From 1d5782ba446bbc571deafd22a0b24ef733a5eb2c Mon Sep 17 00:00:00 2001 From: Jeff Parsons Date: Sun, 25 Mar 2018 17:20:12 -0700 Subject: [PATCH 1/4] Added SPACEMAKER 1.06 --- .../tools/other/spacemaker/1.06/README.md | 15 +++++++ disks/pcx86/tools/other/spacemaker/README.md | 12 +++++ modules/diskdump/bin/disklist | 44 ++++++++++++------- modules/pcx86/lib/video.js | 3 +- modules/shared/lib/proclib.js | 2 + pcjs-disks | 2 +- private-disks | 2 +- 7 files changed, 62 insertions(+), 18 deletions(-) create mode 100644 disks/pcx86/tools/other/spacemaker/1.06/README.md create mode 100644 disks/pcx86/tools/other/spacemaker/README.md diff --git a/disks/pcx86/tools/other/spacemaker/1.06/README.md b/disks/pcx86/tools/other/spacemaker/1.06/README.md new file mode 100644 index 0000000000..ad0ab99d84 --- /dev/null +++ b/disks/pcx86/tools/other/spacemaker/1.06/README.md @@ -0,0 +1,15 @@ +--- +layout: page +title: SPACEMAKER 1.06 +permalink: /disks/pcx86/tools/other/spacemaker/1.06/ +--- + +SPACEMAKER 1.06 +--------------- + +### Directory of SPACEMAKER 1.06 + + Volume in drive A has no label + Directory of A:\ + + SM COM 4680 6-08-88 6:55p diff --git a/disks/pcx86/tools/other/spacemaker/README.md b/disks/pcx86/tools/other/spacemaker/README.md new file mode 100644 index 0000000000..2f5cffbb9e --- /dev/null +++ b/disks/pcx86/tools/other/spacemaker/README.md @@ -0,0 +1,12 @@ +--- +layout: page +title: SPACEMAKER +permalink: /disks/pcx86/tools/other/spacemaker/ +--- + +SPACEMAKER +---------- + +SPACEMAKER was an EXE compression utility created by Realia Inc. + +* [SPACEMAKER 1.06](1.06/) diff --git a/modules/diskdump/bin/disklist b/modules/diskdump/bin/disklist index 2b4d1c70e0..797cb3c85b 100644 --- a/modules/diskdump/bin/disklist +++ b/modules/diskdump/bin/disklist @@ -31,15 +31,20 @@ */ var fs = require("fs"); +var defines = require("../../shared/lib/defines"); +var Str = require("../../../modules/shared/lib/strlib"); +var Proc = require("../../shared/lib/proclib"); +var args = Proc.getArgs(); /** - * println(s) + * printf(format, ...args) * - * @param {*} s + * @param {string} format + * @param {...} args */ -function println(s) +function printf(format, ...args) { - console.log(s); + process.stdout.write(Str.sprintf(format, ...args)); } function processManifest(sManifest) @@ -47,35 +52,39 @@ function processManifest(sManifest) try { var sXML = fs.readFileSync(sManifest, 'utf-8'); } catch(err) { - println("error: unable to read manifest: " + sManifest); + printf("error: unable to read manifest: %s\n", sManifest); return; } var aMatchDisks = sXML.match(/]*>[\S\s]*?<\/disk>/g); if (!aMatchDisks) { - println("warning: no disks found in: " + sManifest); + printf("warning: no disks found in: %s\n", sManifest); return; } + var sDiskTitle; + var matchTitle = sXML.match(/(.*?)<\/title>/); + var matchVersion = sXML.match(/<version>(.*?)<\/version>/); + if (matchTitle && matchVersion) sDiskTitle = matchTitle[1] + ' ' + matchVersion[1]; for (var iDisk = 0; iDisk < aMatchDisks.length; iDisk++) { var sDisk = aMatchDisks[iDisk]; var matchDir = sDisk.match(/dir="(.*?)"/); var matchLink = sDisk.match(/href="(.*?)"/); var matchDiskName = sDisk.match(/<name>(.*?)<\/name>/); var aMatchFiles = sDisk.match(/<file[^>]*>[\S\s]*?<\/file>/g); - var sDiskName = matchDiskName && matchDiskName[1]; + var sDiskName = matchDiskName && matchDiskName[1] || sDiskTitle; if (!aMatchFiles || !sDiskName) { - println("warning: no files in disk: " + sDiskName); + printf("warning: no files in disk: %s\n", sDiskName); return; } - println("### Directory of " + sDiskName + "\n"); - println("\t Volume in drive A " + (matchDiskName? ("is " + matchDiskName[1]) : "has no label")); - println("\t Directory of A:\\\n\t"); + printf("### Directory of %s\n\n", sDiskName); + printf(" Volume in drive A %s\n", (matchDiskName? ("is " + matchDiskName[1]) : "has no label")); + printf(" Directory of A:\\\n \n"); for (var iFile = 0; iFile < aMatchFiles.length; iFile++) { var sFile = aMatchFiles[iFile]; var matchSize = sFile.match(/size="([0-9]*)"/); var matchTime = sFile.match(/time="([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9]) ([0-9][0-9]):([0-9][0-9]):([0-9][0-9])"/); var matchFileName = sFile.match(/>(.*?)</); if (!matchSize || !matchTime || !matchFileName) { - println("warning: file entry #" + iFile + " incomplete"); + printf("warning: file entry #%d incomplete\n", iFile); return; } /* @@ -109,10 +118,15 @@ function processManifest(sManifest) if (iHour > 12) iHour -= 12; } var sTime = (" " + iHour).slice(-4) + ':' + matchTime[5] + sSuffix; - println("\t" + sBaseName + sExtension + sSize + sDate + sTime); + printf(" %s\n", sBaseName + sExtension + sSize + sDate + sTime); } - println(""); + printf("\n"); } } -processManifest("../../../disks/pcx86/tools/microsoft/pascal/4.00/manifest.xml"); +if (args.argc > 1) { + processManifest(args.argv[1]); + process.exit(0); +} + +printf("usage: disklist <manifest>\n"); diff --git a/modules/pcx86/lib/video.js b/modules/pcx86/lib/video.js index 63cbbb8869..a50f409413 100644 --- a/modules/pcx86/lib/video.js +++ b/modules/pcx86/lib/video.js @@ -1288,7 +1288,8 @@ Card.ATC = { }; if (DEBUGGER) { - Card.ATC.REGS = ["PAL00","PAL01","PAL02","PAL03","PAL04","PAL05","PAL06","PAL07", + Card.ATC.REGS = [ + "PAL00","PAL01","PAL02","PAL03","PAL04","PAL05","PAL06","PAL07", "PAL08","PAL09","PAL0A","PAL0B","PAL0C","PAL0D","PAL0E","PAL0F", "MODE","OVERSCAN","PLANES","HPAN"]; } diff --git a/modules/shared/lib/proclib.js b/modules/shared/lib/proclib.js index 0731c219e3..5ab8e7f037 100644 --- a/modules/shared/lib/proclib.js +++ b/modules/shared/lib/proclib.js @@ -48,9 +48,11 @@ class Proc { { var argc = 0; var argv = {}; + argv[argc++] = process.argv[1]; for (var i = 2; i < process.argv.length; i++) { var j, sSep; var sArg = process.argv[i]; + argv[argc++] = sArg; if (!sArg.indexOf(sSep = "--") || !sArg.indexOf(sSep = "—")) { sArg = sArg.substr(sSep.length); var sValue = true; diff --git a/pcjs-disks b/pcjs-disks index 950a645def..e74dcadd14 160000 --- a/pcjs-disks +++ b/pcjs-disks @@ -1 +1 @@ -Subproject commit 950a645def07b76996a155185ff0f48edadd33f0 +Subproject commit e74dcadd14daa6509321277d9dd50915d151e93d diff --git a/private-disks b/private-disks index 9b1fe752ee..67716412cb 160000 --- a/private-disks +++ b/private-disks @@ -1 +1 @@ -Subproject commit 9b1fe752eec246331dba5e304ed2a181c6884588 +Subproject commit 67716412cbb6d42fb9138b092b4453697085f09a From 9247ba5daca123e9fa36b1452dd014a41901fcd3 Mon Sep 17 00:00:00 2001 From: Jeff Parsons <jeff@pcjs.org> Date: Sun, 25 Mar 2018 17:21:03 -0700 Subject: [PATCH 2/4] Added SPACEMAKER 1.06 --- disks/pcx86/library.xml | 1 + disks/pcx86/shareware/pcsig08/library.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/disks/pcx86/library.xml b/disks/pcx86/library.xml index bfafe11d7e..3cb8fa820e 100644 --- a/disks/pcx86/library.xml +++ b/disks/pcx86/library.xml @@ -814,6 +814,7 @@ <disk path="/pcjs-disks/pcx86/tools/other/qemm386/4.23/QEMM386-423.json">QEMM-386 4.23</disk> <disk path="/pcjs-disks/pcx86/tools/other/qemm386/5.13/QEMM386-513.json">QEMM-386 5.13</disk> <disk path="/pcjs-disks/pcx86/tools/other/qemm386/6.02/QEMM386-602.json">QEMM-386 6.02</disk> + <disk path="/pcjs-disks/pcx86/tools/other/spacemaker/1.06/SM106.json">SPACEMAKER 1.06</disk> <disk path="/pcjs-disks/pcx86/games/id/wolf3d/1WOLF14.json">Wolfenstein 3D 1.4</disk> <disk path="/pcjs-disks/pcx86/games/microsoft/flightsim/1982/FLIGHTSIM-1982.json">MS Flight Simulator (1982)</disk> <disk path="/pcjs-disks/pcx86/games/microsoft/flightsim/1984/FLIGHTSIM-1984.json">MS Flight Simulator (1984)</disk> diff --git a/disks/pcx86/shareware/pcsig08/library.xml b/disks/pcx86/shareware/pcsig08/library.xml index 58083ad758..6980c8e130 100644 --- a/disks/pcx86/shareware/pcsig08/library.xml +++ b/disks/pcx86/shareware/pcsig08/library.xml @@ -814,6 +814,7 @@ <disk path="/pcjs-disks/pcx86/tools/other/qemm386/4.23/QEMM386-423.json">QEMM-386 4.23</disk> <disk path="/pcjs-disks/pcx86/tools/other/qemm386/5.13/QEMM386-513.json">QEMM-386 5.13</disk> <disk path="/pcjs-disks/pcx86/tools/other/qemm386/6.02/QEMM386-602.json">QEMM-386 6.02</disk> + <disk path="/pcjs-disks/pcx86/tools/other/spacemaker/1.06/SM106.json">SPACEMAKER 1.06</disk> <disk path="/pcjs-disks/pcx86/games/id/wolf3d/1WOLF14.json">Wolfenstein 3D 1.4</disk> <disk path="/pcjs-disks/pcx86/games/microsoft/flightsim/1982/FLIGHTSIM-1982.json">MS Flight Simulator (1982)</disk> <disk path="/pcjs-disks/pcx86/games/microsoft/flightsim/1984/FLIGHTSIM-1984.json">MS Flight Simulator (1984)</disk> From ebe72f388b03200956ea83de1fb25ab420ec868e Mon Sep 17 00:00:00 2001 From: Jeff Parsons <jeff@pcjs.org> Date: Sun, 25 Mar 2018 17:37:48 -0700 Subject: [PATCH 3/4] Converted disklist to use printf() --- modules/diskdump/bin/disklist | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/modules/diskdump/bin/disklist b/modules/diskdump/bin/disklist index 797cb3c85b..cb98f0b5d8 100644 --- a/modules/diskdump/bin/disklist +++ b/modules/diskdump/bin/disklist @@ -87,11 +87,6 @@ function processManifest(sManifest) printf("warning: file entry #%d incomplete\n", iFile); return; } - /* - * Here's our template, from PC-DOS 2.00: - * - * COMMAND COM 17664 3-08-83 12:00p - */ var sSize = matchSize[1]; var sTime = matchTime[1]; var sFileName = matchFileName[1].replace(/&/g, "&"); @@ -102,12 +97,11 @@ function processManifest(sManifest) sBaseName = sFileName.substr(0, i); sExtension = sFileName.substr(i + 1); } - sBaseName = (sBaseName + " ").substr(0, 9); - sExtension = (sExtension + " ").substr(0, 3); - sSize = (" " + sSize).slice(-9); var iMonth = +matchTime[2]; - var sDate = (" " + iMonth).slice(-4) + '-' + matchTime[3] + '-' + matchTime[1].substr(2); + var iDay = +matchTime[3]; + var iYear = +matchTime[1] % 100; var iHour = +matchTime[4]; + var iMinute = +matchTime[5]; var sSuffix; if (iHour < 12) { sSuffix = "a"; @@ -117,8 +111,12 @@ function processManifest(sManifest) sSuffix = "p"; if (iHour > 12) iHour -= 12; } - var sTime = (" " + iHour).slice(-4) + ':' + matchTime[5] + sSuffix; - printf(" %s\n", sBaseName + sExtension + sSize + sDate + sTime); + /* + * Here's our template, from PC-DOS 2.00: + * + * COMMAND COM 17664 3-08-83 12:00p + */ + printf(" %-8s %-3s %8s %2d-%02d-%02d %2d:%02d%s\n", sBaseName, sExtension, sSize, iMonth, iDay, iYear, iHour, iMinute, sSuffix); } printf("\n"); } From ba845c6a075f145cce6b884597e4ca48d023c5eb Mon Sep 17 00:00:00 2001 From: Jeff Parsons <jeff@pcjs.org> Date: Mon, 26 Mar 2018 10:29:08 -0700 Subject: [PATCH 4/4] Experienced more joy eliminating inspection warnings in both JetBrains and the Closure Compiler; also, removed autoType sequences from all machines with predefined states --- apps/pcx86/1981/donkey/README.md | 1 - apps/pcx86/1981/donkey/debugger/README.md | 1 - apps/pcx86/1981/visicalc/README.md | 1 - modules/c1pjs/lib/computer.js | 2 +- modules/c1pjs/lib/cpu.js | 2 +- modules/c1pjs/lib/debugger.js | 2 +- modules/c1pjs/lib/disk.js | 2 +- modules/c1pjs/lib/keyboard.js | 2 +- modules/c1pjs/lib/panel.js | 2 +- modules/c1pjs/lib/serial.js | 2 +- modules/c1pjs/lib/video.js | 2 +- modules/pc8080/lib/chipset.js | 2 +- modules/pc8080/lib/computer.js | 2 +- modules/pc8080/lib/cpu.js | 4 +- modules/pc8080/lib/cpustate.js | 2 +- modules/pc8080/lib/debugger.js | 2 +- modules/pc8080/lib/keyboard.js | 2 +- modules/pc8080/lib/panel.js | 2 +- modules/pc8080/lib/serial.js | 4 +- modules/pc8080/lib/video.js | 2 +- modules/pcx86/lib/chipset.js | 2 +- modules/pcx86/lib/computer.js | 2 +- modules/pcx86/lib/cpu.js | 4 +- modules/pcx86/lib/cpux86.js | 2 +- modules/pcx86/lib/debugger.js | 8 +- modules/pcx86/lib/fdc.js | 2 +- modules/pcx86/lib/fpux86.js | 3040 +++++++++--------- modules/pcx86/lib/hdc.js | 4 +- modules/pcx86/lib/keyboard.js | 2 +- modules/pcx86/lib/mouse.js | 2 +- modules/pcx86/lib/panel.js | 4 +- modules/pcx86/lib/parallel.js | 4 +- modules/pcx86/lib/serial.js | 4 +- modules/pcx86/lib/testctl.js | 2 +- modules/pcx86/lib/video.js | 22 +- modules/pdp10/lib/computer.js | 6 +- modules/pdp10/lib/cpu.js | 8 +- modules/pdp10/lib/debugger.js | 6 +- modules/pdp10/lib/panel.js | 24 +- modules/pdp10/lib/serial.js | 8 +- modules/pdp11/lib/computer.js | 6 +- modules/pdp11/lib/cpu.js | 8 +- modules/pdp11/lib/debugger.js | 6 +- modules/pdp11/lib/drive.js | 6 +- modules/pdp11/lib/keyboard.js | 6 +- modules/pdp11/lib/panel.js | 24 +- modules/pdp11/lib/pc11.js | 6 +- modules/pdp11/lib/serial.js | 8 +- modules/shared/lib/component.js | 12 +- modules/shared/lib/debugger.js | 2 +- modules/shared/lib/strlib.js | 18 +- versions/c1pjs/1.61.0/c1p-uncompiled.js | 46 +- versions/c1pjs/1.61.0/c1p.js | 2 +- versions/c1pjs/1.61.0/c1p.js.map | 2 +- versions/pc8080/1.61.0/pc8080-uncompiled.js | 54 +- versions/pc8080/1.61.0/pc8080.js | 8 +- versions/pc8080/1.61.0/pc8080.js.map | 2 +- versions/pcx86/1.61.0/pcx86-uncompiled.js | 3121 ++++++++++--------- versions/pcx86/1.61.0/pcx86.js | 26 +- versions/pcx86/1.61.0/pcx86.js.map | 2 +- versions/pdpjs/1.61.0/pdp10-uncompiled.js | 84 +- versions/pdpjs/1.61.0/pdp10.js | 8 +- versions/pdpjs/1.61.0/pdp10.js.map | 2 +- versions/pdpjs/1.61.0/pdp11-uncompiled.js | 102 +- versions/pdpjs/1.61.0/pdp11.js | 12 +- versions/pdpjs/1.61.0/pdp11.js.map | 2 +- 66 files changed, 3373 insertions(+), 3399 deletions(-) diff --git a/apps/pcx86/1981/donkey/README.md b/apps/pcx86/1981/donkey/README.md index a83a905f25..39ffa2de5e 100644 --- a/apps/pcx86/1981/donkey/README.md +++ b/apps/pcx86/1981/donkey/README.md @@ -19,7 +19,6 @@ machines: name: PC-DOS 1.00 B: name: None - autoType: $date\rbasica donkey\r --- IBM PC Running DONKEY.BAS diff --git a/apps/pcx86/1981/donkey/debugger/README.md b/apps/pcx86/1981/donkey/debugger/README.md index f1ca88f9d3..026e0b6c3b 100644 --- a/apps/pcx86/1981/donkey/debugger/README.md +++ b/apps/pcx86/1981/donkey/debugger/README.md @@ -13,7 +13,6 @@ machines: name: PC-DOS 1.00 B: name: None - autoType: $date\rbasica donkey\r --- IBM PC Running DONKEY.BAS (with Debugger) diff --git a/apps/pcx86/1981/visicalc/README.md b/apps/pcx86/1981/visicalc/README.md index c67f216c56..9f42540d56 100644 --- a/apps/pcx86/1981/visicalc/README.md +++ b/apps/pcx86/1981/visicalc/README.md @@ -13,7 +13,6 @@ machines: name: PC-DOS 1.00 B: name: VisiCalc (1981) - autoType: $date\rb:\rvc\r --- VisiCalc (1981) diff --git a/modules/c1pjs/lib/computer.js b/modules/c1pjs/lib/computer.js index 15aa3ce6f7..c66b73f2e7 100644 --- a/modules/c1pjs/lib/computer.js +++ b/modules/c1pjs/lib/computer.js @@ -145,7 +145,7 @@ class C1PComputer extends Component { /** * @this {C1PComputer} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "reset") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/c1pjs/lib/cpu.js b/modules/c1pjs/lib/cpu.js index 96cfb941d9..a00bb3c7d0 100644 --- a/modules/c1pjs/lib/cpu.js +++ b/modules/c1pjs/lib/cpu.js @@ -514,7 +514,7 @@ class C1PCPU extends Component { /** * @this {C1PCPU} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "run") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/c1pjs/lib/debugger.js b/modules/c1pjs/lib/debugger.js index 038e7510a2..c7fa130d27 100644 --- a/modules/c1pjs/lib/debugger.js +++ b/modules/c1pjs/lib/debugger.js @@ -492,7 +492,7 @@ class C1PDebugger extends Component { /** * @this {C1PDebugger} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/c1pjs/lib/disk.js b/modules/c1pjs/lib/disk.js index 01378ece09..3fb69824e6 100644 --- a/modules/c1pjs/lib/disk.js +++ b/modules/c1pjs/lib/disk.js @@ -665,7 +665,7 @@ class C1PDiskController extends Component { /** * @this {C1PDiskController} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "listDisk") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/c1pjs/lib/keyboard.js b/modules/c1pjs/lib/keyboard.js index 2eddbf744f..24b53b7b29 100644 --- a/modules/c1pjs/lib/keyboard.js +++ b/modules/c1pjs/lib/keyboard.js @@ -396,7 +396,7 @@ class C1PKeyboard extends Component { /** * @this {C1PKeyboard} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "esc", "ctrl-c") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/c1pjs/lib/panel.js b/modules/c1pjs/lib/panel.js index 7429fd0287..c54e323408 100644 --- a/modules/c1pjs/lib/panel.js +++ b/modules/c1pjs/lib/panel.js @@ -62,7 +62,7 @@ class C1PPanel extends Component { * component that doesn't recognize the specified binding should simply ignore it. * * @this {C1PPanel} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/c1pjs/lib/serial.js b/modules/c1pjs/lib/serial.js index e60e9bea22..c8aca1ce8d 100644 --- a/modules/c1pjs/lib/serial.js +++ b/modules/c1pjs/lib/serial.js @@ -101,7 +101,7 @@ class C1PSerialPort extends Component { /** * @this {C1PSerialPort} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "listSerial") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/c1pjs/lib/video.js b/modules/c1pjs/lib/video.js index c9a58cf6bf..2796443712 100644 --- a/modules/c1pjs/lib/video.js +++ b/modules/c1pjs/lib/video.js @@ -216,7 +216,7 @@ class C1PVideo extends Component { /** * @this {C1PVideo} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "refresh") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/pc8080/lib/chipset.js b/modules/pc8080/lib/chipset.js index 8f15c358cc..a135bdead1 100644 --- a/modules/pc8080/lib/chipset.js +++ b/modules/pc8080/lib/chipset.js @@ -132,7 +132,7 @@ class ChipSet8080 extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {ChipSet8080} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, "sw1") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/pc8080/lib/computer.js b/modules/pc8080/lib/computer.js index f4c3842e0f..8dba5e45e3 100644 --- a/modules/pc8080/lib/computer.js +++ b/modules/pc8080/lib/computer.js @@ -1036,7 +1036,7 @@ class Computer8080 extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {Computer8080} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/pc8080/lib/cpu.js b/modules/pc8080/lib/cpu.js index f9c1caf7de..56d5a57743 100644 --- a/modules/pc8080/lib/cpu.js +++ b/modules/pc8080/lib/cpu.js @@ -150,7 +150,7 @@ class CPU8080 extends Component { for (var i = 0; i < CPU8080.BUTTONS.length; i++) { var control = this.bindings[CPU8080.BUTTONS[i]]; - if (control) this.cmp.setBinding(null, CPU8080.BUTTONS[i], control); + if (control) this.cmp.setBinding("", CPU8080.BUTTONS[i], control); } /* @@ -439,7 +439,7 @@ class CPU8080 extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {CPU8080} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/pc8080/lib/cpustate.js b/modules/pc8080/lib/cpustate.js index 6d25399f78..e490e82f6f 100644 --- a/modules/pc8080/lib/cpustate.js +++ b/modules/pc8080/lib/cpustate.js @@ -258,7 +258,7 @@ class CPUState8080 extends CPU8080 { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {CPUState8080} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/pc8080/lib/debugger.js b/modules/pc8080/lib/debugger.js index d5f31a3c0e..15f05d0841 100644 --- a/modules/pc8080/lib/debugger.js +++ b/modules/pc8080/lib/debugger.js @@ -209,7 +209,7 @@ class Debugger8080 extends Debugger { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {Debugger8080} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/pc8080/lib/keyboard.js b/modules/pc8080/lib/keyboard.js index cf9d0d127f..0b3e554da6 100644 --- a/modules/pc8080/lib/keyboard.js +++ b/modules/pc8080/lib/keyboard.js @@ -78,7 +78,7 @@ class Keyboard8080 extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {Keyboard8080} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/pc8080/lib/panel.js b/modules/pc8080/lib/panel.js index 015f649b7d..b6041d7212 100644 --- a/modules/pc8080/lib/panel.js +++ b/modules/pc8080/lib/panel.js @@ -66,7 +66,7 @@ class Panel8080 extends Component { * that doesn't recognize the specified binding should simply ignore it. * * @this {Panel8080} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/pc8080/lib/serial.js b/modules/pc8080/lib/serial.js index 3fe2c243d5..1bdca757d1 100644 --- a/modules/pc8080/lib/serial.js +++ b/modules/pc8080/lib/serial.js @@ -174,7 +174,7 @@ class SerialPort8080 extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {SerialPort8080} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, "buffer") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -184,7 +184,7 @@ class SerialPort8080 extends Component { { var serial = this; - if (sHTMLType == null || sHTMLType == "textarea") { + if (!sHTMLType || sHTMLType == "textarea") { this.bindings[sBinding] = this.controlBuffer = control; diff --git a/modules/pc8080/lib/video.js b/modules/pc8080/lib/video.js index ca094efbd3..0b33ef5522 100644 --- a/modules/pc8080/lib/video.js +++ b/modules/pc8080/lib/video.js @@ -342,7 +342,7 @@ class Video8080 extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {Video8080} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, "refresh") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/pcx86/lib/chipset.js b/modules/pcx86/lib/chipset.js index 10fd3e7a30..ca23937baf 100644 --- a/modules/pcx86/lib/chipset.js +++ b/modules/pcx86/lib/chipset.js @@ -268,7 +268,7 @@ class ChipSet extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {ChipSet} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, "sw1") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/pcx86/lib/computer.js b/modules/pcx86/lib/computer.js index 0ad459b4b6..876ae82a96 100644 --- a/modules/pcx86/lib/computer.js +++ b/modules/pcx86/lib/computer.js @@ -1296,7 +1296,7 @@ class Computer extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {Computer} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/pcx86/lib/cpu.js b/modules/pcx86/lib/cpu.js index b6fb1ac352..11956cc9d2 100644 --- a/modules/pcx86/lib/cpu.js +++ b/modules/pcx86/lib/cpu.js @@ -146,7 +146,7 @@ class CPU extends Component { for (var i = 0; i < CPU.BUTTONS.length; i++) { var control = this.bindings[CPU.BUTTONS[i]]; - if (control) this.cmp.setBinding(null, CPU.BUTTONS[i], control); + if (control) this.cmp.setBinding("", CPU.BUTTONS[i], control); } this.fpu = cmp.getMachineComponent("FPU"); @@ -451,7 +451,7 @@ class CPU extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {CPU} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/pcx86/lib/cpux86.js b/modules/pcx86/lib/cpux86.js index 641e18c60e..c5fdd7690c 100644 --- a/modules/pcx86/lib/cpux86.js +++ b/modules/pcx86/lib/cpux86.js @@ -2984,7 +2984,7 @@ class CPUX86 extends CPU { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {CPUX86} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/pcx86/lib/debugger.js b/modules/pcx86/lib/debugger.js index 3655d9fb84..490af43e2b 100644 --- a/modules/pcx86/lib/debugger.js +++ b/modules/pcx86/lib/debugger.js @@ -890,7 +890,7 @@ class DebuggerX86 extends Debugger { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {DebuggerX86} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -4183,7 +4183,7 @@ class DebuggerX86 extends Debugger { * * @this {DebuggerX86} * @param {string} sName - * @param {number|null} sel + * @param {number|null|*} sel * @param {number} addr * @param {number} addrLimit * @return {string} @@ -4378,7 +4378,7 @@ class DebuggerX86 extends Debugger { * @param {number} nSegment (zero if undefined) * @param {number} sel (the default segment/selector for all symbols in this group) * @param {number} off (from the base of the given selector) - * @param {number|null} addr (physical address where the symbols are located, if the memory is physical; eg, ROM) + * @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) */ @@ -4434,7 +4434,7 @@ class DebuggerX86 extends Debugger { * removeSymbols(sModule, nSegment) * * @this {DebuggerX86} - * @param {string|null} sModule + * @param {string|null|*} sModule * @param {number} [nSegment] (segment # if sModule set, selector if sModule clear) * @return {string|null} name of the module removed, or null if no module was found */ diff --git a/modules/pcx86/lib/fdc.js b/modules/pcx86/lib/fdc.js index b77fce31b1..e12f76438b 100644 --- a/modules/pcx86/lib/fdc.js +++ b/modules/pcx86/lib/fdc.js @@ -200,7 +200,7 @@ class FDC extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {FDC} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, "listDisks") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/pcx86/lib/fpux86.js b/modules/pcx86/lib/fpux86.js index 356eebf1c5..8f3f658697 100644 --- a/modules/pcx86/lib/fpux86.js +++ b/modules/pcx86/lib/fpux86.js @@ -69,7 +69,7 @@ if (NODE) { */ /** - * class FPUX86 + * @class FPUX86 * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor) */ class FPUX86 extends Component { @@ -1547,1671 +1547,1671 @@ class FPUX86 extends Component { */ /** - * F2XM1() - * - * F2XM1 (2 to the x minus 1) calculates the function 2^x - 1 and returns the result to ST(0). - * - * On the 8087 and 80287, the value in ST(0) must satisfy the inequality 0 <= ST(0) <= 0.5. On the 80287XL and - * later coprocessors, the permissible range is greater, and ST(0) must satisfy the inequality -1 <= ST(0) <= 1. - * If ST(0) is out of range, the result is undefined, even though no exception is raised. - * - * The F2XM1 instruction is designed to provide an accurate result even when x is close to zero. To obtain 2^x, - * simply add 1.0 to the result returned by F2XM1. - * - * This instruction is useful in performing exponentiation of values other than 2 as shown in the following formulas: - * - * 10^x = 2^(x * log2(10)) - * e^x = 2^(x * log2(e)) - * y^x = 2^(x * log2(y)) - * - * Note that the NPX has dedicated instructions for loading the constants log2(10) and log2(e). The FYL2X instruction - * may be used to calculate x * log2(y). - * - * See also: FYL2X, FLDL2T, FLDL2E. + * FPUX86.init() * - * @this {FPUX86} + * This function operates on every HTML element of class "fpu", extracting the + * JSON-encoded parameters for the FPUX86 constructor from the element's "data-value" + * attribute, invoking the constructor to create an FPUX86 component, and then binding + * any associated HTML controls to the new component. */ - static F2XM1() + static init() { - this.setST(0, Math.pow(2, this.getST(0)) - 1); + var aeFPUs = Component.getElementsByClass(document, PCX86.APPCLASS, "fpu"); + for (var iFPU = 0; iFPU < aeFPUs.length; iFPU++) { + var eFPU = aeFPUs[iFPU]; + var parmsFPU = Component.getComponentParms(eFPU); + var fpu = new FPUX86(parmsFPU); + Component.bindComponentControls(fpu, eFPU, PCX86.APPCLASS); + } } +} - /** - * FABS() - * - * @this {FPUX86} - */ - static FABS() - { - /* - * TODO: This could be implemented more efficiently by simply clearing the sign bit of ST(0). - */ - this.setST(0, Math.abs(this.getST(0))); - } +/** + * F2XM1() + * + * F2XM1 (2 to the x minus 1) calculates the function 2^x - 1 and returns the result to ST(0). + * + * On the 8087 and 80287, the value in ST(0) must satisfy the inequality 0 <= ST(0) <= 0.5. On the 80287XL and + * later coprocessors, the permissible range is greater, and ST(0) must satisfy the inequality -1 <= ST(0) <= 1. + * If ST(0) is out of range, the result is undefined, even though no exception is raised. + * + * The F2XM1 instruction is designed to provide an accurate result even when x is close to zero. To obtain 2^x, + * simply add 1.0 to the result returned by F2XM1. + * + * This instruction is useful in performing exponentiation of values other than 2 as shown in the following formulas: + * + * 10^x = 2^(x * log2(10)) + * e^x = 2^(x * log2(e)) + * y^x = 2^(x * log2(y)) + * + * Note that the NPX has dedicated instructions for loading the constants log2(10) and log2(e). The FYL2X instruction + * may be used to calculate x * log2(y). + * + * See also: FYL2X, FLDL2T, FLDL2E. + * + * @this {FPUX86} + */ +FPUX86.F2XM1 = function() +{ + this.setST(0, Math.pow(2, this.getST(0)) - 1); +}; - /** - * FADDlr() - * - * @this {FPUX86} +/** + * FABS() + * + * @this {FPUX86} + */ +FPUX86.FABS = function() +{ + /* + * TODO: This could be implemented more efficiently by simply clearing the sign bit of ST(0). */ - static FADDlr() - { - this.setST(0, this.doAdd(this.getST(0), this.getLRFromEA())); - } + this.setST(0, Math.abs(this.getST(0))); +}; - /** - * FADDsr() - * - * Encoding 0xD8,reg=0x00 ("FADD short-real"): ST(0) <- ST(0) + REAL32 - * - * @this {FPUX86} - */ - static FADDsr() - { - this.setST(0, this.doAdd(this.getST(0), this.getSRFromEA())); - } +/** + * FADDlr() + * + * @this {FPUX86} + */ +FPUX86.FADDlr = function() +{ + this.setST(0, this.doAdd(this.getST(0), this.getLRFromEA())); +}; - /** - * FADDst() - * - * @this {FPUX86} - */ - static FADDst() - { - this.setST(0, this.doAdd(this.getST(0), this.getST(this.iStack))); - } +/** + * FADDsr() + * + * Encoding 0xD8,reg=0x00 ("FADD short-real"): ST(0) <- ST(0) + REAL32 + * + * @this {FPUX86} + */ +FPUX86.FADDsr = function() +{ + this.setST(0, this.doAdd(this.getST(0), this.getSRFromEA())); +}; - /** - * FADDsti() - * - * @this {FPUX86} - */ - static FADDsti() - { - this.setST(this.iStack, this.doAdd(this.getST(this.iStack), this.getST(0))); - } +/** + * FADDst() + * + * @this {FPUX86} + */ +FPUX86.FADDst = function() +{ + this.setST(0, this.doAdd(this.getST(0), this.getST(this.iStack))); +}; - /** - * FADDPsti() - * - * @this {FPUX86} - */ - static FADDPsti() - { - if (this.setST(this.iStack, this.doAdd(this.getST(this.iStack), this.getST(0)))) this.popValue(); - } +/** + * FADDsti() + * + * @this {FPUX86} + */ +FPUX86.FADDsti = function() +{ + this.setST(this.iStack, this.doAdd(this.getST(this.iStack), this.getST(0))); +}; - /** - * FBLDpd() - * - * @this {FPUX86} - */ - static FBLDpd() - { - var a = this.getTRFromEA(); - /* - * a[0] contains the 8 least-significant BCD digits, a[1] contains the next 8, and a[2] contains - * the next 2 (bit 15 of a[2] is the sign bit, and bits 8-14 of a[2] are unused). - */ - var v = this.decodeBCD(a[0], 8) + this.decodeBCD(a[1], 8) * 100000000 + this.decodeBCD(a[2], 2) * 10000000000000000; - if (a[2] & 0x8000) v = -v; - this.pushValue(v); - } +/** + * FADDPsti() + * + * @this {FPUX86} + */ +FPUX86.FADDPsti = function() +{ + if (this.setST(this.iStack, this.doAdd(this.getST(this.iStack), this.getST(0)))) this.popValue(); +}; - /** - * FBSTPpd() - * - * @this {FPUX86} - */ - static FBSTPpd() - { - /* - * TODO: Verify the operation of FBSTP (eg, does it signal an exception if abs(value) >= 1000000000000000000?) - */ - var v = this.roundValue(this.popValue()); - if (v != null) { - /* - * intTmpTR[0] will contain the 8 least-significant BCD digits, intTmpTR[1] will contain the next 8, - * and intTmpTR[2] will contain the next 2 (bit 15 of intTmpTR[2] will be the sign bit, and bits 8-14 of - * intTmpTR[2] will be unused). - */ - this.intTmpTR[0] = this.encodeBCD(v, 8); - this.intTmpTR[1] = this.encodeBCD(v / 100000000, 8); - this.intTmpTR[2] = this.encodeBCD(v / 10000000000000000, 2); - if (v < 0) this.intTmpTR[2] |= 0x8000; - this.setEAFromTR(); - } - } +/** + * FBLDpd() + * + * @this {FPUX86} + */ +FPUX86.FBLDpd = function() +{ + var a = this.getTRFromEA(); + /* + * a[0] contains the 8 least-significant BCD digits, a[1] contains the next 8, and a[2] contains + * the next 2 (bit 15 of a[2] is the sign bit, and bits 8-14 of a[2] are unused). + */ + var v = this.decodeBCD(a[0], 8) + this.decodeBCD(a[1], 8) * 100000000 + this.decodeBCD(a[2], 2) * 10000000000000000; + if (a[2] & 0x8000) v = -v; + this.pushValue(v); +}; - /** - * FCHS() - * - * @this {FPUX86} +/** + * FBSTPpd() + * + * @this {FPUX86} + */ +FPUX86.FBSTPpd = function() +{ + /* + * TODO: Verify the operation of FBSTP (eg, does it signal an exception if abs(value) >= 1000000000000000000?) */ - static FCHS() - { + var v = this.roundValue(this.popValue()); + if (v != null) { /* - * TODO: This could be implemented more efficiently by simply inverting the sign bit of ST(0). + * intTmpTR[0] will contain the 8 least-significant BCD digits, intTmpTR[1] will contain the next 8, + * and intTmpTR[2] will contain the next 2 (bit 15 of intTmpTR[2] will be the sign bit, and bits 8-14 of + * intTmpTR[2] will be unused). */ - this.setST(0, -this.getST(0)); - } - - /** - * FCLEX() - * - * NOTE: Although we explicitly clear the BUSY bit, there shouldn't be any code setting it, because - * we're never "busy" (all floating-point operations are performed synchronously). Conversely, there's - * no need to explicitly clear the ES bit, because clearStatus() will call checkException(), which - * updates ES and clears/sets FPU interrupt status as appropriate. - * - * @this {FPUX86} - */ - static FCLEX() - { - this.clearStatus(X86.FPU.STATUS.EXC | X86.FPU.STATUS.BUSY); + this.intTmpTR[0] = this.encodeBCD(v, 8); + this.intTmpTR[1] = this.encodeBCD(v / 100000000, 8); + this.intTmpTR[2] = this.encodeBCD(v / 10000000000000000, 2); + if (v < 0) this.intTmpTR[2] |= 0x8000; + this.setEAFromTR(); } +}; - /** - * FCOMlr() - * - * Encoding 0xDC,mod<3,reg=2 ("FCOM long-real"): Evaluate ST(0) - REAL64 - * - * @this {FPUX86} +/** + * FCHS() + * + * @this {FPUX86} + */ +FPUX86.FCHS = function() +{ + /* + * TODO: This could be implemented more efficiently by simply inverting the sign bit of ST(0). */ - static FCOMlr() - { - this.doCompare(this.getST(0), this.getLRFromEA()); - } + this.setST(0, -this.getST(0)); +}; - /** - * FCOMsr() - * - * Encoding 0xD8,mod<3,reg=2 ("FCOM short-real"): Evaluate ST(0) - REAL32 - * - * @this {FPUX86} - */ - static FCOMsr() - { - this.doCompare(this.getST(0), this.getSRFromEA()); - } +/** + * FCLEX() + * + * NOTE: Although we explicitly clear the BUSY bit, there shouldn't be any code setting it, because + * we're never "busy" (all floating-point operations are performed synchronously). Conversely, there's + * no need to explicitly clear the ES bit, because clearStatus() will call checkException(), which + * updates ES and clears/sets FPU interrupt status as appropriate. + * + * @this {FPUX86} + */ +FPUX86.FCLEX = function() +{ + this.clearStatus(X86.FPU.STATUS.EXC | X86.FPU.STATUS.BUSY); +}; - /** - * FCOMst() - * - * Encoding 0xD8,mod=3,reg=2 ("FCOM ST(i)"): Evaluate ST(0) - ST(i) - * - * @this {FPUX86} - */ - static FCOMst() - { - this.doCompare(this.getST(0), this.getST(this.iStack)); - } +/** + * FCOMlr() + * + * Encoding 0xDC,mod<3,reg=2 ("FCOM long-real"): Evaluate ST(0) - REAL64 + * + * @this {FPUX86} + */ +FPUX86.FCOMlr = function() +{ + this.doCompare(this.getST(0), this.getLRFromEA()); +}; - /** - * FCOM8087() - * - * NOTE: This is used with encoding(s) (0xDC,0xD0-0xD7) that were valid for the 8087 and 80287 - * but may no longer be valid as of the 80387. - * - * TODO: Determine if this form subtracted the operands in the same order, or if it requires an FCOMsti(), - * which, like the other *sti() functions, uses ST(0) as the second operand rather than the first. - * - * @this {FPUX86} - */ - static FCOM8087() - { - this.opObsolete(); - FPUX86.FCOMst.call(this); - } +/** + * FCOMsr() + * + * Encoding 0xD8,mod<3,reg=2 ("FCOM short-real"): Evaluate ST(0) - REAL32 + * + * @this {FPUX86} + */ +FPUX86.FCOMsr = function() +{ + this.doCompare(this.getST(0), this.getSRFromEA()); +}; - /** - * FCOMPlr() - * - * Encoding 0xDC,mod<3,reg=3 ("FCOM long-real"): Evaluate ST(0) - REAL64, POP - * - * @this {FPUX86} - */ - static FCOMPlr() - { - if (this.doCompare(this.getST(0), this.getLRFromEA())) this.popValue(); - } +/** + * FCOMst() + * + * Encoding 0xD8,mod=3,reg=2 ("FCOM ST(i)"): Evaluate ST(0) - ST(i) + * + * @this {FPUX86} + */ +FPUX86.FCOMst = function() +{ + this.doCompare(this.getST(0), this.getST(this.iStack)); +}; - /** - * FCOMPsr() - * - * Encoding 0xD8,mod<3,reg=3 ("FCOM short-real"): Evaluate ST(0) - REAL32, POP - * - * @this {FPUX86} - */ - static FCOMPsr() - { - if (this.doCompare(this.getST(0), this.getSRFromEA())) this.popValue(); - } +/** + * FCOM8087() + * + * NOTE: This is used with encoding(s) (0xDC,0xD0-0xD7) that were valid for the 8087 and 80287 + * but may no longer be valid as of the 80387. + * + * TODO: Determine if this form subtracted the operands in the same order, or if it requires an FCOMsti(), + * which, like the other *sti() functions, uses ST(0) as the second operand rather than the first. + * + * @this {FPUX86} + */ +FPUX86.FCOM8087 = function() +{ + this.opObsolete(); + FPUX86.FCOMst.call(this); +}; - /** - * FCOMPst() - * - * Encoding 0xD8,mod=3,reg=3 ("FCOMP ST(i)"): Evaluate ST(0) - ST(i), POP - * - * @this {FPUX86} - */ - static FCOMPst() - { - if (this.doCompare(this.getST(0), this.getST(this.iStack))) this.popValue(); - } +/** + * FCOMPlr() + * + * Encoding 0xDC,mod<3,reg=3 ("FCOM long-real"): Evaluate ST(0) - REAL64, POP + * + * @this {FPUX86} + */ +FPUX86.FCOMPlr = function() +{ + if (this.doCompare(this.getST(0), this.getLRFromEA())) this.popValue(); +}; - /** - * FCOMP8087() - * - * NOTE: This is used with encodings (0xDC,0xD8-0xDF and 0xDE,0xD0-0xD7) that were valid for the 8087 - * and 80287 but may no longer be valid as of the 80387. - * - * TODO: Determine if this form subtracted the operands in the same order, or if it requires an FCOMPsti(), - * which, like the other *sti() functions, uses ST(0) as the second operand rather than the first. - * - * @this {FPUX86} - */ - static FCOMP8087() - { - this.opObsolete(); - FPUX86.FCOMPst.call(this); - } +/** + * FCOMPsr() + * + * Encoding 0xD8,mod<3,reg=3 ("FCOM short-real"): Evaluate ST(0) - REAL32, POP + * + * @this {FPUX86} + */ +FPUX86.FCOMPsr = function() +{ + if (this.doCompare(this.getST(0), this.getSRFromEA())) this.popValue(); +}; - /** - * FCOMPP() - * - * @this {FPUX86} - */ - static FCOMPP() - { - if (this.doCompare(this.getST(0), this.getST(1)) && this.popValue() != null) this.popValue(); - } +/** + * FCOMPst() + * + * Encoding 0xD8,mod=3,reg=3 ("FCOMP ST(i)"): Evaluate ST(0) - ST(i), POP + * + * @this {FPUX86} + */ +FPUX86.FCOMPst = function() +{ + if (this.doCompare(this.getST(0), this.getST(this.iStack))) this.popValue(); +}; - /** - * FDECSTP() - * - * @this {FPUX86} - */ - static FDECSTP() - { - this.iST = (this.iST - 1) & 0x7; - this.regStatus &= ~X86.FPU.STATUS.C1; - } +/** + * FCOMP8087() + * + * NOTE: This is used with encodings (0xDC,0xD8-0xDF and 0xDE,0xD0-0xD7) that were valid for the 8087 + * and 80287 but may no longer be valid as of the 80387. + * + * TODO: Determine if this form subtracted the operands in the same order, or if it requires an FCOMPsti(), + * which, like the other *sti() functions, uses ST(0) as the second operand rather than the first. + * + * @this {FPUX86} + */ +FPUX86.FCOMP8087 = function() +{ + this.opObsolete(); + FPUX86.FCOMPst.call(this); +}; - /** - * FDISI8087() - * - * @this {FPUX86} - */ - static FDISI8087() - { - if (this.isModel(X86.FPU.MODEL_8087)) { - this.regControl |= X86.FPU.CONTROL.IEM; - } - } +/** + * FCOMPP() + * + * @this {FPUX86} + */ +FPUX86.FCOMPP = function() +{ + if (this.doCompare(this.getST(0), this.getST(1)) && this.popValue() != null) this.popValue(); +}; - /** - * FDIVlr() - * - * @this {FPUX86} - */ - static FDIVlr() - { - this.setST(0, this.doDivide(this.getST(0), this.getLRFromEA())); - } +/** + * FDECSTP() + * + * @this {FPUX86} + */ +FPUX86.FDECSTP = function() +{ + this.iST = (this.iST - 1) & 0x7; + this.regStatus &= ~X86.FPU.STATUS.C1; +}; - /** - * FDIVsr() - * - * @this {FPUX86} - */ - static FDIVsr() - { - this.setST(0, this.doDivide(this.getST(0), this.getSRFromEA())); +/** + * FDISI8087() + * + * @this {FPUX86} + */ +FPUX86.FDISI8087 = function() +{ + if (this.isModel(X86.FPU.MODEL_8087)) { + this.regControl |= X86.FPU.CONTROL.IEM; } +}; - /** - * FDIVst() - * - * Encoding 0xD8,0xF0-0xF7 ("FDIV ST,ST(i)"): ST(0) <- ST(0) / ST(i) - * - * @this {FPUX86} - */ - static FDIVst() - { - this.setST(0, this.doDivide(this.getST(0), this.getST(this.iStack))); - } +/** + * FDIVlr() + * + * @this {FPUX86} + */ +FPUX86.FDIVlr = function() +{ + this.setST(0, this.doDivide(this.getST(0), this.getLRFromEA())); +}; - /** - * FDIVsti() - * - * Encoding 0xDC,0xF8-0xFF ("FDIV ST(i),ST"): ST(i) <- ST(i) / ST(0) - * - * @this {FPUX86} - */ - static FDIVsti() - { - this.setST(this.iStack, this.doDivide(this.getST(this.iStack), this.getST(0))); - } +/** + * FDIVsr() + * + * @this {FPUX86} + */ +FPUX86.FDIVsr = function() +{ + this.setST(0, this.doDivide(this.getST(0), this.getSRFromEA())); +}; - /** - * FDIVPsti() - * - * Encoding 0xDE,0xF8-0xFF ("FDIVP ST(i),ST"): ST(i) <- ST(i) / ST(0), POP - * - * @this {FPUX86} - */ - static FDIVPsti() - { - if (this.setST(this.iStack, this.doDivide(this.getST(this.iStack), this.getST(0)))) this.popValue(); - } +/** + * FDIVst() + * + * Encoding 0xD8,0xF0-0xF7 ("FDIV ST,ST(i)"): ST(0) <- ST(0) / ST(i) + * + * @this {FPUX86} + */ +FPUX86.FDIVst = function() +{ + this.setST(0, this.doDivide(this.getST(0), this.getST(this.iStack))); +}; - /** - * FDIVRlr() - * - * @this {FPUX86} - */ - static FDIVRlr() - { - this.setST(0, this.doDivide(this.getLRFromEA(), this.getST(0))); - } +/** + * FDIVsti() + * + * Encoding 0xDC,0xF8-0xFF ("FDIV ST(i),ST"): ST(i) <- ST(i) / ST(0) + * + * @this {FPUX86} + */ +FPUX86.FDIVsti = function() +{ + this.setST(this.iStack, this.doDivide(this.getST(this.iStack), this.getST(0))); +}; - /** - * FDIVRsr() - * - * @this {FPUX86} - */ - static FDIVRsr() - { - this.setST(0, this.doDivide(this.getSRFromEA(), this.getST(0))); - } +/** + * FDIVPsti() + * + * Encoding 0xDE,0xF8-0xFF ("FDIVP ST(i),ST"): ST(i) <- ST(i) / ST(0), POP + * + * @this {FPUX86} + */ +FPUX86.FDIVPsti = function() +{ + if (this.setST(this.iStack, this.doDivide(this.getST(this.iStack), this.getST(0)))) this.popValue(); +}; - /** - * FDIVRst() - * - * Encoding 0xD8,0xF8-0xFF ("FDIVR ST,ST(i)"): ST(0) <- ST(i) / ST(0) - * - * @this {FPUX86} - */ - static FDIVRst() - { - this.setST(0, this.doDivide(this.getST(this.iStack), this.getST(0))); - } +/** + * FDIVRlr() + * + * @this {FPUX86} + */ +FPUX86.FDIVRlr = function() +{ + this.setST(0, this.doDivide(this.getLRFromEA(), this.getST(0))); +}; - /** - * FDIVRsti() - * - * Encoding 0xDC,0xF0-0xF7 ("FDIVR ST(i),ST"): ST(i) <- ST(0) / ST(i) - * - * @this {FPUX86} - */ - static FDIVRsti() - { - this.setST(this.iStack, this.doDivide(this.getST(0), this.getST(this.iStack))); - } +/** + * FDIVRsr() + * + * @this {FPUX86} + */ +FPUX86.FDIVRsr = function() +{ + this.setST(0, this.doDivide(this.getSRFromEA(), this.getST(0))); +}; - /** - * FDIVRPsti() - * - * Encoding 0xDE,0xF0-0xE7 ("FDIVRP ST(i),ST"): ST(i) <- ST(0) / ST(i), POP - * - * @this {FPUX86} - */ - static FDIVRPsti() - { - if (this.setST(this.iStack, this.doDivide(this.getST(0), this.getST(this.iStack)))) this.popValue(); - } +/** + * FDIVRst() + * + * Encoding 0xD8,0xF8-0xFF ("FDIVR ST,ST(i)"): ST(0) <- ST(i) / ST(0) + * + * @this {FPUX86} + */ +FPUX86.FDIVRst = function() +{ + this.setST(0, this.doDivide(this.getST(this.iStack), this.getST(0))); +}; - /** - * FENI8087() - * - * @this {FPUX86} - */ - static FENI8087() - { - if (this.isModel(X86.FPU.MODEL_8087)) { - this.regControl &= ~X86.FPU.CONTROL.IEM; - } - } +/** + * FDIVRsti() + * + * Encoding 0xDC,0xF0-0xF7 ("FDIVR ST(i),ST"): ST(i) <- ST(0) / ST(i) + * + * @this {FPUX86} + */ +FPUX86.FDIVRsti = function() +{ + this.setST(this.iStack, this.doDivide(this.getST(0), this.getST(this.iStack))); +}; - /** - * FFREEsti() - * - * @this {FPUX86} - */ - static FFREEsti() - { - this.setTag(this.iST, X86.FPU.TAGS.EMPTY); - } +/** + * FDIVRPsti() + * + * Encoding 0xDE,0xF0-0xE7 ("FDIVRP ST(i),ST"): ST(i) <- ST(0) / ST(i), POP + * + * @this {FPUX86} + */ +FPUX86.FDIVRPsti = function() +{ + if (this.setST(this.iStack, this.doDivide(this.getST(0), this.getST(this.iStack)))) this.popValue(); +}; - /** - * FFREEP8087() - * - * NOTE: This is used with an encoding (0xDF,0xC0-0xC7) that was valid for the 8087 and 80287 - * but may no longer be valid as of the 80387. Also, if the older documentation is to be believed, - * this instruction has no modern counterpart, as FFREE doesn't pop the stack. - * - * @this {FPUX86} - */ - static FFREEP8087() - { - this.opObsolete(); - FPUX86.FFREEsti.call(this); - this.popValue(); +/** + * FENI8087() + * + * @this {FPUX86} + */ +FPUX86.FENI8087 = function() +{ + if (this.isModel(X86.FPU.MODEL_8087)) { + this.regControl &= ~X86.FPU.CONTROL.IEM; } +}; - /** - * FIADD16() - * - * @this {FPUX86} - */ - static FIADD16() - { - this.setST(0, this.doAdd(this.getST(0), this.getWIFromEA())); - } +/** + * FFREEsti() + * + * @this {FPUX86} + */ +FPUX86.FFREEsti = function() +{ + this.setTag(this.iST, X86.FPU.TAGS.EMPTY); +}; - /** - * FIADD32() - * - * @this {FPUX86} - */ - static FIADD32() - { - this.setST(0, this.doAdd(this.getST(0), this.getSIFromEA())); - } +/** + * FFREEP8087() + * + * NOTE: This is used with an encoding (0xDF,0xC0-0xC7) that was valid for the 8087 and 80287 + * but may no longer be valid as of the 80387. Also, if the older documentation is to be believed, + * this instruction has no modern counterpart, as FFREE doesn't pop the stack. + * + * @this {FPUX86} + */ +FPUX86.FFREEP8087 = function() +{ + this.opObsolete(); + FPUX86.FFREEsti.call(this); + this.popValue(); +}; - /** - * FICOM16() - * - * @this {FPUX86} - */ - static FICOM16() - { - this.doCompare(this.getST(0), this.getWIFromEA()); - } +/** + * FIADD16() + * + * @this {FPUX86} + */ +FPUX86.FIADD16 = function() +{ + this.setST(0, this.doAdd(this.getST(0), this.getWIFromEA())); +}; - /** - * FICOM32() - * - * @this {FPUX86} - */ - static FICOM32() - { - this.doCompare(this.getST(0), this.getSIFromEA()); - } +/** + * FIADD32() + * + * @this {FPUX86} + */ +FPUX86.FIADD32 = function() +{ + this.setST(0, this.doAdd(this.getST(0), this.getSIFromEA())); +}; - /** - * FICOMP16() - * - * @this {FPUX86} - */ - static FICOMP16() - { - if (this.doCompare(this.getST(0), this.getWIFromEA())) this.popValue(); - } +/** + * FICOM16() + * + * @this {FPUX86} + */ +FPUX86.FICOM16 = function() +{ + this.doCompare(this.getST(0), this.getWIFromEA()); +}; - /** - * FICOMP32() - * - * @this {FPUX86} - */ - static FICOMP32() - { - if (this.doCompare(this.getST(0), this.getSIFromEA())) this.popValue(); - } +/** + * FICOM32() + * + * @this {FPUX86} + */ +FPUX86.FICOM32 = function() +{ + this.doCompare(this.getST(0), this.getSIFromEA()); +}; - /** - * FIDIV16() - * - * @this {FPUX86} - */ - static FIDIV16() - { - this.setST(0, this.doDivide(this.getST(0), this.getWIFromEA())); - } +/** + * FICOMP16() + * + * @this {FPUX86} + */ +FPUX86.FICOMP16 = function() +{ + if (this.doCompare(this.getST(0), this.getWIFromEA())) this.popValue(); +}; - /** - * FIDIV32() - * - * @this {FPUX86} - */ - static FIDIV32() - { - this.setST(0, this.doDivide(this.getST(0), this.getSIFromEA())); - } +/** + * FICOMP32() + * + * @this {FPUX86} + */ +FPUX86.FICOMP32 = function() +{ + if (this.doCompare(this.getST(0), this.getSIFromEA())) this.popValue(); +}; - /** - * FIDIVR16() - * - * @this {FPUX86} - */ - static FIDIVR16() - { - this.setST(0, this.doDivide(this.getWIFromEA(), this.getST(0))); - } +/** + * FIDIV16() + * + * @this {FPUX86} + */ +FPUX86.FIDIV16 = function() +{ + this.setST(0, this.doDivide(this.getST(0), this.getWIFromEA())); +}; - /** - * FIDIVR32() - * - * @this {FPUX86} - */ - static FIDIVR32() - { - this.setST(0, this.doDivide(this.getSIFromEA(), this.getST(0))); - } +/** + * FIDIV32() + * + * @this {FPUX86} + */ +FPUX86.FIDIV32 = function() +{ + this.setST(0, this.doDivide(this.getST(0), this.getSIFromEA())); +}; - /** - * FILD16() - * - * @this {FPUX86} - */ - static FILD16() - { - this.pushValue(this.getWIFromEA()); - } +/** + * FIDIVR16() + * + * @this {FPUX86} + */ +FPUX86.FIDIVR16 = function() +{ + this.setST(0, this.doDivide(this.getWIFromEA(), this.getST(0))); +}; - /** - * FILD32() - * - * @this {FPUX86} - */ - static FILD32() - { - this.pushValue(this.getSIFromEA()); - } +/** + * FIDIVR32() + * + * @this {FPUX86} + */ +FPUX86.FIDIVR32 = function() +{ + this.setST(0, this.doDivide(this.getSIFromEA(), this.getST(0))); +}; - /** - * FILD64() - * - * @this {FPUX86} - */ - static FILD64() - { - this.pushValue(this.getLIFromEA()); - } +/** + * FILD16() + * + * @this {FPUX86} + */ +FPUX86.FILD16 = function() +{ + this.pushValue(this.getWIFromEA()); +}; - /** - * FIMUL16() - * - * @this {FPUX86} - */ - static FIMUL16() - { - this.setST(0, this.doMultiply(this.getST(0), this.getWIFromEA())); - } +/** + * FILD32() + * + * @this {FPUX86} + */ +FPUX86.FILD32 = function() +{ + this.pushValue(this.getSIFromEA()); +}; - /** - * FIMUL32() - * - * @this {FPUX86} - */ - static FIMUL32() - { - this.setST(0, this.doMultiply(this.getST(0), this.getSIFromEA())); - } +/** + * FILD64() + * + * @this {FPUX86} + */ +FPUX86.FILD64 = function() +{ + this.pushValue(this.getLIFromEA()); +}; - /** - * FINCSTP() - * - * @this {FPUX86} - */ - static FINCSTP() - { - this.iST = (this.iST + 1) & 0x7; - this.regStatus &= ~X86.FPU.STATUS.C1; - } +/** + * FIMUL16() + * + * @this {FPUX86} + */ +FPUX86.FIMUL16 = function() +{ + this.setST(0, this.doMultiply(this.getST(0), this.getWIFromEA())); +}; - /** - * FINIT() - * - * @this {FPUX86} - */ - static FINIT() - { - this.resetFPU(); - } +/** + * FIMUL32() + * + * @this {FPUX86} + */ +FPUX86.FIMUL32 = function() +{ + this.setST(0, this.doMultiply(this.getST(0), this.getSIFromEA())); +}; - /** - * FIST16() - * - * @this {FPUX86} - */ - static FIST16() - { - if (this.getWI(0)) this.setEAFromWI(); - } +/** + * FINCSTP() + * + * @this {FPUX86} + */ +FPUX86.FINCSTP = function() +{ + this.iST = (this.iST + 1) & 0x7; + this.regStatus &= ~X86.FPU.STATUS.C1; +}; - /** - * FIST32() - * - * @this {FPUX86} - */ - static FIST32() - { - if (this.getSI(0)) this.setEAFromSI(); - } +/** + * FINIT() + * + * @this {FPUX86} + */ +FPUX86.FINIT = function() +{ + this.resetFPU(); +}; - /** - * FISTP16() - * - * @this {FPUX86} - */ - static FISTP16() - { - if (this.getWI(0)) { - this.setEAFromWI(); - this.popValue(); - } - } +/** + * FIST16() + * + * @this {FPUX86} + */ +FPUX86.FIST16 = function() +{ + if (this.getWI(0)) this.setEAFromWI(); +}; - /** - * FISTP32() - * - * @this {FPUX86} - */ - static FISTP32() - { - if (this.getSI(0)) { - this.setEAFromSI(); - this.popValue(); - } - } +/** + * FIST32() + * + * @this {FPUX86} + */ +FPUX86.FIST32 = function() +{ + if (this.getSI(0)) this.setEAFromSI(); +}; - /** - * FISTP64() - * - * @this {FPUX86} - */ - static FISTP64() - { - if (this.getLI(0)) { - this.setEAFromLI(); - this.popValue(); - } +/** + * FISTP16() + * + * @this {FPUX86} + */ +FPUX86.FISTP16 = function() +{ + if (this.getWI(0)) { + this.setEAFromWI(); + this.popValue(); } +}; - /** - * FISUB16() - * - * @this {FPUX86} - */ - static FISUB16() - { - this.setST(0, this.doSubtract(this.getST(0), this.getWIFromEA())); +/** + * FISTP32() + * + * @this {FPUX86} + */ +FPUX86.FISTP32 = function() +{ + if (this.getSI(0)) { + this.setEAFromSI(); + this.popValue(); } +}; - /** - * FISUB32() - * - * @this {FPUX86} - */ - static FISUB32() - { - this.setST(0, this.doSubtract(this.getST(0), this.getSIFromEA())); +/** + * FISTP64() + * + * @this {FPUX86} + */ +FPUX86.FISTP64 = function() +{ + if (this.getLI(0)) { + this.setEAFromLI(); + this.popValue(); } +}; - /** - * FISUBR16() - * - * @this {FPUX86} - */ - static FISUBR16() - { - this.setST(0, this.doSubtract(this.getWIFromEA(), this.getST(0))); - } +/** + * FISUB16() + * + * @this {FPUX86} + */ +FPUX86.FISUB16 = function() +{ + this.setST(0, this.doSubtract(this.getST(0), this.getWIFromEA())); +}; - /** - * FISUBR32() - * - * @this {FPUX86} - */ - static FISUBR32() - { - this.setST(0, this.doSubtract(this.getSIFromEA(), this.getST(0))); - } +/** + * FISUB32() + * + * @this {FPUX86} + */ +FPUX86.FISUB32 = function() +{ + this.setST(0, this.doSubtract(this.getST(0), this.getSIFromEA())); +}; - /** - * FLDlr() - * - * The FLD instruction loads the source operand, converts it to temporary real format (if required), - * and pushes the resulting value onto the floating-point stack. - * - * The load operation is accomplished by decrementing the top-of-stack pointer (TOP) and copying the - * source operand to the new stack top. If the source operand is a float ing-point register, the index of - * the register is taken before TOP is changed. The source operand may also be a short real, long real, - * or temporary real memory operand. Short real and long real operands are converted automatically. - * - * Note that coding the instruction FLD ST(0) duplicates the value at the stack top. - * - * On the 8087 and 80287, the FLD real80 instruction will raise the denormal exception if the memory - * operand is a denormal. The 80287XL and later coprocessors will not, since the operation is not arithmetic. - * - * On the 8087 and 80287, a denormal will be converted to an unnormal by FLD; on the 80287XL and later - * coprocessors, the number will be converted to temporary real. If the next instruction is an FXTRACT or FXAM, - * the 8087/80827 and 80287XL/80387/ 80486 results will be different. - * - * On the 8087 and 80287, the FLD real32 and FLD real64 instructions will not raise an exception when loading - * a signaling NaN; on the 80287XL and later coprocessors, loading a signaling NaN raises the invalid operation - * exception. - * - * @this {FPUX86} - */ - static FLDlr() - { - this.pushValue(this.getLRFromEA()); - } +/** + * FISUBR16() + * + * @this {FPUX86} + */ +FPUX86.FISUBR16 = function() +{ + this.setST(0, this.doSubtract(this.getWIFromEA(), this.getST(0))); +}; - /** - * FLDsr() - * - * @this {FPUX86} - */ - static FLDsr() - { - this.pushValue(this.getSRFromEA()); - } +/** + * FISUBR32() + * + * @this {FPUX86} + */ +FPUX86.FISUBR32 = function() +{ + this.setST(0, this.doSubtract(this.getSIFromEA(), this.getST(0))); +}; - /** - * FLDsti() - * - * @this {FPUX86} - */ - static FLDsti() - { - this.pushValue(this.getST(this.iStack)); - } +/** + * FLDlr() + * + * The FLD instruction loads the source operand, converts it to temporary real format (if required), + * and pushes the resulting value onto the floating-point stack. + * + * The load operation is accomplished by decrementing the top-of-stack pointer (TOP) and copying the + * source operand to the new stack top. If the source operand is a float ing-point register, the index of + * the register is taken before TOP is changed. The source operand may also be a short real, long real, + * or temporary real memory operand. Short real and long real operands are converted automatically. + * + * Note that coding the instruction FLD ST(0) duplicates the value at the stack top. + * + * On the 8087 and 80287, the FLD real80 instruction will raise the denormal exception if the memory + * operand is a denormal. The 80287XL and later coprocessors will not, since the operation is not arithmetic. + * + * On the 8087 and 80287, a denormal will be converted to an unnormal by FLD; on the 80287XL and later + * coprocessors, the number will be converted to temporary real. If the next instruction is an FXTRACT or FXAM, + * the 8087/80827 and 80287XL/80387/ 80486 results will be different. + * + * On the 8087 and 80287, the FLD real32 and FLD real64 instructions will not raise an exception when loading + * a signaling NaN; on the 80287XL and later coprocessors, loading a signaling NaN raises the invalid operation + * exception. + * + * @this {FPUX86} + */ +FPUX86.FLDlr = function() +{ + this.pushValue(this.getLRFromEA()); +}; - /** - * FLDtr() - * - * @this {FPUX86} - */ - static FLDtr() - { - this.pushValue(this.getLRFromTR(this.getTRFromEA())); - } +/** + * FLDsr() + * + * @this {FPUX86} + */ +FPUX86.FLDsr = function() +{ + this.pushValue(this.getSRFromEA()); +}; - /** - * FLDCW() - * - * @this {FPUX86} - */ - static FLDCW() - { - this.assert(this.cpu.regEA !== X86.ADDR_INVALID); - this.setControl(this.cpu.getShort(this.cpu.regEA)); - } +/** + * FLDsti() + * + * @this {FPUX86} + */ +FPUX86.FLDsti = function() +{ + this.pushValue(this.getST(this.iStack)); +}; - /** - * FLDENV() - * - * @this {FPUX86} - */ - static FLDENV() - { - this.assert(this.cpu.regEA !== X86.ADDR_INVALID); - this.loadEnv(this.cpu.regEA); - } +/** + * FLDtr() + * + * @this {FPUX86} + */ +FPUX86.FLDtr = function() +{ + this.pushValue(this.getLRFromTR(this.getTRFromEA())); +}; - /** - * FLD1() - * - * The FLD1 instruction loads the constant +1.0 from the NPX's constant ROM and pushes the value onto the - * floating-point stack. - * - * The constant is stored internally in temporary real format and is simply moved to the stack. - * - * See also: FLDLG2, FLDLN2, FLDL2E, FLDL2T, FLDPI, and FLD1. - * - * @this {FPUX86} - */ - static FLD1() - { - this.pushValue(1.0); - } +/** + * FLDCW() + * + * @this {FPUX86} + */ +FPUX86.FLDCW = function() +{ + this.assert(this.cpu.regEA !== X86.ADDR_INVALID); + this.setControl(this.cpu.getShort(this.cpu.regEA)); +}; - /** - * FLDL2T() - * - * The FLDL2T instruction loads the constant log2(10) from the NPX's constant ROM and pushes the value onto the - * floating-point stack. - * - * The constant is stored internally in temporary real format and is simply moved to the stack. - * - * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and - * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0), round down (toward - * -infinity), or round to nearest or even, the result will be the same as on the 8087 and 80287. If RC is set for - * round up (toward +infinity), the result will differ by one in the least significant bit of the mantissa. - * - * See also: FLDLG2, FLDLN2, FLDL2E, FLDPI, FLD1, and FLDZ. - * - * @this {FPUX86} - */ - static FLDL2T() - { - this.pushValue(FPUX86.regL2T); - } +/** + * FLDENV() + * + * @this {FPUX86} + */ +FPUX86.FLDENV = function() +{ + this.assert(this.cpu.regEA !== X86.ADDR_INVALID); + this.loadEnv(this.cpu.regEA); +}; - /** - * FLDL2E() - * - * The FLDL2E instruction loads the constant log2(e) from the NPX's constant ROM and pushes the value onto the - * floating-point stack. - * - * The constant is stored internally in temporary real format and is simply moved to the stack. - * - * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and - * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward - * -infinity), the result is the same as on the 8087 and 80827. If RC is set for round to nearest or even, or round - * up (toward +infinity), the result will differ by one in the least significant bit of the mantissa. - * - * See also: FLDLG2, FLDLN2, FLDL2T, FLDPI, FLD1, and FLDZ. - * - * @this {FPUX86} - */ - static FLDL2E() - { - this.pushValue(FPUX86.regL2E); - } +/** + * FLD1() + * + * The FLD1 instruction loads the constant +1.0 from the NPX's constant ROM and pushes the value onto the + * floating-point stack. + * + * The constant is stored internally in temporary real format and is simply moved to the stack. + * + * See also: FLDLG2, FLDLN2, FLDL2E, FLDL2T, FLDPI, and FLD1. + * + * @this {FPUX86} + */ +FPUX86.FLD1 = function() +{ + this.pushValue(1.0); +}; - /** - * FLDPI() - * - * The FLDPI instruction loads the constant Pi from the NPX's constant ROM and pushes the value onto the - * floating-point stack. - * - * The constant is stored internally in temporary real format and is simply moved to the stack. - * - * On the 8087 and 80287, rounding control is not in effect for the loading of these constants. On the 80287XL and - * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward - * -infinity), the result is the same as on the 8087 and 80827. If RC is set for round to nearest or even, or round - * up (toward +infinity), the result will differ by one in the least significant bit of the mantissa. - * - * See also: FLDLG2, FLDLN2, FLDL2E, FLDL2T, FLD1, and FLDZ. - * - * @this {FPUX86} - */ - static FLDPI() - { - this.pushValue(FPUX86.regPI); - } +/** + * FLDL2T() + * + * The FLDL2T instruction loads the constant log2(10) from the NPX's constant ROM and pushes the value onto the + * floating-point stack. + * + * The constant is stored internally in temporary real format and is simply moved to the stack. + * + * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and + * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0), round down (toward + * -infinity), or round to nearest or even, the result will be the same as on the 8087 and 80287. If RC is set for + * round up (toward +infinity), the result will differ by one in the least significant bit of the mantissa. + * + * See also: FLDLG2, FLDLN2, FLDL2E, FLDPI, FLD1, and FLDZ. + * + * @this {FPUX86} + */ +FPUX86.FLDL2T = function() +{ + this.pushValue(FPUX86.regL2T); +}; - /** - * FLDLG2() - * - * The FLDLG2 instruction loads the constant log10(2) from the NPX's constant ROM and pushes the value onto the - * floating-point stack. - * - * The constant is stored internally in temporary real format and is simply moved to the stack. - * - * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and - * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward - * -infinity), the result is the same as on the 8087 and 80827. If RC is set for round to nearest or even, or round - * up (toward +infinity), the result will differ by one in the least significant bit of the mantissa. - * - * See also: FLDLN2, FLDL2E, FLDL2T, FLDPI, FLD1, and FLDZ. - * - * @this {FPUX86} - */ - static FLDLG2() - { - this.pushValue(FPUX86.regLG2); - } +/** + * FLDL2E() + * + * The FLDL2E instruction loads the constant log2(e) from the NPX's constant ROM and pushes the value onto the + * floating-point stack. + * + * The constant is stored internally in temporary real format and is simply moved to the stack. + * + * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and + * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward + * -infinity), the result is the same as on the 8087 and 80827. If RC is set for round to nearest or even, or round + * up (toward +infinity), the result will differ by one in the least significant bit of the mantissa. + * + * See also: FLDLG2, FLDLN2, FLDL2T, FLDPI, FLD1, and FLDZ. + * + * @this {FPUX86} + */ +FPUX86.FLDL2E = function() +{ + this.pushValue(FPUX86.regL2E); +}; - /** - * FLDLN2() - * - * The FLDLN2 instruction loads the constant loge(2) from the NPX's constant ROM and pushes the value onto the - * floating-point stack. - * - * The constant is stored internally in temporary real format and is simply moved to the stack. - * - * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and - * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward - * -infinity), the result will be the same as on the 8087 and 80827. If RC is set for round to nearest or even, or - * round up (toward +infinity), the result will differ by one in the least significant bit of the mantissa. - * - * See also: FLDLG2, FLDL2E, FLDL2T, FLDPI, FLD1, and FLDZ. - * - * @this {FPUX86} - */ - static FLDLN2() - { - this.pushValue(FPUX86.regLN2); - } +/** + * FLDPI() + * + * The FLDPI instruction loads the constant Pi from the NPX's constant ROM and pushes the value onto the + * floating-point stack. + * + * The constant is stored internally in temporary real format and is simply moved to the stack. + * + * On the 8087 and 80287, rounding control is not in effect for the loading of these constants. On the 80287XL and + * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward + * -infinity), the result is the same as on the 8087 and 80827. If RC is set for round to nearest or even, or round + * up (toward +infinity), the result will differ by one in the least significant bit of the mantissa. + * + * See also: FLDLG2, FLDLN2, FLDL2E, FLDL2T, FLD1, and FLDZ. + * + * @this {FPUX86} + */ +FPUX86.FLDPI = function() +{ + this.pushValue(FPUX86.regPI); +}; - /** - * FLDZ() - * - * The FLDZ instruction loads the constant +0.0 from the NPX's constant ROM and pushes the value onto the - * floating-point stack. - * - * The constant is stored internally in temporary real format and is simply moved to the stack. - * - * See also: FLDLG2, FLDLN2, FLDL2E, FLDL2T, FLDPI, and FLD1. - * - * @this {FPUX86} - */ - static FLDZ() - { - this.pushValue(0.0); - } +/** + * FLDLG2() + * + * The FLDLG2 instruction loads the constant log10(2) from the NPX's constant ROM and pushes the value onto the + * floating-point stack. + * + * The constant is stored internally in temporary real format and is simply moved to the stack. + * + * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and + * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward + * -infinity), the result is the same as on the 8087 and 80827. If RC is set for round to nearest or even, or round + * up (toward +infinity), the result will differ by one in the least significant bit of the mantissa. + * + * See also: FLDLN2, FLDL2E, FLDL2T, FLDPI, FLD1, and FLDZ. + * + * @this {FPUX86} + */ +FPUX86.FLDLG2 = function() +{ + this.pushValue(FPUX86.regLG2); +}; - /** - * FMULlr() - * - * @this {FPUX86} - */ - static FMULlr() - { - this.setST(0, this.doMultiply(this.getST(0), this.getLRFromEA())); - } +/** + * FLDLN2() + * + * The FLDLN2 instruction loads the constant loge(2) from the NPX's constant ROM and pushes the value onto the + * floating-point stack. + * + * The constant is stored internally in temporary real format and is simply moved to the stack. + * + * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and + * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward + * -infinity), the result will be the same as on the 8087 and 80827. If RC is set for round to nearest or even, or + * round up (toward +infinity), the result will differ by one in the least significant bit of the mantissa. + * + * See also: FLDLG2, FLDL2E, FLDL2T, FLDPI, FLD1, and FLDZ. + * + * @this {FPUX86} + */ +FPUX86.FLDLN2 = function() +{ + this.pushValue(FPUX86.regLN2); +}; - /** - * FMULsr() - * - * Encoding 0xD8,reg=0x01 ("FMUL short-real"): ST(0) <- ST(0) * REAL32 - * - * @this {FPUX86} - */ - static FMULsr() - { - this.setST(0, this.doMultiply(this.getST(0), this.getSRFromEA())); - } +/** + * FLDZ() + * + * The FLDZ instruction loads the constant +0.0 from the NPX's constant ROM and pushes the value onto the + * floating-point stack. + * + * The constant is stored internally in temporary real format and is simply moved to the stack. + * + * See also: FLDLG2, FLDLN2, FLDL2E, FLDL2T, FLDPI, and FLD1. + * + * @this {FPUX86} + */ +FPUX86.FLDZ = function() +{ + this.pushValue(0.0); +}; - /** - * FMULst() - * - * @this {FPUX86} - */ - static FMULst() - { - this.setST(0, this.doMultiply(this.getST(0), this.getST(this.iStack))); - } +/** + * FMULlr() + * + * @this {FPUX86} + */ +FPUX86.FMULlr = function() +{ + this.setST(0, this.doMultiply(this.getST(0), this.getLRFromEA())); +}; - /** - * FMULsti() - * - * @this {FPUX86} - */ - static FMULsti() - { - this.setST(this.iStack, this.doMultiply(this.getST(this.iStack), this.getST(0))); - } +/** + * FMULsr() + * + * Encoding 0xD8,reg=0x01 ("FMUL short-real"): ST(0) <- ST(0) * REAL32 + * + * @this {FPUX86} + */ +FPUX86.FMULsr = function() +{ + this.setST(0, this.doMultiply(this.getST(0), this.getSRFromEA())); +}; - /** - * FMULPsti() - * - * @this {FPUX86} - */ - static FMULPsti() - { - if (this.setST(this.iStack, this.doMultiply(this.getST(this.iStack), this.getST(0)))) this.popValue(); - } +/** + * FMULst() + * + * @this {FPUX86} + */ +FPUX86.FMULst = function() +{ + this.setST(0, this.doMultiply(this.getST(0), this.getST(this.iStack))); +}; - /** - * FNOP() - * - * @this {FPUX86} - */ - static FNOP() - { - } +/** + * FMULsti() + * + * @this {FPUX86} + */ +FPUX86.FMULsti = function() +{ + this.setST(this.iStack, this.doMultiply(this.getST(this.iStack), this.getST(0))); +}; - /** - * FPATAN() - * - * FPATAN calculates the partial arctangent of ST(0) divided by ST(1): - * - * ST(1) = tan^-1( ST(1) / ST(0) ) - * - * On the 8087 and 80287, the arguments must satisfy the inequality 0 <= ST(1) < ST(0) < +infinity. - * On the 80287XL and later coprocessors, the range of the operands is unrestricted. The result is - * returned to ST(1), and the stack is popped, destroying both operands and leaving the result in ST(0). - * - * @this {FPUX86} - */ - static FPATAN() - { - if (this.setST(1, Math.atan2(this.getST(1), this.getST(0)))) this.popValue(); - } +/** + * FMULPsti() + * + * @this {FPUX86} + */ +FPUX86.FMULPsti = function() +{ + if (this.setST(this.iStack, this.doMultiply(this.getST(this.iStack), this.getST(0)))) this.popValue(); +}; - /** - * FPTAN() - * - * FPTAN calculates the partial tangent of ST(0): - * - * y / x = tan( ST(0) ) - * - * The result of the operation is a ratio. y replaces the argument on the stack, and x is pushed onto the stack, - * where it becomes the new ST(0). - * - * On the 8087 and 80287, the FPTAN function assumes that its argument is valid and in-range. No argument checking - * is performed. The value of ST(0) must satisfy the inequality -pi/4 <= ST(0) <= pi/4. In the case of an invalid - * argument, the result is undefined and no error is signaled. - * - * On the 80287XL and later coprocessors, if value of ST(0) satisfies the condition -2^63 < ST(0) < 2^63, it will - * automatically be reduced to within range. If the operand is outside this range, however, C2 is set to 1 to indicate - * that the function is incomplete, and ST(0) is left unchanged. - * - * The 80287XL, 80387, and 80486 always push a value of +1.0 for x. The value of x pushed by the 8087 and 80287 may be - * any real number. In either case, the ratio is the same. The cotangent can be calculated by executing FDIVR immediately - * after FPTAN. The following code will leave the 8087 and 80287 in the same state as the later coprocessors: - * - * FDIV - * FLD1 - * - * ST(7) must be empty before this instruction is executed to avoid an invalid operation exception. If the invalid - * operation exception is masked, the 8087 and 80287 leave the original operand unchanged, but push it to ST(1). On the - * 80287XL and later coprocessors, both ST(0) and ST(1) will contain quiet NaNs. On the 80287XL and later coprocessors, - * if condition code bit C2 is 0 and the precision exception is raised, then C1=1 if the last bit was rounded up. C1 is - * undefined for the 8087 and 80287. - * - * @this {FPUX86} - */ - static FPTAN() - { - if (this.setST(0, Math.tan(this.getST(0)))) this.pushValue(1.0); - } +/** + * FNOP() + * + * @this {FPUX86} + */ +FPUX86.FNOP = function() +{ +}; - /** - * FPREM() - * - * FPREM performs modulo division of ST(0) by ST(1) and returns the result to ST(0). - * - * The FPREM instruction is used to reduce the real operand in ST(0) to a value whose magnitude is less than the - * magnitude of ST(1). FPREM produces an exact result, so the precision exception is never raised and the rounding - * control has no effect. The sign of the remainder is the same as the sign of the original operand. - * - * The remaindering operation is performed by iterative scaled subtractions and can reduce the exponent of ST(0) by - * no more than 63 in one execution. If the remainder is less than ST(1) (the modulus), the function is complete and - * C2 in the status word is cleared. - * - * If the modulo function is incomplete, C2 is set to 1, and the result in ST(0) is termed the partial remainder. - * C2 can be inspected by storing the status word and re-executing the instruction until C2 is clear. Alternately, - * ST(0) can be compared to ST(1). If ST(0) > ST(1), then FPREM must be executed again. If ST(0) = ST(1), then the - * remainder is 0. - * - * FPREM is important for reducing arguments to the periodic transcendental functions such as FPTAN. Because FPREM - * produces an exact result, no round-off error is introduced into the calculation. - * - * When reduction is complete, the three least-significant bits of the quotient are stored in the condition code bits - * C3, C1, and C0, respectively. When arguments to the tangent function are reduced by pi/4, this result can be used - * to identify the octant that contained the original angle. - * - * The FPREM function operates differently than specified by the IEEE 754 standard when rounding the quotient to form - * a partial remainder (see the algorithm). The FPREM1 function (80287XL and up) is provided for compatibility with - * that standard. - * - * The FPREM instruction can also be used to normalize ST(0). If ST(0) is unnormal and ST(1) is greater than ST(0), - * FPREM will normalize ST(0). On the 8087 and 80287, operation on a denormal operand raises the invalid operation - * exception. Underflow is not possible. On the 80287XL and later coprocessors, operation on a denormal is supported - * and an underflow exception can occur. - * - * ALGORITHM: - * - * t = EXPONENT(ST) - EXPONENT(ST(1)) - * IF (t < 64) THEN - * q = R0UND(ST(0) / ST(1), CHOP) - * ST(0) = ST(0) - (ST(1) * q) - * C2 = 0 - * C0 = BIT 2 of q - * C1 = BIT 1 of q - * C3 = BIT 0 of q - * ELSE - * n = a number between 32 and 63 - * q = ROUND((ST(0) / ST(1)) / 2^(t-n), CHOP) - * ST(0) = ST(0) - (ST(1) * q * 2^(t-n)) - * C2 = 1 - * ENDIF - * - * TODO: Determine the extent to which the JavaScript MOD operator differs from the above algorithm. - * - * ERRATA: On the 8087 and 80287, the condition code bits C3, C1, and C0 are incorrect when performing a reduction of - * 64^n + m, where n >= 1, and m=1 or m=2. A bug fix should be implemented in software. - * - * @this {FPUX86} - */ - static FPREM() - { - this.setST(0, this.getST(0) % this.getST(1)); - } +/** + * FPATAN() + * + * FPATAN calculates the partial arctangent of ST(0) divided by ST(1): + * + * ST(1) = tan^-1( ST(1) / ST(0) ) + * + * On the 8087 and 80287, the arguments must satisfy the inequality 0 <= ST(1) < ST(0) < +infinity. + * On the 80287XL and later coprocessors, the range of the operands is unrestricted. The result is + * returned to ST(1), and the stack is popped, destroying both operands and leaving the result in ST(0). + * + * @this {FPUX86} + */ +FPUX86.FPATAN = function() +{ + if (this.setST(1, Math.atan2(this.getST(1), this.getST(0)))) this.popValue(); +}; - /** - * FRSTOR() - * - * @this {FPUX86} - */ - static FRSTOR() - { - var cpu = this.cpu; - var addr = this.loadEnv(cpu.regEA); - var a = this.intTmpTR; - for (var i = 0; i < this.regStack.length; i++) { - a[0] = cpu.getLong(addr); - a[1] = cpu.getLong(addr += 4); - a[2] = cpu.getShort(addr += 4); - this.setTR(i, a); - addr += 2; - } - } +/** + * FPTAN() + * + * FPTAN calculates the partial tangent of ST(0): + * + * y / x = tan( ST(0) ) + * + * The result of the operation is a ratio. y replaces the argument on the stack, and x is pushed onto the stack, + * where it becomes the new ST(0). + * + * On the 8087 and 80287, the FPTAN function assumes that its argument is valid and in-range. No argument checking + * is performed. The value of ST(0) must satisfy the inequality -pi/4 <= ST(0) <= pi/4. In the case of an invalid + * argument, the result is undefined and no error is signaled. + * + * On the 80287XL and later coprocessors, if value of ST(0) satisfies the condition -2^63 < ST(0) < 2^63, it will + * automatically be reduced to within range. If the operand is outside this range, however, C2 is set to 1 to indicate + * that the function is incomplete, and ST(0) is left unchanged. + * + * The 80287XL, 80387, and 80486 always push a value of +1.0 for x. The value of x pushed by the 8087 and 80287 may be + * any real number. In either case, the ratio is the same. The cotangent can be calculated by executing FDIVR immediately + * after FPTAN. The following code will leave the 8087 and 80287 in the same state as the later coprocessors: + * + * FDIV + * FLD1 + * + * ST(7) must be empty before this instruction is executed to avoid an invalid operation exception. If the invalid + * operation exception is masked, the 8087 and 80287 leave the original operand unchanged, but push it to ST(1). On the + * 80287XL and later coprocessors, both ST(0) and ST(1) will contain quiet NaNs. On the 80287XL and later coprocessors, + * if condition code bit C2 is 0 and the precision exception is raised, then C1=1 if the last bit was rounded up. C1 is + * undefined for the 8087 and 80287. + * + * @this {FPUX86} + */ +FPUX86.FPTAN = function() +{ + if (this.setST(0, Math.tan(this.getST(0)))) this.pushValue(1.0); +}; - /** - * FRNDINT() - * - * @this {FPUX86} - */ - static FRNDINT() - { - this.setST(0, this.roundValue(this.getST(0), FPUX86.MAX_INT64)); - } +/** + * FPREM() + * + * FPREM performs modulo division of ST(0) by ST(1) and returns the result to ST(0). + * + * The FPREM instruction is used to reduce the real operand in ST(0) to a value whose magnitude is less than the + * magnitude of ST(1). FPREM produces an exact result, so the precision exception is never raised and the rounding + * control has no effect. The sign of the remainder is the same as the sign of the original operand. + * + * The remaindering operation is performed by iterative scaled subtractions and can reduce the exponent of ST(0) by + * no more than 63 in one execution. If the remainder is less than ST(1) (the modulus), the function is complete and + * C2 in the status word is cleared. + * + * If the modulo function is incomplete, C2 is set to 1, and the result in ST(0) is termed the partial remainder. + * C2 can be inspected by storing the status word and re-executing the instruction until C2 is clear. Alternately, + * ST(0) can be compared to ST(1). If ST(0) > ST(1), then FPREM must be executed again. If ST(0) = ST(1), then the + * remainder is 0. + * + * FPREM is important for reducing arguments to the periodic transcendental functions such as FPTAN. Because FPREM + * produces an exact result, no round-off error is introduced into the calculation. + * + * When reduction is complete, the three least-significant bits of the quotient are stored in the condition code bits + * C3, C1, and C0, respectively. When arguments to the tangent function are reduced by pi/4, this result can be used + * to identify the octant that contained the original angle. + * + * The FPREM function operates differently than specified by the IEEE 754 standard when rounding the quotient to form + * a partial remainder (see the algorithm). The FPREM1 function (80287XL and up) is provided for compatibility with + * that standard. + * + * The FPREM instruction can also be used to normalize ST(0). If ST(0) is unnormal and ST(1) is greater than ST(0), + * FPREM will normalize ST(0). On the 8087 and 80287, operation on a denormal operand raises the invalid operation + * exception. Underflow is not possible. On the 80287XL and later coprocessors, operation on a denormal is supported + * and an underflow exception can occur. + * + * ALGORITHM: + * + * t = EXPONENT(ST) - EXPONENT(ST(1)) + * IF (t < 64) THEN + * q = R0UND(ST(0) / ST(1), CHOP) + * ST(0) = ST(0) - (ST(1) * q) + * C2 = 0 + * C0 = BIT 2 of q + * C1 = BIT 1 of q + * C3 = BIT 0 of q + * ELSE + * n = a number between 32 and 63 + * q = ROUND((ST(0) / ST(1)) / 2^(t-n), CHOP) + * ST(0) = ST(0) - (ST(1) * q * 2^(t-n)) + * C2 = 1 + * ENDIF + * + * TODO: Determine the extent to which the JavaScript MOD operator differs from the above algorithm. + * + * ERRATA: On the 8087 and 80287, the condition code bits C3, C1, and C0 are incorrect when performing a reduction of + * 64^n + m, where n >= 1, and m=1 or m=2. A bug fix should be implemented in software. + * + * @this {FPUX86} + */ +FPUX86.FPREM = function() +{ + this.setST(0, this.getST(0) % this.getST(1)); +}; - /** - * FSAVE() - * - * @this {FPUX86} - */ - static FSAVE() - { - var cpu = this.cpu; - var addr = this.saveEnv(cpu.regEA); - for (var i = 0; i < this.regStack.length; i++) { - var a = this.getTR(i, true); - cpu.setLong(addr, a[0]); - cpu.setLong(addr += 4, a[1]); - cpu.setShort(addr += 4, a[2]); - addr += 2; - } - this.resetFPU(); +/** + * FRSTOR() + * + * @this {FPUX86} + */ +FPUX86.FRSTOR = function() +{ + var cpu = this.cpu; + var addr = this.loadEnv(cpu.regEA); + var a = this.intTmpTR; + for (var i = 0; i < this.regStack.length; i++) { + a[0] = cpu.getLong(addr); + a[1] = cpu.getLong(addr += 4); + a[2] = cpu.getShort(addr += 4); + this.setTR(i, a); + addr += 2; } +}; - /** - * FSCALE() - * - * FSCALE interprets the value in ST(1) as an integer and adds this number to the exponent of the number in ST(0). - * - * The FSCALE instruction provides a means of quickly performing multiplication or division by powers of two. - * This operation is often required when scaling array indexes. - * - * On the 8087 and 80287, FSCALE assumes that the scale factor in ST(1) is an integer that satisfies the inequality - * -2^15 <= ST(1) < +2^15. If ST(1) is not an integer value, the value is chopped to the next smallest integer in - * magnitude (chopped toward zero). If the value is out of range or 0 < ST(1) < 1, FSCALE produces an undefined - * result and doesn't signal an exception. Typically, the value in ST(0) is unchanged but should not be depended on. - * - * On the 80287XL and later coprocessors, there is no limit on the range of the scale factor in ST(1). The value in - * ST(1) is still chopped toward zero. If ST(1) is 0, ST(0) is unchanged. - * - * @this {FPUX86} - */ - static FSCALE() - { - var x = this.getST(0); - var y = this.getST(1); - if (x != null && y != null) this.setST(0, x * Math.pow(2, this.truncateValue(y))); - } +/** + * FRNDINT() + * + * @this {FPUX86} + */ +FPUX86.FRNDINT = function() +{ + this.setST(0, this.roundValue(this.getST(0), FPUX86.MAX_INT64)); +}; - /** - * FSETPM287() - * - * @this {FPUX86} - */ - static FSETPM287() - { - if (this.isModel(X86.FPU.MODEL_80287)) { - this.opUnimplemented(); - } - } +/** + * FSAVE() + * + * @this {FPUX86} + */ +FPUX86.FSAVE = function() +{ + var cpu = this.cpu; + var addr = this.saveEnv(cpu.regEA); + for (var i = 0; i < this.regStack.length; i++) { + var a = this.getTR(i, true); + cpu.setLong(addr, a[0]); + cpu.setLong(addr += 4, a[1]); + cpu.setShort(addr += 4, a[2]); + addr += 2; + } + this.resetFPU(); +}; - /** - * FSINCOS387() - * - * @this {FPUX86} - */ - static FSINCOS387() - { - if (this.isAtLeastModel(X86.FPU.MODEL_80287XL)) { - this.opUnimplemented(); - } - } +/** + * FSCALE() + * + * FSCALE interprets the value in ST(1) as an integer and adds this number to the exponent of the number in ST(0). + * + * The FSCALE instruction provides a means of quickly performing multiplication or division by powers of two. + * This operation is often required when scaling array indexes. + * + * On the 8087 and 80287, FSCALE assumes that the scale factor in ST(1) is an integer that satisfies the inequality + * -2^15 <= ST(1) < +2^15. If ST(1) is not an integer value, the value is chopped to the next smallest integer in + * magnitude (chopped toward zero). If the value is out of range or 0 < ST(1) < 1, FSCALE produces an undefined + * result and doesn't signal an exception. Typically, the value in ST(0) is unchanged but should not be depended on. + * + * On the 80287XL and later coprocessors, there is no limit on the range of the scale factor in ST(1). The value in + * ST(1) is still chopped toward zero. If ST(1) is 0, ST(0) is unchanged. + * + * @this {FPUX86} + */ +FPUX86.FSCALE = function() +{ + var x = this.getST(0); + var y = this.getST(1); + if (x != null && y != null) this.setST(0, x * Math.pow(2, this.truncateValue(y))); +}; - /** - * FSQRT() - * - * @this {FPUX86} - */ - static FSQRT() - { - this.setST(0, this.doSquareRoot(this.getST(0))); +/** + * FSETPM287() + * + * @this {FPUX86} + */ +FPUX86.FSETPM287 = function() +{ + if (this.isModel(X86.FPU.MODEL_80287)) { + this.opUnimplemented(); } +}; - /** - * FSTlr() - * - * @this {FPUX86} - */ - static FSTlr() - { - if (this.getLR(0)) this.setEAFromLR(); +/** + * FSINCOS387() + * + * @this {FPUX86} + */ +FPUX86.FSINCOS387 = function() +{ + if (this.isAtLeastModel(X86.FPU.MODEL_80287XL)) { + this.opUnimplemented(); } +}; - /** - * FSTsr() - * - * @this {FPUX86} - */ - static FSTsr() - { - if (this.getSR(0)) this.setEAFromSR(); - } +/** + * FSQRT() + * + * @this {FPUX86} + */ +FPUX86.FSQRT = function() +{ + this.setST(0, this.doSquareRoot(this.getST(0))); +}; - /** - * FSTsti() - * - * @this {FPUX86} - */ - static FSTsti() - { - this.setST(this.iStack, this.getST(0)); - } +/** + * FSTlr() + * + * @this {FPUX86} + */ +FPUX86.FSTlr = function() +{ + if (this.getLR(0)) this.setEAFromLR(); +}; - /** - * FSTENV() - * - * @this {FPUX86} - */ - static FSTENV() - { - this.assert(this.cpu.regEA !== X86.ADDR_INVALID); - this.saveEnv(this.cpu.regEA); - this.regControl |= X86.FPU.CONTROL.EXC; // mask all exceptions (but do not set IEM) - } +/** + * FSTsr() + * + * @this {FPUX86} + */ +FPUX86.FSTsr = function() +{ + if (this.getSR(0)) this.setEAFromSR(); +}; - /** - * FSTPlr() - * - * @this {FPUX86} - */ - static FSTPlr() - { - if (this.getLR(0)) { - this.setEAFromLR(); - this.popValue(); - } - } +/** + * FSTsti() + * + * @this {FPUX86} + */ +FPUX86.FSTsti = function() +{ + this.setST(this.iStack, this.getST(0)); +}; - /** - * FSTPsr() - * - * @this {FPUX86} - */ - static FSTPsr() - { - if (this.getSR(0)) { - this.setEAFromSR(); - this.popValue(); - } - } +/** + * FSTENV() + * + * @this {FPUX86} + */ +FPUX86.FSTENV = function() +{ + this.assert(this.cpu.regEA !== X86.ADDR_INVALID); + this.saveEnv(this.cpu.regEA); + this.regControl |= X86.FPU.CONTROL.EXC; // mask all exceptions (but do not set IEM) +}; - /** - * FSTPsti() - * - * @this {FPUX86} - */ - static FSTPsti() - { - if (this.setST(this.iStack, this.getST(0))) this.popValue(); +/** + * FSTPlr() + * + * @this {FPUX86} + */ +FPUX86.FSTPlr = function() +{ + if (this.getLR(0)) { + this.setEAFromLR(); + this.popValue(); } +}; - /** - * FSTP8087() - * - * NOTE: This is used with encodings (0xD9,0xD8-0xDF and 0xDF,0xD0-0xDF) that were valid for the 8087 and 80287 - * but may no longer be valid as of the 80387. - * - * @this {FPUX86} - */ - static FSTP8087() - { - this.opObsolete(); - FPUX86.FSTPsti.call(this); +/** + * FSTPsr() + * + * @this {FPUX86} + */ +FPUX86.FSTPsr = function() +{ + if (this.getSR(0)) { + this.setEAFromSR(); + this.popValue(); } +}; - /** - * FSTPtr() - * - * @this {FPUX86} - */ - static FSTPtr() - { - if (this.getTR(0)) { - this.setEAFromTR(); - this.popValue(); - } - } +/** + * FSTPsti() + * + * @this {FPUX86} + */ +FPUX86.FSTPsti = function() +{ + if (this.setST(this.iStack, this.getST(0))) this.popValue(); +}; - /** - * FSTCW() - * - * @this {FPUX86} - */ - static FSTCW() - { - this.assert(this.cpu.regEA !== X86.ADDR_INVALID); - this.cpu.setShort(this.cpu.regEA, this.regControl); - } +/** + * FSTP8087() + * + * NOTE: This is used with encodings (0xD9,0xD8-0xDF and 0xDF,0xD0-0xDF) that were valid for the 8087 and 80287 + * but may no longer be valid as of the 80387. + * + * @this {FPUX86} + */ +FPUX86.FSTP8087 = function() +{ + this.opObsolete(); + FPUX86.FSTPsti.call(this); +}; - /** - * FSTSW() - * - * @this {FPUX86} - */ - static FSTSW() - { - this.assert(this.cpu.regEA !== X86.ADDR_INVALID); - this.cpu.setShort(this.cpu.regEA, this.getStatus()); +/** + * FSTPtr() + * + * @this {FPUX86} + */ +FPUX86.FSTPtr = function() +{ + if (this.getTR(0)) { + this.setEAFromTR(); + this.popValue(); } +}; + +/** + * FSTCW() + * + * @this {FPUX86} + */ +FPUX86.FSTCW = function() +{ + this.assert(this.cpu.regEA !== X86.ADDR_INVALID); + this.cpu.setShort(this.cpu.regEA, this.regControl); +}; + +/** + * FSTSW() + * + * @this {FPUX86} + */ +FPUX86.FSTSW = function() +{ + this.assert(this.cpu.regEA !== X86.ADDR_INVALID); + this.cpu.setShort(this.cpu.regEA, this.getStatus()); +}; - /** - * FSTSWAX287() - * - * @this {FPUX86} - */ - static FSTSWAX287() - { - if (this.isAtLeastModel(X86.FPU.MODEL_80287)) { - this.cpu.regEAX = (this.cpu.regEAX & ~0xffff) | this.getStatus(); - } +/** + * FSTSWAX287() + * + * @this {FPUX86} + */ +FPUX86.FSTSWAX287 = function() +{ + if (this.isAtLeastModel(X86.FPU.MODEL_80287)) { + this.cpu.regEAX = (this.cpu.regEAX & ~0xffff) | this.getStatus(); } +}; - /** - * FSUBlr() - * - * @this {FPUX86} - */ - static FSUBlr() - { - this.setST(0, this.doSubtract(this.getST(0), this.getLRFromEA())); - } +/** + * FSUBlr() + * + * @this {FPUX86} + */ +FPUX86.FSUBlr = function() +{ + this.setST(0, this.doSubtract(this.getST(0), this.getLRFromEA())); +}; - /** - * FSUBsr() - * - * @this {FPUX86} - */ - static FSUBsr() - { - this.setST(0, this.doSubtract(this.getST(0), this.getSRFromEA())); - } +/** + * FSUBsr() + * + * @this {FPUX86} + */ +FPUX86.FSUBsr = function() +{ + this.setST(0, this.doSubtract(this.getST(0), this.getSRFromEA())); +}; - /** - * FSUBst() - * - * Encoding 0xD8,0xE0-0xE7 ("FSUB ST,ST(i)"): ST(0) <- ST(0) - ST(i) - * - * @this {FPUX86} - */ - static FSUBst() - { - this.setST(0, this.doSubtract(this.getST(0), this.getST(this.iStack))); - } +/** + * FSUBst() + * + * Encoding 0xD8,0xE0-0xE7 ("FSUB ST,ST(i)"): ST(0) <- ST(0) - ST(i) + * + * @this {FPUX86} + */ +FPUX86.FSUBst = function() +{ + this.setST(0, this.doSubtract(this.getST(0), this.getST(this.iStack))); +}; - /** - * FSUBsti() - * - * Encoding 0xDC,0xE8-0xEF ("FSUB ST(i),ST"): ST(i) <- ST(i) - ST(0) - * - * @this {FPUX86} - */ - static FSUBsti() - { - this.setST(this.iStack, this.doSubtract(this.getST(this.iStack), this.getST(0))); - } +/** + * FSUBsti() + * + * Encoding 0xDC,0xE8-0xEF ("FSUB ST(i),ST"): ST(i) <- ST(i) - ST(0) + * + * @this {FPUX86} + */ +FPUX86.FSUBsti = function() +{ + this.setST(this.iStack, this.doSubtract(this.getST(this.iStack), this.getST(0))); +}; - /** - * FSUBPsti() - * - * Encoding 0xDE,0xE8-0xEF ("FSUBP ST(i),ST"): ST(i) <- ST(i) - ST(0), POP - * - * @this {FPUX86} - */ - static FSUBPsti() - { - if (this.setST(this.iStack, this.doSubtract(this.getST(this.iStack), this.getST(0)))) this.popValue(); - } +/** + * FSUBPsti() + * + * Encoding 0xDE,0xE8-0xEF ("FSUBP ST(i),ST"): ST(i) <- ST(i) - ST(0), POP + * + * @this {FPUX86} + */ +FPUX86.FSUBPsti = function() +{ + if (this.setST(this.iStack, this.doSubtract(this.getST(this.iStack), this.getST(0)))) this.popValue(); +}; - /** - * FSUBRlr() - * - * @this {FPUX86} - */ - static FSUBRlr() - { - this.setST(0, this.doSubtract(this.getLRFromEA(), this.getST(0))); - } +/** + * FSUBRlr() + * + * @this {FPUX86} + */ +FPUX86.FSUBRlr = function() +{ + this.setST(0, this.doSubtract(this.getLRFromEA(), this.getST(0))); +}; - /** - * FSUBRsr() - * - * @this {FPUX86} - */ - static FSUBRsr() - { - this.setST(0, this.doSubtract(this.getSRFromEA(), this.getST(0))); - } +/** + * FSUBRsr() + * + * @this {FPUX86} + */ +FPUX86.FSUBRsr = function() +{ + this.setST(0, this.doSubtract(this.getSRFromEA(), this.getST(0))); +}; - /** - * FSUBRst() - * - * Encoding 0xD8,0xE8-0xEF ("FSUBR ST,ST(i)"): ST(0) <- ST(i) - ST(0) - * - * @this {FPUX86} - */ - static FSUBRst() - { - this.setST(0, this.doSubtract(this.getST(this.iStack), this.getST(0))); - } +/** + * FSUBRst() + * + * Encoding 0xD8,0xE8-0xEF ("FSUBR ST,ST(i)"): ST(0) <- ST(i) - ST(0) + * + * @this {FPUX86} + */ +FPUX86.FSUBRst = function() +{ + this.setST(0, this.doSubtract(this.getST(this.iStack), this.getST(0))); +}; - /** - * FSUBRsti() - * - * Encoding 0xDC,0xE0-0xE7 ("FSUBR ST(i),ST"): ST(i) <- ST(0) - ST(i) - * - * @this {FPUX86} - */ - static FSUBRsti() - { - this.setST(this.iStack, this.doSubtract(this.getST(0), this.getST(this.iStack))); - } +/** + * FSUBRsti() + * + * Encoding 0xDC,0xE0-0xE7 ("FSUBR ST(i),ST"): ST(i) <- ST(0) - ST(i) + * + * @this {FPUX86} + */ +FPUX86.FSUBRsti = function() +{ + this.setST(this.iStack, this.doSubtract(this.getST(0), this.getST(this.iStack))); +}; - /** - * FSUBRPsti() - * - * Encoding 0xDE,0xE0-0xE7 ("FSUBRP ST(i),ST"): ST(i) <- ST(0) - ST(i), POP - * - * @this {FPUX86} - */ - static FSUBRPsti() - { - if (this.setST(this.iStack, this.doSubtract(this.getST(0), this.getST(this.iStack)))) this.popValue(); - } +/** + * FSUBRPsti() + * + * Encoding 0xDE,0xE0-0xE7 ("FSUBRP ST(i),ST"): ST(i) <- ST(0) - ST(i), POP + * + * @this {FPUX86} + */ +FPUX86.FSUBRPsti = function() +{ + if (this.setST(this.iStack, this.doSubtract(this.getST(0), this.getST(this.iStack)))) this.popValue(); +}; - /** - * FTST() - * - * @this {FPUX86} - */ - static FTST() - { - this.doCompare(this.getST(0), 0); - } +/** + * FTST() + * + * @this {FPUX86} + */ +FPUX86.FTST = function() +{ + this.doCompare(this.getST(0), 0); +}; - /** - * FXAM() - * - * @this {FPUX86} - */ - static FXAM() - { - this.regStatus &= ~X86.FPU.STATUS.CC; +/** + * FXAM() + * + * @this {FPUX86} + */ +FPUX86.FXAM = function() +{ + this.regStatus &= ~X86.FPU.STATUS.CC; - if (this.getSTSign(0)) { - this.regStatus |= X86.FPU.STATUS.C1; + if (this.getSTSign(0)) { + this.regStatus |= X86.FPU.STATUS.C1; + } + if (this.getTag(this.iST) == X86.FPU.TAGS.EMPTY) { + this.regStatus |= X86.FPU.STATUS.C0 | X86.FPU.STATUS.C3; + } + else { + var v = this.getST(0); + if (isNaN(v)) { + this.regStatus |= X86.FPU.STATUS.C0; + } + else if (v === 0) { // this equals -0, too (WTF, strict equality?) + this.regStatus |= X86.FPU.STATUS.C3; } - if (this.getTag(this.iST) == X86.FPU.TAGS.EMPTY) { - this.regStatus |= X86.FPU.STATUS.C0 | X86.FPU.STATUS.C3; + else if (v === Infinity || v === -Infinity) { // these are so divergent that even non-strict equality doesn't consider them equal + this.regStatus |= X86.FPU.STATUS.C0 | X86.FPU.STATUS.C2; } else { - var v = this.getST(0); - if (isNaN(v)) { - this.regStatus |= X86.FPU.STATUS.C0; - } - else if (v === 0) { // this equals -0, too (WTF, strict equality?) - this.regStatus |= X86.FPU.STATUS.C3; - } - else if (v === Infinity || v === -Infinity) { // these are so divergent that even non-strict equality doesn't consider them equal - this.regStatus |= X86.FPU.STATUS.C0 | X86.FPU.STATUS.C2; - } - else { - this.regStatus |= X86.FPU.STATUS.C2; - } + this.regStatus |= X86.FPU.STATUS.C2; } } +}; - /** - * FXCHsti() - * - * @this {FPUX86} - */ - static FXCHsti() - { - var tmp = this.getST(0); - this.setST(0, this.getST(this.iStack)); - this.setST(this.iStack, tmp); - } - - /** - * FXCH8087() - * - * NOTE: This is used with encodings (0xDD,0xC8-0xCF and 0xDF,0xC8-0xCF) that were valid for the 8087 and 80287 - * but may no longer be valid as of the 80387. - * - * @this {FPUX86} - */ - static FXCH8087() - { - this.opObsolete(); - FPUX86.FXCHsti.call(this); - } +/** + * FXCHsti() + * + * @this {FPUX86} + */ +FPUX86.FXCHsti = function() +{ + var tmp = this.getST(0); + this.setST(0, this.getST(this.iStack)); + this.setST(this.iStack, tmp); +}; - /** - * FXTRACT() - * - * FXTRACT splits the value encoded in ST(0) into two separate numbers representing the actual value of the - * fraction (mantissa) and exponent fields. - * - * The FXTRACT instruction is used to decompose the two fields of the temporary real number in ST(0). The exponent - * replaces the value in ST(0), then the fraction is pushed onto the stack. When execution is complete, ST(0) - * contains the original fraction, expressed as a real number with a true exponent of 0 (0x3FFF in biased form), - * and ST(1) contains the value of the original operand's true (unbiased) exponent expressed as a real number. - * - * If ST(0) is 0, the 8087 and 80287 will leave zeros in both ST(0) and ST(1); both zeros will have the same sign as - * the original operand. If ST(0) is +infinity, the invalid operation exception is raised. - * - * On the 80287XL and later coprocessors, if ST(0) is 0, the zero-divide exception is reported and ST(1) is set to - * -infinity. If ST(0) is +infinity, no exception is reported. - * - * The FXTRACT instruction may be thought of as the complement to the FSCALE instruction, which combines a separate - * fraction and exponent into a single value. - * - * ALGORITHM: - * - * IF (ST(0) = 0) THEN - * DEC TOP - * ST(0) = ST(1) - * ELSE - * temp = ST(0) - * ST(0) = EXPONENT(ST(0)) ; stored as true exponent - * DEC TOP - * ST(0) = FRACTION(ST(0)) - * ENDIF - * - * @this {FPUX86} - */ - static FXTRACT() - { - var v = this.getST(0); - if (v != null) { - this.regTmpLR[0] = v; - this.setST(0, ((this.intTmpLR[1] >> 20) & 0x7ff) - 0x3ff); - this.intTmpLR[1] = (this.intTmpLR[1] | 0x3ff00000) & ~0x40000000; - this.pushValue(this.regTmpLR[0]); - } - } +/** + * FXCH8087() + * + * NOTE: This is used with encodings (0xDD,0xC8-0xCF and 0xDF,0xC8-0xCF) that were valid for the 8087 and 80287 + * but may no longer be valid as of the 80387. + * + * @this {FPUX86} + */ +FPUX86.FXCH8087 = function() +{ + this.opObsolete(); + FPUX86.FXCHsti.call(this); +}; - /** - * FYL2X() - * - * FYL2X (y log base 2 of x) calculates: - * - * ST(1) = ST(1) * log2(ST(0)) - * - * The operands must satisfy the inequalities 0 < ST(0) < +infinity and -infinity < ST(1) < +infinity. FYL2X pops - * the stack and returns the result to the new ST(0). Both original operands are destroyed. - * - * The FYL2X function is designed to optimize the calculation of a log to a base, n, other than two. In such a case, - * the following multiplication is required; ie: - * - * logn(x) = logn(2) * log2(x) - * - * @this {FPUX86} - */ - static FYL2X() - { - if (this.setST(1, this.getST(1) * Math.log(this.getST(0)) / Math.LN2)) this.popValue(); +/** + * FXTRACT() + * + * FXTRACT splits the value encoded in ST(0) into two separate numbers representing the actual value of the + * fraction (mantissa) and exponent fields. + * + * The FXTRACT instruction is used to decompose the two fields of the temporary real number in ST(0). The exponent + * replaces the value in ST(0), then the fraction is pushed onto the stack. When execution is complete, ST(0) + * contains the original fraction, expressed as a real number with a true exponent of 0 (0x3FFF in biased form), + * and ST(1) contains the value of the original operand's true (unbiased) exponent expressed as a real number. + * + * If ST(0) is 0, the 8087 and 80287 will leave zeros in both ST(0) and ST(1); both zeros will have the same sign as + * the original operand. If ST(0) is +infinity, the invalid operation exception is raised. + * + * On the 80287XL and later coprocessors, if ST(0) is 0, the zero-divide exception is reported and ST(1) is set to + * -infinity. If ST(0) is +infinity, no exception is reported. + * + * The FXTRACT instruction may be thought of as the complement to the FSCALE instruction, which combines a separate + * fraction and exponent into a single value. + * + * ALGORITHM: + * + * IF (ST(0) = 0) THEN + * DEC TOP + * ST(0) = ST(1) + * ELSE + * temp = ST(0) + * ST(0) = EXPONENT(ST(0)) ; stored as true exponent + * DEC TOP + * ST(0) = FRACTION(ST(0)) + * ENDIF + * + * @this {FPUX86} + */ +FPUX86.FXTRACT = function() +{ + var v = this.getST(0); + if (v != null) { + this.regTmpLR[0] = v; + this.setST(0, ((this.intTmpLR[1] >> 20) & 0x7ff) - 0x3ff); + this.intTmpLR[1] = (this.intTmpLR[1] | 0x3ff00000) & ~0x40000000; + this.pushValue(this.regTmpLR[0]); } +}; - /** - * FYL2XP1() - * - * FYL2XP1 (y log base 2 of x plus 1) calculates: - * - * ST(1) = ST(1) * log2(ST(0) + 1) - * - * The operands must satisfy the inequalities -(1-sqrt(2)/2) < ST(0) < (1-sqrt(2)/2) and -infinity < ST(1) < +infinity. - * FYL2XP1 pops the stack and returns the result to the new ST(0). Both original operands are destroyed. - * - * The FYL2XP1 function provides greater accuracy than FYL2X in computing the log of a number that is very close to 1. - * - * FYL2XP1 is typically used when computing compound interest, for example, which requires the calculation of a logarithm - * of 1.0 + n where 0 < n < 0.29. If 1.0 was added to n, significant digits might be lost. By using FYL2XP1, the result - * will be as accurate as n to within three units of temporary real precision. - * - * @this {FPUX86} - */ - static FYL2XP1() - { - if (this.setST(1, this.getST(1) * Math.log(this.getST(0) + 1.0) / Math.LN2)) this.popValue(); - } +/** + * FYL2X() + * + * FYL2X (y log base 2 of x) calculates: + * + * ST(1) = ST(1) * log2(ST(0)) + * + * The operands must satisfy the inequalities 0 < ST(0) < +infinity and -infinity < ST(1) < +infinity. FYL2X pops + * the stack and returns the result to the new ST(0). Both original operands are destroyed. + * + * The FYL2X function is designed to optimize the calculation of a log to a base, n, other than two. In such a case, + * the following multiplication is required; ie: + * + * logn(x) = logn(2) * log2(x) + * + * @this {FPUX86} + */ +FPUX86.FYL2X = function() +{ + if (this.setST(1, this.getST(1) * Math.log(this.getST(0)) / Math.LN2)) this.popValue(); +}; - /** - * FPUX86.init() - * - * This function operates on every HTML element of class "fpu", extracting the - * JSON-encoded parameters for the FPUX86 constructor from the element's "data-value" - * attribute, invoking the constructor to create an FPUX86 component, and then binding - * any associated HTML controls to the new component. - */ - static init() - { - var aeFPUs = Component.getElementsByClass(document, PCX86.APPCLASS, "fpu"); - for (var iFPU = 0; iFPU < aeFPUs.length; iFPU++) { - var eFPU = aeFPUs[iFPU]; - var parmsFPU = Component.getComponentParms(eFPU); - var fpu = new FPUX86(parmsFPU); - Component.bindComponentControls(fpu, eFPU, PCX86.APPCLASS); - } - } -} +/** + * FYL2XP1() + * + * FYL2XP1 (y log base 2 of x plus 1) calculates: + * + * ST(1) = ST(1) * log2(ST(0) + 1) + * + * The operands must satisfy the inequalities -(1-sqrt(2)/2) < ST(0) < (1-sqrt(2)/2) and -infinity < ST(1) < +infinity. + * FYL2XP1 pops the stack and returns the result to the new ST(0). Both original operands are destroyed. + * + * The FYL2XP1 function provides greater accuracy than FYL2X in computing the log of a number that is very close to 1. + * + * FYL2XP1 is typically used when computing compound interest, for example, which requires the calculation of a logarithm + * of 1.0 + n where 0 < n < 0.29. If 1.0 was added to n, significant digits might be lost. By using FYL2XP1, the result + * will be as accurate as n to within three units of temporary real precision. + * + * @this {FPUX86} + */ +FPUX86.FYL2XP1 = function() +{ + if (this.setST(1, this.getST(1) * Math.log(this.getST(0) + 1.0) / Math.LN2)) this.popValue(); +}; /* * Class constants diff --git a/modules/pcx86/lib/hdc.js b/modules/pcx86/lib/hdc.js index b2801a1aaa..0f9d394d51 100644 --- a/modules/pcx86/lib/hdc.js +++ b/modules/pcx86/lib/hdc.js @@ -119,7 +119,7 @@ class HDC extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {HDC} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, "listDisks") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -1132,7 +1132,7 @@ class HDC extends Component { * simplistic MRU logic. If that fails, the worst that will (or should) happen is we'll burn through * more BackTrack wrapper objects than necessary, and risk running out. */ - var bto = hdc.bus.addBackTrackObject(obj, null, off); + var bto = hdc.bus.addBackTrackObject(obj, /** @type BackTrack */ (null), off); hdc.cpu.backTrack.btiIO = hdc.bus.getBackTrackIndex(bto, off); } }); diff --git a/modules/pcx86/lib/keyboard.js b/modules/pcx86/lib/keyboard.js index d93336556c..c992464692 100644 --- a/modules/pcx86/lib/keyboard.js +++ b/modules/pcx86/lib/keyboard.js @@ -206,7 +206,7 @@ class Keyboard extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {Keyboard} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/pcx86/lib/mouse.js b/modules/pcx86/lib/mouse.js index 0d34f87db6..d120d602b0 100644 --- a/modules/pcx86/lib/mouse.js +++ b/modules/pcx86/lib/mouse.js @@ -557,7 +557,7 @@ class Mouse extends Component { * Byte 3 X 0 Y5 Y4 Y3 Y2 Y1 Y0 * * @this {Mouse} - * @param {string|null} [sDiag] diagnostic message + * @param {string|null|*} [sDiag] diagnostic message * @param {number} [xDiag] original x-coordinate (optional; for diagnostic use only) * @param {number} [yDiag] original y-coordinate (optional; for diagnostic use only) */ diff --git a/modules/pcx86/lib/panel.js b/modules/pcx86/lib/panel.js index 2506e96c6f..a2dda72f37 100644 --- a/modules/pcx86/lib/panel.js +++ b/modules/pcx86/lib/panel.js @@ -243,7 +243,7 @@ class Panel extends Component { * that doesn't recognize the specified binding should simply ignore it. * * @this {Panel} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -887,7 +887,7 @@ class Panel extends Component { * * @this {Panel} * @param {string} sText - * @param {number|null} [nValue] + * @param {number|null|*} [nValue] * @param {number} [nColsSkip] * @param {number} [nLinesSkip] */ diff --git a/modules/pcx86/lib/parallel.js b/modules/pcx86/lib/parallel.js index 2a1bac5b92..8b0186fd19 100644 --- a/modules/pcx86/lib/parallel.js +++ b/modules/pcx86/lib/parallel.js @@ -146,7 +146,7 @@ class ParallelPort extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {ParallelPort} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, "buffer") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -154,7 +154,7 @@ class ParallelPort extends Component { */ setBinding(sHTMLType, sBinding, control, sValue) { - if (sHTMLType == null || sHTMLType == "textarea") { + if (!sHTMLType || sHTMLType == "textarea") { this.bindings[sBinding] = this.controlBuffer = control; return true; } diff --git a/modules/pcx86/lib/serial.js b/modules/pcx86/lib/serial.js index 1ed69bef30..fa1d49921c 100644 --- a/modules/pcx86/lib/serial.js +++ b/modules/pcx86/lib/serial.js @@ -258,7 +258,7 @@ class SerialPort extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {SerialPort} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, "buffer") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -266,7 +266,7 @@ class SerialPort extends Component { */ setBinding(sHTMLType, sBinding, control, sValue) { - if (sHTMLType == null || sHTMLType == "textarea") { + if (!sHTMLType || sHTMLType == "textarea") { var serial = this; this.bindings[sBinding] = this.controlBuffer = /** @type {HTMLTextAreaElement} */ (control); diff --git a/modules/pcx86/lib/testctl.js b/modules/pcx86/lib/testctl.js index 911c896d0f..3d93e5007a 100644 --- a/modules/pcx86/lib/testctl.js +++ b/modules/pcx86/lib/testctl.js @@ -167,7 +167,7 @@ class TestController extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {TestController} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, "buffer") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/modules/pcx86/lib/video.js b/modules/pcx86/lib/video.js index a50f409413..362478467e 100644 --- a/modules/pcx86/lib/video.js +++ b/modules/pcx86/lib/video.js @@ -688,7 +688,7 @@ class Card extends Controller { if (this.nCard >= Video.CARD.EGA) { this.dbg.println(" LATCHES: " + Str.toHex(this.latches)); this.dbg.println(" ACCESS: " + Str.toHex(this.nAccess, 4)); - this.dbg.println("Use 'dump video [addr]' to dump video memory"); + this.dbg.println("Use 'd video [addr]' to dump video memory"); /* * There are few more EGA regs we could dump, like GRCPos1, GRCPos2, but does anyone care? */ @@ -793,7 +793,7 @@ class Card extends Controller { var sData = Str.toHex(this.addrBuffer + idw) + ":"; for (j = 0; j < n && idw < this.adwMemory.length; j++) { var dw = this.adwMemory[idw++]; - sData += ' ' + ((p < 0)? Str.toHex(dw) : Str.toBin((dw >> (p << 3)), 8)); + sData += ' ' + ((p < 0)? Str.toHex(dw, 8) : Str.toBin((dw >> (p << 3)), 8)); } if (fColAdjust) idw += w - n; if (sDump) sDump += "\n"; @@ -1289,8 +1289,8 @@ Card.ATC = { if (DEBUGGER) { Card.ATC.REGS = [ - "PAL00","PAL01","PAL02","PAL03","PAL04","PAL05","PAL06","PAL07", - "PAL08","PAL09","PAL0A","PAL0B","PAL0C","PAL0D","PAL0E","PAL0F", "MODE","OVERSCAN","PLANES","HPAN"]; + "ATC00","ATC01","ATC02","ATC03","ATC04","ATC05","ATC06","ATC07", + "ATC08","ATC09","ATC0A","ATC0B","ATC0C","ATC0D","ATC0E","ATC0F", "ATCMODE","OVERSCAN","PLANES","HPAN"]; } /* @@ -1510,7 +1510,7 @@ Card.GRC = { TOTAL_REGS: 0x09 }; -if (DEBUGGER) Card.GRC.REGS = ["SRESET","ESRESET","COLORCMP","DATAROT","READMAP","MODE","MISC","COLORDC","BITMASK"]; +if (DEBUGGER) Card.GRC.REGS = ["SRESET","ESRESET","COLORCMP","DATAROT","READMAP","GRCMODE","GRCMISC","COLORDC","BITMASK"]; /* * EGA Memory Access Functions @@ -2361,13 +2361,13 @@ class Video extends Component { if (sEvent) { var sFullScreen = Web.findProperty(document, 'fullscreenElement') || Web.findProperty(document, 'fullScreenElement'); document.addEventListener(sEvent, function onFullScreenChange() { - video.notifyFullScreen(!!sFullScreen); + video.notifyFullScreen(document[sFullScreen] != null); }, false); } sEvent = Web.findProperty(document, 'on', 'fullscreenerror'); if (sEvent) { document.addEventListener(sEvent, function onFullScreenError() { - video.notifyFullScreen(null); + video.notifyFullScreen(); }, false); } } @@ -2537,7 +2537,7 @@ class Video extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {Video} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, "refresh") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -2712,7 +2712,7 @@ class Video extends Component { * notifyFullScreen(fFullScreen) * * @this {Video} - * @param {boolean|null} fFullScreen (null if there was a full-screen error) + * @param {boolean|undefined} [fFullScreen] (undefined if there was a full-screen error) */ notifyFullScreen(fFullScreen) { @@ -2723,8 +2723,8 @@ class Video extends Component { this.canvasScreen.style.width = this.canvasScreen.style.height = ""; } } - this.printMessage("notifyFullScreen(" + fFullScreen + ")", true); - if (this.kbd) this.kbd.notifyEscape(fFullScreen); + if (DEBUG) this.printMessage("notifyFullScreen(" + fFullScreen + ")", true); + if (this.kbd) this.kbd.notifyEscape(fFullScreen == true); } /** diff --git a/modules/pdp10/lib/computer.js b/modules/pdp10/lib/computer.js index 51a40ecb43..69cc6042f2 100644 --- a/modules/pdp10/lib/computer.js +++ b/modules/pdp10/lib/computer.js @@ -1086,16 +1086,16 @@ class ComputerPDP10 extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {ComputerPDP10} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "reset") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { var computer = this; diff --git a/modules/pdp10/lib/cpu.js b/modules/pdp10/lib/cpu.js index f654934843..da898554dd 100644 --- a/modules/pdp10/lib/cpu.js +++ b/modules/pdp10/lib/cpu.js @@ -150,7 +150,7 @@ class CPUPDP10 extends Component { this.panel = cmp.panel; for (var i = 0; i < CPUPDP10.BUTTONS.length; i++) { var control = this.bindings[CPUPDP10.BUTTONS[i]]; - if (control) this.cmp.setBinding(null, CPUPDP10.BUTTONS[i], control); + if (control) this.cmp.setBinding("", CPUPDP10.BUTTONS[i], control); } this.setReady(); } @@ -401,16 +401,16 @@ class CPUPDP10 extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {CPUPDP10} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "run") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { var cpu = this; diff --git a/modules/pdp10/lib/debugger.js b/modules/pdp10/lib/debugger.js index 0aeb89ca84..ee090eb291 100644 --- a/modules/pdp10/lib/debugger.js +++ b/modules/pdp10/lib/debugger.js @@ -352,16 +352,16 @@ class DebuggerPDP10 extends Debugger { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {DebuggerPDP10} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "debugInput") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { var dbg = this; switch (sBinding) { diff --git a/modules/pdp10/lib/panel.js b/modules/pdp10/lib/panel.js index 8324630d4f..d0d9f064e9 100644 --- a/modules/pdp10/lib/panel.js +++ b/modules/pdp10/lib/panel.js @@ -296,7 +296,7 @@ class PanelPDP10 extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * Some panel layouts don't have bindings of their own, and even when they do, there may still be some * components (eg, the CPU) that prefer to update their own bindings, so we pass along all binding requests @@ -304,23 +304,17 @@ class PanelPDP10 extends Component { * component that doesn't recognize the specified binding should simply ignore it. * * @this {PanelPDP10} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "reset") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { - if (this.cmp && this.cmp.setBinding(sType, sBinding, control, sValue)) { - return true; - } - if (this.cpu && this.cpu.setBinding(sType, sBinding, control, sValue)) { - return true; - } - if (DEBUGGER && this.dbg && this.dbg.setBinding(sType, sBinding, control, sValue)) { - return true; - } + 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; switch (sBinding) { case 'PC': @@ -336,7 +330,7 @@ class PanelPDP10 extends Component { * * Only *type* and *binding* attributes are required; if *value* is omitted, the default value is 0 ("off"). */ - if (sType == "led" || sType == "rled") { + if (sHTMLType == "led" || sHTMLType == "rled") { this.bindings[sBinding] = control; this.leds[sBinding] = sValue? 1 : 0; this.cLiveRegs++; @@ -352,7 +346,7 @@ class PanelPDP10 extends Component { * Currently, there is no XML attribute to indicate whether a switch is "momentary"; only recognized switches * in our internal table can have that attribute. */ - if (sType == "switch") { + if (sHTMLType == "switch") { /* * Like LEDs, we allow unrecognized switches to be defined as well, but they won't do anything useful, * since only recognized switches will have handlers that perform the appropriate operations. @@ -386,7 +380,7 @@ class PanelPDP10 extends Component { }(this, sBinding); return true; } - return super.setBinding(sType, sBinding, control, sValue); + return super.setBinding(sHTMLType, sBinding, control, sValue); } } diff --git a/modules/pdp10/lib/serial.js b/modules/pdp10/lib/serial.js index c91c5660d8..01703b0d5f 100644 --- a/modules/pdp10/lib/serial.js +++ b/modules/pdp10/lib/serial.js @@ -169,18 +169,18 @@ class SerialPortPDP10 extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {SerialPortPDP10} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "buffer") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { - if (sType == null || sType == "textarea") { + if (!sHTMLType || sHTMLType == "textarea") { var serial = this; this.bindings[sBinding] = this.controlBuffer = control; diff --git a/modules/pdp11/lib/computer.js b/modules/pdp11/lib/computer.js index 978a9f6178..ac1a698f29 100644 --- a/modules/pdp11/lib/computer.js +++ b/modules/pdp11/lib/computer.js @@ -1092,16 +1092,16 @@ class ComputerPDP11 extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {ComputerPDP11} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "reset") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { var computer = this; diff --git a/modules/pdp11/lib/cpu.js b/modules/pdp11/lib/cpu.js index 0b95de05b9..6bbd964dd0 100644 --- a/modules/pdp11/lib/cpu.js +++ b/modules/pdp11/lib/cpu.js @@ -146,7 +146,7 @@ class CPUPDP11 extends Component { this.panel = cmp.panel; 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); + if (control) this.cmp.setBinding("", CPUPDP11.BUTTONS[i], control); } this.setReady(); } @@ -396,16 +396,16 @@ class CPUPDP11 extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {CPUPDP11} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "run") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { var cpu = this; diff --git a/modules/pdp11/lib/debugger.js b/modules/pdp11/lib/debugger.js index 4c54cb2fdc..5e3fe39601 100644 --- a/modules/pdp11/lib/debugger.js +++ b/modules/pdp11/lib/debugger.js @@ -317,16 +317,16 @@ class DebuggerPDP11 extends Debugger { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {DebuggerPDP11} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "debugInput") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { var dbg = this; switch (sBinding) { diff --git a/modules/pdp11/lib/drive.js b/modules/pdp11/lib/drive.js index d7e0fad315..ee17acd73c 100644 --- a/modules/pdp11/lib/drive.js +++ b/modules/pdp11/lib/drive.js @@ -156,16 +156,16 @@ class DriveController extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {DriveController} - * @param {string|null} sType is the type of the HTML control (eg, "button", "list", "text", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "list", "text", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "listDisks") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { var dc = this; diff --git a/modules/pdp11/lib/keyboard.js b/modules/pdp11/lib/keyboard.js index 9bef96ce9f..c36f98e5ef 100644 --- a/modules/pdp11/lib/keyboard.js +++ b/modules/pdp11/lib/keyboard.js @@ -49,16 +49,16 @@ class KeyboardPDP11 extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {KeyboardPDP11} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "esc") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { return false; } diff --git a/modules/pdp11/lib/panel.js b/modules/pdp11/lib/panel.js index 82caeb37b5..782d4df928 100644 --- a/modules/pdp11/lib/panel.js +++ b/modules/pdp11/lib/panel.js @@ -299,7 +299,7 @@ class PanelPDP11 extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * Some panel layouts don't have bindings of their own, and even when they do, there may still be some * components (eg, the CPU) that prefer to update their own bindings, so we pass along all binding requests @@ -307,23 +307,17 @@ class PanelPDP11 extends Component { * component that doesn't recognize the specified binding should simply ignore it. * * @this {PanelPDP11} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "reset") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { - if (this.cmp && this.cmp.setBinding(sType, sBinding, control, sValue)) { - return true; - } - if (this.cpu && this.cpu.setBinding(sType, sBinding, control, sValue)) { - return true; - } - if (DEBUGGER && this.dbg && this.dbg.setBinding(sType, sBinding, control, sValue)) { - return true; - } + 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; switch (sBinding) { case 'R0': @@ -351,7 +345,7 @@ class PanelPDP11 extends Component { * * Only *type* and *binding* attributes are required; if *value* is omitted, the default value is 0 ("off"). */ - if (sType == "led" || sType == "rled") { + if (sHTMLType == "led" || sHTMLType == "rled") { this.bindings[sBinding] = control; this.leds[sBinding] = sValue? 1 : 0; this.cLiveRegs++; @@ -367,7 +361,7 @@ class PanelPDP11 extends Component { * Currently, there is no XML attribute to indicate whether a switch is "momentary"; only recognized switches * in our internal table can have that attribute. */ - if (sType == "switch") { + if (sHTMLType == "switch") { /* * Like LEDs, we allow unrecognized switches to be defined as well, but they won't do anything useful, * since only recognized switches will have handlers that perform the appropriate operations. @@ -401,7 +395,7 @@ class PanelPDP11 extends Component { }(this, sBinding); return true; } - return super.setBinding(sType, sBinding, control, sValue); + return super.setBinding(sHTMLType, sBinding, control, sValue); } } diff --git a/modules/pdp11/lib/pc11.js b/modules/pdp11/lib/pc11.js index 811a002641..a7b25e6ccd 100644 --- a/modules/pdp11/lib/pc11.js +++ b/modules/pdp11/lib/pc11.js @@ -131,16 +131,16 @@ class PC11 extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {PC11} - * @param {string|null} sType is the type of the HTML control (eg, "button", "list", "text", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "list", "text", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "listTapes") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { var pc11 = this; var nTapeTarget = PC11.TARGET.NONE; diff --git a/modules/pdp11/lib/serial.js b/modules/pdp11/lib/serial.js index 4e6bee88c3..f79976c133 100644 --- a/modules/pdp11/lib/serial.js +++ b/modules/pdp11/lib/serial.js @@ -189,18 +189,18 @@ class SerialPortPDP11 extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {SerialPortPDP11} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "buffer") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { - if (sType == null || sType == "textarea") { + if (!sHTMLType || sHTMLType == "textarea") { var serial = this; this.bindings[sBinding] = this.controlBuffer = control; diff --git a/modules/shared/lib/component.js b/modules/shared/lib/component.js index f1e8f072d2..59c3a51f0a 100644 --- a/modules/shared/lib/component.js +++ b/modules/shared/lib/component.js @@ -465,7 +465,7 @@ class Component { if (target) { var control = target.bindings[sBinding]; if (control) { - component.setBinding(null, sBinding, control); + component.setBinding("", sBinding, control); } } } @@ -953,7 +953,7 @@ class Component { * Component's setBinding() method is intended to be overridden by subclasses. * * @this {Component} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, 'print') * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -1406,10 +1406,10 @@ class Component { * * @this {Component} * @param {number} port - * @param {number|null} bOut if an output operation - * @param {number|null} [addrFrom] - * @param {string|null} [name] of the port, if any - * @param {number|null} [bIn] is the input value, if known, on an input operation + * @param {number|null|*} bOut if an output operation + * @param {number|null|*} [addrFrom] + * @param {string|null|*} [name] of the port, if any + * @param {number|null|*} [bIn] is the input value, if known, on an input operation * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s) */ printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage) diff --git a/modules/shared/lib/debugger.js b/modules/shared/lib/debugger.js index 4e916fa275..23887932ba 100644 --- a/modules/shared/lib/debugger.js +++ b/modules/shared/lib/debugger.js @@ -1055,7 +1055,7 @@ class Debugger extends Component * * @this {Debugger} * @param {string|undefined} sValue - * @param {string|null} [sName] is the name of the value, if any + * @param {string|null|*} [sName] is the name of the value, if any * @param {Array|undefined|boolean} [fQuiet] * @param {number} [nUnary] (0 for none, 1 for negate, 2 for complement, 3 for leading zeros) * @return {number|undefined} numeric value, or undefined if sValue is either undefined or invalid diff --git a/modules/shared/lib/strlib.js b/modules/shared/lib/strlib.js index 735b136bd8..e362c9edfd 100644 --- a/modules/shared/lib/strlib.js +++ b/modules/shared/lib/strlib.js @@ -185,7 +185,7 @@ class Str { * * Displays the given number as an unsigned integer using the specified radix and number of digits. * - * @param {number|null|undefined} n + * @param {number|*} n * @param {number} radix (ie, the base) * @param {number} cch (the desired number of digits) * @param {string} [sPrefix] (default is none) @@ -195,17 +195,17 @@ class Str { static toBase(n, radix, cch, sPrefix = "", nGrouping = 0) { /* - * An initial "falsey" check for null takes care of both null and undefined; - * we can't rely entirely on isNaN(), because isNaN(null) returns false, oddly enough. + * We can't rely entirely on isNaN(), because isNaN(null) returns false, and we can't rely + * entirely on typeof either, because typeof Nan returns "number". Sigh. * * Alternatively, we could mask and shift n regardless of whether it's null/undefined/NaN, * since JavaScript coerces such operands to zero, but I think there's "value" in seeing those * values displayed differently. */ var s = ""; - if (isNaN(n)) { + if (isNaN(n) || typeof n != "number") { n = null; - } else if (n != null) { + } else { /* * Callers that produced an input by dividing by a power of two rather than shifting (in order * to access more than 32 bits) may produce a fractional result, which ordinarily we would simply @@ -248,7 +248,7 @@ class Str { * * Converts an integer to binary, with the specified number of digits (up to a maximum of 36). * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of binary digits (0 or undefined for default of either 8, 18, or 36) * @param {number} [nGrouping] * @return {string} the binary representation of n @@ -300,7 +300,7 @@ class Str { * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw * an exception, whereas this function will return '?' characters. * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of octal digits (0 or undefined for default of either 6, 8, or 12) * @param {boolean} [fPrefix] * @return {string} the octal representation of n @@ -330,7 +330,7 @@ class Str { * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw * an exception, whereas this function will return '?' characters. * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of decimal digits (0 or undefined for default of either 5 or 11) * @return {string} the decimal representation of n */ @@ -365,7 +365,7 @@ class Str { * s = "00000000".substr(0, 8 - s.length) + s; * s = s.substr(0, cch).toUpperCase(); * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of hex digits (0 or undefined for default of either 4, 8, or 9) * @param {boolean} [fPrefix] * @return {string} the hex representation of n diff --git a/versions/c1pjs/1.61.0/c1p-uncompiled.js b/versions/c1pjs/1.61.0/c1p-uncompiled.js index f1483b796f..c2c70ccf01 100644 --- a/versions/c1pjs/1.61.0/c1p-uncompiled.js +++ b/versions/c1pjs/1.61.0/c1p-uncompiled.js @@ -339,7 +339,7 @@ class Str { * * Displays the given number as an unsigned integer using the specified radix and number of digits. * - * @param {number|null|undefined} n + * @param {number|*} n * @param {number} radix (ie, the base) * @param {number} cch (the desired number of digits) * @param {string} [sPrefix] (default is none) @@ -349,17 +349,17 @@ class Str { static toBase(n, radix, cch, sPrefix = "", nGrouping = 0) { /* - * An initial "falsey" check for null takes care of both null and undefined; - * we can't rely entirely on isNaN(), because isNaN(null) returns false, oddly enough. + * We can't rely entirely on isNaN(), because isNaN(null) returns false, and we can't rely + * entirely on typeof either, because typeof Nan returns "number". Sigh. * * Alternatively, we could mask and shift n regardless of whether it's null/undefined/NaN, * since JavaScript coerces such operands to zero, but I think there's "value" in seeing those * values displayed differently. */ var s = ""; - if (isNaN(n)) { + if (isNaN(n) || typeof n != "number") { n = null; - } else if (n != null) { + } else { /* * Callers that produced an input by dividing by a power of two rather than shifting (in order * to access more than 32 bits) may produce a fractional result, which ordinarily we would simply @@ -402,7 +402,7 @@ class Str { * * Converts an integer to binary, with the specified number of digits (up to a maximum of 36). * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of binary digits (0 or undefined for default of either 8, 18, or 36) * @param {number} [nGrouping] * @return {string} the binary representation of n @@ -454,7 +454,7 @@ class Str { * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw * an exception, whereas this function will return '?' characters. * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of octal digits (0 or undefined for default of either 6, 8, or 12) * @param {boolean} [fPrefix] * @return {string} the octal representation of n @@ -484,7 +484,7 @@ class Str { * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw * an exception, whereas this function will return '?' characters. * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of decimal digits (0 or undefined for default of either 5 or 11) * @return {string} the decimal representation of n */ @@ -519,7 +519,7 @@ class Str { * s = "00000000".substr(0, 8 - s.length) + s; * s = s.substr(0, cch).toUpperCase(); * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of hex digits (0 or undefined for default of either 4, 8, or 9) * @param {boolean} [fPrefix] * @return {string} the hex representation of n @@ -2849,7 +2849,7 @@ class Component { if (target) { var control = target.bindings[sBinding]; if (control) { - component.setBinding(null, sBinding, control); + component.setBinding("", sBinding, control); } } } @@ -3337,7 +3337,7 @@ class Component { * Component's setBinding() method is intended to be overridden by subclasses. * * @this {Component} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, 'print') * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -3790,10 +3790,10 @@ class Component { * * @this {Component} * @param {number} port - * @param {number|null} bOut if an output operation - * @param {number|null} [addrFrom] - * @param {string|null} [name] of the port, if any - * @param {number|null} [bIn] is the input value, if known, on an input operation + * @param {number|null|*} bOut if an output operation + * @param {number|null|*} [addrFrom] + * @param {string|null|*} [name] of the port, if any + * @param {number|null|*} [bIn] is the input value, if known, on an input operation * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s) */ printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage) @@ -4001,7 +4001,7 @@ class C1PPanel extends Component { * component that doesn't recognize the specified binding should simply ignore it. * * @this {C1PPanel} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -4557,7 +4557,7 @@ class C1PCPU extends Component { /** * @this {C1PCPU} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "run") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -8599,7 +8599,7 @@ class C1PKeyboard extends Component { /** * @this {C1PKeyboard} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "esc", "ctrl-c") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -9502,7 +9502,7 @@ class C1PVideo extends Component { /** * @this {C1PVideo} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "refresh") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -10001,7 +10001,7 @@ class C1PSerialPort extends Component { /** * @this {C1PSerialPort} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "listSerial") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -10987,7 +10987,7 @@ class C1PDiskController extends Component { /** * @this {C1PDiskController} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "listDisk") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -12057,7 +12057,7 @@ class C1PDebugger extends Component { /** * @this {C1PDebugger} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -13903,7 +13903,7 @@ class C1PComputer extends Component { /** * @this {C1PComputer} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea") * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "reset") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/versions/c1pjs/1.61.0/c1p.js b/versions/c1pjs/1.61.0/c1p.js index 6ff0c2db4f..130adf3b50 100644 --- a/versions/c1pjs/1.61.0/c1p.js +++ b/versions/c1pjs/1.61.0/c1p.js @@ -22,7 +22,7 @@ var f,aa="function"==typeof Object.create?Object.create:function(a){function b(){}b.prototype=a;return new b},ba;if("function"==typeof Object.setPrototypeOf)ba=Object.setPrototypeOf;else{var ca;a:{var da={Jb:!0},ea={};try{ea.__proto__=da;ca=ea.Jb;break a}catch(a){}ca=!1}ba=ca?function(a,b){a.__proto__=b;if(a.__proto__!==b)throw new TypeError(a+" is not extensible");return a}:null}var fa=ba; function p(a,b){a.prototype=aa(b.prototype);a.prototype.constructor=a;if(fa)fa(a,b);else for(var c in b)if("prototype"!=c)if(Object.defineProperties){var d=Object.getOwnPropertyDescriptor(b,c);d&&Object.defineProperty(a,c,d)}else a[c]=b[c];a.Se=b.prototype}var ha="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){a!=Array.prototype&&a!=Object.prototype&&(a[b]=c.value)},ia="undefined"!=typeof window&&window===this?this:"undefined"!=typeof global&&null!=global?global:this; function ja(a,b){if(b){var c=ia;a=a.split(".");for(var d=0;d<a.length-1;d++){var e=a[d];e in c||(c[e]={});c=c[e]}a=a[a.length-1];d=c[a];b=b(d);b!=d&&null!=b&&ha(c,a,{configurable:!0,writable:!0,value:b})}}ja("Math.trunc",function(a){return a?a:function(a){a=Number(a);if(isNaN(a)||Infinity===a||-Infinity===a||0===a)return a;var b=Math.floor(Math.abs(a));return 0>a?-b:b}});ja("Number.parseInt",function(a){return a||parseInt}); -function q(a,b,c){b?9<b&&(b=9):(b=Math.abs(a),b=65535>=b?4:4294967295>=b?8:9);c=c?"0x":"";var d=void 0===d?0:d;var e="";isNaN(a)?a=null:null!=a&&(0>a&&-1<a&&(a=-1),0>a&&(a+=Math.pow(16,b)),a>=Math.pow(16,b)&&(b=Math.ceil(Math.log(a)/Math.log(16))));for(var g=d||-1;0<b--;){g||(e=","+e,g=d);if(null==a)e="?"+e;else{var h=a%16;h+=0<=h&&9>=h?48:55;e=String.fromCharCode(h)+e;a=Math.trunc(a/16)}g--}return(void 0===c?"":c)+e}function t(a){return q(a,2,!0)}function u(a){return q(a,4,!0)} +function q(a,b,c){b?9<b&&(b=9):(b=Math.abs(a),b=65535>=b?4:4294967295>=b?8:9);c=c?"0x":"";var d=void 0===d?0:d;var e="";isNaN(a)||"number"!=typeof a?a=null:(0>a&&-1<a&&(a=-1),0>a&&(a+=Math.pow(16,b)),a>=Math.pow(16,b)&&(b=Math.ceil(Math.log(a)/Math.log(16))));for(var g=d||-1;0<b--;){g||(e=","+e,g=d);if(null==a)e="?"+e;else{var h=a%16;h+=0<=h&&9>=h?48:55;e=String.fromCharCode(h)+e;a=Math.trunc(a/16)}g--}return(void 0===c?"":c)+e}function t(a){return q(a,2,!0)}function u(a){return q(a,4,!0)} function ka(a){var b=a,c=a.lastIndexOf("/");0<=c&&(b=a.substr(c+1));c=b.indexOf("\x26");0<c&&(b=b.substr(0,c));return b}function la(a){var b="",c=a.lastIndexOf(".");0<=c&&(b=a.substr(c+1).toLowerCase());return b}function ma(a){return a.replace(/[&<>"']/g,function(a){return na[a]})}var na={"\x26":"\x26amp;","\x3c":"\x26lt;","\x3e":"\x26gt;",'"':"\x26quot;","'":"\x26#039;"},oa=Date.now||function(){return+new Date}; function w(a,b){var c=null,d=!0;c=void 0===c?"text":c;d=void 0===d?!1:d;var e=0,g=null;if("object"==typeof resources&&(g=resources[a]))b&&b(a,g,e);else if(d&&"function"==typeof resources)resources(a,function(c,d){b&&b(a,c,d)});else{a=a.replace(/^\/(pcjs-disks|private-disks)\//,"https://jeffpar.github.io/$1/");var h=window.XMLHttpRequest?new window.XMLHttpRequest:new window.ActiveXObject("Microsoft.XMLHTTP"),l=!1,k="string"===typeof h.responseType,m=function(){if(4!==h.readyState)return null;try{g= l?h.response:h.responseText}catch(r){}if(null==g||200!=h.status&&(h.status||!g.length||"file:"!=(window?window.location.protocol:"file:")))e=h.status||-1;b&&b(a,g,e);return[g,e]};d&&(h.onreadystatechange=m);if(c&&"object"==typeof c){k="";for(var n in c)c.hasOwnProperty(n)&&(k&&(k+="\x26"),k+=n+"\x3d"+encodeURIComponent(c[n]));k=k.replace(/%20/g,"+");h.open("POST",a,d);h.setRequestHeader("Content-type","application/x-www-form-urlencoded");h.send(k)}else h.open("GET",a,d),"arraybuffer"==c&&(k?(l=!0, diff --git a/versions/c1pjs/1.61.0/c1p.js.map b/versions/c1pjs/1.61.0/c1p.js.map index 5cbf342883..004f8d1d9e 100644 --- a/versions/c1pjs/1.61.0/c1p.js.map +++ b/versions/c1pjs/1.61.0/c1p.js.map @@ -1 +1 @@ -{"version":3,"file":"c1p.js","lineCount":202,"mappings":"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","sources":["versions/c1pjs/1.61.0/c1p-uncompiled.js"," [synthetic:util/objectcreate] "," [synthetic:es6/util/setprototypeof] "," [synthetic:es6/util/inherits] "," [synthetic:util/defineproperty] "," [synthetic:util/global] "," [synthetic:util/polyfill] "," [synthetic:es6/math/trunc] "," [synthetic:es6/number/parseint] "],"names":["$jscomp.objectCreate","$jscomp.setPrototypeOf","$jscomp.defineProperty","$jscomp.global","$jscomp.polyfill","toHex","n","cch","fPrefix","v","Math","abs","nGrouping","s","isNaN","pow","radix","ceil","log","g","d","String","fromCharCode","trunc","sPrefix","toHexByte","b","Str.toHex","toHexWord","w","getBaseName","sFileName","sBaseName","i","lastIndexOf","substr","indexOf","getExtension","sExtension","toLowerCase","escapeHTML","sHTML","replace","m","Str.HTMLEscapeMap","Usr.getTime","Date","now","getResource","sURL","done","type","fAsync","nErrorCode","resource","resources","request","window","XMLHttpRequest","ActiveXObject","fArrayBuffer","fXHR2","responseType","callback","readyState","response","responseText","err","status","length","location","protocol","onreadystatechange","sPost","p","hasOwnProperty","encodeURIComponent","open","setRequestHeader","send","overrideMimeType","isUserAgent","userAgent","navigator","match","isMobile","sDevice","sMobile","Web.getURLParm","Web.isUserAgent","fInvert","getURLParm","sParm","Web.parmsURL","sParms","aParms","search","pl","exec","decodeURIComponent","onCountRepeat","fnRepeat","fnComplete","fnTimeout","doCountRepeat","setTimeout","onClickRepeat","e","fn","doClickRepeat","msRepeat","ms","timer","fIgnoreMouseEvents","onmousedown","e.onmousedown","msDelay","ontouchstart","e.ontouchstart","onmouseup","onmouseout","e.onmouseout","clearTimeout","ontouchend","ontouchcancel","e.ontouchcancel","onPageEvent","sFunc","fnPrev","onInit","Web.aPageEventHandlers","push","doPageEvent","afn","Web.fPageEventsEnabled","Component.alertUser","message","enablePageEvents","fEnable","Web.fPageLoaded","Web.sendPageEvent","Web.fPageShowed","sendPageEvent","sEvent","Web.doPageEvent","Web.onPageEvent","onPageLoad","onPageShow","onPageUnload","constructor","Component","parms","bitsMessage","id","name","bindings","idMachine","flags","ready","busy","busyCancel","initDone","powered","unloading","error","fnReady","clearError","dbg","cpu","cmp","Component.components.push","component","alertUser","sMessage","alert","appendControl","control","sText","value","scrollTop","scrollHeight","bindComponentControls","element","aeControls","Component.getElementsByClass","parentNode","iControl","aeChildNodes","childNodes","iNode","nodeType","sClass","getAttribute","aClasses","split","iClass","Component.getComponentParms","undefined","setBinding","getComponentByID","idRelated","Component.components.length","Component.components","getComponentByType","sType","componentPrev","getComponentParms","eval","getElementsByClass","sObjClass","getElementsByClassName","j","ae","aeAll","getElementsByTagName","re","RegExp","test","className","processCommands","fSuccess","aCommands","Component.commands","aTokens","splice","sCommand","fnCallReady","Component.asyncCommands.indexOf","processNextCommand","Component.processCommands","fnCommand","Component.globalCommands","Component.getComponentByType","Component.componentCommands","exports","call","Component.prototype","?.prototype","toString","sHTMLType","sBinding","onclick","clearControl","notice","this.notice","println","print","printControl","Component.appendControl","printlnControl","Component.PRINT.PROGRESS","slice","fPrintOnly","computer","console","setError","isReady","setReady","isBusy","fCancel","setBusy","fBusy","messageEnabled","bitsEnabled","PROGRESS","Component.machines","Component.asyncCommands","scriptAlert","scriptSleep","fnCallback","sDelay","scriptSelect","sValue","aBindings","options","textContent","selectedIndex","Array","prototype","Array.prototype.indexOf","obj","start","isArray","Array.isArray","arg","Object","Function","bind","Function.prototype.bind","fnBound","fToBind","apply","fnNOP","args","concat","arguments","TypeError","C1PPanel","parmsPanel","$jscomp.inherits","kbd","setPower","fOn","C1PPanel.init","init","fReady","aePanels","document","APPCLASS","iPanel","ePanel","panel","Component.getComponentByID","Component.bindComponentControls","Web.onInit","C1PCPU","parmsCPU","clearRegs","running","fAutoStart","SPEED_SLOW","SPEED_FAST","SPEED_MAX","speed","nVideoUpdatesPerSecond","nStatusUpdatesPerSecond","mhzFast","aSpeeds","aSpeedDescs","aReadNotify","aWriteNotify","addrReadLower","addrReadUpper","addrWriteLower","addrWriteUpper","OP_JSR","OP_SIM","SIMOP_MSG","aOpcodeFuncs","opBRK","opORAindx","opSim","opUndefined","opORAzp","opASLzp","opPHP","opORAimm","opASLacc","opORAabs","opASLabs","opBPL","opORAindy","opORAzpx","opASLzpx","opCLC","opORAabsy","opORAabsx","opASLabsx","opJSRabs","opANDindx","opBITzp","opANDzp","opROLzp","opPLP","opANDimm","opROLacc","opBITabs","opANDabs","opROLabs","opBMI","opANDindy","opANDzpx","opROLzpx","opSEC","opANDabsy","opANDabsx","opROLabsx","opRTI","opEORindx","opEORzp","opLSRzp","opPHA","opEORimm","opLSRacc","opJMPimm16","opEORabs","opLSRabs","opBVC","opEORindy","opEORzpx","opLSRzpx","opCLI","opEORabsy","opEORabsx","opLSRabsx","opRTS","opADCindx","opADCzp","opRORzp","opPLA","opADCimm","opRORacc","opJMPabs16","opADCabs","opRORabs","opBVS","opADCindy","opADCzpx","opRORzpx","opSEI","opADCabsy","opADCabsx","opRORabsx","opSTAindx","opSTYzp","opSTAzp","opSTXzp","opDEY","opTXA","opSTYabs","opSTAabs","opSTXabs","opBCC","opSTAindy","opSTYzpx","opSTAzpx","opSTXzpy","opTYA","opSTAabsy","opTXS","opSTAabsx","opLDYimm","opLDAindx","opLDXimm","opLDYzp","opLDAzp","opLDXzp","opTAY","opLDAimm","opTAX","opLDYabs","opLDAabs","opLDXabs","opBCS","opLDAindy","opLDYzpx","opLDAzpx","opLDXzpy","opCLV","opLDAabsy","opTSX","opLDYabsx","opLDAabsx","opLDXabsy","opCPYimm","opCMPindx","opCPYzp","opCMPzp","opDECzp","opINY","opCMPimm","opDEX","opCPYabs","opCMPabs","opDECabs","opBNE","opCMPindy","opCMPzpx","opDECzpx","opCLD","opCMPabsy","opCMPabsx","opDECabsx","opCPXimm","opSBCindx","opCPXzp","opSBCzp","opINCzp","opINX","opSBCimm","opNOP","opCPXabs","opSBCabs","opINCabs","opBEQ","opSBCindy","opSBCzpx","opINCzpx","opSED","opSBCabsy","opSBCabsx","opINCabsx","aOpcodeCycles","C1PCPU.prototype","reset","fPowerOn","halt","regPC","getWord","abMem","VECTOR_RESET","run","fBound","setSpeed","setBuffer","abMemory","end","offMem","cbMem","offLimit","video","displayVideo","updateScreen","setFocus","update","addReadNotify","findNotify","checkReadNotify","addrRead","addrFrom","addWriteNotify","checkWriteNotify","addrWrite","aNotify","fOnClick","innerHTML","nRunCycles","msRunStart","calcCycles","displayReg","sReg","vReg","len","toUpperCase","displayStatus","regA","regX","regY","regP","getRegP","BIT_PC","BIT_PZ","BIT_PI","BIT_PD","BIT_PB","BIT_PV","BIT_PN","regS","mhz","toFixed","fRecalc","nMostUpdatesPerSecond","nYieldsPerSecond","vMultiplier","msPerYield","round","nCyclesPerBurst","floor","nCyclesPerSecond","nCyclesPerYield","nCyclesPerVideoUpdate","nCyclesPerStatusUpdate","nCyclesNextYield","nCyclesNextVideoUpdate","nCyclesNextStatusUpdate","nRecalcCycles","calcRemainingTime","msCurrent","msYield","nCyclesThisRun","msRemainsThisRun","msStartThisRun","msElapsed","calcSpeed","calcStartTime","step","nCycles","nBurstCycles","nStepCycles","stack","stop","nMinCycles","fCompleted","regEA","regEAWrite","aExecBreak","aReadBreak","aWriteBreak","bOpCode","fDebugCheck","fBreak","checkBreakpoint","addr","cIns","aaOpcodeFreqs","aStepHistory","iStepHistory","Str.toHexWord","yieldCPU","getCycles","getByte","regRC","regRZ","regRV","regRU","regRN","setBCD","opADCindxBCD","opADCzpBCD","opADCimmBCD","opADCabsBCD","opADCindyBCD","opADCzpxBCD","opADCabsyBCD","opADCabsxBCD","opSBCindxBCD","opSBCzpBCD","opSBCimmBCD","opSBCabsBCD","opSBCindyBCD","opSBCzpxBCD","opSBCabsyBCD","opSBCabsxBCD","clearBCD","addBCD","reg","mem","carry","r","subBCD","notcarry","bSimOp","SIMOP_HLT","Str.toHexByte","aeCPUs","iCPU","eCPU","C1PROM","parmsROM","abImage","cbROM","sImage","sFileURL","sFileExt","Str.getExtension","FORMAT","host","SITEHOST","rom","Web.getResource","sResponse","convertImage","offROM","setByte","copyImage","messageIO","MESSAGE_PORT","offset","sImageName","sImageData","charAt","ab","asData","sData","parseInt","cbImage","aeROM","iROM","eROM","C1PRAM","parmsRAM","aeRAM","iRAM","eRAM","ram","C1PKeyboard","parmsKbd","nDefaultModel","KEYCODE_DELETE","KEYCODE_LF","KEYCODE_CR","KEYCODE_ESC","CHARCODE_DELETE","CHARCODE_LF","CHARCODE_CR","CHARCODE_ESC","CHARCODE_CTRL","CHARCODE_BREAK","CHARCODE_CTRLC","CHARCODE_CTRLO","BIT_SHIFTLOCK","aButtonCodeMap","aCharCodeMap","CHARCODE_LSHIFT","CHARCODE_RSHIFT","CHARCODE_SHIFTLOCK","C1PKeyboard.prototype","setModel","bitsShift","bKbdRows","abKbdCols","aKbdStates","aKeyTimers","prevKeyDown","prevCharDown","bWriteLast","abKbdColsLast","nCyclesSinceLastEvent","nWritesSinceLastEvent","sInjectBuffer","onkeydown","event","keyEvent","onkeypress","fPass","charCode","which","keyCode","BIT_COMMAND","keyPressSimulate","MESSAGE_KBD","onkeyup","sButton","offKbd","cbKbd","offKbdLimit","nModel","bInvert","fMobile","iOS","calcReleaseDelay","fRepeat","msReleaseRepeat","msReleaseDelay","autoClear","notCharCode","keyEventSimulate","SIMCODE_AUTOCLEAR","injectKeys","sKeyCodes","injectKeysFromBuffer","msInjectDelay","ch","charCodeAt","fDown","fAutoClear","BIT_LSHIFT","PSEUDO_CHARCODE","BIT_RSHIFT","BIT_CTRL","KEYCODE_COMMAND","KEYCODE_TAB","SIMCODE_KEYEVENT","fSimulated","SIMCODE_KEYPRESS","SIMCODE_KEYRELEASE","SIMCODE_KEYTIMEOUT","simCode","bShift","bCode","iRow","iCol","BITS_SIMULATE","fPropagate","updateMemory","C1PKeyboard_prototype$setByte","nCycleDelta","nCyclesThreshold","shift","aeKbd","iKbd","eKbd","C1PVideo","parmsVideo","canvas","context","imgChars","nDefaultCols","nDefaultRows","cxScreen","cyScreen","cxChar","cyChar","setDimensions","canvasScreen","contextScreen","asWebPrefixes","fSmoothing","sSmoothing","C1PVideo.prototype","offVideo","offVideoLimit","random","initScreen","cbVideo","addrVideoPort","nCols","nRows","iRowTop","nRowsVisible","cbScreen","setDrawingDimensions","cxCharDst","cyCharDst","focus","addrGuard","tripGuard","width","height","MESSAGE_VIDEO","nCyclesHigh","C1PVideo_prototype$setByte","aBounds","addrLower","addrUpper","abScreen","row","writeByte","xChar","drawImage","aeVideo","iVideo","eVideo","eCanvas","createElement","getContext","setAttribute","style","backgroundColor","clientWidth","onresize","eParent","eChild","cx","cy","appendChild","imgCharSet","Image","eContext","onload","src","C1PSerialPort","parmsSerial","fDemo","C1PSerialPort.prototype","fHard","autoLoad","C1PSerialPort.AUTOLOAD_6502","bInput","iInput","sInput","nMachine","getMachineNum","aDigits","fConvertLF","C1PSerialPort.AUTOLOAD_NONE","serial","C1PSerialPort.AUTOLOAD_BASIC","control.onclick","loadFile","Web.isMobile","onchange","controlInput.onchange","fieldset","children","submit","disabled","files","onsubmit","controlInput.onsubmit","file","currentTarget","reader","FileReader","reader.onload","result","readAsText","removeChild","offPort","cbPort","offPortLimit","sFileData","nResponse","sSuffix","data","advanceInput","C1PSerialPort_prototype$setByte","MESSAGE_SERIAL","C1PSerialPort.STATUS_DATA","C1PSerialPort.STATUS_NONE","aeSerial","iSerial","eSerial","C1PDiskController","parmsDC","C1PDiskController.prototype","resetRegs","iDriveSelect","aDrives","resetDrive","iDrive","iType","DRIVETYPE_5INCH","nTracks","MAXTRACKS_5INCH","fProtected","nIndexPulse","iTrackSelect","iTrackOffset","aTracks","regDDA","bits","PDA_SD2","read","controller","regCRA","CR_PD_SEL","writePort","PORT_DDA","regPDA","bPDA","setSelectedDrive","regPDB","drive","stopDriveData","advanceDriveData","PORT_PDA","PORT_CRA","regDDB","regCRB","PORT_DDB","bPDB","PDB_ST","PDB_STI","MESSAGE_DISK","PDA_IHD","PORT_PDB","PORT_CRB","regCTRL","CTRL_CDIV","regSTAT","bSTAT","STAT_RDRF","PORT_STAT","regDATA","PORT_DATA","regUnknown","sFilePath","Str.getBaseName","loadDisk","addrController","sDiskName","sDiskData","aHeads","iTrack","iTrackNum","track","sectors","Error","trackData","pushSig","pushBCD","pushBin","iSector","sector","sectorData","a","o","k","cb","getReg","port","fWrite","PORT_CTRL","sName","C1PDiskController_prototype$setByte","aBitIDs","bTest","bChanged","PDB_SD1","aeDC","iDC","eDC","C1PDebugger","parmsDbg","nextAddr","prevCmd","fAssemble","addrAssembleNext","clearBreakpoints","MESSAGE_NONE","aMessageCategories","aOpCodes","aOpSimCodes","setOpModes","aaOperations","OP_BRK","OP_ORA","MODE_INDX","MODE_ZP","OP_ASL","OP_PHP","MODE_IMM","MODE_ACC","MODE_ABS","OP_BPL","MODE_DISP","MODE_INDY","MODE_ZPX","OP_CLC","MODE_ABSY","MODE_ABSX","MODE_IMM16","OP_AND","OP_BIT","OP_ROL","OP_PLP","OP_BMI","OP_SEC","OP_RTI","OP_EOR","OP_LSR","OP_PHA","OP_JMP","OP_BVC","OP_CLI","OP_RTS","OP_ADC","OP_ROR","OP_PLA","MODE_ABS16","OP_BVS","OP_SEI","OP_STA","OP_STY","OP_STX","OP_DEY","OP_TXA","OP_BCC","MODE_ZPY","OP_TYA","OP_TXS","OP_LDY","OP_LDA","OP_LDX","OP_TAY","OP_TAX","OP_BCS","OP_CLV","OP_TSX","OP_CPY","OP_CMP","OP_DEC","OP_INY","OP_DEX","OP_BNE","OP_CLD","OP_CPX","OP_SBC","OP_INC","OP_INX","OP_NOP","OP_BEQ","OP_SED","C1PDebugger.prototype","eDebug","C1PDebugger.input","Web.onClickRepeat","fClassic","sRegEx","aOpModes","iMode","sMode","regexOpModes","aImm16Codes","isCPUOK","fStep","fStepOver","doUnassemble","doRegisters","msStart","msTotal","clearTempBreakpoint","addSignedByte","addExecBreakpoint","findBreakpoint","findExecBreakpoint","fRemove","aBreak","fMatch","setTempBreakpoint","addrTempBP","aBreakpoints","getInstruction","nIns","sLine","aOpDesc","abOperand","OP_DB","sOperand","bOpMode","pop","nextIns","getUserAddr","sAddr","nBase","doFreqs","cData","aaSortedOpcodeFreqs","sort","q","bOpcode","cFreq","sAddrEnd","addrEnd","sIns","asArgs","fIns","getRegs","doTrace","sCount","c","Web.onCountRepeat","input","sCmd","aOpBytes","sCode","iCode","aModeMatch","cModes","asHex","nHex","cBreaks","aAddrs","cLines","sLen","line","sChars","sBytes","addrLine","sOption","sCategory","iHistory","aHistory","nextHistory","nInsHistory","aeDbg","iDbg","eDbg","C1PComputer","parmsComputer","modules","power","C1PComputer.power","aeComputers","iComputer","eComputer","addrStart","iAddr","addrInfo","controlPrint","aComponents","iComponent","cAsyncMachines","loadXML","sXMLFile","fResolve","display","doneLoadXML","sURLName","sXML","parseXML","buildXML","sError","pathname","xmlDoc","async","parseFromString","DOMParser","resolveXML","matchRef","reRef","sRefFile","doneReadXML","sXMLRef","sRefAttrs","aXMLRefTag","sXMLNewTag","matchAttr","reAttr","embedMachine","sXSLFile","displayMessage","eWarning","aeWarning","eMachine","Str.escapeHTML","displayError","Web.enablePageEvents","getElementById","css","head","styleSheet","cssText","createTextNode","processXML","xml","transformXML","sXSL","xsl","sFragment","outerHTML","implementation","createDocument","xsltProcessor","XSLTProcessor","eFragment","replaceChild","embedC1P","commandMachine","fSingle","sComponent","sToken","chQuote"],"sourcesContent":["\"use strict\";\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/defines.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @define {string}\n */\nvar APPVERSION = \"\"; // this @define is overridden by the Closure Compiler with the version in machines.json\n\nvar XMLVERSION = null; // this is set in non-COMPILED builds by embedMachine() if a version number was found in the machine XML\n\nvar COPYRIGHT = \"Copyright © 2012-2018 Jeff Parsons <Jeff@pcjs.org>\";\n\nvar LICENSE = \"License: GPL version 3 or later <http://gnu.org/licenses/gpl.html>\";\n\nvar CSSCLASS = \"pcjs\";\n\n/**\n * @define {string}\n */\nvar SITEHOST = \"localhost:8088\";// this @define is overridden by the Closure Compiler with \"www.pcjs.org\"\n\n/**\n * @define {boolean}\n */\nvar COMPILED = false; // this @define is overridden by the Closure Compiler (to true)\n\n/**\n * @define {boolean}\n */\nvar DEBUG = true; // this @define is overridden by the Closure Compiler (to false) to remove DEBUG-only code\n\n/**\n * @define {boolean}\n */\nvar MAXDEBUG = false; // this @define is overridden by the Closure Compiler (to false) to remove MAXDEBUG-only code\n\n/**\n * @define {boolean}\n */\nvar PRIVATE = false; // this @define is overridden by the Closure Compiler (to false) to enable PRIVATE code\n\n/*\n * RS-232 DB-25 Pin Definitions, mapped to bits 1-25 in a 32-bit status value.\n *\n * SerialPorts in PCjs machines are considered DTE (Data Terminal Equipment), which means they should be \"virtually\"\n * connected to each other via a null-modem cable, which assumes the following cross-wiring:\n *\n * G 1 <-> 1 G (Ground)\n * TD 2 <-> 3 RD (Received Data)\n * RD 3 <-> 2 TD (Transmitted Data)\n * RTS 4 <-> 5 CTS (Clear To Send)\n * CTS 5 <-> 4 RTS (Request To Send)\n * DSR 6+8 <-> 20 DTR (Data Terminal Ready)\n * SG 7 <-> 7 SG (Signal Ground)\n * DTR 20 <-> 6+8 DSR (Data Set Ready + Carrier Detect)\n * RI 22 <-> 22 RI (Ring Indicator)\n *\n * TODO: Move these definitions to a more appropriate shared file at some point.\n */\nvar RS232 = {\n RTS: {\n PIN: 4,\n MASK: 0x00000010\n },\n CTS: {\n PIN: 5,\n MASK: 0x00000020\n },\n DSR: {\n PIN: 6,\n MASK: 0x00000040\n },\n CD: {\n PIN: 8,\n MASK: 0x00000100\n },\n DTR: {\n PIN: 20,\n MASK: 0x00100000\n },\n RI: {\n PIN: 22,\n MASK: 0x00400000\n }\n};\n\n/*\n * NODE should be true if we're running under NodeJS (eg, command-line), false if not (eg, web browser)\n */\nvar NODE = false;\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/dumpapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Our \"DiskDump API\", such as it was, used to look like:\n *\n * http://jsmachines.net/bin/convdisk.php?disk=/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json&format=img\n *\n * To make it (a bit) more \"REST-like\", the above request now looks like:\n *\n * http://www.pcjs.org/api/v1/dump?disk=/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json&format=img\n *\n * Similarly, our \"FileDump API\" used to look like:\n *\n * http://jsmachines.net/bin/convrom.php?rom=/devices/pc/rom/5150/1981-04-24/PCBIOS-REV1.rom&format=json\n *\n * and that request now looks like:\n *\n * http://www.pcjs.org/api/v1/dump?file=/devices/pc/rom/5150/1981-04-24/PCBIOS-REV1.rom&format=json\n *\n * I don't think it makes sense to avoid \"query\" parameters, because blending the path of a disk image with the\n * the rest of the URL would be (a) confusing, and (b) more work to parse.\n */\nvar DumpAPI = {\n ENDPOINT: \"/api/v1/dump\",\n QUERY: {\n DIR: \"dir\", // value is path of a directory (DiskDump only)\n DISK: \"disk\", // value is path of a disk image (DiskDump only)\n FILE: \"file\", // value is path of a ROM image file (FileDump only)\n IMG: \"img\", // alias for DISK\n PATH: \"path\", // value is path of a one or more files (DiskDump only)\n FORMAT: \"format\", // value is one of FORMAT values below\n COMMENTS: \"comments\", // value is either \"true\" or \"false\"\n DECIMAL: \"decimal\", // value is either \"true\" to force all numbers to decimal, \"false\" or undefined otherwise\n MBHD: \"mbhd\", // value is hard drive size in Mb (formerly \"mbsize\") (DiskDump only) (DEPRECATED)\n SIZE: \"size\" // value is target disk size in Kb (supersedes \"mbhd\") (DiskDump only)\n },\n FORMAT: {\n JSON: \"json\", // default\n JSON_GZ: \"gz\", // gzip is currently used ONLY for compressed JSON\n DATA: \"data\", // same as \"json\", but built without JSON.stringify() (DiskDump only)\n HEX: \"hex\", // deprecated\n OCTAL: \"octal\", // displays data as octal words\n BYTES: \"bytes\", // displays data as hex bytes; normally used only when comments are enabled\n WORDS: \"words\", // displays data as hex words; normally used only when comments are enabled\n LONGS: \"longs\", // displays data as dwords\n IMG: \"img\", // returns the raw disk data (ie, using a Buffer object) (DiskDump only)\n ROM: \"rom\" // returns the raw file data (ie, using a Buffer object) (FileDump only)\n }\n};\n\n/*\n * Because we use an overloaded API endpoint (ie, one that's shared with the FileDump module), we must\n * also provide a list of commands which, when combined with the endpoint, define a unique request.\n */\nDumpAPI.asDiskCommands = [DumpAPI.QUERY.DIR, DumpAPI.QUERY.DISK, DumpAPI.QUERY.PATH];\nDumpAPI.asFileCommands = [DumpAPI.QUERY.FILE];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/reportapi.js (C) Jeff Parsons 2012-2018\n */\n\nvar ReportAPI = {\n ENDPOINT: \"/api/v1/report\",\n QUERY: {\n APP: \"app\",\n VER: \"ver\",\n URL: \"url\",\n USER: \"user\",\n TYPE: \"type\",\n DATA: \"data\"\n },\n TYPE: {\n BUG: \"bug\"\n },\n RES: {\n OK: \"Thank you\"\n }\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/strlib.js (C) Jeff Parsons 2012-2018\n */\n\nclass Str {\n /**\n * isValidInt(s, base)\n *\n * The built-in parseInt() function has the annoying feature of returning a partial value (ie,\n * up to the point where it encounters an invalid character); eg, parseInt(\"foo\", 16) returns 0xf.\n *\n * So it's best to use our own Str.parseInt() function, which will in turn use this function to\n * validate the entire string.\n *\n * @param {string} s is the string representation of some number\n * @param {number} [base] is the radix to use (default is 10); only 2, 8, 10 and 16 are supported\n * @return {boolean} true if valid, false if invalid (or the specified base isn't supported)\n */\n static isValidInt(s, base)\n {\n if (!base || base == 10) return s.match(/^-?[0-9]+$/) !== null;\n if (base == 16) return s.match(/^-?[0-9a-f]+$/i) !== null;\n if (base == 8) return s.match(/^-?[0-7]+$/) !== null;\n if (base == 2) return s.match(/^-?[01]+$/) !== null;\n return false;\n }\n\n /**\n * parseInt(s, base)\n *\n * This is a wrapper around the built-in parseInt() function. Our wrapper recognizes certain prefixes\n * ('$' or \"0x\" for hex, '#' or \"0o\" for octal) and suffixes ('.' for decimal, 'h' for hex, 'y' for\n * binary), and then calls isValidInt() to ensure we don't convert strings that contain partial values;\n * see isValidInt() for details.\n *\n * The use of multiple prefix/suffix combinations is undefined (although for the record, we process\n * prefixes first). We do NOT support the \"0b\" prefix to indicate binary UNLESS one or more commas are\n * also present (because \"0b\" is also a valid hex sequence), and we do NOT support a single leading zero\n * to indicate octal (because such a number could also be decimal or hex). Any number of commas are\n * allowed; we remove them all before calling the built-in parseInt().\n *\n * More recently, we've added support for \"^D\", \"^O\", and \"^B\" prefixes to accommodate the base overrides\n * that the PDP-10's MACRO-10 assembly language supports (decimal, octal, and binary, respectively).\n * If this support turns out to adversely affect other debuggers, then it will have to be \"conditionalized\".\n * Similarly, we've added support for \"K\", \"M\", and \"G\" MACRO-10-style suffixes that add 3, 6, or 9 zeros\n * to the value to be parsed, respectively.\n *\n * @param {string} s is the string representation of some number\n * @param {number} [base] is the radix to use (default is 10); can be overridden by prefixes/suffixes\n * @return {number|undefined} corresponding value, or undefined if invalid\n */\n static parseInt(s, base)\n {\n var value;\n\n if (s) {\n if (!base) base = 10;\n\n var ch, chPrefix, chSuffix;\n var fCommas = (s.indexOf(',') > 0);\n if (fCommas) s = s.replace(/,/g, '');\n\n ch = chPrefix = s.charAt(0);\n if (chPrefix == '#') {\n base = 8;\n chPrefix = '';\n }\n else if (chPrefix == '$') {\n base = 16;\n chPrefix = '';\n }\n if (ch != chPrefix) {\n s = s.substr(1);\n }\n else {\n ch = chPrefix = s.substr(0, 2);\n if (chPrefix == '0b' && fCommas || chPrefix == '^B') {\n base = 2;\n chPrefix = '';\n }\n else if (chPrefix == '0o' || chPrefix == '^O') {\n base = 8;\n chPrefix = '';\n }\n else if (chPrefix == '^D') {\n base = 10;\n chPrefix = '';\n }\n else if (chPrefix == '0x') {\n base = 16;\n chPrefix = '';\n }\n if (ch != chPrefix) s = s.substr(2);\n }\n ch = chSuffix = s.slice(-1);\n if (chSuffix == 'Y' || chSuffix == 'y') {\n base = 2;\n chSuffix = '';\n }\n else if (chSuffix == '.') {\n base = 10;\n chSuffix = '';\n }\n else if (chSuffix == 'H' || chSuffix == 'h') {\n base = 16;\n chSuffix = '';\n }\n else if (chSuffix == 'K') {\n chSuffix = '000';\n }\n else if (chSuffix == 'M') {\n chSuffix = '000000';\n }\n else if (chSuffix == 'G') {\n chSuffix = '000000000';\n }\n if (ch != chSuffix) s = s.slice(0, -1) + chSuffix;\n /*\n * This adds support for the MACRO-10 binary shifting (Bn) suffix, which must be stripped from the\n * number before parsing, and then applied to the value after parsing. If n is omitted, 35 is assumed,\n * which is a net shift of zero. If n < 35, then a left shift of (35 - n) is required; if n > 35, then\n * a right shift of -(35 - n) is required.\n */\n var v, shift = 0;\n if (base <= 10) {\n var match = s.match(/(-?[0-9]+)B([0-9]*)/);\n if (match) {\n s = match[1];\n shift = 35 - ((match[2] || 35) & 0xff);\n }\n }\n if (Str.isValidInt(s, base) && !isNaN(v = parseInt(s, base))) {\n /*\n * With the need to support larger (eg, 36-bit) integers, truncating to 32 bits is no longer helpful.\n *\n * value = v|0;\n */\n if (shift) {\n /*\n * Since binary shifting is a logical operation, and since shifting by division only works properly\n * with positive numbers, we must convert a negative value to a positive value, by computing the two's\n * complement.\n */\n if (v < 0) v += Math.pow(2, 36);\n if (shift > 0) {\n v *= Math.pow(2, shift);\n } else {\n v = Math.trunc(v / Math.pow(2, -shift));\n }\n }\n value = v;\n }\n }\n return value;\n }\n\n /**\n * toBase(n, radix, cch, sPrefix, nGrouping)\n *\n * Displays the given number as an unsigned integer using the specified radix and number of digits.\n *\n * @param {number|null|undefined} n\n * @param {number} radix (ie, the base)\n * @param {number} cch (the desired number of digits)\n * @param {string} [sPrefix] (default is none)\n * @param {number} [nGrouping]\n * @return {string}\n */\n static toBase(n, radix, cch, sPrefix = \"\", nGrouping = 0)\n {\n /*\n * An initial \"falsey\" check for null takes care of both null and undefined;\n * we can't rely entirely on isNaN(), because isNaN(null) returns false, oddly enough.\n *\n * Alternatively, we could mask and shift n regardless of whether it's null/undefined/NaN,\n * since JavaScript coerces such operands to zero, but I think there's \"value\" in seeing those\n * values displayed differently.\n */\n var s = \"\";\n if (isNaN(n)) {\n n = null;\n } else if (n != null) {\n /*\n * Callers that produced an input by dividing by a power of two rather than shifting (in order\n * to access more than 32 bits) may produce a fractional result, which ordinarily we would simply\n * ignore, but if the integer portion is zero and the sign is negative, we should probably treat\n * this value as a sign-extension.\n */\n if (n < 0 && n > -1) n = -1;\n /*\n * Negative values should be two's complemented according to the number of digits; for example,\n * 12 octal digits implies an upper limit 8^12.\n */\n if (n < 0) {\n n += Math.pow(radix, cch);\n }\n if (n >= Math.pow(radix, cch)) {\n cch = Math.ceil(Math.log(n) / Math.log(radix));\n }\n }\n var g = nGrouping || -1;\n while (cch-- > 0) {\n if (!g) {\n s = ',' + s;\n g = nGrouping;\n }\n if (n == null) {\n s = '?' + s;\n } else {\n var d = n % radix;\n d += (d >= 0 && d <= 9? 0x30 : 0x41 - 10);\n s = String.fromCharCode(d) + s;\n n = Math.trunc(n / radix);\n }\n g--;\n }\n return sPrefix + s;\n }\n\n /**\n * toBin(n, cch, nGrouping)\n *\n * Converts an integer to binary, with the specified number of digits (up to a maximum of 36).\n *\n * @param {number|null|undefined} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of binary digits (0 or undefined for default of either 8, 18, or 36)\n * @param {number} [nGrouping]\n * @return {string} the binary representation of n\n */\n static toBin(n, cch, nGrouping)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.LN2) || 1;\n var v = Math.abs(n);\n if (v <= 0b11111111) {\n cch = 8;\n } else if (v <= 0b111111111111111111) {\n cch = 18;\n } else {\n cch = 36;\n }\n } else if (cch > 36) cch = 36;\n return Str.toBase(n, 2, cch, \"\", nGrouping);\n }\n\n /**\n * toBinBytes(n, cb, fPrefix)\n *\n * Converts an integer to binary, with the specified number of bytes (up to the default of 4).\n *\n * @param {number|null|undefined} n (interpreted as a 32-bit value)\n * @param {number} [cb] is the desired number of binary bytes (4 is both the default and the maximum)\n * @param {boolean} [fPrefix]\n * @return {string} the binary representation of n\n */\n static toBinBytes(n, cb, fPrefix)\n {\n var s = \"\";\n if (!cb || cb > 4) cb = 4;\n for (var i = 0; i < cb; i++) {\n if (s) s = ',' + s;\n s = Str.toBin(n & 0xff, 8) + s;\n n >>= 8;\n }\n return (fPrefix? \"0b\" : \"\") + s;\n }\n\n /**\n * toOct(n, cch, fPrefix)\n *\n * Converts an integer to octal, with the specified number of digits (default of 6; max of 12)\n *\n * You might be tempted to use the built-in n.toString(8) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw\n * an exception, whereas this function will return '?' characters.\n *\n * @param {number|null|undefined} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of octal digits (0 or undefined for default of either 6, 8, or 12)\n * @param {boolean} [fPrefix]\n * @return {string} the octal representation of n\n */\n static toOct(n, cch, fPrefix)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.log(8)) || 1;\n var v = Math.abs(n);\n if (v <= 0o777777) {\n cch = 6;\n } else if (v <= 0o77777777) {\n cch = 8;\n } else {\n cch = 12;\n }\n } else if (cch > 12) cch = 12;\n return Str.toBase(n, 8, cch, fPrefix? \"0o\" : \"\");\n }\n\n /**\n * toDec(n, cch)\n *\n * Converts an integer to decimal, with the specified number of digits (default of 5; max of 11)\n *\n * You might be tempted to use the built-in n.toString(10) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw\n * an exception, whereas this function will return '?' characters.\n *\n * @param {number|null|undefined} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of decimal digits (0 or undefined for default of either 5 or 11)\n * @return {string} the decimal representation of n\n */\n static toDec(n, cch)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.LN10) || 1;\n var v = Math.abs(n);\n if (v <= 99999) {\n cch = 5;\n } else {\n cch = 11;\n }\n } else if (cch > 11) cch = 11;\n return Str.toBase(n, 10, cch);\n }\n\n /**\n * toHex(n, cch, fPrefix)\n *\n * Converts an integer to hex, with the specified number of digits (default of 4 or 8, max of 9).\n *\n * You might be tempted to use the built-in n.toString(16) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values; for example, if n is -2147483647, then n.toString(16)\n * will return \"-7fffffff\" instead of \"80000001\". Moreover, if n is undefined, n.toString() will\n * throw an exception, whereas this function will return '?' characters.\n *\n * NOTE: The following work-around (adapted from code found on StackOverflow) would be another solution,\n * taking care of negative values, zero-padding, and upper-casing, but not null/undefined/NaN values:\n *\n * s = (n < 0? n + 0x100000000 : n).toString(16);\n * s = \"00000000\".substr(0, 8 - s.length) + s;\n * s = s.substr(0, cch).toUpperCase();\n *\n * @param {number|null|undefined} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of hex digits (0 or undefined for default of either 4, 8, or 9)\n * @param {boolean} [fPrefix]\n * @return {string} the hex representation of n\n */\n static toHex(n, cch, fPrefix)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.log(16)) || 1;\n var v = Math.abs(n);\n if (v <= 0xffff) {\n cch = 4;\n } else if (v <= 0xffffffff) {\n cch = 8;\n } else {\n cch = 9;\n }\n } else if (cch > 9) cch = 9;\n return Str.toBase(n, 16, cch, fPrefix? \"0x\" : \"\");\n }\n\n /**\n * toHexByte(b)\n *\n * Alias for Str.toHex(b, 2, true)\n *\n * @param {number|null|undefined} b is a byte value\n * @return {string} the hex representation of b\n */\n static toHexByte(b)\n {\n return Str.toHex(b, 2, true);\n }\n\n /**\n * toHexWord(w)\n *\n * Alias for Str.toHex(w, 4, true)\n *\n * @param {number|null|undefined} w is a word (16-bit) value\n * @return {string} the hex representation of w\n */\n static toHexWord(w)\n {\n return Str.toHex(w, 4, true);\n }\n\n /**\n * toHexLong(l)\n *\n * Alias for Str.toHex(l, 8, true)\n *\n * @param {number|null|undefined} l is a dword (32-bit) value\n * @return {string} the hex representation of w\n */\n static toHexLong(l)\n {\n return Str.toHex(l, 8, true);\n }\n\n /**\n * getBaseName(sFileName, fStripExt)\n *\n * This is a poor-man's version of Node's path.basename(), which Node-only components should use instead.\n *\n * Note that if fStripExt is true, this strips ANY extension, whereas path.basename() strips the extension only\n * if it matches the second parameter (eg, path.basename(\"/foo/bar/baz/asdf/quux.html\", \".html\") returns \"quux\").\n *\n * @param {string} sFileName\n * @param {boolean} [fStripExt]\n * @return {string}\n */\n static getBaseName(sFileName, fStripExt)\n {\n var sBaseName = sFileName;\n\n var i = sFileName.lastIndexOf('/');\n if (i >= 0) sBaseName = sFileName.substr(i + 1);\n\n /*\n * This next bit is a kludge to clean up names that are part of a URL that includes unsightly query parameters.\n */\n i = sBaseName.indexOf('&');\n if (i > 0) sBaseName = sBaseName.substr(0, i);\n\n if (fStripExt) {\n i = sBaseName.lastIndexOf(\".\");\n if (i > 0) {\n sBaseName = sBaseName.substring(0, i);\n }\n }\n return sBaseName;\n }\n\n /**\n * getExtension(sFileName)\n *\n * This is a poor-man's version of Node's path.extname(), which Node-only components should use instead.\n *\n * Note that we EXCLUDE the period from the returned extension, whereas path.extname() includes it.\n *\n * @param {string} sFileName\n * @return {string} the filename's extension (in lower-case and EXCLUDING the \".\"), or an empty string\n */\n static getExtension(sFileName)\n {\n var sExtension = \"\";\n var i = sFileName.lastIndexOf(\".\");\n if (i >= 0) {\n sExtension = sFileName.substr(i + 1).toLowerCase();\n }\n return sExtension;\n }\n\n /**\n * endsWith(s, sSuffix)\n *\n * @param {string} s\n * @param {string} sSuffix\n * @return {boolean} true if s ends with sSuffix, false if not\n */\n static endsWith(s, sSuffix)\n {\n return s.indexOf(sSuffix, s.length - sSuffix.length) !== -1;\n }\n\n /**\n * escapeHTML(sHTML)\n *\n * @param {string} sHTML\n * @return {string} with HTML entities \"escaped\", similar to PHP's htmlspecialchars()\n */\n static escapeHTML(sHTML)\n {\n return sHTML.replace(/[&<>\"']/g, function(m)\n {\n return Str.HTMLEscapeMap[m];\n });\n }\n\n /**\n * replace(sSearch, sReplace, s)\n *\n * The JavaScript replace() function ALWAYS interprets \"$\" specially in replacement strings, even when\n * the search string is NOT a RegExp; specifically:\n *\n * $$ Inserts a \"$\"\n * $& Inserts the matched substring\n * $` Inserts the portion of the string that precedes the matched substring\n * $' Inserts the portion of the string that follows the matched substring\n * $n Where n is a positive integer less than 100, inserts the nth parenthesized sub-match string,\n * provided the first argument was a RegExp object\n *\n * So, if a replacement string containing dollar signs passes through a series of replace() calls, untold\n * problems could result. Hence, this function, which simply uses the replacement string as-is.\n *\n * Similar to the JavaScript replace() method (when sSearch is a string), this replaces only ONE occurrence\n * (ie, the FIRST occurrence); it might be nice to add options to replace the LAST occurrence and/or ALL\n * occurrences, but we'll revisit that later.\n *\n * @param {string} sSearch\n * @param {string} sReplace\n * @param {string} s\n * @return {string}\n */\n static replace(sSearch, sReplace, s)\n {\n var i = s.indexOf(sSearch);\n if (i >= 0) {\n s = s.substr(0, i) + sReplace + s.substr(i + sSearch.length);\n }\n return s;\n }\n\n /**\n * replaceAll(sSearch, sReplace, s)\n *\n * @param {string} sSearch\n * @param {string} sReplace\n * @param {string} s\n * @return {string}\n */\n static replaceAll(sSearch, sReplace, s)\n {\n var a = {};\n a[sSearch] = sReplace;\n return Str.replaceArray(a, s);\n }\n\n /**\n * replaceArray(a, s)\n *\n * @param {Object} a\n * @param {string} s\n * @return {string}\n */\n static replaceArray(a, s)\n {\n var sMatch = \"\";\n for (var k in a) {\n /*\n * As noted in:\n *\n * http://www.regexguru.com/2008/04/escape-characters-only-when-necessary/\n *\n * inside character classes, only backslash, caret, hyphen and the closing bracket need to be\n * escaped. And in fact, if you ensure that the closing bracket is first, the caret is not first,\n * and the hyphen is last, you can avoid escaping those as well.\n */\n k = k.replace(/([\\\\[\\]*{}().+?|$])/g, \"\\\\$1\");\n sMatch += (sMatch? '|' : '') + k;\n }\n return s.replace(new RegExp('(' + sMatch + ')', \"g\"), function(m)\n {\n return a[m];\n });\n }\n\n /**\n * pad(s, cch, fPadLeft)\n *\n * NOTE: the maximum amount of padding currently supported is 40 spaces.\n *\n * @param {string} s is a string\n * @param {number} cch is desired length\n * @param {boolean} [fPadLeft] (default is padding on the right)\n * @return {string} the original string (s) with spaces padding it to the specified length\n */\n static pad(s, cch, fPadLeft)\n {\n var sPadding = \" \";\n return fPadLeft? (sPadding + s).slice(-cch) : (s + sPadding).slice(0, cch);\n }\n\n /**\n * sprintf(format, ...args)\n *\n * Copied from the CCjs project (https://github.com/jeffpar/ccjs/blob/master/lib/stdio.js) and extended.\n *\n * Far from complete, let alone sprintf-compatible, but it's adequate for the handful of sprintf-style format\n * specifiers that I use.\n *\n * @param {string} format\n * @param {...} args\n * @return {string}\n */\n static sprintf(format, ...args)\n {\n let buffer = \"\";\n let aParts = format.split(/%([-+ 0#]?)([0-9]*)(\\.?)([0-9]*)([hlL]?)([A-Za-z%])/);\n\n let iArg = 0, iPart;\n for (iPart = 0; iPart < aParts.length - 7; iPart += 7) {\n\n buffer += aParts[iPart];\n\n let arg = args[iArg++];\n let flags = aParts[iPart+1];\n let minimum = +aParts[iPart+2] || 0;\n let precision = +aParts[iPart+4] || 0;\n let conversion = aParts[iPart+6];\n let ach = null, s;\n\n switch(conversion) {\n case 'd':\n /*\n * We could use \"arg |= 0\", but there may be some value to supporting integers > 32 bits.\n * \n * Also, unlike the 'X' and 'x' hexadecimal cases, there's no need to explicitly check for a string\n * arguments, because the call to trunc() automatically coerces any string value to a (decimal) number.\n */\n arg = Math.trunc(arg);\n /* falls through */\n\n case 'f':\n s = Math.trunc(arg) + \"\";\n if (precision) {\n minimum -= (precision + 1);\n }\n if (s.length < minimum) {\n if (flags == '0') {\n if (arg < 0) minimum--;\n s = (\"0000000000\" + Math.abs(arg)).slice(-minimum);\n if (arg < 0) s = '-' + s;\n } else {\n s = (\" \" + s).slice(-minimum);\n }\n }\n if (precision) {\n arg = Math.round((arg - Math.trunc(arg)) * Math.pow(10, precision));\n s += '.' + (\"0000000000\" + Math.abs(arg)).slice(-precision);\n }\n buffer += s;\n break;\n\n case 'c':\n arg = String.fromCharCode(arg);\n /* falls through */\n\n case 's':\n if (typeof arg == \"string\") {\n while (arg.length < minimum) {\n if (flags == '-') {\n arg += ' ';\n } else {\n arg = ' ' + arg;\n }\n }\n }\n buffer += arg;\n break;\n\n case 'X':\n ach = Str.HexUpperCase;\n /* falls through */\n\n case 'x':\n if (!ach) ach = Str.HexLowerCase;\n s = \"\";\n if (typeof arg == \"string\") {\n /*\n * Since we're advised to ALWAYS pass a radix to parseInt(), we must detect explicitly\n * hex values ourselves, because using a radix of 10 with any \"0x...\" value always returns 0.\n * \n * And if the value CAN be interpreted as decimal, then we MUST interpret it as decimal, because\n * we have sprintf() calls in /modules/lib/testmon.js that depend on this code to perform decimal\n * to hex conversion. We're allowed to make our own rules here, since passing numbers in string\n * form isn't part of the sprintf \"spec\". \n */\n arg = Number.parseInt(arg, arg.match(/(^0x|[a-f])/i)? 16 : 10);\n } \n do {\n s = ach[arg & 0xf] + s;\n arg >>>= 4;\n } while (--minimum > 0 || arg);\n buffer += s;\n break;\n\n default:\n /*\n * The supported ANSI C set of conversions: \"dioxXucsfeEgGpn%\"\n */\n buffer += \"(unrecognized printf conversion %\" + conversion + \")\";\n break;\n }\n }\n\n buffer += aParts[iPart];\n return buffer;\n }\n\n /**\n * stripLeadingZeros(s, fPad)\n *\n * @param {string} s\n * @param {boolean} [fPad]\n * @return {string}\n */\n static stripLeadingZeros(s, fPad)\n {\n var cch = s.length;\n s = s.replace(/^0+([0-9A-F]+)$/i, \"$1\");\n if (fPad) s = Str.pad(s, cch, true);\n return s;\n }\n\n /**\n * trim(s)\n *\n * @param {string} s\n * @return {string}\n */\n static trim(s)\n {\n if (String.prototype.trim) {\n return s.trim();\n }\n return s.replace(/^\\s+|\\s+$/g, \"\");\n }\n\n /**\n * toASCIICode(b)\n *\n * @param {number} b\n * @return {string}\n */\n static toASCIICode(b)\n {\n var s;\n if (b != Str.ASCII.CR && b != Str.ASCII.LF) {\n s = Str.ASCIICodeMap[b];\n }\n if (s) {\n s = '<' + s + '>';\n } else {\n s = String.fromCharCode(b);\n }\n return s;\n }\n}\n\n/*\n * Map special characters to their HTML escape sequences.\n */\nStr.HTMLEscapeMap = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n};\n\n/*\n * Map \"unprintable\" ASCII codes to mnemonics, to more clearly see what's being printed.\n */\nStr.ASCIICodeMap = {\n 0x00: \"NUL\",\n 0x01: \"SOH\", // (CTRL_A) Start of Heading\n 0x02: \"STX\", // (CTRL_B) Start of Text\n 0x03: \"ETX\", // (CTRL_C) End of Text\n 0x04: \"EOT\", // (CTRL_D) End of Transmission\n 0x05: \"ENQ\", // (CTRL_E) Enquiry\n 0x06: \"ACK\", // (CTRL_F) Acknowledge\n 0x07: \"BEL\", // (CTRL_G) Bell\n 0x08: \"BS\", // (CTRL_H) Backspace\n 0x09: \"TAB\", // (CTRL_I) Horizontal Tab (aka HT)\n 0x0A: \"LF\", // (CTRL_J) Line Feed (New Line)\n 0x0B: \"VT\", // (CTRL_K) Vertical Tab\n 0x0C: \"FF\", // (CTRL_L) Form Feed (New Page)\n 0x0D: \"CR\", // (CTRL_M) Carriage Return\n 0x0E: \"SO\", // (CTRL_N) Shift Out\n 0x0F: \"SI\", // (CTRL_O) Shift In\n 0x10: \"DLE\", // (CTRL_P) Data Link Escape\n 0x11: \"XON\", // (CTRL_Q) Device Control 1 (aka DC1)\n 0x12: \"DC2\", // (CTRL_R) Device Control 2\n 0x13: \"XOFF\", // (CTRL_S) Device Control 3 (aka DC3)\n 0x14: \"DC4\", // (CTRL_T) Device Control 4\n 0x15: \"NAK\", // (CTRL_U) Negative Acknowledge\n 0x16: \"SYN\", // (CTRL_V) Synchronous Idle\n 0x17: \"ETB\", // (CTRL_W) End of Transmission Block\n 0x18: \"CAN\", // (CTRL_X) Cancel\n 0x19: \"EM\", // (CTRL_Y) End of Medium\n 0x1A: \"SUB\", // (CTRL_Z) Substitute\n 0x1B: \"ESC\", // Escape\n 0x1C: \"FS\", // File Separator\n 0x1D: \"GS\", // Group Separator\n 0x1E: \"RS\", // Record Separator\n 0x1F: \"US\", // Unit Separator\n 0x7F: \"DEL\"\n};\n\n/*\n * Refer to: https://en.wikipedia.org/wiki/Code_page_437\n */\nStr.CP437ToUnicode = [\n '\\u0000', '\\u263A', '\\u263B', '\\u2665', '\\u2666', '\\u2663', '\\u2660', '\\u2022',\n '\\u25D8', '\\u25CB', '\\u25D9', '\\u2642', '\\u2640', '\\u266A', '\\u266B', '\\u263C',\n '\\u25BA', '\\u25C4', '\\u2195', '\\u203C', '\\u00B6', '\\u00A7', '\\u25AC', '\\u21A8',\n '\\u2191', '\\u2193', '\\u2192', '\\u2190', '\\u221F', '\\u2194', '\\u25B2', '\\u25BC',\n '\\u0020', '\\u0021', '\\u0022', '\\u0023', '\\u0024', '\\u0025', '\\u0026', '\\u0027',\n '\\u0028', '\\u0029', '\\u002A', '\\u002B', '\\u002C', '\\u002D', '\\u002E', '\\u002F',\n '\\u0030', '\\u0031', '\\u0032', '\\u0033', '\\u0034', '\\u0035', '\\u0036', '\\u0037',\n '\\u0038', '\\u0039', '\\u003A', '\\u003B', '\\u003C', '\\u003D', '\\u003E', '\\u003F',\n '\\u0040', '\\u0041', '\\u0042', '\\u0043', '\\u0044', '\\u0045', '\\u0046', '\\u0047',\n '\\u0048', '\\u0049', '\\u004A', '\\u004B', '\\u004C', '\\u004D', '\\u004E', '\\u004F',\n '\\u0050', '\\u0051', '\\u0052', '\\u0053', '\\u0054', '\\u0055', '\\u0056', '\\u0057',\n '\\u0058', '\\u0059', '\\u005A', '\\u005B', '\\u005C', '\\u005D', '\\u005E', '\\u005F',\n '\\u0060', '\\u0061', '\\u0062', '\\u0063', '\\u0064', '\\u0065', '\\u0066', '\\u0067',\n '\\u0068', '\\u0069', '\\u006A', '\\u006B', '\\u006C', '\\u006D', '\\u006E', '\\u006F',\n '\\u0070', '\\u0071', '\\u0072', '\\u0073', '\\u0074', '\\u0075', '\\u0076', '\\u0077',\n '\\u0078', '\\u0079', '\\u007A', '\\u007B', '\\u007C', '\\u007D', '\\u007E', '\\u2302',\n '\\u00C7', '\\u00FC', '\\u00E9', '\\u00E2', '\\u00E4', '\\u00E0', '\\u00E5', '\\u00E7',\n '\\u00EA', '\\u00EB', '\\u00E8', '\\u00EF', '\\u00EE', '\\u00EC', '\\u00C4', '\\u00C5',\n '\\u00C9', '\\u00E6', '\\u00C6', '\\u00F4', '\\u00F6', '\\u00F2', '\\u00FB', '\\u00F9',\n '\\u00FF', '\\u00D6', '\\u00DC', '\\u00A2', '\\u00A3', '\\u00A5', '\\u20A7', '\\u0192',\n '\\u00E1', '\\u00ED', '\\u00F3', '\\u00FA', '\\u00F1', '\\u00D1', '\\u00AA', '\\u00BA',\n '\\u00BF', '\\u2310', '\\u00AC', '\\u00BD', '\\u00BC', '\\u00A1', '\\u00AB', '\\u00BB',\n '\\u2591', '\\u2592', '\\u2593', '\\u2502', '\\u2524', '\\u2561', '\\u2562', '\\u2556',\n '\\u2555', '\\u2563', '\\u2551', '\\u2557', '\\u255D', '\\u255C', '\\u255B', '\\u2510',\n '\\u2514', '\\u2534', '\\u252C', '\\u251C', '\\u2500', '\\u253C', '\\u255E', '\\u255F',\n '\\u255A', '\\u2554', '\\u2569', '\\u2566', '\\u2560', '\\u2550', '\\u256C', '\\u2567',\n '\\u2568', '\\u2564', '\\u2565', '\\u2559', '\\u2558', '\\u2552', '\\u2553', '\\u256B',\n '\\u256A', '\\u2518', '\\u250C', '\\u2588', '\\u2584', '\\u258C', '\\u2590', '\\u2580',\n '\\u03B1', '\\u00DF', '\\u0393', '\\u03C0', '\\u03A3', '\\u03C3', '\\u00B5', '\\u03C4',\n '\\u03A6', '\\u0398', '\\u03A9', '\\u03B4', '\\u221E', '\\u03C6', '\\u03B5', '\\u2229',\n '\\u2261', '\\u00B1', '\\u2265', '\\u2264', '\\u2320', '\\u2321', '\\u00F7', '\\u2248',\n '\\u00B0', '\\u2219', '\\u00B7', '\\u221A', '\\u207F', '\\u00B2', '\\u25A0', '\\u00A0'\n];\n\n/*\n * TODO: Future home of a complete ASCII table.\n */\nStr.ASCII = {\n LF: 0x0A,\n CR: 0x0D\n};\n\nStr.TYPES = {\n NULL: 0,\n BYTE: 1,\n WORD: 2,\n DWORD: 3,\n NUMBER: 4,\n STRING: 5,\n BOOLEAN: 6,\n OBJECT: 7,\n ARRAY: 8\n};\n\nStr.HexLowerCase = \"0123456789abcdef\";\nStr.HexUpperCase = \"0123456789ABCDEF\";\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/usrlib.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @typedef {{\n * mask: number,\n * shift: number\n * }}\n */\nvar BitField;\n\n/**\n * @typedef {Object.<BitField>}\n */\nvar BitFields;\n\nclass Usr {\n /**\n * binarySearch(a, v, fnCompare)\n *\n * @param {Array} a is an array\n * @param {number|string|Array|Object} v\n * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]\n * @return {number} the index of matching entry if non-negative, otherwise the index of the insertion point\n */\n static binarySearch(a, v, fnCompare)\n {\n var left = 0;\n var right = a.length;\n var found = 0;\n if (fnCompare === undefined) {\n fnCompare = function(a, b)\n {\n return a > b ? 1 : a < b ? -1 : 0;\n };\n }\n while (left < right) {\n var middle = (left + right) >> 1;\n var compareResult;\n compareResult = fnCompare(v, a[middle]);\n if (compareResult > 0) {\n left = middle + 1;\n } else {\n right = middle;\n found = !compareResult;\n }\n }\n return found ? left : ~left;\n }\n\n /**\n * binaryInsert(a, v, fnCompare)\n *\n * If element v already exists in array a, the array is unchanged (we don't allow duplicates); otherwise, the\n * element is inserted into the array at the appropriate index.\n *\n * @param {Array} a is an array\n * @param {number|string|Array|Object} v is the value to insert\n * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]\n */\n static binaryInsert(a, v, fnCompare)\n {\n var index = Usr.binarySearch(a, v, fnCompare);\n if (index < 0) {\n a.splice(-(index + 1), 0, v);\n }\n }\n\n /**\n * getTimestamp()\n *\n * @return {string} timestamp containing the current date and time (\"yyyy-mm-dd hh:mm:ss\")\n */\n static getTimestamp()\n {\n return Usr.formatDate(\"Y-m-d H:i:s\");\n }\n\n /**\n * getMonthDays(nMonth, nYear)\n *\n * Note that if we're being called on behalf of the RTC, its year is always truncated to two digits (mod 100),\n * so we have no idea what century the year 0 might refer to. When using the normal leap-year formula, 0 fails\n * the mod 100 test but passes the mod 400 test, so as far as the RTC is concerned, every century year is a leap\n * year. Since we're most likely dealing with the year 2000, that's fine, since 2000 was also a leap year.\n *\n * TODO: There IS a separate CMOS byte that's supposed to be set to CMOS_ADDR.CENTURY_DATE; it's always BCD,\n * so theoretically it will contain values like 0x19 or 0x20 (for the 20th and 21st centuries, respectively), and\n * we could add that as another parameter to this function, to improve the accuracy, but that would go beyond what\n * a real RTC actually does.\n *\n * @param {number} nMonth (1-12)\n * @param {number} nYear (normally a 4-digit year, but it may also be mod 100)\n * @return {number} the maximum (1-based) day allowed for the specified month and year\n */\n static getMonthDays(nMonth, nYear)\n {\n var nDays = Usr.aMonthDays[nMonth - 1];\n if (nDays == 28) {\n if ((nYear % 4) === 0 && ((nYear % 100) || (nYear % 400) === 0)) {\n nDays++;\n }\n }\n return nDays;\n }\n\n /**\n * formatDate(sFormat, date)\n *\n * @param {string} sFormat (eg, \"F j, Y\", \"Y-m-d H:i:s\")\n * @param {Date} [date] (default is the current time)\n * @return {string}\n *\n * Supported identifiers in sFormat include:\n *\n * a: lowercase ante meridiem and post meridiem (am or pm)\n * d: day of the month, 2 digits with leading zeros (01,02,...,31)\n * D: 3-letter day of the week (\"Sun\",\"Mon\",...,\"Sat\")\n * F: month (\"January\",\"February\",...,\"December\")\n * g: hour in 12-hour format, without leading zeros (1,2,...,12)\n * h: hour in 24-hour format, without leading zeros (0,1,...,23)\n * H: hour in 24-hour format, with leading zeros (00,01,...,23)\n * i: minutes, with leading zeros (00,01,...,59)\n * j: day of the month, without leading zeros (1,2,...,31)\n * l: day of the week (\"Sunday\",\"Monday\",...,\"Saturday\")\n * m: month, with leading zeros (01,02,...,12)\n * M: 3-letter month (\"Jan\",\"Feb\",...,\"Dec\")\n * n: month, without leading zeros (1,2,...,12)\n * s: seconds, with leading zeros (00,01,...,59)\n * y: 2-digit year (eg, 14)\n * Y: 4-digit year (eg, 2014)\n *\n * For more inspiration, see: http://php.net/manual/en/function.date.php (of which we support ONLY a subset).\n */\n static formatDate(sFormat, date)\n {\n var sDate = \"\";\n if (!date) date = new Date();\n var iHour = date.getHours();\n var iDay = date.getDate();\n var iMonth = date.getMonth() + 1;\n for (var i = 0; i < sFormat.length; i++) {\n var ch;\n switch ((ch = sFormat.charAt(i))) {\n case 'a':\n sDate += (iHour < 12 ? \"am\" : \"pm\");\n break;\n case 'd':\n sDate += ('0' + iDay).slice(-2);\n break;\n case 'D':\n sDate += Usr.asDays[date.getDay()].substr(0, 3);\n break;\n case 'F':\n sDate += Usr.asMonths[iMonth - 1];\n break;\n case 'g':\n sDate += (!iHour ? 12 : (iHour > 12 ? iHour - 12 : iHour));\n break;\n case 'h':\n sDate += iHour;\n break;\n case 'H':\n sDate += ('0' + iHour).slice(-2);\n break;\n case 'i':\n sDate += ('0' + date.getMinutes()).slice(-2);\n break;\n case 'j':\n sDate += iDay;\n break;\n case 'l':\n sDate += Usr.asDays[date.getDay()];\n break;\n case 'm':\n sDate += ('0' + iMonth).slice(-2);\n break;\n case 'M':\n sDate += Usr.asMonths[iMonth - 1].substr(0, 3);\n break;\n case 'n':\n sDate += iMonth;\n break;\n case 's':\n sDate += ('0' + date.getSeconds()).slice(-2);\n break;\n case 'y':\n sDate += (\"\" + date.getFullYear()).slice(-2);\n break;\n case 'Y':\n sDate += date.getFullYear();\n break;\n default:\n sDate += ch;\n break;\n }\n }\n return sDate;\n }\n\n /**\n * defineBitFields(bfs)\n *\n * Prepares a bit field definition for use with getBitField() and setBitField(); eg:\n *\n * var bfs = Usr.defineBitFields({num:20, count:8, btmod:1, type:3});\n *\n * The above defines a set of bit fields containing four fields: num (bits 0-19), count (bits 20-27), btmod (bit 28), and type (bits 29-31).\n *\n * Usr.setBitField(bfs.num, n, 1);\n *\n * The above set bit field \"bfs.num\" in numeric variable \"n\" to the value 1.\n *\n * @param {Object} bfs\n * @return {BitFields}\n */\n static defineBitFields(bfs)\n {\n var bit = 0;\n for (var f in bfs) {\n var width = bfs[f];\n var mask = ((1 << width) - 1) << bit;\n bfs[f] = {mask: mask, shift: bit};\n bit += width;\n }\n return bfs;\n }\n\n /**\n * initBitFields(bfs, ...)\n *\n * @param {BitFields} bfs\n * @param {...number} var_args\n * @return {number} a value containing all supplied bit fields\n */\n static initBitFields(bfs, var_args)\n {\n var v = 0, i = 1;\n for (var f in bfs) {\n if (i >= arguments.length) break;\n v = Usr.setBitField(bfs[f], v, arguments[i++]);\n }\n return v;\n }\n\n /**\n * getBitField(bf, v)\n *\n * @param {BitField} bf\n * @param {number} v is a value containing bit fields\n * @return {number} the value of the bit field in v defined by bf\n */\n static getBitField(bf, v)\n {\n return (v & bf.mask) >> bf.shift;\n }\n\n /**\n * setBitField(bf, v, n)\n *\n * @param {BitField} bf\n * @param {number} v is a value containing bit fields\n * @param {number} n is a value to store in v in the bit field defined by bf\n * @return {number} updated v\n */\n static setBitField(bf, v, n)\n {\n return (v & ~bf.mask) | ((n << bf.shift) & bf.mask);\n }\n\n /**\n * indexOf(a, t, i)\n *\n * Use this instead of Array.prototype.indexOf() if you can't be sure the browser supports it.\n *\n * @param {Array} a\n * @param {*} t\n * @param {number} [i]\n * @returns {number}\n */\n static indexOf(a, t, i)\n {\n if (Array.prototype.indexOf) {\n return a.indexOf(t, i);\n }\n i = i || 0;\n if (i < 0) i += a.length;\n if (i < 0) i = 0;\n for (var n = a.length; i < n; i++) {\n if (i in a && a[i] === t) return i;\n }\n return -1;\n }\n}\n\nUsr.asDays = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\nUsr.asMonths = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\nUsr.aMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\n/**\n * getTime()\n *\n * @return {number} the current time, in milliseconds\n */\nUsr.getTime = Date.now || function() { return +new Date(); };\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/weblib.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * According to http://www.w3schools.com/jsref/jsref_obj_global.asp, these are the *global* properties\n * and functions of JavaScript-in-the-Browser:\n *\n * Property Description\n * ---\n * Infinity A numeric value that represents positive/negative infinity\n * NaN \"Not-a-Number\" value\n * undefined Indicates that a variable has not been assigned a value\n *\n * Function Description\n * ---\n * decodeURI() Decodes a URI\n * decodeURIComponent() Decodes a URI component\n * encodeURI() Encodes a URI\n * encodeURIComponent() Encodes a URI component\n * escape() Deprecated in version 1.5. Use encodeURI() or encodeURIComponent() instead\n * eval() Evaluates a string and executes it as if it was script code\n * isFinite() Determines whether a value is a finite, legal number\n * isNaN() Determines whether a value is an illegal number\n * Number() Converts an object's value to a number\n * parseFloat() Parses a string and returns a floating point number\n * parseInt() Parses a string and returns an integer\n * String() Converts an object's value to a string\n * unescape() Deprecated in version 1.5. Use decodeURI() or decodeURIComponent() instead\n *\n * And according to http://www.w3schools.com/jsref/obj_window.asp, these are the properties and functions\n * of the *window* object.\n *\n * Property Description\n * ---\n * closed Returns a Boolean value indicating whether a window has been closed or not\n * defaultStatus Sets or returns the default text in the statusbar of a window\n * document Returns the Document object for the window (See Document object)\n * frames Returns an array of all the frames (including iframes) in the current window\n * history Returns the History object for the window (See History object)\n * innerHeight Returns the inner height of a window's content area\n * innerWidth Returns the inner width of a window's content area\n * length Returns the number of frames (including iframes) in a window\n * location Returns the Location object for the window (See Location object)\n * name Sets or returns the name of a window\n * navigator Returns the Navigator object for the window (See Navigator object)\n * opener Returns a reference to the window that created the window\n * outerHeight Returns the outer height of a window, including toolbars/scrollbars\n * outerWidth Returns the outer width of a window, including toolbars/scrollbars\n * pageXOffset Returns the pixels the current document has been scrolled (horizontally) from the upper left corner of the window\n * pageYOffset Returns the pixels the current document has been scrolled (vertically) from the upper left corner of the window\n * parent Returns the parent window of the current window\n * screen Returns the Screen object for the window (See Screen object)\n * screenLeft Returns the x coordinate of the window relative to the screen\n * screenTop Returns the y coordinate of the window relative to the screen\n * screenX Returns the x coordinate of the window relative to the screen\n * screenY Returns the y coordinate of the window relative to the screen\n * self Returns the current window\n * status Sets or returns the text in the statusbar of a window\n * top Returns the topmost browser window\n *\n * Method Description\n * ---\n * alert() Displays an alert box with a message and an OK button\n * atob() Decodes a base-64 encoded string\n * blur() Removes focus from the current window\n * btoa() Encodes a string in base-64\n * clearInterval() Clears a timer set with setInterval()\n * clearTimeout() Clears a timer set with setTimeout()\n * close() Closes the current window\n * confirm() Displays a dialog box with a message and an OK and a Cancel button\n * createPopup() Creates a pop-up window\n * focus() Sets focus to the current window\n * moveBy() Moves a window relative to its current position\n * moveTo() Moves a window to the specified position\n * open() Opens a new browser window\n * print() Prints the content of the current window\n * prompt() Displays a dialog box that prompts the visitor for input\n * resizeBy() Resizes the window by the specified pixels\n * resizeTo() Resizes the window to the specified width and height\n * scroll() This method has been replaced by the scrollTo() method.\n * scrollBy() Scrolls the content by the specified number of pixels\n * scrollTo() Scrolls the content to the specified coordinates\n * setInterval() Calls a function or evaluates an expression at specified intervals (in milliseconds)\n * setTimeout() Calls a function or evaluates an expression after a specified number of milliseconds\n * stop() Stops the window from loading\n */\n\nclass Web {\n /**\n * log(s, type)\n *\n * For diagnostic output only. DEBUG must be true (or \"--debug\" specified via the command-line)\n * for Component.log() to display anything.\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n static log(s, type)\n {\n Component.log(s, type);\n }\n\n /**\n * notice(s, fPrintOnly, id)\n *\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n */\n static notice(s, fPrintOnly, id)\n {\n Component.notice(s, fPrintOnly, id);\n }\n\n /**\n * alertUser(sMessage)\n * \n * NOTE: Legacy function for older modules (eg, DiskDump); see Component.alertUser().\n *\n * @param {string} sMessage\n */\n static alertUser(sMessage)\n {\n if (window) {\n window.alert(sMessage);\n } else {\n Web.log(sMessage);\n }\n }\n\n /**\n * getResource(sURL, type, fAsync, done, progress)\n *\n * Request the specified resource (sURL), and once the request is complete, notify done().\n *\n * If fAsync is true, a done() callback should ALWAYS be supplied; otherwise, you'll have no\n * idea when the request is complete or what the response was. done() is passed three parameters:\n *\n * done(sURL, resource, nErrorCode)\n *\n * If nErrorCode is zero, resource should contain the requested data; otherwise, an error occurred.\n *\n * If type is set to a string, that string can be used to control the response format;\n * by default, the response format is plain text, but you can specify \"arraybuffer\" to request arbitrary\n * binary data, in which case the returned resource will be a ArrayBuffer rather than a string.\n *\n * @param {string} sURL\n * @param {string|Object|null} [type] (object for POST request, otherwise type of GET request)\n * @param {boolean} [fAsync] is true for an asynchronous request; false otherwise (MUST be set for IE)\n * @param {function(string,string,number)} [done]\n * @param {function(number)} [progress]\n * @return {Array|null} Array containing [resource, nErrorCode], or null if no response available (yet)\n */\n static getResource(sURL, type = \"text\", fAsync = false, done, progress)\n {\n var nErrorCode = 0, resource = null, response = null;\n\n if (typeof resources == 'object' && (resource = resources[sURL])) {\n if (done) done(sURL, resource, nErrorCode);\n return [resource, nErrorCode];\n }\n else if (fAsync && typeof resources == 'function') {\n resources(sURL, function(resource, nErrorCode)\n {\n if (done) done(sURL, resource, nErrorCode);\n });\n return response;\n }\n\n if (!DEBUG && !NODE) {\n /*\n * TODO: Perhaps it's time for our code in netlib.js to finally add support for HTTPS; for now\n * though, it's just as well that the NODE environment assumes all resources are available locally.\n */\n sURL = sURL.replace(/^\\/(pcjs-disks|private-disks)\\//, \"https://jeffpar.github.io/$1/\");\n }\n else {\n /*\n * The larger resources we put on archive.pcjs.org should also be available locally.\n *\n * NOTE: \"http://archive.pcjs.org\" is now \"https://s3-us-west-2.amazonaws.com/archive.pcjs.org\"\n */\n sURL = sURL.replace(/^(http:\\/\\/archive\\.pcjs\\.org|https:\\/\\/s3-us-west-2\\.amazonaws\\.com\\/archive\\.pcjs\\.org)(\\/.*)\\/([^\\/]*)$/, \"$2/archive/$3\");\n sURL = sURL.replace(/^https:\\/\\/jeffpar\\.github\\.io\\/(pcjs-disks|private-disks)\\/(.*)$/, \"/$1/$2\");\n }\n\n\n var request = (window.XMLHttpRequest? new window.XMLHttpRequest() : new window.ActiveXObject(\"Microsoft.XMLHTTP\"));\n var fArrayBuffer = false, fXHR2 = (typeof request.responseType === 'string');\n \n var callback = function() {\n if (request.readyState !== 4) {\n if (progress) progress(1);\n return null;\n }\n /*\n * The following line was recommended for WebKit, as a work-around to prevent the handler firing multiple\n * times when debugging. Unfortunately, that's not the only XMLHttpRequest problem that occurs when\n * debugging, so I think the WebKit problem is deeper than that. When we have multiple XMLHttpRequests\n * pending, any debugging activity means most of them simply get dropped on floor, so what may actually be\n * happening are mis-notifications rather than redundant notifications.\n *\n * request.onreadystatechange = undefined;\n */\n /*\n * If the request failed due to, say, a CORS policy denial; eg:\n * \n * Failed to load http://www.allbootdisks.com/downloads/Disks/Windows_95_Boot_Disk_Download48/Diskette%20Images/Windows95a.img:\n * Redirect from 'http://www.allbootdisks.com/downloads/Disks/Windows_95_Boot_Disk_Download48/Diskette%20Images/Windows95a.img' to\n * 'http://www.allbootdisks.com/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.\n * Origin 'http://pcjs:8088' is therefore not allowed access.\n * \n * and our request type was \"arraybuffer\", attempting to access responseText may trigger an exception; eg:\n * \n * Uncaught DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's\n * 'responseType' is '' or 'text' (was 'arraybuffer').\n * \n * We could tiptoe around these potential landmines, but the safest thing to do is wrap this code with try/catch.\n */\n try {\n resource = fArrayBuffer? request.response : request.responseText;\n } catch(err) {\n if (MAXDEBUG) Web.log(\"xmlHTTPRequest(\" + sURL + \") exception: \" + err.message);\n }\n /*\n * The normal \"success\" case is a non-null resource and an HTTP status code of 200, but when loading files from the\n * local file system (ie, when using the \"file:\" protocol), we have to be a bit more flexible.\n */\n if (resource != null && (request.status == 200 || !request.status && resource.length && Web.getHostProtocol() == \"file:\")) {\n if (MAXDEBUG) Web.log(\"xmlHTTPRequest(\" + sURL + \"): returned \" + resource.length + \" bytes\");\n }\n else {\n nErrorCode = request.status || -1;\n Web.log(\"xmlHTTPRequest(\" + sURL + \"): error code \" + nErrorCode);\n }\n if (progress) progress(2);\n if (done) done(sURL, resource, nErrorCode);\n return [resource, nErrorCode];\n };\n \n if (fAsync) {\n request.onreadystatechange = callback;\n }\n\n if (progress) progress(0);\n\n if (type && typeof type == \"object\") {\n var sPost = \"\";\n for (var p in type) {\n if (!type.hasOwnProperty(p)) continue;\n if (sPost) sPost += \"&\";\n sPost += p + '=' + encodeURIComponent(type[p]);\n }\n sPost = sPost.replace(/%20/g, '+');\n if (MAXDEBUG) Web.log(\"Web.getResource(POST \" + sURL + \"): \" + sPost.length + \" bytes\");\n request.open(\"POST\", sURL, fAsync);\n request.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\n request.send(sPost);\n } else {\n if (MAXDEBUG) Web.log(\"Web.getResource(GET \" + sURL + \")\");\n request.open(\"GET\", sURL, fAsync);\n if (type == \"arraybuffer\") {\n if (fXHR2) {\n fArrayBuffer = true;\n request.responseType = type;\n } else {\n request.overrideMimeType(\"text/plain; charset=x-user-defined\");\n }\n }\n request.send();\n }\n\n if (!fAsync) {\n request.readyState = 4; // this may already be set for synchronous requests, but I don't want to take any chances \n response = callback();\n }\n return response;\n }\n\n /**\n * parseMemoryResource(sURL, sData)\n *\n * This converts a variety of JSON-style data streams into an Object with the following properties:\n *\n * aBytes\n * aSymbols\n * addrLoad\n * addrExec\n *\n * If the source data contains a 'bytes' array, it's passed through to 'aBytes'; alternatively, if\n * it contains a 'words' array, the values are converted from 16-bit to 8-bit and stored in 'aBytes',\n * and if it contains a 'longs' array, the values are converted from 32-bit longs into bytes and\n * stored in 'aBytes'.\n *\n * Alternatively, if the source data contains a 'data' array, we simply pass that through to the output\n * object as:\n *\n * aData\n *\n * @param {string} sURL\n * @param {string} sData\n * @return {Object|null} (resource)\n */\n static parseMemoryResource(sURL, sData)\n {\n var i;\n var resource = {\n aBytes: null,\n aSymbols: null,\n addrLoad: null,\n addrExec: null\n };\n\n if (sData.charAt(0) == \"[\" || sData.charAt(0) == \"{\") {\n try {\n var a, ib, data;\n\n if (sData.substr(0, 1) == \"<\") { // if the \"data\" begins with a \"<\"...\n /*\n * Early server configs reported an error (via the nErrorCode parameter) if a tape URL was invalid,\n * but more recent server configs now display a somewhat friendlier HTML error page. The downside,\n * however, is that the original error has been buried, and we've received \"data\" that isn't actually\n * tape data. So if the data we've received appears to be \"HTML-like\", we treat it as an error message.\n */\n throw new Error(sData);\n }\n\n /*\n * TODO: IE9 is rather unfriendly and restrictive with regard to how much data it's willing to\n * eval(). In particular, the 10Mb disk image we use for the Windows 1.01 demo config fails in\n * IE9 with an \"Out of memory\" exception. One work-around would be to chop the data into chunks\n * (perhaps one track per chunk, using regular expressions) and then manually re-assemble it.\n *\n * However, it turns out that using JSON.parse(sDiskData) instead of eval(\"(\" + sDiskData + \")\")\n * is a much easier fix. The only drawback is that we must first quote any unquoted property names\n * and remove any comments, because while eval() was cool with them, JSON.parse() is more particular;\n * the following RegExp replacements take care of those requirements.\n *\n * The use of hex values is something else that eval() was OK with, but JSON.parse() is not, and\n * while I've stopped using hex values in DumpAPI responses (at least when \"format=json\" is specified),\n * I can't guarantee they won't show up in \"legacy\" images, and there's no simple RegExp replacement\n * for transforming hex values into decimal values, so I cop out and fall back to eval() if I detect\n * any hex prefixes (\"0x\") in the sequence. Ditto for error messages, which appear like so:\n *\n * [\"unrecognized disk path: test.img\"]\n */\n if (sData.indexOf(\"0x\") < 0 && sData.indexOf(\"0o\") < 0 && sData.substr(0, 2) != '[\"') {\n data = JSON.parse(sData.replace(/([a-z]+):/gm, '\"$1\":').replace(/\\/\\/[^\\n]*/gm, \"\"));\n } else {\n data = eval(\"(\" + sData + \")\");\n }\n\n resource.addrLoad = data['load'];\n resource.addrExec = data['exec'];\n\n if (a = data['bytes']) {\n resource.aBytes = a;\n }\n else if (a = data['words']) {\n /*\n * Convert all words into bytes\n */\n resource.aBytes = new Array(a.length * 2);\n for (i = 0, ib = 0; i < a.length; i++) {\n resource.aBytes[ib++] = a[i] & 0xff;\n resource.aBytes[ib++] = (a[i] >> 8) & 0xff;\n\n }\n }\n else if (a = data['longs']) {\n /*\n * Convert all dwords (longs) into bytes\n */\n resource.aBytes = new Array(a.length * 4);\n for (i = 0, ib = 0; i < a.length; i++) {\n resource.aBytes[ib++] = a[i] & 0xff;\n resource.aBytes[ib++] = (a[i] >> 8) & 0xff;\n resource.aBytes[ib++] = (a[i] >> 16) & 0xff;\n resource.aBytes[ib++] = (a[i] >> 24) & 0xff;\n }\n }\n else if (a = data['data']) {\n resource.aData = a;\n }\n else {\n resource.aBytes = data;\n }\n\n if (resource.aBytes) {\n if (!resource.aBytes.length) {\n Component.error(\"Empty resource: \" + sURL);\n resource = null;\n }\n else if (resource.aBytes.length == 1) {\n Component.error(resource.aBytes[0]);\n resource = null;\n }\n }\n resource.aSymbols = data['symbols'];\n\n } catch (e) {\n Component.error(\"Resource data error (\" + sURL + \"): \" + e.message);\n resource = null;\n }\n }\n else {\n /*\n * Parse the data manually; we assume it's a series of hex byte-values separated by whitespace.\n */\n var ab = [];\n var sHexData = sData.replace(/\\n/gm, \" \").replace(/ +$/, \"\");\n var asHexData = sHexData.split(\" \");\n for (i = 0; i < asHexData.length; i++) {\n var n = parseInt(asHexData[i], 16);\n if (isNaN(n)) {\n Component.error(\"Resource data error (\" + sURL + \"): invalid hex byte (\" + asHexData[i] + \")\");\n break;\n }\n ab.push(n & 0xff);\n }\n if (i == asHexData.length) resource.aBytes = ab;\n }\n return resource;\n }\n\n /**\n * sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)\n *\n * Send a report (eg, bug report) to the server.\n *\n * @param {string} sApp (eg, \"PCjs\")\n * @param {string} sVer (eg, \"1.02\")\n * @param {string} sURL (eg, \"/devices/pc/machine/5150/mda/64kb/machine.xml\")\n * @param {string} sUser (ie, the user key, if any)\n * @param {string} sType (eg, \"bug\"); one of ReportAPI.TYPE.*\n * @param {string} sReport (eg, unparsed state data)\n * @param {string} [sHostName] (default is http://SITEHOST)\n */\n static sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)\n {\n var dataPost = {};\n dataPost[ReportAPI.QUERY.APP] = sApp;\n dataPost[ReportAPI.QUERY.VER] = sVer;\n dataPost[ReportAPI.QUERY.URL] = sURL;\n dataPost[ReportAPI.QUERY.USER] = sUser;\n dataPost[ReportAPI.QUERY.TYPE] = sType;\n dataPost[ReportAPI.QUERY.DATA] = sReport;\n var sReportURL = (sHostName? sHostName : \"http://\" + SITEHOST) + ReportAPI.ENDPOINT;\n Web.getResource(sReportURL, dataPost, true);\n }\n\n /**\n * getHost()\n *\n * @return {string}\n */\n static getHost()\n {\n return (\"http://\" + (window? window.location.host : SITEHOST));\n }\n\n /**\n * getHostURL()\n *\n * @return {string|null}\n */\n static getHostURL()\n {\n return (window? window.location.href : null);\n }\n\n /**\n * getHostProtocol()\n *\n * @return {string}\n */\n static getHostProtocol()\n {\n return (window? window.location.protocol : \"file:\");\n }\n\n /**\n * getUserAgent()\n *\n * @return {string}\n */\n static getUserAgent()\n {\n return (window? window.navigator.userAgent : \"\");\n }\n\n /**\n * hasLocalStorage\n *\n * true if localStorage support exists, is enabled, and works; false otherwise\n *\n * @return {boolean}\n */\n static hasLocalStorage()\n {\n if (Web.fLocalStorage == null) {\n var f = false;\n if (window) {\n try {\n window.localStorage.setItem(Web.sLocalStorageTest, Web.sLocalStorageTest);\n f = (window.localStorage.getItem(Web.sLocalStorageTest) == Web.sLocalStorageTest);\n window.localStorage.removeItem(Web.sLocalStorageTest);\n } catch (e) {\n Web.logLocalStorageError(e);\n f = false;\n }\n }\n Web.fLocalStorage = f;\n }\n return Web.fLocalStorage;\n }\n\n /**\n * logLocalStorageError(e)\n *\n * @param {Error} e is an exception\n */\n static logLocalStorageError(e)\n {\n Web.log(e.message, \"localStorage error\");\n }\n\n /**\n * getLocalStorageItem(sKey)\n *\n * Returns the requested key value, or null if the key does not exist, or undefined if localStorage is not available\n *\n * @param {string} sKey\n * @return {string|null|undefined} sValue\n */\n static getLocalStorageItem(sKey)\n {\n var sValue;\n if (window) {\n try {\n sValue = window.localStorage.getItem(sKey);\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n }\n return sValue;\n }\n\n /**\n * setLocalStorageItem(sKey, sValue)\n *\n * @param {string} sKey\n * @param {string} sValue\n * @return {boolean} true if localStorage is available, false if not\n */\n static setLocalStorageItem(sKey, sValue)\n {\n try {\n window.localStorage.setItem(sKey, sValue);\n return true;\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n return false;\n }\n\n /**\n * removeLocalStorageItem(sKey)\n *\n * @param {string} sKey\n */\n static removeLocalStorageItem(sKey)\n {\n try {\n window.localStorage.removeItem(sKey);\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n }\n\n /**\n * getLocalStorageKeys()\n *\n * @return {Array}\n */\n static getLocalStorageKeys()\n {\n var a = [];\n try {\n for (var i = 0, c = window.localStorage.length; i < c; i++) {\n a.push(window.localStorage.key(i));\n }\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n return a;\n }\n\n /**\n * reloadPage()\n */\n static reloadPage()\n {\n if (window) window.location.reload();\n }\n\n /**\n * isUserAgent(s)\n *\n * Check the browser's user-agent string for the given substring; \"iOS\" and \"MSIE\" are special values you can\n * use that will match any iOS or MSIE browser, respectively (even IE11, in the case of \"MSIE\").\n *\n * 2013-11-06: In a questionable move, MSFT changed the user-agent reported by IE11 on Windows 8.1, eliminating\n * the \"MSIE\" string (which MSDN calls a \"version token\"; see http://msdn.microsoft.com/library/ms537503.aspx);\n * they say \"public websites should rely on feature detection, rather than browser detection, in order to design\n * their sites for browsers that don't support the features used by the website.\" So, in IE11, we get a user-agent\n * that tries to fool apps into thinking the browser is more like WebKit or Gecko:\n *\n * Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko\n *\n * That's a nice idea, but in the meantime, they hosed the XSL transform code in embed.js, which contained\n * some very critical browser-specific code; turning on IE's \"Compatibility Mode\" didn't help either, because\n * that's a sledgehammer solution which restores the old user-agent string but also disables other features like\n * HTML5 canvas support. As an interim solution, I'm treating any \"MSIE\" check as a check for either \"MSIE\" or\n * \"Trident\".\n *\n * UPDATE: I've since found ways to make the code in embed.js more browser-agnostic, so for now, there's isn't\n * any code that cares about \"MSIE\", but I've left the change in place, because I wouldn't be surprised if I'll\n * need more IE-specific code in the future, perhaps for things like copy/paste functionality, or mouse capture.\n *\n * @param {string} s is a substring to search for in the user-agent; as noted above, \"iOS\" and \"MSIE\" are special values\n * @return {boolean} is true if the string was found, false if not\n */\n static isUserAgent(s)\n {\n if (window) {\n var userAgent = Web.getUserAgent();\n /*\n * Here's one case where we have to be careful with Component, because when isUserAgent() is called by\n * the init code below, component.js hasn't been loaded yet. The simple solution for now is to remove the call.\n *\n * Web.log(\"agent: \" + userAgent);\n *\n * And yes, it would be pointless to use the conditional (?) operator below, if not for the Google Closure\n * Compiler (v20130823) failing to detect the entire expression as a boolean.\n */\n return s == \"iOS\" && !!userAgent.match(/(iPod|iPhone|iPad)/) && !!userAgent.match(/AppleWebKit/) || s == \"MSIE\" && !!userAgent.match(/(MSIE|Trident)/) || (userAgent.indexOf(s) >= 0);\n }\n return false;\n }\n\n /**\n * isMobile(sDevice)\n *\n * Checks the URL for a \"mobile\" parameter, and failing that, checks the browser's user-agent string for the\n * substring \"Mobi\", as per Mozilla recommendation:\n *\n * https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent\n *\n * @param {string} [sDevice] (eg, \"iPad\" to check for iPad, or \"!iPad\" to specifically exclude it) \n * @return {boolean} is true if the browser appears to be a mobile (ie, non-desktop) web browser, false if not\n */\n static isMobile(sDevice)\n {\n var sMobile = Web.getURLParm(\"mobile\");\n if (sMobile) return sMobile == \"true\";\n if (Web.isUserAgent(\"Mobi\")) {\n if (!sDevice) return true;\n var fInvert = sDevice[0] == '!';\n if (fInvert) sDevice = sDevice.substr(1);\n return Web.isUserAgent(sDevice) != fInvert;\n }\n return false;\n }\n\n /**\n * findProperty(obj, sProp, sSuffix)\n *\n * If both sProp and sSuffix are set, then any browser-specific prefixes are inserted between sProp and sSuffix,\n * and if a match is found, it is returned without sProp.\n *\n * For example, if findProperty(document, 'on', 'fullscreenchange') discovers that 'onwebkitfullscreenchange' exists,\n * it will return 'webkitfullscreenchange', in preparation for an addEventListener() call.\n *\n * More commonly, sSuffix is not used, so whatever property is found is returned as-is.\n *\n * @param {Object|null|undefined} obj\n * @param {string} sProp\n * @param {string} [sSuffix]\n * @return {string|null}\n */\n static findProperty(obj, sProp, sSuffix)\n {\n if (obj) {\n for (var i = 0; i < Web.asBrowserPrefixes.length; i++) {\n var sName = Web.asBrowserPrefixes[i];\n if (sSuffix) {\n sName += sSuffix;\n var sEvent = sProp + sName;\n if (sEvent in obj) return sName;\n } else {\n if (!sName) {\n sName = sProp[0];\n } else {\n sName += sProp[0].toUpperCase();\n }\n sName += sProp.substr(1);\n if (sName in obj) return sName;\n }\n }\n }\n return null;\n }\n\n /**\n * getURLParm(sParm)\n *\n * First looks for sParm exactly as specified, then looks for the lower-case version.\n *\n * @param {string} sParm\n * @return {string|undefined}\n */\n static getURLParm(sParm)\n {\n if (!Web.parmsURL) {\n Web.parmsURL = Web.parseURLParms();\n }\n return Web.parmsURL[sParm] || Web.parmsURL[sParm.toLowerCase()];\n }\n\n /**\n * parseURLParms(sParms)\n *\n * @param {string} [sParms] containing the parameter portion of a URL (ie, after the '?')\n * @return {Object} containing properties for each parameter found\n */\n static parseURLParms(sParms)\n {\n var aParms = {};\n if (window) { // an alternative to \"if (typeof module === 'undefined')\" if require(\"defines\") was used\n if (!sParms) {\n /*\n * Note that window.location.href returns the entire URL, whereas window.location.search\n * returns only the parameters, if any (starting with the '?', which we skip over with a substr() call).\n */\n sParms = window.location.search.substr(1);\n }\n var match;\n var pl = /\\+/g; // RegExp for replacing addition symbol with a space\n var search = /([^&=]+)=?([^&]*)/g;\n var decode = function(s)\n {\n return decodeURIComponent(s.replace(pl, \" \"));\n };\n\n while ((match = search.exec(sParms))) {\n aParms[decode(match[1])] = decode(match[2]);\n }\n }\n return aParms;\n }\n\n /**\n * downloadFile(sData, sType, fBase64, sFileName)\n *\n * @param {string} sData\n * @param {string} sType\n * @param {boolean} [fBase64]\n * @param {string} [sFileName]\n */\n static downloadFile(sData, sType, fBase64, sFileName)\n {\n var link = null, sAlert;\n var sURI = \"data:application/\" + sType + (fBase64? \";base64\" : \"\") + \",\";\n\n if (!Web.isUserAgent(\"Firefox\")) {\n sURI += (fBase64? sData : encodeURI(sData));\n } else {\n sURI += (fBase64? sData : encodeURIComponent(sData));\n }\n if (sFileName) {\n link = document.createElement('a');\n if (typeof link.download != 'string') link = null;\n }\n if (link) {\n link.href = sURI;\n link.download = sFileName;\n document.body.appendChild(link); // Firefox allegedly requires the link to be in the body\n link.click();\n document.body.removeChild(link);\n sAlert = 'Check your Downloads folder for ' + sFileName + '.';\n if (Web.isUserAgent(\"Chrome\")) {\n sAlert += '\\n\\nIn Chrome, after clicking OK, you may ALSO have to select the \"Window\" menu, choose \"Downloads\", and then locate this download and select \"Keep\".';\n sAlert += '\\n\\nThis is part of Chrome\\'s \"Security By Jumping Through Extra Hoops\" technology, which is much easier for Google to implement than actually checking for something malicious.';\n sAlert += '\\n\\nAnd for the record, there is nothing malicious on the PCjs website.';\n }\n } else {\n window.open(sURI);\n sAlert = 'Check your browser for a new window/tab containing the requested data' + (sFileName? (' (' + sFileName + ')') : '') + '.';\n }\n return sAlert;\n }\n\n /**\n * onCountRepeat(n, fnRepeat, fnComplete, msDelay)\n *\n * Call fnRepeat() n times with an msDelay millisecond delay between calls,\n * then call fnComplete() when n has been exhausted OR fnRepeat() returns false.\n *\n * @param {number} n\n * @param {function()} fnRepeat\n * @param {function()} fnComplete\n * @param {number} [msDelay]\n */\n static onCountRepeat(n, fnRepeat, fnComplete, msDelay)\n {\n var fnTimeout = function doCountRepeat()\n {\n n -= 1;\n if (n >= 0) {\n if (!fnRepeat()) n = 0;\n }\n if (n > 0) {\n setTimeout(fnTimeout, msDelay || 0);\n return;\n }\n fnComplete();\n };\n fnTimeout();\n }\n\n /**\n * onClickRepeat(e, msDelay, msRepeat, fn)\n *\n * Repeatedly call fn() with an initial msDelay, and an msRepeat delay thereafter,\n * as long as HTML control Object e has an active \"down\" event and fn() returns true.\n *\n * @param {Object} e\n * @param {number} msDelay\n * @param {number} msRepeat\n * @param {function(boolean)} fn is passed false on the first call, true on all repeated calls\n */\n static onClickRepeat(e, msDelay, msRepeat, fn)\n {\n var ms = 0, timer = null, fIgnoreMouseEvents = false;\n\n var fnRepeat = function doClickRepeat()\n {\n if (fn(ms === msRepeat)) {\n timer = setTimeout(fnRepeat, ms);\n ms = msRepeat;\n }\n };\n e.onmousedown = function()\n {\n // Web.log(\"onMouseDown()\");\n if (!fIgnoreMouseEvents) {\n if (!timer) {\n ms = msDelay;\n fnRepeat();\n }\n }\n };\n e.ontouchstart = function()\n {\n // Web.log(\"onTouchStart()\");\n if (!timer) {\n ms = msDelay;\n fnRepeat();\n }\n };\n e.onmouseup = e.onmouseout = function()\n {\n // Web.log(\"onMouseUp()/onMouseOut()\");\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n };\n e.ontouchend = e.ontouchcancel = function()\n {\n // Web.log(\"onTouchEnd()/onTouchCancel()\");\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n /*\n * Devices that generate ontouch* events ALSO generate onmouse* events,\n * and generally do so immediately after all the touch events are complete,\n * so unless we want double the action, we need to ignore mouse events.\n */\n fIgnoreMouseEvents = true;\n };\n }\n\n /**\n * onPageEvent(sName, fn)\n *\n * For 'onload', 'onunload', and 'onpageshow' events, most callers should NOT use this function, but\n * instead use Web.onInit(), Web.onShow(), and Web.onExit(), respectively.\n *\n * The only components that should still use onPageEvent() are THIS component (see the bottom of this file)\n * and components that need to capture other events (eg, the 'onresize' event in the Video component).\n *\n * This function creates a chain of callbacks, allowing multiple JavaScript modules to define handlers\n * for the same event, which wouldn't be possible if everyone modified window['onload'], window['onunload'],\n * etc, themselves. However, that's less of a concern now, because assuming everyone else is now using\n * onInit(), onExit(), etc, then there really IS only one component setting the window callback: this one.\n *\n * NOTE: It's risky to refer to obscure event handlers with \"dot\" names, because the Closure Compiler may\n * erroneously replace them (eg, window.onpageshow is a good example).\n *\n * @param {string} sFunc\n * @param {function()} fn\n */\n static onPageEvent(sFunc, fn)\n {\n if (window) {\n var fnPrev = window[sFunc];\n if (typeof fnPrev !== 'function') {\n window[sFunc] = fn;\n } else {\n /*\n * TODO: Determine whether there's any value in receiving/sending the Event object that the\n * browser provides when it generates the original event.\n */\n window[sFunc] = function onWindowEvent()\n {\n if (fnPrev) fnPrev();\n fn();\n };\n }\n }\n };\n\n /**\n * onInit(fn)\n *\n * Use this instead of setting window.onload. Allows multiple JavaScript modules to define their own 'onload' event handler.\n *\n * @param {function()} fn\n */\n static onInit(fn)\n {\n Web.aPageEventHandlers['init'].push(fn);\n };\n\n /**\n * onShow(fn)\n *\n * @param {function()} fn\n *\n * Use this instead of setting window.onpageshow. Allows multiple JavaScript modules to define their own 'onpageshow' event handler.\n */\n static onShow(fn)\n {\n Web.aPageEventHandlers['show'].push(fn);\n };\n\n /**\n * onExit(fn)\n *\n * @param {function()} fn\n *\n * Use this instead of setting window.onunload. Allows multiple JavaScript modules to define their own 'onunload' event handler.\n */\n static onExit(fn)\n {\n Web.aPageEventHandlers['exit'].push(fn);\n };\n\n /**\n * doPageEvent(afn)\n *\n * @param {Array.<function()>} afn\n */\n static doPageEvent(afn)\n {\n if (Web.fPageEventsEnabled) {\n try {\n for (var i = 0; i < afn.length; i++) {\n afn[i]();\n }\n } catch (e) {\n Web.notice(\"An unexpected error occurred: \" + e.message + \"\\n\\nIf it happens again, please send this information to support@pcjs.org. Thanks.\");\n }\n }\n };\n\n /**\n * enablePageEvents(fEnable)\n *\n * @param {boolean} fEnable is true to enable page events, false to disable (they're enabled by default)\n */\n static enablePageEvents(fEnable)\n {\n if (!Web.fPageEventsEnabled && fEnable) {\n Web.fPageEventsEnabled = true;\n if (Web.fPageLoaded) Web.sendPageEvent('init');\n if (Web.fPageShowed) Web.sendPageEvent('show');\n return;\n }\n Web.fPageEventsEnabled = fEnable;\n }\n\n /**\n * sendPageEvent(sEvent)\n *\n * This allows us to manually trigger page events.\n *\n * @param {string} sEvent (one of 'init', 'show' or 'exit')\n */\n static sendPageEvent(sEvent)\n {\n if (Web.aPageEventHandlers[sEvent]) {\n Web.doPageEvent(Web.aPageEventHandlers[sEvent]);\n }\n }\n}\n\nWeb.parmsURL = null; // initialized on first call to parseURLParms()\n\nWeb.aPageEventHandlers = {\n 'init': [], // list of window 'onload' handlers\n 'show': [], // list of window 'onpageshow' handlers\n 'exit': [] // list of window 'onunload' handlers (although we prefer to use 'onbeforeunload' if possible)\n};\n\nWeb.asBrowserPrefixes = ['', 'moz', 'ms', 'webkit'];\n\nWeb.fPageLoaded = false; // set once the page's first 'onload' event has occurred\nWeb.fPageShowed = false; // set once the page's first 'onpageshow' event has occurred\nWeb.fPageEventsEnabled = true; // default is true, set to false (or true) by enablePageEvents()\n\n/**\n * fLocalStorage\n *\n * true if localStorage support exists, is enabled, and works; \"falsey\" otherwise\n *\n * @type {boolean|null}\n */\nWeb.fLocalStorage = null;\n\n/**\n * TODO: Is there any way to get the Closure Compiler to stop inlining this string? This isn't cutting it.\n *\n * @const {string}\n */\nWeb.sLocalStorageTest = \"PCjs.localStorage\";\n\nWeb.onPageEvent('onload', function onPageLoad() {\n Web.fPageLoaded = true;\n Web.doPageEvent(Web.aPageEventHandlers['init']);\n});\n\nWeb.onPageEvent('onpageshow', function onPageShow() {\n Web.fPageShowed = true;\n Web.doPageEvent(Web.aPageEventHandlers['show']);\n});\n\nWeb.onPageEvent(Web.isUserAgent(\"iOS\")? 'onpagehide' : (Web.isUserAgent(\"Opera\")? 'onunload' : 'onbeforeunload'), function onPageUnload() {\n Web.doPageEvent(Web.aPageEventHandlers['exit']);\n});\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/component.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * All PCjs components now use JSDoc types, primarily so that Google's Closure Compiler will compile\n * everything with zero warnings when ADVANCED_OPTIMIZATIONS are enabled. For more information about\n * the JSDoc types supported by the Closure Compiler:\n *\n * https://developers.google.com/closure/compiler/docs/js-for-compiler#types\n *\n * I also attempted to validate this code with JSLint, but it complained too much; eg, it didn't like\n * \"while (true)\", a tried and \"true\" programming convention for decades, and it wanted me to replace\n * all \"++\" and \"--\" operators with \"+= 1\" and \"-= 1\", use \"(s || '')\" instead of \"(s? s : '')\", etc.\n *\n * I prefer sticking with traditional C-style idioms, in part because they are more portable. That\n * does NOT mean I'm trying to write \"portable JavaScript,\" but some of this code was ported from C code\n * I'd written long ago, so portability is good, and I'm not going to throw that away if there's no need.\n *\n * UPDATE: I've since switched from JSLint to JSHint, which seems to have more reasonable defaults.\n * And for new code, I have adopted some popular JavaScript idioms, like \"(s || '')\", although the need\n * for those kinds of expressions will be reduced as I also start adopting some ES6 features, like\n * default parameters.\n */\n\n\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * subclass (eg, SerialPort), because otherwise the Compiler won't allow us to *reference*\n * the named property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass Component {\n /**\n * Component(type, parms, bitsMessage)\n *\n * A Component object requires:\n *\n * type: a user-defined type name (eg, \"CPU\")\n *\n * and accepts any or all of the following (parms) properties:\n *\n * id: component ID (default is \"\")\n * name: component name (default is \"\"; if blank, toString() will use the type name only)\n * comment: component comment string (default is undefined)\n *\n * Component subclasses will usually have additional (parms) properties.\n *\n * @param {string} type\n * @param {Object} [parms]\n * @param {number} [bitsMessage] selects message(s) that the component wants to enable (default is 0)\n */\n constructor(type, parms, bitsMessage)\n {\n this.type = type;\n\n if (!parms) parms = {'id': \"\", 'name': \"\"};\n\n this.id = parms['id'] || \"\";\n this.name = parms['name'];\n this.comment = parms['comment'];\n this.parms = parms;\n\n /*\n * The following Component properties need to be accessible by other machines and/or command scripts;\n * well, OK, or we could have exported some new functions to walk the contents of these properties, as we\n * did with findMachineComponent(), but this works just as well.\n *\n * Also, while the double-assignment looks silly (ie, using both dot and bracket property notation), it\n * resolves a complaint from the Closure Compiler, because if we use ONLY bracket notation here, then the\n * Compiler wants us to change all the other references to bracket notation as well.\n */\n this.exports = this['exports'] = {};\n this.bindings = this['bindings'] = {};\n\n var i = this.id.indexOf('.');\n if (i < 0) {\n this.idComponent = this.id;\n } else {\n this.idMachine = this.id.substr(0, i);\n this.idComponent = this.id.substr(i + 1);\n }\n\n /*\n * Gather all the various component flags (booleans) into a single \"flags\" object, and encourage\n * subclasses to do the same, to reduce the property clutter we have to wade through while debugging.\n */\n this.flags = {\n ready: false,\n busy: false,\n busyCancel: false,\n initDone: false,\n powered: false,\n unloading: false,\n error: false\n };\n\n this.fnReady = null;\n this.clearError();\n this.bitsMessage = bitsMessage || 0;\n\n this.cmp = null;\n this.bus = null;\n this.cpu = null;\n this.dbg = null;\n\n /*\n * TODO: Consider adding another parameter to the Component() constructor that allows components to tell\n * us if they support single or multiple instances per machine. For example, there can be multiple SerialPort\n * components per machine, but only one CPU component (some machines also support an FPU, but that component\n * is considered separate from the CPU).\n *\n * It's not critical, but it would help catch machine configuration errors; for example, a machine that mistakenly\n * includes two CPU components may, aside from wasting memory, end up with odd side-effects, like unresponsive\n * CPU controls.\n */\n Component.add(this);\n }\n\n /**\n * Component.add(component)\n *\n * @param {Component} component\n */\n static add(component)\n {\n /*\n * This just generates a lot of useless noise, handy in the early days, not so much these days....\n *\n * if (DEBUG) Component.log(\"Component.add(\" + component.type + \",\" + component.id + \")\");\n */\n Component.components.push(component);\n }\n\n /**\n * Component.addMachine(idMachine)\n *\n * @param {string} idMachine\n */\n static addMachine(idMachine)\n {\n Component.machines[idMachine] = {};\n }\n\n /**\n * Component.addMachineResource(idMachine, sName, data)\n *\n * @param {string} idMachine\n * @param {string|null} sName (name of the resource)\n * @param {*} data\n */\n static addMachineResource(idMachine, sName, data)\n {\n /*\n * I used to assert(Component.machines[idMachine]), but when we're running as a Node app, embed.js is not used,\n * so addMachine() is never called, so resources do not need to be recorded.\n */\n if (Component.machines[idMachine] && sName) {\n Component.machines[idMachine][sName] = data;\n }\n }\n\n /**\n * Component.getMachineResources(idMachine)\n *\n * @param {string} idMachine\n * @return {Object|undefined}\n */\n static getMachineResources(idMachine)\n {\n return Component.machines[idMachine];\n }\n\n /**\n * Component.getTime()\n *\n * @return {number} the current time, in milliseconds\n */\n static getTime()\n {\n return Date.now() || +new Date();\n }\n\n /**\n * Component.log(s, type)\n *\n * For diagnostic output only.\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n static log(s, type)\n {\n if (!COMPILED) {\n if (s) {\n var sElapsed = \"\", sMsg = (type? (type + \": \") : \"\") + s;\n if (typeof Usr != \"undefined\") {\n if (Component.msStart === undefined) {\n Component.msStart = Component.getTime();\n }\n sElapsed = (Component.getTime() - Component.msStart) + \"ms: \";\n }\n sMsg = sMsg.replace(/\\r/g, '\\\\r').replace(/\\n/g, ' ');\n if (window && window.console) console.log(sElapsed + sMsg);\n }\n }\n }\n\n /**\n * Component.assert(f, s)\n *\n * Verifies conditions that must be true (for DEBUG builds only).\n *\n * The Closure Compiler should automatically remove all references to Component.assert() in non-DEBUG builds.\n * TODO: Add a task to the build process that \"asserts\" there are no instances of \"assertion failure\" in RELEASE builds.\n *\n * @param {boolean} f is the expression we are asserting to be true\n * @param {string} [s] is description of the assertion on failure\n */\n static assert(f, s)\n {\n if (DEBUG) {\n if (!f) {\n if (!s) s = \"assertion failure\";\n Component.log(s);\n throw new Error(s);\n }\n }\n }\n\n /**\n * Component.print(s)\n *\n * Components that inherit from this class should use this.print(), rather than Component.print(), because\n * if a Control Panel is loaded, it will override only the instance method, not the class method (overriding the\n * class method would improperly affect any other machines loaded on the same page).\n *\n * @this {Component}\n * @param {string} s\n */\n static print(s)\n {\n if (!COMPILED) {\n var i = s.lastIndexOf('\\n');\n if (i >= 0) {\n Component.println(s.substr(0, i));\n s = s.substr(i + 1);\n }\n Component.printBuffer += s;\n }\n }\n\n /**\n * Component.println(s, type, id)\n *\n * Components that inherit from this class should use this.println(), rather than Component.println(), because\n * if a Control Panel is loaded, it will override only the instance method, not the class method (overriding the\n * class method would improperly affect any other machines loaded on the same page).\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n * @param {string} [id] is the caller's ID, if any\n */\n static println(s, type, id)\n {\n if (!COMPILED) {\n s = Component.printBuffer + (s || \"\");\n Component.log((id? (id + \": \") : \"\") + (s? (\"\\\"\" + s + \"\\\"\") : \"\"), type);\n Component.printBuffer = \"\";\n }\n }\n\n /**\n * Component.notice(s, fPrintOnly, id)\n *\n * notice() is like println() but implies a need for user notification, so we alert() as well.\n *\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n * @return {boolean}\n */\n static notice(s, fPrintOnly, id)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.NOTICE, id);\n }\n if (!fPrintOnly) Component.alertUser((id? (id + \": \") : \"\") + s);\n return true;\n }\n\n /**\n * Component.warning(s)\n *\n * @param {string} s describes the warning\n */\n static warning(s)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.WARNING);\n }\n Component.alertUser(s);\n }\n\n /**\n * Component.error(s)\n *\n * @param {string} s describes the error; an alert() is displayed as well\n */\n static error(s)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.ERROR);\n }\n Component.alertUser(s);\n }\n\n /**\n * Component.alertUser(sMessage)\n *\n * @param {string} sMessage\n */\n static alertUser(sMessage)\n {\n if (window) {\n window.alert(sMessage);\n } else {\n Component.log(sMessage);\n }\n }\n\n /**\n * Component.confirmUser(sPrompt)\n *\n * @param {string} sPrompt\n * @returns {boolean} true if the user clicked OK, false if Cancel/Close\n */\n static confirmUser(sPrompt)\n {\n var fResponse = false;\n if (window) {\n fResponse = window.confirm(sPrompt);\n }\n return fResponse;\n }\n\n /**\n * Component.promptUser()\n *\n * @param {string} sPrompt\n * @param {string} [sDefault]\n * @returns {string|null}\n */\n static promptUser(sPrompt, sDefault)\n {\n var sResponse = null;\n if (window) {\n sResponse = window.prompt(sPrompt, sDefault === undefined? \"\" : sDefault);\n }\n return sResponse;\n }\n\n /**\n * Component.appendControl(control, sText)\n *\n * @param {Object} control\n * @param {string} sText\n */\n static appendControl(control, sText)\n {\n control.value += sText;\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (COMPILED) {\n sText = control.value;\n if (sText.length > 8192) control.value = sText.substr(sText.length - 4096);\n }\n control.scrollTop = control.scrollHeight;\n }\n\n /**\n * Component.replaceControl(control, sSearch, sReplace)\n *\n * @param {Object} control\n * @param {string} sSearch\n * @param {string} sReplace\n */\n static replaceControl(control, sSearch, sReplace)\n {\n var sText = control.value;\n var i = sText.lastIndexOf(sSearch);\n if (i < 0) {\n sText += sSearch + '\\n';\n } else {\n sText = sText.substr(0, i) + sReplace + sText.substr(i + sSearch.length);\n }\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (COMPILED && sText.length > 8192) sText = sText.substr(sText.length - 4096);\n control.value = sText;\n control.scrollTop = control.scrollHeight;\n }\n\n /**\n * Component.bindExternalControl(component, sBinding, sType)\n *\n * @param {Component} component\n * @param {string} sBinding\n * @param {string} [sType] is the external component type (default is \"Panel\")\n */\n static bindExternalControl(component, sBinding, sType = \"Panel\")\n {\n if (sBinding) {\n var target = Component.getComponentByType(sType, component.id);\n if (target) {\n var control = target.bindings[sBinding];\n if (control) {\n component.setBinding(null, sBinding, control);\n }\n }\n }\n }\n\n /**\n * Component.bindComponentControls(component, element, sAppClass)\n *\n * @param {Component} component\n * @param {HTMLElement} element from the DOM\n * @param {string} sAppClass\n */\n static bindComponentControls(component, element, sAppClass)\n {\n var aeControls = Component.getElementsByClass(element.parentNode, sAppClass + \"-control\");\n\n for (var iControl = 0; iControl < aeControls.length; iControl++) {\n\n var aeChildNodes = aeControls[iControl].childNodes;\n\n for (var iNode = 0; iNode < aeChildNodes.length; iNode++) {\n var control = aeChildNodes[iNode];\n if (control.nodeType !== 1 /* document.ELEMENT_NODE */) {\n continue;\n }\n var sClass = control.getAttribute(\"class\");\n if (!sClass) continue;\n var aClasses = sClass.split(\" \");\n for (var iClass = 0; iClass < aClasses.length; iClass++) {\n var parms;\n sClass = aClasses[iClass];\n switch (sClass) {\n case sAppClass + \"-binding\":\n parms = Component.getComponentParms(/** @type {HTMLElement} */(control));\n if (parms && parms['binding'] !== undefined) {\n component.setBinding(parms['type'], parms['binding'], /** @type {HTMLElement} */(control), parms['value']);\n } else if (!parms || parms['type'] != \"description\") {\n Component.log(\"Component '\" + component.toString() + \"' missing binding\" + (parms? \" for \" + parms['type'] : \"\"), \"warning\");\n }\n iClass = aClasses.length;\n break;\n default:\n // if (DEBUG) Component.log(\"Component.bindComponentControls(\" + component.toString() + \"): unrecognized control class \\\"\" + sClass + \"\\\"\", \"warning\");\n break;\n }\n }\n }\n }\n }\n\n /**\n * Component.getComponents(idRelated)\n *\n * We could store components as properties, using the component's ID, and change\n * this linear lookup into a property lookup, but some components may have no ID.\n *\n * @param {string} [idRelated] of related component\n * @return {Array} of components\n */\n static getComponents(idRelated)\n {\n var i;\n var aComponents = [];\n /*\n * getComponentByID(id, idRelated)\n *\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated) {\n if ((i = idRelated.indexOf('.')) > 0)\n idRelated = idRelated.substr(0, i + 1);\n else\n idRelated = \"\";\n }\n for (i = 0; i < Component.components.length; i++) {\n var component = Component.components[i];\n if (!idRelated || !component.id.indexOf(idRelated)) {\n aComponents.push(component);\n }\n }\n return aComponents;\n }\n\n /**\n * Component.getComponentByID(id, idRelated)\n *\n * We could store components as properties, using the component's ID, and change\n * this linear lookup into a property lookup, but some components may have no ID.\n *\n * @param {string} id of the desired component\n * @param {string} [idRelated] of related component\n * @return {Component|null}\n */\n static getComponentByID(id, idRelated)\n {\n if (id !== undefined) {\n var i;\n /*\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated && (i = idRelated.indexOf('.')) > 0) {\n id = idRelated.substr(0, i + 1) + id;\n }\n for (i = 0; i < Component.components.length; i++) {\n if (Component.components[i].id === id) {\n return Component.components[i];\n }\n }\n if (Component.components.length) {\n Component.log(\"Component ID '\" + id + \"' not found\", \"warning\");\n }\n }\n return null;\n }\n\n /**\n * Component.getComponentByType(sType, idRelated, componentPrev)\n *\n * @param {string} sType of the desired component\n * @param {string} [idRelated] of related component\n * @param {Component|null} [componentPrev] of previously returned component, if any\n * @return {Component|null}\n */\n static getComponentByType(sType, idRelated, componentPrev)\n {\n if (sType !== undefined) {\n var i;\n /*\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated) {\n if ((i = idRelated.indexOf('.')) > 0) {\n idRelated = idRelated.substr(0, i + 1);\n } else {\n idRelated = \"\";\n }\n }\n for (i = 0; i < Component.components.length; i++) {\n if (componentPrev) {\n if (componentPrev == Component.components[i]) componentPrev = null;\n continue;\n }\n if (sType == Component.components[i].type && (!idRelated || !Component.components[i].id.indexOf(idRelated))) {\n return Component.components[i];\n }\n }\n Component.log(\"Component type '\" + sType + \"' not found\", \"warning\");\n }\n return null;\n }\n\n /**\n * Component.getComponentParms(element)\n *\n * @param {HTMLElement} element from the DOM\n */\n static getComponentParms(element)\n {\n var parms = null;\n var sParms = element.getAttribute(\"data-value\");\n if (sParms) {\n try {\n parms = eval('(' + sParms + ')'); // jshint ignore:line\n /*\n * We can no longer invoke removeAttribute() because some components (eg, Panel) need\n * to run their initXXX() code more than once, to avoid initialization-order dependencies.\n *\n * if (!DEBUG) {\n * element.removeAttribute(\"data-value\");\n * }\n */\n } catch(e) {\n Component.error(e.message + \" (\" + sParms + \")\");\n }\n }\n return parms;\n }\n\n /**\n * Component.getElementsByClass(element, sClass, sObjClass)\n *\n * This is a cross-browser helper function, since not all browser's support getElementsByClassName()\n *\n * TODO: This should probably be moved into weblib.js at some point, along with the control binding functions above,\n * to keep all the browser-related code together.\n *\n * @param {HTMLDocument|HTMLElement|Node} element from the DOM\n * @param {string} sClass\n * @param {string} [sObjClass]\n * @return {Array|NodeList}\n */\n static getElementsByClass(element, sClass, sObjClass)\n {\n if (sObjClass) sClass += '-' + sObjClass + \"-object\";\n /*\n * Use the browser's built-in getElementsByClassName() if it appears to be available\n * (for example, it's not available in IE8, but it should be available in IE9 and up)\n */\n if (element.getElementsByClassName) {\n return element.getElementsByClassName(sClass);\n }\n var i, j, ae = [];\n var aeAll = element.getElementsByTagName(\"*\");\n var re = new RegExp('(^| )' + sClass + '( |$)');\n for (i = 0, j = aeAll.length; i < j; i++) {\n if (re.test(aeAll[i].className)) {\n ae.push(aeAll[i]);\n }\n }\n if (!ae.length) {\n Component.log('No elements of class \"' + sClass + '\" found');\n }\n return ae;\n }\n\n /**\n * Component.getScriptCommands(sScript)\n *\n * This is a simple parser that breaks sScript into an array of commands, where each command\n * is an array of tokens, where tokens are sequences of characters separated by any of: tab, space,\n * carriage-return (CR), line-feed (LF), semicolon, single-quote, or double-quote; if a quote is\n * used, all characters up to the next matching quote become part of the token, allowing any of the\n * other separators to be part of the token. CR, LF and semicolon also serve to terminate a command,\n * with semicolon being preferred, because it's 1) more visible, and 2) essential when the entire\n * script is a multi-line string where all CR/LF were replaced by spaces (which is what Jekyll does,\n * and since we can't change Jekyll, it's what our own MarkDown Front Matter parser does as well;\n * see convertMD() in markout.js, where the aCommandDefs array is built).\n *\n * Backslash sequences like \\n, \\r, and \\\\ have already been converted to LF, CR and backslash\n * characters, since the entire script string is injected into a JavaScript function call, so any\n * backslash sequence that JavaScript supports is automatically converted:\n *\n * \\0 \\' \\\" \\\\ \\n \\r \\v \\t \\b \\f \\uXXXX \\xXX\n * ^J ^M ^K ^I ^H ^L\n *\n * To support any other non-printable 8-bit character, such as ESC, you should use \\xXX, where XX\n * is the ASCII code in hex. For ESC, that would be \\x1B.\n *\n * @param {string} sScript\n * @return {Array}\n */\n static getScriptCommands(sScript)\n {\n var cch = sScript.length;\n var aCommands = [], aTokens = [], sToken = \"\", chQuote = null;\n for (var i = 0; i < cch; i++) {\n var ch = sScript[i];\n if (ch == '\"' || ch == \"'\") {\n if (chQuote && ch != chQuote) {\n sToken += ch;\n continue;\n }\n if (!chQuote) {\n chQuote = ch;\n } else {\n chQuote = null;\n }\n if (sToken) {\n aTokens.push(sToken);\n sToken = \"\";\n }\n continue;\n }\n if (!chQuote) {\n if (ch == '\\r' || ch == '\\n') {\n ch = ';';\n }\n if (ch == ' ' || ch == '\\t' || ch == ';') {\n if (sToken) {\n aTokens.push(sToken);\n sToken = \"\";\n }\n if (ch == ';' && aTokens.length) {\n aCommands.push(aTokens);\n aTokens = [];\n }\n continue;\n }\n }\n sToken += ch;\n }\n if (sToken) {\n aTokens.push(sToken);\n }\n if (aTokens.length) {\n aCommands.push(aTokens);\n }\n return aCommands;\n }\n\n /**\n * Component.processScript(idMachine, sScript)\n *\n * @param {string} idMachine\n * @param {string} [sScript]\n * @return {boolean}\n */\n static processScript(idMachine, sScript)\n {\n var fSuccess = false;\n idMachine += \".machine\";\n if (!sScript) {\n delete Component.commands[idMachine];\n fSuccess = true;\n }\n else if (typeof sScript == \"string\" && !Component.commands[idMachine]) {\n fSuccess = true;\n Component.commands[idMachine] = Component.getScriptCommands(sScript);\n if (!Component.processCommands(idMachine)) {\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * Component.processCommands(idMachine)\n *\n * @param {string} idMachine\n * @return {boolean}\n */\n static processCommands(idMachine)\n {\n var fSuccess = true;\n var aCommands = Component.commands[idMachine];\n\n // var dbg = Component.getComponentByType(\"Debugger\", idMachine);\n\n while (aCommands && aCommands.length) {\n\n var aTokens = aCommands.splice(0, 1)[0];\n var sCommand = aTokens[0];\n\n /*\n * It's possible to route this output to the Debugger window with dbg.println()\n * instead, but it's a bit too confusing mingling script output in a window that\n * already mingles Debugger and machine output.\n */\n Component.println(aTokens.join(' '), Component.PRINT.SCRIPT);\n\n var fnCallReady = null;\n if (Component.asyncCommands.indexOf(sCommand) >= 0) {\n fnCallReady = function processNextCommand() {\n return function() {\n Component.processCommands(idMachine);\n }\n }();\n }\n\n var fnCommand = Component.globalCommands[sCommand];\n if (fnCommand) {\n if (!fnCallReady) {\n fSuccess = fnCommand(aTokens[1], aTokens[2], aTokens[3]);\n } else {\n if (!fnCommand(fnCallReady, aTokens[1], aTokens[2], aTokens[3])) break;\n }\n }\n else {\n fSuccess = false;\n var component = Component.getComponentByType(aTokens[1], idMachine);\n if (component) {\n fnCommand = Component.componentCommands[sCommand];\n if (fnCommand) {\n fSuccess = fnCommand(component, aTokens[2], aTokens[3]);\n }\n else {\n var exports = component['exports'];\n if (exports) {\n fnCommand = exports[sCommand];\n if (fnCommand) {\n fSuccess = true;\n if (!fnCallReady) {\n fSuccess = fnCommand.call(component, aTokens[2], aTokens[3]);\n } else {\n if (!fnCommand.call(component, fnCallReady, aTokens[2], aTokens[3])) break;\n }\n }\n }\n }\n }\n }\n\n if (!fSuccess) {\n Component.alertUser(\"Script error: '\" + sCommand + \"' command \" + (fnCommand? \" failed\" : \" not recognized\"));\n break;\n }\n }\n\n if (aCommands && !aCommands.length) {\n delete Component.commands[idMachine];\n }\n\n return fSuccess;\n }\n\n /**\n * Component.scriptAlert(sMessage)\n *\n * @param {string} sMessage\n * @return {boolean}\n */\n static scriptAlert(sMessage)\n {\n Component.alertUser(sMessage);\n return true;\n }\n\n /**\n * Component.scriptSelect(component, sBinding, sValue)\n *\n * @param {Component} component\n * @param {string} sBinding\n * @param {string} sValue\n * @return {boolean}\n */\n static scriptSelect(component, sBinding, sValue)\n {\n var fSuccess = false;\n var aBindings = component['bindings'];\n var control = aBindings[sBinding];\n if (control) {\n for (var i = 0; i < control.options.length; i++) {\n if (control.options[i].textContent == sValue) {\n if (control.selectedIndex != i) {\n control.selectedIndex = i;\n }\n fSuccess = true;\n break;\n }\n }\n }\n return fSuccess;\n }\n\n /**\n * Component.scriptSleep(fnCallback, sDelay)\n *\n * @param {function()} fnCallback\n * @param {string} sDelay (in milliseconds)\n * @return {boolean}\n */\n static scriptSleep(fnCallback, sDelay)\n {\n setTimeout(fnCallback, +sDelay);\n return false;\n }\n\n /**\n * toString()\n *\n * @this {Component}\n * @return {string}\n */\n toString()\n {\n return (this.name? this.name : (this.id || this.type));\n }\n\n /**\n * getMachineNum()\n *\n * @this {Component}\n * @return {number} unique machine number\n */\n getMachineNum()\n {\n var nMachine = 1;\n if (this.idMachine) {\n var aDigits = this.idMachine.match(/\\d+/);\n if (aDigits !== null)\n nMachine = parseInt(aDigits[0], 10);\n }\n return nMachine;\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * Component's setBinding() method is intended to be overridden by subclasses.\n *\n * @this {Component}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, 'print')\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n switch (sBinding) {\n case 'clear':\n if (!this.bindings[sBinding]) {\n this.bindings[sBinding] = control;\n control.onclick = (function(component) {\n return function clearControl() {\n if (component.bindings['print']) {\n component.bindings['print'].value = \"\";\n }\n };\n }(this));\n }\n return true;\n case 'print':\n if (!this.bindings[sBinding]) {\n var controlTextArea = /** @type {HTMLTextAreaElement} */(control);\n this.bindings[sBinding] = controlTextArea;\n /**\n * Override this.notice() with a replacement function that eliminates the Component.alertUser() call.\n *\n * @this {Component}\n * @param {string} s\n * @return {boolean}\n */\n this.notice = function noticeControl(s /*, fPrintOnly, id*/) {\n this.println(s, this.type);\n return true;\n };\n /*\n * This was added for Firefox (Safari will clear the <textarea> on a page reload, but Firefox does not).\n */\n controlTextArea.value = \"\";\n this.print = function(control) {\n return function printControl(s) {\n Component.appendControl(control, s);\n };\n }(controlTextArea);\n this.println = function(component, control) {\n return function printlnControl(s, type, id) {\n if (!s) s = \"\";\n if (type != Component.PRINT.PROGRESS || s.slice(-3) != \"...\") {\n if (type) s = type + \": \" + s;\n Component.appendControl(control, s + '\\n');\n } else {\n Component.replaceControl(control, s, s + '.');\n }\n if (!COMPILED && window && window.console) Component.println(s, type, id);\n };\n }(this, controlTextArea);\n }\n return true;\n default:\n return false;\n }\n }\n\n /**\n * log(s, type)\n *\n * For diagnostic output only.\n *\n * WARNING: Even though this function's body is completely wrapped in DEBUG, that won't prevent the Closure Compiler\n * from including it, so all calls must still be prefixed with \"if (DEBUG) ....\". For this reason, the class method,\n * Component.log(), is preferred, because the compiler IS smart enough to remove those calls.\n *\n * @this {Component}\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n log(s, type)\n {\n if (!COMPILED) {\n Component.log(s, type || this.id || this.type);\n }\n }\n\n /**\n * assert(f, s)\n *\n * Verifies conditions that must be true (for DEBUG builds only).\n *\n * WARNING: Make sure you preface all calls to this.assert() with \"if (DEBUG)\", because unlike Component.assert(),\n * the Closure Compiler can't be sure that this instance method hasn't been overridden, so it refuses to treat it as\n * dead code in non-DEBUG builds.\n *\n * TODO: Add a task to the build process that \"asserts\" there are no instances of \"assertion failure\" in RELEASE builds.\n *\n * @this {Component}\n * @param {boolean|number} f is the expression asserted to be true\n * @param {string} [s] is a description of the assertion to be displayed or logged on failure\n */\n assert(f, s)\n {\n if (DEBUG) {\n if (!f) {\n s = \"assertion failure in \" + (this.id || this.type) + (s? \": \" + s : \"\");\n if (DEBUGGER && this.dbg) {\n this.dbg.stopCPU();\n /*\n * Why do we throw an Error only to immediately catch and ignore it? Simply to give\n * any IDE the opportunity to inspect the application's state. Even when the IDE has\n * control, you should still be able to invoke Debugger commands from the IDE's REPL,\n * using the global function that the Debugger constructor defines; eg:\n *\n * pcx86('r')\n * pcx86('dw 0:0')\n * pcx86('h')\n * ...\n *\n * If you have no desire to stop on assertions, consider this a no-op. However, another\n * potential benefit of creating an Error object is that, for browsers like Chrome, we get\n * a stack trace, too.\n */\n try {\n throw new Error(s);\n } catch(e) {\n this.println(e.stack || e.message);\n }\n return;\n }\n this.log(s);\n throw new Error(s);\n }\n }\n }\n\n /**\n * print(s)\n *\n * Components using this.print() should wait until after their constructor has run to display any messages, because\n * if a Control Panel has been loaded, its override will not take effect until its own constructor has run.\n *\n * @this {Component}\n * @param {string} s\n */\n print(s)\n {\n Component.print(s);\n }\n\n /**\n * println(s, type, id)\n *\n * Components using this.println() should wait until after their constructor has run to display any messages, because\n * if a Control Panel has been loaded, its override will not take effect until its own constructor has run.\n *\n * @this {Component}\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n * @param {string} [id] is the caller's ID, if any\n */\n println(s, type, id)\n {\n Component.println(s, type, id || this.id);\n }\n\n /**\n * status(s)\n *\n * status() is like println() but it also includes information about the component (ie, the component type),\n * which is why there is no corresponding Component.status() function.\n *\n * @this {Component}\n * @param {string} s is the message text\n */\n status(s)\n {\n this.println(this.type + \": \" + s);\n }\n\n /**\n * notice(s, fPrintOnly, id)\n *\n * notice() is like println() but implies a need for user notification, so we alert() as well; however, if this.println()\n * is overridden, this.notice will be replaced with a similar override, on the assumption that the override is taking care\n * of alerting the user.\n *\n * @this {Component}\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n * @return {boolean}\n */\n notice(s, fPrintOnly, id)\n {\n if (!fPrintOnly) {\n /*\n * See if the associated computer, if any, is \"unloading\"....\n */\n var computer = Component.getComponentByType(\"Computer\", this.id);\n if (computer && computer.flags.unloading) {\n console.log(\"ignoring notice during unload: \" + s);\n return false;\n }\n }\n Component.notice(s, fPrintOnly, id || this.type);\n return true;\n }\n\n /**\n * setError(s)\n *\n * Set a fatal error condition\n *\n * @this {Component}\n * @param {string} s describes a fatal error condition\n */\n setError(s)\n {\n this.flags.error = true;\n this.notice(s); // TODO: Any cases where we should still prefix this string with \"Fatal error: \"?\n }\n\n /**\n * clearError()\n *\n * Clear any fatal error condition\n *\n * @this {Component}\n */\n clearError() {\n this.flags.error = false;\n }\n\n /**\n * isError()\n *\n * Report any fatal error condition\n *\n * @this {Component}\n * @return {boolean} true if a fatal error condition exists, false if not\n */\n isError()\n {\n if (this.flags.error) {\n this.println(this.toString() + \" error\");\n return true;\n }\n return false;\n }\n\n /**\n * isReady(fnReady)\n *\n * Return the \"ready\" state of the component; if the component is not ready, it will queue the optional\n * notification function, otherwise it will immediately call the notification function, if any, without queuing it.\n *\n * NOTE: Since only the Computer component actually cares about the \"readiness\" of other components, the so-called\n * \"queue\" of notification functions supports exactly one function. This keeps things nice and simple.\n *\n * @this {Component}\n * @param {function()} [fnReady]\n * @return {boolean} true if the component is in a \"ready\" state, false if not\n */\n isReady(fnReady)\n {\n if (fnReady) {\n if (this.flags.ready) {\n fnReady();\n } else {\n if (MAXDEBUG) this.log(\"NOT ready\");\n this.fnReady = fnReady;\n }\n }\n return this.flags.ready;\n }\n\n /**\n * setReady(fReady)\n *\n * Set the \"ready\" state of the component to true, and call any queued notification functions.\n *\n * @this {Component}\n * @param {boolean} [fReady] is assumed to indicate \"ready\" unless EXPLICITLY set to false\n */\n setReady(fReady)\n {\n if (!this.flags.error) {\n this.flags.ready = (fReady !== false);\n if (this.flags.ready) {\n if (MAXDEBUG /* || this.name */) this.log(\"ready\");\n var fnReady = this.fnReady;\n this.fnReady = null;\n if (fnReady) fnReady();\n }\n }\n }\n\n /**\n * isBusy(fCancel)\n *\n * Return the \"busy\" state of the component\n *\n * @this {Component}\n * @param {boolean} [fCancel] is set to true to cancel a \"busy\" state\n * @return {boolean} true if \"busy\", false if not\n */\n isBusy(fCancel)\n {\n if (this.flags.busy) {\n if (fCancel) {\n this.flags.busyCancel = true;\n } else if (fCancel === undefined) {\n this.println(this.toString() + \" busy\");\n }\n }\n return this.flags.busy;\n }\n\n /**\n * setBusy(fBusy)\n *\n * Update the current busy state; if a busyCancel request is pending, it will be honored now.\n *\n * @this {Component}\n * @param {boolean} fBusy\n * @return {boolean}\n */\n setBusy(fBusy)\n {\n if (this.flags.busyCancel) {\n this.flags.busy = false;\n this.flags.busyCancel = false;\n return false;\n }\n if (this.flags.error) {\n this.println(this.toString() + \" error\");\n return false;\n }\n this.flags.busy = fBusy;\n return this.flags.busy;\n }\n\n /**\n * powerUp(fSave)\n *\n * @this {Component}\n * @param {Object|null} data\n * @param {boolean} [fRepower] is true if this is \"repower\" notification\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n this.flags.powered = true;\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Component}\n * @param {boolean} fSave\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n if (fShutdown) this.flags.powered = false;\n return true;\n }\n\n /**\n * messageEnabled(bitsMessage)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n *\n * @this {Component}\n * @param {number} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n * @return {boolean} true if all specified message enabled, false if not\n */\n messageEnabled(bitsMessage = 0)\n {\n if (DEBUGGER && this.dbg) {\n if (this !== this.dbg) {\n bitsMessage = bitsMessage || this.bitsMessage;\n }\n var bitsEnabled = this.dbg.bitsMessage & bitsMessage;\n /*\n * This next \"bit\" of logic is for PCx86 and any other machine where we've expanded the set of\n * messages by reusing bits in the low nibbles in combination with different bits in the high nibble.\n * If the input bits adhere to that format, then the mask we just produced must adhere to it as well,\n * and if it doesn't, zero the mask, ensuring that the test will return false.\n */\n if ((bitsMessage & 0xf0000000) && (bitsMessage & 0x0fffffff)) {\n if (!(bitsEnabled & 0xf0000000) || !(bitsEnabled & 0x0fffffff)) bitsEnabled = 0;\n }\n if (bitsMessage && bitsEnabled === bitsMessage) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * printf(format, ...args)\n *\n * @this {Component}\n * @param {string} format\n * @param {...} args\n */\n printf(format, ...args)\n {\n if (DEBUGGER && this.dbg) {\n if (this.messageEnabled()) {\n let s = Str.sprintf(format, ...args);\n /*\n * Since dbg.message() calls println(), we strip any ending linefeed.\n * \n * We could bypass the Debugger and go straight to this.print(), but we would lose\n * the benefits of debugger messages (eg, automatic buffering, halting, yielding, etc).\n */\n if (s.slice(-1) == '\\n') s = s.slice(0, -1);\n this.dbg.message(s);\n }\n }\n }\n\n /**\n * printMessage(sMessage, bitsMessage, fAddress)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n * If bitsMessage is true, the message is displayed regardless.\n *\n * @this {Component}\n * @param {string} sMessage is any caller-defined message string\n * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n * @param {boolean} [fAddress] is true to display the current address\n */\n printMessage(sMessage, bitsMessage, fAddress)\n {\n if (DEBUGGER && this.dbg) {\n if (bitsMessage === true || this.messageEnabled(bitsMessage | 0)) {\n this.dbg.message(sMessage, fAddress);\n }\n }\n }\n\n /**\n * printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n * If bitsMessage is true, the message is displayed as long as MESSAGE.PORT is enabled.\n *\n * @this {Component}\n * @param {number} port\n * @param {number|null} bOut if an output operation\n * @param {number|null} [addrFrom]\n * @param {string|null} [name] of the port, if any\n * @param {number|null} [bIn] is the input value, if known, on an input operation\n * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n */\n printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage)\n {\n if (DEBUGGER && this.dbg) {\n if (bitsMessage === true) {\n bitsMessage = 0;\n } else if (bitsMessage == null) {\n bitsMessage = this.bitsMessage;\n }\n this.dbg.messageIO(this, port, bOut, addrFrom, name, bIn, bitsMessage);\n }\n }\n}\n\n/*\n * Types recognized and supported by selected functions (eg, Computer.getMachineParm())\n */\nComponent.TYPE = {\n NUMBER: \"number\",\n OBJECT: \"object\",\n STRING: \"string\"\n};\n\n/*\n * These are the standard PRINT values you can pass as an optional argument to println(); in reality,\n * you can pass anything you want, because they are simply prepended to the message, although PROGRESS\n * messages may also be merged with earlier similar messages to keep the output buffer under control.\n */\nComponent.PRINT = {\n ERROR: \"error\",\n NOTICE: \"notice\",\n PROGRESS: \"progress\",\n SCRIPT: \"script\",\n WARNING: \"warning\"\n};\n\n/*\n * Every component created on the current page is recorded in this array (see Component.add()),\n * enabling any component to locate another component by ID (see Component.getComponentByID())\n * or by type (see Component.getComponentByType()).\n *\n * Every machine on the page are now recorded as well, by their machine ID. We then record the\n * various resources used by that machine.\n *\n * Includes a fallback for non-browser-based environments (ie, Node). TODO: This will need to be\n * tailored to Node, probably using the global object instead of the window object, if we ever want\n * to support multi-machine configs in that environment.\n */\nif (window) {\n if (!window['PCjs']) window['PCjs'] = {};\n if (!window['PCjs']['Machines']) window['PCjs']['Machines'] = {};\n if (!window['PCjs']['Components']) window['PCjs']['Components'] = [];\n if (!window['PCjs']['Commands']) window['PCjs']['Commands'] = {};\n}\nComponent.machines = window? window['PCjs']['Machines'] : {};\nComponent.components = window? window['PCjs']['Components'] : [];\nComponent.commands = window? window['PCjs']['Commands'] : {};\n\nComponent.asyncCommands = [\n 'hold', 'sleep', 'wait'\n];\nComponent.globalCommands = {\n 'alert': Component.scriptAlert,\n 'sleep': Component.scriptSleep\n};\nComponent.componentCommands = {\n 'select': Component.scriptSelect\n};\nComponent.printBuffer = \"\";\n\n/*\n * The following polyfills provide ES5 functionality that's missing in older browsers (eg, IE8),\n * allowing PCjs apps to run without slamming into exceptions; however, due to the lack of HTML5 canvas\n * support in those browsers, all you're likely to see are \"soft\" errors (eg, \"Missing <canvas> support\").\n *\n * Perhaps we can implement a text-only faux video display for a fun retro-browser experience someday.\n *\n * TODO: Come up with a better place to put these polyfills. We will likely have more if we decide to\n * make the leap from ES5 to ES6 features.\n */\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf\n */\nif (!Array.prototype.indexOf) {\n Array.prototype.indexOf = function(obj, start) {\n for (var i = (start || 0), j = this.length; i < j; i++) {\n if (this[i] === obj) { return i; }\n }\n return -1;\n }\n}\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray\n */\nif (!Array.isArray) {\n Array.isArray = function(arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n };\n}\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind\n */\nif (!Function.prototype.bind) {\n Function.prototype.bind = function(obj) {\n if (typeof this != \"function\") {\n // Closest thing possible to the ECMAScript 5 internal IsCallable function\n throw new TypeError(\"Function.prototype.bind: non-callable object\");\n }\n var args = Array.prototype.slice.call(arguments, 1);\n var fToBind = this;\n var fnNOP = /** @constructor */ (function() {});\n var fnBound = function() {\n return fToBind.apply(this instanceof fnNOP && obj? this : obj, args.concat(/** @type {Array} */(Array.prototype.slice.call(arguments))));\n };\n fnNOP.prototype = this.prototype;\n fnBound.prototype = new fnNOP();\n return fnBound;\n };\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/defines.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @define {string}\n */\nvar APPCLASS = \"c1pjs\"; // this @define is the default application class (eg, \"pcx86\", \"c1pjs\")\n\n/**\n * @define {string}\n */\nvar APPNAME = \"C1Pjs\"; // this @define is the default application name (eg, \"PCx86\", \"C1Pjs\")\n\n/**\n * @define {boolean}\n *\n * WARNING: DEBUGGER needs to accurately reflect whether or not the Debugger component is (or will be) loaded.\n * In the compiled case, we rely on the Closure Compiler to override DEBUGGER as appropriate. When it's *false*,\n * nearly all of debugger.js will be conditionally removed by the compiler, reducing it to little more than a\n * \"type skeleton\", which also solves some type-related warnings we would otherwise have if we tried to remove\n * debugger.js from the compilation process altogether.\n *\n * However, when we're in \"development mode\" and running uncompiled code in debugger-less configurations,\n * I would like to skip loading debugger.js altogether. When doing that, we must ALSO arrange for an additional file\n * (nodebugger.js) to be loaded immediately after this file, which *explicitly* overrides DEBUGGER with *false*.\n */\nvar DEBUGGER = true; // this @define is overridden by the Closure Compiler to remove Debugger-related support\n\n/*\n * Combine all the shared globals and machine-specific globals into one machine-specific global object,\n * which all machine components should start using; eg: \"if (C1PJS.DEBUG) ...\" instead of \"if (DEBUG) ...\".\n */\nvar C1PJS = {\n APPCLASS: APPCLASS,\n APPNAME: APPNAME,\n APPVERSION: APPVERSION, // shared\n COMPILED: COMPILED, // shared\n CSSCLASS: CSSCLASS, // shared\n DEBUG: DEBUG, // shared\n DEBUGGER: DEBUGGER,\n MAXDEBUG: MAXDEBUG, // shared\n PRIVATE: PRIVATE, // shared\n SITEHOST: SITEHOST, // shared\n XMLVERSION: XMLVERSION // shared\n};\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/panel.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass C1PPanel extends Component {\n /**\n * C1PPanel(parmsPanel)\n *\n * The Panel component has no required (parmsPanel) properties.\n *\n * @this {C1PPanel}\n * @param {Object} parmsPanel\n */\n constructor(parmsPanel)\n {\n super(\"C1PPanel\", parmsPanel);\n\n this.flags.powered = false;\n }\n\n /**\n * The Panel doesn't have any bindings of its own; it passes along all binding requests to\n * the Computer, CPU, Keyboard and Debugger components. The order shouldn't matter, since any\n * component that doesn't recognize the specified binding should simply ignore it.\n *\n * @this {C1PPanel}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n if (this.cmp && this.cmp.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (this.cpu && this.cpu.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (this.kbd && this.kbd.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (DEBUGGER && this.dbg && this.dbg.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n return super.setBinding(sHTMLType, sBinding, control, sValue);\n }\n\n /**\n * @this {C1PPanel}\n * @param {boolean} fOn\n * @param {C1PComputer} cmp\n */\n setPower(fOn, cmp)\n {\n if (fOn && !this.flags.powered) {\n this.flags.powered = true;\n this.cmp = cmp;\n this.cpu = cmp.getComponentByType(\"cpu\");\n this.kbd = cmp.getComponentByType(\"keyboard\");\n if (DEBUGGER) this.dbg = cmp.getComponentByType(\"debugger\");\n C1PPanel.init();\n }\n }\n\n /**\n * C1PPanel.init()\n *\n * This function operates on every HTML element of class \"panel\", extracting the\n * JSON-encoded parameters for the C1PPanel constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a C1PPanel component, and then binding\n * any associated HTML controls to the new component.\n *\n * NOTE: Unlike most other component init() functions, this one is designed to be\n * called multiple times: once at load time, so that we can binding our print()\n * function to the panel's output control ASAP, and again when the C1PComputer component\n * is verifying that all components are ready and invoking their setPower() functions.\n *\n * Our setPower() method gives us a second opportunity to notify any components that\n * that might care (eg, C1PCPU, C1PKeyboard, and C1PDebugger) that we have some controls\n * they might want to use.\n */\n static init()\n {\n var fReady = false;\n var aePanels = Component.getElementsByClass(document, C1PJS.APPCLASS, \"panel\");\n for (var iPanel=0; iPanel < aePanels.length; iPanel++) {\n var ePanel = aePanels[iPanel];\n var parmsPanel = Component.getComponentParms(ePanel);\n var panel = Component.getComponentByID(parmsPanel['id']);\n if (!panel) {\n fReady = true;\n panel = new C1PPanel(parmsPanel);\n }\n Component.bindComponentControls(panel, ePanel, C1PJS.APPCLASS);\n if (fReady) panel.setReady();\n }\n }\n}\n\n/*\n * Initialize every Panel module on the page.\n */\nWeb.onInit(C1PPanel.init);\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/cpu.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass C1PCPU extends Component {\n /**\n * C1PCPU(parmsCPU)\n *\n * The C1PCPU object has one component-specific initialization property:\n *\n * autoStart: true to automatically start, false to not, or null (default)\n * to make the autoStart decision based on whether or not a Debugger is\n * installed (if there's no Debugger AND no \"Run\" button, then auto-start,\n * otherwise don't)\n *\n * It is hard-coded to simulate a 6502 microprocessor, but it also contains\n * hooks into other components for communication with the outside world (eg,\n * Panel and Debugger components). This is a logical simulation, not a physical\n * simulation, and performance is important, so we take lots of liberties; any\n * idiosyncrasies of actual 6502 hardware may not be simulated here, unless it\n * affects the accuracy of the simulation when running actual 6502 software.\n *\n * @this {C1PCPU}\n * @param {Object} parmsCPU\n */\n constructor(parmsCPU)\n {\n super(\"C1PCPU\", parmsCPU);\n\n this.clearRegs();\n this.flags.powered = false;\n this.flags.running = false;\n this.fAutoStart = parmsCPU[\"autoStart\"];\n\n /*\n * speed is a number from 0 to 2, where 0 means run as close to 1Mhz as possible,\n * 1 means run at the fastest safe speed, and 2 means run at maximum speed.\n *\n * It's updated via the setSpeed() function, which the Debugger's \"option\" command\n * uses to adjust the virtual speed (eg, \"o slow\", \"o fast\"). There may also\n * be a button present to control the speed as well (using the \"setSpeed\" binding).\n */\n this.SPEED_SLOW = 0; // see this.mhzSlow\n this.SPEED_FAST = 1; // see this.mhzFast\n this.SPEED_MAX = 2;\n this.speed = this.SPEED_SLOW;\n this.nCyclesPerSecond = 1000000;\n\n /*\n * Additional values that control the overall speed of the simulated hardware,\n * and the frequency at which various updates should occur. There are no UI\n * mechanisms for tweaking these values (yet).\n *\n * NOTE: Use of the term \"second\" below refers to a virtual CPU second, consisting of\n * 1 million simulated cycles. The values below are used to divide those 1 million\n * cycles into intervals of \"work\", and as long we are limiting the simulation to 1Mhz\n * per ACTUAL second, then 1 virtual second == 1 real second.\n *\n * However, if the setSpeed() function is used to lift the 1Mhz limit, then 1 virtual\n * second may become much shorter, which is why you may briefly notice the video and/or\n * status (control panel) updates occurring more frequently. To compensate, calcCycles()\n * will automatically scale these values if a recent speed recalculation reveals that\n * we're running significantly faster than 1Mhz.\n */\n this.nYieldsPerSecond = 30;\n this.nVideoUpdatesPerSecond = 30;\n this.nStatusUpdatesPerSecond = 5;\n this.mhzSlow = 1;\n this.mhzFast = 8;\n this.aSpeeds = [\"Slow\", \"Fast\", \"Max\"];\n this.aSpeedDescs = [\"(\" + this.mhzSlow + \"Mhz)\", \"(up to \" + this.mhzFast + \"Mhz)\", \"(unlimited)\"];\n\n /*\n * Lists of notification handlers: aReadNotify and aWriteNotify are lists (ie, Arrays)\n * of 4-element sub-arrays that, in turn, contain:\n *\n * [0]: starting address of memory range to monitor\n * [1]: ending address of memory range to monitor (inclusive)\n * [2]: registered component\n * [3]: registered function to call for every read/write from/to memory in that range\n *\n * The virtual Serial Port and virtual Keyboard components use these handlers to trap\n * references to their respective memory-based \"ports\". Also, the ROM component uses it\n * to \"repair\" any writes to its address range, since memory is one big array, and arrays\n * don't support \"write-only\" regions.\n *\n * NOTE: the Video component does NOT use notification handlers, because video memory\n * is written (and occasionally read) far too frequently for that to be efficient. We\n * just let the CPU pound on it like any other chunk of memory, and then make periodic\n * calls directly to the Video component to refresh all portions of the video buffer\n * that have changed since the last refresh. See displayVideo() for more details.\n *\n * WARNING: Write notifications currently do not catch STACK writes (ie, BRK, JSR, PHA and\n * PHP instructions), because I simply haven't added the necessary code. Besides, JSR is\n * one of the most-executed instructions, so I'd rather not slow it down. Note that this\n * STACK write limitation affects both the CPU's write-notification handlers AND the Debugger's\n * write breakpoints.\n */\n this.aReadNotify = [];\n this.aWriteNotify = [];\n\n /*\n * To speed up the processing of read and write notification handlers, we keep track of\n * lower and upper address bounds for each set. These variables maintain those bounds.\n * They are initialized to values outside the accessible range of addresses.\n */\n this.addrReadLower = 0x10000;\n this.addrReadUpper = 0x0;\n this.addrWriteLower = 0x10000;\n this.addrWriteUpper = 0x0;\n\n /*\n * Processor status register (P) flag masks\n */\n this.BIT_PN = 0x80; // N = sign\n this.BIT_PV = 0x40; // V = overflow\n this.BIT_PB = 0x10; // B = break\n this.BIT_PD = 0x08; // D = decimal\n this.BIT_PI = 0x04; // I = interrupt\n this.BIT_PZ = 0x02; // Z = zero\n this.BIT_PC = 0x01; // C = carry\n\n // this.VECTOR_NMI = 0xfffa;\n this.VECTOR_RESET = 0xfffc;\n // this.VECTOR_IRQ = 0xfffe;\n\n /*\n * Popular opcodes\n */\n this.OP_JSR = 0x20;\n\n /*\n * opSim operation codes\n */\n this.OP_SIM = 0x02;\n this.SIMOP_HLT = 0x00;\n this.SIMOP_MSG = 0x01;\n\n /*\n * This 256-entry array of opcode functions is at the heart of the CPU engine: step(n).\n *\n * It might be worth trying a switch() statement instead, to see how the performance compares,\n * but I suspect that will vary quite a bit across JavaScript engines; for now, I'm putting my\n * money on array lookup.\n */\n this.aOpcodeFuncs = [\n this.opBRK, // 0x00\n this.opORAindx, // 0x01\n this.opSim, // 0x02\n this.opUndefined, // 0x03\n this.opUndefined, // 0x04\n this.opORAzp, // 0x05\n this.opASLzp, // 0x06\n this.opUndefined, // 0x07\n this.opPHP, // 0x08\n this.opORAimm, // 0x09\n this.opASLacc, // 0x0a\n this.opUndefined, // 0x0b\n this.opUndefined, // 0x0c\n this.opORAabs, // 0x0d\n this.opASLabs, // 0x0e\n this.opUndefined, // 0x0f\n this.opBPL, // 0x10\n this.opORAindy, // 0x11\n this.opUndefined, // 0x12\n this.opUndefined, // 0x13\n this.opUndefined, // 0x14\n this.opORAzpx, // 0x15\n this.opASLzpx, // 0x16\n this.opUndefined, // 0x17\n this.opCLC, // 0x18\n this.opORAabsy, // 0x19\n this.opUndefined, // 0x1a\n this.opUndefined, // 0x1b\n this.opUndefined, // 0x1c\n this.opORAabsx, // 0x1d\n this.opASLabsx, // 0x1e\n this.opUndefined, // 0x1f\n this.opJSRabs, // 0x20\n this.opANDindx, // 0x21\n this.opUndefined, // 0x22\n this.opUndefined, // 0x23\n this.opBITzp, // 0x24\n this.opANDzp, // 0x25\n this.opROLzp, // 0x26\n this.opUndefined, // 0x27\n this.opPLP, // 0x28\n this.opANDimm, // 0x29\n this.opROLacc, // 0x2a\n this.opUndefined, // 0x2b\n this.opBITabs, // 0x2c\n this.opANDabs, // 0x2d\n this.opROLabs, // 0x2e\n this.opUndefined, // 0x2f\n this.opBMI, // 0x30\n this.opANDindy, // 0x31\n this.opUndefined, // 0x32\n this.opUndefined, // 0x33\n this.opUndefined, // 0x34\n this.opANDzpx, // 0x35\n this.opROLzpx, // 0x36\n this.opUndefined, // 0x37\n this.opSEC, // 0x38\n this.opANDabsy, // 0x39\n this.opUndefined, // 0x3a\n this.opUndefined, // 0x3b\n this.opUndefined, // 0x3c\n this.opANDabsx, // 0x3d\n this.opROLabsx, // 0x3e\n this.opUndefined, // 0x3f\n this.opRTI, // 0x40\n this.opEORindx, // 0x41\n this.opUndefined, // 0x42\n this.opUndefined, // 0x43\n this.opUndefined, // 0x44\n this.opEORzp, // 0x45\n this.opLSRzp, // 0x46\n this.opUndefined, // 0x47\n this.opPHA, // 0x48\n this.opEORimm, // 0x49\n this.opLSRacc, // 0x4a\n this.opUndefined, // 0x4b\n this.opJMPimm16, // 0x4c\n this.opEORabs, // 0x4d\n this.opLSRabs, // 0x4e\n this.opUndefined, // 0x4f\n this.opBVC, // 0x50\n this.opEORindy, // 0x51\n this.opUndefined, // 0x52\n this.opUndefined, // 0x53\n this.opUndefined, // 0x54\n this.opEORzpx, // 0x55\n this.opLSRzpx, // 0x56\n this.opUndefined, // 0x57\n this.opCLI, // 0x58\n this.opEORabsy, // 0x59\n this.opUndefined, // 0x5a\n this.opUndefined, // 0x5b\n this.opUndefined, // 0x5c\n this.opEORabsx, // 0x5d\n this.opLSRabsx, // 0x5e\n this.opUndefined, // 0x5f\n this.opRTS, // 0x60\n this.opADCindx, // 0x61\n this.opUndefined, // 0x62\n this.opUndefined, // 0x63\n this.opUndefined, // 0x64\n this.opADCzp, // 0x65\n this.opRORzp, // 0x66\n this.opUndefined, // 0x67\n this.opPLA, // 0x68\n this.opADCimm, // 0x69\n this.opRORacc, // 0x6a\n this.opUndefined, // 0x6b\n this.opJMPabs16, // 0x6c\n this.opADCabs, // 0x6d\n this.opRORabs, // 0x6e\n this.opUndefined, // 0x6f\n this.opBVS, // 0x70\n this.opADCindy, // 0x71\n this.opUndefined, // 0x72\n this.opUndefined, // 0x73\n this.opUndefined, // 0x74\n this.opADCzpx, // 0x75\n this.opRORzpx, // 0x76\n this.opUndefined, // 0x77\n this.opSEI, // 0x78\n this.opADCabsy, // 0x79\n this.opUndefined, // 0x7a\n this.opUndefined, // 0x7b\n this.opUndefined, // 0x7c\n this.opADCabsx, // 0x7d\n this.opRORabsx, // 0x7e\n this.opUndefined, // 0x7f\n this.opUndefined, // 0x80\n this.opSTAindx, // 0x81\n this.opUndefined, // 0x82\n this.opUndefined, // 0x83\n this.opSTYzp, // 0x84\n this.opSTAzp, // 0x85\n this.opSTXzp, // 0x86\n this.opUndefined, // 0x87\n this.opDEY, // 0x88\n this.opUndefined, // 0x89\n this.opTXA, // 0x8a\n this.opUndefined, // 0x8b\n this.opSTYabs, // 0x8c\n this.opSTAabs, // 0x8d\n this.opSTXabs, // 0x8e\n this.opUndefined, // 0x8f\n this.opBCC, // 0x90\n this.opSTAindy, // 0x91\n this.opUndefined, // 0x92\n this.opUndefined, // 0x93\n this.opSTYzpx, // 0x94\n this.opSTAzpx, // 0x95\n this.opSTXzpy, // 0x96\n this.opUndefined, // 0x97\n this.opTYA, // 0x98\n this.opSTAabsy, // 0x99\n this.opTXS, // 0x9a\n this.opUndefined, // 0x9b\n this.opUndefined, // 0x9c\n this.opSTAabsx, // 0x9d\n this.opUndefined, // 0x9e\n this.opUndefined, // 0x9f\n this.opLDYimm, // 0xa0\n this.opLDAindx, // 0xa1\n this.opLDXimm, // 0xa2\n this.opUndefined, // 0xa3\n this.opLDYzp, // 0xa4\n this.opLDAzp, // 0xa5\n this.opLDXzp, // 0xa6\n this.opUndefined, // 0xa7\n this.opTAY, // 0xa8\n this.opLDAimm, // 0xa9\n this.opTAX, // 0xaa\n this.opUndefined, // 0xab\n this.opLDYabs, // 0xac\n this.opLDAabs, // 0xad\n this.opLDXabs, // 0xae\n this.opUndefined, // 0xaf\n this.opBCS, // 0xb0\n this.opLDAindy, // 0xb1\n this.opUndefined, // 0xb2\n this.opUndefined, // 0xb3\n this.opLDYzpx, // 0xb4\n this.opLDAzpx, // 0xb5\n this.opLDXzpy, // 0xb6\n this.opUndefined, // 0xb7\n this.opCLV, // 0xb8\n this.opLDAabsy, // 0xb9\n this.opTSX, // 0xba\n this.opUndefined, // 0xbb\n this.opLDYabsx, // 0xbc\n this.opLDAabsx, // 0xbd\n this.opLDXabsy, // 0xbe\n this.opUndefined, // 0xbf\n this.opCPYimm, // 0xc0\n this.opCMPindx, // 0xc1\n this.opUndefined, // 0xc2\n this.opUndefined, // 0xc3\n this.opCPYzp, // 0xc4\n this.opCMPzp, // 0xc5\n this.opDECzp, // 0xc6\n this.opUndefined, // 0xc7\n this.opINY, // 0xc8\n this.opCMPimm, // 0xc9\n this.opDEX, // 0xca\n this.opUndefined, // 0xcb\n this.opCPYabs, // 0xcc\n this.opCMPabs, // 0xcd\n this.opDECabs, // 0xce\n this.opUndefined, // 0xcf\n this.opBNE, // 0xd0\n this.opCMPindy, // 0xd1\n this.opUndefined, // 0xd2\n this.opUndefined, // 0xd3\n this.opUndefined, // 0xd4\n this.opCMPzpx, // 0xd5\n this.opDECzpx, // 0xd6\n this.opUndefined, // 0xd7\n this.opCLD, // 0xd8\n this.opCMPabsy, // 0xd9\n this.opUndefined, // 0xda\n this.opUndefined, // 0xdb\n this.opUndefined, // 0xdc\n this.opCMPabsx, // 0xdd\n this.opDECabsx, // 0xde\n this.opUndefined, // 0xdf\n this.opCPXimm, // 0xe0\n this.opSBCindx, // 0xe1\n this.opUndefined, // 0xe2\n this.opUndefined, // 0xe3\n this.opCPXzp, // 0xe4\n this.opSBCzp, // 0xe5\n this.opINCzp, // 0xe6\n this.opUndefined, // 0xe7\n this.opINX, // 0xe8\n this.opSBCimm, // 0xe9\n this.opNOP, // 0xea\n this.opUndefined, // 0xeb\n this.opCPXabs, // 0xec\n this.opSBCabs, // 0xed\n this.opINCabs, // 0xee\n this.opUndefined, // 0xef\n this.opBEQ, // 0xf0\n this.opSBCindy, // 0xf1\n this.opUndefined, // 0xf2\n this.opUndefined, // 0xf3\n this.opUndefined, // 0xf4\n this.opSBCzpx, // 0xf5\n this.opINCzpx, // 0xf6\n this.opUndefined, // 0xf7\n this.opSED, // 0xf8\n this.opSBCabsy, // 0xf9\n this.opUndefined, // 0xfa\n this.opUndefined, // 0xfb\n this.opUndefined, // 0xfc\n this.opSBCabsx, // 0xfd\n this.opINCabsx, // 0xfe\n this.opUndefined // 0xff\n ];\n /*\n * This is a 256-byte array of cycle counts, indexed by opcode.\n * Obviously, true cycle counts are a bit more complicated, but this\n * gets us most of the way to an authentic-feeling simulation.\n *\n * NOTE: BCD functions now account for an extra cycle, and branches\n * now account for an extra cycle whenever the branch is taken.\n * However, branches still don't add an extra cycle whenever the branch\n * crosses a page boundary.\n *\n * The other gaping hole in our cycle-counting is accounting for all\n * page-boundary penalties. Ideally, that's just a matter of checking\n * MODE_ABSX, MODE_ABSY, and MODE_INDY instructions for EA straddling\n * a page boundary--but is it more complicated than that? What if the\n * criteria is not the final EA, but whether the pre-indexing and\n * post-indexing EAs are in different pages? I also need to confirm\n * whether any other situations merit checking (eg, when a 2 or 3-byte\n * instruction straddles a page boundary).\n */\n this.aOpcodeCycles = [\n 7,6,0,0,0,3,5,0,3,2,2,0,0,4,6,0,\n 2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0,\n 3,6,0,0,3,3,5,0,4,2,2,0,4,4,6,0,\n 2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0,\n 6,6,0,0,0,3,5,0,3,2,2,0,3,4,6,0,\n 2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0,\n 6,6,0,0,0,3,5,0,4,2,2,0,5,4,6,0,\n 2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0,\n 0,6,0,0,3,3,3,0,2,0,2,0,4,4,4,0,\n 2,5,0,0,4,4,4,0,2,4,2,0,0,4,0,0,\n 2,6,2,0,3,3,3,0,2,2,2,0,4,4,4,0,\n 2,5,0,0,4,4,4,0,2,4,2,0,4,4,4,0,\n 2,6,0,0,3,3,5,0,2,2,2,0,4,4,6,0,\n 2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0,\n 2,6,0,0,3,3,5,0,2,2,2,0,4,4,6,0,\n 2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0\n ];\n }\n\n /**\n * reset(fPowerOn)\n *\n * Note that we follow the same model here as other selected reset() handlers; for example, Video.reset()\n * accepts an fPowerOn parameter to govern what's initially displayed on the video screen.\n *\n * @this {C1PCPU}\n * @param {boolean|undefined} fPowerOn is true for the initial reset, so that if the Debugger isn't\n * loaded, we can elect to start running. Under any other circumstances (such as whenever Computer.reset()\n * is called), \"auto-run\" is not a good idea, and can actually introduce bugs (eg, multiple run() timers).\n */\n reset(fPowerOn)\n {\n if (this.flags.running) {\n this.halt();\n }\n this.clearRegs();\n this.regPC = this.getWord(this.VECTOR_RESET);\n this.clearError(); // clear any fatal error/exception\n /*\n * If there's a Debugger, notify Debugger.reset(); otherwise, start running\n */\n if (DEBUGGER && this.dbg) {\n this.dbg.reset();\n }\n else if (fPowerOn) {\n if (this.fAutoStart === true || this.fAutoStart === null && (!DEBUGGER || !this.dbg) && this.bindings[\"run\"] === undefined) {\n this.run(); // start running automatically on the initial power-up, assuming there's no Debugger\n }\n }\n }\n\n /**\n * @this {C1PCPU}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"run\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var fBound = false;\n switch(sBinding) {\n case \"run\":\n this.bindings[sBinding] = control;\n control.onclick = function(cpu) {\n return function() {\n if (!cpu.flags.running) {\n cpu.run();\n } else {\n cpu.halt();\n }\n };\n }(this);\n fBound = true;\n break;\n case \"A\": case \"X\": case \"Y\": case \"S\": case \"PC\":\n case \"C\": case \"Z\": case \"I\": case \"D\": case \"B\": case \"V\": case \"N\":\n case \"speed\":\n this.bindings[sBinding] = control;\n fBound = true;\n break;\n case \"setSpeed\":\n this.bindings[sBinding] = control;\n control.onclick = function(cpu) {\n return function() {\n var speed = (cpu.speed >= cpu.SPEED_MAX? cpu.SPEED_SLOW : cpu.speed+1);\n cpu.setSpeed(speed, true);\n };\n }(this);\n fBound = true;\n break;\n default:\n break;\n }\n return fBound;\n }\n\n /**\n * @this {C1PCPU}\n * @param {Array} abMemory\n * @param {number} start\n * @param {number} end\n */\n setBuffer(abMemory, start, end)\n {\n this.abMem = abMemory;\n this.offMem = start;\n this.cbMem = end - start + 1;\n this.offLimit = this.offMem + this.cbMem;\n if (this.offMem) {\n /*\n * It's not that we couldn't support an address buffer that starts at a non-zero offset;\n * we simply have lots of code (eg, all the opcode handlers) that assumes offMem is zero,\n * and therefore that abMem can be indexed by any of the CPU registers without adding offMem.\n * All that code would have to be changed (at a slight performance penalty) if we couldn't\n * make this assumption.\n */\n Component.error(\"unsupported CPU address buffer offset (\" + this.offMem + \")\");\n return;\n }\n this.setReady();\n }\n\n /**\n * @this {C1PCPU}\n * @param {boolean} fOn\n * @param {C1PComputer} cmp\n */\n setPower(fOn, cmp)\n {\n if (fOn && !this.flags.powered) {\n this.cmp = cmp;\n /*\n * Attach the Debugger, if any, to the CPU, so that the CPU can periodically\n * notify it as needed (when the CPU starts, stops, and executes instructions)\n */\n if (DEBUGGER) {\n this.dbg = cmp.getComponentByType(\"debugger\");\n if (this.dbg)\n this.dbg.init();\n }\n /*\n * Attach the Video device to the CPU, so that the CPU can periodically update\n * the video display via displayVideo(), as cycles permit.\n */\n var video = cmp.getComponentByType(\"video\");\n if (video) {\n this.displayVideo = function(v) {\n return function() {\n v.updateScreen();\n };\n }(video);\n this.setFocus = function(v) {\n return function() {\n v.setFocus();\n };\n }(video);\n }\n this.flags.powered = true;\n this.reset(true);\n this.update();\n }\n }\n\n /**\n * Add a memory read-notification handler to the CPU's list of such handlers.\n *\n * @this {C1PCPU}\n * @param {number} start address\n * @param {number} end address\n * @param {Component} component\n * @param {function(number,number)} fn is called with the EA and PC values at the time of the write\n */\n addReadNotify(start, end, component, fn)\n {\n if (this.findNotify(this.aReadNotify, start, end, component, fn) < 0) {\n if (this.addrReadLower > start)\n this.addrReadLower = start;\n if (this.addrReadUpper < end)\n this.addrReadUpper = end;\n this.aReadNotify.push([start, end, component, fn]);\n if (DEBUG) this.log(\"addReadNotify(\" + Str.toHexWord(start) + \",\" + Str.toHexWord(end) + \",\" + component.id + \"): new read range: \" + Str.toHexWord(this.addrReadLower) + \"-\" + Str.toHexWord(this.addrReadUpper));\n }\n }\n\n /**\n * @this {C1PCPU}\n * @param {number} addrRead is the EA value at the time of the read\n * @param {number} [addrFrom] is the PC value at the time of the read;\n * this will be undefined for read notifications triggered by assorted Debugger commands,\n * so all handlers should be prepared for that as well.\n */\n checkReadNotify(addrRead, addrFrom)\n {\n for (var i=0; i < this.aReadNotify.length; i++) {\n if (addrRead >= this.aReadNotify[i][0] && addrRead <= this.aReadNotify[i][1]) {\n this.aReadNotify[i][3].call(this.aReadNotify[i][2], addrRead, addrFrom);\n }\n }\n }\n\n /**\n * Remove a memory read-notification handler from the CPU's list of such handlers.\n *\n * @this {C1PCPU}\n * @param {number} start address\n * @param {number} end address\n * @param {Component} component\n * @param {function(number,number)} fn of previously added handler\n * @return {boolean} true if remove was successful, false if the handler was not found\n */\n removeReadNotify(start, end, component, fn)\n {\n var aBounds = this.removeNotify(this.aReadNotify, start, end, component, fn);\n if (aBounds.length == 4) {\n this.addrReadLower = aBounds[2];\n this.addrReadUpper = aBounds[3];\n if (DEBUG) this.log(\"removeReadNotify(\" + Str.toHexWord(start) + \",\" + Str.toHexWord(end) + \",\" + component.id + \"): new read range: \" + Str.toHexWord(this.addrReadLower) + \"-\" + Str.toHexWord(this.addrReadUpper));\n return true;\n }\n return false;\n }\n\n /**\n * Add a memory write-notification handler to the CPU's list of such handlers.\n *\n * @this {C1PCPU}\n * @param {number} start address\n * @param {number} end address\n * @param {Component} component\n * @param {function(number,number)} fn is called with the EA and PC values at the time of the write\n */\n addWriteNotify(start, end, component, fn)\n {\n if (this.findNotify(this.aWriteNotify, start, end, component, fn) < 0) {\n if (this.addrWriteLower > start)\n this.addrWriteLower = start;\n if (this.addrWriteUpper < end)\n this.addrWriteUpper = end;\n this.aWriteNotify.push([start, end, component, fn]);\n if (DEBUG) this.log(\"addWriteNotify(\" + Str.toHexWord(start) + \",\" + Str.toHexWord(end) + \",\" + component.id + \"): new write range: \" + Str.toHexWord(this.addrWriteLower) + \"-\" + Str.toHexWord(this.addrWriteUpper));\n }\n }\n\n /**\n * @this {C1PCPU}\n * @param {number} addrWrite is the EA value at the time of the write\n * @param {number} [addrFrom] is the PC value at the time of the write;\n * this will be undefined for write notifications triggered by assorted Debugger commands,\n * so all handlers should be prepared for that as well.\n */\n checkWriteNotify(addrWrite, addrFrom)\n {\n for (var i=0; i < this.aWriteNotify.length; i++) {\n if (addrWrite >= this.aWriteNotify[i][0] && addrWrite <= this.aWriteNotify[i][1]) {\n this.aWriteNotify[i][3].call(this.aWriteNotify[i][2], addrWrite, addrFrom);\n }\n }\n }\n\n /**\n * Remove a memory write-notification handler from the CPU's list of such handlers.\n *\n * @this {C1PCPU}\n * @param {number} start address\n * @param {number} end address\n * @param {Component} component\n * @param {function(number,number)} fn of previously added handler\n * @return {boolean} true if remove was successful, false if the handler was not found\n */\n removeWriteNotify(start, end, component, fn)\n {\n var aBounds = this.removeNotify(this.aWriteNotify, start, end, component, fn);\n if (aBounds.length == 4) {\n this.addrWriteLower = aBounds[2];\n this.addrWriteUpper = aBounds[3];\n if (DEBUG) this.log(\"removeWriteNotify(\" + Str.toHexWord(start) + \",\" + Str.toHexWord(end) + \",\" + component.id + \"): new write range: \" + Str.toHexWord(this.addrWriteLower) + \"-\" + Str.toHexWord(this.addrWriteUpper));\n return true;\n }\n return false;\n }\n\n /**\n * Find a memory notification handler from the given array of handlers\n *\n * @this {C1PCPU}\n * @param {Array} aNotify array of handlers\n * @param {number} start address\n * @param {number} end address\n * @param {Component} component\n * @param {function(number,number)} fn of previously added handler\n * @return {number} index of the matching handler, or -1 if not found\n */\n findNotify(aNotify, start, end, component, fn)\n {\n for (var i=0; i < aNotify.length; i++) {\n if (aNotify[i][0] == start && aNotify[i][1] == end && aNotify[i][2] == component && aNotify[i][3] == fn) {\n return i;\n }\n }\n return -1;\n }\n\n /**\n * Remove a memory notification handler from the given array of handlers\n *\n * @this {C1PCPU}\n * @param {Array} aNotify array of handlers\n * @param {number} start address\n * @param {number} end address\n * @param {Component} component\n * @param {function(number,number)} fn of previously added handler\n * @return {Array} bounds of previous handler ([0] and [1]) and new lower and upper address bounds ([2] and [3])\n */\n removeNotify(aNotify, start, end, component, fn)\n {\n var aBounds = [];\n var i = this.findNotify(aNotify, start, end, component, fn);\n if (i >= 0) {\n aBounds.push(aNotify[i][0]);\n aBounds.push(aNotify[i][1]);\n aNotify.splice(i, 1);\n var addrLower = 0x10000, addrUpper = 0x0;\n for (i=0; i < aNotify.length; i++) {\n if (addrLower > aNotify[i][0])\n addrLower = aNotify[i][0];\n if (addrUpper < aNotify[i][1])\n addrUpper = aNotify[i][1];\n }\n aBounds.push(addrLower);\n aBounds.push(addrUpper);\n }\n return aBounds;\n }\n\n /**\n * @this {C1PCPU}\n * @param {number} [speed] is one of: 0 (slow), 1 (fast) or 2 (maximum)\n * @param {boolean} [fOnClick] is true if called from a click handler that might have stolen focus\n * @desc Whenever the speed is changed, the running cycle count and corresponding start time must be reset,\n * so that the next effective speed calculation obtains sensible results. In fact, when run() initially calls\n * setSpeed() with no parameters, that's all this function does (it doesn't change the current speed setting).\n */\n setSpeed(speed, fOnClick)\n {\n if (speed !== undefined) {\n this.speed = speed;\n if (this.bindings[\"setSpeed\"])\n this.bindings[\"setSpeed\"].innerHTML = this.aSpeeds[speed >= 2? 0 : speed+1];\n this.println(\"running at \" + this.aSpeeds[speed].toLowerCase() + \" speed \" + this.aSpeedDescs[speed]);\n if (fOnClick) this.setFocus();\n }\n this.nRunCycles = 0;\n this.msRunStart = Usr.getTime();\n this.calcCycles();\n }\n\n /**\n * @this {C1PCPU}\n * @param {number} nCycles\n * @param {number} msElapsed\n */\n calcSpeed(nCycles, msElapsed)\n {\n if (msElapsed) {\n this.mhz = Math.round(nCycles / ( msElapsed * 100)) / 10;\n if (msElapsed >= 86400000)\n this.setSpeed(); // reset all our counters once per day so that we never have to worry about overflow\n }\n }\n\n /**\n * @this {C1PCPU}\n */\n displayVideo()\n {\n // Nothing to do until setPower() installs a replacement function\n }\n\n /**\n * @this {C1PCPU}\n */\n setFocus()\n {\n // Nothing to do until setPower() installs a replacement function\n }\n\n /**\n * @this {C1PCPU}\n * @param {string} sReg\n * @param {number} vReg\n * @param {number} [len]\n */\n displayReg(sReg, vReg, len)\n {\n if (this.bindings[sReg] !== undefined) {\n if (len === undefined) len = 1;\n var s = \"0000\" + vReg.toString(16);\n this.bindings[sReg].innerHTML = s.slice(s.length-len).toUpperCase();\n }\n }\n\n /**\n * @this {C1PCPU}\n */\n displayStatus()\n {\n this.displayReg(\"A\", this.regA, 2);\n this.displayReg(\"X\", this.regX, 2);\n this.displayReg(\"Y\", this.regY, 2);\n var regP = this.getRegP();\n this.displayReg(\"C\", (regP & this.BIT_PC)? 1 : 0);\n this.displayReg(\"Z\", (regP & this.BIT_PZ)? 1 : 0);\n this.displayReg(\"I\", (regP & this.BIT_PI)? 1 : 0);\n this.displayReg(\"D\", (regP & this.BIT_PD)? 1 : 0);\n this.displayReg(\"B\", (regP & this.BIT_PB)? 1 : 0);\n this.displayReg(\"V\", (regP & this.BIT_PV)? 1 : 0);\n this.displayReg(\"N\", (regP & this.BIT_PN)? 1 : 0);\n this.displayReg(\"S\", this.regS, 4);\n this.displayReg(\"PC\", this.regPC, 4);\n if (this.bindings[\"speed\"] && this.mhz) {\n this.bindings[\"speed\"].innerHTML = this.mhz.toFixed(1) + \"Mhz\";\n }\n }\n\n /**\n * @this {C1PCPU}\n * @return {boolean}\n */\n isRunning()\n {\n return this.flags.running;\n }\n\n /**\n * Calculate the number of cycles to process for each \"burst\" of CPU activity. The size of a burst\n * is driven by the following values:\n *\n * nYieldsPerSecond (eg, 30)\n * nVideoUpdatesPerSecond (eg, 30)\n * nStatusUpdatesPerSecond (eg, 5)\n *\n * The largest of the above values forces the size of the burst to its smallest value. Let's say that\n * largest value is 30. Assuming nCyclesPerSecond is 1,000,000, that results in bursts of 33,333 cycles.\n *\n * At the end of each burst, we subtract burst cycles from yield, video, and status cycle \"threshold\"\n * counters. Whenever the \"next yield\" cycle counter goes to (or below) zero, we compare elapsed time\n * to the time we expected the virtual hardware to take (eg, 1000ms/50 or 20ms), and if we still have time\n * remaining, we sleep the remaining time (or 0ms if there's no remaining time), and then restart run().\n *\n * Similarly, whenever the \"next video update\" cycle counter goes to (or below) zero, we call displayVideo(),\n * and whenever the \"next status update\" cycle counter goes to (or below) zero, we call displayStatus().\n *\n * @this {C1PCPU}\n * @param {boolean} [fRecalc] is true if the caller wants to recalculate thresholds based on the\n * most recent mhz calculation (see calcSpeed)\n */\n calcCycles(fRecalc)\n {\n /*\n * Calculate the most cycles we're allowed to execute in a single \"burst\"\n */\n var nMostUpdatesPerSecond = this.nYieldsPerSecond;\n if (nMostUpdatesPerSecond < this.nVideoUpdatesPerSecond) nMostUpdatesPerSecond = this.nVideoUpdatesPerSecond;\n if (nMostUpdatesPerSecond < this.nStatusUpdatesPerSecond) nMostUpdatesPerSecond = this.nStatusUpdatesPerSecond;\n\n /*\n * Calculate \"per\" values for the yield, video update, and status update cycle counters\n */\n var vMultiplier = 1;\n if (fRecalc && this.speed > this.SPEED_SLOW && this.mhz) vMultiplier = this.mhz;\n if (vMultiplier > this.mhzFast && this.speed < this.SPEED_MAX) vMultiplier = this.mhzFast;\n\n this.msPerYield = Math.round(1000/this.nYieldsPerSecond);\n this.nCyclesPerBurst = Math.floor(this.nCyclesPerSecond / nMostUpdatesPerSecond * vMultiplier);\n this.nCyclesPerYield = Math.floor(this.nCyclesPerSecond / this.nYieldsPerSecond * vMultiplier);\n this.nCyclesPerVideoUpdate = Math.floor(this.nCyclesPerSecond / this.nVideoUpdatesPerSecond * vMultiplier);\n this.nCyclesPerStatusUpdate = Math.floor(this.nCyclesPerSecond / this.nStatusUpdatesPerSecond * vMultiplier);\n\n /*\n * And initialize \"next\" yield, video update, and status update cycle \"threshold\" counters to those \"per\" values\n */\n if (!fRecalc) {\n this.nCyclesNextYield = this.nCyclesPerYield;\n this.nCyclesNextVideoUpdate = this.nCyclesPerVideoUpdate;\n this.nCyclesNextStatusUpdate = this.nCyclesPerStatusUpdate;\n }\n this.nRecalcCycles = 0;\n }\n\n /**\n * @this {C1PCPU}\n */\n calcStartTime()\n {\n if (this.nRecalcCycles >= this.nCyclesPerSecond) {\n this.calcCycles(true);\n }\n this.nCyclesThisRun = 0;\n this.msStartThisRun = Usr.getTime();\n }\n\n /**\n * @this {C1PCPU}\n * @return {number}\n */\n calcRemainingTime()\n {\n var msCurrent = Usr.getTime();\n var msYield = this.msPerYield;\n\n if (this.nCyclesThisRun) {\n /*\n * Normally, we would assume we executed a full quota of work over msPerYield, but since the CPU\n * now has the option of calling yieldCPU(), that might not be true. If nCyclesThisRun is correct, then\n * the ratio of nCyclesThisRun/nCyclesPerYield should represent the percentage of work we performed,\n * and so applying that percentage to msPerYield should give us a better estimate of work vs. time.\n */\n msYield = Math.round(msYield * this.nCyclesThisRun / this.nCyclesPerYield);\n // if (msYield < this.msPerYield) this.println(\"scaling msPerYield (\" + this.msPerYield + \") to msYield (\" + msYield + \")\");\n }\n\n var msElapsedThisRun = msCurrent - this.msStartThisRun;\n var msRemainsThisRun = msYield - msElapsedThisRun;\n\n /*\n * We could pass only \"this run\" results to calcSpeed():\n *\n * nCycles = this.nCyclesThisRun;\n * msElapsed = msElapsedThisRun;\n *\n * but it seems preferable to use longer time periods and hopefully get a more accurate speed.\n *\n * Also, if msRemainsThisRun >= 0 && this.speed == this.SPEED_SLOW, we could pass these results instead:\n *\n * nCycles = this.nCyclesThisRun;\n * msElapsed = this.msPerYield;\n *\n * to insure that we display a smooth, constant 1Mhz. But the displayed speed seems pretty steady as-is.\n */\n var nCycles = this.nRunCycles;\n var msElapsed = msCurrent - this.msRunStart;\n\n if (DEBUG && msRemainsThisRun < 0 && this.speed == this.SPEED_FAST) {\n this.println(\"warning: updates @\" + msElapsedThisRun + \"ms (prefer \" + Math.round(msYield) + \"ms)\");\n }\n\n this.calcSpeed(nCycles, msElapsed);\n\n if (msRemainsThisRun < 0) {\n /*\n * This is an easy case: it's taking more than 1 second to simulate 1Mhz,\n * so all we can do is yield for as little time as possible (ie, 0ms) and hope the\n * simulation is at least usable.\n */\n msRemainsThisRun = 0;\n }\n else {\n if (this.speed == this.SPEED_FAST) {\n /*\n * This case requires us to artificially limit the CPU speed. calcSpeed()\n * already cranks up the number of cycles we process per burst, in proportion\n * to the effective mhz, so there isn't much to do here except sleep for\n * whatever time is in msRemainsThisRun.\n *\n * The artificial limit was chosen largely because it's not currently possible\n * for the keyboard component to inject keys fast enough to avoid duplicate\n * keystrokes at higher speeds. Perhaps with future improvements to the keyboard\n * component, this limit can be lifted.\n */\n if (this.mhz <= this.mhzFast)\n msRemainsThisRun = 0;\n }\n else\n if (this.speed == this.SPEED_MAX) {\n /*\n * This is also an easy case: yield for as little time as possible (ie, 0ms), to execute\n * the maximum number of cycles per second.\n */\n msRemainsThisRun = 0;\n }\n }\n\n /*\n * Last but not least, update nRecalcCycles, so that when run() starts up again and calls calcStartTime(),\n * it'll be ready to decide if calcCycles() should be called again.\n */\n this.nRecalcCycles += this.nCyclesThisRun;\n\n return msRemainsThisRun;\n }\n\n /**\n * @this {C1PCPU}\n */\n run()\n {\n if (!this.setBusy(true)) {\n this.update();\n if (this.cmp) this.cmp.stop(this.msRunStart, this.nRunCycles);\n return;\n }\n if (!this.flags.running) {\n /*\n * setSpeed() without a speed parameter leaves the selected speed in place, but also resets the\n * cycle counter and timestamp for the current series of run() calls, calculates the maximum number\n * of cycles for each burst based on the last known effective CPU speed, and resets the nRecalcCycles\n * threshold counter.\n */\n this.setSpeed();\n if (this.cmp) this.cmp.start();\n this.flags.running = true;\n if (this.bindings[\"run\"]) this.bindings[\"run\"].innerHTML = \"Halt\";\n this.setFocus();\n }\n /*\n * calcStartTime() initializes the cycle counter and timestamp for this run() invocation, and optionally\n * recalculates the the maximum number of cycles for each burst if the nRecalcCycles threshold has been reached.\n */\n this.calcStartTime();\n try {\n do {\n /*\n * NOTE: nCyclesPerBurst is how many cycles we WANT to run each iteration of step(), but that just\n * initializes nBurstCycles, which (after subtracting any remaining nStepCycles) is how many cycles\n * we ACTUALLY ran.\n */\n this.step(this.nCyclesPerBurst);\n /*\n * nCyclesThisRun is increased by nBurstCycles, plus any additional cycles step() processed after\n * its cycle count had reached zero (and conversely, minus any cycles that it still had yet to process);\n * ditto for nRunCycles, which is the cycle count since the CPU first started running.\n */\n var nCycles = this.nBurstCycles - this.nStepCycles;\n this.nRunCycles += nCycles;\n this.nCyclesThisRun += nCycles;\n /*\n * These step() cycle variables must be zeroed now, so that getCycles() always returns a valid cycle count.\n */\n this.nBurstCycles = this.nStepCycles = 0;\n\n this.nCyclesNextVideoUpdate -= this.nCyclesPerBurst;\n if (this.nCyclesNextVideoUpdate <= 0) {\n this.nCyclesNextVideoUpdate += this.nCyclesPerVideoUpdate;\n this.displayVideo();\n }\n\n this.nCyclesNextStatusUpdate -= this.nCyclesPerBurst;\n if (this.nCyclesNextStatusUpdate <= 0) {\n this.nCyclesNextStatusUpdate += this.nCyclesPerStatusUpdate;\n this.displayStatus();\n }\n\n this.nCyclesNextYield -= this.nCyclesPerBurst;\n if (this.nCyclesNextYield <= 0) {\n this.nCyclesNextYield += this.nCyclesPerYield;\n break;\n }\n } while (this.flags.running);\n }\n catch (e) {\n this.halt();\n this.update();\n this.setBusy(false);\n this.setError(e.stack || e.message);\n return;\n }\n setTimeout(function(cpu) { return function() {cpu.run();}; }(this), this.calcRemainingTime());\n }\n\n /**\n * @this {C1PCPU}\n * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored)\n * @return {boolean|undefined} undefined indicates that the last instruction was not executed (eg,\n * we hit an execution breakpoint), false implies a post-execution condition was triggered (eg, a write\n * breakpoint), and true indicates successful completion of all requested cycles.\n */\n step(nMinCycles)\n {\n /*\n * The Debugger uses fCompleted to determine if the instruction completed (true) or was interrupted\n * by a breakpoint or some other exceptional condition (false). NOTE: this does NOT include thrown\n * exceptions, which step() expects the caller to catch using its own exception handler.\n *\n * The CPU relies on the use of halt() rather than fCompleted, because the CPU never single-steps\n * (ie, nMinCycles is always some large number), whereas the Debugger does. And conversely, when the\n * Debugger is single-stepping (even when performing multiple single-steps), fRunning is never set,\n * so halt() would have no effect as far as the Debugger is concerned.\n */\n var fCompleted = true;\n\n /*\n * fDebugCheck is true if we need to \"check\" every instruction with the Debugger. The Debugger will\n * call cpu.step(n) with n == 0 if it's executing only ONE instruction (ie, the user just clicked the\n * \"Step\" button, or they've issued a \"t\" or \"t1\" command). Otherwise, it will call with n == 1\n * (ie, the user is holding the \"Step\" button, or they've issued a \"t#\" command where # > 1).\n *\n * In the first case, we want to ignore (ie, \"step over\") any breakpoints; otherwise, the Debugger has\n * no easy way of moving past a breakpoint (other than clearing it, of course). In the second case,\n * we want to honor any breakpoints, which in turn will set fCompleted to false and signal the Debugger\n * to stop.\n *\n * Note that as a practical matter, both 0 and 1 are otherwise treated the same when it comes to the\n * minimum number of cycles to run: one and only one instruction will execute, since every instruction\n * consumes at least 1 cycle.\n */\n this.regEA = this.regEAWrite = -1;\n var fDebugCheck = (DEBUGGER && nMinCycles && this.dbg && this.dbg.checksEnabled());\n\n /*\n * We move the minimum cycle count to nStepCycles (the number of cycles left to run), so that other\n * methods have the ability to force that number to zero (eg, halt()), and thus we don't have to check\n * some other criteria just to determine whether we should continue running or not.\n */\n this.nBurstCycles = this.nStepCycles = nMinCycles;\n do {\n var bOpCode = this.abMem[this.regPC];\n\n if (fDebugCheck && !this.dbg.checkInstruction(this.regPC, bOpCode)) {\n fCompleted = undefined;\n this.halt();\n break;\n }\n\n this.regPC++;\n this.aOpcodeFuncs[bOpCode].call(this);\n\n /*\n * Assert that all register contents remain within their respective ranges.\n */\n\n\n /*\n * WARNING: By making the following read-or-write test exclusive, we're not going to catch\n * those situations where an instruction does BOTH. For example, JSR pushes the old PC\n * (which, if we were tracking STACK writes, would set regEAWrite) and then fetches a new PC\n * (which should set regEA). However, that's a situation which, except for a peculiar\n * combination of read and write breakpoints set by the Debugger, is one we simply don't care\n * about. Moreover, none of our opcode handlers currently set BOTH regEA and regEAWrite,\n * so it would be completely pointless to check both conditions here.\n *\n * Since READS are FAR more common than WRITES, we check the common case first. If the\n * day comes that we implement opcode functions that set both regEA AND regEAWrite, then we'll\n * want to remove the \"else\" below and stop making the read and write tests exclusive.\n * If we don't, then some of those rare/unusual writes will either get missed or delayed.\n *\n * It's also worth mentioning here that not all instructions READ or WRITE (eg, INX, INY and\n * others that are completely flag or register-bound). It's a bit ironic that those instructions,\n * which are typically the fastest, have to perform both the READ and WRITE tests below. But\n * on the plus side, both tests will fail, so they'll still get out of here faster than any of\n * the other instructions.\n */\n if (this.regEA >= 0) {\n /*\n * Serial emulation requires a read notification handler, and the keyboard may eventually\n * want one, too.\n */\n if (this.regEA >= this.addrReadLower && this.regEA <= this.addrReadUpper) {\n this.checkReadNotify(this.regEA, this.regPC);\n }\n if (fDebugCheck && !this.dbg.checkMemoryRead(this.regEA)) {\n fCompleted = false;\n this.halt();\n break;\n }\n this.regEA = -1;\n }\n else if (this.regEAWrite >= 0) {\n /*\n * We process the write notification handlers before the write breakpoint handlers,\n * because we don't want to leave any ROM (read-only memory) writes in place before we\n * (potentially) give up control. Undoing every write to ROM address space is an essential\n * part of simulating the \"read-only\" behavior of ROM.\n *\n * Obviously, there are other write notification handlers as well (like the keyboard's),\n * which may sometimes do things we'd prefer to intercept first, but let's keep things simple.\n */\n if (this.regEAWrite >= this.addrWriteLower && this.regEAWrite <= this.addrWriteUpper) {\n this.checkWriteNotify(this.regEAWrite, this.regPC);\n }\n if (fDebugCheck && !this.dbg.checkMemoryWrite(this.regEAWrite, this.abMem[this.regEAWrite])) {\n fCompleted = false;\n this.halt();\n break;\n }\n this.regEAWrite = -1;\n }\n\n this.nStepCycles -= this.aOpcodeCycles[bOpCode];\n\n } while (this.nStepCycles > 0);\n\n return fCompleted;\n }\n\n /**\n * yieldCPU() is similar to halt() with regard to how it resets various cycle countdown values,\n * but the CPU remains in a \"running\" state.\n *\n * @this {C1PCPU}\n */\n yieldCPU()\n {\n this.nCyclesNextYield = 0; // this will break us out of run(), once we break out of step()\n this.nBurstCycles -= this.nStepCycles;\n this.nStepCycles = 0; // this will break us out of step()\n }\n\n /**\n * halt() is similar to yieldCPU(), but it doesn't need to zero nCyclesNextYield to break out of run();\n * it simply needs to clear fRunning.\n *\n * @this {C1PCPU}\n */\n halt()\n {\n this.isBusy(true);\n this.nBurstCycles -= this.nStepCycles;\n this.nStepCycles = 0;\n if (this.flags.running) {\n this.flags.running = false;\n if (this.bindings[\"run\"]) this.bindings[\"run\"].innerHTML = \"Run\";\n }\n }\n\n /**\n * @this {C1PCPU}\n *\n * This used to be performed at the end of every step(), but run() -- which relies upon step() -- needed to have\n * more control over when these updates are performed. However, for other callers of step(), such as the Debugger,\n * the combination of step() + update() provides the old behavior.\n */\n update()\n {\n this.displayVideo();\n this.displayStatus();\n }\n\n /**\n * getCycles() returns the number of cycles executed so far. Note that we can be called after\n * a run() OR during a run(), perhaps from a handler triggered during the current run's step(),\n * so nRunCycles must always be adjusted by number of cycles step() was asked to run (nBurstCycles),\n * less the number of cycles it has yet to run (nStepCycles).\n *\n * nRunCycles is reset whenever the CPU is halted or the CPU speed is changed, so returning 0 when the\n * CPU is stopped seems perfectly reasonable. As a result, components that rely on getCycles() returning a\n * steadily increasing number should also be prepared for a reset at any time (eg, the Keyboard's\n * updateMemory() function).\n *\n * @this {C1PCPU}\n * @return {number}\n */\n getCycles()\n {\n return (this.flags.running? this.nRunCycles + this.nBurstCycles - this.nStepCycles : 0);\n }\n\n /**\n * @this {C1PCPU}\n * @param {number} addr\n * @return {number}\n *\n * Unlike the Debugger versions of these functions, these presume that addr is always valid,\n * since it's internally generated, not user-supplied. Of course, we could still have internal\n * bugs, so asserts are included, but they are present in DEBUG code only (automatically\n * removed from RELEASE code).\n *\n * Moreover, it's unlikely we'll use this function much (unless performance becomes secondary\n * to code size), since all the opCode functions should perform their own fetches, for obvious\n * performance reasons.\n */\n getByte(addr)\n {\n\n var b = this.abMem[addr];\n\n return b;\n }\n\n /**\n * @this {C1PCPU}\n * @param {number} addr\n * @return {number}\n */\n getWord(addr)\n {\n\n var w = this.abMem[addr] | (this.abMem[addr+1] << 8);\n\n return w;\n }\n\n /**\n * @this {C1PCPU}\n * @param {number} addr\n * @param {number} b\n */\n setByte(addr, b)\n {\n\n\n this.abMem[addr] = b;\n }\n\n /**\n * @this {C1PCPU}\n * @return {number}\n */\n getRegP()\n {\n /*\n * // C = LAZY_C;\n * this.regP = ((this.regP & 0xfe) | ((((this.regRC & 0x0100)))? 0x01 : 0));\n * // Z = LAZY_Z;\n * this.regP = ((this.regP & 0xfd) | ((((this.regRZ & 0xff) == 0))? 0x02 : 0));\n * // V = LAZY_V;\n * this.regP = ((this.regP & 0xbf) | (((((((this.regRV & 0xff) ^ this.regRU) ^ (this.regRV >> 1)) & 0x80) != 0))? 0x40 : 0));\n * // N = LAZY_N;\n * this.regP = ((this.regP & 0x7f) | ((((this.regRN & 0x80)))? 0x80 : 0));\n */\n var regP = ((this.regRC & 0x0100)? 0x01 : 0x00);\n regP |= (!(this.regRZ & 0xff)? 0x02 : 0x00);\n regP |= (((((this.regRV & 0xff) ^ this.regRU) ^ (this.regRV >> 1)) & 0x80)? 0x40 : 0x00);\n regP |= ((this.regRN & 0x80)? 0x80 : 0x00);\n return (this.regP & 0x3C) | regP;\n }\n\n /**\n * @this {C1PCPU}\n *\n * Clear the C flag\n */\n clearC()\n {\n this.regRC = 0x00;\n }\n\n /**\n * @this {C1PCPU}\n *\n * Set the C flag\n */\n setC()\n {\n this.regRC = 0x100;\n }\n\n /**\n * @this {C1PCPU}\n *\n * Clear the N bit\n */\n clearN()\n {\n this.regRN = 0x00;\n }\n\n /**\n * @this {C1PCPU}\n *\n * Set the N bit\n */\n setN()\n {\n this.regRN = 0x80;\n }\n\n /**\n * @this {C1PCPU}\n *\n * Clear the V bit\n */\n clearV()\n {\n this.regRV = 0x00; this.regRU = 0x00;\n }\n\n /**\n * @this {C1PCPU}\n *\n * Set the V bit\n */\n setV()\n {\n this.regRV = 0x00; this.regRU = 0x80;\n }\n\n /**\n * @this {C1PCPU}\n *\n * Clear the Z bit\n */\n clearZ()\n {\n this.regRZ = 0x01;\n }\n\n /**\n * @this {C1PCPU}\n *\n * Set the Z bit\n */\n setZ()\n {\n this.regRZ = 0x00;\n }\n\n /**\n * @this {C1PCPU}\n *\n * Set the BCD bit and install the BCD opcode handlers\n */\n setBCD()\n {\n this.regP |= 0x08;\n this.aOpcodeFuncs[0x61] = this.opADCindxBCD;\n this.aOpcodeFuncs[0x65] = this.opADCzpBCD;\n this.aOpcodeFuncs[0x69] = this.opADCimmBCD;\n this.aOpcodeFuncs[0x6d] = this.opADCabsBCD;\n this.aOpcodeFuncs[0x71] = this.opADCindyBCD;\n this.aOpcodeFuncs[0x75] = this.opADCzpxBCD;\n this.aOpcodeFuncs[0x79] = this.opADCabsyBCD;\n this.aOpcodeFuncs[0x7d] = this.opADCabsxBCD;\n this.aOpcodeFuncs[0xe1] = this.opSBCindxBCD;\n this.aOpcodeFuncs[0xe5] = this.opSBCzpBCD;\n this.aOpcodeFuncs[0xe9] = this.opSBCimmBCD;\n this.aOpcodeFuncs[0xed] = this.opSBCabsBCD;\n this.aOpcodeFuncs[0xf1] = this.opSBCindyBCD;\n this.aOpcodeFuncs[0xf5] = this.opSBCzpxBCD;\n this.aOpcodeFuncs[0xf9] = this.opSBCabsyBCD;\n this.aOpcodeFuncs[0xfd] = this.opSBCabsxBCD;\n }\n\n /**\n * @this {C1PCPU}\n *\n * Clear the BCD bit and remove the BCD opcode handlers\n */\n clearBCD()\n {\n this.regP &= ~0x08;\n this.aOpcodeFuncs[0x61] = this.opADCindx;\n this.aOpcodeFuncs[0x65] = this.opADCzp;\n this.aOpcodeFuncs[0x69] = this.opADCimm;\n this.aOpcodeFuncs[0x6d] = this.opADCabs;\n this.aOpcodeFuncs[0x71] = this.opADCindy;\n this.aOpcodeFuncs[0x75] = this.opADCzpx;\n this.aOpcodeFuncs[0x79] = this.opADCabsy;\n this.aOpcodeFuncs[0x7d] = this.opADCabsx;\n this.aOpcodeFuncs[0xe1] = this.opSBCindx;\n this.aOpcodeFuncs[0xe5] = this.opSBCzp;\n this.aOpcodeFuncs[0xe9] = this.opSBCimm;\n this.aOpcodeFuncs[0xed] = this.opSBCabs;\n this.aOpcodeFuncs[0xf1] = this.opSBCindy;\n this.aOpcodeFuncs[0xf5] = this.opSBCzpx;\n this.aOpcodeFuncs[0xf9] = this.opSBCabsy;\n this.aOpcodeFuncs[0xfd] = this.opSBCabsx;\n }\n\n /**\n * @this {C1PCPU}\n * @param {number} reg\n * @param {number} mem\n * @return {number}\n *\n * Refer to http://www.6502.org/tutorials/decimal_mode.html for 6502-specific details.\n * Refer to http://homepage.cs.uiowa.edu/~jones/bcd/bcd.html for optimization tips.\n */\n addBCD(reg, mem)\n {\n var carry = ((this.regRC & 0x0100)? 1 : 0);\n\n /*\n * First add the low nibbles.\n */\n var r = (reg & 0x0f) + (mem & 0x0f) + carry;\n\n /*\n * Adjust the result. NOTE: The extra AND'ing and ADD'ing isn't necessary if we want to\n * assume that ONLY valid BCD digits will be added, but we probably shouldn't assume that.\n * NOTE: We use an OR instead of an ADD at the end because it's logically equivalent and faster.\n */\n if (r >= 0x0A) r = ((r + 0x06) & 0x0f) | 0x10;\n\n /*\n * Now add the high nibbles.\n */\n r += (reg & 0xf0) + (mem & 0xf0);\n\n /*\n * Before we do the next adjust, it seems that N and V are dependent on this intermediate\n * result (however, the meaning of N and V in BCD mode is not well documented).\n */\n this.regRU = reg ^ mem; this.regRV = r;\n this.regRN = (r & 0xff);\n\n /*\n * Final adjustment.\n */\n if (r >= 0xA0) r += 0x60;\n /*\n * NOTE: If the intermediate result was 0x1A0 or more, then adding 0x60 would yield a result\n * of 0x200 or more, but because the rest of the simulator tests regRC for 0x100, rather than\n * comparing regRC for values >= 0x100, we'll miss the fact that there was a carry, unless we\n * scale any value in the 0x200-0x2ff range down to 0x100-0x1ff. We then assert that the\n * resulting value is within the proper range.\n */\n if (r >= 0x200) r -= 0x100;\n\n\n /*\n * In BCD mode, the C flag reflects the decimal result, but the Z flag reflects binary addition.\n */\n this.regRC = r;\n this.regRZ = ((reg + mem + carry) & 0xff);\n\n /*\n * Account for an extra cycle in BCD mode as well.\n */\n this.nStepCycles--;\n\n return r & 0xff;\n }\n\n /**\n * @this {C1PCPU}\n * @param {number} reg\n * @param {number} mem\n * @return {number}\n *\n * Refer to http://www.6502.org/tutorials/decimal_mode.html for 6502-specific details.\n * Refer to http://homepage.cs.uiowa.edu/~jones/bcd/bcd.html for optimization tips.\n */\n subBCD(reg, mem)\n {\n var notcarry = ((this.regRC & 0x0100)? 0 : 1);\n\n /*\n * First subtract the low nibbles.\n */\n var r = (reg & 0x0f) - (mem & 0x0f) - notcarry;\n\n /*\n * Adjust the result. NOTE: The extra AND'ing and SUB'ing isn't necessary if we want to\n * assume that ONLY valid BCD digits will be added, but we probably shouldn't assume that.\n */\n if (r < 0x00) r = ((r - 0x06) & 0x0f) - 0x10;\n\n /*\n * Now subtract the high nibbles.\n */\n r += (reg & 0xf0) - (mem & 0xf0);\n\n /*\n * Final adjustment.\n */\n if (r < 0x00) r -= 0x60;\n\n /*\n * In BCD mode, the Z -- and C, N and V -- flags are all set as if binary subtraction was performed.\n */\n // RC = (A - ML - !LAZY_C); SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = (this.regRC = (reg - mem - notcarry)) & 0xff;\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = reg ^ mem; this.regRV = this.regRC;\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n\n /*\n * Account for an extra cycle in BCD mode as well.\n */\n this.nStepCycles--;\n\n return r & 0xff;\n }\n\n /**\n * @this {C1PCPU}\n */\n clearRegs()\n {\n this.regA = 0;\n this.regX = 0;\n this.regY = 0;\n this.regS = 0x100;\n this.regP = 0;\n this.regRN = 0;\n this.regRZ = 0;\n this.regRU = 0;\n this.regRV = 0;\n this.regRC = 0;\n this.regPC = 0;\n this.regEA = -1;\n this.regEAWrite = -1;\n this.mhz = 0;\n this.nRunCycles = this.nBurstCycles = this.nStepCycles = 0;\n }\n\n /**\n * @this {C1PCPU}\n */\n opBRK()\n { // opcode 0x00\n // PC++;\n this.regPC++;\n // STACK(S--) = PCH;\n this.abMem[this.regS--] = (this.regPC >> 8);\n this.regS |= 0x100;\n // STACK(S--) = PCL;\n this.abMem[this.regS--] = (this.regPC & 0xff);\n this.regS |= 0x100;\n // B = 1;\n this.regP |= 0x10;\n // C = LAZY_C; Z = LAZY_Z; V = LAZY_V; N = LAZY_N;\n this.regP = this.getRegP();\n // STACK(S--) = P;\n this.abMem[this.regS--] = this.regP;\n this.regS |= 0x100;\n // B = 0;\n this.regP &= 0xef;\n // EA = 0xFFFE;\n this.regEA = 0xFFFE;\n // PC = M;\n this.regPC = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n }\n\n /**\n * @this {C1PCPU}\n */\n opORAindx()\n { // opcode 0x01\n // EA = WORD((BYTE(PC++)+X) & 0xff);\n this.regEA = ((this.abMem[this.regPC++]) + this.regX) & 0xff;\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n // A = A | ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA |= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opORAzp()\n { // opcode 0x05\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // A = A | ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA |= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opASLzp()\n { // opcode 0x06\n // EA = BYTE(PC++);\n this.regEAWrite = this.abMem[this.regPC++];\n // RC = ML << 1;\n this.regRC = this.abMem[this.regEAWrite] << 1;\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opPHP()\n { // opcode 0x08\n this.regP = this.getRegP();\n // STACK(S--) = P;\n this.abMem[this.regS--] = this.regP;\n this.regS |= 0x100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opORAimm()\n { // opcode 0x09\n // EA = PC++;\n this.regEA = this.regPC++;\n // A = A | ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA |= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opASLacc()\n { // opcode 0x0a\n // RC = A << 1;\n this.regRC = this.regA << 1;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opORAabs()\n { // opcode 0x0d\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // A = A | ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA |= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opASLabs()\n { // opcode 0x0e\n // EA = WORD(PC); PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // RC = ML << 1;\n this.regRC = this.abMem[this.regEAWrite] << 1;\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opBPL()\n { // opcode 0x10\n // PC = PC + (LAZY_N == 0? SBYTE(PC) : 0) + 1;\n this.regPC += (!(this.regRN & 0x80)? (this.nStepCycles--,((this.abMem[this.regPC] << 24) >> 24)) : 0) + 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opORAindy()\n { // opcode 0x11\n // EA = WORD(BYTE(PC++))+Y;\n this.regEA = (this.abMem[this.regPC++]);\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8)) + this.regY;\n // A = A | ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA |= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opORAzpx()\n { // opcode 0x15\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // A = A | ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA |= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opASLzpx()\n { // opcode 0x16\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEAWrite = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // RC = ML << 1;\n this.regRC = this.abMem[this.regEAWrite] << 1;\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opCLC()\n { // opcode 0x18\n // SET_LAZY_C(0);\n this.regRC = 0x00;\n }\n\n /**\n * @this {C1PCPU}\n */\n opORAabsy()\n { // opcode 0x19\n // EA = WORD(PC)+Y; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // A = A | ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regA |= this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opORAabsx()\n { // opcode 0x1d\n // EA = WORD(PC)+X; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // A = A | ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regA |= this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opASLabsx()\n { // opcode 0x1e\n // EA = WORD(PC)+X; PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // RC = ML << 1;\n this.regRC = this.abMem[this.regEAWrite] << 1;\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opJSRabs()\n { // opcode 0x20\n // EA = PC; PC += 1;\n this.regEA = this.regPC++;\n // STACK(S--) = PCH;\n this.abMem[this.regS--] = (this.regPC >> 8);\n this.regS |= 0x100;\n // STACK(S--) = PCL;\n this.abMem[this.regS--] = (this.regPC & 0xff);\n this.regS |= 0x100;\n // PC = M;\n this.regPC = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n }\n\n /**\n * @this {C1PCPU}\n */\n opANDindx()\n { // opcode 0x21\n // EA = WORD((BYTE(PC++)+X) & 0xff);\n this.regEA = ((this.abMem[this.regPC++]) + this.regX) & 0xff;\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n // A = A & ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA &= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opBITzp()\n { // opcode 0x24\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // SET_LAZY_Z((A & ML) == 0);\n this.regRZ = (this.regA & this.abMem[this.regEA]);\n // SET_LAZY_N(ML7);\n this.regRN = ((this.regRN & 0x7f) | (this.abMem[this.regEA] & 0x80));\n // SET_LAZY_V(ML6);\n this.regRV = 0; this.regRU = ((this.abMem[this.regEA] & 0x40)? 0x80 : 0x00);\n }\n\n /**\n * @this {C1PCPU}\n */\n opANDzp()\n { // opcode 0x25\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // A = A & ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA &= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opROLzp()\n { // opcode 0x26\n // EA = BYTE(PC++);\n this.regEAWrite = this.abMem[this.regPC++];\n // RCL = ML;\n this.regRC = ((this.regRC & 0xff00) | this.abMem[this.regEAWrite]);\n // RC = RC << 1;\n this.regRC <<= 1;\n // RCL0 = RCH1;\n this.regRC = ((this.regRC & 0xfffe) | (((this.regRC & 0x0200))? 0x0001 : 0));\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opPLP()\n { // opcode 0x28\n // P = STACK(++S);\n this.regS = ((this.regS+1) & 0xff) | 0x100;\n this.regP = this.abMem[this.regS];\n // SET_LAZY_C(C);\n this.regRC = ((this.regP & 0x01)? 0x0100 : 0);\n // SET_LAZY_Z(Z);\n this.regRZ = (!(this.regP & 0x02)? 0x01 : 0);\n // SET_LAZY_N(N);\n this.regRN = (this.regP & 0x80);\n // SET_LAZY_V(V);\n this.regRV = 0; this.regRU = ((this.regP & 0x40)? 0x80 : 0x00);\n }\n\n /**\n * @this {C1PCPU}\n */\n opANDimm()\n { // opcode 0x29\n // EA = PC++;\n this.regEA = this.regPC++;\n // A = A & ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA &= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opROLacc()\n { // opcode 0x2a\n // RCL = A;\n this.regRC = ((this.regRC & 0xff00) | this.regA);\n // RC = RC << 1;\n this.regRC <<= 1;\n // RCL0 = RCH1;\n this.regRC = ((this.regRC & 0xfffe) | ((this.regRC & 0x0200)? 0x0001 : 0));\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opBITabs()\n { // opcode 0x2c\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // SET_LAZY_Z((A & ML) == 0);\n this.regRZ = (this.regA & this.abMem[this.regEA]);\n // SET_LAZY_N(ML7);\n this.regRN = ((this.regRN & 0x7f) | (this.abMem[this.regEA] & 0x80));\n // SET_LAZY_V(ML6);\n this.regRV = 0; this.regRU = ((this.abMem[this.regEA] & 0x40)? 0x80 : 0x00);\n }\n\n /**\n * @this {C1PCPU}\n */\n opANDabs()\n { // opcode 0x2d\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // A = A & ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA &= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opROLabs()\n { // opcode 0x2e\n // EA = WORD(PC); PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // RCL = ML;\n this.regRC = ((this.regRC & 0xff00) | this.abMem[this.regEAWrite]);\n // RC = RC << 1;\n this.regRC <<= 1;\n // RCL0 = RCH1;\n this.regRC = ((this.regRC & 0xfffe) | (((this.regRC & 0x0200))? 0x0001 : 0));\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opBMI()\n { // opcode 0x30\n // PC = PC + (LAZY_N != 0? SBYTE(PC) : 0) + 1;\n this.regPC += ((this.regRN & 0x80)? (this.nStepCycles--,((this.abMem[this.regPC] << 24) >> 24)) : 0) + 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opANDindy()\n { // opcode 0x31\n // EA = WORD(BYTE(PC++))+Y;\n this.regEA = (this.abMem[this.regPC++]);\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8)) + this.regY;\n // A = A & ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA &= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opANDzpx()\n { // opcode 0x35\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // A = A & ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA &= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opROLzpx()\n { // opcode 0x36\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEAWrite = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // RCL = ML;\n this.regRC = ((this.regRC & 0xff00) | this.abMem[this.regEAWrite]);\n // RC = RC << 1;\n this.regRC <<= 1;\n // RCL0 = RCH1;\n this.regRC = ((this.regRC & 0xfffe) | (((this.regRC & 0x0200))? 0x0001 : 0));\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opSEC()\n { // opcode 0x38\n // SET_LAZY_C(1);\n this.regRC = 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opANDabsy()\n { // opcode 0x39\n // EA = WORD(PC)+Y; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // A = A & ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA &= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opANDabsx()\n { // opcode 0x3d\n // EA = WORD(PC)+X; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // A = A & ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA &= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opROLabsx()\n { // opcode 0x3e\n // EA = WORD(PC)+X; PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // RCL = ML;\n this.regRC = ((this.regRC & 0xff00) | this.abMem[this.regEAWrite]);\n // RC = RC << 1;\n this.regRC <<= 1;\n // RCL0 = RCH1;\n this.regRC = ((this.regRC & 0xfffe) | (((this.regRC & 0x0200))? 0x0001 : 0));\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opRTI()\n { // opcode 0x40\n // P = STACK(++S);\n this.regS = ((this.regS+1) & 0xff) | 0x100;\n this.regP = this.abMem[this.regS];\n // SET_LAZY_C(C);\n this.regRC = ((this.regP & 0x01)? 0x0100 : 0);\n // SET_LAZY_Z(Z);\n this.regRZ = (!(this.regP & 0x02)? 0x01 : 0);\n // SET_LAZY_N(N);\n this.regRN = (this.regP & 0x80);\n // SET_LAZY_V(V);\n this.regRV = 0; this.regRU = ((this.regP & 0x40)? 0x80 : 0x00);\n // PCL = STACK(++S);\n // PCH = STACK(++S);\n this.regS = ((this.regS+2) & 0xff) | 0x100;\n this.regPC = (this.abMem[(this.regS-1) | 0x100]) | (this.abMem[this.regS] << 8);\n }\n\n /**\n * @this {C1PCPU}\n */\n opEORindx()\n { // opcode 0x41\n // EA = WORD((BYTE(PC++)+X) & 0xff);\n this.regEA = ((this.abMem[this.regPC++]) + this.regX) & 0xff;\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n // A = A ^ ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA ^= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opEORzp()\n { // opcode 0x45\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // A = A ^ ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA ^= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opLSRzp()\n { // opcode 0x46\n // EA = BYTE(PC++);\n this.regEAWrite = this.abMem[this.regPC++];\n // SET_LAZY_C(ML0);\n this.regRC = ((this.regRC & 0xfeff) | ((this.abMem[this.regEAWrite] & 0x01)? 0x0100 : 0));\n // ML = RCL = ML >> 1;\n this.abMem[this.regEAWrite] = ((this.regRC = ((this.regRC & 0xff00) | (this.abMem[this.regEAWrite] >> 1))) & 0xff);\n // SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = (this.regRC & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opPHA()\n { // opcode 0x48\n // STACK(S--) = A;\n this.abMem[this.regS--] = this.regA;\n this.regS |= 0x100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opEORimm()\n { // opcode 0x49\n // EA = PC++;\n this.regEA = this.regPC++;\n // A = A ^ ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA ^= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opLSRacc()\n { // opcode 0x4a\n // SET_LAZY_C( A0);\n this.regRC = ((this.regRC & 0xfeff) | ((this.regA & 0x01)? 0x0100 : 0));\n // A = RCL = A >> 1;\n this.regA = ((this.regRC = ((this.regRC & 0xff00) | (this.regA >> 1))) & 0xff);\n // SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opJMPimm16()\n { // opcode 0x4c\n // EA = PC;\n this.regEA = this.regPC;\n // PC += 2;\n // this.regPC += 2;\n // PC = M;\n this.regPC = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n }\n\n /**\n * @this {C1PCPU}\n */\n opEORabs()\n { // opcode 0x4d\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // A = A ^ ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA ^= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opLSRabs()\n { // opcode 0x4e\n // EA = WORD(PC); PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // SET_LAZY_C(ML0);\n this.regRC = ((this.regRC & 0xfeff) | ((this.abMem[this.regEAWrite] & 0x01)? 0x0100 : 0));\n // ML = RCL = ML >> 1;\n this.abMem[this.regEAWrite] = ((this.regRC = ((this.regRC & 0xff00) | (this.abMem[this.regEAWrite] >> 1))) & 0xff);\n // SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = (this.regRC & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opBVC()\n { // opcode 0x50\n // PC = PC + (LAZY_V == 0? SBYTE(PC) : 0) + 1;\n this.regPC += (!((((this.regRV & 0xff) ^ this.regRU) ^ (this.regRV >> 1)) & 0x80)? (this.nStepCycles--,((this.abMem[this.regPC] << 24) >> 24)) : 0) + 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opEORindy()\n { // opcode 0x51\n // EA = WORD(BYTE(PC++))+Y;\n this.regEA = this.abMem[this.regPC++];\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8)) + this.regY;\n // A = A ^ ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA ^= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opEORzpx()\n { // opcode 0x55\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // A = A ^ ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA ^= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opLSRzpx()\n { // opcode 0x56\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEAWrite = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // SET_LAZY_C(ML0);\n this.regRC = ((this.regRC & 0xfeff) | ((this.abMem[this.regEAWrite] & 0x01)? 0x0100 : 0));\n // ML = RCL = ML >> 1;\n this.abMem[this.regEAWrite] = ((this.regRC = ((this.regRC & 0xff00) | (this.abMem[this.regEAWrite] >> 1))) & 0xff);\n // SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = (this.regRC & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opCLI()\n { // opcode 0x58\n // I = 0;\n this.regP &= 0xfb;\n }\n\n /**\n * @this {C1PCPU}\n */\n opEORabsy()\n { // opcode 0x59\n // EA = WORD(PC)+Y; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // A = A ^ ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA ^= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opEORabsx()\n { // opcode 0x5d\n // EA = WORD(PC)+X; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // A = A ^ ML; SET_LAZY_NZ(A)\n this.regRN = this.regRZ = (this.regA ^= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opLSRabsx()\n { // opcode 0x5e\n // EA = WORD(PC)+X; PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // SET_LAZY_C(ML0);\n this.regRC = ((this.regRC & 0xfeff) | ((this.abMem[this.regEAWrite] & 0x01)? 0x0100 : 0));\n // ML = RCL = ML >> 1;\n this.abMem[this.regEAWrite] = ((this.regRC = ((this.regRC & 0xff00) | (this.abMem[this.regEAWrite] >> 1))) & 0xff);\n // SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = (this.regRC & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opRTS()\n { // opcode 0x60\n // PCL = STACK(++S);\n // PCH = STACK(++S);\n // PC++;\n this.regS = ((this.regS+2) & 0xff) | 0x100;\n this.regPC = (((this.abMem[(this.regS-1) | 0x100])) | ((this.abMem[this.regS]) << 8)) + 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCindx()\n { // opcode 0x61\n // EA = WORD((BYTE(PC++)+X) & 0xff);\n this.regEA = ((this.abMem[this.regPC++]) + this.regX) & 0xff;\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n // RC = (A + ML + LAZY_C);\n this.regRC = (this.regA + this.abMem[this.regEA] + ((this.regRC & 0x0100)? 1 : 0));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCindxBCD()\n { // opcode 0x61\n // EA = WORD((BYTE(PC++)+X) & 0xff);\n this.regEA = ((this.abMem[this.regPC++]) + this.regX) & 0xff;\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n // A = this.addBCD(A,ML);\n this.regA = this.addBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCzp()\n { // opcode 0x65\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // RC = (A + ML + LAZY_C);\n this.regRC = (this.regA + this.abMem[this.regEA] + ((this.regRC & 0x0100)? 1 : 0));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCzpBCD()\n { // opcode 0x65\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // A = this.addBCD(A,ML);\n this.regA = this.addBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opRORzp()\n { // opcode 0x66\n // EA = BYTE(PC++);\n this.regEAWrite = this.abMem[this.regPC++];\n // RCL = ML;\n this.regRC = ((this.regRC & 0xff00) | this.abMem[this.regEAWrite]);\n // RCH1 = RCL0;\n this.regRC = ((this.regRC & 0xfdff) | ((this.regRC & 0x0001)? 0x0200 : 0));\n // RC = RC >> 1;\n this.regRC >>= 1;\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opPLA()\n { // opcode 0x68\n // A = STACK(++S); SET_LAZY_NZ(A);\n this.regS = ((this.regS+1) & 0xff) | 0x100;\n this.regRN = this.regRZ = this.regA = this.abMem[this.regS];\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCimm()\n { // opcode 0x69\n // EA = PC++;\n this.regEA = this.regPC++;\n // RC = (A + ML + LAZY_C);\n this.regRC = (this.regA + this.abMem[this.regEA] + ((this.regRC & 0x0100)? 1 : 0));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCimmBCD()\n { // opcode 0x69\n // EA = PC++;\n this.regEA = this.regPC++;\n // A = this.addBCD(A,ML);\n this.regA = this.addBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opRORacc()\n { // opcode 0x6a\n // RCL = A;\n this.regRC = ((this.regRC & 0xff00) | this.regA);\n // RCH1 = RCL0;\n this.regRC = ((this.regRC & 0xfdff) | ((this.regRC & 0x0001)? 0x0200 : 0));\n // RC = RC >> 1;\n this.regRC >>= 1;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n *\n * NOTE from Wikipedia: \"The 6502's memory indirect jump instruction, JMP (<address>), is partially broken.\n * If <address> is hex xxFF (i.e., any word ending in FF), the processor will not jump to the address stored in xxFF and xxFF+1 as expected,\n * but rather the one defined by xxFF and xx00. This defect continued through the entire NMOS line, but was corrected in the CMOS derivatives.\"\n */\n opJMPabs16()\n { // opcode 0x6c\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // PC = M;\n this.regPC = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCabs()\n { // opcode 0x6d\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // RC = (A + ML + LAZY_C);\n this.regRC =(this.regA + this.abMem[this.regEA] + ((this.regRC & 0x0100)? 1 : 0));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCabsBCD()\n { // opcode 0x6d\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // A = this.addBCD(A,ML);\n this.regA = this.addBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opRORabs()\n { // opcode 0x6e\n // EA = WORD(PC); PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // RCL = ML;\n this.regRC = ((this.regRC & 0xff00) | this.abMem[this.regEAWrite]);\n // RCH1 = RCL0;\n this.regRC = ((this.regRC & 0xfdff) | ((this.regRC & 0x0001)? 0x0200 : 0));\n // RC = RC >> 1;\n this.regRC >>= 1;\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opBVS()\n { // opcode 0x70\n // PC = PC + (LAZY_V != 0? SBYTE(PC) : 0) + 1;\n this.regPC += (((((this.regRV & 0xff) ^ this.regRU) ^ (this.regRV >> 1)) & 0x80)? (this.nStepCycles--,((this.abMem[this.regPC] << 24) >> 24)) : 0) + 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCindy()\n { // opcode 0x71\n // EA = WORD(BYTE(PC++))+Y;\n this.regEA = (this.abMem[this.regPC++]);\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8)) + this.regY;\n // RC = (A + ML + LAZY_C);\n this.regRC = (this.regA + this.abMem[this.regEA] + ((this.regRC & 0x0100)? 1 : 0));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCindyBCD()\n { // opcode 0x71\n // EA = WORD(BYTE(PC++))+Y;\n this.regEA = (this.abMem[this.regPC++]);\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8)) + this.regY;\n // A = this.addBCD(A,ML);\n this.regA = this.addBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCzpx()\n { // opcode 0x75\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // RC = (A + ML + LAZY_C);\n this.regRC = (this.regA + this.abMem[this.regEA] + ((this.regRC & 0x0100)? 1 : 0));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCzpxBCD()\n { // opcode 0x75\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // A = this.addBCD(A,ML);\n this.regA = this.addBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opRORzpx()\n { // opcode 0x76\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEAWrite = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // RCL = ML;\n this.regRC = ((this.regRC & 0xff00) | this.abMem[this.regEAWrite]);\n // RCH1 = RCL0;\n this.regRC = ((this.regRC & 0xfdff) | ((this.regRC & 0x0001)? 0x0200 : 0));\n // RC = RC >> 1;\n this.regRC >>= 1;\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opSEI()\n { // opcode 0x78\n // I = 1;\n this.regP |= 0x04;\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCabsy()\n { // opcode 0x79\n // EA = WORD(PC)+Y; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // RC = (A + ML + LAZY_C);\n this.regRC = (this.regA + this.abMem[this.regEA] + ((this.regRC & 0x0100)? 1 : 0));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCabsyBCD()\n { // opcode 0x79\n // EA = WORD(PC)+Y; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // A = this.addBCD(A,ML);\n this.regA = this.addBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCabsx()\n { // opcode 0x7d\n // EA = WORD(PC)+X; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // RC = (A + ML + LAZY_C);\n this.regRC = (this.regA + this.abMem[this.regEA] + ((this.regRC & 0x0100)? 1 : 0));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCabsxBCD()\n { // opcode 0x7d\n // EA = WORD(PC)+X; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // A = this.addBCD(A,ML);\n this.regA = this.addBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opRORabsx()\n { // opcode 0x7e\n // EA = WORD(PC)+X; PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // RCL = ML;\n this.regRC = ((this.regRC & 0xff00) | this.abMem[this.regEAWrite]);\n // RCH1 = RCL0;\n this.regRC = ((this.regRC & 0xfdff) | ((this.regRC & 0x0001)? 0x0200 : 0));\n // RC = RC >> 1;\n this.regRC >>= 1;\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTAindx()\n { // opcode 0x81\n // EA = WORD((BYTE(PC++)+X) & 0xff);\n this.regEAWrite = ((this.abMem[this.regPC++]) + this.regX) & 0xff;\n this.regEAWrite = (this.abMem[this.regEAWrite] | (this.abMem[this.regEAWrite+1] << 8));\n // ML = A;\n this.abMem[this.regEAWrite] = this.regA;\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTYzp()\n { // opcode 0x84\n // EA = BYTE(PC++);\n this.regEAWrite = this.abMem[this.regPC++];\n // ML = Y;\n this.abMem[this.regEAWrite] = this.regY;\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTAzp()\n { // opcode 0x85\n // EA = BYTE(PC++);\n this.regEAWrite = this.abMem[this.regPC++];\n // ML = A;\n this.abMem[this.regEAWrite] = this.regA;\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTXzp()\n { // opcode 0x86\n // EA = BYTE(PC++);\n this.regEAWrite = this.abMem[this.regPC++];\n // ML = X;\n this.abMem[this.regEAWrite] = this.regX;\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opDEY()\n { // opcode 0x88\n // Y = ((Y - 1) & 0xff);\n this.regY = ((this.regY - 1) & 0xff);\n // SET_LAZY_NZ(Y);\n this.regRN = this.regRZ = (this.regY);\n }\n\n /**\n * @this {C1PCPU}\n */\n opTXA()\n { // opcode 0x8a\n // A = X; SET_LAZY_NZ(X);\n this.regRN = this.regRZ = this.regA = this.regX;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTYabs()\n { // opcode 0x8c\n // EA = WORD(PC); PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // ML = Y;\n this.abMem[this.regEAWrite] = this.regY;\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTAabs()\n { // opcode 0x8d\n // EA = WORD(PC); PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // ML = A;\n this.abMem[this.regEAWrite] = this.regA;\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTXabs()\n { // opcode 0x8e\n // EA = WORD(PC); PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // ML = X;\n this.abMem[this.regEAWrite] = this.regX;\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opBCC()\n { // opcode 0x90\n // PC = PC + (LAZY_C == 0? SBYTE(PC) : 0) + 1;\n this.regPC += (!(this.regRC & 0x0100)? (this.nStepCycles--,((this.abMem[this.regPC] << 24) >> 24)) : 0) + 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTAindy()\n { // opcode 0x91\n // EA = WORD(BYTE(PC++))+Y;\n this.regEAWrite = (this.abMem[this.regPC++]);\n this.regEAWrite = (this.abMem[this.regEAWrite] | (this.abMem[this.regEAWrite+1] << 8)) + this.regY;\n // ML = A;\n this.abMem[this.regEAWrite] = this.regA;\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTYzpx()\n { // opcode 0x94\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEAWrite = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // ML = Y;\n this.abMem[this.regEAWrite] = this.regY;\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTAzpx()\n { // opcode 0x95\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEAWrite = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // ML = A;\n this.abMem[this.regEAWrite] = this.regA;\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTXzpy()\n { // opcode 0x96\n // EA = (BYTE(PC++)+Y) & 0xff;\n this.regEAWrite = (this.abMem[this.regPC++]+this.regY) & 0xff;\n // ML = X;\n this.abMem[this.regEAWrite] = this.regX;\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opTYA()\n { // opcode 0x98\n // A = Y; SET_LAZY_NZ(Y);\n this.regRN = this.regRZ = this.regA = this.regY;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTAabsy()\n { // opcode 0x99\n // EA = WORD(PC)+Y; PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // ML = A;\n this.abMem[this.regEAWrite] = this.regA;\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opTXS()\n { // opcode 0x9a\n // S = X;\n this.regS = this.regX | 0x100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTAabsx()\n { // opcode 0x9d\n // EA = WORD(PC)+X; PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // ML = A;\n this.abMem[this.regEAWrite] = this.regA;\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDYimm()\n { // opcode 0xa0\n // EA = PC++;\n this.regEA = this.regPC++;\n // Y = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regY = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDAindx()\n { // opcode 0xa1\n // EA = WORD((BYTE(PC++)+X) & 0xff);\n this.regEA = ((this.abMem[this.regPC++]) + this.regX) & 0xff;\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n // A = ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regA = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDXimm()\n { // opcode 0xa2\n // EA = PC++;\n this.regEA = this.regPC++;\n // X = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regX = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDYzp()\n { // opcode 0xa4\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // Y = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regY = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDAzp()\n { // opcode 0xa5\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // A = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regA = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDXzp()\n { // opcode 0xa6\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // X = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regX = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opTAY()\n { // opcode 0xa8\n // Y = A; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regY = this.regA;\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDAimm()\n { // opcode 0xa9\n // EA = PC++;\n this.regEA = this.regPC++;\n // A = ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regA = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opTAX()\n { // opcode 0xaa\n // X = A; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regX = this.regA;\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDYabs()\n { // opcode 0xac\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // Y = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regY = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDAabs()\n { // opcode 0xad\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // A = ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regA = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDXabs()\n { // opcode 0xae\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // X = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regX = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opBCS()\n { // opcode 0xb0\n // PC = PC + (LAZY_C != 0? SBYTE(PC) : 0) + 1;\n this.regPC += ((this.regRC & 0x0100)? (this.nStepCycles--,((this.abMem[this.regPC] << 24) >> 24)) : 0) + 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDAindy()\n { // opcode 0xb1\n // EA = WORD(BYTE(PC++))+Y;\n this.regEA = (this.abMem[this.regPC++]);\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8)) + this.regY;\n // A = ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regA = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDYzpx()\n { // opcode 0xb4\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // Y = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regY = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDAzpx()\n { // opcode 0xb5\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // A = ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regA = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDXzpy()\n { // opcode 0xb6\n // EA = (BYTE(PC++)+Y) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regY) & 0xff;\n // X = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regX = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opCLV()\n { // opcode 0xb8\n // SET_LAZY_V(0);\n this.regRV = 0; this.regRU = 0;\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDAabsy()\n { // opcode 0xb9\n // EA = WORD(PC)+Y; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // A = ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regA = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opTSX()\n { // opcode 0xba\n // X = S; SET_LAZY_NZ(S);\n this.regRN = this.regRZ = this.regX = this.regS & 0xff;\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDYabsx()\n { // opcode 0xbc\n // EA = WORD(PC)+X; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // Y = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regY = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDAabsx()\n { // opcode 0xbd\n // EA = WORD(PC)+X; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // A = ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regA = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDXabsy()\n { // opcode 0xbe\n // EA = WORD(PC)+Y; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // X = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regX = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opCPYimm()\n { // opcode 0xc0\n // EA = PC++;\n this.regEA = this.regPC++;\n // RC = Y - ML;\n this.regRC = this.regY - this.abMem[this.regEA];\n // SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = (this.regRC);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opCMPindx()\n { // opcode 0xc1\n // EA = WORD((BYTE(PC++)+X) & 0xff);\n this.regEA = ((this.abMem[this.regPC++]) + this.regX) & 0xff;\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n // RC = A - ML; SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = this.regRC = (this.regA - this.abMem[this.regEA]);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opCPYzp()\n { // opcode 0xc4\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // RC = Y - ML;\n this.regRC = this.regY - this.abMem[this.regEA];\n // SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = (this.regRC);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opCMPzp()\n { // opcode 0xc5\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // RC = A - ML; SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = this.regRC = (this.regA - this.abMem[this.regEA]);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opDECzp()\n { // opcode 0xc6\n // EA = BYTE(PC++);\n this.regEAWrite = this.abMem[this.regPC++];\n // ML = ML - 1; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = ((this.abMem[this.regEAWrite] - 1) & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opINY()\n { // opcode 0xc8\n // Y = ((Y + 1) & 0xff);\n this.regY = ((this.regY + 1) & 0xff);\n // SET_LAZY_NZ(Y);\n this.regRN = this.regRZ = (this.regY);\n }\n\n /**\n * @this {C1PCPU}\n */\n opCMPimm()\n { // opcode 0xc9\n // EA = PC++;\n this.regEA = this.regPC++;\n // RC = A - ML; SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = this.regRC = (this.regA - this.abMem[this.regEA]);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opDEX()\n { // opcode 0xca\n // X = ((X - 1) & 0xff); SET_LAZY_NZ(X);\n this.regRN = this.regRZ = this.regX = ((this.regX - 1) & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opCPYabs()\n { // opcode 0xcc\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // RC = Y - ML; SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = this.regRC = this.regY - this.abMem[this.regEA];\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opCMPabs()\n { // opcode 0xcd\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // RC = A - ML; SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = this.regRC = (this.regA - this.abMem[this.regEA]);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opDECabs()\n { // opcode 0xce\n // EA = WORD(PC); PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // ML = ML - 1; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = ((this.abMem[this.regEAWrite] - 1) & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opBNE()\n { // opcode 0xd0\n // PC = PC + (LAZY_Z == 0? SBYTE(PC) : 0) + 1;\n this.regPC += ((this.regRZ & 0xff)? (this.nStepCycles--,((this.abMem[this.regPC] << 24) >> 24)) : 0) + 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opCMPindy()\n { // opcode 0xd1\n // EA = WORD(BYTE(PC++))+Y;\n this.regEA = (this.abMem[this.regPC++]);\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8)) + this.regY;\n // RC = A - ML; SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = this.regRC = (this.regA - this.abMem[this.regEA]);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opCMPzpx()\n { // opcode 0xd5\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // RC = A - ML; SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = this.regRC = (this.regA - this.abMem[this.regEA]);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opDECzpx()\n { // opcode 0xd6\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEAWrite = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // ML = ML - 1; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = ((this.abMem[this.regEAWrite] - 1) & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opCLD()\n { // opcode 0xd8\n // D = 0;\n this.clearBCD();\n }\n\n /**\n * @this {C1PCPU}\n */\n opCMPabsy()\n { // opcode 0xd9\n // EA = WORD(PC)+Y; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // RC = A - ML; SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = this.regRC = (this.regA - this.abMem[this.regEA]);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opCMPabsx()\n { // opcode 0xdd\n // EA = WORD(PC)+X; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // RC = A - ML; SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = this.regRC = (this.regA - this.abMem[this.regEA]);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opDECabsx()\n { // opcode 0xde\n // EA = WORD(PC)+X; PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // ML = ML - 1; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = ((this.abMem[this.regEAWrite] - 1) & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opCPXimm()\n { // opcode 0xe0\n // EA = PC++;\n this.regEA = this.regPC++;\n // RC = X - ML;\n this.regRC = this.regX - this.abMem[this.regEA];\n // SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = (this.regRC);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCindx()\n { // opcode 0xe1\n // EA = WORD((BYTE(PC++)+X) & 0xff);\n this.regEA = ((this.abMem[this.regPC++]) + this.regX) & 0xff;\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n // RC = (A - ML - !LAZY_C);\n this.regRC = (this.regA - this.abMem[this.regEA] - ((this.regRC & 0x0100)? 0 : 1));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCindxBCD()\n { // opcode 0xe1\n // EA = WORD((BYTE(PC++)+X) & 0xff);\n this.regEA = ((this.abMem[this.regPC++]) + this.regX) & 0xff;\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n // A = this.subBCD(A,ML);\n this.regA = this.subBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opCPXzp()\n { // opcode 0xe4\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // RC = X - ML;\n this.regRC = this.regX - this.abMem[this.regEA];\n // SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = (this.regRC);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCzp()\n { // opcode 0xe5\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // RC = (A - ML - !LAZY_C);\n this.regRC = (this.regA - this.abMem[this.regEA] - ((this.regRC & 0x0100)? 0 : 1));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCzpBCD()\n { // opcode 0xe5\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // A = this.subBCD(A,ML);\n this.regA = this.subBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opINCzp()\n { // opcode 0xe6\n // EA = BYTE(PC++);\n this.regEAWrite = this.abMem[this.regPC++];\n // ML = ML + 1; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = ((this.abMem[this.regEAWrite] + 1) & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opINX()\n { // opcode 0xe8\n // X = ((X + 1) & 0xff);\n this.regX = ((this.regX + 1) & 0xff);\n // SET_LAZY_NZ(X);\n this.regRN = this.regRZ = (this.regX);\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCimm()\n { // opcode 0xe9\n // EA = PC++;\n this.regEA = this.regPC++;\n // RC = (A - ML - !LAZY_C);\n this.regRC = (this.regA - this.abMem[this.regEA] - ((this.regRC & 0x0100)? 0 : 1));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCimmBCD()\n { // opcode 0xe9\n // EA = PC++;\n this.regEA = this.regPC++;\n // A = this.subBCD(A,ML);\n this.regA = this.subBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opNOP()\n { // opcode 0xea\n //\n }\n\n /**\n * @this {C1PCPU}\n */\n opCPXabs()\n { // opcode 0xec\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // RC = X - ML; SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = this.regRC = this.regX - this.abMem[this.regEA];\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCabs()\n { // opcode 0xed\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // RC = (A - ML - !LAZY_C);\n this.regRC = (this.regA - this.abMem[this.regEA] - ((this.regRC & 0x0100)? 0 : 1));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCabsBCD()\n { // opcode 0xed\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // A = this.subBCD(A,ML);\n this.regA = this.subBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opINCabs()\n { // opcode 0xee\n // EA = WORD(PC); PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // ML = ML + 1; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = ((this.abMem[this.regEAWrite] + 1) & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opBEQ()\n { // opcode 0xf0\n // PC = PC + (LAZY_Z == 1? SBYTE(PC) : 0) + 1;\n this.regPC += (!(this.regRZ & 0xff)? (this.nStepCycles--,((this.abMem[this.regPC] << 24) >> 24)) : 0) + 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCindy()\n { // opcode 0xf1\n // EA = WORD(BYTE(PC++))+Y;\n this.regEA = (this.abMem[this.regPC++]);\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8)) + this.regY;\n // RC = (A - ML - !LAZY_C);\n this.regRC = (this.regA - this.abMem[this.regEA] - ((this.regRC & 0x0100)? 0 : 1));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCindyBCD()\n { // opcode 0xf1\n // EA = WORD(BYTE(PC++))+Y;\n this.regEA = (this.abMem[this.regPC++]);\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8)) + this.regY;\n // A = this.subBCD(A,ML);\n this.regA = this.subBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCzpx()\n { // opcode 0xf5\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // RC = (A - ML - !LAZY_C);\n this.regRC = (this.regA - this.abMem[this.regEA] - ((this.regRC & 0x0100)? 0 : 1));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCzpxBCD()\n { // opcode 0xf5\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // A = this.subBCD(A,ML);\n this.regA = this.subBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opINCzpx()\n { // opcode 0xf6\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEAWrite = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // ML = ML + 1; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = ((this.abMem[this.regEAWrite] + 1) & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opSED()\n { // opcode 0xf8\n // D = 1;\n this.setBCD();\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCabsy()\n { // opcode 0xf9\n // EA = WORD(PC)+Y; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // RC = (A - ML - !LAZY_C);\n this.regRC = (this.regA - this.abMem[this.regEA] - ((this.regRC & 0x0100)? 0 : 1));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCabsyBCD()\n { // opcode 0xf9\n // EA = WORD(PC)+Y; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // A = this.subBCD(A,ML);\n this.regA = this.subBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCabsx()\n { // opcode 0xfd\n // EA = WORD(PC)+X; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // RC = (A - ML - !LAZY_C);\n this.regRC = (this.regA - this.abMem[this.regEA] - ((this.regRC & 0x0100)? 0 : 1));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCabsxBCD()\n { // opcode 0xfd\n // EA = WORD(PC)+X; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // A = this.subBCD(A,ML);\n this.regA = this.subBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opINCabsx()\n { // opcode 0xfe\n // EA = WORD(PC)+X; PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // ML = ML + 1; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = ((this.abMem[this.regEAWrite] + 1) & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSim()\n {\n var addr;\n var bSimOp = this.abMem[this.regPC++];\n switch(bSimOp) {\n\n case this.SIMOP_HLT:\n this.println(\"HALT\");\n this.halt();\n break;\n\n case this.SIMOP_MSG:\n addr = this.regPC; // currently we're using \"inline\" strings\n // addr = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n var s = \"\";\n while (addr < this.abMem.length) {\n var b = this.abMem[addr++];\n if (!b) break;\n s += String.fromCharCode(b);\n }\n this.regPC = addr; // update regPC as long as we're doing \"inline\" strings\n /*\n * Before simply printing the string, what kinds of handy substitutions should we provide?\n *\n * eg: %A for this.regA, %X for this.regX, etc\n */\n s = s.replace(/%A/g, Str.toHex(this.regA, 2)).replace(/%X/g, Str.toHex(this.regX, 2)).replace(/%Y/g, Str.toHex(this.regY, 2));\n this.println(s);\n /*\n * To make printing \"smoother\", let's force a yield\n */\n this.yieldCPU();\n break;\n\n default:\n this.regPC -= 2;\n this.println(\"undefined opSim: \" + Str.toHexByte(bSimOp) + \" at \" + Str.toHexWord(this.regPC));\n this.halt();\n }\n }\n\n /**\n * @this {C1PCPU}\n */\n opUndefined()\n {\n var b = this.abMem[--this.regPC];\n this.println(\"undefined opcode: \" + Str.toHexByte(b) + \" at \" + Str.toHexWord(this.regPC));\n this.halt();\n }\n\n /**\n * C1PCPU.init()\n *\n * This function operates on every HTML element of class \"cpu\", extracting the\n * JSON-encoded parameters for the C1PCPU constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a C1PCPU component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeCPUs = Component.getElementsByClass(document, C1PJS.APPCLASS, \"cpu\");\n for (var iCPU=0; iCPU < aeCPUs.length; iCPU++) {\n var eCPU = aeCPUs[iCPU];\n var parmsCPU = Component.getComponentParms(eCPU);\n var cpu = new C1PCPU(parmsCPU);\n Component.bindComponentControls(cpu, eCPU, C1PJS.APPCLASS);\n }\n }\n}\n\n/*\n * Macro reference (from my original 1998 C source code, preserved in the comments below):\n *\n * #define BYTE(a) (abMem[(a) & 0xffff])\n * #define WORD(a) (*(word *)&BYTE(a))\n * #define SBYTE(a) ((int)(char)BYTE(a))\n * #define STACK(a) BYTE(((a) & 0xff)+0x100)\n * #define M WORD(EA)\n * #define ML BYTE(EA+0)\n * #define MH BYTE(EA+1)\n * #define A (aRegs[0].value) // 8 bits\n * #define X (aRegs[1].value) // 8 bits\n * #define Y (aRegs[2].value) // 8 bits\n * #define S (aRegs[3].value) // 8 bits\n * #define P (aRegs[4].value) // 8 bits\n * #define RN (aRegs[5].value) // 8 bits\n * #define RZ (aRegs[6].value) // 8 bits\n * #define RU (aRegs[7].value) // 8 bits\n * #define RV (aRegs[8].value) // 16 bits\n * #define RC (aRegs[9].value) // 16 bits\n * #define EA (aRegs[10].value)// 16 bits\n * #define LA (aRegs[11].value)// 16 bits\n * #define PC (aRegs[12].value)// 16 bits\n * #define EF (aRegs[13].value)// 8 bits\n * #define C P0\n * #define Z P1\n * #define I P2\n * #define D P3\n * #define B P4\n * #define V P6\n * #define N P7\n * #define W EF0\n * #define LAZY_C (RCH0)\n * #define SET_LAZY_C(b) (RCH0 = (b))\n * #define LAZY_N (RN7)\n * #define SET_LAZY_N(b) (RN7 = (b))\n * #define SET_LAZY_NZ(v) (RN = RZ = (v))\n * #define LAZY_Z ((byte)RZ == 0)\n * #define SET_LAZY_Z(b) (RZ = !(b))\n * #define LAZY_V ((((RVL ^ RU) ^ (RV >> 1)) & 0x80) != 0)\n * #define SET_LAZY_V(b) (RV = 0, RU = ((b)? 0x80 : 0x00))\n * #define SET_LAZY_OV(a,b,r) (RU = (a) ^ (b), RV = (r))\n */\n\n/*\n * Initialize every CPU module on the page (as IF there's ever going to be more than one ;-))\n */\nWeb.onInit(C1PCPU.init);\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/rom.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass C1PROM extends Component {\n /**\n * C1PROM(parmsROM)\n *\n * The ROM component expects the following (parmsROM) properties:\n *\n * size: amount of ROM, in bytes\n * image: name of ROM image file\n *\n * NOTE: The final location for the ROM image, once loaded, will be specified\n * by the Computer object, using the setBuffer() method.\n *\n * @this {C1PROM}\n * @param {Object} parmsROM\n * @property {function()} convertImage\n */\n constructor(parmsROM)\n {\n super(\"C1PROM\", parmsROM);\n\n this.abMem = null;\n this.abImage = null;\n this.cbROM = parmsROM['size'];\n this.sImage = parmsROM['image'];\n if (this.sImage) {\n var sFileURL = this.sImage;\n /**\n * If the selected ROM image has a \".json\" extension, then we assume it's a pre-converted\n * JSON-encoded ROM image, so we load it as-is; ditto for files with a \".hex\" extension. Otherwise,\n * we ask our server-side ROM image converter to return the corresponding JSON-encoded data,\n * in compact form (ie, minimal whitespace, no ASCII data comments, etc).\n */\n var sFileExt = Str.getExtension(this.sImage);\n if (sFileExt != DumpAPI.FORMAT.JSON && sFileExt != DumpAPI.FORMAT.HEX) {\n sFileURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sImage + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES;\n }\n var rom = this;\n Web.getResource(sFileURL, null, true, function(sURL, sResponse, nErrorCode) {\n rom.convertImage(sURL, sResponse, nErrorCode);\n });\n }\n }\n\n /**\n * @this {C1PROM}\n * @param {Array} abMemory\n * @param {number} start\n * @param {number} end\n * @param {C1PCPU} cpu\n */\n setBuffer(abMemory, start, end, cpu)\n {\n this.abMem = abMemory;\n this.offROM = start;\n var cbROM = end - start + 1;\n /*\n * It's possible that the ROM component didn't specify a size,\n * in which case just use the size the Computer component has specified.\n */\n if (!this.cbROM)\n this.cbROM = cbROM;\n if (cbROM != this.cbROM) {\n this.setError(\"computer-specified ROM size (\" + Str.toHexWord(cbROM) + \") does not match component-specified size (\" + Str.toHexWord(this.cbROM) + \")\");\n return;\n }\n if (cpu) {\n this.cpu = cpu;\n cpu.addWriteNotify(start, end, this, this.setByte);\n }\n this.copyImage();\n }\n\n /**\n * @this {C1PROM}\n * @param {boolean} fOn\n * @param {C1PComputer} cmp\n */\n setPower(fOn, cmp)\n {\n if (fOn && !this.flags.powered) {\n this.flags.powered = true;\n if (DEBUGGER) this.dbg = cmp.getComponentByType(\"debugger\");\n }\n }\n\n /**\n * @this {C1PROM}\n * @param {number} addr\n * @param {number|undefined} [addrFrom]\n */\n setByte(addr, addrFrom)\n {\n /*\n * Beyond reporting this write, we need to \"repair\" the ROM, using the original image data,\n * but only if addrFrom is defined (undefined implies this is a write from the Debugger, and\n * we need to allow the Debugger to modify ROM contents).\n */\n if (addrFrom !== undefined) {\n if (DEBUGGER && this.dbg) this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_PORT, true);\n var offset = (addr - this.offROM);\n\n if (!this.abImage)\n this.abMem[this.offROM + offset] = 0;\n else\n this.abMem[this.offROM + offset] = this.abImage[offset];\n }\n }\n\n /**\n * @this {C1PROM}\n * @param {string} sImageName\n * @param {string} sImageData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n convertImage(sImageName, sImageData, nErrorCode)\n {\n if (nErrorCode) {\n this.println(\"Error loading ROM \\\"\" + sImageName + \"\\\" (\" + nErrorCode + \")\");\n return;\n }\n if (sImageData.charAt(0) == \"[\" || sImageData.charAt(0) == \"{\") {\n try {\n /*\n * The most likely source of any exception will be here: parsing the JSON-encoded ROM data.\n */\n var rom = eval(\"(\" + sImageData + \")\");\n var ab = rom['bytes'];\n if (ab) {\n this.abImage = ab;\n } else {\n this.abImage = rom;\n }\n } catch (e) {\n this.println(\"Error processing ROM \\\"\" + sImageName + \"\\\": \" + e.message);\n return;\n }\n }\n else {\n /*\n * Parse the ROM image data manually; we assume it's in \"simplified\" hex form (a series of hex byte-values separated by whitespace)\n */\n var sData = sImageData.replace(/\\n/gm, \" \").replace(/ +$/, \"\");\n var asData = sData.split(\" \");\n this.abImage = new Array(asData.length);\n for (var i=0; i < asData.length; i++) {\n this.abImage[i] = parseInt(asData[i], 16);\n }\n }\n this.copyImage();\n }\n\n /**\n * @this {C1PROM}\n */\n copyImage()\n {\n /*\n * The Computer object may give us the address of the ROM image before we've finished downloading the image,\n * so both setBuffer() and convertImage() call copyImage(), which in turn will copy the image ONLY when both\n * pieces are in place. At that point, the component becomes \"ready\", in much the same way that other components\n * (eg, CPU and Screen) become \"ready\" when all their prerequisites are satisfied.\n */\n if (!this.isReady()) {\n if (!this.sImage) {\n this.setReady();\n }\n else\n if (this.abImage && this.abMem) {\n var cbImage = this.abImage.length;\n if (cbImage != this.cbROM) {\n this.setError(\"ROM image size (\" + Str.toHexWord(cbImage) + \") does not match component-specified size (\" + Str.toHexWord(this.cbROM) + \")\");\n return;\n }\n if (DEBUG) this.log(\"copyImage(): copying ROM to \" + Str.toHexWord(this.offROM) + \" (\" + Str.toHexWord(cbImage) + \" bytes)\");\n for (var i=0; i < cbImage; i++) {\n this.abMem[this.offROM + i] = this.abImage[i];\n }\n this.setReady();\n }\n }\n }\n\n /**\n * C1PROM.init()\n *\n * This function operates on every HTML element of class \"rom\", extracting the\n * JSON-encoded parameters for the C1PROM constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a C1PROM component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeROM = Component.getElementsByClass(document, C1PJS.APPCLASS, \"rom\");\n for (var iROM=0; iROM < aeROM.length; iROM++) {\n var eROM = aeROM[iROM];\n var parmsROM = Component.getComponentParms(eROM);\n var rom = new C1PROM(parmsROM);\n Component.bindComponentControls(rom, eROM, C1PJS.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize all the ROM modules on the page.\n */\nWeb.onInit(C1PROM.init);\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/ram.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass C1PRAM extends Component {\n /**\n * C1PRAM(parmsRAM)\n *\n * The RAM component expects the following (parmsRAM) properties:\n *\n * size: amount of RAM, in bytes\n *\n * NOTE: We may make a note of the specified size, but we will not actually allocate\n * any memory for the RAM; we wait for the Computer object to tell us where our RAM is,\n * using the setBuffer() method.\n *\n * @this {C1PRAM}\n * @param {Object} parmsRAM\n */\n constructor(parmsRAM)\n {\n super(\"C1PRAM\", parmsRAM);\n }\n\n /**\n * @this {C1PRAM}\n * @param {Array} abMemory\n * @param {number} start\n * @param {number} end\n * @param {C1PCPU} cpu\n */\n setBuffer(abMemory, start, end, cpu)\n {\n this.abMem = abMemory;\n // this.offRAM = start;\n // this.cbRAM = end - start + 1;\n this.setReady();\n }\n\n /**\n * C1PRAM.init()\n *\n * This function operates on every HTML element of class \"ram\", extracting the\n * JSON-encoded parameters for the C1PRAM constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a C1PRAM component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeRAM = Component.getElementsByClass(document, C1PJS.APPCLASS, \"ram\");\n for (var iRAM=0; iRAM < aeRAM.length; iRAM++) {\n var eRAM = aeRAM[iRAM];\n var parmsRAM = Component.getComponentParms(eRAM);\n var ram = new C1PRAM(parmsRAM);\n Component.bindComponentControls(ram, eRAM, C1PJS.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize all the RAM modules on the page.\n */\nWeb.onInit(C1PRAM.init);\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/keyboard.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass C1PKeyboard extends Component {\n /**\n * C1PKeyboard(parmsKbd)\n *\n * The Keyboard component can be configured with the following (parmsKbd) properties:\n *\n * model: model number (one of: 542 or 600; 600 is the default)\n *\n * Its main purpose is to receive binding requests for various keyboard events,\n * and to use those events to simulate the C1P's keyboard hardware; specifically,\n * an OSI model 600 board (NOT the model 542).\n *\n * Keys on the C1P keyboard that differ from modern keyboards, along with their\n * closest modern counterpart:\n *\n * C1P PC\n * --- --\n * 2\" 2@\n * 6& 6^\n * 7' 7&\n * 8( 8*\n * 9) 9(\n * 0 0)\n * :* -_\n * -= =+\n * ;+ ;:\n * LINEFEED CTRL-J\n * RETURN ENTER (or CTRL-M)\n * SHIFT-O DELETE (or CTRL-H)\n * SHIFT-N ^\n * SHIFT-P @ (used by the BASIC-IN-ROM to abandon the current line)\n * SHIFT-L \\\n * SHIFT-K [\n * SHIFT-M ]\n * CTRL-C Same (used by the BASIC-IN-ROM to interrupt RUN and LIST, unless disabled with POKE 530,1)\n * CTRL-O Same (used by the BASIC-IN-ROM to suppress output until another CTRL-O is typed)\n * RUB-OUT (no mapping chosen for this key yet)\n * REPEAT (no mapping chosen for this key yet)\n *\n * Problems with iOS Devices\n * -------------------------\n * The keyboard pops up with the SHIFT key depressed, which is not the initial keyboard state that the C1P expects.\n * I tried to fix that by adding an 'autocapitalize=\"off\"' attribute alongside the 'contenteditable=\"true\"' attribute\n * on the <canvas> element, but apparently Safari v5 honors that only inside certain elements (eg, <input>). The simplest\n * work-around is to tap the iOS device's SHIFT key before starting to type, but I'd prefer an automatic solution.\n *\n * Another work-around might be to NEVER pass the real CAPS-LOCK state to the virtual machine, and whenever CAPS-LOCK is\n * actually down, automatically \"uncapitalize\" all letters.\n *\n * However, the current work-around is for keyPressSimulate() to ALWAYS convert all alphabetic charCodes to their\n * lower-case equivalents, and simply let the C1P's own shift-key logic do its thing. Note that we do this ONLY for\n * iOS devices, so that on all other devices, you can still use special shifted key combinations like SHIFT-O and SHIFT-P;\n * this work-around breaks those key combinations for iOS devices, but that seems like a reasonable trade-off.\n *\n * Simple C1P Virtual Hardware Test\n * --------------------------------\n * Using the following code:\n *\n * 10 POKE 530,1\n * 20 KEY=57088\n * 25 Q=-1\n * 30 POKE KEY,64\n * 40 P=PEEK(KEY)\n * 50 IF P<>Q THEN PRINT P\n * 60 Q=P\n * 70 GOTO 30\n *\n * The value 64 (0x40) should have enabled every row except R6. Here were the results for keys\n * on row R7:\n *\n * 1 2 3 4 5 6 7\n * --- --- --- --- --- --- ---\n * 126 190 222 238 246 250 252\n *\n * Sure enough, none of the keys on R6 worked, and all the keys on rows R0-R5 generated the same\n * values as R7. But why were the values read all EVEN instead of ODD (ie, why was bit 0 cleared as\n * well?) Answer: because 0x40 also enables keys on row R0, where the SHIFT-LOCK key resides,\n * and since the SHIFT-LOCK is normally locked AND also sits in column C0, bit 0 will be clear as well.\n *\n * This explains why the \"STAR WARS\" game (SAMPLE4.BAS) expected values \"126,190,222,238,246,250\"\n * for keys 1-6 after POKE'ing 64 into location 57088 (0xdf00), instead of the more typical values\n * \"127,191,223,239,247,251.\" This also means that anyone who happened to unlock their SHIFT-LOCK\n * would have trouble playing that game.\n *\n * @this {C1PKeyboard}\n * @param {Object} parmsKbd\n */\n constructor(parmsKbd)\n {\n super(\"C1PKeyboard\", parmsKbd);\n\n this.flags.powered = false;\n this.nDefaultModel = parmsKbd['model'];\n\n /*\n * keyCodes that I must pay particular attention to\n */\n this.KEYCODE_DELETE = 0x08;\n this.KEYCODE_TAB = 0x09;\n this.KEYCODE_LF = 0x0A;\n this.KEYCODE_CR = 0x0D;\n this.KEYCODE_SHIFT = 0x10; // I map this to CHARCODE_LSHIFT\n this.KEYCODE_CONTROL = 0x11;\n this.KEYCODE_ALT = 0x12; // I map this to CHARCODE_RSHIFT (since the C1P keyboard has no ALT key)\n this.KEYCODE_CAPSLOCK = 0x14;\n this.KEYCODE_ESC = 0x1B; // NOTE: for some reason, this comes in via keyDown/keyUp only, not keyPress\n this.KEYCODE_COMMAND = 0x5B;\n\n /*\n * The following charCodes are the same as the corresponding keyCodes\n */\n this.CHARCODE_DELETE = this.KEYCODE_DELETE;\n this.CHARCODE_LF = this.KEYCODE_LF;\n this.CHARCODE_CR = this.KEYCODE_CR;\n this.CHARCODE_ESC = this.KEYCODE_ESC;\n\n /*\n * The following charCodes are NOT the same as the corresponding keyCodes, hence the bias (PSEUDO_CHARCODE);\n * I've deliberately chosen a bias that still produces values in the byte range (0x00-0xFF) and will therefore\n * fit into aCharCodeMap, but which shouldn't conflict with any actual, type-able keys.\n */\n this.PSEUDO_CHARCODE = 0xE0;\n this.CHARCODE_LSHIFT = this.KEYCODE_SHIFT + this.PSEUDO_CHARCODE;\n this.CHARCODE_CTRL = this.KEYCODE_CONTROL + this.PSEUDO_CHARCODE;\n this.CHARCODE_RSHIFT = this.KEYCODE_ALT + this.PSEUDO_CHARCODE;\n this.CHARCODE_SHIFTLOCK = this.KEYCODE_CAPSLOCK + this.PSEUDO_CHARCODE;\n\n /*\n * Other common character codes, pseudo (like the C1P's \"BREAK\" key, which has no modern analog) or otherwise\n */\n this.CHARCODE_BREAK = 0x00 + this.PSEUDO_CHARCODE;\n this.CHARCODE_CTRLC = 0x03;\n this.CHARCODE_CTRLO = 0x0F;\n\n /*\n * These are \"shift key\" bits I store in bitsShift, and with the exception of BIT_COMMAND (because\n * the C1P doesn't have a COMMAND key), they all match the bit position of the corresponding shift key's\n * column on row 0 (abKbdCols[0]) of the simulated keyboard hardware.\n *\n * NOTE: Whenever shift key bits need to be restored from bitsShift to abKbdCols[0] (eg, when restoring\n * the current shift state at the completion of a simulated key), be sure to mask bitsShift with BITS_SIMULATE\n * before propagating them.\n */\n this.BIT_SHIFTLOCK = 0x01;\n this.BIT_RSHIFT = 0x02;\n this.BIT_LSHIFT = 0x04;\n this.BIT_COMMAND = 0x08; // the C1P has no key \"wired\" to this column, so I can use this bit for COMMAND\n this.BIT_CTRL = 0x40;\n this.BITS_SIMULATE = (this.BIT_RSHIFT | this.BIT_LSHIFT | this.BIT_CTRL);\n\n this.SIMCODE_KEYPRESS = 0;\n this.SIMCODE_KEYRELEASE = 1;\n this.SIMCODE_KEYEVENT = 2;\n this.SIMCODE_KEYTIMEOUT = 3;\n this.SIMCODE_AUTOCLEAR = 4;\n this.aSimCodeDescs = [\"keyPress\",\"keyRelease\",\"keyEvent\",\"keyTimeout\",\"autoClear\"];\n\n /*\n * From \"OSI C1P Technical Report\" p.19 regarding the Model 600 Board:\n *\n * \"By holding down any key, one will first get one character output, and after approximately\n * a half second delay a repeat rate of approximately 5 characters per second.\"\n */\n this.nCyclesThreshold = 8192; // number of virtual CPU cycles required before aKbdStates is propagated\n this.msReleaseDelay = 250; // number of milliseconds before a down key is \"forced\" up (unless we see it go up)\n this.msReleaseRepeat = 100; // number of milliseconds before a held key is \"forced\" up (assuming auto-repeat)\n this.msInjectDelay = 300; // number of milliseconds between injected keystrokes\n\n this.aButtonCodeMap = {};\n this.aButtonCodeMap['break'] = this.CHARCODE_BREAK;\n this.aButtonCodeMap['esc'] = this.CHARCODE_ESC;\n this.aButtonCodeMap['ctrl-c'] = this.CHARCODE_CTRLC;\n this.aButtonCodeMap['ctrl-o'] = this.CHARCODE_CTRLO;\n\n /*\n * This array is used by keyEventSimulate() to lookup a given charCode and convert it to the appropriate\n * row/col bit combination that the C1P requires. I assign each supported charCode a 16-bit value, where\n * the high byte contains the row/col pair (in the high and low nibbles, respectively), and the low byte\n * contains any required shift-key code.\n *\n * For example, an apostrophe (0x27) is an unshifted key on a modern keyboard, but it is a SHIFT-7 on the\n * C1P keyboard, so when I simulate the 7, I must also simulate a SHIFT (I always choose the LEFT shift\n * key -- CHARCODE_LSHIFT -- but that choice is completely arbitrary).\n *\n * Using charCodes (from keyPress events) proved to be more robust than using keyCodes (from keyDown and\n * keyUp events), in part because of differences between the C1P keyboard's layout and modern keyboards,\n * and also because of differences in the way browsers generate the keyDown and keyUp events. For\n * example, Safari on iOS devices will not generate up/down events for shift keys, and for other keys,\n * the up/down events are usually generated after the actual press is complete, and in rapid succession,\n * which doesn't give the slow C1P virtual machine enough time to detect the key.\n *\n * There are still a few times that I call keyEventSimulate() from keyEvent(), and for those occasions,\n * I create a pseudo-charCode value by adding PSEUDO_CHARCODE (0xE0) to the keyCode value, to avoid any\n * confusion with real charCodes:\n *\n * CHARCODE_LSHIFT (originally 0x10, which also looks like CTRL-P, so converted to 0xF0)\n * CHARCODE_CTRL (originally 0x11, which also looks like CTRL-Q, so converted to 0xF1)\n * CHARCODE_RSHIFT (originally 0x12, which also looks like CTRL-R, so converted to 0xF2)\n * CHARCODE_SHIFTLOCK (originally 0x14, which also looks like CTRL-T, so converted to 0xF4)\n *\n * Again, as things currently stand, iOS devices will never generate the above charCodes, so any C1P software\n * that relies detecting on shift-key state changes will not work on those devices.\n *\n * For reference purposes, I've left some parenthetical references to corresponding keyCodes in the comments\n * below. Relying on keyCodes is problematic, which is why I've tried to eliminate most dependencies on them,\n * but still, they're all you get on keyDown/keyUp events.\n */\n this.aCharCodeMap = [];\n this.aCharCodeMap[0x31] = 0x7700; this.aCharCodeMap[0x21] = 0x7700 + this.CHARCODE_LSHIFT; // 1 (0x31) ! (0x31)\n this.aCharCodeMap[0x32] = 0x7600; this.aCharCodeMap[0x22] = 0x7600 + this.CHARCODE_LSHIFT; // 2 (0x32) \" (0xDE)\n this.aCharCodeMap[0x33] = 0x7500; this.aCharCodeMap[0x23] = 0x7500 + this.CHARCODE_LSHIFT; // 3 (0x33) # (0x33)\n this.aCharCodeMap[0x34] = 0x7400; this.aCharCodeMap[0x24] = 0x7400 + this.CHARCODE_LSHIFT; // 4 (0x34) $ (0x34)\n this.aCharCodeMap[0x35] = 0x7300; this.aCharCodeMap[0x25] = 0x7300 + this.CHARCODE_LSHIFT; // 5 (0x35) % (0x35)\n this.aCharCodeMap[0x36] = 0x7200; this.aCharCodeMap[0x26] = 0x7200 + this.CHARCODE_LSHIFT; // 6 (0x36) & (0x37)\n this.aCharCodeMap[0x37] = 0x7100; this.aCharCodeMap[0x27] = 0x7100 + this.CHARCODE_LSHIFT; // 7 (0x37) ' (0xDE)\n this.aCharCodeMap[0x38] = 0x6700; this.aCharCodeMap[0x28] = 0x6700 + this.CHARCODE_LSHIFT; // 8 (0x38) ( (0x39)\n this.aCharCodeMap[0x39] = 0x6600; this.aCharCodeMap[0x29] = 0x6600 + this.CHARCODE_LSHIFT; // 9 (0x39) ) (0x30)\n this.aCharCodeMap[0x30] = 0x6500; // 0\n this.aCharCodeMap[0x3A] = 0x6400; this.aCharCodeMap[0x2A] = 0x6400 + this.CHARCODE_LSHIFT; // : (0xBA) * (0x38)\n this.aCharCodeMap[0x2D] = 0x6300; this.aCharCodeMap[0x3D] = 0x6300 + this.CHARCODE_LSHIFT; // - (0xBD) = (0xBB)\n //this.aCharCodeMap[0x00] = 0x6200; // RUB-OUT (no mapping chosen for this key yet)\n this.aCharCodeMap[0x2E] = 0x5700; this.aCharCodeMap[0x3E] = 0x5700 + this.CHARCODE_LSHIFT; // . (0xBE) > (0xBE)\n this.aCharCodeMap[0x6C] = 0x5600; this.aCharCodeMap[0x4C] = 0x5600 + this.CHARCODE_LSHIFT; this.aCharCodeMap[0x5C] = 0x5600 + this.CHARCODE_LSHIFT; // l L \\\n this.aCharCodeMap[0x6F] = 0x5500; this.aCharCodeMap[0x4F] = 0x5500 + this.CHARCODE_LSHIFT; this.aCharCodeMap[this.CHARCODE_DELETE] = 0x5500 + this.CHARCODE_LSHIFT; // o O DELETE\n this.aCharCodeMap[this.CHARCODE_LF] = 0x5400; // LINE-FEED\n this.aCharCodeMap[this.CHARCODE_CR] = 0x5300; // RETURN\n this.aCharCodeMap[0x77] = 0x4700; this.aCharCodeMap[0x57] = 0x4700 + this.CHARCODE_LSHIFT; // w W\n this.aCharCodeMap[0x65] = 0x4600; this.aCharCodeMap[0x45] = 0x4600 + this.CHARCODE_LSHIFT; // e E\n this.aCharCodeMap[0x72] = 0x4500; this.aCharCodeMap[0x52] = 0x4500 + this.CHARCODE_LSHIFT; // r R\n this.aCharCodeMap[0x74] = 0x4400; this.aCharCodeMap[0x54] = 0x4400 + this.CHARCODE_LSHIFT; // t T\n this.aCharCodeMap[0x79] = 0x4300; this.aCharCodeMap[0x59] = 0x4300 + this.CHARCODE_LSHIFT; // y Y\n this.aCharCodeMap[0x75] = 0x4200; this.aCharCodeMap[0x55] = 0x4200 + this.CHARCODE_LSHIFT; // u U\n this.aCharCodeMap[0x69] = 0x4100; this.aCharCodeMap[0x49] = 0x4100 + this.CHARCODE_LSHIFT; // i I\n this.aCharCodeMap[0x73] = 0x3700; this.aCharCodeMap[0x53] = 0x3700 + this.CHARCODE_LSHIFT; // s S\n this.aCharCodeMap[0x64] = 0x3600; this.aCharCodeMap[0x44] = 0x3600 + this.CHARCODE_LSHIFT; // d D\n this.aCharCodeMap[0x66] = 0x3500; this.aCharCodeMap[0x46] = 0x3500 + this.CHARCODE_LSHIFT; // f F\n this.aCharCodeMap[0x67] = 0x3400; this.aCharCodeMap[0x47] = 0x3400 + this.CHARCODE_LSHIFT; // g G\n this.aCharCodeMap[0x68] = 0x3300; this.aCharCodeMap[0x48] = 0x3300 + this.CHARCODE_LSHIFT; // h H\n this.aCharCodeMap[0x6A] = 0x3200; this.aCharCodeMap[0x4A] = 0x3200 + this.CHARCODE_LSHIFT; // j J\n this.aCharCodeMap[0x6B] = 0x3100; this.aCharCodeMap[0x4B] = 0x3100 + this.CHARCODE_LSHIFT; this.aCharCodeMap[0x5B] = 0x3100 + this.CHARCODE_LSHIFT; // k K [\n this.aCharCodeMap[0x78] = 0x2700; this.aCharCodeMap[0x58] = 0x2700 + this.CHARCODE_LSHIFT; // x X\n this.aCharCodeMap[0x63] = 0x2600; this.aCharCodeMap[0x43] = 0x2600 + this.CHARCODE_LSHIFT; // c C\n this.aCharCodeMap[0x76] = 0x2500; this.aCharCodeMap[0x56] = 0x2500 + this.CHARCODE_LSHIFT; // v V\n this.aCharCodeMap[0x62] = 0x2400; this.aCharCodeMap[0x42] = 0x2400 + this.CHARCODE_LSHIFT; // b B\n this.aCharCodeMap[0x6E] = 0x2300; this.aCharCodeMap[0x4E] = 0x2300 + this.CHARCODE_LSHIFT; this.aCharCodeMap[0x5E] = 0x2300 + this.CHARCODE_LSHIFT; // n N ^\n this.aCharCodeMap[0x6D] = 0x2200; this.aCharCodeMap[0x4D] = 0x2200 + this.CHARCODE_LSHIFT; this.aCharCodeMap[0x5D] = 0x2200 + this.CHARCODE_LSHIFT; // m M ]\n this.aCharCodeMap[0x2C] = 0x2100; this.aCharCodeMap[0x3C] = 0x2100 + this.CHARCODE_LSHIFT; // , (0xBC) < (0xBC)\n this.aCharCodeMap[0x71] = 0x1700; this.aCharCodeMap[0x51] = 0x1700 + this.CHARCODE_LSHIFT; // q Q\n this.aCharCodeMap[0x61] = 0x1600; this.aCharCodeMap[0x41] = 0x1600 + this.CHARCODE_LSHIFT; // a A\n this.aCharCodeMap[0x7A] = 0x1500; this.aCharCodeMap[0x5A] = 0x1500 + this.CHARCODE_LSHIFT; // z Z\n this.aCharCodeMap[0x20] = 0x1400; // SPACE\n this.aCharCodeMap[0x2F] = 0x1300; this.aCharCodeMap[0x3F] = 0x1300 + this.CHARCODE_LSHIFT; // / (0xBF) ? (0xBF)\n this.aCharCodeMap[0x3B] = 0x1200; this.aCharCodeMap[0x2B] = 0x1200 + this.CHARCODE_LSHIFT; // ; (0xBA) + (0xBB)\n this.aCharCodeMap[0x70] = 0x1100; this.aCharCodeMap[0x50] = 0x1100 + this.CHARCODE_LSHIFT; this.aCharCodeMap[0x40] = 0x1100 + this.CHARCODE_LSHIFT; // p P @\n //this.aCharCodeMap[0x00] = 0x0700; // REPEAT (no mapping chosen for this key yet)\n this.aCharCodeMap[this.CHARCODE_CTRL] = 0x0600; // CTRL\n this.aCharCodeMap[this.CHARCODE_ESC] = 0x0500; // ESC\n this.aCharCodeMap[this.CHARCODE_LSHIFT] = 0x0200; // LEFT-SHIFT\n this.aCharCodeMap[this.CHARCODE_RSHIFT] = 0x0100; // RIGHT-SHIFT\n this.aCharCodeMap[this.CHARCODE_SHIFTLOCK] = 0x0000; // SHIFT-LOCK\n\n this.reset();\n }\n\n /**\n * @this {C1PKeyboard}\n */\n reset()\n {\n this.setModel(this.nDefaultModel);\n\n /*\n * The physical (not virtual) state of various shift keys,\n * with the exception of SHIFT-LOCK, which needs to start in the\n * \"locked\" position, regardless of the physical CAPS-LOCK state.\n *\n * QUESTION: In JavaScript, how do you query initial key states?\n */\n this.bitsShift = this.BIT_SHIFTLOCK;\n\n /*\n * Every SET bit of bKbdRows represents an enabled row (this convention\n * is the REVERSE of the C1P hardware, but I prefer it).\n */\n this.bKbdRows = 0x00;\n\n /*\n * Every SET bit of abKbdCols represents an enabled column; again, this is\n * the REVERSE of the C1P hardware, but I compensate for that difference with\n * a quick XOR in updateMemory().\n *\n * Like bitsShift, this 8x8 array (8 byte values, each with 8 bits) represents\n * the physical state of the keyboard, encoded in C1P format; the C1P won't\n * actually see data this until updateMemory() decides it's time to propagate it.\n */\n this.abKbdCols = [this.BIT_SHIFTLOCK,0x00,0x00,0x00,0x00,0x00,0x00,0x00];\n\n /*\n * After a new key event has updated abKbdCols, we \"push\" a copy of that\n * updated keyboard state onto this array. updateMemory() will then \"shift\"\n * the next copy off, update its own copy (abKbdColsLast), and then propagate\n * that to the C1P's keyboard memory, once the CPU has had enough time to\n * process the previous event (see nCyclesThreshold).\n */\n this.aKbdStates = [];\n\n /*\n * When a key \"down\" is simulated on behalf of some charCode, I save\n * the timer object responsible for simulating the key \"up\" here, so that\n * if I detect the actual key going up sooner, I can cancel the timer and\n * simulate the \"up\" immediately. Similarly, if another press for the same\n * key arrives before last one expired (eg, auto-repeat), I need to cancel\n * the previous timer for that key before setting another.\n *\n * NOTE: If this is anything other than an initial reset, then we need to\n * make sure there are no outstanding timers before we blow the array away.\n */\n if (this.aKeyTimers) {\n for (var i in this.aKeyTimers) {\n if (isNaN(+i)) continue; // ignore any non-numeric properties, if any\n if (this.aKeyTimers[i]) clearTimeout(this.aKeyTimers[i]);\n }\n }\n this.aKeyTimers = [];\n this.prevCharDown = 0;\n this.prevKeyDown = 0;\n\n /*\n * These save the last values written to keyboard memory, so that I can\n * avoid rewriting the memory if the values haven't changed since the last update.\n */\n this.bWriteLast = -1;\n this.abKbdColsLast = this.abKbdCols;\n\n /*\n * Due to the way the C1P scans its keyboard rows (from R0 up to R7 *or* to the\n * highest row for which a \"down\" key has just been detected), if we get back-to-back\n * key events for, say, \"I\" and then \"S\", the C1P will see only the \"S\", never the \"I\",\n * because \"I\" is on a higher row.\n *\n * That's why we have aKbdStates, which relies on the following CPU activity variables.\n */\n this.nReadsSinceLastEvent = 0;\n this.nWritesSinceLastEvent = 0;\n this.nCyclesSinceLastEvent = 0;\n\n /*\n * Make sure the auto-injection buffer is empty, too (an injection could have been\n * in progress on any reset after the first).\n */\n this.sInjectBuffer = \"\";\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"esc\", \"ctrl-c\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n /*\n * I want to bind to the first caller (ie, the Screen), not subsequent ones (eg, the Panel)\n */\n if (this.bindings[sBinding] === undefined) {\n switch(sBinding) {\n case \"keyDown\":\n this.bindings[sBinding] = control;\n control.onkeydown = function(kbd) {\n return function(event) {\n return kbd.keyEvent(event, true);\n };\n }(this);\n return true;\n case \"keyPress\":\n this.bindings[sBinding] = control;\n control.onkeypress = function(kbd) {\n return function(event) {\n return kbd.keyPress(event);\n };\n }(this);\n return true;\n case \"keyUp\":\n this.bindings[sBinding] = control;\n control.onkeyup = function(kbd) {\n return function(event) {\n return kbd.keyEvent(event, false);\n };\n }(this);\n return true;\n case \"break\":\n /*\n * The BREAK key is unusual: it requires us forcing the equivalent of someone pressing\n * our \"Reset\" and \"Run\" buttons. As things stand, the Computer component is responsible\n * for end-user \"reset\" requests, so we can simply arrange to call this.cmp.reset(true).\n *\n * NOTE: At the risk of making keyPressSimulate() a bit uglier, I also permit BREAK\n * there, in case someone wants to \"inject\" the BREAK key; however, if it's followed by\n * other injected keys, I'll need to avoid clearing the injection buffer on a reset;\n * currently, reset() resets everything.\n */\n this.bindings[sBinding] = control;\n control.onclick = function(kbd) {\n return function(event) {\n if (DEBUG) kbd.println(\"keyPressSimulate(break)\");\n if (kbd.cmp) kbd.cmp.reset(true);\n };\n }(this);\n return true;\n default:\n if (this.aButtonCodeMap[sBinding] !== undefined) {\n this.bindings[sBinding] = control;\n control.onclick = function(kbd, sButton, charCode) {\n return function(event) {\n if (DEBUG) kbd.println(\"keyPressSimulate(\" + sButton + \")\");\n if (kbd.cpu) kbd.cpu.setFocus();\n return !kbd.keyPressSimulate(charCode);\n };\n }(this, sBinding, this.aButtonCodeMap[sBinding]);\n return true;\n }\n break;\n }\n }\n return false;\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {Array} abMemory\n * @param {number} start\n * @param {number} end\n * @param {C1PCPU} cpu\n */\n setBuffer(abMemory, start, end, cpu)\n {\n this.abMem = abMemory;\n this.offKbd = start;\n this.cbKbd = end - start + 1;\n this.offKbdLimit = this.offKbd + this.cbKbd;\n if (cpu) {\n this.cpu = cpu;\n if (DEBUG) cpu.addReadNotify(start, end, this, this.getByte);\n cpu.addWriteNotify(start, end, this, this.setByte);\n }\n this.setReady();\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {number} nModel\n */\n setModel(nModel)\n {\n this.nModel = nModel;\n /*\n * Default to Model 600 behavior, where the keyboard status lines are inverted\n * (ie, a zero bit indicates a key press).\n */\n this.bInvert = 0xff;\n if (this.nModel != 600) {\n /*\n * No inversion for model 542\n */\n this.bInvert = 0x00;\n this.println(\"updated keyboard model: \" + this.nModel);\n }\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {boolean} fOn\n * @param {C1PComputer} cmp\n *\n * We make a note of the Computer component, so that we can invoke its reset() method when our simulated\n * BREAK key is pressed, and we query the Debugger component so that we can use its info() and halt() functions,\n * which we use to buffer information without adversely affecting timing and then dump later using the Debugger's\n * \"info\" command.\n */\n setPower(fOn, cmp)\n {\n if (fOn && !this.flags.powered) {\n this.flags.powered = true;\n this.cmp = cmp;\n if (DEBUGGER) this.dbg = cmp.getComponentByType(\"debugger\");\n }\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {boolean} [fReady] is assumed to indicate \"ready\" unless EXPLICITLY set to false\n */\n setReady(fReady)\n {\n this.iOS = Web.isUserAgent(\"iOS\");\n this.fMobile = (this.iOS || Web.isUserAgent(\"Android\"));\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(this.dbg.MESSAGE_KBD)) {\n this.dbg.message(\"mobile keyboard support: \" + (this.fMobile? \"true\" : \"false\") + \" (\" + window.navigator.userAgent + \")\");\n }\n super.setReady();\n }\n\n /**\n * calcReleaseDelay(fRepeat)\n *\n * This attempts to scale our default \"release\" delay appropriately for the current CPU speed.\n *\n * Note that if the effective CPU speed exceeds 16Mhz, it becomes very difficult to rely on timer-driven key events\n * (even the shortest available timer delay still gives the CPU too much time, so it thinks that even the briefest key\n * press represents a held key, resulting in multiple keystrokes). We deal with this by artificially limiting the top\n * speed in the CPU component (the current limit for \"fast\" mode is 8Mhz; see CPU.mhzFast)\n *\n * @this {C1PKeyboard}\n * @param {boolean} fRepeat is true if a timeout had already been active for the current key\n * @return {number}\n */\n calcReleaseDelay(fRepeat)\n {\n /*\n * NOTE: This delay affects only the \"up\" delay, not repeat delay, but it's useful to have an initial\n * \"up\" delay that's sufficiently large to ensure the native machine's auto-repeat behavior cooperates\n * with the virtual machine's auto-repeat behavior. msReleaseDelay is the initial delay, msReleaseRepeat\n * is the subsequent delay.\n *\n * Unfortunately, with a large initial delay, we need to enable the auto-clear code in the keyEvent()\n * handler, otherwise doing things like pressing ENTER repeatedly will result in sluggish behavior\n * (because you can generally press/release/repress keys faster than they will auto-repeat).\n */\n var msDelay = (fRepeat? this.msReleaseRepeat: this.msReleaseDelay);\n if (this.cpu && this.cpu.mhz) {\n msDelay /= this.cpu.mhz;\n }\n return msDelay;\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {number} [notCharCode]\n */\n autoClear(notCharCode)\n {\n if (this.prevCharDown && (notCharCode === undefined || notCharCode != this.prevCharDown)) {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(this.dbg.MESSAGE_KBD)) {\n this.dbg.message(\"autoClear(\" + Str.toHexByte(this.prevCharDown) + \")\");\n }\n\n clearTimeout(this.aKeyTimers[this.prevCharDown]);\n this.keyEventSimulate(this.prevCharDown, false, this.SIMCODE_AUTOCLEAR);\n }\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {string} sKeyCodes\n * @param {number} [msDelay] is an optional injection delay (default is msInjectDelay)\n */\n injectKeys(sKeyCodes, msDelay)\n {\n this.sInjectBuffer = sKeyCodes;\n if (DEBUG) this.log(\"injectKeys(\" + this.sInjectBuffer.split(\"\\n\").join(\"\\\\n\") + \")\");\n this.injectKeysFromBuffer(msDelay || this.msInjectDelay);\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {number} msDelay is the delay between injected keys\n */\n injectKeysFromBuffer(msDelay)\n {\n if (this.sInjectBuffer.length > 0) {\n var ch = this.sInjectBuffer.charCodeAt(0);\n /*\n * I could require all callers to supply CRs instead of LFs, but this is friendlier.\n */\n if (ch == 0x0a)\n ch = 0x0d;\n /*\n * Also, if upper-case characters are being injected, convert them to lower-case, and rely\n * on the virtual SHIFT-LOCK remaining locked for the duration; otherwise, we'd have to simulate\n * SHIFT key presses around every character (or around the entire set of characters) as well.\n *\n * UPDATE: Even though keyPressSimulate() currently has some code to do this automatically now,\n * it's really intended as a work-around for a SHIFT-related problem on iOS devices only, so\n * we can't rely on that in the general case.\n */\n if (ch >= 0x41 && ch <= 0x5A)\n ch += 0x20;\n this.sInjectBuffer = this.sInjectBuffer.substr(1);\n this.keyPressSimulate(ch);\n }\n if (this.sInjectBuffer.length > 0) {\n setTimeout(function(kbd) { return function() {kbd.injectKeysFromBuffer(msDelay);}; }(this), msDelay);\n }\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {Object} event\n * @param {boolean} fDown is true if called for a keyDown event, false if called for a keyUp event\n * @return {boolean} true to pass the event along, false to consume it\n */\n keyEvent(event, fDown)\n {\n var fPass;\n var fAutoClear = !fDown;\n var keyCode = event.keyCode;\n\n if (fDown) this.prevKeyDown = keyCode;\n\n if (keyCode == this.CHARCODE_LSHIFT - this.PSEUDO_CHARCODE) {\n this.bitsShift &= ~this.BIT_LSHIFT;\n if (fDown) this.bitsShift |= this.BIT_LSHIFT;\n keyCode += this.PSEUDO_CHARCODE;\n fAutoClear = false;\n }\n else\n if (keyCode == this.CHARCODE_RSHIFT - this.PSEUDO_CHARCODE) {\n this.bitsShift &= ~this.BIT_RSHIFT;\n if (fDown) this.bitsShift |= this.BIT_RSHIFT;\n keyCode += this.PSEUDO_CHARCODE;\n fAutoClear = false;\n }\n else\n if (keyCode == this.CHARCODE_CTRL - this.PSEUDO_CHARCODE) {\n this.bitsShift &= ~this.BIT_CTRL;\n if (fDown) this.bitsShift |= this.BIT_CTRL;\n keyCode += this.PSEUDO_CHARCODE;\n fAutoClear = false;\n }\n else\n if (keyCode == this.CHARCODE_SHIFTLOCK - this.PSEUDO_CHARCODE) {\n /*\n * FYI, this generates a \"down\" event ONLY when getting locked, and an \"up\" event ONLY\n * when getting unlocked--which is exactly what I want, even though that may seem a little\n * counter-intuitive (since the key itself actually went down AND up for each event).\n *\n * Moreover, since most people do NOT have CAPS-LOCK enabled, whereas the C1P needs it\n * enabled by default, we invert fDown, so that if the user enables CAPS-LOCK for some\n * reason, we treat is as *disabling* SHIFT-LOCK, and vice versa.\n */\n fDown = !fDown;\n this.bitsShift &= ~this.BIT_SHIFTLOCK;\n if (fDown) this.bitsShift |= this.BIT_SHIFTLOCK;\n keyCode += this.PSEUDO_CHARCODE;\n fAutoClear = false;\n }\n else\n if (keyCode == this.KEYCODE_COMMAND) {\n /*\n * Avoid interfering with useful Browser key commands, like COMMAND-Q, COMMAND-T, etc.\n */\n this.bitsShift &= ~this.BIT_COMMAND;\n if (fDown) this.bitsShift |= this.BIT_COMMAND;\n fAutoClear = false;\n fPass = true;\n }\n else\n if (keyCode == this.KEYCODE_TAB) {\n /*\n * If I don't consume TAB on the \"down\" event, then that's all I'll see, because the\n * browser will see it and give focus to the next control. But the \"down\" side is that\n * that no \"press\" event will be generated. This puts it in the same category as ESC,\n * which also generates \"down\" and \"up\" events (LOTS of \"down\" events for that matter),\n * but no \"press\" event. However, the C1P has no TAB key, so it's safe to completely ignore.\n */\n fPass = fAutoClear = false;\n }\n else\n if (keyCode == this.KEYCODE_ESC || keyCode == this.KEYCODE_DELETE) {\n /*\n * I don't get keyPress events for ESC (why?) and I never want the browser to act on DELETE\n * (which does double-duty as the \"Back\" button and leaves the current page), so I have to\n * simulate them now.\n *\n * Note that I call the \"press\" simulate method and NOT the \"event\" simulate method, because\n * the former takes care of simulating both individual \"down\" and \"up\" events.\n */\n if (DEBUG && DEBUGGER && keyCode == this.KEYCODE_ESC && this.dbg) this.dbg.halt();\n fPass = (fDown? !this.keyPressSimulate(keyCode) : false);\n }\n else {\n /*\n * Pass on everything else; I'll take care of this key at the keyPress stage, not the\n * the keyDown or keyUp stage.\n */\n fPass = true;\n /*\n * At this point, I have a difficult choice to make: leave fAutoClear true for any remaining\n * \"up\" events, so that keys will repeat immediately when released/pressed repeatedly (most\n * noticeable with the Enter key), or set fAutoClear to false to ensure that polling apps have\n * enough time to see every key press.\n *\n * I've decided that the former is more important than the latter, so if polling apps are still\n * missing keystrokes, then perhaps nCyclesThreshold needs to be supplemented in some way.\n *\n * fAutoClear = false;\n */\n }\n\n if (fAutoClear) {\n /*\n * When you use a command like COMMAND-T, I see the COMMAND key going down, but not going up,\n * so I think the COMMAND key is still down and ignore all input; to easily get out of that state,\n * I clear our internal BIT_COMMAND whenever I see ANY key go up (well, ALMOST any key; cases\n * above that explicitly clear fAutoClear -- such as the COMMAND key itself -- are exceptions\n * to the rule).\n */\n this.bitsShift &= ~this.BIT_COMMAND;\n /*\n * I don't reliably get keyDown/keyUp events for all keys on all devices, but for those devices that\n * I DO, it seems like a good idea to cancel any pending key \"up\" simulation on receipt of the actual\n * keyUp event.\n *\n * However, the following code is problematic for Safari on iOS devices, which as noted above, doesn't\n * generate keyDown/keyUp events until after the press operation is complete, and then they are generated\n * in rapid succession, which doesn't give the C1P enough time to detect the key. So I simply don't do\n * this on iOS devices.\n */\n if (!this.fMobile && keyCode == this.prevKeyDown) this.autoClear();\n }\n\n if (fPass === undefined) {\n fPass = !this.keyEventSimulate(keyCode, fDown, this.SIMCODE_KEYEVENT);\n }\n\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(this.dbg.MESSAGE_KBD)) {\n this.dbg.message(/*(fDown?\"\\n\":\"\") +*/ \"key\" + (fDown?\"Down\":\"Up\") + \"(\" + Str.toHexByte(keyCode) + \"): \" + (fPass? \"pass\" : \"consume\"));\n }\n return fPass;\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {Object} event\n * @return {boolean} true to pass the event along, false to consume it\n *\n * We've stopped relying on keyPress for keyboard emulation purposes, but it's still handy to hook and monitor\n * when debugging.\n */\n keyPress(event)\n {\n var fPass = true;\n /*\n * Browser-independent charCode extraction...\n */\n event = event || window.event;\n var charCode = event.which || event.keyCode;\n\n /*\n * Let's stop any injection currently in progress, too\n */\n this.sInjectBuffer = \"\";\n\n if (this.bitsShift & this.BIT_COMMAND)\n this.bitsShift &= ~this.BIT_COMMAND;\n else\n fPass = !this.keyPressSimulate(charCode);\n\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(this.dbg.MESSAGE_KBD)) {\n this.dbg.message(\"keyPress(\" + Str.toHexByte(charCode) + \"): \" + (fPass? \"pass\" : \"consume\"));\n }\n return fPass;\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {number} charCode\n * @return {boolean} true if successfully simulated, false if unrecognized/unsupported key\n */\n keyPressSimulate(charCode)\n {\n var fSimulated = false;\n if (charCode == this.CHARCODE_BREAK) {\n /*\n * The BREAK key is not wired up to the keyboard like the other keys are, but we simulate\n * it here, so that it can be injected like any other key.\n */\n if (this.cmp) {\n this.cmp.reset(true);\n fSimulated = true;\n }\n }\n else {\n /*\n * WARNING: The next line is why you cannot use SHIFT-N, SHIFT-O, SHIFT-P, etc. But without it,\n * iOS devices with the annoying \"autocapitalization\" feature enabled make the keyboard unusable\n * by default. The trade-off is: either require all iOS users to first tap the shift key to turn\n * \"autocapitalization\" off, or lose the ability to type any of the special shifted alphabetic keys.\n * I choose the latter, because I have friendlier aliases already defined for those keys (eg,\n * ^, DELETE, and @).\n *\n * Furthermore, by doing this for iOS (and Android) devices ONLY, other platforms retain the ability\n * to use those special key combos.\n */\n if (this.fMobile) {\n if (charCode >= 0x41 && charCode <= 0x5A)\n charCode += 0x20;\n }\n\n /*\n * Auto-clear any previous down key EXCEPT for charCode (because it may be held and repeating).\n */\n this.autoClear(charCode);\n\n if (this.keyEventSimulate(charCode, true, this.SIMCODE_KEYPRESS)) {\n /*\n * If CPU speed is unlimited, then we switch to an alternate approach, which is to immediately\n * queue a \"release\" event as well. The problem with the original timer-based approach at high\n * speeds is that the the CPU may get lucky and execute a LOT of instructions between delivery\n * of the keyPress event and the \"keyTimeout\" event. In that case, even enabling keyboard polling\n * detection in updateMemory() won't entirely help -- although we do that, too -- because JavaScript\n * events are delivered synchronously, so it may simply take too long for the \"keyTimeout\" event\n * to arrive.\n *\n * Why don't we ALWAYS do this? Because in the normal case (SPEED_SLOW, and even SPEED_FAST) we want\n * to faithfully simulate how long a key is held, so that features like auto-repeat work properly.\n * You'll notice in the SPEED_MAX case, holding a key no longer has any effect; even though multiple\n * keyPress events WILL arrive, if we simulate a release immediately after each one, then repeat\n * is defeated. Also, the keyboard polling detection code in updateMemory() doesn't work well for\n * all apps.\n */\n if (this.cpu.speed == this.cpu.SPEED_MAX) {\n this.keyEventSimulate(charCode, false, this.SIMCODE_KEYRELEASE);\n }\n else {\n var fRepeat = false;\n if (this.aKeyTimers[charCode]) {\n clearTimeout(this.aKeyTimers[charCode]);\n fRepeat = true;\n }\n var msDelay = this.calcReleaseDelay(fRepeat);\n this.aKeyTimers[this.prevCharDown = charCode] = setTimeout(function(kbd) { return function() {kbd.keyEventSimulate(charCode, false, kbd.SIMCODE_KEYTIMEOUT);}; }(this), msDelay);\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(this.dbg.MESSAGE_KBD)) {\n this.dbg.message(\"keyPressSimulate(\" + Str.toHexByte(charCode) + \"): setTimeout()\");\n }\n }\n fSimulated = true;\n }\n }\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(this.dbg.MESSAGE_KBD)) {\n this.dbg.message(\"keyPressSimulate(\" + Str.toHexByte(charCode) + \"): \" + (fSimulated? \"true\" : \"false\"));\n }\n return fSimulated;\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {number} charCode\n * @param {boolean} fDown\n * @param {number} simCode indicates the origin of the event\n * @return {boolean} true if successfully simulated, false if unrecognized/unsupported key\n */\n keyEventSimulate(charCode, fDown, simCode)\n {\n var fSimulated = false;\n if (!fDown) {\n this.aKeyTimers[charCode] = null;\n if (this.prevCharDown == charCode) this.prevCharDown = 0;\n }\n var bShift = 0;\n var bCode = this.aCharCodeMap[charCode];\n if (bCode === undefined) {\n /*\n * Perhaps we're dealing with a CTRL variation of an alphabetic key; this won't\n * affect non-CTRL-key combos like CR or LF, because they're defined in aCharCodeMap,\n * and this bit of code relieves us from having to explicitly define every CTRL-letter\n * possibility in aCharCodeMap. However, CTRL-anything-else is a different matter.\n */\n if (charCode >= 0x01 && charCode <= 0x1A) {\n charCode += 0x40;\n bShift = this.CHARCODE_CTRL;\n }\n bCode = this.aCharCodeMap[charCode];\n }\n if (bCode !== undefined) {\n var iRow = bCode >> 12;\n var iCol = (bCode >> 8) & 0xf;\n if (!bShift) bShift = bCode & 0xff;\n if (fDown) {\n this.abKbdCols[iRow] |= 1 << iCol;\n if (bShift == this.CHARCODE_CTRL)\n this.abKbdCols[0] |= this.BIT_CTRL;\n else\n if (bShift == this.CHARCODE_LSHIFT)\n this.abKbdCols[0] |= this.BIT_LSHIFT;\n else\n if (bShift == this.CHARCODE_RSHIFT)\n this.abKbdCols[0] |= this.BIT_RSHIFT;\n else\n this.abKbdCols[0] &= ~this.BITS_SIMULATE;\n }\n else {\n this.abKbdCols[iRow] &= ~(1 << iCol);\n this.abKbdCols[0] &= ~this.BITS_SIMULATE;\n this.abKbdCols[0] |= (this.bitsShift & this.BITS_SIMULATE);\n }\n var fPropagate = (simCode == this.SIMCODE_KEYPRESS && !this.aKbdStates.length);\n this.aKbdStates.push(this.abKbdCols.slice());\n this.updateMemory(fPropagate);\n fSimulated = true;\n }\n if (DEBUG && this.dbg) this.dbg.info(\"keyEventSimulate(\" + Str.toHexByte(charCode) + \",\" + (fDown?\"down\":\"up\") + \",\" + this.aSimCodeDescs[simCode] + \"): \" + (fSimulated? \"true\" : \"false\"));\n return fSimulated;\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {number} addr\n * @param {number|undefined} addrFrom (not defined whenever the Debugger tries to read the specified addr)\n *\n * NOTE: As long as we rely on the CPU processing a certain number of cycles (nCyclesThreshold) before\n * propagating the next kbd state, and not how many reads and/or writes the CPU has performed, we could\n * eliminate the overhead of this read-notification handler.\n *\n * It's useful for diagnostic purposes, which is why it's still here.\n */\n getByte(addr, addrFrom)\n {\n /*\n * Don't trigger any further hardware emulation (beyond what we've already stored in memory) if\n * the Debugger performed this read (need a special Debugger I/O command if/when you really want to do that).\n */\n if (DEBUG) {\n if (addrFrom !== undefined) {\n this.nReadsSinceLastEvent++;\n if (DEBUG && this.dbg) this.dbg.info(\"reading kbd \" + Str.toHexWord(addr) + \" @\" + this.cpu.getCycles() + \" cycles\");\n }\n }\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {number} addr\n * @param {number|undefined} addrFrom (not defined whenever the Debugger tries to write the specified addr)\n *\n * NOTE: Ordinarily, I wouldn't allow Debugger writes (addrFrom === undefined) to interfere with the simulated\n * hardware state, but for now, I find it useful to be able to prod the simulation code directly from the Debugger.\n */\n setByte(addr, addrFrom)\n {\n var b = this.cpu.getByte(addr);\n this.bKbdRows = b ^ this.bInvert;\n this.nWritesSinceLastEvent++;\n this.updateMemory(false, addr, b);\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {boolean} fPropagate is true to propagate immediately, false to use normal propagation\n * @param {number} [addr] is the memory address to update; default is the entire memory range\n * @param {number} [bWrite] is the value of any immediately preceding write, or undefined if none\n *\n * Update emulated keyboard memory. By updating the keyboard memory whenever it's written to,\n * as well as whenever a key is pressed or released, I avoid the hit of a read-notification handler.\n * Besides, read-notification handlers are called only AFTER the read has been performed, so it\n * would be too late to update the memory at that point.\n *\n * WARNING: There is a slight risk of an application reading from a different keyboard memory address\n * than it just wrote to. That would be legal, but very odd, and we save valuable time by not updating\n * every other byte in the entire memory range every time a different keyboard \"row\" is selected.\n */\n updateMemory(fPropagate, addr, bWrite)\n {\n /*\n * First, we determine if it's time for event propagation...\n */\n var nCycles = this.cpu.getCycles();\n\n /*\n * Monitoring the C1P's keyboard polling activity is problematic, because not all apps monitor\n * the keyboard in the same way. It's better to simply wait for a certain amount of CPU activity to\n * occur (nCyclesThreshold); it's more reliable and it scales well, because it's not affected by\n * how many cycles we're executing in real time. The trick is finding a value for nCyclesThreshold\n * that works well across the board.\n */\n if (!fPropagate) {\n if (this.cpu.speed == this.cpu.SPEED_MAX)\n fPropagate = (addr !== undefined && this.nWritesSinceLastEvent >= 32);\n else {\n /*\n * We have to handle the delta being less than zero, in case the user changed the speed, thereby\n * resetting the cycle count returned by getCycles().\n */\n var nCycleDelta = nCycles - this.nCyclesSinceLastEvent;\n fPropagate = (nCycleDelta < 0 || nCycleDelta >= this.nCyclesThreshold);\n }\n }\n\n /*\n * Next, we propagate any buffered state (in abKbdStates) as appropriate\n */\n if (fPropagate) {\n var abKbdCols = this.aKbdStates.shift();\n if (abKbdCols !== undefined) {\n if (DEBUG && this.dbg) this.dbg.info(\"kbd update @\" + nCycles + \" cycles, \" + this.nWritesSinceLastEvent + \" writes\");\n this.abKbdColsLast = abKbdCols;\n }\n this.nReadsSinceLastEvent = this.nWritesSinceLastEvent = 0;\n this.nCyclesSinceLastEvent = nCycles;\n }\n /*\n * Then we calculate the value (which may or may not have just been propagated),\n * based on the currently selected keyboard row(s) (bKbdRows).\n */\n var b = 0;\n for (var iRow=0; iRow < 8; iRow++) {\n if (!(this.bKbdRows & (1 << iRow)))\n continue;\n b |= this.abKbdColsLast[iRow];\n }\n /*\n * Now invert all the bits, since I SET the column bit of an \"active\" key,\n * whereas the C1P Model 600 keyboard expects \"active\" column bits to be CLEAR.\n */\n b ^= this.bInvert;\n\n if (addr !== undefined) {\n this.abMem[addr] = b;\n }\n else {\n addr = this.offKbd;\n if (b != this.bWriteLast) {\n for (var offset=addr; offset < this.offKbdLimit; offset++)\n this.abMem[offset] = b;\n }\n }\n this.bWriteLast = b;\n if (DEBUG && this.dbg) this.dbg.info(\"updating kbd \" + Str.toHexWord(addr) + \" with \" + Str.toHexByte(b) + (bWrite !== undefined? (\" following write \" + Str.toHexByte(bWrite)) : \"\") + \" @\" + nCycles + \" cycles\");\n }\n\n /**\n * isShift()\n *\n * @this {C1PKeyboard}\n * @param {number} charCode\n * @return {boolean}\n *\n isShift(charCode)\n {\n return charCode == this.CHARCODE_LSHIFT || charCode == this.CHARCODE_RSHIFT || charCode == this.CHARCODE_CTRL || charCode == this.CHARCODE_SHIFTLOCK;\n }\n */\n\n /**\n * C1PKeyboard.init()\n *\n * This function operates on every HTML element of class \"keyboard\", extracting the\n * JSON-encoded parameters for the C1PKeyboard constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a C1PKeyboard component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeKbd = Component.getElementsByClass(document, C1PJS.APPCLASS, \"keyboard\");\n for (var iKbd=0; iKbd < aeKbd.length; iKbd++) {\n var eKbd = aeKbd[iKbd];\n var parmsKbd = Component.getComponentParms(eKbd);\n var kbd = new C1PKeyboard(parmsKbd);\n Component.bindComponentControls(kbd, eKbd, C1PJS.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize every Keyboard module on the page.\n */\nWeb.onInit(C1PKeyboard.init);\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/video.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass C1PVideo extends Component {\n /**\n * C1PVideo(parmsVideo, canvas, context, imgChars)\n *\n * The Video component can be configured with the following (parmsVideo) properties:\n *\n * model: model number (one of: 540 or 600; 600 is the default)\n * screenWidth: width of the screen window, in pixels\n * screenHeight: height of the screen window, in pixels\n * charCols: number of character columns\n * charRows: number of character rows\n * charWidth: width of charSet characters, in pixels (default is 0)\n * charHeight: height of charSet characters, in pixels (default is 0)\n * charSet: path to image (eg, PNG) file that defines the character set\n * screenColor: background color of the screen window (default is black)\n *\n * The Video object assumes that the video buffer is organized such that offset 0 is mapped\n * to the left-most column and top-most row (col=0,row=0), offset 1 is (1,0), offset 2\n * is (2,0), and so on.\n *\n * The Video object initially contains no underlying video buffer; memory for the buffer\n * must be given to it by the Computer object. We allocate a separate buffer, called\n * the screen buffer, into which we periodically copy the contents of the video buffer\n * via updateScreen(); any differences between the two buffers are then rendered in the\n * associated window, via updateWindow().\n *\n * When updateScreen() finds a byte in the screen buffer must be redisplayed, it converts\n * the offset of that byte into a (col,row) character position for the updateWindow() function,\n * which then converts (col,row) into (x,y) pixel offsets within the underlying canvas.\n *\n * Regarding the C1P (aka Model 600): The C1P has a 1K video buffer located at 0xD000-0xD3FF.\n * The ROM draws the initial \"D/C/W/M ?\" prompt at the \"bottom\" of the video buffer at location\n * 0xD365. That row really begins at 0xD360, but the C1P \"indents\" everything by 5 columns due\n * to the lack of a \"guard band feature.\" Similarly, BASIC defaults to a width of 24 columns\n * avoid display problems near the right edge. BASIC will let you choose a width SMALLER than\n * 24 but not larger. So, while the video buffer supports a theoretical maximum of 32 rows x 32\n * columns, the practical maximum is 25 rows x 24 columns; the last 4 rows of the video buffer\n * are never used, and while content DOES scroll through the top 3 lines of the buffer, it should\n * never be assumed that you can see the top 3 lines.\n *\n * This is partially confirmed by the \"C1P Character Graphics Reference Manual\", p3, which says\n * that the \"the visible character field consists of 25 lines of 25 columns\" and that the \"first\n * visible character in the upper left of the screen is accessed via address 53379,\" or 0xD083.\n * However, they were wrong about both the number of columns and the first visible character.\n *\n * They probably meant 0xD085, because as mentioned earlier, the C1P indents every row by 5\n * characters, not 3. But that's not correct either, because the difference between 0xD365\n * (where the bottom line starts) and 0xD085 is 0x2E0, or 736. 736 divided by 32 equals 23;\n * add the bottom row, and that would give you 24 visible rows, not 25. Since we now have\n * screenshots of a C1P monitor displaying 25 rows (courtesy of Stephan Mühlstrasser), C1Pjs\n * now assumes that only the first 3 lines are not visible, and that the address of the first\n * visible character is actually 0xD065 (53349), yielding 25 visible rows.\n *\n * All of this explains why we now use setDimensions(iRowTop=3, nRowsVisible=25) instead of\n * setDimensions(iRowTop=4, nRowsVisible=24) for the Model 600.\n *\n * Model 540 Video Board vs. Model 600 \"Superboard II\"\n * ---------------------------------------------------\n * This emulation was originally written for the Model 600 \"Superboard II\" (eg, Challenger 1P).\n * Support for the Model 540 video board (as used in the Challenger II-4P and II-8P) was added\n * later.\n *\n * NOTE: When Model 540 video emulation is enabled, Model 542 keyboard emulation must also be\n * enabled, because the former always came with the latter keyboard interface; this is why when\n * we call this.setModel(540), we must also notify the Keyboard via kbd.setModel(542).\n *\n * Key features/differences of the Model 540 video board include:\n *\n * 2K (8 pages) of video memory located at 0xD000-0xD7FF\n * Two display modes: 32 rows x 64 cols (default on power up), and 32 rows x 32 cols\n * 64 bytes per screen row, regardless which display mode is selected\n * The following options can be selected via WRITE to port address 0xDE00:\n * Bit 0: clear to enable 32/64 mode (default on power up), set to enable 32/32\n * Bit 1: 1=tone on (542 keyboard)\n * Bit 2: 1=color on (Rev. B only?)\n * bit 3: 1=enable 38-40Khz AC Home control output (Rev. B only?)\n * Video timing counter status via READ from port address 0xDE00:\n * Bit 7: 0 for 1/120 second, then 1 for 1/120 second, based on video clock (60Hz)\n *\n * @this {C1PVideo}\n * @param {Object} parmsVideo\n * @param {HTMLCanvasElement} canvas\n * @param {CanvasRenderingContext2D} context\n * @param {HTMLImageElement} imgChars\n */\n constructor(parmsVideo, canvas, context, imgChars)\n {\n super(\"C1PVideo\", parmsVideo);\n\n this.nDefaultModel = parmsVideo['model'];\n this.nDefaultCols = parmsVideo['charCols'];\n this.nDefaultRows = parmsVideo['charRows'];\n\n this.cxScreen = parmsVideo['screenWidth'];\n this.cyScreen = parmsVideo['screenHeight'];\n\n /*\n * These (source) character dimensions are tentative, and may not even be provided,\n * but they will become definitive once imgChars has finished loading and setReady() is called.\n */\n this.cxChar = parmsVideo['charWidth'];\n this.cyChar = parmsVideo['charHeight'];\n\n /*\n * This is a preliminary call to setDimensions(), to initialize default screen buffer and\n * window dimensions. A more extensive call to setDimensions() will take place when setModel()\n * is called later, from reset() and possibly via the tripGuard() handler.\n *\n * This preliminary call merely establishes a default screen buffer size, so that when\n * setBuffer() is called, it's able to verify the assigned address space is at least as big\n * as the screen buffer.\n */\n this.setDimensions();\n\n this.canvasScreen = canvas;\n this.contextScreen = context;\n this.imgChars = imgChars;\n\n /*\n * Support for disabling (or, less commonly, enabling) image smoothing, which all browsers\n * seem to support now (well, OK, I still have to test the latest MS Edge browser), despite\n * it still being labelled \"experimental technology\". Let's hope the browsers standardize\n * on this. I see other options emerging, like the CSS property \"image-rendering: pixelated\"\n * that's apparently been added to Chrome. Sigh.\n */\n var i, sEvent, asWebPrefixes = ['', 'moz', 'ms', 'webkit'];\n var fSmoothing = parmsVideo['smoothing'];\n var sSmoothing = Web.getURLParm('smoothing');\n if (sSmoothing) fSmoothing = (sSmoothing == \"true\");\n if (fSmoothing != null) {\n for (i = 0; i < asWebPrefixes.length; i++) {\n sEvent = asWebPrefixes[i];\n if (!sEvent) {\n sEvent = 'imageSmoothingEnabled';\n } else {\n sEvent += 'ImageSmoothingEnabled';\n }\n if (this.contextScreen[sEvent] !== undefined) {\n this.contextScreen[sEvent] = fSmoothing;\n break;\n }\n }\n }\n\n /*\n * QUESTION: Does this video port exist only on the Model 540?\n */\n this.addrVideoPort = 0xDE00; // WARNING: Hard-coded port address -JP\n }\n\n /**\n * @this {C1PVideo}\n * @param {boolean} [fPowerOn] is true for the initial reset, so that we have\n * the option of rendering \"random\" graphic characters, just like the real machine would do.\n */\n reset(fPowerOn)\n {\n this.setModel(this.nDefaultModel);\n\n if (this.abMem) {\n /*\n * Let's treat every reset like a power-cycle, just for fun.\n * If you don't think that's fun, then simply remove the next line.\n *\n fPowerOn = true;\n */\n for (var offset = this.offVideo; offset < this.offVideoLimit; offset++) {\n var b = (fPowerOn? Math.floor(Math.random() * 256) : 0x20);\n\n this.abMem[offset] = b;\n }\n }\n }\n\n /**\n * @this {C1PVideo}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"refresh\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n switch(sBinding) {\n case \"refresh\":\n this.bindings[sBinding] = control;\n control.onclick = function(video) {\n return function() {\n if (DEBUG) video.println(\"refreshScreen()\");\n video.initScreen();\n video.updateScreen();\n };\n }(this);\n return true;\n default:\n break;\n }\n return false;\n }\n\n /**\n * @this {C1PVideo}\n * @param {Array} abMemory\n * @param {number} start\n * @param {number} end\n * @param {C1PCPU} cpu\n */\n setBuffer(abMemory, start, end, cpu)\n {\n this.abMem = abMemory;\n this.offVideo = start;\n this.cbVideo = end - start + 1;\n this.offVideoLimit = this.offVideo + this.cbVideo;\n\n if (cpu) {\n this.cpu = cpu;\n if (this.addrVideoPort !== undefined) {\n cpu.addReadNotify(this.addrVideoPort, this.addrVideoPort, this, this.getByte);\n cpu.addWriteNotify(this.addrVideoPort, this.addrVideoPort, this, this.setByte);\n }\n }\n this.reset(true);\n }\n\n /**\n * @this {C1PVideo}\n * @param {number|undefined} [nCols] (default is nDefaultCols)\n * @param {number|undefined} [nRows] (default is nDefaultRows)\n * @param {number|undefined} [iRowTop] (eg, 4; default is 0)\n * @param {number|undefined} [nRowsVisible] (eg, 24; default is nRows)\n */\n setDimensions(nCols, nRows, iRowTop, nRowsVisible)\n {\n this.nCols = (nCols !== undefined? nCols : this.nDefaultCols);\n this.nRows = (nRows !== undefined? nRows : this.nDefaultRows);\n this.cbScreen = this.nCols * this.nRows;\n this.offVideoLimit = this.offVideo + this.cbScreen;\n /*\n * Set the first visible row and total visible rows next\n */\n this.iRowTop = (iRowTop !== undefined? iRowTop : 0);\n this.nRowsVisible = (nRowsVisible !== undefined? nRowsVisible : nRows);\n this.setDrawingDimensions();\n }\n\n /**\n * @this {C1PVideo}\n *\n * cxScreen and cyScreen give us the overall dimensions of the destination surface. Dividing that by the number of\n * columns and rows yields a target cell size (cxCharDst,cyCharDst), which may or may not map 1-1 to the source cell size\n * (cxChar,cyChar).\n */\n setDrawingDimensions()\n {\n this.cxCharDst = Math.floor(this.cxScreen / this.nCols);\n this.cyCharDst = Math.floor(this.cyScreen / this.nRowsVisible);\n }\n\n /**\n * @this {C1PVideo}\n */\n setFocus()\n {\n this.canvasScreen.focus();\n }\n\n /**\n * @this {C1PVideo}\n * @param {number} nModel\n */\n setModel(nModel)\n {\n this.nModel = nModel;\n /*\n * Default to model 600 behavior (1K video buffer);\n * the only other supported model is 540 (2K video buffer).\n */\n if (this.nModel == 600) {\n this.setDimensions(this.nDefaultCols, this.nDefaultRows, 3, 25);\n if (this.cbScreen == 1024 && this.cpu) {\n /*\n * NOTE: We deliberately set the guard address to the LAST byte of the 2K\n * buffer range, not the FIRST byte, which has the same effect but with the\n * added benefit of deferring any screen update until after the \"Model 540\"\n * screen initialization code has completely blanked the entire 2K buffer,\n * avoiding a brief flicker of unsightly characters.\n */\n this.addrGuard = this.offVideoLimit + this.cbScreen - 1;\n this.cpu.addWriteNotify(this.addrGuard, this.addrGuard, this, this.tripGuard);\n }\n }\n else {\n this.println(\"updated video model: \" + this.nModel);\n this.setDimensions(64, 32);\n }\n this.initScreen();\n this.updateScreen();\n }\n\n /**\n * @this {C1PVideo}\n * @param {boolean} fOn\n * @param {C1PComputer} cmp\n */\n setPower(fOn, cmp)\n {\n /*\n * NOTE: No one should be calling power(true) before first checking isReady(), but we check\n * it ourselves, too. This also means that updateScreen() need check only fPower and not isReady(),\n * since we guarantee that the former implies the latter.\n */\n if (fOn && !this.flags.powered && this.isReady()) {\n this.flags.powered = true;\n if (DEBUGGER) this.dbg = cmp.getComponentByType(\"debugger\");\n /*\n * If we have an associated keyboard, then ensure that the keyboard will be notified whenever\n * the canvas gets focus and receives input.\n *\n * Also, when simulating a Model 540 video board, we need to access to the Keyboard component due\n * to some shared I/O responsibilities; ie, bit 1 of the video control port at 0xDE00 enables whatever\n * tone has been selected via the keyboard frequency port at 0xDF01 (frequency == 49152/n, where n\n * is the value stored at 0xDF01).\n */\n this.kbd = cmp.getComponentByType(\"keyboard\");\n if (this.kbd) {\n this.kbd.setBinding(\"canvas\", \"keyDown\", this.canvasScreen);\n this.kbd.setBinding(\"canvas\", \"keyPress\", this.canvasScreen);\n this.kbd.setBinding(\"canvas\", \"keyUp\", this.canvasScreen);\n }\n }\n else\n if (!fOn && this.flags.powered) {\n this.flags.powered = false;\n /*\n * This is where we would add some method of blanking the display, without the disturbing the video\n * buffer contents, and blocking all further updates to the display.\n */\n }\n }\n\n /**\n * cxChar and cyChar are the source cell size. Originally, those values came strictly from the parmsVideo\n * 'charWidth' and 'charHeight' properties. Now, if those aren't defined (which is normally the case now),\n * then we infer the source cell size from the dimensions of imgChars, which is expected to be a 16x16 array of\n * character bitmaps. We could be even more flexible, by allowing imgChars to be any rectangular dimension\n * (eg, 1x256) as long as we can assume it contains exactly 256 characters, but there's no need to get carried away.\n *\n * @this {C1PVideo}\n * @param {boolean} [fReady] is assumed to indicate \"ready\" unless EXPLICITLY set to false\n */\n setReady(fReady)\n {\n if (!this.cxChar) this.cxChar = Math.floor(this.imgChars.width / 16);\n if (!this.cyChar) this.cyChar = Math.floor(this.imgChars.height / 16);\n super.setReady();\n }\n\n /**\n * @this {C1PVideo}\n * @param {number} addr (ie, addrVideoPort)\n * @param {number|undefined} addrFrom (not defined whenever the Debugger tries to read the specified addr)\n *\n * NOTE: Ordinarily, I wouldn't allow Debugger writes (addrFrom === undefined) to interfere with the simulated\n * hardware state, but for now, I find it useful to be able to prod the simulation code directly from the Debugger.\n */\n getByte(addr, addrFrom)\n {\n var b = this.cpu.getByte(addr);\n if (addrFrom !== undefined) {\n if (DEBUGGER && this.dbg) this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_VIDEO);\n }\n /*\n * The only documented READ bit in addrVideoPort is bit 7, which is supposed to alternate between\n * 0 and 1 every 1/120 of a second. There's no way we're going to add special code to the emulator to update\n * this stupid byte every 8,333 cycles (assuming 1Mhz operation), so clearly we're going to fake it.\n *\n * Faking it means that any polling code will unavoidably get a stale value the FIRST time it reads bit 7.\n * However, we can still do a pretty good job of faking any EXTENSIVE polling: get the number of cycles\n * executed so far, divide that by 8333, floor the quotient, and then set/clear bit 7 according to whether the\n * result is odd/even.\n */\n var nCyclesHigh = Math.floor(this.cpu.getCycles() / 8333);\n this.cpu.setByte(addr, (b & 0x7F) | ((nCyclesHigh & 0x1)? 0x80 : 0));\n }\n\n /**\n * @this {C1PVideo}\n * @param {number} addr (ie, addrVideoPort)\n * @param {number|undefined} addrFrom (not defined whenever the Debugger tries to write the specified addr)\n */\n setByte(addr, addrFrom)\n {\n if (addrFrom !== undefined) {\n if (DEBUGGER && this.dbg) this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_VIDEO);\n }\n }\n\n /**\n * @this {C1PVideo}\n * @param {number} addr (ie, addrGuard)\n * @param {number|undefined} addrFrom (not defined whenever the Debugger tries to read the specified addr)\n */\n tripGuard(addr, addrFrom)\n {\n /*\n * Don't trigger any further hardware emulation (beyond what we've already stored in memory) if\n * the Debugger performed this read (need a special Debugger I/O command if/when you really want to do that).\n */\n if (addrFrom !== undefined) {\n if (DEBUGGER && this.dbg) this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_VIDEO, true);\n /*\n * The CPU has just written to the guard address we established just beyond the video buffer's 1K boundary,\n * implying that the system thinks we have a 2K buffer instead. So we bump our model to 540, bump the\n * associated keyboard model to 542, and remove this guard handler.\n */\n this.setModel(540);\n if (this.kbd) this.kbd.setModel(542);\n this.cpu.removeWriteNotify(this.addrGuard, this.addrGuard, this, this.tripGuard);\n }\n }\n\n /**\n * @this {C1PVideo}\n */\n initScreen()\n {\n this.abScreen = new Array(this.cbScreen);\n for (var offset=0; offset <= this.cbScreen; offset++) {\n this.abScreen[offset] = -1; // initialize every cell of the screen to an invalid value\n }\n }\n\n /**\n * updateScreen() updates the screen buffer from the video buffer and updates the window with any changes.\n *\n * @this {C1PVideo}\n * @return {boolean}\n *\n * For every byte in the video buffer, this renders it if it differs from the byte stored in the screen buffer,\n * and then updates the screen buffer to match. Since initScreen() sets every byte in the screen buffer\n * to an illegal byte value (ie, a value which is outside the byte range 0x00-0xff), that assures the first call\n * to updateScreen() will redraw every byte in the video buffer.\n */\n updateScreen()\n {\n var offset = 0;\n if (this.flags.powered) {\n while (offset < this.cbScreen) {\n var b = this.abMem[this.offVideo + offset];\n if (this.abScreen[offset] != b) {\n if (!this.writeByte(offset, b)) {\n break;\n }\n this.abScreen[offset] = b;\n }\n offset++;\n }\n }\n return (offset == this.cbScreen);\n }\n\n /**\n * @this {C1PVideo}\n * @param {number} offset\n * @param {number} b\n * @return {boolean}\n */\n writeByte(offset, b)\n {\n var col = offset % this.nCols;\n var row = Math.floor(offset / this.nCols);\n return this.updateWindow(col, row, b);\n }\n\n /**\n * updateWindow(col, row, b)\n *\n * Updates a particular position (row,col) in the associated window with the given byte (b)\n *\n * @this {C1PVideo}\n * @param {number} col\n * @param {number} row\n * @param {number} b\n * @return {boolean} true if successful, false if not\n *\n * I originally used (screenWidth,screenHeight) == (512,448) and (cols,rows) == (32,32) and (cxChar,cyChar) == (16,16),\n * and I simply copied the source cells 1-to-1 to the destination (16,16), knowing that we would never try to display\n * more than 28 rows (the last 4 rows of the 32 possible rows were never used to display any content). However, I should\n * still have ignored any attempt to draw past row 28 (aka screenHeight 448). I now perform row clipping and biasing,\n * according to the first visible row (iRowTop) and total visible rows (nRowsVisible).\n *\n * Moreover, I no longer copy the source cell images to the destination 1-to-1. I calculate (cxCharDst,cyCharDst)\n * separately (see setDrawingDimensions). And I no longer assume that (cxChar,cyChar) are (16,16); once the source\n * image file has finished loading, I calculate (cxChar,cyChar) based on the size of image file (see setReady). I made\n * this change when I created chargen1x.png. In fact, at first I thought I might be able to eliminate chargen2x.png\n * and just let drawImage() scale up the individual character images from (8,8) to (16,16) or whatever (cxCharDst,cyCharDst)\n * size was needed, but the results were fuzzy, so it's still best to use chargen2x.png when using larger window sizes.\n */\n updateWindow(col, row, b)\n {\n if (row >= this.iRowTop) {\n row -= this.iRowTop;\n if (row < this.nRowsVisible) {\n var xChar = (b * this.cxChar);\n var ySrc = Math.floor(xChar / this.imgChars.width) * this.cyChar;\n var xSrc = xChar % this.imgChars.width;\n var xDst = col * this.cxCharDst;\n var yDst = row * this.cyCharDst;\n // if (DEBUG) this.log(\"updateWindow(\" + col + \",\" + row + \",\" + b +\"): drawing from \" + xSrc + \",\" + ySrc + \" to \" + xDst + \",\" + yDst);\n this.contextScreen.drawImage(this.imgChars, xSrc, ySrc, this.cxChar, this.cyChar, xDst, yDst, this.cxCharDst, this.cyCharDst);\n }\n }\n return true;\n }\n\n /**\n * C1PVideo.init()\n *\n * This function operates on every HTML element of class \"video\", extracting the\n * JSON-encoded parameters for the C1PVideo constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a C1PVideo component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeVideo = Component.getElementsByClass(document, C1PJS.APPCLASS, \"video\");\n for (var iVideo=0; iVideo < aeVideo.length; iVideo++) {\n var eVideo = aeVideo[iVideo];\n var parmsVideo = Component.getComponentParms(eVideo);\n\n /*\n * As noted in keyboard.js, the keyboard on an iOS device pops up with the SHIFT key depressed,\n * which is not the initial keyboard state that the C1P expects. I originally tried to fix that by\n * adding an 'autocapitalize=\"off\"' attribute alongside the 'contenteditable=\"true\"' attribute\n * on the <canvas> element, but apparently Safari honors that only inside certain elements (eg, <input>).\n *\n * I've since settled on a better work-around in keyboard.js, so I've stopped worrying about how to make\n * \"autocapitalize\" work here.\n */\n var eCanvas = /** @type {HTMLCanvasElement} */ (document.createElement(\"canvas\"));\n if (eCanvas === undefined || !eCanvas.getContext) {\n eVideo.innerHTML = \"<br/>Missing <canvas> support. Please try a newer web browser.\";\n return;\n }\n eCanvas.setAttribute(\"class\", C1PJS.APPCLASS + \"-canvas\");\n eCanvas.setAttribute(\"width\", parmsVideo['screenWidth']);\n eCanvas.setAttribute(\"height\", parmsVideo['screenHeight']);\n\n eCanvas.setAttribute(\"contenteditable\", \"true\");\n eCanvas.setAttribute(\"autocapitalize\", \"off\");\n eCanvas.setAttribute(\"autocorrect\", \"off\");\n eCanvas.style.backgroundColor = parmsVideo['screenColor'];\n\n /*\n * HACK: A canvas style of \"auto\" provides for excellent responsive canvas scaling in EVERY browser\n * except IE9/IE10, so I recalculate the appropriate CSS height every time the parent DIV is resized;\n * IE11 works without this hack, so we take advantage of the fact that IE11 doesn't report itself as \"MSIE\".\n */\n eCanvas.style.height = \"auto\";\n if (Web.getUserAgent().indexOf(\"MSIE\") >= 0) {\n eCanvas.style.height = (((eVideo.clientWidth * parmsVideo['screenHeight']) / parmsVideo['screenWidth']) | 0) + \"px\";\n eVideo.onresize = function(eParent, eChild, cx, cy) {\n return function() {\n eChild.style.height = (((eParent.clientWidth * cy) / cx) | 0) + \"px\";\n };\n }(eVideo, eCanvas, parmsVideo['screenWidth'], parmsVideo['screenHeight']);\n }\n eVideo.appendChild(eCanvas);\n\n /*\n * Now we can create the Video object, record it, and wire it up to the associated document elements.\n *\n * Regarding \"new Image()\", see https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement.Image:\n *\n * This constructor exists for historical reasons only and returns an HTMLImageElement instance just as\n * document.createElement('img') would.\n */\n var imgCharSet = new Image();\n var eContext = /** @type {CanvasRenderingContext2D} */ (eCanvas.getContext(\"2d\"));\n var video = new C1PVideo(parmsVideo, eCanvas, eContext, imgCharSet);\n imgCharSet.onload = function(video, sCharSet) {\n return function() {\n if (DEBUG) video.log(\"onload(): finished loading \" + sCharSet);\n video.setReady();\n };\n }(video, parmsVideo['charSet']); // jshint ignore:line\n imgCharSet.src = parmsVideo['charSet'];\n\n /*\n * Bind any video-specific controls (eg, the Refresh button). There are no essential controls, however;\n * even the \"Refresh\" button is just a diagnostic tool, to verify that the screen contents are up-to-date.\n */\n Component.bindComponentControls(video, eVideo, C1PJS.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize every Video module on the page.\n */\nWeb.onInit(C1PVideo.init);\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/serial.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass C1PSerialPort extends Component {\n /**\n * C1PSerialPort(parmsSerial)\n *\n * The SerialPort component has no component-specific parameters.\n *\n * @this {C1PSerialPort}\n * @param {Object} parmsSerial\n */\n constructor(parmsSerial)\n {\n super(\"C1PSerialPort\", parmsSerial);\n\n this.flags.powered = false;\n this.fDemo = parmsSerial['demo'];\n\n this.reset(true);\n }\n\n /**\n * @this {C1PSerialPort}\n * @param {boolean} [fHard]\n */\n reset(fHard)\n {\n /*\n * Because we reset the machine at the start of a 6502 HEX command file auto-load,\n * we must avoid tossing the serial port's input buffer in that particular case (2).\n */\n if (fHard || this.autoLoad != C1PSerialPort.AUTOLOAD_6502) {\n\n this.bInput = -1;\n this.iInput = 0;\n this.sInput = \"\";\n if (this.fDemo) {\n this.sInput = \"10 PRINT \\\"HELLO OSI #\" + this.getMachineNum() + \"\\\"\\n\";\n }\n\n // this.sOutput = new Array(0);\n // this.iOutputNext = 0;\n\n this.fConvertLF = true;\n this.autoLoad = C1PSerialPort.AUTOLOAD_NONE;\n }\n }\n\n /**\n * @this {C1PSerialPort}\n */\n start()\n {\n if (this.kbd && this.fDemo) {\n this.kbd.injectKeys(\" C\\n\\n\", 3000); // override the default injection delay (currently 300ms)\n setTimeout(function(serial) { return function() {serial.startLoad();}; }(this), 12000);\n }\n this.fDemo = false;\n }\n\n /**\n * @this {C1PSerialPort}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"listSerial\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var serial = this;\n\n switch(sBinding) {\n\n case \"listSerial\":\n this.bindings[sBinding] = control;\n return true;\n\n case \"loadSerial\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickLoadSerial(event) {\n if (serial.bindings[\"listSerial\"]) {\n var sFile = serial.bindings[\"listSerial\"].value;\n // serial.println(\"loading \" + sFile + \"...\");\n Web.getResource(sFile, null, true, function(sURL, sResponse, nErrorCode) {\n serial.loadFile(sURL, sResponse, nErrorCode);\n });\n }\n };\n return true;\n\n case \"mountSerial\":\n /*\n * Check for non-mobile (desktop) browser and the availability of FileReader\n */\n var controlInput = /** @type {Object} */ (control);\n if (!Web.isMobile() && window && 'FileReader' in window) {\n this.bindings[sBinding] = controlInput;\n /*\n * Enable \"Mount\" button only if a file is actually selected\n */\n controlInput.onchange = function onChangeMountSerial() {\n var fieldset = controlInput.children[0];\n var files = fieldset.children[0].files;\n var submit = fieldset.children[1];\n submit.disabled = !files.length;\n };\n controlInput.onsubmit = function onSubmitMountSerial(event) {\n var file = event.currentTarget[1].files[0];\n\n var reader = new FileReader();\n reader.onload = function() {\n // serial.println(\"mounting \" + file.name + \"...\");\n serial.loadFile(file.name, reader.result.toString(), 0);\n };\n reader.readAsText(file);\n\n /*\n * Prevent reloading of web page after form submission\n */\n return false;\n };\n }\n else {\n if (DEBUG) this.log(\"Local file support not available\");\n controlInput.parentNode.removeChild(/** @type {Node} */ (controlInput));\n }\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * @this {C1PSerialPort}\n * @param {Array} abMemory\n * @param {number} start\n * @param {number} end\n * @param {C1PCPU} cpu\n */\n setBuffer(abMemory, start, end, cpu)\n {\n this.abMem = abMemory;\n this.offPort = start;\n this.cbPort = end - start + 1;\n this.offPortLimit = this.offPort + this.cbPort;\n if ((this.cpu = cpu)) {\n cpu.addReadNotify(start, end, this, this.getByte);\n cpu.addWriteNotify(start, end, this, this.setByte);\n }\n this.setReady();\n }\n\n /**\n * @this {C1PSerialPort}\n * @param {boolean} fOn\n * @param {C1PComputer} cmp\n *\n * We make a note of the Computer component, so that we can invoke its reset() method whenever we need to\n * simulate a warm start, and we query the Keyboard component so that we can use its injectKeys() function.\n */\n setPower(fOn, cmp)\n {\n if (fOn && !this.flags.powered) {\n this.flags.powered = true;\n this.cmp = cmp;\n this.kbd = cmp.getComponentByType(\"keyboard\");\n if (DEBUGGER) this.dbg = cmp.getComponentByType(\"debugger\");\n }\n }\n\n /**\n * @this {C1PSerialPort}\n */\n startLoad()\n {\n this.autoLoad = C1PSerialPort.AUTOLOAD_BASIC;\n this.kbd.injectKeys(\"LOAD\\n\");\n }\n\n /**\n * @this {C1PSerialPort}\n * @param {string} sFileName\n * @param {string} sFileData (null if getResource() encountered an error)\n * @param {number} nResponse from server\n */\n loadFile(sFileName, sFileData, nResponse)\n {\n if (!sFileData) {\n this.println(\"Error loading file \\\"\" + sFileName + \"\\\" (\" + nResponse + \")\");\n return;\n }\n\n this.iInput = 0;\n this.sInput = sFileData;\n this.fConvertLF = true;\n this.autoLoad = C1PSerialPort.AUTOLOAD_NONE;\n\n /*\n * The following code adds support for loading \"65V\" files encoded as JSON, which is a cleaner\n * way to store and deliver those files when they contain binary (non-ASCII) data.\n *\n * For example, my 6502 ASSEMBLER/DISASSEMBLER program starts with a conventional \"65V\" loading\n * sequence, which loads and launches a small program loader that loads the rest of the program\n * using a raw (1-to-1) binary format instead of the usual (3-to-1) HEX format used by \"65V\" files.\n *\n * The \"rawness\" of the binary format also necessitates disabling fConvertLF.\n */\n if (Str.endsWith(sFileName, \".json\")) {\n try {\n /*\n * The most likely source of any exception will be here: parsing the JSON-encoded data.\n */\n var s = \"\";\n var data = eval(\"(\" + sFileData + \")\");\n var ab = data['bytes'];\n for (var i = 0; i < ab.length; i++) {\n s += String.fromCharCode(ab[i]);\n }\n this.sInput = s;\n this.fConvertLF = false;\n } catch (e) {\n this.println(\"Error processing file \\\"\" + sFileName + \"\\\": \" + e.message);\n return;\n }\n }\n\n if (this.cmp && this.kbd && this.cpu.isRunning()) {\n this.println(\"auto-loading \" + sFileName);\n /*\n * QUESTION: Is this setFocus() call strictly necessary? We're being called in the\n * context of getResource(), not some user action. If there was an original user action,\n * then the handler for THAT action should take care to switch focus back, not us.\n */\n this.cpu.setFocus();\n /*\n * We interpret the presence of a \".\" at the beginning of the file as a \"65V Monitor\"\n * address-mode command, and consequently treat the file as 6502 HEX command file.\n *\n * Anything else is treated as commands for the BASIC interpreter, which we re-initialize\n * with \"NEW\" and \"LOAD\" commands. To prevent that behavior, halt the CPU, perform the load,\n * and then start it running again. BASIC will start reading the data as soon as you type\n * LOAD.\n */\n if (this.sInput.charAt(0) != '.') {\n this.autoLoad = C1PSerialPort.AUTOLOAD_BASIC;\n this.kbd.injectKeys(\"NEW\\nLOAD\\n\");\n }\n else {\n /*\n * Set autoLoad to AUTOLOAD_6502 before the reset, so that when our reset() method is called,\n * we'll take care to preserve all the data we just loaded.\n */\n this.autoLoad = C1PSerialPort.AUTOLOAD_6502;\n /*\n * Although the Keyboard allows us to inject any key, even the BREAK key, like so:\n *\n * this.kbd.injectKeys(String.fromCharCode(this.kbd.CHARCODE_BREAK))\n *\n * it's easier to initiate a reset() ourselves and then start the machine-language load process\n */\n this.cmp.reset(true);\n this.kbd.injectKeys(\"ML\");\n }\n }\n else {\n this.println(sFileName + \" ready to load\");\n }\n }\n\n /**\n * @this {C1PSerialPort}\n * @param {number} addr\n * @param {number|undefined} addrFrom (not defined whenever the Debugger tries to read the specified addr)\n */\n getByte(addr, addrFrom)\n {\n /*\n * Don't trigger any further hardware emulation (beyond what we've already stored in memory) if\n * the Debugger performed this read (need a special Debugger I/O command if/when you really want to do that).\n */\n if (addrFrom !== undefined) {\n /*\n * WARNING: All I need to do for now is load the COM interface's \"data byte\"\n * with the next byte from the virtual cassette data stream -JP\n */\n if (!(addr & 0x01)) {\n /*\n * An EVEN address implies they're looking, so if we have a fresh buffer,\n * then prime the pump.\n */\n if (this.sInput && !this.iInput)\n this.advanceInput();\n } else {\n /*\n * An ODD address implies they just grabbed a data byte, so prep the next data byte.\n */\n this.advanceInput();\n }\n }\n }\n\n /**\n * @this {C1PSerialPort}\n * @param {number} addr\n * @param {number|undefined} addrFrom (not defined whenever the Debugger tries to write the specified addr)\n */\n setByte(addr, addrFrom)\n {\n /*\n * Don't trigger any further hardware emulation (beyond what we've already stored in memory) if\n * the Debugger performed this write (need a special Debugger I/O command if/when you really want to do that).\n */\n if (addrFrom !== undefined) {\n if (DEBUGGER && this.dbg) this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_SERIAL, true);\n /*\n * WARNING: I don't yet care what state the CPU puts the port into. When it's time to support serial output,\n * obviously that will become an issue.\n */\n }\n }\n\n /**\n * @this {C1PSerialPort}\n */\n advanceInput()\n {\n if (this.sInput !== undefined) {\n this.bInput = -1;\n if (this.iInput < this.sInput.length) {\n var b = this.sInput.charCodeAt(this.iInput++) & 0xff;\n if (this.fConvertLF) {\n if (b == 0x0a) b = 0x0d;\n }\n this.bInput = b;\n // if (DEBUG) this.log(\"advanceInput(\" + Str.toHexByte(b) + \")\");\n }\n else {\n this.sInput = \"\";\n this.iInput = 0;\n if (DEBUG) this.log(\"advanceInput(): out of data\");\n if (this.autoLoad == C1PSerialPort.AUTOLOAD_BASIC && this.kbd) {\n this.kbd.injectKeys(\" \\nRUN\\n\");\n }\n this.autoLoad = C1PSerialPort.AUTOLOAD_NONE;\n }\n this.updateMemory();\n }\n // else if (DEBUG) this.log(\"advanceInput(): no input\");\n }\n\n /**\n * @this {C1PSerialPort}\n */\n updateMemory()\n {\n var offset;\n /*\n * Update all the status (even) bytes\n */\n for (offset = this.offPort+0; offset < this.offPortLimit; offset+=2) {\n this.abMem[offset] = (this.bInput >= 0? C1PSerialPort.STATUS_DATA : C1PSerialPort.STATUS_NONE);\n }\n /*\n * Update all the data (odd) bytes\n */\n for (offset = this.offPort+1; offset < this.offPortLimit; offset+=2) {\n this.abMem[offset] = (this.bInput >= 0? this.bInput : 0);\n }\n }\n\n /**\n * C1PSerialPort.init()\n *\n * This function operates on every HTML element of class \"serial\", extracting the\n * JSON-encoded parameters for the C1PSerialPort constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a C1PSerialPort component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeSerial = Component.getElementsByClass(document, C1PJS.APPCLASS, \"serial\");\n for (var iSerial=0; iSerial < aeSerial.length; iSerial++) {\n var eSerial = aeSerial[iSerial];\n var parmsSerial = Component.getComponentParms(eSerial);\n var serial = new C1PSerialPort(parmsSerial);\n Component.bindComponentControls(serial, eSerial, C1PJS.APPCLASS);\n }\n }\n}\n\nC1PSerialPort.STATUS_NONE = 0x00;\nC1PSerialPort.STATUS_DATA = 0x01; // indicates data available\n\n/*\n * Values for autoLoad:\n *\n * 0: no auto-load active\n * 1: BASIC command file auto-load in progress\n * 2: 6502 HEX command file auto-load in progress\n */\nC1PSerialPort.AUTOLOAD_NONE = 0;\nC1PSerialPort.AUTOLOAD_BASIC = 1;\nC1PSerialPort.AUTOLOAD_6502 = 2;\n\n/*\n * Initialize every SerialPort module on the page.\n */\nWeb.onInit(C1PSerialPort.init);\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/disk.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * @class Drive\n * @property {number} iType\n * @property {number} nTracks\n * @property {boolean} fProtected\n * @property {number} nIndexPulse\n * @property {number} iTrackSelect\n * @property {number} iTrackOffset\n * @property {Array} aTracks\n */\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass C1PDiskController extends Component {\n /**\n * C1PDiskController(parmsDC)\n *\n * The C1PDiskController component has no component-specific parameters.\n *\n * This component is being built to supplement a C1P (aka SuperBoard II) Model 600\n * single-board computer with the addition of a 610 Accessory Board, which included:\n *\n * MC6820 PIA (Peripheral Interface Adapter at $C000-$C003, decoded at $C000-$C00F)\n * MC6850 ACIA (Asynchronous Communications Interface Adapter at $C010-$C011, decoded at $C010-$C01F)\n *\n * From \"OSI C1P Technical Report\" p.4 regarding the 610 Accessory Board:\n *\n * \"This board holds up to 24K of additional RAM memory, a dual mini-floppy disk controller,\n * a BUS expansion facility to Model 620 BUS adapter, and switching circuitry to route the\n * 600 board's serial interface to both the modem and printer as well as an audio cassette.\n * Thus, a fully expanded Challenger lP system can have BASIC-in-ROM, 32K of RAM memory,\n * dual mini-floppies, cassette, printer, modem, and full BUS expansion capability to the OSI\n * 48 line BUS through which over 40 accessories can be added (A/D, D/A, voice, I/O, more memory,\n * etc.).\"\n *\n * On p.20, the Report says that the 610 Accessory Board contains:\n *\n * - Up to 24K of RAM\n * - Dual mini-floppy controller\n * - Real Time Clock (although elsewhere the Report says this is disabled by default)\n * - Expansion interface to a model 620 BUS adapter\n *\n * On p.21, the Report also says:\n *\n * \"The dual mini-floppy interface is designed after Ohio Scientific's extremely popular\n * and successful 470 floppy disk controller. This floppy disk controller and encoding\n * technique has been field proven for several years in thousands of floppy disks and is\n * believed to be one of the most reliable floppy disk configurations in existence. Although\n * the Challenger lP product line is new, it has the advantage of the experience of a company\n * which has been building high performance microcomputers for several years.\"\n *\n * From \"PEEK 65\" Vol.2 No.3 March 1981, p.9:\n *\n * \"The 470 board wired as a floppy disk controller contains two different interfaces:\n * a PIA and an ACIA. The PIA A and B ports are used in control circuits: raise and lower\n * the head, detect drive ready, detect sector hole, clear error faults, etc. The ACIA is\n * the interface over which the data actually travels. Typical operation is to drop the head,\n * reset the ACIA, wait for the index hole to come around, activate the read or write circuit,\n * then read or write characters through the ACIA.\"\n *\n * 470 Board Addressing\n * --------------------\n *\n * Address Read Write\n * ------- ---- -----\n * C000 PIA: PA0 thru PA7 PIA: PA0 thru PA7 or DDA0 thru DDA7\n * C001 PIA: Port A Ctrl PIA: Port A Control\n * C002 PIA: PB0 thru PB7 PIA: PB0 thru PB7 or DDB0 thru DDB7\n * C003 PIA: Port B Ctrl PIA: Port B Control\n * C010 ACIA: Status Reg. ACIA: Control Register\n * C011 ACIA: Data Path ACIA: Data Path\n * C020 Clear Real Time Clock Clear Real Time Clock\n * (Reset) ($FF returned) (Reset) (Data Ignored)\n *\n * PIA Data Register A Layout:\n *\n * PA7 PA6 PA5 PA4 PA3 PA2 PA1 PA0\n * --- --- --- ---- --- --- --- ----\n * IHD | SD2 | WP | RDY2 | SHD | FD | TZD | RDY1\n * (In) (Out) (In) (In) (In) (In) (In) (In)\n *\n * PIA Data Register B Layout:\n *\n * PB7 PB6 PB5 PB4 PB3 PB2 PB1 PB0\n * --- --- --- --- --- --- --- ---\n * HLD | LCS | SD1 | FR | ST | STI | EE | WE\n * (Out) (Out) (Out) (Out) (Out) (Out) (Out) (Out)\n *\n * PIA Data Register A Lines PIA Data Register B Lines\n * ------------------------- -------------------------\n * IHD - Index Hole Detect HLD - Head Load\n * SD2 - Select Drive 2 (Drive B) LCS - Low Current Select\n * WP - Write Protected SD1 - Select Drive 1\n * RDY2- Drive 2 Ready FR - Fault Reset\n * SHD - Sector Hole Detect ST - Step\n * FD - Fault Detected STI - Step In\n * TZD - Track Zero Detected EE - Enable Erase\n * RDY1- Drive 1 Ready WE - Write Enable\n *\n * NOTE: The PIA bit assignments above agree with those described, albeit somewhat less clearly,\n * in http://www.osiweb.org/osiweb/misc/osi-hardware.txt, under \"Model 475 Floppy disk system with\n * 470 Controller board\".\n *\n * There is apparently significant overlap with another OSI board: the Model 505 CPU Board\n * used in C4P/MF systems. According to http://www.osiweb.org/osiweb/misc/osi-hardware.txt, it\n * contained:\n *\n * CPU board w/ ROM, ACIA, Floppy Disk I/O, Real Time Clock\n * ROM $FDxx, $FExx, $FFxx\n * Floppy disk interface: 6820 PIA at $C000, 6850 ACIA at $C010 [Original says \"6850 PIA\"]\n * ACIA 6850 at $FC00 for RS-232 serial I/O. Baud jumpers for 75,150,300,600,1200,2400,4800,9600\n * Disk PIA $C0xx CB1 connected to 400mSEC (2.5/sec) clock divided from system clock (RTC)\n * Home security - PIA $F700-F703\n *\n * Disk Formats (from http://osi.marks-lab.com/files/winOSI/old-source-V1.2/Disk_io.cpp):\n *\n * 5.25\" disk, 40 tracks, 8 sectors/track, 256 bytes/sector, 11 bits/byte (8E1) = 80K/disk.\n *\n * NOTE: 8E1 refers to \"8 data bits, even parity, 1 stop bit,\" plus an implied start bit.\n *\n * OSI uses 8E1 to give a max unformatted capacity of 2272 bytes per track (see below).\n * However other bit encodings (8N1) could give up to 2500 bytes/track.\n *\n * NOTE: 8N1 refers to \"8 data bits, no parity, 1 stop bit,\" plus an implied start bit.\n *\n * The standard speed for 5.25\" drives is 300rpm. Thus one rotation of the disk is 200ms.\n * Stated baud-rate is 125k or 125000 bits/sec and one serial byte is 11 bits (1 start,\n * 8 data, 1 parity, 1 stop). So the theoretical absolute maximum storage per track is\n * (125000 x 0.2) / 11 = 2272 bytes or 8.8 pages.\n *\n * OS-65D loses a bit more because it doesn't write until 10ms after the index pulse, so\n * (125000 x 0.19) / 11 = 2159 bytes or 8.4 pages and this doesn't even allow for the length\n * of the index pulse (a few milliseconds?) and the speed variation between drives.\n *\n * 8\" disk, 77 tracks, 12 sectors/track, 256 bytes/sector, 11 bits/byte (8E1) = 231K/disk.\n * OSI uses 8E1 to give a max unformatted capacity of 3772 bytes/track (see below).\n * However other bit encodings (8N1) could give up to 3900 bytes/track.\n *\n * The standard speed for 8\" drives is 360rpm. Thus one rotation of the disk is 166.6ms.\n * Stated baud rate is 250K or 250000 bits/sec and one serial byte is 11 bits (1 start,\n * 8 data, 1 parity, 1 stop). So the theoretical absolute maximum storage per track is\n * (250000 x 0.166 ) / 11 = 3772 or 14.7 pages.\n *\n * OS-65D loses a bit more because it doesn't write until 10 mS after the index pulse, so\n * (250000 x 0.156) / 11 = 3545 bytes or 13.8 pages and this doesn't even allow for the length\n * of the index pulse (a few milliseconds?) and the speed variation between drives.\n *\n * Track 0 Format\n * --------------\n * (10ms delay after index hole)\n * 0,1 load address of the track in hi,lo form\n * 2 page count of how much data is written on track 0.\n * 3+ sector data\n *\n * Track N Format (N > 0)\n * ----------------------\n * (10ms delay after index hole)\n * 0,1 2-byte start code $43, $57\n * 2 BCD track number\n * 3 track type code (always $58)\n * 4+ sector data\n *\n * Sector Format (5.25\" disks)\n * ---------------------------\n * There can be any mixture of various length sectors. The total page count can not\n * exceed 8 pages (8*256) if more than one sector is on a track. Each sector is written\n * in the following format:\n *\n * previous sector length (4 if none before) times 800 microseconds of delay\n * sector start code $76\n * sector number in binary\n * sector length (#pages) in binary\n * sector data\n * (end of sector mark? $47, $53? MDS)\n *\n * Directory Format\n * ----------------\n * 2 sectors (1 & 2) on track 12 hold the directory information.\n * Each entry requires 8 bytes. There are a total of 64 entries. The entries are\n * formatted as follows:\n *\n * 0-5 ASCII 6 character filename\n * 6 BCD first track of file\n * 7 BCD Last track of file\n *\n * So far, all the 5.25\" disk images I've seen are 92160 bytes, regardless whether they have an\n * .IMG or .65D extension. If we divide that total by 40 (tracks/disk), we get 2304 (bytes/track).\n * Divide 2304 by 256 (bytes/page) and we get 9 pages/track. Presumably a fixed 9 pages was chosen\n * to yield a consistent track size across the entire image, while also allowing room for all the\n * metadata that's typically present on a track as well. As explained above, the upper limit\n * on data per track (both sector data and metadata) is 8.8 pages in theory, or 8.4 pages in practice.\n *\n * @this {C1PDiskController}\n * @param {Object} parmsDC\n */\n constructor(parmsDC)\n {\n super(\"C1PDiskController\", parmsDC);\n\n this.flags.powered = false;\n\n /*\n * Our DiskController simulates the combination of an MC6820 PIA and an MC6850 ACIA.\n * This image of an OSI 470 Controller Board (http://osi.marks-lab.com/boards/images/OSI470.jpg)\n * shows that the chips actually used were MC68B21P and MC68B50P.\n *\n * We start with definitions for the MC6820 PIA.\n */\n this.PORT_PDA = 0; // PIA Peripheral Data Register A\n this.PORT_DDA = 0; // PIA Data Direction Register A (DDA shares the same register offset as PDA)\n this.PORT_CRA = 1; // PIA Control Register A\n\n this.PORT_PDB = 2; // PIA Peripheral Data Register B\n this.PORT_DDB = 2; // PIA Data Direction Register B (DDB shares the same register offset as PDB)\n this.PORT_CRB = 3; // PIA Control Register B\n\n this.CR_IRQ1 = 0x80; // IRQ1\n this.CR_IRQ2 = 0x40; // IRQ2\n // this.CR_C2_OUT = 0x20; // C2 is designated an output\n // this.CR_C2_CTRL = 0x18; // C2 Control (00 and 10 mask IRQ2, 01 and 11 pass IRQ2 through to the CPU)\n this.CR_PD_SEL = 0x04; // set to select PD (PDA or PDB), clear to select DD (DDA or DDB)\n // this.CR_C1_CTRL = 0x03; // C1 Control (00 and 10 mask IRQ1, 01 and 11 pass IRQ1 through to the CPU)\n\n /*\n * The PDA bits have the following hard-wired connections in the OSI Floppy Disk Controller.\n * Each line marked INPUT should have its corresponding Data Direction bit clear (0), and each line\n * marked OUTPUT should have its Data Direction bit set (1); however, we do not currently verify that\n * the Data Direction bits are actually initialized to match these specs (and in fact, in the case\n * of PDA_SD2, they may not be).\n */\n this.PDA_RDY1 = 0x01; // INPUT: 0 = Drive 1 Ready\n this.PDA_TZD = 0x02; // INPUT: 0 = Track Zero Detected\n this.PDA_FD = 0x04; // INPUT: 0 = Fault Detected\n this.PDA_SHD = 0x08; // INPUT: 0 = Sector Hole Detect\n this.PDA_RDY2 = 0x10; // INPUT: 0 = Drive 2 Ready\n this.PDA_WP = 0x20; // INPUT: 0 = Write Protected\n this.PDA_SD2 = 0x40; // OUTPUT: 0 = Select Drive 2 (Drive B)\n this.PDA_IHD = 0x80; // INPUT: 0 = Index Hole Detect\n\n // this.PDB_WE = 0x01; // OUTPUT: 0 = Write Enable\n // this.PDB_EE = 0x02; // OUTPUT: 0 = Erase Enable (set to 1)\n this.PDB_STI = 0x04; // OUTPUT: 0 = Step In (away from track 0)\n this.PDB_ST = 0x08; // OUTPUT: 0 = Step (on 1-to-0 transition)\n // this.PDB_FR = 0x10; // OUTPUT: 0 = Fault Reset (set to 1)\n this.PDB_SD1 = 0x20; // OUTPUT: 0 = Select Drive 1\n // this.PDB_LCS = 0x40; // OUTPUT: 0 = Low Current Select (set to 1)\n // this.PDB_HLD = 0x80; // OUTPUT: 0 = Head Load (head on disk)\n\n /*\n * Next, definitions for the MC6850 ACIA.\n *\n * For reference, here are all the possible CTRL_WSEL (Word Select) values:\n *\n * 000 0x00 7 bits, even parity, 2 stop bits\n * 001 0x04 7 bits, odd parity, 2 stop bits\n * 010 0x08 7 bits, even parity, 1 stop bit\n * 011 0x0C 7 bits, odd parity, 1 stop bit\n * 100 0x10 8 bits, 2 stop bits\n * 101 0x14 8 bits, 1 stop bit\n * 110 0x18 8 bits, even parity, 1 stop bit\n * 111 0x1C 8 bits, odd parity, 1 stop bit\n *\n * And here are all the possible CTRL_TCTL (Transmit Control) values:\n *\n * 00 0x00 RTS=Low, Transmitting Interrupt Disabled\n * 01 0x20 RTS=Low, Transmitting Interrupt Enabled\n * 10 0x40 RTS=High, Transmitting Interrupt Disabled\n * 11 0x60 RTS=Low, Transmits a Break level on the Transmit Data Output; Transmitting Interrupt Disabled\n */\n this.PORT_CTRL = 0x10; // ACIA Control Register (WRITE-only)\n this.PORT_STAT = 0x10; // ACIA Status Register (READ-only)\n this.PORT_DATA = 0x11; // ACIA Data Register (Transmit Data Register on WRITE, Receive Data Register on READ)\n\n this.CTRL_CDIV = 0x03; // Counter Divide (CR1,CR0) [OSI sets both, performing a \"Master Reset\", then immediately clears both, for a divide ratio of 1]\n // this.CTRL_WSEL = 0x1C; // Word Select (CR4,CR3,CR2), determining word length, parity and stop bits [OSI selects 0x18 for \"8 bits, even parity, 1 stop bit\"]\n // this.CTRL_TCTL = 0x60; // Transmit Control (CR6,CR5) [OSI selects 0x40 for \"RTS=High, Transmitting Interrupt Disabled\"]\n // this.CTRL_RINT = 0x80; // Receive Interrupt Enable (CR7) [OSI selects 0x00 for interrupts disabled]\n\n this.STAT_RDRF = 0x01; // Receive Data Register Full\n this.STAT_TDRE = 0x02; // Transmit Data Register Empty\n this.STAT_DCD = 0x04; // Data Carrier Detect\n this.STAT_CTS = 0x08; // Clear To Send\n // this.STAT_FE = 0x10; // Framing Error (ie, the received character is improperly framed by a start and a stop bit and is detected by the absence of the first stop bit)\n // this.STAT_OVRN = 0x20; // Receiver Overrun (ie, one or more characters in the data stream were lost due to not being read from the Receive Data Register in time)\n // this.STAT_PE = 0x40; // Parity Error (ie, the number of highs (ones) in the character does not agree with the preselected odd or even parity)\n // this.STAT_IRQ = 0x80; // Interrupt Request (ie, state of the IRQ output; cleared by a read operation to the Receive Data Register or a write operation to the Transmit Data Register)\n\n /*\n * Last but not least, some internal state definitions and hard-coded assumptions\n */\n this.DRIVETYPE_5INCH = 0;\n // this.DRIVETYPE_8INCH = 1;\n\n this.MAXTRACKS_5INCH = 40;\n // this.MAXTRACKS_8INCH = 77;\n\n /*\n * Some random OS-65D notes\n *\n * Version 3.3 Initialization Code\n * -------------------------------\n *\n * The following code (where X is 0x00):\n *\n * 2217 8E 01 F4 STX $F401\n * 221A 8E 00 F4 STX $F400\n * 221D 8E 03 F4 STX $F403\n *\n * is intended to reset a Printer PIA located at 0xF400.\n *\n * It then takes a detour to \"SET KEYBOARD SOUND GENERATOR TO LOWEST FREQUENCY (192.753 HZ)\"\n * with X set to 0xFF; the sound generator is supposed to be turned off a bit later, presumably\n * at the same time it sets \"64 char/line\" mode -- well, that's what v3.2 did anyway.\n *\n * 2220 CA DEX\n * 2221 8E 01 DF STX $DF01\n *\n * While X is still 0xFF, it continues initializing the Printer PIA:\n *\n * 2224 8E 02 F4 STX $F402\n *\n * Then the code fiddles a bit with a mystery serial port (perhaps the \"Model 430B Cassette & Analog I/O\"\n * interface?)\n *\n * 2227 AD 06 FB LDA $FB06\n * 222A 8E 05 FB STX $FB05\n *\n * And then it's back to more Printer PIA initialization:\n *\n * 222D A9 04 LDA #$04\n * 222F 8D 01 F4 STA $F401\n * 2232 8D 03 F4 STA $F403\n *\n * Then it does some disk resetting (with A still 0x04 and Y set to 0x00):\n *\n * 2235 8C 01 C0 STY $C001\n * 2238 A0 40 LDY #$40 ;'@'\n * 223A 8C 00 C0 STY $C000\n * 223D 8D 01 C0 STA $C001\n *\n * This code supposedly selects DRIVE 1:\n *\n * 2240 A9 01 LDA #$01\n * 2242 20 C6 29 JSR $29C6\n *\n * Then it \"resets\" and \"sets\" the TERMINAL ACIA. Note that the C1P serial port is addressed\n * at 0xF000-0xF0FF, and the C1P has ROM mapped to 0xF800-0xFFFF, so we know nothing of the serial\n * port mentioned above at 0xFBxx, nor this terminal ACIA port at 0xFCxx.\n *\n * 2245 A9 03 LDA #$03\n * 2247 8D 00 FC STA $FC00\n * 224A A0 11 LDY #$11\n * 224C 8C 00 FC STY $FC00\n *\n * Next, there's some code to \"SET CA-10X 16 WAY SERIAL BOARD\" at 0xCF00-0xCF1F; again, something\n * we know nothing about:\n *\n * 224F A2 1E LDX #$1E\n * 2251 9D 00 CF STA $CF00,X\n * 2254 98 TYA\n * 2255 9D 00 CF STA $CF00,X\n * 2258 A9 03 LDA #$03\n * 225A CA DEX\n * 225B CA DEX\n * 225C 10 F3 BPL $2251\n *\n * Then it clears 8 pages of video memory (ie, it simply ASSUMES that this is a Model 540 video board\n * with 2K of video memory):\n *\n * 225E A2 08 LDX #$08\n * 2260 A9 D0 LDA #$D0\n * 2262 85 FF STA $FF\n * 2264 A0 00 LDY #$00\n * 2266 84 FE STY $FE\n * 2268 A9 20 LDA #$20 ;' '\n * 226A 91 FE STA ($FE),Y\n * 226C C8 INY\n * 226D D0 FB BNE $226A\n * 226F E6 FF INC $FF\n * 2271 CA DEX\n * 2272 D0 F6 BNE $226A\n *\n * Then it performs a memory test, starting with a high page of 0xBF, and stores the highest page of\n * available RAM at 0x2300:\n *\n * 2276 A0 BF LDY #$BF\n * 2278 20 EC 22 JSR $22EC\n * 227B F0 03 BEQ $2280\n * 227D 88 DEY\n * 227E D0 F8 BNE $2278\n * 2280 8C 00 23 STY $2300\n *\n * Now it checks for \"SERIAL OR VIDEO (EITHER 65-A OR 65-V PROM)\" (the byte at 0xFE01 on a C1P is 0x28,\n * so X will be 2, implying \"VIDEO\"):\n *\n * 2283 A2 01 LDX #$01\n * 2285 AD 01 FE LDA $FE01\n * 2288 F0 01 BEQ $228B\n * 228A E8 INX\n * 228B 8E C6 2A STX $2AC6\n *\n * Finally, there's some code that's a little different from v3.2; in 3.2, it would set X to 0x01\n * and then store X at 0xDE00, effectively forcing the video board into \"64 char/line\" mode -- which was\n * originally EXACTLY what I was looking for in the video emulation component. But v3.3 doesn't do that.\n * Here's what it does instead:\n *\n * 228F A2 00 LDX #$00\n * 2291 8E 80 DC STX $DC80\n *\n * So, what's supposed to be at 0xDC80?\n */\n\n this.reset(true);\n }\n\n /**\n * @this {C1PDiskController}\n * @param {boolean|undefined} [fPowerOn] is true for the initial reset only\n */\n reset(fPowerOn)\n {\n this.resetRegs();\n this.iDriveSelect = -1;\n if (fPowerOn) {\n this.aDrives = [];\n this.resetDrive(0, this.DRIVETYPE_5INCH, this.MAXTRACKS_5INCH);\n }\n }\n\n /**\n * @this {C1PDiskController}\n */\n resetRegs()\n {\n this.regDDA = {\n bits: this.PDA_SD2, // clear all DDA bits, indicating that all PDA bits represent INPUT lines (well, except for PDA_SD2)\n read: function() {},\n update: function(controller) {\n return function(b) {\n if (b !== undefined) this.bits = b;\n if (!(controller.regCRA.bits & controller.CR_PD_SEL)) {\n controller.writePort(controller.PORT_DDA, this);\n }\n };\n }(this)\n };\n this.regPDA = {\n bits: 0xff,\n read: function() {\n this.update();\n },\n update: function(controller) {\n return function(b) {\n this.bits = controller.updatePDA(b);\n if (controller.regCRA.bits & controller.CR_PD_SEL) {\n controller.writePort(controller.PORT_PDA, this);\n }\n };\n }(this)\n };\n this.regCRA = {\n bits: 0,\n read: function() {},\n update: function(controller) {\n return function(b) {\n /*\n * Most bits written to CRA should be left as-is (the CPU should read back what it wrote);\n * bits 7 and 6 (IRQ1 and IRQ2) are exceptions, since those are tied to peripheral \"Control Lines\"\n * C1 and C2, which can in theory generate an interrupt depending on how the C1_CTRL and C2_CTRL bits\n * in CRA are set. However, assuming there's no need to simulate interrupts for this particular\n * controller hardware, all we'll do is simply insure those two bits are always off.\n */\n if (b !== undefined) this.bits = (b & ~(controller.CR_IRQ1 | controller.CR_IRQ2));\n controller.writePort(controller.PORT_CRA, this);\n /*\n * Since a CRA write may have also changed which register (PDA or DDA) is enabled via the corresponding\n * PDA port, we simply ask ask both to update (only the one that's enabled will write itself to memory).\n */\n controller.regPDA.update();\n controller.regDDA.update();\n };\n }(this)\n };\n this.regDDB = {\n bits: 0xff, // set all DDB bits, indicating that all PDB bits represent OUTPUT lines\n read: function() {},\n update: function(controller) {\n return function(b) {\n if (b !== undefined) this.bits = b;\n if (!(controller.regCRB.bits & controller.CR_PD_SEL)) {\n controller.writePort(controller.PORT_DDB, this);\n }\n };\n }(this)\n };\n this.regPDB = {\n bits: 0xff,\n read: function() {},\n update: function(controller) {\n return function(b) {\n this.bits = controller.updatePDB(b);\n if (controller.regCRB.bits & controller.CR_PD_SEL) {\n controller.writePort(controller.PORT_PDB, this);\n }\n };\n }(this)\n };\n this.regCRB = {\n bits: 0,\n read: function() {},\n update: function(controller) {\n return function(b) {\n /*\n * Most bits written to CRB should be left as-is (the CPU should read back what it wrote);\n * bits 7 and 6 (IRQ1 and IRQ2) are exceptions, since those are tied to peripheral \"Control Lines\"\n * C1 and C2, which can in theory generate an interrupt depending on how the C1_CTRL and C2_CTRL bits\n * in CRB are set. However, assuming there's no need to simulate interrupts for this particular\n * controller hardware, all we'll do is simply insure those two bits are always off.\n */\n if (b !== undefined) this.bits = (b & ~(controller.CR_IRQ1 | controller.CR_IRQ2));\n controller.writePort(controller.PORT_CRB, this);\n /*\n * Since a CRB write may have also changed which register (PDB or DDB) is enabled via the corresponding\n * PDB port, we simply ask ask both to update (only the one that's enabled will write itself to memory).\n */\n controller.regPDB.update();\n controller.regDDB.update();\n };\n }(this)\n };\n this.regCTRL = {\n bits: 0,\n read: function() {},\n update: function(controller) {\n return function(b) {\n if (b !== undefined) {\n if ((b & controller.CTRL_CDIV) == controller.CTRL_CDIV) {\n /*\n * Setting both CTRL_CDIV bits (CR0 and CR1) constitutes a \"Master Reset\" of the ACIA\n */\n controller.regSTAT.bits = (controller.STAT_TDRE | controller.STAT_DCD | controller.STAT_CTS);\n }\n this.bits = b;\n }\n // regCTRL isn't readable; instead, we ensure regSTAT is rewritten in its place\n controller.regSTAT.update();\n };\n }(this)\n };\n this.regSTAT = {\n bits: (this.STAT_TDRE | this.STAT_DCD | this.STAT_CTS),\n read: function() {},\n update: function(controller) {\n return function(b) {\n this.bits = controller.updateSTAT(b);\n controller.writePort(controller.PORT_STAT, this);\n };\n }(this)\n };\n this.regDATA = {\n bits: 0,\n read: function(controller) {\n return function() {\n controller.advanceDriveData();\n };\n }(this),\n update: function(controller) {\n return function(b) {\n if (b !== undefined) this.bits = b;\n controller.writePort(controller.PORT_DATA, this);\n };\n }(this)\n };\n this.regUnknown = {\n bits: 0,\n read: function() {},\n update: function(controller) {\n return function(b) {};\n }(this)\n };\n if (DEBUG) {\n this.regDDA.sName = \"DDA\",\n this.regDDA.aBitIDs = {0x80:\"DD7\",0x40:\"DD6\",0x20:\"DD5\",0x10:\"DD4\",0x08:\"DD3\",0x04:\"DD2\",0x02:\"DD1\",0x01:\"DD0\"}; // jshint ignore:line\n this.regPDA.sName = \"PDA\";\n this.regPDA.aBitIDs = {0x80:\"IHD\",0x40:\"SD2\",0x20:\"WP\",0x10:\"RDY2\",0x08:\"SHD\",0x04:\"FD\",0x02:\"TZD\",0x01:\"RDY1\"};\n this.regCRA.sName = \"CRA\";\n this.regCRA.aBitIDs = {0x80:\"IRQ1\",0x40:\"IRQ2\",0x20:\"C2OUT\",0x10:\"C2:1\",0x08:\"C2:0\",0x04:\"PDS\",0x02:\"C1:1\",0x01:\"C1:0\"};\n this.regDDB.sName = \"DDB\";\n this.regDDB.aBitIDs = {0x80:\"DD7\",0x40:\"DD6\",0x20:\"DD5\",0x10:\"DD4\",0x08:\"DD3\",0x04:\"DD2\",0x02:\"DD1\",0x01:\"DD0\"};\n this.regPDB.sName = \"PDB\";\n this.regPDB.aBitIDs = {0x80:\"HLD\",0x40:\"LCS\",0x20:\"SD1\",0x10:\"FR\",0x08:\"ST\",0x04:\"STI\",0x02:\"EE\",0x01:\"WE\"};\n this.regCRB.sName = \"CRB\";\n this.regCRB.aBitIDs = {0x80:\"IRQ1\",0x40:\"IRQ2\",0x20:\"C2OUT\",0x10:\"C2:1\",0x08:\"C2:0\",0x04:\"PDS\",0x02:\"C1:1\",0x01:\"C1:0\"};\n this.regCTRL.sName = \"CTRL\";\n this.regCTRL.aBitIDs = {0x80:\"CR7\",0x40:\"CR6\",0x20:\"CR5\",0x10:\"CR4\",0x08:\"CR3\",0x04:\"CR2\",0x02:\"CR1\",0x01:\"CR0\"};\n this.regSTAT.sName = \"STAT\";\n this.regDATA.sName = \"DATA\";\n this.regUnknown.sName = \"unknown\";\n }\n }\n\n /**\n * @this {C1PDiskController}\n * @param {number} iDrive\n * @param {number} iDriveType\n * @param {number} nMaxTracks\n */\n resetDrive(iDrive, iDriveType, nMaxTracks)\n {\n this.aDrives[iDrive] = {\n iType: iDriveType,\n nTracks: nMaxTracks,\n fProtected: true, // fake for now\n nIndexPulse: 20, // nIndex (20 is initial index pulse)\n iTrackSelect: 0, // nTrack\n iTrackOffset: -1, // nSector\n /*\n * Our disk data consists of an array of tracks, where each track is an array of sectors;\n * as long as aTracks.length == 0 (empty array), the drive is not considered \"loaded\" with a disk.\n */\n aTracks: []\n };\n }\n\n /**\n * @this {C1PDiskController}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"listDisk\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n switch(sBinding) {\n\n case \"listDisk\":\n this.bindings[sBinding] = control;\n return true;\n\n case \"loadDisk\":\n this.bindings[sBinding] = control;\n control.onclick = function(controller) {\n return function() {\n if (controller.bindings[\"listDisk\"]) {\n var sFilePath = controller.bindings[\"listDisk\"].value;\n var sFileURL = sFilePath;\n /*\n * If the selected disk image has a \".json\" extension, then we assume it's a pre-converted\n * JSON-encoded disk image, so we load it as-is; otherwise, we ask our server-side disk image\n * converter to return the corresponding JSON-encoded data, in compact form (ie, minimal whitespace,\n * no ASCII data comments, etc).\n */\n if (sFilePath.substr(sFilePath.length-5) != \".json\") {\n /*\n * TODO: This code was using a deprecated parameter (compact=1); make sure things still work.\n *\n * TODO: Convert this code to use the new shared Disk API definitions and weblib functions; eg:\n *\n * sDiskURL = Web.getHost() + DumpAPI.ENDPOINT + \"?\" + DumpAPI.QUERY.DISK + \"=\" + sDiskPath;\n */\n sFileURL = \"http://\" + window.location.host + \"/api/v1/dump?disk=\" + sFilePath;\n }\n controller.println(\"loading \" + Str.getBaseName(sFilePath) + \"...\");\n Web.getResource(sFileURL, null, true, function(sURL, sResponse, nErrorCode) {\n controller.loadDisk(sURL, sResponse, nErrorCode);\n });\n }\n };\n }(this);\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * @this {C1PDiskController}\n * @param {Array} abMemory\n * @param {number} start\n * @param {number} end\n * @param {C1PCPU} cpu\n */\n setBuffer(abMemory, start, end, cpu)\n {\n this.abMem = abMemory;\n this.addrController = start;\n // this.addrControllerLimit = end + 1;\n if ((this.cpu = cpu)) {\n cpu.addReadNotify(start, end, this, this.getByte);\n cpu.addWriteNotify(start, end, this, this.setByte);\n }\n this.setReady();\n }\n\n /**\n * @this {C1PDiskController}\n * @param {boolean} fOn\n * @param {C1PComputer} cmp\n *\n * We need We make a note of the Computer component, so that we can invoke its reset() method whenever we need to\n * simulate a warm start, and we query the Keyboard component so that we can use its injectKeys() function.\n */\n setPower(fOn, cmp)\n {\n if (fOn && !this.flags.powered) {\n this.flags.powered = true;\n if (DEBUGGER) this.dbg = cmp.getComponentByType(\"debugger\");\n }\n }\n\n /**\n * @this {C1PDiskController}\n * @param {string} sDiskName\n * @param {string} sDiskData\n * @param {number} nErrorCode (response from server if anything other than 200)\n *\n * NOTE: Although I've expanded the JSON disk-image format to support multiple heads (ie, platters or disk surfaces),\n * this controller implementation currently supports only single-head drives, and therefore only single-sided images.\n * So, if the image contains more than one entry in head data array, all we use is the first entry; data for any remaining\n * heads is discarded.\n *\n * WARNING: The disk-image format should match that used by PCjs, where the image is an array of cylinders, each of which\n * is an array of heads. That's also more typical, because it maintains the original data's physical locality.\n */\n loadDisk(sDiskName, sDiskData, nErrorCode)\n {\n if (nErrorCode) {\n this.println(\"disk load error (\" + nErrorCode + \")\");\n return;\n }\n var aHeads = [];\n this.println(\"mounting \" + sDiskName + \"...\");\n try {\n /*\n * The most likely source of any exception will be right here, where we're parsing\n * the JSON-encoded disk data.\n */\n aHeads = eval(\"(\" + sDiskData + \")\"); // jshint ignore:line\n if (!aHeads.length) {\n this.println(\"no data: \" + sDiskName);\n return;\n }\n if (!aHeads[0].length) {\n this.println(\"no tracks: \" + sDiskName);\n return;\n }\n var aTracks = aHeads[0];\n if (aTracks[0]['trackNum'] === undefined) {\n this.println(\"data error: \" + aTracks[0]);\n return;\n }\n /*\n * NOTE: This should never happen, otherwise we shouldn't have initiated the load\n * in the first place. Can we guarantee that and eliminate this test?\n */\n if (!this.aDrives[0]) {\n this.println(\"no available drives\");\n return;\n }\n /*\n * To make disk access more efficient, we need to supplement every track object with a\n * simple byte-array (trackData) containing all the data bytes for the entire track.\n */\n for (var iTrack=0; iTrack < aTracks.length; iTrack++) {\n var iTrackNum;\n var track = aTracks[iTrack];\n var sectors = track['sectors'];\n /*\n * WARNING: There are MANY other ways the track data could be malformed, but we'll\n * start with the most egregious, and worry about the rest later.\n */\n if ((iTrackNum = track['trackNum']) === undefined || sectors === undefined) {\n throw new Error(\"track \" + iTrack + \" missing data\");\n }\n /*\n * WARNING: We allow out-of-order tracks, because we store each track's data according\n * to its trackNum index, but just in case that wasn't intended, we're going to mention it.\n */\n if (iTrackNum != iTrack) {\n Component.warning(\"track \" + iTrackNum + \" out of order (expected \" + iTrack + \")\");\n }\n /*\n * For each track, we start with an empty trackData array and \"push\" (ie, append) all the\n * sector data onto it. Most of the data is already in byte form and can simply use Array.push(),\n * but there is also some metadata (signatures, types, lengths, etc), for which we have assorted\n * helpers below: pushBCD, pushBin, and pushSig.\n */\n var trackData = [], sector, sectorData, i;\n if (!iTrackNum) {\n sector = sectors[0];\n sectorData = sector['sectorData'];\n this.pushBin(trackData, track, 'trackLoad', 2);\n this.pushBin(trackData, sector, 'sectorPages');\n for (i = 0; i < sectorData.length; i++) {\n trackData.push(sectorData[i]);\n }\n }\n else {\n this.pushSig(trackData, track, 'trackSig');\n this.pushBCD(trackData, track, 'trackNum');\n this.pushBin(trackData, track, 'trackType');\n for (var iSector=0; iSector < sectors.length; iSector++) {\n sector = sectors[iSector];\n sectorData = sector['sectorData'];\n this.pushBin(trackData, sector, 'sectorSig');\n this.pushBin(trackData, sector, 'sectorNum');\n this.pushBin(trackData, sector, 'sectorPages');\n for (i = 0; i < sectorData.length; i++) {\n trackData.push(sectorData[i]);\n }\n this.pushSig(trackData, sector, 'sectorEndSig');\n }\n }\n /*\n * Finally, here's where we add the newly-created chunk of track data to the current track object\n */\n aTracks[iTrackNum].trackData = trackData;\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(this.dbg.MESSAGE_DISK)) {\n this.dbg.message(\"track \" + iTrackNum + \": \" + trackData.length + \" bytes\");\n }\n }\n this.aDrives[0].aTracks = aTracks;\n this.println(\"mount of \" + sDiskName + \" complete\");\n } catch (e) {\n this.println(\"disk data error: \" + e.message);\n }\n }\n\n /**\n * @this {C1PDiskController}\n * @param {Array.<number>} a\n * @param {Object} o is the object containing the key\n * @param {string} k is the key of 8-bit value to convert to BCD (ie, two 4-bit BCD digits) and push\n */\n pushBCD(a, o, k)\n {\n var n = o[k];\n if (n === undefined) {\n throw new Error(\"missing bcd value: \" + k);\n }\n var bcd = (Math.floor(n / 10) << 4) | (n % 10);\n a.push(bcd);\n }\n\n /**\n * @this {C1PDiskController}\n * @param {Array.<number>} a\n * @param {Object} o is the object containing the key\n * @param {string} k is the key of the value\n * @param {number} [cb] is the number of bytes to push (only 1 or 2 is supported, and the default is 1)\n */\n pushBin(a, o, k, cb)\n {\n var n = o[k];\n if (n === undefined) {\n throw new Error(\"missing binary value: \" + k);\n }\n if (cb == 2) {\n a.push((n >> 8) & 0xff);\n }\n a.push(n & 0xff);\n }\n\n /**\n * @this {C1PDiskController}\n * @param {Array.<number>} a\n * @param {Object} o is the object containing the key\n * @param {string} k is the key of the signature string to push\n */\n pushSig(a, o, k)\n {\n var s = o[k];\n if (s === undefined) {\n throw new Error(\"missing signature: \" + k);\n }\n for (var i=0; i < s.length; i++) {\n a.push(s.charCodeAt(i));\n }\n }\n\n /**\n * @this {C1PDiskController}\n * @param {number} port address (0x0000-0x00FF) relative to addrController (0xC000)\n * @param {boolean} fWrite is true if port write, false if port read\n * @return {Object} reg will always be a valid register object, but it may be the \"unknown\" register if we don't recognize the port.\n */\n getReg(port, fWrite)\n {\n var reg;\n port &= 0x3F;\n /*\n * Now that we've masked the full port range of 0x00-0xFF down to 0x00-0x3F, we further mask the\n * PIA port range (0x00-0x0F) to 0x00-0x03, and the ACIA port range (0x10-0x1F) to 0x10-0x11.\n * The rest of the masked range (0x20-0x3F) is unmapped, so we map it to our global unknown register.\n */\n if (port < 0x10)\n port &= 0x03;\n else if (port < 0x20)\n port &= 0x11;\n switch(port) {\n case this.PORT_PDA:\n reg = (this.regCRA.bits & this.CR_PD_SEL)? this.regPDA : this.regDDA;\n break;\n case this.PORT_CRA:\n reg = this.regCRA;\n break;\n case this.PORT_PDB:\n reg = (this.regCRB.bits & this.CR_PD_SEL)? this.regPDB : this.regDDB;\n break;\n case this.PORT_CRB:\n reg = this.regCRB;\n break;\n case this.PORT_CTRL:\n reg = (fWrite? this.regCTRL : this.regSTAT);\n break;\n case this.PORT_DATA:\n reg = this.regDATA;\n break;\n default:\n reg = this.regUnknown;\n break;\n }\n return reg;\n }\n\n /**\n * @this {C1PDiskController}\n * @param {number} addr\n * @param {number|undefined} addrFrom (not defined whenever the Debugger tries to read the specified addr)\n */\n getByte(addr, addrFrom)\n {\n /*\n * Don't trigger any further hardware emulation (beyond what we've already stored in memory) if\n * the Debugger performed this read (need a special Debugger I/O command if/when you really want to do that).\n */\n if (addrFrom !== undefined) {\n var port = addr - this.addrController;\n var reg = this.getReg(port, false);\n if (DEBUGGER && this.dbg) this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_DISK, false, reg.sName);\n reg.read();\n }\n }\n\n /**\n * @this {C1PDiskController}\n * @param {number} addr\n * @param {number|undefined} addrFrom (not defined whenever the Debugger tries to write the specified addr)\n */\n setByte(addr, addrFrom)\n {\n /*\n * Don't trigger any further hardware emulation (beyond what we've already stored in memory) if\n * the Debugger performed this write (need a special Debugger I/O command if/when you really want to do that).\n */\n if (addrFrom !== undefined) {\n var b = this.cpu.getByte(addr);\n var port = addr - this.addrController;\n var reg = this.getReg(port, true);\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(this.dbg.MESSAGE_DISK | this.dbg.MESSAGE_PORT)) {\n this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_DISK, true, reg.sName);\n if (reg.aBitIDs) {\n var bTest = 0x80;\n var bChanged = reg.bits ^ b;\n while (bChanged && bTest) {\n if (bChanged & bTest) {\n this.dbg.message(\" changed \" + reg.sName + \".\" + reg.aBitIDs[bTest] + \" to \" + ((b & bTest)? \"1\" : \"0\"));\n }\n bTest >>= 1;\n }\n }\n }\n reg.update(b);\n }\n }\n\n /**\n * @this {C1PDiskController}\n * @param {number} bPDA\n * @param {number} bPDB\n */\n setSelectedDrive(bPDA, bPDB)\n {\n var iDriveSelect = -1;\n if (bPDA !== undefined && bPDB !== undefined) {\n iDriveSelect = 0;\n if (!(bPDB & this.PDB_SD1))\n iDriveSelect |= 0x02;\n if (!(this.regPDA.bits & this.PDA_SD2))\n iDriveSelect |= 0x01;\n }\n if (this.iDriveSelect != iDriveSelect) {\n this.iDriveSelect = iDriveSelect;\n this.regSTAT.update();\n }\n }\n\n /**\n * @this {C1PDiskController}\n */\n startDriveData()\n {\n if (this.iDriveSelect >= 0) {\n this.aDrives[this.iDriveSelect].iTrackOffset = 0;\n this.advanceDriveData();\n }\n }\n\n /**\n * @this {C1PDiskController}\n */\n stopDriveData()\n {\n if (this.iDriveSelect >= 0) {\n this.aDrives[this.iDriveSelect].iTrackOffset = -1;\n this.regDATA.update(0xFF); // QUESTION: Is this necessary or helpful in some way?\n this.regSTAT.update();\n }\n }\n\n /**\n * @this {C1PDiskController}\n * @return {number} current byte of data from the currently selected drive, or null if no (more) data available\n */\n advanceDriveData()\n {\n var b = null;\n if (this.iDriveSelect >= 0) {\n var drive = this.aDrives[this.iDriveSelect];\n var track = drive.aTracks[drive.iTrackSelect];\n if (track !== undefined) {\n if (drive.iTrackOffset >= 0 && drive.iTrackOffset < track.trackData.length) {\n drive.nIndexPulse = 100; // QUESTION: Necessary?\n b = track.trackData[drive.iTrackOffset++];\n this.regDATA.update(b);\n this.regSTAT.update();\n }\n else {\n drive.nIndexPulse = 10; // QUESTION: Valid or necessary to force index pulse on next poll of $C000?\n this.stopDriveData();\n }\n }\n }\n return b;\n }\n\n /**\n * updatePDA() calculates an updated value for the PDA register.\n *\n * In the process, this may also update iDriveSelect and assorted drive internal variables.\n *\n * @this {C1PDiskController}\n * @param {number|undefined} bPDA\n * @return {number} updated bits for PDA\n */\n updatePDA(bPDA)\n {\n if (bPDA === undefined)\n bPDA = this.regPDA.bits;\n else\n this.setSelectedDrive(bPDA, this.regPDB.bits);\n\n /*\n * We start by turning ON most bits, except for PDA_RDY1, which we always leave\n * OFF (indicating ready). We leave PDA_SD2 alone, so that it reflects whatever\n * the CPU had set.\n *\n * Then we dive into the update logic, which will turn OFF any of the bits we\n * originally turned ON if the corresponding condition is true (because an OFF bit\n * signals an active condition).\n */\n bPDA |= (this.PDA_IHD | this.PDA_WP | this.PDA_SHD | this.PDA_FD | this.PDA_TZD | this.PDA_RDY2);\n bPDA &= ~(this.PDA_RDY1);\n\n if (this.iDriveSelect >= 0) {\n\n if (this.aDrives[this.iDriveSelect].aTracks.length) {\n\n var drive = this.aDrives[this.iDriveSelect];\n\n if (drive.fProtected) {\n bPDA &= ~this.PDA_WP;\n }\n if (!drive.iTrackSelect) {\n bPDA &= ~this.PDA_TZD;\n }\n /*\n * Simulate PHD_IHD (Index Hole Detect)\n */\n if (--drive.nIndexPulse <= 10) {\n if (drive.nIndexPulse > 0) {\n bPDA &= ~this.PDA_IHD;\n this.stopDriveData();\n } else {\n drive.nIndexPulse = 100;\n this.startDriveData();\n }\n }\n }\n }\n return bPDA;\n }\n\n /**\n * updatePDB() calculates an updated value for the PDB register. However, since the\n * PDB consists entirely of OUTPUT bits, none of the given bits should actually be modified.\n *\n * In the process, this may also update iDriveSelect and assorted drive internal variables,\n * as well as selected PDA INPUT bits (hence the call to regPDA.update()).\n *\n * @this {C1PDiskController}\n * @param {number|undefined} bPDB\n * @return {number} updated bits for PDB\n */\n updatePDB(bPDB)\n {\n if (bPDB === undefined)\n bPDB = this.regPDB.bits;\n else\n this.setSelectedDrive(this.regPDA.bits, bPDB);\n\n if (this.iDriveSelect >= 0 && this.iDriveSelect < this.aDrives.length) {\n\n var drive = this.aDrives[this.iDriveSelect];\n\n if (drive.aTracks.length) {\n /*\n * Is PDB_ST transitioning from 1 to 0?\n */\n if ((this.regPDB.bits & this.PDB_ST) && !(bPDB & this.PDB_ST)) {\n /*\n * PDB_STI == 0? step toward track 39 : step toward track 0\n */\n if (bPDB & this.PDB_STI)\n drive.iTrackSelect--;\n else\n drive.iTrackSelect++;\n\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(this.dbg.MESSAGE_DISK)) {\n this.dbg.message(\"stepping \" + ((bPDB & this.PDB_STI)? \"down\" : \"up\") + \" to track \" + drive.iTrackSelect);\n }\n\n if (drive.iTrackSelect >= drive.nTracks)\n drive.iTrackSelect = drive.nTracks;\n\n if (drive.iTrackSelect < 0)\n drive.iTrackSelect = 0;\n\n drive.nIndexPulse = 20;\n\n this.regPDA.update(this.regPDA.bits | this.PDA_IHD);\n this.stopDriveData();\n }\n }\n }\n else if (DEBUG && this.iDriveSelect >= 0) {\n this.println(\"updatePDB(\" + Str.toHexByte(bPDB) + \"): invalid drive: \" + this.iDriveSelect);\n }\n return bPDB;\n }\n\n /**\n * updateSTAT() calculates an updated value for the ACIA Status register.\n *\n * @this {C1PDiskController}\n * @param {number|undefined} bSTAT\n * @return {number} updated bits for STAT\n */\n updateSTAT(bSTAT)\n {\n if (bSTAT === undefined)\n bSTAT = this.regSTAT.bits;\n bSTAT &= ~this.STAT_RDRF;\n if (this.iDriveSelect >= 0 && this.aDrives[this.iDriveSelect].iTrackOffset >= 0)\n bSTAT |= this.STAT_RDRF;\n return bSTAT;\n }\n\n /**\n * @this {C1PDiskController}\n * @param {number} port\n * @param {Object} reg\n */\n writePort(port, reg)\n {\n this.cpu.setByte(port + this.addrController, reg.bits);\n }\n\n /**\n * @this {C1PDiskController}\n * @param {boolean} fLoaded is true if the selected drive must be loaded, false if don't care\n * @return {Object} drive reference to the selected drive, or null if no drive is selected or it doesn't meet the fLoaded requirement\n *\n getSelectedDrive(fLoaded)\n {\n var drive = null;\n if (this.iDriveSelect >= 0) {\n if (this.aDrives[this.iDriveSelect]) {\n if (!fLoaded || this.aDrives[this.iDriveSelect].aTracks.length)\n drive = this.aDrives[this.iDriveSelect];\n }\n }\n return drive;\n }\n */\n\n /**\n * C1PDiskController.init()\n *\n * This function operates on every HTML element of class \"disk\", extracting the\n * JSON-encoded parameters for the C1PDiskController constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a C1PDiskController component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeDC = Component.getElementsByClass(document, C1PJS.APPCLASS, \"disk\");\n for (var iDC=0; iDC < aeDC.length; iDC++) {\n var eDC = aeDC[iDC];\n var parmsDC = Component.getComponentParms(eDC);\n var controller = new C1PDiskController(parmsDC);\n Component.bindComponentControls(controller, eDC, C1PJS.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize every DiskController module on the page.\n */\nWeb.onInit(C1PDiskController.init);\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/debugger.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * @class C1PDebugger\n * @unrestricted\n */\nclass C1PDebugger extends Component {\n /**\n * C1PDebugger(parmsDbg)\n *\n * The C1PDebugger component has no required (parmsDbg) properties.\n *\n * The C1PDebugger component is an optional component that implements a variety of user\n * commands for controlling the CPU, dumping and editing memory, etc.\n *\n * @this {C1PDebugger}\n * @param {Object} parmsDbg\n */\n constructor(parmsDbg)\n {\n if (DEBUGGER) {\n\n super(\"C1PDebugger\", parmsDbg);\n\n this.dbg = this;\n /*\n * This keeps track of instruction activity, but only when tracing or when\n * Debugger checks have been enabled (eg, one or more breakpoints have been set).\n *\n * This is zeroed by CPU notification handlers reset() and stopped().\n * We set it here to -1 to indicate that the CPU has not yet initialized us.\n */\n this.cIns = -1;\n\n /*\n * Some commands, like the dump (d) command, start at nextAddr when no address\n * is given (and they also update nextAddr when they're done).\n */\n this.nextAddr = 0;\n\n /*\n * When Enter is pressed on an empty input buffer, we default to the previous\n * command, which is preserved here.\n */\n this.prevCmd = null;\n\n /*\n * fAssemble is true when \"assemble mode\" is active, false when not.\n */\n this.fAssemble = false;\n this.addrAssembleNext = 0;\n\n /*\n * Initialize the lists of breakpoint addresses. aExecBreak is a list (Array) of addresses\n * to halt at whenever attempting to execute an instruction at the corresponding address,\n * and aReadBreak and aWriteBreak are lists of addresses to halt at whenever a read or write,\n * respectively, occurs at the corresponding address.\n */\n this.clearBreakpoints();\n\n /*\n * Instead of pre-allocating these arrays, we wait until our reset() function is called.\n * These arrays are updated in checkInstruction(), but the CPU will never actually call it\n * unless checksEnabled() returns true, and that won't happen until one or more breakpoints\n * have been set. This ensures that, by default, the CPU runs as fast as possible.\n */\n this.iStepHistory = 0;\n this.aStepHistory = [];\n this.aaOpcodeFreqs = [];\n\n /*\n * This \"info\" buffer is a lightweight logging mechanism that has minimal impact on the\n * browser (unlike printing to either window.console.log or an HTML control, which can make\n * the browser unusable if printing is too frequent). The Debugger's \"i\" command dumps\n * this buffer. Note that dumping too much at once can also bog things down, but by that\n * point, you've presumably already captured the info you need and are willing to wait.\n */\n if (DEBUG) {\n this.iInfoBuffer = 0;\n this.aInfoBuffer = new Array(10000);\n }\n\n /*\n * Message categories supported by the message() function; they are designed to be combined\n * (ie, OR'ed) as needed. The Debugger's \"option\" command is used to turn message categories\n * on and off, like so:\n *\n * o msg port on\n * o msg port off\n * ...\n */\n this.MESSAGE_PORT = 0x01;\n this.MESSAGE_KBD = 0x10;\n this.MESSAGE_VIDEO = 0x20;\n this.MESSAGE_DISK = 0x40;\n this.MESSAGE_SERIAL = 0x80;\n this.MESSAGE_NONE = 0x00;\n // this.MESSAGE_ALL = 0xff;\n this.bitsMessage = this.MESSAGE_NONE;\n this.aMessageCategories = {\n 'port': this.MESSAGE_PORT,\n 'kbd': this.MESSAGE_KBD,\n 'video': this.MESSAGE_VIDEO,\n 'disk': this.MESSAGE_DISK,\n 'serial': this.MESSAGE_SERIAL\n };\n\n /*\n * The aaOperations array is indexed by opcode, and each element is a sub-array that\n * describes the corresponding opcode. The sub-elements are as follows:\n *\n * [0]: {number} of the operation code (see OP_*)\n * [1]: {number} of additional bytes following the opcode byte, if any\n * [2]: {number} of the operation mode operand, if any (see MODE_*)\n *\n * These sub-elements are all optional. If [0] is not present, the opcode is undefined;\n * if [1] is not present (or contains a zero), the opcode is a single-byte opcode; and if\n * [2] is not present, the opcode uses no (or implied) operands.\n */\n this.OP_ADC = 0;\n this.OP_AND = 1;\n this.OP_ASL = 2;\n this.OP_BCC = 3;\n this.OP_BCS = 4;\n this.OP_BEQ = 5;\n this.OP_BIT = 6;\n this.OP_BMI = 7;\n this.OP_BNE = 8;\n this.OP_BPL = 9;\n this.OP_BRK = 10;\n this.OP_BVC = 11;\n this.OP_BVS = 12;\n this.OP_CLC = 13;\n this.OP_CLD = 14;\n this.OP_CLI = 15;\n this.OP_CLV = 16;\n this.OP_CMP = 17;\n this.OP_CPX = 18;\n this.OP_CPY = 19;\n this.OP_DEC = 20;\n this.OP_DEX = 21;\n this.OP_DEY = 22;\n this.OP_EOR = 23;\n this.OP_INC = 24;\n this.OP_INX = 25;\n this.OP_INY = 26;\n this.OP_JMP = 27;\n this.OP_JSR = 28;\n this.OP_LDA = 29;\n this.OP_LDX = 30;\n this.OP_LDY = 31;\n this.OP_LSR = 32;\n this.OP_NOP = 33;\n this.OP_ORA = 34;\n this.OP_PHA = 35;\n this.OP_PHP = 36;\n this.OP_PLA = 37;\n this.OP_PLP = 38;\n this.OP_ROL = 39;\n this.OP_ROR = 40;\n this.OP_RTI = 41;\n this.OP_RTS = 42;\n this.OP_SBC = 43;\n this.OP_SEC = 44;\n this.OP_SED = 45;\n this.OP_SEI = 46;\n this.OP_STA = 47;\n this.OP_STX = 48;\n this.OP_STY = 49;\n this.OP_TAX = 50;\n this.OP_TAY = 51;\n this.OP_TSX = 52;\n this.OP_TXA = 53;\n this.OP_TXS = 54;\n this.OP_TYA = 55;\n this.OP_SIM = 56;\n this.OP_DB = 57;\n\n this.aOpCodes = [\n \"ADC\",\"AND\",\"ASL\",\"BCC\",\"BCS\",\"BEQ\",\"BIT\",\"BMI\",\n \"BNE\",\"BPL\",\"BRK\",\"BVC\",\"BVS\",\"CLC\",\"CLD\",\"CLI\",\n \"CLV\",\"CMP\",\"CPX\",\"CPY\",\"DEC\",\"DEX\",\"DEY\",\"EOR\",\n \"INC\",\"INX\",\"INY\",\"JMP\",\"JSR\",\"LDA\",\"LDX\",\"LDY\",\n \"LSR\",\"NOP\",\"ORA\",\"PHA\",\"PHP\",\"PLA\",\"PLP\",\"ROL\",\n \"ROR\",\"RTI\",\"RTS\",\"SBC\",\"SEC\",\"SED\",\"SEI\",\"STA\",\n \"STX\",\"STY\",\"TAX\",\"TAY\",\"TSX\",\"TXA\",\"TXS\",\"TYA\",\n \"SIM\",\".DB\"\n ];\n\n this.aOpSimCodes = [\n \"HLT\", \"MSG\"\n ];\n\n this.setOpModes(true);\n\n this.aaOperations = [\n /* 0x00 */ [this.OP_BRK],\n /* 0x01 */ [this.OP_ORA, 1, this.MODE_INDX],\n /* 0x02 */ [this.OP_SIM, 1],\n /* 0x03 */ [],\n /* 0x04 */ [],\n /* 0x05 */ [this.OP_ORA, 1, this.MODE_ZP],\n /* 0x06 */ [this.OP_ASL, 1, this.MODE_ZP],\n /* 0x07 */ [],\n /* 0x08 */ [this.OP_PHP],\n /* 0x09 */ [this.OP_ORA, 1, this.MODE_IMM],\n /* 0x0a */ [this.OP_ASL, 0, this.MODE_ACC],\n /* 0x0b */ [],\n /* 0x0c */ [],\n /* 0x0d */ [this.OP_ORA, 2, this.MODE_ABS],\n /* 0x0e */ [this.OP_ASL, 2, this.MODE_ABS],\n /* 0x0f */ [],\n /* 0x10 */ [this.OP_BPL, 1, this.MODE_DISP],\n /* 0x11 */ [this.OP_ORA, 1, this.MODE_INDY],\n /* 0x12 */ [],\n /* 0x13 */ [],\n /* 0x14 */ [],\n /* 0x15 */ [this.OP_ORA, 1, this.MODE_ZPX],\n /* 0x16 */ [this.OP_ASL, 1, this.MODE_ZPX],\n /* 0x17 */ [],\n /* 0x18 */ [this.OP_CLC],\n /* 0x19 */ [this.OP_ORA, 2, this.MODE_ABSY],\n /* 0x1a */ [],\n /* 0x1b */ [],\n /* 0x1c */ [],\n /* 0x1d */ [this.OP_ORA, 2, this.MODE_ABSX],\n /* 0x1e */ [this.OP_ASL, 2, this.MODE_ABSX],\n /* 0x1f */ [],\n /* 0x20 */ [this.OP_JSR, 2, this.MODE_IMM16],\n /* 0x21 */ [this.OP_AND, 1, this.MODE_INDX],\n /* 0x22 */ [],\n /* 0x23 */ [],\n /* 0x24 */ [this.OP_BIT, 1, this.MODE_ZP],\n /* 0x25 */ [this.OP_AND, 1, this.MODE_ZP],\n /* 0x26 */ [this.OP_ROL, 1, this.MODE_ZP],\n /* 0x27 */ [],\n /* 0x28 */ [this.OP_PLP],\n /* 0x29 */ [this.OP_AND, 1, this.MODE_IMM],\n /* 0x2a */ [this.OP_ROL, 0, this.MODE_ACC],\n /* 0x2b */ [],\n /* 0x2c */ [this.OP_BIT, 2, this.MODE_ABS],\n /* 0x2d */ [this.OP_AND, 2, this.MODE_ABS],\n /* 0x2e */ [this.OP_ROL, 2, this.MODE_ABS],\n /* 0x2f */ [],\n /* 0x30 */ [this.OP_BMI, 1, this.MODE_DISP],\n /* 0x31 */ [this.OP_AND, 1, this.MODE_INDY],\n /* 0x32 */ [],\n /* 0x33 */ [],\n /* 0x34 */ [],\n /* 0x35 */ [this.OP_AND, 1, this.MODE_ZPX],\n /* 0x36 */ [this.OP_ROL, 1, this.MODE_ZPX],\n /* 0x37 */ [],\n /* 0x38 */ [this.OP_SEC],\n /* 0x39 */ [this.OP_AND, 2, this.MODE_ABSY],\n /* 0x3a */ [],\n /* 0x3b */ [],\n /* 0x3c */ [],\n /* 0x3d */ [this.OP_AND, 2, this.MODE_ABSX],\n /* 0x3e */ [this.OP_ROL, 2, this.MODE_ABSX],\n /* 0x3f */ [],\n /* 0x40 */ [this.OP_RTI],\n /* 0x41 */ [this.OP_EOR, 1, this.MODE_INDX],\n /* 0x42 */ [],\n /* 0x43 */ [],\n /* 0x44 */ [],\n /* 0x45 */ [this.OP_EOR, 1, this.MODE_ZP],\n /* 0x46 */ [this.OP_LSR, 1, this.MODE_ZP],\n /* 0x47 */ [],\n /* 0x48 */ [this.OP_PHA],\n /* 0x49 */ [this.OP_EOR, 1, this.MODE_IMM],\n /* 0x4a */ [this.OP_LSR, 0, this.MODE_ACC],\n /* 0x4b */ [],\n /* 0x4c */ [this.OP_JMP, 2, this.MODE_IMM16],\n /* 0x4d */ [this.OP_EOR, 2, this.MODE_ABS],\n /* 0x4e */ [this.OP_LSR, 2, this.MODE_ABS],\n /* 0x4f */ [],\n /* 0x50 */ [this.OP_BVC, 1, this.MODE_DISP],\n /* 0x51 */ [this.OP_EOR, 1, this.MODE_INDY],\n /* 0x52 */ [],\n /* 0x53 */ [],\n /* 0x54 */ [],\n /* 0x55 */ [this.OP_EOR, 1, this.MODE_ZPX],\n /* 0x56 */ [this.OP_LSR, 1, this.MODE_ZPX],\n /* 0x57 */ [],\n /* 0x58 */ [this.OP_CLI],\n /* 0x59 */ [this.OP_EOR, 2, this.MODE_ABSY],\n /* 0x5a */ [],\n /* 0x5b */ [],\n /* 0x5c */ [],\n /* 0x5d */ [this.OP_EOR, 2, this.MODE_ABSX],\n /* 0x5e */ [this.OP_LSR, 2, this.MODE_ABSX],\n /* 0x5f */ [],\n /* 0x60 */ [this.OP_RTS],\n /* 0x61 */ [this.OP_ADC, 1, this.MODE_INDX],\n /* 0x62 */ [],\n /* 0x63 */ [],\n /* 0x64 */ [],\n /* 0x65 */ [this.OP_ADC, 1, this.MODE_ZP],\n /* 0x66 */ [this.OP_ROR, 1, this.MODE_ZP],\n /* 0x67 */ [],\n /* 0x68 */ [this.OP_PLA],\n /* 0x69 */ [this.OP_ADC, 1, this.MODE_IMM],\n /* 0x6a */ [this.OP_ROR, 0, this.MODE_ACC],\n /* 0x6b */ [],\n /* 0x6c */ [this.OP_JMP, 2, this.MODE_ABS16],\n /* 0x6d */ [this.OP_ADC, 2, this.MODE_ABS],\n /* 0x6e */ [this.OP_ROR, 2, this.MODE_ABS],\n /* 0x6f */ [],\n /* 0x70 */ [this.OP_BVS, 1, this.MODE_DISP],\n /* 0x71 */ [this.OP_ADC, 1, this.MODE_INDY],\n /* 0x72 */ [],\n /* 0x73 */ [],\n /* 0x74 */ [],\n /* 0x75 */ [this.OP_ADC, 1, this.MODE_ZPX],\n /* 0x76 */ [this.OP_ROR, 1, this.MODE_ZPX],\n /* 0x77 */ [],\n /* 0x78 */ [this.OP_SEI],\n /* 0x79 */ [this.OP_ADC, 2, this.MODE_ABSY],\n /* 0x7a */ [],\n /* 0x7b */ [],\n /* 0x7c */ [],\n /* 0x7d */ [this.OP_ADC, 2, this.MODE_ABSX],\n /* 0x7e */ [this.OP_ROR, 2, this.MODE_ABSX],\n /* 0x7f */ [],\n /* 0x80 */ [],\n /* 0x81 */ [this.OP_STA, 1, this.MODE_INDX],\n /* 0x82 */ [],\n /* 0x83 */ [],\n /* 0x84 */ [this.OP_STY, 1, this.MODE_ZP],\n /* 0x85 */ [this.OP_STA, 1, this.MODE_ZP],\n /* 0x86 */ [this.OP_STX, 1, this.MODE_ZP],\n /* 0x87 */ [],\n /* 0x88 */ [this.OP_DEY],\n /* 0x89 */ [],\n /* 0x8a */ [this.OP_TXA],\n /* 0x8b */ [],\n /* 0x8c */ [this.OP_STY, 2, this.MODE_ABS],\n /* 0x8d */ [this.OP_STA, 2, this.MODE_ABS],\n /* 0x8e */ [this.OP_STX, 2, this.MODE_ABS],\n /* 0x8f */ [],\n /* 0x90 */ [this.OP_BCC, 1, this.MODE_DISP],\n /* 0x91 */ [this.OP_STA, 1, this.MODE_INDY],\n /* 0x92 */ [],\n /* 0x93 */ [],\n /* 0x94 */ [this.OP_STY, 1, this.MODE_ZPX],\n /* 0x95 */ [this.OP_STA, 1, this.MODE_ZPX],\n /* 0x96 */ [this.OP_STX, 1, this.MODE_ZPY],\n /* 0x97 */ [],\n /* 0x98 */ [this.OP_TYA],\n /* 0x99 */ [this.OP_STA, 2, this.MODE_ABSY],\n /* 0x9a */ [this.OP_TXS],\n /* 0x9b */ [],\n /* 0x9c */ [],\n /* 0x9d */ [this.OP_STA, 2, this.MODE_ABSX],\n /* 0x9e */ [],\n /* 0x9f */ [],\n /* 0xa0 */ [this.OP_LDY, 1, this.MODE_IMM],\n /* 0xa1 */ [this.OP_LDA, 1, this.MODE_INDX],\n /* 0xa2 */ [this.OP_LDX, 1, this.MODE_IMM],\n /* 0xa3 */ [],\n /* 0xa4 */ [this.OP_LDY, 1, this.MODE_ZP],\n /* 0xa5 */ [this.OP_LDA, 1, this.MODE_ZP],\n /* 0xa6 */ [this.OP_LDX, 1, this.MODE_ZP],\n /* 0xa7 */ [],\n /* 0xa8 */ [this.OP_TAY],\n /* 0xa9 */ [this.OP_LDA, 1, this.MODE_IMM],\n /* 0xaa */ [this.OP_TAX],\n /* 0xab */ [],\n /* 0xac */ [this.OP_LDY, 2, this.MODE_ABS],\n /* 0xad */ [this.OP_LDA, 2, this.MODE_ABS],\n /* 0xae */ [this.OP_LDX, 2, this.MODE_ABS],\n /* 0xaf */ [],\n /* 0xb0 */ [this.OP_BCS, 1, this.MODE_DISP],\n /* 0xb1 */ [this.OP_LDA, 1, this.MODE_INDY],\n /* 0xb2 */ [],\n /* 0xb3 */ [],\n /* 0xb4 */ [this.OP_LDY, 1, this.MODE_ZPX],\n /* 0xb5 */ [this.OP_LDA, 1, this.MODE_ZPX],\n /* 0xb6 */ [this.OP_LDX, 1, this.MODE_ZPY],\n /* 0xb7 */ [],\n /* 0xb8 */ [this.OP_CLV],\n /* 0xb9 */ [this.OP_LDA, 2, this.MODE_ABSY],\n /* 0xba */ [this.OP_TSX],\n /* 0xbb */ [],\n /* 0xbc */ [this.OP_LDY, 2, this.MODE_ABSX],\n /* 0xbd */ [this.OP_LDA, 2, this.MODE_ABSX],\n /* 0xbe */ [this.OP_LDX, 2, this.MODE_ABSY],\n /* 0xbf */ [],\n /* 0xc0 */ [this.OP_CPY, 1, this.MODE_IMM],\n /* 0xc1 */ [this.OP_CMP, 1, this.MODE_INDX],\n /* 0xc2 */ [],\n /* 0xc3 */ [],\n /* 0xc4 */ [this.OP_CPY, 1, this.MODE_ZP],\n /* 0xc5 */ [this.OP_CMP, 1, this.MODE_ZP],\n /* 0xc6 */ [this.OP_DEC, 1, this.MODE_ZP],\n /* 0xc7 */ [],\n /* 0xc8 */ [this.OP_INY],\n /* 0xc9 */ [this.OP_CMP, 1, this.MODE_IMM],\n /* 0xca */ [this.OP_DEX],\n /* 0xcb */ [],\n /* 0xcc */ [this.OP_CPY, 2, this.MODE_ABS],\n /* 0xcd */ [this.OP_CMP, 2, this.MODE_ABS],\n /* 0xce */ [this.OP_DEC, 2, this.MODE_ABS],\n /* 0xcf */ [],\n /* 0xd0 */ [this.OP_BNE, 1, this.MODE_DISP],\n /* 0xd1 */ [this.OP_CMP, 1, this.MODE_INDY],\n /* 0xd2 */ [],\n /* 0xd3 */ [],\n /* 0xd4 */ [],\n /* 0xd5 */ [this.OP_CMP, 1, this.MODE_ZPX],\n /* 0xd6 */ [this.OP_DEC, 1, this.MODE_ZPX],\n /* 0xd7 */ [],\n /* 0xd8 */ [this.OP_CLD],\n /* 0xd9 */ [this.OP_CMP, 2, this.MODE_ABSY],\n /* 0xda */ [],\n /* 0xdb */ [],\n /* 0xdc */ [],\n /* 0xdd */ [this.OP_CMP, 2, this.MODE_ABSX],\n /* 0xde */ [this.OP_DEC, 2, this.MODE_ABSX],\n /* 0xdf */ [],\n /* 0xe0 */ [this.OP_CPX, 1, this.MODE_IMM],\n /* 0xe1 */ [this.OP_SBC, 1, this.MODE_INDX],\n /* 0xe2 */ [],\n /* 0xe3 */ [],\n /* 0xe4 */ [this.OP_CPX, 1, this.MODE_ZP],\n /* 0xe5 */ [this.OP_SBC, 1, this.MODE_ZP],\n /* 0xe6 */ [this.OP_INC, 1, this.MODE_ZP],\n /* 0xe7 */ [],\n /* 0xe8 */ [this.OP_INX],\n /* 0xe9 */ [this.OP_SBC, 1, this.MODE_IMM],\n /* 0xea */ [this.OP_NOP],\n /* 0xeb */ [],\n /* 0xec */ [this.OP_CPX, 2, this.MODE_ABS],\n /* 0xed */ [this.OP_SBC, 2, this.MODE_ABS],\n /* 0xee */ [this.OP_INC, 2, this.MODE_ABS],\n /* 0xef */ [],\n /* 0xf0 */ [this.OP_BEQ, 1, this.MODE_DISP],\n /* 0xf1 */ [this.OP_SBC, 1, this.MODE_INDY],\n /* 0xf2 */ [],\n /* 0xf3 */ [],\n /* 0xf4 */ [],\n /* 0xf5 */ [this.OP_SBC, 1, this.MODE_ZPX],\n /* 0xf6 */ [this.OP_INC, 1, this.MODE_ZPX],\n /* 0xf7 */ [],\n /* 0xf8 */ [this.OP_SED],\n /* 0xf9 */ [this.OP_SBC, 2, this.MODE_ABSY],\n /* 0xfa */ [],\n /* 0xfb */ [],\n /* 0xfc */ [],\n /* 0xfd */ [this.OP_SBC, 2, this.MODE_ABSX],\n /* 0xfe */ [this.OP_INC, 2, this.MODE_ABSX],\n /* 0xff */ []\n ];\n\n } // endif DEBUGGER\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var dbg = this;\n switch(sBinding) {\n case \"debugInput\":\n this.bindings[sBinding] = control;\n this.eDebug = /** @type {HTMLInputElement} */ (control);\n this.eDebug.focus();\n control.onkeypress = function(dbg, e) {\n return function(event) {\n if (event.keyCode == 13) {\n sBinding = e.value;\n e.value = \"\";\n C1PDebugger.input(dbg, sBinding);\n }\n };\n }(this, control);\n return true;\n \n case \"debugEnter\":\n this.bindings[sBinding] = control;\n /*\n * I've replaced the standard \"onclick\" code with a call to our onClickRepeat() helper in\n * component.js, so that the \"Enter\" button can be held to repeat, just like the \"Step\" button.\n */\n Web.onClickRepeat(\n control, 500, 100,\n function(fRepeat) {\n if (dbg.eDebug) {\n sBinding = dbg.eDebug.value;\n //\n // If we want to use the debugEnter button to repeatedly enter the same command,\n // then don't clear the command string.\n //\n // dbg.eDebug.value = \"\";\n //\n C1PDebugger.input(dbg, sBinding);\n return true;\n }\n if (DEBUG) dbg.log(\"no debugger input buffer\");\n return false;\n }\n );\n return true;\n \n case \"step\":\n this.bindings[sBinding] = control;\n Web.onClickRepeat(\n control, 500, 100,\n function(fRepeat) {\n var fCompleted = false;\n if (!dbg.isBusy(true)) {\n dbg.setBusy(true);\n fCompleted = dbg.step(fRepeat? 1 : 0);\n dbg.setBusy(false);\n }\n return fCompleted;\n }\n );\n return true;\n \n default:\n break;\n }\n return false;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {Array} abMemory\n * @param {number} start\n * @param {number} end\n */\n setBuffer(abMemory, start, end)\n {\n this.abMem = abMemory;\n this.offMem = start;\n this.cbMem = end - start + 1;\n this.offLimit = this.offMem + this.cbMem;\n this.setReady();\n }\n\n /**\n * @this {C1PDebugger}\n * @param {boolean} fOn\n * @param {C1PComputer} cmp\n */\n setPower(fOn, cmp)\n {\n if (fOn && !this.flags.powered) {\n this.flags.powered = true;\n this.cpu = cmp.getComponentByType(\"cpu\");\n }\n }\n\n /**\n * @this {C1PDebugger}\n */\n setFocus()\n {\n this.eDebug.focus();\n }\n\n /**\n * @this {C1PDebugger}\n * @param {boolean} fClassic is true for \"classic\" operand syntax, or false for \"modern\" operand syntax\n *\n * The strings describing the operand(s) also describe the addressing mode, as follows:\n *\n * bbb mode classic modern description\n * --- ---- ------- ------- ----------------\n * 000 INDX ($nn,X) [[nn+X]] Indexed Indirect\n * 001 ZP $nn [nn] Zero-Page\n * 010 IMM #$nn nn Immediate\n * 011 ABS $nnnn [nnnn] Absolute\n * 100 INDY ($nn),Y [[nn]+Y] Indirect Indexed\n * 101 ZPX $nn,X [nn+X] Zero-Page,X\n * 110 ABSY $nnnn,Y [nnnn+Y] Absolute,Y\n * 111 ABSX $nnnn,X [nnnn+X] Absolute,X\n *\n * where bbb generally corresponds to bits 2-4 of the opcode. I find that using brackets in the\n * descriptors to indicate a memory access (or multiple brackets, in the case of indirect accesses),\n * along with \"+\" and any index register, is more intuitive than the \"classic\" operand formats;\n * the absence of any brackets implies immediate data, eliminating the need for a prepended \"#\".\n * Also, the use of 2-digit instead of 4-digit addresses indicates that a zero-page address is\n * being used. Finally, all displacements/addresses and immediate values are displayed in hex by\n * default, so there is no need to waste space prepending the traditional \"$\" to such values.\n *\n * Other addressing modes:\n *\n * 101 ZPY $nn,Y Zero-Page,Y (used by LDX and STX only)\n *\n * ACC A Accumulator\n *\n * IMM16 $nnnn Used by JSR (0x20) and JMP (0x4C); I consider this an \"Immediate\" operation\n * that uses 16 bits, but it is documented as \"Absolute\" addressing (see Zaks)\n *\n * FYI, this is the same operand format used for branch displacements (MODE_DISP),\n * except the displacements are 8-bit values that are signed-extended to 16 bits, so\n * discriminating between MODE_DISP and MODE_IMM16 also requires checking the operand size\n *\n * ABS16 ($nnnn) Used by JMP (0x6C); I consider this an \"Absolute\" operation that fetches\n * 16 bits of data, but it is documented as \"Indirect\" addressing (see Zaks)\n */\n setOpModes(fClassic)\n {\n /*\n * NOTE: The modes are arranged within aOpModes so that longer matches are checked before\n * any subsets that could also match (eg, check for \"$nn,X\" before \"$nn\", \"$nnnn,X\" before \"$nnnn\", etc).\n */\n this.MODE_ACC = 0;\n this.MODE_IMM = 1;\n this.MODE_ABSX = 2;\n this.MODE_ABSY = 3;\n this.MODE_IMM16 = 4;\n this.MODE_ABS16 = 5;\n this.MODE_ZPX = 6;\n this.MODE_ZPY = 7;\n this.MODE_INDX = 8;\n this.MODE_INDY = 9;\n this.MODE_ABS = 10;\n this.MODE_ZP = 11;\n this.MODE_DISP = this.MODE_IMM16;\n\n var sRegEx = \"\";\n var iMode, sMode;\n\n if (fClassic) {\n this.aOpModes = [\n \"A\", // MODE_ACC\n /* 010b */ \"#$nn\", // MODE_IMM\n /* 111b */ \"$nnnn,X\", // MODE_ABSX\n /* 110b */ \"$nnnn,Y\", // MODE_ABSY\n \"$nnnn\", // MODE_IMM16\n \"($nnnn)\", // MODE_ABS16\n /* 101b */ \"$nn,X\", // MODE_ZPX\n \"$nn,Y\", // MODE_ZPY\n /* 000b */ \"($nn,X)\", // MODE_INDX\n /* 100b */ \"($nn),Y\", // MODE_INDY\n /* 011b */ \"$nnnn\", // MODE_ABS\n /* 001b */ \"$nn\" // MODE_ZP\n ];\n for (iMode=0; iMode < this.aOpModes.length; iMode++) {\n sMode = this.aOpModes[iMode];\n sRegEx += \"(\" + sMode.replace(/\\(/g, \"\\\\(\").replace(/\\)/g, \"\\\\)\").replace(/nnnn/g, \"[0-9A-F][0-9A-F][0-9A-F][0-9A-F]?\").replace(/nn/g, \"[0-9A-F][0-9A-F]?\").replace(/\\$/g, \"\\\\$\") + \"|)\";\n }\n this.regexOpModes = new RegExp(sRegEx);\n }\n else {\n this.aOpModes = [\n \"A\", // MODE_ACC\n /* 010b */ \"nn\", // MODE_IMM\n /* 111b */ \"[nnnn+X]\", // MODE_ABSX\n /* 110b */ \"[nnnn+Y]\", // MODE_ABSY\n \"nnnn\", // MODE_IMM16\n \"[nnnn]\", // MODE_ABS16\n /* 101b */ \"[nn+X]\", // MODE_ZPX\n \"[nn+Y]\", // MODE_ZPY\n /* 000b */ \"[[nn+X]]\", // MODE_INDX\n /* 100b */ \"[[nn]+Y]\", // MODE_INDY\n /* 011b */ \"[nnnn]\", // MODE_ABS\n /* 001b */ \"[nn]\" // MODE_ZP\n ];\n for (iMode=0; iMode < this.aOpModes.length; iMode++) {\n sMode = this.aOpModes[iMode];\n sRegEx += \"(\" + sMode.replace(/\\[/g, \"\\\\[\").replace(/]/g, \"\\\\]\").replace(/nnnn/g, \"[0-9A-F][0-9A-F][0-9A-F][0-9A-F]?\").replace(/nn/g, \"[0-9A-F][0-9A-F]?\").replace(/\\+/g, \"\\\\+\") + \"|)\";\n }\n this.regexOpModes = new RegExp(sRegEx);\n }\n /*\n * Regrettably, if \"classic\" operand syntax is in effect, then we will have to look at the context of the\n * operand (ie, the operation code) whenever we have a MODE_IMM16 (or MODE_DISP) match, because it might actually\n * be a MODE_ABS operand. MODE_IMM16 is used with only 2 operations (OP_JSR and OP_JMP), and MODE_DISP only 8\n * (OP_BPL, OP_BMI, OP_BVC, OP_BVS, OP_BCC, OP_BCS, OP_BNE, and OP_BEQ), so if the operation isn't one of those\n * codes (in the following array), then we should convert MODE_IMM16 (aka MODE_DISP) into MODE_ABS.\n */\n this.aImm16Codes = [this.OP_JMP, this.OP_JSR, this.OP_BPL, this.OP_BMI, this.OP_BVC, this.OP_BVS, this.OP_BCC, this.OP_BCS, this.OP_BNE, this.OP_BEQ];\n }\n\n /**\n * @this {C1PDebugger}\n */\n halt()\n {\n /*\n * We ask the CPU to halt, but we can't assume it's stopped until it calls stop()\n */\n this.cpu.halt();\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string} s is any diagnostic string that you can print later using the Debugger's \"i\" command\n */\n info(s)\n {\n if (DEBUG) {\n this.aInfoBuffer[this.iInfoBuffer++] = s;\n if (this.iInfoBuffer >= this.aInfoBuffer.length)\n this.iInfoBuffer = 0;\n }\n }\n\n /**\n * @this {C1PDebugger}\n * @param {Component} component\n * @param {number} addr\n * @param {number|undefined} addrFrom\n * @param {boolean} bitsMessage is a Debugger MESSAGE_* category flag\n * @param {boolean|undefined} [fWrite] is true if this was a write, false (or undefined) if read\n * @param {string|undefined} [name] of the port, if any\n */\n messageIO(component, addr, addrFrom, bitsMessage, fWrite, name)\n {\n if ((this.bitsMessage & bitsMessage) == bitsMessage) {\n var b = this.cpu.getByte(addr);\n this.message(component.id + \".\" + (fWrite? \"setByte\":\"getByte\") + \"(\" + Str.toHexWord(addr) + \")\" + (addrFrom !== undefined? (\" @\" + Str.toHexWord(addrFrom)) : \"\") + \": \" + (name? (name + \"=\") : \"\") + Str.toHexByte(b));\n }\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string} sMessage is any caller-defined message string\n */\n message(sMessage)\n {\n this.println(sMessage);\n this.cpu.yieldCPU(); // these print() calls are at risk of being called with high frequency, so we need to yieldCPU() more\n }\n\n /**\n * @this {C1PDebugger}\n */\n init()\n {\n // this.doHelp();\n this.println(\"Type ? for list of debugger commands\\n\");\n }\n\n /**\n * @this {C1PDebugger}\n * @return {boolean}\n */\n run()\n {\n if (!this.isCPUOK()) return false;\n this.cpu.run();\n return true;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} n (0 implies a single-step, and therefore breakpoints should be ignored)\n * @return {boolean}\n */\n step(n)\n {\n if (!this.isCPUOK()) return false;\n var fCompleted;\n try {\n fCompleted = this.cpu.step(n);\n }\n catch(e) {\n fCompleted = undefined;\n this.cpu.setError(e.stack || e.message);\n }\n if (fCompleted !== undefined) this.cIns++;\n /*\n * Because we called cpu.step() and not cpu.run(), we must\n * nudge the CPU's update code, and then update our own state.\n */\n this.cpu.update(true);\n this.update(true);\n return fCompleted;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {boolean} [fStep]\n */\n update(fStep)\n {\n this.nextAddr = this.cpu.regPC;\n if (fStep || this.fStepOver)\n this.doUnassemble();\n else\n this.doRegisters();\n }\n\n /**\n * @this {C1PDebugger}\n * @return {boolean}\n *\n * Make sure the CPU is ready (finished initializing), not busy (already running), and not in an error state.\n */\n isCPUOK()\n {\n if (!this.cpu)\n return false;\n if (!this.cpu.isReady())\n return false;\n if (this.cpu.isBusy())\n return false;\n return !this.cpu.isError();\n }\n\n /**\n * @this {C1PDebugger}\n *\n * This is a notification handler, called by the CPU, to inform us that the CPU has been reset.\n */\n reset()\n {\n var i;\n if (!this.aStepHistory.length)\n this.aStepHistory = new Array(1000);\n for (i = 0; i < this.aStepHistory.length; i++)\n this.aStepHistory[i] = -1;\n if (!this.aaOpcodeFreqs.length)\n this.aaOpcodeFreqs = new Array(256);\n for (i = 0; i < this.aaOpcodeFreqs.length; i++)\n this.aaOpcodeFreqs[i] = [i, 0];\n if (this.cIns) this.update();\n this.cIns = 0;\n this.cReads = this.cWrites = this.cWritesZP = 0;\n }\n\n /**\n * @this {C1PDebugger}\n *\n * This is a notification handler, called by the CPU, to inform us that the CPU has started running.\n */\n start()\n {\n if (!this.fStepOver) this.println(\"running\");\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} msStart\n * @param {number} nCycles\n *\n * This is a notification handler, called by the CPU, to inform us that the CPU has now stopped running.\n */\n stop(msStart, nCycles)\n {\n if (!this.fStepOver) {\n this.println(\"stopped\");\n if (nCycles) {\n var msTotal = Usr.getTime();\n msTotal -= msStart;\n this.println(msTotal + \"ms (\" + nCycles + \" cycles)\");\n if (DEBUG && msTotal > 0) {\n nCycles = nCycles * 1000 / msTotal;\n this.println(\"total cycles/second: \" + Math.round(nCycles));\n var percent = Math.round((this.cIns? this.cReads / this.cIns : 0) * 1000) / 10;\n this.println(\"total reads: \" + this.cReads + \" (\" + percent + \"%)\");\n percent = Math.round((this.cIns? this.cWrites / this.cIns : 0) * 1000) / 10;\n this.println(\"total writes: \" + this.cWrites + \" (\" + percent + \"%)\");\n percent = Math.round((this.cIns? this.cWritesZP / this.cIns : 0) * 1000) / 10;\n this.println(\"total zero-page writes: \" + this.cWritesZP + \" (\" + percent + \"%)\");\n this.println(\"total instructions: \" + this.cIns);\n }\n }\n }\n this.update();\n this.setFocus();\n if (!this.fStepOver) {\n this.cIns = 0;\n this.cReads = this.cWrites = this.cWritesZP = 0;\n }\n this.clearTempBreakpoint(this.cpu.regPC);\n }\n\n /**\n * @this {C1PDebugger}\n *\n * This is a check function, called by the CPU, indicating whether other instructions need to be checked.\n */\n checksEnabled()\n {\n return (DEBUG? true : (this.aExecBreak.length > 0 || this.aReadBreak.length > 0 || this.aWriteBreak.length > 0));\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @param {number} bOpCode\n * @return {boolean} true to proceed, false to halt\n *\n * This is a check function, called by the CPU, to inform us about the next instruction to be executed, giving\n * us an opportunity to look for \"exec\" breakpoints and update opcode frequencies and instruction history.\n */\n checkInstruction(addr, bOpCode)\n {\n var fBreak = false;\n if (this.checkBreakpoint(addr, this.aExecBreak, \"exec\"))\n fBreak = true;\n else {\n this.cIns++;\n this.aaOpcodeFreqs[bOpCode][1]++;\n this.aStepHistory[this.iStepHistory++] = this.cpu.regPC;\n if (this.iStepHistory >= this.aStepHistory.length)\n this.iStepHistory = 0;\n }\n return !fBreak;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @return {boolean} true to proceed, false to halt\n *\n * This is a check function, called by the CPU, to inform us that a memory read occurred, giving us an\n * opportunity to track the read if we want, and look for a matching \"read\" breakpoint, if any.\n */\n checkMemoryRead(addr)\n {\n var fBreak = false;\n this.cReads++;\n if (this.checkBreakpoint(addr, this.aReadBreak, \"read\"))\n fBreak = true;\n return !fBreak;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @param {number} value written\n * @return {boolean} true to proceed, false to halt\n *\n * This is a check function, called by the CPU, to inform us that a memory write occurred, giving us an\n * opportunity to track the write if we want, and look for a matching \"write\" breakpoint, if any.\n */\n checkMemoryWrite(addr, value)\n {\n var fBreak = false;\n this.cWrites++;\n /*\n * NOTE: We keep track of zero-page writes mainly as a reminder to look into whether it makes sense\n * for the CPU to calculate zero-page EAs using a different variable (eg, regEAWriteZP instead of regEAWrite),\n * because write-notification handlers never care about page zero accesses, and while write breakpoints *may*\n * care, it may not be worth the cost of tracking writes to page zero if there's an associated perf penalty.\n */\n if (!(addr & 0xff00))\n this.cWritesZP++;\n if ((value & 0xff) != value) {\n this.println(\"invalid value at \" + Str.toHexWord(addr) + \": \" + value);\n fBreak = true;\n }\n if (this.checkBreakpoint(addr, this.aWriteBreak, \"write\"))\n fBreak = true;\n return !fBreak;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @param {number} b\n * @return {number}\n */\n addSignedByte(addr, b)\n {\n return addr + ((b << 24) >> 24);\n }\n\n /**\n * getByte() should be used for all memory reads performed by the Debugger (eg, doDump, doUnassemble),\n * to insure that the CPU is properly notified (and by extension, any device that's registered a\n * notification handler with the CPU).\n *\n * @this {C1PDebugger}\n * @param {number} addr\n * @return {number|undefined}\n */\n getByte(addr)\n {\n var b;\n if (addr >= this.offMem && addr < this.offLimit) {\n this.cpu.checkReadNotify(addr);\n b = this.abMem[this.offMem + addr];\n\n b &= 0xff;\n }\n return b;\n }\n\n /**\n * setByte() should be used for all memory writes performed by the Debugger (eg, doAssemble, doEdit),\n * to insure that the CPU is properly notified (and by extension, any device that's registered a\n * notification handler with the CPU).\n *\n * NOTE: Even though we call all write-notification handlers, we don't include a \"from\" address,\n * because the write originated from the Debugger, not from a CPU instruction. As a result, handlers should\n * not refuse the write unless they have good reason; in particular, the ROM handlers will not refuse our writes,\n * allowing the Debugger to modify ROM contents as needed.\n *\n * @this {C1PDebugger}\n * @param {number} addr\n * @param {number} b\n */\n setByte(addr, b)\n {\n if (addr < this.offMem || addr >= this.offLimit) {\n this.println(\"invalid address: \" + Str.toHexWord(addr));\n return;\n }\n this.abMem[this.offMem + addr] = (b & 0xff);\n this.cpu.checkWriteNotify(addr);\n this.cpu.update();\n }\n\n /**\n * @this {C1PDebugger}\n */\n clearBreakpoints()\n {\n this.aExecBreak = [];\n this.aReadBreak = [];\n this.aWriteBreak = [];\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @return {boolean}\n */\n addExecBreakpoint(addr)\n {\n if (!this.findExecBreakpoint(addr)) {\n this.aExecBreak.push(addr);\n }\n return true;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @return {boolean}\n */\n addReadBreakpoint(addr)\n {\n if (!this.findReadBreakpoint(addr)) {\n this.aReadBreak.push(addr);\n }\n return true;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @return {boolean}\n */\n addWriteBreakpoint(addr)\n {\n if (!this.findWriteBreakpoint(addr)) {\n this.aWriteBreak.push(addr);\n }\n return true;\n }\n\n /**\n * @this {C1PDebugger}\n * @return {Array}\n */\n getExecBreakpoints()\n {\n return this.aExecBreak;\n }\n\n /**\n * @this {C1PDebugger}\n * @return {Array}\n */\n getReadBreakpoints()\n {\n return this.aReadBreak;\n }\n\n /**\n * @this {C1PDebugger}\n * @return {Array}\n */\n getWriteBreakpoints()\n {\n return this.aWriteBreak;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {Array} aBreak\n * @param {number} addr\n * @param {boolean} [fRemove]\n * @return {boolean}\n */\n findBreakpoint(aBreak, addr, fRemove)\n {\n var fMatch = false;\n for (var i=0; i < aBreak.length; i++) {\n if (aBreak[i] == addr) {\n if (fRemove) {\n aBreak.splice(i, 1);\n }\n fMatch = true;\n break;\n }\n }\n return fMatch;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @param {boolean} [fRemove]\n * @return {boolean}\n */\n findExecBreakpoint(addr, fRemove)\n {\n return this.findBreakpoint(this.aExecBreak, addr, fRemove);\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @param {boolean} [fRemove]\n * @return {boolean}\n */\n findReadBreakpoint(addr, fRemove)\n {\n return this.findBreakpoint(this.aReadBreak, addr, fRemove);\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @param {boolean} [fRemove]\n * @return {boolean}\n */\n findWriteBreakpoint(addr, fRemove)\n {\n return this.findBreakpoint(this.aWriteBreak, addr, fRemove);\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number|undefined} addr of new temp breakpoint\n */\n setTempBreakpoint(addr)\n {\n if (addr !== undefined) {\n /*\n * I don't want temporary breakpoints growing out of control, so I forcibly clear any\n * existing temp breakpoint by feeding clearTempBreakpoint() the current temp address, if any;\n * but you can remove the next line if you decide multiple temp breakpoints are a good thing.\n */\n this.clearTempBreakpoint(this.addrTempBP);\n if (this.addExecBreakpoint(addr))\n this.addrTempBP = addr;\n }\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr to compare to addrTempBP; the latter is cleared if there's a match\n */\n clearTempBreakpoint(addr)\n {\n if (this.addrTempBP !== undefined && addr == this.addrTempBP) {\n if (this.findExecBreakpoint(this.addrTempBP, true)) {\n this.addrTempBP = undefined;\n }\n }\n this.fStepOver = false;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @param {Array} aBreakpoints\n * @param {string} sType (ie, \"exec\" or \"write\")\n * @return {boolean} true if breakpoint has been hit, false if not\n */\n checkBreakpoint(addr, aBreakpoints, sType)\n {\n /*\n * Time to check for execution breakpoints; note that this should be done BEFORE updating any of the frequency\n * or history data (see checkInstruction), since we might not actually execute the current instruction.\n */\n var fBreak = false;\n for (var i=0; i < aBreakpoints.length; i++) {\n if (aBreakpoints[i] == addr) {\n if (addr != this.addrTempBP)\n this.println(\"breakpoint hit: \" + Str.toHexWord(addr) + \" (\" + sType + \")\");\n fBreak = true;\n break;\n }\n }\n return fBreak;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @param {number} [nIns] is an associated instruction number, or 0 (or undefined) if none\n * @return {string}\n */\n getInstruction(addr, nIns)\n {\n var sLine = Str.toHex(addr, 4);\n var bOpCode = this.getByte(addr++);\n var b = (bOpCode === undefined? 0 : bOpCode);\n var aOpDesc = this.aaOperations[b];\n var abOperand = [];\n var cb = (aOpDesc[1] === undefined? 0 : aOpDesc[1]);\n do {\n sLine += \" \" + Str.toHex(b, 2);\n if (!(cb--)) break;\n b = this.getByte(addr++);\n if (b === undefined) break;\n abOperand.push(b);\n } while (true);\n if (aOpDesc[0] === undefined) {\n aOpDesc = [this.OP_DB, 1, this.MODE_IMM];\n abOperand.push(bOpCode);\n }\n sLine = (sLine + \" \").substr(0, 15);\n sLine += this.aOpCodes[aOpDesc[0]];\n var sOperand = null;\n if (aOpDesc[2] !== undefined) {\n var bOpMode = aOpDesc[2];\n sOperand = this.aOpModes[bOpMode];\n if (aOpDesc[1] == 1 && bOpMode == this.MODE_DISP) {\n sOperand = sOperand.replace(/nnnn/, Str.toHex(this.addSignedByte(addr, b = abOperand.pop()), 4));\n }\n else {\n while (abOperand.length) {\n sOperand = sOperand.replace(/nn/, Str.toHex(b = abOperand.pop(), 2));\n }\n }\n if (bOpMode == this.MODE_IMM && aOpDesc[1] == 1) {\n if (b >= 0x20 && b < 0x80)\n sOperand += \" ;'\" + String.fromCharCode(b) + \"'\";\n }\n }\n if (bOpCode == this.cpu.OP_SIM) {\n if (b < this.aOpSimCodes.length)\n sOperand = this.aOpSimCodes[b];\n if (b == this.cpu.SIMOP_MSG) {\n cb = 0;\n sOperand = \"\\\"\";\n while ((b = this.getByte(addr++))) {\n if (cb < 16)\n sOperand += String.fromCharCode(b);\n else if (cb == 16)\n sOperand += \"…\";\n cb++;\n }\n sOperand += \"\\\"\";\n }\n }\n if (sOperand) sLine += \" \" + sOperand;\n if (nIns) {\n sLine += \" \";\n sLine = sLine.substr(0, 30);\n sLine += \";\" + nIns.toString();\n }\n this.nextIns = addr;\n return sLine;\n }\n\n /**\n * parseInstruction(sCode, sOperand, addr)\n *\n * This generally requires an exact match of both the operation code (sCode) and mode operand (sOperand)\n * against the aOpCodes[] and aOpModes[] arrays, respectively; however, the regular expression built from\n * aOpModes and stored in regexOpModes does relax the matching criteria slightly; ie, a 4-digit hex value\n * (\"nnnn\") will be satisfied with either 3 or 4 digits, and similarly, a 2-digit hex address (nn) will\n * be satisified with either 1 or 2 digits.\n *\n * Note that this function does not actually store the instruction into memory, even though it requires\n * a target address (addr); that parameter is currently needed ONLY for \"branch\" instructions, because in\n * order to calculate the branch displacement, it needs to know where the instruction will ultimately be\n * stored, relative to its target address.\n *\n * Another handy feature of this function is its ability to display all available modes for a particular\n * operation. For example, while in \"assemble mode\", if one types:\n *\n * ldy?\n *\n * the Debugger will display:\n *\n * supported opcodes:\n * A0: LDY nn\n * A4: LDY [nn]\n * AC: LDY [nnnn]\n * B4: LDY [nn+X]\n * BC: LDY [nnnn+X]\n *\n * Use of a trailing \"?\" on any opcode will display all variations of that opcode; no instruction will be\n * assembled, and the operand parameter, if any, will be ignored.\n *\n * Although this function is capable of reporting numerous errors, roughly half of them indicate internal\n * consistency errors, not user errors; the former should really be asserts, but I'm not comfortable bombing\n * out because of my error as opposed to their error. The only errors a user should expect to see:\n *\n * \"unknown operation\": sCode is not a valid operation (per aOpCodes)\n * \"unknown operand\": sOperand is not a valid operand (per aOpModes)\n * \"unknown instruction\": the combination of sCode + sOperand does not exist (per aaOperations)\n * \"branch out of range\": the branch address, relative to addr, is too far away\n *\n * @this {C1PDebugger}\n * @param {string} sCode\n * @param {string|undefined} sOperand\n * @param {number} addr of memory where this instruction is being assembled\n * @return {Array.<number>} of opcode bytes; if the instruction can't be parsed, the array will be empty\n */\n parseInstruction(sCode, sOperand, addr)\n {\n var aOpBytes = [];\n if (sCode !== undefined) {\n var iCode, iMode;\n /*\n * Find the iCode that corresponds to the given operation code\n */\n sCode = sCode.toUpperCase();\n if (sCode.charAt(sCode.length-1) == \"?\") {\n sOperand = \"?\";\n sCode = sCode.substr(0, sCode.length-1);\n }\n for (iCode=0; iCode < this.aOpCodes.length; iCode++) {\n if (sCode == this.aOpCodes[iCode]) {\n break;\n }\n }\n if (iCode == this.aOpCodes.length) {\n this.println(\"unknown operation: \" + sCode);\n iCode = -1;\n }\n var sMode = \"\", aModeMatch, i;\n if (iCode >= 0 && sOperand !== undefined) {\n sMode = sOperand.toUpperCase();\n if (sMode == \"?\") {\n var cModes = 0;\n for (i = 0; i < this.aaOperations.length; i++) {\n if (this.aaOperations[i][0] === iCode) {\n if (!cModes) this.println(\"supported opcodes:\");\n this.println(\" \" + Str.toHex(i, 2) + \": \" + sCode + (this.aaOperations[i][2] !== undefined? (\" \" + this.aOpModes[this.aaOperations[i][2]]) : \"\"));\n cModes++;\n }\n }\n iCode = -1;\n }\n else {\n /*\n * Find the iMode that corresponds to the given operand\n */\n aModeMatch = sMode.match(this.regexOpModes);\n if (aModeMatch !== null && aModeMatch[0] == sMode) {\n /*\n * One of the sub-patterns must have matched as well; the index of the matching\n * sub-pattern will correspond to the proper aOpModes index, albeit off-by-one since\n * the regex match at [0] is the complete match, not a sub-pattern match.\n */\n for (i = 1; i < aModeMatch.length; i++) {\n if (aModeMatch[i] == sMode) {\n if (iMode === undefined)\n iMode = i-1;\n else {\n /*\n * This is really an internal consistency error; regardless what the user types, this should not occur.\n */\n //noinspection JSUnusedAssignment\n this.println(\"too many operand matches (both \" + this.aOpModes[iMode] + \" and \" + this.aOpModes[i-1] + \")\");\n iCode = -1;\n break;\n }\n }\n }\n /*\n * Regrettably, if \"classic\" operand syntax is in effect, then we must look at the context of the\n * operand (ie, the operation code) whenever we have a MODE_IMM16 (or MODE_DISP) match, because it might\n * actually be a MODE_ABS operand; see setOpModes() for details of the aImm16Codes array.\n */\n if (iMode == this.MODE_IMM16) {\n if (this.aImm16Codes.indexOf(iCode) < 0)\n iMode = this.MODE_ABS;\n }\n /*\n * Even in \"modern\" syntax mode, we have to look at the context of a MODE_ABS16 match, because unless\n * the operation is OP_JMP, then the mode must actually be MODE_ABS.\n */\n if (iMode == this.MODE_ABS16) {\n if (iCode != this.OP_JMP)\n iMode = this.MODE_ABS;\n }\n }\n else {\n this.println(\"unknown operand: \" + sMode);\n iCode = -1;\n }\n }\n }\n if (iCode >= 0) {\n /*\n * So we have an iCode and possibly an iMode; find the one (and hopefully only) aaOperations instruction entry that matches\n */\n var bOpCode = -1;\n for (i = 0; i < this.aaOperations.length; i++) {\n if (this.aaOperations[i][0] === iCode && this.aaOperations[i][2] === iMode) {\n if (bOpCode < 0)\n bOpCode = i;\n else {\n /*\n * This is really an internal consistency error; regardless what the user types, this should not occur.\n */\n this.println(\"too many instruction matches (both \" + Str.toHexByte(bOpCode) + \" and \" + Str.toHexByte(i) + \")\");\n bOpCode = -2;\n break;\n }\n }\n }\n if (bOpCode >= 0) {\n aOpBytes.push(bOpCode);\n if (iMode !== undefined) {\n var cb = this.aaOperations[bOpCode][1];\n var asHex = sMode.match(/[0-9A-F]+/);\n if (asHex !== null) {\n var nHex = parseInt(asHex[0], 16);\n if (cb == 1 && iMode == this.MODE_DISP) {\n nHex -= (addr + 2);\n if (nHex < -128 || nHex > 127) {\n this.println(\"branch out of range (\" + nHex + \")\");\n aOpBytes = [];\n cb = 0;\n }\n }\n for (i = 0; i < cb; i++) {\n aOpBytes.push(nHex & 0xff);\n nHex >>>= 8;\n }\n }\n else if (cb) {\n /*\n * This is really an internal consistency error; regardless what the user types, this should not occur.\n */\n this.println(\"instruction missing \" + cb + \" bytes\");\n }\n }\n }\n else {\n this.println(\"unknown instruction: \" + sCode + \" \" + sMode + (DEBUG? (\" (\" + iMode + \")\") : \"\"));\n }\n }\n }\n return aOpBytes;\n }\n\n /**\n * @this {C1PDebugger}\n * @return {string}\n */\n getRegs()\n {\n return \"A=\" + Str.toHex(this.cpu.regA, 2) +\n \" X=\" + Str.toHex(this.cpu.regX, 2) +\n \" Y=\" + Str.toHex(this.cpu.regY, 2) +\n \" P=\" + Str.toHex(this.cpu.getRegP(), 2) +\n \" S=\" + Str.toHex(this.cpu.regS, 4) +\n \" PC=\" + Str.toHex(this.cpu.regPC, 4);\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string|undefined} [sAddr]\n * @return {number|undefined}\n */\n getUserAddr(sAddr)\n {\n var addr = this.nextAddr;\n if (sAddr !== undefined) {\n var nBase = 16;\n if (sAddr.charAt(0) == \"$\")\n sAddr = sAddr.substr(1);\n else\n if (sAddr.substr(0, 2) == \"0x\")\n sAddr = sAddr.substr(2);\n else\n if (sAddr.charAt(sAddr.length-1) == \".\") {\n nBase = 10;\n sAddr = sAddr.substr(0, sAddr.length-1);\n }\n addr = parseInt(sAddr, nBase);\n if (isNaN(addr)) {\n this.println(\"invalid base-\" + nBase + \" address: \" + sAddr);\n addr = undefined;\n }\n }\n if (addr !== undefined && (addr < this.offMem || addr >= this.offLimit)) {\n this.println(\"address out of range: \" + Str.toHex(addr));\n addr = undefined;\n }\n return addr;\n }\n\n /**\n * @this {C1PDebugger}\n */\n doHelp()\n {\n this.println(\"\\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\");\n this.println(\"note: frequency and history commands operate only when breakpoints are set\");\n }\n\n /**\n * doAssemble() always receives the complete argument array, where the order of the arguments is:\n *\n * [0]: the assemble command (assumed to be \"a\")\n * [1]: the target address (eg, \"200\")\n * [2]: the operation code, aka mnemonic (eg, \"adc\")\n * [3]: the operation mode operand, if any (eg, \"14\", \"[1234]\", etc)\n *\n * The Debugger enters \"assemble mode\" whenever only the first (or first and second) arguments are present.\n * As long as \"assemble mode is active, the user can omit the first two arguments on all later assemble commands\n * until \"assemble mode\" is cancelled with an empty command line; the command processor automatically prepends \"a\"\n * and the next available target address to the argument array.\n *\n * Entering \"assemble mode\" is optional; one could enter a series of fully-qualified assemble commands; eg:\n *\n * a ff00 cld\n * a ff01 ldx 28\n * ...\n *\n * without ever entering \"assemble mode\", but of course, that requires more typing and doesn't take advantage\n * of automatic target address advancement (see addrAssembleNext).\n *\n * NOTE: As the previous example implies, you can even assemble new instructions into ROM address space;\n * as our setByte() function explains, the ROM write-notification handlers only refuse writes from the CPU.\n *\n * @this {C1PDebugger}\n * @param {Array.<string>} asArgs is the complete argument array, beginning with the \"a\" command in asArgs[0]\n */\n doAssemble(asArgs)\n {\n var addr = this.getUserAddr(asArgs[1]);\n if (addr === undefined)\n return;\n this.addrAssembleNext = addr;\n if (asArgs[2] === undefined) {\n this.println(\"begin assemble @\" + Str.toHexWord(this.addrAssembleNext));\n this.fAssemble = true;\n this.cpu.update();\n return;\n }\n var aOpBytes = this.parseInstruction(asArgs[2], asArgs[3], this.addrAssembleNext);\n if (aOpBytes.length) {\n for (var i=0; i < aOpBytes.length; i++) {\n // this.println(Str.toHexWord(this.addrAssembleNext) + \": \" + Str.toHexByte(aOpBytes[i]));\n this.setByte(this.addrAssembleNext+i, aOpBytes[i]);\n }\n this.println(this.getInstruction(this.addrAssembleNext));\n this.addrAssembleNext += aOpBytes.length;\n }\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string} [sParm]\n * @param {string} [sAddr]\n */\n doBreak(sParm, sAddr)\n {\n if (sParm === undefined || sParm == \"?\") {\n this.println(\"\\nbreakpoint commands:\");\n this.println(\"bp [a]\\tset exec breakpoint at [a]\");\n this.println(\"br [a]\\tset read breakpoint at [a]\");\n this.println(\"bw [a]\\tset write breakpoint at [a]\");\n this.println(\"bc [a]\\tclear breakpoint at [a]\");\n this.println(\"bl\\tlist all breakpoints\");\n return;\n }\n if (sAddr === undefined && sParm.length > 1) {\n sAddr = sParm.substr(1);\n sParm = sParm.substr(0, 1);\n }\n if (sParm == \"l\") {\n var cBreaks = 0, i;\n var aAddrs = this.getExecBreakpoints();\n for (i = 0; i < aAddrs.length; i++) {\n this.println(\"breakpoint enabled: \" + Str.toHexWord(aAddrs[i]) + \" (exec)\");\n cBreaks++;\n }\n aAddrs = this.getReadBreakpoints();\n for (i = 0; i < aAddrs.length; i++) {\n this.println(\"breakpoint enabled: \" + Str.toHexWord(aAddrs[i]) + \" (read)\");\n cBreaks++;\n }\n aAddrs = this.getWriteBreakpoints();\n for (i = 0; i < aAddrs.length; i++) {\n this.println(\"breakpoint enabled: \" + Str.toHexWord(aAddrs[i]) + \" (write)\");\n cBreaks++;\n }\n if (!cBreaks)\n this.println(\"no breakpoints\");\n return;\n }\n if (sAddr === undefined) {\n this.println(\"missing breakpoint address\");\n return;\n }\n if (sParm == \"c\" && sAddr == \"*\") {\n this.clearBreakpoints();\n this.println(\"all breakpoints cleared\");\n return;\n }\n var addr = this.getUserAddr(sAddr);\n if (addr === undefined)\n return;\n if (sParm == \"p\") {\n if (this.addExecBreakpoint(addr))\n this.println(\"breakpoint enabled: \" + Str.toHexWord(addr) + \" (exec)\");\n else\n this.println(\"breakpoint not set: \" + Str.toHexWord(addr));\n return;\n }\n if (sParm == \"c\") {\n if (this.findExecBreakpoint(addr, true))\n this.println(\"breakpoint cleared: \" + Str.toHexWord(addr) + \" (exec)\");\n else\n if (this.findReadBreakpoint(addr, true))\n this.println(\"breakpoint cleared: \" + Str.toHexWord(addr) + \" (read)\");\n else\n if (this.findWriteBreakpoint(addr, true))\n this.println(\"breakpoint cleared: \" + Str.toHexWord(addr) + \" (write)\");\n else\n this.println(\"breakpoint missing: \" + Str.toHexWord(addr));\n return;\n }\n if (sParm == \"r\") {\n if (this.addReadBreakpoint(addr))\n this.println(\"breakpoint enabled: \" + Str.toHexWord(addr) + \" (read)\");\n else\n this.println(\"breakpoint not set: \" + Str.toHexWord(addr));\n return;\n }\n if (sParm == \"w\") {\n if (this.addWriteBreakpoint(addr))\n this.println(\"breakpoint enabled: \" + Str.toHexWord(addr) + \" (write)\");\n else\n this.println(\"breakpoint not set: \" + Str.toHexWord(addr));\n return;\n }\n this.println(\"unknown breakpoint command: \" + sParm);\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string} sAddr\n * @param {string} sLen\n */\n doDump(sAddr, sLen)\n {\n if (sAddr == \"?\") {\n this.println(\"\\ndump commands:\");\n this.println(\"d [a] [#] dump # lines of memory\");\n return;\n }\n var addr = this.getUserAddr(sAddr);\n if (addr === undefined)\n return;\n var cLines = 0;\n if (sLen !== undefined) {\n if (sLen.charAt(0) == \"l\")\n sLen = sLen.substr(1);\n cLines = parseInt(sLen, 10);\n }\n if (!cLines) cLines = 1;\n for (var line=0; line < cLines; line++) {\n var sBytes = \"\";\n var sChars = \"\";\n var addrLine = addr;\n for (var i=0; i < 8 && addr < this.offLimit; i++) {\n var b = this.getByte(addr);\n if (b === undefined) b = 0;\n sBytes += Str.toHex(b, 2) + \" \";\n sChars += (b >= 32 && b < 127? String.fromCharCode(b) : \".\");\n addr++;\n }\n this.println(Str.toHex(addrLine, 4) + \" \" + sBytes + sChars);\n }\n this.nextAddr = addr;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {Array.<string>} asArgs\n */\n doEdit(asArgs)\n {\n var sAddr = asArgs[1];\n if (sAddr === undefined) {\n this.println(\"missing address\");\n return;\n }\n var addr = this.getUserAddr(sAddr);\n if (addr === undefined)\n return;\n for (var i=2; i < asArgs.length; i++) {\n var b = parseInt(asArgs[i], 16);\n this.setByte(addr++, b);\n }\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string} sParm\n */\n doFreqs(sParm)\n {\n if (sParm == \"?\") {\n this.println(\"\\nfrequency commands:\");\n this.println(\"clear\\tclear all frequency counts\");\n return;\n }\n var cData = 0, i;\n if (this.aaOpcodeFreqs) {\n if (sParm == \"clear\") {\n for (i = 0; i < this.aaOpcodeFreqs.length; i++)\n this.aaOpcodeFreqs[i] = [i, 0];\n this.println(\"frequency data cleared\");\n cData++;\n }\n else if (sParm !== undefined) {\n this.println(\"unknown frequency command: \" + sParm);\n cData++;\n }\n else {\n var aaSortedOpcodeFreqs = this.aaOpcodeFreqs.slice();\n aaSortedOpcodeFreqs.sort(function(p, q) {return q[1] - p[1];});\n for (i = 0; i < aaSortedOpcodeFreqs.length; i++) {\n var bOpcode = aaSortedOpcodeFreqs[i][0];\n var cFreq = aaSortedOpcodeFreqs[i][1];\n if (cFreq) {\n this.println(this.aOpCodes[this.aaOperations[bOpcode][0]] + \" (\" + Str.toHexByte(bOpcode) + \"): \" + cFreq + \" times\");\n cData++;\n }\n }\n }\n }\n if (!cData) {\n this.println(\"no frequency data available\");\n }\n }\n\n /**\n * @this {C1PDebugger}\n */\n doHalt()\n {\n this.halt();\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string} sCount\n */\n doHistory(sCount)\n {\n var cLines = 10;\n var iHistory = this.iStepHistory;\n var aHistory = this.aStepHistory;\n if (aHistory !== undefined) {\n var n = (sCount === undefined? this.nextHistory : parseInt(sCount, 10));\n if (n === undefined)\n n = 10;\n if (n > aHistory.length) {\n this.println(\"note: only \" + aHistory.length + \" available\");\n n = aHistory.length;\n }\n if (sCount !== undefined) {\n this.nInsHistory = 0;\n this.println(n + \" instructions earlier:\");\n }\n var nIns = (this.nInsHistory? this.nInsHistory : 1);\n iHistory -= n;\n if (iHistory < 0) iHistory = aHistory.length - 1;\n while (cLines && iHistory != this.iStepHistory) {\n var addr = aHistory[iHistory];\n if (addr < 0) break;\n this.println(this.getInstruction(addr, nIns++));\n if (++iHistory == aHistory.length) iHistory = 0;\n cLines--;\n n--;\n }\n this.nextHistory = n;\n this.nInsHistory = nIns;\n }\n if (cLines == 10) this.println(\"no history available\");\n }\n\n /**\n * Prints the contents of the Debugger's \"info\" buffer (filled by calls like cpu.dbg.info())\n * @this {C1PDebugger}\n * @param {string|undefined} sCount\n * @return {boolean|undefined} true only if the \"info\" command is supported\n */\n doInfo(sCount)\n {\n if (DEBUG) {\n var cLines = (sCount === undefined? -1 : parseInt(sCount, 10));\n var i = this.iInfoBuffer;\n do {\n var s = this.aInfoBuffer[i++];\n if (s !== undefined) {\n this.println(s);\n cLines--;\n }\n if (i >= this.aInfoBuffer.length)\n i = 0;\n } while (cLines && i != this.iInfoBuffer);\n this.println(\"nYieldsPerSecond: \" + this.cpu.nYieldsPerSecond);\n this.println(\"msPerYield: \" + this.cpu.msPerYield);\n this.println(\"nCyclesPerBurst: \" + this.cpu.nCyclesPerBurst);\n this.println(\"nCyclesPerYield: \" + this.cpu.nCyclesPerYield);\n this.println(\"nCyclesPerVideoUpdate: \" + this.cpu.nCyclesPerVideoUpdate);\n this.println(\"nCyclesPerStatusUpdate: \" + this.cpu.nCyclesPerStatusUpdate);\n return true;\n }\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string} [sAddr]\n * @param {string} [sAddrEnd]\n * @param {number} [n]\n */\n doUnassemble(sAddr, sAddrEnd, n)\n {\n var addr = this.getUserAddr(sAddr);\n if (addr === undefined)\n return;\n\n if (n === undefined) n = 1;\n var addrEnd = this.offLimit;\n if (sAddrEnd !== undefined) {\n addrEnd = this.getUserAddr(sAddrEnd);\n if (addrEnd === undefined || addrEnd < addr)\n return;\n if (!DEBUG && (addrEnd - addr) > 0x100) {\n /*\n * Limiting the amount of disassembled code to one \"memory page\" in non-DEBUG builds is partly\n * to prevent the user from wedging their browser, but also a recognition that, in non-DEBUG builds,\n * the println() output buffer is truncated to 8K, which is only enough for about two pages of\n * disassembled code anyway.\n */\n this.println(\"range too large\");\n return;\n }\n addrEnd++;\n n = -1;\n }\n\n if (addr != this.nextAddr)\n this.println();\n\n while (n-- && addr < addrEnd) {\n var sIns = this.getInstruction(addr, this.isBusy(false) || this.fStepOver? this.cIns : 0);\n this.println(sIns);\n this.nextAddr = addr = this.nextIns;\n }\n }\n\n /**\n * @this {C1PDebugger}\n * @param {Array.<string>} asArgs\n */\n doOptions(asArgs)\n {\n if (asArgs[1] === undefined || asArgs[1] == \"?\") {\n this.println(\"\\noption commands:\");\n this.println(\"max\\trun at maximum speed\");\n this.println(\"fast\\trun faster (up to \" + this.cpu.mhzFast + \"Mhz)\");\n this.println(\"slow\\trun at normal speed (1Mhz)\");\n this.println(\"classic\\tuse classic operand syntax\");\n this.println(\"modern\\tuse modern operand syntax\");\n this.println(\"msg\\tenable message categories\");\n return;\n }\n var sOption = asArgs[1];\n switch(sOption) {\n case \"slow\":\n this.cpu.setSpeed(this.cpu.SPEED_SLOW);\n break;\n case \"fast\":\n this.cpu.setSpeed(this.cpu.SPEED_FAST);\n break;\n case \"max\":\n this.cpu.setSpeed(this.cpu.SPEED_MAX);\n break;\n case \"classic\":\n this.setOpModes(true);\n this.println(\"classic syntax enabled\");\n break;\n case \"modern\":\n this.setOpModes(false);\n this.println(\"modern syntax enabled\");\n break;\n case \"msg\":\n var bitsMessage = 0;\n if (asArgs[2] !== undefined) {\n if (asArgs[2] == \"all\")\n bitsMessage = 0xff;\n else if (this.aMessageCategories[asArgs[2]] !== undefined)\n bitsMessage = this.aMessageCategories[asArgs[2]];\n if (bitsMessage) {\n if (asArgs[3] == \"on\") {\n this.bitsMessage |= bitsMessage;\n }\n else if (asArgs[3] == \"off\") {\n this.bitsMessage &= ~bitsMessage;\n }\n }\n }\n for (var sCategory in this.aMessageCategories) {\n if (asArgs[2] !== undefined && (asArgs[2] != \"all\" && asArgs[2] != sCategory)) continue;\n bitsMessage = this.aMessageCategories[sCategory];\n this.println(sCategory + \" messages: \" + ((this.bitsMessage & bitsMessage)? \"on\" : \"off\"));\n }\n break;\n default:\n this.println(\"unknown option: \" + sOption);\n break;\n }\n }\n\n /**\n * @this {C1PDebugger}\n * @param {Array.<string>} [asArgs]\n */\n doRegisters(asArgs)\n {\n if (asArgs && asArgs[1] == \"?\") {\n this.println(\"\\nregister commands:\");\n this.println(\"r to display all\");\n this.println(\"r [target=value] to modify\");\n this.println(\"supported targets:\");\n this.println(\"A,X,Y,S,PC and flags C,Z,D,V,N\");\n return;\n }\n var fIns = true;\n if (asArgs !== undefined && asArgs.length > 1) {\n fIns = false;\n var sReg = asArgs[1];\n var sValue = null;\n var i = sReg.indexOf(\"=\");\n if (i > 0) {\n sValue = sReg.substr(i+1);\n sReg = sReg.substr(0, i);\n }\n else if (asArgs.length > 2) {\n sValue = asArgs[2];\n }\n else {\n this.println(\"missing value for \" + asArgs[1]);\n return;\n }\n var b = parseInt(sValue, 16);\n if (!isNaN(b)) {\n switch(sReg.toUpperCase()) {\n case \"A\":\n this.cpu.regA = b & 0xff;\n break;\n case \"X\":\n this.cpu.regX = b & 0xff;\n break;\n case \"Y\":\n this.cpu.regY = b & 0xff;\n break;\n case \"C\":\n if (b) this.cpu.setC(); else this.cpu.clearC();\n break;\n case \"Z\":\n if (b) this.cpu.setZ(); else this.cpu.clearZ();\n break;\n case \"D\":\n if (b) this.cpu.setBCD(); else this.cpu.clearBCD();\n break;\n case \"V\":\n if (b) this.cpu.setV(); else this.cpu.clearV();\n break;\n case \"N\":\n if (b) this.cpu.setN(); else this.cpu.clearN();\n break;\n case \"S\":\n if ((b & ~0xff) != 0x100) {\n this.println(\"invalid stack pointer: \" + sValue);\n return;\n }\n this.cpu.regS = b;\n break;\n case \"PC\":\n fIns = true;\n this.cpu.regPC = b & 0xffff;\n this.nextAddr = this.cpu.regPC;\n break;\n default:\n this.println(\"unknown register: \" + sReg);\n return;\n }\n }\n else {\n this.println(\"invalid value: \" + sValue);\n return;\n }\n this.cpu.update();\n }\n this.println(this.getRegs());\n if (fIns) this.doUnassemble(Str.toHex(this.nextAddr = this.cpu.regPC, 4));\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string} sAddr\n */\n doRun(sAddr)\n {\n if (sAddr !== undefined)\n this.setTempBreakpoint(this.getUserAddr(sAddr));\n if (!this.run()) {\n this.cpu.setFocus();\n }\n }\n\n /**\n * @this {C1PDebugger}\n */\n doStep()\n {\n if (this.getByte(this.cpu.regPC) == this.cpu.OP_JSR) {\n this.setTempBreakpoint(this.cpu.regPC+3);\n this.fStepOver = true;\n if (!this.run())\n this.cpu.setFocus();\n }\n else {\n this.doTrace();\n }\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string} [sCount]\n */\n doTrace(sCount)\n {\n var c = (sCount === undefined? 1 : parseInt(sCount, 10));\n var n = (c == 1? 0 : 1);\n Web.onCountRepeat(\n c,\n function(dbg) {\n return function() {\n return dbg.setBusy(true) && dbg.step(n);\n };\n }(this),\n function(dbg) {\n return function() {\n dbg.setBusy(false);\n };\n }(this)\n );\n }\n\n static input(dbg, sCmd)\n {\n if (!sCmd.length) {\n if (dbg.fAssemble) {\n dbg.println(\"ended assemble @\" + Str.toHex(dbg.addrAssembleNext, 4));\n dbg.nextAddr = dbg.addrAssembleNext;\n dbg.fAssemble = false;\n }\n else\n if (dbg.prevCmd)\n sCmd = dbg.prevCmd;\n }\n if (dbg.isReady() && !dbg.isBusy(true) && sCmd.length > 0) {\n\n if (dbg.fAssemble) {\n sCmd = \"a \" + Str.toHex(dbg.addrAssembleNext, 4) + \" \" + sCmd;\n }\n else if (sCmd.length > 1 && sCmd.indexOf(\" \") != 1) {\n /*\n * For certain commands lacking a space after the first character,\n * insert an automatic space, so that split(\" \") has the desired effect.\n */\n var ch = sCmd.charAt(0).toLowerCase();\n sCmd = ch + \" \" + sCmd.substr(1);\n }\n\n var asArgs = sCmd.split(\" \");\n dbg.prevCmd = asArgs[0];\n\n switch(asArgs[0].toLowerCase()) {\n case \"a\":\n dbg.doAssemble(asArgs);\n break;\n case \"b\":\n dbg.doBreak(asArgs[1], asArgs[2]);\n break;\n case \"d\":\n dbg.doDump(asArgs[1], asArgs[2]);\n break;\n case \"e\":\n dbg.doEdit(asArgs);\n break;\n case \"f\":\n dbg.doFreqs(asArgs[1]);\n break;\n case \"g\":\n dbg.doRun(asArgs[1]);\n break;\n case \"h\":\n dbg.doHalt();\n break;\n case \"o\":\n dbg.doOptions(asArgs);\n break;\n case \"p\":\n dbg.doHistory(asArgs[1]);\n break;\n case \"r\":\n dbg.doRegisters(asArgs);\n break;\n case \"s\":\n dbg.doStep();\n break;\n case \"t\":\n dbg.doTrace(asArgs[1]);\n break;\n case \"u\":\n dbg.doUnassemble(asArgs[1], asArgs[2], 8);\n break;\n case \"?\":\n case \"help\":\n dbg.doHelp();\n break;\n case \"i\":\n if (dbg.doInfo(asArgs[1])) break;\n /* falls through */\n default:\n dbg.println(\"unknown command: \" + sCmd);\n break;\n }\n }\n }\n\n /**\n * C1PDebugger.init()\n *\n * This function operates on every HTML element of class \"debugger\", extracting the\n * JSON-encoded parameters for the C1PDebugger constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a C1PDebugger component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeDbg = Component.getElementsByClass(document, C1PJS.APPCLASS, \"debugger\");\n for (var iDbg=0; iDbg < aeDbg.length; iDbg++) {\n var eDbg = aeDbg[iDbg];\n var parmsDbg = Component.getComponentParms(eDbg);\n var dbg = new C1PDebugger(parmsDbg);\n Component.bindComponentControls(dbg, eDbg, C1PJS.APPCLASS);\n }\n }\n}\n\nif (DEBUGGER) {\n\n /*\n * Initialize every Debugger module on the page (as IF there's ever going to be more than one ;-))\n */\n Web.onInit(C1PDebugger.init);\n\n} // endif DEBUGGER\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/computer.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass C1PComputer extends Component {\n /**\n * C1PComputer(parmsComputer, modules)\n *\n * The C1PComputer component expects the following (parmsComputer) properties:\n *\n * modules[{}] (from the <module> definition(s) for the computer)\n *\n * This component processes all the <module> \"start\" and \"end\" specifications\n * and \"wires\" everything to a common \"address buffer\"; namely, the abMemory array.\n * abMemory encompasses the computer's entire address space, but every component must\n * play nice and use only its assigned section of abMemory -- and pretend it's an array\n * of bytes, when in fact it's an array of floating-point values (the only primitive\n * numeric data type that JavaScript provides).\n *\n * This component also insures that all the other components are ready; in particular,\n * this means that the ROM and Video components have finished loading their resources\n * and are ready for operation. Other components become ready as soon as we call their\n * setBuffer() method (eg, CPU, RAM, Keyboard, Debugger, SerialPort, DiskController), and\n * others, like Panel, become ready even earlier, at the end of their initialization.\n *\n * Once every component has indicated it's ready, we call its setPower() notification\n * function (if it has one; it's optional). We call the CPU's setPower() function last,\n * so that the CPU is assured that all other components are ready and \"powered\".\n *\n * @this {C1PComputer}\n * @param {Object} parmsComputer\n * @param {Object} modules\n */\n constructor(parmsComputer, modules)\n {\n super(\"C1PComputer\", parmsComputer);\n\n this.modules = modules;\n }\n\n /**\n * reset(fPowerOn)\n *\n * @this {C1PComputer}\n * @param {boolean} [fPowerOn] is true to indicate that we should start the CPU running\n */\n reset(fPowerOn)\n {\n var cpu = null;\n for (var sType in this.modules) {\n for (var i=0; i < this.modules[sType].length; i++) {\n var component = this.modules[sType][i];\n if (component && component.reset) {\n if (DEBUG) this.println(\"resetting \" + sType);\n component.reset();\n if (sType == \"cpu\") cpu = component;\n }\n }\n }\n if (cpu) {\n cpu.update();\n if (fPowerOn) cpu.run();\n }\n }\n\n /**\n * start()\n *\n * Called by the CPU to notify all component start() handlers.\n *\n * @this {C1PComputer}\n */\n start()\n {\n for (var sType in this.modules) {\n if (sType == \"cpu\") continue;\n for (var i=0; i < this.modules[sType].length; i++) {\n var component = this.modules[sType][i];\n if (component && component.start) {\n component.start();\n }\n }\n }\n }\n\n /**\n * stop(msStart, nCycles)\n *\n * Called by the CPU to notify all component stop() handlers\n *\n * @this {C1PComputer}\n * @param {number} msStart\n * @param {number} nCycles\n */\n stop(msStart, nCycles)\n {\n for (var sType in this.modules) {\n if (sType == \"cpu\") continue;\n for (var i=0; i < this.modules[sType].length; i++) {\n var component = this.modules[sType][i];\n if (component && component.stop) {\n component.stop(msStart, nCycles);\n }\n }\n }\n }\n\n /**\n * @this {C1PComputer}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n switch(sBinding) {\n case \"reset\":\n this.bindings[sBinding] = control;\n control.onclick = function(computer) {\n return function() {\n computer.reset();\n };\n }(this);\n return true;\n default:\n break;\n }\n return false;\n }\n\n /**\n * NOTE: If there are multiple components for a given type, we may need to provide a means of discriminating.\n *\n * @this {C1PComputer}\n * @param {string} sType\n * @param {string} [idRelated] of related component\n * @param {Component|null} [componentPrev] of previously returned component, if any\n * @return {Component|null}\n */\n getComponentByType(sType, idRelated, componentPrev)\n {\n if (this.modules[sType]) {\n return this.modules[sType][0];\n }\n return null;\n }\n\n static power(computer)\n {\n /*\n * Insure that the ROMs, Video and CPU are all ready before \"powering\" everything; always \"power\"\n * the CPU last, to make sure it doesn't start asking other components to do things before they're ready.\n */\n var cpu = null;\n for (var sType in computer.modules) {\n for (var i=0; i < computer.modules[sType].length; i++) {\n var component = computer.modules[sType][i];\n if (!component) continue;\n if (!component.isReady()) {\n component.isReady(function(computer) {\n return function() {\n C1PComputer.power(computer);\n };\n }(computer)); // jshint ignore:line\n return;\n }\n /*\n * The CPU component's setPower() notification handler is a special case: we don't want\n * to call it until the end (below), after all others have been called.\n */\n if (sType == \"cpu\")\n cpu = component;\n else if (component.setPower) {\n component.setPower(true, computer);\n }\n }\n }\n\n /*\n * The entire computer is finally ready; we call our own setReady() for completeness, not because any\n * other component actually cares when we're ready.\n */\n computer.setReady();\n\n computer.println(C1PJS.APPNAME + \" v\" + C1PJS.APPVERSION + \"\\n\" + COPYRIGHT);\n\n /*\n * Once we get to this point, we're guaranteed that all components are ready, so it's safe to \"power\" the CPU;\n * setPower() includes an automatic reset(fPowerOn), so the CPU should begin executing immediately, unless a debugger\n * is attached.\n */\n if (cpu) cpu.setPower(true, computer);\n }\n\n /*\n * C1PComputer.init()\n *\n * This function operates on every HTML element of class \"c1pjs-computer\", extracting the\n * JSON-encoded parameters for the C1PComputer constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a C1PComputer component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n /*\n * In non-COMPILED builds, embedMachine() may have set XMLVERSION.\n */\n if (!COMPILED && XMLVERSION) C1PJS.APPVERSION = XMLVERSION;\n\n var aeComputers = Component.getElementsByClass(document, C1PJS.APPCLASS, \"computer\");\n\n for (var iComputer=0; iComputer < aeComputers.length; iComputer++) {\n\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n\n var component;\n var modules = {};\n\n var abMemory;\n var addrStart = 0, addrEnd = 0;\n\n for (var iAddr=0; iAddr < parmsComputer['modules'].length; iAddr++) {\n var addrInfo = parmsComputer['modules'][iAddr];\n /*\n * The first address range (ie, the CPU range) must specify the range for the entire\n * address space (abMemory), which we allocate and zero-initialize.\n *\n * NOTE: We might consider doing what the Video component does on first reset: initializing\n * the entire memory buffer to random values. However, a constant (eg, 0xA5) might be\n * more useful, acting as a crude indicator of memory the client code hasn't written yet.\n */\n if (!iAddr) {\n if (addrInfo['type'] != \"cpu\") break;\n addrStart = addrInfo['start'];\n addrEnd = addrInfo['end'];\n abMemory = new Array(addrEnd+1 - addrStart);\n for (var addr=addrStart; addr < abMemory.length; addr++) {\n abMemory[addr] = 0;\n }\n }\n component = Component.getComponentByID(addrInfo['refID'], parmsComputer['id']);\n if (component) {\n var sType = addrInfo['type'];\n if (modules[sType] === undefined)\n modules[sType] = [];\n modules[sType].push(component);\n if (component.setBuffer && addrInfo['start'] !== undefined) {\n component.setBuffer(abMemory, addrInfo['start'], addrInfo['end'], modules['cpu'][0]);\n }\n }\n else {\n Component.error(\"no component for <module refid=\\\"\" + addrInfo['refID'] + \"\\\">\");\n return;\n }\n }\n\n if (abMemory === undefined) {\n Component.error(\"<module type=\\\"cpu\\\"> definition must appear first in the <computer> specification\");\n return;\n }\n\n /*\n * Let's see if the Debugger is installed (NOTE: its ID must be \"debugger\", and only one per machine is supported);\n * the Debugger needs our setBuffer(), setPower() and reset() notifications, and this relieves us from having an explicit\n * <module> entry for type=\"debugger\".\n */\n component = Component.getComponentByID('debugger', parmsComputer['id']);\n if (component) {\n modules['debugger'] = [component];\n if (component.setBuffer) {\n component.setBuffer(abMemory, addrStart, addrEnd, modules['cpu'][0]);\n }\n }\n\n var computer = new C1PComputer(parmsComputer, modules);\n\n /*\n * Let's see if the Control Panel is installed (NOTE: its ID must be \"panel\", and only one per machine is supported);\n * the Panel needs our setPower() notifications, and this relieves us from having an explicit <module> entry for type=\"panel\".\n */\n var panel = Component.getComponentByID('panel', parmsComputer['id']);\n if (panel) {\n modules['panel'] = [panel];\n /*\n * Iterate through all the other components and update their print methods if the Control Panel has provided overrides.\n */\n var controlPrint = panel.bindings['print'];\n if (controlPrint) {\n var aComponents = Component.getComponents(parmsComputer['id']);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component == panel) continue;\n component.notice = panel.notice;\n component.print = panel.print;\n component.println = panel.println;\n }\n }\n }\n\n /*\n * We may eventually add a \"Power\" button, but for now, all we have is a \"Reset\" button\n */\n Component.bindComponentControls(computer, eComputer, C1PJS.APPCLASS);\n\n /*\n * \"Power\" the computer automatically\n */\n C1PComputer.power(computer);\n }\n }\n}\n\n/*\n * Initialize every Computer on the page.\n */\nWeb.onInit(C1PComputer.init);\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/embed.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * We now support asynchronous XML and XSL file loads; simply set fAsync (below) to true.\n *\n * NOTE: For that support to work, we have to keep track of the number of machines on the page\n * (ie, how many embedMachine() calls were issued), reduce the count as each machine XML file\n * is fully transformed into HTML, and when the count finally returns to zero, notify all the\n * machine component init() handlers.\n *\n * Also, to prevent those init() handlers from running prematurely, we must disable all page\n * notification events at the start of the embedding process (Web.enablePageEvents(false)) and\n * re-enable them at the end (Web.enablePageEvents(true)).\n */\nvar fAsync = true;\nvar cAsyncMachines = 0;\n\n/**\n * loadXML(sFile, idMachine, sAppName, sAppClass, sParms, fResolve, display, done)\n *\n * This is the preferred way to load all XML and XSL files. It uses getResource()\n * to load them as strings, which parseXML() can massage before parsing/transforming them.\n *\n * For example, since I've been unable to get the XSLT document() function to work inside any\n * XSL document loaded by JavaScript's XSLT processor, that has prevented me from dynamically\n * loading any XML machine file that uses the \"ref\" attribute to refer to and incorporate\n * another XML document.\n *\n * To solve that, I've added an fResolve parameter that tells parseXML() to fetch any\n * referenced documents ITSELF and insert them into the XML string prior to parsing, instead\n * of relying on the XSLT template to pull them in. That fetching is handled by resolveXML(),\n * which iterates over the XML until all \"refs\" have been resolved (including any nested\n * references).\n *\n * Also, XSL files with a <!DOCTYPE [...]> cause MSIE's Microsoft.XMLDOM.loadXML() function\n * to choke, so I strip that out prior to parsing as well.\n *\n * TODO: Figure out why the XSLT document() function works great when the web browser loads an\n * XML file (and the associated XSL file) itself, but does not work when loading documents via\n * JavaScript XSLT support. Is it broken, is it a security issue, or am I just calling it wrong?\n *\n * @param {string} sXMLFile\n * @param {string|null|undefined} idMachine\n * @param {string|null|undefined} sAppName\n * @param {string|null|undefined} sAppClass\n * @param {string|null|undefined} sParms (machine parameters, if any)\n * @param {string|null|undefined} sClass (an optional machine class name used to style the machine)\n * @param {boolean} fResolve is true to resolve any \"ref\" attributes\n * @param {function(string)} display\n * @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)\n */\nfunction loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n{\n var doneLoadXML = function(sURLName, sXML, nErrorCode) {\n if (nErrorCode) {\n if (!sXML) sXML = \"unable to load \" + sXMLFile + \" (\" + nErrorCode + \")\";\n done(sXML, null);\n return;\n }\n parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done);\n };\n display(\"Loading \" + sXMLFile + \"...\");\n Web.getResource(sXMLFile, null, fAsync, doneLoadXML);\n}\n\n/**\n * parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n *\n * Generates an XML document from an XML string. This function also provides a work-around for XSLT's\n * lack of support for the document() function (at least on some browsers), by replacing every reference\n * tag (ie, a tag with a \"ref\" attribute) with the contents of the referenced file.\n *\n * @param {string} sXML\n * @param {string|null} sXMLFile\n * @param {string|null|undefined} idMachine\n * @param {string|null|undefined} sAppName\n * @param {string|null|undefined} sAppClass\n * @param {string|null|undefined} sParms (machine parameters, if any)\n * @param {string|null|undefined} sClass (an optional machine class name used to style the machine)\n * @param {boolean} fResolve is true to resolve any \"ref\" attributes; default is false\n * @param {function(string)} display\n * @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)\n */\nfunction parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n{\n var buildXML = function(sXML, sError) {\n if (sError) {\n done(sError, null);\n return;\n }\n if (idMachine) {\n\n /*\n * A more sensible place to record the machine XML would be embedMachine(), like we do for the\n * XSL file, but since we're about to modify the original machine XML, it's best to record it now.\n */\n Component.addMachineResource(idMachine, sXMLFile, sXML);\n\n var sURL = sXMLFile;\n if (sURL && sURL.indexOf('/') < 0 && window.location.pathname.slice(-1) == '/') {\n sURL = window.location.pathname + sURL;\n }\n /*\n * We embed the URL of the XML file both as a separate \"xml\" attribute for easy access from the\n * XSL file, and as part of the \"parms\" attribute for easy access from machines (see getMachineParm()).\n */\n if (!sParms) {\n sParms = '{';\n } else if (sParms.slice(-1) == '}') {\n sParms = sParms.slice(0, -1);\n if (sParms.length > 1) sParms += ',';\n } else { // sParms must just be a \"state\" file, so encode it as a \"state\" property\n sParms = '{state:\"' + sParms + '\",';\n }\n sParms += 'url:\"' + sURL + '\"}';\n /*\n * Note that while we no longer generate a machine XML file with a \"state\" attribute (because it's\n * encoded inside the \"parms\" attribute), the XSL file must still cope with \"state\" attributes inside\n * other XML files; for example, manifest XML files like /apps/pcx86/1981/visicalc/manifest.xml contain\n * machine elements with \"state\" attributes that must still be passed down to the computer element\n * \"the old fashioned way\".\n *\n * Until/unless that changes, components.xsl cannot be simplified as much as I might have hoped.\n */\n if (typeof resources == 'object') sURL = null; // turn off URL inclusion if we have embedded resources\n sParms = sParms.replace(/\\$/g, \"$$$$\");\n if (sClass) {\n /*\n * If there's no hard-coded \"class\" attribute in the machine tag, then we can set one in the final\n * replacement below, just like we do for sParms and sURL. However, if a \"class\" attribute already\n * exists, we need alter it and then zap the sClass variable.\n */\n var match = sXML.match(/(<machine[^>]*\\sclass=)(['\"])(.*?)(\\2.*?>)/);\n if (match) {\n sXML = sXML.replace(match[0], match[1] + match[2] + sClass + match[4]);\n sClass = null;\n }\n }\n sXML = sXML.replace(/(<machine[^>]*\\sid=)(['\"]).*?\\2/, \"$1$2\" + idMachine + \"$2\" + (sClass? ' class=\"' + sClass + '\"' : '') + (sParms? \" parms='\" + sParms + \"'\" : \"\") + (sURL? ' url=\"' + sURL + '\"' : ''));\n }\n\n if (!fResolve) {\n /*\n * I'm trying to switch to a shared components.xsl (at least for all PC-class machines),\n * but in the interim, that means hacking the XSL file on the fly to reflect the actual class.\n */\n sXML = sXML.replace(/(<xsl:variable name=\"APPNAME\">).*?(<\\/xsl:variable>)/, \"$1\" + sAppName + \"$2\");\n sXML = sXML.replace(/(<xsl:variable name=\"APPCLASS\">).*?(<\\/xsl:variable>)/, \"$1\" + sAppClass + \"$2\");\n\n /*\n * Non-COMPILED kludge to replace the version number template in the XSL file (which we assume we're reading,\n * since fResolve is false) with whatever XMLVERSION we extracted from the XML file (see corresponding kludge below).\n *\n * ES6 ALERT: Template strings.\n */\n if (!COMPILED && XMLVERSION) {\n sXML = sXML.replace(/<xsl:variable name=\"APPVERSION\"\\/>/, `<xsl:variable name=\"APPVERSION\">${XMLVERSION}</xsl:variable>`);\n }\n }\n\n /*\n * If the resource we requested is not really an XML file (or the file didn't exist and the server simply returned\n * a message like \"Cannot GET /devices/pc/machine/5150/cga/64kb/donkey/machine.xml\"), we'd like to display a more\n * meaningful message, because the XML DOM parsers will blithely return a document that contains nothing useful; eg:\n *\n * This page contains the following errors:error on line 1 at column 1:\n * Document is empty Below is a rendering of the page up to the first error.\n *\n * Supposedly, the IE XML DOM parser will throw an exception, but I haven't tested that, and unless all other\n * browsers do that, that's not helpful.\n *\n * The best I can do at this stage (assuming Web.getResource() didn't drop any error information on the floor)\n * is verify that the requested resource \"looks like\" valid XML (in other words, it begins with a '<').\n */\n var xmlDoc = null;\n if (sXML.charAt(0) == '<') {\n try {\n /*\n * Another hack for MSIE, which fails to load XSL documents containing a <!DOCTYPE [...]> tag.\n *\n * This is also why the XSLTProcessor 'transformToFragment' method in Microsoft Edge silently failed,\n * so I had pull this hack out of the \"ActiveXObject\" code. And rather than add yet-another Microsoft\n * browser check, I'm going to try doing this across the board, and hope that none of the other XSLT\n * processors fail *without* the DOCTYPE tag.\n */\n if (!fResolve) {\n sXML = sXML.replace(/<!DOCTYPE(.|[\\r\\n])*]>\\s*/g, \"\");\n }\n /*\n * Beginning with Microsoft Edge and the corresponding release of Windows 10, all the\n * 'ActiveXObject' crud has gone away; but of course, this code must remain in place if\n * we want to continue supporting older Internet Explorer browsers (ie, back to IE9).\n */\n /** @namespace window.ActiveXObject */\n if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1\n xmlDoc = new window.ActiveXObject(\"Microsoft.XMLDOM\");\n xmlDoc.async = false;\n xmlDoc['loadXML'](sXML);\n } else {\n /** @namespace window.DOMParser */\n xmlDoc = (new window.DOMParser()).parseFromString(sXML, \"text/xml\");\n }\n } catch(e) {\n xmlDoc = null;\n sXML = e.message;\n }\n } else {\n sXML = \"unrecognized XML: \" + (sXML.length > 255? sXML.substr(0, 255) + \"...\" : sXML);\n }\n done(sXML, xmlDoc);\n };\n if (sXML) {\n if (PRIVATE) sXML = sXML.replace(/\\/library.xml/, \"/private/library.xml\");\n if (fResolve) {\n resolveXML(sXML, display, buildXML);\n return;\n }\n buildXML(sXML, null);\n return;\n }\n done(\"no data\" + (sXMLFile? \" for file: \" + sXMLFile : \"\"), null);\n}\n\n/**\n * resolveXML(sXML, display, done)\n *\n * Replaces every tag with a \"ref\" attribute with the contents of the corresponding file.\n *\n * TODO: Fix some of the limitations of this code, such as: 1) requiring the \"ref\" attribute\n * to appear as the tag's first attribute, 2) requiring the \"ref\" attribute to be double-quoted,\n * and 3) requiring the \"ref\" tag to be self-closing.\n *\n * @param {string} sXML\n * @param {function(string)} display\n * @param {function(string,(string|null))} done (the first string contains the resolved XML data, the second is for any error message)\n */\nfunction resolveXML(sXML, display, done)\n{\n var matchRef;\n var reRef = /<([a-z]+)\\s+ref=\"(.*?)\"(.*?)\\/>/g;\n\n if ((matchRef = reRef.exec(sXML))) {\n\n var sRefFile = matchRef[2];\n\n var doneReadXML = function(sURLName, sXMLRef, nErrorCode) {\n if (nErrorCode || !sXMLRef) {\n done(sXML, \"unable to resolve XML reference: \" + matchRef[0] + \" (\" + nErrorCode + \")\");\n return;\n }\n /*\n * If there are additional attributes in the \"referring\" XML tag, we want to insert them\n * into the \"referred\" XML tag; attributes that don't exist in the referred tag should be\n * appended, and attributes that DO exist should be overwritten.\n */\n var sRefAttrs = matchRef[3];\n if (sRefAttrs) {\n var aXMLRefTag = sXMLRef.match(new RegExp(\"<\" + matchRef[1] + \"[^>]*>\"));\n if (aXMLRefTag) {\n var sXMLNewTag = aXMLRefTag[0];\n /*\n * Iterate over all the attributes in the \"referring\" XML tag (sRefAttrs)\n */\n var matchAttr;\n var reAttr = /( [a-z]+=)(['\"])(.*?)\\2/gi;\n while ((matchAttr = reAttr.exec(sRefAttrs))) {\n if (sXMLNewTag.toLowerCase().indexOf(matchAttr[1].toLowerCase()) < 0) {\n /*\n * This is the append case....\n */\n sXMLNewTag = sXMLNewTag.replace(\">\", matchAttr[0] + \">\");\n } else {\n /*\n * This is the overwrite case....\n */\n sXMLNewTag = sXMLNewTag.replace(new RegExp(matchAttr[1] + \"(['\\\"])(.*?)\\\\1\"), matchAttr[0]);\n }\n }\n if (aXMLRefTag[0] != sXMLNewTag) {\n sXMLRef = sXMLRef.replace(aXMLRefTag[0], sXMLNewTag);\n }\n } else {\n done(sXML, \"missing <\" + matchRef[1] + \"> in \" + sRefFile);\n return;\n }\n }\n\n /*\n * Apparently when a Windows Azure server delivers one of my XML files, it may modify the first line:\n *\n * <?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n\n *\n * I didn't determine exactly what it was doing at this point (probably just changing the \\n to \\r\\n),\n * but in any case, relaxing the following replace() solved it.\n */\n sXMLRef = sXMLRef.replace(/<\\?xml[^>]*>[\\r\\n]*/, \"\");\n\n sXML = sXML.replace(matchRef[0], sXMLRef);\n\n resolveXML(sXML, display, done);\n };\n\n display(\"Loading \" + sRefFile + \"...\");\n Web.getResource(sRefFile, null, fAsync, doneReadXML);\n return;\n }\n done(sXML, null);\n}\n\n/**\n * embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * This allows to you embed a machine on a web page, by transforming the machine XML into HTML.\n *\n * @param {string} sAppName is the app name (eg, \"PCx86\")\n * @param {string} sAppClass is the app class (eg, \"pcx86\"); also known as the machine class\n * @param {string} sVersion is the app version (eg, \"1.15.7\")\n * @param {string} idMachine\n * @param {string|undefined} sXMLFile\n * @param {string|undefined} sXSLFile\n * @param {string|undefined} sParms (machine parameters, if any)\n * @param {string|undefined} sClass (an optional machine class name used to style the machine)\n * @return {boolean} true if successful, false if error\n */\nfunction embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n var eMachine, eWarning, fSuccess = true;\n\n if (!sXMLFile) {\n sXMLFile = \"machine.xml\";\n if (!sXSLFile) sXSLFile = \"components.xsl\";\n }\n \n cAsyncMachines++;\n Component.addMachine(idMachine);\n\n var doneMachine = function() {\n\n if (!--cAsyncMachines) {\n if (fAsync) Web.enablePageEvents(true);\n }\n };\n\n var displayError = function(sError) {\n Component.log(sError);\n displayMessage(\"Error: \" + sError);\n if (fSuccess) doneMachine();\n fSuccess = false;\n };\n\n var displayMessage = function(sMessage) {\n if (eWarning === undefined) {\n /*\n * Our MarkOut module (in convertMDMachineLinks()) creates machine containers that look like:\n *\n * <div id=\"' + sMachineID + '\" class=\"machine-placeholder\"><p>Embedded PC</p><p class=\"machine-warning\">...</p></div>\n *\n * with the \"machine-warning\" paragraph pre-populated with a warning message that the user will\n * see if nothing at all happens. But hopefully, in the normal case (and especially the error case),\n * *something* will have happened.\n *\n * Note that it is the HTMLOut module (in processMachines()) that ultimately decides which scripts to\n * include and then generates the embedXXX() call.\n */\n var aeWarning = (eMachine && Component.getElementsByClass(eMachine, \"machine-warning\"));\n eWarning = (aeWarning && aeWarning[0]) || eMachine;\n }\n if (eWarning) eWarning.innerHTML = Str.escapeHTML(sMessage);\n };\n\n try {\n eMachine = document.getElementById(idMachine);\n if (eMachine) {\n\n /*\n * If we have a 'css' resource, add it to the page first.\n */\n var css;\n if (typeof resources == \"object\" && (css = resources['css'])) {\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n // noinspection JSDeprecatedSymbols\n if (style.styleSheet) {\n // noinspection JSDeprecatedSymbols\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n head.appendChild(style);\n }\n\n if (!sXSLFile) {\n /*\n * Now that PCjs is an open-source project, we can make the following test more flexible,\n * and revert to the internal template if DEBUG *or* internal version (instead of *and*).\n *\n * Third-party sites that don't use the PCjs server will ALWAYS want to specify a fully-qualified\n * path to the XSL file, unless they choose to mirror our folder structure.\n */\n var sAppFolder = sAppClass;\n if (DEBUG || !sVersion) {\n if (sAppClass != \"c1pjs\") sAppFolder = \"shared\";\n sXSLFile = \"/modules/\" + sAppFolder + \"/templates/components.xsl\";\n } else {\n if (sAppClass.substr(0, 3) == \"pdp\") sAppFolder = \"pdpjs\";\n sXSLFile = \"/versions/\" + sAppFolder + \"/\" + sVersion + \"/components.xsl\";\n }\n }\n\n var processXML = function(sXML, xml) {\n if (!xml) {\n displayError(sXML);\n return;\n }\n\n /*\n * Non-COMPILED kludge to extract the version number from the stylesheet path in the machine XML file;\n * we don't need this code in COMPILED (non-DEBUG) releases, because APPVERSION is hard-coded into them.\n */\n if (!COMPILED) {\n var aMatch = sXML.match(/<\\?xml-stylesheet[^>]* href=(['\"])[^'\"]*?\\/([0-9.]*)\\/([^'\"]*)\\1/);\n if (aMatch) {\n XMLVERSION = aMatch[2];\n }\n }\n\n var transformXML = function(sXSL, xsl) {\n if (!xsl) {\n displayError(sXSL);\n return;\n }\n\n /*\n * Record the XSL file, in case someone wants to save the entire machine later.\n * \n * NOTE: sXSLFile will never be undefined by this point, but apparently the Closure Compiler doesn't realize that. \n */\n Component.addMachineResource(idMachine, sXSLFile || \"\", sXSL);\n\n /*\n * The <machine> template in components.xsl now generates a \"machine div\" that makes\n * the div we required the caller of embedMachine() to provide redundant, so instead\n * of appending this fragment to the caller's node, we REPLACE the caller's node.\n * This works only because because we ALSO inject the caller's \"machine div\" ID into\n * the fragment's ID during parseXML().\n *\n * eMachine.innerHTML = sFragment;\n *\n * Also, if the transform function fails, make sure you're using the appropriate\n * \"components.xsl\" and not a \"machine.xsl\", because the latter will not produce valid\n * embeddable HTML (and is the most common cause of failure at this final stage).\n */\n displayMessage(\"Processing \" + sXMLFile + \"...\");\n\n /*\n * Beginning with Microsoft Edge and the corresponding release of Windows 10, all the\n * 'ActiveXObject' crud has gone away; but of course, this code must remain in place if\n * we want to continue supporting older Internet Explorer browsers (ie, back to IE9).\n */\n if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1\n var sFragment = xml['transformNode'](xsl);\n if (sFragment) {\n eMachine.outerHTML = sFragment;\n doneMachine();\n } else {\n displayError(\"transformNodeToObject failed\");\n }\n }\n else if (document.implementation && document.implementation.createDocument) {\n var xsltProcessor = new XSLTProcessor();\n xsltProcessor['importStylesheet'](xsl);\n var eFragment = xsltProcessor['transformToFragment'](xml, document);\n if (eFragment) {\n /*\n * This fails in Microsoft Edge...\n *\n var machine = eFragment.getElementById(idMachine);\n if (!machine) {\n displayError(\"machine generation failed: \" + idMachine);\n } else\n */\n if (eMachine.parentNode) {\n eMachine.parentNode.replaceChild(eFragment, eMachine);\n doneMachine();\n } else {\n /*\n * NOTE: This error can occur if our Node web server, when processing a folder with\n * both a manifest.xml with a machine.xml reference AND a README.md containing a\n * machine link, generates duplicate embedXXX() calls for the same machine; if the\n * first embedXXX() call finds its target, subsequent calls for the same target will\n * fail.\n *\n * Technically, such a folder is in a misconfigured state, but it happens, in part\n * because when we switched to the Jekyll web server, we had to add machine links to\n * all README.md files where we had previously relied on manifest.xml or machine.xml\n * processing. This is because the Jekyll web server currently doesn't process XML\n * files, nor is support for that likely to be added any time soon; it was a nice\n * feature of the Node web server, but it's not clear that it's worth doing for Jekyll.\n */\n displayError(\"invalid machine element: \" + idMachine);\n }\n } else {\n displayError(\"transformToFragment failed\");\n }\n } else {\n /*\n * Perhaps I should have performed this test at the outset; on the other hand, I'm\n * not aware of any browsers don't support one or both of the above XSLT transformation\n * methods, so treat this as a bug.\n */\n displayError(\"unable to transform XML: unsupported browser\");\n }\n };\n /*\n * NOTE: sXSLFile will never be undefined by this point, but apparently the Closure Compiler doesn't realize that. \n */\n loadXML(sXSLFile || \"\", null, sAppName, sAppClass, null, null, false, displayMessage, transformXML);\n };\n\n if (sXMLFile.charAt(0) != '<') {\n loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, true, displayMessage, processXML);\n } else {\n parseXML(sXMLFile, null, idMachine, sAppName, sAppClass, sParms, sClass, false, displayMessage, processXML);\n }\n } else {\n displayError(\"missing machine element: \" + idMachine);\n }\n } catch(e) {\n displayError(e.message);\n }\n return fSuccess;\n}\n\n/**\n * embedC1P(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedC1P(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"C1Pjs\", \"c1pjs\", APPVERSION, idMachine, sXMLFile, sXSLFile, undefined, sClass);\n}\n\n/**\n * embedPCx86(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPCx86(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PCx86\", \"pcx86\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPC8080(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPC8080(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PC8080\", \"pc8080\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPDP10(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPDP10(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PDPjs\", \"pdp10\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPDP11(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPDP11(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PDPjs\", \"pdp11\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * findMachineComponent(idMachine, sType)\n *\n * @param {string} idMachine\n * @param {string} sType\n * @return {Component|null}\n */\nfunction findMachineComponent(idMachine, sType)\n{\n return Component.getComponentByType(sType, idMachine + \".machine\");\n}\n\n/**\n * commandMachine(control, fSingle, idMachine, sComponent, sCommand, sValue)\n *\n * Use Component methods to find the requested component for a specific machine, and if the component is found,\n * then check its 'exports' table for an entry matching the specified command string, and if an entry is found, then\n * the corresponding function is called with the specified data.\n *\n * @param {Object} control\n * @param {boolean} fSingle\n * @param {string} idMachine\n * @param {string} sComponent\n * @param {string} sCommand\n * @param {string} [sValue]\n * @return {boolean}\n */\nfunction commandMachine(control, fSingle, idMachine, sComponent, sCommand, sValue)\n{\n if (sCommand == \"script\") {\n if (Component.processScript(idMachine, sValue)) {\n if (fSingle) control.disabled = true;\n return true;\n }\n return false;\n }\n if (sComponent) {\n var component = Component.getComponentByType(sComponent, idMachine + \".machine\");\n if (component) {\n var exports = component['exports'];\n if (exports) {\n var fnCommand = exports[sCommand];\n if (fnCommand) {\n if (fnCommand.call(component, sValue)) {\n if (fSingle) control.disabled = true;\n return true;\n }\n return false;\n }\n }\n }\n }\n console.log(\"unimplemented: commandMachine('\" + idMachine + \"','\" + sComponent + \"','\" + sCommand + \"','\" + sValue + \"')\");\n return false;\n}\n\n/**\n * Prevent the Closure Compiler from renaming functions we want to export, by adding them as global properties.\n *\n * TODO: Consider making all these functions properties on a single global object (eg, 'PCjs'), to minimize global\n * pollution and risk of name collision.\n */\nif (APPNAME == \"C1Pjs\") {\n window['embedC1P'] = embedC1P;\n}\nif (APPNAME == \"PCx86\") {\n window['embedPC'] = embedPCx86; // WARNING: embedPC() deprecated as of v1.23.0\n window['embedPCx86'] = embedPCx86;\n}\nif (APPNAME == \"PC8080\") {\n window['embedPC8080'] = embedPC8080;\n}\nif (APPNAME == \"PDPjs\") {\n window['embedPDP10'] = embedPDP10;\n window['embedPDP11'] = embedPDP11;\n}\n\nwindow['commandMachine'] = commandMachine;\n\nwindow['enableEvents'] = Web.enablePageEvents;\nwindow['sendEvent'] = Web.sendPageEvent;\n"]} \ No newline at end of file +{"version":3,"file":"c1p.js","lineCount":202,"mappings":"A;;;;;;;;;;;;;;;;;;;;;AAAA,IAAA,CAAA,CC8BAA,GACmD,UAA/C,EAAuB,MAAO,OAAA,OAA9B,CACA,MAAA,OADA,CAEA,QAAQ,CAAC,CAAD,CAAY,CAEP,QAAA,EAAQ,EAAG,EACtB,CAAA,UAAA,CAAiB,CACjB,OAAO,KAAI,CAJO,CDjCxB,CE8CyB,EAAA,IAAiC,UAAjC,EAAC,MAAO,OAAA,eAAR,CACrB,EAAA,CAAA,MAAA,eADqB,KAAA,CAErB,IAAA,EAvByC,EAAA,CAAA,CAC3C,IAAI,GAAI,CAAC,GAAG,CAAA,CAAJ,CAAR,CACI,GAAI,EACR,IAAI,CACF,EAAA,UAAA,CAAc,EACd,GAAA,CAAO,EAAA,GAAP,OAAA,CAFE,CAGF,MAAO,CAAP,CAAU,EAGZ,EAAA,CAAO,CAAA,CAToC,CAuBzC,EAAA,CAAA,EAAA,CAAA,QAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,UAAA,CAAA,CAAA,IAAA,CAAA,UAAA,GAAA,CAAA,CAAA,KAAA,KAAA,SAAA,CAAA,CAAA,CAAA,oBAAA,CAAA,CAAA,MAAA,EAAA,CAAA,CAAA,IAFqB,CAAzB,IAAAC,GAAyB,ECSN;QAAA,EAAQ,CAAC,CAAD,CAAY,CAAZ,CAAwB,CACjD,CAAA,UAAA,CAAsBD,EAAA,CAAqB,CAAA,UAArB,CACL,EAAA,UAAA,YAAA,CAAkC,CACnD,IAAIC,EAAJ,CAGuBA,EACrB,CAAe,CAAf,CAA0B,CAA1B,CAJF,KAQE,KAAK,IAAI,CAAT,GAAc,EAAd,CACE,GAAS,WAAT,EAAI,CAAJ,CAIA,GAAI,MAAA,iBAAJ,CAA6B,CAC3B,IAAI,EAAa,MAAA,yBAAA,CAAgC,CAAhC,CAA4C,CAA5C,CACb,EAAJ,EACE,MAAA,eAAA,CAAsB,CAAtB,CAAiC,CAAjC,CAAoC,CAApC,CAHyB,CAA7B,IAOE,EAAA,CAAU,CAAV,CAAA,CAAe,CAAA,CAAW,CAAX,CAKrB,EAAA,GAAA,CAAwB,CAAA,UA5ByB,CCnBnD,IAAAC,GAC4D,UAAxD,EAAsB,MAAO,OAAA,iBAA7B,CACA,MAAA,eADA,CAEA,QAAQ,CAAC,CAAD,CAAS,CAAT,CAAmB,CAAnB,CAA+B,CAOjC,CAAJ,EAAc,KAAA,UAAd,EAAiC,CAAjC,EAA2C,MAAA,UAA3C,GACA,CAAA,CAAO,CAAP,CADA,CACmB,CAAA,MADnB,CAPqC,CAH3C,CCOAC,GAb2B,WAAlB,EAAC,MAAO,OAAR,EAAiC,MAAjC,GAa0B,IAb1B,CAa0B,IAb1B,CAEe,WAAlB,EAAC,MAAO,OAAR,EAA2C,IAA3C,EAAiC,MAAjC,CAAmD,MAAnD,CAW6B,ICChB;QAAA,GAAQ,CAAC,CAAD,CAAS,CAAT,CAAqC,CAC9D,GAAK,CAAL,CAAA,CACA,IAAI,EAAMA,EACN,EAAA,CAAQ,CAAA,MAAA,CAAa,GAAb,CACZ,KAAK,IAAI,EAAI,CAAb,CAAgB,CAAhB,CAAoB,CAAA,OAApB,CAAmC,CAAnC,CAAsC,CAAA,EAAtC,CAA2C,CACzC,IAAI,EAAM,CAAA,CAAM,CAAN,CACJ,EAAN,GAAa,EAAb,GAAmB,CAAA,CAAI,CAAJ,CAAnB,CAA8B,EAA9B,CACA,EAAA,CAAM,CAAA,CAAI,CAAJ,CAHmC,CAKvC,CAAA,CAAW,CAAA,CAAM,CAAA,OAAN,CAAqB,CAArB,CACX,EAAA,CAAO,CAAA,CAAI,CAAJ,CACP,EAAA,CAAO,CAAA,CAAS,CAAT,CACP,EAAJ,EAAY,CAAZ,EAA4B,IAA5B,EAAoB,CAApB,EACAD,EAAA,CACI,CADJ,CACS,CADT,CACmB,CAAC,aAAc,CAAA,CAAf,CAAqB,SAAU,CAAA,CAA/B,CAAqC,MAAO,CAA5C,CADnB,CAZA,CAD8D,CC1BhEE,EAAA,CAAiB,YAAjB,CAA+B,QAAQ,CAAC,CAAD,CAAO,CAC5C,MAAI,EAAJ,CAAiB,CAAjB,CAUe,QAAQ,CAAC,CAAD,CAAI,CACzB,CAAA,CAAI,MAAA,CAAO,CAAP,CACJ,IAAI,KAAA,CAAM,CAAN,CAAJ,EAAsB,QAAtB,GAAgB,CAAhB,EAAwC,CAAC,QAAzC,GAAkC,CAAlC,EAA2D,CAA3D,GAAqD,CAArD,CAA8D,MAAO,EACrE,KAAI,EAAI,IAAA,MAAA,CAAW,IAAA,IAAA,CAAS,CAAT,CAAX,CACR,OAAW,EAAJ,CAAA,CAAA,CAAQ,CAAC,CAAT,CAAa,CAJK,CAXiB,CAA9C,CCAAA,GAAA,CAAiB,iBAAjB,CAAoC,QAAQ,CAAC,CAAD,CAAO,CACjD,MAAO,EAAP,EAAe,QADkC,CAAnD,CR4fIC;QAAO,EAAK,CAACC,CAAD,CAAIC,CAAJ,CAASC,CAAT,CACZ,CACSD,CAAL,CAUiB,CAVjB,CAUWA,CAVX,GAUoBA,CAVpB,CAU0B,CAV1B,GAEQE,CAEA,CAFIC,IAAAC,IAAA,CAASL,CAAT,CAEJ,CAAAC,CAAA,CADK,KAAT,EAAIE,CAAJ,CACU,CADV,CAEgB,UAAT,EAAIA,CAAJ,CACG,CADH,CAGG,CARd,CAW8B,EAAA,CAAAD,CAAA,CAAS,IAAT,CAAgB,EA/LP,KAAAI,EAAA,IAAA,EAAA,GAAAA,CAAA,CAAY,CAAZ,CAAAA,CAUvC,KAAIC,EAAI,EACJC,MAAA,CAAMR,CAAN,CAAJ,EAA4B,QAA5B,EAAgB,MAAOA,EAAvB,CACIA,CADJ,CACQ,IADR,EASY,CAQR,CARIA,CAQJ,EARkB,EAQlB,CARaA,CAQb,GARqBA,CAQrB,CAR0B,EAQ1B,EAHQ,CAGR,CAHIA,CAGJ,GAFIA,CAEJ,EAFSI,IAAAK,IAAA,CAqKQC,EArKR,CAAgBT,CAAhB,CAET,EAAID,CAAJ,EAASI,IAAAK,IAAA,CAmKQC,EAnKR,CAAgBT,CAAhB,CAAT,GACIA,CADJ,CACUG,IAAAO,KAAA,CAAUP,IAAAQ,IAAA,CAASZ,CAAT,CAAV,CAAwBI,IAAAQ,IAAA,CAkKjBF,EAlKiB,CAAxB,CADV,CAjBJ,CAsBA,KADA,IAAIG,EAAIP,CAAJO,EAAkB,EACtB,CAAe,CAAf,CAAOZ,CAAA,EAAP,CAAA,CAAkB,CACTY,CAAL,GACIN,CACA,CADI,GACJ,CADUA,CACV,CAAAM,CAAA,CAAIP,CAFR,CAIA,IAAS,IAAT,EAAIN,CAAJ,CACIO,CAAA,CAAI,GAAJ,CAAUA,CADd,KAEO,CACH,IAAIO,EAAId,CAAJc,CAsJSJ,EArJbI,EAAA,EAAW,CAAL,EAAAA,CAAA,EAAe,CAAf,EAAUA,CAAV,CAAkB,EAAlB,CAAyB,EAC/BP,EAAA,CAAIQ,MAAAC,aAAA,CAAoBF,CAApB,CAAJ,CAA6BP,CAC7BP,EAAA,CAAII,IAAAa,MAAA,CAAWjB,CAAX,CAmJSU,EAnJT,CAJD,CAMPG,CAAA,EAbc,CA8JlB,OA/LyB,IAAA,EAAAK,GAAAA,CAAAA,CAAU,EAAVA,CAAAA,CA+LzB,EA/IiBX,CAmIrB,CAuBAY,QAAO,EAAS,CAACC,CAAD,CAChB,CACI,MAAOC,EAAA,CAAUD,CAAV,CAAa,CAAb,CAAgB,CAAA,CAAhB,CADX,CAYAE,QAAO,EAAS,CAACC,CAAD,CAChB,CACI,MAAOF,EAAA,CAAUE,CAAV,CAAa,CAAb,CAAgB,CAAA,CAAhB,CADX;AA6BAC,QAAO,GAAW,CAACC,CAAD,CAClB,CACI,IAAIC,EAAYD,CAAhB,CAEIE,EAAIF,CAAAG,YAAA,CAAsB,GAAtB,CACC,EAAT,EAAID,CAAJ,GAAYD,CAAZ,CAAwBD,CAAAI,OAAA,CAAiBF,CAAjB,CAAqB,CAArB,CAAxB,CAKAA,EAAA,CAAID,CAAAI,QAAA,CAAkB,MAAlB,CACI,EAAR,CAAIH,CAAJ,GAAWD,CAAX,CAAuBA,CAAAG,OAAA,CAAiB,CAAjB,CAAoBF,CAApB,CAAvB,CAQA,OAAOD,EAlBX,CA+BAK,QAAO,GAAY,CAACN,CAAD,CACnB,CACI,IAAIO,EAAa,EAAjB,CACIL,EAAIF,CAAAG,YAAA,CAAsB,GAAtB,CACC,EAAT,EAAID,CAAJ,GACIK,CADJ,CACiBP,CAAAI,OAAA,CAAiBF,CAAjB,CAAqB,CAArB,CAAAM,YAAA,EADjB,CAGA,OAAOD,EANX,CA2BAE,QAAO,GAAU,CAACC,CAAD,CACjB,CACI,MAAOA,EAAAC,QAAA,CAAc,UAAd,CAA0B,QAAQ,CAACC,CAAD,CACzC,CACI,MAAOC,GAAA,CAAkBD,CAAlB,CADX,CADO,CADX,CA+QJ,IAAAC,GAAoB,CAChB,OAAK,UADW,CAEhB,OAAK,SAFW,CAGhB,OAAK,SAHW,CAIhB,IAAK,WAJW,CAKhB,IAAK,WALW,CAApB,CA+ZAC,GAAcC,IAAAC,IAAdF,EAA0B,QAAQ,EAAG,CAAE,MAAO,CAAC,IAAIC,IAAd,CA+JjCE;QAAO,EAAW,CAACC,CAAD,CAAsCC,CAAtC,CAClB,CADyBC,IAAAA,EA61MS,IA71MTA,CAAeC,EA61MA,CAAA,CA71MfD,EAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAO,MAAP,CAAAA,CAAeC,EAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAS,CAAA,CAAT,CAAAA,CACxC,KACQC,EAAa,CADrB,CACwBC,EAAW,IAE/B,IAAwB,QAAxB,EAAI,MAAOC,UAAX,GAAqCD,CAArC,CAAgDC,SAAA,CAAUN,CAAV,CAAhD,EACQC,CAAJ,EAAUA,CAAA,CAAKD,CAAL,CAAWK,CAAX,CAAqBD,CAArB,CADd,KAIK,IAAID,CAAJ,EAAkC,UAAlC,EAAc,MAAOG,UAArB,CACDA,SAAA,CAAUN,CAAV,CAAgB,QAAQ,CAACK,CAAD,CAAWD,CAAX,CACxB,CACQH,CAAJ,EAAUA,CAAA,CAAKD,CAAL,CAAWK,CAAX,CAAqBD,CAArB,CADd,CADA,CADC,KAAA,CAaDJ,CAAA,CAAOA,CAAAP,QAAA,CAAa,iCAAb,CAAgD,+BAAhD,CAaX,KAAIc,EAAWC,MAAAC,eAAA,CAAuB,IAAID,MAAAC,eAA3B,CAAqD,IAAID,MAAAE,cAAJ,CAAyB,mBAAzB,CAApE,CACIC,EAAe,CAAA,CADnB,CAC0BC,EAAyC,QAAzCA,GAAS,MAAOL,EAAAM,aAD1C,CAGIC,EAAWA,QAAQ,EAAG,CACtB,GAA2B,CAA3B,GAAIP,CAAAQ,WAAJ,CAEI,MAAO,KA0BX,IAAI,CACAV,CAAA;AAAWM,CAAA,CAAcJ,CAAAS,SAAd,CAAiCT,CAAAU,aAD5C,CAEF,MAAMC,CAAN,CAAW,EAOb,GAAgB,IAAhB,EAAIb,CAAJ,EAA2C,GAA3C,EAAyBE,CAAAY,OAAzB,GAAmDZ,CAAAY,OAAnD,EAAqEC,CAAAf,CAAAe,OAArE,EAAiH,OAAjH,GA0PIZ,MAAA,CAAQA,MAAAa,SAAAC,SAAR,CAAmC,OA1PvC,GAIIlB,CAAA,CAAaG,CAAAY,OAAb,EAAgC,EAIhClB,EAAJ,EAAUA,CAAA,CAAKD,CAAL,CAAWK,CAAX,CAAqBD,CAArB,CACV,OAAO,CAACC,CAAD,CAAWD,CAAX,CA/Ce,CAkDtBD,EAAJ,GACII,CAAAgB,mBADJ,CACiCT,CADjC,CAMA,IAAIZ,CAAJ,EAA2B,QAA3B,EAAY,MAAOA,EAAnB,CAAqC,CAC7BsB,CAAAA,CAAQ,EACZ,KAAKC,IAAIA,CAAT,GAAcvB,EAAd,CACSA,CAAAwB,eAAA,CAAoBD,CAApB,CAAL,GACID,CACJ,GADWA,CACX,EADoB,MACpB,EAAAA,CAAA,EAASC,CAAT,CAAa,MAAb,CAAmBE,kBAAA,CAAmBzB,CAAA,CAAKuB,CAAL,CAAnB,CAFnB,CAIJD,EAAA,CAAQA,CAAA/B,QAAA,CAAc,MAAd,CAAsB,GAAtB,CAERc,EAAAqB,KAAA,CAAa,MAAb,CAAqB5B,CAArB,CAA2BG,CAA3B,CACAI,EAAAsB,iBAAA,CAAyB,cAAzB,CAAyC,mCAAzC,CACAtB,EAAAuB,KAAA,CAAaN,CAAb,CAXiC,CAArC,IAcIjB,EAAAqB,KAAA,CAAa,KAAb,CAAoB5B,CAApB,CAA0BG,CAA1B,CASA,CARY,aAQZ,EARID,CAQJ,GAPQU,CAAJ,EACID,CACA,CADe,CAAA,CACf;AAAAJ,CAAAM,aAAA,CAAuBX,CAF3B,EAIIK,CAAAwB,iBAAA,CAAyB,uCAAzB,CAGR,EAAAxB,CAAAuB,KAAA,EAGC3B,EAAL,GACII,CAAAQ,WACW,CADU,CACV,CAAAD,CAAA,EAFf,CA/GK,CAPT,CA+dAkB,QAAO,EAAW,CAACpE,CAAD,CAClB,CACI,GAAI4C,MAAJ,CAAY,CACR,IAAIyB,EApJAzB,MAAA,CAAQA,MAAA0B,UAAAD,UAAR,CAAqC,EA8JzC,OAAY,KAAZ,EAAOrE,CAAP,EAAqB,CAAC,CAACqE,CAAAE,MAAA,CAAgB,oBAAhB,CAAvB,EAAgE,CAAC,CAACF,CAAAE,MAAA,CAAgB,aAAhB,CAAlE,EAAyG,MAAzG,EAAoGvE,CAApG,EAAmH,CAAC,CAACqE,CAAAE,MAAA,CAAgB,gBAAhB,CAArH,EAAmL,CAAnL,EAA2JF,CAAA9C,QAAA,CAAkBvB,CAAlB,CAXnJ,CAaZ,MAAO,CAAA,CAdX,CA4BAwE,QAAO,GAAQ,EACf,CADgBC,IAAAA,CAAAA,CAERC,EAAUC,EAAA,CAAe,QAAf,CACd,IAAID,CAAJ,CAAa,MAAkB,MAAlB,EAAOA,CACpB,IAAIE,CAAA,CAAgB,MAAhB,CAAJ,CAA6B,CACzB,GAAI,CAACH,CAAL,CAAc,MAAO,CAAA,CAErB,EADII,CACJ,CAD4B,GAC5B,EADcJ,CAAA,CAAQ,CAAR,CACd,IAAaA,CAAb,CAAuBA,CAAAnD,OAAA,CAAe,CAAf,CAAvB,CACA,OAAOsD,EAAA,CAAgBH,CAAhB,CAAP,EAAmCI,CAJV,CAM7B,MAAO,CAAA,CATX;AA2DAC,QAAO,GAAU,CAACC,CAAD,CACjB,CACI,GAAKC,CAAAA,EAAL,CAAA,CAYiBC,IAAAA,CAAAA,CAEbC,EAAS,EACb,IAAItC,MAAJ,CAAY,CACHqC,CAAL,GAKIA,CALJ,CAKarC,MAAAa,SAAA0B,OAAA7D,OAAA,CAA8B,CAA9B,CALb,CAeA,KARA,IAAIiD,CAAJ,CACIa,EAAK,KADT,CAEID,EAAS,oBAMb,CAAQZ,CAAR,CAAgBY,CAAAE,KAAA,CAAYJ,CAAZ,CAAhB,CAAA,CACIC,CAAA,CAJOI,kBAAA,CAIOf,CAAAvE,CAAM,CAANA,CAJY6B,QAAA,CAAUuD,CAAV,CAAc,GAAd,CAAnB,CAIP,CAAA,CAJOE,kBAAA,CAI2Bf,CAAAvE,CAAM,CAANA,CAJR6B,QAAA,CAAUuD,CAAV,CAAc,GAAd,CAAnB,CAbH,CAoBZ,EAAA,CAAOF,CAnCP,CAGA,MAAOF,GAAA,CAAaD,CAAb,CAAP,EAA8BC,EAAA,CAAaD,CAAArD,YAAA,EAAb,CAJlC,CA2FA6D,QAAO,GAAa,CAAC9F,CAAD,CAAI+F,CAAJ,CAAcC,CAAd,CACpB,CACoBC,QAASC,EAAa,EACtC,CACI,EAAAlG,CACS,EAAT,EAAIA,CAAJ,GACS+F,CAAA,EADT,GACqB/F,CADrB,CACyB,CADzB,EAGQ,EAAR,CAAIA,CAAJ,CACImG,UAAA,CAAWF,CAAX,CAAiC,CAAjC,CADJ,CAIAD,CAAA,EATJ,CAWAC,CAAA,EAbJ;AA2BAG,QAAO,GAAa,CAACC,CAAD,CAAuBC,CAAvB,CACpB,CAGmBP,QAASQ,EAAa,EACrC,CACQD,CAAA,CAyqTcE,GAzqTd,GAAGC,CAAH,CAAJ,GACIC,CACA,CADQP,UAAA,CAAWJ,CAAX,CAAqBU,CAArB,CACR,CAAAA,CAAA,CAuqTcD,GAzqTlB,CADJ,CAJJ,IACQC,EAAK,CADb,CACgBC,EAAQ,IADxB,CAC8BC,EAAqB,CAAA,CAS/CN,EAAAO,YAAA,CAAgBC,QAAQ,EACxB,CAESF,CAAL,EACSD,CADT,GAEQD,CACA,CA8pTKK,GA9pTL,CAAAf,CAAA,EAHR,CAFJ,CASAM,EAAAU,aAAA,CAAiBC,QAAQ,EACzB,CAESN,CAAL,GACID,CACA,CAqpTSK,GArpTT,CAAAf,CAAA,EAFJ,CAFJ,CAOAM,EAAAY,UAAA,CAAcZ,CAAAa,WAAd,CAA6BC,QAAQ,EACrC,CAEQT,CAAJ,GACIU,YAAA,CAAaV,CAAb,CACA,CAAAA,CAAA,CAAQ,IAFZ,CAFJ,CAOAL,EAAAgB,WAAA,CAAehB,CAAAiB,cAAf,CAAiCC,QAAQ,EACzC,CAEQb,CAAJ,GACIU,YAAA,CAAaV,CAAb,CACA,CAAAA,CAAA,CAAQ,IAFZ,CASAC,EAAA,CAAqB,CAAA,CAXzB,CArCJ,CAwEAa,QAAO,GAAW,CAACC,CAAD,CAAQnB,CAAR,CAClB,CACI,GAAInD,MAAJ,CAAY,CACR,IAAIuE,EAASvE,MAAA,CAAOsE,CAAP,CAETtE,OAAA,CAAOsE,CAAP,CAAA,CADkB,UAAtB,GAAI,MAAOC,EAAX,CACoBpB,CADpB,CAOoB,QAAsB,EACtC,CACQoB,CAAJ,EAAYA,CAAA,EACZpB,EAAA,EAFJ,CAVI,CADhB,CA0BAqB,QAAO,EAAM,CAACrB,CAAD,CACb,CACIsB,CAAA,KAAAC,KAAA,CAAoCvB,CAApC,CADJ;AAiCAwB,QAAO,GAAW,CAACC,CAAD,CAClB,CACI,GAAIC,EAAJ,CACI,GAAI,CACA,IAAK,IAAIrG,EAAI,CAAb,CAAgBA,CAAhB,CAAoBoG,CAAAhE,OAApB,CAAgCpC,CAAA,EAAhC,CACIoG,CAAA,CAAIpG,CAAJ,CAAA,EAFJ,CAIF,MAAO0E,CAAP,CAAU,CAsYC4B,CAAA,CAAuC,EAAvC,EArYE,gCAqYF,CArYqC5B,CAAA6B,QAqYrC,CArYiD,oFAqYjD,EAtYD,CANpB,CAiBAC,QAAO,EAAgB,CAACC,CAAD,CACvB,CACQ,CAACJ,EAAL,EAA+BI,CAA/B,EACIJ,EAEA,CAFyB,CAAA,CAEzB,CADIK,EACJ,EADqBC,EAAA,CAAkB,MAAlB,CACrB,CAAIC,EAAJ,EAAqBD,EAAA,CAAkB,MAAlB,CAHzB,EAMAN,EANA,CAMyBI,CAP7B,CAiBAI,QAAO,GAAa,CAACC,CAAD,CACpB,CACQb,CAAA,CAAuBa,CAAvB,CAAJ,EACIC,EAAA,CAAgBd,CAAA,CAAuBa,CAAvB,CAAhB,CAFR,CAOJ,IAAAlD,GAAe,IAAf,CAEAqC,EAAyB,CACrB,KAAQ,EADa,CAErB,KAAQ,EAFa,CAGrB,KAAQ,EAHa,CAFzB,CAUAS,GAAkB,CAAA,CAVlB,CAWAE,GAAkB,CAAA,CAXlB,CAYAP,GAAyB,CAAA,CAkBzBW,GAAA,CAAgB,QAAhB,CAA0BC,QAAmB,EAAG,CAC5CP,EAAA,CAAkB,CAAA,CAClBK,GAAA,CAAgBd,CAAA,KAAhB,CAF4C,CAAhD,CAKAe,GAAA,CAAgB,YAAhB,CAA8BE,QAAmB,EAAG,CAChDN,EAAA,CAAkB,CAAA,CAClBG,GAAA,CAAgBd,CAAA,KAAhB,CAFgD,CAApD,CAKAe;EAAA,CAAgBxD,CAAA,CAAgB,KAAhB,CAAA,CAAwB,YAAxB,CAAwCA,CAAA,CAAgB,OAAhB,CAAA,CAA0B,UAA1B,CAAuC,gBAA/F,CAAkH2D,QAAqB,EAAG,CACtIJ,EAAA,CAAgBd,CAAA,KAAhB,CADsI,CAA1I,CA8EImB,SApBEC,EAoBS,CAACnG,CAAD,CAAOoG,CAAP,CAAcC,CAAd,CACX,CACI,IAAArG,KAAA,CAAYA,CAEPoG,EAAL,GAAYA,CAAZ,CAAoB,CAAC,GAAM,EAAP,CAAW,KAAQ,EAAnB,CAApB,CAEA,KAAAE,GAAA,CAAUF,CAAA,GAAV,EAAyB,EACzB,KAAAG,KAAA,CAAYH,CAAA,KAaG,KAAA,QAAf,CAAiC,EACjC,KAAAI,EAAA,CAAgB,IAAA,SAAhB,CAAmC,EAE/B1H,EAAAA,CAAI,IAAAwH,GAAArH,QAAA,CAAgB,GAAhB,CACA,EAAR,CAAIH,CAAJ,GAGI,IAAA2H,GAHJ,CAGqB,IAAAH,GAAAtH,OAAA,CAAe,CAAf,CAAkBF,CAAlB,CAHrB,CAWA,KAAA4H,EAAA,CAAa,CACTC,MAAY,CAAA,CADH,CAETC,GAAY,CAAA,CAFH,CAGTC,GAAY,CAAA,CAHH,CAITC,GAAY,CAAA,CAJH,CAKTC,EAAY,CAAA,CALH,CAMTC,GAAY,CAAA,CANH,CAOTC,MAAY,CAAA,CAPH,CAUb,KAAAC,GAAA,CAAe,IACfC,KA8gCAT,EAAAO,MAAA,CAAmB,CAAA,CA7gCnB,KAAAZ,GAAA,CAAmBA,CAAnB,EAAkC,CAKlC,KAAAe,EAAA,CADA,IAAAC,EACA,CAHA,IAAAC,EAGA,CAHW,IA8BXC,EAAAvC,KAAA,CAfcwC,IAed,CA9EJ,CA6QAC,QAAO,EAAS,CAACC,CAAD,CAChB,CACQpH,MAAJ,EACIA,MAAAqH,MAAA,CAAaD,CAAb,CAFR;AA6CAE,QAAO,GAAa,CAACC,CAAD,CAAUC,CAAV,CACpB,CACID,CAAAE,MAAA,EAAiBD,CAKbA,EAAA,CAAQD,CAAAE,MACW,KAAnB,CAAID,CAAA5G,OAAJ,GAAyB2G,CAAAE,MAAzB,CAAyCD,CAAA9I,OAAA,CAAa8I,CAAA5G,OAAb,CAA4B,IAA5B,CAAzC,CAEJ2G,EAAAG,UAAA,CAAoBH,CAAAI,aATxB,CA+DAC,QAAO,EAAqB,CAACV,CAAD,CAAYW,CAAZ,CAC5B,CACQC,CAAAA,CAAaC,CAAA,CAA6BF,CAAAG,WAA7B,CAAiD,eAAjD,CAEjB,KAAK,IAAIC,EAAW,CAApB,CAAuBA,CAAvB,CAAkCH,CAAAlH,OAAlC,CAAqDqH,CAAA,EAArD,CAII,IAFA,IAAIC,EAAeJ,CAAA,CAAWG,CAAX,CAAAE,WAAnB,CAESC,EAAQ,CAAjB,CAAoBA,CAApB,CAA4BF,CAAAtH,OAA5B,CAAiDwH,CAAA,EAAjD,CAA0D,CACtD,IAAIb,EAAUW,CAAA,CAAaE,CAAb,CACd,IAAyB,CAAzB,GAAIb,CAAAc,SAAJ,CAAA,CAGA,IAAIC,EAASf,CAAAgB,aAAA,CAAqB,OAArB,CACb,IAAKD,CAAL,CAEA,IADA,IAAIE,EAAWF,CAAAG,MAAA,CAAa,GAAb,CAAf,CACSC,EAAS,CAAlB,CAAqBA,CAArB,CAA8BF,CAAA5H,OAA9B,CAA+C8H,CAAA,EAA/C,CAGI,OADAJ,CACQA,CADCE,CAAA,CAASE,CAAT,CACDJ,CAAAA,CAAR,EACI,KAAK,eAAL,CAOI,CANAxC,CAMA,CANQ6C,CAAA,CAAuDpB,CAAvD,CAMR,GALkCqB,IAAAA,EAKlC,GALa9C,CAAA,QAKb,EAJIoB,CAAA2B,EAAA,CAAqB/C,CAAA,KAArB,CAAoCA,CAAA,QAApC,CAAiFyB,CAAjF,CAA2FzB,CAAA,MAA3F,CAIJ,CAAA4C,CAAA,CAASF,CAAA5H,OARjB,CATJ,CAFsD,CAPlE;AAkFAkI,QAAO,GAAgB,CAAC9C,CAAD,CAAK+C,CAAL,CACvB,CACI,GAAWH,IAAAA,EAAX,GAAI5C,CAAJ,CAAsB,CAClB,IAAIxH,CAMAuK,EAAJ,EAAgD,CAAhD,EAAkBvK,CAAlB,CAAsBuK,CAAApK,QAAA,CAAkB,GAAlB,CAAtB,IACIqH,CADJ,CACS+C,CAAArK,OAAA,CAAiB,CAAjB,CAAoBF,CAApB,CAAwB,CAAxB,CADT,CACsCwH,CADtC,CAGA,KAAKxH,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgBwK,CAAApI,OAAhB,CAA6CpC,CAAA,EAA7C,CACI,GAAIyK,CAAA,CAAqBzK,CAArB,CAAAwH,GAAJ,GAAmCA,CAAnC,CACI,MAAOiD,EAAA,CAAqBzK,CAArB,CAZG,CAmBtB,MAAO,KApBX,CA+BA0K,QAAO,GAAkB,CAACC,CAAD,CAAQJ,CAAR,CACzB,CAD4CK,IAAAA,CAExC,IAAcR,IAAAA,EAAd,GAAIO,CAAJ,CAAyB,CACrB,IAAI3K,CAMAuK,EAAJ,GAEQA,CAFR,CACuC,CAAnC,EAAKvK,CAAL,CAASuK,CAAApK,QAAA,CAAkB,GAAlB,CAAT,EACgBoK,CAAArK,OAAA,CAAiB,CAAjB,CAAoBF,CAApB,CAAwB,CAAxB,CADhB,CAGgB,EAJpB,CAOA,KAAKA,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgBwK,CAAApI,OAAhB,CAA6CpC,CAAA,EAA7C,CACI,GAAI4K,CAAJ,CACQA,CAAJ,EAAqBH,CAAA,CAAqBzK,CAArB,CAArB,GAA8C4K,CAA9C,CAA8D,IAA9D,CADJ,KAIA,IAAI,EAAAD,CAAA,EAASF,CAAA,CAAqBzK,CAArB,CAAAkB,KAAT,EAA2CqJ,CAA3C,EAAyDE,CAAA,CAAqBzK,CAArB,CAAAwH,GAAArH,QAAA,CAAmCoK,CAAnC,CAAzD,CAAJ,CACI,MAAOE,EAAA,CAAqBzK,CAArB,CApBM,CAyBzB,MAAO,KA1BX,CAkCA6K,QAAO,EAAiB,CAACxB,CAAD,CACxB,CACI,IAAI/B,EAAQ,IAEZ,IADIzD,CACJ,CADawF,CAAAU,aAAA,CAAqB,YAArB,CACb,CACI,GAAI,CACAzC,CAAA,CAAQwD,IAAA,CAAK,GAAL,CAAWjH,CAAX,CAAoB,GAApB,CADR,CAUF,MAAMa,CAAN,CAAS,CA3Rf4B,CAAA,CA4RwB5B,CAAA6B,QA5RxB,CA4RoC,IA5RpC,CA4R2C1C,CA5R3C,CA4RoD,GA5RpD,CA2Re,CAIf,MAAOyD,EAlBX;AAkCAyD,QAAO,EAAkB,CAAC1B,CAAD,CAAUS,CAAV,CAAkBkB,CAAlB,CACzB,CACQA,CAAJ,GAAelB,CAAf,EAAyB,GAAzB,CAA+BkB,CAA/B,CAA2C,SAA3C,CAKA,IAAI3B,CAAA4B,uBAAJ,CACI,MAAO5B,EAAA4B,uBAAA,CAA+BnB,CAA/B,CAPf,KASWoB,CAAGC,EAAAA,CAAK,EACXC,EAAAA,CAAQ/B,CAAAgC,qBAAA,CAA6B,GAA7B,CACZ,KAAIC,EAAK,IAAIC,MAAJ,CAAW,OAAX,CAAqBzB,CAArB,CAA8B,OAA9B,CACJ9J,EAAA,CAAI,CAAT,KAAYkL,CAAZ,CAAgBE,CAAAhJ,OAAhB,CAA8BpC,CAA9B,CAAkCkL,CAAlC,CAAqClL,CAAA,EAArC,CACQsL,CAAAE,KAAA,CAAQJ,CAAA,CAAMpL,CAAN,CAAAyL,UAAR,CAAJ,EACIN,CAAAjF,KAAA,CAAQkF,CAAA,CAAMpL,CAAN,CAAR,CAMR,OAAOmL,EApBX;AAiIAO,QAAO,GAAe,CAAC/D,CAAD,CACtB,CAMI,IALA,IAAIgE,EAAW,CAAA,CAAf,CACIC,EAAYC,CAAA,CAAmBlE,CAAnB,CAIhB,CAAOiE,CAAP,EAAoBA,CAAAxJ,OAApB,CAAA,CAAsC,CAElC,IAAI0J,EAAUF,CAAAG,OAAA,CAAiB,CAAjB,CAAoB,CAApB,CAAA,CAAuB,CAAvB,CAAd,CACIC,EAAWF,CAAA,CAAQ,CAAR,CADf,CAUIG,EAAc,IAC+B,EAAjD,EAAIC,EAAA/L,QAAA,CAAgC6L,CAAhC,CAAJ,GACIC,CADJ,CACkBE,QAA2B,EAAG,CACxC,MAAO,SAAQ,EAAG,CACdC,EAAA,CAA0BzE,CAA1B,CADc,CADsB,CAA9B,EADlB,CAQA,KAAI0E,EAAYC,EAAA,CAAyBN,CAAzB,CAChB,IAAIK,CAAJ,CACI,GAAI,CAACJ,CAAL,CACIN,CAAA,CAAWU,CAAA,CAAUP,CAAA,CAAQ,CAAR,CAAV,CAAsBA,CAAA,CAAQ,CAAR,CAAtB,CAAkCA,CAAA,CAAQ,CAAR,CAAlC,CADf,KAGI,IAAI,CAACO,CAAA,CAAUJ,CAAV,CAAuBH,CAAA,CAAQ,CAAR,CAAvB,CAAmCA,CAAA,CAAQ,CAAR,CAAnC,CAA+CA,CAAA,CAAQ,CAAR,CAA/C,CAAL,CAAiE,KAAjE,CAJR,IAOK,CACDH,CAAA,CAAW,CAAA,CACX,KAAIjD,EAAY6D,EAAA,CAA6BT,CAAA,CAAQ,CAAR,CAA7B,CAAyCnE,CAAzC,CAChB,IAAIe,CAAJ,CAEI,GADA2D,CACA,CADYG,EAAA,CAA4BR,CAA5B,CACZ,CACIL,CAAA,CAAWU,CAAA,CAAU3D,CAAV,CAAqBoD,CAAA,CAAQ,CAAR,CAArB,CAAiCA,CAAA,CAAQ,CAAR,CAAjC,CADf,KAGK,CACD,IAAIW,EAAU/D,CAAA,QACd,IAAI+D,CAAJ,GACIJ,CADJ,CACgBI,CAAA,CAAQT,CAAR,CADhB,EAIQ,GADAL,CACI,CADO,CAAA,CACP,CAAA,CAACM,CAAL,CACIN,CAAA,CAAWU,CAAAK,KAAA,CAAehE,CAAf,CAA0BoD,CAAA,CAAQ,CAAR,CAA1B,CAAsCA,CAAA,CAAQ,CAAR,CAAtC,CADf,KAGI,IAAI,CAACO,CAAAK,KAAA,CAAehE,CAAf,CAA0BuD,CAA1B,CAAuCH,CAAA,CAAQ,CAAR,CAAvC,CAAmDA,CAAA,CAAQ,CAAR,CAAnD,CAAL,CAAqE,KAThF,CARR,CAyBL,GAAI,CAACH,CAAL,CAAe,CACXrF,CAAA,CAAoB,iBAApB,CAAwC0F,CAAxC,CAAmD,YAAnD,EAAmEK,CAAA,CAAW,SAAX,CAAuB,iBAA1F,EACA,MAFW,CAtDmB,CA4DlCT,CAAJ,EAAiB,CAACA,CAAAxJ,OAAlB,EACI,OAAOyJ,CAAA,CAAmBlE,CAAnB,CAGX,OAAOgE,EAtEX;AAmIA,CAAA,CA/uGJ,CAAAgB,UA+uGIC,EAAAC,SAAA,CAAAA,QAAQ,EACR,CACI,MAAQ,KAAApF,KAAA,CAAW,IAAAA,KAAX,CAAwB,IAAAD,GAAxB,EAAmC,IAAAtG,KAD/C,CAiCA0L;CAAAvC,EAAA,CAAAA,QAAU,CAACyC,CAAD,CAAYC,CAAZ,CAAsBhE,CAAtB,CACV,CACI,OAAQgE,CAAR,EACA,KAAK,OAAL,CAWI,MAVK,KAAArF,EAAA,CAAcqF,CAAd,CAUE,GATH,IAAArF,EAAA,CAAcqF,CAAd,CACA,CAD0BhE,CAC1B,CAAAA,CAAAiE,QAAA,CAAmB,QAAQ,CAACtE,CAAD,CAAY,CACnC,MAAOuE,SAAqB,EAAG,CACvBvE,CAAAhB,EAAA,MAAJ,GACIgB,CAAAhB,EAAA,MAAAuB,MADJ,CACwC,EADxC,CAD2B,CADI,CAApB,CAMjB,IANiB,CAQhB,EAAA,CAAA,CACX,MAAK,OAAL,CAqCI,MApCK,KAAAvB,EAAA,CAAcqF,CAAd,CAoCE,GAlCH,IAAArF,EAAA,CAAcqF,CAAd,CAqBA,CAtByDhE,CAsBzD,CAbA,IAAAmE,GAaA,CAbcC,QAAsB,CAACvO,CAAD,CAAyB,CACzD,IAAAwO,EAAA,CAAaxO,CAAb,CAAgB,IAAAsC,KAAhB,CACA,OAAO,CAAA,CAFkD,CAa7D,CAtByD6H,CAgBzDE,MAMA,CANwB,EAMxB,CALA,IAAAoE,MAKA,CALa,QAAQ,CAACtE,CAAD,CAAU,CAC3B,MAAOuE,SAAqB,CAAC1O,CAAD,CAAI,CAC5B2O,EAAA,CAAwBxE,CAAxB,CAAiCnK,CAAjC,CAD4B,CADL,CAAlB,CAjB4CmK,CAiB5C,CAKb,CAAA,IAAAqE,EAAA,CAAe,QAAQ,CAAC1E,CAAD,CAAYK,CAAZ,CAAqB,CACxC,MAAOyE,SAAuB,CAAC5O,CAAD,CAAIsC,CAAJ,CAAc,CACnCtC,CAAL,GAAQA,CAAR,CAAY,EAAZ,CACA,IAAIsC,CAAJ,EAAYuM,EAAZ,EAAuD,KAAvD,EAAwC7O,CAAA8O,MAAA,CAAS,EAAT,CAAxC,CACQxM,CACJ,GADUtC,CACV,CADcsC,CACd,CADqB,IACrB,CAD4BtC,CAC5B,EAAA2O,EAAA,CAAwBxE,CAAxB,CAAiCnK,CAAjC,CAAqC,IAArC,CAFJ,KAGO,CAxjBnBoK,CAAAA,CAyjByCD,CAzjBjCE,MACZ,KAAIjJ,EAAIgJ,CAAA/I,YAAA,CAwjB8CrB,CAxjB9C,CACA,EAAR,CAAIoB,CAAJ,CACIgJ,CADJ,EAujBsDpK,CAvjBtD,CACuB,IADvB,CAGIoK,CAHJ,CAGYA,CAAA9I,OAAA,CAAa,CAAb,CAAgBF,CAAhB,CAHZ,EAujByDpB,CAvjBzD,CAujB6D,GAvjB7D;AAG4CoK,CAAA9I,OAAA,CAAaF,CAAb,CAojBUpB,CApjBOwD,OAAjB,CAKb,KAA/B,CAAgB4G,CAAA5G,OAAhB,GAAqC4G,CAArC,CAA6CA,CAAA9I,OAAA,CAAa8I,CAAA5G,OAAb,CAA4B,IAA5B,CAA7C,CA+iB6C2G,EA9iB7CE,MAAA,CAAgBD,CA8iB6BD,EA7iB7CG,UAAA,CA6iB6CH,CA7iBzBI,aA4iBG,CALiC,CADJ,CAA7B,CAWb,IAXa,CAtB0CJ,CAsB1C,CAaZ,EAAA,CAAA,CACX,SACI,MAAO,CAAA,CApDX,CADJ,CAsEA6D,EAAA3N,IAAA,CAAAA,QAAG,EACH,EAiEA2N,EAAAS,MAAA,CAAAA,QAAK,EACL,EAeAT,EAAAQ,EAAA,CAAAA,QAAO,EACP,EAaAR,EAAAzK,OAAA,CAAAA,QAAM,CAACvD,CAAD,CACN,CACI,IAAAwO,EAAA,CAAa,IAAAlM,KAAb,CAAyB,IAAzB,CAAgCtC,CAAhC,CADJ,CAiBAgO,EAAAM,GAAA,CAAAA,QAAM,CAACtO,CAAD,CAAI+O,CAAJ,CAAgBnG,CAAhB,CACN,CACI,GAAI,CAACmG,CAAL,CAAiB,CAIb,IAAIC,EAAWrB,EAAA,CAA6B,UAA7B,CAAyC,IAAA/E,GAAzC,CACf,IAAIoG,CAAJ,EAAgBA,CAAAhG,EAAAM,GAAhB,CAEI,MADA2F,QAAA5O,IAAA,CAAY,iCAAZ,CAAgDL,CAAhD,CACO,CAAA,CAAA,CAPE,CAUe,CAAA,CAAA4I,CAAA,EAAM,IAAAtG,KAAlByM,EAvzBpB,EAAiBrH,CAAA,EAAqBkB,CAAA,CAAKA,CAAL,CAAU,IAAV,CAAkB,EAAvC,EAuzBA5I,CAvzBA,CAwzBjB,OAAO,CAAA,CAZX,CAuBAkP,SAAA,GAAQ,CAARA,CAAQ,CAAClP,CAAD,CACR,CACI,CAAAgJ,EAAAO,MAAA,CAAmB,CAAA,CACnB,EAAA+E,GAAA,CAAYtO,CAAZ,CAFJ;AA8CAmP,QAAA,EAAO,CAAPA,CAAO,CAAC3F,CAAD,CACP,CACQA,CAAJ,GACQ,CAAAR,EAAAC,MAAJ,CACIO,CAAA,EADJ,CAII,CAAAA,GAJJ,CAImBA,CALvB,CAQA,OAAO,EAAAR,EAAAC,MATX,CAoBA+E,CAAAoB,EAAA,CAAAA,QAAQ,EACR,CACI,GAAI,CAAC,IAAApG,EAAAO,MAAL,GACI,IAAAP,EAAAC,MACIA,CADgB,CAAA,CAChBA,CAAA,IAAAD,EAAAC,MAFR,EAE0B,CAElB,IAAIO,EAAU,IAAAA,GACd,KAAAA,GAAA,CAAe,IACXA,EAAJ,EAAaA,CAAA,EAJK,CAH9B,CAqBA6F,SAAA,EAAM,CAANA,CAAM,CAACC,CAAD,CACN,CACQ,CAAAtG,EAAAE,GAAJ,GACQoG,CAAJ,CACI,CAAAtG,EAAAG,GADJ,CAC4B,CAAA,CAD5B,CAEuBqC,IAAAA,EAFvB,GAEW8D,CAFX,EAGI,CAAAd,EAAA,CAAa,CAAAP,SAAA,EAAb,CAA+B,OAA/B,CAJR,CAOA,OAAO,EAAAjF,EAAAE,GARX,CAoBAqG,QAAA,EAAO,CAAPA,CAAO,CAACC,CAAD,CACP,CACI,GAAI,CAAAxG,EAAAG,GAAJ,CAGI,MAFA,EAAAH,EAAAE,GACA,CADkB,CAAA,CAClB,CAAA,CAAAF,EAAAG,GAAA,CAAwB,CAAA,CAG5B,IAAI,CAAAH,EAAAO,MAAJ,CAEI,MADA,EAAAiF,EAAA,CAAa,CAAAP,SAAA,EAAb,CAA+B,QAA/B,CACO,CAAA,CAAA,CAEX,EAAAjF,EAAAE,GAAA,CAAkBsG,CAClB,OAAO,EAAAxG,EAAAE,GAXX;AAmDAuG,QAAA,EAAc,CAAdA,CAAc,CAAC9G,CAAD,CACd,CADeA,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAc,CAAd,CAAAA,CAEX,OAAgB,EAAAe,EAAhB,GACQ,CAaA,GAbS,CAAAA,EAaT,GAZAf,CAYA,CAZcA,CAYd,EAZ6B,CAAAA,GAY7B,EAVA+G,CAUA,CAVc,CAAAhG,EAAAf,GAUd,CAVqCA,CAUrC,CAHCA,CAGD,CAHe,UAGf,EAH+BA,CAG/B,CAH6C,SAG7C,GAFM+G,CAEN,CAFoB,UAEpB,EAFqCA,CAErC,CAFmD,SAEnD,GAFgEA,CAEhE,CAF8E,CAE9E,GAAA/G,CAAA,EAAe+G,CAAf,GAA+B/G,CAdvC,EAee,CAAA,CAff,CAkBO,CAAA,CAnBX,CA8GAgH,IAAAA,GAAYA,UAiBZ/M,OAAJ,GACSA,MAAA,KAGL,GAHqBA,MAAA,KAGrB,CAHsC,EAGtC,EAFKA,MAAA,KAAA,SAEL,GAFiCA,MAAA,KAAA,SAEjC,CAF8D,EAE9D,EADKA,MAAA,KAAA,WACL,GADmCA,MAAA,KAAA,WACnC,CADkE,EAClE,EAAKA,MAAA,KAAA,SAAL,GAAiCA,MAAA,KAAA,SAAjC,CAA8D,EAA9D,CAJJ,CAMA;IAAAgN,EAAqBhN,MAAA,CAAQA,MAAA,KAAA,SAAR,CAAqC,EAA1D,CACAiJ,EAAuBjJ,MAAA,CAAQA,MAAA,KAAA,WAAR,CAAuC,EAD9D,CAEAqK,EAAqBrK,MAAA,CAAQA,MAAA,KAAA,SAAR,CAAqC,EAF1D,CAIAiN,GAA0B,CACtB,MADsB,CACd,OADc,CACL,MADK,CAJ1B,CAOAnC,GAA2B,CACvB,MAxlBAoC,QAAkB,CAAC9F,CAAD,CAClB,CACItC,CAAA,CAAoBsC,CAApB,CACA,OAAO,CAAA,CAFX,CAslBuB,CAEvB,MAjjBA+F,QAAkB,CAACC,CAAD,CAAaC,CAAb,CAClB,CACIrK,UAAA,CAAWoK,CAAX,CAAuB,CAACC,CAAxB,CACA,OAAO,CAAA,CAFX,CA8iBuB,CAP3B,CAWArC,GAA8B,CAC1B,OA9kBAsC,QAAmB,CAACpG,CAAD,CAAYqE,CAAZ,CAAsBgC,CAAtB,CACnB,CACI,IAAIpD,EAAW,CAAA,CAGf,IADI5C,CACJ,CAFgBL,CAAAsG,SACF,CAAUjC,CAAV,CACd,CACI,IAAS/M,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoB+I,CAAAkG,QAAA7M,OAApB,CAA4CpC,CAAA,EAA5C,CACI,GAAI+I,CAAAkG,QAAA,CAAgBjP,CAAhB,CAAAkP,YAAJ,EAAsCH,CAAtC,CAA8C,CACtChG,CAAAoG,cAAJ,EAA6BnP,CAA7B,GACI+I,CAAAoG,cADJ,CAC4BnP,CAD5B,CAGA2L,EAAA,CAAW,CAAA,CACX,MAL0C,CAStD,MAAOA,EAfX,CA4kB0B,CAmBzByD;KAAAC,UAAAlP,QAAL,GACIiP,KAAAC,UAAAlP,QADJ,CAC8BmP,QAAQ,CAACC,CAAD,CAAMC,CAAN,CAAa,CAClCxP,CAAAA,CAAKwP,CAALxP,EAAc,CAAvB,KAAK,IAAsBkL,EAAI,IAAA9I,OAA/B,CAA4CpC,CAA5C,CAAgDkL,CAAhD,CAAmDlL,CAAA,EAAnD,CACI,GAAI,IAAA,CAAKA,CAAL,CAAJ,GAAgBuP,CAAhB,CAAuB,MAAOvP,EAElC,OAAQ,EAJmC,CADnD,CAYKoP,MAAAK,QAAL,GACIL,KAAAK,QADJ,CACoBC,QAAQ,CAACC,CAAD,CAAM,CAC1B,MAA+C,gBAA/C,GAAOC,MAAAP,UAAAxC,SAAAH,KAAA,CAA+BiD,CAA/B,CADmB,CADlC,CASKE;QAAAR,UAAAS,KAAL,GACID,QAAAR,UAAAS,KADJ,CAC8BC,QAAQ,CAACR,CAAD,CAAM,CAQtBS,QAAA,EAAQ,EAAG,CACrB,MAAOC,EAAAC,MAAA,CAAc,IAAA,WAAgBC,EAAhB,EAAyBZ,CAAzB,CAA8B,IAA9B,CAAqCA,CAAnD,CAAwDa,CAAAC,OAAA,CAAiCjB,KAAAC,UAAA3B,MAAAhB,KAAA,CAA2B4D,SAA3B,CAAjC,CAAxD,CADc,CADQH,QAAA,EAAQ,EAAG,EAN5C,GAAmB,UAAnB,EAAI,MAAO,KAAX,CAEI,KAAM,KAAII,SAAJ,CAAc,8CAAd,CAAN,CAEJ,IAAIH,EAAOhB,KAAAC,UAAA3B,MAAAhB,KAAA,CAA2B4D,SAA3B,CAAsC,CAAtC,CAAX,CACIL,EAAU,IAKdE,EAAAd,UAAA,CAAkB,IAAAA,UAClBW,EAAAX,UAAA,CAAoB,IAAIc,CACxB,OAAOH,EAb6B,CAD5C,CAwFI5I,SATEoJ,GASS,CAACC,CAAD,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,UAAN,CAAkBA,CAAlB,CAEA,KAAA7I,EAAAK,EAAA,CAAqB,CAAA,CAHzB,CAVmByI,CAAArJ,CAAjBmJ,EAAiBnJ,CAAAA,CAAAA,CA4BnB;EAAA,UAAA,EAAA,CAAAgD,QAAU,CAACyC,CAAD,CAAYC,CAAZ,CAAsBhE,CAAtB,CAA+BgG,CAA/B,CACV,CAII,MAHI,KAAAvG,EAGJ,EAHgB,IAAAA,EAAA6B,EAAA,CAAoByC,CAApB,CAA+BC,CAA/B,CAAyChE,CAAzC,CAAkDgG,CAAlD,CAGhB,EAFI,IAAAxG,EAEJ,EAFgB,IAAAA,EAAA8B,EAAA,CAAoByC,CAApB,CAA+BC,CAA/B,CAAyChE,CAAzC,CAAkDgG,CAAlD,CAEhB,EADI,IAAA4B,EACJ,EADgB,IAAAA,EAAAtG,EAAA,CAAoByC,CAApB,CAA+BC,CAA/B,CAAyChE,CAAzC,CAAkDgG,CAAlD,CAChB,EAAgB,IAAAzG,EAAhB,EAA4B,IAAAA,EAAA+B,EAAA,CAAoByC,CAApB,CAA+BC,CAA/B,CAAyChE,CAAzC,CAAkDgG,CAAlD,CAA5B,CAA8F,CAAA,CAA9F,CACO1E,CAAAA,UAAAA,EAAAA,KAAAA,CAAAA,IAAAA,CAAiByC,CAAjBzC,CAA4B0C,CAA5B1C,CAAsCtB,CAAtCsB,CAA+C0E,CAA/C1E,CALX,CAaA,GAAA,UAAA,GAAA,CAAAuG,QAAQ,CAACC,CAAD,CAAMrI,CAAN,CACR,CACQqI,CAAJ,EAAW,CAAC,IAAAjJ,EAAAK,EAAZ,GACI,IAAAL,EAAAK,EAKA,CALqB,CAAA,CAKrB,CAJA,IAAAO,EAIA,CAJWA,CAIX,CAHA,IAAAD,EAGA,CAHWmC,CAAA,CAAAlC,CAAA,CAAuB,KAAvB,CAGX,CAFA,IAAAmI,EAEA,CAFWjG,CAAA,CAAAlC,CAAA,CAAuB,UAAvB,CAEX,CADc,IAAAF,EACd,CADyBoC,CAAA,CAAAlC,CAAA,CAAuB,UAAvB,CACzB,CAAAsI,EAAA,EANJ,CADJ,CA4BAC,SAAO,GAAI,EACX,CAGI,IAFA,IAAIC,EAAS,CAAA,CAAb,CACIC,EAAW1H,CAAA,CAA6B2H,QAA7B,CA9HRC,OA8HQ,CAAuD,OAAvD,CADf,CAESC,EAAO,CAAhB,CAAmBA,CAAnB,CAA4BH,CAAA7O,OAA5B,CAA6CgP,CAAA,EAA7C,CAAuD,CACnD,IAAIC,EAASJ,CAAA,CAASG,CAAT,CAAb,CACIX,EAAatG,CAAA,CAA4BkH,CAA5B,CADjB,CAEIC,EAAQC,EAAA,CAA2Bd,CAAA,GAA3B,CACPa,EAAL,GACIN,CACA,CADS,CAAA,CACT,CAAAM,CAAA,CAAQ,IAAId,EAAJ,CAAaC,CAAb,CAFZ,CAIAe,EAAA,CAAgCF,CAAhC,CAAuCD,CAAvC,CACIL,EAAJ,EAAYM,CAAAtD,EAAA,EATuC,CAH3D,CAoBJyD,CAAA,CAAWX,EAAX,CAmCI1J;QArBEsK,GAqBS,CAACC,CAAD,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,QAAN,CAAgBA,CAAhB,CAEAC,GAAA,CAAAA,IAAA,CACA,KAAAhK,EAAAK,EAAA,CAAqB,CAAA,CACrB,KAAAL,EAAAiK,GAAA,CAAqB,CAAA,CACrB,KAAAC,GAAA,CAAkBH,CAAA,UAUlB,KAAAI,GAAA,CAAkB,CAClB,KAAAC,GAAA,CAAkB,CAClB,KAAAC,GAAA,CAAkB,CAClB,KAAAC,MAAA,CAAa,IAAAH,GAoBb,KAAAI,GAAA,CAA8B,EAC9B,KAAAC,GAAA,CAA+B,CAE/B,KAAAC,GAAA,CAAe,CACf,KAAAC,GAAA,CAAe,CAAC,MAAD,CAAS,MAAT,CAAiB,KAAjB,CACf,KAAAC,GAAA,CAAmB,CAAC,QAAD,CAA8B,SAA9B,CAA0C,IAAAF,GAA1C,CAAyD,MAAzD,CAAiE,aAAjE,CA4BnB,KAAAG,EAAA,CAAmB,EACnB,KAAAC,EAAA,CAAoB,EAOpB,KAAAC,GAAA,CAAqB,KACrB,KAAAC,GAAA,CAAqB,CACrB,KAAAC,GAAA,CAAsB,KACtB,KAAAC,GAAA,CAAsB,CAoBtB,KAAAC,GAAA,CAAsB,EAKtB,KAAAC,GAAA,CAAsB,CAEtB,KAAAC,GAAA,CAAsB,CAStB,KAAAC,EAAA,CAAoB,CAChB,IAAAC,GADgB,CAEhB,IAAAC,GAFgB,CAGhB,IAAAC,GAHgB,CAIhB,IAAAC,EAJgB,CAKhB,IAAAA,EALgB,CAMhB,IAAAC,GANgB,CAOhB,IAAAC,GAPgB,CAQhB,IAAAF,EARgB,CAShB,IAAAG,GATgB,CAUhB,IAAAC,GAVgB,CAWhB,IAAAC,GAXgB,CAYhB,IAAAL,EAZgB,CAahB,IAAAA,EAbgB,CAchB,IAAAM,GAdgB,CAehB,IAAAC,GAfgB,CAgBhB,IAAAP,EAhBgB,CAiBhB,IAAAQ,GAjBgB,CAkBhB,IAAAC,GAlBgB;AAmBhB,IAAAT,EAnBgB,CAoBhB,IAAAA,EApBgB,CAqBhB,IAAAA,EArBgB,CAsBhB,IAAAU,GAtBgB,CAuBhB,IAAAC,GAvBgB,CAwBhB,IAAAX,EAxBgB,CAyBhB,IAAAY,GAzBgB,CA0BhB,IAAAC,GA1BgB,CA2BhB,IAAAb,EA3BgB,CA4BhB,IAAAA,EA5BgB,CA6BhB,IAAAA,EA7BgB,CA8BhB,IAAAc,GA9BgB,CA+BhB,IAAAC,GA/BgB,CAgChB,IAAAf,EAhCgB,CAiChB,IAAAgB,GAjCgB,CAkChB,IAAAC,GAlCgB,CAmChB,IAAAjB,EAnCgB,CAoChB,IAAAA,EApCgB,CAqChB,IAAAkB,GArCgB,CAsChB,IAAAC,GAtCgB,CAuChB,IAAAC,GAvCgB,CAwChB,IAAApB,EAxCgB,CAyChB,IAAAqB,GAzCgB,CA0ChB,IAAAC,GA1CgB,CA2ChB,IAAAC,GA3CgB,CA4ChB,IAAAvB,EA5CgB,CA6ChB,IAAAwB,GA7CgB,CA8ChB,IAAAC,GA9CgB,CA+ChB,IAAAC,GA/CgB,CAgDhB,IAAA1B,EAhDgB,CAiDhB,IAAA2B,GAjDgB,CAkDhB,IAAAC,GAlDgB,CAmDhB,IAAA5B,EAnDgB,CAoDhB,IAAAA,EApDgB,CAqDhB,IAAAA,EArDgB,CAsDhB,IAAA6B,GAtDgB,CAuDhB,IAAAC,GAvDgB,CAwDhB,IAAA9B,EAxDgB,CAyDhB,IAAA+B,GAzDgB,CA0DhB,IAAAC,GA1DgB,CA2DhB,IAAAhC,EA3DgB,CA4DhB,IAAAA,EA5DgB,CA6DhB,IAAAA,EA7DgB,CA8DhB,IAAAiC,GA9DgB,CA+DhB,IAAAC,GA/DgB,CAgEhB,IAAAlC,EAhEgB,CAiEhB,IAAAmC,GAjEgB,CAkEhB,IAAAC,GAlEgB,CAmEhB,IAAApC,EAnEgB,CAoEhB,IAAAA,EApEgB,CAqEhB,IAAAA,EArEgB,CAsEhB,IAAAqC,GAtEgB,CAuEhB,IAAAC,GAvEgB,CAwEhB,IAAAtC,EAxEgB,CAyEhB,IAAAuC,GAzEgB,CA0EhB,IAAAC,GA1EgB,CA2EhB,IAAAC,GA3EgB,CA4EhB,IAAAzC,EA5EgB,CA6EhB,IAAA0C,GA7EgB,CA8EhB,IAAAC,GA9EgB,CA+EhB,IAAAC,GA/EgB,CAgFhB,IAAA5C,EAhFgB,CAiFhB,IAAA6C,GAjFgB,CAkFhB,IAAAC,GAlFgB,CAmFhB,IAAA9C,EAnFgB,CAoFhB,IAAAA,EApFgB,CAqFhB,IAAAA,EArFgB;AAsFhB,IAAA+C,GAtFgB,CAuFhB,IAAAC,GAvFgB,CAwFhB,IAAAhD,EAxFgB,CAyFhB,IAAAiD,GAzFgB,CA0FhB,IAAAC,GA1FgB,CA2FhB,IAAAlD,EA3FgB,CA4FhB,IAAAA,EA5FgB,CA6FhB,IAAAA,EA7FgB,CA8FhB,IAAAmD,GA9FgB,CA+FhB,IAAAC,GA/FgB,CAgGhB,IAAApD,EAhGgB,CAiGhB,IAAAqD,GAjGgB,CAkGhB,IAAAC,GAlGgB,CAmGhB,IAAAtD,EAnGgB,CAoGhB,IAAAA,EApGgB,CAqGhB,IAAAA,EArGgB,CAsGhB,IAAAuD,GAtGgB,CAuGhB,IAAAC,GAvGgB,CAwGhB,IAAAxD,EAxGgB,CAyGhB,IAAAyD,GAzGgB,CA0GhB,IAAAC,GA1GgB,CA2GhB,IAAAC,GA3GgB,CA4GhB,IAAA3D,EA5GgB,CA6GhB,IAAA4D,GA7GgB,CA8GhB,IAAAC,GA9GgB,CA+GhB,IAAAC,GA/GgB,CAgHhB,IAAA9D,EAhHgB,CAiHhB,IAAA+D,GAjHgB,CAkHhB,IAAAC,GAlHgB,CAmHhB,IAAAhE,EAnHgB,CAoHhB,IAAAA,EApHgB,CAqHhB,IAAAA,EArHgB,CAsHhB,IAAAiE,GAtHgB,CAuHhB,IAAAC,GAvHgB,CAwHhB,IAAAlE,EAxHgB,CAyHhB,IAAAmE,GAzHgB,CA0HhB,IAAAC,GA1HgB,CA2HhB,IAAApE,EA3HgB,CA4HhB,IAAAA,EA5HgB,CA6HhB,IAAAA,EA7HgB,CA8HhB,IAAAqE,GA9HgB,CA+HhB,IAAAC,GA/HgB,CAgIhB,IAAAtE,EAhIgB,CAiIhB,IAAAA,EAjIgB,CAkIhB,IAAAuE,GAlIgB,CAmIhB,IAAAvE,EAnIgB,CAoIhB,IAAAA,EApIgB,CAqIhB,IAAAwE,GArIgB,CAsIhB,IAAAC,GAtIgB,CAuIhB,IAAAC,GAvIgB,CAwIhB,IAAA1E,EAxIgB,CAyIhB,IAAA2E,GAzIgB,CA0IhB,IAAA3E,EA1IgB,CA2IhB,IAAA4E,GA3IgB,CA4IhB,IAAA5E,EA5IgB,CA6IhB,IAAA6E,GA7IgB,CA8IhB,IAAAC,GA9IgB,CA+IhB,IAAAC,GA/IgB,CAgJhB,IAAA/E,EAhJgB,CAiJhB,IAAAgF,GAjJgB,CAkJhB,IAAAC,GAlJgB,CAmJhB,IAAAjF,EAnJgB,CAoJhB,IAAAA,EApJgB,CAqJhB,IAAAkF,GArJgB,CAsJhB,IAAAC,GAtJgB,CAuJhB,IAAAC,GAvJgB,CAwJhB,IAAApF,EAxJgB;AAyJhB,IAAAqF,GAzJgB,CA0JhB,IAAAC,GA1JgB,CA2JhB,IAAAC,GA3JgB,CA4JhB,IAAAvF,EA5JgB,CA6JhB,IAAAA,EA7JgB,CA8JhB,IAAAwF,GA9JgB,CA+JhB,IAAAxF,EA/JgB,CAgKhB,IAAAA,EAhKgB,CAiKhB,IAAAyF,GAjKgB,CAkKhB,IAAAC,GAlKgB,CAmKhB,IAAAC,GAnKgB,CAoKhB,IAAA3F,EApKgB,CAqKhB,IAAA4F,GArKgB,CAsKhB,IAAAC,GAtKgB,CAuKhB,IAAAC,GAvKgB,CAwKhB,IAAA9F,EAxKgB,CAyKhB,IAAA+F,GAzKgB,CA0KhB,IAAAC,GA1KgB,CA2KhB,IAAAC,GA3KgB,CA4KhB,IAAAjG,EA5KgB,CA6KhB,IAAAkG,GA7KgB,CA8KhB,IAAAC,GA9KgB,CA+KhB,IAAAC,GA/KgB,CAgLhB,IAAApG,EAhLgB,CAiLhB,IAAAqG,GAjLgB,CAkLhB,IAAAC,GAlLgB,CAmLhB,IAAAtG,EAnLgB,CAoLhB,IAAAA,EApLgB,CAqLhB,IAAAuG,GArLgB,CAsLhB,IAAAC,GAtLgB,CAuLhB,IAAAC,GAvLgB,CAwLhB,IAAAzG,EAxLgB,CAyLhB,IAAA0G,GAzLgB,CA0LhB,IAAAC,GA1LgB,CA2LhB,IAAAC,GA3LgB,CA4LhB,IAAA5G,EA5LgB,CA6LhB,IAAA6G,GA7LgB,CA8LhB,IAAAC,GA9LgB,CA+LhB,IAAAC,GA/LgB,CAgMhB,IAAA/G,EAhMgB,CAiMhB,IAAAgH,GAjMgB,CAkMhB,IAAAC,GAlMgB,CAmMhB,IAAAjH,EAnMgB,CAoMhB,IAAAA,EApMgB,CAqMhB,IAAAkH,GArMgB,CAsMhB,IAAAC,GAtMgB,CAuMhB,IAAAC,GAvMgB,CAwMhB,IAAApH,EAxMgB,CAyMhB,IAAAqH,GAzMgB,CA0MhB,IAAAC,GA1MgB,CA2MhB,IAAAC,GA3MgB,CA4MhB,IAAAvH,EA5MgB,CA6MhB,IAAAwH,GA7MgB,CA8MhB,IAAAC,GA9MgB,CA+MhB,IAAAC,GA/MgB,CAgNhB,IAAA1H,EAhNgB,CAiNhB,IAAA2H,GAjNgB,CAkNhB,IAAAC,GAlNgB,CAmNhB,IAAA5H,EAnNgB,CAoNhB,IAAAA,EApNgB,CAqNhB,IAAAA,EArNgB,CAsNhB,IAAA6H,GAtNgB,CAuNhB,IAAAC,GAvNgB,CAwNhB,IAAA9H,EAxNgB,CAyNhB,IAAA+H,GAzNgB,CA0NhB,IAAAC,GA1NgB;AA2NhB,IAAAhI,EA3NgB,CA4NhB,IAAAA,EA5NgB,CA6NhB,IAAAA,EA7NgB,CA8NhB,IAAAiI,GA9NgB,CA+NhB,IAAAC,GA/NgB,CAgOhB,IAAAlI,EAhOgB,CAiOhB,IAAAmI,GAjOgB,CAkOhB,IAAAC,GAlOgB,CAmOhB,IAAApI,EAnOgB,CAoOhB,IAAAA,EApOgB,CAqOhB,IAAAqI,GArOgB,CAsOhB,IAAAC,GAtOgB,CAuOhB,IAAAC,GAvOgB,CAwOhB,IAAAvI,EAxOgB,CAyOhB,IAAAwI,GAzOgB,CA0OhB,IAAAC,GA1OgB,CA2OhB,IAAAC,GA3OgB,CA4OhB,IAAA1I,EA5OgB,CA6OhB,IAAA2I,GA7OgB,CA8OhB,IAAAC,GA9OgB,CA+OhB,IAAAC,GA/OgB,CAgPhB,IAAA7I,EAhPgB,CAiPhB,IAAA8I,GAjPgB,CAkPhB,IAAAC,GAlPgB,CAmPhB,IAAA/I,EAnPgB,CAoPhB,IAAAA,EApPgB,CAqPhB,IAAAA,EArPgB,CAsPhB,IAAAgJ,GAtPgB,CAuPhB,IAAAC,GAvPgB,CAwPhB,IAAAjJ,EAxPgB,CAyPhB,IAAAkJ,GAzPgB,CA0PhB,IAAAC,GA1PgB,CA2PhB,IAAAnJ,EA3PgB,CA4PhB,IAAAA,EA5PgB,CA6PhB,IAAAA,EA7PgB,CA8PhB,IAAAoJ,GA9PgB,CA+PhB,IAAAC,GA/PgB,CAgQhB,IAAArJ,EAhQgB,CAqRpB,KAAAsJ,GAAA,CAAqB,CACjB,CADiB,CACf,CADe,CACb,CADa,CACX,CADW,CACT,CADS,CACP,CADO,CACL,CADK,CACH,CADG,CACD,CADC,CACC,CADD,CACG,CADH,CACK,CADL,CACO,CADP,CACS,CADT,CACW,CADX,CACa,CADb,CAEjB,CAFiB,CAEf,CAFe,CAEb,CAFa,CAEX,CAFW,CAET,CAFS,CAEP,CAFO,CAEL,CAFK,CAEH,CAFG,CAED,CAFC,CAEC,CAFD,CAEG,CAFH,CAEK,CAFL,CAEO,CAFP,CAES,CAFT,CAEW,CAFX,CAEa,CAFb,CAGjB,CAHiB,CAGf,CAHe,CAGb,CAHa,CAGX,CAHW,CAGT,CAHS,CAGP,CAHO,CAGL,CAHK,CAGH,CAHG,CAGD,CAHC,CAGC,CAHD,CAGG,CAHH,CAGK,CAHL,CAGO,CAHP,CAGS,CAHT,CAGW,CAHX,CAGa,CAHb,CAIjB,CAJiB,CAIf,CAJe,CAIb,CAJa,CAIX,CAJW,CAIT,CAJS,CAIP,CAJO,CAIL,CAJK,CAIH,CAJG,CAID,CAJC,CAIC,CAJD,CAIG,CAJH,CAIK,CAJL,CAIO,CAJP,CAIS,CAJT,CAIW,CAJX,CAIa,CAJb,CAKjB,CALiB,CAKf,CALe,CAKb,CALa,CAKX,CALW,CAKT,CALS,CAKP,CALO,CAKL,CALK,CAKH,CALG,CAKD,CALC,CAKC,CALD,CAKG,CALH,CAKK,CALL,CAKO,CALP,CAKS,CALT,CAKW,CALX,CAKa,CALb,CAMjB,CANiB,CAMf,CANe,CAMb,CANa,CAMX,CANW,CAMT,CANS,CAMP,CANO,CAML,CANK,CAMH,CANG,CAMD,CANC,CAMC,CAND,CAMG,CANH,CAMK,CANL,CAMO,CANP,CAMS,CANT,CAMW,CANX,CAMa,CANb,CAOjB,CAPiB,CAOf,CAPe,CAOb,CAPa,CAOX,CAPW,CAOT,CAPS,CAOP,CAPO;AAOL,CAPK,CAOH,CAPG,CAOD,CAPC,CAOC,CAPD,CAOG,CAPH,CAOK,CAPL,CAOO,CAPP,CAOS,CAPT,CAOW,CAPX,CAOa,CAPb,CAQjB,CARiB,CAQf,CARe,CAQb,CARa,CAQX,CARW,CAQT,CARS,CAQP,CARO,CAQL,CARK,CAQH,CARG,CAQD,CARC,CAQC,CARD,CAQG,CARH,CAQK,CARL,CAQO,CARP,CAQS,CART,CAQW,CARX,CAQa,CARb,CASjB,CATiB,CASf,CATe,CASb,CATa,CASX,CATW,CAST,CATS,CASP,CATO,CASL,CATK,CASH,CATG,CASD,CATC,CASC,CATD,CASG,CATH,CASK,CATL,CASO,CATP,CASS,CATT,CASW,CATX,CASa,CATb,CAUjB,CAViB,CAUf,CAVe,CAUb,CAVa,CAUX,CAVW,CAUT,CAVS,CAUP,CAVO,CAUL,CAVK,CAUH,CAVG,CAUD,CAVC,CAUC,CAVD,CAUG,CAVH,CAUK,CAVL,CAUO,CAVP,CAUS,CAVT,CAUW,CAVX,CAUa,CAVb,CAWjB,CAXiB,CAWf,CAXe,CAWb,CAXa,CAWX,CAXW,CAWT,CAXS,CAWP,CAXO,CAWL,CAXK,CAWH,CAXG,CAWD,CAXC,CAWC,CAXD,CAWG,CAXH,CAWK,CAXL,CAWO,CAXP,CAWS,CAXT,CAWW,CAXX,CAWa,CAXb,CAYjB,CAZiB,CAYf,CAZe,CAYb,CAZa,CAYX,CAZW,CAYT,CAZS,CAYP,CAZO,CAYL,CAZK,CAYH,CAZG,CAYD,CAZC,CAYC,CAZD,CAYG,CAZH,CAYK,CAZL,CAYO,CAZP,CAYS,CAZT,CAYW,CAZX,CAYa,CAZb,CAajB,CAbiB,CAaf,CAbe,CAab,CAba,CAaX,CAbW,CAaT,CAbS,CAaP,CAbO,CAaL,CAbK,CAaH,CAbG,CAaD,CAbC,CAaC,CAbD,CAaG,CAbH,CAaK,CAbL,CAaO,CAbP,CAaS,CAbT,CAaW,CAbX,CAaa,CAbb,CAcjB,CAdiB,CAcf,CAde,CAcb,CAda,CAcX,CAdW,CAcT,CAdS,CAcP,CAdO,CAcL,CAdK,CAcH,CAdG,CAcD,CAdC,CAcC,CAdD,CAcG,CAdH,CAcK,CAdL,CAcO,CAdP,CAcS,CAdT,CAcW,CAdX,CAca,CAdb,CAejB,CAfiB,CAef,CAfe,CAeb,CAfa,CAeX,CAfW,CAeT,CAfS,CAeP,CAfO,CAeL,CAfK,CAeH,CAfG,CAeD,CAfC,CAeC,CAfD,CAeG,CAfH,CAeK,CAfL,CAeO,CAfP,CAeS,CAfT,CAeW,CAfX,CAea,CAfb,CAgBjB,CAhBiB,CAgBf,CAhBe,CAgBb,CAhBa,CAgBX,CAhBW,CAgBT,CAhBS,CAgBP,CAhBO,CAgBL,CAhBK,CAgBH,CAhBG,CAgBD,CAhBC,CAgBC,CAhBD,CAgBG,CAhBH,CAgBK,CAhBL,CAgBO,CAhBP,CAgBS,CAhBT,CAgBW,CAhBX,CAgBa,CAhBb,CA5YzB,CAtBiBjM,CAAArJ,CAAfqK,EAAerK,CAAAA,CAAAA,CAicjB,EAAA,CAx7IJ,EAAAuV,UAw7IIhQ;CAAAiQ,MAAA,CAAAA,QAAK,CAACC,CAAD,CACL,CACQ,IAAAlV,EAAAiK,GAAJ,EACI,IAAAkL,GAAA,EAEJnL,GAAA,CAAAA,IAAA,CACA,KAAAoL,EAAA,CAAaC,IAo1BLC,EAAA,CApqCcC,KAoqCd,CAp1BR,CAAaF,IAo1BeC,EAAA,CAAW,KAAX,CAp1B5B,EAo1BkD,CAn1BlD7U,KA/8BAT,EAAAO,MAAA,CAAmB,CAAA,CAm9BH,KAAAG,EAAhB,CACI,IAAAA,EAAAuU,MAAA,EADJ,CAGSC,CAHT,GAI4B,CAAA,CAJ5B,GAIQ,IAAAhL,GAJR,EAIwD,IAJxD,GAIoC,IAAAA,GAJpC,EAI8E,CAAC,IAAAxJ,EAJ/E,EAIqH8B,IAAAA,EAJrH,GAI4F,IAAA1C,EAAA,IAJ5F,GAKQ,IAAA0V,GAAA,EAfZ,CA4BAxQ;CAAAvC,EAAA,CAAAA,QAAU,CAACyC,CAAD,CAAYC,CAAZ,CAAsBhE,CAAtB,CACV,CACQsU,CAAAA,CAAS,CAAA,CACb,QAAOtQ,CAAP,EACI,KAAK,KAAL,CACI,IAAArF,EAAA,CAAcqF,CAAd,CAAA,CAA0BhE,CAC1BA,EAAAiE,QAAA,CAAkB,QAAQ,CAACzE,CAAD,CAAM,CAC5B,MAAO,SAAQ,EAAG,CACTA,CAAAX,EAAAiK,GAAL,CAGItJ,CAAAwU,GAAA,EAHJ,CACIxU,CAAA6U,GAAA,EAFU,CADU,CAAd,CAQhB,IARgB,CASlBC,EAAA,CAAS,CAAA,CACT,MACJ,MAAK,GAAL,CAAU,KAAK,GAAL,CAAU,KAAK,GAAL,CAAU,KAAK,GAAL,CAAU,KAAK,IAAL,CACxC,KAAK,GAAL,CAAU,KAAK,GAAL,CAAU,KAAK,GAAL,CAAU,KAAK,GAAL,CAAU,KAAK,GAAL,CAAU,KAAK,GAAL,CAAU,KAAK,GAAL,CAC5D,KAAK,OAAL,CACI,IAAA3V,EAAA,CAAcqF,CAAd,CAAA,CAA0BhE,CAC1BsU,EAAA,CAAS,CAAA,CACT,MACJ,MAAK,UAAL,CACI,IAAA3V,EAAA,CAAcqF,CAAd,CAOA,CAP0BhE,CAO1B,CANAA,CAAAiE,QAMA,CANkB,QAAQ,CAACzE,CAAD,CAAM,CAC5B,MAAO,SAAQ,EAAG,CAEd+U,CAAA,CAAA/U,CAAA,CAldE0J,CAidWC,EAAA3J,CAAA2J,MAAAA,CAA4B3J,CAAAwJ,GAA5BG,CAA6C3J,CAAA2J,MAA7CA,CAAuD,CACpE,CAAoB,CAAA,CAApB,CAFc,CADU,CAAd,CAKhB,IALgB,CAMlB,CAAAmL,CAAA,CAAS,CAAA,CA5BjB,CAiCA,MAAOA,EAnCX,CA4CAzQ;CAAA2Q,GAAA,CAAAA,QAAS,CAACC,CAAD,CAAWhO,CAAX,CAAkBiO,CAAlB,CACT,CACI,IAAAP,EAAA,CAAaM,CACb,KAAAE,EAAA,CAAclO,CACd,KAAAmO,GAAA,CAAaF,CAAb,CAAmBjO,CAAnB,CAA2B,CAC3B,KAAAoO,GAAA,CAAgB,IAAAF,EAAhB,CAA8B,IAAAC,GAC1B,KAAAD,EAAJ,CA90DApX,CAAA,CAs1DoB,yCAt1DpB,CAs1DgE,IAAAoX,EAt1DhE,CAs1D8E,GAt1D9E,CA80DA,CAWA,IAAA1P,EAAA,EAhBJ,CAwBApB,EAAAgE,GAAA,CAAAA,QAAQ,CAACC,CAAD,CAAMrI,CAAN,CACR,CACI,GAAIqI,CAAJ,EAAW,CAAC,IAAAjJ,EAAAK,EAAZ,CAAgC,CAC5B,IAAAO,EAAA,CAAWA,CAOP,EADA,IAAAF,EACA,CADWoC,CAAA,CAAAlC,CAAA,CAAuB,UAAvB,CACX,GACI,IAAAF,EAAAyI,GAAA,EAOR,IADI8M,CACJ,CADYnT,CAAA,CAAAlC,CAAA,CAAuB,OAAvB,CACZ,CACI,IAAAsV,GAKA,CALoB,QAAQ,CAACtf,CAAD,CAAI,CAC5B,MAAO,SAAQ,EAAG,CACduf,EAAA,CAAAvf,CAAA,CADc,CADU,CAAZ,CAIlBqf,CAJkB,CAKpB,CAAA,IAAAG,GAAA,CAAgB,QAAQ,CAACxf,CAAD,CAAI,CACxB,MAAO,SAAQ,EAAG,CACdA,CAAAwf,GAAA,EADc,CADM,CAAZ,CAIdH,CAJc,CAMpB,KAAAjW,EAAAK,EAAA,CAAqB,CAAA,CACrB,KAAA4U,MAAA,CAAW,CAAA,CAAX,CACA,KAAAoB,OAAA,EA9B4B,CADpC,CA4CAC,SAAA,GAAa,CAAbA,CAAa,CAAC1O,CAAD,CAAQiO,CAAR,CAAa/U,CAAb,CAAwB/D,CAAxB,CACb,CACuE,CAAnE,CAAIwZ,EAAA,CAAgB,CAAA3L,EAAhB,CAAkChD,CAAlC,CAAyCiO,CAAzC,CAA8C/U,CAA9C,CAAyD/D,CAAzD,CAAJ,GACQ,CAAA+N,GAIJ,CAJyBlD,CAIzB,GAHI,CAAAkD,GAGJ,CAHyBlD,CAGzB,EAFI,CAAAmD,GAEJ,CAFyB8K,CAEzB,GADI,CAAA9K,GACJ,CADyB8K,CACzB,EAAA,CAAAjL,EAAAtM,KAAA,CAAsB,CAACsJ,CAAD,CAAQiO,CAAR,CAAa/U,CAAb,CAAwB/D,CAAxB,CAAtB,CALJ,CADJ;AAkBAyZ,QAAA,GAAe,CAAfA,CAAe,CAACC,CAAD,CAAWC,CAAX,CACf,CACI,IAAK,IAAIte,EAAE,CAAX,CAAcA,CAAd,CAAkB,CAAAwS,EAAApQ,OAAlB,CAA2CpC,CAAA,EAA3C,CACQqe,CAAJ,EAAgB,CAAA7L,EAAA,CAAiBxS,CAAjB,CAAA,CAAoB,CAApB,CAAhB,EAA0Cqe,CAA1C,EAAsD,CAAA7L,EAAA,CAAiBxS,CAAjB,CAAA,CAAoB,CAApB,CAAtD,EACI,CAAAwS,EAAA,CAAiBxS,CAAjB,CAAA,CAAoB,CAApB,CAAA0M,KAAA,CAA4B,CAAA8F,EAAA,CAAiBxS,CAAjB,CAAA,CAAoB,CAApB,CAA5B,CAAoDqe,CAApD,CAA8DC,CAA9D,CAHZ,CAuCAC,QAAA,EAAc,CAAdA,CAAc,CAAC/O,CAAD,CAAQiO,CAAR,CAAa/U,CAAb,CAAwB/D,CAAxB,CACd,CACwE,CAApE,CAAIwZ,EAAA,CAAgB,CAAA1L,EAAhB,CAAmCjD,CAAnC,CAA0CiO,CAA1C,CAA+C/U,CAA/C,CAA0D/D,CAA1D,CAAJ,GACQ,CAAAiO,GAIJ,CAJ0BpD,CAI1B,GAHI,CAAAoD,GAGJ,CAH0BpD,CAG1B,EAFI,CAAAqD,GAEJ,CAF0B4K,CAE1B,GADI,CAAA5K,GACJ,CAD0B4K,CAC1B,EAAA,CAAAhL,EAAAvM,KAAA,CAAuB,CAACsJ,CAAD,CAAQiO,CAAR,CAAa/U,CAAb,CAAwB/D,CAAxB,CAAvB,CALJ,CADJ,CAkBA6Z,QAAA,GAAgB,CAAhBA,CAAgB,CAACC,CAAD,CAAYH,CAAZ,CAChB,CACI,IAAK,IAAIte,EAAE,CAAX,CAAcA,CAAd,CAAkB,CAAAyS,EAAArQ,OAAlB,CAA4CpC,CAAA,EAA5C,CACQye,CAAJ,EAAiB,CAAAhM,EAAA,CAAkBzS,CAAlB,CAAA,CAAqB,CAArB,CAAjB,EAA4Cye,CAA5C,EAAyD,CAAAhM,EAAA,CAAkBzS,CAAlB,CAAA,CAAqB,CAArB,CAAzD,EACI,CAAAyS,EAAA,CAAkBzS,CAAlB,CAAA,CAAqB,CAArB,CAAA0M,KAAA,CAA6B,CAAA+F,EAAA,CAAkBzS,CAAlB,CAAA,CAAqB,CAArB,CAA7B,CAAsDye,CAAtD,CAAiEH,CAAjE,CAHZ,CAyCAH,QAAA,GAAU,CAACO,CAAD,CAAUlP,CAAV,CAAiBiO,CAAjB,CAAsB/U,CAAtB,CAAiC/D,CAAjC,CACV,CACI,IAAK,IAAI3E,EAAE,CAAX,CAAcA,CAAd,CAAkB0e,CAAAtc,OAAlB,CAAkCpC,CAAA,EAAlC,CACI,GAAI0e,CAAA,CAAQ1e,CAAR,CAAA,CAAW,CAAX,CAAJ,EAAqBwP,CAArB,EAA8BkP,CAAA,CAAQ1e,CAAR,CAAA,CAAW,CAAX,CAA9B,EAA+Cyd,CAA/C,EAAsDiB,CAAA,CAAQ1e,CAAR,CAAA,CAAW,CAAX,CAAtD,EAAuE0I,CAAvE,EAAoFgW,CAAA,CAAQ1e,CAAR,CAAA,CAAW,CAAX,CAApF,EAAqG2E,CAArG,CACI,MAAO3E,EAGf,OAAQ,EANZ;AAiDAsd,QAAA,EAAQ,CAARA,CAAQ,CAACpL,CAAD,CAAQyM,CAAR,CACR,CACkBvU,IAAAA,EAAd,GAAI8H,CAAJ,GACI,CAAAA,MAIA,CAJaA,CAIb,CAHI,CAAAxK,EAAA,SAGJ,GAFI,CAAAA,EAAA,SAAAkX,UAEJ,CAF0C,CAAAtM,GAAA,CAAsB,CAAT,EAAAJ,CAAA,CAAY,CAAZ,CAAgBA,CAAhB,CAAsB,CAAnC,CAE1C,EADA,CAAA9E,EAAA,CAAa,aAAb,CAA6B,CAAAkF,GAAA,CAAaJ,CAAb,CAAA5R,YAAA,EAA7B,CAAiE,SAAjE,CAA6E,CAAAiS,GAAA,CAAiBL,CAAjB,CAA7E,CACA,CAAIyM,CAAJ,EAAc,CAAAX,GAAA,EALlB,CAOA,EAAAa,EAAA,CAAkB,CAClB,EAAAC,GAAA,CAAkBle,EAAA,EAClBme,GAAA,CAAAA,CAAA,CAVJ,CA8BAnS,CAAAkR,GAAA,CAAAA,QAAY,EACZ,EAOAlR,EAAAoR,GAAA,CAAAA,QAAQ,EACR,EAUAgB,SAAA,EAAU,CAAVA,CAAU,CAACC,CAAD,CAAOC,CAAP,CAAaC,CAAb,CACV,CACgC/U,IAAAA,EAA5B,GAAI,CAAA1C,EAAA,CAAcuX,CAAd,CAAJ,GACgB7U,IAAAA,EAEZ,GAFI+U,CAEJ,GAFuBA,CAEvB,CAF6B,CAE7B,EADIvgB,CACJ,CADQ,MACR,CADiBsgB,CAAArS,SAAA,CAAc,EAAd,CACjB,CAAA,CAAAnF,EAAA,CAAcuX,CAAd,CAAAL,UAAA,CAAgChgB,CAAA8O,MAAA,CAAQ9O,CAAAwD,OAAR,CAAiB+c,CAAjB,CAAAC,YAAA,EAHpC,CADJ;AAWAC,QAAA,GAAa,CAAbA,CAAa,CACb,CACIL,CAAA,CAAAA,CAAA,CAAgB,GAAhB,CAAqB,CAAAM,EAArB,CAAgC,CAAhC,CACAN,EAAA,CAAAA,CAAA,CAAgB,GAAhB,CAAqB,CAAAO,EAArB,CAAgC,CAAhC,CACAP,EAAA,CAAAA,CAAA,CAAgB,GAAhB,CAAqB,CAAAQ,EAArB,CAAgC,CAAhC,CACA,KAAIC,EAAOC,EAAA,CAAAA,CAAA,CACXV,EAAA,CAAAA,CAAA,CAAgB,GAAhB,CAAsBS,CAAD,CA3sBPE,CA2sBO,CAAsB,CAAtB,CAA0B,CAA/C,CACAX,EAAA,CAAAA,CAAA,CAAgB,GAAhB,CAAsBS,CAAD,CA7sBPG,CA6sBO,CAAsB,CAAtB,CAA0B,CAA/C,CACAZ,EAAA,CAAAA,CAAA,CAAgB,GAAhB,CAAsBS,CAAD,CA/sBPI,CA+sBO,CAAsB,CAAtB,CAA0B,CAA/C,CACAb,EAAA,CAAAA,CAAA,CAAgB,GAAhB,CAAsBS,CAAD,CAjtBPK,CAitBO,CAAsB,CAAtB,CAA0B,CAA/C,CACAd,EAAA,CAAAA,CAAA,CAAgB,GAAhB,CAAsBS,CAAD,CAntBPM,EAmtBO,CAAsB,CAAtB,CAA0B,CAA/C,CACAf,EAAA,CAAAA,CAAA,CAAgB,GAAhB,CAAsBS,CAAD,CArtBPO,EAqtBO,CAAsB,CAAtB,CAA0B,CAA/C,CACAhB,EAAA,CAAAA,CAAA,CAAgB,GAAhB,CAAsBS,CAAD,CAvtBPQ,GAutBO,CAAsB,CAAtB,CAA0B,CAA/C,CACAjB,EAAA,CAAAA,CAAA,CAAgB,GAAhB,CAAqB,CAAAkB,EAArB,CAAgC,CAAhC,CACAlB,EAAA,CAAAA,CAAA,CAAgB,IAAhB,CAAsB,CAAAhC,EAAtB,CAAkC,CAAlC,CACI,EAAAtV,EAAA,MAAJ,EAA8B,CAAAyY,EAA9B,GACI,CAAAzY,EAAA,MAAAkX,UADJ,CACuC,CAAAuB,EAAAC,QAAA,CAAiB,CAAjB,CADvC,CAC6D,KAD7D,CAdJ;AAmDArB,QAAA,GAAU,CAAVA,CAAU,CAACsB,CAAD,CACV,CAII,IAAIC,EAtzBoBC,EAuzBpBD,EAAJ,CAA4B,CAAAnO,GAA5B,GAAyDmO,CAAzD,CAAiF,CAAAnO,GAAjF,CACImO,EAAJ,CAA4B,CAAAlO,GAA5B,GAA0DkO,CAA1D,CAAkF,CAAAlO,GAAlF,CAKA,KAAIoO,EAAc,CACdH,EAAJ,EAAe,CAAAnO,MAAf,CAA4B,CAAAH,GAA5B,EAA+C,CAAAoO,EAA/C,GAAyDK,CAAzD,CAAuE,CAAAL,EAAvE,CACIK,EAAJ,CAAkB,CAAAnO,GAAlB,EAn1BkBJ,CAm1BlB,CAAkC,CAAAC,MAAlC,GAA+DsO,CAA/D,CAA6E,CAAAnO,GAA7E,CAEA,EAAAoO,GAAA,CAAkBhiB,IAAAiiB,MAAA,CAAW,GAAX,CAj0BMH,EAi0BN,CAClB,EAAAI,GAAA,CAAuBliB,IAAAmiB,MAAA,CAp1BCC,GAo1BD,CAAmCP,CAAnC,CAA2DE,CAA3D,CACvB,EAAAM,GAAA,CAAuBriB,IAAAmiB,MAAA,CAr1BCC,GAq1BD,CAn0BCN,EAm0BD,CAA2DC,CAA3D,CACvB,EAAAO,GAAA,CAA6BtiB,IAAAmiB,MAAA,CAt1BLC,GAs1BK,CAAmC,CAAA1O,GAAnC,CAAiEqO,CAAjE,CAC7B,EAAAQ,GAAA,CAA8BviB,IAAAmiB,MAAA,CAv1BNC,GAu1BM,CAAmC,CAAAzO,GAAnC,CAAkEoO,CAAlE,CAKzBH,EAAL,GACI,CAAAY,EAEA,CAFwB,CAAAH,GAExB,CADA,CAAAI,EACA,CAD8B,CAAAH,GAC9B,CAAA,CAAAI,EAAA,CAA+B,CAAAH,GAHnC,CAKA,EAAAI,GAAA,CAAqB,CA7BzB;AAgDAC,QAAA,GAAiB,CAAjBA,CAAiB,CACjB,CACI,IAAIC,EAAY1gB,EAAA,EAAhB,CACI2gB,EAAU,CAAAd,GAEV,EAAAe,EAAJ,GAOID,CAPJ,CAOc9iB,IAAAiiB,MAAA,CAAWa,CAAX,CAAqB,CAAAC,EAArB,CAA2C,CAAAV,GAA3C,CAPd,CAYuBS,EAAnBE,EADmBH,CACnBG,CAD+B,CAAAC,GA9JnC,IAiLgBJ,CAjLhB,EAiL4BK,CAAA7C,GAjL5B,CAuLA8C,CAtLIzB,EACA,CADW1hB,IAAAiiB,MAAA,CA+KD,CAAA7B,EA/KC,EAAmC,GAAnC,CAAuB8C,CAAvB,EACX,CADsD,EACtD,CAAiB,KAAjB,EAAIA,CAAJ,EACIrE,CAAA,CAoLRsE,CApLQ,CAsLe,EAAvB,CAAIH,CAAJ,CAMIA,CANJ,CAMuB,CANvB,CAl6BkBzP,CA26Bd,EAAI,CAAAE,MAAJ,CAYQ,CAAAiO,EAZR,EAYoB,CAAA9N,GAZpB,GAaQoP,CAbR,CAa2B,CAb3B,EA16BcxP,CA06Bd,EAgBI,CAAAC,MAhBJ,GAqBIuP,CArBJ,CAqBuB,CArBvB,CA6BJ,EAAAL,GAAA,EAAsB,CAAAI,EAEtB,OAAOC,EAlFX;AAwFA7U,CAAAwQ,GAAA,CAAAA,QAAG,EACH,CACI,GAAKjP,CAAA,CAAAA,IAAA,CAAa,CAAA,CAAb,CAAL,CAAA,CAKK,IAAAvG,EAAAiK,GAAL,GAOIyL,CAAA,CAAAA,IAAA,CAIA,CAHI,IAAA9U,EAGJ,EAHc,IAAAA,EAAAgH,MAAA,EAGd,CAFA,IAAA5H,EAAAiK,GAEA,CAFqB,CAAA,CAErB,CADI,IAAAnK,EAAA,IACJ,GAD0B,IAAAA,EAAA,IAAAkX,UAC1B,CAD2D,MAC3D,EAAA,IAAAZ,GAAA,EAXJ,CAp9BwB6C,IAy2BxB,EA4HAgB,IA5HIT,GAAJ,EACIrC,EAAA,CA2HJ8C,IA3HI,CAAgB,CAAA,CAAhB,CA2HJA,KAzHAL,EAAA,CAAsB,CAyHtBK,KAxHAH,GAAA,CAAsB9gB,EAAA,EAyHtB,IAAI,CACA,EAAG,CAMC,IAAAkhB,KAAA,CAAU,IAAAnB,GAAV,CAMA,KAAIoB,EAAU,IAAAC,EAAVD,CAA8B,IAAAE,EAClC,KAAApD,EAAA,EAAmBkD,CACnB,KAAAP,EAAA,EAAuBO,CAIvB,KAAAC,EAAA,CAAoB,IAAAC,EAApB,CAAuC,CAEvC,KAAAf,EAAA,EAA+B,IAAAP,GACI,EAAnC,EAAI,IAAAO,EAAJ,GACI,IAAAA,EACA,EAD+B,IAAAH,GAC/B,CAAA,IAAAjD,GAAA,EAFJ,CAKA,KAAAqD,EAAA,EAAgC,IAAAR,GACI,EAApC,EAAI,IAAAQ,EAAJ,GACI,IAAAA,EACA,EADgC,IAAAH,GAChC,CAAA3B,EAAA,CAAAA,IAAA,CAFJ,CAKA,KAAA4B,EAAA,EAAyB,IAAAN,GACzB,IAA6B,CAA7B,EAAI,IAAAM,EAAJ,CAAgC,CAC5B,IAAAA,EAAA,EAAyB,IAAAH,GACzB,MAF4B,CAjCjC,CAAH,MAqCS,IAAAlZ,EAAAiK,GArCT,CADA,CAwCJ,MAAOnN,CAAP,CAAU,CACN,IAAAqY,GAAA,EACA,KAAAkB,OAAA,EACA9P,EAAA,CAAAA,IAAA,CAAa,CAAA,CAAb,CACAL,GAAA,CAAAA,IAAA;AAAcpJ,CAAAwd,MAAd,EAAyBxd,CAAA6B,QAAzB,CACA,OALM,CAOV/B,UAAA,CAAW,QAAQ,CAAC+D,CAAD,CAAM,CAAE,MAAO,SAAQ,EAAG,CAACA,CAAA6U,GAAA,EAAD,CAApB,CAAd,CAAkD,IAAlD,CAAX,CAAoEiE,EAAA,CAAAA,IAAA,CAApE,CAtEA,CAAA,IACI,KAAApD,OAAA,EACA,CAAI,IAAAzV,EAAJ,EAAc,IAAAA,EAAA2Z,KAAA,CAAc,IAAArD,GAAd,CAA+B,IAAAD,EAA/B,CAHtB,CAiFAjS;CAAAkV,KAAA,CAAAA,QAAI,CAACM,CAAD,CACJ,CAWI,IAAIC,EAAa,CAAA,CAiBjB,KAAAC,EAAA,CAAa,IAAAC,EAAb,CAAgC,EACb,KAAA,CAAA,IAAA,CAAA,CAAA,CAAA,EAAA,IAAA,EAAA,CAAsC,CAwmOzD,CAxmOyD,IAAA,EAwmOzD,CAAA,CAAA,CAAgD,CAAhD,CAAuB,CAAAC,GAAApgB,OAAvB,EAA8E,CAA9E,CAAqD,CAAAqgB,GAAArgB,OAArD,EAA6G,CAA7G,CAAmF,CAAAsgB,GAAAtgB,OAjmOnF,KAAA4f,EAAA,CAAoB,IAAAC,EAApB,CAAuCG,CACvC,GAAG,CACKO,CAAAA,CAAU,IAAAzF,EAAA,CAAW,IAAAF,EAAX,CAEV,KAAA,CAAA,IAAA4F,CAAA,CAAAA,CAAA,CAAA,CAAe,CAAA,CAAA,IAAA,EAAA,KAAA,EAAA,CAAA,CA2mOnBC,EAAS,CAAA,CACTC,GAAA,CAAAA,CAAA,CA5mOmB,IAAAC,EA4mOnB,CAA2B,CAAAP,GAA3B,CAA4C,MAA5C,CAAJ,CACIK,CADJ,CACa,CAAA,CADb,EAGI,CAAAG,EAAA,EAGA,CAFA,CAAAC,EAAA,CAAmBN,CAAnB,CAAA,CAA4B,CAA5B,CAAA,EAEA,CADA,CAAAO,GAAA,CAAkB,CAAAC,GAAA,EAAlB,CACA,CADyC,CAAA5a,EAAAyU,EACzC,CAAI,CAAAmG,GAAJ,EAAyB,CAAAD,GAAA9gB,OAAzB,GACI,CAAA+gB,GADJ,CACwB,CADxB,CANJ,CA5mOuB,EAAA,CAAA,CAqnOhB,CAACN,CArnOA,CAAJ,GAAI,CAAJ,CAAoE,CAChER,CAAA,CAAajY,IAAAA,EACb,KAAA2S,GAAA,EACA,MAHgE,CAMpE,IAAAC,EAAA,EACA,KAAA/J,EAAA,CAAkB0P,CAAlB,CAAAjW,KAAA,CAAgC,IAAhC,CA2BA,IAAkB,CAAlB,EAAI,IAAA4V,EAAJ,CAAqB,CAKb,IAAAA,EAAJ,EAAkB,IAAA5P,GAAlB,EAAwC,IAAA4P,EAAxC,EAAsD,IAAA3P,GAAtD,EACIyL,EAAA,CAAAA,IAAA,CAAqB,IAAAkE,EAArB,CAAiC,IAAAtF,EAAjC,CAEA,IAAA4F,CAAA,CAAAA,CAAA,CAAe,CAAA,CAAA,IAAA,EAAA,CAwlOvBC,CAxlOuB,CAwlOd,CAAA,CAxlOc,CA0lOvBC,EAAA,CAAAA,CAAA,CA1lOuB,IAAAC,EA0lOvB,CAA2B,CAAAN,GAA3B,CAA4C,MAA5C,CA1lOuB,GA2lOvBI,CA3lOuB,CA2lOd,CAAA,CA3lOc,EAAA,CAAA,CAAA,CA4lOpB,CAACA,CA5lOA,IAAI,CAAJ,CAA0D,CACtDR,CAAA,CAAa,CAAA,CACb,KAAAtF,GAAA,EACA;KAHsD,CAK1D,IAAAuF,EAAA,CAAc,EAbG,CAArB,IAeK,IAAuB,CAAvB,EAAI,IAAAC,EAAJ,CAA0B,CAUvB,IAAAA,EAAJ,EAAuB,IAAA3P,GAAvB,EAA8C,IAAA2P,EAA9C,EAAiE,IAAA1P,GAAjE,EACI2L,EAAA,CAAAA,IAAA,CAAsB,IAAA+D,EAAtB,CAAuC,IAAAvF,EAAvC,CAEA,IAAA4F,CAAA,CAAAA,CAAA,CAAA,CAAe,CAAA,CAAA,IAAA,EAAA,EAAA,CAAA,IAAA,EAAA,EAAA,CAAA,IAAA,EAAA,CAAA,IAAA,EAAA,CAslO3B,KAAIC,EAAS,CAAA,CAUb,EAAK5Z,CAAL,CAAa,GAAb,GAAsBA,CAAtB,GACI,CAAAmE,EAAA,CAAa,mBAAb,CAAmCgW,CAAA,CAAcL,CAAd,CAAnC,CAAyD,IAAzD,CAAgE9Z,CAAhE,CACA,CAAA4Z,CAAA,CAAS,CAAA,CAFb,CAIIC,GAAA,CAAAA,CAAA,CAAqBC,CAArB,CAA2B,CAAAL,GAA3B,CAA6C,OAA7C,CAAJ,GACIG,CADJ,CACa,CAAA,CADb,CApmO2B,EAAA,CAAA,CAsmOpB,CAACA,CAtmOI,CAAJ,GAAI,CAAJ,CAA6F,CACzFR,CAAA,CAAa,CAAA,CACb,KAAAtF,GAAA,EACA,MAHyF,CAK7F,IAAAwF,EAAA,CAAmB,EAlBQ,CAqB/B,IAAAN,EAAA,EAAoB,IAAAtF,GAAA,CAAmBgG,CAAnB,CAzErB,CAAH,MA2E4B,CA3E5B,CA2ES,IAAAV,EA3ET,CA6EA,OAAOI,EAlHX,CA2HAgB,SAAA,GAAQ,CAARA,CAAQ,CACR,CACI,CAAApC,EAAA,CAAwB,CACxB,EAAAe,EAAA,EAAqB,CAAAC,EACrB,EAAAA,EAAA,CAAmB,CAHvB,CAYArV,CAAAmQ,GAAA,CAAAA,QAAI,EACJ,CACI9O,CAAA,CAAAA,IAAA,CAAY,CAAA,CAAZ,CACA,KAAA+T,EAAA,EAAqB,IAAAC,EACrB,KAAAA,EAAA,CAAmB,CACf,KAAAra,EAAAiK,GAAJ,GACI,IAAAjK,EAAAiK,GACA,CADqB,CAAA,CACrB,CAAI,IAAAnK,EAAA,IAAJ,GAA0B,IAAAA,EAAA,IAAAkX,UAA1B,CAA2D,KAA3D,CAFJ,CAJJ,CAiBAhS;CAAAqR,OAAA,CAAAA,QAAM,EACN,CACI,IAAAH,GAAA,EACAuB,GAAA,CAAAA,IAAA,CAFJ,CAmBAiE,SAAA,GAAS,CAATA,CAAS,CACT,CACI,MAAQ,EAAA1b,EAAAiK,GAAA,CAAoB,CAAAgN,EAApB,CAAsC,CAAAmD,EAAtC,CAA0D,CAAAC,EAA1D,CAA6E,CADzF,CAkBArV,CAAA2W,EAAA,CAAAA,QAAO,CAACR,CAAD,CACP,CAII,MAFQ,KAAA7F,EAAAzd,CAAWsjB,CAAXtjB,CAFZ,CAoCAigB,SAAA,GAAO,CAAPA,CAAO,CACP,CAWI,IAAID,EAAS,CAAA+D,EAAD,CAAc,GAAd,CAAuB,CAAvB,CAA8B,CAC1C/D,EAAA,EAAW,CAAAgE,EAAF,CAAe,GAAf,CAA6B,CAA7B,CAAsB,CAC/BhE,EAAA,EAAS,CAAI,CAAAiE,EAAJ,CAAiB,GAAjB,CAAyB,CAAAC,EAAzB,CAAwC,CAAAD,EAAxC,EAAsD,CAAtD,EAA4D,GAA5D,CAAmE,EAAnE,CAA0E,CACnFjE,EAAA,EAAU,CAAAmE,EAAD,CAAc,GAAd,CAAqB,GAArB,CAA4B,CACrC,OAAQ,EAAAnE,EAAR,CAAoB,EAApB,CAA4BA,CAfhC,CAuGAoE,QAAA,GAAM,CAANA,CAAM,CACN,CACI,CAAApE,EAAA,EAAa,CACb,EAAAxM,EAAA,CAAkB,EAAlB,CAAA,CAA0B,CAAA6Q,GAC1B,EAAA7Q,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAA8Q,GAC1B,EAAA9Q,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAA+Q,GAC1B,EAAA/Q,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAgR,GAC1B,EAAAhR,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAiR,GAC1B,EAAAjR,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAkR,GAC1B,EAAAlR,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAmR,GAC1B,EAAAnR,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAoR,GAC1B,EAAApR,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAqR,GAC1B,EAAArR,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAsR,GAC1B,EAAAtR,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAuR,GAC1B,EAAAvR,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAwR,GAC1B,EAAAxR,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAyR,GAC1B,EAAAzR,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAA0R,GAC1B,EAAA1R,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAA2R,GAC1B,EAAA3R,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAA4R,GAjB9B;AAyBAC,QAAA,GAAQ,CAARA,CAAQ,CACR,CACI,CAAArF,EAAA,EAAa,EACb,EAAAxM,EAAA,CAAkB,EAAlB,CAAA,CAA0B,CAAA0D,GAC1B,EAAA1D,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAA2D,GAC1B,EAAA3D,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAA8D,GAC1B,EAAA9D,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAiE,GAC1B,EAAAjE,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAoE,GAC1B,EAAApE,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAqE,GAC1B,EAAArE,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAwE,GAC1B,EAAAxE,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAyE,GAC1B,EAAAzE,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAwI,GAC1B,EAAAxI,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAA0I,GAC1B,EAAA1I,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAA6I,GAC1B,EAAA7I,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAgJ,GAC1B,EAAAhJ,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAmJ,GAC1B,EAAAnJ,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAoJ,GAC1B,EAAApJ,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAuJ,GAC1B,EAAAvJ,EAAA,CAAkB,GAAlB,CAAA,CAA0B,CAAAwJ,GAjB9B,CA6BAsI,QAAA,EAAM,CAANA,CAAM,CAACC,CAAD,CAAMC,CAAN,CACN,CACI,IAAIC,EAAU,CAAA1B,EAAD,CAAc,GAAd,CAAuB,CAAvB,CAA2B,CAAxC,CAKI2B,GAAKH,CAALG,CAAW,EAAXA,GAAoBF,CAApBE,CAA0B,EAA1BA,EAAkCD,CAO7B,GAAT,EAAIC,CAAJ,GAAeA,CAAf,CAAqBA,CAArB,CAAyB,CAAzB,CAAiC,EAAjC,CAAyC,EAAzC,CAKAA,EAAA,GAAMH,CAAN,CAAY,GAAZ,GAAqBC,CAArB,CAA2B,GAA3B,CAMA,EAAAtB,EAAA,CAAaqB,CAAb,CAAmBC,CAAK,EAAAvB,EAAA,CAAayB,CACrC,EAAAvB,EAAA,CAAcuB,CAAd,CAAkB,GAKT,IAAT,EAAIA,CAAJ,GAAeA,CAAf,EAAoB,EAApB,CAQS,IAAT,EAAIA,CAAJ,GAAgBA,CAAhB,EAAqB,GAArB,CAMA,EAAA3B,EAAA,CAAa2B,CACb,EAAA1B,EAAA,CAAeuB,CAAf,CAAqBC,CAArB,CAA2BC,CAA3B,CAAoC,GAKpC,EAAAjD,EAAA,EAEA,OAAOkD,EAAP,CAAW,GApDf;AAgEAC,QAAA,EAAM,CAANA,CAAM,CAACJ,CAAD,CAAMC,CAAN,CACN,CACI,IAAII,EAAa,CAAA7B,EAAD,CAAc,GAAd,CAAuB,CAAvB,CAA2B,CAA3C,CAKI2B,GAAKH,CAALG,CAAW,EAAXA,GAAoBF,CAApBE,CAA0B,EAA1BA,EAAkCE,CAM9B,EAAR,CAAIF,CAAJ,GAAcA,CAAd,EAAoBA,CAApB,CAAwB,CAAxB,CAAgC,EAAhC,EAAwC,EAAxC,CAKAA,EAAA,GAAMH,CAAN,CAAY,GAAZ,GAAqBC,CAArB,CAA2B,GAA3B,CAKQ,EAAR,CAAIE,CAAJ,GAAcA,CAAd,EAAmB,EAAnB,CAMA,EAAAvB,EAAA,CAAa,CAAAH,EAAb,EAA2B,CAAAD,EAA3B,CAAyCwB,CAAzC,CAA+CC,CAA/C,CAAqDI,CAArD,EAAkE,GAElE,EAAA1B,EAAA,CAAaqB,CAAb,CAAmBC,CAAK,EAAAvB,EAAA,CAAa,CAAAF,EAErC,EAAAA,EAAA,EAAc,GAKd,EAAAvB,EAAA,EAEA,OAAOkD,EAAP,CAAW,GAvCf,CA6CAvT,QAAA,GAAS,CAATA,CAAS,CACT,CACI,CAAA0N,EAAA,CAAY,CACZ,EAAAC,EAAA,CAAY,CACZ,EAAAC,EAAA,CAAY,CACZ,EAAAU,EAAA,CAAY,GACZ,EAAAT,EAAA,CAAY,CACZ,EAAAmE,EAAA,CAAa,CACb,EAAAH,EAAA,CAAa,CACb,EAAAE,EAAA,CAAa,CACb,EAAAD,EAAA,CAAa,CACb,EAAAF,EAAA,CAAa,CACb,EAAAxG,EAAA,CAAa,CACb,EAAAsF,EAAA,CAAc,EACd,EAAAC,EAAA,CAAmB,EACnB,EAAApC,EAAA,CAAW,CACX,EAAAtB,EAAA,CAAkB,CAAAmD,EAAlB,CAAsC,CAAAC,EAAtC,CAAyD,CAf7D;AAqBArV,CAAAsG,GAAA,CAAAA,QAAK,EACL,CAEI,IAAA8J,EAAA,EAEA,KAAAE,EAAA,CAAW,IAAAgD,EAAA,EAAX,CAAA,CAA2B,IAAAlD,EAA3B,EAAyC,CACzC,KAAAkD,EAAA,EAAa,GAEb,KAAAhD,EAAA,CAAW,IAAAgD,EAAA,EAAX,CAAA,CAA2B,IAAAlD,EAA3B,CAAwC,GACxC,KAAAkD,EAAA,EAAa,GAEb,KAAAT,EAAA,EAAa,EAEb,KAAAA,EAAA,CAAYC,EAAA,CAAAA,IAAA,CAEZ,KAAAxC,EAAA,CAAW,IAAAgD,EAAA,EAAX,CAAA,CAA0B,IAAAT,EAC1B,KAAAS,EAAA,EAAa,GAEb,KAAAT,EAAA,EAAa,GAEb,KAAA6C,EAAA,CAAa,KAEb,KAAAtF,EAAA,CAAc,IAAAE,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CArBxE,CA2BA1V,EAAAuG,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAmP,EAAA,CAAe,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAf,CAA2C,IAAAuC,EAA3C,CAAwD,GACxD,KAAA+C,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CAEpE,KAAAsB,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAL5C,CAWA1V,EAAA0G,GAAA,CAAAA,QAAO,EACP,CAEI,IAAAgP,EAAA,CAAa,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAEb,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ5C,CAUA1V;CAAA2G,GAAA,CAAAA,QAAO,EACP,CAEI,IAAAgP,EAAA,CAAkB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAElB,KAAAwG,EAAA,CAAa,IAAAtG,EAAA,CAAW,IAAAqF,EAAX,CAAb,EAA4C,CAE5C,KAAAqB,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAvG,EAAA,CAAW,IAAAqF,EAAX,CAA1B,CAAyD,IAAAiB,EAAzD,CAAsE,GAN1E,CAYA5W,EAAA4G,GAAA,CAAAA,QAAK,EACL,CACI,IAAAiM,EAAA,CAAYC,EAAA,CAAAA,IAAA,CAEZ,KAAAxC,EAAA,CAAW,IAAAgD,EAAA,EAAX,CAAA,CAA0B,IAAAT,EAC1B,KAAAS,EAAA,EAAa,GAJjB,CAUAtT,EAAA6G,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAA6O,EAAA,CAAa,IAAAtF,EAAA,EAEb,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ5C,CAUA1V,EAAA8G,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAA8P,EAAA,CAAa,IAAAlE,EAAb,EAA0B,CAE1B,KAAAsE,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAuC,IAAAkE,EAAvC,CAAoD,GAJxD,CAUA5W,EAAA+G,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAA2O,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAEtE,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ5C,CAUA1V;CAAAgH,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAA2O,EAAA,CAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA+C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA/C,EAA2E,CAE3E,KAAAwG,EAAA,CAAa,IAAAtG,EAAA,CAAW,IAAAqF,EAAX,CAAb,EAA4C,CAE5C,KAAAqB,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAvG,EAAA,CAAW,IAAAqF,EAAX,CAA1B,CAAyD,IAAAiB,EAAzD,CAAsE,GAN1E,CAaA5W,EAAAiH,GAAA,CAAAA,QAAK,EACL,CAEI,IAAAmJ,EAAA,GAAiB,IAAA4G,EAAF,CAAe,GAAf,CAAoF,CAApF,EAAuB,IAAA3B,EAAA,EAAA,CAAqB,IAAA/E,EAAA,CAAW,IAAAF,EAAX,CAArB,EAA+C,EAA/C,EAAsD,EAA7E,CAAf,EAAwG,CAF5G,CAQApQ,EAAAkH,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAwO,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CACd,KAAAsF,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CAApE,EAA0E,IAAA9C,EAE1E,KAAAoE,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAL5C,CAWA1V,EAAAmH,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAuO,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAAuC,IAAAuC,EAAvC,CAAoD,GAEpD,KAAAqE,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ5C,CAUA1V;CAAAoH,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAuO,EAAA,CAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA4C,IAAAuC,EAA5C,CAAyD,GAEzD,KAAAiE,EAAA,CAAa,IAAAtG,EAAA,CAAW,IAAAqF,EAAX,CAAb,EAA4C,CAE5C,KAAAqB,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAvG,EAAA,CAAW,IAAAqF,EAAX,CAA1B,CAAyD,IAAAiB,EAAzD,CAAsE,GAN1E,CAcA5W,EAAAqH,GAAA,CAAAA,QAAK,EACL,CAEI,IAAAuP,EAAA,CAAa,CAFjB,CAQA5W,EAAAsH,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAoO,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAAtE,EAA4E,IAAAwC,EAE5E,KAAAoE,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,EAAuC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ3C,CAUA1V,EAAAuH,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAmO,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAAtE,EAA4E,IAAAuC,EAE5E,KAAAqE,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,EAAuC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ3C,CAUA1V,EAAAwH,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAmO,EAAA,EAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA+C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA/C,EAA2E,CAA3E,EAAiF,IAAAuC,EAEjF,KAAAiE,EAAA,CAAa,IAAAtG,EAAA,CAAW,IAAAqF,EAAX,CAAb,EAA4C,CAE5C,KAAAqB,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAvG,EAAA,CAAW,IAAAqF,EAAX,CAA1B,CAAyD,IAAAiB,EAAzD,CAAsE,GAN1E,CAaA5W;CAAAyH,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAiO,EAAA,CAAa,IAAAtF,EAAA,EAEb,KAAAE,EAAA,CAAW,IAAAgD,EAAA,EAAX,CAAA,CAA2B,IAAAlD,EAA3B,EAAyC,CACzC,KAAAkD,EAAA,EAAa,GAEb,KAAAhD,EAAA,CAAW,IAAAgD,EAAA,EAAX,CAAA,CAA2B,IAAAlD,EAA3B,CAAwC,GACxC,KAAAkD,EAAA,EAAa,GAEb,KAAAlD,EAAA,CAAc,IAAAE,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CAVxE,CAgBA1V,EAAA0H,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAgO,EAAA,CAAe,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAf,CAA2C,IAAAuC,EAA3C,CAAwD,GACxD,KAAA+C,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CAEpE,KAAAsB,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAL5C,CAWA1V,EAAA2H,GAAA,CAAAA,QAAO,EACP,CAEI,IAAA+N,EAAA,CAAa,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAEb,KAAAyG,EAAA,CAAc,IAAAnE,EAAd,CAA0B,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAE1B,KAAAsB,EAAA,CAAe,IAAAA,EAAf,CAA4B,GAA5B,CAAqC,IAAA1G,EAAA,CAAW,IAAAoF,EAAX,CAArC,CAA8D,GAE9D,KAAAoB,EAAA,CAAa,CAAG,KAAAC,EAAA,CAAe,IAAAzG,EAAA,CAAW,IAAAoF,EAAX,CAAD,CAA0B,EAA1B,CAAiC,GAAjC,CAAwC,CAR1E,CAcA1V,EAAA4H,GAAA,CAAAA,QAAO,EACP,CAEI,IAAA8N,EAAA,CAAa,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAEb,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ5C,CAUA1V;CAAA6H,GAAA,CAAAA,QAAO,EACP,CAEI,IAAA8N,EAAA,CAAkB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAElB,KAAAwG,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,CAAsC,IAAAtG,EAAA,CAAW,IAAAqF,EAAX,CAEtC,KAAAiB,EAAA,GAAe,CAEf,KAAAA,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,EAAyC,IAAAA,EAAF,CAAe,GAAf,CAAyB,CAAzB,CAAkC,CAAzE,CAEA,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAvG,EAAA,CAAW,IAAAqF,EAAX,CAA1B,CAAyD,IAAAiB,EAAzD,CAAsE,GAV1E,CAkBA5W,EAAA8H,GAAA,CAAAA,QAAK,EACL,CAEI,IAAAwL,EAAA,CAAc,IAAAA,EAAd,CAAwB,CAAxB,CAA6B,GAA7B,CAAqC,GACrC,KAAAT,EAAA,CAAY,IAAAvC,EAAA,CAAW,IAAAgD,EAAX,CAEZ,KAAAsD,EAAA,CAAe,IAAA/D,EAAD,CAAa,CAAb,CAAoB,GAApB,CAA6B,CAE3C,KAAAgE,EAAA,CAAgB,IAAAhE,EAAF,CAAc,CAAd,CAA4B,CAA5B,CAAqB,CAEnC,KAAAmE,EAAA,CAAc,IAAAnE,EAAd,CAA0B,GAE1B,KAAAiE,EAAA,CAAa,CAAG,KAAAC,EAAA,CAAe,IAAAlE,EAAD,CAAa,EAAb,CAAoB,GAApB,CAA2B,CAX7D,CAiBA7S,EAAA+H,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAA2N,EAAA,CAAa,IAAAtF,EAAA,EAEb,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ5C,CAUA1V;CAAAgI,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAA4O,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,CAAsC,IAAAlE,EAEtC,KAAAkE,EAAA,GAAe,CAEf,KAAAA,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,EAAwC,IAAAA,EAAD,CAAc,GAAd,CAAuB,CAAvB,CAAgC,CAAvE,CAEA,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAuC,IAAAkE,EAAvC,CAAoD,GARxD,CAcA5W,EAAAiI,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAyN,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAEtE,KAAAyG,EAAA,CAAc,IAAAnE,EAAd,CAA0B,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAE1B,KAAAsB,EAAA,CAAe,IAAAA,EAAf,CAA4B,GAA5B,CAAqC,IAAA1G,EAAA,CAAW,IAAAoF,EAAX,CAArC,CAA8D,GAE9D,KAAAoB,EAAA,CAAa,CAAG,KAAAC,EAAA,CAAe,IAAAzG,EAAA,CAAW,IAAAoF,EAAX,CAAD,CAA0B,EAA1B,CAAiC,GAAjC,CAAwC,CAR1E,CAcA1V,EAAAkI,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAwN,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAEtE,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ5C,CAUA1V;CAAAmI,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAwN,EAAA,CAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA+C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA/C,EAA2E,CAE3E,KAAAwG,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,CAAsC,IAAAtG,EAAA,CAAW,IAAAqF,EAAX,CAEtC,KAAAiB,EAAA,GAAe,CAEf,KAAAA,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,EAAyC,IAAAA,EAAF,CAAe,GAAf,CAAyB,CAAzB,CAAkC,CAAzE,CAEA,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAvG,EAAA,CAAW,IAAAqF,EAAX,CAA1B,CAAyD,IAAAiB,EAAzD,CAAsE,GAV1E,CAiBA5W,EAAAoI,GAAA,CAAAA,QAAK,EACL,CAEI,IAAAgI,EAAA,GAAgB,IAAA4G,EAAD,CAAc,GAAd,EAAsB,IAAA3B,EAAA,EAAA,CAAqB,IAAA/E,EAAA,CAAW,IAAAF,EAAX,CAArB,EAA+C,EAA/C,EAAsD,EAA5E,EAAmF,CAAlG,EAAuG,CAF3G,CAQApQ,EAAAqI,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAqN,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CACd,KAAAsF,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CAApE,EAA0E,IAAA9C,EAE1E,KAAAoE,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAL5C,CAWA1V,EAAAsI,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAoN,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAAuC,IAAAuC,EAAvC,CAAoD,GAEpD,KAAAqE,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ5C,CAUA1V;CAAAuI,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAoN,EAAA,CAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA4C,IAAAuC,EAA5C,CAAyD,GAEzD,KAAAiE,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,CAAsC,IAAAtG,EAAA,CAAW,IAAAqF,EAAX,CAEtC,KAAAiB,EAAA,GAAe,CAEf,KAAAA,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,EAAyC,IAAAA,EAAF,CAAe,GAAf,CAAyB,CAAzB,CAAkC,CAAzE,CAEA,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAvG,EAAA,CAAW,IAAAqF,EAAX,CAA1B,CAAyD,IAAAiB,EAAzD,CAAsE,GAV1E,CAkBA5W,EAAAwI,GAAA,CAAAA,QAAK,EACL,CAEI,IAAAoO,EAAA,CAAa,GAFjB,CAQA5W,EAAAyI,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAiN,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAAtE,EAA4E,IAAAwC,EAE5E,KAAAoE,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ5C,CAUA1V,EAAA0I,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAgN,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAAtE,EAA4E,IAAAuC,EAE5E,KAAAqE,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ5C,CAUA1V;CAAA2I,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAgN,EAAA,EAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA+C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA/C,EAA2E,CAA3E,EAAiF,IAAAuC,EAEjF,KAAAiE,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,CAAsC,IAAAtG,EAAA,CAAW,IAAAqF,EAAX,CAEtC,KAAAiB,EAAA,GAAe,CAEf,KAAAA,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,EAAyC,IAAAA,EAAF,CAAe,GAAf,CAAyB,CAAzB,CAAkC,CAAzE,CAEA,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAvG,EAAA,CAAW,IAAAqF,EAAX,CAA1B,CAAyD,IAAAiB,EAAzD,CAAsE,GAV1E,CAiBA5W,EAAA4I,GAAA,CAAAA,QAAK,EACL,CAEI,IAAA0K,EAAA,CAAc,IAAAA,EAAd,CAAwB,CAAxB,CAA6B,GAA7B,CAAqC,GACrC,KAAAT,EAAA,CAAY,IAAAvC,EAAA,CAAW,IAAAgD,EAAX,CAEZ,KAAAsD,EAAA,CAAe,IAAA/D,EAAD,CAAa,CAAb,CAAoB,GAApB,CAA6B,CAE3C,KAAAgE,EAAA,CAAgB,IAAAhE,EAAF,CAAc,CAAd,CAA4B,CAA5B,CAAqB,CAEnC,KAAAmE,EAAA,CAAc,IAAAnE,EAAd,CAA0B,GAE1B,KAAAiE,EAAA,CAAa,CAAG,KAAAC,EAAA,CAAe,IAAAlE,EAAD,CAAa,EAAb,CAAoB,GAApB,CAA2B,CAGzD,KAAAS,EAAA,CAAc,IAAAA,EAAd,CAAwB,CAAxB,CAA6B,GAA7B,CAAqC,GACrC,KAAAlD,EAAA,CAAc,IAAAE,EAAA,CAAY,IAAAgD,EAAZ,CAAsB,CAAtB,CAA2B,GAA3B,CAAd,CAAoD,IAAAhD,EAAA,CAAW,IAAAgD,EAAX,CAApD,EAA6E,CAfjF,CAqBAtT;CAAA6I,GAAA,CAAAA,QAAS,EACT,CAEI,IAAA6M,EAAA,CAAe,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAf,CAA2C,IAAAuC,EAA3C,CAAwD,GACxD,KAAA+C,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CAEpE,KAAAsB,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAL5C,CAWA1V,EAAA8I,GAAA,CAAAA,QAAO,EACP,CAEI,IAAA4M,EAAA,CAAa,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAEb,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ5C,CAUA1V,EAAA+I,GAAA,CAAAA,QAAO,EACP,CAEI,IAAA4M,EAAA,CAAkB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAElB,KAAAwG,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,EAAwC,IAAAtG,EAAA,CAAW,IAAAqF,EAAX,CAAD,CAA+B,CAA/B,CAAsC,GAAtC,CAA+C,CAAtF,CAEA,KAAArF,EAAA,CAAW,IAAAqF,EAAX,CAAA,EAAgC,IAAAiB,EAAhC,CAA+C,IAAAA,EAA/C,CAA4D,KAA5D,CAAuE,IAAAtG,EAAA,CAAW,IAAAqF,EAAX,CAAvE,EAAsG,CAAtG,EAA6G,GAE7G,KAAAqB,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAD,EAA3B,CAAwC,GAR5C,CAgBA5W,EAAAgJ,GAAA,CAAAA,QAAK,EACL,CAEI,IAAAsH,EAAA,CAAW,IAAAgD,EAAA,EAAX,CAAA,CAA0B,IAAAZ,EAC1B,KAAAY,EAAA,EAAa,GAHjB,CASAtT,EAAAiJ,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAyM,EAAA,CAAa,IAAAtF,EAAA,EAEb,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ5C,CAUA1V;CAAAkJ,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAA0N,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,EAAwC,IAAAlE,EAAD,CAAa,CAAb,CAAoB,GAApB,CAA6B,CAApE,CAEA,KAAAA,EAAA,EAAc,IAAAkE,EAAd,CAA6B,IAAAA,EAA7B,CAA0C,KAA1C,CAAqD,IAAAlE,EAArD,EAAkE,CAAlE,EAAyE,GAEzE,KAAAsE,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAD,EAA3B,CAAwC,GAN5C,CAYA5W,EAAAmJ,GAAA,CAAAA,QAAU,EACV,CAEI,IAAAuM,EAAA,CAAa,IAAAtF,EAIb,KAAAA,EAAA,CAAc,IAAAE,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CANxE,CAYA1V,EAAAoJ,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAsM,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAEtE,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ5C,CAUA1V,EAAAqJ,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAsM,EAAA,CAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA+C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA/C,EAA2E,CAE3E,KAAAwG,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,EAAwC,IAAAtG,EAAA,CAAW,IAAAqF,EAAX,CAAD,CAA+B,CAA/B,CAAsC,GAAtC,CAA+C,CAAtF,CAEA,KAAArF,EAAA,CAAW,IAAAqF,EAAX,CAAA,EAAgC,IAAAiB,EAAhC,CAA+C,IAAAA,EAA/C,CAA4D,KAA5D,CAAuE,IAAAtG,EAAA,CAAW,IAAAqF,EAAX,CAAvE,EAAsG,CAAtG,EAA6G,GAE7G,KAAAqB,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAD,EAA3B,CAAwC,GAR5C,CAeA5W;CAAAsJ,GAAA,CAAAA,QAAK,EACL,CAEI,IAAA8G,EAAA,GAAe,CAAK,IAAA0G,EAAL,CAAkB,GAAlB,CAA0B,IAAAC,EAA1B,CAAyC,IAAAD,EAAzC,EAAuD,CAAvD,EAA6D,GAA7D,CAAkI,CAAlI,EAAqE,IAAAzB,EAAA,EAAA,CAAqB,IAAA/E,EAAA,CAAW,IAAAF,EAAX,CAArB,EAA+C,EAA/C,EAAsD,EAA3H,CAAf,EAAsJ,CAF1J,CAQApQ,EAAAuJ,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAmM,EAAA,CAAa,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CACb,KAAAsF,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CAApE,EAA0E,IAAA9C,EAE1E,KAAAoE,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAL5C,CAWA1V,EAAAwJ,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAkM,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAAuC,IAAAuC,EAAvC,CAAoD,GAEpD,KAAAqE,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ5C,CAUA1V,EAAAyJ,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAkM,EAAA,CAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA4C,IAAAuC,EAA5C,CAAyD,GAEzD,KAAAiE,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,EAAwC,IAAAtG,EAAA,CAAW,IAAAqF,EAAX,CAAD,CAA+B,CAA/B,CAAsC,GAAtC,CAA+C,CAAtF,CAEA,KAAArF,EAAA,CAAW,IAAAqF,EAAX,CAAA,EAAgC,IAAAiB,EAAhC,CAA+C,IAAAA,EAA/C,CAA4D,KAA5D,CAAuE,IAAAtG,EAAA,CAAW,IAAAqF,EAAX,CAAvE,EAAsG,CAAtG,EAA6G,GAE7G,KAAAqB,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAD,EAA3B,CAAwC,GAR5C,CAgBA5W;CAAA0J,GAAA,CAAAA,QAAK,EACL,CAEI,IAAAmJ,EAAA,EAAa,GAFjB,CAQA7S,EAAA2J,GAAA,CAAAA,QAAS,EACT,CAEI,IAAA+L,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAAtE,EAA4E,IAAAwC,EAE5E,KAAAoE,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ5C,CAUA1V,EAAA4J,GAAA,CAAAA,QAAS,EACT,CAEI,IAAA8L,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAAtE,EAA4E,IAAAuC,EAE5E,KAAAqE,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAnE,EAA3B,EAAwC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ5C,CAUA1V,EAAA6J,GAAA,CAAAA,QAAS,EACT,CAEI,IAAA8L,EAAA,EAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA+C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA/C,EAA2E,CAA3E,EAAiF,IAAAuC,EAEjF,KAAAiE,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,EAAwC,IAAAtG,EAAA,CAAW,IAAAqF,EAAX,CAAD,CAA+B,CAA/B,CAAsC,GAAtC,CAA+C,CAAtF,CAEA,KAAArF,EAAA,CAAW,IAAAqF,EAAX,CAAA,EAAgC,IAAAiB,EAAhC,CAA+C,IAAAA,EAA/C,CAA4D,KAA5D,CAAuE,IAAAtG,EAAA,CAAW,IAAAqF,EAAX,CAAvE,EAAsG,CAAtG,EAA6G,GAE7G,KAAAqB,EAAA,CAAa,IAAAH,EAAb,CAA2B,IAAAD,EAA3B,CAAwC,GAR5C,CAeA5W;CAAA8J,GAAA,CAAAA,QAAK,EACL,CAII,IAAAwJ,EAAA,CAAc,IAAAA,EAAd,CAAwB,CAAxB,CAA6B,GAA7B,CAAqC,GACrC,KAAAlD,EAAA,EAAgB,IAAAE,EAAA,CAAY,IAAAgD,EAAZ,CAAsB,CAAtB,CAA2B,GAA3B,CAAhB,CAAwD,IAAAhD,EAAA,CAAW,IAAAgD,EAAX,CAAxD,EAAkF,CAAlF,EAAwF,CAL5F,CAWAtT,EAAA+J,GAAA,CAAAA,QAAS,EACT,CAEI,IAAA2L,EAAA,CAAe,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAf,CAA2C,IAAAuC,EAA3C,CAAwD,GACxD,KAAA+C,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CAEpE,KAAAkB,EAAA,CAAc,IAAAlE,EAAd,CAA0B,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAA1B,EAAqD,IAAAkB,EAAD,CAAc,GAAd,CAAuB,CAAvB,CAA2B,CAA/E,CAEA,KAAAG,EAAA,CAAa,IAAArE,EAAb,CAAyB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAwB,KAAAoB,EAAA,CAAa,IAAAF,EAE9D,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAuC,IAAAkE,EAAvC,CAAoD,GATxD,CAeA5W,EAAAkX,GAAA,CAAAA,QAAY,EACZ,CAEI,IAAAxB,EAAA,CAAe,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAf,CAA2C,IAAAuC,EAA3C,CAAwD,GACxD,KAAA+C,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CAEpE,KAAAhD,EAAA,CAAYyF,CAAA,CAAAA,IAAA,CAAY,IAAAzF,EAAZ,CAAuB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAvB,CALhB,CAWA1V;CAAAgK,GAAA,CAAAA,QAAO,EACP,CAEI,IAAA0L,EAAA,CAAa,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAEb,KAAAwG,EAAA,CAAc,IAAAlE,EAAd,CAA0B,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAA1B,EAAqD,IAAAkB,EAAD,CAAc,GAAd,CAAuB,CAAvB,CAA2B,CAA/E,CAEA,KAAAG,EAAA,CAAa,IAAArE,EAAb,CAAyB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAwB,KAAAoB,EAAA,CAAa,IAAAF,EAE9D,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAuC,IAAAkE,EAAvC,CAAoD,GARxD,CAcA5W,EAAAmX,GAAA,CAAAA,QAAU,EACV,CAEI,IAAAzB,EAAA,CAAa,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAEb,KAAAsC,EAAA,CAAYyF,CAAA,CAAAA,IAAA,CAAY,IAAAzF,EAAZ,CAAuB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAvB,CAJhB,CAUA1V,EAAAiK,GAAA,CAAAA,QAAO,EACP,CAEI,IAAA0L,EAAA,CAAkB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAElB,KAAAwG,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,CAAsC,IAAAtG,EAAA,CAAW,IAAAqF,EAAX,CAEtC,KAAAiB,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,EAAwC,IAAAA,EAAD,CAAc,CAAd,CAAuB,GAAvB,CAAgC,CAAvE,CAEA,KAAAA,EAAA,GAAe,CAEf,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAvG,EAAA,CAAW,IAAAqF,EAAX,CAA1B,CAAyD,IAAAiB,EAAzD,CAAsE,GAV1E,CAkBA5W,EAAAkK,GAAA,CAAAA,QAAK,EACL,CAEI,IAAAoJ,EAAA,CAAc,IAAAA,EAAd,CAAwB,CAAxB,CAA6B,GAA7B,CAAqC,GACrC,KAAA0D,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAsC,IAAApC,EAAA,CAAW,IAAAgD,EAAX,CAH1C,CASAtT;CAAAmK,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAuL,EAAA,CAAa,IAAAtF,EAAA,EAEb,KAAAwG,EAAA,CAAc,IAAAlE,EAAd,CAA0B,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAA1B,EAAqD,IAAAkB,EAAD,CAAc,GAAd,CAAuB,CAAvB,CAA2B,CAA/E,CAEA,KAAAG,EAAA,CAAa,IAAArE,EAAb,CAAyB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAwB,KAAAoB,EAAA,CAAa,IAAAF,EAE9D,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAuC,IAAAkE,EAAvC,CAAoD,GARxD,CAcA5W,EAAAoX,GAAA,CAAAA,QAAW,EACX,CAEI,IAAA1B,EAAA,CAAa,IAAAtF,EAAA,EAEb,KAAAsC,EAAA,CAAYyF,CAAA,CAAAA,IAAA,CAAY,IAAAzF,EAAZ,CAAuB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAvB,CAJhB,CAUA1V,EAAAoK,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAwM,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,CAAsC,IAAAlE,EAEtC,KAAAkE,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,EAAwC,IAAAA,EAAD,CAAc,CAAd,CAAuB,GAAvB,CAAgC,CAAvE,CAEA,KAAAA,EAAA,GAAe,CAEf,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAuC,IAAAkE,EAAvC,CAAoD,GARxD,CAkBA5W,EAAAqK,GAAA,CAAAA,QAAU,EACV,CAEI,IAAAqL,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAEtE,KAAAA,EAAA,CAAc,IAAAE,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CAJxE,CAUA1V;CAAAsK,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAoL,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAEtE,KAAAwG,EAAA,CAAa,IAAAlE,EAAb,CAAyB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAzB,EAAoD,IAAAkB,EAAD,CAAc,GAAd,CAAuB,CAAvB,CAA2B,CAA9E,CAEA,KAAAG,EAAA,CAAa,IAAArE,EAAb,CAAyB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAwB,KAAAoB,EAAA,CAAa,IAAAF,EAE9D,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAuC,IAAAkE,EAAvC,CAAoD,GARxD,CAcA5W,EAAAqX,GAAA,CAAAA,QAAW,EACX,CAEI,IAAA3B,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAEtE,KAAAsC,EAAA,CAAYyF,CAAA,CAAAA,IAAA,CAAY,IAAAzF,EAAZ,CAAuB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAvB,CAJhB,CAUA1V,EAAAuK,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAoL,EAAA,CAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA+C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA/C,EAA2E,CAE3E,KAAAwG,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,CAAsC,IAAAtG,EAAA,CAAW,IAAAqF,EAAX,CAEtC,KAAAiB,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,EAAwC,IAAAA,EAAD,CAAc,CAAd,CAAuB,GAAvB,CAAgC,CAAvE,CAEA,KAAAA,EAAA,GAAe,CAEf,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAvG,EAAA,CAAW,IAAAqF,EAAX,CAA1B,CAAyD,IAAAiB,EAAzD,CAAsE,GAV1E,CAiBA5W;CAAAwK,GAAA,CAAAA,QAAK,EACL,CAEI,IAAA4F,EAAA,GAAe,CAAI,IAAA0G,EAAJ,CAAiB,GAAjB,CAAyB,IAAAC,EAAzB,CAAwC,IAAAD,EAAxC,EAAsD,CAAtD,EAA4D,GAA5D,EAAoE,IAAAzB,EAAA,EAAA,CAAqB,IAAA/E,EAAA,CAAW,IAAAF,EAAX,CAArB,EAA+C,EAA/C,EAAsD,EAA1H,EAAiI,CAAhJ,EAAqJ,CAFzJ,CAQApQ,EAAAyK,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAiL,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CACd,KAAAsF,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CAApE,EAA0E,IAAA9C,EAE1E,KAAAgE,EAAA,CAAc,IAAAlE,EAAd,CAA0B,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAA1B,EAAqD,IAAAkB,EAAD,CAAc,GAAd,CAAuB,CAAvB,CAA2B,CAA/E,CAEA,KAAAG,EAAA,CAAa,IAAArE,EAAb,CAAyB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAwB,KAAAoB,EAAA,CAAa,IAAAF,EAE9D,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAuC,IAAAkE,EAAvC,CAAoD,GATxD,CAeA5W,EAAAsX,GAAA,CAAAA,QAAY,EACZ,CAEI,IAAA5B,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CACd,KAAAsF,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CAApE,EAA0E,IAAA9C,EAE1E,KAAAF,EAAA,CAAYyF,CAAA,CAAAA,IAAA,CAAY,IAAAzF,EAAZ,CAAuB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAvB,CALhB,CAWA1V;CAAA0K,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAgL,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAAuC,IAAAuC,EAAvC,CAAoD,GAEpD,KAAAiE,EAAA,CAAc,IAAAlE,EAAd,CAA0B,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAA1B,EAAqD,IAAAkB,EAAD,CAAc,GAAd,CAAuB,CAAvB,CAA2B,CAA/E,CAEA,KAAAG,EAAA,CAAa,IAAArE,EAAb,CAAyB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAwB,KAAAoB,EAAA,CAAa,IAAAF,EAE9D,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAuC,IAAAkE,EAAvC,CAAoD,GARxD,CAcA5W,EAAAuX,GAAA,CAAAA,QAAW,EACX,CAEI,IAAA7B,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAAuC,IAAAuC,EAAvC,CAAoD,GAEpD,KAAAD,EAAA,CAAYyF,CAAA,CAAAA,IAAA,CAAY,IAAAzF,EAAZ,CAAuB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAvB,CAJhB,CAUA1V,EAAA2K,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAgL,EAAA,CAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA4C,IAAAuC,EAA5C,CAAyD,GAEzD,KAAAiE,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,CAAsC,IAAAtG,EAAA,CAAW,IAAAqF,EAAX,CAEtC,KAAAiB,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,EAAwC,IAAAA,EAAD,CAAc,CAAd,CAAuB,GAAvB,CAAgC,CAAvE,CAEA,KAAAA,EAAA,GAAe,CAEf,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAvG,EAAA,CAAW,IAAAqF,EAAX,CAA1B,CAAyD,IAAAiB,EAAzD,CAAsE,GAV1E,CAkBA5W,EAAA4K,GAAA,CAAAA,QAAK,EACL,CAEI,IAAAiI,EAAA,EAAa,CAFjB,CAQA7S;CAAA6K,GAAA,CAAAA,QAAS,EACT,CAEI,IAAA6K,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAAtE,EAA4E,IAAAwC,EAE5E,KAAAgE,EAAA,CAAc,IAAAlE,EAAd,CAA0B,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAA1B,EAAqD,IAAAkB,EAAD,CAAc,GAAd,CAAuB,CAAvB,CAA2B,CAA/E,CAEA,KAAAG,EAAA,CAAa,IAAArE,EAAb,CAAyB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAwB,KAAAoB,EAAA,CAAa,IAAAF,EAE9D,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAuC,IAAAkE,EAAvC,CAAoD,GARxD,CAcA5W,EAAAwX,GAAA,CAAAA,QAAY,EACZ,CAEI,IAAA9B,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAAtE,EAA4E,IAAAwC,EAE5E,KAAAF,EAAA,CAAYyF,CAAA,CAAAA,IAAA,CAAY,IAAAzF,EAAZ,CAAuB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAvB,CAJhB,CAUA1V,EAAA8K,GAAA,CAAAA,QAAS,EACT,CAEI,IAAA4K,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAAtE,EAA4E,IAAAuC,EAE5E,KAAAiE,EAAA,CAAc,IAAAlE,EAAd,CAA0B,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAA1B,EAAqD,IAAAkB,EAAD,CAAc,GAAd,CAAuB,CAAvB,CAA2B,CAA/E,CAEA,KAAAG,EAAA,CAAa,IAAArE,EAAb,CAAyB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAwB,KAAAoB,EAAA,CAAa,IAAAF,EAE9D,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAuC,IAAAkE,EAAvC,CAAoD,GARxD,CAcA5W;CAAAyX,GAAA,CAAAA,QAAY,EACZ,CAEI,IAAA/B,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAAtE,EAA4E,IAAAuC,EAE5E,KAAAD,EAAA,CAAYyF,CAAA,CAAAA,IAAA,CAAY,IAAAzF,EAAZ,CAAuB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAvB,CAJhB,CAUA1V,EAAA+K,GAAA,CAAAA,QAAS,EACT,CAEI,IAAA4K,EAAA,EAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA+C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA/C,EAA2E,CAA3E,EAAiF,IAAAuC,EAEjF,KAAAiE,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,CAAsC,IAAAtG,EAAA,CAAW,IAAAqF,EAAX,CAEtC,KAAAiB,EAAA,CAAe,IAAAA,EAAf,CAA4B,KAA5B,EAAwC,IAAAA,EAAD,CAAc,CAAd,CAAuB,GAAvB,CAAgC,CAAvE,CAEA,KAAAA,EAAA,GAAe,CAEf,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAvG,EAAA,CAAW,IAAAqF,EAAX,CAA1B,CAAyD,IAAAiB,EAAzD,CAAsE,GAV1E,CAiBA5W,EAAAgL,GAAA,CAAAA,QAAS,EACT,CAEI,IAAA2K,EAAA,CAAoB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAApB,CAAgD,IAAAuC,EAAhD,CAA6D,GAC7D,KAAAgD,EAAA,CAAmB,IAAArF,EAAA,CAAW,IAAAqF,EAAX,CAAnB,CAAkD,IAAArF,EAAA,CAAW,IAAAqF,EAAX,CAA2B,CAA3B,CAAlD,EAAmF,CAEnF,KAAArF,EAAA,CAAW,IAAAqF,EAAX,CAAA,CAA8B,IAAAjD,EALlC,CAYA1S,EAAAiL,GAAA,CAAAA,QAAO,EACP,CAEI,IAAA0K,EAAA,CAAkB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAElB,KAAAE,EAAA,CAAW,IAAAqF,EAAX,CAAA,CAA8B,IAAA/C,EAJlC,CAYA5S;CAAAkL,GAAA,CAAAA,QAAO,EACP,CAEI,IAAAyK,EAAA,CAAkB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAElB,KAAAE,EAAA,CAAW,IAAAqF,EAAX,CAAA,CAA8B,IAAAjD,EAJlC,CAYA1S,EAAAmL,GAAA,CAAAA,QAAO,EACP,CAEI,IAAAwK,EAAA,CAAkB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAElB,KAAAE,EAAA,CAAW,IAAAqF,EAAX,CAAA,CAA8B,IAAAhD,EAJlC,CAYA3S,EAAAoL,GAAA,CAAAA,QAAK,EACL,CAII,IAAA4L,EAAA,CAAa,IAAAH,EAAb,CAFA,IAAAjE,EAEA,CAFc,IAAAA,EAEd,CAF0B,CAE1B,CAF+B,GAFnC,CAUA5S,EAAAqL,GAAA,CAAAA,QAAK,EACL,CAEI,IAAA2L,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAsC,IAAAC,EAF1C,CAQA3S,EAAAsL,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAqK,EAAA,CAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA+C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA/C,EAA2E,CAE3E,KAAAE,EAAA,CAAW,IAAAqF,EAAX,CAAA,CAA8B,IAAA/C,EAJlC,CAWA5S,EAAAuL,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAoK,EAAA,CAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA+C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA/C,EAA2E,CAE3E,KAAAE,EAAA,CAAW,IAAAqF,EAAX,CAAA,CAA8B,IAAAjD,EAJlC,CAWA1S,EAAAwL,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAmK,EAAA,CAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA+C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA/C,EAA2E,CAE3E,KAAAE,EAAA,CAAW,IAAAqF,EAAX,CAAA,CAA8B,IAAAhD,EAJlC,CAWA3S;CAAAyL,GAAA,CAAAA,QAAK,EACL,CAEI,IAAA2E,EAAA,GAAiB,IAAAwG,EAAF,CAAe,GAAf,CAAsF,CAAtF,EAAyB,IAAAvB,EAAA,EAAA,CAAqB,IAAA/E,EAAA,CAAW,IAAAF,EAAX,CAArB,EAA+C,EAA/C,EAAsD,EAA/E,CAAf,EAA0G,CAF9G,CAQApQ,EAAA0L,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAiK,EAAA,CAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CACnB,KAAAuF,EAAA,EAAmB,IAAArF,EAAA,CAAW,IAAAqF,EAAX,CAAnB,CAAkD,IAAArF,EAAA,CAAW,IAAAqF,EAAX,CAA2B,CAA3B,CAAlD,EAAmF,CAAnF,EAAyF,IAAA/C,EAEzF,KAAAtC,EAAA,CAAW,IAAAqF,EAAX,CAAA,CAA8B,IAAAjD,EALlC,CAYA1S,EAAA2L,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAgK,EAAA,CAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA4C,IAAAuC,EAA5C,CAAyD,GAEzD,KAAArC,EAAA,CAAW,IAAAqF,EAAX,CAAA,CAA8B,IAAA/C,EAJlC,CAYA5S,EAAA4L,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAA+J,EAAA,CAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA4C,IAAAuC,EAA5C,CAAyD,GAEzD,KAAArC,EAAA,CAAW,IAAAqF,EAAX,CAAA,CAA8B,IAAAjD,EAJlC,CAYA1S,EAAA6L,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAA8J,EAAA,CAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA4C,IAAAwC,EAA5C,CAAyD,GAEzD,KAAAtC,EAAA,CAAW,IAAAqF,EAAX,CAAA,CAA8B,IAAAhD,EAJlC,CAYA3S,EAAA8L,GAAA,CAAAA,QAAK,EACL,CAEI,IAAAkL,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAsC,IAAAE,EAF1C,CAQA5S;CAAA+L,GAAA,CAAAA,QAAS,EACT,CAEI,IAAA4J,EAAA,EAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA+C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA/C,EAA2E,CAA3E,EAAiF,IAAAwC,EAEjF,KAAAtC,EAAA,CAAW,IAAAqF,EAAX,CAAA,CAA8B,IAAAjD,EAJlC,CAWA1S,EAAAgM,GAAA,CAAAA,QAAK,EACL,CAEI,IAAAsH,EAAA,CAAY,IAAAX,EAAZ,CAAwB,GAF5B,CAQA3S,EAAAiM,GAAA,CAAAA,QAAS,EACT,CAEI,IAAA0J,EAAA,EAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA+C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA/C,EAA2E,CAA3E,EAAiF,IAAAuC,EAEjF,KAAArC,EAAA,CAAW,IAAAqF,EAAX,CAAA,CAA8B,IAAAjD,EAJlC,CAWA1S,EAAAkM,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAwJ,EAAA,CAAa,IAAAtF,EAAA,EAEb,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAjE,EAA1B,CAAsC,IAAAtC,EAAA,CAAW,IAAAoF,EAAX,CAJ1C,CAUA1V,EAAAmM,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAuJ,EAAA,CAAe,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAf,CAA2C,IAAAuC,EAA3C,CAAwD,GACxD,KAAA+C,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CAEpE,KAAAsB,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAsC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAL1C,CAWA1V,EAAAoM,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAsJ,EAAA,CAAa,IAAAtF,EAAA,EAEb,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAlE,EAA1B,CAAsC,IAAArC,EAAA,CAAW,IAAAoF,EAAX,CAJ1C,CAUA1V;CAAAqM,GAAA,CAAAA,QAAO,EACP,CAEI,IAAAqJ,EAAA,CAAa,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAEb,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAjE,EAA1B,CAAsC,IAAAtC,EAAA,CAAW,IAAAoF,EAAX,CAJ1C,CAUA1V,EAAAsM,GAAA,CAAAA,QAAO,EACP,CAEI,IAAAoJ,EAAA,CAAa,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAEb,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAsC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ1C,CAUA1V,EAAAuM,GAAA,CAAAA,QAAO,EACP,CAEI,IAAAmJ,EAAA,CAAa,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAEb,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAlE,EAA1B,CAAsC,IAAArC,EAAA,CAAW,IAAAoF,EAAX,CAJ1C,CAUA1V,EAAAwM,GAAA,CAAAA,QAAK,EACL,CAEI,IAAAwK,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAjE,EAA1B,CAAsC,IAAAF,EAF1C,CAQA1S,EAAAyM,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAiJ,EAAA,CAAa,IAAAtF,EAAA,EAEb,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAsC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ1C,CAUA1V,EAAA0M,GAAA,CAAAA,QAAK,EACL,CAEI,IAAAsK,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAlE,EAA1B,CAAsC,IAAAD,EAF1C,CAQA1S,EAAA2M,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAA+I,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAEtE,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAjE,EAA1B,CAAsC,IAAAtC,EAAA,CAAW,IAAAoF,EAAX,CAJ1C,CAUA1V;CAAA4M,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAA8I,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAEtE,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAsC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ1C,CAUA1V,EAAA6M,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAA6I,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAEtE,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAlE,EAA1B,CAAsC,IAAArC,EAAA,CAAW,IAAAoF,EAAX,CAJ1C,CAUA1V,EAAA8M,GAAA,CAAAA,QAAK,EACL,CAEI,IAAAsD,EAAA,GAAgB,IAAAwG,EAAD,CAAc,GAAd,EAAwB,IAAAvB,EAAA,EAAA,CAAqB,IAAA/E,EAAA,CAAW,IAAAF,EAAX,CAArB,EAA+C,EAA/C,EAAsD,EAA9E,EAAqF,CAApG,EAAyG,CAF7G,CAQApQ,EAAA+M,GAAA,CAAAA,QAAS,EACT,CAEI,IAAA2I,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CACd,KAAAsF,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CAApE,EAA0E,IAAA9C,EAE1E,KAAAoE,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAsC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAL1C,CAWA1V,EAAAgN,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAA0I,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAAuC,IAAAuC,EAAvC,CAAoD,GAEpD,KAAAqE,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAjE,EAA1B,CAAsC,IAAAtC,EAAA,CAAW,IAAAoF,EAAX,CAJ1C,CAUA1V;CAAAiN,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAyI,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAAuC,IAAAuC,EAAvC,CAAoD,GAEpD,KAAAqE,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAsC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ1C,CAUA1V,EAAAkN,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAwI,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAAuC,IAAAwC,EAAvC,CAAoD,GAEpD,KAAAoE,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAlE,EAA1B,CAAsC,IAAArC,EAAA,CAAW,IAAAoF,EAAX,CAJ1C,CAUA1V,EAAAmN,GAAA,CAAAA,QAAK,EACL,CAEoB,IAAA4J,EAAA,CAAhB,IAAAD,EAAgB,CAAH,CAFjB,CAQA9W,EAAAoN,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAsI,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAAtE,EAA4E,IAAAwC,EAE5E,KAAAoE,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAsC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ1C,CAUA1V,EAAAqN,GAAA,CAAAA,QAAK,EACL,CAEI,IAAA2J,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAlE,EAA1B,CAAsC,IAAAW,EAAtC,CAAkD,GAFtD,CAQAtT,EAAAsN,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAoI,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAAtE,EAA4E,IAAAuC,EAE5E,KAAAqE,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAjE,EAA1B,CAAsC,IAAAtC,EAAA,CAAW,IAAAoF,EAAX,CAJ1C,CAUA1V;CAAAuN,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAmI,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAAtE,EAA4E,IAAAuC,EAE5E,KAAAqE,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAsC,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAJ1C,CAUA1V,EAAAwN,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAkI,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAAtE,EAA4E,IAAAwC,EAE5E,KAAAoE,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAlE,EAA1B,CAAsC,IAAArC,EAAA,CAAW,IAAAoF,EAAX,CAJ1C,CAUA1V,EAAAyN,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAiI,EAAA,CAAa,IAAAtF,EAAA,EAIb,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAFA,IAAAD,EAEA,CAFa,IAAAhE,EAEb,CAFyB,IAAAtC,EAAA,CAAW,IAAAoF,EAAX,CAIzB,KAAAkB,EAAA,EAAc,GARlB,CAcA5W,EAAA0N,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAgI,EAAA,CAAe,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAf,CAA2C,IAAAuC,EAA3C,CAAwD,GACxD,KAAA+C,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CAEpE,KAAAsB,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAD,EAA1B,CAAwC,IAAAlE,EAAxC,CAAoD,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAEpD,KAAAkB,EAAA,EAAc,GAPlB,CAaA5W;CAAA2N,GAAA,CAAAA,QAAO,EACP,CAEI,IAAA+H,EAAA,CAAa,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAIb,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAFA,IAAAD,EAEA,CAFa,IAAAhE,EAEb,CAFyB,IAAAtC,EAAA,CAAW,IAAAoF,EAAX,CAIzB,KAAAkB,EAAA,EAAc,GARlB,CAcA5W,EAAA4N,GAAA,CAAAA,QAAO,EACP,CAEI,IAAA8H,EAAA,CAAa,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAEb,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAD,EAA1B,CAAwC,IAAAlE,EAAxC,CAAoD,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAEpD,KAAAkB,EAAA,EAAc,GANlB,CAYA5W,EAAA6N,GAAA,CAAAA,QAAO,EACP,CAEI,IAAA8H,EAAA,CAAkB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAElB,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAvG,EAAA,CAAW,IAAAqF,EAAX,CAA1B,CAA0D,IAAArF,EAAA,CAAW,IAAAqF,EAAX,CAA1D,CAAwF,CAAxF,CAA6F,GAJjG,CAYA3V,EAAA8N,GAAA,CAAAA,QAAK,EACL,CAII,IAAAkJ,EAAA,CAAa,IAAAH,EAAb,CAFA,IAAAjE,EAEA,CAFc,IAAAA,EAEd,CAF0B,CAE1B,CAF+B,GAFnC,CAUA5S,EAAA+N,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAA2H,EAAA,CAAa,IAAAtF,EAAA,EAEb,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAD,EAA1B,CAAwC,IAAAlE,EAAxC,CAAoD,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAEpD,KAAAkB,EAAA,EAAc,GANlB,CAYA5W,EAAAgO,GAAA,CAAAA,QAAK,EACL,CAEI,IAAAgJ,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAlE,EAA1B,CAAwC,IAAAA,EAAxC,CAAoD,CAApD,CAAyD,GAF7D,CAQA3S;CAAAiO,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAyH,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAEtE,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAD,EAA1B,CAAuC,IAAAhE,EAAvC,CAAmD,IAAAtC,EAAA,CAAW,IAAAoF,EAAX,CAEnD,KAAAkB,EAAA,EAAc,GANlB,CAYA5W,EAAAkO,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAwH,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAEtE,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAD,EAA1B,CAAwC,IAAAlE,EAAxC,CAAoD,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAEpD,KAAAkB,EAAA,EAAc,GANlB,CAYA5W,EAAAmO,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAwH,EAAA,CAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA+C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA/C,EAA2E,CAE3E,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAvG,EAAA,CAAW,IAAAqF,EAAX,CAA1B,CAA0D,IAAArF,EAAA,CAAW,IAAAqF,EAAX,CAA1D,CAAwF,CAAxF,CAA6F,GAJjG,CAWA3V,EAAAoO,GAAA,CAAAA,QAAK,EACL,CAEI,IAAAgC,EAAA,GAAgB,IAAAyG,EAAD,CAAc,GAAd,EAAsB,IAAAxB,EAAA,EAAA,CAAqB,IAAA/E,EAAA,CAAW,IAAAF,EAAX,CAArB,EAA+C,EAA/C,EAAsD,EAA5E,EAAmF,CAAlG,EAAuG,CAF3G,CAQApQ;CAAAqO,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAqH,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CACd,KAAAsF,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CAApE,EAA0E,IAAA9C,EAE1E,KAAAoE,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAD,EAA1B,CAAwC,IAAAlE,EAAxC,CAAoD,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAEpD,KAAAkB,EAAA,EAAc,GAPlB,CAaA5W,EAAAsO,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAoH,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAAuC,IAAAuC,EAAvC,CAAoD,GAEpD,KAAAqE,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAD,EAA1B,CAAwC,IAAAlE,EAAxC,CAAoD,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAEpD,KAAAkB,EAAA,EAAc,GANlB,CAYA5W,EAAAuO,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAoH,EAAA,CAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA4C,IAAAuC,EAA5C,CAAyD,GAEzD,KAAAqE,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAvG,EAAA,CAAW,IAAAqF,EAAX,CAA1B,CAA0D,IAAArF,EAAA,CAAW,IAAAqF,EAAX,CAA1D,CAAwF,CAAxF,CAA6F,GAJjG,CAYA3V,EAAAwO,GAAA,CAAAA,QAAK,EACL,CAEI0J,EAAA,CAAAA,IAAA,CAFJ,CAQAlY;CAAAyO,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAiH,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAAtE,EAA4E,IAAAwC,EAE5E,KAAAoE,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAD,EAA1B,CAAwC,IAAAlE,EAAxC,CAAoD,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAEpD,KAAAkB,EAAA,EAAc,GANlB,CAYA5W,EAAA0O,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAgH,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAAtE,EAA4E,IAAAuC,EAE5E,KAAAqE,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAD,EAA1B,CAAwC,IAAAlE,EAAxC,CAAoD,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAEpD,KAAAkB,EAAA,EAAc,GANlB,CAYA5W,EAAA2O,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAgH,EAAA,EAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA+C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA/C,EAA2E,CAA3E,EAAiF,IAAAuC,EAEjF,KAAAqE,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAvG,EAAA,CAAW,IAAAqF,EAAX,CAA1B,CAA0D,IAAArF,EAAA,CAAW,IAAAqF,EAAX,CAA1D,CAAwF,CAAxF,CAA6F,GAJjG,CAWA3V,EAAA4O,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAA8G,EAAA,CAAa,IAAAtF,EAAA,EAIb,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAFA,IAAAD,EAEA,CAFa,IAAAjE,EAEb,CAFyB,IAAArC,EAAA,CAAW,IAAAoF,EAAX,CAIzB,KAAAkB,EAAA,EAAc,GARlB,CAcA5W;CAAA6O,GAAA,CAAAA,QAAS,EACT,CAEI,IAAA6G,EAAA,CAAe,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAf,CAA2C,IAAAuC,EAA3C,CAAwD,GACxD,KAAA+C,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CAEpE,KAAAkB,EAAA,CAAc,IAAAlE,EAAd,CAA0B,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAA1B,EAAqD,IAAAkB,EAAD,CAAc,GAAd,CAAuB,CAAvB,CAA2B,CAA/E,CAEA,KAAAG,EAAA,CAAa,IAAArE,EAAb,CAAyB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAwB,KAAAoB,EAAA,CAAa,IAAAF,EAE9D,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAuC,IAAAkE,EAAvC,CAAoD,GAEpD,KAAAA,EAAA,EAAc,GAXlB,CAiBA5W,EAAA0X,GAAA,CAAAA,QAAY,EACZ,CAEI,IAAAhC,EAAA,CAAe,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAf,CAA2C,IAAAuC,EAA3C,CAAwD,GACxD,KAAA+C,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CAEpE,KAAAhD,EAAA,CAAY8F,CAAA,CAAAA,IAAA,CAAY,IAAA9F,EAAZ,CAAuB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAvB,CALhB,CAWA1V,EAAA8O,GAAA,CAAAA,QAAO,EACP,CAEI,IAAA4G,EAAA,CAAa,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAIb,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAFA,IAAAD,EAEA,CAFa,IAAAjE,EAEb,CAFyB,IAAArC,EAAA,CAAW,IAAAoF,EAAX,CAIzB,KAAAkB,EAAA,EAAc,GARlB,CAcA5W;CAAA+O,GAAA,CAAAA,QAAO,EACP,CAEI,IAAA2G,EAAA,CAAa,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAEb,KAAAwG,EAAA,CAAc,IAAAlE,EAAd,CAA0B,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAA1B,EAAqD,IAAAkB,EAAD,CAAc,GAAd,CAAuB,CAAvB,CAA2B,CAA/E,CAEA,KAAAG,EAAA,CAAa,IAAArE,EAAb,CAAyB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAwB,KAAAoB,EAAA,CAAa,IAAAF,EAE9D,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAuC,IAAAkE,EAAvC,CAAoD,GAEpD,KAAAA,EAAA,EAAc,GAVlB,CAgBA5W,EAAA2X,GAAA,CAAAA,QAAU,EACV,CAEI,IAAAjC,EAAA,CAAa,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAEb,KAAAsC,EAAA,CAAY8F,CAAA,CAAAA,IAAA,CAAY,IAAA9F,EAAZ,CAAuB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAvB,CAJhB,CAUA1V,EAAAgP,GAAA,CAAAA,QAAO,EACP,CAEI,IAAA2G,EAAA,CAAkB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAElB,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAvG,EAAA,CAAW,IAAAqF,EAAX,CAA1B,CAA0D,IAAArF,EAAA,CAAW,IAAAqF,EAAX,CAA1D,CAAwF,CAAxF,CAA6F,GAJjG,CAYA3V,EAAAiP,GAAA,CAAAA,QAAK,EACL,CAII,IAAA+H,EAAA,CAAa,IAAAH,EAAb,CAFA,IAAAlE,EAEA,CAFc,IAAAA,EAEd,CAF0B,CAE1B,CAF+B,GAFnC,CAUA3S;CAAAkP,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAwG,EAAA,CAAa,IAAAtF,EAAA,EAEb,KAAAwG,EAAA,CAAc,IAAAlE,EAAd,CAA0B,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAA1B,EAAqD,IAAAkB,EAAD,CAAc,GAAd,CAAuB,CAAvB,CAA2B,CAA/E,CAEA,KAAAG,EAAA,CAAa,IAAArE,EAAb,CAAyB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAwB,KAAAoB,EAAA,CAAa,IAAAF,EAE9D,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAuC,IAAAkE,EAAvC,CAAoD,GAEpD,KAAAA,EAAA,EAAc,GAVlB,CAgBA5W,EAAA4X,GAAA,CAAAA,QAAW,EACX,CAEI,IAAAlC,EAAA,CAAa,IAAAtF,EAAA,EAEb,KAAAsC,EAAA,CAAY8F,CAAA,CAAAA,IAAA,CAAY,IAAA9F,EAAZ,CAAuB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAvB,CAJhB,CAUA1V,EAAAmP,GAAA,CAAAA,QAAK,EACL,EAOAnP,EAAAoP,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAsG,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAEtE,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAD,EAA1B,CAAuC,IAAAjE,EAAvC,CAAmD,IAAArC,EAAA,CAAW,IAAAoF,EAAX,CAEnD,KAAAkB,EAAA,EAAc,GANlB,CAYA5W;CAAAqP,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAqG,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAEtE,KAAAwG,EAAA,CAAc,IAAAlE,EAAd,CAA0B,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAA1B,EAAqD,IAAAkB,EAAD,CAAc,GAAd,CAAuB,CAAvB,CAA2B,CAA/E,CAEA,KAAAG,EAAA,CAAa,IAAArE,EAAb,CAAyB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAwB,KAAAoB,EAAA,CAAa,IAAAF,EAE9D,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAuC,IAAAkE,EAAvC,CAAoD,GAEpD,KAAAA,EAAA,EAAc,GAVlB,CAgBA5W,EAAA6X,GAAA,CAAAA,QAAW,EACX,CAEI,IAAAnC,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAEtE,KAAAsC,EAAA,CAAY8F,CAAA,CAAAA,IAAA,CAAY,IAAA9F,EAAZ,CAAuB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAvB,CAJhB,CAUA1V,EAAAsP,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAqG,EAAA,CAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA+C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA/C,EAA2E,CAE3E,KAAA4G,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAvG,EAAA,CAAW,IAAAqF,EAAX,CAA1B,CAA0D,IAAArF,EAAA,CAAW,IAAAqF,EAAX,CAA1D,CAAwF,CAAxF,CAA6F,GAJjG,CAWA3V,EAAAuP,GAAA,CAAAA,QAAK,EACL,CAEI,IAAAa,EAAA,GAAiB,IAAAyG,EAAF,CAAe,GAAf,CAAoF,CAApF,EAAuB,IAAAxB,EAAA,EAAA,CAAqB,IAAA/E,EAAA,CAAW,IAAAF,EAAX,CAArB,EAA+C,EAA/C,EAAsD,EAA7E,CAAf,EAAwG,CAF5G,CAQApQ;CAAAwP,GAAA,CAAAA,QAAS,EACT,CAEI,IAAAkG,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CACd,KAAAsF,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CAApE,EAA0E,IAAA9C,EAE1E,KAAAgE,EAAA,CAAc,IAAAlE,EAAd,CAA0B,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAA1B,EAAqD,IAAAkB,EAAD,CAAc,GAAd,CAAuB,CAAvB,CAA2B,CAA/E,CAEA,KAAAG,EAAA,CAAa,IAAArE,EAAb,CAAyB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAwB,KAAAoB,EAAA,CAAa,IAAAF,EAE9D,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAuC,IAAAkE,EAAvC,CAAoD,GAEpD,KAAAA,EAAA,EAAc,GAXlB,CAiBA5W,EAAA8X,GAAA,CAAAA,QAAY,EACZ,CAEI,IAAApC,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CACd,KAAAsF,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAd,CAAwC,IAAApF,EAAA,CAAW,IAAAoF,EAAX,CAAsB,CAAtB,CAAxC,EAAoE,CAApE,EAA0E,IAAA9C,EAE1E,KAAAF,EAAA,CAAY8F,CAAA,CAAAA,IAAA,CAAY,IAAA9F,EAAZ,CAAuB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAvB,CALhB,CAWA1V;CAAAyP,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAiG,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAAuC,IAAAuC,EAAvC,CAAoD,GAEpD,KAAAiE,EAAA,CAAc,IAAAlE,EAAd,CAA0B,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAA1B,EAAqD,IAAAkB,EAAD,CAAc,GAAd,CAAuB,CAAvB,CAA2B,CAA/E,CAEA,KAAAG,EAAA,CAAa,IAAArE,EAAb,CAAyB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAwB,KAAAoB,EAAA,CAAa,IAAAF,EAE9D,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAuC,IAAAkE,EAAvC,CAAoD,GAEpD,KAAAA,EAAA,EAAc,GAVlB,CAgBA5W,EAAA+X,GAAA,CAAAA,QAAW,EACX,CAEI,IAAArC,EAAA,CAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAAuC,IAAAuC,EAAvC,CAAoD,GAEpD,KAAAD,EAAA,CAAY8F,CAAA,CAAAA,IAAA,CAAY,IAAA9F,EAAZ,CAAuB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAvB,CAJhB,CAUA1V,EAAA0P,GAAA,CAAAA,QAAQ,EACR,CAEI,IAAAiG,EAAA,CAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA4C,IAAAuC,EAA5C,CAAyD,GAEzD,KAAAqE,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAvG,EAAA,CAAW,IAAAqF,EAAX,CAA1B,CAA0D,IAAArF,EAAA,CAAW,IAAAqF,EAAX,CAA1D,CAAwF,CAAxF,CAA6F,GAJjG,CAYA3V,EAAA2P,GAAA,CAAAA,QAAK,EACL,CAEIsH,EAAA,CAAAA,IAAA,CAFJ,CAQAjX;CAAA4P,GAAA,CAAAA,QAAS,EACT,CAEI,IAAA8F,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAAtE,EAA4E,IAAAwC,EAE5E,KAAAgE,EAAA,CAAc,IAAAlE,EAAd,CAA0B,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAA1B,EAAqD,IAAAkB,EAAD,CAAc,GAAd,CAAuB,CAAvB,CAA2B,CAA/E,CAEA,KAAAG,EAAA,CAAa,IAAArE,EAAb,CAAyB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAwB,KAAAoB,EAAA,CAAa,IAAAF,EAE9D,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAuC,IAAAkE,EAAvC,CAAoD,GAEpD,KAAAA,EAAA,EAAc,GAVlB,CAgBA5W,EAAAgY,GAAA,CAAAA,QAAY,EACZ,CAEI,IAAAtC,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAAtE,EAA4E,IAAAwC,EAE5E,KAAAF,EAAA,CAAY8F,CAAA,CAAAA,IAAA,CAAY,IAAA9F,EAAZ,CAAuB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAvB,CAJhB,CAUA1V;CAAA6P,GAAA,CAAAA,QAAS,EACT,CAEI,IAAA6F,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAAtE,EAA4E,IAAAuC,EAE5E,KAAAiE,EAAA,CAAc,IAAAlE,EAAd,CAA0B,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAA1B,EAAqD,IAAAkB,EAAD,CAAc,GAAd,CAAuB,CAAvB,CAA2B,CAA/E,CAEA,KAAAG,EAAA,CAAa,IAAArE,EAAb,CAAyB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAwB,KAAAoB,EAAA,CAAa,IAAAF,EAE9D,KAAAI,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAnE,EAA1B,CAAuC,IAAAkE,EAAvC,CAAoD,GAEpD,KAAAA,EAAA,EAAc,GAVlB,CAgBA5W,EAAAiY,GAAA,CAAAA,QAAY,EACZ,CAEI,IAAAvC,EAAA,EAAc,IAAApF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAd,CAA0C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA1C,EAAsE,CAAtE,EAA4E,IAAAuC,EAE5E,KAAAD,EAAA,CAAY8F,CAAA,CAAAA,IAAA,CAAY,IAAA9F,EAAZ,CAAuB,IAAApC,EAAA,CAAW,IAAAoF,EAAX,CAAvB,CAJhB,CAUA1V,EAAA8P,GAAA,CAAAA,QAAS,EACT,CAEI,IAAA6F,EAAA,EAAmB,IAAArF,EAAA,CAAW,IAAAF,EAAA,EAAX,CAAnB,CAA+C,IAAAE,EAAA,CAAW,IAAAF,EAAA,EAAX,CAA/C,EAA2E,CAA3E,EAAiF,IAAAuC,EAEjF,KAAAqE,EAAA,CAAa,IAAAH,EAAb,CAA0B,IAAAvG,EAAA,CAAW,IAAAqF,EAAX,CAA1B,CAA0D,IAAArF,EAAA,CAAW,IAAAqF,EAAX,CAA1D,CAAwF,CAAxF,CAA6F,GAJjG,CAWA3V;CAAAwG,GAAA,CAAAA,QAAK,EACL,CAEQkS,IAAAA,EAAS,IAAApI,EAAA,CAAW,IAAAF,EAAA,EAAX,CACb,QAAOsI,CAAP,EAEI,KA3hHkBC,CA2hHlB,CACI,IAAAnY,EAAA,CAAa,MAAb,CACA,KAAA2P,GAAA,EACA,MAEJ,MA/hHkB/J,CA+hHlB,CACI+P,CAAA,CAAO,IAAA/F,EAGP,KADA,IAAIpe,EAAI,EACR,CAAOmkB,CAAP,CAAc,IAAA7F,EAAA9a,OAAd,CAAA,CAAiC,CAC7B,IAAI3C,EAAI,IAAAyd,EAAA,CAAW6F,CAAA,EAAX,CACR,IAAI,CAACtjB,CAAL,CAAQ,KACRb,EAAA,EAAKQ,MAAAC,aAAA,CAAoBI,CAApB,CAHwB,CAKjC,IAAAud,EAAA,CAAa+F,CAMbnkB,EAAA,CAAIA,CAAA6B,QAAA,CAAU,KAAV,CAAiBf,CAAA,CAAU,IAAA4f,EAAV,CAAqB,CAArB,CAAjB,CAAA7e,QAAA,CAAkD,KAAlD,CAAyDf,CAAA,CAAU,IAAA6f,EAAV,CAAqB,CAArB,CAAzD,CAAA9e,QAAA,CAA0F,KAA1F,CAAiGf,CAAA,CAAU,IAAA8f,EAAV,CAAqB,CAArB,CAAjG,CACJ,KAAApS,EAAA,CAAaxO,CAAb,CAIAykB,GAAA,CAAAA,IAAA,CACA,MAEJ,SACI,IAAArG,EAEA,EAFc,CAEd,CADA,IAAA5P,EAAA,CAAa,mBAAb,CAAmCoY,CAAA,CAAcF,CAAd,CAAnC,CAA2D,MAA3D,CAAoElC,CAAA,CAAc,IAAApG,EAAd,CAApE,CACA,CAAA,IAAAD,GAAA,EAjCR,CAHJ,CA2CAnQ,EAAAyG,EAAA,CAAAA,QAAW,EACX,CACI,IAAI5T,EAAI,IAAAyd,EAAA,CAAW,EAAE,IAAAF,EAAb,CACR,KAAA5P,EAAA,CAAa,oBAAb,CAAoCoY,CAAA,CAAc/lB,CAAd,CAApC,CAAuD,MAAvD,CAAgE2jB,CAAA,CAAc,IAAApG,EAAd,CAAhE,CACA,KAAAD,GAAA,EAHJ,CAyEJtL;CAAA,CA3DIV,QAAW,EACX,CAEI,IADA,IAAI0U,EAASlc,CAAA,CAA6B2H,QAA7B,CAn3HNC,OAm3HM,CAAuD,KAAvD,CAAb,CACSuU,EAAK,CAAd,CAAiBA,CAAjB,CAAwBD,CAAArjB,OAAxB,CAAuCsjB,CAAA,EAAvC,CAA+C,CAC3C,IAAIC,EAAOF,CAAA,CAAOC,CAAP,CAAX,CACI/T,EAAWxH,CAAA,CAA4Bwb,CAA5B,CACXpd,EAAAA,CAAM,IAAImJ,EAAJ,CAAWC,CAAX,CACVH,EAAA,CAAgCjJ,CAAhC,CAAqCod,CAArC,CAJ2C,CAFnD,CA0DJ,CA8BIve,SAhBEwe,GAgBS,CAACC,CAAD,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,QAAN,CAAgBA,CAAhB,CAGA,KAAAC,EAAA,CADA,IAAA5I,EACA,CADa,IAEb,KAAA6I,EAAA,CAAaF,CAAA,KAEb,IADA,IAAAG,EACA,CADcH,CAAA,MACd,CAAiB,CACTI,CAAAA,CAAW,IAAAD,EAOf,KAAIE,EAAWC,EAAA,CAAiB,IAAAH,EAAjB,CA7qPPI,OA8qPR,EAAIF,CAAJ,EA3qPQE,KA2qPR,EAAuCF,CAAvC,GACID,CADJ,CAxiMI,SAwiMJ,EAxiMiBzkB,MAAA,CAAQA,MAAAa,SAAAgkB,KAAR,CAtvDdC,cA8xPH,EAC6E,uBAD7E,CACmF,IAAAN,EADnF,CAzqPQI,qBAyqPR,CAGA,KAAIG,EAAM,IACVC,EAAA,CAAgBP,CAAhB,CAAsC,QAAQ,CAACjlB,CAAD,CAAOylB,CAAP,CAAkBrlB,CAAlB,CAA8B,CACxEslB,EAAA,CAAAH,CAAA,CAAiBvlB,CAAjB,CAAuBylB,CAAvB,CAAkCrlB,CAAlC,CADwE,CAA5E,CAba,CAPrB,CAjBiBsP,CAAArJ,CAAfue,EAAeve,CAAAA,CAAAA,CAkDjB;EAAA,UAAA,GAAA,CAAAkW,QAAS,CAACC,CAAD,CAAWhO,CAAX,CAAkBiO,CAAlB,CAAuBlV,CAAvB,CACT,CACI,IAAA2U,EAAA,CAAaM,CACb,KAAAmJ,EAAA,CAAcnX,CACVuW,EAAAA,CAAQtI,CAARsI,CAAcvW,CAAduW,CAAsB,CAKrB,KAAAA,EAAL,GACI,IAAAA,EADJ,CACiBA,CADjB,CAEIA,EAAJ,EAAa,IAAAA,EAAb,CACIjY,EAAA,CAAAA,IAAA,CAAc,+BAAd,CAAgDsV,CAAA,CAAc2C,CAAd,CAAhD,CAAuE,6CAAvE,CAAuH3C,CAAA,CAAc,IAAA2C,EAAd,CAAvH,CAAmJ,GAAnJ,CADJ,EAIIxd,CAIJ,GAHI,IAAAA,EACA,CADWA,CACX,CAAAgW,CAAA,CAAAhW,CAAA,CAAmBiH,CAAnB,CAA0BiO,CAA1B,CAA+B,IAA/B,CAAqC,IAAAmJ,EAArC,CAEJ,EAAAC,EAAA,CAAAA,IAAA,CARA,CAVJ,CA0BA,GAAA,UAAA,GAAA,CAAAjW,QAAQ,CAACC,CAAD,CAAMrI,CAAN,CACR,CACQqI,CAAJ,EAAW,CAAC,IAAAjJ,EAAAK,EAAZ,GACI,IAAAL,EAAAK,EACc,CADO,CAAA,CACP,CAAA,IAAAK,EAAA,CAAWoC,CAAA,CAAAlC,CAAA,CAAuB,UAAvB,CAF7B,CADJ,CAYA,GAAA,UAAA,EAAA,CAAAoe,QAAO,CAAC7D,CAAD,CAAOzE,CAAP,CACP,CAMqBlU,IAAAA,EAAjB,GAAIkU,CAAJ,GACoB,IAAAhW,EAMZ,EANsBwe,CAAA,CAAA,IAAAxe,EAAA,CAAmB,IAAnB,CAAyBya,CAAzB,CAA+BzE,CAA/B,CAAyC,IAAAhW,EAAAye,GAAzC,CAAgE,CAAA,CAAhE,CAMtB,CALUhE,CAKV,EALiB,IAAA4D,EAKjB,CAAA,IAAAzJ,EAAA,CAAW,IAAAyJ,EAAX,CAAyBK,CAAzB,CAAA,CAHC,IAAAlB,EAAL,CAGuC,IAAAA,EAAA,CAAakB,CAAb,CAHvC,CACuC,CAL3C,CANJ,CAuBAN;QAAA,GAAY,CAAZA,CAAY,CAACO,CAAD,CAAaC,CAAb,CAAyB9lB,CAAzB,CACZ,CACI,GAAIA,CAAJ,CACI,CAAAgM,EAAA,CAAa,qBAAb,CAAsC6Z,CAAtC,CAAmD,KAAnD,CAA4D7lB,CAA5D,CAAyE,GAAzE,CADJ,KAAA,CAIA,GAA4B,GAA5B,EAAI8lB,CAAAC,OAAA,CAAkB,CAAlB,CAAJ,EAA2D,GAA3D,EAAmCD,CAAAC,OAAA,CAAkB,CAAlB,CAAnC,CACI,GAAI,CAIA,IAAIZ,EAAMzb,IAAA,CAAK,GAAL,CAAWoc,CAAX,CAAwB,GAAxB,CAAV,CACIE,EAAKb,CAAA,MACLa,EAAJ,CACI,CAAAtB,EADJ,CACmBsB,CADnB,CAGI,CAAAtB,EAHJ,CAGmBS,CATnB,CAWF,MAAO7hB,CAAP,CAAU,CACR,CAAA0I,EAAA,CAAa,wBAAb,CAAyC6Z,CAAzC,CAAsD,KAAtD,CAA+DviB,CAAA6B,QAA/D,CACA,OAFQ,CAZhB,IAwBI,KAFI8gB,CAEKrnB,CAHGknB,CAAAzmB,QAAA,CAAmB,MAAnB,CAA2B,GAA3B,CAAAA,QAAA6mB,CAAwC,KAAxCA,CAA+C,EAA/CA,CACCrd,MAAA,CAAY,GAAZ,CAEJjK,CADT,CAAA8lB,EACS9lB,CADUoP,KAAJ,CAAUiY,CAAAjlB,OAAV,CACNpC,CAAAA,CAAAA,CAAE,CAAX,CAAcA,CAAd,CAAkBqnB,CAAAjlB,OAAlB,CAAiCpC,CAAA,EAAjC,CACI,CAAA8lB,EAAA,CAAa9lB,CAAb,CAAA,CAAkBunB,QAAA,CAASF,CAAA,CAAOrnB,CAAP,CAAT,CAAoB,EAApB,CAG1B6mB,GAAA,CAAAA,CAAA,CAhCA,CADJ;AAuCAA,QAAA,GAAS,CAATA,CAAS,CACT,CAOI,GAAI,CAAC9Y,CAAA,CAAAA,CAAA,CAAL,CACI,GAAI,CAAC,CAAAiY,EAAL,CACI,CAAAhY,EAAA,EADJ,KAIA,IAAI,CAAA8X,EAAJ,EAAoB,CAAA5I,EAApB,CAAgC,CAC5B,IAAIsK,EAAU,CAAA1B,EAAA1jB,OACd,IAAIolB,CAAJ,EAAe,CAAAzB,EAAf,CACIjY,EAAA,CAAAA,CAAA,CAAc,kBAAd,CAAmCsV,CAAA,CAAcoE,CAAd,CAAnC,CAA4D,6CAA5D,CAA4GpE,CAAA,CAAc,CAAA2C,EAAd,CAA5G,CAAwI,GAAxI,CADJ,KAAA,CAKA,IAAK,IAAI/lB,EAAE,CAAX,CAAcA,CAAd,CAAkBwnB,CAAlB,CAA2BxnB,CAAA,EAA3B,CACI,CAAAkd,EAAA,CAAW,CAAAyJ,EAAX,CAAyB3mB,CAAzB,CAAA,CAA8B,CAAA8lB,EAAA,CAAa9lB,CAAb,CAElC,EAAAgO,EAAA,EARA,CAF4B,CAZxC,CAkDJyD,CAAA,CAfIV,QAAW,EACX,CAEI,IADA,IAAI0W,EAAQle,CAAA,CAA6B2H,QAA7B,CA1nILC,OA0nIK,CAAuD,KAAvD,CAAZ,CACSuW,EAAK,CAAd,CAAiBA,CAAjB,CAAwBD,CAAArlB,OAAxB,CAAsCslB,CAAA,EAAtC,CAA8C,CAC1C,IAAIC,EAAOF,CAAA,CAAMC,CAAN,CAAX,CACI7B,EAAW1b,CAAA,CAA4Bwd,CAA5B,CACXpB,EAAAA,CAAM,IAAIX,EAAJ,CAAWC,CAAX,CACVrU,EAAA,CAAgC+U,CAAhC,CAAqCoB,CAArC,CAJ0C,CAFlD,CAcJ,CA6BIvgB,SAfEwgB,GAeS,CAACC,CAAD,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,QAAN,CAAgBA,CAAhB,CADJ,CAhBiBnX,CAAArJ,CAAfugB,EAAevgB,CAAAA,CAAAA,CA2BjB,GAAA,UAAA,GAAA,CAAAkW,QAAS,CAACC,CAAD,CACT,CACI,IAAAN,EAAA,CAAaM,CAGb,KAAAxP,EAAA,EAJJ,CA8BJyD;CAAA,CAfIV,QAAW,EACX,CAEI,IADA,IAAI+W,EAAQve,CAAA,CAA6B2H,QAA7B,CAlsILC,OAksIK,CAAuD,KAAvD,CAAZ,CACS4W,EAAK,CAAd,CAAiBA,CAAjB,CAAwBD,CAAA1lB,OAAxB,CAAsC2lB,CAAA,EAAtC,CAA8C,CAC1C,IAAIC,EAAOF,CAAA,CAAMC,CAAN,CAAX,CACIF,EAAW1d,CAAA,CAA4B6d,CAA5B,CACXC,EAAAA,CAAM,IAAIL,EAAJ,CAAWC,CAAX,CACVrW,EAAA,CAAgCyW,CAAhC,CAAqCD,CAArC,CAJ0C,CAFlD,CAcJ,CAqGI5gB;QAvFE8gB,GAuFS,CAACC,CAAD,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,aAAN,CAAqBA,CAArB,CAEA,KAAAvgB,EAAAK,EAAA,CAAqB,CAAA,CACrB,KAAAmgB,GAAA,CAAqBD,CAAA,MAKrB,KAAAE,EAAA,CAA0B,CAE1B,KAAAC,GAAA,CAA0B,EAC1B,KAAAC,GAAA,CAA0B,EAK1B,KAAAC,GAAA,CAA0B,EAM1B,KAAAC,GAAA,CAA0B,IAAAJ,EAC1B,KAAAK,GAAA,CAA0B,IAAAJ,GAC1B,KAAAK,GAAA,CAA0B,IAAAJ,GAC1B,KAAAK,EAAA,CAA0B,IAAAJ,GAS1B,KAAAK,EAAA,CAA0B,GAO1B,KAAAC,EAAA,CAA0B,GAC1B,KAAAC,GAAA,CAA0B,CAC1B,KAAAC,GAAA,CAA0B,EAW1B,KAAAC,EAAA,CAA0B,CAyB1B,KAAAC,EAAA,CAAsB,EACtB,KAAAA,EAAA,CAAoB,OAApB,CAAA,CAAgC,IAAAJ,EAChC,KAAAI,EAAA,IAAA,CAAgC,IAAAN,EAChC,KAAAM,EAAA,CAAoB,QAApB,CAAA,CAAgC,IAAAH,GAChC,KAAAG,EAAA,CAAoB,QAApB,CAAA,CAAgC,IAAAF,GAmChC,KAAAG,EAAA,CAAoB,EACpB,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA;AAA0B,KAC5D,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC1B,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAE5D,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAA+B,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KACrH,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IAA+B,KAAAA,EAAA,CAAkB,IAAAV,GAAlB,CAAA,CAA0C,IACrI,KAAAU,EAAA,CAAkB,IAAAT,GAAlB,CAAA,CAAsC,KACtC,KAAAS,EAAA,CAAkB,IAAAR,GAAlB,CAAA,CAAsC,KACtC,KAAAQ,EAAA,CAAkB,GAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA;AAA0B,KAC5D,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,KAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAA+B,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KACrH,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,IAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,KAC5D,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IAC5D,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,IAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA;AAA0B,IAC5D,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IAC5D,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,IAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IAA+B,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IACrH,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,IAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IAA+B,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IACrH,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IAC5D,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,IAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IAC5D,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IAC5D,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,IAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IAC5D,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IAC1B,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IAC5D,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IAC5D,KAAAA,EAAA,CAAkB,GAAlB,CAAA,CAA0B,IAAQ,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IAA+B,KAAAA,EAAA,CAAkB,EAAlB,CAAA,CAA0B,IAErH,KAAAA,EAAA,CAAkB,IAAAN,EAAlB,CAAA,CAA8C,IAC9C,KAAAM,EAAA,CAAkB,IAAAP,EAAlB,CAAA,CAA8C,IAC9C,KAAAO,EAAA,CAvI0BC,GAuI1B,CAAA,CAA8C,GAC9C,KAAAD,EAAA,CAtI0BE,GAsI1B,CAAA,CAA8C,GAC9C,KAAAF,EAAA,CAtI0BG,GAsI1B,CAAA,CAA8C,CAE9C,KAAAzM,MAAA,EA7KJ,CAxFsBnM,CAAArJ,CAApB6gB,EAAoB7gB,CAAAA,CAAAA,CA2QtB;CAAA,CAj0QJ,EAAAkiB,UAi0QI3c,EAAAiQ,MAAA,CAAAA,QAAK,EACL,CACI,IAAA2M,GAAA,CAAc,IAAApB,GAAd,CASA,KAAAqB,EAAA,CAAiB,IAAAR,EAMjB,KAAAS,GAAA,CAAgB,CAWhB,KAAAC,EAAA,CAAiB,CAAC,IAAAV,EAAD,CAAoB,CAApB,CAAyB,CAAzB,CAA8B,CAA9B,CAAmC,CAAnC,CAAwC,CAAxC,CAA6C,CAA7C,CAAkD,CAAlD,CASjB,KAAAW,EAAA,CAAkB,EAalB,IAAI,IAAAC,EAAJ,CACI,IAAK7pB,IAAIA,CAAT,GAAc,KAAA6pB,EAAd,CACQhrB,KAAA,CAAM,CAACmB,CAAP,CAAJ,EACI,IAAA6pB,EAAA,CAAgB7pB,CAAhB,CADJ,EACwByF,YAAA,CAAa,IAAAokB,EAAA,CAAgB7pB,CAAhB,CAAb,CAGhC,KAAA6pB,EAAA,CAAkB,EAElB,KAAAC,GAAA,CADA,IAAAC,EACA,CADoB,CAOpB,KAAAC,GAAA,CAAmB,EACnB,KAAAC,GAAA,CAAqB,IAAAN,EAYrB,KAAAO,GAAA,CADA,IAAAC,EACA,CAD6B,CAO7B,KAAAC,EAAA,CAAqB,EAlFzB,CA6FAxd;CAAAvC,EAAA,CAAAA,QAAU,CAACyC,CAAD,CAAYC,CAAZ,CAAsBhE,CAAtB,CACV,CAII,GAAgCqB,IAAAA,EAAhC,GAAI,IAAA1C,EAAA,CAAcqF,CAAd,CAAJ,CACI,OAAOA,CAAP,EACA,KAAK,SAAL,CAOI,MANA,KAAArF,EAAA,CAAcqF,CAAd,CAMO,CANmBhE,CAMnB,CALPA,CAAAshB,UAKO,CALa,QAAQ,CAAC1Z,CAAD,CAAM,CAC9B,MAAO,SAAQ,CAAC2Z,CAAD,CAAQ,CACnB,MAAOC,GAAA,CAAA5Z,CAAA,CAAa2Z,CAAb,CAAoB,CAAA,CAApB,CADY,CADO,CAAd,CAIlB,IAJkB,CAKb,CAAA,CAAA,CACX,MAAK,UAAL,CAOI,MANA,KAAA5iB,EAAA,CAAcqF,CAAd,CAMO,CANmBhE,CAMnB,CALPA,CAAAyhB,WAKO,CALc,QAAQ,CAAC7Z,CAAD,CAAM,CAC/B,MAAO,SAAQ,CAAC2Z,CAAD,CAAQ,CA4WnC,IAAIG,EAAQ,CAAA,CAIZH,EAAA,CA/WoCA,CA+WpC,EAAiB9oB,MAAA8oB,MACbI,EAAAA,CAAWJ,CAAAK,MAAXD,EAA0BJ,CAAAM,QAhXPja,EAqXvByZ,EAAA,CAAqB,EArXEzZ,EAuXnB8Y,EAAJ,CAjmB0BoB,CAimB1B,CAvXuBla,CAwXnB8Y,EADJ,EACsB,EADtB,CAGIgB,CAHJ,CAGY,CAACK,EAAA,CA1XUna,CA0XV,CAAsB+Z,CAAtB,CA1XU/Z,EA4XPrI,EAAhB,EAA4B+F,CAAA,CA5XLsC,CA4XKrI,EAAA,CA5XLqI,CA4X6BrI,EAAAyiB,GAAxB,CAA5B,EA5XuBpa,CA6XnBrI,EAAA/B,QAAA,CAAiB,WAAjB,CAA+Bif,CAAA,CAAckF,CAAd,CAA/B,CAAyD,KAAzD,EAAkED,CAAA,CAAO,MAAP,CAAgB,SAAlF,EA7XY,OA+XTA,EAhY4B,CADQ,CAAd,CAInB,IAJmB,CAKd,CAAA,CAAA,CACX,MAAK,OAAL,CAOI,MANA,KAAA/iB,EAAA,CAAcqF,CAAd,CAMO,CANmBhE,CAMnB,CALPA,CAAAiiB,QAKO,CALW,QAAQ,CAACra,CAAD,CAAM,CAC5B,MAAO,SAAQ,CAAC2Z,CAAD,CAAQ,CACnB,MAAOC,GAAA,CAAA5Z,CAAA,CAAa2Z,CAAb;AAAoB,CAAA,CAApB,CADY,CADK,CAAd,CAIhB,IAJgB,CAKX,CAAA,CAAA,CACX,MAAK,OAAL,CAkBI,MAPA,KAAA5iB,EAAA,CAAcqF,CAAd,CAOO,CAPmBhE,CAOnB,CANPA,CAAAiE,QAMO,CANW,QAAQ,CAAC2D,CAAD,CAAM,CAC5B,MAAO,SAAQ,EAAQ,CAEfA,CAAAnI,EAAJ,EAAamI,CAAAnI,EAAAqU,MAAA,CAAc,CAAA,CAAd,CAFM,CADK,CAAd,CAKhB,IALgB,CAMX,CAAA,CAAA,CACX,SACI,GAAsCzS,IAAAA,EAAtC,GAAI,IAAA8e,EAAA,CAAoBnc,CAApB,CAAJ,CASI,MARA,KAAArF,EAAA,CAAcqF,CAAd,CAQO,CARmBhE,CAQnB,CAPPA,CAAAiE,QAOO,CAPW,QAAQ,CAAC2D,CAAD,CAAMsa,CAAN,CAAeP,CAAf,CAAyB,CAC/C,MAAO,SAAQ,EAAQ,CAEf/Z,CAAApI,EAAJ,EAAaoI,CAAApI,EAAAyV,GAAA,EACb,OAAO,CAAC8M,EAAA,CAAAna,CAAA,CAAqB+Z,CAArB,CAHW,CADwB,CAAjC,CAMhB,IANgB,CAMV3d,CANU,CAMA,IAAAmc,EAAA,CAAoBnc,CAApB,CANA,CAOX,CAAA,CAAA,CAtDf,CA2DJ,MAAO,CAAA,CAhEX,CA0EAH,EAAA2Q,GAAA,CAAAA,QAAS,CAACC,CAAD,CAAWhO,CAAX,CAAkBiO,CAAlB,CAAuBlV,CAAvB,CACT,CACI,IAAA2U,EAAA,CAAaM,CACb,KAAA0N,GAAA,CAAc1b,CACd,KAAA2b,GAAA,CAAa1N,CAAb,CAAmBjO,CAAnB,CAA2B,CAC3B,KAAA4b,GAAA,CAAmB,IAAAF,GAAnB,CAAiC,IAAAC,GAC7B5iB,EAAJ,GACI,IAAAA,EAEA,CAFWA,CAEX,CAAAgW,CAAA,CAAAhW,CAAA,CAAmBiH,CAAnB,CAA0BiO,CAA1B,CAA+B,IAA/B,CAAqC,IAAAmJ,GAArC,CAHJ,CAKA,KAAA5Y,EAAA,EAVJ,CAiBApB,EAAA4c,GAAA,CAAAA,QAAQ,CAAC6B,CAAD,CACR,CACI,IAAAA,EAAA,CAAcA,CAKd,KAAAC,EAAA,CAAe,GACI,IAAnB,EAAI,IAAAD,EAAJ,GAII,IAAAC,EACA,CADe,CACf,CAAA,IAAAle,EAAA,CAAa,0BAAb,CAA0C,IAAAie,EAA1C,CALJ,CAPJ,CA0BAze;CAAAgE,GAAA,CAAAA,QAAQ,CAACC,CAAD,CAAMrI,CAAN,CACR,CACQqI,CAAJ,EAAW,CAAC,IAAAjJ,EAAAK,EAAZ,GACI,IAAAL,EAAAK,EAEc,CAFO,CAAA,CAEP,CADd,IAAAO,EACc,CADHA,CACG,CAAA,IAAAF,EAAA,CAAWoC,CAAA,CAAAlC,CAAA,CAAuB,UAAvB,CAH7B,CADJ,CAYAoE,EAAAoB,EAAA,CAAAA,QAAQ,EACR,CAEI,IAAAud,EAAA,EADA,IAAAC,GACA,CADWhoB,CAAA,CAAgB,KAAhB,CACX,GAA4BA,CAAA,CAAgB,SAAhB,CACZ,KAAA8E,EAAhB,EAA4B+F,CAAA,CAAA,IAAA/F,EAAA,CAAwB,IAAAA,EAAAyiB,GAAxB,CAA5B,EACI,IAAAziB,EAAA/B,QAAA,CAAiB,2BAAjB,EAAgD,IAAAglB,EAAA,CAAc,MAAd,CAAuB,OAAvE,EAAkF,IAAlF,CAAyF/pB,MAAA0B,UAAAD,UAAzF,CAAsH,GAAtH,CAEJ+K,EAAAA,UAAAA,EAAAA,KAAAA,CAAAA,IAAAA,CANJ,CAuBAyd,SAAA,GAAgB,CAAhBA,CAAgB,CAACC,CAAD,CAChB,CAWQvmB,CAAAA,CAAWumB,CAAA,CA7WWC,GA6WX,CA9WWC,GA+WtB,EAAArjB,EAAJ,EAAgB,CAAAA,EAAA4X,EAAhB,GACIhb,CADJ,EACe,CAAAoD,EAAA4X,EADf,CAGA,OAAOhb,EAfX,CAsBA0mB,QAAA,GAAS,CAATA,CAAS,CAACC,CAAD,CACT,CACQ/B,CAAA,CAAAA,EAAJ,EAA0C3f,IAAAA,EAA1C,GAA0B0hB,CAA1B,EAAuDA,CAAvD,EAAsE,CAAA/B,EAAtE,GACoB,CAAAzhB,EAKhB,EAL4B+F,CAAA,CAAA,CAAA/F,EAAA,CAAwB,CAAAA,EAAAyiB,GAAxB,CAK5B,EAJI,CAAAziB,EAAA/B,QAAA,CAAiB,YAAjB,CAAgCif,CAAA,CAAc,CAAAuE,EAAd,CAAhC,CAAmE,GAAnE,CAIJ,CADAtkB,YAAA,CAAa,CAAAokB,EAAA,CAAgB,CAAAE,EAAhB,CAAb,CACA,CAAAgC,EAAA,CAAAA,CAAA,CAAsB,CAAAhC,EAAtB,CAAyC,CAAA,CAAzC,CA3YsBiC,CA2YtB,CANJ,CADJ;AAgBAC,QAAA,GAAU,CAAVA,CAAU,CAACC,CAAD,CAAY/mB,CAAZ,CACV,CACI,CAAAilB,EAAA,CAAqB8B,CAErBC,GAAA,CAAAA,CAAA,CAA0BhnB,CAA1B,EA5Y0BinB,GA4Y1B,CAHJ,CAUAD,QAAA,GAAoB,CAApBA,CAAoB,CAAChnB,CAAD,CACpB,CACI,GAAgC,CAAhC,CAAI,CAAAilB,EAAAhoB,OAAJ,CAAmC,CAC/B,IAAIiqB,EAAK,CAAAjC,EAAAkC,WAAA,CAA8B,CAA9B,CAIC,GAAV,EAAID,CAAJ,GACIA,CADJ,CACS,EADT,CAWU,GAAV,EAAIA,CAAJ,EAAwB,EAAxB,EAAkBA,CAAlB,GACIA,CADJ,EACU,EADV,CAEA,EAAAjC,EAAA,CAAqB,CAAAA,EAAAlqB,OAAA,CAA0B,CAA1B,CACrB4qB,GAAA,CAAAA,CAAA,CAAsBuB,CAAtB,CAnB+B,CAqBH,CAAhC,CAAI,CAAAjC,EAAAhoB,OAAJ,EACIoC,UAAA,CAAW,QAAQ,CAACmM,CAAD,CAAM,CAAE,MAAO,SAAQ,EAAG,CAACwb,EAAA,CAAAxb,CAAA,CAAyBxL,CAAzB,CAAD,CAApB,CAAd,CAA0E,CAA1E,CAAX,CAA4FA,CAA5F,CAvBR;AAiCAolB,QAAA,GAAQ,CAARA,CAAQ,CAACD,CAAD,CAAQiC,CAAR,CACR,CACI,IACIC,EAAa,CAACD,CACd3B,EAAAA,CAAUN,CAAAM,QAEV2B,EAAJ,GAAW,CAAAzC,GAAX,CAA8Bc,CAA9B,CAEA,IAAe,EAAf,EAAIA,CAAJ,CACI,CAAAnB,EAGA,EAHkB,EAGlB,CAFI8C,CAEJ,GAFW,CAAA9C,EAEX,EAtdsBgD,CAsdtB,EADA7B,CACA,EA9esB8B,GA8etB,CAAAF,CAAA,CAAa,CAAA,CAJjB,KAOA,IAAe,EAAf,EAAI5B,CAAJ,CACI,CAAAnB,EAGA,EAHkB,EAGlB,CAFI8C,CAEJ,GAFW,CAAA9C,EAEX,EA9dsBkD,CA8dtB,EADA/B,CACA,EArfsB8B,GAqftB,CAAAF,CAAA,CAAa,CAAA,CAJjB,KAOA,IAAI5B,CAAJ,EAAe,CAAA/B,EAAf,CAxf0B6D,GAwf1B,CACI,CAAAjD,EAGA,EAHkB,GAGlB,CAFI8C,CAEJ,GAFW,CAAA9C,EAEX,EAlesBmD,EAketB,EADAhC,CACA,EA5fsB8B,GA4ftB,CAAAF,CAAA,CAAa,CAAA,CAJjB,KAOA,IAAe,EAAf,EAAI5B,CAAJ,CAUI2B,CAIA,CAJQ,CAACA,CAIT,CAHA,CAAA9C,EAGA,EAHkB,CAAC,CAAAR,EAGnB,CAFIsD,CAEJ,GAFW,CAAA9C,EAEX,EAF6B,CAAAR,EAE7B,EADA2B,CACA,EA7gBsB8B,GA6gBtB,CAAAF,CAAA,CAAa,CAAA,CAdjB,KAiBA,IA/hB0BK,EA+hB1B,EAAIjC,CAAJ,CAAqC,CAIjC,CAAAnB,EAAA,EAAkB,EACd8C,EAAJ,GAAW,CAAA9C,EAAX,EA5fsBoB,CA4ftB,CACA2B,EAAA,CAAa,CAAA,CACb,KAAA/B,EAAQ,CAAA,CAPyB,CAArC,IAkBIA,EAAA,CAzjBsBqC,CAijB1B,EAAIlC,CAAJ,CAQY4B,CARZ,CAQyB,CAAA,CARzB,CAWI5B,CAAJ,EAAe,CAAApC,GAAf,EAAmCoC,CAAnC,EAA8C,CAAAvC,EAA9C,CAUakE,CAAA,CAAO,CAACzB,EAAA,CAAAA,CAAA,CAAsBF,CAAtB,CAAR,CAAyC,CAAA,CAVtD,CAiBY,CAAA,CAcR4B,EAAJ,GAQI,CAAA/C,EAWA,EAXkB,EAWlB,CAAK,CAAA8B,EAAL,EAAqBX,CAArB,EAAgC,CAAAd,GAAhC,EAAkD+B,EAAA,CAAAA,CAAA,CAnBtD,CAsBczhB,KAAAA,EAAd,GAAIqgB,CAAJ,GACIA,CADJ,CACY,CAACsB,EAAA,CAAAA,CAAA,CAAsBnB,CAAtB,CAA+B2B,CAA/B,CA5jBaQ,CA4jBb,CADb,CAIgB,EAAAzkB,EAAhB,EAA4B+F,CAAA,CAAA,CAAA/F,EAAA,CAAwB,CAAAA,EAAAyiB,GAAxB,CAA5B,EACI,CAAAziB,EAAA/B,QAAA,CAAuC,KAAvC,EAAgDgmB,CAAA,CAAM,MAAN,CAAa,IAA7D,EAAqE,GAArE,CAA2E/G,CAAA,CAAcoF,CAAd,CAA3E,CAAoG,KAApG,EAA6GH,CAAA,CAAO,MAAP,CAAgB,SAA7H,EAEJ,OAAOA,EA9HX;AAuKAK,QAAA,GAAgB,CAAhBA,CAAgB,CAACJ,CAAD,CAChB,CACI,IAAIsC,EAAa,CAAA,CACbtC,EAAJ,EAAgB,CAAA5B,EAAhB,CAKQ,CAAAtgB,EALR,GAMQ,CAAAA,EAAAqU,MAAA,CAAe,CAAA,CAAf,CACA,CAAAmQ,CAAA,CAAa,CAAA,CAPrB,GAsBQ,CAAAzB,EAUJ,EAToB,EASpB,EATQb,CASR,EATwC,EASxC,EAT4BA,CAS5B,GARQA,CAQR,EARoB,EAQpB,EAFAmB,EAAA,CAAAA,CAAA,CAAenB,CAAf,CAEA,CAAIqB,EAAA,CAAAA,CAAA,CAAsBrB,CAAtB,CAAgC,CAAA,CAAhC,CAhpBkBuC,CAgpBlB,CAAJ,GA7zJchb,CA80JV,EAAI,CAAA1J,EAAA2J,MAAJ,CACI6Z,EAAA,CAAAA,CAAA,CAAsBrB,CAAtB,CAAgC,CAAA,CAAhC,CAjqBcwC,CAiqBd,CADJ,EAIQxB,CAOJ,CAPc,CAAA,CAOd,CANI,CAAA7B,EAAA,CAAgBa,CAAhB,CAMJ,GALIjlB,YAAA,CAAa,CAAAokB,EAAA,CAAgBa,CAAhB,CAAb,CACA,CAAAgB,CAAA,CAAU,CAAA,CAId,EAFIvmB,CAEJ,CAFcsmB,EAAA,CAAAA,CAAA,CAAsBC,CAAtB,CAEd,CADA,CAAA7B,EAAA,CAAgB,CAAAE,EAAhB,CAAoCW,CAApC,CACA,CADgDlmB,UAAA,CAAW,QAAQ,CAACmM,CAAD,CAAM,CAAE,MAAO,SAAQ,EAAG,CAACob,EAAA,CAAApb,CAAA,CAAqB+Z,CAArB,CAA+B,CAAA,CAA/B,CAxqBhFyC,CAwqBgF,CAAD,CAApB,CAAd,CAAsG,CAAtG,CAAX,CAAwHhoB,CAAxH,CAChD,CAAgB,CAAAmD,EAAhB,EAA4B+F,CAAA,CAAA,CAAA/F,EAAA,CAAwB,CAAAA,EAAAyiB,GAAxB,CAA5B,EACI,CAAAziB,EAAA/B,QAAA,CAAiB,mBAAjB,CAAuCif,CAAA,CAAckF,CAAd,CAAvC,CAAiE,iBAAjE,CAZR,CAeA,CAAAsC,CAAA,CAAa,CAAA,CAhCjB,CAhCJ,CAmEgB,EAAA1kB,EAAhB,EAA4B+F,CAAA,CAAA,CAAA/F,EAAA,CAAwB,CAAAA,EAAAyiB,GAAxB,CAA5B,EACI,CAAAziB,EAAA/B,QAAA,CAAiB,mBAAjB,CAAuCif,CAAA,CAAckF,CAAd,CAAvC,CAAiE,KAAjE,EAA0EsC,CAAA,CAAY,MAAZ,CAAqB,OAA/F,EAEJ,OAAOA,EAxEX;AAkFAjB,QAAA,GAAgB,CAAhBA,CAAgB,CAACrB,CAAD,CAAW6B,CAAX,CAAkBa,CAAlB,CAChB,CACI,IAAIJ,EAAa,CAAA,CACZT,EAAL,GACI,CAAA1C,EAAA,CAAgBa,CAAhB,CACA,CAD4B,IAC5B,CAAI,CAAAX,EAAJ,EAAyBW,CAAzB,GAAmC,CAAAX,EAAnC,CAAuD,CAAvD,CAFJ,CAIA,KAAIsD,EAAS,CAAb,CACIC,EAAQ,CAAAnE,EAAA,CAAkBuB,CAAlB,CACEtgB,KAAAA,EAAd,GAAIkjB,CAAJ,GAOoB,CAIhB,EAJI5C,CAIJ,EAJoC,EAIpC,EAJwBA,CAIxB,GAHIA,CACA,EADY,EACZ,CAAA2C,CAAA,CAAS,CAAAxE,EAEb,EAAAyE,CAAA,CAAQ,CAAAnE,EAAA,CAAkBuB,CAAlB,CAXZ,CAactgB,KAAAA,EAAd,GAAIkjB,CAAJ,GACQC,CAwBJ,CAxBWD,CAwBX,EAxBoB,EAwBpB,CAvBIE,CAuBJ,CAvBYF,CAuBZ,EAvBqB,CAuBrB,CAvB0B,EAuB1B,CAtBKD,CAsBL,GAtBaA,CAsBb,CAtBsBC,CAsBtB,CAtB8B,GAsB9B,EArBIf,CAAJ,EACI,CAAA5C,EAAA,CAAe4D,CAAf,CAEI,EAFoB,CAEpB,EAFyBC,CAEzB,CAAA,CAAA7D,EAAA,CAAe,CAAf,CAAA,CADA0D,CAAJ,EAAc,CAAAxE,EAAd,CACI,CAAAc,EAAA,CAAe,CAAf,CADJ,CA/tBkBiD,EA+tBlB,CAxvBkBxD,GA2vBlB,EAAIiE,CAAJ,CACI,CAAA1D,EAAA,CAAe,CAAf,CADJ,CApuBkB8C,CAouBlB,CAzvBkBpD,GA4vBlB,EAAIgE,CAAJ,CACI,CAAA1D,EAAA,CAAe,CAAf,CADJ,CAxuBkBgD,CAwuBlB,CAGI,CAAAhD,EAAA,CAAe,CAAf,CAHJ,CAGyB,GAX7B,GAcI,CAAAA,EAAA,CAAe4D,CAAf,CAEA,EAFwB,EAAE,CAAF,EAAOC,CAAP,CAExB,CADA,CAAA7D,EAAA,CAAe,CAAf,CACA,EADqB,GACrB,CAAA,CAAAA,EAAA,CAAe,CAAf,CAAA,EAAsB,CAAAF,EAAtB,CA5uBmBgE,EA4tBvB,CAqBA,CAHIC,CAGJ,CA/uBsBT,CA+uBtB,EAHkBG,CAGlB,EAHsD,CAAC,CAAAxD,EAAAxnB,OAGvD,CAFA,CAAAwnB,EAAA1jB,KAAA,CAAqB,CAAAyjB,EAAAjc,MAAA,EAArB,CAEA,CADAigB,EAAA,CAAAA,CAAA,CAAkBD,CAAlB,CACA,CAAAV,CAAA,CAAa,CAAA,CAzBjB,CA4BA,OAAOA,EAjDX,CA+DApgB,CAAA2W,EAAA,CAAAA,QAAO,EACP,EAqBA3W,EAAAghB,GAAA,CAAAhH,QAAO,CAAC7D,CAAD,CACP,CAEI,IAAA2G,GAAA,CADQ,IAAAnhB,EAAAgb,EAAA9jB,CAAiBsjB,CAAjBtjB,CACR,CAAoB,IAAA6rB,EACpB,KAAAnB,EAAA,EACAwD,GAAA,CAAAA,IAAA,CAAkB,CAAA,CAAlB,CAAyB5K,CAAzB,CAJJ,CAsBA4K;QAAA,GAAY,CAAZA,CAAY,CAACD,CAAD,CAAa3K,CAAb,CACZ,CAII,IAAIhB,EAAUuB,EAAA,CAAA,CAAA/a,EAAA,CASTmlB,EAAL,GAx+JkBzb,CAy+Jd,EAAI,CAAA1J,EAAA2J,MAAJ,CACIwb,CADJ,CAC2BtjB,IAAAA,EAD3B,GACkB2Y,CADlB,EACsE,EADtE,EACwC,CAAAoH,EADxC,EAOQ0D,CACJ,CADkB9L,CAClB,CAD4B,CAAAmI,GAC5B,CAAAwD,CAAA,CAA4B,CAA5B,CAAcG,CAAd,EAvzBkBC,IAuzBlB,EAAiCD,CARrC,CADJ,CAgBIH,EAAJ,GACQ/D,CAMJ,CANgB,CAAAC,EAAAmE,MAAA,EAMhB,CALkB3jB,IAAAA,EAKlB,GALIuf,CAKJ,GAHI,CAAAM,GAGJ,CAHyBN,CAGzB,EAD4B,CAAAQ,EAC5B,CADyD,CACzD,CAAA,CAAAD,GAAA,CAA6BnI,CAPjC,CAcA,KAASwL,CAAT,CADI9tB,CACJ,CADQ,CACR,CAAwB,CAAxB,CAAiB8tB,CAAjB,CAA2BA,CAAA,EAA3B,CACU,CAAA7D,GAAN,CAAuB,CAAvB,EAA4B6D,CAA5B,GAEA9tB,CAFA,EAEK,CAAAwqB,GAAA,CAAmBsD,CAAnB,CAFL,CAQJ9tB,EAAA,EAAK,CAAA6rB,EAEL,IAAalhB,IAAAA,EAAb,GAAI2Y,CAAJ,CACI,CAAA7F,EAAA,CAAW6F,CAAX,CAAA,CAAmBtjB,CADvB,KAKI,IADAsjB,CACI,CADG,CAAAmI,GACH,CAAAzrB,CAAA,EAAK,CAAAuqB,GAAT,CACI,IAAA,CAAsBhD,CAAtB,CAA+B,CAAAoE,GAA/B,CAAiDpE,CAAA,EAAjD,CACI,CAAA9J,EAAA,CAAW8J,CAAX,CAAA,CAAqBvnB,CAGjC,EAAAuqB,GAAA,CAAkBvqB,CAhEtB,CAwGJgS,CAAA,CAfIV,QAAW,EACX,CAEI,IADA,IAAIid,EAAQzkB,CAAA,CAA6B2H,QAA7B,CA5vKLC,OA4vKK,CAAuD,UAAvD,CAAZ,CACS8c,EAAK,CAAd,CAAiBA,CAAjB,CAAwBD,CAAA5rB,OAAxB,CAAsC6rB,CAAA,EAAtC,CAA8C,CAC1C,IAAIC,EAAOF,CAAA,CAAMC,CAAN,CAAX,CACI9F,EAAWhe,CAAA,CAA4B+jB,CAA5B,CACXvd,EAAAA,CAAM,IAAIuX,EAAJ,CAAgBC,CAAhB,CACV3W,EAAA,CAAgCb,CAAhC,CAAqCud,CAArC,CAJ0C,CAFlD,CAcJ,CAmGI9mB;QArFE+mB,GAqFS,CAACC,CAAD,CAAaC,CAAb,CAAqBC,CAArB,CAA8BC,CAA9B,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,UAAN,CAAkBH,CAAlB,CAEA,KAAAhG,GAAA,CAAqBgG,CAAA,MACrB,KAAAI,EAAA,CAAoBJ,CAAA,SACpB,KAAAK,GAAA,CAAoBL,CAAA,SAEpB,KAAAM,GAAA,CAAgBN,CAAA,YAChB,KAAAO,GAAA,CAAgBP,CAAA,aAMhB,KAAAQ,EAAA,CAAcR,CAAA,UACd,KAAAS,EAAA,CAAcT,CAAA,WAWdU,GAAA,CAAAA,IAAA,CAEA,KAAAC,EAAA,CAAoBV,CACpB,KAAAW,EAAA,CAAqBV,CACrB,KAAAC,EAAA,CAAgBA,CASDU,EAAAA,CAAgB,CAAC,EAAD,CAAK,KAAL,CAAY,IAAZ,CAAkB,QAAlB,CAC3BC,EAAAA,CAAad,CAAA,UAEjB,EADIe,CACJ,CADiB5rB,EAAA,CAAe,WAAf,CACjB,IAAgB2rB,CAAhB,CAA4C,MAA5C,EAA8BC,CAA9B,CACA,IAAkB,IAAlB,EAAID,CAAJ,CACI,IAAKlvB,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgBivB,CAAA7sB,OAAhB,CAAsCpC,CAAA,EAAtC,CAOI,GAFI8G,CAEA,CALJ,CADAA,CACA,CADSmoB,CAAA,CAAcjvB,CAAd,CACT,EAGI8G,CAHJ,CAGc,uBAHd,CACa,uBAIT,CAA+BsD,IAAAA,EAA/B,GAAA,IAAA4kB,EAAA,CAAmBloB,CAAnB,CAAJ,CAA8C,CAC1C,IAAAkoB,EAAA,CAAmBloB,CAAnB,CAAA,CAA6BooB,CAC7B,MAF0C,CAnD1D,CAtFmBxe,CAAArJ,CAAjB8mB,EAAiB9mB,CAAAA,CAAAA,CA2JnB,EAAA,CA3wSJ,EAAA+nB,UA2wSIxiB;CAAAiQ,MAAA,CAAAA,QAAK,CAACC,CAAD,CACL,CACI,IAAA0M,GAAA,CAAc,IAAApB,GAAd,CAEA,IAAI,IAAAlL,EAAJ,CAOI,IAAK,IAAI8J,EAAS,IAAAqI,EAAlB,CAAiCrI,CAAjC,CAA0C,IAAAsI,EAA1C,CAA8DtI,CAAA,EAA9D,CAGI,IAAA9J,EAAA,CAAW8J,CAAX,CAAA,CAFSlK,CAAArd,CAAUhB,IAAAmiB,MAAA,CAA2B,GAA3B,CAAWniB,IAAA8wB,OAAA,EAAX,CAAV9vB,CAA4C,EAXjE,CA0BAmN,EAAAvC,EAAA,CAAAA,QAAU,CAACyC,CAAD,CAAYC,CAAZ,CAAsBhE,CAAtB,CACV,CACI,OAAOgE,CAAP,EACA,KAAK,SAAL,CASI,MARA,KAAArF,EAAA,CAAcqF,CAAd,CAQO,CARmBhE,CAQnB,CAPPA,CAAAiE,QAOO,CAPW,QAAQ,CAAC6Q,CAAD,CAAQ,CAC9B,MAAO,SAAQ,EAAG,CAEd2R,EAAA,CAAA3R,CAAA,CACAE,GAAA,CAAAF,CAAA,CAHc,CADY,CAAhB,CAMhB,IANgB,CAOX,CAAA,CAAA,CAVX,CAcA,MAAO,CAAA,CAfX,CAyBAjR,EAAA2Q,GAAA,CAAAA,QAAS,CAACC,CAAD,CAAWhO,CAAX,CAAkBiO,CAAlB,CAAuBlV,CAAvB,CACT,CACI,IAAA2U,EAAA,CAAaM,CACb,KAAA6R,EAAA,CAAgB7f,CAChB,KAAAigB,GAAA,CAAehS,CAAf,CAAqBjO,CAArB,CAA6B,CAC7B,KAAA8f,EAAA,CAAqB,IAAAD,EAArB,CAAqC,IAAAI,GAEjClnB,EAAJ,GACI,IAAAA,EAGI,CAHOA,CAGP,CADA2V,EAAA,CAAA3V,CAAA,CAvEamnB,KAuEb,CAvEaA,KAuEb,CAA0D,IAA1D,CAAgE,IAAAnM,EAAhE,CACA,CAAAhF,CAAA,CAAAhW,CAAA,CAxEamnB,KAwEb,CAxEaA,KAwEb,CAA2D,IAA3D,CAAiE,IAAA9I,GAAjE,CAJR,CAOA,KAAA/J,MAAA,CAAW,CAAA,CAAX,CAbJ,CAuBAiS;QAAA,GAAa,CAAbA,CAAa,CAACa,CAAD,CAAQC,CAAR,CAAeC,CAAf,CAAwBC,CAAxB,CACb,CACI,CAAAH,EAAA,CAAwBvlB,IAAAA,EAAV,GAAAulB,CAAA,CAAqBA,CAArB,CAA6B,CAAAnB,EAC3C,EAAAoB,GAAA,CAAwBxlB,IAAAA,EAAV,GAAAwlB,CAAA,CAAqBA,CAArB,CAA6B,CAAAnB,GAC3C,EAAAsB,EAAA,CAAgB,CAAAJ,EAAhB,CAA6B,CAAAC,GAC7B,EAAAN,EAAA,CAAqB,CAAAD,EAArB,CAAqC,CAAAU,EAIrC,EAAAF,EAAA,CAA4BzlB,IAAAA,EAAZ,GAAAylB,CAAA,CAAuBA,CAAvB,CAAiC,CACjD,EAAAC,GAAA,CAAsC1lB,IAAAA,EAAjB,GAAA0lB,CAAA,CAA4BA,CAA5B,CAA2CF,CAChEI,EAYAC,EAAA,CAAiBxxB,IAAAmiB,MAAA,CAZjBoP,CAY4BtB,GAAX,CAZjBsB,CAY4CL,EAA3B,CAZjBK,EAaAE,EAAA,CAAiBzxB,IAAAmiB,MAAA,CAbjBoP,CAa4BrB,GAAX,CAbjBqB,CAa4CF,GAA3B,CAvBrB,CA6BAljB,CAAAoR,GAAA,CAAAA,QAAQ,EACR,CACI,IAAA+Q,EAAAoB,MAAA,EADJ,CAQAvjB,EAAA4c,GAAA,CAAAA,QAAQ,CAAC6B,CAAD,CACR,CACI,IAAAA,EAAA,CAAcA,CAKK,IAAnB,EAAI,IAAAA,EAAJ,EACIyD,EAAA,CAAAA,IAAA,CAAmB,IAAAN,EAAnB,CAAsC,IAAAC,GAAtC,CAAyD,CAAzD,CAA4D,EAA5D,CACA,CAAqB,IAArB,EAAI,IAAAsB,EAAJ,EAA6B,IAAAxnB,EAA7B,GAQI,IAAA6nB,EACA,CADiB,IAAAd,EACjB,CADsC,IAAAS,EACtC,CADsD,CACtD,CAAAxR,CAAA,CAAA,IAAAhW,EAAA,CAAwB,IAAA6nB,EAAxB,CAAwC,IAAAA,EAAxC,CAAwD,IAAxD,CAA8D,IAAAC,GAA9D,CATJ,CAFJ,GAeI,IAAAjjB,EAAA,CAAa,uBAAb,CAAuC,IAAAie,EAAvC,CACA,CAAAyD,EAAA,CAAAA,IAAA,CAAmB,EAAnB,CAAuB,EAAvB,CAhBJ,CAkBAU,GAAA,CAAAA,IAAA,CACAzR,GAAA,CAAAA,IAAA,CAzBJ,CAiCAnR;CAAAgE,GAAA,CAAAA,QAAQ,CAACC,CAAD,CAAMrI,CAAN,CACR,CAMI,GAAIqI,CAAJ,EAAW,CAAC,IAAAjJ,EAAAK,EAAZ,EAAkC8F,CAAA,CAAAA,IAAA,CAAlC,CAaI,IAZA,IAAAnG,EAAAK,EAWA0I,CAXqB,CAAA,CAWrBA,CAVc,IAAArI,EAUdqI,CAVyBjG,CAAA,CAAAlC,CAAA,CAAuB,UAAvB,CAUzBmI,CAAA,IAAAA,EAAAA,CAAWjG,CAAA,CAAAlC,CAAA,CAAuB,UAAvB,CACX,CACI,IAAAmI,EAAAtG,EAAA,CAAoB,QAApB,CAA8B,SAA9B,CAAyC,IAAA0kB,EAAzC,CAEA,CADA,IAAApe,EAAAtG,EAAA,CAAoB,QAApB,CAA8B,UAA9B,CAA0C,IAAA0kB,EAA1C,CACA,CAAA,IAAApe,EAAAtG,EAAA,CAAoB,QAApB,CAA8B,OAA9B,CAAuC,IAAA0kB,EAAvC,CAHJ,CAbJ,IAoBI,CAACle,CAAL,EAAY,IAAAjJ,EAAAK,EAAZ,GACI,IAAAL,EAAAK,EADJ,CACyB,CAAA,CADzB,CA1BJ,CA6CA2E,EAAAoB,EAAA,CAAAA,QAAQ,EACR,CACS,IAAA4gB,EAAL,GAAkB,IAAAA,EAAlB,CAAgCnwB,IAAAmiB,MAAA,CAAW,IAAA2N,EAAA+B,MAAX,CAAiC,EAAjC,CAAhC,CACK,KAAAzB,EAAL,GAAkB,IAAAA,EAAlB,CAAgCpwB,IAAAmiB,MAAA,CAAW,IAAA2N,EAAAgC,OAAX,CAAkC,EAAlC,CAAhC,CACAviB,EAAAA,UAAAA,EAAAA,KAAAA,CAAAA,IAAAA,CAHJ,CAcApB;CAAA2W,EAAA,CAAAA,QAAO,CAACR,CAAD,CAAOzE,CAAP,CACP,CACI,IAAI7e,EAAI,IAAA8I,EAAAgb,EAAA,CAAiBR,CAAjB,CACS3Y,KAAAA,EAAjB,GAAIkU,CAAJ,EACoB,IAAAhW,EADpB,EAC8Bwe,CAAA,CAAA,IAAAxe,EAAA,CAAmB,IAAnB,CAAyBya,CAAzB,CAA+BzE,CAA/B,CAAyC,IAAAhW,EAAAkoB,GAAzC,CAa9B,KAAAjoB,EA/sIA2U,EAAA,CA+sIiB6F,CA/sIjB,CAAA,CA+sIwBtjB,CA/sIxB,CA+sI4B,GA/sI5B,EA8sIkBhB,IAAAmiB,MAAA6P,CAAWnN,EAAA,CAAA,IAAA/a,EAAA,CAAXkoB,CAAkC,IAAlCA,CACmB,CAAe,CAAf,CAAqB,GAArB,CAA4B,CA/sIjE,CA+rIJ,CAwBA7jB,EAAA8jB,GAAA,CAAA9J,QAAO,CAAC7D,CAAD,CAAOzE,CAAP,CACP,CACqBlU,IAAAA,EAAjB,GAAIkU,CAAJ,EACoB,IAAAhW,EADpB,EAC8Bwe,CAAA,CAAA,IAAAxe,EAAA,CAAmB,IAAnB,CAAyBya,CAAzB,CAA+BzE,CAA/B,CAAyC,IAAAhW,EAAAkoB,GAAzC,CAFlC,CAWA5jB;CAAAyjB,GAAA,CAAAA,QAAS,CAACtN,CAAD,CAAOzE,CAAP,CACT,CAKI,GAAiBlU,IAAAA,EAAjB,GAAIkU,CAAJ,CAA4B,CACR,IAAAhW,EAAhB,EAA0Bwe,CAAA,CAAA,IAAAxe,EAAA,CAAmB,IAAnB,CAAyBya,CAAzB,CAA+BzE,CAA/B,CAAyC,IAAAhW,EAAAkoB,GAAzC,CAAiE,CAAA,CAAjE,CAM1B,KAAAhH,GAAA,CAAc,GAAd,CACI,KAAA7Y,EAAJ,EAAc,IAAAA,EAAA6Y,GAAA,CAAkB,GAAlB,CACdjhB,EAAAA,CAAAA,IAAAA,EAv2J4BkK,EAAAA,CAAAA,CAAAA,EA4ChC,KAAIke,EAAU,EAAd,CACI3wB,EAAIme,EAAA,CAAgBO,CAAhB,CA0zJuB,IAAA0R,EA1zJvB,CA0zJuC,IAAAA,EA1zJvC,CA0zJuD1nB,IA1zJvD,CA0zJ6D,IAAA2nB,GA1zJ7D,CACR,IAAS,CAAT,EAAIrwB,CAAJ,CAAY,CACR2wB,CAAAzqB,KAAA,CAAawY,CAAA,CAAQ1e,CAAR,CAAA,CAAW,CAAX,CAAb,CACA2wB,EAAAzqB,KAAA,CAAawY,CAAA,CAAQ1e,CAAR,CAAA,CAAW,CAAX,CAAb,CACA0e,EAAA3S,OAAA,CAAe/L,CAAf,CAAkB,CAAlB,CAHQ,KAIJ4wB,EAAY,KAJR,CAIiBC,EAAY,CACrC,KAAK7wB,CAAL,CAAO,CAAP,CAAUA,CAAV,CAAc0e,CAAAtc,OAAd,CAA8BpC,CAAA,EAA9B,CACQ4wB,CAEJ,CAFgBlS,CAAA,CAAQ1e,CAAR,CAAA,CAAW,CAAX,CAEhB,GADI4wB,CACJ,CADgBlS,CAAA,CAAQ1e,CAAR,CAAA,CAAW,CAAX,CAChB,EAAI6wB,CAAJ,CAAgBnS,CAAA,CAAQ1e,CAAR,CAAA,CAAW,CAAX,CAAhB,GACI6wB,CADJ,CACgBnS,CAAA,CAAQ1e,CAAR,CAAA,CAAW,CAAX,CADhB,CAGJ2wB,EAAAzqB,KAAA,CAAa0qB,CAAb,CACAD,EAAAzqB,KAAA,CAAa2qB,CAAb,CAZQ,CA7CU,CAAtB,EA2DOF,CA3DHvuB,OAAJ,GACI,CAAAwQ,GACA,CAyDG+d,CA1DmB,CAAQ,CAAR,CACtB,CAAA,CAAA9d,GAAA,CAyDG8d,CAzDmB,CAAQ,CAAR,CAF1B,CA61J4B,CALhC,CAqBAnB,SAAA,GAAU,CAAVA,CAAU,CACV,CACI,CAAAsB,EAAA,CAAoB1hB,KAAJ,CAAU,CAAA2gB,EAAV,CAChB,KAAK,IAAI/I,EAAO,CAAhB,CAAmBA,CAAnB,EAA6B,CAAA+I,EAA7B,CAA4C/I,CAAA,EAA5C,CACI,CAAA8J,EAAA,CAAc9J,CAAd,CAAA,CAAyB,EAHjC;AAkBAjJ,QAAA,GAAY,CAAZA,CAAY,CACZ,CACI,IAAIiJ,EAAS,CACb,IAAI,CAAApf,EAAAK,EAAJ,CACI,IAAA,CAAO+e,CAAP,CAAgB,CAAA+I,EAAhB,CAAA,CAA+B,CAC3B,IAAItwB,EAAI,CAAAyd,EAAA,CAAW,CAAAmS,EAAX,CAA2BrI,CAA3B,CACR,IAAI,CAAA8J,EAAA,CAAc9J,CAAd,CAAJ,EAA6BvnB,CAA7B,CAAgC,CAqB9BsxB,IAAAA,EAAAtyB,IAAAmiB,MAAAmQ,CApBsB/J,CAoBtB+J,CApBOC,CAoBarB,EAApBoB,CA8BV,IAAIA,CAAJ,EAlDiBC,CAkDNnB,EAAX,GACIkB,CACI,EApDSC,CAmDNnB,EACH,CAAAkB,CAAA,CApDSC,CAoDHlB,GAFd,EAEiC,CACzB,IAAImB,EArD4BxxB,CAqD5BwxB,CArDKD,CAqDQpC,EArDRoC,EA2DThC,EAAAkC,UAAA,CA3DSF,CA2DoBzC,EAA7B,CAJW0C,CAIX,CA3DSD,CAuDUzC,EAAA+B,MAInB,CALW7xB,IAAAmiB,MAAA,CAAWqQ,CAAX,CAtDFD,CAsDqBzC,EAAA+B,MAAnB,CAKX,CA3DSU,CAsD4CnC,EAKrD,CA3DSmC,CA2D+CpC,EAAxD,CA3DSoC,CA2D4DnC,EAArE,CA3DwB7H,CA2DxB,CA3DSgK,CAmBErB,EAwCX,CA3DSqB,CAwDQf,EAGjB,CAFWc,CAEX,CA3DSC,CAyDQd,EAEjB,CA3DSc,CA2DqFf,EAA9F,CA3DSe,CA2DqGd,EAA9G,CAPyB,CAjDrB,CAAAY,EAAA,CAAc9J,CAAd,CAAA,CAAwBvnB,CAJI,CAMhCunB,CAAA,EAR2B,CAHvC;AA4JJvV,CAAA,CA7EIV,QAAW,EACX,CAEI,IADA,IAAIogB,EAAU5nB,CAAA,CAA6B2H,QAA7B,CAryLPC,OAqyLO,CAAuD,OAAvD,CAAd,CACSigB,EAAO,CAAhB,CAAmBA,CAAnB,CAA4BD,CAAA/uB,OAA5B,CAA4CgvB,CAAA,EAA5C,CAAsD,CAClD,IAAIC,EAASF,CAAA,CAAQC,CAAR,CAAb,CACIhD,EAAajkB,CAAA,CAA4BknB,CAA5B,CADjB,CAYIC,EAA4CpgB,QAAAqgB,cAAA,CAAuB,QAAvB,CAChD,IAAgBnnB,IAAAA,EAAhB,GAAIknB,CAAJ,EAA6B,CAACA,CAAAE,WAA9B,CAAkD,CAC9CH,CAAAzS,UAAA,CAAmB,kFACnB,MAF8C,CAIlD0S,CAAAG,aAAA,CAAqB,OAArB,CAA8B,cAA9B,CACAH,EAAAG,aAAA,CAAqB,OAArB,CAA8BrD,CAAA,YAA9B,CACAkD,EAAAG,aAAA,CAAqB,QAArB,CAA+BrD,CAAA,aAA/B,CAEAkD,EAAAG,aAAA,CAAqB,iBAArB,CAAwC,MAAxC,CACAH,EAAAG,aAAA,CAAqB,gBAArB,CAAuC,KAAvC,CACAH,EAAAG,aAAA,CAAqB,aAArB,CAAoC,KAApC,CACAH,EAAAI,MAAAC,gBAAA;AAAgCvD,CAAA,YAOhCkD,EAAAI,MAAAnB,OAAA,CAAuB,MACmB,EAA1C,EAAIpwB,CAt3PAqB,MAAA,CAAQA,MAAA0B,UAAAD,UAAR,CAAqC,EAs3PrC9C,SAAA,CAA2B,MAA3B,CAAJ,GACImxB,CAAAI,MAAAnB,OACA,EAD0Bc,CAAAO,YAC1B,CAD+CxD,CAAA,aAC/C,CAD6EA,CAAA,YAC7E,CAD0G,CAC1G,EAD+G,IAC/G,CAAAiD,CAAAQ,SAAA,CAAkB,QAAQ,CAACC,CAAD,CAAUC,CAAV,CAAkBC,CAAlB,CAAsBC,CAAtB,CAA0B,CAChD,MAAO,SAAQ,EAAG,CACdF,CAAAL,MAAAnB,OAAA,EAAyBuB,CAAAF,YAAzB,CAA+CK,CAA/C,CAAqDD,CAArD,CAA2D,CAA3D,EAAgE,IADlD,CAD8B,CAAlC,CAIhBX,CAJgB,CAIRC,CAJQ,CAIClD,CAAA,YAJD,CAI4BA,CAAA,aAJ5B,CAFtB,CAQAiD,EAAAa,YAAA,CAAmBZ,CAAnB,CAUA,KAAIa,EAAa,IAAIC,KAArB,CACIC,EAAoDf,CAAAE,WAAA,CAAmB,IAAnB,CACpD3T,EAAAA,CAAQ,IAAIsQ,EAAJ,CAAaC,CAAb,CAAyBkD,CAAzB,CAAkCe,CAAlC,CAA4CF,CAA5C,CACZA,EAAAG,OAAA,CAAoB,QAAQ,CAACzU,CAAD,CAAkB,CAC1C,MAAO,SAAQ,EAAG,CAEdA,CAAA7P,EAAA,EAFc,CADwB,CAA1B,CAKlB6P,CALkB,CAKXuQ,CAAA,QALW,CAMpB+D,EAAAI,IAAA,CAAiBnE,CAAA,QAMjB5c,EAAA,CAAgCqM,CAAhC,CAAuCwT,CAAvC,CAlEkD,CAF1D,CA4EJ,CAuBIjqB;QATEorB,GASS,CAACC,CAAD,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,eAAN,CAAuBA,CAAvB,CAEA,KAAA7qB,EAAAK,EAAA,CAAqB,CAAA,CACrB,KAAAyqB,EAAA,CAAaD,CAAA,KAEb,KAAA5V,MAAA,CAAW,CAAA,CAAX,CANJ,CAVwBnM,CAAArJ,CAAtBmrB,EAAsBnrB,CAAAA,CAAAA,CAuBxB,EAAA,CA9uTJ,EAAAsrB,UA8uTI/lB,EAAAiQ,MAAA,CAAAA,QAAK,CAAC+V,CAAD,CACL,CAKI,GAAIA,CAAJ,EAAa,IAAAC,EAAb,EAA8BC,EAA9B,CAA2D,CAEvD,IAAAC,EAAA,CAAe,EACf,KAAAC,EAAA,CAAc,CACd,KAAAC,EAAA,CAAc,EACd,IAAI,IAAAP,EAAJ,CAAgB,CA7/MhBQ,CAAAA,CAAW,CACf,IA6/MiDC,IA7/M7CxrB,GAAJ,CAAoB,CAChB,IAAIyrB,EA4/MyCD,IA5/M/BxrB,GAAAxE,MAAA,CAAqB,KAArB,CACE,KAAhB,GAAIiwB,CAAJ,GACIF,CADJ,CACe3L,QAAA,CAAS6L,CAAA,CAAQ,CAAR,CAAT,CAAqB,EAArB,CADf,CAFgB,CA6/MZ,IAAAH,EAAA,CAAc,uBAAd,CAx/MDC,CAw/MC,CAAgE,KADpD,CAOhB,IAAAG,EAAA,CAAkB,CAAA,CAClB,KAAAR,EAAA,CAAgBS,EAbuC,CAL/D,CAyBA1mB,EAAA4C,MAAA,CAAAA,QAAK,EACL,CACQ,IAAAmB,EAAJ,EAAgB,IAAA+hB,EAAhB,GACIzG,EAAA,CAAA,IAAAtb,EAAA,CAAoB,QAApB,CAA8B,GAA9B,CACA,CAAAnM,UAAA,CAAW,QAAQ,CAAC+uB,CAAD,CAAS,CAAE,MAAO,SAAQ,EAAG,CAACA,CA2HrDV,EAAA,CAAgBW,EAChBvH,GAAA,CA5HqDsH,CA4HrD5iB,EAAA,CAAoB,QAApB,CA5HoD,CAApB,CAAjB,CAA8D,IAA9D,CAAX,CAAgF,IAAhF,CAFJ,CAIA,KAAA+hB,EAAA,CAAa,CAAA,CALjB,CAgBA9lB;CAAAvC,EAAA,CAAAA,QAAU,CAACyC,CAAD,CAAYC,CAAZ,CAAsBhE,CAAtB,CACV,CACI,IAAIwqB,EAAS,IAEb,QAAOxmB,CAAP,EAEA,KAAK,YAAL,CAEI,MADA,KAAArF,EAAA,CAAcqF,CAAd,CACO,CADmBhE,CACnB,CAAA,CAAA,CAEX,MAAK,YAAL,CAWI,MAVA,KAAArB,EAAA,CAAcqF,CAAd,CAUO,CAVmBhE,CAUnB,CATPA,CAAAiE,QASO,CATWymB,QAA0B,EAAQ,CAC5CF,CAAA7rB,EAAA,WAAJ,EAGI8e,CAAA,CAFY+M,CAAA7rB,EAAA,WAAAuB,MAEZ,CAAmC,QAAQ,CAACjI,CAAD,CAAOylB,CAAP,CAAkBrlB,CAAlB,CAA8B,CACrEsyB,EAAA,CAAAH,CAAA,CAAgBvyB,CAAhB,CAAsBylB,CAAtB,CAAiCrlB,CAAjC,CADqE,CAAzE,CAJ4C,CAS7C,CAAA,CAAA,CAEX,MAAK,aAAL,CAoCI,MA/BI,CAACuyB,EAAA,EAAL,EAAuBnyB,MAAvB,EAAiC,YAAjC,EAAiDA,OAAjD,EACI,IAAAkG,EAAA,CAAcqF,CAAd,CAUA,CAZsChE,CAYtC,CAZsCA,CAMtC6qB,SAMA,CANwBC,QAA4B,EAAG,CACnD,IAAIC,EAP8B/qB,CAOnBgrB,SAAA,CAAsB,CAAtB,CAEFD,EAAAC,SAAAC,CAAkB,CAAlBA,CACbC,SAAA,CAAkB,CAFNH,CAAAC,SAAA,CAAkB,CAAlB,CAAAG,MAEO9xB,OAJgC,CAMvD,CAZsC2G,CAYtCorB,SAAA,CAAwBC,QAA4B,CAAC9J,CAAD,CAAQ,CACxD,IAAI+J,EAAO/J,CAAAgK,cAAA,CAAoB,CAApB,CAAAJ,MAAA,CAA6B,CAA7B,CAAX,CAEIK,EAAS,IAAIC,UACjBD,EAAAjC,OAAA,CAAgBmC,QAAQ,EAAG,CAEvBf,EAAA,CAAAH,CAAA,CAAgBc,CAAA5sB,KAAhB,CAA2B8sB,CAAAG,OAAA7nB,SAAA,EAA3B;AAAqD,CAArD,CAFuB,CAI3B0nB,EAAAI,WAAA,CAAkBN,CAAlB,CAKA,OAAO,CAAA,CAbiD,CAXhE,EAD0CtrB,CA8BtCS,WAAAorB,YAAA,CA9BsC7rB,CA8BtC,CAEG,CAAA,CAAA,CAvDX,CA4DA,MAAO,CAAA,CA/DX,CAyEA6D,EAAA2Q,GAAA,CAAAA,QAAS,CAACC,CAAD,CAAWhO,CAAX,CAAkBiO,CAAlB,CAAuBlV,CAAvB,CACT,CACI,IAAA2U,EAAA,CAAaM,CACb,KAAAqX,EAAA,CAAerlB,CACf,KAAAslB,EAAA,CAAcrX,CAAd,CAAoBjO,CAApB,CAA4B,CAC5B,KAAAulB,EAAA,CAAoB,IAAAF,EAApB,CAAmC,IAAAC,EACnC,IAAK,IAAAvsB,EAAL,CAAgBA,CAAhB,CACI2V,EAAA,CAAA3V,CAAA,CAAkBiH,CAAlB,CAAyBiO,CAAzB,CAA8B,IAA9B,CAAoC,IAAA8F,EAApC,CACA,CAAAhF,CAAA,CAAAhW,CAAA,CAAmBiH,CAAnB,CAA0BiO,CAA1B,CAA+B,IAA/B,CAAqC,IAAAmJ,GAArC,CAEJ,KAAA5Y,EAAA,EATJ,CAoBApB,EAAAgE,GAAA,CAAAA,QAAQ,CAACC,CAAD,CAAMrI,CAAN,CACR,CACQqI,CAAJ,EAAW,CAAC,IAAAjJ,EAAAK,EAAZ,GACI,IAAAL,EAAAK,EAGc,CAHO,CAAA,CAGP,CAFd,IAAAO,EAEc,CAFHA,CAEG,CADd,IAAAmI,EACc,CADHjG,CAAA,CAAAlC,CAAA,CAAuB,UAAvB,CACG,CAAA,IAAAF,EAAA,CAAWoC,CAAA,CAAAlC,CAAA,CAAuB,UAAvB,CAJ7B,CADJ,CAwBAkrB;QAAA,GAAQ,CAARA,CAAQ,CAAC5zB,CAAD,CAAYk1B,CAAZ,CAAuBC,CAAvB,CACR,CACI,GAAKD,CAAL,CAAA,CAKA,CAAAhC,EAAA,CAAc,CACd,EAAAC,EAAA,CAAc+B,CACd,EAAA3B,EAAA,CAAkB,CAAA,CAClB,EAAAR,EAAA,CAAgBS,EAYhB,IAnyS0D,EAmyS1D,GAAiBxzB,CAnySVK,QAAA,CAmySqB+0B,OAnySrB,CAmySUp1B,CAnySSsC,OAAnB,CAA8BA,CAA9B,CAmySP,CACI,GAAI,CAIIxD,CAAAA,CAAI,EAER,KAAIwoB,EADOtc,IAAAqqB,CAAK,GAALA,CAAWH,CAAXG,CAAuB,GAAvBA,CACF,MACT,KAASn1B,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoBonB,CAAAhlB,OAApB,CAA+BpC,CAAA,EAA/B,CACIpB,CAAA,EAAKQ,MAAAC,aAAA,CAAoB+nB,CAAA,CAAGpnB,CAAH,CAApB,CAET,EAAAizB,EAAA,CAAcr0B,CACd,EAAAy0B,EAAA,CAAkB,CAAA,CAXlB,CAYF,MAAO3uB,CAAP,CAAU,CACR,CAAA0I,EAAA,CAAa,yBAAb,CAA0CtN,CAA1C,CAAsD,KAAtD,CAA+D4E,CAAA6B,QAA/D,CACA,OAFQ,CAMZ,CAAAiC,EAAJ,EAAgB,CAAAmI,EAAhB,EAA4B,CAAApI,EAhnKrBX,EAAAiK,GAgnKP,EACI,CAAAzE,EAAA,CAAa,eAAb,CAA+BtN,CAA/B,CAgBA,CAVA,CAAAyI,EAAAyV,GAAA,EAUA,CAA6B,GAA7B,EAAI,CAAAiV,EAAA9L,OAAA,CAAmB,CAAnB,CAAJ,EACI,CAAA0L,EACA,CADgBW,EAChB,CAAAvH,EAAA,CAAA,CAAAtb,EAAA,CAAoB,aAApB,CAFJ,GASI,CAAAkiB,EASA,CATgBC,EAShB,CADA,CAAAtqB,EAAAqU,MAAA,CAAe,CAAA,CAAf,CACA,CAAAoP,EAAA,CAAA,CAAAtb,EAAA,CAAoB,IAApB,CAlBJ,CAjBJ,EAuCI,CAAAvD,EAAA,CAAatN,CAAb,CAAyB,gBAAzB,CA9EJ,CAAA,IACI,EAAAsN,EAAA,CAAa,sBAAb,CAAuCtN,CAAvC,CAAmD,KAAnD,CAA4Dm1B,CAA5D,CAAwE,GAAxE,CAFR;AAwFAroB,CAAA2W,EAAA,CAAAA,QAAO,CAACR,CAAD,CAAOzE,CAAP,CACP,CAKqBlU,IAAAA,EAAjB,GAAIkU,CAAJ,GAKUyE,CAAN,CAAa,CAAb,CAWIqS,EAAA,CAAAA,IAAA,CAXJ,CAKQ,IAAAnC,EALR,EAKuB,CAAC,IAAAD,EALxB,EAMQoC,EAAA,CAAAA,IAAA,CAXZ,CALJ,CA+BAxoB,EAAAyoB,GAAA,CAAAzO,QAAO,CAAC7D,CAAD,CAAOzE,CAAP,CACP,CAKqBlU,IAAAA,EAAjB,GAAIkU,CAAJ,EACoB,IAAAhW,EADpB,EAC8Bwe,CAAA,CAAA,IAAAxe,EAAA,CAAmB,IAAnB,CAAyBya,CAAzB,CAA+BzE,CAA/B,CAAyC,IAAAhW,EAAAgtB,GAAzC,CAAkE,CAAA,CAAlE,CANlC,CAiBAF,SAAA,GAAY,CAAZA,CAAY,CACZ,CACI,GAAoBhrB,IAAAA,EAApB,GAAI,CAAA6oB,EAAJ,CAA+B,CAC3B,CAAAF,EAAA,CAAe,EACf,IAAI,CAAAC,EAAJ,CAAkB,CAAAC,EAAA7wB,OAAlB,CAAsC,CAClC,IAAI3C,EAAI,CAAAwzB,EAAA3G,WAAA,CAAuB,CAAA0G,EAAA,EAAvB,CAAJvzB,CAA4C,GAC5C,EAAA4zB,EAAJ,EACa,EADb,EACQ5zB,CADR,GACmBA,CADnB,CACuB,EADvB,CAGA,EAAAszB,EAAA,CAActzB,CALoB,CAAtC,IASI,EAAAwzB,EAMA,CANc,EAMd,CALA,CAAAD,EAKA,CALc,CAKd,CAHI,CAAAH,EAGJ,EAHqBW,EAGrB,EAHqD,CAAA7iB,EAGrD,EAFIsb,EAAA,CAAA,CAAAtb,EAAA,CAAoB,UAApB,CAEJ,CAAA,CAAAkiB,EAAA,CAAgBS,EAgBxB,KAAKtM,CAAL,CAdI2G,CAcUkH,EAAd,CAA2B,CAA3B,CAA8B7N,CAA9B,CAdI2G,CAcmCoH,EAAvC,CAA0D/N,CAA1D,EAAkE,CAAlE,CAdI2G,CAeAzQ,EAAA,CAAW8J,CAAX,CAAA,CAAqC,CAAf,EAftB2G,CAesBoF,EAAA,CAAkBwC,EAAlB,CAA8CC,EAKxE,KAAKxO,CAAL,CApBI2G,CAoBUkH,EAAd,CAA2B,CAA3B,CAA8B7N,CAA9B,CApBI2G,CAoBmCoH,EAAvC,CAA0D/N,CAA1D,EAAkE,CAAlE,CApBI2G,CAqBAzQ,EAAA,CAAW8J,CAAX,CAAA,CAAqC,CAAf,EArBtB2G,CAqBsBoF,EAAA,CArBtBpF,CAqBwCoF,EAAlB,CAAgC,CAxC3B,CADnC,CAiEJ,IAAAyC,GAA8B,CAA9B,CACAD,GAA8B,CAD9B,CAUAjC,GAA+B,CAV/B,CAWAE,GAA+B,CAX/B,CAYAV,GAA+B,CAK/BrhB;CAAA,CA7BIV,QAAW,EACX,CAEI,IADA,IAAI0kB,EAAWlsB,CAAA,CAA6B2H,QAA7B,CA3vMRC,OA2vMQ,CAAuD,QAAvD,CAAf,CACSukB,EAAQ,CAAjB,CAAoBA,CAApB,CAA8BD,CAAArzB,OAA9B,CAA+CszB,CAAA,EAA/C,CAA0D,CACtD,IAAIC,EAAUF,CAAA,CAASC,CAAT,CAAd,CACIjD,EAActoB,CAAA,CAA4BwrB,CAA5B,CACdpC,EAAAA,CAAS,IAAIf,EAAJ,CAAkBC,CAAlB,CACbjhB,EAAA,CAAgC+hB,CAAhC,CAAwCoC,CAAxC,CAJsD,CAF9D,CA4BJ,CA+MIvuB,SAtLEwuB,GAsLS,CAACC,CAAD,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,mBAAN,CAA2BA,CAA3B,CAEA,KAAAjuB,EAAAK,EAAA,CAAqB,CAAA,CAqNrB,KAAA4U,MAAA,CAAW,CAAA,CAAX,CAxNJ,CAvL4BnM,CAAArJ,CAA1BuuB,EAA0BvuB,CAAAA,CAAAA,CAsZ5B,EAAA,CA9hVJ,EAAAyuB,UA8hVIlpB,EAAAiQ,MAAA,CAAAA,QAAK,CAACC,CAAD,CACL,CACIiZ,EAAA,CAAAA,IAAA,CACA,KAAAC,EAAA,CAAqB,EACjBlZ,EAAJ,GACI,IAAAmZ,EAyLJ,CAzLmB,EAyLnB,CAxLIC,IAwLJD,EAAA,CAxLoBE,CAwLpB,CAAA,CAAuB,CACnBC,GAhUmBC,CA+TA,CAEnBC,GA9TmBC,EA4TA,CAGnBC,GAAY,CAAA,CAHO,CAInBC,GAAa,EAJM,CAKnBC,GAAc,CALK,CAMnBC,GAAe,EANI,CAWnBC,GAAS,EAXU,CA1LvB,CAHJ,CAYAb;QAAA,GAAS,CAATA,CAAS,CACT,CACI,CAAAc,EAAA,CAAc,CACVC,EAvMcC,EAsMJ,CAEVC,KAAMA,QAAQ,EAAG,EAFP,CAGV/Y,OAAQ,QAAQ,CAACgZ,CAAD,CAAa,CACzB,MAAO,SAAQ,CAACx3B,CAAD,CAAI,CACL2K,IAAAA,EAAV,GAAI3K,CAAJ,GAAqB,IAAAq3B,EAArB,CAAiCr3B,CAAjC,CACMw3B,EAAAC,EAAAJ,EAAN,CA5NMK,CA4NN,EACIC,CAAA,CAAAH,CAAA,CAxOEI,CAwOF,CAA0C,IAA1C,CAHW,CADM,CAArB,CAON,CAPM,CAHE,CAYd,EAAAC,EAAA,CAAc,CACVR,EAAM,GADI,CAEVE,KAAMA,QAAQ,EAAG,CACb,IAAA/Y,OAAA,EADa,CAFP,CAKVA,OAAQ,QAAQ,CAACgZ,CAAD,CAAa,CACzB,MAAO,SAAQ,CAACx3B,CAAD,CAAI,CAgmBd2K,IAAAA,EAAb,GAAImtB,CAAJ,CACIA,CADJ,CA/lBwBN,CAgmBbK,EAAAR,EADX,CAGIU,EAAA,CAlmBoBP,CAkmBpB,CAAsBM,CAAtB,CAlmBoBN,CAkmBQQ,EAAAX,EAA5B,CAYJS,EAAA,EADAA,CACA,CADS,GACT,EAAQ,EAER,IAAyB,CAAzB,EAhnBwBN,CAgnBpBjB,EAAJ,EAhnBwBiB,CAknBhBhB,EAAA,CAlnBgBgB,CAknBHjB,EAAb,CAAAY,GAAAx0B,OAFR,CAEwD,CAEhD,IAAIs1B,EApnBYT,CAonBJhB,EAAA,CApnBIgB,CAonBSjB,EAAb,CAER0B,EAAAlB,GAAJ,GACIe,CADJ,EACY,GADZ,CAGKG,EAAAhB,GAAL,GACIa,CADJ,EACY,EADZ,CAM2B,GAA3B,EAAI,EAAEG,CAAAjB,GAAN,GAC4B,CAAxB,CAAIiB,CAAAjB,GAAJ,EACIc,CACA,EADQ,IACR,CAAAI,EAAA,CAloBQV,CAkoBR,CAFJ,GAIIS,CAAAjB,GA5FhB,CA4FoC,GA5FpC,CAAyB,CAAzB,EAxiBwBQ,CAwiBpBjB,EAAJ,GAxiBwBiB,CAyiBpBhB,EAAA,CAziBoBgB,CAyiBPjB,EAAb,CAAAW,GACA,CAD+C,CAC/C,CAAAiB,EAAA,CA1iBoBX,CA0iBpB,CAFJ,CAwFY,CADJ,CAbgD,CAlnB5C,IAAAH,EAAA,CA0oBLS,CAzoBSN,EAAAC,EAAAJ,EAAJ,CA1OMK,CA0ON,EACIC,CAAA,CAAAH,CAAA,CAvPEY,CAuPF,CAA0C,IAA1C,CAHW,CADM,CAArB,CAON,CAPM,CALE,CAcd,EAAAX,EAAA,CAAc,CACVJ,EAAM,CADI,CAEVE,KAAMA,QAAQ,EAAG,EAFP,CAGV/Y,OAAQ,QAAQ,CAACgZ,CAAD,CAAa,CACzB,MAAO,SAAQ,CAACx3B,CAAD,CAAI,CAQL2K,IAAAA,EAAV;AAAI3K,CAAJ,GAAqB,IAAAq3B,EAArB,CAAkCr3B,CAAlC,CAAsC,IAAtC,CACA23B,EAAA,CAAAH,CAAA,CAvQMa,CAuQN,CAA0C,IAA1C,CAKAb,EAAAK,EAAArZ,OAAA,EACAgZ,EAAAJ,EAAA5Y,OAAA,EAfe,CADM,CAArB,CAkBN,CAlBM,CAHE,CAuBd,EAAA8Z,EAAA,CAAc,CACVjB,EAAM,GADI,CAEVE,KAAMA,QAAQ,EAAG,EAFP,CAGV/Y,OAAQ,QAAQ,CAACgZ,CAAD,CAAa,CACzB,MAAO,SAAQ,CAACx3B,CAAD,CAAI,CACL2K,IAAAA,EAAV,GAAI3K,CAAJ,GAAqB,IAAAq3B,EAArB,CAAiCr3B,CAAjC,CACMw3B,EAAAe,EAAAlB,EAAN,CA7QMK,CA6QN,EACIC,CAAA,CAAAH,CAAA,CArREgB,CAqRF,CAA0C,IAA1C,CAHW,CADM,CAArB,CAON,CAPM,CAHE,CAYd,EAAAR,EAAA,CAAc,CACVX,EAAM,GADI,CAEVE,KAAMA,QAAQ,EAAG,EAFP,CAGV/Y,OAAQ,QAAQ,CAACgZ,CAAD,CAAa,CACzB,MAAO,SAAQ,CAACx3B,CAAD,CAAI,CA4mBd2K,IAAAA,EAAb,GAAI8tB,CAAJ,CACIA,CADJ,CA3mBwBjB,CA4mBbQ,EAAAX,EADX,CAGIU,EAAA,CA9mBoBP,CA8mBpB,CA9mBoBA,CA8mBEK,EAAAR,EAAtB,CAAwCoB,CAAxC,CAEJ,IAAyB,CAAzB,EAhnBwBjB,CAgnBpBjB,EAAJ,EAhnBwBiB,CAgnBMjB,EAA9B,CAhnBwBiB,CAgnB0BhB,EAAA7zB,OAAlD,CAAuE,CAEnE,IAAIs1B,EAlnBgBT,CAknBRhB,EAAA,CAlnBQgB,CAknBKjB,EAAb,CAER0B,EAAAd,GAAAx0B,OAAJ,EApnBoB60B,CAwnBXQ,EAAAX,EAJT,CAt3BcqB,CAs3Bd,EAI4C,EAAED,CAAF,CA13B9BC,CA03B8B,CAJ5C,GAQYD,CAAJ,CA/3BME,CA+3BN,CACIV,CAAAhB,GAAA,EADJ,CAGIgB,CAAAhB,GAAA,EAeJ,CA9oBYO,CAioBI3uB,EAahB,EAb4B+F,CAAA,CAjoBhB4oB,CAioBgB3uB,EAAA,CAjoBhB2uB,CAioBwC3uB,EAAA+vB,GAAxB,CAa5B,EA9oBYpB,CAkoBR3uB,EAAA/B,QAAA,CAAiB,WAAjB,EAAiC2xB,CAAD,CAr4B9BE,CAq4B8B,CAAuB,MAAvB,CAAgC,IAAhE,EAAwE,YAAxE,CAAuFV,CAAAhB,GAAvF,CAYJ,CATIgB,CAAAhB,GASJ,EAT0BgB,CAAApB,GAS1B,GARIoB,CAAAhB,GAQJ,CARyBgB,CAAApB,GAQzB,EANyB,CAMzB,CANIoB,CAAAhB,GAMJ,GALIgB,CAAAhB,GAKJ,CALyB,CAKzB,EAHAgB,CAAAjB,GAGA,CAHoB,EAGpB;AA9oBYQ,CA6oBZK,EAAArZ,OAAA,CA7oBYgZ,CA6oBOK,EAAAR,EAAnB,CAp5BMwB,GAo5BN,CACA,CAAAX,EAAA,CA9oBYV,CA8oBZ,CA1BR,CAJmE,CAhnB3D,IAAAH,EAAA,CAqpBLoB,CAppBSjB,EAAAe,EAAAlB,EAAJ,CAzRMK,CAyRN,EACIC,CAAA,CAAAH,CAAA,CAlSEsB,CAkSF,CAA0C,IAA1C,CAHW,CADM,CAArB,CAON,CAPM,CAHE,CAYd,EAAAP,EAAA,CAAc,CACVlB,EAAM,CADI,CAEVE,KAAMA,QAAQ,EAAG,EAFP,CAGV/Y,OAAQ,QAAQ,CAACgZ,CAAD,CAAa,CACzB,MAAO,SAAQ,CAACx3B,CAAD,CAAI,CAQL2K,IAAAA,EAAV,GAAI3K,CAAJ,GAAqB,IAAAq3B,EAArB,CAAkCr3B,CAAlC,CAAsC,IAAtC,CACA23B,EAAA,CAAAH,CAAA,CAlTMuB,CAkTN,CAA0C,IAA1C,CAKAvB,EAAAQ,EAAAxZ,OAAA,EACAgZ,EAAAc,EAAA9Z,OAAA,EAfe,CADM,CAArB,CAkBN,CAlBM,CAHE,CAuBd,EAAAwa,EAAA,CAAe,CACX3B,EAAM,CADK,CAEXE,KAAMA,QAAQ,EAAG,EAFN,CAGX/Y,OAAQ,QAAQ,CAACgZ,CAAD,CAAa,CACzB,MAAO,SAAQ,CAACx3B,CAAD,CAAI,CACL2K,IAAAA,EAAV,GAAI3K,CAAJ,GAtQMi5B,CA6QF,GANKj5B,CAML,CA7QEi5B,CA6QF,IAFIzB,CAAA0B,EAAA7B,EAEJ,CAF+B,EAE/B,EAAA,IAAAA,EAAA,CAAYr3B,CAPhB,CAUAw3B,EAAA0B,EAAA1a,OAAA,EAXe,CADM,CAArB,CAcN,CAdM,CAHG,CAmBf,EAAA0a,EAAA,CAAe,CACX7B,EAAO,EADI,CAEXE,KAAMA,QAAQ,EAAG,EAFN,CAGX/Y,OAAQ,QAAQ,CAACgZ,CAAD,CAAa,CACzB,MAAO,SAAQ,CAACx3B,CAAD,CAAI,CA4mBb2K,IAAAA,EAAd,GAAIwuB,CAAJ,GACIA,CADJ,CA3mBwB3B,CA4mBZ0B,EAAA7B,EADZ,CAEA8B,EAAA,EAAS,EACgB,EAAzB,EA9mBwB3B,CA8mBpBjB,EAAJ,EAA8E,CAA9E,EA9mBwBiB,CA8mBMhB,EAAA,CA9mBNgB,CA8mBmBjB,EAAb,CAAAW,GAA9B,GACIiC,CADJ,EAl4BkBC,CAk4BlB,CA9mBY,KAAA/B,EAAA,CAgnBL8B,CA/mBKxB,EAAA,CAAAH,CAAA,CA7RK6B,EA6RL,CAA2C,IAA3C,CAFe,CADM,CAArB,CAKN,CALM,CAHG,CAUf,EAAAC,EAAA,CAAe,CACXjC,EAAM,CADK,CAEXE,KAAM,QAAQ,CAACC,CAAD,CAAa,CACvB,MAAO,SAAQ,EAAG,CACdW,EAAA,CAAAX,CAAA,CADc,CADK,CAArB,CAIJ,CAJI,CAFK;AAOXhZ,OAAQ,QAAQ,CAACgZ,CAAD,CAAa,CACzB,MAAO,SAAQ,CAACx3B,CAAD,CAAI,CACL2K,IAAAA,EAAV,GAAI3K,CAAJ,GAAqB,IAAAq3B,EAArB,CAAiCr3B,CAAjC,CACA23B,EAAA,CAAAH,CAAA,CA1SK+B,EA0SL,CAA2C,IAA3C,CAFe,CADM,CAArB,CAKN,CALM,CAPG,CAcf,EAAAC,EAAA,CAAkB,CACdnC,EAAM,CADQ,CAEdE,KAAMA,QAAQ,EAAG,EAFH,CAGd/Y,OAAQ,QAAQ,EAAa,CACzB,MAAO,SAAQ,EAAI,EADM,CAArB,CAEN,CAFM,CAHM,CA5ItB;AAuMArR,CAAAvC,EAAA,CAAAA,QAAU,CAACyC,CAAD,CAAYC,CAAZ,CAAsBhE,CAAtB,CACV,CACI,OAAOgE,CAAP,EAEA,KAAK,UAAL,CAEI,MADA,KAAArF,EAAA,CAAcqF,CAAd,CACO,CADmBhE,CACnB,CAAA,CAAA,CAEX,MAAK,UAAL,CA8BI,MA7BA,KAAArB,EAAA,CAAcqF,CAAd,CA6BO,CA7BmBhE,CA6BnB,CA5BPA,CAAAiE,QA4BO,CA5BW,QAAQ,CAACiqB,CAAD,CAAa,CACnC,MAAO,SAAQ,EAAG,CACd,GAAIA,CAAAvvB,EAAA,SAAJ,CAAqC,CACjC,IAAIwxB,EAAYjC,CAAAvvB,EAAA,SAAAuB,MAAhB,CACIgd,EAAWiT,CAO6B,QAA5C,EAAIA,CAAAh5B,OAAA,CAAiBg5B,CAAA92B,OAAjB,CAAkC,CAAlC,CAAJ,GAQI6jB,CARJ,CAQe,SARf,CAQ2BzkB,MAAAa,SAAAgkB,KAR3B,CAQkD,uBARlD,CAQyE6S,CARzE,CAUAjC,EAAA7pB,EAAA,CAAmB,WAAnB,CAAiC+rB,EAAA,CAAgBD,CAAhB,CAAjC,CAA8D,KAA9D,CACA1S,EAAA,CAAgBP,CAAhB,CAAsC,QAAQ,CAACjlB,CAAD,CAAOylB,CAAP,CAAkBrlB,CAAlB,CAA8B,CACxEg4B,EAAA,CAAAnC,CAAA,CAAoBj2B,CAApB,CAA0BylB,CAA1B,CAAqCrlB,CAArC,CADwE,CAA5E,CApBiC,CADvB,CADiB,CAArB,CA2BhB,IA3BgB,CA4BX,CAAA,CAAA,CApCX,CAyCA,MAAO,CAAA,CA1CX,CAoDAwL,EAAA2Q,GAAA,CAAAA,QAAS,CAACC,CAAD,CAAWhO,CAAX,CAAkBiO,CAAlB,CAAuBlV,CAAvB,CACT,CACI,IAAA2U,EAAA,CAAaM,CACb,KAAA6b,EAAA,CAAsB7pB,CAEtB,IAAK,IAAAjH,EAAL,CAAgBA,CAAhB,CACI2V,EAAA,CAAA3V,CAAA,CAAkBiH,CAAlB,CAAyBiO,CAAzB,CAA8B,IAA9B,CAAoC,IAAA8F,EAApC,CACA,CAAAhF,CAAA,CAAAhW,CAAA,CAAmBiH,CAAnB,CAA0BiO,CAA1B,CAA+B,IAA/B,CAAqC,IAAAmJ,GAArC,CAEJ,KAAA5Y,EAAA,EARJ,CAmBApB;CAAAgE,GAAA,CAAAA,QAAQ,CAACC,CAAD,CAAMrI,CAAN,CACR,CACQqI,CAAJ,EAAW,CAAC,IAAAjJ,EAAAK,EAAZ,GACI,IAAAL,EAAAK,EACc,CADO,CAAA,CACP,CAAA,IAAAK,EAAA,CAAWoC,CAAA,CAAAlC,CAAA,CAAuB,UAAvB,CAF7B,CADJ,CAqBA4wB;QAAA,GAAQ,CAARA,CAAQ,CAACE,CAAD,CAAYC,CAAZ,CAAuBn4B,CAAvB,CACR,CACI,GAAIA,CAAJ,CACI,CAAAgM,EAAA,CAAa,mBAAb,CAAmChM,CAAnC,CAAgD,GAAhD,CADJ,KAAA,CAIIo4B,CAAAA,CAAS,EACb,EAAApsB,EAAA,CAAa,WAAb,CAA2BksB,CAA3B,CAAuC,KAAvC,CACA,IAAI,CAMA,GADAE,CACKp3B,CADI0I,IAAA,CAAK,GAAL,CAAWyuB,CAAX,CAAuB,GAAvB,CACJn3B,CAAAo3B,CAAAp3B,OAAL,CAIA,GAAKo3B,CAAA,CAAO,CAAP,CAAAp3B,OAAL,CAAA,CAIA,IAAIw0B,EAAU4C,CAAA,CAAO,CAAP,CACd,IAA+BpvB,IAAAA,EAA/B,GAAIwsB,CAAA,CAAQ,CAAR,CAAA,SAAJ,CACI,CAAAxpB,EAAA,CAAa,cAAb,CAA8BwpB,CAAA,CAAQ,CAAR,CAA9B,CADJ,KAQA,IAAK,CAAAX,EAAA,CAAa,CAAb,CAAL,CAAA,CAQA,IAASwD,CAAT,CAAgB,CAAhB,CAAmBA,CAAnB,CAA4B7C,CAAAx0B,OAA5B,CAA4Cq3B,CAAA,EAA5C,CAAsD,CAClD,IAAIC,CAAJ,CACIC,EAAQ/C,CAAA,CAAQ6C,CAAR,CADZ,CAEIG,EAAUD,CAAA,QAKd,IAAwCvvB,IAAAA,EAAxC,IAAKsvB,CAAL,CAAiBC,CAAA,SAAjB,GAAiEvvB,IAAAA,EAAjE,GAAqDwvB,CAArD,CACI,KAAUC,MAAJ,CAAU,QAAV,CAAqBJ,CAArB,CAA8B,eAA9B,CAAN,CAMAC,CAAJ,EAAiBD,CAAjB,EA3tQRnzB,CAAA,CA4tQ8B,QA5tQ9B,CA4tQyCozB,CA5tQzC,CA4tQqD,0BA5tQrD,CA4tQkFD,CA5tQlF,CA4tQ2F,GA5tQ3F,CAouQYK,EAAAA,CAAY,EAxBkC,KAwBV95B,CACxC,IAAK05B,CAAL,CASK,CACDK,EAAA,CAAaD,CAAb,CAAwBH,CAAxB,CAA+B,UAA/B,CACAK,GAAA,CAAaF,CAAb,CAAwBH,CAAxB,CACAM,EAAA,CAAaH,CAAb,CAAwBH,CAAxB,CAA+B,WAA/B,CACA,KAAK,IAAIO,EAAQ,CAAjB,CAAoBA,CAApB,CAA8BN,CAAAx3B,OAA9B,CAA8C83B,CAAA,EAA9C,CAAyD,CACrD,IAAAC,EAASP,CAAA,CAAQM,CAAR,CACT;IAAAE,EAAaD,CAAA,WACbF,EAAA,CAAaH,CAAb,CAAwBK,CAAxB,CAAgC,WAAhC,CACAF,EAAA,CAAaH,CAAb,CAAwBK,CAAxB,CAAgC,WAAhC,CACAF,EAAA,CAAaH,CAAb,CAAwBK,CAAxB,CAAgC,aAAhC,CACA,KAAKn6B,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgBo6B,CAAAh4B,OAAhB,CAAmCpC,CAAA,EAAnC,CACI85B,CAAA5zB,KAAA,CAAek0B,CAAA,CAAWp6B,CAAX,CAAf,CAEJ+5B,GAAA,CAAaD,CAAb,CAAwBK,CAAxB,CAAgC,cAAhC,CATqD,CAJxD,CATL,IAKI,KAJAA,CAIK,CAJIP,CAAA,CAAQ,CAAR,CAIJ,CAHLQ,CAGK,CAHQD,CAAA,WAGR,CAFLF,CAAA,CAAaH,CAAb,CAAwBH,CAAxB,CAA+B,WAA/B,CAA4C,CAA5C,CAEK,CADLM,CAAA,CAAaH,CAAb,CAAwBK,CAAxB,CAAgC,aAAhC,CACK,CAAAn6B,CAAA,CAAI,CAAT,CAAYA,CAAZ,CAAgBo6B,CAAAh4B,OAAhB,CAAmCpC,CAAA,EAAnC,CACI85B,CAAA5zB,KAAA,CAAek0B,CAAA,CAAWp6B,CAAX,CAAf,CAsBR42B,EAAA,CAAQ8C,CAAR,CAAAI,GAAA,CAA+BA,CACf,EAAAxxB,EAAhB,EAA4B+F,CAAA,CAAA,CAAA/F,EAAA,CAAwB,CAAAA,EAAA+vB,GAAxB,CAA5B,EACI,CAAA/vB,EAAA/B,QAAA,CAAiB,QAAjB,CAA4BmzB,CAA5B,CAAwC,IAAxC,CAA+CI,CAAA13B,OAA/C,CAAkE,QAAlE,CAvD8C,CA0DtD,CAAA6zB,EAAA,CAAa,CAAb,CAAAW,GAAA,CAA0BA,CAC1B,EAAAxpB,EAAA,CAAa,WAAb,CAA2BksB,CAA3B,CAAuC,WAAvC,CAnEA,CAAA,IACI,EAAAlsB,EAAA,CAAa,qBAAb,CAdJ,CAAA,IACI,EAAAA,EAAA,CAAa,aAAb,CAA6BksB,CAA7B,CALJ,KACI,EAAAlsB,EAAA,CAAa,WAAb,CAA2BksB,CAA3B,CAPJ,CA2FF,MAAO50B,CAAP,CAAU,CACR,CAAA0I,EAAA,CAAa,mBAAb,CAAmC1I,CAAA6B,QAAnC,CADQ,CAjGZ,CADJ;AA6GAyzB,QAAA,GAAO,CAACK,CAAD,CAAIC,CAAJ,CACP,CACQj8B,CAAAA,CAAIi8B,CAAA,SACR,IAAUlwB,IAAAA,EAAV,GAAI/L,CAAJ,CACI,KAAUw7B,MAAJ,CAAU,6BAAV,CAAN,CAGJQ,CAAAn0B,KAAA,CADWzH,IAAAmiB,MAAA,CAAWviB,CAAX,CAAe,EAAf,CACX,EADiC,CACjC,CADuCA,CACvC,CAD2C,EAC3C,CANJ,CAgBA47B,QAAA,EAAO,CAACI,CAAD,CAAIC,CAAJ,CAAOC,CAAP,CAAUC,CAAV,CACP,CACQn8B,CAAAA,CAAIi8B,CAAA,CAAEC,CAAF,CACR,IAAUnwB,IAAAA,EAAV,GAAI/L,CAAJ,CACI,KAAUw7B,MAAJ,CAAU,wBAAV,CAAqCU,CAArC,CAAN,CAEM,CAAV,EAAIC,CAAJ,EACIH,CAAAn0B,KAAA,CAAQ7H,CAAR,EAAa,CAAb,CAAkB,GAAlB,CAEJg8B,EAAAn0B,KAAA,CAAO7H,CAAP,CAAW,GAAX,CARJ,CAiBA07B,QAAA,GAAO,CAACM,CAAD,CAAIC,CAAJ,CAAOC,CAAP,CACP,CACQ37B,CAAAA,CAAI07B,CAAA,CAAEC,CAAF,CACR,IAAUnwB,IAAAA,EAAV,GAAIxL,CAAJ,CACI,KAAUi7B,MAAJ,CAAU,qBAAV,CAAkCU,CAAlC,CAAN,CAEJ,IAASv6B,CAAT,CAAW,CAAX,CAAcA,CAAd,CAAkBpB,CAAAwD,OAAlB,CAA4BpC,CAAA,EAA5B,CACIq6B,CAAAn0B,KAAA,CAAOtH,CAAA0tB,WAAA,CAAatsB,CAAb,CAAP,CANR;AAgBAy6B,QAAA,GAAM,CAANA,CAAM,CAACC,CAAD,CAAOC,CAAP,CACN,CAEID,CAAA,EAAQ,EAMG,GAAX,CAAIA,CAAJ,CACIA,CADJ,EACY,CADZ,CAEgB,EAFhB,CAESA,CAFT,GAGIA,CAHJ,EAGY,EAHZ,CAIA,QAAOA,CAAP,EACA,KAvrBkB7C,CAurBlB,CACI7S,CAAA,CAAO,CAAAkS,EAAAJ,EAAD,CA5qBQK,CA4qBR,CAAqC,CAAAG,EAArC,CAAmD,CAAAT,EACzD,MACJ,MAxrBkBiB,CAwrBlB,CACI9S,CAAA,CAAM,CAAAkS,EACN,MACJ,MAzrBkBqB,CAyrBlB,CACIvT,CAAA,CAAO,CAAAgT,EAAAlB,EAAD,CAlrBQK,CAkrBR,CAAqC,CAAAM,EAArC,CAAmD,CAAAM,EACzD,MACJ,MA1rBkBS,CA0rBlB,CACIxT,CAAA,CAAM,CAAAgT,EACN,MACJ,MAtoBiB4C,EAsoBjB,CACI5V,CAAA,CAAO2V,CAAA,CAAQ,CAAAlC,EAAR,CAAuB,CAAAE,EAC9B,MACJ,MAvoBiBK,EAuoBjB,CACIhU,CAAA,CAAM,CAAA+T,EACN,MACJ,SACI/T,CAAA,CAAM,CAAAiU,EApBV,CAuBA,MAAOjU,EAnCX,CA2CApY,CAAA2W,EAAA,CAAAA,QAAO,CAACR,CAAD,CAAOzE,CAAP,CACP,CAKI,GAAiBlU,IAAAA,EAAjB,GAAIkU,CAAJ,CAA4B,CAExB,IAAI0G,EAAMyV,EAAA,CAAAA,IAAA,CADC1X,CACD,CADQ,IAAAsW,EACR,CAAkB,CAAA,CAAlB,CACM,KAAA/wB,EAAhB,EAA0Bwe,CAAA,CAAA,IAAAxe,EAAA,CAAmB,IAAnB,CAAyBya,CAAzB,CAA+BzE,CAA/B,CAAyC,IAAAhW,EAAA+vB,GAAzC,CAAgE,CAAA,CAAhE,CAAuErT,CAAA6V,GAAvE,CAC1B7V,EAAAgS,KAAA,EAJwB,CALhC,CAkBApqB;CAAAkuB,GAAA,CAAAlU,QAAO,CAAC7D,CAAD,CAAOzE,CAAP,CACP,CAKI,GAAiBlU,IAAAA,EAAjB,GAAIkU,CAAJ,CAA4B,CACxB,IAAI7e,EAAI,IAAA8I,EAAAgb,EAAA,CAAiBR,CAAjB,CAAR,CAEIiC,EAAMyV,EAAA,CAAAA,IAAA,CADC1X,CACD,CADQ,IAAAsW,EACR,CAAkB,CAAA,CAAlB,CACV,IAAgB,IAAA/wB,EAAhB,EAA4B+F,CAAA,CAAA,IAAA/F,EAAA,CAAwB,IAAAA,EAAA+vB,GAAxB,CAAgD,IAAA/vB,EAAAye,GAAhD,CAA5B,GACID,CAAA,CAAA,IAAAxe,EAAA,CAAmB,IAAnB,CAAyBya,CAAzB,CAA+BzE,CAA/B,CAAyC,IAAAhW,EAAA+vB,GAAzC,CAAgE,CAAA,CAAhE,CAAsErT,CAAA6V,GAAtE,CACIE,CAAA/V,CAAA+V,GAFR,EAKQ,IAFIC,CACAC,CADQ,GACRA,CAAAA,CAAAA,CAAWjW,CAAA8R,EAAXmE,CAAsBx7B,CAC1B,CAAOw7B,CAAP,EAAmBD,CAAnB,CAAA,CACQC,CAGJ,CAHeD,CAGf,EAFI,IAAA1yB,EAAA/B,QAAA,CAAiB,YAAjB,CAAgCye,CAAA6V,GAAhC,CAA4C,GAA5C,CAAkD7V,CAAA+V,GAAA,CAAYC,CAAZ,CAAlD,CAAuE,MAAvE,EAAkFv7B,CAAD,CAAKu7B,CAAL,CAAa,GAAb,CAAmB,GAApG,EAEJ,CAAAA,CAAA,GAAU,CAItBhW,EAAA/G,OAAA,CAAWxe,CAAX,CAjBwB,CALhC,CA+BA+3B,SAAA,GAAgB,CAAhBA,CAAgB,CAACD,CAAD,CAAOW,CAAP,CAChB,CACI,IAAIlC,EAAgB,EACP5rB,KAAAA,EAAb,GAAImtB,CAAJ,EAAmCntB,IAAAA,EAAnC,GAA0B8tB,CAA1B,GACIlC,CAGA,CAHe,CAGf,CAFMkC,CAEN,CA3uBcgD,EA2uBd,GADIlF,CACJ,EADoB,CACpB,EAAM,CAAAsB,EAAAR,EAAN,CAnvBcC,EAmvBd,GACIf,CADJ,EACoB,CADpB,CAJJ,CAOI,EAAAA,EAAJ,EAAyBA,CAAzB,GACI,CAAAA,EACA,CADoBA,CACpB,CAAA,CAAA2C,EAAA1a,OAAA,EAFJ,CATJ,CA6BA0Z,QAAA,GAAa,CAAbA,CAAa,CACb,CAC6B,CAAzB,EAAI,CAAA3B,EAAJ,GACI,CAAAC,EAAA,CAAa,CAAAD,EAAb,CAAAW,GAEA,CAFgD,EAEhD,CADA,CAAAoC,EAAA9a,OAAA,CAAoB,GAApB,CACA,CAAA,CAAA0a,EAAA1a,OAAA,EAHJ,CADJ;AAYA2Z,QAAA,GAAgB,CAAhBA,CAAgB,CAChB,CAEI,GAAyB,CAAzB,EAAI,CAAA5B,EAAJ,CAA4B,CACpB0B,IAAAA,EAAQ,CAAAzB,EAAA,CAAa,CAAAD,EAAb,CACZ,KAAI2D,EAAQjC,CAAAd,GAAA,CAAcc,CAAAhB,GAAd,CACEtsB,KAAAA,EAAd,GAAIuvB,CAAJ,GAC8B,CAA1B,EAAIjC,CAAAf,GAAJ,EAA+Be,CAAAf,GAA/B,CAAoDgD,CAAAG,GAAA13B,OAApD,EACIs1B,CAAAjB,GAGA,CAHoB,GAGpB,CAFAh3B,CAEA,CAFIk6B,CAAAG,GAAA,CAAgBpC,CAAAf,GAAA,EAAhB,CAEJ,CADA,CAAAoC,EAAA9a,OAAA,CAAoBxe,CAApB,CACA,CAAA,CAAAk5B,EAAA1a,OAAA,EAJJ,GAOIyZ,CAAAjB,GACA,CADoB,EACpB,CAAAkB,EAAA,CAAAA,CAAA,CARJ,CADJ,CAHwB,CAFhC,CA8JAP,QAAA,EAAS,CAATA,CAAS,CAACsD,CAAD,CAAO1V,CAAP,CACT,CACI,CAAAzc,EA//LA2U,EAAA,CA+/LiBwd,CA//LjB,CA+/LwB,CAAArB,EA//LxB,CAAA,CA+/L6CrU,CAAA8R,EADjD,CA6CJrlB,CAAA,CAfIV,QAAW,EACX,CAEI,IADA,IAAIoqB,EAAO5xB,CAAA,CAA6B2H,QAA7B,CAr+OJC,OAq+OI,CAAuD,MAAvD,CAAX,CACSiqB,EAAI,CAAb,CAAgBA,CAAhB,CAAsBD,CAAA/4B,OAAtB,CAAmCg5B,CAAA,EAAnC,CAA0C,CACtC,IAAIC,EAAMF,CAAA,CAAKC,CAAL,CAAV,CACIvF,EAAU1rB,CAAA,CAA4BkxB,CAA5B,CACVpE,EAAAA,CAAa,IAAIrB,EAAJ,CAAsBC,CAAtB,CACjBrkB,EAAA,CAAgCylB,CAAhC,CAA4CoE,CAA5C,CAJsC,CAF9C,CAcJ,CAuBIj0B;QAZEk0B,GAYS,CAACC,CAAD,CACX,CAGQ,CAAA,KAAA,CAAA,IAAA,CAAM,aAAN,CAAqBA,CAArB,CAEA,KAAAjzB,EAAA,CAAW,IAQX,KAAA0a,EAAA,CAAa,EAMb,KAAAwY,GAAA,CAAgB,CAMhB,KAAAC,GAAA,CAAe,IAKf,KAAAC,GAAA,CAAiB,CAAA,CACjB,KAAAC,GAAA,CAAwB,CAQxBC,KAo8BJpZ,GAAA,CAAkB,EAp8BdoZ,KAq8BJnZ,GAAA,CAAkB,EAr8BdmZ,KAs8BJlZ,GAAA,CAAmB,EA97Bf,KAAAS,GAAA,CAAoB,CACpB,KAAAD,GAAA,CAAoB,EACpB,KAAAD,EAAA,CAAqB,EAuBrB,KAAA8D,GAAA,CAAsB,CACtB,KAAAgE,GAAA,CAAsB,EACtB,KAAAyF,GAAA,CAAsB,EACtB,KAAA6H,GAAA,CAAsB,EACtB,KAAA/C,GAAA,CAAsB,GAGtB,KAAA/tB,GAAA,CAFA,IAAAs0B,EAEA,CAFsB,CAGtB,KAAAC,GAAA,CAA0B,CACtB,KATkB/U,CAQI,CAEtB,IATkBgE,EAOI,CAGtB,MATkByF,EAMI,CAItB,KATkB6H,EAKI,CAKtB,OATkB/C,GAII,CAgD1B,KAAAxiB,GAAA,CAAc,EA4Bd,KAAAC,GAAA,CAAc,EAGd,KAAAgpB,GAAA,CAAgB,yOAAA,MAAA,CAAA,GAAA,CAWhB;IAAAC,EAAA,CAAmB,CACf,KADe,CACR,KADQ,CAInBC,GAAA,CAAAA,IAAA,CAAgB,CAAA,CAAhB,CAEA,KAAAC,GAAA,CAAoB,CACL,CAnEDC,EAmEC,CADK,CAEL,CA5CDC,EA4CC,CAAc,CAAd,CAAiB,IAAAC,EAAjB,CAFK,CAGL,CAAC,IAAAtpB,GAAD,CAAc,CAAd,CAHK,CAIL,EAJK,CAKL,EALK,CAML,CAhDDqpB,EAgDC,CAAc,CAAd,CAAiB,IAAAE,EAAjB,CANK,CAOL,CAjFDC,CAiFC,CAAc,CAAd,CAAiB,IAAAD,EAAjB,CAPK,CAQL,EARK,CASL,CAjDDE,EAiDC,CATK,CAUL,CApDDJ,EAoDC,CAAc,CAAd,CAAiB,IAAAK,EAAjB,CAVK,CAWL,CArFDF,CAqFC,CAAc,CAAd,CAAiB,IAAAG,EAAjB,CAXK,CAYL,EAZK,CAaL,EAbK,CAcL,CAxDDN,EAwDC,CAAc,CAAd,CAAiB,IAAAO,EAAjB,CAdK,CAeL,CAzFDJ,CAyFC,CAAc,CAAd,CAAiB,IAAAI,EAAjB,CAfK,CAgBL,EAhBK,CAiBL,CApFDC,CAoFC,CAAc,CAAd,CAAiB,IAAAC,GAAjB,CAjBK,CAkBL,CA5DDT,EA4DC,CAAc,CAAd,CAAiB,IAAAU,EAAjB,CAlBK,CAmBL,EAnBK,CAoBL,EApBK,CAqBL,EArBK,CAsBL,CAhEDV,EAgEC,CAAc,CAAd,CAAiB,IAAAW,EAAjB,CAtBK,CAuBL,CAjGDR,CAiGC,CAAc,CAAd,CAAiB,IAAAQ,EAAjB,CAvBK,CAwBL,EAxBK,CAyBL,CAxFDC,EAwFC,CAzBK,CA0BL,CApEDZ,EAoEC,CAAc,CAAd,CAAiB,IAAAa,EAAjB,CA1BK,CA2BL,EA3BK,CA4BL,EA5BK,CA6BL,EA7BK,CA8BL,CAxEDb,EAwEC,CAAc,CAAd,CAAiB,IAAAc,EAAjB,CA9BK,CA+BL,CAzGDX,CAyGC,CAAc,CAAd,CAAiB,IAAAW,EAAjB,CA/BK,CAgCL,EAhCK,CAiCL,CAAC,IAAApqB,GAAD,CAAc,CAAd,CAAiB,IAAAqqB,GAAjB,CAjCK,CAkCL,CA7GDC,CA6GC,CAAc,CAAd,CAAiB,IAAAf,EAAjB,CAlCK,CAmCL,EAnCK,CAoCL,EApCK,CAqCL,CA3GDgB,CA2GC,CAAc,CAAd,CAAiB,IAAAf,EAAjB,CArCK,CAsCL,CAjHDc,CAiHC,CAAc,CAAd,CAAiB,IAAAd,EAAjB,CAtCK,CAuCL,CA5EDgB,EA4EC,CAAc,CAAd,CAAiB,IAAAhB,EAAjB,CAvCK,CAwCL,EAxCK,CAyCL,CA/EDiB,EA+EC,CAzCK,CA0CL,CArHDH,CAqHC,CAAc,CAAd,CAAiB,IAAAX,EAAjB,CA1CK,CA2CL,CAhFDa,EAgFC,CAAc,CAAd,CAAiB,IAAAZ,EAAjB,CA3CK,CA4CL,EA5CK,CA6CL,CAnHDW,CAmHC,CAAc,CAAd,CAAiB,IAAAV,EAAjB,CA7CK,CA8CL,CAzHDS,CAyHC,CAAc,CAAd,CAAiB,IAAAT,EAAjB,CA9CK,CA+CL,CApFDW,EAoFC,CAAc,CAAd,CAAiB,IAAAX,EAAjB,CA/CK,CAgDL,EAhDK,CAiDL,CAtHDa,CAsHC,CAAc,CAAd,CAAiB,IAAAX,GAAjB,CAjDK,CAkDL,CA7HDO,CA6HC,CAAc,CAAd,CAAiB,IAAAN,EAAjB,CAlDK,CAmDL,EAnDK,CAoDL,EApDK,CAqDL,EArDK,CAsDL,CAjIDM,CAiIC;AAAc,CAAd,CAAiB,IAAAL,EAAjB,CAtDK,CAuDL,CA5FDO,EA4FC,CAAc,CAAd,CAAiB,IAAAP,EAAjB,CAvDK,CAwDL,EAxDK,CAyDL,CAzFDU,EAyFC,CAzDK,CA0DL,CArIDL,CAqIC,CAAc,CAAd,CAAiB,IAAAH,EAAjB,CA1DK,CA2DL,EA3DK,CA4DL,EA5DK,CA6DL,EA7DK,CA8DL,CAzIDG,CAyIC,CAAc,CAAd,CAAiB,IAAAF,EAAjB,CA9DK,CA+DL,CApGDI,EAoGC,CAAc,CAAd,CAAiB,IAAAJ,EAAjB,CA/DK,CAgEL,EAhEK,CAiEL,CApGDQ,EAoGC,CAjEK,CAkEL,CAvHDC,EAuHC,CAAc,CAAd,CAAiB,IAAAtB,EAAjB,CAlEK,CAmEL,EAnEK,CAoEL,EApEK,CAqEL,EArEK,CAsEL,CA3HDsB,EA2HC,CAAc,CAAd,CAAiB,IAAArB,EAAjB,CAtEK,CAuEL,CAnHDsB,EAmHC,CAAc,CAAd,CAAiB,IAAAtB,EAAjB,CAvEK,CAwEL,EAxEK,CAyEL,CAlHDuB,EAkHC,CAzEK,CA0EL,CA/HDF,EA+HC,CAAc,CAAd,CAAiB,IAAAlB,EAAjB,CA1EK,CA2EL,CAvHDmB,EAuHC,CAAc,CAAd,CAAiB,IAAAlB,EAAjB,CA3EK,CA4EL,EA5EK,CA6EL,CA9HDoB,EA8HC,CAAc,CAAd,CAAiB,IAAAX,GAAjB,CA7EK,CA8EL,CAnIDQ,EAmIC,CAAc,CAAd,CAAiB,IAAAhB,EAAjB,CA9EK,CA+EL,CA3HDiB,EA2HC,CAAc,CAAd,CAAiB,IAAAjB,EAAjB,CA/EK,CAgFL,EAhFK,CAiFL,CAlJDoB,EAkJC,CAAc,CAAd,CAAiB,IAAAlB,GAAjB,CAjFK,CAkFL,CAvIDc,EAuIC,CAAc,CAAd,CAAiB,IAAAb,EAAjB,CAlFK,CAmFL,EAnFK,CAoFL,EApFK,CAqFL,EArFK,CAsFL,CA3IDa,EA2IC,CAAc,CAAd,CAAiB,IAAAZ,EAAjB,CAtFK,CAuFL,CAnIDa,EAmIC,CAAc,CAAd,CAAiB,IAAAb,EAAjB,CAvFK,CAwFL,EAxFK,CAyFL,CAtJDiB,EAsJC,CAzFK,CA0FL,CA/IDL,EA+IC,CAAc,CAAd,CAAiB,IAAAV,EAAjB,CA1FK,CA2FL,EA3FK,CA4FL,EA5FK,CA6FL,EA7FK,CA8FL,CAnJDU,EAmJC,CAAc,CAAd,CAAiB,IAAAT,EAAjB,CA9FK,CA+FL,CA3IDU,EA2IC,CAAc,CAAd,CAAiB,IAAAV,EAAjB,CA/FK,CAgGL,EAhGK,CAiGL,CAnIDe,EAmIC,CAjGK,CAkGL,CA9KDC,CA8KC,CAAc,CAAd,CAAiB,IAAA7B,EAAjB,CAlGK,CAmGL,EAnGK,CAoGL,EApGK,CAqGL,EArGK,CAsGL,CAlLD6B,CAkLC,CAAc,CAAd,CAAiB,IAAA5B,EAAjB,CAtGK,CAuGL,CA3ID6B,EA2IC,CAAc,CAAd,CAAiB,IAAA7B,EAAjB,CAvGK,CAwGL,EAxGK,CAyGL,CAhJD8B,EAgJC,CAzGK,CA0GL,CAtLDF,CAsLC,CAAc,CAAd,CAAiB,IAAAzB,EAAjB,CA1GK,CA2GL,CA/ID0B,EA+IC,CAAc,CAAd,CAAiB,IAAAzB,EAAjB,CA3GK,CA4GL,EA5GK,CA6GL,CA9JDoB,EA8JC,CAAc,CAAd,CAAiB,IAAAO,GAAjB,CA7GK,CA8GL,CA1LDH,CA0LC,CAAc,CAAd,CAAiB,IAAAvB,EAAjB,CA9GK,CA+GL,CAnJDwB,EAmJC,CAAc,CAAd,CAAiB,IAAAxB,EAAjB,CA/GK,CAgHL,EAhHK,CAiHL,CAjLD2B,EAiLC,CAAc,CAAd,CAAiB,IAAAzB,GAAjB,CAjHK;AAkHL,CA9LDqB,CA8LC,CAAc,CAAd,CAAiB,IAAApB,EAAjB,CAlHK,CAmHL,EAnHK,CAoHL,EApHK,CAqHL,EArHK,CAsHL,CAlMDoB,CAkMC,CAAc,CAAd,CAAiB,IAAAnB,EAAjB,CAtHK,CAuHL,CA3JDoB,EA2JC,CAAc,CAAd,CAAiB,IAAApB,EAAjB,CAvHK,CAwHL,EAxHK,CAyHL,CAvJDwB,EAuJC,CAzHK,CA0HL,CAtMDL,CAsMC,CAAc,CAAd,CAAiB,IAAAjB,EAAjB,CA1HK,CA2HL,EA3HK,CA4HL,EA5HK,CA6HL,EA7HK,CA8HL,CA1MDiB,CA0MC,CAAc,CAAd,CAAiB,IAAAhB,EAAjB,CA9HK,CA+HL,CAnKDiB,EAmKC,CAAc,CAAd,CAAiB,IAAAjB,EAAjB,CA/HK,CAgIL,EAhIK,CAiIL,EAjIK,CAkIL,CA/JDsB,EA+JC,CAAc,CAAd,CAAiB,IAAAnC,EAAjB,CAlIK,CAmIL,EAnIK,CAoIL,EApIK,CAqIL,CAhKDoC,EAgKC,CAAc,CAAd,CAAiB,IAAAnC,EAAjB,CArIK,CAsIL,CAnKDkC,EAmKC,CAAc,CAAd,CAAiB,IAAAlC,EAAjB,CAtIK,CAuIL,CAnKDoC,EAmKC,CAAc,CAAd,CAAiB,IAAApC,EAAjB,CAvIK,CAwIL,EAxIK,CAyIL,CA/LDqC,EA+LC,CAzIK,CA0IL,EA1IK,CA2IL,CAlKDC,EAkKC,CA3IK,CA4IL,EA5IK,CA6IL,CAxKDH,EAwKC,CAAc,CAAd,CAAiB,IAAA9B,EAAjB,CA7IK,CA8IL,CA3KD6B,EA2KC,CAAc,CAAd,CAAiB,IAAA7B,EAAjB,CA9IK,CA+IL,CA3KD+B,EA2KC,CAAc,CAAd,CAAiB,IAAA/B,EAAjB,CA/IK,CAgJL,EAhJK,CAiJL,CA1NDkC,CA0NC,CAAc,CAAd,CAAiB,IAAAhC,GAAjB,CAjJK,CAkJL,CA/KD2B,EA+KC,CAAc,CAAd,CAAiB,IAAA1B,EAAjB,CAlJK,CAmJL,EAnJK,CAoJL,EApJK,CAqJL,CAhLD2B,EAgLC,CAAc,CAAd,CAAiB,IAAA1B,EAAjB,CArJK,CAsJL,CAnLDyB,EAmLC,CAAc,CAAd,CAAiB,IAAAzB,EAAjB,CAtJK,CAuJL,CAnLD2B,EAmLC,CAAc,CAAd,CAAiB,IAAAI,EAAjB,CAvJK,CAwJL,EAxJK,CAyJL,CA9KDC,EA8KC,CAzJK,CA0JL,CAvLDP,EAuLC,CAAc,CAAd,CAAiB,IAAAvB,EAAjB,CA1JK,CA2JL,CAjLD+B,EAiLC,CA3JK,CA4JL,EA5JK,CA6JL,EA7JK,CA8JL,CA3LDR,EA2LC,CAAc,CAAd,CAAiB,IAAAtB,EAAjB,CA9JK,CA+JL,EA/JK,CAgKL,EAhKK,CAiKL,CA9MD+B,EA8MC,CAAc,CAAd,CAAiB,IAAAxC,EAAjB,CAjKK,CAkKL,CAjNDyC,EAiNC,CAAc,CAAd,CAAiB,IAAA7C,EAAjB,CAlKK,CAmKL,CAjND8C,EAiNC,CAAc,CAAd,CAAiB,IAAA1C,EAAjB,CAnKK,CAoKL,EApKK,CAqKL,CAlNDwC,EAkNC,CAAc,CAAd,CAAiB,IAAA3C,EAAjB,CArKK,CAsKL,CArND4C,EAqNC,CAAc,CAAd,CAAiB,IAAA5C,EAAjB,CAtKK,CAuKL,CArND6C,EAqNC,CAAc,CAAd,CAAiB,IAAA7C,EAAjB,CAvKK,CAwKL,EAxKK,CAyKL,CAlMD8C,EAkMC,CAzKK,CA0KL,CAzNDF,EAyNC,CAAc,CAAd,CAAiB,IAAAzC,EAAjB,CA1KK,CA2KL,CArMD4C,EAqMC,CA3KK,CA4KL,EA5KK,CA6KL,CA1NDJ,EA0NC,CAAc,CAAd,CAAiB,IAAAtC,EAAjB,CA7KK,CA8KL,CA7NDuC,EA6NC;AAAc,CAAd,CAAiB,IAAAvC,EAAjB,CA9KK,CA+KL,CA7NDwC,EA6NC,CAAc,CAAd,CAAiB,IAAAxC,EAAjB,CA/KK,CAgLL,EAhLK,CAiLL,CAzPD2C,CAyPC,CAAc,CAAd,CAAiB,IAAAzC,GAAjB,CAjLK,CAkLL,CAjODqC,EAiOC,CAAc,CAAd,CAAiB,IAAApC,EAAjB,CAlLK,CAmLL,EAnLK,CAoLL,EApLK,CAqLL,CAlODmC,EAkOC,CAAc,CAAd,CAAiB,IAAAlC,EAAjB,CArLK,CAsLL,CArODmC,EAqOC,CAAc,CAAd,CAAiB,IAAAnC,EAAjB,CAtLK,CAuLL,CArODoC,EAqOC,CAAc,CAAd,CAAiB,IAAAL,EAAjB,CAvLK,CAwLL,EAxLK,CAyLL,CArPDS,EAqPC,CAzLK,CA0LL,CAzODL,EAyOC,CAAc,CAAd,CAAiB,IAAAjC,EAAjB,CA1LK,CA2LL,CAnNDuC,EAmNC,CA3LK,CA4LL,EA5LK,CA6LL,CA1ODP,EA0OC,CAAc,CAAd,CAAiB,IAAA/B,EAAjB,CA7LK,CA8LL,CA7ODgC,EA6OC,CAAc,CAAd,CAAiB,IAAAhC,EAAjB,CA9LK,CA+LL,CA7ODiC,EA6OC,CAAc,CAAd,CAAiB,IAAAlC,EAAjB,CA/LK,CAgML,EAhMK,CAiML,CA1PDwC,EA0PC,CAAc,CAAd,CAAiB,IAAAhD,EAAjB,CAjMK,CAkML,CA7PDiD,EA6PC,CAAc,CAAd,CAAiB,IAAArD,EAAjB,CAlMK,CAmML,EAnMK,CAoML,EApMK,CAqML,CA9PDoD,EA8PC,CAAc,CAAd,CAAiB,IAAAnD,EAAjB,CArMK,CAsML,CAjQDoD,EAiQC,CAAc,CAAd,CAAiB,IAAApD,EAAjB,CAtMK,CAuML,CA/PDqD,EA+PC,CAAc,CAAd,CAAiB,IAAArD,EAAjB,CAvMK,CAwML,EAxMK,CAyML,CA3PDsD,EA2PC,CAzMK,CA0ML,CArQDF,EAqQC,CAAc,CAAd,CAAiB,IAAAjD,EAAjB,CA1MK,CA2ML,CAlQDoD,EAkQC,CA3MK,CA4ML,EA5MK,CA6ML,CAtQDJ,EAsQC,CAAc,CAAd,CAAiB,IAAA9C,EAAjB,CA7MK,CA8ML,CAzQD+C,EAyQC,CAAc,CAAd,CAAiB,IAAA/C,EAAjB,CA9MK,CA+ML,CAvQDgD,EAuQC,CAAc,CAAd,CAAiB,IAAAhD,EAAjB,CA/MK,CAgNL,EAhNK,CAiNL,CArRDmD,CAqRC,CAAc,CAAd,CAAiB,IAAAjD,GAAjB,CAjNK,CAkNL,CA7QD6C,EA6QC,CAAc,CAAd,CAAiB,IAAA5C,EAAjB,CAlNK,CAmNL,EAnNK,CAoNL,EApNK,CAqNL,EArNK,CAsNL,CAjRD4C,EAiRC,CAAc,CAAd,CAAiB,IAAA3C,EAAjB,CAtNK,CAuNL,CA/QD4C,EA+QC,CAAc,CAAd,CAAiB,IAAA5C,EAAjB,CAvNK,CAwNL,EAxNK,CAyNL,CAvRDgD,EAuRC,CAzNK,CA0NL,CArRDL,EAqRC,CAAc,CAAd,CAAiB,IAAAzC,EAAjB,CA1NK,CA2NL,EA3NK,CA4NL,EA5NK,CA6NL,EA7NK,CA8NL,CAzRDyC,EAyRC,CAAc,CAAd,CAAiB,IAAAxC,EAAjB,CA9NK,CA+NL,CAvRDyC,EAuRC,CAAc,CAAd,CAAiB,IAAAzC,EAAjB,CA/NK,CAgOL,EAhOK,CAiOL,CA3RD8C,EA2RC,CAAc,CAAd,CAAiB,IAAAvD,EAAjB,CAjOK,CAkOL,CAnQDwD,EAmQC,CAAc,CAAd,CAAiB,IAAA5D,EAAjB,CAlOK,CAmOL,EAnOK,CAoOL,EApOK,CAqOL,CA/RD2D,EA+RC,CAAc,CAAd,CAAiB,IAAA1D,EAAjB,CArOK;AAsOL,CAvQD2D,EAuQC,CAAc,CAAd,CAAiB,IAAA3D,EAAjB,CAtOK,CAuOL,CA3RD4D,EA2RC,CAAc,CAAd,CAAiB,IAAA5D,EAAjB,CAvOK,CAwOL,EAxOK,CAyOL,CA5RD6D,EA4RC,CAzOK,CA0OL,CA3QDF,EA2QC,CAAc,CAAd,CAAiB,IAAAxD,EAAjB,CA1OK,CA2OL,CAtRD2D,EAsRC,CA3OK,CA4OL,EA5OK,CA6OL,CAvSDJ,EAuSC,CAAc,CAAd,CAAiB,IAAArD,EAAjB,CA7OK,CA8OL,CA/QDsD,EA+QC,CAAc,CAAd,CAAiB,IAAAtD,EAAjB,CA9OK,CA+OL,CAnSDuD,EAmSC,CAAc,CAAd,CAAiB,IAAAvD,EAAjB,CA/OK,CAgPL,EAhPK,CAiPL,CAxTD0D,CAwTC,CAAc,CAAd,CAAiB,IAAAxD,GAAjB,CAjPK,CAkPL,CAnRDoD,EAmRC,CAAc,CAAd,CAAiB,IAAAnD,EAAjB,CAlPK,CAmPL,EAnPK,CAoPL,EApPK,CAqPL,EArPK,CAsPL,CAvRDmD,EAuRC,CAAc,CAAd,CAAiB,IAAAlD,EAAjB,CAtPK,CAuPL,CA3SDmD,EA2SC,CAAc,CAAd,CAAiB,IAAAnD,EAAjB,CAvPK,CAwPL,EAxPK,CAyPL,CAxRDuD,EAwRC,CAzPK,CA0PL,CA3RDL,EA2RC,CAAc,CAAd,CAAiB,IAAAhD,EAAjB,CA1PK,CA2PL,EA3PK,CA4PL,EA5PK,CA6PL,EA7PK,CA8PL,CA/RDgD,EA+RC,CAAc,CAAd,CAAiB,IAAA/C,EAAjB,CA9PK,CA+PL,CAnTDgD,EAmTC,CAAc,CAAd,CAAiB,IAAAhD,EAAjB,CA/PK,CAgQL,EAhQK,CAhL5B,CAbsBxsB,CAAArJ,CAApBi0B,EAAoBj0B,CAAAA,CAAAA,CA2ctB,EAAA,CAjyXJ,EAAAk5B,UAiyXI3zB;CAAAvC,EAAA,CAAAA,QAAU,CAACyC,CAAD,CAAYC,CAAZ,CAAsBhE,CAAtB,CACV,CACI,IAAIT,EAAM,IACV,QAAOyE,CAAP,EACA,KAAK,YAAL,CAaI,MAXA,KAAAyzB,EAWO,CAZP,IAAA94B,EAAA,CAAcqF,CAAd,CAYO,CAZmBhE,CAYnB,CAVP,IAAAy3B,EAAArQ,MAAA,EAUO,CATPpnB,CAAAyhB,WASO,CATc,QAAQ,CAACliB,CAAD,CAAM5D,CAAN,CAAS,CAClC,MAAO,SAAQ,CAAC4lB,CAAD,CAAQ,CACE,EAArB,EAAIA,CAAAM,QAAJ,GACI7d,CAEA,CAFWrI,CAAAuE,MAEX,CADAvE,CAAAuE,MACA,CADU,EACV,CAAAw3B,EAAA,CAAkBn4B,CAAlB,CAAuByE,CAAvB,CAHJ,CADmB,CADW,CAAjB,CAQnB,IARmB,CAQbhE,CARa,CASd,CAAA,CAAA,CAEX,MAAK,YAAL,CAwBI,MAvBA,KAAArB,EAAA,CAAcqF,CAAd,CAuBO,CAvBmBhE,CAuBnB,CAlBP23B,EAAA,CACI33B,CADJ,CAEI,QAAQ,EAAU,CACd,MAAIT,EAAAk4B,EAAJ,EACIzzB,CAQO,CARIzE,CAAAk4B,EAAAv3B,MAQJ,CADPw3B,EAAA,CAAkBn4B,CAAlB,CAAuByE,CAAvB,CACO,CAAA,CAAA,CATX,EAYO,CAAA,CAbO,CAFtB,CAkBO,CAAA,CAAA,CAEX,MAAK,MAAL,CAcI,MAbA,KAAArF,EAAA,CAAcqF,CAAd,CAaO,CAbmBhE,CAanB,CAZP23B,EAAA,CACI33B,CADJ,CAEI,QAAQ,CAAC2iB,CAAD,CAAU,CACd,IAAIrJ,EAAa,CAAA,CACZpU,EAAA,CAAA3F,CAAA,CAAW,CAAA,CAAX,CAAL,GACI6F,CAAA,CAAA7F,CAAA,CAAY,CAAA,CAAZ,CAEA,CADA+Z,CACA,CADa/Z,CAAAwZ,KAAA,CAAS4J,CAAA,CAAS,CAAT,CAAa,CAAtB,CACb,CAAAvd,CAAA,CAAA7F,CAAA,CAAY,CAAA,CAAZ,CAHJ,CAKA,OAAO+Z,EAPO,CAFtB,CAYO,CAAA,CAAA,CAxDX,CA6DA,MAAO,CAAA,CA/DX,CAwEAzV;CAAA2Q,GAAA,CAAAA,QAAS,CAACC,CAAD,CAAWhO,CAAX,CAAkBiO,CAAlB,CACT,CACI,IAAAP,EAAA,CAAaM,CACb,KAAAE,EAAA,CAAclO,CACd,KAAAmO,GAAA,CAAaF,CAAb,CAAmBjO,CAAnB,CAA2B,CAC3B,KAAAoO,GAAA,CAAgB,IAAAF,EAAhB,CAA8B,IAAAC,GAC9B,KAAA3P,EAAA,EALJ,CAaApB,EAAAgE,GAAA,CAAAA,QAAQ,CAACC,CAAD,CAAMrI,CAAN,CACR,CACQqI,CAAJ,EAAW,CAAC,IAAAjJ,EAAAK,EAAZ,GACI,IAAAL,EAAAK,EACA,CADqB,CAAA,CACrB,CAAA,IAAAM,EAAA,CAAWmC,CAAA,CAAAlC,CAAA,CAAuB,KAAvB,CAFf,CADJ,CAUAoE,EAAAoR,GAAA,CAAAA,QAAQ,EACR,CACI,IAAAwiB,EAAArQ,MAAA,EADJ,CA6CA8L;QAAA,GAAU,CAAVA,CAAU,CAAC0E,CAAD,CACV,CAKI,CAAAjE,EAAA,CAAkB,CAClB,EAAAD,EAAA,CAAkB,CAClB,EAAAS,EAAA,CAAkB,CAClB,EAAAD,EAAA,CAAkB,CAClB,EAAAE,GAAA,CAAkB,CAClB,EAAAkB,GAAA,CAAkB,CAClB,EAAAtB,EAAA,CAAkB,CAClB,EAAA+B,EAAA,CAAkB,CAClB,EAAAzC,EAAA,CAAkB,CAClB,EAAAS,EAAA,CAAkB,CAClB,EAAAH,EAAA,CAAkB,EAClB,EAAAL,EAAA,CAAkB,EAClB,EAAAO,GAAA,CAAkB,CAAAM,GAElB,KAAIyD,EAAS,EAGb,IAAID,CAAJ,CAeI,IAdA,CAAAE,GAcK,CAdW,4EAAA,MAAA,CAAA,GAAA,CAcX,CAAAC,CAAA,CAAM,CAAX,CAAcA,CAAd,CAAsB,CAAAD,GAAAz+B,OAAtB,CAA4C0+B,CAAA,EAA5C,CAAqD,CACjD,IAAAC,EAAQ,CAAAF,GAAA,CAAcC,CAAd,CACRF,EAAA,EAAU,GAAV,CAAgBG,CAAAtgC,QAAA,CAAc,KAAd,CAAqB,KAArB,CAAAA,QAAA,CAAoC,KAApC,CAA2C,KAA3C,CAAAA,QAAA,CAA0D,OAA1D,CAAmE,mCAAnE,CAAAA,QAAA,CAAgH,KAAhH,CAAuH,mBAAvH,CAAAA,QAAA,CAAoJ,KAApJ,CAA2J,KAA3J,CAAhB,CAAoL,IAFnI,CAfzD,IAoCI,KAdA,CAAAogC,GAcK,CAdW,gFAAA,MAAA,CAAA,GAAA,CAcX;AAAAC,CAAA,CAAM,CAAX,CAAcA,CAAd,CAAsB,CAAAD,GAAAz+B,OAAtB,CAA4C0+B,CAAA,EAA5C,CACIC,CACA,CADQ,CAAAF,GAAA,CAAcC,CAAd,CACR,CAAAF,CAAA,EAAU,GAAV,CAAgBG,CAAAtgC,QAAA,CAAc,KAAd,CAAqB,KAArB,CAAAA,QAAA,CAAoC,IAApC,CAA0C,KAA1C,CAAAA,QAAA,CAAyD,OAAzD,CAAkE,mCAAlE,CAAAA,QAAA,CAA+G,KAA/G,CAAsH,mBAAtH,CAAAA,QAAA,CAAmJ,KAAnJ,CAA0J,KAA1J,CAAhB,CAAmL,IAnBvL,EAAAugC,GAAA,CAAoB,IAAIz1B,MAAJ,CAAWq1B,CAAX,CA8BxB,EAAAK,GAAA,CAAmB,CAvhBDnD,EAuhBC,CAAc,CAAAhrB,GAAd,CAziBD8pB,CAyiBC,CA3iBDY,CA2iBC,CAviBDO,EAuiBC,CAtiBDO,EAsiBC,CA/iBDO,CA+iBC,CA9iBDS,CA8iBC,CA1iBDQ,CA0iBC,CA7iBDO,CA6iBC,CAvEvB,CA6EAzzB,CAAAmQ,GAAA,CAAAA,QAAI,EACJ,CAII,IAAAxU,EAAAwU,GAAA,EAJJ,CA6BA+J,SAAA,EAAS,CAATA,CAAS,CAACpe,CAAD,CAAYqa,CAAZ,CAAkBzE,CAAlB,CAA4B/W,CAA5B,CAAyCozB,CAAzC,CAAiDlzB,CAAjD,CACT,CACI,CAAK,CAAAF,GAAL,CAAwBA,CAAxB,GAAwCA,CAAxC,GACQ9H,CACJ,CADQ,CAAA8I,EAAAgb,EAAA,CAAiBR,CAAjB,CACR,CAAA,CAAAxc,QAAA,CAAamC,CAAAlB,GAAb,CAA4B,GAA5B,EAAmCmzB,CAAA,CAAQ,SAAR,CAAkB,SAArD,EAAkE,GAAlE,CAAwEvX,CAAA,CAAcL,CAAd,CAAxE,CAA8F,GAA9F,EAAkH3Y,IAAAA,EAAb,GAAAkU,CAAA,CAAyB,IAAzB,CAAgC8E,CAAA,CAAc9E,CAAd,CAAhC,CAA2D,EAAhK,EAAsK,IAAtK,EAA8K7W,CAAA,CAAOA,CAAP,CAAc,MAAd,CAAqB,EAAnM,EAAyM+d,CAAA,CAAc/lB,CAAd,CAAzM,CAFJ,CADJ,CAWAmN,CAAArG,QAAA,CAAAA,QAAO,CAACqC,CAAD,CACP,CACI,IAAAwE,EAAA,CAAaxE,CAAb,CACAya,GAAA,CAAA,IAAA9a,EAAA,CAFJ,CAQAqE,EAAAmE,GAAA,CAAAA,QAAI,EACJ,CAEI,IAAA3D,EAAA,CAAa,wCAAb,CAFJ,CASAR;CAAAwQ,GAAA,CAAAA,QAAG,EACH,CACI,GAAI,CAAC8jB,EAAA,CAAAA,IAAA,CAAL,CAAqB,MAAO,CAAA,CAC5B,KAAA34B,EAAA6U,GAAA,EACA,OAAO,CAAA,CAHX,CAWAxQ,EAAAkV,KAAA,CAAAA,QAAI,CAACzjB,CAAD,CACJ,CACI,GAAI,CAAC6iC,EAAA,CAAAA,IAAA,CAAL,CAAqB,MAAO,CAAA,CAE5B,IAAI,CACA,IAAA7e,EAAa,IAAA9Z,EAAAuZ,KAAA,CAAczjB,CAAd,CADb,CAGJ,MAAMqG,CAAN,CAAS,CACL2d,CACA,CADajY,IAAAA,EACb,CAAA0D,EAAA,CAAA,IAAAvF,EAAA,CAAkB7D,CAAAwd,MAAlB,EAA6Bxd,CAAA6B,QAA7B,CAFK,CAIU6D,IAAAA,EAAnB,GAAIiY,CAAJ,EAA8B,IAAAW,EAAA,EAK9B,KAAAza,EAAA0V,OAAA,CAAgB,CAAA,CAAhB,CACA,KAAAA,OAAA,CAAY,CAAA,CAAZ,CACA,OAAOoE,EAjBX,CAwBAzV,EAAAqR,OAAA,CAAAA,QAAM,CAACkjB,CAAD,CACN,CACI,IAAA3F,GAAA,CAAgB,IAAAjzB,EAAAyU,EACZmkB,EAAJ,EAAa,IAAAC,GAAb,CACIC,EAAA,CAAAA,IAAA,CADJ,CAGIC,EAAA,CAAAA,IAAA,CALR,CAcAJ,SAAA,GAAO,CAAPA,CAAO,CACP,CACS,CAAA34B,EAIL,EAFKwF,CAAA,CAAA,CAAAxF,EAAA,CAEL,EAAI,CAAA0F,CAAA,CAAA,CAAA1F,EAAA,CAAJ,EAEO,CAAA,CAAA,CAAA,EAAA,CA3nRH,CAAAX,EAAAO,MAAJ,EACI,CAAAiF,EAAA,CAAa,CAAAP,SAAA,EAAb,CAA+B,QAA/B,CACA,CAAA,CAAA,CAAO,CAAA,CAFX,EAIA,CAJA,CAIO,CAAA,CAunRA,CAAA,CAAA,CAAA,CAAA,CAFP,EACW,CADX,CACW,CAAA,CADX,OAAA,EALJ;AAeAD,CAAAiQ,MAAA,CAAAA,QAAK,EACL,CACI,IAAI7c,CACC,KAAAkjB,GAAA9gB,OAAL,GACI,IAAA8gB,GADJ,CAC4B9T,KAAJ,CAAU,GAAV,CADxB,CAEA,KAAKpP,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB,IAAAkjB,GAAA9gB,OAAhB,CAA0CpC,CAAA,EAA1C,CACI,IAAAkjB,GAAA,CAAkBljB,CAAlB,CAAA,CAAwB,EACvB,KAAAijB,EAAA7gB,OAAL,GACI,IAAA6gB,EADJ,CAC6B7T,KAAJ,CAAU,GAAV,CADzB,CAEA,KAAKpP,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB,IAAAijB,EAAA7gB,OAAhB,CAA2CpC,CAAA,EAA3C,CACI,IAAAijB,EAAA,CAAmBjjB,CAAnB,CAAA,CAAwB,CAACA,CAAD,CAAI,CAAJ,CACxB,KAAAgjB,EAAJ,EAAe,IAAA/E,OAAA,EACf,KAAA+E,EAAA,CAAY,CAXhB,CAoBApW,EAAA4C,MAAA,CAAAA,QAAK,EACL,CACS,IAAA4xB,GAAL,EAAqB,IAAAh0B,EAAA,CAAa,SAAb,CADzB,CAWAR,EAAAuV,KAAA,CAAAA,QAAI,CAACof,CAAD,CAAUxf,CAAV,CACJ,CACI,GAAI,CAAC,IAAAqf,GAAL,GACI,IAAAh0B,EAAA,CAAa,SAAb,CACI2U,CAAAA,CAFR,EAEiB,CACT,IAAIyf,EAAU5gC,EAAA,EAEd,KAAAwM,EAAA,CADAo0B,CACA,CADWD,CACX,CAAuB,MAAvB,CAAgCxf,CAAhC,CAA0C,UAA1C,CAHS,CAiBjB,IAAA9D,OAAA,EACA,KAAAD,GAAA,EACK,KAAAojB,GAAL,GACI,IAAApe,EADJ,CACgB,CADhB,CAIAye,GAAA,CAAAA,IAAA,CAAyB,IAAAl5B,EAAAyU,EAAzB,CA1BJ,CAoHA0kB,SAAA,GAAa,CAAC3e,CAAD,CAAOtjB,CAAP,CACb,CACI,MAAOsjB,EAAP,EAAgBtjB,CAAhB,EAAqB,EAArB,EAA4B,EAA5B,CADJ;AAaAmN,CAAA2W,EAAA,CAAAA,QAAO,CAACR,CAAD,CACP,CAEI,GAAIA,CAAJ,EAAY,IAAArF,EAAZ,EAA2BqF,CAA3B,CAAkC,IAAAnF,GAAlC,CAAiD,CAC7CQ,EAAA,CAAA,IAAA7V,EAAA,CAAyBwa,CAAzB,CACA,KAAAtjB,EAAI,IAAAyd,EAAA,CAAW,IAAAQ,EAAX,CAAyBqF,CAAzB,CAEJtjB,EAAA,EAAK,GAJwC,CAMjD,MAAOA,EARX,CAyBAmnB,SAAA,GAAO,CAAPA,CAAO,CAAC7D,CAAD,CAAOtjB,CAAP,CACP,CACQsjB,CAAJ,CAAW,CAAArF,EAAX,EAA0BqF,CAA1B,EAAkC,CAAAnF,GAAlC,CACI,CAAAxQ,EAAA,CAAa,mBAAb,CAAmCgW,CAAA,CAAcL,CAAd,CAAnC,CADJ,EAIA,CAAA7F,EAAA,CAAW,CAAAQ,EAAX,CAAyBqF,CAAzB,CAEA,CAFkCtjB,CAElC,CAFsC,GAEtC,CADA+e,EAAA,CAAA,CAAAjW,EAAA,CAA0Bwa,CAA1B,CACA,CAAA,CAAAxa,EAAA0V,OAAA,EANA,CADJ,CAyBA0jB,QAAA,GAAiB,CAAjBA,CAAiB,CAAC5e,CAAD,CACjB,CA0FW6e,CAAA,CAzFFC,CAyFsBrf,GAApB,CAzFsBO,CAyFtB,CAzFF+e,IAAA,EAyFE,CAzFP,EACI,CAAAtf,GAAAtc,KAAA,CAAqB6c,CAArB,CAEJ,OAAO,CAAA,CAJX,CAmEA6e,QAAA,EAAc,CAACG,CAAD,CAAShf,CAAT,CAAe+e,CAAf,CACd,CAEI,IADA,IAAIE,EAAS,CAAA,CAAb,CACShiC,EAAE,CAAX,CAAcA,CAAd,CAAkB+hC,CAAA3/B,OAAlB,CAAiCpC,CAAA,EAAjC,CACI,GAAI+hC,CAAA,CAAO/hC,CAAP,CAAJ,EAAiB+iB,CAAjB,CAAuB,CACf+e,CAAJ,EACIC,CAAAh2B,OAAA,CAAc/L,CAAd,CAAiB,CAAjB,CAEJgiC,EAAA,CAAS,CAAA,CACT,MALmB,CAQ3B,MAAOA,EAXX,CAmDAC,QAAA,GAAiB,CAAjBA,CAAiB,CAAClf,CAAD,CACjB,CACiB3Y,IAAAA,EAAb,GAAI2Y,CAAJ,GAMI0e,EAAA,CAAAA,CAAA,CAAyB,CAAAS,EAAzB,CACA,CAAIP,EAAA,CAAAA,CAAA,CAAuB5e,CAAvB,CAAJ,GACI,CAAAmf,EADJ,CACsBnf,CADtB,CAPJ,CADJ,CAiBA0e,QAAA,GAAmB,CAAnBA,CAAmB,CAAC1e,CAAD,CACnB,CAC4B3Y,IAAAA,EAAxB,GAAI,CAAA83B,EAAJ,EAAqCnf,CAArC,EAA6C,CAAAmf,EAA7C,EAjDON,CAAA,CAkDCC,CAlDmBrf,GAApB,CAkDyB,CAAA0f,EAlDzB,CAkD0CJ,CAAAA,CAlD1C,CAiDP,GAEQ,CAAAI,EAFR,CAE0B93B,IAAAA,EAF1B,CAKA,EAAAg3B,GAAA,CAAiB,CAAA,CANrB;AAgBAte,QAAA,GAAe,CAAfA,CAAe,CAACC,CAAD,CAAOof,CAAP,CAAqBx3B,CAArB,CACf,CAMI,IADA,IAAIkY,EAAS,CAAA,CAAb,CACS7iB,EAAE,CAAX,CAAcA,CAAd,CAAkBmiC,CAAA//B,OAAlB,CAAuCpC,CAAA,EAAvC,CACI,GAAImiC,CAAA,CAAaniC,CAAb,CAAJ,EAAuB+iB,CAAvB,CAA6B,CACrBA,CAAJ,EAAY,CAAAmf,EAAZ,EACI,CAAA90B,EAAA,CAAa,kBAAb,CAAkCgW,CAAA,CAAcL,CAAd,CAAlC,CAAwD,IAAxD,CAA+DpY,CAA/D,CAAuE,GAAvE,CACJkY,EAAA,CAAS,CAAA,CACT,MAJyB,CAOjC,MAAOA,EAdX;AAuBAuf,QAAA,GAAc,CAAdA,CAAc,CAACrf,CAAD,CAAOsf,CAAP,CACd,CACI,IAAIC,EAAQ5iC,CAAA,CAAUqjB,CAAV,CAAgB,CAAhB,CAAZ,CACIJ,EAAU,CAAAY,EAAA,CAAaR,CAAA,EAAb,CADd,CAEItjB,EAAiB2K,IAAAA,EAAZ,GAAAuY,CAAA,CAAuB,CAAvB,CAA2BA,CAFpC,CAGI4f,EAAU,CAAArG,GAAA,CAAkBz8B,CAAlB,CAHd,CAII+iC,EAAY,EAJhB,CAKIhI,EAAqBpwB,IAAAA,EAAf,GAAAm4B,CAAA,CAAQ,CAAR,CAAA,CAA0B,CAA1B,CAA8BA,CAAA,CAAQ,CAAR,CACxC,GAAG,CACCD,CAAA,EAAS,GAAT,CAAe5iC,CAAA,CAAUD,CAAV,CAAa,CAAb,CACf,IAAI,CAAE+6B,CAAA,EAAN,CAAa,KACb/6B,EAAA,CAAI,CAAA8jB,EAAA,CAAaR,CAAA,EAAb,CACJ,IAAU3Y,IAAAA,EAAV,GAAI3K,CAAJ,CAAqB,KACrB+iC,EAAAt8B,KAAA,CAAezG,CAAf,CALD,CAAH,MAMS,CANT,CAOmB2K,KAAAA,EAAnB,GAAIm4B,CAAA,CAAQ,CAAR,CAAJ,GACIA,CACA,CADU,CA3hCIE,EA2hCJ,CAAa,CAAb,CAAgB,CAAAhG,EAAhB,CACV,CAAA+F,CAAAt8B,KAAA,CAAeyc,CAAf,CAFJ,CAIA2f,EAAA,CAAQpiC,CAACoiC,CAADpiC,CAAS,UAATA,QAAA,CAA4B,CAA5B,CAA+B,EAA/B,CACRoiC,EAAA,EAAS,CAAAvG,GAAA,CAAcwG,CAAA,CAAQ,CAAR,CAAd,CACT,KAAIG,EAAW,IACf,IAAmBt4B,IAAAA,EAAnB,GAAIm4B,CAAA,CAAQ,CAAR,CAAJ,CAA8B,CACtBI,CAAAA,CAAUJ,CAAA,CAAQ,CAAR,CACdG,EAAA,CAAW,CAAA7B,GAAA,CAAc8B,CAAd,CACX,IAAkB,CAAlB,EAAIJ,CAAA,CAAQ,CAAR,CAAJ,EAAuBI,CAAvB,EAAkC,CAAA9F,GAAlC,CACI6F,CAAA,CAAWA,CAAAjiC,QAAA,CAAiB,MAAjB,CAAyBf,CAAA,CAAUgiC,EAAA,CAAmB3e,CAAnB,CAAyBtjB,CAAzB,CAA6B+iC,CAAAI,IAAA,EAA7B,CAAV,CAAyD,CAAzD,CAAzB,CADf,KAII,KAAA,CAAOJ,CAAApgC,OAAP,CAAA,CACIsgC,CAAA,CAAWA,CAAAjiC,QAAA,CAAiB,IAAjB,CAAuBf,CAAA,CAAUD,CAAV,CAAc+iC,CAAAI,IAAA,EAAd,CAA+B,CAA/B,CAAvB,CAGfD,EAAJ,EAAe,CAAAlG,EAAf,EAA8C,CAA9C,EAAgC8F,CAAA,CAAQ,CAAR,CAAhC,EACa,EADb,EACQ9iC,CADR,EACyB,GADzB,CACqBA,CADrB,GAEQijC,CAFR,EAEoB,KAFpB,CAE4BtjC,MAAAC,aAAA,CAAoBI,CAApB,CAF5B,CAEqD,GAFrD,CAX0B,CAgB9B,GAAIkjB,CAAJ,EAAe,CAAApa,EAAAwK,GAAf;CACQtT,CAEA,CAFI,CAAAu8B,EAAA55B,OAEJ,GADAsgC,CACA,CADW,CAAA1G,EAAA,CAAiBv8B,CAAjB,CACX,EAAAA,CAAA,EAAK,CAAA8I,EAAAyK,GAHb,EAGiC,CACzBwnB,CAAA,CAAK,CAEL,KADAkI,CACA,CADW,GACX,CAAQjjC,CAAR,CAAY,CAAA8jB,EAAA,CAAaR,CAAA,EAAb,CAAZ,CAAA,CACa,EAAT,CAAIyX,CAAJ,CACIkI,CADJ,EACgBtjC,MAAAC,aAAA,CAAoBI,CAApB,CADhB,CAEe,EAFf,EAES+6B,CAFT,GAGIkI,CAHJ,EAGgB,QAHhB,CAIA,CAAAlI,CAAA,EAEJkI,EAAA,EAAY,GAVa,CAa7BA,CAAJ,GAAcJ,CAAd,EAAuB,GAAvB,CAA6BI,CAA7B,CACIL,EAAJ,GAEIC,CACA,CADQpiC,CADRoiC,CACQpiC,CADC,iBACDA,QAAA,CAAa,CAAb,CAAgB,EAAhB,CACR,CAAAoiC,CAAA,EAAS,GAAT,CAAeD,CAAAx1B,SAAA,EAHnB,CAKA,EAAAg2B,EAAA,CAAe9f,CACf,OAAOuf,EA5DX;AA6QAQ,QAAA,EAAW,CAAXA,CAAW,CAACC,CAAD,CACX,CACI,IAAIhgB,EAAO,CAAAyY,GACX,IAAcpxB,IAAAA,EAAd,GAAI24B,CAAJ,CAAyB,CACrB,IAAIC,EAAQ,EACW,IAAvB,EAAID,CAAA5b,OAAA,CAAa,CAAb,CAAJ,CACI4b,CADJ,CACYA,CAAA7iC,OAAA,CAAa,CAAb,CADZ,CAG0B,IAA1B,EAAI6iC,CAAA7iC,OAAA,CAAa,CAAb,CAAgB,CAAhB,CAAJ,CACI6iC,CADJ,CACYA,CAAA7iC,OAAA,CAAa,CAAb,CADZ,CAGoC,GAHpC,EAGI6iC,CAAA5b,OAAA,CAAa4b,CAAA3gC,OAAb,CAA0B,CAA1B,CAHJ,GAII4gC,CACA,CADQ,EACR,CAAAD,CAAA,CAAQA,CAAA7iC,OAAA,CAAa,CAAb,CAAgB6iC,CAAA3gC,OAAhB,CAA6B,CAA7B,CALZ,CAOA2gB,EAAA,CAAOwE,QAAA,CAASwb,CAAT,CAAgBC,CAAhB,CACHnkC,MAAA,CAAMkkB,CAAN,CAAJ,GACI,CAAA3V,EAAA,CAAa,eAAb,CAA+B41B,CAA/B,CAAuC,YAAvC,CAAsDD,CAAtD,CACA,CAAAhgB,CAAA,CAAO3Y,IAAAA,EAFX,CAbqB,CAkBZA,IAAAA,EAAb,GAAI2Y,CAAJ,GAA2BA,CAA3B,CAAkC,CAAArF,EAAlC,EAAiDqF,CAAjD,EAAyD,CAAAnF,GAAzD,IACI,CAAAxQ,EAAA,CAAa,wBAAb,CAAwC1N,CAAA,CAAUqjB,CAAV,CAAxC,CACA,CAAAA,CAAA,CAAO3Y,IAAAA,EAFX,CAIA,OAAO2Y,EAxBX;AA+OAkgB,QAAA,GAAO,CAAPA,CAAO,CAACt/B,CAAD,CACP,CACI,GAAa,GAAb,EAAIA,CAAJ,CACI,CAAAyJ,EAAA,CAAa,uBAAb,CACA,CAAA,CAAAA,EAAA,CAAa,mCAAb,CAFJ,KAAA,CADJ,IAMQ81B,EAAQ,CACZ,IAAI,CAAAjgB,EAAJ,CACI,GAAa,OAAb,EAAItf,CAAJ,CAAsB,CAClB,IAAK3D,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB,CAAAijB,EAAA7gB,OAAhB,CAA2CpC,CAAA,EAA3C,CACI,CAAAijB,EAAA,CAAmBjjB,CAAnB,CAAA,CAAwB,CAACA,CAAD,CAAI,CAAJ,CAC5B,EAAAoN,EAAA,CAAa,wBAAb,CACA81B,EAAA,EAJkB,CAAtB,IAMK,IAAc94B,IAAAA,EAAd,GAAIzG,CAAJ,CACD,CAAAyJ,EAAA,CAAa,6BAAb,CAA6CzJ,CAA7C,CACA,CAAAu/B,CAAA,EAFC,KAIA,CACD,IAAIC,EAAsB,CAAAlgB,EAAAvV,MAAA,EAC1By1B,EAAAC,KAAA,CAAyB,QAAQ,CAAC3gC,CAAD,CAAI4gC,CAAJ,CAAO,CAAC,MAAOA,EAAA,CAAE,CAAF,CAAP,CAAc5gC,CAAA,CAAE,CAAF,CAAf,CAAxC,CACA,KAAKzC,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgBmjC,CAAA/gC,OAAhB,CAA4CpC,CAAA,EAA5C,CAAiD,CAC7C,IAAIsjC,EAAUH,CAAA,CAAoBnjC,CAApB,CAAA,CAAuB,CAAvB,CAAd,CACIujC,EAAQJ,CAAA,CAAoBnjC,CAApB,CAAA,CAAuB,CAAvB,CACRujC,EAAJ,GACI,CAAAn2B,EAAA,CAAa,CAAA2uB,GAAA,CAAc,CAAAG,GAAA,CAAkBoH,CAAlB,CAAA,CAA2B,CAA3B,CAAd,CAAb,CAA4D,IAA5D,CAAmE9d,CAAA,CAAc8d,CAAd,CAAnE,CAA4F,KAA5F,CAAoGC,CAApG,CAA4G,QAA5G,CACA,CAAAL,CAAA,EAFJ,CAH6C,CAHhD,CAaJA,CAAL,EACI,CAAA91B,EAAA,CAAa,6BAAb,CA/BJ,CADJ;AAsHAi0B,QAAA,GAAY,CAAZA,CAAY,CAAC0B,CAAD,CAAQS,CAAR,CAAkBnlC,CAAlB,CACZ,CACI,IAAI0kB,EAAO+f,CAAA,CAAAA,CAAA,CAAiBC,CAAjB,CACX,IAAa34B,IAAAA,EAAb,GAAI2Y,CAAJ,CAAA,CAGU3Y,IAAAA,EAAV,GAAI/L,CAAJ,GAAqBA,CAArB,CAAyB,CAAzB,CACIolC,EAAAA,CAAU,CAAA7lB,GACd,IAAiBxT,IAAAA,EAAjB,GAAIo5B,CAAJ,CAA4B,CACxBC,CAAA,CAAUX,CAAA,CAAAA,CAAA,CAAiBU,CAAjB,CACV,IAAgBp5B,IAAAA,EAAhB,GAAIq5B,CAAJ,EAA6BA,CAA7B,CAAuC1gB,CAAvC,CACI,MACJ,IAAiC,GAAjC,CAAe0gB,CAAf,CAAyB1gB,CAAzB,CAAwC,CAOpC,CAAA3V,EAAA,CAAa,iBAAb,CACA,OARoC,CAUxCq2B,CAAA,EACAplC,EAAA,CAAK,EAfmB,CAqB5B,IAHI0kB,CAGJ,EAHY,CAAAyY,GAGZ,EAFI,CAAApuB,EAAA,EAEJ,CAAO/O,CAAA,EAAP,EAAc0kB,CAAd,CAAqB0gB,CAArB,CAAA,CACQC,CAEJ,CAFWtB,EAAA,CAAAA,CAAA,CAAoBrf,CAApB,CAA0B9U,CAAA,CAAAA,CAAA,CAAY,CAAA,CAAZ,CAAA,EAAsB,CAAAmzB,GAAtB,CAAsC,CAAApe,EAAtC,CAAkD,CAA5E,CAEX,CADA,CAAA5V,EAAA,CAAas2B,CAAb,CACA,CAAA,CAAAlI,GAAA,CAAgBzY,CAAhB,CAAuB,CAAA8f,EA7B3B,CAFJ;AAsGAvB,QAAA,GAAW,CAAXA,CAAW,CAACqC,CAAD,CACX,CACI,GAAIA,CAAJ,EAA2B,GAA3B,EAAcA,CAAA,CAAO,CAAP,CAAd,CACI,CAAAv2B,EAAA,CAAa,sBAAb,CAIA,CAHA,CAAAA,EAAA,CAAa,kBAAb,CAGA,CAFA,CAAAA,EAAA,CAAa,+BAAb,CAEA,CADA,CAAAA,EAAA,CAAa,oBAAb,CACA,CAAA,CAAAA,EAAA,CAAa,gCAAb,CALJ,KAAA,CAQA,IAAIw2B,EAAO,CAAA,CACX,IAAex5B,IAAAA,EAAf,GAAIu5B,CAAJ,EAA4C,CAA5C,CAA4BA,CAAAvhC,OAA5B,CAA+C,CAC3CwhC,CAAA,CAAO,CAAA,CACP,KAAI3kB,EAAO0kB,CAAA,CAAO,CAAP,CAAX,CAEI3jC,EAAIif,CAAA9e,QAAA,CAAa,MAAb,CACR,IAAQ,CAAR,CAAIH,CAAJ,CACI+O,CACA,CADSkQ,CAAA/e,OAAA,CAAYF,CAAZ,CAAc,CAAd,CACT,CAAAif,CAAA,CAAOA,CAAA/e,OAAA,CAAY,CAAZ,CAAeF,CAAf,CAFX,KAIK,IAAoB,CAApB,CAAI2jC,CAAAvhC,OAAJ,CACD2M,CAAA,CAAS40B,CAAA,CAAO,CAAP,CADR,KAGA,CACD,CAAAv2B,EAAA,CAAa,oBAAb,CAAoCu2B,CAAA,CAAO,CAAP,CAApC,CACA,OAFC,CAIDlkC,CAAAA,CAAI8nB,QAAA,CAASxY,CAAT,CAAiB,EAAjB,CACR,IAAKlQ,KAAA,CAAMY,CAAN,CAAL,CA2CK,CACD,CAAA2N,EAAA,CAAa,iBAAb,CAAiC2B,CAAjC,CACA,OAFC,CA1CD,OAAOkQ,CAAAG,YAAA,EAAP,EACA,KAAK,GAAL,CACI,CAAA7W,EAAA+W,EAAA,CAAgB7f,CAAhB,CAAoB,GACpB,MACJ,MAAK,GAAL,CACI,CAAA8I,EAAAgX,EAAA,CAAgB9f,CAAhB;AAAoB,GACpB,MACJ,MAAK,GAAL,CACI,CAAA8I,EAAAiX,EAAA,CAAgB/f,CAAhB,CAAoB,GACpB,MACJ,MAAK,GAAL,CACW,CAAA8I,EAp8PnBib,EAAA,CAo8PgB/jB,CAAJ,CAp8PC,GAo8PD,CA98PC,CA+8PD,MACJ,MAAK,GAAL,CACW,CAAA8I,EA34PnBkb,EAAA,CA24PgBhkB,CAAJ,CA34PC,CA24PD,CAr5PC,CAs5PD,MACJ,MAAK,GAAL,CACQA,CAAJ,CAAOokB,EAAA,CAAA,CAAAtb,EAAA,CAAP,CAA+Buc,EAAA,CAAA,CAAAvc,EAAA,CAC/B,MACJ,MAAK,GAAL,CACQ9I,CAAJ,EAAO8I,CAr6PA,CAq6PAA,CAAAA,EAr6PA,CAAnB,CAAAmb,EAAmB,CAAN,CAAM,CAAA,CAAAC,EAAA,CAAa,GAq6PpB,GAA6Bpb,CA/6PtB,CA+6PsBA,CAAAA,EA/6PtB,CAAnB,CAAAmb,EAAmB,CAAN,CAAM,CAAA,CAAAC,EAAA,CAAa,CA+6PpB,CACA,MACJ,MAAK,GAAL,CACW,CAAApb,EA57PnBqb,EAAA,CA47PgBnkB,CAAJ,CA57PC,GA47PD,CAt8PC,CAu8PD,MACJ,MAAK,GAAL,CACI,GAAmB,GAAnB,GAAKA,CAAL,CAAS,IAAT,EAA0B,CACtB,CAAA2N,EAAA,CAAa,yBAAb,CAAyC2B,CAAzC,CACA,OAFsB,CAI1B,CAAAxG,EAAA2X,EAAA,CAAgBzgB,CAChB,MACJ,MAAK,IAAL,CACImkC,CAAA,CAAO,CAAA,CACP,EAAAr7B,EAAAyU,EAAA,CAAiBvd,CAAjB,CAAqB,KACrB,EAAA+7B,GAAA,CAAgB,CAAAjzB,EAAAyU,EAChB,MACJ,SACI,CAAA5P,EAAA,CAAa,oBAAb,CAAoC6R,CAApC,CACA,OAvCJ,CA8CJ,CAAA1W,EAAA0V,OAAA,EAhE2C,CAkE/C,CAAA7Q,EAAA,CAxiBO,OAwiBP,CAxiBc1N,CAAA,CAwiBDmkC,CAxiBWt7B,EAAA+W,EAAV,CAAyB,CAAzB,CAwiBd,CAviBM,QAuiBN,CAviBc5f,CAAA,CAuiBDmkC,CAviBWt7B,EAAAgX,EAAV,CAAyB,CAAzB,CAuiBd,CAtiBM,QAsiBN,CAtiBc7f,CAAA,CAsiBDmkC,CAtiBWt7B,EAAAiX,EAAV,CAAyB,CAAzB,CAsiBd,CAriBM,QAqiBN,CAriBc9f,CAAA,CAAUggB,EAAA,CAqiBXmkB,CAriBWt7B,EAAA,CAAV,CAA8B,CAA9B,CAqiBd,CApiBM,QAoiBN,CApiBc7I,CAAA,CAoiBDmkC,CApiBWt7B,EAAA2X,EAAV,CAAyB,CAAzB,CAoiBd;AAniBM,SAmiBN,CAniBexgB,CAAA,CAmiBFmkC,CAniBYt7B,EAAAyU,EAAV,CAA0B,CAA1B,CAmiBf,CACI4mB,EAAJ,EAAUvC,EAAA,CAAAA,CAAA,CAAkB3hC,CAAA,CAAU,CAAA87B,GAAV,CAA0B,CAAAjzB,EAAAyU,EAA1B,CAA0C,CAA1C,CAAlB,CA5EV,CADJ,CAiHA8mB,QAAA,GAAO,CAAPA,CAAO,CAACC,CAAD,CACP,CACQC,CAAAA,CAAgB55B,IAAAA,EAAX,GAAA25B,CAAA,CAAsB,CAAtB,CAA0Bxc,QAAA,CAASwc,CAAT,CAAiB,EAAjB,CACnC,KAAI1lC,EAAU,CAAL,EAAA2lC,CAAA,CAAQ,CAAR,CAAY,CACrBC,GAAA,CACID,CADJ,CAEI,QAAQ,CAAC17B,CAAD,CAAM,CACV,MAAO,SAAQ,EAAG,CACd,MAAO6F,EAAA,CAAA7F,CAAA,CAAY,CAAA,CAAZ,CAAP,EAA4BA,CAAAwZ,KAAA,CAASzjB,CAAT,CADd,CADR,CAAd,CAIE,CAJF,CAFJ,CAOI,QAAQ,CAACiK,CAAD,CAAM,CACV,MAAO,SAAQ,EAAG,CACd6F,CAAA,CAAA7F,CAAA,CAAY,CAAA,CAAZ,CADc,CADR,CAAd,CAIE,CAJF,CAPJ,CAHJ;AAkBA47B,QAAO,GAAK,CAAC57B,CAAD,CAAM67B,CAAN,CACZ,CACSA,CAAA/hC,OAAL,GACQkG,CAAAozB,GAAJ,EACIpzB,CAAA8E,EAAA,CAAY,kBAAZ,CAAiC1N,CAAA,CAAU4I,CAAAqzB,GAAV,CAAgC,CAAhC,CAAjC,CAEA,CADArzB,CAAAkzB,GACA,CADelzB,CAAAqzB,GACf,CAAArzB,CAAAozB,GAAA,CAAgB,CAAA,CAHpB,EAMIpzB,CAAAmzB,GANJ,GAOI0I,CAPJ,CAOW77B,CAAAmzB,GAPX,CADJ,CAUA,IAAI1tB,CAAA,CAAAzF,CAAA,CAAJ,EAAqB,CAAC2F,CAAA,CAAA3F,CAAA,CAAW,CAAA,CAAX,CAAtB,EAAwD,CAAxD,CAA0C67B,CAAA/hC,OAA1C,CAA2D,CAEnDkG,CAAAozB,GAAJ,CACIyI,CADJ,CACW,IADX,CACkBzkC,CAAA,CAAU4I,CAAAqzB,GAAV,CAAgC,CAAhC,CADlB,CACuD,GADvD,CAC6DwI,CAD7D,CAGuB,CAHvB,CAGSA,CAAA/hC,OAHT,EAGiD,CAHjD,EAG4B+hC,CAAAhkC,QAAA,CAAa,GAAb,CAH5B,GASIgkC,CATJ,CAQaA,CAAAhd,OAAA,CAAY,CAAZ,CAAA7mB,YAAA+rB,EARb,CASgB,GAThB,CASsB8X,CAAAjkC,OAAA,CAAY,CAAZ,CATtB,CAYA,KAAIyjC,EAASQ,CAAAl6B,MAAA,CAAW,GAAX,CACb3B,EAAAmzB,GAAA,CAAckI,CAAA,CAAO,CAAP,CAEd,QAAOA,CAAA,CAAO,CAAP,CAAArjC,YAAA,EAAP,EACA,KAAK,GAAL,CA9iBJ,IAAIyiB,EAAO+f,CAAA,CA+iBHx6B,CA/iBG,CA+iBYq7B,CA/iBK,CAAO,CAAP,CAAjB,CACX,IAAav5B,IAAAA,EAAb,GAAI2Y,CAAJ,CAGA,GA2iBQza,CA5iBRqzB,GACI,CADoB5Y,CACpB,CAAc3Y,IAAAA,EAAd,GA2iBmBu5B,CA3iBnB,CAAO,CAAP,CAAJ,CA2iBQr7B,CA1iBJ8E,EAAA,CAAa,kBAAb,CAAkCgW,CAAA,CA0iB9B9a,CA1iB4CqzB,GAAd,CAAlC,CAEA,CAwiBIrzB,CAziBJozB,GACA,CADiB,CAAA,CACjB,CAwiBIpzB,CAxiBJC,EAAA0V,OAAA,EAHJ,KAAA,CAMqC,CAAA,CAqiBd0lB,CAriBc,CAAO,CAAP,CAAW,KAAA,EAqiBzBA,CAriByB,CAAO,CAAP,CAAWhI,EAAAA,CAqiBnDrzB,CAriBmDqzB,GA3OvDyI,EAAAA,CAAW,EACf,IAAch6B,IAAAA,EAAd,GAAIi6B,CAAJ,CAAyB,CAAA,IACjBC,CAIJD,EAAA,CAAQA,CAAAjlB,YAAA,EAC4B,IAApC,EAAIilB,CAAAld,OAAA,CAAakd,CAAAjiC,OAAb;AAA0B,CAA1B,CAAJ,GACIsgC,CACA,CADW,GACX,CAAA2B,CAAA,CAAQA,CAAAnkC,OAAA,CAAa,CAAb,CAAgBmkC,CAAAjiC,OAAhB,CAA6B,CAA7B,CAFZ,CAIA,KAAKkiC,CAAL,CAAW,CAAX,CAAcA,CAAd,CAqwBIh8B,CArwBkByzB,GAAA35B,OAAtB,EACQiiC,CADR,EAqwBI/7B,CApwBayzB,GAAA,CAAcuI,CAAd,CADjB,CAA4CA,CAAA,EAA5C,EAKIA,CAAJ,EAgwBIh8B,CAhwBSyzB,GAAA35B,OAAb,GAgwBIkG,CA/vBA8E,EAAA,CAAa,qBAAb,CAAqCi3B,CAArC,CACA,CAAAC,CAAA,CAAS,EAFb,CAfqB,KAmBjBvD,EAAQ,EAnBS,CAmBLwD,CAChB,IAAa,CAAb,EAAID,CAAJ,EAA+Bl6B,IAAAA,EAA/B,GAAkBs4B,CAAlB,CAEI,GADA3B,CACI,CADI2B,CAAAtjB,YAAA,EACJ,CAAS,GAAT,EAAA2hB,CAAJ,CAAkB,CAEd,IAAK/gC,CAAL,CADIwkC,CACJ,CADa,CACb,CAAYxkC,CAAZ,CAuvBJsI,CAvvBoB4zB,GAAA95B,OAAhB,CAA0CpC,CAAA,EAA1C,CAuvBJsI,CAtvBY4zB,GAAA,CAAkBl8B,CAAlB,CAAA,CAAqB,CAArB,CAAJ,GAAgCskC,CAAhC,GACSE,CAEL,EAmvBZl8B,CArvByB8E,EAAA,CAAa,oBAAb,CAEb,CAmvBZ9E,CApvBY8E,EAAA,CAAa,OAAb,CAAuB1N,CAAA,CAAUM,CAAV,CAAa,CAAb,CAAvB,CAAyC,IAAzC,CAAgDqkC,CAAhD,EAAqFj6B,IAAAA,EAA5B,GAovBrE9B,CApvBqE4zB,GAAA,CAAkBl8B,CAAlB,CAAA,CAAqB,CAArB,CAAA,CAAwC,GAAxC,CAovBrEsI,CApvBmHu4B,GAAA,CAovBnHv4B,CApvBiI4zB,GAAA,CAAkBl8B,CAAlB,CAAA,CAAqB,CAArB,CAAd,CAA9C,CAAwF,EAAjJ,EACA,CAAAwkC,CAAA,EAHJ,CAMJF,EAAA,CAAS,EATK,CAAlB,IAgBI,IADAC,CACI,CADSxD,CAAA59B,MAAA,CA0uBjBmF,CA1uB6B04B,GAAZ,CACT,CAAe,IAAf,GAAAuD,CAAA,EAAuBA,CAAA,CAAW,CAAX,CAAvB,EAAwCxD,CAA5C,CAAmD,CAM/C,IAAK/gC,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgBukC,CAAAniC,OAAhB,CAAmCpC,CAAA,EAAnC,CACI,GAAIukC,CAAA,CAAWvkC,CAAX,CAAJ,EAAqB+gC,CAArB,CACI,GAAc32B,IAAAA,EAAd,GAAI02B,CAAJ,CACI,IAAAA,EAAQ9gC,CAAR8gC,CAAU,CADd,KAEK,CA+tBrBx4B,CA1tBoB8E,EAAA,CAAa,iCAAb,CA0tBpB9E,CA1tBqEu4B,GAAA,CAAcC,CAAd,CAAjD,CAAwE,OAAxE;AA0tBpBx4B,CA1tBsGu4B,GAAA,CAAc7gC,CAAd,CAAgB,CAAhB,CAAlF,CAAuG,GAAvG,CACAskC,EAAA,CAAS,EACT,MAPC,CAgBTxD,CAAJ,EA+sBRx4B,CA/sBqB60B,GAAb,EAC0C,CAD1C,CA+sBR70B,CA9sBgB24B,GAAA9gC,QAAA,CAAyBmkC,CAAzB,CADR,GAEQxD,CAFR,CA+sBRx4B,CA7sBwBq0B,EAFhB,CAQImE,EAAJ,EAusBRx4B,CAvsBqB+1B,GAAb,EAluCEP,EAkuCF,EACQwG,CADR,GAEQxD,CAFR,CAusBRx4B,CArsBwBq0B,EAFhB,CAlC+C,CAAnD,IAyuBJr0B,EAjsBQ8E,EAAA,CAAa,mBAAb,CAAmC2zB,CAAnC,CACA,CAAAuD,CAAA,CAAS,EAIrB,IAAa,CAAb,EAAIA,CAAJ,CAAgB,CAIR3hB,CAAAA,CAAW,EACf,KAAK3iB,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAurBAsI,CAvrBgB4zB,GAAA95B,OAAhB,CAA0CpC,CAAA,EAA1C,CACI,GAsrBJsI,CAtrBQ4zB,GAAA,CAAkBl8B,CAAlB,CAAA,CAAqB,CAArB,CAAJ,GAAgCskC,CAAhC,EAsrBJh8B,CAtrB6C4zB,GAAA,CAAkBl8B,CAAlB,CAAA,CAAqB,CAArB,CAAzC,GAAqE8gC,CAArE,CACI,GAAc,CAAd,CAAIne,CAAJ,CACIA,CAAA,CAAU3iB,CADd,KAEK,CAmrBbsI,CA/qBY8E,EAAA,CAAa,qCAAb,CAAqDoY,CAAA,CAAc7C,CAAd,CAArD,CAA8E,OAA9E,CAAwF6C,CAAA,CAAcxlB,CAAd,CAAxF,CAA2G,GAA3G,CACA2iB,EAAA,CAAW,EACX,MANC,CAUb,GAAe,CAAf,EAAIA,CAAJ,CAEI,IADAyhB,CAAAl+B,KAAA,CAAcyc,CAAd,CACI,CAAUvY,IAAAA,EAAV,GAAA02B,CAAJ,CAGI,GAFItG,CAEA,CAoqBZlyB,CAtqBiB4zB,GAAA,CAAkBvZ,CAAlB,CAAA,CAA2B,CAA3B,CAEL,CADA8hB,CACA,CADQ1D,CAAA59B,MAAA,CAAY,WAAZ,CACR,CAAU,IAAV,GAAAshC,CAAJ,CAUI,IATIC,CASC,CATMnd,QAAA,CAASkd,CAAA,CAAM,CAAN,CAAT,CAAmB,EAAnB,CASN,CARK,CAQL,EARDjK,CAQC,EARUsG,CAQV,EA0pBjBx4B,CAlqBoCu0B,GAQnB,GAPD6H,CACI,EADK3hB,CACL,CADY,CACZ,CAAQ,IAAR,CAAA2hB,CAAA,EAAsB,GAAtB,CAAeA,CAMlB,IA0pBjBp8B,CA/pBoB8E,EAAA,CAAa,uBAAb,CAAuCs3B,CAAvC,CAA8C,GAA9C,CAEA,CADAN,CACA,CADW,EACX,CAAA5J,CAAA,CAAK,CAGR,EAAAx6B,CAAA,CAAI,CAAT,CAAYA,CAAZ,CAAgBw6B,CAAhB,CAAoBx6B,CAAA,EAApB,CACIokC,CAAAl+B,KAAA,CAAcw+B,CAAd,CAAqB,GAArB,CACA;AAAAA,CAAA,IAAU,CAZlB,KAeSlK,EAAJ,EAqpBblyB,CAjpBY8E,EAAA,CAAa,sBAAb,CAAsCotB,CAAtC,CAA2C,QAA3C,CAtBR,CAFJ,IAyqBAlyB,EA5oBI8E,EAAA,CAAa,uBAAb,CAAuCi3B,CAAvC,CAA+C,GAA/C,CAAqDtD,CAArD,CAA4F,EAA5F,CAhDQ,CAnFK,CAuIzB,CAAA,CAAOqD,CAoGP,IAAIA,CAAAhiC,OAAJ,CAAqB,CACjB,IAASpC,CAAT,CAAW,CAAX,CAAcA,CAAd,CAAkBokC,CAAAhiC,OAAlB,CAAmCpC,CAAA,EAAnC,CAEI4mB,EAAA,CAiiBAte,CAjiBA,CAiiBAA,CAjiBaqzB,GAAb,CAAmC37B,CAAnC,CAAsCokC,CAAA,CAASpkC,CAAT,CAAtC,CAiiBAsI,EA/hBJ8E,EAAA,CAAag1B,EAAA,CA+hBT95B,CA/hBS,CA+hBTA,CA/hB6BqzB,GAApB,CAAb,CA+hBIrzB,EA9hBJqzB,GAAA,EAAyByI,CAAAhiC,OANR,CAPrB,CA4iBQ,KACJ,MAAK,GAAL,CACgB,CAAA,CAAAuhC,CAAA,CAAO,CAAP,CAAW,EAAA,CAAAA,CAAA,CAAO,CAAP,CAthB/B,IAAcv5B,IAAAA,EAAd,GAAIzG,CAAJ,EAAoC,GAApC,EAA2BA,CAA3B,CAshBQ2E,CArhBJ8E,EAAA,CAAa,wBAAb,CAKA,CAghBI9E,CAphBJ8E,EAAA,CAAa,oCAAb,CAIA,CAghBI9E,CAnhBJ8E,EAAA,CAAa,oCAAb,CAGA,CAghBI9E,CAlhBJ8E,EAAA,CAAa,qCAAb,CAEA,CAghBI9E,CAjhBJ8E,EAAA,CAAa,iCAAb,CACA,CAghBI9E,CAhhBJ8E,EAAA,CAAa,0BAAb,CANJ,KAaA,IAJchD,IAAAA,EAIV,GAJA24B,CAIA,EAJsC,CAItC,CAJuBp/B,CAAAvB,OAIvB;CAHA2gC,CACA,CADQp/B,CAAAzD,OAAA,CAAa,CAAb,CACR,CAAAyD,CAAA,CAAQA,CAAAzD,OAAA,CAAa,CAAb,CAER,EAAS,GAAT,EAAAyD,CAAJ,CAAkB,CACVghC,CAAAA,CAAU,CACVC,EAAAA,CAugBAt8B,CA9gCDka,GAwgBH,KAAKxiB,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB4kC,CAAAxiC,OAAhB,CAA+BpC,CAAA,EAA/B,CAsgBIsI,CArgBA8E,EAAA,CAAa,sBAAb,CAAsCgW,CAAA,CAAcwhB,CAAA,CAAO5kC,CAAP,CAAd,CAAtC,CAAiE,SAAjE,CACA,CAAA2kC,CAAA,EAEJC,EAAA,CAkgBIt8B,CArgCDma,GAogBH,KAAKziB,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB4kC,CAAAxiC,OAAhB,CAA+BpC,CAAA,EAA/B,CAigBIsI,CAhgBA8E,EAAA,CAAa,sBAAb,CAAsCgW,CAAA,CAAcwhB,CAAA,CAAO5kC,CAAP,CAAd,CAAtC,CAAiE,SAAjE,CACA,CAAA2kC,CAAA,EAEJC,EAAA,CA6fIt8B,CA5/BDoa,GAggBH,KAAK1iB,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB4kC,CAAAxiC,OAAhB,CAA+BpC,CAAA,EAA/B,CA4fIsI,CA3fA8E,EAAA,CAAa,sBAAb,CAAsCgW,CAAA,CAAcwhB,CAAA,CAAO5kC,CAAP,CAAd,CAAtC,CAAiE,UAAjE,CACA,CAAA2kC,CAAA,EAECA,EAAL,EAwfIr8B,CAvfA8E,EAAA,CAAa,gBAAb,CAlBU,CAAlB,IAqBchD,KAAAA,EAAd,GAAI24B,CAAJ,CAofQz6B,CAnfJ8E,EAAA,CAAa,4BAAb,CADJ,CAIa,GAAb,EAAIzJ,CAAJ,EAA6B,GAA7B,EAAoBo/B,CAApB,EAgfQz6B,CAhkCRka,GAklBI,CAllBc,EAklBd,CA8eIla,CA/jCRma,GAilBI,CAjlBc,EAilBd,CA8eIna,CA9jCRoa,GAglBI,CAhlBe,EAglBf,CA8eIpa,CA9eJ8E,EAAA,CAAa,yBAAb,CAFJ,GAKI2V,CACJ,CADW+f,CAAA,CA2eHx6B,CA3eG,CAAiBy6B,CAAjB,CACX,CAAa34B,IAAAA,EAAb,GAAI2Y,CAAJ,GAEa,GAAb,EAAIpf,CAAJ,CACQg+B,EAAA,CAueAr5B,CAveA,CAAuBya,CAAvB,CAAJ,CAueIza,CAteA8E,EAAA,CAAa,sBAAb,CAAsCgW,CAAA,CAAcL,CAAd,CAAtC,CAA4D,SAA5D,CADJ;AAueIza,CApeA8E,EAAA,CAAa,sBAAb,CAAsCgW,CAAA,CAAcL,CAAd,CAAtC,CAJR,CAOa,GAAb,EAAIpf,CAAJ,CA1fOi+B,CAAA,CA29BCt5B,CA39BmBka,GAApB,CA2fyBO,CA3fzB,CA2f+B+e,CAAAA,CA3f/B,CA2fH,CAgeIx5B,CA/dA8E,EAAA,CAAa,sBAAb,CAAsCgW,CAAA,CAAcL,CAAd,CAAtC,CAA4D,SAA5D,CADJ,CAhfG6e,CAAA,CAg9BCt5B,CAh9BmBma,GAApB,CAmfyBM,CAnfzB,CAmf+B+e,CAAAA,CAnf/B,CAmfH,CA6dIx5B,CA5dA8E,EAAA,CAAa,sBAAb,CAAsCgW,CAAA,CAAcL,CAAd,CAAtC,CAA4D,SAA5D,CADJ,CAxeG6e,CAAA,CAq8BCt5B,CAr8BmBoa,GAApB,CA2e0BK,CA3e1B,CA2egC+e,CAAAA,CA3ehC,CA2eH,CA0dIx5B,CAzdA8E,EAAA,CAAa,sBAAb,CAAsCgW,CAAA,CAAcL,CAAd,CAAtC,CAA4D,UAA5D,CADJ,CA0dIza,CAvdA8E,EAAA,CAAa,sBAAb,CAAsCgW,CAAA,CAAcL,CAAd,CAAtC,CAVR,CAaa,GAAb,EAAIpf,CAAJ,EA5fOi+B,CAAA,CAg9BCt5B,CAh9BmBma,GAApB,CA6fwBM,CA7fxB,CAvFF+e,IAAA,EAuFE,CA8fC,EAkdAx5B,CAtiCJma,GAAAvc,KAAA,CAmlB2B6c,CAnlB3B,CAolBI,CAkdAza,CAldA8E,EAAA,CAAa,sBAAb,CAAsCgW,CAAA,CAAcL,CAAd,CAAtC,CAA4D,SAA5D,CAFR,EAOa,GAAb,EAAIpf,CAAJ,EAxfOi+B,CAAA,CAq8BCt5B,CAr8BmBoa,GAApB,CAyfyBK,CAzfzB,CArFF+e,IAAA,EAqFE,CA0fC,EA2cAx5B,CAzhCJoa,GAAAxc,KAAA,CA6kB4B6c,CA7kB5B,CA8kBI,CA2cAza,CA3cA8E,EAAA,CAAa,sBAAb,CAAsCgW,CAAA,CAAcL,CAAd,CAAtC,CAA4D,UAA5D,CAFR,EA6cQza,CAtcR8E,EAAA,CAAa,8BAAb,CAA8CzJ,CAA9C,CApCA,CANA,CAifQ,MACJ,MAAK,GAAL,CACe,CAAA,CAAAggC,CAAA,CAAO,CAAP,CAAW,EAAA,CAAAA,CAAA,CAAO,CAAP,CA/b9B,IAAa,GAAb,EAAIZ,CAAJ,CA+bQz6B,CA9bJ8E,EAAA,CAAa,kBAAb,CACA;AA6bI9E,CA7bJ8E,EAAA,CAAa,qCAAb,CAFJ,KAMA,IADI2V,CACA,CADO+f,CAAA,CA0bHx6B,CA1bG,CAAiBy6B,CAAjB,CACP,CAAS34B,IAAAA,EAAT,GAAA2Y,CAAJ,CAAA,CAEI8hB,CAAAA,CAAS,CACAz6B,KAAAA,EAAb,GAAI06B,CAAJ,GAC0B,GAEtB,EAFIA,CAAA3d,OAAA,CAAY,CAAZ,CAEJ,GADI2d,CACJ,CADWA,CAAA5kC,OAAA,CAAY,CAAZ,CACX,EAAA2kC,CAAA,CAAStd,QAAA,CAASud,CAAT,CAAe,EAAf,CAHb,CAKKD,EAAL,GAAaA,CAAb,CAAsB,CAAtB,CACA,KAASE,CAAT,CAAc,CAAd,CAAiBA,CAAjB,CAAwBF,CAAxB,CAAgCE,CAAA,EAAhC,CAAwC,CAEhCC,CAAAA,CADAC,CACAD,CADS,EAETE,EAAAA,CAAWniB,CACf,KAAS/iB,CAAT,CAAW,CAAX,CAAkB,CAAlB,CAAcA,CAAd,EAAuB+iB,CAAvB,CA4aIza,CA5a0BsV,GAA9B,CAA6C5d,CAAA,EAA7C,CACQP,CAIJ,CAuaA6I,CA3aQib,EAAA,CAAaR,CAAb,CAIR,CAHU3Y,IAAAA,EAGV,GAHI3K,CAGJ,GAHqBA,CAGrB,CAHyB,CAGzB,EAFAwlC,CAEA,EAFUvlC,CAAA,CAAUD,CAAV,CAAa,CAAb,CAEV,CAF4B,GAE5B,CADAulC,CACA,EADgB,EAAL,EAAAvlC,CAAA,EAAe,GAAf,CAAWA,CAAX,CAAoBL,MAAAC,aAAA,CAAoBI,CAApB,CAApB,CAA6C,GACxD,CAAAsjB,CAAA,EAuaAza,EAraJ8E,EAAA,CAAa1N,CAAA,CAAUwlC,CAAV,CAAoB,CAApB,CAAb,CAAsC,GAAtC,CAA4CD,CAA5C,CAAqDD,CAArD,CAXoC,CAgbhC18B,CAnaRkzB,GAAA,CAAgBzY,CAtBhB,CA0bQ,KACJ,MAAK,GAAL,CA5ZAggB,CAAAA,CA6ZeY,CA7ZP,CAAO,CAAP,CACZ,IAAcv5B,IAAAA,EAAd,GAAI24B,CAAJ,CA4ZQz6B,CA3ZJ8E,EAAA,CAAa,iBAAb,CADJ,KAKA,IADI2V,CACA,CADO+f,CAAA,CAwZHx6B,CAxZG,CAAiBy6B,CAAjB,CACP,CAAS34B,IAAAA,EAAT,GAAA2Y,CAAJ,CAEA,IAAS/iB,CAAT,CAAW,CAAX,CAAcA,CAAd,CAqZmB2jC,CArZDvhC,OAAlB,CAAiCpC,CAAA,EAAjC,CACQP,CACJ,CADQ8nB,QAAA,CAoZOoc,CApZE,CAAO3jC,CAAP,CAAT,CAAoB,EAApB,CACR,CAAA4mB,EAAA,CAmZIte,CAnZJ,CAAaya,CAAA,EAAb,CAAqBtjB,CAArB,CAoZI,MACJ,MAAK,GAAL,CACIwjC,EAAA,CAAA36B,CAAA,CAAYq7B,CAAA,CAAO,CAAP,CAAZ,CACA,MACJ,MAAK,GAAL,CACc,CAAA;AAAAA,CAAA,CAAO,CAAP,CA5FJv5B,KAAAA,EAAd,GAAI24B,CAAJ,EACId,EAAA,CA2FI35B,CA3FJ,CAAuBw6B,CAAA,CA2FnBx6B,CA3FmB,CAAiBy6B,CAAjB,CAAvB,CA2FIz6B,EA1FH8U,GAAA,EAAL,EA0FQ9U,CAzFJC,EAAAyV,GAAA,EA0FI,MACJ,MAAK,GAAL,CACI1V,CA1WRyU,GAAA,EA2WQ,MACJ,MAAK,GAAL,CArPJ,GAAkB3S,IAAAA,EAAlB,GAsPsBu5B,CAtPlB,CAAO,CAAP,CAAJ,EAA4C,GAA5C,EAsPsBA,CAtPS,CAAO,CAAP,CAA/B,CAsPQr7B,CArPJ8E,EAAA,CAAa,oBAAb,CAMA,CA+OI9E,CApPJ8E,EAAA,CAAa,2BAAb,CAKA,CA+OI9E,CAnPJ8E,EAAA,CAAa,0BAAb,CAmPI9E,CAnPsCC,EAAA8J,GAA1C,CAA6D,MAA7D,CAIA,CA+OI/J,CAlPJ8E,EAAA,CAAa,kCAAb,CAGA,CA+OI9E,CAjPJ8E,EAAA,CAAa,qCAAb,CAEA,CA+OI9E,CAhPJ8E,EAAA,CAAa,mCAAb,CACA,CA+OI9E,CA/OJ8E,EAAA,CAAa,gCAAb,CAPJ,KAWA,QADI+3B,CACGA,CA2OexB,CA5OR,CAAO,CAAP,CACPwB,CAAAA,CAAP,EACA,KAAK,MAAL,CACI7nB,CAAA,CAyOIhV,CAzOJC,EAAA,CAyOID,CAzOcC,EAAAwJ,GAAlB,CACA,MACJ,MAAK,MAAL,CACIuL,CAAA,CAsOIhV,CAtOJC,EAAA,CAsOID,CAtOcC,EAAAyJ,GAAlB,CACA,MACJ,MAAK,KAAL,CACIsL,CAAA,CAmOIhV,CAnOJC,EAAA,CAmOID,CAnOcC,EAAA0J,GAAlB,CACA,MACJ,MAAK,SAAL,CACIgqB,EAAA,CAgOI3zB,CAhOJ;AAAgB,CAAA,CAAhB,CAgOIA,EA/NJ8E,EAAA,CAAa,wBAAb,CACA,MACJ,MAAK,QAAL,CACI6uB,EAAA,CA4NI3zB,CA5NJ,CAAgB,CAAA,CAAhB,CA4NIA,EA3NJ8E,EAAA,CAAa,uBAAb,CACA,MACJ,MAAK,KAAL,CACQ7F,CAAAA,CAAc,CACA6C,KAAAA,EAAlB,GAuNkBu5B,CAvNd,CAAO,CAAP,CAAJ,GACqB,KAAjB,EAsNcA,CAtNV,CAAO,CAAP,CAAJ,CACIp8B,CADJ,CACkB,GADlB,CAEgD6C,IAAAA,EAFhD,GAsNA9B,CApNSwzB,GAAA,CAoNK6H,CApNmB,CAAO,CAAP,CAAxB,CAFT,GAGIp8B,CAHJ,CAsNAe,CAnNkBwzB,GAAA,CAmNJ6H,CAnN4B,CAAO,CAAP,CAAxB,CAHlB,CAIA,CAAIp8B,CAAJ,GACqB,IAAjB,EAiNUo8B,CAjNN,CAAO,CAAP,CAAJ,CAiNJr7B,CAhNQf,GADJ,EACwBA,CADxB,CAGsB,KAHtB,EAiNUo8B,CA9MD,CAAO,CAAP,CAHT,GAiNJr7B,CA7MQf,GAJJ,EAIwB,CAACA,CAJzB,CADJ,CALJ,CAcA,KAAS69B,CAAT,GAyMI98B,EAzMkBwzB,GAAtB,CACI,GAAkB1xB,IAAAA,EAAlB,GAwMcu5B,CAxMV,CAAO,CAAP,CAAJ,EAA6C,KAA7C,EAwMcA,CAxMkB,CAAO,CAAP,CAAhC,EAwMcA,CAxMwC,CAAO,CAAP,CAAtD,EAAmEyB,CAAnE,CACA79B,CACA,CAsMAe,CAvMcwzB,GAAA,CAAwBsJ,CAAxB,CACd,CAsMA98B,CAtMA8E,EAAA,CAAag4B,CAAb,CAAyB,aAAzB,EAsMA98B,CAtM2Cf,GAAD,CAAoBA,CAApB,CAAkC,IAAlC,CAAyC,KAAnF,EAEJ,MACJ,SAmMQe,CAlMJ8E,EAAA,CAAa,kBAAb,CAAkC+3B,CAAlC,CAzCJ,CA4OQ,KACJ,MAAK,GAAL,CACkB,CAAA,CAAAxB,CAAA,CAAO,CAAP,CAvWlBkB,EAAAA,CAAS,EACTQ,EAAAA,CAsWI/8B,CAtWO6a,GACXmiB,EAAAA,CAqWIh9B,CArWO4a,GACf,IAAiB9Y,IAAAA,EAAjB,GAAIk7B,CAAJ,CAA4B,CACpBjnC,CAAAA,CAAgB+L,IAAAA,EAAX,GAAA25B,CAAA,CAmWLz7B,CAnW2Bi9B,GAAtB,CAAyChe,QAAA,CAASwc,CAAT,CAAiB,EAAjB,CACxC35B,KAAAA,EAAV,GAAI/L,CAAJ,GACIA,CADJ,CACQ,EADR,CAEIA,EAAJ,CAAQinC,CAAAljC,OAAR,GAgWIkG,CA/VA8E,EAAA,CAAa,aAAb;AAA6Bk4B,CAAAljC,OAA7B,CAA+C,YAA/C,CACA,CAAA/D,CAAA,CAAIinC,CAAAljC,OAFR,CAIegI,KAAAA,EAAf,GAAI25B,CAAJ,GA4VIz7B,CA3VAk9B,GACA,CADmB,CACnB,CA0VAl9B,CA1VA8E,EAAA,CAAa/O,CAAb,CAAiB,wBAAjB,CAFJ,CAIIgkC,EAAAA,CAwVA/5B,CAxVQk9B,GAAA,CAwVRl9B,CAxV0Bk9B,GAAlB,CAAqC,CACjDH,EAAA,EAAYhnC,CAEZ,KADe,CACf,CADIgnC,CACJ,GADkBA,CAClB,CAD6BC,CAAAljC,OAC7B,CAD+C,CAC/C,EAAOyiC,CAAP,EAAiBQ,CAAjB,EAqVI/8B,CArVyB6a,GAA7B,CAAA,CAAgD,CACxCJ,CAAAA,CAAOuiB,CAAA,CAASD,CAAT,CACX,IAAW,CAAX,CAAItiB,CAAJ,CAAc,KAmVdza,EAlVA8E,EAAA,CAAag1B,EAAA,CAkVb95B,CAlVa,CAAoBya,CAApB,CAA0Bsf,CAAA,EAA1B,CAAb,CACI,GAAEgD,CAAN,EAAkBC,CAAAljC,OAAlB,GAAmCijC,CAAnC,CAA8C,CAA9C,CACAR,EAAA,EACAxmC,EAAA,EAN4C,CAqV5CiK,CA7UJi9B,GAAA,CAAmBlnC,CA6UfiK,EA5UJk9B,GAAA,CAAmBnD,CAxBK,CA0Bd,EAAd,EAAIwC,CAAJ,EA0UQv8B,CA1UU8E,EAAA,CAAa,sBAAb,CA2UV,MACJ,MAAK,GAAL,CACIk0B,EAAA,CAAAh5B,CAAA,CAAgBq7B,CAAhB,CACA,MACJ,MAAK,GAAL,CACIr7B,CA/FJib,EAAA,CA+FIjb,CA/FSC,EAAAyU,EAAb,CAAJ,EA+FQ1U,CA/F4BC,EAAAuK,GAApC,EACImvB,EAAA,CA8FI35B,CA9FJ,CA8FIA,CA9FmBC,EAAAyU,EAAvB,CAAsC,CAAtC,CAEA,CA4FI1U,CA7FJ84B,GACA,CADiB,CAAA,CACjB,CA4FI94B,CA5FC8U,GAAA,EAAL,EA4FI9U,CA3FAC,EAAAyV,GAAA,EAJR,EAOI8lB,EAAA,CAwFIx7B,CAxFJ,CAyFI,MACJ,MAAK,GAAL,CACIw7B,EAAA,CAAAx7B,CAAA,CAAYq7B,CAAA,CAAO,CAAP,CAAZ,CACA,MACJ,MAAK,GAAL,CACItC,EAAA,CAAA/4B,CAAA,CAAiBq7B,CAAA,CAAO,CAAP,CAAjB,CAA4BA,CAAA,CAAO,CAAP,CAA5B,CAAuC,CAAvC,CACA,MACJ,MAAK,GAAL,CACA,KAAK,MAAL,CACIr7B,CAznBR8E,EAAA,CAAa,qRAAb,CAynBQ9E;CAxnBR8E,EAAA,CAAa,4EAAb,CAynBQ,MAIJ,SACI9E,CAAA8E,EAAA,CAAY,mBAAZ,CAAkC+2B,CAAlC,CAhDJ,CAjBuD,CAX/D,CA2GA1yB,CAAA,CAjBAV,QAAW,EACX,CAEI,IADA,IAAI00B,EAAQl8B,CAAA,CAA6B2H,QAA7B,CAhnTLC,OAgnTK,CAAuD,UAAvD,CAAZ,CACSu0B,EAAK,CAAd,CAAiBA,CAAjB,CAAwBD,CAAArjC,OAAxB,CAAsCsjC,CAAA,EAAtC,CAA8C,CAC1C,IAAIC,EAAOF,CAAA,CAAMC,CAAN,CAAX,CACInK,EAAWpxB,CAAA,CAA4Bw7B,CAA5B,CACXr9B,EAAAA,CAAM,IAAIgzB,EAAJ,CAAgBC,CAAhB,CACV/pB,EAAA,CAAgClJ,CAAhC,CAAqCq9B,CAArC,CAJ0C,CAFlD,CAgBA,CA6CAv+B,SA7BEw+B,EA6BS,CAACC,CAAD,CAAgBC,CAAhB,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,aAAN,CAAqBD,CAArB,CAEA,KAAAC,EAAA,CAAeA,CAHnB,CA9BsBp1B,CAAArJ,CAApBu+B,CAAoBv+B,CAAAA,CAAAA,CA0CtB,EAAA,UAAA,MAAA,CAAAwV,QAAK,CAACC,CAAD,CACL,CACI,IAAIvU,EAAM,IAAV,CACSoC,CAAT,KAASA,CAAT,GAAkB,KAAAm7B,EAAlB,CACI,IAAK,IAAI9lC,EAAE,CAAX,CAAcA,CAAd,CAAkB,IAAA8lC,EAAA,CAAan7B,CAAb,CAAAvI,OAAlB,CAA8CpC,CAAA,EAA9C,CAAmD,CAC/C,IAAI0I,EAAY,IAAAo9B,EAAA,CAAan7B,CAAb,CAAA,CAAoB3K,CAApB,CACZ0I,EAAJ,EAAiBA,CAAAmU,MAAjB,GAEInU,CAAAmU,MAAA,EACA,CAAa,KAAb,EAAIlS,CAAJ,GAAoBpC,CAApB,CAA0BG,CAA1B,CAHJ,CAF+C,CASnDH,CAAJ,GACIA,CAAA0V,OAAA,EACA,CAAInB,CAAJ,EAAcvU,CAAA6U,GAAA,EAFlB,CAZJ,CAyBA;CAAA,UAAA,MAAA,CAAA5N,QAAK,EACL,CACI,IAAK7E,IAAIA,CAAT,GAAkB,KAAAm7B,EAAlB,CACI,GAAa,KAAb,EAAIn7B,CAAJ,CACA,IAAK,IAAI3K,EAAE,CAAX,CAAcA,CAAd,CAAkB,IAAA8lC,EAAA,CAAan7B,CAAb,CAAAvI,OAAlB,CAA8CpC,CAAA,EAA9C,CAAmD,CAC/C,IAAI0I,EAAY,IAAAo9B,EAAA,CAAan7B,CAAb,CAAA,CAAoB3K,CAApB,CACZ0I,EAAJ,EAAiBA,CAAA8G,MAAjB,EACI9G,CAAA8G,MAAA,EAH2C,CAH3D,CAqBA,EAAA,UAAA,KAAA,CAAA2S,QAAI,CAACof,CAAD,CAAUxf,CAAV,CACJ,CACI,IAAKpX,IAAIA,CAAT,GAAkB,KAAAm7B,EAAlB,CACI,GAAa,KAAb,EAAIn7B,CAAJ,CACA,IAAK,IAAI3K,EAAE,CAAX,CAAcA,CAAd,CAAkB,IAAA8lC,EAAA,CAAan7B,CAAb,CAAAvI,OAAlB,CAA8CpC,CAAA,EAA9C,CAAmD,CAC/C,IAAI0I,EAAY,IAAAo9B,EAAA,CAAan7B,CAAb,CAAA,CAAoB3K,CAApB,CACZ0I,EAAJ,EAAiBA,CAAAyZ,KAAjB,EACIzZ,CAAAyZ,KAAA,CAAeof,CAAf,CAAwBxf,CAAxB,CAH2C,CAH3D,CAoBA,EAAA,UAAA,EAAA,CAAA1X,QAAU,CAACyC,CAAD,CAAYC,CAAZ,CAAsBhE,CAAtB,CACV,CACI,OAAOgE,CAAP,EACA,KAAK,OAAL,CAOI,MANA,KAAArF,EAAA,CAAcqF,CAAd,CAMO,CANmBhE,CAMnB,CALPA,CAAAiE,QAKO,CALW,QAAQ,CAACY,CAAD,CAAW,CACjC,MAAO,SAAQ,EAAG,CACdA,CAAAiP,MAAA,EADc,CADe,CAAnB,CAIhB,IAJgB,CAKX,CAAA,CAAA,CARX,CAYA,MAAO,CAAA,CAbX,CAyBAnS,SAAA,EAAkB,CAAlBA,CAAkB,CAACC,CAAD,CAClB,CACI,MAAI,EAAAm7B,EAAA,CAAan7B,CAAb,CAAJ,CACW,CAAAm7B,EAAA,CAAan7B,CAAb,CAAA,CAAoB,CAApB,CADX,CAGO,IAJX;AAOAo7B,QAAO,GAAK,CAACn4B,CAAD,CACZ,CAKI,IAAIrF,EAAM,IAAV,CACSoC,CAAT,KAASA,CAAT,GAAkBiD,EAAAk4B,EAAlB,CACI,IAAK,IAAI9lC,EAAE,CAAX,CAAcA,CAAd,CAAkB4N,CAAAk4B,EAAA,CAAiBn7B,CAAjB,CAAAvI,OAAlB,CAAkDpC,CAAA,EAAlD,CAAuD,CACnD,IAAI0I,EAAYkF,CAAAk4B,EAAA,CAAiBn7B,CAAjB,CAAA,CAAwB3K,CAAxB,CAChB,IAAK0I,CAAL,CAAA,CACA,GAAI,CAACqF,CAAA,CAAArF,CAAA,CAAL,CAA0B,CACtBqF,CAAA,CAAArF,CAAA,CAAkB,QAAQ,CAACkF,CAAD,CAAW,CACjC,MAAO,SAAQ,EAAG,CACdo4B,EAAA,CAAkBp4B,CAAlB,CADc,CADe,CAAnB,CAIhBA,CAJgB,CAAlB,CAKA,OANsB,CAYb,KAAb,EAAIjD,CAAJ,CACIpC,CADJ,CACUG,CADV,CAESA,CAAAkI,GAFT,EAGIlI,CAAAkI,GAAA,CAAmB,CAAA,CAAnB,CAAyBhD,CAAzB,CAhBJ,CAFmD,CA2B3DA,CAAAI,EAAA,EAEAJ,EAAAR,EAAA,CAAiB,8EAAjB,CAOI7E,EAAJ,EAASA,CAAAqI,GAAA,CAAa,CAAA,CAAb,CAAmBhD,CAAnB,CA3Cb;AAwKJ6D,CAAA,CAlHIV,QAAW,EACX,CAQI,IAFA,IAAIk1B,EAAc18B,CAAA,CAA6B2H,QAA7B,CA91TXC,OA81TW,CAAuD,UAAvD,CAAlB,CAES+0B,EAAU,CAAnB,CAAsBA,CAAtB,CAAkCD,CAAA7jC,OAAlC,CAAsD8jC,CAAA,EAAtD,CAAmE,CAW/D,IATA,IAAIC,EAAYF,CAAA,CAAYC,CAAZ,CAAhB,CACIL,EAAgB17B,CAAA,CAA4Bg8B,CAA5B,CADpB,CAGIz9B,CAHJ,CAIIo9B,EAAU,EAJd,CAMItoB,CANJ,CAOI4oB,EAAY,CAPhB,CAOmB3C,EAAU,CAP7B,CASS4C,EAAM,CAAf,CAAkBA,CAAlB,CAA0BR,CAAA,QAAAzjC,OAA1B,CAA2DikC,CAAA,EAA3D,CAAoE,CAChE,IAAIC,EAAWT,CAAA,QAAA,CAAyBQ,CAAzB,CASf,IAAI,CAACA,CAAL,CAAY,CACR,GAAwB,KAAxB,EAAIC,CAAA,KAAJ,CAA+B,KAC/BF,EAAA,CAAYE,CAAA,MACZ7C,EAAA,CAAU6C,CAAA,IACV9oB,EAAA,CAAepO,KAAJ,CAAUq0B,CAAV,CAAkB,CAAlB,CAAsB2C,CAAtB,CACX,KAASrjB,CAAT,CAAcqjB,CAAd,CAAyBrjB,CAAzB,CAAgCvF,CAAApb,OAAhC,CAAiD2gB,CAAA,EAAjD,CACIvF,CAAA,CAASuF,CAAT,CAAA,CAAiB,CANb,CAUZ,GADAra,CACA,CADY6I,EAAA,CAA2B+0B,CAAA,MAA3B,CAA8CT,CAAA,GAA9C,CACZ,CAAe,CACX,IAAIl7B,EAAQ27B,CAAA,KACWl8B,KAAAA,EAAvB,GAAI07B,CAAA,CAAQn7B,CAAR,CAAJ,GACIm7B,CAAA,CAAQn7B,CAAR,CADJ,CACqB,EADrB,CAEAm7B,EAAA,CAAQn7B,CAAR,CAAAzE,KAAA,CAAoBwC,CAApB,CACIA,EAAA6U,GAAJ,EAAiDnT,IAAAA,EAAjD,GAA2Bk8B,CAAA,MAA3B,EACI59B,CAAA6U,GAAA,CAAoBC,CAApB,CAA8B8oB,CAAA,MAA9B,CAAiDA,CAAA,IAAjD,CAAkER,CAAA,IAAA,CAAe,CAAf,CAAlE,CANO,CAAf,IASK,CAviWbx/B,CAAA,CAwiW4B,wCAxiW5B,CAwiWkEggC,CAAA,MAxiWlE,CAwiWsF,OAxiWtF,CAyiWY,OAFC,CA7B2D,CAmCpE,GAAiBl8B,IAAAA,EAAjB,GAAIoT,CAAJ,CAA4B,CA7iWhClX,CAAA,CA8iWwB1H,iGA9iWxB,CA+iWQ;KAFwB,CAW5B,GADA8J,CACA,CADY6I,EAAA,CAA2B,UAA3B,CAAuCs0B,CAAA,GAAvC,CACZ,CACIC,CAAA,CAAQ,UAAR,CACA,CADsB,CAACp9B,CAAD,CACtB,CAAIA,CAAA6U,GAAJ,EACI7U,CAAA6U,GAAA,CAAoBC,CAApB,CAA8B4oB,CAA9B,CAAyC3C,CAAzC,CAAkDqC,CAAA,IAAA,CAAe,CAAf,CAAlD,CAIJl4B,EAAAA,CAAW,IAAIg4B,CAAJ,CAAgBC,CAAhB,CAA+BC,CAA/B,CAOf,IADIx0B,CACJ,CADYC,EAAA,CAA2B,OAA3B,CAAoCs0B,CAAA,GAApC,CACZ,CAMI,GALAC,CAAA,MAImBS,CAJA,CAACj1B,CAAD,CAIAi1B,CAAAj1B,CAAA5J,EAAA6+B,MACnB,CAAkB,CAr6VtBvmC,CAAAA,CAAAA,IAAAA,EAs6VkD,EAAA,CAAA6lC,CAAA,GAr6VlDW,EAAAA,CAAc,EAQdj8B,EAAJ,GAEQA,CAFR,CACuC,CAAnC,EAAKvK,CAAL,CAASuK,CAAApK,QAAA,CAAkB,GAAlB,CAAT,EACgBoK,CAAArK,OAAA,CAAiB,CAAjB,CAAoBF,CAApB,CAAwB,CAAxB,CADhB,CAGgB,EAJpB,CAMA,KAAKA,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgBwK,CAAApI,OAAhB,CAA6CpC,CAAA,EAA7C,CACQ0I,CACJ,CADgB+B,CAAA,CAAqBzK,CAArB,CAChB,CAAKuK,CAAL,EAAmB7B,CAAAlB,GAAArH,QAAA,CAAqBoK,CAArB,CAAnB,EACIi8B,CAAAtgC,KAAA,CAAiBwC,CAAjB,CAGR,EAAA,CAAO89B,CAk5VK,KAASC,CAAT,CAAsB,CAAtB,CAAyBA,CAAzB,CAAsCD,CAAApkC,OAAtC,CAA0DqkC,CAAA,EAA1D,CACI/9B,CACA,CADY89B,CAAA,CAAYC,CAAZ,CACZ,CAAI/9B,CAAJ,EAAiB4I,CAAjB,GACA5I,CAAAwE,GAEA,CAFmBoE,CAAApE,GAEnB,CADAxE,CAAA2E,MACA,CADkBiE,CAAAjE,MAClB,CAAA3E,CAAA0E,EAAA,CAAoBkE,CAAAlE,EAHpB,CAJU,CAetBoE,CAAA,CAAgC5D,CAAhC,CAA0Cu4B,CAA1C,CAKAH,GAAA,CAAkBp4B,CAAlB,CAjG+D,CARvE,CAiHJ,CAoBA,KAAI84B,GAAiB,CAoCrBC;QAASA,GAAO,CAACC,CAAD,CAAWj/B,CAAX,CAA2C9D,CAA3C,CAAmDiG,CAAnD,CAA2D+8B,CAA3D,CAAqEC,CAArE,CAA8E7lC,CAA9E,CAChB,CASI6lC,CAAA,CAAQ,UAAR,CAAqBF,CAArB,CAAgC,KAAhC,CACApgB,EAAA,CAAgBogB,CAAhB,CATkBG,QAAQ,CAACC,CAAD,CAAWC,CAAX,CAAiB7lC,CAAjB,CAA6B,CAC/CA,CAAJ,EACS6lC,CACL,GADWA,CACX,CADkB,iBAClB,CADsCL,CACtC,CADiD,IACjD,CADwDxlC,CACxD,CADqE,GACrE,EAAAH,CAAA,CAAKgmC,CAAL,CAAW,IAAX,CAFJ,EAKAC,EAAA,CAASD,CAAT,CAAeL,CAAf,CAAyBj/B,CAAzB,CAAyD9D,CAAzD,CAAiEiG,CAAjE,CAAyE+8B,CAAzE,CAAmFC,CAAnF,CAA4F7lC,CAA5F,CANmD,CASvD,CAVJ;AA+BAimC,QAASA,GAAQ,CAACD,CAAD,CAAOL,CAAP,CAAiBj/B,CAAjB,CAAiD9D,CAAjD,CAAyDiG,CAAzD,CAAiE+8B,CAAjE,CAA2EC,CAA3E,CAAoF7lC,CAApF,CACjB,CACmBkmC,QAAA,EAAQ,CAACF,CAAD,CAAOG,CAAP,CAAe,CAClC,GAAIA,CAAJ,CACInmC,CAAA,CAAKmmC,CAAL,CAAa,IAAb,CADJ,KAAA,CAIA,GAAIz/B,CAAJ,CAAe,CAp2WX6G,CAAA,CA02W6B7G,CA12W7B,CAAJ,EA02W4Ci/B,CA12W5C,GACIp4B,CAAA,CAy2W6B7G,CAz2W7B,CAAA,CAy2WwCi/B,CAz2WxC,CADJ,CA02WsDK,CA12WtD,CA62WI,EADIjmC,CACJ,CADW4lC,CACX,GAAgC,CAAhC,CAAY5lC,CAAAb,QAAA,CAAa,GAAb,CAAZ,EAA2E,GAA3E,EAAqCqB,MAAAa,SAAAglC,SAAA35B,MAAA,CAAgC,EAAhC,CAArC,GACI1M,CADJ,CACWQ,MAAAa,SAAAglC,SADX,CACsCrmC,CADtC,CAOK6C,EAAL,CAE+B,GAAxB,EAAIA,CAAA6J,MAAA,CAAc,EAAd,CAAJ,EACH7J,CACA,CADSA,CAAA6J,MAAA,CAAa,CAAb,CAAiB,EAAjB,CACT,CAAoB,CAApB,CAAI7J,CAAAzB,OAAJ,GAAuByB,CAAvB,EAAiC,GAAjC,CAFG,EAIHA,CAJG,CAIM,UAJN,CAImBA,CAJnB,CAI4B,IANnC,CACIA,CADJ,CACa,GAObA,EAAA,EAAU,OAAV,CAAoB7C,CAApB,CAA2B,IAUH,SAAxB,EAAI,MAAOM,UAAX,GAAkCN,CAAlC,CAAyC,IAAzC,CACA6C,EAAA,CAASA,CAAApD,QAAA,CAAe,KAAf,CAAsB,MAAtB,CACT,IAAIqJ,CAAJ,CAAY,CAMR,IAAI3G,EAAQ8jC,CAAA9jC,MAAA,CAAW,4CAAX,CACRA,EAAJ,GACI8jC,CACA,CADOA,CAAAxmC,QAAA,CAAa0C,CAAA,CAAM,CAAN,CAAb,CAAuBA,CAAA,CAAM,CAAN,CAAvB,CAAkCA,CAAA,CAAM,CAAN,CAAlC,CAA6C2G,CAA7C,CAAsD3G,CAAA,CAAM,CAAN,CAAtD,CACP,CAAA2G,CAAA,CAAS,IAFb,CAPQ,CAYZm9B,CAAA,CAAOA,CAAAxmC,QAAA,CAAa,iCAAb;AAAgD,MAAhD,CAAyDkH,CAAzD,CAAqE,IAArE,EAA6EmC,CAAA,CAAQ,aAAR,CAAqBA,CAArB,CAA8B,GAA9B,CAAoC,EAAjH,GAAwHjG,CAAA,CAAQ,aAAR,CAAqBA,CAArB,CAA8B,GAA9B,CAAoC,EAA5J,GAAmK7C,CAAA,CAAM,WAAN,CAAiBA,CAAjB,CAAwB,GAAxB,CAA8B,EAAjM,EAhDI,CAmDV6lC,CAAL,GAKII,CACA,CADOA,CAAAxmC,QAAA,CAAa,sDAAb,CAAqE,WAArE,CACP,CAAAwmC,CAAA,CAAOA,CAAAxmC,QAAA,CAAa,uDAAb,CAAsE,WAAtE,CANX,CAiCI6mC,EAAAA,CAAS,IACb,IAAsB,MAAtB,EAAIL,CAAA9f,OAAA,CAAY,CAAZ,CAAJ,CACI,GAAI,CASK0f,CASL,GARII,CAQJ,CARWA,CAAAxmC,QAAA,CAAa,4BAAb,CAA2C,EAA3C,CAQX,EAAIe,MAAAE,cAAJ,EAA4B,eAA5B,EAA+CF,OAA/C,EACI8lC,CAEA,CAFS,IAAI9lC,MAAAE,cAAJ,CAAyB,kBAAzB,CAET,CADA4lC,CAAAC,MACA,CADe,CAAA,CACf,CAAAD,CAAA,QAAA,CAAkBL,CAAlB,CAHJ,EAMIK,CANJ,CAMaE,CAAC,IAAIhmC,MAAAimC,UAALD,iBAAA,CAAyCP,CAAzC;AAA+C,UAA/C,CAxBb,CA0BF,MAAMviC,CAAN,CAAS,CACP4iC,CACA,CADS,IACT,CAAAL,CAAA,CAAOviC,CAAA6B,QAFA,CA3Bf,IAgCI0gC,EAAA,CAAO,oBAAP,EAA6C,GAAd,CAAAA,CAAA7kC,OAAA,CAAmB6kC,CAAA/mC,OAAA,CAAY,CAAZ,CAAe,GAAf,CAAnB,CAAyC,KAAzC,CAAiD+mC,CAAhF,CAEJhmC,EAAA,CAAKgmC,CAAL,CAAWK,CAAX,CA3HA,CADkC,CA8HlCL,CAAJ,CAEQJ,CAAJ,CACIa,EAAA,CAAWT,CAAX,CAAiBH,CAAjB,CAA0BK,CAA1B,CADJ,CAIAA,CAAA,CAASF,CAAT,CAAe,IAAf,CANJ,CASAhmC,CAAA,CAAK,SAAL,EAAkB2lC,CAAA,CAAU,aAAV,CAA0BA,CAA1B,CAAqC,EAAvD,EAA4D,IAA5D,CAxIJ;AAwJAc,QAASA,GAAU,CAACT,CAAD,CAAOH,CAAP,CAAgB7lC,CAAhB,CACnB,CACI,IAAI0mC,CAGJ,IAAKA,CAAL,CAFYC,kCAEI3jC,KAAA,CAAWgjC,CAAX,CAAhB,CAAmC,CAE/B,IAAIY,EAAWF,CAAA,CAAS,CAAT,CA2Dfb,EAAA,CAAQ,UAAR,CAAqBe,CAArB,CAAgC,KAAhC,CACArhB,EAAA,CAAgBqhB,CAAhB,CA1DkBC,QAAQ,CAACd,CAAD,CAAWe,CAAX,CAAoB3mC,CAApB,CAAgC,CACtD,GAAIA,CAAJ,EAAkB,CAAC2mC,CAAnB,CACI9mC,CAAA,CAAKgmC,CAAL,CAAW,mCAAX,CAAiDU,CAAA,CAAS,CAAT,CAAjD,CAA+D,IAA/D,CAAsEvmC,CAAtE,CAAmF,GAAnF,CADJ,KAAA,CAUA,GADI4mC,CACJ,CADgBL,CAAA,CAAS,CAAT,CAChB,CAEI,GADIM,CACJ,CADiBF,CAAA5kC,MAAA,CAAc,IAAIoI,MAAJ,CAAW,MAAX,CAAiBo8B,CAAA,CAAS,CAAT,CAAjB,CAA+B,cAA/B,CAAd,CACjB,CAAgB,CAOZ,IANA,IAAIO,EAAaD,CAAA,CAAW,CAAX,CAAjB,CAIIE,CAJJ,CAKIC,EAAS,2BACb,CAAQD,CAAR,CAAoBC,CAAAnkC,KAAA,CAAY+jC,CAAZ,CAApB,CAAA,CAKQE,CAAA,CAJ+D,CAAnE,CAAIA,CAAA5nC,YAAA,EAAAH,QAAA,CAAiCgoC,CAAA,CAAU,CAAV,CAAA7nC,YAAA,EAAjC,CAAJ,CAIiB4nC,CAAAznC,QAAA,CAAmB,MAAnB,CAAwB0nC,CAAA,CAAU,CAAV,CAAxB,CAAuC,MAAvC,CAJjB,CASiBD,CAAAznC,QAAA,CAAmB,IAAI8K,MAAJ,CAAW48B,CAAA,CAAU,CAAV,CAAX,CAA0B,iBAA1B,CAAnB,CAAiEA,CAAA,CAAU,CAAV,CAAjE,CAGjBF,EAAA,CAAW,CAAX,CAAJ,EAAqBC,CAArB,GACIH,CADJ,CACcA,CAAAtnC,QAAA,CAAgBwnC,CAAA,CAAW,CAAX,CAAhB,CAA+BC,CAA/B,CADd,CApBY,CAAhB,IAuBO,CACHjnC,CAAA,CAAKgmC,CAAL,CAAW,cAAX;AAAyBU,CAAA,CAAS,CAAT,CAAzB,CAAuC,UAAvC,CAAiDE,CAAjD,CACA,OAFG,CAcXE,CAAA,CAAUA,CAAAtnC,QAAA,CAAgB,qBAAhB,CAAuC,EAAvC,CAEVwmC,EAAA,CAAOA,CAAAxmC,QAAA,CAAaknC,CAAA,CAAS,CAAT,CAAb,CAA0BI,CAA1B,CAEPL,GAAA,CAAWT,CAAX,CAAiBH,CAAjB,CAA0B7lC,CAA1B,CArDA,CADsD,CA0D1D,CA9D+B,CAAnC,IAiEAA,EAAA,CAAKgmC,CAAL,CAAW,IAAX,CArEJ;AAuFAoB,QAASA,GAAY,CAAgC1gC,CAAhC,CAA2Ci/B,CAA3C,CAAqD0B,CAArD,CAAuEx+B,CAAvE,CACrB,CAyByBy+B,QAAA,EAAQ,CAAC3/B,CAAD,CAAW,CACpC,GAAiBwB,IAAAA,EAAjB,GAAIo+B,CAAJ,CAA4B,CAaxB,IAAIC,EAAaC,CAAbD,EAAyBl/B,CAAA,CAA6Bm/B,CAA7B,CAAuC,iBAAvC,CAC7BF,EAAA,CAAYC,CAAZ,EAAyBA,CAAA,CAAU,CAAV,CAAzB,EAA0CC,CAdlB,CAgBxBF,CAAJ,GAAcA,CAAA5pB,UAAd,CAAmC+pB,EAAA,CAAe//B,CAAf,CAAnC,CAjBoC,CAPrBggC,QAAA,EAAQ,CAACxB,CAAD,CAAS,CAEhCmB,CAAA,CAAe,SAAf,CAA2BnB,CAA3B,CACIz7B,EAAJ,GARK,EAAE+6B,EAQP,EAPgBmC,CAAA,CAAqB,CAAA,CAArB,CAOhB,CACAl9B,EAAA,CAAW,CAAA,CAJqB,CAlBxC,IACQ+8B,CADR,CACkBF,CADlB,CAC4B78B,EAAW,CAAA,CAE9Bi7B,EAAL,GACIA,CACA,CADW,aACX,CAAK0B,CAAL,GAAeA,CAAf,CAA0B,gBAA1B,CAFJ,CAKA5B,GAAA,EAvmXIl4B,EAAA,CAwmXiB7G,CAxmXjB,CAAA,CAAgC,EA4oXpC,IAAI,CAEA,GADA+gC,CACA,CADWx3B,QAAA43B,eAAA,CAAwBnhC,CAAxB,CACX,CAAc,CAKV,IAAIohC,CACJ,IAAwB,QAAxB,EAAI,MAAOznC,UAAX,GAAqCynC,CAArC,CAA2CznC,SAAA,IAA3C,EAA8D,CAC1D,IAAI0nC,EAAO93B,QAAA83B,KAAPA,EAAwB93B,QAAA7F,qBAAA,CAA8B,MAA9B,CAAA,CAAsC,CAAtC,CAA5B,CACIqmB,EAAQxgB,QAAAqgB,cAAA,CAAuB,OAAvB,CACZG,EAAAxwB,KAAA,CAAa,UAETwwB,EAAAuX,WAAJ,CAEIvX,CAAAuX,WAAAC,QAFJ,CAE+BH,CAF/B,CAIIrX,CAAAQ,YAAA,CAAkBhhB,QAAAi4B,eAAA,CAAwBJ,CAAxB,CAAlB,CAEJC;CAAA9W,YAAA,CAAiBR,CAAjB,CAX0D,CAczD4W,CAAL,GAcQA,CAdR,CAcmB,uCAdnB,CAkBIc,EAAAA,CAAaA,QAAQ,CAACnC,CAAD,CAAOoC,CAAP,CAAY,CAC5BA,CAAL,CA0GA1C,EAAA,CAAQ2B,CAAR,EAAoB,EAApB,CAAwB,IAAxB,CAAmD,IAAnD,CAAyD,IAAzD,CAA+D,CAAA,CAA/D,CAAsEC,CAAtE,CA1FmBe,QAAQ,CAACC,CAAD,CAAOC,CAAP,CAAY,CACnC,GAAKA,CAAL,CAAA,CAUwC,IAAA,EAAAlB,CAAA,EAAY,EAhsX5D95B,EAAA,CAgsXqC7G,CAhsXrC,CAAJ,EAAqCkzB,CAArC,GACIrsB,CAAA,CA+rXqC7G,CA/rXrC,CAAA,CAA8BkzB,CAA9B,CADJ,CAgsXoE0O,CAhsXpE,CA+sXYhB,EAAA,CAAe,aAAf,CAA+B3B,CAA/B,CAA0C,KAA1C,CAOIplC,OAAAE,cAAJ,EAA4B,eAA5B,EAA+CF,OAA/C,CAEI,CADIioC,CACJ,CADgBJ,CAAA,cAAA,CAAqBG,CAArB,CAChB,GACId,CAAAgB,UA7HpB,CA6HyCD,CA7HzC,CAAK,EAAE/C,EAAP,EACgBmC,CAAA,CAAqB,CAAA,CAArB,CA2HA,EAIID,CAAA,CAAa,8BAAb,CANR,CASS13B,QAAAy4B,eAAJ,EAA+Bz4B,QAAAy4B,eAAAC,eAA/B,EACGC,CAGJ,CAHoB,IAAIC,aAGxB,CAFAD,CAAA,iBAAA,CAAkCL,CAAlC,CAEA,CAAA,CADIO,CACJ,CADgBF,CAAA,oBAAA,CAAqCR,CAArC,CAA0Cn4B,QAA1C,CAChB,EASQw3B,CAAAl/B,WAAJ,EACIk/B,CAAAl/B,WAAAwgC,aAAA,CAAiCD,CAAjC;AAA4CrB,CAA5C,CAjJxB,CAAK,EAAEhC,EAAP,EACgBmC,CAAA,CAAqB,CAAA,CAArB,CA+II,EAkBID,CAAA,CAAa,2BAAb,CAA2CjhC,CAA3C,CA3BR,CA8BIihC,CAAA,CAAa,4BAAb,CAlCH,EA0CDA,CAAA,CAAa,8CAAb,CAnFJ,CAAA,IACIA,EAAA,CAAaW,CAAb,CAF+B,CA0FvC,CA1GA,CACIX,CAAA,CAAa3B,CAAb,CAF6B,CA8GX,OAA1B,EAAIL,CAAAzf,OAAA,CAAgB,CAAhB,CAAJ,CACIwf,EAAA,CAAQC,CAAR,CAAkBj/B,CAAlB,CA0BqEyC,IAAAA,EA1BrE,CAA0DN,CAA1D,CAAkE,CAAA,CAAlE,CAAwEy+B,CAAxE,CAAwFa,CAAxF,CADJ,CAGIlC,EAAA,CAASN,CAAT,CAAmB,IAAnB,CAAyBj/B,CAAzB,CAwBqEyC,IAAAA,EAxBrE,CAAiEN,CAAjE,CAAyE,CAAA,CAAzE,CAAgFy+B,CAAhF,CAAgGa,CAAhG,CAvJM,CAAd,IA0JIR,EAAA,CAAa,2BAAb,CAA2CjhC,CAA3C,CA5JJ,CA8JF,MAAMjD,CAAN,CAAS,CACPkkC,CAAA,CAAalkC,CAAA6B,QAAb,CADO,CAGX,MAAOoF,EA9MX,CAgWInK,MAAA,SAAA,CArIJyoC,QAAiB,CAACtiC,CAAD,CAAYi/B,CAAZ,CAAsB0B,CAAtB,CAAgCzkC,CAAhC,CAAwCiG,CAAxC,CACjB,CACgB++B,CAAA,CAAqB,CAAA,CAArB,CACZ,OAAOR,GAAA,CAA2C1gC,CAA3C,CAAsDi/B,CAAtD,CAAgE0B,CAAhE,CAAqFx+B,CAArF,CAFX,CAkJAtI;MAAA,eAAA,CAlDA0oC,QAAuB,CAACnhC,CAAD,CAAUohC,CAAV,CAAmBxiC,CAAnB,CAA8ByiC,CAA9B,CAA0Cp+B,CAA1C,CAAoD+C,CAApD,CACvB,CACI,GAAgB,QAAhB,EAAI/C,CAAJ,CAA0B,CAr1WlBL,CAAAA,CAAW,CAAA,CAs1WahE,EAr1W5B,EAAa,UACb,IAAI,CAo1WmCoH,CAp1WvC,CACI,OAAOlD,CAAA,CAAmBlE,CAAnB,CACP,CAAAgE,CAAA,CAAW,CAAA,CAFf,KAIK,IAAsB,QAAtB,EAAI,MAg1W8BoD,EAh1WlC,EAAkC,CAAClD,CAAA,CAAmBlE,CAAnB,CAAnC,CAAkE,CACnEgE,CAAA,CAAW,CAAA,CACXE,EAAAA,CAAAA,CA9DJ,KA8DuBlE,IAAAA,EAAAA,CAAAA,CAhEnBrJ,EA84WmCyQ,CA94W7B3M,OAgEauF,CA/DnBiE,EAAY,EA+DOjE,CA/DHmE,EAAU,EA+DPnE,CA/DW0iC,EAAS,EA+DpB1iC,CA/DwB2iC,EAAU,IA+DlC3iC,CA9Dd3H,EAAI,CAAb,CAAgBA,CAAhB,CAAoB1B,CAApB,CAAyB0B,CAAA,EAAzB,CAA8B,CAC1B,IAAIqsB,EA24W+Btd,CA34W1B,CAAQ/O,CAAR,CACT,IAAU,GAAV,EAAIqsB,CAAJ,EAAuB,GAAvB,EAAiBA,CAAjB,CACQie,CAAJ,EAAeje,CAAf,EAAqBie,CAArB,CACID,CADJ,EACche,CADd,EAIKie,CAAL,CAGIA,CAHJ,CAGc,IAHd,CACIA,CADJ,CACcje,CAId,CAAIge,CAAJ,GACIv+B,CAAA5F,KAAA,CAAamkC,CAAb,CACA,CAAAA,CAAA,CAAS,EAFb,CATA,CADJ,KAAA,CAgBA,GAAI,CAACC,CAAL,CAAc,CACV,GAAU,IAAV,EAAIje,CAAJ,EAAwB,IAAxB,EAAkBA,CAAlB,CACIA,CAAA,CAAK,GAET,IAAU,GAAV,EAAIA,CAAJ,EAAuB,IAAvB,EAAiBA,CAAjB,EAAqC,GAArC,EAA+BA,CAA/B,CAA0C,CAClCge,CAAJ,GACIv+B,CAAA5F,KAAA,CAAamkC,CAAb,CACA,CAAAA,CAAA,CAAS,EAFb,CAIU,IAAV,EAAIhe,CAAJ,EAAiBvgB,CAAA1J,OAAjB,GACIwJ,CAAA1F,KAAA,CAAe4F,CAAf,CACA,CAAAA,CAAA,CAAU,EAFd,CAIA,SATsC,CAJhC,CAgBdu+B,CAAA,EAAUhe,CAhCV,CAF0B,CAoC1Bge,CAAJ,EACIv+B,CAAA5F,KAAA,CAAamkC,CAAb,CAEAv+B,EAAA1J,OAAJ,EACIwJ,CAAA1F,KAAA,CAAe4F,CAAf,CAsBAD,EAAA,CAAmBlE,CAAnB,CAAA,CApBGiE,CAqBEQ,GAAA,CAA0BzE,CAA1B,CAAL,GACIgE,CADJ,CACe,CAAA,CADf,CAHmE,CAg1WvE,MAz0WOA,EAy0WP,EACQw+B,CACG,GADMphC,CAAAkrB,SACN,CADyB,CAAA,CACzB;AAAA,CAAA,CAFX,EAIO,CAAA,CALe,CAO1B,GAAImW,CAAJ,GACQ1hC,CADR,CACoB6D,EAAA,CAA6B69B,CAA7B,CAAyCziC,CAAzC,CAAqD,UAArD,CADpB,IAGY8E,CAHZ,CAGsB/D,CAAA,QAHtB,IAKgB2D,CALhB,CAK4BI,CAAA,CAAQT,CAAR,CAL5B,EAOgB,MAAIK,EAAAK,KAAA,CAAehE,CAAf,CAA0BqG,CAA1B,CAAJ,EACQo7B,CACG,GADMphC,CAAAkrB,SACN,CADyB,CAAA,CACzB,EAAA,CAAA,CAFX,EAIO,CAAA,CAKvBpmB,QAAA5O,IAAA,CAAY,iCAAZ,CAAgD0I,CAAhD,CAA4D,KAA5D,CAAoEyiC,CAApE,CAAiF,KAAjF,CAAyFp+B,CAAzF,CAAoG,KAApG,CAA4G+C,CAA5G,CAAqH,IAArH,CACA,OAAO,CAAA,CAzBX,CAmDAvN,OAAA,aAAA,CAAyBqnC,CACzBrnC,OAAA,UAAA,CAAyBmF;","sources":["versions/c1pjs/1.61.0/c1p-uncompiled.js"," [synthetic:util/objectcreate] "," [synthetic:es6/util/setprototypeof] "," [synthetic:es6/util/inherits] "," [synthetic:util/defineproperty] "," [synthetic:util/global] "," [synthetic:util/polyfill] "," [synthetic:es6/math/trunc] "," [synthetic:es6/number/parseint] "],"names":["$jscomp.objectCreate","$jscomp.setPrototypeOf","$jscomp.defineProperty","$jscomp.global","$jscomp.polyfill","toHex","n","cch","fPrefix","v","Math","abs","nGrouping","s","isNaN","pow","radix","ceil","log","g","d","String","fromCharCode","trunc","sPrefix","toHexByte","b","Str.toHex","toHexWord","w","getBaseName","sFileName","sBaseName","i","lastIndexOf","substr","indexOf","getExtension","sExtension","toLowerCase","escapeHTML","sHTML","replace","m","Str.HTMLEscapeMap","Usr.getTime","Date","now","getResource","sURL","done","type","fAsync","nErrorCode","resource","resources","request","window","XMLHttpRequest","ActiveXObject","fArrayBuffer","fXHR2","responseType","callback","readyState","response","responseText","err","status","length","location","protocol","onreadystatechange","sPost","p","hasOwnProperty","encodeURIComponent","open","setRequestHeader","send","overrideMimeType","isUserAgent","userAgent","navigator","match","isMobile","sDevice","sMobile","Web.getURLParm","Web.isUserAgent","fInvert","getURLParm","sParm","Web.parmsURL","sParms","aParms","search","pl","exec","decodeURIComponent","onCountRepeat","fnRepeat","fnComplete","fnTimeout","doCountRepeat","setTimeout","onClickRepeat","e","fn","doClickRepeat","msRepeat","ms","timer","fIgnoreMouseEvents","onmousedown","e.onmousedown","msDelay","ontouchstart","e.ontouchstart","onmouseup","onmouseout","e.onmouseout","clearTimeout","ontouchend","ontouchcancel","e.ontouchcancel","onPageEvent","sFunc","fnPrev","onInit","Web.aPageEventHandlers","push","doPageEvent","afn","Web.fPageEventsEnabled","Component.alertUser","message","enablePageEvents","fEnable","Web.fPageLoaded","Web.sendPageEvent","Web.fPageShowed","sendPageEvent","sEvent","Web.doPageEvent","Web.onPageEvent","onPageLoad","onPageShow","onPageUnload","constructor","Component","parms","bitsMessage","id","name","bindings","idMachine","flags","ready","busy","busyCancel","initDone","powered","unloading","error","fnReady","clearError","dbg","cpu","cmp","Component.components.push","component","alertUser","sMessage","alert","appendControl","control","sText","value","scrollTop","scrollHeight","bindComponentControls","element","aeControls","Component.getElementsByClass","parentNode","iControl","aeChildNodes","childNodes","iNode","nodeType","sClass","getAttribute","aClasses","split","iClass","Component.getComponentParms","undefined","setBinding","getComponentByID","idRelated","Component.components.length","Component.components","getComponentByType","sType","componentPrev","getComponentParms","eval","getElementsByClass","sObjClass","getElementsByClassName","j","ae","aeAll","getElementsByTagName","re","RegExp","test","className","processCommands","fSuccess","aCommands","Component.commands","aTokens","splice","sCommand","fnCallReady","Component.asyncCommands.indexOf","processNextCommand","Component.processCommands","fnCommand","Component.globalCommands","Component.getComponentByType","Component.componentCommands","exports","call","Component.prototype","?.prototype","toString","sHTMLType","sBinding","onclick","clearControl","notice","this.notice","println","print","printControl","Component.appendControl","printlnControl","Component.PRINT.PROGRESS","slice","fPrintOnly","computer","console","setError","isReady","setReady","isBusy","fCancel","setBusy","fBusy","messageEnabled","bitsEnabled","PROGRESS","Component.machines","Component.asyncCommands","scriptAlert","scriptSleep","fnCallback","sDelay","scriptSelect","sValue","aBindings","options","textContent","selectedIndex","Array","prototype","Array.prototype.indexOf","obj","start","isArray","Array.isArray","arg","Object","Function","bind","Function.prototype.bind","fnBound","fToBind","apply","fnNOP","args","concat","arguments","TypeError","C1PPanel","parmsPanel","$jscomp.inherits","kbd","setPower","fOn","C1PPanel.init","init","fReady","aePanels","document","APPCLASS","iPanel","ePanel","panel","Component.getComponentByID","Component.bindComponentControls","Web.onInit","C1PCPU","parmsCPU","clearRegs","running","fAutoStart","SPEED_SLOW","SPEED_FAST","SPEED_MAX","speed","nVideoUpdatesPerSecond","nStatusUpdatesPerSecond","mhzFast","aSpeeds","aSpeedDescs","aReadNotify","aWriteNotify","addrReadLower","addrReadUpper","addrWriteLower","addrWriteUpper","OP_JSR","OP_SIM","SIMOP_MSG","aOpcodeFuncs","opBRK","opORAindx","opSim","opUndefined","opORAzp","opASLzp","opPHP","opORAimm","opASLacc","opORAabs","opASLabs","opBPL","opORAindy","opORAzpx","opASLzpx","opCLC","opORAabsy","opORAabsx","opASLabsx","opJSRabs","opANDindx","opBITzp","opANDzp","opROLzp","opPLP","opANDimm","opROLacc","opBITabs","opANDabs","opROLabs","opBMI","opANDindy","opANDzpx","opROLzpx","opSEC","opANDabsy","opANDabsx","opROLabsx","opRTI","opEORindx","opEORzp","opLSRzp","opPHA","opEORimm","opLSRacc","opJMPimm16","opEORabs","opLSRabs","opBVC","opEORindy","opEORzpx","opLSRzpx","opCLI","opEORabsy","opEORabsx","opLSRabsx","opRTS","opADCindx","opADCzp","opRORzp","opPLA","opADCimm","opRORacc","opJMPabs16","opADCabs","opRORabs","opBVS","opADCindy","opADCzpx","opRORzpx","opSEI","opADCabsy","opADCabsx","opRORabsx","opSTAindx","opSTYzp","opSTAzp","opSTXzp","opDEY","opTXA","opSTYabs","opSTAabs","opSTXabs","opBCC","opSTAindy","opSTYzpx","opSTAzpx","opSTXzpy","opTYA","opSTAabsy","opTXS","opSTAabsx","opLDYimm","opLDAindx","opLDXimm","opLDYzp","opLDAzp","opLDXzp","opTAY","opLDAimm","opTAX","opLDYabs","opLDAabs","opLDXabs","opBCS","opLDAindy","opLDYzpx","opLDAzpx","opLDXzpy","opCLV","opLDAabsy","opTSX","opLDYabsx","opLDAabsx","opLDXabsy","opCPYimm","opCMPindx","opCPYzp","opCMPzp","opDECzp","opINY","opCMPimm","opDEX","opCPYabs","opCMPabs","opDECabs","opBNE","opCMPindy","opCMPzpx","opDECzpx","opCLD","opCMPabsy","opCMPabsx","opDECabsx","opCPXimm","opSBCindx","opCPXzp","opSBCzp","opINCzp","opINX","opSBCimm","opNOP","opCPXabs","opSBCabs","opINCabs","opBEQ","opSBCindy","opSBCzpx","opINCzpx","opSED","opSBCabsy","opSBCabsx","opINCabsx","aOpcodeCycles","C1PCPU.prototype","reset","fPowerOn","halt","regPC","getWord","abMem","VECTOR_RESET","run","fBound","setSpeed","setBuffer","abMemory","end","offMem","cbMem","offLimit","video","displayVideo","updateScreen","setFocus","update","addReadNotify","findNotify","checkReadNotify","addrRead","addrFrom","addWriteNotify","checkWriteNotify","addrWrite","aNotify","fOnClick","innerHTML","nRunCycles","msRunStart","calcCycles","displayReg","sReg","vReg","len","toUpperCase","displayStatus","regA","regX","regY","regP","getRegP","BIT_PC","BIT_PZ","BIT_PI","BIT_PD","BIT_PB","BIT_PV","BIT_PN","regS","mhz","toFixed","fRecalc","nMostUpdatesPerSecond","nYieldsPerSecond","vMultiplier","msPerYield","round","nCyclesPerBurst","floor","nCyclesPerSecond","nCyclesPerYield","nCyclesPerVideoUpdate","nCyclesPerStatusUpdate","nCyclesNextYield","nCyclesNextVideoUpdate","nCyclesNextStatusUpdate","nRecalcCycles","calcRemainingTime","msCurrent","msYield","nCyclesThisRun","msRemainsThisRun","msStartThisRun","msElapsed","calcSpeed","calcStartTime","step","nCycles","nBurstCycles","nStepCycles","stack","stop","nMinCycles","fCompleted","regEA","regEAWrite","aExecBreak","aReadBreak","aWriteBreak","bOpCode","fDebugCheck","fBreak","checkBreakpoint","addr","cIns","aaOpcodeFreqs","aStepHistory","iStepHistory","Str.toHexWord","yieldCPU","getCycles","getByte","regRC","regRZ","regRV","regRU","regRN","setBCD","opADCindxBCD","opADCzpBCD","opADCimmBCD","opADCabsBCD","opADCindyBCD","opADCzpxBCD","opADCabsyBCD","opADCabsxBCD","opSBCindxBCD","opSBCzpBCD","opSBCimmBCD","opSBCabsBCD","opSBCindyBCD","opSBCzpxBCD","opSBCabsyBCD","opSBCabsxBCD","clearBCD","addBCD","reg","mem","carry","r","subBCD","notcarry","bSimOp","SIMOP_HLT","Str.toHexByte","aeCPUs","iCPU","eCPU","C1PROM","parmsROM","abImage","cbROM","sImage","sFileURL","sFileExt","Str.getExtension","FORMAT","host","SITEHOST","rom","Web.getResource","sResponse","convertImage","offROM","setByte","copyImage","messageIO","MESSAGE_PORT","offset","sImageName","sImageData","charAt","ab","asData","sData","parseInt","cbImage","aeROM","iROM","eROM","C1PRAM","parmsRAM","aeRAM","iRAM","eRAM","ram","C1PKeyboard","parmsKbd","nDefaultModel","KEYCODE_DELETE","KEYCODE_LF","KEYCODE_CR","KEYCODE_ESC","CHARCODE_DELETE","CHARCODE_LF","CHARCODE_CR","CHARCODE_ESC","CHARCODE_CTRL","CHARCODE_BREAK","CHARCODE_CTRLC","CHARCODE_CTRLO","BIT_SHIFTLOCK","aButtonCodeMap","aCharCodeMap","CHARCODE_LSHIFT","CHARCODE_RSHIFT","CHARCODE_SHIFTLOCK","C1PKeyboard.prototype","setModel","bitsShift","bKbdRows","abKbdCols","aKbdStates","aKeyTimers","prevKeyDown","prevCharDown","bWriteLast","abKbdColsLast","nCyclesSinceLastEvent","nWritesSinceLastEvent","sInjectBuffer","onkeydown","event","keyEvent","onkeypress","fPass","charCode","which","keyCode","BIT_COMMAND","keyPressSimulate","MESSAGE_KBD","onkeyup","sButton","offKbd","cbKbd","offKbdLimit","nModel","bInvert","fMobile","iOS","calcReleaseDelay","fRepeat","msReleaseRepeat","msReleaseDelay","autoClear","notCharCode","keyEventSimulate","SIMCODE_AUTOCLEAR","injectKeys","sKeyCodes","injectKeysFromBuffer","msInjectDelay","ch","charCodeAt","fDown","fAutoClear","BIT_LSHIFT","PSEUDO_CHARCODE","BIT_RSHIFT","BIT_CTRL","KEYCODE_COMMAND","KEYCODE_TAB","SIMCODE_KEYEVENT","fSimulated","SIMCODE_KEYPRESS","SIMCODE_KEYRELEASE","SIMCODE_KEYTIMEOUT","simCode","bShift","bCode","iRow","iCol","BITS_SIMULATE","fPropagate","updateMemory","C1PKeyboard_prototype$setByte","nCycleDelta","nCyclesThreshold","shift","aeKbd","iKbd","eKbd","C1PVideo","parmsVideo","canvas","context","imgChars","nDefaultCols","nDefaultRows","cxScreen","cyScreen","cxChar","cyChar","setDimensions","canvasScreen","contextScreen","asWebPrefixes","fSmoothing","sSmoothing","C1PVideo.prototype","offVideo","offVideoLimit","random","initScreen","cbVideo","addrVideoPort","nCols","nRows","iRowTop","nRowsVisible","cbScreen","setDrawingDimensions","cxCharDst","cyCharDst","focus","addrGuard","tripGuard","width","height","MESSAGE_VIDEO","nCyclesHigh","C1PVideo_prototype$setByte","aBounds","addrLower","addrUpper","abScreen","row","writeByte","xChar","drawImage","aeVideo","iVideo","eVideo","eCanvas","createElement","getContext","setAttribute","style","backgroundColor","clientWidth","onresize","eParent","eChild","cx","cy","appendChild","imgCharSet","Image","eContext","onload","src","C1PSerialPort","parmsSerial","fDemo","C1PSerialPort.prototype","fHard","autoLoad","C1PSerialPort.AUTOLOAD_6502","bInput","iInput","sInput","nMachine","getMachineNum","aDigits","fConvertLF","C1PSerialPort.AUTOLOAD_NONE","serial","C1PSerialPort.AUTOLOAD_BASIC","control.onclick","loadFile","Web.isMobile","onchange","controlInput.onchange","fieldset","children","submit","disabled","files","onsubmit","controlInput.onsubmit","file","currentTarget","reader","FileReader","reader.onload","result","readAsText","removeChild","offPort","cbPort","offPortLimit","sFileData","nResponse","sSuffix","data","advanceInput","C1PSerialPort_prototype$setByte","MESSAGE_SERIAL","C1PSerialPort.STATUS_DATA","C1PSerialPort.STATUS_NONE","aeSerial","iSerial","eSerial","C1PDiskController","parmsDC","C1PDiskController.prototype","resetRegs","iDriveSelect","aDrives","resetDrive","iDrive","iType","DRIVETYPE_5INCH","nTracks","MAXTRACKS_5INCH","fProtected","nIndexPulse","iTrackSelect","iTrackOffset","aTracks","regDDA","bits","PDA_SD2","read","controller","regCRA","CR_PD_SEL","writePort","PORT_DDA","regPDA","bPDA","setSelectedDrive","regPDB","drive","stopDriveData","advanceDriveData","PORT_PDA","PORT_CRA","regDDB","regCRB","PORT_DDB","bPDB","PDB_ST","PDB_STI","MESSAGE_DISK","PDA_IHD","PORT_PDB","PORT_CRB","regCTRL","CTRL_CDIV","regSTAT","bSTAT","STAT_RDRF","PORT_STAT","regDATA","PORT_DATA","regUnknown","sFilePath","Str.getBaseName","loadDisk","addrController","sDiskName","sDiskData","aHeads","iTrack","iTrackNum","track","sectors","Error","trackData","pushSig","pushBCD","pushBin","iSector","sector","sectorData","a","o","k","cb","getReg","port","fWrite","PORT_CTRL","sName","C1PDiskController_prototype$setByte","aBitIDs","bTest","bChanged","PDB_SD1","aeDC","iDC","eDC","C1PDebugger","parmsDbg","nextAddr","prevCmd","fAssemble","addrAssembleNext","clearBreakpoints","MESSAGE_NONE","aMessageCategories","aOpCodes","aOpSimCodes","setOpModes","aaOperations","OP_BRK","OP_ORA","MODE_INDX","MODE_ZP","OP_ASL","OP_PHP","MODE_IMM","MODE_ACC","MODE_ABS","OP_BPL","MODE_DISP","MODE_INDY","MODE_ZPX","OP_CLC","MODE_ABSY","MODE_ABSX","MODE_IMM16","OP_AND","OP_BIT","OP_ROL","OP_PLP","OP_BMI","OP_SEC","OP_RTI","OP_EOR","OP_LSR","OP_PHA","OP_JMP","OP_BVC","OP_CLI","OP_RTS","OP_ADC","OP_ROR","OP_PLA","MODE_ABS16","OP_BVS","OP_SEI","OP_STA","OP_STY","OP_STX","OP_DEY","OP_TXA","OP_BCC","MODE_ZPY","OP_TYA","OP_TXS","OP_LDY","OP_LDA","OP_LDX","OP_TAY","OP_TAX","OP_BCS","OP_CLV","OP_TSX","OP_CPY","OP_CMP","OP_DEC","OP_INY","OP_DEX","OP_BNE","OP_CLD","OP_CPX","OP_SBC","OP_INC","OP_INX","OP_NOP","OP_BEQ","OP_SED","C1PDebugger.prototype","eDebug","C1PDebugger.input","Web.onClickRepeat","fClassic","sRegEx","aOpModes","iMode","sMode","regexOpModes","aImm16Codes","isCPUOK","fStep","fStepOver","doUnassemble","doRegisters","msStart","msTotal","clearTempBreakpoint","addSignedByte","addExecBreakpoint","findBreakpoint","findExecBreakpoint","fRemove","aBreak","fMatch","setTempBreakpoint","addrTempBP","aBreakpoints","getInstruction","nIns","sLine","aOpDesc","abOperand","OP_DB","sOperand","bOpMode","pop","nextIns","getUserAddr","sAddr","nBase","doFreqs","cData","aaSortedOpcodeFreqs","sort","q","bOpcode","cFreq","sAddrEnd","addrEnd","sIns","asArgs","fIns","getRegs","doTrace","sCount","c","Web.onCountRepeat","input","sCmd","aOpBytes","sCode","iCode","aModeMatch","cModes","asHex","nHex","cBreaks","aAddrs","cLines","sLen","line","sChars","sBytes","addrLine","sOption","sCategory","iHistory","aHistory","nextHistory","nInsHistory","aeDbg","iDbg","eDbg","C1PComputer","parmsComputer","modules","power","C1PComputer.power","aeComputers","iComputer","eComputer","addrStart","iAddr","addrInfo","controlPrint","aComponents","iComponent","cAsyncMachines","loadXML","sXMLFile","fResolve","display","doneLoadXML","sURLName","sXML","parseXML","buildXML","sError","pathname","xmlDoc","async","parseFromString","DOMParser","resolveXML","matchRef","reRef","sRefFile","doneReadXML","sXMLRef","sRefAttrs","aXMLRefTag","sXMLNewTag","matchAttr","reAttr","embedMachine","sXSLFile","displayMessage","eWarning","aeWarning","eMachine","Str.escapeHTML","displayError","Web.enablePageEvents","getElementById","css","head","styleSheet","cssText","createTextNode","processXML","xml","transformXML","sXSL","xsl","sFragment","outerHTML","implementation","createDocument","xsltProcessor","XSLTProcessor","eFragment","replaceChild","embedC1P","commandMachine","fSingle","sComponent","sToken","chQuote"],"sourcesContent":["\"use strict\";\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/defines.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @define {string}\n */\nvar APPVERSION = \"\"; // this @define is overridden by the Closure Compiler with the version in machines.json\n\nvar XMLVERSION = null; // this is set in non-COMPILED builds by embedMachine() if a version number was found in the machine XML\n\nvar COPYRIGHT = \"Copyright © 2012-2018 Jeff Parsons <Jeff@pcjs.org>\";\n\nvar LICENSE = \"License: GPL version 3 or later <http://gnu.org/licenses/gpl.html>\";\n\nvar CSSCLASS = \"pcjs\";\n\n/**\n * @define {string}\n */\nvar SITEHOST = \"localhost:8088\";// this @define is overridden by the Closure Compiler with \"www.pcjs.org\"\n\n/**\n * @define {boolean}\n */\nvar COMPILED = false; // this @define is overridden by the Closure Compiler (to true)\n\n/**\n * @define {boolean}\n */\nvar DEBUG = true; // this @define is overridden by the Closure Compiler (to false) to remove DEBUG-only code\n\n/**\n * @define {boolean}\n */\nvar MAXDEBUG = false; // this @define is overridden by the Closure Compiler (to false) to remove MAXDEBUG-only code\n\n/**\n * @define {boolean}\n */\nvar PRIVATE = false; // this @define is overridden by the Closure Compiler (to false) to enable PRIVATE code\n\n/*\n * RS-232 DB-25 Pin Definitions, mapped to bits 1-25 in a 32-bit status value.\n *\n * SerialPorts in PCjs machines are considered DTE (Data Terminal Equipment), which means they should be \"virtually\"\n * connected to each other via a null-modem cable, which assumes the following cross-wiring:\n *\n * G 1 <-> 1 G (Ground)\n * TD 2 <-> 3 RD (Received Data)\n * RD 3 <-> 2 TD (Transmitted Data)\n * RTS 4 <-> 5 CTS (Clear To Send)\n * CTS 5 <-> 4 RTS (Request To Send)\n * DSR 6+8 <-> 20 DTR (Data Terminal Ready)\n * SG 7 <-> 7 SG (Signal Ground)\n * DTR 20 <-> 6+8 DSR (Data Set Ready + Carrier Detect)\n * RI 22 <-> 22 RI (Ring Indicator)\n *\n * TODO: Move these definitions to a more appropriate shared file at some point.\n */\nvar RS232 = {\n RTS: {\n PIN: 4,\n MASK: 0x00000010\n },\n CTS: {\n PIN: 5,\n MASK: 0x00000020\n },\n DSR: {\n PIN: 6,\n MASK: 0x00000040\n },\n CD: {\n PIN: 8,\n MASK: 0x00000100\n },\n DTR: {\n PIN: 20,\n MASK: 0x00100000\n },\n RI: {\n PIN: 22,\n MASK: 0x00400000\n }\n};\n\n/*\n * NODE should be true if we're running under NodeJS (eg, command-line), false if not (eg, web browser)\n */\nvar NODE = false;\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/dumpapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Our \"DiskDump API\", such as it was, used to look like:\n *\n * http://jsmachines.net/bin/convdisk.php?disk=/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json&format=img\n *\n * To make it (a bit) more \"REST-like\", the above request now looks like:\n *\n * http://www.pcjs.org/api/v1/dump?disk=/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json&format=img\n *\n * Similarly, our \"FileDump API\" used to look like:\n *\n * http://jsmachines.net/bin/convrom.php?rom=/devices/pc/rom/5150/1981-04-24/PCBIOS-REV1.rom&format=json\n *\n * and that request now looks like:\n *\n * http://www.pcjs.org/api/v1/dump?file=/devices/pc/rom/5150/1981-04-24/PCBIOS-REV1.rom&format=json\n *\n * I don't think it makes sense to avoid \"query\" parameters, because blending the path of a disk image with the\n * the rest of the URL would be (a) confusing, and (b) more work to parse.\n */\nvar DumpAPI = {\n ENDPOINT: \"/api/v1/dump\",\n QUERY: {\n DIR: \"dir\", // value is path of a directory (DiskDump only)\n DISK: \"disk\", // value is path of a disk image (DiskDump only)\n FILE: \"file\", // value is path of a ROM image file (FileDump only)\n IMG: \"img\", // alias for DISK\n PATH: \"path\", // value is path of a one or more files (DiskDump only)\n FORMAT: \"format\", // value is one of FORMAT values below\n COMMENTS: \"comments\", // value is either \"true\" or \"false\"\n DECIMAL: \"decimal\", // value is either \"true\" to force all numbers to decimal, \"false\" or undefined otherwise\n MBHD: \"mbhd\", // value is hard drive size in Mb (formerly \"mbsize\") (DiskDump only) (DEPRECATED)\n SIZE: \"size\" // value is target disk size in Kb (supersedes \"mbhd\") (DiskDump only)\n },\n FORMAT: {\n JSON: \"json\", // default\n JSON_GZ: \"gz\", // gzip is currently used ONLY for compressed JSON\n DATA: \"data\", // same as \"json\", but built without JSON.stringify() (DiskDump only)\n HEX: \"hex\", // deprecated\n OCTAL: \"octal\", // displays data as octal words\n BYTES: \"bytes\", // displays data as hex bytes; normally used only when comments are enabled\n WORDS: \"words\", // displays data as hex words; normally used only when comments are enabled\n LONGS: \"longs\", // displays data as dwords\n IMG: \"img\", // returns the raw disk data (ie, using a Buffer object) (DiskDump only)\n ROM: \"rom\" // returns the raw file data (ie, using a Buffer object) (FileDump only)\n }\n};\n\n/*\n * Because we use an overloaded API endpoint (ie, one that's shared with the FileDump module), we must\n * also provide a list of commands which, when combined with the endpoint, define a unique request.\n */\nDumpAPI.asDiskCommands = [DumpAPI.QUERY.DIR, DumpAPI.QUERY.DISK, DumpAPI.QUERY.PATH];\nDumpAPI.asFileCommands = [DumpAPI.QUERY.FILE];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/reportapi.js (C) Jeff Parsons 2012-2018\n */\n\nvar ReportAPI = {\n ENDPOINT: \"/api/v1/report\",\n QUERY: {\n APP: \"app\",\n VER: \"ver\",\n URL: \"url\",\n USER: \"user\",\n TYPE: \"type\",\n DATA: \"data\"\n },\n TYPE: {\n BUG: \"bug\"\n },\n RES: {\n OK: \"Thank you\"\n }\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/strlib.js (C) Jeff Parsons 2012-2018\n */\n\nclass Str {\n /**\n * isValidInt(s, base)\n *\n * The built-in parseInt() function has the annoying feature of returning a partial value (ie,\n * up to the point where it encounters an invalid character); eg, parseInt(\"foo\", 16) returns 0xf.\n *\n * So it's best to use our own Str.parseInt() function, which will in turn use this function to\n * validate the entire string.\n *\n * @param {string} s is the string representation of some number\n * @param {number} [base] is the radix to use (default is 10); only 2, 8, 10 and 16 are supported\n * @return {boolean} true if valid, false if invalid (or the specified base isn't supported)\n */\n static isValidInt(s, base)\n {\n if (!base || base == 10) return s.match(/^-?[0-9]+$/) !== null;\n if (base == 16) return s.match(/^-?[0-9a-f]+$/i) !== null;\n if (base == 8) return s.match(/^-?[0-7]+$/) !== null;\n if (base == 2) return s.match(/^-?[01]+$/) !== null;\n return false;\n }\n\n /**\n * parseInt(s, base)\n *\n * This is a wrapper around the built-in parseInt() function. Our wrapper recognizes certain prefixes\n * ('$' or \"0x\" for hex, '#' or \"0o\" for octal) and suffixes ('.' for decimal, 'h' for hex, 'y' for\n * binary), and then calls isValidInt() to ensure we don't convert strings that contain partial values;\n * see isValidInt() for details.\n *\n * The use of multiple prefix/suffix combinations is undefined (although for the record, we process\n * prefixes first). We do NOT support the \"0b\" prefix to indicate binary UNLESS one or more commas are\n * also present (because \"0b\" is also a valid hex sequence), and we do NOT support a single leading zero\n * to indicate octal (because such a number could also be decimal or hex). Any number of commas are\n * allowed; we remove them all before calling the built-in parseInt().\n *\n * More recently, we've added support for \"^D\", \"^O\", and \"^B\" prefixes to accommodate the base overrides\n * that the PDP-10's MACRO-10 assembly language supports (decimal, octal, and binary, respectively).\n * If this support turns out to adversely affect other debuggers, then it will have to be \"conditionalized\".\n * Similarly, we've added support for \"K\", \"M\", and \"G\" MACRO-10-style suffixes that add 3, 6, or 9 zeros\n * to the value to be parsed, respectively.\n *\n * @param {string} s is the string representation of some number\n * @param {number} [base] is the radix to use (default is 10); can be overridden by prefixes/suffixes\n * @return {number|undefined} corresponding value, or undefined if invalid\n */\n static parseInt(s, base)\n {\n var value;\n\n if (s) {\n if (!base) base = 10;\n\n var ch, chPrefix, chSuffix;\n var fCommas = (s.indexOf(',') > 0);\n if (fCommas) s = s.replace(/,/g, '');\n\n ch = chPrefix = s.charAt(0);\n if (chPrefix == '#') {\n base = 8;\n chPrefix = '';\n }\n else if (chPrefix == '$') {\n base = 16;\n chPrefix = '';\n }\n if (ch != chPrefix) {\n s = s.substr(1);\n }\n else {\n ch = chPrefix = s.substr(0, 2);\n if (chPrefix == '0b' && fCommas || chPrefix == '^B') {\n base = 2;\n chPrefix = '';\n }\n else if (chPrefix == '0o' || chPrefix == '^O') {\n base = 8;\n chPrefix = '';\n }\n else if (chPrefix == '^D') {\n base = 10;\n chPrefix = '';\n }\n else if (chPrefix == '0x') {\n base = 16;\n chPrefix = '';\n }\n if (ch != chPrefix) s = s.substr(2);\n }\n ch = chSuffix = s.slice(-1);\n if (chSuffix == 'Y' || chSuffix == 'y') {\n base = 2;\n chSuffix = '';\n }\n else if (chSuffix == '.') {\n base = 10;\n chSuffix = '';\n }\n else if (chSuffix == 'H' || chSuffix == 'h') {\n base = 16;\n chSuffix = '';\n }\n else if (chSuffix == 'K') {\n chSuffix = '000';\n }\n else if (chSuffix == 'M') {\n chSuffix = '000000';\n }\n else if (chSuffix == 'G') {\n chSuffix = '000000000';\n }\n if (ch != chSuffix) s = s.slice(0, -1) + chSuffix;\n /*\n * This adds support for the MACRO-10 binary shifting (Bn) suffix, which must be stripped from the\n * number before parsing, and then applied to the value after parsing. If n is omitted, 35 is assumed,\n * which is a net shift of zero. If n < 35, then a left shift of (35 - n) is required; if n > 35, then\n * a right shift of -(35 - n) is required.\n */\n var v, shift = 0;\n if (base <= 10) {\n var match = s.match(/(-?[0-9]+)B([0-9]*)/);\n if (match) {\n s = match[1];\n shift = 35 - ((match[2] || 35) & 0xff);\n }\n }\n if (Str.isValidInt(s, base) && !isNaN(v = parseInt(s, base))) {\n /*\n * With the need to support larger (eg, 36-bit) integers, truncating to 32 bits is no longer helpful.\n *\n * value = v|0;\n */\n if (shift) {\n /*\n * Since binary shifting is a logical operation, and since shifting by division only works properly\n * with positive numbers, we must convert a negative value to a positive value, by computing the two's\n * complement.\n */\n if (v < 0) v += Math.pow(2, 36);\n if (shift > 0) {\n v *= Math.pow(2, shift);\n } else {\n v = Math.trunc(v / Math.pow(2, -shift));\n }\n }\n value = v;\n }\n }\n return value;\n }\n\n /**\n * toBase(n, radix, cch, sPrefix, nGrouping)\n *\n * Displays the given number as an unsigned integer using the specified radix and number of digits.\n *\n * @param {number|*} n\n * @param {number} radix (ie, the base)\n * @param {number} cch (the desired number of digits)\n * @param {string} [sPrefix] (default is none)\n * @param {number} [nGrouping]\n * @return {string}\n */\n static toBase(n, radix, cch, sPrefix = \"\", nGrouping = 0)\n {\n /*\n * We can't rely entirely on isNaN(), because isNaN(null) returns false, and we can't rely\n * entirely on typeof either, because typeof Nan returns \"number\". Sigh.\n *\n * Alternatively, we could mask and shift n regardless of whether it's null/undefined/NaN,\n * since JavaScript coerces such operands to zero, but I think there's \"value\" in seeing those\n * values displayed differently.\n */\n var s = \"\";\n if (isNaN(n) || typeof n != \"number\") {\n n = null;\n } else {\n /*\n * Callers that produced an input by dividing by a power of two rather than shifting (in order\n * to access more than 32 bits) may produce a fractional result, which ordinarily we would simply\n * ignore, but if the integer portion is zero and the sign is negative, we should probably treat\n * this value as a sign-extension.\n */\n if (n < 0 && n > -1) n = -1;\n /*\n * Negative values should be two's complemented according to the number of digits; for example,\n * 12 octal digits implies an upper limit 8^12.\n */\n if (n < 0) {\n n += Math.pow(radix, cch);\n }\n if (n >= Math.pow(radix, cch)) {\n cch = Math.ceil(Math.log(n) / Math.log(radix));\n }\n }\n var g = nGrouping || -1;\n while (cch-- > 0) {\n if (!g) {\n s = ',' + s;\n g = nGrouping;\n }\n if (n == null) {\n s = '?' + s;\n } else {\n var d = n % radix;\n d += (d >= 0 && d <= 9? 0x30 : 0x41 - 10);\n s = String.fromCharCode(d) + s;\n n = Math.trunc(n / radix);\n }\n g--;\n }\n return sPrefix + s;\n }\n\n /**\n * toBin(n, cch, nGrouping)\n *\n * Converts an integer to binary, with the specified number of digits (up to a maximum of 36).\n *\n * @param {number|*} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of binary digits (0 or undefined for default of either 8, 18, or 36)\n * @param {number} [nGrouping]\n * @return {string} the binary representation of n\n */\n static toBin(n, cch, nGrouping)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.LN2) || 1;\n var v = Math.abs(n);\n if (v <= 0b11111111) {\n cch = 8;\n } else if (v <= 0b111111111111111111) {\n cch = 18;\n } else {\n cch = 36;\n }\n } else if (cch > 36) cch = 36;\n return Str.toBase(n, 2, cch, \"\", nGrouping);\n }\n\n /**\n * toBinBytes(n, cb, fPrefix)\n *\n * Converts an integer to binary, with the specified number of bytes (up to the default of 4).\n *\n * @param {number|null|undefined} n (interpreted as a 32-bit value)\n * @param {number} [cb] is the desired number of binary bytes (4 is both the default and the maximum)\n * @param {boolean} [fPrefix]\n * @return {string} the binary representation of n\n */\n static toBinBytes(n, cb, fPrefix)\n {\n var s = \"\";\n if (!cb || cb > 4) cb = 4;\n for (var i = 0; i < cb; i++) {\n if (s) s = ',' + s;\n s = Str.toBin(n & 0xff, 8) + s;\n n >>= 8;\n }\n return (fPrefix? \"0b\" : \"\") + s;\n }\n\n /**\n * toOct(n, cch, fPrefix)\n *\n * Converts an integer to octal, with the specified number of digits (default of 6; max of 12)\n *\n * You might be tempted to use the built-in n.toString(8) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw\n * an exception, whereas this function will return '?' characters.\n *\n * @param {number|*} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of octal digits (0 or undefined for default of either 6, 8, or 12)\n * @param {boolean} [fPrefix]\n * @return {string} the octal representation of n\n */\n static toOct(n, cch, fPrefix)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.log(8)) || 1;\n var v = Math.abs(n);\n if (v <= 0o777777) {\n cch = 6;\n } else if (v <= 0o77777777) {\n cch = 8;\n } else {\n cch = 12;\n }\n } else if (cch > 12) cch = 12;\n return Str.toBase(n, 8, cch, fPrefix? \"0o\" : \"\");\n }\n\n /**\n * toDec(n, cch)\n *\n * Converts an integer to decimal, with the specified number of digits (default of 5; max of 11)\n *\n * You might be tempted to use the built-in n.toString(10) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw\n * an exception, whereas this function will return '?' characters.\n *\n * @param {number|*} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of decimal digits (0 or undefined for default of either 5 or 11)\n * @return {string} the decimal representation of n\n */\n static toDec(n, cch)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.LN10) || 1;\n var v = Math.abs(n);\n if (v <= 99999) {\n cch = 5;\n } else {\n cch = 11;\n }\n } else if (cch > 11) cch = 11;\n return Str.toBase(n, 10, cch);\n }\n\n /**\n * toHex(n, cch, fPrefix)\n *\n * Converts an integer to hex, with the specified number of digits (default of 4 or 8, max of 9).\n *\n * You might be tempted to use the built-in n.toString(16) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values; for example, if n is -2147483647, then n.toString(16)\n * will return \"-7fffffff\" instead of \"80000001\". Moreover, if n is undefined, n.toString() will\n * throw an exception, whereas this function will return '?' characters.\n *\n * NOTE: The following work-around (adapted from code found on StackOverflow) would be another solution,\n * taking care of negative values, zero-padding, and upper-casing, but not null/undefined/NaN values:\n *\n * s = (n < 0? n + 0x100000000 : n).toString(16);\n * s = \"00000000\".substr(0, 8 - s.length) + s;\n * s = s.substr(0, cch).toUpperCase();\n *\n * @param {number|*} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of hex digits (0 or undefined for default of either 4, 8, or 9)\n * @param {boolean} [fPrefix]\n * @return {string} the hex representation of n\n */\n static toHex(n, cch, fPrefix)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.log(16)) || 1;\n var v = Math.abs(n);\n if (v <= 0xffff) {\n cch = 4;\n } else if (v <= 0xffffffff) {\n cch = 8;\n } else {\n cch = 9;\n }\n } else if (cch > 9) cch = 9;\n return Str.toBase(n, 16, cch, fPrefix? \"0x\" : \"\");\n }\n\n /**\n * toHexByte(b)\n *\n * Alias for Str.toHex(b, 2, true)\n *\n * @param {number|null|undefined} b is a byte value\n * @return {string} the hex representation of b\n */\n static toHexByte(b)\n {\n return Str.toHex(b, 2, true);\n }\n\n /**\n * toHexWord(w)\n *\n * Alias for Str.toHex(w, 4, true)\n *\n * @param {number|null|undefined} w is a word (16-bit) value\n * @return {string} the hex representation of w\n */\n static toHexWord(w)\n {\n return Str.toHex(w, 4, true);\n }\n\n /**\n * toHexLong(l)\n *\n * Alias for Str.toHex(l, 8, true)\n *\n * @param {number|null|undefined} l is a dword (32-bit) value\n * @return {string} the hex representation of w\n */\n static toHexLong(l)\n {\n return Str.toHex(l, 8, true);\n }\n\n /**\n * getBaseName(sFileName, fStripExt)\n *\n * This is a poor-man's version of Node's path.basename(), which Node-only components should use instead.\n *\n * Note that if fStripExt is true, this strips ANY extension, whereas path.basename() strips the extension only\n * if it matches the second parameter (eg, path.basename(\"/foo/bar/baz/asdf/quux.html\", \".html\") returns \"quux\").\n *\n * @param {string} sFileName\n * @param {boolean} [fStripExt]\n * @return {string}\n */\n static getBaseName(sFileName, fStripExt)\n {\n var sBaseName = sFileName;\n\n var i = sFileName.lastIndexOf('/');\n if (i >= 0) sBaseName = sFileName.substr(i + 1);\n\n /*\n * This next bit is a kludge to clean up names that are part of a URL that includes unsightly query parameters.\n */\n i = sBaseName.indexOf('&');\n if (i > 0) sBaseName = sBaseName.substr(0, i);\n\n if (fStripExt) {\n i = sBaseName.lastIndexOf(\".\");\n if (i > 0) {\n sBaseName = sBaseName.substring(0, i);\n }\n }\n return sBaseName;\n }\n\n /**\n * getExtension(sFileName)\n *\n * This is a poor-man's version of Node's path.extname(), which Node-only components should use instead.\n *\n * Note that we EXCLUDE the period from the returned extension, whereas path.extname() includes it.\n *\n * @param {string} sFileName\n * @return {string} the filename's extension (in lower-case and EXCLUDING the \".\"), or an empty string\n */\n static getExtension(sFileName)\n {\n var sExtension = \"\";\n var i = sFileName.lastIndexOf(\".\");\n if (i >= 0) {\n sExtension = sFileName.substr(i + 1).toLowerCase();\n }\n return sExtension;\n }\n\n /**\n * endsWith(s, sSuffix)\n *\n * @param {string} s\n * @param {string} sSuffix\n * @return {boolean} true if s ends with sSuffix, false if not\n */\n static endsWith(s, sSuffix)\n {\n return s.indexOf(sSuffix, s.length - sSuffix.length) !== -1;\n }\n\n /**\n * escapeHTML(sHTML)\n *\n * @param {string} sHTML\n * @return {string} with HTML entities \"escaped\", similar to PHP's htmlspecialchars()\n */\n static escapeHTML(sHTML)\n {\n return sHTML.replace(/[&<>\"']/g, function(m)\n {\n return Str.HTMLEscapeMap[m];\n });\n }\n\n /**\n * replace(sSearch, sReplace, s)\n *\n * The JavaScript replace() function ALWAYS interprets \"$\" specially in replacement strings, even when\n * the search string is NOT a RegExp; specifically:\n *\n * $$ Inserts a \"$\"\n * $& Inserts the matched substring\n * $` Inserts the portion of the string that precedes the matched substring\n * $' Inserts the portion of the string that follows the matched substring\n * $n Where n is a positive integer less than 100, inserts the nth parenthesized sub-match string,\n * provided the first argument was a RegExp object\n *\n * So, if a replacement string containing dollar signs passes through a series of replace() calls, untold\n * problems could result. Hence, this function, which simply uses the replacement string as-is.\n *\n * Similar to the JavaScript replace() method (when sSearch is a string), this replaces only ONE occurrence\n * (ie, the FIRST occurrence); it might be nice to add options to replace the LAST occurrence and/or ALL\n * occurrences, but we'll revisit that later.\n *\n * @param {string} sSearch\n * @param {string} sReplace\n * @param {string} s\n * @return {string}\n */\n static replace(sSearch, sReplace, s)\n {\n var i = s.indexOf(sSearch);\n if (i >= 0) {\n s = s.substr(0, i) + sReplace + s.substr(i + sSearch.length);\n }\n return s;\n }\n\n /**\n * replaceAll(sSearch, sReplace, s)\n *\n * @param {string} sSearch\n * @param {string} sReplace\n * @param {string} s\n * @return {string}\n */\n static replaceAll(sSearch, sReplace, s)\n {\n var a = {};\n a[sSearch] = sReplace;\n return Str.replaceArray(a, s);\n }\n\n /**\n * replaceArray(a, s)\n *\n * @param {Object} a\n * @param {string} s\n * @return {string}\n */\n static replaceArray(a, s)\n {\n var sMatch = \"\";\n for (var k in a) {\n /*\n * As noted in:\n *\n * http://www.regexguru.com/2008/04/escape-characters-only-when-necessary/\n *\n * inside character classes, only backslash, caret, hyphen and the closing bracket need to be\n * escaped. And in fact, if you ensure that the closing bracket is first, the caret is not first,\n * and the hyphen is last, you can avoid escaping those as well.\n */\n k = k.replace(/([\\\\[\\]*{}().+?|$])/g, \"\\\\$1\");\n sMatch += (sMatch? '|' : '') + k;\n }\n return s.replace(new RegExp('(' + sMatch + ')', \"g\"), function(m)\n {\n return a[m];\n });\n }\n\n /**\n * pad(s, cch, fPadLeft)\n *\n * NOTE: the maximum amount of padding currently supported is 40 spaces.\n *\n * @param {string} s is a string\n * @param {number} cch is desired length\n * @param {boolean} [fPadLeft] (default is padding on the right)\n * @return {string} the original string (s) with spaces padding it to the specified length\n */\n static pad(s, cch, fPadLeft)\n {\n var sPadding = \" \";\n return fPadLeft? (sPadding + s).slice(-cch) : (s + sPadding).slice(0, cch);\n }\n\n /**\n * sprintf(format, ...args)\n *\n * Copied from the CCjs project (https://github.com/jeffpar/ccjs/blob/master/lib/stdio.js) and extended.\n *\n * Far from complete, let alone sprintf-compatible, but it's adequate for the handful of sprintf-style format\n * specifiers that I use.\n *\n * @param {string} format\n * @param {...} args\n * @return {string}\n */\n static sprintf(format, ...args)\n {\n let buffer = \"\";\n let aParts = format.split(/%([-+ 0#]?)([0-9]*)(\\.?)([0-9]*)([hlL]?)([A-Za-z%])/);\n\n let iArg = 0, iPart;\n for (iPart = 0; iPart < aParts.length - 7; iPart += 7) {\n\n buffer += aParts[iPart];\n\n let arg = args[iArg++];\n let flags = aParts[iPart+1];\n let minimum = +aParts[iPart+2] || 0;\n let precision = +aParts[iPart+4] || 0;\n let conversion = aParts[iPart+6];\n let ach = null, s;\n\n switch(conversion) {\n case 'd':\n /*\n * We could use \"arg |= 0\", but there may be some value to supporting integers > 32 bits.\n * \n * Also, unlike the 'X' and 'x' hexadecimal cases, there's no need to explicitly check for a string\n * arguments, because the call to trunc() automatically coerces any string value to a (decimal) number.\n */\n arg = Math.trunc(arg);\n /* falls through */\n\n case 'f':\n s = Math.trunc(arg) + \"\";\n if (precision) {\n minimum -= (precision + 1);\n }\n if (s.length < minimum) {\n if (flags == '0') {\n if (arg < 0) minimum--;\n s = (\"0000000000\" + Math.abs(arg)).slice(-minimum);\n if (arg < 0) s = '-' + s;\n } else {\n s = (\" \" + s).slice(-minimum);\n }\n }\n if (precision) {\n arg = Math.round((arg - Math.trunc(arg)) * Math.pow(10, precision));\n s += '.' + (\"0000000000\" + Math.abs(arg)).slice(-precision);\n }\n buffer += s;\n break;\n\n case 'c':\n arg = String.fromCharCode(arg);\n /* falls through */\n\n case 's':\n if (typeof arg == \"string\") {\n while (arg.length < minimum) {\n if (flags == '-') {\n arg += ' ';\n } else {\n arg = ' ' + arg;\n }\n }\n }\n buffer += arg;\n break;\n\n case 'X':\n ach = Str.HexUpperCase;\n /* falls through */\n\n case 'x':\n if (!ach) ach = Str.HexLowerCase;\n s = \"\";\n if (typeof arg == \"string\") {\n /*\n * Since we're advised to ALWAYS pass a radix to parseInt(), we must detect explicitly\n * hex values ourselves, because using a radix of 10 with any \"0x...\" value always returns 0.\n * \n * And if the value CAN be interpreted as decimal, then we MUST interpret it as decimal, because\n * we have sprintf() calls in /modules/lib/testmon.js that depend on this code to perform decimal\n * to hex conversion. We're allowed to make our own rules here, since passing numbers in string\n * form isn't part of the sprintf \"spec\". \n */\n arg = Number.parseInt(arg, arg.match(/(^0x|[a-f])/i)? 16 : 10);\n } \n do {\n s = ach[arg & 0xf] + s;\n arg >>>= 4;\n } while (--minimum > 0 || arg);\n buffer += s;\n break;\n\n default:\n /*\n * The supported ANSI C set of conversions: \"dioxXucsfeEgGpn%\"\n */\n buffer += \"(unrecognized printf conversion %\" + conversion + \")\";\n break;\n }\n }\n\n buffer += aParts[iPart];\n return buffer;\n }\n\n /**\n * stripLeadingZeros(s, fPad)\n *\n * @param {string} s\n * @param {boolean} [fPad]\n * @return {string}\n */\n static stripLeadingZeros(s, fPad)\n {\n var cch = s.length;\n s = s.replace(/^0+([0-9A-F]+)$/i, \"$1\");\n if (fPad) s = Str.pad(s, cch, true);\n return s;\n }\n\n /**\n * trim(s)\n *\n * @param {string} s\n * @return {string}\n */\n static trim(s)\n {\n if (String.prototype.trim) {\n return s.trim();\n }\n return s.replace(/^\\s+|\\s+$/g, \"\");\n }\n\n /**\n * toASCIICode(b)\n *\n * @param {number} b\n * @return {string}\n */\n static toASCIICode(b)\n {\n var s;\n if (b != Str.ASCII.CR && b != Str.ASCII.LF) {\n s = Str.ASCIICodeMap[b];\n }\n if (s) {\n s = '<' + s + '>';\n } else {\n s = String.fromCharCode(b);\n }\n return s;\n }\n}\n\n/*\n * Map special characters to their HTML escape sequences.\n */\nStr.HTMLEscapeMap = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n};\n\n/*\n * Map \"unprintable\" ASCII codes to mnemonics, to more clearly see what's being printed.\n */\nStr.ASCIICodeMap = {\n 0x00: \"NUL\",\n 0x01: \"SOH\", // (CTRL_A) Start of Heading\n 0x02: \"STX\", // (CTRL_B) Start of Text\n 0x03: \"ETX\", // (CTRL_C) End of Text\n 0x04: \"EOT\", // (CTRL_D) End of Transmission\n 0x05: \"ENQ\", // (CTRL_E) Enquiry\n 0x06: \"ACK\", // (CTRL_F) Acknowledge\n 0x07: \"BEL\", // (CTRL_G) Bell\n 0x08: \"BS\", // (CTRL_H) Backspace\n 0x09: \"TAB\", // (CTRL_I) Horizontal Tab (aka HT)\n 0x0A: \"LF\", // (CTRL_J) Line Feed (New Line)\n 0x0B: \"VT\", // (CTRL_K) Vertical Tab\n 0x0C: \"FF\", // (CTRL_L) Form Feed (New Page)\n 0x0D: \"CR\", // (CTRL_M) Carriage Return\n 0x0E: \"SO\", // (CTRL_N) Shift Out\n 0x0F: \"SI\", // (CTRL_O) Shift In\n 0x10: \"DLE\", // (CTRL_P) Data Link Escape\n 0x11: \"XON\", // (CTRL_Q) Device Control 1 (aka DC1)\n 0x12: \"DC2\", // (CTRL_R) Device Control 2\n 0x13: \"XOFF\", // (CTRL_S) Device Control 3 (aka DC3)\n 0x14: \"DC4\", // (CTRL_T) Device Control 4\n 0x15: \"NAK\", // (CTRL_U) Negative Acknowledge\n 0x16: \"SYN\", // (CTRL_V) Synchronous Idle\n 0x17: \"ETB\", // (CTRL_W) End of Transmission Block\n 0x18: \"CAN\", // (CTRL_X) Cancel\n 0x19: \"EM\", // (CTRL_Y) End of Medium\n 0x1A: \"SUB\", // (CTRL_Z) Substitute\n 0x1B: \"ESC\", // Escape\n 0x1C: \"FS\", // File Separator\n 0x1D: \"GS\", // Group Separator\n 0x1E: \"RS\", // Record Separator\n 0x1F: \"US\", // Unit Separator\n 0x7F: \"DEL\"\n};\n\n/*\n * Refer to: https://en.wikipedia.org/wiki/Code_page_437\n */\nStr.CP437ToUnicode = [\n '\\u0000', '\\u263A', '\\u263B', '\\u2665', '\\u2666', '\\u2663', '\\u2660', '\\u2022',\n '\\u25D8', '\\u25CB', '\\u25D9', '\\u2642', '\\u2640', '\\u266A', '\\u266B', '\\u263C',\n '\\u25BA', '\\u25C4', '\\u2195', '\\u203C', '\\u00B6', '\\u00A7', '\\u25AC', '\\u21A8',\n '\\u2191', '\\u2193', '\\u2192', '\\u2190', '\\u221F', '\\u2194', '\\u25B2', '\\u25BC',\n '\\u0020', '\\u0021', '\\u0022', '\\u0023', '\\u0024', '\\u0025', '\\u0026', '\\u0027',\n '\\u0028', '\\u0029', '\\u002A', '\\u002B', '\\u002C', '\\u002D', '\\u002E', '\\u002F',\n '\\u0030', '\\u0031', '\\u0032', '\\u0033', '\\u0034', '\\u0035', '\\u0036', '\\u0037',\n '\\u0038', '\\u0039', '\\u003A', '\\u003B', '\\u003C', '\\u003D', '\\u003E', '\\u003F',\n '\\u0040', '\\u0041', '\\u0042', '\\u0043', '\\u0044', '\\u0045', '\\u0046', '\\u0047',\n '\\u0048', '\\u0049', '\\u004A', '\\u004B', '\\u004C', '\\u004D', '\\u004E', '\\u004F',\n '\\u0050', '\\u0051', '\\u0052', '\\u0053', '\\u0054', '\\u0055', '\\u0056', '\\u0057',\n '\\u0058', '\\u0059', '\\u005A', '\\u005B', '\\u005C', '\\u005D', '\\u005E', '\\u005F',\n '\\u0060', '\\u0061', '\\u0062', '\\u0063', '\\u0064', '\\u0065', '\\u0066', '\\u0067',\n '\\u0068', '\\u0069', '\\u006A', '\\u006B', '\\u006C', '\\u006D', '\\u006E', '\\u006F',\n '\\u0070', '\\u0071', '\\u0072', '\\u0073', '\\u0074', '\\u0075', '\\u0076', '\\u0077',\n '\\u0078', '\\u0079', '\\u007A', '\\u007B', '\\u007C', '\\u007D', '\\u007E', '\\u2302',\n '\\u00C7', '\\u00FC', '\\u00E9', '\\u00E2', '\\u00E4', '\\u00E0', '\\u00E5', '\\u00E7',\n '\\u00EA', '\\u00EB', '\\u00E8', '\\u00EF', '\\u00EE', '\\u00EC', '\\u00C4', '\\u00C5',\n '\\u00C9', '\\u00E6', '\\u00C6', '\\u00F4', '\\u00F6', '\\u00F2', '\\u00FB', '\\u00F9',\n '\\u00FF', '\\u00D6', '\\u00DC', '\\u00A2', '\\u00A3', '\\u00A5', '\\u20A7', '\\u0192',\n '\\u00E1', '\\u00ED', '\\u00F3', '\\u00FA', '\\u00F1', '\\u00D1', '\\u00AA', '\\u00BA',\n '\\u00BF', '\\u2310', '\\u00AC', '\\u00BD', '\\u00BC', '\\u00A1', '\\u00AB', '\\u00BB',\n '\\u2591', '\\u2592', '\\u2593', '\\u2502', '\\u2524', '\\u2561', '\\u2562', '\\u2556',\n '\\u2555', '\\u2563', '\\u2551', '\\u2557', '\\u255D', '\\u255C', '\\u255B', '\\u2510',\n '\\u2514', '\\u2534', '\\u252C', '\\u251C', '\\u2500', '\\u253C', '\\u255E', '\\u255F',\n '\\u255A', '\\u2554', '\\u2569', '\\u2566', '\\u2560', '\\u2550', '\\u256C', '\\u2567',\n '\\u2568', '\\u2564', '\\u2565', '\\u2559', '\\u2558', '\\u2552', '\\u2553', '\\u256B',\n '\\u256A', '\\u2518', '\\u250C', '\\u2588', '\\u2584', '\\u258C', '\\u2590', '\\u2580',\n '\\u03B1', '\\u00DF', '\\u0393', '\\u03C0', '\\u03A3', '\\u03C3', '\\u00B5', '\\u03C4',\n '\\u03A6', '\\u0398', '\\u03A9', '\\u03B4', '\\u221E', '\\u03C6', '\\u03B5', '\\u2229',\n '\\u2261', '\\u00B1', '\\u2265', '\\u2264', '\\u2320', '\\u2321', '\\u00F7', '\\u2248',\n '\\u00B0', '\\u2219', '\\u00B7', '\\u221A', '\\u207F', '\\u00B2', '\\u25A0', '\\u00A0'\n];\n\n/*\n * TODO: Future home of a complete ASCII table.\n */\nStr.ASCII = {\n LF: 0x0A,\n CR: 0x0D\n};\n\nStr.TYPES = {\n NULL: 0,\n BYTE: 1,\n WORD: 2,\n DWORD: 3,\n NUMBER: 4,\n STRING: 5,\n BOOLEAN: 6,\n OBJECT: 7,\n ARRAY: 8\n};\n\nStr.HexLowerCase = \"0123456789abcdef\";\nStr.HexUpperCase = \"0123456789ABCDEF\";\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/usrlib.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @typedef {{\n * mask: number,\n * shift: number\n * }}\n */\nvar BitField;\n\n/**\n * @typedef {Object.<BitField>}\n */\nvar BitFields;\n\nclass Usr {\n /**\n * binarySearch(a, v, fnCompare)\n *\n * @param {Array} a is an array\n * @param {number|string|Array|Object} v\n * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]\n * @return {number} the index of matching entry if non-negative, otherwise the index of the insertion point\n */\n static binarySearch(a, v, fnCompare)\n {\n var left = 0;\n var right = a.length;\n var found = 0;\n if (fnCompare === undefined) {\n fnCompare = function(a, b)\n {\n return a > b ? 1 : a < b ? -1 : 0;\n };\n }\n while (left < right) {\n var middle = (left + right) >> 1;\n var compareResult;\n compareResult = fnCompare(v, a[middle]);\n if (compareResult > 0) {\n left = middle + 1;\n } else {\n right = middle;\n found = !compareResult;\n }\n }\n return found ? left : ~left;\n }\n\n /**\n * binaryInsert(a, v, fnCompare)\n *\n * If element v already exists in array a, the array is unchanged (we don't allow duplicates); otherwise, the\n * element is inserted into the array at the appropriate index.\n *\n * @param {Array} a is an array\n * @param {number|string|Array|Object} v is the value to insert\n * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]\n */\n static binaryInsert(a, v, fnCompare)\n {\n var index = Usr.binarySearch(a, v, fnCompare);\n if (index < 0) {\n a.splice(-(index + 1), 0, v);\n }\n }\n\n /**\n * getTimestamp()\n *\n * @return {string} timestamp containing the current date and time (\"yyyy-mm-dd hh:mm:ss\")\n */\n static getTimestamp()\n {\n return Usr.formatDate(\"Y-m-d H:i:s\");\n }\n\n /**\n * getMonthDays(nMonth, nYear)\n *\n * Note that if we're being called on behalf of the RTC, its year is always truncated to two digits (mod 100),\n * so we have no idea what century the year 0 might refer to. When using the normal leap-year formula, 0 fails\n * the mod 100 test but passes the mod 400 test, so as far as the RTC is concerned, every century year is a leap\n * year. Since we're most likely dealing with the year 2000, that's fine, since 2000 was also a leap year.\n *\n * TODO: There IS a separate CMOS byte that's supposed to be set to CMOS_ADDR.CENTURY_DATE; it's always BCD,\n * so theoretically it will contain values like 0x19 or 0x20 (for the 20th and 21st centuries, respectively), and\n * we could add that as another parameter to this function, to improve the accuracy, but that would go beyond what\n * a real RTC actually does.\n *\n * @param {number} nMonth (1-12)\n * @param {number} nYear (normally a 4-digit year, but it may also be mod 100)\n * @return {number} the maximum (1-based) day allowed for the specified month and year\n */\n static getMonthDays(nMonth, nYear)\n {\n var nDays = Usr.aMonthDays[nMonth - 1];\n if (nDays == 28) {\n if ((nYear % 4) === 0 && ((nYear % 100) || (nYear % 400) === 0)) {\n nDays++;\n }\n }\n return nDays;\n }\n\n /**\n * formatDate(sFormat, date)\n *\n * @param {string} sFormat (eg, \"F j, Y\", \"Y-m-d H:i:s\")\n * @param {Date} [date] (default is the current time)\n * @return {string}\n *\n * Supported identifiers in sFormat include:\n *\n * a: lowercase ante meridiem and post meridiem (am or pm)\n * d: day of the month, 2 digits with leading zeros (01,02,...,31)\n * D: 3-letter day of the week (\"Sun\",\"Mon\",...,\"Sat\")\n * F: month (\"January\",\"February\",...,\"December\")\n * g: hour in 12-hour format, without leading zeros (1,2,...,12)\n * h: hour in 24-hour format, without leading zeros (0,1,...,23)\n * H: hour in 24-hour format, with leading zeros (00,01,...,23)\n * i: minutes, with leading zeros (00,01,...,59)\n * j: day of the month, without leading zeros (1,2,...,31)\n * l: day of the week (\"Sunday\",\"Monday\",...,\"Saturday\")\n * m: month, with leading zeros (01,02,...,12)\n * M: 3-letter month (\"Jan\",\"Feb\",...,\"Dec\")\n * n: month, without leading zeros (1,2,...,12)\n * s: seconds, with leading zeros (00,01,...,59)\n * y: 2-digit year (eg, 14)\n * Y: 4-digit year (eg, 2014)\n *\n * For more inspiration, see: http://php.net/manual/en/function.date.php (of which we support ONLY a subset).\n */\n static formatDate(sFormat, date)\n {\n var sDate = \"\";\n if (!date) date = new Date();\n var iHour = date.getHours();\n var iDay = date.getDate();\n var iMonth = date.getMonth() + 1;\n for (var i = 0; i < sFormat.length; i++) {\n var ch;\n switch ((ch = sFormat.charAt(i))) {\n case 'a':\n sDate += (iHour < 12 ? \"am\" : \"pm\");\n break;\n case 'd':\n sDate += ('0' + iDay).slice(-2);\n break;\n case 'D':\n sDate += Usr.asDays[date.getDay()].substr(0, 3);\n break;\n case 'F':\n sDate += Usr.asMonths[iMonth - 1];\n break;\n case 'g':\n sDate += (!iHour ? 12 : (iHour > 12 ? iHour - 12 : iHour));\n break;\n case 'h':\n sDate += iHour;\n break;\n case 'H':\n sDate += ('0' + iHour).slice(-2);\n break;\n case 'i':\n sDate += ('0' + date.getMinutes()).slice(-2);\n break;\n case 'j':\n sDate += iDay;\n break;\n case 'l':\n sDate += Usr.asDays[date.getDay()];\n break;\n case 'm':\n sDate += ('0' + iMonth).slice(-2);\n break;\n case 'M':\n sDate += Usr.asMonths[iMonth - 1].substr(0, 3);\n break;\n case 'n':\n sDate += iMonth;\n break;\n case 's':\n sDate += ('0' + date.getSeconds()).slice(-2);\n break;\n case 'y':\n sDate += (\"\" + date.getFullYear()).slice(-2);\n break;\n case 'Y':\n sDate += date.getFullYear();\n break;\n default:\n sDate += ch;\n break;\n }\n }\n return sDate;\n }\n\n /**\n * defineBitFields(bfs)\n *\n * Prepares a bit field definition for use with getBitField() and setBitField(); eg:\n *\n * var bfs = Usr.defineBitFields({num:20, count:8, btmod:1, type:3});\n *\n * The above defines a set of bit fields containing four fields: num (bits 0-19), count (bits 20-27), btmod (bit 28), and type (bits 29-31).\n *\n * Usr.setBitField(bfs.num, n, 1);\n *\n * The above set bit field \"bfs.num\" in numeric variable \"n\" to the value 1.\n *\n * @param {Object} bfs\n * @return {BitFields}\n */\n static defineBitFields(bfs)\n {\n var bit = 0;\n for (var f in bfs) {\n var width = bfs[f];\n var mask = ((1 << width) - 1) << bit;\n bfs[f] = {mask: mask, shift: bit};\n bit += width;\n }\n return bfs;\n }\n\n /**\n * initBitFields(bfs, ...)\n *\n * @param {BitFields} bfs\n * @param {...number} var_args\n * @return {number} a value containing all supplied bit fields\n */\n static initBitFields(bfs, var_args)\n {\n var v = 0, i = 1;\n for (var f in bfs) {\n if (i >= arguments.length) break;\n v = Usr.setBitField(bfs[f], v, arguments[i++]);\n }\n return v;\n }\n\n /**\n * getBitField(bf, v)\n *\n * @param {BitField} bf\n * @param {number} v is a value containing bit fields\n * @return {number} the value of the bit field in v defined by bf\n */\n static getBitField(bf, v)\n {\n return (v & bf.mask) >> bf.shift;\n }\n\n /**\n * setBitField(bf, v, n)\n *\n * @param {BitField} bf\n * @param {number} v is a value containing bit fields\n * @param {number} n is a value to store in v in the bit field defined by bf\n * @return {number} updated v\n */\n static setBitField(bf, v, n)\n {\n return (v & ~bf.mask) | ((n << bf.shift) & bf.mask);\n }\n\n /**\n * indexOf(a, t, i)\n *\n * Use this instead of Array.prototype.indexOf() if you can't be sure the browser supports it.\n *\n * @param {Array} a\n * @param {*} t\n * @param {number} [i]\n * @returns {number}\n */\n static indexOf(a, t, i)\n {\n if (Array.prototype.indexOf) {\n return a.indexOf(t, i);\n }\n i = i || 0;\n if (i < 0) i += a.length;\n if (i < 0) i = 0;\n for (var n = a.length; i < n; i++) {\n if (i in a && a[i] === t) return i;\n }\n return -1;\n }\n}\n\nUsr.asDays = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\nUsr.asMonths = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\nUsr.aMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\n/**\n * getTime()\n *\n * @return {number} the current time, in milliseconds\n */\nUsr.getTime = Date.now || function() { return +new Date(); };\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/weblib.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * According to http://www.w3schools.com/jsref/jsref_obj_global.asp, these are the *global* properties\n * and functions of JavaScript-in-the-Browser:\n *\n * Property Description\n * ---\n * Infinity A numeric value that represents positive/negative infinity\n * NaN \"Not-a-Number\" value\n * undefined Indicates that a variable has not been assigned a value\n *\n * Function Description\n * ---\n * decodeURI() Decodes a URI\n * decodeURIComponent() Decodes a URI component\n * encodeURI() Encodes a URI\n * encodeURIComponent() Encodes a URI component\n * escape() Deprecated in version 1.5. Use encodeURI() or encodeURIComponent() instead\n * eval() Evaluates a string and executes it as if it was script code\n * isFinite() Determines whether a value is a finite, legal number\n * isNaN() Determines whether a value is an illegal number\n * Number() Converts an object's value to a number\n * parseFloat() Parses a string and returns a floating point number\n * parseInt() Parses a string and returns an integer\n * String() Converts an object's value to a string\n * unescape() Deprecated in version 1.5. Use decodeURI() or decodeURIComponent() instead\n *\n * And according to http://www.w3schools.com/jsref/obj_window.asp, these are the properties and functions\n * of the *window* object.\n *\n * Property Description\n * ---\n * closed Returns a Boolean value indicating whether a window has been closed or not\n * defaultStatus Sets or returns the default text in the statusbar of a window\n * document Returns the Document object for the window (See Document object)\n * frames Returns an array of all the frames (including iframes) in the current window\n * history Returns the History object for the window (See History object)\n * innerHeight Returns the inner height of a window's content area\n * innerWidth Returns the inner width of a window's content area\n * length Returns the number of frames (including iframes) in a window\n * location Returns the Location object for the window (See Location object)\n * name Sets or returns the name of a window\n * navigator Returns the Navigator object for the window (See Navigator object)\n * opener Returns a reference to the window that created the window\n * outerHeight Returns the outer height of a window, including toolbars/scrollbars\n * outerWidth Returns the outer width of a window, including toolbars/scrollbars\n * pageXOffset Returns the pixels the current document has been scrolled (horizontally) from the upper left corner of the window\n * pageYOffset Returns the pixels the current document has been scrolled (vertically) from the upper left corner of the window\n * parent Returns the parent window of the current window\n * screen Returns the Screen object for the window (See Screen object)\n * screenLeft Returns the x coordinate of the window relative to the screen\n * screenTop Returns the y coordinate of the window relative to the screen\n * screenX Returns the x coordinate of the window relative to the screen\n * screenY Returns the y coordinate of the window relative to the screen\n * self Returns the current window\n * status Sets or returns the text in the statusbar of a window\n * top Returns the topmost browser window\n *\n * Method Description\n * ---\n * alert() Displays an alert box with a message and an OK button\n * atob() Decodes a base-64 encoded string\n * blur() Removes focus from the current window\n * btoa() Encodes a string in base-64\n * clearInterval() Clears a timer set with setInterval()\n * clearTimeout() Clears a timer set with setTimeout()\n * close() Closes the current window\n * confirm() Displays a dialog box with a message and an OK and a Cancel button\n * createPopup() Creates a pop-up window\n * focus() Sets focus to the current window\n * moveBy() Moves a window relative to its current position\n * moveTo() Moves a window to the specified position\n * open() Opens a new browser window\n * print() Prints the content of the current window\n * prompt() Displays a dialog box that prompts the visitor for input\n * resizeBy() Resizes the window by the specified pixels\n * resizeTo() Resizes the window to the specified width and height\n * scroll() This method has been replaced by the scrollTo() method.\n * scrollBy() Scrolls the content by the specified number of pixels\n * scrollTo() Scrolls the content to the specified coordinates\n * setInterval() Calls a function or evaluates an expression at specified intervals (in milliseconds)\n * setTimeout() Calls a function or evaluates an expression after a specified number of milliseconds\n * stop() Stops the window from loading\n */\n\nclass Web {\n /**\n * log(s, type)\n *\n * For diagnostic output only. DEBUG must be true (or \"--debug\" specified via the command-line)\n * for Component.log() to display anything.\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n static log(s, type)\n {\n Component.log(s, type);\n }\n\n /**\n * notice(s, fPrintOnly, id)\n *\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n */\n static notice(s, fPrintOnly, id)\n {\n Component.notice(s, fPrintOnly, id);\n }\n\n /**\n * alertUser(sMessage)\n * \n * NOTE: Legacy function for older modules (eg, DiskDump); see Component.alertUser().\n *\n * @param {string} sMessage\n */\n static alertUser(sMessage)\n {\n if (window) {\n window.alert(sMessage);\n } else {\n Web.log(sMessage);\n }\n }\n\n /**\n * getResource(sURL, type, fAsync, done, progress)\n *\n * Request the specified resource (sURL), and once the request is complete, notify done().\n *\n * If fAsync is true, a done() callback should ALWAYS be supplied; otherwise, you'll have no\n * idea when the request is complete or what the response was. done() is passed three parameters:\n *\n * done(sURL, resource, nErrorCode)\n *\n * If nErrorCode is zero, resource should contain the requested data; otherwise, an error occurred.\n *\n * If type is set to a string, that string can be used to control the response format;\n * by default, the response format is plain text, but you can specify \"arraybuffer\" to request arbitrary\n * binary data, in which case the returned resource will be a ArrayBuffer rather than a string.\n *\n * @param {string} sURL\n * @param {string|Object|null} [type] (object for POST request, otherwise type of GET request)\n * @param {boolean} [fAsync] is true for an asynchronous request; false otherwise (MUST be set for IE)\n * @param {function(string,string,number)} [done]\n * @param {function(number)} [progress]\n * @return {Array|null} Array containing [resource, nErrorCode], or null if no response available (yet)\n */\n static getResource(sURL, type = \"text\", fAsync = false, done, progress)\n {\n var nErrorCode = 0, resource = null, response = null;\n\n if (typeof resources == 'object' && (resource = resources[sURL])) {\n if (done) done(sURL, resource, nErrorCode);\n return [resource, nErrorCode];\n }\n else if (fAsync && typeof resources == 'function') {\n resources(sURL, function(resource, nErrorCode)\n {\n if (done) done(sURL, resource, nErrorCode);\n });\n return response;\n }\n\n if (!DEBUG && !NODE) {\n /*\n * TODO: Perhaps it's time for our code in netlib.js to finally add support for HTTPS; for now\n * though, it's just as well that the NODE environment assumes all resources are available locally.\n */\n sURL = sURL.replace(/^\\/(pcjs-disks|private-disks)\\//, \"https://jeffpar.github.io/$1/\");\n }\n else {\n /*\n * The larger resources we put on archive.pcjs.org should also be available locally.\n *\n * NOTE: \"http://archive.pcjs.org\" is now \"https://s3-us-west-2.amazonaws.com/archive.pcjs.org\"\n */\n sURL = sURL.replace(/^(http:\\/\\/archive\\.pcjs\\.org|https:\\/\\/s3-us-west-2\\.amazonaws\\.com\\/archive\\.pcjs\\.org)(\\/.*)\\/([^\\/]*)$/, \"$2/archive/$3\");\n sURL = sURL.replace(/^https:\\/\\/jeffpar\\.github\\.io\\/(pcjs-disks|private-disks)\\/(.*)$/, \"/$1/$2\");\n }\n\n\n var request = (window.XMLHttpRequest? new window.XMLHttpRequest() : new window.ActiveXObject(\"Microsoft.XMLHTTP\"));\n var fArrayBuffer = false, fXHR2 = (typeof request.responseType === 'string');\n \n var callback = function() {\n if (request.readyState !== 4) {\n if (progress) progress(1);\n return null;\n }\n /*\n * The following line was recommended for WebKit, as a work-around to prevent the handler firing multiple\n * times when debugging. Unfortunately, that's not the only XMLHttpRequest problem that occurs when\n * debugging, so I think the WebKit problem is deeper than that. When we have multiple XMLHttpRequests\n * pending, any debugging activity means most of them simply get dropped on floor, so what may actually be\n * happening are mis-notifications rather than redundant notifications.\n *\n * request.onreadystatechange = undefined;\n */\n /*\n * If the request failed due to, say, a CORS policy denial; eg:\n * \n * Failed to load http://www.allbootdisks.com/downloads/Disks/Windows_95_Boot_Disk_Download48/Diskette%20Images/Windows95a.img:\n * Redirect from 'http://www.allbootdisks.com/downloads/Disks/Windows_95_Boot_Disk_Download48/Diskette%20Images/Windows95a.img' to\n * 'http://www.allbootdisks.com/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.\n * Origin 'http://pcjs:8088' is therefore not allowed access.\n * \n * and our request type was \"arraybuffer\", attempting to access responseText may trigger an exception; eg:\n * \n * Uncaught DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's\n * 'responseType' is '' or 'text' (was 'arraybuffer').\n * \n * We could tiptoe around these potential landmines, but the safest thing to do is wrap this code with try/catch.\n */\n try {\n resource = fArrayBuffer? request.response : request.responseText;\n } catch(err) {\n if (MAXDEBUG) Web.log(\"xmlHTTPRequest(\" + sURL + \") exception: \" + err.message);\n }\n /*\n * The normal \"success\" case is a non-null resource and an HTTP status code of 200, but when loading files from the\n * local file system (ie, when using the \"file:\" protocol), we have to be a bit more flexible.\n */\n if (resource != null && (request.status == 200 || !request.status && resource.length && Web.getHostProtocol() == \"file:\")) {\n if (MAXDEBUG) Web.log(\"xmlHTTPRequest(\" + sURL + \"): returned \" + resource.length + \" bytes\");\n }\n else {\n nErrorCode = request.status || -1;\n Web.log(\"xmlHTTPRequest(\" + sURL + \"): error code \" + nErrorCode);\n }\n if (progress) progress(2);\n if (done) done(sURL, resource, nErrorCode);\n return [resource, nErrorCode];\n };\n \n if (fAsync) {\n request.onreadystatechange = callback;\n }\n\n if (progress) progress(0);\n\n if (type && typeof type == \"object\") {\n var sPost = \"\";\n for (var p in type) {\n if (!type.hasOwnProperty(p)) continue;\n if (sPost) sPost += \"&\";\n sPost += p + '=' + encodeURIComponent(type[p]);\n }\n sPost = sPost.replace(/%20/g, '+');\n if (MAXDEBUG) Web.log(\"Web.getResource(POST \" + sURL + \"): \" + sPost.length + \" bytes\");\n request.open(\"POST\", sURL, fAsync);\n request.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\n request.send(sPost);\n } else {\n if (MAXDEBUG) Web.log(\"Web.getResource(GET \" + sURL + \")\");\n request.open(\"GET\", sURL, fAsync);\n if (type == \"arraybuffer\") {\n if (fXHR2) {\n fArrayBuffer = true;\n request.responseType = type;\n } else {\n request.overrideMimeType(\"text/plain; charset=x-user-defined\");\n }\n }\n request.send();\n }\n\n if (!fAsync) {\n request.readyState = 4; // this may already be set for synchronous requests, but I don't want to take any chances \n response = callback();\n }\n return response;\n }\n\n /**\n * parseMemoryResource(sURL, sData)\n *\n * This converts a variety of JSON-style data streams into an Object with the following properties:\n *\n * aBytes\n * aSymbols\n * addrLoad\n * addrExec\n *\n * If the source data contains a 'bytes' array, it's passed through to 'aBytes'; alternatively, if\n * it contains a 'words' array, the values are converted from 16-bit to 8-bit and stored in 'aBytes',\n * and if it contains a 'longs' array, the values are converted from 32-bit longs into bytes and\n * stored in 'aBytes'.\n *\n * Alternatively, if the source data contains a 'data' array, we simply pass that through to the output\n * object as:\n *\n * aData\n *\n * @param {string} sURL\n * @param {string} sData\n * @return {Object|null} (resource)\n */\n static parseMemoryResource(sURL, sData)\n {\n var i;\n var resource = {\n aBytes: null,\n aSymbols: null,\n addrLoad: null,\n addrExec: null\n };\n\n if (sData.charAt(0) == \"[\" || sData.charAt(0) == \"{\") {\n try {\n var a, ib, data;\n\n if (sData.substr(0, 1) == \"<\") { // if the \"data\" begins with a \"<\"...\n /*\n * Early server configs reported an error (via the nErrorCode parameter) if a tape URL was invalid,\n * but more recent server configs now display a somewhat friendlier HTML error page. The downside,\n * however, is that the original error has been buried, and we've received \"data\" that isn't actually\n * tape data. So if the data we've received appears to be \"HTML-like\", we treat it as an error message.\n */\n throw new Error(sData);\n }\n\n /*\n * TODO: IE9 is rather unfriendly and restrictive with regard to how much data it's willing to\n * eval(). In particular, the 10Mb disk image we use for the Windows 1.01 demo config fails in\n * IE9 with an \"Out of memory\" exception. One work-around would be to chop the data into chunks\n * (perhaps one track per chunk, using regular expressions) and then manually re-assemble it.\n *\n * However, it turns out that using JSON.parse(sDiskData) instead of eval(\"(\" + sDiskData + \")\")\n * is a much easier fix. The only drawback is that we must first quote any unquoted property names\n * and remove any comments, because while eval() was cool with them, JSON.parse() is more particular;\n * the following RegExp replacements take care of those requirements.\n *\n * The use of hex values is something else that eval() was OK with, but JSON.parse() is not, and\n * while I've stopped using hex values in DumpAPI responses (at least when \"format=json\" is specified),\n * I can't guarantee they won't show up in \"legacy\" images, and there's no simple RegExp replacement\n * for transforming hex values into decimal values, so I cop out and fall back to eval() if I detect\n * any hex prefixes (\"0x\") in the sequence. Ditto for error messages, which appear like so:\n *\n * [\"unrecognized disk path: test.img\"]\n */\n if (sData.indexOf(\"0x\") < 0 && sData.indexOf(\"0o\") < 0 && sData.substr(0, 2) != '[\"') {\n data = JSON.parse(sData.replace(/([a-z]+):/gm, '\"$1\":').replace(/\\/\\/[^\\n]*/gm, \"\"));\n } else {\n data = eval(\"(\" + sData + \")\");\n }\n\n resource.addrLoad = data['load'];\n resource.addrExec = data['exec'];\n\n if (a = data['bytes']) {\n resource.aBytes = a;\n }\n else if (a = data['words']) {\n /*\n * Convert all words into bytes\n */\n resource.aBytes = new Array(a.length * 2);\n for (i = 0, ib = 0; i < a.length; i++) {\n resource.aBytes[ib++] = a[i] & 0xff;\n resource.aBytes[ib++] = (a[i] >> 8) & 0xff;\n\n }\n }\n else if (a = data['longs']) {\n /*\n * Convert all dwords (longs) into bytes\n */\n resource.aBytes = new Array(a.length * 4);\n for (i = 0, ib = 0; i < a.length; i++) {\n resource.aBytes[ib++] = a[i] & 0xff;\n resource.aBytes[ib++] = (a[i] >> 8) & 0xff;\n resource.aBytes[ib++] = (a[i] >> 16) & 0xff;\n resource.aBytes[ib++] = (a[i] >> 24) & 0xff;\n }\n }\n else if (a = data['data']) {\n resource.aData = a;\n }\n else {\n resource.aBytes = data;\n }\n\n if (resource.aBytes) {\n if (!resource.aBytes.length) {\n Component.error(\"Empty resource: \" + sURL);\n resource = null;\n }\n else if (resource.aBytes.length == 1) {\n Component.error(resource.aBytes[0]);\n resource = null;\n }\n }\n resource.aSymbols = data['symbols'];\n\n } catch (e) {\n Component.error(\"Resource data error (\" + sURL + \"): \" + e.message);\n resource = null;\n }\n }\n else {\n /*\n * Parse the data manually; we assume it's a series of hex byte-values separated by whitespace.\n */\n var ab = [];\n var sHexData = sData.replace(/\\n/gm, \" \").replace(/ +$/, \"\");\n var asHexData = sHexData.split(\" \");\n for (i = 0; i < asHexData.length; i++) {\n var n = parseInt(asHexData[i], 16);\n if (isNaN(n)) {\n Component.error(\"Resource data error (\" + sURL + \"): invalid hex byte (\" + asHexData[i] + \")\");\n break;\n }\n ab.push(n & 0xff);\n }\n if (i == asHexData.length) resource.aBytes = ab;\n }\n return resource;\n }\n\n /**\n * sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)\n *\n * Send a report (eg, bug report) to the server.\n *\n * @param {string} sApp (eg, \"PCjs\")\n * @param {string} sVer (eg, \"1.02\")\n * @param {string} sURL (eg, \"/devices/pc/machine/5150/mda/64kb/machine.xml\")\n * @param {string} sUser (ie, the user key, if any)\n * @param {string} sType (eg, \"bug\"); one of ReportAPI.TYPE.*\n * @param {string} sReport (eg, unparsed state data)\n * @param {string} [sHostName] (default is http://SITEHOST)\n */\n static sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)\n {\n var dataPost = {};\n dataPost[ReportAPI.QUERY.APP] = sApp;\n dataPost[ReportAPI.QUERY.VER] = sVer;\n dataPost[ReportAPI.QUERY.URL] = sURL;\n dataPost[ReportAPI.QUERY.USER] = sUser;\n dataPost[ReportAPI.QUERY.TYPE] = sType;\n dataPost[ReportAPI.QUERY.DATA] = sReport;\n var sReportURL = (sHostName? sHostName : \"http://\" + SITEHOST) + ReportAPI.ENDPOINT;\n Web.getResource(sReportURL, dataPost, true);\n }\n\n /**\n * getHost()\n *\n * @return {string}\n */\n static getHost()\n {\n return (\"http://\" + (window? window.location.host : SITEHOST));\n }\n\n /**\n * getHostURL()\n *\n * @return {string|null}\n */\n static getHostURL()\n {\n return (window? window.location.href : null);\n }\n\n /**\n * getHostProtocol()\n *\n * @return {string}\n */\n static getHostProtocol()\n {\n return (window? window.location.protocol : \"file:\");\n }\n\n /**\n * getUserAgent()\n *\n * @return {string}\n */\n static getUserAgent()\n {\n return (window? window.navigator.userAgent : \"\");\n }\n\n /**\n * hasLocalStorage\n *\n * true if localStorage support exists, is enabled, and works; false otherwise\n *\n * @return {boolean}\n */\n static hasLocalStorage()\n {\n if (Web.fLocalStorage == null) {\n var f = false;\n if (window) {\n try {\n window.localStorage.setItem(Web.sLocalStorageTest, Web.sLocalStorageTest);\n f = (window.localStorage.getItem(Web.sLocalStorageTest) == Web.sLocalStorageTest);\n window.localStorage.removeItem(Web.sLocalStorageTest);\n } catch (e) {\n Web.logLocalStorageError(e);\n f = false;\n }\n }\n Web.fLocalStorage = f;\n }\n return Web.fLocalStorage;\n }\n\n /**\n * logLocalStorageError(e)\n *\n * @param {Error} e is an exception\n */\n static logLocalStorageError(e)\n {\n Web.log(e.message, \"localStorage error\");\n }\n\n /**\n * getLocalStorageItem(sKey)\n *\n * Returns the requested key value, or null if the key does not exist, or undefined if localStorage is not available\n *\n * @param {string} sKey\n * @return {string|null|undefined} sValue\n */\n static getLocalStorageItem(sKey)\n {\n var sValue;\n if (window) {\n try {\n sValue = window.localStorage.getItem(sKey);\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n }\n return sValue;\n }\n\n /**\n * setLocalStorageItem(sKey, sValue)\n *\n * @param {string} sKey\n * @param {string} sValue\n * @return {boolean} true if localStorage is available, false if not\n */\n static setLocalStorageItem(sKey, sValue)\n {\n try {\n window.localStorage.setItem(sKey, sValue);\n return true;\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n return false;\n }\n\n /**\n * removeLocalStorageItem(sKey)\n *\n * @param {string} sKey\n */\n static removeLocalStorageItem(sKey)\n {\n try {\n window.localStorage.removeItem(sKey);\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n }\n\n /**\n * getLocalStorageKeys()\n *\n * @return {Array}\n */\n static getLocalStorageKeys()\n {\n var a = [];\n try {\n for (var i = 0, c = window.localStorage.length; i < c; i++) {\n a.push(window.localStorage.key(i));\n }\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n return a;\n }\n\n /**\n * reloadPage()\n */\n static reloadPage()\n {\n if (window) window.location.reload();\n }\n\n /**\n * isUserAgent(s)\n *\n * Check the browser's user-agent string for the given substring; \"iOS\" and \"MSIE\" are special values you can\n * use that will match any iOS or MSIE browser, respectively (even IE11, in the case of \"MSIE\").\n *\n * 2013-11-06: In a questionable move, MSFT changed the user-agent reported by IE11 on Windows 8.1, eliminating\n * the \"MSIE\" string (which MSDN calls a \"version token\"; see http://msdn.microsoft.com/library/ms537503.aspx);\n * they say \"public websites should rely on feature detection, rather than browser detection, in order to design\n * their sites for browsers that don't support the features used by the website.\" So, in IE11, we get a user-agent\n * that tries to fool apps into thinking the browser is more like WebKit or Gecko:\n *\n * Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko\n *\n * That's a nice idea, but in the meantime, they hosed the XSL transform code in embed.js, which contained\n * some very critical browser-specific code; turning on IE's \"Compatibility Mode\" didn't help either, because\n * that's a sledgehammer solution which restores the old user-agent string but also disables other features like\n * HTML5 canvas support. As an interim solution, I'm treating any \"MSIE\" check as a check for either \"MSIE\" or\n * \"Trident\".\n *\n * UPDATE: I've since found ways to make the code in embed.js more browser-agnostic, so for now, there's isn't\n * any code that cares about \"MSIE\", but I've left the change in place, because I wouldn't be surprised if I'll\n * need more IE-specific code in the future, perhaps for things like copy/paste functionality, or mouse capture.\n *\n * @param {string} s is a substring to search for in the user-agent; as noted above, \"iOS\" and \"MSIE\" are special values\n * @return {boolean} is true if the string was found, false if not\n */\n static isUserAgent(s)\n {\n if (window) {\n var userAgent = Web.getUserAgent();\n /*\n * Here's one case where we have to be careful with Component, because when isUserAgent() is called by\n * the init code below, component.js hasn't been loaded yet. The simple solution for now is to remove the call.\n *\n * Web.log(\"agent: \" + userAgent);\n *\n * And yes, it would be pointless to use the conditional (?) operator below, if not for the Google Closure\n * Compiler (v20130823) failing to detect the entire expression as a boolean.\n */\n return s == \"iOS\" && !!userAgent.match(/(iPod|iPhone|iPad)/) && !!userAgent.match(/AppleWebKit/) || s == \"MSIE\" && !!userAgent.match(/(MSIE|Trident)/) || (userAgent.indexOf(s) >= 0);\n }\n return false;\n }\n\n /**\n * isMobile(sDevice)\n *\n * Checks the URL for a \"mobile\" parameter, and failing that, checks the browser's user-agent string for the\n * substring \"Mobi\", as per Mozilla recommendation:\n *\n * https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent\n *\n * @param {string} [sDevice] (eg, \"iPad\" to check for iPad, or \"!iPad\" to specifically exclude it) \n * @return {boolean} is true if the browser appears to be a mobile (ie, non-desktop) web browser, false if not\n */\n static isMobile(sDevice)\n {\n var sMobile = Web.getURLParm(\"mobile\");\n if (sMobile) return sMobile == \"true\";\n if (Web.isUserAgent(\"Mobi\")) {\n if (!sDevice) return true;\n var fInvert = sDevice[0] == '!';\n if (fInvert) sDevice = sDevice.substr(1);\n return Web.isUserAgent(sDevice) != fInvert;\n }\n return false;\n }\n\n /**\n * findProperty(obj, sProp, sSuffix)\n *\n * If both sProp and sSuffix are set, then any browser-specific prefixes are inserted between sProp and sSuffix,\n * and if a match is found, it is returned without sProp.\n *\n * For example, if findProperty(document, 'on', 'fullscreenchange') discovers that 'onwebkitfullscreenchange' exists,\n * it will return 'webkitfullscreenchange', in preparation for an addEventListener() call.\n *\n * More commonly, sSuffix is not used, so whatever property is found is returned as-is.\n *\n * @param {Object|null|undefined} obj\n * @param {string} sProp\n * @param {string} [sSuffix]\n * @return {string|null}\n */\n static findProperty(obj, sProp, sSuffix)\n {\n if (obj) {\n for (var i = 0; i < Web.asBrowserPrefixes.length; i++) {\n var sName = Web.asBrowserPrefixes[i];\n if (sSuffix) {\n sName += sSuffix;\n var sEvent = sProp + sName;\n if (sEvent in obj) return sName;\n } else {\n if (!sName) {\n sName = sProp[0];\n } else {\n sName += sProp[0].toUpperCase();\n }\n sName += sProp.substr(1);\n if (sName in obj) return sName;\n }\n }\n }\n return null;\n }\n\n /**\n * getURLParm(sParm)\n *\n * First looks for sParm exactly as specified, then looks for the lower-case version.\n *\n * @param {string} sParm\n * @return {string|undefined}\n */\n static getURLParm(sParm)\n {\n if (!Web.parmsURL) {\n Web.parmsURL = Web.parseURLParms();\n }\n return Web.parmsURL[sParm] || Web.parmsURL[sParm.toLowerCase()];\n }\n\n /**\n * parseURLParms(sParms)\n *\n * @param {string} [sParms] containing the parameter portion of a URL (ie, after the '?')\n * @return {Object} containing properties for each parameter found\n */\n static parseURLParms(sParms)\n {\n var aParms = {};\n if (window) { // an alternative to \"if (typeof module === 'undefined')\" if require(\"defines\") was used\n if (!sParms) {\n /*\n * Note that window.location.href returns the entire URL, whereas window.location.search\n * returns only the parameters, if any (starting with the '?', which we skip over with a substr() call).\n */\n sParms = window.location.search.substr(1);\n }\n var match;\n var pl = /\\+/g; // RegExp for replacing addition symbol with a space\n var search = /([^&=]+)=?([^&]*)/g;\n var decode = function(s)\n {\n return decodeURIComponent(s.replace(pl, \" \"));\n };\n\n while ((match = search.exec(sParms))) {\n aParms[decode(match[1])] = decode(match[2]);\n }\n }\n return aParms;\n }\n\n /**\n * downloadFile(sData, sType, fBase64, sFileName)\n *\n * @param {string} sData\n * @param {string} sType\n * @param {boolean} [fBase64]\n * @param {string} [sFileName]\n */\n static downloadFile(sData, sType, fBase64, sFileName)\n {\n var link = null, sAlert;\n var sURI = \"data:application/\" + sType + (fBase64? \";base64\" : \"\") + \",\";\n\n if (!Web.isUserAgent(\"Firefox\")) {\n sURI += (fBase64? sData : encodeURI(sData));\n } else {\n sURI += (fBase64? sData : encodeURIComponent(sData));\n }\n if (sFileName) {\n link = document.createElement('a');\n if (typeof link.download != 'string') link = null;\n }\n if (link) {\n link.href = sURI;\n link.download = sFileName;\n document.body.appendChild(link); // Firefox allegedly requires the link to be in the body\n link.click();\n document.body.removeChild(link);\n sAlert = 'Check your Downloads folder for ' + sFileName + '.';\n if (Web.isUserAgent(\"Chrome\")) {\n sAlert += '\\n\\nIn Chrome, after clicking OK, you may ALSO have to select the \"Window\" menu, choose \"Downloads\", and then locate this download and select \"Keep\".';\n sAlert += '\\n\\nThis is part of Chrome\\'s \"Security By Jumping Through Extra Hoops\" technology, which is much easier for Google to implement than actually checking for something malicious.';\n sAlert += '\\n\\nAnd for the record, there is nothing malicious on the PCjs website.';\n }\n } else {\n window.open(sURI);\n sAlert = 'Check your browser for a new window/tab containing the requested data' + (sFileName? (' (' + sFileName + ')') : '') + '.';\n }\n return sAlert;\n }\n\n /**\n * onCountRepeat(n, fnRepeat, fnComplete, msDelay)\n *\n * Call fnRepeat() n times with an msDelay millisecond delay between calls,\n * then call fnComplete() when n has been exhausted OR fnRepeat() returns false.\n *\n * @param {number} n\n * @param {function()} fnRepeat\n * @param {function()} fnComplete\n * @param {number} [msDelay]\n */\n static onCountRepeat(n, fnRepeat, fnComplete, msDelay)\n {\n var fnTimeout = function doCountRepeat()\n {\n n -= 1;\n if (n >= 0) {\n if (!fnRepeat()) n = 0;\n }\n if (n > 0) {\n setTimeout(fnTimeout, msDelay || 0);\n return;\n }\n fnComplete();\n };\n fnTimeout();\n }\n\n /**\n * onClickRepeat(e, msDelay, msRepeat, fn)\n *\n * Repeatedly call fn() with an initial msDelay, and an msRepeat delay thereafter,\n * as long as HTML control Object e has an active \"down\" event and fn() returns true.\n *\n * @param {Object} e\n * @param {number} msDelay\n * @param {number} msRepeat\n * @param {function(boolean)} fn is passed false on the first call, true on all repeated calls\n */\n static onClickRepeat(e, msDelay, msRepeat, fn)\n {\n var ms = 0, timer = null, fIgnoreMouseEvents = false;\n\n var fnRepeat = function doClickRepeat()\n {\n if (fn(ms === msRepeat)) {\n timer = setTimeout(fnRepeat, ms);\n ms = msRepeat;\n }\n };\n e.onmousedown = function()\n {\n // Web.log(\"onMouseDown()\");\n if (!fIgnoreMouseEvents) {\n if (!timer) {\n ms = msDelay;\n fnRepeat();\n }\n }\n };\n e.ontouchstart = function()\n {\n // Web.log(\"onTouchStart()\");\n if (!timer) {\n ms = msDelay;\n fnRepeat();\n }\n };\n e.onmouseup = e.onmouseout = function()\n {\n // Web.log(\"onMouseUp()/onMouseOut()\");\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n };\n e.ontouchend = e.ontouchcancel = function()\n {\n // Web.log(\"onTouchEnd()/onTouchCancel()\");\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n /*\n * Devices that generate ontouch* events ALSO generate onmouse* events,\n * and generally do so immediately after all the touch events are complete,\n * so unless we want double the action, we need to ignore mouse events.\n */\n fIgnoreMouseEvents = true;\n };\n }\n\n /**\n * onPageEvent(sName, fn)\n *\n * For 'onload', 'onunload', and 'onpageshow' events, most callers should NOT use this function, but\n * instead use Web.onInit(), Web.onShow(), and Web.onExit(), respectively.\n *\n * The only components that should still use onPageEvent() are THIS component (see the bottom of this file)\n * and components that need to capture other events (eg, the 'onresize' event in the Video component).\n *\n * This function creates a chain of callbacks, allowing multiple JavaScript modules to define handlers\n * for the same event, which wouldn't be possible if everyone modified window['onload'], window['onunload'],\n * etc, themselves. However, that's less of a concern now, because assuming everyone else is now using\n * onInit(), onExit(), etc, then there really IS only one component setting the window callback: this one.\n *\n * NOTE: It's risky to refer to obscure event handlers with \"dot\" names, because the Closure Compiler may\n * erroneously replace them (eg, window.onpageshow is a good example).\n *\n * @param {string} sFunc\n * @param {function()} fn\n */\n static onPageEvent(sFunc, fn)\n {\n if (window) {\n var fnPrev = window[sFunc];\n if (typeof fnPrev !== 'function') {\n window[sFunc] = fn;\n } else {\n /*\n * TODO: Determine whether there's any value in receiving/sending the Event object that the\n * browser provides when it generates the original event.\n */\n window[sFunc] = function onWindowEvent()\n {\n if (fnPrev) fnPrev();\n fn();\n };\n }\n }\n };\n\n /**\n * onInit(fn)\n *\n * Use this instead of setting window.onload. Allows multiple JavaScript modules to define their own 'onload' event handler.\n *\n * @param {function()} fn\n */\n static onInit(fn)\n {\n Web.aPageEventHandlers['init'].push(fn);\n };\n\n /**\n * onShow(fn)\n *\n * @param {function()} fn\n *\n * Use this instead of setting window.onpageshow. Allows multiple JavaScript modules to define their own 'onpageshow' event handler.\n */\n static onShow(fn)\n {\n Web.aPageEventHandlers['show'].push(fn);\n };\n\n /**\n * onExit(fn)\n *\n * @param {function()} fn\n *\n * Use this instead of setting window.onunload. Allows multiple JavaScript modules to define their own 'onunload' event handler.\n */\n static onExit(fn)\n {\n Web.aPageEventHandlers['exit'].push(fn);\n };\n\n /**\n * doPageEvent(afn)\n *\n * @param {Array.<function()>} afn\n */\n static doPageEvent(afn)\n {\n if (Web.fPageEventsEnabled) {\n try {\n for (var i = 0; i < afn.length; i++) {\n afn[i]();\n }\n } catch (e) {\n Web.notice(\"An unexpected error occurred: \" + e.message + \"\\n\\nIf it happens again, please send this information to support@pcjs.org. Thanks.\");\n }\n }\n };\n\n /**\n * enablePageEvents(fEnable)\n *\n * @param {boolean} fEnable is true to enable page events, false to disable (they're enabled by default)\n */\n static enablePageEvents(fEnable)\n {\n if (!Web.fPageEventsEnabled && fEnable) {\n Web.fPageEventsEnabled = true;\n if (Web.fPageLoaded) Web.sendPageEvent('init');\n if (Web.fPageShowed) Web.sendPageEvent('show');\n return;\n }\n Web.fPageEventsEnabled = fEnable;\n }\n\n /**\n * sendPageEvent(sEvent)\n *\n * This allows us to manually trigger page events.\n *\n * @param {string} sEvent (one of 'init', 'show' or 'exit')\n */\n static sendPageEvent(sEvent)\n {\n if (Web.aPageEventHandlers[sEvent]) {\n Web.doPageEvent(Web.aPageEventHandlers[sEvent]);\n }\n }\n}\n\nWeb.parmsURL = null; // initialized on first call to parseURLParms()\n\nWeb.aPageEventHandlers = {\n 'init': [], // list of window 'onload' handlers\n 'show': [], // list of window 'onpageshow' handlers\n 'exit': [] // list of window 'onunload' handlers (although we prefer to use 'onbeforeunload' if possible)\n};\n\nWeb.asBrowserPrefixes = ['', 'moz', 'ms', 'webkit'];\n\nWeb.fPageLoaded = false; // set once the page's first 'onload' event has occurred\nWeb.fPageShowed = false; // set once the page's first 'onpageshow' event has occurred\nWeb.fPageEventsEnabled = true; // default is true, set to false (or true) by enablePageEvents()\n\n/**\n * fLocalStorage\n *\n * true if localStorage support exists, is enabled, and works; \"falsey\" otherwise\n *\n * @type {boolean|null}\n */\nWeb.fLocalStorage = null;\n\n/**\n * TODO: Is there any way to get the Closure Compiler to stop inlining this string? This isn't cutting it.\n *\n * @const {string}\n */\nWeb.sLocalStorageTest = \"PCjs.localStorage\";\n\nWeb.onPageEvent('onload', function onPageLoad() {\n Web.fPageLoaded = true;\n Web.doPageEvent(Web.aPageEventHandlers['init']);\n});\n\nWeb.onPageEvent('onpageshow', function onPageShow() {\n Web.fPageShowed = true;\n Web.doPageEvent(Web.aPageEventHandlers['show']);\n});\n\nWeb.onPageEvent(Web.isUserAgent(\"iOS\")? 'onpagehide' : (Web.isUserAgent(\"Opera\")? 'onunload' : 'onbeforeunload'), function onPageUnload() {\n Web.doPageEvent(Web.aPageEventHandlers['exit']);\n});\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/component.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * All PCjs components now use JSDoc types, primarily so that Google's Closure Compiler will compile\n * everything with zero warnings when ADVANCED_OPTIMIZATIONS are enabled. For more information about\n * the JSDoc types supported by the Closure Compiler:\n *\n * https://developers.google.com/closure/compiler/docs/js-for-compiler#types\n *\n * I also attempted to validate this code with JSLint, but it complained too much; eg, it didn't like\n * \"while (true)\", a tried and \"true\" programming convention for decades, and it wanted me to replace\n * all \"++\" and \"--\" operators with \"+= 1\" and \"-= 1\", use \"(s || '')\" instead of \"(s? s : '')\", etc.\n *\n * I prefer sticking with traditional C-style idioms, in part because they are more portable. That\n * does NOT mean I'm trying to write \"portable JavaScript,\" but some of this code was ported from C code\n * I'd written long ago, so portability is good, and I'm not going to throw that away if there's no need.\n *\n * UPDATE: I've since switched from JSLint to JSHint, which seems to have more reasonable defaults.\n * And for new code, I have adopted some popular JavaScript idioms, like \"(s || '')\", although the need\n * for those kinds of expressions will be reduced as I also start adopting some ES6 features, like\n * default parameters.\n */\n\n\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * subclass (eg, SerialPort), because otherwise the Compiler won't allow us to *reference*\n * the named property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass Component {\n /**\n * Component(type, parms, bitsMessage)\n *\n * A Component object requires:\n *\n * type: a user-defined type name (eg, \"CPU\")\n *\n * and accepts any or all of the following (parms) properties:\n *\n * id: component ID (default is \"\")\n * name: component name (default is \"\"; if blank, toString() will use the type name only)\n * comment: component comment string (default is undefined)\n *\n * Component subclasses will usually have additional (parms) properties.\n *\n * @param {string} type\n * @param {Object} [parms]\n * @param {number} [bitsMessage] selects message(s) that the component wants to enable (default is 0)\n */\n constructor(type, parms, bitsMessage)\n {\n this.type = type;\n\n if (!parms) parms = {'id': \"\", 'name': \"\"};\n\n this.id = parms['id'] || \"\";\n this.name = parms['name'];\n this.comment = parms['comment'];\n this.parms = parms;\n\n /*\n * The following Component properties need to be accessible by other machines and/or command scripts;\n * well, OK, or we could have exported some new functions to walk the contents of these properties, as we\n * did with findMachineComponent(), but this works just as well.\n *\n * Also, while the double-assignment looks silly (ie, using both dot and bracket property notation), it\n * resolves a complaint from the Closure Compiler, because if we use ONLY bracket notation here, then the\n * Compiler wants us to change all the other references to bracket notation as well.\n */\n this.exports = this['exports'] = {};\n this.bindings = this['bindings'] = {};\n\n var i = this.id.indexOf('.');\n if (i < 0) {\n this.idComponent = this.id;\n } else {\n this.idMachine = this.id.substr(0, i);\n this.idComponent = this.id.substr(i + 1);\n }\n\n /*\n * Gather all the various component flags (booleans) into a single \"flags\" object, and encourage\n * subclasses to do the same, to reduce the property clutter we have to wade through while debugging.\n */\n this.flags = {\n ready: false,\n busy: false,\n busyCancel: false,\n initDone: false,\n powered: false,\n unloading: false,\n error: false\n };\n\n this.fnReady = null;\n this.clearError();\n this.bitsMessage = bitsMessage || 0;\n\n this.cmp = null;\n this.bus = null;\n this.cpu = null;\n this.dbg = null;\n\n /*\n * TODO: Consider adding another parameter to the Component() constructor that allows components to tell\n * us if they support single or multiple instances per machine. For example, there can be multiple SerialPort\n * components per machine, but only one CPU component (some machines also support an FPU, but that component\n * is considered separate from the CPU).\n *\n * It's not critical, but it would help catch machine configuration errors; for example, a machine that mistakenly\n * includes two CPU components may, aside from wasting memory, end up with odd side-effects, like unresponsive\n * CPU controls.\n */\n Component.add(this);\n }\n\n /**\n * Component.add(component)\n *\n * @param {Component} component\n */\n static add(component)\n {\n /*\n * This just generates a lot of useless noise, handy in the early days, not so much these days....\n *\n * if (DEBUG) Component.log(\"Component.add(\" + component.type + \",\" + component.id + \")\");\n */\n Component.components.push(component);\n }\n\n /**\n * Component.addMachine(idMachine)\n *\n * @param {string} idMachine\n */\n static addMachine(idMachine)\n {\n Component.machines[idMachine] = {};\n }\n\n /**\n * Component.addMachineResource(idMachine, sName, data)\n *\n * @param {string} idMachine\n * @param {string|null} sName (name of the resource)\n * @param {*} data\n */\n static addMachineResource(idMachine, sName, data)\n {\n /*\n * I used to assert(Component.machines[idMachine]), but when we're running as a Node app, embed.js is not used,\n * so addMachine() is never called, so resources do not need to be recorded.\n */\n if (Component.machines[idMachine] && sName) {\n Component.machines[idMachine][sName] = data;\n }\n }\n\n /**\n * Component.getMachineResources(idMachine)\n *\n * @param {string} idMachine\n * @return {Object|undefined}\n */\n static getMachineResources(idMachine)\n {\n return Component.machines[idMachine];\n }\n\n /**\n * Component.getTime()\n *\n * @return {number} the current time, in milliseconds\n */\n static getTime()\n {\n return Date.now() || +new Date();\n }\n\n /**\n * Component.log(s, type)\n *\n * For diagnostic output only.\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n static log(s, type)\n {\n if (!COMPILED) {\n if (s) {\n var sElapsed = \"\", sMsg = (type? (type + \": \") : \"\") + s;\n if (typeof Usr != \"undefined\") {\n if (Component.msStart === undefined) {\n Component.msStart = Component.getTime();\n }\n sElapsed = (Component.getTime() - Component.msStart) + \"ms: \";\n }\n sMsg = sMsg.replace(/\\r/g, '\\\\r').replace(/\\n/g, ' ');\n if (window && window.console) console.log(sElapsed + sMsg);\n }\n }\n }\n\n /**\n * Component.assert(f, s)\n *\n * Verifies conditions that must be true (for DEBUG builds only).\n *\n * The Closure Compiler should automatically remove all references to Component.assert() in non-DEBUG builds.\n * TODO: Add a task to the build process that \"asserts\" there are no instances of \"assertion failure\" in RELEASE builds.\n *\n * @param {boolean} f is the expression we are asserting to be true\n * @param {string} [s] is description of the assertion on failure\n */\n static assert(f, s)\n {\n if (DEBUG) {\n if (!f) {\n if (!s) s = \"assertion failure\";\n Component.log(s);\n throw new Error(s);\n }\n }\n }\n\n /**\n * Component.print(s)\n *\n * Components that inherit from this class should use this.print(), rather than Component.print(), because\n * if a Control Panel is loaded, it will override only the instance method, not the class method (overriding the\n * class method would improperly affect any other machines loaded on the same page).\n *\n * @this {Component}\n * @param {string} s\n */\n static print(s)\n {\n if (!COMPILED) {\n var i = s.lastIndexOf('\\n');\n if (i >= 0) {\n Component.println(s.substr(0, i));\n s = s.substr(i + 1);\n }\n Component.printBuffer += s;\n }\n }\n\n /**\n * Component.println(s, type, id)\n *\n * Components that inherit from this class should use this.println(), rather than Component.println(), because\n * if a Control Panel is loaded, it will override only the instance method, not the class method (overriding the\n * class method would improperly affect any other machines loaded on the same page).\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n * @param {string} [id] is the caller's ID, if any\n */\n static println(s, type, id)\n {\n if (!COMPILED) {\n s = Component.printBuffer + (s || \"\");\n Component.log((id? (id + \": \") : \"\") + (s? (\"\\\"\" + s + \"\\\"\") : \"\"), type);\n Component.printBuffer = \"\";\n }\n }\n\n /**\n * Component.notice(s, fPrintOnly, id)\n *\n * notice() is like println() but implies a need for user notification, so we alert() as well.\n *\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n * @return {boolean}\n */\n static notice(s, fPrintOnly, id)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.NOTICE, id);\n }\n if (!fPrintOnly) Component.alertUser((id? (id + \": \") : \"\") + s);\n return true;\n }\n\n /**\n * Component.warning(s)\n *\n * @param {string} s describes the warning\n */\n static warning(s)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.WARNING);\n }\n Component.alertUser(s);\n }\n\n /**\n * Component.error(s)\n *\n * @param {string} s describes the error; an alert() is displayed as well\n */\n static error(s)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.ERROR);\n }\n Component.alertUser(s);\n }\n\n /**\n * Component.alertUser(sMessage)\n *\n * @param {string} sMessage\n */\n static alertUser(sMessage)\n {\n if (window) {\n window.alert(sMessage);\n } else {\n Component.log(sMessage);\n }\n }\n\n /**\n * Component.confirmUser(sPrompt)\n *\n * @param {string} sPrompt\n * @returns {boolean} true if the user clicked OK, false if Cancel/Close\n */\n static confirmUser(sPrompt)\n {\n var fResponse = false;\n if (window) {\n fResponse = window.confirm(sPrompt);\n }\n return fResponse;\n }\n\n /**\n * Component.promptUser()\n *\n * @param {string} sPrompt\n * @param {string} [sDefault]\n * @returns {string|null}\n */\n static promptUser(sPrompt, sDefault)\n {\n var sResponse = null;\n if (window) {\n sResponse = window.prompt(sPrompt, sDefault === undefined? \"\" : sDefault);\n }\n return sResponse;\n }\n\n /**\n * Component.appendControl(control, sText)\n *\n * @param {Object} control\n * @param {string} sText\n */\n static appendControl(control, sText)\n {\n control.value += sText;\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (COMPILED) {\n sText = control.value;\n if (sText.length > 8192) control.value = sText.substr(sText.length - 4096);\n }\n control.scrollTop = control.scrollHeight;\n }\n\n /**\n * Component.replaceControl(control, sSearch, sReplace)\n *\n * @param {Object} control\n * @param {string} sSearch\n * @param {string} sReplace\n */\n static replaceControl(control, sSearch, sReplace)\n {\n var sText = control.value;\n var i = sText.lastIndexOf(sSearch);\n if (i < 0) {\n sText += sSearch + '\\n';\n } else {\n sText = sText.substr(0, i) + sReplace + sText.substr(i + sSearch.length);\n }\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (COMPILED && sText.length > 8192) sText = sText.substr(sText.length - 4096);\n control.value = sText;\n control.scrollTop = control.scrollHeight;\n }\n\n /**\n * Component.bindExternalControl(component, sBinding, sType)\n *\n * @param {Component} component\n * @param {string} sBinding\n * @param {string} [sType] is the external component type (default is \"Panel\")\n */\n static bindExternalControl(component, sBinding, sType = \"Panel\")\n {\n if (sBinding) {\n var target = Component.getComponentByType(sType, component.id);\n if (target) {\n var control = target.bindings[sBinding];\n if (control) {\n component.setBinding(\"\", sBinding, control);\n }\n }\n }\n }\n\n /**\n * Component.bindComponentControls(component, element, sAppClass)\n *\n * @param {Component} component\n * @param {HTMLElement} element from the DOM\n * @param {string} sAppClass\n */\n static bindComponentControls(component, element, sAppClass)\n {\n var aeControls = Component.getElementsByClass(element.parentNode, sAppClass + \"-control\");\n\n for (var iControl = 0; iControl < aeControls.length; iControl++) {\n\n var aeChildNodes = aeControls[iControl].childNodes;\n\n for (var iNode = 0; iNode < aeChildNodes.length; iNode++) {\n var control = aeChildNodes[iNode];\n if (control.nodeType !== 1 /* document.ELEMENT_NODE */) {\n continue;\n }\n var sClass = control.getAttribute(\"class\");\n if (!sClass) continue;\n var aClasses = sClass.split(\" \");\n for (var iClass = 0; iClass < aClasses.length; iClass++) {\n var parms;\n sClass = aClasses[iClass];\n switch (sClass) {\n case sAppClass + \"-binding\":\n parms = Component.getComponentParms(/** @type {HTMLElement} */(control));\n if (parms && parms['binding'] !== undefined) {\n component.setBinding(parms['type'], parms['binding'], /** @type {HTMLElement} */(control), parms['value']);\n } else if (!parms || parms['type'] != \"description\") {\n Component.log(\"Component '\" + component.toString() + \"' missing binding\" + (parms? \" for \" + parms['type'] : \"\"), \"warning\");\n }\n iClass = aClasses.length;\n break;\n default:\n // if (DEBUG) Component.log(\"Component.bindComponentControls(\" + component.toString() + \"): unrecognized control class \\\"\" + sClass + \"\\\"\", \"warning\");\n break;\n }\n }\n }\n }\n }\n\n /**\n * Component.getComponents(idRelated)\n *\n * We could store components as properties, using the component's ID, and change\n * this linear lookup into a property lookup, but some components may have no ID.\n *\n * @param {string} [idRelated] of related component\n * @return {Array} of components\n */\n static getComponents(idRelated)\n {\n var i;\n var aComponents = [];\n /*\n * getComponentByID(id, idRelated)\n *\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated) {\n if ((i = idRelated.indexOf('.')) > 0)\n idRelated = idRelated.substr(0, i + 1);\n else\n idRelated = \"\";\n }\n for (i = 0; i < Component.components.length; i++) {\n var component = Component.components[i];\n if (!idRelated || !component.id.indexOf(idRelated)) {\n aComponents.push(component);\n }\n }\n return aComponents;\n }\n\n /**\n * Component.getComponentByID(id, idRelated)\n *\n * We could store components as properties, using the component's ID, and change\n * this linear lookup into a property lookup, but some components may have no ID.\n *\n * @param {string} id of the desired component\n * @param {string} [idRelated] of related component\n * @return {Component|null}\n */\n static getComponentByID(id, idRelated)\n {\n if (id !== undefined) {\n var i;\n /*\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated && (i = idRelated.indexOf('.')) > 0) {\n id = idRelated.substr(0, i + 1) + id;\n }\n for (i = 0; i < Component.components.length; i++) {\n if (Component.components[i].id === id) {\n return Component.components[i];\n }\n }\n if (Component.components.length) {\n Component.log(\"Component ID '\" + id + \"' not found\", \"warning\");\n }\n }\n return null;\n }\n\n /**\n * Component.getComponentByType(sType, idRelated, componentPrev)\n *\n * @param {string} sType of the desired component\n * @param {string} [idRelated] of related component\n * @param {Component|null} [componentPrev] of previously returned component, if any\n * @return {Component|null}\n */\n static getComponentByType(sType, idRelated, componentPrev)\n {\n if (sType !== undefined) {\n var i;\n /*\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated) {\n if ((i = idRelated.indexOf('.')) > 0) {\n idRelated = idRelated.substr(0, i + 1);\n } else {\n idRelated = \"\";\n }\n }\n for (i = 0; i < Component.components.length; i++) {\n if (componentPrev) {\n if (componentPrev == Component.components[i]) componentPrev = null;\n continue;\n }\n if (sType == Component.components[i].type && (!idRelated || !Component.components[i].id.indexOf(idRelated))) {\n return Component.components[i];\n }\n }\n Component.log(\"Component type '\" + sType + \"' not found\", \"warning\");\n }\n return null;\n }\n\n /**\n * Component.getComponentParms(element)\n *\n * @param {HTMLElement} element from the DOM\n */\n static getComponentParms(element)\n {\n var parms = null;\n var sParms = element.getAttribute(\"data-value\");\n if (sParms) {\n try {\n parms = eval('(' + sParms + ')'); // jshint ignore:line\n /*\n * We can no longer invoke removeAttribute() because some components (eg, Panel) need\n * to run their initXXX() code more than once, to avoid initialization-order dependencies.\n *\n * if (!DEBUG) {\n * element.removeAttribute(\"data-value\");\n * }\n */\n } catch(e) {\n Component.error(e.message + \" (\" + sParms + \")\");\n }\n }\n return parms;\n }\n\n /**\n * Component.getElementsByClass(element, sClass, sObjClass)\n *\n * This is a cross-browser helper function, since not all browser's support getElementsByClassName()\n *\n * TODO: This should probably be moved into weblib.js at some point, along with the control binding functions above,\n * to keep all the browser-related code together.\n *\n * @param {HTMLDocument|HTMLElement|Node} element from the DOM\n * @param {string} sClass\n * @param {string} [sObjClass]\n * @return {Array|NodeList}\n */\n static getElementsByClass(element, sClass, sObjClass)\n {\n if (sObjClass) sClass += '-' + sObjClass + \"-object\";\n /*\n * Use the browser's built-in getElementsByClassName() if it appears to be available\n * (for example, it's not available in IE8, but it should be available in IE9 and up)\n */\n if (element.getElementsByClassName) {\n return element.getElementsByClassName(sClass);\n }\n var i, j, ae = [];\n var aeAll = element.getElementsByTagName(\"*\");\n var re = new RegExp('(^| )' + sClass + '( |$)');\n for (i = 0, j = aeAll.length; i < j; i++) {\n if (re.test(aeAll[i].className)) {\n ae.push(aeAll[i]);\n }\n }\n if (!ae.length) {\n Component.log('No elements of class \"' + sClass + '\" found');\n }\n return ae;\n }\n\n /**\n * Component.getScriptCommands(sScript)\n *\n * This is a simple parser that breaks sScript into an array of commands, where each command\n * is an array of tokens, where tokens are sequences of characters separated by any of: tab, space,\n * carriage-return (CR), line-feed (LF), semicolon, single-quote, or double-quote; if a quote is\n * used, all characters up to the next matching quote become part of the token, allowing any of the\n * other separators to be part of the token. CR, LF and semicolon also serve to terminate a command,\n * with semicolon being preferred, because it's 1) more visible, and 2) essential when the entire\n * script is a multi-line string where all CR/LF were replaced by spaces (which is what Jekyll does,\n * and since we can't change Jekyll, it's what our own MarkDown Front Matter parser does as well;\n * see convertMD() in markout.js, where the aCommandDefs array is built).\n *\n * Backslash sequences like \\n, \\r, and \\\\ have already been converted to LF, CR and backslash\n * characters, since the entire script string is injected into a JavaScript function call, so any\n * backslash sequence that JavaScript supports is automatically converted:\n *\n * \\0 \\' \\\" \\\\ \\n \\r \\v \\t \\b \\f \\uXXXX \\xXX\n * ^J ^M ^K ^I ^H ^L\n *\n * To support any other non-printable 8-bit character, such as ESC, you should use \\xXX, where XX\n * is the ASCII code in hex. For ESC, that would be \\x1B.\n *\n * @param {string} sScript\n * @return {Array}\n */\n static getScriptCommands(sScript)\n {\n var cch = sScript.length;\n var aCommands = [], aTokens = [], sToken = \"\", chQuote = null;\n for (var i = 0; i < cch; i++) {\n var ch = sScript[i];\n if (ch == '\"' || ch == \"'\") {\n if (chQuote && ch != chQuote) {\n sToken += ch;\n continue;\n }\n if (!chQuote) {\n chQuote = ch;\n } else {\n chQuote = null;\n }\n if (sToken) {\n aTokens.push(sToken);\n sToken = \"\";\n }\n continue;\n }\n if (!chQuote) {\n if (ch == '\\r' || ch == '\\n') {\n ch = ';';\n }\n if (ch == ' ' || ch == '\\t' || ch == ';') {\n if (sToken) {\n aTokens.push(sToken);\n sToken = \"\";\n }\n if (ch == ';' && aTokens.length) {\n aCommands.push(aTokens);\n aTokens = [];\n }\n continue;\n }\n }\n sToken += ch;\n }\n if (sToken) {\n aTokens.push(sToken);\n }\n if (aTokens.length) {\n aCommands.push(aTokens);\n }\n return aCommands;\n }\n\n /**\n * Component.processScript(idMachine, sScript)\n *\n * @param {string} idMachine\n * @param {string} [sScript]\n * @return {boolean}\n */\n static processScript(idMachine, sScript)\n {\n var fSuccess = false;\n idMachine += \".machine\";\n if (!sScript) {\n delete Component.commands[idMachine];\n fSuccess = true;\n }\n else if (typeof sScript == \"string\" && !Component.commands[idMachine]) {\n fSuccess = true;\n Component.commands[idMachine] = Component.getScriptCommands(sScript);\n if (!Component.processCommands(idMachine)) {\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * Component.processCommands(idMachine)\n *\n * @param {string} idMachine\n * @return {boolean}\n */\n static processCommands(idMachine)\n {\n var fSuccess = true;\n var aCommands = Component.commands[idMachine];\n\n // var dbg = Component.getComponentByType(\"Debugger\", idMachine);\n\n while (aCommands && aCommands.length) {\n\n var aTokens = aCommands.splice(0, 1)[0];\n var sCommand = aTokens[0];\n\n /*\n * It's possible to route this output to the Debugger window with dbg.println()\n * instead, but it's a bit too confusing mingling script output in a window that\n * already mingles Debugger and machine output.\n */\n Component.println(aTokens.join(' '), Component.PRINT.SCRIPT);\n\n var fnCallReady = null;\n if (Component.asyncCommands.indexOf(sCommand) >= 0) {\n fnCallReady = function processNextCommand() {\n return function() {\n Component.processCommands(idMachine);\n }\n }();\n }\n\n var fnCommand = Component.globalCommands[sCommand];\n if (fnCommand) {\n if (!fnCallReady) {\n fSuccess = fnCommand(aTokens[1], aTokens[2], aTokens[3]);\n } else {\n if (!fnCommand(fnCallReady, aTokens[1], aTokens[2], aTokens[3])) break;\n }\n }\n else {\n fSuccess = false;\n var component = Component.getComponentByType(aTokens[1], idMachine);\n if (component) {\n fnCommand = Component.componentCommands[sCommand];\n if (fnCommand) {\n fSuccess = fnCommand(component, aTokens[2], aTokens[3]);\n }\n else {\n var exports = component['exports'];\n if (exports) {\n fnCommand = exports[sCommand];\n if (fnCommand) {\n fSuccess = true;\n if (!fnCallReady) {\n fSuccess = fnCommand.call(component, aTokens[2], aTokens[3]);\n } else {\n if (!fnCommand.call(component, fnCallReady, aTokens[2], aTokens[3])) break;\n }\n }\n }\n }\n }\n }\n\n if (!fSuccess) {\n Component.alertUser(\"Script error: '\" + sCommand + \"' command \" + (fnCommand? \" failed\" : \" not recognized\"));\n break;\n }\n }\n\n if (aCommands && !aCommands.length) {\n delete Component.commands[idMachine];\n }\n\n return fSuccess;\n }\n\n /**\n * Component.scriptAlert(sMessage)\n *\n * @param {string} sMessage\n * @return {boolean}\n */\n static scriptAlert(sMessage)\n {\n Component.alertUser(sMessage);\n return true;\n }\n\n /**\n * Component.scriptSelect(component, sBinding, sValue)\n *\n * @param {Component} component\n * @param {string} sBinding\n * @param {string} sValue\n * @return {boolean}\n */\n static scriptSelect(component, sBinding, sValue)\n {\n var fSuccess = false;\n var aBindings = component['bindings'];\n var control = aBindings[sBinding];\n if (control) {\n for (var i = 0; i < control.options.length; i++) {\n if (control.options[i].textContent == sValue) {\n if (control.selectedIndex != i) {\n control.selectedIndex = i;\n }\n fSuccess = true;\n break;\n }\n }\n }\n return fSuccess;\n }\n\n /**\n * Component.scriptSleep(fnCallback, sDelay)\n *\n * @param {function()} fnCallback\n * @param {string} sDelay (in milliseconds)\n * @return {boolean}\n */\n static scriptSleep(fnCallback, sDelay)\n {\n setTimeout(fnCallback, +sDelay);\n return false;\n }\n\n /**\n * toString()\n *\n * @this {Component}\n * @return {string}\n */\n toString()\n {\n return (this.name? this.name : (this.id || this.type));\n }\n\n /**\n * getMachineNum()\n *\n * @this {Component}\n * @return {number} unique machine number\n */\n getMachineNum()\n {\n var nMachine = 1;\n if (this.idMachine) {\n var aDigits = this.idMachine.match(/\\d+/);\n if (aDigits !== null)\n nMachine = parseInt(aDigits[0], 10);\n }\n return nMachine;\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * Component's setBinding() method is intended to be overridden by subclasses.\n *\n * @this {Component}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, 'print')\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n switch (sBinding) {\n case 'clear':\n if (!this.bindings[sBinding]) {\n this.bindings[sBinding] = control;\n control.onclick = (function(component) {\n return function clearControl() {\n if (component.bindings['print']) {\n component.bindings['print'].value = \"\";\n }\n };\n }(this));\n }\n return true;\n case 'print':\n if (!this.bindings[sBinding]) {\n var controlTextArea = /** @type {HTMLTextAreaElement} */(control);\n this.bindings[sBinding] = controlTextArea;\n /**\n * Override this.notice() with a replacement function that eliminates the Component.alertUser() call.\n *\n * @this {Component}\n * @param {string} s\n * @return {boolean}\n */\n this.notice = function noticeControl(s /*, fPrintOnly, id*/) {\n this.println(s, this.type);\n return true;\n };\n /*\n * This was added for Firefox (Safari will clear the <textarea> on a page reload, but Firefox does not).\n */\n controlTextArea.value = \"\";\n this.print = function(control) {\n return function printControl(s) {\n Component.appendControl(control, s);\n };\n }(controlTextArea);\n this.println = function(component, control) {\n return function printlnControl(s, type, id) {\n if (!s) s = \"\";\n if (type != Component.PRINT.PROGRESS || s.slice(-3) != \"...\") {\n if (type) s = type + \": \" + s;\n Component.appendControl(control, s + '\\n');\n } else {\n Component.replaceControl(control, s, s + '.');\n }\n if (!COMPILED && window && window.console) Component.println(s, type, id);\n };\n }(this, controlTextArea);\n }\n return true;\n default:\n return false;\n }\n }\n\n /**\n * log(s, type)\n *\n * For diagnostic output only.\n *\n * WARNING: Even though this function's body is completely wrapped in DEBUG, that won't prevent the Closure Compiler\n * from including it, so all calls must still be prefixed with \"if (DEBUG) ....\". For this reason, the class method,\n * Component.log(), is preferred, because the compiler IS smart enough to remove those calls.\n *\n * @this {Component}\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n log(s, type)\n {\n if (!COMPILED) {\n Component.log(s, type || this.id || this.type);\n }\n }\n\n /**\n * assert(f, s)\n *\n * Verifies conditions that must be true (for DEBUG builds only).\n *\n * WARNING: Make sure you preface all calls to this.assert() with \"if (DEBUG)\", because unlike Component.assert(),\n * the Closure Compiler can't be sure that this instance method hasn't been overridden, so it refuses to treat it as\n * dead code in non-DEBUG builds.\n *\n * TODO: Add a task to the build process that \"asserts\" there are no instances of \"assertion failure\" in RELEASE builds.\n *\n * @this {Component}\n * @param {boolean|number} f is the expression asserted to be true\n * @param {string} [s] is a description of the assertion to be displayed or logged on failure\n */\n assert(f, s)\n {\n if (DEBUG) {\n if (!f) {\n s = \"assertion failure in \" + (this.id || this.type) + (s? \": \" + s : \"\");\n if (DEBUGGER && this.dbg) {\n this.dbg.stopCPU();\n /*\n * Why do we throw an Error only to immediately catch and ignore it? Simply to give\n * any IDE the opportunity to inspect the application's state. Even when the IDE has\n * control, you should still be able to invoke Debugger commands from the IDE's REPL,\n * using the global function that the Debugger constructor defines; eg:\n *\n * pcx86('r')\n * pcx86('dw 0:0')\n * pcx86('h')\n * ...\n *\n * If you have no desire to stop on assertions, consider this a no-op. However, another\n * potential benefit of creating an Error object is that, for browsers like Chrome, we get\n * a stack trace, too.\n */\n try {\n throw new Error(s);\n } catch(e) {\n this.println(e.stack || e.message);\n }\n return;\n }\n this.log(s);\n throw new Error(s);\n }\n }\n }\n\n /**\n * print(s)\n *\n * Components using this.print() should wait until after their constructor has run to display any messages, because\n * if a Control Panel has been loaded, its override will not take effect until its own constructor has run.\n *\n * @this {Component}\n * @param {string} s\n */\n print(s)\n {\n Component.print(s);\n }\n\n /**\n * println(s, type, id)\n *\n * Components using this.println() should wait until after their constructor has run to display any messages, because\n * if a Control Panel has been loaded, its override will not take effect until its own constructor has run.\n *\n * @this {Component}\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n * @param {string} [id] is the caller's ID, if any\n */\n println(s, type, id)\n {\n Component.println(s, type, id || this.id);\n }\n\n /**\n * status(s)\n *\n * status() is like println() but it also includes information about the component (ie, the component type),\n * which is why there is no corresponding Component.status() function.\n *\n * @this {Component}\n * @param {string} s is the message text\n */\n status(s)\n {\n this.println(this.type + \": \" + s);\n }\n\n /**\n * notice(s, fPrintOnly, id)\n *\n * notice() is like println() but implies a need for user notification, so we alert() as well; however, if this.println()\n * is overridden, this.notice will be replaced with a similar override, on the assumption that the override is taking care\n * of alerting the user.\n *\n * @this {Component}\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n * @return {boolean}\n */\n notice(s, fPrintOnly, id)\n {\n if (!fPrintOnly) {\n /*\n * See if the associated computer, if any, is \"unloading\"....\n */\n var computer = Component.getComponentByType(\"Computer\", this.id);\n if (computer && computer.flags.unloading) {\n console.log(\"ignoring notice during unload: \" + s);\n return false;\n }\n }\n Component.notice(s, fPrintOnly, id || this.type);\n return true;\n }\n\n /**\n * setError(s)\n *\n * Set a fatal error condition\n *\n * @this {Component}\n * @param {string} s describes a fatal error condition\n */\n setError(s)\n {\n this.flags.error = true;\n this.notice(s); // TODO: Any cases where we should still prefix this string with \"Fatal error: \"?\n }\n\n /**\n * clearError()\n *\n * Clear any fatal error condition\n *\n * @this {Component}\n */\n clearError() {\n this.flags.error = false;\n }\n\n /**\n * isError()\n *\n * Report any fatal error condition\n *\n * @this {Component}\n * @return {boolean} true if a fatal error condition exists, false if not\n */\n isError()\n {\n if (this.flags.error) {\n this.println(this.toString() + \" error\");\n return true;\n }\n return false;\n }\n\n /**\n * isReady(fnReady)\n *\n * Return the \"ready\" state of the component; if the component is not ready, it will queue the optional\n * notification function, otherwise it will immediately call the notification function, if any, without queuing it.\n *\n * NOTE: Since only the Computer component actually cares about the \"readiness\" of other components, the so-called\n * \"queue\" of notification functions supports exactly one function. This keeps things nice and simple.\n *\n * @this {Component}\n * @param {function()} [fnReady]\n * @return {boolean} true if the component is in a \"ready\" state, false if not\n */\n isReady(fnReady)\n {\n if (fnReady) {\n if (this.flags.ready) {\n fnReady();\n } else {\n if (MAXDEBUG) this.log(\"NOT ready\");\n this.fnReady = fnReady;\n }\n }\n return this.flags.ready;\n }\n\n /**\n * setReady(fReady)\n *\n * Set the \"ready\" state of the component to true, and call any queued notification functions.\n *\n * @this {Component}\n * @param {boolean} [fReady] is assumed to indicate \"ready\" unless EXPLICITLY set to false\n */\n setReady(fReady)\n {\n if (!this.flags.error) {\n this.flags.ready = (fReady !== false);\n if (this.flags.ready) {\n if (MAXDEBUG /* || this.name */) this.log(\"ready\");\n var fnReady = this.fnReady;\n this.fnReady = null;\n if (fnReady) fnReady();\n }\n }\n }\n\n /**\n * isBusy(fCancel)\n *\n * Return the \"busy\" state of the component\n *\n * @this {Component}\n * @param {boolean} [fCancel] is set to true to cancel a \"busy\" state\n * @return {boolean} true if \"busy\", false if not\n */\n isBusy(fCancel)\n {\n if (this.flags.busy) {\n if (fCancel) {\n this.flags.busyCancel = true;\n } else if (fCancel === undefined) {\n this.println(this.toString() + \" busy\");\n }\n }\n return this.flags.busy;\n }\n\n /**\n * setBusy(fBusy)\n *\n * Update the current busy state; if a busyCancel request is pending, it will be honored now.\n *\n * @this {Component}\n * @param {boolean} fBusy\n * @return {boolean}\n */\n setBusy(fBusy)\n {\n if (this.flags.busyCancel) {\n this.flags.busy = false;\n this.flags.busyCancel = false;\n return false;\n }\n if (this.flags.error) {\n this.println(this.toString() + \" error\");\n return false;\n }\n this.flags.busy = fBusy;\n return this.flags.busy;\n }\n\n /**\n * powerUp(fSave)\n *\n * @this {Component}\n * @param {Object|null} data\n * @param {boolean} [fRepower] is true if this is \"repower\" notification\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n this.flags.powered = true;\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Component}\n * @param {boolean} fSave\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n if (fShutdown) this.flags.powered = false;\n return true;\n }\n\n /**\n * messageEnabled(bitsMessage)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n *\n * @this {Component}\n * @param {number} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n * @return {boolean} true if all specified message enabled, false if not\n */\n messageEnabled(bitsMessage = 0)\n {\n if (DEBUGGER && this.dbg) {\n if (this !== this.dbg) {\n bitsMessage = bitsMessage || this.bitsMessage;\n }\n var bitsEnabled = this.dbg.bitsMessage & bitsMessage;\n /*\n * This next \"bit\" of logic is for PCx86 and any other machine where we've expanded the set of\n * messages by reusing bits in the low nibbles in combination with different bits in the high nibble.\n * If the input bits adhere to that format, then the mask we just produced must adhere to it as well,\n * and if it doesn't, zero the mask, ensuring that the test will return false.\n */\n if ((bitsMessage & 0xf0000000) && (bitsMessage & 0x0fffffff)) {\n if (!(bitsEnabled & 0xf0000000) || !(bitsEnabled & 0x0fffffff)) bitsEnabled = 0;\n }\n if (bitsMessage && bitsEnabled === bitsMessage) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * printf(format, ...args)\n *\n * @this {Component}\n * @param {string} format\n * @param {...} args\n */\n printf(format, ...args)\n {\n if (DEBUGGER && this.dbg) {\n if (this.messageEnabled()) {\n let s = Str.sprintf(format, ...args);\n /*\n * Since dbg.message() calls println(), we strip any ending linefeed.\n * \n * We could bypass the Debugger and go straight to this.print(), but we would lose\n * the benefits of debugger messages (eg, automatic buffering, halting, yielding, etc).\n */\n if (s.slice(-1) == '\\n') s = s.slice(0, -1);\n this.dbg.message(s);\n }\n }\n }\n\n /**\n * printMessage(sMessage, bitsMessage, fAddress)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n * If bitsMessage is true, the message is displayed regardless.\n *\n * @this {Component}\n * @param {string} sMessage is any caller-defined message string\n * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n * @param {boolean} [fAddress] is true to display the current address\n */\n printMessage(sMessage, bitsMessage, fAddress)\n {\n if (DEBUGGER && this.dbg) {\n if (bitsMessage === true || this.messageEnabled(bitsMessage | 0)) {\n this.dbg.message(sMessage, fAddress);\n }\n }\n }\n\n /**\n * printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n * If bitsMessage is true, the message is displayed as long as MESSAGE.PORT is enabled.\n *\n * @this {Component}\n * @param {number} port\n * @param {number|null|*} bOut if an output operation\n * @param {number|null|*} [addrFrom]\n * @param {string|null|*} [name] of the port, if any\n * @param {number|null|*} [bIn] is the input value, if known, on an input operation\n * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n */\n printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage)\n {\n if (DEBUGGER && this.dbg) {\n if (bitsMessage === true) {\n bitsMessage = 0;\n } else if (bitsMessage == null) {\n bitsMessage = this.bitsMessage;\n }\n this.dbg.messageIO(this, port, bOut, addrFrom, name, bIn, bitsMessage);\n }\n }\n}\n\n/*\n * Types recognized and supported by selected functions (eg, Computer.getMachineParm())\n */\nComponent.TYPE = {\n NUMBER: \"number\",\n OBJECT: \"object\",\n STRING: \"string\"\n};\n\n/*\n * These are the standard PRINT values you can pass as an optional argument to println(); in reality,\n * you can pass anything you want, because they are simply prepended to the message, although PROGRESS\n * messages may also be merged with earlier similar messages to keep the output buffer under control.\n */\nComponent.PRINT = {\n ERROR: \"error\",\n NOTICE: \"notice\",\n PROGRESS: \"progress\",\n SCRIPT: \"script\",\n WARNING: \"warning\"\n};\n\n/*\n * Every component created on the current page is recorded in this array (see Component.add()),\n * enabling any component to locate another component by ID (see Component.getComponentByID())\n * or by type (see Component.getComponentByType()).\n *\n * Every machine on the page are now recorded as well, by their machine ID. We then record the\n * various resources used by that machine.\n *\n * Includes a fallback for non-browser-based environments (ie, Node). TODO: This will need to be\n * tailored to Node, probably using the global object instead of the window object, if we ever want\n * to support multi-machine configs in that environment.\n */\nif (window) {\n if (!window['PCjs']) window['PCjs'] = {};\n if (!window['PCjs']['Machines']) window['PCjs']['Machines'] = {};\n if (!window['PCjs']['Components']) window['PCjs']['Components'] = [];\n if (!window['PCjs']['Commands']) window['PCjs']['Commands'] = {};\n}\nComponent.machines = window? window['PCjs']['Machines'] : {};\nComponent.components = window? window['PCjs']['Components'] : [];\nComponent.commands = window? window['PCjs']['Commands'] : {};\n\nComponent.asyncCommands = [\n 'hold', 'sleep', 'wait'\n];\nComponent.globalCommands = {\n 'alert': Component.scriptAlert,\n 'sleep': Component.scriptSleep\n};\nComponent.componentCommands = {\n 'select': Component.scriptSelect\n};\nComponent.printBuffer = \"\";\n\n/*\n * The following polyfills provide ES5 functionality that's missing in older browsers (eg, IE8),\n * allowing PCjs apps to run without slamming into exceptions; however, due to the lack of HTML5 canvas\n * support in those browsers, all you're likely to see are \"soft\" errors (eg, \"Missing <canvas> support\").\n *\n * Perhaps we can implement a text-only faux video display for a fun retro-browser experience someday.\n *\n * TODO: Come up with a better place to put these polyfills. We will likely have more if we decide to\n * make the leap from ES5 to ES6 features.\n */\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf\n */\nif (!Array.prototype.indexOf) {\n Array.prototype.indexOf = function(obj, start) {\n for (var i = (start || 0), j = this.length; i < j; i++) {\n if (this[i] === obj) { return i; }\n }\n return -1;\n }\n}\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray\n */\nif (!Array.isArray) {\n Array.isArray = function(arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n };\n}\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind\n */\nif (!Function.prototype.bind) {\n Function.prototype.bind = function(obj) {\n if (typeof this != \"function\") {\n // Closest thing possible to the ECMAScript 5 internal IsCallable function\n throw new TypeError(\"Function.prototype.bind: non-callable object\");\n }\n var args = Array.prototype.slice.call(arguments, 1);\n var fToBind = this;\n var fnNOP = /** @constructor */ (function() {});\n var fnBound = function() {\n return fToBind.apply(this instanceof fnNOP && obj? this : obj, args.concat(/** @type {Array} */(Array.prototype.slice.call(arguments))));\n };\n fnNOP.prototype = this.prototype;\n fnBound.prototype = new fnNOP();\n return fnBound;\n };\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/defines.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @define {string}\n */\nvar APPCLASS = \"c1pjs\"; // this @define is the default application class (eg, \"pcx86\", \"c1pjs\")\n\n/**\n * @define {string}\n */\nvar APPNAME = \"C1Pjs\"; // this @define is the default application name (eg, \"PCx86\", \"C1Pjs\")\n\n/**\n * @define {boolean}\n *\n * WARNING: DEBUGGER needs to accurately reflect whether or not the Debugger component is (or will be) loaded.\n * In the compiled case, we rely on the Closure Compiler to override DEBUGGER as appropriate. When it's *false*,\n * nearly all of debugger.js will be conditionally removed by the compiler, reducing it to little more than a\n * \"type skeleton\", which also solves some type-related warnings we would otherwise have if we tried to remove\n * debugger.js from the compilation process altogether.\n *\n * However, when we're in \"development mode\" and running uncompiled code in debugger-less configurations,\n * I would like to skip loading debugger.js altogether. When doing that, we must ALSO arrange for an additional file\n * (nodebugger.js) to be loaded immediately after this file, which *explicitly* overrides DEBUGGER with *false*.\n */\nvar DEBUGGER = true; // this @define is overridden by the Closure Compiler to remove Debugger-related support\n\n/*\n * Combine all the shared globals and machine-specific globals into one machine-specific global object,\n * which all machine components should start using; eg: \"if (C1PJS.DEBUG) ...\" instead of \"if (DEBUG) ...\".\n */\nvar C1PJS = {\n APPCLASS: APPCLASS,\n APPNAME: APPNAME,\n APPVERSION: APPVERSION, // shared\n COMPILED: COMPILED, // shared\n CSSCLASS: CSSCLASS, // shared\n DEBUG: DEBUG, // shared\n DEBUGGER: DEBUGGER,\n MAXDEBUG: MAXDEBUG, // shared\n PRIVATE: PRIVATE, // shared\n SITEHOST: SITEHOST, // shared\n XMLVERSION: XMLVERSION // shared\n};\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/panel.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass C1PPanel extends Component {\n /**\n * C1PPanel(parmsPanel)\n *\n * The Panel component has no required (parmsPanel) properties.\n *\n * @this {C1PPanel}\n * @param {Object} parmsPanel\n */\n constructor(parmsPanel)\n {\n super(\"C1PPanel\", parmsPanel);\n\n this.flags.powered = false;\n }\n\n /**\n * The Panel doesn't have any bindings of its own; it passes along all binding requests to\n * the Computer, CPU, Keyboard and Debugger components. The order shouldn't matter, since any\n * component that doesn't recognize the specified binding should simply ignore it.\n *\n * @this {C1PPanel}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n if (this.cmp && this.cmp.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (this.cpu && this.cpu.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (this.kbd && this.kbd.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (DEBUGGER && this.dbg && this.dbg.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n return super.setBinding(sHTMLType, sBinding, control, sValue);\n }\n\n /**\n * @this {C1PPanel}\n * @param {boolean} fOn\n * @param {C1PComputer} cmp\n */\n setPower(fOn, cmp)\n {\n if (fOn && !this.flags.powered) {\n this.flags.powered = true;\n this.cmp = cmp;\n this.cpu = cmp.getComponentByType(\"cpu\");\n this.kbd = cmp.getComponentByType(\"keyboard\");\n if (DEBUGGER) this.dbg = cmp.getComponentByType(\"debugger\");\n C1PPanel.init();\n }\n }\n\n /**\n * C1PPanel.init()\n *\n * This function operates on every HTML element of class \"panel\", extracting the\n * JSON-encoded parameters for the C1PPanel constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a C1PPanel component, and then binding\n * any associated HTML controls to the new component.\n *\n * NOTE: Unlike most other component init() functions, this one is designed to be\n * called multiple times: once at load time, so that we can binding our print()\n * function to the panel's output control ASAP, and again when the C1PComputer component\n * is verifying that all components are ready and invoking their setPower() functions.\n *\n * Our setPower() method gives us a second opportunity to notify any components that\n * that might care (eg, C1PCPU, C1PKeyboard, and C1PDebugger) that we have some controls\n * they might want to use.\n */\n static init()\n {\n var fReady = false;\n var aePanels = Component.getElementsByClass(document, C1PJS.APPCLASS, \"panel\");\n for (var iPanel=0; iPanel < aePanels.length; iPanel++) {\n var ePanel = aePanels[iPanel];\n var parmsPanel = Component.getComponentParms(ePanel);\n var panel = Component.getComponentByID(parmsPanel['id']);\n if (!panel) {\n fReady = true;\n panel = new C1PPanel(parmsPanel);\n }\n Component.bindComponentControls(panel, ePanel, C1PJS.APPCLASS);\n if (fReady) panel.setReady();\n }\n }\n}\n\n/*\n * Initialize every Panel module on the page.\n */\nWeb.onInit(C1PPanel.init);\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/cpu.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass C1PCPU extends Component {\n /**\n * C1PCPU(parmsCPU)\n *\n * The C1PCPU object has one component-specific initialization property:\n *\n * autoStart: true to automatically start, false to not, or null (default)\n * to make the autoStart decision based on whether or not a Debugger is\n * installed (if there's no Debugger AND no \"Run\" button, then auto-start,\n * otherwise don't)\n *\n * It is hard-coded to simulate a 6502 microprocessor, but it also contains\n * hooks into other components for communication with the outside world (eg,\n * Panel and Debugger components). This is a logical simulation, not a physical\n * simulation, and performance is important, so we take lots of liberties; any\n * idiosyncrasies of actual 6502 hardware may not be simulated here, unless it\n * affects the accuracy of the simulation when running actual 6502 software.\n *\n * @this {C1PCPU}\n * @param {Object} parmsCPU\n */\n constructor(parmsCPU)\n {\n super(\"C1PCPU\", parmsCPU);\n\n this.clearRegs();\n this.flags.powered = false;\n this.flags.running = false;\n this.fAutoStart = parmsCPU[\"autoStart\"];\n\n /*\n * speed is a number from 0 to 2, where 0 means run as close to 1Mhz as possible,\n * 1 means run at the fastest safe speed, and 2 means run at maximum speed.\n *\n * It's updated via the setSpeed() function, which the Debugger's \"option\" command\n * uses to adjust the virtual speed (eg, \"o slow\", \"o fast\"). There may also\n * be a button present to control the speed as well (using the \"setSpeed\" binding).\n */\n this.SPEED_SLOW = 0; // see this.mhzSlow\n this.SPEED_FAST = 1; // see this.mhzFast\n this.SPEED_MAX = 2;\n this.speed = this.SPEED_SLOW;\n this.nCyclesPerSecond = 1000000;\n\n /*\n * Additional values that control the overall speed of the simulated hardware,\n * and the frequency at which various updates should occur. There are no UI\n * mechanisms for tweaking these values (yet).\n *\n * NOTE: Use of the term \"second\" below refers to a virtual CPU second, consisting of\n * 1 million simulated cycles. The values below are used to divide those 1 million\n * cycles into intervals of \"work\", and as long we are limiting the simulation to 1Mhz\n * per ACTUAL second, then 1 virtual second == 1 real second.\n *\n * However, if the setSpeed() function is used to lift the 1Mhz limit, then 1 virtual\n * second may become much shorter, which is why you may briefly notice the video and/or\n * status (control panel) updates occurring more frequently. To compensate, calcCycles()\n * will automatically scale these values if a recent speed recalculation reveals that\n * we're running significantly faster than 1Mhz.\n */\n this.nYieldsPerSecond = 30;\n this.nVideoUpdatesPerSecond = 30;\n this.nStatusUpdatesPerSecond = 5;\n this.mhzSlow = 1;\n this.mhzFast = 8;\n this.aSpeeds = [\"Slow\", \"Fast\", \"Max\"];\n this.aSpeedDescs = [\"(\" + this.mhzSlow + \"Mhz)\", \"(up to \" + this.mhzFast + \"Mhz)\", \"(unlimited)\"];\n\n /*\n * Lists of notification handlers: aReadNotify and aWriteNotify are lists (ie, Arrays)\n * of 4-element sub-arrays that, in turn, contain:\n *\n * [0]: starting address of memory range to monitor\n * [1]: ending address of memory range to monitor (inclusive)\n * [2]: registered component\n * [3]: registered function to call for every read/write from/to memory in that range\n *\n * The virtual Serial Port and virtual Keyboard components use these handlers to trap\n * references to their respective memory-based \"ports\". Also, the ROM component uses it\n * to \"repair\" any writes to its address range, since memory is one big array, and arrays\n * don't support \"write-only\" regions.\n *\n * NOTE: the Video component does NOT use notification handlers, because video memory\n * is written (and occasionally read) far too frequently for that to be efficient. We\n * just let the CPU pound on it like any other chunk of memory, and then make periodic\n * calls directly to the Video component to refresh all portions of the video buffer\n * that have changed since the last refresh. See displayVideo() for more details.\n *\n * WARNING: Write notifications currently do not catch STACK writes (ie, BRK, JSR, PHA and\n * PHP instructions), because I simply haven't added the necessary code. Besides, JSR is\n * one of the most-executed instructions, so I'd rather not slow it down. Note that this\n * STACK write limitation affects both the CPU's write-notification handlers AND the Debugger's\n * write breakpoints.\n */\n this.aReadNotify = [];\n this.aWriteNotify = [];\n\n /*\n * To speed up the processing of read and write notification handlers, we keep track of\n * lower and upper address bounds for each set. These variables maintain those bounds.\n * They are initialized to values outside the accessible range of addresses.\n */\n this.addrReadLower = 0x10000;\n this.addrReadUpper = 0x0;\n this.addrWriteLower = 0x10000;\n this.addrWriteUpper = 0x0;\n\n /*\n * Processor status register (P) flag masks\n */\n this.BIT_PN = 0x80; // N = sign\n this.BIT_PV = 0x40; // V = overflow\n this.BIT_PB = 0x10; // B = break\n this.BIT_PD = 0x08; // D = decimal\n this.BIT_PI = 0x04; // I = interrupt\n this.BIT_PZ = 0x02; // Z = zero\n this.BIT_PC = 0x01; // C = carry\n\n // this.VECTOR_NMI = 0xfffa;\n this.VECTOR_RESET = 0xfffc;\n // this.VECTOR_IRQ = 0xfffe;\n\n /*\n * Popular opcodes\n */\n this.OP_JSR = 0x20;\n\n /*\n * opSim operation codes\n */\n this.OP_SIM = 0x02;\n this.SIMOP_HLT = 0x00;\n this.SIMOP_MSG = 0x01;\n\n /*\n * This 256-entry array of opcode functions is at the heart of the CPU engine: step(n).\n *\n * It might be worth trying a switch() statement instead, to see how the performance compares,\n * but I suspect that will vary quite a bit across JavaScript engines; for now, I'm putting my\n * money on array lookup.\n */\n this.aOpcodeFuncs = [\n this.opBRK, // 0x00\n this.opORAindx, // 0x01\n this.opSim, // 0x02\n this.opUndefined, // 0x03\n this.opUndefined, // 0x04\n this.opORAzp, // 0x05\n this.opASLzp, // 0x06\n this.opUndefined, // 0x07\n this.opPHP, // 0x08\n this.opORAimm, // 0x09\n this.opASLacc, // 0x0a\n this.opUndefined, // 0x0b\n this.opUndefined, // 0x0c\n this.opORAabs, // 0x0d\n this.opASLabs, // 0x0e\n this.opUndefined, // 0x0f\n this.opBPL, // 0x10\n this.opORAindy, // 0x11\n this.opUndefined, // 0x12\n this.opUndefined, // 0x13\n this.opUndefined, // 0x14\n this.opORAzpx, // 0x15\n this.opASLzpx, // 0x16\n this.opUndefined, // 0x17\n this.opCLC, // 0x18\n this.opORAabsy, // 0x19\n this.opUndefined, // 0x1a\n this.opUndefined, // 0x1b\n this.opUndefined, // 0x1c\n this.opORAabsx, // 0x1d\n this.opASLabsx, // 0x1e\n this.opUndefined, // 0x1f\n this.opJSRabs, // 0x20\n this.opANDindx, // 0x21\n this.opUndefined, // 0x22\n this.opUndefined, // 0x23\n this.opBITzp, // 0x24\n this.opANDzp, // 0x25\n this.opROLzp, // 0x26\n this.opUndefined, // 0x27\n this.opPLP, // 0x28\n this.opANDimm, // 0x29\n this.opROLacc, // 0x2a\n this.opUndefined, // 0x2b\n this.opBITabs, // 0x2c\n this.opANDabs, // 0x2d\n this.opROLabs, // 0x2e\n this.opUndefined, // 0x2f\n this.opBMI, // 0x30\n this.opANDindy, // 0x31\n this.opUndefined, // 0x32\n this.opUndefined, // 0x33\n this.opUndefined, // 0x34\n this.opANDzpx, // 0x35\n this.opROLzpx, // 0x36\n this.opUndefined, // 0x37\n this.opSEC, // 0x38\n this.opANDabsy, // 0x39\n this.opUndefined, // 0x3a\n this.opUndefined, // 0x3b\n this.opUndefined, // 0x3c\n this.opANDabsx, // 0x3d\n this.opROLabsx, // 0x3e\n this.opUndefined, // 0x3f\n this.opRTI, // 0x40\n this.opEORindx, // 0x41\n this.opUndefined, // 0x42\n this.opUndefined, // 0x43\n this.opUndefined, // 0x44\n this.opEORzp, // 0x45\n this.opLSRzp, // 0x46\n this.opUndefined, // 0x47\n this.opPHA, // 0x48\n this.opEORimm, // 0x49\n this.opLSRacc, // 0x4a\n this.opUndefined, // 0x4b\n this.opJMPimm16, // 0x4c\n this.opEORabs, // 0x4d\n this.opLSRabs, // 0x4e\n this.opUndefined, // 0x4f\n this.opBVC, // 0x50\n this.opEORindy, // 0x51\n this.opUndefined, // 0x52\n this.opUndefined, // 0x53\n this.opUndefined, // 0x54\n this.opEORzpx, // 0x55\n this.opLSRzpx, // 0x56\n this.opUndefined, // 0x57\n this.opCLI, // 0x58\n this.opEORabsy, // 0x59\n this.opUndefined, // 0x5a\n this.opUndefined, // 0x5b\n this.opUndefined, // 0x5c\n this.opEORabsx, // 0x5d\n this.opLSRabsx, // 0x5e\n this.opUndefined, // 0x5f\n this.opRTS, // 0x60\n this.opADCindx, // 0x61\n this.opUndefined, // 0x62\n this.opUndefined, // 0x63\n this.opUndefined, // 0x64\n this.opADCzp, // 0x65\n this.opRORzp, // 0x66\n this.opUndefined, // 0x67\n this.opPLA, // 0x68\n this.opADCimm, // 0x69\n this.opRORacc, // 0x6a\n this.opUndefined, // 0x6b\n this.opJMPabs16, // 0x6c\n this.opADCabs, // 0x6d\n this.opRORabs, // 0x6e\n this.opUndefined, // 0x6f\n this.opBVS, // 0x70\n this.opADCindy, // 0x71\n this.opUndefined, // 0x72\n this.opUndefined, // 0x73\n this.opUndefined, // 0x74\n this.opADCzpx, // 0x75\n this.opRORzpx, // 0x76\n this.opUndefined, // 0x77\n this.opSEI, // 0x78\n this.opADCabsy, // 0x79\n this.opUndefined, // 0x7a\n this.opUndefined, // 0x7b\n this.opUndefined, // 0x7c\n this.opADCabsx, // 0x7d\n this.opRORabsx, // 0x7e\n this.opUndefined, // 0x7f\n this.opUndefined, // 0x80\n this.opSTAindx, // 0x81\n this.opUndefined, // 0x82\n this.opUndefined, // 0x83\n this.opSTYzp, // 0x84\n this.opSTAzp, // 0x85\n this.opSTXzp, // 0x86\n this.opUndefined, // 0x87\n this.opDEY, // 0x88\n this.opUndefined, // 0x89\n this.opTXA, // 0x8a\n this.opUndefined, // 0x8b\n this.opSTYabs, // 0x8c\n this.opSTAabs, // 0x8d\n this.opSTXabs, // 0x8e\n this.opUndefined, // 0x8f\n this.opBCC, // 0x90\n this.opSTAindy, // 0x91\n this.opUndefined, // 0x92\n this.opUndefined, // 0x93\n this.opSTYzpx, // 0x94\n this.opSTAzpx, // 0x95\n this.opSTXzpy, // 0x96\n this.opUndefined, // 0x97\n this.opTYA, // 0x98\n this.opSTAabsy, // 0x99\n this.opTXS, // 0x9a\n this.opUndefined, // 0x9b\n this.opUndefined, // 0x9c\n this.opSTAabsx, // 0x9d\n this.opUndefined, // 0x9e\n this.opUndefined, // 0x9f\n this.opLDYimm, // 0xa0\n this.opLDAindx, // 0xa1\n this.opLDXimm, // 0xa2\n this.opUndefined, // 0xa3\n this.opLDYzp, // 0xa4\n this.opLDAzp, // 0xa5\n this.opLDXzp, // 0xa6\n this.opUndefined, // 0xa7\n this.opTAY, // 0xa8\n this.opLDAimm, // 0xa9\n this.opTAX, // 0xaa\n this.opUndefined, // 0xab\n this.opLDYabs, // 0xac\n this.opLDAabs, // 0xad\n this.opLDXabs, // 0xae\n this.opUndefined, // 0xaf\n this.opBCS, // 0xb0\n this.opLDAindy, // 0xb1\n this.opUndefined, // 0xb2\n this.opUndefined, // 0xb3\n this.opLDYzpx, // 0xb4\n this.opLDAzpx, // 0xb5\n this.opLDXzpy, // 0xb6\n this.opUndefined, // 0xb7\n this.opCLV, // 0xb8\n this.opLDAabsy, // 0xb9\n this.opTSX, // 0xba\n this.opUndefined, // 0xbb\n this.opLDYabsx, // 0xbc\n this.opLDAabsx, // 0xbd\n this.opLDXabsy, // 0xbe\n this.opUndefined, // 0xbf\n this.opCPYimm, // 0xc0\n this.opCMPindx, // 0xc1\n this.opUndefined, // 0xc2\n this.opUndefined, // 0xc3\n this.opCPYzp, // 0xc4\n this.opCMPzp, // 0xc5\n this.opDECzp, // 0xc6\n this.opUndefined, // 0xc7\n this.opINY, // 0xc8\n this.opCMPimm, // 0xc9\n this.opDEX, // 0xca\n this.opUndefined, // 0xcb\n this.opCPYabs, // 0xcc\n this.opCMPabs, // 0xcd\n this.opDECabs, // 0xce\n this.opUndefined, // 0xcf\n this.opBNE, // 0xd0\n this.opCMPindy, // 0xd1\n this.opUndefined, // 0xd2\n this.opUndefined, // 0xd3\n this.opUndefined, // 0xd4\n this.opCMPzpx, // 0xd5\n this.opDECzpx, // 0xd6\n this.opUndefined, // 0xd7\n this.opCLD, // 0xd8\n this.opCMPabsy, // 0xd9\n this.opUndefined, // 0xda\n this.opUndefined, // 0xdb\n this.opUndefined, // 0xdc\n this.opCMPabsx, // 0xdd\n this.opDECabsx, // 0xde\n this.opUndefined, // 0xdf\n this.opCPXimm, // 0xe0\n this.opSBCindx, // 0xe1\n this.opUndefined, // 0xe2\n this.opUndefined, // 0xe3\n this.opCPXzp, // 0xe4\n this.opSBCzp, // 0xe5\n this.opINCzp, // 0xe6\n this.opUndefined, // 0xe7\n this.opINX, // 0xe8\n this.opSBCimm, // 0xe9\n this.opNOP, // 0xea\n this.opUndefined, // 0xeb\n this.opCPXabs, // 0xec\n this.opSBCabs, // 0xed\n this.opINCabs, // 0xee\n this.opUndefined, // 0xef\n this.opBEQ, // 0xf0\n this.opSBCindy, // 0xf1\n this.opUndefined, // 0xf2\n this.opUndefined, // 0xf3\n this.opUndefined, // 0xf4\n this.opSBCzpx, // 0xf5\n this.opINCzpx, // 0xf6\n this.opUndefined, // 0xf7\n this.opSED, // 0xf8\n this.opSBCabsy, // 0xf9\n this.opUndefined, // 0xfa\n this.opUndefined, // 0xfb\n this.opUndefined, // 0xfc\n this.opSBCabsx, // 0xfd\n this.opINCabsx, // 0xfe\n this.opUndefined // 0xff\n ];\n /*\n * This is a 256-byte array of cycle counts, indexed by opcode.\n * Obviously, true cycle counts are a bit more complicated, but this\n * gets us most of the way to an authentic-feeling simulation.\n *\n * NOTE: BCD functions now account for an extra cycle, and branches\n * now account for an extra cycle whenever the branch is taken.\n * However, branches still don't add an extra cycle whenever the branch\n * crosses a page boundary.\n *\n * The other gaping hole in our cycle-counting is accounting for all\n * page-boundary penalties. Ideally, that's just a matter of checking\n * MODE_ABSX, MODE_ABSY, and MODE_INDY instructions for EA straddling\n * a page boundary--but is it more complicated than that? What if the\n * criteria is not the final EA, but whether the pre-indexing and\n * post-indexing EAs are in different pages? I also need to confirm\n * whether any other situations merit checking (eg, when a 2 or 3-byte\n * instruction straddles a page boundary).\n */\n this.aOpcodeCycles = [\n 7,6,0,0,0,3,5,0,3,2,2,0,0,4,6,0,\n 2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0,\n 3,6,0,0,3,3,5,0,4,2,2,0,4,4,6,0,\n 2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0,\n 6,6,0,0,0,3,5,0,3,2,2,0,3,4,6,0,\n 2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0,\n 6,6,0,0,0,3,5,0,4,2,2,0,5,4,6,0,\n 2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0,\n 0,6,0,0,3,3,3,0,2,0,2,0,4,4,4,0,\n 2,5,0,0,4,4,4,0,2,4,2,0,0,4,0,0,\n 2,6,2,0,3,3,3,0,2,2,2,0,4,4,4,0,\n 2,5,0,0,4,4,4,0,2,4,2,0,4,4,4,0,\n 2,6,0,0,3,3,5,0,2,2,2,0,4,4,6,0,\n 2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0,\n 2,6,0,0,3,3,5,0,2,2,2,0,4,4,6,0,\n 2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0\n ];\n }\n\n /**\n * reset(fPowerOn)\n *\n * Note that we follow the same model here as other selected reset() handlers; for example, Video.reset()\n * accepts an fPowerOn parameter to govern what's initially displayed on the video screen.\n *\n * @this {C1PCPU}\n * @param {boolean|undefined} fPowerOn is true for the initial reset, so that if the Debugger isn't\n * loaded, we can elect to start running. Under any other circumstances (such as whenever Computer.reset()\n * is called), \"auto-run\" is not a good idea, and can actually introduce bugs (eg, multiple run() timers).\n */\n reset(fPowerOn)\n {\n if (this.flags.running) {\n this.halt();\n }\n this.clearRegs();\n this.regPC = this.getWord(this.VECTOR_RESET);\n this.clearError(); // clear any fatal error/exception\n /*\n * If there's a Debugger, notify Debugger.reset(); otherwise, start running\n */\n if (DEBUGGER && this.dbg) {\n this.dbg.reset();\n }\n else if (fPowerOn) {\n if (this.fAutoStart === true || this.fAutoStart === null && (!DEBUGGER || !this.dbg) && this.bindings[\"run\"] === undefined) {\n this.run(); // start running automatically on the initial power-up, assuming there's no Debugger\n }\n }\n }\n\n /**\n * @this {C1PCPU}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"run\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var fBound = false;\n switch(sBinding) {\n case \"run\":\n this.bindings[sBinding] = control;\n control.onclick = function(cpu) {\n return function() {\n if (!cpu.flags.running) {\n cpu.run();\n } else {\n cpu.halt();\n }\n };\n }(this);\n fBound = true;\n break;\n case \"A\": case \"X\": case \"Y\": case \"S\": case \"PC\":\n case \"C\": case \"Z\": case \"I\": case \"D\": case \"B\": case \"V\": case \"N\":\n case \"speed\":\n this.bindings[sBinding] = control;\n fBound = true;\n break;\n case \"setSpeed\":\n this.bindings[sBinding] = control;\n control.onclick = function(cpu) {\n return function() {\n var speed = (cpu.speed >= cpu.SPEED_MAX? cpu.SPEED_SLOW : cpu.speed+1);\n cpu.setSpeed(speed, true);\n };\n }(this);\n fBound = true;\n break;\n default:\n break;\n }\n return fBound;\n }\n\n /**\n * @this {C1PCPU}\n * @param {Array} abMemory\n * @param {number} start\n * @param {number} end\n */\n setBuffer(abMemory, start, end)\n {\n this.abMem = abMemory;\n this.offMem = start;\n this.cbMem = end - start + 1;\n this.offLimit = this.offMem + this.cbMem;\n if (this.offMem) {\n /*\n * It's not that we couldn't support an address buffer that starts at a non-zero offset;\n * we simply have lots of code (eg, all the opcode handlers) that assumes offMem is zero,\n * and therefore that abMem can be indexed by any of the CPU registers without adding offMem.\n * All that code would have to be changed (at a slight performance penalty) if we couldn't\n * make this assumption.\n */\n Component.error(\"unsupported CPU address buffer offset (\" + this.offMem + \")\");\n return;\n }\n this.setReady();\n }\n\n /**\n * @this {C1PCPU}\n * @param {boolean} fOn\n * @param {C1PComputer} cmp\n */\n setPower(fOn, cmp)\n {\n if (fOn && !this.flags.powered) {\n this.cmp = cmp;\n /*\n * Attach the Debugger, if any, to the CPU, so that the CPU can periodically\n * notify it as needed (when the CPU starts, stops, and executes instructions)\n */\n if (DEBUGGER) {\n this.dbg = cmp.getComponentByType(\"debugger\");\n if (this.dbg)\n this.dbg.init();\n }\n /*\n * Attach the Video device to the CPU, so that the CPU can periodically update\n * the video display via displayVideo(), as cycles permit.\n */\n var video = cmp.getComponentByType(\"video\");\n if (video) {\n this.displayVideo = function(v) {\n return function() {\n v.updateScreen();\n };\n }(video);\n this.setFocus = function(v) {\n return function() {\n v.setFocus();\n };\n }(video);\n }\n this.flags.powered = true;\n this.reset(true);\n this.update();\n }\n }\n\n /**\n * Add a memory read-notification handler to the CPU's list of such handlers.\n *\n * @this {C1PCPU}\n * @param {number} start address\n * @param {number} end address\n * @param {Component} component\n * @param {function(number,number)} fn is called with the EA and PC values at the time of the write\n */\n addReadNotify(start, end, component, fn)\n {\n if (this.findNotify(this.aReadNotify, start, end, component, fn) < 0) {\n if (this.addrReadLower > start)\n this.addrReadLower = start;\n if (this.addrReadUpper < end)\n this.addrReadUpper = end;\n this.aReadNotify.push([start, end, component, fn]);\n if (DEBUG) this.log(\"addReadNotify(\" + Str.toHexWord(start) + \",\" + Str.toHexWord(end) + \",\" + component.id + \"): new read range: \" + Str.toHexWord(this.addrReadLower) + \"-\" + Str.toHexWord(this.addrReadUpper));\n }\n }\n\n /**\n * @this {C1PCPU}\n * @param {number} addrRead is the EA value at the time of the read\n * @param {number} [addrFrom] is the PC value at the time of the read;\n * this will be undefined for read notifications triggered by assorted Debugger commands,\n * so all handlers should be prepared for that as well.\n */\n checkReadNotify(addrRead, addrFrom)\n {\n for (var i=0; i < this.aReadNotify.length; i++) {\n if (addrRead >= this.aReadNotify[i][0] && addrRead <= this.aReadNotify[i][1]) {\n this.aReadNotify[i][3].call(this.aReadNotify[i][2], addrRead, addrFrom);\n }\n }\n }\n\n /**\n * Remove a memory read-notification handler from the CPU's list of such handlers.\n *\n * @this {C1PCPU}\n * @param {number} start address\n * @param {number} end address\n * @param {Component} component\n * @param {function(number,number)} fn of previously added handler\n * @return {boolean} true if remove was successful, false if the handler was not found\n */\n removeReadNotify(start, end, component, fn)\n {\n var aBounds = this.removeNotify(this.aReadNotify, start, end, component, fn);\n if (aBounds.length == 4) {\n this.addrReadLower = aBounds[2];\n this.addrReadUpper = aBounds[3];\n if (DEBUG) this.log(\"removeReadNotify(\" + Str.toHexWord(start) + \",\" + Str.toHexWord(end) + \",\" + component.id + \"): new read range: \" + Str.toHexWord(this.addrReadLower) + \"-\" + Str.toHexWord(this.addrReadUpper));\n return true;\n }\n return false;\n }\n\n /**\n * Add a memory write-notification handler to the CPU's list of such handlers.\n *\n * @this {C1PCPU}\n * @param {number} start address\n * @param {number} end address\n * @param {Component} component\n * @param {function(number,number)} fn is called with the EA and PC values at the time of the write\n */\n addWriteNotify(start, end, component, fn)\n {\n if (this.findNotify(this.aWriteNotify, start, end, component, fn) < 0) {\n if (this.addrWriteLower > start)\n this.addrWriteLower = start;\n if (this.addrWriteUpper < end)\n this.addrWriteUpper = end;\n this.aWriteNotify.push([start, end, component, fn]);\n if (DEBUG) this.log(\"addWriteNotify(\" + Str.toHexWord(start) + \",\" + Str.toHexWord(end) + \",\" + component.id + \"): new write range: \" + Str.toHexWord(this.addrWriteLower) + \"-\" + Str.toHexWord(this.addrWriteUpper));\n }\n }\n\n /**\n * @this {C1PCPU}\n * @param {number} addrWrite is the EA value at the time of the write\n * @param {number} [addrFrom] is the PC value at the time of the write;\n * this will be undefined for write notifications triggered by assorted Debugger commands,\n * so all handlers should be prepared for that as well.\n */\n checkWriteNotify(addrWrite, addrFrom)\n {\n for (var i=0; i < this.aWriteNotify.length; i++) {\n if (addrWrite >= this.aWriteNotify[i][0] && addrWrite <= this.aWriteNotify[i][1]) {\n this.aWriteNotify[i][3].call(this.aWriteNotify[i][2], addrWrite, addrFrom);\n }\n }\n }\n\n /**\n * Remove a memory write-notification handler from the CPU's list of such handlers.\n *\n * @this {C1PCPU}\n * @param {number} start address\n * @param {number} end address\n * @param {Component} component\n * @param {function(number,number)} fn of previously added handler\n * @return {boolean} true if remove was successful, false if the handler was not found\n */\n removeWriteNotify(start, end, component, fn)\n {\n var aBounds = this.removeNotify(this.aWriteNotify, start, end, component, fn);\n if (aBounds.length == 4) {\n this.addrWriteLower = aBounds[2];\n this.addrWriteUpper = aBounds[3];\n if (DEBUG) this.log(\"removeWriteNotify(\" + Str.toHexWord(start) + \",\" + Str.toHexWord(end) + \",\" + component.id + \"): new write range: \" + Str.toHexWord(this.addrWriteLower) + \"-\" + Str.toHexWord(this.addrWriteUpper));\n return true;\n }\n return false;\n }\n\n /**\n * Find a memory notification handler from the given array of handlers\n *\n * @this {C1PCPU}\n * @param {Array} aNotify array of handlers\n * @param {number} start address\n * @param {number} end address\n * @param {Component} component\n * @param {function(number,number)} fn of previously added handler\n * @return {number} index of the matching handler, or -1 if not found\n */\n findNotify(aNotify, start, end, component, fn)\n {\n for (var i=0; i < aNotify.length; i++) {\n if (aNotify[i][0] == start && aNotify[i][1] == end && aNotify[i][2] == component && aNotify[i][3] == fn) {\n return i;\n }\n }\n return -1;\n }\n\n /**\n * Remove a memory notification handler from the given array of handlers\n *\n * @this {C1PCPU}\n * @param {Array} aNotify array of handlers\n * @param {number} start address\n * @param {number} end address\n * @param {Component} component\n * @param {function(number,number)} fn of previously added handler\n * @return {Array} bounds of previous handler ([0] and [1]) and new lower and upper address bounds ([2] and [3])\n */\n removeNotify(aNotify, start, end, component, fn)\n {\n var aBounds = [];\n var i = this.findNotify(aNotify, start, end, component, fn);\n if (i >= 0) {\n aBounds.push(aNotify[i][0]);\n aBounds.push(aNotify[i][1]);\n aNotify.splice(i, 1);\n var addrLower = 0x10000, addrUpper = 0x0;\n for (i=0; i < aNotify.length; i++) {\n if (addrLower > aNotify[i][0])\n addrLower = aNotify[i][0];\n if (addrUpper < aNotify[i][1])\n addrUpper = aNotify[i][1];\n }\n aBounds.push(addrLower);\n aBounds.push(addrUpper);\n }\n return aBounds;\n }\n\n /**\n * @this {C1PCPU}\n * @param {number} [speed] is one of: 0 (slow), 1 (fast) or 2 (maximum)\n * @param {boolean} [fOnClick] is true if called from a click handler that might have stolen focus\n * @desc Whenever the speed is changed, the running cycle count and corresponding start time must be reset,\n * so that the next effective speed calculation obtains sensible results. In fact, when run() initially calls\n * setSpeed() with no parameters, that's all this function does (it doesn't change the current speed setting).\n */\n setSpeed(speed, fOnClick)\n {\n if (speed !== undefined) {\n this.speed = speed;\n if (this.bindings[\"setSpeed\"])\n this.bindings[\"setSpeed\"].innerHTML = this.aSpeeds[speed >= 2? 0 : speed+1];\n this.println(\"running at \" + this.aSpeeds[speed].toLowerCase() + \" speed \" + this.aSpeedDescs[speed]);\n if (fOnClick) this.setFocus();\n }\n this.nRunCycles = 0;\n this.msRunStart = Usr.getTime();\n this.calcCycles();\n }\n\n /**\n * @this {C1PCPU}\n * @param {number} nCycles\n * @param {number} msElapsed\n */\n calcSpeed(nCycles, msElapsed)\n {\n if (msElapsed) {\n this.mhz = Math.round(nCycles / ( msElapsed * 100)) / 10;\n if (msElapsed >= 86400000)\n this.setSpeed(); // reset all our counters once per day so that we never have to worry about overflow\n }\n }\n\n /**\n * @this {C1PCPU}\n */\n displayVideo()\n {\n // Nothing to do until setPower() installs a replacement function\n }\n\n /**\n * @this {C1PCPU}\n */\n setFocus()\n {\n // Nothing to do until setPower() installs a replacement function\n }\n\n /**\n * @this {C1PCPU}\n * @param {string} sReg\n * @param {number} vReg\n * @param {number} [len]\n */\n displayReg(sReg, vReg, len)\n {\n if (this.bindings[sReg] !== undefined) {\n if (len === undefined) len = 1;\n var s = \"0000\" + vReg.toString(16);\n this.bindings[sReg].innerHTML = s.slice(s.length-len).toUpperCase();\n }\n }\n\n /**\n * @this {C1PCPU}\n */\n displayStatus()\n {\n this.displayReg(\"A\", this.regA, 2);\n this.displayReg(\"X\", this.regX, 2);\n this.displayReg(\"Y\", this.regY, 2);\n var regP = this.getRegP();\n this.displayReg(\"C\", (regP & this.BIT_PC)? 1 : 0);\n this.displayReg(\"Z\", (regP & this.BIT_PZ)? 1 : 0);\n this.displayReg(\"I\", (regP & this.BIT_PI)? 1 : 0);\n this.displayReg(\"D\", (regP & this.BIT_PD)? 1 : 0);\n this.displayReg(\"B\", (regP & this.BIT_PB)? 1 : 0);\n this.displayReg(\"V\", (regP & this.BIT_PV)? 1 : 0);\n this.displayReg(\"N\", (regP & this.BIT_PN)? 1 : 0);\n this.displayReg(\"S\", this.regS, 4);\n this.displayReg(\"PC\", this.regPC, 4);\n if (this.bindings[\"speed\"] && this.mhz) {\n this.bindings[\"speed\"].innerHTML = this.mhz.toFixed(1) + \"Mhz\";\n }\n }\n\n /**\n * @this {C1PCPU}\n * @return {boolean}\n */\n isRunning()\n {\n return this.flags.running;\n }\n\n /**\n * Calculate the number of cycles to process for each \"burst\" of CPU activity. The size of a burst\n * is driven by the following values:\n *\n * nYieldsPerSecond (eg, 30)\n * nVideoUpdatesPerSecond (eg, 30)\n * nStatusUpdatesPerSecond (eg, 5)\n *\n * The largest of the above values forces the size of the burst to its smallest value. Let's say that\n * largest value is 30. Assuming nCyclesPerSecond is 1,000,000, that results in bursts of 33,333 cycles.\n *\n * At the end of each burst, we subtract burst cycles from yield, video, and status cycle \"threshold\"\n * counters. Whenever the \"next yield\" cycle counter goes to (or below) zero, we compare elapsed time\n * to the time we expected the virtual hardware to take (eg, 1000ms/50 or 20ms), and if we still have time\n * remaining, we sleep the remaining time (or 0ms if there's no remaining time), and then restart run().\n *\n * Similarly, whenever the \"next video update\" cycle counter goes to (or below) zero, we call displayVideo(),\n * and whenever the \"next status update\" cycle counter goes to (or below) zero, we call displayStatus().\n *\n * @this {C1PCPU}\n * @param {boolean} [fRecalc] is true if the caller wants to recalculate thresholds based on the\n * most recent mhz calculation (see calcSpeed)\n */\n calcCycles(fRecalc)\n {\n /*\n * Calculate the most cycles we're allowed to execute in a single \"burst\"\n */\n var nMostUpdatesPerSecond = this.nYieldsPerSecond;\n if (nMostUpdatesPerSecond < this.nVideoUpdatesPerSecond) nMostUpdatesPerSecond = this.nVideoUpdatesPerSecond;\n if (nMostUpdatesPerSecond < this.nStatusUpdatesPerSecond) nMostUpdatesPerSecond = this.nStatusUpdatesPerSecond;\n\n /*\n * Calculate \"per\" values for the yield, video update, and status update cycle counters\n */\n var vMultiplier = 1;\n if (fRecalc && this.speed > this.SPEED_SLOW && this.mhz) vMultiplier = this.mhz;\n if (vMultiplier > this.mhzFast && this.speed < this.SPEED_MAX) vMultiplier = this.mhzFast;\n\n this.msPerYield = Math.round(1000/this.nYieldsPerSecond);\n this.nCyclesPerBurst = Math.floor(this.nCyclesPerSecond / nMostUpdatesPerSecond * vMultiplier);\n this.nCyclesPerYield = Math.floor(this.nCyclesPerSecond / this.nYieldsPerSecond * vMultiplier);\n this.nCyclesPerVideoUpdate = Math.floor(this.nCyclesPerSecond / this.nVideoUpdatesPerSecond * vMultiplier);\n this.nCyclesPerStatusUpdate = Math.floor(this.nCyclesPerSecond / this.nStatusUpdatesPerSecond * vMultiplier);\n\n /*\n * And initialize \"next\" yield, video update, and status update cycle \"threshold\" counters to those \"per\" values\n */\n if (!fRecalc) {\n this.nCyclesNextYield = this.nCyclesPerYield;\n this.nCyclesNextVideoUpdate = this.nCyclesPerVideoUpdate;\n this.nCyclesNextStatusUpdate = this.nCyclesPerStatusUpdate;\n }\n this.nRecalcCycles = 0;\n }\n\n /**\n * @this {C1PCPU}\n */\n calcStartTime()\n {\n if (this.nRecalcCycles >= this.nCyclesPerSecond) {\n this.calcCycles(true);\n }\n this.nCyclesThisRun = 0;\n this.msStartThisRun = Usr.getTime();\n }\n\n /**\n * @this {C1PCPU}\n * @return {number}\n */\n calcRemainingTime()\n {\n var msCurrent = Usr.getTime();\n var msYield = this.msPerYield;\n\n if (this.nCyclesThisRun) {\n /*\n * Normally, we would assume we executed a full quota of work over msPerYield, but since the CPU\n * now has the option of calling yieldCPU(), that might not be true. If nCyclesThisRun is correct, then\n * the ratio of nCyclesThisRun/nCyclesPerYield should represent the percentage of work we performed,\n * and so applying that percentage to msPerYield should give us a better estimate of work vs. time.\n */\n msYield = Math.round(msYield * this.nCyclesThisRun / this.nCyclesPerYield);\n // if (msYield < this.msPerYield) this.println(\"scaling msPerYield (\" + this.msPerYield + \") to msYield (\" + msYield + \")\");\n }\n\n var msElapsedThisRun = msCurrent - this.msStartThisRun;\n var msRemainsThisRun = msYield - msElapsedThisRun;\n\n /*\n * We could pass only \"this run\" results to calcSpeed():\n *\n * nCycles = this.nCyclesThisRun;\n * msElapsed = msElapsedThisRun;\n *\n * but it seems preferable to use longer time periods and hopefully get a more accurate speed.\n *\n * Also, if msRemainsThisRun >= 0 && this.speed == this.SPEED_SLOW, we could pass these results instead:\n *\n * nCycles = this.nCyclesThisRun;\n * msElapsed = this.msPerYield;\n *\n * to insure that we display a smooth, constant 1Mhz. But the displayed speed seems pretty steady as-is.\n */\n var nCycles = this.nRunCycles;\n var msElapsed = msCurrent - this.msRunStart;\n\n if (DEBUG && msRemainsThisRun < 0 && this.speed == this.SPEED_FAST) {\n this.println(\"warning: updates @\" + msElapsedThisRun + \"ms (prefer \" + Math.round(msYield) + \"ms)\");\n }\n\n this.calcSpeed(nCycles, msElapsed);\n\n if (msRemainsThisRun < 0) {\n /*\n * This is an easy case: it's taking more than 1 second to simulate 1Mhz,\n * so all we can do is yield for as little time as possible (ie, 0ms) and hope the\n * simulation is at least usable.\n */\n msRemainsThisRun = 0;\n }\n else {\n if (this.speed == this.SPEED_FAST) {\n /*\n * This case requires us to artificially limit the CPU speed. calcSpeed()\n * already cranks up the number of cycles we process per burst, in proportion\n * to the effective mhz, so there isn't much to do here except sleep for\n * whatever time is in msRemainsThisRun.\n *\n * The artificial limit was chosen largely because it's not currently possible\n * for the keyboard component to inject keys fast enough to avoid duplicate\n * keystrokes at higher speeds. Perhaps with future improvements to the keyboard\n * component, this limit can be lifted.\n */\n if (this.mhz <= this.mhzFast)\n msRemainsThisRun = 0;\n }\n else\n if (this.speed == this.SPEED_MAX) {\n /*\n * This is also an easy case: yield for as little time as possible (ie, 0ms), to execute\n * the maximum number of cycles per second.\n */\n msRemainsThisRun = 0;\n }\n }\n\n /*\n * Last but not least, update nRecalcCycles, so that when run() starts up again and calls calcStartTime(),\n * it'll be ready to decide if calcCycles() should be called again.\n */\n this.nRecalcCycles += this.nCyclesThisRun;\n\n return msRemainsThisRun;\n }\n\n /**\n * @this {C1PCPU}\n */\n run()\n {\n if (!this.setBusy(true)) {\n this.update();\n if (this.cmp) this.cmp.stop(this.msRunStart, this.nRunCycles);\n return;\n }\n if (!this.flags.running) {\n /*\n * setSpeed() without a speed parameter leaves the selected speed in place, but also resets the\n * cycle counter and timestamp for the current series of run() calls, calculates the maximum number\n * of cycles for each burst based on the last known effective CPU speed, and resets the nRecalcCycles\n * threshold counter.\n */\n this.setSpeed();\n if (this.cmp) this.cmp.start();\n this.flags.running = true;\n if (this.bindings[\"run\"]) this.bindings[\"run\"].innerHTML = \"Halt\";\n this.setFocus();\n }\n /*\n * calcStartTime() initializes the cycle counter and timestamp for this run() invocation, and optionally\n * recalculates the the maximum number of cycles for each burst if the nRecalcCycles threshold has been reached.\n */\n this.calcStartTime();\n try {\n do {\n /*\n * NOTE: nCyclesPerBurst is how many cycles we WANT to run each iteration of step(), but that just\n * initializes nBurstCycles, which (after subtracting any remaining nStepCycles) is how many cycles\n * we ACTUALLY ran.\n */\n this.step(this.nCyclesPerBurst);\n /*\n * nCyclesThisRun is increased by nBurstCycles, plus any additional cycles step() processed after\n * its cycle count had reached zero (and conversely, minus any cycles that it still had yet to process);\n * ditto for nRunCycles, which is the cycle count since the CPU first started running.\n */\n var nCycles = this.nBurstCycles - this.nStepCycles;\n this.nRunCycles += nCycles;\n this.nCyclesThisRun += nCycles;\n /*\n * These step() cycle variables must be zeroed now, so that getCycles() always returns a valid cycle count.\n */\n this.nBurstCycles = this.nStepCycles = 0;\n\n this.nCyclesNextVideoUpdate -= this.nCyclesPerBurst;\n if (this.nCyclesNextVideoUpdate <= 0) {\n this.nCyclesNextVideoUpdate += this.nCyclesPerVideoUpdate;\n this.displayVideo();\n }\n\n this.nCyclesNextStatusUpdate -= this.nCyclesPerBurst;\n if (this.nCyclesNextStatusUpdate <= 0) {\n this.nCyclesNextStatusUpdate += this.nCyclesPerStatusUpdate;\n this.displayStatus();\n }\n\n this.nCyclesNextYield -= this.nCyclesPerBurst;\n if (this.nCyclesNextYield <= 0) {\n this.nCyclesNextYield += this.nCyclesPerYield;\n break;\n }\n } while (this.flags.running);\n }\n catch (e) {\n this.halt();\n this.update();\n this.setBusy(false);\n this.setError(e.stack || e.message);\n return;\n }\n setTimeout(function(cpu) { return function() {cpu.run();}; }(this), this.calcRemainingTime());\n }\n\n /**\n * @this {C1PCPU}\n * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored)\n * @return {boolean|undefined} undefined indicates that the last instruction was not executed (eg,\n * we hit an execution breakpoint), false implies a post-execution condition was triggered (eg, a write\n * breakpoint), and true indicates successful completion of all requested cycles.\n */\n step(nMinCycles)\n {\n /*\n * The Debugger uses fCompleted to determine if the instruction completed (true) or was interrupted\n * by a breakpoint or some other exceptional condition (false). NOTE: this does NOT include thrown\n * exceptions, which step() expects the caller to catch using its own exception handler.\n *\n * The CPU relies on the use of halt() rather than fCompleted, because the CPU never single-steps\n * (ie, nMinCycles is always some large number), whereas the Debugger does. And conversely, when the\n * Debugger is single-stepping (even when performing multiple single-steps), fRunning is never set,\n * so halt() would have no effect as far as the Debugger is concerned.\n */\n var fCompleted = true;\n\n /*\n * fDebugCheck is true if we need to \"check\" every instruction with the Debugger. The Debugger will\n * call cpu.step(n) with n == 0 if it's executing only ONE instruction (ie, the user just clicked the\n * \"Step\" button, or they've issued a \"t\" or \"t1\" command). Otherwise, it will call with n == 1\n * (ie, the user is holding the \"Step\" button, or they've issued a \"t#\" command where # > 1).\n *\n * In the first case, we want to ignore (ie, \"step over\") any breakpoints; otherwise, the Debugger has\n * no easy way of moving past a breakpoint (other than clearing it, of course). In the second case,\n * we want to honor any breakpoints, which in turn will set fCompleted to false and signal the Debugger\n * to stop.\n *\n * Note that as a practical matter, both 0 and 1 are otherwise treated the same when it comes to the\n * minimum number of cycles to run: one and only one instruction will execute, since every instruction\n * consumes at least 1 cycle.\n */\n this.regEA = this.regEAWrite = -1;\n var fDebugCheck = (DEBUGGER && nMinCycles && this.dbg && this.dbg.checksEnabled());\n\n /*\n * We move the minimum cycle count to nStepCycles (the number of cycles left to run), so that other\n * methods have the ability to force that number to zero (eg, halt()), and thus we don't have to check\n * some other criteria just to determine whether we should continue running or not.\n */\n this.nBurstCycles = this.nStepCycles = nMinCycles;\n do {\n var bOpCode = this.abMem[this.regPC];\n\n if (fDebugCheck && !this.dbg.checkInstruction(this.regPC, bOpCode)) {\n fCompleted = undefined;\n this.halt();\n break;\n }\n\n this.regPC++;\n this.aOpcodeFuncs[bOpCode].call(this);\n\n /*\n * Assert that all register contents remain within their respective ranges.\n */\n\n\n /*\n * WARNING: By making the following read-or-write test exclusive, we're not going to catch\n * those situations where an instruction does BOTH. For example, JSR pushes the old PC\n * (which, if we were tracking STACK writes, would set regEAWrite) and then fetches a new PC\n * (which should set regEA). However, that's a situation which, except for a peculiar\n * combination of read and write breakpoints set by the Debugger, is one we simply don't care\n * about. Moreover, none of our opcode handlers currently set BOTH regEA and regEAWrite,\n * so it would be completely pointless to check both conditions here.\n *\n * Since READS are FAR more common than WRITES, we check the common case first. If the\n * day comes that we implement opcode functions that set both regEA AND regEAWrite, then we'll\n * want to remove the \"else\" below and stop making the read and write tests exclusive.\n * If we don't, then some of those rare/unusual writes will either get missed or delayed.\n *\n * It's also worth mentioning here that not all instructions READ or WRITE (eg, INX, INY and\n * others that are completely flag or register-bound). It's a bit ironic that those instructions,\n * which are typically the fastest, have to perform both the READ and WRITE tests below. But\n * on the plus side, both tests will fail, so they'll still get out of here faster than any of\n * the other instructions.\n */\n if (this.regEA >= 0) {\n /*\n * Serial emulation requires a read notification handler, and the keyboard may eventually\n * want one, too.\n */\n if (this.regEA >= this.addrReadLower && this.regEA <= this.addrReadUpper) {\n this.checkReadNotify(this.regEA, this.regPC);\n }\n if (fDebugCheck && !this.dbg.checkMemoryRead(this.regEA)) {\n fCompleted = false;\n this.halt();\n break;\n }\n this.regEA = -1;\n }\n else if (this.regEAWrite >= 0) {\n /*\n * We process the write notification handlers before the write breakpoint handlers,\n * because we don't want to leave any ROM (read-only memory) writes in place before we\n * (potentially) give up control. Undoing every write to ROM address space is an essential\n * part of simulating the \"read-only\" behavior of ROM.\n *\n * Obviously, there are other write notification handlers as well (like the keyboard's),\n * which may sometimes do things we'd prefer to intercept first, but let's keep things simple.\n */\n if (this.regEAWrite >= this.addrWriteLower && this.regEAWrite <= this.addrWriteUpper) {\n this.checkWriteNotify(this.regEAWrite, this.regPC);\n }\n if (fDebugCheck && !this.dbg.checkMemoryWrite(this.regEAWrite, this.abMem[this.regEAWrite])) {\n fCompleted = false;\n this.halt();\n break;\n }\n this.regEAWrite = -1;\n }\n\n this.nStepCycles -= this.aOpcodeCycles[bOpCode];\n\n } while (this.nStepCycles > 0);\n\n return fCompleted;\n }\n\n /**\n * yieldCPU() is similar to halt() with regard to how it resets various cycle countdown values,\n * but the CPU remains in a \"running\" state.\n *\n * @this {C1PCPU}\n */\n yieldCPU()\n {\n this.nCyclesNextYield = 0; // this will break us out of run(), once we break out of step()\n this.nBurstCycles -= this.nStepCycles;\n this.nStepCycles = 0; // this will break us out of step()\n }\n\n /**\n * halt() is similar to yieldCPU(), but it doesn't need to zero nCyclesNextYield to break out of run();\n * it simply needs to clear fRunning.\n *\n * @this {C1PCPU}\n */\n halt()\n {\n this.isBusy(true);\n this.nBurstCycles -= this.nStepCycles;\n this.nStepCycles = 0;\n if (this.flags.running) {\n this.flags.running = false;\n if (this.bindings[\"run\"]) this.bindings[\"run\"].innerHTML = \"Run\";\n }\n }\n\n /**\n * @this {C1PCPU}\n *\n * This used to be performed at the end of every step(), but run() -- which relies upon step() -- needed to have\n * more control over when these updates are performed. However, for other callers of step(), such as the Debugger,\n * the combination of step() + update() provides the old behavior.\n */\n update()\n {\n this.displayVideo();\n this.displayStatus();\n }\n\n /**\n * getCycles() returns the number of cycles executed so far. Note that we can be called after\n * a run() OR during a run(), perhaps from a handler triggered during the current run's step(),\n * so nRunCycles must always be adjusted by number of cycles step() was asked to run (nBurstCycles),\n * less the number of cycles it has yet to run (nStepCycles).\n *\n * nRunCycles is reset whenever the CPU is halted or the CPU speed is changed, so returning 0 when the\n * CPU is stopped seems perfectly reasonable. As a result, components that rely on getCycles() returning a\n * steadily increasing number should also be prepared for a reset at any time (eg, the Keyboard's\n * updateMemory() function).\n *\n * @this {C1PCPU}\n * @return {number}\n */\n getCycles()\n {\n return (this.flags.running? this.nRunCycles + this.nBurstCycles - this.nStepCycles : 0);\n }\n\n /**\n * @this {C1PCPU}\n * @param {number} addr\n * @return {number}\n *\n * Unlike the Debugger versions of these functions, these presume that addr is always valid,\n * since it's internally generated, not user-supplied. Of course, we could still have internal\n * bugs, so asserts are included, but they are present in DEBUG code only (automatically\n * removed from RELEASE code).\n *\n * Moreover, it's unlikely we'll use this function much (unless performance becomes secondary\n * to code size), since all the opCode functions should perform their own fetches, for obvious\n * performance reasons.\n */\n getByte(addr)\n {\n\n var b = this.abMem[addr];\n\n return b;\n }\n\n /**\n * @this {C1PCPU}\n * @param {number} addr\n * @return {number}\n */\n getWord(addr)\n {\n\n var w = this.abMem[addr] | (this.abMem[addr+1] << 8);\n\n return w;\n }\n\n /**\n * @this {C1PCPU}\n * @param {number} addr\n * @param {number} b\n */\n setByte(addr, b)\n {\n\n\n this.abMem[addr] = b;\n }\n\n /**\n * @this {C1PCPU}\n * @return {number}\n */\n getRegP()\n {\n /*\n * // C = LAZY_C;\n * this.regP = ((this.regP & 0xfe) | ((((this.regRC & 0x0100)))? 0x01 : 0));\n * // Z = LAZY_Z;\n * this.regP = ((this.regP & 0xfd) | ((((this.regRZ & 0xff) == 0))? 0x02 : 0));\n * // V = LAZY_V;\n * this.regP = ((this.regP & 0xbf) | (((((((this.regRV & 0xff) ^ this.regRU) ^ (this.regRV >> 1)) & 0x80) != 0))? 0x40 : 0));\n * // N = LAZY_N;\n * this.regP = ((this.regP & 0x7f) | ((((this.regRN & 0x80)))? 0x80 : 0));\n */\n var regP = ((this.regRC & 0x0100)? 0x01 : 0x00);\n regP |= (!(this.regRZ & 0xff)? 0x02 : 0x00);\n regP |= (((((this.regRV & 0xff) ^ this.regRU) ^ (this.regRV >> 1)) & 0x80)? 0x40 : 0x00);\n regP |= ((this.regRN & 0x80)? 0x80 : 0x00);\n return (this.regP & 0x3C) | regP;\n }\n\n /**\n * @this {C1PCPU}\n *\n * Clear the C flag\n */\n clearC()\n {\n this.regRC = 0x00;\n }\n\n /**\n * @this {C1PCPU}\n *\n * Set the C flag\n */\n setC()\n {\n this.regRC = 0x100;\n }\n\n /**\n * @this {C1PCPU}\n *\n * Clear the N bit\n */\n clearN()\n {\n this.regRN = 0x00;\n }\n\n /**\n * @this {C1PCPU}\n *\n * Set the N bit\n */\n setN()\n {\n this.regRN = 0x80;\n }\n\n /**\n * @this {C1PCPU}\n *\n * Clear the V bit\n */\n clearV()\n {\n this.regRV = 0x00; this.regRU = 0x00;\n }\n\n /**\n * @this {C1PCPU}\n *\n * Set the V bit\n */\n setV()\n {\n this.regRV = 0x00; this.regRU = 0x80;\n }\n\n /**\n * @this {C1PCPU}\n *\n * Clear the Z bit\n */\n clearZ()\n {\n this.regRZ = 0x01;\n }\n\n /**\n * @this {C1PCPU}\n *\n * Set the Z bit\n */\n setZ()\n {\n this.regRZ = 0x00;\n }\n\n /**\n * @this {C1PCPU}\n *\n * Set the BCD bit and install the BCD opcode handlers\n */\n setBCD()\n {\n this.regP |= 0x08;\n this.aOpcodeFuncs[0x61] = this.opADCindxBCD;\n this.aOpcodeFuncs[0x65] = this.opADCzpBCD;\n this.aOpcodeFuncs[0x69] = this.opADCimmBCD;\n this.aOpcodeFuncs[0x6d] = this.opADCabsBCD;\n this.aOpcodeFuncs[0x71] = this.opADCindyBCD;\n this.aOpcodeFuncs[0x75] = this.opADCzpxBCD;\n this.aOpcodeFuncs[0x79] = this.opADCabsyBCD;\n this.aOpcodeFuncs[0x7d] = this.opADCabsxBCD;\n this.aOpcodeFuncs[0xe1] = this.opSBCindxBCD;\n this.aOpcodeFuncs[0xe5] = this.opSBCzpBCD;\n this.aOpcodeFuncs[0xe9] = this.opSBCimmBCD;\n this.aOpcodeFuncs[0xed] = this.opSBCabsBCD;\n this.aOpcodeFuncs[0xf1] = this.opSBCindyBCD;\n this.aOpcodeFuncs[0xf5] = this.opSBCzpxBCD;\n this.aOpcodeFuncs[0xf9] = this.opSBCabsyBCD;\n this.aOpcodeFuncs[0xfd] = this.opSBCabsxBCD;\n }\n\n /**\n * @this {C1PCPU}\n *\n * Clear the BCD bit and remove the BCD opcode handlers\n */\n clearBCD()\n {\n this.regP &= ~0x08;\n this.aOpcodeFuncs[0x61] = this.opADCindx;\n this.aOpcodeFuncs[0x65] = this.opADCzp;\n this.aOpcodeFuncs[0x69] = this.opADCimm;\n this.aOpcodeFuncs[0x6d] = this.opADCabs;\n this.aOpcodeFuncs[0x71] = this.opADCindy;\n this.aOpcodeFuncs[0x75] = this.opADCzpx;\n this.aOpcodeFuncs[0x79] = this.opADCabsy;\n this.aOpcodeFuncs[0x7d] = this.opADCabsx;\n this.aOpcodeFuncs[0xe1] = this.opSBCindx;\n this.aOpcodeFuncs[0xe5] = this.opSBCzp;\n this.aOpcodeFuncs[0xe9] = this.opSBCimm;\n this.aOpcodeFuncs[0xed] = this.opSBCabs;\n this.aOpcodeFuncs[0xf1] = this.opSBCindy;\n this.aOpcodeFuncs[0xf5] = this.opSBCzpx;\n this.aOpcodeFuncs[0xf9] = this.opSBCabsy;\n this.aOpcodeFuncs[0xfd] = this.opSBCabsx;\n }\n\n /**\n * @this {C1PCPU}\n * @param {number} reg\n * @param {number} mem\n * @return {number}\n *\n * Refer to http://www.6502.org/tutorials/decimal_mode.html for 6502-specific details.\n * Refer to http://homepage.cs.uiowa.edu/~jones/bcd/bcd.html for optimization tips.\n */\n addBCD(reg, mem)\n {\n var carry = ((this.regRC & 0x0100)? 1 : 0);\n\n /*\n * First add the low nibbles.\n */\n var r = (reg & 0x0f) + (mem & 0x0f) + carry;\n\n /*\n * Adjust the result. NOTE: The extra AND'ing and ADD'ing isn't necessary if we want to\n * assume that ONLY valid BCD digits will be added, but we probably shouldn't assume that.\n * NOTE: We use an OR instead of an ADD at the end because it's logically equivalent and faster.\n */\n if (r >= 0x0A) r = ((r + 0x06) & 0x0f) | 0x10;\n\n /*\n * Now add the high nibbles.\n */\n r += (reg & 0xf0) + (mem & 0xf0);\n\n /*\n * Before we do the next adjust, it seems that N and V are dependent on this intermediate\n * result (however, the meaning of N and V in BCD mode is not well documented).\n */\n this.regRU = reg ^ mem; this.regRV = r;\n this.regRN = (r & 0xff);\n\n /*\n * Final adjustment.\n */\n if (r >= 0xA0) r += 0x60;\n /*\n * NOTE: If the intermediate result was 0x1A0 or more, then adding 0x60 would yield a result\n * of 0x200 or more, but because the rest of the simulator tests regRC for 0x100, rather than\n * comparing regRC for values >= 0x100, we'll miss the fact that there was a carry, unless we\n * scale any value in the 0x200-0x2ff range down to 0x100-0x1ff. We then assert that the\n * resulting value is within the proper range.\n */\n if (r >= 0x200) r -= 0x100;\n\n\n /*\n * In BCD mode, the C flag reflects the decimal result, but the Z flag reflects binary addition.\n */\n this.regRC = r;\n this.regRZ = ((reg + mem + carry) & 0xff);\n\n /*\n * Account for an extra cycle in BCD mode as well.\n */\n this.nStepCycles--;\n\n return r & 0xff;\n }\n\n /**\n * @this {C1PCPU}\n * @param {number} reg\n * @param {number} mem\n * @return {number}\n *\n * Refer to http://www.6502.org/tutorials/decimal_mode.html for 6502-specific details.\n * Refer to http://homepage.cs.uiowa.edu/~jones/bcd/bcd.html for optimization tips.\n */\n subBCD(reg, mem)\n {\n var notcarry = ((this.regRC & 0x0100)? 0 : 1);\n\n /*\n * First subtract the low nibbles.\n */\n var r = (reg & 0x0f) - (mem & 0x0f) - notcarry;\n\n /*\n * Adjust the result. NOTE: The extra AND'ing and SUB'ing isn't necessary if we want to\n * assume that ONLY valid BCD digits will be added, but we probably shouldn't assume that.\n */\n if (r < 0x00) r = ((r - 0x06) & 0x0f) - 0x10;\n\n /*\n * Now subtract the high nibbles.\n */\n r += (reg & 0xf0) - (mem & 0xf0);\n\n /*\n * Final adjustment.\n */\n if (r < 0x00) r -= 0x60;\n\n /*\n * In BCD mode, the Z -- and C, N and V -- flags are all set as if binary subtraction was performed.\n */\n // RC = (A - ML - !LAZY_C); SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = (this.regRC = (reg - mem - notcarry)) & 0xff;\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = reg ^ mem; this.regRV = this.regRC;\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n\n /*\n * Account for an extra cycle in BCD mode as well.\n */\n this.nStepCycles--;\n\n return r & 0xff;\n }\n\n /**\n * @this {C1PCPU}\n */\n clearRegs()\n {\n this.regA = 0;\n this.regX = 0;\n this.regY = 0;\n this.regS = 0x100;\n this.regP = 0;\n this.regRN = 0;\n this.regRZ = 0;\n this.regRU = 0;\n this.regRV = 0;\n this.regRC = 0;\n this.regPC = 0;\n this.regEA = -1;\n this.regEAWrite = -1;\n this.mhz = 0;\n this.nRunCycles = this.nBurstCycles = this.nStepCycles = 0;\n }\n\n /**\n * @this {C1PCPU}\n */\n opBRK()\n { // opcode 0x00\n // PC++;\n this.regPC++;\n // STACK(S--) = PCH;\n this.abMem[this.regS--] = (this.regPC >> 8);\n this.regS |= 0x100;\n // STACK(S--) = PCL;\n this.abMem[this.regS--] = (this.regPC & 0xff);\n this.regS |= 0x100;\n // B = 1;\n this.regP |= 0x10;\n // C = LAZY_C; Z = LAZY_Z; V = LAZY_V; N = LAZY_N;\n this.regP = this.getRegP();\n // STACK(S--) = P;\n this.abMem[this.regS--] = this.regP;\n this.regS |= 0x100;\n // B = 0;\n this.regP &= 0xef;\n // EA = 0xFFFE;\n this.regEA = 0xFFFE;\n // PC = M;\n this.regPC = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n }\n\n /**\n * @this {C1PCPU}\n */\n opORAindx()\n { // opcode 0x01\n // EA = WORD((BYTE(PC++)+X) & 0xff);\n this.regEA = ((this.abMem[this.regPC++]) + this.regX) & 0xff;\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n // A = A | ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA |= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opORAzp()\n { // opcode 0x05\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // A = A | ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA |= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opASLzp()\n { // opcode 0x06\n // EA = BYTE(PC++);\n this.regEAWrite = this.abMem[this.regPC++];\n // RC = ML << 1;\n this.regRC = this.abMem[this.regEAWrite] << 1;\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opPHP()\n { // opcode 0x08\n this.regP = this.getRegP();\n // STACK(S--) = P;\n this.abMem[this.regS--] = this.regP;\n this.regS |= 0x100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opORAimm()\n { // opcode 0x09\n // EA = PC++;\n this.regEA = this.regPC++;\n // A = A | ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA |= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opASLacc()\n { // opcode 0x0a\n // RC = A << 1;\n this.regRC = this.regA << 1;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opORAabs()\n { // opcode 0x0d\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // A = A | ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA |= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opASLabs()\n { // opcode 0x0e\n // EA = WORD(PC); PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // RC = ML << 1;\n this.regRC = this.abMem[this.regEAWrite] << 1;\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opBPL()\n { // opcode 0x10\n // PC = PC + (LAZY_N == 0? SBYTE(PC) : 0) + 1;\n this.regPC += (!(this.regRN & 0x80)? (this.nStepCycles--,((this.abMem[this.regPC] << 24) >> 24)) : 0) + 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opORAindy()\n { // opcode 0x11\n // EA = WORD(BYTE(PC++))+Y;\n this.regEA = (this.abMem[this.regPC++]);\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8)) + this.regY;\n // A = A | ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA |= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opORAzpx()\n { // opcode 0x15\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // A = A | ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA |= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opASLzpx()\n { // opcode 0x16\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEAWrite = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // RC = ML << 1;\n this.regRC = this.abMem[this.regEAWrite] << 1;\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opCLC()\n { // opcode 0x18\n // SET_LAZY_C(0);\n this.regRC = 0x00;\n }\n\n /**\n * @this {C1PCPU}\n */\n opORAabsy()\n { // opcode 0x19\n // EA = WORD(PC)+Y; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // A = A | ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regA |= this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opORAabsx()\n { // opcode 0x1d\n // EA = WORD(PC)+X; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // A = A | ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regA |= this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opASLabsx()\n { // opcode 0x1e\n // EA = WORD(PC)+X; PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // RC = ML << 1;\n this.regRC = this.abMem[this.regEAWrite] << 1;\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opJSRabs()\n { // opcode 0x20\n // EA = PC; PC += 1;\n this.regEA = this.regPC++;\n // STACK(S--) = PCH;\n this.abMem[this.regS--] = (this.regPC >> 8);\n this.regS |= 0x100;\n // STACK(S--) = PCL;\n this.abMem[this.regS--] = (this.regPC & 0xff);\n this.regS |= 0x100;\n // PC = M;\n this.regPC = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n }\n\n /**\n * @this {C1PCPU}\n */\n opANDindx()\n { // opcode 0x21\n // EA = WORD((BYTE(PC++)+X) & 0xff);\n this.regEA = ((this.abMem[this.regPC++]) + this.regX) & 0xff;\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n // A = A & ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA &= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opBITzp()\n { // opcode 0x24\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // SET_LAZY_Z((A & ML) == 0);\n this.regRZ = (this.regA & this.abMem[this.regEA]);\n // SET_LAZY_N(ML7);\n this.regRN = ((this.regRN & 0x7f) | (this.abMem[this.regEA] & 0x80));\n // SET_LAZY_V(ML6);\n this.regRV = 0; this.regRU = ((this.abMem[this.regEA] & 0x40)? 0x80 : 0x00);\n }\n\n /**\n * @this {C1PCPU}\n */\n opANDzp()\n { // opcode 0x25\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // A = A & ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA &= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opROLzp()\n { // opcode 0x26\n // EA = BYTE(PC++);\n this.regEAWrite = this.abMem[this.regPC++];\n // RCL = ML;\n this.regRC = ((this.regRC & 0xff00) | this.abMem[this.regEAWrite]);\n // RC = RC << 1;\n this.regRC <<= 1;\n // RCL0 = RCH1;\n this.regRC = ((this.regRC & 0xfffe) | (((this.regRC & 0x0200))? 0x0001 : 0));\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opPLP()\n { // opcode 0x28\n // P = STACK(++S);\n this.regS = ((this.regS+1) & 0xff) | 0x100;\n this.regP = this.abMem[this.regS];\n // SET_LAZY_C(C);\n this.regRC = ((this.regP & 0x01)? 0x0100 : 0);\n // SET_LAZY_Z(Z);\n this.regRZ = (!(this.regP & 0x02)? 0x01 : 0);\n // SET_LAZY_N(N);\n this.regRN = (this.regP & 0x80);\n // SET_LAZY_V(V);\n this.regRV = 0; this.regRU = ((this.regP & 0x40)? 0x80 : 0x00);\n }\n\n /**\n * @this {C1PCPU}\n */\n opANDimm()\n { // opcode 0x29\n // EA = PC++;\n this.regEA = this.regPC++;\n // A = A & ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA &= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opROLacc()\n { // opcode 0x2a\n // RCL = A;\n this.regRC = ((this.regRC & 0xff00) | this.regA);\n // RC = RC << 1;\n this.regRC <<= 1;\n // RCL0 = RCH1;\n this.regRC = ((this.regRC & 0xfffe) | ((this.regRC & 0x0200)? 0x0001 : 0));\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opBITabs()\n { // opcode 0x2c\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // SET_LAZY_Z((A & ML) == 0);\n this.regRZ = (this.regA & this.abMem[this.regEA]);\n // SET_LAZY_N(ML7);\n this.regRN = ((this.regRN & 0x7f) | (this.abMem[this.regEA] & 0x80));\n // SET_LAZY_V(ML6);\n this.regRV = 0; this.regRU = ((this.abMem[this.regEA] & 0x40)? 0x80 : 0x00);\n }\n\n /**\n * @this {C1PCPU}\n */\n opANDabs()\n { // opcode 0x2d\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // A = A & ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA &= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opROLabs()\n { // opcode 0x2e\n // EA = WORD(PC); PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // RCL = ML;\n this.regRC = ((this.regRC & 0xff00) | this.abMem[this.regEAWrite]);\n // RC = RC << 1;\n this.regRC <<= 1;\n // RCL0 = RCH1;\n this.regRC = ((this.regRC & 0xfffe) | (((this.regRC & 0x0200))? 0x0001 : 0));\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opBMI()\n { // opcode 0x30\n // PC = PC + (LAZY_N != 0? SBYTE(PC) : 0) + 1;\n this.regPC += ((this.regRN & 0x80)? (this.nStepCycles--,((this.abMem[this.regPC] << 24) >> 24)) : 0) + 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opANDindy()\n { // opcode 0x31\n // EA = WORD(BYTE(PC++))+Y;\n this.regEA = (this.abMem[this.regPC++]);\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8)) + this.regY;\n // A = A & ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA &= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opANDzpx()\n { // opcode 0x35\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // A = A & ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA &= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opROLzpx()\n { // opcode 0x36\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEAWrite = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // RCL = ML;\n this.regRC = ((this.regRC & 0xff00) | this.abMem[this.regEAWrite]);\n // RC = RC << 1;\n this.regRC <<= 1;\n // RCL0 = RCH1;\n this.regRC = ((this.regRC & 0xfffe) | (((this.regRC & 0x0200))? 0x0001 : 0));\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opSEC()\n { // opcode 0x38\n // SET_LAZY_C(1);\n this.regRC = 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opANDabsy()\n { // opcode 0x39\n // EA = WORD(PC)+Y; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // A = A & ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA &= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opANDabsx()\n { // opcode 0x3d\n // EA = WORD(PC)+X; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // A = A & ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA &= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opROLabsx()\n { // opcode 0x3e\n // EA = WORD(PC)+X; PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // RCL = ML;\n this.regRC = ((this.regRC & 0xff00) | this.abMem[this.regEAWrite]);\n // RC = RC << 1;\n this.regRC <<= 1;\n // RCL0 = RCH1;\n this.regRC = ((this.regRC & 0xfffe) | (((this.regRC & 0x0200))? 0x0001 : 0));\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opRTI()\n { // opcode 0x40\n // P = STACK(++S);\n this.regS = ((this.regS+1) & 0xff) | 0x100;\n this.regP = this.abMem[this.regS];\n // SET_LAZY_C(C);\n this.regRC = ((this.regP & 0x01)? 0x0100 : 0);\n // SET_LAZY_Z(Z);\n this.regRZ = (!(this.regP & 0x02)? 0x01 : 0);\n // SET_LAZY_N(N);\n this.regRN = (this.regP & 0x80);\n // SET_LAZY_V(V);\n this.regRV = 0; this.regRU = ((this.regP & 0x40)? 0x80 : 0x00);\n // PCL = STACK(++S);\n // PCH = STACK(++S);\n this.regS = ((this.regS+2) & 0xff) | 0x100;\n this.regPC = (this.abMem[(this.regS-1) | 0x100]) | (this.abMem[this.regS] << 8);\n }\n\n /**\n * @this {C1PCPU}\n */\n opEORindx()\n { // opcode 0x41\n // EA = WORD((BYTE(PC++)+X) & 0xff);\n this.regEA = ((this.abMem[this.regPC++]) + this.regX) & 0xff;\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n // A = A ^ ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA ^= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opEORzp()\n { // opcode 0x45\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // A = A ^ ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA ^= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opLSRzp()\n { // opcode 0x46\n // EA = BYTE(PC++);\n this.regEAWrite = this.abMem[this.regPC++];\n // SET_LAZY_C(ML0);\n this.regRC = ((this.regRC & 0xfeff) | ((this.abMem[this.regEAWrite] & 0x01)? 0x0100 : 0));\n // ML = RCL = ML >> 1;\n this.abMem[this.regEAWrite] = ((this.regRC = ((this.regRC & 0xff00) | (this.abMem[this.regEAWrite] >> 1))) & 0xff);\n // SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = (this.regRC & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opPHA()\n { // opcode 0x48\n // STACK(S--) = A;\n this.abMem[this.regS--] = this.regA;\n this.regS |= 0x100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opEORimm()\n { // opcode 0x49\n // EA = PC++;\n this.regEA = this.regPC++;\n // A = A ^ ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA ^= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opLSRacc()\n { // opcode 0x4a\n // SET_LAZY_C( A0);\n this.regRC = ((this.regRC & 0xfeff) | ((this.regA & 0x01)? 0x0100 : 0));\n // A = RCL = A >> 1;\n this.regA = ((this.regRC = ((this.regRC & 0xff00) | (this.regA >> 1))) & 0xff);\n // SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opJMPimm16()\n { // opcode 0x4c\n // EA = PC;\n this.regEA = this.regPC;\n // PC += 2;\n // this.regPC += 2;\n // PC = M;\n this.regPC = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n }\n\n /**\n * @this {C1PCPU}\n */\n opEORabs()\n { // opcode 0x4d\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // A = A ^ ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA ^= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opLSRabs()\n { // opcode 0x4e\n // EA = WORD(PC); PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // SET_LAZY_C(ML0);\n this.regRC = ((this.regRC & 0xfeff) | ((this.abMem[this.regEAWrite] & 0x01)? 0x0100 : 0));\n // ML = RCL = ML >> 1;\n this.abMem[this.regEAWrite] = ((this.regRC = ((this.regRC & 0xff00) | (this.abMem[this.regEAWrite] >> 1))) & 0xff);\n // SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = (this.regRC & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opBVC()\n { // opcode 0x50\n // PC = PC + (LAZY_V == 0? SBYTE(PC) : 0) + 1;\n this.regPC += (!((((this.regRV & 0xff) ^ this.regRU) ^ (this.regRV >> 1)) & 0x80)? (this.nStepCycles--,((this.abMem[this.regPC] << 24) >> 24)) : 0) + 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opEORindy()\n { // opcode 0x51\n // EA = WORD(BYTE(PC++))+Y;\n this.regEA = this.abMem[this.regPC++];\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8)) + this.regY;\n // A = A ^ ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA ^= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opEORzpx()\n { // opcode 0x55\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // A = A ^ ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA ^= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opLSRzpx()\n { // opcode 0x56\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEAWrite = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // SET_LAZY_C(ML0);\n this.regRC = ((this.regRC & 0xfeff) | ((this.abMem[this.regEAWrite] & 0x01)? 0x0100 : 0));\n // ML = RCL = ML >> 1;\n this.abMem[this.regEAWrite] = ((this.regRC = ((this.regRC & 0xff00) | (this.abMem[this.regEAWrite] >> 1))) & 0xff);\n // SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = (this.regRC & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opCLI()\n { // opcode 0x58\n // I = 0;\n this.regP &= 0xfb;\n }\n\n /**\n * @this {C1PCPU}\n */\n opEORabsy()\n { // opcode 0x59\n // EA = WORD(PC)+Y; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // A = A ^ ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = (this.regA ^= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opEORabsx()\n { // opcode 0x5d\n // EA = WORD(PC)+X; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // A = A ^ ML; SET_LAZY_NZ(A)\n this.regRN = this.regRZ = (this.regA ^= this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opLSRabsx()\n { // opcode 0x5e\n // EA = WORD(PC)+X; PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // SET_LAZY_C(ML0);\n this.regRC = ((this.regRC & 0xfeff) | ((this.abMem[this.regEAWrite] & 0x01)? 0x0100 : 0));\n // ML = RCL = ML >> 1;\n this.abMem[this.regEAWrite] = ((this.regRC = ((this.regRC & 0xff00) | (this.abMem[this.regEAWrite] >> 1))) & 0xff);\n // SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = (this.regRC & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opRTS()\n { // opcode 0x60\n // PCL = STACK(++S);\n // PCH = STACK(++S);\n // PC++;\n this.regS = ((this.regS+2) & 0xff) | 0x100;\n this.regPC = (((this.abMem[(this.regS-1) | 0x100])) | ((this.abMem[this.regS]) << 8)) + 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCindx()\n { // opcode 0x61\n // EA = WORD((BYTE(PC++)+X) & 0xff);\n this.regEA = ((this.abMem[this.regPC++]) + this.regX) & 0xff;\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n // RC = (A + ML + LAZY_C);\n this.regRC = (this.regA + this.abMem[this.regEA] + ((this.regRC & 0x0100)? 1 : 0));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCindxBCD()\n { // opcode 0x61\n // EA = WORD((BYTE(PC++)+X) & 0xff);\n this.regEA = ((this.abMem[this.regPC++]) + this.regX) & 0xff;\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n // A = this.addBCD(A,ML);\n this.regA = this.addBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCzp()\n { // opcode 0x65\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // RC = (A + ML + LAZY_C);\n this.regRC = (this.regA + this.abMem[this.regEA] + ((this.regRC & 0x0100)? 1 : 0));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCzpBCD()\n { // opcode 0x65\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // A = this.addBCD(A,ML);\n this.regA = this.addBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opRORzp()\n { // opcode 0x66\n // EA = BYTE(PC++);\n this.regEAWrite = this.abMem[this.regPC++];\n // RCL = ML;\n this.regRC = ((this.regRC & 0xff00) | this.abMem[this.regEAWrite]);\n // RCH1 = RCL0;\n this.regRC = ((this.regRC & 0xfdff) | ((this.regRC & 0x0001)? 0x0200 : 0));\n // RC = RC >> 1;\n this.regRC >>= 1;\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opPLA()\n { // opcode 0x68\n // A = STACK(++S); SET_LAZY_NZ(A);\n this.regS = ((this.regS+1) & 0xff) | 0x100;\n this.regRN = this.regRZ = this.regA = this.abMem[this.regS];\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCimm()\n { // opcode 0x69\n // EA = PC++;\n this.regEA = this.regPC++;\n // RC = (A + ML + LAZY_C);\n this.regRC = (this.regA + this.abMem[this.regEA] + ((this.regRC & 0x0100)? 1 : 0));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCimmBCD()\n { // opcode 0x69\n // EA = PC++;\n this.regEA = this.regPC++;\n // A = this.addBCD(A,ML);\n this.regA = this.addBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opRORacc()\n { // opcode 0x6a\n // RCL = A;\n this.regRC = ((this.regRC & 0xff00) | this.regA);\n // RCH1 = RCL0;\n this.regRC = ((this.regRC & 0xfdff) | ((this.regRC & 0x0001)? 0x0200 : 0));\n // RC = RC >> 1;\n this.regRC >>= 1;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n *\n * NOTE from Wikipedia: \"The 6502's memory indirect jump instruction, JMP (<address>), is partially broken.\n * If <address> is hex xxFF (i.e., any word ending in FF), the processor will not jump to the address stored in xxFF and xxFF+1 as expected,\n * but rather the one defined by xxFF and xx00. This defect continued through the entire NMOS line, but was corrected in the CMOS derivatives.\"\n */\n opJMPabs16()\n { // opcode 0x6c\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // PC = M;\n this.regPC = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCabs()\n { // opcode 0x6d\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // RC = (A + ML + LAZY_C);\n this.regRC =(this.regA + this.abMem[this.regEA] + ((this.regRC & 0x0100)? 1 : 0));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCabsBCD()\n { // opcode 0x6d\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // A = this.addBCD(A,ML);\n this.regA = this.addBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opRORabs()\n { // opcode 0x6e\n // EA = WORD(PC); PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // RCL = ML;\n this.regRC = ((this.regRC & 0xff00) | this.abMem[this.regEAWrite]);\n // RCH1 = RCL0;\n this.regRC = ((this.regRC & 0xfdff) | ((this.regRC & 0x0001)? 0x0200 : 0));\n // RC = RC >> 1;\n this.regRC >>= 1;\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opBVS()\n { // opcode 0x70\n // PC = PC + (LAZY_V != 0? SBYTE(PC) : 0) + 1;\n this.regPC += (((((this.regRV & 0xff) ^ this.regRU) ^ (this.regRV >> 1)) & 0x80)? (this.nStepCycles--,((this.abMem[this.regPC] << 24) >> 24)) : 0) + 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCindy()\n { // opcode 0x71\n // EA = WORD(BYTE(PC++))+Y;\n this.regEA = (this.abMem[this.regPC++]);\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8)) + this.regY;\n // RC = (A + ML + LAZY_C);\n this.regRC = (this.regA + this.abMem[this.regEA] + ((this.regRC & 0x0100)? 1 : 0));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCindyBCD()\n { // opcode 0x71\n // EA = WORD(BYTE(PC++))+Y;\n this.regEA = (this.abMem[this.regPC++]);\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8)) + this.regY;\n // A = this.addBCD(A,ML);\n this.regA = this.addBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCzpx()\n { // opcode 0x75\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // RC = (A + ML + LAZY_C);\n this.regRC = (this.regA + this.abMem[this.regEA] + ((this.regRC & 0x0100)? 1 : 0));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCzpxBCD()\n { // opcode 0x75\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // A = this.addBCD(A,ML);\n this.regA = this.addBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opRORzpx()\n { // opcode 0x76\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEAWrite = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // RCL = ML;\n this.regRC = ((this.regRC & 0xff00) | this.abMem[this.regEAWrite]);\n // RCH1 = RCL0;\n this.regRC = ((this.regRC & 0xfdff) | ((this.regRC & 0x0001)? 0x0200 : 0));\n // RC = RC >> 1;\n this.regRC >>= 1;\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opSEI()\n { // opcode 0x78\n // I = 1;\n this.regP |= 0x04;\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCabsy()\n { // opcode 0x79\n // EA = WORD(PC)+Y; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // RC = (A + ML + LAZY_C);\n this.regRC = (this.regA + this.abMem[this.regEA] + ((this.regRC & 0x0100)? 1 : 0));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCabsyBCD()\n { // opcode 0x79\n // EA = WORD(PC)+Y; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // A = this.addBCD(A,ML);\n this.regA = this.addBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCabsx()\n { // opcode 0x7d\n // EA = WORD(PC)+X; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // RC = (A + ML + LAZY_C);\n this.regRC = (this.regA + this.abMem[this.regEA] + ((this.regRC & 0x0100)? 1 : 0));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opADCabsxBCD()\n { // opcode 0x7d\n // EA = WORD(PC)+X; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // A = this.addBCD(A,ML);\n this.regA = this.addBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opRORabsx()\n { // opcode 0x7e\n // EA = WORD(PC)+X; PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // RCL = ML;\n this.regRC = ((this.regRC & 0xff00) | this.abMem[this.regEAWrite]);\n // RCH1 = RCL0;\n this.regRC = ((this.regRC & 0xfdff) | ((this.regRC & 0x0001)? 0x0200 : 0));\n // RC = RC >> 1;\n this.regRC >>= 1;\n // ML = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = (this.regRC & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTAindx()\n { // opcode 0x81\n // EA = WORD((BYTE(PC++)+X) & 0xff);\n this.regEAWrite = ((this.abMem[this.regPC++]) + this.regX) & 0xff;\n this.regEAWrite = (this.abMem[this.regEAWrite] | (this.abMem[this.regEAWrite+1] << 8));\n // ML = A;\n this.abMem[this.regEAWrite] = this.regA;\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTYzp()\n { // opcode 0x84\n // EA = BYTE(PC++);\n this.regEAWrite = this.abMem[this.regPC++];\n // ML = Y;\n this.abMem[this.regEAWrite] = this.regY;\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTAzp()\n { // opcode 0x85\n // EA = BYTE(PC++);\n this.regEAWrite = this.abMem[this.regPC++];\n // ML = A;\n this.abMem[this.regEAWrite] = this.regA;\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTXzp()\n { // opcode 0x86\n // EA = BYTE(PC++);\n this.regEAWrite = this.abMem[this.regPC++];\n // ML = X;\n this.abMem[this.regEAWrite] = this.regX;\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opDEY()\n { // opcode 0x88\n // Y = ((Y - 1) & 0xff);\n this.regY = ((this.regY - 1) & 0xff);\n // SET_LAZY_NZ(Y);\n this.regRN = this.regRZ = (this.regY);\n }\n\n /**\n * @this {C1PCPU}\n */\n opTXA()\n { // opcode 0x8a\n // A = X; SET_LAZY_NZ(X);\n this.regRN = this.regRZ = this.regA = this.regX;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTYabs()\n { // opcode 0x8c\n // EA = WORD(PC); PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // ML = Y;\n this.abMem[this.regEAWrite] = this.regY;\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTAabs()\n { // opcode 0x8d\n // EA = WORD(PC); PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // ML = A;\n this.abMem[this.regEAWrite] = this.regA;\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTXabs()\n { // opcode 0x8e\n // EA = WORD(PC); PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // ML = X;\n this.abMem[this.regEAWrite] = this.regX;\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opBCC()\n { // opcode 0x90\n // PC = PC + (LAZY_C == 0? SBYTE(PC) : 0) + 1;\n this.regPC += (!(this.regRC & 0x0100)? (this.nStepCycles--,((this.abMem[this.regPC] << 24) >> 24)) : 0) + 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTAindy()\n { // opcode 0x91\n // EA = WORD(BYTE(PC++))+Y;\n this.regEAWrite = (this.abMem[this.regPC++]);\n this.regEAWrite = (this.abMem[this.regEAWrite] | (this.abMem[this.regEAWrite+1] << 8)) + this.regY;\n // ML = A;\n this.abMem[this.regEAWrite] = this.regA;\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTYzpx()\n { // opcode 0x94\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEAWrite = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // ML = Y;\n this.abMem[this.regEAWrite] = this.regY;\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTAzpx()\n { // opcode 0x95\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEAWrite = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // ML = A;\n this.abMem[this.regEAWrite] = this.regA;\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTXzpy()\n { // opcode 0x96\n // EA = (BYTE(PC++)+Y) & 0xff;\n this.regEAWrite = (this.abMem[this.regPC++]+this.regY) & 0xff;\n // ML = X;\n this.abMem[this.regEAWrite] = this.regX;\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opTYA()\n { // opcode 0x98\n // A = Y; SET_LAZY_NZ(Y);\n this.regRN = this.regRZ = this.regA = this.regY;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTAabsy()\n { // opcode 0x99\n // EA = WORD(PC)+Y; PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // ML = A;\n this.abMem[this.regEAWrite] = this.regA;\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opTXS()\n { // opcode 0x9a\n // S = X;\n this.regS = this.regX | 0x100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSTAabsx()\n { // opcode 0x9d\n // EA = WORD(PC)+X; PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // ML = A;\n this.abMem[this.regEAWrite] = this.regA;\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDYimm()\n { // opcode 0xa0\n // EA = PC++;\n this.regEA = this.regPC++;\n // Y = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regY = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDAindx()\n { // opcode 0xa1\n // EA = WORD((BYTE(PC++)+X) & 0xff);\n this.regEA = ((this.abMem[this.regPC++]) + this.regX) & 0xff;\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n // A = ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regA = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDXimm()\n { // opcode 0xa2\n // EA = PC++;\n this.regEA = this.regPC++;\n // X = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regX = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDYzp()\n { // opcode 0xa4\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // Y = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regY = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDAzp()\n { // opcode 0xa5\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // A = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regA = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDXzp()\n { // opcode 0xa6\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // X = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regX = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opTAY()\n { // opcode 0xa8\n // Y = A; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regY = this.regA;\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDAimm()\n { // opcode 0xa9\n // EA = PC++;\n this.regEA = this.regPC++;\n // A = ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regA = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opTAX()\n { // opcode 0xaa\n // X = A; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regX = this.regA;\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDYabs()\n { // opcode 0xac\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // Y = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regY = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDAabs()\n { // opcode 0xad\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // A = ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regA = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDXabs()\n { // opcode 0xae\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // X = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regX = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opBCS()\n { // opcode 0xb0\n // PC = PC + (LAZY_C != 0? SBYTE(PC) : 0) + 1;\n this.regPC += ((this.regRC & 0x0100)? (this.nStepCycles--,((this.abMem[this.regPC] << 24) >> 24)) : 0) + 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDAindy()\n { // opcode 0xb1\n // EA = WORD(BYTE(PC++))+Y;\n this.regEA = (this.abMem[this.regPC++]);\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8)) + this.regY;\n // A = ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regA = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDYzpx()\n { // opcode 0xb4\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // Y = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regY = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDAzpx()\n { // opcode 0xb5\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // A = ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regA = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDXzpy()\n { // opcode 0xb6\n // EA = (BYTE(PC++)+Y) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regY) & 0xff;\n // X = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regX = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opCLV()\n { // opcode 0xb8\n // SET_LAZY_V(0);\n this.regRV = 0; this.regRU = 0;\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDAabsy()\n { // opcode 0xb9\n // EA = WORD(PC)+Y; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // A = ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regA = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opTSX()\n { // opcode 0xba\n // X = S; SET_LAZY_NZ(S);\n this.regRN = this.regRZ = this.regX = this.regS & 0xff;\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDYabsx()\n { // opcode 0xbc\n // EA = WORD(PC)+X; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // Y = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regY = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDAabsx()\n { // opcode 0xbd\n // EA = WORD(PC)+X; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // A = ML; SET_LAZY_NZ(A);\n this.regRN = this.regRZ = this.regA = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opLDXabsy()\n { // opcode 0xbe\n // EA = WORD(PC)+Y; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // X = ML; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.regX = this.abMem[this.regEA];\n }\n\n /**\n * @this {C1PCPU}\n */\n opCPYimm()\n { // opcode 0xc0\n // EA = PC++;\n this.regEA = this.regPC++;\n // RC = Y - ML;\n this.regRC = this.regY - this.abMem[this.regEA];\n // SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = (this.regRC);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opCMPindx()\n { // opcode 0xc1\n // EA = WORD((BYTE(PC++)+X) & 0xff);\n this.regEA = ((this.abMem[this.regPC++]) + this.regX) & 0xff;\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n // RC = A - ML; SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = this.regRC = (this.regA - this.abMem[this.regEA]);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opCPYzp()\n { // opcode 0xc4\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // RC = Y - ML;\n this.regRC = this.regY - this.abMem[this.regEA];\n // SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = (this.regRC);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opCMPzp()\n { // opcode 0xc5\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // RC = A - ML; SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = this.regRC = (this.regA - this.abMem[this.regEA]);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opDECzp()\n { // opcode 0xc6\n // EA = BYTE(PC++);\n this.regEAWrite = this.abMem[this.regPC++];\n // ML = ML - 1; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = ((this.abMem[this.regEAWrite] - 1) & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opINY()\n { // opcode 0xc8\n // Y = ((Y + 1) & 0xff);\n this.regY = ((this.regY + 1) & 0xff);\n // SET_LAZY_NZ(Y);\n this.regRN = this.regRZ = (this.regY);\n }\n\n /**\n * @this {C1PCPU}\n */\n opCMPimm()\n { // opcode 0xc9\n // EA = PC++;\n this.regEA = this.regPC++;\n // RC = A - ML; SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = this.regRC = (this.regA - this.abMem[this.regEA]);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opDEX()\n { // opcode 0xca\n // X = ((X - 1) & 0xff); SET_LAZY_NZ(X);\n this.regRN = this.regRZ = this.regX = ((this.regX - 1) & 0xff);\n }\n\n /**\n * @this {C1PCPU}\n */\n opCPYabs()\n { // opcode 0xcc\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // RC = Y - ML; SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = this.regRC = this.regY - this.abMem[this.regEA];\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opCMPabs()\n { // opcode 0xcd\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // RC = A - ML; SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = this.regRC = (this.regA - this.abMem[this.regEA]);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opDECabs()\n { // opcode 0xce\n // EA = WORD(PC); PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // ML = ML - 1; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = ((this.abMem[this.regEAWrite] - 1) & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opBNE()\n { // opcode 0xd0\n // PC = PC + (LAZY_Z == 0? SBYTE(PC) : 0) + 1;\n this.regPC += ((this.regRZ & 0xff)? (this.nStepCycles--,((this.abMem[this.regPC] << 24) >> 24)) : 0) + 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opCMPindy()\n { // opcode 0xd1\n // EA = WORD(BYTE(PC++))+Y;\n this.regEA = (this.abMem[this.regPC++]);\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8)) + this.regY;\n // RC = A - ML; SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = this.regRC = (this.regA - this.abMem[this.regEA]);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opCMPzpx()\n { // opcode 0xd5\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // RC = A - ML; SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = this.regRC = (this.regA - this.abMem[this.regEA]);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opDECzpx()\n { // opcode 0xd6\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEAWrite = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // ML = ML - 1; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = ((this.abMem[this.regEAWrite] - 1) & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opCLD()\n { // opcode 0xd8\n // D = 0;\n this.clearBCD();\n }\n\n /**\n * @this {C1PCPU}\n */\n opCMPabsy()\n { // opcode 0xd9\n // EA = WORD(PC)+Y; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // RC = A - ML; SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = this.regRC = (this.regA - this.abMem[this.regEA]);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opCMPabsx()\n { // opcode 0xdd\n // EA = WORD(PC)+X; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // RC = A - ML; SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = this.regRC = (this.regA - this.abMem[this.regEA]);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opDECabsx()\n { // opcode 0xde\n // EA = WORD(PC)+X; PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // ML = ML - 1; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = ((this.abMem[this.regEAWrite] - 1) & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opCPXimm()\n { // opcode 0xe0\n // EA = PC++;\n this.regEA = this.regPC++;\n // RC = X - ML;\n this.regRC = this.regX - this.abMem[this.regEA];\n // SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = (this.regRC);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCindx()\n { // opcode 0xe1\n // EA = WORD((BYTE(PC++)+X) & 0xff);\n this.regEA = ((this.abMem[this.regPC++]) + this.regX) & 0xff;\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n // RC = (A - ML - !LAZY_C);\n this.regRC = (this.regA - this.abMem[this.regEA] - ((this.regRC & 0x0100)? 0 : 1));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCindxBCD()\n { // opcode 0xe1\n // EA = WORD((BYTE(PC++)+X) & 0xff);\n this.regEA = ((this.abMem[this.regPC++]) + this.regX) & 0xff;\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8));\n // A = this.subBCD(A,ML);\n this.regA = this.subBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opCPXzp()\n { // opcode 0xe4\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // RC = X - ML;\n this.regRC = this.regX - this.abMem[this.regEA];\n // SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = (this.regRC);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCzp()\n { // opcode 0xe5\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // RC = (A - ML - !LAZY_C);\n this.regRC = (this.regA - this.abMem[this.regEA] - ((this.regRC & 0x0100)? 0 : 1));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCzpBCD()\n { // opcode 0xe5\n // EA = BYTE(PC++);\n this.regEA = this.abMem[this.regPC++];\n // A = this.subBCD(A,ML);\n this.regA = this.subBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opINCzp()\n { // opcode 0xe6\n // EA = BYTE(PC++);\n this.regEAWrite = this.abMem[this.regPC++];\n // ML = ML + 1; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = ((this.abMem[this.regEAWrite] + 1) & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opINX()\n { // opcode 0xe8\n // X = ((X + 1) & 0xff);\n this.regX = ((this.regX + 1) & 0xff);\n // SET_LAZY_NZ(X);\n this.regRN = this.regRZ = (this.regX);\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCimm()\n { // opcode 0xe9\n // EA = PC++;\n this.regEA = this.regPC++;\n // RC = (A - ML - !LAZY_C);\n this.regRC = (this.regA - this.abMem[this.regEA] - ((this.regRC & 0x0100)? 0 : 1));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCimmBCD()\n { // opcode 0xe9\n // EA = PC++;\n this.regEA = this.regPC++;\n // A = this.subBCD(A,ML);\n this.regA = this.subBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opNOP()\n { // opcode 0xea\n //\n }\n\n /**\n * @this {C1PCPU}\n */\n opCPXabs()\n { // opcode 0xec\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // RC = X - ML; SET_LAZY_NZ(RC);\n this.regRN = this.regRZ = this.regRC = this.regX - this.abMem[this.regEA];\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCabs()\n { // opcode 0xed\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // RC = (A - ML - !LAZY_C);\n this.regRC = (this.regA - this.abMem[this.regEA] - ((this.regRC & 0x0100)? 0 : 1));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCabsBCD()\n { // opcode 0xed\n // EA = WORD(PC); PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // A = this.subBCD(A,ML);\n this.regA = this.subBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opINCabs()\n { // opcode 0xee\n // EA = WORD(PC); PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n // ML = ML + 1; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = ((this.abMem[this.regEAWrite] + 1) & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opBEQ()\n { // opcode 0xf0\n // PC = PC + (LAZY_Z == 1? SBYTE(PC) : 0) + 1;\n this.regPC += (!(this.regRZ & 0xff)? (this.nStepCycles--,((this.abMem[this.regPC] << 24) >> 24)) : 0) + 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCindy()\n { // opcode 0xf1\n // EA = WORD(BYTE(PC++))+Y;\n this.regEA = (this.abMem[this.regPC++]);\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8)) + this.regY;\n // RC = (A - ML - !LAZY_C);\n this.regRC = (this.regA - this.abMem[this.regEA] - ((this.regRC & 0x0100)? 0 : 1));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCindyBCD()\n { // opcode 0xf1\n // EA = WORD(BYTE(PC++))+Y;\n this.regEA = (this.abMem[this.regPC++]);\n this.regEA = (this.abMem[this.regEA] | (this.abMem[this.regEA+1] << 8)) + this.regY;\n // A = this.subBCD(A,ML);\n this.regA = this.subBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCzpx()\n { // opcode 0xf5\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // RC = (A - ML - !LAZY_C);\n this.regRC = (this.regA - this.abMem[this.regEA] - ((this.regRC & 0x0100)? 0 : 1));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCzpxBCD()\n { // opcode 0xf5\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEA = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // A = this.subBCD(A,ML);\n this.regA = this.subBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opINCzpx()\n { // opcode 0xf6\n // EA = (BYTE(PC++)+X) & 0xff;\n this.regEAWrite = (this.abMem[this.regPC++]+this.regX) & 0xff;\n // ML = ML + 1; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = ((this.abMem[this.regEAWrite] + 1) & 0xff);\n // W = 1;\n // NOTE: Consider alternatives for tracking zero-page writes (eg, regEAWriteZP)\n }\n\n /**\n * @this {C1PCPU}\n */\n opSED()\n { // opcode 0xf8\n // D = 1;\n this.setBCD();\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCabsy()\n { // opcode 0xf9\n // EA = WORD(PC)+Y; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // RC = (A - ML - !LAZY_C);\n this.regRC = (this.regA - this.abMem[this.regEA] - ((this.regRC & 0x0100)? 0 : 1));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCabsyBCD()\n { // opcode 0xf9\n // EA = WORD(PC)+Y; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regY;\n // A = this.subBCD(A,ML);\n this.regA = this.subBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCabsx()\n { // opcode 0xfd\n // EA = WORD(PC)+X; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // RC = (A - ML - !LAZY_C);\n this.regRC = (this.regA - this.abMem[this.regEA] - ((this.regRC & 0x0100)? 0 : 1));\n // SET_LAZY_OV(A,ML,RC);\n this.regRU = this.regA ^ this.abMem[this.regEA]; this.regRV = this.regRC;\n // A = RCL; SET_LAZY_NZ(RCL);\n this.regRN = this.regRZ = this.regA = (this.regRC & 0xff);\n // SET_LAZY_C(!LAZY_C);\n this.regRC ^= 0x0100;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSBCabsxBCD()\n { // opcode 0xfd\n // EA = WORD(PC)+X; PC += 2;\n this.regEA = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // A = this.subBCD(A,ML);\n this.regA = this.subBCD(this.regA, this.abMem[this.regEA]);\n }\n\n /**\n * @this {C1PCPU}\n */\n opINCabsx()\n { // opcode 0xfe\n // EA = WORD(PC)+X; PC += 2;\n this.regEAWrite = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8)) + this.regX;\n // ML = ML + 1; SET_LAZY_NZ(ML);\n this.regRN = this.regRZ = this.abMem[this.regEAWrite] = ((this.abMem[this.regEAWrite] + 1) & 0xff);\n // W = 1;\n }\n\n /**\n * @this {C1PCPU}\n */\n opSim()\n {\n var addr;\n var bSimOp = this.abMem[this.regPC++];\n switch(bSimOp) {\n\n case this.SIMOP_HLT:\n this.println(\"HALT\");\n this.halt();\n break;\n\n case this.SIMOP_MSG:\n addr = this.regPC; // currently we're using \"inline\" strings\n // addr = (this.abMem[this.regPC++] | (this.abMem[this.regPC++] << 8));\n var s = \"\";\n while (addr < this.abMem.length) {\n var b = this.abMem[addr++];\n if (!b) break;\n s += String.fromCharCode(b);\n }\n this.regPC = addr; // update regPC as long as we're doing \"inline\" strings\n /*\n * Before simply printing the string, what kinds of handy substitutions should we provide?\n *\n * eg: %A for this.regA, %X for this.regX, etc\n */\n s = s.replace(/%A/g, Str.toHex(this.regA, 2)).replace(/%X/g, Str.toHex(this.regX, 2)).replace(/%Y/g, Str.toHex(this.regY, 2));\n this.println(s);\n /*\n * To make printing \"smoother\", let's force a yield\n */\n this.yieldCPU();\n break;\n\n default:\n this.regPC -= 2;\n this.println(\"undefined opSim: \" + Str.toHexByte(bSimOp) + \" at \" + Str.toHexWord(this.regPC));\n this.halt();\n }\n }\n\n /**\n * @this {C1PCPU}\n */\n opUndefined()\n {\n var b = this.abMem[--this.regPC];\n this.println(\"undefined opcode: \" + Str.toHexByte(b) + \" at \" + Str.toHexWord(this.regPC));\n this.halt();\n }\n\n /**\n * C1PCPU.init()\n *\n * This function operates on every HTML element of class \"cpu\", extracting the\n * JSON-encoded parameters for the C1PCPU constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a C1PCPU component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeCPUs = Component.getElementsByClass(document, C1PJS.APPCLASS, \"cpu\");\n for (var iCPU=0; iCPU < aeCPUs.length; iCPU++) {\n var eCPU = aeCPUs[iCPU];\n var parmsCPU = Component.getComponentParms(eCPU);\n var cpu = new C1PCPU(parmsCPU);\n Component.bindComponentControls(cpu, eCPU, C1PJS.APPCLASS);\n }\n }\n}\n\n/*\n * Macro reference (from my original 1998 C source code, preserved in the comments below):\n *\n * #define BYTE(a) (abMem[(a) & 0xffff])\n * #define WORD(a) (*(word *)&BYTE(a))\n * #define SBYTE(a) ((int)(char)BYTE(a))\n * #define STACK(a) BYTE(((a) & 0xff)+0x100)\n * #define M WORD(EA)\n * #define ML BYTE(EA+0)\n * #define MH BYTE(EA+1)\n * #define A (aRegs[0].value) // 8 bits\n * #define X (aRegs[1].value) // 8 bits\n * #define Y (aRegs[2].value) // 8 bits\n * #define S (aRegs[3].value) // 8 bits\n * #define P (aRegs[4].value) // 8 bits\n * #define RN (aRegs[5].value) // 8 bits\n * #define RZ (aRegs[6].value) // 8 bits\n * #define RU (aRegs[7].value) // 8 bits\n * #define RV (aRegs[8].value) // 16 bits\n * #define RC (aRegs[9].value) // 16 bits\n * #define EA (aRegs[10].value)// 16 bits\n * #define LA (aRegs[11].value)// 16 bits\n * #define PC (aRegs[12].value)// 16 bits\n * #define EF (aRegs[13].value)// 8 bits\n * #define C P0\n * #define Z P1\n * #define I P2\n * #define D P3\n * #define B P4\n * #define V P6\n * #define N P7\n * #define W EF0\n * #define LAZY_C (RCH0)\n * #define SET_LAZY_C(b) (RCH0 = (b))\n * #define LAZY_N (RN7)\n * #define SET_LAZY_N(b) (RN7 = (b))\n * #define SET_LAZY_NZ(v) (RN = RZ = (v))\n * #define LAZY_Z ((byte)RZ == 0)\n * #define SET_LAZY_Z(b) (RZ = !(b))\n * #define LAZY_V ((((RVL ^ RU) ^ (RV >> 1)) & 0x80) != 0)\n * #define SET_LAZY_V(b) (RV = 0, RU = ((b)? 0x80 : 0x00))\n * #define SET_LAZY_OV(a,b,r) (RU = (a) ^ (b), RV = (r))\n */\n\n/*\n * Initialize every CPU module on the page (as IF there's ever going to be more than one ;-))\n */\nWeb.onInit(C1PCPU.init);\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/rom.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass C1PROM extends Component {\n /**\n * C1PROM(parmsROM)\n *\n * The ROM component expects the following (parmsROM) properties:\n *\n * size: amount of ROM, in bytes\n * image: name of ROM image file\n *\n * NOTE: The final location for the ROM image, once loaded, will be specified\n * by the Computer object, using the setBuffer() method.\n *\n * @this {C1PROM}\n * @param {Object} parmsROM\n * @property {function()} convertImage\n */\n constructor(parmsROM)\n {\n super(\"C1PROM\", parmsROM);\n\n this.abMem = null;\n this.abImage = null;\n this.cbROM = parmsROM['size'];\n this.sImage = parmsROM['image'];\n if (this.sImage) {\n var sFileURL = this.sImage;\n /**\n * If the selected ROM image has a \".json\" extension, then we assume it's a pre-converted\n * JSON-encoded ROM image, so we load it as-is; ditto for files with a \".hex\" extension. Otherwise,\n * we ask our server-side ROM image converter to return the corresponding JSON-encoded data,\n * in compact form (ie, minimal whitespace, no ASCII data comments, etc).\n */\n var sFileExt = Str.getExtension(this.sImage);\n if (sFileExt != DumpAPI.FORMAT.JSON && sFileExt != DumpAPI.FORMAT.HEX) {\n sFileURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sImage + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES;\n }\n var rom = this;\n Web.getResource(sFileURL, null, true, function(sURL, sResponse, nErrorCode) {\n rom.convertImage(sURL, sResponse, nErrorCode);\n });\n }\n }\n\n /**\n * @this {C1PROM}\n * @param {Array} abMemory\n * @param {number} start\n * @param {number} end\n * @param {C1PCPU} cpu\n */\n setBuffer(abMemory, start, end, cpu)\n {\n this.abMem = abMemory;\n this.offROM = start;\n var cbROM = end - start + 1;\n /*\n * It's possible that the ROM component didn't specify a size,\n * in which case just use the size the Computer component has specified.\n */\n if (!this.cbROM)\n this.cbROM = cbROM;\n if (cbROM != this.cbROM) {\n this.setError(\"computer-specified ROM size (\" + Str.toHexWord(cbROM) + \") does not match component-specified size (\" + Str.toHexWord(this.cbROM) + \")\");\n return;\n }\n if (cpu) {\n this.cpu = cpu;\n cpu.addWriteNotify(start, end, this, this.setByte);\n }\n this.copyImage();\n }\n\n /**\n * @this {C1PROM}\n * @param {boolean} fOn\n * @param {C1PComputer} cmp\n */\n setPower(fOn, cmp)\n {\n if (fOn && !this.flags.powered) {\n this.flags.powered = true;\n if (DEBUGGER) this.dbg = cmp.getComponentByType(\"debugger\");\n }\n }\n\n /**\n * @this {C1PROM}\n * @param {number} addr\n * @param {number|undefined} [addrFrom]\n */\n setByte(addr, addrFrom)\n {\n /*\n * Beyond reporting this write, we need to \"repair\" the ROM, using the original image data,\n * but only if addrFrom is defined (undefined implies this is a write from the Debugger, and\n * we need to allow the Debugger to modify ROM contents).\n */\n if (addrFrom !== undefined) {\n if (DEBUGGER && this.dbg) this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_PORT, true);\n var offset = (addr - this.offROM);\n\n if (!this.abImage)\n this.abMem[this.offROM + offset] = 0;\n else\n this.abMem[this.offROM + offset] = this.abImage[offset];\n }\n }\n\n /**\n * @this {C1PROM}\n * @param {string} sImageName\n * @param {string} sImageData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n convertImage(sImageName, sImageData, nErrorCode)\n {\n if (nErrorCode) {\n this.println(\"Error loading ROM \\\"\" + sImageName + \"\\\" (\" + nErrorCode + \")\");\n return;\n }\n if (sImageData.charAt(0) == \"[\" || sImageData.charAt(0) == \"{\") {\n try {\n /*\n * The most likely source of any exception will be here: parsing the JSON-encoded ROM data.\n */\n var rom = eval(\"(\" + sImageData + \")\");\n var ab = rom['bytes'];\n if (ab) {\n this.abImage = ab;\n } else {\n this.abImage = rom;\n }\n } catch (e) {\n this.println(\"Error processing ROM \\\"\" + sImageName + \"\\\": \" + e.message);\n return;\n }\n }\n else {\n /*\n * Parse the ROM image data manually; we assume it's in \"simplified\" hex form (a series of hex byte-values separated by whitespace)\n */\n var sData = sImageData.replace(/\\n/gm, \" \").replace(/ +$/, \"\");\n var asData = sData.split(\" \");\n this.abImage = new Array(asData.length);\n for (var i=0; i < asData.length; i++) {\n this.abImage[i] = parseInt(asData[i], 16);\n }\n }\n this.copyImage();\n }\n\n /**\n * @this {C1PROM}\n */\n copyImage()\n {\n /*\n * The Computer object may give us the address of the ROM image before we've finished downloading the image,\n * so both setBuffer() and convertImage() call copyImage(), which in turn will copy the image ONLY when both\n * pieces are in place. At that point, the component becomes \"ready\", in much the same way that other components\n * (eg, CPU and Screen) become \"ready\" when all their prerequisites are satisfied.\n */\n if (!this.isReady()) {\n if (!this.sImage) {\n this.setReady();\n }\n else\n if (this.abImage && this.abMem) {\n var cbImage = this.abImage.length;\n if (cbImage != this.cbROM) {\n this.setError(\"ROM image size (\" + Str.toHexWord(cbImage) + \") does not match component-specified size (\" + Str.toHexWord(this.cbROM) + \")\");\n return;\n }\n if (DEBUG) this.log(\"copyImage(): copying ROM to \" + Str.toHexWord(this.offROM) + \" (\" + Str.toHexWord(cbImage) + \" bytes)\");\n for (var i=0; i < cbImage; i++) {\n this.abMem[this.offROM + i] = this.abImage[i];\n }\n this.setReady();\n }\n }\n }\n\n /**\n * C1PROM.init()\n *\n * This function operates on every HTML element of class \"rom\", extracting the\n * JSON-encoded parameters for the C1PROM constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a C1PROM component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeROM = Component.getElementsByClass(document, C1PJS.APPCLASS, \"rom\");\n for (var iROM=0; iROM < aeROM.length; iROM++) {\n var eROM = aeROM[iROM];\n var parmsROM = Component.getComponentParms(eROM);\n var rom = new C1PROM(parmsROM);\n Component.bindComponentControls(rom, eROM, C1PJS.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize all the ROM modules on the page.\n */\nWeb.onInit(C1PROM.init);\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/ram.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass C1PRAM extends Component {\n /**\n * C1PRAM(parmsRAM)\n *\n * The RAM component expects the following (parmsRAM) properties:\n *\n * size: amount of RAM, in bytes\n *\n * NOTE: We may make a note of the specified size, but we will not actually allocate\n * any memory for the RAM; we wait for the Computer object to tell us where our RAM is,\n * using the setBuffer() method.\n *\n * @this {C1PRAM}\n * @param {Object} parmsRAM\n */\n constructor(parmsRAM)\n {\n super(\"C1PRAM\", parmsRAM);\n }\n\n /**\n * @this {C1PRAM}\n * @param {Array} abMemory\n * @param {number} start\n * @param {number} end\n * @param {C1PCPU} cpu\n */\n setBuffer(abMemory, start, end, cpu)\n {\n this.abMem = abMemory;\n // this.offRAM = start;\n // this.cbRAM = end - start + 1;\n this.setReady();\n }\n\n /**\n * C1PRAM.init()\n *\n * This function operates on every HTML element of class \"ram\", extracting the\n * JSON-encoded parameters for the C1PRAM constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a C1PRAM component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeRAM = Component.getElementsByClass(document, C1PJS.APPCLASS, \"ram\");\n for (var iRAM=0; iRAM < aeRAM.length; iRAM++) {\n var eRAM = aeRAM[iRAM];\n var parmsRAM = Component.getComponentParms(eRAM);\n var ram = new C1PRAM(parmsRAM);\n Component.bindComponentControls(ram, eRAM, C1PJS.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize all the RAM modules on the page.\n */\nWeb.onInit(C1PRAM.init);\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/keyboard.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass C1PKeyboard extends Component {\n /**\n * C1PKeyboard(parmsKbd)\n *\n * The Keyboard component can be configured with the following (parmsKbd) properties:\n *\n * model: model number (one of: 542 or 600; 600 is the default)\n *\n * Its main purpose is to receive binding requests for various keyboard events,\n * and to use those events to simulate the C1P's keyboard hardware; specifically,\n * an OSI model 600 board (NOT the model 542).\n *\n * Keys on the C1P keyboard that differ from modern keyboards, along with their\n * closest modern counterpart:\n *\n * C1P PC\n * --- --\n * 2\" 2@\n * 6& 6^\n * 7' 7&\n * 8( 8*\n * 9) 9(\n * 0 0)\n * :* -_\n * -= =+\n * ;+ ;:\n * LINEFEED CTRL-J\n * RETURN ENTER (or CTRL-M)\n * SHIFT-O DELETE (or CTRL-H)\n * SHIFT-N ^\n * SHIFT-P @ (used by the BASIC-IN-ROM to abandon the current line)\n * SHIFT-L \\\n * SHIFT-K [\n * SHIFT-M ]\n * CTRL-C Same (used by the BASIC-IN-ROM to interrupt RUN and LIST, unless disabled with POKE 530,1)\n * CTRL-O Same (used by the BASIC-IN-ROM to suppress output until another CTRL-O is typed)\n * RUB-OUT (no mapping chosen for this key yet)\n * REPEAT (no mapping chosen for this key yet)\n *\n * Problems with iOS Devices\n * -------------------------\n * The keyboard pops up with the SHIFT key depressed, which is not the initial keyboard state that the C1P expects.\n * I tried to fix that by adding an 'autocapitalize=\"off\"' attribute alongside the 'contenteditable=\"true\"' attribute\n * on the <canvas> element, but apparently Safari v5 honors that only inside certain elements (eg, <input>). The simplest\n * work-around is to tap the iOS device's SHIFT key before starting to type, but I'd prefer an automatic solution.\n *\n * Another work-around might be to NEVER pass the real CAPS-LOCK state to the virtual machine, and whenever CAPS-LOCK is\n * actually down, automatically \"uncapitalize\" all letters.\n *\n * However, the current work-around is for keyPressSimulate() to ALWAYS convert all alphabetic charCodes to their\n * lower-case equivalents, and simply let the C1P's own shift-key logic do its thing. Note that we do this ONLY for\n * iOS devices, so that on all other devices, you can still use special shifted key combinations like SHIFT-O and SHIFT-P;\n * this work-around breaks those key combinations for iOS devices, but that seems like a reasonable trade-off.\n *\n * Simple C1P Virtual Hardware Test\n * --------------------------------\n * Using the following code:\n *\n * 10 POKE 530,1\n * 20 KEY=57088\n * 25 Q=-1\n * 30 POKE KEY,64\n * 40 P=PEEK(KEY)\n * 50 IF P<>Q THEN PRINT P\n * 60 Q=P\n * 70 GOTO 30\n *\n * The value 64 (0x40) should have enabled every row except R6. Here were the results for keys\n * on row R7:\n *\n * 1 2 3 4 5 6 7\n * --- --- --- --- --- --- ---\n * 126 190 222 238 246 250 252\n *\n * Sure enough, none of the keys on R6 worked, and all the keys on rows R0-R5 generated the same\n * values as R7. But why were the values read all EVEN instead of ODD (ie, why was bit 0 cleared as\n * well?) Answer: because 0x40 also enables keys on row R0, where the SHIFT-LOCK key resides,\n * and since the SHIFT-LOCK is normally locked AND also sits in column C0, bit 0 will be clear as well.\n *\n * This explains why the \"STAR WARS\" game (SAMPLE4.BAS) expected values \"126,190,222,238,246,250\"\n * for keys 1-6 after POKE'ing 64 into location 57088 (0xdf00), instead of the more typical values\n * \"127,191,223,239,247,251.\" This also means that anyone who happened to unlock their SHIFT-LOCK\n * would have trouble playing that game.\n *\n * @this {C1PKeyboard}\n * @param {Object} parmsKbd\n */\n constructor(parmsKbd)\n {\n super(\"C1PKeyboard\", parmsKbd);\n\n this.flags.powered = false;\n this.nDefaultModel = parmsKbd['model'];\n\n /*\n * keyCodes that I must pay particular attention to\n */\n this.KEYCODE_DELETE = 0x08;\n this.KEYCODE_TAB = 0x09;\n this.KEYCODE_LF = 0x0A;\n this.KEYCODE_CR = 0x0D;\n this.KEYCODE_SHIFT = 0x10; // I map this to CHARCODE_LSHIFT\n this.KEYCODE_CONTROL = 0x11;\n this.KEYCODE_ALT = 0x12; // I map this to CHARCODE_RSHIFT (since the C1P keyboard has no ALT key)\n this.KEYCODE_CAPSLOCK = 0x14;\n this.KEYCODE_ESC = 0x1B; // NOTE: for some reason, this comes in via keyDown/keyUp only, not keyPress\n this.KEYCODE_COMMAND = 0x5B;\n\n /*\n * The following charCodes are the same as the corresponding keyCodes\n */\n this.CHARCODE_DELETE = this.KEYCODE_DELETE;\n this.CHARCODE_LF = this.KEYCODE_LF;\n this.CHARCODE_CR = this.KEYCODE_CR;\n this.CHARCODE_ESC = this.KEYCODE_ESC;\n\n /*\n * The following charCodes are NOT the same as the corresponding keyCodes, hence the bias (PSEUDO_CHARCODE);\n * I've deliberately chosen a bias that still produces values in the byte range (0x00-0xFF) and will therefore\n * fit into aCharCodeMap, but which shouldn't conflict with any actual, type-able keys.\n */\n this.PSEUDO_CHARCODE = 0xE0;\n this.CHARCODE_LSHIFT = this.KEYCODE_SHIFT + this.PSEUDO_CHARCODE;\n this.CHARCODE_CTRL = this.KEYCODE_CONTROL + this.PSEUDO_CHARCODE;\n this.CHARCODE_RSHIFT = this.KEYCODE_ALT + this.PSEUDO_CHARCODE;\n this.CHARCODE_SHIFTLOCK = this.KEYCODE_CAPSLOCK + this.PSEUDO_CHARCODE;\n\n /*\n * Other common character codes, pseudo (like the C1P's \"BREAK\" key, which has no modern analog) or otherwise\n */\n this.CHARCODE_BREAK = 0x00 + this.PSEUDO_CHARCODE;\n this.CHARCODE_CTRLC = 0x03;\n this.CHARCODE_CTRLO = 0x0F;\n\n /*\n * These are \"shift key\" bits I store in bitsShift, and with the exception of BIT_COMMAND (because\n * the C1P doesn't have a COMMAND key), they all match the bit position of the corresponding shift key's\n * column on row 0 (abKbdCols[0]) of the simulated keyboard hardware.\n *\n * NOTE: Whenever shift key bits need to be restored from bitsShift to abKbdCols[0] (eg, when restoring\n * the current shift state at the completion of a simulated key), be sure to mask bitsShift with BITS_SIMULATE\n * before propagating them.\n */\n this.BIT_SHIFTLOCK = 0x01;\n this.BIT_RSHIFT = 0x02;\n this.BIT_LSHIFT = 0x04;\n this.BIT_COMMAND = 0x08; // the C1P has no key \"wired\" to this column, so I can use this bit for COMMAND\n this.BIT_CTRL = 0x40;\n this.BITS_SIMULATE = (this.BIT_RSHIFT | this.BIT_LSHIFT | this.BIT_CTRL);\n\n this.SIMCODE_KEYPRESS = 0;\n this.SIMCODE_KEYRELEASE = 1;\n this.SIMCODE_KEYEVENT = 2;\n this.SIMCODE_KEYTIMEOUT = 3;\n this.SIMCODE_AUTOCLEAR = 4;\n this.aSimCodeDescs = [\"keyPress\",\"keyRelease\",\"keyEvent\",\"keyTimeout\",\"autoClear\"];\n\n /*\n * From \"OSI C1P Technical Report\" p.19 regarding the Model 600 Board:\n *\n * \"By holding down any key, one will first get one character output, and after approximately\n * a half second delay a repeat rate of approximately 5 characters per second.\"\n */\n this.nCyclesThreshold = 8192; // number of virtual CPU cycles required before aKbdStates is propagated\n this.msReleaseDelay = 250; // number of milliseconds before a down key is \"forced\" up (unless we see it go up)\n this.msReleaseRepeat = 100; // number of milliseconds before a held key is \"forced\" up (assuming auto-repeat)\n this.msInjectDelay = 300; // number of milliseconds between injected keystrokes\n\n this.aButtonCodeMap = {};\n this.aButtonCodeMap['break'] = this.CHARCODE_BREAK;\n this.aButtonCodeMap['esc'] = this.CHARCODE_ESC;\n this.aButtonCodeMap['ctrl-c'] = this.CHARCODE_CTRLC;\n this.aButtonCodeMap['ctrl-o'] = this.CHARCODE_CTRLO;\n\n /*\n * This array is used by keyEventSimulate() to lookup a given charCode and convert it to the appropriate\n * row/col bit combination that the C1P requires. I assign each supported charCode a 16-bit value, where\n * the high byte contains the row/col pair (in the high and low nibbles, respectively), and the low byte\n * contains any required shift-key code.\n *\n * For example, an apostrophe (0x27) is an unshifted key on a modern keyboard, but it is a SHIFT-7 on the\n * C1P keyboard, so when I simulate the 7, I must also simulate a SHIFT (I always choose the LEFT shift\n * key -- CHARCODE_LSHIFT -- but that choice is completely arbitrary).\n *\n * Using charCodes (from keyPress events) proved to be more robust than using keyCodes (from keyDown and\n * keyUp events), in part because of differences between the C1P keyboard's layout and modern keyboards,\n * and also because of differences in the way browsers generate the keyDown and keyUp events. For\n * example, Safari on iOS devices will not generate up/down events for shift keys, and for other keys,\n * the up/down events are usually generated after the actual press is complete, and in rapid succession,\n * which doesn't give the slow C1P virtual machine enough time to detect the key.\n *\n * There are still a few times that I call keyEventSimulate() from keyEvent(), and for those occasions,\n * I create a pseudo-charCode value by adding PSEUDO_CHARCODE (0xE0) to the keyCode value, to avoid any\n * confusion with real charCodes:\n *\n * CHARCODE_LSHIFT (originally 0x10, which also looks like CTRL-P, so converted to 0xF0)\n * CHARCODE_CTRL (originally 0x11, which also looks like CTRL-Q, so converted to 0xF1)\n * CHARCODE_RSHIFT (originally 0x12, which also looks like CTRL-R, so converted to 0xF2)\n * CHARCODE_SHIFTLOCK (originally 0x14, which also looks like CTRL-T, so converted to 0xF4)\n *\n * Again, as things currently stand, iOS devices will never generate the above charCodes, so any C1P software\n * that relies detecting on shift-key state changes will not work on those devices.\n *\n * For reference purposes, I've left some parenthetical references to corresponding keyCodes in the comments\n * below. Relying on keyCodes is problematic, which is why I've tried to eliminate most dependencies on them,\n * but still, they're all you get on keyDown/keyUp events.\n */\n this.aCharCodeMap = [];\n this.aCharCodeMap[0x31] = 0x7700; this.aCharCodeMap[0x21] = 0x7700 + this.CHARCODE_LSHIFT; // 1 (0x31) ! (0x31)\n this.aCharCodeMap[0x32] = 0x7600; this.aCharCodeMap[0x22] = 0x7600 + this.CHARCODE_LSHIFT; // 2 (0x32) \" (0xDE)\n this.aCharCodeMap[0x33] = 0x7500; this.aCharCodeMap[0x23] = 0x7500 + this.CHARCODE_LSHIFT; // 3 (0x33) # (0x33)\n this.aCharCodeMap[0x34] = 0x7400; this.aCharCodeMap[0x24] = 0x7400 + this.CHARCODE_LSHIFT; // 4 (0x34) $ (0x34)\n this.aCharCodeMap[0x35] = 0x7300; this.aCharCodeMap[0x25] = 0x7300 + this.CHARCODE_LSHIFT; // 5 (0x35) % (0x35)\n this.aCharCodeMap[0x36] = 0x7200; this.aCharCodeMap[0x26] = 0x7200 + this.CHARCODE_LSHIFT; // 6 (0x36) & (0x37)\n this.aCharCodeMap[0x37] = 0x7100; this.aCharCodeMap[0x27] = 0x7100 + this.CHARCODE_LSHIFT; // 7 (0x37) ' (0xDE)\n this.aCharCodeMap[0x38] = 0x6700; this.aCharCodeMap[0x28] = 0x6700 + this.CHARCODE_LSHIFT; // 8 (0x38) ( (0x39)\n this.aCharCodeMap[0x39] = 0x6600; this.aCharCodeMap[0x29] = 0x6600 + this.CHARCODE_LSHIFT; // 9 (0x39) ) (0x30)\n this.aCharCodeMap[0x30] = 0x6500; // 0\n this.aCharCodeMap[0x3A] = 0x6400; this.aCharCodeMap[0x2A] = 0x6400 + this.CHARCODE_LSHIFT; // : (0xBA) * (0x38)\n this.aCharCodeMap[0x2D] = 0x6300; this.aCharCodeMap[0x3D] = 0x6300 + this.CHARCODE_LSHIFT; // - (0xBD) = (0xBB)\n //this.aCharCodeMap[0x00] = 0x6200; // RUB-OUT (no mapping chosen for this key yet)\n this.aCharCodeMap[0x2E] = 0x5700; this.aCharCodeMap[0x3E] = 0x5700 + this.CHARCODE_LSHIFT; // . (0xBE) > (0xBE)\n this.aCharCodeMap[0x6C] = 0x5600; this.aCharCodeMap[0x4C] = 0x5600 + this.CHARCODE_LSHIFT; this.aCharCodeMap[0x5C] = 0x5600 + this.CHARCODE_LSHIFT; // l L \\\n this.aCharCodeMap[0x6F] = 0x5500; this.aCharCodeMap[0x4F] = 0x5500 + this.CHARCODE_LSHIFT; this.aCharCodeMap[this.CHARCODE_DELETE] = 0x5500 + this.CHARCODE_LSHIFT; // o O DELETE\n this.aCharCodeMap[this.CHARCODE_LF] = 0x5400; // LINE-FEED\n this.aCharCodeMap[this.CHARCODE_CR] = 0x5300; // RETURN\n this.aCharCodeMap[0x77] = 0x4700; this.aCharCodeMap[0x57] = 0x4700 + this.CHARCODE_LSHIFT; // w W\n this.aCharCodeMap[0x65] = 0x4600; this.aCharCodeMap[0x45] = 0x4600 + this.CHARCODE_LSHIFT; // e E\n this.aCharCodeMap[0x72] = 0x4500; this.aCharCodeMap[0x52] = 0x4500 + this.CHARCODE_LSHIFT; // r R\n this.aCharCodeMap[0x74] = 0x4400; this.aCharCodeMap[0x54] = 0x4400 + this.CHARCODE_LSHIFT; // t T\n this.aCharCodeMap[0x79] = 0x4300; this.aCharCodeMap[0x59] = 0x4300 + this.CHARCODE_LSHIFT; // y Y\n this.aCharCodeMap[0x75] = 0x4200; this.aCharCodeMap[0x55] = 0x4200 + this.CHARCODE_LSHIFT; // u U\n this.aCharCodeMap[0x69] = 0x4100; this.aCharCodeMap[0x49] = 0x4100 + this.CHARCODE_LSHIFT; // i I\n this.aCharCodeMap[0x73] = 0x3700; this.aCharCodeMap[0x53] = 0x3700 + this.CHARCODE_LSHIFT; // s S\n this.aCharCodeMap[0x64] = 0x3600; this.aCharCodeMap[0x44] = 0x3600 + this.CHARCODE_LSHIFT; // d D\n this.aCharCodeMap[0x66] = 0x3500; this.aCharCodeMap[0x46] = 0x3500 + this.CHARCODE_LSHIFT; // f F\n this.aCharCodeMap[0x67] = 0x3400; this.aCharCodeMap[0x47] = 0x3400 + this.CHARCODE_LSHIFT; // g G\n this.aCharCodeMap[0x68] = 0x3300; this.aCharCodeMap[0x48] = 0x3300 + this.CHARCODE_LSHIFT; // h H\n this.aCharCodeMap[0x6A] = 0x3200; this.aCharCodeMap[0x4A] = 0x3200 + this.CHARCODE_LSHIFT; // j J\n this.aCharCodeMap[0x6B] = 0x3100; this.aCharCodeMap[0x4B] = 0x3100 + this.CHARCODE_LSHIFT; this.aCharCodeMap[0x5B] = 0x3100 + this.CHARCODE_LSHIFT; // k K [\n this.aCharCodeMap[0x78] = 0x2700; this.aCharCodeMap[0x58] = 0x2700 + this.CHARCODE_LSHIFT; // x X\n this.aCharCodeMap[0x63] = 0x2600; this.aCharCodeMap[0x43] = 0x2600 + this.CHARCODE_LSHIFT; // c C\n this.aCharCodeMap[0x76] = 0x2500; this.aCharCodeMap[0x56] = 0x2500 + this.CHARCODE_LSHIFT; // v V\n this.aCharCodeMap[0x62] = 0x2400; this.aCharCodeMap[0x42] = 0x2400 + this.CHARCODE_LSHIFT; // b B\n this.aCharCodeMap[0x6E] = 0x2300; this.aCharCodeMap[0x4E] = 0x2300 + this.CHARCODE_LSHIFT; this.aCharCodeMap[0x5E] = 0x2300 + this.CHARCODE_LSHIFT; // n N ^\n this.aCharCodeMap[0x6D] = 0x2200; this.aCharCodeMap[0x4D] = 0x2200 + this.CHARCODE_LSHIFT; this.aCharCodeMap[0x5D] = 0x2200 + this.CHARCODE_LSHIFT; // m M ]\n this.aCharCodeMap[0x2C] = 0x2100; this.aCharCodeMap[0x3C] = 0x2100 + this.CHARCODE_LSHIFT; // , (0xBC) < (0xBC)\n this.aCharCodeMap[0x71] = 0x1700; this.aCharCodeMap[0x51] = 0x1700 + this.CHARCODE_LSHIFT; // q Q\n this.aCharCodeMap[0x61] = 0x1600; this.aCharCodeMap[0x41] = 0x1600 + this.CHARCODE_LSHIFT; // a A\n this.aCharCodeMap[0x7A] = 0x1500; this.aCharCodeMap[0x5A] = 0x1500 + this.CHARCODE_LSHIFT; // z Z\n this.aCharCodeMap[0x20] = 0x1400; // SPACE\n this.aCharCodeMap[0x2F] = 0x1300; this.aCharCodeMap[0x3F] = 0x1300 + this.CHARCODE_LSHIFT; // / (0xBF) ? (0xBF)\n this.aCharCodeMap[0x3B] = 0x1200; this.aCharCodeMap[0x2B] = 0x1200 + this.CHARCODE_LSHIFT; // ; (0xBA) + (0xBB)\n this.aCharCodeMap[0x70] = 0x1100; this.aCharCodeMap[0x50] = 0x1100 + this.CHARCODE_LSHIFT; this.aCharCodeMap[0x40] = 0x1100 + this.CHARCODE_LSHIFT; // p P @\n //this.aCharCodeMap[0x00] = 0x0700; // REPEAT (no mapping chosen for this key yet)\n this.aCharCodeMap[this.CHARCODE_CTRL] = 0x0600; // CTRL\n this.aCharCodeMap[this.CHARCODE_ESC] = 0x0500; // ESC\n this.aCharCodeMap[this.CHARCODE_LSHIFT] = 0x0200; // LEFT-SHIFT\n this.aCharCodeMap[this.CHARCODE_RSHIFT] = 0x0100; // RIGHT-SHIFT\n this.aCharCodeMap[this.CHARCODE_SHIFTLOCK] = 0x0000; // SHIFT-LOCK\n\n this.reset();\n }\n\n /**\n * @this {C1PKeyboard}\n */\n reset()\n {\n this.setModel(this.nDefaultModel);\n\n /*\n * The physical (not virtual) state of various shift keys,\n * with the exception of SHIFT-LOCK, which needs to start in the\n * \"locked\" position, regardless of the physical CAPS-LOCK state.\n *\n * QUESTION: In JavaScript, how do you query initial key states?\n */\n this.bitsShift = this.BIT_SHIFTLOCK;\n\n /*\n * Every SET bit of bKbdRows represents an enabled row (this convention\n * is the REVERSE of the C1P hardware, but I prefer it).\n */\n this.bKbdRows = 0x00;\n\n /*\n * Every SET bit of abKbdCols represents an enabled column; again, this is\n * the REVERSE of the C1P hardware, but I compensate for that difference with\n * a quick XOR in updateMemory().\n *\n * Like bitsShift, this 8x8 array (8 byte values, each with 8 bits) represents\n * the physical state of the keyboard, encoded in C1P format; the C1P won't\n * actually see data this until updateMemory() decides it's time to propagate it.\n */\n this.abKbdCols = [this.BIT_SHIFTLOCK,0x00,0x00,0x00,0x00,0x00,0x00,0x00];\n\n /*\n * After a new key event has updated abKbdCols, we \"push\" a copy of that\n * updated keyboard state onto this array. updateMemory() will then \"shift\"\n * the next copy off, update its own copy (abKbdColsLast), and then propagate\n * that to the C1P's keyboard memory, once the CPU has had enough time to\n * process the previous event (see nCyclesThreshold).\n */\n this.aKbdStates = [];\n\n /*\n * When a key \"down\" is simulated on behalf of some charCode, I save\n * the timer object responsible for simulating the key \"up\" here, so that\n * if I detect the actual key going up sooner, I can cancel the timer and\n * simulate the \"up\" immediately. Similarly, if another press for the same\n * key arrives before last one expired (eg, auto-repeat), I need to cancel\n * the previous timer for that key before setting another.\n *\n * NOTE: If this is anything other than an initial reset, then we need to\n * make sure there are no outstanding timers before we blow the array away.\n */\n if (this.aKeyTimers) {\n for (var i in this.aKeyTimers) {\n if (isNaN(+i)) continue; // ignore any non-numeric properties, if any\n if (this.aKeyTimers[i]) clearTimeout(this.aKeyTimers[i]);\n }\n }\n this.aKeyTimers = [];\n this.prevCharDown = 0;\n this.prevKeyDown = 0;\n\n /*\n * These save the last values written to keyboard memory, so that I can\n * avoid rewriting the memory if the values haven't changed since the last update.\n */\n this.bWriteLast = -1;\n this.abKbdColsLast = this.abKbdCols;\n\n /*\n * Due to the way the C1P scans its keyboard rows (from R0 up to R7 *or* to the\n * highest row for which a \"down\" key has just been detected), if we get back-to-back\n * key events for, say, \"I\" and then \"S\", the C1P will see only the \"S\", never the \"I\",\n * because \"I\" is on a higher row.\n *\n * That's why we have aKbdStates, which relies on the following CPU activity variables.\n */\n this.nReadsSinceLastEvent = 0;\n this.nWritesSinceLastEvent = 0;\n this.nCyclesSinceLastEvent = 0;\n\n /*\n * Make sure the auto-injection buffer is empty, too (an injection could have been\n * in progress on any reset after the first).\n */\n this.sInjectBuffer = \"\";\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"esc\", \"ctrl-c\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n /*\n * I want to bind to the first caller (ie, the Screen), not subsequent ones (eg, the Panel)\n */\n if (this.bindings[sBinding] === undefined) {\n switch(sBinding) {\n case \"keyDown\":\n this.bindings[sBinding] = control;\n control.onkeydown = function(kbd) {\n return function(event) {\n return kbd.keyEvent(event, true);\n };\n }(this);\n return true;\n case \"keyPress\":\n this.bindings[sBinding] = control;\n control.onkeypress = function(kbd) {\n return function(event) {\n return kbd.keyPress(event);\n };\n }(this);\n return true;\n case \"keyUp\":\n this.bindings[sBinding] = control;\n control.onkeyup = function(kbd) {\n return function(event) {\n return kbd.keyEvent(event, false);\n };\n }(this);\n return true;\n case \"break\":\n /*\n * The BREAK key is unusual: it requires us forcing the equivalent of someone pressing\n * our \"Reset\" and \"Run\" buttons. As things stand, the Computer component is responsible\n * for end-user \"reset\" requests, so we can simply arrange to call this.cmp.reset(true).\n *\n * NOTE: At the risk of making keyPressSimulate() a bit uglier, I also permit BREAK\n * there, in case someone wants to \"inject\" the BREAK key; however, if it's followed by\n * other injected keys, I'll need to avoid clearing the injection buffer on a reset;\n * currently, reset() resets everything.\n */\n this.bindings[sBinding] = control;\n control.onclick = function(kbd) {\n return function(event) {\n if (DEBUG) kbd.println(\"keyPressSimulate(break)\");\n if (kbd.cmp) kbd.cmp.reset(true);\n };\n }(this);\n return true;\n default:\n if (this.aButtonCodeMap[sBinding] !== undefined) {\n this.bindings[sBinding] = control;\n control.onclick = function(kbd, sButton, charCode) {\n return function(event) {\n if (DEBUG) kbd.println(\"keyPressSimulate(\" + sButton + \")\");\n if (kbd.cpu) kbd.cpu.setFocus();\n return !kbd.keyPressSimulate(charCode);\n };\n }(this, sBinding, this.aButtonCodeMap[sBinding]);\n return true;\n }\n break;\n }\n }\n return false;\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {Array} abMemory\n * @param {number} start\n * @param {number} end\n * @param {C1PCPU} cpu\n */\n setBuffer(abMemory, start, end, cpu)\n {\n this.abMem = abMemory;\n this.offKbd = start;\n this.cbKbd = end - start + 1;\n this.offKbdLimit = this.offKbd + this.cbKbd;\n if (cpu) {\n this.cpu = cpu;\n if (DEBUG) cpu.addReadNotify(start, end, this, this.getByte);\n cpu.addWriteNotify(start, end, this, this.setByte);\n }\n this.setReady();\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {number} nModel\n */\n setModel(nModel)\n {\n this.nModel = nModel;\n /*\n * Default to Model 600 behavior, where the keyboard status lines are inverted\n * (ie, a zero bit indicates a key press).\n */\n this.bInvert = 0xff;\n if (this.nModel != 600) {\n /*\n * No inversion for model 542\n */\n this.bInvert = 0x00;\n this.println(\"updated keyboard model: \" + this.nModel);\n }\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {boolean} fOn\n * @param {C1PComputer} cmp\n *\n * We make a note of the Computer component, so that we can invoke its reset() method when our simulated\n * BREAK key is pressed, and we query the Debugger component so that we can use its info() and halt() functions,\n * which we use to buffer information without adversely affecting timing and then dump later using the Debugger's\n * \"info\" command.\n */\n setPower(fOn, cmp)\n {\n if (fOn && !this.flags.powered) {\n this.flags.powered = true;\n this.cmp = cmp;\n if (DEBUGGER) this.dbg = cmp.getComponentByType(\"debugger\");\n }\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {boolean} [fReady] is assumed to indicate \"ready\" unless EXPLICITLY set to false\n */\n setReady(fReady)\n {\n this.iOS = Web.isUserAgent(\"iOS\");\n this.fMobile = (this.iOS || Web.isUserAgent(\"Android\"));\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(this.dbg.MESSAGE_KBD)) {\n this.dbg.message(\"mobile keyboard support: \" + (this.fMobile? \"true\" : \"false\") + \" (\" + window.navigator.userAgent + \")\");\n }\n super.setReady();\n }\n\n /**\n * calcReleaseDelay(fRepeat)\n *\n * This attempts to scale our default \"release\" delay appropriately for the current CPU speed.\n *\n * Note that if the effective CPU speed exceeds 16Mhz, it becomes very difficult to rely on timer-driven key events\n * (even the shortest available timer delay still gives the CPU too much time, so it thinks that even the briefest key\n * press represents a held key, resulting in multiple keystrokes). We deal with this by artificially limiting the top\n * speed in the CPU component (the current limit for \"fast\" mode is 8Mhz; see CPU.mhzFast)\n *\n * @this {C1PKeyboard}\n * @param {boolean} fRepeat is true if a timeout had already been active for the current key\n * @return {number}\n */\n calcReleaseDelay(fRepeat)\n {\n /*\n * NOTE: This delay affects only the \"up\" delay, not repeat delay, but it's useful to have an initial\n * \"up\" delay that's sufficiently large to ensure the native machine's auto-repeat behavior cooperates\n * with the virtual machine's auto-repeat behavior. msReleaseDelay is the initial delay, msReleaseRepeat\n * is the subsequent delay.\n *\n * Unfortunately, with a large initial delay, we need to enable the auto-clear code in the keyEvent()\n * handler, otherwise doing things like pressing ENTER repeatedly will result in sluggish behavior\n * (because you can generally press/release/repress keys faster than they will auto-repeat).\n */\n var msDelay = (fRepeat? this.msReleaseRepeat: this.msReleaseDelay);\n if (this.cpu && this.cpu.mhz) {\n msDelay /= this.cpu.mhz;\n }\n return msDelay;\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {number} [notCharCode]\n */\n autoClear(notCharCode)\n {\n if (this.prevCharDown && (notCharCode === undefined || notCharCode != this.prevCharDown)) {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(this.dbg.MESSAGE_KBD)) {\n this.dbg.message(\"autoClear(\" + Str.toHexByte(this.prevCharDown) + \")\");\n }\n\n clearTimeout(this.aKeyTimers[this.prevCharDown]);\n this.keyEventSimulate(this.prevCharDown, false, this.SIMCODE_AUTOCLEAR);\n }\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {string} sKeyCodes\n * @param {number} [msDelay] is an optional injection delay (default is msInjectDelay)\n */\n injectKeys(sKeyCodes, msDelay)\n {\n this.sInjectBuffer = sKeyCodes;\n if (DEBUG) this.log(\"injectKeys(\" + this.sInjectBuffer.split(\"\\n\").join(\"\\\\n\") + \")\");\n this.injectKeysFromBuffer(msDelay || this.msInjectDelay);\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {number} msDelay is the delay between injected keys\n */\n injectKeysFromBuffer(msDelay)\n {\n if (this.sInjectBuffer.length > 0) {\n var ch = this.sInjectBuffer.charCodeAt(0);\n /*\n * I could require all callers to supply CRs instead of LFs, but this is friendlier.\n */\n if (ch == 0x0a)\n ch = 0x0d;\n /*\n * Also, if upper-case characters are being injected, convert them to lower-case, and rely\n * on the virtual SHIFT-LOCK remaining locked for the duration; otherwise, we'd have to simulate\n * SHIFT key presses around every character (or around the entire set of characters) as well.\n *\n * UPDATE: Even though keyPressSimulate() currently has some code to do this automatically now,\n * it's really intended as a work-around for a SHIFT-related problem on iOS devices only, so\n * we can't rely on that in the general case.\n */\n if (ch >= 0x41 && ch <= 0x5A)\n ch += 0x20;\n this.sInjectBuffer = this.sInjectBuffer.substr(1);\n this.keyPressSimulate(ch);\n }\n if (this.sInjectBuffer.length > 0) {\n setTimeout(function(kbd) { return function() {kbd.injectKeysFromBuffer(msDelay);}; }(this), msDelay);\n }\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {Object} event\n * @param {boolean} fDown is true if called for a keyDown event, false if called for a keyUp event\n * @return {boolean} true to pass the event along, false to consume it\n */\n keyEvent(event, fDown)\n {\n var fPass;\n var fAutoClear = !fDown;\n var keyCode = event.keyCode;\n\n if (fDown) this.prevKeyDown = keyCode;\n\n if (keyCode == this.CHARCODE_LSHIFT - this.PSEUDO_CHARCODE) {\n this.bitsShift &= ~this.BIT_LSHIFT;\n if (fDown) this.bitsShift |= this.BIT_LSHIFT;\n keyCode += this.PSEUDO_CHARCODE;\n fAutoClear = false;\n }\n else\n if (keyCode == this.CHARCODE_RSHIFT - this.PSEUDO_CHARCODE) {\n this.bitsShift &= ~this.BIT_RSHIFT;\n if (fDown) this.bitsShift |= this.BIT_RSHIFT;\n keyCode += this.PSEUDO_CHARCODE;\n fAutoClear = false;\n }\n else\n if (keyCode == this.CHARCODE_CTRL - this.PSEUDO_CHARCODE) {\n this.bitsShift &= ~this.BIT_CTRL;\n if (fDown) this.bitsShift |= this.BIT_CTRL;\n keyCode += this.PSEUDO_CHARCODE;\n fAutoClear = false;\n }\n else\n if (keyCode == this.CHARCODE_SHIFTLOCK - this.PSEUDO_CHARCODE) {\n /*\n * FYI, this generates a \"down\" event ONLY when getting locked, and an \"up\" event ONLY\n * when getting unlocked--which is exactly what I want, even though that may seem a little\n * counter-intuitive (since the key itself actually went down AND up for each event).\n *\n * Moreover, since most people do NOT have CAPS-LOCK enabled, whereas the C1P needs it\n * enabled by default, we invert fDown, so that if the user enables CAPS-LOCK for some\n * reason, we treat is as *disabling* SHIFT-LOCK, and vice versa.\n */\n fDown = !fDown;\n this.bitsShift &= ~this.BIT_SHIFTLOCK;\n if (fDown) this.bitsShift |= this.BIT_SHIFTLOCK;\n keyCode += this.PSEUDO_CHARCODE;\n fAutoClear = false;\n }\n else\n if (keyCode == this.KEYCODE_COMMAND) {\n /*\n * Avoid interfering with useful Browser key commands, like COMMAND-Q, COMMAND-T, etc.\n */\n this.bitsShift &= ~this.BIT_COMMAND;\n if (fDown) this.bitsShift |= this.BIT_COMMAND;\n fAutoClear = false;\n fPass = true;\n }\n else\n if (keyCode == this.KEYCODE_TAB) {\n /*\n * If I don't consume TAB on the \"down\" event, then that's all I'll see, because the\n * browser will see it and give focus to the next control. But the \"down\" side is that\n * that no \"press\" event will be generated. This puts it in the same category as ESC,\n * which also generates \"down\" and \"up\" events (LOTS of \"down\" events for that matter),\n * but no \"press\" event. However, the C1P has no TAB key, so it's safe to completely ignore.\n */\n fPass = fAutoClear = false;\n }\n else\n if (keyCode == this.KEYCODE_ESC || keyCode == this.KEYCODE_DELETE) {\n /*\n * I don't get keyPress events for ESC (why?) and I never want the browser to act on DELETE\n * (which does double-duty as the \"Back\" button and leaves the current page), so I have to\n * simulate them now.\n *\n * Note that I call the \"press\" simulate method and NOT the \"event\" simulate method, because\n * the former takes care of simulating both individual \"down\" and \"up\" events.\n */\n if (DEBUG && DEBUGGER && keyCode == this.KEYCODE_ESC && this.dbg) this.dbg.halt();\n fPass = (fDown? !this.keyPressSimulate(keyCode) : false);\n }\n else {\n /*\n * Pass on everything else; I'll take care of this key at the keyPress stage, not the\n * the keyDown or keyUp stage.\n */\n fPass = true;\n /*\n * At this point, I have a difficult choice to make: leave fAutoClear true for any remaining\n * \"up\" events, so that keys will repeat immediately when released/pressed repeatedly (most\n * noticeable with the Enter key), or set fAutoClear to false to ensure that polling apps have\n * enough time to see every key press.\n *\n * I've decided that the former is more important than the latter, so if polling apps are still\n * missing keystrokes, then perhaps nCyclesThreshold needs to be supplemented in some way.\n *\n * fAutoClear = false;\n */\n }\n\n if (fAutoClear) {\n /*\n * When you use a command like COMMAND-T, I see the COMMAND key going down, but not going up,\n * so I think the COMMAND key is still down and ignore all input; to easily get out of that state,\n * I clear our internal BIT_COMMAND whenever I see ANY key go up (well, ALMOST any key; cases\n * above that explicitly clear fAutoClear -- such as the COMMAND key itself -- are exceptions\n * to the rule).\n */\n this.bitsShift &= ~this.BIT_COMMAND;\n /*\n * I don't reliably get keyDown/keyUp events for all keys on all devices, but for those devices that\n * I DO, it seems like a good idea to cancel any pending key \"up\" simulation on receipt of the actual\n * keyUp event.\n *\n * However, the following code is problematic for Safari on iOS devices, which as noted above, doesn't\n * generate keyDown/keyUp events until after the press operation is complete, and then they are generated\n * in rapid succession, which doesn't give the C1P enough time to detect the key. So I simply don't do\n * this on iOS devices.\n */\n if (!this.fMobile && keyCode == this.prevKeyDown) this.autoClear();\n }\n\n if (fPass === undefined) {\n fPass = !this.keyEventSimulate(keyCode, fDown, this.SIMCODE_KEYEVENT);\n }\n\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(this.dbg.MESSAGE_KBD)) {\n this.dbg.message(/*(fDown?\"\\n\":\"\") +*/ \"key\" + (fDown?\"Down\":\"Up\") + \"(\" + Str.toHexByte(keyCode) + \"): \" + (fPass? \"pass\" : \"consume\"));\n }\n return fPass;\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {Object} event\n * @return {boolean} true to pass the event along, false to consume it\n *\n * We've stopped relying on keyPress for keyboard emulation purposes, but it's still handy to hook and monitor\n * when debugging.\n */\n keyPress(event)\n {\n var fPass = true;\n /*\n * Browser-independent charCode extraction...\n */\n event = event || window.event;\n var charCode = event.which || event.keyCode;\n\n /*\n * Let's stop any injection currently in progress, too\n */\n this.sInjectBuffer = \"\";\n\n if (this.bitsShift & this.BIT_COMMAND)\n this.bitsShift &= ~this.BIT_COMMAND;\n else\n fPass = !this.keyPressSimulate(charCode);\n\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(this.dbg.MESSAGE_KBD)) {\n this.dbg.message(\"keyPress(\" + Str.toHexByte(charCode) + \"): \" + (fPass? \"pass\" : \"consume\"));\n }\n return fPass;\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {number} charCode\n * @return {boolean} true if successfully simulated, false if unrecognized/unsupported key\n */\n keyPressSimulate(charCode)\n {\n var fSimulated = false;\n if (charCode == this.CHARCODE_BREAK) {\n /*\n * The BREAK key is not wired up to the keyboard like the other keys are, but we simulate\n * it here, so that it can be injected like any other key.\n */\n if (this.cmp) {\n this.cmp.reset(true);\n fSimulated = true;\n }\n }\n else {\n /*\n * WARNING: The next line is why you cannot use SHIFT-N, SHIFT-O, SHIFT-P, etc. But without it,\n * iOS devices with the annoying \"autocapitalization\" feature enabled make the keyboard unusable\n * by default. The trade-off is: either require all iOS users to first tap the shift key to turn\n * \"autocapitalization\" off, or lose the ability to type any of the special shifted alphabetic keys.\n * I choose the latter, because I have friendlier aliases already defined for those keys (eg,\n * ^, DELETE, and @).\n *\n * Furthermore, by doing this for iOS (and Android) devices ONLY, other platforms retain the ability\n * to use those special key combos.\n */\n if (this.fMobile) {\n if (charCode >= 0x41 && charCode <= 0x5A)\n charCode += 0x20;\n }\n\n /*\n * Auto-clear any previous down key EXCEPT for charCode (because it may be held and repeating).\n */\n this.autoClear(charCode);\n\n if (this.keyEventSimulate(charCode, true, this.SIMCODE_KEYPRESS)) {\n /*\n * If CPU speed is unlimited, then we switch to an alternate approach, which is to immediately\n * queue a \"release\" event as well. The problem with the original timer-based approach at high\n * speeds is that the the CPU may get lucky and execute a LOT of instructions between delivery\n * of the keyPress event and the \"keyTimeout\" event. In that case, even enabling keyboard polling\n * detection in updateMemory() won't entirely help -- although we do that, too -- because JavaScript\n * events are delivered synchronously, so it may simply take too long for the \"keyTimeout\" event\n * to arrive.\n *\n * Why don't we ALWAYS do this? Because in the normal case (SPEED_SLOW, and even SPEED_FAST) we want\n * to faithfully simulate how long a key is held, so that features like auto-repeat work properly.\n * You'll notice in the SPEED_MAX case, holding a key no longer has any effect; even though multiple\n * keyPress events WILL arrive, if we simulate a release immediately after each one, then repeat\n * is defeated. Also, the keyboard polling detection code in updateMemory() doesn't work well for\n * all apps.\n */\n if (this.cpu.speed == this.cpu.SPEED_MAX) {\n this.keyEventSimulate(charCode, false, this.SIMCODE_KEYRELEASE);\n }\n else {\n var fRepeat = false;\n if (this.aKeyTimers[charCode]) {\n clearTimeout(this.aKeyTimers[charCode]);\n fRepeat = true;\n }\n var msDelay = this.calcReleaseDelay(fRepeat);\n this.aKeyTimers[this.prevCharDown = charCode] = setTimeout(function(kbd) { return function() {kbd.keyEventSimulate(charCode, false, kbd.SIMCODE_KEYTIMEOUT);}; }(this), msDelay);\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(this.dbg.MESSAGE_KBD)) {\n this.dbg.message(\"keyPressSimulate(\" + Str.toHexByte(charCode) + \"): setTimeout()\");\n }\n }\n fSimulated = true;\n }\n }\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(this.dbg.MESSAGE_KBD)) {\n this.dbg.message(\"keyPressSimulate(\" + Str.toHexByte(charCode) + \"): \" + (fSimulated? \"true\" : \"false\"));\n }\n return fSimulated;\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {number} charCode\n * @param {boolean} fDown\n * @param {number} simCode indicates the origin of the event\n * @return {boolean} true if successfully simulated, false if unrecognized/unsupported key\n */\n keyEventSimulate(charCode, fDown, simCode)\n {\n var fSimulated = false;\n if (!fDown) {\n this.aKeyTimers[charCode] = null;\n if (this.prevCharDown == charCode) this.prevCharDown = 0;\n }\n var bShift = 0;\n var bCode = this.aCharCodeMap[charCode];\n if (bCode === undefined) {\n /*\n * Perhaps we're dealing with a CTRL variation of an alphabetic key; this won't\n * affect non-CTRL-key combos like CR or LF, because they're defined in aCharCodeMap,\n * and this bit of code relieves us from having to explicitly define every CTRL-letter\n * possibility in aCharCodeMap. However, CTRL-anything-else is a different matter.\n */\n if (charCode >= 0x01 && charCode <= 0x1A) {\n charCode += 0x40;\n bShift = this.CHARCODE_CTRL;\n }\n bCode = this.aCharCodeMap[charCode];\n }\n if (bCode !== undefined) {\n var iRow = bCode >> 12;\n var iCol = (bCode >> 8) & 0xf;\n if (!bShift) bShift = bCode & 0xff;\n if (fDown) {\n this.abKbdCols[iRow] |= 1 << iCol;\n if (bShift == this.CHARCODE_CTRL)\n this.abKbdCols[0] |= this.BIT_CTRL;\n else\n if (bShift == this.CHARCODE_LSHIFT)\n this.abKbdCols[0] |= this.BIT_LSHIFT;\n else\n if (bShift == this.CHARCODE_RSHIFT)\n this.abKbdCols[0] |= this.BIT_RSHIFT;\n else\n this.abKbdCols[0] &= ~this.BITS_SIMULATE;\n }\n else {\n this.abKbdCols[iRow] &= ~(1 << iCol);\n this.abKbdCols[0] &= ~this.BITS_SIMULATE;\n this.abKbdCols[0] |= (this.bitsShift & this.BITS_SIMULATE);\n }\n var fPropagate = (simCode == this.SIMCODE_KEYPRESS && !this.aKbdStates.length);\n this.aKbdStates.push(this.abKbdCols.slice());\n this.updateMemory(fPropagate);\n fSimulated = true;\n }\n if (DEBUG && this.dbg) this.dbg.info(\"keyEventSimulate(\" + Str.toHexByte(charCode) + \",\" + (fDown?\"down\":\"up\") + \",\" + this.aSimCodeDescs[simCode] + \"): \" + (fSimulated? \"true\" : \"false\"));\n return fSimulated;\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {number} addr\n * @param {number|undefined} addrFrom (not defined whenever the Debugger tries to read the specified addr)\n *\n * NOTE: As long as we rely on the CPU processing a certain number of cycles (nCyclesThreshold) before\n * propagating the next kbd state, and not how many reads and/or writes the CPU has performed, we could\n * eliminate the overhead of this read-notification handler.\n *\n * It's useful for diagnostic purposes, which is why it's still here.\n */\n getByte(addr, addrFrom)\n {\n /*\n * Don't trigger any further hardware emulation (beyond what we've already stored in memory) if\n * the Debugger performed this read (need a special Debugger I/O command if/when you really want to do that).\n */\n if (DEBUG) {\n if (addrFrom !== undefined) {\n this.nReadsSinceLastEvent++;\n if (DEBUG && this.dbg) this.dbg.info(\"reading kbd \" + Str.toHexWord(addr) + \" @\" + this.cpu.getCycles() + \" cycles\");\n }\n }\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {number} addr\n * @param {number|undefined} addrFrom (not defined whenever the Debugger tries to write the specified addr)\n *\n * NOTE: Ordinarily, I wouldn't allow Debugger writes (addrFrom === undefined) to interfere with the simulated\n * hardware state, but for now, I find it useful to be able to prod the simulation code directly from the Debugger.\n */\n setByte(addr, addrFrom)\n {\n var b = this.cpu.getByte(addr);\n this.bKbdRows = b ^ this.bInvert;\n this.nWritesSinceLastEvent++;\n this.updateMemory(false, addr, b);\n }\n\n /**\n * @this {C1PKeyboard}\n * @param {boolean} fPropagate is true to propagate immediately, false to use normal propagation\n * @param {number} [addr] is the memory address to update; default is the entire memory range\n * @param {number} [bWrite] is the value of any immediately preceding write, or undefined if none\n *\n * Update emulated keyboard memory. By updating the keyboard memory whenever it's written to,\n * as well as whenever a key is pressed or released, I avoid the hit of a read-notification handler.\n * Besides, read-notification handlers are called only AFTER the read has been performed, so it\n * would be too late to update the memory at that point.\n *\n * WARNING: There is a slight risk of an application reading from a different keyboard memory address\n * than it just wrote to. That would be legal, but very odd, and we save valuable time by not updating\n * every other byte in the entire memory range every time a different keyboard \"row\" is selected.\n */\n updateMemory(fPropagate, addr, bWrite)\n {\n /*\n * First, we determine if it's time for event propagation...\n */\n var nCycles = this.cpu.getCycles();\n\n /*\n * Monitoring the C1P's keyboard polling activity is problematic, because not all apps monitor\n * the keyboard in the same way. It's better to simply wait for a certain amount of CPU activity to\n * occur (nCyclesThreshold); it's more reliable and it scales well, because it's not affected by\n * how many cycles we're executing in real time. The trick is finding a value for nCyclesThreshold\n * that works well across the board.\n */\n if (!fPropagate) {\n if (this.cpu.speed == this.cpu.SPEED_MAX)\n fPropagate = (addr !== undefined && this.nWritesSinceLastEvent >= 32);\n else {\n /*\n * We have to handle the delta being less than zero, in case the user changed the speed, thereby\n * resetting the cycle count returned by getCycles().\n */\n var nCycleDelta = nCycles - this.nCyclesSinceLastEvent;\n fPropagate = (nCycleDelta < 0 || nCycleDelta >= this.nCyclesThreshold);\n }\n }\n\n /*\n * Next, we propagate any buffered state (in abKbdStates) as appropriate\n */\n if (fPropagate) {\n var abKbdCols = this.aKbdStates.shift();\n if (abKbdCols !== undefined) {\n if (DEBUG && this.dbg) this.dbg.info(\"kbd update @\" + nCycles + \" cycles, \" + this.nWritesSinceLastEvent + \" writes\");\n this.abKbdColsLast = abKbdCols;\n }\n this.nReadsSinceLastEvent = this.nWritesSinceLastEvent = 0;\n this.nCyclesSinceLastEvent = nCycles;\n }\n /*\n * Then we calculate the value (which may or may not have just been propagated),\n * based on the currently selected keyboard row(s) (bKbdRows).\n */\n var b = 0;\n for (var iRow=0; iRow < 8; iRow++) {\n if (!(this.bKbdRows & (1 << iRow)))\n continue;\n b |= this.abKbdColsLast[iRow];\n }\n /*\n * Now invert all the bits, since I SET the column bit of an \"active\" key,\n * whereas the C1P Model 600 keyboard expects \"active\" column bits to be CLEAR.\n */\n b ^= this.bInvert;\n\n if (addr !== undefined) {\n this.abMem[addr] = b;\n }\n else {\n addr = this.offKbd;\n if (b != this.bWriteLast) {\n for (var offset=addr; offset < this.offKbdLimit; offset++)\n this.abMem[offset] = b;\n }\n }\n this.bWriteLast = b;\n if (DEBUG && this.dbg) this.dbg.info(\"updating kbd \" + Str.toHexWord(addr) + \" with \" + Str.toHexByte(b) + (bWrite !== undefined? (\" following write \" + Str.toHexByte(bWrite)) : \"\") + \" @\" + nCycles + \" cycles\");\n }\n\n /**\n * isShift()\n *\n * @this {C1PKeyboard}\n * @param {number} charCode\n * @return {boolean}\n *\n isShift(charCode)\n {\n return charCode == this.CHARCODE_LSHIFT || charCode == this.CHARCODE_RSHIFT || charCode == this.CHARCODE_CTRL || charCode == this.CHARCODE_SHIFTLOCK;\n }\n */\n\n /**\n * C1PKeyboard.init()\n *\n * This function operates on every HTML element of class \"keyboard\", extracting the\n * JSON-encoded parameters for the C1PKeyboard constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a C1PKeyboard component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeKbd = Component.getElementsByClass(document, C1PJS.APPCLASS, \"keyboard\");\n for (var iKbd=0; iKbd < aeKbd.length; iKbd++) {\n var eKbd = aeKbd[iKbd];\n var parmsKbd = Component.getComponentParms(eKbd);\n var kbd = new C1PKeyboard(parmsKbd);\n Component.bindComponentControls(kbd, eKbd, C1PJS.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize every Keyboard module on the page.\n */\nWeb.onInit(C1PKeyboard.init);\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/video.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass C1PVideo extends Component {\n /**\n * C1PVideo(parmsVideo, canvas, context, imgChars)\n *\n * The Video component can be configured with the following (parmsVideo) properties:\n *\n * model: model number (one of: 540 or 600; 600 is the default)\n * screenWidth: width of the screen window, in pixels\n * screenHeight: height of the screen window, in pixels\n * charCols: number of character columns\n * charRows: number of character rows\n * charWidth: width of charSet characters, in pixels (default is 0)\n * charHeight: height of charSet characters, in pixels (default is 0)\n * charSet: path to image (eg, PNG) file that defines the character set\n * screenColor: background color of the screen window (default is black)\n *\n * The Video object assumes that the video buffer is organized such that offset 0 is mapped\n * to the left-most column and top-most row (col=0,row=0), offset 1 is (1,0), offset 2\n * is (2,0), and so on.\n *\n * The Video object initially contains no underlying video buffer; memory for the buffer\n * must be given to it by the Computer object. We allocate a separate buffer, called\n * the screen buffer, into which we periodically copy the contents of the video buffer\n * via updateScreen(); any differences between the two buffers are then rendered in the\n * associated window, via updateWindow().\n *\n * When updateScreen() finds a byte in the screen buffer must be redisplayed, it converts\n * the offset of that byte into a (col,row) character position for the updateWindow() function,\n * which then converts (col,row) into (x,y) pixel offsets within the underlying canvas.\n *\n * Regarding the C1P (aka Model 600): The C1P has a 1K video buffer located at 0xD000-0xD3FF.\n * The ROM draws the initial \"D/C/W/M ?\" prompt at the \"bottom\" of the video buffer at location\n * 0xD365. That row really begins at 0xD360, but the C1P \"indents\" everything by 5 columns due\n * to the lack of a \"guard band feature.\" Similarly, BASIC defaults to a width of 24 columns\n * avoid display problems near the right edge. BASIC will let you choose a width SMALLER than\n * 24 but not larger. So, while the video buffer supports a theoretical maximum of 32 rows x 32\n * columns, the practical maximum is 25 rows x 24 columns; the last 4 rows of the video buffer\n * are never used, and while content DOES scroll through the top 3 lines of the buffer, it should\n * never be assumed that you can see the top 3 lines.\n *\n * This is partially confirmed by the \"C1P Character Graphics Reference Manual\", p3, which says\n * that the \"the visible character field consists of 25 lines of 25 columns\" and that the \"first\n * visible character in the upper left of the screen is accessed via address 53379,\" or 0xD083.\n * However, they were wrong about both the number of columns and the first visible character.\n *\n * They probably meant 0xD085, because as mentioned earlier, the C1P indents every row by 5\n * characters, not 3. But that's not correct either, because the difference between 0xD365\n * (where the bottom line starts) and 0xD085 is 0x2E0, or 736. 736 divided by 32 equals 23;\n * add the bottom row, and that would give you 24 visible rows, not 25. Since we now have\n * screenshots of a C1P monitor displaying 25 rows (courtesy of Stephan Mühlstrasser), C1Pjs\n * now assumes that only the first 3 lines are not visible, and that the address of the first\n * visible character is actually 0xD065 (53349), yielding 25 visible rows.\n *\n * All of this explains why we now use setDimensions(iRowTop=3, nRowsVisible=25) instead of\n * setDimensions(iRowTop=4, nRowsVisible=24) for the Model 600.\n *\n * Model 540 Video Board vs. Model 600 \"Superboard II\"\n * ---------------------------------------------------\n * This emulation was originally written for the Model 600 \"Superboard II\" (eg, Challenger 1P).\n * Support for the Model 540 video board (as used in the Challenger II-4P and II-8P) was added\n * later.\n *\n * NOTE: When Model 540 video emulation is enabled, Model 542 keyboard emulation must also be\n * enabled, because the former always came with the latter keyboard interface; this is why when\n * we call this.setModel(540), we must also notify the Keyboard via kbd.setModel(542).\n *\n * Key features/differences of the Model 540 video board include:\n *\n * 2K (8 pages) of video memory located at 0xD000-0xD7FF\n * Two display modes: 32 rows x 64 cols (default on power up), and 32 rows x 32 cols\n * 64 bytes per screen row, regardless which display mode is selected\n * The following options can be selected via WRITE to port address 0xDE00:\n * Bit 0: clear to enable 32/64 mode (default on power up), set to enable 32/32\n * Bit 1: 1=tone on (542 keyboard)\n * Bit 2: 1=color on (Rev. B only?)\n * bit 3: 1=enable 38-40Khz AC Home control output (Rev. B only?)\n * Video timing counter status via READ from port address 0xDE00:\n * Bit 7: 0 for 1/120 second, then 1 for 1/120 second, based on video clock (60Hz)\n *\n * @this {C1PVideo}\n * @param {Object} parmsVideo\n * @param {HTMLCanvasElement} canvas\n * @param {CanvasRenderingContext2D} context\n * @param {HTMLImageElement} imgChars\n */\n constructor(parmsVideo, canvas, context, imgChars)\n {\n super(\"C1PVideo\", parmsVideo);\n\n this.nDefaultModel = parmsVideo['model'];\n this.nDefaultCols = parmsVideo['charCols'];\n this.nDefaultRows = parmsVideo['charRows'];\n\n this.cxScreen = parmsVideo['screenWidth'];\n this.cyScreen = parmsVideo['screenHeight'];\n\n /*\n * These (source) character dimensions are tentative, and may not even be provided,\n * but they will become definitive once imgChars has finished loading and setReady() is called.\n */\n this.cxChar = parmsVideo['charWidth'];\n this.cyChar = parmsVideo['charHeight'];\n\n /*\n * This is a preliminary call to setDimensions(), to initialize default screen buffer and\n * window dimensions. A more extensive call to setDimensions() will take place when setModel()\n * is called later, from reset() and possibly via the tripGuard() handler.\n *\n * This preliminary call merely establishes a default screen buffer size, so that when\n * setBuffer() is called, it's able to verify the assigned address space is at least as big\n * as the screen buffer.\n */\n this.setDimensions();\n\n this.canvasScreen = canvas;\n this.contextScreen = context;\n this.imgChars = imgChars;\n\n /*\n * Support for disabling (or, less commonly, enabling) image smoothing, which all browsers\n * seem to support now (well, OK, I still have to test the latest MS Edge browser), despite\n * it still being labelled \"experimental technology\". Let's hope the browsers standardize\n * on this. I see other options emerging, like the CSS property \"image-rendering: pixelated\"\n * that's apparently been added to Chrome. Sigh.\n */\n var i, sEvent, asWebPrefixes = ['', 'moz', 'ms', 'webkit'];\n var fSmoothing = parmsVideo['smoothing'];\n var sSmoothing = Web.getURLParm('smoothing');\n if (sSmoothing) fSmoothing = (sSmoothing == \"true\");\n if (fSmoothing != null) {\n for (i = 0; i < asWebPrefixes.length; i++) {\n sEvent = asWebPrefixes[i];\n if (!sEvent) {\n sEvent = 'imageSmoothingEnabled';\n } else {\n sEvent += 'ImageSmoothingEnabled';\n }\n if (this.contextScreen[sEvent] !== undefined) {\n this.contextScreen[sEvent] = fSmoothing;\n break;\n }\n }\n }\n\n /*\n * QUESTION: Does this video port exist only on the Model 540?\n */\n this.addrVideoPort = 0xDE00; // WARNING: Hard-coded port address -JP\n }\n\n /**\n * @this {C1PVideo}\n * @param {boolean} [fPowerOn] is true for the initial reset, so that we have\n * the option of rendering \"random\" graphic characters, just like the real machine would do.\n */\n reset(fPowerOn)\n {\n this.setModel(this.nDefaultModel);\n\n if (this.abMem) {\n /*\n * Let's treat every reset like a power-cycle, just for fun.\n * If you don't think that's fun, then simply remove the next line.\n *\n fPowerOn = true;\n */\n for (var offset = this.offVideo; offset < this.offVideoLimit; offset++) {\n var b = (fPowerOn? Math.floor(Math.random() * 256) : 0x20);\n\n this.abMem[offset] = b;\n }\n }\n }\n\n /**\n * @this {C1PVideo}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"refresh\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n switch(sBinding) {\n case \"refresh\":\n this.bindings[sBinding] = control;\n control.onclick = function(video) {\n return function() {\n if (DEBUG) video.println(\"refreshScreen()\");\n video.initScreen();\n video.updateScreen();\n };\n }(this);\n return true;\n default:\n break;\n }\n return false;\n }\n\n /**\n * @this {C1PVideo}\n * @param {Array} abMemory\n * @param {number} start\n * @param {number} end\n * @param {C1PCPU} cpu\n */\n setBuffer(abMemory, start, end, cpu)\n {\n this.abMem = abMemory;\n this.offVideo = start;\n this.cbVideo = end - start + 1;\n this.offVideoLimit = this.offVideo + this.cbVideo;\n\n if (cpu) {\n this.cpu = cpu;\n if (this.addrVideoPort !== undefined) {\n cpu.addReadNotify(this.addrVideoPort, this.addrVideoPort, this, this.getByte);\n cpu.addWriteNotify(this.addrVideoPort, this.addrVideoPort, this, this.setByte);\n }\n }\n this.reset(true);\n }\n\n /**\n * @this {C1PVideo}\n * @param {number|undefined} [nCols] (default is nDefaultCols)\n * @param {number|undefined} [nRows] (default is nDefaultRows)\n * @param {number|undefined} [iRowTop] (eg, 4; default is 0)\n * @param {number|undefined} [nRowsVisible] (eg, 24; default is nRows)\n */\n setDimensions(nCols, nRows, iRowTop, nRowsVisible)\n {\n this.nCols = (nCols !== undefined? nCols : this.nDefaultCols);\n this.nRows = (nRows !== undefined? nRows : this.nDefaultRows);\n this.cbScreen = this.nCols * this.nRows;\n this.offVideoLimit = this.offVideo + this.cbScreen;\n /*\n * Set the first visible row and total visible rows next\n */\n this.iRowTop = (iRowTop !== undefined? iRowTop : 0);\n this.nRowsVisible = (nRowsVisible !== undefined? nRowsVisible : nRows);\n this.setDrawingDimensions();\n }\n\n /**\n * @this {C1PVideo}\n *\n * cxScreen and cyScreen give us the overall dimensions of the destination surface. Dividing that by the number of\n * columns and rows yields a target cell size (cxCharDst,cyCharDst), which may or may not map 1-1 to the source cell size\n * (cxChar,cyChar).\n */\n setDrawingDimensions()\n {\n this.cxCharDst = Math.floor(this.cxScreen / this.nCols);\n this.cyCharDst = Math.floor(this.cyScreen / this.nRowsVisible);\n }\n\n /**\n * @this {C1PVideo}\n */\n setFocus()\n {\n this.canvasScreen.focus();\n }\n\n /**\n * @this {C1PVideo}\n * @param {number} nModel\n */\n setModel(nModel)\n {\n this.nModel = nModel;\n /*\n * Default to model 600 behavior (1K video buffer);\n * the only other supported model is 540 (2K video buffer).\n */\n if (this.nModel == 600) {\n this.setDimensions(this.nDefaultCols, this.nDefaultRows, 3, 25);\n if (this.cbScreen == 1024 && this.cpu) {\n /*\n * NOTE: We deliberately set the guard address to the LAST byte of the 2K\n * buffer range, not the FIRST byte, which has the same effect but with the\n * added benefit of deferring any screen update until after the \"Model 540\"\n * screen initialization code has completely blanked the entire 2K buffer,\n * avoiding a brief flicker of unsightly characters.\n */\n this.addrGuard = this.offVideoLimit + this.cbScreen - 1;\n this.cpu.addWriteNotify(this.addrGuard, this.addrGuard, this, this.tripGuard);\n }\n }\n else {\n this.println(\"updated video model: \" + this.nModel);\n this.setDimensions(64, 32);\n }\n this.initScreen();\n this.updateScreen();\n }\n\n /**\n * @this {C1PVideo}\n * @param {boolean} fOn\n * @param {C1PComputer} cmp\n */\n setPower(fOn, cmp)\n {\n /*\n * NOTE: No one should be calling power(true) before first checking isReady(), but we check\n * it ourselves, too. This also means that updateScreen() need check only fPower and not isReady(),\n * since we guarantee that the former implies the latter.\n */\n if (fOn && !this.flags.powered && this.isReady()) {\n this.flags.powered = true;\n if (DEBUGGER) this.dbg = cmp.getComponentByType(\"debugger\");\n /*\n * If we have an associated keyboard, then ensure that the keyboard will be notified whenever\n * the canvas gets focus and receives input.\n *\n * Also, when simulating a Model 540 video board, we need to access to the Keyboard component due\n * to some shared I/O responsibilities; ie, bit 1 of the video control port at 0xDE00 enables whatever\n * tone has been selected via the keyboard frequency port at 0xDF01 (frequency == 49152/n, where n\n * is the value stored at 0xDF01).\n */\n this.kbd = cmp.getComponentByType(\"keyboard\");\n if (this.kbd) {\n this.kbd.setBinding(\"canvas\", \"keyDown\", this.canvasScreen);\n this.kbd.setBinding(\"canvas\", \"keyPress\", this.canvasScreen);\n this.kbd.setBinding(\"canvas\", \"keyUp\", this.canvasScreen);\n }\n }\n else\n if (!fOn && this.flags.powered) {\n this.flags.powered = false;\n /*\n * This is where we would add some method of blanking the display, without the disturbing the video\n * buffer contents, and blocking all further updates to the display.\n */\n }\n }\n\n /**\n * cxChar and cyChar are the source cell size. Originally, those values came strictly from the parmsVideo\n * 'charWidth' and 'charHeight' properties. Now, if those aren't defined (which is normally the case now),\n * then we infer the source cell size from the dimensions of imgChars, which is expected to be a 16x16 array of\n * character bitmaps. We could be even more flexible, by allowing imgChars to be any rectangular dimension\n * (eg, 1x256) as long as we can assume it contains exactly 256 characters, but there's no need to get carried away.\n *\n * @this {C1PVideo}\n * @param {boolean} [fReady] is assumed to indicate \"ready\" unless EXPLICITLY set to false\n */\n setReady(fReady)\n {\n if (!this.cxChar) this.cxChar = Math.floor(this.imgChars.width / 16);\n if (!this.cyChar) this.cyChar = Math.floor(this.imgChars.height / 16);\n super.setReady();\n }\n\n /**\n * @this {C1PVideo}\n * @param {number} addr (ie, addrVideoPort)\n * @param {number|undefined} addrFrom (not defined whenever the Debugger tries to read the specified addr)\n *\n * NOTE: Ordinarily, I wouldn't allow Debugger writes (addrFrom === undefined) to interfere with the simulated\n * hardware state, but for now, I find it useful to be able to prod the simulation code directly from the Debugger.\n */\n getByte(addr, addrFrom)\n {\n var b = this.cpu.getByte(addr);\n if (addrFrom !== undefined) {\n if (DEBUGGER && this.dbg) this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_VIDEO);\n }\n /*\n * The only documented READ bit in addrVideoPort is bit 7, which is supposed to alternate between\n * 0 and 1 every 1/120 of a second. There's no way we're going to add special code to the emulator to update\n * this stupid byte every 8,333 cycles (assuming 1Mhz operation), so clearly we're going to fake it.\n *\n * Faking it means that any polling code will unavoidably get a stale value the FIRST time it reads bit 7.\n * However, we can still do a pretty good job of faking any EXTENSIVE polling: get the number of cycles\n * executed so far, divide that by 8333, floor the quotient, and then set/clear bit 7 according to whether the\n * result is odd/even.\n */\n var nCyclesHigh = Math.floor(this.cpu.getCycles() / 8333);\n this.cpu.setByte(addr, (b & 0x7F) | ((nCyclesHigh & 0x1)? 0x80 : 0));\n }\n\n /**\n * @this {C1PVideo}\n * @param {number} addr (ie, addrVideoPort)\n * @param {number|undefined} addrFrom (not defined whenever the Debugger tries to write the specified addr)\n */\n setByte(addr, addrFrom)\n {\n if (addrFrom !== undefined) {\n if (DEBUGGER && this.dbg) this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_VIDEO);\n }\n }\n\n /**\n * @this {C1PVideo}\n * @param {number} addr (ie, addrGuard)\n * @param {number|undefined} addrFrom (not defined whenever the Debugger tries to read the specified addr)\n */\n tripGuard(addr, addrFrom)\n {\n /*\n * Don't trigger any further hardware emulation (beyond what we've already stored in memory) if\n * the Debugger performed this read (need a special Debugger I/O command if/when you really want to do that).\n */\n if (addrFrom !== undefined) {\n if (DEBUGGER && this.dbg) this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_VIDEO, true);\n /*\n * The CPU has just written to the guard address we established just beyond the video buffer's 1K boundary,\n * implying that the system thinks we have a 2K buffer instead. So we bump our model to 540, bump the\n * associated keyboard model to 542, and remove this guard handler.\n */\n this.setModel(540);\n if (this.kbd) this.kbd.setModel(542);\n this.cpu.removeWriteNotify(this.addrGuard, this.addrGuard, this, this.tripGuard);\n }\n }\n\n /**\n * @this {C1PVideo}\n */\n initScreen()\n {\n this.abScreen = new Array(this.cbScreen);\n for (var offset=0; offset <= this.cbScreen; offset++) {\n this.abScreen[offset] = -1; // initialize every cell of the screen to an invalid value\n }\n }\n\n /**\n * updateScreen() updates the screen buffer from the video buffer and updates the window with any changes.\n *\n * @this {C1PVideo}\n * @return {boolean}\n *\n * For every byte in the video buffer, this renders it if it differs from the byte stored in the screen buffer,\n * and then updates the screen buffer to match. Since initScreen() sets every byte in the screen buffer\n * to an illegal byte value (ie, a value which is outside the byte range 0x00-0xff), that assures the first call\n * to updateScreen() will redraw every byte in the video buffer.\n */\n updateScreen()\n {\n var offset = 0;\n if (this.flags.powered) {\n while (offset < this.cbScreen) {\n var b = this.abMem[this.offVideo + offset];\n if (this.abScreen[offset] != b) {\n if (!this.writeByte(offset, b)) {\n break;\n }\n this.abScreen[offset] = b;\n }\n offset++;\n }\n }\n return (offset == this.cbScreen);\n }\n\n /**\n * @this {C1PVideo}\n * @param {number} offset\n * @param {number} b\n * @return {boolean}\n */\n writeByte(offset, b)\n {\n var col = offset % this.nCols;\n var row = Math.floor(offset / this.nCols);\n return this.updateWindow(col, row, b);\n }\n\n /**\n * updateWindow(col, row, b)\n *\n * Updates a particular position (row,col) in the associated window with the given byte (b)\n *\n * @this {C1PVideo}\n * @param {number} col\n * @param {number} row\n * @param {number} b\n * @return {boolean} true if successful, false if not\n *\n * I originally used (screenWidth,screenHeight) == (512,448) and (cols,rows) == (32,32) and (cxChar,cyChar) == (16,16),\n * and I simply copied the source cells 1-to-1 to the destination (16,16), knowing that we would never try to display\n * more than 28 rows (the last 4 rows of the 32 possible rows were never used to display any content). However, I should\n * still have ignored any attempt to draw past row 28 (aka screenHeight 448). I now perform row clipping and biasing,\n * according to the first visible row (iRowTop) and total visible rows (nRowsVisible).\n *\n * Moreover, I no longer copy the source cell images to the destination 1-to-1. I calculate (cxCharDst,cyCharDst)\n * separately (see setDrawingDimensions). And I no longer assume that (cxChar,cyChar) are (16,16); once the source\n * image file has finished loading, I calculate (cxChar,cyChar) based on the size of image file (see setReady). I made\n * this change when I created chargen1x.png. In fact, at first I thought I might be able to eliminate chargen2x.png\n * and just let drawImage() scale up the individual character images from (8,8) to (16,16) or whatever (cxCharDst,cyCharDst)\n * size was needed, but the results were fuzzy, so it's still best to use chargen2x.png when using larger window sizes.\n */\n updateWindow(col, row, b)\n {\n if (row >= this.iRowTop) {\n row -= this.iRowTop;\n if (row < this.nRowsVisible) {\n var xChar = (b * this.cxChar);\n var ySrc = Math.floor(xChar / this.imgChars.width) * this.cyChar;\n var xSrc = xChar % this.imgChars.width;\n var xDst = col * this.cxCharDst;\n var yDst = row * this.cyCharDst;\n // if (DEBUG) this.log(\"updateWindow(\" + col + \",\" + row + \",\" + b +\"): drawing from \" + xSrc + \",\" + ySrc + \" to \" + xDst + \",\" + yDst);\n this.contextScreen.drawImage(this.imgChars, xSrc, ySrc, this.cxChar, this.cyChar, xDst, yDst, this.cxCharDst, this.cyCharDst);\n }\n }\n return true;\n }\n\n /**\n * C1PVideo.init()\n *\n * This function operates on every HTML element of class \"video\", extracting the\n * JSON-encoded parameters for the C1PVideo constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a C1PVideo component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeVideo = Component.getElementsByClass(document, C1PJS.APPCLASS, \"video\");\n for (var iVideo=0; iVideo < aeVideo.length; iVideo++) {\n var eVideo = aeVideo[iVideo];\n var parmsVideo = Component.getComponentParms(eVideo);\n\n /*\n * As noted in keyboard.js, the keyboard on an iOS device pops up with the SHIFT key depressed,\n * which is not the initial keyboard state that the C1P expects. I originally tried to fix that by\n * adding an 'autocapitalize=\"off\"' attribute alongside the 'contenteditable=\"true\"' attribute\n * on the <canvas> element, but apparently Safari honors that only inside certain elements (eg, <input>).\n *\n * I've since settled on a better work-around in keyboard.js, so I've stopped worrying about how to make\n * \"autocapitalize\" work here.\n */\n var eCanvas = /** @type {HTMLCanvasElement} */ (document.createElement(\"canvas\"));\n if (eCanvas === undefined || !eCanvas.getContext) {\n eVideo.innerHTML = \"<br/>Missing <canvas> support. Please try a newer web browser.\";\n return;\n }\n eCanvas.setAttribute(\"class\", C1PJS.APPCLASS + \"-canvas\");\n eCanvas.setAttribute(\"width\", parmsVideo['screenWidth']);\n eCanvas.setAttribute(\"height\", parmsVideo['screenHeight']);\n\n eCanvas.setAttribute(\"contenteditable\", \"true\");\n eCanvas.setAttribute(\"autocapitalize\", \"off\");\n eCanvas.setAttribute(\"autocorrect\", \"off\");\n eCanvas.style.backgroundColor = parmsVideo['screenColor'];\n\n /*\n * HACK: A canvas style of \"auto\" provides for excellent responsive canvas scaling in EVERY browser\n * except IE9/IE10, so I recalculate the appropriate CSS height every time the parent DIV is resized;\n * IE11 works without this hack, so we take advantage of the fact that IE11 doesn't report itself as \"MSIE\".\n */\n eCanvas.style.height = \"auto\";\n if (Web.getUserAgent().indexOf(\"MSIE\") >= 0) {\n eCanvas.style.height = (((eVideo.clientWidth * parmsVideo['screenHeight']) / parmsVideo['screenWidth']) | 0) + \"px\";\n eVideo.onresize = function(eParent, eChild, cx, cy) {\n return function() {\n eChild.style.height = (((eParent.clientWidth * cy) / cx) | 0) + \"px\";\n };\n }(eVideo, eCanvas, parmsVideo['screenWidth'], parmsVideo['screenHeight']);\n }\n eVideo.appendChild(eCanvas);\n\n /*\n * Now we can create the Video object, record it, and wire it up to the associated document elements.\n *\n * Regarding \"new Image()\", see https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement.Image:\n *\n * This constructor exists for historical reasons only and returns an HTMLImageElement instance just as\n * document.createElement('img') would.\n */\n var imgCharSet = new Image();\n var eContext = /** @type {CanvasRenderingContext2D} */ (eCanvas.getContext(\"2d\"));\n var video = new C1PVideo(parmsVideo, eCanvas, eContext, imgCharSet);\n imgCharSet.onload = function(video, sCharSet) {\n return function() {\n if (DEBUG) video.log(\"onload(): finished loading \" + sCharSet);\n video.setReady();\n };\n }(video, parmsVideo['charSet']); // jshint ignore:line\n imgCharSet.src = parmsVideo['charSet'];\n\n /*\n * Bind any video-specific controls (eg, the Refresh button). There are no essential controls, however;\n * even the \"Refresh\" button is just a diagnostic tool, to verify that the screen contents are up-to-date.\n */\n Component.bindComponentControls(video, eVideo, C1PJS.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize every Video module on the page.\n */\nWeb.onInit(C1PVideo.init);\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/serial.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass C1PSerialPort extends Component {\n /**\n * C1PSerialPort(parmsSerial)\n *\n * The SerialPort component has no component-specific parameters.\n *\n * @this {C1PSerialPort}\n * @param {Object} parmsSerial\n */\n constructor(parmsSerial)\n {\n super(\"C1PSerialPort\", parmsSerial);\n\n this.flags.powered = false;\n this.fDemo = parmsSerial['demo'];\n\n this.reset(true);\n }\n\n /**\n * @this {C1PSerialPort}\n * @param {boolean} [fHard]\n */\n reset(fHard)\n {\n /*\n * Because we reset the machine at the start of a 6502 HEX command file auto-load,\n * we must avoid tossing the serial port's input buffer in that particular case (2).\n */\n if (fHard || this.autoLoad != C1PSerialPort.AUTOLOAD_6502) {\n\n this.bInput = -1;\n this.iInput = 0;\n this.sInput = \"\";\n if (this.fDemo) {\n this.sInput = \"10 PRINT \\\"HELLO OSI #\" + this.getMachineNum() + \"\\\"\\n\";\n }\n\n // this.sOutput = new Array(0);\n // this.iOutputNext = 0;\n\n this.fConvertLF = true;\n this.autoLoad = C1PSerialPort.AUTOLOAD_NONE;\n }\n }\n\n /**\n * @this {C1PSerialPort}\n */\n start()\n {\n if (this.kbd && this.fDemo) {\n this.kbd.injectKeys(\" C\\n\\n\", 3000); // override the default injection delay (currently 300ms)\n setTimeout(function(serial) { return function() {serial.startLoad();}; }(this), 12000);\n }\n this.fDemo = false;\n }\n\n /**\n * @this {C1PSerialPort}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"listSerial\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var serial = this;\n\n switch(sBinding) {\n\n case \"listSerial\":\n this.bindings[sBinding] = control;\n return true;\n\n case \"loadSerial\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickLoadSerial(event) {\n if (serial.bindings[\"listSerial\"]) {\n var sFile = serial.bindings[\"listSerial\"].value;\n // serial.println(\"loading \" + sFile + \"...\");\n Web.getResource(sFile, null, true, function(sURL, sResponse, nErrorCode) {\n serial.loadFile(sURL, sResponse, nErrorCode);\n });\n }\n };\n return true;\n\n case \"mountSerial\":\n /*\n * Check for non-mobile (desktop) browser and the availability of FileReader\n */\n var controlInput = /** @type {Object} */ (control);\n if (!Web.isMobile() && window && 'FileReader' in window) {\n this.bindings[sBinding] = controlInput;\n /*\n * Enable \"Mount\" button only if a file is actually selected\n */\n controlInput.onchange = function onChangeMountSerial() {\n var fieldset = controlInput.children[0];\n var files = fieldset.children[0].files;\n var submit = fieldset.children[1];\n submit.disabled = !files.length;\n };\n controlInput.onsubmit = function onSubmitMountSerial(event) {\n var file = event.currentTarget[1].files[0];\n\n var reader = new FileReader();\n reader.onload = function() {\n // serial.println(\"mounting \" + file.name + \"...\");\n serial.loadFile(file.name, reader.result.toString(), 0);\n };\n reader.readAsText(file);\n\n /*\n * Prevent reloading of web page after form submission\n */\n return false;\n };\n }\n else {\n if (DEBUG) this.log(\"Local file support not available\");\n controlInput.parentNode.removeChild(/** @type {Node} */ (controlInput));\n }\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * @this {C1PSerialPort}\n * @param {Array} abMemory\n * @param {number} start\n * @param {number} end\n * @param {C1PCPU} cpu\n */\n setBuffer(abMemory, start, end, cpu)\n {\n this.abMem = abMemory;\n this.offPort = start;\n this.cbPort = end - start + 1;\n this.offPortLimit = this.offPort + this.cbPort;\n if ((this.cpu = cpu)) {\n cpu.addReadNotify(start, end, this, this.getByte);\n cpu.addWriteNotify(start, end, this, this.setByte);\n }\n this.setReady();\n }\n\n /**\n * @this {C1PSerialPort}\n * @param {boolean} fOn\n * @param {C1PComputer} cmp\n *\n * We make a note of the Computer component, so that we can invoke its reset() method whenever we need to\n * simulate a warm start, and we query the Keyboard component so that we can use its injectKeys() function.\n */\n setPower(fOn, cmp)\n {\n if (fOn && !this.flags.powered) {\n this.flags.powered = true;\n this.cmp = cmp;\n this.kbd = cmp.getComponentByType(\"keyboard\");\n if (DEBUGGER) this.dbg = cmp.getComponentByType(\"debugger\");\n }\n }\n\n /**\n * @this {C1PSerialPort}\n */\n startLoad()\n {\n this.autoLoad = C1PSerialPort.AUTOLOAD_BASIC;\n this.kbd.injectKeys(\"LOAD\\n\");\n }\n\n /**\n * @this {C1PSerialPort}\n * @param {string} sFileName\n * @param {string} sFileData (null if getResource() encountered an error)\n * @param {number} nResponse from server\n */\n loadFile(sFileName, sFileData, nResponse)\n {\n if (!sFileData) {\n this.println(\"Error loading file \\\"\" + sFileName + \"\\\" (\" + nResponse + \")\");\n return;\n }\n\n this.iInput = 0;\n this.sInput = sFileData;\n this.fConvertLF = true;\n this.autoLoad = C1PSerialPort.AUTOLOAD_NONE;\n\n /*\n * The following code adds support for loading \"65V\" files encoded as JSON, which is a cleaner\n * way to store and deliver those files when they contain binary (non-ASCII) data.\n *\n * For example, my 6502 ASSEMBLER/DISASSEMBLER program starts with a conventional \"65V\" loading\n * sequence, which loads and launches a small program loader that loads the rest of the program\n * using a raw (1-to-1) binary format instead of the usual (3-to-1) HEX format used by \"65V\" files.\n *\n * The \"rawness\" of the binary format also necessitates disabling fConvertLF.\n */\n if (Str.endsWith(sFileName, \".json\")) {\n try {\n /*\n * The most likely source of any exception will be here: parsing the JSON-encoded data.\n */\n var s = \"\";\n var data = eval(\"(\" + sFileData + \")\");\n var ab = data['bytes'];\n for (var i = 0; i < ab.length; i++) {\n s += String.fromCharCode(ab[i]);\n }\n this.sInput = s;\n this.fConvertLF = false;\n } catch (e) {\n this.println(\"Error processing file \\\"\" + sFileName + \"\\\": \" + e.message);\n return;\n }\n }\n\n if (this.cmp && this.kbd && this.cpu.isRunning()) {\n this.println(\"auto-loading \" + sFileName);\n /*\n * QUESTION: Is this setFocus() call strictly necessary? We're being called in the\n * context of getResource(), not some user action. If there was an original user action,\n * then the handler for THAT action should take care to switch focus back, not us.\n */\n this.cpu.setFocus();\n /*\n * We interpret the presence of a \".\" at the beginning of the file as a \"65V Monitor\"\n * address-mode command, and consequently treat the file as 6502 HEX command file.\n *\n * Anything else is treated as commands for the BASIC interpreter, which we re-initialize\n * with \"NEW\" and \"LOAD\" commands. To prevent that behavior, halt the CPU, perform the load,\n * and then start it running again. BASIC will start reading the data as soon as you type\n * LOAD.\n */\n if (this.sInput.charAt(0) != '.') {\n this.autoLoad = C1PSerialPort.AUTOLOAD_BASIC;\n this.kbd.injectKeys(\"NEW\\nLOAD\\n\");\n }\n else {\n /*\n * Set autoLoad to AUTOLOAD_6502 before the reset, so that when our reset() method is called,\n * we'll take care to preserve all the data we just loaded.\n */\n this.autoLoad = C1PSerialPort.AUTOLOAD_6502;\n /*\n * Although the Keyboard allows us to inject any key, even the BREAK key, like so:\n *\n * this.kbd.injectKeys(String.fromCharCode(this.kbd.CHARCODE_BREAK))\n *\n * it's easier to initiate a reset() ourselves and then start the machine-language load process\n */\n this.cmp.reset(true);\n this.kbd.injectKeys(\"ML\");\n }\n }\n else {\n this.println(sFileName + \" ready to load\");\n }\n }\n\n /**\n * @this {C1PSerialPort}\n * @param {number} addr\n * @param {number|undefined} addrFrom (not defined whenever the Debugger tries to read the specified addr)\n */\n getByte(addr, addrFrom)\n {\n /*\n * Don't trigger any further hardware emulation (beyond what we've already stored in memory) if\n * the Debugger performed this read (need a special Debugger I/O command if/when you really want to do that).\n */\n if (addrFrom !== undefined) {\n /*\n * WARNING: All I need to do for now is load the COM interface's \"data byte\"\n * with the next byte from the virtual cassette data stream -JP\n */\n if (!(addr & 0x01)) {\n /*\n * An EVEN address implies they're looking, so if we have a fresh buffer,\n * then prime the pump.\n */\n if (this.sInput && !this.iInput)\n this.advanceInput();\n } else {\n /*\n * An ODD address implies they just grabbed a data byte, so prep the next data byte.\n */\n this.advanceInput();\n }\n }\n }\n\n /**\n * @this {C1PSerialPort}\n * @param {number} addr\n * @param {number|undefined} addrFrom (not defined whenever the Debugger tries to write the specified addr)\n */\n setByte(addr, addrFrom)\n {\n /*\n * Don't trigger any further hardware emulation (beyond what we've already stored in memory) if\n * the Debugger performed this write (need a special Debugger I/O command if/when you really want to do that).\n */\n if (addrFrom !== undefined) {\n if (DEBUGGER && this.dbg) this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_SERIAL, true);\n /*\n * WARNING: I don't yet care what state the CPU puts the port into. When it's time to support serial output,\n * obviously that will become an issue.\n */\n }\n }\n\n /**\n * @this {C1PSerialPort}\n */\n advanceInput()\n {\n if (this.sInput !== undefined) {\n this.bInput = -1;\n if (this.iInput < this.sInput.length) {\n var b = this.sInput.charCodeAt(this.iInput++) & 0xff;\n if (this.fConvertLF) {\n if (b == 0x0a) b = 0x0d;\n }\n this.bInput = b;\n // if (DEBUG) this.log(\"advanceInput(\" + Str.toHexByte(b) + \")\");\n }\n else {\n this.sInput = \"\";\n this.iInput = 0;\n if (DEBUG) this.log(\"advanceInput(): out of data\");\n if (this.autoLoad == C1PSerialPort.AUTOLOAD_BASIC && this.kbd) {\n this.kbd.injectKeys(\" \\nRUN\\n\");\n }\n this.autoLoad = C1PSerialPort.AUTOLOAD_NONE;\n }\n this.updateMemory();\n }\n // else if (DEBUG) this.log(\"advanceInput(): no input\");\n }\n\n /**\n * @this {C1PSerialPort}\n */\n updateMemory()\n {\n var offset;\n /*\n * Update all the status (even) bytes\n */\n for (offset = this.offPort+0; offset < this.offPortLimit; offset+=2) {\n this.abMem[offset] = (this.bInput >= 0? C1PSerialPort.STATUS_DATA : C1PSerialPort.STATUS_NONE);\n }\n /*\n * Update all the data (odd) bytes\n */\n for (offset = this.offPort+1; offset < this.offPortLimit; offset+=2) {\n this.abMem[offset] = (this.bInput >= 0? this.bInput : 0);\n }\n }\n\n /**\n * C1PSerialPort.init()\n *\n * This function operates on every HTML element of class \"serial\", extracting the\n * JSON-encoded parameters for the C1PSerialPort constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a C1PSerialPort component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeSerial = Component.getElementsByClass(document, C1PJS.APPCLASS, \"serial\");\n for (var iSerial=0; iSerial < aeSerial.length; iSerial++) {\n var eSerial = aeSerial[iSerial];\n var parmsSerial = Component.getComponentParms(eSerial);\n var serial = new C1PSerialPort(parmsSerial);\n Component.bindComponentControls(serial, eSerial, C1PJS.APPCLASS);\n }\n }\n}\n\nC1PSerialPort.STATUS_NONE = 0x00;\nC1PSerialPort.STATUS_DATA = 0x01; // indicates data available\n\n/*\n * Values for autoLoad:\n *\n * 0: no auto-load active\n * 1: BASIC command file auto-load in progress\n * 2: 6502 HEX command file auto-load in progress\n */\nC1PSerialPort.AUTOLOAD_NONE = 0;\nC1PSerialPort.AUTOLOAD_BASIC = 1;\nC1PSerialPort.AUTOLOAD_6502 = 2;\n\n/*\n * Initialize every SerialPort module on the page.\n */\nWeb.onInit(C1PSerialPort.init);\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/disk.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * @class Drive\n * @property {number} iType\n * @property {number} nTracks\n * @property {boolean} fProtected\n * @property {number} nIndexPulse\n * @property {number} iTrackSelect\n * @property {number} iTrackOffset\n * @property {Array} aTracks\n */\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass C1PDiskController extends Component {\n /**\n * C1PDiskController(parmsDC)\n *\n * The C1PDiskController component has no component-specific parameters.\n *\n * This component is being built to supplement a C1P (aka SuperBoard II) Model 600\n * single-board computer with the addition of a 610 Accessory Board, which included:\n *\n * MC6820 PIA (Peripheral Interface Adapter at $C000-$C003, decoded at $C000-$C00F)\n * MC6850 ACIA (Asynchronous Communications Interface Adapter at $C010-$C011, decoded at $C010-$C01F)\n *\n * From \"OSI C1P Technical Report\" p.4 regarding the 610 Accessory Board:\n *\n * \"This board holds up to 24K of additional RAM memory, a dual mini-floppy disk controller,\n * a BUS expansion facility to Model 620 BUS adapter, and switching circuitry to route the\n * 600 board's serial interface to both the modem and printer as well as an audio cassette.\n * Thus, a fully expanded Challenger lP system can have BASIC-in-ROM, 32K of RAM memory,\n * dual mini-floppies, cassette, printer, modem, and full BUS expansion capability to the OSI\n * 48 line BUS through which over 40 accessories can be added (A/D, D/A, voice, I/O, more memory,\n * etc.).\"\n *\n * On p.20, the Report says that the 610 Accessory Board contains:\n *\n * - Up to 24K of RAM\n * - Dual mini-floppy controller\n * - Real Time Clock (although elsewhere the Report says this is disabled by default)\n * - Expansion interface to a model 620 BUS adapter\n *\n * On p.21, the Report also says:\n *\n * \"The dual mini-floppy interface is designed after Ohio Scientific's extremely popular\n * and successful 470 floppy disk controller. This floppy disk controller and encoding\n * technique has been field proven for several years in thousands of floppy disks and is\n * believed to be one of the most reliable floppy disk configurations in existence. Although\n * the Challenger lP product line is new, it has the advantage of the experience of a company\n * which has been building high performance microcomputers for several years.\"\n *\n * From \"PEEK 65\" Vol.2 No.3 March 1981, p.9:\n *\n * \"The 470 board wired as a floppy disk controller contains two different interfaces:\n * a PIA and an ACIA. The PIA A and B ports are used in control circuits: raise and lower\n * the head, detect drive ready, detect sector hole, clear error faults, etc. The ACIA is\n * the interface over which the data actually travels. Typical operation is to drop the head,\n * reset the ACIA, wait for the index hole to come around, activate the read or write circuit,\n * then read or write characters through the ACIA.\"\n *\n * 470 Board Addressing\n * --------------------\n *\n * Address Read Write\n * ------- ---- -----\n * C000 PIA: PA0 thru PA7 PIA: PA0 thru PA7 or DDA0 thru DDA7\n * C001 PIA: Port A Ctrl PIA: Port A Control\n * C002 PIA: PB0 thru PB7 PIA: PB0 thru PB7 or DDB0 thru DDB7\n * C003 PIA: Port B Ctrl PIA: Port B Control\n * C010 ACIA: Status Reg. ACIA: Control Register\n * C011 ACIA: Data Path ACIA: Data Path\n * C020 Clear Real Time Clock Clear Real Time Clock\n * (Reset) ($FF returned) (Reset) (Data Ignored)\n *\n * PIA Data Register A Layout:\n *\n * PA7 PA6 PA5 PA4 PA3 PA2 PA1 PA0\n * --- --- --- ---- --- --- --- ----\n * IHD | SD2 | WP | RDY2 | SHD | FD | TZD | RDY1\n * (In) (Out) (In) (In) (In) (In) (In) (In)\n *\n * PIA Data Register B Layout:\n *\n * PB7 PB6 PB5 PB4 PB3 PB2 PB1 PB0\n * --- --- --- --- --- --- --- ---\n * HLD | LCS | SD1 | FR | ST | STI | EE | WE\n * (Out) (Out) (Out) (Out) (Out) (Out) (Out) (Out)\n *\n * PIA Data Register A Lines PIA Data Register B Lines\n * ------------------------- -------------------------\n * IHD - Index Hole Detect HLD - Head Load\n * SD2 - Select Drive 2 (Drive B) LCS - Low Current Select\n * WP - Write Protected SD1 - Select Drive 1\n * RDY2- Drive 2 Ready FR - Fault Reset\n * SHD - Sector Hole Detect ST - Step\n * FD - Fault Detected STI - Step In\n * TZD - Track Zero Detected EE - Enable Erase\n * RDY1- Drive 1 Ready WE - Write Enable\n *\n * NOTE: The PIA bit assignments above agree with those described, albeit somewhat less clearly,\n * in http://www.osiweb.org/osiweb/misc/osi-hardware.txt, under \"Model 475 Floppy disk system with\n * 470 Controller board\".\n *\n * There is apparently significant overlap with another OSI board: the Model 505 CPU Board\n * used in C4P/MF systems. According to http://www.osiweb.org/osiweb/misc/osi-hardware.txt, it\n * contained:\n *\n * CPU board w/ ROM, ACIA, Floppy Disk I/O, Real Time Clock\n * ROM $FDxx, $FExx, $FFxx\n * Floppy disk interface: 6820 PIA at $C000, 6850 ACIA at $C010 [Original says \"6850 PIA\"]\n * ACIA 6850 at $FC00 for RS-232 serial I/O. Baud jumpers for 75,150,300,600,1200,2400,4800,9600\n * Disk PIA $C0xx CB1 connected to 400mSEC (2.5/sec) clock divided from system clock (RTC)\n * Home security - PIA $F700-F703\n *\n * Disk Formats (from http://osi.marks-lab.com/files/winOSI/old-source-V1.2/Disk_io.cpp):\n *\n * 5.25\" disk, 40 tracks, 8 sectors/track, 256 bytes/sector, 11 bits/byte (8E1) = 80K/disk.\n *\n * NOTE: 8E1 refers to \"8 data bits, even parity, 1 stop bit,\" plus an implied start bit.\n *\n * OSI uses 8E1 to give a max unformatted capacity of 2272 bytes per track (see below).\n * However other bit encodings (8N1) could give up to 2500 bytes/track.\n *\n * NOTE: 8N1 refers to \"8 data bits, no parity, 1 stop bit,\" plus an implied start bit.\n *\n * The standard speed for 5.25\" drives is 300rpm. Thus one rotation of the disk is 200ms.\n * Stated baud-rate is 125k or 125000 bits/sec and one serial byte is 11 bits (1 start,\n * 8 data, 1 parity, 1 stop). So the theoretical absolute maximum storage per track is\n * (125000 x 0.2) / 11 = 2272 bytes or 8.8 pages.\n *\n * OS-65D loses a bit more because it doesn't write until 10ms after the index pulse, so\n * (125000 x 0.19) / 11 = 2159 bytes or 8.4 pages and this doesn't even allow for the length\n * of the index pulse (a few milliseconds?) and the speed variation between drives.\n *\n * 8\" disk, 77 tracks, 12 sectors/track, 256 bytes/sector, 11 bits/byte (8E1) = 231K/disk.\n * OSI uses 8E1 to give a max unformatted capacity of 3772 bytes/track (see below).\n * However other bit encodings (8N1) could give up to 3900 bytes/track.\n *\n * The standard speed for 8\" drives is 360rpm. Thus one rotation of the disk is 166.6ms.\n * Stated baud rate is 250K or 250000 bits/sec and one serial byte is 11 bits (1 start,\n * 8 data, 1 parity, 1 stop). So the theoretical absolute maximum storage per track is\n * (250000 x 0.166 ) / 11 = 3772 or 14.7 pages.\n *\n * OS-65D loses a bit more because it doesn't write until 10 mS after the index pulse, so\n * (250000 x 0.156) / 11 = 3545 bytes or 13.8 pages and this doesn't even allow for the length\n * of the index pulse (a few milliseconds?) and the speed variation between drives.\n *\n * Track 0 Format\n * --------------\n * (10ms delay after index hole)\n * 0,1 load address of the track in hi,lo form\n * 2 page count of how much data is written on track 0.\n * 3+ sector data\n *\n * Track N Format (N > 0)\n * ----------------------\n * (10ms delay after index hole)\n * 0,1 2-byte start code $43, $57\n * 2 BCD track number\n * 3 track type code (always $58)\n * 4+ sector data\n *\n * Sector Format (5.25\" disks)\n * ---------------------------\n * There can be any mixture of various length sectors. The total page count can not\n * exceed 8 pages (8*256) if more than one sector is on a track. Each sector is written\n * in the following format:\n *\n * previous sector length (4 if none before) times 800 microseconds of delay\n * sector start code $76\n * sector number in binary\n * sector length (#pages) in binary\n * sector data\n * (end of sector mark? $47, $53? MDS)\n *\n * Directory Format\n * ----------------\n * 2 sectors (1 & 2) on track 12 hold the directory information.\n * Each entry requires 8 bytes. There are a total of 64 entries. The entries are\n * formatted as follows:\n *\n * 0-5 ASCII 6 character filename\n * 6 BCD first track of file\n * 7 BCD Last track of file\n *\n * So far, all the 5.25\" disk images I've seen are 92160 bytes, regardless whether they have an\n * .IMG or .65D extension. If we divide that total by 40 (tracks/disk), we get 2304 (bytes/track).\n * Divide 2304 by 256 (bytes/page) and we get 9 pages/track. Presumably a fixed 9 pages was chosen\n * to yield a consistent track size across the entire image, while also allowing room for all the\n * metadata that's typically present on a track as well. As explained above, the upper limit\n * on data per track (both sector data and metadata) is 8.8 pages in theory, or 8.4 pages in practice.\n *\n * @this {C1PDiskController}\n * @param {Object} parmsDC\n */\n constructor(parmsDC)\n {\n super(\"C1PDiskController\", parmsDC);\n\n this.flags.powered = false;\n\n /*\n * Our DiskController simulates the combination of an MC6820 PIA and an MC6850 ACIA.\n * This image of an OSI 470 Controller Board (http://osi.marks-lab.com/boards/images/OSI470.jpg)\n * shows that the chips actually used were MC68B21P and MC68B50P.\n *\n * We start with definitions for the MC6820 PIA.\n */\n this.PORT_PDA = 0; // PIA Peripheral Data Register A\n this.PORT_DDA = 0; // PIA Data Direction Register A (DDA shares the same register offset as PDA)\n this.PORT_CRA = 1; // PIA Control Register A\n\n this.PORT_PDB = 2; // PIA Peripheral Data Register B\n this.PORT_DDB = 2; // PIA Data Direction Register B (DDB shares the same register offset as PDB)\n this.PORT_CRB = 3; // PIA Control Register B\n\n this.CR_IRQ1 = 0x80; // IRQ1\n this.CR_IRQ2 = 0x40; // IRQ2\n // this.CR_C2_OUT = 0x20; // C2 is designated an output\n // this.CR_C2_CTRL = 0x18; // C2 Control (00 and 10 mask IRQ2, 01 and 11 pass IRQ2 through to the CPU)\n this.CR_PD_SEL = 0x04; // set to select PD (PDA or PDB), clear to select DD (DDA or DDB)\n // this.CR_C1_CTRL = 0x03; // C1 Control (00 and 10 mask IRQ1, 01 and 11 pass IRQ1 through to the CPU)\n\n /*\n * The PDA bits have the following hard-wired connections in the OSI Floppy Disk Controller.\n * Each line marked INPUT should have its corresponding Data Direction bit clear (0), and each line\n * marked OUTPUT should have its Data Direction bit set (1); however, we do not currently verify that\n * the Data Direction bits are actually initialized to match these specs (and in fact, in the case\n * of PDA_SD2, they may not be).\n */\n this.PDA_RDY1 = 0x01; // INPUT: 0 = Drive 1 Ready\n this.PDA_TZD = 0x02; // INPUT: 0 = Track Zero Detected\n this.PDA_FD = 0x04; // INPUT: 0 = Fault Detected\n this.PDA_SHD = 0x08; // INPUT: 0 = Sector Hole Detect\n this.PDA_RDY2 = 0x10; // INPUT: 0 = Drive 2 Ready\n this.PDA_WP = 0x20; // INPUT: 0 = Write Protected\n this.PDA_SD2 = 0x40; // OUTPUT: 0 = Select Drive 2 (Drive B)\n this.PDA_IHD = 0x80; // INPUT: 0 = Index Hole Detect\n\n // this.PDB_WE = 0x01; // OUTPUT: 0 = Write Enable\n // this.PDB_EE = 0x02; // OUTPUT: 0 = Erase Enable (set to 1)\n this.PDB_STI = 0x04; // OUTPUT: 0 = Step In (away from track 0)\n this.PDB_ST = 0x08; // OUTPUT: 0 = Step (on 1-to-0 transition)\n // this.PDB_FR = 0x10; // OUTPUT: 0 = Fault Reset (set to 1)\n this.PDB_SD1 = 0x20; // OUTPUT: 0 = Select Drive 1\n // this.PDB_LCS = 0x40; // OUTPUT: 0 = Low Current Select (set to 1)\n // this.PDB_HLD = 0x80; // OUTPUT: 0 = Head Load (head on disk)\n\n /*\n * Next, definitions for the MC6850 ACIA.\n *\n * For reference, here are all the possible CTRL_WSEL (Word Select) values:\n *\n * 000 0x00 7 bits, even parity, 2 stop bits\n * 001 0x04 7 bits, odd parity, 2 stop bits\n * 010 0x08 7 bits, even parity, 1 stop bit\n * 011 0x0C 7 bits, odd parity, 1 stop bit\n * 100 0x10 8 bits, 2 stop bits\n * 101 0x14 8 bits, 1 stop bit\n * 110 0x18 8 bits, even parity, 1 stop bit\n * 111 0x1C 8 bits, odd parity, 1 stop bit\n *\n * And here are all the possible CTRL_TCTL (Transmit Control) values:\n *\n * 00 0x00 RTS=Low, Transmitting Interrupt Disabled\n * 01 0x20 RTS=Low, Transmitting Interrupt Enabled\n * 10 0x40 RTS=High, Transmitting Interrupt Disabled\n * 11 0x60 RTS=Low, Transmits a Break level on the Transmit Data Output; Transmitting Interrupt Disabled\n */\n this.PORT_CTRL = 0x10; // ACIA Control Register (WRITE-only)\n this.PORT_STAT = 0x10; // ACIA Status Register (READ-only)\n this.PORT_DATA = 0x11; // ACIA Data Register (Transmit Data Register on WRITE, Receive Data Register on READ)\n\n this.CTRL_CDIV = 0x03; // Counter Divide (CR1,CR0) [OSI sets both, performing a \"Master Reset\", then immediately clears both, for a divide ratio of 1]\n // this.CTRL_WSEL = 0x1C; // Word Select (CR4,CR3,CR2), determining word length, parity and stop bits [OSI selects 0x18 for \"8 bits, even parity, 1 stop bit\"]\n // this.CTRL_TCTL = 0x60; // Transmit Control (CR6,CR5) [OSI selects 0x40 for \"RTS=High, Transmitting Interrupt Disabled\"]\n // this.CTRL_RINT = 0x80; // Receive Interrupt Enable (CR7) [OSI selects 0x00 for interrupts disabled]\n\n this.STAT_RDRF = 0x01; // Receive Data Register Full\n this.STAT_TDRE = 0x02; // Transmit Data Register Empty\n this.STAT_DCD = 0x04; // Data Carrier Detect\n this.STAT_CTS = 0x08; // Clear To Send\n // this.STAT_FE = 0x10; // Framing Error (ie, the received character is improperly framed by a start and a stop bit and is detected by the absence of the first stop bit)\n // this.STAT_OVRN = 0x20; // Receiver Overrun (ie, one or more characters in the data stream were lost due to not being read from the Receive Data Register in time)\n // this.STAT_PE = 0x40; // Parity Error (ie, the number of highs (ones) in the character does not agree with the preselected odd or even parity)\n // this.STAT_IRQ = 0x80; // Interrupt Request (ie, state of the IRQ output; cleared by a read operation to the Receive Data Register or a write operation to the Transmit Data Register)\n\n /*\n * Last but not least, some internal state definitions and hard-coded assumptions\n */\n this.DRIVETYPE_5INCH = 0;\n // this.DRIVETYPE_8INCH = 1;\n\n this.MAXTRACKS_5INCH = 40;\n // this.MAXTRACKS_8INCH = 77;\n\n /*\n * Some random OS-65D notes\n *\n * Version 3.3 Initialization Code\n * -------------------------------\n *\n * The following code (where X is 0x00):\n *\n * 2217 8E 01 F4 STX $F401\n * 221A 8E 00 F4 STX $F400\n * 221D 8E 03 F4 STX $F403\n *\n * is intended to reset a Printer PIA located at 0xF400.\n *\n * It then takes a detour to \"SET KEYBOARD SOUND GENERATOR TO LOWEST FREQUENCY (192.753 HZ)\"\n * with X set to 0xFF; the sound generator is supposed to be turned off a bit later, presumably\n * at the same time it sets \"64 char/line\" mode -- well, that's what v3.2 did anyway.\n *\n * 2220 CA DEX\n * 2221 8E 01 DF STX $DF01\n *\n * While X is still 0xFF, it continues initializing the Printer PIA:\n *\n * 2224 8E 02 F4 STX $F402\n *\n * Then the code fiddles a bit with a mystery serial port (perhaps the \"Model 430B Cassette & Analog I/O\"\n * interface?)\n *\n * 2227 AD 06 FB LDA $FB06\n * 222A 8E 05 FB STX $FB05\n *\n * And then it's back to more Printer PIA initialization:\n *\n * 222D A9 04 LDA #$04\n * 222F 8D 01 F4 STA $F401\n * 2232 8D 03 F4 STA $F403\n *\n * Then it does some disk resetting (with A still 0x04 and Y set to 0x00):\n *\n * 2235 8C 01 C0 STY $C001\n * 2238 A0 40 LDY #$40 ;'@'\n * 223A 8C 00 C0 STY $C000\n * 223D 8D 01 C0 STA $C001\n *\n * This code supposedly selects DRIVE 1:\n *\n * 2240 A9 01 LDA #$01\n * 2242 20 C6 29 JSR $29C6\n *\n * Then it \"resets\" and \"sets\" the TERMINAL ACIA. Note that the C1P serial port is addressed\n * at 0xF000-0xF0FF, and the C1P has ROM mapped to 0xF800-0xFFFF, so we know nothing of the serial\n * port mentioned above at 0xFBxx, nor this terminal ACIA port at 0xFCxx.\n *\n * 2245 A9 03 LDA #$03\n * 2247 8D 00 FC STA $FC00\n * 224A A0 11 LDY #$11\n * 224C 8C 00 FC STY $FC00\n *\n * Next, there's some code to \"SET CA-10X 16 WAY SERIAL BOARD\" at 0xCF00-0xCF1F; again, something\n * we know nothing about:\n *\n * 224F A2 1E LDX #$1E\n * 2251 9D 00 CF STA $CF00,X\n * 2254 98 TYA\n * 2255 9D 00 CF STA $CF00,X\n * 2258 A9 03 LDA #$03\n * 225A CA DEX\n * 225B CA DEX\n * 225C 10 F3 BPL $2251\n *\n * Then it clears 8 pages of video memory (ie, it simply ASSUMES that this is a Model 540 video board\n * with 2K of video memory):\n *\n * 225E A2 08 LDX #$08\n * 2260 A9 D0 LDA #$D0\n * 2262 85 FF STA $FF\n * 2264 A0 00 LDY #$00\n * 2266 84 FE STY $FE\n * 2268 A9 20 LDA #$20 ;' '\n * 226A 91 FE STA ($FE),Y\n * 226C C8 INY\n * 226D D0 FB BNE $226A\n * 226F E6 FF INC $FF\n * 2271 CA DEX\n * 2272 D0 F6 BNE $226A\n *\n * Then it performs a memory test, starting with a high page of 0xBF, and stores the highest page of\n * available RAM at 0x2300:\n *\n * 2276 A0 BF LDY #$BF\n * 2278 20 EC 22 JSR $22EC\n * 227B F0 03 BEQ $2280\n * 227D 88 DEY\n * 227E D0 F8 BNE $2278\n * 2280 8C 00 23 STY $2300\n *\n * Now it checks for \"SERIAL OR VIDEO (EITHER 65-A OR 65-V PROM)\" (the byte at 0xFE01 on a C1P is 0x28,\n * so X will be 2, implying \"VIDEO\"):\n *\n * 2283 A2 01 LDX #$01\n * 2285 AD 01 FE LDA $FE01\n * 2288 F0 01 BEQ $228B\n * 228A E8 INX\n * 228B 8E C6 2A STX $2AC6\n *\n * Finally, there's some code that's a little different from v3.2; in 3.2, it would set X to 0x01\n * and then store X at 0xDE00, effectively forcing the video board into \"64 char/line\" mode -- which was\n * originally EXACTLY what I was looking for in the video emulation component. But v3.3 doesn't do that.\n * Here's what it does instead:\n *\n * 228F A2 00 LDX #$00\n * 2291 8E 80 DC STX $DC80\n *\n * So, what's supposed to be at 0xDC80?\n */\n\n this.reset(true);\n }\n\n /**\n * @this {C1PDiskController}\n * @param {boolean|undefined} [fPowerOn] is true for the initial reset only\n */\n reset(fPowerOn)\n {\n this.resetRegs();\n this.iDriveSelect = -1;\n if (fPowerOn) {\n this.aDrives = [];\n this.resetDrive(0, this.DRIVETYPE_5INCH, this.MAXTRACKS_5INCH);\n }\n }\n\n /**\n * @this {C1PDiskController}\n */\n resetRegs()\n {\n this.regDDA = {\n bits: this.PDA_SD2, // clear all DDA bits, indicating that all PDA bits represent INPUT lines (well, except for PDA_SD2)\n read: function() {},\n update: function(controller) {\n return function(b) {\n if (b !== undefined) this.bits = b;\n if (!(controller.regCRA.bits & controller.CR_PD_SEL)) {\n controller.writePort(controller.PORT_DDA, this);\n }\n };\n }(this)\n };\n this.regPDA = {\n bits: 0xff,\n read: function() {\n this.update();\n },\n update: function(controller) {\n return function(b) {\n this.bits = controller.updatePDA(b);\n if (controller.regCRA.bits & controller.CR_PD_SEL) {\n controller.writePort(controller.PORT_PDA, this);\n }\n };\n }(this)\n };\n this.regCRA = {\n bits: 0,\n read: function() {},\n update: function(controller) {\n return function(b) {\n /*\n * Most bits written to CRA should be left as-is (the CPU should read back what it wrote);\n * bits 7 and 6 (IRQ1 and IRQ2) are exceptions, since those are tied to peripheral \"Control Lines\"\n * C1 and C2, which can in theory generate an interrupt depending on how the C1_CTRL and C2_CTRL bits\n * in CRA are set. However, assuming there's no need to simulate interrupts for this particular\n * controller hardware, all we'll do is simply insure those two bits are always off.\n */\n if (b !== undefined) this.bits = (b & ~(controller.CR_IRQ1 | controller.CR_IRQ2));\n controller.writePort(controller.PORT_CRA, this);\n /*\n * Since a CRA write may have also changed which register (PDA or DDA) is enabled via the corresponding\n * PDA port, we simply ask ask both to update (only the one that's enabled will write itself to memory).\n */\n controller.regPDA.update();\n controller.regDDA.update();\n };\n }(this)\n };\n this.regDDB = {\n bits: 0xff, // set all DDB bits, indicating that all PDB bits represent OUTPUT lines\n read: function() {},\n update: function(controller) {\n return function(b) {\n if (b !== undefined) this.bits = b;\n if (!(controller.regCRB.bits & controller.CR_PD_SEL)) {\n controller.writePort(controller.PORT_DDB, this);\n }\n };\n }(this)\n };\n this.regPDB = {\n bits: 0xff,\n read: function() {},\n update: function(controller) {\n return function(b) {\n this.bits = controller.updatePDB(b);\n if (controller.regCRB.bits & controller.CR_PD_SEL) {\n controller.writePort(controller.PORT_PDB, this);\n }\n };\n }(this)\n };\n this.regCRB = {\n bits: 0,\n read: function() {},\n update: function(controller) {\n return function(b) {\n /*\n * Most bits written to CRB should be left as-is (the CPU should read back what it wrote);\n * bits 7 and 6 (IRQ1 and IRQ2) are exceptions, since those are tied to peripheral \"Control Lines\"\n * C1 and C2, which can in theory generate an interrupt depending on how the C1_CTRL and C2_CTRL bits\n * in CRB are set. However, assuming there's no need to simulate interrupts for this particular\n * controller hardware, all we'll do is simply insure those two bits are always off.\n */\n if (b !== undefined) this.bits = (b & ~(controller.CR_IRQ1 | controller.CR_IRQ2));\n controller.writePort(controller.PORT_CRB, this);\n /*\n * Since a CRB write may have also changed which register (PDB or DDB) is enabled via the corresponding\n * PDB port, we simply ask ask both to update (only the one that's enabled will write itself to memory).\n */\n controller.regPDB.update();\n controller.regDDB.update();\n };\n }(this)\n };\n this.regCTRL = {\n bits: 0,\n read: function() {},\n update: function(controller) {\n return function(b) {\n if (b !== undefined) {\n if ((b & controller.CTRL_CDIV) == controller.CTRL_CDIV) {\n /*\n * Setting both CTRL_CDIV bits (CR0 and CR1) constitutes a \"Master Reset\" of the ACIA\n */\n controller.regSTAT.bits = (controller.STAT_TDRE | controller.STAT_DCD | controller.STAT_CTS);\n }\n this.bits = b;\n }\n // regCTRL isn't readable; instead, we ensure regSTAT is rewritten in its place\n controller.regSTAT.update();\n };\n }(this)\n };\n this.regSTAT = {\n bits: (this.STAT_TDRE | this.STAT_DCD | this.STAT_CTS),\n read: function() {},\n update: function(controller) {\n return function(b) {\n this.bits = controller.updateSTAT(b);\n controller.writePort(controller.PORT_STAT, this);\n };\n }(this)\n };\n this.regDATA = {\n bits: 0,\n read: function(controller) {\n return function() {\n controller.advanceDriveData();\n };\n }(this),\n update: function(controller) {\n return function(b) {\n if (b !== undefined) this.bits = b;\n controller.writePort(controller.PORT_DATA, this);\n };\n }(this)\n };\n this.regUnknown = {\n bits: 0,\n read: function() {},\n update: function(controller) {\n return function(b) {};\n }(this)\n };\n if (DEBUG) {\n this.regDDA.sName = \"DDA\",\n this.regDDA.aBitIDs = {0x80:\"DD7\",0x40:\"DD6\",0x20:\"DD5\",0x10:\"DD4\",0x08:\"DD3\",0x04:\"DD2\",0x02:\"DD1\",0x01:\"DD0\"}; // jshint ignore:line\n this.regPDA.sName = \"PDA\";\n this.regPDA.aBitIDs = {0x80:\"IHD\",0x40:\"SD2\",0x20:\"WP\",0x10:\"RDY2\",0x08:\"SHD\",0x04:\"FD\",0x02:\"TZD\",0x01:\"RDY1\"};\n this.regCRA.sName = \"CRA\";\n this.regCRA.aBitIDs = {0x80:\"IRQ1\",0x40:\"IRQ2\",0x20:\"C2OUT\",0x10:\"C2:1\",0x08:\"C2:0\",0x04:\"PDS\",0x02:\"C1:1\",0x01:\"C1:0\"};\n this.regDDB.sName = \"DDB\";\n this.regDDB.aBitIDs = {0x80:\"DD7\",0x40:\"DD6\",0x20:\"DD5\",0x10:\"DD4\",0x08:\"DD3\",0x04:\"DD2\",0x02:\"DD1\",0x01:\"DD0\"};\n this.regPDB.sName = \"PDB\";\n this.regPDB.aBitIDs = {0x80:\"HLD\",0x40:\"LCS\",0x20:\"SD1\",0x10:\"FR\",0x08:\"ST\",0x04:\"STI\",0x02:\"EE\",0x01:\"WE\"};\n this.regCRB.sName = \"CRB\";\n this.regCRB.aBitIDs = {0x80:\"IRQ1\",0x40:\"IRQ2\",0x20:\"C2OUT\",0x10:\"C2:1\",0x08:\"C2:0\",0x04:\"PDS\",0x02:\"C1:1\",0x01:\"C1:0\"};\n this.regCTRL.sName = \"CTRL\";\n this.regCTRL.aBitIDs = {0x80:\"CR7\",0x40:\"CR6\",0x20:\"CR5\",0x10:\"CR4\",0x08:\"CR3\",0x04:\"CR2\",0x02:\"CR1\",0x01:\"CR0\"};\n this.regSTAT.sName = \"STAT\";\n this.regDATA.sName = \"DATA\";\n this.regUnknown.sName = \"unknown\";\n }\n }\n\n /**\n * @this {C1PDiskController}\n * @param {number} iDrive\n * @param {number} iDriveType\n * @param {number} nMaxTracks\n */\n resetDrive(iDrive, iDriveType, nMaxTracks)\n {\n this.aDrives[iDrive] = {\n iType: iDriveType,\n nTracks: nMaxTracks,\n fProtected: true, // fake for now\n nIndexPulse: 20, // nIndex (20 is initial index pulse)\n iTrackSelect: 0, // nTrack\n iTrackOffset: -1, // nSector\n /*\n * Our disk data consists of an array of tracks, where each track is an array of sectors;\n * as long as aTracks.length == 0 (empty array), the drive is not considered \"loaded\" with a disk.\n */\n aTracks: []\n };\n }\n\n /**\n * @this {C1PDiskController}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"listDisk\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n switch(sBinding) {\n\n case \"listDisk\":\n this.bindings[sBinding] = control;\n return true;\n\n case \"loadDisk\":\n this.bindings[sBinding] = control;\n control.onclick = function(controller) {\n return function() {\n if (controller.bindings[\"listDisk\"]) {\n var sFilePath = controller.bindings[\"listDisk\"].value;\n var sFileURL = sFilePath;\n /*\n * If the selected disk image has a \".json\" extension, then we assume it's a pre-converted\n * JSON-encoded disk image, so we load it as-is; otherwise, we ask our server-side disk image\n * converter to return the corresponding JSON-encoded data, in compact form (ie, minimal whitespace,\n * no ASCII data comments, etc).\n */\n if (sFilePath.substr(sFilePath.length-5) != \".json\") {\n /*\n * TODO: This code was using a deprecated parameter (compact=1); make sure things still work.\n *\n * TODO: Convert this code to use the new shared Disk API definitions and weblib functions; eg:\n *\n * sDiskURL = Web.getHost() + DumpAPI.ENDPOINT + \"?\" + DumpAPI.QUERY.DISK + \"=\" + sDiskPath;\n */\n sFileURL = \"http://\" + window.location.host + \"/api/v1/dump?disk=\" + sFilePath;\n }\n controller.println(\"loading \" + Str.getBaseName(sFilePath) + \"...\");\n Web.getResource(sFileURL, null, true, function(sURL, sResponse, nErrorCode) {\n controller.loadDisk(sURL, sResponse, nErrorCode);\n });\n }\n };\n }(this);\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * @this {C1PDiskController}\n * @param {Array} abMemory\n * @param {number} start\n * @param {number} end\n * @param {C1PCPU} cpu\n */\n setBuffer(abMemory, start, end, cpu)\n {\n this.abMem = abMemory;\n this.addrController = start;\n // this.addrControllerLimit = end + 1;\n if ((this.cpu = cpu)) {\n cpu.addReadNotify(start, end, this, this.getByte);\n cpu.addWriteNotify(start, end, this, this.setByte);\n }\n this.setReady();\n }\n\n /**\n * @this {C1PDiskController}\n * @param {boolean} fOn\n * @param {C1PComputer} cmp\n *\n * We need We make a note of the Computer component, so that we can invoke its reset() method whenever we need to\n * simulate a warm start, and we query the Keyboard component so that we can use its injectKeys() function.\n */\n setPower(fOn, cmp)\n {\n if (fOn && !this.flags.powered) {\n this.flags.powered = true;\n if (DEBUGGER) this.dbg = cmp.getComponentByType(\"debugger\");\n }\n }\n\n /**\n * @this {C1PDiskController}\n * @param {string} sDiskName\n * @param {string} sDiskData\n * @param {number} nErrorCode (response from server if anything other than 200)\n *\n * NOTE: Although I've expanded the JSON disk-image format to support multiple heads (ie, platters or disk surfaces),\n * this controller implementation currently supports only single-head drives, and therefore only single-sided images.\n * So, if the image contains more than one entry in head data array, all we use is the first entry; data for any remaining\n * heads is discarded.\n *\n * WARNING: The disk-image format should match that used by PCjs, where the image is an array of cylinders, each of which\n * is an array of heads. That's also more typical, because it maintains the original data's physical locality.\n */\n loadDisk(sDiskName, sDiskData, nErrorCode)\n {\n if (nErrorCode) {\n this.println(\"disk load error (\" + nErrorCode + \")\");\n return;\n }\n var aHeads = [];\n this.println(\"mounting \" + sDiskName + \"...\");\n try {\n /*\n * The most likely source of any exception will be right here, where we're parsing\n * the JSON-encoded disk data.\n */\n aHeads = eval(\"(\" + sDiskData + \")\"); // jshint ignore:line\n if (!aHeads.length) {\n this.println(\"no data: \" + sDiskName);\n return;\n }\n if (!aHeads[0].length) {\n this.println(\"no tracks: \" + sDiskName);\n return;\n }\n var aTracks = aHeads[0];\n if (aTracks[0]['trackNum'] === undefined) {\n this.println(\"data error: \" + aTracks[0]);\n return;\n }\n /*\n * NOTE: This should never happen, otherwise we shouldn't have initiated the load\n * in the first place. Can we guarantee that and eliminate this test?\n */\n if (!this.aDrives[0]) {\n this.println(\"no available drives\");\n return;\n }\n /*\n * To make disk access more efficient, we need to supplement every track object with a\n * simple byte-array (trackData) containing all the data bytes for the entire track.\n */\n for (var iTrack=0; iTrack < aTracks.length; iTrack++) {\n var iTrackNum;\n var track = aTracks[iTrack];\n var sectors = track['sectors'];\n /*\n * WARNING: There are MANY other ways the track data could be malformed, but we'll\n * start with the most egregious, and worry about the rest later.\n */\n if ((iTrackNum = track['trackNum']) === undefined || sectors === undefined) {\n throw new Error(\"track \" + iTrack + \" missing data\");\n }\n /*\n * WARNING: We allow out-of-order tracks, because we store each track's data according\n * to its trackNum index, but just in case that wasn't intended, we're going to mention it.\n */\n if (iTrackNum != iTrack) {\n Component.warning(\"track \" + iTrackNum + \" out of order (expected \" + iTrack + \")\");\n }\n /*\n * For each track, we start with an empty trackData array and \"push\" (ie, append) all the\n * sector data onto it. Most of the data is already in byte form and can simply use Array.push(),\n * but there is also some metadata (signatures, types, lengths, etc), for which we have assorted\n * helpers below: pushBCD, pushBin, and pushSig.\n */\n var trackData = [], sector, sectorData, i;\n if (!iTrackNum) {\n sector = sectors[0];\n sectorData = sector['sectorData'];\n this.pushBin(trackData, track, 'trackLoad', 2);\n this.pushBin(trackData, sector, 'sectorPages');\n for (i = 0; i < sectorData.length; i++) {\n trackData.push(sectorData[i]);\n }\n }\n else {\n this.pushSig(trackData, track, 'trackSig');\n this.pushBCD(trackData, track, 'trackNum');\n this.pushBin(trackData, track, 'trackType');\n for (var iSector=0; iSector < sectors.length; iSector++) {\n sector = sectors[iSector];\n sectorData = sector['sectorData'];\n this.pushBin(trackData, sector, 'sectorSig');\n this.pushBin(trackData, sector, 'sectorNum');\n this.pushBin(trackData, sector, 'sectorPages');\n for (i = 0; i < sectorData.length; i++) {\n trackData.push(sectorData[i]);\n }\n this.pushSig(trackData, sector, 'sectorEndSig');\n }\n }\n /*\n * Finally, here's where we add the newly-created chunk of track data to the current track object\n */\n aTracks[iTrackNum].trackData = trackData;\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(this.dbg.MESSAGE_DISK)) {\n this.dbg.message(\"track \" + iTrackNum + \": \" + trackData.length + \" bytes\");\n }\n }\n this.aDrives[0].aTracks = aTracks;\n this.println(\"mount of \" + sDiskName + \" complete\");\n } catch (e) {\n this.println(\"disk data error: \" + e.message);\n }\n }\n\n /**\n * @this {C1PDiskController}\n * @param {Array.<number>} a\n * @param {Object} o is the object containing the key\n * @param {string} k is the key of 8-bit value to convert to BCD (ie, two 4-bit BCD digits) and push\n */\n pushBCD(a, o, k)\n {\n var n = o[k];\n if (n === undefined) {\n throw new Error(\"missing bcd value: \" + k);\n }\n var bcd = (Math.floor(n / 10) << 4) | (n % 10);\n a.push(bcd);\n }\n\n /**\n * @this {C1PDiskController}\n * @param {Array.<number>} a\n * @param {Object} o is the object containing the key\n * @param {string} k is the key of the value\n * @param {number} [cb] is the number of bytes to push (only 1 or 2 is supported, and the default is 1)\n */\n pushBin(a, o, k, cb)\n {\n var n = o[k];\n if (n === undefined) {\n throw new Error(\"missing binary value: \" + k);\n }\n if (cb == 2) {\n a.push((n >> 8) & 0xff);\n }\n a.push(n & 0xff);\n }\n\n /**\n * @this {C1PDiskController}\n * @param {Array.<number>} a\n * @param {Object} o is the object containing the key\n * @param {string} k is the key of the signature string to push\n */\n pushSig(a, o, k)\n {\n var s = o[k];\n if (s === undefined) {\n throw new Error(\"missing signature: \" + k);\n }\n for (var i=0; i < s.length; i++) {\n a.push(s.charCodeAt(i));\n }\n }\n\n /**\n * @this {C1PDiskController}\n * @param {number} port address (0x0000-0x00FF) relative to addrController (0xC000)\n * @param {boolean} fWrite is true if port write, false if port read\n * @return {Object} reg will always be a valid register object, but it may be the \"unknown\" register if we don't recognize the port.\n */\n getReg(port, fWrite)\n {\n var reg;\n port &= 0x3F;\n /*\n * Now that we've masked the full port range of 0x00-0xFF down to 0x00-0x3F, we further mask the\n * PIA port range (0x00-0x0F) to 0x00-0x03, and the ACIA port range (0x10-0x1F) to 0x10-0x11.\n * The rest of the masked range (0x20-0x3F) is unmapped, so we map it to our global unknown register.\n */\n if (port < 0x10)\n port &= 0x03;\n else if (port < 0x20)\n port &= 0x11;\n switch(port) {\n case this.PORT_PDA:\n reg = (this.regCRA.bits & this.CR_PD_SEL)? this.regPDA : this.regDDA;\n break;\n case this.PORT_CRA:\n reg = this.regCRA;\n break;\n case this.PORT_PDB:\n reg = (this.regCRB.bits & this.CR_PD_SEL)? this.regPDB : this.regDDB;\n break;\n case this.PORT_CRB:\n reg = this.regCRB;\n break;\n case this.PORT_CTRL:\n reg = (fWrite? this.regCTRL : this.regSTAT);\n break;\n case this.PORT_DATA:\n reg = this.regDATA;\n break;\n default:\n reg = this.regUnknown;\n break;\n }\n return reg;\n }\n\n /**\n * @this {C1PDiskController}\n * @param {number} addr\n * @param {number|undefined} addrFrom (not defined whenever the Debugger tries to read the specified addr)\n */\n getByte(addr, addrFrom)\n {\n /*\n * Don't trigger any further hardware emulation (beyond what we've already stored in memory) if\n * the Debugger performed this read (need a special Debugger I/O command if/when you really want to do that).\n */\n if (addrFrom !== undefined) {\n var port = addr - this.addrController;\n var reg = this.getReg(port, false);\n if (DEBUGGER && this.dbg) this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_DISK, false, reg.sName);\n reg.read();\n }\n }\n\n /**\n * @this {C1PDiskController}\n * @param {number} addr\n * @param {number|undefined} addrFrom (not defined whenever the Debugger tries to write the specified addr)\n */\n setByte(addr, addrFrom)\n {\n /*\n * Don't trigger any further hardware emulation (beyond what we've already stored in memory) if\n * the Debugger performed this write (need a special Debugger I/O command if/when you really want to do that).\n */\n if (addrFrom !== undefined) {\n var b = this.cpu.getByte(addr);\n var port = addr - this.addrController;\n var reg = this.getReg(port, true);\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(this.dbg.MESSAGE_DISK | this.dbg.MESSAGE_PORT)) {\n this.dbg.messageIO(this, addr, addrFrom, this.dbg.MESSAGE_DISK, true, reg.sName);\n if (reg.aBitIDs) {\n var bTest = 0x80;\n var bChanged = reg.bits ^ b;\n while (bChanged && bTest) {\n if (bChanged & bTest) {\n this.dbg.message(\" changed \" + reg.sName + \".\" + reg.aBitIDs[bTest] + \" to \" + ((b & bTest)? \"1\" : \"0\"));\n }\n bTest >>= 1;\n }\n }\n }\n reg.update(b);\n }\n }\n\n /**\n * @this {C1PDiskController}\n * @param {number} bPDA\n * @param {number} bPDB\n */\n setSelectedDrive(bPDA, bPDB)\n {\n var iDriveSelect = -1;\n if (bPDA !== undefined && bPDB !== undefined) {\n iDriveSelect = 0;\n if (!(bPDB & this.PDB_SD1))\n iDriveSelect |= 0x02;\n if (!(this.regPDA.bits & this.PDA_SD2))\n iDriveSelect |= 0x01;\n }\n if (this.iDriveSelect != iDriveSelect) {\n this.iDriveSelect = iDriveSelect;\n this.regSTAT.update();\n }\n }\n\n /**\n * @this {C1PDiskController}\n */\n startDriveData()\n {\n if (this.iDriveSelect >= 0) {\n this.aDrives[this.iDriveSelect].iTrackOffset = 0;\n this.advanceDriveData();\n }\n }\n\n /**\n * @this {C1PDiskController}\n */\n stopDriveData()\n {\n if (this.iDriveSelect >= 0) {\n this.aDrives[this.iDriveSelect].iTrackOffset = -1;\n this.regDATA.update(0xFF); // QUESTION: Is this necessary or helpful in some way?\n this.regSTAT.update();\n }\n }\n\n /**\n * @this {C1PDiskController}\n * @return {number} current byte of data from the currently selected drive, or null if no (more) data available\n */\n advanceDriveData()\n {\n var b = null;\n if (this.iDriveSelect >= 0) {\n var drive = this.aDrives[this.iDriveSelect];\n var track = drive.aTracks[drive.iTrackSelect];\n if (track !== undefined) {\n if (drive.iTrackOffset >= 0 && drive.iTrackOffset < track.trackData.length) {\n drive.nIndexPulse = 100; // QUESTION: Necessary?\n b = track.trackData[drive.iTrackOffset++];\n this.regDATA.update(b);\n this.regSTAT.update();\n }\n else {\n drive.nIndexPulse = 10; // QUESTION: Valid or necessary to force index pulse on next poll of $C000?\n this.stopDriveData();\n }\n }\n }\n return b;\n }\n\n /**\n * updatePDA() calculates an updated value for the PDA register.\n *\n * In the process, this may also update iDriveSelect and assorted drive internal variables.\n *\n * @this {C1PDiskController}\n * @param {number|undefined} bPDA\n * @return {number} updated bits for PDA\n */\n updatePDA(bPDA)\n {\n if (bPDA === undefined)\n bPDA = this.regPDA.bits;\n else\n this.setSelectedDrive(bPDA, this.regPDB.bits);\n\n /*\n * We start by turning ON most bits, except for PDA_RDY1, which we always leave\n * OFF (indicating ready). We leave PDA_SD2 alone, so that it reflects whatever\n * the CPU had set.\n *\n * Then we dive into the update logic, which will turn OFF any of the bits we\n * originally turned ON if the corresponding condition is true (because an OFF bit\n * signals an active condition).\n */\n bPDA |= (this.PDA_IHD | this.PDA_WP | this.PDA_SHD | this.PDA_FD | this.PDA_TZD | this.PDA_RDY2);\n bPDA &= ~(this.PDA_RDY1);\n\n if (this.iDriveSelect >= 0) {\n\n if (this.aDrives[this.iDriveSelect].aTracks.length) {\n\n var drive = this.aDrives[this.iDriveSelect];\n\n if (drive.fProtected) {\n bPDA &= ~this.PDA_WP;\n }\n if (!drive.iTrackSelect) {\n bPDA &= ~this.PDA_TZD;\n }\n /*\n * Simulate PHD_IHD (Index Hole Detect)\n */\n if (--drive.nIndexPulse <= 10) {\n if (drive.nIndexPulse > 0) {\n bPDA &= ~this.PDA_IHD;\n this.stopDriveData();\n } else {\n drive.nIndexPulse = 100;\n this.startDriveData();\n }\n }\n }\n }\n return bPDA;\n }\n\n /**\n * updatePDB() calculates an updated value for the PDB register. However, since the\n * PDB consists entirely of OUTPUT bits, none of the given bits should actually be modified.\n *\n * In the process, this may also update iDriveSelect and assorted drive internal variables,\n * as well as selected PDA INPUT bits (hence the call to regPDA.update()).\n *\n * @this {C1PDiskController}\n * @param {number|undefined} bPDB\n * @return {number} updated bits for PDB\n */\n updatePDB(bPDB)\n {\n if (bPDB === undefined)\n bPDB = this.regPDB.bits;\n else\n this.setSelectedDrive(this.regPDA.bits, bPDB);\n\n if (this.iDriveSelect >= 0 && this.iDriveSelect < this.aDrives.length) {\n\n var drive = this.aDrives[this.iDriveSelect];\n\n if (drive.aTracks.length) {\n /*\n * Is PDB_ST transitioning from 1 to 0?\n */\n if ((this.regPDB.bits & this.PDB_ST) && !(bPDB & this.PDB_ST)) {\n /*\n * PDB_STI == 0? step toward track 39 : step toward track 0\n */\n if (bPDB & this.PDB_STI)\n drive.iTrackSelect--;\n else\n drive.iTrackSelect++;\n\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(this.dbg.MESSAGE_DISK)) {\n this.dbg.message(\"stepping \" + ((bPDB & this.PDB_STI)? \"down\" : \"up\") + \" to track \" + drive.iTrackSelect);\n }\n\n if (drive.iTrackSelect >= drive.nTracks)\n drive.iTrackSelect = drive.nTracks;\n\n if (drive.iTrackSelect < 0)\n drive.iTrackSelect = 0;\n\n drive.nIndexPulse = 20;\n\n this.regPDA.update(this.regPDA.bits | this.PDA_IHD);\n this.stopDriveData();\n }\n }\n }\n else if (DEBUG && this.iDriveSelect >= 0) {\n this.println(\"updatePDB(\" + Str.toHexByte(bPDB) + \"): invalid drive: \" + this.iDriveSelect);\n }\n return bPDB;\n }\n\n /**\n * updateSTAT() calculates an updated value for the ACIA Status register.\n *\n * @this {C1PDiskController}\n * @param {number|undefined} bSTAT\n * @return {number} updated bits for STAT\n */\n updateSTAT(bSTAT)\n {\n if (bSTAT === undefined)\n bSTAT = this.regSTAT.bits;\n bSTAT &= ~this.STAT_RDRF;\n if (this.iDriveSelect >= 0 && this.aDrives[this.iDriveSelect].iTrackOffset >= 0)\n bSTAT |= this.STAT_RDRF;\n return bSTAT;\n }\n\n /**\n * @this {C1PDiskController}\n * @param {number} port\n * @param {Object} reg\n */\n writePort(port, reg)\n {\n this.cpu.setByte(port + this.addrController, reg.bits);\n }\n\n /**\n * @this {C1PDiskController}\n * @param {boolean} fLoaded is true if the selected drive must be loaded, false if don't care\n * @return {Object} drive reference to the selected drive, or null if no drive is selected or it doesn't meet the fLoaded requirement\n *\n getSelectedDrive(fLoaded)\n {\n var drive = null;\n if (this.iDriveSelect >= 0) {\n if (this.aDrives[this.iDriveSelect]) {\n if (!fLoaded || this.aDrives[this.iDriveSelect].aTracks.length)\n drive = this.aDrives[this.iDriveSelect];\n }\n }\n return drive;\n }\n */\n\n /**\n * C1PDiskController.init()\n *\n * This function operates on every HTML element of class \"disk\", extracting the\n * JSON-encoded parameters for the C1PDiskController constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a C1PDiskController component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeDC = Component.getElementsByClass(document, C1PJS.APPCLASS, \"disk\");\n for (var iDC=0; iDC < aeDC.length; iDC++) {\n var eDC = aeDC[iDC];\n var parmsDC = Component.getComponentParms(eDC);\n var controller = new C1PDiskController(parmsDC);\n Component.bindComponentControls(controller, eDC, C1PJS.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize every DiskController module on the page.\n */\nWeb.onInit(C1PDiskController.init);\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/debugger.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * @class C1PDebugger\n * @unrestricted\n */\nclass C1PDebugger extends Component {\n /**\n * C1PDebugger(parmsDbg)\n *\n * The C1PDebugger component has no required (parmsDbg) properties.\n *\n * The C1PDebugger component is an optional component that implements a variety of user\n * commands for controlling the CPU, dumping and editing memory, etc.\n *\n * @this {C1PDebugger}\n * @param {Object} parmsDbg\n */\n constructor(parmsDbg)\n {\n if (DEBUGGER) {\n\n super(\"C1PDebugger\", parmsDbg);\n\n this.dbg = this;\n /*\n * This keeps track of instruction activity, but only when tracing or when\n * Debugger checks have been enabled (eg, one or more breakpoints have been set).\n *\n * This is zeroed by CPU notification handlers reset() and stopped().\n * We set it here to -1 to indicate that the CPU has not yet initialized us.\n */\n this.cIns = -1;\n\n /*\n * Some commands, like the dump (d) command, start at nextAddr when no address\n * is given (and they also update nextAddr when they're done).\n */\n this.nextAddr = 0;\n\n /*\n * When Enter is pressed on an empty input buffer, we default to the previous\n * command, which is preserved here.\n */\n this.prevCmd = null;\n\n /*\n * fAssemble is true when \"assemble mode\" is active, false when not.\n */\n this.fAssemble = false;\n this.addrAssembleNext = 0;\n\n /*\n * Initialize the lists of breakpoint addresses. aExecBreak is a list (Array) of addresses\n * to halt at whenever attempting to execute an instruction at the corresponding address,\n * and aReadBreak and aWriteBreak are lists of addresses to halt at whenever a read or write,\n * respectively, occurs at the corresponding address.\n */\n this.clearBreakpoints();\n\n /*\n * Instead of pre-allocating these arrays, we wait until our reset() function is called.\n * These arrays are updated in checkInstruction(), but the CPU will never actually call it\n * unless checksEnabled() returns true, and that won't happen until one or more breakpoints\n * have been set. This ensures that, by default, the CPU runs as fast as possible.\n */\n this.iStepHistory = 0;\n this.aStepHistory = [];\n this.aaOpcodeFreqs = [];\n\n /*\n * This \"info\" buffer is a lightweight logging mechanism that has minimal impact on the\n * browser (unlike printing to either window.console.log or an HTML control, which can make\n * the browser unusable if printing is too frequent). The Debugger's \"i\" command dumps\n * this buffer. Note that dumping too much at once can also bog things down, but by that\n * point, you've presumably already captured the info you need and are willing to wait.\n */\n if (DEBUG) {\n this.iInfoBuffer = 0;\n this.aInfoBuffer = new Array(10000);\n }\n\n /*\n * Message categories supported by the message() function; they are designed to be combined\n * (ie, OR'ed) as needed. The Debugger's \"option\" command is used to turn message categories\n * on and off, like so:\n *\n * o msg port on\n * o msg port off\n * ...\n */\n this.MESSAGE_PORT = 0x01;\n this.MESSAGE_KBD = 0x10;\n this.MESSAGE_VIDEO = 0x20;\n this.MESSAGE_DISK = 0x40;\n this.MESSAGE_SERIAL = 0x80;\n this.MESSAGE_NONE = 0x00;\n // this.MESSAGE_ALL = 0xff;\n this.bitsMessage = this.MESSAGE_NONE;\n this.aMessageCategories = {\n 'port': this.MESSAGE_PORT,\n 'kbd': this.MESSAGE_KBD,\n 'video': this.MESSAGE_VIDEO,\n 'disk': this.MESSAGE_DISK,\n 'serial': this.MESSAGE_SERIAL\n };\n\n /*\n * The aaOperations array is indexed by opcode, and each element is a sub-array that\n * describes the corresponding opcode. The sub-elements are as follows:\n *\n * [0]: {number} of the operation code (see OP_*)\n * [1]: {number} of additional bytes following the opcode byte, if any\n * [2]: {number} of the operation mode operand, if any (see MODE_*)\n *\n * These sub-elements are all optional. If [0] is not present, the opcode is undefined;\n * if [1] is not present (or contains a zero), the opcode is a single-byte opcode; and if\n * [2] is not present, the opcode uses no (or implied) operands.\n */\n this.OP_ADC = 0;\n this.OP_AND = 1;\n this.OP_ASL = 2;\n this.OP_BCC = 3;\n this.OP_BCS = 4;\n this.OP_BEQ = 5;\n this.OP_BIT = 6;\n this.OP_BMI = 7;\n this.OP_BNE = 8;\n this.OP_BPL = 9;\n this.OP_BRK = 10;\n this.OP_BVC = 11;\n this.OP_BVS = 12;\n this.OP_CLC = 13;\n this.OP_CLD = 14;\n this.OP_CLI = 15;\n this.OP_CLV = 16;\n this.OP_CMP = 17;\n this.OP_CPX = 18;\n this.OP_CPY = 19;\n this.OP_DEC = 20;\n this.OP_DEX = 21;\n this.OP_DEY = 22;\n this.OP_EOR = 23;\n this.OP_INC = 24;\n this.OP_INX = 25;\n this.OP_INY = 26;\n this.OP_JMP = 27;\n this.OP_JSR = 28;\n this.OP_LDA = 29;\n this.OP_LDX = 30;\n this.OP_LDY = 31;\n this.OP_LSR = 32;\n this.OP_NOP = 33;\n this.OP_ORA = 34;\n this.OP_PHA = 35;\n this.OP_PHP = 36;\n this.OP_PLA = 37;\n this.OP_PLP = 38;\n this.OP_ROL = 39;\n this.OP_ROR = 40;\n this.OP_RTI = 41;\n this.OP_RTS = 42;\n this.OP_SBC = 43;\n this.OP_SEC = 44;\n this.OP_SED = 45;\n this.OP_SEI = 46;\n this.OP_STA = 47;\n this.OP_STX = 48;\n this.OP_STY = 49;\n this.OP_TAX = 50;\n this.OP_TAY = 51;\n this.OP_TSX = 52;\n this.OP_TXA = 53;\n this.OP_TXS = 54;\n this.OP_TYA = 55;\n this.OP_SIM = 56;\n this.OP_DB = 57;\n\n this.aOpCodes = [\n \"ADC\",\"AND\",\"ASL\",\"BCC\",\"BCS\",\"BEQ\",\"BIT\",\"BMI\",\n \"BNE\",\"BPL\",\"BRK\",\"BVC\",\"BVS\",\"CLC\",\"CLD\",\"CLI\",\n \"CLV\",\"CMP\",\"CPX\",\"CPY\",\"DEC\",\"DEX\",\"DEY\",\"EOR\",\n \"INC\",\"INX\",\"INY\",\"JMP\",\"JSR\",\"LDA\",\"LDX\",\"LDY\",\n \"LSR\",\"NOP\",\"ORA\",\"PHA\",\"PHP\",\"PLA\",\"PLP\",\"ROL\",\n \"ROR\",\"RTI\",\"RTS\",\"SBC\",\"SEC\",\"SED\",\"SEI\",\"STA\",\n \"STX\",\"STY\",\"TAX\",\"TAY\",\"TSX\",\"TXA\",\"TXS\",\"TYA\",\n \"SIM\",\".DB\"\n ];\n\n this.aOpSimCodes = [\n \"HLT\", \"MSG\"\n ];\n\n this.setOpModes(true);\n\n this.aaOperations = [\n /* 0x00 */ [this.OP_BRK],\n /* 0x01 */ [this.OP_ORA, 1, this.MODE_INDX],\n /* 0x02 */ [this.OP_SIM, 1],\n /* 0x03 */ [],\n /* 0x04 */ [],\n /* 0x05 */ [this.OP_ORA, 1, this.MODE_ZP],\n /* 0x06 */ [this.OP_ASL, 1, this.MODE_ZP],\n /* 0x07 */ [],\n /* 0x08 */ [this.OP_PHP],\n /* 0x09 */ [this.OP_ORA, 1, this.MODE_IMM],\n /* 0x0a */ [this.OP_ASL, 0, this.MODE_ACC],\n /* 0x0b */ [],\n /* 0x0c */ [],\n /* 0x0d */ [this.OP_ORA, 2, this.MODE_ABS],\n /* 0x0e */ [this.OP_ASL, 2, this.MODE_ABS],\n /* 0x0f */ [],\n /* 0x10 */ [this.OP_BPL, 1, this.MODE_DISP],\n /* 0x11 */ [this.OP_ORA, 1, this.MODE_INDY],\n /* 0x12 */ [],\n /* 0x13 */ [],\n /* 0x14 */ [],\n /* 0x15 */ [this.OP_ORA, 1, this.MODE_ZPX],\n /* 0x16 */ [this.OP_ASL, 1, this.MODE_ZPX],\n /* 0x17 */ [],\n /* 0x18 */ [this.OP_CLC],\n /* 0x19 */ [this.OP_ORA, 2, this.MODE_ABSY],\n /* 0x1a */ [],\n /* 0x1b */ [],\n /* 0x1c */ [],\n /* 0x1d */ [this.OP_ORA, 2, this.MODE_ABSX],\n /* 0x1e */ [this.OP_ASL, 2, this.MODE_ABSX],\n /* 0x1f */ [],\n /* 0x20 */ [this.OP_JSR, 2, this.MODE_IMM16],\n /* 0x21 */ [this.OP_AND, 1, this.MODE_INDX],\n /* 0x22 */ [],\n /* 0x23 */ [],\n /* 0x24 */ [this.OP_BIT, 1, this.MODE_ZP],\n /* 0x25 */ [this.OP_AND, 1, this.MODE_ZP],\n /* 0x26 */ [this.OP_ROL, 1, this.MODE_ZP],\n /* 0x27 */ [],\n /* 0x28 */ [this.OP_PLP],\n /* 0x29 */ [this.OP_AND, 1, this.MODE_IMM],\n /* 0x2a */ [this.OP_ROL, 0, this.MODE_ACC],\n /* 0x2b */ [],\n /* 0x2c */ [this.OP_BIT, 2, this.MODE_ABS],\n /* 0x2d */ [this.OP_AND, 2, this.MODE_ABS],\n /* 0x2e */ [this.OP_ROL, 2, this.MODE_ABS],\n /* 0x2f */ [],\n /* 0x30 */ [this.OP_BMI, 1, this.MODE_DISP],\n /* 0x31 */ [this.OP_AND, 1, this.MODE_INDY],\n /* 0x32 */ [],\n /* 0x33 */ [],\n /* 0x34 */ [],\n /* 0x35 */ [this.OP_AND, 1, this.MODE_ZPX],\n /* 0x36 */ [this.OP_ROL, 1, this.MODE_ZPX],\n /* 0x37 */ [],\n /* 0x38 */ [this.OP_SEC],\n /* 0x39 */ [this.OP_AND, 2, this.MODE_ABSY],\n /* 0x3a */ [],\n /* 0x3b */ [],\n /* 0x3c */ [],\n /* 0x3d */ [this.OP_AND, 2, this.MODE_ABSX],\n /* 0x3e */ [this.OP_ROL, 2, this.MODE_ABSX],\n /* 0x3f */ [],\n /* 0x40 */ [this.OP_RTI],\n /* 0x41 */ [this.OP_EOR, 1, this.MODE_INDX],\n /* 0x42 */ [],\n /* 0x43 */ [],\n /* 0x44 */ [],\n /* 0x45 */ [this.OP_EOR, 1, this.MODE_ZP],\n /* 0x46 */ [this.OP_LSR, 1, this.MODE_ZP],\n /* 0x47 */ [],\n /* 0x48 */ [this.OP_PHA],\n /* 0x49 */ [this.OP_EOR, 1, this.MODE_IMM],\n /* 0x4a */ [this.OP_LSR, 0, this.MODE_ACC],\n /* 0x4b */ [],\n /* 0x4c */ [this.OP_JMP, 2, this.MODE_IMM16],\n /* 0x4d */ [this.OP_EOR, 2, this.MODE_ABS],\n /* 0x4e */ [this.OP_LSR, 2, this.MODE_ABS],\n /* 0x4f */ [],\n /* 0x50 */ [this.OP_BVC, 1, this.MODE_DISP],\n /* 0x51 */ [this.OP_EOR, 1, this.MODE_INDY],\n /* 0x52 */ [],\n /* 0x53 */ [],\n /* 0x54 */ [],\n /* 0x55 */ [this.OP_EOR, 1, this.MODE_ZPX],\n /* 0x56 */ [this.OP_LSR, 1, this.MODE_ZPX],\n /* 0x57 */ [],\n /* 0x58 */ [this.OP_CLI],\n /* 0x59 */ [this.OP_EOR, 2, this.MODE_ABSY],\n /* 0x5a */ [],\n /* 0x5b */ [],\n /* 0x5c */ [],\n /* 0x5d */ [this.OP_EOR, 2, this.MODE_ABSX],\n /* 0x5e */ [this.OP_LSR, 2, this.MODE_ABSX],\n /* 0x5f */ [],\n /* 0x60 */ [this.OP_RTS],\n /* 0x61 */ [this.OP_ADC, 1, this.MODE_INDX],\n /* 0x62 */ [],\n /* 0x63 */ [],\n /* 0x64 */ [],\n /* 0x65 */ [this.OP_ADC, 1, this.MODE_ZP],\n /* 0x66 */ [this.OP_ROR, 1, this.MODE_ZP],\n /* 0x67 */ [],\n /* 0x68 */ [this.OP_PLA],\n /* 0x69 */ [this.OP_ADC, 1, this.MODE_IMM],\n /* 0x6a */ [this.OP_ROR, 0, this.MODE_ACC],\n /* 0x6b */ [],\n /* 0x6c */ [this.OP_JMP, 2, this.MODE_ABS16],\n /* 0x6d */ [this.OP_ADC, 2, this.MODE_ABS],\n /* 0x6e */ [this.OP_ROR, 2, this.MODE_ABS],\n /* 0x6f */ [],\n /* 0x70 */ [this.OP_BVS, 1, this.MODE_DISP],\n /* 0x71 */ [this.OP_ADC, 1, this.MODE_INDY],\n /* 0x72 */ [],\n /* 0x73 */ [],\n /* 0x74 */ [],\n /* 0x75 */ [this.OP_ADC, 1, this.MODE_ZPX],\n /* 0x76 */ [this.OP_ROR, 1, this.MODE_ZPX],\n /* 0x77 */ [],\n /* 0x78 */ [this.OP_SEI],\n /* 0x79 */ [this.OP_ADC, 2, this.MODE_ABSY],\n /* 0x7a */ [],\n /* 0x7b */ [],\n /* 0x7c */ [],\n /* 0x7d */ [this.OP_ADC, 2, this.MODE_ABSX],\n /* 0x7e */ [this.OP_ROR, 2, this.MODE_ABSX],\n /* 0x7f */ [],\n /* 0x80 */ [],\n /* 0x81 */ [this.OP_STA, 1, this.MODE_INDX],\n /* 0x82 */ [],\n /* 0x83 */ [],\n /* 0x84 */ [this.OP_STY, 1, this.MODE_ZP],\n /* 0x85 */ [this.OP_STA, 1, this.MODE_ZP],\n /* 0x86 */ [this.OP_STX, 1, this.MODE_ZP],\n /* 0x87 */ [],\n /* 0x88 */ [this.OP_DEY],\n /* 0x89 */ [],\n /* 0x8a */ [this.OP_TXA],\n /* 0x8b */ [],\n /* 0x8c */ [this.OP_STY, 2, this.MODE_ABS],\n /* 0x8d */ [this.OP_STA, 2, this.MODE_ABS],\n /* 0x8e */ [this.OP_STX, 2, this.MODE_ABS],\n /* 0x8f */ [],\n /* 0x90 */ [this.OP_BCC, 1, this.MODE_DISP],\n /* 0x91 */ [this.OP_STA, 1, this.MODE_INDY],\n /* 0x92 */ [],\n /* 0x93 */ [],\n /* 0x94 */ [this.OP_STY, 1, this.MODE_ZPX],\n /* 0x95 */ [this.OP_STA, 1, this.MODE_ZPX],\n /* 0x96 */ [this.OP_STX, 1, this.MODE_ZPY],\n /* 0x97 */ [],\n /* 0x98 */ [this.OP_TYA],\n /* 0x99 */ [this.OP_STA, 2, this.MODE_ABSY],\n /* 0x9a */ [this.OP_TXS],\n /* 0x9b */ [],\n /* 0x9c */ [],\n /* 0x9d */ [this.OP_STA, 2, this.MODE_ABSX],\n /* 0x9e */ [],\n /* 0x9f */ [],\n /* 0xa0 */ [this.OP_LDY, 1, this.MODE_IMM],\n /* 0xa1 */ [this.OP_LDA, 1, this.MODE_INDX],\n /* 0xa2 */ [this.OP_LDX, 1, this.MODE_IMM],\n /* 0xa3 */ [],\n /* 0xa4 */ [this.OP_LDY, 1, this.MODE_ZP],\n /* 0xa5 */ [this.OP_LDA, 1, this.MODE_ZP],\n /* 0xa6 */ [this.OP_LDX, 1, this.MODE_ZP],\n /* 0xa7 */ [],\n /* 0xa8 */ [this.OP_TAY],\n /* 0xa9 */ [this.OP_LDA, 1, this.MODE_IMM],\n /* 0xaa */ [this.OP_TAX],\n /* 0xab */ [],\n /* 0xac */ [this.OP_LDY, 2, this.MODE_ABS],\n /* 0xad */ [this.OP_LDA, 2, this.MODE_ABS],\n /* 0xae */ [this.OP_LDX, 2, this.MODE_ABS],\n /* 0xaf */ [],\n /* 0xb0 */ [this.OP_BCS, 1, this.MODE_DISP],\n /* 0xb1 */ [this.OP_LDA, 1, this.MODE_INDY],\n /* 0xb2 */ [],\n /* 0xb3 */ [],\n /* 0xb4 */ [this.OP_LDY, 1, this.MODE_ZPX],\n /* 0xb5 */ [this.OP_LDA, 1, this.MODE_ZPX],\n /* 0xb6 */ [this.OP_LDX, 1, this.MODE_ZPY],\n /* 0xb7 */ [],\n /* 0xb8 */ [this.OP_CLV],\n /* 0xb9 */ [this.OP_LDA, 2, this.MODE_ABSY],\n /* 0xba */ [this.OP_TSX],\n /* 0xbb */ [],\n /* 0xbc */ [this.OP_LDY, 2, this.MODE_ABSX],\n /* 0xbd */ [this.OP_LDA, 2, this.MODE_ABSX],\n /* 0xbe */ [this.OP_LDX, 2, this.MODE_ABSY],\n /* 0xbf */ [],\n /* 0xc0 */ [this.OP_CPY, 1, this.MODE_IMM],\n /* 0xc1 */ [this.OP_CMP, 1, this.MODE_INDX],\n /* 0xc2 */ [],\n /* 0xc3 */ [],\n /* 0xc4 */ [this.OP_CPY, 1, this.MODE_ZP],\n /* 0xc5 */ [this.OP_CMP, 1, this.MODE_ZP],\n /* 0xc6 */ [this.OP_DEC, 1, this.MODE_ZP],\n /* 0xc7 */ [],\n /* 0xc8 */ [this.OP_INY],\n /* 0xc9 */ [this.OP_CMP, 1, this.MODE_IMM],\n /* 0xca */ [this.OP_DEX],\n /* 0xcb */ [],\n /* 0xcc */ [this.OP_CPY, 2, this.MODE_ABS],\n /* 0xcd */ [this.OP_CMP, 2, this.MODE_ABS],\n /* 0xce */ [this.OP_DEC, 2, this.MODE_ABS],\n /* 0xcf */ [],\n /* 0xd0 */ [this.OP_BNE, 1, this.MODE_DISP],\n /* 0xd1 */ [this.OP_CMP, 1, this.MODE_INDY],\n /* 0xd2 */ [],\n /* 0xd3 */ [],\n /* 0xd4 */ [],\n /* 0xd5 */ [this.OP_CMP, 1, this.MODE_ZPX],\n /* 0xd6 */ [this.OP_DEC, 1, this.MODE_ZPX],\n /* 0xd7 */ [],\n /* 0xd8 */ [this.OP_CLD],\n /* 0xd9 */ [this.OP_CMP, 2, this.MODE_ABSY],\n /* 0xda */ [],\n /* 0xdb */ [],\n /* 0xdc */ [],\n /* 0xdd */ [this.OP_CMP, 2, this.MODE_ABSX],\n /* 0xde */ [this.OP_DEC, 2, this.MODE_ABSX],\n /* 0xdf */ [],\n /* 0xe0 */ [this.OP_CPX, 1, this.MODE_IMM],\n /* 0xe1 */ [this.OP_SBC, 1, this.MODE_INDX],\n /* 0xe2 */ [],\n /* 0xe3 */ [],\n /* 0xe4 */ [this.OP_CPX, 1, this.MODE_ZP],\n /* 0xe5 */ [this.OP_SBC, 1, this.MODE_ZP],\n /* 0xe6 */ [this.OP_INC, 1, this.MODE_ZP],\n /* 0xe7 */ [],\n /* 0xe8 */ [this.OP_INX],\n /* 0xe9 */ [this.OP_SBC, 1, this.MODE_IMM],\n /* 0xea */ [this.OP_NOP],\n /* 0xeb */ [],\n /* 0xec */ [this.OP_CPX, 2, this.MODE_ABS],\n /* 0xed */ [this.OP_SBC, 2, this.MODE_ABS],\n /* 0xee */ [this.OP_INC, 2, this.MODE_ABS],\n /* 0xef */ [],\n /* 0xf0 */ [this.OP_BEQ, 1, this.MODE_DISP],\n /* 0xf1 */ [this.OP_SBC, 1, this.MODE_INDY],\n /* 0xf2 */ [],\n /* 0xf3 */ [],\n /* 0xf4 */ [],\n /* 0xf5 */ [this.OP_SBC, 1, this.MODE_ZPX],\n /* 0xf6 */ [this.OP_INC, 1, this.MODE_ZPX],\n /* 0xf7 */ [],\n /* 0xf8 */ [this.OP_SED],\n /* 0xf9 */ [this.OP_SBC, 2, this.MODE_ABSY],\n /* 0xfa */ [],\n /* 0xfb */ [],\n /* 0xfc */ [],\n /* 0xfd */ [this.OP_SBC, 2, this.MODE_ABSX],\n /* 0xfe */ [this.OP_INC, 2, this.MODE_ABSX],\n /* 0xff */ []\n ];\n\n } // endif DEBUGGER\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var dbg = this;\n switch(sBinding) {\n case \"debugInput\":\n this.bindings[sBinding] = control;\n this.eDebug = /** @type {HTMLInputElement} */ (control);\n this.eDebug.focus();\n control.onkeypress = function(dbg, e) {\n return function(event) {\n if (event.keyCode == 13) {\n sBinding = e.value;\n e.value = \"\";\n C1PDebugger.input(dbg, sBinding);\n }\n };\n }(this, control);\n return true;\n \n case \"debugEnter\":\n this.bindings[sBinding] = control;\n /*\n * I've replaced the standard \"onclick\" code with a call to our onClickRepeat() helper in\n * component.js, so that the \"Enter\" button can be held to repeat, just like the \"Step\" button.\n */\n Web.onClickRepeat(\n control, 500, 100,\n function(fRepeat) {\n if (dbg.eDebug) {\n sBinding = dbg.eDebug.value;\n //\n // If we want to use the debugEnter button to repeatedly enter the same command,\n // then don't clear the command string.\n //\n // dbg.eDebug.value = \"\";\n //\n C1PDebugger.input(dbg, sBinding);\n return true;\n }\n if (DEBUG) dbg.log(\"no debugger input buffer\");\n return false;\n }\n );\n return true;\n \n case \"step\":\n this.bindings[sBinding] = control;\n Web.onClickRepeat(\n control, 500, 100,\n function(fRepeat) {\n var fCompleted = false;\n if (!dbg.isBusy(true)) {\n dbg.setBusy(true);\n fCompleted = dbg.step(fRepeat? 1 : 0);\n dbg.setBusy(false);\n }\n return fCompleted;\n }\n );\n return true;\n \n default:\n break;\n }\n return false;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {Array} abMemory\n * @param {number} start\n * @param {number} end\n */\n setBuffer(abMemory, start, end)\n {\n this.abMem = abMemory;\n this.offMem = start;\n this.cbMem = end - start + 1;\n this.offLimit = this.offMem + this.cbMem;\n this.setReady();\n }\n\n /**\n * @this {C1PDebugger}\n * @param {boolean} fOn\n * @param {C1PComputer} cmp\n */\n setPower(fOn, cmp)\n {\n if (fOn && !this.flags.powered) {\n this.flags.powered = true;\n this.cpu = cmp.getComponentByType(\"cpu\");\n }\n }\n\n /**\n * @this {C1PDebugger}\n */\n setFocus()\n {\n this.eDebug.focus();\n }\n\n /**\n * @this {C1PDebugger}\n * @param {boolean} fClassic is true for \"classic\" operand syntax, or false for \"modern\" operand syntax\n *\n * The strings describing the operand(s) also describe the addressing mode, as follows:\n *\n * bbb mode classic modern description\n * --- ---- ------- ------- ----------------\n * 000 INDX ($nn,X) [[nn+X]] Indexed Indirect\n * 001 ZP $nn [nn] Zero-Page\n * 010 IMM #$nn nn Immediate\n * 011 ABS $nnnn [nnnn] Absolute\n * 100 INDY ($nn),Y [[nn]+Y] Indirect Indexed\n * 101 ZPX $nn,X [nn+X] Zero-Page,X\n * 110 ABSY $nnnn,Y [nnnn+Y] Absolute,Y\n * 111 ABSX $nnnn,X [nnnn+X] Absolute,X\n *\n * where bbb generally corresponds to bits 2-4 of the opcode. I find that using brackets in the\n * descriptors to indicate a memory access (or multiple brackets, in the case of indirect accesses),\n * along with \"+\" and any index register, is more intuitive than the \"classic\" operand formats;\n * the absence of any brackets implies immediate data, eliminating the need for a prepended \"#\".\n * Also, the use of 2-digit instead of 4-digit addresses indicates that a zero-page address is\n * being used. Finally, all displacements/addresses and immediate values are displayed in hex by\n * default, so there is no need to waste space prepending the traditional \"$\" to such values.\n *\n * Other addressing modes:\n *\n * 101 ZPY $nn,Y Zero-Page,Y (used by LDX and STX only)\n *\n * ACC A Accumulator\n *\n * IMM16 $nnnn Used by JSR (0x20) and JMP (0x4C); I consider this an \"Immediate\" operation\n * that uses 16 bits, but it is documented as \"Absolute\" addressing (see Zaks)\n *\n * FYI, this is the same operand format used for branch displacements (MODE_DISP),\n * except the displacements are 8-bit values that are signed-extended to 16 bits, so\n * discriminating between MODE_DISP and MODE_IMM16 also requires checking the operand size\n *\n * ABS16 ($nnnn) Used by JMP (0x6C); I consider this an \"Absolute\" operation that fetches\n * 16 bits of data, but it is documented as \"Indirect\" addressing (see Zaks)\n */\n setOpModes(fClassic)\n {\n /*\n * NOTE: The modes are arranged within aOpModes so that longer matches are checked before\n * any subsets that could also match (eg, check for \"$nn,X\" before \"$nn\", \"$nnnn,X\" before \"$nnnn\", etc).\n */\n this.MODE_ACC = 0;\n this.MODE_IMM = 1;\n this.MODE_ABSX = 2;\n this.MODE_ABSY = 3;\n this.MODE_IMM16 = 4;\n this.MODE_ABS16 = 5;\n this.MODE_ZPX = 6;\n this.MODE_ZPY = 7;\n this.MODE_INDX = 8;\n this.MODE_INDY = 9;\n this.MODE_ABS = 10;\n this.MODE_ZP = 11;\n this.MODE_DISP = this.MODE_IMM16;\n\n var sRegEx = \"\";\n var iMode, sMode;\n\n if (fClassic) {\n this.aOpModes = [\n \"A\", // MODE_ACC\n /* 010b */ \"#$nn\", // MODE_IMM\n /* 111b */ \"$nnnn,X\", // MODE_ABSX\n /* 110b */ \"$nnnn,Y\", // MODE_ABSY\n \"$nnnn\", // MODE_IMM16\n \"($nnnn)\", // MODE_ABS16\n /* 101b */ \"$nn,X\", // MODE_ZPX\n \"$nn,Y\", // MODE_ZPY\n /* 000b */ \"($nn,X)\", // MODE_INDX\n /* 100b */ \"($nn),Y\", // MODE_INDY\n /* 011b */ \"$nnnn\", // MODE_ABS\n /* 001b */ \"$nn\" // MODE_ZP\n ];\n for (iMode=0; iMode < this.aOpModes.length; iMode++) {\n sMode = this.aOpModes[iMode];\n sRegEx += \"(\" + sMode.replace(/\\(/g, \"\\\\(\").replace(/\\)/g, \"\\\\)\").replace(/nnnn/g, \"[0-9A-F][0-9A-F][0-9A-F][0-9A-F]?\").replace(/nn/g, \"[0-9A-F][0-9A-F]?\").replace(/\\$/g, \"\\\\$\") + \"|)\";\n }\n this.regexOpModes = new RegExp(sRegEx);\n }\n else {\n this.aOpModes = [\n \"A\", // MODE_ACC\n /* 010b */ \"nn\", // MODE_IMM\n /* 111b */ \"[nnnn+X]\", // MODE_ABSX\n /* 110b */ \"[nnnn+Y]\", // MODE_ABSY\n \"nnnn\", // MODE_IMM16\n \"[nnnn]\", // MODE_ABS16\n /* 101b */ \"[nn+X]\", // MODE_ZPX\n \"[nn+Y]\", // MODE_ZPY\n /* 000b */ \"[[nn+X]]\", // MODE_INDX\n /* 100b */ \"[[nn]+Y]\", // MODE_INDY\n /* 011b */ \"[nnnn]\", // MODE_ABS\n /* 001b */ \"[nn]\" // MODE_ZP\n ];\n for (iMode=0; iMode < this.aOpModes.length; iMode++) {\n sMode = this.aOpModes[iMode];\n sRegEx += \"(\" + sMode.replace(/\\[/g, \"\\\\[\").replace(/]/g, \"\\\\]\").replace(/nnnn/g, \"[0-9A-F][0-9A-F][0-9A-F][0-9A-F]?\").replace(/nn/g, \"[0-9A-F][0-9A-F]?\").replace(/\\+/g, \"\\\\+\") + \"|)\";\n }\n this.regexOpModes = new RegExp(sRegEx);\n }\n /*\n * Regrettably, if \"classic\" operand syntax is in effect, then we will have to look at the context of the\n * operand (ie, the operation code) whenever we have a MODE_IMM16 (or MODE_DISP) match, because it might actually\n * be a MODE_ABS operand. MODE_IMM16 is used with only 2 operations (OP_JSR and OP_JMP), and MODE_DISP only 8\n * (OP_BPL, OP_BMI, OP_BVC, OP_BVS, OP_BCC, OP_BCS, OP_BNE, and OP_BEQ), so if the operation isn't one of those\n * codes (in the following array), then we should convert MODE_IMM16 (aka MODE_DISP) into MODE_ABS.\n */\n this.aImm16Codes = [this.OP_JMP, this.OP_JSR, this.OP_BPL, this.OP_BMI, this.OP_BVC, this.OP_BVS, this.OP_BCC, this.OP_BCS, this.OP_BNE, this.OP_BEQ];\n }\n\n /**\n * @this {C1PDebugger}\n */\n halt()\n {\n /*\n * We ask the CPU to halt, but we can't assume it's stopped until it calls stop()\n */\n this.cpu.halt();\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string} s is any diagnostic string that you can print later using the Debugger's \"i\" command\n */\n info(s)\n {\n if (DEBUG) {\n this.aInfoBuffer[this.iInfoBuffer++] = s;\n if (this.iInfoBuffer >= this.aInfoBuffer.length)\n this.iInfoBuffer = 0;\n }\n }\n\n /**\n * @this {C1PDebugger}\n * @param {Component} component\n * @param {number} addr\n * @param {number|undefined} addrFrom\n * @param {boolean} bitsMessage is a Debugger MESSAGE_* category flag\n * @param {boolean|undefined} [fWrite] is true if this was a write, false (or undefined) if read\n * @param {string|undefined} [name] of the port, if any\n */\n messageIO(component, addr, addrFrom, bitsMessage, fWrite, name)\n {\n if ((this.bitsMessage & bitsMessage) == bitsMessage) {\n var b = this.cpu.getByte(addr);\n this.message(component.id + \".\" + (fWrite? \"setByte\":\"getByte\") + \"(\" + Str.toHexWord(addr) + \")\" + (addrFrom !== undefined? (\" @\" + Str.toHexWord(addrFrom)) : \"\") + \": \" + (name? (name + \"=\") : \"\") + Str.toHexByte(b));\n }\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string} sMessage is any caller-defined message string\n */\n message(sMessage)\n {\n this.println(sMessage);\n this.cpu.yieldCPU(); // these print() calls are at risk of being called with high frequency, so we need to yieldCPU() more\n }\n\n /**\n * @this {C1PDebugger}\n */\n init()\n {\n // this.doHelp();\n this.println(\"Type ? for list of debugger commands\\n\");\n }\n\n /**\n * @this {C1PDebugger}\n * @return {boolean}\n */\n run()\n {\n if (!this.isCPUOK()) return false;\n this.cpu.run();\n return true;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} n (0 implies a single-step, and therefore breakpoints should be ignored)\n * @return {boolean}\n */\n step(n)\n {\n if (!this.isCPUOK()) return false;\n var fCompleted;\n try {\n fCompleted = this.cpu.step(n);\n }\n catch(e) {\n fCompleted = undefined;\n this.cpu.setError(e.stack || e.message);\n }\n if (fCompleted !== undefined) this.cIns++;\n /*\n * Because we called cpu.step() and not cpu.run(), we must\n * nudge the CPU's update code, and then update our own state.\n */\n this.cpu.update(true);\n this.update(true);\n return fCompleted;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {boolean} [fStep]\n */\n update(fStep)\n {\n this.nextAddr = this.cpu.regPC;\n if (fStep || this.fStepOver)\n this.doUnassemble();\n else\n this.doRegisters();\n }\n\n /**\n * @this {C1PDebugger}\n * @return {boolean}\n *\n * Make sure the CPU is ready (finished initializing), not busy (already running), and not in an error state.\n */\n isCPUOK()\n {\n if (!this.cpu)\n return false;\n if (!this.cpu.isReady())\n return false;\n if (this.cpu.isBusy())\n return false;\n return !this.cpu.isError();\n }\n\n /**\n * @this {C1PDebugger}\n *\n * This is a notification handler, called by the CPU, to inform us that the CPU has been reset.\n */\n reset()\n {\n var i;\n if (!this.aStepHistory.length)\n this.aStepHistory = new Array(1000);\n for (i = 0; i < this.aStepHistory.length; i++)\n this.aStepHistory[i] = -1;\n if (!this.aaOpcodeFreqs.length)\n this.aaOpcodeFreqs = new Array(256);\n for (i = 0; i < this.aaOpcodeFreqs.length; i++)\n this.aaOpcodeFreqs[i] = [i, 0];\n if (this.cIns) this.update();\n this.cIns = 0;\n this.cReads = this.cWrites = this.cWritesZP = 0;\n }\n\n /**\n * @this {C1PDebugger}\n *\n * This is a notification handler, called by the CPU, to inform us that the CPU has started running.\n */\n start()\n {\n if (!this.fStepOver) this.println(\"running\");\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} msStart\n * @param {number} nCycles\n *\n * This is a notification handler, called by the CPU, to inform us that the CPU has now stopped running.\n */\n stop(msStart, nCycles)\n {\n if (!this.fStepOver) {\n this.println(\"stopped\");\n if (nCycles) {\n var msTotal = Usr.getTime();\n msTotal -= msStart;\n this.println(msTotal + \"ms (\" + nCycles + \" cycles)\");\n if (DEBUG && msTotal > 0) {\n nCycles = nCycles * 1000 / msTotal;\n this.println(\"total cycles/second: \" + Math.round(nCycles));\n var percent = Math.round((this.cIns? this.cReads / this.cIns : 0) * 1000) / 10;\n this.println(\"total reads: \" + this.cReads + \" (\" + percent + \"%)\");\n percent = Math.round((this.cIns? this.cWrites / this.cIns : 0) * 1000) / 10;\n this.println(\"total writes: \" + this.cWrites + \" (\" + percent + \"%)\");\n percent = Math.round((this.cIns? this.cWritesZP / this.cIns : 0) * 1000) / 10;\n this.println(\"total zero-page writes: \" + this.cWritesZP + \" (\" + percent + \"%)\");\n this.println(\"total instructions: \" + this.cIns);\n }\n }\n }\n this.update();\n this.setFocus();\n if (!this.fStepOver) {\n this.cIns = 0;\n this.cReads = this.cWrites = this.cWritesZP = 0;\n }\n this.clearTempBreakpoint(this.cpu.regPC);\n }\n\n /**\n * @this {C1PDebugger}\n *\n * This is a check function, called by the CPU, indicating whether other instructions need to be checked.\n */\n checksEnabled()\n {\n return (DEBUG? true : (this.aExecBreak.length > 0 || this.aReadBreak.length > 0 || this.aWriteBreak.length > 0));\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @param {number} bOpCode\n * @return {boolean} true to proceed, false to halt\n *\n * This is a check function, called by the CPU, to inform us about the next instruction to be executed, giving\n * us an opportunity to look for \"exec\" breakpoints and update opcode frequencies and instruction history.\n */\n checkInstruction(addr, bOpCode)\n {\n var fBreak = false;\n if (this.checkBreakpoint(addr, this.aExecBreak, \"exec\"))\n fBreak = true;\n else {\n this.cIns++;\n this.aaOpcodeFreqs[bOpCode][1]++;\n this.aStepHistory[this.iStepHistory++] = this.cpu.regPC;\n if (this.iStepHistory >= this.aStepHistory.length)\n this.iStepHistory = 0;\n }\n return !fBreak;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @return {boolean} true to proceed, false to halt\n *\n * This is a check function, called by the CPU, to inform us that a memory read occurred, giving us an\n * opportunity to track the read if we want, and look for a matching \"read\" breakpoint, if any.\n */\n checkMemoryRead(addr)\n {\n var fBreak = false;\n this.cReads++;\n if (this.checkBreakpoint(addr, this.aReadBreak, \"read\"))\n fBreak = true;\n return !fBreak;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @param {number} value written\n * @return {boolean} true to proceed, false to halt\n *\n * This is a check function, called by the CPU, to inform us that a memory write occurred, giving us an\n * opportunity to track the write if we want, and look for a matching \"write\" breakpoint, if any.\n */\n checkMemoryWrite(addr, value)\n {\n var fBreak = false;\n this.cWrites++;\n /*\n * NOTE: We keep track of zero-page writes mainly as a reminder to look into whether it makes sense\n * for the CPU to calculate zero-page EAs using a different variable (eg, regEAWriteZP instead of regEAWrite),\n * because write-notification handlers never care about page zero accesses, and while write breakpoints *may*\n * care, it may not be worth the cost of tracking writes to page zero if there's an associated perf penalty.\n */\n if (!(addr & 0xff00))\n this.cWritesZP++;\n if ((value & 0xff) != value) {\n this.println(\"invalid value at \" + Str.toHexWord(addr) + \": \" + value);\n fBreak = true;\n }\n if (this.checkBreakpoint(addr, this.aWriteBreak, \"write\"))\n fBreak = true;\n return !fBreak;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @param {number} b\n * @return {number}\n */\n addSignedByte(addr, b)\n {\n return addr + ((b << 24) >> 24);\n }\n\n /**\n * getByte() should be used for all memory reads performed by the Debugger (eg, doDump, doUnassemble),\n * to insure that the CPU is properly notified (and by extension, any device that's registered a\n * notification handler with the CPU).\n *\n * @this {C1PDebugger}\n * @param {number} addr\n * @return {number|undefined}\n */\n getByte(addr)\n {\n var b;\n if (addr >= this.offMem && addr < this.offLimit) {\n this.cpu.checkReadNotify(addr);\n b = this.abMem[this.offMem + addr];\n\n b &= 0xff;\n }\n return b;\n }\n\n /**\n * setByte() should be used for all memory writes performed by the Debugger (eg, doAssemble, doEdit),\n * to insure that the CPU is properly notified (and by extension, any device that's registered a\n * notification handler with the CPU).\n *\n * NOTE: Even though we call all write-notification handlers, we don't include a \"from\" address,\n * because the write originated from the Debugger, not from a CPU instruction. As a result, handlers should\n * not refuse the write unless they have good reason; in particular, the ROM handlers will not refuse our writes,\n * allowing the Debugger to modify ROM contents as needed.\n *\n * @this {C1PDebugger}\n * @param {number} addr\n * @param {number} b\n */\n setByte(addr, b)\n {\n if (addr < this.offMem || addr >= this.offLimit) {\n this.println(\"invalid address: \" + Str.toHexWord(addr));\n return;\n }\n this.abMem[this.offMem + addr] = (b & 0xff);\n this.cpu.checkWriteNotify(addr);\n this.cpu.update();\n }\n\n /**\n * @this {C1PDebugger}\n */\n clearBreakpoints()\n {\n this.aExecBreak = [];\n this.aReadBreak = [];\n this.aWriteBreak = [];\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @return {boolean}\n */\n addExecBreakpoint(addr)\n {\n if (!this.findExecBreakpoint(addr)) {\n this.aExecBreak.push(addr);\n }\n return true;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @return {boolean}\n */\n addReadBreakpoint(addr)\n {\n if (!this.findReadBreakpoint(addr)) {\n this.aReadBreak.push(addr);\n }\n return true;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @return {boolean}\n */\n addWriteBreakpoint(addr)\n {\n if (!this.findWriteBreakpoint(addr)) {\n this.aWriteBreak.push(addr);\n }\n return true;\n }\n\n /**\n * @this {C1PDebugger}\n * @return {Array}\n */\n getExecBreakpoints()\n {\n return this.aExecBreak;\n }\n\n /**\n * @this {C1PDebugger}\n * @return {Array}\n */\n getReadBreakpoints()\n {\n return this.aReadBreak;\n }\n\n /**\n * @this {C1PDebugger}\n * @return {Array}\n */\n getWriteBreakpoints()\n {\n return this.aWriteBreak;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {Array} aBreak\n * @param {number} addr\n * @param {boolean} [fRemove]\n * @return {boolean}\n */\n findBreakpoint(aBreak, addr, fRemove)\n {\n var fMatch = false;\n for (var i=0; i < aBreak.length; i++) {\n if (aBreak[i] == addr) {\n if (fRemove) {\n aBreak.splice(i, 1);\n }\n fMatch = true;\n break;\n }\n }\n return fMatch;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @param {boolean} [fRemove]\n * @return {boolean}\n */\n findExecBreakpoint(addr, fRemove)\n {\n return this.findBreakpoint(this.aExecBreak, addr, fRemove);\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @param {boolean} [fRemove]\n * @return {boolean}\n */\n findReadBreakpoint(addr, fRemove)\n {\n return this.findBreakpoint(this.aReadBreak, addr, fRemove);\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @param {boolean} [fRemove]\n * @return {boolean}\n */\n findWriteBreakpoint(addr, fRemove)\n {\n return this.findBreakpoint(this.aWriteBreak, addr, fRemove);\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number|undefined} addr of new temp breakpoint\n */\n setTempBreakpoint(addr)\n {\n if (addr !== undefined) {\n /*\n * I don't want temporary breakpoints growing out of control, so I forcibly clear any\n * existing temp breakpoint by feeding clearTempBreakpoint() the current temp address, if any;\n * but you can remove the next line if you decide multiple temp breakpoints are a good thing.\n */\n this.clearTempBreakpoint(this.addrTempBP);\n if (this.addExecBreakpoint(addr))\n this.addrTempBP = addr;\n }\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr to compare to addrTempBP; the latter is cleared if there's a match\n */\n clearTempBreakpoint(addr)\n {\n if (this.addrTempBP !== undefined && addr == this.addrTempBP) {\n if (this.findExecBreakpoint(this.addrTempBP, true)) {\n this.addrTempBP = undefined;\n }\n }\n this.fStepOver = false;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @param {Array} aBreakpoints\n * @param {string} sType (ie, \"exec\" or \"write\")\n * @return {boolean} true if breakpoint has been hit, false if not\n */\n checkBreakpoint(addr, aBreakpoints, sType)\n {\n /*\n * Time to check for execution breakpoints; note that this should be done BEFORE updating any of the frequency\n * or history data (see checkInstruction), since we might not actually execute the current instruction.\n */\n var fBreak = false;\n for (var i=0; i < aBreakpoints.length; i++) {\n if (aBreakpoints[i] == addr) {\n if (addr != this.addrTempBP)\n this.println(\"breakpoint hit: \" + Str.toHexWord(addr) + \" (\" + sType + \")\");\n fBreak = true;\n break;\n }\n }\n return fBreak;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {number} addr\n * @param {number} [nIns] is an associated instruction number, or 0 (or undefined) if none\n * @return {string}\n */\n getInstruction(addr, nIns)\n {\n var sLine = Str.toHex(addr, 4);\n var bOpCode = this.getByte(addr++);\n var b = (bOpCode === undefined? 0 : bOpCode);\n var aOpDesc = this.aaOperations[b];\n var abOperand = [];\n var cb = (aOpDesc[1] === undefined? 0 : aOpDesc[1]);\n do {\n sLine += \" \" + Str.toHex(b, 2);\n if (!(cb--)) break;\n b = this.getByte(addr++);\n if (b === undefined) break;\n abOperand.push(b);\n } while (true);\n if (aOpDesc[0] === undefined) {\n aOpDesc = [this.OP_DB, 1, this.MODE_IMM];\n abOperand.push(bOpCode);\n }\n sLine = (sLine + \" \").substr(0, 15);\n sLine += this.aOpCodes[aOpDesc[0]];\n var sOperand = null;\n if (aOpDesc[2] !== undefined) {\n var bOpMode = aOpDesc[2];\n sOperand = this.aOpModes[bOpMode];\n if (aOpDesc[1] == 1 && bOpMode == this.MODE_DISP) {\n sOperand = sOperand.replace(/nnnn/, Str.toHex(this.addSignedByte(addr, b = abOperand.pop()), 4));\n }\n else {\n while (abOperand.length) {\n sOperand = sOperand.replace(/nn/, Str.toHex(b = abOperand.pop(), 2));\n }\n }\n if (bOpMode == this.MODE_IMM && aOpDesc[1] == 1) {\n if (b >= 0x20 && b < 0x80)\n sOperand += \" ;'\" + String.fromCharCode(b) + \"'\";\n }\n }\n if (bOpCode == this.cpu.OP_SIM) {\n if (b < this.aOpSimCodes.length)\n sOperand = this.aOpSimCodes[b];\n if (b == this.cpu.SIMOP_MSG) {\n cb = 0;\n sOperand = \"\\\"\";\n while ((b = this.getByte(addr++))) {\n if (cb < 16)\n sOperand += String.fromCharCode(b);\n else if (cb == 16)\n sOperand += \"…\";\n cb++;\n }\n sOperand += \"\\\"\";\n }\n }\n if (sOperand) sLine += \" \" + sOperand;\n if (nIns) {\n sLine += \" \";\n sLine = sLine.substr(0, 30);\n sLine += \";\" + nIns.toString();\n }\n this.nextIns = addr;\n return sLine;\n }\n\n /**\n * parseInstruction(sCode, sOperand, addr)\n *\n * This generally requires an exact match of both the operation code (sCode) and mode operand (sOperand)\n * against the aOpCodes[] and aOpModes[] arrays, respectively; however, the regular expression built from\n * aOpModes and stored in regexOpModes does relax the matching criteria slightly; ie, a 4-digit hex value\n * (\"nnnn\") will be satisfied with either 3 or 4 digits, and similarly, a 2-digit hex address (nn) will\n * be satisified with either 1 or 2 digits.\n *\n * Note that this function does not actually store the instruction into memory, even though it requires\n * a target address (addr); that parameter is currently needed ONLY for \"branch\" instructions, because in\n * order to calculate the branch displacement, it needs to know where the instruction will ultimately be\n * stored, relative to its target address.\n *\n * Another handy feature of this function is its ability to display all available modes for a particular\n * operation. For example, while in \"assemble mode\", if one types:\n *\n * ldy?\n *\n * the Debugger will display:\n *\n * supported opcodes:\n * A0: LDY nn\n * A4: LDY [nn]\n * AC: LDY [nnnn]\n * B4: LDY [nn+X]\n * BC: LDY [nnnn+X]\n *\n * Use of a trailing \"?\" on any opcode will display all variations of that opcode; no instruction will be\n * assembled, and the operand parameter, if any, will be ignored.\n *\n * Although this function is capable of reporting numerous errors, roughly half of them indicate internal\n * consistency errors, not user errors; the former should really be asserts, but I'm not comfortable bombing\n * out because of my error as opposed to their error. The only errors a user should expect to see:\n *\n * \"unknown operation\": sCode is not a valid operation (per aOpCodes)\n * \"unknown operand\": sOperand is not a valid operand (per aOpModes)\n * \"unknown instruction\": the combination of sCode + sOperand does not exist (per aaOperations)\n * \"branch out of range\": the branch address, relative to addr, is too far away\n *\n * @this {C1PDebugger}\n * @param {string} sCode\n * @param {string|undefined} sOperand\n * @param {number} addr of memory where this instruction is being assembled\n * @return {Array.<number>} of opcode bytes; if the instruction can't be parsed, the array will be empty\n */\n parseInstruction(sCode, sOperand, addr)\n {\n var aOpBytes = [];\n if (sCode !== undefined) {\n var iCode, iMode;\n /*\n * Find the iCode that corresponds to the given operation code\n */\n sCode = sCode.toUpperCase();\n if (sCode.charAt(sCode.length-1) == \"?\") {\n sOperand = \"?\";\n sCode = sCode.substr(0, sCode.length-1);\n }\n for (iCode=0; iCode < this.aOpCodes.length; iCode++) {\n if (sCode == this.aOpCodes[iCode]) {\n break;\n }\n }\n if (iCode == this.aOpCodes.length) {\n this.println(\"unknown operation: \" + sCode);\n iCode = -1;\n }\n var sMode = \"\", aModeMatch, i;\n if (iCode >= 0 && sOperand !== undefined) {\n sMode = sOperand.toUpperCase();\n if (sMode == \"?\") {\n var cModes = 0;\n for (i = 0; i < this.aaOperations.length; i++) {\n if (this.aaOperations[i][0] === iCode) {\n if (!cModes) this.println(\"supported opcodes:\");\n this.println(\" \" + Str.toHex(i, 2) + \": \" + sCode + (this.aaOperations[i][2] !== undefined? (\" \" + this.aOpModes[this.aaOperations[i][2]]) : \"\"));\n cModes++;\n }\n }\n iCode = -1;\n }\n else {\n /*\n * Find the iMode that corresponds to the given operand\n */\n aModeMatch = sMode.match(this.regexOpModes);\n if (aModeMatch !== null && aModeMatch[0] == sMode) {\n /*\n * One of the sub-patterns must have matched as well; the index of the matching\n * sub-pattern will correspond to the proper aOpModes index, albeit off-by-one since\n * the regex match at [0] is the complete match, not a sub-pattern match.\n */\n for (i = 1; i < aModeMatch.length; i++) {\n if (aModeMatch[i] == sMode) {\n if (iMode === undefined)\n iMode = i-1;\n else {\n /*\n * This is really an internal consistency error; regardless what the user types, this should not occur.\n */\n //noinspection JSUnusedAssignment\n this.println(\"too many operand matches (both \" + this.aOpModes[iMode] + \" and \" + this.aOpModes[i-1] + \")\");\n iCode = -1;\n break;\n }\n }\n }\n /*\n * Regrettably, if \"classic\" operand syntax is in effect, then we must look at the context of the\n * operand (ie, the operation code) whenever we have a MODE_IMM16 (or MODE_DISP) match, because it might\n * actually be a MODE_ABS operand; see setOpModes() for details of the aImm16Codes array.\n */\n if (iMode == this.MODE_IMM16) {\n if (this.aImm16Codes.indexOf(iCode) < 0)\n iMode = this.MODE_ABS;\n }\n /*\n * Even in \"modern\" syntax mode, we have to look at the context of a MODE_ABS16 match, because unless\n * the operation is OP_JMP, then the mode must actually be MODE_ABS.\n */\n if (iMode == this.MODE_ABS16) {\n if (iCode != this.OP_JMP)\n iMode = this.MODE_ABS;\n }\n }\n else {\n this.println(\"unknown operand: \" + sMode);\n iCode = -1;\n }\n }\n }\n if (iCode >= 0) {\n /*\n * So we have an iCode and possibly an iMode; find the one (and hopefully only) aaOperations instruction entry that matches\n */\n var bOpCode = -1;\n for (i = 0; i < this.aaOperations.length; i++) {\n if (this.aaOperations[i][0] === iCode && this.aaOperations[i][2] === iMode) {\n if (bOpCode < 0)\n bOpCode = i;\n else {\n /*\n * This is really an internal consistency error; regardless what the user types, this should not occur.\n */\n this.println(\"too many instruction matches (both \" + Str.toHexByte(bOpCode) + \" and \" + Str.toHexByte(i) + \")\");\n bOpCode = -2;\n break;\n }\n }\n }\n if (bOpCode >= 0) {\n aOpBytes.push(bOpCode);\n if (iMode !== undefined) {\n var cb = this.aaOperations[bOpCode][1];\n var asHex = sMode.match(/[0-9A-F]+/);\n if (asHex !== null) {\n var nHex = parseInt(asHex[0], 16);\n if (cb == 1 && iMode == this.MODE_DISP) {\n nHex -= (addr + 2);\n if (nHex < -128 || nHex > 127) {\n this.println(\"branch out of range (\" + nHex + \")\");\n aOpBytes = [];\n cb = 0;\n }\n }\n for (i = 0; i < cb; i++) {\n aOpBytes.push(nHex & 0xff);\n nHex >>>= 8;\n }\n }\n else if (cb) {\n /*\n * This is really an internal consistency error; regardless what the user types, this should not occur.\n */\n this.println(\"instruction missing \" + cb + \" bytes\");\n }\n }\n }\n else {\n this.println(\"unknown instruction: \" + sCode + \" \" + sMode + (DEBUG? (\" (\" + iMode + \")\") : \"\"));\n }\n }\n }\n return aOpBytes;\n }\n\n /**\n * @this {C1PDebugger}\n * @return {string}\n */\n getRegs()\n {\n return \"A=\" + Str.toHex(this.cpu.regA, 2) +\n \" X=\" + Str.toHex(this.cpu.regX, 2) +\n \" Y=\" + Str.toHex(this.cpu.regY, 2) +\n \" P=\" + Str.toHex(this.cpu.getRegP(), 2) +\n \" S=\" + Str.toHex(this.cpu.regS, 4) +\n \" PC=\" + Str.toHex(this.cpu.regPC, 4);\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string|undefined} [sAddr]\n * @return {number|undefined}\n */\n getUserAddr(sAddr)\n {\n var addr = this.nextAddr;\n if (sAddr !== undefined) {\n var nBase = 16;\n if (sAddr.charAt(0) == \"$\")\n sAddr = sAddr.substr(1);\n else\n if (sAddr.substr(0, 2) == \"0x\")\n sAddr = sAddr.substr(2);\n else\n if (sAddr.charAt(sAddr.length-1) == \".\") {\n nBase = 10;\n sAddr = sAddr.substr(0, sAddr.length-1);\n }\n addr = parseInt(sAddr, nBase);\n if (isNaN(addr)) {\n this.println(\"invalid base-\" + nBase + \" address: \" + sAddr);\n addr = undefined;\n }\n }\n if (addr !== undefined && (addr < this.offMem || addr >= this.offLimit)) {\n this.println(\"address out of range: \" + Str.toHex(addr));\n addr = undefined;\n }\n return addr;\n }\n\n /**\n * @this {C1PDebugger}\n */\n doHelp()\n {\n this.println(\"\\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\");\n this.println(\"note: frequency and history commands operate only when breakpoints are set\");\n }\n\n /**\n * doAssemble() always receives the complete argument array, where the order of the arguments is:\n *\n * [0]: the assemble command (assumed to be \"a\")\n * [1]: the target address (eg, \"200\")\n * [2]: the operation code, aka mnemonic (eg, \"adc\")\n * [3]: the operation mode operand, if any (eg, \"14\", \"[1234]\", etc)\n *\n * The Debugger enters \"assemble mode\" whenever only the first (or first and second) arguments are present.\n * As long as \"assemble mode is active, the user can omit the first two arguments on all later assemble commands\n * until \"assemble mode\" is cancelled with an empty command line; the command processor automatically prepends \"a\"\n * and the next available target address to the argument array.\n *\n * Entering \"assemble mode\" is optional; one could enter a series of fully-qualified assemble commands; eg:\n *\n * a ff00 cld\n * a ff01 ldx 28\n * ...\n *\n * without ever entering \"assemble mode\", but of course, that requires more typing and doesn't take advantage\n * of automatic target address advancement (see addrAssembleNext).\n *\n * NOTE: As the previous example implies, you can even assemble new instructions into ROM address space;\n * as our setByte() function explains, the ROM write-notification handlers only refuse writes from the CPU.\n *\n * @this {C1PDebugger}\n * @param {Array.<string>} asArgs is the complete argument array, beginning with the \"a\" command in asArgs[0]\n */\n doAssemble(asArgs)\n {\n var addr = this.getUserAddr(asArgs[1]);\n if (addr === undefined)\n return;\n this.addrAssembleNext = addr;\n if (asArgs[2] === undefined) {\n this.println(\"begin assemble @\" + Str.toHexWord(this.addrAssembleNext));\n this.fAssemble = true;\n this.cpu.update();\n return;\n }\n var aOpBytes = this.parseInstruction(asArgs[2], asArgs[3], this.addrAssembleNext);\n if (aOpBytes.length) {\n for (var i=0; i < aOpBytes.length; i++) {\n // this.println(Str.toHexWord(this.addrAssembleNext) + \": \" + Str.toHexByte(aOpBytes[i]));\n this.setByte(this.addrAssembleNext+i, aOpBytes[i]);\n }\n this.println(this.getInstruction(this.addrAssembleNext));\n this.addrAssembleNext += aOpBytes.length;\n }\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string} [sParm]\n * @param {string} [sAddr]\n */\n doBreak(sParm, sAddr)\n {\n if (sParm === undefined || sParm == \"?\") {\n this.println(\"\\nbreakpoint commands:\");\n this.println(\"bp [a]\\tset exec breakpoint at [a]\");\n this.println(\"br [a]\\tset read breakpoint at [a]\");\n this.println(\"bw [a]\\tset write breakpoint at [a]\");\n this.println(\"bc [a]\\tclear breakpoint at [a]\");\n this.println(\"bl\\tlist all breakpoints\");\n return;\n }\n if (sAddr === undefined && sParm.length > 1) {\n sAddr = sParm.substr(1);\n sParm = sParm.substr(0, 1);\n }\n if (sParm == \"l\") {\n var cBreaks = 0, i;\n var aAddrs = this.getExecBreakpoints();\n for (i = 0; i < aAddrs.length; i++) {\n this.println(\"breakpoint enabled: \" + Str.toHexWord(aAddrs[i]) + \" (exec)\");\n cBreaks++;\n }\n aAddrs = this.getReadBreakpoints();\n for (i = 0; i < aAddrs.length; i++) {\n this.println(\"breakpoint enabled: \" + Str.toHexWord(aAddrs[i]) + \" (read)\");\n cBreaks++;\n }\n aAddrs = this.getWriteBreakpoints();\n for (i = 0; i < aAddrs.length; i++) {\n this.println(\"breakpoint enabled: \" + Str.toHexWord(aAddrs[i]) + \" (write)\");\n cBreaks++;\n }\n if (!cBreaks)\n this.println(\"no breakpoints\");\n return;\n }\n if (sAddr === undefined) {\n this.println(\"missing breakpoint address\");\n return;\n }\n if (sParm == \"c\" && sAddr == \"*\") {\n this.clearBreakpoints();\n this.println(\"all breakpoints cleared\");\n return;\n }\n var addr = this.getUserAddr(sAddr);\n if (addr === undefined)\n return;\n if (sParm == \"p\") {\n if (this.addExecBreakpoint(addr))\n this.println(\"breakpoint enabled: \" + Str.toHexWord(addr) + \" (exec)\");\n else\n this.println(\"breakpoint not set: \" + Str.toHexWord(addr));\n return;\n }\n if (sParm == \"c\") {\n if (this.findExecBreakpoint(addr, true))\n this.println(\"breakpoint cleared: \" + Str.toHexWord(addr) + \" (exec)\");\n else\n if (this.findReadBreakpoint(addr, true))\n this.println(\"breakpoint cleared: \" + Str.toHexWord(addr) + \" (read)\");\n else\n if (this.findWriteBreakpoint(addr, true))\n this.println(\"breakpoint cleared: \" + Str.toHexWord(addr) + \" (write)\");\n else\n this.println(\"breakpoint missing: \" + Str.toHexWord(addr));\n return;\n }\n if (sParm == \"r\") {\n if (this.addReadBreakpoint(addr))\n this.println(\"breakpoint enabled: \" + Str.toHexWord(addr) + \" (read)\");\n else\n this.println(\"breakpoint not set: \" + Str.toHexWord(addr));\n return;\n }\n if (sParm == \"w\") {\n if (this.addWriteBreakpoint(addr))\n this.println(\"breakpoint enabled: \" + Str.toHexWord(addr) + \" (write)\");\n else\n this.println(\"breakpoint not set: \" + Str.toHexWord(addr));\n return;\n }\n this.println(\"unknown breakpoint command: \" + sParm);\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string} sAddr\n * @param {string} sLen\n */\n doDump(sAddr, sLen)\n {\n if (sAddr == \"?\") {\n this.println(\"\\ndump commands:\");\n this.println(\"d [a] [#] dump # lines of memory\");\n return;\n }\n var addr = this.getUserAddr(sAddr);\n if (addr === undefined)\n return;\n var cLines = 0;\n if (sLen !== undefined) {\n if (sLen.charAt(0) == \"l\")\n sLen = sLen.substr(1);\n cLines = parseInt(sLen, 10);\n }\n if (!cLines) cLines = 1;\n for (var line=0; line < cLines; line++) {\n var sBytes = \"\";\n var sChars = \"\";\n var addrLine = addr;\n for (var i=0; i < 8 && addr < this.offLimit; i++) {\n var b = this.getByte(addr);\n if (b === undefined) b = 0;\n sBytes += Str.toHex(b, 2) + \" \";\n sChars += (b >= 32 && b < 127? String.fromCharCode(b) : \".\");\n addr++;\n }\n this.println(Str.toHex(addrLine, 4) + \" \" + sBytes + sChars);\n }\n this.nextAddr = addr;\n }\n\n /**\n * @this {C1PDebugger}\n * @param {Array.<string>} asArgs\n */\n doEdit(asArgs)\n {\n var sAddr = asArgs[1];\n if (sAddr === undefined) {\n this.println(\"missing address\");\n return;\n }\n var addr = this.getUserAddr(sAddr);\n if (addr === undefined)\n return;\n for (var i=2; i < asArgs.length; i++) {\n var b = parseInt(asArgs[i], 16);\n this.setByte(addr++, b);\n }\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string} sParm\n */\n doFreqs(sParm)\n {\n if (sParm == \"?\") {\n this.println(\"\\nfrequency commands:\");\n this.println(\"clear\\tclear all frequency counts\");\n return;\n }\n var cData = 0, i;\n if (this.aaOpcodeFreqs) {\n if (sParm == \"clear\") {\n for (i = 0; i < this.aaOpcodeFreqs.length; i++)\n this.aaOpcodeFreqs[i] = [i, 0];\n this.println(\"frequency data cleared\");\n cData++;\n }\n else if (sParm !== undefined) {\n this.println(\"unknown frequency command: \" + sParm);\n cData++;\n }\n else {\n var aaSortedOpcodeFreqs = this.aaOpcodeFreqs.slice();\n aaSortedOpcodeFreqs.sort(function(p, q) {return q[1] - p[1];});\n for (i = 0; i < aaSortedOpcodeFreqs.length; i++) {\n var bOpcode = aaSortedOpcodeFreqs[i][0];\n var cFreq = aaSortedOpcodeFreqs[i][1];\n if (cFreq) {\n this.println(this.aOpCodes[this.aaOperations[bOpcode][0]] + \" (\" + Str.toHexByte(bOpcode) + \"): \" + cFreq + \" times\");\n cData++;\n }\n }\n }\n }\n if (!cData) {\n this.println(\"no frequency data available\");\n }\n }\n\n /**\n * @this {C1PDebugger}\n */\n doHalt()\n {\n this.halt();\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string} sCount\n */\n doHistory(sCount)\n {\n var cLines = 10;\n var iHistory = this.iStepHistory;\n var aHistory = this.aStepHistory;\n if (aHistory !== undefined) {\n var n = (sCount === undefined? this.nextHistory : parseInt(sCount, 10));\n if (n === undefined)\n n = 10;\n if (n > aHistory.length) {\n this.println(\"note: only \" + aHistory.length + \" available\");\n n = aHistory.length;\n }\n if (sCount !== undefined) {\n this.nInsHistory = 0;\n this.println(n + \" instructions earlier:\");\n }\n var nIns = (this.nInsHistory? this.nInsHistory : 1);\n iHistory -= n;\n if (iHistory < 0) iHistory = aHistory.length - 1;\n while (cLines && iHistory != this.iStepHistory) {\n var addr = aHistory[iHistory];\n if (addr < 0) break;\n this.println(this.getInstruction(addr, nIns++));\n if (++iHistory == aHistory.length) iHistory = 0;\n cLines--;\n n--;\n }\n this.nextHistory = n;\n this.nInsHistory = nIns;\n }\n if (cLines == 10) this.println(\"no history available\");\n }\n\n /**\n * Prints the contents of the Debugger's \"info\" buffer (filled by calls like cpu.dbg.info())\n * @this {C1PDebugger}\n * @param {string|undefined} sCount\n * @return {boolean|undefined} true only if the \"info\" command is supported\n */\n doInfo(sCount)\n {\n if (DEBUG) {\n var cLines = (sCount === undefined? -1 : parseInt(sCount, 10));\n var i = this.iInfoBuffer;\n do {\n var s = this.aInfoBuffer[i++];\n if (s !== undefined) {\n this.println(s);\n cLines--;\n }\n if (i >= this.aInfoBuffer.length)\n i = 0;\n } while (cLines && i != this.iInfoBuffer);\n this.println(\"nYieldsPerSecond: \" + this.cpu.nYieldsPerSecond);\n this.println(\"msPerYield: \" + this.cpu.msPerYield);\n this.println(\"nCyclesPerBurst: \" + this.cpu.nCyclesPerBurst);\n this.println(\"nCyclesPerYield: \" + this.cpu.nCyclesPerYield);\n this.println(\"nCyclesPerVideoUpdate: \" + this.cpu.nCyclesPerVideoUpdate);\n this.println(\"nCyclesPerStatusUpdate: \" + this.cpu.nCyclesPerStatusUpdate);\n return true;\n }\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string} [sAddr]\n * @param {string} [sAddrEnd]\n * @param {number} [n]\n */\n doUnassemble(sAddr, sAddrEnd, n)\n {\n var addr = this.getUserAddr(sAddr);\n if (addr === undefined)\n return;\n\n if (n === undefined) n = 1;\n var addrEnd = this.offLimit;\n if (sAddrEnd !== undefined) {\n addrEnd = this.getUserAddr(sAddrEnd);\n if (addrEnd === undefined || addrEnd < addr)\n return;\n if (!DEBUG && (addrEnd - addr) > 0x100) {\n /*\n * Limiting the amount of disassembled code to one \"memory page\" in non-DEBUG builds is partly\n * to prevent the user from wedging their browser, but also a recognition that, in non-DEBUG builds,\n * the println() output buffer is truncated to 8K, which is only enough for about two pages of\n * disassembled code anyway.\n */\n this.println(\"range too large\");\n return;\n }\n addrEnd++;\n n = -1;\n }\n\n if (addr != this.nextAddr)\n this.println();\n\n while (n-- && addr < addrEnd) {\n var sIns = this.getInstruction(addr, this.isBusy(false) || this.fStepOver? this.cIns : 0);\n this.println(sIns);\n this.nextAddr = addr = this.nextIns;\n }\n }\n\n /**\n * @this {C1PDebugger}\n * @param {Array.<string>} asArgs\n */\n doOptions(asArgs)\n {\n if (asArgs[1] === undefined || asArgs[1] == \"?\") {\n this.println(\"\\noption commands:\");\n this.println(\"max\\trun at maximum speed\");\n this.println(\"fast\\trun faster (up to \" + this.cpu.mhzFast + \"Mhz)\");\n this.println(\"slow\\trun at normal speed (1Mhz)\");\n this.println(\"classic\\tuse classic operand syntax\");\n this.println(\"modern\\tuse modern operand syntax\");\n this.println(\"msg\\tenable message categories\");\n return;\n }\n var sOption = asArgs[1];\n switch(sOption) {\n case \"slow\":\n this.cpu.setSpeed(this.cpu.SPEED_SLOW);\n break;\n case \"fast\":\n this.cpu.setSpeed(this.cpu.SPEED_FAST);\n break;\n case \"max\":\n this.cpu.setSpeed(this.cpu.SPEED_MAX);\n break;\n case \"classic\":\n this.setOpModes(true);\n this.println(\"classic syntax enabled\");\n break;\n case \"modern\":\n this.setOpModes(false);\n this.println(\"modern syntax enabled\");\n break;\n case \"msg\":\n var bitsMessage = 0;\n if (asArgs[2] !== undefined) {\n if (asArgs[2] == \"all\")\n bitsMessage = 0xff;\n else if (this.aMessageCategories[asArgs[2]] !== undefined)\n bitsMessage = this.aMessageCategories[asArgs[2]];\n if (bitsMessage) {\n if (asArgs[3] == \"on\") {\n this.bitsMessage |= bitsMessage;\n }\n else if (asArgs[3] == \"off\") {\n this.bitsMessage &= ~bitsMessage;\n }\n }\n }\n for (var sCategory in this.aMessageCategories) {\n if (asArgs[2] !== undefined && (asArgs[2] != \"all\" && asArgs[2] != sCategory)) continue;\n bitsMessage = this.aMessageCategories[sCategory];\n this.println(sCategory + \" messages: \" + ((this.bitsMessage & bitsMessage)? \"on\" : \"off\"));\n }\n break;\n default:\n this.println(\"unknown option: \" + sOption);\n break;\n }\n }\n\n /**\n * @this {C1PDebugger}\n * @param {Array.<string>} [asArgs]\n */\n doRegisters(asArgs)\n {\n if (asArgs && asArgs[1] == \"?\") {\n this.println(\"\\nregister commands:\");\n this.println(\"r to display all\");\n this.println(\"r [target=value] to modify\");\n this.println(\"supported targets:\");\n this.println(\"A,X,Y,S,PC and flags C,Z,D,V,N\");\n return;\n }\n var fIns = true;\n if (asArgs !== undefined && asArgs.length > 1) {\n fIns = false;\n var sReg = asArgs[1];\n var sValue = null;\n var i = sReg.indexOf(\"=\");\n if (i > 0) {\n sValue = sReg.substr(i+1);\n sReg = sReg.substr(0, i);\n }\n else if (asArgs.length > 2) {\n sValue = asArgs[2];\n }\n else {\n this.println(\"missing value for \" + asArgs[1]);\n return;\n }\n var b = parseInt(sValue, 16);\n if (!isNaN(b)) {\n switch(sReg.toUpperCase()) {\n case \"A\":\n this.cpu.regA = b & 0xff;\n break;\n case \"X\":\n this.cpu.regX = b & 0xff;\n break;\n case \"Y\":\n this.cpu.regY = b & 0xff;\n break;\n case \"C\":\n if (b) this.cpu.setC(); else this.cpu.clearC();\n break;\n case \"Z\":\n if (b) this.cpu.setZ(); else this.cpu.clearZ();\n break;\n case \"D\":\n if (b) this.cpu.setBCD(); else this.cpu.clearBCD();\n break;\n case \"V\":\n if (b) this.cpu.setV(); else this.cpu.clearV();\n break;\n case \"N\":\n if (b) this.cpu.setN(); else this.cpu.clearN();\n break;\n case \"S\":\n if ((b & ~0xff) != 0x100) {\n this.println(\"invalid stack pointer: \" + sValue);\n return;\n }\n this.cpu.regS = b;\n break;\n case \"PC\":\n fIns = true;\n this.cpu.regPC = b & 0xffff;\n this.nextAddr = this.cpu.regPC;\n break;\n default:\n this.println(\"unknown register: \" + sReg);\n return;\n }\n }\n else {\n this.println(\"invalid value: \" + sValue);\n return;\n }\n this.cpu.update();\n }\n this.println(this.getRegs());\n if (fIns) this.doUnassemble(Str.toHex(this.nextAddr = this.cpu.regPC, 4));\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string} sAddr\n */\n doRun(sAddr)\n {\n if (sAddr !== undefined)\n this.setTempBreakpoint(this.getUserAddr(sAddr));\n if (!this.run()) {\n this.cpu.setFocus();\n }\n }\n\n /**\n * @this {C1PDebugger}\n */\n doStep()\n {\n if (this.getByte(this.cpu.regPC) == this.cpu.OP_JSR) {\n this.setTempBreakpoint(this.cpu.regPC+3);\n this.fStepOver = true;\n if (!this.run())\n this.cpu.setFocus();\n }\n else {\n this.doTrace();\n }\n }\n\n /**\n * @this {C1PDebugger}\n * @param {string} [sCount]\n */\n doTrace(sCount)\n {\n var c = (sCount === undefined? 1 : parseInt(sCount, 10));\n var n = (c == 1? 0 : 1);\n Web.onCountRepeat(\n c,\n function(dbg) {\n return function() {\n return dbg.setBusy(true) && dbg.step(n);\n };\n }(this),\n function(dbg) {\n return function() {\n dbg.setBusy(false);\n };\n }(this)\n );\n }\n\n static input(dbg, sCmd)\n {\n if (!sCmd.length) {\n if (dbg.fAssemble) {\n dbg.println(\"ended assemble @\" + Str.toHex(dbg.addrAssembleNext, 4));\n dbg.nextAddr = dbg.addrAssembleNext;\n dbg.fAssemble = false;\n }\n else\n if (dbg.prevCmd)\n sCmd = dbg.prevCmd;\n }\n if (dbg.isReady() && !dbg.isBusy(true) && sCmd.length > 0) {\n\n if (dbg.fAssemble) {\n sCmd = \"a \" + Str.toHex(dbg.addrAssembleNext, 4) + \" \" + sCmd;\n }\n else if (sCmd.length > 1 && sCmd.indexOf(\" \") != 1) {\n /*\n * For certain commands lacking a space after the first character,\n * insert an automatic space, so that split(\" \") has the desired effect.\n */\n var ch = sCmd.charAt(0).toLowerCase();\n sCmd = ch + \" \" + sCmd.substr(1);\n }\n\n var asArgs = sCmd.split(\" \");\n dbg.prevCmd = asArgs[0];\n\n switch(asArgs[0].toLowerCase()) {\n case \"a\":\n dbg.doAssemble(asArgs);\n break;\n case \"b\":\n dbg.doBreak(asArgs[1], asArgs[2]);\n break;\n case \"d\":\n dbg.doDump(asArgs[1], asArgs[2]);\n break;\n case \"e\":\n dbg.doEdit(asArgs);\n break;\n case \"f\":\n dbg.doFreqs(asArgs[1]);\n break;\n case \"g\":\n dbg.doRun(asArgs[1]);\n break;\n case \"h\":\n dbg.doHalt();\n break;\n case \"o\":\n dbg.doOptions(asArgs);\n break;\n case \"p\":\n dbg.doHistory(asArgs[1]);\n break;\n case \"r\":\n dbg.doRegisters(asArgs);\n break;\n case \"s\":\n dbg.doStep();\n break;\n case \"t\":\n dbg.doTrace(asArgs[1]);\n break;\n case \"u\":\n dbg.doUnassemble(asArgs[1], asArgs[2], 8);\n break;\n case \"?\":\n case \"help\":\n dbg.doHelp();\n break;\n case \"i\":\n if (dbg.doInfo(asArgs[1])) break;\n /* falls through */\n default:\n dbg.println(\"unknown command: \" + sCmd);\n break;\n }\n }\n }\n\n /**\n * C1PDebugger.init()\n *\n * This function operates on every HTML element of class \"debugger\", extracting the\n * JSON-encoded parameters for the C1PDebugger constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a C1PDebugger component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeDbg = Component.getElementsByClass(document, C1PJS.APPCLASS, \"debugger\");\n for (var iDbg=0; iDbg < aeDbg.length; iDbg++) {\n var eDbg = aeDbg[iDbg];\n var parmsDbg = Component.getComponentParms(eDbg);\n var dbg = new C1PDebugger(parmsDbg);\n Component.bindComponentControls(dbg, eDbg, C1PJS.APPCLASS);\n }\n }\n}\n\nif (DEBUGGER) {\n\n /*\n * Initialize every Debugger module on the page (as IF there's ever going to be more than one ;-))\n */\n Web.onInit(C1PDebugger.init);\n\n} // endif DEBUGGER\n\n/**\n * @copyright https://www.pcjs.org/modules/c1pjs/lib/computer.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass C1PComputer extends Component {\n /**\n * C1PComputer(parmsComputer, modules)\n *\n * The C1PComputer component expects the following (parmsComputer) properties:\n *\n * modules[{}] (from the <module> definition(s) for the computer)\n *\n * This component processes all the <module> \"start\" and \"end\" specifications\n * and \"wires\" everything to a common \"address buffer\"; namely, the abMemory array.\n * abMemory encompasses the computer's entire address space, but every component must\n * play nice and use only its assigned section of abMemory -- and pretend it's an array\n * of bytes, when in fact it's an array of floating-point values (the only primitive\n * numeric data type that JavaScript provides).\n *\n * This component also insures that all the other components are ready; in particular,\n * this means that the ROM and Video components have finished loading their resources\n * and are ready for operation. Other components become ready as soon as we call their\n * setBuffer() method (eg, CPU, RAM, Keyboard, Debugger, SerialPort, DiskController), and\n * others, like Panel, become ready even earlier, at the end of their initialization.\n *\n * Once every component has indicated it's ready, we call its setPower() notification\n * function (if it has one; it's optional). We call the CPU's setPower() function last,\n * so that the CPU is assured that all other components are ready and \"powered\".\n *\n * @this {C1PComputer}\n * @param {Object} parmsComputer\n * @param {Object} modules\n */\n constructor(parmsComputer, modules)\n {\n super(\"C1PComputer\", parmsComputer);\n\n this.modules = modules;\n }\n\n /**\n * reset(fPowerOn)\n *\n * @this {C1PComputer}\n * @param {boolean} [fPowerOn] is true to indicate that we should start the CPU running\n */\n reset(fPowerOn)\n {\n var cpu = null;\n for (var sType in this.modules) {\n for (var i=0; i < this.modules[sType].length; i++) {\n var component = this.modules[sType][i];\n if (component && component.reset) {\n if (DEBUG) this.println(\"resetting \" + sType);\n component.reset();\n if (sType == \"cpu\") cpu = component;\n }\n }\n }\n if (cpu) {\n cpu.update();\n if (fPowerOn) cpu.run();\n }\n }\n\n /**\n * start()\n *\n * Called by the CPU to notify all component start() handlers.\n *\n * @this {C1PComputer}\n */\n start()\n {\n for (var sType in this.modules) {\n if (sType == \"cpu\") continue;\n for (var i=0; i < this.modules[sType].length; i++) {\n var component = this.modules[sType][i];\n if (component && component.start) {\n component.start();\n }\n }\n }\n }\n\n /**\n * stop(msStart, nCycles)\n *\n * Called by the CPU to notify all component stop() handlers\n *\n * @this {C1PComputer}\n * @param {number} msStart\n * @param {number} nCycles\n */\n stop(msStart, nCycles)\n {\n for (var sType in this.modules) {\n if (sType == \"cpu\") continue;\n for (var i=0; i < this.modules[sType].length; i++) {\n var component = this.modules[sType][i];\n if (component && component.stop) {\n component.stop(msStart, nCycles);\n }\n }\n }\n }\n\n /**\n * @this {C1PComputer}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n switch(sBinding) {\n case \"reset\":\n this.bindings[sBinding] = control;\n control.onclick = function(computer) {\n return function() {\n computer.reset();\n };\n }(this);\n return true;\n default:\n break;\n }\n return false;\n }\n\n /**\n * NOTE: If there are multiple components for a given type, we may need to provide a means of discriminating.\n *\n * @this {C1PComputer}\n * @param {string} sType\n * @param {string} [idRelated] of related component\n * @param {Component|null} [componentPrev] of previously returned component, if any\n * @return {Component|null}\n */\n getComponentByType(sType, idRelated, componentPrev)\n {\n if (this.modules[sType]) {\n return this.modules[sType][0];\n }\n return null;\n }\n\n static power(computer)\n {\n /*\n * Insure that the ROMs, Video and CPU are all ready before \"powering\" everything; always \"power\"\n * the CPU last, to make sure it doesn't start asking other components to do things before they're ready.\n */\n var cpu = null;\n for (var sType in computer.modules) {\n for (var i=0; i < computer.modules[sType].length; i++) {\n var component = computer.modules[sType][i];\n if (!component) continue;\n if (!component.isReady()) {\n component.isReady(function(computer) {\n return function() {\n C1PComputer.power(computer);\n };\n }(computer)); // jshint ignore:line\n return;\n }\n /*\n * The CPU component's setPower() notification handler is a special case: we don't want\n * to call it until the end (below), after all others have been called.\n */\n if (sType == \"cpu\")\n cpu = component;\n else if (component.setPower) {\n component.setPower(true, computer);\n }\n }\n }\n\n /*\n * The entire computer is finally ready; we call our own setReady() for completeness, not because any\n * other component actually cares when we're ready.\n */\n computer.setReady();\n\n computer.println(C1PJS.APPNAME + \" v\" + C1PJS.APPVERSION + \"\\n\" + COPYRIGHT);\n\n /*\n * Once we get to this point, we're guaranteed that all components are ready, so it's safe to \"power\" the CPU;\n * setPower() includes an automatic reset(fPowerOn), so the CPU should begin executing immediately, unless a debugger\n * is attached.\n */\n if (cpu) cpu.setPower(true, computer);\n }\n\n /*\n * C1PComputer.init()\n *\n * This function operates on every HTML element of class \"c1pjs-computer\", extracting the\n * JSON-encoded parameters for the C1PComputer constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a C1PComputer component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n /*\n * In non-COMPILED builds, embedMachine() may have set XMLVERSION.\n */\n if (!COMPILED && XMLVERSION) C1PJS.APPVERSION = XMLVERSION;\n\n var aeComputers = Component.getElementsByClass(document, C1PJS.APPCLASS, \"computer\");\n\n for (var iComputer=0; iComputer < aeComputers.length; iComputer++) {\n\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n\n var component;\n var modules = {};\n\n var abMemory;\n var addrStart = 0, addrEnd = 0;\n\n for (var iAddr=0; iAddr < parmsComputer['modules'].length; iAddr++) {\n var addrInfo = parmsComputer['modules'][iAddr];\n /*\n * The first address range (ie, the CPU range) must specify the range for the entire\n * address space (abMemory), which we allocate and zero-initialize.\n *\n * NOTE: We might consider doing what the Video component does on first reset: initializing\n * the entire memory buffer to random values. However, a constant (eg, 0xA5) might be\n * more useful, acting as a crude indicator of memory the client code hasn't written yet.\n */\n if (!iAddr) {\n if (addrInfo['type'] != \"cpu\") break;\n addrStart = addrInfo['start'];\n addrEnd = addrInfo['end'];\n abMemory = new Array(addrEnd+1 - addrStart);\n for (var addr=addrStart; addr < abMemory.length; addr++) {\n abMemory[addr] = 0;\n }\n }\n component = Component.getComponentByID(addrInfo['refID'], parmsComputer['id']);\n if (component) {\n var sType = addrInfo['type'];\n if (modules[sType] === undefined)\n modules[sType] = [];\n modules[sType].push(component);\n if (component.setBuffer && addrInfo['start'] !== undefined) {\n component.setBuffer(abMemory, addrInfo['start'], addrInfo['end'], modules['cpu'][0]);\n }\n }\n else {\n Component.error(\"no component for <module refid=\\\"\" + addrInfo['refID'] + \"\\\">\");\n return;\n }\n }\n\n if (abMemory === undefined) {\n Component.error(\"<module type=\\\"cpu\\\"> definition must appear first in the <computer> specification\");\n return;\n }\n\n /*\n * Let's see if the Debugger is installed (NOTE: its ID must be \"debugger\", and only one per machine is supported);\n * the Debugger needs our setBuffer(), setPower() and reset() notifications, and this relieves us from having an explicit\n * <module> entry for type=\"debugger\".\n */\n component = Component.getComponentByID('debugger', parmsComputer['id']);\n if (component) {\n modules['debugger'] = [component];\n if (component.setBuffer) {\n component.setBuffer(abMemory, addrStart, addrEnd, modules['cpu'][0]);\n }\n }\n\n var computer = new C1PComputer(parmsComputer, modules);\n\n /*\n * Let's see if the Control Panel is installed (NOTE: its ID must be \"panel\", and only one per machine is supported);\n * the Panel needs our setPower() notifications, and this relieves us from having an explicit <module> entry for type=\"panel\".\n */\n var panel = Component.getComponentByID('panel', parmsComputer['id']);\n if (panel) {\n modules['panel'] = [panel];\n /*\n * Iterate through all the other components and update their print methods if the Control Panel has provided overrides.\n */\n var controlPrint = panel.bindings['print'];\n if (controlPrint) {\n var aComponents = Component.getComponents(parmsComputer['id']);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component == panel) continue;\n component.notice = panel.notice;\n component.print = panel.print;\n component.println = panel.println;\n }\n }\n }\n\n /*\n * We may eventually add a \"Power\" button, but for now, all we have is a \"Reset\" button\n */\n Component.bindComponentControls(computer, eComputer, C1PJS.APPCLASS);\n\n /*\n * \"Power\" the computer automatically\n */\n C1PComputer.power(computer);\n }\n }\n}\n\n/*\n * Initialize every Computer on the page.\n */\nWeb.onInit(C1PComputer.init);\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/embed.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * We now support asynchronous XML and XSL file loads; simply set fAsync (below) to true.\n *\n * NOTE: For that support to work, we have to keep track of the number of machines on the page\n * (ie, how many embedMachine() calls were issued), reduce the count as each machine XML file\n * is fully transformed into HTML, and when the count finally returns to zero, notify all the\n * machine component init() handlers.\n *\n * Also, to prevent those init() handlers from running prematurely, we must disable all page\n * notification events at the start of the embedding process (Web.enablePageEvents(false)) and\n * re-enable them at the end (Web.enablePageEvents(true)).\n */\nvar fAsync = true;\nvar cAsyncMachines = 0;\n\n/**\n * loadXML(sFile, idMachine, sAppName, sAppClass, sParms, fResolve, display, done)\n *\n * This is the preferred way to load all XML and XSL files. It uses getResource()\n * to load them as strings, which parseXML() can massage before parsing/transforming them.\n *\n * For example, since I've been unable to get the XSLT document() function to work inside any\n * XSL document loaded by JavaScript's XSLT processor, that has prevented me from dynamically\n * loading any XML machine file that uses the \"ref\" attribute to refer to and incorporate\n * another XML document.\n *\n * To solve that, I've added an fResolve parameter that tells parseXML() to fetch any\n * referenced documents ITSELF and insert them into the XML string prior to parsing, instead\n * of relying on the XSLT template to pull them in. That fetching is handled by resolveXML(),\n * which iterates over the XML until all \"refs\" have been resolved (including any nested\n * references).\n *\n * Also, XSL files with a <!DOCTYPE [...]> cause MSIE's Microsoft.XMLDOM.loadXML() function\n * to choke, so I strip that out prior to parsing as well.\n *\n * TODO: Figure out why the XSLT document() function works great when the web browser loads an\n * XML file (and the associated XSL file) itself, but does not work when loading documents via\n * JavaScript XSLT support. Is it broken, is it a security issue, or am I just calling it wrong?\n *\n * @param {string} sXMLFile\n * @param {string|null|undefined} idMachine\n * @param {string|null|undefined} sAppName\n * @param {string|null|undefined} sAppClass\n * @param {string|null|undefined} sParms (machine parameters, if any)\n * @param {string|null|undefined} sClass (an optional machine class name used to style the machine)\n * @param {boolean} fResolve is true to resolve any \"ref\" attributes\n * @param {function(string)} display\n * @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)\n */\nfunction loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n{\n var doneLoadXML = function(sURLName, sXML, nErrorCode) {\n if (nErrorCode) {\n if (!sXML) sXML = \"unable to load \" + sXMLFile + \" (\" + nErrorCode + \")\";\n done(sXML, null);\n return;\n }\n parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done);\n };\n display(\"Loading \" + sXMLFile + \"...\");\n Web.getResource(sXMLFile, null, fAsync, doneLoadXML);\n}\n\n/**\n * parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n *\n * Generates an XML document from an XML string. This function also provides a work-around for XSLT's\n * lack of support for the document() function (at least on some browsers), by replacing every reference\n * tag (ie, a tag with a \"ref\" attribute) with the contents of the referenced file.\n *\n * @param {string} sXML\n * @param {string|null} sXMLFile\n * @param {string|null|undefined} idMachine\n * @param {string|null|undefined} sAppName\n * @param {string|null|undefined} sAppClass\n * @param {string|null|undefined} sParms (machine parameters, if any)\n * @param {string|null|undefined} sClass (an optional machine class name used to style the machine)\n * @param {boolean} fResolve is true to resolve any \"ref\" attributes; default is false\n * @param {function(string)} display\n * @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)\n */\nfunction parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n{\n var buildXML = function(sXML, sError) {\n if (sError) {\n done(sError, null);\n return;\n }\n if (idMachine) {\n\n /*\n * A more sensible place to record the machine XML would be embedMachine(), like we do for the\n * XSL file, but since we're about to modify the original machine XML, it's best to record it now.\n */\n Component.addMachineResource(idMachine, sXMLFile, sXML);\n\n var sURL = sXMLFile;\n if (sURL && sURL.indexOf('/') < 0 && window.location.pathname.slice(-1) == '/') {\n sURL = window.location.pathname + sURL;\n }\n /*\n * We embed the URL of the XML file both as a separate \"xml\" attribute for easy access from the\n * XSL file, and as part of the \"parms\" attribute for easy access from machines (see getMachineParm()).\n */\n if (!sParms) {\n sParms = '{';\n } else if (sParms.slice(-1) == '}') {\n sParms = sParms.slice(0, -1);\n if (sParms.length > 1) sParms += ',';\n } else { // sParms must just be a \"state\" file, so encode it as a \"state\" property\n sParms = '{state:\"' + sParms + '\",';\n }\n sParms += 'url:\"' + sURL + '\"}';\n /*\n * Note that while we no longer generate a machine XML file with a \"state\" attribute (because it's\n * encoded inside the \"parms\" attribute), the XSL file must still cope with \"state\" attributes inside\n * other XML files; for example, manifest XML files like /apps/pcx86/1981/visicalc/manifest.xml contain\n * machine elements with \"state\" attributes that must still be passed down to the computer element\n * \"the old fashioned way\".\n *\n * Until/unless that changes, components.xsl cannot be simplified as much as I might have hoped.\n */\n if (typeof resources == 'object') sURL = null; // turn off URL inclusion if we have embedded resources\n sParms = sParms.replace(/\\$/g, \"$$$$\");\n if (sClass) {\n /*\n * If there's no hard-coded \"class\" attribute in the machine tag, then we can set one in the final\n * replacement below, just like we do for sParms and sURL. However, if a \"class\" attribute already\n * exists, we need alter it and then zap the sClass variable.\n */\n var match = sXML.match(/(<machine[^>]*\\sclass=)(['\"])(.*?)(\\2.*?>)/);\n if (match) {\n sXML = sXML.replace(match[0], match[1] + match[2] + sClass + match[4]);\n sClass = null;\n }\n }\n sXML = sXML.replace(/(<machine[^>]*\\sid=)(['\"]).*?\\2/, \"$1$2\" + idMachine + \"$2\" + (sClass? ' class=\"' + sClass + '\"' : '') + (sParms? \" parms='\" + sParms + \"'\" : \"\") + (sURL? ' url=\"' + sURL + '\"' : ''));\n }\n\n if (!fResolve) {\n /*\n * I'm trying to switch to a shared components.xsl (at least for all PC-class machines),\n * but in the interim, that means hacking the XSL file on the fly to reflect the actual class.\n */\n sXML = sXML.replace(/(<xsl:variable name=\"APPNAME\">).*?(<\\/xsl:variable>)/, \"$1\" + sAppName + \"$2\");\n sXML = sXML.replace(/(<xsl:variable name=\"APPCLASS\">).*?(<\\/xsl:variable>)/, \"$1\" + sAppClass + \"$2\");\n\n /*\n * Non-COMPILED kludge to replace the version number template in the XSL file (which we assume we're reading,\n * since fResolve is false) with whatever XMLVERSION we extracted from the XML file (see corresponding kludge below).\n *\n * ES6 ALERT: Template strings.\n */\n if (!COMPILED && XMLVERSION) {\n sXML = sXML.replace(/<xsl:variable name=\"APPVERSION\"\\/>/, `<xsl:variable name=\"APPVERSION\">${XMLVERSION}</xsl:variable>`);\n }\n }\n\n /*\n * If the resource we requested is not really an XML file (or the file didn't exist and the server simply returned\n * a message like \"Cannot GET /devices/pc/machine/5150/cga/64kb/donkey/machine.xml\"), we'd like to display a more\n * meaningful message, because the XML DOM parsers will blithely return a document that contains nothing useful; eg:\n *\n * This page contains the following errors:error on line 1 at column 1:\n * Document is empty Below is a rendering of the page up to the first error.\n *\n * Supposedly, the IE XML DOM parser will throw an exception, but I haven't tested that, and unless all other\n * browsers do that, that's not helpful.\n *\n * The best I can do at this stage (assuming Web.getResource() didn't drop any error information on the floor)\n * is verify that the requested resource \"looks like\" valid XML (in other words, it begins with a '<').\n */\n var xmlDoc = null;\n if (sXML.charAt(0) == '<') {\n try {\n /*\n * Another hack for MSIE, which fails to load XSL documents containing a <!DOCTYPE [...]> tag.\n *\n * This is also why the XSLTProcessor 'transformToFragment' method in Microsoft Edge silently failed,\n * so I had pull this hack out of the \"ActiveXObject\" code. And rather than add yet-another Microsoft\n * browser check, I'm going to try doing this across the board, and hope that none of the other XSLT\n * processors fail *without* the DOCTYPE tag.\n */\n if (!fResolve) {\n sXML = sXML.replace(/<!DOCTYPE(.|[\\r\\n])*]>\\s*/g, \"\");\n }\n /*\n * Beginning with Microsoft Edge and the corresponding release of Windows 10, all the\n * 'ActiveXObject' crud has gone away; but of course, this code must remain in place if\n * we want to continue supporting older Internet Explorer browsers (ie, back to IE9).\n */\n /** @namespace window.ActiveXObject */\n if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1\n xmlDoc = new window.ActiveXObject(\"Microsoft.XMLDOM\");\n xmlDoc.async = false;\n xmlDoc['loadXML'](sXML);\n } else {\n /** @namespace window.DOMParser */\n xmlDoc = (new window.DOMParser()).parseFromString(sXML, \"text/xml\");\n }\n } catch(e) {\n xmlDoc = null;\n sXML = e.message;\n }\n } else {\n sXML = \"unrecognized XML: \" + (sXML.length > 255? sXML.substr(0, 255) + \"...\" : sXML);\n }\n done(sXML, xmlDoc);\n };\n if (sXML) {\n if (PRIVATE) sXML = sXML.replace(/\\/library.xml/, \"/private/library.xml\");\n if (fResolve) {\n resolveXML(sXML, display, buildXML);\n return;\n }\n buildXML(sXML, null);\n return;\n }\n done(\"no data\" + (sXMLFile? \" for file: \" + sXMLFile : \"\"), null);\n}\n\n/**\n * resolveXML(sXML, display, done)\n *\n * Replaces every tag with a \"ref\" attribute with the contents of the corresponding file.\n *\n * TODO: Fix some of the limitations of this code, such as: 1) requiring the \"ref\" attribute\n * to appear as the tag's first attribute, 2) requiring the \"ref\" attribute to be double-quoted,\n * and 3) requiring the \"ref\" tag to be self-closing.\n *\n * @param {string} sXML\n * @param {function(string)} display\n * @param {function(string,(string|null))} done (the first string contains the resolved XML data, the second is for any error message)\n */\nfunction resolveXML(sXML, display, done)\n{\n var matchRef;\n var reRef = /<([a-z]+)\\s+ref=\"(.*?)\"(.*?)\\/>/g;\n\n if ((matchRef = reRef.exec(sXML))) {\n\n var sRefFile = matchRef[2];\n\n var doneReadXML = function(sURLName, sXMLRef, nErrorCode) {\n if (nErrorCode || !sXMLRef) {\n done(sXML, \"unable to resolve XML reference: \" + matchRef[0] + \" (\" + nErrorCode + \")\");\n return;\n }\n /*\n * If there are additional attributes in the \"referring\" XML tag, we want to insert them\n * into the \"referred\" XML tag; attributes that don't exist in the referred tag should be\n * appended, and attributes that DO exist should be overwritten.\n */\n var sRefAttrs = matchRef[3];\n if (sRefAttrs) {\n var aXMLRefTag = sXMLRef.match(new RegExp(\"<\" + matchRef[1] + \"[^>]*>\"));\n if (aXMLRefTag) {\n var sXMLNewTag = aXMLRefTag[0];\n /*\n * Iterate over all the attributes in the \"referring\" XML tag (sRefAttrs)\n */\n var matchAttr;\n var reAttr = /( [a-z]+=)(['\"])(.*?)\\2/gi;\n while ((matchAttr = reAttr.exec(sRefAttrs))) {\n if (sXMLNewTag.toLowerCase().indexOf(matchAttr[1].toLowerCase()) < 0) {\n /*\n * This is the append case....\n */\n sXMLNewTag = sXMLNewTag.replace(\">\", matchAttr[0] + \">\");\n } else {\n /*\n * This is the overwrite case....\n */\n sXMLNewTag = sXMLNewTag.replace(new RegExp(matchAttr[1] + \"(['\\\"])(.*?)\\\\1\"), matchAttr[0]);\n }\n }\n if (aXMLRefTag[0] != sXMLNewTag) {\n sXMLRef = sXMLRef.replace(aXMLRefTag[0], sXMLNewTag);\n }\n } else {\n done(sXML, \"missing <\" + matchRef[1] + \"> in \" + sRefFile);\n return;\n }\n }\n\n /*\n * Apparently when a Windows Azure server delivers one of my XML files, it may modify the first line:\n *\n * <?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n\n *\n * I didn't determine exactly what it was doing at this point (probably just changing the \\n to \\r\\n),\n * but in any case, relaxing the following replace() solved it.\n */\n sXMLRef = sXMLRef.replace(/<\\?xml[^>]*>[\\r\\n]*/, \"\");\n\n sXML = sXML.replace(matchRef[0], sXMLRef);\n\n resolveXML(sXML, display, done);\n };\n\n display(\"Loading \" + sRefFile + \"...\");\n Web.getResource(sRefFile, null, fAsync, doneReadXML);\n return;\n }\n done(sXML, null);\n}\n\n/**\n * embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * This allows to you embed a machine on a web page, by transforming the machine XML into HTML.\n *\n * @param {string} sAppName is the app name (eg, \"PCx86\")\n * @param {string} sAppClass is the app class (eg, \"pcx86\"); also known as the machine class\n * @param {string} sVersion is the app version (eg, \"1.15.7\")\n * @param {string} idMachine\n * @param {string|undefined} sXMLFile\n * @param {string|undefined} sXSLFile\n * @param {string|undefined} sParms (machine parameters, if any)\n * @param {string|undefined} sClass (an optional machine class name used to style the machine)\n * @return {boolean} true if successful, false if error\n */\nfunction embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n var eMachine, eWarning, fSuccess = true;\n\n if (!sXMLFile) {\n sXMLFile = \"machine.xml\";\n if (!sXSLFile) sXSLFile = \"components.xsl\";\n }\n \n cAsyncMachines++;\n Component.addMachine(idMachine);\n\n var doneMachine = function() {\n\n if (!--cAsyncMachines) {\n if (fAsync) Web.enablePageEvents(true);\n }\n };\n\n var displayError = function(sError) {\n Component.log(sError);\n displayMessage(\"Error: \" + sError);\n if (fSuccess) doneMachine();\n fSuccess = false;\n };\n\n var displayMessage = function(sMessage) {\n if (eWarning === undefined) {\n /*\n * Our MarkOut module (in convertMDMachineLinks()) creates machine containers that look like:\n *\n * <div id=\"' + sMachineID + '\" class=\"machine-placeholder\"><p>Embedded PC</p><p class=\"machine-warning\">...</p></div>\n *\n * with the \"machine-warning\" paragraph pre-populated with a warning message that the user will\n * see if nothing at all happens. But hopefully, in the normal case (and especially the error case),\n * *something* will have happened.\n *\n * Note that it is the HTMLOut module (in processMachines()) that ultimately decides which scripts to\n * include and then generates the embedXXX() call.\n */\n var aeWarning = (eMachine && Component.getElementsByClass(eMachine, \"machine-warning\"));\n eWarning = (aeWarning && aeWarning[0]) || eMachine;\n }\n if (eWarning) eWarning.innerHTML = Str.escapeHTML(sMessage);\n };\n\n try {\n eMachine = document.getElementById(idMachine);\n if (eMachine) {\n\n /*\n * If we have a 'css' resource, add it to the page first.\n */\n var css;\n if (typeof resources == \"object\" && (css = resources['css'])) {\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n // noinspection JSDeprecatedSymbols\n if (style.styleSheet) {\n // noinspection JSDeprecatedSymbols\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n head.appendChild(style);\n }\n\n if (!sXSLFile) {\n /*\n * Now that PCjs is an open-source project, we can make the following test more flexible,\n * and revert to the internal template if DEBUG *or* internal version (instead of *and*).\n *\n * Third-party sites that don't use the PCjs server will ALWAYS want to specify a fully-qualified\n * path to the XSL file, unless they choose to mirror our folder structure.\n */\n var sAppFolder = sAppClass;\n if (DEBUG || !sVersion) {\n if (sAppClass != \"c1pjs\") sAppFolder = \"shared\";\n sXSLFile = \"/modules/\" + sAppFolder + \"/templates/components.xsl\";\n } else {\n if (sAppClass.substr(0, 3) == \"pdp\") sAppFolder = \"pdpjs\";\n sXSLFile = \"/versions/\" + sAppFolder + \"/\" + sVersion + \"/components.xsl\";\n }\n }\n\n var processXML = function(sXML, xml) {\n if (!xml) {\n displayError(sXML);\n return;\n }\n\n /*\n * Non-COMPILED kludge to extract the version number from the stylesheet path in the machine XML file;\n * we don't need this code in COMPILED (non-DEBUG) releases, because APPVERSION is hard-coded into them.\n */\n if (!COMPILED) {\n var aMatch = sXML.match(/<\\?xml-stylesheet[^>]* href=(['\"])[^'\"]*?\\/([0-9.]*)\\/([^'\"]*)\\1/);\n if (aMatch) {\n XMLVERSION = aMatch[2];\n }\n }\n\n var transformXML = function(sXSL, xsl) {\n if (!xsl) {\n displayError(sXSL);\n return;\n }\n\n /*\n * Record the XSL file, in case someone wants to save the entire machine later.\n * \n * NOTE: sXSLFile will never be undefined by this point, but apparently the Closure Compiler doesn't realize that. \n */\n Component.addMachineResource(idMachine, sXSLFile || \"\", sXSL);\n\n /*\n * The <machine> template in components.xsl now generates a \"machine div\" that makes\n * the div we required the caller of embedMachine() to provide redundant, so instead\n * of appending this fragment to the caller's node, we REPLACE the caller's node.\n * This works only because because we ALSO inject the caller's \"machine div\" ID into\n * the fragment's ID during parseXML().\n *\n * eMachine.innerHTML = sFragment;\n *\n * Also, if the transform function fails, make sure you're using the appropriate\n * \"components.xsl\" and not a \"machine.xsl\", because the latter will not produce valid\n * embeddable HTML (and is the most common cause of failure at this final stage).\n */\n displayMessage(\"Processing \" + sXMLFile + \"...\");\n\n /*\n * Beginning with Microsoft Edge and the corresponding release of Windows 10, all the\n * 'ActiveXObject' crud has gone away; but of course, this code must remain in place if\n * we want to continue supporting older Internet Explorer browsers (ie, back to IE9).\n */\n if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1\n var sFragment = xml['transformNode'](xsl);\n if (sFragment) {\n eMachine.outerHTML = sFragment;\n doneMachine();\n } else {\n displayError(\"transformNodeToObject failed\");\n }\n }\n else if (document.implementation && document.implementation.createDocument) {\n var xsltProcessor = new XSLTProcessor();\n xsltProcessor['importStylesheet'](xsl);\n var eFragment = xsltProcessor['transformToFragment'](xml, document);\n if (eFragment) {\n /*\n * This fails in Microsoft Edge...\n *\n var machine = eFragment.getElementById(idMachine);\n if (!machine) {\n displayError(\"machine generation failed: \" + idMachine);\n } else\n */\n if (eMachine.parentNode) {\n eMachine.parentNode.replaceChild(eFragment, eMachine);\n doneMachine();\n } else {\n /*\n * NOTE: This error can occur if our Node web server, when processing a folder with\n * both a manifest.xml with a machine.xml reference AND a README.md containing a\n * machine link, generates duplicate embedXXX() calls for the same machine; if the\n * first embedXXX() call finds its target, subsequent calls for the same target will\n * fail.\n *\n * Technically, such a folder is in a misconfigured state, but it happens, in part\n * because when we switched to the Jekyll web server, we had to add machine links to\n * all README.md files where we had previously relied on manifest.xml or machine.xml\n * processing. This is because the Jekyll web server currently doesn't process XML\n * files, nor is support for that likely to be added any time soon; it was a nice\n * feature of the Node web server, but it's not clear that it's worth doing for Jekyll.\n */\n displayError(\"invalid machine element: \" + idMachine);\n }\n } else {\n displayError(\"transformToFragment failed\");\n }\n } else {\n /*\n * Perhaps I should have performed this test at the outset; on the other hand, I'm\n * not aware of any browsers don't support one or both of the above XSLT transformation\n * methods, so treat this as a bug.\n */\n displayError(\"unable to transform XML: unsupported browser\");\n }\n };\n /*\n * NOTE: sXSLFile will never be undefined by this point, but apparently the Closure Compiler doesn't realize that. \n */\n loadXML(sXSLFile || \"\", null, sAppName, sAppClass, null, null, false, displayMessage, transformXML);\n };\n\n if (sXMLFile.charAt(0) != '<') {\n loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, true, displayMessage, processXML);\n } else {\n parseXML(sXMLFile, null, idMachine, sAppName, sAppClass, sParms, sClass, false, displayMessage, processXML);\n }\n } else {\n displayError(\"missing machine element: \" + idMachine);\n }\n } catch(e) {\n displayError(e.message);\n }\n return fSuccess;\n}\n\n/**\n * embedC1P(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedC1P(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"C1Pjs\", \"c1pjs\", APPVERSION, idMachine, sXMLFile, sXSLFile, undefined, sClass);\n}\n\n/**\n * embedPCx86(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPCx86(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PCx86\", \"pcx86\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPC8080(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPC8080(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PC8080\", \"pc8080\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPDP10(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPDP10(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PDPjs\", \"pdp10\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPDP11(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPDP11(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PDPjs\", \"pdp11\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * findMachineComponent(idMachine, sType)\n *\n * @param {string} idMachine\n * @param {string} sType\n * @return {Component|null}\n */\nfunction findMachineComponent(idMachine, sType)\n{\n return Component.getComponentByType(sType, idMachine + \".machine\");\n}\n\n/**\n * commandMachine(control, fSingle, idMachine, sComponent, sCommand, sValue)\n *\n * Use Component methods to find the requested component for a specific machine, and if the component is found,\n * then check its 'exports' table for an entry matching the specified command string, and if an entry is found, then\n * the corresponding function is called with the specified data.\n *\n * @param {Object} control\n * @param {boolean} fSingle\n * @param {string} idMachine\n * @param {string} sComponent\n * @param {string} sCommand\n * @param {string} [sValue]\n * @return {boolean}\n */\nfunction commandMachine(control, fSingle, idMachine, sComponent, sCommand, sValue)\n{\n if (sCommand == \"script\") {\n if (Component.processScript(idMachine, sValue)) {\n if (fSingle) control.disabled = true;\n return true;\n }\n return false;\n }\n if (sComponent) {\n var component = Component.getComponentByType(sComponent, idMachine + \".machine\");\n if (component) {\n var exports = component['exports'];\n if (exports) {\n var fnCommand = exports[sCommand];\n if (fnCommand) {\n if (fnCommand.call(component, sValue)) {\n if (fSingle) control.disabled = true;\n return true;\n }\n return false;\n }\n }\n }\n }\n console.log(\"unimplemented: commandMachine('\" + idMachine + \"','\" + sComponent + \"','\" + sCommand + \"','\" + sValue + \"')\");\n return false;\n}\n\n/**\n * Prevent the Closure Compiler from renaming functions we want to export, by adding them as global properties.\n *\n * TODO: Consider making all these functions properties on a single global object (eg, 'PCjs'), to minimize global\n * pollution and risk of name collision.\n */\nif (APPNAME == \"C1Pjs\") {\n window['embedC1P'] = embedC1P;\n}\nif (APPNAME == \"PCx86\") {\n window['embedPC'] = embedPCx86; // WARNING: embedPC() deprecated as of v1.23.0\n window['embedPCx86'] = embedPCx86;\n}\nif (APPNAME == \"PC8080\") {\n window['embedPC8080'] = embedPC8080;\n}\nif (APPNAME == \"PDPjs\") {\n window['embedPDP10'] = embedPDP10;\n window['embedPDP11'] = embedPDP11;\n}\n\nwindow['commandMachine'] = commandMachine;\n\nwindow['enableEvents'] = Web.enablePageEvents;\nwindow['sendEvent'] = Web.sendPageEvent;\n"]} \ No newline at end of file diff --git a/versions/pc8080/1.61.0/pc8080-uncompiled.js b/versions/pc8080/1.61.0/pc8080-uncompiled.js index 7835e8499a..6d586f4ffa 100644 --- a/versions/pc8080/1.61.0/pc8080-uncompiled.js +++ b/versions/pc8080/1.61.0/pc8080-uncompiled.js @@ -629,7 +629,7 @@ class Str { * * Displays the given number as an unsigned integer using the specified radix and number of digits. * - * @param {number|null|undefined} n + * @param {number|*} n * @param {number} radix (ie, the base) * @param {number} cch (the desired number of digits) * @param {string} [sPrefix] (default is none) @@ -639,17 +639,17 @@ class Str { static toBase(n, radix, cch, sPrefix = "", nGrouping = 0) { /* - * An initial "falsey" check for null takes care of both null and undefined; - * we can't rely entirely on isNaN(), because isNaN(null) returns false, oddly enough. + * We can't rely entirely on isNaN(), because isNaN(null) returns false, and we can't rely + * entirely on typeof either, because typeof Nan returns "number". Sigh. * * Alternatively, we could mask and shift n regardless of whether it's null/undefined/NaN, * since JavaScript coerces such operands to zero, but I think there's "value" in seeing those * values displayed differently. */ var s = ""; - if (isNaN(n)) { + if (isNaN(n) || typeof n != "number") { n = null; - } else if (n != null) { + } else { /* * Callers that produced an input by dividing by a power of two rather than shifting (in order * to access more than 32 bits) may produce a fractional result, which ordinarily we would simply @@ -692,7 +692,7 @@ class Str { * * Converts an integer to binary, with the specified number of digits (up to a maximum of 36). * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of binary digits (0 or undefined for default of either 8, 18, or 36) * @param {number} [nGrouping] * @return {string} the binary representation of n @@ -744,7 +744,7 @@ class Str { * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw * an exception, whereas this function will return '?' characters. * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of octal digits (0 or undefined for default of either 6, 8, or 12) * @param {boolean} [fPrefix] * @return {string} the octal representation of n @@ -774,7 +774,7 @@ class Str { * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw * an exception, whereas this function will return '?' characters. * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of decimal digits (0 or undefined for default of either 5 or 11) * @return {string} the decimal representation of n */ @@ -809,7 +809,7 @@ class Str { * s = "00000000".substr(0, 8 - s.length) + s; * s = s.substr(0, cch).toUpperCase(); * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of hex digits (0 or undefined for default of either 4, 8, or 9) * @param {boolean} [fPrefix] * @return {string} the hex representation of n @@ -3139,7 +3139,7 @@ class Component { if (target) { var control = target.bindings[sBinding]; if (control) { - component.setBinding(null, sBinding, control); + component.setBinding("", sBinding, control); } } } @@ -3627,7 +3627,7 @@ class Component { * Component's setBinding() method is intended to be overridden by subclasses. * * @this {Component} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, 'print') * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -4080,10 +4080,10 @@ class Component { * * @this {Component} * @param {number} port - * @param {number|null} bOut if an output operation - * @param {number|null} [addrFrom] - * @param {string|null} [name] of the port, if any - * @param {number|null} [bIn] is the input value, if known, on an input operation + * @param {number|null|*} bOut if an output operation + * @param {number|null|*} [addrFrom] + * @param {string|null|*} [name] of the port, if any + * @param {number|null|*} [bIn] is the input value, if known, on an input operation * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s) */ printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage) @@ -4481,7 +4481,7 @@ class Panel8080 extends Component { * that doesn't recognize the specified binding should simply ignore it. * * @this {Panel8080} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -6641,7 +6641,7 @@ class CPU8080 extends Component { for (var i = 0; i < CPU8080.BUTTONS.length; i++) { var control = this.bindings[CPU8080.BUTTONS[i]]; - if (control) this.cmp.setBinding(null, CPU8080.BUTTONS[i], control); + if (control) this.cmp.setBinding("", CPU8080.BUTTONS[i], control); } /* @@ -6930,7 +6930,7 @@ class CPU8080 extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {CPU8080} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -7997,7 +7997,7 @@ class CPUState8080 extends CPU8080 { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {CPUState8080} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -11925,7 +11925,7 @@ class ChipSet8080 extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {ChipSet8080} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, "sw1") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -13691,7 +13691,7 @@ class Keyboard8080 extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {Keyboard8080} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -15389,7 +15389,7 @@ class Video8080 extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {Video8080} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, "refresh") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -16733,7 +16733,7 @@ class SerialPort8080 extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {SerialPort8080} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, "buffer") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -16743,7 +16743,7 @@ class SerialPort8080 extends Component { { var serial = this; - if (sHTMLType == null || sHTMLType == "textarea") { + if (!sHTMLType || sHTMLType == "textarea") { this.bindings[sBinding] = this.controlBuffer = control; @@ -18544,7 +18544,7 @@ class Debugger extends Component * * @this {Debugger} * @param {string|undefined} sValue - * @param {string|null} [sName] is the name of the value, if any + * @param {string|null|*} [sName] is the name of the value, if any * @param {Array|undefined|boolean} [fQuiet] * @param {number} [nUnary] (0 for none, 1 for negate, 2 for complement, 3 for leading zeros) * @return {number|undefined} numeric value, or undefined if sValue is either undefined or invalid @@ -19023,7 +19023,7 @@ class Debugger8080 extends Debugger { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {Debugger8080} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -24180,7 +24180,7 @@ class Computer8080 extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {Computer8080} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/versions/pc8080/1.61.0/pc8080.js b/versions/pc8080/1.61.0/pc8080.js index a83de0356e..e38ac1402d 100644 --- a/versions/pc8080/1.61.0/pc8080.js +++ b/versions/pc8080/1.61.0/pc8080.js @@ -37,7 +37,7 @@ var m={ze:0,Ce:1,De:2,Ee:3,Fe:4,Ge:5,He:6,Ie:7,Je:8,Ke:9,Le:10,Me:11,Ne:12,Oe:13 qc:85,sc:86,tc:87,vc:88,wc:89,sb:90,"[":91,"\\":92,"]":93,"^":94,_:95,"`":96,ub:97,sd:98,ud:99,d:100,e:101,yd:102,Ad:103,Bd:104,Cd:105,Ld:106,k:107,Md:108,Od:109,n:110,Pd:111,p:112,q:113,r:114,le:115,t:116,ne:117,oe:118,pe:119,x:120,y:121,z:122,"{":123,"|":124,"}":125,"~":126,bf:127},na={59:186,61:187,173:189,224:91}; function oa(a,b){if(a){b||(b=10);var c,d=0<a.indexOf(",");d&&(a=a.replace(/,/g,""));var e=c=a.charAt(0);"#"==c?(b=8,c=""):"$"==c&&(b=16,c="");e!=c?a=a.substr(1):(e=c=a.substr(0,2),"0b"==c&&d||"^B"==c?(b=2,c=""):"0o"==c||"^O"==c?(b=8,c=""):"^D"==c?(b=10,c=""):"0x"==c&&(b=16,c=""),e!=c&&(a=a.substr(2)));e=c=a.slice(-1);"Y"==c||"y"==c?(b=2,c=""):"."==c?(b=10,c=""):"H"==c||"h"==c?(b=16,c=""):"K"==c?c="000":"M"==c?c="000000":"G"==c&&(c="000000000");e!=c&&(a=a.slice(0,-1)+c);var f;e=0;10>=b&&(c=a.match(/(-?[0-9]+)B([0-9]*)/))&& (a=c[1],e=35-((c[2]||35)&255));c=a;if(((d=b)&&10!=d?16==d?null!==c.match(/^-?[0-9a-f]+$/i):8==d?null!==c.match(/^-?[0-7]+$/):2==d&&null!==c.match(/^-?[01]+$/):null!==c.match(/^-?[0-9]+$/))&&!isNaN(f=parseInt(a,b))){e&&(0>f&&(f+=Math.pow(2,36)),f=0<e?f*Math.pow(2,e):Math.trunc(f/Math.pow(2,-e)));var g=f}}return g} -function pa(a,b,c,d,e){e=void 0===e?0:e;var f="";isNaN(a)?a=null:null!=a&&(0>a&&-1<a&&(a=-1),0>a&&(a+=Math.pow(b,c)),a>=Math.pow(b,c)&&(c=Math.ceil(Math.log(a)/Math.log(b))));for(var g=e||-1;0<c--;){g||(f=","+f,g=e);if(null==a)f="?"+f;else{var h=a%b;h+=0<=h&&9>=h?48:55;f=String.fromCharCode(h)+f;a=Math.trunc(a/b)}g--}return(void 0===d?"":d)+f}function n(a,b,c){b?9<b&&(b=9):(b=Math.abs(a),b=65535>=b?4:4294967295>=b?8:9);return pa(a,16,b,c?"0x":"")}function qa(a){return n(a,2,!0)} +function pa(a,b,c,d,e){e=void 0===e?0:e;var f="";isNaN(a)||"number"!=typeof a?a=null:(0>a&&-1<a&&(a=-1),0>a&&(a+=Math.pow(b,c)),a>=Math.pow(b,c)&&(c=Math.ceil(Math.log(a)/Math.log(b))));for(var g=e||-1;0<c--;){g||(f=","+f,g=e);if(null==a)f="?"+f;else{var h=a%b;h+=0<=h&&9>=h?48:55;f=String.fromCharCode(h)+f;a=Math.trunc(a/b)}g--}return(void 0===d?"":d)+f}function n(a,b,c){b?9<b&&(b=9):(b=Math.abs(a),b=65535>=b?4:4294967295>=b?8:9);return pa(a,16,b,c?"0x":"")}function qa(a){return n(a,2,!0)} function q(a){return n(a,4,!0)}function ra(a){var b=a,c=a.lastIndexOf("/");0<=c&&(b=a.substr(c+1));c=b.indexOf("\x26");0<c&&(b=b.substr(0,c));return b}function sa(a){var b="",c=a.lastIndexOf(".");0<=c&&(b=a.substr(c+1).toLowerCase());return b}function ta(){var a=wa();return-1!==a.indexOf("pcjs.org",a.length-8)}function xa(a){return a.replace(/[&<>"']/g,function(a){return ya[a]})}function za(a,b){return(a+" ").slice(0,b)} function Aa(a){return String.prototype.trim?a.trim():a.replace(/^\s+|\s+$/g,"")}var ya={"\x26":"\x26amp;","\x3c":"\x26lt;","\x3e":"\x26gt;",'"':"\x26quot;","'":"\x26#039;"},Ca={0:"NUL",1:"SOH",2:"STX",3:"ETX",4:"EOT",5:"ENQ",6:"ACK",7:"BEL",8:"BS",9:"TAB",10:"LF",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",127:"DEL"}; function Da(a,b,c){var d=0,e=a.length,f=0;for(void 0===c&&(c=function(a,b){return a>b?1:a<b?-1:0});d<e;){var g=d+e>>1;var h=c(b,a[g]);0<h?d=g+1:(e=g,f=!h)}return f?d:~d} @@ -89,7 +89,7 @@ l.xe=function(a,b){var c=a>>2;a=(a&3)<<3;24>a?this.b[c]=this.b[c]&~(65535<<a)|b< l.re=function(a,b,c){if(this.J&&null!=this.K){var d=this.J;Oc(d,this.K+a,1,d.B)&&Pc(d,!0)}this.w?this.nb(a,b,c):this.mb(a,b,c)};l.ve=function(a,b,c){if(this.J&&null!=this.K){var d=this.J;Oc(d,this.K+a,2,d.B)&&Pc(d,!0)}this.w?this.nb(a,b,c):this.Rb(a,b,c)};l.ce=function(a){return this.g[a]};l.ee=function(a){return this.g[a]};l.ge=function(a){return this.j.getUint16(a,!0)};l.ie=function(a){return a&1?this.g[a]|this.g[a+1]<<8:this.u[a>>1]};l.qe=function(a,b){this.g[a]=b;this.Ca=!0}; l.se=function(a,b){this.g[a]=b;this.Ca=!0};l.ue=function(a,b){this.j.setUint16(a,b,!0);this.Ca=!0};l.we=function(a,b){a&1?(this.g[a]=b,this.g[a+1]=b>>8):this.u[a>>1]=b;this.Ca=!0};var Ec=0,Fc=2,ac=["NONE","RAM","ROM","VID","H/W"],Dc=0,Kc=[],Jc=[A.prototype.fe,A.prototype.te,A.prototype.je,A.prototype.xe],Nc=[A.prototype.de,A.prototype.re,A.prototype.he,A.prototype.ve];if(Ob)var Ic=[A.prototype.ce,A.prototype.qe,A.prototype.ge,A.prototype.ue],Hc=[A.prototype.ee,A.prototype.se,A.prototype.ie,A.prototype.we]; function Qc(a,b){u.call(this,"CPU",a,1);var c=a.multiplier||1;this.xa=a.cycles||b;this.S=c;this.Qa=Math.round(this.xa/1E4)/100;this.Y=this.Qa*this.S;this.flags.ia=!1;this.flags.Ob=!1;this.flags.gb=a.autoStart;this.flags.zc=!1;this.flags.Ta=!1;this.ua=this.ma=0;this.wa=a.csStart;this.la=a.csInterval;this.qa=a.csStop;this.T=[];this.Ab=this.pb.bind(this);Ib(this)}ia(Qc,u);l=Qc.prototype; -l.Da=function(a,b,c,d){this.P=a;this.H=b;this.J=d;for(b=0;b<Rc.length;b++)(c=this.O[Rc[b]])&&this.P.ca(null,Rc[b],c);this.V=Sb(a,"ChipSet");a=Sc(a,"autoStart");null!=a&&(this.flags.gb="true"==a?!0:"false"==a?!1:!!a);Ib(this)};l.reset=function(){};l.save=function(){return null};l.restore=function(){return!1}; +l.Da=function(a,b,c,d){this.P=a;this.H=b;this.J=d;for(b=0;b<Rc.length;b++)(c=this.O[Rc[b]])&&this.P.ca("",Rc[b],c);this.V=Sb(a,"ChipSet");a=Sc(a,"autoStart");null!=a&&(this.flags.gb="true"==a?!0:"false"==a?!1:!!a);Ib(this)};l.reset=function(){};l.save=function(){return null};l.restore=function(){return!1}; l.ta=function(a,b){if(!b){if(a&&this.restore){Tc(this);if(!this.restore(a))return!1;Uc(this)}else this.reset();this.J?(a=this.J,a.i("Type ? for help with PC8080 Debugger commands"),Vc(a),a.la&&(b=a.la,a.la=null,Wc(a,b))):this.i("No debugger detected")}Xc(this);return!0};l.sa=function(a){return a?this.save():!0};l.gb=function(){return this.flags.gb||!this.J&&void 0===this.O.run?(this.pb(),!0):!1};l.Cc=function(){return 0}; function Uc(a){void 0===a.wa&&(a.wa=0);void 0===a.la&&(a.la=-1);void 0===a.qa&&(a.qa=-1);a.flags.Ta=0<=a.wa&&0<a.la;a.flags.Ta&&(a.ua=0,a.ma=a.wa-a.ja)}function Yc(a,b){if(a.flags.Ta){var c=!1;a.ua=a.ua+a.Cc()|0;a.ma-=b;0>=a.ma&&(a.ma+=a.la,c=!0);0<=a.qa&&a.qa<=Zc(a)&&(a.la=a.qa=-1,Uc(a),$c(a),c=!0);c&&a.i(Zc(a)+" cycles: checksum\x3d"+n(a.ua))}} l.ca=function(a,b,c){var d=this;a=!1;switch(b){case "power":case "reset":this.O[b]=c;a=!0;break;case "run":this.O[b]=c;c.onclick=function(){var a;if(a=d.P)if(a=d.P,a.flags.ha)a=!0;else{var b=null,c,h=wb(a.id);for(c=0;c<h.length&&(b=h[c],b===a||b.flags.ready);c++);if(c==h.length)for(c=0;c<h.length&&(b=h[c],b===a||b.flags.ha);c++);c==h.length&&(b=a);r("The "+b.type+" component ("+b.id+") is not "+(b.flags.ready?"powered yet":"ready yet"+(b.wb?" (waiting for notification)":""))+".");a=!1}a&&(d.flags.ia? @@ -194,8 +194,8 @@ function td(a,b){var c=!0;if(!b){a.ma&&(120==a.ma?a.cb&1?(Zd(a.w,2),c=!1):Zd(a.w !0;b<a.C&&(f=p-b,d-=c,a.g&&(g=b,h=f,b=c,f=d,c=a.C-(g+h),d=h),a.ra.putImageData(a.Sa,0,0,b,c,f,d),a.j.drawImage(a.D,0,0,a.D.width,a.D.height,0,0,a.L,a.G))}}var zf=0,Af=1,xf=2,tf=0,yf=1,Bf=2,sf={SI1978:yf,VT100:Bf},Cf=96,Ef=64,Ff=32,Gf=0,If=127,Kf=15,Lf=16,Jf=96,Mf=8192,Nf=16384; $a(function(){for(var a=ub(document,"pc8080","video"),b=0;b<a.length;b++){var c=a[b],d=vb(c),e=document.createElement("canvas");if(void 0===e||!e.getContext){c.innerHTML="\x3cbr/\x3eMissing \x26lt;canvas\x26gt; 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<=Ka().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&&(Za("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"),f.style.fontSize="16px");c.appendChild(f);var g=e.getContext("2d");d=new rf(d,e,g,f,c);tb(d,c)}}); -function Of(a){u.call(this,"SerialPort",a,8388608);this.S=+a.adapter;switch(this.S){case 0:this.T=0;this.W=2;break;default:r("Unrecognized serial adapter #"+this.S);return}this.g=this.j=null;this.U=a.tabSize;this.R=a.charBOL;this.u=0;this.M=!1;this.D=!0;a=a.binding;if("console"==a)this.j="";else if(a){var b=yb("Panel",this.id);b&&(b=b.O[a])&&this.ca(null,a,b)}this.A="";this.b=this.Oa=this.G=null;this.exports={connect:this.Dc,receiveData:this.Mb,receiveStatus:this.ke}}ia(Of,u);l=Of.prototype; -l.ca=function(a,b,c,d){var e=this;return null==a||"textarea"==a?(this.O[b]=this.g=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<b&&(b-=64),Pf(e,b);return!0},c.onkeypress=function(a){a=a||window.event;Pf(e,a.which||a.keyCode);a.preventDefault&&a.preventDefault();return!0},c.removeAttribute("readonly"),!0):d?(this.O[b]=c,c.onclick=function(){e.Mb(d);return!0},!0):!1}; +function Of(a){u.call(this,"SerialPort",a,8388608);this.S=+a.adapter;switch(this.S){case 0:this.T=0;this.W=2;break;default:r("Unrecognized serial adapter #"+this.S);return}this.g=this.j=null;this.U=a.tabSize;this.R=a.charBOL;this.u=0;this.M=!1;this.D=!0;a=a.binding;if("console"==a)this.j="";else if(a){var b=yb("Panel",this.id);b&&(b=b.O[a])&&this.ca("",a,b)}this.A="";this.b=this.Oa=this.G=null;this.exports={connect:this.Dc,receiveData:this.Mb,receiveStatus:this.ke}}ia(Of,u);l=Of.prototype; +l.ca=function(a,b,c,d){var e=this;return a&&"textarea"!=a?d?(this.O[b]=c,c.onclick=function(){e.Mb(d);return!0},!0):!1:(this.O[b]=this.g=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<b&&(b-=64),Pf(e,b);return!0},c.onkeypress=function(a){a=a||window.event;Pf(e,a.which||a.keyCode);a.preventDefault&&a.preventDefault();return!0},c.removeAttribute("readonly"),!0)}; l.Da=function(a,b,c,d){this.P=a;this.H=b;this.w=c;this.J=d;var e=this;this.X=od(this.w,this.id+".receive",function(){e.Mb()});this.Y=od(this.w,this.id+".transmit",function(){$e(e)});this.V=Sb(a,"ChipSet");kc(b,this,Qf,this.T);oc(b,this,Rf,this.T);Ib(this)}; l.Dc=function(a){if(!this.b){var b=Sc(this.P,"connection");if(b){var c=b.split("-\x3e");if(2==c.length){var d=Aa(c[0]);if(d!=this.Fb)return;c=Aa(c[1]);if(this.b=xb(c)){var e=this.b.exports;if(e){var f=e.connect;f&&f.call(this.b,this.D);if(this.Oa=e.receiveData){this.D=a;this.G=e.receiveStatus;this.status("Connected "+this.Za+"."+d+" to "+c);return}}}}this.status("Unable to establish connection: "+b)}}}; l.ta=function(a,b){if(!b)if(this.Dc(this.D),!a||!this.restore)this.reset();else if(!this.restore(a))return!1;return!0};l.sa=function(a){return a?this.save():!0};l.reset=function(){Sf(this)};l.save=function(){var a=new Bd(this),b=0,c=[];c[b++]=this.F;c[b++]=this.L;c[b++]=this.N;c[b++]=this.ga;c[b++]=this.B;c[b++]=this.C;c[b]=this.I;a.set(0,c);return a.data()};l.restore=function(a){return Sf(this,a[0])}; diff --git a/versions/pc8080/1.61.0/pc8080.js.map b/versions/pc8080/1.61.0/pc8080.js.map index 6dae2bb7c0..6b5f838c5c 100644 --- a/versions/pc8080/1.61.0/pc8080.js.map +++ b/versions/pc8080/1.61.0/pc8080.js.map @@ -1 +1 @@ -{"version":3,"file":"pc8080.js","lineCount":315,"mappings":"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","sources":["versions/pc8080/1.61.0/pc8080-uncompiled.js"," [synthetic:util/objectcreate] "," [synthetic:es6/util/setprototypeof] "," [synthetic:es6/util/inherits] "," [synthetic:util/defineproperty] "," [synthetic:util/global] "," [synthetic:util/polyfill] "," [synthetic:es6/math/trunc] "," [synthetic:es6/number/parseint] "],"names":["$jscomp.objectCreate","$jscomp.setPrototypeOf","$jscomp.defineProperty","$jscomp.global","$jscomp.polyfill","ASCII","BREAK","CTRL_A","CTRL_B","CTRL_C","CTRL_D","CTRL_E","CTRL_F","CTRL_G","CTRL_H","CTRL_I","CTRL_J","CTRL_K","CTRL_L","CTRL_M","CTRL_N","CTRL_O","CTRL_P","CTRL_Q","CTRL_R","CTRL_S","CTRL_T","CTRL_U","CTRL_V","CTRL_W","CTRL_X","CTRL_Y","CTRL_Z","ESC","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","DEL","Keys.FF_KEYCODES","KEYCODE","parseInt","base","chPrefix","fCommas","indexOf","replace","ch","charAt","substr","chSuffix","slice","shift","match","isNaN","Math","pow","trunc","value","toBase","radix","cch","sPrefix","nGrouping","ceil","log","String","fromCharCode","toHex","fPrefix","abs","Str.toBase","toHexByte","Str.toHex","toHexWord","getBaseName","sFileName","sBaseName","lastIndexOf","getExtension","sExtension","toLowerCase","endsWith","Web.getHost","sSuffix","length","escapeHTML","sHTML","Str.HTMLEscapeMap","pad","sPadding","trim","prototype","Str.ASCIICodeMap","binarySearch","fnCompare","left","right","found","undefined","middle","compareResult","formatDate","date","sDate","Date","iHour","getHours","iDay","getDate","iMonth","getMonth","sFormat","Usr.asDays","getDay","Usr.asMonths","getMinutes","getSeconds","getFullYear","Array","getResource","sURL","type","fAsync","done","callback","request","readyState","resource","fArrayBuffer","response","responseText","err","status","window","location","protocol","nErrorCode","resources","XMLHttpRequest","ActiveXObject","fXHR2","responseType","onreadystatechange","sPost","hasOwnProperty","encodeURIComponent","open","setRequestHeader","send","overrideMimeType","parseMemoryResource","sData","aBytes","aSymbols","addrLoad","addrExec","ib","Error","data","JSON","parse","eval","aData","Component.alertUser","message","ab","asHexData","sHexData","split","push","getHost","host","SITEHOST","getUserAgent","navigator","userAgent","hasLocalStorage","Web.fLocalStorage","localStorage","setItem","Web.sLocalStorageTest","getItem","removeItem","getLocalStorageItem","sKey","sValue","setLocalStorageItem","isUserAgent","Web.getUserAgent","findProperty","obj","sProp","Web.asBrowserPrefixes.length","sName","Web.asBrowserPrefixes","toUpperCase","getURLParm","sParm","Web.parmsURL","sParms","aParms","search","pl","exec","decodeURIComponent","onCountRepeat","fnRepeat","fnComplete","fnTimeout","doCountRepeat","setTimeout","onClickRepeat","fn","doClickRepeat","msRepeat","ms","timer","fIgnoreMouseEvents","onmousedown","e.onmousedown","msDelay","ontouchstart","e.ontouchstart","onmouseup","onmouseout","e.onmouseout","clearTimeout","ontouchend","ontouchcancel","e.ontouchcancel","onPageEvent","sFunc","fnPrev","onInit","Web.aPageEventHandlers","doPageEvent","afn","Web.fPageEventsEnabled","Component.notice","fPrintOnly","id","enablePageEvents","fEnable","Web.fPageLoaded","Web.sendPageEvent","Web.fPageShowed","sendPageEvent","sEvent","Web.doPageEvent","Web.onPageEvent","onPageLoad","onPageShow","Web.isUserAgent","onPageUnload","constructor","Component","parms","bitsMessage","name","comment","bindings","idComponent","idMachine","flags","ready","busy","busyCancel","initDone","powered","unloading","error","fnReady","clearError","dbg","cpu","bus","cmp","Component.components.push","component","addMachineResource","Component.machines","getTime","now","notice","alertUser","sMessage","alert","confirmUser","sPrompt","fResponse","confirm","appendControl","control","sText","scrollTop","scrollHeight","bindComponentControls","element","aeControls","Component.getElementsByClass","parentNode","iControl","aeChildNodes","childNodes","iNode","nodeType","sClass","getAttribute","aClasses","iClass","Component.getComponentParms","setBinding","getComponents","idRelated","aComponents","Component.components.length","Component.components","getComponentByID","getComponentByType","sType","componentPrev","getComponentParms","getElementsByClass","sObjClass","getElementsByClassName","ae","aeAll","getElementsByTagName","re","RegExp","test","className","processCommands","fSuccess","aCommands","Component.commands","aTokens","splice","sCommand","fnCallReady","Component.asyncCommands.indexOf","processNextCommand","Component.processCommands","fnCommand","Component.globalCommands","Component.getComponentByType","Component.componentCommands","exports","call","Component.prototype","?.prototype","toString","sHTMLType","sBinding","onclick","clearControl","this.notice","println","print","printControl","Component.appendControl","printlnControl","Component.PRINT.PROGRESS","computer","console","setError","isReady","setReady","isBusy","fCancel","setBusy","fBusy","powerUp","powerDown","fSave","fShutdown","messageEnabled","bitsEnabled","printMessage","fAddress","printMessageIO","port","bOut","addrFrom","bIn","messageIO","PROGRESS","Component.asyncCommands","scriptAlert","scriptSleep","fnCallback","sDelay","scriptSelect","aBindings","options","textContent","selectedIndex","Array.prototype.indexOf","start","isArray","Array.isArray","arg","Object","Function","bind","Function.prototype.bind","fnBound","fToBind","apply","fnNOP","args","concat","arguments","TypeError","TYPEDARRAYS","ArrayBuffer","PARITY","Messages8080.CATEGORIES","CPU","BUS","MEM","PORT","NVR","CHIPSET","KEYBOARD","KEYS","VIDEO","FDC","DISK","SERIAL","SPEAKER","COMPUTER","BUFFER","WARN","HALT","Panel8080","parmsPanel","$jscomp.inherits","kbd","initBus","getMachineComponent","fRepower","Panel8080.init","init","fReady","aePanels","document","APPCLASS","iPanel","ePanel","panel","Component.getComponentByID","Component.bindComponentControls","Web.onInit","Bus8080","parmsBus","nBusWidth","addrTotal","nBusMask","nBlockShift","nBlockSize","nBlockLen","nBlockLimit","nBlockTotal","nBlockMask","aPortInputNotify","aPortOutputNotify","fPortInputBreakAll","fPortOutputBreakAll","aPortInputWidth","aPortOutputWidth","block","Memory8080","copyBreakpoints","initMemory","aMemBlocks","iBlock","reset","addMemory","addr","size","addrNext","sizeLeft","addrBlock","sizeBlock","used","sizeAvail","reportError","Bus8080.ERROR.ADD_MEM_INUSE","blockNew","floor","Memory8080.TYPE.NAMES","Str.toHexWord","Bus8080.ERROR.ADD_MEM_BADRANGE","getByteDirect","readByteDirect","getShort","off","readShort","readByte","getShortDirect","readShortDirect","setByteDirect","writeByteDirect","setShort","writeShort","writeByte","removeMemBreak","fWrite","removeBreakpoint","cWriteBreakpoints","resetWriteAccess","fReadOnly","writeNone","writeShortDefault","writeShortDirect","cReadBreakpoints","resetReadAccess","saveMemory","fDirty","fDirtyEver","save","iSrc","iComp","aComp","aSrc","iCompare","addPortInputBreak","addPortInputTable","table","offset","addPortInputNotify","end","checkPortInputNotify","addrIP","aNotify","sizePort","maskPort","dataPort","checkPortInput","addPortOutputBreak","addPortOutputTable","addPortOutputNotify","checkPortOutputNotify","checkPortOutput","op","ADD_MEM_INUSE","ADD_MEM_BADRANGE","buffer","setUint16","DataView","Uint16Array","littleEndian","Memory8080.idBlock","adw","Memory8080.TYPE.NONE","Memory8080.TYPE.ROM","dv","Uint8Array","aw","Int32Array","setAccess","Memory8080.afnArrayLE","Memory8080.afnArrayBE","Memory8080.afnMemory","Memory8080.prototype","getInt32","restore","setInt32","Memory8080.afnNone","setReadAccess","fDirect","setWriteAccess","readNone","readShortDefault","addBreakpoint","Memory8080.afnChecked","mem","readByteMemory","readShortMemory","idw","nShift","dw","writeByteMemory","writeShortMemory","readByteChecked","checkBreakpoint","aBreakRead","stopCPU","readShortChecked","nb","writeByteChecked","aBreakWrite","writeShortChecked","readByteBE","readByteLE","readShortBE","getUint16","readShortLE","writeByteBE","writeByteLE","writeShortBE","writeShortLE","NONE","ROM","NAMES","CPU8080","parmsCPU","nCyclesDefault","nMultiplier","nCyclesPerSecond","nCyclesMultiplier","mhzDefault","round","mhzTarget","running","starting","autoStart","displayLiveRegs","checksum","nChecksum","nCyclesChecksumNext","nCyclesChecksumStart","nCyclesChecksumInterval","nCyclesChecksumStop","aTimers","onRunTimeout","runCPU","CPU8080.prototype","CPU8080.BUTTONS.length","CPU8080.BUTTONS","chipset","sAutoStart","getMachineParm","resetCycles","resetChecksum","updateStatus","sInitCommands","sCmds","doCommands","updateCPU","getChecksum","nTotalCycles","updateChecksum","nCycles","fDisplay","getCycles","displayChecksum","fBound","control.onclick","iComponent","Component.getComponents","setSpeed","getSpeedTarget","toFixed","addCycles","fEndStep","nBurstCycles","nStepCycles","calcCycles","fRecalc","vMultiplier","mhz","msPerYield","CPU8080.YIELDS_PER_SECOND","nCyclesPerYield","nCyclesNextYield","nCyclesRecalc","nRunCycles","nYieldsSinceStatusUpdate","fUpdateFocus","sSpeed","controlSpeed","updateFocus","msStartRun","Component.getTime","msEndThisRun","addTimer","callBack","iTimer","setTimer","getMSCycles","endBurst","fReset","CPU8080_prototype$runCPU","startCPU","controlRun","calcStartTime","nCyclesThisRun","msStartThisRun","msDelta","getBurstCycles","stepCPU","updateTimers","CPU8080.YIELDS_PER_STATUS","stop","stack","calcRemainingTime","msYield","msRemainsThisRun","msElapsed","CPU8080_prototype$stepCPU","fComplete","complete","fForce","aVideo","updateScreen","CPUState8080","model","MODEL_8080","initProcessor","aOps","CPUDef8080.aOps8080","debugCheck","cLiveRegs","afnHalt","addrReset","resetRegs","addHaltCheck","CPUState8080.prototype","regA","regB","regC","regD","regE","regH","regL","setSP","regSP","setPC","setPS","intFlags","INTFLAG","setReset","sum","getSP","getPC","regPC","getPS","state","State","set","getSpeed","iDst","aDst","getBC","setBC","getDE","setDE","getHL","setHL","getCF","resultZeroCarry","PS","updateCF","CF","getPF","CPUDef8080.PARITY","resultParitySign","getAF","resultAuxOverflow","getZF","getSF","regPS","addByte","src","addByteCarry","andByte","decByte","incByte","orByte","subByte","subByteBorrow","xorByte","getByte","setByte","getPCByte","getPCWord","getWord","popWord","pushWord","setWord","checkINTR","getIF","nLevel","clearINTR","bitsClear","clearIF","OPCODE","requestINTR","updateReg","sReg","nValue","displayValue","sVal","nMinCycles","fDebugCheck","checksEnabled","nDebugState","checkInstruction","aeCPUs","iCPU","eCPU","CPUDef8080.opNOP","CPUDef8080.opJMP","CPUDef8080.opRET","CPUDef8080.opCALL","CPUDef8080.opLXIB","CPUDef8080.opSTAXB","CPUDef8080.opINXB","CPUDef8080.opINRB","CPUDef8080.opDCRB","CPUDef8080.opMVIB","CPUDef8080.opRLC","carry","CPUDef8080.opDADB","CPUDef8080.opLDAXB","CPUDef8080.opDCXB","CPUDef8080.opINRC","CPUDef8080.opDCRC","CPUDef8080.opMVIC","CPUDef8080.opRRC","CPUDef8080.opLXID","CPUDef8080.opSTAXD","CPUDef8080.opINXD","CPUDef8080.opINRD","CPUDef8080.opDCRD","CPUDef8080.opMVID","CPUDef8080.opRAL","CPUDef8080.opDADD","CPUDef8080.opLDAXD","CPUDef8080.opDCXD","CPUDef8080.opINRE","CPUDef8080.opDCRE","CPUDef8080.opMVIE","CPUDef8080.opRAR","CPUDef8080.opLXIH","CPUDef8080.opSHLD","CPUDef8080.opINXH","CPUDef8080.opINRH","CPUDef8080.opDCRH","CPUDef8080.opMVIH","CPUDef8080.opDAA","AF","CPUDef8080.opDADH","CPUDef8080.opLHLD","CPUDef8080.opDCXH","CPUDef8080.opINRL","CPUDef8080.opDCRL","CPUDef8080.opMVIL","CPUDef8080.opCMA","CPUDef8080.opLXISP","CPUDef8080.opSTA","CPUDef8080.opINXSP","CPUDef8080.opINRM","CPUDef8080.opDCRM","CPUDef8080.opMVIM","CPUDef8080.opSTC","setCF","CPUDef8080.opDADSP","CPUDef8080.opLDA","CPUDef8080.opDCXSP","CPUDef8080.opINRA","CPUDef8080.opDCRA","CPUDef8080.opMVIA","CPUDef8080.opCMC","CPUDef8080.opMOVBB","CPUDef8080.opMOVBC","CPUDef8080.opMOVBD","CPUDef8080.opMOVBE","CPUDef8080.opMOVBH","CPUDef8080.opMOVBL","CPUDef8080.opMOVBM","CPUDef8080.opMOVBA","CPUDef8080.opMOVCB","CPUDef8080.opMOVCC","CPUDef8080.opMOVCD","CPUDef8080.opMOVCE","CPUDef8080.opMOVCH","CPUDef8080.opMOVCL","CPUDef8080.opMOVCM","CPUDef8080.opMOVCA","CPUDef8080.opMOVDB","CPUDef8080.opMOVDC","CPUDef8080.opMOVDD","CPUDef8080.opMOVDE","CPUDef8080.opMOVDH","CPUDef8080.opMOVDL","CPUDef8080.opMOVDM","CPUDef8080.opMOVDA","CPUDef8080.opMOVEB","CPUDef8080.opMOVEC","CPUDef8080.opMOVED","CPUDef8080.opMOVEE","CPUDef8080.opMOVEH","CPUDef8080.opMOVEL","CPUDef8080.opMOVEM","CPUDef8080.opMOVEA","CPUDef8080.opMOVHB","CPUDef8080.opMOVHC","CPUDef8080.opMOVHD","CPUDef8080.opMOVHE","CPUDef8080.opMOVHH","CPUDef8080.opMOVHL","CPUDef8080.opMOVHM","CPUDef8080.opMOVHA","CPUDef8080.opMOVLB","CPUDef8080.opMOVLC","CPUDef8080.opMOVLD","CPUDef8080.opMOVLE","CPUDef8080.opMOVLH","CPUDef8080.opMOVLL","CPUDef8080.opMOVLM","CPUDef8080.opMOVLA","CPUDef8080.opMOVMB","CPUDef8080.opMOVMC","CPUDef8080.opMOVMD","CPUDef8080.opMOVME","CPUDef8080.opMOVMH","CPUDef8080.opMOVML","CPUDef8080.opHLT","requestHALT","CPUDef8080.opMOVMA","CPUDef8080.opMOVAB","CPUDef8080.opMOVAC","CPUDef8080.opMOVAD","CPUDef8080.opMOVAE","CPUDef8080.opMOVAH","CPUDef8080.opMOVAL","CPUDef8080.opMOVAM","CPUDef8080.opMOVAA","CPUDef8080.opADDB","CPUDef8080.opADDC","CPUDef8080.opADDD","CPUDef8080.opADDE","CPUDef8080.opADDH","CPUDef8080.opADDL","CPUDef8080.opADDM","CPUDef8080.opADDA","CPUDef8080.opADCB","CPUDef8080.opADCC","CPUDef8080.opADCD","CPUDef8080.opADCE","CPUDef8080.opADCH","CPUDef8080.opADCL","CPUDef8080.opADCM","CPUDef8080.opADCA","CPUDef8080.opSUBB","CPUDef8080.opSUBC","CPUDef8080.opSUBD","CPUDef8080.opSUBE","CPUDef8080.opSUBH","CPUDef8080.opSUBL","CPUDef8080.opSUBM","CPUDef8080.opSUBA","CPUDef8080.opSBBB","CPUDef8080.opSBBC","CPUDef8080.opSBBD","CPUDef8080.opSBBE","CPUDef8080.opSBBH","CPUDef8080.opSBBL","CPUDef8080.opSBBM","CPUDef8080.opSBBA","CPUDef8080.opANAB","CPUDef8080.opANAC","CPUDef8080.opANAD","CPUDef8080.opANAE","CPUDef8080.opANAH","CPUDef8080.opANAL","CPUDef8080.opANAM","CPUDef8080.opANAA","CPUDef8080.opXRAB","CPUDef8080.opXRAC","CPUDef8080.opXRAD","CPUDef8080.opXRAE","CPUDef8080.opXRAH","CPUDef8080.opXRAL","CPUDef8080.opXRAM","CPUDef8080.opXRAA","CPUDef8080.opORAB","CPUDef8080.opORAC","CPUDef8080.opORAD","CPUDef8080.opORAE","CPUDef8080.opORAH","CPUDef8080.opORAL","CPUDef8080.opORAM","CPUDef8080.opORAA","CPUDef8080.opCMPB","CPUDef8080.opCMPC","CPUDef8080.opCMPD","CPUDef8080.opCMPE","CPUDef8080.opCMPH","CPUDef8080.opCMPL","CPUDef8080.opCMPM","CPUDef8080.opCMPA","CPUDef8080.opRNZ","CPUDef8080.opPOPB","CPUDef8080.opJNZ","CPUDef8080.opCNZ","CPUDef8080.opPUSHB","CPUDef8080.opADI","CPUDef8080.opRST0","CPUDef8080.opRZ","CPUDef8080.opJZ","CPUDef8080.opCZ","CPUDef8080.opACI","CPUDef8080.opRST1","CPUDef8080.opRNC","CPUDef8080.opPOPD","CPUDef8080.opJNC","CPUDef8080.opOUT","offPC","CPUDef8080.opCNC","CPUDef8080.opPUSHD","CPUDef8080.opSUI","CPUDef8080.opRST2","CPUDef8080.opRC","CPUDef8080.opJC","CPUDef8080.opIN","CPUDef8080.opCC","CPUDef8080.opSBI","CPUDef8080.opRST3","CPUDef8080.opRPO","CPUDef8080.opPOPH","CPUDef8080.opJPO","CPUDef8080.opXTHL","CPUDef8080.opCPO","CPUDef8080.opPUSHH","CPUDef8080.opANI","CPUDef8080.opRST4","CPUDef8080.opRPE","CPUDef8080.opPCHL","CPUDef8080.opJPE","CPUDef8080.opXCHG","CPUDef8080.opCPE","CPUDef8080.opXRI","CPUDef8080.opRST5","CPUDef8080.opRP","CPUDef8080.opPOPSW","setPSW","CPUDef8080.opJP","CPUDef8080.opDI","CPUDef8080.opCP","CPUDef8080.opPUPSW","getPSW","CPUDef8080.opORI","CPUDef8080.opRST6","CPUDef8080.opRM","CPUDef8080.opSPHL","CPUDef8080.opJM","CPUDef8080.opEI","setIF","CPUDef8080.opCM","CPUDef8080.opCPI","CPUDef8080.opRST7","ChipSet8080","parmsChipSet","ChipSet8080.MODELS","config","classAudio","ChipSet8080.prototype","serial","video","portsInput","portsOutput","messageDump","onDumpNVR","sDump","iWord","aNVRWords","INIT","MODEL","ChipSet8080.SI1978.MODEL","bStatus0","bStatus1","bStatus2","wShiftData","bShiftCount","bSound1","bSound2","ChipSet8080.VT100.MODEL","bBrightness","bFlags","bDC011Cols","bDC011Rate","bDC012Scroll","bDC012Blink","bDC012Reverse","bDC012Attr","dNVRAddr","wNVRData","bNVRLatch","bNVROut","inSIStatus0","inSIStatus1","inSIStatus2","inSIShiftResult","outSIShiftCount","outSISound1","outSIShiftData","outSISound2","outSIWatchdog","getNVRAddr","tens","ones","inVT100Flags","ChipSet8080.VT100.FLAGS.NVR_CLK","FLAGS","NVR_CLK","getVT100LBA","bit","doNVRCommand","bCmd","ChipSet8080.VT100.NVR.CMD.STANDBY","CMD","STANDBY","ChipSet8080.VT100.NVR.CMD.ACCEPT_ADDR","ACCEPT_ADDR","ChipSet8080.VT100.NVR.CMD.ERASE","ERASE","ChipSet8080.VT100.NVR.WORDMASK","WORDMASK","ChipSet8080.VT100.NVR.CMD.ACCEPT_DATA","ACCEPT_DATA","ChipSet8080.VT100.NVR.CMD.WRITE","WRITE","ChipSet8080.VT100.NVR.CMD.READ","READ","ChipSet8080.VT100.NVR.CMD.SHIFT_OUT","SHIFT_OUT","Str.toHexByte","ChipSet8080.VT100.FLAGS.NVR_DATA","NVR_DATA","ChipSet8080.VT100.FLAGS.KBD_XMIT","KBD_XMIT","fVT100UARTBusy","ChipSet8080.VT100.FLAGS.UART_XMIT","UART_XMIT","bStatus","SerialPort8080.UART8251.STATUS.XMIT_READY","outVT100Brightness","outVT100NVRLatch","outVT100DC012","bOpt","bScroll","bScrollOffset","fSkipSingleCellUpdate","outVT100DC011","ChipSet8080.VT100.DC011.RATE60","DC011","RATE60","ChipSet8080.VT100.DC011.RATE50","RATE50","nRate","rateMonitor","ChipSet8080.VT100.DC011.COLS132","COLS132","nCols","nRows","ChipSet8080.VT100.FLAGS.NO_AVO","NO_AVO","nColsBuffer","cxCell","cxCellDefault","initBuffers","createFonts","ChipSet8080.SI1978","STATUS0","DIP4","FIRE","LEFT","RIGHT","PORT7","ALWAYS_SET","STATUS1","CREDIT","P2","P1","P1_FIRE","P1_LEFT","P1_RIGHT","STATUS2","DIP3_5","TILT","DIP6","P2_FIRE","P2_LEFT","P2_RIGHT","DIP7","SHIFT_RESULT","SHIFT_COUNT","MASK","SOUND1","UFO","SHOT","PDEATH","IDEATH","EXPLAY","AMP_ENABLE","SHIFT_DATA","SOUND2","FLEET1","FLEET2","FLEET3","FLEET4","UFO_HIT","ChipSet8080.VT100","NO_GFX","OPTION","NO_EVEN","BRIGHTNESS","COLS80","INITCOLS","INITRATE","DC012","SCROLL_LO","INITSCROLL","INITBLINK","INITREVERSE","INITATTR","LATCH","ChipSet8080.SI1978.INIT","ChipSet8080.SI1978.STATUS0.ALWAYS_SET","ChipSet8080.SI1978.STATUS1.ALWAYS_SET","ChipSet8080.SI1978.STATUS2.ALWAYS_SET","ChipSet8080.VT100.INIT","ChipSet8080.VT100.BRIGHTNESS.INIT","ChipSet8080.VT100.FLAGS.NO_GFX","ChipSet8080.VT100.DC011.INITCOLS","ChipSet8080.VT100.DC011.INITRATE","ChipSet8080.VT100.DC012.INITSCROLL","ChipSet8080.VT100.DC012.INITBLINK","ChipSet8080.VT100.DC012.INITREVERSE","ChipSet8080.VT100.DC012.INITATTR","ChipSet8080.SI1978.portsInput","ChipSet8080.SI1978.portsOutput","ChipSet8080.VT100.portsInput","ChipSet8080.VT100.portsOutput","aeChipSet","iChip","eChipSet","ROM8080","parmsROM","abROM","addrROM","sizeROM","addrAlias","sFilePath","Str.getBaseName","sFileURL","sFileExt","Str.getExtension","FORMAT","rom","Web.getResource","sResponse","doneLoad","copyROM","aOffsets","sSymbol","symbol","offSymbol","sAnnotation","index","Usr.binarySearch","comparePairs","aSymbolTable","symbolTable","sModule","len","sROMData","Component.addMachineResource","Str.parseInt","addROM","aliases","cloneROM","aBlocks","aeROM","iROM","eROM","RAM8080","parmsRAM","abInit","addrRAM","sizeRAM","fAllocated","ram","Web.parseMemoryResource","initRAM","RAM","RAM8080.CPM.INIT","RAM8080.CPM.VECTORS.length","RAM8080.CPM.VECTORS","RAM8080.CPM.VECTORS.indexOf","fCPM","RAM8080.CPM.BDOS.VECTOR","RAM8080.CPM.BDOS.FUNC.CON_WRITE","RAM8080.CPM.BDOS.FUNC.STR_WRITE","cchMax","bEnd","CPUDef8080.opRET.call","VECTOR","BDOS","CON_WRITE","STR_WRITE","BIOS","aeRAM","iRAM","eRAM","Keyboard8080","parmsKbd","Keyboard8080.MODELS","Keyboard8080.prototype","LEDCODES","onkeypress","control.onkeypress","event","fShifted","bMapping","CHARMAP","keyCode","charCode","KEYMAP","softCode","onSoftKeyDown","onkeydown","control.onkeydown","oniOSKeyDown","onkeyup","control.onkeyup","onKeyDown","Keys.ASCII.A","Keys.ASCII.Z","bitsState","Keyboard8080.STATE.SHIFTS","Keyboard8080.STATE.CAPS_LOCK","updateLEDs","Keys.ASCII.a","Keys.ASCII.z","onpaste","control.onpaste","sendData","stopPropagation","clipboardData","preventDefault","transmitData","getData","SOFTCODES","onKeyboardBindingDown","fDown","Keyboard8080.STATE.CTRL","style","fontWeight","checkModifierKeys","timerReleaseKeys","checkSoftKeysToRelease","aKeysActive","Keyboard8080.VT100.MODEL","bVT100Status","bVT100Address","nVT100UARTCycleSnap","Keyboard8080.SI1978.MODEL","Keyboard8080.VT100.STATUS.LEDS","STATUS","LEDS","iKeyNext","bLEDs","bitLED","fOn","backgroundColor","color","fRight","Keyboard8080.STATE.RSHIFT","Keyboard8080.STATE.SHIFT","Keyboard8080.STATE.RCTRL","Keyboard8080.STATE.RALT","Keyboard8080.STATE.ALT","Keyboard8080.STATE.RCMD","Keyboard8080.STATE.CMD","fPass","LOCATION","getSoftCode","ALTCODES","sSoftCode","metaKey","fRemapped","Keyboard8080.STATE.ALTS","Keyboard8080.STATE.REMAPPED","Keyboard8080.STATE.CTRLS","fAutoRelease","indexOfSoftKey","msDown","Keyboard8080.MINPRESSTIME","ChipSet8080.SI1978.STATUS1.P1","ChipSet8080.SI1978.STATUS1.P2","ChipSet8080.SI1978.STATUS1.CREDIT","ChipSet8080.SI1978.STATUS1.P1_LEFT","ChipSet8080.SI1978.STATUS1.P1_RIGHT","ChipSet8080.SI1978.STATUS1.P1_FIRE","msDelayMin","inVT100UARTAddress","key","Keyboard8080.VT100.KEYMAP","Keyboard8080.VT100.KEYLAST","KEYLAST","outVT100UARTStatus","Keyboard8080.VT100.STATUS.START","START","RSHIFT","SHIFT","SHIFTS","RCTRL","CTRL","CTRLS","RALT","ALT","ALTS","RCMD","CAPS_LOCK","REMAPPED","Keyboard8080.WASDCODES","Keys.ASCII.D","Keys.ASCII.L","Keyboard8080.SI1978","Keyboard8080.VT100","Keys.ASCII.P","Keys.ASCII.O","Keys.ASCII.Y","Keys.ASCII.T","Keys.ASCII.W","Keys.ASCII.Q","Keys.ASCII.I","Keys.ASCII.U","Keys.ASCII.R","Keys.ASCII.E","Keys.ASCII.K","Keys.ASCII.G","Keys.ASCII.F","Keys.KEYCODE.NUM_CR","Keys.ASCII.J","Keys.ASCII.H","Keys.ASCII.S","Keys.ASCII.N","Keys.ASCII.B","Keys.ASCII.X","Keys.ASCII.M","Keys.ASCII","Keys.ASCII.V","Keys.ASCII.C","Keys.ASCII.p","Keys.ASCII.o","Keys.ASCII.y","Keys.ASCII.t","Keys.ASCII.w","Keys.ASCII.q","Keys.ASCII.i","Keys.ASCII.u","Keys.ASCII.r","Keys.ASCII.e","Keys.ASCII.l","Keys.ASCII.k","Keys.ASCII.g","Keys.ASCII.f","Keys.ASCII.j","Keys.ASCII.h","Keys.ASCII.d","Keys.ASCII.s","Keys.ASCII.n","Keys.ASCII.b","Keys.ASCII.x","Keys.ASCII.m","Keys.ASCII.v","Keys.ASCII.c","ADDRESS","LED4","LED3","LED2","LED1","LOCKED","LOCAL","CLICK","Keyboard8080.VT100.LEDCODES","Keyboard8080.VT100.STATUS.LED4","Keyboard8080.VT100.STATUS.LED3","Keyboard8080.VT100.STATUS.LED2","Keyboard8080.VT100.STATUS.LED1","Keyboard8080.VT100.STATUS.LOCKED","Keyboard8080.VT100.STATUS.LOCAL","Keyboard8080.VT100.INIT","Keyboard8080.VT100.STATUS.INIT","Keyboard8080.VT100.ADDRESS.INIT","Keyboard8080.VT100.portsInput","Keyboard8080.VT100.portsOutput","aeKbd","iKbd","eKbd","Video8080","parmsVideo","canvas","context","textarea","container","fGecko","cxScreen","cyScreen","addrBuffer","fUseRAM","nFormat","Video8080.FORMATS","Video8080.FORMAT.UNKNOWN","nRowsBuffer","cyCell","abFontData","fDotStretcher","nBitsPerPixel","iBitFirstPixel","rotateBuffer","rateInterrupt","rateRefresh","canvasScreen","contextScreen","inputScreen","textareaScreen","cxScreenOffset","cyScreenOffset","cxScreenCell","cyScreenCell","fSmoothing","sSmoothing","Web.getURLParm","Web.findProperty","rotateScreen","translate","rotate","PI","scale","doFullScreen","sFullScreen","addEventListener","onFullScreenChange","notifyFullScreen","onFullScreenError","sFontROM","ledBindings","cxBuffer","cyBuffer","sizeBuffer","imageBuffer","createImageData","nPixelsPerCell","initCellCache","canvasBuffer","createElement","width","height","contextBuffer","getContext","aFonts","initColors","nColors","aRGB","Video8080.COLORS.OVERLAY_TOTAL","rgbBlack","rgbWhite","Video8080.FORMAT.SI1978","Video8080.COLORS.OVERLAY_TOP","rgbYellow","Video8080.COLORS.OVERLAY_BOTTOM","rgbGreen","Video8080.FORMAT.VT100","fUnderline","abLineBuffer","Video8080.prototype","removeChild","timerUpdateNext","max","getRefreshTime","nUpdates","sFontData","Video8080.VT100.FONT.NORML","createFontVariation","Video8080.VT100.FONT.DWIDE","Video8080.VT100.FONT.DHIGH","Video8080.VT100.FONT.DHIGH_BOT","nFontBytesPerChar","nFontByteOffset","nChars","fReverse","font","imageChar","iChar","yDst","offFontData","bits","bitPrev","xDst","bitReal","setPixel","putImageData","sWidth","screen","aspectPhys","aspectVirt","display","margin","sHeight","setFocus","focus","fFullScreen","nCells","nCellCache","fCellCacheValid","aCellCache","image","bPixel","rgb","fForced","fUpdate","fClean","updateScreenText","fontNext","nFill","cUpdated","iCell","iCellUpdated","nColsVisible","Video8080.VT100.LINETERM","Video8080.VT100.LINEATTR.FONTMASK","Video8080.VT100.LINEATTR.ADDRMASK","Video8080.VT100.LINEATTR.ADDRBIAS","Video8080.VT100.ADDRBIAS_LO","Video8080.VT100.ADDRBIAS_HI","fLineCacheValid","iCol","bChar","xSrc","ySrc","cxSrc","cySrc","cxDst","cyDst","drawImage","xScreenOffset","yScreenOffset","updateScreenGraphics","addrLimit","yBuffer","xBuffer","xDirty","xMaxDirty","yDirty","nShiftInit","yMaxDirty","nShiftPixel","nMask","cPixels","cxDirty","xDirtyOrig","cxDirtyOrig","cyDirty","OVERLAY_TOP","OVERLAY_BOTTOM","OVERLAY_TOTAL","UNKNOWN","SI1978","VT100","NORML","FONT","DWIDE","DHIGH","DHIGH_BOT","LINETERM","ADDRMASK","LINEATTR","ADDRBIAS","FONTMASK","ADDRBIAS_LO","ADDRBIAS_HI","aeVideo","iVideo","eVideo","eCanvas","innerHTML","setAttribute","onresize","eParent","eChild","cx","cy","onResizeVideo","clientWidth","aspect","aspectRatio","onResizeWindow","appendChild","eTextArea","fontSize","eContext","SerialPort8080","parmsSerial","iAdapter","portBase","nIRQ","controlBuffer","consoleBuffer","tabSize","charBOL","iLogicalCol","fAutoStop","fNullModem","target","sDataReceived","connection","initConnection","receiveData","receiveStatus","SerialPort8080.prototype","ctrlKey","receiveByte","which","removeAttribute","timerReceiveNext","timerTransmitNext","SerialPort8080.aPortInput","SerialPort8080.aPortOutput","sConnection","asParts","sSourceID","Str.trim","sTargetID","fnConnect","initState","saveRegisters","bDataIn","bDataOut","bMode","bCommand","bBaudRates","SerialPort8080.UART8251.INIT","getBaudTimeout","maskRate","indexRate","nBaud","SerialPort8080.UART8251.BAUDTABLE","nBits","SerialPort8080.UART8251.MODE.DATA_BITS","SerialPort8080.UART8251.MODE.PARITY_ENABLE","SerialPort8080.UART8251.MODE.STOP_BITS","SerialPort8080.UART8251.STATUS.RECV_FULL","charCodeAt","SerialPort8080.UART8251.BAUDRATES.RECV_RATE","pins","SerialPort8080.UART8251.STATUS.DSR","DSR","SerialPort8080.UART8251.STATUS.XMIT_EMPTY","inData","inControl","outData","transmitByte","CR","LF","Str.pad","SerialPort8080.UART8251.BAUDRATES.XMIT_RATE","outControl","SerialPort8080.UART8251.COMMAND.RTS","SerialPort8080.UART8251.COMMAND.DTR","CTS","RTS","DTR","SerialPort8080.UART8251.COMMAND.INTERNAL_RESET","outBaudRates","DATA_BITS","MODE","PARITY_ENABLE","STOP_BITS","COMMAND","INTERNAL_RESET","XMIT_READY","RECV_FULL","XMIT_EMPTY","RECV_RATE","BAUDRATES","XMIT_RATE","BAUDTABLE","aeSerial","iSerial","eSerial","Debugger","parmsDbg","nBase","achGroup","achAddress","cOpcodes","cOpcodesStart","fAssemble","iPrevCmd","aPrevCmds","aVariables","getRegIndex","getRegValue","parseCommand","sCmd","chSep","iPrev","chQuote","substring","truncate","fUnsigned","vNew","limit","evalOps","aVals","cOps","chOp","pop","val2","val1","valNew","parseArray","asValues","iValue","iLimit","aUndefined","fError","nUnary","nBasePrev","sOp","parseValue","cOpen","iStart","parseUnary","aBinOp","Debugger.aDECOpPrecedence","Debugger.aBinOpPrecedence","parseASCII","sExp","chDelim","toStrBase","parseExpression","fQuiet","fPrint","join","regExp","printValue","parseReference","chOpen","chClose","chEscape","chInnerEscape","reSubExp","sReplace","sAddr","parseSysVars","iReg","getVariable","sVar","sUndefined","getVariableFixup","valueUndefined","fDefined","printVariable","cVariables","aVars","keys","sort","Debugger8080","Debugger8080.STYLE_8080","dbgAddrNextCode","newAddr","dbgAddrNextData","dbgAddrAssemble","aBreakExec","clearBreakpoints","nBreakIns","historyInit","afnDumpers","messageInit","global","Debugger8080.prototype","sMessages","aaOpDescs","Debugger8080.aaOpDescs","onDumpBus","asArgs","getAddr","parseAddr","ADDR_INVALID","typePrev","cPrev","controlDebug","setSelectionRange","Web.onClickRepeat","onClickDebugEnter","onClickStep","fRepeat","fCompleted","dbgAddr","Debugger8080_prototype$getByte","inc","incAddr","Debugger8080_prototype$getShort","Debugger8080_prototype$setByte","Debugger8080_prototype$setShort","fTemporary","unpackAddr","aAddr","fCode","dbgAddrNext","sUpperCase","iTable","findSymbolAddr","parseAddrOptions","sOptions","aCmds","toHexAddr","getSZ","sEnable","sMessagePrev","aMessageBuffer","aEnable","Usr.indexOf","bitMessage","fnDumper","Debugger8080.REGS","getRegString","Debugger8080.REG_A","Debugger8080.REG_B","Debugger8080.REG_C","Debugger8080.REG_D","Debugger8080.REG_E","Debugger8080.REG_H","Debugger8080.REG_L","Debugger8080.REG_M","Debugger8080.REG_BC","Debugger8080.REG_DE","Debugger8080.REG_HL","Debugger8080.REG_SP","Debugger8080.REG_PC","Debugger8080.REG_PS","Debugger8080.REG_PSW","replaceRegs","sChar","aOpcodeHistory","Debugger8080.HISTORY_LIMIT","iOpcodeHistory","aaOpcodeCounts","isCPUAvail","fRegs","fUpdateCPU","nCyclesStep","exception","nStep","doRegisters","doUnassemble","clearTempBreakpoint","msStart","nCyclesStart","sStopped","msTotal","nState","bOpcode","nSuppressBreaks","aBreak","findBreakpoint","printBreakpoint","fFound","dbgAddrBreak","listBreakpoints","sAction","fBreak","addrBreak","doCommand","getInstruction","sComment","nSequence","dbgAddrIns","aOpDesc","sOperands","sOpcode","asOpcodes","Debugger8080.STYLE_8086","Debugger8080.INS_NAMES","Debugger8080.INS_NAMES_8086","iIns","cOperands","typeSizeDefault","Debugger8080.TYPE_NONE","iOperand","sOperand","Debugger8080.TYPE_OPT","typeMode","Debugger8080.TYPE_MODE","typeSize","Debugger8080.TYPE_SIZE","Debugger8080.TYPE_OTHER","Debugger8080.TYPE_OUT","Debugger8080.TYPE_IN","Debugger8080.TYPE_IMM","getImmOperand","Debugger8080.TYPE_BYTE","Debugger8080.TYPE_SBYTE","Debugger8080.TYPE_WORD","Debugger8080.TYPE_MEM","Debugger8080.TYPE_REG","Debugger8080.TYPE_IREG","getRegOperand","Debugger8080.TYPE_INT","sBytes","sLine","Debugger8080.TYPE_UNDOC","getFlagOutput","sFlag","getRegOutput","getRegDump","p1","p2","findSymbol","fNearest","aSymbol","addrSymbol","result","returnSymbol","iOffset","doFreqs","cData","aaSortedOpcodeCounts","cFreq","doVar","delVariable","setVariable","doList","nDelta","sDelta","doOptions","fInstruction","sRegMatch","doPrint","doTrace","sCount","nCount","Web.onCountRepeat","onCountStep","onCountStepComplete","sAddrEnd","cb","dbgAddrEnd","cLines","sInstruction","sLabel","s0","ch0","unshift","doAssemble","aOpBytes","doBreak","cBreaks","doClear","controlPrint","sLen","sDumpers","doDump","sState","powerOff","sSymbolOrig","sCmdDumpPrev","sMore","cHistory","iHistory","aHistory","nPrev","sPrev","nextHistory","nLines","sLines","aFilters","dbgAddrNew","cOverrides","iByte","sChars","mask","fnGet","doEdit","fnSet","vOld","doRun","doHalt","sMsg","doIf","doInt","sLevel","sPort","doInput","doStackTrace","cFrames","dbgAddrCall","dbgAddrStack","nFrames","sCall","cTests","addrOrig","sCallPrev","fCriteria","sCategory","doMessages","sCategories","fEnabled","doOutput","sByte","doStep","Debugger8080.COMMANDS","doHelp","Debugger8080.TYPE_A","Debugger8080.TYPE_B","Debugger8080.TYPE_C","Debugger8080.TYPE_D","Debugger8080.TYPE_E","Debugger8080.TYPE_H","Debugger8080.TYPE_L","Debugger8080.TYPE_M","Debugger8080.TYPE_BC","Debugger8080.TYPE_DE","Debugger8080.TYPE_HL","Debugger8080.TYPE_SP","Debugger8080.TYPE_PSW","NOP","LXI","STAX","INX","INR","DCR","MVI","RLC","DAD","LDAX","DCX","RRC","RAL","RAR","SHLD","Debugger8080.TYPE_ADDR","DAA","LHLD","CMA","STA","STC","LDA","CMC","MOV","HLT","ADD","ADC","SUB","SBB","ANA","XRA","ORA","CMP","RNZ","POP","JNZ","JMP","CNZ","PUSH","ADI","RST","RZ","RET","JZ","CZ","CALL","ACI","RNC","JNC","OUT","CNC","SUI","RC","JC","IN","CC","SBI","RPO","JPO","XTHL","CPO","ANI","RPE","PCHL","JPE","XCHG","CPE","XRI","RP","JP","DI","CP","ORI","RM","SPHL","JM","EI","CM","CPI","aeDbg","iDbg","eDbg","Computer8080","parmsComputer","parmsMachine","fSuspended","setMachineParms","fAutoPower","nPowerChange","resume","Computer8080.RESUME_NONE","sStateData","fServerState","fStateData","url","random","sUserID","queryUserID","sStatePath","sResume","sResumePath","fAllowResume","stateComputer","APPVERSION","load","getServerStatePath","sResource","wait","powerOn","parmsComponent","sParmLC","Computer8080.prototype","onComponentReady","validateState","stateValidate","Computer8080.STATE_VALIDATE","sTimestampValidate","get","Computer8080.STATE_TIMESTAMP","sTimestampComputer","clear","Computer8080.RESUME_AUTO","fRestore","fRestoreError","Computer8080.RESUME_REPOWER","stateFailSafe","Computer8080.STATE_FAILSAFE","powerReport","Computer8080.RESUME_PROMPT","unload","Usr.formatDate","store","fValidate","Component.confirmUser","sCode","RES","CODE","FAIL","Web.setLocalStorageItem","Computer8080.STATE_USERID","resetUserID","powerRestore","donePowerOn","reload","asComments","fInitialized","controlPower","getUserID","dataPost","QUERY","APPNAME","sUser","TYPE","sReport","sReportURL","sTimestamp","Computer8080.STATE_VERSION","Computer8080.STATE_HOSTURL","href","Computer8080.STATE_BROWSER","fClearAll","fClear","saveServerState","Computer8080.RESUME_DELETE","Str.endsWith","fPrompt","Web.getLocalStorageItem","prompt","verifyUserID","code","State.key","REQ","storeServerState","ENDPOINT","sError","fScroll","scrollX","scrollY","scrollTo","getSpeedCurrent","aeMachines","iMachine","eMachine","aeComputers","iComputer","eComputer","show","exit","sVersion","json","fLoaded","fParsed","State.prototype","Web.hasLocalStorage","stringify","fAll","cAsyncMachines","loadXML","sXMLFile","fResolve","doneLoadXML","sURLName","sXML","parseXML","buildXML","pathname","xmlDoc","async","parseFromString","DOMParser","resolveXML","matchRef","reRef","sRefFile","doneReadXML","sXMLRef","sRefAttrs","aXMLRefTag","sXMLNewTag","matchAttr","reAttr","embedMachine","sXSLFile","displayMessage","eWarning","aeWarning","Str.escapeHTML","displayError","Web.enablePageEvents","getElementById","css","head","styleSheet","cssText","createTextNode","processXML","xml","transformXML","sXSL","xsl","sFragment","outerHTML","implementation","createDocument","xsltProcessor","XSLTProcessor","eFragment","replaceChild","embedPC8080","commandMachine","fSingle","sComponent","sToken","disabled"],"sourcesContent":["\"use strict\";\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/defines.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @define {string}\n */\nvar APPVERSION = \"\"; // this @define is overridden by the Closure Compiler with the version in machines.json\n\nvar XMLVERSION = null; // this is set in non-COMPILED builds by embedMachine() if a version number was found in the machine XML\n\nvar COPYRIGHT = \"Copyright © 2012-2018 Jeff Parsons <Jeff@pcjs.org>\";\n\nvar LICENSE = \"License: GPL version 3 or later <http://gnu.org/licenses/gpl.html>\";\n\nvar CSSCLASS = \"pcjs\";\n\n/**\n * @define {string}\n */\nvar SITEHOST = \"localhost:8088\";// this @define is overridden by the Closure Compiler with \"www.pcjs.org\"\n\n/**\n * @define {boolean}\n */\nvar COMPILED = false; // this @define is overridden by the Closure Compiler (to true)\n\n/**\n * @define {boolean}\n */\nvar DEBUG = true; // this @define is overridden by the Closure Compiler (to false) to remove DEBUG-only code\n\n/**\n * @define {boolean}\n */\nvar MAXDEBUG = false; // this @define is overridden by the Closure Compiler (to false) to remove MAXDEBUG-only code\n\n/**\n * @define {boolean}\n */\nvar PRIVATE = false; // this @define is overridden by the Closure Compiler (to false) to enable PRIVATE code\n\n/*\n * RS-232 DB-25 Pin Definitions, mapped to bits 1-25 in a 32-bit status value.\n *\n * SerialPorts in PCjs machines are considered DTE (Data Terminal Equipment), which means they should be \"virtually\"\n * connected to each other via a null-modem cable, which assumes the following cross-wiring:\n *\n * G 1 <-> 1 G (Ground)\n * TD 2 <-> 3 RD (Received Data)\n * RD 3 <-> 2 TD (Transmitted Data)\n * RTS 4 <-> 5 CTS (Clear To Send)\n * CTS 5 <-> 4 RTS (Request To Send)\n * DSR 6+8 <-> 20 DTR (Data Terminal Ready)\n * SG 7 <-> 7 SG (Signal Ground)\n * DTR 20 <-> 6+8 DSR (Data Set Ready + Carrier Detect)\n * RI 22 <-> 22 RI (Ring Indicator)\n *\n * TODO: Move these definitions to a more appropriate shared file at some point.\n */\nvar RS232 = {\n RTS: {\n PIN: 4,\n MASK: 0x00000010\n },\n CTS: {\n PIN: 5,\n MASK: 0x00000020\n },\n DSR: {\n PIN: 6,\n MASK: 0x00000040\n },\n CD: {\n PIN: 8,\n MASK: 0x00000100\n },\n DTR: {\n PIN: 20,\n MASK: 0x00100000\n },\n RI: {\n PIN: 22,\n MASK: 0x00400000\n }\n};\n\n/*\n * NODE should be true if we're running under NodeJS (eg, command-line), false if not (eg, web browser)\n */\nvar NODE = false;\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/dumpapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Our \"DiskDump API\", such as it was, used to look like:\n *\n * http://jsmachines.net/bin/convdisk.php?disk=/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json&format=img\n *\n * To make it (a bit) more \"REST-like\", the above request now looks like:\n *\n * http://www.pcjs.org/api/v1/dump?disk=/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json&format=img\n *\n * Similarly, our \"FileDump API\" used to look like:\n *\n * http://jsmachines.net/bin/convrom.php?rom=/devices/pc/rom/5150/1981-04-24/PCBIOS-REV1.rom&format=json\n *\n * and that request now looks like:\n *\n * http://www.pcjs.org/api/v1/dump?file=/devices/pc/rom/5150/1981-04-24/PCBIOS-REV1.rom&format=json\n *\n * I don't think it makes sense to avoid \"query\" parameters, because blending the path of a disk image with the\n * the rest of the URL would be (a) confusing, and (b) more work to parse.\n */\nvar DumpAPI = {\n ENDPOINT: \"/api/v1/dump\",\n QUERY: {\n DIR: \"dir\", // value is path of a directory (DiskDump only)\n DISK: \"disk\", // value is path of a disk image (DiskDump only)\n FILE: \"file\", // value is path of a ROM image file (FileDump only)\n IMG: \"img\", // alias for DISK\n PATH: \"path\", // value is path of a one or more files (DiskDump only)\n FORMAT: \"format\", // value is one of FORMAT values below\n COMMENTS: \"comments\", // value is either \"true\" or \"false\"\n DECIMAL: \"decimal\", // value is either \"true\" to force all numbers to decimal, \"false\" or undefined otherwise\n MBHD: \"mbhd\", // value is hard drive size in Mb (formerly \"mbsize\") (DiskDump only) (DEPRECATED)\n SIZE: \"size\" // value is target disk size in Kb (supersedes \"mbhd\") (DiskDump only)\n },\n FORMAT: {\n JSON: \"json\", // default\n JSON_GZ: \"gz\", // gzip is currently used ONLY for compressed JSON\n DATA: \"data\", // same as \"json\", but built without JSON.stringify() (DiskDump only)\n HEX: \"hex\", // deprecated\n OCTAL: \"octal\", // displays data as octal words\n BYTES: \"bytes\", // displays data as hex bytes; normally used only when comments are enabled\n WORDS: \"words\", // displays data as hex words; normally used only when comments are enabled\n LONGS: \"longs\", // displays data as dwords\n IMG: \"img\", // returns the raw disk data (ie, using a Buffer object) (DiskDump only)\n ROM: \"rom\" // returns the raw file data (ie, using a Buffer object) (FileDump only)\n }\n};\n\n/*\n * Because we use an overloaded API endpoint (ie, one that's shared with the FileDump module), we must\n * also provide a list of commands which, when combined with the endpoint, define a unique request.\n */\nDumpAPI.asDiskCommands = [DumpAPI.QUERY.DIR, DumpAPI.QUERY.DISK, DumpAPI.QUERY.PATH];\nDumpAPI.asFileCommands = [DumpAPI.QUERY.FILE];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/reportapi.js (C) Jeff Parsons 2012-2018\n */\n\nvar ReportAPI = {\n ENDPOINT: \"/api/v1/report\",\n QUERY: {\n APP: \"app\",\n VER: \"ver\",\n URL: \"url\",\n USER: \"user\",\n TYPE: \"type\",\n DATA: \"data\"\n },\n TYPE: {\n BUG: \"bug\"\n },\n RES: {\n OK: \"Thank you\"\n }\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/userapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Examples of User API requests:\n *\n * web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.VERIFY + '&' + UserAPI.QUERY.USER + '=' + sUser;\n */\nvar UserAPI = {\n ENDPOINT: \"/api/v1/user\",\n QUERY: {\n REQ: \"req\", // specifies a request\n USER: \"user\", // specifies a user ID\n STATE: \"state\", // specifies a state ID\n DATA: \"data\" // specifies state data\n },\n REQ: {\n CREATE: \"create\", // creates a user ID\n VERIFY: \"verify\", // requests verification of a user ID\n STORE: \"store\", // stores a machine state on the server\n LOAD: \"load\" // loads a machine state from the server\n },\n RES: {\n CODE: \"code\",\n DATA: \"data\"\n },\n CODE: {\n OK: \"ok\",\n FAIL: \"error\"\n },\n FAIL: {\n DUPLICATE: \"user already exists\",\n VERIFY: \"unable to verify user\",\n BADSTATE: \"invalid state parameter\",\n NOSTATE: \"no machine state\",\n BADLOAD: \"unable to load machine state\",\n BADSTORE: \"unable to save machine state\"\n }\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/keys.js (C) Jeff Parsons 2012-2018\n */\n\nvar Keys = {\n /*\n * Keys and/or key combinations that generate common ASCII codes.\n *\n * NOTE: If you're looking for a general-purpose ASCII code table, see Str.ASCII in strlib.js;\n * if something's missing, that's probably the more appropriate table to add it to.\n *\n * TODO: The Closure Compiler doesn't inline all references to these values, at least those with\n * quoted property names, which is why I've 'unquoted' as many of them as possible. One solution\n * would be to add mnemonics for all of them, not just the non-printable ones (eg, SPACE instead\n * of ' ', AMP instead of '&', etc.)\n */\n ASCII: {\n BREAK: 0, CTRL_A: 1, CTRL_B: 2, CTRL_C: 3, CTRL_D: 4, CTRL_E: 5, CTRL_F: 6, CTRL_G: 7,\n CTRL_H: 8, CTRL_I: 9, CTRL_J: 10, CTRL_K: 11, CTRL_L: 12, CTRL_M: 13, CTRL_N: 14, CTRL_O: 15,\n CTRL_P: 16, CTRL_Q: 17, CTRL_R: 18, CTRL_S: 19, CTRL_T: 20, CTRL_U: 21, CTRL_V: 22, CTRL_W: 23,\n CTRL_X: 24, CTRL_Y: 25, CTRL_Z: 26, ESC: 27,\n ' ': 32, '!': 33, '\"': 34, '#': 35, '$': 36, '%': 37, '&': 38, \"'\": 39,\n '(': 40, ')': 41, '*': 42, '+': 43, ',': 44, '-': 45, '.': 46, '/': 47,\n '0': 48, '1': 49, '2': 50, '3': 51, '4': 52, '5': 53, '6': 54, '7': 55,\n '8': 56, '9': 57, ':': 58, ';': 59, '<': 60, '=': 61, '>': 62, '?': 63,\n '@': 64, A: 65, B: 66, C: 67, D: 68, E: 69, F: 70, G: 71,\n H: 72, I: 73, J: 74, K: 75, L: 76, M: 77, N: 78, O: 79,\n P: 80, Q: 81, R: 82, S: 83, T: 84, U: 85, V: 86, W: 87,\n X: 88, Y: 89, Z: 90, '[': 91, '\\\\':92, ']': 93, '^': 94, '_': 95,\n '`': 96, a: 97, b: 98, c: 99, d: 100, e: 101, f: 102, g: 103,\n h: 104, i: 105, j: 106, k: 107, l: 108, m: 109, n: 110, o: 111,\n p: 112, q: 113, r: 114, s: 115, t: 116, u: 117, v: 118, w: 119,\n x: 120, y: 121, z: 122, '{':123, '|':124, '}':125, '~':126, DEL: 127\n },\n /*\n * Browser keyCodes we must pay particular attention to. For the most part, these are non-alphanumeric\n * or function keys, some which may require special treatment (eg, preventDefault() if returning false on\n * the initial keyDown event is insufficient).\n *\n * keyCodes for most common ASCII keys can simply use the appropriate ASCII code above.\n *\n * Most of these represent non-ASCII keys (eg, the LEFT arrow key), yet for some reason, browsers defined\n * them using ASCII codes (eg, the LEFT arrow key uses the ASCII code for '%' or 37).\n */\n KEYCODE: {\n /* 0x08 */ BS: 8, // BACKSPACE (ASCII.CTRL_H)\n /* 0x09 */ TAB: 9, // TAB (ASCII.CTRL_I)\n /* 0x0A */ LF: 10, // LINE-FEED (ASCII.CTRL_J) (Some Windows-based browsers used to generate this via CTRL-ENTER)\n /* 0x0D */ CR: 13, // CARRIAGE RETURN (ASCII.CTRL_M)\n /* 0x10 */ SHIFT: 16,\n /* 0x11 */ CTRL: 17,\n /* 0x12 */ ALT: 18,\n /* 0x13 */ PAUSE: 19, // PAUSE/BREAK\n /* 0x14 */ CAPS_LOCK: 20,\n /* 0x1B */ ESC: 27,\n /* 0x20 */ SPACE: 32,\n /* 0x21 */ PGUP: 33,\n /* 0x22 */ PGDN: 34,\n /* 0x23 */ END: 35,\n /* 0x24 */ HOME: 36,\n /* 0x25 */ LEFT: 37,\n /* 0x26 */ UP: 38,\n /* 0x27 */ RIGHT: 39,\n /* 0x27 */ FF_QUOTE: 39,\n /* 0x28 */ DOWN: 40,\n /* 0x2C */ FF_COMMA: 44,\n /* 0x2C */ PRTSC: 44,\n /* 0x2D */ INS: 45,\n /* 0x2E */ DEL: 46,\n /* 0x2E */ FF_PERIOD: 46,\n /* 0x2F */ FF_SLASH: 47,\n /* 0x30 */ ZERO: 48,\n /* 0x31 */ ONE: 49,\n /* 0x32 */ TWO: 50,\n /* 0x33 */ THREE: 51,\n /* 0x34 */ FOUR: 52,\n /* 0x35 */ FIVE: 53,\n /* 0x36 */ SIX: 54,\n /* 0x37 */ SEVEN: 55,\n /* 0x38 */ EIGHT: 56,\n /* 0x39 */ NINE: 57,\n /* 0x3B */ FF_SEMI: 59,\n /* 0x3D */ FF_EQUALS: 61,\n /* 0x5B */ CMD: 91, // aka WIN\n /* 0x5B */ FF_LBRACK: 91,\n /* 0x5C */ FF_BSLASH: 92,\n /* 0x5D */ RCMD: 93, // aka MENU\n /* 0x5D */ FF_RBRACK: 93,\n /* 0x60 */ NUM_0: 96,\n /* 0x60 */ NUM_INS: 96,\n /* 0x60 */ FF_BQUOTE: 96,\n /* 0x61 */ NUM_1: 97,\n /* 0x61 */ NUM_END: 97,\n /* 0x62 */ NUM_2: 98,\n /* 0x62 */ NUM_DOWN: 98,\n /* 0x63 */ NUM_3: 99,\n /* 0x63 */ NUM_PGDN: 99,\n /* 0x64 */ NUM_4: 100,\n /* 0x64 */ NUM_LEFT: 100,\n /* 0x65 */ NUM_5: 101,\n /* 0x65 */ NUM_CENTER: 101,\n /* 0x66 */ NUM_6: 102,\n /* 0x66 */ NUM_RIGHT: 102,\n /* 0x67 */ NUM_7: 103,\n /* 0x67 */ NUM_HOME: 103,\n /* 0x68 */ NUM_8: 104,\n /* 0x68 */ NUM_UP: 104,\n /* 0x69 */ NUM_9: 105,\n /* 0x69 */ NUM_PGUP: 105,\n /* 0x6A */ NUM_MUL: 106,\n /* 0x6B */ NUM_ADD: 107,\n /* 0x6D */ NUM_SUB: 109,\n /* 0x6E */ NUM_DEL: 110, // aka PERIOD\n /* 0x6F */ NUM_DIV: 111,\n /* 0x70 */ F1: 112,\n /* 0x71 */ F2: 113,\n /* 0x72 */ F3: 114,\n /* 0x73 */ F4: 115,\n /* 0x74 */ F5: 116,\n /* 0x75 */ F6: 117,\n /* 0x76 */ F7: 118,\n /* 0x77 */ F8: 119,\n /* 0x78 */ F9: 120,\n /* 0x79 */ F10: 121,\n /* 0x7A */ F11: 122,\n /* 0x7B */ F12: 123,\n /* 0x90 */ NUM_LOCK: 144,\n /* 0x91 */ SCROLL_LOCK: 145,\n /* 0xAD */ FF_DASH: 173,\n /* 0xBA */ SEMI: 186, // Firefox: 59 (FF_SEMI)\n /* 0xBB */ EQUALS: 187, // Firefox: 61 (FF_EQUALS)\n /* 0xBC */ COMMA: 188,\n /* 0xBD */ DASH: 189, // Firefox: 173 (FF_DASH)\n /* 0xBE */ PERIOD: 190,\n /* 0xBF */ SLASH: 191,\n /* 0xC0 */ BQUOTE: 192,\n /* 0xDB */ LBRACK: 219,\n /* 0xDC */ BSLASH: 220,\n /* 0xDD */ RBRACK: 221,\n /* 0xDE */ QUOTE: 222,\n /* 0xE0 */ FF_CMD: 224, // Firefox only (used for both CMD and RCMD)\n //\n // The following biases use what I'll call Decimal Coded Binary or DCB (the opposite of BCD),\n // where the thousands digit is used to store the sum of \"binary\" digits 1 and/or 2 and/or 4.\n //\n // Technically, that makes it DCO (Decimal Coded Octal), but then again, BCD should have really\n // been called HCD (Hexadecimal Coded Decimal), so if \"they\" can take liberties, so can I.\n //\n // ONDOWN is a bias we add to browser keyCodes that we want to handle on \"down\" rather than on \"press\".\n //\n ONDOWN: 1000,\n //\n // ONRIGHT is a bias we add to browser keyCodes that need to check for a \"right\" location (default is \"left\")\n //\n ONRIGHT: 2000,\n //\n // FAKE is a bias we add to signal these are fake keyCodes corresponding to internal keystroke combinations.\n // The actual values are for internal use only and merely need to be unique and used consistently.\n //\n FAKE: 4000\n },\n /*\n * The set of values that a browser may store in the 'location' property of a keyboard event object\n * which we also support.\n */\n LOCATION: {\n LEFT: 1,\n RIGHT: 2,\n NUMPAD: 3\n }\n};\n\n/*\n * Check the event object's 'location' property for a non-zero value for the following ONRIGHT keys.\n */\nKeys.KEYCODE.NUM_CR = Keys.KEYCODE.CR + Keys.KEYCODE.ONRIGHT;\n\n\n/*\n * Maps Firefox keyCodes to their more common keyCode counterparts; a number of entries in this table\n * are no longer valid (if indeed they ever were), so they've been commented out. It's likely that I\n * simply extended this table to resolve additional differences in other browsers (ie, Opera), but without\n * browser-specific checks, it's not safe to perform all the mappings shown below.\n */\nKeys.FF_KEYCODES = {};\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_SEMI] = Keys.KEYCODE.SEMI; // 59 -> 186\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_EQUALS] = Keys.KEYCODE.EQUALS; // 61 -> 187\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.KEYCODE.DASH; // 173 -> 189\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_CMD] = Keys.KEYCODE.CMD; // 224 -> 91\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_COMMA] = Keys.KEYCODE.COMMA; // 44 -> 188\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_PERIOD] = Keys.KEYCODE.PERIOD; // 46 -> 190\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_SLASH] = Keys.KEYCODE.SLASH; // 47 -> 191\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_BQUOTE] = Keys.KEYCODE.BQUOTE; // 96 -> 192\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_LBRACK = Keys.KEYCODE.LBRACK; // 91 -> 219\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_BSLASH] = Keys.KEYCODE.BSLASH; // 92 -> 220\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_RBRACK] = Keys.KEYCODE.RBRACK; // 93 -> 221\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_QUOTE] = Keys.KEYCODE.QUOTE; // 39 -> 222\n\n/*\n * Maps non-ASCII keyCodes to their ASCII counterparts\n */\nKeys.NONASCII_KEYCODES = {};\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.ASCII['-']; // 173 -> 45\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.SEMI] = Keys.ASCII[';']; // 186 -> 59\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.EQUALS] = Keys.ASCII['=']; // 187 -> 61\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.DASH] = Keys.ASCII['-']; // 189 -> 45\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.COMMA] = Keys.ASCII[',']; // 188 -> 44\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.PERIOD] = Keys.ASCII['.']; // 190 -> 46\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.SLASH] = Keys.ASCII['/']; // 191 -> 47\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.BQUOTE] = Keys.ASCII['`']; // 192 -> 96\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.LBRACK] = Keys.ASCII['[']; // 219 -> 91\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.BSLASH] = Keys.ASCII['\\\\']; // 220 -> 92\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.RBRACK] = Keys.ASCII[']']; // 221 -> 93\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.QUOTE] = Keys.ASCII[\"'\"]; // 222 -> 39\n\n/*\n * Maps unshifted keyCodes to their shifted counterparts; to be used when a shift-key is down.\n * Alphabetic characters are handled in code, since they must also take CAPS_LOCK into consideration.\n */\nKeys.SHIFTED_KEYCODES = {};\nKeys.SHIFTED_KEYCODES[Keys.ASCII['1']] = Keys.ASCII['!'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['2']] = Keys.ASCII['@'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['3']] = Keys.ASCII['#'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['4']] = Keys.ASCII['$'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['5']] = Keys.ASCII['%'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['6']] = Keys.ASCII['^'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['7']] = Keys.ASCII['&'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['8']] = Keys.ASCII['*'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['9']] = Keys.ASCII['('];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['0']] = Keys.ASCII[')'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.SEMI] = Keys.ASCII[':'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.EQUALS] = Keys.ASCII['+'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.COMMA] = Keys.ASCII['<'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.DASH] = Keys.ASCII['_'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.PERIOD] = Keys.ASCII['>'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.SLASH] = Keys.ASCII['?'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.BQUOTE] = Keys.ASCII['~'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.LBRACK] = Keys.ASCII['{'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.BSLASH] = Keys.ASCII['|'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.RBRACK] = Keys.ASCII['}'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.QUOTE] = Keys.ASCII['\"'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.ASCII['_'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_EQUALS] = Keys.ASCII['+'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_SEMI] = Keys.ASCII[':'];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/strlib.js (C) Jeff Parsons 2012-2018\n */\n\nclass Str {\n /**\n * isValidInt(s, base)\n *\n * The built-in parseInt() function has the annoying feature of returning a partial value (ie,\n * up to the point where it encounters an invalid character); eg, parseInt(\"foo\", 16) returns 0xf.\n *\n * So it's best to use our own Str.parseInt() function, which will in turn use this function to\n * validate the entire string.\n *\n * @param {string} s is the string representation of some number\n * @param {number} [base] is the radix to use (default is 10); only 2, 8, 10 and 16 are supported\n * @return {boolean} true if valid, false if invalid (or the specified base isn't supported)\n */\n static isValidInt(s, base)\n {\n if (!base || base == 10) return s.match(/^-?[0-9]+$/) !== null;\n if (base == 16) return s.match(/^-?[0-9a-f]+$/i) !== null;\n if (base == 8) return s.match(/^-?[0-7]+$/) !== null;\n if (base == 2) return s.match(/^-?[01]+$/) !== null;\n return false;\n }\n\n /**\n * parseInt(s, base)\n *\n * This is a wrapper around the built-in parseInt() function. Our wrapper recognizes certain prefixes\n * ('$' or \"0x\" for hex, '#' or \"0o\" for octal) and suffixes ('.' for decimal, 'h' for hex, 'y' for\n * binary), and then calls isValidInt() to ensure we don't convert strings that contain partial values;\n * see isValidInt() for details.\n *\n * The use of multiple prefix/suffix combinations is undefined (although for the record, we process\n * prefixes first). We do NOT support the \"0b\" prefix to indicate binary UNLESS one or more commas are\n * also present (because \"0b\" is also a valid hex sequence), and we do NOT support a single leading zero\n * to indicate octal (because such a number could also be decimal or hex). Any number of commas are\n * allowed; we remove them all before calling the built-in parseInt().\n *\n * More recently, we've added support for \"^D\", \"^O\", and \"^B\" prefixes to accommodate the base overrides\n * that the PDP-10's MACRO-10 assembly language supports (decimal, octal, and binary, respectively).\n * If this support turns out to adversely affect other debuggers, then it will have to be \"conditionalized\".\n * Similarly, we've added support for \"K\", \"M\", and \"G\" MACRO-10-style suffixes that add 3, 6, or 9 zeros\n * to the value to be parsed, respectively.\n *\n * @param {string} s is the string representation of some number\n * @param {number} [base] is the radix to use (default is 10); can be overridden by prefixes/suffixes\n * @return {number|undefined} corresponding value, or undefined if invalid\n */\n static parseInt(s, base)\n {\n var value;\n\n if (s) {\n if (!base) base = 10;\n\n var ch, chPrefix, chSuffix;\n var fCommas = (s.indexOf(',') > 0);\n if (fCommas) s = s.replace(/,/g, '');\n\n ch = chPrefix = s.charAt(0);\n if (chPrefix == '#') {\n base = 8;\n chPrefix = '';\n }\n else if (chPrefix == '$') {\n base = 16;\n chPrefix = '';\n }\n if (ch != chPrefix) {\n s = s.substr(1);\n }\n else {\n ch = chPrefix = s.substr(0, 2);\n if (chPrefix == '0b' && fCommas || chPrefix == '^B') {\n base = 2;\n chPrefix = '';\n }\n else if (chPrefix == '0o' || chPrefix == '^O') {\n base = 8;\n chPrefix = '';\n }\n else if (chPrefix == '^D') {\n base = 10;\n chPrefix = '';\n }\n else if (chPrefix == '0x') {\n base = 16;\n chPrefix = '';\n }\n if (ch != chPrefix) s = s.substr(2);\n }\n ch = chSuffix = s.slice(-1);\n if (chSuffix == 'Y' || chSuffix == 'y') {\n base = 2;\n chSuffix = '';\n }\n else if (chSuffix == '.') {\n base = 10;\n chSuffix = '';\n }\n else if (chSuffix == 'H' || chSuffix == 'h') {\n base = 16;\n chSuffix = '';\n }\n else if (chSuffix == 'K') {\n chSuffix = '000';\n }\n else if (chSuffix == 'M') {\n chSuffix = '000000';\n }\n else if (chSuffix == 'G') {\n chSuffix = '000000000';\n }\n if (ch != chSuffix) s = s.slice(0, -1) + chSuffix;\n /*\n * This adds support for the MACRO-10 binary shifting (Bn) suffix, which must be stripped from the\n * number before parsing, and then applied to the value after parsing. If n is omitted, 35 is assumed,\n * which is a net shift of zero. If n < 35, then a left shift of (35 - n) is required; if n > 35, then\n * a right shift of -(35 - n) is required.\n */\n var v, shift = 0;\n if (base <= 10) {\n var match = s.match(/(-?[0-9]+)B([0-9]*)/);\n if (match) {\n s = match[1];\n shift = 35 - ((match[2] || 35) & 0xff);\n }\n }\n if (Str.isValidInt(s, base) && !isNaN(v = parseInt(s, base))) {\n /*\n * With the need to support larger (eg, 36-bit) integers, truncating to 32 bits is no longer helpful.\n *\n * value = v|0;\n */\n if (shift) {\n /*\n * Since binary shifting is a logical operation, and since shifting by division only works properly\n * with positive numbers, we must convert a negative value to a positive value, by computing the two's\n * complement.\n */\n if (v < 0) v += Math.pow(2, 36);\n if (shift > 0) {\n v *= Math.pow(2, shift);\n } else {\n v = Math.trunc(v / Math.pow(2, -shift));\n }\n }\n value = v;\n }\n }\n return value;\n }\n\n /**\n * toBase(n, radix, cch, sPrefix, nGrouping)\n *\n * Displays the given number as an unsigned integer using the specified radix and number of digits.\n *\n * @param {number|null|undefined} n\n * @param {number} radix (ie, the base)\n * @param {number} cch (the desired number of digits)\n * @param {string} [sPrefix] (default is none)\n * @param {number} [nGrouping]\n * @return {string}\n */\n static toBase(n, radix, cch, sPrefix = \"\", nGrouping = 0)\n {\n /*\n * An initial \"falsey\" check for null takes care of both null and undefined;\n * we can't rely entirely on isNaN(), because isNaN(null) returns false, oddly enough.\n *\n * Alternatively, we could mask and shift n regardless of whether it's null/undefined/NaN,\n * since JavaScript coerces such operands to zero, but I think there's \"value\" in seeing those\n * values displayed differently.\n */\n var s = \"\";\n if (isNaN(n)) {\n n = null;\n } else if (n != null) {\n /*\n * Callers that produced an input by dividing by a power of two rather than shifting (in order\n * to access more than 32 bits) may produce a fractional result, which ordinarily we would simply\n * ignore, but if the integer portion is zero and the sign is negative, we should probably treat\n * this value as a sign-extension.\n */\n if (n < 0 && n > -1) n = -1;\n /*\n * Negative values should be two's complemented according to the number of digits; for example,\n * 12 octal digits implies an upper limit 8^12.\n */\n if (n < 0) {\n n += Math.pow(radix, cch);\n }\n if (n >= Math.pow(radix, cch)) {\n cch = Math.ceil(Math.log(n) / Math.log(radix));\n }\n }\n var g = nGrouping || -1;\n while (cch-- > 0) {\n if (!g) {\n s = ',' + s;\n g = nGrouping;\n }\n if (n == null) {\n s = '?' + s;\n } else {\n var d = n % radix;\n d += (d >= 0 && d <= 9? 0x30 : 0x41 - 10);\n s = String.fromCharCode(d) + s;\n n = Math.trunc(n / radix);\n }\n g--;\n }\n return sPrefix + s;\n }\n\n /**\n * toBin(n, cch, nGrouping)\n *\n * Converts an integer to binary, with the specified number of digits (up to a maximum of 36).\n *\n * @param {number|null|undefined} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of binary digits (0 or undefined for default of either 8, 18, or 36)\n * @param {number} [nGrouping]\n * @return {string} the binary representation of n\n */\n static toBin(n, cch, nGrouping)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.LN2) || 1;\n var v = Math.abs(n);\n if (v <= 0b11111111) {\n cch = 8;\n } else if (v <= 0b111111111111111111) {\n cch = 18;\n } else {\n cch = 36;\n }\n } else if (cch > 36) cch = 36;\n return Str.toBase(n, 2, cch, \"\", nGrouping);\n }\n\n /**\n * toBinBytes(n, cb, fPrefix)\n *\n * Converts an integer to binary, with the specified number of bytes (up to the default of 4).\n *\n * @param {number|null|undefined} n (interpreted as a 32-bit value)\n * @param {number} [cb] is the desired number of binary bytes (4 is both the default and the maximum)\n * @param {boolean} [fPrefix]\n * @return {string} the binary representation of n\n */\n static toBinBytes(n, cb, fPrefix)\n {\n var s = \"\";\n if (!cb || cb > 4) cb = 4;\n for (var i = 0; i < cb; i++) {\n if (s) s = ',' + s;\n s = Str.toBin(n & 0xff, 8) + s;\n n >>= 8;\n }\n return (fPrefix? \"0b\" : \"\") + s;\n }\n\n /**\n * toOct(n, cch, fPrefix)\n *\n * Converts an integer to octal, with the specified number of digits (default of 6; max of 12)\n *\n * You might be tempted to use the built-in n.toString(8) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw\n * an exception, whereas this function will return '?' characters.\n *\n * @param {number|null|undefined} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of octal digits (0 or undefined for default of either 6, 8, or 12)\n * @param {boolean} [fPrefix]\n * @return {string} the octal representation of n\n */\n static toOct(n, cch, fPrefix)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.log(8)) || 1;\n var v = Math.abs(n);\n if (v <= 0o777777) {\n cch = 6;\n } else if (v <= 0o77777777) {\n cch = 8;\n } else {\n cch = 12;\n }\n } else if (cch > 12) cch = 12;\n return Str.toBase(n, 8, cch, fPrefix? \"0o\" : \"\");\n }\n\n /**\n * toDec(n, cch)\n *\n * Converts an integer to decimal, with the specified number of digits (default of 5; max of 11)\n *\n * You might be tempted to use the built-in n.toString(10) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw\n * an exception, whereas this function will return '?' characters.\n *\n * @param {number|null|undefined} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of decimal digits (0 or undefined for default of either 5 or 11)\n * @return {string} the decimal representation of n\n */\n static toDec(n, cch)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.LN10) || 1;\n var v = Math.abs(n);\n if (v <= 99999) {\n cch = 5;\n } else {\n cch = 11;\n }\n } else if (cch > 11) cch = 11;\n return Str.toBase(n, 10, cch);\n }\n\n /**\n * toHex(n, cch, fPrefix)\n *\n * Converts an integer to hex, with the specified number of digits (default of 4 or 8, max of 9).\n *\n * You might be tempted to use the built-in n.toString(16) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values; for example, if n is -2147483647, then n.toString(16)\n * will return \"-7fffffff\" instead of \"80000001\". Moreover, if n is undefined, n.toString() will\n * throw an exception, whereas this function will return '?' characters.\n *\n * NOTE: The following work-around (adapted from code found on StackOverflow) would be another solution,\n * taking care of negative values, zero-padding, and upper-casing, but not null/undefined/NaN values:\n *\n * s = (n < 0? n + 0x100000000 : n).toString(16);\n * s = \"00000000\".substr(0, 8 - s.length) + s;\n * s = s.substr(0, cch).toUpperCase();\n *\n * @param {number|null|undefined} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of hex digits (0 or undefined for default of either 4, 8, or 9)\n * @param {boolean} [fPrefix]\n * @return {string} the hex representation of n\n */\n static toHex(n, cch, fPrefix)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.log(16)) || 1;\n var v = Math.abs(n);\n if (v <= 0xffff) {\n cch = 4;\n } else if (v <= 0xffffffff) {\n cch = 8;\n } else {\n cch = 9;\n }\n } else if (cch > 9) cch = 9;\n return Str.toBase(n, 16, cch, fPrefix? \"0x\" : \"\");\n }\n\n /**\n * toHexByte(b)\n *\n * Alias for Str.toHex(b, 2, true)\n *\n * @param {number|null|undefined} b is a byte value\n * @return {string} the hex representation of b\n */\n static toHexByte(b)\n {\n return Str.toHex(b, 2, true);\n }\n\n /**\n * toHexWord(w)\n *\n * Alias for Str.toHex(w, 4, true)\n *\n * @param {number|null|undefined} w is a word (16-bit) value\n * @return {string} the hex representation of w\n */\n static toHexWord(w)\n {\n return Str.toHex(w, 4, true);\n }\n\n /**\n * toHexLong(l)\n *\n * Alias for Str.toHex(l, 8, true)\n *\n * @param {number|null|undefined} l is a dword (32-bit) value\n * @return {string} the hex representation of w\n */\n static toHexLong(l)\n {\n return Str.toHex(l, 8, true);\n }\n\n /**\n * getBaseName(sFileName, fStripExt)\n *\n * This is a poor-man's version of Node's path.basename(), which Node-only components should use instead.\n *\n * Note that if fStripExt is true, this strips ANY extension, whereas path.basename() strips the extension only\n * if it matches the second parameter (eg, path.basename(\"/foo/bar/baz/asdf/quux.html\", \".html\") returns \"quux\").\n *\n * @param {string} sFileName\n * @param {boolean} [fStripExt]\n * @return {string}\n */\n static getBaseName(sFileName, fStripExt)\n {\n var sBaseName = sFileName;\n\n var i = sFileName.lastIndexOf('/');\n if (i >= 0) sBaseName = sFileName.substr(i + 1);\n\n /*\n * This next bit is a kludge to clean up names that are part of a URL that includes unsightly query parameters.\n */\n i = sBaseName.indexOf('&');\n if (i > 0) sBaseName = sBaseName.substr(0, i);\n\n if (fStripExt) {\n i = sBaseName.lastIndexOf(\".\");\n if (i > 0) {\n sBaseName = sBaseName.substring(0, i);\n }\n }\n return sBaseName;\n }\n\n /**\n * getExtension(sFileName)\n *\n * This is a poor-man's version of Node's path.extname(), which Node-only components should use instead.\n *\n * Note that we EXCLUDE the period from the returned extension, whereas path.extname() includes it.\n *\n * @param {string} sFileName\n * @return {string} the filename's extension (in lower-case and EXCLUDING the \".\"), or an empty string\n */\n static getExtension(sFileName)\n {\n var sExtension = \"\";\n var i = sFileName.lastIndexOf(\".\");\n if (i >= 0) {\n sExtension = sFileName.substr(i + 1).toLowerCase();\n }\n return sExtension;\n }\n\n /**\n * endsWith(s, sSuffix)\n *\n * @param {string} s\n * @param {string} sSuffix\n * @return {boolean} true if s ends with sSuffix, false if not\n */\n static endsWith(s, sSuffix)\n {\n return s.indexOf(sSuffix, s.length - sSuffix.length) !== -1;\n }\n\n /**\n * escapeHTML(sHTML)\n *\n * @param {string} sHTML\n * @return {string} with HTML entities \"escaped\", similar to PHP's htmlspecialchars()\n */\n static escapeHTML(sHTML)\n {\n return sHTML.replace(/[&<>\"']/g, function(m)\n {\n return Str.HTMLEscapeMap[m];\n });\n }\n\n /**\n * replace(sSearch, sReplace, s)\n *\n * The JavaScript replace() function ALWAYS interprets \"$\" specially in replacement strings, even when\n * the search string is NOT a RegExp; specifically:\n *\n * $$ Inserts a \"$\"\n * $& Inserts the matched substring\n * $` Inserts the portion of the string that precedes the matched substring\n * $' Inserts the portion of the string that follows the matched substring\n * $n Where n is a positive integer less than 100, inserts the nth parenthesized sub-match string,\n * provided the first argument was a RegExp object\n *\n * So, if a replacement string containing dollar signs passes through a series of replace() calls, untold\n * problems could result. Hence, this function, which simply uses the replacement string as-is.\n *\n * Similar to the JavaScript replace() method (when sSearch is a string), this replaces only ONE occurrence\n * (ie, the FIRST occurrence); it might be nice to add options to replace the LAST occurrence and/or ALL\n * occurrences, but we'll revisit that later.\n *\n * @param {string} sSearch\n * @param {string} sReplace\n * @param {string} s\n * @return {string}\n */\n static replace(sSearch, sReplace, s)\n {\n var i = s.indexOf(sSearch);\n if (i >= 0) {\n s = s.substr(0, i) + sReplace + s.substr(i + sSearch.length);\n }\n return s;\n }\n\n /**\n * replaceAll(sSearch, sReplace, s)\n *\n * @param {string} sSearch\n * @param {string} sReplace\n * @param {string} s\n * @return {string}\n */\n static replaceAll(sSearch, sReplace, s)\n {\n var a = {};\n a[sSearch] = sReplace;\n return Str.replaceArray(a, s);\n }\n\n /**\n * replaceArray(a, s)\n *\n * @param {Object} a\n * @param {string} s\n * @return {string}\n */\n static replaceArray(a, s)\n {\n var sMatch = \"\";\n for (var k in a) {\n /*\n * As noted in:\n *\n * http://www.regexguru.com/2008/04/escape-characters-only-when-necessary/\n *\n * inside character classes, only backslash, caret, hyphen and the closing bracket need to be\n * escaped. And in fact, if you ensure that the closing bracket is first, the caret is not first,\n * and the hyphen is last, you can avoid escaping those as well.\n */\n k = k.replace(/([\\\\[\\]*{}().+?|$])/g, \"\\\\$1\");\n sMatch += (sMatch? '|' : '') + k;\n }\n return s.replace(new RegExp('(' + sMatch + ')', \"g\"), function(m)\n {\n return a[m];\n });\n }\n\n /**\n * pad(s, cch, fPadLeft)\n *\n * NOTE: the maximum amount of padding currently supported is 40 spaces.\n *\n * @param {string} s is a string\n * @param {number} cch is desired length\n * @param {boolean} [fPadLeft] (default is padding on the right)\n * @return {string} the original string (s) with spaces padding it to the specified length\n */\n static pad(s, cch, fPadLeft)\n {\n var sPadding = \" \";\n return fPadLeft? (sPadding + s).slice(-cch) : (s + sPadding).slice(0, cch);\n }\n\n /**\n * sprintf(format, ...args)\n *\n * Copied from the CCjs project (https://github.com/jeffpar/ccjs/blob/master/lib/stdio.js) and extended.\n *\n * Far from complete, let alone sprintf-compatible, but it's adequate for the handful of sprintf-style format\n * specifiers that I use.\n *\n * @param {string} format\n * @param {...} args\n * @return {string}\n */\n static sprintf(format, ...args)\n {\n let buffer = \"\";\n let aParts = format.split(/%([-+ 0#]?)([0-9]*)(\\.?)([0-9]*)([hlL]?)([A-Za-z%])/);\n\n let iArg = 0, iPart;\n for (iPart = 0; iPart < aParts.length - 7; iPart += 7) {\n\n buffer += aParts[iPart];\n\n let arg = args[iArg++];\n let flags = aParts[iPart+1];\n let minimum = +aParts[iPart+2] || 0;\n let precision = +aParts[iPart+4] || 0;\n let conversion = aParts[iPart+6];\n let ach = null, s;\n\n switch(conversion) {\n case 'd':\n /*\n * We could use \"arg |= 0\", but there may be some value to supporting integers > 32 bits.\n * \n * Also, unlike the 'X' and 'x' hexadecimal cases, there's no need to explicitly check for a string\n * arguments, because the call to trunc() automatically coerces any string value to a (decimal) number.\n */\n arg = Math.trunc(arg);\n /* falls through */\n\n case 'f':\n s = Math.trunc(arg) + \"\";\n if (precision) {\n minimum -= (precision + 1);\n }\n if (s.length < minimum) {\n if (flags == '0') {\n if (arg < 0) minimum--;\n s = (\"0000000000\" + Math.abs(arg)).slice(-minimum);\n if (arg < 0) s = '-' + s;\n } else {\n s = (\" \" + s).slice(-minimum);\n }\n }\n if (precision) {\n arg = Math.round((arg - Math.trunc(arg)) * Math.pow(10, precision));\n s += '.' + (\"0000000000\" + Math.abs(arg)).slice(-precision);\n }\n buffer += s;\n break;\n\n case 'c':\n arg = String.fromCharCode(arg);\n /* falls through */\n\n case 's':\n if (typeof arg == \"string\") {\n while (arg.length < minimum) {\n if (flags == '-') {\n arg += ' ';\n } else {\n arg = ' ' + arg;\n }\n }\n }\n buffer += arg;\n break;\n\n case 'X':\n ach = Str.HexUpperCase;\n /* falls through */\n\n case 'x':\n if (!ach) ach = Str.HexLowerCase;\n s = \"\";\n if (typeof arg == \"string\") {\n /*\n * Since we're advised to ALWAYS pass a radix to parseInt(), we must detect explicitly\n * hex values ourselves, because using a radix of 10 with any \"0x...\" value always returns 0.\n * \n * And if the value CAN be interpreted as decimal, then we MUST interpret it as decimal, because\n * we have sprintf() calls in /modules/lib/testmon.js that depend on this code to perform decimal\n * to hex conversion. We're allowed to make our own rules here, since passing numbers in string\n * form isn't part of the sprintf \"spec\". \n */\n arg = Number.parseInt(arg, arg.match(/(^0x|[a-f])/i)? 16 : 10);\n } \n do {\n s = ach[arg & 0xf] + s;\n arg >>>= 4;\n } while (--minimum > 0 || arg);\n buffer += s;\n break;\n\n default:\n /*\n * The supported ANSI C set of conversions: \"dioxXucsfeEgGpn%\"\n */\n buffer += \"(unrecognized printf conversion %\" + conversion + \")\";\n break;\n }\n }\n\n buffer += aParts[iPart];\n return buffer;\n }\n\n /**\n * stripLeadingZeros(s, fPad)\n *\n * @param {string} s\n * @param {boolean} [fPad]\n * @return {string}\n */\n static stripLeadingZeros(s, fPad)\n {\n var cch = s.length;\n s = s.replace(/^0+([0-9A-F]+)$/i, \"$1\");\n if (fPad) s = Str.pad(s, cch, true);\n return s;\n }\n\n /**\n * trim(s)\n *\n * @param {string} s\n * @return {string}\n */\n static trim(s)\n {\n if (String.prototype.trim) {\n return s.trim();\n }\n return s.replace(/^\\s+|\\s+$/g, \"\");\n }\n\n /**\n * toASCIICode(b)\n *\n * @param {number} b\n * @return {string}\n */\n static toASCIICode(b)\n {\n var s;\n if (b != Str.ASCII.CR && b != Str.ASCII.LF) {\n s = Str.ASCIICodeMap[b];\n }\n if (s) {\n s = '<' + s + '>';\n } else {\n s = String.fromCharCode(b);\n }\n return s;\n }\n}\n\n/*\n * Map special characters to their HTML escape sequences.\n */\nStr.HTMLEscapeMap = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n};\n\n/*\n * Map \"unprintable\" ASCII codes to mnemonics, to more clearly see what's being printed.\n */\nStr.ASCIICodeMap = {\n 0x00: \"NUL\",\n 0x01: \"SOH\", // (CTRL_A) Start of Heading\n 0x02: \"STX\", // (CTRL_B) Start of Text\n 0x03: \"ETX\", // (CTRL_C) End of Text\n 0x04: \"EOT\", // (CTRL_D) End of Transmission\n 0x05: \"ENQ\", // (CTRL_E) Enquiry\n 0x06: \"ACK\", // (CTRL_F) Acknowledge\n 0x07: \"BEL\", // (CTRL_G) Bell\n 0x08: \"BS\", // (CTRL_H) Backspace\n 0x09: \"TAB\", // (CTRL_I) Horizontal Tab (aka HT)\n 0x0A: \"LF\", // (CTRL_J) Line Feed (New Line)\n 0x0B: \"VT\", // (CTRL_K) Vertical Tab\n 0x0C: \"FF\", // (CTRL_L) Form Feed (New Page)\n 0x0D: \"CR\", // (CTRL_M) Carriage Return\n 0x0E: \"SO\", // (CTRL_N) Shift Out\n 0x0F: \"SI\", // (CTRL_O) Shift In\n 0x10: \"DLE\", // (CTRL_P) Data Link Escape\n 0x11: \"XON\", // (CTRL_Q) Device Control 1 (aka DC1)\n 0x12: \"DC2\", // (CTRL_R) Device Control 2\n 0x13: \"XOFF\", // (CTRL_S) Device Control 3 (aka DC3)\n 0x14: \"DC4\", // (CTRL_T) Device Control 4\n 0x15: \"NAK\", // (CTRL_U) Negative Acknowledge\n 0x16: \"SYN\", // (CTRL_V) Synchronous Idle\n 0x17: \"ETB\", // (CTRL_W) End of Transmission Block\n 0x18: \"CAN\", // (CTRL_X) Cancel\n 0x19: \"EM\", // (CTRL_Y) End of Medium\n 0x1A: \"SUB\", // (CTRL_Z) Substitute\n 0x1B: \"ESC\", // Escape\n 0x1C: \"FS\", // File Separator\n 0x1D: \"GS\", // Group Separator\n 0x1E: \"RS\", // Record Separator\n 0x1F: \"US\", // Unit Separator\n 0x7F: \"DEL\"\n};\n\n/*\n * Refer to: https://en.wikipedia.org/wiki/Code_page_437\n */\nStr.CP437ToUnicode = [\n '\\u0000', '\\u263A', '\\u263B', '\\u2665', '\\u2666', '\\u2663', '\\u2660', '\\u2022',\n '\\u25D8', '\\u25CB', '\\u25D9', '\\u2642', '\\u2640', '\\u266A', '\\u266B', '\\u263C',\n '\\u25BA', '\\u25C4', '\\u2195', '\\u203C', '\\u00B6', '\\u00A7', '\\u25AC', '\\u21A8',\n '\\u2191', '\\u2193', '\\u2192', '\\u2190', '\\u221F', '\\u2194', '\\u25B2', '\\u25BC',\n '\\u0020', '\\u0021', '\\u0022', '\\u0023', '\\u0024', '\\u0025', '\\u0026', '\\u0027',\n '\\u0028', '\\u0029', '\\u002A', '\\u002B', '\\u002C', '\\u002D', '\\u002E', '\\u002F',\n '\\u0030', '\\u0031', '\\u0032', '\\u0033', '\\u0034', '\\u0035', '\\u0036', '\\u0037',\n '\\u0038', '\\u0039', '\\u003A', '\\u003B', '\\u003C', '\\u003D', '\\u003E', '\\u003F',\n '\\u0040', '\\u0041', '\\u0042', '\\u0043', '\\u0044', '\\u0045', '\\u0046', '\\u0047',\n '\\u0048', '\\u0049', '\\u004A', '\\u004B', '\\u004C', '\\u004D', '\\u004E', '\\u004F',\n '\\u0050', '\\u0051', '\\u0052', '\\u0053', '\\u0054', '\\u0055', '\\u0056', '\\u0057',\n '\\u0058', '\\u0059', '\\u005A', '\\u005B', '\\u005C', '\\u005D', '\\u005E', '\\u005F',\n '\\u0060', '\\u0061', '\\u0062', '\\u0063', '\\u0064', '\\u0065', '\\u0066', '\\u0067',\n '\\u0068', '\\u0069', '\\u006A', '\\u006B', '\\u006C', '\\u006D', '\\u006E', '\\u006F',\n '\\u0070', '\\u0071', '\\u0072', '\\u0073', '\\u0074', '\\u0075', '\\u0076', '\\u0077',\n '\\u0078', '\\u0079', '\\u007A', '\\u007B', '\\u007C', '\\u007D', '\\u007E', '\\u2302',\n '\\u00C7', '\\u00FC', '\\u00E9', '\\u00E2', '\\u00E4', '\\u00E0', '\\u00E5', '\\u00E7',\n '\\u00EA', '\\u00EB', '\\u00E8', '\\u00EF', '\\u00EE', '\\u00EC', '\\u00C4', '\\u00C5',\n '\\u00C9', '\\u00E6', '\\u00C6', '\\u00F4', '\\u00F6', '\\u00F2', '\\u00FB', '\\u00F9',\n '\\u00FF', '\\u00D6', '\\u00DC', '\\u00A2', '\\u00A3', '\\u00A5', '\\u20A7', '\\u0192',\n '\\u00E1', '\\u00ED', '\\u00F3', '\\u00FA', '\\u00F1', '\\u00D1', '\\u00AA', '\\u00BA',\n '\\u00BF', '\\u2310', '\\u00AC', '\\u00BD', '\\u00BC', '\\u00A1', '\\u00AB', '\\u00BB',\n '\\u2591', '\\u2592', '\\u2593', '\\u2502', '\\u2524', '\\u2561', '\\u2562', '\\u2556',\n '\\u2555', '\\u2563', '\\u2551', '\\u2557', '\\u255D', '\\u255C', '\\u255B', '\\u2510',\n '\\u2514', '\\u2534', '\\u252C', '\\u251C', '\\u2500', '\\u253C', '\\u255E', '\\u255F',\n '\\u255A', '\\u2554', '\\u2569', '\\u2566', '\\u2560', '\\u2550', '\\u256C', '\\u2567',\n '\\u2568', '\\u2564', '\\u2565', '\\u2559', '\\u2558', '\\u2552', '\\u2553', '\\u256B',\n '\\u256A', '\\u2518', '\\u250C', '\\u2588', '\\u2584', '\\u258C', '\\u2590', '\\u2580',\n '\\u03B1', '\\u00DF', '\\u0393', '\\u03C0', '\\u03A3', '\\u03C3', '\\u00B5', '\\u03C4',\n '\\u03A6', '\\u0398', '\\u03A9', '\\u03B4', '\\u221E', '\\u03C6', '\\u03B5', '\\u2229',\n '\\u2261', '\\u00B1', '\\u2265', '\\u2264', '\\u2320', '\\u2321', '\\u00F7', '\\u2248',\n '\\u00B0', '\\u2219', '\\u00B7', '\\u221A', '\\u207F', '\\u00B2', '\\u25A0', '\\u00A0'\n];\n\n/*\n * TODO: Future home of a complete ASCII table.\n */\nStr.ASCII = {\n LF: 0x0A,\n CR: 0x0D\n};\n\nStr.TYPES = {\n NULL: 0,\n BYTE: 1,\n WORD: 2,\n DWORD: 3,\n NUMBER: 4,\n STRING: 5,\n BOOLEAN: 6,\n OBJECT: 7,\n ARRAY: 8\n};\n\nStr.HexLowerCase = \"0123456789abcdef\";\nStr.HexUpperCase = \"0123456789ABCDEF\";\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/usrlib.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @typedef {{\n * mask: number,\n * shift: number\n * }}\n */\nvar BitField;\n\n/**\n * @typedef {Object.<BitField>}\n */\nvar BitFields;\n\nclass Usr {\n /**\n * binarySearch(a, v, fnCompare)\n *\n * @param {Array} a is an array\n * @param {number|string|Array|Object} v\n * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]\n * @return {number} the index of matching entry if non-negative, otherwise the index of the insertion point\n */\n static binarySearch(a, v, fnCompare)\n {\n var left = 0;\n var right = a.length;\n var found = 0;\n if (fnCompare === undefined) {\n fnCompare = function(a, b)\n {\n return a > b ? 1 : a < b ? -1 : 0;\n };\n }\n while (left < right) {\n var middle = (left + right) >> 1;\n var compareResult;\n compareResult = fnCompare(v, a[middle]);\n if (compareResult > 0) {\n left = middle + 1;\n } else {\n right = middle;\n found = !compareResult;\n }\n }\n return found ? left : ~left;\n }\n\n /**\n * binaryInsert(a, v, fnCompare)\n *\n * If element v already exists in array a, the array is unchanged (we don't allow duplicates); otherwise, the\n * element is inserted into the array at the appropriate index.\n *\n * @param {Array} a is an array\n * @param {number|string|Array|Object} v is the value to insert\n * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]\n */\n static binaryInsert(a, v, fnCompare)\n {\n var index = Usr.binarySearch(a, v, fnCompare);\n if (index < 0) {\n a.splice(-(index + 1), 0, v);\n }\n }\n\n /**\n * getTimestamp()\n *\n * @return {string} timestamp containing the current date and time (\"yyyy-mm-dd hh:mm:ss\")\n */\n static getTimestamp()\n {\n return Usr.formatDate(\"Y-m-d H:i:s\");\n }\n\n /**\n * getMonthDays(nMonth, nYear)\n *\n * Note that if we're being called on behalf of the RTC, its year is always truncated to two digits (mod 100),\n * so we have no idea what century the year 0 might refer to. When using the normal leap-year formula, 0 fails\n * the mod 100 test but passes the mod 400 test, so as far as the RTC is concerned, every century year is a leap\n * year. Since we're most likely dealing with the year 2000, that's fine, since 2000 was also a leap year.\n *\n * TODO: There IS a separate CMOS byte that's supposed to be set to CMOS_ADDR.CENTURY_DATE; it's always BCD,\n * so theoretically it will contain values like 0x19 or 0x20 (for the 20th and 21st centuries, respectively), and\n * we could add that as another parameter to this function, to improve the accuracy, but that would go beyond what\n * a real RTC actually does.\n *\n * @param {number} nMonth (1-12)\n * @param {number} nYear (normally a 4-digit year, but it may also be mod 100)\n * @return {number} the maximum (1-based) day allowed for the specified month and year\n */\n static getMonthDays(nMonth, nYear)\n {\n var nDays = Usr.aMonthDays[nMonth - 1];\n if (nDays == 28) {\n if ((nYear % 4) === 0 && ((nYear % 100) || (nYear % 400) === 0)) {\n nDays++;\n }\n }\n return nDays;\n }\n\n /**\n * formatDate(sFormat, date)\n *\n * @param {string} sFormat (eg, \"F j, Y\", \"Y-m-d H:i:s\")\n * @param {Date} [date] (default is the current time)\n * @return {string}\n *\n * Supported identifiers in sFormat include:\n *\n * a: lowercase ante meridiem and post meridiem (am or pm)\n * d: day of the month, 2 digits with leading zeros (01,02,...,31)\n * D: 3-letter day of the week (\"Sun\",\"Mon\",...,\"Sat\")\n * F: month (\"January\",\"February\",...,\"December\")\n * g: hour in 12-hour format, without leading zeros (1,2,...,12)\n * h: hour in 24-hour format, without leading zeros (0,1,...,23)\n * H: hour in 24-hour format, with leading zeros (00,01,...,23)\n * i: minutes, with leading zeros (00,01,...,59)\n * j: day of the month, without leading zeros (1,2,...,31)\n * l: day of the week (\"Sunday\",\"Monday\",...,\"Saturday\")\n * m: month, with leading zeros (01,02,...,12)\n * M: 3-letter month (\"Jan\",\"Feb\",...,\"Dec\")\n * n: month, without leading zeros (1,2,...,12)\n * s: seconds, with leading zeros (00,01,...,59)\n * y: 2-digit year (eg, 14)\n * Y: 4-digit year (eg, 2014)\n *\n * For more inspiration, see: http://php.net/manual/en/function.date.php (of which we support ONLY a subset).\n */\n static formatDate(sFormat, date)\n {\n var sDate = \"\";\n if (!date) date = new Date();\n var iHour = date.getHours();\n var iDay = date.getDate();\n var iMonth = date.getMonth() + 1;\n for (var i = 0; i < sFormat.length; i++) {\n var ch;\n switch ((ch = sFormat.charAt(i))) {\n case 'a':\n sDate += (iHour < 12 ? \"am\" : \"pm\");\n break;\n case 'd':\n sDate += ('0' + iDay).slice(-2);\n break;\n case 'D':\n sDate += Usr.asDays[date.getDay()].substr(0, 3);\n break;\n case 'F':\n sDate += Usr.asMonths[iMonth - 1];\n break;\n case 'g':\n sDate += (!iHour ? 12 : (iHour > 12 ? iHour - 12 : iHour));\n break;\n case 'h':\n sDate += iHour;\n break;\n case 'H':\n sDate += ('0' + iHour).slice(-2);\n break;\n case 'i':\n sDate += ('0' + date.getMinutes()).slice(-2);\n break;\n case 'j':\n sDate += iDay;\n break;\n case 'l':\n sDate += Usr.asDays[date.getDay()];\n break;\n case 'm':\n sDate += ('0' + iMonth).slice(-2);\n break;\n case 'M':\n sDate += Usr.asMonths[iMonth - 1].substr(0, 3);\n break;\n case 'n':\n sDate += iMonth;\n break;\n case 's':\n sDate += ('0' + date.getSeconds()).slice(-2);\n break;\n case 'y':\n sDate += (\"\" + date.getFullYear()).slice(-2);\n break;\n case 'Y':\n sDate += date.getFullYear();\n break;\n default:\n sDate += ch;\n break;\n }\n }\n return sDate;\n }\n\n /**\n * defineBitFields(bfs)\n *\n * Prepares a bit field definition for use with getBitField() and setBitField(); eg:\n *\n * var bfs = Usr.defineBitFields({num:20, count:8, btmod:1, type:3});\n *\n * The above defines a set of bit fields containing four fields: num (bits 0-19), count (bits 20-27), btmod (bit 28), and type (bits 29-31).\n *\n * Usr.setBitField(bfs.num, n, 1);\n *\n * The above set bit field \"bfs.num\" in numeric variable \"n\" to the value 1.\n *\n * @param {Object} bfs\n * @return {BitFields}\n */\n static defineBitFields(bfs)\n {\n var bit = 0;\n for (var f in bfs) {\n var width = bfs[f];\n var mask = ((1 << width) - 1) << bit;\n bfs[f] = {mask: mask, shift: bit};\n bit += width;\n }\n return bfs;\n }\n\n /**\n * initBitFields(bfs, ...)\n *\n * @param {BitFields} bfs\n * @param {...number} var_args\n * @return {number} a value containing all supplied bit fields\n */\n static initBitFields(bfs, var_args)\n {\n var v = 0, i = 1;\n for (var f in bfs) {\n if (i >= arguments.length) break;\n v = Usr.setBitField(bfs[f], v, arguments[i++]);\n }\n return v;\n }\n\n /**\n * getBitField(bf, v)\n *\n * @param {BitField} bf\n * @param {number} v is a value containing bit fields\n * @return {number} the value of the bit field in v defined by bf\n */\n static getBitField(bf, v)\n {\n return (v & bf.mask) >> bf.shift;\n }\n\n /**\n * setBitField(bf, v, n)\n *\n * @param {BitField} bf\n * @param {number} v is a value containing bit fields\n * @param {number} n is a value to store in v in the bit field defined by bf\n * @return {number} updated v\n */\n static setBitField(bf, v, n)\n {\n return (v & ~bf.mask) | ((n << bf.shift) & bf.mask);\n }\n\n /**\n * indexOf(a, t, i)\n *\n * Use this instead of Array.prototype.indexOf() if you can't be sure the browser supports it.\n *\n * @param {Array} a\n * @param {*} t\n * @param {number} [i]\n * @returns {number}\n */\n static indexOf(a, t, i)\n {\n if (Array.prototype.indexOf) {\n return a.indexOf(t, i);\n }\n i = i || 0;\n if (i < 0) i += a.length;\n if (i < 0) i = 0;\n for (var n = a.length; i < n; i++) {\n if (i in a && a[i] === t) return i;\n }\n return -1;\n }\n}\n\nUsr.asDays = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\nUsr.asMonths = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\nUsr.aMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\n/**\n * getTime()\n *\n * @return {number} the current time, in milliseconds\n */\nUsr.getTime = Date.now || function() { return +new Date(); };\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/weblib.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * According to http://www.w3schools.com/jsref/jsref_obj_global.asp, these are the *global* properties\n * and functions of JavaScript-in-the-Browser:\n *\n * Property Description\n * ---\n * Infinity A numeric value that represents positive/negative infinity\n * NaN \"Not-a-Number\" value\n * undefined Indicates that a variable has not been assigned a value\n *\n * Function Description\n * ---\n * decodeURI() Decodes a URI\n * decodeURIComponent() Decodes a URI component\n * encodeURI() Encodes a URI\n * encodeURIComponent() Encodes a URI component\n * escape() Deprecated in version 1.5. Use encodeURI() or encodeURIComponent() instead\n * eval() Evaluates a string and executes it as if it was script code\n * isFinite() Determines whether a value is a finite, legal number\n * isNaN() Determines whether a value is an illegal number\n * Number() Converts an object's value to a number\n * parseFloat() Parses a string and returns a floating point number\n * parseInt() Parses a string and returns an integer\n * String() Converts an object's value to a string\n * unescape() Deprecated in version 1.5. Use decodeURI() or decodeURIComponent() instead\n *\n * And according to http://www.w3schools.com/jsref/obj_window.asp, these are the properties and functions\n * of the *window* object.\n *\n * Property Description\n * ---\n * closed Returns a Boolean value indicating whether a window has been closed or not\n * defaultStatus Sets or returns the default text in the statusbar of a window\n * document Returns the Document object for the window (See Document object)\n * frames Returns an array of all the frames (including iframes) in the current window\n * history Returns the History object for the window (See History object)\n * innerHeight Returns the inner height of a window's content area\n * innerWidth Returns the inner width of a window's content area\n * length Returns the number of frames (including iframes) in a window\n * location Returns the Location object for the window (See Location object)\n * name Sets or returns the name of a window\n * navigator Returns the Navigator object for the window (See Navigator object)\n * opener Returns a reference to the window that created the window\n * outerHeight Returns the outer height of a window, including toolbars/scrollbars\n * outerWidth Returns the outer width of a window, including toolbars/scrollbars\n * pageXOffset Returns the pixels the current document has been scrolled (horizontally) from the upper left corner of the window\n * pageYOffset Returns the pixels the current document has been scrolled (vertically) from the upper left corner of the window\n * parent Returns the parent window of the current window\n * screen Returns the Screen object for the window (See Screen object)\n * screenLeft Returns the x coordinate of the window relative to the screen\n * screenTop Returns the y coordinate of the window relative to the screen\n * screenX Returns the x coordinate of the window relative to the screen\n * screenY Returns the y coordinate of the window relative to the screen\n * self Returns the current window\n * status Sets or returns the text in the statusbar of a window\n * top Returns the topmost browser window\n *\n * Method Description\n * ---\n * alert() Displays an alert box with a message and an OK button\n * atob() Decodes a base-64 encoded string\n * blur() Removes focus from the current window\n * btoa() Encodes a string in base-64\n * clearInterval() Clears a timer set with setInterval()\n * clearTimeout() Clears a timer set with setTimeout()\n * close() Closes the current window\n * confirm() Displays a dialog box with a message and an OK and a Cancel button\n * createPopup() Creates a pop-up window\n * focus() Sets focus to the current window\n * moveBy() Moves a window relative to its current position\n * moveTo() Moves a window to the specified position\n * open() Opens a new browser window\n * print() Prints the content of the current window\n * prompt() Displays a dialog box that prompts the visitor for input\n * resizeBy() Resizes the window by the specified pixels\n * resizeTo() Resizes the window to the specified width and height\n * scroll() This method has been replaced by the scrollTo() method.\n * scrollBy() Scrolls the content by the specified number of pixels\n * scrollTo() Scrolls the content to the specified coordinates\n * setInterval() Calls a function or evaluates an expression at specified intervals (in milliseconds)\n * setTimeout() Calls a function or evaluates an expression after a specified number of milliseconds\n * stop() Stops the window from loading\n */\n\nclass Web {\n /**\n * log(s, type)\n *\n * For diagnostic output only. DEBUG must be true (or \"--debug\" specified via the command-line)\n * for Component.log() to display anything.\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n static log(s, type)\n {\n Component.log(s, type);\n }\n\n /**\n * notice(s, fPrintOnly, id)\n *\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n */\n static notice(s, fPrintOnly, id)\n {\n Component.notice(s, fPrintOnly, id);\n }\n\n /**\n * alertUser(sMessage)\n * \n * NOTE: Legacy function for older modules (eg, DiskDump); see Component.alertUser().\n *\n * @param {string} sMessage\n */\n static alertUser(sMessage)\n {\n if (window) {\n window.alert(sMessage);\n } else {\n Web.log(sMessage);\n }\n }\n\n /**\n * getResource(sURL, type, fAsync, done, progress)\n *\n * Request the specified resource (sURL), and once the request is complete, notify done().\n *\n * If fAsync is true, a done() callback should ALWAYS be supplied; otherwise, you'll have no\n * idea when the request is complete or what the response was. done() is passed three parameters:\n *\n * done(sURL, resource, nErrorCode)\n *\n * If nErrorCode is zero, resource should contain the requested data; otherwise, an error occurred.\n *\n * If type is set to a string, that string can be used to control the response format;\n * by default, the response format is plain text, but you can specify \"arraybuffer\" to request arbitrary\n * binary data, in which case the returned resource will be a ArrayBuffer rather than a string.\n *\n * @param {string} sURL\n * @param {string|Object|null} [type] (object for POST request, otherwise type of GET request)\n * @param {boolean} [fAsync] is true for an asynchronous request; false otherwise (MUST be set for IE)\n * @param {function(string,string,number)} [done]\n * @param {function(number)} [progress]\n * @return {Array|null} Array containing [resource, nErrorCode], or null if no response available (yet)\n */\n static getResource(sURL, type = \"text\", fAsync = false, done, progress)\n {\n var nErrorCode = 0, resource = null, response = null;\n\n if (typeof resources == 'object' && (resource = resources[sURL])) {\n if (done) done(sURL, resource, nErrorCode);\n return [resource, nErrorCode];\n }\n else if (fAsync && typeof resources == 'function') {\n resources(sURL, function(resource, nErrorCode)\n {\n if (done) done(sURL, resource, nErrorCode);\n });\n return response;\n }\n\n if (!DEBUG && !NODE) {\n /*\n * TODO: Perhaps it's time for our code in netlib.js to finally add support for HTTPS; for now\n * though, it's just as well that the NODE environment assumes all resources are available locally.\n */\n sURL = sURL.replace(/^\\/(pcjs-disks|private-disks)\\//, \"https://jeffpar.github.io/$1/\");\n }\n else {\n /*\n * The larger resources we put on archive.pcjs.org should also be available locally.\n *\n * NOTE: \"http://archive.pcjs.org\" is now \"https://s3-us-west-2.amazonaws.com/archive.pcjs.org\"\n */\n sURL = sURL.replace(/^(http:\\/\\/archive\\.pcjs\\.org|https:\\/\\/s3-us-west-2\\.amazonaws\\.com\\/archive\\.pcjs\\.org)(\\/.*)\\/([^\\/]*)$/, \"$2/archive/$3\");\n sURL = sURL.replace(/^https:\\/\\/jeffpar\\.github\\.io\\/(pcjs-disks|private-disks)\\/(.*)$/, \"/$1/$2\");\n }\n\n\n var request = (window.XMLHttpRequest? new window.XMLHttpRequest() : new window.ActiveXObject(\"Microsoft.XMLHTTP\"));\n var fArrayBuffer = false, fXHR2 = (typeof request.responseType === 'string');\n \n var callback = function() {\n if (request.readyState !== 4) {\n if (progress) progress(1);\n return null;\n }\n /*\n * The following line was recommended for WebKit, as a work-around to prevent the handler firing multiple\n * times when debugging. Unfortunately, that's not the only XMLHttpRequest problem that occurs when\n * debugging, so I think the WebKit problem is deeper than that. When we have multiple XMLHttpRequests\n * pending, any debugging activity means most of them simply get dropped on floor, so what may actually be\n * happening are mis-notifications rather than redundant notifications.\n *\n * request.onreadystatechange = undefined;\n */\n /*\n * If the request failed due to, say, a CORS policy denial; eg:\n * \n * Failed to load http://www.allbootdisks.com/downloads/Disks/Windows_95_Boot_Disk_Download48/Diskette%20Images/Windows95a.img:\n * Redirect from 'http://www.allbootdisks.com/downloads/Disks/Windows_95_Boot_Disk_Download48/Diskette%20Images/Windows95a.img' to\n * 'http://www.allbootdisks.com/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.\n * Origin 'http://pcjs:8088' is therefore not allowed access.\n * \n * and our request type was \"arraybuffer\", attempting to access responseText may trigger an exception; eg:\n * \n * Uncaught DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's\n * 'responseType' is '' or 'text' (was 'arraybuffer').\n * \n * We could tiptoe around these potential landmines, but the safest thing to do is wrap this code with try/catch.\n */\n try {\n resource = fArrayBuffer? request.response : request.responseText;\n } catch(err) {\n if (MAXDEBUG) Web.log(\"xmlHTTPRequest(\" + sURL + \") exception: \" + err.message);\n }\n /*\n * The normal \"success\" case is a non-null resource and an HTTP status code of 200, but when loading files from the\n * local file system (ie, when using the \"file:\" protocol), we have to be a bit more flexible.\n */\n if (resource != null && (request.status == 200 || !request.status && resource.length && Web.getHostProtocol() == \"file:\")) {\n if (MAXDEBUG) Web.log(\"xmlHTTPRequest(\" + sURL + \"): returned \" + resource.length + \" bytes\");\n }\n else {\n nErrorCode = request.status || -1;\n Web.log(\"xmlHTTPRequest(\" + sURL + \"): error code \" + nErrorCode);\n }\n if (progress) progress(2);\n if (done) done(sURL, resource, nErrorCode);\n return [resource, nErrorCode];\n };\n \n if (fAsync) {\n request.onreadystatechange = callback;\n }\n\n if (progress) progress(0);\n\n if (type && typeof type == \"object\") {\n var sPost = \"\";\n for (var p in type) {\n if (!type.hasOwnProperty(p)) continue;\n if (sPost) sPost += \"&\";\n sPost += p + '=' + encodeURIComponent(type[p]);\n }\n sPost = sPost.replace(/%20/g, '+');\n if (MAXDEBUG) Web.log(\"Web.getResource(POST \" + sURL + \"): \" + sPost.length + \" bytes\");\n request.open(\"POST\", sURL, fAsync);\n request.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\n request.send(sPost);\n } else {\n if (MAXDEBUG) Web.log(\"Web.getResource(GET \" + sURL + \")\");\n request.open(\"GET\", sURL, fAsync);\n if (type == \"arraybuffer\") {\n if (fXHR2) {\n fArrayBuffer = true;\n request.responseType = type;\n } else {\n request.overrideMimeType(\"text/plain; charset=x-user-defined\");\n }\n }\n request.send();\n }\n\n if (!fAsync) {\n request.readyState = 4; // this may already be set for synchronous requests, but I don't want to take any chances \n response = callback();\n }\n return response;\n }\n\n /**\n * parseMemoryResource(sURL, sData)\n *\n * This converts a variety of JSON-style data streams into an Object with the following properties:\n *\n * aBytes\n * aSymbols\n * addrLoad\n * addrExec\n *\n * If the source data contains a 'bytes' array, it's passed through to 'aBytes'; alternatively, if\n * it contains a 'words' array, the values are converted from 16-bit to 8-bit and stored in 'aBytes',\n * and if it contains a 'longs' array, the values are converted from 32-bit longs into bytes and\n * stored in 'aBytes'.\n *\n * Alternatively, if the source data contains a 'data' array, we simply pass that through to the output\n * object as:\n *\n * aData\n *\n * @param {string} sURL\n * @param {string} sData\n * @return {Object|null} (resource)\n */\n static parseMemoryResource(sURL, sData)\n {\n var i;\n var resource = {\n aBytes: null,\n aSymbols: null,\n addrLoad: null,\n addrExec: null\n };\n\n if (sData.charAt(0) == \"[\" || sData.charAt(0) == \"{\") {\n try {\n var a, ib, data;\n\n if (sData.substr(0, 1) == \"<\") { // if the \"data\" begins with a \"<\"...\n /*\n * Early server configs reported an error (via the nErrorCode parameter) if a tape URL was invalid,\n * but more recent server configs now display a somewhat friendlier HTML error page. The downside,\n * however, is that the original error has been buried, and we've received \"data\" that isn't actually\n * tape data. So if the data we've received appears to be \"HTML-like\", we treat it as an error message.\n */\n throw new Error(sData);\n }\n\n /*\n * TODO: IE9 is rather unfriendly and restrictive with regard to how much data it's willing to\n * eval(). In particular, the 10Mb disk image we use for the Windows 1.01 demo config fails in\n * IE9 with an \"Out of memory\" exception. One work-around would be to chop the data into chunks\n * (perhaps one track per chunk, using regular expressions) and then manually re-assemble it.\n *\n * However, it turns out that using JSON.parse(sDiskData) instead of eval(\"(\" + sDiskData + \")\")\n * is a much easier fix. The only drawback is that we must first quote any unquoted property names\n * and remove any comments, because while eval() was cool with them, JSON.parse() is more particular;\n * the following RegExp replacements take care of those requirements.\n *\n * The use of hex values is something else that eval() was OK with, but JSON.parse() is not, and\n * while I've stopped using hex values in DumpAPI responses (at least when \"format=json\" is specified),\n * I can't guarantee they won't show up in \"legacy\" images, and there's no simple RegExp replacement\n * for transforming hex values into decimal values, so I cop out and fall back to eval() if I detect\n * any hex prefixes (\"0x\") in the sequence. Ditto for error messages, which appear like so:\n *\n * [\"unrecognized disk path: test.img\"]\n */\n if (sData.indexOf(\"0x\") < 0 && sData.indexOf(\"0o\") < 0 && sData.substr(0, 2) != '[\"') {\n data = JSON.parse(sData.replace(/([a-z]+):/gm, '\"$1\":').replace(/\\/\\/[^\\n]*/gm, \"\"));\n } else {\n data = eval(\"(\" + sData + \")\");\n }\n\n resource.addrLoad = data['load'];\n resource.addrExec = data['exec'];\n\n if (a = data['bytes']) {\n resource.aBytes = a;\n }\n else if (a = data['words']) {\n /*\n * Convert all words into bytes\n */\n resource.aBytes = new Array(a.length * 2);\n for (i = 0, ib = 0; i < a.length; i++) {\n resource.aBytes[ib++] = a[i] & 0xff;\n resource.aBytes[ib++] = (a[i] >> 8) & 0xff;\n\n }\n }\n else if (a = data['longs']) {\n /*\n * Convert all dwords (longs) into bytes\n */\n resource.aBytes = new Array(a.length * 4);\n for (i = 0, ib = 0; i < a.length; i++) {\n resource.aBytes[ib++] = a[i] & 0xff;\n resource.aBytes[ib++] = (a[i] >> 8) & 0xff;\n resource.aBytes[ib++] = (a[i] >> 16) & 0xff;\n resource.aBytes[ib++] = (a[i] >> 24) & 0xff;\n }\n }\n else if (a = data['data']) {\n resource.aData = a;\n }\n else {\n resource.aBytes = data;\n }\n\n if (resource.aBytes) {\n if (!resource.aBytes.length) {\n Component.error(\"Empty resource: \" + sURL);\n resource = null;\n }\n else if (resource.aBytes.length == 1) {\n Component.error(resource.aBytes[0]);\n resource = null;\n }\n }\n resource.aSymbols = data['symbols'];\n\n } catch (e) {\n Component.error(\"Resource data error (\" + sURL + \"): \" + e.message);\n resource = null;\n }\n }\n else {\n /*\n * Parse the data manually; we assume it's a series of hex byte-values separated by whitespace.\n */\n var ab = [];\n var sHexData = sData.replace(/\\n/gm, \" \").replace(/ +$/, \"\");\n var asHexData = sHexData.split(\" \");\n for (i = 0; i < asHexData.length; i++) {\n var n = parseInt(asHexData[i], 16);\n if (isNaN(n)) {\n Component.error(\"Resource data error (\" + sURL + \"): invalid hex byte (\" + asHexData[i] + \")\");\n break;\n }\n ab.push(n & 0xff);\n }\n if (i == asHexData.length) resource.aBytes = ab;\n }\n return resource;\n }\n\n /**\n * sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)\n *\n * Send a report (eg, bug report) to the server.\n *\n * @param {string} sApp (eg, \"PCjs\")\n * @param {string} sVer (eg, \"1.02\")\n * @param {string} sURL (eg, \"/devices/pc/machine/5150/mda/64kb/machine.xml\")\n * @param {string} sUser (ie, the user key, if any)\n * @param {string} sType (eg, \"bug\"); one of ReportAPI.TYPE.*\n * @param {string} sReport (eg, unparsed state data)\n * @param {string} [sHostName] (default is http://SITEHOST)\n */\n static sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)\n {\n var dataPost = {};\n dataPost[ReportAPI.QUERY.APP] = sApp;\n dataPost[ReportAPI.QUERY.VER] = sVer;\n dataPost[ReportAPI.QUERY.URL] = sURL;\n dataPost[ReportAPI.QUERY.USER] = sUser;\n dataPost[ReportAPI.QUERY.TYPE] = sType;\n dataPost[ReportAPI.QUERY.DATA] = sReport;\n var sReportURL = (sHostName? sHostName : \"http://\" + SITEHOST) + ReportAPI.ENDPOINT;\n Web.getResource(sReportURL, dataPost, true);\n }\n\n /**\n * getHost()\n *\n * @return {string}\n */\n static getHost()\n {\n return (\"http://\" + (window? window.location.host : SITEHOST));\n }\n\n /**\n * getHostURL()\n *\n * @return {string|null}\n */\n static getHostURL()\n {\n return (window? window.location.href : null);\n }\n\n /**\n * getHostProtocol()\n *\n * @return {string}\n */\n static getHostProtocol()\n {\n return (window? window.location.protocol : \"file:\");\n }\n\n /**\n * getUserAgent()\n *\n * @return {string}\n */\n static getUserAgent()\n {\n return (window? window.navigator.userAgent : \"\");\n }\n\n /**\n * hasLocalStorage\n *\n * true if localStorage support exists, is enabled, and works; false otherwise\n *\n * @return {boolean}\n */\n static hasLocalStorage()\n {\n if (Web.fLocalStorage == null) {\n var f = false;\n if (window) {\n try {\n window.localStorage.setItem(Web.sLocalStorageTest, Web.sLocalStorageTest);\n f = (window.localStorage.getItem(Web.sLocalStorageTest) == Web.sLocalStorageTest);\n window.localStorage.removeItem(Web.sLocalStorageTest);\n } catch (e) {\n Web.logLocalStorageError(e);\n f = false;\n }\n }\n Web.fLocalStorage = f;\n }\n return Web.fLocalStorage;\n }\n\n /**\n * logLocalStorageError(e)\n *\n * @param {Error} e is an exception\n */\n static logLocalStorageError(e)\n {\n Web.log(e.message, \"localStorage error\");\n }\n\n /**\n * getLocalStorageItem(sKey)\n *\n * Returns the requested key value, or null if the key does not exist, or undefined if localStorage is not available\n *\n * @param {string} sKey\n * @return {string|null|undefined} sValue\n */\n static getLocalStorageItem(sKey)\n {\n var sValue;\n if (window) {\n try {\n sValue = window.localStorage.getItem(sKey);\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n }\n return sValue;\n }\n\n /**\n * setLocalStorageItem(sKey, sValue)\n *\n * @param {string} sKey\n * @param {string} sValue\n * @return {boolean} true if localStorage is available, false if not\n */\n static setLocalStorageItem(sKey, sValue)\n {\n try {\n window.localStorage.setItem(sKey, sValue);\n return true;\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n return false;\n }\n\n /**\n * removeLocalStorageItem(sKey)\n *\n * @param {string} sKey\n */\n static removeLocalStorageItem(sKey)\n {\n try {\n window.localStorage.removeItem(sKey);\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n }\n\n /**\n * getLocalStorageKeys()\n *\n * @return {Array}\n */\n static getLocalStorageKeys()\n {\n var a = [];\n try {\n for (var i = 0, c = window.localStorage.length; i < c; i++) {\n a.push(window.localStorage.key(i));\n }\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n return a;\n }\n\n /**\n * reloadPage()\n */\n static reloadPage()\n {\n if (window) window.location.reload();\n }\n\n /**\n * isUserAgent(s)\n *\n * Check the browser's user-agent string for the given substring; \"iOS\" and \"MSIE\" are special values you can\n * use that will match any iOS or MSIE browser, respectively (even IE11, in the case of \"MSIE\").\n *\n * 2013-11-06: In a questionable move, MSFT changed the user-agent reported by IE11 on Windows 8.1, eliminating\n * the \"MSIE\" string (which MSDN calls a \"version token\"; see http://msdn.microsoft.com/library/ms537503.aspx);\n * they say \"public websites should rely on feature detection, rather than browser detection, in order to design\n * their sites for browsers that don't support the features used by the website.\" So, in IE11, we get a user-agent\n * that tries to fool apps into thinking the browser is more like WebKit or Gecko:\n *\n * Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko\n *\n * That's a nice idea, but in the meantime, they hosed the XSL transform code in embed.js, which contained\n * some very critical browser-specific code; turning on IE's \"Compatibility Mode\" didn't help either, because\n * that's a sledgehammer solution which restores the old user-agent string but also disables other features like\n * HTML5 canvas support. As an interim solution, I'm treating any \"MSIE\" check as a check for either \"MSIE\" or\n * \"Trident\".\n *\n * UPDATE: I've since found ways to make the code in embed.js more browser-agnostic, so for now, there's isn't\n * any code that cares about \"MSIE\", but I've left the change in place, because I wouldn't be surprised if I'll\n * need more IE-specific code in the future, perhaps for things like copy/paste functionality, or mouse capture.\n *\n * @param {string} s is a substring to search for in the user-agent; as noted above, \"iOS\" and \"MSIE\" are special values\n * @return {boolean} is true if the string was found, false if not\n */\n static isUserAgent(s)\n {\n if (window) {\n var userAgent = Web.getUserAgent();\n /*\n * Here's one case where we have to be careful with Component, because when isUserAgent() is called by\n * the init code below, component.js hasn't been loaded yet. The simple solution for now is to remove the call.\n *\n * Web.log(\"agent: \" + userAgent);\n *\n * And yes, it would be pointless to use the conditional (?) operator below, if not for the Google Closure\n * Compiler (v20130823) failing to detect the entire expression as a boolean.\n */\n return s == \"iOS\" && !!userAgent.match(/(iPod|iPhone|iPad)/) && !!userAgent.match(/AppleWebKit/) || s == \"MSIE\" && !!userAgent.match(/(MSIE|Trident)/) || (userAgent.indexOf(s) >= 0);\n }\n return false;\n }\n\n /**\n * isMobile(sDevice)\n *\n * Checks the URL for a \"mobile\" parameter, and failing that, checks the browser's user-agent string for the\n * substring \"Mobi\", as per Mozilla recommendation:\n *\n * https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent\n *\n * @param {string} [sDevice] (eg, \"iPad\" to check for iPad, or \"!iPad\" to specifically exclude it) \n * @return {boolean} is true if the browser appears to be a mobile (ie, non-desktop) web browser, false if not\n */\n static isMobile(sDevice)\n {\n var sMobile = Web.getURLParm(\"mobile\");\n if (sMobile) return sMobile == \"true\";\n if (Web.isUserAgent(\"Mobi\")) {\n if (!sDevice) return true;\n var fInvert = sDevice[0] == '!';\n if (fInvert) sDevice = sDevice.substr(1);\n return Web.isUserAgent(sDevice) != fInvert;\n }\n return false;\n }\n\n /**\n * findProperty(obj, sProp, sSuffix)\n *\n * If both sProp and sSuffix are set, then any browser-specific prefixes are inserted between sProp and sSuffix,\n * and if a match is found, it is returned without sProp.\n *\n * For example, if findProperty(document, 'on', 'fullscreenchange') discovers that 'onwebkitfullscreenchange' exists,\n * it will return 'webkitfullscreenchange', in preparation for an addEventListener() call.\n *\n * More commonly, sSuffix is not used, so whatever property is found is returned as-is.\n *\n * @param {Object|null|undefined} obj\n * @param {string} sProp\n * @param {string} [sSuffix]\n * @return {string|null}\n */\n static findProperty(obj, sProp, sSuffix)\n {\n if (obj) {\n for (var i = 0; i < Web.asBrowserPrefixes.length; i++) {\n var sName = Web.asBrowserPrefixes[i];\n if (sSuffix) {\n sName += sSuffix;\n var sEvent = sProp + sName;\n if (sEvent in obj) return sName;\n } else {\n if (!sName) {\n sName = sProp[0];\n } else {\n sName += sProp[0].toUpperCase();\n }\n sName += sProp.substr(1);\n if (sName in obj) return sName;\n }\n }\n }\n return null;\n }\n\n /**\n * getURLParm(sParm)\n *\n * First looks for sParm exactly as specified, then looks for the lower-case version.\n *\n * @param {string} sParm\n * @return {string|undefined}\n */\n static getURLParm(sParm)\n {\n if (!Web.parmsURL) {\n Web.parmsURL = Web.parseURLParms();\n }\n return Web.parmsURL[sParm] || Web.parmsURL[sParm.toLowerCase()];\n }\n\n /**\n * parseURLParms(sParms)\n *\n * @param {string} [sParms] containing the parameter portion of a URL (ie, after the '?')\n * @return {Object} containing properties for each parameter found\n */\n static parseURLParms(sParms)\n {\n var aParms = {};\n if (window) { // an alternative to \"if (typeof module === 'undefined')\" if require(\"defines\") was used\n if (!sParms) {\n /*\n * Note that window.location.href returns the entire URL, whereas window.location.search\n * returns only the parameters, if any (starting with the '?', which we skip over with a substr() call).\n */\n sParms = window.location.search.substr(1);\n }\n var match;\n var pl = /\\+/g; // RegExp for replacing addition symbol with a space\n var search = /([^&=]+)=?([^&]*)/g;\n var decode = function(s)\n {\n return decodeURIComponent(s.replace(pl, \" \"));\n };\n\n while ((match = search.exec(sParms))) {\n aParms[decode(match[1])] = decode(match[2]);\n }\n }\n return aParms;\n }\n\n /**\n * downloadFile(sData, sType, fBase64, sFileName)\n *\n * @param {string} sData\n * @param {string} sType\n * @param {boolean} [fBase64]\n * @param {string} [sFileName]\n */\n static downloadFile(sData, sType, fBase64, sFileName)\n {\n var link = null, sAlert;\n var sURI = \"data:application/\" + sType + (fBase64? \";base64\" : \"\") + \",\";\n\n if (!Web.isUserAgent(\"Firefox\")) {\n sURI += (fBase64? sData : encodeURI(sData));\n } else {\n sURI += (fBase64? sData : encodeURIComponent(sData));\n }\n if (sFileName) {\n link = document.createElement('a');\n if (typeof link.download != 'string') link = null;\n }\n if (link) {\n link.href = sURI;\n link.download = sFileName;\n document.body.appendChild(link); // Firefox allegedly requires the link to be in the body\n link.click();\n document.body.removeChild(link);\n sAlert = 'Check your Downloads folder for ' + sFileName + '.';\n if (Web.isUserAgent(\"Chrome\")) {\n sAlert += '\\n\\nIn Chrome, after clicking OK, you may ALSO have to select the \"Window\" menu, choose \"Downloads\", and then locate this download and select \"Keep\".';\n sAlert += '\\n\\nThis is part of Chrome\\'s \"Security By Jumping Through Extra Hoops\" technology, which is much easier for Google to implement than actually checking for something malicious.';\n sAlert += '\\n\\nAnd for the record, there is nothing malicious on the PCjs website.';\n }\n } else {\n window.open(sURI);\n sAlert = 'Check your browser for a new window/tab containing the requested data' + (sFileName? (' (' + sFileName + ')') : '') + '.';\n }\n return sAlert;\n }\n\n /**\n * onCountRepeat(n, fnRepeat, fnComplete, msDelay)\n *\n * Call fnRepeat() n times with an msDelay millisecond delay between calls,\n * then call fnComplete() when n has been exhausted OR fnRepeat() returns false.\n *\n * @param {number} n\n * @param {function()} fnRepeat\n * @param {function()} fnComplete\n * @param {number} [msDelay]\n */\n static onCountRepeat(n, fnRepeat, fnComplete, msDelay)\n {\n var fnTimeout = function doCountRepeat()\n {\n n -= 1;\n if (n >= 0) {\n if (!fnRepeat()) n = 0;\n }\n if (n > 0) {\n setTimeout(fnTimeout, msDelay || 0);\n return;\n }\n fnComplete();\n };\n fnTimeout();\n }\n\n /**\n * onClickRepeat(e, msDelay, msRepeat, fn)\n *\n * Repeatedly call fn() with an initial msDelay, and an msRepeat delay thereafter,\n * as long as HTML control Object e has an active \"down\" event and fn() returns true.\n *\n * @param {Object} e\n * @param {number} msDelay\n * @param {number} msRepeat\n * @param {function(boolean)} fn is passed false on the first call, true on all repeated calls\n */\n static onClickRepeat(e, msDelay, msRepeat, fn)\n {\n var ms = 0, timer = null, fIgnoreMouseEvents = false;\n\n var fnRepeat = function doClickRepeat()\n {\n if (fn(ms === msRepeat)) {\n timer = setTimeout(fnRepeat, ms);\n ms = msRepeat;\n }\n };\n e.onmousedown = function()\n {\n // Web.log(\"onMouseDown()\");\n if (!fIgnoreMouseEvents) {\n if (!timer) {\n ms = msDelay;\n fnRepeat();\n }\n }\n };\n e.ontouchstart = function()\n {\n // Web.log(\"onTouchStart()\");\n if (!timer) {\n ms = msDelay;\n fnRepeat();\n }\n };\n e.onmouseup = e.onmouseout = function()\n {\n // Web.log(\"onMouseUp()/onMouseOut()\");\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n };\n e.ontouchend = e.ontouchcancel = function()\n {\n // Web.log(\"onTouchEnd()/onTouchCancel()\");\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n /*\n * Devices that generate ontouch* events ALSO generate onmouse* events,\n * and generally do so immediately after all the touch events are complete,\n * so unless we want double the action, we need to ignore mouse events.\n */\n fIgnoreMouseEvents = true;\n };\n }\n\n /**\n * onPageEvent(sName, fn)\n *\n * For 'onload', 'onunload', and 'onpageshow' events, most callers should NOT use this function, but\n * instead use Web.onInit(), Web.onShow(), and Web.onExit(), respectively.\n *\n * The only components that should still use onPageEvent() are THIS component (see the bottom of this file)\n * and components that need to capture other events (eg, the 'onresize' event in the Video component).\n *\n * This function creates a chain of callbacks, allowing multiple JavaScript modules to define handlers\n * for the same event, which wouldn't be possible if everyone modified window['onload'], window['onunload'],\n * etc, themselves. However, that's less of a concern now, because assuming everyone else is now using\n * onInit(), onExit(), etc, then there really IS only one component setting the window callback: this one.\n *\n * NOTE: It's risky to refer to obscure event handlers with \"dot\" names, because the Closure Compiler may\n * erroneously replace them (eg, window.onpageshow is a good example).\n *\n * @param {string} sFunc\n * @param {function()} fn\n */\n static onPageEvent(sFunc, fn)\n {\n if (window) {\n var fnPrev = window[sFunc];\n if (typeof fnPrev !== 'function') {\n window[sFunc] = fn;\n } else {\n /*\n * TODO: Determine whether there's any value in receiving/sending the Event object that the\n * browser provides when it generates the original event.\n */\n window[sFunc] = function onWindowEvent()\n {\n if (fnPrev) fnPrev();\n fn();\n };\n }\n }\n };\n\n /**\n * onInit(fn)\n *\n * Use this instead of setting window.onload. Allows multiple JavaScript modules to define their own 'onload' event handler.\n *\n * @param {function()} fn\n */\n static onInit(fn)\n {\n Web.aPageEventHandlers['init'].push(fn);\n };\n\n /**\n * onShow(fn)\n *\n * @param {function()} fn\n *\n * Use this instead of setting window.onpageshow. Allows multiple JavaScript modules to define their own 'onpageshow' event handler.\n */\n static onShow(fn)\n {\n Web.aPageEventHandlers['show'].push(fn);\n };\n\n /**\n * onExit(fn)\n *\n * @param {function()} fn\n *\n * Use this instead of setting window.onunload. Allows multiple JavaScript modules to define their own 'onunload' event handler.\n */\n static onExit(fn)\n {\n Web.aPageEventHandlers['exit'].push(fn);\n };\n\n /**\n * doPageEvent(afn)\n *\n * @param {Array.<function()>} afn\n */\n static doPageEvent(afn)\n {\n if (Web.fPageEventsEnabled) {\n try {\n for (var i = 0; i < afn.length; i++) {\n afn[i]();\n }\n } catch (e) {\n Web.notice(\"An unexpected error occurred: \" + e.message + \"\\n\\nIf it happens again, please send this information to support@pcjs.org. Thanks.\");\n }\n }\n };\n\n /**\n * enablePageEvents(fEnable)\n *\n * @param {boolean} fEnable is true to enable page events, false to disable (they're enabled by default)\n */\n static enablePageEvents(fEnable)\n {\n if (!Web.fPageEventsEnabled && fEnable) {\n Web.fPageEventsEnabled = true;\n if (Web.fPageLoaded) Web.sendPageEvent('init');\n if (Web.fPageShowed) Web.sendPageEvent('show');\n return;\n }\n Web.fPageEventsEnabled = fEnable;\n }\n\n /**\n * sendPageEvent(sEvent)\n *\n * This allows us to manually trigger page events.\n *\n * @param {string} sEvent (one of 'init', 'show' or 'exit')\n */\n static sendPageEvent(sEvent)\n {\n if (Web.aPageEventHandlers[sEvent]) {\n Web.doPageEvent(Web.aPageEventHandlers[sEvent]);\n }\n }\n}\n\nWeb.parmsURL = null; // initialized on first call to parseURLParms()\n\nWeb.aPageEventHandlers = {\n 'init': [], // list of window 'onload' handlers\n 'show': [], // list of window 'onpageshow' handlers\n 'exit': [] // list of window 'onunload' handlers (although we prefer to use 'onbeforeunload' if possible)\n};\n\nWeb.asBrowserPrefixes = ['', 'moz', 'ms', 'webkit'];\n\nWeb.fPageLoaded = false; // set once the page's first 'onload' event has occurred\nWeb.fPageShowed = false; // set once the page's first 'onpageshow' event has occurred\nWeb.fPageEventsEnabled = true; // default is true, set to false (or true) by enablePageEvents()\n\n/**\n * fLocalStorage\n *\n * true if localStorage support exists, is enabled, and works; \"falsey\" otherwise\n *\n * @type {boolean|null}\n */\nWeb.fLocalStorage = null;\n\n/**\n * TODO: Is there any way to get the Closure Compiler to stop inlining this string? This isn't cutting it.\n *\n * @const {string}\n */\nWeb.sLocalStorageTest = \"PCjs.localStorage\";\n\nWeb.onPageEvent('onload', function onPageLoad() {\n Web.fPageLoaded = true;\n Web.doPageEvent(Web.aPageEventHandlers['init']);\n});\n\nWeb.onPageEvent('onpageshow', function onPageShow() {\n Web.fPageShowed = true;\n Web.doPageEvent(Web.aPageEventHandlers['show']);\n});\n\nWeb.onPageEvent(Web.isUserAgent(\"iOS\")? 'onpagehide' : (Web.isUserAgent(\"Opera\")? 'onunload' : 'onbeforeunload'), function onPageUnload() {\n Web.doPageEvent(Web.aPageEventHandlers['exit']);\n});\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/component.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * All PCjs components now use JSDoc types, primarily so that Google's Closure Compiler will compile\n * everything with zero warnings when ADVANCED_OPTIMIZATIONS are enabled. For more information about\n * the JSDoc types supported by the Closure Compiler:\n *\n * https://developers.google.com/closure/compiler/docs/js-for-compiler#types\n *\n * I also attempted to validate this code with JSLint, but it complained too much; eg, it didn't like\n * \"while (true)\", a tried and \"true\" programming convention for decades, and it wanted me to replace\n * all \"++\" and \"--\" operators with \"+= 1\" and \"-= 1\", use \"(s || '')\" instead of \"(s? s : '')\", etc.\n *\n * I prefer sticking with traditional C-style idioms, in part because they are more portable. That\n * does NOT mean I'm trying to write \"portable JavaScript,\" but some of this code was ported from C code\n * I'd written long ago, so portability is good, and I'm not going to throw that away if there's no need.\n *\n * UPDATE: I've since switched from JSLint to JSHint, which seems to have more reasonable defaults.\n * And for new code, I have adopted some popular JavaScript idioms, like \"(s || '')\", although the need\n * for those kinds of expressions will be reduced as I also start adopting some ES6 features, like\n * default parameters.\n */\n\n\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * subclass (eg, SerialPort), because otherwise the Compiler won't allow us to *reference*\n * the named property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass Component {\n /**\n * Component(type, parms, bitsMessage)\n *\n * A Component object requires:\n *\n * type: a user-defined type name (eg, \"CPU\")\n *\n * and accepts any or all of the following (parms) properties:\n *\n * id: component ID (default is \"\")\n * name: component name (default is \"\"; if blank, toString() will use the type name only)\n * comment: component comment string (default is undefined)\n *\n * Component subclasses will usually have additional (parms) properties.\n *\n * @param {string} type\n * @param {Object} [parms]\n * @param {number} [bitsMessage] selects message(s) that the component wants to enable (default is 0)\n */\n constructor(type, parms, bitsMessage)\n {\n this.type = type;\n\n if (!parms) parms = {'id': \"\", 'name': \"\"};\n\n this.id = parms['id'] || \"\";\n this.name = parms['name'];\n this.comment = parms['comment'];\n this.parms = parms;\n\n /*\n * The following Component properties need to be accessible by other machines and/or command scripts;\n * well, OK, or we could have exported some new functions to walk the contents of these properties, as we\n * did with findMachineComponent(), but this works just as well.\n *\n * Also, while the double-assignment looks silly (ie, using both dot and bracket property notation), it\n * resolves a complaint from the Closure Compiler, because if we use ONLY bracket notation here, then the\n * Compiler wants us to change all the other references to bracket notation as well.\n */\n this.exports = this['exports'] = {};\n this.bindings = this['bindings'] = {};\n\n var i = this.id.indexOf('.');\n if (i < 0) {\n this.idComponent = this.id;\n } else {\n this.idMachine = this.id.substr(0, i);\n this.idComponent = this.id.substr(i + 1);\n }\n\n /*\n * Gather all the various component flags (booleans) into a single \"flags\" object, and encourage\n * subclasses to do the same, to reduce the property clutter we have to wade through while debugging.\n */\n this.flags = {\n ready: false,\n busy: false,\n busyCancel: false,\n initDone: false,\n powered: false,\n unloading: false,\n error: false\n };\n\n this.fnReady = null;\n this.clearError();\n this.bitsMessage = bitsMessage || 0;\n\n this.cmp = null;\n this.bus = null;\n this.cpu = null;\n this.dbg = null;\n\n /*\n * TODO: Consider adding another parameter to the Component() constructor that allows components to tell\n * us if they support single or multiple instances per machine. For example, there can be multiple SerialPort\n * components per machine, but only one CPU component (some machines also support an FPU, but that component\n * is considered separate from the CPU).\n *\n * It's not critical, but it would help catch machine configuration errors; for example, a machine that mistakenly\n * includes two CPU components may, aside from wasting memory, end up with odd side-effects, like unresponsive\n * CPU controls.\n */\n Component.add(this);\n }\n\n /**\n * Component.add(component)\n *\n * @param {Component} component\n */\n static add(component)\n {\n /*\n * This just generates a lot of useless noise, handy in the early days, not so much these days....\n *\n * if (DEBUG) Component.log(\"Component.add(\" + component.type + \",\" + component.id + \")\");\n */\n Component.components.push(component);\n }\n\n /**\n * Component.addMachine(idMachine)\n *\n * @param {string} idMachine\n */\n static addMachine(idMachine)\n {\n Component.machines[idMachine] = {};\n }\n\n /**\n * Component.addMachineResource(idMachine, sName, data)\n *\n * @param {string} idMachine\n * @param {string|null} sName (name of the resource)\n * @param {*} data\n */\n static addMachineResource(idMachine, sName, data)\n {\n /*\n * I used to assert(Component.machines[idMachine]), but when we're running as a Node app, embed.js is not used,\n * so addMachine() is never called, so resources do not need to be recorded.\n */\n if (Component.machines[idMachine] && sName) {\n Component.machines[idMachine][sName] = data;\n }\n }\n\n /**\n * Component.getMachineResources(idMachine)\n *\n * @param {string} idMachine\n * @return {Object|undefined}\n */\n static getMachineResources(idMachine)\n {\n return Component.machines[idMachine];\n }\n\n /**\n * Component.getTime()\n *\n * @return {number} the current time, in milliseconds\n */\n static getTime()\n {\n return Date.now() || +new Date();\n }\n\n /**\n * Component.log(s, type)\n *\n * For diagnostic output only.\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n static log(s, type)\n {\n if (!COMPILED) {\n if (s) {\n var sElapsed = \"\", sMsg = (type? (type + \": \") : \"\") + s;\n if (typeof Usr != \"undefined\") {\n if (Component.msStart === undefined) {\n Component.msStart = Component.getTime();\n }\n sElapsed = (Component.getTime() - Component.msStart) + \"ms: \";\n }\n sMsg = sMsg.replace(/\\r/g, '\\\\r').replace(/\\n/g, ' ');\n if (window && window.console) console.log(sElapsed + sMsg);\n }\n }\n }\n\n /**\n * Component.assert(f, s)\n *\n * Verifies conditions that must be true (for DEBUG builds only).\n *\n * The Closure Compiler should automatically remove all references to Component.assert() in non-DEBUG builds.\n * TODO: Add a task to the build process that \"asserts\" there are no instances of \"assertion failure\" in RELEASE builds.\n *\n * @param {boolean} f is the expression we are asserting to be true\n * @param {string} [s] is description of the assertion on failure\n */\n static assert(f, s)\n {\n if (DEBUG) {\n if (!f) {\n if (!s) s = \"assertion failure\";\n Component.log(s);\n throw new Error(s);\n }\n }\n }\n\n /**\n * Component.print(s)\n *\n * Components that inherit from this class should use this.print(), rather than Component.print(), because\n * if a Control Panel is loaded, it will override only the instance method, not the class method (overriding the\n * class method would improperly affect any other machines loaded on the same page).\n *\n * @this {Component}\n * @param {string} s\n */\n static print(s)\n {\n if (!COMPILED) {\n var i = s.lastIndexOf('\\n');\n if (i >= 0) {\n Component.println(s.substr(0, i));\n s = s.substr(i + 1);\n }\n Component.printBuffer += s;\n }\n }\n\n /**\n * Component.println(s, type, id)\n *\n * Components that inherit from this class should use this.println(), rather than Component.println(), because\n * if a Control Panel is loaded, it will override only the instance method, not the class method (overriding the\n * class method would improperly affect any other machines loaded on the same page).\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n * @param {string} [id] is the caller's ID, if any\n */\n static println(s, type, id)\n {\n if (!COMPILED) {\n s = Component.printBuffer + (s || \"\");\n Component.log((id? (id + \": \") : \"\") + (s? (\"\\\"\" + s + \"\\\"\") : \"\"), type);\n Component.printBuffer = \"\";\n }\n }\n\n /**\n * Component.notice(s, fPrintOnly, id)\n *\n * notice() is like println() but implies a need for user notification, so we alert() as well.\n *\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n * @return {boolean}\n */\n static notice(s, fPrintOnly, id)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.NOTICE, id);\n }\n if (!fPrintOnly) Component.alertUser((id? (id + \": \") : \"\") + s);\n return true;\n }\n\n /**\n * Component.warning(s)\n *\n * @param {string} s describes the warning\n */\n static warning(s)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.WARNING);\n }\n Component.alertUser(s);\n }\n\n /**\n * Component.error(s)\n *\n * @param {string} s describes the error; an alert() is displayed as well\n */\n static error(s)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.ERROR);\n }\n Component.alertUser(s);\n }\n\n /**\n * Component.alertUser(sMessage)\n *\n * @param {string} sMessage\n */\n static alertUser(sMessage)\n {\n if (window) {\n window.alert(sMessage);\n } else {\n Component.log(sMessage);\n }\n }\n\n /**\n * Component.confirmUser(sPrompt)\n *\n * @param {string} sPrompt\n * @returns {boolean} true if the user clicked OK, false if Cancel/Close\n */\n static confirmUser(sPrompt)\n {\n var fResponse = false;\n if (window) {\n fResponse = window.confirm(sPrompt);\n }\n return fResponse;\n }\n\n /**\n * Component.promptUser()\n *\n * @param {string} sPrompt\n * @param {string} [sDefault]\n * @returns {string|null}\n */\n static promptUser(sPrompt, sDefault)\n {\n var sResponse = null;\n if (window) {\n sResponse = window.prompt(sPrompt, sDefault === undefined? \"\" : sDefault);\n }\n return sResponse;\n }\n\n /**\n * Component.appendControl(control, sText)\n *\n * @param {Object} control\n * @param {string} sText\n */\n static appendControl(control, sText)\n {\n control.value += sText;\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (COMPILED) {\n sText = control.value;\n if (sText.length > 8192) control.value = sText.substr(sText.length - 4096);\n }\n control.scrollTop = control.scrollHeight;\n }\n\n /**\n * Component.replaceControl(control, sSearch, sReplace)\n *\n * @param {Object} control\n * @param {string} sSearch\n * @param {string} sReplace\n */\n static replaceControl(control, sSearch, sReplace)\n {\n var sText = control.value;\n var i = sText.lastIndexOf(sSearch);\n if (i < 0) {\n sText += sSearch + '\\n';\n } else {\n sText = sText.substr(0, i) + sReplace + sText.substr(i + sSearch.length);\n }\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (COMPILED && sText.length > 8192) sText = sText.substr(sText.length - 4096);\n control.value = sText;\n control.scrollTop = control.scrollHeight;\n }\n\n /**\n * Component.bindExternalControl(component, sBinding, sType)\n *\n * @param {Component} component\n * @param {string} sBinding\n * @param {string} [sType] is the external component type (default is \"Panel\")\n */\n static bindExternalControl(component, sBinding, sType = \"Panel\")\n {\n if (sBinding) {\n var target = Component.getComponentByType(sType, component.id);\n if (target) {\n var control = target.bindings[sBinding];\n if (control) {\n component.setBinding(null, sBinding, control);\n }\n }\n }\n }\n\n /**\n * Component.bindComponentControls(component, element, sAppClass)\n *\n * @param {Component} component\n * @param {HTMLElement} element from the DOM\n * @param {string} sAppClass\n */\n static bindComponentControls(component, element, sAppClass)\n {\n var aeControls = Component.getElementsByClass(element.parentNode, sAppClass + \"-control\");\n\n for (var iControl = 0; iControl < aeControls.length; iControl++) {\n\n var aeChildNodes = aeControls[iControl].childNodes;\n\n for (var iNode = 0; iNode < aeChildNodes.length; iNode++) {\n var control = aeChildNodes[iNode];\n if (control.nodeType !== 1 /* document.ELEMENT_NODE */) {\n continue;\n }\n var sClass = control.getAttribute(\"class\");\n if (!sClass) continue;\n var aClasses = sClass.split(\" \");\n for (var iClass = 0; iClass < aClasses.length; iClass++) {\n var parms;\n sClass = aClasses[iClass];\n switch (sClass) {\n case sAppClass + \"-binding\":\n parms = Component.getComponentParms(/** @type {HTMLElement} */(control));\n if (parms && parms['binding'] !== undefined) {\n component.setBinding(parms['type'], parms['binding'], /** @type {HTMLElement} */(control), parms['value']);\n } else if (!parms || parms['type'] != \"description\") {\n Component.log(\"Component '\" + component.toString() + \"' missing binding\" + (parms? \" for \" + parms['type'] : \"\"), \"warning\");\n }\n iClass = aClasses.length;\n break;\n default:\n // if (DEBUG) Component.log(\"Component.bindComponentControls(\" + component.toString() + \"): unrecognized control class \\\"\" + sClass + \"\\\"\", \"warning\");\n break;\n }\n }\n }\n }\n }\n\n /**\n * Component.getComponents(idRelated)\n *\n * We could store components as properties, using the component's ID, and change\n * this linear lookup into a property lookup, but some components may have no ID.\n *\n * @param {string} [idRelated] of related component\n * @return {Array} of components\n */\n static getComponents(idRelated)\n {\n var i;\n var aComponents = [];\n /*\n * getComponentByID(id, idRelated)\n *\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated) {\n if ((i = idRelated.indexOf('.')) > 0)\n idRelated = idRelated.substr(0, i + 1);\n else\n idRelated = \"\";\n }\n for (i = 0; i < Component.components.length; i++) {\n var component = Component.components[i];\n if (!idRelated || !component.id.indexOf(idRelated)) {\n aComponents.push(component);\n }\n }\n return aComponents;\n }\n\n /**\n * Component.getComponentByID(id, idRelated)\n *\n * We could store components as properties, using the component's ID, and change\n * this linear lookup into a property lookup, but some components may have no ID.\n *\n * @param {string} id of the desired component\n * @param {string} [idRelated] of related component\n * @return {Component|null}\n */\n static getComponentByID(id, idRelated)\n {\n if (id !== undefined) {\n var i;\n /*\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated && (i = idRelated.indexOf('.')) > 0) {\n id = idRelated.substr(0, i + 1) + id;\n }\n for (i = 0; i < Component.components.length; i++) {\n if (Component.components[i].id === id) {\n return Component.components[i];\n }\n }\n if (Component.components.length) {\n Component.log(\"Component ID '\" + id + \"' not found\", \"warning\");\n }\n }\n return null;\n }\n\n /**\n * Component.getComponentByType(sType, idRelated, componentPrev)\n *\n * @param {string} sType of the desired component\n * @param {string} [idRelated] of related component\n * @param {Component|null} [componentPrev] of previously returned component, if any\n * @return {Component|null}\n */\n static getComponentByType(sType, idRelated, componentPrev)\n {\n if (sType !== undefined) {\n var i;\n /*\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated) {\n if ((i = idRelated.indexOf('.')) > 0) {\n idRelated = idRelated.substr(0, i + 1);\n } else {\n idRelated = \"\";\n }\n }\n for (i = 0; i < Component.components.length; i++) {\n if (componentPrev) {\n if (componentPrev == Component.components[i]) componentPrev = null;\n continue;\n }\n if (sType == Component.components[i].type && (!idRelated || !Component.components[i].id.indexOf(idRelated))) {\n return Component.components[i];\n }\n }\n Component.log(\"Component type '\" + sType + \"' not found\", \"warning\");\n }\n return null;\n }\n\n /**\n * Component.getComponentParms(element)\n *\n * @param {HTMLElement} element from the DOM\n */\n static getComponentParms(element)\n {\n var parms = null;\n var sParms = element.getAttribute(\"data-value\");\n if (sParms) {\n try {\n parms = eval('(' + sParms + ')'); // jshint ignore:line\n /*\n * We can no longer invoke removeAttribute() because some components (eg, Panel) need\n * to run their initXXX() code more than once, to avoid initialization-order dependencies.\n *\n * if (!DEBUG) {\n * element.removeAttribute(\"data-value\");\n * }\n */\n } catch(e) {\n Component.error(e.message + \" (\" + sParms + \")\");\n }\n }\n return parms;\n }\n\n /**\n * Component.getElementsByClass(element, sClass, sObjClass)\n *\n * This is a cross-browser helper function, since not all browser's support getElementsByClassName()\n *\n * TODO: This should probably be moved into weblib.js at some point, along with the control binding functions above,\n * to keep all the browser-related code together.\n *\n * @param {HTMLDocument|HTMLElement|Node} element from the DOM\n * @param {string} sClass\n * @param {string} [sObjClass]\n * @return {Array|NodeList}\n */\n static getElementsByClass(element, sClass, sObjClass)\n {\n if (sObjClass) sClass += '-' + sObjClass + \"-object\";\n /*\n * Use the browser's built-in getElementsByClassName() if it appears to be available\n * (for example, it's not available in IE8, but it should be available in IE9 and up)\n */\n if (element.getElementsByClassName) {\n return element.getElementsByClassName(sClass);\n }\n var i, j, ae = [];\n var aeAll = element.getElementsByTagName(\"*\");\n var re = new RegExp('(^| )' + sClass + '( |$)');\n for (i = 0, j = aeAll.length; i < j; i++) {\n if (re.test(aeAll[i].className)) {\n ae.push(aeAll[i]);\n }\n }\n if (!ae.length) {\n Component.log('No elements of class \"' + sClass + '\" found');\n }\n return ae;\n }\n\n /**\n * Component.getScriptCommands(sScript)\n *\n * This is a simple parser that breaks sScript into an array of commands, where each command\n * is an array of tokens, where tokens are sequences of characters separated by any of: tab, space,\n * carriage-return (CR), line-feed (LF), semicolon, single-quote, or double-quote; if a quote is\n * used, all characters up to the next matching quote become part of the token, allowing any of the\n * other separators to be part of the token. CR, LF and semicolon also serve to terminate a command,\n * with semicolon being preferred, because it's 1) more visible, and 2) essential when the entire\n * script is a multi-line string where all CR/LF were replaced by spaces (which is what Jekyll does,\n * and since we can't change Jekyll, it's what our own MarkDown Front Matter parser does as well;\n * see convertMD() in markout.js, where the aCommandDefs array is built).\n *\n * Backslash sequences like \\n, \\r, and \\\\ have already been converted to LF, CR and backslash\n * characters, since the entire script string is injected into a JavaScript function call, so any\n * backslash sequence that JavaScript supports is automatically converted:\n *\n * \\0 \\' \\\" \\\\ \\n \\r \\v \\t \\b \\f \\uXXXX \\xXX\n * ^J ^M ^K ^I ^H ^L\n *\n * To support any other non-printable 8-bit character, such as ESC, you should use \\xXX, where XX\n * is the ASCII code in hex. For ESC, that would be \\x1B.\n *\n * @param {string} sScript\n * @return {Array}\n */\n static getScriptCommands(sScript)\n {\n var cch = sScript.length;\n var aCommands = [], aTokens = [], sToken = \"\", chQuote = null;\n for (var i = 0; i < cch; i++) {\n var ch = sScript[i];\n if (ch == '\"' || ch == \"'\") {\n if (chQuote && ch != chQuote) {\n sToken += ch;\n continue;\n }\n if (!chQuote) {\n chQuote = ch;\n } else {\n chQuote = null;\n }\n if (sToken) {\n aTokens.push(sToken);\n sToken = \"\";\n }\n continue;\n }\n if (!chQuote) {\n if (ch == '\\r' || ch == '\\n') {\n ch = ';';\n }\n if (ch == ' ' || ch == '\\t' || ch == ';') {\n if (sToken) {\n aTokens.push(sToken);\n sToken = \"\";\n }\n if (ch == ';' && aTokens.length) {\n aCommands.push(aTokens);\n aTokens = [];\n }\n continue;\n }\n }\n sToken += ch;\n }\n if (sToken) {\n aTokens.push(sToken);\n }\n if (aTokens.length) {\n aCommands.push(aTokens);\n }\n return aCommands;\n }\n\n /**\n * Component.processScript(idMachine, sScript)\n *\n * @param {string} idMachine\n * @param {string} [sScript]\n * @return {boolean}\n */\n static processScript(idMachine, sScript)\n {\n var fSuccess = false;\n idMachine += \".machine\";\n if (!sScript) {\n delete Component.commands[idMachine];\n fSuccess = true;\n }\n else if (typeof sScript == \"string\" && !Component.commands[idMachine]) {\n fSuccess = true;\n Component.commands[idMachine] = Component.getScriptCommands(sScript);\n if (!Component.processCommands(idMachine)) {\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * Component.processCommands(idMachine)\n *\n * @param {string} idMachine\n * @return {boolean}\n */\n static processCommands(idMachine)\n {\n var fSuccess = true;\n var aCommands = Component.commands[idMachine];\n\n // var dbg = Component.getComponentByType(\"Debugger\", idMachine);\n\n while (aCommands && aCommands.length) {\n\n var aTokens = aCommands.splice(0, 1)[0];\n var sCommand = aTokens[0];\n\n /*\n * It's possible to route this output to the Debugger window with dbg.println()\n * instead, but it's a bit too confusing mingling script output in a window that\n * already mingles Debugger and machine output.\n */\n Component.println(aTokens.join(' '), Component.PRINT.SCRIPT);\n\n var fnCallReady = null;\n if (Component.asyncCommands.indexOf(sCommand) >= 0) {\n fnCallReady = function processNextCommand() {\n return function() {\n Component.processCommands(idMachine);\n }\n }();\n }\n\n var fnCommand = Component.globalCommands[sCommand];\n if (fnCommand) {\n if (!fnCallReady) {\n fSuccess = fnCommand(aTokens[1], aTokens[2], aTokens[3]);\n } else {\n if (!fnCommand(fnCallReady, aTokens[1], aTokens[2], aTokens[3])) break;\n }\n }\n else {\n fSuccess = false;\n var component = Component.getComponentByType(aTokens[1], idMachine);\n if (component) {\n fnCommand = Component.componentCommands[sCommand];\n if (fnCommand) {\n fSuccess = fnCommand(component, aTokens[2], aTokens[3]);\n }\n else {\n var exports = component['exports'];\n if (exports) {\n fnCommand = exports[sCommand];\n if (fnCommand) {\n fSuccess = true;\n if (!fnCallReady) {\n fSuccess = fnCommand.call(component, aTokens[2], aTokens[3]);\n } else {\n if (!fnCommand.call(component, fnCallReady, aTokens[2], aTokens[3])) break;\n }\n }\n }\n }\n }\n }\n\n if (!fSuccess) {\n Component.alertUser(\"Script error: '\" + sCommand + \"' command \" + (fnCommand? \" failed\" : \" not recognized\"));\n break;\n }\n }\n\n if (aCommands && !aCommands.length) {\n delete Component.commands[idMachine];\n }\n\n return fSuccess;\n }\n\n /**\n * Component.scriptAlert(sMessage)\n *\n * @param {string} sMessage\n * @return {boolean}\n */\n static scriptAlert(sMessage)\n {\n Component.alertUser(sMessage);\n return true;\n }\n\n /**\n * Component.scriptSelect(component, sBinding, sValue)\n *\n * @param {Component} component\n * @param {string} sBinding\n * @param {string} sValue\n * @return {boolean}\n */\n static scriptSelect(component, sBinding, sValue)\n {\n var fSuccess = false;\n var aBindings = component['bindings'];\n var control = aBindings[sBinding];\n if (control) {\n for (var i = 0; i < control.options.length; i++) {\n if (control.options[i].textContent == sValue) {\n if (control.selectedIndex != i) {\n control.selectedIndex = i;\n }\n fSuccess = true;\n break;\n }\n }\n }\n return fSuccess;\n }\n\n /**\n * Component.scriptSleep(fnCallback, sDelay)\n *\n * @param {function()} fnCallback\n * @param {string} sDelay (in milliseconds)\n * @return {boolean}\n */\n static scriptSleep(fnCallback, sDelay)\n {\n setTimeout(fnCallback, +sDelay);\n return false;\n }\n\n /**\n * toString()\n *\n * @this {Component}\n * @return {string}\n */\n toString()\n {\n return (this.name? this.name : (this.id || this.type));\n }\n\n /**\n * getMachineNum()\n *\n * @this {Component}\n * @return {number} unique machine number\n */\n getMachineNum()\n {\n var nMachine = 1;\n if (this.idMachine) {\n var aDigits = this.idMachine.match(/\\d+/);\n if (aDigits !== null)\n nMachine = parseInt(aDigits[0], 10);\n }\n return nMachine;\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * Component's setBinding() method is intended to be overridden by subclasses.\n *\n * @this {Component}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, 'print')\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n switch (sBinding) {\n case 'clear':\n if (!this.bindings[sBinding]) {\n this.bindings[sBinding] = control;\n control.onclick = (function(component) {\n return function clearControl() {\n if (component.bindings['print']) {\n component.bindings['print'].value = \"\";\n }\n };\n }(this));\n }\n return true;\n case 'print':\n if (!this.bindings[sBinding]) {\n var controlTextArea = /** @type {HTMLTextAreaElement} */(control);\n this.bindings[sBinding] = controlTextArea;\n /**\n * Override this.notice() with a replacement function that eliminates the Component.alertUser() call.\n *\n * @this {Component}\n * @param {string} s\n * @return {boolean}\n */\n this.notice = function noticeControl(s /*, fPrintOnly, id*/) {\n this.println(s, this.type);\n return true;\n };\n /*\n * This was added for Firefox (Safari will clear the <textarea> on a page reload, but Firefox does not).\n */\n controlTextArea.value = \"\";\n this.print = function(control) {\n return function printControl(s) {\n Component.appendControl(control, s);\n };\n }(controlTextArea);\n this.println = function(component, control) {\n return function printlnControl(s, type, id) {\n if (!s) s = \"\";\n if (type != Component.PRINT.PROGRESS || s.slice(-3) != \"...\") {\n if (type) s = type + \": \" + s;\n Component.appendControl(control, s + '\\n');\n } else {\n Component.replaceControl(control, s, s + '.');\n }\n if (!COMPILED && window && window.console) Component.println(s, type, id);\n };\n }(this, controlTextArea);\n }\n return true;\n default:\n return false;\n }\n }\n\n /**\n * log(s, type)\n *\n * For diagnostic output only.\n *\n * WARNING: Even though this function's body is completely wrapped in DEBUG, that won't prevent the Closure Compiler\n * from including it, so all calls must still be prefixed with \"if (DEBUG) ....\". For this reason, the class method,\n * Component.log(), is preferred, because the compiler IS smart enough to remove those calls.\n *\n * @this {Component}\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n log(s, type)\n {\n if (!COMPILED) {\n Component.log(s, type || this.id || this.type);\n }\n }\n\n /**\n * assert(f, s)\n *\n * Verifies conditions that must be true (for DEBUG builds only).\n *\n * WARNING: Make sure you preface all calls to this.assert() with \"if (DEBUG)\", because unlike Component.assert(),\n * the Closure Compiler can't be sure that this instance method hasn't been overridden, so it refuses to treat it as\n * dead code in non-DEBUG builds.\n *\n * TODO: Add a task to the build process that \"asserts\" there are no instances of \"assertion failure\" in RELEASE builds.\n *\n * @this {Component}\n * @param {boolean|number} f is the expression asserted to be true\n * @param {string} [s] is a description of the assertion to be displayed or logged on failure\n */\n assert(f, s)\n {\n if (DEBUG) {\n if (!f) {\n s = \"assertion failure in \" + (this.id || this.type) + (s? \": \" + s : \"\");\n if (DEBUGGER && this.dbg) {\n this.dbg.stopCPU();\n /*\n * Why do we throw an Error only to immediately catch and ignore it? Simply to give\n * any IDE the opportunity to inspect the application's state. Even when the IDE has\n * control, you should still be able to invoke Debugger commands from the IDE's REPL,\n * using the global function that the Debugger constructor defines; eg:\n *\n * pcx86('r')\n * pcx86('dw 0:0')\n * pcx86('h')\n * ...\n *\n * If you have no desire to stop on assertions, consider this a no-op. However, another\n * potential benefit of creating an Error object is that, for browsers like Chrome, we get\n * a stack trace, too.\n */\n try {\n throw new Error(s);\n } catch(e) {\n this.println(e.stack || e.message);\n }\n return;\n }\n this.log(s);\n throw new Error(s);\n }\n }\n }\n\n /**\n * print(s)\n *\n * Components using this.print() should wait until after their constructor has run to display any messages, because\n * if a Control Panel has been loaded, its override will not take effect until its own constructor has run.\n *\n * @this {Component}\n * @param {string} s\n */\n print(s)\n {\n Component.print(s);\n }\n\n /**\n * println(s, type, id)\n *\n * Components using this.println() should wait until after their constructor has run to display any messages, because\n * if a Control Panel has been loaded, its override will not take effect until its own constructor has run.\n *\n * @this {Component}\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n * @param {string} [id] is the caller's ID, if any\n */\n println(s, type, id)\n {\n Component.println(s, type, id || this.id);\n }\n\n /**\n * status(s)\n *\n * status() is like println() but it also includes information about the component (ie, the component type),\n * which is why there is no corresponding Component.status() function.\n *\n * @this {Component}\n * @param {string} s is the message text\n */\n status(s)\n {\n this.println(this.type + \": \" + s);\n }\n\n /**\n * notice(s, fPrintOnly, id)\n *\n * notice() is like println() but implies a need for user notification, so we alert() as well; however, if this.println()\n * is overridden, this.notice will be replaced with a similar override, on the assumption that the override is taking care\n * of alerting the user.\n *\n * @this {Component}\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n * @return {boolean}\n */\n notice(s, fPrintOnly, id)\n {\n if (!fPrintOnly) {\n /*\n * See if the associated computer, if any, is \"unloading\"....\n */\n var computer = Component.getComponentByType(\"Computer\", this.id);\n if (computer && computer.flags.unloading) {\n console.log(\"ignoring notice during unload: \" + s);\n return false;\n }\n }\n Component.notice(s, fPrintOnly, id || this.type);\n return true;\n }\n\n /**\n * setError(s)\n *\n * Set a fatal error condition\n *\n * @this {Component}\n * @param {string} s describes a fatal error condition\n */\n setError(s)\n {\n this.flags.error = true;\n this.notice(s); // TODO: Any cases where we should still prefix this string with \"Fatal error: \"?\n }\n\n /**\n * clearError()\n *\n * Clear any fatal error condition\n *\n * @this {Component}\n */\n clearError() {\n this.flags.error = false;\n }\n\n /**\n * isError()\n *\n * Report any fatal error condition\n *\n * @this {Component}\n * @return {boolean} true if a fatal error condition exists, false if not\n */\n isError()\n {\n if (this.flags.error) {\n this.println(this.toString() + \" error\");\n return true;\n }\n return false;\n }\n\n /**\n * isReady(fnReady)\n *\n * Return the \"ready\" state of the component; if the component is not ready, it will queue the optional\n * notification function, otherwise it will immediately call the notification function, if any, without queuing it.\n *\n * NOTE: Since only the Computer component actually cares about the \"readiness\" of other components, the so-called\n * \"queue\" of notification functions supports exactly one function. This keeps things nice and simple.\n *\n * @this {Component}\n * @param {function()} [fnReady]\n * @return {boolean} true if the component is in a \"ready\" state, false if not\n */\n isReady(fnReady)\n {\n if (fnReady) {\n if (this.flags.ready) {\n fnReady();\n } else {\n if (MAXDEBUG) this.log(\"NOT ready\");\n this.fnReady = fnReady;\n }\n }\n return this.flags.ready;\n }\n\n /**\n * setReady(fReady)\n *\n * Set the \"ready\" state of the component to true, and call any queued notification functions.\n *\n * @this {Component}\n * @param {boolean} [fReady] is assumed to indicate \"ready\" unless EXPLICITLY set to false\n */\n setReady(fReady)\n {\n if (!this.flags.error) {\n this.flags.ready = (fReady !== false);\n if (this.flags.ready) {\n if (MAXDEBUG /* || this.name */) this.log(\"ready\");\n var fnReady = this.fnReady;\n this.fnReady = null;\n if (fnReady) fnReady();\n }\n }\n }\n\n /**\n * isBusy(fCancel)\n *\n * Return the \"busy\" state of the component\n *\n * @this {Component}\n * @param {boolean} [fCancel] is set to true to cancel a \"busy\" state\n * @return {boolean} true if \"busy\", false if not\n */\n isBusy(fCancel)\n {\n if (this.flags.busy) {\n if (fCancel) {\n this.flags.busyCancel = true;\n } else if (fCancel === undefined) {\n this.println(this.toString() + \" busy\");\n }\n }\n return this.flags.busy;\n }\n\n /**\n * setBusy(fBusy)\n *\n * Update the current busy state; if a busyCancel request is pending, it will be honored now.\n *\n * @this {Component}\n * @param {boolean} fBusy\n * @return {boolean}\n */\n setBusy(fBusy)\n {\n if (this.flags.busyCancel) {\n this.flags.busy = false;\n this.flags.busyCancel = false;\n return false;\n }\n if (this.flags.error) {\n this.println(this.toString() + \" error\");\n return false;\n }\n this.flags.busy = fBusy;\n return this.flags.busy;\n }\n\n /**\n * powerUp(fSave)\n *\n * @this {Component}\n * @param {Object|null} data\n * @param {boolean} [fRepower] is true if this is \"repower\" notification\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n this.flags.powered = true;\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Component}\n * @param {boolean} fSave\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n if (fShutdown) this.flags.powered = false;\n return true;\n }\n\n /**\n * messageEnabled(bitsMessage)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n *\n * @this {Component}\n * @param {number} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n * @return {boolean} true if all specified message enabled, false if not\n */\n messageEnabled(bitsMessage = 0)\n {\n if (DEBUGGER && this.dbg) {\n if (this !== this.dbg) {\n bitsMessage = bitsMessage || this.bitsMessage;\n }\n var bitsEnabled = this.dbg.bitsMessage & bitsMessage;\n /*\n * This next \"bit\" of logic is for PCx86 and any other machine where we've expanded the set of\n * messages by reusing bits in the low nibbles in combination with different bits in the high nibble.\n * If the input bits adhere to that format, then the mask we just produced must adhere to it as well,\n * and if it doesn't, zero the mask, ensuring that the test will return false.\n */\n if ((bitsMessage & 0xf0000000) && (bitsMessage & 0x0fffffff)) {\n if (!(bitsEnabled & 0xf0000000) || !(bitsEnabled & 0x0fffffff)) bitsEnabled = 0;\n }\n if (bitsMessage && bitsEnabled === bitsMessage) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * printf(format, ...args)\n *\n * @this {Component}\n * @param {string} format\n * @param {...} args\n */\n printf(format, ...args)\n {\n if (DEBUGGER && this.dbg) {\n if (this.messageEnabled()) {\n let s = Str.sprintf(format, ...args);\n /*\n * Since dbg.message() calls println(), we strip any ending linefeed.\n * \n * We could bypass the Debugger and go straight to this.print(), but we would lose\n * the benefits of debugger messages (eg, automatic buffering, halting, yielding, etc).\n */\n if (s.slice(-1) == '\\n') s = s.slice(0, -1);\n this.dbg.message(s);\n }\n }\n }\n\n /**\n * printMessage(sMessage, bitsMessage, fAddress)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n * If bitsMessage is true, the message is displayed regardless.\n *\n * @this {Component}\n * @param {string} sMessage is any caller-defined message string\n * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n * @param {boolean} [fAddress] is true to display the current address\n */\n printMessage(sMessage, bitsMessage, fAddress)\n {\n if (DEBUGGER && this.dbg) {\n if (bitsMessage === true || this.messageEnabled(bitsMessage | 0)) {\n this.dbg.message(sMessage, fAddress);\n }\n }\n }\n\n /**\n * printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n * If bitsMessage is true, the message is displayed as long as MESSAGE.PORT is enabled.\n *\n * @this {Component}\n * @param {number} port\n * @param {number|null} bOut if an output operation\n * @param {number|null} [addrFrom]\n * @param {string|null} [name] of the port, if any\n * @param {number|null} [bIn] is the input value, if known, on an input operation\n * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n */\n printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage)\n {\n if (DEBUGGER && this.dbg) {\n if (bitsMessage === true) {\n bitsMessage = 0;\n } else if (bitsMessage == null) {\n bitsMessage = this.bitsMessage;\n }\n this.dbg.messageIO(this, port, bOut, addrFrom, name, bIn, bitsMessage);\n }\n }\n}\n\n/*\n * Types recognized and supported by selected functions (eg, Computer.getMachineParm())\n */\nComponent.TYPE = {\n NUMBER: \"number\",\n OBJECT: \"object\",\n STRING: \"string\"\n};\n\n/*\n * These are the standard PRINT values you can pass as an optional argument to println(); in reality,\n * you can pass anything you want, because they are simply prepended to the message, although PROGRESS\n * messages may also be merged with earlier similar messages to keep the output buffer under control.\n */\nComponent.PRINT = {\n ERROR: \"error\",\n NOTICE: \"notice\",\n PROGRESS: \"progress\",\n SCRIPT: \"script\",\n WARNING: \"warning\"\n};\n\n/*\n * Every component created on the current page is recorded in this array (see Component.add()),\n * enabling any component to locate another component by ID (see Component.getComponentByID())\n * or by type (see Component.getComponentByType()).\n *\n * Every machine on the page are now recorded as well, by their machine ID. We then record the\n * various resources used by that machine.\n *\n * Includes a fallback for non-browser-based environments (ie, Node). TODO: This will need to be\n * tailored to Node, probably using the global object instead of the window object, if we ever want\n * to support multi-machine configs in that environment.\n */\nif (window) {\n if (!window['PCjs']) window['PCjs'] = {};\n if (!window['PCjs']['Machines']) window['PCjs']['Machines'] = {};\n if (!window['PCjs']['Components']) window['PCjs']['Components'] = [];\n if (!window['PCjs']['Commands']) window['PCjs']['Commands'] = {};\n}\nComponent.machines = window? window['PCjs']['Machines'] : {};\nComponent.components = window? window['PCjs']['Components'] : [];\nComponent.commands = window? window['PCjs']['Commands'] : {};\n\nComponent.asyncCommands = [\n 'hold', 'sleep', 'wait'\n];\nComponent.globalCommands = {\n 'alert': Component.scriptAlert,\n 'sleep': Component.scriptSleep\n};\nComponent.componentCommands = {\n 'select': Component.scriptSelect\n};\nComponent.printBuffer = \"\";\n\n/*\n * The following polyfills provide ES5 functionality that's missing in older browsers (eg, IE8),\n * allowing PCjs apps to run without slamming into exceptions; however, due to the lack of HTML5 canvas\n * support in those browsers, all you're likely to see are \"soft\" errors (eg, \"Missing <canvas> support\").\n *\n * Perhaps we can implement a text-only faux video display for a fun retro-browser experience someday.\n *\n * TODO: Come up with a better place to put these polyfills. We will likely have more if we decide to\n * make the leap from ES5 to ES6 features.\n */\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf\n */\nif (!Array.prototype.indexOf) {\n Array.prototype.indexOf = function(obj, start) {\n for (var i = (start || 0), j = this.length; i < j; i++) {\n if (this[i] === obj) { return i; }\n }\n return -1;\n }\n}\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray\n */\nif (!Array.isArray) {\n Array.isArray = function(arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n };\n}\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind\n */\nif (!Function.prototype.bind) {\n Function.prototype.bind = function(obj) {\n if (typeof this != \"function\") {\n // Closest thing possible to the ECMAScript 5 internal IsCallable function\n throw new TypeError(\"Function.prototype.bind: non-callable object\");\n }\n var args = Array.prototype.slice.call(arguments, 1);\n var fToBind = this;\n var fnNOP = /** @constructor */ (function() {});\n var fnBound = function() {\n return fToBind.apply(this instanceof fnNOP && obj? this : obj, args.concat(/** @type {Array} */(Array.prototype.slice.call(arguments))));\n };\n fnNOP.prototype = this.prototype;\n fnBound.prototype = new fnNOP();\n return fnBound;\n };\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/defines.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @define {string}\n */\nvar APPCLASS = \"pc8080\"; // this @define is the default application class (eg, \"pcx86\", \"c1pjs\")\n\n/**\n * @define {string}\n */\nvar APPNAME = \"PC8080\"; // this @define is the default application name (eg, \"PCx86\", \"C1Pjs\")\n\n/**\n * @define {boolean}\n *\n * WARNING: DEBUGGER needs to accurately reflect whether or not the Debugger component is (or will be) loaded.\n * In the compiled case, we rely on the Closure Compiler to override DEBUGGER as appropriate. When it's *false*,\n * nearly all of debugger.js will be conditionally removed by the compiler, reducing it to little more than a\n * \"type skeleton\", which also solves some type-related warnings we would otherwise have if we tried to remove\n * debugger.js from the compilation process altogether.\n *\n * However, when we're in \"development mode\" and running uncompiled code in debugger-less configurations,\n * I would like to skip loading debugger.js altogether. When doing that, we must ALSO arrange for an additional file\n * (nodebugger.js) to be loaded immediately after this file, which *explicitly* overrides DEBUGGER with *false*.\n */\nvar DEBUGGER = true; // this @define is overridden by the Closure Compiler to remove Debugger-related support\n\n/**\n * @define {boolean}\n *\n * BYTEARRAYS is a Closure Compiler compile-time option that allocates an Array of numbers for every Memory block,\n * where each a number represents ONE byte; very wasteful, but potentially slightly faster.\n *\n * See the Memory component for details.\n */\nvar BYTEARRAYS = false;\n\n/**\n * TYPEDARRAYS enables use of typed arrays for Memory blocks. This used to be a compile-time-only option, but I've\n * added Memory access functions for typed arrays (see Memory8080.afnTypedArray), so support can be enabled dynamically now.\n *\n * See the Memory component for details.\n */\nvar TYPEDARRAYS = (typeof ArrayBuffer !== 'undefined');\n\n/*\n * Combine all the shared globals and machine-specific globals into one machine-specific global object,\n * which all machine components should start using; eg: \"if (PC8080.DEBUG) ...\" instead of \"if (DEBUG) ...\".\n */\nvar PC8080 = {\n APPCLASS: APPCLASS,\n APPNAME: APPNAME,\n APPVERSION: APPVERSION, // shared\n BYTEARRAYS: BYTEARRAYS,\n COMPILED: COMPILED, // shared\n CSSCLASS: CSSCLASS, // shared\n DEBUG: DEBUG, // shared\n DEBUGGER: DEBUGGER,\n MAXDEBUG: MAXDEBUG, // shared\n PRIVATE: PRIVATE, // shared\n TYPEDARRAYS: TYPEDARRAYS,\n SITEHOST: SITEHOST, // shared\n XMLVERSION: XMLVERSION // shared\n};\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/cpudef.js (C) Jeff Parsons 2012-2018\n */\n\nvar CPUDef8080 = {\n /*\n * CPU model numbers (supported)\n */\n MODEL_8080: 8080,\n\n /*\n * This constant is used to mark points in the code where the physical address being returned\n * is invalid and should not be used.\n *\n * In a 32-bit CPU, -1 (ie, 0xffffffff) could actually be a valid address, so consider changing\n * ADDR_INVALID to NaN or null (which is also why all ADDR_INVALID tests should use strict equality\n * operators).\n *\n * The main reason I'm NOT using NaN or null now is my concern that, by mixing non-numbers\n * (specifically, values outside the range of signed 32-bit integers), performance may suffer.\n *\n * WARNING: Like many of the properties defined here, ADDR_INVALID is a common constant, which the\n * Closure Compiler will happily inline (with or without @const annotations; in fact, I've yet to\n * see a @const annotation EVER improve automatic inlining). However, if you don't make ABSOLUTELY\n * certain that this file is included BEFORE the first reference to any of these properties, that\n * automatic inlining will no longer occur.\n */\n ADDR_INVALID: -1,\n\n /*\n * Processor Status flag definitions (stored in regPS)\n */\n PS: {\n CF: 0x0001, // bit 0: Carry Flag\n BIT1: 0x0002, // bit 1: reserved, always set\n PF: 0x0004, // bit 2: Parity Flag\n BIT3: 0x0008, // bit 3: reserved, always clear\n AF: 0x0010, // bit 4: Auxiliary Carry Flag\n BIT5: 0x0020, // bit 5: reserved, always clear\n ZF: 0x0040, // bit 6: Zero Flag\n SF: 0x0080, // bit 7: Sign Flag\n ALL: 0x00D5, // all \"arithmetic\" flags (CF, PF, AF, ZF, SF)\n MASK: 0x00FF, //\n IF: 0x0200 // bit 9: Interrupt Flag (set if interrupts enabled; Intel calls this the INTE bit)\n },\n PARITY: [ // 256-byte array with a 1 wherever the number of set bits of the array index is EVEN\n 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\n 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\n 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\n 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\n 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\n 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\n 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\n 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\n 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\n 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\n 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\n 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\n 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\n 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\n 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\n 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1\n ],\n /*\n * Interrupt-related flags (stored in intFlags)\n */\n INTFLAG: {\n NONE: 0x0000,\n INTR: 0x00ff, // mask for 8 bits, representing interrupt levels 0-7\n HALT: 0x0100 // halt requested; see opHLT()\n },\n /*\n * Opcode definitions\n */\n OPCODE: {\n HLT: 0x76, // Halt\n ACI: 0xCE, // Add with Carry Immediate (affects PS.ALL)\n CALL: 0xCD, // Call\n RST0: 0xC7\n // to be continued....\n }\n};\n\n/*\n * These are the internal PS bits (outside of PS.MASK) that getPS() and setPS() can get and set,\n * but which cannot be seen with any of the documented instructions.\n */\nCPUDef8080.PS.INTERNAL = (CPUDef8080.PS.IF);\n\n/*\n * PS \"arithmetic\" flags are NOT stored in regPS; they are maintained across separate result registers,\n * hence the RESULT designation.\n */\nCPUDef8080.PS.RESULT = (CPUDef8080.PS.CF | CPUDef8080.PS.PF | CPUDef8080.PS.AF | CPUDef8080.PS.ZF | CPUDef8080.PS.SF);\n\n/*\n * These are the \"always set\" PS bits for the 8080.\n */\nCPUDef8080.PS.SET = (CPUDef8080.PS.BIT1);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/messages.js (C) Jeff Parsons 2012-2018\n */\n\nvar Messages8080 = {\n CPU: 0x00000001,\n BUS: 0x00000040,\n MEM: 0x00000080,\n PORT: 0x00000100,\n NVR: 0x00004000,\n CHIPSET: 0x00008000,\n KEYBOARD: 0x00010000,\n KEYS: 0x00020000,\n VIDEO: 0x00040000,\n FDC: 0x00080000,\n DISK: 0x00200000,\n SERIAL: 0x00800000,\n SPEAKER: 0x02000000,\n COMPUTER: 0x04000000,\n BUFFER: 0x20000000,\n WARN: 0x40000000,\n HALT: 0x80000000|0\n};\n\n/*\n * Message categories supported by the messageEnabled() function and other assorted message\n * functions. Each category has a corresponding bit value that can be combined (ie, OR'ed) as\n * needed. The Debugger's message command (\"m\") is used to turn message categories on and off,\n * like so:\n *\n * m port on\n * m port off\n * ...\n *\n * NOTE: The order of these categories can be rearranged, alphabetized, etc, as desired; just be\n * aware that changing the bit values could break saved Debugger states (not a huge concern, just\n * something to be aware of).\n */\nMessages8080.CATEGORIES = {\n \"cpu\": Messages8080.CPU,\n \"bus\": Messages8080.BUS,\n \"mem\": Messages8080.MEM,\n \"port\": Messages8080.PORT,\n \"nvr\": Messages8080.NVR,\n \"chipset\": Messages8080.CHIPSET,\n \"keyboard\": Messages8080.KEYBOARD, // \"kbd\" is also allowed as shorthand for \"keyboard\"; see doMessages()\n \"key\": Messages8080.KEYS, // using \"key\" instead of \"keys\", since the latter is a method on JavasScript objects\n \"video\": Messages8080.VIDEO,\n \"fdc\": Messages8080.FDC,\n \"disk\": Messages8080.DISK,\n \"serial\": Messages8080.SERIAL,\n \"speaker\": Messages8080.SPEAKER,\n \"computer\": Messages8080.COMPUTER,\n /*\n * Now we turn to message actions rather than message types; for example, setting \"halt\"\n * on or off doesn't enable \"halt\" messages, but rather halts the CPU on any message above.\n *\n * Similarly, \"m buffer on\" turns on message buffering, deferring the display of all messages\n * until \"m buffer off\" is issued.\n */\n \"buffer\": Messages8080.BUFFER,\n \"warn\": Messages8080.WARN,\n \"halt\": Messages8080.HALT\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/panel.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass Panel8080 extends Component {\n /**\n * Panel8080(parmsPanel)\n *\n * The Panel8080 component has no required (parmsPanel) properties.\n *\n * @this {Panel8080}\n * @param {Object} parmsPanel\n */\n constructor(parmsPanel)\n {\n super(\"Panel\", parmsPanel);\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * Most panel layouts don't have bindings of their own, so we pass along all binding requests to the\n * Computer, CPU, Keyboard and Debugger components first. The order shouldn't matter, since any component\n * that doesn't recognize the specified binding should simply ignore it.\n *\n * @this {Panel8080}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n if (this.cmp && this.cmp.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (this.cpu && this.cpu.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (this.kbd && this.kbd.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (DEBUGGER && this.dbg && this.dbg.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n return super.setBinding(sHTMLType, sBinding, control, sValue);\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {Panel8080}\n * @param {Computer8080} cmp\n * @param {Bus8080} bus\n * @param {CPUState8080} cpu\n * @param {Debugger8080} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.kbd = /** @type {Keyboard8080} */ (cmp.getMachineComponent(\"Keyboard\"));\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {Panel8080}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) Panel8080.init();\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Panel8080}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return true;\n }\n\n /**\n * updateStatus(fForce)\n *\n * Update function for Panels containing elements with high-frequency display requirements.\n *\n * For older (and slower) DOM-based display elements, those are sill being managed by the CPUState component,\n * so it has its own updateStatus() handler.\n *\n * The Computer's updateStatus() handler is currently responsible for calling both our handler and the CPU's handler.\n *\n * @this {Panel8080}\n * @param {boolean} [fForce] (true will display registers even if the CPU is running and \"live\" registers are not enabled)\n */\n updateStatus(fForce)\n {\n }\n\n /**\n * Panel8080.init()\n *\n * This function operates on every HTML element of class \"panel\", extracting the\n * JSON-encoded parameters for the Panel8080 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Panel8080 component, and then binding\n * any associated HTML controls to the new component.\n *\n * NOTE: Unlike most other component init() functions, this one is designed to be\n * called multiple times: once at load time, so that we can bind our print()\n * function to the panel's output control ASAP, and again when the Computer component\n * is verifying that all components are ready and invoking their powerUp() functions.\n *\n * Our powerUp() method gives us a second opportunity to notify any components that\n * that might care (eg, CPU, Keyboard, and Debugger) that we have some controls they\n * might want to use.\n */\n static init()\n {\n var fReady = false;\n var aePanels = Component.getElementsByClass(document, PC8080.APPCLASS, \"panel\");\n for (var iPanel=0; iPanel < aePanels.length; iPanel++) {\n var ePanel = aePanels[iPanel];\n var parmsPanel = Component.getComponentParms(ePanel);\n var panel = Component.getComponentByID(parmsPanel['id']);\n if (!panel) {\n fReady = true;\n panel = new Panel8080(parmsPanel);\n }\n Component.bindComponentControls(panel, ePanel, PC8080.APPCLASS);\n if (fReady) panel.setReady();\n }\n }\n}\n\n/*\n * Initialize every Panel module on the page.\n */\nWeb.onInit(Panel8080.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/bus.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass Bus8080 extends Component {\n /**\n * Bus8080(cpu, dbg)\n *\n * The Bus8080 component manages physical memory and I/O address spaces.\n *\n * The Bus8080 component has no UI elements, so it does not require an init() handler,\n * but it still inherits from the Component class and must be allocated like any\n * other device component. It's currently allocated by the Computer's init() handler,\n * which then calls the initBus() method of all the other components.\n *\n * For memory beyond the simple needs of the ROM and RAM components (ie, memory-mapped\n * devices), the address space must still be allocated through the Bus8080 component via\n * addMemory(). If the component needs something more than simple read/write storage,\n * it must provide a custom controller.\n *\n * All port (I/O) operations are defined by external handlers; they register with us,\n * and we manage those registrations and provide support for I/O breakpoints, but the\n * only default I/O behavior we provide is ignoring writes to any unregistered output\n * ports and returning 0xff from any unregistered input ports.\n *\n * @this {Bus8080}\n * @param {Object} parmsBus\n * @param {CPUState8080} cpu\n * @param {Debugger8080} dbg\n */\n constructor(parmsBus, cpu, dbg)\n {\n super(\"Bus\", parmsBus);\n\n this.cpu = cpu;\n this.dbg = dbg;\n\n this.nBusWidth = parmsBus['busWidth'] || 16;\n\n /*\n * Compute all Bus8080 memory block parameters, based on the width of the bus. The entire\n * address space is divided into blocks, using a block size that is (hopefully) appropriate to\n * the bus width. The following table summarizes our simplistic calculations.\n *\n * Bus Width Block Shift Block Size\n * --------- ----------- ----------\n * 16 bits (64Kb address space): 10 1Kb (64 maximum blocks)\n * 18 bits (256Kb address space): 11 2Kb (128 maximum blocks)\n * 20 bits (1Mb address space): 12 4Kb (256 maximum blocks)\n * 22 bits (4Mb address space): 13 8Kb (512 maximum blocks)\n * 24 bits (16Mb address space): 14 16Kb (1K maximum blocks)\n * 32 bits (4Gb address space); 15 32Kb (128K maximum blocks)\n *\n * The coarser block granularities (ie, 16Kb and 32Kb) may cause problems for certain RAM and/or ROM\n * allocations that are contiguous but are allocated out of order, or that have different controller\n * requirements. Your choices, for the moment, are either to ensure the allocations are performed in\n * order, or to choose smaller nBlockShift values (at the expense of a generating a larger block array).\n */\n this.addrTotal = Math.pow(2, this.nBusWidth);\n this.nBusLimit = this.nBusMask = (this.addrTotal - 1) | 0;\n this.nBlockShift = (this.nBusWidth >> 1) + 2;\n if (this.nBlockShift < 10) this.nBlockShift = 10;\n if (this.nBlockShift > 15) this.nBlockShift = 15;\n this.nBlockSize = 1 << this.nBlockShift;\n this.nBlockLen = this.nBlockSize >> 2;\n this.nBlockLimit = this.nBlockSize - 1;\n this.nBlockTotal = (this.addrTotal / this.nBlockSize) | 0;\n this.nBlockMask = this.nBlockTotal - 1;\n\n\n /*\n * Lists of I/O notification functions: aPortInputNotify and aPortOutputNotify are arrays, indexed by\n * port, of sub-arrays which contain:\n *\n * [0]: registered function to call for every I/O access\n *\n * The registered function is called with the port address, and if the access was triggered by the CPU,\n * the instruction pointer (IP) at the point of access.\n *\n * WARNING: Unlike the (old) read and write memory notification functions, these support only one\n * pair of input/output functions per port. A more sophisticated architecture could support a list\n * of chained functions across multiple components, but I doubt that will be necessary here.\n *\n * UPDATE: The Debugger now piggy-backs on these arrays to indicate ports for which it wants notification\n * of I/O. In those cases, the registered component/function elements may or may not be set, but the\n * following additional element will be set:\n *\n * [1]: true to break on I/O, false to ignore I/O\n *\n * The false case is important if fPortInputBreakAll and/or fPortOutputBreakAll is set, because it allows the\n * Debugger to selectively ignore specific ports.\n */\n this.aPortInputNotify = [];\n this.aPortOutputNotify = [];\n this.fPortInputBreakAll = this.fPortOutputBreakAll = false;\n\n /*\n * By default, all I/O ports are 1 byte wide; ports that are wider must add themselves to one or both of\n * these lists, using addPortInputWidth() and/or addPortOutputWidth().\n */\n this.aPortInputWidth = [];\n this.aPortOutputWidth = [];\n\n /*\n * Allocate empty Memory blocks to span the entire physical address space.\n */\n this.initMemory();\n\n this.setReady();\n }\n\n /**\n * initMemory()\n *\n * Allocate enough (empty) Memory blocks to span the entire physical address space.\n *\n * @this {Bus8080}\n */\n initMemory()\n {\n var block = new Memory8080();\n block.copyBreakpoints(this.dbg);\n this.aMemBlocks = new Array(this.nBlockTotal);\n for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {\n this.aMemBlocks[iBlock] = block;\n }\n }\n\n /**\n * reset()\n *\n * @this {Bus8080}\n */\n reset()\n {\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * We don't need a powerDown() handler, because for largely historical reasons, our state is saved by saveMemory(),\n * which called by the CPU.\n *\n * However, we do need a powerUp() handler, because on resumable machines, the Computer's onReset() function calls\n * everyone's powerUp() handler rather than their reset() handler.\n *\n * TODO: Perhaps Computer should be smarter: if there's no powerUp() handler, then fallback to the reset() handler.\n * In that case, however, we'd either need to remove the powerUp() stub in Component, or detect the existence of the stub.\n *\n * @this {Bus8080}\n * @param {Object|null} data (always null because we supply no powerDown() handler)\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) this.reset();\n return true;\n }\n\n /**\n * addMemory(addr, size, type)\n *\n * Adds new Memory blocks to the specified address range. Any Memory blocks previously\n * added to that range must first be removed via removeMemory(); otherwise, you'll get\n * an allocation conflict error. This helps prevent address calculation errors, redundant\n * allocations, etc.\n *\n * We've relaxed some of the original requirements (ie, that addresses must start at a\n * block-granular address, or that sizes must be equal to exactly one or more blocks),\n * because machines with large block sizes can make it impossible to load certain ROMs at\n * their required addresses. Every allocation still allocates a whole number of blocks.\n *\n * Even so, Bus8080 memory management does NOT provide a general-purpose heap. Most memory\n * allocations occur during machine initialization and never change. In particular, there\n * is NO support for removing partial-block allocations.\n *\n * Each Memory block keeps track of a start address (addr) and length (used), indicating\n * the used space within the block; any free space that precedes or follows that used space\n * can be allocated later, by simply extending the beginning or ending of the previously used\n * space. However, any holes that might have existed between the original allocation and an\n * extension are subsumed by the extension.\n *\n * @this {Bus8080}\n * @param {number} addr is the starting physical address of the request\n * @param {number} size of the request, in bytes\n * @param {number} type is one of the Memory8080.TYPE constants\n * @return {boolean} true if successful, false if not\n */\n addMemory(addr, size, type)\n {\n var addrNext = addr;\n var sizeLeft = size;\n var iBlock = addrNext >>> this.nBlockShift;\n\n while (sizeLeft > 0 && iBlock < this.aMemBlocks.length) {\n\n var block = this.aMemBlocks[iBlock];\n var addrBlock = iBlock * this.nBlockSize;\n var sizeBlock = this.nBlockSize - (addrNext - addrBlock);\n if (sizeBlock > sizeLeft) sizeBlock = sizeLeft;\n\n if (block && block.size) {\n if (block.type == type) {\n /*\n * Where there is already a similar block with a non-zero size, we allow the allocation only if:\n *\n * 1) addrNext + sizeLeft <= block.addr (the request precedes the used portion of the current block), or\n * 2) addrNext >= block.addr + block.used (the request follows the used portion of the current block)\n */\n if (addrNext + sizeLeft <= block.addr) {\n block.used += (block.addr - addrNext);\n block.addr = addrNext;\n return true;\n }\n if (addrNext >= block.addr + block.used) {\n var sizeAvail = block.size - (addrNext - addrBlock);\n if (sizeAvail > sizeLeft) sizeAvail = sizeLeft;\n block.used = addrNext - block.addr + sizeAvail;\n addrNext = addrBlock + this.nBlockSize;\n sizeLeft -= sizeAvail;\n iBlock++;\n continue;\n }\n }\n return this.reportError(Bus8080.ERROR.ADD_MEM_INUSE, addrNext, sizeLeft);\n }\n\n var blockNew = new Memory8080(addrNext, sizeBlock, this.nBlockSize, type);\n blockNew.copyBreakpoints(this.dbg, block);\n this.aMemBlocks[iBlock++] = blockNew;\n\n addrNext = addrBlock + this.nBlockSize;\n sizeLeft -= sizeBlock;\n }\n\n if (sizeLeft <= 0) {\n this.status(Math.floor(size / 1024) + \"Kb \" + Memory8080.TYPE.NAMES[type] + \" at \" + Str.toHexWord(addr));\n return true;\n }\n\n return this.reportError(Bus8080.ERROR.ADD_MEM_BADRANGE, addr, size);\n }\n\n /**\n * cleanMemory(addr, size)\n *\n * @this {Bus8080}\n * @param {number} addr\n * @param {number} size\n * @return {boolean} true if all blocks were clean, false if dirty; all blocks are cleaned in the process\n */\n cleanMemory(addr, size)\n {\n var fClean = true;\n var iBlock = addr >>> this.nBlockShift;\n var sizeBlock = this.nBlockSize - (addr & this.nBlockLimit);\n while (size > 0 && iBlock < this.aMemBlocks.length) {\n if (this.aMemBlocks[iBlock].fDirty) {\n this.aMemBlocks[iBlock].fDirty = fClean = false;\n this.aMemBlocks[iBlock].fDirtyEver = true;\n }\n size -= sizeBlock;\n sizeBlock = this.nBlockSize;\n iBlock++;\n }\n return fClean;\n }\n\n /**\n * scanMemory(info, addr, size)\n *\n * Returns a BusInfo8080 object for the specified address range.\n *\n * @this {Bus8080}\n * @param {Object} [info] previous BusInfo8080, if any\n * @param {number} [addr] starting address of range (0 if none provided)\n * @param {number} [size] size of range, in bytes (up to end of address space if none provided)\n * @return {Object} updated info (or new info if no previous info provided)\n */\n scanMemory(info, addr, size)\n {\n if (addr == null) addr = 0;\n if (size == null) size = (this.addrTotal - addr) | 0;\n if (info == null) info = {cbTotal: 0, cBlocks: 0, aBlocks: []};\n\n var iBlock = addr >>> this.nBlockShift;\n var iBlockMax = ((addr + size - 1) >>> this.nBlockShift);\n\n info.cbTotal = 0;\n info.cBlocks = 0;\n while (iBlock <= iBlockMax) {\n var block = this.aMemBlocks[iBlock];\n info.cbTotal += block.size;\n if (block.size) {\n info.aBlocks.push(Usr.initBitFields(Bus8080.BlockInfo, iBlock, 0, 0, block.type));\n info.cBlocks++\n }\n iBlock++;\n }\n return info;\n }\n\n /**\n * getWidth()\n *\n * @this {Bus8080}\n * @return {number}\n */\n getWidth()\n {\n return this.nBusWidth;\n }\n\n /**\n * removeMemory(addr, size)\n *\n * Replaces every block in the specified address range with empty Memory blocks that ignore all reads/writes.\n *\n * TODO: Update the removeMemory() interface to reflect the relaxed requirements of the addMemory() interface.\n *\n * @this {Bus8080}\n * @param {number} addr\n * @param {number} size\n * @return {boolean} true if successful, false if not\n */\n removeMemory(addr, size)\n {\n if (!(addr & this.nBlockLimit) && size && !(size & this.nBlockLimit)) {\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0) {\n var blockOld = this.aMemBlocks[iBlock];\n var blockNew = new Memory8080(addr);\n blockNew.copyBreakpoints(this.dbg, blockOld);\n this.aMemBlocks[iBlock++] = blockNew;\n addr = iBlock * this.nBlockSize;\n size -= this.nBlockSize;\n }\n return true;\n }\n return this.reportError(Bus8080.ERROR.REM_MEM_BADRANGE, addr, size);\n }\n\n /**\n * getMemoryBlocks(addr, size)\n *\n * @this {Bus8080}\n * @param {number} addr is the starting physical address\n * @param {number} size of the request, in bytes\n * @return {Array} of Memory blocks\n */\n getMemoryBlocks(addr, size)\n {\n var aBlocks = [];\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0 && iBlock < this.aMemBlocks.length) {\n aBlocks.push(this.aMemBlocks[iBlock++]);\n size -= this.nBlockSize;\n }\n return aBlocks;\n }\n\n /**\n * setMemoryBlocks(addr, size, aBlocks, type)\n *\n * If no type is specified, then specified address range uses all the provided blocks as-is;\n * this form of setMemoryBlocks() is used for complete physical aliases.\n *\n * Otherwise, new blocks are allocated with the specified type; the underlying memory from the\n * provided blocks is still used, but the new blocks may have different access to that memory.\n *\n * @this {Bus8080}\n * @param {number} addr is the starting physical address\n * @param {number} size of the request, in bytes\n * @param {Array} aBlocks as returned by getMemoryBlocks()\n * @param {number} [type] is one of the Memory8080.TYPE constants\n */\n setMemoryBlocks(addr, size, aBlocks, type)\n {\n var i = 0;\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0 && iBlock < this.aMemBlocks.length) {\n var block = aBlocks[i++];\n\n if (!block) break;\n if (type !== undefined) {\n var blockNew = new Memory8080(addr);\n blockNew.clone(block, type, this.dbg);\n block = blockNew;\n }\n this.aMemBlocks[iBlock++] = block;\n size -= this.nBlockSize;\n }\n }\n\n /**\n * getByte(addr)\n *\n * @this {Bus8080}\n * @param {number} addr is a physical address\n * @return {number} byte (8-bit) value at that address\n */\n getByte(addr)\n {\n return this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].readByte(addr & this.nBlockLimit, addr);\n }\n\n /**\n * getByteDirect(addr)\n *\n * This is useful for the Debugger and other components that want to bypass getByte() breakpoint detection.\n *\n * @this {Bus8080}\n * @param {number} addr is a physical address\n * @return {number} byte (8-bit) value at that address\n */\n getByteDirect(addr)\n {\n return this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].readByteDirect(addr & this.nBlockLimit, addr);\n }\n\n /**\n * getShort(addr)\n *\n * @this {Bus8080}\n * @param {number} addr is a physical address\n * @return {number} word (16-bit) value at that address\n */\n getShort(addr)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off != this.nBlockLimit) {\n return this.aMemBlocks[iBlock].readShort(off, addr);\n }\n return this.aMemBlocks[iBlock++].readByte(off, addr) | (this.aMemBlocks[iBlock & this.nBlockMask].readByte(0, addr + 1) << 8);\n }\n\n /**\n * getShortDirect(addr)\n *\n * This is useful for the Debugger and other components that want to bypass getShort() breakpoint detection.\n *\n * @this {Bus8080}\n * @param {number} addr is a physical address\n * @return {number} word (16-bit) value at that address\n */\n getShortDirect(addr)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off != this.nBlockLimit) {\n return this.aMemBlocks[iBlock].readShortDirect(off, addr);\n }\n return this.aMemBlocks[iBlock++].readByteDirect(off, addr) | (this.aMemBlocks[iBlock & this.nBlockMask].readByteDirect(0, addr + 1) << 8);\n }\n\n /**\n * setByte(addr, b)\n *\n * @this {Bus8080}\n * @param {number} addr is a physical address\n * @param {number} b is the byte (8-bit) value to write (we truncate it to 8 bits to be safe)\n */\n setByte(addr, b)\n {\n this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].writeByte(addr & this.nBlockLimit, b & 0xff, addr);\n }\n\n /**\n * setByteDirect(addr, b)\n *\n * This is useful for the Debugger and other components that want to bypass breakpoint detection AND read-only\n * memory protection (for example, this is an interface the ROM component could use to initialize ROM contents).\n *\n * @this {Bus8080}\n * @param {number} addr is a physical address\n * @param {number} b is the byte (8-bit) value to write (we truncate it to 8 bits to be safe)\n */\n setByteDirect(addr, b)\n {\n this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].writeByteDirect(addr & this.nBlockLimit, b & 0xff, addr);\n }\n\n /**\n * setShort(addr, w)\n *\n * @this {Bus8080}\n * @param {number} addr is a physical address\n * @param {number} w is the word (16-bit) value to write (we truncate it to 16 bits to be safe)\n */\n setShort(addr, w)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off != this.nBlockLimit) {\n this.aMemBlocks[iBlock].writeShort(off, w & 0xffff, addr);\n return;\n }\n this.aMemBlocks[iBlock++].writeByte(off, w & 0xff, addr);\n this.aMemBlocks[iBlock & this.nBlockMask].writeByte(0, (w >> 8) & 0xff, addr + 1);\n }\n\n /**\n * setShortDirect(addr, w)\n *\n * This is useful for the Debugger and other components that want to bypass breakpoint detection AND read-only\n * memory protection (for example, this is an interface the ROM component could use to initialize ROM contents).\n *\n * @this {Bus8080}\n * @param {number} addr is a physical address\n * @param {number} w is the word (16-bit) value to write (we truncate it to 16 bits to be safe)\n */\n setShortDirect(addr, w)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off != this.nBlockLimit) {\n this.aMemBlocks[iBlock].writeShortDirect(off, w & 0xffff, addr);\n return;\n }\n this.aMemBlocks[iBlock++].writeByteDirect(off, w & 0xff, addr);\n this.aMemBlocks[iBlock & this.nBlockMask].writeByteDirect(0, (w >> 8) & 0xff, addr + 1);\n }\n\n /**\n * addMemBreak(addr, fWrite)\n *\n * @this {Bus8080}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint\n */\n addMemBreak(addr, fWrite)\n {\n if (DEBUGGER) {\n var iBlock = addr >>> this.nBlockShift;\n this.aMemBlocks[iBlock].addBreakpoint(addr & this.nBlockLimit, fWrite);\n }\n }\n\n /**\n * removeMemBreak(addr, fWrite)\n *\n * @this {Bus8080}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint\n */\n removeMemBreak(addr, fWrite)\n {\n if (DEBUGGER) {\n var iBlock = addr >>> this.nBlockShift;\n this.aMemBlocks[iBlock].removeBreakpoint(addr & this.nBlockLimit, fWrite);\n }\n }\n\n /**\n * saveMemory(fAll)\n *\n * The only memory blocks we save are those marked as dirty, but most likely all of RAM will have been marked dirty,\n * and even if our dirty-memory flags were as smart as our dirty-sector flags (ie, were set only when a write changed\n * what was already there), it's unlikely that would reduce the number of RAM blocks we must save/restore. At least\n * all the ROM blocks should be clean (except in the unlikely event that the Debugger was used to modify them).\n *\n * All dirty blocks will be stored in a single array, as pairs of block numbers and data arrays, like so:\n *\n * [iBlock0, [dw0, dw1, ...], iBlock1, [dw0, dw1, ...], ...]\n *\n * In a normal 4Kb block, there will be 1K DWORD values in the data array. Remember that each DWORD is a signed 32-bit\n * integer (because they are formed using bitwise operator rather than floating-point math operators), so don't be\n * surprised to see negative numbers in the data.\n *\n * The above example assumes \"uncompressed\" data arrays. If we choose to use \"compressed\" data arrays, the data arrays\n * will look like:\n *\n * [count0, dw0, count1, dw1, ...]\n *\n * where each count indicates how many times the following DWORD value occurs. A data array length less than 1K indicates\n * that it's compressed, since we'll only store them in compressed form if they actually shrank, and we'll use State\n * helper methods compress() and decompress() to create and expand the compressed data arrays.\n *\n * @this {Bus8080}\n * @param {boolean} [fAll] (true to save all non-ROM memory blocks, regardless of their dirty flags)\n * @return {Array} a\n */\n saveMemory(fAll)\n {\n var i = 0;\n var a = [];\n\n for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {\n var block = this.aMemBlocks[iBlock];\n /*\n * We have to check both fDirty and fDirtyEver, because we may have called cleanMemory() on some of\n * the memory blocks (eg, video memory), and while cleanMemory() will clear a dirty block's fDirty flag,\n * it also sets the dirty block's fDirtyEver flag, which is left set for the lifetime of the machine.\n */\n if (fAll && block.type != Memory8080.TYPE.ROM || block.fDirty || block.fDirtyEver) {\n a[i++] = iBlock;\n a[i++] = State.compress(block.save());\n }\n }\n\n return a;\n }\n\n /**\n * restoreMemory(a)\n *\n * This restores the contents of all Memory blocks; called by CPUState.restore().\n *\n * In theory, we ONLY have to save/restore block contents. Other block attributes,\n * like the type, the memory controller (if any), and the active memory access functions,\n * should already be restored, since every component (re)allocates all the memory blocks\n * it was using when it's restored. And since the CPU is guaranteed to be the last\n * component to be restored, all those blocks (and their attributes) should be in place now.\n *\n * See saveMemory() for more information on how the memory block contents are saved.\n *\n * @this {Bus8080}\n * @param {Array} a\n * @return {boolean} true if successful, false if not\n */\n restoreMemory(a)\n {\n var i;\n for (i = 0; i < a.length - 1; i += 2) {\n var iBlock = a[i];\n var adw = a[i+1];\n if (adw && adw.length < this.nBlockLen) {\n adw = State.decompress(adw, this.nBlockLen);\n }\n var block = this.aMemBlocks[iBlock];\n if (!block || !block.restore(adw)) {\n /*\n * Either the block to restore hasn't been allocated, indicating a change in the machine\n * configuration since it was last saved (the most likely explanation) or there's some internal\n * inconsistency (eg, the block size is wrong).\n */\n Component.error(\"Unable to restore memory block \" + iBlock);\n return false;\n }\n }\n return true;\n }\n\n /**\n * addPortInputBreak(port)\n *\n * @this {Bus8080}\n * @param {number} [port]\n * @return {boolean} true if break on port input enabled, false if disabled\n */\n addPortInputBreak(port)\n {\n if (port === undefined) {\n this.fPortInputBreakAll = !this.fPortInputBreakAll;\n return this.fPortInputBreakAll;\n }\n if (this.aPortInputNotify[port] === undefined) {\n this.aPortInputNotify[port] = [null, false];\n }\n this.aPortInputNotify[port][1] = !this.aPortInputNotify[port][1];\n return this.aPortInputNotify[port][1];\n }\n\n /**\n * addPortInputNotify(start, end, fn)\n *\n * Add a port input-notification handler to the list of such handlers.\n *\n * @this {Bus8080}\n * @param {number} start port address\n * @param {number} end port address\n * @param {function(number,number)} fn is called with the port and IP values at the time of the input\n */\n addPortInputNotify(start, end, fn)\n {\n if (fn !== undefined) {\n for (var port = start; port <= end; port++) {\n if (this.aPortInputNotify[port] !== undefined) {\n Component.warning(\"Input port \" + Str.toHexWord(port) + \" already registered\");\n continue;\n }\n this.aPortInputNotify[port] = [fn, false];\n if (MAXDEBUG) this.log(\"addPortInputNotify(\" + Str.toHexWord(port) + \")\");\n }\n }\n }\n\n /**\n * addPortInputTable(component, table, offset)\n *\n * Add port input-notification handlers from the specified table (a batch version of addPortInputNotify)\n *\n * @this {Bus8080}\n * @param {Component} component\n * @param {Object} table\n * @param {number} [offset] is an optional port offset\n */\n addPortInputTable(component, table, offset)\n {\n if (offset === undefined) offset = 0;\n if (table) {\n for (var port in table) {\n this.addPortInputNotify(+port + offset, +port + offset, table[port].bind(component));\n }\n }\n }\n\n /**\n * addPortInputWidth(port, size)\n *\n * By default, all input ports are 1 byte wide; ports that are wider must call this function.\n *\n * @this {Bus8080}\n * @param {number} port\n * @param {number} size (1, 2 or 4)\n */\n addPortInputWidth(port, size)\n {\n this.aPortInputWidth[port] = size;\n }\n\n /**\n * checkPortInputNotify(port, size, addrIP)\n *\n * @this {Bus8080}\n * @param {number} port\n * @param {number} size (1, 2 or 4)\n * @param {number} [addrIP] is the IP value at the time of the input\n * @return {number} simulated port data\n *\n * NOTE: It seems that parts of the ROM BIOS (like the RS-232 probes around F000:E5D7 in the 5150 BIOS)\n * assume that ports for non-existent hardware return 0xff rather than 0x00, hence my new default (0xff) below.\n */\n checkPortInputNotify(port, size, addrIP)\n {\n var data = 0, shift = 0;\n\n while (size > 0) {\n\n var aNotify = this.aPortInputNotify[port];\n var sizePort = this.aPortInputWidth[port] || 1;\n var maskPort = (sizePort == 1? 0xff : (sizePort == 2? 0xffff : -1));\n var dataPort = maskPort;\n\n /*\n * TODO: We need to decide what to do about 8-bit I/O to a 16-bit port (ditto for 16-bit I/O\n * to a 32-bit port). We probably should pass the size through to the aNotify[0] handler,\n * and let it decide what to do, but I don't feel like changing all the I/O handlers right now.\n * The good news, at least, is that the 8-bit handlers would not have to do anything special.\n * This assert will warn us if this is a pressing need.\n */\n\n\n if (aNotify !== undefined) {\n if (aNotify[0]) {\n dataPort = aNotify[0](port, addrIP);\n if (dataPort === undefined) {\n dataPort = maskPort;\n } else {\n dataPort &= maskPort;\n }\n }\n if (DEBUGGER && this.dbg && this.fPortInputBreakAll != aNotify[1]) {\n this.dbg.checkPortInput(port, size, dataPort);\n }\n }\n else {\n if (DEBUGGER && this.dbg) {\n this.dbg.messageIO(this, port, null, addrIP);\n if (this.fPortInputBreakAll) this.dbg.checkPortInput(port, size, dataPort);\n }\n }\n\n data |= dataPort << shift;\n shift += (sizePort << 3);\n port += sizePort;\n size -= sizePort;\n }\n\n\n return data;\n }\n\n /**\n * addPortOutputBreak(port)\n *\n * @this {Bus8080}\n * @param {number} [port]\n * @return {boolean} true if break on port output enabled, false if disabled\n */\n addPortOutputBreak(port)\n {\n if (port === undefined) {\n this.fPortOutputBreakAll = !this.fPortOutputBreakAll;\n return this.fPortOutputBreakAll;\n }\n if (this.aPortOutputNotify[port] === undefined) {\n this.aPortOutputNotify[port] = [null, false];\n }\n this.aPortOutputNotify[port][1] = !this.aPortOutputNotify[port][1];\n return this.aPortOutputNotify[port][1];\n }\n\n /**\n * addPortOutputNotify(start, end, fn)\n *\n * Add a port output-notification handler to the list of such handlers.\n *\n * @this {Bus8080}\n * @param {number} start port address\n * @param {number} end port address\n * @param {function(number,number)} fn is called with the port and IP values at the time of the output\n */\n addPortOutputNotify(start, end, fn)\n {\n if (fn !== undefined) {\n for (var port = start; port <= end; port++) {\n if (this.aPortOutputNotify[port] !== undefined) {\n Component.warning(\"Output port \" + Str.toHexWord(port) + \" already registered\");\n continue;\n }\n this.aPortOutputNotify[port] = [fn, false];\n if (MAXDEBUG) this.log(\"addPortOutputNotify(\" + Str.toHexWord(port) + \")\");\n }\n }\n }\n\n /**\n * addPortOutputTable(component, table, offset)\n *\n * Add port output-notification handlers from the specified table (a batch version of addPortOutputNotify)\n *\n * @this {Bus8080}\n * @param {Component} component\n * @param {Object} table\n * @param {number} [offset] is an optional port offset\n */\n addPortOutputTable(component, table, offset)\n {\n if (offset === undefined) offset = 0;\n if (table) {\n for (var port in table) {\n this.addPortOutputNotify(+port + offset, +port + offset, table[port].bind(component));\n }\n }\n }\n\n /**\n * addPortOutputWidth(port, size)\n *\n * By default, all output ports are 1 byte wide; ports that are wider must call this function.\n *\n * @this {Bus8080}\n * @param {number} port\n * @param {number} size (1, 2 or 4)\n */\n addPortOutputWidth(port, size)\n {\n this.aPortOutputWidth[port] = size;\n }\n\n /**\n * checkPortOutputNotify(port, size, data, addrIP)\n *\n * @this {Bus8080}\n * @param {number} port\n * @param {number} size\n * @param {number} data\n * @param {number} [addrIP] is the IP value at the time of the output\n */\n checkPortOutputNotify(port, size, data, addrIP)\n {\n var shift = 0;\n\n while (size > 0) {\n\n var aNotify = this.aPortOutputNotify[port];\n var sizePort = this.aPortOutputWidth[port] || 1;\n var maskPort = (sizePort == 1? 0xff : (sizePort == 2? 0xffff : -1));\n var dataPort = (data >>>= shift) & maskPort;\n\n /*\n * TODO: We need to decide what to do about 8-bit I/O to a 16-bit port (ditto for 16-bit I/O\n * to a 32-bit port). We probably should pass the size through to the aNotify[0] handler,\n * and let it decide what to do, but I don't feel like changing all the I/O handlers right now.\n * The good news, at least, is that the 8-bit handlers would not have to do anything special.\n * This assert will warn us if this is a pressing need.\n */\n\n\n if (aNotify !== undefined) {\n if (aNotify[0]) {\n aNotify[0](port, dataPort, addrIP);\n }\n if (DEBUGGER && this.dbg && this.fPortOutputBreakAll != aNotify[1]) {\n this.dbg.checkPortOutput(port, size, dataPort);\n }\n }\n else {\n if (DEBUGGER && this.dbg) {\n this.dbg.messageIO(this, port, dataPort, addrIP);\n if (this.fPortOutputBreakAll) this.dbg.checkPortOutput(port, size, dataPort);\n }\n }\n\n shift += (sizePort << 3);\n port += sizePort;\n size -= sizePort;\n }\n\n }\n\n /**\n * removePortInputNotify(start, end)\n *\n * Remove port input-notification handler(s) (to be ENABLED later if needed)\n *\n * @this {Bus8080}\n * @param {number} start address\n * @param {number} end address\n *\n removePortInputNotify(start, end)\n {\n for (var port = start; port < end; port++) {\n if (this.aPortInputNotify[port]) {\n delete this.aPortInputNotify[port];\n }\n }\n }\n */\n\n /**\n * removePortOutputNotify(start, end)\n *\n * Remove port output-notification handler(s) (to be ENABLED later if needed)\n *\n * @this {Bus8080}\n * @param {number} start address\n * @param {number} end address\n *\n removePortOutputNotify(start, end)\n {\n for (var port = start; port < end; port++) {\n if (this.aPortOutputNotify[port]) {\n delete this.aPortOutputNotify[port];\n }\n }\n }\n */\n\n /**\n * reportError(op, addr, size, fQuiet)\n *\n * @this {Bus8080}\n * @param {number} op\n * @param {number} addr\n * @param {number} size\n * @param {boolean} [fQuiet] (true if any error should be quietly logged)\n * @return {boolean} false\n */\n reportError(op, addr, size, fQuiet)\n {\n var sError = \"Memory block error (\" + op + \": \" + Str.toHex(addr) + \",\" + Str.toHex(size) + \")\";\n if (fQuiet) {\n if (this.dbg) {\n this.dbg.message(sError);\n } else {\n this.log(sError);\n }\n } else {\n Component.error(sError);\n }\n return false;\n }\n}\n\nBus8080.ERROR = {\n ADD_MEM_INUSE: 1,\n ADD_MEM_BADRANGE: 2,\n SET_MEM_BADRANGE: 4,\n REM_MEM_BADRANGE: 5\n};\n\n/*\n * Data types used by scanMemory()\n */\n\n/**\n * @typedef {number}\n */\nvar BlockInfo;\n\n/**\n * This defines the BlockInfo bit fields used by scanMemory() when it creates the aBlocks array.\n *\n * @typedef {{\n * num: BitField,\n * count: BitField,\n * btmod: BitField,\n * type: BitField\n * }}\n */\nBus8080.BlockInfo = Usr.defineBitFields({num:20, count:8, btmod:1, type:3});\n\n/**\n * BusInfo8080 object definition (returned by scanMemory())\n *\n * cbTotal: total bytes allocated\n * cBlocks: total Memory blocks allocated\n * aBlocks: array of allocated Memory block numbers\n *\n * @typedef {{\n * cbTotal: number,\n * cBlocks: number,\n * aBlocks: Array.<BlockInfo>\n * }}\n */\nvar BusInfo8080;\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/memory.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * @class DataView\n * @property {function(number,boolean):number} getUint8\n * @property {function(number,number,boolean)} setUint8\n * @property {function(number,boolean):number} getUint16\n * @property {function(number,number,boolean)} setUint16\n * @property {function(number,boolean):number} getInt32\n * @property {function(number,number,boolean)} setInt32\n */\n\nvar littleEndian = (TYPEDARRAYS? (function() {\n var buffer = new ArrayBuffer(2);\n new DataView(buffer).setUint16(0, 256, true);\n return new Uint16Array(buffer)[0] === 256;\n})() : false);\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass Memory8080 {\n /**\n * Memory8080(addr, used, size, type)\n *\n * The Bus component allocates Memory8080 objects so that each has a memory buffer with a\n * block-granular starting address and an address range equal to bus.nBlockSize; however,\n * the size of any given Memory8080 object's underlying buffer can be either zero or bus.nBlockSize;\n * memory read/write functions for empty (buffer-less) blocks are mapped to readNone/writeNone.\n *\n * The Bus allocates empty blocks for the entire address space during initialization, so that\n * any reads/writes to undefined addresses will have no effect. Later, the ROM and RAM\n * components will ask the Bus to allocate memory for specific ranges, and the Bus will allocate\n * as many new blockSize Memory8080 objects as the ranges require. Partial Memory8080 blocks could\n * also be supported in theory, but in practice, they're not.\n *\n * Because Memory8080 blocks now allow us to have a \"sparse\" address space, we could choose to\n * take the memory hit of allocating 4K arrays per block, where each element stores only one byte,\n * instead of the more frugal but slightly slower approach of allocating arrays of 32-bit dwords\n * (LONGARRAYS) and shifting/masking bytes/words to/from dwords; in theory, byte accesses would\n * be faster and word accesses somewhat less faster.\n *\n * However, preliminary testing of that feature (BYTEARRAYS) did not yield significantly faster\n * performance, so it is OFF by default to minimize our memory consumption. Using TYPEDARRAYS\n * would seem best, but as discussed in defines.js, it's off by default, because it doesn't perform\n * as well as LONGARRAYS; the other advantage of TYPEDARRAYS is that it should theoretically use\n * about 1/2 the memory of LONGARRAYS (32-bit elements vs 64-bit numbers), but I value speed over\n * size at this point. Also, not all JavaScript implementations support TYPEDARRAYS (IE9 is probably\n * the only real outlier: it lacks typed arrays but otherwise has all the necessary HTML5 support).\n *\n * WARNING: Since Memory8080 blocks are low-level objects that have no UI requirements, they\n * do not inherit from the Component class, so if you want to use any Component class methods,\n * such as Component.assert(), use the corresponding Debugger methods instead (assuming a debugger\n * is available).\n *\n * @this {Memory8080}\n * @param {number|null} [addr] of lowest used address in block\n * @param {number} [used] portion of block in bytes (0 for none); must be a multiple of 4\n * @param {number} [size] of block's buffer in bytes (0 for none); must be a multiple of 4\n * @param {number} [type] is one of the Memory8080.TYPE constants (default is Memory8080.TYPE.NONE)\n */\n constructor(addr, used, size, type)\n {\n var i;\n this.id = (Memory8080.idBlock += 2);\n this.adw = null;\n this.offset = 0;\n this.addr = addr;\n this.used = used;\n this.size = size || 0;\n this.type = type || Memory8080.TYPE.NONE;\n this.fReadOnly = (type == Memory8080.TYPE.ROM);\n this.copyBreakpoints(); // initialize the block's Debugger info; the caller will reinitialize\n\n /*\n * TODO: Study the impact of dirty block tracking. The original purposes were to allow saveMemory()\n * to save only dirty blocks, and to enable the Video component to quickly detect changes to the video buffer.\n * But the benefit to saveMemory() is minimal, and the Video component has other options; for example, it now\n * uses a custom memory controller for all EGA/VGA video modes, which performs its own dirty block tracking,\n * and that could easily be extended to the older MDA/CGA video modes, which still use conventional memory blocks.\n * Alternatively, we could restrict the use of dirty block tracking to certain memory types (eg, VIDEO memory).\n *\n * However, a quick test with dirty block tracking disabled didn't yield a noticeable improvement in performance,\n * so I think the overhead of our block-based architecture is swamping the impact of these micro-updates.\n */\n this.fDirty = this.fDirtyEver = false;\n\n /*\n * For empty memory blocks, all we need to do is ensure all access functions are mapped to \"none\" handlers.\n */\n if (!size) {\n this.setAccess();\n return;\n }\n\n /*\n * This is the normal case: allocate a buffer that provides 8 bits of data per address;\n * no controller is required because our default memory access functions (see afnMemory)\n * know how to deal with this simple 1-1 mapping of addresses to bytes and words.\n *\n * TODO: Consider initializing the memory array to random (or pseudo-random) values in DEBUG\n * mode; pseudo-random might be best, to help make any bugs reproducible.\n */\n if (TYPEDARRAYS) {\n this.buffer = new ArrayBuffer(size);\n this.dv = new DataView(this.buffer, 0, size);\n /*\n * If littleEndian is true, we can use ab[], aw[] and adw[] directly; well, we can use them\n * whenever the offset is a multiple of 1, 2 or 4, respectively. Otherwise, we must fallback to\n * dv.getUint8()/dv.setUint8(), dv.getUint16()/dv.setUint16() and dv.getInt32()/dv.setInt32().\n */\n this.ab = new Uint8Array(this.buffer, 0, size);\n this.aw = new Uint16Array(this.buffer, 0, size >> 1);\n this.adw = new Int32Array(this.buffer, 0, size >> 2);\n this.setAccess(littleEndian? Memory8080.afnArrayLE : Memory8080.afnArrayBE);\n } else {\n if (BYTEARRAYS) {\n this.ab = new Array(size);\n } else {\n /*\n * NOTE: This is the default mode of operation (!TYPEDARRAYS && !BYTEARRAYS), because it\n * seems to provide the best performance; and although in theory, that performance might\n * come at twice the overhead of TYPEDARRAYS, it's increasingly likely that the JavaScript\n * runtime will notice that all we ever store are 32-bit values, and optimize accordingly.\n */\n this.adw = new Array(size >> 2);\n for (i = 0; i < this.adw.length; i++) this.adw[i] = 0;\n }\n this.setAccess(Memory8080.afnMemory);\n }\n }\n\n /**\n * init(addr)\n *\n * Quick reinitializer when reusing a Memory8080 block.\n *\n * @this {Memory8080}\n * @param {number} addr\n */\n init(addr)\n {\n this.addr = addr;\n }\n\n /**\n * clone(mem, type)\n *\n * Converts the current Memory8080 block (this) into a clone of the given Memory8080 block (mem),\n * and optionally overrides the current block's type with the specified type.\n *\n * @this {Memory8080}\n * @param {Memory8080} mem\n * @param {number} [type]\n * @param {Debugger8080} [dbg]\n */\n clone(mem, type, dbg)\n {\n /*\n * Original memory block IDs are even; cloned memory block IDs are odd;\n * the original ID of the current block is lost, but that's OK, since it was presumably\n * produced merely to become a clone.\n */\n this.id = mem.id | 0x1;\n this.used = mem.used;\n this.size = mem.size;\n if (type) {\n this.type = type;\n this.fReadOnly = (type == Memory8080.TYPE.ROM);\n }\n if (TYPEDARRAYS) {\n this.buffer = mem.buffer;\n this.dv = mem.dv;\n this.ab = mem.ab;\n this.aw = mem.aw;\n this.adw = mem.adw;\n this.setAccess(littleEndian? Memory8080.afnArrayLE : Memory8080.afnArrayBE);\n } else {\n if (BYTEARRAYS) {\n this.ab = mem.ab;\n } else {\n this.adw = mem.adw;\n }\n this.setAccess(Memory8080.afnMemory);\n }\n this.copyBreakpoints(dbg, mem);\n }\n\n /**\n * save()\n *\n * This gets the contents of a Memory8080 block as an array of 32-bit values; used by Bus8080.saveMemory(),\n * which in turn is called by CPUState.save().\n *\n * Memory8080 blocks with custom memory controllers do NOT save their contents; that's the responsibility\n * of the controller component.\n *\n * @this {Memory8080}\n * @return {Array|Int32Array|null}\n */\n save()\n {\n var adw, i;\n if (BYTEARRAYS) {\n adw = new Array(this.size >> 2);\n var off = 0;\n for (i = 0; i < adw.length; i++) {\n adw[i] = this.ab[off] | (this.ab[off + 1] << 8) | (this.ab[off + 2] << 16) | (this.ab[off + 3] << 24);\n off += 4;\n }\n }\n else if (TYPEDARRAYS) {\n /*\n * It might be tempting to just return a copy of Int32Array(this.buffer, 0, this.size >> 2),\n * but we can't be sure of the \"endianness\" of an Int32Array -- which would be OK if the array\n * was always saved/restored on the same machine, but there's no guarantee of that, either.\n * So we use getInt32() and require little-endian values.\n *\n * Moreover, an Int32Array isn't treated by JSON.stringify() and JSON.parse() exactly like\n * a normal array; it's serialized as an Object rather than an Array, so it lacks a \"length\"\n * property and causes problems for State.store() and State.parse().\n */\n adw = new Array(this.size >> 2);\n for (i = 0; i < adw.length; i++) {\n adw[i] = this.dv.getInt32(i << 2, true);\n }\n }\n else {\n adw = this.adw;\n }\n return adw;\n }\n\n /**\n * restore(adw)\n *\n * This restores the contents of a Memory8080 block from an array of 32-bit values;\n * used by Bus8080.restoreMemory(), which is called by CPUState.restore(), after all other\n * components have been restored and thus all Memory8080 blocks have been allocated\n * by their respective components.\n *\n * @this {Memory8080}\n * @param {Array|null} adw\n * @return {boolean} true if successful, false if block size mismatch\n */\n restore(adw)\n {\n /*\n * At this point, it's a consistency error for adw to be null; it's happened once already,\n * when there was a restore bug in the Video component that added the frame buffer at the video\n * card's \"spec'ed\" address instead of the programmed address, so there were no controller-owned\n * memory blocks installed at the programmed address, and so we arrived here at a block with\n * no controller AND no data.\n */\n\n\n if (adw && this.size == adw.length << 2) {\n var i;\n if (BYTEARRAYS) {\n var off = 0;\n for (i = 0; i < adw.length; i++) {\n this.ab[off] = adw[i] & 0xff;\n this.ab[off + 1] = (adw[i] >> 8) & 0xff;\n this.ab[off + 2] = (adw[i] >> 16) & 0xff;\n this.ab[off + 3] = (adw[i] >> 24) & 0xff;\n off += 4;\n }\n } else if (TYPEDARRAYS) {\n for (i = 0; i < adw.length; i++) {\n this.dv.setInt32(i << 2, adw[i], true);\n }\n } else {\n this.adw = adw;\n }\n this.fDirty = true;\n return true;\n }\n return false;\n }\n\n /**\n * setAccess(afn, fDirect)\n *\n * If no function table is specified, a default is selected based on the Memory8080 type.\n *\n * @this {Memory8080}\n * @param {Array.<function()>} [afn] function table\n * @param {boolean} [fDirect] (true to update direct access functions as well; default is true)\n */\n setAccess(afn, fDirect)\n {\n if (!afn) {\n\n afn = Memory8080.afnNone;\n }\n this.setReadAccess(afn, fDirect);\n this.setWriteAccess(afn, fDirect);\n }\n\n /**\n * setReadAccess(afn, fDirect)\n *\n * @this {Memory8080}\n * @param {Array.<function()>} afn\n * @param {boolean} [fDirect]\n */\n setReadAccess(afn, fDirect)\n {\n if (!fDirect || !this.cReadBreakpoints) {\n this.readByte = afn[0] || this.readNone;\n this.readShort = afn[2] || this.readShortDefault;\n }\n if (fDirect || fDirect === undefined) {\n this.readByteDirect = afn[0] || this.readNone;\n this.readShortDirect = afn[2] || this.readShortDefault;\n }\n }\n\n /**\n * setWriteAccess(afn, fDirect)\n *\n * @this {Memory8080}\n * @param {Array.<function()>} afn\n * @param {boolean} [fDirect]\n */\n setWriteAccess(afn, fDirect)\n {\n if (!fDirect || !this.cWriteBreakpoints) {\n this.writeByte = !this.fReadOnly && afn[1] || this.writeNone;\n this.writeShort = !this.fReadOnly && afn[3] || this.writeShortDefault;\n }\n if (fDirect || fDirect === undefined) {\n this.writeByteDirect = afn[1] || this.writeNone;\n this.writeShortDirect = afn[3] || this.writeShortDefault;\n }\n }\n\n /**\n * resetReadAccess()\n *\n * @this {Memory8080}\n */\n resetReadAccess()\n {\n this.readByte = this.readByteDirect;\n this.readShort = this.readShortDirect;\n }\n\n /**\n * resetWriteAccess()\n *\n * @this {Memory8080}\n */\n resetWriteAccess()\n {\n this.writeByte = this.fReadOnly? this.writeNone : this.writeByteDirect;\n this.writeShort = this.fReadOnly? this.writeShortDefault : this.writeShortDirect;\n }\n\n /**\n * printAddr(sMessage)\n *\n * @this {Memory8080}\n * @param {string} sMessage\n */\n printAddr(sMessage)\n {\n if (DEBUG && this.dbg && this.dbg.messageEnabled(Messages8080.MEM)) {\n this.dbg.printMessage(sMessage + ' ' + (this.addr != null? ('%' + Str.toHex(this.addr)) : '#' + this.id), true);\n }\n }\n\n /**\n * addBreakpoint(off, fWrite)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {boolean} fWrite\n */\n addBreakpoint(off, fWrite)\n {\n if (!fWrite) {\n if (this.cReadBreakpoints++ === 0) {\n this.setReadAccess(Memory8080.afnChecked, false);\n }\n if (DEBUG) this.printAddr(\"read breakpoint added to memory block\");\n }\n else {\n if (this.cWriteBreakpoints++ === 0) {\n this.setWriteAccess(Memory8080.afnChecked, false);\n }\n if (DEBUG) this.printAddr(\"write breakpoint added to memory block\");\n }\n }\n\n /**\n * removeBreakpoint(off, fWrite)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {boolean} fWrite\n */\n removeBreakpoint(off, fWrite)\n {\n if (!fWrite) {\n if (--this.cReadBreakpoints === 0) {\n this.resetReadAccess();\n if (DEBUG) this.printAddr(\"all read breakpoints removed from memory block\");\n }\n\n }\n else {\n if (--this.cWriteBreakpoints === 0) {\n this.resetWriteAccess();\n if (DEBUG) this.printAddr(\"all write breakpoints removed from memory block\");\n }\n\n }\n }\n\n /**\n * copyBreakpoints(dbg, mem)\n *\n * @this {Memory8080}\n * @param {Debugger8080} [dbg]\n * @param {Memory8080} [mem] (outgoing Memory8080 block to copy breakpoints from, if any)\n */\n copyBreakpoints(dbg, mem)\n {\n this.dbg = dbg;\n this.cReadBreakpoints = this.cWriteBreakpoints = 0;\n if (mem) {\n if ((this.cReadBreakpoints = mem.cReadBreakpoints)) {\n this.setReadAccess(Memory8080.afnChecked, false);\n }\n if ((this.cWriteBreakpoints = mem.cWriteBreakpoints)) {\n this.setWriteAccess(Memory8080.afnChecked, false);\n }\n }\n }\n\n /**\n * readNone(off)\n *\n * Previously, this always returned 0x00, but the initial memory probe by the COMPAQ DeskPro 386 ROM BIOS\n * writes 0x0000 to the first word of every 64Kb block in the nearly 16Mb address space it supports, and\n * if it reads back 0x0000, it will initially think that LOTS of RAM exists, only to be disappointed later\n * when it performs a more exhaustive memory test, generating unwanted error messages in the process.\n *\n * TODO: Determine if we should have separate readByteNone(), readShortNone() and readLongNone() functions\n * to return 0xff, 0xffff and 0xffffffff|0, respectively. This seems sufficient for now, as it seems unlikely\n * that a system would require nonexistent memory locations to return ALL bits set.\n *\n * Also, I'm reluctant to address that potential issue by simply returning -1, because to date, the above\n * Memory8080 interfaces have always returned values that are properly masked to 8, 16 or 32 bits, respectively.\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readNone(off, addr)\n {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages8080.CPU | Messages8080.MEM) /* && !off */) {\n this.dbg.message(\"attempt to read invalid block %\" + Str.toHex(this.addr), true);\n }\n return 0xff;\n }\n\n /**\n * writeNone(off, v, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} v (could be either a byte or word value, since we use the same handler for both kinds of accesses)\n * @param {number} addr\n */\n writeNone(off, v, addr)\n {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages8080.CPU | Messages8080.MEM) /* && !off */) {\n this.dbg.message(\"attempt to write \" + Str.toHexWord(v) + \" to invalid block %\" + Str.toHex(this.addr), true);\n }\n }\n\n /**\n * readShortDefault(off, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortDefault(off, addr)\n {\n return this.readByte(off++, addr++) | (this.readByte(off, addr) << 8);\n }\n\n /**\n * writeShortDefault(off, w, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeShortDefault(off, w, addr)\n {\n this.writeByte(off++, w & 0xff, addr++);\n this.writeByte(off, w >> 8, addr);\n }\n\n /**\n * readByteMemory(off, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteMemory(off, addr)\n {\n if (BYTEARRAYS) {\n return this.ab[off];\n }\n return ((this.adw[off >> 2] >>> ((off & 0x3) << 3)) & 0xff);\n }\n\n /**\n * readShortMemory(off, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortMemory(off, addr)\n {\n if (BYTEARRAYS) {\n return this.ab[off] | (this.ab[off + 1] << 8);\n }\n var w;\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n var dw = (this.adw[idw] >> nShift);\n if (nShift < 24) {\n w = dw & 0xffff;\n } else {\n w = (dw & 0xff) | ((this.adw[idw + 1] & 0xff) << 8);\n }\n return w;\n }\n\n /**\n * writeByteMemory(off, b, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} b\n * @param {number} addr\n */\n writeByteMemory(off, b, addr)\n {\n if (BYTEARRAYS) {\n this.ab[off] = b;\n } else {\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n this.adw[idw] = (this.adw[idw] & ~(0xff << nShift)) | (b << nShift);\n }\n this.fDirty = true;\n }\n\n /**\n * writeShortMemory(off, w, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeShortMemory(off, w, addr)\n {\n if (BYTEARRAYS) {\n this.ab[off] = (w & 0xff);\n this.ab[off + 1] = (w >> 8);\n } else {\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n if (nShift < 24) {\n this.adw[idw] = (this.adw[idw] & ~(0xffff << nShift)) | (w << nShift);\n } else {\n this.adw[idw] = (this.adw[idw] & 0x00ffffff) | (w << 24);\n idw++;\n this.adw[idw] = (this.adw[idw] & (0xffffff00|0)) | (w >> 8);\n }\n }\n this.fDirty = true;\n }\n\n /**\n * readByteChecked(off, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteChecked(off, addr)\n {\n if (DEBUGGER && this.dbg && this.addr != null) {\n this.dbg.checkMemoryRead(this.addr + off);\n }\n return this.readByteDirect(off, addr);\n }\n\n /**\n * readShortChecked(off, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortChecked(off, addr)\n {\n if (DEBUGGER && this.dbg && this.addr != null) {\n this.dbg.checkMemoryRead(this.addr + off, 2);\n }\n return this.readShortDirect(off, addr);\n }\n\n /**\n * writeByteChecked(off, b, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @param {number} b\n */\n writeByteChecked(off, b, addr)\n {\n if (DEBUGGER && this.dbg && this.addr != null) {\n this.dbg.checkMemoryWrite(this.addr + off);\n }\n if (this.fReadOnly) this.writeNone(off, b, addr); else this.writeByteDirect(off, b, addr);\n }\n\n /**\n * writeShortChecked(off, w, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @param {number} w\n */\n writeShortChecked(off, w, addr)\n {\n if (DEBUGGER && this.dbg && this.addr != null) {\n this.dbg.checkMemoryWrite(this.addr + off, 2)\n }\n if (this.fReadOnly) this.writeNone(off, w, addr); else this.writeShortDirect(off, w, addr);\n }\n\n /**\n * readByteBE(off, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteBE(off, addr)\n {\n return this.ab[off];\n }\n\n /**\n * readByteLE(off, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteLE(off, addr)\n {\n return this.ab[off];\n }\n\n /**\n * readShortBE(off, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortBE(off, addr)\n {\n return this.dv.getUint16(off, true);\n }\n\n /**\n * readShortLE(off, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortLE(off, addr)\n {\n /*\n * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned read\n * vs. always reading the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.\n */\n return (off & 0x1)? (this.ab[off] | (this.ab[off+1] << 8)) : this.aw[off >> 1];\n }\n\n /**\n * writeByteBE(off, b, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} b\n * @param {number} addr\n */\n writeByteBE(off, b, addr)\n {\n this.ab[off] = b;\n this.fDirty = true;\n }\n\n /**\n * writeByteLE(off, b, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @param {number} b\n */\n writeByteLE(off, b, addr)\n {\n this.ab[off] = b;\n this.fDirty = true;\n }\n\n /**\n * writeShortBE(off, w, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @param {number} w\n */\n writeShortBE(off, w, addr)\n {\n this.dv.setUint16(off, w, true);\n this.fDirty = true;\n }\n\n /**\n * writeShortLE(off, w, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @param {number} w\n */\n writeShortLE(off, w, addr)\n {\n /*\n * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned write\n * vs. always writing the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.\n */\n if (off & 0x1) {\n this.ab[off] = w;\n this.ab[off+1] = w >> 8;\n } else {\n this.aw[off >> 1] = w;\n }\n this.fDirty = true;\n }\n\n /**\n * adjustEndian(dw)\n *\n * @param {number} dw\n * @return {number}\n */\n static adjustEndian(dw)\n {\n if (TYPEDARRAYS && !littleEndian) {\n dw = (dw << 24) | ((dw << 8) & 0x00ff0000) | ((dw >> 8) & 0x0000ff00) | (dw >>> 24);\n }\n return dw;\n }\n}\n\n/*\n * Basic memory types\n *\n * RAM is the most conventional memory type, providing full read/write capability to x86-compatible (ie,\n * 'little endian\") storage. ROM is equally conventional, except that the fReadOnly property is set,\n * disabling writes. VIDEO is treated exactly like RAM, unless a controller is provided. Both RAM and\n * VIDEO memory are always considered writable, and even ROM can be written using the Bus setByteDirect()\n * interface (which in turn uses the Memory8080 writeByteDirect() interface), allowing the ROM component to\n * initialize its own memory. The CTRL type is used to identify memory-mapped devices that do not need\n * any default storage and always provide their own controller.\n *\n * Unallocated regions of the address space contain a special memory block of type NONE that contains\n * no storage. Mapping every addressible location to a memory block allows all accesses to be routed in\n * exactly the same manner, without resorting to any range or processor checks.\n *\n * These types are not mutually exclusive. For example, VIDEO memory could be allocated as RAM, with or\n * without a custom controller (the original Monochrome and CGA video cards used read/write storage that\n * was indistinguishable from RAM), and CTRL memory could be allocated as an empty block of any type, with\n * a custom controller. A few types are required for certain features (eg, ROM is required if you want\n * read-only memory), but the larger purpose of these types is to help document the caller's intent and to\n * provide the Control Panel with the ability to highlight memory regions accordingly.\n */\nMemory8080.TYPE = {\n NONE: 0,\n RAM: 1,\n ROM: 2,\n VIDEO: 3,\n CTRL: 4,\n COLORS: [\"black\", \"blue\", \"green\", \"cyan\"],\n NAMES: [\"NONE\", \"RAM\", \"ROM\", \"VID\", \"H/W\"]\n};\n\n/*\n * Last used block ID (used for debugging only)\n */\nMemory8080.idBlock = 0;\n\n\n/*\n * This is the effective definition of afnNone, but we need not fully define it, because setAccess()\n * uses these defaults when any of the 4 handlers (ie, 2 byte handlers and 2 short handlers) are undefined.\n *\nMemory8080.afnNone = [\n Memory8080.prototype.readNone,\n Memory8080.prototype.writeNone,\n Memory8080.prototype.readShortDefault,\n Memory8080.prototype.writeShortDefault\n];\n */\nMemory8080.afnNone = [];\n\nMemory8080.afnMemory = [\n Memory8080.prototype.readByteMemory,\n Memory8080.prototype.writeByteMemory,\n Memory8080.prototype.readShortMemory,\n Memory8080.prototype.writeShortMemory\n];\n\nMemory8080.afnChecked = [\n Memory8080.prototype.readByteChecked,\n Memory8080.prototype.writeByteChecked,\n Memory8080.prototype.readShortChecked,\n Memory8080.prototype.writeShortChecked\n];\n\nif (TYPEDARRAYS) {\n Memory8080.afnArrayBE = [\n Memory8080.prototype.readByteBE,\n Memory8080.prototype.writeByteBE,\n Memory8080.prototype.readShortBE,\n Memory8080.prototype.writeShortBE\n ];\n\n Memory8080.afnArrayLE = [\n Memory8080.prototype.readByteLE,\n Memory8080.prototype.writeByteLE,\n Memory8080.prototype.readShortLE,\n Memory8080.prototype.writeShortLE\n ];\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/cpu.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass CPU8080 extends Component {\n /**\n * CPU8080(parmsCPU, nCyclesDefault)\n *\n * The CPU8080 class supports the following (parmsCPU) properties:\n *\n * cycles: the machine's base cycles per second; the CPUState8080 constructor\n * will provide us with a default (based on the CPU model) to use as a fallback.\n *\n * multiplier: base cycle multiplier; default is 1.\n *\n * autoStart: true to automatically start, false to not, or null if \"it depends\";\n * null is the default, which means do not autostart UNLESS there is no Debugger\n * and no \"Run\" button (ie, no way to manually start the machine).\n *\n * csStart: the number of cycles that runCPU() must wait before generating\n * checksum records; -1 if disabled. checksum records are a diagnostic aid\n * used to help compare one CPU run to another.\n *\n * csInterval: the number of cycles that runCPU() must execute before generating\n * a checksum record; -1 if disabled.\n *\n * csStop: the number of cycles to stop generating checksum records.\n *\n * This component is primarily responsible for interfacing the CPU with the outside\n * world (eg, Panel and Debugger components), and managing overall CPU operation.\n *\n * It is extended by the CPUState8080 component, where the simulation control logic resides.\n *\n * @this {CPU8080}\n * @param {Object} parmsCPU\n * @param {number} nCyclesDefault\n */\n constructor(parmsCPU, nCyclesDefault)\n {\n super(\"CPU\", parmsCPU, Messages8080.CPU);\n\n var nCycles = parmsCPU['cycles'] || nCyclesDefault;\n\n var nMultiplier = parmsCPU['multiplier'] || 1;\n\n this.nCyclesPerSecond = nCycles;\n\n /*\n * nCyclesMultiplier replaces the old \"speed\" variable (0, 1, 2) and eliminates the need for\n * the constants (SPEED_SLOW, SPEED_FAST and SPEED_MAX). The UI simply doubles the multiplier\n * until we've exceeded the host's speed limit and then starts the multiplier over at 1.\n */\n this.nCyclesMultiplier = nMultiplier;\n this.mhzDefault = Math.round(this.nCyclesPerSecond / 10000) / 100;\n /*\n * TODO: Take care of this with an initial setSpeed() call instead?\n */\n this.mhzTarget = this.mhzDefault * this.nCyclesMultiplier;\n\n /*\n * We add a number of flags to the set initialized by Component\n */\n this.flags.running = false;\n this.flags.starting = false;\n this.flags.autoStart = parmsCPU['autoStart'];\n\n /*\n * TODO: Add some UI for fDisplayLiveRegs (either an XML property, or a UI checkbox, or both)\n */\n this.flags.displayLiveRegs = false;\n\n /*\n * Get checksum parameters, if any. runCPU() behavior is not affected until fChecksum\n * is true, which won't happen until resetChecksum() is called with nCyclesChecksumInterval\n * (\"csInterval\") set to a positive value.\n *\n * As above, any of these parameters can also be set with the Debugger's execution options\n * command (\"x\"); for example, \"x cs int 5000\" will set nCyclesChecksumInterval to 5000\n * and call resetChecksum().\n */\n this.flags.checksum = false;\n this.nChecksum = this.nCyclesChecksumNext = 0;\n this.nCyclesChecksumStart = parmsCPU[\"csStart\"];\n this.nCyclesChecksumInterval = parmsCPU[\"csInterval\"];\n this.nCyclesChecksumStop = parmsCPU[\"csStop\"];\n\n /*\n * Array of countdown timers managed by addTimer() and setTimer().\n */\n this.aTimers = [];\n\n this.onRunTimeout = this.runCPU.bind(this); // function onRunTimeout() { cpu.runCPU(); };\n\n this.setReady();\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {CPU8080}\n * @param {Computer8080} cmp\n * @param {Bus8080} bus\n * @param {CPU8080} cpu\n * @param {Debugger8080} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.dbg = dbg;\n\n for (var i = 0; i < CPU8080.BUTTONS.length; i++) {\n var control = this.bindings[CPU8080.BUTTONS[i]];\n if (control) this.cmp.setBinding(null, CPU8080.BUTTONS[i], control);\n }\n\n /*\n * Attach the ChipSet component to the CPU so that it can be notified whenever the CPU stops and starts.\n */\n this.chipset = /** @type {ChipSet8080} */ (cmp.getMachineComponent(\"ChipSet\"));\n\n /*\n * We've already saved the parmsCPU 'autoStart' setting, but there may be a machine (or URL) override.\n */\n var sAutoStart = cmp.getMachineParm('autoStart');\n if (sAutoStart != null) {\n this.flags.autoStart = (sAutoStart == \"true\"? true : (sAutoStart == \"false\"? false : !!sAutoStart));\n }\n\n this.setReady();\n }\n\n /**\n * reset()\n *\n * @this {CPU8080}\n */\n reset()\n {\n }\n\n /**\n * save()\n *\n * This is a placeholder for save support (overridden by the CPUState8080 component).\n *\n * @this {CPU8080}\n * @return {Object|null}\n */\n save()\n {\n return null;\n }\n\n /**\n * restore(data)\n *\n * This is a placeholder for restore support (overridden by the CPUState8080 component).\n *\n * @this {CPU8080}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n return false;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {CPU8080}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data || !this.restore) {\n this.reset();\n } else {\n this.resetCycles();\n if (!this.restore(data)) return false;\n this.resetChecksum();\n }\n /*\n * Give the Debugger a chance to do/print something once we've powered up\n */\n if (DEBUGGER && this.dbg) {\n this.dbg.init();\n } else {\n this.println(\"No debugger detected\");\n }\n }\n /*\n * The Computer component (which is responsible for all powerDown and powerUp notifications)\n * is now responsible for managing a component's fPowered flag, not us.\n *\n * this.flags.powered = true;\n */\n this.updateCPU();\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {CPU8080}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n /*\n * The Computer component (which is responsible for all powerDown and powerUp notifications)\n * is now responsible for managing a component's fPowered flag, not us.\n *\n * this.flags.powered = false;\n */\n return fSave? this.save() : true;\n }\n\n /**\n * autoStart()\n *\n * @this {CPU8080}\n * @return {boolean} true if started, false if not\n */\n autoStart()\n {\n /*\n * Start running automatically on power-up, assuming there's no Debugger and no \"Run\" button\n */\n if (this.flags.autoStart || (!DEBUGGER || !this.dbg) && this.bindings[\"run\"] === undefined) {\n /*\n * We used to also set fUpdateFocus when calling runCPU(), on the assumption that in the \"auto-starting\"\n * context, a machine without focus is like a day without sunshine, but in reality, focus should only be\n * forced when the user takes some other machine-related action.\n */\n this.runCPU();\n return true;\n }\n return false;\n }\n\n /**\n * isPowered()\n *\n * @this {CPU8080}\n * @return {boolean}\n */\n isPowered()\n {\n if (!this.flags.powered) {\n this.println(this.toString() + \" not powered\");\n return false;\n }\n return true;\n }\n\n /**\n * isRunning()\n *\n * @this {CPU8080}\n * @return {boolean}\n */\n isRunning()\n {\n return this.flags.running;\n }\n\n /**\n * getChecksum()\n *\n * This will be implemented by the CPUState8080 component.\n *\n * @this {CPU8080}\n * @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code)\n */\n getChecksum()\n {\n return 0;\n }\n\n /**\n * resetChecksum()\n *\n * If checksum generation is enabled (fChecksum is true), this resets the running 32-bit checksum and the\n * cycle counter that will trigger the next displayChecksum(); called by resetCycles(), which is called whenever\n * the CPU is reset or restored.\n *\n * @this {CPU8080}\n * @return {boolean} true if checksum generation enabled, false if not\n */\n resetChecksum()\n {\n if (this.nCyclesChecksumStart === undefined) this.nCyclesChecksumStart = 0;\n if (this.nCyclesChecksumInterval === undefined) this.nCyclesChecksumInterval = -1;\n if (this.nCyclesChecksumStop === undefined) this.nCyclesChecksumStop = -1;\n this.flags.checksum = (this.nCyclesChecksumStart >= 0 && this.nCyclesChecksumInterval > 0);\n if (this.flags.checksum) {\n this.nChecksum = 0;\n this.nCyclesChecksumNext = this.nCyclesChecksumStart - this.nTotalCycles;\n /*\n * this.nCyclesChecksumNext = this.nCyclesChecksumStart + this.nCyclesChecksumInterval -\n * (this.nTotalCycles % this.nCyclesChecksumInterval);\n */\n return true;\n }\n return false;\n }\n\n /**\n * updateChecksum(nCycles)\n *\n * When checksum generation is enabled (fChecksum is true), runCPU() asks stepCPU() to execute a minimum\n * number of cycles (1), effectively limiting execution to a single instruction, and then we're called with\n * the exact number cycles that were actually executed. This should give us instruction-granular checksums\n * at precise intervals that are 100% repeatable.\n *\n * @this {CPU8080}\n * @param {number} nCycles\n */\n updateChecksum(nCycles)\n {\n if (this.flags.checksum) {\n /*\n * Get a 32-bit summation of the current CPU state and add it to our running 32-bit checksum\n */\n var fDisplay = false;\n this.nChecksum = (this.nChecksum + this.getChecksum())|0;\n this.nCyclesChecksumNext -= nCycles;\n if (this.nCyclesChecksumNext <= 0) {\n this.nCyclesChecksumNext += this.nCyclesChecksumInterval;\n fDisplay = true;\n }\n if (this.nCyclesChecksumStop >= 0) {\n if (this.nCyclesChecksumStop <= this.getCycles()) {\n this.nCyclesChecksumInterval = this.nCyclesChecksumStop = -1;\n this.resetChecksum();\n this.stopCPU();\n fDisplay = true;\n }\n }\n if (fDisplay) this.displayChecksum();\n }\n }\n\n /**\n * displayChecksum()\n *\n * When checksum generation is enabled (fChecksum is true), this is called to provide a crude log of all\n * checksums generated at the specified cycle intervals, as specified by the \"csStart\" and \"csInterval\" parmsCPU\n * properties).\n *\n * @this {CPU8080}\n */\n displayChecksum()\n {\n this.println(this.getCycles() + \" cycles: \" + \"checksum=\" + Str.toHex(this.nChecksum));\n }\n\n /**\n * displayValue(sLabel, nValue, cch)\n *\n * This is principally for displaying register values, but in reality, it can be used to display any\n * numeric (hex) value bound to the given label.\n *\n * @this {CPU8080}\n * @param {string} sLabel\n * @param {number} nValue\n * @param {number} cch\n */\n displayValue(sLabel, nValue, cch)\n {\n if (this.bindings[sLabel]) {\n if (nValue === undefined) {\n this.setError(\"Value for \" + sLabel + \" is invalid\");\n this.stopCPU();\n }\n var sVal;\n if (!this.flags.running || this.flags.displayLiveRegs) {\n sVal = Str.toHex(nValue, cch);\n } else {\n sVal = \"--------\".substr(0, cch);\n }\n /*\n * TODO: Determine if this test actually avoids any redrawing when a register hasn't changed, and/or if\n * we should maintain our own (numeric) cache of displayed register values (to avoid creating these temporary\n * string values that will have to garbage-collected), and/or if this is actually slower, and/or if I'm being\n * too obsessive.\n */\n if (this.bindings[sLabel].textContent != sVal) this.bindings[sLabel].textContent = sVal;\n }\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {CPU8080}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"run\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var cpu = this;\n var fBound = false;\n\n switch (sBinding) {\n case \"power\":\n case \"reset\":\n /*\n * The \"power\" and \"reset\" buttons are functions of the entire computer, not just the CPU,\n * but it's not always convenient to stick a power button in the Computer component definition,\n * so we record those bindings here and pass them on to the Computer component in initBus().\n */\n this.bindings[sBinding] = control;\n fBound = true;\n break;\n\n case \"run\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickRun() {\n if (!cpu.cmp || !cpu.cmp.checkPower()) return;\n /*\n * We no longer pass true to these runCPU()/stopCPU() calls, on the theory that if the \"run\"\n * control is visible, then the computer is probably sufficiently visible as well; the problem\n * with setting fUpdateFocus to true is that it can jerk the web page around in annoying ways.\n */\n if (!cpu.flags.running)\n cpu.runCPU();\n else\n cpu.stopCPU();\n };\n fBound = true;\n break;\n\n case \"speed\":\n this.bindings[sBinding] = control;\n fBound = true;\n break;\n\n case \"setSpeed\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickSetSpeed() {\n cpu.setSpeed(cpu.nCyclesMultiplier << 1, true);\n };\n control.textContent = this.getSpeedTarget();\n fBound = true;\n break;\n\n default:\n break;\n }\n return fBound;\n }\n\n /**\n * setBurstCycles(nCycles)\n *\n * This function is used by the ChipSet component whenever a very low timer count is set,\n * in anticipation of the timer requiring an update sooner than the normal nCyclesPerYield\n * period in runCPU() would normally provide.\n *\n * NOTE: In this context, \"timer\" refers to a timer chip (eg, an Intel 8253) being emulated by\n * by the ChipSet component, not the timers managed by the CPU (eg, addTimer(), setTimer(), etc).\n *\n * @this {CPU8080}\n * @param {number} nCycles is the target number of cycles to drop the current burst to\n * @return {boolean}\n */\n setBurstCycles(nCycles)\n {\n if (this.flags.running) {\n var nDelta = this.nStepCycles - nCycles;\n /*\n * NOTE: If nDelta is negative, we will actually be increasing nStepCycles and nBurstCycles.\n * Which is OK, but if we're also taking snapshots of the cycle counts, to make sure that instruction\n * costs are being properly assessed, then we need to update nSnapCycles as well.\n *\n * TODO: If the delta is negative, we could simply ignore the request, but we must first carefully\n * consider the impact on the ChipSet timers, if any.\n */\n // if (DEBUG) this.nSnapCycles -= nDelta;\n this.nStepCycles -= nDelta;\n this.nBurstCycles -= nDelta;\n return true;\n }\n return false;\n }\n\n /**\n * addCycles(nCycles, fEndStep)\n *\n * @this {CPU8080}\n * @param {number} nCycles\n * @param {boolean} [fEndStep]\n */\n addCycles(nCycles, fEndStep)\n {\n this.nTotalCycles += nCycles;\n if (fEndStep) {\n this.nBurstCycles = this.nStepCycles = 0;\n }\n }\n\n /**\n * calcCycles(fRecalc)\n *\n * Calculate the number of cycles to process for each \"burst\" of CPU activity. The size of a burst\n * is driven by YIELDS_PER_SECOND (eg, 30).\n *\n * At the end of each burst, we subtract burst cycles from the yield cycle \"threshold\" counter.\n * Whenever the \"next yield\" cycle counter goes to (or below) zero, we compare elapsed time to the time\n * we expected the virtual hardware to take (eg, 1000ms/50 or 20ms), and if we still have time remaining,\n * we sleep the remaining time (or 0ms if there's no remaining time), and then restart runCPU().\n *\n * @this {CPU8080}\n * @param {boolean} [fRecalc] is true if the caller wants to recalculate thresholds based on the most recent\n * speed calculation (see calcSpeed).\n */\n calcCycles(fRecalc)\n {\n /*\n * Calculate \"per\" yield values.\n */\n var vMultiplier = 1;\n if (fRecalc) {\n if (this.nCyclesMultiplier > 1 && this.mhz) {\n vMultiplier = (this.mhz / this.mhzDefault);\n }\n }\n\n this.msPerYield = Math.round(1000 / CPU8080.YIELDS_PER_SECOND);\n this.nCyclesPerYield = Math.floor(this.nCyclesPerSecond / CPU8080.YIELDS_PER_SECOND * vMultiplier);\n\n /*\n * And initialize \"next\" yield values to the \"per\" values.\n */\n if (!fRecalc) {\n this.nCyclesNextYield = this.nCyclesPerYield;\n }\n this.nCyclesRecalc = 0;\n }\n\n /**\n * getCycles(fScaled)\n *\n * getCycles() returns the number of cycles executed so far. Note that we can be called after\n * runCPU() OR during runCPU(), perhaps from a handler triggered during the current run's stepCPU(),\n * so nRunCycles must always be adjusted by number of cycles stepCPU() was asked to run (nBurstCycles),\n * less the number of cycles it has yet to run (nStepCycles).\n *\n * nRunCycles is zeroed whenever the CPU is halted or the CPU speed is changed, which is why we also\n * have nTotalCycles, which accumulates all nRunCycles before we zero it. However, nRunCycles and\n * nTotalCycles eventually get reset by calcSpeed(), to avoid overflow, so components that rely on\n * getCycles() returning steadily increasing values should also be prepared for a reset at any time.\n *\n * @this {CPU8080}\n * @param {boolean} [fScaled] is true if the caller wants a cycle count relative to a multiplier of 1\n * @return {number}\n */\n getCycles(fScaled)\n {\n var nCycles = this.nTotalCycles + this.nRunCycles + this.nBurstCycles - this.nStepCycles;\n if (fScaled && this.nCyclesMultiplier > 1 && this.mhz > this.mhzDefault) {\n /*\n * We could scale the current cycle count by the current effective speed (this.mhz); eg:\n *\n * nCycles = Math.round(nCycles / (this.mhz / this.mhzDefault));\n *\n * but that speed will fluctuate somewhat: large fluctuations at first, but increasingly smaller\n * fluctuations after each burst of instructions that runCPU() executes.\n *\n * Alternatively, we can scale the cycle count by the multiplier, which is good in that the\n * multiplier doesn't vary once the user changes it, but a potential downside is that the\n * multiplier might be set too high, resulting in a target speed that's higher than the effective\n * speed is able to reach.\n *\n * Also, if multipliers were always limited to a power-of-two, then this could be calculated\n * with a simple shift. However, only the \"setSpeed\" UI binding limits it that way; the Debugger\n * interface allows any value, as does the CPU \"multiplier\" parmsCPU property (from the machine's\n * XML file).\n */\n nCycles = Math.round(nCycles / this.nCyclesMultiplier);\n }\n return nCycles;\n }\n\n /**\n * getCyclesPerSecond()\n *\n * This returns the CPU's \"base\" speed (ie, the original cycles per second defined for the machine)\n *\n * @this {CPU8080}\n * @return {number}\n */\n getCyclesPerSecond()\n {\n return this.nCyclesPerSecond;\n }\n\n /**\n * resetCycles()\n *\n * Resets speed and cycle information as part of any reset() or restore(); this typically occurs during powerUp().\n * It's important that this be called BEFORE the actual restore() call, because restore() may want to call setSpeed(),\n * which in turn assumes that all the cycle counts have been initialized to sensible values.\n *\n * @this {CPU8080}\n */\n resetCycles()\n {\n this.mhz = 0;\n this.nYieldsSinceStatusUpdate = 0;\n this.nTotalCycles = this.nRunCycles = this.nBurstCycles = this.nStepCycles = 0;\n this.resetChecksum();\n this.setSpeed(1);\n }\n\n /**\n * getSpeed()\n *\n * @this {CPU8080}\n * @return {number} the current speed multiplier\n */\n getSpeed()\n {\n return this.nCyclesMultiplier;\n }\n\n /**\n * getSpeedCurrent()\n *\n * @this {CPU8080}\n * @return {string} the current speed, in mhz, as a string formatted to two decimal places\n */\n getSpeedCurrent()\n {\n /*\n * TODO: Has toFixed() been \"fixed\" in all browsers (eg, IE) to return a rounded value now?\n */\n return ((this.flags.running && this.mhz)? (this.mhz.toFixed(2) + \"Mhz\") : \"Stopped\");\n }\n\n /**\n * getSpeedTarget()\n *\n * @this {CPU8080}\n * @return {string} the target speed, in mhz, as a string formatted to two decimal places\n */\n getSpeedTarget()\n {\n /*\n * TODO: Has toFixed() been \"fixed\" in all browsers (eg, IE) to return a rounded value now?\n */\n return this.mhzTarget.toFixed(2) + \"Mhz\";\n }\n\n /**\n * setSpeed(nMultiplier, fUpdateFocus)\n *\n * NOTE: This used to return the target speed, in mhz, but no callers appear to care at this point.\n *\n * @desc Whenever the speed is changed, the running cycle count and corresponding start time must be reset,\n * so that the next effective speed calculation obtains sensible results. In fact, when runCPU() initially calls\n * setSpeed() with no parameters, that's all this function does (it doesn't change the current speed setting).\n *\n * @this {CPU8080}\n * @param {number} [nMultiplier] is the new proposed multiplier (reverts to 1 if the target was too high)\n * @param {boolean} [fUpdateFocus] is true to update Computer focus\n * @return {boolean} true if successful, false if not\n */\n setSpeed(nMultiplier, fUpdateFocus)\n {\n var fSuccess = false;\n if (nMultiplier !== undefined) {\n /*\n * If we haven't reached 80% (0.8) of the current target speed, revert to a multiplier of one (1).\n */\n if (this.mhz / this.mhzTarget < 0.8) {\n nMultiplier = 1;\n } else {\n fSuccess = true;\n }\n this.nCyclesMultiplier = nMultiplier;\n var mhz = this.mhzDefault * this.nCyclesMultiplier;\n if (this.mhzTarget != mhz) {\n this.mhzTarget = mhz;\n var sSpeed = this.getSpeedTarget();\n var controlSpeed = this.bindings[\"setSpeed\"];\n if (controlSpeed) controlSpeed.textContent = sSpeed;\n this.println(\"target speed: \" + sSpeed);\n }\n if (fUpdateFocus && this.cmp) this.cmp.updateFocus();\n }\n this.addCycles(this.nRunCycles);\n this.nRunCycles = 0;\n this.msStartRun = Component.getTime();\n this.msEndThisRun = 0;\n this.calcCycles();\n return fSuccess;\n }\n\n /**\n * calcSpeed(nCycles, msElapsed)\n *\n * @this {CPU8080}\n * @param {number} nCycles\n * @param {number} msElapsed\n */\n calcSpeed(nCycles, msElapsed)\n {\n if (msElapsed) {\n this.mhz = Math.round(nCycles / (msElapsed * 10)) / 100;\n if (msElapsed >= 86400000) {\n this.nTotalCycles = 0;\n this.setSpeed(); // reset all counters once per day so that we never have to worry about overflow\n }\n }\n }\n\n /**\n * calcStartTime()\n *\n * @this {CPU8080}\n */\n calcStartTime()\n {\n if (this.nCyclesRecalc >= this.nCyclesPerSecond) {\n this.calcCycles(true);\n }\n this.nCyclesThisRun = 0;\n this.msStartThisRun = Component.getTime();\n\n /*\n * Try to detect situations where the browser may have throttled us, such as when the user switches\n * to a different tab; in those situations, Chrome and Safari may restrict setTimeout() callbacks\n * to roughly one per second.\n *\n * Another scenario: the user resizes the browser window. setTimeout() callbacks are not throttled,\n * but there can still be enough of a lag between the callbacks that CPU speed will be noticeably\n * erratic if we don't compensate for it here.\n *\n * We can detect throttling/lagging by verifying that msEndThisRun (which was set at the end of the\n * previous run and includes any requested sleep time) is comparable to the current msStartThisRun;\n * if the delta is significant, we compensate by bumping msStartRun forward by that delta.\n *\n * This shouldn't be triggered when the Debugger halts the CPU, because setSpeed() -- which is called\n * whenever the CPU starts running again -- zeroes msEndThisRun.\n *\n * This also won't do anything about other internal delays; for example, Debugger message() calls.\n * By the time the message() function has called yieldCPU(), the cost of the message has already been\n * incurred, so it will be end up being charged against the instruction(s) that triggered it.\n *\n * TODO: Consider calling yieldCPU() sooner from message(), so that it can arrange for the msEndThisRun\n * \"snapshot\" to occur sooner; it's unclear, however, whether that will really improve the CPU's ability\n * to hit its target speed, since you would expect any instruction that displays a message to be an\n * EXTREMELY slow instruction.\n */\n if (this.msEndThisRun) {\n var msDelta = this.msStartThisRun - this.msEndThisRun;\n if (msDelta > this.msPerYield) {\n if (MAXDEBUG) this.println(\"large time delay: \" + msDelta + \"ms\");\n this.msStartRun += msDelta;\n /*\n * Bumping msStartRun forward should NEVER cause it to exceed msStartThisRun; however, just\n * in case, I make absolutely sure it cannot happen, since doing so could result in negative\n * speed calculations.\n */\n\n if (this.msStartRun > this.msStartThisRun) {\n this.msStartRun = this.msStartThisRun;\n }\n }\n }\n }\n\n /**\n * calcRemainingTime()\n *\n * @this {CPU8080}\n * @return {number}\n */\n calcRemainingTime()\n {\n this.msEndThisRun = Component.getTime();\n\n var msYield = this.msPerYield;\n if (this.nCyclesThisRun) {\n /*\n * Normally, we would assume we executed a full quota of work over msPerYield, but since the CPU\n * now has the option of calling yieldCPU(), that might not be true. If nCyclesThisRun is correct, then\n * the ratio of nCyclesThisRun/nCyclesPerYield should represent the percentage of work we performed,\n * and so applying that percentage to msPerYield should give us a better estimate of work vs. time.\n */\n msYield = Math.round(msYield * this.nCyclesThisRun / this.nCyclesPerYield);\n }\n\n var msElapsedThisRun = this.msEndThisRun - this.msStartThisRun;\n var msRemainsThisRun = msYield - msElapsedThisRun;\n\n /*\n * We could pass only \"this run\" results to calcSpeed():\n *\n * nCycles = this.nCyclesThisRun;\n * msElapsed = msElapsedThisRun;\n *\n * but it seems preferable to use longer time periods and hopefully get a more accurate speed.\n *\n * Also, if msRemainsThisRun >= 0 && this.nCyclesMultiplier == 1, we could pass these results instead:\n *\n * nCycles = this.nCyclesThisRun;\n * msElapsed = this.msPerYield;\n *\n * to insure that we display a smooth, constant N Mhz. But for now, I prefer seeing any fluctuations.\n */\n var nCycles = this.nRunCycles;\n var msElapsed = this.msEndThisRun - this.msStartRun;\n\n if (MAXDEBUG && msRemainsThisRun < 0 && this.nCyclesMultiplier > 1) {\n this.println(\"warning: updates @\" + msElapsedThisRun + \"ms (prefer \" + Math.round(msYield) + \"ms)\");\n }\n\n this.calcSpeed(nCycles, msElapsed);\n\n if (msRemainsThisRun < 0 || this.mhz < this.mhzTarget) {\n /*\n * Try \"throwing out\" the effects of large anomalies, by moving the overall run start time up;\n * ordinarily, this should only happen when the someone is using an external Debugger or some other\n * tool or feature that is interfering with our overall execution.\n */\n if (msRemainsThisRun < -1000) {\n this.msStartRun -= msRemainsThisRun;\n }\n /*\n * If the last burst took MORE time than we allotted (ie, it's taking more than 1 second to simulate\n * nCyclesPerSecond), all we can do is yield for as little time as possible (ie, 0ms) and hope that the\n * simulation is at least usable.\n */\n msRemainsThisRun = 0;\n }\n\n /*\n * Last but not least, update nCyclesRecalc, so that when runCPU() starts up again and calls calcStartTime(),\n * it'll be ready to decide if calcCycles() should be called again.\n */\n this.nCyclesRecalc += this.nCyclesThisRun;\n\n if (DEBUG && this.messageEnabled(Messages8080.CPU) && msRemainsThisRun) {\n this.printMessage(\"calcRemainingTime: \" + msRemainsThisRun + \"ms to sleep after \" + this.msEndThisRun + \"ms\");\n }\n\n this.msEndThisRun += msRemainsThisRun;\n return msRemainsThisRun;\n }\n\n /**\n * addTimer(id, callBack, ms)\n *\n * Components that want to have timers that fire after some number of milliseconds call addTimer() to create\n * the timer, and then setTimer() when they want to arm it. Alternatively, they can specify an automatic timeout\n * value (in milliseconds) to have the timer fire automatically at regular intervals. There is currently\n * no removeTimer() because these are generally used for the entire lifetime of a component.\n *\n * Internally, each timer entry is a preallocated Array with the following entries:\n *\n * [0]: timer ID\n * [1]: countdown value, in cycles\n * [2]: automatic setTimer value, if any, in milliseconds\n * [3]: callback function\n *\n * A timer is initially dormant; dormant timers have a countdown value of -1 (although any negative number\n * will suffice) and active timers have a non-negative value.\n *\n * Why not use JavaScript's setTimeout() instead? Good question. For a good answer, see setTimer() below.\n *\n * @this {CPU8080}\n * @param {string} id\n * @param {function()} callBack\n * @param {number} [ms] (if set, enables automatic setTimer calls)\n * @return {number} timer index\n */\n addTimer(id, callBack, ms = -1)\n {\n var iTimer = this.aTimers.length;\n this.aTimers.push([id, -1, ms, callBack]);\n if (ms >= 0) this.setTimer(iTimer, ms);\n return iTimer;\n }\n\n /**\n * findTimer(id)\n *\n * @this {CPU8080}\n * @param {string} id\n * @return {Array|null}\n */\n findTimer(id)\n {\n for (var iTimer = 0; iTimer < this.aTimers.length; iTimer++) {\n var timer = this.aTimers[iTimer];\n if (timer[0] == id) return timer;\n }\n return null;\n }\n\n /**\n * setTimer(iTimer, ms, fReset)\n *\n * Using the timer index from a previous addTimer() call, this sets that timer to fire after the\n * specified number of milliseconds.\n *\n * This is preferred over JavaScript's setTimeout(), because all our timers are effectively paused when\n * the CPU is paused (eg, when the Debugger halts execution). Moreover, setTimeout() handlers only run after\n * runCPU() yields, which is far too granular for some components (eg, when the SerialPort tries to simulate\n * interrupts at 9600 baud).\n *\n * Ideally, the only function that would use setTimeout() is runCPU(), while the rest of the components\n * use setTimer(); however, due to legacy code (ie, code that predates these functions) and/or laziness,\n * that's currently not the case. TODO: Fix.\n *\n * @this {CPU8080}\n * @param {number} iTimer\n * @param {number} ms (converted into a cycle countdown internally)\n * @param {boolean} [fReset] (true if the timer should be reset even if already armed)\n * @return {number} (number of cycles used to arm timer, or -1 if error)\n */\n setTimer(iTimer, ms, fReset)\n {\n var nCycles = -1;\n if (iTimer >= 0 && iTimer < this.aTimers.length) {\n var timer = this.aTimers[iTimer];\n if (fReset || timer[1] < 0) {\n nCycles = this.getMSCycles(ms);\n /*\n * If the CPU is currently executing a burst of cycles, the number of cycles it has executed in\n * that burst so far must NOT be charged against the cycle timeout we're about to set. The simplest\n * way to resolve that is to immediately call endBurst() and bias the cycle timeout by the number\n * of cycles that the burst executed.\n */\n if (this.flags.running) {\n nCycles += this.endBurst();\n }\n timer[1] = nCycles;\n }\n }\n return nCycles;\n }\n\n /**\n * getMSCycles(ms)\n *\n * @this {CPU8080}\n * @param {number} ms\n * @return {number} number of corresponding cycles\n */\n getMSCycles(ms)\n {\n return ((this.nCyclesPerSecond * this.nCyclesMultiplier) / 1000 * ms)|0;\n }\n\n /**\n * getBurstCycles(nCycles)\n *\n * Used by runCPU() to get min(nCycles,[timer cycle counts])\n *\n * @this {CPU8080}\n * @param {number} nCycles (number of cycles about to execute)\n * @return {number} (either nCycles or less if a timer needs to fire)\n */\n getBurstCycles(nCycles)\n {\n for (var iTimer = this.aTimers.length - 1; iTimer >= 0; iTimer--) {\n var timer = this.aTimers[iTimer];\n\n if (timer[1] < 0) continue;\n if (nCycles > timer[1]) {\n nCycles = timer[1];\n }\n }\n return nCycles;\n }\n\n /**\n * updateTimers(nCycles)\n *\n * Used by runCPU() to reduce all active timer countdown values by the number of cycles just executed;\n * this is the function that actually \"fires\" any timer(s) whose countdown has reached (or dropped below)\n * zero, invoking their callback function.\n *\n * @this {CPU8080}\n * @param {number} nCycles (number of cycles actually executed)\n */\n updateTimers(nCycles)\n {\n for (var iTimer = this.aTimers.length - 1; iTimer >= 0; iTimer--) {\n var timer = this.aTimers[iTimer];\n\n if (timer[1] < 0) continue;\n timer[1] -= nCycles;\n if (timer[1] <= 0) {\n if (DEBUG && this.messageEnabled(Messages8080.CPU)) {\n this.printMessage(\"updateTimer(\" + nCycles + \"): firing \" + timer[0] + \" with only \" + (timer[1] + nCycles) + \" cycles left\");\n }\n timer[1] = -1; // zero is technically an \"active\" value, so ensure the timer is dormant now\n timer[3](); // safe to invoke the callback function now\n if (timer[2] >= 0) {\n this.setTimer(iTimer, timer[2]);\n if (DEBUG && this.messageEnabled(Messages8080.CPU)) {\n this.printMessage(\"updateTimer(\" + nCycles + \"): rearming \" + timer[0] + \" for \" + timer[2] + \"ms (\" + timer[1] + \" cycles)\");\n }\n }\n }\n }\n }\n\n /**\n * endBurst(fReset)\n *\n * @this {CPU8080}\n * @param {boolean} [fReset]\n * @return {number} (number of cycles executed in the most recent burst)\n */\n endBurst(fReset)\n {\n var nCycles = this.nBurstCycles -= this.nStepCycles;\n this.nStepCycles = 0;\n if (fReset) this.nBurstCycles = 0;\n return nCycles;\n }\n\n /**\n * runCPU(fUpdateFocus)\n *\n * @this {CPU8080}\n * @param {boolean} [fUpdateFocus] is true to update Computer focus\n */\n runCPU(fUpdateFocus)\n {\n if (!this.setBusy(true)) {\n this.updateCPU();\n if (this.cmp) this.cmp.stop(Component.getTime(), this.getCycles());\n return;\n }\n\n this.startCPU(fUpdateFocus);\n\n /*\n * calcStartTime() initializes the cycle counter and timestamp for this runCPU() invocation, and optionally\n * recalculates the the maximum number of cycles for each burst if the nCyclesRecalc threshold has been reached.\n */\n this.calcStartTime();\n\n try {\n do {\n /*\n * nCycles is how many cycles we WANT to run on each iteration of stepCPU(), and may be as\n * HIGH as nCyclesPerYield, but it may be significantly less. getBurstCycles() will adjust\n * nCycles downward if any CPU timers need to fire during the next burst.\n */\n var nCycles = this.getBurstCycles(this.flags.checksum? 1 : this.nCyclesPerYield);\n\n /*\n * Execute the burst.\n */\n this.stepCPU(nCycles);\n\n /*\n * Terminate the burst, returning the number of cycles that stepCPU() actually ran.\n */\n nCycles = this.endBurst(true);\n\n /*\n * Add nCycles to nCyclesThisRun, as well as nRunCycles (the cycle count since the CPU first started).\n */\n this.nCyclesThisRun += nCycles;\n this.nRunCycles += nCycles;\n this.updateChecksum(nCycles);\n\n /*\n * Update any/all timers, firing those whose cycle countdowns have reached (or dropped below) zero.\n */\n this.updateTimers(nCycles);\n\n this.nCyclesNextYield -= nCycles;\n if (this.nCyclesNextYield <= 0) {\n this.nCyclesNextYield += this.nCyclesPerYield;\n if (++this.nYieldsSinceStatusUpdate >= CPU8080.YIELDS_PER_STATUS) {\n if (this.cmp) this.cmp.updateStatus();\n this.nYieldsSinceStatusUpdate = 0;\n }\n break;\n }\n } while (this.flags.running);\n }\n catch (e) {\n this.stopCPU();\n this.updateCPU();\n if (this.cmp) this.cmp.stop(Component.getTime(), this.getCycles());\n this.setBusy(false);\n this.setError(e.stack || e.message);\n return;\n }\n\n setTimeout(this.onRunTimeout, this.calcRemainingTime());\n }\n\n /**\n * startCPU(fUpdateFocus)\n *\n * WARNING: Other components must use runCPU() to get the CPU running; this is a runCPU() helper function only.\n *\n * @param {boolean} [fUpdateFocus]\n */\n startCPU(fUpdateFocus)\n {\n if (!this.flags.running) {\n /*\n * setSpeed() without a speed parameter leaves the selected speed in place, but also resets the\n * cycle counter and timestamp for the current series of runCPU() calls, calculates the maximum number\n * of cycles for each burst based on the last known effective CPU speed, and resets the nCyclesRecalc\n * threshold counter.\n */\n this.setSpeed();\n if (this.cmp) this.cmp.start(this.msStartRun, this.getCycles());\n this.flags.running = true;\n this.flags.starting = true;\n if (this.chipset) this.chipset.start();\n var controlRun = this.bindings[\"run\"];\n if (controlRun) controlRun.textContent = \"Halt\";\n if (this.cmp) {\n this.cmp.updateStatus(true);\n if (fUpdateFocus) this.cmp.updateFocus(true);\n }\n }\n }\n\n /**\n * stepCPU(nMinCycles)\n *\n * This will be implemented by the CPUState8080 component.\n *\n * @this {CPU8080}\n * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored)\n * @return {number} of cycles executed; 0 indicates that the last instruction was not executed\n */\n stepCPU(nMinCycles)\n {\n return 0;\n }\n\n /**\n * stopCPU(fComplete)\n *\n * For use by any component that wants to stop the CPU.\n *\n * This similar to yieldCPU(), but it doesn't need to zero nCyclesNextYield to break out of runCPU();\n * it simply needs to clear fRunning (well, \"simply\" may be oversimplifying a bit....)\n *\n * @this {CPU8080}\n * @param {boolean} [fComplete]\n */\n stopCPU(fComplete)\n {\n this.isBusy(true);\n this.endBurst();\n this.addCycles(this.nRunCycles);\n this.nRunCycles = 0;\n if (this.flags.running) {\n this.flags.running = false;\n if (this.chipset) this.chipset.stop();\n var controlRun = this.bindings[\"run\"];\n if (controlRun) controlRun.textContent = \"Run\";\n }\n this.flags.complete = fComplete;\n }\n\n /**\n * updateCPU(fForce)\n *\n * This used to be performed at the end of every stepCPU(), but runCPU() -- which relies upon\n * stepCPU() -- needed to have more control over when these updates are performed. However, for\n * other callers of stepCPU(), such as the Debugger, the combination of stepCPU() + updateCPU()\n * provides the old behavior.\n *\n * @this {CPU8080}\n * @param {boolean} [fForce] (true to force a video update; used by the Debugger)\n */\n updateCPU(fForce)\n {\n if (this.cmp) {\n this.cmp.updateVideo(fForce);\n this.cmp.updateStatus(fForce);\n }\n }\n\n /**\n * yieldCPU()\n *\n * Similar to stopCPU() with regard to how it resets various cycle countdown values, but the CPU\n * remains in a \"running\" state.\n *\n * @this {CPU8080}\n */\n yieldCPU()\n {\n this.endBurst(); // this will break us out of stepCPU()\n this.nCyclesNextYield = 0; // this will break us out of runCPU(), once we break out of stepCPU()\n // if (DEBUG) this.nSnapCycles = this.nBurstCycles;\n /*\n * The Debugger calls yieldCPU() after every message() to ensure browser responsiveness, but it looks\n * odd for those messages to show CPU state changes but for the CPU's own status display to not (ditto\n * for the Video display), so I've added this call to try to keep things looking synchronized.\n */\n this.updateCPU();\n }\n}\n\n/*\n * Constants that control the frequency at which various updates should occur.\n *\n * These values do NOT control the simulation directly. Instead, they are used by\n * calcCycles(), which uses the nCyclesPerSecond passed to the constructor as a starting\n * point and computes the following variables:\n *\n * this.nCyclesPerYield: (this.nCyclesPerSecond / CPU8080.YIELDS_PER_SECOND)\n *\n * The above variables are also multiplied by any cycle multiplier in effect, via setSpeed(),\n * and then they're used to initialize another set of variables for each runCPU() iteration:\n *\n * this.nCyclesNextYield: this.nCyclesPerYield\n */\nCPU8080.YIELDS_PER_SECOND = 30; // just a gut feeling for the MINIMUM number of yields per second\nCPU8080.YIELDS_PER_STATUS = 15; // every 15 yields (ie, twice per second), perform CPU status updates\n\nCPU8080.BUTTONS = [\"power\", \"reset\"];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/cpustate.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass CPUState8080 extends CPU8080 {\n /**\n * CPUState8080(parmsCPU)\n *\n * The CPUState8080 class uses the following (parmsCPU) properties:\n *\n * model: a number (eg, 8080) that should match one of the CPUDef8080.MODEL_* values\n *\n * This extends the CPU class and passes any remaining parmsCPU properties to the CPU class\n * constructor, along with a default speed (cycles per second) based on the specified (or default)\n * CPU model number.\n *\n * The CPUState8080 class was initially written to simulate a 8080 microprocessor, although over time\n * it may evolved to support other microprocessors (eg, the Zilog Z80).\n *\n * @this {CPUState8080}\n * @param {Object} parmsCPU\n */\n constructor(parmsCPU)\n {\n var nCyclesDefault = 0;\n var model = +parmsCPU['model'] || CPUDef8080.MODEL_8080;\n\n switch(model) {\n case CPUDef8080.MODEL_8080:\n default:\n nCyclesDefault = 1000000;\n break;\n }\n\n super(parmsCPU, nCyclesDefault);\n\n this.model = model;\n\n /*\n * Initialize processor operation to match the requested model\n */\n this.initProcessor();\n\n /*\n * A variety of stepCPU() state variables that don't strictly need to be initialized before the first\n * stepCPU() call, but it's good form to do so.\n */\n this.resetCycles();\n this.flags.complete = this.flags.debugCheck = false;\n\n /*\n * If there are no live registers to display, then updateStatus() can skip a bit....\n */\n this.cLiveRegs = 0;\n\n /*\n * Array of halt handlers, if any (see addHaltCheck)\n */\n this.afnHalt = [];\n this.addrReset = 0x0000;\n\n /*\n * This initial resetRegs() call is important to create all the registers, so that if/when we call restore(),\n * it will have something to fill in.\n */\n this.resetRegs();\n }\n\n /**\n * addHaltCheck(fn)\n *\n * Records a function that will be called during HLT opcode processing.\n *\n * @this {CPUState8080}\n * @param {function(number)} fn\n */\n addHaltCheck(fn)\n {\n this.afnHalt.push(fn);\n }\n\n /**\n * initProcessor()\n *\n * Interestingly, if I dynamically generate aOps as an array of functions bound to \"this\", using the bind()\n * method, overall performance is worse. You would think that eliminating the need to use the call() method\n * on every opcode function invocation would be helpful, but it's not. I'm not sure exactly why yet; perhaps\n * a Closure Compiler optimization is defeated when generating the function array at run-time instead of at\n * compile-time.\n *\n * @this {CPUState8080}\n */\n initProcessor()\n {\n this.aOps = CPUDef8080.aOps8080;\n }\n\n /**\n * reset()\n *\n * @this {CPUState8080}\n */\n reset()\n {\n if (this.flags.running) this.stopCPU();\n this.resetRegs();\n this.resetCycles();\n this.clearError(); // clear any fatal error/exception that setError() may have flagged\n super.reset();\n }\n\n /**\n * resetRegs()\n *\n * @this {CPUState8080}\n */\n resetRegs()\n {\n this.regA = 0;\n this.regB = 0;\n this.regC = 0;\n this.regD = 0;\n this.regE = 0;\n this.regH = 0;\n this.regL = 0;\n this.setSP(0);\n this.setPC(this.addrReset);\n\n /*\n * This resets the Processor Status flags (regPS), along with all the internal \"result registers\".\n */\n this.setPS(0);\n\n /*\n * intFlags contains some internal states we use to indicate whether a hardware interrupt (INTFLAG.INTR) or\n * Trap software interrupt (INTR.TRAP) has been requested, as well as when we're in a \"HLT\" state (INTFLAG.HALT)\n * that requires us to wait for a hardware interrupt (INTFLAG.INTR) before continuing execution.\n */\n this.intFlags = CPUDef8080.INTFLAG.NONE;\n }\n\n /**\n * setReset(addr)\n *\n * @this {CPUState8080}\n * @param {number} addr\n */\n setReset(addr)\n {\n this.addrReset = addr;\n this.setPC(addr);\n }\n\n /**\n * getChecksum()\n *\n * @this {CPUState8080}\n * @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code)\n */\n getChecksum()\n {\n var sum = (this.regA + this.regB + this.regC + this.regD + this.regE + this.regH + this.regL)|0;\n sum = (sum + this.getSP() + this.getPC() + this.getPS())|0;\n return sum;\n }\n\n /**\n * save()\n *\n * This implements save support for the CPUState8080 component.\n *\n * @this {CPUState8080}\n * @return {Object|null}\n */\n save()\n {\n var state = new State(this);\n state.set(0, [this.regA, this.regB, this.regC, this.regD, this.regE, this.regH, this.regL, this.getSP(), this.getPC(), this.getPS()]);\n state.set(1, [this.intFlags, this.nTotalCycles, this.getSpeed()]);\n state.set(2, this.bus.saveMemory());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the CPUState8080 component.\n *\n * @this {CPUState8080}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n var a = data[0];\n this.regA = a[0];\n this.regB = a[1];\n this.regC = a[2];\n this.regD = a[3];\n this.regE = a[4];\n this.regH = a[5];\n this.regL = a[6];\n this.setSP(a[7]);\n this.setPC(a[8]);\n this.setPS(a[9]);\n a = data[1];\n this.intFlags = a[0];\n this.nTotalCycles = a[1];\n this.setSpeed(a[3]);\n return this.bus.restoreMemory(data[2]);\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {CPUState8080}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"AX\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var fBound = false;\n switch (sBinding) {\n case \"A\":\n case \"B\":\n case \"C\":\n case \"BC\":\n case \"D\":\n case \"E\":\n case \"DE\":\n case \"H\":\n case \"L\":\n case \"HL\":\n case \"SP\":\n case \"PC\":\n case \"PS\":\n case \"IF\":\n case \"SF\":\n case \"ZF\":\n case \"AF\":\n case \"PF\":\n case \"CF\":\n this.bindings[sBinding] = control;\n this.cLiveRegs++;\n fBound = true;\n break;\n default:\n fBound = super.setBinding(sHTMLType, sBinding, control);\n break;\n }\n return fBound;\n }\n\n /**\n * getBC()\n *\n * @this {CPUState8080}\n * @return {number}\n */\n getBC()\n {\n return (this.regB << 8) | this.regC;\n }\n\n /**\n * setBC(w)\n *\n * @this {CPUState8080}\n * @param {number} w\n */\n setBC(w)\n {\n this.regB = (w >> 8) & 0xff;\n this.regC = w & 0xff;\n }\n\n /**\n * getDE()\n *\n * @this {CPUState8080}\n * @return {number}\n */\n getDE()\n {\n return (this.regD << 8) | this.regE;\n }\n\n /**\n * setDE(w)\n *\n * @this {CPUState8080}\n * @param {number} w\n */\n setDE(w)\n {\n this.regD = (w >> 8) & 0xff;\n this.regE = w & 0xff;\n }\n\n /**\n * getHL()\n *\n * @this {CPUState8080}\n * @return {number}\n */\n getHL()\n {\n return (this.regH << 8) | this.regL;\n }\n\n /**\n * setHL(w)\n *\n * @this {CPUState8080}\n * @param {number} w\n */\n setHL(w)\n {\n this.regH = (w >> 8) & 0xff;\n this.regL = w & 0xff;\n }\n\n /**\n * getSP()\n *\n * @this {CPUState8080}\n * @return {number}\n */\n getSP()\n {\n return this.regSP;\n }\n\n /**\n * setSP(off)\n *\n * @this {CPUState8080}\n * @param {number} off\n */\n setSP(off)\n {\n this.regSP = off & 0xffff;\n }\n\n /**\n * getPC()\n *\n * @this {CPUState8080}\n * @return {number}\n */\n getPC()\n {\n return this.regPC;\n }\n\n /**\n * offPC()\n *\n * @this {CPUState8080}\n * @param {number} off\n * @return {number}\n */\n offPC(off)\n {\n return (this.regPC + off) & 0xffff;\n }\n\n /**\n * setPC(off)\n *\n * @this {CPUState8080}\n * @param {number} off\n */\n setPC(off)\n {\n this.regPC = off & 0xffff;\n }\n\n /**\n * clearCF()\n *\n * @this {CPUState8080}\n */\n clearCF()\n {\n this.resultZeroCarry &= 0xff;\n }\n\n /**\n * getCF()\n *\n * @this {CPUState8080}\n * @return {number} 0 or 1 (CPUDef8080.PS.CF)\n */\n getCF()\n {\n return (this.resultZeroCarry & 0x100)? CPUDef8080.PS.CF : 0;\n }\n\n /**\n * setCF()\n *\n * @this {CPUState8080}\n */\n setCF()\n {\n this.resultZeroCarry |= 0x100;\n }\n\n /**\n * updateCF(CF)\n *\n * @this {CPUState8080}\n * @param {number} CF (0x000 or 0x100)\n */\n updateCF(CF)\n {\n this.resultZeroCarry = (this.resultZeroCarry & 0xff) | CF;\n }\n\n /**\n * clearPF()\n *\n * @this {CPUState8080}\n */\n clearPF()\n {\n if (this.getPF()) this.resultParitySign ^= 0x1;\n }\n\n /**\n * getPF()\n *\n * @this {CPUState8080}\n * @return {number} 0 or CPUDef8080.PS.PF\n */\n getPF()\n {\n return (CPUDef8080.PARITY[this.resultParitySign & 0xff])? CPUDef8080.PS.PF : 0;\n }\n\n /**\n * setPF()\n *\n * @this {CPUState8080}\n */\n setPF()\n {\n if (!this.getPF()) this.resultParitySign ^= 0x1;\n }\n\n /**\n * clearAF()\n *\n * @this {CPUState8080}\n */\n clearAF()\n {\n this.resultAuxOverflow = (this.resultParitySign & 0x10) | (this.resultAuxOverflow & ~0x10);\n }\n\n /**\n * getAF()\n *\n * @this {CPUState8080}\n * @return {number} 0 or CPUDef8080.PS.AF\n */\n getAF()\n {\n return ((this.resultParitySign ^ this.resultAuxOverflow) & 0x10)? CPUDef8080.PS.AF : 0;\n }\n\n /**\n * setAF()\n *\n * @this {CPUState8080}\n */\n setAF()\n {\n this.resultAuxOverflow = (~this.resultParitySign & 0x10) | (this.resultAuxOverflow & ~0x10);\n }\n\n /**\n * clearZF()\n *\n * @this {CPUState8080}\n */\n clearZF()\n {\n this.resultZeroCarry |= 0xff;\n }\n\n /**\n * getZF()\n *\n * @this {CPUState8080}\n * @return {number} 0 or CPUDef8080.PS.ZF\n */\n getZF()\n {\n return (this.resultZeroCarry & 0xff)? 0 : CPUDef8080.PS.ZF;\n }\n\n /**\n * setZF()\n *\n * @this {CPUState8080}\n */\n setZF()\n {\n this.resultZeroCarry &= ~0xff;\n }\n\n /**\n * clearSF()\n *\n * @this {CPUState8080}\n */\n clearSF()\n {\n if (this.getSF()) this.resultParitySign ^= 0xc0;\n }\n\n /**\n * getSF()\n *\n * @this {CPUState8080}\n * @return {number} 0 or CPUDef8080.PS.SF\n */\n getSF()\n {\n return (this.resultParitySign & 0x80)? CPUDef8080.PS.SF : 0;\n }\n\n /**\n * setSF()\n *\n * @this {CPUState8080}\n */\n setSF()\n {\n if (!this.getSF()) this.resultParitySign ^= 0xc0;\n }\n\n /**\n * clearIF()\n *\n * @this {CPUState8080}\n */\n clearIF()\n {\n this.regPS &= ~CPUDef8080.PS.IF;\n }\n\n /**\n * getIF()\n *\n * @this {CPUState8080}\n * @return {number} 0 or CPUDef8080.PS.IF\n */\n getIF()\n {\n return (this.regPS & CPUDef8080.PS.IF);\n }\n\n /**\n * setIF()\n *\n * @this {CPUState8080}\n */\n setIF()\n {\n this.regPS |= CPUDef8080.PS.IF;\n }\n\n /**\n * getPS()\n *\n * @this {CPUState8080}\n * @return {number}\n */\n getPS()\n {\n return (this.regPS & ~CPUDef8080.PS.RESULT) | (this.getSF() | this.getZF() | this.getAF() | this.getPF() | this.getCF());\n }\n\n /**\n * setPS(regPS)\n *\n * @this {CPUState8080}\n * @param {number} regPS\n */\n setPS(regPS)\n {\n this.resultZeroCarry = this.resultParitySign = this.resultAuxOverflow = 0;\n if (regPS & CPUDef8080.PS.CF) this.resultZeroCarry |= 0x100;\n if (!(regPS & CPUDef8080.PS.PF)) this.resultParitySign |= 0x01;\n if (regPS & CPUDef8080.PS.AF) this.resultAuxOverflow |= 0x10;\n if (!(regPS & CPUDef8080.PS.ZF)) this.resultZeroCarry |= 0xff;\n if (regPS & CPUDef8080.PS.SF) this.resultParitySign ^= 0xc0;\n this.regPS = (this.regPS & ~(CPUDef8080.PS.RESULT | CPUDef8080.PS.INTERNAL)) | (regPS & CPUDef8080.PS.INTERNAL) | CPUDef8080.PS.SET;\n\n }\n\n /**\n * getPSW()\n *\n * @this {CPUState8080}\n * @return {number}\n */\n getPSW()\n {\n return (this.getPS() & CPUDef8080.PS.MASK) | (this.regA << 8);\n }\n\n /**\n * setPSW(w)\n *\n * @this {CPUState8080}\n * @param {number} w\n */\n setPSW(w)\n {\n this.setPS((w & CPUDef8080.PS.MASK) | (this.regPS & ~CPUDef8080.PS.MASK));\n this.regA = w >> 8;\n }\n\n /**\n * addByte(src)\n *\n * @this {CPUState8080}\n * @param {number} src\n * @return {number} regA + src\n */\n addByte(src)\n {\n this.resultAuxOverflow = this.regA ^ src;\n return this.resultParitySign = (this.resultZeroCarry = this.regA + src) & 0xff;\n }\n\n /**\n * addByteCarry(src)\n *\n * @this {CPUState8080}\n * @param {number} src\n * @return {number} regA + src + carry\n */\n addByteCarry(src)\n {\n this.resultAuxOverflow = this.regA ^ src;\n return this.resultParitySign = (this.resultZeroCarry = this.regA + src + ((this.resultZeroCarry & 0x100)? 1 : 0)) & 0xff;\n }\n\n /**\n * andByte(src)\n *\n * Ordinarily, one would expect the Auxiliary Carry flag (AF) to be clear after this operation,\n * but apparently the 8080 will set AF if bit 3 in either operand is set.\n *\n * @this {CPUState8080}\n * @param {number} src\n * @return {number} regA & src\n */\n andByte(src)\n {\n this.resultZeroCarry = this.resultParitySign = this.resultAuxOverflow = this.regA & src;\n if ((this.regA | src) & 0x8) this.resultAuxOverflow ^= 0x10; // set AF by inverting bit 4 in resultAuxOverflow\n return this.resultZeroCarry;\n }\n\n /**\n * decByte(b)\n *\n * We perform this operation using 8-bit two's complement arithmetic, by negating and then adding\n * the implied src of 1. This appears to mimic how the 8080 manages the Auxiliary Carry flag (AF).\n *\n * @this {CPUState8080}\n * @param {number} b\n * @return {number}\n */\n decByte(b)\n {\n this.resultAuxOverflow = b ^ 0xff;\n b = this.resultParitySign = (b + 0xff) & 0xff;\n this.resultZeroCarry = (this.resultZeroCarry & ~0xff) | b;\n return b;\n }\n\n /**\n * incByte(b)\n *\n * @this {CPUState8080}\n * @param {number} b\n * @return {number}\n */\n incByte(b)\n {\n this.resultAuxOverflow = b;\n b = this.resultParitySign = (b + 1) & 0xff;\n this.resultZeroCarry = (this.resultZeroCarry & ~0xff) | b;\n return b;\n }\n\n /**\n * orByte(src)\n *\n * @this {CPUState8080}\n * @param {number} src\n * @return {number} regA | src\n */\n orByte(src)\n {\n return this.resultParitySign = this.resultZeroCarry = this.resultAuxOverflow = this.regA | src;\n }\n\n /**\n * subByte(src)\n *\n * We perform this operation using 8-bit two's complement arithmetic, by inverting src, adding\n * src + 1, and then inverting the resulting carry (resultZeroCarry ^ 0x100). This appears to mimic\n * how the 8080 manages the Auxiliary Carry flag (AF).\n *\n * This function is also used as a cmpByte() function; compare instructions simply ignore the\n * return value.\n *\n * Example: A=66, SUI $10\n *\n * If we created the two's complement of 0x10 by negating it, there would just be one addition:\n *\n * 0110 0110 (0x66)\n * + 1111 0000 (0xF0) (ie, -0x10)\n * ---------\n * 1 0101 0110 (0x56)\n *\n * But in order to mimic the 8080's AF flag, we must perform the two's complement of src in two steps,\n * inverting it before the add, and then incrementing after the add; eg:\n *\n * 0110 0110 (0x66)\n * + 1110 1111 (0xEF) (ie, ~0x10)\n * ---------\n * 1 0101 0101 (0x55)\n * + 0000 0001 (0x01)\n * ---------\n * 1 0101 0110 (0x56)\n *\n * @this {CPUState8080}\n * @param {number} src\n * @return {number} regA - src\n */\n subByte(src)\n {\n src ^= 0xff;\n this.resultAuxOverflow = this.regA ^ src;\n return this.resultParitySign = (this.resultZeroCarry = (this.regA + src + 1) ^ 0x100) & 0xff;\n }\n\n /**\n * subByteBorrow(src)\n *\n * We perform this operation using 8-bit two's complement arithmetic, using logic similar to subByte(),\n * but changing the final increment to a conditional increment, because if the Carry flag (CF) is set, then\n * we don't need to perform the increment at all.\n *\n * This mimics the behavior of subByte() when the Carry flag (CF) is clear, and hopefully also mimics how the\n * 8080 manages the Auxiliary Carry flag (AF) when the Carry flag (CF) is set.\n *\n * @this {CPUState8080}\n * @param {number} src\n * @return {number} regA - src - carry\n */\n subByteBorrow(src)\n {\n src ^= 0xff;\n this.resultAuxOverflow = this.regA ^ src;\n return this.resultParitySign = (this.resultZeroCarry = (this.regA + src + ((this.resultZeroCarry & 0x100)? 0 : 1)) ^ 0x100) & 0xff;\n }\n\n /**\n * xorByte(src)\n *\n * @this {CPUState8080}\n * @param {number} src\n * @return {number} regA ^ src\n */\n xorByte(src)\n {\n return this.resultParitySign = this.resultZeroCarry = this.resultAuxOverflow = this.regA ^ src;\n }\n\n /**\n * getByte(addr)\n *\n * @this {CPUState8080}\n * @param {number} addr is a linear address\n * @return {number} byte (8-bit) value at that address\n */\n getByte(addr)\n {\n return this.bus.getByte(addr);\n }\n\n /**\n * getWord(addr)\n *\n * @this {CPUState8080}\n * @param {number} addr is a linear address\n * @return {number} word (16-bit) value at that address\n */\n getWord(addr)\n {\n return this.bus.getShort(addr);\n }\n\n /**\n * setByte(addr, b)\n *\n * @this {CPUState8080}\n * @param {number} addr is a linear address\n * @param {number} b is the byte (8-bit) value to write (which we truncate to 8 bits; required by opSTOSb)\n */\n setByte(addr, b)\n {\n this.bus.setByte(addr, b);\n }\n\n /**\n * setWord(addr, w)\n *\n * @this {CPUState8080}\n * @param {number} addr is a linear address\n * @param {number} w is the word (16-bit) value to write (which we truncate to 16 bits to be safe)\n */\n setWord(addr, w)\n {\n this.bus.setShort(addr, w);\n }\n\n /**\n * getPCByte()\n *\n * @this {CPUState8080}\n * @return {number} byte at the current PC; PC advanced by 1\n */\n getPCByte()\n {\n var b = this.getByte(this.regPC);\n this.setPC(this.regPC + 1);\n return b;\n }\n\n /**\n * getPCWord()\n *\n * @this {CPUState8080}\n * @return {number} word at the current PC; PC advanced by 2\n */\n getPCWord()\n {\n var w = this.getWord(this.regPC);\n this.setPC(this.regPC + 2);\n return w;\n }\n\n /**\n * popWord()\n *\n * @this {CPUState8080}\n * @return {number} word popped from the current SP; SP increased by 2\n */\n popWord()\n {\n var w = this.getWord(this.regSP);\n this.setSP(this.regSP + 2);\n return w;\n }\n\n /**\n * pushWord(w)\n *\n * @this {CPUState8080}\n * @param {number} w is the word (16-bit) value to push at current SP; SP decreased by 2\n */\n pushWord(w)\n {\n this.setSP(this.regSP - 2);\n this.setWord(this.regSP, w);\n }\n\n /**\n * checkINTR()\n *\n * @this {CPUState8080}\n * @return {boolean} true if execution may proceed, false if not\n */\n checkINTR()\n {\n /*\n * If the Debugger is single-stepping, this.nStepCycles will always be zero, which we take\n * advantage of here to avoid processing interrupts. The Debugger will have to issue a \"g\"\n * command (or \"p\" command on a call instruction) if you want interrupts to be processed.\n */\n if (this.nStepCycles) {\n if ((this.intFlags & CPUDef8080.INTFLAG.INTR) && this.getIF()) {\n for (var nLevel = 0; nLevel < 8; nLevel++) {\n if (this.intFlags & (1 << nLevel)) break;\n }\n this.clearINTR(nLevel);\n this.clearIF();\n this.intFlags &= ~CPUDef8080.INTFLAG.HALT;\n this.aOps[CPUDef8080.OPCODE.RST0 | (nLevel << 3)].call(this);\n }\n }\n if (this.intFlags & CPUDef8080.INTFLAG.HALT) {\n /*\n * As discussed in opHLT(), the CPU is never REALLY halted by a HLT instruction; instead, opHLT()\n * calls requestHALT(), which sets INTFLAG.HALT and signals to stepCPU() that it's free to end the\n * current burst AND that it should not execute any more instructions until checkINTR() indicates\n * that a hardware interrupt has been requested.\n */\n this.endBurst();\n return false;\n }\n return true;\n }\n\n /**\n * clearINTR(nLevel)\n *\n * Clear the corresponding interrupt level.\n *\n * nLevel can either be a valid interrupt level (0-7), or -1 to clear all pending interrupts\n * (eg, in the event of a system-wide reset).\n *\n * @this {CPUState8080}\n * @param {number} nLevel (0-7, or -1 for all)\n */\n clearINTR(nLevel)\n {\n var bitsClear = nLevel < 0? 0xff : (1 << nLevel);\n this.intFlags &= ~bitsClear;\n }\n\n /**\n * requestHALT()\n *\n * @this {CPUState8080}\n */\n requestHALT()\n {\n this.intFlags |= CPUDef8080.INTFLAG.HALT;\n this.endBurst();\n }\n\n /**\n * requestINTR(nLevel)\n *\n * Request the corresponding interrupt level.\n *\n * Each interrupt level (0-7) has its own intFlags bit (0-7). If the Interrupt Flag (IF) is also\n * set, then we know that checkINTR() will want to issue the interrupt, so we end the current burst\n * by setting nStepCycles to zero. But before we do, we subtract nStepCycles from nBurstCycles,\n * so that the calculation of how many cycles were actually executed on this burst is correct.\n *\n * @this {CPUState8080}\n * @param {number} nLevel (0-7)\n */\n requestINTR(nLevel)\n {\n this.intFlags |= (1 << nLevel);\n if (this.getIF()) {\n this.endBurst();\n }\n }\n\n /**\n * updateReg(sReg, nValue, cch)\n *\n * This function helps updateStatus() by massaging the register names and values according to\n * CPU type before passing the call to displayValue(); in the \"old days\", updateStatus() called\n * displayValue() directly (although then it was called displayReg()).\n *\n * @this {CPUState8080}\n * @param {string} sReg\n * @param {number} nValue\n * @param {number} [cch] (default is 2 hex digits)\n */\n updateReg(sReg, nValue, cch)\n {\n this.displayValue(sReg, nValue, cch || 2);\n }\n\n /**\n * updateStatus(fForce)\n *\n * This provides periodic Control Panel updates (eg, a few times per second; see YIELDS_PER_STATUS).\n * this is where we take care of any DOM updates (eg, register values) while the CPU is running.\n *\n * Any high-frequency updates should be performed in updateVideo(), which should avoid DOM updates,\n * since updateVideo() can be called up to 60 times per second.\n *\n * @this {CPUState8080}\n * @param {boolean} [fForce] (true will display registers even if the CPU is running and \"live\" registers are not enabled)\n */\n updateStatus(fForce)\n {\n if (this.cLiveRegs) {\n if (fForce || !this.flags.running || this.flags.displayLiveRegs) {\n this.updateReg(\"A\", this.regA);\n this.updateReg(\"B\", this.regB);\n this.updateReg(\"C\", this.regC);\n this.updateReg(\"BC\", this.getBC(), 4);\n this.updateReg(\"D\", this.regD);\n this.updateReg(\"E\", this.regE);\n this.updateReg(\"DE\", this.getDE(), 4);\n this.updateReg(\"H\", this.regH);\n this.updateReg(\"L\", this.regL);\n this.updateReg(\"HL\", this.getHL(), 4);\n this.updateReg(\"SP\", this.getSP(), 4);\n this.updateReg(\"PC\", this.getPC(), 4);\n var regPS = this.getPS();\n this.updateReg(\"PS\", regPS, 4);\n this.updateReg(\"IF\", (regPS & CPUDef8080.PS.IF)? 1 : 0, 1);\n this.updateReg(\"SF\", (regPS & CPUDef8080.PS.SF)? 1 : 0, 1);\n this.updateReg(\"ZF\", (regPS & CPUDef8080.PS.ZF)? 1 : 0, 1);\n this.updateReg(\"AF\", (regPS & CPUDef8080.PS.AF)? 1 : 0, 1);\n this.updateReg(\"PF\", (regPS & CPUDef8080.PS.PF)? 1 : 0, 1);\n this.updateReg(\"CF\", (regPS & CPUDef8080.PS.CF)? 1 : 0, 1);\n }\n }\n var controlSpeed = this.bindings[\"speed\"];\n if (controlSpeed) controlSpeed.textContent = this.getSpeedCurrent();\n }\n\n /**\n * stepCPU(nMinCycles)\n *\n * NOTE: Single-stepping should not be confused with the Trap flag; single-stepping is a Debugger\n * operation that's completely independent of Trap status. The CPU can go in and out of Trap mode,\n * in and out of h/w interrupt service routines (ISRs), etc, but from the Debugger's perspective,\n * they're all one continuous stream of instructions that can be stepped or run at will. Moreover,\n * stepping vs. running should never change the behavior of the simulation.\n *\n * @this {CPUState8080}\n * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored)\n * @return {number} of cycles executed; 0 indicates a pre-execution condition (ie, an execution breakpoint\n * was hit), -1 indicates a post-execution condition (eg, a read or write breakpoint was hit), and a positive\n * number indicates successful completion of that many cycles (which should always be >= nMinCycles).\n */\n stepCPU(nMinCycles)\n {\n /*\n * The Debugger uses fComplete to determine if the instruction completed (true) or was interrupted\n * by a breakpoint or some other exceptional condition (false). NOTE: this does NOT include JavaScript\n * exceptions, which stepCPU() expects the caller to catch using its own exception handler.\n *\n * The CPU relies on the use of stopCPU() rather than fComplete, because the CPU never single-steps\n * (ie, nMinCycles is always some large number), whereas the Debugger does. And conversely, when the\n * Debugger is single-stepping (even when performing multiple single-steps), fRunning is never set,\n * so stopCPU() would have no effect as far as the Debugger is concerned.\n */\n this.flags.complete = true;\n\n /*\n * fDebugCheck is true if we need to \"check\" every instruction with the Debugger.\n */\n var fDebugCheck = this.flags.debugCheck = (DEBUGGER && this.dbg && this.dbg.checksEnabled());\n\n /*\n * nDebugState is checked only when fDebugCheck is true, and its sole purpose is to tell the first call\n * to checkInstruction() that it can skip breakpoint checks, and that will be true ONLY when fStarting is\n * true OR nMinCycles is zero (the latter means the Debugger is single-stepping).\n *\n * Once we snap fStarting, we clear it, because technically, we've moved beyond \"starting\" and have\n * officially \"started\" now.\n */\n var nDebugState = (!nMinCycles)? -1 : (this.flags.starting? 0 : 1);\n this.flags.starting = false;\n\n /*\n * We move the minimum cycle count to nStepCycles (the number of cycles left to step), so that other\n * functions have the ability to force that number to zero (eg, stopCPU()), and thus we don't have to check\n * any other criteria to determine whether we should continue stepping or not.\n */\n this.nBurstCycles = this.nStepCycles = nMinCycles;\n\n /*\n * NOTE: If checkINTR() returns false, INTFLAG.HALT must be set, so no instructions should be executed.\n */\n if (this.checkINTR()) {\n do {\n if (DEBUGGER && fDebugCheck) {\n if (this.dbg.checkInstruction(this.regPC, nDebugState)) {\n this.stopCPU();\n break;\n }\n nDebugState = 1;\n }\n this.aOps[this.getPCByte()].call(this);\n\n } while (this.nStepCycles > 0);\n }\n\n return (this.flags.complete? this.nBurstCycles - this.nStepCycles : (this.flags.complete === undefined? 0 : -1));\n }\n\n /**\n * CPUState8080.init()\n *\n * This function operates on every HTML element of class \"cpu\", extracting the\n * JSON-encoded parameters for the CPUState8080 constructor from the element's \"data-value\"\n * attribute, invoking the constructor (which in turn invokes the CPU constructor)\n * to create a CPUState8080 component, and then binding any associated HTML controls to the\n * new component.\n */\n static init()\n {\n var aeCPUs = Component.getElementsByClass(document, PC8080.APPCLASS, \"cpu\");\n for (var iCPU = 0; iCPU < aeCPUs.length; iCPU++) {\n var eCPU = aeCPUs[iCPU];\n var parmsCPU = Component.getComponentParms(eCPU);\n var cpu = new CPUState8080(parmsCPU);\n Component.bindComponentControls(cpu, eCPU, PC8080.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize every CPU module on the page\n */\nWeb.onInit(CPUState8080.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/cpuops.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * op=0x00 (NOP)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opNOP = function()\n{\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x01 (LXI B,d16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opLXIB = function()\n{\n this.setBC(this.getPCWord());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x02 (STAX B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSTAXB = function()\n{\n this.setByte(this.getBC(), this.regA);\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x03 (INX B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINXB = function()\n{\n this.setBC(this.getBC() + 1);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x04 (INR B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINRB = function()\n{\n this.regB = this.incByte(this.regB);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x05 (DCR B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCRB = function()\n{\n this.regB = this.decByte(this.regB);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x06 (MVI B,d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMVIB = function()\n{\n this.regB = this.getPCByte();\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x07 (RLC)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRLC = function()\n{\n var carry = this.regA << 1;\n this.regA = (carry & 0xff) | (carry >> 8);\n this.updateCF(carry & 0x100);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x09 (DAD B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDADB = function()\n{\n var w;\n this.setHL(w = this.getHL() + this.getBC());\n this.updateCF((w >> 8) & 0x100);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x0A (LDAX B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opLDAXB = function()\n{\n this.regA = this.getByte(this.getBC());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x0B (DCX B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCXB = function()\n{\n this.setBC(this.getBC() - 1);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x0C (INR C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINRC = function()\n{\n this.regC = this.incByte(this.regC);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x0D (DCR C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCRC = function()\n{\n this.regC = this.decByte(this.regC);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x0E (MVI C,d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMVIC = function()\n{\n this.regC = this.getPCByte();\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x0F (RRC)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRRC = function()\n{\n var carry = (this.regA << 8) & 0x100;\n this.regA = (carry | this.regA) >> 1;\n this.updateCF(carry);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x11 (LXI D,d16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opLXID = function()\n{\n this.setDE(this.getPCWord());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x12 (STAX D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSTAXD = function()\n{\n this.setByte(this.getDE(), this.regA);\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x13 (INX D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINXD = function()\n{\n this.setDE(this.getDE() + 1);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x14 (INR D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINRD = function()\n{\n this.regD = this.incByte(this.regD);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x15 (DCR D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCRD = function()\n{\n this.regD = this.decByte(this.regD);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x16 (MVI D,d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMVID = function()\n{\n this.regD = this.getPCByte();\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x17 (RAL)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRAL = function()\n{\n var carry = this.regA << 1;\n this.regA = (carry & 0xff) | this.getCF();\n this.updateCF(carry & 0x100);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x19 (DAD D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDADD = function()\n{\n var w;\n this.setHL(w = this.getHL() + this.getDE());\n this.updateCF((w >> 8) & 0x100);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x1A (LDAX D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opLDAXD = function()\n{\n this.regA = this.getByte(this.getDE());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x1B (DCX D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCXD = function()\n{\n this.setDE(this.getDE() - 1);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x1C (INR E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINRE = function()\n{\n this.regE = this.incByte(this.regE);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x1D (DCR E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCRE = function()\n{\n this.regE = this.decByte(this.regE);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x1E (MVI E,d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMVIE = function()\n{\n this.regE = this.getPCByte();\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x1F (RAR)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRAR = function()\n{\n var carry = (this.regA << 8);\n this.regA = ((this.getCF() << 8) | this.regA) >> 1;\n this.updateCF(carry & 0x100);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x21 (LXI H,d16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opLXIH = function()\n{\n this.setHL(this.getPCWord());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x22 (SHLD a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSHLD = function()\n{\n this.setWord(this.getPCWord(), this.getHL());\n this.nStepCycles -= 16;\n};\n\n/**\n * op=0x23 (INX H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINXH = function()\n{\n this.setHL(this.getHL() + 1);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x24 (INR H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINRH = function()\n{\n this.regH = this.incByte(this.regH);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x25 (DCR H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCRH = function()\n{\n this.regH = this.decByte(this.regH);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x26 (MVI H,d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMVIH = function()\n{\n this.regH = this.getPCByte();\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x27 (DAA)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDAA = function()\n{\n var src = 0;\n var CF = this.getCF();\n var AF = this.getAF();\n if (AF || (this.regA & 0x0F) > 9) {\n src |= 0x06;\n }\n if (CF || this.regA >= 0x9A) {\n src |= 0x60;\n CF = CPUDef8080.PS.CF;\n }\n this.regA = this.addByte(src);\n this.updateCF(CF? 0x100 : 0);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x29 (DAD H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDADH = function()\n{\n var w;\n this.setHL(w = this.getHL() + this.getHL());\n this.updateCF((w >> 8) & 0x100);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x2A (LHLD a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opLHLD = function()\n{\n this.setHL(this.getWord(this.getPCWord()));\n this.nStepCycles -= 16;\n};\n\n/**\n * op=0x2B (DCX H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCXH = function()\n{\n this.setHL(this.getHL() - 1);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x2C (INR L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINRL = function()\n{\n this.regL = this.incByte(this.regL);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x2D (DCR L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCRL = function()\n{\n this.regL = this.decByte(this.regL);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x2E (MVI L,d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMVIL = function()\n{\n this.regL = this.getPCByte();\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x2F (CMA)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCMA = function()\n{\n this.regA = ~this.regA & 0xff;\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x31 (LXI SP,d16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opLXISP = function()\n{\n this.setSP(this.getPCWord());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x32 (STA a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSTA = function()\n{\n this.setByte(this.getPCWord(), this.regA);\n this.nStepCycles -= 13;\n};\n\n/**\n * op=0x33 (INX SP)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINXSP = function()\n{\n this.setSP(this.getSP() + 1);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x34 (INR M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINRM = function()\n{\n var addr = this.getHL();\n this.setByte(addr, this.incByte(this.getByte(addr)));\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x35 (DCR M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCRM = function()\n{\n var addr = this.getHL();\n this.setByte(addr, this.decByte(this.getByte(addr)));\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x36 (MVI M,d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMVIM = function()\n{\n this.setByte(this.getHL(), this.getPCByte());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x37 (STC)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSTC = function()\n{\n this.setCF();\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x39 (DAD SP)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDADSP = function()\n{\n var w;\n this.setHL(w = this.getHL() + this.getSP());\n this.updateCF((w >> 8) & 0x100);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x3A (LDA a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opLDA = function()\n{\n this.regA = this.getByte(this.getPCWord());\n this.nStepCycles -= 13;\n};\n\n/**\n * op=0x3B (DCX SP)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCXSP = function()\n{\n this.setSP(this.getSP() - 1);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x3C (INR A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINRA = function()\n{\n this.regA = this.incByte(this.regA);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x3D (DCR A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCRA = function()\n{\n this.regA = this.decByte(this.regA);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x3E (MVI A,d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMVIA = function()\n{\n this.regA = this.getPCByte();\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x3F (CMC)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCMC = function()\n{\n this.updateCF(this.getCF()? 0 : 0x100);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x40 (MOV B,B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVBB = function()\n{\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x41 (MOV B,C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVBC = function()\n{\n this.regB = this.regC;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x42 (MOV B,D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVBD = function()\n{\n this.regB = this.regD;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x43 (MOV B,E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVBE = function()\n{\n this.regB = this.regE;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x44 (MOV B,H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVBH = function()\n{\n this.regB = this.regH;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x45 (MOV B,L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVBL = function()\n{\n this.regB = this.regL;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x46 (MOV B,M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVBM = function()\n{\n this.regB = this.getByte(this.getHL());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x47 (MOV B,A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVBA = function()\n{\n this.regB = this.regA;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x48 (MOV C,B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVCB = function()\n{\n this.regC = this.regB;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x49 (MOV C,C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVCC = function()\n{\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x4A (MOV C,D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVCD = function()\n{\n this.regC = this.regD;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x4B (MOV C,E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVCE = function()\n{\n this.regC = this.regE;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x4C (MOV C,H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVCH = function()\n{\n this.regC = this.regH;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x4D (MOV C,L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVCL = function()\n{\n this.regC = this.regL;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x4E (MOV C,M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVCM = function()\n{\n this.regC = this.getByte(this.getHL());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x4F (MOV C,A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVCA = function()\n{\n this.regC = this.regA;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x50 (MOV D,B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVDB = function()\n{\n this.regD = this.regB;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x51 (MOV D,C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVDC = function()\n{\n this.regD = this.regC;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x52 (MOV D,D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVDD = function()\n{\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x53 (MOV D,E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVDE = function()\n{\n this.regD = this.regE;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x54 (MOV D,H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVDH = function()\n{\n this.regD = this.regH;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x55 (MOV D,L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVDL = function()\n{\n this.regD = this.regL;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x56 (MOV D,M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVDM = function()\n{\n this.regD = this.getByte(this.getHL());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x57 (MOV D,A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVDA = function()\n{\n this.regD = this.regA;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x58 (MOV E,B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVEB = function()\n{\n this.regE = this.regB;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x59 (MOV E,C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVEC = function()\n{\n this.regE = this.regC;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x5A (MOV E,D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVED = function()\n{\n this.regE = this.regD;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x5B (MOV E,E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVEE = function()\n{\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x5C (MOV E,H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVEH = function()\n{\n this.regE = this.regH;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x5D (MOV E,L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVEL = function()\n{\n this.regE = this.regL;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x5E (MOV E,M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVEM = function()\n{\n this.regE = this.getByte(this.getHL());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x5F (MOV E,A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVEA = function()\n{\n this.regE = this.regA;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x60 (MOV H,B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVHB = function()\n{\n this.regH = this.regB;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x61 (MOV H,C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVHC = function()\n{\n this.regH = this.regC;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x62 (MOV H,D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVHD = function()\n{\n this.regH = this.regD;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x63 (MOV H,E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVHE = function()\n{\n this.regH = this.regE;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x64 (MOV H,H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVHH = function()\n{\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x65 (MOV H,L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVHL = function()\n{\n this.regH = this.regL;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x66 (MOV H,M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVHM = function()\n{\n this.regH = this.getByte(this.getHL());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x67 (MOV H,A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVHA = function()\n{\n this.regH = this.regA;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x68 (MOV L,B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVLB = function()\n{\n this.regL = this.regB;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x69 (MOV L,C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVLC = function()\n{\n this.regL = this.regC;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x6A (MOV L,D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVLD = function()\n{\n this.regL = this.regD;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x6B (MOV L,E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVLE = function()\n{\n this.regL = this.regE;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x6C (MOV L,H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVLH = function()\n{\n this.regL = this.regH;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x6D (MOV L,L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVLL = function()\n{\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x6E (MOV L,M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVLM = function()\n{\n this.regL = this.getByte(this.getHL());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x6F (MOV L,A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVLA = function()\n{\n this.regL = this.regA;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x70 (MOV M,B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVMB = function()\n{\n this.setByte(this.getHL(), this.regB);\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x71 (MOV M,C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVMC = function()\n{\n this.setByte(this.getHL(), this.regC);\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x72 (MOV M,D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVMD = function()\n{\n this.setByte(this.getHL(), this.regD);\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x73 (MOV M,E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVME = function()\n{\n this.setByte(this.getHL(), this.regE);\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x74 (MOV M,H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVMH = function()\n{\n this.setByte(this.getHL(), this.regH);\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x75 (MOV M,L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVML = function()\n{\n this.setByte(this.getHL(), this.regL);\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x76 (HLT)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opHLT = function()\n{\n var addr = this.getPC() - 1;\n\n /*\n * If any HLT check functions are installed, call them, and if any of them return true, then\n * immediately stop HLT processing.\n */\n if (this.afnHalt.length) {\n for (var i = 0; i < this.afnHalt.length; i++) {\n if (this.afnHalt[i](addr)) return;\n }\n }\n\n this.nStepCycles -= 7;\n\n /*\n * The CPU is never REALLY halted by a HLT instruction; instead, we call requestHALT(), which\n * signals to stepCPU() that it should end the current burst AND that it should not execute any\n * more instructions until checkINTR() indicates a hardware interrupt has been requested.\n */\n this.requestHALT();\n\n /*\n * If a Debugger is present and the HALT message category is enabled, then we REALLY halt the CPU,\n * on the theory that whoever's using the Debugger would like to see HLTs.\n */\n if (DEBUGGER && this.dbg && this.messageEnabled(Messages8080.HALT)) {\n this.setPC(addr); // this is purely for the Debugger's benefit, to show the HLT\n this.dbg.stopCPU();\n return;\n }\n\n /*\n * We also REALLY halt the machine if interrupts have been disabled, since that means it's dead\n * in the water (we have no NMI generation mechanism at the moment).\n */\n if (!this.getIF()) {\n if (DEBUGGER && this.dbg) this.setPC(addr);\n this.stopCPU();\n }\n};\n\n/**\n * op=0x77 (MOV M,A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVMA = function()\n{\n this.setByte(this.getHL(), this.regA);\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x78 (MOV A,B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVAB = function()\n{\n this.regA = this.regB;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x79 (MOV A,C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVAC = function()\n{\n this.regA = this.regC;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x7A (MOV A,D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVAD = function()\n{\n this.regA = this.regD;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x7B (MOV A,E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVAE = function()\n{\n this.regA = this.regE;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x7C (MOV A,H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVAH = function()\n{\n this.regA = this.regH;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x7D (MOV A,L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVAL = function()\n{\n this.regA = this.regL;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x7E (MOV A,M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVAM = function()\n{\n this.regA = this.getByte(this.getHL());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x7F (MOV A,A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVAA = function()\n{\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x80 (ADD B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADDB = function()\n{\n this.regA = this.addByte(this.regB);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x81 (ADD C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADDC = function()\n{\n this.regA = this.addByte(this.regC);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x82 (ADD D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADDD = function()\n{\n this.regA = this.addByte(this.regD);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x83 (ADD E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADDE = function()\n{\n this.regA = this.addByte(this.regE);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x84 (ADD H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADDH = function()\n{\n this.regA = this.addByte(this.regH);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x85 (ADD L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADDL = function()\n{\n this.regA = this.addByte(this.regL);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x86 (ADD M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADDM = function()\n{\n this.regA = this.addByte(this.getByte(this.getHL()));\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x87 (ADD A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADDA = function()\n{\n this.regA = this.addByte(this.regA);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x88 (ADC B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADCB = function()\n{\n this.regA = this.addByteCarry(this.regB);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x89 (ADC C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADCC = function()\n{\n this.regA = this.addByteCarry(this.regC);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x8A (ADC D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADCD = function()\n{\n this.regA = this.addByteCarry(this.regD);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x8B (ADC E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADCE = function()\n{\n this.regA = this.addByteCarry(this.regE);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x8C (ADC H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADCH = function()\n{\n this.regA = this.addByteCarry(this.regH);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x8D (ADC L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADCL = function()\n{\n this.regA = this.addByteCarry(this.regL);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x8E (ADC M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADCM = function()\n{\n this.regA = this.addByteCarry(this.getByte(this.getHL()));\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x8F (ADC A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADCA = function()\n{\n this.regA = this.addByteCarry(this.regA);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x90 (SUB B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSUBB = function()\n{\n this.regA = this.subByte(this.regB);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x91 (SUB C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSUBC = function()\n{\n this.regA = this.subByte(this.regC);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x92 (SUB D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSUBD = function()\n{\n this.regA = this.subByte(this.regD);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x93 (SUB E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSUBE = function()\n{\n this.regA = this.subByte(this.regE);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x94 (SUB H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSUBH = function()\n{\n this.regA = this.subByte(this.regH);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x95 (SUB L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSUBL = function()\n{\n this.regA = this.subByte(this.regL);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x96 (SUB M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSUBM = function()\n{\n this.regA = this.subByte(this.getByte(this.getHL()));\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x97 (SUB A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSUBA = function()\n{\n this.regA = this.subByte(this.regA);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x98 (SBB B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSBBB = function()\n{\n this.regA = this.subByteBorrow(this.regB);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x99 (SBB C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSBBC = function()\n{\n this.regA = this.subByteBorrow(this.regC);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x9A (SBB D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSBBD = function()\n{\n this.regA = this.subByteBorrow(this.regD);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x9B (SBB E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSBBE = function()\n{\n this.regA = this.subByteBorrow(this.regE);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x9C (SBB H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSBBH = function()\n{\n this.regA = this.subByteBorrow(this.regH);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x9D (SBB L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSBBL = function()\n{\n this.regA = this.subByteBorrow(this.regL);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x9E (SBB M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSBBM = function()\n{\n this.regA = this.subByteBorrow(this.getByte(this.getHL()));\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x9F (SBB A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSBBA = function()\n{\n this.regA = this.subByteBorrow(this.regA);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xA0 (ANA B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opANAB = function()\n{\n this.regA = this.andByte(this.regB);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xA1 (ANA C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opANAC = function()\n{\n this.regA = this.andByte(this.regC);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xA2 (ANA D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opANAD = function()\n{\n this.regA = this.andByte(this.regD);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xA3 (ANA E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opANAE = function()\n{\n this.regA = this.andByte(this.regE);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xA4 (ANA H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opANAH = function()\n{\n this.regA = this.andByte(this.regH);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xA5 (ANA L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opANAL = function()\n{\n this.regA = this.andByte(this.regL);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xA6 (ANA M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opANAM = function()\n{\n this.regA = this.andByte(this.getByte(this.getHL()));\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xA7 (ANA A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opANAA = function()\n{\n this.regA = this.andByte(this.regA);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xA8 (XRA B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXRAB = function()\n{\n this.regA = this.xorByte(this.regB);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xA9 (XRA C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXRAC = function()\n{\n this.regA = this.xorByte(this.regC);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xAA (XRA D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXRAD = function()\n{\n this.regA = this.xorByte(this.regD);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xAB (XRA E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXRAE = function()\n{\n this.regA = this.xorByte(this.regE);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xAC (XRA H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXRAH = function()\n{\n this.regA = this.xorByte(this.regH);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xAD (XRA L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXRAL = function()\n{\n this.regA = this.xorByte(this.regL);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xAE (XRA M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXRAM = function()\n{\n this.regA = this.xorByte(this.getByte(this.getHL()));\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xAF (XRA A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXRAA = function()\n{\n this.regA = this.xorByte(this.regA);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xB0 (ORA B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opORAB = function()\n{\n this.regA = this.orByte(this.regB);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xB1 (ORA C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opORAC = function()\n{\n this.regA = this.orByte(this.regC);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xB2 (ORA D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opORAD = function()\n{\n this.regA = this.orByte(this.regD);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xB3 (ORA E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opORAE = function()\n{\n this.regA = this.orByte(this.regE);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xB4 (ORA H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opORAH = function()\n{\n this.regA = this.orByte(this.regH);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xB5 (ORA L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opORAL = function()\n{\n this.regA = this.orByte(this.regL);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xB6 (ORA M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opORAM = function()\n{\n this.regA = this.orByte(this.getByte(this.getHL()));\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xB7 (ORA A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opORAA = function()\n{\n this.regA = this.orByte(this.regA);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xB8 (CMP B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCMPB = function()\n{\n this.subByte(this.regB);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xB9 (CMP C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCMPC = function()\n{\n this.subByte(this.regC);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xBA (CMP D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCMPD = function()\n{\n this.subByte(this.regD);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xBB (CMP E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCMPE = function()\n{\n this.subByte(this.regE);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xBC (CMP H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCMPH = function()\n{\n this.subByte(this.regH);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xBD (CMP L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCMPL = function()\n{\n this.subByte(this.regL);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xBE (CMP M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCMPM = function()\n{\n this.subByte(this.getByte(this.getHL()));\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xBF (CMP A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCMPA = function()\n{\n this.subByte(this.regA);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xC0 (RNZ)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRNZ = function()\n{\n if (!this.getZF()) {\n this.setPC(this.popWord());\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xC1 (POP B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opPOPB = function()\n{\n this.setBC(this.popWord());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xC2 (JNZ a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opJNZ = function()\n{\n var w = this.getPCWord();\n if (!this.getZF()) this.setPC(w);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xC3 (JMP a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opJMP = function()\n{\n this.setPC(this.getPCWord());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xC4 (CNZ a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCNZ = function()\n{\n var w = this.getPCWord();\n if (!this.getZF()) {\n this.pushWord(this.getPC());\n this.setPC(w);\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xC5 (PUSH B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opPUSHB = function()\n{\n this.pushWord(this.getBC());\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xC6 (ADI d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADI = function()\n{\n this.regA = this.addByte(this.getPCByte());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xC7 (RST 0)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRST0 = function()\n{\n this.pushWord(this.getPC());\n this.setPC(0);\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xC8 (RZ)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRZ = function()\n{\n if (this.getZF()) {\n this.setPC(this.popWord());\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xC9 (RET)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRET = function()\n{\n this.setPC(this.popWord());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xCA (JZ a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opJZ = function()\n{\n var w = this.getPCWord();\n if (this.getZF()) this.setPC(w);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xCC (CZ a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCZ = function()\n{\n var w = this.getPCWord();\n if (this.getZF()) {\n this.pushWord(this.getPC());\n this.setPC(w);\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xCD (CALL a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCALL = function()\n{\n var w = this.getPCWord();\n this.pushWord(this.getPC());\n this.setPC(w);\n this.nStepCycles -= 17;\n};\n\n/**\n * op=0xCE (ACI d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opACI = function()\n{\n this.regA = this.addByteCarry(this.getPCByte());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xCF (RST 1)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRST1 = function()\n{\n this.pushWord(this.getPC());\n this.setPC(0x08);\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xD0 (RNC)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRNC = function()\n{\n if (!this.getCF()) {\n this.setPC(this.popWord());\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xD1 (POP D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opPOPD = function()\n{\n this.setDE(this.popWord());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xD2 (JNC a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opJNC = function()\n{\n var w = this.getPCWord();\n if (!this.getCF()) this.setPC(w);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xD3 (OUT d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opOUT = function()\n{\n var port = this.getPCByte();\n this.bus.checkPortOutputNotify(port, 1, this.regA, this.offPC(-2));\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xD4 (CNC a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCNC = function()\n{\n var w = this.getPCWord();\n if (!this.getCF()) {\n this.pushWord(this.getPC());\n this.setPC(w);\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xD5 (PUSH D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opPUSHD = function()\n{\n this.pushWord(this.getDE());\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xD6 (SUI d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSUI = function()\n{\n this.regA = this.subByte(this.getPCByte());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xD7 (RST 2)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRST2 = function()\n{\n this.pushWord(this.getPC());\n this.setPC(0x10);\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xD8 (RC)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRC = function()\n{\n if (this.getCF()) {\n this.setPC(this.popWord());\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xDA (JC a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opJC = function()\n{\n var w = this.getPCWord();\n if (this.getCF()) this.setPC(w);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xDB (IN d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opIN = function()\n{\n var port = this.getPCByte();\n this.regA = this.bus.checkPortInputNotify(port, 1, this.offPC(-2)) & 0xff;\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xDC (CC a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCC = function()\n{\n var w = this.getPCWord();\n if (this.getCF()) {\n this.pushWord(this.getPC());\n this.setPC(w);\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xDE (SBI d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSBI = function()\n{\n this.regA = this.subByteBorrow(this.getPCByte());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xDF (RST 3)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRST3 = function()\n{\n this.pushWord(this.getPC());\n this.setPC(0x18);\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xE0 (RPO)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRPO = function()\n{\n if (!this.getPF()) {\n this.setPC(this.popWord());\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xE1 (POP H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opPOPH = function()\n{\n this.setHL(this.popWord());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xE2 (JPO a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opJPO = function()\n{\n var w = this.getPCWord();\n if (!this.getPF()) this.setPC(w);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xE3 (XTHL)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXTHL = function()\n{\n var w = this.popWord();\n this.pushWord(this.getHL());\n this.setHL(w);\n this.nStepCycles -= 18;\n};\n\n/**\n * op=0xE4 (CPO a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCPO = function()\n{\n var w = this.getPCWord();\n if (!this.getPF()) {\n this.pushWord(this.getPC());\n this.setPC(w);\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xE5 (PUSH H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opPUSHH = function()\n{\n this.pushWord(this.getHL());\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xE6 (ANI d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opANI = function()\n{\n this.regA = this.andByte(this.getPCByte());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xE7 (RST 4)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRST4 = function()\n{\n this.pushWord(this.getPC());\n this.setPC(0x20);\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xE8 (RPE)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRPE = function()\n{\n if (this.getPF()) {\n this.setPC(this.popWord());\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xE9 (PCHL)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opPCHL = function()\n{\n this.setPC(this.getHL());\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xEA (JPE a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opJPE = function()\n{\n var w = this.getPCWord();\n if (this.getPF()) this.setPC(w);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xEB (XCHG)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXCHG = function()\n{\n var w = this.getHL();\n this.setHL(this.getDE());\n this.setDE(w);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xEC (CPE a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCPE = function()\n{\n var w = this.getPCWord();\n if (this.getPF()) {\n this.pushWord(this.getPC());\n this.setPC(w);\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xEE (XRI d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXRI = function()\n{\n this.regA = this.xorByte(this.getPCByte());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xEF (RST 5)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRST5 = function()\n{\n this.pushWord(this.getPC());\n this.setPC(0x28);\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xF0 (RP)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRP = function()\n{\n if (!this.getSF()) {\n this.setPC(this.popWord());\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xF1 (POP PSW)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opPOPSW = function()\n{\n this.setPSW(this.popWord());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xF2 (JP a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opJP = function()\n{\n var w = this.getPCWord();\n if (!this.getSF()) this.setPC(w);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xF3 (DI)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDI = function()\n{\n this.clearIF();\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xF4 (CP a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCP = function()\n{\n var w = this.getPCWord();\n if (!this.getSF()) {\n this.pushWord(this.getPC());\n this.setPC(w);\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xF5 (PUSH PSW)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opPUPSW = function()\n{\n this.pushWord(this.getPSW());\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xF6 (ORI d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opORI = function()\n{\n this.regA = this.orByte(this.getPCByte());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xF7 (RST 6)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRST6 = function()\n{\n this.pushWord(this.getPC());\n this.setPC(0x30);\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xF8 (RM)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRM = function()\n{\n if (this.getSF()) {\n this.setPC(this.popWord());\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xF9 (SPHL)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSPHL = function()\n{\n this.setSP(this.getHL());\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xFA (JM a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opJM = function()\n{\n var w = this.getPCWord();\n if (this.getSF()) this.setPC(w);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xFB (EI)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opEI = function()\n{\n this.setIF();\n this.nStepCycles -= 4;\n this.checkINTR();\n};\n\n/**\n * op=0xFC (CM a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCM = function()\n{\n var w = this.getPCWord();\n if (this.getSF()) {\n this.pushWord(this.getPC());\n this.setPC(w);\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xFE (CPI d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCPI = function()\n{\n this.subByte(this.getPCByte());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xFF (RST 7)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRST7 = function()\n{\n this.pushWord(this.getPC());\n this.setPC(0x38);\n this.nStepCycles -= 11;\n};\n\n/*\n * This 256-entry array of opcode functions is at the heart of the CPU engine: stepCPU(n).\n *\n * It might be worth trying a switch() statement instead, to see how the performance compares,\n * but I suspect that would vary quite a bit across JavaScript engines; for now, I'm putting my\n * money on array lookup.\n */\nCPUDef8080.aOps8080 = [\n /* 0x00-0x03 */ CPUDef8080.opNOP, CPUDef8080.opLXIB, CPUDef8080.opSTAXB, CPUDef8080.opINXB,\n /* 0x04-0x07 */ CPUDef8080.opINRB, CPUDef8080.opDCRB, CPUDef8080.opMVIB, CPUDef8080.opRLC,\n /* 0x08-0x0B */ CPUDef8080.opNOP, CPUDef8080.opDADB, CPUDef8080.opLDAXB, CPUDef8080.opDCXB,\n /* 0x0C-0x0F */ CPUDef8080.opINRC, CPUDef8080.opDCRC, CPUDef8080.opMVIC, CPUDef8080.opRRC,\n /* 0x10-0x13 */ CPUDef8080.opNOP, CPUDef8080.opLXID, CPUDef8080.opSTAXD, CPUDef8080.opINXD,\n /* 0x14-0x17 */ CPUDef8080.opINRD, CPUDef8080.opDCRD, CPUDef8080.opMVID, CPUDef8080.opRAL,\n /* 0x18-0x1B */ CPUDef8080.opNOP, CPUDef8080.opDADD, CPUDef8080.opLDAXD, CPUDef8080.opDCXD,\n /* 0x1C-0x1F */ CPUDef8080.opINRE, CPUDef8080.opDCRE, CPUDef8080.opMVIE, CPUDef8080.opRAR,\n /* 0x20-0x23 */ CPUDef8080.opNOP, CPUDef8080.opLXIH, CPUDef8080.opSHLD, CPUDef8080.opINXH,\n /* 0x24-0x27 */ CPUDef8080.opINRH, CPUDef8080.opDCRH, CPUDef8080.opMVIH, CPUDef8080.opDAA,\n /* 0x28-0x2B */ CPUDef8080.opNOP, CPUDef8080.opDADH, CPUDef8080.opLHLD, CPUDef8080.opDCXH,\n /* 0x2C-0x2F */ CPUDef8080.opINRL, CPUDef8080.opDCRL, CPUDef8080.opMVIL, CPUDef8080.opCMA,\n /* 0x30-0x33 */ CPUDef8080.opNOP, CPUDef8080.opLXISP, CPUDef8080.opSTA, CPUDef8080.opINXSP,\n /* 0x34-0x37 */ CPUDef8080.opINRM, CPUDef8080.opDCRM, CPUDef8080.opMVIM, CPUDef8080.opSTC,\n /* 0x38-0x3B */ CPUDef8080.opNOP, CPUDef8080.opDADSP, CPUDef8080.opLDA, CPUDef8080.opDCXSP,\n /* 0x3C-0x3F */ CPUDef8080.opINRA, CPUDef8080.opDCRA, CPUDef8080.opMVIA, CPUDef8080.opCMC,\n /* 0x40-0x43 */ CPUDef8080.opMOVBB, CPUDef8080.opMOVBC, CPUDef8080.opMOVBD, CPUDef8080.opMOVBE,\n /* 0x44-0x47 */ CPUDef8080.opMOVBH, CPUDef8080.opMOVBL, CPUDef8080.opMOVBM, CPUDef8080.opMOVBA,\n /* 0x48-0x4B */ CPUDef8080.opMOVCB, CPUDef8080.opMOVCC, CPUDef8080.opMOVCD, CPUDef8080.opMOVCE,\n /* 0x4C-0x4F */ CPUDef8080.opMOVCH, CPUDef8080.opMOVCL, CPUDef8080.opMOVCM, CPUDef8080.opMOVCA,\n /* 0x50-0x53 */ CPUDef8080.opMOVDB, CPUDef8080.opMOVDC, CPUDef8080.opMOVDD, CPUDef8080.opMOVDE,\n /* 0x54-0x57 */ CPUDef8080.opMOVDH, CPUDef8080.opMOVDL, CPUDef8080.opMOVDM, CPUDef8080.opMOVDA,\n /* 0x58-0x5B */ CPUDef8080.opMOVEB, CPUDef8080.opMOVEC, CPUDef8080.opMOVED, CPUDef8080.opMOVEE,\n /* 0x5C-0x5F */ CPUDef8080.opMOVEH, CPUDef8080.opMOVEL, CPUDef8080.opMOVEM, CPUDef8080.opMOVEA,\n /* 0x60-0x63 */ CPUDef8080.opMOVHB, CPUDef8080.opMOVHC, CPUDef8080.opMOVHD, CPUDef8080.opMOVHE,\n /* 0x64-0x67 */ CPUDef8080.opMOVHH, CPUDef8080.opMOVHL, CPUDef8080.opMOVHM, CPUDef8080.opMOVHA,\n /* 0x68-0x6B */ CPUDef8080.opMOVLB, CPUDef8080.opMOVLC, CPUDef8080.opMOVLD, CPUDef8080.opMOVLE,\n /* 0x6C-0x6F */ CPUDef8080.opMOVLH, CPUDef8080.opMOVLL, CPUDef8080.opMOVLM, CPUDef8080.opMOVLA,\n /* 0x70-0x73 */ CPUDef8080.opMOVMB, CPUDef8080.opMOVMC, CPUDef8080.opMOVMD, CPUDef8080.opMOVME,\n /* 0x74-0x77 */ CPUDef8080.opMOVMH, CPUDef8080.opMOVML, CPUDef8080.opHLT, CPUDef8080.opMOVMA,\n /* 0x78-0x7B */ CPUDef8080.opMOVAB, CPUDef8080.opMOVAC, CPUDef8080.opMOVAD, CPUDef8080.opMOVAE,\n /* 0x7C-0x7F */ CPUDef8080.opMOVAH, CPUDef8080.opMOVAL, CPUDef8080.opMOVAM, CPUDef8080.opMOVAA,\n /* 0x80-0x83 */ CPUDef8080.opADDB, CPUDef8080.opADDC, CPUDef8080.opADDD, CPUDef8080.opADDE,\n /* 0x84-0x87 */ CPUDef8080.opADDH, CPUDef8080.opADDL, CPUDef8080.opADDM, CPUDef8080.opADDA,\n /* 0x88-0x8B */ CPUDef8080.opADCB, CPUDef8080.opADCC, CPUDef8080.opADCD, CPUDef8080.opADCE,\n /* 0x8C-0x8F */ CPUDef8080.opADCH, CPUDef8080.opADCL, CPUDef8080.opADCM, CPUDef8080.opADCA,\n /* 0x90-0x93 */ CPUDef8080.opSUBB, CPUDef8080.opSUBC, CPUDef8080.opSUBD, CPUDef8080.opSUBE,\n /* 0x94-0x97 */ CPUDef8080.opSUBH, CPUDef8080.opSUBL, CPUDef8080.opSUBM, CPUDef8080.opSUBA,\n /* 0x98-0x9B */ CPUDef8080.opSBBB, CPUDef8080.opSBBC, CPUDef8080.opSBBD, CPUDef8080.opSBBE,\n /* 0x9C-0x9F */ CPUDef8080.opSBBH, CPUDef8080.opSBBL, CPUDef8080.opSBBM, CPUDef8080.opSBBA,\n /* 0xA0-0xA3 */ CPUDef8080.opANAB, CPUDef8080.opANAC, CPUDef8080.opANAD, CPUDef8080.opANAE,\n /* 0xA4-0xA7 */ CPUDef8080.opANAH, CPUDef8080.opANAL, CPUDef8080.opANAM, CPUDef8080.opANAA,\n /* 0xA8-0xAB */ CPUDef8080.opXRAB, CPUDef8080.opXRAC, CPUDef8080.opXRAD, CPUDef8080.opXRAE,\n /* 0xAC-0xAF */ CPUDef8080.opXRAH, CPUDef8080.opXRAL, CPUDef8080.opXRAM, CPUDef8080.opXRAA,\n /* 0xB0-0xB3 */ CPUDef8080.opORAB, CPUDef8080.opORAC, CPUDef8080.opORAD, CPUDef8080.opORAE,\n /* 0xB4-0xB7 */ CPUDef8080.opORAH, CPUDef8080.opORAL, CPUDef8080.opORAM, CPUDef8080.opORAA,\n /* 0xB8-0xBB */ CPUDef8080.opCMPB, CPUDef8080.opCMPC, CPUDef8080.opCMPD, CPUDef8080.opCMPE,\n /* 0xBC-0xBF */ CPUDef8080.opCMPH, CPUDef8080.opCMPL, CPUDef8080.opCMPM, CPUDef8080.opCMPA,\n /* 0xC0-0xC3 */ CPUDef8080.opRNZ, CPUDef8080.opPOPB, CPUDef8080.opJNZ, CPUDef8080.opJMP,\n /* 0xC4-0xC7 */ CPUDef8080.opCNZ, CPUDef8080.opPUSHB, CPUDef8080.opADI, CPUDef8080.opRST0,\n /* 0xC8-0xCB */ CPUDef8080.opRZ, CPUDef8080.opRET, CPUDef8080.opJZ, CPUDef8080.opJMP,\n /* 0xCC-0xCF */ CPUDef8080.opCZ, CPUDef8080.opCALL, CPUDef8080.opACI, CPUDef8080.opRST1,\n /* 0xD0-0xD3 */ CPUDef8080.opRNC, CPUDef8080.opPOPD, CPUDef8080.opJNC, CPUDef8080.opOUT,\n /* 0xD4-0xD7 */ CPUDef8080.opCNC, CPUDef8080.opPUSHD, CPUDef8080.opSUI, CPUDef8080.opRST2,\n /* 0xD8-0xDB */ CPUDef8080.opRC, CPUDef8080.opRET, CPUDef8080.opJC, CPUDef8080.opIN,\n /* 0xDC-0xDF */ CPUDef8080.opCC, CPUDef8080.opCALL, CPUDef8080.opSBI, CPUDef8080.opRST3,\n /* 0xE0-0xE3 */ CPUDef8080.opRPO, CPUDef8080.opPOPH, CPUDef8080.opJPO, CPUDef8080.opXTHL,\n /* 0xE4-0xE7 */ CPUDef8080.opCPO, CPUDef8080.opPUSHH, CPUDef8080.opANI, CPUDef8080.opRST4,\n /* 0xE8-0xEB */ CPUDef8080.opRPE, CPUDef8080.opPCHL, CPUDef8080.opJPE, CPUDef8080.opXCHG,\n /* 0xEC-0xEF */ CPUDef8080.opCPE, CPUDef8080.opCALL, CPUDef8080.opXRI, CPUDef8080.opRST5,\n /* 0xF0-0xF3 */ CPUDef8080.opRP, CPUDef8080.opPOPSW, CPUDef8080.opJP, CPUDef8080.opDI,\n /* 0xF4-0xF7 */ CPUDef8080.opCP, CPUDef8080.opPUPSW, CPUDef8080.opORI, CPUDef8080.opRST6,\n /* 0xF8-0xFB */ CPUDef8080.opRM, CPUDef8080.opSPHL, CPUDef8080.opJM, CPUDef8080.opEI,\n /* 0xFC-0xFF */ CPUDef8080.opCM, CPUDef8080.opCALL, CPUDef8080.opCPI, CPUDef8080.opRST7\n];\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/chipset.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass ChipSet8080 extends Component {\n /**\n * ChipSet8080(parmsChipSet)\n *\n * The ChipSet8080 component has the following component-specific (parmsChipSet) properties:\n *\n * model: eg, \"SI1978\" (should be a member of ChipSet8080.MODELS)\n * swDIP: eg, \"00000000\", where swDIP[0] is DIP0, swDIP[1] is DIP1, etc.\n *\n * @this {ChipSet8080}\n * @param {Object} parmsChipSet\n */\n constructor(parmsChipSet)\n {\n super(\"ChipSet\", parmsChipSet, Messages8080.CHIPSET);\n\n var model = parmsChipSet['model'];\n\n if (model && !ChipSet8080.MODELS[model]) {\n Component.notice(\"Unrecognized ChipSet model: \" + model);\n }\n\n this.config = ChipSet8080.MODELS[model] || {};\n\n this.bSwitches = this.parseDIPSwitches(parmsChipSet['swDIP']);\n\n /*\n * Here, I'm finally getting around to trying the Web Audio API. Fortunately, based on what little I know about\n * sound generation, using the API to make the same noises as the IBM PC speaker seems straightforward.\n *\n * To start, we create an audio context, unless the 'sound' parameter has been explicitly set to false.\n *\n * From:\n *\n * http://developer.apple.com/library/safari/#documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/PlayingandSynthesizingSounds/PlayingandSynthesizingSounds.html\n *\n * \"Similar to how HTML5 canvas requires a context on which lines and curves are drawn, Web Audio requires an audio context\n * on which sounds are played and manipulated. This context will be the parent object of further audio objects to come....\n * Your audio context is typically created when your page initializes and should be long-lived. You can play multiple sounds\n * coming from multiple sources within the same context, so it is unnecessary to create more than one audio context per page.\"\n */\n this.fSpeaker = false;\n if (parmsChipSet['sound']) {\n this.classAudio = this.contextAudio = null;\n if (window) {\n this.classAudio = window['AudioContext'] || window['webkitAudioContext'];\n }\n if (this.classAudio) {\n this.contextAudio = new this.classAudio();\n } else {\n if (DEBUG) this.log(\"AudioContext not available\");\n }\n }\n\n this.setReady();\n }\n\n /**\n * parseDIPSwitches(sBits, bDefault)\n *\n * @this {ChipSet8080}\n * @param {string} sBits describing switch settings\n * @param {number} [bDefault]\n * @return {number|undefined}\n */\n parseDIPSwitches(sBits, bDefault)\n {\n var b = bDefault;\n if (sBits) {\n /*\n * NOTE: We can't use parseInt() with a base of 2, because both bit order and bit sense are reversed.\n */\n b = 0;\n var bit = 0x1;\n for (var i = 0; i < sBits.length; i++) {\n if (sBits.charAt(i) == \"0\") b |= bit;\n bit <<= 1;\n }\n }\n return b;\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {ChipSet8080}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"sw1\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {ChipSet8080}\n * @param {Computer8080} cmp\n * @param {Bus8080} bus\n * @param {CPUState8080} cpu\n * @param {Debugger8080} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.cmp = cmp;\n this.kbd = /** @type {Keyboard8080} */ (cmp.getMachineComponent(\"Keyboard\"));\n this.serial = /** @type {SerialPort8080} */ (cmp.getMachineComponent(\"SerialPort\"));\n this.video = /** @type {Video8080} */ (cmp.getMachineComponent(\"Video\"));\n bus.addPortInputTable(this, this.config.portsInput);\n bus.addPortOutputTable(this, this.config.portsOutput);\n\n if (DEBUGGER) {\n if (dbg) {\n var chipset = this;\n dbg.messageDump(Messages8080.NVR, function onDumpNVR() {\n chipset.dumpNVR();\n });\n }\n }\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {ChipSet8080}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {ChipSet8080}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * dumpNVR()\n *\n * @this {ChipSet8080}\n */\n dumpNVR()\n {\n if (DEBUGGER) {\n var sDump = \"\";\n for (var iWord = 0; iWord < this.aNVRWords.length; iWord++) {\n if (sDump) {\n sDump += (iWord && (iWord % 10)? \", \" : \",\\n\");\n }\n sDump += Str.toHexWord(this.aNVRWords[iWord]);\n }\n this.dbg.println(sDump);\n }\n }\n\n /**\n * reset()\n *\n * @this {ChipSet8080}\n */\n reset()\n {\n if (this.config.INIT && !this.restore(this.config.INIT)) {\n this.notice(\"reset error\");\n }\n }\n\n /**\n * save()\n *\n * This implements save support for the ChipSet component.\n *\n * @this {ChipSet8080}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n switch(this.config.MODEL) {\n case ChipSet8080.SI1978.MODEL:\n state.set(0, [this.bStatus0, this.bStatus1, this.bStatus2, this.wShiftData, this.bShiftCount, this.bSound1, this.bSound2]);\n break;\n case ChipSet8080.VT100.MODEL:\n state.set(0, [this.bBrightness, this.bFlags]);\n state.set(1, [this.bDC011Cols, this.bDC011Rate]);\n state.set(2, [this.bDC012Scroll, this.bDC012Blink, this.bDC012Reverse, this.bDC012Attr]);\n state.set(3, [this.dNVRAddr, this.wNVRData, this.bNVRLatch, this.bNVROut, this.aNVRWords]);\n break;\n }\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the ChipSet component.\n *\n * @this {ChipSet8080}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var a;\n if (data && (a = data[0]) && a.length) {\n switch(this.config.MODEL) {\n case ChipSet8080.SI1978.MODEL:\n this.bStatus0 = a[0];\n this.bStatus1 = a[1];\n this.bStatus2 = a[2];\n this.wShiftData = a[3];\n this.bShiftCount = a[4];\n this.bSound1 = a[5];\n this.bSound2 = a[6];\n return true;\n case ChipSet8080.VT100.MODEL:\n this.bBrightness = a[0];\n this.bFlags = a[1];\n a = data[1];\n this.bDC011Cols = a[0];\n this.bDC011Rate = a[1];\n a = data[2];\n this.bDC012Scroll = a[0];\n this.bDC012Blink = a[1];\n this.bDC012Reverse = a[2];\n this.bDC012Attr = a[3];\n a = data[3];\n this.dNVRAddr = a[0]; // 20-bit address\n this.wNVRData = a[1]; // 14-bit word\n this.bNVRLatch = a[2]; // 1 byte\n this.bNVROut = a[3]; // 1 bit\n this.aNVRWords = a[4]; // 100 14-bit words\n return true;\n }\n }\n return false;\n }\n\n /**\n * start()\n *\n * Notification from the CPU that it's starting.\n *\n * @this {ChipSet8080}\n */\n start()\n {\n /*\n * Currently, all we (may) do with this notification is allow the speaker to make noise.\n */\n }\n\n /**\n * stop()\n *\n * Notification from the CPU that it's stopping.\n *\n * @this {ChipSet8080}\n */\n stop()\n {\n /*\n * Currently, all we (may) do with this notification is prevent the speaker from making noise.\n */\n }\n\n /**\n * updateStatus0(bit, fSet)\n *\n * @this {ChipSet8080}\n * @param {number} bit\n * @param {boolean} fSet\n */\n updateStatus0(bit, fSet)\n {\n this.bStatus0 &= ~bit;\n if (fSet) this.bStatus0 |= bit;\n }\n\n /**\n * updateStatus1(bit, fSet)\n *\n * @this {ChipSet8080}\n * @param {number} bit\n * @param {boolean} fSet\n */\n updateStatus1(bit, fSet)\n {\n this.bStatus1 &= ~bit;\n if (fSet) this.bStatus1 |= bit;\n }\n\n /**\n * updateStatus2(bit, fSet)\n *\n * @this {ChipSet8080}\n * @param {number} bit\n * @param {boolean} fSet\n */\n updateStatus2(bit, fSet)\n {\n this.bStatus2 &= ~bit;\n if (fSet) this.bStatus2 |= bit;\n }\n\n /**\n * inSIStatus0(port, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x00)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inSIStatus0(port, addrFrom)\n {\n var b = this.bStatus0;\n this.printMessageIO(port, null, addrFrom, \"STATUS0\", b, true);\n return b;\n }\n\n /**\n * inSIStatus1(port, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x01)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inSIStatus1(port, addrFrom)\n {\n var b = this.bStatus1;\n this.printMessageIO(port, null, addrFrom, \"STATUS1\", b, true);\n return b;\n }\n\n /**\n * inSIStatus2(port, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x02)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inSIStatus2(port, addrFrom)\n {\n var b = this.bStatus2;\n this.printMessageIO(port, null, addrFrom, \"STATUS2\", b, true);\n return b;\n }\n\n /**\n * inSIShiftResult(port, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x03)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inSIShiftResult(port, addrFrom)\n {\n var b = (this.wShiftData >> (8 - this.bShiftCount)) & 0xff;\n this.printMessageIO(port, null, addrFrom, \"SHIFT.RESULT\", b, true);\n return b;\n }\n\n /**\n * outSIShiftCount(port, b, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x02)\n * @param {number} b\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outSIShiftCount(port, b, addrFrom)\n {\n this.printMessageIO(port, b, addrFrom, \"SHIFT.COUNT\", null, true);\n this.bShiftCount = b;\n }\n\n /**\n * outSISound1(port, b, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x03)\n * @param {number} b\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outSISound1(port, b, addrFrom)\n {\n this.printMessageIO(port, b, addrFrom, \"SOUND1\", null, true);\n this.bSound1 = b;\n }\n\n /**\n * outSIShiftData(port, b, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x04)\n * @param {number} b\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outSIShiftData(port, b, addrFrom)\n {\n this.printMessageIO(port, b, addrFrom, \"SHIFT.DATA\", null, true);\n this.wShiftData = (b << 8) | (this.wShiftData >> 8);\n }\n\n /**\n * outSISound2(port, b, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x05)\n * @param {number} b\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outSISound2(port, b, addrFrom)\n {\n this.printMessageIO(port, b, addrFrom, \"SOUND2\", null, true);\n this.bSound2 = b;\n }\n\n /**\n * outSIWatchdog(port, b, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x06)\n * @param {number} b\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outSIWatchdog(port, b, addrFrom)\n {\n this.printMessageIO(port, b, addrFrom, \"WATCHDOG\", null, true);\n }\n\n /**\n * getVT100LBA(iBit)\n *\n * Returns the state of the requested (simulated) LBA bit.\n *\n * NOTE: This is currently only used to obtain LBA7, which we approximate with the slightly faster approach\n * of masking bit 6 of the CPU cycle count (see the DC011 discussion above). This will result in a shorter LBA7\n * period than if we divided the cycle count by 88, but a shorter LBA7 period is probably helpful in terms of\n * overall performance.\n *\n * @param {number} iBit\n * @return {number}\n */\n getVT100LBA(iBit)\n {\n return (this.cpu.getCycles() & (1 << (iBit - 1))) << 1;\n }\n\n /**\n * getNVRAddr()\n *\n * @return {number}\n */\n getNVRAddr()\n {\n var i;\n var tens = 0, ones = 0;\n var addr = ~this.dNVRAddr;\n for (i = 0; i < 10; i++) {\n if (addr & 0x1) tens = 9-i;\n addr >>= 1;\n }\n for (i = 0; i < 10; i++) {\n if (addr & 0x1) ones = 9-i;\n addr >>= 1;\n }\n addr = tens*10 + ones;\n\n return addr;\n }\n\n /**\n * doNVRCommand()\n */\n doNVRCommand()\n {\n var addr, data;\n var bit = this.bNVRLatch & 0x1;\n var bCmd = (this.bNVRLatch >> 1) & 0x7;\n\n switch(bCmd) {\n case ChipSet8080.VT100.NVR.CMD.STANDBY:\n break;\n\n case ChipSet8080.VT100.NVR.CMD.ACCEPT_ADDR:\n this.dNVRAddr = (this.dNVRAddr << 1) | bit;\n break;\n\n case ChipSet8080.VT100.NVR.CMD.ERASE:\n addr = this.getNVRAddr();\n this.aNVRWords[addr] = ChipSet8080.VT100.NVR.WORDMASK;\n this.printMessage(\"doNVRCommand(): erase data at addr \" + Str.toHexWord(addr));\n break;\n\n case ChipSet8080.VT100.NVR.CMD.ACCEPT_DATA:\n this.wNVRData = (this.wNVRData << 1) | bit;\n break;\n\n case ChipSet8080.VT100.NVR.CMD.WRITE:\n addr = this.getNVRAddr();\n data = this.wNVRData & ChipSet8080.VT100.NVR.WORDMASK;\n this.aNVRWords[addr] = data;\n this.printMessage(\"doNVRCommand(): write data \" + Str.toHexWord(data) + \" to addr \" + Str.toHexWord(addr));\n break;\n\n case ChipSet8080.VT100.NVR.CMD.READ:\n addr = this.getNVRAddr();\n data = this.aNVRWords[addr];\n /*\n * If we don't explicitly initialize aNVRWords[], pretend any uninitialized words contains WORDMASK.\n */\n if (data == null) data = ChipSet8080.VT100.NVR.WORDMASK;\n this.wNVRData = data;\n this.printMessage(\"doNVRCommand(): read data \" + Str.toHexWord(data) + \" from addr \" + Str.toHexWord(addr));\n break;\n\n case ChipSet8080.VT100.NVR.CMD.SHIFT_OUT:\n this.wNVRData <<= 1;\n /*\n * Since WORDMASK is 0x3fff, this will mask the shifted data with 0x4000, which is the bit we want to isolate.\n */\n this.bNVROut = this.wNVRData & (ChipSet8080.VT100.NVR.WORDMASK + 1);\n break;\n\n default:\n this.printMessage(\"doNVRCommand(): unrecognized command \" + Str.toHexByte(bCmd));\n break;\n }\n }\n\n /**\n * inVT100Flags(port, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x42)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inVT100Flags(port, addrFrom)\n {\n var b = this.bFlags;\n\n /*\n * The NVR_CLK bit is driven by LBA7 (ie, bit 7 from Line Buffer Address generation); see the DC011 discussion above.\n */\n b &= ~ChipSet8080.VT100.FLAGS.NVR_CLK;\n if (this.getVT100LBA(7)) {\n b |= ChipSet8080.VT100.FLAGS.NVR_CLK;\n if (b != this.bFlags) {\n this.doNVRCommand();\n }\n }\n\n b &= ~ChipSet8080.VT100.FLAGS.NVR_DATA;\n if (this.bNVROut) {\n b |= ChipSet8080.VT100.FLAGS.NVR_DATA;\n }\n\n b &= ~ChipSet8080.VT100.FLAGS.KBD_XMIT;\n if (this.kbd && this.kbd.isVT100TransmitterReady()) {\n b |= ChipSet8080.VT100.FLAGS.KBD_XMIT;\n }\n\n b &= ~ChipSet8080.VT100.FLAGS.UART_XMIT;\n if (this.serial && this.serial.isTransmitterReady()) {\n b |= ChipSet8080.VT100.FLAGS.UART_XMIT;\n }\n\n this.bFlags = b;\n this.printMessageIO(port, null, addrFrom, \"FLAGS\", b);\n return b;\n }\n\n /**\n * outVT100Brightness(port, b, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x42)\n * @param {number} b\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outVT100Brightness(port, b, addrFrom)\n {\n this.printMessageIO(port, b, addrFrom, \"BRIGHTNESS\");\n this.bBrightness = b;\n }\n\n /**\n * outVT100NVRLatch(port, b, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x62)\n * @param {number} b\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outVT100NVRLatch(port, b, addrFrom)\n {\n this.printMessageIO(port, b, addrFrom, \"NVR.LATCH\");\n this.bNVRLatch = b;\n }\n\n /**\n * outVT100DC012(port, b, addrFrom)\n *\n * TODO: Consider whether we should disable any interrupts (eg, vertical retrace) until\n * this port is initialized at runtime.\n *\n * @this {ChipSet8080}\n * @param {number} port (0xA2)\n * @param {number} b\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outVT100DC012(port, b, addrFrom)\n {\n this.printMessageIO(port, b, addrFrom, \"DC012\");\n\n var bOpt = b & 0x3;\n var bCmd = (b >> 2) & 0x3;\n switch(bCmd) {\n case 0x0:\n this.bDC012Scroll = (this.bDC012Scroll & ~0x3) | bOpt;\n break;\n case 0x1:\n this.bDC012Scroll = (this.bDC012Scroll & ~0xC) | (bOpt << 2);\n if (this.video) this.video.updateScrollOffset(this.bDC012Scroll);\n break;\n case 0x2:\n switch(bOpt) {\n case 0x0:\n this.bDC012Blink = ~this.bDC012Blink;\n break;\n case 0x1:\n // TODO: Clear vertical frequency interrupt?\n break;\n case 0x2:\n case 0x3:\n this.bDC012Reverse = 0x3 - bOpt;\n break;\n }\n break;\n case 0x3:\n this.bDC012Attr = bOpt;\n break;\n }\n }\n\n /**\n * outVT100DC011(port, b, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0xC2)\n * @param {number} b\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outVT100DC011(port, b, addrFrom)\n {\n this.printMessageIO(port, b, addrFrom, \"DC011\");\n if (b & ChipSet8080.VT100.DC011.RATE60) {\n b &= ChipSet8080.VT100.DC011.RATE50;\n if (this.bDC011Rate != b) {\n this.bDC011Rate = b;\n if (this.video) {\n this.video.updateRate(this.bDC011Rate == ChipSet8080.VT100.DC011.RATE50? 50 : 60);\n }\n }\n } else {\n b &= ChipSet8080.VT100.DC011.COLS132;\n if (this.bDC011Cols != b) {\n this.bDC011Cols = b;\n if (this.video) {\n var nCols = (this.bDC011Cols == ChipSet8080.VT100.DC011.COLS132? 132 : 80);\n var nRows = (nCols > 80 && (this.bFlags & ChipSet8080.VT100.FLAGS.NO_AVO)? 14 : 24);\n this.video.updateDimensions(nCols, nRows);\n }\n }\n }\n }\n\n /**\n * ChipSet8080.init()\n *\n * This function operates on every HTML element of class \"chipset\", extracting the\n * JSON-encoded parameters for the ChipSet constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a ChipSet component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeChipSet = Component.getElementsByClass(document, PC8080.APPCLASS, \"chipset\");\n for (var iChip = 0; iChip < aeChipSet.length; iChip++) {\n var eChipSet = aeChipSet[iChip];\n var parmsChipSet = Component.getComponentParms(eChipSet);\n var chipset = new ChipSet8080(parmsChipSet);\n Component.bindComponentControls(chipset, eChipSet, PC8080.APPCLASS);\n }\n }\n}\n\n/*\n * NOTE: The STATUS1 port could have been handled entirely by the Keyboard component, but it was just as easy\n * to create a simple ChipSet interface, updateStatus1(), that the Keyboard calls whenever it wants to simulate a\n * button press or release. It's a six-of-one, half-a-dozen-of-another choice, since technically, Space Invaders\n * doesn't have a keyboard.\n */\nChipSet8080.SI1978 = {\n MODEL: 1978.1,\n STATUS0: { // NOTE: STATUS0 not used by the SI1978 ROMs; refer to STATUS1 instead\n PORT: 0,\n DIP4: 0x01, // self-test request at power up?\n FIRE: 0x10, // 1 = fire\n LEFT: 0x20, // 1 = left\n RIGHT: 0x40, // 1 = right\n PORT7: 0x80, // some connection to (undocumented) port 7\n ALWAYS_SET: 0x0E // always set\n },\n STATUS1: {\n PORT: 1,\n CREDIT: 0x01, // credit (coin slot)\n P2: 0x02, // 1 = 2P start\n P1: 0x04, // 1 = 1P start\n P1_FIRE: 0x10, // 1 = fire (P1 fire if cocktail machine?)\n P1_LEFT: 0x20, // 1 = left (P1 left if cocktail machine?)\n P1_RIGHT: 0x40, // 1 = right (P1 right if cocktail machine?)\n ALWAYS_SET: 0x08 // always set\n },\n STATUS2: {\n PORT: 2,\n DIP3_5: 0x03, // 00 = 3 ships, 01 = 4 ships, 10 = 5 ships, 11 = 6 ships\n TILT: 0x04, // 1 = tilt detected\n DIP6: 0x08, // 0 = extra ship at 1500, 1 = extra ship at 1000\n P2_FIRE: 0x10, // 1 = P2 fire (cocktail machines only?)\n P2_LEFT: 0x20, // 1 = P2 left (cocktail machines only?)\n P2_RIGHT: 0x40, // 1 = P2 right (cocktail machines only?)\n DIP7: 0x80, // 0 = display coin info on demo (\"attract\") screen\n ALWAYS_SET: 0x00\n },\n SHIFT_RESULT: { // bits 0-7 of barrel shifter result\n PORT: 3\n },\n SHIFT_COUNT: {\n PORT: 2,\n MASK: 0x07\n },\n SOUND1: {\n PORT: 3,\n UFO: 0x01,\n SHOT: 0x02,\n PDEATH: 0x04,\n IDEATH: 0x08,\n EXPLAY: 0x10,\n AMP_ENABLE: 0x20\n },\n SHIFT_DATA: {\n PORT: 4\n },\n SOUND2: {\n PORT: 5,\n FLEET1: 0x01,\n FLEET2: 0x02,\n FLEET3: 0x04,\n FLEET4: 0x08,\n UFO_HIT: 0x10\n }\n};\n\n/*\n * One of the many chips in the VT100 is an 8224, which operates at 24.8832MHz. That frequency is divided by 9\n * to yield a 361.69ns clock period for the 8080 CPU, which means (in theory) that the CPU is running at 2.76Mhz.\n *\n * Hence the CPU component in the VT100's machine.xml should be defined as:\n *\n * <cpu id=\"cpu8080\" model=\"8080\" cycles=\"2764800\"/>\n *\n * WARNING: The choice of clock speed has an effect on other simulated VT100 circuits; see the DC011 Timing Chip\n * discussion below, along with the getVT100LBA() function.\n *\n * For reference, here is a list of all the VT100 I/O ports, from /devices/pc8080/machine/vt100/debugger/README.md,\n * which in turn comes from p. 4-17 of the VT100 Technical Manual (July 1982):\n *\n * READ OR WRITE\n * 00H PUSART data bus\n * 01H PUSART command port\n *\n * WRITE ONLY (Decoded with I/O WR L)\n * 02H Baud rate generator\n * 42H Brightness D/A latch\n * 62H NVR latch\n * 82H Keyboard UART data input [used to update the Keyboard Status Byte -JP]\n * A2H Video processor DC012\n * C2H Video processor DC011\n * E2H Graphics port\n *\n * READ ONLY (Decoded with I/O RD L)\n * 22H Modem buffer\n * 42H Flags buffer\n * 82H Keyboard UART data output\n *\n * Most of these are handled by the ChipSet component, since it exists as sort of a \"catch-all\" component,\n * but some are more appropriately handled by other components; eg, port 0x82 is handled by the Keyboard component,\n * so it's defined there instead of here.\n */\nChipSet8080.VT100 = {\n MODEL: 100.0,\n FLAGS: {\n PORT: 0x42, // read-only\n UART_XMIT: 0x01, // PUSART transmit buffer empty if SET\n NO_AVO: 0x02, // AVO present if CLEAR\n NO_GFX: 0x04, // VT125 graphics board present if CLEAR\n OPTION: 0x08, // OPTION present if SET\n NO_EVEN: 0x10, // EVEN FIELD active if CLEAR\n NVR_DATA: 0x20, // NVR DATA if SET\n NVR_CLK: 0x40, // NVR CLOCK if SET\n KBD_XMIT: 0x80 // KBD transmit buffer empty if SET\n },\n BRIGHTNESS: {\n PORT: 0x42, // write-only\n INIT: 0x00 // for lack of a better guess\n },\n /*\n * DC011 is referred to as a Timing Chip.\n *\n * As p. 4-55 (105) of the VT100 Technical Manual (July 1982) explains:\n *\n * The DCO11 is a custom designed bipolar circuit that provides most of the timing signals required by the\n * video processor. Internal counters divide the output of a 24.0734 MHz oscillator (located elsewhere on the\n * terminal controller module) into the lower frequencies that define dot, character, scan, and frame timing.\n * The counters are programmable through various input pins to control the number of characters per line,\n * the frequency at which the screen is refreshed, and whether the display is interlaced or noninterlaced.\n * These parameters can be controlled through SET-UP mode or by the host.\n *\n * Table 4-6-1: Video Mode Selection (Write Address 0xC2)\n *\n * D5 D4 Configuration\n * -- -- -------------\n * 0 0 80-column mode, interlaced\n * 0 1 132-column mode, interlaced\n * 1 0 60Hz, non-interlaced\n * 1 1 50Hz, non-interlaced\n *\n * On p. 4-56, the DC011 Block Diagram shows 8 outputs labeled LBA0 through LBA7. From p. 4-61:\n *\n * Several of the LBAs are used as general purpose clocks in the VT100. LBA3 and LBA4 are used to generate\n * timing for the keyboard. These signals satisfy the keyboard's requirement of two square-waves, one twice the\n * frequency of the other, even though every 16th transition is delayed (the second stage of the horizontal\n * counter divides by 17, not 16). LBA7 is used by the nonvolatile RAM.\n *\n * And on p. 4-62, timings are provided for the LBA0 through LBA7; in particular:\n *\n * LBA6: 16.82353us (when LBA6 is low, for a period of 33.64706us)\n * LBA7: 31.77778us (when LBA7 is high, for a period of 63.55556us)\n *\n * If we assume that the CPU cycle count increments once every 361.69ns, it will increment roughly 88 times every\n * time LBA7 toggles. So we can divide the CPU cycle count by 88 and set LBA to the low bit of that truncated\n * result. An even faster (but less accurate) solution would be to mask bit 6 of the CPU cycle count, which will\n * doesn't change until the count has been incremented 64 times. See getVT100LBA() for the chosen implementation.\n */\n DC011: { // generates Line Buffer Addresses (LBAs) for the Video Processor\n PORT: 0xC2, // write-only\n COLS80: 0x00,\n COLS132: 0x10,\n RATE60: 0x20,\n RATE50: 0x30,\n INITCOLS: 0x00, // ie, COLS80\n INITRATE: 0x20 // ie, RATE60\n },\n /*\n * DC012 is referred to as a Control Chip.\n *\n * As p. 4-67 (117) of the VT100 Technical Manual (July 1982) explains:\n *\n * The DCO12 performs three main functions.\n *\n * 1. Scan count generation. This involves two counters, a multiplexer to switch between the counters,\n * double-height logic, scroll and line attribute latches, and various logic controlling switching between\n * the two counters. This is the biggest part of the chip. It includes all scrolling, double-height logic,\n * and feeds into the underline and hold request circuits.\n *\n * 2. Generation of HOLD REQUEST. This uses information from the scan counters and the scrolling logic to\n * decide when to generate HOLD REQUEST.\n *\n * 3. Video modifications: dot stretching, blanking, addition of attributes to video outputs, and multiple\n * intensity levels.\n *\n * The input decoder accepts a 4-bit command from the microprocessor when VID WR 2 L is asserted. Table 4-6-2\n * lists the commands.\n *\n * D3 D2 D1 D0 Function\n * -- -- -- -- --------\n * 0 0 0 0 Load low order scroll latch = 00\n * 0 0 0 1 Load low order scroll latch = 01\n * 0 0 1 0 Load low order scroll latch = 10\n * 0 0 1 1 Load low order scroll latch = 11\n *\n * 0 1 0 0 Load high order scroll latch = 00\n * 0 1 0 1 Load high order scroll latch = 01\n * 0 1 1 0 Load high order scroll latch = 10\n * 0 1 1 1 Load high order scroll latch = 11 (not used)\n *\n * 1 0 0 0 Toggle blink flip-flop\n * 1 0 0 1 Clear vertical frequency interrupt\n *\n * 1 0 1 0 Set reverse field on\n * 1 0 1 1 Set reverse field off\n *\n * 1 1 0 0 Set basic attribute to underline*\n * 1 1 0 1 Set basic attribute to reverse video*\n * 1 1 1 0 Reserved for future specification*\n * 1 1 1 1 Reserved for future specification*\n *\n * *These functions also clear blink flip-flop.\n */\n DC012: { // generates scan counts for the Video Processor\n PORT: 0xA2, // write-only\n SCROLL_LO: 0x00,\n INITSCROLL: 0x00,\n INITBLINK: 0x00,\n INITREVERSE:0x00,\n INITATTR: 0x00\n },\n /*\n * ER1400 Non-Volatile RAM (NVR) Chip Definitions\n */\n NVR: {\n LATCH: {\n PORT: 0x62 // write-only\n },\n CMD: {\n ACCEPT_DATA: 0x0,\n ACCEPT_ADDR: 0x1,\n SHIFT_OUT: 0x2,\n WRITE: 0x4,\n ERASE: 0x5,\n READ: 0x6,\n STANDBY: 0x7\n },\n WORDMASK: 0x3fff // NVR words are 14-bit\n /*\n * The Technical Manual, p. 4-18, also notes that \"Early VT100s can disable the receiver interrupt by\n * programming D4 in the NVR latch. However, this is never used by the VT100.\"\n */\n }\n};\n\n/*\n * Supported models and their configurations\n */\nChipSet8080.MODELS = {\n \"SI1978\": ChipSet8080.SI1978,\n \"VT100\": ChipSet8080.VT100\n};\n\nChipSet8080.SI1978.INIT = [\n [\n ChipSet8080.SI1978.STATUS0.ALWAYS_SET,\n ChipSet8080.SI1978.STATUS1.ALWAYS_SET,\n ChipSet8080.SI1978.STATUS2.ALWAYS_SET,\n 0, 0, 0, 0\n ]\n];\n\nChipSet8080.VT100.INIT = [\n [\n ChipSet8080.VT100.BRIGHTNESS.INIT,\n ChipSet8080.VT100.FLAGS.NO_AVO | ChipSet8080.VT100.FLAGS.NO_GFX\n ],\n [\n ChipSet8080.VT100.DC011.INITCOLS,\n ChipSet8080.VT100.DC011.INITRATE\n ],\n [\n ChipSet8080.VT100.DC012.INITSCROLL,\n ChipSet8080.VT100.DC012.INITBLINK,\n ChipSet8080.VT100.DC012.INITREVERSE,\n ChipSet8080.VT100.DC012.INITATTR\n ],\n [\n 0, 0, 0, 0,\n [\n /*\n * The following array contains the data we use to initialize all (100) words of NVR (Non-Volatile RAM).\n *\n * I used to initialize every word to 0x3ff, as if the NVR had been freshly erased, but that causes the\n * firmware to (attempt to) beep and then display an error code (2). As the DEC Technical Manual says:\n *\n * If the NVR fails, the bell sounds several times to inform the operator, and then default settings\n * stored in the ROM allow the terminal to work.\n *\n * but I think what they meant to say is that default settings are stored in the RAM copy of NVR. So then\n * I went into SET-UP, pressed SHIFT-S to save those settings back to NVR, and then used the PC8080 debugger\n * \"d nvr\" command to dump the NVR contents. The results are below.\n *\n * The first dump actually contains only two modifications to the factory defaults: enabling ONLINE instead\n * of LOCAL operation, and turning ANSI support ON. The second dump is unmodified (the TRUE factory defaults).\n *\n * By making selective changes, you can discern where the bits for certain features are stored. For example,\n * smooth-scrolling is apparently controlled by bit 7 of the word at offset 0x2B (and is ON by default in\n * the factory settings). And it's likely that the word at offset 0x32 (ie, the last word that's not zero)\n * is the NVR checksum.\n */\n 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80,\n 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80,\n 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80,\n 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E00,\n 0x2E08, 0x2E8E, 0x2E00, 0x2ED0, 0x2E70, 0x2E00, 0x2E20, 0x2E00, 0x2EE0, 0x2EE0,\n 0x2E7D, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,\n 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,\n 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,\n 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,\n 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000\n ],\n [\n /*\n * The TRUE factory defaults (not currently used for anything; they're just here for reference, wasting space....)\n */\n 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80,\n 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80,\n 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80,\n 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E00,\n 0x2E08, 0x2E8E, 0x2E20, 0x2ED0, 0x2E50, 0x2E00, 0x2E20, 0x2E00, 0x2EE0, 0x2EE0,\n 0x2E69, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,\n 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,\n 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,\n 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,\n 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000\n ]\n ]\n];\n\n/*\n * Port notification tables\n */\nChipSet8080.SI1978.portsInput = {\n 0x00: ChipSet8080.prototype.inSIStatus0,\n 0x01: ChipSet8080.prototype.inSIStatus1,\n 0x02: ChipSet8080.prototype.inSIStatus2,\n 0x03: ChipSet8080.prototype.inSIShiftResult\n};\n\nChipSet8080.SI1978.portsOutput = {\n 0x02: ChipSet8080.prototype.outSIShiftCount,\n 0x03: ChipSet8080.prototype.outSISound1,\n 0x04: ChipSet8080.prototype.outSIShiftData,\n 0x05: ChipSet8080.prototype.outSISound2,\n 0x06: ChipSet8080.prototype.outSIWatchdog\n};\n\nChipSet8080.VT100.portsInput = {\n 0x42: ChipSet8080.prototype.inVT100Flags\n};\n\nChipSet8080.VT100.portsOutput = {\n 0x42: ChipSet8080.prototype.outVT100Brightness,\n 0x62: ChipSet8080.prototype.outVT100NVRLatch,\n 0xA2: ChipSet8080.prototype.outVT100DC012,\n 0xC2: ChipSet8080.prototype.outVT100DC011\n};\n\n/*\n * Initialize every ChipSet module on the page.\n */\nWeb.onInit(ChipSet8080.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/rom.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass ROM8080 extends Component {\n /**\n * ROM8080(parmsROM)\n *\n * The ROM8080 component expects the following (parmsROM) properties:\n *\n * addr: physical address of ROM\n * size: amount of ROM, in bytes\n * alias: physical alias address (null if none)\n * file: name of ROM data file\n *\n * NOTE: The ROM data will not be copied into place until the Bus is ready (see initBus()) AND the\n * ROM data file has finished loading (see doneLoad()).\n *\n * Also, while the size parameter may seem redundant, I consider it useful to confirm that the ROM you received\n * is the ROM you expected.\n *\n * @this {ROM8080}\n * @param {Object} parmsROM\n */\n constructor(parmsROM)\n {\n super(\"ROM\", parmsROM);\n\n this.abROM = null;\n this.addrROM = parmsROM['addr'];\n this.sizeROM = parmsROM['size'];\n\n /*\n * The new 'alias' property can now be EITHER a single physical address (like 'addr') OR an array of\n * physical addresses; eg:\n *\n * [0xf0000,0xffff0000,0xffff8000]\n *\n * We could have overloaded 'addr' to accomplish the same thing, but I think it's better to have any\n * aliased locations listed under a separate property.\n *\n * Most ROMs are not aliased, in which case the 'alias' property should have the default value of null.\n */\n this.addrAlias = parmsROM['alias'];\n\n this.sFilePath = parmsROM['file'];\n this.sFileName = Str.getBaseName(this.sFilePath);\n\n if (this.sFilePath) {\n var sFileURL = this.sFilePath;\n if (DEBUG) this.log('load(\"' + sFileURL + '\")');\n /*\n * If the selected ROM file has a \".json\" extension, then we assume it's pre-converted\n * JSON-encoded ROM data, so we load it as-is; ditto for ROM files with a \".hex\" extension.\n * Otherwise, we ask our server-side ROM converter to return the file in a JSON-compatible format.\n */\n var sFileExt = Str.getExtension(this.sFileName);\n if (sFileExt != DumpAPI.FORMAT.JSON && sFileExt != DumpAPI.FORMAT.HEX) {\n sFileURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFilePath + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES + '&' + DumpAPI.QUERY.DECIMAL + '=true';\n }\n var rom = this;\n Web.getResource(sFileURL, null, true, function(sURL, sResponse, nErrorCode) {\n rom.doneLoad(sURL, sResponse, nErrorCode);\n });\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {ROM8080}\n * @param {Computer8080} cmp\n * @param {Bus8080} bus\n * @param {CPUState8080} cpu\n * @param {Debugger8080} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.copyROM();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {ROM8080}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (this.aSymbols) {\n if (this.dbg) {\n this.dbg.addSymbols(this.id, this.addrROM, this.sizeROM, this.aSymbols);\n }\n /*\n * Our only role in the handling of symbols is to hand them off to the Debugger at our\n * first opportunity. Now that we've done that, our copy of the symbols, if any, are toast.\n */\n delete this.aSymbols;\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * Since we have nothing to do on powerDown(), and no state to return, we could simply omit\n * this function. But it doesn't hurt anything, and maybe we'll use our state to save something\n * useful down the road, like user-defined symbols (ie, symbols that the Debugger may have\n * created, above and beyond those symbols we automatically loaded, if any, along with the ROM).\n *\n * @this {ROM8080}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return true;\n }\n\n /**\n * doneLoad(sURL, sROMData, nErrorCode)\n *\n * @this {ROM8080}\n * @param {string} sURL\n * @param {string} sROMData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n doneLoad(sURL, sROMData, nErrorCode)\n {\n if (nErrorCode) {\n this.notice(\"Unable to load system ROM (error \" + nErrorCode + \": \" + sURL + \")\");\n return;\n }\n\n Component.addMachineResource(this.idMachine, sURL, sROMData);\n\n if (sROMData.charAt(0) == \"[\" || sROMData.charAt(0) == \"{\") {\n try {\n /*\n * The most likely source of any exception will be here: parsing the JSON-encoded ROM data.\n */\n var rom = eval(\"(\" + sROMData + \")\");\n var ab = rom['bytes'];\n /*\n * Resource 'longs' should always be 32-bit DWORD values, whereas 'data' bit lengths\n * will vary according to the machine architecture for which the resource was designed.\n */\n var adw = rom['longs'] || rom['data'];\n\n if (ab) {\n this.abROM = ab;\n }\n else if (adw) {\n /*\n * Convert all the DWORDs into BYTEs, so that subsequent code only has to deal with abROM.\n */\n this.abROM = new Array(adw.length * 4);\n for (var idw = 0, ib = 0; idw < adw.length; idw++) {\n this.abROM[ib++] = adw[idw] & 0xff;\n this.abROM[ib++] = (adw[idw] >> 8) & 0xff;\n this.abROM[ib++] = (adw[idw] >> 16) & 0xff;\n this.abROM[ib++] = (adw[idw] >> 24) & 0xff;\n }\n }\n else {\n this.abROM = rom;\n }\n\n this.aSymbols = rom['symbols'];\n\n if (!this.abROM.length) {\n Component.error(\"Empty ROM: \" + sURL);\n return;\n }\n else if (this.abROM.length == 1) {\n Component.error(this.abROM[0]);\n return;\n }\n } catch (e) {\n this.notice(\"ROM data error: \" + e.message);\n return;\n }\n }\n else {\n /*\n * Parse the ROM data manually; we assume it's in \"simplified\" hex form (a series of hex byte-values\n * separated by whitespace).\n */\n var sHexData = sROMData.replace(/\\n/gm, \" \").replace(/ +$/, \"\");\n var asHexData = sHexData.split(\" \");\n this.abROM = new Array(asHexData.length);\n for (var i = 0; i < asHexData.length; i++) {\n this.abROM[i] = Str.parseInt(asHexData[i], 16);\n }\n }\n this.copyROM();\n }\n\n /**\n * copyROM()\n *\n * This function is called by both initBus() and doneLoad(), but it cannot copy the the ROM data into place\n * until after initBus() has received the Bus component AND doneLoad() has received the abROM data. When both\n * those criteria are satisfied, the component becomes \"ready\".\n *\n * @this {ROM8080}\n */\n copyROM()\n {\n if (!this.isReady()) {\n if (!this.sFilePath) {\n this.setReady();\n }\n else if (this.abROM && this.bus) {\n /*\n * If no explicit size was specified, then use whatever the actual size is.\n */\n if (!this.sizeROM) {\n this.sizeROM = this.abROM.length;\n }\n if (this.abROM.length != this.sizeROM) {\n /*\n * Note that setError() sets the component's fError flag, which in turn prevents setReady() from\n * marking the component ready. TODO: Revisit this decision. On the one hand, it sounds like a\n * good idea to stop the machine in its tracks whenever a setError() occurs, but there may also be\n * times when we'd like to forge ahead anyway.\n */\n this.setError(\"ROM size (\" + Str.toHexLong(this.abROM.length) + \") does not match specified size (\" + Str.toHexLong(this.sizeROM) + \")\");\n }\n else if (this.addROM(this.addrROM)) {\n\n var aliases = [];\n if (typeof this.addrAlias == \"number\") {\n aliases.push(this.addrAlias);\n } else if (this.addrAlias != null && this.addrAlias.length) {\n aliases = this.addrAlias;\n }\n for (var i = 0; i < aliases.length; i++) {\n this.cloneROM(aliases[i]);\n }\n /*\n * We used to hang onto the original ROM data so that we could restore any bytes the CPU overwrote,\n * using memory write-notification handlers, but with the introduction of read-only memory blocks, that's\n * no longer necessary.\n *\n * TODO: Consider an option to retain the ROM data, and give the user some way of restoring ROMs.\n * That may be useful for \"resumable\" machines that save/restore all dirty block of memory, regardless\n * whether they're ROM or RAM. However, the only way to modify a machine's ROM is with the Debugger,\n * and Debugger users should know better.\n */\n delete this.abROM;\n }\n this.setReady();\n }\n }\n }\n\n /**\n * addROM(addr)\n *\n * @this {ROM8080}\n * @param {number} addr\n * @return {boolean}\n */\n addROM(addr)\n {\n if (this.bus.addMemory(addr, this.sizeROM, Memory8080.TYPE.ROM)) {\n if (DEBUG) this.log(\"addROM(): copying ROM to \" + Str.toHexLong(addr) + \" (\" + Str.toHexLong(this.abROM.length) + \" bytes)\");\n var i;\n for (i = 0; i < this.abROM.length; i++) {\n this.bus.setByteDirect(addr + i, this.abROM[i]);\n }\n return true;\n }\n /*\n * We don't need to report an error here, because addMemory() already takes care of that.\n */\n return false;\n }\n\n /**\n * cloneROM(addr)\n *\n * For ROMs with one or more alias addresses, we used to call addROM() for each address. However,\n * that obviously wasted memory, since each alias was an independent copy, and if you used the\n * Debugger to edit the ROM in one location, the changes would not appear in the other location(s).\n *\n * Now that the Bus component provides low-level getMemoryBlocks() and setMemoryBlocks() methods\n * to manually get and set the blocks of any memory range, it is now possible to create true aliases.\n *\n * @this {ROM8080}\n * @param {number} addr\n */\n cloneROM(addr)\n {\n var aBlocks = this.bus.getMemoryBlocks(this.addrROM, this.sizeROM);\n this.bus.setMemoryBlocks(addr, this.sizeROM, aBlocks);\n }\n\n /**\n * ROM8080.init()\n *\n * This function operates on every HTML element of class \"rom\", extracting the\n * JSON-encoded parameters for the ROM8080 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a ROM8080 component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeROM = Component.getElementsByClass(document, PC8080.APPCLASS, \"rom\");\n for (var iROM = 0; iROM < aeROM.length; iROM++) {\n var eROM = aeROM[iROM];\n var parmsROM = Component.getComponentParms(eROM);\n var rom = new ROM8080(parmsROM);\n Component.bindComponentControls(rom, eROM, PC8080.APPCLASS);\n }\n }\n}\n\n/*\n * NOTE: There's currently no need for this component to have a reset() function, since\n * once the ROM data is loaded, it can't be changed, so there's nothing to reinitialize.\n *\n * OK, well, I take that back, because the Debugger, if installed, has the ability to modify\n * ROM contents, so in that case, having a reset() function that restores the original ROM data\n * might be useful; then again, it might not, depending on what you're trying to debug.\n *\n * If we do add reset(), then we'll want to change copyROM() to hang onto the original\n * ROM data; currently, we release it after copying it into the read-only memory allocated\n * via bus.addMemory().\n */\n\n/*\n * Initialize all the ROM8080 modules on the page.\n */\nWeb.onInit(ROM8080.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/ram.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass RAM8080 extends Component {\n /**\n * RAM8080(parmsRAM)\n *\n * The RAM8080 component expects the following (parmsRAM) properties:\n *\n * addr: starting physical address of RAM (default is 0)\n * size: amount of RAM, in bytes (default is 0, which means defer to motherboard switch settings)\n * file: name of optional data file to load into RAM (default is \"\")\n * load: optional file load address (overrides any load address specified in the data file; default is null)\n * exec: optional file exec address (overrides any exec address specified in the data file; default is null)\n *\n * NOTE: We make a note of the specified size, but no memory is initially allocated for the RAM until the\n * Computer component calls powerUp().\n *\n * @this {RAM8080}\n * @param {Object} parmsRAM\n */\n constructor(parmsRAM)\n {\n super(\"RAM\", parmsRAM);\n\n this.abInit = null;\n this.aSymbols = null;\n\n this.addrRAM = parmsRAM['addr'];\n this.sizeRAM = parmsRAM['size'];\n this.addrLoad = parmsRAM['load'];\n this.addrExec = parmsRAM['exec'];\n\n this.fInstalled = (!!this.sizeRAM); // 0 is the default value for 'size' when none is specified\n this.fAllocated = false;\n\n this.sFilePath = parmsRAM['file'];\n this.sFileName = Str.getBaseName(this.sFilePath);\n\n if (this.sFilePath) {\n var sFileURL = this.sFilePath;\n if (DEBUG) this.log('load(\"' + sFileURL + '\")');\n /*\n * If the selected data file has a \".json\" extension, then we assume it's pre-converted\n * JSON-encoded data, so we load it as-is; ditto for ROM files with a \".hex\" extension.\n * Otherwise, we ask our server-side converter to return the file in a JSON-compatible format.\n */\n var sFileExt = Str.getExtension(this.sFileName);\n if (sFileExt != DumpAPI.FORMAT.JSON && sFileExt != DumpAPI.FORMAT.HEX) {\n sFileURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFilePath + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES + '&' + DumpAPI.QUERY.DECIMAL + '=true';\n }\n var ram = this;\n Web.getResource(sFileURL, null, true, function(sURL, sResponse, nErrorCode) {\n ram.doneLoad(sURL, sResponse, nErrorCode);\n });\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {RAM8080}\n * @param {Computer8080} cmp\n * @param {Bus8080} bus\n * @param {CPUState8080} cpu\n * @param {Debugger8080} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.initRAM();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {RAM8080}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n /*\n * The Computer powers up the CPU last, at which point CPUState state is restored,\n * which includes the Bus state, and since we use the Bus to allocate all our memory,\n * memory contents are already restored for us, so we don't need the usual restore\n * logic.\n */\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {RAM8080}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n /*\n * The Computer powers down the CPU first, at which point CPUState state is saved,\n * which includes the Bus state, and since we use the Bus component to allocate all\n * our memory, memory contents are already saved for us, so we don't need the usual\n * save logic.\n */\n return true;\n }\n\n /**\n * doneLoad(sURL, sData, nErrorCode)\n *\n * @this {RAM8080}\n * @param {string} sURL\n * @param {string} sData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n doneLoad(sURL, sData, nErrorCode)\n {\n if (nErrorCode) {\n this.notice(\"Unable to load RAM resource (error \" + nErrorCode + \": \" + sURL + \")\");\n return;\n }\n\n Component.addMachineResource(this.idMachine, sURL, sData);\n\n var resource = Web.parseMemoryResource(sURL, sData);\n if (resource) {\n this.abInit = resource.aBytes;\n this.aSymbols = resource.aSymbols;\n if (this.addrLoad == null) this.addrLoad = resource.addrLoad;\n if (this.addrExec == null) this.addrExec = resource.addrExec;\n } else {\n this.sFilePath = null;\n }\n this.initRAM();\n }\n\n /**\n * initRAM()\n *\n * This function is called by both initBus() and doneLoad(), but it cannot copy the initial data into place\n * until after initBus() has received the Bus component AND doneLoad() has received the data. When both those\n * criteria are satisfied, the component becomes \"ready\".\n *\n * @this {RAM8080}\n */\n initRAM()\n {\n if (!this.fAllocated && this.sizeRAM) {\n if (this.bus.addMemory(this.addrRAM, this.sizeRAM, Memory8080.TYPE.RAM)) {\n this.fAllocated = true;\n }\n }\n if (!this.isReady()) {\n if (!this.fAllocated) {\n Component.error(\"No RAM allocated\");\n }\n else if (this.sFilePath) {\n /*\n * Too early...\n */\n if (!this.abInit || !this.bus) return;\n\n var addr = this.addrRAM;\n if (this.addrLoad !== null) addr = this.addrLoad;\n for (var i = 0; i < this.abInit.length; i++) {\n this.bus.setByteDirect(addr + i, this.abInit[i]);\n }\n\n if (this.addrExec !== null) {\n /*\n * Here's where we enable our \"Fake CP/M\" support, triggered by the user loading a \"writable\" ROM image\n * at offset 0x100. Fake CP/M support works by installing HLT opcodes at well-known CP/M addresses\n * (namely, 0x0000, which is the CP/M reset vector, and 0x0005, which is the CP/M system call vector) and\n * then telling the CPU to call us whenever a HLT occurs, so we can check PC for one of these addresses.\n */\n if (this.addrExec == RAM8080.CPM.INIT) {\n for (i = 0; i < RAM8080.CPM.VECTORS.length; i++) {\n this.bus.setByteDirect(RAM8080.CPM.VECTORS[i], CPUDef8080.OPCODE.HLT);\n }\n\n this.cpu.addHaltCheck(function(rom) {\n return function(addr) {\n return rom.checkCPMVector(addr)\n };\n }(this));\n }\n this.cpu.setReset(this.addrExec);\n }\n\n /*\n * TODO: Consider an option to retain this data and give the user a way of restoring the initial contents.\n */\n delete this.abInit;\n }\n this.setReady();\n }\n }\n\n /**\n * reset()\n *\n * @this {RAM8080}\n */\n reset()\n {\n /*\n * If you want to zero RAM on reset, then this would be a good place to do it.\n */\n }\n\n /**\n * checkCPMVector(addr)\n *\n * @this {RAM8080}\n * @param {number} addr (of the HLT opcode)\n * @return {boolean} true if special processing performed, false if not\n */\n checkCPMVector(addr)\n {\n var i = RAM8080.CPM.VECTORS.indexOf(addr);\n if (i >= 0) {\n var fCPM = false;\n var cpu = this.cpu;\n var dbg = this.dbg;\n if (addr == RAM8080.CPM.BDOS.VECTOR) {\n fCPM = true;\n switch(cpu.regC) {\n case RAM8080.CPM.BDOS.FUNC.CON_WRITE:\n this.writeCPMString(this.getCPMChar(cpu.regE));\n break;\n case RAM8080.CPM.BDOS.FUNC.STR_WRITE:\n this.writeCPMString(this.getCPMString(cpu.getDE(), '$'));\n break;\n default:\n fCPM = false;\n break;\n }\n }\n if (fCPM) {\n CPUDef8080.opRET.call(cpu); // for recognized calls, automatically return\n }\n else if (dbg) {\n this.println(\"\\nCP/M vector \" + Str.toHexWord(addr));\n cpu.setPC(addr); // this is purely for the Debugger's benefit, to show the HLT\n dbg.stopCPU();\n }\n return true;\n }\n return false;\n }\n\n /**\n * getCPMChar(ch)\n *\n * @this {RAM8080}\n * @param {number} ch\n * @return {string}\n */\n getCPMChar(ch)\n {\n return String.fromCharCode(ch);\n }\n\n /**\n * getCPMString(addr, chEnd)\n *\n * @this {RAM8080}\n * @param {number} addr (of a string)\n * @param {string|number} [chEnd] (terminating character, default is 0)\n * @return {string}\n */\n getCPMString(addr, chEnd)\n {\n var s = \"\";\n var cchMax = 255;\n var bEnd = chEnd && chEnd.length && chEnd.charCodeAt(0) || chEnd || 0;\n while (cchMax--) {\n var b = this.cpu.getByte(addr++);\n if (b == bEnd) break;\n s += String.fromCharCode(b);\n }\n return s;\n }\n\n /**\n * writeCPMString(s)\n *\n * @this {RAM8080}\n * @param {string} s\n */\n writeCPMString(s)\n {\n this.print(s.replace(/\\r/g, ''));\n }\n\n /**\n * RAM8080.init()\n *\n * This function operates on every HTML element of class \"ram\", extracting the\n * JSON-encoded parameters for the RAM8080 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a RAM8080 component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeRAM = Component.getElementsByClass(document, PC8080.APPCLASS, \"ram\");\n for (var iRAM = 0; iRAM < aeRAM.length; iRAM++) {\n var eRAM = aeRAM[iRAM];\n var parmsRAM = Component.getComponentParms(eRAM);\n var ram = new RAM8080(parmsRAM);\n Component.bindComponentControls(ram, eRAM, PC8080.APPCLASS);\n }\n }\n}\n\nRAM8080.CPM = {\n BIOS: {\n VECTOR: 0x0000\n },\n BDOS: {\n VECTOR: 0x0005,\n FUNC: { // function number (specified in regC)\n RESET: 0x00,\n CON_READ: 0x01, // output: A = L = ASCII character\n CON_WRITE: 0x02, // input: E = ASCII character\n AUX_READ: 0x03, // output: A = L = ASCII character\n AUX_WRITE: 0x04, // input: E = ASCII character\n PRN_WRITE: 0x05, // input: E = ASCII character\n MEM_SIZE: 0x06, // output: base address of CCP (Console Command Processor), but which register? (perhaps moot if this was CP/M 1.3 only...)\n CON_IO: 0x06, // input: E = ASCII character (or 0xFF to return ASCII character in A)\n GET_IOBYTE: 0x07,\n SET_IOBYTE: 0x08,\n STR_WRITE: 0x09 // input: DE = address of string\n }\n },\n INIT: 0x100\n};\n\nRAM8080.CPM.VECTORS = [RAM8080.CPM.BIOS.VECTOR, RAM8080.CPM.BDOS.VECTOR];\n\n/*\n * Initialize all the RAM8080 modules on the page.\n */\nWeb.onInit(RAM8080.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/keyboard.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass Keyboard8080 extends Component {\n /**\n * Keyboard8080(parmsKbd)\n *\n * The Keyboard8080 component has the following component-specific (parmsKbd) properties:\n *\n * model: eg, \"VT100\" (should be a member of Keyboard8080.MODELS)\n *\n * @this {Keyboard8080}\n * @param {Object} parmsKbd\n */\n constructor(parmsKbd)\n {\n super(\"Keyboard\", parmsKbd, Messages8080.KEYBOARD);\n\n var model = parmsKbd['model'];\n\n if (model && !Keyboard8080.MODELS[model]) {\n Component.notice(\"Unrecognized Keyboard8080 model: \" + model);\n }\n\n this.config = Keyboard8080.MODELS[model] || {};\n\n this.reset();\n\n this.setReady();\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {Keyboard8080}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"esc\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n /*\n * There's a special binding that the Video component uses (\"screen\") to effectively bind its\n * screen to the entire keyboard, in Video.powerUp(); ie:\n *\n * video.kbd.setBinding(\"canvas\", \"screen\", video.canvasScreen);\n * or:\n * video.kbd.setBinding(\"textarea\", \"screen\", video.textareaScreen);\n *\n * However, it's also possible for the keyboard XML definition to define a control that serves\n * a similar purpose; eg:\n *\n * <control type=\"text\" binding=\"kbd\" width=\"2em\">Keyboard</control>\n *\n * The latter is purely experimental, while we work on finding ways to trigger the soft keyboard on\n * certain pesky devices (like the Kindle Fire). Note that even if you use the latter, the former will\n * still be enabled (there's currently no way to configure the Video component to not bind its screen,\n * but we could certainly add one if the need ever arose).\n */\n var kbd = this;\n var id = sHTMLType + '-' + sBinding;\n\n if (this.bindings[id] === undefined) {\n\n if (sHTMLType == \"led\" && this.config.LEDCODES[sBinding]) {\n this.bindings[id] = control;\n return true;\n }\n\n switch (sBinding) {\n case \"kbd\":\n case \"screen\":\n /*\n * Recording the binding ID prevents multiple controls (or components) from attempting to erroneously\n * bind a control to the same ID, but in the case of a \"dual display\" configuration, we actually want\n * to allow BOTH video components to call setBinding() for \"screen\", so that it doesn't matter which\n * display the user gives focus to.\n *\n * this.bindings[id] = control;\n */\n if (Web.isUserAgent(\"iOS\")) {\n /*\n * For iOS devices, it's best to deal only with keypress events. The main reason is that we don't\n * get shift-key events, so we have no way of distinguishing between certain keys, such as ':' and\n * ';', unless we are monitoring key presses. Another reason is that, under certain poorly documented\n * conditions, an iOS keyup event will not contain any keyCode; this is most easily reproduced with\n * the iOS simulator and a physical keyboard (not the pop-up keyboard). When this happens, we think\n * the key is stuck. Finally, certain other problems that we have tried to resolve when using a physical\n * keyboard (eg, keeping the physical and virtual CAPS-LOCK states in sync) simply don't exist in the\n * iOS environment.\n *\n * So, with all that mind, it seems best to have a separate iOS keypress handler and forego keydown\n * and keyup events entirely. The iOS keypress handler must also perform some additional checks, such\n * as watching for keys that can only be typed on the emulated device when a shift key is down, and\n * simulating \"fake\" shift-key down and up events.\n *\n * Perhaps we can eventually standardize on this alternate keypress-centric approach for ALL devices,\n * but until then, it's safer to have these two code paths.\n *\n * UPDATE: So much for the best laid plans. iOS won't deliver BACKSPACE events to the keypress handler,\n * so we have to deal with keydown/keyup events after all.\n */\n control.onkeypress = function oniOSKeyPress(event)\n {\n return kbd.oniOSKeyPress(event);\n };\n control.onkeydown = function oniOSKeyDown(event)\n {\n return kbd.oniOSKeyDown(event, true);\n };\n control.onkeyup = function oniOSKeyUp(event)\n {\n return kbd.oniOSKeyDown(event, false);\n };\n }\n else {\n control.onkeydown = function onKeyDown(event)\n {\n return kbd.onKeyDown(event, true);\n };\n control.onkeyup = function onKeyUp(event)\n {\n return kbd.onKeyDown(event, false);\n };\n control.onkeypress = function onKeyPress(event)\n {\n return kbd.onKeyPress(event);\n };\n }\n control.onpaste = function onKeyPaste(event)\n {\n return kbd.onPaste(event);\n };\n return true;\n\n default:\n if (this.config.SOFTCODES && this.config.SOFTCODES[sBinding] !== undefined) {\n this.bindings[id] = control;\n control.onclick = function(kbd, keyCode) {\n return function onKeyboardBindingDown(event) {\n /*\n * iOS usability improvement: calling preventDefault() prevents rapid clicks from\n * also being (mis)interpreted as a desire to \"zoom\" in on the machine.\n */\n if (event.preventDefault) event.preventDefault();\n /*\n * TODO: Add some additional SOFTCODES configuration info that will tell us which soft\n * keys (eg, CTRL) should be treated as toggles, instead of hard-coding that knowledge below.\n *\n * Moreover, if a *real* CTRL or CAPS-LOCK key is pressed or released, it would be nice\n * to update the state of these on-screen controls, too (ie, not just when the controls are\n * clicked).\n */\n var fDown = true, bit = 0;\n if (keyCode == Keys.KEYCODE.CTRL) {\n bit = Keyboard8080.STATE.CTRL;\n }\n else if (keyCode == Keys.KEYCODE.CAPS_LOCK) {\n bit = Keyboard8080.STATE.CAPS_LOCK;\n }\n if (bit) {\n control.style.fontWeight = \"normal\";\n fDown = !(kbd.bitsState & bit);\n if (fDown) control.style.fontWeight = \"bold\";\n kbd.checkModifierKeys(keyCode, fDown);\n }\n kbd.onSoftKeyDown(keyCode, fDown, !bit);\n if (kbd.cmp) kbd.cmp.updateFocus();\n };\n }(this, this.config.SOFTCODES[sBinding]);\n //\n // var fnUp = function (kbd, keyCode) {\n // return function onKeyboardBindingUp(event) {\n // kbd.onSoftKeyDown(keyCode, false);\n // /*\n // * Give focus back to the machine (since clicking the button takes focus away).\n // *\n // * if (kbd.cmp) kbd.cmp.updateFocus();\n // *\n // * iOS Usability Improvement: NOT calling updateFocus() keeps the soft keyboard down\n // * (assuming it was already down).\n // */\n // };\n // }(this, this.config.SOFTCODES[sBinding]);\n //\n // if ('ontouchstart' in window) {\n // control.ontouchstart = fnDown;\n // control.ontouchend = fnUp;\n // } else {\n // control.onmousedown = fnDown;\n // control.onmouseup = control.onmouseout = fnUp;\n // }\n //\n // UPDATE: Since the only controls that we explicitly bind to SOFTCODES are buttons, I'm simplifying\n // the above code with a conventional \"onclick\" handler. The only corresponding change I had to make\n // to the onclick (formerly fnDown) function was to set fAutoRelease on its call to onSoftKeyDown(),\n // since we're no longer attempting to detect when the control (ie, the button) is actually released.\n //\n // This change also resolves a problem I ran into with the Epiphany (WebKit-based) web browser running\n // on the \"elementary\" (Ubuntu-based) OS, where clicks on the SET-UP button were ignored; perhaps its\n // buttons don't generate mouse and/or touch events. Anyway, an argument for keeping things simple.\n //\n return true;\n }\n break;\n }\n }\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {Keyboard8080}\n * @param {Computer8080} cmp\n * @param {Bus8080} bus\n * @param {CPUState8080} cpu\n * @param {Debugger8080} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.cpu = cpu;\n this.dbg = dbg; // NOTE: The \"dbg\" property must be set for the message functions to work\n\n var kbd = this;\n this.timerReleaseKeys = this.cpu.addTimer(this.id, function() {\n kbd.checkSoftKeysToRelease();\n });\n\n this.chipset = /** @type {ChipSet8080} */ (cmp.getMachineComponent(\"ChipSet\"));\n\n this.serial = /** @type {SerialPort8080} */ (cmp.getMachineComponent(\"SerialPort\"));\n\n bus.addPortInputTable(this, this.config.portsInput);\n bus.addPortOutputTable(this, this.config.portsOutput);\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {Keyboard8080}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Keyboard8080}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {Keyboard8080}\n */\n reset()\n {\n /*\n * As keyDown events are encountered, a corresponding \"softCode\" is looked up. If one is found,\n * then an entry for the key is added to the aKeysActive array. Each \"key\" entry in aKeysActive contains:\n *\n * softCode: number or string representing the key pressed\n * msDown: timestamp of the most recent \"down\" event\n * fAutoRelease: true to auto-release the key after MINPRESSTIME (set when \"up\" occurs too quickly)\n *\n * When the key is finally released (or auto-released), its entry is removed from the array.\n */\n this.aKeysActive = [];\n\n /*\n * The current (assumed) physical (and simulated) states of the various shift/lock keys.\n *\n * TODO: Determine how (or whether) we can query the browser's initial shift/lock key states.\n */\n this.bitsState = 0;\n\n if (this.config.INIT && !this.restore(this.config.INIT)) {\n this.notice(\"reset error\");\n }\n }\n\n /**\n * save()\n *\n * This implements save support for the Keyboard component.\n *\n * @this {Keyboard8080}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n switch(this.config.MODEL) {\n case Keyboard8080.SI1978.MODEL:\n break;\n case Keyboard8080.VT100.MODEL:\n state.set(0, [this.bVT100Status, this.bVT100Address, this.fVT100UARTBusy, this.nVT100UARTCycleSnap, -1]);\n break;\n }\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the Keyboard component.\n *\n * @this {Keyboard8080}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var a;\n if (data && (a = data[0]) && a.length) {\n switch(this.config.MODEL) {\n case Keyboard8080.SI1978.MODEL:\n return true;\n\n case Keyboard8080.VT100.MODEL:\n this.bVT100Status = a[0];\n this.updateLEDs(this.bVT100Status & Keyboard8080.VT100.STATUS.LEDS);\n this.bVT100Address = a[1];\n this.fVT100UARTBusy = a[2];\n this.nVT100UARTCycleSnap = a[3];\n this.iKeyNext = a[4];\n return true;\n }\n }\n return false;\n }\n\n /**\n * setLED(control, f, color)\n *\n * TODO: Add support for user-definable LED colors\n *\n * @this {Keyboard8080}\n * @param {Object} control is an HTML control DOM object\n * @param {boolean|number} f is true if the LED represented by control should be \"on\", false if \"off\"\n * @param {number} color (ie, 0xff0000 for RED, or 0x00ff00 for GREEN)\n */\n setLED(control, f, color)\n {\n control.style.backgroundColor = (f? ('#' + Str.toHex(color, 6)) : \"#000000\");\n }\n\n /**\n * updateLEDs(bLEDs)\n *\n * @this {Keyboard8080}\n * @param {number} [bLEDs]\n */\n updateLEDs(bLEDs)\n {\n var id, control;\n if (bLEDs != null) {\n this.bLEDs = bLEDs;\n } else {\n bLEDs = this.bLEDs;\n }\n for (var sBinding in this.config.LEDCODES) {\n id = \"led-\" + sBinding;\n control = this.bindings[id];\n if (control) {\n var bitLED = this.config.LEDCODES[sBinding];\n var fOn = !!(bLEDs & bitLED);\n if (bitLED & (bitLED-1)) {\n fOn = !(bLEDs & ~bitLED);\n }\n this.setLED(control, fOn, 0xff0000);\n }\n }\n id = \"led-caps-lock\";\n control = this.bindings[id];\n if (control) {\n this.setLED(control, (this.bitsState & Keyboard8080.STATE.CAPS_LOCK), 0x00ff00);\n }\n }\n\n /**\n * checkModifierKeys(keyCode, fDown, fRight)\n *\n * @this {Keyboard8080}\n * @param {number} keyCode (ie, either a keycode or string ID)\n * @param {boolean} fDown (true if key going down, false if key going up)\n * @param {boolean} [fRight] (true if key is on the right, false if not or unknown or n/a)\n * @return {boolean} (fDown updated as needed for CAPS-LOCK weirdness)\n */\n checkModifierKeys(keyCode, fDown, fRight)\n {\n var bit = 0;\n switch(keyCode) {\n case Keys.KEYCODE.SHIFT:\n bit = fRight? Keyboard8080.STATE.RSHIFT : Keyboard8080.STATE.SHIFT;\n break;\n case Keys.KEYCODE.CTRL:\n bit = fRight? Keyboard8080.STATE.RCTRL : Keyboard8080.STATE.CTRL;\n break;\n case Keys.KEYCODE.ALT:\n bit = fRight? Keyboard8080.STATE.RALT : Keyboard8080.STATE.ALT;\n break;\n case Keys.KEYCODE.CMD:\n bit = fRight? Keyboard8080.STATE.RCMD : Keyboard8080.STATE.CMD;\n break;\n case Keys.KEYCODE.CAPS_LOCK:\n bit = Keyboard8080.STATE.CAPS_LOCK;\n /*\n * WARNING: You have an entered a browser weirdness zone. In Chrome, pressing-and-releasing\n * CAPS-LOCK generates a \"down\" event when it turns the lock on and an \"up\" event when it turns\n * the lock off. Firefox, OTOH, generates only \"down\" events, so we have to \"manufacture\"\n * the fDown parameter ourselves -- which means we also have to propagate it back to the caller.\n *\n * And, while this isn't necessary for Chrome, it doesn't appear to hurt anything in Chrome, so\n * we're not going to bother making it browser-specific.\n */\n fDown = !(this.bitsState & bit);\n break;\n }\n if (bit) {\n if (fDown) {\n this.bitsState |= bit;\n } else {\n this.bitsState &= ~bit;\n }\n }\n return fDown;\n }\n\n /**\n * getSoftCode(keyCode)\n *\n * Returns a number if the keyCode exists in the KEYMAP, or a string if the keyCode has a string ID.\n *\n * @this {Keyboard8080}\n * @return {string|number|null}\n */\n getSoftCode(keyCode)\n {\n keyCode = this.config.ALTCODES[keyCode] || keyCode;\n if (this.config.KEYMAP[keyCode]) {\n return keyCode;\n }\n for (var sSoftCode in this.config.SOFTCODES) {\n if (this.config.SOFTCODES[sSoftCode] === keyCode) {\n return sSoftCode;\n }\n }\n return null;\n }\n\n /**\n * onKeyDown(event, fDown)\n *\n * @this {Keyboard8080}\n * @param {Object} event\n * @param {boolean} fDown is true for a keyDown event, false for up\n * @return {boolean} true to pass the event along, false to consume it\n */\n onKeyDown(event, fDown)\n {\n var fPass = true;\n var keyCode = event.keyCode;\n\n if (!COMPILED && this.messageEnabled(Messages8080.KEYS)) {\n this.printMessage(\"onKey\" + (fDown? \"Down\" : \"Up\") + \"(\" + keyCode + \")\", true);\n }\n\n /*\n * A note about Firefox: it uses different keyCodes for certain keys; there's a logic to the differences\n * (they use ASCII codes), but since other browsers didn't follow suit, we must use a mapping table to\n * convert their keyCodes to the more traditional values.\n */\n keyCode = Keys.FF_KEYCODES[keyCode] || keyCode;\n\n /*\n * We now keep track of physical keyboard modifier keys. This makes it possible for new services\n * to eventually be implemented (simulateKeysDown() and simulateKeysUp()), to map special ALT-key\n * combinations to VT100 keys, etc.\n */\n fDown = this.checkModifierKeys(keyCode, fDown, event.location == Keys.LOCATION.RIGHT);\n\n var softCode = this.getSoftCode(keyCode);\n if (softCode) {\n /*\n * Key combinations involving the \"meta\" key (ie, the Windows or Command key) are meaningless to\n * the VT100, so we ignore them. The \"meta\" key itself is already effectively ignored, because it's\n * not acknowledged by getSoftCode(), but we also don't want any of the keys combined with \"meta\"\n * slipping through either.\n */\n if (!event.metaKey) {\n /*\n * The LINE-FEED key is an important key on the VT100, and while we DO map a host function key\n * to it (F7), I like the idea of making ALT-ENTER an alias for LINE-FEED as well. Ditto for\n * making ALT-DELETE an alias for BACKSPACE (and no, I don't mean ALT-BACKSPACE as an alias for\n * DELETE; see my earlier discussion involving BACKSPACE and DELETE).\n *\n * Of course, as experienced VT100 users know, it's always possible to type CTRL-J for LINE-FEED\n * and CTRL-H for BACKSPACE, too. But not all our users are that experienced.\n *\n * I was also tempted to use CTRL-ENTER or SHIFT-ENTER, but those are composable VT100 key\n * sequences, so it's best not to muck with those.\n *\n * Finally, this hack is complicated by the fact that if the ALT key is released first, we run\n * the risk of the remapped key being stuck \"down\". Hence the new REMAPPED bit, which should\n * remain set (as a \"proxy\" for the ALT bit) as long as a remapped key is down.\n */\n var fRemapped = false;\n if (this.bitsState & (Keyboard8080.STATE.ALTS | Keyboard8080.STATE.REMAPPED)) {\n if (softCode == Keys.KEYCODE.CR) {\n softCode = Keys.KEYCODE.F7;\n fRemapped = true;\n }\n else if (softCode == Keys.KEYCODE.BS) {\n softCode = Keys.KEYCODE.DEL;\n fRemapped = true;\n }\n if (fRemapped) {\n if (fDown) {\n this.bitsState |= Keyboard8080.STATE.REMAPPED;\n } else {\n this.bitsState &= ~Keyboard8080.STATE.REMAPPED;\n }\n }\n }\n fPass = this.onSoftKeyDown(softCode, fDown);\n /*\n * As onKeyPress() explains, the only key presses we're interested in are letters, which provide\n * an important clue regarding the CAPS-LOCK state. For all other keys, we call preventDefault(),\n * which normally \"suppresses\" the keyPress event, as well as other unwanted browser behaviors\n * (eg, the SPACE key, which browsers interpret as a desire to scroll the entire web page down).\n *\n * And, even if the key IS a letter, we STILL want to call preventDefault() if a CTRL key is down,\n * so that Windows-based browsers (eg, Edge) don't interfere with their stupid CTRL-based shortcuts. ;-)\n *\n * NOTE: We COULD check event.ctrlKey too, but it's six of one, half a dozen of another.\n */\n if (!(softCode >= Keys.ASCII.A && softCode <= Keys.ASCII.Z) || (this.bitsState | Keyboard8080.STATE.CTRLS)) {\n if (event.preventDefault) event.preventDefault();\n }\n }\n }\n\n if (!COMPILED && this.messageEnabled(Messages8080.KEYS)) {\n this.printMessage(\"onKey\" + (fDown? \"Down\" : \"Up\") + \"(\" + keyCode + \"): softCode=\" + softCode + \", pass=\" + fPass, true);\n }\n\n return fPass;\n }\n\n /**\n * onKeyPress(event)\n *\n * For now, our only interest in keyPress events is letters, as a means of detecting the CAPS-LOCK state.\n *\n * @this {Keyboard8080}\n * @param {Object} event\n * @return {boolean} true to pass the event along, false to consume it\n */\n onKeyPress(event)\n {\n /*\n * A note about Firefox: the KeyboardEvent they pass to a keypress handler doesn't set 'keyCode', so\n * we have to fallback to 'charCode' (or 'which'), both of which are deprecated but realistically can't\n * really go away.\n *\n * TODO: Consider \"upgrading\" this code to use the new 'key' property. Note, however, that it's a string,\n * not a number; for example; if the colon key is pressed, 'key' will be \":\", whereas 'charCode' and 'which'\n * will be 58.\n */\n var charCode = event.keyCode || event.charCode;\n\n if (charCode >= Keys.ASCII.A && charCode <= Keys.ASCII.Z) {\n if (!(this.bitsState & (Keyboard8080.STATE.SHIFTS | Keyboard8080.STATE.CAPS_LOCK))) {\n this.bitsState |= Keyboard8080.STATE.CAPS_LOCK;\n this.onSoftKeyDown(Keys.KEYCODE.CAPS_LOCK, true);\n this.updateLEDs();\n }\n }\n else if (charCode >= Keys.ASCII.a && charCode <= Keys.ASCII.z) {\n if (this.bitsState & Keyboard8080.STATE.CAPS_LOCK) {\n this.bitsState &= ~Keyboard8080.STATE.CAPS_LOCK;\n this.onSoftKeyDown(Keys.KEYCODE.CAPS_LOCK, false);\n this.updateLEDs();\n }\n }\n\n if (!COMPILED && this.messageEnabled(Messages8080.KEYS)) {\n this.printMessage(\"onKeyPress(\" + charCode + \")\", true);\n }\n\n return true;\n }\n\n /**\n * oniOSKeyDown(event, fDown)\n *\n * @this {Keyboard8080}\n * @param {Object} event\n * @param {boolean} fDown is true for a keyDown event, false for up\n * @return {boolean} true to pass the event along, false to consume it\n */\n oniOSKeyDown(event, fDown)\n {\n var fPass = true;\n /*\n * Because keydown/keyup events on iOS are inherently \"fake\", they can be delivered so quickly that\n * if we generated matching down/up events, then the emulated machine might not see the key transition.\n * So we now deliver only down events, with fAutoRelease always set (see below).\n *\n * Also, because of iOS weirdness discussed in setBinding() when using a physical keyboard, the keyup\n * event may not provide a valid keyCode, which is another reason we have no choice but to always deliver\n * keys with fAutoRelease set to true.\n */\n if (fDown) {\n var keyCode = event.keyCode;\n var bMapping = this.config.KEYMAP[keyCode];\n if (bMapping) {\n /*\n * If this is a mappable key, but the mapping isn't in the CHARMAP table, then we have to process\n * it now; the most common reason is that the key doesn't generate a keypress event (eg, BACKSPACE).\n */\n if (!this.indexOfCharMap(bMapping)) {\n fPass = this.onSoftKeyDown(keyCode, fDown, true);\n if (event.preventDefault) event.preventDefault();\n if (!COMPILED && this.messageEnabled(Messages8080.KEYS)) {\n this.printMessage(\"oniOSKey\" + (fDown ? \"Down\" : \"Up\") + \"(\" + keyCode + \"): pass=\" + fPass, true);\n }\n }\n }\n }\n return fPass;\n }\n\n /**\n * oniOSKeyPress(event)\n *\n * @this {Keyboard8080}\n * @param {Object} event\n * @return {boolean} true to pass the event along, false to consume it\n */\n oniOSKeyPress(event)\n {\n /*\n * A note about Firefox: the KeyboardEvent they pass to a keypress handler doesn't set 'keyCode', so\n * we have to fallback to 'charCode' (or 'which'), both of which are deprecated but realistically can't\n * really go away.\n *\n * TODO: Consider \"upgrading\" this code to use the new 'key' property. Note, however, that it's a string,\n * not a number; for example; if the colon key is pressed, 'key' will be \":\", whereas 'charCode' and 'which'\n * will be 58.\n */\n var charCode = event.keyCode || event.charCode;\n\n var fShifted = false;\n var bMapping = this.config.CHARMAP[charCode];\n if (bMapping) {\n if (bMapping & 0x80) {\n bMapping &= 0x7f;\n fShifted = true;\n }\n /*\n * Since the rest of our code was built around keyCodes, not charCodes, we look up the CHARMAP byte\n * in the KEYMAP table to find a corresponding keyCode, and that's what we'll use to simulate the key\n * press/release.\n */\n var softCode = this.indexOfKeyMap(bMapping);\n if (softCode) {\n if (!fShifted) {\n this.onSoftKeyDown(Keys.KEYCODE.SHIFT, false);\n } else {\n this.onSoftKeyDown(Keys.KEYCODE.SHIFT, true, true);\n }\n this.onSoftKeyDown(softCode, true, true);\n }\n }\n\n if (!COMPILED && this.messageEnabled(Messages8080.KEYS)) {\n this.printMessage(\"oniOSKeyPress(\" + charCode + \")\", true);\n }\n\n return true;\n }\n\n /**\n * onPaste(event)\n *\n * @this {Keyboard8080}\n * @param {Object} event\n * @return {boolean} true to pass the event along, false to consume it\n */\n onPaste(event)\n {\n /*\n * TODO: In a perfect world, we would have implemented simulateKeysDown() and simulateKeysUp(),\n * which would transform any given text into the appropriate keystrokes. But for now, we're going\n * to leapfrog all that and try invoking the SerialPort's sendData() function, which if available,\n * is nothing more than a call into a connected machine's receiveData() function.\n *\n * Besides, paste functionality doesn't seem to be consistently implemented across all browsers\n * (partly out of security concerns, apparently) so it may not make sense to expend much more\n * effort on this right now. If you want to paste a lot of text into a machine, you're better off\n * pasting into a machine that's been configured to use a textarea as part of its Control Panel.\n * A visible textarea seems to have less issues than the hidden textarea overlaid on top of our\n * Video display.\n */\n if (this.serial && this.serial.sendData) {\n if (event.stopPropagation) event.stopPropagation();\n if (event.preventDefault) event.preventDefault();\n var clipboardData = event.clipboardData || window.clipboardData;\n if (clipboardData) {\n this.serial.transmitData(clipboardData.getData('Text'));\n return false;\n }\n }\n return true;\n }\n\n /**\n * indexOfKeyMap(bMapping)\n *\n * @this {Keyboard8080}\n * @param {number} bMapping\n * @return {number}\n */\n indexOfKeyMap(bMapping)\n {\n for (var keyCode in this.config.KEYMAP) {\n if (this.config.KEYMAP[keyCode] == bMapping) return +keyCode;\n }\n return 0;\n }\n\n /**\n * indexOfCharMap(bMapping)\n *\n * @this {Keyboard8080}\n * @param {number} bMapping\n * @return {number}\n */\n indexOfCharMap(bMapping)\n {\n for (var charCode in this.config.CHARMAP) {\n if (this.config.CHARMAP[charCode] == bMapping) return +charCode;\n }\n return 0;\n }\n\n /**\n * indexOfSoftKey(softCode)\n *\n * @this {Keyboard8080}\n * @param {number|string} softCode\n * @return {number} index of softCode in aKeysActive, or -1 if not found\n */\n indexOfSoftKey(softCode)\n {\n for (var i = 0; i < this.aKeysActive.length; i++) {\n if (this.aKeysActive[i].softCode == softCode) return i;\n }\n return -1;\n }\n\n /**\n * onSoftKeyDown(softCode, fDown, fAutoRelease)\n *\n * @this {Keyboard8080}\n * @param {number|string} softCode\n * @param {boolean} fDown is true for a down event, false for up\n * @param {boolean} [fAutoRelease] is true only if we know we want the key to auto-release\n * @return {boolean} true to pass the event along, false to consume it\n */\n onSoftKeyDown(softCode, fDown, fAutoRelease)\n {\n var i = this.indexOfSoftKey(softCode);\n if (fDown) {\n // this.println(softCode + \" down\");\n if (i < 0) {\n this.aKeysActive.push({\n softCode: softCode,\n msDown: Date.now(),\n fAutoRelease: fAutoRelease || false\n });\n } else {\n this.aKeysActive[i].msDown = Date.now();\n this.aKeysActive[i].fAutoRelease = fAutoRelease || false;\n }\n if (fAutoRelease) this.checkSoftKeysToRelease(); // prime the pump\n } else if (i >= 0) {\n // this.println(softCode + \" up\");\n if (!this.aKeysActive[i].fAutoRelease) {\n var msDown = this.aKeysActive[i].msDown;\n if (msDown) {\n var msElapsed = Date.now() - msDown;\n if (msElapsed < Keyboard8080.MINPRESSTIME) {\n // this.println(softCode + \" released after only \" + msElapsed + \"ms\");\n this.aKeysActive[i].fAutoRelease = true;\n this.checkSoftKeysToRelease();\n return true;\n }\n }\n }\n this.aKeysActive.splice(i, 1);\n } else {\n // this.println(softCode + \" up with no down?\");\n }\n\n if (this.chipset) {\n var bit = 0;\n switch(softCode) {\n case '1p':\n bit = ChipSet8080.SI1978.STATUS1.P1;\n break;\n case '2p':\n bit = ChipSet8080.SI1978.STATUS1.P2;\n break;\n case 'coin':\n bit = ChipSet8080.SI1978.STATUS1.CREDIT;\n break;\n case 'left':\n bit = ChipSet8080.SI1978.STATUS1.P1_LEFT;\n break;\n case 'right':\n bit = ChipSet8080.SI1978.STATUS1.P1_RIGHT;\n break;\n case 'fire':\n bit = ChipSet8080.SI1978.STATUS1.P1_FIRE;\n break;\n }\n if (bit) {\n this.chipset.updateStatus1(bit, fDown);\n }\n }\n return true;\n }\n\n /**\n * checkSoftKeysToRelease()\n *\n * @this {Keyboard8080}\n */\n checkSoftKeysToRelease()\n {\n var i = 0;\n var msDelayMin = -1;\n while (i < this.aKeysActive.length) {\n if (this.aKeysActive[i].fAutoRelease) {\n var softCode = this.aKeysActive[i].softCode;\n var msDown = this.aKeysActive[i].msDown;\n var msElapsed = Date.now() - msDown;\n var msDelay = Keyboard8080.MINPRESSTIME - msElapsed;\n if (msDelay > 0) {\n if (msDelayMin < 0 || msDelayMin > msDelay) {\n msDelayMin = msDelay;\n }\n } else {\n /*\n * Because the key is already in the auto-release state, this next call guarantees that the\n * key will be removed from the array; a consequence of that removal, however, is that we must\n * reset our array index to zero.\n */\n this.onSoftKeyDown(softCode, false);\n i = 0;\n continue;\n }\n }\n i++;\n }\n if (msDelayMin >= 0) {\n /*\n * Replaced the klunky browser setTimeout() call with our own timer service.\n *\n * var kbd = this;\n * setTimeout(function() { kbd.checkSoftKeysToRelease(); }, msDelayMin);\n */\n this.cpu.setTimer(this.timerReleaseKeys, msDelayMin);\n }\n }\n\n /**\n * isVT100TransmitterReady()\n *\n * Called whenever the VT100 ChipSet circuit needs the Keyboard UART's transmitter status.\n *\n * From p. 4-32 of the VT100 Technical Manual (July 1982):\n *\n * The operating clock for the keyboard interface comes from an address line in the video processor (LBA4).\n * This signal has an average period of 7.945 microseconds. Each data byte is transmitted with one start bit\n * and one stop bit, and each bit lasts 16 clock periods. The total time for each data byte is 160 times 7.945\n * or 1.27 milliseconds. Each time the Transmit Buffer Empty flag on the terminal's UART gets set (when the\n * current byte is being transmitted), the microprocessor loads another byte into the transmit buffer. In this\n * way, the stream of status bytes to the keyboard is continuous.\n *\n * We used to always return true (after all, what's wrong with an infinitely fast UART?), but unfortunately,\n * the VT100 firmware relies on the UART's slow transmission speed to drive cursor blink rate. We have several\n * options:\n *\n * 1) Snapshot the CPU cycle count each time a byte is transmitted (see outVT100UARTStatus()) and then every\n * time this is polled, see if the cycle count has exceeded the snapshot value by the necessary threshold;\n * if we assume 361.69ns per CPU cycle, there are 22 CPU cycles for every 1 LBA4 cycle, and since transmission\n * time is supposed to last for 160 LBA4 cycles, the threshold is 22*160 CPU cycles, or 3520 cycles.\n *\n * 2) Set a CPU timer using the new setTimer() interface, which can be passed the number of milliseconds to\n * wait before firing (in this case, roughly 1.27ms).\n *\n * 3) Call the ChipSet's getVT100LBA(4) function for the state of the simulated LBA4, and count 160 LBA4\n * transitions; however, that would be the worst solution, because there's no guarantee that the firmware's\n * UART polling will occur regularly and/or frequently enough for us to catch every LBA4 transition.\n *\n * I'm going with solution #1 because it's less overhead.\n *\n * @this {Keyboard8080}\n * @return {boolean} (true if ready, false if not)\n */\n isVT100TransmitterReady()\n {\n if (this.fVT100UARTBusy) {\n /*\n * NOTE: getMSCycles(1.2731488) should work out to 3520 cycles for a CPU clocked at 361.69ns per cycle,\n * which is roughly 2.76Mhz. We could just hard-code 3520 instead of calling getMSCycles(), but this helps\n * maintain a reasonable blink rate for the cursor even when the user cranks up the CPU speed.\n */\n if (this.cpu.getCycles() >= this.nVT100UARTCycleSnap + this.cpu.getMSCycles(1.2731488)) {\n this.fVT100UARTBusy = false;\n }\n }\n return !this.fVT100UARTBusy;\n }\n\n /**\n * inVT100UARTAddress(port, addrFrom)\n *\n * We take our cue from iKeyNext. If it's -1 (default), we simply return the last value latched\n * in bVT100Address. Otherwise, if iKeyNext is a valid index into aKeysActive, we look up the key\n * in the VT100.KEYMAP, latch it, and increment iKeyNext. Failing that, we latch Keyboard8080.VT100.KEYLAST\n * and reset iKeyNext to -1.\n *\n * @this {Keyboard8080}\n * @param {number} port (0x82)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n * @return {number} simulated port value\n */\n inVT100UARTAddress(port, addrFrom)\n {\n var b = this.bVT100Address;\n if (this.iKeyNext >= 0) {\n if (this.iKeyNext < this.aKeysActive.length) {\n var key = this.aKeysActive[this.iKeyNext];\n if (!MAXDEBUG) {\n this.iKeyNext++;\n } else {\n /*\n * In MAXDEBUG builds, this code removes the key as soon as it's been reported, because\n * when debugging, it's easy for the window to lose focus and never receive the keyUp event,\n * thereby leaving us with a stuck key. However, this may cause more problems than it solves,\n * because the VT100's ROM seems to require that key presses persist for more than a single poll.\n */\n this.aKeysActive.splice(this.iKeyNext, 1);\n }\n b = Keyboard8080.VT100.KEYMAP[key.softCode];\n if (b & 0x80) {\n /*\n * TODO: This code is supposed to be accompanied by a SHIFT key; make sure that it is.\n */\n b &= 0x7F;\n }\n } else {\n this.iKeyNext = -1;\n b = Keyboard8080.VT100.KEYLAST;\n }\n this.bVT100Address = b;\n this.cpu.requestINTR(1);\n }\n this.printMessageIO(port, null, addrFrom, \"KBDUART.ADDRESS\", b);\n return b;\n }\n\n /**\n * outVT100UARTStatus(port, b, addrFrom)\n *\n * @this {Keyboard8080}\n * @param {number} port (0x82)\n * @param {number} b\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outVT100UARTStatus(port, b, addrFrom)\n {\n this.printMessageIO(port, b, addrFrom, \"KBDUART.STATUS\");\n this.bVT100Status = b;\n this.fVT100UARTBusy = true;\n this.nVT100UARTCycleSnap = this.cpu.getCycles();\n this.updateLEDs(b & Keyboard8080.VT100.STATUS.LEDS);\n if (b & Keyboard8080.VT100.STATUS.START) {\n this.iKeyNext = 0;\n this.cpu.requestINTR(1);\n }\n }\n\n /**\n * Keyboard8080.init()\n *\n * This function operates on every HTML element of class \"keyboard\", extracting the\n * JSON-encoded parameters for the Keyboard constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Keyboard component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeKbd = Component.getElementsByClass(document, PC8080.APPCLASS, \"keyboard\");\n for (var iKbd = 0; iKbd < aeKbd.length; iKbd++) {\n var eKbd = aeKbd[iKbd];\n var parmsKbd = Component.getComponentParms(eKbd);\n var kbd = new Keyboard8080(parmsKbd);\n Component.bindComponentControls(kbd, eKbd, PC8080.APPCLASS);\n }\n }\n}\n\n/*\n * Now that we want to keep track of the physical (and simulated) state of modifier keys, I've\n * grabbed a copy of the same bit definitions used by /modules/pcx86/lib/keyboard.js, since it's\n * only important that we have a set of unique values; what the values are isn't critical.\n */\nKeyboard8080.STATE = {\n RSHIFT: 0x0001,\n SHIFT: 0x0002,\n SHIFTS: 0x0003,\n RCTRL: 0x0004, // 101-key keyboard only\n CTRL: 0x0008,\n CTRLS: 0x000C,\n RALT: 0x0010, // 101-key keyboard only\n ALT: 0x0020,\n ALTS: 0x0030,\n RCMD: 0x0040, // 101-key keyboard only\n CMD: 0x0080, // 101-key keyboard only\n CMDS: 0x00C0,\n ALL_RIGHT: 0x0055, // RSHIFT | RCTRL | RALT | RCMD\n ALL_SHIFT: 0x00FF, // SHIFT | RSHIFT | CTRL | RCTRL | ALT | RALT | CMD | RCMD\n INSERT: 0x0100, // TODO: Placeholder (we currently have no notion of any \"insert\" states)\n CAPS_LOCK: 0x0200,\n NUM_LOCK: 0x0400,\n SCROLL_LOCK: 0x0800,\n ALL_LOCKS: 0x0E00, // CAPS_LOCK | NUM_LOCK | SCROLL_LOCK\n REMAPPED: 0x1000\n};\n\nKeyboard8080.MINPRESSTIME = 50; // minimum milliseconds to wait before auto-releasing keys\n\n/**\n * Alternate keyCode mappings to support popular \"WASD\"-style directional-key mappings.\n *\n * TODO: ES6 computed property name support may now be in all mainstream browsers, allowing us to use\n * a simple object literal for this and all other object initializations.\n */\nKeyboard8080.WASDCODES = {};\nKeyboard8080.WASDCODES[Keys.ASCII.A] = Keys.KEYCODE.LEFT;\nKeyboard8080.WASDCODES[Keys.ASCII.D] = Keys.KEYCODE.RIGHT;\nKeyboard8080.WASDCODES[Keys.ASCII.L] = Keys.KEYCODE.SPACE;\n\n/*\n * Supported keyboard configurations.\n *\n * A word (or two) about SOFTCODES. Their main purpose is to provide a naming convention for machine-specific\n * controls, without tying us to any particular keyboard mapping. They are used in two main ways.\n *\n * First, if we have a binding to the machine's \"screen\", there will, at a minimum, be onkeydown and onkeyup\n * handlers attached to the screen, and those handlers will need to iterate through the SOFTCODES table, looking\n * for key codes that we care about and converting them to corresponding soft codes. Some machines, like\n * Space Invaders, will then act directly upon the soft code (eg, converting it to a machine-specific status bit).\n *\n * Second, a machine may have other bindings (eg, buttons) to one or more of these soft codes, and those bindings\n * will need to know which key codes they're supposed to generate. Some machines, like the VT100, will then use\n * another table (KEYMAP) to convert key codes into a machine-specific \"key addresses\".\n */\nKeyboard8080.SI1978 = {\n MODEL: 1978.1,\n KEYMAP: {},\n CHARMAP: {},\n ALTCODES: Keyboard8080.WASDCODES,\n LEDCODES: {},\n SOFTCODES: {\n '1p': Keys.KEYCODE.ONE,\n '2p': Keys.KEYCODE.TWO,\n 'coin': Keys.KEYCODE.THREE,\n 'left': Keys.KEYCODE.LEFT,\n 'right': Keys.KEYCODE.RIGHT,\n 'fire': Keys.KEYCODE.SPACE\n }\n};\n\nKeyboard8080.VT100 = {\n MODEL: 100.0,\n KEYMAP: {\n /*\n * Map of keydown keyCodes to VT100 key addresses (7-bit values representing key positions on the VT100).\n *\n * NOTE: The VT100 keyboard has both BACKSPACE and DELETE keys, whereas modern keyboards generally only\n * have DELETE. And sadly, when you press DELETE, your modern keyboard and/or modern browser is reporting\n * it as keyCode 8: the code for BACKSPACE, aka CTRL-H. You have to press a modified DELETE key to get\n * the actual DELETE keyCode of 127.\n *\n * We resolve this below by mapping KEYCODE.BS (8) to VT100 keyCode DELETE (0x03) and KEYCODE.DEL (127)\n * to VT100 keyCode BACKSPACE (0x33). So, DELETE is BACKSPACE and BACKSPACE is DELETE. Fortunately, this\n * confusion is all internal, because your physical key is (or should be) labeled DELETE, so the fact that\n * the browser is converting it to BACKSPACE and that we're converting BACKSPACE back into DELETE is\n * something most people don't need to worry their heads about.\n *\n * ES6 ALERT: As you can see below, I've finally started using computed property names.\n */\n [Keys.KEYCODE.BS]: 0x03,\n [Keys.ASCII.P]: 0x05,\n [Keys.ASCII.O]: 0x06,\n [Keys.ASCII.Y]: 0x07,\n [Keys.ASCII.T]: 0x08,\n [Keys.ASCII.W]: 0x09,\n [Keys.ASCII.Q]: 0x0A,\n [Keys.KEYCODE.RIGHT]: 0x10,\n [Keys.KEYCODE.RBRACK]: 0x14,\n [Keys.KEYCODE.LBRACK]: 0x15,\n [Keys.ASCII.I]: 0x16,\n [Keys.ASCII.U]: 0x17,\n [Keys.ASCII.R]: 0x18,\n [Keys.ASCII.E]: 0x19,\n [Keys.KEYCODE.ONE]: 0x1A,\n [Keys.KEYCODE.LEFT]: 0x20,\n [Keys.KEYCODE.DOWN]: 0x22,\n [Keys.KEYCODE.F6]: 0x23, // aka BREAK\n [Keys.KEYCODE.PAUSE]: 0x23, // aka BREAK\n [Keys.KEYCODE.BQUOTE]: 0x24,\n [Keys.KEYCODE.DASH]: 0x25,\n [Keys.KEYCODE.NINE]: 0x26,\n [Keys.KEYCODE.SEVEN]: 0x27,\n [Keys.KEYCODE.FOUR]: 0x28,\n [Keys.KEYCODE.THREE]: 0x29,\n [Keys.KEYCODE.ESC]: 0x2A,\n [Keys.KEYCODE.UP]: 0x30,\n [Keys.KEYCODE.F3]: 0x31, // aka PF3\n [Keys.KEYCODE.F1]: 0x32, // aka PF1\n [Keys.KEYCODE.DEL]: 0x33,\n [Keys.KEYCODE.EQUALS]: 0x34,\n [Keys.KEYCODE.ZERO]: 0x35,\n [Keys.KEYCODE.EIGHT]: 0x36,\n [Keys.KEYCODE.SIX]: 0x37,\n [Keys.KEYCODE.FIVE]: 0x38,\n [Keys.KEYCODE.TWO]: 0x39,\n [Keys.KEYCODE.TAB]: 0x3A,\n [Keys.KEYCODE.NUM_7]: 0x40,\n [Keys.KEYCODE.F4]: 0x41, // aka PF4\n [Keys.KEYCODE.F2]: 0x42, // aka PF2\n [Keys.KEYCODE.NUM_0]: 0x43,\n [Keys.KEYCODE.F7]: 0x44, // aka LINE-FEED\n [Keys.KEYCODE.BSLASH]: 0x45,\n [Keys.ASCII.L]: 0x46,\n [Keys.ASCII.K]: 0x47,\n [Keys.ASCII.G]: 0x48,\n [Keys.ASCII.F]: 0x49,\n [Keys.ASCII.A]: 0x4A,\n [Keys.KEYCODE.NUM_8]: 0x50,\n [Keys.KEYCODE.NUM_CR]: 0x51,\n [Keys.KEYCODE.NUM_2]: 0x52,\n [Keys.KEYCODE.NUM_1]: 0x53,\n [Keys.KEYCODE.QUOTE]: 0x55,\n [Keys.KEYCODE.SEMI]: 0x56,\n [Keys.ASCII.J]: 0x57,\n [Keys.ASCII.H]: 0x58,\n [Keys.ASCII.D]: 0x59,\n [Keys.ASCII.S]: 0x5A,\n [Keys.KEYCODE.NUM_DEL]: 0x60, // keypad period\n [Keys.KEYCODE.F5]: 0x61, // aka KEYPAD COMMA\n [Keys.KEYCODE.NUM_5]: 0x62,\n [Keys.KEYCODE.NUM_4]: 0x63,\n [Keys.KEYCODE.CR]: 0x64, // TODO: Figure out why the Technical Manual lists CR at both 0x04 and 0x64\n [Keys.KEYCODE.PERIOD]: 0x65,\n [Keys.KEYCODE.COMMA]: 0x66,\n [Keys.ASCII.N]: 0x67,\n [Keys.ASCII.B]: 0x68,\n [Keys.ASCII.X]: 0x69,\n [Keys.KEYCODE.F8]: 0x6A, // aka NO-SCROLL\n [Keys.KEYCODE.NUM_9]: 0x70,\n [Keys.KEYCODE.NUM_3]: 0x71,\n [Keys.KEYCODE.NUM_6]: 0x72,\n [Keys.KEYCODE.NUM_SUB]: 0x73, // aka KEYPAD MINUS\n [Keys.KEYCODE.SLASH]: 0x75,\n [Keys.ASCII.M]: 0x76,\n [Keys.ASCII[' ']]: 0x77,\n [Keys.ASCII.V]: 0x78,\n [Keys.ASCII.C]: 0x79,\n [Keys.ASCII.Z]: 0x7A,\n [Keys.KEYCODE.F9]: 0x7B, // aka SET-UP\n [Keys.KEYCODE.CTRL]: 0x7C,\n [Keys.KEYCODE.SHIFT]: 0x7D, // either shift key (doesn't matter)\n [Keys.KEYCODE.CAPS_LOCK]:0x7E\n },\n CHARMAP: {\n /*\n * Map of keypress charCodes to VT100 key addresses (7-bit values representing key positions on the VT100);\n * the 8th bit (0x80) is set for keys that need to be shifted.\n *\n * This is currently used only with the iOS keypress handler, which processes character codes rather than\n * keyboard codes. As a result, this table is not as complete as the KEYMAP table, since certain keys are\n * not delivered as key presses (eg, BACKSPACE) and/or are simply not present on the iOS keyboard (eg, ESC,\n * arrow keys). Also, SPACE had to be removed from the CHARMAP table as well, because otherwise it causes\n * the entire page to scroll down (you have to wonder who thought THAT was a good idea).\n *\n * ES6 ALERT: As you can see below, I've finally started using computed property names.\n */\n [Keys.ASCII.p]: 0x05,\n [Keys.ASCII.o]: 0x06,\n [Keys.ASCII.y]: 0x07,\n [Keys.ASCII.t]: 0x08,\n [Keys.ASCII.w]: 0x09,\n [Keys.ASCII.q]: 0x0A,\n [Keys.ASCII[']']]: 0x14,\n [Keys.ASCII['[']]: 0x15,\n [Keys.ASCII.i]: 0x16,\n [Keys.ASCII.u]: 0x17,\n [Keys.ASCII.r]: 0x18,\n [Keys.ASCII.e]: 0x19,\n [Keys.ASCII['1']]: 0x1A,\n [Keys.ASCII['`']]: 0x24,\n [Keys.ASCII['-']]: 0x25,\n [Keys.ASCII['9']]: 0x26,\n [Keys.ASCII['7']]: 0x27,\n [Keys.ASCII['4']]: 0x28,\n [Keys.ASCII['3']]: 0x29,\n [Keys.ASCII['=']]: 0x34,\n [Keys.ASCII['0']]: 0x35,\n [Keys.ASCII['8']]: 0x36,\n [Keys.ASCII['6']]: 0x37,\n [Keys.ASCII['5']]: 0x38,\n [Keys.ASCII['2']]: 0x39,\n [Keys.ASCII['\\\\']]: 0x45,\n [Keys.ASCII.l]: 0x46,\n [Keys.ASCII.k]: 0x47,\n [Keys.ASCII.g]: 0x48,\n [Keys.ASCII.f]: 0x49,\n [Keys.ASCII.a]: 0x4A,\n [Keys.ASCII[\"'\"]]: 0x55,\n [Keys.ASCII[';']]: 0x56,\n [Keys.ASCII.j]: 0x57,\n [Keys.ASCII.h]: 0x58,\n [Keys.ASCII.d]: 0x59,\n [Keys.ASCII.s]: 0x5A,\n [Keys.KEYCODE.CR]: 0x64, // TODO: Figure out why the Technical Manual lists CR at both 0x04 and 0x64\n [Keys.ASCII['.']]: 0x65,\n [Keys.ASCII[',']]: 0x66,\n [Keys.ASCII.n]: 0x67,\n [Keys.ASCII.b]: 0x68,\n [Keys.ASCII.x]: 0x69,\n [Keys.ASCII['/']]: 0x75,\n [Keys.ASCII.m]: 0x76,\n // [Keys.ASCII[' ']]: 0x77, // as noted above, we need to process SPACE at keydown rather than keypress\n [Keys.ASCII.v]: 0x78,\n [Keys.ASCII.c]: 0x79,\n [Keys.ASCII.z]: 0x7A,\n [Keys.ASCII.P]: 0x85,\n [Keys.ASCII.O]: 0x86,\n [Keys.ASCII.Y]: 0x87,\n [Keys.ASCII.T]: 0x88,\n [Keys.ASCII.W]: 0x89,\n [Keys.ASCII.Q]: 0x8A,\n [Keys.ASCII['}']]: 0x94,\n [Keys.ASCII['{']]: 0x95,\n [Keys.ASCII.I]: 0x96,\n [Keys.ASCII.U]: 0x97,\n [Keys.ASCII.R]: 0x98,\n [Keys.ASCII.E]: 0x99,\n [Keys.ASCII['!']]: 0x9A,\n [Keys.ASCII['~']]: 0xA4,\n [Keys.ASCII['_']]: 0xA5,\n [Keys.ASCII['(']]: 0xA6,\n [Keys.ASCII['&']]: 0xA7,\n [Keys.ASCII['$']]: 0xA8,\n [Keys.ASCII['#']]: 0xA9,\n [Keys.ASCII['+']]: 0xB4,\n [Keys.ASCII[')']]: 0xB5,\n [Keys.ASCII['*']]: 0xB6,\n [Keys.ASCII['^']]: 0xB7,\n [Keys.ASCII['%']]: 0xB8,\n [Keys.ASCII['@']]: 0xB9,\n [Keys.ASCII['|']]: 0xC5,\n [Keys.ASCII.L]: 0xC6,\n [Keys.ASCII.K]: 0xC7,\n [Keys.ASCII.G]: 0xC8,\n [Keys.ASCII.F]: 0xC9,\n [Keys.ASCII.A]: 0xCA,\n [Keys.ASCII['\"']]: 0xD5,\n [Keys.ASCII[':']]: 0xD6,\n [Keys.ASCII.J]: 0xD7,\n [Keys.ASCII.H]: 0xD8,\n [Keys.ASCII.D]: 0xD9,\n [Keys.ASCII.S]: 0xDA,\n [Keys.ASCII['>']]: 0xE5,\n [Keys.ASCII['<']]: 0xE6,\n [Keys.ASCII.N]: 0xE7,\n [Keys.ASCII.B]: 0xE8,\n [Keys.ASCII.X]: 0xE9,\n [Keys.ASCII['?']]: 0xF5,\n [Keys.ASCII.M]: 0xF6,\n [Keys.ASCII.V]: 0xF8,\n [Keys.ASCII.C]: 0xF9,\n [Keys.ASCII.Z]: 0xFA\n },\n ALTCODES: {},\n LEDCODES: {},\n SOFTCODES: {\n 'caps-lock': Keys.KEYCODE.CAPS_LOCK,\n 'ctrl': Keys.KEYCODE.CTRL,\n 'esc': Keys.KEYCODE.ESC,\n 'tab': Keys.KEYCODE.TAB,\n 'num-comma': Keys.KEYCODE.F5, // since modern keypads don't typically have a comma...\n 'break': Keys.KEYCODE.F6,\n 'line-feed': Keys.KEYCODE.F7,\n 'no-scroll': Keys.KEYCODE.F8,\n 'setup': Keys.KEYCODE.F9\n },\n /*\n * Reading port 0x82 returns a key address from the VT100 keyboard's UART data output.\n *\n * Every time a keyboard scan is initiated (by setting the START bit of the status byte),\n * our internal address index (iKeyNext) is set to zero, and an interrupt is generated for\n * each entry in the aKeysActive array, along with a final interrupt for KEYLAST.\n */\n ADDRESS: {\n PORT: 0x82,\n INIT: 0x7F\n },\n /*\n * Writing port 0x82 updates the VT100's keyboard status byte via the keyboard's UART data input.\n */\n STATUS: {\n PORT: 0x82, // write-only\n LED4: 0x01,\n LED3: 0x02,\n LED2: 0x04,\n LED1: 0x08,\n LOCKED: 0x10,\n LOCAL: 0x20,\n LEDS: 0x3F, // all LEDs\n START: 0x40, // set to initiate a scan\n /*\n * From p. 4-38 of the VT100 Technical Manual (July 1982):\n *\n * A bit (CLICK) in the keyboard status word controls the bell.... When a single status word contains\n * the bell bit, flip-flop E3 toggles and turns on E1, generating a click. If the bell bit is set for\n * many words in succession, the UART latch holds the data output constant..., allowing the circuit to\n * produce an 800 hertz tone. Bell is generated by setting the bell bit for 0.25 seconds. Each cycle of\n * the tone is at a reduced amplitude compared with the single keyclick.... The overall effect of the\n * tone burst on the ear is that of a beep.\n */\n CLICK: 0x80,\n INIT: 0x00\n },\n KEYLAST: 0x7F // special end-of-scan key address (all valid key addresses are < KEYLAST)\n};\n\nKeyboard8080.VT100.LEDCODES = {\n 'l4': Keyboard8080.VT100.STATUS.LED4,\n 'l3': Keyboard8080.VT100.STATUS.LED3,\n 'l2': Keyboard8080.VT100.STATUS.LED2,\n 'l1': Keyboard8080.VT100.STATUS.LED1,\n 'locked': Keyboard8080.VT100.STATUS.LOCKED,\n 'local': Keyboard8080.VT100.STATUS.LOCAL,\n 'online': ~Keyboard8080.VT100.STATUS.LOCAL,\n 'caps-lock':Keyboard8080.STATE.CAPS_LOCK\n};\n\n/*\n * Supported models and their configurations\n */\nKeyboard8080.MODELS = {\n \"SI1978\": Keyboard8080.SI1978,\n \"VT100\": Keyboard8080.VT100\n};\n\nKeyboard8080.VT100.INIT = [\n [\n Keyboard8080.VT100.STATUS.INIT, // bVT100Status\n Keyboard8080.VT100.ADDRESS.INIT, // bVT100Address\n false, // fVT100UARTBusy\n 0, // nVT100UARTCycleSnap\n -1 // iKeyNext\n ]\n];\n\n/*\n * Port notification tables\n */\nKeyboard8080.VT100.portsInput = {\n 0x82: Keyboard8080.prototype.inVT100UARTAddress\n};\n\nKeyboard8080.VT100.portsOutput = {\n 0x82: Keyboard8080.prototype.outVT100UARTStatus\n};\n\n/*\n * Initialize every Keyboard module on the page.\n */\nWeb.onInit(Keyboard8080.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/video.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass Video8080 extends Component {\n /**\n * Video8080(parmsVideo, canvas, context, textarea, container)\n *\n * The Video8080 component can be configured with the following (parmsVideo) properties:\n *\n * screenWidth: width of the screen canvas, in pixels\n * screenHeight: height of the screen canvas, in pixels\n * screenColor: background color of the screen canvas (default is black)\n * screenRotate: the amount of counter-clockwise screen rotation required (eg, -90 or 270)\n * aspectRatio (eg, 1.33)\n * bufferAddr: the starting address of the frame buffer (eg, 0x2400)\n * bufferRAM: true to use existing RAM (default is false)\n * bufferFormat: if defined, one of the recognized formats in Video8080.FORMATS (eg, \"vt100\")\n * bufferCols: the width of a single frame buffer row, in pixels (eg, 256)\n * bufferRows: the number of frame buffer rows (eg, 224)\n * bufferBits: the number of bits per column (default is 1)\n * bufferLeft: the bit position of the left-most pixel in a byte (default is 0; CGA uses 7)\n * bufferRotate: the amount of counter-clockwise buffer rotation required (eg, -90 or 270)\n * interruptRate: normally the same as (or some multiple of) refreshRate (eg, 120)\n * refreshRate: how many times updateScreen() should be performed per second (eg, 60)\n *\n * In addition, if a text-only display is being emulated, define the following properties:\n *\n * fontROM: URL of font ROM\n * fontColor: default is white\n * cellWidth: number (eg, 10 for VT100)\n * cellHeight: number (eg, 10 for VT100)\n *\n * We record all the above values now, but we defer creation of the frame buffer until our initBus()\n * handler is called. At that point, we will also compute the extent of the frame buffer, determine the\n * appropriate \"cell\" size (ie, the number of pixels that updateScreen() will fetch and process at once),\n * and then allocate our cell cache.\n *\n * Why interruptRate in addition to refreshRate? A higher interrupt rate is required for Space Invaders,\n * because even though the CRT refreshes at 60Hz, the CRT controller interrupts the CPU *twice* per\n * refresh (once after the top half of the screen has been redrawn, and again after the bottom half has\n * been redrawn), so we need an interrupt rate of 120Hz. We pass the higher rate on to the CPU, so that\n * it will call updateScreen() more frequently, but we still limit our screen updates to every *other* call.\n *\n * bufferRotate is an alternative to screenRotate; you may set one or the other (but not both) to -90 to\n * enable different approaches to counter-clockwise 90-degree image rotation. screenRotate uses canvas\n * transformation methods (translate(), rotate(), and scale()), while bufferRotate inverts the dimensions\n * of the off-screen buffer and then relies on setPixel() to \"rotate\" the data into the proper location.\n *\n * @this {Video8080}\n * @param {Object} parmsVideo\n * @param {Object} [canvas]\n * @param {Object} [context]\n * @param {Object} [textarea]\n * @param {Object} [container]\n */\n constructor(parmsVideo, canvas, context, textarea, container)\n {\n super(\"Video\", parmsVideo, Messages8080.VIDEO);\n\n var video = this, sProp, sEvent;\n this.fGecko = Web.isUserAgent(\"Gecko/\");\n\n this.cxScreen = parmsVideo['screenWidth'];\n this.cyScreen = parmsVideo['screenHeight'];\n\n this.addrBuffer = parmsVideo['bufferAddr'];\n this.fUseRAM = parmsVideo['bufferRAM'];\n\n var sFormat = parmsVideo['bufferFormat'];\n this.nFormat = sFormat && Video8080.FORMATS[sFormat.toUpperCase()] || Video8080.FORMAT.UNKNOWN;\n\n this.nColsBuffer = parmsVideo['bufferCols'];\n this.nRowsBuffer = parmsVideo['bufferRows'];\n\n this.cxCellDefault = this.cxCell = parmsVideo['cellWidth'] || 1;\n this.cyCellDefault = this.cyCell = parmsVideo['cellHeight'] || 1;\n this.abFontData = null;\n this.fDotStretcher = false;\n\n this.nBitsPerPixel = parmsVideo['bufferBits'] || 1;\n this.iBitFirstPixel = parmsVideo['bufferLeft'] || 0;\n\n this.rotateBuffer = parmsVideo['bufferRotate'];\n if (this.rotateBuffer) {\n this.rotateBuffer = this.rotateBuffer % 360;\n if (this.rotateBuffer > 0) this.rotateBuffer -= 360;\n if (this.rotateBuffer != -90) {\n this.notice(\"unsupported buffer rotation: \" + this.rotateBuffer);\n this.rotateBuffer = 0;\n }\n }\n\n this.rateInterrupt = parmsVideo['interruptRate'];\n this.rateRefresh = parmsVideo['refreshRate'] || 60;\n\n this.canvasScreen = canvas;\n this.contextScreen = context;\n this.textareaScreen = textarea;\n this.inputScreen = textarea || canvas || null;\n\n /*\n * These variables are here in case we want/need to add support for borders later...\n */\n this.xScreenOffset = this.yScreenOffset = 0;\n this.cxScreenOffset = this.cxScreen;\n this.cyScreenOffset = this.cyScreen;\n\n this.cxScreenCell = (this.cxScreen / this.nColsBuffer)|0;\n this.cyScreenCell = (this.cyScreen / this.nRowsBuffer)|0;\n\n /*\n * Now that we've finished using nRowsBuffer to help define the screen size, we add one more\n * row for text modes, to account for the VT100's scroll line buffer (used for smooth scrolling).\n */\n if (this.cyCell > 1) {\n this.nRowsBuffer++;\n this.bScrollOffset = 0;\n this.fSkipSingleCellUpdate = false;\n }\n\n /*\n * Support for disabling (or, less commonly, enabling) image smoothing, which all browsers\n * seem to support now (well, OK, I still have to test the latest MS Edge browser), despite\n * it still being labelled \"experimental technology\". Let's hope the browsers standardize\n * on this. I see other options emerging, like the CSS property \"image-rendering: pixelated\"\n * that's apparently been added to Chrome. Sigh.\n */\n var fSmoothing = parmsVideo['smoothing'];\n var sSmoothing = Web.getURLParm('smoothing');\n if (sSmoothing) fSmoothing = (sSmoothing == \"true\");\n if (fSmoothing != null) {\n sProp = Web.findProperty(this.contextScreen, 'imageSmoothingEnabled');\n if (sProp) this.contextScreen[sProp] = fSmoothing;\n }\n\n this.rotateScreen = parmsVideo['screenRotate'];\n if (this.rotateScreen) {\n this.rotateScreen = this.rotateScreen % 360;\n if (this.rotateScreen > 0) this.rotateScreen -= 360;\n /*\n * TODO: Consider also disallowing any rotateScreen value if bufferRotate was already set; setting\n * both is most likely a mistake, but who knows, maybe someone wants to use both for 180-degree rotation?\n */\n if (this.rotateScreen != -90) {\n this.notice(\"unsupported screen rotation: \" + this.rotateScreen);\n this.rotateScreen = 0;\n } else {\n this.contextScreen.translate(0, this.cyScreen);\n this.contextScreen.rotate((this.rotateScreen * Math.PI)/180);\n this.contextScreen.scale(this.cyScreen/this.cxScreen, this.cxScreen/this.cyScreen);\n }\n }\n\n /*\n * Here's the gross code to handle full-screen support across all supported browsers. The lack of standards\n * is exasperating; browsers can't agree on 'Fullscreen' (most common) or 'FullScreen' (least common), and while\n * some browsers honor other browser prefixes, most don't. Event handlers tend to be more consistent (ie, all\n * lower-case).\n */\n this.container = container;\n if (this.container) {\n sProp = Web.findProperty(container, 'requestFullscreen') || Web.findProperty(container, 'requestFullScreen');\n if (sProp) {\n this.container.doFullScreen = container[sProp];\n sEvent = Web.findProperty(document, 'on', 'fullscreenchange');\n if (sEvent) {\n var sFullScreen = Web.findProperty(document, 'fullscreenElement') || Web.findProperty(document, 'fullScreenElement');\n document.addEventListener(sEvent, function onFullScreenChange() {\n video.notifyFullScreen(!!sFullScreen);\n }, false);\n }\n sEvent = Web.findProperty(document, 'on', 'fullscreenerror');\n if (sEvent) {\n document.addEventListener(sEvent, function onFullScreenError() {\n video.notifyFullScreen(null);\n }, false);\n }\n }\n }\n\n this.sFontROM = parmsVideo['fontROM'];\n if (this.sFontROM) {\n var sFileExt = Str.getExtension(this.sFontROM);\n if (sFileExt != \"json\") {\n this.sFontROM = Web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFontROM + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES;\n }\n Web.getResource(this.sFontROM, null, true, function(sURL, sResponse, nErrorCode) {\n video.doneLoad(sURL, sResponse, nErrorCode);\n });\n }\n\n this.ledBindings = {};\n }\n\n /**\n * initBuffers()\n *\n * @this {Video8080}\n * @return {boolean}\n */\n initBuffers()\n {\n /*\n * Allocate off-screen buffers now\n */\n this.cxBuffer = this.nColsBuffer * this.cxCell;\n this.cyBuffer = this.nRowsBuffer * this.cyCell;\n\n var cxBuffer = this.cxBuffer;\n var cyBuffer = this.cyBuffer;\n if (this.rotateBuffer) {\n cxBuffer = this.cyBuffer;\n cyBuffer = this.cxBuffer;\n }\n\n this.sizeBuffer = 0;\n if (!this.fUseRAM) {\n this.sizeBuffer = ((this.cxBuffer * this.nBitsPerPixel) >> 3) * this.cyBuffer;\n if (!this.bus.addMemory(this.addrBuffer, this.sizeBuffer, Memory8080.TYPE.VIDEO)) {\n return false;\n }\n }\n\n /*\n * imageBuffer is only used for graphics modes. For text modes, we create a canvas\n * for each font and draw characters by drawing from the font canvas to the target canvas.\n */\n if (this.sizeBuffer) {\n this.imageBuffer = this.contextScreen.createImageData(cxBuffer, cyBuffer);\n this.nPixelsPerCell = (16 / this.nBitsPerPixel)|0;\n this.initCellCache(this.sizeBuffer >> 1);\n } else {\n /*\n * We add an extra column per row to store the visible line length at the start of every row.\n */\n this.initCellCache((this.nColsBuffer + 1) * this.nRowsBuffer);\n }\n\n this.canvasBuffer = document.createElement(\"canvas\");\n this.canvasBuffer.width = cxBuffer;\n this.canvasBuffer.height = cyBuffer;\n this.contextBuffer = this.canvasBuffer.getContext(\"2d\");\n\n this.aFonts = {};\n this.initColors();\n\n if (this.nFormat == Video8080.FORMAT.VT100) {\n /*\n * Beyond fonts, VT100 support requires that we maintain a number of additional properties:\n *\n * rateMonitor: must be either 50 or 60 (defaults to 60); we don't emulate the monitor refresh rate,\n * but we do need to keep track of which rate has been selected, because that affects the number of\n * \"fill lines\" present at the top of the VT100's frame buffer: 2 lines for 60Hz, 5 lines for 50Hz.\n *\n * The VT100 July 1982 Technical Manual, p. 4-89, shows the following sample frame buffer layout:\n *\n * 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n * --------------------------------------------------------------\n * 0x2000: 7F 70 03 7F F2 D0 7F 70 06 7F 70 0C 7F 70 0F 7F\n * 0x2010: 70 03 .. .. .. .. .. .. .. .. .. .. .. .. .. ..\n * ...\n * 0x22D0: 'D' 'A' 'T' 'A' ' ' 'F' 'O' 'R' ' ' 'F' 'I' 'R' 'S' 'T' ' ' 'L'\n * 0x22E0: 'I' 'N' 'E' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '\n * ...\n * 0x2320: 7F F3 23 'D' 'A' 'T' 'A' ' ' 'F' 'O' 'R' ' ' 'S' 'E' 'C' 'O'\n * 0x2330: 'N' 'D' ' ' 'L' 'I' 'N' 'E' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '\n * ...\n * 0x2BE0: ' ' ' ' 'E' 'N' 'D' ' ' 'O' 'F' ' ' 'L' 'A' 'S' 'T' ' ' 'L' 'I'\n * 0x2BF0: 'N' 'E' 7F 70 06 .. .. .. .. .. .. .. .. .. .. ..\n * 0x2C00: [AVO SCREEN RAM, IF ANY, BEGINS HERE]\n *\n * ERRATA: The manual claims that if you change the byte at 0x2002 from 03 to 09, the number of \"fill\n * lines\" will change from 2 to 5 (for 50Hz operation), but it shows 06 instead of 0C at location 0x200B;\n * if you follow the links, it's pretty clear that byte has to be 0C to yield 5 \"fill lines\". Since the\n * address following the terminator at 0x2006 points to itself, it never makes sense for that terminator\n * to be used EXCEPT at the end of the frame buffer.\n *\n * As an alternative to tracking the monitor refresh rate, we could hard-code some knowledge about how\n * the VT100's 8080 code uses memory, and simply ignore lines below address 0x22D0. But the VT100 Video\n * Processor makes no such assumption, and it would also break our test code in createFonts(), which\n * builds a contiguous screen of test data starting at the default frame buffer address (0x2000).\n */\n this.rateMonitor = 60;\n\n /*\n * The default character-selectable attribute (reverse video vs. underline) is controlled by fUnderline.\n */\n this.fUnderline = false;\n\n this.abLineBuffer = new Array(this.nColsBuffer);\n }\n return true;\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {Video8080}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"refresh\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var video = this;\n\n /*\n * TODO: A more general-purpose binding mechanism would be nice someday....\n */\n if (sHTMLType == \"led\" || sHTMLType == \"rled\") {\n this.ledBindings[sBinding] = control;\n return true;\n }\n\n switch (sBinding) {\n case \"fullScreen\":\n this.bindings[sBinding] = control;\n if (this.container && this.container.doFullScreen) {\n control.onclick = function onClickFullScreen() {\n if (DEBUG) video.printMessage(\"fullScreen()\");\n video.doFullScreen();\n };\n } else {\n if (DEBUG) this.log(\"FullScreen API not available\");\n control.parentNode.removeChild(/** @type {Node} */ (control));\n }\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {Video8080}\n * @param {Computer8080} cmp\n * @param {Bus8080} bus\n * @param {CPUState8080} cpu\n * @param {Debugger8080} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n /*\n * Allocate the frame buffer (as needed) along with all other buffers.\n */\n this.initBuffers();\n\n /*\n * If we have an associated keyboard, then ensure that the keyboard will be notified\n * whenever the canvas gets focus and receives input.\n */\n this.kbd = /** @type {Keyboard8080} */ (cmp.getMachineComponent(\"Keyboard\"));\n if (this.kbd) {\n for (var s in this.ledBindings) {\n this.kbd.setBinding(\"led\", s, this.ledBindings[s]);\n }\n if (this.canvasScreen) {\n this.kbd.setBinding(this.textareaScreen? \"textarea\" : \"canvas\", \"screen\", /** @type {HTMLElement} */ (this.inputScreen));\n }\n }\n\n var video = this;\n this.timerUpdateNext = this.cpu.addTimer(this.id, function() {\n video.updateScreen();\n });\n this.cpu.setTimer(this.timerUpdateNext, this.getRefreshTime());\n this.nUpdates = 0;\n\n if (!this.sFontROM) this.setReady();\n }\n\n /**\n * doneLoad(sURL, sFontData, nErrorCode)\n *\n * @this {Video8080}\n * @param {string} sURL\n * @param {string} sFontData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n doneLoad(sURL, sFontData, nErrorCode)\n {\n if (nErrorCode) {\n this.notice(\"Unable to load font ROM (error \" + nErrorCode + \": \" + sURL + \")\");\n return;\n }\n\n Component.addMachineResource(this.idMachine, sURL, sFontData);\n\n try {\n /*\n * The most likely source of any exception will be here: parsing the JSON-encoded data.\n */\n var ab = eval(\"(\" + sFontData + \")\");\n\n var abFontData = ab['bytes'] || ab;\n\n if (!abFontData || !abFontData.length) {\n Component.error(\"Empty font ROM: \" + sURL);\n return;\n }\n else if (abFontData.length == 1) {\n Component.error(abFontData[0]);\n return;\n }\n\n /*\n * Minimal font data validation, just to make sure we're not getting garbage from the server.\n */\n if (abFontData.length == 2048) {\n this.abFontData = abFontData;\n this.createFonts();\n }\n else {\n this.notice(\"Unrecognized font data length (\" + abFontData.length + \")\");\n return;\n }\n\n } catch (e) {\n this.notice(\"Font ROM data error: \" + e.message);\n return;\n }\n\n /*\n * If we're still here, then we're ready!\n *\n * UPDATE: Per issue #21, I'm issuing setReady() *only* if a valid contextScreen exists *or* a Debugger is attached.\n *\n * TODO: Consider a more general-purpose solution for deciding whether or not the user wants to run in a \"headless\" mode.\n */\n if (this.contextScreen || this.dbg) this.setReady();\n }\n\n /**\n * createFonts()\n *\n * @this {Video8080}\n * @return {boolean}\n */\n createFonts()\n {\n /*\n * We retain abFontData in case we have to rebuild the fonts (eg, when we switch from 80 to 132 columns)\n */\n if (this.abFontData) {\n this.fDotStretcher = (this.nFormat == Video8080.FORMAT.VT100);\n this.aFonts[Video8080.VT100.FONT.NORML] = [\n this.createFontVariation(this.cxCell, this.cyCell),\n this.createFontVariation(this.cxCell, this.cyCell, this.fUnderline)\n ];\n this.aFonts[Video8080.VT100.FONT.DWIDE] = [\n this.createFontVariation(this.cxCell*2, this.cyCell),\n this.createFontVariation(this.cxCell*2, this.cyCell, this.fUnderline)\n ];\n this.aFonts[Video8080.VT100.FONT.DHIGH] = this.aFonts[Video8080.VT100.FONT.DHIGH_BOT] = [\n this.createFontVariation(this.cxCell*2, this.cyCell*2),\n this.createFontVariation(this.cxCell*2, this.cyCell*2, this.fUnderline)\n ];\n return true;\n }\n return false;\n }\n\n /**\n * createFontVariation(cxCell, cyCell, fUnderline)\n *\n * This creates a 16x16 character grid for the requested font variation. Variations include:\n *\n * 1) no variation (cell size is this.cxCell x this.cyCell)\n * 2) double-wide characters (cell size is this.cxCell*2 x this.cyCell)\n * 3) double-high double-wide characters (cell size is this.cxCell*2 x this.cyCell*2)\n * 4) any of the above with either reverse video or underline enabled (default is neither)\n *\n * @this {Video8080}\n * @param {number} cxCell is the target width of each character in the grid\n * @param {number} cyCell is the target height of each character in the grid\n * @param {boolean} [fUnderline] (null for unmodified font, false for reverse video, true for underline)\n * @return {Object}\n */\n createFontVariation(cxCell, cyCell, fUnderline)\n {\n /*\n * On a VT100, cxCell,cyCell is initially 10,10, but may change to 9,10 for 132-column mode.\n */\n\n\n\n /*\n * Create a font canvas that is both 16 times the target character width and the target character height,\n * ensuring that it will accommodate 16x16 characters (for a maximum of 256). Note that the VT100 font ROM\n * defines only 128 characters, so that canvas will contain only 16x8 entries.\n */\n var nFontBytesPerChar = this.cxCellDefault <= 8? 8 : 16;\n var nFontByteOffset = nFontBytesPerChar > 8? 15 : 0;\n var nChars = this.abFontData.length / nFontBytesPerChar;\n\n /*\n * The absence of a boolean for fUnderline means that both fReverse and fUnderline are \"falsey\". The presence\n * of a boolean means that fReverse will be true OR fUnderline will be true, but NOT both.\n */\n var fReverse = (fUnderline === false);\n\n var font = {cxCell: cxCell, cyCell: cyCell};\n font.canvas = document.createElement(\"canvas\");\n font.canvas.width = cxCell * 16;\n font.canvas.height = cyCell * (nChars / 16);\n font.context = font.canvas.getContext(\"2d\");\n\n var imageChar = font.context.createImageData(cxCell, cyCell);\n\n for (var iChar = 0; iChar < nChars; iChar++) {\n for (var y = 0, yDst = y; y < this.cyCell; y++) {\n var offFontData = iChar * nFontBytesPerChar + ((nFontByteOffset + y) & (nFontBytesPerChar - 1));\n var bits = (fUnderline && y == 8? 0xff : this.abFontData[offFontData]);\n for (var nRows = 0; nRows < (cyCell / this.cyCell); nRows++) {\n var bitPrev = 0;\n for (var x = 0, xDst = x; x < this.cxCell; x++) {\n /*\n * While x goes from 0 to cxCell-1, obviously we will run out of bits after x is 7;\n * since the final bit must be replicated all the way to the right edge of the cell\n * (so that line-drawing characters seamlessly connect), we ensure that the effective\n * shift count remains stuck at 7 once it reaches 7.\n */\n var bitReal = bits & (0x80 >> (x > 7? 7 : x));\n var bit = (this.fDotStretcher && !bitReal && bitPrev)? bitPrev : bitReal;\n for (var nCols = 0; nCols < (cxCell / this.cxCell); nCols++) {\n if (fReverse) bit = !bit;\n this.setPixel(imageChar, xDst, yDst, bit? 1 : 0);\n xDst++;\n }\n bitPrev = bitReal;\n }\n yDst++;\n }\n }\n /*\n * (iChar >> 4) performs the integer equivalent of Math.floor(iChar / 16), and (iChar & 0xf) is the equivalent of (iChar % 16).\n */\n font.context.putImageData(imageChar, (iChar & 0xf) * cxCell, (iChar >> 4) * cyCell);\n }\n return font;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {Video8080}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (data) {\n if (!this.restore(data)) return false;\n }\n }\n /*\n * Because the VT100 frame buffer can be located anywhere in RAM (above 0x2000), we must defer this\n * test code until the powerUp() notification handler is called, when all RAM has (hopefully) been allocated.\n *\n * NOTE: The following test screen was useful for early testing, but a *real* VT100 doesn't display a test screen,\n * so this code is no longer enabled by default. Remove MAXDEBUG if you want to see it again.\n */\n if (MAXDEBUG && this.nFormat == Video8080.FORMAT.VT100) {\n /*\n * Build a test screen in the VT100 frame buffer; we'll mimic the \"SET-UP A\" screen, since it uses\n * all the font variations. The process involves iterating over 0-based row numbers -2 (or -5 if 50Hz\n * operation is selected) through 24, checking aLineData for a matching row number, and converting the\n * corresponding string(s) to appropriate byte values. Negative row numbers correspond to \"fill lines\"\n * and do not require a row entry. If multiple strings are present for a given row, we invert the\n * default character attribute for subsequent strings. An empty array ends the screen build process.\n */\n var aLineData = {\n 0: [Video8080.VT100.FONT.DHIGH, 'SET-UP A'],\n 2: [Video8080.VT100.FONT.DWIDE, 'TO EXIT PRESS \"SET-UP\"'],\n 22: [Video8080.VT100.FONT.NORML, ' T T T T T T T T T'],\n 23: [Video8080.VT100.FONT.NORML, '1234567890', '1234567890', '1234567890', '1234567890', '1234567890', '1234567890', '1234567890', '1234567890'],\n 24: []\n };\n var addr = this.addrBuffer;\n var addrNext = -1, font = -1;\n var b, nFill = (this.rateMonitor == 60? 2 : 5);\n for (var iRow = -nFill; iRow < this.nRowsBuffer; iRow++) {\n var lineData = aLineData[iRow];\n if (addrNext >= 0) {\n var fBreak = false;\n addrNext = addr + 2;\n if (!lineData) {\n if (font == Video8080.VT100.FONT.DHIGH) {\n lineData = aLineData[iRow-1];\n font = Video8080.VT100.FONT.DHIGH_BOT;\n }\n }\n else {\n if (lineData.length) {\n font = lineData[0];\n } else {\n addrNext = addr - 1;\n fBreak = true;\n }\n }\n b = (font & Video8080.VT100.LINEATTR.FONTMASK) | ((addrNext >> 8) & Video8080.VT100.LINEATTR.ADDRMASK) | Video8080.VT100.LINEATTR.ADDRBIAS;\n this.bus.setByteDirect(addr++, b);\n this.bus.setByteDirect(addr++, addrNext & 0xff);\n if (fBreak) break;\n }\n if (lineData) {\n var attr = 0;\n for (var j = 1; j < lineData.length; j++) {\n var s = lineData[j];\n for (var k = 0; k < s.length; k++) {\n this.bus.setByteDirect(addr++, s.charCodeAt(k) | attr);\n }\n attr ^= 0x80;\n }\n }\n this.bus.setByteDirect(addr++, Video8080.VT100.LINETERM);\n addrNext = addr;\n }\n /*\n * NOTE: By calling updateVT100() directly, we are bypassing any checks that might block the update.\n */\n this.updateVT100();\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Video8080}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return !fSave || this.save();\n }\n\n /**\n * save()\n *\n * This implements save support for the Video8080 component.\n *\n * @this {Video8080}\n * @return {Object|null}\n */\n save()\n {\n var state = new State(this);\n state.set(0, []);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the Video8080 component.\n *\n * @this {Video8080}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n return true;\n }\n\n /**\n * updateDimensions(nCols, nRows)\n *\n * Called from the ChipSet component whenever the screen dimensions have been dynamically altered.\n *\n * @this {Video8080}\n * @param {number} nCols (should be either 80 or 132; 80 is the default)\n * @param {number} nRows (should be either 24 or 14; 24 is the default)\n */\n updateDimensions(nCols, nRows)\n {\n this.printMessage(\"updateDimensions(\" + nCols + \",\" + nRows + \")\");\n this.nColsBuffer = nCols;\n /*\n * Even when the number of effective rows is 14 (or 15 counting the scroll line buffer), we want\n * to leave the number of rows at 24 (or 25 counting the scroll line buffer), because the VT100 doesn't\n * actually change character height (only character width).\n *\n * this.nRowsBuffer = nRows+1; // +1 for scroll line buffer\n */\n this.cxCell = this.cxCellDefault;\n if (nCols > 80) this.cxCell--; // VT100 font cells are 9x10 instead of 10x10 in 132-column mode\n if (this.initBuffers()) {\n this.createFonts();\n }\n }\n\n /**\n * updateRate(nRate)\n *\n * Called from the ChipSet component whenever the monitor refresh rate has been dynamically altered.\n *\n * @this {Video8080}\n * @param {number} nRate (should be either 50 or 60; 60 is the default)\n */\n updateRate(nRate)\n {\n this.printMessage(\"updateRate(\" + nRate + \")\");\n this.rateMonitor = nRate;\n }\n\n /**\n * updateScrollOffset(bScroll)\n *\n * Called from the ChipSet component whenever the screen scroll offset has been dynamically altered.\n *\n * @this {Video8080}\n * @param {number} bScroll\n */\n updateScrollOffset(bScroll)\n {\n this.printMessage(\"updateScrollOffset(\" + bScroll + \")\");\n if (this.bScrollOffset !== bScroll) {\n this.bScrollOffset = bScroll;\n /*\n * WARNING: If we immediately redraw the screen on the first wrap of the scroll offset back to zero,\n * we end up \"slamming\" the screen's contents back down again, because it seems that the frame buffer\n * contents haven't actually been scrolled yet. So we redraw now ONLY if bScroll is non-zero, lest\n * we ruin the smooth-scroll effect.\n *\n * And this change, while necessary, is not sufficient, because another intervening updateScreen()\n * call could still occur before the frame buffer contents are actually scrolled; and ordinarily, if the\n * buffer hasn't changed, updateScreen() would do nothing, but alas, if the cursor happens to get toggled\n * in the interim, updateScreen() will want to update exactly ONE cell.\n *\n * So we deal with that by setting the fSkipSingleCellUpdate flag. Now of course, there's no guarantee\n * that the next update of only ONE cell will always be a cursor update, but even if it isn't, skipping\n * that update doesn't seem like a huge cause for concern.\n */\n if (bScroll) {\n this.updateScreen(true);\n } else {\n this.fSkipSingleCellUpdate = true;\n }\n }\n }\n\n /**\n * doFullScreen()\n *\n * @this {Video8080}\n * @return {boolean} true if request successful, false if not (eg, failed OR not supported)\n */\n doFullScreen()\n {\n var fSuccess = false;\n if (this.container) {\n if (this.container.doFullScreen) {\n /*\n * Styling the container with a width of \"100%\" and a height of \"auto\" works great when the aspect ratio\n * of our virtual screen is at least roughly equivalent to the physical screen's aspect ratio, but now that\n * we support virtual VGA screens with an aspect ratio of 1.33, that's very much out of step with modern\n * wide-screen monitors, which usually have an aspect ratio of 1.6 or greater.\n *\n * And unfortunately, none of the browsers I've tested appear to make any attempt to scale our container to\n * the physical screen's dimensions, so the bottom of our screen gets clipped. To prevent that, I reduce\n * the width from 100% to whatever percentage will accommodate the entire height of the virtual screen.\n *\n * NOTE: Mozilla recommends both a width and a height of \"100%\", but all my tests suggest that using \"auto\"\n * for height works equally well, so I'm sticking with it, because \"auto\" is also consistent with how I've\n * implemented a responsive canvas when the browser window is being resized.\n */\n var sWidth = \"100%\";\n var sHeight = \"auto\";\n if (screen && screen.width && screen.height) {\n var aspectPhys = screen.width / screen.height;\n var aspectVirt = this.cxScreen / this.cyScreen;\n if (aspectPhys > aspectVirt) {\n sWidth = Math.round(aspectVirt / aspectPhys * 100) + '%';\n }\n // TODO: We may need to someday consider the case of a physical screen with an aspect ratio < 1.0....\n }\n if (!this.fGecko) {\n this.container.style.width = sWidth;\n this.container.style.height = sHeight;\n } else {\n /*\n * Sadly, the above code doesn't work for Firefox, because as http://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode\n * explains:\n *\n * 'It's worth noting a key difference here between the Gecko and WebKit implementations at this time:\n * Gecko automatically adds CSS rules to the element to stretch it to fill the screen: \"width: 100%; height: 100%\".\n *\n * Which would be OK if Gecko did that BEFORE we're called, but apparently it does that AFTER, effectively\n * overwriting our careful calculations. So we style the inner element (canvasScreen) instead, which\n * requires even more work to ensure that the canvas is properly centered. FYI, this solution is consistent\n * with Mozilla's recommendation for working around their automatic CSS rules:\n *\n * '[I]f you're trying to emulate WebKit's behavior on Gecko, you need to place the element you want\n * to present inside another element, which you'll make fullscreen instead, and use CSS rules to adjust\n * the inner element to match the appearance you want.'\n */\n this.canvasScreen.style.width = sWidth;\n this.canvasScreen.style.width = sWidth;\n this.canvasScreen.style.display = \"block\";\n this.canvasScreen.style.margin = \"auto\";\n }\n this.container.style.backgroundColor = \"black\";\n this.container.doFullScreen();\n fSuccess = true;\n }\n this.setFocus();\n }\n return fSuccess;\n }\n\n /**\n * notifyFullScreen(fFullScreen)\n *\n * @this {Video8080}\n * @param {boolean|null} fFullScreen (null if there was a full-screen error)\n */\n notifyFullScreen(fFullScreen)\n {\n if (!fFullScreen && this.container) {\n if (!this.fGecko) {\n this.container.style.width = this.container.style.height = \"\";\n } else {\n this.canvasScreen.style.width = this.canvasScreen.style.height = \"\";\n }\n }\n this.printMessage(\"notifyFullScreen(\" + fFullScreen + \")\");\n }\n\n /**\n * setFocus()\n *\n * @this {Video8080}\n */\n setFocus()\n {\n if (this.inputScreen) this.inputScreen.focus();\n }\n\n /**\n * getRefreshTime()\n *\n * @this {Video8080}\n * @return {number} (number of milliseconds per refresh)\n */\n getRefreshTime()\n {\n return 1000 / Math.max(this.rateRefresh, this.rateInterrupt);\n }\n\n /**\n * initCellCache(nCells)\n *\n * Initializes the contents of our internal cell cache.\n *\n * @this {Video8080}\n * @param {number} nCells\n */\n initCellCache(nCells)\n {\n this.nCellCache = nCells;\n this.fCellCacheValid = false;\n if (this.aCellCache === undefined || this.aCellCache.length != this.nCellCache) {\n this.aCellCache = new Array(this.nCellCache);\n }\n }\n\n /**\n * initColors()\n *\n * This creates an array of nColors, with additional OVERLAY_TOTAL colors tacked on to the end of the array.\n *\n * @this {Video8080}\n */\n initColors()\n {\n var rgbBlack = [0x00, 0x00, 0x00, 0xff];\n var rgbWhite = [0xff, 0xff, 0xff, 0xff];\n this.nColors = (1 << this.nBitsPerPixel);\n this.aRGB = new Array(this.nColors + Video8080.COLORS.OVERLAY_TOTAL);\n this.aRGB[0] = rgbBlack;\n this.aRGB[1] = rgbWhite;\n if (this.nFormat == Video8080.FORMAT.SI1978) {\n var rgbGreen = [0x00, 0xff, 0x00, 0xff];\n //noinspection UnnecessaryLocalVariableJS\n var rgbYellow = [0xff, 0xff, 0x00, 0xff];\n this.aRGB[this.nColors + Video8080.COLORS.OVERLAY_TOP] = rgbYellow;\n this.aRGB[this.nColors + Video8080.COLORS.OVERLAY_BOTTOM] = rgbGreen;\n }\n }\n\n /**\n * setPixel(image, x, y, bPixel)\n *\n * @this {Video8080}\n * @param {Object} image\n * @param {number} x\n * @param {number} y\n * @param {number} bPixel (ie, an index into aRGB)\n */\n setPixel(image, x, y, bPixel)\n {\n var index;\n if (!this.rotateBuffer) {\n index = (x + y * image.width);\n } else {\n index = (image.height - x - 1) * image.width + y;\n }\n if (bPixel && this.nFormat == Video8080.FORMAT.SI1978) {\n if (x >= 208 && x < 236) {\n bPixel = this.nColors + Video8080.COLORS.OVERLAY_TOP;\n }\n else if (x >= 28 && x < 72) {\n bPixel = this.nColors + Video8080.COLORS.OVERLAY_BOTTOM;\n }\n }\n var rgb = this.aRGB[bPixel];\n index *= rgb.length;\n image.data[index] = rgb[0];\n image.data[index+1] = rgb[1];\n image.data[index+2] = rgb[2];\n image.data[index+3] = rgb[3];\n }\n\n /**\n * updateChar(idFont, col, row, data, context)\n *\n * Updates a particular character cell (row,col) in the associated window.\n *\n * @this {Video8080}\n * @param {number} idFont\n * @param {number} col\n * @param {number} row\n * @param {number} data\n * @param {Object} [context]\n */\n updateChar(idFont, col, row, data, context)\n {\n var bChar = data & 0x7f;\n var font = this.aFonts[idFont][(data & 0x80)? 1 : 0];\n if (!font) return;\n\n var xSrc = (bChar & 0xf) * font.cxCell;\n var ySrc = (bChar >> 4) * font.cyCell;\n\n var xDst, yDst, cxDst, cyDst;\n\n var cxSrc = font.cxCell;\n var cySrc = font.cyCell;\n\n if (context) {\n xDst = col * this.cxCell;\n yDst = row * this.cyCell;\n cxDst = this.cxCell;\n cyDst = this.cyCell;\n } else {\n xDst = col * this.cxScreenCell;\n yDst = row * this.cyScreenCell;\n cxDst = this.cxScreenCell;\n cyDst = this.cyScreenCell;\n }\n\n /*\n * If font.cxCell > this.cxCell, then we assume the caller wants to draw a double-wide character,\n * so we will double xDst and cxDst.\n */\n if (font.cxCell > this.cxCell) {\n xDst *= 2;\n cxDst *= 2;\n\n }\n\n /*\n * If font.cyCell > this.cyCell, then we rely on idFont to indicate whether the top half or bottom half\n * of the character should be drawn.\n */\n if (font.cyCell > this.cyCell) {\n if (idFont == Video8080.VT100.FONT.DHIGH_BOT) ySrc += this.cyCell;\n cySrc = this.cyCell;\n\n }\n\n if (context) {\n context.drawImage(font.canvas, xSrc, ySrc, cxSrc, cySrc, xDst, yDst, cxDst, cyDst);\n } else {\n xDst += this.xScreenOffset;\n yDst += this.yScreenOffset;\n this.contextScreen.drawImage(font.canvas, xSrc, ySrc, cxSrc, cySrc, xDst, yDst, cxDst, cyDst);\n }\n }\n\n /**\n * updateVT100(fForced)\n *\n * @this {Video8080}\n * @param {boolean} [fForced]\n */\n updateVT100(fForced)\n {\n var addrNext = this.addrBuffer, fontNext = -1;\n\n var nRows = 0;\n var nFill = (this.rateMonitor == 60? 2 : 5);\n var iCell = 0, cUpdated = 0, iCellUpdated = -1;\n\n\n\n while (nRows < this.nRowsBuffer) {\n /*\n * Populate the line buffer\n */\n var nCols = 0;\n var addr = addrNext;\n var font = fontNext;\n var nColsVisible = this.nColsBuffer;\n if (font != Video8080.VT100.FONT.NORML) nColsVisible >>= 1;\n while (true) {\n var data = this.bus.getByteDirect(addr++);\n if ((data & Video8080.VT100.LINETERM) == Video8080.VT100.LINETERM) {\n var b = this.bus.getByteDirect(addr++);\n fontNext = b & Video8080.VT100.LINEATTR.FONTMASK;\n addrNext = ((b & Video8080.VT100.LINEATTR.ADDRMASK) << 8) | this.bus.getByteDirect(addr);\n addrNext += (b & Video8080.VT100.LINEATTR.ADDRBIAS)? Video8080.VT100.ADDRBIAS_LO : Video8080.VT100.ADDRBIAS_HI;\n break;\n }\n if (nCols < nColsVisible) {\n this.abLineBuffer[nCols++] = data;\n } else {\n break; // ideally, we would wait for a LINETERM byte, but it's not safe to loop without limit\n }\n }\n\n /*\n * Skip the first few \"fill lines\"\n */\n if (nFill) {\n nFill--;\n continue;\n }\n\n /*\n * Pad the line buffer as needed\n */\n while (nCols < this.abLineBuffer.length) {\n this.abLineBuffer[nCols++] = 0; // character code 0 is a empty font character\n }\n\n /*\n * Display the line buffer; ordinarily, the font number would be valid after processing the \"fill lines\",\n * but if the buffer isn't initialized yet, those lines might be missing, so the font number might not be set.\n */\n if (font >= 0) {\n /*\n * Cell cache logic is complicated by the fact that a line may be single-width one frame and double-width\n * the next. So we store the visible line length at the start of each row in the cache, which must match if\n * the cache can be considered valid for the current line.\n */\n var fLineCacheValid = this.fCellCacheValid && (this.aCellCache[iCell] == nColsVisible);\n this.aCellCache[iCell++] = nColsVisible;\n for (var iCol = 0; iCol < nCols; iCol++) {\n data = this.abLineBuffer[iCol];\n if (!fLineCacheValid || data !== this.aCellCache[iCell]) {\n this.aCellCache[iCellUpdated = iCell] = data;\n this.updateChar(font, iCol, nRows, data, this.contextBuffer);\n cUpdated++;\n }\n iCell++;\n }\n }\n nRows++;\n }\n\n this.fCellCacheValid = true;\n\n\n\n if (!fForced && this.fSkipSingleCellUpdate && cUpdated == 1) {\n /*\n * We're going to blow off this update, since it comes on the heels of a smooth-scroll that *may*\n * not be completely finished yet, and at the same time, we're going to zap the only updated cell\n * cache entry, to guarantee that it's redrawn on the next update.\n */\n\n /*\n * TODO: If I change the RECV rate to 19200 and enable smooth scrolling, I sometimes see a spurious\n * \"H\" on the bottom line after a long series of \"HELLO WORLD!\\r\\n\" tests. Dumping video memory shows\n * \"HELLO WORLD!\" on 23 lines and an \"H\" on the 24th line, so it's really there. But strangely, if\n * I then press SET-UP two times, the restored screen does NOT have the spurious \"H\". So somehow the\n * firmware knows what should and shouldn't be on-screen.\n *\n * Possible VT100 firmware bug? I'm not sure. Anyway, this DEBUG-only code is here to help trap\n * that scenario, until I figure it out.\n */\n if (DEBUG && (this.aCellCache[iCellUpdated] & 0x7f) == 0x48) {\n console.log(\"spurious character?\");\n }\n this.aCellCache[iCellUpdated] = -1;\n cUpdated = 0;\n }\n this.fSkipSingleCellUpdate = false;\n\n if ((cUpdated || fForced) && this.contextBuffer) {\n /*\n * We must subtract cyCell from cyBuffer to avoid displaying the extra \"scroll line\" that we normally\n * buffer, in support of smooth scrolling. Speaking of which, we must also add bScrollOffset to ySrc\n * (well, ySrc is always relative to zero, so no add is actually required).\n */\n this.contextScreen.drawImage(\n this.canvasBuffer,\n 0, // xSrc\n this.bScrollOffset, // ySrc\n this.cxBuffer, // cxSrc\n this.cyBuffer - this.cyCell, // cySrc\n this.xScreenOffset, // xDst\n this.yScreenOffset, // yDst\n this.cxScreenOffset, // cxDst\n this.cyScreenOffset // cyDst\n );\n }\n }\n\n /**\n * updateScreen(fForced)\n *\n * Propagates the video buffer to the cell cache and updates the screen with any changes. Forced updates\n * are generally internal updates triggered by an I/O operation or other state change, while non-forced updates\n * are the periodic updates coming from the CPU.\n *\n * For every cell in the video buffer, compare it to the cell stored in the cell cache, render if it differs,\n * and then update the cell cache to match. Since initCellCache() sets every cell in the cell cache to an\n * invalid value, we're assured that the next call to updateScreen() will redraw the entire (visible) video buffer.\n *\n * @this {Video8080}\n * @param {boolean} [fForced]\n */\n updateScreen(fForced)\n {\n var fUpdate = true;\n\n if (!fForced) {\n if (this.rateInterrupt) {\n /*\n * TODO: Incorporate these hard-coded interrupt vector numbers into configuration blocks.\n */\n if (this.rateInterrupt == 120) {\n if (!(this.nUpdates & 1)) {\n /*\n * On even updates, call cpu.requestINTR(1), and also update our copy of the screen.\n */\n this.cpu.requestINTR(1);\n } else {\n /*\n * On odd updates, call cpu.requestINTR(2), but do NOT update our copy of the screen, because\n * the machine has presumably only updated the top half of the frame buffer at this point; it will\n * update the bottom half of the frame buffer after acknowledging this interrupt.\n */\n this.cpu.requestINTR(2);\n fUpdate = false;\n }\n } else {\n this.cpu.requestINTR(4);\n }\n }\n\n /*\n * Since this is not a forced update, if our cell cache is valid AND we allocated our own buffer AND the buffer\n * is clean, then there's nothing to do.\n */\n if (fUpdate && this.fCellCacheValid && this.sizeBuffer) {\n if (this.bus.cleanMemory(this.addrBuffer, this.sizeBuffer)) {\n fUpdate = false;\n }\n }\n this.cpu.setTimer(this.timerUpdateNext, this.getRefreshTime());\n this.nUpdates++;\n }\n\n if (!fUpdate) {\n return;\n }\n\n if (this.cxCell > 1) {\n this.updateScreenText(fForced);\n } else {\n this.updateScreenGraphics(fForced);\n }\n }\n\n /**\n * updateScreenText(fForced)\n *\n * @this {Video8080}\n * @param {boolean} [fForced]\n */\n updateScreenText(fForced)\n {\n switch(this.nFormat) {\n case Video8080.FORMAT.VT100:\n this.updateVT100(fForced);\n break;\n }\n }\n\n /**\n * updateScreenGraphics(fForced)\n *\n * @this {Video8080}\n * @param {boolean} [fForced]\n */\n updateScreenGraphics(fForced)\n {\n var addr = this.addrBuffer;\n var addrLimit = addr + this.sizeBuffer;\n\n var iCell = 0;\n var nPixelShift = 1;\n\n var xBuffer = 0, yBuffer = 0;\n var xDirty = this.cxBuffer, xMaxDirty = 0, yDirty = this.cyBuffer, yMaxDirty = 0;\n\n var nShiftInit = 0;\n var nShiftPixel = this.nBitsPerPixel;\n var nMask = (1 << nShiftPixel) - 1;\n if (this.iBitFirstPixel) {\n nShiftPixel = -nShiftPixel;\n nShiftInit = 16 + nShiftPixel;\n }\n\n while (addr < addrLimit) {\n var data = this.bus.getShortDirect(addr);\n\n if (this.fCellCacheValid && data === this.aCellCache[iCell]) {\n xBuffer += this.nPixelsPerCell;\n } else {\n this.aCellCache[iCell] = data;\n var nShift = nShiftInit;\n if (nShift) data = ((data >> 8) | ((data & 0xff) << 8));\n if (xBuffer < xDirty) xDirty = xBuffer;\n var cPixels = this.nPixelsPerCell;\n while (cPixels--) {\n var bPixel = (data >> nShift) & nMask;\n this.setPixel(this.imageBuffer, xBuffer++, yBuffer, bPixel);\n nShift += nShiftPixel;\n }\n if (xBuffer > xMaxDirty) xMaxDirty = xBuffer;\n if (yBuffer < yDirty) yDirty = yBuffer;\n if (yBuffer >= yMaxDirty) yMaxDirty = yBuffer + 1;\n }\n addr += 2; iCell++;\n if (xBuffer >= this.cxBuffer) {\n xBuffer = 0; yBuffer++;\n if (yBuffer > this.cyBuffer) break;\n }\n }\n\n this.fCellCacheValid = true;\n\n /*\n * Instead of blasting the ENTIRE imageBuffer into contextBuffer, and then blasting the ENTIRE\n * canvasBuffer onto contextScreen, even for the smallest change, let's try to be a bit smarter about\n * the update (well, to the extent that the canvas APIs permit).\n */\n if (xDirty < this.cxBuffer) {\n var cxDirty = xMaxDirty - xDirty;\n var cyDirty = yMaxDirty - yDirty;\n if (this.rotateBuffer) {\n /*\n * If rotateBuffer is set, then it must be -90, so we must \"rotate\" the dirty coordinates as well,\n * because they are relative to the frame buffer, not the rotated image buffer. Alternatively, you\n * can use the following call to blast the ENTIRE imageBuffer into contextBuffer instead:\n *\n * this.contextBuffer.putImageData(this.imageBuffer, 0, 0);\n */\n var xDirtyOrig = xDirty, cxDirtyOrig = cxDirty;\n //noinspection JSSuspiciousNameCombination\n xDirty = yDirty;\n cxDirty = cyDirty;\n yDirty = this.cxBuffer - (xDirtyOrig + cxDirtyOrig);\n cyDirty = cxDirtyOrig;\n }\n this.contextBuffer.putImageData(this.imageBuffer, 0, 0, xDirty, yDirty, cxDirty, cyDirty);\n /*\n * As originally noted in /modules/pcx86/lib/video.js, I would prefer to draw only the dirty portion of\n * canvasBuffer, but there usually isn't a 1-1 pixel mapping between canvasBuffer and contextScreen, so\n * if we draw interior rectangles, we can end up with subpixel artifacts along the edges of those rectangles.\n */\n this.contextScreen.drawImage(this.canvasBuffer, 0, 0, this.canvasBuffer.width, this.canvasBuffer.height, 0, 0, this.cxScreen, this.cyScreen);\n }\n }\n\n /**\n * Video8080.init()\n *\n * This function operates on every HTML element of class \"video\", extracting the\n * JSON-encoded parameters for the Video constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Video component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeVideo = Component.getElementsByClass(document, PC8080.APPCLASS, \"video\");\n for (var iVideo = 0; iVideo < aeVideo.length; iVideo++) {\n var eVideo = aeVideo[iVideo];\n var parmsVideo = Component.getComponentParms(eVideo);\n\n var eCanvas = document.createElement(\"canvas\");\n if (eCanvas === undefined || !eCanvas.getContext) {\n eVideo.innerHTML = \"<br/>Missing <canvas> support. Please try a newer web browser.\";\n return;\n }\n\n eCanvas.setAttribute(\"class\", \"pcjs-canvas\");\n eCanvas.setAttribute(\"width\", parmsVideo['screenWidth']);\n eCanvas.setAttribute(\"height\", parmsVideo['screenHeight']);\n eCanvas.style.backgroundColor = parmsVideo['screenColor'];\n\n /*\n * The \"contenteditable\" attribute on a canvas element NOTICEABLY slows down canvas drawing on\n * Safari as soon as you give the canvas focus (ie, click away from the canvas, and drawing speeds\n * up; click on the canvas, and drawing slows down). So the \"transparent textarea hack\" that we\n * once employed as only a work-around for Android devices is now our default.\n *\n * eCanvas.setAttribute(\"contenteditable\", \"true\");\n *\n * HACK: A canvas style of \"auto\" provides for excellent responsive canvas scaling in EVERY browser\n * except IE9/IE10, so I recalculate the appropriate CSS height every time the parent DIV is resized;\n * IE11 works without this hack, so we take advantage of the fact that IE11 doesn't identify as \"MSIE\".\n *\n * The other reason it's good to keep this particular hack limited to IE9/IE10 is that most other\n * browsers don't actually support an 'onresize' handler on anything but the window object.\n */\n eCanvas.style.height = \"auto\";\n if (Web.getUserAgent().indexOf(\"MSIE\") >= 0) {\n eVideo.onresize = function(eParent, eChild, cx, cy) {\n return function onResizeVideo() {\n eChild.style.height = (((eParent.clientWidth * cy) / cx) | 0) + \"px\";\n };\n }(eVideo, eCanvas, parmsVideo['screenWidth'], parmsVideo['screenHeight']);\n eVideo.onresize();\n }\n /*\n * The following is a related hack that allows the user to force the screen to use a particular aspect\n * ratio if an 'aspect' attribute or URL parameter is set. Initially, it's just for testing purposes\n * until we figure out a better UI. And note that we use our web.onPageEvent() helper function to make\n * sure we don't trample any other 'onresize' handler(s) attached to the window object.\n */\n var aspect = +(parmsVideo['aspect'] || Web.getURLParm('aspect'));\n /*\n * No 'aspect' parameter yields NaN, which is falsey, and anything else must satisfy my arbitrary\n * constraints of 0.3 <= aspect <= 3.33, to prevent any useless (or worse, browser-blowing) results.\n */\n if (aspect && aspect >= 0.3 && aspect <= 3.33) {\n Web.onPageEvent('onresize', function(eParent, eChild, aspectRatio) {\n return function onResizeWindow() {\n /*\n * Since aspectRatio is the target width/height, we have:\n *\n * eParent.clientWidth / eChild.style.height = aspectRatio\n *\n * which means that:\n *\n * eChild.style.height = eParent.clientWidth / aspectRatio\n *\n * so for example, if aspectRatio is 16:9, or 1.78, and clientWidth = 640,\n * then the calculated height should approximately 360.\n */\n eChild.style.height = ((eParent.clientWidth / aspectRatio)|0) + \"px\";\n };\n }(eVideo, eCanvas, aspect));\n window['onresize']();\n }\n eVideo.appendChild(eCanvas);\n\n /*\n * HACK: Android-based browsers, like the Silk (Amazon) browser and Chrome for Android, don't honor the\n * \"contenteditable\" attribute; that is, when the canvas receives focus, they don't activate the on-screen\n * keyboard. So my fallback is to create a transparent textarea on top of the canvas.\n *\n * The parent DIV must have a style of \"position:relative\" (alternatively, a class of \"pcjs-container\"),\n * so that we can position the textarea using absolute coordinates. Also, we don't want the textarea to be\n * visible, but we must use \"opacity:0\" instead of \"visibility:hidden\", because the latter seems to prevent\n * the element from receiving events. These styling requirements are taken care of in components.css\n * (see references to the \"pcjs-video-object\" class).\n *\n * UPDATE: Unfortunately, Android keyboards like to compose whole words before transmitting any of the\n * intervening characters; our textarea's keyDown/keyUp event handlers DO receive intervening key events,\n * but their keyCode property is ZERO. Virtually the only usable key event we receive is the Enter key.\n * Android users will have to use machines that include their own on-screen \"soft keyboard\", or use an\n * external keyboard.\n *\n * The following attempt to use a password-enabled input field didn't work any better on Android. You could\n * clearly see the overlaid semi-transparent input field, but none of the input characters were passed along,\n * with the exception of the \"Go\" (Enter) key.\n *\n * var eInput = document.createElement(\"input\");\n * eInput.setAttribute(\"type\", \"password\");\n * eInput.setAttribute(\"style\", \"position:absolute; left:0; top:0; width:100%; height:100%; opacity:0.5\");\n * eVideo.appendChild(eInput);\n *\n * See this Chromium issue for more information: https://code.google.com/p/chromium/issues/detail?id=118639\n */\n var eTextArea = document.createElement(\"textarea\");\n\n /*\n * As noted in keyboard.js, the keyboard on an iOS device tends to pop up with the SHIFT key depressed,\n * which is not the initial keyboard state that the Keyboard component expects, so hopefully turning off\n * these \"auto\" attributes will help.\n */\n if (Web.isUserAgent(\"iOS\")) {\n eTextArea.setAttribute(\"autocapitalize\", \"off\");\n eTextArea.setAttribute(\"autocorrect\", \"off\");\n /*\n * One of the problems on iOS devices is that after a soft-key control is clicked, we need to give\n * focus back to the above textarea, usually by calling cmp.updateFocus(), but in doing so, iOS may\n * also \"zoom\" the page rather jarringly. While it's a simple matter to completely disable zooming,\n * by fiddling with the page's viewport, that prevents the user from intentionally zooming. A bit of\n * Googling reveals that another way to prevent those jarring unintentional zooms is to simply set the\n * font-size of the text control to 16px. So that's what we do.\n */\n eTextArea.style.fontSize = \"16px\";\n }\n eVideo.appendChild(eTextArea);\n\n /*\n * Now we can create the Video object, record it, and wire it up to the associated document elements.\n */\n var eContext = eCanvas.getContext(\"2d\");\n var video = new Video8080(parmsVideo, eCanvas, eContext, eTextArea /* || eInput */, eVideo);\n\n /*\n * Bind any video-specific controls (eg, the Refresh button). There are no essential controls, however;\n * even the \"Refresh\" button is just a diagnostic tool, to ensure that the screen contents are up-to-date.\n */\n Component.bindComponentControls(video, eVideo, PC8080.APPCLASS);\n }\n }\n}\n\nVideo8080.COLORS = {\n OVERLAY_TOP: 0,\n OVERLAY_BOTTOM: 1,\n OVERLAY_TOTAL: 2\n};\n\nVideo8080.FORMAT = {\n UNKNOWN: 0,\n SI1978: 1,\n VT100: 2\n};\n\nVideo8080.FORMATS = {\n \"SI1978\": Video8080.FORMAT.SI1978,\n \"VT100\": Video8080.FORMAT.VT100\n};\n\n\nVideo8080.VT100 = {\n /*\n * The following font IDs are nothing more than all the possible LINEATTR values masked with FONTMASK;\n * also, note that double-high implies double-wide; the VT100 doesn't support a double-high single-wide font.\n */\n FONT: {\n NORML: 0x60, // normal font (eg, 10x10)\n DWIDE: 0x40, // double-wide, single-high font (eg, 20x10)\n DHIGH: 0x20, // technically, this means display only the TOP half of the double-high font (eg, 20x20)\n DHIGH_BOT: 0x00 // technically, this means display only the BOTTOM half of the double-high font (eg, 20x20)\n },\n LINETERM: 0x7F,\n LINEATTR: {\n ADDRMASK: 0x0F,\n ADDRBIAS: 0x10, // 0x10 == ADDRBIAS_LO, 0x00 = ADDRBIAS_HI\n FONTMASK: 0x60,\n SCROLL: 0x80\n },\n ADDRBIAS_LO: 0x2000,\n ADDRBIAS_HI: 0x4000\n};\n\n/*\n * Initialize every Video module on the page.\n */\nWeb.onInit(Video8080.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/serial.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * SerialPort8080 class\n *\n * The class property declarations below started as a way of informing the code inspector of the controlBuffer\n * property, which remained undefined until a setBinding() call set it later, but I've since decided that explicitly\n * initializing such properties in the constructor is a better way to go -- even though it's more code -- because\n * JavaScript compilers are supposed to be happier when the underlying object structures aren't constantly changing.\n *\n * Besides, I'm not sure I want to get into documenting every property this way, for this or any/every other class,\n * let alone getting into which ones should be considered private or protected, because PCjs isn't really a library\n * for third-party apps.\n * \n * @class SerialPort8080\n * @property {number} iAdapter\n * @property {number} portBase\n * @property {number} nIRQ\n * @property {Object} controlBuffer is a DOM element bound to the port (for rudimentary output; see transmitByte())\n * @unrestricted\n */\nclass SerialPort8080 extends Component {\n /**\n * SerialPort8080(parmsSerial)\n *\n * The SerialPort8080 component has the following component-specific (parmsSerial) properties:\n *\n * adapter: 0 if not defined\n *\n * binding: name of a control (based on its \"binding\" attribute) to bind to this port's I/O\n *\n * tabSize: set to a non-zero number to convert tabs to spaces (applies only to output to\n * the above binding); default is 0 (no conversion)\n *\n * In the future, we may support 'port' and 'irq' properties that allow the machine to define a\n * non-standard serial port configuration, instead of only our pre-defined 'adapter' configurations.\n *\n * NOTE: Since the XSL file defines 'adapter' as a number, not a string, there's no need to use\n * parseInt(), and as an added benefit, we don't need to worry about whether a hex or decimal format\n * was used.\n *\n * @this {SerialPort8080}\n * @param {Object} parmsSerial\n */\n constructor(parmsSerial)\n {\n super(\"SerialPort\", parmsSerial, Messages8080.SERIAL);\n\n this.iAdapter = +parmsSerial['adapter'];\n\n switch (this.iAdapter) {\n case 0:\n this.portBase = 0;\n this.nIRQ = 2;\n break;\n default:\n Component.warning(\"Unrecognized serial adapter #\" + this.iAdapter);\n return;\n }\n /**\n * consoleBuffer becomes a string that records serial port output if the 'binding' property is set to the\n * reserved name \"console\". Nothing is written to the console, however, until a linefeed (0x0A) is output\n * or the string length reaches a threshold (currently, 1024 characters).\n *\n * @type {string|null}\n */\n this.consoleBuffer = null;\n\n /**\n * controlBuffer is a DOM element bound to the port (currently used for output only; see transmitByte()).\n *\n * @type {Object}\n */\n this.controlBuffer = null;\n\n /*\n * If controlBuffer is being used AND 'tabSize' is set, then we make an attempt to monitor the characters\n * being echoed via transmitByte(), maintain a logical column position, and convert any tabs into the appropriate\n * number of spaces.\n *\n * charBOL, if nonzero, is a character to automatically output at the beginning of every line. This probably\n * isn't generally useful; I use it internally to preformat serial output.\n */\n this.tabSize = parmsSerial['tabSize'];\n this.charBOL = parmsSerial['charBOL'];\n this.iLogicalCol = 0;\n\n /*\n * fAutoXOFF enables some experimental auto-XOFF/XON processing. It assumes if the VT100 firmware\n * issues an XOFF, receiveByte() should stop accepting more data until the firmware issues an XOFF.\n *\n * The downside is that this doesn't really do anything to stem the flow of incoming data; it just\n * prevents the VT100's internal buffer from overflowing. TODO: Eliminate the need for this hack\n * and add some *real* flow-control interfaces between connected SerialPort components.\n */\n this.fAutoXOFF = true;\n this.fAutoStop = false;\n this.fNullModem = true;\n\n var sBinding = parmsSerial['binding'];\n if (sBinding == \"console\") {\n this.consoleBuffer = \"\";\n } else {\n /*\n * If the SerialPort wants to bind to a control (eg, \"print\") in a DIFFERENT component (eg, \"Panel\"),\n * then it specifies the name of that control with the 'binding' property. The SerialPort constructor\n * will then call bindExternalControl(), which looks up the control, and then passes it to our own\n * setBinding() handler.\n * \n * For bindExternalControl() to succeed, it also need to know the target component; for now, that's\n * been hard-coded to \"Panel\", in part because that's one of the few components we can rely upon\n * initializing before we do, but it would be a simple matter to include a component type or ID as part\n * of the 'binding' property as well, if we need more flexibility later.\n * \n * NOTE: If sBinding is not the name of a valid Control Panel DOM element, this call does nothing.\n */\n Component.bindExternalControl(this, sBinding);\n }\n\n /*\n * No connection until initConnection() is called.\n */\n this.sDataReceived = \"\";\n this.connection = this.sendData = this.updateStatus = null;\n\n /*\n * Export all functions required by initConnection().\n */\n this['exports'] = {\n 'connect': this.initConnection,\n 'receiveData': this.receiveData,\n 'receiveStatus': this.receiveStatus\n };\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {SerialPort8080}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"buffer\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var serial = this;\n \n if (sHTMLType == null || sHTMLType == \"textarea\") {\n\n this.bindings[sBinding] = this.controlBuffer = control;\n\n /*\n * By establishing an onkeypress handler here, we make it possible for DOS commands like\n * \"CTTY COM1\" to more or less work (use \"CTTY CON\" to restore control to the DOS console).\n */\n control.onkeydown = function onKeyDown(event) {\n /*\n * This is required in addition to onkeypress, because it's the only way to prevent\n * BACKSPACE (keyCode 8) from being interpreted by the browser as a \"Back\" operation;\n * moreover, not all browsers generate an onkeypress notification for BACKSPACE.\n *\n * A related problem exists for Ctrl-key combinations in most Windows-based browsers\n * (eg, IE, Edge, Chrome for Windows, etc), because keys like Ctrl-C and Ctrl-S have\n * special meanings (eg, Copy, Save). To the extent the browser will allow it, we\n * attempt to disable that default behavior when this control receives an onkeydown\n * event for one of those keys (probably the only event the browser generates for them).\n */\n event = event || window.event;\n var keyCode = event.keyCode;\n if (keyCode === 0x08 || event.ctrlKey && keyCode >= 0x41 && keyCode <= 0x5A) {\n if (event.preventDefault) event.preventDefault();\n if (keyCode > 0x40) keyCode -= 0x40;\n serial.receiveByte(keyCode);\n }\n return true;\n };\n\n control.onkeypress = function onKeyPress(event) {\n /*\n * Browser-independent keyCode extraction; refer to onKeyPress() and the other key event\n * handlers in keyboard.js.\n */\n event = event || window.event;\n var keyCode = event.which || event.keyCode;\n serial.receiveByte(keyCode);\n /*\n * Since we're going to remove the \"readonly\" attribute from the <textarea> control\n * (so that the soft keyboard activates on iOS), instead of calling preventDefault() for\n * selected keys (eg, the SPACE key, whose default behavior is to scroll the page), we must\n * now call it for *all* keys, so that the keyCode isn't added to the control immediately,\n * on top of whatever the machine is echoing back, resulting in double characters.\n */\n if (event.preventDefault) event.preventDefault();\n return true;\n };\n\n /*\n * Now that we've added an onkeypress handler that calls preventDefault() for ALL keys, the control\n * itself no longer needs the \"readonly\" attribute; we primarily need to remove it for iOS browsers,\n * so that the soft keyboard will activate, but it shouldn't hurt to remove the attribute for all browsers.\n */\n control.removeAttribute(\"readonly\");\n return true;\n }\n \n if (sValue) {\n /*\n * Instead of just having a dedicated \"test\" control, we now treat any unrecognized control with\n * a \"value\" attribute as a test control. The only caveat is that such controls must have binding IDs\n * that do not conflict with predefined controls (which, of course, is the only way you can get here).\n */\n this.bindings[sBinding] = control;\n\n /*\n * Backslash sequences like \\n, \\r, and \\\\ have already been converted to LF, CR and backslash\n * characters, by virtue of the eval() function that all our component parameter strings pass through;\n * eval() treats strings like \"source code\", so any backslash sequence that JavaScript supports is\n * automatically converted.\n *\n * The complete list of backslash sequences supported by JavaScript:\n *\n * \\0 \\' \\\" \\\\ \\n \\r \\v \\t \\b \\f \\uXXXX \\xXX\n * ^J ^M ^K ^I ^H ^L\n *\n * To support any other non-printable 8-bit character, such as ESC, you should use \\xXX, where XX\n * is the ASCII code in hex. For ESC, that would \\x1B.\n */\n control.onclick = function onClickTest(event) {\n serial.receiveData(sValue);\n /*\n * Give focus back to the machine (since clicking the button takes focus away).\n *\n * if (serial.cmp) serial.cmp.updateFocus();\n *\n * iOS Usability Improvement: NOT calling updateFocus() keeps the soft keyboard down\n * (assuming it was already down).\n */\n return true;\n };\n return true;\n }\n \n return false;\n }\n\n /**\n * echoByte(b)\n *\n * @this {SerialPort8080}\n * @param {number} b\n * @return {boolean} true if echo, false if not\n */\n echoByte(b)\n {\n var fEchoed = false;\n\n if (this.controlBuffer) {\n if (b == 0x08) {\n this.controlBuffer.value = this.controlBuffer.value.slice(0, -1);\n /*\n * TODO: Back up the correct number of columns if the character erased was a tab.\n */\n if (this.iLogicalCol > 0) this.iLogicalCol--;\n }\n else {\n var s = Str.toASCIICode(b);\n var nChars = s.length;\n if (b == 0x09) {\n var tabSize = this.tabSize || 8;\n nChars = tabSize - (this.iLogicalCol % tabSize);\n if (this.tabSize) s = Str.pad(\"\", nChars);\n }\n else if (b == 0x0D) {\n this.iLogicalCol = nChars = 0;\n s = \"\\n\";\n }\n if (this.charBOL && !this.iLogicalCol && nChars) s = String.fromCharCode(this.charBOL) + s;\n this.controlBuffer.value += s;\n this.controlBuffer.scrollTop = this.controlBuffer.scrollHeight;\n this.iLogicalCol += nChars;\n }\n fEchoed = true;\n }\n else if (this.consoleBuffer != null) {\n if (b == 0x0A || this.consoleBuffer.length >= 1024) {\n this.println(this.consoleBuffer);\n this.consoleBuffer = \"\";\n }\n if (b != 0x0A) {\n this.consoleBuffer += String.fromCharCode(b);\n }\n fEchoed = true;\n }\n\n return fEchoed;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {SerialPort8080}\n * @param {Computer8080} cmp\n * @param {Bus8080} bus\n * @param {CPUState8080} cpu\n * @param {Debugger8080} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n var serial = this;\n this.timerReceiveNext = this.cpu.addTimer(this.id + \".receive\", function() {\n serial.receiveData();\n });\n this.timerTransmitNext = this.cpu.addTimer(this.id + \".transmit\", function() {\n serial.transmitData();\n });\n\n this.chipset = /** @type {ChipSet8080} */ (cmp.getMachineComponent(\"ChipSet\"));\n\n bus.addPortInputTable(this, SerialPort8080.aPortInput, this.portBase);\n bus.addPortOutputTable(this, SerialPort8080.aPortOutput, this.portBase);\n\n this.setReady();\n }\n\n /**\n * initConnection(fNullModem)\n *\n * If a machine 'connection' parameter exists of the form \"{sourcePort}->{targetMachine}.{targetPort}\",\n * and \"{sourcePort}\" matches our idComponent, then look for a component with id \"{targetMachine}.{targetPort}\".\n *\n * If the target component is found, then verify that it has exported functions with the following names:\n *\n * receiveData(data): called when we have data to transmit; aliased internally to sendData(data)\n * receiveStatus(pins): called when our control signals have changed; aliased internally to updateStatus(pins)\n *\n * For now, we're not going to worry about communication in the other direction, because when the target component\n * performs its own initConnection(), it will find our receiveData() and receiveStatus() functions, at which point\n * communication in both directions should be established, and the circle of life complete.\n *\n * For added robustness, if the target machine initializes much more slowly than we do, and our connection attempt\n * fails, that's OK, because when it finally initializes, its initConnection() will call our initConnection();\n * if we've already initialized, no harm done.\n *\n * @this {SerialPort8080}\n * @param {boolean} [fNullModem] (caller's null-modem setting, to ensure our settings are in agreement)\n */\n initConnection(fNullModem)\n {\n if (!this.connection) {\n var sConnection = this.cmp.getMachineParm(\"connection\");\n if (sConnection) {\n var asParts = sConnection.split('->');\n if (asParts.length == 2) {\n var sSourceID = Str.trim(asParts[0]);\n if (sSourceID != this.idComponent) return; // this connection string is intended for another instance\n var sTargetID = Str.trim(asParts[1]);\n this.connection = Component.getComponentByID(sTargetID);\n if (this.connection) {\n var exports = this.connection['exports'];\n if (exports) {\n var fnConnect = /** @function */ (exports['connect']);\n if (fnConnect) fnConnect.call(this.connection, this.fNullModem);\n this.sendData = exports['receiveData'];\n if (this.sendData) {\n this.fNullModem = fNullModem;\n this.updateStatus = exports['receiveStatus'];\n this.status(\"Connected \" + this.idMachine + '.' + sSourceID + \" to \" + sTargetID);\n return;\n }\n }\n }\n }\n /*\n * Changed from notice() to status() because sometimes a connection fails simply because one of us is a laggard.\n */\n this.status(\"Unable to establish connection: \" + sConnection);\n }\n }\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {SerialPort8080}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n\n /*\n * This is as late as we can currently wait to make our first inter-machine connection attempt;\n * even so, the target machine's initialization process may still be ongoing, so any connection\n * may be not fully resolved until the target machine performs its own initConnection(), which will\n * in turn invoke our initConnection() again.\n */\n this.initConnection(this.fNullModem);\n\n if (!data || !this.restore) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {SerialPort8080}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {SerialPort8080}\n */\n reset()\n {\n this.initState();\n }\n\n /**\n * save()\n *\n * This implements save support for the SerialPort8080 component.\n *\n * @this {SerialPort8080}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveRegisters());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the SerialPort8080 component.\n *\n * @this {SerialPort8080}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return this.initState(data[0]);\n }\n\n /**\n * initState(data)\n *\n * @this {SerialPort8080}\n * @param {Array} [data]\n * @return {boolean} true if successful, false if failure\n */\n initState(data)\n {\n var i = 0;\n if (data === undefined) {\n data = SerialPort8080.UART8251.INIT;\n }\n this.fReady = data[i++];\n this.bDataIn = data[i++];\n this.bDataOut = data[i++];\n this.bStatus = data[i++];\n this.bMode = data[i++];\n this.bCommand = data[i++];\n this.bBaudRates = data[i];\n return true;\n }\n\n /**\n * saveRegisters()\n *\n * @this {SerialPort8080}\n * @return {Array}\n */\n saveRegisters()\n {\n var i = 0;\n var data = [];\n data[i++] = this.fReady;\n data[i++] = this.bDataIn;\n data[i++] = this.bDataOut;\n data[i++] = this.bStatus;\n data[i++] = this.bMode;\n data[i++] = this.bCommand;\n data[i] = this.bBaudRates;\n return data;\n }\n\n /**\n * getBaudTimeout(maskRate)\n *\n * @this {SerialPort8080}\n * @param {number} maskRate (either SerialPort8080.UART8251.BAUDRATES.RECV_RATE or SerialPort8080.UART8251.BAUDRATES.XMIT_RATE)\n * @return {number} (number of milliseconds per byte)\n */\n getBaudTimeout(maskRate)\n {\n var indexRate = (this.bBaudRates & maskRate);\n if (!(maskRate & 0xf)) indexRate >>= 4;\n var nBaud = SerialPort8080.UART8251.BAUDTABLE[indexRate];\n var nBits = ((this.bMode & SerialPort8080.UART8251.MODE.DATA_BITS) >> 2) + 6; // includes an extra +1 for start bit\n if (this.bMode & SerialPort8080.UART8251.MODE.PARITY_ENABLE) nBits++;\n nBits += ((((this.bMode & SerialPort8080.UART8251.MODE.STOP_BITS) >> 6) + 1) >> 1);\n var nBytesPerSecond = nBaud / nBits;\n return (1000 / nBytesPerSecond)|0;\n }\n\n /**\n * receiveByte(b)\n *\n * @this {SerialPort8080}\n * @param {number} b\n * @return {boolean}\n */\n receiveByte(b)\n {\n if (MAXDEBUG) this.echoByte(b);\n this.printMessage(\"receiveByte(\" + Str.toHexByte(b) + \"), status=\" + Str.toHexByte(this.bStatus));\n if (!this.fAutoStop && !(this.bStatus & SerialPort8080.UART8251.STATUS.RECV_FULL)) {\n this.bDataIn = b;\n this.bStatus |= SerialPort8080.UART8251.STATUS.RECV_FULL;\n this.cpu.requestINTR(this.nIRQ);\n return true;\n }\n return false;\n }\n\n /**\n * receiveData(data)\n *\n * Helper for clocking received data at the expected RECV_RATE.\n *\n * When we're cramming test data down the terminal's throat, that data will typically be in the form\n * of a string. When we're called by another component, data will typically be a number (ie, byte). If no\n * data is specified at all, then all we do is \"clock\" any remaining data into the receiver.\n *\n * @this {SerialPort8080}\n * @param {number|string|undefined} [data]\n * @return {boolean} true if received, false if not\n */\n receiveData(data)\n {\n if (data != null) {\n if (typeof data != \"number\") {\n this.sDataReceived = data;\n } else {\n this.sDataReceived += String.fromCharCode(data);\n }\n }\n if (this.sDataReceived) {\n if (this.receiveByte(this.sDataReceived.charCodeAt(0))) {\n this.sDataReceived = this.sDataReceived.substr(1);\n }\n if (this.sDataReceived && this.cpu) {\n this.cpu.setTimer(this.timerReceiveNext, this.getBaudTimeout(SerialPort8080.UART8251.BAUDRATES.RECV_RATE));\n }\n }\n return true; // for now, return true regardless, since we're buffering everything anyway\n }\n\n /**\n * receiveStatus(pins)\n *\n * NOTE: Prior to the addition of this interface, the DSR bit was initialized set and remained set for the life\n * of the machine. It is entirely appropriate that this is the only way the bit can be changed, because it represents\n * an external control signal.\n *\n * @this {SerialPort8080}\n * @param {number} pins\n */\n receiveStatus(pins)\n {\n this.bStatus &= ~SerialPort8080.UART8251.STATUS.DSR;\n if (pins & RS232.DSR.MASK) this.bStatus |= SerialPort8080.UART8251.STATUS.DSR;\n }\n\n /**\n * transmitByte(b)\n *\n * @this {SerialPort8080}\n * @param {number} b\n * @return {boolean} true if transmitted, false if not\n */\n transmitByte(b)\n {\n var fTransmitted = false;\n\n this.printMessage(\"transmitByte(\" + Str.toHexByte(b) + \")\");\n\n if (this.fAutoXOFF) {\n if (b == 0x13) { // XOFF\n this.fAutoStop = true;\n return false;\n }\n if (b == 0x11) { // XON\n this.fAutoStop = false;\n return false;\n }\n }\n\n if (this.sendData && this.sendData.call(this.connection, b)) {\n fTransmitted = true;\n }\n\n if (this.echoByte(b)) {\n fTransmitted = true;\n }\n\n return fTransmitted;\n }\n\n /**\n * transmitData(sData)\n *\n * Helper for clocking transmitted data at the expected XMIT_RATE.\n *\n * When timerTransmitNext fires, we have honored the programmed XMIT_RATE period, so we can\n * set XMIT_READY (and XMIT_EMPTY), which signals the firmware that another byte can be transmitted.\n *\n * The sData parameter is not used when we're called via the timer; it's an optional parameter used by\n * the Keyboard component to deliver data pasted via the clipboard, and is currently only useful when\n * the SerialPort is connected to another machine. TODO: Define a separate interface for that feature.\n *\n * @this {SerialPort8080}\n * @param {string} [sData]\n * @return {boolean} true if successful, false if not\n */\n transmitData(sData)\n {\n this.bStatus |= (SerialPort8080.UART8251.STATUS.XMIT_READY | SerialPort8080.UART8251.STATUS.XMIT_EMPTY);\n if (sData) {\n return this.sendData? this.sendData.call(this.connection, sData) : false;\n }\n return true;\n }\n\n /**\n * isTransmitterReady()\n *\n * Called whenever a ChipSet circuit needs the SerialPort8080 UART's transmitter status.\n *\n * @this {SerialPort8080}\n * @return {boolean} (true if ready, false if not)\n */\n isTransmitterReady()\n {\n return !!(this.bStatus & SerialPort8080.UART8251.STATUS.XMIT_READY);\n }\n\n /**\n * inData(port, addrFrom)\n *\n * @this {SerialPort8080}\n * @param {number} port (0x0)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inData(port, addrFrom)\n {\n var b = this.bDataIn;\n this.printMessageIO(port, null, addrFrom, \"DATA\", b);\n this.bStatus &= ~SerialPort8080.UART8251.STATUS.RECV_FULL;\n return b;\n }\n\n /**\n * inControl(port, addrFrom)\n *\n * @this {SerialPort8080}\n * @param {number} port (0x1)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inControl(port, addrFrom)\n {\n var b = this.bStatus;\n this.printMessageIO(port, null, addrFrom, \"STATUS\", b);\n return b;\n }\n\n /**\n * outData(port, bOut, addrFrom)\n *\n * @this {SerialPort8080}\n * @param {number} port (0x0)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outData(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"DATA\");\n this.bDataOut = bOut;\n this.bStatus &= ~(SerialPort8080.UART8251.STATUS.XMIT_READY | SerialPort8080.UART8251.STATUS.XMIT_EMPTY);\n /*\n * If we're transmitting to a virtual device that has no measurable delay, this code may clear XMIT_READY\n * too quickly:\n *\n * if (this.transmitByte(bOut)) {\n * this.bStatus |= (SerialPort8080.UART8251.STATUS.XMIT_READY | SerialPort8080.UART8251.STATUS.XMIT_EMPTY);\n * }\n *\n * A better solution is to arm a timer based on the XMIT_RATE baud rate, and clear the above bits when that\n * timer fires. Consequently, we no longer care what transmitByte() reports.\n */\n this.transmitByte(bOut);\n if (this.cpu) {\n this.cpu.setTimer(this.timerTransmitNext, this.getBaudTimeout(SerialPort8080.UART8251.BAUDRATES.XMIT_RATE));\n }\n }\n\n /**\n * outControl(port, bOut, addrFrom)\n *\n * Writes to the CONTROL port (0x1) are either MODE or COMMAND bytes. If the device has just\n * been powered or reset, it is in a \"not ready\" state and is waiting for a MODE byte. Once it\n * has received that initial byte, the device is marked \"ready\", and all further bytes are\n * interpreted as COMMAND bytes (until/unless a COMMAND byte with the INTERNAL_RESET bit is set).\n *\n * @this {SerialPort8080}\n * @param {number} port (0x1)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outControl(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"CONTROL\");\n if (!this.fReady) {\n this.bMode = bOut;\n this.fReady = true;\n } else {\n /*\n * Whenever DTR or RTS changes, we also want to notify any connected machine, via updateStatus().\n */\n if (this.updateStatus) {\n var delta = (bOut ^ this.bCommand);\n if (delta & (SerialPort8080.UART8251.COMMAND.RTS | SerialPort8080.UART8251.COMMAND.DTR)) {\n var pins = 0;\n if (this.fNullModem) {\n pins |= (bOut & SerialPort8080.UART8251.COMMAND.RTS)? RS232.CTS.MASK : 0;\n pins |= (bOut & SerialPort8080.UART8251.COMMAND.DTR)? (RS232.DSR.MASK | RS232.CD.MASK): 0;\n } else {\n pins |= (bOut & SerialPort8080.UART8251.COMMAND.RTS)? RS232.RTS.MASK : 0;\n pins |= (bOut & SerialPort8080.UART8251.COMMAND.DTR)? RS232.DTR.MASK : 0;\n }\n this.updateStatus.call(this.connection, pins);\n }\n }\n this.bCommand = bOut;\n if (this.bCommand & SerialPort8080.UART8251.COMMAND.INTERNAL_RESET) {\n this.fReady = false;\n }\n }\n }\n\n /**\n * outBaudRates(port, bOut, addrFrom)\n *\n * @this {SerialPort8080}\n * @param {number} port (0x2)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outBaudRates(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"BAUDRATES\");\n this.bBaudRates = bOut;\n }\n\n /**\n * SerialPort8080.init()\n *\n * This function operates on every HTML element of class \"serial\", extracting the\n * JSON-encoded parameters for the SerialPort8080 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a SerialPort8080 component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeSerial = Component.getElementsByClass(document, PC8080.APPCLASS, \"serial\");\n for (var iSerial = 0; iSerial < aeSerial.length; iSerial++) {\n var eSerial = aeSerial[iSerial];\n var parmsSerial = Component.getComponentParms(eSerial);\n var serial = new SerialPort8080(parmsSerial);\n Component.bindComponentControls(serial, eSerial, PC8080.APPCLASS);\n }\n }\n}\n\nSerialPort8080.UART8251 = {\n /*\n * Format of MODE byte written to CONTROL port 0x1\n */\n MODE: {\n BAUD_FACTOR: 0x03, // 00=SYNC, 01=1x, 10=16x, 11=64x\n DATA_BITS: 0x0C, // 00=5, 01=6, 10=7, 11=8\n PARITY_ENABLE: 0x10,\n EVEN_PARITY: 0x20,\n STOP_BITS: 0xC0, // 00=invalid, 01=1, 10=1.5, 11=2\n INIT: 0x8E // 16x baud rate, 8 data bits, no parity, 1.5 stop bits\n },\n /*\n * Format of COMMAND byte written to CONTROL port 0x1\n */\n COMMAND: {\n XMIT_ENABLE: 0x01,\n DTR: 0x02, // Data Terminal Ready\n RECV_ENABLE: 0x04,\n SEND_BREAK: 0x08,\n ERROR_RESET: 0x10,\n RTS: 0x20, // Request To Send\n INTERNAL_RESET: 0x40,\n HUNT_MODE: 0x80,\n INIT: 0x27 // XMIT_ENABLE | DTR | RECV_ENABLE | RTS\n },\n /*\n * Format of STATUS byte read from CONTROL port 0x1\n */\n STATUS: {\n XMIT_READY: 0x01,\n RECV_FULL: 0x02,\n XMIT_EMPTY: 0x04,\n PARITY_ERROR: 0x08,\n OVERRUN_ERROR: 0x10,\n FRAMING_ERROR: 0x20,\n BREAK_DETECT: 0x40,\n DSR: 0x80, // Data Set Ready\n INIT: 0x85 // XMIT_READY | XMIT_EMPTY | DSR\n },\n /*\n * Format of BAUDRATES byte written to port 0x2\n *\n * Each nibble is an index (0x0-0xF) into a set of internal CPU clock divisors that yield the\n * following baud rates:\n *\n * Index Divisor Baud Rate\n * ----- ------- ---------\n * 0x0 3456 50\n * 0x1 2304 75\n * 0x2 1571 110\n * 0x3 1285 134.5\n * 0x4 1152 150\n * 0x5 864 200\n * 0x6 576 300\n * 0x7 288 600\n * 0x8 144 1200\n * 0x9 96 1800\n * 0xA 86 2000\n * 0xB 72 2400\n * 0xC 48 3600\n * 0xD 36 4800\n * 0xE 18 9600 (default)\n * 0xF 9 19200\n *\n * NOTE: This is a VT100-specific port and baud rate table.\n */\n BAUDRATES: {\n RECV_RATE: 0x0F,\n XMIT_RATE: 0xF0,\n INIT: 0xEE // default to 9600 (0xE) for both XMIT and RECV\n },\n BAUDTABLE: [\n 50, 75, 110, 134.5, 150, 200, 300, 600, 1200, 1800, 2000, 2400, 3600, 4800, 9600, 19200\n ]\n};\n\nSerialPort8080.UART8251.INIT = [\n false,\n 0,\n 0,\n SerialPort8080.UART8251.STATUS.INIT,\n SerialPort8080.UART8251.MODE.INIT,\n SerialPort8080.UART8251.COMMAND.INIT,\n SerialPort8080.UART8251.BAUDRATES.INIT\n];\n\n/*\n * Port input notification table\n */\nSerialPort8080.aPortInput = {\n 0x0: SerialPort8080.prototype.inData,\n 0x1: SerialPort8080.prototype.inControl\n\n};\n\n/*\n * Port output notification table\n */\nSerialPort8080.aPortOutput = {\n 0x0: SerialPort8080.prototype.outData,\n 0x1: SerialPort8080.prototype.outControl,\n 0x2: SerialPort8080.prototype.outBaudRates\n};\n\n/*\n * Initialize every SerialPort8080 module on the page.\n */\nWeb.onInit(SerialPort8080.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/debugger.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Debugger Address Object\n *\n * This is the basic structure; other debuggers may extend it.\n *\n * addr address\n * fTemporary true if this is a temporary breakpoint address\n * sCmd set for breakpoint addresses if there's an associated command string\n * aCmds preprocessed commands (from sCmd)\n *\n * @typedef {{\n * addr:(number|undefined),\n * fTemporary:(boolean|undefined),\n * sCmd:(string|undefined),\n * aCmds:(Array.<string>|undefined)\n * }}\n */\nvar DbgAddr;\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * subclass (eg, SerialPort), because otherwise the Compiler won't allow us to *reference*\n * the named property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass Debugger extends Component\n{\n /**\n * Debugger(parmsDbg)\n *\n * The Debugger component supports the following optional (parmsDbg) properties:\n *\n * base: the base to use for most numeric input/output (default is 16)\n *\n * The Debugger component is a shared component containing a subset of functionality used by\n * the other CPU-specific Debuggers (eg, DebuggerX86). Over time, the goal is to factor out as\n * much common debugging support as possible from those components into this one.\n *\n * @param {Object} parmsDbg\n */\n constructor(parmsDbg)\n {\n if (DEBUGGER) {\n\n super(\"Debugger\", parmsDbg);\n\n /*\n * Default base used to display all values; modified with the \"s base\" command.\n */\n this.nBase = +parmsDbg['base'] || 16;\n\n /*\n * Default number of bits of integer precision; it can be overridden by the Debugger\n * but there is no command to adjust it.\n */\n this.nBits = 32;\n\n this.achGroup = ['{','}'];\n this.achAddress = ['[',']'];\n\n /*\n * These keep track of instruction activity, but only when tracing or when Debugger checks\n * have been enabled (eg, one or more breakpoints have been set).\n *\n * They are zeroed by the reset() notification handler. cInstructions is advanced by\n * stepCPU() and checkInstruction() calls. nCycles is updated by every stepCPU() or stop()\n * call and simply represents the number of cycles performed by the last run of instructions.\n */\n this.nCycles = 0;\n this.cOpcodes = this.cOpcodesStart = 0;\n\n /*\n * fAssemble is true when \"assemble mode\" is active, false when not.\n */\n this.fAssemble = false;\n\n /*\n * This maintains command history. New commands are inserted at index 0 of the array.\n * When Enter is pressed on an empty input buffer, we default to the command at aPrevCmds[0].\n */\n this.iPrevCmd = -1;\n this.aPrevCmds = [];\n\n /*\n * aVariables is an object with properties that grow as setVariable() assigns more variables;\n * each property corresponds to one variable, where the property name is the variable name (ie,\n * a string beginning with a non-digit, followed by zero or more symbol characters and/or digits)\n * and the property value is the variable's numeric value. See doVar() and setVariable() for\n * details.\n *\n * Note that parseValue() parses variables before numbers, so any variable that looks like a\n * unprefixed hex value (eg, \"a5\" as opposed to \"0xa5\") will trump the numeric value. Unprefixed\n * hex values are a convenience of parseValue(), which always calls Str.parseInt() with a default\n * base of 16; however, that default be overridden with a variety of explicit prefixes or suffixes\n * (eg, a leading \"0o\" to indicate octal, a trailing period to indicate decimal, etc.)\n *\n * See Str.parseInt() for more details about supported numbers.\n */\n this.aVariables = {};\n\n } // endif DEBUGGER\n }\n\n /**\n * getRegIndex(sReg, off)\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {string} sReg\n * @param {number} [off] optional offset into sReg\n * @return {number} register index, or -1 if not found\n */\n getRegIndex(sReg, off)\n {\n return -1;\n }\n\n /**\n * getRegValue(iReg)\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {number} iReg\n * @return {number|undefined}\n */\n getRegValue(iReg)\n {\n return undefined;\n }\n\n /**\n * parseAddrReference(s, sAddr)\n *\n * Returns the given string with the given address reference replaced with the contents of that address.\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {string} s\n * @param {string} sAddr\n * @return {string}\n */\n parseAddrReference(s, sAddr)\n {\n return s.replace('[' + sAddr + ']', \"unimplemented\");\n }\n\n /**\n * getNextCommand()\n *\n * @this {Debugger}\n * @return {string}\n */\n getNextCommand()\n {\n var sCmd;\n if (this.iPrevCmd > 0) {\n sCmd = this.aPrevCmds[--this.iPrevCmd];\n } else {\n sCmd = \"\";\n this.iPrevCmd = -1;\n }\n return sCmd;\n }\n\n /**\n * getPrevCommand()\n *\n * @this {Debugger}\n * @return {string|null}\n */\n getPrevCommand()\n {\n var sCmd = null;\n if (this.iPrevCmd < this.aPrevCmds.length - 1) {\n sCmd = this.aPrevCmds[++this.iPrevCmd];\n }\n return sCmd;\n }\n\n /**\n * parseCommand(sCmd, fSave, chSep)\n *\n * @this {Debugger}\n * @param {string|undefined} sCmd\n * @param {boolean} [fSave] is true to save the command, false if not\n * @param {string} [chSep] is the command separator character (default is ';')\n * @return {Array.<string>}\n */\n parseCommand(sCmd, fSave, chSep)\n {\n if (fSave) {\n if (!sCmd) {\n if (this.fAssemble) {\n sCmd = \"end\";\n } else {\n sCmd = this.aPrevCmds[this.iPrevCmd+1];\n }\n } else {\n if (this.iPrevCmd < 0 && this.aPrevCmds.length) {\n this.iPrevCmd = 0;\n }\n if (this.iPrevCmd < 0 || sCmd != this.aPrevCmds[this.iPrevCmd]) {\n this.aPrevCmds.splice(0, 0, sCmd);\n this.iPrevCmd = 0;\n }\n this.iPrevCmd--;\n }\n }\n var a = [];\n if (sCmd) {\n /*\n * With the introduction of breakpoint commands (ie, quoted command sequences\n * associated with a breakpoint), we can no longer perform simplistic splitting.\n *\n * a = sCmd.split(chSep || ';');\n * for (var i = 0; i < a.length; i++) a[i] = Str.trim(a[i]);\n *\n * We may now split on semi-colons ONLY if they are outside a quoted sequence.\n *\n * Also, to allow quoted strings *inside* breakpoint commands, we first replace all\n * DOUBLE double-quotes with single quotes.\n */\n sCmd = sCmd.replace(/\"\"/g, \"'\");\n\n var iPrev = 0;\n var chQuote = null;\n chSep = chSep || ';';\n /*\n * NOTE: Processing charAt() up to and INCLUDING length is not a typo; we're taking\n * advantage of the fact that charAt() with an invalid index returns an empty string,\n * allowing us to use the same substring() call to capture the final portion of sCmd.\n *\n * In a sense, it allows us to pretend that the string ends with a zero terminator.\n */\n for (var i = 0; i <= sCmd.length; i++) {\n var ch = sCmd.charAt(i);\n if (ch == '\"' || ch == \"'\") {\n if (!chQuote) {\n chQuote = ch;\n } else if (ch == chQuote) {\n chQuote = null;\n }\n }\n else if (ch == chSep && !chQuote || !ch) {\n /*\n * Recall that substring() accepts starting (inclusive) and ending (exclusive)\n * indexes, whereas substr() accepts a starting index and a length. We need the former.\n */\n a.push(Str.trim(sCmd.substring(iPrev, i)));\n iPrev = i + 1;\n }\n }\n }\n return a;\n }\n\n /**\n * evalAND(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.AND().\n *\n * Performs the bitwise \"and\" (AND) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst & src)\n */\n evalAND(dst, src)\n {\n /*\n * We AND the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 AND 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst & src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) & ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst & src) >>> 0);\n }\n\n /**\n * evalIOR(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.IOR().\n *\n * Performs the logical \"inclusive-or\" (OR) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst | src)\n */\n evalIOR(dst, src)\n {\n /*\n * We OR the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 OR 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst | src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) | ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst | src) >>> 0);\n }\n\n /**\n * evalXOR(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.XOR().\n *\n * Performs the logical \"exclusive-or\" (XOR) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst ^ src)\n */\n evalXOR(dst, src)\n {\n /*\n * We XOR the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 XOR 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst | src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) ^ ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst ^ src) >>> 0);\n }\n\n /**\n * evalMUL(dst, src)\n *\n * I could have adapted the code from /modules/pdp10/lib/cpuops.js:PDP10.doMUL(), but it was simpler to\n * write this base method and let the PDP-10 Debugger override it with a call to the *actual* doMUL() method.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst * src)\n */\n evalMUL(dst, src)\n {\n return dst * src;\n }\n\n /**\n * truncate(v, nBits, fUnsigned)\n *\n * @this {Debugger}\n * @param {number} v\n * @param {number} [nBits]\n * @param {boolean} [fUnsigned]\n * @return {number}\n */\n truncate(v, nBits, fUnsigned)\n {\n var limit, vNew = v;\n nBits = nBits || this.nBits;\n\n if (fUnsigned) {\n if (nBits == 32) {\n vNew = v >>> 0;\n }\n else if (nBits < 32) {\n vNew = v & ((1 << nBits) - 1);\n }\n else {\n limit = Math.pow(2, nBits);\n if (v < 0 || v >= limit) {\n vNew = v % limit;\n if (vNew < 0) vNew += limit;\n }\n }\n }\n else {\n if (nBits <= 32) {\n vNew = (v << (32 - nBits)) >> (32 - nBits);\n }\n else {\n limit = Math.pow(2, nBits - 1);\n if (v >= limit) {\n vNew = (v % limit);\n if (((v / limit)|0) & 1) vNew -= limit;\n } else if (v < -limit) {\n vNew = (v % limit);\n if ((((-v - 1) / limit) | 0) & 1) {\n if (vNew) vNew += limit;\n }\n else {\n if (!vNew) vNew -= limit;\n }\n }\n }\n }\n if (v != vNew) {\n if (MAXDEBUG) this.println(\"warning: value \" + v + \" truncated to \" + vNew);\n v = vNew;\n }\n return v;\n }\n\n /**\n * evalOps(aVals, aOps, cOps)\n *\n * Some of our clients want a specific number of bits of integer precision. If that precision is\n * greater than 32, some of the operations below will fail; for example, JavaScript bitwise operators\n * always truncate the result to 32 bits, so beware when using shift operations. Similarly, it would\n * be wrong to always \"|0\" the final result, which is why we rely on truncate() now.\n *\n * Note that JavaScript integer precision is limited to 52 bits. For example, in Node, if you set a\n * variable to 0x80000001:\n *\n * foo=0x80000001|0\n *\n * then calculate foo*foo and display the result in binary using \"(foo*foo).toString(2)\":\n *\n * '11111111111111111111111111111100000000000000000000000000000000'\n *\n * which is slightly incorrect because it has overflowed JavaScript's floating-point precision.\n *\n * 0x80000001 in decimal is -2147483647, so the product is 4611686014132420609, which is 0x3FFFFFFF00000001.\n *\n * @this {Debugger}\n * @param {Array.<number>} aVals\n * @param {Array.<string>} aOps\n * @param {number} [cOps] (default is -1 for all)\n * @return {boolean} true if successful, false if error\n */\n evalOps(aVals, aOps, cOps = -1)\n {\n while (cOps-- && aOps.length) {\n var chOp = aOps.pop();\n if (aVals.length < 2) return false;\n var valNew;\n var val2 = aVals.pop();\n var val1 = aVals.pop();\n switch(chOp) {\n case '*':\n valNew = this.evalMUL(val1, val2);\n break;\n case '/':\n if (!val2) return false;\n valNew = Math.trunc(val1 / val2);\n break;\n case '^/':\n if (!val2) return false;\n valNew = val1 % val2;\n break;\n case '+':\n valNew = val1 + val2;\n break;\n case '-':\n valNew = val1 - val2;\n break;\n case '<<':\n valNew = val1 << val2;\n break;\n case '>>':\n valNew = val1 >> val2;\n break;\n case '>>>':\n valNew = val1 >>> val2;\n break;\n case '<':\n valNew = (val1 < val2? 1 : 0);\n break;\n case '<=':\n valNew = (val1 <= val2? 1 : 0);\n break;\n case '>':\n valNew = (val1 > val2? 1 : 0);\n break;\n case '>=':\n valNew = (val1 >= val2? 1 : 0);\n break;\n case '==':\n valNew = (val1 == val2? 1 : 0);\n break;\n case '!=':\n valNew = (val1 != val2? 1 : 0);\n break;\n case '&':\n valNew = this.evalAND(val1, val2);\n break;\n case '!': // alias for MACRO-10 to perform a bitwise inclusive-or (OR)\n case '|':\n valNew = this.evalIOR(val1, val2);\n break;\n case '^!': // since MACRO-10 uses '^' for base overrides, '^!' is used for bitwise exclusive-or (XOR)\n valNew = this.evalXOR(val1, val2);\n break;\n case '&&':\n valNew = (val1 && val2? 1 : 0);\n break;\n case '||':\n valNew = (val1 || val2? 1 : 0);\n break;\n case ',,':\n valNew = this.truncate(val1, 18, true) * Math.pow(2, 18) + this.truncate(val2, 18, true);\n break;\n case '_':\n case '^_':\n valNew = val1;\n /*\n * While we always try to avoid assuming any particular number of bits of precision, the 'B' shift\n * operator (which we've converted to '^_') is unique to the MACRO-10 environment, which imposes the\n * following restrictions on the shift count.\n */\n if (chOp == '^_') val2 = 35 - (val2 & 0xff);\n if (val2) {\n /*\n * Since binary shifting is a logical (not arithmetic) operation, and since shifting by division only\n * works properly with positive numbers, we call truncate() to produce an unsigned value.\n */\n valNew = this.truncate(valNew, 0, true);\n if (val2 > 0) {\n valNew *= Math.pow(2, val2);\n } else {\n valNew = Math.trunc(valNew / Math.pow(2, -val2));\n }\n }\n break;\n default:\n return false;\n }\n aVals.push(this.truncate(valNew));\n }\n return true;\n }\n\n /**\n * parseArray(asValues, iValue, iLimit, nBase, aUndefined)\n *\n * parseExpression() takes a complete expression and divides it into array elements, where even elements\n * are values (which may be empty if two or more operators appear consecutively) and odd elements are operators.\n *\n * For example, if the original expression was \"2*{3+{4/2}}\", parseExpression() would call parseArray() with:\n *\n * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14\n * - - - - - - - - - - -- -- -- -- --\n * 2 * { 3 + { 4 / 2 } }\n *\n * This function takes care of recursively processing grouped expressions, by processing subsets of the array,\n * as well as handling certain base overrides (eg, temporarily switching to base-10 for binary shift suffixes).\n *\n * @param {Array.<string>} asValues\n * @param {number} iValue\n * @param {number} iLimit\n * @param {number} nBase\n * @param {Array|undefined} [aUndefined]\n * @return {number|undefined}\n */\n parseArray(asValues, iValue, iLimit, nBase, aUndefined)\n {\n var value;\n var sValue, sOp;\n var fError = false;\n var nUnary = 0;\n var aVals = [], aOps = [];\n\n var nBasePrev = this.nBase;\n this.nBase = nBase;\n\n while (iValue < iLimit) {\n var v;\n sValue = asValues[iValue++].trim();\n sOp = (iValue < iLimit? asValues[iValue++] : \"\");\n\n if (sValue) {\n v = this.parseValue(sValue, null, aUndefined, nUnary);\n } else {\n if (sOp == '{') {\n var cOpen = 1;\n var iStart = iValue;\n while (iValue < iLimit) {\n sValue = asValues[iValue++].trim();\n sOp = (iValue < asValues.length? asValues[iValue++] : \"\");\n if (sOp == '{') {\n cOpen++;\n } else if (sOp == '}') {\n if (!--cOpen) break;\n }\n }\n v = this.parseArray(asValues, iStart, iValue-1, this.nBase, aUndefined);\n if (v != null && nUnary) {\n v = this.parseUnary(v, nUnary);\n }\n sValue = (iValue < iLimit? asValues[iValue++].trim() : \"\");\n sOp = (iValue < iLimit? asValues[iValue++] : \"\");\n }\n else {\n /*\n * When parseExpression() calls us, it has collapsed all runs of whitespace into single spaces,\n * and although it allows single spaces to divide the elements of the expression, a space is neither\n * a unary nor binary operator. It's essentially a no-op. If we encounter it here, then it followed\n * another operator and is easily ignored (although perhaps it should still trigger a reset of nBase\n * and nUnary -- TBD).\n */\n if (sOp == ' ') {\n continue;\n }\n if (sOp == '^B') {\n this.nBase = 2;\n continue;\n }\n if (sOp == '^O') {\n this.nBase = 8;\n continue;\n }\n if (sOp == '^D') {\n this.nBase = 10;\n continue;\n }\n if (!(nUnary & (0xC0000000|0))) {\n if (sOp == '+') {\n continue;\n }\n if (sOp == '-') {\n nUnary = (nUnary << 2) | 1;\n continue;\n }\n if (sOp == '~' || sOp == '^-') {\n nUnary = (nUnary << 2) | 2;\n continue;\n }\n if (sOp == '^L') {\n nUnary = (nUnary << 2) | 3;\n continue;\n }\n }\n fError = true;\n break;\n }\n }\n\n if (v === undefined) {\n if (aUndefined) {\n aUndefined.push(sValue);\n v = 0;\n } else {\n fError = true;\n aUndefined = [];\n break;\n }\n }\n\n aVals.push(this.truncate(v));\n\n /*\n * When parseExpression() calls us, it has collapsed all runs of whitespace into single spaces,\n * and although it allows single spaces to divide the elements of the expression, a space is neither\n * a unary nor binary operator. It's essentially a no-op. If we encounter it here, then it followed\n * a value, and since we don't want to misinterpret the next operator as a unary operator, we look\n * ahead and grab the next operator if it's not preceded by a value.\n */\n if (sOp == ' ') {\n if (iValue < asValues.length - 1 && !asValues[iValue]) {\n iValue++;\n sOp = asValues[iValue++]\n } else {\n fError = true;\n break;\n }\n }\n\n if (!sOp) break;\n\n var aBinOp = (this.achGroup[0] == '<'? Debugger.aDECOpPrecedence : Debugger.aBinOpPrecedence);\n if (!aBinOp[sOp]) {\n fError = true;\n break;\n }\n if (aOps.length && aBinOp[sOp] <= aBinOp[aOps[aOps.length - 1]]) {\n this.evalOps(aVals, aOps, 1);\n }\n aOps.push(sOp);\n\n /*\n * The MACRO-10 binary shifting operator assumes a base-10 shift count, regardless of the current\n * base, so we must override the current base to ensure the count is parsed correctly.\n */\n this.nBase = (sOp == '^_')? 10 : nBase;\n nUnary = 0;\n }\n\n if (fError || !this.evalOps(aVals, aOps) || aVals.length != 1) {\n fError = true;\n }\n\n if (!fError) {\n value = aVals.pop();\n\n } else if (!aUndefined) {\n this.println(\"parse error (\" + (sValue || sOp) + \")\");\n }\n\n this.nBase = nBasePrev;\n return value;\n }\n\n /**\n * parseASCII(sExp, chDelim, nBits, cchMax)\n *\n * @this {Debugger}\n * @param {string} sExp\n * @param {string} chDelim\n * @param {number} nBits\n * @param {number} cchMax\n * @return {string|undefined}\n */\n parseASCII(sExp, chDelim, nBits, cchMax)\n {\n var i;\n while ((i = sExp.indexOf(chDelim)) >= 0) {\n var v = 0;\n var j = i + 1;\n var cch = cchMax;\n while (j < sExp.length) {\n var ch = sExp[j++];\n if (ch == chDelim) {\n cch = -1;\n break;\n }\n if (!cch) break;\n cch--;\n var c = ch.charCodeAt(0);\n if (nBits == 7) {\n c &= 0x7F;\n } else {\n c = (c - 0x20) & 0x3F;\n }\n v = this.truncate(v * Math.pow(2, nBits) + c, nBits * cchMax, true);\n }\n if (cch >= 0) {\n this.println(\"parse error (\" + chDelim + sExp + chDelim + \")\");\n return undefined;\n } else {\n sExp = sExp.substr(0, i) + this.toStrBase(v, -1) + sExp.substr(j);\n }\n }\n return sExp;\n }\n\n /**\n * parseExpression(sExp, fQuiet)\n *\n * A quick-and-dirty expression parser. It takes an expression like:\n *\n * EDX+EDX*4+12345678\n *\n * and builds a value stack in aVals and a \"binop\" (binary operator) stack in aOps:\n *\n * aVals aOps\n * ----- ----\n * EDX +\n * EDX *\n * 4 +\n * ...\n *\n * We pop 1 \"binop\" from aOps and 2 values from aVals whenever a \"binop\" of lower priority than its\n * predecessor is encountered, evaluate, and push the result back onto aVals. Only selected unary\n * operators are supported (eg, negate and complement); no ternary operators like '?:' are supported.\n *\n * fQuiet can be used to pass an array that collects any undefined variables that parseExpression()\n * encounters; the value of an undefined variable is zero. This mode was added for components that need\n * to support expressions containing \"fixups\" (ie, values that must be determined later).\n *\n * @this {Debugger}\n * @param {string|undefined} sExp\n * @param {Array|undefined|boolean} [fQuiet]\n * @return {number|undefined} numeric value, or undefined if sExp contains any undefined or invalid values\n */\n parseExpression(sExp, fQuiet)\n {\n var value = undefined;\n var fPrint = (fQuiet === false);\n var aUndefined = Array.isArray(fQuiet)? fQuiet : undefined;\n\n if (sExp) {\n\n /*\n * The default delimiting characters for grouped expressions are braces; they can be changed by altering\n * achGroup, but when that happens, instead of changing our regular expressions and operator tables,\n * we simply replace all achGroup characters with braces in the given expression.\n *\n * Why not use parentheses for grouped expressions? Because some debuggers use parseReference() to perform\n * parenthetical value replacements in message strings, and they don't want parentheses taking on a different\n * meaning. And for some machines, like the PDP-10, the convention is to use parentheses for other things,\n * like indexed addressing, and to use angle brackets for grouped expressions.\n */\n if (this.achGroup[0] != '{') {\n sExp = sExp.split(this.achGroup[0]).join('{').split(this.achGroup[1]).join('}');\n }\n\n /*\n * Quoted ASCII characters can have a numeric value, too, which must be converted now, to avoid any\n * conflicts with the operators below.\n */\n sExp = this.parseASCII(sExp, '\"', 7, 5); // MACRO-10 packs up to 5 7-bit ASCII codes into a value\n if (!sExp) return value;\n sExp = this.parseASCII(sExp, \"'\", 6, 6); // MACRO-10 packs up to 6 6-bit ASCII (SIXBIT) codes into a value\n if (!sExp) return value;\n\n /*\n * All browsers (including, I believe, IE9 and up) support the following idiosyncrasy of a RegExp split():\n * when the RegExp uses a capturing pattern, the resulting array will include entries for all the pattern\n * matches along with the non-matches. This effectively means that, in the set of expressions that we\n * support, all even entries in asValues will contain \"values\" and all odd entries will contain \"operators\".\n *\n * Although I started listing the operators in the RegExp in \"precedential\" order, that's not important;\n * what IS important is listing operators than contain shorter operators first. For example, bitwise\n * shift operators must be listed BEFORE the logical less-than or greater-than operators. The aBinOp tables\n * (aBinOpPrecedence and aDECOpPrecedence) are what determine precedence, not the RegExp.\n *\n * Also, to better accommodate MACRO-10 syntax, I've replaced the single '^' for XOR with '^!', and I've\n * added '!' as an alias for '|' (bitwise inclusive-or), '^-' as an alias for '~' (one's complement operator),\n * and '_' as a shift operator (+/- values specify a left/right shift, and the count is not limited to 32).\n *\n * And to avoid conflicts with MACRO-10 syntax, I've replaced the original mod operator ('%') with '^/'.\n *\n * The MACRO-10 binary shifting suffix ('B') is a bit more problematic, since a capital B can also appear\n * inside symbols, or inside hex values. So if the default base is NOT 16, then I pre-scan for that suffix\n * and replace all non-symbolic occurrences with an internal shift operator ('^_').\n *\n * Note that Str.parseInt(), which parseValue() relies on, supports both the MACRO-10 base prefix overrides\n * and the binary shifting suffix ('B'), but since that suffix can also be a bracketed expression, we have to\n * support it here as well.\n *\n * MACRO-10 supports only a subset of all the PCjs operators; for example, MACRO-10 doesn't support any of\n * the boolean logical/compare operators. But unless we run into conflicts, I prefer sticking with this\n * common set of operators.\n *\n * All whitespace in the expression is collapsed to single spaces, and space has been added to the list\n * of \"operators\", but its sole function is as a separator, not as an operator. parseArray() will ignore\n * single spaces as long as they are preceded and/or followed by a \"real\" operator. It would be dangerous\n * to remove spaces entirely, because if an operator-less expression like \"A B\" was passed in, we would want\n * that to generate an error; if we converted it to \"AB\", evaluation might inadvertently succeed.\n */\n var regExp = /({|}|\\|\\||&&|\\||\\^!|\\^B|\\^O|\\^D|\\^L|\\^-|~|\\^_|_|&|!=|!|==|>=|>>>|>>|>|<=|<<|<|-|\\+|\\^\\/|\\/|\\*|,,| )/;\n if (this.nBase != 16) {\n sExp = sExp.replace(/(^|[^A-Z0-9$%.])([0-9]+)B/, \"$1$2^_\").replace(/\\s+/g, ' ');\n }\n var asValues = sExp.split(regExp);\n value = this.parseArray(asValues, 0, asValues.length, this.nBase, aUndefined);\n if (value !== undefined && fPrint) {\n this.printValue(null, value);\n }\n }\n return value;\n }\n\n /**\n * parseReference(s)\n *\n * Returns the given string with any \"{expression}\" sequences replaced with the value of the expression,\n * and any \"[address]\" references replaced with the contents of the address. Expressions are parsed BEFORE\n * addresses.\n *\n * @this {Debugger}\n * @param {string} s\n * @return {string|undefined}\n */\n parseReference(s)\n {\n var a;\n var chOpen = this.achGroup[0];\n var chClose = this.achGroup[1];\n var chEscape = (chOpen == '(' || chOpen == '{' || chOpen == '[')? '\\\\' : '';\n var chInnerEscape = (chOpen == '['? '\\\\' : '');\n var reSubExp = new RegExp(chEscape + chOpen + \"([^\" + chInnerEscape + chOpen + chInnerEscape + chClose + \"]+)\" + chEscape + chClose);\n while (a = s.match(reSubExp)) {\n var value = this.parseExpression(a[1]);\n if (value === undefined) return undefined;\n var sSearch = chOpen + a[1] + chClose;\n var sReplace = value != null? this.toStrBase(value) : \"undefined\";\n /*\n * Note that by default, the String replace() method only replaces the FIRST occurrence,\n * and there MIGHT be more than one occurrence of the expression we just parsed, so we could\n * do this instead:\n *\n * s = s.split(sSearch).join(sReplace);\n *\n * However, that's knd of an expensive (slow) solution, and it's not strictly necessary, since\n * any additional identical expressions will be picked up on a subsequent iteration through this loop.\n */\n s = s.replace(sSearch, sReplace);\n }\n if (this.achAddress.length) {\n chOpen = this.achAddress[0];\n chClose = this.achAddress[1];\n chEscape = (chOpen == '(' || chOpen == '{' || chOpen == '[')? '\\\\' : '';\n chInnerEscape = (chOpen == '['? '\\\\' : '');\n reSubExp = new RegExp(chEscape + chOpen + \"([^\" + chInnerEscape + chOpen + chInnerEscape + chClose + \"]+)\" + chEscape + chClose);\n while (a = s.match(reSubExp)) {\n s = this.parseAddrReference(s, a[1]);\n }\n }\n return this.parseSysVars(s);\n }\n\n /**\n * parseSysVars(s)\n *\n * Returns the given string with any recognized \"$var\" replaced with its value; eg:\n *\n * $ops: the number of opcodes executed since the last time it was displayed (or reset)\n *\n * @this {Debugger}\n * @param {string} s\n * @return {string}\n */\n parseSysVars(s)\n {\n var a;\n while (a = s.match(/\\$([a-z]+)/i)) {\n var v = null;\n switch(a[1].toLowerCase()) {\n case \"ops\":\n v = this.cOpcodes - this.cOpcodesStart;\n break;\n }\n if (v == null) break;\n s = s.replace(a[0], v.toString());\n }\n return s;\n }\n\n /**\n * parseUnary(value, nUnary)\n *\n * nUnary is actually a small \"stack\" of unary operations encoded in successive pairs of bits.\n * As parseExpression() encounters each unary operator, nUnary is shifted left 2 bits, and the\n * new unary operator is encoded in bits 0 and 1 (0b00 is none, 0b01 is negate, 0b10 is complement,\n * and 0b11 is reserved). Here, we process the bits in reverse order (hence the stack-like nature),\n * ensuring that we process the unary operators associated with this value right-to-left.\n *\n * Since bitwise operators see only 32 bits, more than 16 unary operators cannot be supported\n * using this method. We'll let parseExpression() worry about that; if it ever happens in practice,\n * then we'll have to switch to a more \"expensive\" approach (eg, an actual array of unary operators).\n *\n * @this {Debugger}\n * @param {number} value\n * @param {number} nUnary\n * @return {number}\n */\n parseUnary(value, nUnary)\n {\n while (nUnary) {\n switch(nUnary & 0o3) {\n case 1:\n value = -this.truncate(value);\n break;\n case 2:\n value = this.evalXOR(value, -1); // this is easier than adding an evalNOT()...\n break;\n case 3:\n var bit = 35; // simple left-to-right zero-bit-counting loop...\n while (bit >= 0 && !this.evalAND(value, Math.pow(2, bit))) bit--;\n value = 35 - bit;\n break;\n }\n nUnary >>>= 2;\n }\n return value;\n }\n\n /**\n * parseValue(sValue, sName, fQuiet, nUnary)\n *\n * @this {Debugger}\n * @param {string|undefined} sValue\n * @param {string|null} [sName] is the name of the value, if any\n * @param {Array|undefined|boolean} [fQuiet]\n * @param {number} [nUnary] (0 for none, 1 for negate, 2 for complement, 3 for leading zeros)\n * @return {number|undefined} numeric value, or undefined if sValue is either undefined or invalid\n */\n parseValue(sValue, sName, fQuiet, nUnary = 0)\n {\n var value;\n var aUndefined = Array.isArray(fQuiet)? fQuiet : undefined;\n\n if (sValue != null) {\n var iReg = this.getRegIndex(sValue);\n if (iReg >= 0) {\n value = this.getRegValue(iReg);\n } else {\n value = this.getVariable(sValue);\n if (value != null) {\n var sUndefined = this.getVariableFixup(sValue);\n if (sUndefined) {\n if (aUndefined) {\n aUndefined.push(sUndefined);\n } else {\n var valueUndefined = this.parseExpression(sUndefined, fQuiet);\n if (valueUndefined !== undefined) {\n value += valueUndefined;\n } else {\n if (!fQuiet) {\n this.println(\"undefined \" + (sName || \"value\") + \": \" + sValue + \" (\" + sUndefined + \")\");\n }\n value = undefined;\n }\n }\n }\n } else {\n /*\n * A feature of MACRO-10 is that any single-digit number is automatically interpreted as base-10.\n */\n value = Str.parseInt(sValue, sValue.length > 1 || this.nBase > 10? this.nBase : 10);\n }\n }\n if (value != null) {\n value = this.truncate(this.parseUnary(value, nUnary));\n } else {\n if (!fQuiet) {\n this.println(\"invalid \" + (sName || \"value\") + \": \" + sValue);\n }\n }\n } else {\n if (!fQuiet) {\n this.println(\"missing \" + (sName || \"value\"));\n }\n }\n return value;\n }\n\n /**\n * printValue(sVar, value)\n *\n * @this {Debugger}\n * @param {string|null} sVar\n * @param {number|undefined} value\n * @return {boolean} true if value defined, false if not\n */\n printValue(sVar, value)\n {\n var sValue;\n var fDefined = false;\n if (value !== undefined) {\n fDefined = true;\n if (this.nBase == 8) {\n sValue = this.toStrBase(value, this.nBits, 8, 1) + \" \" + value + '.';\n } else {\n sValue = this.toStrBase(value, this.nBits, 16, 1) + \" \" + this.toStrBase(value, this.nBits, 8, 1) + \" \" + this.toStrBase(value, this.nBits, 2, this.nBits <= 32? 8 : 6) + \" \" + value + '.';\n }\n if (value >= 0x20 && value < 0x7F) {\n sValue += \" '\" + String.fromCharCode(value) + \"'\";\n }\n }\n sVar = (sVar != null? (sVar + \": \") : \"\");\n this.println(sVar + sValue);\n return fDefined;\n }\n\n /**\n * resetVariables()\n *\n * @this {Debugger}\n * @return {Object}\n */\n resetVariables()\n {\n var a = this.aVariables;\n this.aVariables = {};\n return a;\n }\n\n /**\n * restoreVariables(a)\n *\n * @this {Debugger}\n * @param {Object} a (from previous resetVariables() call)\n */\n restoreVariables(a)\n {\n this.aVariables = a;\n }\n\n /**\n * printVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} [sVar]\n * @return {boolean} true if all value(s) defined, false if not\n */\n printVariable(sVar)\n {\n var cVariables = 0;\n if (this.aVariables) {\n if (sVar) {\n return this.printValue(sVar, this.aVariables[sVar] && this.aVariables[sVar].value);\n }\n var aVars = Object.keys(this.aVariables);\n aVars.sort();\n for (var i = 0; i < aVars.length; i++) {\n this.printValue(aVars[i], this.aVariables[aVars[i]].value);\n cVariables++;\n }\n }\n return cVariables > 0;\n }\n\n /**\n * delVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n */\n delVariable(sVar)\n {\n delete this.aVariables[sVar];\n }\n\n /**\n * getVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {number|undefined}\n */\n getVariable(sVar)\n {\n if (this.aVariables[sVar]) {\n return this.aVariables[sVar].value;\n }\n sVar = sVar.substr(0, 6);\n return this.aVariables[sVar] && this.aVariables[sVar].value;\n }\n\n /**\n * getVariableFixup(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {string|undefined}\n */\n getVariableFixup(sVar)\n {\n return this.aVariables[sVar] && this.aVariables[sVar].sUndefined;\n }\n\n /**\n * isVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {boolean}\n */\n isVariable(sVar)\n {\n return this.aVariables[sVar] !== undefined;\n }\n\n /**\n * setVariable(sVar, value, sUndefined)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @param {number} value\n * @param {string|undefined} [sUndefined]\n */\n setVariable(sVar, value, sUndefined)\n {\n this.aVariables[sVar] = {value, sUndefined};\n }\n\n /**\n * toStrBase(n, nBits, nBase, nGrouping)\n *\n * Use this instead of Str's toOct()/toDec()/toHex() to convert numbers to the Debugger's default base.\n *\n * @this {Debugger}\n * @param {number|null|undefined} n\n * @param {number} [nBits] (-1 to strip leading zeros, 0 to allow a variable number of digits)\n * @param {number} [nBase]\n * @param {number} [nGrouping] (if nBase is 2, this is a grouping; otherwise, it's a prefix condition)\n * @return {string}\n */\n toStrBase(n, nBits = 0, nBase = 0, nGrouping = 0)\n {\n var s;\n switch(nBase || this.nBase) {\n case 2:\n s = Str.toBin(n, nBits > 0? nBits : 0, nGrouping);\n break;\n case 8:\n s = Str.toOct(n, nBits > 0? ((nBits + 2)/3)|0 : 0, !!nGrouping);\n break;\n case 10:\n /*\n * The multiplier is actually Math.log(2)/Math.log(10), but an approximation is more than adequate.\n */\n s = Str.toDec(n, nBits > 0? Math.ceil(nBits * 0.3) : 0);\n break;\n case 16:\n default:\n s = Str.toHex(n, nBits > 0? ((nBits + 3) >> 2) : 0, !!nGrouping);\n break;\n }\n return (nBits < 0? Str.stripLeadingZeros(s) : s);\n }\n}\n\nif (DEBUGGER) {\n\n /*\n * These are our operator precedence tables. Operators toward the bottom (with higher values) have\n * higher precedence. aBinOpPrecedence was our original table; we had to add aDECOpPrecedence because\n * the precedence of operators in DEC's MACRO-10 expressions differ. Having separate tables also allows\n * us to remove operators that shouldn't be supported, but unless some operator creates a problem,\n * I prefer to keep as much commonality between the tables as possible.\n *\n * Missing from these tables are the (limited) set of unary operators we support (negate and complement),\n * since this is only a BINARY operator precedence, not a general-purpose precedence table. Assume that\n * all unary operators take precedence over all binary operators.\n */\n Debugger.aBinOpPrecedence = {\n '||': 5, // logical OR\n '&&': 6, // logical AND\n '!': 7, // bitwise OR (conflicts with logical NOT, but we never supported that)\n '|': 7, // bitwise OR\n '^!': 8, // bitwise XOR (added by MACRO-10 sometime between the 1972 and 1978 versions)\n '&': 9, // bitwise AND\n '!=': 10, // inequality\n '==': 10, // equality\n '>=': 11, // greater than or equal to\n '>': 11, // greater than\n '<=': 11, // less than or equal to\n '<': 11, // less than\n '>>>': 12, // unsigned bitwise right shift\n '>>': 12, // bitwise right shift\n '<<': 12, // bitwise left shift\n '-': 13, // subtraction\n '+': 13, // addition\n '^/': 14, // remainder\n '/': 14, // division\n '*': 14, // multiplication\n '_': 19, // MACRO-10 shift operator\n '^_': 19, // MACRO-10 internal shift operator (converted from 'B' suffix form that MACRO-10 uses)\n '{': 20, // open grouped expression (converted from achGroup[0])\n '}': 20 // close grouped expression (converted from achGroup[1])\n };\n Debugger.aDECOpPrecedence = {\n ',,': 1, // high-word,,low-word\n '||': 5, // logical OR\n '&&': 6, // logical AND\n '!=': 10, // inequality\n '==': 10, // equality\n '>=': 11, // greater than or equal to\n '>': 11, // greater than\n '<=': 11, // less than or equal to\n '<': 11, // less than\n '>>>': 12, // unsigned bitwise right shift\n '>>': 12, // bitwise right shift\n '<<': 12, // bitwise left shift\n '-': 13, // subtraction\n '+': 13, // addition\n '^/': 14, // remainder\n '/': 14, // division\n '*': 14, // multiplication\n '!': 15, // bitwise OR (conflicts with logical NOT, but we never supported that)\n '|': 15, // bitwise OR\n '^!': 15, // bitwise XOR (added by MACRO-10 sometime between the 1972 and 1978 versions)\n '&': 15, // bitwise AND\n '_': 19, // MACRO-10 shift operator\n '^_': 19, // MACRO-10 internal shift operator (converted from 'B' suffix form that MACRO-10 uses)\n '{': 20, // open grouped expression (converted from achGroup[0])\n '}': 20 // close grouped expression (converted from achGroup[1])\n };\n\n /*\n * Assorted constants\n */\n Debugger.TWO_POW32 = Math.pow(2, 32);\n\n} // endif DEBUGGER\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/debugger.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Debugger8080 Address Object\n *\n * addr address\n * fTemporary true if this is a temporary breakpoint address\n * sCmd set for breakpoint addresses if there's an associated command string\n * aCmds preprocessed commands (from sCmd)\n *\n * @typedef {{\n * addr:(number|undefined),\n * fTemporary:(boolean|undefined),\n * sCmd:(string|undefined),\n * aCmds:(Array.<string>|undefined)\n * }}\n */\nvar DbgAddr8080;\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass Debugger8080 extends Debugger {\n /**\n * Debugger8080(parmsDbg)\n *\n * The Debugger8080 component supports the following optional (parmsDbg) properties:\n *\n * commands: string containing zero or more commands, separated by ';'\n *\n * messages: string containing zero or more message categories to enable;\n * multiple categories must be separated by '|' or ';'. Parsed by messageInit().\n *\n * The Debugger8080 component is an optional component that implements a variety of user\n * commands for controlling the CPU, dumping and editing memory, etc.\n *\n * @this {Debugger8080}\n * @param {Object} parmsDbg\n */\n constructor(parmsDbg)\n {\n if (DEBUGGER) {\n\n super(parmsDbg);\n\n this.style = Debugger8080.STYLE_8080;\n\n /*\n * Most commands that require an address call parseAddr(), which defaults to dbgAddrNextCode\n * or dbgAddrNextData when no address has been given. doDump() and doUnassemble(), in turn,\n * update dbgAddrNextData and dbgAddrNextCode, respectively, when they're done.\n *\n * For TEMPORARY breakpoint addresses, we set fTemporary to true, so that they can be automatically\n * cleared when they're hit.\n */\n this.dbgAddrNextCode = this.newAddr();\n this.dbgAddrNextData = this.newAddr();\n this.dbgAddrAssemble = this.newAddr();\n\n /*\n * aSymbolTable is an array of SymbolTable objects, one per ROM or other chunk of address space,\n * where each object contains the following properties:\n *\n * sModule\n * addr (physical address, if any; eg, symbols for a ROM)\n * len\n * aSymbols\n * aOffsets\n *\n * See addSymbols() for more details, since that's how callers add sets of symbols to the table.\n */\n this.aSymbolTable = [];\n\n /*\n * clearBreakpoints() initializes the breakpoints lists: aBreakExec is a list of addresses\n * to halt on whenever attempting to execute an instruction at the corresponding address,\n * and aBreakRead and aBreakWrite are lists of addresses to halt on whenever a read or write,\n * respectively, occurs at the corresponding address.\n *\n * NOTE: Curiously, after upgrading the Google Closure Compiler from v20141215 to v20150609,\n * the resulting compiled code would crash in clearBreakpoints(), because the (renamed) aBreakRead\n * property was already defined. To eliminate whatever was confusing the Closure Compiler, I've\n * explicitly initialized all the properties that clearBreakpoints() (re)initializes.\n */\n this.aBreakExec = this.aBreakRead = this.aBreakWrite = [];\n this.clearBreakpoints();\n\n /*\n * The new \"bn\" command allows you to specify a number of instructions to execute and then stop;\n * \"bn 0\" disables any outstanding count.\n */\n this.nBreakIns = 0;\n\n /*\n * Execution history is allocated by historyInit() whenever checksEnabled() conditions change.\n * Execution history is updated whenever the CPU calls checkInstruction(), which will happen\n * only when checksEnabled() returns true (eg, whenever one or more breakpoints have been set).\n * This ensures that, by default, the CPU runs as fast as possible.\n */\n this.historyInit();\n\n /*\n * Initialize Debugger8080 message support\n */\n this.afnDumpers = {};\n this.messageInit(parmsDbg['messages']);\n\n this.sInitCommands = parmsDbg['commands'];\n\n /*\n * Make it easier to access Debugger commands from an external REPL, like the WebStorm \"live\" console\n * window; eg:\n *\n * pc8080('r')\n * pc8080('dw 0:0')\n * pc8080('h')\n * ...\n */\n var dbg = this;\n if (window) {\n if (window[PC8080.APPCLASS] === undefined) {\n window[PC8080.APPCLASS] = function(s) { return dbg.doCommands(s); };\n }\n } else {\n if (global[PC8080.APPCLASS] === undefined) {\n global[PC8080.APPCLASS] = function(s) { return dbg.doCommands(s); };\n }\n }\n\n } // endif DEBUGGER\n }\n\n /**\n * initBus(bus, cpu, dbg)\n *\n * @this {Debugger8080}\n * @param {Computer8080} cmp\n * @param {Bus8080} bus\n * @param {CPUState8080} cpu\n * @param {Debugger8080} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.cmp = cmp;\n\n /*\n * Re-initialize Debugger message support if necessary\n */\n var sMessages = cmp.getMachineParm('messages');\n if (sMessages) this.messageInit(sMessages);\n\n this.aaOpDescs = Debugger8080.aaOpDescs;\n\n this.messageDump(Messages8080.BUS, function onDumpBus(asArgs) { dbg.dumpBus(asArgs); });\n\n this.setReady();\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {Debugger8080}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"debugInput\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var dbg = this;\n switch (sBinding) {\n\n case \"debugInput\":\n this.bindings[sBinding] = control;\n this.controlDebug = /** @type {HTMLInputElement} */ (control);\n /*\n * For halted machines, this is fine, but for auto-start machines, it can be annoying.\n *\n * control.focus();\n */\n control.onkeydown = function onKeyDownDebugInput(event) {\n var sCmd;\n if (event.keyCode == Keys.KEYCODE.CR) {\n sCmd = dbg.controlDebug.value;\n dbg.controlDebug.value = \"\";\n dbg.doCommands(sCmd, true);\n }\n else if (event.keyCode == Keys.KEYCODE.ESC) {\n dbg.controlDebug.value = sCmd = \"\";\n }\n else {\n if (event.keyCode == Keys.KEYCODE.UP) {\n sCmd = dbg.getPrevCommand();\n }\n else if (event.keyCode == Keys.KEYCODE.DOWN) {\n sCmd = dbg.getNextCommand();\n }\n if (sCmd != null) {\n var cch = sCmd.length;\n dbg.controlDebug.value = sCmd;\n dbg.controlDebug.setSelectionRange(cch, cch);\n }\n }\n if (sCmd != null && event.preventDefault) event.preventDefault();\n };\n return true;\n\n case \"debugEnter\":\n this.bindings[sBinding] = control;\n Web.onClickRepeat(\n control,\n 500, 100,\n function onClickDebugEnter(fRepeat) {\n if (dbg.controlDebug) {\n var sCmds = dbg.controlDebug.value;\n dbg.controlDebug.value = \"\";\n dbg.doCommands(sCmds, true);\n return true;\n }\n if (DEBUG) dbg.log(\"no debugger input buffer\");\n return false;\n }\n );\n return true;\n\n case \"step\":\n this.bindings[sBinding] = control;\n Web.onClickRepeat(\n control,\n 500, 100,\n function onClickStep(fRepeat) {\n var fCompleted = false;\n if (!dbg.isBusy(true)) {\n dbg.setBusy(true);\n fCompleted = dbg.stepCPU(fRepeat? 1 : 0);\n dbg.setBusy(false);\n }\n return fCompleted;\n }\n );\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * updateFocus()\n *\n * @this {Debugger8080}\n */\n updateFocus()\n {\n if (this.controlDebug) this.controlDebug.focus();\n }\n\n /**\n * getAddr(dbgAddr, fWrite, nb)\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080|null|undefined} dbgAddr\n * @param {boolean} [fWrite]\n * @param {number} [nb] number of bytes to check (1 or 2); default is 1\n * @return {number} is the corresponding linear address, or CPUDef8080.ADDR_INVALID\n */\n getAddr(dbgAddr, fWrite, nb)\n {\n var addr = dbgAddr && dbgAddr.addr;\n if (addr == null) {\n addr = CPUDef8080.ADDR_INVALID;\n }\n return addr;\n }\n\n /**\n * getByte(dbgAddr, inc)\n *\n * We must route all our memory requests through the CPU now, in case paging is enabled.\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {number} [inc]\n * @return {number}\n */\n getByte(dbgAddr, inc)\n {\n var b = 0xff;\n var addr = this.getAddr(dbgAddr, false, 1);\n if (addr !== CPUDef8080.ADDR_INVALID) {\n b = this.bus.getByteDirect(addr);\n if (inc) this.incAddr(dbgAddr, inc);\n }\n return b;\n }\n\n /**\n * getWord(dbgAddr, fAdvance)\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {boolean} [fAdvance]\n * @return {number}\n */\n getWord(dbgAddr, fAdvance)\n {\n return this.getShort(dbgAddr, fAdvance? 2 : 0);\n }\n\n /**\n * getShort(dbgAddr, inc)\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {number} [inc]\n * @return {number}\n */\n getShort(dbgAddr, inc)\n {\n var w = 0xffff;\n var addr = this.getAddr(dbgAddr, false, 2);\n if (addr !== CPUDef8080.ADDR_INVALID) {\n w = this.bus.getShortDirect(addr);\n if (inc) this.incAddr(dbgAddr, inc);\n }\n return w;\n }\n\n /**\n * setByte(dbgAddr, b, inc)\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {number} b\n * @param {number} [inc]\n */\n setByte(dbgAddr, b, inc)\n {\n var addr = this.getAddr(dbgAddr, true, 1);\n if (addr !== CPUDef8080.ADDR_INVALID) {\n this.bus.setByteDirect(addr, b);\n if (inc) this.incAddr(dbgAddr, inc);\n this.cpu.updateCPU(true); // we set fForce to true in case video memory was the target\n }\n }\n\n /**\n * setShort(dbgAddr, w, inc)\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {number} w\n * @param {number} [inc]\n */\n setShort(dbgAddr, w, inc)\n {\n var addr = this.getAddr(dbgAddr, true, 2);\n if (addr !== CPUDef8080.ADDR_INVALID) {\n this.bus.setShortDirect(addr, w);\n if (inc) this.incAddr(dbgAddr, inc);\n this.cpu.updateCPU(true); // we set fForce to true in case video memory was the target\n }\n }\n\n /**\n * newAddr(addr)\n *\n * Returns a NEW DbgAddr8080 object, initialized with specified values and/or defaults.\n *\n * @this {Debugger8080}\n * @param {number} [addr]\n * @return {DbgAddr8080}\n */\n newAddr(addr)\n {\n return {addr: addr, fTemporary: false};\n }\n\n /**\n * setAddr(dbgAddr, addr)\n *\n * Updates an EXISTING DbgAddr8080 object, initialized with specified values and/or defaults.\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {number} addr\n * @return {DbgAddr8080}\n */\n setAddr(dbgAddr, addr)\n {\n dbgAddr.addr = addr;\n dbgAddr.fTemporary = false;\n return dbgAddr;\n }\n\n /**\n * packAddr(dbgAddr)\n *\n * Packs a DbgAddr8080 object into an Array suitable for saving in a machine state object.\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @return {Array}\n */\n packAddr(dbgAddr)\n {\n return [dbgAddr.addr, dbgAddr.fTemporary];\n }\n\n /**\n * unpackAddr(aAddr)\n *\n * Unpacks a DbgAddr8080 object from an Array created by packAddr() and restored from a saved machine state.\n *\n * @this {Debugger8080}\n * @param {Array} aAddr\n * @return {DbgAddr8080}\n */\n unpackAddr(aAddr)\n {\n return {addr: aAddr[0], fTemporary: aAddr[1]};\n }\n\n /**\n * parseAddr(sAddr, fCode, fNoChecks)\n *\n * Address evaluation and validation (eg, range checks) are no longer performed at this stage. That's\n * done later, by getAddr(), which returns CPUDef8080.ADDR_INVALID for invalid segments, out-of-range offsets,\n * etc. The Debugger's low-level get/set memory functions verify all getAddr() results, but even if an\n * invalid address is passed through to the Bus memory interfaces, the address will simply be masked with\n * Bus8080.nBusLimit; in the case of CPUDef8080.ADDR_INVALID, that will generally refer to the top of the physical\n * address space.\n *\n * @this {Debugger8080}\n * @param {string|undefined} sAddr\n * @param {boolean} [fCode] (true if target is code, false if target is data)\n * @param {boolean} [fNoChecks] (true when setting breakpoints that may not be valid now, but will be later)\n * @return {DbgAddr8080|null|undefined}\n */\n parseAddr(sAddr, fCode, fNoChecks)\n {\n var dbgAddr;\n var dbgAddrNext = (fCode? this.dbgAddrNextCode : this.dbgAddrNextData);\n var addr = dbgAddrNext.addr;\n if (sAddr !== undefined) {\n sAddr = this.parseReference(sAddr) || sAddr;\n dbgAddr = this.findSymbolAddr(sAddr);\n if (dbgAddr) return dbgAddr;\n addr = this.parseExpression(sAddr);\n }\n if (addr != null) {\n dbgAddr = this.newAddr(addr);\n }\n return dbgAddr;\n }\n\n /**\n * parseAddrOptions(dbdAddr, sOptions)\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {string} [sOptions]\n */\n parseAddrOptions(dbgAddr, sOptions)\n {\n if (sOptions) {\n var a = sOptions.match(/(['\"])(.*?)\\1/);\n if (a) {\n dbgAddr.aCmds = this.parseCommand(dbgAddr.sCmd = a[2]);\n }\n }\n }\n\n /**\n * incAddr(dbgAddr, inc)\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {number} [inc] contains value to increment dbgAddr by (default is 1)\n */\n incAddr(dbgAddr, inc)\n {\n if (dbgAddr.addr != null) {\n dbgAddr.addr += (inc || 1);\n }\n }\n\n /**\n * toHexOffset(off)\n *\n * @this {Debugger8080}\n * @param {number|null|undefined} [off]\n * @return {string} the hex representation of off\n */\n toHexOffset(off)\n {\n return Str.toHex(off, 4);\n }\n\n /**\n * toHexAddr(dbgAddr)\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @return {string} the hex representation of the address\n */\n toHexAddr(dbgAddr)\n {\n return this.toHexOffset(dbgAddr.addr);\n }\n\n /**\n * getSZ(dbgAddr, cchMax)\n *\n * Gets zero-terminated (aka \"ASCIIZ\") string from dbgAddr. It also stops at the first '$', in case this is\n * a '$'-terminated string -- mainly because I'm lazy and didn't feel like writing a separate get() function.\n * Yes, a zero-terminated string containing a '$' will be prematurely terminated, and no, I don't care.\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {number} [cchMax] (default is 256)\n * @return {string} (and dbgAddr advanced past the terminating zero)\n */\n getSZ(dbgAddr, cchMax)\n {\n var s = \"\";\n cchMax = cchMax || 256;\n while (s.length < cchMax) {\n var b = this.getByte(dbgAddr, 1);\n if (!b || b == 0x24 || b >= 127) break;\n s += (b >= 32? String.fromCharCode(b) : '.');\n }\n return s;\n }\n\n /**\n * dumpBlocks(aBlocks, sAddr)\n *\n * @this {Debugger8080}\n * @param {Array} aBlocks\n * @param {string} [sAddr] (optional block address)\n */\n dumpBlocks(aBlocks, sAddr)\n {\n var addr = 0, i = 0, n = aBlocks.length;\n\n if (sAddr) {\n addr = this.getAddr(this.parseAddr(sAddr));\n if (addr === CPUDef8080.ADDR_INVALID) {\n this.println(\"invalid address: \" + sAddr);\n return;\n }\n i = addr >>> this.bus.nBlockShift;\n n = 1;\n }\n\n this.println(\"blockid physical blockaddr used size type\");\n this.println(\"-------- --------- ---------- ------ ------ ----\");\n\n var typePrev = -1, cPrev = 0;\n while (n--) {\n var block = aBlocks[i];\n if (block.type == typePrev) {\n if (!cPrev++) this.println(\"...\");\n } else {\n typePrev = block.type;\n var sType = Memory8080.TYPE.NAMES[typePrev];\n if (block) {\n 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);\n }\n if (typePrev != Memory8080.TYPE.NONE) typePrev = -1;\n cPrev = 0;\n }\n addr += this.bus.nBlockSize;\n i++;\n }\n }\n\n /**\n * dumpBus(asArgs)\n *\n * Dumps Bus allocations.\n *\n * @this {Debugger8080}\n * @param {Array.<string>} asArgs (asArgs[0] is an optional block address)\n */\n dumpBus(asArgs)\n {\n this.dumpBlocks(this.bus.aMemBlocks, asArgs[0]);\n }\n\n /**\n * dumpHistory(sPrev, sLines)\n *\n * If sLines is not a number, it can be a instruction filter. However, for the moment, the only\n * supported filter is \"call\", which filters the history buffer for all CALL and RET instructions\n * from the specified previous point forward.\n *\n * @this {Debugger8080}\n * @param {string} [sPrev] is a (decimal) number of instructions to rewind to (default is 10)\n * @param {string} [sLines] is a (decimal) number of instructions to print (default is, again, 10)\n */\n dumpHistory(sPrev, sLines)\n {\n var sMore = \"\";\n var cHistory = 0;\n var iHistory = this.iOpcodeHistory;\n var aHistory = this.aOpcodeHistory;\n\n if (aHistory.length) {\n var nPrev = +sPrev || this.nextHistory;\n var nLines = +sLines || 10;\n\n if (isNaN(nPrev)) {\n nPrev = nLines;\n } else {\n sMore = \"more \";\n }\n\n if (nPrev > aHistory.length) {\n this.println(\"note: only \" + aHistory.length + \" available\");\n nPrev = aHistory.length;\n }\n\n iHistory -= nPrev;\n if (iHistory < 0) {\n /*\n * If the dbgAddr of the last aHistory element contains a valid selector, wrap around.\n */\n if (aHistory[aHistory.length - 1].addr == null) {\n nPrev = iHistory + nPrev;\n iHistory = 0;\n } else {\n iHistory += aHistory.length;\n }\n }\n\n var aFilters = [];\n if (sLines == \"call\") {\n nLines = 100000;\n aFilters = [\"CALL\"];\n }\n\n if (sPrev !== undefined) {\n this.println(nPrev + \" instructions earlier:\");\n }\n\n /*\n * TODO: The following is necessary to prevent dumpHistory() from causing additional (or worse, recursive)\n * faults due to segmented addresses that are no longer valid, but the only alternative is to dramatically\n * increase the amount of memory used to store instruction history (eg, storing copies of all the instruction\n * bytes alongside the execution addresses).\n *\n * For now, we're living dangerously, so that our history dumps actually work.\n *\n * this.nSuppressBreaks++;\n *\n * If you re-enable this protection, be sure to re-enable the decrement below, too.\n */\n while (nLines > 0 && iHistory != this.iOpcodeHistory) {\n\n var dbgAddr = aHistory[iHistory++];\n if (dbgAddr.addr == null) break;\n\n /*\n * We must create a new dbgAddr from the address in aHistory, because dbgAddr was\n * a reference, not a copy, and we don't want getInstruction() modifying the original.\n */\n var dbgAddrNew = this.newAddr(dbgAddr.addr);\n\n var sComment = \"history\";\n var nSequence = nPrev--;\n if (DEBUG && dbgAddr.cycleCount != null) {\n sComment = \"cycles\";\n nSequence = dbgAddr.cycleCount;\n }\n\n var sInstruction = this.getInstruction(dbgAddrNew, sComment, nSequence);\n\n if (!aFilters.length || sInstruction.indexOf(aFilters[0]) >= 0) {\n this.println(sInstruction);\n }\n\n /*\n * If there were OPERAND or ADDRESS overrides on the previous instruction, getInstruction()\n * will have automatically disassembled additional bytes, so skip additional history entries.\n */\n if (dbgAddrNew.cOverrides) {\n iHistory += dbgAddrNew.cOverrides; nLines -= dbgAddrNew.cOverrides; nPrev -= dbgAddrNew.cOverrides;\n }\n\n if (iHistory >= aHistory.length) iHistory = 0;\n this.nextHistory = nPrev;\n cHistory++;\n nLines--;\n }\n /*\n * See comments above.\n *\n * this.nSuppressBreaks--;\n */\n }\n\n if (!cHistory) {\n this.println(\"no \" + sMore + \"history available\");\n this.nextHistory = undefined;\n }\n }\n\n /**\n * messageInit(sEnable)\n *\n * @this {Debugger8080}\n * @param {string|undefined} sEnable contains zero or more message categories to enable, separated by '|'\n */\n messageInit(sEnable)\n {\n this.dbg = this;\n this.bitsMessage = this.bitsWarning = Messages8080.WARN;\n this.sMessagePrev = null;\n this.aMessageBuffer = [];\n /*\n * Internally, we use \"key\" instead of \"keys\", since the latter is a method on JavasScript objects,\n * but externally, we allow the user to specify \"keys\"; \"kbd\" is also allowed as shorthand for \"keyboard\".\n */\n var aEnable = this.parseCommand(sEnable.replace(\"keys\",\"key\").replace(\"kbd\",\"keyboard\"), false, '|');\n if (aEnable.length) {\n for (var m in Messages8080.CATEGORIES) {\n if (Usr.indexOf(aEnable, m) >= 0) {\n this.bitsMessage |= Messages8080.CATEGORIES[m];\n this.println(m + \" messages enabled\");\n }\n }\n }\n }\n\n /**\n * messageDump(bitMessage, fnDumper)\n *\n * @this {Debugger8080}\n * @param {number} bitMessage is one Messages category flag\n * @param {function(Array.<string>)} fnDumper is a function the Debugger can use to dump data for that category\n * @return {boolean} true if successfully registered, false if not\n */\n messageDump(bitMessage, fnDumper)\n {\n for (var m in Messages8080.CATEGORIES) {\n if (bitMessage == Messages8080.CATEGORIES[m]) {\n this.afnDumpers[m] = fnDumper;\n return true;\n }\n }\n return false;\n }\n\n /**\n * getRegIndex(sReg, off)\n *\n * @this {Debugger8080}\n * @param {string} sReg\n * @param {number} [off] optional offset into sReg\n * @return {number} register index, or -1 if not found\n */\n getRegIndex(sReg, off)\n {\n var i;\n sReg = sReg.toUpperCase();\n if (off == null) {\n i = Usr.indexOf(Debugger8080.REGS, sReg);\n } else {\n i = Usr.indexOf(Debugger8080.REGS, sReg.substr(off, 2));\n if (i < 0) i = Usr.indexOf(Debugger8080.REGS, sReg.substr(off, 1));\n }\n return i;\n }\n\n /**\n * getRegString(iReg)\n *\n * @this {Debugger8080}\n * @param {number} iReg\n * @return {string}\n */\n getRegString(iReg)\n {\n var cch = 0;\n var n = this.getRegValue(iReg);\n if (n !== undefined) {\n switch(iReg) {\n case Debugger8080.REG_A:\n case Debugger8080.REG_B:\n case Debugger8080.REG_C:\n case Debugger8080.REG_D:\n case Debugger8080.REG_E:\n case Debugger8080.REG_H:\n case Debugger8080.REG_L:\n case Debugger8080.REG_M:\n cch = 2;\n break;\n case Debugger8080.REG_BC:\n case Debugger8080.REG_DE:\n case Debugger8080.REG_HL:\n case Debugger8080.REG_SP:\n case Debugger8080.REG_PC:\n case Debugger8080.REG_PS:\n case Debugger8080.REG_PSW:\n cch = 4;\n break;\n }\n }\n return cch? Str.toHex(n, cch) : \"??\";\n }\n\n /**\n * getRegValue(iReg)\n *\n * @this {Debugger8080}\n * @param {number} iReg\n * @return {number|undefined}\n */\n getRegValue(iReg)\n {\n var n;\n if (iReg >= 0) {\n var cpu = this.cpu;\n switch(iReg) {\n case Debugger8080.REG_A:\n n = cpu.regA;\n break;\n case Debugger8080.REG_B:\n n = cpu.regB;\n break;\n case Debugger8080.REG_C:\n n = cpu.regC;\n break;\n case Debugger8080.REG_BC:\n n = cpu.getBC();\n break;\n case Debugger8080.REG_D:\n n = cpu.regD;\n break;\n case Debugger8080.REG_E:\n n = cpu.regE;\n break;\n case Debugger8080.REG_DE:\n n = cpu.getDE();\n break;\n case Debugger8080.REG_H:\n n = cpu.regH;\n break;\n case Debugger8080.REG_L:\n n = cpu.regL;\n break;\n case Debugger8080.REG_HL:\n n = cpu.getHL();\n break;\n case Debugger8080.REG_M:\n n = cpu.getByte(cpu.getHL());\n break;\n case Debugger8080.REG_SP:\n n = cpu.getSP();\n break;\n case Debugger8080.REG_PC:\n n = cpu.getPC();\n break;\n case Debugger8080.REG_PS:\n n = cpu.getPS();\n break;\n case Debugger8080.REG_PSW:\n n = cpu.getPSW();\n break;\n default:\n break;\n }\n }\n return n;\n }\n\n /**\n * replaceRegs(s)\n *\n * @this {Debugger8080}\n * @param {string} s\n * @return {string}\n */\n replaceRegs(s)\n {\n /*\n * Replace any references first; this means that register references inside the reference\n * do NOT need to be prefixed with '@'.\n */\n s = this.parseReference(s) || s;\n\n /*\n * Replace every @XX (or @XXX), where XX (or XXX) is a register, with the register's value.\n */\n var i = 0;\n var b, sChar, sAddr, dbgAddr, sReplace;\n while ((i = s.indexOf('@', i)) >= 0) {\n var iReg = this.getRegIndex(s, i + 1);\n if (iReg >= 0) {\n s = s.substr(0, i) + this.getRegString(iReg) + s.substr(i + 1 + Debugger8080.REGS[iReg].length);\n }\n i++;\n }\n /*\n * Replace every #XX, where XX is a hex byte value, with the corresponding ASCII character (if printable).\n */\n i = 0;\n while ((i = s.indexOf('#', i)) >= 0) {\n sChar = s.substr(i+1, 2);\n b = Str.parseInt(sChar, 16);\n if (b != null && b >= 32 && b < 127) {\n sReplace = sChar + \" '\" + String.fromCharCode(b) + \"'\";\n s = s.replace('#' + sChar, sReplace);\n i += sReplace.length;\n continue;\n }\n i++;\n }\n /*\n * Replace every $XXXX:XXXX, where XXXX:XXXX is a segmented address, with the zero-terminated string at that address.\n */\n i = 0;\n while ((i = s.indexOf('$', i)) >= 0) {\n sAddr = s.substr(i+1, 9);\n dbgAddr = this.parseAddr(sAddr);\n if (dbgAddr) {\n sReplace = sAddr + ' \"' + this.getSZ(dbgAddr) + '\"';\n s = s.replace('$' + sAddr, sReplace);\n i += sReplace.length;\n continue;\n }\n i++;\n }\n /*\n * Replace every ^XXXX:XXXX, where XXXX:XXXX is a segmented address, with the FCB filename stored at that address.\n */\n i = 0;\n while ((i = s.indexOf('^', i)) >= 0) {\n sAddr = s.substr(i+1, 9);\n dbgAddr = this.parseAddr(sAddr);\n if (dbgAddr) {\n this.incAddr(dbgAddr);\n sReplace = sAddr + ' \"' + this.getSZ(dbgAddr, 11) + '\"';\n s = s.replace('^' + sAddr, sReplace);\n i += sReplace.length;\n continue;\n }\n i++;\n }\n return s;\n }\n\n /**\n * message(sMessage, fAddress)\n *\n * @this {Debugger8080}\n * @param {string} sMessage is any caller-defined message string\n * @param {boolean} [fAddress] is true to display the current CS:IP\n */\n message(sMessage, fAddress)\n {\n if (fAddress) {\n sMessage += \" at \" + this.toHexAddr(this.newAddr(this.cpu.getPC()));\n }\n\n if (this.bitsMessage & Messages8080.BUFFER) {\n this.aMessageBuffer.push(sMessage);\n return;\n }\n\n if (this.sMessagePrev && sMessage == this.sMessagePrev) return;\n this.sMessagePrev = sMessage;\n\n if (this.bitsMessage & Messages8080.HALT) {\n this.stopCPU();\n sMessage += \" (cpu halted)\";\n }\n\n this.println(sMessage); // + \" (\" + this.cpu.getCycles() + \" cycles)\"\n\n /*\n * We have no idea what the frequency of println() calls might be; all we know is that they easily\n * screw up the CPU's careful assumptions about cycles per burst. So we call yieldCPU() after every\n * message, to effectively end the current burst and start fresh.\n *\n * TODO: See CPU8080.calcStartTime() for a discussion of why we might want to call yieldCPU() *before*\n * we display the message.\n */\n if (this.cpu) this.cpu.yieldCPU();\n }\n\n /**\n * messageIO(component, port, bOut, addrFrom, name, bIn, bitsMessage)\n *\n * Most (if not all) port handlers should provide a name for their respective ports, so if no name is provided,\n * we assume this is an unknown port, and display a message by default.\n *\n * @this {Debugger8080}\n * @param {Component} component\n * @param {number} port\n * @param {number|null} bOut if an output operation\n * @param {number|null} [addrFrom]\n * @param {string|null} [name] of the port, if any\n * @param {number|null} [bIn] is the input value, if known, on an input operation\n * @param {number} [bitsMessage] is one or more Messages category flag(s)\n */\n messageIO(component, port, bOut, addrFrom, name, bIn, bitsMessage)\n {\n bitsMessage |= Messages8080.PORT;\n if (name == null || (this.bitsMessage & bitsMessage) == bitsMessage) {\n this.message(component.idComponent + '.' + (bOut != null? \"outPort\" : \"inPort\") + '(' + Str.toHexWord(port) + ',' + (name? name : \"unknown\") + (bOut != null? ',' + Str.toHexByte(bOut) : \"\") + ')' + (bIn != null? (\": \" + Str.toHexByte(bIn)) : \"\") + (addrFrom != null? (\" at \" + this.toHexOffset(addrFrom)) : \"\"));\n }\n }\n\n /**\n * init()\n *\n * @this {Debugger8080}\n */\n init()\n {\n this.println(\"Type ? for help with PC8080 Debugger commands\");\n this.updateStatus();\n if (this.sInitCommands) {\n var sCmds = this.sInitCommands;\n this.sInitCommands = null;\n this.doCommands(sCmds);\n }\n }\n\n /**\n * historyInit(fQuiet)\n *\n * This function is intended to be called by the constructor, reset(), addBreakpoint(), findBreakpoint()\n * and any other function that changes the checksEnabled() criteria used to decide whether checkInstruction()\n * should be called.\n *\n * That is, if the history arrays need to be allocated and haven't already been allocated, then allocate them,\n * and if the arrays are no longer needed, then deallocate them.\n *\n * @this {Debugger8080}\n * @param {boolean} [fQuiet]\n */\n historyInit(fQuiet)\n {\n var i;\n if (!this.checksEnabled()) {\n if (this.aOpcodeHistory && this.aOpcodeHistory.length && !fQuiet) {\n this.println(\"instruction history buffer freed\");\n }\n this.iOpcodeHistory = 0;\n this.aOpcodeHistory = [];\n this.aaOpcodeCounts = [];\n return;\n }\n if (!this.aOpcodeHistory || !this.aOpcodeHistory.length) {\n this.aOpcodeHistory = new Array(Debugger8080.HISTORY_LIMIT);\n for (i = 0; i < this.aOpcodeHistory.length; i++) {\n /*\n * Preallocate dummy Addr (Array) objects in every history slot, so that\n * checkInstruction() doesn't need to call newAddr() on every slot update.\n */\n this.aOpcodeHistory[i] = this.newAddr();\n }\n this.iOpcodeHistory = 0;\n if (!fQuiet) {\n this.println(\"instruction history buffer allocated\");\n }\n }\n if (!this.aaOpcodeCounts || !this.aaOpcodeCounts.length) {\n this.aaOpcodeCounts = new Array(256);\n for (i = 0; i < this.aaOpcodeCounts.length; i++) {\n this.aaOpcodeCounts[i] = [i, 0];\n }\n }\n }\n\n /**\n * runCPU(fUpdateFocus)\n *\n * @this {Debugger8080}\n * @param {boolean} [fUpdateFocus] is true to update focus\n * @return {boolean} true if run request successful, false if not\n */\n runCPU(fUpdateFocus)\n {\n if (!this.isCPUAvail()) return false;\n this.cpu.runCPU(fUpdateFocus);\n return true;\n }\n\n /**\n * stepCPU(nCycles, fRegs, fUpdateCPU)\n *\n * @this {Debugger8080}\n * @param {number} nCycles (0 for one instruction without checking breakpoints)\n * @param {boolean} [fRegs] is true to display registers after step (default is false)\n * @param {boolean} [fUpdateCPU] is false to disable calls to updateCPU() (default is true)\n * @return {boolean}\n */\n stepCPU(nCycles, fRegs, fUpdateCPU)\n {\n if (!this.isCPUAvail()) return false;\n\n this.nCycles = 0;\n\n if (!nCycles) {\n /*\n * When single-stepping, the CPU won't call checkInstruction(), which is good for\n * avoiding breakpoints, but bad for instruction data collection if checks are enabled.\n * So we call checkInstruction() ourselves.\n */\n if (this.checksEnabled()) this.checkInstruction(this.cpu.getPC(), 0);\n }\n try {\n var nCyclesStep = this.cpu.stepCPU(nCycles);\n if (nCyclesStep > 0) {\n this.nCycles += nCyclesStep;\n this.cpu.addCycles(nCyclesStep, true);\n this.cpu.updateChecksum(nCyclesStep);\n this.cOpcodes++;\n }\n }\n catch(exception) {\n if (typeof exception != \"number\") {\n var e = exception;\n this.nCycles = 0;\n this.cpu.setError(e.stack || e.message);\n }\n }\n\n /*\n * Because we called cpu.stepCPU() and not cpu.runCPU(), we must nudge the cpu's update code,\n * and then update our own state. Normally, the only time fUpdateCPU will be false is when doTrace()\n * is calling us in a loop, in which case it will perform its own updateCPU() when it's done.\n */\n if (fUpdateCPU !== false) this.cpu.updateCPU();\n\n this.updateStatus(fRegs || false);\n return (this.nCycles > 0);\n }\n\n /**\n * stopCPU()\n *\n * @this {Debugger8080}\n * @param {boolean} [fComplete]\n */\n stopCPU(fComplete)\n {\n if (this.cpu) this.cpu.stopCPU(fComplete);\n }\n\n /**\n * updateStatus(fRegs)\n *\n * @this {Debugger8080}\n * @param {boolean} [fRegs] (default is true)\n */\n updateStatus(fRegs)\n {\n if (fRegs === undefined) fRegs = true;\n\n this.dbgAddrNextCode = this.newAddr(this.cpu.getPC());\n /*\n * this.nStep used to be a simple boolean, but now it's 0 (or undefined)\n * if inactive, 1 if stepping over an instruction without a register dump, or 2\n * if stepping over an instruction with a register dump.\n */\n if (!fRegs || this.nStep == 1)\n this.doUnassemble();\n else {\n this.doRegisters();\n }\n }\n\n /**\n * isCPUAvail()\n *\n * Make sure the CPU is ready (finished initializing), not busy (already running), and not in an error state.\n *\n * @this {Debugger8080}\n * @return {boolean}\n */\n isCPUAvail()\n {\n if (!this.cpu)\n return false;\n if (!this.cpu.isReady())\n return false;\n if (!this.cpu.isPowered())\n return false;\n if (this.cpu.isBusy())\n return false;\n return !this.cpu.isError();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {Debugger8080}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n /*\n * Because Debugger save/restore support is somewhat limited (and didn't always exist),\n * we deviate from the typical save/restore design pattern: instead of reset OR restore,\n * we always reset and then perform a (potentially limited) restore.\n */\n this.reset(true);\n\n // this.println(data? \"resuming\" : \"powering up\");\n\n if (data && this.restore) {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Debugger8080}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean}\n */\n powerDown(fSave, fShutdown)\n {\n if (fShutdown) this.println(fSave? \"suspending\" : \"shutting down\");\n return fSave? this.save() : true;\n }\n\n /**\n * reset(fQuiet)\n *\n * This is a notification handler, called by the Computer, to inform us of a reset.\n *\n * @this {Debugger8080}\n * @param {boolean} fQuiet (true only when called from our own powerUp handler)\n */\n reset(fQuiet)\n {\n this.historyInit();\n this.cOpcodes = this.cOpcodesStart = 0;\n this.sMessagePrev = null;\n this.nCycles = 0;\n this.dbgAddrNextCode = this.newAddr(this.cpu.getPC());\n /*\n * fRunning is set by start() and cleared by stop(). In addition, we clear\n * it here, so that if the CPU is reset while running, we can prevent stop()\n * from unnecessarily dumping the CPU state.\n */\n this.flags.running = false;\n this.clearTempBreakpoint();\n if (!fQuiet) this.updateStatus();\n }\n\n /**\n * save()\n *\n * This implements (very rudimentary) save support for the Debugger component.\n *\n * @this {Debugger8080}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.packAddr(this.dbgAddrNextCode));\n state.set(1, this.packAddr(this.dbgAddrAssemble));\n state.set(2, [this.aPrevCmds, this.fAssemble, this.bitsMessage]);\n state.set(3, this.aSymbolTable);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements (very rudimentary) restore support for the Debugger component.\n *\n * @this {Debugger8080}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var i = 0;\n if (data[2] !== undefined) {\n this.dbgAddrNextCode = this.unpackAddr(data[i++]);\n this.dbgAddrAssemble = this.unpackAddr(data[i++]);\n this.aPrevCmds = data[i][0];\n if (typeof this.aPrevCmds == \"string\") this.aPrevCmds = [this.aPrevCmds];\n this.fAssemble = data[i][1];\n this.bitsMessage |= data[i][2]; // keep our current message bits set, and simply \"add\" any extra bits defined by the saved state\n }\n if (data[3]) this.aSymbolTable = data[3];\n return true;\n }\n\n /**\n * start(ms, nCycles)\n *\n * This is a notification handler, called by the Computer, to inform us the CPU has started.\n *\n * @this {Debugger8080}\n * @param {number} ms\n * @param {number} nCycles\n */\n start(ms, nCycles)\n {\n if (!this.nStep) this.println(\"running\");\n this.flags.running = true;\n this.msStart = ms;\n this.nCyclesStart = nCycles;\n }\n\n /**\n * stop(ms, nCycles)\n *\n * This is a notification handler, called by the Computer, to inform us the CPU has now stopped.\n *\n * @this {Debugger8080}\n * @param {number} ms\n * @param {number} nCycles\n */\n stop(ms, nCycles)\n {\n if (this.flags.running) {\n this.flags.running = false;\n this.nCycles = nCycles - this.nCyclesStart;\n if (!this.nStep) {\n var sStopped = \"stopped\";\n if (this.nCycles) {\n var msTotal = ms - this.msStart;\n var nCyclesPerSecond = (msTotal > 0? Math.round(this.nCycles * 1000 / msTotal) : 0);\n sStopped += \" (\";\n if (this.checksEnabled()) {\n sStopped += this.cOpcodes + \" opcodes, \";\n /*\n * $ops displays progress by calculating cOpcodes - cOpcodesStart, so before\n * zeroing cOpcodes, we should subtract cOpcodes from cOpcodesStart (since we're\n * effectively subtracting cOpcodes from cOpcodes as well).\n */\n this.cOpcodesStart -= this.cOpcodes;\n this.cOpcodes = 0;\n }\n sStopped += this.nCycles + \" cycles, \" + msTotal + \" ms, \" + nCyclesPerSecond + \" hz)\";\n } else {\n if (this.messageEnabled(Messages8080.HALT)) {\n /*\n * It's possible the user is trying to 'g' past a fault that was blocked by helpCheckFault()\n * for the Debugger's benefit; if so, it will continue to be blocked, so try displaying a helpful\n * message (another helpful tip would be to simply turn off the \"halt\" message category).\n */\n sStopped += \" (use the 't' command to execute blocked faults)\";\n }\n }\n this.println(sStopped);\n }\n this.updateStatus(true);\n this.updateFocus();\n this.clearTempBreakpoint(this.cpu.getPC());\n }\n }\n\n /**\n * checksEnabled(fRelease)\n *\n * This \"check\" function is called by the CPU; we indicate whether or not every instruction needs to be checked.\n *\n * Originally, this returned true even when there were only read and/or write breakpoints, but those breakpoints\n * no longer require the intervention of checkInstruction(); the Bus component automatically swaps in/out appropriate\n * \"checked\" Memory access functions to deal with those breakpoints in the corresponding Memory blocks. So I've\n * simplified the test below.\n *\n * @this {Debugger8080}\n * @param {boolean} [fRelease] is true for release criteria only; default is false (any criteria)\n * @return {boolean} true if every instruction needs to pass through checkInstruction(), false if not\n */\n checksEnabled(fRelease)\n {\n return ((DEBUG && !fRelease)? true : (this.aBreakExec.length > 1 || !!this.nBreakIns));\n }\n\n /**\n * checkInstruction(addr, nState)\n *\n * This \"check\" function is called by the CPU to inform us about the next instruction to be executed,\n * giving us an opportunity to look for \"exec\" breakpoints and update opcode frequencies and instruction history.\n *\n * @this {Debugger8080}\n * @param {number} addr\n * @param {number} nState is < 0 if stepping, 0 if starting, or > 0 if running\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkInstruction(addr, nState)\n {\n var cpu = this.cpu;\n\n if (nState > 0) {\n if (this.nBreakIns && !--this.nBreakIns) {\n return true;\n }\n if (this.checkBreakpoint(addr, 1, this.aBreakExec)) {\n return true;\n }\n }\n\n /*\n * The rest of the instruction tracking logic can only be performed if historyInit() has allocated the\n * necessary data structures. Note that there is no explicit UI for enabling/disabling history, other than\n * adding/removing breakpoints, simply because it's breakpoints that trigger the call to checkInstruction();\n * well, OK, and a few other things now, like enabling Messages8080.INT messages.\n */\n if (nState >= 0 && this.aaOpcodeCounts.length) {\n this.cOpcodes++;\n var bOpcode = this.bus.getByteDirect(addr);\n if (bOpcode != null) {\n this.aaOpcodeCounts[bOpcode][1]++;\n var dbgAddr = this.aOpcodeHistory[this.iOpcodeHistory];\n this.setAddr(dbgAddr, cpu.getPC());\n if (DEBUG) dbgAddr.cycleCount = cpu.getCycles();\n if (++this.iOpcodeHistory == this.aOpcodeHistory.length) this.iOpcodeHistory = 0;\n }\n }\n return false;\n }\n\n /**\n * checkMemoryRead(addr, nb)\n *\n * This \"check\" function is called by a Memory block to inform us that a memory read occurred, giving us an\n * opportunity to track the read if we want, and look for a matching \"read\" breakpoint, if any.\n *\n * In the \"old days\", it would be an error for this call to fail to find a matching Debugger breakpoint, but now\n * Memory blocks have no idea whether the Debugger or the machine's Debug register(s) triggered this \"checked\" read.\n *\n * If we return true, we \"trump\" the machine's Debug register(s); false allows normal Debug register processing.\n *\n * @this {Debugger8080}\n * @param {number} addr\n * @param {number} [nb] (# of bytes; default is 1)\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkMemoryRead(addr, nb)\n {\n if (this.checkBreakpoint(addr, nb || 1, this.aBreakRead)) {\n this.stopCPU(true);\n return true;\n }\n return false;\n }\n\n /**\n * checkMemoryWrite(addr, nb)\n *\n * This \"check\" function is called by a Memory block to inform us that a memory write occurred, giving us an\n * opportunity to track the write if we want, and look for a matching \"write\" breakpoint, if any.\n *\n * In the \"old days\", it would be an error for this call to fail to find a matching Debugger breakpoint, but now\n * Memory blocks have no idea whether the Debugger or the machine's Debug register(s) triggered this \"checked\" write.\n *\n * If we return true, we \"trump\" the machine's Debug register(s); false allows normal Debug register processing.\n *\n * @this {Debugger8080}\n * @param {number} addr\n * @param {number} [nb] (# of bytes; default is 1)\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkMemoryWrite(addr, nb)\n {\n if (this.checkBreakpoint(addr, nb || 1, this.aBreakWrite)) {\n this.stopCPU(true);\n return true;\n }\n return false;\n }\n\n /**\n * checkPortInput(port, size, data)\n *\n * This \"check\" function is called by the Bus component to inform us that port input occurred.\n *\n * @this {Debugger8080}\n * @param {number} port\n * @param {number} size\n * @param {number} data\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkPortInput(port, size, data)\n {\n /*\n * We trust that the Bus component won't call us unless we told it to, so we halt unconditionally\n */\n this.println(\"break on input from port \" + Str.toHexWord(port) + \": \" + Str.toHex(data));\n this.stopCPU(true);\n return true;\n }\n\n /**\n * checkPortOutput(port, size, data)\n *\n * This \"check\" function is called by the Bus component to inform us that port output occurred.\n *\n * @this {Debugger8080}\n * @param {number} port\n * @param {number} size\n * @param {number} data\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkPortOutput(port, size, data)\n {\n /*\n * We trust that the Bus component won't call us unless we told it to, so we halt unconditionally\n */\n this.println(\"break on output to port \" + Str.toHexWord(port) + \": \" + Str.toHex(data));\n this.stopCPU(true);\n return true;\n }\n\n /**\n * clearBreakpoints()\n *\n * @this {Debugger8080}\n */\n clearBreakpoints()\n {\n var i, dbgAddr;\n this.aBreakExec = [\"bp\"];\n if (this.aBreakRead !== undefined) {\n for (i = 1; i < this.aBreakRead.length; i++) {\n dbgAddr = this.aBreakRead[i];\n this.bus.removeMemBreak(this.getAddr(dbgAddr), false);\n }\n }\n this.aBreakRead = [\"br\"];\n if (this.aBreakWrite !== undefined) {\n for (i = 1; i < this.aBreakWrite.length; i++) {\n dbgAddr = this.aBreakWrite[i];\n this.bus.removeMemBreak(this.getAddr(dbgAddr), true);\n }\n }\n this.aBreakWrite = [\"bw\"];\n /*\n * nSuppressBreaks ensures we can't get into an infinite loop where a breakpoint lookup requires\n * reading a segment descriptor via getSegment(), and that triggers more memory reads, which triggers\n * more breakpoint checks.\n */\n this.nSuppressBreaks = 0;\n }\n\n /**\n * addBreakpoint(aBreak, dbgAddr, fTemporary)\n *\n * In case you haven't already figured this out, all our breakpoint commands use the address\n * to identify a breakpoint, not an incrementally assigned breakpoint index like other debuggers;\n * see doBreak() for details.\n *\n * This has a few implications, one being that you CANNOT set more than one kind of breakpoint\n * on a single address. In practice, that's rarely a problem, because you can almost always set\n * a different breakpoint on a neighboring address.\n *\n * Also, there is one exception to the \"one address, one breakpoint\" rule, and that involves\n * temporary breakpoints (ie, one-time execution breakpoints that either a \"p\" or \"g\" command\n * may create to step over a chunk of code). Those breakpoints automatically clear themselves,\n * so there usually isn't any need to refer to them using breakpoint commands.\n *\n * TODO: Consider supporting the more \"traditional\" breakpoint index syntax; the current\n * address-based syntax was implemented solely for expediency and consistency. At the same time,\n * also consider a more WDEB386-like syntax, where \"br\" is used to set a variety of access-specific\n * breakpoints, using modifiers like \"r1\", \"r2\", \"w1\", \"w2, etc.\n *\n * @this {Debugger8080}\n * @param {Array} aBreak\n * @param {DbgAddr8080} dbgAddr\n * @param {boolean} [fTemporary]\n * @return {boolean} true if breakpoint added, false if already exists\n */\n addBreakpoint(aBreak, dbgAddr, fTemporary)\n {\n var fSuccess = true;\n\n // this.nSuppressBreaks++;\n\n /*\n * Instead of complaining that a breakpoint already exists (as we used to do), we now\n * allow breakpoints to be re-set; this makes it easier to update any commands that may\n * be associated with the breakpoint.\n *\n * The only exception: we DO allow a temporary breakpoint at an address where there may\n * already be a breakpoint, so that you can easily step (\"p\" or \"g\") over such addresses.\n */\n if (!fTemporary) {\n this.findBreakpoint(aBreak, dbgAddr, true, false, true);\n }\n\n if (aBreak != this.aBreakExec) {\n var addr = this.getAddr(dbgAddr);\n if (addr === CPUDef8080.ADDR_INVALID) {\n this.println(\"invalid address: \" + this.toHexAddr(dbgAddr));\n fSuccess = false;\n } else {\n this.bus.addMemBreak(addr, aBreak == this.aBreakWrite);\n }\n }\n\n if (fSuccess) {\n aBreak.push(dbgAddr);\n if (fTemporary) {\n dbgAddr.fTemporary = true;\n }\n else {\n this.printBreakpoint(aBreak, aBreak.length-1, \"set\");\n this.historyInit();\n }\n }\n\n // this.nSuppressBreaks--;\n\n return fSuccess;\n }\n\n /**\n * findBreakpoint(aBreak, dbgAddr, fRemove, fTemporary, fQuiet)\n *\n * @this {Debugger8080}\n * @param {Array} aBreak\n * @param {DbgAddr8080} dbgAddr\n * @param {boolean} [fRemove]\n * @param {boolean} [fTemporary]\n * @param {boolean} [fQuiet]\n * @return {boolean} true if found, false if not\n */\n findBreakpoint(aBreak, dbgAddr, fRemove, fTemporary, fQuiet)\n {\n var fFound = false;\n var addr = this.getAddr(dbgAddr);\n for (var i = 1; i < aBreak.length; i++) {\n var dbgAddrBreak = aBreak[i];\n if (addr == this.getAddr(dbgAddrBreak)) {\n if (!fTemporary || dbgAddrBreak.fTemporary) {\n fFound = true;\n if (fRemove) {\n if (!dbgAddrBreak.fTemporary && !fQuiet) {\n this.printBreakpoint(aBreak, i, \"cleared\");\n }\n aBreak.splice(i, 1);\n if (aBreak != this.aBreakExec) {\n this.bus.removeMemBreak(addr, aBreak == this.aBreakWrite);\n }\n /*\n * We'll mirror the logic in addBreakpoint() and leave the history buffer alone if this\n * was a temporary breakpoint.\n */\n if (!dbgAddrBreak.fTemporary) {\n this.historyInit();\n }\n break;\n }\n if (!fQuiet) this.printBreakpoint(aBreak, i, \"exists\");\n break;\n }\n }\n }\n return fFound;\n }\n\n /**\n * listBreakpoints(aBreak)\n *\n * @this {Debugger8080}\n * @param {Array} aBreak\n * @return {number} of breakpoints listed, 0 if none\n */\n listBreakpoints(aBreak)\n {\n for (var i = 1; i < aBreak.length; i++) {\n this.printBreakpoint(aBreak, i);\n }\n return aBreak.length - 1;\n }\n\n /**\n * printBreakpoint(aBreak, i, sAction)\n *\n * @this {Debugger8080}\n * @param {Array} aBreak\n * @param {number} i\n * @param {string} [sAction]\n */\n printBreakpoint(aBreak, i, sAction)\n {\n var dbgAddr = aBreak[i];\n this.println(aBreak[0] + ' ' + this.toHexAddr(dbgAddr) + (sAction? (' ' + sAction) : (dbgAddr.sCmd? (' \"' + dbgAddr.sCmd + '\"') : '')));\n }\n\n /**\n * setTempBreakpoint(dbgAddr)\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr of new temp breakpoint\n */\n setTempBreakpoint(dbgAddr)\n {\n this.addBreakpoint(this.aBreakExec, dbgAddr, true);\n }\n\n /**\n * clearTempBreakpoint(addr)\n *\n * @this {Debugger8080}\n * @param {number|undefined} [addr] clear all temp breakpoints if no address specified\n */\n clearTempBreakpoint(addr)\n {\n if (addr !== undefined) {\n this.checkBreakpoint(addr, 1, this.aBreakExec, true);\n this.nStep = 0;\n } else {\n for (var i = 1; i < this.aBreakExec.length; i++) {\n var dbgAddrBreak = this.aBreakExec[i];\n if (dbgAddrBreak.fTemporary) {\n if (!this.findBreakpoint(this.aBreakExec, dbgAddrBreak, true, true)) break;\n i = 0;\n }\n }\n }\n }\n\n /**\n * checkBreakpoint(addr, nb, aBreak, fTemporary)\n *\n * @this {Debugger8080}\n * @param {number} addr\n * @param {number} nb (# of bytes)\n * @param {Array} aBreak\n * @param {boolean} [fTemporary]\n * @return {boolean} true if breakpoint has been hit, false if not\n */\n checkBreakpoint(addr, nb, aBreak, fTemporary)\n {\n /*\n * Time to check for execution breakpoints; note that this should be done BEFORE updating frequency\n * or history data (see checkInstruction), since we might not actually execute the current instruction.\n */\n var fBreak = false;\n\n if (!this.nSuppressBreaks++) {\n\n for (var i = 1; !fBreak && i < aBreak.length; i++) {\n\n var dbgAddrBreak = aBreak[i];\n\n if (fTemporary && !dbgAddrBreak.fTemporary) continue;\n\n /*\n * We used to calculate the linear address of the breakpoint at the time the\n * breakpoint was added, so that a breakpoint set in one mode (eg, in real-mode)\n * would still work as intended if the mode changed later (eg, to protected-mode).\n *\n * However, that created difficulties setting protected-mode breakpoints in segments\n * that might not be defined yet, or that could move in physical memory.\n *\n * If you want to create a real-mode breakpoint that will break regardless of mode,\n * use the physical address of the real-mode memory location instead.\n */\n var addrBreak = this.getAddr(dbgAddrBreak);\n for (var n = 0; n < nb; n++) {\n if (addr + n == addrBreak) {\n var a;\n fBreak = true;\n if (dbgAddrBreak.fTemporary) {\n this.findBreakpoint(aBreak, dbgAddrBreak, true, true);\n fTemporary = true;\n }\n if (a = dbgAddrBreak.aCmds) {\n /*\n * When one or more commands are attached to a breakpoint, we don't halt by default.\n * Instead, we set fBreak to true only if, at the completion of all the commands, the\n * CPU is halted; in other words, you should include \"h\" as one of the breakpoint commands\n * if you want the breakpoint to stop execution.\n *\n * Another useful command is \"if\", which will return false if the expression is false,\n * at which point we'll jump ahead to the next \"else\" command, and if there isn't an \"else\",\n * we abort.\n */\n fBreak = false;\n for (var j = 0; j < a.length; j++) {\n if (!this.doCommand(a[j], true)) {\n if (a[j].indexOf(\"if\")) {\n fBreak = true; // the failed command wasn't \"if\", so abort\n break;\n }\n var k = j + 1;\n for (; k < a.length; k++) {\n if (!a[k].indexOf(\"else\")) break;\n j++;\n }\n if (k == a.length) { // couldn't find an \"else\" after the \"if\", so abort\n fBreak = true;\n break;\n }\n /*\n * If we're still here, we'll execute the \"else\" command (which is just a no-op),\n * followed by any remaining commands.\n */\n }\n }\n if (!this.cpu.isRunning()) fBreak = true;\n }\n if (fBreak) {\n if (!fTemporary) this.printBreakpoint(aBreak, i, \"hit\");\n break;\n }\n }\n }\n }\n }\n\n this.nSuppressBreaks--;\n\n return fBreak;\n }\n\n /**\n * getInstruction(dbgAddr, sComment, nSequence)\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {string} [sComment] is an associated comment\n * @param {number|null} [nSequence] is an associated sequence number, undefined if none\n * @return {string} (and dbgAddr is updated to the next instruction)\n */\n getInstruction(dbgAddr, sComment, nSequence)\n {\n var dbgAddrIns = this.newAddr(dbgAddr.addr);\n\n var bOpcode = this.getByte(dbgAddr, 1);\n\n var asOpcodes = this.style != Debugger8080.STYLE_8086? Debugger8080.INS_NAMES : Debugger8080.INS_NAMES_8086;\n var aOpDesc = this.aaOpDescs[bOpcode];\n var iIns = aOpDesc[0];\n\n var sOperands = \"\";\n var sOpcode = asOpcodes[iIns];\n var cOperands = aOpDesc.length - 1;\n var typeSizeDefault = Debugger8080.TYPE_NONE, type;\n\n for (var iOperand = 1; iOperand <= cOperands; iOperand++) {\n\n var disp, off, cch;\n var sOperand = \"\";\n\n type = aOpDesc[iOperand];\n if (type === undefined) continue;\n if ((type & Debugger8080.TYPE_OPT) && this.style == Debugger8080.STYLE_8080) continue;\n\n var typeMode = type & Debugger8080.TYPE_MODE;\n if (!typeMode) continue;\n\n var typeSize = type & Debugger8080.TYPE_SIZE;\n if (!typeSize) {\n type |= typeSizeDefault;\n } else {\n typeSizeDefault = typeSize;\n }\n\n var typeOther = type & Debugger8080.TYPE_OTHER;\n if (!typeOther) {\n type |= (iOperand == 1? Debugger8080.TYPE_OUT : Debugger8080.TYPE_IN);\n }\n\n if (typeMode & Debugger8080.TYPE_IMM) {\n sOperand = this.getImmOperand(type, dbgAddr);\n }\n else if (typeMode & Debugger8080.TYPE_REG) {\n sOperand = this.getRegOperand((type & Debugger8080.TYPE_IREG) >> 8, type, dbgAddr);\n }\n else if (typeMode & Debugger8080.TYPE_INT) {\n sOperand = ((bOpcode >> 3) & 0x7).toString();\n }\n\n if (!sOperand || !sOperand.length) {\n sOperands = \"INVALID\";\n break;\n }\n if (sOperands.length > 0) sOperands += ',';\n sOperands += (sOperand || \"???\");\n }\n\n var sBytes = \"\";\n var sLine = this.toHexAddr(dbgAddrIns) + ' ';\n if (dbgAddrIns.addr !== CPUDef8080.ADDR_INVALID && dbgAddr.addr !== CPUDef8080.ADDR_INVALID) {\n do {\n sBytes += Str.toHex(this.getByte(dbgAddrIns, 1), 2);\n if (dbgAddrIns.addr == null) break;\n } while (dbgAddrIns.addr != dbgAddr.addr);\n }\n\n sLine += Str.pad(sBytes, 10);\n sLine += (type & Debugger8080.TYPE_UNDOC)? '*' : ' ';\n sLine += Str.pad(sOpcode, 7);\n if (sOperands) sLine += ' ' + sOperands;\n\n if (sComment) {\n sLine = Str.pad(sLine, 40) + ';' + sComment;\n if (!this.cpu.flags.checksum) {\n sLine += (nSequence != null? '=' + nSequence.toString() : \"\");\n } else {\n var nCycles = this.cpu.getCycles();\n sLine += \"cycles=\" + nCycles.toString() + \" cs=\" + Str.toHex(this.cpu.nChecksum);\n }\n }\n return sLine;\n }\n\n /**\n * getImmOperand(type, dbgAddr)\n *\n * @this {Debugger8080}\n * @param {number} type\n * @param {DbgAddr8080} dbgAddr\n * @return {string} operand\n */\n getImmOperand(type, dbgAddr)\n {\n var sOperand = ' ';\n var typeSize = type & Debugger8080.TYPE_SIZE;\n\n switch (typeSize) {\n case Debugger8080.TYPE_BYTE:\n sOperand = Str.toHex(this.getByte(dbgAddr, 1), 2);\n break;\n case Debugger8080.TYPE_SBYTE:\n sOperand = Str.toHex((this.getByte(dbgAddr, 1) << 24) >> 24, 4);\n break;\n case Debugger8080.TYPE_WORD:\n sOperand = Str.toHex(this.getShort(dbgAddr, 2), 4);\n break;\n default:\n return \"imm(\" + Str.toHexWord(type) + ')';\n }\n if (this.style == Debugger8080.STYLE_8086 && (type & Debugger8080.TYPE_MEM)) {\n sOperand = '[' + sOperand + ']';\n } else if (!(type & Debugger8080.TYPE_REG)) {\n sOperand = (this.style == Debugger8080.STYLE_8080? '$' : \"0x\") + sOperand;\n }\n return sOperand;\n }\n\n /**\n * getRegOperand(iReg, type, dbgAddr)\n *\n * @this {Debugger8080}\n * @param {number} iReg\n * @param {number} type\n * @param {DbgAddr8080} dbgAddr\n * @return {string} operand\n */\n getRegOperand(iReg, type, dbgAddr)\n {\n /*\n * Although this breaks with 8080 assembler conventions, I'm going to experiment with some different\n * mnemonics; specifically, \"[HL]\" instead of \"M\". This is also more in keeping with how getImmOperand()\n * displays memory references (ie, by enclosing them in brackets).\n */\n var sOperand = Debugger8080.REGS[iReg];\n if (this.style == Debugger8080.STYLE_8086 && (type & Debugger8080.TYPE_MEM)) {\n if (iReg == Debugger8080.REG_M) {\n sOperand = \"HL\";\n }\n sOperand = '[' + sOperand + ']';\n }\n return sOperand;\n }\n\n /**\n * parseInstruction(sOp, sOperand, addr)\n *\n * TODO: Unimplemented. See parseInstruction() in modules/c1pjs/lib/debugger.js for a working implementation.\n *\n * @this {Debugger8080}\n * @param {string} sOp\n * @param {string|undefined} sOperand\n * @param {DbgAddr8080} dbgAddr of memory where this instruction is being assembled\n * @return {Array.<number>} of opcode bytes; if the instruction can't be parsed, the array will be empty\n */\n parseInstruction(sOp, sOperand, dbgAddr)\n {\n var aOpBytes = [];\n this.println(\"not supported yet\");\n return aOpBytes;\n }\n\n /**\n * getFlagOutput(sFlag)\n *\n * @this {Debugger8080}\n * @param {string} sFlag\n * @return {string} value of flag\n */\n getFlagOutput(sFlag)\n {\n var b;\n switch (sFlag) {\n case \"IF\":\n b = this.cpu.getIF();\n break;\n case \"SF\":\n b = this.cpu.getSF();\n break;\n case \"ZF\":\n b = this.cpu.getZF();\n break;\n case \"AF\":\n b = this.cpu.getAF();\n break;\n case \"PF\":\n b = this.cpu.getPF();\n break;\n case \"CF\":\n b = this.cpu.getCF();\n break;\n default:\n b = 0;\n break;\n }\n return sFlag.charAt(0) + (b? '1' : '0') + ' ';\n }\n\n /**\n * getRegOutput(iReg)\n *\n * @this {Debugger8080}\n * @param {number} iReg\n * @return {string}\n */\n getRegOutput(iReg)\n {\n var sReg = Debugger8080.REGS[iReg];\n return sReg + '=' + this.getRegString(iReg) + ' ';\n }\n\n /**\n * getRegDump()\n *\n * Sample 8080 register dump:\n *\n * A=00 BC=0000 DE=0000 HL=0000 SP=0000 I0 S0 Z0 A0 P0 C0\n * 0000 00 NOP\n *\n * @this {Debugger8080}\n * @return {string}\n */\n getRegDump()\n {\n var s;\n s = this.getRegOutput(Debugger8080.REG_A) +\n this.getRegOutput(Debugger8080.REG_BC) +\n this.getRegOutput(Debugger8080.REG_DE) +\n this.getRegOutput(Debugger8080.REG_HL) +\n this.getRegOutput(Debugger8080.REG_SP) +\n this.getFlagOutput(\"IF\") + this.getFlagOutput(\"SF\") + this.getFlagOutput(\"ZF\") +\n this.getFlagOutput(\"AF\") + this.getFlagOutput(\"PF\") + this.getFlagOutput(\"CF\");\n return s;\n }\n\n /**\n * comparePairs(p1, p2)\n *\n * @this {Debugger8080}\n * @param {number|string|Array|Object} p1\n * @param {number|string|Array|Object} p2\n * @return {number}\n */\n comparePairs(p1, p2)\n {\n return p1[0] > p2[0]? 1 : p1[0] < p2[0]? -1 : 0;\n }\n\n /**\n * addSymbols(sModule, addr, len, aSymbols)\n *\n * As filedump.js (formerly convrom.php) explains, aSymbols is a JSON-encoded object whose properties consist\n * of all the symbols (in upper-case), and the values of those properties are objects containing any or all of\n * the following properties:\n *\n * 'v': the value of an absolute (unsized) value\n * 'b': either 1, 2, 4 or undefined if an unsized value\n * 's': either a hard-coded segment or undefined\n * 'o': the offset of the symbol within the associated address space\n * 'l': the original-case version of the symbol, present only if it wasn't originally upper-case\n * 'a': annotation for the specified offset; eg, the original assembly language, with optional comment\n *\n * To that list of properties, we also add:\n *\n * 'p': the physical address (calculated whenever both 's' and 'o' properties are defined)\n *\n * Note that values for any 'v', 'b', 's' and 'o' properties are unquoted decimal values, and the values\n * for any 'l' or 'a' properties are quoted strings. Also, if double-quotes were used in any of the original\n * annotation ('a') values, they will have been converted to two single-quotes, so we're responsible for\n * converting them back to individual double-quotes.\n *\n * For example:\n * {\n * 'HF_PORT': {\n * 'v':800\n * },\n * 'HDISK_INT': {\n * 'b':4, 's':0, 'o':52\n * },\n * 'ORG_VECTOR': {\n * 'b':4, 's':0, 'o':76\n * },\n * 'CMD_BLOCK': {\n * 'b':1, 's':64, 'o':66\n * },\n * 'DISK_SETUP': {\n * 'o':3\n * },\n * '.40': {\n * 'o':40, 'a':\"MOV AX,WORD PTR ORG_VECTOR ;GET DISKETTE VECTOR\"\n * }\n * }\n *\n * If a symbol only has an offset, then that offset value can be assigned to the symbol property directly:\n *\n * 'DISK_SETUP': 3\n *\n * The last property is an example of an \"anonymous\" entry, for offsets where there is no associated symbol.\n * Such entries are identified by a period followed by a unique number (usually the offset of the entry), and\n * they usually only contain offset ('o') and annotation ('a') properties. I could eliminate the leading\n * period, but it offers a very convenient way of quickly discriminating among genuine vs. anonymous symbols.\n *\n * We add all these entries to our internal symbol table, which is an array of 4-element arrays, each of which\n * look like:\n *\n * [addr, len, aSymbols, aOffsets]\n *\n * There are two basic symbol operations: findSymbol(), which takes an address and finds the symbol, if any,\n * at that address, and findSymbolAddr(), which takes a string and attempts to match it to a non-anonymous\n * symbol with a matching offset ('o') property.\n *\n * To implement findSymbol() efficiently, addSymbols() creates an array of [offset, sSymbol] pairs\n * (aOffsets), one pair for each symbol that corresponds to an offset within the specified address space.\n *\n * We guarantee the elements of aOffsets are in offset order, because we build it using binaryInsert();\n * it's quite likely that the MAP file already ordered all its symbols in offset order, but since they're\n * hand-edited files, we can't assume that, and we need to ensure that findSymbol()'s binarySearch() operates\n * properly.\n *\n * @this {Debugger8080}\n * @param {string|null} sModule\n * @param {number|null} addr (physical address where the symbols are located, if the memory is physical; eg, ROM)\n * @param {number} len (the size of the region, in bytes)\n * @param {Object} aSymbols (collection of symbols in this group; the format of this collection is described below)\n */\n addSymbols(sModule, addr, len, aSymbols)\n {\n var dbgAddr = {};\n var aOffsets = [];\n for (var sSymbol in aSymbols) {\n var symbol = aSymbols[sSymbol];\n if (typeof symbol == \"number\") {\n aSymbols[sSymbol] = symbol = {'o': symbol};\n }\n var offSymbol = symbol['o'];\n var sAnnotation = symbol['a'];\n if (offSymbol !== undefined) {\n Usr.binaryInsert(aOffsets, [offSymbol >>> 0, sSymbol], this.comparePairs);\n }\n if (sAnnotation) symbol['a'] = sAnnotation.replace(/''/g, \"\\\"\");\n }\n var symbolTable = {\n sModule: sModule,\n addr: addr,\n len: len,\n aSymbols: aSymbols,\n aOffsets: aOffsets\n };\n this.aSymbolTable.push(symbolTable);\n }\n\n /**\n * dumpSymbols()\n *\n * TODO: Add \"numerical\" and \"alphabetical\" dump options. This is simply dumping them in whatever\n * order they appeared in the original MAP file.\n *\n * @this {Debugger8080}\n */\n dumpSymbols()\n {\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n for (var sSymbol in symbolTable.aSymbols) {\n if (sSymbol.charAt(0) == '.') continue;\n var symbol = symbolTable.aSymbols[sSymbol];\n var offSymbol = symbol['o'];\n if (offSymbol === undefined) continue;\n var sSymbolOrig = symbolTable.aSymbols[sSymbol]['l'];\n if (sSymbolOrig) sSymbol = sSymbolOrig;\n this.println(this.toHexOffset(offSymbol) + ' ' + sSymbol);\n }\n }\n }\n\n /**\n * findSymbol(dbgAddr, fNearest)\n *\n * Search aSymbolTable for dbgAddr, and return an Array for the corresponding symbol (empty if not found).\n *\n * If fNearest is true, and no exact match was found, then the Array returned will contain TWO sets of\n * entries: [0]-[3] will refer to closest preceding symbol, and [4]-[7] will refer to the closest subsequent symbol.\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {boolean} [fNearest]\n * @return {Array} where [0] == symbol name, [1] == symbol value, [2] == any annotation, and [3] == any associated comment\n */\n findSymbol(dbgAddr, fNearest)\n {\n var aSymbol = [];\n var addrSymbol = this.getAddr(dbgAddr) >>> 0;\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n var addr = symbolTable.addr >>> 0;\n var len = symbolTable.len;\n if (addrSymbol >= addr && addrSymbol < addr + len) {\n var offSymbol = addrSymbol - addr;\n var result = Usr.binarySearch(symbolTable.aOffsets, [offSymbol], this.comparePairs);\n if (result >= 0) {\n this.returnSymbol(iTable, result, aSymbol);\n }\n else if (fNearest) {\n result = ~result;\n this.returnSymbol(iTable, result-1, aSymbol);\n this.returnSymbol(iTable, result, aSymbol);\n }\n break;\n }\n }\n return aSymbol;\n }\n\n /**\n * findSymbolAddr(sSymbol)\n *\n * Search aSymbolTable for sSymbol, and if found, return a dbgAddr (same as parseAddr())\n *\n * @this {Debugger8080}\n * @param {string} sSymbol\n * @return {DbgAddr8080|undefined}\n */\n findSymbolAddr(sSymbol)\n {\n var dbgAddr;\n if (sSymbol.match(/^[a-z_][a-z0-9_]*$/i)) {\n var sUpperCase = sSymbol.toUpperCase();\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n var symbol = symbolTable.aSymbols[sUpperCase];\n if (symbol !== undefined) {\n var offSymbol = symbol['o'];\n if (offSymbol !== undefined) {\n /*\n * We assume that every ROM is ORG'ed at 0x0000, and therefore unless the symbol has an\n * explicitly-defined segment, we return the segment associated with the entire group; for\n * a ROM, that segment is normally \"addrROM >>> 4\". Down the road, we may want/need to\n * support a special symbol entry (eg, \".ORG\") that defines an alternate origin.\n */\n dbgAddr = this.newAddr(offSymbol);\n }\n /*\n * The symbol matched, but it wasn't for an address (no 'o' offset), and there's no point\n * looking any farther, since each symbol appears only once, so we indicate it's an unknown symbol.\n */\n break;\n }\n }\n }\n return dbgAddr;\n }\n\n /**\n * returnSymbol(iTable, iOffset, aSymbol)\n *\n * Helper function for findSymbol().\n *\n * @param {number} iTable\n * @param {number} iOffset\n * @param {Array} aSymbol is updated with the specified symbol, if it exists\n */\n returnSymbol(iTable, iOffset, aSymbol)\n {\n var symbol = {};\n var aOffsets = this.aSymbolTable[iTable].aOffsets;\n var offset = 0, sSymbol = null;\n if (iOffset >= 0 && iOffset < aOffsets.length) {\n offset = aOffsets[iOffset][0];\n sSymbol = aOffsets[iOffset][1];\n }\n if (sSymbol) {\n symbol = this.aSymbolTable[iTable].aSymbols[sSymbol];\n sSymbol = (sSymbol.charAt(0) == '.'? null : (symbol['l'] || sSymbol));\n }\n aSymbol.push(sSymbol);\n aSymbol.push(offset);\n aSymbol.push(symbol['a']);\n aSymbol.push(symbol['c']);\n }\n\n /**\n * doHelp()\n *\n * @this {Debugger8080}\n */\n doHelp()\n {\n var s = \"commands:\";\n for (var sCommand in Debugger8080.COMMANDS) {\n s += '\\n' + Str.pad(sCommand, 9) + Debugger8080.COMMANDS[sCommand];\n }\n if (!this.checksEnabled()) s += \"\\nnote: frequency/history disabled if no exec breakpoints\";\n this.println(s);\n }\n\n /**\n * doAssemble(asArgs)\n *\n * This always receives the complete argument array, where the order of the arguments is:\n *\n * [0]: the assemble command (assumed to be \"a\")\n * [1]: the target address (eg, \"200\")\n * [2]: the operation code, aka instruction name (eg, \"adc\")\n * [3]: the operation mode operand, if any (eg, \"14\", \"[1234]\", etc)\n *\n * The Debugger enters \"assemble mode\" whenever only the first (or first and second) arguments are present.\n * As long as \"assemble mode is active, the user can omit the first two arguments on all later assemble commands\n * until \"assemble mode\" is cancelled with an empty command line; the command processor automatically prepends \"a\"\n * and the next available target address to the argument array.\n *\n * Entering \"assemble mode\" is optional; one could enter a series of fully-qualified assemble commands; eg:\n *\n * a ff00 cld\n * a ff01 ldx 28\n * ...\n *\n * without ever entering \"assemble mode\", but of course, that requires more typing and doesn't take advantage\n * of automatic target address advancement (see dbgAddrAssemble).\n *\n * NOTE: As the previous example implies, you can even assemble new instructions into ROM address space;\n * as our setByte() function explains, the ROM write-notification handlers only refuse writes from the CPU.\n *\n * @this {Debugger8080}\n * @param {Array.<string>} asArgs is the complete argument array, beginning with the \"a\" command in asArgs[0]\n */\n doAssemble(asArgs)\n {\n var dbgAddr = this.parseAddr(asArgs[1], true);\n if (!dbgAddr) return;\n\n this.dbgAddrAssemble = dbgAddr;\n if (asArgs[2] === undefined) {\n this.println(\"begin assemble at \" + this.toHexAddr(dbgAddr));\n this.fAssemble = true;\n this.cpu.updateCPU();\n return;\n }\n\n var aOpBytes = this.parseInstruction(asArgs[2], asArgs[3], dbgAddr);\n if (aOpBytes.length) {\n for (var i = 0; i < aOpBytes.length; i++) {\n this.setByte(dbgAddr, aOpBytes[i], 1);\n }\n /*\n * Since getInstruction() also updates the specified address, dbgAddrAssemble is automatically advanced.\n */\n this.println(this.getInstruction(this.dbgAddrAssemble));\n }\n }\n\n /**\n * doBreak(sCmd, sAddr, sOptions)\n *\n * As the \"help\" output below indicates, the following breakpoint commands are supported:\n *\n * bp [a] set exec breakpoint on linear addr [a]\n * br [a] set read breakpoint on linear addr [a]\n * bw [a] set write breakpoint on linear addr [a]\n * bc [a] clear breakpoint on linear addr [a] (use \"*\" for all breakpoints)\n * bl list breakpoints\n *\n * to which we have recently added the following I/O breakpoint commands:\n *\n * bi [p] toggle input breakpoint on port [p] (use \"*\" for all input ports)\n * bo [p] toggle output breakpoint on port [p] (use \"*\" for all output ports)\n *\n * These two new commands operate as toggles so that if \"*\" is used to trap all input (or output),\n * you can also use these commands to NOT trap specific ports.\n *\n * bn [n] break after [n] instructions\n *\n * TODO: Update the \"bl\" command to include any/all I/O breakpoints, and the \"bc\" command to\n * clear them. Because \"bi\" and \"bo\" commands are piggy-backing on Bus functions, those breakpoints\n * are currently outside the realm of what the \"bl\" and \"bc\" commands are aware of.\n *\n * @this {Debugger8080}\n * @param {string} sCmd\n * @param {string|undefined} [sAddr]\n * @param {string} [sOptions] (the rest of the breakpoint command-line)\n */\n doBreak(sCmd, sAddr, sOptions)\n {\n if (sAddr == '?') {\n this.println(\"breakpoint commands:\");\n this.println(\"\\tbi [p]\\ttoggle break on input port [p]\");\n this.println(\"\\tbo [p]\\ttoggle break on output port [p]\");\n this.println(\"\\tbp [a]\\tset exec breakpoint at addr [a]\");\n this.println(\"\\tbr [a]\\tset read breakpoint at addr [a]\");\n this.println(\"\\tbw [a]\\tset write breakpoint at addr [a]\");\n this.println(\"\\tbc [a]\\tclear breakpoint at addr [a]\");\n this.println(\"\\tbl\\tlist all breakpoints\");\n this.println(\"\\tbn [n]\\tbreak after [n] instruction(s)\");\n return;\n }\n\n var sParm = sCmd.charAt(1);\n if (sParm == 'l') {\n var cBreaks = 0;\n cBreaks += this.listBreakpoints(this.aBreakExec);\n cBreaks += this.listBreakpoints(this.aBreakRead);\n cBreaks += this.listBreakpoints(this.aBreakWrite);\n if (!cBreaks) this.println(\"no breakpoints\");\n return;\n }\n\n if (sParm == 'n') {\n this.nBreakIns = this.parseValue(sAddr);\n this.println(\"break after \" + this.nBreakIns + \" instruction(s)\");\n return;\n }\n\n if (sAddr === undefined) {\n this.println(\"missing breakpoint address\");\n return;\n }\n\n var dbgAddr = this.newAddr();\n if (sAddr != '*') {\n dbgAddr = this.parseAddr(sAddr, true, true);\n if (!dbgAddr) return;\n }\n\n sAddr = Str.toHexWord(dbgAddr.addr);\n\n if (sParm == 'c') {\n if (dbgAddr.addr == null) {\n this.clearBreakpoints();\n this.println(\"all breakpoints cleared\");\n return;\n }\n if (this.findBreakpoint(this.aBreakExec, dbgAddr, true))\n return;\n if (this.findBreakpoint(this.aBreakRead, dbgAddr, true))\n return;\n if (this.findBreakpoint(this.aBreakWrite, dbgAddr, true))\n return;\n this.println(\"breakpoint missing: \" + this.toHexAddr(dbgAddr));\n return;\n }\n\n if (sParm == 'i') {\n this.println(\"breakpoint \" + (this.bus.addPortInputBreak(dbgAddr.addr)? \"enabled\" : \"cleared\") + \": port \" + sAddr + \" (input)\");\n return;\n }\n\n if (sParm == 'o') {\n this.println(\"breakpoint \" + (this.bus.addPortOutputBreak(dbgAddr.addr)? \"enabled\" : \"cleared\") + \": port \" + sAddr + \" (output)\");\n return;\n }\n\n if (dbgAddr.addr == null) return;\n\n this.parseAddrOptions(dbgAddr, sOptions);\n\n if (sParm == 'p') {\n this.addBreakpoint(this.aBreakExec, dbgAddr);\n return;\n }\n if (sParm == 'r') {\n this.addBreakpoint(this.aBreakRead, dbgAddr);\n return;\n }\n if (sParm == 'w') {\n this.addBreakpoint(this.aBreakWrite, dbgAddr);\n return;\n }\n this.println(\"unknown breakpoint command: \" + sParm);\n }\n\n /**\n * doClear(sCmd)\n *\n * @this {Debugger8080}\n * @param {string} [sCmd] (eg, \"cls\" or \"clear\")\n */\n doClear(sCmd)\n {\n this.cmp.clearPanel();\n }\n\n /**\n * doDump(asArgs)\n *\n * The length parameter is interpreted as a number of bytes, in hex, which we convert to the appropriate number\n * of lines, because we always display whole lines. If the length is omitted/undefined, it defaults to 0x80 (128.)\n * bytes, which normally translates to 8 lines.\n *\n * @this {Debugger8080}\n * @param {Array.<string>} asArgs (formerly sCmd, [sAddr], [sLen] and [sBytes])\n */\n doDump(asArgs)\n {\n var m;\n var sCmd = asArgs[0];\n var sAddr = asArgs[1];\n var sLen = asArgs[2];\n var sBytes = asArgs[3];\n\n if (sAddr == '?') {\n var sDumpers = \"\";\n for (m in Messages8080.CATEGORIES) {\n if (this.afnDumpers[m]) {\n if (sDumpers) sDumpers += ',';\n sDumpers = sDumpers + m;\n }\n }\n sDumpers += \",state,symbols\";\n this.println(\"dump memory commands:\");\n this.println(\"\\tdb [a] [#] dump # bytes at address a\");\n this.println(\"\\tdw [a] [#] dump # words at address a\");\n this.println(\"\\tdd [a] [#] dump # dwords at address a\");\n this.println(\"\\tdh [#] [#] dump # instructions from history\");\n if (sDumpers.length) this.println(\"dump extension commands:\\n\\t\" + sDumpers);\n return;\n }\n\n if (sAddr == \"state\") {\n var sState = this.cmp.powerOff(true);\n if (sLen == \"console\") {\n /*\n * Console buffers are notoriously small, and even the following code, which breaks the\n * data into parts (eg, \"d state console 1\", \"d state console 2\", etc) just isn't that helpful.\n *\n * var nPart = +sBytes;\n * if (nPart) sState = sState.substr(1000000 * (nPart-1), 1000000);\n *\n * So, the best way to capture a large machine state is to use the new \"Save Machine\" link\n * that downloads a machine's entire state. Alternatively, run your own local server and use\n * server-side storage. Take a look at the \"Save\" binding in computer.js, which binds an HTML\n * control to the computer.powerOff() and computer.saveServerState() functions.\n */\n console.log(sState);\n } else {\n this.doClear();\n if (sState) this.println(sState);\n }\n return;\n }\n\n if (sAddr == \"symbols\") {\n this.dumpSymbols();\n return;\n }\n\n if (sCmd == \"d\") {\n for (m in Messages8080.CATEGORIES) {\n if (asArgs[1] == m) {\n var fnDumper = this.afnDumpers[m];\n if (fnDumper) {\n asArgs.shift();\n asArgs.shift();\n fnDumper(asArgs);\n } else {\n this.println(\"no dump registered for \" + sAddr);\n }\n return;\n }\n }\n if (!sAddr) sCmd = this.sCmdDumpPrev || \"db\";\n } else {\n this.sCmdDumpPrev = sCmd;\n }\n\n if (sCmd == \"dh\") {\n this.dumpHistory(sAddr, sLen);\n return;\n }\n\n var dbgAddr = this.parseAddr(sAddr);\n if (!dbgAddr) return;\n\n var len = 0; // 0 is not a default; it triggers the appropriate default below\n if (sLen) {\n if (sLen.charAt(0) == 'l') {\n sLen = sLen.substr(1) || sBytes;\n }\n len = this.parseValue(sLen) >>> 0; // negative lengths not allowed\n if (len > 0x10000) len = 0x10000; // prevent bad user (or variable) input from producing excessive output\n }\n\n var sDump = \"\";\n var size = (sCmd == \"dd\"? 4 : (sCmd == \"dw\"? 2 : 1));\n var cb = (size * len) || 128;\n var cLines = ((cb + 15) >> 4) || 1;\n\n while (cLines-- && cb > 0) {\n var data = 0, iByte = 0, i;\n var sData = \"\", sChars = \"\";\n sAddr = this.toHexAddr(dbgAddr);\n for (i = 16; i > 0 && cb > 0; i--) {\n var b = this.getByte(dbgAddr, 1);\n data |= (b << (iByte++ << 3));\n if (iByte == size) {\n sData += Str.toHex(data, size * 2);\n sData += (size == 1? (i == 9? '-' : ' ') : \" \");\n data = iByte = 0;\n }\n sChars += (b >= 32 && b < 127? String.fromCharCode(b) : '.');\n cb--;\n }\n if (sDump) sDump += '\\n';\n sDump += sAddr + \" \" + sData + ((i == 0)? (' ' + sChars) : \"\");\n }\n\n if (sDump) this.println(sDump);\n this.dbgAddrNextData = dbgAddr;\n }\n\n /**\n * doEdit(asArgs)\n *\n * @this {Debugger8080}\n * @param {Array.<string>} asArgs\n */\n doEdit(asArgs)\n {\n var size = 1;\n var mask = 0xff;\n var fnGet = this.getByte;\n var fnSet = this.setByte;\n if (asArgs[0] == \"ew\") {\n size = 2;\n mask = 0xffff;\n fnGet = this.getShort;\n fnSet = this.setShort;\n }\n var cch = size << 1;\n\n var sAddr = asArgs[1];\n if (sAddr == null) {\n this.println(\"edit memory commands:\");\n this.println(\"\\teb [a] [...] edit bytes at address a\");\n this.println(\"\\tew [a] [...] edit words at address a\");\n return;\n }\n\n var dbgAddr = this.parseAddr(sAddr);\n if (!dbgAddr) return;\n\n for (var i = 2; i < asArgs.length; i++) {\n var vNew = this.parseExpression(asArgs[i]);\n if (vNew === undefined) {\n this.println(\"unrecognized value: \" + asArgs[i]);\n break;\n }\n if (vNew & ~mask) {\n this.println(\"warning: \" + Str.toHex(vNew) + \" exceeds \" + size + \"-byte value\");\n }\n var vOld = fnGet.call(this, dbgAddr);\n this.println(\"changing \" + this.toHexAddr(dbgAddr) + \" from \" + Str.toHex(vOld, cch, true) + \" to \" + Str.toHex(vNew, cch, true));\n fnSet.call(this, dbgAddr, vNew, size);\n }\n }\n\n /**\n * doFreqs(sParm)\n *\n * @this {Debugger8080}\n * @param {string|undefined} sParm\n */\n doFreqs(sParm)\n {\n if (sParm == '?') {\n this.println(\"frequency commands:\");\n this.println(\"\\tclear\\tclear all frequency counts\");\n return;\n }\n var i;\n var cData = 0;\n if (this.aaOpcodeCounts) {\n if (sParm == \"clear\") {\n for (i = 0; i < this.aaOpcodeCounts.length; i++)\n this.aaOpcodeCounts[i] = [i, 0];\n this.println(\"frequency data cleared\");\n cData++;\n }\n else if (sParm !== undefined) {\n this.println(\"unknown frequency command: \" + sParm);\n cData++;\n }\n else {\n var aaSortedOpcodeCounts = this.aaOpcodeCounts.slice();\n aaSortedOpcodeCounts.sort(function(p, q) {\n return q[1] - p[1];\n });\n var asOpcodes = this.style != Debugger8080.STYLE_8086? Debugger8080.INS_NAMES : Debugger8080.INS_NAMES_8086;\n for (i = 0; i < aaSortedOpcodeCounts.length; i++) {\n var bOpcode = aaSortedOpcodeCounts[i][0];\n var cFreq = aaSortedOpcodeCounts[i][1];\n if (cFreq) {\n this.println((asOpcodes[this.aaOpDescs[bOpcode][0]] + \" \").substr(0, 5) + \" (\" + Str.toHexByte(bOpcode) + \"): \" + cFreq + \" times\");\n cData++;\n }\n }\n }\n }\n if (!cData) {\n this.println(\"no frequency data available\");\n }\n }\n\n /**\n * doHalt(fQuiet)\n *\n * @this {Debugger8080}\n * @param {boolean} [fQuiet]\n */\n doHalt(fQuiet)\n {\n var sMsg;\n if (this.flags.running) {\n sMsg = \"halting\";\n this.stopCPU();\n } else {\n if (this.isBusy(true)) return;\n sMsg = \"already halted\";\n }\n if (!fQuiet) this.println(sMsg);\n }\n\n /**\n * doIf(sCmd, fQuiet)\n *\n * NOTE: Don't forget that the default base for all numeric constants is 16 (hex), so when you evaluate\n * an expression like \"a==10\", it will compare the value of the variable \"a\" to 0x10; use a trailing period\n * (eg, \"10.\") if you really intend decimal.\n *\n * Also, if no variable named \"a\" exists, \"a\" will evaluate to 0x0A, so the expression \"a==10\" becomes\n * \"0x0A==0x10\" (false), whereas the expression \"a==10.\" becomes \"0x0A==0x0A\" (true).\n *\n * @this {Debugger8080}\n * @param {string} sCmd\n * @param {boolean} [fQuiet]\n * @return {boolean} true if expression is non-zero, false if zero (or undefined due to a parse error)\n */\n doIf(sCmd, fQuiet)\n {\n sCmd = Str.trim(sCmd);\n if (!this.parseExpression(sCmd)) {\n if (!fQuiet) this.println(\"false: \" + sCmd);\n return false;\n }\n if (!fQuiet) this.println(\"true: \" + sCmd);\n return true;\n }\n\n /**\n * doInfo(asArgs)\n *\n * @this {Debugger8080}\n * @param {Array.<string>} asArgs\n * @return {boolean} true only if the instruction info command (\"n\") is supported\n */\n doInfo(asArgs)\n {\n if (DEBUG) {\n this.println(\"msPerYield: \" + this.cpu.msPerYield);\n this.println(\"nCyclesPerYield: \" + this.cpu.nCyclesPerYield);\n return true;\n }\n return false;\n }\n\n /**\n * doInput(sPort)\n *\n * Simulate a 1-byte port input operation.\n *\n * @this {Debugger8080}\n * @param {string|undefined} sPort\n */\n doInput(sPort)\n {\n if (!sPort || sPort == '?') {\n this.println(\"input commands:\");\n this.println(\"\\ti [p]\\tread port [p]\");\n /*\n * TODO: Regarding this warning, consider adding an \"unchecked\" version of\n * bus.checkPortInputNotify(), since all Debugger memory accesses are unchecked, too.\n *\n * All port I/O handlers ARE aware when the Debugger is calling (addrFrom is undefined),\n * but changing them all to be non-destructive would take time, and situations where you\n * actually want to affect the hardware state are just as likely as not....\n */\n this.println(\"warning: port accesses can affect hardware state\");\n return;\n }\n var port = this.parseValue(sPort);\n if (port !== undefined) {\n var bIn = this.bus.checkPortInputNotify(port, 1);\n this.println(Str.toHexWord(port) + \": \" + Str.toHexByte(bIn));\n }\n }\n\n /**\n * doInt(sLevel)\n *\n * @this {Debugger8080}\n * @param {string} sLevel\n * @return {boolean} true if success, false if error\n */\n doInt(sLevel)\n {\n if (!this.cpu.getIF()) {\n this.println(\"interrupts disabled (use rif=1 to enable)\");\n return false;\n }\n var nLevel = this.parseExpression(sLevel);\n if (nLevel == null) return false;\n this.println(\"requesting interrupt level \" + nLevel);\n this.cpu.requestINTR(nLevel);\n return true;\n }\n\n /**\n * doVar(sCmd)\n *\n * The command must be of the form \"{variable} = [{expression}]\", where expression may contain constants,\n * operators, registers, symbols, other variables, or nothing at all; in the latter case, the variable, if\n * any, is deleted.\n *\n * Other supported shorthand: \"var\" with no parameters prints the values of all variables, and \"var {variable}\"\n * prints the value of the specified variable.\n *\n * @this {Debugger8080}\n * @param {string} sCmd\n * @return {boolean} true if valid \"var\" assignment, false if not\n */\n doVar(sCmd)\n {\n var a = sCmd.match(/^\\s*([A-Z_]?[A-Z0-9_]*)\\s*(=?)\\s*(.*)$/i);\n if (a) {\n if (!a[1]) {\n if (!this.printVariable()) this.println(\"no variables\");\n return true; // it's not considered an error to print an empty list of variables\n }\n if (!a[2]) {\n return this.printVariable(a[1]);\n }\n if (!a[3]) {\n this.delVariable(a[1]);\n return true; // it's not considered an error to delete a variable that didn't exist\n }\n var v = this.parseExpression(a[3]);\n if (v !== undefined) {\n this.setVariable(a[1], v);\n return true;\n }\n return false;\n }\n this.println(\"invalid assignment:\" + sCmd);\n return false;\n }\n\n /**\n * doList(sAddr, fPrint)\n *\n * @this {Debugger8080}\n * @param {string} sAddr\n * @param {boolean} [fPrint]\n * @return {string|null}\n */\n doList(sAddr, fPrint)\n {\n var sSymbol = null;\n\n var dbgAddr = this.parseAddr(sAddr, true);\n if (dbgAddr) {\n var addr = this.getAddr(dbgAddr);\n var aSymbol = this.findSymbol(dbgAddr, true);\n if (aSymbol.length) {\n var nDelta, sDelta, s;\n if (aSymbol[0]) {\n sDelta = \"\";\n nDelta = dbgAddr.addr - aSymbol[1];\n if (nDelta) sDelta = \" + \" + Str.toHexWord(nDelta);\n s = aSymbol[0] + \" (\" + this.toHexOffset(aSymbol[1]) + ')' + sDelta;\n if (fPrint) this.println(s);\n sSymbol = s;\n }\n if (aSymbol.length > 4 && aSymbol[4]) {\n sDelta = \"\";\n nDelta = aSymbol[5] - dbgAddr.addr;\n if (nDelta) sDelta = \" - \" + Str.toHexWord(nDelta);\n s = aSymbol[4] + \" (\" + this.toHexOffset(aSymbol[5]) + ')' + sDelta;\n if (fPrint) this.println(s);\n if (!sSymbol) sSymbol = s;\n }\n } else {\n if (fPrint) this.println(\"no symbols\");\n }\n }\n return sSymbol;\n }\n\n /**\n * doMessages(asArgs)\n *\n * @this {Debugger8080}\n * @param {Array.<string>} asArgs\n */\n doMessages(asArgs)\n {\n var m;\n var fCriteria = null;\n var sCategory = asArgs[1];\n if (sCategory == '?') sCategory = undefined;\n\n if (sCategory !== undefined) {\n var bitsMessage = 0;\n if (sCategory == \"all\") {\n bitsMessage = (0xffffffff|0) & ~(Messages8080.HALT | Messages8080.KEYS | Messages8080.BUFFER);\n sCategory = null;\n } else if (sCategory == \"on\") {\n fCriteria = true;\n sCategory = null;\n } else if (sCategory == \"off\") {\n fCriteria = false;\n sCategory = null;\n } else {\n /*\n * Internally, we use \"key\" instead of \"keys\", since the latter is a method on JavasScript objects,\n * but externally, we allow the user to specify \"keys\"; \"kbd\" is also allowed as shorthand for \"keyboard\".\n */\n if (sCategory == \"keys\") sCategory = \"key\";\n if (sCategory == \"kbd\") sCategory = \"keyboard\";\n for (m in Messages8080.CATEGORIES) {\n if (sCategory == m) {\n bitsMessage = Messages8080.CATEGORIES[m];\n fCriteria = !!(this.bitsMessage & bitsMessage);\n break;\n }\n }\n if (!bitsMessage) {\n this.println(\"unknown message category: \" + sCategory);\n return;\n }\n }\n if (bitsMessage) {\n if (asArgs[2] == \"on\") {\n this.bitsMessage |= bitsMessage;\n fCriteria = true;\n }\n else if (asArgs[2] == \"off\") {\n this.bitsMessage &= ~bitsMessage;\n fCriteria = false;\n if (bitsMessage == Messages8080.BUFFER) {\n for (var i = 0; i < this.aMessageBuffer.length; i++) {\n this.println(this.aMessageBuffer[i]);\n }\n this.aMessageBuffer = [];\n }\n }\n }\n }\n\n /*\n * Display those message categories that match the current criteria (on or off)\n */\n var n = 0;\n var sCategories = \"\";\n for (m in Messages8080.CATEGORIES) {\n if (!sCategory || sCategory == m) {\n var bitMessage = Messages8080.CATEGORIES[m];\n var fEnabled = !!(this.bitsMessage & bitMessage);\n if (fCriteria !== null && fCriteria != fEnabled) continue;\n if (sCategories) sCategories += ',';\n if (!(++n % 10)) sCategories += \"\\n\\t\"; // jshint ignore:line\n /*\n * Internally, we use \"key\" instead of \"keys\", since the latter is a method on JavasScript objects,\n * but externally, we allow the user to specify \"keys\".\n */\n if (m == \"key\") m = \"keys\";\n sCategories += m;\n }\n }\n\n if (sCategory === undefined) {\n this.println(\"message commands:\\n\\tm [category] [on|off]\\tturn categories on/off\");\n }\n\n this.println((fCriteria !== null? (fCriteria? \"messages on: \" : \"messages off: \") : \"message categories:\\n\\t\") + (sCategories || \"none\"));\n\n this.historyInit(); // call this just in case Messages8080.INT was turned on\n }\n\n /**\n * doOptions(asArgs)\n *\n * @this {Debugger8080}\n * @param {Array.<string>} asArgs\n */\n doOptions(asArgs)\n {\n switch (asArgs[1]) {\n case \"8080\":\n this.style = Debugger8080.STYLE_8080;\n break;\n\n case \"8086\":\n this.style = Debugger8080.STYLE_8086;\n break;\n\n case \"cs\":\n var nCycles;\n if (asArgs[3] !== undefined) nCycles = +asArgs[3]; // warning: decimal instead of hex conversion\n switch (asArgs[2]) {\n case \"int\":\n this.cpu.nCyclesChecksumInterval = nCycles;\n break;\n case \"start\":\n this.cpu.nCyclesChecksumStart = nCycles;\n break;\n case \"stop\":\n this.cpu.nCyclesChecksumStop = nCycles;\n break;\n default:\n this.println(\"unknown cs option\");\n return;\n }\n if (nCycles !== undefined) {\n this.cpu.resetChecksum();\n }\n this.println(\"checksums \" + (this.cpu.flags.checksum? \"enabled\" : \"disabled\"));\n return;\n\n case \"sp\":\n if (asArgs[2] !== undefined) {\n if (!this.cpu.setSpeed(+asArgs[2])) {\n this.println(\"warning: using 1x multiplier, previous target not reached\");\n }\n }\n this.println(\"target speed: \" + this.cpu.getSpeedTarget() + \" (\" + this.cpu.getSpeed() + \"x)\");\n return;\n\n case \"?\":\n this.println(\"debugger options:\");\n this.println(\"\\t8080\\t\\tselect 8080-style mnemonics\");\n this.println(\"\\t8086\\t\\tselect 8086-style mnemonics\");\n this.println(\"\\tcs int #\\tset checksum cycle interval to #\");\n this.println(\"\\tcs start #\\tset checksum cycle start count to #\");\n this.println(\"\\tcs stop #\\tset checksum cycle stop count to #\");\n this.println(\"\\tsp #\\t\\tset speed multiplier to #\");\n break;\n\n default:\n if (asArgs[1]) {\n this.println(\"unknown option: \" + asArgs[1]);\n return;\n }\n break;\n }\n this.println(this.style + \"-style mnemonics enabled\");\n }\n\n /**\n * doOutput(sPort, sByte)\n *\n * Simulate a 1-byte port output operation.\n *\n * @this {Debugger8080}\n * @param {string|undefined} sPort\n * @param {string|undefined} sByte (string representation of 1 byte)\n */\n doOutput(sPort, sByte)\n {\n if (!sPort || sPort == '?') {\n this.println(\"output commands:\");\n this.println(\"\\to [p] [b]\\twrite byte [b] to port [p]\");\n /*\n * TODO: Regarding this warning, consider adding an \"unchecked\" version of\n * bus.checkPortOutputNotify(), since all Debugger memory accesses are unchecked, too.\n *\n * All port I/O handlers ARE aware when the Debugger is calling (addrFrom is undefined),\n * but changing them all to be non-destructive would take time, and situations where you\n * actually want to affect the hardware state are just as likely as not....\n */\n this.println(\"warning: port accesses can affect hardware state\");\n return;\n }\n var port = this.parseValue(sPort, \"port #\");\n var bOut = this.parseValue(sByte);\n if (port !== undefined && bOut !== undefined) {\n this.bus.checkPortOutputNotify(port, 1, bOut);\n this.println(Str.toHexWord(port) + \": \" + Str.toHexByte(bOut));\n }\n }\n\n /**\n * doRegisters(asArgs, fInstruction)\n *\n * @this {Debugger8080}\n * @param {Array.<string>} [asArgs]\n * @param {boolean} [fInstruction] (true to include the current instruction; default is true)\n */\n doRegisters(asArgs, fInstruction)\n {\n if (asArgs && asArgs[1] == '?') {\n this.println(\"register commands:\");\n this.println(\"\\tr\\tdump registers\");\n this.println(\"\\trx [#]\\tset flag or register x to [#]\");\n return;\n }\n\n var cpu = this.cpu;\n if (fInstruction == null) fInstruction = true;\n\n if (asArgs != null && asArgs.length > 1) {\n var sReg = asArgs[1];\n var sValue = null;\n var i = sReg.indexOf('=');\n if (i > 0) {\n sValue = sReg.substr(i + 1);\n sReg = sReg.substr(0, i);\n }\n else if (asArgs.length > 2) {\n sValue = asArgs[2];\n }\n else {\n this.println(\"missing value for \" + asArgs[1]);\n return;\n }\n\n var w = this.parseExpression(sValue);\n if (w === undefined) return;\n\n var sRegMatch = sReg.toUpperCase();\n switch (sRegMatch) {\n case \"A\":\n cpu.regA = w & 0xff;\n break;\n case \"B\":\n cpu.regB = w & 0xff;\n break;\n case \"BC\":\n cpu.regB = ((w >> 8) & 0xff);\n /* falls through */\n case \"C\":\n cpu.regC = w & 0xff;\n break;\n case \"D\":\n cpu.regD = w & 0xff;\n break;\n case \"DE\":\n cpu.regD = ((w >> 8) & 0xff);\n /* falls through */\n case \"E\":\n cpu.regE = w & 0xff;\n break;\n case \"H\":\n cpu.regH = w & 0xff;\n break;\n case \"HL\":\n cpu.regH = ((w >> 8) & 0xff);\n /* falls through */\n case \"L\":\n cpu.regL = w & 0xff;\n break;\n case \"SP\":\n cpu.setSP(w);\n break;\n case \"PC\":\n cpu.setPC(w);\n this.dbgAddrNextCode = this.newAddr(cpu.getPC());\n break;\n case \"PS\":\n cpu.setPS(w);\n break;\n case \"PSW\":\n cpu.setPSW(w);\n break;\n case \"CF\":\n if (w) cpu.setCF(); else cpu.clearCF();\n break;\n case \"PF\":\n if (w) cpu.setPF(); else cpu.clearPF();\n break;\n case \"AF\":\n if (w) cpu.setAF(); else cpu.clearAF();\n break;\n case \"ZF\":\n if (w) cpu.setZF(); else cpu.clearZF();\n break;\n case \"SF\":\n if (w) cpu.setSF(); else cpu.clearSF();\n break;\n case \"IF\":\n if (w) cpu.setIF(); else cpu.clearIF();\n break;\n default:\n this.println(\"unknown register: \" + sReg);\n return;\n }\n cpu.updateCPU();\n this.println(\"updated registers:\");\n }\n\n this.println(this.getRegDump());\n\n if (fInstruction) {\n this.dbgAddrNextCode = this.newAddr(cpu.getPC());\n this.doUnassemble(this.toHexAddr(this.dbgAddrNextCode));\n }\n }\n\n /**\n * doRun(sCmd, sAddr, sOptions, fQuiet)\n *\n * @this {Debugger8080}\n * @param {string} sCmd\n * @param {string|undefined} [sAddr]\n * @param {string} [sOptions] (the rest of the breakpoint command-line)\n * @param {boolean} [fQuiet]\n */\n doRun(sCmd, sAddr, sOptions, fQuiet)\n {\n if (sCmd == \"gt\") {\n this.fIgnoreNextCheckFault = true;\n }\n if (sAddr !== undefined) {\n var dbgAddr = this.parseAddr(sAddr, true);\n if (!dbgAddr) return;\n this.parseAddrOptions(dbgAddr, sOptions);\n this.setTempBreakpoint(dbgAddr);\n }\n if (!this.runCPU(true)) {\n if (!fQuiet) this.println(\"cpu busy or unavailable, run command ignored\");\n }\n }\n\n /**\n * doPrint(sCmd)\n *\n * NOTE: If the string to print is a quoted string, then we run it through replaceRegs(), so that\n * you can take advantage of all the special replacement options used for software interrupt logging.\n *\n * @this {Debugger8080}\n * @param {string} sCmd\n */\n doPrint(sCmd)\n {\n sCmd = Str.trim(sCmd);\n var a = sCmd.match(/^(['\"])(.*?)\\1$/);\n if (!a) {\n this.parseExpression(sCmd, false);\n } else {\n this.println(this.replaceRegs(a[2]));\n }\n }\n\n /**\n * doStep(sCmd)\n *\n * @this {Debugger8080}\n * @param {string} [sCmd] \"p\" or \"pr\"\n */\n doStep(sCmd)\n {\n var fCallStep = true;\n var fRegs = (sCmd == \"pr\"? 1 : 0);\n /*\n * Set up the value for this.nStep (ie, 1 or 2) depending on whether the user wants\n * a subsequent register dump (\"pr\") or not (\"p\").\n */\n var nStep = 1 + fRegs;\n if (!this.nStep) {\n var dbgAddr = this.newAddr(this.cpu.getPC());\n var bOpcode = this.getByte(dbgAddr);\n\n switch (bOpcode) {\n case CPUDef8080.OPCODE.CALL:\n if (fCallStep) {\n this.nStep = nStep;\n this.incAddr(dbgAddr, 3);\n }\n break;\n default:\n break;\n }\n\n if (this.nStep) {\n this.setTempBreakpoint(dbgAddr);\n if (!this.runCPU()) {\n if (this.cmp) this.cmp.updateFocus();\n this.nStep = 0;\n }\n /*\n * A successful run will ultimately call stop(), which will in turn call clearTempBreakpoint(),\n * which will clear nStep, so there's your assurance that nStep will be reset. Now we may have\n * stopped for reasons unrelated to the temporary breakpoint, but that's OK.\n */\n } else {\n this.doTrace(fRegs? \"tr\" : \"t\");\n }\n } else {\n this.println(\"step in progress\");\n }\n }\n\n /**\n * getCall(dbgAddr)\n *\n * Given a possible return address (typically from the stack), look for a matching CALL (or INT) that\n * immediately precedes that address.\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @return {string|null} CALL instruction at or near dbgAddr, or null if none\n */\n getCall(dbgAddr)\n {\n var sCall = null;\n var addr = dbgAddr.addr;\n var addrOrig = addr;\n for (var n = 1; n <= 6 && !!addr; n++) {\n if (n > 2) {\n dbgAddr.addr = addr;\n var s = this.getInstruction(dbgAddr);\n if (s.indexOf(\"CALL\") >= 0) {\n /*\n * Verify that the length of this CALL (or INT), when added to the address of the CALL (or INT),\n * matches the original return address. We do this by getting the string index of the opcode bytes,\n * subtracting that from the string index of the next space, and dividing that difference by two,\n * to yield the length of the CALL (or INT) instruction, in bytes.\n */\n var i = s.indexOf(' ');\n var j = s.indexOf(' ', i+1);\n if (addr + (j - i - 1)/2 == addrOrig) {\n sCall = s;\n break;\n }\n }\n }\n addr--;\n }\n dbgAddr.addr = addrOrig;\n return sCall;\n }\n\n /**\n * doStackTrace(sCmd, sAddr)\n *\n * Use \"k\" for a normal stack trace and \"ks\" for a stack trace with symbolic info.\n *\n * @this {Debugger8080}\n * @param {string} [sCmd]\n * @param {string} [sAddr] (not used yet)\n */\n doStackTrace(sCmd, sAddr)\n {\n if (sAddr == '?') {\n this.println(\"stack trace commands:\");\n this.println(\"\\tk\\tshow frame addresses\");\n this.println(\"\\tks\\tshow symbol information\");\n return;\n }\n\n var nFrames = 10, cFrames = 0;\n var dbgAddrCall = this.newAddr();\n var dbgAddrStack = this.newAddr(this.cpu.getSP());\n this.println(\"stack trace for \" + this.toHexAddr(dbgAddrStack));\n\n while (cFrames < nFrames) {\n var sCall = null, sCallPrev = null, cTests = 256;\n while ((dbgAddrStack.addr >>> 0) < 0x10000) {\n dbgAddrCall.addr = this.getWord(dbgAddrStack, true);\n /*\n * Because we're using the auto-increment feature of getWord(), and because that will automatically\n * wrap the offset around the end of the segment, we must also check the addr property to detect the wrap.\n */\n if (dbgAddrStack.addr == null || !cTests--) break;\n sCall = this.getCall(dbgAddrCall);\n if (sCall) break;\n }\n /*\n * The sCallPrev check eliminates duplicate sequential calls, which are usually (but not always)\n * indicative of a false positive, in which case the previous call is probably bogus as well, but\n * at least we won't duplicate that mistake. Of course, there are always exceptions, recursion\n * being one of them, but it's rare that we're debugging recursive code.\n */\n if (!sCall || sCall == sCallPrev) break;\n var sSymbol = null;\n if (sCmd == \"ks\") {\n var a = sCall.match(/[0-9A-F]+$/);\n if (a) sSymbol = this.doList(a[0]);\n }\n sCall = Str.pad(sCall, 50) + \" ;\" + (sSymbol || \"stack=\" + this.toHexAddr(dbgAddrStack)); // + \" return=\" + this.toHexAddr(dbgAddrCall));\n this.println(sCall);\n sCallPrev = sCall;\n cFrames++;\n }\n if (!cFrames) this.println(\"no return addresses found\");\n }\n\n /**\n * doTrace(sCmd, sCount)\n *\n * The \"t\" and \"tr\" commands interpret the count as a number of instructions, and since\n * we call the Debugger's stepCPU() for each iteration, a single instruction includes\n * any/all prefixes; the CPU's stepCPU() treats prefixes as discrete operations. The only\n * difference between \"t\" and \"tr\": the former displays only the next instruction, while\n * the latter also displays the (updated) registers.\n *\n * The \"tc\" command interprets the count as a number of cycles rather than instructions,\n * allowing you to quickly execute large chunks of instructions with a single command; it\n * doesn't display anything until the the chunk has finished.\n *\n * However, generally a more useful command is \"bn\", which allows you to break after some\n * number of instructions have been executed (as opposed to some number of cycles).\n *\n * @this {Debugger8080}\n * @param {string} [sCmd] (\"t\", \"tc\", or \"tr\")\n * @param {string} [sCount] # of instructions to step\n */\n doTrace(sCmd, sCount)\n {\n var dbg = this;\n var fRegs = (sCmd != \"t\");\n var nCount = this.parseValue(sCount, null, true) || 1;\n var nCycles = (nCount == 1? 0 : 1);\n if (sCmd == \"tc\") {\n nCycles = nCount;\n nCount = 1;\n }\n Web.onCountRepeat(\n nCount,\n function onCountStep() {\n return dbg.setBusy(true) && dbg.stepCPU(nCycles, fRegs, false);\n },\n function onCountStepComplete() {\n /*\n * We explicitly called stepCPU() with fUpdateCPU === false, because repeatedly\n * calling updateCPU() can be very slow, especially when fDisplayLiveRegs is true,\n * so once the repeat count has been exhausted, we must perform a final updateCPU().\n */\n dbg.cpu.updateCPU();\n dbg.setBusy(false);\n }\n );\n }\n\n /**\n * doUnassemble(sAddr, sAddrEnd, n)\n *\n * @this {Debugger8080}\n * @param {string} [sAddr]\n * @param {string} [sAddrEnd]\n * @param {number} [n]\n */\n doUnassemble(sAddr, sAddrEnd, n)\n {\n var dbgAddr = this.parseAddr(sAddr, true);\n if (!dbgAddr) return;\n\n if (n === undefined) n = 1;\n\n var cb = 0x100;\n if (sAddrEnd !== undefined) {\n\n var dbgAddrEnd = this.parseAddr(sAddrEnd, true);\n if (!dbgAddrEnd || dbgAddrEnd.addr < dbgAddr.addr) return;\n\n cb = dbgAddrEnd.addr - dbgAddr.addr;\n if (!DEBUG && cb > 0x100) {\n /*\n * Limiting the amount of disassembled code to 256 bytes in non-DEBUG builds is partly to\n * prevent the user from wedging the browser by dumping too many lines, but also a recognition\n * that, in non-DEBUG builds, this.println() keeps print output buffer truncated to 8Kb anyway.\n */\n this.println(\"range too large\");\n return;\n }\n n = -1;\n }\n\n var cLines = 0;\n var sInstruction;\n\n while (cb > 0 && n--) {\n\n var nSequence = (this.isBusy(false) || this.nStep)? this.nCycles : null;\n var sComment = (nSequence != null? \"cycles\" : null);\n var aSymbol = this.findSymbol(dbgAddr);\n\n var addr = dbgAddr.addr; // we snap dbgAddr.addr *after* calling findSymbol(), which re-evaluates it\n\n if (aSymbol[0] && n) {\n if (!cLines && n || aSymbol[0].indexOf('+') < 0) {\n var sLabel = aSymbol[0] + ':';\n if (aSymbol[2]) sLabel += ' ' + aSymbol[2];\n this.println(sLabel);\n }\n }\n\n if (aSymbol[3]) {\n sComment = aSymbol[3];\n nSequence = null;\n }\n\n sInstruction = this.getInstruction(dbgAddr, sComment, nSequence);\n\n this.println(sInstruction);\n this.dbgAddrNextCode = dbgAddr;\n cb -= dbgAddr.addr - addr;\n cLines++;\n }\n }\n\n /**\n * parseCommand(sCmd, fSave, chSep)\n *\n * @this {Debugger8080}\n * @param {string|undefined} sCmd\n * @param {boolean} [fSave] is true to save the command, false if not\n * @param {string} [chSep] is the command separator character (default is ';')\n * @return {Array.<string>}\n */\n parseCommand(sCmd, fSave, chSep)\n {\n if (fSave) {\n if (!sCmd) {\n if (this.fAssemble) {\n sCmd = \"end\";\n } else {\n sCmd = this.aPrevCmds[this.iPrevCmd+1];\n }\n } else {\n if (this.iPrevCmd < 0 && this.aPrevCmds.length) {\n this.iPrevCmd = 0;\n }\n if (this.iPrevCmd < 0 || sCmd != this.aPrevCmds[this.iPrevCmd]) {\n this.aPrevCmds.splice(0, 0, sCmd);\n this.iPrevCmd = 0;\n }\n this.iPrevCmd--;\n }\n }\n var a = [];\n if (sCmd) {\n /*\n * With the introduction of breakpoint commands (ie, quoted command sequences\n * associated with a breakpoint), we can no longer perform simplistic splitting.\n *\n * a = sCmd.split(chSep || ';');\n * for (var i = 0; i < a.length; i++) a[i] = str.trim(a[i]);\n *\n * We may now split on semi-colons ONLY if they are outside a quoted sequence.\n *\n * Also, to allow quoted strings *inside* breakpoint commands, we first replace all\n * DOUBLE double-quotes with single quotes.\n */\n sCmd = sCmd.toLowerCase().replace(/\"\"/g, \"'\");\n\n var iPrev = 0;\n var chQuote = null;\n chSep = chSep || ';';\n /*\n * NOTE: Processing charAt() up to and INCLUDING length is not a typo; we're taking\n * advantage of the fact that charAt() with an invalid index returns an empty string,\n * allowing us to use the same substring() call to capture the final portion of sCmd.\n *\n * In a sense, it allows us to pretend that the string ends with a zero terminator.\n */\n for (var i = 0; i <= sCmd.length; i++) {\n var ch = sCmd.charAt(i);\n if (ch == '\"' || ch == \"'\") {\n if (!chQuote) {\n chQuote = ch;\n } else if (ch == chQuote) {\n chQuote = null;\n }\n }\n else if (ch == chSep && !chQuote || !ch) {\n /*\n * Recall that substring() accepts starting (inclusive) and ending (exclusive)\n * indexes, whereas substr() accepts a starting index and a length. We need the former.\n */\n a.push(Str.trim(sCmd.substring(iPrev, i)));\n iPrev = i + 1;\n }\n }\n }\n return a;\n }\n\n /**\n * shiftArgs(asArgs)\n *\n * Used with any command (eg, \"r\") that allows but doesn't require whitespace between command and first argument.\n *\n * @this {Debugger8080}\n * @param {Array.<string>} asArgs\n * @return {Array.<string>}\n */\n shiftArgs(asArgs)\n {\n if (asArgs && asArgs.length) {\n var s0 = asArgs[0];\n var ch0 = s0.charAt(0);\n for (var i = 1; i < s0.length; i++) {\n var ch = s0.charAt(i);\n if (ch0 == '?' || ch0 == 'r' || ch < 'a' || ch > 'z') {\n asArgs[0] = s0.substr(i);\n asArgs.unshift(s0.substr(0, i));\n break;\n }\n }\n }\n return asArgs;\n }\n\n /**\n * doCommand(sCmd, fQuiet)\n *\n * @this {Debugger8080}\n * @param {string} sCmd\n * @param {boolean} [fQuiet]\n * @return {boolean} true if command processed, false if unrecognized\n */\n doCommand(sCmd, fQuiet)\n {\n var result = true;\n\n try {\n if (!sCmd.length || sCmd == \"end\") {\n if (this.fAssemble) {\n this.println(\"ended assemble at \" + this.toHexAddr(this.dbgAddrAssemble));\n this.dbgAddrNextCode = this.dbgAddrAssemble;\n this.fAssemble = false;\n }\n sCmd = \"\";\n }\n else if (!fQuiet) {\n var sPrompt = \">> \";\n this.println(sPrompt + sCmd);\n }\n\n var ch = sCmd.charAt(0);\n if (ch == '\"' || ch == \"'\") return true;\n\n /*\n * Zap the previous message buffer to ensure the new command's output is not tossed out as a repeat.\n */\n this.sMessagePrev = null;\n\n /*\n * I've relaxed the !isBusy() requirement, to maximize our ability to issue Debugger commands externally.\n */\n if (this.isReady() /* && !this.isBusy(true) */ && sCmd.length > 0) {\n\n if (this.fAssemble) {\n sCmd = \"a \" + this.toHexAddr(this.dbgAddrAssemble) + ' ' + sCmd;\n }\n\n var asArgs = this.shiftArgs(sCmd.replace(/ +/g, ' ').split(' '));\n\n switch (asArgs[0].charAt(0)) {\n case 'a':\n this.doAssemble(asArgs);\n break;\n case 'b':\n this.doBreak(asArgs[0], asArgs[1], sCmd);\n break;\n case 'c':\n this.doClear(asArgs[0]);\n break;\n case 'd':\n if (!COMPILED && sCmd == \"debug\") {\n window.DEBUG = true;\n this.println(\"DEBUG checks on\");\n break;\n }\n this.doDump(asArgs);\n break;\n case 'e':\n if (asArgs[0] == \"else\") break;\n this.doEdit(asArgs);\n break;\n case 'f':\n this.doFreqs(asArgs[1]);\n break;\n case 'g':\n this.doRun(asArgs[0], asArgs[1], sCmd, fQuiet);\n break;\n case 'h':\n this.doHalt(fQuiet);\n break;\n case 'i':\n if (asArgs[0] == \"if\") {\n if (!this.doIf(sCmd.substr(2), fQuiet)) {\n result = false;\n }\n break;\n }\n if (asArgs[0] == \"int\") {\n if (!this.doInt(asArgs[1])) {\n result = false;\n }\n break;\n }\n this.doInput(asArgs[1]);\n break;\n case 'k':\n this.doStackTrace(asArgs[0], asArgs[1]);\n break;\n case 'l':\n if (asArgs[0] == \"ln\") {\n this.doList(asArgs[1], true);\n break;\n }\n break;\n case 'm':\n this.doMessages(asArgs);\n break;\n case 'o':\n this.doOutput(asArgs[1], asArgs[2]);\n break;\n case 'p':\n if (asArgs[0] == \"print\") {\n this.doPrint(sCmd.substr(5));\n break;\n }\n this.doStep(asArgs[0]);\n break;\n case 'r':\n if (sCmd == \"reset\") {\n if (this.cmp) this.cmp.reset();\n break;\n }\n this.doRegisters(asArgs);\n break;\n case 's':\n this.doOptions(asArgs);\n break;\n case 't':\n this.doTrace(asArgs[0], asArgs[1]);\n break;\n case 'u':\n this.doUnassemble(asArgs[1], asArgs[2], 8);\n break;\n case 'v':\n if (asArgs[0] == \"var\") {\n if (!this.doVar(sCmd.substr(3))) {\n result = false;\n }\n break;\n }\n this.println((PC8080.APPNAME || \"PC8080\") + \" version \" + (XMLVERSION || PC8080.APPVERSION) + \" (\" + this.cpu.model + (PC8080.COMPILED? \",RELEASE\" : (PC8080.DEBUG? \",DEBUG\" : \",NODEBUG\")) + (PC8080.TYPEDARRAYS? \",TYPEDARRAYS\" : (PC8080.BYTEARRAYS? \",BYTEARRAYS\" : \",LONGARRAYS\")) + ')');\n this.println(Web.getUserAgent());\n break;\n case '?':\n if (asArgs[1]) {\n this.doPrint(sCmd.substr(1));\n break;\n }\n this.doHelp();\n break;\n case 'n':\n if (!COMPILED && sCmd == \"nodebug\") {\n window.DEBUG = false;\n this.println(\"DEBUG checks off\");\n break;\n }\n if (this.doInfo(asArgs)) break;\n /* falls through */\n default:\n this.println(\"unknown command: \" + sCmd);\n result = false;\n break;\n }\n }\n } catch(e) {\n this.println(\"debugger error: \" + (e.stack || e.message));\n result = false;\n }\n return result;\n }\n\n /**\n * doCommands(sCmds, fSave)\n *\n * @this {Debugger8080}\n * @param {string} sCmds\n * @param {boolean} [fSave]\n * @return {boolean} true if all commands processed, false if not\n */\n doCommands(sCmds, fSave)\n {\n var a = this.parseCommand(sCmds, fSave);\n for (var s in a) {\n if (!this.doCommand(a[+s])) return false;\n }\n return true;\n }\n\n /**\n * Debugger8080.init()\n *\n * This function operates on every HTML element of class \"debugger\", extracting the\n * JSON-encoded parameters for the Debugger constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Debugger component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeDbg = Component.getElementsByClass(document, PC8080.APPCLASS, \"debugger\");\n for (var iDbg = 0; iDbg < aeDbg.length; iDbg++) {\n var eDbg = aeDbg[iDbg];\n var parmsDbg = Component.getComponentParms(eDbg);\n var dbg = new Debugger8080(parmsDbg);\n Component.bindComponentControls(dbg, eDbg, PC8080.APPCLASS);\n }\n }\n}\n\nif (DEBUGGER) {\n\n /*\n * NOTE: Every Debugger8080 property from here to the first prototype function definition (initBus()) is\n * considered a \"class constant\"; most of them use our \"all-caps\" convention (and all of them SHOULD, but\n * that wouldn't help us catch any bugs).\n *\n * Technically, all of them should ALSO be preceded by a \"@const\" annotation, but that's a lot of work and it\n * really clutters the code. I wish the Closure Compiler had a way to annotate every definition with a given\n * section with a single annotation....\n *\n * Bugs can slip through the cracks without those annotations; for example, I unthinkingly redefined TYPE_SIZE\n * at one point, and if all the definitions had been preceded by an \"@const\", that mistake would have been\n * caught at compile-time.\n */\n\n Debugger8080.COMMANDS = {\n '?': \"help/print\",\n 'a [#]': \"assemble\", // TODO: Implement this command someday\n 'b [#]': \"breakpoint\", // multiple variations (use b? to list them)\n 'c': \"clear output\",\n 'd [#]': \"dump memory\", // additional syntax: d [#] [l#], where l# is a number of bytes to dump\n 'e [#]': \"edit memory\",\n 'f': \"frequencies\",\n 'g [#]': \"go [to #]\",\n 'h': \"halt\",\n 'i [#]': \"input port #\",\n 'if': \"eval expression\",\n 'int [#]': \"request interrupt\",\n 'k': \"stack trace\",\n \"ln\": \"list nearest symbol(s)\",\n 'm': \"messages\",\n 'o [#]': \"output port #\",\n 'p': \"step over\", // other variations: pr (step and dump registers)\n 'print': \"print expression\",\n 'r': \"dump/set registers\",\n 'reset': \"reset machine\",\n 's': \"set options\",\n 't [#]': \"trace\", // other variations: tr (trace and dump registers)\n 'u [#]': \"unassemble\",\n 'v': \"print version\",\n 'var': \"assign variable\"\n };\n\n Debugger8080.STYLE_8080 = 8080;\n Debugger8080.STYLE_8086 = 8086;\n\n /*\n * CPU instruction ordinals\n */\n Debugger8080.INS = {\n NONE: 0, ACI: 1, ADC: 2, ADD: 3, ADI: 4, ANA: 5, ANI: 6, CALL: 7,\n CC: 8, CM: 9, CNC: 10, CNZ: 11, CP: 12, CPE: 13, CPO: 14, CZ: 15,\n CMA: 16, CMC: 17, CMP: 18, CPI: 19, DAA: 20, DAD: 21, DCR: 22, DCX: 23,\n DI: 24, EI: 25, HLT: 26, IN: 27, INR: 28, INX: 29, JMP: 30, JC: 31,\n JM: 32, JNC: 33, JNZ: 34, JP: 35, JPE: 36, JPO: 37, JZ: 38, LDA: 39,\n LDAX: 40, LHLD: 41, LXI: 42, MOV: 43, MVI: 44, NOP: 45, ORA: 46, ORI: 47,\n OUT: 48, PCHL: 49, POP: 50, PUSH: 51, RAL: 52, RAR: 53, RET: 54, RC: 55,\n RM: 56, RNC: 57, RNZ: 58, RP: 59, RPE: 60, RPO: 61, RZ: 62, RLC: 63,\n RRC: 64, RST: 65, SBB: 66, SBI: 67, SHLD: 68, SPHL: 69, STA: 70, STAX: 71,\n STC: 72, SUB: 73, SUI: 74, XCHG: 75, XRA: 76, XRI: 77, XTHL: 78\n };\n\n /*\n * CPU instruction names (mnemonics), indexed by CPU instruction ordinal (above)\n *\n * If you change the default style, using the \"s\" command (eg, \"s 8086\"), then the 8086 table\n * will be used instead. TODO: Add a \"s z80\" command for Z80-style mnemonics.\n */\n Debugger8080.INS_NAMES = [\n \"NONE\", \"ACI\", \"ADC\", \"ADD\", \"ADI\", \"ANA\", \"ANI\", \"CALL\",\n \"CC\", \"CM\", \"CNC\", \"CNZ\", \"CP\", \"CPE\", \"CPO\", \"CZ\",\n \"CMA\", \"CMC\", \"CMP\", \"CPI\", \"DAA\", \"DAD\", \"DCR\", \"DCX\",\n \"DI\", \"EI\", \"HLT\", \"IN\", \"INR\", \"INX\", \"JMP\", \"JC\",\n \"JM\", \"JNC\", \"JNZ\", \"JP\", \"JPE\", \"JPO\", \"JZ\", \"LDA\",\n \"LDAX\", \"LHLD\", \"LXI\", \"MOV\", \"MVI\", \"NOP\", \"ORA\", \"ORI\",\n \"OUT\", \"PCHL\", \"POP\", \"PUSH\", \"RAL\", \"RAR\", \"RET\", \"RC\",\n \"RM\", \"RNC\", \"RNZ\", \"RP\", \"RPE\", \"RPO\", \"RZ\", \"RLC\",\n \"RRC\", \"RST\", \"SBB\", \"SBI\", \"SHLD\", \"SPHL\", \"STA\", \"STAX\",\n \"STC\", \"SUB\", \"SUI\", \"XCHG\", \"XRA\", \"XRI\", \"XTHL\"\n ];\n\n Debugger8080.INS_NAMES_8086 = [\n \"NONE\", \"ADC\", \"ADC\", \"ADD\", \"ADD\", \"AND\", \"AND\", \"CALL\",\n \"CALLC\", \"CALLS\", \"CALLNC\", \"CALLNZ\", \"CALLNS\", \"CALLP\", \"CALLNP\", \"CALLZ\",\n \"NOT\", \"CMC\", \"CMP\", \"CMP\", \"DAA\", \"ADD\", \"DEC\", \"DEC\",\n \"CLI\", \"STI\", \"HLT\", \"IN\", \"INC\", \"INC\", \"JMP\", \"JC\",\n \"JS\", \"JNC\", \"JNZ\", \"JNS\", \"JP\", \"JNP\", \"JZ\", \"MOV\",\n \"MOV\", \"MOV\", \"MOV\", \"MOV\", \"MOV\", \"NOP\", \"OR\", \"OR\",\n \"OUT\", \"JMP\", \"POP\", \"PUSH\", \"RCL\", \"RCR\", \"RET\", \"RETC\",\n \"RETS\", \"RETNC\", \"RETNZ\", \"RETNS\", \"RETP\", \"RETNP\", \"RETZ\", \"ROL\",\n \"ROR\", \"RST\", \"SBB\", \"SBB\", \"MOV\", \"MOV\", \"MOV\", \"MOV\",\n \"STC\", \"SUB\", \"SUB\", \"XCHG\", \"XOR\", \"XOR\", \"XCHG\"\n ];\n\n Debugger8080.REG_B = 0x00;\n Debugger8080.REG_C = 0x01;\n Debugger8080.REG_D = 0x02;\n Debugger8080.REG_E = 0x03;\n Debugger8080.REG_H = 0x04;\n Debugger8080.REG_L = 0x05;\n Debugger8080.REG_M = 0x06;\n Debugger8080.REG_A = 0x07;\n Debugger8080.REG_BC = 0x08;\n Debugger8080.REG_DE = 0x09;\n Debugger8080.REG_HL = 0x0A;\n Debugger8080.REG_SP = 0x0B;\n Debugger8080.REG_PC = 0x0C;\n Debugger8080.REG_PS = 0x0D;\n Debugger8080.REG_PSW = 0x0E; // aka AF if Z80-style mnemonics\n\n /*\n * NOTE: \"PS\" is the complete processor status, which includes bits like the Interrupt flag (IF),\n * which is NOT the same as \"PSW\", which is the low 8 bits of \"PS\" combined with \"A\" in the high byte.\n */\n Debugger8080.REGS = [\n \"B\", \"C\", \"D\", \"E\", \"H\", \"L\", \"M\", \"A\", \"BC\", \"DE\", \"HL\", \"SP\", \"PC\", \"PS\", \"PSW\"\n ];\n\n /*\n * Operand type descriptor masks and definitions\n */\n Debugger8080.TYPE_SIZE = 0x000F; // size field\n Debugger8080.TYPE_MODE = 0x00F0; // mode field\n Debugger8080.TYPE_IREG = 0x0F00; // implied register field\n Debugger8080.TYPE_OTHER = 0xF000; // \"other\" field\n\n /*\n * TYPE_SIZE values\n */\n Debugger8080.TYPE_NONE = 0x0000; // (all other TYPE fields ignored)\n Debugger8080.TYPE_BYTE = 0x0001; // byte, regardless of operand size\n Debugger8080.TYPE_SBYTE = 0x0002; // byte sign-extended to word\n Debugger8080.TYPE_WORD = 0x0003; // word (16-bit value)\n\n /*\n * TYPE_MODE values\n */\n Debugger8080.TYPE_REG = 0x0010; // register\n Debugger8080.TYPE_IMM = 0x0020; // immediate data\n Debugger8080.TYPE_ADDR = 0x0033; // immediate (word) address\n Debugger8080.TYPE_MEM = 0x0040; // memory reference\n Debugger8080.TYPE_INT = 0x0080; // interrupt level encoded in instruction (bits 3-5)\n\n /*\n * TYPE_IREG values, based on the REG_* constants.\n *\n * Note that TYPE_M isn't really a register, just an alternative form of TYPE_HL | TYPE_MEM.\n */\n Debugger8080.TYPE_A = (Debugger8080.REG_A << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_BYTE);\n Debugger8080.TYPE_B = (Debugger8080.REG_B << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_BYTE);\n Debugger8080.TYPE_C = (Debugger8080.REG_C << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_BYTE);\n Debugger8080.TYPE_D = (Debugger8080.REG_D << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_BYTE);\n Debugger8080.TYPE_E = (Debugger8080.REG_E << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_BYTE);\n Debugger8080.TYPE_H = (Debugger8080.REG_H << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_BYTE);\n Debugger8080.TYPE_L = (Debugger8080.REG_L << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_BYTE);\n Debugger8080.TYPE_M = (Debugger8080.REG_M << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_BYTE | Debugger8080.TYPE_MEM);\n Debugger8080.TYPE_BC = (Debugger8080.REG_BC << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_WORD);\n Debugger8080.TYPE_DE = (Debugger8080.REG_DE << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_WORD);\n Debugger8080.TYPE_HL = (Debugger8080.REG_HL << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_WORD);\n Debugger8080.TYPE_SP = (Debugger8080.REG_SP << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_WORD);\n Debugger8080.TYPE_PC = (Debugger8080.REG_PC << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_WORD);\n Debugger8080.TYPE_PSW = (Debugger8080.REG_PSW<< 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_WORD);\n\n /*\n * TYPE_OTHER bit definitions\n */\n Debugger8080.TYPE_IN = 0x1000; // operand is input\n Debugger8080.TYPE_OUT = 0x2000; // operand is output\n Debugger8080.TYPE_BOTH = (Debugger8080.TYPE_IN | Debugger8080.TYPE_OUT);\n Debugger8080.TYPE_OPT = 0x4000; // optional operand (ie, normally omitted in 8080 assembly language)\n Debugger8080.TYPE_UNDOC = 0x8000; // opcode is an undocumented alternative encoding\n\n /*\n * The aaOpDescs array is indexed by opcode, and each element is a sub-array (aOpDesc) that describes\n * the corresponding opcode. The sub-elements are as follows:\n *\n * [0]: {number} of the opcode name (see INS.*)\n * [1]: {number} containing the destination operand descriptor bit(s), if any\n * [2]: {number} containing the source operand descriptor bit(s), if any\n * [3]: {number} containing the occasional third operand descriptor bit(s), if any\n *\n * These sub-elements are all optional. If [0] is not present, the opcode is undefined; if [1] is not\n * present (or contains zero), the opcode has no (or only implied) operands; if [2] is not present, the\n * opcode has only a single operand. And so on.\n *\n * Additional default rules:\n *\n * 1) If no TYPE_OTHER bits are specified for the first (destination) operand, TYPE_OUT is assumed;\n * 2) If no TYPE_OTHER bits are specified for the second (source) operand, TYPE_IN is assumed;\n * 3) If no size is specified for the second operand, the size is assumed to match the first operand.\n */\n Debugger8080.aaOpDescs = [\n /* 0x00 */ [Debugger8080.INS.NOP],\n /* 0x01 */ [Debugger8080.INS.LXI, Debugger8080.TYPE_BC, Debugger8080.TYPE_IMM],\n /* 0x02 */ [Debugger8080.INS.STAX, Debugger8080.TYPE_BC | Debugger8080.TYPE_MEM, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT],\n /* 0x03 */ [Debugger8080.INS.INX, Debugger8080.TYPE_BC],\n /* 0x04 */ [Debugger8080.INS.INR, Debugger8080.TYPE_B],\n /* 0x05 */ [Debugger8080.INS.DCR, Debugger8080.TYPE_B],\n /* 0x06 */ [Debugger8080.INS.MVI, Debugger8080.TYPE_B, Debugger8080.TYPE_IMM],\n /* 0x07 */ [Debugger8080.INS.RLC],\n /* 0x08 */ [Debugger8080.INS.NOP, Debugger8080.TYPE_UNDOC],\n /* 0x09 */ [Debugger8080.INS.DAD, Debugger8080.TYPE_HL | Debugger8080.TYPE_OPT, Debugger8080.TYPE_BC],\n /* 0x0A */ [Debugger8080.INS.LDAX, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_BC | Debugger8080.TYPE_MEM],\n /* 0x0B */ [Debugger8080.INS.DCX, Debugger8080.TYPE_BC],\n /* 0x0C */ [Debugger8080.INS.INR, Debugger8080.TYPE_C],\n /* 0x0D */ [Debugger8080.INS.DCR, Debugger8080.TYPE_C],\n /* 0x0E */ [Debugger8080.INS.MVI, Debugger8080.TYPE_C, Debugger8080.TYPE_IMM],\n /* 0x0F */ [Debugger8080.INS.RRC],\n /* 0x10 */ [Debugger8080.INS.NOP, Debugger8080.TYPE_UNDOC],\n /* 0x11 */ [Debugger8080.INS.LXI, Debugger8080.TYPE_DE, Debugger8080.TYPE_IMM],\n /* 0x12 */ [Debugger8080.INS.STAX, Debugger8080.TYPE_DE | Debugger8080.TYPE_MEM, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT],\n /* 0x13 */ [Debugger8080.INS.INX, Debugger8080.TYPE_DE],\n /* 0x14 */ [Debugger8080.INS.INR, Debugger8080.TYPE_D],\n /* 0x15 */ [Debugger8080.INS.DCR, Debugger8080.TYPE_D],\n /* 0x16 */ [Debugger8080.INS.MVI, Debugger8080.TYPE_D, Debugger8080.TYPE_IMM],\n /* 0x17 */ [Debugger8080.INS.RAL],\n /* 0x18 */ [Debugger8080.INS.NOP, Debugger8080.TYPE_UNDOC],\n /* 0x19 */ [Debugger8080.INS.DAD, Debugger8080.TYPE_HL | Debugger8080.TYPE_OPT, Debugger8080.TYPE_DE],\n /* 0x1A */ [Debugger8080.INS.LDAX, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_DE | Debugger8080.TYPE_MEM],\n /* 0x1B */ [Debugger8080.INS.DCX, Debugger8080.TYPE_DE],\n /* 0x1C */ [Debugger8080.INS.INR, Debugger8080.TYPE_E],\n /* 0x1D */ [Debugger8080.INS.DCR, Debugger8080.TYPE_E],\n /* 0x1E */ [Debugger8080.INS.MVI, Debugger8080.TYPE_E, Debugger8080.TYPE_IMM],\n /* 0x1F */ [Debugger8080.INS.RAR],\n /* 0x20 */ [Debugger8080.INS.NOP, Debugger8080.TYPE_UNDOC],\n /* 0x21 */ [Debugger8080.INS.LXI, Debugger8080.TYPE_HL, Debugger8080.TYPE_IMM],\n /* 0x22 */ [Debugger8080.INS.SHLD, Debugger8080.TYPE_ADDR | Debugger8080.TYPE_MEM, Debugger8080.TYPE_HL | Debugger8080.TYPE_OPT],\n /* 0x23 */ [Debugger8080.INS.INX, Debugger8080.TYPE_HL],\n /* 0x24 */ [Debugger8080.INS.INR, Debugger8080.TYPE_H],\n /* 0x25 */ [Debugger8080.INS.DCR, Debugger8080.TYPE_H],\n /* 0x26 */ [Debugger8080.INS.MVI, Debugger8080.TYPE_H, Debugger8080.TYPE_IMM],\n /* 0x27 */ [Debugger8080.INS.DAA],\n /* 0x28 */ [Debugger8080.INS.NOP, Debugger8080.TYPE_UNDOC],\n /* 0x29 */ [Debugger8080.INS.DAD, Debugger8080.TYPE_HL | Debugger8080.TYPE_OPT, Debugger8080.TYPE_HL],\n /* 0x2A */ [Debugger8080.INS.LHLD, Debugger8080.TYPE_HL | Debugger8080.TYPE_OPT, Debugger8080.TYPE_ADDR | Debugger8080.TYPE_MEM],\n /* 0x2B */ [Debugger8080.INS.DCX, Debugger8080.TYPE_HL],\n /* 0x2C */ [Debugger8080.INS.INR, Debugger8080.TYPE_L],\n /* 0x2D */ [Debugger8080.INS.DCR, Debugger8080.TYPE_L],\n /* 0x2E */ [Debugger8080.INS.MVI, Debugger8080.TYPE_L, Debugger8080.TYPE_IMM],\n /* 0x2F */ [Debugger8080.INS.CMA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT],\n /* 0x30 */ [Debugger8080.INS.NOP, Debugger8080.TYPE_UNDOC],\n /* 0x31 */ [Debugger8080.INS.LXI, Debugger8080.TYPE_SP, Debugger8080.TYPE_IMM],\n /* 0x32 */ [Debugger8080.INS.STA, Debugger8080.TYPE_ADDR | Debugger8080.TYPE_MEM, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT],\n /* 0x33 */ [Debugger8080.INS.INX, Debugger8080.TYPE_SP],\n /* 0x34 */ [Debugger8080.INS.INR, Debugger8080.TYPE_M],\n /* 0x35 */ [Debugger8080.INS.DCR, Debugger8080.TYPE_M],\n /* 0x36 */ [Debugger8080.INS.MVI, Debugger8080.TYPE_M, Debugger8080.TYPE_IMM],\n /* 0x37 */ [Debugger8080.INS.STC],\n /* 0x38 */ [Debugger8080.INS.NOP, Debugger8080.TYPE_UNDOC],\n /* 0x39 */ [Debugger8080.INS.DAD, Debugger8080.TYPE_HL | Debugger8080.TYPE_OPT, Debugger8080.TYPE_SP],\n /* 0x3A */ [Debugger8080.INS.LDA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_ADDR | Debugger8080.TYPE_MEM],\n /* 0x3B */ [Debugger8080.INS.DCX, Debugger8080.TYPE_SP],\n /* 0x3C */ [Debugger8080.INS.INR, Debugger8080.TYPE_A],\n /* 0x3D */ [Debugger8080.INS.DCR, Debugger8080.TYPE_A],\n /* 0x3E */ [Debugger8080.INS.MVI, Debugger8080.TYPE_A, Debugger8080.TYPE_IMM],\n /* 0x3F */ [Debugger8080.INS.CMC],\n /* 0x40 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_B, Debugger8080.TYPE_B],\n /* 0x41 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_B, Debugger8080.TYPE_C],\n /* 0x42 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_B, Debugger8080.TYPE_D],\n /* 0x43 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_B, Debugger8080.TYPE_E],\n /* 0x44 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_B, Debugger8080.TYPE_H],\n /* 0x45 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_B, Debugger8080.TYPE_L],\n /* 0x46 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_B, Debugger8080.TYPE_M],\n /* 0x47 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_B, Debugger8080.TYPE_A],\n /* 0x48 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_C, Debugger8080.TYPE_B],\n /* 0x49 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_C, Debugger8080.TYPE_C],\n /* 0x4A */ [Debugger8080.INS.MOV, Debugger8080.TYPE_C, Debugger8080.TYPE_D],\n /* 0x4B */ [Debugger8080.INS.MOV, Debugger8080.TYPE_C, Debugger8080.TYPE_E],\n /* 0x4C */ [Debugger8080.INS.MOV, Debugger8080.TYPE_C, Debugger8080.TYPE_H],\n /* 0x4D */ [Debugger8080.INS.MOV, Debugger8080.TYPE_C, Debugger8080.TYPE_L],\n /* 0x4E */ [Debugger8080.INS.MOV, Debugger8080.TYPE_C, Debugger8080.TYPE_M],\n /* 0x4F */ [Debugger8080.INS.MOV, Debugger8080.TYPE_C, Debugger8080.TYPE_A],\n /* 0x50 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_D, Debugger8080.TYPE_B],\n /* 0x51 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_D, Debugger8080.TYPE_C],\n /* 0x52 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_D, Debugger8080.TYPE_D],\n /* 0x53 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_D, Debugger8080.TYPE_E],\n /* 0x54 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_D, Debugger8080.TYPE_H],\n /* 0x55 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_D, Debugger8080.TYPE_L],\n /* 0x56 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_D, Debugger8080.TYPE_M],\n /* 0x57 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_D, Debugger8080.TYPE_A],\n /* 0x58 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_E, Debugger8080.TYPE_B],\n /* 0x59 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_E, Debugger8080.TYPE_C],\n /* 0x5A */ [Debugger8080.INS.MOV, Debugger8080.TYPE_E, Debugger8080.TYPE_D],\n /* 0x5B */ [Debugger8080.INS.MOV, Debugger8080.TYPE_E, Debugger8080.TYPE_E],\n /* 0x5C */ [Debugger8080.INS.MOV, Debugger8080.TYPE_E, Debugger8080.TYPE_H],\n /* 0x5D */ [Debugger8080.INS.MOV, Debugger8080.TYPE_E, Debugger8080.TYPE_L],\n /* 0x5E */ [Debugger8080.INS.MOV, Debugger8080.TYPE_E, Debugger8080.TYPE_M],\n /* 0x5F */ [Debugger8080.INS.MOV, Debugger8080.TYPE_E, Debugger8080.TYPE_A],\n /* 0x60 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_H, Debugger8080.TYPE_B],\n /* 0x61 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_H, Debugger8080.TYPE_C],\n /* 0x62 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_H, Debugger8080.TYPE_D],\n /* 0x63 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_H, Debugger8080.TYPE_E],\n /* 0x64 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_H, Debugger8080.TYPE_H],\n /* 0x65 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_H, Debugger8080.TYPE_L],\n /* 0x66 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_H, Debugger8080.TYPE_M],\n /* 0x67 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_H, Debugger8080.TYPE_A],\n /* 0x68 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_L, Debugger8080.TYPE_B],\n /* 0x69 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_L, Debugger8080.TYPE_C],\n /* 0x6A */ [Debugger8080.INS.MOV, Debugger8080.TYPE_L, Debugger8080.TYPE_D],\n /* 0x6B */ [Debugger8080.INS.MOV, Debugger8080.TYPE_L, Debugger8080.TYPE_E],\n /* 0x6C */ [Debugger8080.INS.MOV, Debugger8080.TYPE_L, Debugger8080.TYPE_H],\n /* 0x6D */ [Debugger8080.INS.MOV, Debugger8080.TYPE_L, Debugger8080.TYPE_L],\n /* 0x6E */ [Debugger8080.INS.MOV, Debugger8080.TYPE_L, Debugger8080.TYPE_M],\n /* 0x6F */ [Debugger8080.INS.MOV, Debugger8080.TYPE_L, Debugger8080.TYPE_A],\n /* 0x70 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_M, Debugger8080.TYPE_B],\n /* 0x71 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_M, Debugger8080.TYPE_C],\n /* 0x72 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_M, Debugger8080.TYPE_D],\n /* 0x73 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_M, Debugger8080.TYPE_E],\n /* 0x74 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_M, Debugger8080.TYPE_H],\n /* 0x75 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_M, Debugger8080.TYPE_L],\n /* 0x76 */ [Debugger8080.INS.HLT],\n /* 0x77 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_M, Debugger8080.TYPE_A],\n /* 0x78 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_A, Debugger8080.TYPE_B],\n /* 0x79 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_A, Debugger8080.TYPE_C],\n /* 0x7A */ [Debugger8080.INS.MOV, Debugger8080.TYPE_A, Debugger8080.TYPE_D],\n /* 0x7B */ [Debugger8080.INS.MOV, Debugger8080.TYPE_A, Debugger8080.TYPE_E],\n /* 0x7C */ [Debugger8080.INS.MOV, Debugger8080.TYPE_A, Debugger8080.TYPE_H],\n /* 0x7D */ [Debugger8080.INS.MOV, Debugger8080.TYPE_A, Debugger8080.TYPE_L],\n /* 0x7E */ [Debugger8080.INS.MOV, Debugger8080.TYPE_A, Debugger8080.TYPE_M],\n /* 0x7F */ [Debugger8080.INS.MOV, Debugger8080.TYPE_A, Debugger8080.TYPE_A],\n /* 0x80 */ [Debugger8080.INS.ADD, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_B],\n /* 0x81 */ [Debugger8080.INS.ADD, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_C],\n /* 0x82 */ [Debugger8080.INS.ADD, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_D],\n /* 0x83 */ [Debugger8080.INS.ADD, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_E],\n /* 0x84 */ [Debugger8080.INS.ADD, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_H],\n /* 0x85 */ [Debugger8080.INS.ADD, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_L],\n /* 0x86 */ [Debugger8080.INS.ADD, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_M],\n /* 0x87 */ [Debugger8080.INS.ADD, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_A],\n /* 0x88 */ [Debugger8080.INS.ADC, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_B],\n /* 0x89 */ [Debugger8080.INS.ADC, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_C],\n /* 0x8A */ [Debugger8080.INS.ADC, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_D],\n /* 0x8B */ [Debugger8080.INS.ADC, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_E],\n /* 0x8C */ [Debugger8080.INS.ADC, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_H],\n /* 0x8D */ [Debugger8080.INS.ADC, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_L],\n /* 0x8E */ [Debugger8080.INS.ADC, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_M],\n /* 0x8F */ [Debugger8080.INS.ADC, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_A],\n /* 0x90 */ [Debugger8080.INS.SUB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_B],\n /* 0x91 */ [Debugger8080.INS.SUB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_C],\n /* 0x92 */ [Debugger8080.INS.SUB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_D],\n /* 0x93 */ [Debugger8080.INS.SUB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_E],\n /* 0x94 */ [Debugger8080.INS.SUB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_H],\n /* 0x95 */ [Debugger8080.INS.SUB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_L],\n /* 0x96 */ [Debugger8080.INS.SUB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_M],\n /* 0x97 */ [Debugger8080.INS.SUB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_A],\n /* 0x98 */ [Debugger8080.INS.SBB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_B],\n /* 0x99 */ [Debugger8080.INS.SBB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_C],\n /* 0x9A */ [Debugger8080.INS.SBB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_D],\n /* 0x9B */ [Debugger8080.INS.SBB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_E],\n /* 0x9C */ [Debugger8080.INS.SBB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_H],\n /* 0x9D */ [Debugger8080.INS.SBB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_L],\n /* 0x9E */ [Debugger8080.INS.SBB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_M],\n /* 0x9F */ [Debugger8080.INS.SBB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_A],\n /* 0xA0 */ [Debugger8080.INS.ANA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_B],\n /* 0xA1 */ [Debugger8080.INS.ANA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_C],\n /* 0xA2 */ [Debugger8080.INS.ANA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_D],\n /* 0xA3 */ [Debugger8080.INS.ANA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_E],\n /* 0xA4 */ [Debugger8080.INS.ANA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_H],\n /* 0xA5 */ [Debugger8080.INS.ANA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_L],\n /* 0xA6 */ [Debugger8080.INS.ANA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_M],\n /* 0xA7 */ [Debugger8080.INS.ANA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_A],\n /* 0xA8 */ [Debugger8080.INS.XRA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_B],\n /* 0xA9 */ [Debugger8080.INS.XRA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_C],\n /* 0xAA */ [Debugger8080.INS.XRA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_D],\n /* 0xAB */ [Debugger8080.INS.XRA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_E],\n /* 0xAC */ [Debugger8080.INS.XRA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_H],\n /* 0xAD */ [Debugger8080.INS.XRA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_L],\n /* 0xAE */ [Debugger8080.INS.XRA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_M],\n /* 0xAF */ [Debugger8080.INS.XRA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_A],\n /* 0xB0 */ [Debugger8080.INS.ORA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_B],\n /* 0xB1 */ [Debugger8080.INS.ORA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_C],\n /* 0xB2 */ [Debugger8080.INS.ORA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_D],\n /* 0xB3 */ [Debugger8080.INS.ORA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_E],\n /* 0xB4 */ [Debugger8080.INS.ORA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_H],\n /* 0xB5 */ [Debugger8080.INS.ORA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_L],\n /* 0xB6 */ [Debugger8080.INS.ORA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_M],\n /* 0xB7 */ [Debugger8080.INS.ORA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_A],\n /* 0xB8 */ [Debugger8080.INS.CMP, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_B],\n /* 0xB9 */ [Debugger8080.INS.CMP, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_C],\n /* 0xBA */ [Debugger8080.INS.CMP, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_D],\n /* 0xBB */ [Debugger8080.INS.CMP, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_E],\n /* 0xBC */ [Debugger8080.INS.CMP, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_H],\n /* 0xBD */ [Debugger8080.INS.CMP, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_L],\n /* 0xBE */ [Debugger8080.INS.CMP, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_M],\n /* 0xBF */ [Debugger8080.INS.CMP, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_A],\n /* 0xC0 */ [Debugger8080.INS.RNZ],\n /* 0xC1 */ [Debugger8080.INS.POP, Debugger8080.TYPE_BC],\n /* 0xC2 */ [Debugger8080.INS.JNZ, Debugger8080.TYPE_ADDR],\n /* 0xC3 */ [Debugger8080.INS.JMP, Debugger8080.TYPE_ADDR],\n /* 0xC4 */ [Debugger8080.INS.CNZ, Debugger8080.TYPE_ADDR],\n /* 0xC5 */ [Debugger8080.INS.PUSH, Debugger8080.TYPE_BC],\n /* 0xC6 */ [Debugger8080.INS.ADI, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_IMM | Debugger8080.TYPE_BYTE],\n /* 0xC7 */ [Debugger8080.INS.RST, Debugger8080.TYPE_INT],\n /* 0xC8 */ [Debugger8080.INS.RZ],\n /* 0xC9 */ [Debugger8080.INS.RET],\n /* 0xCA */ [Debugger8080.INS.JZ, Debugger8080.TYPE_ADDR],\n /* 0xCB */ [Debugger8080.INS.JMP, Debugger8080.TYPE_ADDR | Debugger8080.TYPE_UNDOC],\n /* 0xCC */ [Debugger8080.INS.CZ, Debugger8080.TYPE_ADDR],\n /* 0xCD */ [Debugger8080.INS.CALL, Debugger8080.TYPE_ADDR],\n /* 0xCE */ [Debugger8080.INS.ACI, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_IMM | Debugger8080.TYPE_BYTE],\n /* 0xCF */ [Debugger8080.INS.RST, Debugger8080.TYPE_INT],\n /* 0xD0 */ [Debugger8080.INS.RNC],\n /* 0xD1 */ [Debugger8080.INS.POP, Debugger8080.TYPE_DE],\n /* 0xD2 */ [Debugger8080.INS.JNC, Debugger8080.TYPE_ADDR],\n /* 0xD3 */ [Debugger8080.INS.OUT, Debugger8080.TYPE_IMM | Debugger8080.TYPE_BYTE,Debugger8080.TYPE_A | Debugger8080.TYPE_OPT],\n /* 0xD4 */ [Debugger8080.INS.CNC, Debugger8080.TYPE_ADDR],\n /* 0xD5 */ [Debugger8080.INS.PUSH, Debugger8080.TYPE_DE],\n /* 0xD6 */ [Debugger8080.INS.SUI, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_IMM | Debugger8080.TYPE_BYTE],\n /* 0xD7 */ [Debugger8080.INS.RST, Debugger8080.TYPE_INT],\n /* 0xD8 */ [Debugger8080.INS.RC],\n /* 0xD9 */ [Debugger8080.INS.RET, Debugger8080.TYPE_UNDOC],\n /* 0xDA */ [Debugger8080.INS.JC, Debugger8080.TYPE_ADDR],\n /* 0xDB */ [Debugger8080.INS.IN, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_IMM | Debugger8080.TYPE_BYTE],\n /* 0xDC */ [Debugger8080.INS.CC, Debugger8080.TYPE_ADDR],\n /* 0xDD */ [Debugger8080.INS.CALL, Debugger8080.TYPE_ADDR | Debugger8080.TYPE_UNDOC],\n /* 0xDE */ [Debugger8080.INS.SBI, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_IMM | Debugger8080.TYPE_BYTE],\n /* 0xDF */ [Debugger8080.INS.RST, Debugger8080.TYPE_INT],\n /* 0xE0 */ [Debugger8080.INS.RPO],\n /* 0xE1 */ [Debugger8080.INS.POP, Debugger8080.TYPE_HL],\n /* 0xE2 */ [Debugger8080.INS.JPO, Debugger8080.TYPE_ADDR],\n /* 0xE3 */ [Debugger8080.INS.XTHL, Debugger8080.TYPE_SP | Debugger8080.TYPE_MEM| Debugger8080.TYPE_OPT, Debugger8080.TYPE_HL | Debugger8080.TYPE_OPT],\n /* 0xE4 */ [Debugger8080.INS.CPO, Debugger8080.TYPE_ADDR],\n /* 0xE5 */ [Debugger8080.INS.PUSH, Debugger8080.TYPE_HL],\n /* 0xE6 */ [Debugger8080.INS.ANI, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_IMM | Debugger8080.TYPE_BYTE],\n /* 0xE7 */ [Debugger8080.INS.RST, Debugger8080.TYPE_INT],\n /* 0xE8 */ [Debugger8080.INS.RPE],\n /* 0xE9 */ [Debugger8080.INS.PCHL, Debugger8080.TYPE_HL],\n /* 0xEA */ [Debugger8080.INS.JPE, Debugger8080.TYPE_ADDR],\n /* 0xEB */ [Debugger8080.INS.XCHG, Debugger8080.TYPE_HL | Debugger8080.TYPE_OPT, Debugger8080.TYPE_DE | Debugger8080.TYPE_OPT],\n /* 0xEC */ [Debugger8080.INS.CPE, Debugger8080.TYPE_ADDR],\n /* 0xED */ [Debugger8080.INS.CALL, Debugger8080.TYPE_ADDR | Debugger8080.TYPE_UNDOC],\n /* 0xEE */ [Debugger8080.INS.XRI, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_IMM | Debugger8080.TYPE_BYTE],\n /* 0xEF */ [Debugger8080.INS.RST, Debugger8080.TYPE_INT],\n /* 0xF0 */ [Debugger8080.INS.RP],\n /* 0xF1 */ [Debugger8080.INS.POP, Debugger8080.TYPE_PSW],\n /* 0xF2 */ [Debugger8080.INS.JP, Debugger8080.TYPE_ADDR],\n /* 0xF3 */ [Debugger8080.INS.DI],\n /* 0xF4 */ [Debugger8080.INS.CP, Debugger8080.TYPE_ADDR],\n /* 0xF5 */ [Debugger8080.INS.PUSH, Debugger8080.TYPE_PSW],\n /* 0xF6 */ [Debugger8080.INS.ORI, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_IMM | Debugger8080.TYPE_BYTE],\n /* 0xF7 */ [Debugger8080.INS.RST, Debugger8080.TYPE_INT],\n /* 0xF8 */ [Debugger8080.INS.RM],\n /* 0xF9 */ [Debugger8080.INS.SPHL, Debugger8080.TYPE_SP | Debugger8080.TYPE_OPT, Debugger8080.TYPE_HL | Debugger8080.TYPE_OPT],\n /* 0xFA */ [Debugger8080.INS.JM, Debugger8080.TYPE_ADDR],\n /* 0xFB */ [Debugger8080.INS.EI],\n /* 0xFC */ [Debugger8080.INS.CM, Debugger8080.TYPE_ADDR],\n /* 0xFD */ [Debugger8080.INS.CALL, Debugger8080.TYPE_ADDR | Debugger8080.TYPE_UNDOC],\n /* 0xFE */ [Debugger8080.INS.CPI, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_IMM | Debugger8080.TYPE_BYTE],\n /* 0xFF */ [Debugger8080.INS.RST, Debugger8080.TYPE_INT]\n ];\n\n Debugger8080.HISTORY_LIMIT = DEBUG? 100000 : 1000;\n\n /*\n * Initialize every Debugger module on the page (as IF there's ever going to be more than one ;-))\n */\n Web.onInit(Debugger8080.init);\n\n} // endif DEBUGGER\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/computer.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass Computer8080 extends Component {\n /**\n * Computer8080(parmsComputer, parmsMachine, fSuspended)\n *\n * The Computer8080 component has no required (parmsComputer) properties, but it does\n * support the following:\n *\n * autoPower: true to automatically power the computer (default), false to wait;\n * false is honored only if a \"power\" button binding exists.\n *\n * busWidth: number of memory address lines (address bits) on the computer's \"bus\";\n * 20 is the minimum (and the default), which implies 8086/8088 real-mode addressing,\n * while 24 is required for 80286 protected-mode addressing. This value is passed\n * directly through to the Bus component; see that component for more details.\n *\n * resume: one of the Computer8080.RESUME constants, which are as follows:\n * '0' if resume disabled (default)\n * '1' if enabled without prompting\n * '2' if enabled with prompting\n * '3' if enabled with prompting and auto-delete\n * or a string containing the path of a predefined JSON-encoded state\n *\n * state: the path to JSON-encoded state file (see details regarding 'state' below)\n *\n * The parmsMachine object, if provided, may contain any of:\n *\n * autoMount: if set, this should override any 'autoMount' property in the FDC's\n * parmsFDC object.\n *\n * autoPower: if set, this should override any 'autoPower' property in the Computer8080's\n * parmsComputer object.\n *\n * messages: if set, this should override any 'messages' property in the Debugger's\n * parmsDbg object.\n *\n * state: if set, this should override any 'state' property in the Computer8080's\n * parmsComputer object.\n *\n * url: the location of the machine XML file\n *\n * If a predefined state is supplied AND it's successfully loaded, then resume behavior\n * defaults to '1' (ie, resume enabled without prompting).\n *\n * This component insures that all components are ready before \"powering\" them.\n *\n * Different components become ready at different times, and initialization order (ie,\n * the order the scripts are combined on the page) only partially determines readiness.\n * This is because components like ROM and Video must finish loading their resource files\n * before they are ready. Other components become ready after we call their initBus()\n * function, because they have a Bus or CPU dependency, such as access to memory management\n * functions. And other components, like CPU and Panel, are ready as soon as their\n * constructor finishes.\n *\n * Once a component has indicated it's ready, we call its powerUp() notification\n * function (if it has one--it's optional). We call the CPU's powerUp() function last,\n * so that the CPU is assured that all other components are ready and \"powered\".\n *\n * @this {Computer8080}\n * @param {Object} parmsComputer\n * @param {Object} [parmsMachine]\n * @param {boolean} [fSuspended]\n */\n constructor(parmsComputer, parmsMachine, fSuspended)\n {\n super(\"Computer\", parmsComputer, Messages8080.COMPUTER);\n\n this.flags.powered = false;\n\n this.setMachineParms(parmsMachine);\n\n this.fAutoPower = this.getMachineParm('autoPower', parmsComputer);\n\n /*\n * nPowerChange is 0 while the power state is stable, 1 while power is transitioning\n * to \"on\", and -1 while power is transitioning to \"off\".\n */\n this.nPowerChange = 0;\n\n /*\n * TODO: Deprecate 'buswidth' (it should have always used camelCase)\n */\n this.nBusWidth = parmsComputer['busWidth'] || parmsComputer['buswidth'];\n\n this.resume = Computer8080.RESUME_NONE;\n this.sStateData = null;\n this.fStateData = false; // remembers if sStateData was loaded\n this.fServerState = false;\n\n this.url = this.getMachineParm('url') || \"\";\n\n /*\n * Generate a random number x (where 0 <= x < 1), add 0.1 so that it's guaranteed to be\n * non-zero, convert to base 36, and chop off the leading digit and \"decimal\" point.\n */\n this.sMachineID = (Math.random() + 0.1).toString(36).substr(2,12);\n this.sUserID = this.queryUserID();\n\n /*\n * Find the appropriate CPU (and Debugger and Control Panel, if any)\n *\n * CLOSURE COMPILER TIP: To override the type of a right-hand expression (as we need to do here,\n * where we know getComponentByType() will only return an CPUState object or null), wrap the expression\n * in parentheses. I never knew this until I stumbled across it in \"Closure: The Definitive Guide\".\n */\n this.cpu = /** @type {CPUState8080} */ (Component.getComponentByType(\"CPU\", this.id));\n if (!this.cpu) {\n Component.error(\"Unable to find CPU component\");\n return;\n }\n this.dbg = /** @type {Debugger8080} */ (Component.getComponentByType(\"Debugger\", this.id));\n\n /*\n * Enumerate all Video components for future updateVideo() calls.\n */\n this.aVideo = [];\n for (var video = null; (video = this.getMachineComponent(\"Video\", video));) {\n this.aVideo.push(video);\n }\n\n /*\n * Initialize the Bus component\n */\n this.bus = new Bus8080({'id': this.idMachine + '.bus', 'busWidth': this.nBusWidth}, this.cpu, this.dbg);\n\n /*\n * Iterate through all the components and connect them to the Control Panel, if any\n */\n var iComponent, component;\n var aComponents = Component.getComponents(this.id);\n\n this.panel = /** @type {Panel8080} */ (Component.getComponentByType(\"Panel\", this.id));\n this.controlPrint = this.panel && this.panel.bindings['print'];\n\n if (this.controlPrint) {\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n /*\n * I can think of many \"cleaner\" ways for the Control Panel component to pass its\n * notice(), println(), etc, overrides on to all the other components, but it's just\n * too darn convenient to slam those overrides into the components directly.\n */\n component.notice = this.panel.notice;\n component.print = this.panel.print;\n component.println = this.panel.println;\n }\n }\n\n this.println(PC8080.APPNAME + \" v\" + (XMLVERSION || PC8080.APPVERSION) + \"\\n\" + COPYRIGHT + \"\\n\" + LICENSE);\n\n if (DEBUG && this.messageEnabled()) this.printMessage(\"TYPEDARRAYS: \" + TYPEDARRAYS);\n\n /*\n * Iterate through all the components again and call their initBus() handler, if any\n */\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component.initBus) component.initBus(this, this.bus, this.cpu, this.dbg);\n }\n\n var sStatePath = null;\n var sResume = this.getMachineParm('resume', parmsComputer);\n if (sResume !== undefined) {\n /*\n * Decide whether the 'resume' property is a number or the path of a state file to resume.\n */\n if (sResume.length > 1) {\n sStatePath = this.sResumePath = sResume;\n } else {\n this.resume = parseInt(sResume, 10);\n }\n }\n\n /*\n * The Computer 'state' property allows a state file to be specified independent of the 'resume' feature;\n * previously, you could only use 'resume' to load a state file -- which we still support, but loading a state\n * file that way prevents the machine's state from being saved, since we always resume from the 'resume' file.\n *\n * The other wrinkle is on the restore side: we need to IGNORE the 'state' property if a saved state now exists.\n * So we have to peek at localStorage, and unfortunately, the only way to \"peek\" is to actually load the data,\n * but we're not ready to use it yet, so powerUp() has been changed to use any existing stateComputer that we've\n * already loaded.\n *\n * However, there's now a wrinkle to the wrinkle: if a 'state' parameter has been passed via the URL, then that\n * OVERRIDES everything; it overrides any 'state' Computer parameter AND it disables resume of any saved state in\n * localStorage (in other words, it prevents fAllowResume from being true, and forcing resume off).\n */\n var fAllowResume;\n var sState = this.getMachineParm('state') || (fAllowResume = true) && parmsComputer['state'];\n\n if (sState) {\n sStatePath = this.sStatePath = sState;\n if (!fAllowResume) {\n this.fServerState = true;\n this.resume = Computer8080.RESUME_NONE;\n }\n if (this.resume) {\n this.stateComputer = new State(this, PC8080.APPVERSION);\n if (this.stateComputer.load()) {\n sStatePath = null;\n } else {\n delete this.stateComputer;\n }\n }\n }\n\n /*\n * If sStatePath is set, we must use it. But if there's no sStatePath AND resume is set,\n * then we have the option of resuming from a server-side state, assuming a valid USERID.\n */\n if (!sStatePath && this.resume) {\n sStatePath = this.getServerStatePath();\n if (sStatePath) this.fServerState = true;\n }\n\n if (!sStatePath) {\n this.setReady();\n } else {\n var cmp = this;\n Web.getResource(sStatePath, null, true, function(sURL, sResource, nErrorCode) {\n cmp.doneLoad(sURL, sResource, nErrorCode);\n });\n }\n\n if (!this.bindings[\"power\"]) this.fAutoPower = true;\n\n /*\n * Power on the computer, giving every component the opportunity to reset or restore itself.\n */\n if (!fSuspended && this.fAutoPower) this.wait(this.powerOn);\n }\n\n /**\n * clearPanel()\n *\n * @this {Computer8080}\n */\n clearPanel()\n {\n if (this.controlPrint) {\n this.controlPrint.value = \"\";\n }\n }\n\n /**\n * getMachineID()\n *\n * @this {Computer8080}\n * @return {string}\n */\n getMachineID()\n {\n return this.sMachineID;\n }\n\n /**\n * setMachineParms(parmsMachine)\n *\n * If no explicit machine parms were provided, then we check for 'parms' in the bundled resources (if any).\n *\n * @this {Computer8080}\n * @param {Object} [parmsMachine]\n */\n setMachineParms(parmsMachine)\n {\n if (!parmsMachine) {\n var sParms;\n if (typeof resources == 'object' && (sParms = resources['parms'])) {\n try {\n parmsMachine = /** @type {Object} */ (eval(\"(\" + sParms + \")\"));\n } catch(e) {\n Component.error(e.message + \" (\" + sParms + \")\");\n }\n }\n }\n this.parmsMachine = parmsMachine;\n }\n\n /**\n * getMachineParm(sParm, parmsComponent)\n *\n * If the machine parameter doesn't exist, we check for a matching component parameter (if parmsComponent is provided),\n * and failing that, we check the bundled resources (if any).\n *\n * At the moment, the only bundled resource request we expect to encounter is 'state'; if it exists, then we return\n * 'state' back to the caller (ie, the name of the resource), so that the caller will then attempt to load the 'state'\n * resource to obtain the actual state.\n *\n * @this {Computer8080}\n * @param {string} sParm\n * @param {Object} [parmsComponent]\n * @return {string|undefined}\n */\n getMachineParm(sParm, parmsComponent)\n {\n /*\n * When using getURLParm(), the check is allowed be a bit looser, because URL parameters are\n * user-supplied, whereas most other parameters are developer-supplied. Granted, a developer\n * may also be sloppy and neglect to use correct case (eg, 'automount' instead of 'autoMount'),\n * but there are limits to my paranoia.\n */\n var sParmLC = sParm.toLowerCase();\n var value = Web.getURLParm(sParm) || Web.getURLParm(sParmLC);\n\n if (value === undefined && this.parmsMachine) {\n value = this.parmsMachine[sParm];\n }\n if (value === undefined && parmsComponent) {\n value = parmsComponent[sParm];\n }\n if (value === undefined && typeof resources == 'object' && resources[sParm]) {\n value = sParm;\n }\n return value;\n }\n\n /**\n * saveMachineParms()\n *\n * @this {Computer8080}\n * @return {string|null}\n */\n saveMachineParms()\n {\n return this.parmsMachine? JSON.stringify(this.parmsMachine) : null;\n }\n\n /**\n * getUserID()\n *\n * @this {Computer8080}\n * @return {string}\n */\n getUserID()\n {\n return this.sUserID || \"\";\n }\n\n /**\n * doneLoad(sURL, sStateData, nErrorCode)\n *\n * @this {Computer8080}\n * @param {string} sURL\n * @param {string} sStateData\n * @param {number} nErrorCode\n */\n doneLoad(sURL, sStateData, nErrorCode)\n {\n if (!nErrorCode) {\n this.sStateData = sStateData;\n this.fStateData = true;\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"loaded state file \" + sURL.replace(this.sUserID || \"xxx\", \"xxx\"));\n }\n } else {\n this.sResumePath = null;\n this.fServerState = false;\n this.notice('Unable to load machine state from server (error ' + nErrorCode + (sStateData? ': ' + Str.trim(sStateData) : '') + ')');\n }\n this.setReady();\n }\n\n /**\n * wait(fn, parms)\n *\n * wait() waits until every component is ready (including ourselves, the last component we check), then calls the\n * specified Computer method.\n *\n * TODO: The Closure Compiler makes it difficult for us to define a function type for \"fn\" that works in all cases;\n * sometimes we want to pass a function that takes only a \"number\", and other times we want to pass a function that\n * takes only an \"Array\" (the type will mirror that of the \"parms\" parameter). However, the Closure Compiler insists\n * that both functions must be declared as accepting both types of parameters. So once again, we must use an untyped\n * function declaration, instead of something stricter like:\n *\n * param {function(this:Computer, (number|Array|undefined)): undefined} fn\n *\n * @this {Computer8080}\n * @param {function(...)} fn\n * @param {number|Array} [parms] optional parameters\n */\n wait(fn, parms)\n {\n var computer = this;\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent <= aComponents.length; iComponent++) {\n var component = (iComponent < aComponents.length ? aComponents[iComponent] : this);\n if (!component.isReady()) {\n component.isReady(function onComponentReady() {\n computer.wait(fn, parms);\n });\n return;\n }\n }\n if (DEBUG && this.messageEnabled()) this.printMessage(\"Computer8080.wait(ready)\");\n fn.call(this, parms);\n }\n\n /**\n * validateState(stateComputer)\n *\n * NOTE: We clear() stateValidate only when there's no stateComputer.\n *\n * @this {Computer8080}\n * @param {State|null} [stateComputer]\n * @return {boolean} true if state passes validation, false if not\n */\n validateState(stateComputer)\n {\n var fValid = true;\n var stateValidate = new State(this, PC8080.APPVERSION, Computer8080.STATE_VALIDATE);\n if (stateValidate.load() && stateValidate.parse()) {\n var sTimestampValidate = stateValidate.get(Computer8080.STATE_TIMESTAMP);\n var sTimestampComputer = stateComputer? stateComputer.get(Computer8080.STATE_TIMESTAMP) : \"unknown\";\n if (sTimestampValidate != sTimestampComputer) {\n this.notice(\"Machine state may be out-of-date\\n(\" + sTimestampValidate + \" vs. \" + sTimestampComputer + \")\\nCheck your browser's local storage limits\");\n fValid = false;\n if (!stateComputer) stateValidate.clear();\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"Last state: \" + sTimestampComputer + \" (validate: \" + sTimestampValidate + \")\");\n }\n }\n }\n return fValid;\n }\n\n /**\n * powerOn(resume)\n *\n * Power every component \"up\", applying any previously available state information.\n *\n * @this {Computer8080}\n * @param {number} [resume] is a valid RESUME value; default is this.resume\n */\n powerOn(resume)\n {\n if (resume === undefined) {\n resume = this.resume || (this.sStateData? Computer8080.RESUME_AUTO : Computer8080.RESUME_NONE);\n }\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"Computer8080.powerOn(\" + (resume == Computer8080.RESUME_REPOWER ? \"repower\" : (resume ? \"resume\" : \"\")) + \")\");\n }\n\n if (this.nPowerChange) {\n return;\n }\n this.nPowerChange++;\n\n var fRepower = false;\n var fRestore = false;\n this.fRestoreError = false;\n var stateComputer = this.stateComputer || new State(this, PC8080.APPVERSION);\n\n if (resume == Computer8080.RESUME_REPOWER) {\n fRepower = true;\n }\n else if (resume > Computer8080.RESUME_NONE) {\n if (stateComputer.load(this.sStateData)) {\n /*\n * Since we're resuming something (either a predefined state or a state from localStorage), let's\n * create a \"failsafe\" checkpoint in localStorage, and destroy it at the end of a successful powerOn().\n * Which means, of course, that if a previous \"failsafe\" checkpoint already exists, something bad\n * may have happened the last time around.\n */\n this.stateFailSafe = new State(this, PC8080.APPVERSION, Computer8080.STATE_FAILSAFE);\n if (this.stateFailSafe.load()) {\n this.powerReport(stateComputer);\n /*\n * We already know resume is something other than RESUME_NONE, so we'll go ahead and bump it\n * all the way to RESUME_PROMPT, so that the user will be prompted, and if the user declines to\n * restore, the state will be removed.\n */\n resume = Computer8080.RESUME_PROMPT;\n /*\n * To ensure that the set() below succeeds, we need to call unload(), otherwise it may fail\n * with a \"read only\" error (eg, \"TypeError: Cannot assign to read only property 'timestamp'\").\n */\n this.stateFailSafe.unload();\n }\n\n this.stateFailSafe.set(Computer8080.STATE_TIMESTAMP, Usr.getTimestamp());\n this.stateFailSafe.store();\n\n var fValidate = this.resume && !this.fServerState;\n if (resume == Computer8080.RESUME_AUTO || Component.confirmUser(\"Click OK to restore the previous \" + PC8080.APPNAME + \" machine state, or CANCEL to reset the machine.\")) {\n fRestore = stateComputer.parse();\n if (fRestore) {\n var sCode = /** @type {string} */ (stateComputer.get(UserAPI.RES.CODE));\n var sData = /** @type {string} */ (stateComputer.get(UserAPI.RES.DATA));\n if (sCode) {\n if (sCode == UserAPI.CODE.OK) {\n stateComputer.load(sData);\n } else {\n /*\n * A missing (or not yet created) state file is no cause for alarm, but other errors might be\n */\n if (sCode == UserAPI.CODE.FAIL && sData != UserAPI.FAIL.NOSTATE) {\n this.notice(\"Error: \" + sData);\n if (sData == UserAPI.FAIL.VERIFY) this.resetUserID();\n } else {\n this.println(sCode + \": \" + sData);\n }\n /*\n * Try falling back to the state that we should have saved in localStorage, as a backup to the\n * server-side state.\n */\n stateComputer.unload(); // discard the invalid server-side state first\n if (stateComputer.load()) {\n fRestore = stateComputer.parse();\n fValidate = true;\n } else {\n fRestore = false; // hmmm, there was nothing in localStorage either\n }\n }\n }\n }\n /*\n * If the load/parse was successful, and it was from localStorage (not sStateData),\n * then we should to try verify that localStorage snapshot is current. One reason it may\n * NOT be current is if localStorage was full and we got a quota error during the last\n * powerOff().\n */\n if (fValidate) this.validateState(fRestore? stateComputer : null);\n } else {\n /*\n * RESUME_PROMPT indicates we should delete the state if they clicked Cancel to confirm() above.\n */\n if (resume == Computer8080.RESUME_PROMPT) stateComputer.clear();\n }\n } else {\n /*\n * If there's no state, then there should also be no validation timestamp; if there is, then once again,\n * we're probably dealing with a quota error.\n */\n this.validateState();\n }\n delete this.sStateData;\n delete this.stateComputer;\n }\n\n /*\n * Start powering all components, including any data they may need to restore their state;\n * we restore power to the CPU last.\n */\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component !== this && component != this.cpu) {\n fRestore = this.powerRestore(component, stateComputer, fRepower, fRestore);\n }\n }\n\n /*\n * Assuming this is not a repower, we must perform another wait, because some components may\n * have marked themselves as \"not ready\" again (eg, the FDC component, if the restore forced it\n * to mount one or more additional disk images).\n */\n var aParms = [stateComputer, resume, fRestore];\n\n if (resume != Computer8080.RESUME_REPOWER) {\n this.wait(this.donePowerOn, aParms);\n return;\n }\n this.donePowerOn(aParms);\n }\n\n /**\n * powerRestore(component, stateComputer, fRepower, fRestore)\n *\n * @this {Computer8080}\n * @param {Component} component\n * @param {State} stateComputer\n * @param {boolean} fRepower\n * @param {boolean} fRestore\n * @return {boolean} true if restore should continue, false if not\n */\n powerRestore(component, stateComputer, fRepower, fRestore)\n {\n if (!component.flags.powered) {\n\n component.flags.powered = true;\n\n if (component.powerUp) {\n\n var data = null;\n if (fRestore) {\n data = stateComputer.get(component.id);\n if (!data) {\n /*\n * This is a hack that makes it possible for a machine whose ID has been\n * supplemented with a hyphenated numeric suffix to find object IDs in states\n * created from a machine without such a suffix.\n *\n * For example, if a state file was created from a machine with ID \"ibm5160\"\n * but the current machine is \"ibm5160-1\", this attempts a second lookup with\n * \"ibm5160\", enabling us to find objects that match the original machine ID\n * (eg, \"ibm5160.romEGA\").\n *\n * See /devices/pcx86/machine/5160/ega/640kb/array/ for examples of this.\n */\n data = stateComputer.get(component.id.replace(/-[0-9]+\\./i, '.'));\n }\n }\n\n /*\n * State.get() will return whatever was originally passed to State.set() (eg, an\n * Object or a string), but components are supposed to store only Objects, so if a\n * string comes back, something went wrong. By explicitly eliminating \"string\" data,\n * the Closure Compiler stops complaining that we might be passing strings to our\n * powerUp() functions (even though we know we're not).\n *\n * TODO: Determine if there's some way to coerce the Closure Compiler into treating\n * data as Object or null, without having to include this runtime check. An assert\n * would be a good idea, but this is overkill.\n */\n if (typeof data === \"string\") data = null;\n\n /*\n * If computer is null, this is simply a repower notification, which most components\n * don't do anything with. Exceptions include: CPU (since it may be halted) and Video\n * (since its screen may be \"turned off\").\n */\n if (!component.powerUp(data, fRepower) && data) {\n\n Component.error(\"Unable to restore state for \" + component.type);\n /*\n * If this is a resume error for a machine that also has a predefined state\n * AND we're not restoring from that state, then throw away the current state,\n * prevent any new state from being created, and then force a reload, which will\n * hopefully restore us to the functioning predefined state.\n *\n * TODO: Considering doing this in ALL cases, not just in situations where a\n * 'state' exists but we're not actually resuming from it.\n */\n if (this.sStatePath && !this.fStateData) {\n stateComputer.clear();\n this.resume = Computer8080.RESUME_NONE;\n Web.reloadPage();\n } else {\n /*\n * In all other cases, we set fRestoreError, which should trigger a call to\n * powerReport() and then delete the offending state.\n */\n this.fRestoreError = true;\n }\n /*\n * Any failure triggers an automatic to call powerUp() again, without any state,\n * in the hopes that the component can recover by performing a reset.\n */\n component.powerUp(null);\n /*\n * We also disable the rest of the restore operation, because it's not clear\n * the remaining state information can be trusted; the machine is already in an\n * inconsistent state, so we're not likely to make things worse, and the only\n * alternative (starting over and performing a state-less reset) isn't likely to make\n * the user any happier. But, we'll see... we need some experience with the code.\n */\n fRestore = false;\n }\n }\n\n if (!fRepower && component.comment) {\n var asComments = component.comment.split(\"|\");\n for (var i = 0; i < asComments.length; i++) {\n component.status(asComments[i]);\n }\n }\n }\n return fRestore;\n }\n\n /**\n * donePowerOn(aParms)\n *\n * This is nothing more than a continuation of powerOn(), giving us the option of calling wait() one more time.\n *\n * @this {Computer8080}\n * @param {Array} aParms containing [stateComputer, resume, fRestore]\n */\n donePowerOn(aParms)\n {\n var stateComputer = aParms[0];\n var fRepower = (aParms[1] < 0);\n var fRestore = aParms[2];\n\n if (DEBUG && this.flags.powered && this.messageEnabled()) {\n this.printMessage(\"Computer8080.donePowerOn(): redundant\");\n }\n\n this.fInitialized = true;\n this.flags.powered = true;\n var controlPower = this.bindings[\"power\"];\n if (controlPower) controlPower.textContent = \"Shutdown\";\n\n /*\n * Once we get to this point, we're guaranteed that all components are ready, so it's safe to power the CPU;\n * the CPU should begin executing immediately, unless a debugger is attached.\n */\n if (this.cpu) {\n /*\n * TODO: Do we not care about the return value here? (ie, is checking fRestoreError sufficient)?\n */\n this.powerRestore(this.cpu, stateComputer, fRepower, fRestore);\n this.cpu.autoStart();\n }\n\n /*\n * If the state was bad, offer to report it and then delete it. Deleting may be moot, since invariably a new\n * state will be created on powerOff() before the next powerOn(), but it seems like good paranoia all the same.\n */\n if (this.fRestoreError) {\n this.powerReport(stateComputer);\n stateComputer.clear();\n }\n\n if (!fRepower && this.stateFailSafe) {\n this.stateFailSafe.clear();\n delete this.stateFailSafe;\n }\n\n this.nPowerChange = 0;\n }\n\n /**\n * checkPower()\n *\n * @this {Computer8080}\n * @return {boolean} true if the computer is fully powered, false otherwise\n */\n checkPower()\n {\n if (this.flags.powered) return true;\n\n var component = null, iComponent;\n var aComponents = Component.getComponents(this.id);\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component !== this && !component.flags.ready) break;\n }\n if (iComponent == aComponents.length) {\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component !== this && !component.flags.powered) break;\n }\n }\n if (iComponent == aComponents.length) component = this;\n var s = \"The \" + component.type + \" component (\" + component.id + \") is not \" + (!component.flags.ready? \"ready yet\" + (component.fnReady? \" (waiting for notification)\" : \"\") : \"powered yet\") + \".\";\n Component.alertUser(s);\n return false;\n }\n\n /**\n * powerReport(stateComputer)\n *\n * @this {Computer8080}\n * @param {State} stateComputer\n */\n powerReport(stateComputer)\n {\n if (Component.confirmUser(\"There may be a problem with your \" + PC8080.APPNAME + \" machine.\\n\\nTo help us diagnose it, click OK to send this \" + PC8080.APPNAME + \" machine state to http://\" + SITEHOST + \".\")) {\n Web.sendReport(PC8080.APPNAME, PC8080.APPVERSION, this.url, this.getUserID(), ReportAPI.TYPE.BUG, stateComputer.toString());\n }\n }\n\n /**\n * powerOff(fSave, fShutdown)\n *\n * Power every component \"down\" and optionally save the machine state.\n *\n * There's one scenario that powerOff() isn't currently able to deal with very effectively: what to do when\n * the user switches away while it's still being restored, causing Disk getResource() calls to fail. The\n * Disk component calls notify() when that happens -- see Disk.mount() -- but the FDC and HDC controllers don't\n * notify *us* of those problems, so Computer assumes that the restore was completely successful, when in fact\n * it was only partially successful.\n *\n * Then we immediately arrive here to perform a save, following that incomplete restore. It would be wrong to\n * deal with that incomplete restore by setting fRestoreError, because we don't want to trigger a powerReport()\n * and the deletion of the previous state, because the state itself was presumably OK. Unfortunately, the new\n * state we now save will no longer include manually mounted disk images whose remounts were interrupted, so future\n * restores won't remount them either.\n *\n * We could perhaps solve this by having the Disk component notify us in those situations, set a new flag\n * (fRestoreIncomplete?), and set fSave to false if that's ever set. Be careful though: when fSave is false,\n * that means MORE than not saving; it also means deleting any previous state, which is NOT what you'd want to\n * do in a \"fRestoreIncomplete\" situation. Also, we have to worry about Disk operations that fail for other reasons,\n * making sure those failures don't interfere with the save process in the same way.\n *\n * As it stands, the worst that happens is any manually mounted disk images might have to be manually remounted,\n * which doesn't seem like a huge problem.\n *\n * @this {Computer8080}\n * @param {boolean} [fSave] is true to request a saved state\n * @param {boolean} [fShutdown] is true if the machine is being shut down\n * @return {string|null} string representing the saved state (or null if error)\n */\n powerOff(fSave, fShutdown)\n {\n var data;\n var sState = \"none\";\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"Computer8080.powerOff(\" + (fSave ? \"save\" : \"nosave\") + (fShutdown ? \",shutdown\" : \"\") + \")\");\n }\n\n if (this.nPowerChange) {\n return null;\n }\n this.nPowerChange--;\n\n var stateComputer = new State(this, PC8080.APPVERSION);\n var stateValidate = new State(this, PC8080.APPVERSION, Computer8080.STATE_VALIDATE);\n\n var sTimestamp = Usr.getTimestamp();\n stateValidate.set(Computer8080.STATE_TIMESTAMP, sTimestamp);\n stateComputer.set(Computer8080.STATE_TIMESTAMP, sTimestamp);\n stateComputer.set(Computer8080.STATE_VERSION, APPVERSION);\n stateComputer.set(Computer8080.STATE_HOSTURL, Web.getHostURL());\n stateComputer.set(Computer8080.STATE_BROWSER, Web.getUserAgent());\n\n /*\n * Always power the CPU \"down\" first, just to help insure it doesn't ask other components to do anything\n * after they're no longer ready.\n */\n if (this.cpu && this.cpu.powerDown) {\n if (fShutdown) this.cpu.stopCPU();\n data = this.cpu.powerDown(fSave, fShutdown);\n if (typeof data === \"object\") stateComputer.set(this.cpu.id, data);\n if (fShutdown) {\n this.cpu.flags.powered = false;\n if (data === false) sState = null;\n }\n }\n\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.flags.powered) {\n if (component.powerDown) {\n data = component.powerDown(fSave, fShutdown);\n if (typeof data === \"object\") stateComputer.set(component.id, data);\n }\n if (fShutdown) {\n component.flags.powered = false;\n if (data === false) sState = null;\n }\n }\n }\n\n if (sState) {\n if (fShutdown) {\n var fClear = false;\n var fClearAll = false;\n if (fSave) {\n if (this.sUserID) {\n this.saveServerState(this.sUserID, stateComputer.toString());\n }\n if (!stateValidate.store() || !stateComputer.store()) {\n sState = null;\n /*\n * New behavior as of v1.13.2: if it appears that localStorage is full, we blow it ALL away.\n * Dedicated server-side storage is the only way we'll ever be able to reliably preserve a\n * particular machine's state. Historically, attempting to limp along with whatever localStorage\n * is left just generates the same useless and annoying warnings over and over.\n */\n fClear = fClearAll = true;\n }\n }\n else {\n /*\n * I used to ALWAYS clear (ie, delete) any associated computer state, but now I do this only if the\n * current machine is \"resumable\", because there are situations where I have two configurations\n * for the same machine -- one resumable and one not -- and I don't want the latter throwing away the\n * state of the former.\n *\n * So this code is here now strictly for callers to delete the state of a \"resumable\" machine, not as\n * some paranoid clean-up operation.\n *\n * An undocumented feature of this operation is that if your configuration uses the special 'resume=\"3\"'\n * value, and you click the \"Reset\" button, and then you click OK to reset the everything, this will\n * actually reset EVERYTHING (ie, all localStorage for ALL configs will be reclaimed).\n */\n if (this.resume) {\n fClear = true;\n fClearAll = (this.resume == Computer8080.RESUME_DELETE);\n }\n }\n if (fClear) {\n stateComputer.clear(fClearAll);\n }\n } else {\n sState = stateComputer.toString();\n }\n }\n\n if (fShutdown) {\n this.flags.powered = false;\n var controlPower = this.bindings[\"power\"];\n if (controlPower) controlPower.textContent = \"Power\";\n }\n\n this.nPowerChange = 0;\n\n return sState;\n }\n\n /**\n * reset()\n *\n * Notify all (other) components with a reset() method that the Computer is being reset.\n *\n * NOTE: We'd like to reset the Bus first (due to the importance of the A20 line), but since we\n * allocated the Bus object ourselves, after all the other components were allocated, it ends\n * up near the end of Component's list of components. Hence the special case for this.bus below.\n *\n * @this {Computer8080}\n */\n reset()\n {\n if (this.bus && this.bus.reset) {\n /*\n * TODO: Why does WebStorm think that this.bus.type is undefined? The base class (Component)\n * constructor defines it.\n */\n this.printMessage(\"Resetting \" + this.bus.type);\n this.bus.reset();\n }\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component !== this && component !== this.bus && component.reset) {\n this.printMessage(\"Resetting \" + component.type);\n component.reset();\n }\n }\n }\n\n /**\n * start(ms, nCycles)\n *\n * Notify all (other) components with a start() method that the CPU has started.\n *\n * Note that we're called by runCPU(), which is why we exclude the CPU component,\n * as well as ourselves.\n *\n * @this {Computer8080}\n * @param {number} ms\n * @param {number} nCycles\n */\n start(ms, nCycles)\n {\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.type == \"CPU\" || component === this) continue;\n if (component.start) {\n component.start(ms, nCycles);\n }\n }\n }\n\n /**\n * stop(ms, nCycles)\n *\n * Notify all (other) components with a stop() method that the CPU has stopped.\n *\n * Note that we're called by runCPU(), which is why we exclude the CPU component,\n * as well as ourselves.\n *\n * @this {Computer8080}\n * @param {number} ms\n * @param {number} nCycles\n */\n stop(ms, nCycles)\n {\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.type == \"CPU\" || component === this) continue;\n if (component.stop) {\n component.stop(ms, nCycles);\n }\n }\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {Computer8080}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var computer = this;\n\n switch (sBinding) {\n case \"power\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickPower() {\n computer.onPower();\n };\n return true;\n\n case \"reset\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickReset() {\n computer.onReset();\n };\n return true;\n\n /*\n * Technically, this binding should now be called \"saveState\", to clearly distinguish it from\n * the \"Save Machine\" control that's normally bound to the savePC() function in save.js. Saving\n * an entire machine includes everything needed to start/restore the machine; eg, the machine\n * XML configuration file(s) *and* the JSON-encoded machine state.\n */\n case \"save\":\n /*\n * Since this feature depends on the server supporting the PCjs User API (see userapi.js),\n * and since pcjs.org is no longer running a Node web server, we disable the feature for that\n * particular host.\n */\n if (Str.endsWith(Web.getHost(), \"pcjs.org\")) {\n if (DEBUG) this.log(\"Remote user API not available\");\n /*\n * We could also simply hide the control; eg:\n *\n * control.style.display = \"none\";\n *\n * but removing the control altogether seems better.\n */\n control.parentNode.removeChild(/** @type {Node} */ (control));\n return false;\n }\n this.bindings[sBinding] = control;\n control.onclick = function onClickSave() {\n var sUserID = computer.queryUserID(true);\n if (sUserID) {\n /*\n * I modified the test to include a check for sStatePath so that I could save new states\n * for machines with existing states; otherwise, I'd have no (easy) way of capturing and\n * updating their state. Making the machine (even temporarily) resumable would have been\n * one work-around, but it's not appropriate for some machines, as their state is simply\n * too large (for localStorage anyway, which is the default storage solution).\n */\n var fSave = !!(computer.resume && !computer.sResumePath || computer.sStatePath);\n var sState = computer.powerOff(fSave);\n if (fSave) {\n computer.saveServerState(sUserID, sState);\n } else {\n computer.notice(\"Resume disabled, machine state not saved\");\n }\n }\n /*\n * This seemed like a handy alternative, but it turned out to be a no-go, at least for large states:\n *\n * var sState = computer.powerOff(true);\n * if (sState) {\n * sState = \"data:text/json;charset=utf-8,\" + encodeURIComponent(sState);\n * window.open(sState);\n * }\n *\n * Perhaps if I embedded the data in a link on the current page instead; eg:\n *\n * $('<a href=\"' + sState + '\" download=\"state.json\">Download</a>').appendTo('#container');\n */\n };\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * resetUserID()\n */\n resetUserID()\n {\n Web.setLocalStorageItem(Computer8080.STATE_USERID, \"\");\n this.sUserID = null;\n }\n\n /**\n * queryUserID(fPrompt)\n *\n * @param {boolean} [fPrompt]\n * @returns {string|null|undefined}\n */\n queryUserID(fPrompt)\n {\n var sUserID = this.sUserID;\n if (!sUserID) {\n sUserID = Web.getLocalStorageItem(Computer8080.STATE_USERID);\n if (sUserID !== undefined) {\n if (!sUserID && fPrompt) {\n /*\n * NOTE: Warning the user here that \"Save\" operations are not currently supported by pcjs.org is\n * merely a precaution, because ordinarily, setBinding() should have already determined if we are\n * running from pcjs.org and disabled any \"Save\" button.\n */\n sUserID = Component.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.\");\n if (sUserID) {\n sUserID = this.verifyUserID(sUserID);\n if (!sUserID) this.notice(\"The user ID is invalid.\");\n }\n }\n } else if (fPrompt) {\n this.notice(\"Browser local storage is not available\");\n }\n }\n return sUserID;\n }\n\n /**\n * verifyUserID(sUserID)\n *\n * @this {Computer8080}\n * @param {string} sUserID\n * @return {string} validated user ID, or null if error\n */\n verifyUserID(sUserID)\n {\n this.sUserID = null;\n var fMessages = DEBUG && this.messageEnabled();\n if (fMessages) this.printMessage(\"verifyUserID(\" + sUserID + \")\");\n var sRequest = Web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.VERIFY + '&' + UserAPI.QUERY.USER + '=' + sUserID;\n var response = Web.getResource(sRequest);\n var nErrorCode = response[0];\n var sResponse = response[1];\n if (!nErrorCode && sResponse) {\n try {\n response = eval(\"(\" + sResponse + \")\");\n if (response.code && response.code == UserAPI.CODE.OK) {\n Web.setLocalStorageItem(Computer8080.STATE_USERID, response.data);\n if (fMessages) this.printMessage(Computer8080.STATE_USERID + \" updated: \" + response.data);\n this.sUserID = response.data;\n } else {\n if (fMessages) this.printMessage(response.code + \": \" + response.data);\n }\n } catch (e) {\n Component.error(e.message + \" (\" + sResponse + \")\");\n }\n } else {\n if (fMessages) this.printMessage(\"invalid response (error \" + nErrorCode + \")\");\n }\n return this.sUserID;\n }\n\n /**\n * getServerStatePath()\n *\n * @this {Computer8080}\n * @return {string|null} sStatePath (null if no localStorage or no USERID stored in localStorage)\n */\n getServerStatePath()\n {\n var sStatePath = null;\n if (this.sUserID) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(Computer8080.STATE_USERID + \" for load: \" + this.sUserID);\n }\n sStatePath = Web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.LOAD + '&' + UserAPI.QUERY.USER + '=' + this.sUserID + '&' + UserAPI.QUERY.STATE + '=' + State.key(this, PC8080.APPVERSION);\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(Computer8080.STATE_USERID + \" unavailable\");\n }\n }\n return sStatePath;\n }\n\n /**\n * saveServerState(sUserID, sState)\n *\n * @param {string} sUserID\n * @param {string|null} sState\n */\n saveServerState(sUserID, sState)\n {\n /*\n * We must pass fSync == true, because (as I understand it) browsers will blow off any async\n * requests when a page is being closed. Since our request is synchronous, storeServerState()\n * should also return a result, but there's not much we can do with it, since browsers ALSO\n * tend to blow off alerts() and the like when closing down.\n */\n if (sState) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"size of server state: \" + sState.length + \" bytes\");\n }\n var response = this.storeServerState(sUserID, sState, true);\n if (response && response[UserAPI.RES.CODE] == UserAPI.CODE.OK) {\n this.notice(\"Machine state saved to server\");\n } else if (sState) {\n var sError = (response && response[UserAPI.RES.DATA]) || UserAPI.FAIL.BADSTORE;\n if (response[UserAPI.RES.CODE] == UserAPI.CODE.FAIL) {\n sError = \"Error: \" + sError;\n } else {\n sError = \"Error \" + response[UserAPI.RES.CODE] + \": \" + sError;\n }\n this.notice(sError);\n this.resetUserID();\n }\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"no state to store\");\n }\n }\n }\n\n /**\n * storeServerState(sUserID, sState, fSync)\n *\n * @this {Computer8080}\n * @param {string} sUserID\n * @param {string} sState\n * @param {boolean} [fSync] is true if we're powering down and should perform a synchronous request (default is async)\n * @return {*} server response if fSync is true and a response was received; otherwise null\n */\n storeServerState(sUserID, sState, fSync)\n {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(Computer8080.STATE_USERID + \" for store: \" + sUserID);\n }\n /*\n * TODO: Determine whether or not any browsers cancel our request if we're called during a browser \"shutdown\" event,\n * and whether or not it matters if we do an async request (currently, we're not, to try to ensure the request goes through).\n */\n var dataPost = {};\n dataPost[UserAPI.QUERY.REQ] = UserAPI.REQ.STORE;\n dataPost[UserAPI.QUERY.USER] = sUserID;\n dataPost[UserAPI.QUERY.STATE] = State.key(this, PC8080.APPVERSION);\n dataPost[UserAPI.QUERY.DATA] = sState;\n var sRequest = Web.getHost() + UserAPI.ENDPOINT;\n if (!fSync) {\n Web.getResource(sRequest, dataPost, true);\n } else {\n var response = Web.getResource(sRequest, dataPost);\n var sResponse = response[0];\n if (response[1]) {\n if (sResponse) {\n var i = sResponse.indexOf('\\n');\n if (i > 0) sResponse = sResponse.substr(0, i);\n if (!sResponse.indexOf(\"Error: \")) sResponse = sResponse.substr(7);\n }\n sResponse = '{\"' + UserAPI.RES.CODE + '\":' + response[1] + ',\"' + UserAPI.RES.DATA + '\":\"' + sResponse + '\"}';\n }\n if (DEBUG && this.messageEnabled()) this.printMessage(sResponse);\n return JSON.parse(sResponse);\n }\n return null;\n }\n\n /**\n * onPower()\n *\n * This handles UI requests to toggle the computer's power (eg, see the \"power\" button binding).\n *\n * @this {Computer8080}\n */\n onPower()\n {\n if (!this.nPowerChange) {\n if (!this.flags.powered) {\n this.wait(this.powerOn);\n } else {\n this.powerOff(false, true);\n }\n }\n }\n\n /**\n * onReset()\n *\n * This handles UI requests to reset the computer's state (eg, see the \"reset\" button binding).\n *\n * @this {Computer8080}\n */\n onReset()\n {\n /*\n * I'm going to start with the presumption that it makes little sense for an \"unpowered\" computer to be \"reset\";\n * ditto if the power state is currently being changed.\n */\n if (!this.flags.powered || this.nPowerChange) return;\n\n /*\n * If this is a \"resumable\" machine (and it's not using a predefined state), then we overload the reset\n * operation to offer an explicit \"save or discard\" option first. This is currently the only UI we offer to\n * discard a machine's state, including any disk changes. The traditional \"reset\" operation is still available\n * for non-resumable machines.\n *\n * TODO: Break this behavior out into a separate \"discard\" operation, in case the designer of the machine really\n * wants to clutter the UI with confusing options. ;-)\n */\n if (this.resume && !this.sResumePath) {\n /*\n * I used to bypass the prompt if this.resume == Computer8080.RESUME_AUTO, setting fSave to true automatically,\n * but that gives the user no means of resetting a resumable machine that contains errors in its resume state.\n */\n var fSave = (/* this.resume == Computer8080.RESUME_AUTO || */ Component.confirmUser(\"Click OK to save changes to this \" + PC8080.APPNAME + \" machine.\\n\\nWARNING: If you CANCEL, all disk changes will be discarded.\"));\n this.powerOff(fSave, true);\n /*\n * Forcing the page to reload is an expedient option, but ugly. It's preferable to call powerOn()\n * and rely on all the components to reset themselves to their default state. The components with\n * the greatest burden here are FDC and HDC, which must rely on the fReload flag to determine whether\n * or not to unload/reload all their original auto-mounted disk images.\n *\n * However, if we started with a predefined state (ie, sStatePath is set), we take this shortcut, because\n * we don't (yet) have code in place to gracefully reload the initial state (requires calling getResource()\n * again); alternatively, we could avoid throwing that state away, but it seems better to save the memory.\n *\n * TODO: Make this more graceful, so that we can stop using the reloadPage() sledgehammer.\n */\n if (!fSave && this.sStatePath) {\n Web.reloadPage();\n return;\n }\n if (!fSave) this.fReload = true;\n this.powerOn(Computer8080.RESUME_NONE);\n this.fReload = false;\n } else {\n this.reset();\n if (this.cpu) this.cpu.autoStart();\n }\n }\n\n /**\n * getMachineComponent(sType, componentPrev)\n *\n * @this {Computer8080}\n * @param {string} sType\n * @param {Component|null} [componentPrev] of previously returned component, if any\n * @return {Component|null}\n */\n getMachineComponent(sType, componentPrev)\n {\n var componentLast = componentPrev;\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (componentPrev) {\n if (componentPrev == component) componentPrev = null;\n continue;\n }\n if (component.type == sType) return component;\n }\n if (!componentLast) Component.log(\"Machine component type '\" + sType + \"' not found\", \"warning\");\n return null;\n }\n\n /**\n * updateFocus(fScroll)\n *\n * NOTE: When soft keyboard buttons call us to return focus to the machine (and away from the button),\n * the browser's default behavior is to scroll the element into view, which can be annoying, especially on iOS,\n * where the display is more constrained, so we no longer do it by default (fScroll must be true).\n *\n * @this {Computer8080}\n * @param {boolean} [fScroll] (true if you really want the control scrolled into view)\n */\n updateFocus(fScroll)\n {\n if (this.aVideo.length) {\n /*\n * This seems to be recommended work-around to prevent the browser from scrolling the focused element\n * into view. The CPU is not a visual component, so when the CPU wants to set focus, the primary intent\n * is to ensure that keyboard input is fielded properly.\n */\n var x = 0, y = 0;\n if (!fScroll && window) {\n x = window.scrollX;\n y = window.scrollY;\n }\n\n /*\n * TODO: We need a mechanism to determine the \"active\" display, instead of hard-coding this to aVideo[0].\n */\n this.aVideo[0].setFocus();\n\n if (!fScroll && window) {\n window.scrollTo(x, y);\n }\n }\n }\n\n /**\n * updateStatus(fForce)\n *\n * If any DOM controls were bound to the CPU, then we need to call its updateStatus() handler; if there are no\n * such bindings, then cpu.updateStatus() does nothing.\n *\n * Similarly, if there's a Panel, then we need to call its updateStatus() handler, in case it created its own canvas\n * and implemented its own register display (eg, dumpRegisters()); if not, then panel.updateStatus() also does nothing.\n *\n * In practice, there will *either* be a Panel with a custom canvas *or* a set of DOM controls bound to the CPU *or*\n * neither. In theory, there could be BOTH, but that would be unusual.\n *\n * TODO: Consider alternate approaches to these largely register-oriented display updates. Ordinarily, we like to\n * separate logic from presentation, and currently the CPUState contains both, since it's the component that intimately\n * knows the names, number, sizes, etc, of all the active registers. The Panel component is the logical candidate,\n * but Panel is an optional component; generally, only machines that include Debugger also include Panel.\n *\n * @this {Computer8080}\n * @param {boolean} [fForce] (true will display registers even if the CPU is running and \"live\" registers are not enabled)\n */\n updateStatus(fForce)\n {\n /*\n * fForce is generally set to true whenever the CPU is transitioning to/from a running state, in which case\n * cpu.updateStatus() will definitely want to hide/show register contents; however, at other times, when the\n * CPU is running, constantly updating the DOM controls too frequently can adversely impact overall performance.\n *\n * So fForce serves as a hint to help cpu.updateStatus() make a more informed decision. panel.updateStatus()\n * currently doesn't care, on the theory that canvas updates should be significantly faster than DOM updates,\n * but we still pass fForce on.\n */\n if (this.cpu) this.cpu.updateStatus(fForce);\n if (this.panel) this.panel.updateStatus(fForce);\n }\n\n /**\n * updateVideo(fForced)\n *\n * Any high-frequency updates should be performed here (avoid updating DOM elements).\n *\n * @this {Computer8080}\n * @param {boolean} [fForced]\n */\n updateVideo(fForced)\n {\n for (var i = 0; i < this.aVideo.length; i++) {\n this.aVideo[i].updateScreen(fForced);\n }\n }\n\n /**\n * Computer8080.init()\n *\n * For every machine represented by an HTML element of class \"pc8080-machine\", this function\n * locates the HTML element of class \"computer\", extracting the JSON-encoded parameters for the\n * Computer constructor from the element's \"data-value\" attribute, invoking the constructor to\n * create a Computer component, and then binding any associated HTML controls to the new component.\n */\n static init()\n {\n /*\n * In non-COMPILED builds, embedMachine() may have set XMLVERSION.\n */\n if (!COMPILED && XMLVERSION) PC8080.APPVERSION = XMLVERSION;\n\n var aeMachines = Component.getElementsByClass(document, PC8080.APPCLASS + \"-machine\");\n\n for (var iMachine = 0; iMachine < aeMachines.length; iMachine++) {\n\n var eMachine = aeMachines[iMachine];\n var parmsMachine = Component.getComponentParms(eMachine);\n\n var aeComputers = Component.getElementsByClass(eMachine, PC8080.APPCLASS, \"computer\");\n\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n\n /*\n * We set fSuspended in the Computer constructor because we want to \"power up\" the\n * computer ourselves, after any/all bindings are in place.\n */\n var computer = new Computer8080(parmsComputer, parmsMachine, true);\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onInit(\" + computer.flags.powered + \")\");\n }\n\n /*\n * Bind any \"power\", \"reset\" and \"save\" buttons. An \"erase\" button was also considered,\n * but \"reset\" now provides a way to force the machine to start from scratch again, so \"erase\"\n * may be redundant now.\n */\n Component.bindComponentControls(computer, eComputer, PC8080.APPCLASS);\n\n /*\n * Power on the computer, giving every component the opportunity to reset or restore itself.\n */\n if (computer.fAutoPower) computer.wait(computer.powerOn);\n }\n }\n }\n\n /**\n * Computer8080.show()\n *\n * When exit() is using an \"onbeforeunload\" handler, this \"onpageshow\" handler allows us to repower everything,\n * without either resetting or restoring. We call powerOn() with a special resume value (RESUME_REPOWER) if the\n * computer is already marked as \"ready\", meaning the browser didn't change anything. This \"repower\" process\n * should be very quick, essentially just marking all components as powered again (so that, for example, the Video\n * component will start drawing again) and firing the CPU up again.\n */\n static show()\n {\n var aeComputers = Component.getElementsByClass(document, PC8080.APPCLASS, \"computer\");\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n var computer = /** @type {Computer8080} */ (Component.getComponentByType(\"Computer\", parmsComputer['id']));\n if (computer) {\n\n computer.flags.unloading = false;\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onShow(\" + computer.fInitialized + \",\" + computer.flags.powered + \")\");\n }\n\n /*\n * Note that the FIRST 'onpageshow' event, and therefore the first show() callback, occurs\n * AFTER the the initial 'onload' event, and at that point in time, fInitialized will not be set yet.\n * So, practically speaking, the first show() callback isn't all that useful.\n */\n if (computer.fInitialized && !computer.flags.powered) {\n /**\n * Repower the computer, notifying every component to continue running as-is.\n */\n computer.powerOn(Computer8080.RESUME_REPOWER);\n }\n }\n }\n }\n\n /**\n * Computer8080.exit()\n *\n * The Computer is currently the only component that uses an \"exit\" handler, which web.onExit() defines as\n * either an \"unload\" or \"onbeforeunload\" handler. This gives us the opportunity to save the machine state,\n * using our powerOff() function, before the page goes away.\n *\n * It's worth noting that \"onbeforeunload\" offers one nice feature when used instead of \"onload\": the entire\n * page (and therefore this entire application) is retained in its current state by the browser (well, some\n * browsers), so that if you go to a new URL, either by entering a new URL in the same window/tab, or by pressing\n * the FORWARD button, and then you press the BACK button, the page is immediately restored to its previous state.\n *\n * In fact, that's how some browsers operate whether you have an \"onbeforeunload\" handler or not; in other words,\n * an \"onbeforeunload\" handler doesn't change the page retention behavior of the browser. By contrast, the mere\n * presence of an \"onunload\" handler generally causes a browser to throw the page away once the handler returns.\n *\n * However, in order to safely use \"onbeforeunload\", we must add yet another handler (\"onpageshow\") to repower\n * everything, without either resetting or restoring. Hence, the Computer8080.show() function, which calls powerOn()\n * with a special resume value (RESUME_REPOWER) if the computer is already marked as \"ready\", meaning the browser\n * didn't change anything. This \"repower\" process should be very quick, essentially just marking all components as\n * powered again (so that, for example, the Video component will start drawing again) and firing the CPU up again.\n *\n * Reportedly, some browsers (eg, Opera) don't support \"onbeforeunload\", in which case Component will have to use\n * \"unload\" instead. But even when the page must be rebuilt from scratch, the combination of browser cache and\n * localStorage means the simulation should be restored and become operational almost immediately.\n */\n static exit()\n {\n var aeComputers = Component.getElementsByClass(document, PC8080.APPCLASS, \"computer\");\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n var computer = /** @type {Computer8080} */ (Component.getComponentByType(\"Computer\", parmsComputer['id']));\n if (computer) {\n\n /*\n * Added a new flag that Component functions (eg, notice()) should check before alerting the user.\n */\n computer.flags.unloading = true;\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onExit(\" + computer.flags.powered + \")\");\n }\n\n if (computer.flags.powered) {\n /**\n * Power off the computer, giving every component an opportunity to save its state,\n * but only if 'resume' has been set AND there is no valid resume path (because if a valid resume\n * path exists, we'll always load our state from there, and not from whatever we save here).\n */\n computer.powerOff(!!(computer.resume && !computer.sResumePath), true);\n }\n }\n }\n }\n}\n\nComputer8080.STATE_FAILSAFE = \"failsafe\";\nComputer8080.STATE_VALIDATE = \"validate\";\nComputer8080.STATE_TIMESTAMP = \"timestamp\";\nComputer8080.STATE_VERSION = \"version\";\nComputer8080.STATE_HOSTURL = \"url\";\nComputer8080.STATE_BROWSER = \"browser\";\nComputer8080.STATE_USERID = \"user\";\n\n/*\n * The following constants define all the resume options. Negative values (eg, RESUME_REPOWER) are for\n * internal use only, and RESUME_DELETE is not documented (it provides a way of deleting ALL saved states\n * whenever a resume is declined). As a result, the only \"end-user\" values are 0, 1 and 2.\n */\nComputer8080.RESUME_REPOWER = -1; // resume without changing any state (for internal use only)\nComputer8080.RESUME_NONE = 0; // default (no resume)\nComputer8080.RESUME_AUTO = 1; // automatically save/restore state\nComputer8080.RESUME_PROMPT = 2; // automatically save but conditionally restore (WARNING: if restore is declined, any state is discarded)\nComputer8080.RESUME_DELETE = 3; // same as RESUME_PROMPT but discards ALL machines states whenever ANY machine restore is declined (undocumented)\n\n/*\n * Initialize every Computer on the page.\n */\nWeb.onInit(Computer8080.init);\nWeb.onShow(Computer8080.show);\nWeb.onExit(Computer8080.exit);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/state.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass State {\n /**\n * State(component, sVersion, sSuffix)\n *\n * State objects are used by components to save/restore their state.\n *\n * During a save operation, components add data to a State object via set(), and then return\n * the resulting data using data().\n *\n * During a restore operation, the Computer component passes the results of each data() call\n * back to the originating component.\n *\n * WARNING: Since State objects are low-level objects that have no UI requirements, they do not\n * inherit from the Component class, so you should only use class methods of Component, such as\n * Component.assert() (or Debugger methods if the Debugger is available).\n *\n * NOTE: 1.01 is the first version to provide limited save/restore support using localStorage.\n * From that point on, care must be taken to insure that any new version that's incompatible with\n * previous localStorage data be released with a version number that is at least 1 greater,\n * since we're tagging the localStorage data with the integer portion of the version string.\n *\n * @param {Component} component\n * @param {string} [sVersion] is used to append a major version number to the key\n * @param {string} [sSuffix] is used to append any additional suffixes to the key\n */\n constructor(component, sVersion, sSuffix)\n {\n this.id = component.id;\n this.dbg = component.dbg;\n this.json = \"\";\n this.state = {};\n this.fLoaded = this.fParsed = false;\n this.key = State.key(component, sVersion, sSuffix);\n this.unload(component.parms);\n }\n\n /**\n * set(id, data)\n *\n * @this {State}\n * @param {number|string} id\n * @param {Object|string} data\n */\n set(id, data)\n {\n try {\n this.state[id] = data;\n } catch(e) {\n Component.log(e.message);\n }\n }\n\n /**\n * get(id)\n *\n * @this {State}\n * @param {number|string} id\n * @return {Object|string|null}\n */\n get(id)\n {\n return this.state[id] || null;\n }\n\n /**\n * data()\n *\n * @this {State}\n * @return {Object}\n */\n data()\n {\n return this.state;\n }\n\n /**\n * load(json)\n *\n * WARNING: Make sure you follow this call with either a call to parse() or unload(),\n * because any stringified data that we've loaded isn't usable until it's been parsed.\n *\n * @this {State}\n * @param {string|null} [json]\n * @return {boolean} true if state exists in localStorage, false if not\n */\n load(json)\n {\n if (json) {\n this.json = json;\n this.fLoaded = true;\n this.fParsed = false;\n return true;\n }\n if (this.fLoaded) {\n /*\n * This is assumed to be a redundant load().\n */\n return true;\n }\n if (Web.hasLocalStorage()) {\n var s = Web.getLocalStorageItem(this.key);\n if (s) {\n this.json = s;\n this.fLoaded = true;\n if (DEBUG) Component.log(\"localStorage(\" + this.key + \"): \" + s.length + \" bytes loaded\");\n return true;\n }\n }\n return false;\n }\n\n /**\n * parse()\n *\n * This completes the load() operation, by parsing what was loaded, on the assumption there\n * might be some benefit to deferring parsing until we've given the user a chance to confirm.\n * Otherwise, load() could have just as easily done this, too.\n *\n * @this {State}\n * @return {boolean} true if successful, false if error\n */\n parse()\n {\n var fSuccess = true;\n if (!this.fParsed) {\n try {\n this.state = JSON.parse(this.json);\n this.fParsed = true;\n } catch (e) {\n Component.error(e.message || e);\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * store()\n *\n * @this {State}\n * @return {boolean} true if successful, false if error\n */\n store()\n {\n var fSuccess = true;\n if (Web.hasLocalStorage()) {\n var s = JSON.stringify(this.state);\n if (Web.setLocalStorageItem(this.key, s)) {\n if (DEBUG) Component.log(\"localStorage(\" + this.key + \"): \" + s.length + \" bytes stored\");\n } else {\n /*\n * WARNING: Because browsers tend to disable all alerts() during an \"unload\" operation,\n * it's unlikely anyone will ever see the \"quota\" errors that occur at this point. Need to\n * think of some way to notify the user that there's a problem, and offer a way of cleaning\n * up old states.\n */\n Component.error(\"Unable to store \" + s.length + \" bytes in browser local storage\");\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * toString()\n *\n * @this {State}\n * @return {string} JSON-encoded state\n */\n toString()\n {\n return this.state? JSON.stringify(this.state) : this.json;\n }\n\n /**\n * unload(parms)\n *\n * This discards any data saved via set() or loaded via load(), creating an empty State object.\n * Note that you have to follow this call with an explicit call to store() if you want to remove\n * the state from localStorage as well.\n *\n * @this {State}\n * @param {Object} [parms]\n */\n unload(parms)\n {\n this.json = \"\";\n this.state = {};\n this.fLoaded = this.fParsed = false;\n if (parms) this.set(\"parms\", parms);\n }\n\n /**\n * clear(fAll)\n *\n * This unloads the current state, and then clears ALL localStorage for the current machine,\n * independent of version, to reduce the chance of orphaned states wasting part of our limited allocation.\n *\n * @this {State}\n * @param {boolean} [fAll] true to unconditionally clear ALL localStorage for the current domain\n */\n clear(fAll)\n {\n this.unload();\n var aKeys = Web.getLocalStorageKeys();\n for (var i = 0; i < aKeys.length; i++) {\n var sKey = aKeys[i];\n if (sKey && (fAll || sKey.substr(0, this.key.length) == this.key)) {\n Web.removeLocalStorageItem(sKey);\n if (DEBUG) Component.log(\"localStorage(\" + sKey + \") removed\");\n aKeys.splice(i, 1);\n i = 0;\n }\n }\n }\n\n /**\n * State.key(component, sVersion, sSuffix)\n *\n * This encapsulates the key generation code.\n *\n * @param {Component} component\n * @param {string} [sVersion] is used to append a major version number to the key\n * @param {string} [sSuffix] is used to append any additional suffixes to the key\n * @return {string} key\n */\n static key(component, sVersion, sSuffix)\n {\n var key = component.id;\n if (sVersion) {\n var i = sVersion.indexOf('.');\n if (i > 0) key += \".v\" + sVersion.substr(0, i);\n }\n if (sSuffix) {\n key += \".\" + sSuffix;\n }\n return key;\n }\n\n /**\n * State.compress(aSrc)\n *\n * @param {Array.<number>|null} aSrc\n * @return {Array.<number>|null} is either the original array (aSrc), or a smaller array of \"count, value\" pairs (aComp)\n */\n static compress(aSrc)\n {\n if (aSrc) {\n var iSrc = 0;\n var iComp = 0;\n var aComp = [];\n while (iSrc < aSrc.length) {\n var n = aSrc[iSrc];\n\n var iCompare = iSrc + 1;\n while (iCompare < aSrc.length && aSrc[iCompare] === n) iCompare++;\n aComp[iComp++] = iCompare - iSrc;\n aComp[iComp++] = n;\n iSrc = iCompare;\n }\n if (aComp.length < aSrc.length) return aComp;\n }\n return aSrc;\n }\n\n /**\n * State.decompress(aComp)\n *\n * @param {Array.<number>} aComp\n * @param {number} nLength is expected length of decompressed data\n * @return {Array.<number>}\n */\n static decompress(aComp, nLength)\n {\n var iDst = 0;\n var aDst = new Array(nLength);\n var iComp = 0;\n while (iComp < aComp.length - 1) {\n var c = aComp[iComp++];\n var n = aComp[iComp++];\n while (c--) {\n aDst[iDst++] = n;\n }\n }\n\n return aDst;\n }\n\n /**\n * State.compressEvenOdd(aSrc)\n *\n * This is a very simple variation on compress() that compresses all the EVEN elements of aSrc first,\n * followed by all the ODD elements. This tends to work better on EGA video memory, because when odd/even\n * addressing is enabled (eg, for text modes), the DWORD values tend to alternate, which is the worst case\n * for compress(), but the best case for compressEvenOdd().\n *\n * One wrinkle we support: if the first element is uninitialized, then we assume the entire array is undefined,\n * and return an empty compressed array. Conversely, decompressEvenOdd() will take an empty compressed array\n * and return an uninitialized array.\n *\n * @param {Array.<number>|null} aSrc\n * @return {Array.<number>|null} is either the original array (aSrc), or a smaller array of \"count, value\" pairs (aComp)\n */\n static compressEvenOdd(aSrc)\n {\n if (aSrc) {\n var iComp = 0, aComp = [];\n if (aSrc[0] !== undefined) {\n for (var off = 0; off < 2; off++) {\n var iSrc = off;\n while (iSrc < aSrc.length) {\n var n = aSrc[iSrc];\n var iCompare = iSrc + 2;\n while (iCompare < aSrc.length && aSrc[iCompare] === n) iCompare += 2;\n aComp[iComp++] = (iCompare - iSrc) >> 1;\n aComp[iComp++] = n;\n iSrc = iCompare;\n }\n }\n }\n if (aComp.length < aSrc.length) return aComp;\n }\n return aSrc;\n }\n\n /**\n * State.decompressEvenOdd(aComp, nLength)\n *\n * This is the counterpart to compressEvenOdd(). Note that because there's nothing in the compressed sequence\n * that differentiates a compress() sequence from a compressEvenOdd() sequence, you simply have to be consistent:\n * if you used even/odd compression, then you must use even/odd decompression.\n *\n * @param {Array.<number>} aComp\n * @param {number} nLength is expected length of decompressed data\n * @return {Array.<number>}\n */\n static decompressEvenOdd(aComp, nLength)\n {\n var iDst = 0;\n var aDst = new Array(nLength);\n var iComp = 0;\n while (iComp < aComp.length - 1) {\n var c = aComp[iComp++];\n var n = aComp[iComp++];\n while (c--) {\n aDst[iDst] = n;\n iDst += 2;\n }\n /*\n * The output of a \"count,value\" pair will never exceed the end of the output array, so as soon as we reach it\n * the first time, we know it's time to switch to ODD elements, and as soon as we reach it again, we should be\n * done.\n */\n\n if (iDst == nLength) iDst = 1;\n }\n\n return aDst;\n }\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/embed.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * We now support asynchronous XML and XSL file loads; simply set fAsync (below) to true.\n *\n * NOTE: For that support to work, we have to keep track of the number of machines on the page\n * (ie, how many embedMachine() calls were issued), reduce the count as each machine XML file\n * is fully transformed into HTML, and when the count finally returns to zero, notify all the\n * machine component init() handlers.\n *\n * Also, to prevent those init() handlers from running prematurely, we must disable all page\n * notification events at the start of the embedding process (Web.enablePageEvents(false)) and\n * re-enable them at the end (Web.enablePageEvents(true)).\n */\nvar fAsync = true;\nvar cAsyncMachines = 0;\n\n/**\n * loadXML(sFile, idMachine, sAppName, sAppClass, sParms, fResolve, display, done)\n *\n * This is the preferred way to load all XML and XSL files. It uses getResource()\n * to load them as strings, which parseXML() can massage before parsing/transforming them.\n *\n * For example, since I've been unable to get the XSLT document() function to work inside any\n * XSL document loaded by JavaScript's XSLT processor, that has prevented me from dynamically\n * loading any XML machine file that uses the \"ref\" attribute to refer to and incorporate\n * another XML document.\n *\n * To solve that, I've added an fResolve parameter that tells parseXML() to fetch any\n * referenced documents ITSELF and insert them into the XML string prior to parsing, instead\n * of relying on the XSLT template to pull them in. That fetching is handled by resolveXML(),\n * which iterates over the XML until all \"refs\" have been resolved (including any nested\n * references).\n *\n * Also, XSL files with a <!DOCTYPE [...]> cause MSIE's Microsoft.XMLDOM.loadXML() function\n * to choke, so I strip that out prior to parsing as well.\n *\n * TODO: Figure out why the XSLT document() function works great when the web browser loads an\n * XML file (and the associated XSL file) itself, but does not work when loading documents via\n * JavaScript XSLT support. Is it broken, is it a security issue, or am I just calling it wrong?\n *\n * @param {string} sXMLFile\n * @param {string|null|undefined} idMachine\n * @param {string|null|undefined} sAppName\n * @param {string|null|undefined} sAppClass\n * @param {string|null|undefined} sParms (machine parameters, if any)\n * @param {string|null|undefined} sClass (an optional machine class name used to style the machine)\n * @param {boolean} fResolve is true to resolve any \"ref\" attributes\n * @param {function(string)} display\n * @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)\n */\nfunction loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n{\n var doneLoadXML = function(sURLName, sXML, nErrorCode) {\n if (nErrorCode) {\n if (!sXML) sXML = \"unable to load \" + sXMLFile + \" (\" + nErrorCode + \")\";\n done(sXML, null);\n return;\n }\n parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done);\n };\n display(\"Loading \" + sXMLFile + \"...\");\n Web.getResource(sXMLFile, null, fAsync, doneLoadXML);\n}\n\n/**\n * parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n *\n * Generates an XML document from an XML string. This function also provides a work-around for XSLT's\n * lack of support for the document() function (at least on some browsers), by replacing every reference\n * tag (ie, a tag with a \"ref\" attribute) with the contents of the referenced file.\n *\n * @param {string} sXML\n * @param {string|null} sXMLFile\n * @param {string|null|undefined} idMachine\n * @param {string|null|undefined} sAppName\n * @param {string|null|undefined} sAppClass\n * @param {string|null|undefined} sParms (machine parameters, if any)\n * @param {string|null|undefined} sClass (an optional machine class name used to style the machine)\n * @param {boolean} fResolve is true to resolve any \"ref\" attributes; default is false\n * @param {function(string)} display\n * @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)\n */\nfunction parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n{\n var buildXML = function(sXML, sError) {\n if (sError) {\n done(sError, null);\n return;\n }\n if (idMachine) {\n\n /*\n * A more sensible place to record the machine XML would be embedMachine(), like we do for the\n * XSL file, but since we're about to modify the original machine XML, it's best to record it now.\n */\n Component.addMachineResource(idMachine, sXMLFile, sXML);\n\n var sURL = sXMLFile;\n if (sURL && sURL.indexOf('/') < 0 && window.location.pathname.slice(-1) == '/') {\n sURL = window.location.pathname + sURL;\n }\n /*\n * We embed the URL of the XML file both as a separate \"xml\" attribute for easy access from the\n * XSL file, and as part of the \"parms\" attribute for easy access from machines (see getMachineParm()).\n */\n if (!sParms) {\n sParms = '{';\n } else if (sParms.slice(-1) == '}') {\n sParms = sParms.slice(0, -1);\n if (sParms.length > 1) sParms += ',';\n } else { // sParms must just be a \"state\" file, so encode it as a \"state\" property\n sParms = '{state:\"' + sParms + '\",';\n }\n sParms += 'url:\"' + sURL + '\"}';\n /*\n * Note that while we no longer generate a machine XML file with a \"state\" attribute (because it's\n * encoded inside the \"parms\" attribute), the XSL file must still cope with \"state\" attributes inside\n * other XML files; for example, manifest XML files like /apps/pcx86/1981/visicalc/manifest.xml contain\n * machine elements with \"state\" attributes that must still be passed down to the computer element\n * \"the old fashioned way\".\n *\n * Until/unless that changes, components.xsl cannot be simplified as much as I might have hoped.\n */\n if (typeof resources == 'object') sURL = null; // turn off URL inclusion if we have embedded resources\n sParms = sParms.replace(/\\$/g, \"$$$$\");\n if (sClass) {\n /*\n * If there's no hard-coded \"class\" attribute in the machine tag, then we can set one in the final\n * replacement below, just like we do for sParms and sURL. However, if a \"class\" attribute already\n * exists, we need alter it and then zap the sClass variable.\n */\n var match = sXML.match(/(<machine[^>]*\\sclass=)(['\"])(.*?)(\\2.*?>)/);\n if (match) {\n sXML = sXML.replace(match[0], match[1] + match[2] + sClass + match[4]);\n sClass = null;\n }\n }\n sXML = sXML.replace(/(<machine[^>]*\\sid=)(['\"]).*?\\2/, \"$1$2\" + idMachine + \"$2\" + (sClass? ' class=\"' + sClass + '\"' : '') + (sParms? \" parms='\" + sParms + \"'\" : \"\") + (sURL? ' url=\"' + sURL + '\"' : ''));\n }\n\n if (!fResolve) {\n /*\n * I'm trying to switch to a shared components.xsl (at least for all PC-class machines),\n * but in the interim, that means hacking the XSL file on the fly to reflect the actual class.\n */\n sXML = sXML.replace(/(<xsl:variable name=\"APPNAME\">).*?(<\\/xsl:variable>)/, \"$1\" + sAppName + \"$2\");\n sXML = sXML.replace(/(<xsl:variable name=\"APPCLASS\">).*?(<\\/xsl:variable>)/, \"$1\" + sAppClass + \"$2\");\n\n /*\n * Non-COMPILED kludge to replace the version number template in the XSL file (which we assume we're reading,\n * since fResolve is false) with whatever XMLVERSION we extracted from the XML file (see corresponding kludge below).\n *\n * ES6 ALERT: Template strings.\n */\n if (!COMPILED && XMLVERSION) {\n sXML = sXML.replace(/<xsl:variable name=\"APPVERSION\"\\/>/, `<xsl:variable name=\"APPVERSION\">${XMLVERSION}</xsl:variable>`);\n }\n }\n\n /*\n * If the resource we requested is not really an XML file (or the file didn't exist and the server simply returned\n * a message like \"Cannot GET /devices/pc/machine/5150/cga/64kb/donkey/machine.xml\"), we'd like to display a more\n * meaningful message, because the XML DOM parsers will blithely return a document that contains nothing useful; eg:\n *\n * This page contains the following errors:error on line 1 at column 1:\n * Document is empty Below is a rendering of the page up to the first error.\n *\n * Supposedly, the IE XML DOM parser will throw an exception, but I haven't tested that, and unless all other\n * browsers do that, that's not helpful.\n *\n * The best I can do at this stage (assuming Web.getResource() didn't drop any error information on the floor)\n * is verify that the requested resource \"looks like\" valid XML (in other words, it begins with a '<').\n */\n var xmlDoc = null;\n if (sXML.charAt(0) == '<') {\n try {\n /*\n * Another hack for MSIE, which fails to load XSL documents containing a <!DOCTYPE [...]> tag.\n *\n * This is also why the XSLTProcessor 'transformToFragment' method in Microsoft Edge silently failed,\n * so I had pull this hack out of the \"ActiveXObject\" code. And rather than add yet-another Microsoft\n * browser check, I'm going to try doing this across the board, and hope that none of the other XSLT\n * processors fail *without* the DOCTYPE tag.\n */\n if (!fResolve) {\n sXML = sXML.replace(/<!DOCTYPE(.|[\\r\\n])*]>\\s*/g, \"\");\n }\n /*\n * Beginning with Microsoft Edge and the corresponding release of Windows 10, all the\n * 'ActiveXObject' crud has gone away; but of course, this code must remain in place if\n * we want to continue supporting older Internet Explorer browsers (ie, back to IE9).\n */\n /** @namespace window.ActiveXObject */\n if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1\n xmlDoc = new window.ActiveXObject(\"Microsoft.XMLDOM\");\n xmlDoc.async = false;\n xmlDoc['loadXML'](sXML);\n } else {\n /** @namespace window.DOMParser */\n xmlDoc = (new window.DOMParser()).parseFromString(sXML, \"text/xml\");\n }\n } catch(e) {\n xmlDoc = null;\n sXML = e.message;\n }\n } else {\n sXML = \"unrecognized XML: \" + (sXML.length > 255? sXML.substr(0, 255) + \"...\" : sXML);\n }\n done(sXML, xmlDoc);\n };\n if (sXML) {\n if (PRIVATE) sXML = sXML.replace(/\\/library.xml/, \"/private/library.xml\");\n if (fResolve) {\n resolveXML(sXML, display, buildXML);\n return;\n }\n buildXML(sXML, null);\n return;\n }\n done(\"no data\" + (sXMLFile? \" for file: \" + sXMLFile : \"\"), null);\n}\n\n/**\n * resolveXML(sXML, display, done)\n *\n * Replaces every tag with a \"ref\" attribute with the contents of the corresponding file.\n *\n * TODO: Fix some of the limitations of this code, such as: 1) requiring the \"ref\" attribute\n * to appear as the tag's first attribute, 2) requiring the \"ref\" attribute to be double-quoted,\n * and 3) requiring the \"ref\" tag to be self-closing.\n *\n * @param {string} sXML\n * @param {function(string)} display\n * @param {function(string,(string|null))} done (the first string contains the resolved XML data, the second is for any error message)\n */\nfunction resolveXML(sXML, display, done)\n{\n var matchRef;\n var reRef = /<([a-z]+)\\s+ref=\"(.*?)\"(.*?)\\/>/g;\n\n if ((matchRef = reRef.exec(sXML))) {\n\n var sRefFile = matchRef[2];\n\n var doneReadXML = function(sURLName, sXMLRef, nErrorCode) {\n if (nErrorCode || !sXMLRef) {\n done(sXML, \"unable to resolve XML reference: \" + matchRef[0] + \" (\" + nErrorCode + \")\");\n return;\n }\n /*\n * If there are additional attributes in the \"referring\" XML tag, we want to insert them\n * into the \"referred\" XML tag; attributes that don't exist in the referred tag should be\n * appended, and attributes that DO exist should be overwritten.\n */\n var sRefAttrs = matchRef[3];\n if (sRefAttrs) {\n var aXMLRefTag = sXMLRef.match(new RegExp(\"<\" + matchRef[1] + \"[^>]*>\"));\n if (aXMLRefTag) {\n var sXMLNewTag = aXMLRefTag[0];\n /*\n * Iterate over all the attributes in the \"referring\" XML tag (sRefAttrs)\n */\n var matchAttr;\n var reAttr = /( [a-z]+=)(['\"])(.*?)\\2/gi;\n while ((matchAttr = reAttr.exec(sRefAttrs))) {\n if (sXMLNewTag.toLowerCase().indexOf(matchAttr[1].toLowerCase()) < 0) {\n /*\n * This is the append case....\n */\n sXMLNewTag = sXMLNewTag.replace(\">\", matchAttr[0] + \">\");\n } else {\n /*\n * This is the overwrite case....\n */\n sXMLNewTag = sXMLNewTag.replace(new RegExp(matchAttr[1] + \"(['\\\"])(.*?)\\\\1\"), matchAttr[0]);\n }\n }\n if (aXMLRefTag[0] != sXMLNewTag) {\n sXMLRef = sXMLRef.replace(aXMLRefTag[0], sXMLNewTag);\n }\n } else {\n done(sXML, \"missing <\" + matchRef[1] + \"> in \" + sRefFile);\n return;\n }\n }\n\n /*\n * Apparently when a Windows Azure server delivers one of my XML files, it may modify the first line:\n *\n * <?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n\n *\n * I didn't determine exactly what it was doing at this point (probably just changing the \\n to \\r\\n),\n * but in any case, relaxing the following replace() solved it.\n */\n sXMLRef = sXMLRef.replace(/<\\?xml[^>]*>[\\r\\n]*/, \"\");\n\n sXML = sXML.replace(matchRef[0], sXMLRef);\n\n resolveXML(sXML, display, done);\n };\n\n display(\"Loading \" + sRefFile + \"...\");\n Web.getResource(sRefFile, null, fAsync, doneReadXML);\n return;\n }\n done(sXML, null);\n}\n\n/**\n * embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * This allows to you embed a machine on a web page, by transforming the machine XML into HTML.\n *\n * @param {string} sAppName is the app name (eg, \"PCx86\")\n * @param {string} sAppClass is the app class (eg, \"pcx86\"); also known as the machine class\n * @param {string} sVersion is the app version (eg, \"1.15.7\")\n * @param {string} idMachine\n * @param {string|undefined} sXMLFile\n * @param {string|undefined} sXSLFile\n * @param {string|undefined} sParms (machine parameters, if any)\n * @param {string|undefined} sClass (an optional machine class name used to style the machine)\n * @return {boolean} true if successful, false if error\n */\nfunction embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n var eMachine, eWarning, fSuccess = true;\n\n if (!sXMLFile) {\n sXMLFile = \"machine.xml\";\n if (!sXSLFile) sXSLFile = \"components.xsl\";\n }\n \n cAsyncMachines++;\n Component.addMachine(idMachine);\n\n var doneMachine = function() {\n\n if (!--cAsyncMachines) {\n if (fAsync) Web.enablePageEvents(true);\n }\n };\n\n var displayError = function(sError) {\n Component.log(sError);\n displayMessage(\"Error: \" + sError);\n if (fSuccess) doneMachine();\n fSuccess = false;\n };\n\n var displayMessage = function(sMessage) {\n if (eWarning === undefined) {\n /*\n * Our MarkOut module (in convertMDMachineLinks()) creates machine containers that look like:\n *\n * <div id=\"' + sMachineID + '\" class=\"machine-placeholder\"><p>Embedded PC</p><p class=\"machine-warning\">...</p></div>\n *\n * with the \"machine-warning\" paragraph pre-populated with a warning message that the user will\n * see if nothing at all happens. But hopefully, in the normal case (and especially the error case),\n * *something* will have happened.\n *\n * Note that it is the HTMLOut module (in processMachines()) that ultimately decides which scripts to\n * include and then generates the embedXXX() call.\n */\n var aeWarning = (eMachine && Component.getElementsByClass(eMachine, \"machine-warning\"));\n eWarning = (aeWarning && aeWarning[0]) || eMachine;\n }\n if (eWarning) eWarning.innerHTML = Str.escapeHTML(sMessage);\n };\n\n try {\n eMachine = document.getElementById(idMachine);\n if (eMachine) {\n\n /*\n * If we have a 'css' resource, add it to the page first.\n */\n var css;\n if (typeof resources == \"object\" && (css = resources['css'])) {\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n // noinspection JSDeprecatedSymbols\n if (style.styleSheet) {\n // noinspection JSDeprecatedSymbols\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n head.appendChild(style);\n }\n\n if (!sXSLFile) {\n /*\n * Now that PCjs is an open-source project, we can make the following test more flexible,\n * and revert to the internal template if DEBUG *or* internal version (instead of *and*).\n *\n * Third-party sites that don't use the PCjs server will ALWAYS want to specify a fully-qualified\n * path to the XSL file, unless they choose to mirror our folder structure.\n */\n var sAppFolder = sAppClass;\n if (DEBUG || !sVersion) {\n if (sAppClass != \"c1pjs\") sAppFolder = \"shared\";\n sXSLFile = \"/modules/\" + sAppFolder + \"/templates/components.xsl\";\n } else {\n if (sAppClass.substr(0, 3) == \"pdp\") sAppFolder = \"pdpjs\";\n sXSLFile = \"/versions/\" + sAppFolder + \"/\" + sVersion + \"/components.xsl\";\n }\n }\n\n var processXML = function(sXML, xml) {\n if (!xml) {\n displayError(sXML);\n return;\n }\n\n /*\n * Non-COMPILED kludge to extract the version number from the stylesheet path in the machine XML file;\n * we don't need this code in COMPILED (non-DEBUG) releases, because APPVERSION is hard-coded into them.\n */\n if (!COMPILED) {\n var aMatch = sXML.match(/<\\?xml-stylesheet[^>]* href=(['\"])[^'\"]*?\\/([0-9.]*)\\/([^'\"]*)\\1/);\n if (aMatch) {\n XMLVERSION = aMatch[2];\n }\n }\n\n var transformXML = function(sXSL, xsl) {\n if (!xsl) {\n displayError(sXSL);\n return;\n }\n\n /*\n * Record the XSL file, in case someone wants to save the entire machine later.\n * \n * NOTE: sXSLFile will never be undefined by this point, but apparently the Closure Compiler doesn't realize that. \n */\n Component.addMachineResource(idMachine, sXSLFile || \"\", sXSL);\n\n /*\n * The <machine> template in components.xsl now generates a \"machine div\" that makes\n * the div we required the caller of embedMachine() to provide redundant, so instead\n * of appending this fragment to the caller's node, we REPLACE the caller's node.\n * This works only because because we ALSO inject the caller's \"machine div\" ID into\n * the fragment's ID during parseXML().\n *\n * eMachine.innerHTML = sFragment;\n *\n * Also, if the transform function fails, make sure you're using the appropriate\n * \"components.xsl\" and not a \"machine.xsl\", because the latter will not produce valid\n * embeddable HTML (and is the most common cause of failure at this final stage).\n */\n displayMessage(\"Processing \" + sXMLFile + \"...\");\n\n /*\n * Beginning with Microsoft Edge and the corresponding release of Windows 10, all the\n * 'ActiveXObject' crud has gone away; but of course, this code must remain in place if\n * we want to continue supporting older Internet Explorer browsers (ie, back to IE9).\n */\n if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1\n var sFragment = xml['transformNode'](xsl);\n if (sFragment) {\n eMachine.outerHTML = sFragment;\n doneMachine();\n } else {\n displayError(\"transformNodeToObject failed\");\n }\n }\n else if (document.implementation && document.implementation.createDocument) {\n var xsltProcessor = new XSLTProcessor();\n xsltProcessor['importStylesheet'](xsl);\n var eFragment = xsltProcessor['transformToFragment'](xml, document);\n if (eFragment) {\n /*\n * This fails in Microsoft Edge...\n *\n var machine = eFragment.getElementById(idMachine);\n if (!machine) {\n displayError(\"machine generation failed: \" + idMachine);\n } else\n */\n if (eMachine.parentNode) {\n eMachine.parentNode.replaceChild(eFragment, eMachine);\n doneMachine();\n } else {\n /*\n * NOTE: This error can occur if our Node web server, when processing a folder with\n * both a manifest.xml with a machine.xml reference AND a README.md containing a\n * machine link, generates duplicate embedXXX() calls for the same machine; if the\n * first embedXXX() call finds its target, subsequent calls for the same target will\n * fail.\n *\n * Technically, such a folder is in a misconfigured state, but it happens, in part\n * because when we switched to the Jekyll web server, we had to add machine links to\n * all README.md files where we had previously relied on manifest.xml or machine.xml\n * processing. This is because the Jekyll web server currently doesn't process XML\n * files, nor is support for that likely to be added any time soon; it was a nice\n * feature of the Node web server, but it's not clear that it's worth doing for Jekyll.\n */\n displayError(\"invalid machine element: \" + idMachine);\n }\n } else {\n displayError(\"transformToFragment failed\");\n }\n } else {\n /*\n * Perhaps I should have performed this test at the outset; on the other hand, I'm\n * not aware of any browsers don't support one or both of the above XSLT transformation\n * methods, so treat this as a bug.\n */\n displayError(\"unable to transform XML: unsupported browser\");\n }\n };\n /*\n * NOTE: sXSLFile will never be undefined by this point, but apparently the Closure Compiler doesn't realize that. \n */\n loadXML(sXSLFile || \"\", null, sAppName, sAppClass, null, null, false, displayMessage, transformXML);\n };\n\n if (sXMLFile.charAt(0) != '<') {\n loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, true, displayMessage, processXML);\n } else {\n parseXML(sXMLFile, null, idMachine, sAppName, sAppClass, sParms, sClass, false, displayMessage, processXML);\n }\n } else {\n displayError(\"missing machine element: \" + idMachine);\n }\n } catch(e) {\n displayError(e.message);\n }\n return fSuccess;\n}\n\n/**\n * embedC1P(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedC1P(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"C1Pjs\", \"c1pjs\", APPVERSION, idMachine, sXMLFile, sXSLFile, undefined, sClass);\n}\n\n/**\n * embedPCx86(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPCx86(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PCx86\", \"pcx86\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPC8080(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPC8080(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PC8080\", \"pc8080\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPDP10(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPDP10(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PDPjs\", \"pdp10\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPDP11(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPDP11(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PDPjs\", \"pdp11\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * findMachineComponent(idMachine, sType)\n *\n * @param {string} idMachine\n * @param {string} sType\n * @return {Component|null}\n */\nfunction findMachineComponent(idMachine, sType)\n{\n return Component.getComponentByType(sType, idMachine + \".machine\");\n}\n\n/**\n * commandMachine(control, fSingle, idMachine, sComponent, sCommand, sValue)\n *\n * Use Component methods to find the requested component for a specific machine, and if the component is found,\n * then check its 'exports' table for an entry matching the specified command string, and if an entry is found, then\n * the corresponding function is called with the specified data.\n *\n * @param {Object} control\n * @param {boolean} fSingle\n * @param {string} idMachine\n * @param {string} sComponent\n * @param {string} sCommand\n * @param {string} [sValue]\n * @return {boolean}\n */\nfunction commandMachine(control, fSingle, idMachine, sComponent, sCommand, sValue)\n{\n if (sCommand == \"script\") {\n if (Component.processScript(idMachine, sValue)) {\n if (fSingle) control.disabled = true;\n return true;\n }\n return false;\n }\n if (sComponent) {\n var component = Component.getComponentByType(sComponent, idMachine + \".machine\");\n if (component) {\n var exports = component['exports'];\n if (exports) {\n var fnCommand = exports[sCommand];\n if (fnCommand) {\n if (fnCommand.call(component, sValue)) {\n if (fSingle) control.disabled = true;\n return true;\n }\n return false;\n }\n }\n }\n }\n console.log(\"unimplemented: commandMachine('\" + idMachine + \"','\" + sComponent + \"','\" + sCommand + \"','\" + sValue + \"')\");\n return false;\n}\n\n/**\n * Prevent the Closure Compiler from renaming functions we want to export, by adding them as global properties.\n *\n * TODO: Consider making all these functions properties on a single global object (eg, 'PCjs'), to minimize global\n * pollution and risk of name collision.\n */\nif (APPNAME == \"C1Pjs\") {\n window['embedC1P'] = embedC1P;\n}\nif (APPNAME == \"PCx86\") {\n window['embedPC'] = embedPCx86; // WARNING: embedPC() deprecated as of v1.23.0\n window['embedPCx86'] = embedPCx86;\n}\nif (APPNAME == \"PC8080\") {\n window['embedPC8080'] = embedPC8080;\n}\nif (APPNAME == \"PDPjs\") {\n window['embedPDP10'] = embedPDP10;\n window['embedPDP11'] = embedPDP11;\n}\n\nwindow['commandMachine'] = commandMachine;\n\nwindow['enableEvents'] = Web.enablePageEvents;\nwindow['sendEvent'] = Web.sendPageEvent;\n"]} \ No newline at end of file +{"version":3,"file":"pc8080.js","lineCount":315,"mappings":"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","sources":["versions/pc8080/1.61.0/pc8080-uncompiled.js"," [synthetic:util/objectcreate] "," [synthetic:es6/util/setprototypeof] "," [synthetic:es6/util/inherits] "," [synthetic:util/defineproperty] "," [synthetic:util/global] "," [synthetic:util/polyfill] "," [synthetic:es6/math/trunc] "," [synthetic:es6/number/parseint] "],"names":["$jscomp.objectCreate","$jscomp.setPrototypeOf","$jscomp.defineProperty","$jscomp.global","$jscomp.polyfill","ASCII","BREAK","CTRL_A","CTRL_B","CTRL_C","CTRL_D","CTRL_E","CTRL_F","CTRL_G","CTRL_H","CTRL_I","CTRL_J","CTRL_K","CTRL_L","CTRL_M","CTRL_N","CTRL_O","CTRL_P","CTRL_Q","CTRL_R","CTRL_S","CTRL_T","CTRL_U","CTRL_V","CTRL_W","CTRL_X","CTRL_Y","CTRL_Z","ESC","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","DEL","Keys.FF_KEYCODES","KEYCODE","parseInt","base","chPrefix","fCommas","indexOf","replace","ch","charAt","substr","chSuffix","slice","shift","match","isNaN","Math","pow","trunc","value","toBase","radix","cch","sPrefix","nGrouping","ceil","log","String","fromCharCode","toHex","fPrefix","abs","Str.toBase","toHexByte","Str.toHex","toHexWord","getBaseName","sFileName","sBaseName","lastIndexOf","getExtension","sExtension","toLowerCase","endsWith","Web.getHost","sSuffix","length","escapeHTML","sHTML","Str.HTMLEscapeMap","pad","sPadding","trim","prototype","Str.ASCIICodeMap","binarySearch","fnCompare","left","right","found","undefined","middle","compareResult","formatDate","date","sDate","Date","iHour","getHours","iDay","getDate","iMonth","getMonth","sFormat","Usr.asDays","getDay","Usr.asMonths","getMinutes","getSeconds","getFullYear","Array","getResource","sURL","type","fAsync","done","callback","request","readyState","resource","fArrayBuffer","response","responseText","err","status","window","location","protocol","nErrorCode","resources","XMLHttpRequest","ActiveXObject","fXHR2","responseType","onreadystatechange","sPost","hasOwnProperty","encodeURIComponent","open","setRequestHeader","send","overrideMimeType","parseMemoryResource","sData","aBytes","aSymbols","addrLoad","addrExec","ib","Error","data","JSON","parse","eval","aData","Component.alertUser","message","ab","asHexData","sHexData","split","push","getHost","host","SITEHOST","getUserAgent","navigator","userAgent","hasLocalStorage","Web.fLocalStorage","localStorage","setItem","Web.sLocalStorageTest","getItem","removeItem","getLocalStorageItem","sKey","sValue","setLocalStorageItem","isUserAgent","Web.getUserAgent","findProperty","obj","sProp","Web.asBrowserPrefixes.length","sName","Web.asBrowserPrefixes","toUpperCase","getURLParm","sParm","Web.parmsURL","sParms","aParms","search","pl","exec","decodeURIComponent","onCountRepeat","fnRepeat","fnComplete","fnTimeout","doCountRepeat","setTimeout","onClickRepeat","fn","doClickRepeat","msRepeat","ms","timer","fIgnoreMouseEvents","onmousedown","e.onmousedown","msDelay","ontouchstart","e.ontouchstart","onmouseup","onmouseout","e.onmouseout","clearTimeout","ontouchend","ontouchcancel","e.ontouchcancel","onPageEvent","sFunc","fnPrev","onInit","Web.aPageEventHandlers","doPageEvent","afn","Web.fPageEventsEnabled","Component.notice","fPrintOnly","id","enablePageEvents","fEnable","Web.fPageLoaded","Web.sendPageEvent","Web.fPageShowed","sendPageEvent","sEvent","Web.doPageEvent","Web.onPageEvent","onPageLoad","onPageShow","Web.isUserAgent","onPageUnload","constructor","Component","parms","bitsMessage","name","comment","bindings","idComponent","idMachine","flags","ready","busy","busyCancel","initDone","powered","unloading","error","fnReady","clearError","dbg","cpu","bus","cmp","Component.components.push","component","addMachineResource","Component.machines","getTime","now","notice","alertUser","sMessage","alert","confirmUser","sPrompt","fResponse","confirm","appendControl","control","sText","scrollTop","scrollHeight","bindComponentControls","element","aeControls","Component.getElementsByClass","parentNode","iControl","aeChildNodes","childNodes","iNode","nodeType","sClass","getAttribute","aClasses","iClass","Component.getComponentParms","setBinding","getComponents","idRelated","aComponents","Component.components.length","Component.components","getComponentByID","getComponentByType","sType","componentPrev","getComponentParms","getElementsByClass","sObjClass","getElementsByClassName","ae","aeAll","getElementsByTagName","re","RegExp","test","className","processCommands","fSuccess","aCommands","Component.commands","aTokens","splice","sCommand","fnCallReady","Component.asyncCommands.indexOf","processNextCommand","Component.processCommands","fnCommand","Component.globalCommands","Component.getComponentByType","Component.componentCommands","exports","call","Component.prototype","?.prototype","toString","sHTMLType","sBinding","onclick","clearControl","this.notice","println","print","printControl","Component.appendControl","printlnControl","Component.PRINT.PROGRESS","computer","console","setError","isReady","setReady","isBusy","fCancel","setBusy","fBusy","powerUp","powerDown","fSave","fShutdown","messageEnabled","bitsEnabled","printMessage","fAddress","printMessageIO","port","bOut","addrFrom","bIn","messageIO","PROGRESS","Component.asyncCommands","scriptAlert","scriptSleep","fnCallback","sDelay","scriptSelect","aBindings","options","textContent","selectedIndex","Array.prototype.indexOf","start","isArray","Array.isArray","arg","Object","Function","bind","Function.prototype.bind","fnBound","fToBind","apply","fnNOP","args","concat","arguments","TypeError","TYPEDARRAYS","ArrayBuffer","PARITY","Messages8080.CATEGORIES","CPU","BUS","MEM","PORT","NVR","CHIPSET","KEYBOARD","KEYS","VIDEO","FDC","DISK","SERIAL","SPEAKER","COMPUTER","BUFFER","WARN","HALT","Panel8080","parmsPanel","$jscomp.inherits","kbd","initBus","getMachineComponent","fRepower","Panel8080.init","init","fReady","aePanels","document","APPCLASS","iPanel","ePanel","panel","Component.getComponentByID","Component.bindComponentControls","Web.onInit","Bus8080","parmsBus","nBusWidth","addrTotal","nBusMask","nBlockShift","nBlockSize","nBlockLen","nBlockLimit","nBlockTotal","nBlockMask","aPortInputNotify","aPortOutputNotify","fPortInputBreakAll","fPortOutputBreakAll","aPortInputWidth","aPortOutputWidth","block","Memory8080","copyBreakpoints","initMemory","aMemBlocks","iBlock","reset","addMemory","addr","size","addrNext","sizeLeft","addrBlock","sizeBlock","used","sizeAvail","reportError","Bus8080.ERROR.ADD_MEM_INUSE","blockNew","floor","Memory8080.TYPE.NAMES","Str.toHexWord","Bus8080.ERROR.ADD_MEM_BADRANGE","getByteDirect","readByteDirect","getShort","off","readShort","readByte","getShortDirect","readShortDirect","setByteDirect","writeByteDirect","setShort","writeShort","writeByte","removeMemBreak","fWrite","removeBreakpoint","cWriteBreakpoints","resetWriteAccess","fReadOnly","writeNone","writeShortDefault","writeShortDirect","cReadBreakpoints","resetReadAccess","saveMemory","fDirty","fDirtyEver","save","iSrc","iComp","aComp","aSrc","iCompare","addPortInputBreak","addPortInputTable","table","offset","addPortInputNotify","end","checkPortInputNotify","addrIP","aNotify","sizePort","maskPort","dataPort","checkPortInput","addPortOutputBreak","addPortOutputTable","addPortOutputNotify","checkPortOutputNotify","checkPortOutput","op","ADD_MEM_INUSE","ADD_MEM_BADRANGE","buffer","setUint16","DataView","Uint16Array","littleEndian","Memory8080.idBlock","adw","Memory8080.TYPE.NONE","Memory8080.TYPE.ROM","dv","Uint8Array","aw","Int32Array","setAccess","Memory8080.afnArrayLE","Memory8080.afnArrayBE","Memory8080.afnMemory","Memory8080.prototype","getInt32","restore","setInt32","Memory8080.afnNone","setReadAccess","fDirect","setWriteAccess","readNone","readShortDefault","addBreakpoint","Memory8080.afnChecked","mem","readByteMemory","readShortMemory","idw","nShift","dw","writeByteMemory","writeShortMemory","readByteChecked","checkBreakpoint","aBreakRead","stopCPU","readShortChecked","nb","writeByteChecked","aBreakWrite","writeShortChecked","readByteBE","readByteLE","readShortBE","getUint16","readShortLE","writeByteBE","writeByteLE","writeShortBE","writeShortLE","NONE","ROM","NAMES","CPU8080","parmsCPU","nCyclesDefault","nMultiplier","nCyclesPerSecond","nCyclesMultiplier","mhzDefault","round","mhzTarget","running","starting","autoStart","displayLiveRegs","checksum","nChecksum","nCyclesChecksumNext","nCyclesChecksumStart","nCyclesChecksumInterval","nCyclesChecksumStop","aTimers","onRunTimeout","runCPU","CPU8080.prototype","CPU8080.BUTTONS.length","CPU8080.BUTTONS","chipset","sAutoStart","getMachineParm","resetCycles","resetChecksum","updateStatus","sInitCommands","sCmds","doCommands","updateCPU","getChecksum","nTotalCycles","updateChecksum","nCycles","fDisplay","getCycles","displayChecksum","fBound","control.onclick","iComponent","Component.getComponents","setSpeed","getSpeedTarget","toFixed","addCycles","fEndStep","nBurstCycles","nStepCycles","calcCycles","fRecalc","vMultiplier","mhz","msPerYield","CPU8080.YIELDS_PER_SECOND","nCyclesPerYield","nCyclesNextYield","nCyclesRecalc","nRunCycles","nYieldsSinceStatusUpdate","fUpdateFocus","sSpeed","controlSpeed","updateFocus","msStartRun","Component.getTime","msEndThisRun","addTimer","callBack","iTimer","setTimer","getMSCycles","endBurst","fReset","CPU8080_prototype$runCPU","startCPU","controlRun","calcStartTime","nCyclesThisRun","msStartThisRun","msDelta","getBurstCycles","stepCPU","updateTimers","CPU8080.YIELDS_PER_STATUS","stop","stack","calcRemainingTime","msYield","msRemainsThisRun","msElapsed","CPU8080_prototype$stepCPU","fComplete","complete","fForce","aVideo","updateScreen","CPUState8080","model","MODEL_8080","initProcessor","aOps","CPUDef8080.aOps8080","debugCheck","cLiveRegs","afnHalt","addrReset","resetRegs","addHaltCheck","CPUState8080.prototype","regA","regB","regC","regD","regE","regH","regL","setSP","regSP","setPC","setPS","intFlags","INTFLAG","setReset","sum","getSP","getPC","regPC","getPS","state","State","set","getSpeed","iDst","aDst","getBC","setBC","getDE","setDE","getHL","setHL","getCF","resultZeroCarry","PS","updateCF","CF","getPF","CPUDef8080.PARITY","resultParitySign","getAF","resultAuxOverflow","getZF","getSF","regPS","addByte","src","addByteCarry","andByte","decByte","incByte","orByte","subByte","subByteBorrow","xorByte","getByte","setByte","getPCByte","getPCWord","getWord","popWord","pushWord","setWord","checkINTR","getIF","nLevel","clearINTR","bitsClear","clearIF","OPCODE","requestINTR","updateReg","sReg","nValue","displayValue","sVal","nMinCycles","fDebugCheck","checksEnabled","nDebugState","checkInstruction","aeCPUs","iCPU","eCPU","CPUDef8080.opNOP","CPUDef8080.opJMP","CPUDef8080.opRET","CPUDef8080.opCALL","CPUDef8080.opLXIB","CPUDef8080.opSTAXB","CPUDef8080.opINXB","CPUDef8080.opINRB","CPUDef8080.opDCRB","CPUDef8080.opMVIB","CPUDef8080.opRLC","carry","CPUDef8080.opDADB","CPUDef8080.opLDAXB","CPUDef8080.opDCXB","CPUDef8080.opINRC","CPUDef8080.opDCRC","CPUDef8080.opMVIC","CPUDef8080.opRRC","CPUDef8080.opLXID","CPUDef8080.opSTAXD","CPUDef8080.opINXD","CPUDef8080.opINRD","CPUDef8080.opDCRD","CPUDef8080.opMVID","CPUDef8080.opRAL","CPUDef8080.opDADD","CPUDef8080.opLDAXD","CPUDef8080.opDCXD","CPUDef8080.opINRE","CPUDef8080.opDCRE","CPUDef8080.opMVIE","CPUDef8080.opRAR","CPUDef8080.opLXIH","CPUDef8080.opSHLD","CPUDef8080.opINXH","CPUDef8080.opINRH","CPUDef8080.opDCRH","CPUDef8080.opMVIH","CPUDef8080.opDAA","AF","CPUDef8080.opDADH","CPUDef8080.opLHLD","CPUDef8080.opDCXH","CPUDef8080.opINRL","CPUDef8080.opDCRL","CPUDef8080.opMVIL","CPUDef8080.opCMA","CPUDef8080.opLXISP","CPUDef8080.opSTA","CPUDef8080.opINXSP","CPUDef8080.opINRM","CPUDef8080.opDCRM","CPUDef8080.opMVIM","CPUDef8080.opSTC","setCF","CPUDef8080.opDADSP","CPUDef8080.opLDA","CPUDef8080.opDCXSP","CPUDef8080.opINRA","CPUDef8080.opDCRA","CPUDef8080.opMVIA","CPUDef8080.opCMC","CPUDef8080.opMOVBB","CPUDef8080.opMOVBC","CPUDef8080.opMOVBD","CPUDef8080.opMOVBE","CPUDef8080.opMOVBH","CPUDef8080.opMOVBL","CPUDef8080.opMOVBM","CPUDef8080.opMOVBA","CPUDef8080.opMOVCB","CPUDef8080.opMOVCC","CPUDef8080.opMOVCD","CPUDef8080.opMOVCE","CPUDef8080.opMOVCH","CPUDef8080.opMOVCL","CPUDef8080.opMOVCM","CPUDef8080.opMOVCA","CPUDef8080.opMOVDB","CPUDef8080.opMOVDC","CPUDef8080.opMOVDD","CPUDef8080.opMOVDE","CPUDef8080.opMOVDH","CPUDef8080.opMOVDL","CPUDef8080.opMOVDM","CPUDef8080.opMOVDA","CPUDef8080.opMOVEB","CPUDef8080.opMOVEC","CPUDef8080.opMOVED","CPUDef8080.opMOVEE","CPUDef8080.opMOVEH","CPUDef8080.opMOVEL","CPUDef8080.opMOVEM","CPUDef8080.opMOVEA","CPUDef8080.opMOVHB","CPUDef8080.opMOVHC","CPUDef8080.opMOVHD","CPUDef8080.opMOVHE","CPUDef8080.opMOVHH","CPUDef8080.opMOVHL","CPUDef8080.opMOVHM","CPUDef8080.opMOVHA","CPUDef8080.opMOVLB","CPUDef8080.opMOVLC","CPUDef8080.opMOVLD","CPUDef8080.opMOVLE","CPUDef8080.opMOVLH","CPUDef8080.opMOVLL","CPUDef8080.opMOVLM","CPUDef8080.opMOVLA","CPUDef8080.opMOVMB","CPUDef8080.opMOVMC","CPUDef8080.opMOVMD","CPUDef8080.opMOVME","CPUDef8080.opMOVMH","CPUDef8080.opMOVML","CPUDef8080.opHLT","requestHALT","CPUDef8080.opMOVMA","CPUDef8080.opMOVAB","CPUDef8080.opMOVAC","CPUDef8080.opMOVAD","CPUDef8080.opMOVAE","CPUDef8080.opMOVAH","CPUDef8080.opMOVAL","CPUDef8080.opMOVAM","CPUDef8080.opMOVAA","CPUDef8080.opADDB","CPUDef8080.opADDC","CPUDef8080.opADDD","CPUDef8080.opADDE","CPUDef8080.opADDH","CPUDef8080.opADDL","CPUDef8080.opADDM","CPUDef8080.opADDA","CPUDef8080.opADCB","CPUDef8080.opADCC","CPUDef8080.opADCD","CPUDef8080.opADCE","CPUDef8080.opADCH","CPUDef8080.opADCL","CPUDef8080.opADCM","CPUDef8080.opADCA","CPUDef8080.opSUBB","CPUDef8080.opSUBC","CPUDef8080.opSUBD","CPUDef8080.opSUBE","CPUDef8080.opSUBH","CPUDef8080.opSUBL","CPUDef8080.opSUBM","CPUDef8080.opSUBA","CPUDef8080.opSBBB","CPUDef8080.opSBBC","CPUDef8080.opSBBD","CPUDef8080.opSBBE","CPUDef8080.opSBBH","CPUDef8080.opSBBL","CPUDef8080.opSBBM","CPUDef8080.opSBBA","CPUDef8080.opANAB","CPUDef8080.opANAC","CPUDef8080.opANAD","CPUDef8080.opANAE","CPUDef8080.opANAH","CPUDef8080.opANAL","CPUDef8080.opANAM","CPUDef8080.opANAA","CPUDef8080.opXRAB","CPUDef8080.opXRAC","CPUDef8080.opXRAD","CPUDef8080.opXRAE","CPUDef8080.opXRAH","CPUDef8080.opXRAL","CPUDef8080.opXRAM","CPUDef8080.opXRAA","CPUDef8080.opORAB","CPUDef8080.opORAC","CPUDef8080.opORAD","CPUDef8080.opORAE","CPUDef8080.opORAH","CPUDef8080.opORAL","CPUDef8080.opORAM","CPUDef8080.opORAA","CPUDef8080.opCMPB","CPUDef8080.opCMPC","CPUDef8080.opCMPD","CPUDef8080.opCMPE","CPUDef8080.opCMPH","CPUDef8080.opCMPL","CPUDef8080.opCMPM","CPUDef8080.opCMPA","CPUDef8080.opRNZ","CPUDef8080.opPOPB","CPUDef8080.opJNZ","CPUDef8080.opCNZ","CPUDef8080.opPUSHB","CPUDef8080.opADI","CPUDef8080.opRST0","CPUDef8080.opRZ","CPUDef8080.opJZ","CPUDef8080.opCZ","CPUDef8080.opACI","CPUDef8080.opRST1","CPUDef8080.opRNC","CPUDef8080.opPOPD","CPUDef8080.opJNC","CPUDef8080.opOUT","offPC","CPUDef8080.opCNC","CPUDef8080.opPUSHD","CPUDef8080.opSUI","CPUDef8080.opRST2","CPUDef8080.opRC","CPUDef8080.opJC","CPUDef8080.opIN","CPUDef8080.opCC","CPUDef8080.opSBI","CPUDef8080.opRST3","CPUDef8080.opRPO","CPUDef8080.opPOPH","CPUDef8080.opJPO","CPUDef8080.opXTHL","CPUDef8080.opCPO","CPUDef8080.opPUSHH","CPUDef8080.opANI","CPUDef8080.opRST4","CPUDef8080.opRPE","CPUDef8080.opPCHL","CPUDef8080.opJPE","CPUDef8080.opXCHG","CPUDef8080.opCPE","CPUDef8080.opXRI","CPUDef8080.opRST5","CPUDef8080.opRP","CPUDef8080.opPOPSW","setPSW","CPUDef8080.opJP","CPUDef8080.opDI","CPUDef8080.opCP","CPUDef8080.opPUPSW","getPSW","CPUDef8080.opORI","CPUDef8080.opRST6","CPUDef8080.opRM","CPUDef8080.opSPHL","CPUDef8080.opJM","CPUDef8080.opEI","setIF","CPUDef8080.opCM","CPUDef8080.opCPI","CPUDef8080.opRST7","ChipSet8080","parmsChipSet","ChipSet8080.MODELS","config","classAudio","ChipSet8080.prototype","serial","video","portsInput","portsOutput","messageDump","onDumpNVR","sDump","iWord","aNVRWords","INIT","MODEL","ChipSet8080.SI1978.MODEL","bStatus0","bStatus1","bStatus2","wShiftData","bShiftCount","bSound1","bSound2","ChipSet8080.VT100.MODEL","bBrightness","bFlags","bDC011Cols","bDC011Rate","bDC012Scroll","bDC012Blink","bDC012Reverse","bDC012Attr","dNVRAddr","wNVRData","bNVRLatch","bNVROut","inSIStatus0","inSIStatus1","inSIStatus2","inSIShiftResult","outSIShiftCount","outSISound1","outSIShiftData","outSISound2","outSIWatchdog","getNVRAddr","tens","ones","inVT100Flags","ChipSet8080.VT100.FLAGS.NVR_CLK","FLAGS","NVR_CLK","getVT100LBA","bit","doNVRCommand","bCmd","ChipSet8080.VT100.NVR.CMD.STANDBY","CMD","STANDBY","ChipSet8080.VT100.NVR.CMD.ACCEPT_ADDR","ACCEPT_ADDR","ChipSet8080.VT100.NVR.CMD.ERASE","ERASE","ChipSet8080.VT100.NVR.WORDMASK","WORDMASK","ChipSet8080.VT100.NVR.CMD.ACCEPT_DATA","ACCEPT_DATA","ChipSet8080.VT100.NVR.CMD.WRITE","WRITE","ChipSet8080.VT100.NVR.CMD.READ","READ","ChipSet8080.VT100.NVR.CMD.SHIFT_OUT","SHIFT_OUT","Str.toHexByte","ChipSet8080.VT100.FLAGS.NVR_DATA","NVR_DATA","ChipSet8080.VT100.FLAGS.KBD_XMIT","KBD_XMIT","fVT100UARTBusy","ChipSet8080.VT100.FLAGS.UART_XMIT","UART_XMIT","bStatus","SerialPort8080.UART8251.STATUS.XMIT_READY","outVT100Brightness","outVT100NVRLatch","outVT100DC012","bOpt","bScroll","bScrollOffset","fSkipSingleCellUpdate","outVT100DC011","ChipSet8080.VT100.DC011.RATE60","DC011","RATE60","ChipSet8080.VT100.DC011.RATE50","RATE50","nRate","rateMonitor","ChipSet8080.VT100.DC011.COLS132","COLS132","nCols","nRows","ChipSet8080.VT100.FLAGS.NO_AVO","NO_AVO","nColsBuffer","cxCell","cxCellDefault","initBuffers","createFonts","ChipSet8080.SI1978","STATUS0","DIP4","FIRE","LEFT","RIGHT","PORT7","ALWAYS_SET","STATUS1","CREDIT","P2","P1","P1_FIRE","P1_LEFT","P1_RIGHT","STATUS2","DIP3_5","TILT","DIP6","P2_FIRE","P2_LEFT","P2_RIGHT","DIP7","SHIFT_RESULT","SHIFT_COUNT","MASK","SOUND1","UFO","SHOT","PDEATH","IDEATH","EXPLAY","AMP_ENABLE","SHIFT_DATA","SOUND2","FLEET1","FLEET2","FLEET3","FLEET4","UFO_HIT","ChipSet8080.VT100","NO_GFX","OPTION","NO_EVEN","BRIGHTNESS","COLS80","INITCOLS","INITRATE","DC012","SCROLL_LO","INITSCROLL","INITBLINK","INITREVERSE","INITATTR","LATCH","ChipSet8080.SI1978.INIT","ChipSet8080.SI1978.STATUS0.ALWAYS_SET","ChipSet8080.SI1978.STATUS1.ALWAYS_SET","ChipSet8080.SI1978.STATUS2.ALWAYS_SET","ChipSet8080.VT100.INIT","ChipSet8080.VT100.BRIGHTNESS.INIT","ChipSet8080.VT100.FLAGS.NO_GFX","ChipSet8080.VT100.DC011.INITCOLS","ChipSet8080.VT100.DC011.INITRATE","ChipSet8080.VT100.DC012.INITSCROLL","ChipSet8080.VT100.DC012.INITBLINK","ChipSet8080.VT100.DC012.INITREVERSE","ChipSet8080.VT100.DC012.INITATTR","ChipSet8080.SI1978.portsInput","ChipSet8080.SI1978.portsOutput","ChipSet8080.VT100.portsInput","ChipSet8080.VT100.portsOutput","aeChipSet","iChip","eChipSet","ROM8080","parmsROM","abROM","addrROM","sizeROM","addrAlias","sFilePath","Str.getBaseName","sFileURL","sFileExt","Str.getExtension","FORMAT","rom","Web.getResource","sResponse","doneLoad","copyROM","aOffsets","sSymbol","symbol","offSymbol","sAnnotation","index","Usr.binarySearch","comparePairs","aSymbolTable","symbolTable","sModule","len","sROMData","Component.addMachineResource","Str.parseInt","addROM","aliases","cloneROM","aBlocks","aeROM","iROM","eROM","RAM8080","parmsRAM","abInit","addrRAM","sizeRAM","fAllocated","ram","Web.parseMemoryResource","initRAM","RAM","RAM8080.CPM.INIT","RAM8080.CPM.VECTORS.length","RAM8080.CPM.VECTORS","RAM8080.CPM.VECTORS.indexOf","fCPM","RAM8080.CPM.BDOS.VECTOR","RAM8080.CPM.BDOS.FUNC.CON_WRITE","RAM8080.CPM.BDOS.FUNC.STR_WRITE","cchMax","bEnd","CPUDef8080.opRET.call","VECTOR","BDOS","CON_WRITE","STR_WRITE","BIOS","aeRAM","iRAM","eRAM","Keyboard8080","parmsKbd","Keyboard8080.MODELS","Keyboard8080.prototype","LEDCODES","onkeypress","control.onkeypress","event","fShifted","bMapping","CHARMAP","keyCode","charCode","KEYMAP","softCode","onSoftKeyDown","onkeydown","control.onkeydown","oniOSKeyDown","onkeyup","control.onkeyup","onKeyDown","Keys.ASCII.A","Keys.ASCII.Z","bitsState","Keyboard8080.STATE.SHIFTS","Keyboard8080.STATE.CAPS_LOCK","updateLEDs","Keys.ASCII.a","Keys.ASCII.z","onpaste","control.onpaste","sendData","stopPropagation","clipboardData","preventDefault","transmitData","getData","SOFTCODES","onKeyboardBindingDown","fDown","Keyboard8080.STATE.CTRL","style","fontWeight","checkModifierKeys","timerReleaseKeys","checkSoftKeysToRelease","aKeysActive","Keyboard8080.VT100.MODEL","bVT100Status","bVT100Address","nVT100UARTCycleSnap","Keyboard8080.SI1978.MODEL","Keyboard8080.VT100.STATUS.LEDS","STATUS","LEDS","iKeyNext","bLEDs","bitLED","fOn","backgroundColor","color","fRight","Keyboard8080.STATE.RSHIFT","Keyboard8080.STATE.SHIFT","Keyboard8080.STATE.RCTRL","Keyboard8080.STATE.RALT","Keyboard8080.STATE.ALT","Keyboard8080.STATE.RCMD","Keyboard8080.STATE.CMD","fPass","LOCATION","getSoftCode","ALTCODES","sSoftCode","metaKey","fRemapped","Keyboard8080.STATE.ALTS","Keyboard8080.STATE.REMAPPED","Keyboard8080.STATE.CTRLS","fAutoRelease","indexOfSoftKey","msDown","Keyboard8080.MINPRESSTIME","ChipSet8080.SI1978.STATUS1.P1","ChipSet8080.SI1978.STATUS1.P2","ChipSet8080.SI1978.STATUS1.CREDIT","ChipSet8080.SI1978.STATUS1.P1_LEFT","ChipSet8080.SI1978.STATUS1.P1_RIGHT","ChipSet8080.SI1978.STATUS1.P1_FIRE","msDelayMin","inVT100UARTAddress","key","Keyboard8080.VT100.KEYMAP","Keyboard8080.VT100.KEYLAST","KEYLAST","outVT100UARTStatus","Keyboard8080.VT100.STATUS.START","START","RSHIFT","SHIFT","SHIFTS","RCTRL","CTRL","CTRLS","RALT","ALT","ALTS","RCMD","CAPS_LOCK","REMAPPED","Keyboard8080.WASDCODES","Keys.ASCII.D","Keys.ASCII.L","Keyboard8080.SI1978","Keyboard8080.VT100","Keys.ASCII.P","Keys.ASCII.O","Keys.ASCII.Y","Keys.ASCII.T","Keys.ASCII.W","Keys.ASCII.Q","Keys.ASCII.I","Keys.ASCII.U","Keys.ASCII.R","Keys.ASCII.E","Keys.ASCII.K","Keys.ASCII.G","Keys.ASCII.F","Keys.KEYCODE.NUM_CR","Keys.ASCII.J","Keys.ASCII.H","Keys.ASCII.S","Keys.ASCII.N","Keys.ASCII.B","Keys.ASCII.X","Keys.ASCII.M","Keys.ASCII","Keys.ASCII.V","Keys.ASCII.C","Keys.ASCII.p","Keys.ASCII.o","Keys.ASCII.y","Keys.ASCII.t","Keys.ASCII.w","Keys.ASCII.q","Keys.ASCII.i","Keys.ASCII.u","Keys.ASCII.r","Keys.ASCII.e","Keys.ASCII.l","Keys.ASCII.k","Keys.ASCII.g","Keys.ASCII.f","Keys.ASCII.j","Keys.ASCII.h","Keys.ASCII.d","Keys.ASCII.s","Keys.ASCII.n","Keys.ASCII.b","Keys.ASCII.x","Keys.ASCII.m","Keys.ASCII.v","Keys.ASCII.c","ADDRESS","LED4","LED3","LED2","LED1","LOCKED","LOCAL","CLICK","Keyboard8080.VT100.LEDCODES","Keyboard8080.VT100.STATUS.LED4","Keyboard8080.VT100.STATUS.LED3","Keyboard8080.VT100.STATUS.LED2","Keyboard8080.VT100.STATUS.LED1","Keyboard8080.VT100.STATUS.LOCKED","Keyboard8080.VT100.STATUS.LOCAL","Keyboard8080.VT100.INIT","Keyboard8080.VT100.STATUS.INIT","Keyboard8080.VT100.ADDRESS.INIT","Keyboard8080.VT100.portsInput","Keyboard8080.VT100.portsOutput","aeKbd","iKbd","eKbd","Video8080","parmsVideo","canvas","context","textarea","container","fGecko","cxScreen","cyScreen","addrBuffer","fUseRAM","nFormat","Video8080.FORMATS","Video8080.FORMAT.UNKNOWN","nRowsBuffer","cyCell","abFontData","fDotStretcher","nBitsPerPixel","iBitFirstPixel","rotateBuffer","rateInterrupt","rateRefresh","canvasScreen","contextScreen","inputScreen","textareaScreen","cxScreenOffset","cyScreenOffset","cxScreenCell","cyScreenCell","fSmoothing","sSmoothing","Web.getURLParm","Web.findProperty","rotateScreen","translate","rotate","PI","scale","doFullScreen","sFullScreen","addEventListener","onFullScreenChange","notifyFullScreen","onFullScreenError","sFontROM","ledBindings","cxBuffer","cyBuffer","sizeBuffer","imageBuffer","createImageData","nPixelsPerCell","initCellCache","canvasBuffer","createElement","width","height","contextBuffer","getContext","aFonts","initColors","nColors","aRGB","Video8080.COLORS.OVERLAY_TOTAL","rgbBlack","rgbWhite","Video8080.FORMAT.SI1978","Video8080.COLORS.OVERLAY_TOP","rgbYellow","Video8080.COLORS.OVERLAY_BOTTOM","rgbGreen","Video8080.FORMAT.VT100","fUnderline","abLineBuffer","Video8080.prototype","removeChild","timerUpdateNext","max","getRefreshTime","nUpdates","sFontData","Video8080.VT100.FONT.NORML","createFontVariation","Video8080.VT100.FONT.DWIDE","Video8080.VT100.FONT.DHIGH","Video8080.VT100.FONT.DHIGH_BOT","nFontBytesPerChar","nFontByteOffset","nChars","fReverse","font","imageChar","iChar","yDst","offFontData","bits","bitPrev","xDst","bitReal","setPixel","putImageData","sWidth","screen","aspectPhys","aspectVirt","display","margin","sHeight","setFocus","focus","fFullScreen","nCells","nCellCache","fCellCacheValid","aCellCache","image","bPixel","rgb","fForced","fUpdate","fClean","updateScreenText","fontNext","nFill","cUpdated","iCell","iCellUpdated","nColsVisible","Video8080.VT100.LINETERM","Video8080.VT100.LINEATTR.FONTMASK","Video8080.VT100.LINEATTR.ADDRMASK","Video8080.VT100.LINEATTR.ADDRBIAS","Video8080.VT100.ADDRBIAS_LO","Video8080.VT100.ADDRBIAS_HI","fLineCacheValid","iCol","bChar","xSrc","ySrc","cxSrc","cySrc","cxDst","cyDst","drawImage","xScreenOffset","yScreenOffset","updateScreenGraphics","addrLimit","yBuffer","xBuffer","xDirty","xMaxDirty","yDirty","nShiftInit","yMaxDirty","nShiftPixel","nMask","cPixels","cxDirty","xDirtyOrig","cxDirtyOrig","cyDirty","OVERLAY_TOP","OVERLAY_BOTTOM","OVERLAY_TOTAL","UNKNOWN","SI1978","VT100","NORML","FONT","DWIDE","DHIGH","DHIGH_BOT","LINETERM","ADDRMASK","LINEATTR","ADDRBIAS","FONTMASK","ADDRBIAS_LO","ADDRBIAS_HI","aeVideo","iVideo","eVideo","eCanvas","innerHTML","setAttribute","onresize","eParent","eChild","cx","cy","onResizeVideo","clientWidth","aspect","aspectRatio","onResizeWindow","appendChild","eTextArea","fontSize","eContext","SerialPort8080","parmsSerial","iAdapter","portBase","nIRQ","controlBuffer","consoleBuffer","tabSize","charBOL","iLogicalCol","fAutoStop","fNullModem","target","sDataReceived","connection","initConnection","receiveData","receiveStatus","SerialPort8080.prototype","ctrlKey","receiveByte","which","removeAttribute","timerReceiveNext","timerTransmitNext","SerialPort8080.aPortInput","SerialPort8080.aPortOutput","sConnection","asParts","sSourceID","Str.trim","sTargetID","fnConnect","initState","saveRegisters","bDataIn","bDataOut","bMode","bCommand","bBaudRates","SerialPort8080.UART8251.INIT","getBaudTimeout","maskRate","indexRate","nBaud","SerialPort8080.UART8251.BAUDTABLE","nBits","SerialPort8080.UART8251.MODE.DATA_BITS","SerialPort8080.UART8251.MODE.PARITY_ENABLE","SerialPort8080.UART8251.MODE.STOP_BITS","SerialPort8080.UART8251.STATUS.RECV_FULL","charCodeAt","SerialPort8080.UART8251.BAUDRATES.RECV_RATE","pins","SerialPort8080.UART8251.STATUS.DSR","DSR","SerialPort8080.UART8251.STATUS.XMIT_EMPTY","inData","inControl","outData","transmitByte","CR","LF","Str.pad","SerialPort8080.UART8251.BAUDRATES.XMIT_RATE","outControl","SerialPort8080.UART8251.COMMAND.RTS","SerialPort8080.UART8251.COMMAND.DTR","CTS","RTS","DTR","SerialPort8080.UART8251.COMMAND.INTERNAL_RESET","outBaudRates","DATA_BITS","MODE","PARITY_ENABLE","STOP_BITS","COMMAND","INTERNAL_RESET","XMIT_READY","RECV_FULL","XMIT_EMPTY","RECV_RATE","BAUDRATES","XMIT_RATE","BAUDTABLE","aeSerial","iSerial","eSerial","Debugger","parmsDbg","nBase","achGroup","achAddress","cOpcodes","cOpcodesStart","fAssemble","iPrevCmd","aPrevCmds","aVariables","getRegIndex","getRegValue","parseCommand","sCmd","chSep","iPrev","chQuote","substring","truncate","fUnsigned","vNew","limit","evalOps","aVals","cOps","chOp","pop","val2","val1","valNew","parseArray","asValues","iValue","iLimit","aUndefined","fError","nUnary","nBasePrev","sOp","parseValue","cOpen","iStart","parseUnary","aBinOp","Debugger.aDECOpPrecedence","Debugger.aBinOpPrecedence","parseASCII","sExp","chDelim","toStrBase","parseExpression","fQuiet","fPrint","join","regExp","printValue","parseReference","chOpen","chClose","chEscape","chInnerEscape","reSubExp","sReplace","sAddr","parseSysVars","iReg","getVariable","sVar","sUndefined","getVariableFixup","valueUndefined","fDefined","printVariable","cVariables","aVars","keys","sort","Debugger8080","Debugger8080.STYLE_8080","dbgAddrNextCode","newAddr","dbgAddrNextData","dbgAddrAssemble","aBreakExec","clearBreakpoints","nBreakIns","historyInit","afnDumpers","messageInit","global","Debugger8080.prototype","sMessages","aaOpDescs","Debugger8080.aaOpDescs","onDumpBus","asArgs","getAddr","parseAddr","ADDR_INVALID","typePrev","cPrev","controlDebug","setSelectionRange","Web.onClickRepeat","onClickDebugEnter","onClickStep","fRepeat","fCompleted","dbgAddr","Debugger8080_prototype$getByte","inc","incAddr","Debugger8080_prototype$getShort","Debugger8080_prototype$setByte","Debugger8080_prototype$setShort","fTemporary","unpackAddr","aAddr","fCode","dbgAddrNext","sUpperCase","iTable","findSymbolAddr","parseAddrOptions","sOptions","aCmds","toHexAddr","getSZ","sEnable","sMessagePrev","aMessageBuffer","aEnable","Usr.indexOf","bitMessage","fnDumper","Debugger8080.REGS","getRegString","Debugger8080.REG_A","Debugger8080.REG_B","Debugger8080.REG_C","Debugger8080.REG_D","Debugger8080.REG_E","Debugger8080.REG_H","Debugger8080.REG_L","Debugger8080.REG_M","Debugger8080.REG_BC","Debugger8080.REG_DE","Debugger8080.REG_HL","Debugger8080.REG_SP","Debugger8080.REG_PC","Debugger8080.REG_PS","Debugger8080.REG_PSW","replaceRegs","sChar","aOpcodeHistory","Debugger8080.HISTORY_LIMIT","iOpcodeHistory","aaOpcodeCounts","isCPUAvail","fRegs","fUpdateCPU","nCyclesStep","exception","nStep","doRegisters","doUnassemble","clearTempBreakpoint","msStart","nCyclesStart","sStopped","msTotal","nState","bOpcode","nSuppressBreaks","aBreak","findBreakpoint","printBreakpoint","fFound","dbgAddrBreak","listBreakpoints","sAction","fBreak","addrBreak","doCommand","getInstruction","sComment","nSequence","dbgAddrIns","aOpDesc","sOperands","sOpcode","asOpcodes","Debugger8080.STYLE_8086","Debugger8080.INS_NAMES","Debugger8080.INS_NAMES_8086","iIns","cOperands","typeSizeDefault","Debugger8080.TYPE_NONE","iOperand","sOperand","Debugger8080.TYPE_OPT","typeMode","Debugger8080.TYPE_MODE","typeSize","Debugger8080.TYPE_SIZE","Debugger8080.TYPE_OTHER","Debugger8080.TYPE_OUT","Debugger8080.TYPE_IN","Debugger8080.TYPE_IMM","getImmOperand","Debugger8080.TYPE_BYTE","Debugger8080.TYPE_SBYTE","Debugger8080.TYPE_WORD","Debugger8080.TYPE_MEM","Debugger8080.TYPE_REG","Debugger8080.TYPE_IREG","getRegOperand","Debugger8080.TYPE_INT","sBytes","sLine","Debugger8080.TYPE_UNDOC","getFlagOutput","sFlag","getRegOutput","getRegDump","p1","p2","findSymbol","fNearest","aSymbol","addrSymbol","result","returnSymbol","iOffset","doFreqs","cData","aaSortedOpcodeCounts","cFreq","doVar","delVariable","setVariable","doList","nDelta","sDelta","doOptions","fInstruction","sRegMatch","doPrint","doTrace","sCount","nCount","Web.onCountRepeat","onCountStep","onCountStepComplete","sAddrEnd","cb","dbgAddrEnd","cLines","sInstruction","sLabel","s0","ch0","unshift","doAssemble","aOpBytes","doBreak","cBreaks","doClear","controlPrint","sLen","sDumpers","doDump","sState","powerOff","sSymbolOrig","sCmdDumpPrev","sMore","cHistory","iHistory","aHistory","nPrev","sPrev","nextHistory","nLines","sLines","aFilters","dbgAddrNew","cOverrides","iByte","sChars","mask","fnGet","doEdit","fnSet","vOld","doRun","doHalt","sMsg","doIf","doInt","sLevel","sPort","doInput","doStackTrace","cFrames","dbgAddrCall","dbgAddrStack","nFrames","sCall","cTests","addrOrig","sCallPrev","fCriteria","sCategory","doMessages","sCategories","fEnabled","doOutput","sByte","doStep","Debugger8080.COMMANDS","doHelp","Debugger8080.TYPE_A","Debugger8080.TYPE_B","Debugger8080.TYPE_C","Debugger8080.TYPE_D","Debugger8080.TYPE_E","Debugger8080.TYPE_H","Debugger8080.TYPE_L","Debugger8080.TYPE_M","Debugger8080.TYPE_BC","Debugger8080.TYPE_DE","Debugger8080.TYPE_HL","Debugger8080.TYPE_SP","Debugger8080.TYPE_PSW","NOP","LXI","STAX","INX","INR","DCR","MVI","RLC","DAD","LDAX","DCX","RRC","RAL","RAR","SHLD","Debugger8080.TYPE_ADDR","DAA","LHLD","CMA","STA","STC","LDA","CMC","MOV","HLT","ADD","ADC","SUB","SBB","ANA","XRA","ORA","CMP","RNZ","POP","JNZ","JMP","CNZ","PUSH","ADI","RST","RZ","RET","JZ","CZ","CALL","ACI","RNC","JNC","OUT","CNC","SUI","RC","JC","IN","CC","SBI","RPO","JPO","XTHL","CPO","ANI","RPE","PCHL","JPE","XCHG","CPE","XRI","RP","JP","DI","CP","ORI","RM","SPHL","JM","EI","CM","CPI","aeDbg","iDbg","eDbg","Computer8080","parmsComputer","parmsMachine","fSuspended","setMachineParms","fAutoPower","nPowerChange","resume","Computer8080.RESUME_NONE","sStateData","fServerState","fStateData","url","random","sUserID","queryUserID","sStatePath","sResume","sResumePath","fAllowResume","stateComputer","APPVERSION","load","getServerStatePath","sResource","wait","powerOn","parmsComponent","sParmLC","Computer8080.prototype","onComponentReady","validateState","stateValidate","Computer8080.STATE_VALIDATE","sTimestampValidate","get","Computer8080.STATE_TIMESTAMP","sTimestampComputer","clear","Computer8080.RESUME_AUTO","fRestore","fRestoreError","Computer8080.RESUME_REPOWER","stateFailSafe","Computer8080.STATE_FAILSAFE","powerReport","Computer8080.RESUME_PROMPT","unload","Usr.formatDate","store","fValidate","Component.confirmUser","sCode","RES","CODE","FAIL","Web.setLocalStorageItem","Computer8080.STATE_USERID","resetUserID","powerRestore","donePowerOn","reload","asComments","fInitialized","controlPower","getUserID","dataPost","QUERY","APPNAME","sUser","TYPE","sReport","sReportURL","sTimestamp","Computer8080.STATE_VERSION","Computer8080.STATE_HOSTURL","href","Computer8080.STATE_BROWSER","fClearAll","fClear","saveServerState","Computer8080.RESUME_DELETE","Str.endsWith","fPrompt","Web.getLocalStorageItem","prompt","verifyUserID","code","State.key","REQ","storeServerState","ENDPOINT","sError","fScroll","scrollX","scrollY","scrollTo","getSpeedCurrent","aeMachines","iMachine","eMachine","aeComputers","iComputer","eComputer","show","exit","sVersion","json","fLoaded","fParsed","State.prototype","Web.hasLocalStorage","stringify","fAll","cAsyncMachines","loadXML","sXMLFile","fResolve","doneLoadXML","sURLName","sXML","parseXML","buildXML","pathname","xmlDoc","async","parseFromString","DOMParser","resolveXML","matchRef","reRef","sRefFile","doneReadXML","sXMLRef","sRefAttrs","aXMLRefTag","sXMLNewTag","matchAttr","reAttr","embedMachine","sXSLFile","displayMessage","eWarning","aeWarning","Str.escapeHTML","displayError","Web.enablePageEvents","getElementById","css","head","styleSheet","cssText","createTextNode","processXML","xml","transformXML","sXSL","xsl","sFragment","outerHTML","implementation","createDocument","xsltProcessor","XSLTProcessor","eFragment","replaceChild","embedPC8080","commandMachine","fSingle","sComponent","sToken","disabled"],"sourcesContent":["\"use strict\";\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/defines.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @define {string}\n */\nvar APPVERSION = \"\"; // this @define is overridden by the Closure Compiler with the version in machines.json\n\nvar XMLVERSION = null; // this is set in non-COMPILED builds by embedMachine() if a version number was found in the machine XML\n\nvar COPYRIGHT = \"Copyright © 2012-2018 Jeff Parsons <Jeff@pcjs.org>\";\n\nvar LICENSE = \"License: GPL version 3 or later <http://gnu.org/licenses/gpl.html>\";\n\nvar CSSCLASS = \"pcjs\";\n\n/**\n * @define {string}\n */\nvar SITEHOST = \"localhost:8088\";// this @define is overridden by the Closure Compiler with \"www.pcjs.org\"\n\n/**\n * @define {boolean}\n */\nvar COMPILED = false; // this @define is overridden by the Closure Compiler (to true)\n\n/**\n * @define {boolean}\n */\nvar DEBUG = true; // this @define is overridden by the Closure Compiler (to false) to remove DEBUG-only code\n\n/**\n * @define {boolean}\n */\nvar MAXDEBUG = false; // this @define is overridden by the Closure Compiler (to false) to remove MAXDEBUG-only code\n\n/**\n * @define {boolean}\n */\nvar PRIVATE = false; // this @define is overridden by the Closure Compiler (to false) to enable PRIVATE code\n\n/*\n * RS-232 DB-25 Pin Definitions, mapped to bits 1-25 in a 32-bit status value.\n *\n * SerialPorts in PCjs machines are considered DTE (Data Terminal Equipment), which means they should be \"virtually\"\n * connected to each other via a null-modem cable, which assumes the following cross-wiring:\n *\n * G 1 <-> 1 G (Ground)\n * TD 2 <-> 3 RD (Received Data)\n * RD 3 <-> 2 TD (Transmitted Data)\n * RTS 4 <-> 5 CTS (Clear To Send)\n * CTS 5 <-> 4 RTS (Request To Send)\n * DSR 6+8 <-> 20 DTR (Data Terminal Ready)\n * SG 7 <-> 7 SG (Signal Ground)\n * DTR 20 <-> 6+8 DSR (Data Set Ready + Carrier Detect)\n * RI 22 <-> 22 RI (Ring Indicator)\n *\n * TODO: Move these definitions to a more appropriate shared file at some point.\n */\nvar RS232 = {\n RTS: {\n PIN: 4,\n MASK: 0x00000010\n },\n CTS: {\n PIN: 5,\n MASK: 0x00000020\n },\n DSR: {\n PIN: 6,\n MASK: 0x00000040\n },\n CD: {\n PIN: 8,\n MASK: 0x00000100\n },\n DTR: {\n PIN: 20,\n MASK: 0x00100000\n },\n RI: {\n PIN: 22,\n MASK: 0x00400000\n }\n};\n\n/*\n * NODE should be true if we're running under NodeJS (eg, command-line), false if not (eg, web browser)\n */\nvar NODE = false;\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/dumpapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Our \"DiskDump API\", such as it was, used to look like:\n *\n * http://jsmachines.net/bin/convdisk.php?disk=/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json&format=img\n *\n * To make it (a bit) more \"REST-like\", the above request now looks like:\n *\n * http://www.pcjs.org/api/v1/dump?disk=/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json&format=img\n *\n * Similarly, our \"FileDump API\" used to look like:\n *\n * http://jsmachines.net/bin/convrom.php?rom=/devices/pc/rom/5150/1981-04-24/PCBIOS-REV1.rom&format=json\n *\n * and that request now looks like:\n *\n * http://www.pcjs.org/api/v1/dump?file=/devices/pc/rom/5150/1981-04-24/PCBIOS-REV1.rom&format=json\n *\n * I don't think it makes sense to avoid \"query\" parameters, because blending the path of a disk image with the\n * the rest of the URL would be (a) confusing, and (b) more work to parse.\n */\nvar DumpAPI = {\n ENDPOINT: \"/api/v1/dump\",\n QUERY: {\n DIR: \"dir\", // value is path of a directory (DiskDump only)\n DISK: \"disk\", // value is path of a disk image (DiskDump only)\n FILE: \"file\", // value is path of a ROM image file (FileDump only)\n IMG: \"img\", // alias for DISK\n PATH: \"path\", // value is path of a one or more files (DiskDump only)\n FORMAT: \"format\", // value is one of FORMAT values below\n COMMENTS: \"comments\", // value is either \"true\" or \"false\"\n DECIMAL: \"decimal\", // value is either \"true\" to force all numbers to decimal, \"false\" or undefined otherwise\n MBHD: \"mbhd\", // value is hard drive size in Mb (formerly \"mbsize\") (DiskDump only) (DEPRECATED)\n SIZE: \"size\" // value is target disk size in Kb (supersedes \"mbhd\") (DiskDump only)\n },\n FORMAT: {\n JSON: \"json\", // default\n JSON_GZ: \"gz\", // gzip is currently used ONLY for compressed JSON\n DATA: \"data\", // same as \"json\", but built without JSON.stringify() (DiskDump only)\n HEX: \"hex\", // deprecated\n OCTAL: \"octal\", // displays data as octal words\n BYTES: \"bytes\", // displays data as hex bytes; normally used only when comments are enabled\n WORDS: \"words\", // displays data as hex words; normally used only when comments are enabled\n LONGS: \"longs\", // displays data as dwords\n IMG: \"img\", // returns the raw disk data (ie, using a Buffer object) (DiskDump only)\n ROM: \"rom\" // returns the raw file data (ie, using a Buffer object) (FileDump only)\n }\n};\n\n/*\n * Because we use an overloaded API endpoint (ie, one that's shared with the FileDump module), we must\n * also provide a list of commands which, when combined with the endpoint, define a unique request.\n */\nDumpAPI.asDiskCommands = [DumpAPI.QUERY.DIR, DumpAPI.QUERY.DISK, DumpAPI.QUERY.PATH];\nDumpAPI.asFileCommands = [DumpAPI.QUERY.FILE];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/reportapi.js (C) Jeff Parsons 2012-2018\n */\n\nvar ReportAPI = {\n ENDPOINT: \"/api/v1/report\",\n QUERY: {\n APP: \"app\",\n VER: \"ver\",\n URL: \"url\",\n USER: \"user\",\n TYPE: \"type\",\n DATA: \"data\"\n },\n TYPE: {\n BUG: \"bug\"\n },\n RES: {\n OK: \"Thank you\"\n }\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/userapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Examples of User API requests:\n *\n * web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.VERIFY + '&' + UserAPI.QUERY.USER + '=' + sUser;\n */\nvar UserAPI = {\n ENDPOINT: \"/api/v1/user\",\n QUERY: {\n REQ: \"req\", // specifies a request\n USER: \"user\", // specifies a user ID\n STATE: \"state\", // specifies a state ID\n DATA: \"data\" // specifies state data\n },\n REQ: {\n CREATE: \"create\", // creates a user ID\n VERIFY: \"verify\", // requests verification of a user ID\n STORE: \"store\", // stores a machine state on the server\n LOAD: \"load\" // loads a machine state from the server\n },\n RES: {\n CODE: \"code\",\n DATA: \"data\"\n },\n CODE: {\n OK: \"ok\",\n FAIL: \"error\"\n },\n FAIL: {\n DUPLICATE: \"user already exists\",\n VERIFY: \"unable to verify user\",\n BADSTATE: \"invalid state parameter\",\n NOSTATE: \"no machine state\",\n BADLOAD: \"unable to load machine state\",\n BADSTORE: \"unable to save machine state\"\n }\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/keys.js (C) Jeff Parsons 2012-2018\n */\n\nvar Keys = {\n /*\n * Keys and/or key combinations that generate common ASCII codes.\n *\n * NOTE: If you're looking for a general-purpose ASCII code table, see Str.ASCII in strlib.js;\n * if something's missing, that's probably the more appropriate table to add it to.\n *\n * TODO: The Closure Compiler doesn't inline all references to these values, at least those with\n * quoted property names, which is why I've 'unquoted' as many of them as possible. One solution\n * would be to add mnemonics for all of them, not just the non-printable ones (eg, SPACE instead\n * of ' ', AMP instead of '&', etc.)\n */\n ASCII: {\n BREAK: 0, CTRL_A: 1, CTRL_B: 2, CTRL_C: 3, CTRL_D: 4, CTRL_E: 5, CTRL_F: 6, CTRL_G: 7,\n CTRL_H: 8, CTRL_I: 9, CTRL_J: 10, CTRL_K: 11, CTRL_L: 12, CTRL_M: 13, CTRL_N: 14, CTRL_O: 15,\n CTRL_P: 16, CTRL_Q: 17, CTRL_R: 18, CTRL_S: 19, CTRL_T: 20, CTRL_U: 21, CTRL_V: 22, CTRL_W: 23,\n CTRL_X: 24, CTRL_Y: 25, CTRL_Z: 26, ESC: 27,\n ' ': 32, '!': 33, '\"': 34, '#': 35, '$': 36, '%': 37, '&': 38, \"'\": 39,\n '(': 40, ')': 41, '*': 42, '+': 43, ',': 44, '-': 45, '.': 46, '/': 47,\n '0': 48, '1': 49, '2': 50, '3': 51, '4': 52, '5': 53, '6': 54, '7': 55,\n '8': 56, '9': 57, ':': 58, ';': 59, '<': 60, '=': 61, '>': 62, '?': 63,\n '@': 64, A: 65, B: 66, C: 67, D: 68, E: 69, F: 70, G: 71,\n H: 72, I: 73, J: 74, K: 75, L: 76, M: 77, N: 78, O: 79,\n P: 80, Q: 81, R: 82, S: 83, T: 84, U: 85, V: 86, W: 87,\n X: 88, Y: 89, Z: 90, '[': 91, '\\\\':92, ']': 93, '^': 94, '_': 95,\n '`': 96, a: 97, b: 98, c: 99, d: 100, e: 101, f: 102, g: 103,\n h: 104, i: 105, j: 106, k: 107, l: 108, m: 109, n: 110, o: 111,\n p: 112, q: 113, r: 114, s: 115, t: 116, u: 117, v: 118, w: 119,\n x: 120, y: 121, z: 122, '{':123, '|':124, '}':125, '~':126, DEL: 127\n },\n /*\n * Browser keyCodes we must pay particular attention to. For the most part, these are non-alphanumeric\n * or function keys, some which may require special treatment (eg, preventDefault() if returning false on\n * the initial keyDown event is insufficient).\n *\n * keyCodes for most common ASCII keys can simply use the appropriate ASCII code above.\n *\n * Most of these represent non-ASCII keys (eg, the LEFT arrow key), yet for some reason, browsers defined\n * them using ASCII codes (eg, the LEFT arrow key uses the ASCII code for '%' or 37).\n */\n KEYCODE: {\n /* 0x08 */ BS: 8, // BACKSPACE (ASCII.CTRL_H)\n /* 0x09 */ TAB: 9, // TAB (ASCII.CTRL_I)\n /* 0x0A */ LF: 10, // LINE-FEED (ASCII.CTRL_J) (Some Windows-based browsers used to generate this via CTRL-ENTER)\n /* 0x0D */ CR: 13, // CARRIAGE RETURN (ASCII.CTRL_M)\n /* 0x10 */ SHIFT: 16,\n /* 0x11 */ CTRL: 17,\n /* 0x12 */ ALT: 18,\n /* 0x13 */ PAUSE: 19, // PAUSE/BREAK\n /* 0x14 */ CAPS_LOCK: 20,\n /* 0x1B */ ESC: 27,\n /* 0x20 */ SPACE: 32,\n /* 0x21 */ PGUP: 33,\n /* 0x22 */ PGDN: 34,\n /* 0x23 */ END: 35,\n /* 0x24 */ HOME: 36,\n /* 0x25 */ LEFT: 37,\n /* 0x26 */ UP: 38,\n /* 0x27 */ RIGHT: 39,\n /* 0x27 */ FF_QUOTE: 39,\n /* 0x28 */ DOWN: 40,\n /* 0x2C */ FF_COMMA: 44,\n /* 0x2C */ PRTSC: 44,\n /* 0x2D */ INS: 45,\n /* 0x2E */ DEL: 46,\n /* 0x2E */ FF_PERIOD: 46,\n /* 0x2F */ FF_SLASH: 47,\n /* 0x30 */ ZERO: 48,\n /* 0x31 */ ONE: 49,\n /* 0x32 */ TWO: 50,\n /* 0x33 */ THREE: 51,\n /* 0x34 */ FOUR: 52,\n /* 0x35 */ FIVE: 53,\n /* 0x36 */ SIX: 54,\n /* 0x37 */ SEVEN: 55,\n /* 0x38 */ EIGHT: 56,\n /* 0x39 */ NINE: 57,\n /* 0x3B */ FF_SEMI: 59,\n /* 0x3D */ FF_EQUALS: 61,\n /* 0x5B */ CMD: 91, // aka WIN\n /* 0x5B */ FF_LBRACK: 91,\n /* 0x5C */ FF_BSLASH: 92,\n /* 0x5D */ RCMD: 93, // aka MENU\n /* 0x5D */ FF_RBRACK: 93,\n /* 0x60 */ NUM_0: 96,\n /* 0x60 */ NUM_INS: 96,\n /* 0x60 */ FF_BQUOTE: 96,\n /* 0x61 */ NUM_1: 97,\n /* 0x61 */ NUM_END: 97,\n /* 0x62 */ NUM_2: 98,\n /* 0x62 */ NUM_DOWN: 98,\n /* 0x63 */ NUM_3: 99,\n /* 0x63 */ NUM_PGDN: 99,\n /* 0x64 */ NUM_4: 100,\n /* 0x64 */ NUM_LEFT: 100,\n /* 0x65 */ NUM_5: 101,\n /* 0x65 */ NUM_CENTER: 101,\n /* 0x66 */ NUM_6: 102,\n /* 0x66 */ NUM_RIGHT: 102,\n /* 0x67 */ NUM_7: 103,\n /* 0x67 */ NUM_HOME: 103,\n /* 0x68 */ NUM_8: 104,\n /* 0x68 */ NUM_UP: 104,\n /* 0x69 */ NUM_9: 105,\n /* 0x69 */ NUM_PGUP: 105,\n /* 0x6A */ NUM_MUL: 106,\n /* 0x6B */ NUM_ADD: 107,\n /* 0x6D */ NUM_SUB: 109,\n /* 0x6E */ NUM_DEL: 110, // aka PERIOD\n /* 0x6F */ NUM_DIV: 111,\n /* 0x70 */ F1: 112,\n /* 0x71 */ F2: 113,\n /* 0x72 */ F3: 114,\n /* 0x73 */ F4: 115,\n /* 0x74 */ F5: 116,\n /* 0x75 */ F6: 117,\n /* 0x76 */ F7: 118,\n /* 0x77 */ F8: 119,\n /* 0x78 */ F9: 120,\n /* 0x79 */ F10: 121,\n /* 0x7A */ F11: 122,\n /* 0x7B */ F12: 123,\n /* 0x90 */ NUM_LOCK: 144,\n /* 0x91 */ SCROLL_LOCK: 145,\n /* 0xAD */ FF_DASH: 173,\n /* 0xBA */ SEMI: 186, // Firefox: 59 (FF_SEMI)\n /* 0xBB */ EQUALS: 187, // Firefox: 61 (FF_EQUALS)\n /* 0xBC */ COMMA: 188,\n /* 0xBD */ DASH: 189, // Firefox: 173 (FF_DASH)\n /* 0xBE */ PERIOD: 190,\n /* 0xBF */ SLASH: 191,\n /* 0xC0 */ BQUOTE: 192,\n /* 0xDB */ LBRACK: 219,\n /* 0xDC */ BSLASH: 220,\n /* 0xDD */ RBRACK: 221,\n /* 0xDE */ QUOTE: 222,\n /* 0xE0 */ FF_CMD: 224, // Firefox only (used for both CMD and RCMD)\n //\n // The following biases use what I'll call Decimal Coded Binary or DCB (the opposite of BCD),\n // where the thousands digit is used to store the sum of \"binary\" digits 1 and/or 2 and/or 4.\n //\n // Technically, that makes it DCO (Decimal Coded Octal), but then again, BCD should have really\n // been called HCD (Hexadecimal Coded Decimal), so if \"they\" can take liberties, so can I.\n //\n // ONDOWN is a bias we add to browser keyCodes that we want to handle on \"down\" rather than on \"press\".\n //\n ONDOWN: 1000,\n //\n // ONRIGHT is a bias we add to browser keyCodes that need to check for a \"right\" location (default is \"left\")\n //\n ONRIGHT: 2000,\n //\n // FAKE is a bias we add to signal these are fake keyCodes corresponding to internal keystroke combinations.\n // The actual values are for internal use only and merely need to be unique and used consistently.\n //\n FAKE: 4000\n },\n /*\n * The set of values that a browser may store in the 'location' property of a keyboard event object\n * which we also support.\n */\n LOCATION: {\n LEFT: 1,\n RIGHT: 2,\n NUMPAD: 3\n }\n};\n\n/*\n * Check the event object's 'location' property for a non-zero value for the following ONRIGHT keys.\n */\nKeys.KEYCODE.NUM_CR = Keys.KEYCODE.CR + Keys.KEYCODE.ONRIGHT;\n\n\n/*\n * Maps Firefox keyCodes to their more common keyCode counterparts; a number of entries in this table\n * are no longer valid (if indeed they ever were), so they've been commented out. It's likely that I\n * simply extended this table to resolve additional differences in other browsers (ie, Opera), but without\n * browser-specific checks, it's not safe to perform all the mappings shown below.\n */\nKeys.FF_KEYCODES = {};\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_SEMI] = Keys.KEYCODE.SEMI; // 59 -> 186\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_EQUALS] = Keys.KEYCODE.EQUALS; // 61 -> 187\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.KEYCODE.DASH; // 173 -> 189\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_CMD] = Keys.KEYCODE.CMD; // 224 -> 91\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_COMMA] = Keys.KEYCODE.COMMA; // 44 -> 188\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_PERIOD] = Keys.KEYCODE.PERIOD; // 46 -> 190\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_SLASH] = Keys.KEYCODE.SLASH; // 47 -> 191\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_BQUOTE] = Keys.KEYCODE.BQUOTE; // 96 -> 192\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_LBRACK = Keys.KEYCODE.LBRACK; // 91 -> 219\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_BSLASH] = Keys.KEYCODE.BSLASH; // 92 -> 220\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_RBRACK] = Keys.KEYCODE.RBRACK; // 93 -> 221\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_QUOTE] = Keys.KEYCODE.QUOTE; // 39 -> 222\n\n/*\n * Maps non-ASCII keyCodes to their ASCII counterparts\n */\nKeys.NONASCII_KEYCODES = {};\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.ASCII['-']; // 173 -> 45\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.SEMI] = Keys.ASCII[';']; // 186 -> 59\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.EQUALS] = Keys.ASCII['=']; // 187 -> 61\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.DASH] = Keys.ASCII['-']; // 189 -> 45\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.COMMA] = Keys.ASCII[',']; // 188 -> 44\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.PERIOD] = Keys.ASCII['.']; // 190 -> 46\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.SLASH] = Keys.ASCII['/']; // 191 -> 47\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.BQUOTE] = Keys.ASCII['`']; // 192 -> 96\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.LBRACK] = Keys.ASCII['[']; // 219 -> 91\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.BSLASH] = Keys.ASCII['\\\\']; // 220 -> 92\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.RBRACK] = Keys.ASCII[']']; // 221 -> 93\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.QUOTE] = Keys.ASCII[\"'\"]; // 222 -> 39\n\n/*\n * Maps unshifted keyCodes to their shifted counterparts; to be used when a shift-key is down.\n * Alphabetic characters are handled in code, since they must also take CAPS_LOCK into consideration.\n */\nKeys.SHIFTED_KEYCODES = {};\nKeys.SHIFTED_KEYCODES[Keys.ASCII['1']] = Keys.ASCII['!'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['2']] = Keys.ASCII['@'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['3']] = Keys.ASCII['#'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['4']] = Keys.ASCII['$'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['5']] = Keys.ASCII['%'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['6']] = Keys.ASCII['^'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['7']] = Keys.ASCII['&'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['8']] = Keys.ASCII['*'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['9']] = Keys.ASCII['('];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['0']] = Keys.ASCII[')'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.SEMI] = Keys.ASCII[':'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.EQUALS] = Keys.ASCII['+'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.COMMA] = Keys.ASCII['<'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.DASH] = Keys.ASCII['_'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.PERIOD] = Keys.ASCII['>'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.SLASH] = Keys.ASCII['?'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.BQUOTE] = Keys.ASCII['~'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.LBRACK] = Keys.ASCII['{'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.BSLASH] = Keys.ASCII['|'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.RBRACK] = Keys.ASCII['}'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.QUOTE] = Keys.ASCII['\"'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.ASCII['_'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_EQUALS] = Keys.ASCII['+'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_SEMI] = Keys.ASCII[':'];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/strlib.js (C) Jeff Parsons 2012-2018\n */\n\nclass Str {\n /**\n * isValidInt(s, base)\n *\n * The built-in parseInt() function has the annoying feature of returning a partial value (ie,\n * up to the point where it encounters an invalid character); eg, parseInt(\"foo\", 16) returns 0xf.\n *\n * So it's best to use our own Str.parseInt() function, which will in turn use this function to\n * validate the entire string.\n *\n * @param {string} s is the string representation of some number\n * @param {number} [base] is the radix to use (default is 10); only 2, 8, 10 and 16 are supported\n * @return {boolean} true if valid, false if invalid (or the specified base isn't supported)\n */\n static isValidInt(s, base)\n {\n if (!base || base == 10) return s.match(/^-?[0-9]+$/) !== null;\n if (base == 16) return s.match(/^-?[0-9a-f]+$/i) !== null;\n if (base == 8) return s.match(/^-?[0-7]+$/) !== null;\n if (base == 2) return s.match(/^-?[01]+$/) !== null;\n return false;\n }\n\n /**\n * parseInt(s, base)\n *\n * This is a wrapper around the built-in parseInt() function. Our wrapper recognizes certain prefixes\n * ('$' or \"0x\" for hex, '#' or \"0o\" for octal) and suffixes ('.' for decimal, 'h' for hex, 'y' for\n * binary), and then calls isValidInt() to ensure we don't convert strings that contain partial values;\n * see isValidInt() for details.\n *\n * The use of multiple prefix/suffix combinations is undefined (although for the record, we process\n * prefixes first). We do NOT support the \"0b\" prefix to indicate binary UNLESS one or more commas are\n * also present (because \"0b\" is also a valid hex sequence), and we do NOT support a single leading zero\n * to indicate octal (because such a number could also be decimal or hex). Any number of commas are\n * allowed; we remove them all before calling the built-in parseInt().\n *\n * More recently, we've added support for \"^D\", \"^O\", and \"^B\" prefixes to accommodate the base overrides\n * that the PDP-10's MACRO-10 assembly language supports (decimal, octal, and binary, respectively).\n * If this support turns out to adversely affect other debuggers, then it will have to be \"conditionalized\".\n * Similarly, we've added support for \"K\", \"M\", and \"G\" MACRO-10-style suffixes that add 3, 6, or 9 zeros\n * to the value to be parsed, respectively.\n *\n * @param {string} s is the string representation of some number\n * @param {number} [base] is the radix to use (default is 10); can be overridden by prefixes/suffixes\n * @return {number|undefined} corresponding value, or undefined if invalid\n */\n static parseInt(s, base)\n {\n var value;\n\n if (s) {\n if (!base) base = 10;\n\n var ch, chPrefix, chSuffix;\n var fCommas = (s.indexOf(',') > 0);\n if (fCommas) s = s.replace(/,/g, '');\n\n ch = chPrefix = s.charAt(0);\n if (chPrefix == '#') {\n base = 8;\n chPrefix = '';\n }\n else if (chPrefix == '$') {\n base = 16;\n chPrefix = '';\n }\n if (ch != chPrefix) {\n s = s.substr(1);\n }\n else {\n ch = chPrefix = s.substr(0, 2);\n if (chPrefix == '0b' && fCommas || chPrefix == '^B') {\n base = 2;\n chPrefix = '';\n }\n else if (chPrefix == '0o' || chPrefix == '^O') {\n base = 8;\n chPrefix = '';\n }\n else if (chPrefix == '^D') {\n base = 10;\n chPrefix = '';\n }\n else if (chPrefix == '0x') {\n base = 16;\n chPrefix = '';\n }\n if (ch != chPrefix) s = s.substr(2);\n }\n ch = chSuffix = s.slice(-1);\n if (chSuffix == 'Y' || chSuffix == 'y') {\n base = 2;\n chSuffix = '';\n }\n else if (chSuffix == '.') {\n base = 10;\n chSuffix = '';\n }\n else if (chSuffix == 'H' || chSuffix == 'h') {\n base = 16;\n chSuffix = '';\n }\n else if (chSuffix == 'K') {\n chSuffix = '000';\n }\n else if (chSuffix == 'M') {\n chSuffix = '000000';\n }\n else if (chSuffix == 'G') {\n chSuffix = '000000000';\n }\n if (ch != chSuffix) s = s.slice(0, -1) + chSuffix;\n /*\n * This adds support for the MACRO-10 binary shifting (Bn) suffix, which must be stripped from the\n * number before parsing, and then applied to the value after parsing. If n is omitted, 35 is assumed,\n * which is a net shift of zero. If n < 35, then a left shift of (35 - n) is required; if n > 35, then\n * a right shift of -(35 - n) is required.\n */\n var v, shift = 0;\n if (base <= 10) {\n var match = s.match(/(-?[0-9]+)B([0-9]*)/);\n if (match) {\n s = match[1];\n shift = 35 - ((match[2] || 35) & 0xff);\n }\n }\n if (Str.isValidInt(s, base) && !isNaN(v = parseInt(s, base))) {\n /*\n * With the need to support larger (eg, 36-bit) integers, truncating to 32 bits is no longer helpful.\n *\n * value = v|0;\n */\n if (shift) {\n /*\n * Since binary shifting is a logical operation, and since shifting by division only works properly\n * with positive numbers, we must convert a negative value to a positive value, by computing the two's\n * complement.\n */\n if (v < 0) v += Math.pow(2, 36);\n if (shift > 0) {\n v *= Math.pow(2, shift);\n } else {\n v = Math.trunc(v / Math.pow(2, -shift));\n }\n }\n value = v;\n }\n }\n return value;\n }\n\n /**\n * toBase(n, radix, cch, sPrefix, nGrouping)\n *\n * Displays the given number as an unsigned integer using the specified radix and number of digits.\n *\n * @param {number|*} n\n * @param {number} radix (ie, the base)\n * @param {number} cch (the desired number of digits)\n * @param {string} [sPrefix] (default is none)\n * @param {number} [nGrouping]\n * @return {string}\n */\n static toBase(n, radix, cch, sPrefix = \"\", nGrouping = 0)\n {\n /*\n * We can't rely entirely on isNaN(), because isNaN(null) returns false, and we can't rely\n * entirely on typeof either, because typeof Nan returns \"number\". Sigh.\n *\n * Alternatively, we could mask and shift n regardless of whether it's null/undefined/NaN,\n * since JavaScript coerces such operands to zero, but I think there's \"value\" in seeing those\n * values displayed differently.\n */\n var s = \"\";\n if (isNaN(n) || typeof n != \"number\") {\n n = null;\n } else {\n /*\n * Callers that produced an input by dividing by a power of two rather than shifting (in order\n * to access more than 32 bits) may produce a fractional result, which ordinarily we would simply\n * ignore, but if the integer portion is zero and the sign is negative, we should probably treat\n * this value as a sign-extension.\n */\n if (n < 0 && n > -1) n = -1;\n /*\n * Negative values should be two's complemented according to the number of digits; for example,\n * 12 octal digits implies an upper limit 8^12.\n */\n if (n < 0) {\n n += Math.pow(radix, cch);\n }\n if (n >= Math.pow(radix, cch)) {\n cch = Math.ceil(Math.log(n) / Math.log(radix));\n }\n }\n var g = nGrouping || -1;\n while (cch-- > 0) {\n if (!g) {\n s = ',' + s;\n g = nGrouping;\n }\n if (n == null) {\n s = '?' + s;\n } else {\n var d = n % radix;\n d += (d >= 0 && d <= 9? 0x30 : 0x41 - 10);\n s = String.fromCharCode(d) + s;\n n = Math.trunc(n / radix);\n }\n g--;\n }\n return sPrefix + s;\n }\n\n /**\n * toBin(n, cch, nGrouping)\n *\n * Converts an integer to binary, with the specified number of digits (up to a maximum of 36).\n *\n * @param {number|*} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of binary digits (0 or undefined for default of either 8, 18, or 36)\n * @param {number} [nGrouping]\n * @return {string} the binary representation of n\n */\n static toBin(n, cch, nGrouping)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.LN2) || 1;\n var v = Math.abs(n);\n if (v <= 0b11111111) {\n cch = 8;\n } else if (v <= 0b111111111111111111) {\n cch = 18;\n } else {\n cch = 36;\n }\n } else if (cch > 36) cch = 36;\n return Str.toBase(n, 2, cch, \"\", nGrouping);\n }\n\n /**\n * toBinBytes(n, cb, fPrefix)\n *\n * Converts an integer to binary, with the specified number of bytes (up to the default of 4).\n *\n * @param {number|null|undefined} n (interpreted as a 32-bit value)\n * @param {number} [cb] is the desired number of binary bytes (4 is both the default and the maximum)\n * @param {boolean} [fPrefix]\n * @return {string} the binary representation of n\n */\n static toBinBytes(n, cb, fPrefix)\n {\n var s = \"\";\n if (!cb || cb > 4) cb = 4;\n for (var i = 0; i < cb; i++) {\n if (s) s = ',' + s;\n s = Str.toBin(n & 0xff, 8) + s;\n n >>= 8;\n }\n return (fPrefix? \"0b\" : \"\") + s;\n }\n\n /**\n * toOct(n, cch, fPrefix)\n *\n * Converts an integer to octal, with the specified number of digits (default of 6; max of 12)\n *\n * You might be tempted to use the built-in n.toString(8) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw\n * an exception, whereas this function will return '?' characters.\n *\n * @param {number|*} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of octal digits (0 or undefined for default of either 6, 8, or 12)\n * @param {boolean} [fPrefix]\n * @return {string} the octal representation of n\n */\n static toOct(n, cch, fPrefix)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.log(8)) || 1;\n var v = Math.abs(n);\n if (v <= 0o777777) {\n cch = 6;\n } else if (v <= 0o77777777) {\n cch = 8;\n } else {\n cch = 12;\n }\n } else if (cch > 12) cch = 12;\n return Str.toBase(n, 8, cch, fPrefix? \"0o\" : \"\");\n }\n\n /**\n * toDec(n, cch)\n *\n * Converts an integer to decimal, with the specified number of digits (default of 5; max of 11)\n *\n * You might be tempted to use the built-in n.toString(10) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw\n * an exception, whereas this function will return '?' characters.\n *\n * @param {number|*} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of decimal digits (0 or undefined for default of either 5 or 11)\n * @return {string} the decimal representation of n\n */\n static toDec(n, cch)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.LN10) || 1;\n var v = Math.abs(n);\n if (v <= 99999) {\n cch = 5;\n } else {\n cch = 11;\n }\n } else if (cch > 11) cch = 11;\n return Str.toBase(n, 10, cch);\n }\n\n /**\n * toHex(n, cch, fPrefix)\n *\n * Converts an integer to hex, with the specified number of digits (default of 4 or 8, max of 9).\n *\n * You might be tempted to use the built-in n.toString(16) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values; for example, if n is -2147483647, then n.toString(16)\n * will return \"-7fffffff\" instead of \"80000001\". Moreover, if n is undefined, n.toString() will\n * throw an exception, whereas this function will return '?' characters.\n *\n * NOTE: The following work-around (adapted from code found on StackOverflow) would be another solution,\n * taking care of negative values, zero-padding, and upper-casing, but not null/undefined/NaN values:\n *\n * s = (n < 0? n + 0x100000000 : n).toString(16);\n * s = \"00000000\".substr(0, 8 - s.length) + s;\n * s = s.substr(0, cch).toUpperCase();\n *\n * @param {number|*} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of hex digits (0 or undefined for default of either 4, 8, or 9)\n * @param {boolean} [fPrefix]\n * @return {string} the hex representation of n\n */\n static toHex(n, cch, fPrefix)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.log(16)) || 1;\n var v = Math.abs(n);\n if (v <= 0xffff) {\n cch = 4;\n } else if (v <= 0xffffffff) {\n cch = 8;\n } else {\n cch = 9;\n }\n } else if (cch > 9) cch = 9;\n return Str.toBase(n, 16, cch, fPrefix? \"0x\" : \"\");\n }\n\n /**\n * toHexByte(b)\n *\n * Alias for Str.toHex(b, 2, true)\n *\n * @param {number|null|undefined} b is a byte value\n * @return {string} the hex representation of b\n */\n static toHexByte(b)\n {\n return Str.toHex(b, 2, true);\n }\n\n /**\n * toHexWord(w)\n *\n * Alias for Str.toHex(w, 4, true)\n *\n * @param {number|null|undefined} w is a word (16-bit) value\n * @return {string} the hex representation of w\n */\n static toHexWord(w)\n {\n return Str.toHex(w, 4, true);\n }\n\n /**\n * toHexLong(l)\n *\n * Alias for Str.toHex(l, 8, true)\n *\n * @param {number|null|undefined} l is a dword (32-bit) value\n * @return {string} the hex representation of w\n */\n static toHexLong(l)\n {\n return Str.toHex(l, 8, true);\n }\n\n /**\n * getBaseName(sFileName, fStripExt)\n *\n * This is a poor-man's version of Node's path.basename(), which Node-only components should use instead.\n *\n * Note that if fStripExt is true, this strips ANY extension, whereas path.basename() strips the extension only\n * if it matches the second parameter (eg, path.basename(\"/foo/bar/baz/asdf/quux.html\", \".html\") returns \"quux\").\n *\n * @param {string} sFileName\n * @param {boolean} [fStripExt]\n * @return {string}\n */\n static getBaseName(sFileName, fStripExt)\n {\n var sBaseName = sFileName;\n\n var i = sFileName.lastIndexOf('/');\n if (i >= 0) sBaseName = sFileName.substr(i + 1);\n\n /*\n * This next bit is a kludge to clean up names that are part of a URL that includes unsightly query parameters.\n */\n i = sBaseName.indexOf('&');\n if (i > 0) sBaseName = sBaseName.substr(0, i);\n\n if (fStripExt) {\n i = sBaseName.lastIndexOf(\".\");\n if (i > 0) {\n sBaseName = sBaseName.substring(0, i);\n }\n }\n return sBaseName;\n }\n\n /**\n * getExtension(sFileName)\n *\n * This is a poor-man's version of Node's path.extname(), which Node-only components should use instead.\n *\n * Note that we EXCLUDE the period from the returned extension, whereas path.extname() includes it.\n *\n * @param {string} sFileName\n * @return {string} the filename's extension (in lower-case and EXCLUDING the \".\"), or an empty string\n */\n static getExtension(sFileName)\n {\n var sExtension = \"\";\n var i = sFileName.lastIndexOf(\".\");\n if (i >= 0) {\n sExtension = sFileName.substr(i + 1).toLowerCase();\n }\n return sExtension;\n }\n\n /**\n * endsWith(s, sSuffix)\n *\n * @param {string} s\n * @param {string} sSuffix\n * @return {boolean} true if s ends with sSuffix, false if not\n */\n static endsWith(s, sSuffix)\n {\n return s.indexOf(sSuffix, s.length - sSuffix.length) !== -1;\n }\n\n /**\n * escapeHTML(sHTML)\n *\n * @param {string} sHTML\n * @return {string} with HTML entities \"escaped\", similar to PHP's htmlspecialchars()\n */\n static escapeHTML(sHTML)\n {\n return sHTML.replace(/[&<>\"']/g, function(m)\n {\n return Str.HTMLEscapeMap[m];\n });\n }\n\n /**\n * replace(sSearch, sReplace, s)\n *\n * The JavaScript replace() function ALWAYS interprets \"$\" specially in replacement strings, even when\n * the search string is NOT a RegExp; specifically:\n *\n * $$ Inserts a \"$\"\n * $& Inserts the matched substring\n * $` Inserts the portion of the string that precedes the matched substring\n * $' Inserts the portion of the string that follows the matched substring\n * $n Where n is a positive integer less than 100, inserts the nth parenthesized sub-match string,\n * provided the first argument was a RegExp object\n *\n * So, if a replacement string containing dollar signs passes through a series of replace() calls, untold\n * problems could result. Hence, this function, which simply uses the replacement string as-is.\n *\n * Similar to the JavaScript replace() method (when sSearch is a string), this replaces only ONE occurrence\n * (ie, the FIRST occurrence); it might be nice to add options to replace the LAST occurrence and/or ALL\n * occurrences, but we'll revisit that later.\n *\n * @param {string} sSearch\n * @param {string} sReplace\n * @param {string} s\n * @return {string}\n */\n static replace(sSearch, sReplace, s)\n {\n var i = s.indexOf(sSearch);\n if (i >= 0) {\n s = s.substr(0, i) + sReplace + s.substr(i + sSearch.length);\n }\n return s;\n }\n\n /**\n * replaceAll(sSearch, sReplace, s)\n *\n * @param {string} sSearch\n * @param {string} sReplace\n * @param {string} s\n * @return {string}\n */\n static replaceAll(sSearch, sReplace, s)\n {\n var a = {};\n a[sSearch] = sReplace;\n return Str.replaceArray(a, s);\n }\n\n /**\n * replaceArray(a, s)\n *\n * @param {Object} a\n * @param {string} s\n * @return {string}\n */\n static replaceArray(a, s)\n {\n var sMatch = \"\";\n for (var k in a) {\n /*\n * As noted in:\n *\n * http://www.regexguru.com/2008/04/escape-characters-only-when-necessary/\n *\n * inside character classes, only backslash, caret, hyphen and the closing bracket need to be\n * escaped. And in fact, if you ensure that the closing bracket is first, the caret is not first,\n * and the hyphen is last, you can avoid escaping those as well.\n */\n k = k.replace(/([\\\\[\\]*{}().+?|$])/g, \"\\\\$1\");\n sMatch += (sMatch? '|' : '') + k;\n }\n return s.replace(new RegExp('(' + sMatch + ')', \"g\"), function(m)\n {\n return a[m];\n });\n }\n\n /**\n * pad(s, cch, fPadLeft)\n *\n * NOTE: the maximum amount of padding currently supported is 40 spaces.\n *\n * @param {string} s is a string\n * @param {number} cch is desired length\n * @param {boolean} [fPadLeft] (default is padding on the right)\n * @return {string} the original string (s) with spaces padding it to the specified length\n */\n static pad(s, cch, fPadLeft)\n {\n var sPadding = \" \";\n return fPadLeft? (sPadding + s).slice(-cch) : (s + sPadding).slice(0, cch);\n }\n\n /**\n * sprintf(format, ...args)\n *\n * Copied from the CCjs project (https://github.com/jeffpar/ccjs/blob/master/lib/stdio.js) and extended.\n *\n * Far from complete, let alone sprintf-compatible, but it's adequate for the handful of sprintf-style format\n * specifiers that I use.\n *\n * @param {string} format\n * @param {...} args\n * @return {string}\n */\n static sprintf(format, ...args)\n {\n let buffer = \"\";\n let aParts = format.split(/%([-+ 0#]?)([0-9]*)(\\.?)([0-9]*)([hlL]?)([A-Za-z%])/);\n\n let iArg = 0, iPart;\n for (iPart = 0; iPart < aParts.length - 7; iPart += 7) {\n\n buffer += aParts[iPart];\n\n let arg = args[iArg++];\n let flags = aParts[iPart+1];\n let minimum = +aParts[iPart+2] || 0;\n let precision = +aParts[iPart+4] || 0;\n let conversion = aParts[iPart+6];\n let ach = null, s;\n\n switch(conversion) {\n case 'd':\n /*\n * We could use \"arg |= 0\", but there may be some value to supporting integers > 32 bits.\n * \n * Also, unlike the 'X' and 'x' hexadecimal cases, there's no need to explicitly check for a string\n * arguments, because the call to trunc() automatically coerces any string value to a (decimal) number.\n */\n arg = Math.trunc(arg);\n /* falls through */\n\n case 'f':\n s = Math.trunc(arg) + \"\";\n if (precision) {\n minimum -= (precision + 1);\n }\n if (s.length < minimum) {\n if (flags == '0') {\n if (arg < 0) minimum--;\n s = (\"0000000000\" + Math.abs(arg)).slice(-minimum);\n if (arg < 0) s = '-' + s;\n } else {\n s = (\" \" + s).slice(-minimum);\n }\n }\n if (precision) {\n arg = Math.round((arg - Math.trunc(arg)) * Math.pow(10, precision));\n s += '.' + (\"0000000000\" + Math.abs(arg)).slice(-precision);\n }\n buffer += s;\n break;\n\n case 'c':\n arg = String.fromCharCode(arg);\n /* falls through */\n\n case 's':\n if (typeof arg == \"string\") {\n while (arg.length < minimum) {\n if (flags == '-') {\n arg += ' ';\n } else {\n arg = ' ' + arg;\n }\n }\n }\n buffer += arg;\n break;\n\n case 'X':\n ach = Str.HexUpperCase;\n /* falls through */\n\n case 'x':\n if (!ach) ach = Str.HexLowerCase;\n s = \"\";\n if (typeof arg == \"string\") {\n /*\n * Since we're advised to ALWAYS pass a radix to parseInt(), we must detect explicitly\n * hex values ourselves, because using a radix of 10 with any \"0x...\" value always returns 0.\n * \n * And if the value CAN be interpreted as decimal, then we MUST interpret it as decimal, because\n * we have sprintf() calls in /modules/lib/testmon.js that depend on this code to perform decimal\n * to hex conversion. We're allowed to make our own rules here, since passing numbers in string\n * form isn't part of the sprintf \"spec\". \n */\n arg = Number.parseInt(arg, arg.match(/(^0x|[a-f])/i)? 16 : 10);\n } \n do {\n s = ach[arg & 0xf] + s;\n arg >>>= 4;\n } while (--minimum > 0 || arg);\n buffer += s;\n break;\n\n default:\n /*\n * The supported ANSI C set of conversions: \"dioxXucsfeEgGpn%\"\n */\n buffer += \"(unrecognized printf conversion %\" + conversion + \")\";\n break;\n }\n }\n\n buffer += aParts[iPart];\n return buffer;\n }\n\n /**\n * stripLeadingZeros(s, fPad)\n *\n * @param {string} s\n * @param {boolean} [fPad]\n * @return {string}\n */\n static stripLeadingZeros(s, fPad)\n {\n var cch = s.length;\n s = s.replace(/^0+([0-9A-F]+)$/i, \"$1\");\n if (fPad) s = Str.pad(s, cch, true);\n return s;\n }\n\n /**\n * trim(s)\n *\n * @param {string} s\n * @return {string}\n */\n static trim(s)\n {\n if (String.prototype.trim) {\n return s.trim();\n }\n return s.replace(/^\\s+|\\s+$/g, \"\");\n }\n\n /**\n * toASCIICode(b)\n *\n * @param {number} b\n * @return {string}\n */\n static toASCIICode(b)\n {\n var s;\n if (b != Str.ASCII.CR && b != Str.ASCII.LF) {\n s = Str.ASCIICodeMap[b];\n }\n if (s) {\n s = '<' + s + '>';\n } else {\n s = String.fromCharCode(b);\n }\n return s;\n }\n}\n\n/*\n * Map special characters to their HTML escape sequences.\n */\nStr.HTMLEscapeMap = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n};\n\n/*\n * Map \"unprintable\" ASCII codes to mnemonics, to more clearly see what's being printed.\n */\nStr.ASCIICodeMap = {\n 0x00: \"NUL\",\n 0x01: \"SOH\", // (CTRL_A) Start of Heading\n 0x02: \"STX\", // (CTRL_B) Start of Text\n 0x03: \"ETX\", // (CTRL_C) End of Text\n 0x04: \"EOT\", // (CTRL_D) End of Transmission\n 0x05: \"ENQ\", // (CTRL_E) Enquiry\n 0x06: \"ACK\", // (CTRL_F) Acknowledge\n 0x07: \"BEL\", // (CTRL_G) Bell\n 0x08: \"BS\", // (CTRL_H) Backspace\n 0x09: \"TAB\", // (CTRL_I) Horizontal Tab (aka HT)\n 0x0A: \"LF\", // (CTRL_J) Line Feed (New Line)\n 0x0B: \"VT\", // (CTRL_K) Vertical Tab\n 0x0C: \"FF\", // (CTRL_L) Form Feed (New Page)\n 0x0D: \"CR\", // (CTRL_M) Carriage Return\n 0x0E: \"SO\", // (CTRL_N) Shift Out\n 0x0F: \"SI\", // (CTRL_O) Shift In\n 0x10: \"DLE\", // (CTRL_P) Data Link Escape\n 0x11: \"XON\", // (CTRL_Q) Device Control 1 (aka DC1)\n 0x12: \"DC2\", // (CTRL_R) Device Control 2\n 0x13: \"XOFF\", // (CTRL_S) Device Control 3 (aka DC3)\n 0x14: \"DC4\", // (CTRL_T) Device Control 4\n 0x15: \"NAK\", // (CTRL_U) Negative Acknowledge\n 0x16: \"SYN\", // (CTRL_V) Synchronous Idle\n 0x17: \"ETB\", // (CTRL_W) End of Transmission Block\n 0x18: \"CAN\", // (CTRL_X) Cancel\n 0x19: \"EM\", // (CTRL_Y) End of Medium\n 0x1A: \"SUB\", // (CTRL_Z) Substitute\n 0x1B: \"ESC\", // Escape\n 0x1C: \"FS\", // File Separator\n 0x1D: \"GS\", // Group Separator\n 0x1E: \"RS\", // Record Separator\n 0x1F: \"US\", // Unit Separator\n 0x7F: \"DEL\"\n};\n\n/*\n * Refer to: https://en.wikipedia.org/wiki/Code_page_437\n */\nStr.CP437ToUnicode = [\n '\\u0000', '\\u263A', '\\u263B', '\\u2665', '\\u2666', '\\u2663', '\\u2660', '\\u2022',\n '\\u25D8', '\\u25CB', '\\u25D9', '\\u2642', '\\u2640', '\\u266A', '\\u266B', '\\u263C',\n '\\u25BA', '\\u25C4', '\\u2195', '\\u203C', '\\u00B6', '\\u00A7', '\\u25AC', '\\u21A8',\n '\\u2191', '\\u2193', '\\u2192', '\\u2190', '\\u221F', '\\u2194', '\\u25B2', '\\u25BC',\n '\\u0020', '\\u0021', '\\u0022', '\\u0023', '\\u0024', '\\u0025', '\\u0026', '\\u0027',\n '\\u0028', '\\u0029', '\\u002A', '\\u002B', '\\u002C', '\\u002D', '\\u002E', '\\u002F',\n '\\u0030', '\\u0031', '\\u0032', '\\u0033', '\\u0034', '\\u0035', '\\u0036', '\\u0037',\n '\\u0038', '\\u0039', '\\u003A', '\\u003B', '\\u003C', '\\u003D', '\\u003E', '\\u003F',\n '\\u0040', '\\u0041', '\\u0042', '\\u0043', '\\u0044', '\\u0045', '\\u0046', '\\u0047',\n '\\u0048', '\\u0049', '\\u004A', '\\u004B', '\\u004C', '\\u004D', '\\u004E', '\\u004F',\n '\\u0050', '\\u0051', '\\u0052', '\\u0053', '\\u0054', '\\u0055', '\\u0056', '\\u0057',\n '\\u0058', '\\u0059', '\\u005A', '\\u005B', '\\u005C', '\\u005D', '\\u005E', '\\u005F',\n '\\u0060', '\\u0061', '\\u0062', '\\u0063', '\\u0064', '\\u0065', '\\u0066', '\\u0067',\n '\\u0068', '\\u0069', '\\u006A', '\\u006B', '\\u006C', '\\u006D', '\\u006E', '\\u006F',\n '\\u0070', '\\u0071', '\\u0072', '\\u0073', '\\u0074', '\\u0075', '\\u0076', '\\u0077',\n '\\u0078', '\\u0079', '\\u007A', '\\u007B', '\\u007C', '\\u007D', '\\u007E', '\\u2302',\n '\\u00C7', '\\u00FC', '\\u00E9', '\\u00E2', '\\u00E4', '\\u00E0', '\\u00E5', '\\u00E7',\n '\\u00EA', '\\u00EB', '\\u00E8', '\\u00EF', '\\u00EE', '\\u00EC', '\\u00C4', '\\u00C5',\n '\\u00C9', '\\u00E6', '\\u00C6', '\\u00F4', '\\u00F6', '\\u00F2', '\\u00FB', '\\u00F9',\n '\\u00FF', '\\u00D6', '\\u00DC', '\\u00A2', '\\u00A3', '\\u00A5', '\\u20A7', '\\u0192',\n '\\u00E1', '\\u00ED', '\\u00F3', '\\u00FA', '\\u00F1', '\\u00D1', '\\u00AA', '\\u00BA',\n '\\u00BF', '\\u2310', '\\u00AC', '\\u00BD', '\\u00BC', '\\u00A1', '\\u00AB', '\\u00BB',\n '\\u2591', '\\u2592', '\\u2593', '\\u2502', '\\u2524', '\\u2561', '\\u2562', '\\u2556',\n '\\u2555', '\\u2563', '\\u2551', '\\u2557', '\\u255D', '\\u255C', '\\u255B', '\\u2510',\n '\\u2514', '\\u2534', '\\u252C', '\\u251C', '\\u2500', '\\u253C', '\\u255E', '\\u255F',\n '\\u255A', '\\u2554', '\\u2569', '\\u2566', '\\u2560', '\\u2550', '\\u256C', '\\u2567',\n '\\u2568', '\\u2564', '\\u2565', '\\u2559', '\\u2558', '\\u2552', '\\u2553', '\\u256B',\n '\\u256A', '\\u2518', '\\u250C', '\\u2588', '\\u2584', '\\u258C', '\\u2590', '\\u2580',\n '\\u03B1', '\\u00DF', '\\u0393', '\\u03C0', '\\u03A3', '\\u03C3', '\\u00B5', '\\u03C4',\n '\\u03A6', '\\u0398', '\\u03A9', '\\u03B4', '\\u221E', '\\u03C6', '\\u03B5', '\\u2229',\n '\\u2261', '\\u00B1', '\\u2265', '\\u2264', '\\u2320', '\\u2321', '\\u00F7', '\\u2248',\n '\\u00B0', '\\u2219', '\\u00B7', '\\u221A', '\\u207F', '\\u00B2', '\\u25A0', '\\u00A0'\n];\n\n/*\n * TODO: Future home of a complete ASCII table.\n */\nStr.ASCII = {\n LF: 0x0A,\n CR: 0x0D\n};\n\nStr.TYPES = {\n NULL: 0,\n BYTE: 1,\n WORD: 2,\n DWORD: 3,\n NUMBER: 4,\n STRING: 5,\n BOOLEAN: 6,\n OBJECT: 7,\n ARRAY: 8\n};\n\nStr.HexLowerCase = \"0123456789abcdef\";\nStr.HexUpperCase = \"0123456789ABCDEF\";\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/usrlib.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @typedef {{\n * mask: number,\n * shift: number\n * }}\n */\nvar BitField;\n\n/**\n * @typedef {Object.<BitField>}\n */\nvar BitFields;\n\nclass Usr {\n /**\n * binarySearch(a, v, fnCompare)\n *\n * @param {Array} a is an array\n * @param {number|string|Array|Object} v\n * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]\n * @return {number} the index of matching entry if non-negative, otherwise the index of the insertion point\n */\n static binarySearch(a, v, fnCompare)\n {\n var left = 0;\n var right = a.length;\n var found = 0;\n if (fnCompare === undefined) {\n fnCompare = function(a, b)\n {\n return a > b ? 1 : a < b ? -1 : 0;\n };\n }\n while (left < right) {\n var middle = (left + right) >> 1;\n var compareResult;\n compareResult = fnCompare(v, a[middle]);\n if (compareResult > 0) {\n left = middle + 1;\n } else {\n right = middle;\n found = !compareResult;\n }\n }\n return found ? left : ~left;\n }\n\n /**\n * binaryInsert(a, v, fnCompare)\n *\n * If element v already exists in array a, the array is unchanged (we don't allow duplicates); otherwise, the\n * element is inserted into the array at the appropriate index.\n *\n * @param {Array} a is an array\n * @param {number|string|Array|Object} v is the value to insert\n * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]\n */\n static binaryInsert(a, v, fnCompare)\n {\n var index = Usr.binarySearch(a, v, fnCompare);\n if (index < 0) {\n a.splice(-(index + 1), 0, v);\n }\n }\n\n /**\n * getTimestamp()\n *\n * @return {string} timestamp containing the current date and time (\"yyyy-mm-dd hh:mm:ss\")\n */\n static getTimestamp()\n {\n return Usr.formatDate(\"Y-m-d H:i:s\");\n }\n\n /**\n * getMonthDays(nMonth, nYear)\n *\n * Note that if we're being called on behalf of the RTC, its year is always truncated to two digits (mod 100),\n * so we have no idea what century the year 0 might refer to. When using the normal leap-year formula, 0 fails\n * the mod 100 test but passes the mod 400 test, so as far as the RTC is concerned, every century year is a leap\n * year. Since we're most likely dealing with the year 2000, that's fine, since 2000 was also a leap year.\n *\n * TODO: There IS a separate CMOS byte that's supposed to be set to CMOS_ADDR.CENTURY_DATE; it's always BCD,\n * so theoretically it will contain values like 0x19 or 0x20 (for the 20th and 21st centuries, respectively), and\n * we could add that as another parameter to this function, to improve the accuracy, but that would go beyond what\n * a real RTC actually does.\n *\n * @param {number} nMonth (1-12)\n * @param {number} nYear (normally a 4-digit year, but it may also be mod 100)\n * @return {number} the maximum (1-based) day allowed for the specified month and year\n */\n static getMonthDays(nMonth, nYear)\n {\n var nDays = Usr.aMonthDays[nMonth - 1];\n if (nDays == 28) {\n if ((nYear % 4) === 0 && ((nYear % 100) || (nYear % 400) === 0)) {\n nDays++;\n }\n }\n return nDays;\n }\n\n /**\n * formatDate(sFormat, date)\n *\n * @param {string} sFormat (eg, \"F j, Y\", \"Y-m-d H:i:s\")\n * @param {Date} [date] (default is the current time)\n * @return {string}\n *\n * Supported identifiers in sFormat include:\n *\n * a: lowercase ante meridiem and post meridiem (am or pm)\n * d: day of the month, 2 digits with leading zeros (01,02,...,31)\n * D: 3-letter day of the week (\"Sun\",\"Mon\",...,\"Sat\")\n * F: month (\"January\",\"February\",...,\"December\")\n * g: hour in 12-hour format, without leading zeros (1,2,...,12)\n * h: hour in 24-hour format, without leading zeros (0,1,...,23)\n * H: hour in 24-hour format, with leading zeros (00,01,...,23)\n * i: minutes, with leading zeros (00,01,...,59)\n * j: day of the month, without leading zeros (1,2,...,31)\n * l: day of the week (\"Sunday\",\"Monday\",...,\"Saturday\")\n * m: month, with leading zeros (01,02,...,12)\n * M: 3-letter month (\"Jan\",\"Feb\",...,\"Dec\")\n * n: month, without leading zeros (1,2,...,12)\n * s: seconds, with leading zeros (00,01,...,59)\n * y: 2-digit year (eg, 14)\n * Y: 4-digit year (eg, 2014)\n *\n * For more inspiration, see: http://php.net/manual/en/function.date.php (of which we support ONLY a subset).\n */\n static formatDate(sFormat, date)\n {\n var sDate = \"\";\n if (!date) date = new Date();\n var iHour = date.getHours();\n var iDay = date.getDate();\n var iMonth = date.getMonth() + 1;\n for (var i = 0; i < sFormat.length; i++) {\n var ch;\n switch ((ch = sFormat.charAt(i))) {\n case 'a':\n sDate += (iHour < 12 ? \"am\" : \"pm\");\n break;\n case 'd':\n sDate += ('0' + iDay).slice(-2);\n break;\n case 'D':\n sDate += Usr.asDays[date.getDay()].substr(0, 3);\n break;\n case 'F':\n sDate += Usr.asMonths[iMonth - 1];\n break;\n case 'g':\n sDate += (!iHour ? 12 : (iHour > 12 ? iHour - 12 : iHour));\n break;\n case 'h':\n sDate += iHour;\n break;\n case 'H':\n sDate += ('0' + iHour).slice(-2);\n break;\n case 'i':\n sDate += ('0' + date.getMinutes()).slice(-2);\n break;\n case 'j':\n sDate += iDay;\n break;\n case 'l':\n sDate += Usr.asDays[date.getDay()];\n break;\n case 'm':\n sDate += ('0' + iMonth).slice(-2);\n break;\n case 'M':\n sDate += Usr.asMonths[iMonth - 1].substr(0, 3);\n break;\n case 'n':\n sDate += iMonth;\n break;\n case 's':\n sDate += ('0' + date.getSeconds()).slice(-2);\n break;\n case 'y':\n sDate += (\"\" + date.getFullYear()).slice(-2);\n break;\n case 'Y':\n sDate += date.getFullYear();\n break;\n default:\n sDate += ch;\n break;\n }\n }\n return sDate;\n }\n\n /**\n * defineBitFields(bfs)\n *\n * Prepares a bit field definition for use with getBitField() and setBitField(); eg:\n *\n * var bfs = Usr.defineBitFields({num:20, count:8, btmod:1, type:3});\n *\n * The above defines a set of bit fields containing four fields: num (bits 0-19), count (bits 20-27), btmod (bit 28), and type (bits 29-31).\n *\n * Usr.setBitField(bfs.num, n, 1);\n *\n * The above set bit field \"bfs.num\" in numeric variable \"n\" to the value 1.\n *\n * @param {Object} bfs\n * @return {BitFields}\n */\n static defineBitFields(bfs)\n {\n var bit = 0;\n for (var f in bfs) {\n var width = bfs[f];\n var mask = ((1 << width) - 1) << bit;\n bfs[f] = {mask: mask, shift: bit};\n bit += width;\n }\n return bfs;\n }\n\n /**\n * initBitFields(bfs, ...)\n *\n * @param {BitFields} bfs\n * @param {...number} var_args\n * @return {number} a value containing all supplied bit fields\n */\n static initBitFields(bfs, var_args)\n {\n var v = 0, i = 1;\n for (var f in bfs) {\n if (i >= arguments.length) break;\n v = Usr.setBitField(bfs[f], v, arguments[i++]);\n }\n return v;\n }\n\n /**\n * getBitField(bf, v)\n *\n * @param {BitField} bf\n * @param {number} v is a value containing bit fields\n * @return {number} the value of the bit field in v defined by bf\n */\n static getBitField(bf, v)\n {\n return (v & bf.mask) >> bf.shift;\n }\n\n /**\n * setBitField(bf, v, n)\n *\n * @param {BitField} bf\n * @param {number} v is a value containing bit fields\n * @param {number} n is a value to store in v in the bit field defined by bf\n * @return {number} updated v\n */\n static setBitField(bf, v, n)\n {\n return (v & ~bf.mask) | ((n << bf.shift) & bf.mask);\n }\n\n /**\n * indexOf(a, t, i)\n *\n * Use this instead of Array.prototype.indexOf() if you can't be sure the browser supports it.\n *\n * @param {Array} a\n * @param {*} t\n * @param {number} [i]\n * @returns {number}\n */\n static indexOf(a, t, i)\n {\n if (Array.prototype.indexOf) {\n return a.indexOf(t, i);\n }\n i = i || 0;\n if (i < 0) i += a.length;\n if (i < 0) i = 0;\n for (var n = a.length; i < n; i++) {\n if (i in a && a[i] === t) return i;\n }\n return -1;\n }\n}\n\nUsr.asDays = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\nUsr.asMonths = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\nUsr.aMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\n/**\n * getTime()\n *\n * @return {number} the current time, in milliseconds\n */\nUsr.getTime = Date.now || function() { return +new Date(); };\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/weblib.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * According to http://www.w3schools.com/jsref/jsref_obj_global.asp, these are the *global* properties\n * and functions of JavaScript-in-the-Browser:\n *\n * Property Description\n * ---\n * Infinity A numeric value that represents positive/negative infinity\n * NaN \"Not-a-Number\" value\n * undefined Indicates that a variable has not been assigned a value\n *\n * Function Description\n * ---\n * decodeURI() Decodes a URI\n * decodeURIComponent() Decodes a URI component\n * encodeURI() Encodes a URI\n * encodeURIComponent() Encodes a URI component\n * escape() Deprecated in version 1.5. Use encodeURI() or encodeURIComponent() instead\n * eval() Evaluates a string and executes it as if it was script code\n * isFinite() Determines whether a value is a finite, legal number\n * isNaN() Determines whether a value is an illegal number\n * Number() Converts an object's value to a number\n * parseFloat() Parses a string and returns a floating point number\n * parseInt() Parses a string and returns an integer\n * String() Converts an object's value to a string\n * unescape() Deprecated in version 1.5. Use decodeURI() or decodeURIComponent() instead\n *\n * And according to http://www.w3schools.com/jsref/obj_window.asp, these are the properties and functions\n * of the *window* object.\n *\n * Property Description\n * ---\n * closed Returns a Boolean value indicating whether a window has been closed or not\n * defaultStatus Sets or returns the default text in the statusbar of a window\n * document Returns the Document object for the window (See Document object)\n * frames Returns an array of all the frames (including iframes) in the current window\n * history Returns the History object for the window (See History object)\n * innerHeight Returns the inner height of a window's content area\n * innerWidth Returns the inner width of a window's content area\n * length Returns the number of frames (including iframes) in a window\n * location Returns the Location object for the window (See Location object)\n * name Sets or returns the name of a window\n * navigator Returns the Navigator object for the window (See Navigator object)\n * opener Returns a reference to the window that created the window\n * outerHeight Returns the outer height of a window, including toolbars/scrollbars\n * outerWidth Returns the outer width of a window, including toolbars/scrollbars\n * pageXOffset Returns the pixels the current document has been scrolled (horizontally) from the upper left corner of the window\n * pageYOffset Returns the pixels the current document has been scrolled (vertically) from the upper left corner of the window\n * parent Returns the parent window of the current window\n * screen Returns the Screen object for the window (See Screen object)\n * screenLeft Returns the x coordinate of the window relative to the screen\n * screenTop Returns the y coordinate of the window relative to the screen\n * screenX Returns the x coordinate of the window relative to the screen\n * screenY Returns the y coordinate of the window relative to the screen\n * self Returns the current window\n * status Sets or returns the text in the statusbar of a window\n * top Returns the topmost browser window\n *\n * Method Description\n * ---\n * alert() Displays an alert box with a message and an OK button\n * atob() Decodes a base-64 encoded string\n * blur() Removes focus from the current window\n * btoa() Encodes a string in base-64\n * clearInterval() Clears a timer set with setInterval()\n * clearTimeout() Clears a timer set with setTimeout()\n * close() Closes the current window\n * confirm() Displays a dialog box with a message and an OK and a Cancel button\n * createPopup() Creates a pop-up window\n * focus() Sets focus to the current window\n * moveBy() Moves a window relative to its current position\n * moveTo() Moves a window to the specified position\n * open() Opens a new browser window\n * print() Prints the content of the current window\n * prompt() Displays a dialog box that prompts the visitor for input\n * resizeBy() Resizes the window by the specified pixels\n * resizeTo() Resizes the window to the specified width and height\n * scroll() This method has been replaced by the scrollTo() method.\n * scrollBy() Scrolls the content by the specified number of pixels\n * scrollTo() Scrolls the content to the specified coordinates\n * setInterval() Calls a function or evaluates an expression at specified intervals (in milliseconds)\n * setTimeout() Calls a function or evaluates an expression after a specified number of milliseconds\n * stop() Stops the window from loading\n */\n\nclass Web {\n /**\n * log(s, type)\n *\n * For diagnostic output only. DEBUG must be true (or \"--debug\" specified via the command-line)\n * for Component.log() to display anything.\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n static log(s, type)\n {\n Component.log(s, type);\n }\n\n /**\n * notice(s, fPrintOnly, id)\n *\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n */\n static notice(s, fPrintOnly, id)\n {\n Component.notice(s, fPrintOnly, id);\n }\n\n /**\n * alertUser(sMessage)\n * \n * NOTE: Legacy function for older modules (eg, DiskDump); see Component.alertUser().\n *\n * @param {string} sMessage\n */\n static alertUser(sMessage)\n {\n if (window) {\n window.alert(sMessage);\n } else {\n Web.log(sMessage);\n }\n }\n\n /**\n * getResource(sURL, type, fAsync, done, progress)\n *\n * Request the specified resource (sURL), and once the request is complete, notify done().\n *\n * If fAsync is true, a done() callback should ALWAYS be supplied; otherwise, you'll have no\n * idea when the request is complete or what the response was. done() is passed three parameters:\n *\n * done(sURL, resource, nErrorCode)\n *\n * If nErrorCode is zero, resource should contain the requested data; otherwise, an error occurred.\n *\n * If type is set to a string, that string can be used to control the response format;\n * by default, the response format is plain text, but you can specify \"arraybuffer\" to request arbitrary\n * binary data, in which case the returned resource will be a ArrayBuffer rather than a string.\n *\n * @param {string} sURL\n * @param {string|Object|null} [type] (object for POST request, otherwise type of GET request)\n * @param {boolean} [fAsync] is true for an asynchronous request; false otherwise (MUST be set for IE)\n * @param {function(string,string,number)} [done]\n * @param {function(number)} [progress]\n * @return {Array|null} Array containing [resource, nErrorCode], or null if no response available (yet)\n */\n static getResource(sURL, type = \"text\", fAsync = false, done, progress)\n {\n var nErrorCode = 0, resource = null, response = null;\n\n if (typeof resources == 'object' && (resource = resources[sURL])) {\n if (done) done(sURL, resource, nErrorCode);\n return [resource, nErrorCode];\n }\n else if (fAsync && typeof resources == 'function') {\n resources(sURL, function(resource, nErrorCode)\n {\n if (done) done(sURL, resource, nErrorCode);\n });\n return response;\n }\n\n if (!DEBUG && !NODE) {\n /*\n * TODO: Perhaps it's time for our code in netlib.js to finally add support for HTTPS; for now\n * though, it's just as well that the NODE environment assumes all resources are available locally.\n */\n sURL = sURL.replace(/^\\/(pcjs-disks|private-disks)\\//, \"https://jeffpar.github.io/$1/\");\n }\n else {\n /*\n * The larger resources we put on archive.pcjs.org should also be available locally.\n *\n * NOTE: \"http://archive.pcjs.org\" is now \"https://s3-us-west-2.amazonaws.com/archive.pcjs.org\"\n */\n sURL = sURL.replace(/^(http:\\/\\/archive\\.pcjs\\.org|https:\\/\\/s3-us-west-2\\.amazonaws\\.com\\/archive\\.pcjs\\.org)(\\/.*)\\/([^\\/]*)$/, \"$2/archive/$3\");\n sURL = sURL.replace(/^https:\\/\\/jeffpar\\.github\\.io\\/(pcjs-disks|private-disks)\\/(.*)$/, \"/$1/$2\");\n }\n\n\n var request = (window.XMLHttpRequest? new window.XMLHttpRequest() : new window.ActiveXObject(\"Microsoft.XMLHTTP\"));\n var fArrayBuffer = false, fXHR2 = (typeof request.responseType === 'string');\n \n var callback = function() {\n if (request.readyState !== 4) {\n if (progress) progress(1);\n return null;\n }\n /*\n * The following line was recommended for WebKit, as a work-around to prevent the handler firing multiple\n * times when debugging. Unfortunately, that's not the only XMLHttpRequest problem that occurs when\n * debugging, so I think the WebKit problem is deeper than that. When we have multiple XMLHttpRequests\n * pending, any debugging activity means most of them simply get dropped on floor, so what may actually be\n * happening are mis-notifications rather than redundant notifications.\n *\n * request.onreadystatechange = undefined;\n */\n /*\n * If the request failed due to, say, a CORS policy denial; eg:\n * \n * Failed to load http://www.allbootdisks.com/downloads/Disks/Windows_95_Boot_Disk_Download48/Diskette%20Images/Windows95a.img:\n * Redirect from 'http://www.allbootdisks.com/downloads/Disks/Windows_95_Boot_Disk_Download48/Diskette%20Images/Windows95a.img' to\n * 'http://www.allbootdisks.com/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.\n * Origin 'http://pcjs:8088' is therefore not allowed access.\n * \n * and our request type was \"arraybuffer\", attempting to access responseText may trigger an exception; eg:\n * \n * Uncaught DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's\n * 'responseType' is '' or 'text' (was 'arraybuffer').\n * \n * We could tiptoe around these potential landmines, but the safest thing to do is wrap this code with try/catch.\n */\n try {\n resource = fArrayBuffer? request.response : request.responseText;\n } catch(err) {\n if (MAXDEBUG) Web.log(\"xmlHTTPRequest(\" + sURL + \") exception: \" + err.message);\n }\n /*\n * The normal \"success\" case is a non-null resource and an HTTP status code of 200, but when loading files from the\n * local file system (ie, when using the \"file:\" protocol), we have to be a bit more flexible.\n */\n if (resource != null && (request.status == 200 || !request.status && resource.length && Web.getHostProtocol() == \"file:\")) {\n if (MAXDEBUG) Web.log(\"xmlHTTPRequest(\" + sURL + \"): returned \" + resource.length + \" bytes\");\n }\n else {\n nErrorCode = request.status || -1;\n Web.log(\"xmlHTTPRequest(\" + sURL + \"): error code \" + nErrorCode);\n }\n if (progress) progress(2);\n if (done) done(sURL, resource, nErrorCode);\n return [resource, nErrorCode];\n };\n \n if (fAsync) {\n request.onreadystatechange = callback;\n }\n\n if (progress) progress(0);\n\n if (type && typeof type == \"object\") {\n var sPost = \"\";\n for (var p in type) {\n if (!type.hasOwnProperty(p)) continue;\n if (sPost) sPost += \"&\";\n sPost += p + '=' + encodeURIComponent(type[p]);\n }\n sPost = sPost.replace(/%20/g, '+');\n if (MAXDEBUG) Web.log(\"Web.getResource(POST \" + sURL + \"): \" + sPost.length + \" bytes\");\n request.open(\"POST\", sURL, fAsync);\n request.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\n request.send(sPost);\n } else {\n if (MAXDEBUG) Web.log(\"Web.getResource(GET \" + sURL + \")\");\n request.open(\"GET\", sURL, fAsync);\n if (type == \"arraybuffer\") {\n if (fXHR2) {\n fArrayBuffer = true;\n request.responseType = type;\n } else {\n request.overrideMimeType(\"text/plain; charset=x-user-defined\");\n }\n }\n request.send();\n }\n\n if (!fAsync) {\n request.readyState = 4; // this may already be set for synchronous requests, but I don't want to take any chances \n response = callback();\n }\n return response;\n }\n\n /**\n * parseMemoryResource(sURL, sData)\n *\n * This converts a variety of JSON-style data streams into an Object with the following properties:\n *\n * aBytes\n * aSymbols\n * addrLoad\n * addrExec\n *\n * If the source data contains a 'bytes' array, it's passed through to 'aBytes'; alternatively, if\n * it contains a 'words' array, the values are converted from 16-bit to 8-bit and stored in 'aBytes',\n * and if it contains a 'longs' array, the values are converted from 32-bit longs into bytes and\n * stored in 'aBytes'.\n *\n * Alternatively, if the source data contains a 'data' array, we simply pass that through to the output\n * object as:\n *\n * aData\n *\n * @param {string} sURL\n * @param {string} sData\n * @return {Object|null} (resource)\n */\n static parseMemoryResource(sURL, sData)\n {\n var i;\n var resource = {\n aBytes: null,\n aSymbols: null,\n addrLoad: null,\n addrExec: null\n };\n\n if (sData.charAt(0) == \"[\" || sData.charAt(0) == \"{\") {\n try {\n var a, ib, data;\n\n if (sData.substr(0, 1) == \"<\") { // if the \"data\" begins with a \"<\"...\n /*\n * Early server configs reported an error (via the nErrorCode parameter) if a tape URL was invalid,\n * but more recent server configs now display a somewhat friendlier HTML error page. The downside,\n * however, is that the original error has been buried, and we've received \"data\" that isn't actually\n * tape data. So if the data we've received appears to be \"HTML-like\", we treat it as an error message.\n */\n throw new Error(sData);\n }\n\n /*\n * TODO: IE9 is rather unfriendly and restrictive with regard to how much data it's willing to\n * eval(). In particular, the 10Mb disk image we use for the Windows 1.01 demo config fails in\n * IE9 with an \"Out of memory\" exception. One work-around would be to chop the data into chunks\n * (perhaps one track per chunk, using regular expressions) and then manually re-assemble it.\n *\n * However, it turns out that using JSON.parse(sDiskData) instead of eval(\"(\" + sDiskData + \")\")\n * is a much easier fix. The only drawback is that we must first quote any unquoted property names\n * and remove any comments, because while eval() was cool with them, JSON.parse() is more particular;\n * the following RegExp replacements take care of those requirements.\n *\n * The use of hex values is something else that eval() was OK with, but JSON.parse() is not, and\n * while I've stopped using hex values in DumpAPI responses (at least when \"format=json\" is specified),\n * I can't guarantee they won't show up in \"legacy\" images, and there's no simple RegExp replacement\n * for transforming hex values into decimal values, so I cop out and fall back to eval() if I detect\n * any hex prefixes (\"0x\") in the sequence. Ditto for error messages, which appear like so:\n *\n * [\"unrecognized disk path: test.img\"]\n */\n if (sData.indexOf(\"0x\") < 0 && sData.indexOf(\"0o\") < 0 && sData.substr(0, 2) != '[\"') {\n data = JSON.parse(sData.replace(/([a-z]+):/gm, '\"$1\":').replace(/\\/\\/[^\\n]*/gm, \"\"));\n } else {\n data = eval(\"(\" + sData + \")\");\n }\n\n resource.addrLoad = data['load'];\n resource.addrExec = data['exec'];\n\n if (a = data['bytes']) {\n resource.aBytes = a;\n }\n else if (a = data['words']) {\n /*\n * Convert all words into bytes\n */\n resource.aBytes = new Array(a.length * 2);\n for (i = 0, ib = 0; i < a.length; i++) {\n resource.aBytes[ib++] = a[i] & 0xff;\n resource.aBytes[ib++] = (a[i] >> 8) & 0xff;\n\n }\n }\n else if (a = data['longs']) {\n /*\n * Convert all dwords (longs) into bytes\n */\n resource.aBytes = new Array(a.length * 4);\n for (i = 0, ib = 0; i < a.length; i++) {\n resource.aBytes[ib++] = a[i] & 0xff;\n resource.aBytes[ib++] = (a[i] >> 8) & 0xff;\n resource.aBytes[ib++] = (a[i] >> 16) & 0xff;\n resource.aBytes[ib++] = (a[i] >> 24) & 0xff;\n }\n }\n else if (a = data['data']) {\n resource.aData = a;\n }\n else {\n resource.aBytes = data;\n }\n\n if (resource.aBytes) {\n if (!resource.aBytes.length) {\n Component.error(\"Empty resource: \" + sURL);\n resource = null;\n }\n else if (resource.aBytes.length == 1) {\n Component.error(resource.aBytes[0]);\n resource = null;\n }\n }\n resource.aSymbols = data['symbols'];\n\n } catch (e) {\n Component.error(\"Resource data error (\" + sURL + \"): \" + e.message);\n resource = null;\n }\n }\n else {\n /*\n * Parse the data manually; we assume it's a series of hex byte-values separated by whitespace.\n */\n var ab = [];\n var sHexData = sData.replace(/\\n/gm, \" \").replace(/ +$/, \"\");\n var asHexData = sHexData.split(\" \");\n for (i = 0; i < asHexData.length; i++) {\n var n = parseInt(asHexData[i], 16);\n if (isNaN(n)) {\n Component.error(\"Resource data error (\" + sURL + \"): invalid hex byte (\" + asHexData[i] + \")\");\n break;\n }\n ab.push(n & 0xff);\n }\n if (i == asHexData.length) resource.aBytes = ab;\n }\n return resource;\n }\n\n /**\n * sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)\n *\n * Send a report (eg, bug report) to the server.\n *\n * @param {string} sApp (eg, \"PCjs\")\n * @param {string} sVer (eg, \"1.02\")\n * @param {string} sURL (eg, \"/devices/pc/machine/5150/mda/64kb/machine.xml\")\n * @param {string} sUser (ie, the user key, if any)\n * @param {string} sType (eg, \"bug\"); one of ReportAPI.TYPE.*\n * @param {string} sReport (eg, unparsed state data)\n * @param {string} [sHostName] (default is http://SITEHOST)\n */\n static sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)\n {\n var dataPost = {};\n dataPost[ReportAPI.QUERY.APP] = sApp;\n dataPost[ReportAPI.QUERY.VER] = sVer;\n dataPost[ReportAPI.QUERY.URL] = sURL;\n dataPost[ReportAPI.QUERY.USER] = sUser;\n dataPost[ReportAPI.QUERY.TYPE] = sType;\n dataPost[ReportAPI.QUERY.DATA] = sReport;\n var sReportURL = (sHostName? sHostName : \"http://\" + SITEHOST) + ReportAPI.ENDPOINT;\n Web.getResource(sReportURL, dataPost, true);\n }\n\n /**\n * getHost()\n *\n * @return {string}\n */\n static getHost()\n {\n return (\"http://\" + (window? window.location.host : SITEHOST));\n }\n\n /**\n * getHostURL()\n *\n * @return {string|null}\n */\n static getHostURL()\n {\n return (window? window.location.href : null);\n }\n\n /**\n * getHostProtocol()\n *\n * @return {string}\n */\n static getHostProtocol()\n {\n return (window? window.location.protocol : \"file:\");\n }\n\n /**\n * getUserAgent()\n *\n * @return {string}\n */\n static getUserAgent()\n {\n return (window? window.navigator.userAgent : \"\");\n }\n\n /**\n * hasLocalStorage\n *\n * true if localStorage support exists, is enabled, and works; false otherwise\n *\n * @return {boolean}\n */\n static hasLocalStorage()\n {\n if (Web.fLocalStorage == null) {\n var f = false;\n if (window) {\n try {\n window.localStorage.setItem(Web.sLocalStorageTest, Web.sLocalStorageTest);\n f = (window.localStorage.getItem(Web.sLocalStorageTest) == Web.sLocalStorageTest);\n window.localStorage.removeItem(Web.sLocalStorageTest);\n } catch (e) {\n Web.logLocalStorageError(e);\n f = false;\n }\n }\n Web.fLocalStorage = f;\n }\n return Web.fLocalStorage;\n }\n\n /**\n * logLocalStorageError(e)\n *\n * @param {Error} e is an exception\n */\n static logLocalStorageError(e)\n {\n Web.log(e.message, \"localStorage error\");\n }\n\n /**\n * getLocalStorageItem(sKey)\n *\n * Returns the requested key value, or null if the key does not exist, or undefined if localStorage is not available\n *\n * @param {string} sKey\n * @return {string|null|undefined} sValue\n */\n static getLocalStorageItem(sKey)\n {\n var sValue;\n if (window) {\n try {\n sValue = window.localStorage.getItem(sKey);\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n }\n return sValue;\n }\n\n /**\n * setLocalStorageItem(sKey, sValue)\n *\n * @param {string} sKey\n * @param {string} sValue\n * @return {boolean} true if localStorage is available, false if not\n */\n static setLocalStorageItem(sKey, sValue)\n {\n try {\n window.localStorage.setItem(sKey, sValue);\n return true;\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n return false;\n }\n\n /**\n * removeLocalStorageItem(sKey)\n *\n * @param {string} sKey\n */\n static removeLocalStorageItem(sKey)\n {\n try {\n window.localStorage.removeItem(sKey);\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n }\n\n /**\n * getLocalStorageKeys()\n *\n * @return {Array}\n */\n static getLocalStorageKeys()\n {\n var a = [];\n try {\n for (var i = 0, c = window.localStorage.length; i < c; i++) {\n a.push(window.localStorage.key(i));\n }\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n return a;\n }\n\n /**\n * reloadPage()\n */\n static reloadPage()\n {\n if (window) window.location.reload();\n }\n\n /**\n * isUserAgent(s)\n *\n * Check the browser's user-agent string for the given substring; \"iOS\" and \"MSIE\" are special values you can\n * use that will match any iOS or MSIE browser, respectively (even IE11, in the case of \"MSIE\").\n *\n * 2013-11-06: In a questionable move, MSFT changed the user-agent reported by IE11 on Windows 8.1, eliminating\n * the \"MSIE\" string (which MSDN calls a \"version token\"; see http://msdn.microsoft.com/library/ms537503.aspx);\n * they say \"public websites should rely on feature detection, rather than browser detection, in order to design\n * their sites for browsers that don't support the features used by the website.\" So, in IE11, we get a user-agent\n * that tries to fool apps into thinking the browser is more like WebKit or Gecko:\n *\n * Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko\n *\n * That's a nice idea, but in the meantime, they hosed the XSL transform code in embed.js, which contained\n * some very critical browser-specific code; turning on IE's \"Compatibility Mode\" didn't help either, because\n * that's a sledgehammer solution which restores the old user-agent string but also disables other features like\n * HTML5 canvas support. As an interim solution, I'm treating any \"MSIE\" check as a check for either \"MSIE\" or\n * \"Trident\".\n *\n * UPDATE: I've since found ways to make the code in embed.js more browser-agnostic, so for now, there's isn't\n * any code that cares about \"MSIE\", but I've left the change in place, because I wouldn't be surprised if I'll\n * need more IE-specific code in the future, perhaps for things like copy/paste functionality, or mouse capture.\n *\n * @param {string} s is a substring to search for in the user-agent; as noted above, \"iOS\" and \"MSIE\" are special values\n * @return {boolean} is true if the string was found, false if not\n */\n static isUserAgent(s)\n {\n if (window) {\n var userAgent = Web.getUserAgent();\n /*\n * Here's one case where we have to be careful with Component, because when isUserAgent() is called by\n * the init code below, component.js hasn't been loaded yet. The simple solution for now is to remove the call.\n *\n * Web.log(\"agent: \" + userAgent);\n *\n * And yes, it would be pointless to use the conditional (?) operator below, if not for the Google Closure\n * Compiler (v20130823) failing to detect the entire expression as a boolean.\n */\n return s == \"iOS\" && !!userAgent.match(/(iPod|iPhone|iPad)/) && !!userAgent.match(/AppleWebKit/) || s == \"MSIE\" && !!userAgent.match(/(MSIE|Trident)/) || (userAgent.indexOf(s) >= 0);\n }\n return false;\n }\n\n /**\n * isMobile(sDevice)\n *\n * Checks the URL for a \"mobile\" parameter, and failing that, checks the browser's user-agent string for the\n * substring \"Mobi\", as per Mozilla recommendation:\n *\n * https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent\n *\n * @param {string} [sDevice] (eg, \"iPad\" to check for iPad, or \"!iPad\" to specifically exclude it) \n * @return {boolean} is true if the browser appears to be a mobile (ie, non-desktop) web browser, false if not\n */\n static isMobile(sDevice)\n {\n var sMobile = Web.getURLParm(\"mobile\");\n if (sMobile) return sMobile == \"true\";\n if (Web.isUserAgent(\"Mobi\")) {\n if (!sDevice) return true;\n var fInvert = sDevice[0] == '!';\n if (fInvert) sDevice = sDevice.substr(1);\n return Web.isUserAgent(sDevice) != fInvert;\n }\n return false;\n }\n\n /**\n * findProperty(obj, sProp, sSuffix)\n *\n * If both sProp and sSuffix are set, then any browser-specific prefixes are inserted between sProp and sSuffix,\n * and if a match is found, it is returned without sProp.\n *\n * For example, if findProperty(document, 'on', 'fullscreenchange') discovers that 'onwebkitfullscreenchange' exists,\n * it will return 'webkitfullscreenchange', in preparation for an addEventListener() call.\n *\n * More commonly, sSuffix is not used, so whatever property is found is returned as-is.\n *\n * @param {Object|null|undefined} obj\n * @param {string} sProp\n * @param {string} [sSuffix]\n * @return {string|null}\n */\n static findProperty(obj, sProp, sSuffix)\n {\n if (obj) {\n for (var i = 0; i < Web.asBrowserPrefixes.length; i++) {\n var sName = Web.asBrowserPrefixes[i];\n if (sSuffix) {\n sName += sSuffix;\n var sEvent = sProp + sName;\n if (sEvent in obj) return sName;\n } else {\n if (!sName) {\n sName = sProp[0];\n } else {\n sName += sProp[0].toUpperCase();\n }\n sName += sProp.substr(1);\n if (sName in obj) return sName;\n }\n }\n }\n return null;\n }\n\n /**\n * getURLParm(sParm)\n *\n * First looks for sParm exactly as specified, then looks for the lower-case version.\n *\n * @param {string} sParm\n * @return {string|undefined}\n */\n static getURLParm(sParm)\n {\n if (!Web.parmsURL) {\n Web.parmsURL = Web.parseURLParms();\n }\n return Web.parmsURL[sParm] || Web.parmsURL[sParm.toLowerCase()];\n }\n\n /**\n * parseURLParms(sParms)\n *\n * @param {string} [sParms] containing the parameter portion of a URL (ie, after the '?')\n * @return {Object} containing properties for each parameter found\n */\n static parseURLParms(sParms)\n {\n var aParms = {};\n if (window) { // an alternative to \"if (typeof module === 'undefined')\" if require(\"defines\") was used\n if (!sParms) {\n /*\n * Note that window.location.href returns the entire URL, whereas window.location.search\n * returns only the parameters, if any (starting with the '?', which we skip over with a substr() call).\n */\n sParms = window.location.search.substr(1);\n }\n var match;\n var pl = /\\+/g; // RegExp for replacing addition symbol with a space\n var search = /([^&=]+)=?([^&]*)/g;\n var decode = function(s)\n {\n return decodeURIComponent(s.replace(pl, \" \"));\n };\n\n while ((match = search.exec(sParms))) {\n aParms[decode(match[1])] = decode(match[2]);\n }\n }\n return aParms;\n }\n\n /**\n * downloadFile(sData, sType, fBase64, sFileName)\n *\n * @param {string} sData\n * @param {string} sType\n * @param {boolean} [fBase64]\n * @param {string} [sFileName]\n */\n static downloadFile(sData, sType, fBase64, sFileName)\n {\n var link = null, sAlert;\n var sURI = \"data:application/\" + sType + (fBase64? \";base64\" : \"\") + \",\";\n\n if (!Web.isUserAgent(\"Firefox\")) {\n sURI += (fBase64? sData : encodeURI(sData));\n } else {\n sURI += (fBase64? sData : encodeURIComponent(sData));\n }\n if (sFileName) {\n link = document.createElement('a');\n if (typeof link.download != 'string') link = null;\n }\n if (link) {\n link.href = sURI;\n link.download = sFileName;\n document.body.appendChild(link); // Firefox allegedly requires the link to be in the body\n link.click();\n document.body.removeChild(link);\n sAlert = 'Check your Downloads folder for ' + sFileName + '.';\n if (Web.isUserAgent(\"Chrome\")) {\n sAlert += '\\n\\nIn Chrome, after clicking OK, you may ALSO have to select the \"Window\" menu, choose \"Downloads\", and then locate this download and select \"Keep\".';\n sAlert += '\\n\\nThis is part of Chrome\\'s \"Security By Jumping Through Extra Hoops\" technology, which is much easier for Google to implement than actually checking for something malicious.';\n sAlert += '\\n\\nAnd for the record, there is nothing malicious on the PCjs website.';\n }\n } else {\n window.open(sURI);\n sAlert = 'Check your browser for a new window/tab containing the requested data' + (sFileName? (' (' + sFileName + ')') : '') + '.';\n }\n return sAlert;\n }\n\n /**\n * onCountRepeat(n, fnRepeat, fnComplete, msDelay)\n *\n * Call fnRepeat() n times with an msDelay millisecond delay between calls,\n * then call fnComplete() when n has been exhausted OR fnRepeat() returns false.\n *\n * @param {number} n\n * @param {function()} fnRepeat\n * @param {function()} fnComplete\n * @param {number} [msDelay]\n */\n static onCountRepeat(n, fnRepeat, fnComplete, msDelay)\n {\n var fnTimeout = function doCountRepeat()\n {\n n -= 1;\n if (n >= 0) {\n if (!fnRepeat()) n = 0;\n }\n if (n > 0) {\n setTimeout(fnTimeout, msDelay || 0);\n return;\n }\n fnComplete();\n };\n fnTimeout();\n }\n\n /**\n * onClickRepeat(e, msDelay, msRepeat, fn)\n *\n * Repeatedly call fn() with an initial msDelay, and an msRepeat delay thereafter,\n * as long as HTML control Object e has an active \"down\" event and fn() returns true.\n *\n * @param {Object} e\n * @param {number} msDelay\n * @param {number} msRepeat\n * @param {function(boolean)} fn is passed false on the first call, true on all repeated calls\n */\n static onClickRepeat(e, msDelay, msRepeat, fn)\n {\n var ms = 0, timer = null, fIgnoreMouseEvents = false;\n\n var fnRepeat = function doClickRepeat()\n {\n if (fn(ms === msRepeat)) {\n timer = setTimeout(fnRepeat, ms);\n ms = msRepeat;\n }\n };\n e.onmousedown = function()\n {\n // Web.log(\"onMouseDown()\");\n if (!fIgnoreMouseEvents) {\n if (!timer) {\n ms = msDelay;\n fnRepeat();\n }\n }\n };\n e.ontouchstart = function()\n {\n // Web.log(\"onTouchStart()\");\n if (!timer) {\n ms = msDelay;\n fnRepeat();\n }\n };\n e.onmouseup = e.onmouseout = function()\n {\n // Web.log(\"onMouseUp()/onMouseOut()\");\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n };\n e.ontouchend = e.ontouchcancel = function()\n {\n // Web.log(\"onTouchEnd()/onTouchCancel()\");\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n /*\n * Devices that generate ontouch* events ALSO generate onmouse* events,\n * and generally do so immediately after all the touch events are complete,\n * so unless we want double the action, we need to ignore mouse events.\n */\n fIgnoreMouseEvents = true;\n };\n }\n\n /**\n * onPageEvent(sName, fn)\n *\n * For 'onload', 'onunload', and 'onpageshow' events, most callers should NOT use this function, but\n * instead use Web.onInit(), Web.onShow(), and Web.onExit(), respectively.\n *\n * The only components that should still use onPageEvent() are THIS component (see the bottom of this file)\n * and components that need to capture other events (eg, the 'onresize' event in the Video component).\n *\n * This function creates a chain of callbacks, allowing multiple JavaScript modules to define handlers\n * for the same event, which wouldn't be possible if everyone modified window['onload'], window['onunload'],\n * etc, themselves. However, that's less of a concern now, because assuming everyone else is now using\n * onInit(), onExit(), etc, then there really IS only one component setting the window callback: this one.\n *\n * NOTE: It's risky to refer to obscure event handlers with \"dot\" names, because the Closure Compiler may\n * erroneously replace them (eg, window.onpageshow is a good example).\n *\n * @param {string} sFunc\n * @param {function()} fn\n */\n static onPageEvent(sFunc, fn)\n {\n if (window) {\n var fnPrev = window[sFunc];\n if (typeof fnPrev !== 'function') {\n window[sFunc] = fn;\n } else {\n /*\n * TODO: Determine whether there's any value in receiving/sending the Event object that the\n * browser provides when it generates the original event.\n */\n window[sFunc] = function onWindowEvent()\n {\n if (fnPrev) fnPrev();\n fn();\n };\n }\n }\n };\n\n /**\n * onInit(fn)\n *\n * Use this instead of setting window.onload. Allows multiple JavaScript modules to define their own 'onload' event handler.\n *\n * @param {function()} fn\n */\n static onInit(fn)\n {\n Web.aPageEventHandlers['init'].push(fn);\n };\n\n /**\n * onShow(fn)\n *\n * @param {function()} fn\n *\n * Use this instead of setting window.onpageshow. Allows multiple JavaScript modules to define their own 'onpageshow' event handler.\n */\n static onShow(fn)\n {\n Web.aPageEventHandlers['show'].push(fn);\n };\n\n /**\n * onExit(fn)\n *\n * @param {function()} fn\n *\n * Use this instead of setting window.onunload. Allows multiple JavaScript modules to define their own 'onunload' event handler.\n */\n static onExit(fn)\n {\n Web.aPageEventHandlers['exit'].push(fn);\n };\n\n /**\n * doPageEvent(afn)\n *\n * @param {Array.<function()>} afn\n */\n static doPageEvent(afn)\n {\n if (Web.fPageEventsEnabled) {\n try {\n for (var i = 0; i < afn.length; i++) {\n afn[i]();\n }\n } catch (e) {\n Web.notice(\"An unexpected error occurred: \" + e.message + \"\\n\\nIf it happens again, please send this information to support@pcjs.org. Thanks.\");\n }\n }\n };\n\n /**\n * enablePageEvents(fEnable)\n *\n * @param {boolean} fEnable is true to enable page events, false to disable (they're enabled by default)\n */\n static enablePageEvents(fEnable)\n {\n if (!Web.fPageEventsEnabled && fEnable) {\n Web.fPageEventsEnabled = true;\n if (Web.fPageLoaded) Web.sendPageEvent('init');\n if (Web.fPageShowed) Web.sendPageEvent('show');\n return;\n }\n Web.fPageEventsEnabled = fEnable;\n }\n\n /**\n * sendPageEvent(sEvent)\n *\n * This allows us to manually trigger page events.\n *\n * @param {string} sEvent (one of 'init', 'show' or 'exit')\n */\n static sendPageEvent(sEvent)\n {\n if (Web.aPageEventHandlers[sEvent]) {\n Web.doPageEvent(Web.aPageEventHandlers[sEvent]);\n }\n }\n}\n\nWeb.parmsURL = null; // initialized on first call to parseURLParms()\n\nWeb.aPageEventHandlers = {\n 'init': [], // list of window 'onload' handlers\n 'show': [], // list of window 'onpageshow' handlers\n 'exit': [] // list of window 'onunload' handlers (although we prefer to use 'onbeforeunload' if possible)\n};\n\nWeb.asBrowserPrefixes = ['', 'moz', 'ms', 'webkit'];\n\nWeb.fPageLoaded = false; // set once the page's first 'onload' event has occurred\nWeb.fPageShowed = false; // set once the page's first 'onpageshow' event has occurred\nWeb.fPageEventsEnabled = true; // default is true, set to false (or true) by enablePageEvents()\n\n/**\n * fLocalStorage\n *\n * true if localStorage support exists, is enabled, and works; \"falsey\" otherwise\n *\n * @type {boolean|null}\n */\nWeb.fLocalStorage = null;\n\n/**\n * TODO: Is there any way to get the Closure Compiler to stop inlining this string? This isn't cutting it.\n *\n * @const {string}\n */\nWeb.sLocalStorageTest = \"PCjs.localStorage\";\n\nWeb.onPageEvent('onload', function onPageLoad() {\n Web.fPageLoaded = true;\n Web.doPageEvent(Web.aPageEventHandlers['init']);\n});\n\nWeb.onPageEvent('onpageshow', function onPageShow() {\n Web.fPageShowed = true;\n Web.doPageEvent(Web.aPageEventHandlers['show']);\n});\n\nWeb.onPageEvent(Web.isUserAgent(\"iOS\")? 'onpagehide' : (Web.isUserAgent(\"Opera\")? 'onunload' : 'onbeforeunload'), function onPageUnload() {\n Web.doPageEvent(Web.aPageEventHandlers['exit']);\n});\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/component.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * All PCjs components now use JSDoc types, primarily so that Google's Closure Compiler will compile\n * everything with zero warnings when ADVANCED_OPTIMIZATIONS are enabled. For more information about\n * the JSDoc types supported by the Closure Compiler:\n *\n * https://developers.google.com/closure/compiler/docs/js-for-compiler#types\n *\n * I also attempted to validate this code with JSLint, but it complained too much; eg, it didn't like\n * \"while (true)\", a tried and \"true\" programming convention for decades, and it wanted me to replace\n * all \"++\" and \"--\" operators with \"+= 1\" and \"-= 1\", use \"(s || '')\" instead of \"(s? s : '')\", etc.\n *\n * I prefer sticking with traditional C-style idioms, in part because they are more portable. That\n * does NOT mean I'm trying to write \"portable JavaScript,\" but some of this code was ported from C code\n * I'd written long ago, so portability is good, and I'm not going to throw that away if there's no need.\n *\n * UPDATE: I've since switched from JSLint to JSHint, which seems to have more reasonable defaults.\n * And for new code, I have adopted some popular JavaScript idioms, like \"(s || '')\", although the need\n * for those kinds of expressions will be reduced as I also start adopting some ES6 features, like\n * default parameters.\n */\n\n\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * subclass (eg, SerialPort), because otherwise the Compiler won't allow us to *reference*\n * the named property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass Component {\n /**\n * Component(type, parms, bitsMessage)\n *\n * A Component object requires:\n *\n * type: a user-defined type name (eg, \"CPU\")\n *\n * and accepts any or all of the following (parms) properties:\n *\n * id: component ID (default is \"\")\n * name: component name (default is \"\"; if blank, toString() will use the type name only)\n * comment: component comment string (default is undefined)\n *\n * Component subclasses will usually have additional (parms) properties.\n *\n * @param {string} type\n * @param {Object} [parms]\n * @param {number} [bitsMessage] selects message(s) that the component wants to enable (default is 0)\n */\n constructor(type, parms, bitsMessage)\n {\n this.type = type;\n\n if (!parms) parms = {'id': \"\", 'name': \"\"};\n\n this.id = parms['id'] || \"\";\n this.name = parms['name'];\n this.comment = parms['comment'];\n this.parms = parms;\n\n /*\n * The following Component properties need to be accessible by other machines and/or command scripts;\n * well, OK, or we could have exported some new functions to walk the contents of these properties, as we\n * did with findMachineComponent(), but this works just as well.\n *\n * Also, while the double-assignment looks silly (ie, using both dot and bracket property notation), it\n * resolves a complaint from the Closure Compiler, because if we use ONLY bracket notation here, then the\n * Compiler wants us to change all the other references to bracket notation as well.\n */\n this.exports = this['exports'] = {};\n this.bindings = this['bindings'] = {};\n\n var i = this.id.indexOf('.');\n if (i < 0) {\n this.idComponent = this.id;\n } else {\n this.idMachine = this.id.substr(0, i);\n this.idComponent = this.id.substr(i + 1);\n }\n\n /*\n * Gather all the various component flags (booleans) into a single \"flags\" object, and encourage\n * subclasses to do the same, to reduce the property clutter we have to wade through while debugging.\n */\n this.flags = {\n ready: false,\n busy: false,\n busyCancel: false,\n initDone: false,\n powered: false,\n unloading: false,\n error: false\n };\n\n this.fnReady = null;\n this.clearError();\n this.bitsMessage = bitsMessage || 0;\n\n this.cmp = null;\n this.bus = null;\n this.cpu = null;\n this.dbg = null;\n\n /*\n * TODO: Consider adding another parameter to the Component() constructor that allows components to tell\n * us if they support single or multiple instances per machine. For example, there can be multiple SerialPort\n * components per machine, but only one CPU component (some machines also support an FPU, but that component\n * is considered separate from the CPU).\n *\n * It's not critical, but it would help catch machine configuration errors; for example, a machine that mistakenly\n * includes two CPU components may, aside from wasting memory, end up with odd side-effects, like unresponsive\n * CPU controls.\n */\n Component.add(this);\n }\n\n /**\n * Component.add(component)\n *\n * @param {Component} component\n */\n static add(component)\n {\n /*\n * This just generates a lot of useless noise, handy in the early days, not so much these days....\n *\n * if (DEBUG) Component.log(\"Component.add(\" + component.type + \",\" + component.id + \")\");\n */\n Component.components.push(component);\n }\n\n /**\n * Component.addMachine(idMachine)\n *\n * @param {string} idMachine\n */\n static addMachine(idMachine)\n {\n Component.machines[idMachine] = {};\n }\n\n /**\n * Component.addMachineResource(idMachine, sName, data)\n *\n * @param {string} idMachine\n * @param {string|null} sName (name of the resource)\n * @param {*} data\n */\n static addMachineResource(idMachine, sName, data)\n {\n /*\n * I used to assert(Component.machines[idMachine]), but when we're running as a Node app, embed.js is not used,\n * so addMachine() is never called, so resources do not need to be recorded.\n */\n if (Component.machines[idMachine] && sName) {\n Component.machines[idMachine][sName] = data;\n }\n }\n\n /**\n * Component.getMachineResources(idMachine)\n *\n * @param {string} idMachine\n * @return {Object|undefined}\n */\n static getMachineResources(idMachine)\n {\n return Component.machines[idMachine];\n }\n\n /**\n * Component.getTime()\n *\n * @return {number} the current time, in milliseconds\n */\n static getTime()\n {\n return Date.now() || +new Date();\n }\n\n /**\n * Component.log(s, type)\n *\n * For diagnostic output only.\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n static log(s, type)\n {\n if (!COMPILED) {\n if (s) {\n var sElapsed = \"\", sMsg = (type? (type + \": \") : \"\") + s;\n if (typeof Usr != \"undefined\") {\n if (Component.msStart === undefined) {\n Component.msStart = Component.getTime();\n }\n sElapsed = (Component.getTime() - Component.msStart) + \"ms: \";\n }\n sMsg = sMsg.replace(/\\r/g, '\\\\r').replace(/\\n/g, ' ');\n if (window && window.console) console.log(sElapsed + sMsg);\n }\n }\n }\n\n /**\n * Component.assert(f, s)\n *\n * Verifies conditions that must be true (for DEBUG builds only).\n *\n * The Closure Compiler should automatically remove all references to Component.assert() in non-DEBUG builds.\n * TODO: Add a task to the build process that \"asserts\" there are no instances of \"assertion failure\" in RELEASE builds.\n *\n * @param {boolean} f is the expression we are asserting to be true\n * @param {string} [s] is description of the assertion on failure\n */\n static assert(f, s)\n {\n if (DEBUG) {\n if (!f) {\n if (!s) s = \"assertion failure\";\n Component.log(s);\n throw new Error(s);\n }\n }\n }\n\n /**\n * Component.print(s)\n *\n * Components that inherit from this class should use this.print(), rather than Component.print(), because\n * if a Control Panel is loaded, it will override only the instance method, not the class method (overriding the\n * class method would improperly affect any other machines loaded on the same page).\n *\n * @this {Component}\n * @param {string} s\n */\n static print(s)\n {\n if (!COMPILED) {\n var i = s.lastIndexOf('\\n');\n if (i >= 0) {\n Component.println(s.substr(0, i));\n s = s.substr(i + 1);\n }\n Component.printBuffer += s;\n }\n }\n\n /**\n * Component.println(s, type, id)\n *\n * Components that inherit from this class should use this.println(), rather than Component.println(), because\n * if a Control Panel is loaded, it will override only the instance method, not the class method (overriding the\n * class method would improperly affect any other machines loaded on the same page).\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n * @param {string} [id] is the caller's ID, if any\n */\n static println(s, type, id)\n {\n if (!COMPILED) {\n s = Component.printBuffer + (s || \"\");\n Component.log((id? (id + \": \") : \"\") + (s? (\"\\\"\" + s + \"\\\"\") : \"\"), type);\n Component.printBuffer = \"\";\n }\n }\n\n /**\n * Component.notice(s, fPrintOnly, id)\n *\n * notice() is like println() but implies a need for user notification, so we alert() as well.\n *\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n * @return {boolean}\n */\n static notice(s, fPrintOnly, id)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.NOTICE, id);\n }\n if (!fPrintOnly) Component.alertUser((id? (id + \": \") : \"\") + s);\n return true;\n }\n\n /**\n * Component.warning(s)\n *\n * @param {string} s describes the warning\n */\n static warning(s)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.WARNING);\n }\n Component.alertUser(s);\n }\n\n /**\n * Component.error(s)\n *\n * @param {string} s describes the error; an alert() is displayed as well\n */\n static error(s)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.ERROR);\n }\n Component.alertUser(s);\n }\n\n /**\n * Component.alertUser(sMessage)\n *\n * @param {string} sMessage\n */\n static alertUser(sMessage)\n {\n if (window) {\n window.alert(sMessage);\n } else {\n Component.log(sMessage);\n }\n }\n\n /**\n * Component.confirmUser(sPrompt)\n *\n * @param {string} sPrompt\n * @returns {boolean} true if the user clicked OK, false if Cancel/Close\n */\n static confirmUser(sPrompt)\n {\n var fResponse = false;\n if (window) {\n fResponse = window.confirm(sPrompt);\n }\n return fResponse;\n }\n\n /**\n * Component.promptUser()\n *\n * @param {string} sPrompt\n * @param {string} [sDefault]\n * @returns {string|null}\n */\n static promptUser(sPrompt, sDefault)\n {\n var sResponse = null;\n if (window) {\n sResponse = window.prompt(sPrompt, sDefault === undefined? \"\" : sDefault);\n }\n return sResponse;\n }\n\n /**\n * Component.appendControl(control, sText)\n *\n * @param {Object} control\n * @param {string} sText\n */\n static appendControl(control, sText)\n {\n control.value += sText;\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (COMPILED) {\n sText = control.value;\n if (sText.length > 8192) control.value = sText.substr(sText.length - 4096);\n }\n control.scrollTop = control.scrollHeight;\n }\n\n /**\n * Component.replaceControl(control, sSearch, sReplace)\n *\n * @param {Object} control\n * @param {string} sSearch\n * @param {string} sReplace\n */\n static replaceControl(control, sSearch, sReplace)\n {\n var sText = control.value;\n var i = sText.lastIndexOf(sSearch);\n if (i < 0) {\n sText += sSearch + '\\n';\n } else {\n sText = sText.substr(0, i) + sReplace + sText.substr(i + sSearch.length);\n }\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (COMPILED && sText.length > 8192) sText = sText.substr(sText.length - 4096);\n control.value = sText;\n control.scrollTop = control.scrollHeight;\n }\n\n /**\n * Component.bindExternalControl(component, sBinding, sType)\n *\n * @param {Component} component\n * @param {string} sBinding\n * @param {string} [sType] is the external component type (default is \"Panel\")\n */\n static bindExternalControl(component, sBinding, sType = \"Panel\")\n {\n if (sBinding) {\n var target = Component.getComponentByType(sType, component.id);\n if (target) {\n var control = target.bindings[sBinding];\n if (control) {\n component.setBinding(\"\", sBinding, control);\n }\n }\n }\n }\n\n /**\n * Component.bindComponentControls(component, element, sAppClass)\n *\n * @param {Component} component\n * @param {HTMLElement} element from the DOM\n * @param {string} sAppClass\n */\n static bindComponentControls(component, element, sAppClass)\n {\n var aeControls = Component.getElementsByClass(element.parentNode, sAppClass + \"-control\");\n\n for (var iControl = 0; iControl < aeControls.length; iControl++) {\n\n var aeChildNodes = aeControls[iControl].childNodes;\n\n for (var iNode = 0; iNode < aeChildNodes.length; iNode++) {\n var control = aeChildNodes[iNode];\n if (control.nodeType !== 1 /* document.ELEMENT_NODE */) {\n continue;\n }\n var sClass = control.getAttribute(\"class\");\n if (!sClass) continue;\n var aClasses = sClass.split(\" \");\n for (var iClass = 0; iClass < aClasses.length; iClass++) {\n var parms;\n sClass = aClasses[iClass];\n switch (sClass) {\n case sAppClass + \"-binding\":\n parms = Component.getComponentParms(/** @type {HTMLElement} */(control));\n if (parms && parms['binding'] !== undefined) {\n component.setBinding(parms['type'], parms['binding'], /** @type {HTMLElement} */(control), parms['value']);\n } else if (!parms || parms['type'] != \"description\") {\n Component.log(\"Component '\" + component.toString() + \"' missing binding\" + (parms? \" for \" + parms['type'] : \"\"), \"warning\");\n }\n iClass = aClasses.length;\n break;\n default:\n // if (DEBUG) Component.log(\"Component.bindComponentControls(\" + component.toString() + \"): unrecognized control class \\\"\" + sClass + \"\\\"\", \"warning\");\n break;\n }\n }\n }\n }\n }\n\n /**\n * Component.getComponents(idRelated)\n *\n * We could store components as properties, using the component's ID, and change\n * this linear lookup into a property lookup, but some components may have no ID.\n *\n * @param {string} [idRelated] of related component\n * @return {Array} of components\n */\n static getComponents(idRelated)\n {\n var i;\n var aComponents = [];\n /*\n * getComponentByID(id, idRelated)\n *\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated) {\n if ((i = idRelated.indexOf('.')) > 0)\n idRelated = idRelated.substr(0, i + 1);\n else\n idRelated = \"\";\n }\n for (i = 0; i < Component.components.length; i++) {\n var component = Component.components[i];\n if (!idRelated || !component.id.indexOf(idRelated)) {\n aComponents.push(component);\n }\n }\n return aComponents;\n }\n\n /**\n * Component.getComponentByID(id, idRelated)\n *\n * We could store components as properties, using the component's ID, and change\n * this linear lookup into a property lookup, but some components may have no ID.\n *\n * @param {string} id of the desired component\n * @param {string} [idRelated] of related component\n * @return {Component|null}\n */\n static getComponentByID(id, idRelated)\n {\n if (id !== undefined) {\n var i;\n /*\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated && (i = idRelated.indexOf('.')) > 0) {\n id = idRelated.substr(0, i + 1) + id;\n }\n for (i = 0; i < Component.components.length; i++) {\n if (Component.components[i].id === id) {\n return Component.components[i];\n }\n }\n if (Component.components.length) {\n Component.log(\"Component ID '\" + id + \"' not found\", \"warning\");\n }\n }\n return null;\n }\n\n /**\n * Component.getComponentByType(sType, idRelated, componentPrev)\n *\n * @param {string} sType of the desired component\n * @param {string} [idRelated] of related component\n * @param {Component|null} [componentPrev] of previously returned component, if any\n * @return {Component|null}\n */\n static getComponentByType(sType, idRelated, componentPrev)\n {\n if (sType !== undefined) {\n var i;\n /*\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated) {\n if ((i = idRelated.indexOf('.')) > 0) {\n idRelated = idRelated.substr(0, i + 1);\n } else {\n idRelated = \"\";\n }\n }\n for (i = 0; i < Component.components.length; i++) {\n if (componentPrev) {\n if (componentPrev == Component.components[i]) componentPrev = null;\n continue;\n }\n if (sType == Component.components[i].type && (!idRelated || !Component.components[i].id.indexOf(idRelated))) {\n return Component.components[i];\n }\n }\n Component.log(\"Component type '\" + sType + \"' not found\", \"warning\");\n }\n return null;\n }\n\n /**\n * Component.getComponentParms(element)\n *\n * @param {HTMLElement} element from the DOM\n */\n static getComponentParms(element)\n {\n var parms = null;\n var sParms = element.getAttribute(\"data-value\");\n if (sParms) {\n try {\n parms = eval('(' + sParms + ')'); // jshint ignore:line\n /*\n * We can no longer invoke removeAttribute() because some components (eg, Panel) need\n * to run their initXXX() code more than once, to avoid initialization-order dependencies.\n *\n * if (!DEBUG) {\n * element.removeAttribute(\"data-value\");\n * }\n */\n } catch(e) {\n Component.error(e.message + \" (\" + sParms + \")\");\n }\n }\n return parms;\n }\n\n /**\n * Component.getElementsByClass(element, sClass, sObjClass)\n *\n * This is a cross-browser helper function, since not all browser's support getElementsByClassName()\n *\n * TODO: This should probably be moved into weblib.js at some point, along with the control binding functions above,\n * to keep all the browser-related code together.\n *\n * @param {HTMLDocument|HTMLElement|Node} element from the DOM\n * @param {string} sClass\n * @param {string} [sObjClass]\n * @return {Array|NodeList}\n */\n static getElementsByClass(element, sClass, sObjClass)\n {\n if (sObjClass) sClass += '-' + sObjClass + \"-object\";\n /*\n * Use the browser's built-in getElementsByClassName() if it appears to be available\n * (for example, it's not available in IE8, but it should be available in IE9 and up)\n */\n if (element.getElementsByClassName) {\n return element.getElementsByClassName(sClass);\n }\n var i, j, ae = [];\n var aeAll = element.getElementsByTagName(\"*\");\n var re = new RegExp('(^| )' + sClass + '( |$)');\n for (i = 0, j = aeAll.length; i < j; i++) {\n if (re.test(aeAll[i].className)) {\n ae.push(aeAll[i]);\n }\n }\n if (!ae.length) {\n Component.log('No elements of class \"' + sClass + '\" found');\n }\n return ae;\n }\n\n /**\n * Component.getScriptCommands(sScript)\n *\n * This is a simple parser that breaks sScript into an array of commands, where each command\n * is an array of tokens, where tokens are sequences of characters separated by any of: tab, space,\n * carriage-return (CR), line-feed (LF), semicolon, single-quote, or double-quote; if a quote is\n * used, all characters up to the next matching quote become part of the token, allowing any of the\n * other separators to be part of the token. CR, LF and semicolon also serve to terminate a command,\n * with semicolon being preferred, because it's 1) more visible, and 2) essential when the entire\n * script is a multi-line string where all CR/LF were replaced by spaces (which is what Jekyll does,\n * and since we can't change Jekyll, it's what our own MarkDown Front Matter parser does as well;\n * see convertMD() in markout.js, where the aCommandDefs array is built).\n *\n * Backslash sequences like \\n, \\r, and \\\\ have already been converted to LF, CR and backslash\n * characters, since the entire script string is injected into a JavaScript function call, so any\n * backslash sequence that JavaScript supports is automatically converted:\n *\n * \\0 \\' \\\" \\\\ \\n \\r \\v \\t \\b \\f \\uXXXX \\xXX\n * ^J ^M ^K ^I ^H ^L\n *\n * To support any other non-printable 8-bit character, such as ESC, you should use \\xXX, where XX\n * is the ASCII code in hex. For ESC, that would be \\x1B.\n *\n * @param {string} sScript\n * @return {Array}\n */\n static getScriptCommands(sScript)\n {\n var cch = sScript.length;\n var aCommands = [], aTokens = [], sToken = \"\", chQuote = null;\n for (var i = 0; i < cch; i++) {\n var ch = sScript[i];\n if (ch == '\"' || ch == \"'\") {\n if (chQuote && ch != chQuote) {\n sToken += ch;\n continue;\n }\n if (!chQuote) {\n chQuote = ch;\n } else {\n chQuote = null;\n }\n if (sToken) {\n aTokens.push(sToken);\n sToken = \"\";\n }\n continue;\n }\n if (!chQuote) {\n if (ch == '\\r' || ch == '\\n') {\n ch = ';';\n }\n if (ch == ' ' || ch == '\\t' || ch == ';') {\n if (sToken) {\n aTokens.push(sToken);\n sToken = \"\";\n }\n if (ch == ';' && aTokens.length) {\n aCommands.push(aTokens);\n aTokens = [];\n }\n continue;\n }\n }\n sToken += ch;\n }\n if (sToken) {\n aTokens.push(sToken);\n }\n if (aTokens.length) {\n aCommands.push(aTokens);\n }\n return aCommands;\n }\n\n /**\n * Component.processScript(idMachine, sScript)\n *\n * @param {string} idMachine\n * @param {string} [sScript]\n * @return {boolean}\n */\n static processScript(idMachine, sScript)\n {\n var fSuccess = false;\n idMachine += \".machine\";\n if (!sScript) {\n delete Component.commands[idMachine];\n fSuccess = true;\n }\n else if (typeof sScript == \"string\" && !Component.commands[idMachine]) {\n fSuccess = true;\n Component.commands[idMachine] = Component.getScriptCommands(sScript);\n if (!Component.processCommands(idMachine)) {\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * Component.processCommands(idMachine)\n *\n * @param {string} idMachine\n * @return {boolean}\n */\n static processCommands(idMachine)\n {\n var fSuccess = true;\n var aCommands = Component.commands[idMachine];\n\n // var dbg = Component.getComponentByType(\"Debugger\", idMachine);\n\n while (aCommands && aCommands.length) {\n\n var aTokens = aCommands.splice(0, 1)[0];\n var sCommand = aTokens[0];\n\n /*\n * It's possible to route this output to the Debugger window with dbg.println()\n * instead, but it's a bit too confusing mingling script output in a window that\n * already mingles Debugger and machine output.\n */\n Component.println(aTokens.join(' '), Component.PRINT.SCRIPT);\n\n var fnCallReady = null;\n if (Component.asyncCommands.indexOf(sCommand) >= 0) {\n fnCallReady = function processNextCommand() {\n return function() {\n Component.processCommands(idMachine);\n }\n }();\n }\n\n var fnCommand = Component.globalCommands[sCommand];\n if (fnCommand) {\n if (!fnCallReady) {\n fSuccess = fnCommand(aTokens[1], aTokens[2], aTokens[3]);\n } else {\n if (!fnCommand(fnCallReady, aTokens[1], aTokens[2], aTokens[3])) break;\n }\n }\n else {\n fSuccess = false;\n var component = Component.getComponentByType(aTokens[1], idMachine);\n if (component) {\n fnCommand = Component.componentCommands[sCommand];\n if (fnCommand) {\n fSuccess = fnCommand(component, aTokens[2], aTokens[3]);\n }\n else {\n var exports = component['exports'];\n if (exports) {\n fnCommand = exports[sCommand];\n if (fnCommand) {\n fSuccess = true;\n if (!fnCallReady) {\n fSuccess = fnCommand.call(component, aTokens[2], aTokens[3]);\n } else {\n if (!fnCommand.call(component, fnCallReady, aTokens[2], aTokens[3])) break;\n }\n }\n }\n }\n }\n }\n\n if (!fSuccess) {\n Component.alertUser(\"Script error: '\" + sCommand + \"' command \" + (fnCommand? \" failed\" : \" not recognized\"));\n break;\n }\n }\n\n if (aCommands && !aCommands.length) {\n delete Component.commands[idMachine];\n }\n\n return fSuccess;\n }\n\n /**\n * Component.scriptAlert(sMessage)\n *\n * @param {string} sMessage\n * @return {boolean}\n */\n static scriptAlert(sMessage)\n {\n Component.alertUser(sMessage);\n return true;\n }\n\n /**\n * Component.scriptSelect(component, sBinding, sValue)\n *\n * @param {Component} component\n * @param {string} sBinding\n * @param {string} sValue\n * @return {boolean}\n */\n static scriptSelect(component, sBinding, sValue)\n {\n var fSuccess = false;\n var aBindings = component['bindings'];\n var control = aBindings[sBinding];\n if (control) {\n for (var i = 0; i < control.options.length; i++) {\n if (control.options[i].textContent == sValue) {\n if (control.selectedIndex != i) {\n control.selectedIndex = i;\n }\n fSuccess = true;\n break;\n }\n }\n }\n return fSuccess;\n }\n\n /**\n * Component.scriptSleep(fnCallback, sDelay)\n *\n * @param {function()} fnCallback\n * @param {string} sDelay (in milliseconds)\n * @return {boolean}\n */\n static scriptSleep(fnCallback, sDelay)\n {\n setTimeout(fnCallback, +sDelay);\n return false;\n }\n\n /**\n * toString()\n *\n * @this {Component}\n * @return {string}\n */\n toString()\n {\n return (this.name? this.name : (this.id || this.type));\n }\n\n /**\n * getMachineNum()\n *\n * @this {Component}\n * @return {number} unique machine number\n */\n getMachineNum()\n {\n var nMachine = 1;\n if (this.idMachine) {\n var aDigits = this.idMachine.match(/\\d+/);\n if (aDigits !== null)\n nMachine = parseInt(aDigits[0], 10);\n }\n return nMachine;\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * Component's setBinding() method is intended to be overridden by subclasses.\n *\n * @this {Component}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, 'print')\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n switch (sBinding) {\n case 'clear':\n if (!this.bindings[sBinding]) {\n this.bindings[sBinding] = control;\n control.onclick = (function(component) {\n return function clearControl() {\n if (component.bindings['print']) {\n component.bindings['print'].value = \"\";\n }\n };\n }(this));\n }\n return true;\n case 'print':\n if (!this.bindings[sBinding]) {\n var controlTextArea = /** @type {HTMLTextAreaElement} */(control);\n this.bindings[sBinding] = controlTextArea;\n /**\n * Override this.notice() with a replacement function that eliminates the Component.alertUser() call.\n *\n * @this {Component}\n * @param {string} s\n * @return {boolean}\n */\n this.notice = function noticeControl(s /*, fPrintOnly, id*/) {\n this.println(s, this.type);\n return true;\n };\n /*\n * This was added for Firefox (Safari will clear the <textarea> on a page reload, but Firefox does not).\n */\n controlTextArea.value = \"\";\n this.print = function(control) {\n return function printControl(s) {\n Component.appendControl(control, s);\n };\n }(controlTextArea);\n this.println = function(component, control) {\n return function printlnControl(s, type, id) {\n if (!s) s = \"\";\n if (type != Component.PRINT.PROGRESS || s.slice(-3) != \"...\") {\n if (type) s = type + \": \" + s;\n Component.appendControl(control, s + '\\n');\n } else {\n Component.replaceControl(control, s, s + '.');\n }\n if (!COMPILED && window && window.console) Component.println(s, type, id);\n };\n }(this, controlTextArea);\n }\n return true;\n default:\n return false;\n }\n }\n\n /**\n * log(s, type)\n *\n * For diagnostic output only.\n *\n * WARNING: Even though this function's body is completely wrapped in DEBUG, that won't prevent the Closure Compiler\n * from including it, so all calls must still be prefixed with \"if (DEBUG) ....\". For this reason, the class method,\n * Component.log(), is preferred, because the compiler IS smart enough to remove those calls.\n *\n * @this {Component}\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n log(s, type)\n {\n if (!COMPILED) {\n Component.log(s, type || this.id || this.type);\n }\n }\n\n /**\n * assert(f, s)\n *\n * Verifies conditions that must be true (for DEBUG builds only).\n *\n * WARNING: Make sure you preface all calls to this.assert() with \"if (DEBUG)\", because unlike Component.assert(),\n * the Closure Compiler can't be sure that this instance method hasn't been overridden, so it refuses to treat it as\n * dead code in non-DEBUG builds.\n *\n * TODO: Add a task to the build process that \"asserts\" there are no instances of \"assertion failure\" in RELEASE builds.\n *\n * @this {Component}\n * @param {boolean|number} f is the expression asserted to be true\n * @param {string} [s] is a description of the assertion to be displayed or logged on failure\n */\n assert(f, s)\n {\n if (DEBUG) {\n if (!f) {\n s = \"assertion failure in \" + (this.id || this.type) + (s? \": \" + s : \"\");\n if (DEBUGGER && this.dbg) {\n this.dbg.stopCPU();\n /*\n * Why do we throw an Error only to immediately catch and ignore it? Simply to give\n * any IDE the opportunity to inspect the application's state. Even when the IDE has\n * control, you should still be able to invoke Debugger commands from the IDE's REPL,\n * using the global function that the Debugger constructor defines; eg:\n *\n * pcx86('r')\n * pcx86('dw 0:0')\n * pcx86('h')\n * ...\n *\n * If you have no desire to stop on assertions, consider this a no-op. However, another\n * potential benefit of creating an Error object is that, for browsers like Chrome, we get\n * a stack trace, too.\n */\n try {\n throw new Error(s);\n } catch(e) {\n this.println(e.stack || e.message);\n }\n return;\n }\n this.log(s);\n throw new Error(s);\n }\n }\n }\n\n /**\n * print(s)\n *\n * Components using this.print() should wait until after their constructor has run to display any messages, because\n * if a Control Panel has been loaded, its override will not take effect until its own constructor has run.\n *\n * @this {Component}\n * @param {string} s\n */\n print(s)\n {\n Component.print(s);\n }\n\n /**\n * println(s, type, id)\n *\n * Components using this.println() should wait until after their constructor has run to display any messages, because\n * if a Control Panel has been loaded, its override will not take effect until its own constructor has run.\n *\n * @this {Component}\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n * @param {string} [id] is the caller's ID, if any\n */\n println(s, type, id)\n {\n Component.println(s, type, id || this.id);\n }\n\n /**\n * status(s)\n *\n * status() is like println() but it also includes information about the component (ie, the component type),\n * which is why there is no corresponding Component.status() function.\n *\n * @this {Component}\n * @param {string} s is the message text\n */\n status(s)\n {\n this.println(this.type + \": \" + s);\n }\n\n /**\n * notice(s, fPrintOnly, id)\n *\n * notice() is like println() but implies a need for user notification, so we alert() as well; however, if this.println()\n * is overridden, this.notice will be replaced with a similar override, on the assumption that the override is taking care\n * of alerting the user.\n *\n * @this {Component}\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n * @return {boolean}\n */\n notice(s, fPrintOnly, id)\n {\n if (!fPrintOnly) {\n /*\n * See if the associated computer, if any, is \"unloading\"....\n */\n var computer = Component.getComponentByType(\"Computer\", this.id);\n if (computer && computer.flags.unloading) {\n console.log(\"ignoring notice during unload: \" + s);\n return false;\n }\n }\n Component.notice(s, fPrintOnly, id || this.type);\n return true;\n }\n\n /**\n * setError(s)\n *\n * Set a fatal error condition\n *\n * @this {Component}\n * @param {string} s describes a fatal error condition\n */\n setError(s)\n {\n this.flags.error = true;\n this.notice(s); // TODO: Any cases where we should still prefix this string with \"Fatal error: \"?\n }\n\n /**\n * clearError()\n *\n * Clear any fatal error condition\n *\n * @this {Component}\n */\n clearError() {\n this.flags.error = false;\n }\n\n /**\n * isError()\n *\n * Report any fatal error condition\n *\n * @this {Component}\n * @return {boolean} true if a fatal error condition exists, false if not\n */\n isError()\n {\n if (this.flags.error) {\n this.println(this.toString() + \" error\");\n return true;\n }\n return false;\n }\n\n /**\n * isReady(fnReady)\n *\n * Return the \"ready\" state of the component; if the component is not ready, it will queue the optional\n * notification function, otherwise it will immediately call the notification function, if any, without queuing it.\n *\n * NOTE: Since only the Computer component actually cares about the \"readiness\" of other components, the so-called\n * \"queue\" of notification functions supports exactly one function. This keeps things nice and simple.\n *\n * @this {Component}\n * @param {function()} [fnReady]\n * @return {boolean} true if the component is in a \"ready\" state, false if not\n */\n isReady(fnReady)\n {\n if (fnReady) {\n if (this.flags.ready) {\n fnReady();\n } else {\n if (MAXDEBUG) this.log(\"NOT ready\");\n this.fnReady = fnReady;\n }\n }\n return this.flags.ready;\n }\n\n /**\n * setReady(fReady)\n *\n * Set the \"ready\" state of the component to true, and call any queued notification functions.\n *\n * @this {Component}\n * @param {boolean} [fReady] is assumed to indicate \"ready\" unless EXPLICITLY set to false\n */\n setReady(fReady)\n {\n if (!this.flags.error) {\n this.flags.ready = (fReady !== false);\n if (this.flags.ready) {\n if (MAXDEBUG /* || this.name */) this.log(\"ready\");\n var fnReady = this.fnReady;\n this.fnReady = null;\n if (fnReady) fnReady();\n }\n }\n }\n\n /**\n * isBusy(fCancel)\n *\n * Return the \"busy\" state of the component\n *\n * @this {Component}\n * @param {boolean} [fCancel] is set to true to cancel a \"busy\" state\n * @return {boolean} true if \"busy\", false if not\n */\n isBusy(fCancel)\n {\n if (this.flags.busy) {\n if (fCancel) {\n this.flags.busyCancel = true;\n } else if (fCancel === undefined) {\n this.println(this.toString() + \" busy\");\n }\n }\n return this.flags.busy;\n }\n\n /**\n * setBusy(fBusy)\n *\n * Update the current busy state; if a busyCancel request is pending, it will be honored now.\n *\n * @this {Component}\n * @param {boolean} fBusy\n * @return {boolean}\n */\n setBusy(fBusy)\n {\n if (this.flags.busyCancel) {\n this.flags.busy = false;\n this.flags.busyCancel = false;\n return false;\n }\n if (this.flags.error) {\n this.println(this.toString() + \" error\");\n return false;\n }\n this.flags.busy = fBusy;\n return this.flags.busy;\n }\n\n /**\n * powerUp(fSave)\n *\n * @this {Component}\n * @param {Object|null} data\n * @param {boolean} [fRepower] is true if this is \"repower\" notification\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n this.flags.powered = true;\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Component}\n * @param {boolean} fSave\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n if (fShutdown) this.flags.powered = false;\n return true;\n }\n\n /**\n * messageEnabled(bitsMessage)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n *\n * @this {Component}\n * @param {number} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n * @return {boolean} true if all specified message enabled, false if not\n */\n messageEnabled(bitsMessage = 0)\n {\n if (DEBUGGER && this.dbg) {\n if (this !== this.dbg) {\n bitsMessage = bitsMessage || this.bitsMessage;\n }\n var bitsEnabled = this.dbg.bitsMessage & bitsMessage;\n /*\n * This next \"bit\" of logic is for PCx86 and any other machine where we've expanded the set of\n * messages by reusing bits in the low nibbles in combination with different bits in the high nibble.\n * If the input bits adhere to that format, then the mask we just produced must adhere to it as well,\n * and if it doesn't, zero the mask, ensuring that the test will return false.\n */\n if ((bitsMessage & 0xf0000000) && (bitsMessage & 0x0fffffff)) {\n if (!(bitsEnabled & 0xf0000000) || !(bitsEnabled & 0x0fffffff)) bitsEnabled = 0;\n }\n if (bitsMessage && bitsEnabled === bitsMessage) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * printf(format, ...args)\n *\n * @this {Component}\n * @param {string} format\n * @param {...} args\n */\n printf(format, ...args)\n {\n if (DEBUGGER && this.dbg) {\n if (this.messageEnabled()) {\n let s = Str.sprintf(format, ...args);\n /*\n * Since dbg.message() calls println(), we strip any ending linefeed.\n * \n * We could bypass the Debugger and go straight to this.print(), but we would lose\n * the benefits of debugger messages (eg, automatic buffering, halting, yielding, etc).\n */\n if (s.slice(-1) == '\\n') s = s.slice(0, -1);\n this.dbg.message(s);\n }\n }\n }\n\n /**\n * printMessage(sMessage, bitsMessage, fAddress)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n * If bitsMessage is true, the message is displayed regardless.\n *\n * @this {Component}\n * @param {string} sMessage is any caller-defined message string\n * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n * @param {boolean} [fAddress] is true to display the current address\n */\n printMessage(sMessage, bitsMessage, fAddress)\n {\n if (DEBUGGER && this.dbg) {\n if (bitsMessage === true || this.messageEnabled(bitsMessage | 0)) {\n this.dbg.message(sMessage, fAddress);\n }\n }\n }\n\n /**\n * printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n * If bitsMessage is true, the message is displayed as long as MESSAGE.PORT is enabled.\n *\n * @this {Component}\n * @param {number} port\n * @param {number|null|*} bOut if an output operation\n * @param {number|null|*} [addrFrom]\n * @param {string|null|*} [name] of the port, if any\n * @param {number|null|*} [bIn] is the input value, if known, on an input operation\n * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n */\n printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage)\n {\n if (DEBUGGER && this.dbg) {\n if (bitsMessage === true) {\n bitsMessage = 0;\n } else if (bitsMessage == null) {\n bitsMessage = this.bitsMessage;\n }\n this.dbg.messageIO(this, port, bOut, addrFrom, name, bIn, bitsMessage);\n }\n }\n}\n\n/*\n * Types recognized and supported by selected functions (eg, Computer.getMachineParm())\n */\nComponent.TYPE = {\n NUMBER: \"number\",\n OBJECT: \"object\",\n STRING: \"string\"\n};\n\n/*\n * These are the standard PRINT values you can pass as an optional argument to println(); in reality,\n * you can pass anything you want, because they are simply prepended to the message, although PROGRESS\n * messages may also be merged with earlier similar messages to keep the output buffer under control.\n */\nComponent.PRINT = {\n ERROR: \"error\",\n NOTICE: \"notice\",\n PROGRESS: \"progress\",\n SCRIPT: \"script\",\n WARNING: \"warning\"\n};\n\n/*\n * Every component created on the current page is recorded in this array (see Component.add()),\n * enabling any component to locate another component by ID (see Component.getComponentByID())\n * or by type (see Component.getComponentByType()).\n *\n * Every machine on the page are now recorded as well, by their machine ID. We then record the\n * various resources used by that machine.\n *\n * Includes a fallback for non-browser-based environments (ie, Node). TODO: This will need to be\n * tailored to Node, probably using the global object instead of the window object, if we ever want\n * to support multi-machine configs in that environment.\n */\nif (window) {\n if (!window['PCjs']) window['PCjs'] = {};\n if (!window['PCjs']['Machines']) window['PCjs']['Machines'] = {};\n if (!window['PCjs']['Components']) window['PCjs']['Components'] = [];\n if (!window['PCjs']['Commands']) window['PCjs']['Commands'] = {};\n}\nComponent.machines = window? window['PCjs']['Machines'] : {};\nComponent.components = window? window['PCjs']['Components'] : [];\nComponent.commands = window? window['PCjs']['Commands'] : {};\n\nComponent.asyncCommands = [\n 'hold', 'sleep', 'wait'\n];\nComponent.globalCommands = {\n 'alert': Component.scriptAlert,\n 'sleep': Component.scriptSleep\n};\nComponent.componentCommands = {\n 'select': Component.scriptSelect\n};\nComponent.printBuffer = \"\";\n\n/*\n * The following polyfills provide ES5 functionality that's missing in older browsers (eg, IE8),\n * allowing PCjs apps to run without slamming into exceptions; however, due to the lack of HTML5 canvas\n * support in those browsers, all you're likely to see are \"soft\" errors (eg, \"Missing <canvas> support\").\n *\n * Perhaps we can implement a text-only faux video display for a fun retro-browser experience someday.\n *\n * TODO: Come up with a better place to put these polyfills. We will likely have more if we decide to\n * make the leap from ES5 to ES6 features.\n */\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf\n */\nif (!Array.prototype.indexOf) {\n Array.prototype.indexOf = function(obj, start) {\n for (var i = (start || 0), j = this.length; i < j; i++) {\n if (this[i] === obj) { return i; }\n }\n return -1;\n }\n}\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray\n */\nif (!Array.isArray) {\n Array.isArray = function(arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n };\n}\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind\n */\nif (!Function.prototype.bind) {\n Function.prototype.bind = function(obj) {\n if (typeof this != \"function\") {\n // Closest thing possible to the ECMAScript 5 internal IsCallable function\n throw new TypeError(\"Function.prototype.bind: non-callable object\");\n }\n var args = Array.prototype.slice.call(arguments, 1);\n var fToBind = this;\n var fnNOP = /** @constructor */ (function() {});\n var fnBound = function() {\n return fToBind.apply(this instanceof fnNOP && obj? this : obj, args.concat(/** @type {Array} */(Array.prototype.slice.call(arguments))));\n };\n fnNOP.prototype = this.prototype;\n fnBound.prototype = new fnNOP();\n return fnBound;\n };\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/defines.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @define {string}\n */\nvar APPCLASS = \"pc8080\"; // this @define is the default application class (eg, \"pcx86\", \"c1pjs\")\n\n/**\n * @define {string}\n */\nvar APPNAME = \"PC8080\"; // this @define is the default application name (eg, \"PCx86\", \"C1Pjs\")\n\n/**\n * @define {boolean}\n *\n * WARNING: DEBUGGER needs to accurately reflect whether or not the Debugger component is (or will be) loaded.\n * In the compiled case, we rely on the Closure Compiler to override DEBUGGER as appropriate. When it's *false*,\n * nearly all of debugger.js will be conditionally removed by the compiler, reducing it to little more than a\n * \"type skeleton\", which also solves some type-related warnings we would otherwise have if we tried to remove\n * debugger.js from the compilation process altogether.\n *\n * However, when we're in \"development mode\" and running uncompiled code in debugger-less configurations,\n * I would like to skip loading debugger.js altogether. When doing that, we must ALSO arrange for an additional file\n * (nodebugger.js) to be loaded immediately after this file, which *explicitly* overrides DEBUGGER with *false*.\n */\nvar DEBUGGER = true; // this @define is overridden by the Closure Compiler to remove Debugger-related support\n\n/**\n * @define {boolean}\n *\n * BYTEARRAYS is a Closure Compiler compile-time option that allocates an Array of numbers for every Memory block,\n * where each a number represents ONE byte; very wasteful, but potentially slightly faster.\n *\n * See the Memory component for details.\n */\nvar BYTEARRAYS = false;\n\n/**\n * TYPEDARRAYS enables use of typed arrays for Memory blocks. This used to be a compile-time-only option, but I've\n * added Memory access functions for typed arrays (see Memory8080.afnTypedArray), so support can be enabled dynamically now.\n *\n * See the Memory component for details.\n */\nvar TYPEDARRAYS = (typeof ArrayBuffer !== 'undefined');\n\n/*\n * Combine all the shared globals and machine-specific globals into one machine-specific global object,\n * which all machine components should start using; eg: \"if (PC8080.DEBUG) ...\" instead of \"if (DEBUG) ...\".\n */\nvar PC8080 = {\n APPCLASS: APPCLASS,\n APPNAME: APPNAME,\n APPVERSION: APPVERSION, // shared\n BYTEARRAYS: BYTEARRAYS,\n COMPILED: COMPILED, // shared\n CSSCLASS: CSSCLASS, // shared\n DEBUG: DEBUG, // shared\n DEBUGGER: DEBUGGER,\n MAXDEBUG: MAXDEBUG, // shared\n PRIVATE: PRIVATE, // shared\n TYPEDARRAYS: TYPEDARRAYS,\n SITEHOST: SITEHOST, // shared\n XMLVERSION: XMLVERSION // shared\n};\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/cpudef.js (C) Jeff Parsons 2012-2018\n */\n\nvar CPUDef8080 = {\n /*\n * CPU model numbers (supported)\n */\n MODEL_8080: 8080,\n\n /*\n * This constant is used to mark points in the code where the physical address being returned\n * is invalid and should not be used.\n *\n * In a 32-bit CPU, -1 (ie, 0xffffffff) could actually be a valid address, so consider changing\n * ADDR_INVALID to NaN or null (which is also why all ADDR_INVALID tests should use strict equality\n * operators).\n *\n * The main reason I'm NOT using NaN or null now is my concern that, by mixing non-numbers\n * (specifically, values outside the range of signed 32-bit integers), performance may suffer.\n *\n * WARNING: Like many of the properties defined here, ADDR_INVALID is a common constant, which the\n * Closure Compiler will happily inline (with or without @const annotations; in fact, I've yet to\n * see a @const annotation EVER improve automatic inlining). However, if you don't make ABSOLUTELY\n * certain that this file is included BEFORE the first reference to any of these properties, that\n * automatic inlining will no longer occur.\n */\n ADDR_INVALID: -1,\n\n /*\n * Processor Status flag definitions (stored in regPS)\n */\n PS: {\n CF: 0x0001, // bit 0: Carry Flag\n BIT1: 0x0002, // bit 1: reserved, always set\n PF: 0x0004, // bit 2: Parity Flag\n BIT3: 0x0008, // bit 3: reserved, always clear\n AF: 0x0010, // bit 4: Auxiliary Carry Flag\n BIT5: 0x0020, // bit 5: reserved, always clear\n ZF: 0x0040, // bit 6: Zero Flag\n SF: 0x0080, // bit 7: Sign Flag\n ALL: 0x00D5, // all \"arithmetic\" flags (CF, PF, AF, ZF, SF)\n MASK: 0x00FF, //\n IF: 0x0200 // bit 9: Interrupt Flag (set if interrupts enabled; Intel calls this the INTE bit)\n },\n PARITY: [ // 256-byte array with a 1 wherever the number of set bits of the array index is EVEN\n 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\n 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\n 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\n 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\n 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\n 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\n 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\n 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\n 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\n 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\n 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\n 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\n 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\n 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\n 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\n 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1\n ],\n /*\n * Interrupt-related flags (stored in intFlags)\n */\n INTFLAG: {\n NONE: 0x0000,\n INTR: 0x00ff, // mask for 8 bits, representing interrupt levels 0-7\n HALT: 0x0100 // halt requested; see opHLT()\n },\n /*\n * Opcode definitions\n */\n OPCODE: {\n HLT: 0x76, // Halt\n ACI: 0xCE, // Add with Carry Immediate (affects PS.ALL)\n CALL: 0xCD, // Call\n RST0: 0xC7\n // to be continued....\n }\n};\n\n/*\n * These are the internal PS bits (outside of PS.MASK) that getPS() and setPS() can get and set,\n * but which cannot be seen with any of the documented instructions.\n */\nCPUDef8080.PS.INTERNAL = (CPUDef8080.PS.IF);\n\n/*\n * PS \"arithmetic\" flags are NOT stored in regPS; they are maintained across separate result registers,\n * hence the RESULT designation.\n */\nCPUDef8080.PS.RESULT = (CPUDef8080.PS.CF | CPUDef8080.PS.PF | CPUDef8080.PS.AF | CPUDef8080.PS.ZF | CPUDef8080.PS.SF);\n\n/*\n * These are the \"always set\" PS bits for the 8080.\n */\nCPUDef8080.PS.SET = (CPUDef8080.PS.BIT1);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/messages.js (C) Jeff Parsons 2012-2018\n */\n\nvar Messages8080 = {\n CPU: 0x00000001,\n BUS: 0x00000040,\n MEM: 0x00000080,\n PORT: 0x00000100,\n NVR: 0x00004000,\n CHIPSET: 0x00008000,\n KEYBOARD: 0x00010000,\n KEYS: 0x00020000,\n VIDEO: 0x00040000,\n FDC: 0x00080000,\n DISK: 0x00200000,\n SERIAL: 0x00800000,\n SPEAKER: 0x02000000,\n COMPUTER: 0x04000000,\n BUFFER: 0x20000000,\n WARN: 0x40000000,\n HALT: 0x80000000|0\n};\n\n/*\n * Message categories supported by the messageEnabled() function and other assorted message\n * functions. Each category has a corresponding bit value that can be combined (ie, OR'ed) as\n * needed. The Debugger's message command (\"m\") is used to turn message categories on and off,\n * like so:\n *\n * m port on\n * m port off\n * ...\n *\n * NOTE: The order of these categories can be rearranged, alphabetized, etc, as desired; just be\n * aware that changing the bit values could break saved Debugger states (not a huge concern, just\n * something to be aware of).\n */\nMessages8080.CATEGORIES = {\n \"cpu\": Messages8080.CPU,\n \"bus\": Messages8080.BUS,\n \"mem\": Messages8080.MEM,\n \"port\": Messages8080.PORT,\n \"nvr\": Messages8080.NVR,\n \"chipset\": Messages8080.CHIPSET,\n \"keyboard\": Messages8080.KEYBOARD, // \"kbd\" is also allowed as shorthand for \"keyboard\"; see doMessages()\n \"key\": Messages8080.KEYS, // using \"key\" instead of \"keys\", since the latter is a method on JavasScript objects\n \"video\": Messages8080.VIDEO,\n \"fdc\": Messages8080.FDC,\n \"disk\": Messages8080.DISK,\n \"serial\": Messages8080.SERIAL,\n \"speaker\": Messages8080.SPEAKER,\n \"computer\": Messages8080.COMPUTER,\n /*\n * Now we turn to message actions rather than message types; for example, setting \"halt\"\n * on or off doesn't enable \"halt\" messages, but rather halts the CPU on any message above.\n *\n * Similarly, \"m buffer on\" turns on message buffering, deferring the display of all messages\n * until \"m buffer off\" is issued.\n */\n \"buffer\": Messages8080.BUFFER,\n \"warn\": Messages8080.WARN,\n \"halt\": Messages8080.HALT\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/panel.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass Panel8080 extends Component {\n /**\n * Panel8080(parmsPanel)\n *\n * The Panel8080 component has no required (parmsPanel) properties.\n *\n * @this {Panel8080}\n * @param {Object} parmsPanel\n */\n constructor(parmsPanel)\n {\n super(\"Panel\", parmsPanel);\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * Most panel layouts don't have bindings of their own, so we pass along all binding requests to the\n * Computer, CPU, Keyboard and Debugger components first. The order shouldn't matter, since any component\n * that doesn't recognize the specified binding should simply ignore it.\n *\n * @this {Panel8080}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n if (this.cmp && this.cmp.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (this.cpu && this.cpu.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (this.kbd && this.kbd.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (DEBUGGER && this.dbg && this.dbg.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n return super.setBinding(sHTMLType, sBinding, control, sValue);\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {Panel8080}\n * @param {Computer8080} cmp\n * @param {Bus8080} bus\n * @param {CPUState8080} cpu\n * @param {Debugger8080} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.kbd = /** @type {Keyboard8080} */ (cmp.getMachineComponent(\"Keyboard\"));\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {Panel8080}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) Panel8080.init();\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Panel8080}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return true;\n }\n\n /**\n * updateStatus(fForce)\n *\n * Update function for Panels containing elements with high-frequency display requirements.\n *\n * For older (and slower) DOM-based display elements, those are sill being managed by the CPUState component,\n * so it has its own updateStatus() handler.\n *\n * The Computer's updateStatus() handler is currently responsible for calling both our handler and the CPU's handler.\n *\n * @this {Panel8080}\n * @param {boolean} [fForce] (true will display registers even if the CPU is running and \"live\" registers are not enabled)\n */\n updateStatus(fForce)\n {\n }\n\n /**\n * Panel8080.init()\n *\n * This function operates on every HTML element of class \"panel\", extracting the\n * JSON-encoded parameters for the Panel8080 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Panel8080 component, and then binding\n * any associated HTML controls to the new component.\n *\n * NOTE: Unlike most other component init() functions, this one is designed to be\n * called multiple times: once at load time, so that we can bind our print()\n * function to the panel's output control ASAP, and again when the Computer component\n * is verifying that all components are ready and invoking their powerUp() functions.\n *\n * Our powerUp() method gives us a second opportunity to notify any components that\n * that might care (eg, CPU, Keyboard, and Debugger) that we have some controls they\n * might want to use.\n */\n static init()\n {\n var fReady = false;\n var aePanels = Component.getElementsByClass(document, PC8080.APPCLASS, \"panel\");\n for (var iPanel=0; iPanel < aePanels.length; iPanel++) {\n var ePanel = aePanels[iPanel];\n var parmsPanel = Component.getComponentParms(ePanel);\n var panel = Component.getComponentByID(parmsPanel['id']);\n if (!panel) {\n fReady = true;\n panel = new Panel8080(parmsPanel);\n }\n Component.bindComponentControls(panel, ePanel, PC8080.APPCLASS);\n if (fReady) panel.setReady();\n }\n }\n}\n\n/*\n * Initialize every Panel module on the page.\n */\nWeb.onInit(Panel8080.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/bus.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass Bus8080 extends Component {\n /**\n * Bus8080(cpu, dbg)\n *\n * The Bus8080 component manages physical memory and I/O address spaces.\n *\n * The Bus8080 component has no UI elements, so it does not require an init() handler,\n * but it still inherits from the Component class and must be allocated like any\n * other device component. It's currently allocated by the Computer's init() handler,\n * which then calls the initBus() method of all the other components.\n *\n * For memory beyond the simple needs of the ROM and RAM components (ie, memory-mapped\n * devices), the address space must still be allocated through the Bus8080 component via\n * addMemory(). If the component needs something more than simple read/write storage,\n * it must provide a custom controller.\n *\n * All port (I/O) operations are defined by external handlers; they register with us,\n * and we manage those registrations and provide support for I/O breakpoints, but the\n * only default I/O behavior we provide is ignoring writes to any unregistered output\n * ports and returning 0xff from any unregistered input ports.\n *\n * @this {Bus8080}\n * @param {Object} parmsBus\n * @param {CPUState8080} cpu\n * @param {Debugger8080} dbg\n */\n constructor(parmsBus, cpu, dbg)\n {\n super(\"Bus\", parmsBus);\n\n this.cpu = cpu;\n this.dbg = dbg;\n\n this.nBusWidth = parmsBus['busWidth'] || 16;\n\n /*\n * Compute all Bus8080 memory block parameters, based on the width of the bus. The entire\n * address space is divided into blocks, using a block size that is (hopefully) appropriate to\n * the bus width. The following table summarizes our simplistic calculations.\n *\n * Bus Width Block Shift Block Size\n * --------- ----------- ----------\n * 16 bits (64Kb address space): 10 1Kb (64 maximum blocks)\n * 18 bits (256Kb address space): 11 2Kb (128 maximum blocks)\n * 20 bits (1Mb address space): 12 4Kb (256 maximum blocks)\n * 22 bits (4Mb address space): 13 8Kb (512 maximum blocks)\n * 24 bits (16Mb address space): 14 16Kb (1K maximum blocks)\n * 32 bits (4Gb address space); 15 32Kb (128K maximum blocks)\n *\n * The coarser block granularities (ie, 16Kb and 32Kb) may cause problems for certain RAM and/or ROM\n * allocations that are contiguous but are allocated out of order, or that have different controller\n * requirements. Your choices, for the moment, are either to ensure the allocations are performed in\n * order, or to choose smaller nBlockShift values (at the expense of a generating a larger block array).\n */\n this.addrTotal = Math.pow(2, this.nBusWidth);\n this.nBusLimit = this.nBusMask = (this.addrTotal - 1) | 0;\n this.nBlockShift = (this.nBusWidth >> 1) + 2;\n if (this.nBlockShift < 10) this.nBlockShift = 10;\n if (this.nBlockShift > 15) this.nBlockShift = 15;\n this.nBlockSize = 1 << this.nBlockShift;\n this.nBlockLen = this.nBlockSize >> 2;\n this.nBlockLimit = this.nBlockSize - 1;\n this.nBlockTotal = (this.addrTotal / this.nBlockSize) | 0;\n this.nBlockMask = this.nBlockTotal - 1;\n\n\n /*\n * Lists of I/O notification functions: aPortInputNotify and aPortOutputNotify are arrays, indexed by\n * port, of sub-arrays which contain:\n *\n * [0]: registered function to call for every I/O access\n *\n * The registered function is called with the port address, and if the access was triggered by the CPU,\n * the instruction pointer (IP) at the point of access.\n *\n * WARNING: Unlike the (old) read and write memory notification functions, these support only one\n * pair of input/output functions per port. A more sophisticated architecture could support a list\n * of chained functions across multiple components, but I doubt that will be necessary here.\n *\n * UPDATE: The Debugger now piggy-backs on these arrays to indicate ports for which it wants notification\n * of I/O. In those cases, the registered component/function elements may or may not be set, but the\n * following additional element will be set:\n *\n * [1]: true to break on I/O, false to ignore I/O\n *\n * The false case is important if fPortInputBreakAll and/or fPortOutputBreakAll is set, because it allows the\n * Debugger to selectively ignore specific ports.\n */\n this.aPortInputNotify = [];\n this.aPortOutputNotify = [];\n this.fPortInputBreakAll = this.fPortOutputBreakAll = false;\n\n /*\n * By default, all I/O ports are 1 byte wide; ports that are wider must add themselves to one or both of\n * these lists, using addPortInputWidth() and/or addPortOutputWidth().\n */\n this.aPortInputWidth = [];\n this.aPortOutputWidth = [];\n\n /*\n * Allocate empty Memory blocks to span the entire physical address space.\n */\n this.initMemory();\n\n this.setReady();\n }\n\n /**\n * initMemory()\n *\n * Allocate enough (empty) Memory blocks to span the entire physical address space.\n *\n * @this {Bus8080}\n */\n initMemory()\n {\n var block = new Memory8080();\n block.copyBreakpoints(this.dbg);\n this.aMemBlocks = new Array(this.nBlockTotal);\n for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {\n this.aMemBlocks[iBlock] = block;\n }\n }\n\n /**\n * reset()\n *\n * @this {Bus8080}\n */\n reset()\n {\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * We don't need a powerDown() handler, because for largely historical reasons, our state is saved by saveMemory(),\n * which called by the CPU.\n *\n * However, we do need a powerUp() handler, because on resumable machines, the Computer's onReset() function calls\n * everyone's powerUp() handler rather than their reset() handler.\n *\n * TODO: Perhaps Computer should be smarter: if there's no powerUp() handler, then fallback to the reset() handler.\n * In that case, however, we'd either need to remove the powerUp() stub in Component, or detect the existence of the stub.\n *\n * @this {Bus8080}\n * @param {Object|null} data (always null because we supply no powerDown() handler)\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) this.reset();\n return true;\n }\n\n /**\n * addMemory(addr, size, type)\n *\n * Adds new Memory blocks to the specified address range. Any Memory blocks previously\n * added to that range must first be removed via removeMemory(); otherwise, you'll get\n * an allocation conflict error. This helps prevent address calculation errors, redundant\n * allocations, etc.\n *\n * We've relaxed some of the original requirements (ie, that addresses must start at a\n * block-granular address, or that sizes must be equal to exactly one or more blocks),\n * because machines with large block sizes can make it impossible to load certain ROMs at\n * their required addresses. Every allocation still allocates a whole number of blocks.\n *\n * Even so, Bus8080 memory management does NOT provide a general-purpose heap. Most memory\n * allocations occur during machine initialization and never change. In particular, there\n * is NO support for removing partial-block allocations.\n *\n * Each Memory block keeps track of a start address (addr) and length (used), indicating\n * the used space within the block; any free space that precedes or follows that used space\n * can be allocated later, by simply extending the beginning or ending of the previously used\n * space. However, any holes that might have existed between the original allocation and an\n * extension are subsumed by the extension.\n *\n * @this {Bus8080}\n * @param {number} addr is the starting physical address of the request\n * @param {number} size of the request, in bytes\n * @param {number} type is one of the Memory8080.TYPE constants\n * @return {boolean} true if successful, false if not\n */\n addMemory(addr, size, type)\n {\n var addrNext = addr;\n var sizeLeft = size;\n var iBlock = addrNext >>> this.nBlockShift;\n\n while (sizeLeft > 0 && iBlock < this.aMemBlocks.length) {\n\n var block = this.aMemBlocks[iBlock];\n var addrBlock = iBlock * this.nBlockSize;\n var sizeBlock = this.nBlockSize - (addrNext - addrBlock);\n if (sizeBlock > sizeLeft) sizeBlock = sizeLeft;\n\n if (block && block.size) {\n if (block.type == type) {\n /*\n * Where there is already a similar block with a non-zero size, we allow the allocation only if:\n *\n * 1) addrNext + sizeLeft <= block.addr (the request precedes the used portion of the current block), or\n * 2) addrNext >= block.addr + block.used (the request follows the used portion of the current block)\n */\n if (addrNext + sizeLeft <= block.addr) {\n block.used += (block.addr - addrNext);\n block.addr = addrNext;\n return true;\n }\n if (addrNext >= block.addr + block.used) {\n var sizeAvail = block.size - (addrNext - addrBlock);\n if (sizeAvail > sizeLeft) sizeAvail = sizeLeft;\n block.used = addrNext - block.addr + sizeAvail;\n addrNext = addrBlock + this.nBlockSize;\n sizeLeft -= sizeAvail;\n iBlock++;\n continue;\n }\n }\n return this.reportError(Bus8080.ERROR.ADD_MEM_INUSE, addrNext, sizeLeft);\n }\n\n var blockNew = new Memory8080(addrNext, sizeBlock, this.nBlockSize, type);\n blockNew.copyBreakpoints(this.dbg, block);\n this.aMemBlocks[iBlock++] = blockNew;\n\n addrNext = addrBlock + this.nBlockSize;\n sizeLeft -= sizeBlock;\n }\n\n if (sizeLeft <= 0) {\n this.status(Math.floor(size / 1024) + \"Kb \" + Memory8080.TYPE.NAMES[type] + \" at \" + Str.toHexWord(addr));\n return true;\n }\n\n return this.reportError(Bus8080.ERROR.ADD_MEM_BADRANGE, addr, size);\n }\n\n /**\n * cleanMemory(addr, size)\n *\n * @this {Bus8080}\n * @param {number} addr\n * @param {number} size\n * @return {boolean} true if all blocks were clean, false if dirty; all blocks are cleaned in the process\n */\n cleanMemory(addr, size)\n {\n var fClean = true;\n var iBlock = addr >>> this.nBlockShift;\n var sizeBlock = this.nBlockSize - (addr & this.nBlockLimit);\n while (size > 0 && iBlock < this.aMemBlocks.length) {\n if (this.aMemBlocks[iBlock].fDirty) {\n this.aMemBlocks[iBlock].fDirty = fClean = false;\n this.aMemBlocks[iBlock].fDirtyEver = true;\n }\n size -= sizeBlock;\n sizeBlock = this.nBlockSize;\n iBlock++;\n }\n return fClean;\n }\n\n /**\n * scanMemory(info, addr, size)\n *\n * Returns a BusInfo8080 object for the specified address range.\n *\n * @this {Bus8080}\n * @param {Object} [info] previous BusInfo8080, if any\n * @param {number} [addr] starting address of range (0 if none provided)\n * @param {number} [size] size of range, in bytes (up to end of address space if none provided)\n * @return {Object} updated info (or new info if no previous info provided)\n */\n scanMemory(info, addr, size)\n {\n if (addr == null) addr = 0;\n if (size == null) size = (this.addrTotal - addr) | 0;\n if (info == null) info = {cbTotal: 0, cBlocks: 0, aBlocks: []};\n\n var iBlock = addr >>> this.nBlockShift;\n var iBlockMax = ((addr + size - 1) >>> this.nBlockShift);\n\n info.cbTotal = 0;\n info.cBlocks = 0;\n while (iBlock <= iBlockMax) {\n var block = this.aMemBlocks[iBlock];\n info.cbTotal += block.size;\n if (block.size) {\n info.aBlocks.push(Usr.initBitFields(Bus8080.BlockInfo, iBlock, 0, 0, block.type));\n info.cBlocks++\n }\n iBlock++;\n }\n return info;\n }\n\n /**\n * getWidth()\n *\n * @this {Bus8080}\n * @return {number}\n */\n getWidth()\n {\n return this.nBusWidth;\n }\n\n /**\n * removeMemory(addr, size)\n *\n * Replaces every block in the specified address range with empty Memory blocks that ignore all reads/writes.\n *\n * TODO: Update the removeMemory() interface to reflect the relaxed requirements of the addMemory() interface.\n *\n * @this {Bus8080}\n * @param {number} addr\n * @param {number} size\n * @return {boolean} true if successful, false if not\n */\n removeMemory(addr, size)\n {\n if (!(addr & this.nBlockLimit) && size && !(size & this.nBlockLimit)) {\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0) {\n var blockOld = this.aMemBlocks[iBlock];\n var blockNew = new Memory8080(addr);\n blockNew.copyBreakpoints(this.dbg, blockOld);\n this.aMemBlocks[iBlock++] = blockNew;\n addr = iBlock * this.nBlockSize;\n size -= this.nBlockSize;\n }\n return true;\n }\n return this.reportError(Bus8080.ERROR.REM_MEM_BADRANGE, addr, size);\n }\n\n /**\n * getMemoryBlocks(addr, size)\n *\n * @this {Bus8080}\n * @param {number} addr is the starting physical address\n * @param {number} size of the request, in bytes\n * @return {Array} of Memory blocks\n */\n getMemoryBlocks(addr, size)\n {\n var aBlocks = [];\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0 && iBlock < this.aMemBlocks.length) {\n aBlocks.push(this.aMemBlocks[iBlock++]);\n size -= this.nBlockSize;\n }\n return aBlocks;\n }\n\n /**\n * setMemoryBlocks(addr, size, aBlocks, type)\n *\n * If no type is specified, then specified address range uses all the provided blocks as-is;\n * this form of setMemoryBlocks() is used for complete physical aliases.\n *\n * Otherwise, new blocks are allocated with the specified type; the underlying memory from the\n * provided blocks is still used, but the new blocks may have different access to that memory.\n *\n * @this {Bus8080}\n * @param {number} addr is the starting physical address\n * @param {number} size of the request, in bytes\n * @param {Array} aBlocks as returned by getMemoryBlocks()\n * @param {number} [type] is one of the Memory8080.TYPE constants\n */\n setMemoryBlocks(addr, size, aBlocks, type)\n {\n var i = 0;\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0 && iBlock < this.aMemBlocks.length) {\n var block = aBlocks[i++];\n\n if (!block) break;\n if (type !== undefined) {\n var blockNew = new Memory8080(addr);\n blockNew.clone(block, type, this.dbg);\n block = blockNew;\n }\n this.aMemBlocks[iBlock++] = block;\n size -= this.nBlockSize;\n }\n }\n\n /**\n * getByte(addr)\n *\n * @this {Bus8080}\n * @param {number} addr is a physical address\n * @return {number} byte (8-bit) value at that address\n */\n getByte(addr)\n {\n return this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].readByte(addr & this.nBlockLimit, addr);\n }\n\n /**\n * getByteDirect(addr)\n *\n * This is useful for the Debugger and other components that want to bypass getByte() breakpoint detection.\n *\n * @this {Bus8080}\n * @param {number} addr is a physical address\n * @return {number} byte (8-bit) value at that address\n */\n getByteDirect(addr)\n {\n return this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].readByteDirect(addr & this.nBlockLimit, addr);\n }\n\n /**\n * getShort(addr)\n *\n * @this {Bus8080}\n * @param {number} addr is a physical address\n * @return {number} word (16-bit) value at that address\n */\n getShort(addr)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off != this.nBlockLimit) {\n return this.aMemBlocks[iBlock].readShort(off, addr);\n }\n return this.aMemBlocks[iBlock++].readByte(off, addr) | (this.aMemBlocks[iBlock & this.nBlockMask].readByte(0, addr + 1) << 8);\n }\n\n /**\n * getShortDirect(addr)\n *\n * This is useful for the Debugger and other components that want to bypass getShort() breakpoint detection.\n *\n * @this {Bus8080}\n * @param {number} addr is a physical address\n * @return {number} word (16-bit) value at that address\n */\n getShortDirect(addr)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off != this.nBlockLimit) {\n return this.aMemBlocks[iBlock].readShortDirect(off, addr);\n }\n return this.aMemBlocks[iBlock++].readByteDirect(off, addr) | (this.aMemBlocks[iBlock & this.nBlockMask].readByteDirect(0, addr + 1) << 8);\n }\n\n /**\n * setByte(addr, b)\n *\n * @this {Bus8080}\n * @param {number} addr is a physical address\n * @param {number} b is the byte (8-bit) value to write (we truncate it to 8 bits to be safe)\n */\n setByte(addr, b)\n {\n this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].writeByte(addr & this.nBlockLimit, b & 0xff, addr);\n }\n\n /**\n * setByteDirect(addr, b)\n *\n * This is useful for the Debugger and other components that want to bypass breakpoint detection AND read-only\n * memory protection (for example, this is an interface the ROM component could use to initialize ROM contents).\n *\n * @this {Bus8080}\n * @param {number} addr is a physical address\n * @param {number} b is the byte (8-bit) value to write (we truncate it to 8 bits to be safe)\n */\n setByteDirect(addr, b)\n {\n this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].writeByteDirect(addr & this.nBlockLimit, b & 0xff, addr);\n }\n\n /**\n * setShort(addr, w)\n *\n * @this {Bus8080}\n * @param {number} addr is a physical address\n * @param {number} w is the word (16-bit) value to write (we truncate it to 16 bits to be safe)\n */\n setShort(addr, w)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off != this.nBlockLimit) {\n this.aMemBlocks[iBlock].writeShort(off, w & 0xffff, addr);\n return;\n }\n this.aMemBlocks[iBlock++].writeByte(off, w & 0xff, addr);\n this.aMemBlocks[iBlock & this.nBlockMask].writeByte(0, (w >> 8) & 0xff, addr + 1);\n }\n\n /**\n * setShortDirect(addr, w)\n *\n * This is useful for the Debugger and other components that want to bypass breakpoint detection AND read-only\n * memory protection (for example, this is an interface the ROM component could use to initialize ROM contents).\n *\n * @this {Bus8080}\n * @param {number} addr is a physical address\n * @param {number} w is the word (16-bit) value to write (we truncate it to 16 bits to be safe)\n */\n setShortDirect(addr, w)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off != this.nBlockLimit) {\n this.aMemBlocks[iBlock].writeShortDirect(off, w & 0xffff, addr);\n return;\n }\n this.aMemBlocks[iBlock++].writeByteDirect(off, w & 0xff, addr);\n this.aMemBlocks[iBlock & this.nBlockMask].writeByteDirect(0, (w >> 8) & 0xff, addr + 1);\n }\n\n /**\n * addMemBreak(addr, fWrite)\n *\n * @this {Bus8080}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint\n */\n addMemBreak(addr, fWrite)\n {\n if (DEBUGGER) {\n var iBlock = addr >>> this.nBlockShift;\n this.aMemBlocks[iBlock].addBreakpoint(addr & this.nBlockLimit, fWrite);\n }\n }\n\n /**\n * removeMemBreak(addr, fWrite)\n *\n * @this {Bus8080}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint\n */\n removeMemBreak(addr, fWrite)\n {\n if (DEBUGGER) {\n var iBlock = addr >>> this.nBlockShift;\n this.aMemBlocks[iBlock].removeBreakpoint(addr & this.nBlockLimit, fWrite);\n }\n }\n\n /**\n * saveMemory(fAll)\n *\n * The only memory blocks we save are those marked as dirty, but most likely all of RAM will have been marked dirty,\n * and even if our dirty-memory flags were as smart as our dirty-sector flags (ie, were set only when a write changed\n * what was already there), it's unlikely that would reduce the number of RAM blocks we must save/restore. At least\n * all the ROM blocks should be clean (except in the unlikely event that the Debugger was used to modify them).\n *\n * All dirty blocks will be stored in a single array, as pairs of block numbers and data arrays, like so:\n *\n * [iBlock0, [dw0, dw1, ...], iBlock1, [dw0, dw1, ...], ...]\n *\n * In a normal 4Kb block, there will be 1K DWORD values in the data array. Remember that each DWORD is a signed 32-bit\n * integer (because they are formed using bitwise operator rather than floating-point math operators), so don't be\n * surprised to see negative numbers in the data.\n *\n * The above example assumes \"uncompressed\" data arrays. If we choose to use \"compressed\" data arrays, the data arrays\n * will look like:\n *\n * [count0, dw0, count1, dw1, ...]\n *\n * where each count indicates how many times the following DWORD value occurs. A data array length less than 1K indicates\n * that it's compressed, since we'll only store them in compressed form if they actually shrank, and we'll use State\n * helper methods compress() and decompress() to create and expand the compressed data arrays.\n *\n * @this {Bus8080}\n * @param {boolean} [fAll] (true to save all non-ROM memory blocks, regardless of their dirty flags)\n * @return {Array} a\n */\n saveMemory(fAll)\n {\n var i = 0;\n var a = [];\n\n for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {\n var block = this.aMemBlocks[iBlock];\n /*\n * We have to check both fDirty and fDirtyEver, because we may have called cleanMemory() on some of\n * the memory blocks (eg, video memory), and while cleanMemory() will clear a dirty block's fDirty flag,\n * it also sets the dirty block's fDirtyEver flag, which is left set for the lifetime of the machine.\n */\n if (fAll && block.type != Memory8080.TYPE.ROM || block.fDirty || block.fDirtyEver) {\n a[i++] = iBlock;\n a[i++] = State.compress(block.save());\n }\n }\n\n return a;\n }\n\n /**\n * restoreMemory(a)\n *\n * This restores the contents of all Memory blocks; called by CPUState.restore().\n *\n * In theory, we ONLY have to save/restore block contents. Other block attributes,\n * like the type, the memory controller (if any), and the active memory access functions,\n * should already be restored, since every component (re)allocates all the memory blocks\n * it was using when it's restored. And since the CPU is guaranteed to be the last\n * component to be restored, all those blocks (and their attributes) should be in place now.\n *\n * See saveMemory() for more information on how the memory block contents are saved.\n *\n * @this {Bus8080}\n * @param {Array} a\n * @return {boolean} true if successful, false if not\n */\n restoreMemory(a)\n {\n var i;\n for (i = 0; i < a.length - 1; i += 2) {\n var iBlock = a[i];\n var adw = a[i+1];\n if (adw && adw.length < this.nBlockLen) {\n adw = State.decompress(adw, this.nBlockLen);\n }\n var block = this.aMemBlocks[iBlock];\n if (!block || !block.restore(adw)) {\n /*\n * Either the block to restore hasn't been allocated, indicating a change in the machine\n * configuration since it was last saved (the most likely explanation) or there's some internal\n * inconsistency (eg, the block size is wrong).\n */\n Component.error(\"Unable to restore memory block \" + iBlock);\n return false;\n }\n }\n return true;\n }\n\n /**\n * addPortInputBreak(port)\n *\n * @this {Bus8080}\n * @param {number} [port]\n * @return {boolean} true if break on port input enabled, false if disabled\n */\n addPortInputBreak(port)\n {\n if (port === undefined) {\n this.fPortInputBreakAll = !this.fPortInputBreakAll;\n return this.fPortInputBreakAll;\n }\n if (this.aPortInputNotify[port] === undefined) {\n this.aPortInputNotify[port] = [null, false];\n }\n this.aPortInputNotify[port][1] = !this.aPortInputNotify[port][1];\n return this.aPortInputNotify[port][1];\n }\n\n /**\n * addPortInputNotify(start, end, fn)\n *\n * Add a port input-notification handler to the list of such handlers.\n *\n * @this {Bus8080}\n * @param {number} start port address\n * @param {number} end port address\n * @param {function(number,number)} fn is called with the port and IP values at the time of the input\n */\n addPortInputNotify(start, end, fn)\n {\n if (fn !== undefined) {\n for (var port = start; port <= end; port++) {\n if (this.aPortInputNotify[port] !== undefined) {\n Component.warning(\"Input port \" + Str.toHexWord(port) + \" already registered\");\n continue;\n }\n this.aPortInputNotify[port] = [fn, false];\n if (MAXDEBUG) this.log(\"addPortInputNotify(\" + Str.toHexWord(port) + \")\");\n }\n }\n }\n\n /**\n * addPortInputTable(component, table, offset)\n *\n * Add port input-notification handlers from the specified table (a batch version of addPortInputNotify)\n *\n * @this {Bus8080}\n * @param {Component} component\n * @param {Object} table\n * @param {number} [offset] is an optional port offset\n */\n addPortInputTable(component, table, offset)\n {\n if (offset === undefined) offset = 0;\n if (table) {\n for (var port in table) {\n this.addPortInputNotify(+port + offset, +port + offset, table[port].bind(component));\n }\n }\n }\n\n /**\n * addPortInputWidth(port, size)\n *\n * By default, all input ports are 1 byte wide; ports that are wider must call this function.\n *\n * @this {Bus8080}\n * @param {number} port\n * @param {number} size (1, 2 or 4)\n */\n addPortInputWidth(port, size)\n {\n this.aPortInputWidth[port] = size;\n }\n\n /**\n * checkPortInputNotify(port, size, addrIP)\n *\n * @this {Bus8080}\n * @param {number} port\n * @param {number} size (1, 2 or 4)\n * @param {number} [addrIP] is the IP value at the time of the input\n * @return {number} simulated port data\n *\n * NOTE: It seems that parts of the ROM BIOS (like the RS-232 probes around F000:E5D7 in the 5150 BIOS)\n * assume that ports for non-existent hardware return 0xff rather than 0x00, hence my new default (0xff) below.\n */\n checkPortInputNotify(port, size, addrIP)\n {\n var data = 0, shift = 0;\n\n while (size > 0) {\n\n var aNotify = this.aPortInputNotify[port];\n var sizePort = this.aPortInputWidth[port] || 1;\n var maskPort = (sizePort == 1? 0xff : (sizePort == 2? 0xffff : -1));\n var dataPort = maskPort;\n\n /*\n * TODO: We need to decide what to do about 8-bit I/O to a 16-bit port (ditto for 16-bit I/O\n * to a 32-bit port). We probably should pass the size through to the aNotify[0] handler,\n * and let it decide what to do, but I don't feel like changing all the I/O handlers right now.\n * The good news, at least, is that the 8-bit handlers would not have to do anything special.\n * This assert will warn us if this is a pressing need.\n */\n\n\n if (aNotify !== undefined) {\n if (aNotify[0]) {\n dataPort = aNotify[0](port, addrIP);\n if (dataPort === undefined) {\n dataPort = maskPort;\n } else {\n dataPort &= maskPort;\n }\n }\n if (DEBUGGER && this.dbg && this.fPortInputBreakAll != aNotify[1]) {\n this.dbg.checkPortInput(port, size, dataPort);\n }\n }\n else {\n if (DEBUGGER && this.dbg) {\n this.dbg.messageIO(this, port, null, addrIP);\n if (this.fPortInputBreakAll) this.dbg.checkPortInput(port, size, dataPort);\n }\n }\n\n data |= dataPort << shift;\n shift += (sizePort << 3);\n port += sizePort;\n size -= sizePort;\n }\n\n\n return data;\n }\n\n /**\n * addPortOutputBreak(port)\n *\n * @this {Bus8080}\n * @param {number} [port]\n * @return {boolean} true if break on port output enabled, false if disabled\n */\n addPortOutputBreak(port)\n {\n if (port === undefined) {\n this.fPortOutputBreakAll = !this.fPortOutputBreakAll;\n return this.fPortOutputBreakAll;\n }\n if (this.aPortOutputNotify[port] === undefined) {\n this.aPortOutputNotify[port] = [null, false];\n }\n this.aPortOutputNotify[port][1] = !this.aPortOutputNotify[port][1];\n return this.aPortOutputNotify[port][1];\n }\n\n /**\n * addPortOutputNotify(start, end, fn)\n *\n * Add a port output-notification handler to the list of such handlers.\n *\n * @this {Bus8080}\n * @param {number} start port address\n * @param {number} end port address\n * @param {function(number,number)} fn is called with the port and IP values at the time of the output\n */\n addPortOutputNotify(start, end, fn)\n {\n if (fn !== undefined) {\n for (var port = start; port <= end; port++) {\n if (this.aPortOutputNotify[port] !== undefined) {\n Component.warning(\"Output port \" + Str.toHexWord(port) + \" already registered\");\n continue;\n }\n this.aPortOutputNotify[port] = [fn, false];\n if (MAXDEBUG) this.log(\"addPortOutputNotify(\" + Str.toHexWord(port) + \")\");\n }\n }\n }\n\n /**\n * addPortOutputTable(component, table, offset)\n *\n * Add port output-notification handlers from the specified table (a batch version of addPortOutputNotify)\n *\n * @this {Bus8080}\n * @param {Component} component\n * @param {Object} table\n * @param {number} [offset] is an optional port offset\n */\n addPortOutputTable(component, table, offset)\n {\n if (offset === undefined) offset = 0;\n if (table) {\n for (var port in table) {\n this.addPortOutputNotify(+port + offset, +port + offset, table[port].bind(component));\n }\n }\n }\n\n /**\n * addPortOutputWidth(port, size)\n *\n * By default, all output ports are 1 byte wide; ports that are wider must call this function.\n *\n * @this {Bus8080}\n * @param {number} port\n * @param {number} size (1, 2 or 4)\n */\n addPortOutputWidth(port, size)\n {\n this.aPortOutputWidth[port] = size;\n }\n\n /**\n * checkPortOutputNotify(port, size, data, addrIP)\n *\n * @this {Bus8080}\n * @param {number} port\n * @param {number} size\n * @param {number} data\n * @param {number} [addrIP] is the IP value at the time of the output\n */\n checkPortOutputNotify(port, size, data, addrIP)\n {\n var shift = 0;\n\n while (size > 0) {\n\n var aNotify = this.aPortOutputNotify[port];\n var sizePort = this.aPortOutputWidth[port] || 1;\n var maskPort = (sizePort == 1? 0xff : (sizePort == 2? 0xffff : -1));\n var dataPort = (data >>>= shift) & maskPort;\n\n /*\n * TODO: We need to decide what to do about 8-bit I/O to a 16-bit port (ditto for 16-bit I/O\n * to a 32-bit port). We probably should pass the size through to the aNotify[0] handler,\n * and let it decide what to do, but I don't feel like changing all the I/O handlers right now.\n * The good news, at least, is that the 8-bit handlers would not have to do anything special.\n * This assert will warn us if this is a pressing need.\n */\n\n\n if (aNotify !== undefined) {\n if (aNotify[0]) {\n aNotify[0](port, dataPort, addrIP);\n }\n if (DEBUGGER && this.dbg && this.fPortOutputBreakAll != aNotify[1]) {\n this.dbg.checkPortOutput(port, size, dataPort);\n }\n }\n else {\n if (DEBUGGER && this.dbg) {\n this.dbg.messageIO(this, port, dataPort, addrIP);\n if (this.fPortOutputBreakAll) this.dbg.checkPortOutput(port, size, dataPort);\n }\n }\n\n shift += (sizePort << 3);\n port += sizePort;\n size -= sizePort;\n }\n\n }\n\n /**\n * removePortInputNotify(start, end)\n *\n * Remove port input-notification handler(s) (to be ENABLED later if needed)\n *\n * @this {Bus8080}\n * @param {number} start address\n * @param {number} end address\n *\n removePortInputNotify(start, end)\n {\n for (var port = start; port < end; port++) {\n if (this.aPortInputNotify[port]) {\n delete this.aPortInputNotify[port];\n }\n }\n }\n */\n\n /**\n * removePortOutputNotify(start, end)\n *\n * Remove port output-notification handler(s) (to be ENABLED later if needed)\n *\n * @this {Bus8080}\n * @param {number} start address\n * @param {number} end address\n *\n removePortOutputNotify(start, end)\n {\n for (var port = start; port < end; port++) {\n if (this.aPortOutputNotify[port]) {\n delete this.aPortOutputNotify[port];\n }\n }\n }\n */\n\n /**\n * reportError(op, addr, size, fQuiet)\n *\n * @this {Bus8080}\n * @param {number} op\n * @param {number} addr\n * @param {number} size\n * @param {boolean} [fQuiet] (true if any error should be quietly logged)\n * @return {boolean} false\n */\n reportError(op, addr, size, fQuiet)\n {\n var sError = \"Memory block error (\" + op + \": \" + Str.toHex(addr) + \",\" + Str.toHex(size) + \")\";\n if (fQuiet) {\n if (this.dbg) {\n this.dbg.message(sError);\n } else {\n this.log(sError);\n }\n } else {\n Component.error(sError);\n }\n return false;\n }\n}\n\nBus8080.ERROR = {\n ADD_MEM_INUSE: 1,\n ADD_MEM_BADRANGE: 2,\n SET_MEM_BADRANGE: 4,\n REM_MEM_BADRANGE: 5\n};\n\n/*\n * Data types used by scanMemory()\n */\n\n/**\n * @typedef {number}\n */\nvar BlockInfo;\n\n/**\n * This defines the BlockInfo bit fields used by scanMemory() when it creates the aBlocks array.\n *\n * @typedef {{\n * num: BitField,\n * count: BitField,\n * btmod: BitField,\n * type: BitField\n * }}\n */\nBus8080.BlockInfo = Usr.defineBitFields({num:20, count:8, btmod:1, type:3});\n\n/**\n * BusInfo8080 object definition (returned by scanMemory())\n *\n * cbTotal: total bytes allocated\n * cBlocks: total Memory blocks allocated\n * aBlocks: array of allocated Memory block numbers\n *\n * @typedef {{\n * cbTotal: number,\n * cBlocks: number,\n * aBlocks: Array.<BlockInfo>\n * }}\n */\nvar BusInfo8080;\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/memory.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * @class DataView\n * @property {function(number,boolean):number} getUint8\n * @property {function(number,number,boolean)} setUint8\n * @property {function(number,boolean):number} getUint16\n * @property {function(number,number,boolean)} setUint16\n * @property {function(number,boolean):number} getInt32\n * @property {function(number,number,boolean)} setInt32\n */\n\nvar littleEndian = (TYPEDARRAYS? (function() {\n var buffer = new ArrayBuffer(2);\n new DataView(buffer).setUint16(0, 256, true);\n return new Uint16Array(buffer)[0] === 256;\n})() : false);\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass Memory8080 {\n /**\n * Memory8080(addr, used, size, type)\n *\n * The Bus component allocates Memory8080 objects so that each has a memory buffer with a\n * block-granular starting address and an address range equal to bus.nBlockSize; however,\n * the size of any given Memory8080 object's underlying buffer can be either zero or bus.nBlockSize;\n * memory read/write functions for empty (buffer-less) blocks are mapped to readNone/writeNone.\n *\n * The Bus allocates empty blocks for the entire address space during initialization, so that\n * any reads/writes to undefined addresses will have no effect. Later, the ROM and RAM\n * components will ask the Bus to allocate memory for specific ranges, and the Bus will allocate\n * as many new blockSize Memory8080 objects as the ranges require. Partial Memory8080 blocks could\n * also be supported in theory, but in practice, they're not.\n *\n * Because Memory8080 blocks now allow us to have a \"sparse\" address space, we could choose to\n * take the memory hit of allocating 4K arrays per block, where each element stores only one byte,\n * instead of the more frugal but slightly slower approach of allocating arrays of 32-bit dwords\n * (LONGARRAYS) and shifting/masking bytes/words to/from dwords; in theory, byte accesses would\n * be faster and word accesses somewhat less faster.\n *\n * However, preliminary testing of that feature (BYTEARRAYS) did not yield significantly faster\n * performance, so it is OFF by default to minimize our memory consumption. Using TYPEDARRAYS\n * would seem best, but as discussed in defines.js, it's off by default, because it doesn't perform\n * as well as LONGARRAYS; the other advantage of TYPEDARRAYS is that it should theoretically use\n * about 1/2 the memory of LONGARRAYS (32-bit elements vs 64-bit numbers), but I value speed over\n * size at this point. Also, not all JavaScript implementations support TYPEDARRAYS (IE9 is probably\n * the only real outlier: it lacks typed arrays but otherwise has all the necessary HTML5 support).\n *\n * WARNING: Since Memory8080 blocks are low-level objects that have no UI requirements, they\n * do not inherit from the Component class, so if you want to use any Component class methods,\n * such as Component.assert(), use the corresponding Debugger methods instead (assuming a debugger\n * is available).\n *\n * @this {Memory8080}\n * @param {number|null} [addr] of lowest used address in block\n * @param {number} [used] portion of block in bytes (0 for none); must be a multiple of 4\n * @param {number} [size] of block's buffer in bytes (0 for none); must be a multiple of 4\n * @param {number} [type] is one of the Memory8080.TYPE constants (default is Memory8080.TYPE.NONE)\n */\n constructor(addr, used, size, type)\n {\n var i;\n this.id = (Memory8080.idBlock += 2);\n this.adw = null;\n this.offset = 0;\n this.addr = addr;\n this.used = used;\n this.size = size || 0;\n this.type = type || Memory8080.TYPE.NONE;\n this.fReadOnly = (type == Memory8080.TYPE.ROM);\n this.copyBreakpoints(); // initialize the block's Debugger info; the caller will reinitialize\n\n /*\n * TODO: Study the impact of dirty block tracking. The original purposes were to allow saveMemory()\n * to save only dirty blocks, and to enable the Video component to quickly detect changes to the video buffer.\n * But the benefit to saveMemory() is minimal, and the Video component has other options; for example, it now\n * uses a custom memory controller for all EGA/VGA video modes, which performs its own dirty block tracking,\n * and that could easily be extended to the older MDA/CGA video modes, which still use conventional memory blocks.\n * Alternatively, we could restrict the use of dirty block tracking to certain memory types (eg, VIDEO memory).\n *\n * However, a quick test with dirty block tracking disabled didn't yield a noticeable improvement in performance,\n * so I think the overhead of our block-based architecture is swamping the impact of these micro-updates.\n */\n this.fDirty = this.fDirtyEver = false;\n\n /*\n * For empty memory blocks, all we need to do is ensure all access functions are mapped to \"none\" handlers.\n */\n if (!size) {\n this.setAccess();\n return;\n }\n\n /*\n * This is the normal case: allocate a buffer that provides 8 bits of data per address;\n * no controller is required because our default memory access functions (see afnMemory)\n * know how to deal with this simple 1-1 mapping of addresses to bytes and words.\n *\n * TODO: Consider initializing the memory array to random (or pseudo-random) values in DEBUG\n * mode; pseudo-random might be best, to help make any bugs reproducible.\n */\n if (TYPEDARRAYS) {\n this.buffer = new ArrayBuffer(size);\n this.dv = new DataView(this.buffer, 0, size);\n /*\n * If littleEndian is true, we can use ab[], aw[] and adw[] directly; well, we can use them\n * whenever the offset is a multiple of 1, 2 or 4, respectively. Otherwise, we must fallback to\n * dv.getUint8()/dv.setUint8(), dv.getUint16()/dv.setUint16() and dv.getInt32()/dv.setInt32().\n */\n this.ab = new Uint8Array(this.buffer, 0, size);\n this.aw = new Uint16Array(this.buffer, 0, size >> 1);\n this.adw = new Int32Array(this.buffer, 0, size >> 2);\n this.setAccess(littleEndian? Memory8080.afnArrayLE : Memory8080.afnArrayBE);\n } else {\n if (BYTEARRAYS) {\n this.ab = new Array(size);\n } else {\n /*\n * NOTE: This is the default mode of operation (!TYPEDARRAYS && !BYTEARRAYS), because it\n * seems to provide the best performance; and although in theory, that performance might\n * come at twice the overhead of TYPEDARRAYS, it's increasingly likely that the JavaScript\n * runtime will notice that all we ever store are 32-bit values, and optimize accordingly.\n */\n this.adw = new Array(size >> 2);\n for (i = 0; i < this.adw.length; i++) this.adw[i] = 0;\n }\n this.setAccess(Memory8080.afnMemory);\n }\n }\n\n /**\n * init(addr)\n *\n * Quick reinitializer when reusing a Memory8080 block.\n *\n * @this {Memory8080}\n * @param {number} addr\n */\n init(addr)\n {\n this.addr = addr;\n }\n\n /**\n * clone(mem, type)\n *\n * Converts the current Memory8080 block (this) into a clone of the given Memory8080 block (mem),\n * and optionally overrides the current block's type with the specified type.\n *\n * @this {Memory8080}\n * @param {Memory8080} mem\n * @param {number} [type]\n * @param {Debugger8080} [dbg]\n */\n clone(mem, type, dbg)\n {\n /*\n * Original memory block IDs are even; cloned memory block IDs are odd;\n * the original ID of the current block is lost, but that's OK, since it was presumably\n * produced merely to become a clone.\n */\n this.id = mem.id | 0x1;\n this.used = mem.used;\n this.size = mem.size;\n if (type) {\n this.type = type;\n this.fReadOnly = (type == Memory8080.TYPE.ROM);\n }\n if (TYPEDARRAYS) {\n this.buffer = mem.buffer;\n this.dv = mem.dv;\n this.ab = mem.ab;\n this.aw = mem.aw;\n this.adw = mem.adw;\n this.setAccess(littleEndian? Memory8080.afnArrayLE : Memory8080.afnArrayBE);\n } else {\n if (BYTEARRAYS) {\n this.ab = mem.ab;\n } else {\n this.adw = mem.adw;\n }\n this.setAccess(Memory8080.afnMemory);\n }\n this.copyBreakpoints(dbg, mem);\n }\n\n /**\n * save()\n *\n * This gets the contents of a Memory8080 block as an array of 32-bit values; used by Bus8080.saveMemory(),\n * which in turn is called by CPUState.save().\n *\n * Memory8080 blocks with custom memory controllers do NOT save their contents; that's the responsibility\n * of the controller component.\n *\n * @this {Memory8080}\n * @return {Array|Int32Array|null}\n */\n save()\n {\n var adw, i;\n if (BYTEARRAYS) {\n adw = new Array(this.size >> 2);\n var off = 0;\n for (i = 0; i < adw.length; i++) {\n adw[i] = this.ab[off] | (this.ab[off + 1] << 8) | (this.ab[off + 2] << 16) | (this.ab[off + 3] << 24);\n off += 4;\n }\n }\n else if (TYPEDARRAYS) {\n /*\n * It might be tempting to just return a copy of Int32Array(this.buffer, 0, this.size >> 2),\n * but we can't be sure of the \"endianness\" of an Int32Array -- which would be OK if the array\n * was always saved/restored on the same machine, but there's no guarantee of that, either.\n * So we use getInt32() and require little-endian values.\n *\n * Moreover, an Int32Array isn't treated by JSON.stringify() and JSON.parse() exactly like\n * a normal array; it's serialized as an Object rather than an Array, so it lacks a \"length\"\n * property and causes problems for State.store() and State.parse().\n */\n adw = new Array(this.size >> 2);\n for (i = 0; i < adw.length; i++) {\n adw[i] = this.dv.getInt32(i << 2, true);\n }\n }\n else {\n adw = this.adw;\n }\n return adw;\n }\n\n /**\n * restore(adw)\n *\n * This restores the contents of a Memory8080 block from an array of 32-bit values;\n * used by Bus8080.restoreMemory(), which is called by CPUState.restore(), after all other\n * components have been restored and thus all Memory8080 blocks have been allocated\n * by their respective components.\n *\n * @this {Memory8080}\n * @param {Array|null} adw\n * @return {boolean} true if successful, false if block size mismatch\n */\n restore(adw)\n {\n /*\n * At this point, it's a consistency error for adw to be null; it's happened once already,\n * when there was a restore bug in the Video component that added the frame buffer at the video\n * card's \"spec'ed\" address instead of the programmed address, so there were no controller-owned\n * memory blocks installed at the programmed address, and so we arrived here at a block with\n * no controller AND no data.\n */\n\n\n if (adw && this.size == adw.length << 2) {\n var i;\n if (BYTEARRAYS) {\n var off = 0;\n for (i = 0; i < adw.length; i++) {\n this.ab[off] = adw[i] & 0xff;\n this.ab[off + 1] = (adw[i] >> 8) & 0xff;\n this.ab[off + 2] = (adw[i] >> 16) & 0xff;\n this.ab[off + 3] = (adw[i] >> 24) & 0xff;\n off += 4;\n }\n } else if (TYPEDARRAYS) {\n for (i = 0; i < adw.length; i++) {\n this.dv.setInt32(i << 2, adw[i], true);\n }\n } else {\n this.adw = adw;\n }\n this.fDirty = true;\n return true;\n }\n return false;\n }\n\n /**\n * setAccess(afn, fDirect)\n *\n * If no function table is specified, a default is selected based on the Memory8080 type.\n *\n * @this {Memory8080}\n * @param {Array.<function()>} [afn] function table\n * @param {boolean} [fDirect] (true to update direct access functions as well; default is true)\n */\n setAccess(afn, fDirect)\n {\n if (!afn) {\n\n afn = Memory8080.afnNone;\n }\n this.setReadAccess(afn, fDirect);\n this.setWriteAccess(afn, fDirect);\n }\n\n /**\n * setReadAccess(afn, fDirect)\n *\n * @this {Memory8080}\n * @param {Array.<function()>} afn\n * @param {boolean} [fDirect]\n */\n setReadAccess(afn, fDirect)\n {\n if (!fDirect || !this.cReadBreakpoints) {\n this.readByte = afn[0] || this.readNone;\n this.readShort = afn[2] || this.readShortDefault;\n }\n if (fDirect || fDirect === undefined) {\n this.readByteDirect = afn[0] || this.readNone;\n this.readShortDirect = afn[2] || this.readShortDefault;\n }\n }\n\n /**\n * setWriteAccess(afn, fDirect)\n *\n * @this {Memory8080}\n * @param {Array.<function()>} afn\n * @param {boolean} [fDirect]\n */\n setWriteAccess(afn, fDirect)\n {\n if (!fDirect || !this.cWriteBreakpoints) {\n this.writeByte = !this.fReadOnly && afn[1] || this.writeNone;\n this.writeShort = !this.fReadOnly && afn[3] || this.writeShortDefault;\n }\n if (fDirect || fDirect === undefined) {\n this.writeByteDirect = afn[1] || this.writeNone;\n this.writeShortDirect = afn[3] || this.writeShortDefault;\n }\n }\n\n /**\n * resetReadAccess()\n *\n * @this {Memory8080}\n */\n resetReadAccess()\n {\n this.readByte = this.readByteDirect;\n this.readShort = this.readShortDirect;\n }\n\n /**\n * resetWriteAccess()\n *\n * @this {Memory8080}\n */\n resetWriteAccess()\n {\n this.writeByte = this.fReadOnly? this.writeNone : this.writeByteDirect;\n this.writeShort = this.fReadOnly? this.writeShortDefault : this.writeShortDirect;\n }\n\n /**\n * printAddr(sMessage)\n *\n * @this {Memory8080}\n * @param {string} sMessage\n */\n printAddr(sMessage)\n {\n if (DEBUG && this.dbg && this.dbg.messageEnabled(Messages8080.MEM)) {\n this.dbg.printMessage(sMessage + ' ' + (this.addr != null? ('%' + Str.toHex(this.addr)) : '#' + this.id), true);\n }\n }\n\n /**\n * addBreakpoint(off, fWrite)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {boolean} fWrite\n */\n addBreakpoint(off, fWrite)\n {\n if (!fWrite) {\n if (this.cReadBreakpoints++ === 0) {\n this.setReadAccess(Memory8080.afnChecked, false);\n }\n if (DEBUG) this.printAddr(\"read breakpoint added to memory block\");\n }\n else {\n if (this.cWriteBreakpoints++ === 0) {\n this.setWriteAccess(Memory8080.afnChecked, false);\n }\n if (DEBUG) this.printAddr(\"write breakpoint added to memory block\");\n }\n }\n\n /**\n * removeBreakpoint(off, fWrite)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {boolean} fWrite\n */\n removeBreakpoint(off, fWrite)\n {\n if (!fWrite) {\n if (--this.cReadBreakpoints === 0) {\n this.resetReadAccess();\n if (DEBUG) this.printAddr(\"all read breakpoints removed from memory block\");\n }\n\n }\n else {\n if (--this.cWriteBreakpoints === 0) {\n this.resetWriteAccess();\n if (DEBUG) this.printAddr(\"all write breakpoints removed from memory block\");\n }\n\n }\n }\n\n /**\n * copyBreakpoints(dbg, mem)\n *\n * @this {Memory8080}\n * @param {Debugger8080} [dbg]\n * @param {Memory8080} [mem] (outgoing Memory8080 block to copy breakpoints from, if any)\n */\n copyBreakpoints(dbg, mem)\n {\n this.dbg = dbg;\n this.cReadBreakpoints = this.cWriteBreakpoints = 0;\n if (mem) {\n if ((this.cReadBreakpoints = mem.cReadBreakpoints)) {\n this.setReadAccess(Memory8080.afnChecked, false);\n }\n if ((this.cWriteBreakpoints = mem.cWriteBreakpoints)) {\n this.setWriteAccess(Memory8080.afnChecked, false);\n }\n }\n }\n\n /**\n * readNone(off)\n *\n * Previously, this always returned 0x00, but the initial memory probe by the COMPAQ DeskPro 386 ROM BIOS\n * writes 0x0000 to the first word of every 64Kb block in the nearly 16Mb address space it supports, and\n * if it reads back 0x0000, it will initially think that LOTS of RAM exists, only to be disappointed later\n * when it performs a more exhaustive memory test, generating unwanted error messages in the process.\n *\n * TODO: Determine if we should have separate readByteNone(), readShortNone() and readLongNone() functions\n * to return 0xff, 0xffff and 0xffffffff|0, respectively. This seems sufficient for now, as it seems unlikely\n * that a system would require nonexistent memory locations to return ALL bits set.\n *\n * Also, I'm reluctant to address that potential issue by simply returning -1, because to date, the above\n * Memory8080 interfaces have always returned values that are properly masked to 8, 16 or 32 bits, respectively.\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readNone(off, addr)\n {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages8080.CPU | Messages8080.MEM) /* && !off */) {\n this.dbg.message(\"attempt to read invalid block %\" + Str.toHex(this.addr), true);\n }\n return 0xff;\n }\n\n /**\n * writeNone(off, v, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} v (could be either a byte or word value, since we use the same handler for both kinds of accesses)\n * @param {number} addr\n */\n writeNone(off, v, addr)\n {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages8080.CPU | Messages8080.MEM) /* && !off */) {\n this.dbg.message(\"attempt to write \" + Str.toHexWord(v) + \" to invalid block %\" + Str.toHex(this.addr), true);\n }\n }\n\n /**\n * readShortDefault(off, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortDefault(off, addr)\n {\n return this.readByte(off++, addr++) | (this.readByte(off, addr) << 8);\n }\n\n /**\n * writeShortDefault(off, w, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeShortDefault(off, w, addr)\n {\n this.writeByte(off++, w & 0xff, addr++);\n this.writeByte(off, w >> 8, addr);\n }\n\n /**\n * readByteMemory(off, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteMemory(off, addr)\n {\n if (BYTEARRAYS) {\n return this.ab[off];\n }\n return ((this.adw[off >> 2] >>> ((off & 0x3) << 3)) & 0xff);\n }\n\n /**\n * readShortMemory(off, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortMemory(off, addr)\n {\n if (BYTEARRAYS) {\n return this.ab[off] | (this.ab[off + 1] << 8);\n }\n var w;\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n var dw = (this.adw[idw] >> nShift);\n if (nShift < 24) {\n w = dw & 0xffff;\n } else {\n w = (dw & 0xff) | ((this.adw[idw + 1] & 0xff) << 8);\n }\n return w;\n }\n\n /**\n * writeByteMemory(off, b, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} b\n * @param {number} addr\n */\n writeByteMemory(off, b, addr)\n {\n if (BYTEARRAYS) {\n this.ab[off] = b;\n } else {\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n this.adw[idw] = (this.adw[idw] & ~(0xff << nShift)) | (b << nShift);\n }\n this.fDirty = true;\n }\n\n /**\n * writeShortMemory(off, w, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeShortMemory(off, w, addr)\n {\n if (BYTEARRAYS) {\n this.ab[off] = (w & 0xff);\n this.ab[off + 1] = (w >> 8);\n } else {\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n if (nShift < 24) {\n this.adw[idw] = (this.adw[idw] & ~(0xffff << nShift)) | (w << nShift);\n } else {\n this.adw[idw] = (this.adw[idw] & 0x00ffffff) | (w << 24);\n idw++;\n this.adw[idw] = (this.adw[idw] & (0xffffff00|0)) | (w >> 8);\n }\n }\n this.fDirty = true;\n }\n\n /**\n * readByteChecked(off, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteChecked(off, addr)\n {\n if (DEBUGGER && this.dbg && this.addr != null) {\n this.dbg.checkMemoryRead(this.addr + off);\n }\n return this.readByteDirect(off, addr);\n }\n\n /**\n * readShortChecked(off, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortChecked(off, addr)\n {\n if (DEBUGGER && this.dbg && this.addr != null) {\n this.dbg.checkMemoryRead(this.addr + off, 2);\n }\n return this.readShortDirect(off, addr);\n }\n\n /**\n * writeByteChecked(off, b, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @param {number} b\n */\n writeByteChecked(off, b, addr)\n {\n if (DEBUGGER && this.dbg && this.addr != null) {\n this.dbg.checkMemoryWrite(this.addr + off);\n }\n if (this.fReadOnly) this.writeNone(off, b, addr); else this.writeByteDirect(off, b, addr);\n }\n\n /**\n * writeShortChecked(off, w, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @param {number} w\n */\n writeShortChecked(off, w, addr)\n {\n if (DEBUGGER && this.dbg && this.addr != null) {\n this.dbg.checkMemoryWrite(this.addr + off, 2)\n }\n if (this.fReadOnly) this.writeNone(off, w, addr); else this.writeShortDirect(off, w, addr);\n }\n\n /**\n * readByteBE(off, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteBE(off, addr)\n {\n return this.ab[off];\n }\n\n /**\n * readByteLE(off, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteLE(off, addr)\n {\n return this.ab[off];\n }\n\n /**\n * readShortBE(off, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortBE(off, addr)\n {\n return this.dv.getUint16(off, true);\n }\n\n /**\n * readShortLE(off, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortLE(off, addr)\n {\n /*\n * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned read\n * vs. always reading the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.\n */\n return (off & 0x1)? (this.ab[off] | (this.ab[off+1] << 8)) : this.aw[off >> 1];\n }\n\n /**\n * writeByteBE(off, b, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} b\n * @param {number} addr\n */\n writeByteBE(off, b, addr)\n {\n this.ab[off] = b;\n this.fDirty = true;\n }\n\n /**\n * writeByteLE(off, b, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @param {number} b\n */\n writeByteLE(off, b, addr)\n {\n this.ab[off] = b;\n this.fDirty = true;\n }\n\n /**\n * writeShortBE(off, w, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @param {number} w\n */\n writeShortBE(off, w, addr)\n {\n this.dv.setUint16(off, w, true);\n this.fDirty = true;\n }\n\n /**\n * writeShortLE(off, w, addr)\n *\n * @this {Memory8080}\n * @param {number} off\n * @param {number} addr\n * @param {number} w\n */\n writeShortLE(off, w, addr)\n {\n /*\n * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned write\n * vs. always writing the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.\n */\n if (off & 0x1) {\n this.ab[off] = w;\n this.ab[off+1] = w >> 8;\n } else {\n this.aw[off >> 1] = w;\n }\n this.fDirty = true;\n }\n\n /**\n * adjustEndian(dw)\n *\n * @param {number} dw\n * @return {number}\n */\n static adjustEndian(dw)\n {\n if (TYPEDARRAYS && !littleEndian) {\n dw = (dw << 24) | ((dw << 8) & 0x00ff0000) | ((dw >> 8) & 0x0000ff00) | (dw >>> 24);\n }\n return dw;\n }\n}\n\n/*\n * Basic memory types\n *\n * RAM is the most conventional memory type, providing full read/write capability to x86-compatible (ie,\n * 'little endian\") storage. ROM is equally conventional, except that the fReadOnly property is set,\n * disabling writes. VIDEO is treated exactly like RAM, unless a controller is provided. Both RAM and\n * VIDEO memory are always considered writable, and even ROM can be written using the Bus setByteDirect()\n * interface (which in turn uses the Memory8080 writeByteDirect() interface), allowing the ROM component to\n * initialize its own memory. The CTRL type is used to identify memory-mapped devices that do not need\n * any default storage and always provide their own controller.\n *\n * Unallocated regions of the address space contain a special memory block of type NONE that contains\n * no storage. Mapping every addressible location to a memory block allows all accesses to be routed in\n * exactly the same manner, without resorting to any range or processor checks.\n *\n * These types are not mutually exclusive. For example, VIDEO memory could be allocated as RAM, with or\n * without a custom controller (the original Monochrome and CGA video cards used read/write storage that\n * was indistinguishable from RAM), and CTRL memory could be allocated as an empty block of any type, with\n * a custom controller. A few types are required for certain features (eg, ROM is required if you want\n * read-only memory), but the larger purpose of these types is to help document the caller's intent and to\n * provide the Control Panel with the ability to highlight memory regions accordingly.\n */\nMemory8080.TYPE = {\n NONE: 0,\n RAM: 1,\n ROM: 2,\n VIDEO: 3,\n CTRL: 4,\n COLORS: [\"black\", \"blue\", \"green\", \"cyan\"],\n NAMES: [\"NONE\", \"RAM\", \"ROM\", \"VID\", \"H/W\"]\n};\n\n/*\n * Last used block ID (used for debugging only)\n */\nMemory8080.idBlock = 0;\n\n\n/*\n * This is the effective definition of afnNone, but we need not fully define it, because setAccess()\n * uses these defaults when any of the 4 handlers (ie, 2 byte handlers and 2 short handlers) are undefined.\n *\nMemory8080.afnNone = [\n Memory8080.prototype.readNone,\n Memory8080.prototype.writeNone,\n Memory8080.prototype.readShortDefault,\n Memory8080.prototype.writeShortDefault\n];\n */\nMemory8080.afnNone = [];\n\nMemory8080.afnMemory = [\n Memory8080.prototype.readByteMemory,\n Memory8080.prototype.writeByteMemory,\n Memory8080.prototype.readShortMemory,\n Memory8080.prototype.writeShortMemory\n];\n\nMemory8080.afnChecked = [\n Memory8080.prototype.readByteChecked,\n Memory8080.prototype.writeByteChecked,\n Memory8080.prototype.readShortChecked,\n Memory8080.prototype.writeShortChecked\n];\n\nif (TYPEDARRAYS) {\n Memory8080.afnArrayBE = [\n Memory8080.prototype.readByteBE,\n Memory8080.prototype.writeByteBE,\n Memory8080.prototype.readShortBE,\n Memory8080.prototype.writeShortBE\n ];\n\n Memory8080.afnArrayLE = [\n Memory8080.prototype.readByteLE,\n Memory8080.prototype.writeByteLE,\n Memory8080.prototype.readShortLE,\n Memory8080.prototype.writeShortLE\n ];\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/cpu.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass CPU8080 extends Component {\n /**\n * CPU8080(parmsCPU, nCyclesDefault)\n *\n * The CPU8080 class supports the following (parmsCPU) properties:\n *\n * cycles: the machine's base cycles per second; the CPUState8080 constructor\n * will provide us with a default (based on the CPU model) to use as a fallback.\n *\n * multiplier: base cycle multiplier; default is 1.\n *\n * autoStart: true to automatically start, false to not, or null if \"it depends\";\n * null is the default, which means do not autostart UNLESS there is no Debugger\n * and no \"Run\" button (ie, no way to manually start the machine).\n *\n * csStart: the number of cycles that runCPU() must wait before generating\n * checksum records; -1 if disabled. checksum records are a diagnostic aid\n * used to help compare one CPU run to another.\n *\n * csInterval: the number of cycles that runCPU() must execute before generating\n * a checksum record; -1 if disabled.\n *\n * csStop: the number of cycles to stop generating checksum records.\n *\n * This component is primarily responsible for interfacing the CPU with the outside\n * world (eg, Panel and Debugger components), and managing overall CPU operation.\n *\n * It is extended by the CPUState8080 component, where the simulation control logic resides.\n *\n * @this {CPU8080}\n * @param {Object} parmsCPU\n * @param {number} nCyclesDefault\n */\n constructor(parmsCPU, nCyclesDefault)\n {\n super(\"CPU\", parmsCPU, Messages8080.CPU);\n\n var nCycles = parmsCPU['cycles'] || nCyclesDefault;\n\n var nMultiplier = parmsCPU['multiplier'] || 1;\n\n this.nCyclesPerSecond = nCycles;\n\n /*\n * nCyclesMultiplier replaces the old \"speed\" variable (0, 1, 2) and eliminates the need for\n * the constants (SPEED_SLOW, SPEED_FAST and SPEED_MAX). The UI simply doubles the multiplier\n * until we've exceeded the host's speed limit and then starts the multiplier over at 1.\n */\n this.nCyclesMultiplier = nMultiplier;\n this.mhzDefault = Math.round(this.nCyclesPerSecond / 10000) / 100;\n /*\n * TODO: Take care of this with an initial setSpeed() call instead?\n */\n this.mhzTarget = this.mhzDefault * this.nCyclesMultiplier;\n\n /*\n * We add a number of flags to the set initialized by Component\n */\n this.flags.running = false;\n this.flags.starting = false;\n this.flags.autoStart = parmsCPU['autoStart'];\n\n /*\n * TODO: Add some UI for fDisplayLiveRegs (either an XML property, or a UI checkbox, or both)\n */\n this.flags.displayLiveRegs = false;\n\n /*\n * Get checksum parameters, if any. runCPU() behavior is not affected until fChecksum\n * is true, which won't happen until resetChecksum() is called with nCyclesChecksumInterval\n * (\"csInterval\") set to a positive value.\n *\n * As above, any of these parameters can also be set with the Debugger's execution options\n * command (\"x\"); for example, \"x cs int 5000\" will set nCyclesChecksumInterval to 5000\n * and call resetChecksum().\n */\n this.flags.checksum = false;\n this.nChecksum = this.nCyclesChecksumNext = 0;\n this.nCyclesChecksumStart = parmsCPU[\"csStart\"];\n this.nCyclesChecksumInterval = parmsCPU[\"csInterval\"];\n this.nCyclesChecksumStop = parmsCPU[\"csStop\"];\n\n /*\n * Array of countdown timers managed by addTimer() and setTimer().\n */\n this.aTimers = [];\n\n this.onRunTimeout = this.runCPU.bind(this); // function onRunTimeout() { cpu.runCPU(); };\n\n this.setReady();\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {CPU8080}\n * @param {Computer8080} cmp\n * @param {Bus8080} bus\n * @param {CPU8080} cpu\n * @param {Debugger8080} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.dbg = dbg;\n\n for (var i = 0; i < CPU8080.BUTTONS.length; i++) {\n var control = this.bindings[CPU8080.BUTTONS[i]];\n if (control) this.cmp.setBinding(\"\", CPU8080.BUTTONS[i], control);\n }\n\n /*\n * Attach the ChipSet component to the CPU so that it can be notified whenever the CPU stops and starts.\n */\n this.chipset = /** @type {ChipSet8080} */ (cmp.getMachineComponent(\"ChipSet\"));\n\n /*\n * We've already saved the parmsCPU 'autoStart' setting, but there may be a machine (or URL) override.\n */\n var sAutoStart = cmp.getMachineParm('autoStart');\n if (sAutoStart != null) {\n this.flags.autoStart = (sAutoStart == \"true\"? true : (sAutoStart == \"false\"? false : !!sAutoStart));\n }\n\n this.setReady();\n }\n\n /**\n * reset()\n *\n * @this {CPU8080}\n */\n reset()\n {\n }\n\n /**\n * save()\n *\n * This is a placeholder for save support (overridden by the CPUState8080 component).\n *\n * @this {CPU8080}\n * @return {Object|null}\n */\n save()\n {\n return null;\n }\n\n /**\n * restore(data)\n *\n * This is a placeholder for restore support (overridden by the CPUState8080 component).\n *\n * @this {CPU8080}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n return false;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {CPU8080}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data || !this.restore) {\n this.reset();\n } else {\n this.resetCycles();\n if (!this.restore(data)) return false;\n this.resetChecksum();\n }\n /*\n * Give the Debugger a chance to do/print something once we've powered up\n */\n if (DEBUGGER && this.dbg) {\n this.dbg.init();\n } else {\n this.println(\"No debugger detected\");\n }\n }\n /*\n * The Computer component (which is responsible for all powerDown and powerUp notifications)\n * is now responsible for managing a component's fPowered flag, not us.\n *\n * this.flags.powered = true;\n */\n this.updateCPU();\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {CPU8080}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n /*\n * The Computer component (which is responsible for all powerDown and powerUp notifications)\n * is now responsible for managing a component's fPowered flag, not us.\n *\n * this.flags.powered = false;\n */\n return fSave? this.save() : true;\n }\n\n /**\n * autoStart()\n *\n * @this {CPU8080}\n * @return {boolean} true if started, false if not\n */\n autoStart()\n {\n /*\n * Start running automatically on power-up, assuming there's no Debugger and no \"Run\" button\n */\n if (this.flags.autoStart || (!DEBUGGER || !this.dbg) && this.bindings[\"run\"] === undefined) {\n /*\n * We used to also set fUpdateFocus when calling runCPU(), on the assumption that in the \"auto-starting\"\n * context, a machine without focus is like a day without sunshine, but in reality, focus should only be\n * forced when the user takes some other machine-related action.\n */\n this.runCPU();\n return true;\n }\n return false;\n }\n\n /**\n * isPowered()\n *\n * @this {CPU8080}\n * @return {boolean}\n */\n isPowered()\n {\n if (!this.flags.powered) {\n this.println(this.toString() + \" not powered\");\n return false;\n }\n return true;\n }\n\n /**\n * isRunning()\n *\n * @this {CPU8080}\n * @return {boolean}\n */\n isRunning()\n {\n return this.flags.running;\n }\n\n /**\n * getChecksum()\n *\n * This will be implemented by the CPUState8080 component.\n *\n * @this {CPU8080}\n * @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code)\n */\n getChecksum()\n {\n return 0;\n }\n\n /**\n * resetChecksum()\n *\n * If checksum generation is enabled (fChecksum is true), this resets the running 32-bit checksum and the\n * cycle counter that will trigger the next displayChecksum(); called by resetCycles(), which is called whenever\n * the CPU is reset or restored.\n *\n * @this {CPU8080}\n * @return {boolean} true if checksum generation enabled, false if not\n */\n resetChecksum()\n {\n if (this.nCyclesChecksumStart === undefined) this.nCyclesChecksumStart = 0;\n if (this.nCyclesChecksumInterval === undefined) this.nCyclesChecksumInterval = -1;\n if (this.nCyclesChecksumStop === undefined) this.nCyclesChecksumStop = -1;\n this.flags.checksum = (this.nCyclesChecksumStart >= 0 && this.nCyclesChecksumInterval > 0);\n if (this.flags.checksum) {\n this.nChecksum = 0;\n this.nCyclesChecksumNext = this.nCyclesChecksumStart - this.nTotalCycles;\n /*\n * this.nCyclesChecksumNext = this.nCyclesChecksumStart + this.nCyclesChecksumInterval -\n * (this.nTotalCycles % this.nCyclesChecksumInterval);\n */\n return true;\n }\n return false;\n }\n\n /**\n * updateChecksum(nCycles)\n *\n * When checksum generation is enabled (fChecksum is true), runCPU() asks stepCPU() to execute a minimum\n * number of cycles (1), effectively limiting execution to a single instruction, and then we're called with\n * the exact number cycles that were actually executed. This should give us instruction-granular checksums\n * at precise intervals that are 100% repeatable.\n *\n * @this {CPU8080}\n * @param {number} nCycles\n */\n updateChecksum(nCycles)\n {\n if (this.flags.checksum) {\n /*\n * Get a 32-bit summation of the current CPU state and add it to our running 32-bit checksum\n */\n var fDisplay = false;\n this.nChecksum = (this.nChecksum + this.getChecksum())|0;\n this.nCyclesChecksumNext -= nCycles;\n if (this.nCyclesChecksumNext <= 0) {\n this.nCyclesChecksumNext += this.nCyclesChecksumInterval;\n fDisplay = true;\n }\n if (this.nCyclesChecksumStop >= 0) {\n if (this.nCyclesChecksumStop <= this.getCycles()) {\n this.nCyclesChecksumInterval = this.nCyclesChecksumStop = -1;\n this.resetChecksum();\n this.stopCPU();\n fDisplay = true;\n }\n }\n if (fDisplay) this.displayChecksum();\n }\n }\n\n /**\n * displayChecksum()\n *\n * When checksum generation is enabled (fChecksum is true), this is called to provide a crude log of all\n * checksums generated at the specified cycle intervals, as specified by the \"csStart\" and \"csInterval\" parmsCPU\n * properties).\n *\n * @this {CPU8080}\n */\n displayChecksum()\n {\n this.println(this.getCycles() + \" cycles: \" + \"checksum=\" + Str.toHex(this.nChecksum));\n }\n\n /**\n * displayValue(sLabel, nValue, cch)\n *\n * This is principally for displaying register values, but in reality, it can be used to display any\n * numeric (hex) value bound to the given label.\n *\n * @this {CPU8080}\n * @param {string} sLabel\n * @param {number} nValue\n * @param {number} cch\n */\n displayValue(sLabel, nValue, cch)\n {\n if (this.bindings[sLabel]) {\n if (nValue === undefined) {\n this.setError(\"Value for \" + sLabel + \" is invalid\");\n this.stopCPU();\n }\n var sVal;\n if (!this.flags.running || this.flags.displayLiveRegs) {\n sVal = Str.toHex(nValue, cch);\n } else {\n sVal = \"--------\".substr(0, cch);\n }\n /*\n * TODO: Determine if this test actually avoids any redrawing when a register hasn't changed, and/or if\n * we should maintain our own (numeric) cache of displayed register values (to avoid creating these temporary\n * string values that will have to garbage-collected), and/or if this is actually slower, and/or if I'm being\n * too obsessive.\n */\n if (this.bindings[sLabel].textContent != sVal) this.bindings[sLabel].textContent = sVal;\n }\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {CPU8080}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"run\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var cpu = this;\n var fBound = false;\n\n switch (sBinding) {\n case \"power\":\n case \"reset\":\n /*\n * The \"power\" and \"reset\" buttons are functions of the entire computer, not just the CPU,\n * but it's not always convenient to stick a power button in the Computer component definition,\n * so we record those bindings here and pass them on to the Computer component in initBus().\n */\n this.bindings[sBinding] = control;\n fBound = true;\n break;\n\n case \"run\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickRun() {\n if (!cpu.cmp || !cpu.cmp.checkPower()) return;\n /*\n * We no longer pass true to these runCPU()/stopCPU() calls, on the theory that if the \"run\"\n * control is visible, then the computer is probably sufficiently visible as well; the problem\n * with setting fUpdateFocus to true is that it can jerk the web page around in annoying ways.\n */\n if (!cpu.flags.running)\n cpu.runCPU();\n else\n cpu.stopCPU();\n };\n fBound = true;\n break;\n\n case \"speed\":\n this.bindings[sBinding] = control;\n fBound = true;\n break;\n\n case \"setSpeed\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickSetSpeed() {\n cpu.setSpeed(cpu.nCyclesMultiplier << 1, true);\n };\n control.textContent = this.getSpeedTarget();\n fBound = true;\n break;\n\n default:\n break;\n }\n return fBound;\n }\n\n /**\n * setBurstCycles(nCycles)\n *\n * This function is used by the ChipSet component whenever a very low timer count is set,\n * in anticipation of the timer requiring an update sooner than the normal nCyclesPerYield\n * period in runCPU() would normally provide.\n *\n * NOTE: In this context, \"timer\" refers to a timer chip (eg, an Intel 8253) being emulated by\n * by the ChipSet component, not the timers managed by the CPU (eg, addTimer(), setTimer(), etc).\n *\n * @this {CPU8080}\n * @param {number} nCycles is the target number of cycles to drop the current burst to\n * @return {boolean}\n */\n setBurstCycles(nCycles)\n {\n if (this.flags.running) {\n var nDelta = this.nStepCycles - nCycles;\n /*\n * NOTE: If nDelta is negative, we will actually be increasing nStepCycles and nBurstCycles.\n * Which is OK, but if we're also taking snapshots of the cycle counts, to make sure that instruction\n * costs are being properly assessed, then we need to update nSnapCycles as well.\n *\n * TODO: If the delta is negative, we could simply ignore the request, but we must first carefully\n * consider the impact on the ChipSet timers, if any.\n */\n // if (DEBUG) this.nSnapCycles -= nDelta;\n this.nStepCycles -= nDelta;\n this.nBurstCycles -= nDelta;\n return true;\n }\n return false;\n }\n\n /**\n * addCycles(nCycles, fEndStep)\n *\n * @this {CPU8080}\n * @param {number} nCycles\n * @param {boolean} [fEndStep]\n */\n addCycles(nCycles, fEndStep)\n {\n this.nTotalCycles += nCycles;\n if (fEndStep) {\n this.nBurstCycles = this.nStepCycles = 0;\n }\n }\n\n /**\n * calcCycles(fRecalc)\n *\n * Calculate the number of cycles to process for each \"burst\" of CPU activity. The size of a burst\n * is driven by YIELDS_PER_SECOND (eg, 30).\n *\n * At the end of each burst, we subtract burst cycles from the yield cycle \"threshold\" counter.\n * Whenever the \"next yield\" cycle counter goes to (or below) zero, we compare elapsed time to the time\n * we expected the virtual hardware to take (eg, 1000ms/50 or 20ms), and if we still have time remaining,\n * we sleep the remaining time (or 0ms if there's no remaining time), and then restart runCPU().\n *\n * @this {CPU8080}\n * @param {boolean} [fRecalc] is true if the caller wants to recalculate thresholds based on the most recent\n * speed calculation (see calcSpeed).\n */\n calcCycles(fRecalc)\n {\n /*\n * Calculate \"per\" yield values.\n */\n var vMultiplier = 1;\n if (fRecalc) {\n if (this.nCyclesMultiplier > 1 && this.mhz) {\n vMultiplier = (this.mhz / this.mhzDefault);\n }\n }\n\n this.msPerYield = Math.round(1000 / CPU8080.YIELDS_PER_SECOND);\n this.nCyclesPerYield = Math.floor(this.nCyclesPerSecond / CPU8080.YIELDS_PER_SECOND * vMultiplier);\n\n /*\n * And initialize \"next\" yield values to the \"per\" values.\n */\n if (!fRecalc) {\n this.nCyclesNextYield = this.nCyclesPerYield;\n }\n this.nCyclesRecalc = 0;\n }\n\n /**\n * getCycles(fScaled)\n *\n * getCycles() returns the number of cycles executed so far. Note that we can be called after\n * runCPU() OR during runCPU(), perhaps from a handler triggered during the current run's stepCPU(),\n * so nRunCycles must always be adjusted by number of cycles stepCPU() was asked to run (nBurstCycles),\n * less the number of cycles it has yet to run (nStepCycles).\n *\n * nRunCycles is zeroed whenever the CPU is halted or the CPU speed is changed, which is why we also\n * have nTotalCycles, which accumulates all nRunCycles before we zero it. However, nRunCycles and\n * nTotalCycles eventually get reset by calcSpeed(), to avoid overflow, so components that rely on\n * getCycles() returning steadily increasing values should also be prepared for a reset at any time.\n *\n * @this {CPU8080}\n * @param {boolean} [fScaled] is true if the caller wants a cycle count relative to a multiplier of 1\n * @return {number}\n */\n getCycles(fScaled)\n {\n var nCycles = this.nTotalCycles + this.nRunCycles + this.nBurstCycles - this.nStepCycles;\n if (fScaled && this.nCyclesMultiplier > 1 && this.mhz > this.mhzDefault) {\n /*\n * We could scale the current cycle count by the current effective speed (this.mhz); eg:\n *\n * nCycles = Math.round(nCycles / (this.mhz / this.mhzDefault));\n *\n * but that speed will fluctuate somewhat: large fluctuations at first, but increasingly smaller\n * fluctuations after each burst of instructions that runCPU() executes.\n *\n * Alternatively, we can scale the cycle count by the multiplier, which is good in that the\n * multiplier doesn't vary once the user changes it, but a potential downside is that the\n * multiplier might be set too high, resulting in a target speed that's higher than the effective\n * speed is able to reach.\n *\n * Also, if multipliers were always limited to a power-of-two, then this could be calculated\n * with a simple shift. However, only the \"setSpeed\" UI binding limits it that way; the Debugger\n * interface allows any value, as does the CPU \"multiplier\" parmsCPU property (from the machine's\n * XML file).\n */\n nCycles = Math.round(nCycles / this.nCyclesMultiplier);\n }\n return nCycles;\n }\n\n /**\n * getCyclesPerSecond()\n *\n * This returns the CPU's \"base\" speed (ie, the original cycles per second defined for the machine)\n *\n * @this {CPU8080}\n * @return {number}\n */\n getCyclesPerSecond()\n {\n return this.nCyclesPerSecond;\n }\n\n /**\n * resetCycles()\n *\n * Resets speed and cycle information as part of any reset() or restore(); this typically occurs during powerUp().\n * It's important that this be called BEFORE the actual restore() call, because restore() may want to call setSpeed(),\n * which in turn assumes that all the cycle counts have been initialized to sensible values.\n *\n * @this {CPU8080}\n */\n resetCycles()\n {\n this.mhz = 0;\n this.nYieldsSinceStatusUpdate = 0;\n this.nTotalCycles = this.nRunCycles = this.nBurstCycles = this.nStepCycles = 0;\n this.resetChecksum();\n this.setSpeed(1);\n }\n\n /**\n * getSpeed()\n *\n * @this {CPU8080}\n * @return {number} the current speed multiplier\n */\n getSpeed()\n {\n return this.nCyclesMultiplier;\n }\n\n /**\n * getSpeedCurrent()\n *\n * @this {CPU8080}\n * @return {string} the current speed, in mhz, as a string formatted to two decimal places\n */\n getSpeedCurrent()\n {\n /*\n * TODO: Has toFixed() been \"fixed\" in all browsers (eg, IE) to return a rounded value now?\n */\n return ((this.flags.running && this.mhz)? (this.mhz.toFixed(2) + \"Mhz\") : \"Stopped\");\n }\n\n /**\n * getSpeedTarget()\n *\n * @this {CPU8080}\n * @return {string} the target speed, in mhz, as a string formatted to two decimal places\n */\n getSpeedTarget()\n {\n /*\n * TODO: Has toFixed() been \"fixed\" in all browsers (eg, IE) to return a rounded value now?\n */\n return this.mhzTarget.toFixed(2) + \"Mhz\";\n }\n\n /**\n * setSpeed(nMultiplier, fUpdateFocus)\n *\n * NOTE: This used to return the target speed, in mhz, but no callers appear to care at this point.\n *\n * @desc Whenever the speed is changed, the running cycle count and corresponding start time must be reset,\n * so that the next effective speed calculation obtains sensible results. In fact, when runCPU() initially calls\n * setSpeed() with no parameters, that's all this function does (it doesn't change the current speed setting).\n *\n * @this {CPU8080}\n * @param {number} [nMultiplier] is the new proposed multiplier (reverts to 1 if the target was too high)\n * @param {boolean} [fUpdateFocus] is true to update Computer focus\n * @return {boolean} true if successful, false if not\n */\n setSpeed(nMultiplier, fUpdateFocus)\n {\n var fSuccess = false;\n if (nMultiplier !== undefined) {\n /*\n * If we haven't reached 80% (0.8) of the current target speed, revert to a multiplier of one (1).\n */\n if (this.mhz / this.mhzTarget < 0.8) {\n nMultiplier = 1;\n } else {\n fSuccess = true;\n }\n this.nCyclesMultiplier = nMultiplier;\n var mhz = this.mhzDefault * this.nCyclesMultiplier;\n if (this.mhzTarget != mhz) {\n this.mhzTarget = mhz;\n var sSpeed = this.getSpeedTarget();\n var controlSpeed = this.bindings[\"setSpeed\"];\n if (controlSpeed) controlSpeed.textContent = sSpeed;\n this.println(\"target speed: \" + sSpeed);\n }\n if (fUpdateFocus && this.cmp) this.cmp.updateFocus();\n }\n this.addCycles(this.nRunCycles);\n this.nRunCycles = 0;\n this.msStartRun = Component.getTime();\n this.msEndThisRun = 0;\n this.calcCycles();\n return fSuccess;\n }\n\n /**\n * calcSpeed(nCycles, msElapsed)\n *\n * @this {CPU8080}\n * @param {number} nCycles\n * @param {number} msElapsed\n */\n calcSpeed(nCycles, msElapsed)\n {\n if (msElapsed) {\n this.mhz = Math.round(nCycles / (msElapsed * 10)) / 100;\n if (msElapsed >= 86400000) {\n this.nTotalCycles = 0;\n this.setSpeed(); // reset all counters once per day so that we never have to worry about overflow\n }\n }\n }\n\n /**\n * calcStartTime()\n *\n * @this {CPU8080}\n */\n calcStartTime()\n {\n if (this.nCyclesRecalc >= this.nCyclesPerSecond) {\n this.calcCycles(true);\n }\n this.nCyclesThisRun = 0;\n this.msStartThisRun = Component.getTime();\n\n /*\n * Try to detect situations where the browser may have throttled us, such as when the user switches\n * to a different tab; in those situations, Chrome and Safari may restrict setTimeout() callbacks\n * to roughly one per second.\n *\n * Another scenario: the user resizes the browser window. setTimeout() callbacks are not throttled,\n * but there can still be enough of a lag between the callbacks that CPU speed will be noticeably\n * erratic if we don't compensate for it here.\n *\n * We can detect throttling/lagging by verifying that msEndThisRun (which was set at the end of the\n * previous run and includes any requested sleep time) is comparable to the current msStartThisRun;\n * if the delta is significant, we compensate by bumping msStartRun forward by that delta.\n *\n * This shouldn't be triggered when the Debugger halts the CPU, because setSpeed() -- which is called\n * whenever the CPU starts running again -- zeroes msEndThisRun.\n *\n * This also won't do anything about other internal delays; for example, Debugger message() calls.\n * By the time the message() function has called yieldCPU(), the cost of the message has already been\n * incurred, so it will be end up being charged against the instruction(s) that triggered it.\n *\n * TODO: Consider calling yieldCPU() sooner from message(), so that it can arrange for the msEndThisRun\n * \"snapshot\" to occur sooner; it's unclear, however, whether that will really improve the CPU's ability\n * to hit its target speed, since you would expect any instruction that displays a message to be an\n * EXTREMELY slow instruction.\n */\n if (this.msEndThisRun) {\n var msDelta = this.msStartThisRun - this.msEndThisRun;\n if (msDelta > this.msPerYield) {\n if (MAXDEBUG) this.println(\"large time delay: \" + msDelta + \"ms\");\n this.msStartRun += msDelta;\n /*\n * Bumping msStartRun forward should NEVER cause it to exceed msStartThisRun; however, just\n * in case, I make absolutely sure it cannot happen, since doing so could result in negative\n * speed calculations.\n */\n\n if (this.msStartRun > this.msStartThisRun) {\n this.msStartRun = this.msStartThisRun;\n }\n }\n }\n }\n\n /**\n * calcRemainingTime()\n *\n * @this {CPU8080}\n * @return {number}\n */\n calcRemainingTime()\n {\n this.msEndThisRun = Component.getTime();\n\n var msYield = this.msPerYield;\n if (this.nCyclesThisRun) {\n /*\n * Normally, we would assume we executed a full quota of work over msPerYield, but since the CPU\n * now has the option of calling yieldCPU(), that might not be true. If nCyclesThisRun is correct, then\n * the ratio of nCyclesThisRun/nCyclesPerYield should represent the percentage of work we performed,\n * and so applying that percentage to msPerYield should give us a better estimate of work vs. time.\n */\n msYield = Math.round(msYield * this.nCyclesThisRun / this.nCyclesPerYield);\n }\n\n var msElapsedThisRun = this.msEndThisRun - this.msStartThisRun;\n var msRemainsThisRun = msYield - msElapsedThisRun;\n\n /*\n * We could pass only \"this run\" results to calcSpeed():\n *\n * nCycles = this.nCyclesThisRun;\n * msElapsed = msElapsedThisRun;\n *\n * but it seems preferable to use longer time periods and hopefully get a more accurate speed.\n *\n * Also, if msRemainsThisRun >= 0 && this.nCyclesMultiplier == 1, we could pass these results instead:\n *\n * nCycles = this.nCyclesThisRun;\n * msElapsed = this.msPerYield;\n *\n * to insure that we display a smooth, constant N Mhz. But for now, I prefer seeing any fluctuations.\n */\n var nCycles = this.nRunCycles;\n var msElapsed = this.msEndThisRun - this.msStartRun;\n\n if (MAXDEBUG && msRemainsThisRun < 0 && this.nCyclesMultiplier > 1) {\n this.println(\"warning: updates @\" + msElapsedThisRun + \"ms (prefer \" + Math.round(msYield) + \"ms)\");\n }\n\n this.calcSpeed(nCycles, msElapsed);\n\n if (msRemainsThisRun < 0 || this.mhz < this.mhzTarget) {\n /*\n * Try \"throwing out\" the effects of large anomalies, by moving the overall run start time up;\n * ordinarily, this should only happen when the someone is using an external Debugger or some other\n * tool or feature that is interfering with our overall execution.\n */\n if (msRemainsThisRun < -1000) {\n this.msStartRun -= msRemainsThisRun;\n }\n /*\n * If the last burst took MORE time than we allotted (ie, it's taking more than 1 second to simulate\n * nCyclesPerSecond), all we can do is yield for as little time as possible (ie, 0ms) and hope that the\n * simulation is at least usable.\n */\n msRemainsThisRun = 0;\n }\n\n /*\n * Last but not least, update nCyclesRecalc, so that when runCPU() starts up again and calls calcStartTime(),\n * it'll be ready to decide if calcCycles() should be called again.\n */\n this.nCyclesRecalc += this.nCyclesThisRun;\n\n if (DEBUG && this.messageEnabled(Messages8080.CPU) && msRemainsThisRun) {\n this.printMessage(\"calcRemainingTime: \" + msRemainsThisRun + \"ms to sleep after \" + this.msEndThisRun + \"ms\");\n }\n\n this.msEndThisRun += msRemainsThisRun;\n return msRemainsThisRun;\n }\n\n /**\n * addTimer(id, callBack, ms)\n *\n * Components that want to have timers that fire after some number of milliseconds call addTimer() to create\n * the timer, and then setTimer() when they want to arm it. Alternatively, they can specify an automatic timeout\n * value (in milliseconds) to have the timer fire automatically at regular intervals. There is currently\n * no removeTimer() because these are generally used for the entire lifetime of a component.\n *\n * Internally, each timer entry is a preallocated Array with the following entries:\n *\n * [0]: timer ID\n * [1]: countdown value, in cycles\n * [2]: automatic setTimer value, if any, in milliseconds\n * [3]: callback function\n *\n * A timer is initially dormant; dormant timers have a countdown value of -1 (although any negative number\n * will suffice) and active timers have a non-negative value.\n *\n * Why not use JavaScript's setTimeout() instead? Good question. For a good answer, see setTimer() below.\n *\n * @this {CPU8080}\n * @param {string} id\n * @param {function()} callBack\n * @param {number} [ms] (if set, enables automatic setTimer calls)\n * @return {number} timer index\n */\n addTimer(id, callBack, ms = -1)\n {\n var iTimer = this.aTimers.length;\n this.aTimers.push([id, -1, ms, callBack]);\n if (ms >= 0) this.setTimer(iTimer, ms);\n return iTimer;\n }\n\n /**\n * findTimer(id)\n *\n * @this {CPU8080}\n * @param {string} id\n * @return {Array|null}\n */\n findTimer(id)\n {\n for (var iTimer = 0; iTimer < this.aTimers.length; iTimer++) {\n var timer = this.aTimers[iTimer];\n if (timer[0] == id) return timer;\n }\n return null;\n }\n\n /**\n * setTimer(iTimer, ms, fReset)\n *\n * Using the timer index from a previous addTimer() call, this sets that timer to fire after the\n * specified number of milliseconds.\n *\n * This is preferred over JavaScript's setTimeout(), because all our timers are effectively paused when\n * the CPU is paused (eg, when the Debugger halts execution). Moreover, setTimeout() handlers only run after\n * runCPU() yields, which is far too granular for some components (eg, when the SerialPort tries to simulate\n * interrupts at 9600 baud).\n *\n * Ideally, the only function that would use setTimeout() is runCPU(), while the rest of the components\n * use setTimer(); however, due to legacy code (ie, code that predates these functions) and/or laziness,\n * that's currently not the case. TODO: Fix.\n *\n * @this {CPU8080}\n * @param {number} iTimer\n * @param {number} ms (converted into a cycle countdown internally)\n * @param {boolean} [fReset] (true if the timer should be reset even if already armed)\n * @return {number} (number of cycles used to arm timer, or -1 if error)\n */\n setTimer(iTimer, ms, fReset)\n {\n var nCycles = -1;\n if (iTimer >= 0 && iTimer < this.aTimers.length) {\n var timer = this.aTimers[iTimer];\n if (fReset || timer[1] < 0) {\n nCycles = this.getMSCycles(ms);\n /*\n * If the CPU is currently executing a burst of cycles, the number of cycles it has executed in\n * that burst so far must NOT be charged against the cycle timeout we're about to set. The simplest\n * way to resolve that is to immediately call endBurst() and bias the cycle timeout by the number\n * of cycles that the burst executed.\n */\n if (this.flags.running) {\n nCycles += this.endBurst();\n }\n timer[1] = nCycles;\n }\n }\n return nCycles;\n }\n\n /**\n * getMSCycles(ms)\n *\n * @this {CPU8080}\n * @param {number} ms\n * @return {number} number of corresponding cycles\n */\n getMSCycles(ms)\n {\n return ((this.nCyclesPerSecond * this.nCyclesMultiplier) / 1000 * ms)|0;\n }\n\n /**\n * getBurstCycles(nCycles)\n *\n * Used by runCPU() to get min(nCycles,[timer cycle counts])\n *\n * @this {CPU8080}\n * @param {number} nCycles (number of cycles about to execute)\n * @return {number} (either nCycles or less if a timer needs to fire)\n */\n getBurstCycles(nCycles)\n {\n for (var iTimer = this.aTimers.length - 1; iTimer >= 0; iTimer--) {\n var timer = this.aTimers[iTimer];\n\n if (timer[1] < 0) continue;\n if (nCycles > timer[1]) {\n nCycles = timer[1];\n }\n }\n return nCycles;\n }\n\n /**\n * updateTimers(nCycles)\n *\n * Used by runCPU() to reduce all active timer countdown values by the number of cycles just executed;\n * this is the function that actually \"fires\" any timer(s) whose countdown has reached (or dropped below)\n * zero, invoking their callback function.\n *\n * @this {CPU8080}\n * @param {number} nCycles (number of cycles actually executed)\n */\n updateTimers(nCycles)\n {\n for (var iTimer = this.aTimers.length - 1; iTimer >= 0; iTimer--) {\n var timer = this.aTimers[iTimer];\n\n if (timer[1] < 0) continue;\n timer[1] -= nCycles;\n if (timer[1] <= 0) {\n if (DEBUG && this.messageEnabled(Messages8080.CPU)) {\n this.printMessage(\"updateTimer(\" + nCycles + \"): firing \" + timer[0] + \" with only \" + (timer[1] + nCycles) + \" cycles left\");\n }\n timer[1] = -1; // zero is technically an \"active\" value, so ensure the timer is dormant now\n timer[3](); // safe to invoke the callback function now\n if (timer[2] >= 0) {\n this.setTimer(iTimer, timer[2]);\n if (DEBUG && this.messageEnabled(Messages8080.CPU)) {\n this.printMessage(\"updateTimer(\" + nCycles + \"): rearming \" + timer[0] + \" for \" + timer[2] + \"ms (\" + timer[1] + \" cycles)\");\n }\n }\n }\n }\n }\n\n /**\n * endBurst(fReset)\n *\n * @this {CPU8080}\n * @param {boolean} [fReset]\n * @return {number} (number of cycles executed in the most recent burst)\n */\n endBurst(fReset)\n {\n var nCycles = this.nBurstCycles -= this.nStepCycles;\n this.nStepCycles = 0;\n if (fReset) this.nBurstCycles = 0;\n return nCycles;\n }\n\n /**\n * runCPU(fUpdateFocus)\n *\n * @this {CPU8080}\n * @param {boolean} [fUpdateFocus] is true to update Computer focus\n */\n runCPU(fUpdateFocus)\n {\n if (!this.setBusy(true)) {\n this.updateCPU();\n if (this.cmp) this.cmp.stop(Component.getTime(), this.getCycles());\n return;\n }\n\n this.startCPU(fUpdateFocus);\n\n /*\n * calcStartTime() initializes the cycle counter and timestamp for this runCPU() invocation, and optionally\n * recalculates the the maximum number of cycles for each burst if the nCyclesRecalc threshold has been reached.\n */\n this.calcStartTime();\n\n try {\n do {\n /*\n * nCycles is how many cycles we WANT to run on each iteration of stepCPU(), and may be as\n * HIGH as nCyclesPerYield, but it may be significantly less. getBurstCycles() will adjust\n * nCycles downward if any CPU timers need to fire during the next burst.\n */\n var nCycles = this.getBurstCycles(this.flags.checksum? 1 : this.nCyclesPerYield);\n\n /*\n * Execute the burst.\n */\n this.stepCPU(nCycles);\n\n /*\n * Terminate the burst, returning the number of cycles that stepCPU() actually ran.\n */\n nCycles = this.endBurst(true);\n\n /*\n * Add nCycles to nCyclesThisRun, as well as nRunCycles (the cycle count since the CPU first started).\n */\n this.nCyclesThisRun += nCycles;\n this.nRunCycles += nCycles;\n this.updateChecksum(nCycles);\n\n /*\n * Update any/all timers, firing those whose cycle countdowns have reached (or dropped below) zero.\n */\n this.updateTimers(nCycles);\n\n this.nCyclesNextYield -= nCycles;\n if (this.nCyclesNextYield <= 0) {\n this.nCyclesNextYield += this.nCyclesPerYield;\n if (++this.nYieldsSinceStatusUpdate >= CPU8080.YIELDS_PER_STATUS) {\n if (this.cmp) this.cmp.updateStatus();\n this.nYieldsSinceStatusUpdate = 0;\n }\n break;\n }\n } while (this.flags.running);\n }\n catch (e) {\n this.stopCPU();\n this.updateCPU();\n if (this.cmp) this.cmp.stop(Component.getTime(), this.getCycles());\n this.setBusy(false);\n this.setError(e.stack || e.message);\n return;\n }\n\n setTimeout(this.onRunTimeout, this.calcRemainingTime());\n }\n\n /**\n * startCPU(fUpdateFocus)\n *\n * WARNING: Other components must use runCPU() to get the CPU running; this is a runCPU() helper function only.\n *\n * @param {boolean} [fUpdateFocus]\n */\n startCPU(fUpdateFocus)\n {\n if (!this.flags.running) {\n /*\n * setSpeed() without a speed parameter leaves the selected speed in place, but also resets the\n * cycle counter and timestamp for the current series of runCPU() calls, calculates the maximum number\n * of cycles for each burst based on the last known effective CPU speed, and resets the nCyclesRecalc\n * threshold counter.\n */\n this.setSpeed();\n if (this.cmp) this.cmp.start(this.msStartRun, this.getCycles());\n this.flags.running = true;\n this.flags.starting = true;\n if (this.chipset) this.chipset.start();\n var controlRun = this.bindings[\"run\"];\n if (controlRun) controlRun.textContent = \"Halt\";\n if (this.cmp) {\n this.cmp.updateStatus(true);\n if (fUpdateFocus) this.cmp.updateFocus(true);\n }\n }\n }\n\n /**\n * stepCPU(nMinCycles)\n *\n * This will be implemented by the CPUState8080 component.\n *\n * @this {CPU8080}\n * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored)\n * @return {number} of cycles executed; 0 indicates that the last instruction was not executed\n */\n stepCPU(nMinCycles)\n {\n return 0;\n }\n\n /**\n * stopCPU(fComplete)\n *\n * For use by any component that wants to stop the CPU.\n *\n * This similar to yieldCPU(), but it doesn't need to zero nCyclesNextYield to break out of runCPU();\n * it simply needs to clear fRunning (well, \"simply\" may be oversimplifying a bit....)\n *\n * @this {CPU8080}\n * @param {boolean} [fComplete]\n */\n stopCPU(fComplete)\n {\n this.isBusy(true);\n this.endBurst();\n this.addCycles(this.nRunCycles);\n this.nRunCycles = 0;\n if (this.flags.running) {\n this.flags.running = false;\n if (this.chipset) this.chipset.stop();\n var controlRun = this.bindings[\"run\"];\n if (controlRun) controlRun.textContent = \"Run\";\n }\n this.flags.complete = fComplete;\n }\n\n /**\n * updateCPU(fForce)\n *\n * This used to be performed at the end of every stepCPU(), but runCPU() -- which relies upon\n * stepCPU() -- needed to have more control over when these updates are performed. However, for\n * other callers of stepCPU(), such as the Debugger, the combination of stepCPU() + updateCPU()\n * provides the old behavior.\n *\n * @this {CPU8080}\n * @param {boolean} [fForce] (true to force a video update; used by the Debugger)\n */\n updateCPU(fForce)\n {\n if (this.cmp) {\n this.cmp.updateVideo(fForce);\n this.cmp.updateStatus(fForce);\n }\n }\n\n /**\n * yieldCPU()\n *\n * Similar to stopCPU() with regard to how it resets various cycle countdown values, but the CPU\n * remains in a \"running\" state.\n *\n * @this {CPU8080}\n */\n yieldCPU()\n {\n this.endBurst(); // this will break us out of stepCPU()\n this.nCyclesNextYield = 0; // this will break us out of runCPU(), once we break out of stepCPU()\n // if (DEBUG) this.nSnapCycles = this.nBurstCycles;\n /*\n * The Debugger calls yieldCPU() after every message() to ensure browser responsiveness, but it looks\n * odd for those messages to show CPU state changes but for the CPU's own status display to not (ditto\n * for the Video display), so I've added this call to try to keep things looking synchronized.\n */\n this.updateCPU();\n }\n}\n\n/*\n * Constants that control the frequency at which various updates should occur.\n *\n * These values do NOT control the simulation directly. Instead, they are used by\n * calcCycles(), which uses the nCyclesPerSecond passed to the constructor as a starting\n * point and computes the following variables:\n *\n * this.nCyclesPerYield: (this.nCyclesPerSecond / CPU8080.YIELDS_PER_SECOND)\n *\n * The above variables are also multiplied by any cycle multiplier in effect, via setSpeed(),\n * and then they're used to initialize another set of variables for each runCPU() iteration:\n *\n * this.nCyclesNextYield: this.nCyclesPerYield\n */\nCPU8080.YIELDS_PER_SECOND = 30; // just a gut feeling for the MINIMUM number of yields per second\nCPU8080.YIELDS_PER_STATUS = 15; // every 15 yields (ie, twice per second), perform CPU status updates\n\nCPU8080.BUTTONS = [\"power\", \"reset\"];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/cpustate.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass CPUState8080 extends CPU8080 {\n /**\n * CPUState8080(parmsCPU)\n *\n * The CPUState8080 class uses the following (parmsCPU) properties:\n *\n * model: a number (eg, 8080) that should match one of the CPUDef8080.MODEL_* values\n *\n * This extends the CPU class and passes any remaining parmsCPU properties to the CPU class\n * constructor, along with a default speed (cycles per second) based on the specified (or default)\n * CPU model number.\n *\n * The CPUState8080 class was initially written to simulate a 8080 microprocessor, although over time\n * it may evolved to support other microprocessors (eg, the Zilog Z80).\n *\n * @this {CPUState8080}\n * @param {Object} parmsCPU\n */\n constructor(parmsCPU)\n {\n var nCyclesDefault = 0;\n var model = +parmsCPU['model'] || CPUDef8080.MODEL_8080;\n\n switch(model) {\n case CPUDef8080.MODEL_8080:\n default:\n nCyclesDefault = 1000000;\n break;\n }\n\n super(parmsCPU, nCyclesDefault);\n\n this.model = model;\n\n /*\n * Initialize processor operation to match the requested model\n */\n this.initProcessor();\n\n /*\n * A variety of stepCPU() state variables that don't strictly need to be initialized before the first\n * stepCPU() call, but it's good form to do so.\n */\n this.resetCycles();\n this.flags.complete = this.flags.debugCheck = false;\n\n /*\n * If there are no live registers to display, then updateStatus() can skip a bit....\n */\n this.cLiveRegs = 0;\n\n /*\n * Array of halt handlers, if any (see addHaltCheck)\n */\n this.afnHalt = [];\n this.addrReset = 0x0000;\n\n /*\n * This initial resetRegs() call is important to create all the registers, so that if/when we call restore(),\n * it will have something to fill in.\n */\n this.resetRegs();\n }\n\n /**\n * addHaltCheck(fn)\n *\n * Records a function that will be called during HLT opcode processing.\n *\n * @this {CPUState8080}\n * @param {function(number)} fn\n */\n addHaltCheck(fn)\n {\n this.afnHalt.push(fn);\n }\n\n /**\n * initProcessor()\n *\n * Interestingly, if I dynamically generate aOps as an array of functions bound to \"this\", using the bind()\n * method, overall performance is worse. You would think that eliminating the need to use the call() method\n * on every opcode function invocation would be helpful, but it's not. I'm not sure exactly why yet; perhaps\n * a Closure Compiler optimization is defeated when generating the function array at run-time instead of at\n * compile-time.\n *\n * @this {CPUState8080}\n */\n initProcessor()\n {\n this.aOps = CPUDef8080.aOps8080;\n }\n\n /**\n * reset()\n *\n * @this {CPUState8080}\n */\n reset()\n {\n if (this.flags.running) this.stopCPU();\n this.resetRegs();\n this.resetCycles();\n this.clearError(); // clear any fatal error/exception that setError() may have flagged\n super.reset();\n }\n\n /**\n * resetRegs()\n *\n * @this {CPUState8080}\n */\n resetRegs()\n {\n this.regA = 0;\n this.regB = 0;\n this.regC = 0;\n this.regD = 0;\n this.regE = 0;\n this.regH = 0;\n this.regL = 0;\n this.setSP(0);\n this.setPC(this.addrReset);\n\n /*\n * This resets the Processor Status flags (regPS), along with all the internal \"result registers\".\n */\n this.setPS(0);\n\n /*\n * intFlags contains some internal states we use to indicate whether a hardware interrupt (INTFLAG.INTR) or\n * Trap software interrupt (INTR.TRAP) has been requested, as well as when we're in a \"HLT\" state (INTFLAG.HALT)\n * that requires us to wait for a hardware interrupt (INTFLAG.INTR) before continuing execution.\n */\n this.intFlags = CPUDef8080.INTFLAG.NONE;\n }\n\n /**\n * setReset(addr)\n *\n * @this {CPUState8080}\n * @param {number} addr\n */\n setReset(addr)\n {\n this.addrReset = addr;\n this.setPC(addr);\n }\n\n /**\n * getChecksum()\n *\n * @this {CPUState8080}\n * @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code)\n */\n getChecksum()\n {\n var sum = (this.regA + this.regB + this.regC + this.regD + this.regE + this.regH + this.regL)|0;\n sum = (sum + this.getSP() + this.getPC() + this.getPS())|0;\n return sum;\n }\n\n /**\n * save()\n *\n * This implements save support for the CPUState8080 component.\n *\n * @this {CPUState8080}\n * @return {Object|null}\n */\n save()\n {\n var state = new State(this);\n state.set(0, [this.regA, this.regB, this.regC, this.regD, this.regE, this.regH, this.regL, this.getSP(), this.getPC(), this.getPS()]);\n state.set(1, [this.intFlags, this.nTotalCycles, this.getSpeed()]);\n state.set(2, this.bus.saveMemory());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the CPUState8080 component.\n *\n * @this {CPUState8080}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n var a = data[0];\n this.regA = a[0];\n this.regB = a[1];\n this.regC = a[2];\n this.regD = a[3];\n this.regE = a[4];\n this.regH = a[5];\n this.regL = a[6];\n this.setSP(a[7]);\n this.setPC(a[8]);\n this.setPS(a[9]);\n a = data[1];\n this.intFlags = a[0];\n this.nTotalCycles = a[1];\n this.setSpeed(a[3]);\n return this.bus.restoreMemory(data[2]);\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {CPUState8080}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"AX\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var fBound = false;\n switch (sBinding) {\n case \"A\":\n case \"B\":\n case \"C\":\n case \"BC\":\n case \"D\":\n case \"E\":\n case \"DE\":\n case \"H\":\n case \"L\":\n case \"HL\":\n case \"SP\":\n case \"PC\":\n case \"PS\":\n case \"IF\":\n case \"SF\":\n case \"ZF\":\n case \"AF\":\n case \"PF\":\n case \"CF\":\n this.bindings[sBinding] = control;\n this.cLiveRegs++;\n fBound = true;\n break;\n default:\n fBound = super.setBinding(sHTMLType, sBinding, control);\n break;\n }\n return fBound;\n }\n\n /**\n * getBC()\n *\n * @this {CPUState8080}\n * @return {number}\n */\n getBC()\n {\n return (this.regB << 8) | this.regC;\n }\n\n /**\n * setBC(w)\n *\n * @this {CPUState8080}\n * @param {number} w\n */\n setBC(w)\n {\n this.regB = (w >> 8) & 0xff;\n this.regC = w & 0xff;\n }\n\n /**\n * getDE()\n *\n * @this {CPUState8080}\n * @return {number}\n */\n getDE()\n {\n return (this.regD << 8) | this.regE;\n }\n\n /**\n * setDE(w)\n *\n * @this {CPUState8080}\n * @param {number} w\n */\n setDE(w)\n {\n this.regD = (w >> 8) & 0xff;\n this.regE = w & 0xff;\n }\n\n /**\n * getHL()\n *\n * @this {CPUState8080}\n * @return {number}\n */\n getHL()\n {\n return (this.regH << 8) | this.regL;\n }\n\n /**\n * setHL(w)\n *\n * @this {CPUState8080}\n * @param {number} w\n */\n setHL(w)\n {\n this.regH = (w >> 8) & 0xff;\n this.regL = w & 0xff;\n }\n\n /**\n * getSP()\n *\n * @this {CPUState8080}\n * @return {number}\n */\n getSP()\n {\n return this.regSP;\n }\n\n /**\n * setSP(off)\n *\n * @this {CPUState8080}\n * @param {number} off\n */\n setSP(off)\n {\n this.regSP = off & 0xffff;\n }\n\n /**\n * getPC()\n *\n * @this {CPUState8080}\n * @return {number}\n */\n getPC()\n {\n return this.regPC;\n }\n\n /**\n * offPC()\n *\n * @this {CPUState8080}\n * @param {number} off\n * @return {number}\n */\n offPC(off)\n {\n return (this.regPC + off) & 0xffff;\n }\n\n /**\n * setPC(off)\n *\n * @this {CPUState8080}\n * @param {number} off\n */\n setPC(off)\n {\n this.regPC = off & 0xffff;\n }\n\n /**\n * clearCF()\n *\n * @this {CPUState8080}\n */\n clearCF()\n {\n this.resultZeroCarry &= 0xff;\n }\n\n /**\n * getCF()\n *\n * @this {CPUState8080}\n * @return {number} 0 or 1 (CPUDef8080.PS.CF)\n */\n getCF()\n {\n return (this.resultZeroCarry & 0x100)? CPUDef8080.PS.CF : 0;\n }\n\n /**\n * setCF()\n *\n * @this {CPUState8080}\n */\n setCF()\n {\n this.resultZeroCarry |= 0x100;\n }\n\n /**\n * updateCF(CF)\n *\n * @this {CPUState8080}\n * @param {number} CF (0x000 or 0x100)\n */\n updateCF(CF)\n {\n this.resultZeroCarry = (this.resultZeroCarry & 0xff) | CF;\n }\n\n /**\n * clearPF()\n *\n * @this {CPUState8080}\n */\n clearPF()\n {\n if (this.getPF()) this.resultParitySign ^= 0x1;\n }\n\n /**\n * getPF()\n *\n * @this {CPUState8080}\n * @return {number} 0 or CPUDef8080.PS.PF\n */\n getPF()\n {\n return (CPUDef8080.PARITY[this.resultParitySign & 0xff])? CPUDef8080.PS.PF : 0;\n }\n\n /**\n * setPF()\n *\n * @this {CPUState8080}\n */\n setPF()\n {\n if (!this.getPF()) this.resultParitySign ^= 0x1;\n }\n\n /**\n * clearAF()\n *\n * @this {CPUState8080}\n */\n clearAF()\n {\n this.resultAuxOverflow = (this.resultParitySign & 0x10) | (this.resultAuxOverflow & ~0x10);\n }\n\n /**\n * getAF()\n *\n * @this {CPUState8080}\n * @return {number} 0 or CPUDef8080.PS.AF\n */\n getAF()\n {\n return ((this.resultParitySign ^ this.resultAuxOverflow) & 0x10)? CPUDef8080.PS.AF : 0;\n }\n\n /**\n * setAF()\n *\n * @this {CPUState8080}\n */\n setAF()\n {\n this.resultAuxOverflow = (~this.resultParitySign & 0x10) | (this.resultAuxOverflow & ~0x10);\n }\n\n /**\n * clearZF()\n *\n * @this {CPUState8080}\n */\n clearZF()\n {\n this.resultZeroCarry |= 0xff;\n }\n\n /**\n * getZF()\n *\n * @this {CPUState8080}\n * @return {number} 0 or CPUDef8080.PS.ZF\n */\n getZF()\n {\n return (this.resultZeroCarry & 0xff)? 0 : CPUDef8080.PS.ZF;\n }\n\n /**\n * setZF()\n *\n * @this {CPUState8080}\n */\n setZF()\n {\n this.resultZeroCarry &= ~0xff;\n }\n\n /**\n * clearSF()\n *\n * @this {CPUState8080}\n */\n clearSF()\n {\n if (this.getSF()) this.resultParitySign ^= 0xc0;\n }\n\n /**\n * getSF()\n *\n * @this {CPUState8080}\n * @return {number} 0 or CPUDef8080.PS.SF\n */\n getSF()\n {\n return (this.resultParitySign & 0x80)? CPUDef8080.PS.SF : 0;\n }\n\n /**\n * setSF()\n *\n * @this {CPUState8080}\n */\n setSF()\n {\n if (!this.getSF()) this.resultParitySign ^= 0xc0;\n }\n\n /**\n * clearIF()\n *\n * @this {CPUState8080}\n */\n clearIF()\n {\n this.regPS &= ~CPUDef8080.PS.IF;\n }\n\n /**\n * getIF()\n *\n * @this {CPUState8080}\n * @return {number} 0 or CPUDef8080.PS.IF\n */\n getIF()\n {\n return (this.regPS & CPUDef8080.PS.IF);\n }\n\n /**\n * setIF()\n *\n * @this {CPUState8080}\n */\n setIF()\n {\n this.regPS |= CPUDef8080.PS.IF;\n }\n\n /**\n * getPS()\n *\n * @this {CPUState8080}\n * @return {number}\n */\n getPS()\n {\n return (this.regPS & ~CPUDef8080.PS.RESULT) | (this.getSF() | this.getZF() | this.getAF() | this.getPF() | this.getCF());\n }\n\n /**\n * setPS(regPS)\n *\n * @this {CPUState8080}\n * @param {number} regPS\n */\n setPS(regPS)\n {\n this.resultZeroCarry = this.resultParitySign = this.resultAuxOverflow = 0;\n if (regPS & CPUDef8080.PS.CF) this.resultZeroCarry |= 0x100;\n if (!(regPS & CPUDef8080.PS.PF)) this.resultParitySign |= 0x01;\n if (regPS & CPUDef8080.PS.AF) this.resultAuxOverflow |= 0x10;\n if (!(regPS & CPUDef8080.PS.ZF)) this.resultZeroCarry |= 0xff;\n if (regPS & CPUDef8080.PS.SF) this.resultParitySign ^= 0xc0;\n this.regPS = (this.regPS & ~(CPUDef8080.PS.RESULT | CPUDef8080.PS.INTERNAL)) | (regPS & CPUDef8080.PS.INTERNAL) | CPUDef8080.PS.SET;\n\n }\n\n /**\n * getPSW()\n *\n * @this {CPUState8080}\n * @return {number}\n */\n getPSW()\n {\n return (this.getPS() & CPUDef8080.PS.MASK) | (this.regA << 8);\n }\n\n /**\n * setPSW(w)\n *\n * @this {CPUState8080}\n * @param {number} w\n */\n setPSW(w)\n {\n this.setPS((w & CPUDef8080.PS.MASK) | (this.regPS & ~CPUDef8080.PS.MASK));\n this.regA = w >> 8;\n }\n\n /**\n * addByte(src)\n *\n * @this {CPUState8080}\n * @param {number} src\n * @return {number} regA + src\n */\n addByte(src)\n {\n this.resultAuxOverflow = this.regA ^ src;\n return this.resultParitySign = (this.resultZeroCarry = this.regA + src) & 0xff;\n }\n\n /**\n * addByteCarry(src)\n *\n * @this {CPUState8080}\n * @param {number} src\n * @return {number} regA + src + carry\n */\n addByteCarry(src)\n {\n this.resultAuxOverflow = this.regA ^ src;\n return this.resultParitySign = (this.resultZeroCarry = this.regA + src + ((this.resultZeroCarry & 0x100)? 1 : 0)) & 0xff;\n }\n\n /**\n * andByte(src)\n *\n * Ordinarily, one would expect the Auxiliary Carry flag (AF) to be clear after this operation,\n * but apparently the 8080 will set AF if bit 3 in either operand is set.\n *\n * @this {CPUState8080}\n * @param {number} src\n * @return {number} regA & src\n */\n andByte(src)\n {\n this.resultZeroCarry = this.resultParitySign = this.resultAuxOverflow = this.regA & src;\n if ((this.regA | src) & 0x8) this.resultAuxOverflow ^= 0x10; // set AF by inverting bit 4 in resultAuxOverflow\n return this.resultZeroCarry;\n }\n\n /**\n * decByte(b)\n *\n * We perform this operation using 8-bit two's complement arithmetic, by negating and then adding\n * the implied src of 1. This appears to mimic how the 8080 manages the Auxiliary Carry flag (AF).\n *\n * @this {CPUState8080}\n * @param {number} b\n * @return {number}\n */\n decByte(b)\n {\n this.resultAuxOverflow = b ^ 0xff;\n b = this.resultParitySign = (b + 0xff) & 0xff;\n this.resultZeroCarry = (this.resultZeroCarry & ~0xff) | b;\n return b;\n }\n\n /**\n * incByte(b)\n *\n * @this {CPUState8080}\n * @param {number} b\n * @return {number}\n */\n incByte(b)\n {\n this.resultAuxOverflow = b;\n b = this.resultParitySign = (b + 1) & 0xff;\n this.resultZeroCarry = (this.resultZeroCarry & ~0xff) | b;\n return b;\n }\n\n /**\n * orByte(src)\n *\n * @this {CPUState8080}\n * @param {number} src\n * @return {number} regA | src\n */\n orByte(src)\n {\n return this.resultParitySign = this.resultZeroCarry = this.resultAuxOverflow = this.regA | src;\n }\n\n /**\n * subByte(src)\n *\n * We perform this operation using 8-bit two's complement arithmetic, by inverting src, adding\n * src + 1, and then inverting the resulting carry (resultZeroCarry ^ 0x100). This appears to mimic\n * how the 8080 manages the Auxiliary Carry flag (AF).\n *\n * This function is also used as a cmpByte() function; compare instructions simply ignore the\n * return value.\n *\n * Example: A=66, SUI $10\n *\n * If we created the two's complement of 0x10 by negating it, there would just be one addition:\n *\n * 0110 0110 (0x66)\n * + 1111 0000 (0xF0) (ie, -0x10)\n * ---------\n * 1 0101 0110 (0x56)\n *\n * But in order to mimic the 8080's AF flag, we must perform the two's complement of src in two steps,\n * inverting it before the add, and then incrementing after the add; eg:\n *\n * 0110 0110 (0x66)\n * + 1110 1111 (0xEF) (ie, ~0x10)\n * ---------\n * 1 0101 0101 (0x55)\n * + 0000 0001 (0x01)\n * ---------\n * 1 0101 0110 (0x56)\n *\n * @this {CPUState8080}\n * @param {number} src\n * @return {number} regA - src\n */\n subByte(src)\n {\n src ^= 0xff;\n this.resultAuxOverflow = this.regA ^ src;\n return this.resultParitySign = (this.resultZeroCarry = (this.regA + src + 1) ^ 0x100) & 0xff;\n }\n\n /**\n * subByteBorrow(src)\n *\n * We perform this operation using 8-bit two's complement arithmetic, using logic similar to subByte(),\n * but changing the final increment to a conditional increment, because if the Carry flag (CF) is set, then\n * we don't need to perform the increment at all.\n *\n * This mimics the behavior of subByte() when the Carry flag (CF) is clear, and hopefully also mimics how the\n * 8080 manages the Auxiliary Carry flag (AF) when the Carry flag (CF) is set.\n *\n * @this {CPUState8080}\n * @param {number} src\n * @return {number} regA - src - carry\n */\n subByteBorrow(src)\n {\n src ^= 0xff;\n this.resultAuxOverflow = this.regA ^ src;\n return this.resultParitySign = (this.resultZeroCarry = (this.regA + src + ((this.resultZeroCarry & 0x100)? 0 : 1)) ^ 0x100) & 0xff;\n }\n\n /**\n * xorByte(src)\n *\n * @this {CPUState8080}\n * @param {number} src\n * @return {number} regA ^ src\n */\n xorByte(src)\n {\n return this.resultParitySign = this.resultZeroCarry = this.resultAuxOverflow = this.regA ^ src;\n }\n\n /**\n * getByte(addr)\n *\n * @this {CPUState8080}\n * @param {number} addr is a linear address\n * @return {number} byte (8-bit) value at that address\n */\n getByte(addr)\n {\n return this.bus.getByte(addr);\n }\n\n /**\n * getWord(addr)\n *\n * @this {CPUState8080}\n * @param {number} addr is a linear address\n * @return {number} word (16-bit) value at that address\n */\n getWord(addr)\n {\n return this.bus.getShort(addr);\n }\n\n /**\n * setByte(addr, b)\n *\n * @this {CPUState8080}\n * @param {number} addr is a linear address\n * @param {number} b is the byte (8-bit) value to write (which we truncate to 8 bits; required by opSTOSb)\n */\n setByte(addr, b)\n {\n this.bus.setByte(addr, b);\n }\n\n /**\n * setWord(addr, w)\n *\n * @this {CPUState8080}\n * @param {number} addr is a linear address\n * @param {number} w is the word (16-bit) value to write (which we truncate to 16 bits to be safe)\n */\n setWord(addr, w)\n {\n this.bus.setShort(addr, w);\n }\n\n /**\n * getPCByte()\n *\n * @this {CPUState8080}\n * @return {number} byte at the current PC; PC advanced by 1\n */\n getPCByte()\n {\n var b = this.getByte(this.regPC);\n this.setPC(this.regPC + 1);\n return b;\n }\n\n /**\n * getPCWord()\n *\n * @this {CPUState8080}\n * @return {number} word at the current PC; PC advanced by 2\n */\n getPCWord()\n {\n var w = this.getWord(this.regPC);\n this.setPC(this.regPC + 2);\n return w;\n }\n\n /**\n * popWord()\n *\n * @this {CPUState8080}\n * @return {number} word popped from the current SP; SP increased by 2\n */\n popWord()\n {\n var w = this.getWord(this.regSP);\n this.setSP(this.regSP + 2);\n return w;\n }\n\n /**\n * pushWord(w)\n *\n * @this {CPUState8080}\n * @param {number} w is the word (16-bit) value to push at current SP; SP decreased by 2\n */\n pushWord(w)\n {\n this.setSP(this.regSP - 2);\n this.setWord(this.regSP, w);\n }\n\n /**\n * checkINTR()\n *\n * @this {CPUState8080}\n * @return {boolean} true if execution may proceed, false if not\n */\n checkINTR()\n {\n /*\n * If the Debugger is single-stepping, this.nStepCycles will always be zero, which we take\n * advantage of here to avoid processing interrupts. The Debugger will have to issue a \"g\"\n * command (or \"p\" command on a call instruction) if you want interrupts to be processed.\n */\n if (this.nStepCycles) {\n if ((this.intFlags & CPUDef8080.INTFLAG.INTR) && this.getIF()) {\n for (var nLevel = 0; nLevel < 8; nLevel++) {\n if (this.intFlags & (1 << nLevel)) break;\n }\n this.clearINTR(nLevel);\n this.clearIF();\n this.intFlags &= ~CPUDef8080.INTFLAG.HALT;\n this.aOps[CPUDef8080.OPCODE.RST0 | (nLevel << 3)].call(this);\n }\n }\n if (this.intFlags & CPUDef8080.INTFLAG.HALT) {\n /*\n * As discussed in opHLT(), the CPU is never REALLY halted by a HLT instruction; instead, opHLT()\n * calls requestHALT(), which sets INTFLAG.HALT and signals to stepCPU() that it's free to end the\n * current burst AND that it should not execute any more instructions until checkINTR() indicates\n * that a hardware interrupt has been requested.\n */\n this.endBurst();\n return false;\n }\n return true;\n }\n\n /**\n * clearINTR(nLevel)\n *\n * Clear the corresponding interrupt level.\n *\n * nLevel can either be a valid interrupt level (0-7), or -1 to clear all pending interrupts\n * (eg, in the event of a system-wide reset).\n *\n * @this {CPUState8080}\n * @param {number} nLevel (0-7, or -1 for all)\n */\n clearINTR(nLevel)\n {\n var bitsClear = nLevel < 0? 0xff : (1 << nLevel);\n this.intFlags &= ~bitsClear;\n }\n\n /**\n * requestHALT()\n *\n * @this {CPUState8080}\n */\n requestHALT()\n {\n this.intFlags |= CPUDef8080.INTFLAG.HALT;\n this.endBurst();\n }\n\n /**\n * requestINTR(nLevel)\n *\n * Request the corresponding interrupt level.\n *\n * Each interrupt level (0-7) has its own intFlags bit (0-7). If the Interrupt Flag (IF) is also\n * set, then we know that checkINTR() will want to issue the interrupt, so we end the current burst\n * by setting nStepCycles to zero. But before we do, we subtract nStepCycles from nBurstCycles,\n * so that the calculation of how many cycles were actually executed on this burst is correct.\n *\n * @this {CPUState8080}\n * @param {number} nLevel (0-7)\n */\n requestINTR(nLevel)\n {\n this.intFlags |= (1 << nLevel);\n if (this.getIF()) {\n this.endBurst();\n }\n }\n\n /**\n * updateReg(sReg, nValue, cch)\n *\n * This function helps updateStatus() by massaging the register names and values according to\n * CPU type before passing the call to displayValue(); in the \"old days\", updateStatus() called\n * displayValue() directly (although then it was called displayReg()).\n *\n * @this {CPUState8080}\n * @param {string} sReg\n * @param {number} nValue\n * @param {number} [cch] (default is 2 hex digits)\n */\n updateReg(sReg, nValue, cch)\n {\n this.displayValue(sReg, nValue, cch || 2);\n }\n\n /**\n * updateStatus(fForce)\n *\n * This provides periodic Control Panel updates (eg, a few times per second; see YIELDS_PER_STATUS).\n * this is where we take care of any DOM updates (eg, register values) while the CPU is running.\n *\n * Any high-frequency updates should be performed in updateVideo(), which should avoid DOM updates,\n * since updateVideo() can be called up to 60 times per second.\n *\n * @this {CPUState8080}\n * @param {boolean} [fForce] (true will display registers even if the CPU is running and \"live\" registers are not enabled)\n */\n updateStatus(fForce)\n {\n if (this.cLiveRegs) {\n if (fForce || !this.flags.running || this.flags.displayLiveRegs) {\n this.updateReg(\"A\", this.regA);\n this.updateReg(\"B\", this.regB);\n this.updateReg(\"C\", this.regC);\n this.updateReg(\"BC\", this.getBC(), 4);\n this.updateReg(\"D\", this.regD);\n this.updateReg(\"E\", this.regE);\n this.updateReg(\"DE\", this.getDE(), 4);\n this.updateReg(\"H\", this.regH);\n this.updateReg(\"L\", this.regL);\n this.updateReg(\"HL\", this.getHL(), 4);\n this.updateReg(\"SP\", this.getSP(), 4);\n this.updateReg(\"PC\", this.getPC(), 4);\n var regPS = this.getPS();\n this.updateReg(\"PS\", regPS, 4);\n this.updateReg(\"IF\", (regPS & CPUDef8080.PS.IF)? 1 : 0, 1);\n this.updateReg(\"SF\", (regPS & CPUDef8080.PS.SF)? 1 : 0, 1);\n this.updateReg(\"ZF\", (regPS & CPUDef8080.PS.ZF)? 1 : 0, 1);\n this.updateReg(\"AF\", (regPS & CPUDef8080.PS.AF)? 1 : 0, 1);\n this.updateReg(\"PF\", (regPS & CPUDef8080.PS.PF)? 1 : 0, 1);\n this.updateReg(\"CF\", (regPS & CPUDef8080.PS.CF)? 1 : 0, 1);\n }\n }\n var controlSpeed = this.bindings[\"speed\"];\n if (controlSpeed) controlSpeed.textContent = this.getSpeedCurrent();\n }\n\n /**\n * stepCPU(nMinCycles)\n *\n * NOTE: Single-stepping should not be confused with the Trap flag; single-stepping is a Debugger\n * operation that's completely independent of Trap status. The CPU can go in and out of Trap mode,\n * in and out of h/w interrupt service routines (ISRs), etc, but from the Debugger's perspective,\n * they're all one continuous stream of instructions that can be stepped or run at will. Moreover,\n * stepping vs. running should never change the behavior of the simulation.\n *\n * @this {CPUState8080}\n * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored)\n * @return {number} of cycles executed; 0 indicates a pre-execution condition (ie, an execution breakpoint\n * was hit), -1 indicates a post-execution condition (eg, a read or write breakpoint was hit), and a positive\n * number indicates successful completion of that many cycles (which should always be >= nMinCycles).\n */\n stepCPU(nMinCycles)\n {\n /*\n * The Debugger uses fComplete to determine if the instruction completed (true) or was interrupted\n * by a breakpoint or some other exceptional condition (false). NOTE: this does NOT include JavaScript\n * exceptions, which stepCPU() expects the caller to catch using its own exception handler.\n *\n * The CPU relies on the use of stopCPU() rather than fComplete, because the CPU never single-steps\n * (ie, nMinCycles is always some large number), whereas the Debugger does. And conversely, when the\n * Debugger is single-stepping (even when performing multiple single-steps), fRunning is never set,\n * so stopCPU() would have no effect as far as the Debugger is concerned.\n */\n this.flags.complete = true;\n\n /*\n * fDebugCheck is true if we need to \"check\" every instruction with the Debugger.\n */\n var fDebugCheck = this.flags.debugCheck = (DEBUGGER && this.dbg && this.dbg.checksEnabled());\n\n /*\n * nDebugState is checked only when fDebugCheck is true, and its sole purpose is to tell the first call\n * to checkInstruction() that it can skip breakpoint checks, and that will be true ONLY when fStarting is\n * true OR nMinCycles is zero (the latter means the Debugger is single-stepping).\n *\n * Once we snap fStarting, we clear it, because technically, we've moved beyond \"starting\" and have\n * officially \"started\" now.\n */\n var nDebugState = (!nMinCycles)? -1 : (this.flags.starting? 0 : 1);\n this.flags.starting = false;\n\n /*\n * We move the minimum cycle count to nStepCycles (the number of cycles left to step), so that other\n * functions have the ability to force that number to zero (eg, stopCPU()), and thus we don't have to check\n * any other criteria to determine whether we should continue stepping or not.\n */\n this.nBurstCycles = this.nStepCycles = nMinCycles;\n\n /*\n * NOTE: If checkINTR() returns false, INTFLAG.HALT must be set, so no instructions should be executed.\n */\n if (this.checkINTR()) {\n do {\n if (DEBUGGER && fDebugCheck) {\n if (this.dbg.checkInstruction(this.regPC, nDebugState)) {\n this.stopCPU();\n break;\n }\n nDebugState = 1;\n }\n this.aOps[this.getPCByte()].call(this);\n\n } while (this.nStepCycles > 0);\n }\n\n return (this.flags.complete? this.nBurstCycles - this.nStepCycles : (this.flags.complete === undefined? 0 : -1));\n }\n\n /**\n * CPUState8080.init()\n *\n * This function operates on every HTML element of class \"cpu\", extracting the\n * JSON-encoded parameters for the CPUState8080 constructor from the element's \"data-value\"\n * attribute, invoking the constructor (which in turn invokes the CPU constructor)\n * to create a CPUState8080 component, and then binding any associated HTML controls to the\n * new component.\n */\n static init()\n {\n var aeCPUs = Component.getElementsByClass(document, PC8080.APPCLASS, \"cpu\");\n for (var iCPU = 0; iCPU < aeCPUs.length; iCPU++) {\n var eCPU = aeCPUs[iCPU];\n var parmsCPU = Component.getComponentParms(eCPU);\n var cpu = new CPUState8080(parmsCPU);\n Component.bindComponentControls(cpu, eCPU, PC8080.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize every CPU module on the page\n */\nWeb.onInit(CPUState8080.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/cpuops.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * op=0x00 (NOP)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opNOP = function()\n{\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x01 (LXI B,d16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opLXIB = function()\n{\n this.setBC(this.getPCWord());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x02 (STAX B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSTAXB = function()\n{\n this.setByte(this.getBC(), this.regA);\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x03 (INX B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINXB = function()\n{\n this.setBC(this.getBC() + 1);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x04 (INR B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINRB = function()\n{\n this.regB = this.incByte(this.regB);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x05 (DCR B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCRB = function()\n{\n this.regB = this.decByte(this.regB);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x06 (MVI B,d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMVIB = function()\n{\n this.regB = this.getPCByte();\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x07 (RLC)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRLC = function()\n{\n var carry = this.regA << 1;\n this.regA = (carry & 0xff) | (carry >> 8);\n this.updateCF(carry & 0x100);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x09 (DAD B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDADB = function()\n{\n var w;\n this.setHL(w = this.getHL() + this.getBC());\n this.updateCF((w >> 8) & 0x100);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x0A (LDAX B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opLDAXB = function()\n{\n this.regA = this.getByte(this.getBC());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x0B (DCX B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCXB = function()\n{\n this.setBC(this.getBC() - 1);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x0C (INR C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINRC = function()\n{\n this.regC = this.incByte(this.regC);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x0D (DCR C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCRC = function()\n{\n this.regC = this.decByte(this.regC);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x0E (MVI C,d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMVIC = function()\n{\n this.regC = this.getPCByte();\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x0F (RRC)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRRC = function()\n{\n var carry = (this.regA << 8) & 0x100;\n this.regA = (carry | this.regA) >> 1;\n this.updateCF(carry);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x11 (LXI D,d16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opLXID = function()\n{\n this.setDE(this.getPCWord());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x12 (STAX D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSTAXD = function()\n{\n this.setByte(this.getDE(), this.regA);\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x13 (INX D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINXD = function()\n{\n this.setDE(this.getDE() + 1);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x14 (INR D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINRD = function()\n{\n this.regD = this.incByte(this.regD);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x15 (DCR D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCRD = function()\n{\n this.regD = this.decByte(this.regD);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x16 (MVI D,d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMVID = function()\n{\n this.regD = this.getPCByte();\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x17 (RAL)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRAL = function()\n{\n var carry = this.regA << 1;\n this.regA = (carry & 0xff) | this.getCF();\n this.updateCF(carry & 0x100);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x19 (DAD D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDADD = function()\n{\n var w;\n this.setHL(w = this.getHL() + this.getDE());\n this.updateCF((w >> 8) & 0x100);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x1A (LDAX D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opLDAXD = function()\n{\n this.regA = this.getByte(this.getDE());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x1B (DCX D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCXD = function()\n{\n this.setDE(this.getDE() - 1);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x1C (INR E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINRE = function()\n{\n this.regE = this.incByte(this.regE);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x1D (DCR E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCRE = function()\n{\n this.regE = this.decByte(this.regE);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x1E (MVI E,d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMVIE = function()\n{\n this.regE = this.getPCByte();\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x1F (RAR)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRAR = function()\n{\n var carry = (this.regA << 8);\n this.regA = ((this.getCF() << 8) | this.regA) >> 1;\n this.updateCF(carry & 0x100);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x21 (LXI H,d16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opLXIH = function()\n{\n this.setHL(this.getPCWord());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x22 (SHLD a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSHLD = function()\n{\n this.setWord(this.getPCWord(), this.getHL());\n this.nStepCycles -= 16;\n};\n\n/**\n * op=0x23 (INX H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINXH = function()\n{\n this.setHL(this.getHL() + 1);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x24 (INR H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINRH = function()\n{\n this.regH = this.incByte(this.regH);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x25 (DCR H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCRH = function()\n{\n this.regH = this.decByte(this.regH);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x26 (MVI H,d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMVIH = function()\n{\n this.regH = this.getPCByte();\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x27 (DAA)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDAA = function()\n{\n var src = 0;\n var CF = this.getCF();\n var AF = this.getAF();\n if (AF || (this.regA & 0x0F) > 9) {\n src |= 0x06;\n }\n if (CF || this.regA >= 0x9A) {\n src |= 0x60;\n CF = CPUDef8080.PS.CF;\n }\n this.regA = this.addByte(src);\n this.updateCF(CF? 0x100 : 0);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x29 (DAD H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDADH = function()\n{\n var w;\n this.setHL(w = this.getHL() + this.getHL());\n this.updateCF((w >> 8) & 0x100);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x2A (LHLD a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opLHLD = function()\n{\n this.setHL(this.getWord(this.getPCWord()));\n this.nStepCycles -= 16;\n};\n\n/**\n * op=0x2B (DCX H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCXH = function()\n{\n this.setHL(this.getHL() - 1);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x2C (INR L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINRL = function()\n{\n this.regL = this.incByte(this.regL);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x2D (DCR L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCRL = function()\n{\n this.regL = this.decByte(this.regL);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x2E (MVI L,d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMVIL = function()\n{\n this.regL = this.getPCByte();\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x2F (CMA)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCMA = function()\n{\n this.regA = ~this.regA & 0xff;\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x31 (LXI SP,d16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opLXISP = function()\n{\n this.setSP(this.getPCWord());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x32 (STA a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSTA = function()\n{\n this.setByte(this.getPCWord(), this.regA);\n this.nStepCycles -= 13;\n};\n\n/**\n * op=0x33 (INX SP)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINXSP = function()\n{\n this.setSP(this.getSP() + 1);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x34 (INR M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINRM = function()\n{\n var addr = this.getHL();\n this.setByte(addr, this.incByte(this.getByte(addr)));\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x35 (DCR M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCRM = function()\n{\n var addr = this.getHL();\n this.setByte(addr, this.decByte(this.getByte(addr)));\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x36 (MVI M,d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMVIM = function()\n{\n this.setByte(this.getHL(), this.getPCByte());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x37 (STC)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSTC = function()\n{\n this.setCF();\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x39 (DAD SP)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDADSP = function()\n{\n var w;\n this.setHL(w = this.getHL() + this.getSP());\n this.updateCF((w >> 8) & 0x100);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0x3A (LDA a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opLDA = function()\n{\n this.regA = this.getByte(this.getPCWord());\n this.nStepCycles -= 13;\n};\n\n/**\n * op=0x3B (DCX SP)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCXSP = function()\n{\n this.setSP(this.getSP() - 1);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x3C (INR A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opINRA = function()\n{\n this.regA = this.incByte(this.regA);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x3D (DCR A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDCRA = function()\n{\n this.regA = this.decByte(this.regA);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x3E (MVI A,d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMVIA = function()\n{\n this.regA = this.getPCByte();\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x3F (CMC)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCMC = function()\n{\n this.updateCF(this.getCF()? 0 : 0x100);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x40 (MOV B,B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVBB = function()\n{\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x41 (MOV B,C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVBC = function()\n{\n this.regB = this.regC;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x42 (MOV B,D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVBD = function()\n{\n this.regB = this.regD;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x43 (MOV B,E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVBE = function()\n{\n this.regB = this.regE;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x44 (MOV B,H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVBH = function()\n{\n this.regB = this.regH;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x45 (MOV B,L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVBL = function()\n{\n this.regB = this.regL;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x46 (MOV B,M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVBM = function()\n{\n this.regB = this.getByte(this.getHL());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x47 (MOV B,A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVBA = function()\n{\n this.regB = this.regA;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x48 (MOV C,B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVCB = function()\n{\n this.regC = this.regB;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x49 (MOV C,C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVCC = function()\n{\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x4A (MOV C,D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVCD = function()\n{\n this.regC = this.regD;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x4B (MOV C,E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVCE = function()\n{\n this.regC = this.regE;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x4C (MOV C,H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVCH = function()\n{\n this.regC = this.regH;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x4D (MOV C,L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVCL = function()\n{\n this.regC = this.regL;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x4E (MOV C,M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVCM = function()\n{\n this.regC = this.getByte(this.getHL());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x4F (MOV C,A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVCA = function()\n{\n this.regC = this.regA;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x50 (MOV D,B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVDB = function()\n{\n this.regD = this.regB;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x51 (MOV D,C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVDC = function()\n{\n this.regD = this.regC;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x52 (MOV D,D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVDD = function()\n{\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x53 (MOV D,E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVDE = function()\n{\n this.regD = this.regE;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x54 (MOV D,H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVDH = function()\n{\n this.regD = this.regH;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x55 (MOV D,L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVDL = function()\n{\n this.regD = this.regL;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x56 (MOV D,M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVDM = function()\n{\n this.regD = this.getByte(this.getHL());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x57 (MOV D,A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVDA = function()\n{\n this.regD = this.regA;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x58 (MOV E,B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVEB = function()\n{\n this.regE = this.regB;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x59 (MOV E,C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVEC = function()\n{\n this.regE = this.regC;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x5A (MOV E,D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVED = function()\n{\n this.regE = this.regD;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x5B (MOV E,E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVEE = function()\n{\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x5C (MOV E,H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVEH = function()\n{\n this.regE = this.regH;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x5D (MOV E,L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVEL = function()\n{\n this.regE = this.regL;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x5E (MOV E,M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVEM = function()\n{\n this.regE = this.getByte(this.getHL());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x5F (MOV E,A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVEA = function()\n{\n this.regE = this.regA;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x60 (MOV H,B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVHB = function()\n{\n this.regH = this.regB;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x61 (MOV H,C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVHC = function()\n{\n this.regH = this.regC;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x62 (MOV H,D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVHD = function()\n{\n this.regH = this.regD;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x63 (MOV H,E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVHE = function()\n{\n this.regH = this.regE;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x64 (MOV H,H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVHH = function()\n{\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x65 (MOV H,L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVHL = function()\n{\n this.regH = this.regL;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x66 (MOV H,M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVHM = function()\n{\n this.regH = this.getByte(this.getHL());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x67 (MOV H,A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVHA = function()\n{\n this.regH = this.regA;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x68 (MOV L,B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVLB = function()\n{\n this.regL = this.regB;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x69 (MOV L,C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVLC = function()\n{\n this.regL = this.regC;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x6A (MOV L,D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVLD = function()\n{\n this.regL = this.regD;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x6B (MOV L,E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVLE = function()\n{\n this.regL = this.regE;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x6C (MOV L,H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVLH = function()\n{\n this.regL = this.regH;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x6D (MOV L,L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVLL = function()\n{\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x6E (MOV L,M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVLM = function()\n{\n this.regL = this.getByte(this.getHL());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x6F (MOV L,A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVLA = function()\n{\n this.regL = this.regA;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x70 (MOV M,B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVMB = function()\n{\n this.setByte(this.getHL(), this.regB);\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x71 (MOV M,C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVMC = function()\n{\n this.setByte(this.getHL(), this.regC);\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x72 (MOV M,D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVMD = function()\n{\n this.setByte(this.getHL(), this.regD);\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x73 (MOV M,E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVME = function()\n{\n this.setByte(this.getHL(), this.regE);\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x74 (MOV M,H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVMH = function()\n{\n this.setByte(this.getHL(), this.regH);\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x75 (MOV M,L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVML = function()\n{\n this.setByte(this.getHL(), this.regL);\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x76 (HLT)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opHLT = function()\n{\n var addr = this.getPC() - 1;\n\n /*\n * If any HLT check functions are installed, call them, and if any of them return true, then\n * immediately stop HLT processing.\n */\n if (this.afnHalt.length) {\n for (var i = 0; i < this.afnHalt.length; i++) {\n if (this.afnHalt[i](addr)) return;\n }\n }\n\n this.nStepCycles -= 7;\n\n /*\n * The CPU is never REALLY halted by a HLT instruction; instead, we call requestHALT(), which\n * signals to stepCPU() that it should end the current burst AND that it should not execute any\n * more instructions until checkINTR() indicates a hardware interrupt has been requested.\n */\n this.requestHALT();\n\n /*\n * If a Debugger is present and the HALT message category is enabled, then we REALLY halt the CPU,\n * on the theory that whoever's using the Debugger would like to see HLTs.\n */\n if (DEBUGGER && this.dbg && this.messageEnabled(Messages8080.HALT)) {\n this.setPC(addr); // this is purely for the Debugger's benefit, to show the HLT\n this.dbg.stopCPU();\n return;\n }\n\n /*\n * We also REALLY halt the machine if interrupts have been disabled, since that means it's dead\n * in the water (we have no NMI generation mechanism at the moment).\n */\n if (!this.getIF()) {\n if (DEBUGGER && this.dbg) this.setPC(addr);\n this.stopCPU();\n }\n};\n\n/**\n * op=0x77 (MOV M,A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVMA = function()\n{\n this.setByte(this.getHL(), this.regA);\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x78 (MOV A,B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVAB = function()\n{\n this.regA = this.regB;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x79 (MOV A,C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVAC = function()\n{\n this.regA = this.regC;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x7A (MOV A,D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVAD = function()\n{\n this.regA = this.regD;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x7B (MOV A,E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVAE = function()\n{\n this.regA = this.regE;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x7C (MOV A,H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVAH = function()\n{\n this.regA = this.regH;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x7D (MOV A,L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVAL = function()\n{\n this.regA = this.regL;\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x7E (MOV A,M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVAM = function()\n{\n this.regA = this.getByte(this.getHL());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x7F (MOV A,A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opMOVAA = function()\n{\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0x80 (ADD B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADDB = function()\n{\n this.regA = this.addByte(this.regB);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x81 (ADD C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADDC = function()\n{\n this.regA = this.addByte(this.regC);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x82 (ADD D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADDD = function()\n{\n this.regA = this.addByte(this.regD);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x83 (ADD E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADDE = function()\n{\n this.regA = this.addByte(this.regE);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x84 (ADD H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADDH = function()\n{\n this.regA = this.addByte(this.regH);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x85 (ADD L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADDL = function()\n{\n this.regA = this.addByte(this.regL);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x86 (ADD M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADDM = function()\n{\n this.regA = this.addByte(this.getByte(this.getHL()));\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x87 (ADD A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADDA = function()\n{\n this.regA = this.addByte(this.regA);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x88 (ADC B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADCB = function()\n{\n this.regA = this.addByteCarry(this.regB);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x89 (ADC C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADCC = function()\n{\n this.regA = this.addByteCarry(this.regC);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x8A (ADC D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADCD = function()\n{\n this.regA = this.addByteCarry(this.regD);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x8B (ADC E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADCE = function()\n{\n this.regA = this.addByteCarry(this.regE);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x8C (ADC H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADCH = function()\n{\n this.regA = this.addByteCarry(this.regH);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x8D (ADC L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADCL = function()\n{\n this.regA = this.addByteCarry(this.regL);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x8E (ADC M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADCM = function()\n{\n this.regA = this.addByteCarry(this.getByte(this.getHL()));\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x8F (ADC A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADCA = function()\n{\n this.regA = this.addByteCarry(this.regA);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x90 (SUB B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSUBB = function()\n{\n this.regA = this.subByte(this.regB);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x91 (SUB C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSUBC = function()\n{\n this.regA = this.subByte(this.regC);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x92 (SUB D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSUBD = function()\n{\n this.regA = this.subByte(this.regD);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x93 (SUB E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSUBE = function()\n{\n this.regA = this.subByte(this.regE);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x94 (SUB H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSUBH = function()\n{\n this.regA = this.subByte(this.regH);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x95 (SUB L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSUBL = function()\n{\n this.regA = this.subByte(this.regL);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x96 (SUB M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSUBM = function()\n{\n this.regA = this.subByte(this.getByte(this.getHL()));\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x97 (SUB A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSUBA = function()\n{\n this.regA = this.subByte(this.regA);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x98 (SBB B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSBBB = function()\n{\n this.regA = this.subByteBorrow(this.regB);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x99 (SBB C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSBBC = function()\n{\n this.regA = this.subByteBorrow(this.regC);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x9A (SBB D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSBBD = function()\n{\n this.regA = this.subByteBorrow(this.regD);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x9B (SBB E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSBBE = function()\n{\n this.regA = this.subByteBorrow(this.regE);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x9C (SBB H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSBBH = function()\n{\n this.regA = this.subByteBorrow(this.regH);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x9D (SBB L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSBBL = function()\n{\n this.regA = this.subByteBorrow(this.regL);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0x9E (SBB M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSBBM = function()\n{\n this.regA = this.subByteBorrow(this.getByte(this.getHL()));\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0x9F (SBB A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSBBA = function()\n{\n this.regA = this.subByteBorrow(this.regA);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xA0 (ANA B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opANAB = function()\n{\n this.regA = this.andByte(this.regB);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xA1 (ANA C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opANAC = function()\n{\n this.regA = this.andByte(this.regC);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xA2 (ANA D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opANAD = function()\n{\n this.regA = this.andByte(this.regD);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xA3 (ANA E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opANAE = function()\n{\n this.regA = this.andByte(this.regE);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xA4 (ANA H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opANAH = function()\n{\n this.regA = this.andByte(this.regH);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xA5 (ANA L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opANAL = function()\n{\n this.regA = this.andByte(this.regL);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xA6 (ANA M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opANAM = function()\n{\n this.regA = this.andByte(this.getByte(this.getHL()));\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xA7 (ANA A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opANAA = function()\n{\n this.regA = this.andByte(this.regA);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xA8 (XRA B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXRAB = function()\n{\n this.regA = this.xorByte(this.regB);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xA9 (XRA C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXRAC = function()\n{\n this.regA = this.xorByte(this.regC);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xAA (XRA D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXRAD = function()\n{\n this.regA = this.xorByte(this.regD);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xAB (XRA E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXRAE = function()\n{\n this.regA = this.xorByte(this.regE);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xAC (XRA H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXRAH = function()\n{\n this.regA = this.xorByte(this.regH);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xAD (XRA L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXRAL = function()\n{\n this.regA = this.xorByte(this.regL);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xAE (XRA M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXRAM = function()\n{\n this.regA = this.xorByte(this.getByte(this.getHL()));\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xAF (XRA A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXRAA = function()\n{\n this.regA = this.xorByte(this.regA);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xB0 (ORA B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opORAB = function()\n{\n this.regA = this.orByte(this.regB);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xB1 (ORA C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opORAC = function()\n{\n this.regA = this.orByte(this.regC);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xB2 (ORA D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opORAD = function()\n{\n this.regA = this.orByte(this.regD);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xB3 (ORA E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opORAE = function()\n{\n this.regA = this.orByte(this.regE);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xB4 (ORA H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opORAH = function()\n{\n this.regA = this.orByte(this.regH);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xB5 (ORA L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opORAL = function()\n{\n this.regA = this.orByte(this.regL);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xB6 (ORA M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opORAM = function()\n{\n this.regA = this.orByte(this.getByte(this.getHL()));\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xB7 (ORA A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opORAA = function()\n{\n this.regA = this.orByte(this.regA);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xB8 (CMP B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCMPB = function()\n{\n this.subByte(this.regB);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xB9 (CMP C)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCMPC = function()\n{\n this.subByte(this.regC);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xBA (CMP D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCMPD = function()\n{\n this.subByte(this.regD);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xBB (CMP E)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCMPE = function()\n{\n this.subByte(this.regE);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xBC (CMP H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCMPH = function()\n{\n this.subByte(this.regH);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xBD (CMP L)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCMPL = function()\n{\n this.subByte(this.regL);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xBE (CMP M)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCMPM = function()\n{\n this.subByte(this.getByte(this.getHL()));\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xBF (CMP A)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCMPA = function()\n{\n this.subByte(this.regA);\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xC0 (RNZ)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRNZ = function()\n{\n if (!this.getZF()) {\n this.setPC(this.popWord());\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xC1 (POP B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opPOPB = function()\n{\n this.setBC(this.popWord());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xC2 (JNZ a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opJNZ = function()\n{\n var w = this.getPCWord();\n if (!this.getZF()) this.setPC(w);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xC3 (JMP a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opJMP = function()\n{\n this.setPC(this.getPCWord());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xC4 (CNZ a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCNZ = function()\n{\n var w = this.getPCWord();\n if (!this.getZF()) {\n this.pushWord(this.getPC());\n this.setPC(w);\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xC5 (PUSH B)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opPUSHB = function()\n{\n this.pushWord(this.getBC());\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xC6 (ADI d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opADI = function()\n{\n this.regA = this.addByte(this.getPCByte());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xC7 (RST 0)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRST0 = function()\n{\n this.pushWord(this.getPC());\n this.setPC(0);\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xC8 (RZ)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRZ = function()\n{\n if (this.getZF()) {\n this.setPC(this.popWord());\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xC9 (RET)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRET = function()\n{\n this.setPC(this.popWord());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xCA (JZ a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opJZ = function()\n{\n var w = this.getPCWord();\n if (this.getZF()) this.setPC(w);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xCC (CZ a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCZ = function()\n{\n var w = this.getPCWord();\n if (this.getZF()) {\n this.pushWord(this.getPC());\n this.setPC(w);\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xCD (CALL a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCALL = function()\n{\n var w = this.getPCWord();\n this.pushWord(this.getPC());\n this.setPC(w);\n this.nStepCycles -= 17;\n};\n\n/**\n * op=0xCE (ACI d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opACI = function()\n{\n this.regA = this.addByteCarry(this.getPCByte());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xCF (RST 1)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRST1 = function()\n{\n this.pushWord(this.getPC());\n this.setPC(0x08);\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xD0 (RNC)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRNC = function()\n{\n if (!this.getCF()) {\n this.setPC(this.popWord());\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xD1 (POP D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opPOPD = function()\n{\n this.setDE(this.popWord());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xD2 (JNC a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opJNC = function()\n{\n var w = this.getPCWord();\n if (!this.getCF()) this.setPC(w);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xD3 (OUT d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opOUT = function()\n{\n var port = this.getPCByte();\n this.bus.checkPortOutputNotify(port, 1, this.regA, this.offPC(-2));\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xD4 (CNC a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCNC = function()\n{\n var w = this.getPCWord();\n if (!this.getCF()) {\n this.pushWord(this.getPC());\n this.setPC(w);\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xD5 (PUSH D)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opPUSHD = function()\n{\n this.pushWord(this.getDE());\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xD6 (SUI d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSUI = function()\n{\n this.regA = this.subByte(this.getPCByte());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xD7 (RST 2)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRST2 = function()\n{\n this.pushWord(this.getPC());\n this.setPC(0x10);\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xD8 (RC)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRC = function()\n{\n if (this.getCF()) {\n this.setPC(this.popWord());\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xDA (JC a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opJC = function()\n{\n var w = this.getPCWord();\n if (this.getCF()) this.setPC(w);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xDB (IN d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opIN = function()\n{\n var port = this.getPCByte();\n this.regA = this.bus.checkPortInputNotify(port, 1, this.offPC(-2)) & 0xff;\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xDC (CC a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCC = function()\n{\n var w = this.getPCWord();\n if (this.getCF()) {\n this.pushWord(this.getPC());\n this.setPC(w);\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xDE (SBI d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSBI = function()\n{\n this.regA = this.subByteBorrow(this.getPCByte());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xDF (RST 3)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRST3 = function()\n{\n this.pushWord(this.getPC());\n this.setPC(0x18);\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xE0 (RPO)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRPO = function()\n{\n if (!this.getPF()) {\n this.setPC(this.popWord());\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xE1 (POP H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opPOPH = function()\n{\n this.setHL(this.popWord());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xE2 (JPO a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opJPO = function()\n{\n var w = this.getPCWord();\n if (!this.getPF()) this.setPC(w);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xE3 (XTHL)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXTHL = function()\n{\n var w = this.popWord();\n this.pushWord(this.getHL());\n this.setHL(w);\n this.nStepCycles -= 18;\n};\n\n/**\n * op=0xE4 (CPO a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCPO = function()\n{\n var w = this.getPCWord();\n if (!this.getPF()) {\n this.pushWord(this.getPC());\n this.setPC(w);\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xE5 (PUSH H)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opPUSHH = function()\n{\n this.pushWord(this.getHL());\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xE6 (ANI d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opANI = function()\n{\n this.regA = this.andByte(this.getPCByte());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xE7 (RST 4)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRST4 = function()\n{\n this.pushWord(this.getPC());\n this.setPC(0x20);\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xE8 (RPE)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRPE = function()\n{\n if (this.getPF()) {\n this.setPC(this.popWord());\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xE9 (PCHL)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opPCHL = function()\n{\n this.setPC(this.getHL());\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xEA (JPE a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opJPE = function()\n{\n var w = this.getPCWord();\n if (this.getPF()) this.setPC(w);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xEB (XCHG)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXCHG = function()\n{\n var w = this.getHL();\n this.setHL(this.getDE());\n this.setDE(w);\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xEC (CPE a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCPE = function()\n{\n var w = this.getPCWord();\n if (this.getPF()) {\n this.pushWord(this.getPC());\n this.setPC(w);\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xEE (XRI d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opXRI = function()\n{\n this.regA = this.xorByte(this.getPCByte());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xEF (RST 5)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRST5 = function()\n{\n this.pushWord(this.getPC());\n this.setPC(0x28);\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xF0 (RP)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRP = function()\n{\n if (!this.getSF()) {\n this.setPC(this.popWord());\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xF1 (POP PSW)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opPOPSW = function()\n{\n this.setPSW(this.popWord());\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xF2 (JP a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opJP = function()\n{\n var w = this.getPCWord();\n if (!this.getSF()) this.setPC(w);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xF3 (DI)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opDI = function()\n{\n this.clearIF();\n this.nStepCycles -= 4;\n};\n\n/**\n * op=0xF4 (CP a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCP = function()\n{\n var w = this.getPCWord();\n if (!this.getSF()) {\n this.pushWord(this.getPC());\n this.setPC(w);\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xF5 (PUSH PSW)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opPUPSW = function()\n{\n this.pushWord(this.getPSW());\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xF6 (ORI d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opORI = function()\n{\n this.regA = this.orByte(this.getPCByte());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xF7 (RST 6)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRST6 = function()\n{\n this.pushWord(this.getPC());\n this.setPC(0x30);\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xF8 (RM)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRM = function()\n{\n if (this.getSF()) {\n this.setPC(this.popWord());\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xF9 (SPHL)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opSPHL = function()\n{\n this.setSP(this.getHL());\n this.nStepCycles -= 5;\n};\n\n/**\n * op=0xFA (JM a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opJM = function()\n{\n var w = this.getPCWord();\n if (this.getSF()) this.setPC(w);\n this.nStepCycles -= 10;\n};\n\n/**\n * op=0xFB (EI)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opEI = function()\n{\n this.setIF();\n this.nStepCycles -= 4;\n this.checkINTR();\n};\n\n/**\n * op=0xFC (CM a16)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCM = function()\n{\n var w = this.getPCWord();\n if (this.getSF()) {\n this.pushWord(this.getPC());\n this.setPC(w);\n this.nStepCycles -= 6;\n }\n this.nStepCycles -= 11;\n};\n\n/**\n * op=0xFE (CPI d8)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opCPI = function()\n{\n this.subByte(this.getPCByte());\n this.nStepCycles -= 7;\n};\n\n/**\n * op=0xFF (RST 7)\n *\n * @this {CPUState8080}\n */\nCPUDef8080.opRST7 = function()\n{\n this.pushWord(this.getPC());\n this.setPC(0x38);\n this.nStepCycles -= 11;\n};\n\n/*\n * This 256-entry array of opcode functions is at the heart of the CPU engine: stepCPU(n).\n *\n * It might be worth trying a switch() statement instead, to see how the performance compares,\n * but I suspect that would vary quite a bit across JavaScript engines; for now, I'm putting my\n * money on array lookup.\n */\nCPUDef8080.aOps8080 = [\n /* 0x00-0x03 */ CPUDef8080.opNOP, CPUDef8080.opLXIB, CPUDef8080.opSTAXB, CPUDef8080.opINXB,\n /* 0x04-0x07 */ CPUDef8080.opINRB, CPUDef8080.opDCRB, CPUDef8080.opMVIB, CPUDef8080.opRLC,\n /* 0x08-0x0B */ CPUDef8080.opNOP, CPUDef8080.opDADB, CPUDef8080.opLDAXB, CPUDef8080.opDCXB,\n /* 0x0C-0x0F */ CPUDef8080.opINRC, CPUDef8080.opDCRC, CPUDef8080.opMVIC, CPUDef8080.opRRC,\n /* 0x10-0x13 */ CPUDef8080.opNOP, CPUDef8080.opLXID, CPUDef8080.opSTAXD, CPUDef8080.opINXD,\n /* 0x14-0x17 */ CPUDef8080.opINRD, CPUDef8080.opDCRD, CPUDef8080.opMVID, CPUDef8080.opRAL,\n /* 0x18-0x1B */ CPUDef8080.opNOP, CPUDef8080.opDADD, CPUDef8080.opLDAXD, CPUDef8080.opDCXD,\n /* 0x1C-0x1F */ CPUDef8080.opINRE, CPUDef8080.opDCRE, CPUDef8080.opMVIE, CPUDef8080.opRAR,\n /* 0x20-0x23 */ CPUDef8080.opNOP, CPUDef8080.opLXIH, CPUDef8080.opSHLD, CPUDef8080.opINXH,\n /* 0x24-0x27 */ CPUDef8080.opINRH, CPUDef8080.opDCRH, CPUDef8080.opMVIH, CPUDef8080.opDAA,\n /* 0x28-0x2B */ CPUDef8080.opNOP, CPUDef8080.opDADH, CPUDef8080.opLHLD, CPUDef8080.opDCXH,\n /* 0x2C-0x2F */ CPUDef8080.opINRL, CPUDef8080.opDCRL, CPUDef8080.opMVIL, CPUDef8080.opCMA,\n /* 0x30-0x33 */ CPUDef8080.opNOP, CPUDef8080.opLXISP, CPUDef8080.opSTA, CPUDef8080.opINXSP,\n /* 0x34-0x37 */ CPUDef8080.opINRM, CPUDef8080.opDCRM, CPUDef8080.opMVIM, CPUDef8080.opSTC,\n /* 0x38-0x3B */ CPUDef8080.opNOP, CPUDef8080.opDADSP, CPUDef8080.opLDA, CPUDef8080.opDCXSP,\n /* 0x3C-0x3F */ CPUDef8080.opINRA, CPUDef8080.opDCRA, CPUDef8080.opMVIA, CPUDef8080.opCMC,\n /* 0x40-0x43 */ CPUDef8080.opMOVBB, CPUDef8080.opMOVBC, CPUDef8080.opMOVBD, CPUDef8080.opMOVBE,\n /* 0x44-0x47 */ CPUDef8080.opMOVBH, CPUDef8080.opMOVBL, CPUDef8080.opMOVBM, CPUDef8080.opMOVBA,\n /* 0x48-0x4B */ CPUDef8080.opMOVCB, CPUDef8080.opMOVCC, CPUDef8080.opMOVCD, CPUDef8080.opMOVCE,\n /* 0x4C-0x4F */ CPUDef8080.opMOVCH, CPUDef8080.opMOVCL, CPUDef8080.opMOVCM, CPUDef8080.opMOVCA,\n /* 0x50-0x53 */ CPUDef8080.opMOVDB, CPUDef8080.opMOVDC, CPUDef8080.opMOVDD, CPUDef8080.opMOVDE,\n /* 0x54-0x57 */ CPUDef8080.opMOVDH, CPUDef8080.opMOVDL, CPUDef8080.opMOVDM, CPUDef8080.opMOVDA,\n /* 0x58-0x5B */ CPUDef8080.opMOVEB, CPUDef8080.opMOVEC, CPUDef8080.opMOVED, CPUDef8080.opMOVEE,\n /* 0x5C-0x5F */ CPUDef8080.opMOVEH, CPUDef8080.opMOVEL, CPUDef8080.opMOVEM, CPUDef8080.opMOVEA,\n /* 0x60-0x63 */ CPUDef8080.opMOVHB, CPUDef8080.opMOVHC, CPUDef8080.opMOVHD, CPUDef8080.opMOVHE,\n /* 0x64-0x67 */ CPUDef8080.opMOVHH, CPUDef8080.opMOVHL, CPUDef8080.opMOVHM, CPUDef8080.opMOVHA,\n /* 0x68-0x6B */ CPUDef8080.opMOVLB, CPUDef8080.opMOVLC, CPUDef8080.opMOVLD, CPUDef8080.opMOVLE,\n /* 0x6C-0x6F */ CPUDef8080.opMOVLH, CPUDef8080.opMOVLL, CPUDef8080.opMOVLM, CPUDef8080.opMOVLA,\n /* 0x70-0x73 */ CPUDef8080.opMOVMB, CPUDef8080.opMOVMC, CPUDef8080.opMOVMD, CPUDef8080.opMOVME,\n /* 0x74-0x77 */ CPUDef8080.opMOVMH, CPUDef8080.opMOVML, CPUDef8080.opHLT, CPUDef8080.opMOVMA,\n /* 0x78-0x7B */ CPUDef8080.opMOVAB, CPUDef8080.opMOVAC, CPUDef8080.opMOVAD, CPUDef8080.opMOVAE,\n /* 0x7C-0x7F */ CPUDef8080.opMOVAH, CPUDef8080.opMOVAL, CPUDef8080.opMOVAM, CPUDef8080.opMOVAA,\n /* 0x80-0x83 */ CPUDef8080.opADDB, CPUDef8080.opADDC, CPUDef8080.opADDD, CPUDef8080.opADDE,\n /* 0x84-0x87 */ CPUDef8080.opADDH, CPUDef8080.opADDL, CPUDef8080.opADDM, CPUDef8080.opADDA,\n /* 0x88-0x8B */ CPUDef8080.opADCB, CPUDef8080.opADCC, CPUDef8080.opADCD, CPUDef8080.opADCE,\n /* 0x8C-0x8F */ CPUDef8080.opADCH, CPUDef8080.opADCL, CPUDef8080.opADCM, CPUDef8080.opADCA,\n /* 0x90-0x93 */ CPUDef8080.opSUBB, CPUDef8080.opSUBC, CPUDef8080.opSUBD, CPUDef8080.opSUBE,\n /* 0x94-0x97 */ CPUDef8080.opSUBH, CPUDef8080.opSUBL, CPUDef8080.opSUBM, CPUDef8080.opSUBA,\n /* 0x98-0x9B */ CPUDef8080.opSBBB, CPUDef8080.opSBBC, CPUDef8080.opSBBD, CPUDef8080.opSBBE,\n /* 0x9C-0x9F */ CPUDef8080.opSBBH, CPUDef8080.opSBBL, CPUDef8080.opSBBM, CPUDef8080.opSBBA,\n /* 0xA0-0xA3 */ CPUDef8080.opANAB, CPUDef8080.opANAC, CPUDef8080.opANAD, CPUDef8080.opANAE,\n /* 0xA4-0xA7 */ CPUDef8080.opANAH, CPUDef8080.opANAL, CPUDef8080.opANAM, CPUDef8080.opANAA,\n /* 0xA8-0xAB */ CPUDef8080.opXRAB, CPUDef8080.opXRAC, CPUDef8080.opXRAD, CPUDef8080.opXRAE,\n /* 0xAC-0xAF */ CPUDef8080.opXRAH, CPUDef8080.opXRAL, CPUDef8080.opXRAM, CPUDef8080.opXRAA,\n /* 0xB0-0xB3 */ CPUDef8080.opORAB, CPUDef8080.opORAC, CPUDef8080.opORAD, CPUDef8080.opORAE,\n /* 0xB4-0xB7 */ CPUDef8080.opORAH, CPUDef8080.opORAL, CPUDef8080.opORAM, CPUDef8080.opORAA,\n /* 0xB8-0xBB */ CPUDef8080.opCMPB, CPUDef8080.opCMPC, CPUDef8080.opCMPD, CPUDef8080.opCMPE,\n /* 0xBC-0xBF */ CPUDef8080.opCMPH, CPUDef8080.opCMPL, CPUDef8080.opCMPM, CPUDef8080.opCMPA,\n /* 0xC0-0xC3 */ CPUDef8080.opRNZ, CPUDef8080.opPOPB, CPUDef8080.opJNZ, CPUDef8080.opJMP,\n /* 0xC4-0xC7 */ CPUDef8080.opCNZ, CPUDef8080.opPUSHB, CPUDef8080.opADI, CPUDef8080.opRST0,\n /* 0xC8-0xCB */ CPUDef8080.opRZ, CPUDef8080.opRET, CPUDef8080.opJZ, CPUDef8080.opJMP,\n /* 0xCC-0xCF */ CPUDef8080.opCZ, CPUDef8080.opCALL, CPUDef8080.opACI, CPUDef8080.opRST1,\n /* 0xD0-0xD3 */ CPUDef8080.opRNC, CPUDef8080.opPOPD, CPUDef8080.opJNC, CPUDef8080.opOUT,\n /* 0xD4-0xD7 */ CPUDef8080.opCNC, CPUDef8080.opPUSHD, CPUDef8080.opSUI, CPUDef8080.opRST2,\n /* 0xD8-0xDB */ CPUDef8080.opRC, CPUDef8080.opRET, CPUDef8080.opJC, CPUDef8080.opIN,\n /* 0xDC-0xDF */ CPUDef8080.opCC, CPUDef8080.opCALL, CPUDef8080.opSBI, CPUDef8080.opRST3,\n /* 0xE0-0xE3 */ CPUDef8080.opRPO, CPUDef8080.opPOPH, CPUDef8080.opJPO, CPUDef8080.opXTHL,\n /* 0xE4-0xE7 */ CPUDef8080.opCPO, CPUDef8080.opPUSHH, CPUDef8080.opANI, CPUDef8080.opRST4,\n /* 0xE8-0xEB */ CPUDef8080.opRPE, CPUDef8080.opPCHL, CPUDef8080.opJPE, CPUDef8080.opXCHG,\n /* 0xEC-0xEF */ CPUDef8080.opCPE, CPUDef8080.opCALL, CPUDef8080.opXRI, CPUDef8080.opRST5,\n /* 0xF0-0xF3 */ CPUDef8080.opRP, CPUDef8080.opPOPSW, CPUDef8080.opJP, CPUDef8080.opDI,\n /* 0xF4-0xF7 */ CPUDef8080.opCP, CPUDef8080.opPUPSW, CPUDef8080.opORI, CPUDef8080.opRST6,\n /* 0xF8-0xFB */ CPUDef8080.opRM, CPUDef8080.opSPHL, CPUDef8080.opJM, CPUDef8080.opEI,\n /* 0xFC-0xFF */ CPUDef8080.opCM, CPUDef8080.opCALL, CPUDef8080.opCPI, CPUDef8080.opRST7\n];\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/chipset.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass ChipSet8080 extends Component {\n /**\n * ChipSet8080(parmsChipSet)\n *\n * The ChipSet8080 component has the following component-specific (parmsChipSet) properties:\n *\n * model: eg, \"SI1978\" (should be a member of ChipSet8080.MODELS)\n * swDIP: eg, \"00000000\", where swDIP[0] is DIP0, swDIP[1] is DIP1, etc.\n *\n * @this {ChipSet8080}\n * @param {Object} parmsChipSet\n */\n constructor(parmsChipSet)\n {\n super(\"ChipSet\", parmsChipSet, Messages8080.CHIPSET);\n\n var model = parmsChipSet['model'];\n\n if (model && !ChipSet8080.MODELS[model]) {\n Component.notice(\"Unrecognized ChipSet model: \" + model);\n }\n\n this.config = ChipSet8080.MODELS[model] || {};\n\n this.bSwitches = this.parseDIPSwitches(parmsChipSet['swDIP']);\n\n /*\n * Here, I'm finally getting around to trying the Web Audio API. Fortunately, based on what little I know about\n * sound generation, using the API to make the same noises as the IBM PC speaker seems straightforward.\n *\n * To start, we create an audio context, unless the 'sound' parameter has been explicitly set to false.\n *\n * From:\n *\n * http://developer.apple.com/library/safari/#documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/PlayingandSynthesizingSounds/PlayingandSynthesizingSounds.html\n *\n * \"Similar to how HTML5 canvas requires a context on which lines and curves are drawn, Web Audio requires an audio context\n * on which sounds are played and manipulated. This context will be the parent object of further audio objects to come....\n * Your audio context is typically created when your page initializes and should be long-lived. You can play multiple sounds\n * coming from multiple sources within the same context, so it is unnecessary to create more than one audio context per page.\"\n */\n this.fSpeaker = false;\n if (parmsChipSet['sound']) {\n this.classAudio = this.contextAudio = null;\n if (window) {\n this.classAudio = window['AudioContext'] || window['webkitAudioContext'];\n }\n if (this.classAudio) {\n this.contextAudio = new this.classAudio();\n } else {\n if (DEBUG) this.log(\"AudioContext not available\");\n }\n }\n\n this.setReady();\n }\n\n /**\n * parseDIPSwitches(sBits, bDefault)\n *\n * @this {ChipSet8080}\n * @param {string} sBits describing switch settings\n * @param {number} [bDefault]\n * @return {number|undefined}\n */\n parseDIPSwitches(sBits, bDefault)\n {\n var b = bDefault;\n if (sBits) {\n /*\n * NOTE: We can't use parseInt() with a base of 2, because both bit order and bit sense are reversed.\n */\n b = 0;\n var bit = 0x1;\n for (var i = 0; i < sBits.length; i++) {\n if (sBits.charAt(i) == \"0\") b |= bit;\n bit <<= 1;\n }\n }\n return b;\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {ChipSet8080}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"sw1\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {ChipSet8080}\n * @param {Computer8080} cmp\n * @param {Bus8080} bus\n * @param {CPUState8080} cpu\n * @param {Debugger8080} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.cmp = cmp;\n this.kbd = /** @type {Keyboard8080} */ (cmp.getMachineComponent(\"Keyboard\"));\n this.serial = /** @type {SerialPort8080} */ (cmp.getMachineComponent(\"SerialPort\"));\n this.video = /** @type {Video8080} */ (cmp.getMachineComponent(\"Video\"));\n bus.addPortInputTable(this, this.config.portsInput);\n bus.addPortOutputTable(this, this.config.portsOutput);\n\n if (DEBUGGER) {\n if (dbg) {\n var chipset = this;\n dbg.messageDump(Messages8080.NVR, function onDumpNVR() {\n chipset.dumpNVR();\n });\n }\n }\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {ChipSet8080}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {ChipSet8080}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * dumpNVR()\n *\n * @this {ChipSet8080}\n */\n dumpNVR()\n {\n if (DEBUGGER) {\n var sDump = \"\";\n for (var iWord = 0; iWord < this.aNVRWords.length; iWord++) {\n if (sDump) {\n sDump += (iWord && (iWord % 10)? \", \" : \",\\n\");\n }\n sDump += Str.toHexWord(this.aNVRWords[iWord]);\n }\n this.dbg.println(sDump);\n }\n }\n\n /**\n * reset()\n *\n * @this {ChipSet8080}\n */\n reset()\n {\n if (this.config.INIT && !this.restore(this.config.INIT)) {\n this.notice(\"reset error\");\n }\n }\n\n /**\n * save()\n *\n * This implements save support for the ChipSet component.\n *\n * @this {ChipSet8080}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n switch(this.config.MODEL) {\n case ChipSet8080.SI1978.MODEL:\n state.set(0, [this.bStatus0, this.bStatus1, this.bStatus2, this.wShiftData, this.bShiftCount, this.bSound1, this.bSound2]);\n break;\n case ChipSet8080.VT100.MODEL:\n state.set(0, [this.bBrightness, this.bFlags]);\n state.set(1, [this.bDC011Cols, this.bDC011Rate]);\n state.set(2, [this.bDC012Scroll, this.bDC012Blink, this.bDC012Reverse, this.bDC012Attr]);\n state.set(3, [this.dNVRAddr, this.wNVRData, this.bNVRLatch, this.bNVROut, this.aNVRWords]);\n break;\n }\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the ChipSet component.\n *\n * @this {ChipSet8080}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var a;\n if (data && (a = data[0]) && a.length) {\n switch(this.config.MODEL) {\n case ChipSet8080.SI1978.MODEL:\n this.bStatus0 = a[0];\n this.bStatus1 = a[1];\n this.bStatus2 = a[2];\n this.wShiftData = a[3];\n this.bShiftCount = a[4];\n this.bSound1 = a[5];\n this.bSound2 = a[6];\n return true;\n case ChipSet8080.VT100.MODEL:\n this.bBrightness = a[0];\n this.bFlags = a[1];\n a = data[1];\n this.bDC011Cols = a[0];\n this.bDC011Rate = a[1];\n a = data[2];\n this.bDC012Scroll = a[0];\n this.bDC012Blink = a[1];\n this.bDC012Reverse = a[2];\n this.bDC012Attr = a[3];\n a = data[3];\n this.dNVRAddr = a[0]; // 20-bit address\n this.wNVRData = a[1]; // 14-bit word\n this.bNVRLatch = a[2]; // 1 byte\n this.bNVROut = a[3]; // 1 bit\n this.aNVRWords = a[4]; // 100 14-bit words\n return true;\n }\n }\n return false;\n }\n\n /**\n * start()\n *\n * Notification from the CPU that it's starting.\n *\n * @this {ChipSet8080}\n */\n start()\n {\n /*\n * Currently, all we (may) do with this notification is allow the speaker to make noise.\n */\n }\n\n /**\n * stop()\n *\n * Notification from the CPU that it's stopping.\n *\n * @this {ChipSet8080}\n */\n stop()\n {\n /*\n * Currently, all we (may) do with this notification is prevent the speaker from making noise.\n */\n }\n\n /**\n * updateStatus0(bit, fSet)\n *\n * @this {ChipSet8080}\n * @param {number} bit\n * @param {boolean} fSet\n */\n updateStatus0(bit, fSet)\n {\n this.bStatus0 &= ~bit;\n if (fSet) this.bStatus0 |= bit;\n }\n\n /**\n * updateStatus1(bit, fSet)\n *\n * @this {ChipSet8080}\n * @param {number} bit\n * @param {boolean} fSet\n */\n updateStatus1(bit, fSet)\n {\n this.bStatus1 &= ~bit;\n if (fSet) this.bStatus1 |= bit;\n }\n\n /**\n * updateStatus2(bit, fSet)\n *\n * @this {ChipSet8080}\n * @param {number} bit\n * @param {boolean} fSet\n */\n updateStatus2(bit, fSet)\n {\n this.bStatus2 &= ~bit;\n if (fSet) this.bStatus2 |= bit;\n }\n\n /**\n * inSIStatus0(port, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x00)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inSIStatus0(port, addrFrom)\n {\n var b = this.bStatus0;\n this.printMessageIO(port, null, addrFrom, \"STATUS0\", b, true);\n return b;\n }\n\n /**\n * inSIStatus1(port, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x01)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inSIStatus1(port, addrFrom)\n {\n var b = this.bStatus1;\n this.printMessageIO(port, null, addrFrom, \"STATUS1\", b, true);\n return b;\n }\n\n /**\n * inSIStatus2(port, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x02)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inSIStatus2(port, addrFrom)\n {\n var b = this.bStatus2;\n this.printMessageIO(port, null, addrFrom, \"STATUS2\", b, true);\n return b;\n }\n\n /**\n * inSIShiftResult(port, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x03)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inSIShiftResult(port, addrFrom)\n {\n var b = (this.wShiftData >> (8 - this.bShiftCount)) & 0xff;\n this.printMessageIO(port, null, addrFrom, \"SHIFT.RESULT\", b, true);\n return b;\n }\n\n /**\n * outSIShiftCount(port, b, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x02)\n * @param {number} b\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outSIShiftCount(port, b, addrFrom)\n {\n this.printMessageIO(port, b, addrFrom, \"SHIFT.COUNT\", null, true);\n this.bShiftCount = b;\n }\n\n /**\n * outSISound1(port, b, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x03)\n * @param {number} b\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outSISound1(port, b, addrFrom)\n {\n this.printMessageIO(port, b, addrFrom, \"SOUND1\", null, true);\n this.bSound1 = b;\n }\n\n /**\n * outSIShiftData(port, b, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x04)\n * @param {number} b\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outSIShiftData(port, b, addrFrom)\n {\n this.printMessageIO(port, b, addrFrom, \"SHIFT.DATA\", null, true);\n this.wShiftData = (b << 8) | (this.wShiftData >> 8);\n }\n\n /**\n * outSISound2(port, b, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x05)\n * @param {number} b\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outSISound2(port, b, addrFrom)\n {\n this.printMessageIO(port, b, addrFrom, \"SOUND2\", null, true);\n this.bSound2 = b;\n }\n\n /**\n * outSIWatchdog(port, b, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x06)\n * @param {number} b\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outSIWatchdog(port, b, addrFrom)\n {\n this.printMessageIO(port, b, addrFrom, \"WATCHDOG\", null, true);\n }\n\n /**\n * getVT100LBA(iBit)\n *\n * Returns the state of the requested (simulated) LBA bit.\n *\n * NOTE: This is currently only used to obtain LBA7, which we approximate with the slightly faster approach\n * of masking bit 6 of the CPU cycle count (see the DC011 discussion above). This will result in a shorter LBA7\n * period than if we divided the cycle count by 88, but a shorter LBA7 period is probably helpful in terms of\n * overall performance.\n *\n * @param {number} iBit\n * @return {number}\n */\n getVT100LBA(iBit)\n {\n return (this.cpu.getCycles() & (1 << (iBit - 1))) << 1;\n }\n\n /**\n * getNVRAddr()\n *\n * @return {number}\n */\n getNVRAddr()\n {\n var i;\n var tens = 0, ones = 0;\n var addr = ~this.dNVRAddr;\n for (i = 0; i < 10; i++) {\n if (addr & 0x1) tens = 9-i;\n addr >>= 1;\n }\n for (i = 0; i < 10; i++) {\n if (addr & 0x1) ones = 9-i;\n addr >>= 1;\n }\n addr = tens*10 + ones;\n\n return addr;\n }\n\n /**\n * doNVRCommand()\n */\n doNVRCommand()\n {\n var addr, data;\n var bit = this.bNVRLatch & 0x1;\n var bCmd = (this.bNVRLatch >> 1) & 0x7;\n\n switch(bCmd) {\n case ChipSet8080.VT100.NVR.CMD.STANDBY:\n break;\n\n case ChipSet8080.VT100.NVR.CMD.ACCEPT_ADDR:\n this.dNVRAddr = (this.dNVRAddr << 1) | bit;\n break;\n\n case ChipSet8080.VT100.NVR.CMD.ERASE:\n addr = this.getNVRAddr();\n this.aNVRWords[addr] = ChipSet8080.VT100.NVR.WORDMASK;\n this.printMessage(\"doNVRCommand(): erase data at addr \" + Str.toHexWord(addr));\n break;\n\n case ChipSet8080.VT100.NVR.CMD.ACCEPT_DATA:\n this.wNVRData = (this.wNVRData << 1) | bit;\n break;\n\n case ChipSet8080.VT100.NVR.CMD.WRITE:\n addr = this.getNVRAddr();\n data = this.wNVRData & ChipSet8080.VT100.NVR.WORDMASK;\n this.aNVRWords[addr] = data;\n this.printMessage(\"doNVRCommand(): write data \" + Str.toHexWord(data) + \" to addr \" + Str.toHexWord(addr));\n break;\n\n case ChipSet8080.VT100.NVR.CMD.READ:\n addr = this.getNVRAddr();\n data = this.aNVRWords[addr];\n /*\n * If we don't explicitly initialize aNVRWords[], pretend any uninitialized words contains WORDMASK.\n */\n if (data == null) data = ChipSet8080.VT100.NVR.WORDMASK;\n this.wNVRData = data;\n this.printMessage(\"doNVRCommand(): read data \" + Str.toHexWord(data) + \" from addr \" + Str.toHexWord(addr));\n break;\n\n case ChipSet8080.VT100.NVR.CMD.SHIFT_OUT:\n this.wNVRData <<= 1;\n /*\n * Since WORDMASK is 0x3fff, this will mask the shifted data with 0x4000, which is the bit we want to isolate.\n */\n this.bNVROut = this.wNVRData & (ChipSet8080.VT100.NVR.WORDMASK + 1);\n break;\n\n default:\n this.printMessage(\"doNVRCommand(): unrecognized command \" + Str.toHexByte(bCmd));\n break;\n }\n }\n\n /**\n * inVT100Flags(port, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x42)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inVT100Flags(port, addrFrom)\n {\n var b = this.bFlags;\n\n /*\n * The NVR_CLK bit is driven by LBA7 (ie, bit 7 from Line Buffer Address generation); see the DC011 discussion above.\n */\n b &= ~ChipSet8080.VT100.FLAGS.NVR_CLK;\n if (this.getVT100LBA(7)) {\n b |= ChipSet8080.VT100.FLAGS.NVR_CLK;\n if (b != this.bFlags) {\n this.doNVRCommand();\n }\n }\n\n b &= ~ChipSet8080.VT100.FLAGS.NVR_DATA;\n if (this.bNVROut) {\n b |= ChipSet8080.VT100.FLAGS.NVR_DATA;\n }\n\n b &= ~ChipSet8080.VT100.FLAGS.KBD_XMIT;\n if (this.kbd && this.kbd.isVT100TransmitterReady()) {\n b |= ChipSet8080.VT100.FLAGS.KBD_XMIT;\n }\n\n b &= ~ChipSet8080.VT100.FLAGS.UART_XMIT;\n if (this.serial && this.serial.isTransmitterReady()) {\n b |= ChipSet8080.VT100.FLAGS.UART_XMIT;\n }\n\n this.bFlags = b;\n this.printMessageIO(port, null, addrFrom, \"FLAGS\", b);\n return b;\n }\n\n /**\n * outVT100Brightness(port, b, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x42)\n * @param {number} b\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outVT100Brightness(port, b, addrFrom)\n {\n this.printMessageIO(port, b, addrFrom, \"BRIGHTNESS\");\n this.bBrightness = b;\n }\n\n /**\n * outVT100NVRLatch(port, b, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0x62)\n * @param {number} b\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outVT100NVRLatch(port, b, addrFrom)\n {\n this.printMessageIO(port, b, addrFrom, \"NVR.LATCH\");\n this.bNVRLatch = b;\n }\n\n /**\n * outVT100DC012(port, b, addrFrom)\n *\n * TODO: Consider whether we should disable any interrupts (eg, vertical retrace) until\n * this port is initialized at runtime.\n *\n * @this {ChipSet8080}\n * @param {number} port (0xA2)\n * @param {number} b\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outVT100DC012(port, b, addrFrom)\n {\n this.printMessageIO(port, b, addrFrom, \"DC012\");\n\n var bOpt = b & 0x3;\n var bCmd = (b >> 2) & 0x3;\n switch(bCmd) {\n case 0x0:\n this.bDC012Scroll = (this.bDC012Scroll & ~0x3) | bOpt;\n break;\n case 0x1:\n this.bDC012Scroll = (this.bDC012Scroll & ~0xC) | (bOpt << 2);\n if (this.video) this.video.updateScrollOffset(this.bDC012Scroll);\n break;\n case 0x2:\n switch(bOpt) {\n case 0x0:\n this.bDC012Blink = ~this.bDC012Blink;\n break;\n case 0x1:\n // TODO: Clear vertical frequency interrupt?\n break;\n case 0x2:\n case 0x3:\n this.bDC012Reverse = 0x3 - bOpt;\n break;\n }\n break;\n case 0x3:\n this.bDC012Attr = bOpt;\n break;\n }\n }\n\n /**\n * outVT100DC011(port, b, addrFrom)\n *\n * @this {ChipSet8080}\n * @param {number} port (0xC2)\n * @param {number} b\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outVT100DC011(port, b, addrFrom)\n {\n this.printMessageIO(port, b, addrFrom, \"DC011\");\n if (b & ChipSet8080.VT100.DC011.RATE60) {\n b &= ChipSet8080.VT100.DC011.RATE50;\n if (this.bDC011Rate != b) {\n this.bDC011Rate = b;\n if (this.video) {\n this.video.updateRate(this.bDC011Rate == ChipSet8080.VT100.DC011.RATE50? 50 : 60);\n }\n }\n } else {\n b &= ChipSet8080.VT100.DC011.COLS132;\n if (this.bDC011Cols != b) {\n this.bDC011Cols = b;\n if (this.video) {\n var nCols = (this.bDC011Cols == ChipSet8080.VT100.DC011.COLS132? 132 : 80);\n var nRows = (nCols > 80 && (this.bFlags & ChipSet8080.VT100.FLAGS.NO_AVO)? 14 : 24);\n this.video.updateDimensions(nCols, nRows);\n }\n }\n }\n }\n\n /**\n * ChipSet8080.init()\n *\n * This function operates on every HTML element of class \"chipset\", extracting the\n * JSON-encoded parameters for the ChipSet constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a ChipSet component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeChipSet = Component.getElementsByClass(document, PC8080.APPCLASS, \"chipset\");\n for (var iChip = 0; iChip < aeChipSet.length; iChip++) {\n var eChipSet = aeChipSet[iChip];\n var parmsChipSet = Component.getComponentParms(eChipSet);\n var chipset = new ChipSet8080(parmsChipSet);\n Component.bindComponentControls(chipset, eChipSet, PC8080.APPCLASS);\n }\n }\n}\n\n/*\n * NOTE: The STATUS1 port could have been handled entirely by the Keyboard component, but it was just as easy\n * to create a simple ChipSet interface, updateStatus1(), that the Keyboard calls whenever it wants to simulate a\n * button press or release. It's a six-of-one, half-a-dozen-of-another choice, since technically, Space Invaders\n * doesn't have a keyboard.\n */\nChipSet8080.SI1978 = {\n MODEL: 1978.1,\n STATUS0: { // NOTE: STATUS0 not used by the SI1978 ROMs; refer to STATUS1 instead\n PORT: 0,\n DIP4: 0x01, // self-test request at power up?\n FIRE: 0x10, // 1 = fire\n LEFT: 0x20, // 1 = left\n RIGHT: 0x40, // 1 = right\n PORT7: 0x80, // some connection to (undocumented) port 7\n ALWAYS_SET: 0x0E // always set\n },\n STATUS1: {\n PORT: 1,\n CREDIT: 0x01, // credit (coin slot)\n P2: 0x02, // 1 = 2P start\n P1: 0x04, // 1 = 1P start\n P1_FIRE: 0x10, // 1 = fire (P1 fire if cocktail machine?)\n P1_LEFT: 0x20, // 1 = left (P1 left if cocktail machine?)\n P1_RIGHT: 0x40, // 1 = right (P1 right if cocktail machine?)\n ALWAYS_SET: 0x08 // always set\n },\n STATUS2: {\n PORT: 2,\n DIP3_5: 0x03, // 00 = 3 ships, 01 = 4 ships, 10 = 5 ships, 11 = 6 ships\n TILT: 0x04, // 1 = tilt detected\n DIP6: 0x08, // 0 = extra ship at 1500, 1 = extra ship at 1000\n P2_FIRE: 0x10, // 1 = P2 fire (cocktail machines only?)\n P2_LEFT: 0x20, // 1 = P2 left (cocktail machines only?)\n P2_RIGHT: 0x40, // 1 = P2 right (cocktail machines only?)\n DIP7: 0x80, // 0 = display coin info on demo (\"attract\") screen\n ALWAYS_SET: 0x00\n },\n SHIFT_RESULT: { // bits 0-7 of barrel shifter result\n PORT: 3\n },\n SHIFT_COUNT: {\n PORT: 2,\n MASK: 0x07\n },\n SOUND1: {\n PORT: 3,\n UFO: 0x01,\n SHOT: 0x02,\n PDEATH: 0x04,\n IDEATH: 0x08,\n EXPLAY: 0x10,\n AMP_ENABLE: 0x20\n },\n SHIFT_DATA: {\n PORT: 4\n },\n SOUND2: {\n PORT: 5,\n FLEET1: 0x01,\n FLEET2: 0x02,\n FLEET3: 0x04,\n FLEET4: 0x08,\n UFO_HIT: 0x10\n }\n};\n\n/*\n * One of the many chips in the VT100 is an 8224, which operates at 24.8832MHz. That frequency is divided by 9\n * to yield a 361.69ns clock period for the 8080 CPU, which means (in theory) that the CPU is running at 2.76Mhz.\n *\n * Hence the CPU component in the VT100's machine.xml should be defined as:\n *\n * <cpu id=\"cpu8080\" model=\"8080\" cycles=\"2764800\"/>\n *\n * WARNING: The choice of clock speed has an effect on other simulated VT100 circuits; see the DC011 Timing Chip\n * discussion below, along with the getVT100LBA() function.\n *\n * For reference, here is a list of all the VT100 I/O ports, from /devices/pc8080/machine/vt100/debugger/README.md,\n * which in turn comes from p. 4-17 of the VT100 Technical Manual (July 1982):\n *\n * READ OR WRITE\n * 00H PUSART data bus\n * 01H PUSART command port\n *\n * WRITE ONLY (Decoded with I/O WR L)\n * 02H Baud rate generator\n * 42H Brightness D/A latch\n * 62H NVR latch\n * 82H Keyboard UART data input [used to update the Keyboard Status Byte -JP]\n * A2H Video processor DC012\n * C2H Video processor DC011\n * E2H Graphics port\n *\n * READ ONLY (Decoded with I/O RD L)\n * 22H Modem buffer\n * 42H Flags buffer\n * 82H Keyboard UART data output\n *\n * Most of these are handled by the ChipSet component, since it exists as sort of a \"catch-all\" component,\n * but some are more appropriately handled by other components; eg, port 0x82 is handled by the Keyboard component,\n * so it's defined there instead of here.\n */\nChipSet8080.VT100 = {\n MODEL: 100.0,\n FLAGS: {\n PORT: 0x42, // read-only\n UART_XMIT: 0x01, // PUSART transmit buffer empty if SET\n NO_AVO: 0x02, // AVO present if CLEAR\n NO_GFX: 0x04, // VT125 graphics board present if CLEAR\n OPTION: 0x08, // OPTION present if SET\n NO_EVEN: 0x10, // EVEN FIELD active if CLEAR\n NVR_DATA: 0x20, // NVR DATA if SET\n NVR_CLK: 0x40, // NVR CLOCK if SET\n KBD_XMIT: 0x80 // KBD transmit buffer empty if SET\n },\n BRIGHTNESS: {\n PORT: 0x42, // write-only\n INIT: 0x00 // for lack of a better guess\n },\n /*\n * DC011 is referred to as a Timing Chip.\n *\n * As p. 4-55 (105) of the VT100 Technical Manual (July 1982) explains:\n *\n * The DCO11 is a custom designed bipolar circuit that provides most of the timing signals required by the\n * video processor. Internal counters divide the output of a 24.0734 MHz oscillator (located elsewhere on the\n * terminal controller module) into the lower frequencies that define dot, character, scan, and frame timing.\n * The counters are programmable through various input pins to control the number of characters per line,\n * the frequency at which the screen is refreshed, and whether the display is interlaced or noninterlaced.\n * These parameters can be controlled through SET-UP mode or by the host.\n *\n * Table 4-6-1: Video Mode Selection (Write Address 0xC2)\n *\n * D5 D4 Configuration\n * -- -- -------------\n * 0 0 80-column mode, interlaced\n * 0 1 132-column mode, interlaced\n * 1 0 60Hz, non-interlaced\n * 1 1 50Hz, non-interlaced\n *\n * On p. 4-56, the DC011 Block Diagram shows 8 outputs labeled LBA0 through LBA7. From p. 4-61:\n *\n * Several of the LBAs are used as general purpose clocks in the VT100. LBA3 and LBA4 are used to generate\n * timing for the keyboard. These signals satisfy the keyboard's requirement of two square-waves, one twice the\n * frequency of the other, even though every 16th transition is delayed (the second stage of the horizontal\n * counter divides by 17, not 16). LBA7 is used by the nonvolatile RAM.\n *\n * And on p. 4-62, timings are provided for the LBA0 through LBA7; in particular:\n *\n * LBA6: 16.82353us (when LBA6 is low, for a period of 33.64706us)\n * LBA7: 31.77778us (when LBA7 is high, for a period of 63.55556us)\n *\n * If we assume that the CPU cycle count increments once every 361.69ns, it will increment roughly 88 times every\n * time LBA7 toggles. So we can divide the CPU cycle count by 88 and set LBA to the low bit of that truncated\n * result. An even faster (but less accurate) solution would be to mask bit 6 of the CPU cycle count, which will\n * doesn't change until the count has been incremented 64 times. See getVT100LBA() for the chosen implementation.\n */\n DC011: { // generates Line Buffer Addresses (LBAs) for the Video Processor\n PORT: 0xC2, // write-only\n COLS80: 0x00,\n COLS132: 0x10,\n RATE60: 0x20,\n RATE50: 0x30,\n INITCOLS: 0x00, // ie, COLS80\n INITRATE: 0x20 // ie, RATE60\n },\n /*\n * DC012 is referred to as a Control Chip.\n *\n * As p. 4-67 (117) of the VT100 Technical Manual (July 1982) explains:\n *\n * The DCO12 performs three main functions.\n *\n * 1. Scan count generation. This involves two counters, a multiplexer to switch between the counters,\n * double-height logic, scroll and line attribute latches, and various logic controlling switching between\n * the two counters. This is the biggest part of the chip. It includes all scrolling, double-height logic,\n * and feeds into the underline and hold request circuits.\n *\n * 2. Generation of HOLD REQUEST. This uses information from the scan counters and the scrolling logic to\n * decide when to generate HOLD REQUEST.\n *\n * 3. Video modifications: dot stretching, blanking, addition of attributes to video outputs, and multiple\n * intensity levels.\n *\n * The input decoder accepts a 4-bit command from the microprocessor when VID WR 2 L is asserted. Table 4-6-2\n * lists the commands.\n *\n * D3 D2 D1 D0 Function\n * -- -- -- -- --------\n * 0 0 0 0 Load low order scroll latch = 00\n * 0 0 0 1 Load low order scroll latch = 01\n * 0 0 1 0 Load low order scroll latch = 10\n * 0 0 1 1 Load low order scroll latch = 11\n *\n * 0 1 0 0 Load high order scroll latch = 00\n * 0 1 0 1 Load high order scroll latch = 01\n * 0 1 1 0 Load high order scroll latch = 10\n * 0 1 1 1 Load high order scroll latch = 11 (not used)\n *\n * 1 0 0 0 Toggle blink flip-flop\n * 1 0 0 1 Clear vertical frequency interrupt\n *\n * 1 0 1 0 Set reverse field on\n * 1 0 1 1 Set reverse field off\n *\n * 1 1 0 0 Set basic attribute to underline*\n * 1 1 0 1 Set basic attribute to reverse video*\n * 1 1 1 0 Reserved for future specification*\n * 1 1 1 1 Reserved for future specification*\n *\n * *These functions also clear blink flip-flop.\n */\n DC012: { // generates scan counts for the Video Processor\n PORT: 0xA2, // write-only\n SCROLL_LO: 0x00,\n INITSCROLL: 0x00,\n INITBLINK: 0x00,\n INITREVERSE:0x00,\n INITATTR: 0x00\n },\n /*\n * ER1400 Non-Volatile RAM (NVR) Chip Definitions\n */\n NVR: {\n LATCH: {\n PORT: 0x62 // write-only\n },\n CMD: {\n ACCEPT_DATA: 0x0,\n ACCEPT_ADDR: 0x1,\n SHIFT_OUT: 0x2,\n WRITE: 0x4,\n ERASE: 0x5,\n READ: 0x6,\n STANDBY: 0x7\n },\n WORDMASK: 0x3fff // NVR words are 14-bit\n /*\n * The Technical Manual, p. 4-18, also notes that \"Early VT100s can disable the receiver interrupt by\n * programming D4 in the NVR latch. However, this is never used by the VT100.\"\n */\n }\n};\n\n/*\n * Supported models and their configurations\n */\nChipSet8080.MODELS = {\n \"SI1978\": ChipSet8080.SI1978,\n \"VT100\": ChipSet8080.VT100\n};\n\nChipSet8080.SI1978.INIT = [\n [\n ChipSet8080.SI1978.STATUS0.ALWAYS_SET,\n ChipSet8080.SI1978.STATUS1.ALWAYS_SET,\n ChipSet8080.SI1978.STATUS2.ALWAYS_SET,\n 0, 0, 0, 0\n ]\n];\n\nChipSet8080.VT100.INIT = [\n [\n ChipSet8080.VT100.BRIGHTNESS.INIT,\n ChipSet8080.VT100.FLAGS.NO_AVO | ChipSet8080.VT100.FLAGS.NO_GFX\n ],\n [\n ChipSet8080.VT100.DC011.INITCOLS,\n ChipSet8080.VT100.DC011.INITRATE\n ],\n [\n ChipSet8080.VT100.DC012.INITSCROLL,\n ChipSet8080.VT100.DC012.INITBLINK,\n ChipSet8080.VT100.DC012.INITREVERSE,\n ChipSet8080.VT100.DC012.INITATTR\n ],\n [\n 0, 0, 0, 0,\n [\n /*\n * The following array contains the data we use to initialize all (100) words of NVR (Non-Volatile RAM).\n *\n * I used to initialize every word to 0x3ff, as if the NVR had been freshly erased, but that causes the\n * firmware to (attempt to) beep and then display an error code (2). As the DEC Technical Manual says:\n *\n * If the NVR fails, the bell sounds several times to inform the operator, and then default settings\n * stored in the ROM allow the terminal to work.\n *\n * but I think what they meant to say is that default settings are stored in the RAM copy of NVR. So then\n * I went into SET-UP, pressed SHIFT-S to save those settings back to NVR, and then used the PC8080 debugger\n * \"d nvr\" command to dump the NVR contents. The results are below.\n *\n * The first dump actually contains only two modifications to the factory defaults: enabling ONLINE instead\n * of LOCAL operation, and turning ANSI support ON. The second dump is unmodified (the TRUE factory defaults).\n *\n * By making selective changes, you can discern where the bits for certain features are stored. For example,\n * smooth-scrolling is apparently controlled by bit 7 of the word at offset 0x2B (and is ON by default in\n * the factory settings). And it's likely that the word at offset 0x32 (ie, the last word that's not zero)\n * is the NVR checksum.\n */\n 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80,\n 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80,\n 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80,\n 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E00,\n 0x2E08, 0x2E8E, 0x2E00, 0x2ED0, 0x2E70, 0x2E00, 0x2E20, 0x2E00, 0x2EE0, 0x2EE0,\n 0x2E7D, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,\n 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,\n 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,\n 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,\n 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000\n ],\n [\n /*\n * The TRUE factory defaults (not currently used for anything; they're just here for reference, wasting space....)\n */\n 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80,\n 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80,\n 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80,\n 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E80, 0x2E00,\n 0x2E08, 0x2E8E, 0x2E20, 0x2ED0, 0x2E50, 0x2E00, 0x2E20, 0x2E00, 0x2EE0, 0x2EE0,\n 0x2E69, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,\n 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,\n 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,\n 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,\n 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000\n ]\n ]\n];\n\n/*\n * Port notification tables\n */\nChipSet8080.SI1978.portsInput = {\n 0x00: ChipSet8080.prototype.inSIStatus0,\n 0x01: ChipSet8080.prototype.inSIStatus1,\n 0x02: ChipSet8080.prototype.inSIStatus2,\n 0x03: ChipSet8080.prototype.inSIShiftResult\n};\n\nChipSet8080.SI1978.portsOutput = {\n 0x02: ChipSet8080.prototype.outSIShiftCount,\n 0x03: ChipSet8080.prototype.outSISound1,\n 0x04: ChipSet8080.prototype.outSIShiftData,\n 0x05: ChipSet8080.prototype.outSISound2,\n 0x06: ChipSet8080.prototype.outSIWatchdog\n};\n\nChipSet8080.VT100.portsInput = {\n 0x42: ChipSet8080.prototype.inVT100Flags\n};\n\nChipSet8080.VT100.portsOutput = {\n 0x42: ChipSet8080.prototype.outVT100Brightness,\n 0x62: ChipSet8080.prototype.outVT100NVRLatch,\n 0xA2: ChipSet8080.prototype.outVT100DC012,\n 0xC2: ChipSet8080.prototype.outVT100DC011\n};\n\n/*\n * Initialize every ChipSet module on the page.\n */\nWeb.onInit(ChipSet8080.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/rom.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass ROM8080 extends Component {\n /**\n * ROM8080(parmsROM)\n *\n * The ROM8080 component expects the following (parmsROM) properties:\n *\n * addr: physical address of ROM\n * size: amount of ROM, in bytes\n * alias: physical alias address (null if none)\n * file: name of ROM data file\n *\n * NOTE: The ROM data will not be copied into place until the Bus is ready (see initBus()) AND the\n * ROM data file has finished loading (see doneLoad()).\n *\n * Also, while the size parameter may seem redundant, I consider it useful to confirm that the ROM you received\n * is the ROM you expected.\n *\n * @this {ROM8080}\n * @param {Object} parmsROM\n */\n constructor(parmsROM)\n {\n super(\"ROM\", parmsROM);\n\n this.abROM = null;\n this.addrROM = parmsROM['addr'];\n this.sizeROM = parmsROM['size'];\n\n /*\n * The new 'alias' property can now be EITHER a single physical address (like 'addr') OR an array of\n * physical addresses; eg:\n *\n * [0xf0000,0xffff0000,0xffff8000]\n *\n * We could have overloaded 'addr' to accomplish the same thing, but I think it's better to have any\n * aliased locations listed under a separate property.\n *\n * Most ROMs are not aliased, in which case the 'alias' property should have the default value of null.\n */\n this.addrAlias = parmsROM['alias'];\n\n this.sFilePath = parmsROM['file'];\n this.sFileName = Str.getBaseName(this.sFilePath);\n\n if (this.sFilePath) {\n var sFileURL = this.sFilePath;\n if (DEBUG) this.log('load(\"' + sFileURL + '\")');\n /*\n * If the selected ROM file has a \".json\" extension, then we assume it's pre-converted\n * JSON-encoded ROM data, so we load it as-is; ditto for ROM files with a \".hex\" extension.\n * Otherwise, we ask our server-side ROM converter to return the file in a JSON-compatible format.\n */\n var sFileExt = Str.getExtension(this.sFileName);\n if (sFileExt != DumpAPI.FORMAT.JSON && sFileExt != DumpAPI.FORMAT.HEX) {\n sFileURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFilePath + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES + '&' + DumpAPI.QUERY.DECIMAL + '=true';\n }\n var rom = this;\n Web.getResource(sFileURL, null, true, function(sURL, sResponse, nErrorCode) {\n rom.doneLoad(sURL, sResponse, nErrorCode);\n });\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {ROM8080}\n * @param {Computer8080} cmp\n * @param {Bus8080} bus\n * @param {CPUState8080} cpu\n * @param {Debugger8080} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.copyROM();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {ROM8080}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (this.aSymbols) {\n if (this.dbg) {\n this.dbg.addSymbols(this.id, this.addrROM, this.sizeROM, this.aSymbols);\n }\n /*\n * Our only role in the handling of symbols is to hand them off to the Debugger at our\n * first opportunity. Now that we've done that, our copy of the symbols, if any, are toast.\n */\n delete this.aSymbols;\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * Since we have nothing to do on powerDown(), and no state to return, we could simply omit\n * this function. But it doesn't hurt anything, and maybe we'll use our state to save something\n * useful down the road, like user-defined symbols (ie, symbols that the Debugger may have\n * created, above and beyond those symbols we automatically loaded, if any, along with the ROM).\n *\n * @this {ROM8080}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return true;\n }\n\n /**\n * doneLoad(sURL, sROMData, nErrorCode)\n *\n * @this {ROM8080}\n * @param {string} sURL\n * @param {string} sROMData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n doneLoad(sURL, sROMData, nErrorCode)\n {\n if (nErrorCode) {\n this.notice(\"Unable to load system ROM (error \" + nErrorCode + \": \" + sURL + \")\");\n return;\n }\n\n Component.addMachineResource(this.idMachine, sURL, sROMData);\n\n if (sROMData.charAt(0) == \"[\" || sROMData.charAt(0) == \"{\") {\n try {\n /*\n * The most likely source of any exception will be here: parsing the JSON-encoded ROM data.\n */\n var rom = eval(\"(\" + sROMData + \")\");\n var ab = rom['bytes'];\n /*\n * Resource 'longs' should always be 32-bit DWORD values, whereas 'data' bit lengths\n * will vary according to the machine architecture for which the resource was designed.\n */\n var adw = rom['longs'] || rom['data'];\n\n if (ab) {\n this.abROM = ab;\n }\n else if (adw) {\n /*\n * Convert all the DWORDs into BYTEs, so that subsequent code only has to deal with abROM.\n */\n this.abROM = new Array(adw.length * 4);\n for (var idw = 0, ib = 0; idw < adw.length; idw++) {\n this.abROM[ib++] = adw[idw] & 0xff;\n this.abROM[ib++] = (adw[idw] >> 8) & 0xff;\n this.abROM[ib++] = (adw[idw] >> 16) & 0xff;\n this.abROM[ib++] = (adw[idw] >> 24) & 0xff;\n }\n }\n else {\n this.abROM = rom;\n }\n\n this.aSymbols = rom['symbols'];\n\n if (!this.abROM.length) {\n Component.error(\"Empty ROM: \" + sURL);\n return;\n }\n else if (this.abROM.length == 1) {\n Component.error(this.abROM[0]);\n return;\n }\n } catch (e) {\n this.notice(\"ROM data error: \" + e.message);\n return;\n }\n }\n else {\n /*\n * Parse the ROM data manually; we assume it's in \"simplified\" hex form (a series of hex byte-values\n * separated by whitespace).\n */\n var sHexData = sROMData.replace(/\\n/gm, \" \").replace(/ +$/, \"\");\n var asHexData = sHexData.split(\" \");\n this.abROM = new Array(asHexData.length);\n for (var i = 0; i < asHexData.length; i++) {\n this.abROM[i] = Str.parseInt(asHexData[i], 16);\n }\n }\n this.copyROM();\n }\n\n /**\n * copyROM()\n *\n * This function is called by both initBus() and doneLoad(), but it cannot copy the the ROM data into place\n * until after initBus() has received the Bus component AND doneLoad() has received the abROM data. When both\n * those criteria are satisfied, the component becomes \"ready\".\n *\n * @this {ROM8080}\n */\n copyROM()\n {\n if (!this.isReady()) {\n if (!this.sFilePath) {\n this.setReady();\n }\n else if (this.abROM && this.bus) {\n /*\n * If no explicit size was specified, then use whatever the actual size is.\n */\n if (!this.sizeROM) {\n this.sizeROM = this.abROM.length;\n }\n if (this.abROM.length != this.sizeROM) {\n /*\n * Note that setError() sets the component's fError flag, which in turn prevents setReady() from\n * marking the component ready. TODO: Revisit this decision. On the one hand, it sounds like a\n * good idea to stop the machine in its tracks whenever a setError() occurs, but there may also be\n * times when we'd like to forge ahead anyway.\n */\n this.setError(\"ROM size (\" + Str.toHexLong(this.abROM.length) + \") does not match specified size (\" + Str.toHexLong(this.sizeROM) + \")\");\n }\n else if (this.addROM(this.addrROM)) {\n\n var aliases = [];\n if (typeof this.addrAlias == \"number\") {\n aliases.push(this.addrAlias);\n } else if (this.addrAlias != null && this.addrAlias.length) {\n aliases = this.addrAlias;\n }\n for (var i = 0; i < aliases.length; i++) {\n this.cloneROM(aliases[i]);\n }\n /*\n * We used to hang onto the original ROM data so that we could restore any bytes the CPU overwrote,\n * using memory write-notification handlers, but with the introduction of read-only memory blocks, that's\n * no longer necessary.\n *\n * TODO: Consider an option to retain the ROM data, and give the user some way of restoring ROMs.\n * That may be useful for \"resumable\" machines that save/restore all dirty block of memory, regardless\n * whether they're ROM or RAM. However, the only way to modify a machine's ROM is with the Debugger,\n * and Debugger users should know better.\n */\n delete this.abROM;\n }\n this.setReady();\n }\n }\n }\n\n /**\n * addROM(addr)\n *\n * @this {ROM8080}\n * @param {number} addr\n * @return {boolean}\n */\n addROM(addr)\n {\n if (this.bus.addMemory(addr, this.sizeROM, Memory8080.TYPE.ROM)) {\n if (DEBUG) this.log(\"addROM(): copying ROM to \" + Str.toHexLong(addr) + \" (\" + Str.toHexLong(this.abROM.length) + \" bytes)\");\n var i;\n for (i = 0; i < this.abROM.length; i++) {\n this.bus.setByteDirect(addr + i, this.abROM[i]);\n }\n return true;\n }\n /*\n * We don't need to report an error here, because addMemory() already takes care of that.\n */\n return false;\n }\n\n /**\n * cloneROM(addr)\n *\n * For ROMs with one or more alias addresses, we used to call addROM() for each address. However,\n * that obviously wasted memory, since each alias was an independent copy, and if you used the\n * Debugger to edit the ROM in one location, the changes would not appear in the other location(s).\n *\n * Now that the Bus component provides low-level getMemoryBlocks() and setMemoryBlocks() methods\n * to manually get and set the blocks of any memory range, it is now possible to create true aliases.\n *\n * @this {ROM8080}\n * @param {number} addr\n */\n cloneROM(addr)\n {\n var aBlocks = this.bus.getMemoryBlocks(this.addrROM, this.sizeROM);\n this.bus.setMemoryBlocks(addr, this.sizeROM, aBlocks);\n }\n\n /**\n * ROM8080.init()\n *\n * This function operates on every HTML element of class \"rom\", extracting the\n * JSON-encoded parameters for the ROM8080 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a ROM8080 component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeROM = Component.getElementsByClass(document, PC8080.APPCLASS, \"rom\");\n for (var iROM = 0; iROM < aeROM.length; iROM++) {\n var eROM = aeROM[iROM];\n var parmsROM = Component.getComponentParms(eROM);\n var rom = new ROM8080(parmsROM);\n Component.bindComponentControls(rom, eROM, PC8080.APPCLASS);\n }\n }\n}\n\n/*\n * NOTE: There's currently no need for this component to have a reset() function, since\n * once the ROM data is loaded, it can't be changed, so there's nothing to reinitialize.\n *\n * OK, well, I take that back, because the Debugger, if installed, has the ability to modify\n * ROM contents, so in that case, having a reset() function that restores the original ROM data\n * might be useful; then again, it might not, depending on what you're trying to debug.\n *\n * If we do add reset(), then we'll want to change copyROM() to hang onto the original\n * ROM data; currently, we release it after copying it into the read-only memory allocated\n * via bus.addMemory().\n */\n\n/*\n * Initialize all the ROM8080 modules on the page.\n */\nWeb.onInit(ROM8080.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/ram.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass RAM8080 extends Component {\n /**\n * RAM8080(parmsRAM)\n *\n * The RAM8080 component expects the following (parmsRAM) properties:\n *\n * addr: starting physical address of RAM (default is 0)\n * size: amount of RAM, in bytes (default is 0, which means defer to motherboard switch settings)\n * file: name of optional data file to load into RAM (default is \"\")\n * load: optional file load address (overrides any load address specified in the data file; default is null)\n * exec: optional file exec address (overrides any exec address specified in the data file; default is null)\n *\n * NOTE: We make a note of the specified size, but no memory is initially allocated for the RAM until the\n * Computer component calls powerUp().\n *\n * @this {RAM8080}\n * @param {Object} parmsRAM\n */\n constructor(parmsRAM)\n {\n super(\"RAM\", parmsRAM);\n\n this.abInit = null;\n this.aSymbols = null;\n\n this.addrRAM = parmsRAM['addr'];\n this.sizeRAM = parmsRAM['size'];\n this.addrLoad = parmsRAM['load'];\n this.addrExec = parmsRAM['exec'];\n\n this.fInstalled = (!!this.sizeRAM); // 0 is the default value for 'size' when none is specified\n this.fAllocated = false;\n\n this.sFilePath = parmsRAM['file'];\n this.sFileName = Str.getBaseName(this.sFilePath);\n\n if (this.sFilePath) {\n var sFileURL = this.sFilePath;\n if (DEBUG) this.log('load(\"' + sFileURL + '\")');\n /*\n * If the selected data file has a \".json\" extension, then we assume it's pre-converted\n * JSON-encoded data, so we load it as-is; ditto for ROM files with a \".hex\" extension.\n * Otherwise, we ask our server-side converter to return the file in a JSON-compatible format.\n */\n var sFileExt = Str.getExtension(this.sFileName);\n if (sFileExt != DumpAPI.FORMAT.JSON && sFileExt != DumpAPI.FORMAT.HEX) {\n sFileURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFilePath + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES + '&' + DumpAPI.QUERY.DECIMAL + '=true';\n }\n var ram = this;\n Web.getResource(sFileURL, null, true, function(sURL, sResponse, nErrorCode) {\n ram.doneLoad(sURL, sResponse, nErrorCode);\n });\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {RAM8080}\n * @param {Computer8080} cmp\n * @param {Bus8080} bus\n * @param {CPUState8080} cpu\n * @param {Debugger8080} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.initRAM();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {RAM8080}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n /*\n * The Computer powers up the CPU last, at which point CPUState state is restored,\n * which includes the Bus state, and since we use the Bus to allocate all our memory,\n * memory contents are already restored for us, so we don't need the usual restore\n * logic.\n */\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {RAM8080}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n /*\n * The Computer powers down the CPU first, at which point CPUState state is saved,\n * which includes the Bus state, and since we use the Bus component to allocate all\n * our memory, memory contents are already saved for us, so we don't need the usual\n * save logic.\n */\n return true;\n }\n\n /**\n * doneLoad(sURL, sData, nErrorCode)\n *\n * @this {RAM8080}\n * @param {string} sURL\n * @param {string} sData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n doneLoad(sURL, sData, nErrorCode)\n {\n if (nErrorCode) {\n this.notice(\"Unable to load RAM resource (error \" + nErrorCode + \": \" + sURL + \")\");\n return;\n }\n\n Component.addMachineResource(this.idMachine, sURL, sData);\n\n var resource = Web.parseMemoryResource(sURL, sData);\n if (resource) {\n this.abInit = resource.aBytes;\n this.aSymbols = resource.aSymbols;\n if (this.addrLoad == null) this.addrLoad = resource.addrLoad;\n if (this.addrExec == null) this.addrExec = resource.addrExec;\n } else {\n this.sFilePath = null;\n }\n this.initRAM();\n }\n\n /**\n * initRAM()\n *\n * This function is called by both initBus() and doneLoad(), but it cannot copy the initial data into place\n * until after initBus() has received the Bus component AND doneLoad() has received the data. When both those\n * criteria are satisfied, the component becomes \"ready\".\n *\n * @this {RAM8080}\n */\n initRAM()\n {\n if (!this.fAllocated && this.sizeRAM) {\n if (this.bus.addMemory(this.addrRAM, this.sizeRAM, Memory8080.TYPE.RAM)) {\n this.fAllocated = true;\n }\n }\n if (!this.isReady()) {\n if (!this.fAllocated) {\n Component.error(\"No RAM allocated\");\n }\n else if (this.sFilePath) {\n /*\n * Too early...\n */\n if (!this.abInit || !this.bus) return;\n\n var addr = this.addrRAM;\n if (this.addrLoad !== null) addr = this.addrLoad;\n for (var i = 0; i < this.abInit.length; i++) {\n this.bus.setByteDirect(addr + i, this.abInit[i]);\n }\n\n if (this.addrExec !== null) {\n /*\n * Here's where we enable our \"Fake CP/M\" support, triggered by the user loading a \"writable\" ROM image\n * at offset 0x100. Fake CP/M support works by installing HLT opcodes at well-known CP/M addresses\n * (namely, 0x0000, which is the CP/M reset vector, and 0x0005, which is the CP/M system call vector) and\n * then telling the CPU to call us whenever a HLT occurs, so we can check PC for one of these addresses.\n */\n if (this.addrExec == RAM8080.CPM.INIT) {\n for (i = 0; i < RAM8080.CPM.VECTORS.length; i++) {\n this.bus.setByteDirect(RAM8080.CPM.VECTORS[i], CPUDef8080.OPCODE.HLT);\n }\n\n this.cpu.addHaltCheck(function(rom) {\n return function(addr) {\n return rom.checkCPMVector(addr)\n };\n }(this));\n }\n this.cpu.setReset(this.addrExec);\n }\n\n /*\n * TODO: Consider an option to retain this data and give the user a way of restoring the initial contents.\n */\n delete this.abInit;\n }\n this.setReady();\n }\n }\n\n /**\n * reset()\n *\n * @this {RAM8080}\n */\n reset()\n {\n /*\n * If you want to zero RAM on reset, then this would be a good place to do it.\n */\n }\n\n /**\n * checkCPMVector(addr)\n *\n * @this {RAM8080}\n * @param {number} addr (of the HLT opcode)\n * @return {boolean} true if special processing performed, false if not\n */\n checkCPMVector(addr)\n {\n var i = RAM8080.CPM.VECTORS.indexOf(addr);\n if (i >= 0) {\n var fCPM = false;\n var cpu = this.cpu;\n var dbg = this.dbg;\n if (addr == RAM8080.CPM.BDOS.VECTOR) {\n fCPM = true;\n switch(cpu.regC) {\n case RAM8080.CPM.BDOS.FUNC.CON_WRITE:\n this.writeCPMString(this.getCPMChar(cpu.regE));\n break;\n case RAM8080.CPM.BDOS.FUNC.STR_WRITE:\n this.writeCPMString(this.getCPMString(cpu.getDE(), '$'));\n break;\n default:\n fCPM = false;\n break;\n }\n }\n if (fCPM) {\n CPUDef8080.opRET.call(cpu); // for recognized calls, automatically return\n }\n else if (dbg) {\n this.println(\"\\nCP/M vector \" + Str.toHexWord(addr));\n cpu.setPC(addr); // this is purely for the Debugger's benefit, to show the HLT\n dbg.stopCPU();\n }\n return true;\n }\n return false;\n }\n\n /**\n * getCPMChar(ch)\n *\n * @this {RAM8080}\n * @param {number} ch\n * @return {string}\n */\n getCPMChar(ch)\n {\n return String.fromCharCode(ch);\n }\n\n /**\n * getCPMString(addr, chEnd)\n *\n * @this {RAM8080}\n * @param {number} addr (of a string)\n * @param {string|number} [chEnd] (terminating character, default is 0)\n * @return {string}\n */\n getCPMString(addr, chEnd)\n {\n var s = \"\";\n var cchMax = 255;\n var bEnd = chEnd && chEnd.length && chEnd.charCodeAt(0) || chEnd || 0;\n while (cchMax--) {\n var b = this.cpu.getByte(addr++);\n if (b == bEnd) break;\n s += String.fromCharCode(b);\n }\n return s;\n }\n\n /**\n * writeCPMString(s)\n *\n * @this {RAM8080}\n * @param {string} s\n */\n writeCPMString(s)\n {\n this.print(s.replace(/\\r/g, ''));\n }\n\n /**\n * RAM8080.init()\n *\n * This function operates on every HTML element of class \"ram\", extracting the\n * JSON-encoded parameters for the RAM8080 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a RAM8080 component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeRAM = Component.getElementsByClass(document, PC8080.APPCLASS, \"ram\");\n for (var iRAM = 0; iRAM < aeRAM.length; iRAM++) {\n var eRAM = aeRAM[iRAM];\n var parmsRAM = Component.getComponentParms(eRAM);\n var ram = new RAM8080(parmsRAM);\n Component.bindComponentControls(ram, eRAM, PC8080.APPCLASS);\n }\n }\n}\n\nRAM8080.CPM = {\n BIOS: {\n VECTOR: 0x0000\n },\n BDOS: {\n VECTOR: 0x0005,\n FUNC: { // function number (specified in regC)\n RESET: 0x00,\n CON_READ: 0x01, // output: A = L = ASCII character\n CON_WRITE: 0x02, // input: E = ASCII character\n AUX_READ: 0x03, // output: A = L = ASCII character\n AUX_WRITE: 0x04, // input: E = ASCII character\n PRN_WRITE: 0x05, // input: E = ASCII character\n MEM_SIZE: 0x06, // output: base address of CCP (Console Command Processor), but which register? (perhaps moot if this was CP/M 1.3 only...)\n CON_IO: 0x06, // input: E = ASCII character (or 0xFF to return ASCII character in A)\n GET_IOBYTE: 0x07,\n SET_IOBYTE: 0x08,\n STR_WRITE: 0x09 // input: DE = address of string\n }\n },\n INIT: 0x100\n};\n\nRAM8080.CPM.VECTORS = [RAM8080.CPM.BIOS.VECTOR, RAM8080.CPM.BDOS.VECTOR];\n\n/*\n * Initialize all the RAM8080 modules on the page.\n */\nWeb.onInit(RAM8080.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/keyboard.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass Keyboard8080 extends Component {\n /**\n * Keyboard8080(parmsKbd)\n *\n * The Keyboard8080 component has the following component-specific (parmsKbd) properties:\n *\n * model: eg, \"VT100\" (should be a member of Keyboard8080.MODELS)\n *\n * @this {Keyboard8080}\n * @param {Object} parmsKbd\n */\n constructor(parmsKbd)\n {\n super(\"Keyboard\", parmsKbd, Messages8080.KEYBOARD);\n\n var model = parmsKbd['model'];\n\n if (model && !Keyboard8080.MODELS[model]) {\n Component.notice(\"Unrecognized Keyboard8080 model: \" + model);\n }\n\n this.config = Keyboard8080.MODELS[model] || {};\n\n this.reset();\n\n this.setReady();\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {Keyboard8080}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"esc\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n /*\n * There's a special binding that the Video component uses (\"screen\") to effectively bind its\n * screen to the entire keyboard, in Video.powerUp(); ie:\n *\n * video.kbd.setBinding(\"canvas\", \"screen\", video.canvasScreen);\n * or:\n * video.kbd.setBinding(\"textarea\", \"screen\", video.textareaScreen);\n *\n * However, it's also possible for the keyboard XML definition to define a control that serves\n * a similar purpose; eg:\n *\n * <control type=\"text\" binding=\"kbd\" width=\"2em\">Keyboard</control>\n *\n * The latter is purely experimental, while we work on finding ways to trigger the soft keyboard on\n * certain pesky devices (like the Kindle Fire). Note that even if you use the latter, the former will\n * still be enabled (there's currently no way to configure the Video component to not bind its screen,\n * but we could certainly add one if the need ever arose).\n */\n var kbd = this;\n var id = sHTMLType + '-' + sBinding;\n\n if (this.bindings[id] === undefined) {\n\n if (sHTMLType == \"led\" && this.config.LEDCODES[sBinding]) {\n this.bindings[id] = control;\n return true;\n }\n\n switch (sBinding) {\n case \"kbd\":\n case \"screen\":\n /*\n * Recording the binding ID prevents multiple controls (or components) from attempting to erroneously\n * bind a control to the same ID, but in the case of a \"dual display\" configuration, we actually want\n * to allow BOTH video components to call setBinding() for \"screen\", so that it doesn't matter which\n * display the user gives focus to.\n *\n * this.bindings[id] = control;\n */\n if (Web.isUserAgent(\"iOS\")) {\n /*\n * For iOS devices, it's best to deal only with keypress events. The main reason is that we don't\n * get shift-key events, so we have no way of distinguishing between certain keys, such as ':' and\n * ';', unless we are monitoring key presses. Another reason is that, under certain poorly documented\n * conditions, an iOS keyup event will not contain any keyCode; this is most easily reproduced with\n * the iOS simulator and a physical keyboard (not the pop-up keyboard). When this happens, we think\n * the key is stuck. Finally, certain other problems that we have tried to resolve when using a physical\n * keyboard (eg, keeping the physical and virtual CAPS-LOCK states in sync) simply don't exist in the\n * iOS environment.\n *\n * So, with all that mind, it seems best to have a separate iOS keypress handler and forego keydown\n * and keyup events entirely. The iOS keypress handler must also perform some additional checks, such\n * as watching for keys that can only be typed on the emulated device when a shift key is down, and\n * simulating \"fake\" shift-key down and up events.\n *\n * Perhaps we can eventually standardize on this alternate keypress-centric approach for ALL devices,\n * but until then, it's safer to have these two code paths.\n *\n * UPDATE: So much for the best laid plans. iOS won't deliver BACKSPACE events to the keypress handler,\n * so we have to deal with keydown/keyup events after all.\n */\n control.onkeypress = function oniOSKeyPress(event)\n {\n return kbd.oniOSKeyPress(event);\n };\n control.onkeydown = function oniOSKeyDown(event)\n {\n return kbd.oniOSKeyDown(event, true);\n };\n control.onkeyup = function oniOSKeyUp(event)\n {\n return kbd.oniOSKeyDown(event, false);\n };\n }\n else {\n control.onkeydown = function onKeyDown(event)\n {\n return kbd.onKeyDown(event, true);\n };\n control.onkeyup = function onKeyUp(event)\n {\n return kbd.onKeyDown(event, false);\n };\n control.onkeypress = function onKeyPress(event)\n {\n return kbd.onKeyPress(event);\n };\n }\n control.onpaste = function onKeyPaste(event)\n {\n return kbd.onPaste(event);\n };\n return true;\n\n default:\n if (this.config.SOFTCODES && this.config.SOFTCODES[sBinding] !== undefined) {\n this.bindings[id] = control;\n control.onclick = function(kbd, keyCode) {\n return function onKeyboardBindingDown(event) {\n /*\n * iOS usability improvement: calling preventDefault() prevents rapid clicks from\n * also being (mis)interpreted as a desire to \"zoom\" in on the machine.\n */\n if (event.preventDefault) event.preventDefault();\n /*\n * TODO: Add some additional SOFTCODES configuration info that will tell us which soft\n * keys (eg, CTRL) should be treated as toggles, instead of hard-coding that knowledge below.\n *\n * Moreover, if a *real* CTRL or CAPS-LOCK key is pressed or released, it would be nice\n * to update the state of these on-screen controls, too (ie, not just when the controls are\n * clicked).\n */\n var fDown = true, bit = 0;\n if (keyCode == Keys.KEYCODE.CTRL) {\n bit = Keyboard8080.STATE.CTRL;\n }\n else if (keyCode == Keys.KEYCODE.CAPS_LOCK) {\n bit = Keyboard8080.STATE.CAPS_LOCK;\n }\n if (bit) {\n control.style.fontWeight = \"normal\";\n fDown = !(kbd.bitsState & bit);\n if (fDown) control.style.fontWeight = \"bold\";\n kbd.checkModifierKeys(keyCode, fDown);\n }\n kbd.onSoftKeyDown(keyCode, fDown, !bit);\n if (kbd.cmp) kbd.cmp.updateFocus();\n };\n }(this, this.config.SOFTCODES[sBinding]);\n //\n // var fnUp = function (kbd, keyCode) {\n // return function onKeyboardBindingUp(event) {\n // kbd.onSoftKeyDown(keyCode, false);\n // /*\n // * Give focus back to the machine (since clicking the button takes focus away).\n // *\n // * if (kbd.cmp) kbd.cmp.updateFocus();\n // *\n // * iOS Usability Improvement: NOT calling updateFocus() keeps the soft keyboard down\n // * (assuming it was already down).\n // */\n // };\n // }(this, this.config.SOFTCODES[sBinding]);\n //\n // if ('ontouchstart' in window) {\n // control.ontouchstart = fnDown;\n // control.ontouchend = fnUp;\n // } else {\n // control.onmousedown = fnDown;\n // control.onmouseup = control.onmouseout = fnUp;\n // }\n //\n // UPDATE: Since the only controls that we explicitly bind to SOFTCODES are buttons, I'm simplifying\n // the above code with a conventional \"onclick\" handler. The only corresponding change I had to make\n // to the onclick (formerly fnDown) function was to set fAutoRelease on its call to onSoftKeyDown(),\n // since we're no longer attempting to detect when the control (ie, the button) is actually released.\n //\n // This change also resolves a problem I ran into with the Epiphany (WebKit-based) web browser running\n // on the \"elementary\" (Ubuntu-based) OS, where clicks on the SET-UP button were ignored; perhaps its\n // buttons don't generate mouse and/or touch events. Anyway, an argument for keeping things simple.\n //\n return true;\n }\n break;\n }\n }\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {Keyboard8080}\n * @param {Computer8080} cmp\n * @param {Bus8080} bus\n * @param {CPUState8080} cpu\n * @param {Debugger8080} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.cpu = cpu;\n this.dbg = dbg; // NOTE: The \"dbg\" property must be set for the message functions to work\n\n var kbd = this;\n this.timerReleaseKeys = this.cpu.addTimer(this.id, function() {\n kbd.checkSoftKeysToRelease();\n });\n\n this.chipset = /** @type {ChipSet8080} */ (cmp.getMachineComponent(\"ChipSet\"));\n\n this.serial = /** @type {SerialPort8080} */ (cmp.getMachineComponent(\"SerialPort\"));\n\n bus.addPortInputTable(this, this.config.portsInput);\n bus.addPortOutputTable(this, this.config.portsOutput);\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {Keyboard8080}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Keyboard8080}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {Keyboard8080}\n */\n reset()\n {\n /*\n * As keyDown events are encountered, a corresponding \"softCode\" is looked up. If one is found,\n * then an entry for the key is added to the aKeysActive array. Each \"key\" entry in aKeysActive contains:\n *\n * softCode: number or string representing the key pressed\n * msDown: timestamp of the most recent \"down\" event\n * fAutoRelease: true to auto-release the key after MINPRESSTIME (set when \"up\" occurs too quickly)\n *\n * When the key is finally released (or auto-released), its entry is removed from the array.\n */\n this.aKeysActive = [];\n\n /*\n * The current (assumed) physical (and simulated) states of the various shift/lock keys.\n *\n * TODO: Determine how (or whether) we can query the browser's initial shift/lock key states.\n */\n this.bitsState = 0;\n\n if (this.config.INIT && !this.restore(this.config.INIT)) {\n this.notice(\"reset error\");\n }\n }\n\n /**\n * save()\n *\n * This implements save support for the Keyboard component.\n *\n * @this {Keyboard8080}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n switch(this.config.MODEL) {\n case Keyboard8080.SI1978.MODEL:\n break;\n case Keyboard8080.VT100.MODEL:\n state.set(0, [this.bVT100Status, this.bVT100Address, this.fVT100UARTBusy, this.nVT100UARTCycleSnap, -1]);\n break;\n }\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the Keyboard component.\n *\n * @this {Keyboard8080}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var a;\n if (data && (a = data[0]) && a.length) {\n switch(this.config.MODEL) {\n case Keyboard8080.SI1978.MODEL:\n return true;\n\n case Keyboard8080.VT100.MODEL:\n this.bVT100Status = a[0];\n this.updateLEDs(this.bVT100Status & Keyboard8080.VT100.STATUS.LEDS);\n this.bVT100Address = a[1];\n this.fVT100UARTBusy = a[2];\n this.nVT100UARTCycleSnap = a[3];\n this.iKeyNext = a[4];\n return true;\n }\n }\n return false;\n }\n\n /**\n * setLED(control, f, color)\n *\n * TODO: Add support for user-definable LED colors\n *\n * @this {Keyboard8080}\n * @param {Object} control is an HTML control DOM object\n * @param {boolean|number} f is true if the LED represented by control should be \"on\", false if \"off\"\n * @param {number} color (ie, 0xff0000 for RED, or 0x00ff00 for GREEN)\n */\n setLED(control, f, color)\n {\n control.style.backgroundColor = (f? ('#' + Str.toHex(color, 6)) : \"#000000\");\n }\n\n /**\n * updateLEDs(bLEDs)\n *\n * @this {Keyboard8080}\n * @param {number} [bLEDs]\n */\n updateLEDs(bLEDs)\n {\n var id, control;\n if (bLEDs != null) {\n this.bLEDs = bLEDs;\n } else {\n bLEDs = this.bLEDs;\n }\n for (var sBinding in this.config.LEDCODES) {\n id = \"led-\" + sBinding;\n control = this.bindings[id];\n if (control) {\n var bitLED = this.config.LEDCODES[sBinding];\n var fOn = !!(bLEDs & bitLED);\n if (bitLED & (bitLED-1)) {\n fOn = !(bLEDs & ~bitLED);\n }\n this.setLED(control, fOn, 0xff0000);\n }\n }\n id = \"led-caps-lock\";\n control = this.bindings[id];\n if (control) {\n this.setLED(control, (this.bitsState & Keyboard8080.STATE.CAPS_LOCK), 0x00ff00);\n }\n }\n\n /**\n * checkModifierKeys(keyCode, fDown, fRight)\n *\n * @this {Keyboard8080}\n * @param {number} keyCode (ie, either a keycode or string ID)\n * @param {boolean} fDown (true if key going down, false if key going up)\n * @param {boolean} [fRight] (true if key is on the right, false if not or unknown or n/a)\n * @return {boolean} (fDown updated as needed for CAPS-LOCK weirdness)\n */\n checkModifierKeys(keyCode, fDown, fRight)\n {\n var bit = 0;\n switch(keyCode) {\n case Keys.KEYCODE.SHIFT:\n bit = fRight? Keyboard8080.STATE.RSHIFT : Keyboard8080.STATE.SHIFT;\n break;\n case Keys.KEYCODE.CTRL:\n bit = fRight? Keyboard8080.STATE.RCTRL : Keyboard8080.STATE.CTRL;\n break;\n case Keys.KEYCODE.ALT:\n bit = fRight? Keyboard8080.STATE.RALT : Keyboard8080.STATE.ALT;\n break;\n case Keys.KEYCODE.CMD:\n bit = fRight? Keyboard8080.STATE.RCMD : Keyboard8080.STATE.CMD;\n break;\n case Keys.KEYCODE.CAPS_LOCK:\n bit = Keyboard8080.STATE.CAPS_LOCK;\n /*\n * WARNING: You have an entered a browser weirdness zone. In Chrome, pressing-and-releasing\n * CAPS-LOCK generates a \"down\" event when it turns the lock on and an \"up\" event when it turns\n * the lock off. Firefox, OTOH, generates only \"down\" events, so we have to \"manufacture\"\n * the fDown parameter ourselves -- which means we also have to propagate it back to the caller.\n *\n * And, while this isn't necessary for Chrome, it doesn't appear to hurt anything in Chrome, so\n * we're not going to bother making it browser-specific.\n */\n fDown = !(this.bitsState & bit);\n break;\n }\n if (bit) {\n if (fDown) {\n this.bitsState |= bit;\n } else {\n this.bitsState &= ~bit;\n }\n }\n return fDown;\n }\n\n /**\n * getSoftCode(keyCode)\n *\n * Returns a number if the keyCode exists in the KEYMAP, or a string if the keyCode has a string ID.\n *\n * @this {Keyboard8080}\n * @return {string|number|null}\n */\n getSoftCode(keyCode)\n {\n keyCode = this.config.ALTCODES[keyCode] || keyCode;\n if (this.config.KEYMAP[keyCode]) {\n return keyCode;\n }\n for (var sSoftCode in this.config.SOFTCODES) {\n if (this.config.SOFTCODES[sSoftCode] === keyCode) {\n return sSoftCode;\n }\n }\n return null;\n }\n\n /**\n * onKeyDown(event, fDown)\n *\n * @this {Keyboard8080}\n * @param {Object} event\n * @param {boolean} fDown is true for a keyDown event, false for up\n * @return {boolean} true to pass the event along, false to consume it\n */\n onKeyDown(event, fDown)\n {\n var fPass = true;\n var keyCode = event.keyCode;\n\n if (!COMPILED && this.messageEnabled(Messages8080.KEYS)) {\n this.printMessage(\"onKey\" + (fDown? \"Down\" : \"Up\") + \"(\" + keyCode + \")\", true);\n }\n\n /*\n * A note about Firefox: it uses different keyCodes for certain keys; there's a logic to the differences\n * (they use ASCII codes), but since other browsers didn't follow suit, we must use a mapping table to\n * convert their keyCodes to the more traditional values.\n */\n keyCode = Keys.FF_KEYCODES[keyCode] || keyCode;\n\n /*\n * We now keep track of physical keyboard modifier keys. This makes it possible for new services\n * to eventually be implemented (simulateKeysDown() and simulateKeysUp()), to map special ALT-key\n * combinations to VT100 keys, etc.\n */\n fDown = this.checkModifierKeys(keyCode, fDown, event.location == Keys.LOCATION.RIGHT);\n\n var softCode = this.getSoftCode(keyCode);\n if (softCode) {\n /*\n * Key combinations involving the \"meta\" key (ie, the Windows or Command key) are meaningless to\n * the VT100, so we ignore them. The \"meta\" key itself is already effectively ignored, because it's\n * not acknowledged by getSoftCode(), but we also don't want any of the keys combined with \"meta\"\n * slipping through either.\n */\n if (!event.metaKey) {\n /*\n * The LINE-FEED key is an important key on the VT100, and while we DO map a host function key\n * to it (F7), I like the idea of making ALT-ENTER an alias for LINE-FEED as well. Ditto for\n * making ALT-DELETE an alias for BACKSPACE (and no, I don't mean ALT-BACKSPACE as an alias for\n * DELETE; see my earlier discussion involving BACKSPACE and DELETE).\n *\n * Of course, as experienced VT100 users know, it's always possible to type CTRL-J for LINE-FEED\n * and CTRL-H for BACKSPACE, too. But not all our users are that experienced.\n *\n * I was also tempted to use CTRL-ENTER or SHIFT-ENTER, but those are composable VT100 key\n * sequences, so it's best not to muck with those.\n *\n * Finally, this hack is complicated by the fact that if the ALT key is released first, we run\n * the risk of the remapped key being stuck \"down\". Hence the new REMAPPED bit, which should\n * remain set (as a \"proxy\" for the ALT bit) as long as a remapped key is down.\n */\n var fRemapped = false;\n if (this.bitsState & (Keyboard8080.STATE.ALTS | Keyboard8080.STATE.REMAPPED)) {\n if (softCode == Keys.KEYCODE.CR) {\n softCode = Keys.KEYCODE.F7;\n fRemapped = true;\n }\n else if (softCode == Keys.KEYCODE.BS) {\n softCode = Keys.KEYCODE.DEL;\n fRemapped = true;\n }\n if (fRemapped) {\n if (fDown) {\n this.bitsState |= Keyboard8080.STATE.REMAPPED;\n } else {\n this.bitsState &= ~Keyboard8080.STATE.REMAPPED;\n }\n }\n }\n fPass = this.onSoftKeyDown(softCode, fDown);\n /*\n * As onKeyPress() explains, the only key presses we're interested in are letters, which provide\n * an important clue regarding the CAPS-LOCK state. For all other keys, we call preventDefault(),\n * which normally \"suppresses\" the keyPress event, as well as other unwanted browser behaviors\n * (eg, the SPACE key, which browsers interpret as a desire to scroll the entire web page down).\n *\n * And, even if the key IS a letter, we STILL want to call preventDefault() if a CTRL key is down,\n * so that Windows-based browsers (eg, Edge) don't interfere with their stupid CTRL-based shortcuts. ;-)\n *\n * NOTE: We COULD check event.ctrlKey too, but it's six of one, half a dozen of another.\n */\n if (!(softCode >= Keys.ASCII.A && softCode <= Keys.ASCII.Z) || (this.bitsState | Keyboard8080.STATE.CTRLS)) {\n if (event.preventDefault) event.preventDefault();\n }\n }\n }\n\n if (!COMPILED && this.messageEnabled(Messages8080.KEYS)) {\n this.printMessage(\"onKey\" + (fDown? \"Down\" : \"Up\") + \"(\" + keyCode + \"): softCode=\" + softCode + \", pass=\" + fPass, true);\n }\n\n return fPass;\n }\n\n /**\n * onKeyPress(event)\n *\n * For now, our only interest in keyPress events is letters, as a means of detecting the CAPS-LOCK state.\n *\n * @this {Keyboard8080}\n * @param {Object} event\n * @return {boolean} true to pass the event along, false to consume it\n */\n onKeyPress(event)\n {\n /*\n * A note about Firefox: the KeyboardEvent they pass to a keypress handler doesn't set 'keyCode', so\n * we have to fallback to 'charCode' (or 'which'), both of which are deprecated but realistically can't\n * really go away.\n *\n * TODO: Consider \"upgrading\" this code to use the new 'key' property. Note, however, that it's a string,\n * not a number; for example; if the colon key is pressed, 'key' will be \":\", whereas 'charCode' and 'which'\n * will be 58.\n */\n var charCode = event.keyCode || event.charCode;\n\n if (charCode >= Keys.ASCII.A && charCode <= Keys.ASCII.Z) {\n if (!(this.bitsState & (Keyboard8080.STATE.SHIFTS | Keyboard8080.STATE.CAPS_LOCK))) {\n this.bitsState |= Keyboard8080.STATE.CAPS_LOCK;\n this.onSoftKeyDown(Keys.KEYCODE.CAPS_LOCK, true);\n this.updateLEDs();\n }\n }\n else if (charCode >= Keys.ASCII.a && charCode <= Keys.ASCII.z) {\n if (this.bitsState & Keyboard8080.STATE.CAPS_LOCK) {\n this.bitsState &= ~Keyboard8080.STATE.CAPS_LOCK;\n this.onSoftKeyDown(Keys.KEYCODE.CAPS_LOCK, false);\n this.updateLEDs();\n }\n }\n\n if (!COMPILED && this.messageEnabled(Messages8080.KEYS)) {\n this.printMessage(\"onKeyPress(\" + charCode + \")\", true);\n }\n\n return true;\n }\n\n /**\n * oniOSKeyDown(event, fDown)\n *\n * @this {Keyboard8080}\n * @param {Object} event\n * @param {boolean} fDown is true for a keyDown event, false for up\n * @return {boolean} true to pass the event along, false to consume it\n */\n oniOSKeyDown(event, fDown)\n {\n var fPass = true;\n /*\n * Because keydown/keyup events on iOS are inherently \"fake\", they can be delivered so quickly that\n * if we generated matching down/up events, then the emulated machine might not see the key transition.\n * So we now deliver only down events, with fAutoRelease always set (see below).\n *\n * Also, because of iOS weirdness discussed in setBinding() when using a physical keyboard, the keyup\n * event may not provide a valid keyCode, which is another reason we have no choice but to always deliver\n * keys with fAutoRelease set to true.\n */\n if (fDown) {\n var keyCode = event.keyCode;\n var bMapping = this.config.KEYMAP[keyCode];\n if (bMapping) {\n /*\n * If this is a mappable key, but the mapping isn't in the CHARMAP table, then we have to process\n * it now; the most common reason is that the key doesn't generate a keypress event (eg, BACKSPACE).\n */\n if (!this.indexOfCharMap(bMapping)) {\n fPass = this.onSoftKeyDown(keyCode, fDown, true);\n if (event.preventDefault) event.preventDefault();\n if (!COMPILED && this.messageEnabled(Messages8080.KEYS)) {\n this.printMessage(\"oniOSKey\" + (fDown ? \"Down\" : \"Up\") + \"(\" + keyCode + \"): pass=\" + fPass, true);\n }\n }\n }\n }\n return fPass;\n }\n\n /**\n * oniOSKeyPress(event)\n *\n * @this {Keyboard8080}\n * @param {Object} event\n * @return {boolean} true to pass the event along, false to consume it\n */\n oniOSKeyPress(event)\n {\n /*\n * A note about Firefox: the KeyboardEvent they pass to a keypress handler doesn't set 'keyCode', so\n * we have to fallback to 'charCode' (or 'which'), both of which are deprecated but realistically can't\n * really go away.\n *\n * TODO: Consider \"upgrading\" this code to use the new 'key' property. Note, however, that it's a string,\n * not a number; for example; if the colon key is pressed, 'key' will be \":\", whereas 'charCode' and 'which'\n * will be 58.\n */\n var charCode = event.keyCode || event.charCode;\n\n var fShifted = false;\n var bMapping = this.config.CHARMAP[charCode];\n if (bMapping) {\n if (bMapping & 0x80) {\n bMapping &= 0x7f;\n fShifted = true;\n }\n /*\n * Since the rest of our code was built around keyCodes, not charCodes, we look up the CHARMAP byte\n * in the KEYMAP table to find a corresponding keyCode, and that's what we'll use to simulate the key\n * press/release.\n */\n var softCode = this.indexOfKeyMap(bMapping);\n if (softCode) {\n if (!fShifted) {\n this.onSoftKeyDown(Keys.KEYCODE.SHIFT, false);\n } else {\n this.onSoftKeyDown(Keys.KEYCODE.SHIFT, true, true);\n }\n this.onSoftKeyDown(softCode, true, true);\n }\n }\n\n if (!COMPILED && this.messageEnabled(Messages8080.KEYS)) {\n this.printMessage(\"oniOSKeyPress(\" + charCode + \")\", true);\n }\n\n return true;\n }\n\n /**\n * onPaste(event)\n *\n * @this {Keyboard8080}\n * @param {Object} event\n * @return {boolean} true to pass the event along, false to consume it\n */\n onPaste(event)\n {\n /*\n * TODO: In a perfect world, we would have implemented simulateKeysDown() and simulateKeysUp(),\n * which would transform any given text into the appropriate keystrokes. But for now, we're going\n * to leapfrog all that and try invoking the SerialPort's sendData() function, which if available,\n * is nothing more than a call into a connected machine's receiveData() function.\n *\n * Besides, paste functionality doesn't seem to be consistently implemented across all browsers\n * (partly out of security concerns, apparently) so it may not make sense to expend much more\n * effort on this right now. If you want to paste a lot of text into a machine, you're better off\n * pasting into a machine that's been configured to use a textarea as part of its Control Panel.\n * A visible textarea seems to have less issues than the hidden textarea overlaid on top of our\n * Video display.\n */\n if (this.serial && this.serial.sendData) {\n if (event.stopPropagation) event.stopPropagation();\n if (event.preventDefault) event.preventDefault();\n var clipboardData = event.clipboardData || window.clipboardData;\n if (clipboardData) {\n this.serial.transmitData(clipboardData.getData('Text'));\n return false;\n }\n }\n return true;\n }\n\n /**\n * indexOfKeyMap(bMapping)\n *\n * @this {Keyboard8080}\n * @param {number} bMapping\n * @return {number}\n */\n indexOfKeyMap(bMapping)\n {\n for (var keyCode in this.config.KEYMAP) {\n if (this.config.KEYMAP[keyCode] == bMapping) return +keyCode;\n }\n return 0;\n }\n\n /**\n * indexOfCharMap(bMapping)\n *\n * @this {Keyboard8080}\n * @param {number} bMapping\n * @return {number}\n */\n indexOfCharMap(bMapping)\n {\n for (var charCode in this.config.CHARMAP) {\n if (this.config.CHARMAP[charCode] == bMapping) return +charCode;\n }\n return 0;\n }\n\n /**\n * indexOfSoftKey(softCode)\n *\n * @this {Keyboard8080}\n * @param {number|string} softCode\n * @return {number} index of softCode in aKeysActive, or -1 if not found\n */\n indexOfSoftKey(softCode)\n {\n for (var i = 0; i < this.aKeysActive.length; i++) {\n if (this.aKeysActive[i].softCode == softCode) return i;\n }\n return -1;\n }\n\n /**\n * onSoftKeyDown(softCode, fDown, fAutoRelease)\n *\n * @this {Keyboard8080}\n * @param {number|string} softCode\n * @param {boolean} fDown is true for a down event, false for up\n * @param {boolean} [fAutoRelease] is true only if we know we want the key to auto-release\n * @return {boolean} true to pass the event along, false to consume it\n */\n onSoftKeyDown(softCode, fDown, fAutoRelease)\n {\n var i = this.indexOfSoftKey(softCode);\n if (fDown) {\n // this.println(softCode + \" down\");\n if (i < 0) {\n this.aKeysActive.push({\n softCode: softCode,\n msDown: Date.now(),\n fAutoRelease: fAutoRelease || false\n });\n } else {\n this.aKeysActive[i].msDown = Date.now();\n this.aKeysActive[i].fAutoRelease = fAutoRelease || false;\n }\n if (fAutoRelease) this.checkSoftKeysToRelease(); // prime the pump\n } else if (i >= 0) {\n // this.println(softCode + \" up\");\n if (!this.aKeysActive[i].fAutoRelease) {\n var msDown = this.aKeysActive[i].msDown;\n if (msDown) {\n var msElapsed = Date.now() - msDown;\n if (msElapsed < Keyboard8080.MINPRESSTIME) {\n // this.println(softCode + \" released after only \" + msElapsed + \"ms\");\n this.aKeysActive[i].fAutoRelease = true;\n this.checkSoftKeysToRelease();\n return true;\n }\n }\n }\n this.aKeysActive.splice(i, 1);\n } else {\n // this.println(softCode + \" up with no down?\");\n }\n\n if (this.chipset) {\n var bit = 0;\n switch(softCode) {\n case '1p':\n bit = ChipSet8080.SI1978.STATUS1.P1;\n break;\n case '2p':\n bit = ChipSet8080.SI1978.STATUS1.P2;\n break;\n case 'coin':\n bit = ChipSet8080.SI1978.STATUS1.CREDIT;\n break;\n case 'left':\n bit = ChipSet8080.SI1978.STATUS1.P1_LEFT;\n break;\n case 'right':\n bit = ChipSet8080.SI1978.STATUS1.P1_RIGHT;\n break;\n case 'fire':\n bit = ChipSet8080.SI1978.STATUS1.P1_FIRE;\n break;\n }\n if (bit) {\n this.chipset.updateStatus1(bit, fDown);\n }\n }\n return true;\n }\n\n /**\n * checkSoftKeysToRelease()\n *\n * @this {Keyboard8080}\n */\n checkSoftKeysToRelease()\n {\n var i = 0;\n var msDelayMin = -1;\n while (i < this.aKeysActive.length) {\n if (this.aKeysActive[i].fAutoRelease) {\n var softCode = this.aKeysActive[i].softCode;\n var msDown = this.aKeysActive[i].msDown;\n var msElapsed = Date.now() - msDown;\n var msDelay = Keyboard8080.MINPRESSTIME - msElapsed;\n if (msDelay > 0) {\n if (msDelayMin < 0 || msDelayMin > msDelay) {\n msDelayMin = msDelay;\n }\n } else {\n /*\n * Because the key is already in the auto-release state, this next call guarantees that the\n * key will be removed from the array; a consequence of that removal, however, is that we must\n * reset our array index to zero.\n */\n this.onSoftKeyDown(softCode, false);\n i = 0;\n continue;\n }\n }\n i++;\n }\n if (msDelayMin >= 0) {\n /*\n * Replaced the klunky browser setTimeout() call with our own timer service.\n *\n * var kbd = this;\n * setTimeout(function() { kbd.checkSoftKeysToRelease(); }, msDelayMin);\n */\n this.cpu.setTimer(this.timerReleaseKeys, msDelayMin);\n }\n }\n\n /**\n * isVT100TransmitterReady()\n *\n * Called whenever the VT100 ChipSet circuit needs the Keyboard UART's transmitter status.\n *\n * From p. 4-32 of the VT100 Technical Manual (July 1982):\n *\n * The operating clock for the keyboard interface comes from an address line in the video processor (LBA4).\n * This signal has an average period of 7.945 microseconds. Each data byte is transmitted with one start bit\n * and one stop bit, and each bit lasts 16 clock periods. The total time for each data byte is 160 times 7.945\n * or 1.27 milliseconds. Each time the Transmit Buffer Empty flag on the terminal's UART gets set (when the\n * current byte is being transmitted), the microprocessor loads another byte into the transmit buffer. In this\n * way, the stream of status bytes to the keyboard is continuous.\n *\n * We used to always return true (after all, what's wrong with an infinitely fast UART?), but unfortunately,\n * the VT100 firmware relies on the UART's slow transmission speed to drive cursor blink rate. We have several\n * options:\n *\n * 1) Snapshot the CPU cycle count each time a byte is transmitted (see outVT100UARTStatus()) and then every\n * time this is polled, see if the cycle count has exceeded the snapshot value by the necessary threshold;\n * if we assume 361.69ns per CPU cycle, there are 22 CPU cycles for every 1 LBA4 cycle, and since transmission\n * time is supposed to last for 160 LBA4 cycles, the threshold is 22*160 CPU cycles, or 3520 cycles.\n *\n * 2) Set a CPU timer using the new setTimer() interface, which can be passed the number of milliseconds to\n * wait before firing (in this case, roughly 1.27ms).\n *\n * 3) Call the ChipSet's getVT100LBA(4) function for the state of the simulated LBA4, and count 160 LBA4\n * transitions; however, that would be the worst solution, because there's no guarantee that the firmware's\n * UART polling will occur regularly and/or frequently enough for us to catch every LBA4 transition.\n *\n * I'm going with solution #1 because it's less overhead.\n *\n * @this {Keyboard8080}\n * @return {boolean} (true if ready, false if not)\n */\n isVT100TransmitterReady()\n {\n if (this.fVT100UARTBusy) {\n /*\n * NOTE: getMSCycles(1.2731488) should work out to 3520 cycles for a CPU clocked at 361.69ns per cycle,\n * which is roughly 2.76Mhz. We could just hard-code 3520 instead of calling getMSCycles(), but this helps\n * maintain a reasonable blink rate for the cursor even when the user cranks up the CPU speed.\n */\n if (this.cpu.getCycles() >= this.nVT100UARTCycleSnap + this.cpu.getMSCycles(1.2731488)) {\n this.fVT100UARTBusy = false;\n }\n }\n return !this.fVT100UARTBusy;\n }\n\n /**\n * inVT100UARTAddress(port, addrFrom)\n *\n * We take our cue from iKeyNext. If it's -1 (default), we simply return the last value latched\n * in bVT100Address. Otherwise, if iKeyNext is a valid index into aKeysActive, we look up the key\n * in the VT100.KEYMAP, latch it, and increment iKeyNext. Failing that, we latch Keyboard8080.VT100.KEYLAST\n * and reset iKeyNext to -1.\n *\n * @this {Keyboard8080}\n * @param {number} port (0x82)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n * @return {number} simulated port value\n */\n inVT100UARTAddress(port, addrFrom)\n {\n var b = this.bVT100Address;\n if (this.iKeyNext >= 0) {\n if (this.iKeyNext < this.aKeysActive.length) {\n var key = this.aKeysActive[this.iKeyNext];\n if (!MAXDEBUG) {\n this.iKeyNext++;\n } else {\n /*\n * In MAXDEBUG builds, this code removes the key as soon as it's been reported, because\n * when debugging, it's easy for the window to lose focus and never receive the keyUp event,\n * thereby leaving us with a stuck key. However, this may cause more problems than it solves,\n * because the VT100's ROM seems to require that key presses persist for more than a single poll.\n */\n this.aKeysActive.splice(this.iKeyNext, 1);\n }\n b = Keyboard8080.VT100.KEYMAP[key.softCode];\n if (b & 0x80) {\n /*\n * TODO: This code is supposed to be accompanied by a SHIFT key; make sure that it is.\n */\n b &= 0x7F;\n }\n } else {\n this.iKeyNext = -1;\n b = Keyboard8080.VT100.KEYLAST;\n }\n this.bVT100Address = b;\n this.cpu.requestINTR(1);\n }\n this.printMessageIO(port, null, addrFrom, \"KBDUART.ADDRESS\", b);\n return b;\n }\n\n /**\n * outVT100UARTStatus(port, b, addrFrom)\n *\n * @this {Keyboard8080}\n * @param {number} port (0x82)\n * @param {number} b\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outVT100UARTStatus(port, b, addrFrom)\n {\n this.printMessageIO(port, b, addrFrom, \"KBDUART.STATUS\");\n this.bVT100Status = b;\n this.fVT100UARTBusy = true;\n this.nVT100UARTCycleSnap = this.cpu.getCycles();\n this.updateLEDs(b & Keyboard8080.VT100.STATUS.LEDS);\n if (b & Keyboard8080.VT100.STATUS.START) {\n this.iKeyNext = 0;\n this.cpu.requestINTR(1);\n }\n }\n\n /**\n * Keyboard8080.init()\n *\n * This function operates on every HTML element of class \"keyboard\", extracting the\n * JSON-encoded parameters for the Keyboard constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Keyboard component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeKbd = Component.getElementsByClass(document, PC8080.APPCLASS, \"keyboard\");\n for (var iKbd = 0; iKbd < aeKbd.length; iKbd++) {\n var eKbd = aeKbd[iKbd];\n var parmsKbd = Component.getComponentParms(eKbd);\n var kbd = new Keyboard8080(parmsKbd);\n Component.bindComponentControls(kbd, eKbd, PC8080.APPCLASS);\n }\n }\n}\n\n/*\n * Now that we want to keep track of the physical (and simulated) state of modifier keys, I've\n * grabbed a copy of the same bit definitions used by /modules/pcx86/lib/keyboard.js, since it's\n * only important that we have a set of unique values; what the values are isn't critical.\n */\nKeyboard8080.STATE = {\n RSHIFT: 0x0001,\n SHIFT: 0x0002,\n SHIFTS: 0x0003,\n RCTRL: 0x0004, // 101-key keyboard only\n CTRL: 0x0008,\n CTRLS: 0x000C,\n RALT: 0x0010, // 101-key keyboard only\n ALT: 0x0020,\n ALTS: 0x0030,\n RCMD: 0x0040, // 101-key keyboard only\n CMD: 0x0080, // 101-key keyboard only\n CMDS: 0x00C0,\n ALL_RIGHT: 0x0055, // RSHIFT | RCTRL | RALT | RCMD\n ALL_SHIFT: 0x00FF, // SHIFT | RSHIFT | CTRL | RCTRL | ALT | RALT | CMD | RCMD\n INSERT: 0x0100, // TODO: Placeholder (we currently have no notion of any \"insert\" states)\n CAPS_LOCK: 0x0200,\n NUM_LOCK: 0x0400,\n SCROLL_LOCK: 0x0800,\n ALL_LOCKS: 0x0E00, // CAPS_LOCK | NUM_LOCK | SCROLL_LOCK\n REMAPPED: 0x1000\n};\n\nKeyboard8080.MINPRESSTIME = 50; // minimum milliseconds to wait before auto-releasing keys\n\n/**\n * Alternate keyCode mappings to support popular \"WASD\"-style directional-key mappings.\n *\n * TODO: ES6 computed property name support may now be in all mainstream browsers, allowing us to use\n * a simple object literal for this and all other object initializations.\n */\nKeyboard8080.WASDCODES = {};\nKeyboard8080.WASDCODES[Keys.ASCII.A] = Keys.KEYCODE.LEFT;\nKeyboard8080.WASDCODES[Keys.ASCII.D] = Keys.KEYCODE.RIGHT;\nKeyboard8080.WASDCODES[Keys.ASCII.L] = Keys.KEYCODE.SPACE;\n\n/*\n * Supported keyboard configurations.\n *\n * A word (or two) about SOFTCODES. Their main purpose is to provide a naming convention for machine-specific\n * controls, without tying us to any particular keyboard mapping. They are used in two main ways.\n *\n * First, if we have a binding to the machine's \"screen\", there will, at a minimum, be onkeydown and onkeyup\n * handlers attached to the screen, and those handlers will need to iterate through the SOFTCODES table, looking\n * for key codes that we care about and converting them to corresponding soft codes. Some machines, like\n * Space Invaders, will then act directly upon the soft code (eg, converting it to a machine-specific status bit).\n *\n * Second, a machine may have other bindings (eg, buttons) to one or more of these soft codes, and those bindings\n * will need to know which key codes they're supposed to generate. Some machines, like the VT100, will then use\n * another table (KEYMAP) to convert key codes into a machine-specific \"key addresses\".\n */\nKeyboard8080.SI1978 = {\n MODEL: 1978.1,\n KEYMAP: {},\n CHARMAP: {},\n ALTCODES: Keyboard8080.WASDCODES,\n LEDCODES: {},\n SOFTCODES: {\n '1p': Keys.KEYCODE.ONE,\n '2p': Keys.KEYCODE.TWO,\n 'coin': Keys.KEYCODE.THREE,\n 'left': Keys.KEYCODE.LEFT,\n 'right': Keys.KEYCODE.RIGHT,\n 'fire': Keys.KEYCODE.SPACE\n }\n};\n\nKeyboard8080.VT100 = {\n MODEL: 100.0,\n KEYMAP: {\n /*\n * Map of keydown keyCodes to VT100 key addresses (7-bit values representing key positions on the VT100).\n *\n * NOTE: The VT100 keyboard has both BACKSPACE and DELETE keys, whereas modern keyboards generally only\n * have DELETE. And sadly, when you press DELETE, your modern keyboard and/or modern browser is reporting\n * it as keyCode 8: the code for BACKSPACE, aka CTRL-H. You have to press a modified DELETE key to get\n * the actual DELETE keyCode of 127.\n *\n * We resolve this below by mapping KEYCODE.BS (8) to VT100 keyCode DELETE (0x03) and KEYCODE.DEL (127)\n * to VT100 keyCode BACKSPACE (0x33). So, DELETE is BACKSPACE and BACKSPACE is DELETE. Fortunately, this\n * confusion is all internal, because your physical key is (or should be) labeled DELETE, so the fact that\n * the browser is converting it to BACKSPACE and that we're converting BACKSPACE back into DELETE is\n * something most people don't need to worry their heads about.\n *\n * ES6 ALERT: As you can see below, I've finally started using computed property names.\n */\n [Keys.KEYCODE.BS]: 0x03,\n [Keys.ASCII.P]: 0x05,\n [Keys.ASCII.O]: 0x06,\n [Keys.ASCII.Y]: 0x07,\n [Keys.ASCII.T]: 0x08,\n [Keys.ASCII.W]: 0x09,\n [Keys.ASCII.Q]: 0x0A,\n [Keys.KEYCODE.RIGHT]: 0x10,\n [Keys.KEYCODE.RBRACK]: 0x14,\n [Keys.KEYCODE.LBRACK]: 0x15,\n [Keys.ASCII.I]: 0x16,\n [Keys.ASCII.U]: 0x17,\n [Keys.ASCII.R]: 0x18,\n [Keys.ASCII.E]: 0x19,\n [Keys.KEYCODE.ONE]: 0x1A,\n [Keys.KEYCODE.LEFT]: 0x20,\n [Keys.KEYCODE.DOWN]: 0x22,\n [Keys.KEYCODE.F6]: 0x23, // aka BREAK\n [Keys.KEYCODE.PAUSE]: 0x23, // aka BREAK\n [Keys.KEYCODE.BQUOTE]: 0x24,\n [Keys.KEYCODE.DASH]: 0x25,\n [Keys.KEYCODE.NINE]: 0x26,\n [Keys.KEYCODE.SEVEN]: 0x27,\n [Keys.KEYCODE.FOUR]: 0x28,\n [Keys.KEYCODE.THREE]: 0x29,\n [Keys.KEYCODE.ESC]: 0x2A,\n [Keys.KEYCODE.UP]: 0x30,\n [Keys.KEYCODE.F3]: 0x31, // aka PF3\n [Keys.KEYCODE.F1]: 0x32, // aka PF1\n [Keys.KEYCODE.DEL]: 0x33,\n [Keys.KEYCODE.EQUALS]: 0x34,\n [Keys.KEYCODE.ZERO]: 0x35,\n [Keys.KEYCODE.EIGHT]: 0x36,\n [Keys.KEYCODE.SIX]: 0x37,\n [Keys.KEYCODE.FIVE]: 0x38,\n [Keys.KEYCODE.TWO]: 0x39,\n [Keys.KEYCODE.TAB]: 0x3A,\n [Keys.KEYCODE.NUM_7]: 0x40,\n [Keys.KEYCODE.F4]: 0x41, // aka PF4\n [Keys.KEYCODE.F2]: 0x42, // aka PF2\n [Keys.KEYCODE.NUM_0]: 0x43,\n [Keys.KEYCODE.F7]: 0x44, // aka LINE-FEED\n [Keys.KEYCODE.BSLASH]: 0x45,\n [Keys.ASCII.L]: 0x46,\n [Keys.ASCII.K]: 0x47,\n [Keys.ASCII.G]: 0x48,\n [Keys.ASCII.F]: 0x49,\n [Keys.ASCII.A]: 0x4A,\n [Keys.KEYCODE.NUM_8]: 0x50,\n [Keys.KEYCODE.NUM_CR]: 0x51,\n [Keys.KEYCODE.NUM_2]: 0x52,\n [Keys.KEYCODE.NUM_1]: 0x53,\n [Keys.KEYCODE.QUOTE]: 0x55,\n [Keys.KEYCODE.SEMI]: 0x56,\n [Keys.ASCII.J]: 0x57,\n [Keys.ASCII.H]: 0x58,\n [Keys.ASCII.D]: 0x59,\n [Keys.ASCII.S]: 0x5A,\n [Keys.KEYCODE.NUM_DEL]: 0x60, // keypad period\n [Keys.KEYCODE.F5]: 0x61, // aka KEYPAD COMMA\n [Keys.KEYCODE.NUM_5]: 0x62,\n [Keys.KEYCODE.NUM_4]: 0x63,\n [Keys.KEYCODE.CR]: 0x64, // TODO: Figure out why the Technical Manual lists CR at both 0x04 and 0x64\n [Keys.KEYCODE.PERIOD]: 0x65,\n [Keys.KEYCODE.COMMA]: 0x66,\n [Keys.ASCII.N]: 0x67,\n [Keys.ASCII.B]: 0x68,\n [Keys.ASCII.X]: 0x69,\n [Keys.KEYCODE.F8]: 0x6A, // aka NO-SCROLL\n [Keys.KEYCODE.NUM_9]: 0x70,\n [Keys.KEYCODE.NUM_3]: 0x71,\n [Keys.KEYCODE.NUM_6]: 0x72,\n [Keys.KEYCODE.NUM_SUB]: 0x73, // aka KEYPAD MINUS\n [Keys.KEYCODE.SLASH]: 0x75,\n [Keys.ASCII.M]: 0x76,\n [Keys.ASCII[' ']]: 0x77,\n [Keys.ASCII.V]: 0x78,\n [Keys.ASCII.C]: 0x79,\n [Keys.ASCII.Z]: 0x7A,\n [Keys.KEYCODE.F9]: 0x7B, // aka SET-UP\n [Keys.KEYCODE.CTRL]: 0x7C,\n [Keys.KEYCODE.SHIFT]: 0x7D, // either shift key (doesn't matter)\n [Keys.KEYCODE.CAPS_LOCK]:0x7E\n },\n CHARMAP: {\n /*\n * Map of keypress charCodes to VT100 key addresses (7-bit values representing key positions on the VT100);\n * the 8th bit (0x80) is set for keys that need to be shifted.\n *\n * This is currently used only with the iOS keypress handler, which processes character codes rather than\n * keyboard codes. As a result, this table is not as complete as the KEYMAP table, since certain keys are\n * not delivered as key presses (eg, BACKSPACE) and/or are simply not present on the iOS keyboard (eg, ESC,\n * arrow keys). Also, SPACE had to be removed from the CHARMAP table as well, because otherwise it causes\n * the entire page to scroll down (you have to wonder who thought THAT was a good idea).\n *\n * ES6 ALERT: As you can see below, I've finally started using computed property names.\n */\n [Keys.ASCII.p]: 0x05,\n [Keys.ASCII.o]: 0x06,\n [Keys.ASCII.y]: 0x07,\n [Keys.ASCII.t]: 0x08,\n [Keys.ASCII.w]: 0x09,\n [Keys.ASCII.q]: 0x0A,\n [Keys.ASCII[']']]: 0x14,\n [Keys.ASCII['[']]: 0x15,\n [Keys.ASCII.i]: 0x16,\n [Keys.ASCII.u]: 0x17,\n [Keys.ASCII.r]: 0x18,\n [Keys.ASCII.e]: 0x19,\n [Keys.ASCII['1']]: 0x1A,\n [Keys.ASCII['`']]: 0x24,\n [Keys.ASCII['-']]: 0x25,\n [Keys.ASCII['9']]: 0x26,\n [Keys.ASCII['7']]: 0x27,\n [Keys.ASCII['4']]: 0x28,\n [Keys.ASCII['3']]: 0x29,\n [Keys.ASCII['=']]: 0x34,\n [Keys.ASCII['0']]: 0x35,\n [Keys.ASCII['8']]: 0x36,\n [Keys.ASCII['6']]: 0x37,\n [Keys.ASCII['5']]: 0x38,\n [Keys.ASCII['2']]: 0x39,\n [Keys.ASCII['\\\\']]: 0x45,\n [Keys.ASCII.l]: 0x46,\n [Keys.ASCII.k]: 0x47,\n [Keys.ASCII.g]: 0x48,\n [Keys.ASCII.f]: 0x49,\n [Keys.ASCII.a]: 0x4A,\n [Keys.ASCII[\"'\"]]: 0x55,\n [Keys.ASCII[';']]: 0x56,\n [Keys.ASCII.j]: 0x57,\n [Keys.ASCII.h]: 0x58,\n [Keys.ASCII.d]: 0x59,\n [Keys.ASCII.s]: 0x5A,\n [Keys.KEYCODE.CR]: 0x64, // TODO: Figure out why the Technical Manual lists CR at both 0x04 and 0x64\n [Keys.ASCII['.']]: 0x65,\n [Keys.ASCII[',']]: 0x66,\n [Keys.ASCII.n]: 0x67,\n [Keys.ASCII.b]: 0x68,\n [Keys.ASCII.x]: 0x69,\n [Keys.ASCII['/']]: 0x75,\n [Keys.ASCII.m]: 0x76,\n // [Keys.ASCII[' ']]: 0x77, // as noted above, we need to process SPACE at keydown rather than keypress\n [Keys.ASCII.v]: 0x78,\n [Keys.ASCII.c]: 0x79,\n [Keys.ASCII.z]: 0x7A,\n [Keys.ASCII.P]: 0x85,\n [Keys.ASCII.O]: 0x86,\n [Keys.ASCII.Y]: 0x87,\n [Keys.ASCII.T]: 0x88,\n [Keys.ASCII.W]: 0x89,\n [Keys.ASCII.Q]: 0x8A,\n [Keys.ASCII['}']]: 0x94,\n [Keys.ASCII['{']]: 0x95,\n [Keys.ASCII.I]: 0x96,\n [Keys.ASCII.U]: 0x97,\n [Keys.ASCII.R]: 0x98,\n [Keys.ASCII.E]: 0x99,\n [Keys.ASCII['!']]: 0x9A,\n [Keys.ASCII['~']]: 0xA4,\n [Keys.ASCII['_']]: 0xA5,\n [Keys.ASCII['(']]: 0xA6,\n [Keys.ASCII['&']]: 0xA7,\n [Keys.ASCII['$']]: 0xA8,\n [Keys.ASCII['#']]: 0xA9,\n [Keys.ASCII['+']]: 0xB4,\n [Keys.ASCII[')']]: 0xB5,\n [Keys.ASCII['*']]: 0xB6,\n [Keys.ASCII['^']]: 0xB7,\n [Keys.ASCII['%']]: 0xB8,\n [Keys.ASCII['@']]: 0xB9,\n [Keys.ASCII['|']]: 0xC5,\n [Keys.ASCII.L]: 0xC6,\n [Keys.ASCII.K]: 0xC7,\n [Keys.ASCII.G]: 0xC8,\n [Keys.ASCII.F]: 0xC9,\n [Keys.ASCII.A]: 0xCA,\n [Keys.ASCII['\"']]: 0xD5,\n [Keys.ASCII[':']]: 0xD6,\n [Keys.ASCII.J]: 0xD7,\n [Keys.ASCII.H]: 0xD8,\n [Keys.ASCII.D]: 0xD9,\n [Keys.ASCII.S]: 0xDA,\n [Keys.ASCII['>']]: 0xE5,\n [Keys.ASCII['<']]: 0xE6,\n [Keys.ASCII.N]: 0xE7,\n [Keys.ASCII.B]: 0xE8,\n [Keys.ASCII.X]: 0xE9,\n [Keys.ASCII['?']]: 0xF5,\n [Keys.ASCII.M]: 0xF6,\n [Keys.ASCII.V]: 0xF8,\n [Keys.ASCII.C]: 0xF9,\n [Keys.ASCII.Z]: 0xFA\n },\n ALTCODES: {},\n LEDCODES: {},\n SOFTCODES: {\n 'caps-lock': Keys.KEYCODE.CAPS_LOCK,\n 'ctrl': Keys.KEYCODE.CTRL,\n 'esc': Keys.KEYCODE.ESC,\n 'tab': Keys.KEYCODE.TAB,\n 'num-comma': Keys.KEYCODE.F5, // since modern keypads don't typically have a comma...\n 'break': Keys.KEYCODE.F6,\n 'line-feed': Keys.KEYCODE.F7,\n 'no-scroll': Keys.KEYCODE.F8,\n 'setup': Keys.KEYCODE.F9\n },\n /*\n * Reading port 0x82 returns a key address from the VT100 keyboard's UART data output.\n *\n * Every time a keyboard scan is initiated (by setting the START bit of the status byte),\n * our internal address index (iKeyNext) is set to zero, and an interrupt is generated for\n * each entry in the aKeysActive array, along with a final interrupt for KEYLAST.\n */\n ADDRESS: {\n PORT: 0x82,\n INIT: 0x7F\n },\n /*\n * Writing port 0x82 updates the VT100's keyboard status byte via the keyboard's UART data input.\n */\n STATUS: {\n PORT: 0x82, // write-only\n LED4: 0x01,\n LED3: 0x02,\n LED2: 0x04,\n LED1: 0x08,\n LOCKED: 0x10,\n LOCAL: 0x20,\n LEDS: 0x3F, // all LEDs\n START: 0x40, // set to initiate a scan\n /*\n * From p. 4-38 of the VT100 Technical Manual (July 1982):\n *\n * A bit (CLICK) in the keyboard status word controls the bell.... When a single status word contains\n * the bell bit, flip-flop E3 toggles and turns on E1, generating a click. If the bell bit is set for\n * many words in succession, the UART latch holds the data output constant..., allowing the circuit to\n * produce an 800 hertz tone. Bell is generated by setting the bell bit for 0.25 seconds. Each cycle of\n * the tone is at a reduced amplitude compared with the single keyclick.... The overall effect of the\n * tone burst on the ear is that of a beep.\n */\n CLICK: 0x80,\n INIT: 0x00\n },\n KEYLAST: 0x7F // special end-of-scan key address (all valid key addresses are < KEYLAST)\n};\n\nKeyboard8080.VT100.LEDCODES = {\n 'l4': Keyboard8080.VT100.STATUS.LED4,\n 'l3': Keyboard8080.VT100.STATUS.LED3,\n 'l2': Keyboard8080.VT100.STATUS.LED2,\n 'l1': Keyboard8080.VT100.STATUS.LED1,\n 'locked': Keyboard8080.VT100.STATUS.LOCKED,\n 'local': Keyboard8080.VT100.STATUS.LOCAL,\n 'online': ~Keyboard8080.VT100.STATUS.LOCAL,\n 'caps-lock':Keyboard8080.STATE.CAPS_LOCK\n};\n\n/*\n * Supported models and their configurations\n */\nKeyboard8080.MODELS = {\n \"SI1978\": Keyboard8080.SI1978,\n \"VT100\": Keyboard8080.VT100\n};\n\nKeyboard8080.VT100.INIT = [\n [\n Keyboard8080.VT100.STATUS.INIT, // bVT100Status\n Keyboard8080.VT100.ADDRESS.INIT, // bVT100Address\n false, // fVT100UARTBusy\n 0, // nVT100UARTCycleSnap\n -1 // iKeyNext\n ]\n];\n\n/*\n * Port notification tables\n */\nKeyboard8080.VT100.portsInput = {\n 0x82: Keyboard8080.prototype.inVT100UARTAddress\n};\n\nKeyboard8080.VT100.portsOutput = {\n 0x82: Keyboard8080.prototype.outVT100UARTStatus\n};\n\n/*\n * Initialize every Keyboard module on the page.\n */\nWeb.onInit(Keyboard8080.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/video.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass Video8080 extends Component {\n /**\n * Video8080(parmsVideo, canvas, context, textarea, container)\n *\n * The Video8080 component can be configured with the following (parmsVideo) properties:\n *\n * screenWidth: width of the screen canvas, in pixels\n * screenHeight: height of the screen canvas, in pixels\n * screenColor: background color of the screen canvas (default is black)\n * screenRotate: the amount of counter-clockwise screen rotation required (eg, -90 or 270)\n * aspectRatio (eg, 1.33)\n * bufferAddr: the starting address of the frame buffer (eg, 0x2400)\n * bufferRAM: true to use existing RAM (default is false)\n * bufferFormat: if defined, one of the recognized formats in Video8080.FORMATS (eg, \"vt100\")\n * bufferCols: the width of a single frame buffer row, in pixels (eg, 256)\n * bufferRows: the number of frame buffer rows (eg, 224)\n * bufferBits: the number of bits per column (default is 1)\n * bufferLeft: the bit position of the left-most pixel in a byte (default is 0; CGA uses 7)\n * bufferRotate: the amount of counter-clockwise buffer rotation required (eg, -90 or 270)\n * interruptRate: normally the same as (or some multiple of) refreshRate (eg, 120)\n * refreshRate: how many times updateScreen() should be performed per second (eg, 60)\n *\n * In addition, if a text-only display is being emulated, define the following properties:\n *\n * fontROM: URL of font ROM\n * fontColor: default is white\n * cellWidth: number (eg, 10 for VT100)\n * cellHeight: number (eg, 10 for VT100)\n *\n * We record all the above values now, but we defer creation of the frame buffer until our initBus()\n * handler is called. At that point, we will also compute the extent of the frame buffer, determine the\n * appropriate \"cell\" size (ie, the number of pixels that updateScreen() will fetch and process at once),\n * and then allocate our cell cache.\n *\n * Why interruptRate in addition to refreshRate? A higher interrupt rate is required for Space Invaders,\n * because even though the CRT refreshes at 60Hz, the CRT controller interrupts the CPU *twice* per\n * refresh (once after the top half of the screen has been redrawn, and again after the bottom half has\n * been redrawn), so we need an interrupt rate of 120Hz. We pass the higher rate on to the CPU, so that\n * it will call updateScreen() more frequently, but we still limit our screen updates to every *other* call.\n *\n * bufferRotate is an alternative to screenRotate; you may set one or the other (but not both) to -90 to\n * enable different approaches to counter-clockwise 90-degree image rotation. screenRotate uses canvas\n * transformation methods (translate(), rotate(), and scale()), while bufferRotate inverts the dimensions\n * of the off-screen buffer and then relies on setPixel() to \"rotate\" the data into the proper location.\n *\n * @this {Video8080}\n * @param {Object} parmsVideo\n * @param {Object} [canvas]\n * @param {Object} [context]\n * @param {Object} [textarea]\n * @param {Object} [container]\n */\n constructor(parmsVideo, canvas, context, textarea, container)\n {\n super(\"Video\", parmsVideo, Messages8080.VIDEO);\n\n var video = this, sProp, sEvent;\n this.fGecko = Web.isUserAgent(\"Gecko/\");\n\n this.cxScreen = parmsVideo['screenWidth'];\n this.cyScreen = parmsVideo['screenHeight'];\n\n this.addrBuffer = parmsVideo['bufferAddr'];\n this.fUseRAM = parmsVideo['bufferRAM'];\n\n var sFormat = parmsVideo['bufferFormat'];\n this.nFormat = sFormat && Video8080.FORMATS[sFormat.toUpperCase()] || Video8080.FORMAT.UNKNOWN;\n\n this.nColsBuffer = parmsVideo['bufferCols'];\n this.nRowsBuffer = parmsVideo['bufferRows'];\n\n this.cxCellDefault = this.cxCell = parmsVideo['cellWidth'] || 1;\n this.cyCellDefault = this.cyCell = parmsVideo['cellHeight'] || 1;\n this.abFontData = null;\n this.fDotStretcher = false;\n\n this.nBitsPerPixel = parmsVideo['bufferBits'] || 1;\n this.iBitFirstPixel = parmsVideo['bufferLeft'] || 0;\n\n this.rotateBuffer = parmsVideo['bufferRotate'];\n if (this.rotateBuffer) {\n this.rotateBuffer = this.rotateBuffer % 360;\n if (this.rotateBuffer > 0) this.rotateBuffer -= 360;\n if (this.rotateBuffer != -90) {\n this.notice(\"unsupported buffer rotation: \" + this.rotateBuffer);\n this.rotateBuffer = 0;\n }\n }\n\n this.rateInterrupt = parmsVideo['interruptRate'];\n this.rateRefresh = parmsVideo['refreshRate'] || 60;\n\n this.canvasScreen = canvas;\n this.contextScreen = context;\n this.textareaScreen = textarea;\n this.inputScreen = textarea || canvas || null;\n\n /*\n * These variables are here in case we want/need to add support for borders later...\n */\n this.xScreenOffset = this.yScreenOffset = 0;\n this.cxScreenOffset = this.cxScreen;\n this.cyScreenOffset = this.cyScreen;\n\n this.cxScreenCell = (this.cxScreen / this.nColsBuffer)|0;\n this.cyScreenCell = (this.cyScreen / this.nRowsBuffer)|0;\n\n /*\n * Now that we've finished using nRowsBuffer to help define the screen size, we add one more\n * row for text modes, to account for the VT100's scroll line buffer (used for smooth scrolling).\n */\n if (this.cyCell > 1) {\n this.nRowsBuffer++;\n this.bScrollOffset = 0;\n this.fSkipSingleCellUpdate = false;\n }\n\n /*\n * Support for disabling (or, less commonly, enabling) image smoothing, which all browsers\n * seem to support now (well, OK, I still have to test the latest MS Edge browser), despite\n * it still being labelled \"experimental technology\". Let's hope the browsers standardize\n * on this. I see other options emerging, like the CSS property \"image-rendering: pixelated\"\n * that's apparently been added to Chrome. Sigh.\n */\n var fSmoothing = parmsVideo['smoothing'];\n var sSmoothing = Web.getURLParm('smoothing');\n if (sSmoothing) fSmoothing = (sSmoothing == \"true\");\n if (fSmoothing != null) {\n sProp = Web.findProperty(this.contextScreen, 'imageSmoothingEnabled');\n if (sProp) this.contextScreen[sProp] = fSmoothing;\n }\n\n this.rotateScreen = parmsVideo['screenRotate'];\n if (this.rotateScreen) {\n this.rotateScreen = this.rotateScreen % 360;\n if (this.rotateScreen > 0) this.rotateScreen -= 360;\n /*\n * TODO: Consider also disallowing any rotateScreen value if bufferRotate was already set; setting\n * both is most likely a mistake, but who knows, maybe someone wants to use both for 180-degree rotation?\n */\n if (this.rotateScreen != -90) {\n this.notice(\"unsupported screen rotation: \" + this.rotateScreen);\n this.rotateScreen = 0;\n } else {\n this.contextScreen.translate(0, this.cyScreen);\n this.contextScreen.rotate((this.rotateScreen * Math.PI)/180);\n this.contextScreen.scale(this.cyScreen/this.cxScreen, this.cxScreen/this.cyScreen);\n }\n }\n\n /*\n * Here's the gross code to handle full-screen support across all supported browsers. The lack of standards\n * is exasperating; browsers can't agree on 'Fullscreen' (most common) or 'FullScreen' (least common), and while\n * some browsers honor other browser prefixes, most don't. Event handlers tend to be more consistent (ie, all\n * lower-case).\n */\n this.container = container;\n if (this.container) {\n sProp = Web.findProperty(container, 'requestFullscreen') || Web.findProperty(container, 'requestFullScreen');\n if (sProp) {\n this.container.doFullScreen = container[sProp];\n sEvent = Web.findProperty(document, 'on', 'fullscreenchange');\n if (sEvent) {\n var sFullScreen = Web.findProperty(document, 'fullscreenElement') || Web.findProperty(document, 'fullScreenElement');\n document.addEventListener(sEvent, function onFullScreenChange() {\n video.notifyFullScreen(!!sFullScreen);\n }, false);\n }\n sEvent = Web.findProperty(document, 'on', 'fullscreenerror');\n if (sEvent) {\n document.addEventListener(sEvent, function onFullScreenError() {\n video.notifyFullScreen(null);\n }, false);\n }\n }\n }\n\n this.sFontROM = parmsVideo['fontROM'];\n if (this.sFontROM) {\n var sFileExt = Str.getExtension(this.sFontROM);\n if (sFileExt != \"json\") {\n this.sFontROM = Web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFontROM + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES;\n }\n Web.getResource(this.sFontROM, null, true, function(sURL, sResponse, nErrorCode) {\n video.doneLoad(sURL, sResponse, nErrorCode);\n });\n }\n\n this.ledBindings = {};\n }\n\n /**\n * initBuffers()\n *\n * @this {Video8080}\n * @return {boolean}\n */\n initBuffers()\n {\n /*\n * Allocate off-screen buffers now\n */\n this.cxBuffer = this.nColsBuffer * this.cxCell;\n this.cyBuffer = this.nRowsBuffer * this.cyCell;\n\n var cxBuffer = this.cxBuffer;\n var cyBuffer = this.cyBuffer;\n if (this.rotateBuffer) {\n cxBuffer = this.cyBuffer;\n cyBuffer = this.cxBuffer;\n }\n\n this.sizeBuffer = 0;\n if (!this.fUseRAM) {\n this.sizeBuffer = ((this.cxBuffer * this.nBitsPerPixel) >> 3) * this.cyBuffer;\n if (!this.bus.addMemory(this.addrBuffer, this.sizeBuffer, Memory8080.TYPE.VIDEO)) {\n return false;\n }\n }\n\n /*\n * imageBuffer is only used for graphics modes. For text modes, we create a canvas\n * for each font and draw characters by drawing from the font canvas to the target canvas.\n */\n if (this.sizeBuffer) {\n this.imageBuffer = this.contextScreen.createImageData(cxBuffer, cyBuffer);\n this.nPixelsPerCell = (16 / this.nBitsPerPixel)|0;\n this.initCellCache(this.sizeBuffer >> 1);\n } else {\n /*\n * We add an extra column per row to store the visible line length at the start of every row.\n */\n this.initCellCache((this.nColsBuffer + 1) * this.nRowsBuffer);\n }\n\n this.canvasBuffer = document.createElement(\"canvas\");\n this.canvasBuffer.width = cxBuffer;\n this.canvasBuffer.height = cyBuffer;\n this.contextBuffer = this.canvasBuffer.getContext(\"2d\");\n\n this.aFonts = {};\n this.initColors();\n\n if (this.nFormat == Video8080.FORMAT.VT100) {\n /*\n * Beyond fonts, VT100 support requires that we maintain a number of additional properties:\n *\n * rateMonitor: must be either 50 or 60 (defaults to 60); we don't emulate the monitor refresh rate,\n * but we do need to keep track of which rate has been selected, because that affects the number of\n * \"fill lines\" present at the top of the VT100's frame buffer: 2 lines for 60Hz, 5 lines for 50Hz.\n *\n * The VT100 July 1982 Technical Manual, p. 4-89, shows the following sample frame buffer layout:\n *\n * 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n * --------------------------------------------------------------\n * 0x2000: 7F 70 03 7F F2 D0 7F 70 06 7F 70 0C 7F 70 0F 7F\n * 0x2010: 70 03 .. .. .. .. .. .. .. .. .. .. .. .. .. ..\n * ...\n * 0x22D0: 'D' 'A' 'T' 'A' ' ' 'F' 'O' 'R' ' ' 'F' 'I' 'R' 'S' 'T' ' ' 'L'\n * 0x22E0: 'I' 'N' 'E' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '\n * ...\n * 0x2320: 7F F3 23 'D' 'A' 'T' 'A' ' ' 'F' 'O' 'R' ' ' 'S' 'E' 'C' 'O'\n * 0x2330: 'N' 'D' ' ' 'L' 'I' 'N' 'E' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '\n * ...\n * 0x2BE0: ' ' ' ' 'E' 'N' 'D' ' ' 'O' 'F' ' ' 'L' 'A' 'S' 'T' ' ' 'L' 'I'\n * 0x2BF0: 'N' 'E' 7F 70 06 .. .. .. .. .. .. .. .. .. .. ..\n * 0x2C00: [AVO SCREEN RAM, IF ANY, BEGINS HERE]\n *\n * ERRATA: The manual claims that if you change the byte at 0x2002 from 03 to 09, the number of \"fill\n * lines\" will change from 2 to 5 (for 50Hz operation), but it shows 06 instead of 0C at location 0x200B;\n * if you follow the links, it's pretty clear that byte has to be 0C to yield 5 \"fill lines\". Since the\n * address following the terminator at 0x2006 points to itself, it never makes sense for that terminator\n * to be used EXCEPT at the end of the frame buffer.\n *\n * As an alternative to tracking the monitor refresh rate, we could hard-code some knowledge about how\n * the VT100's 8080 code uses memory, and simply ignore lines below address 0x22D0. But the VT100 Video\n * Processor makes no such assumption, and it would also break our test code in createFonts(), which\n * builds a contiguous screen of test data starting at the default frame buffer address (0x2000).\n */\n this.rateMonitor = 60;\n\n /*\n * The default character-selectable attribute (reverse video vs. underline) is controlled by fUnderline.\n */\n this.fUnderline = false;\n\n this.abLineBuffer = new Array(this.nColsBuffer);\n }\n return true;\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {Video8080}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"refresh\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var video = this;\n\n /*\n * TODO: A more general-purpose binding mechanism would be nice someday....\n */\n if (sHTMLType == \"led\" || sHTMLType == \"rled\") {\n this.ledBindings[sBinding] = control;\n return true;\n }\n\n switch (sBinding) {\n case \"fullScreen\":\n this.bindings[sBinding] = control;\n if (this.container && this.container.doFullScreen) {\n control.onclick = function onClickFullScreen() {\n if (DEBUG) video.printMessage(\"fullScreen()\");\n video.doFullScreen();\n };\n } else {\n if (DEBUG) this.log(\"FullScreen API not available\");\n control.parentNode.removeChild(/** @type {Node} */ (control));\n }\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {Video8080}\n * @param {Computer8080} cmp\n * @param {Bus8080} bus\n * @param {CPUState8080} cpu\n * @param {Debugger8080} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n /*\n * Allocate the frame buffer (as needed) along with all other buffers.\n */\n this.initBuffers();\n\n /*\n * If we have an associated keyboard, then ensure that the keyboard will be notified\n * whenever the canvas gets focus and receives input.\n */\n this.kbd = /** @type {Keyboard8080} */ (cmp.getMachineComponent(\"Keyboard\"));\n if (this.kbd) {\n for (var s in this.ledBindings) {\n this.kbd.setBinding(\"led\", s, this.ledBindings[s]);\n }\n if (this.canvasScreen) {\n this.kbd.setBinding(this.textareaScreen? \"textarea\" : \"canvas\", \"screen\", /** @type {HTMLElement} */ (this.inputScreen));\n }\n }\n\n var video = this;\n this.timerUpdateNext = this.cpu.addTimer(this.id, function() {\n video.updateScreen();\n });\n this.cpu.setTimer(this.timerUpdateNext, this.getRefreshTime());\n this.nUpdates = 0;\n\n if (!this.sFontROM) this.setReady();\n }\n\n /**\n * doneLoad(sURL, sFontData, nErrorCode)\n *\n * @this {Video8080}\n * @param {string} sURL\n * @param {string} sFontData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n doneLoad(sURL, sFontData, nErrorCode)\n {\n if (nErrorCode) {\n this.notice(\"Unable to load font ROM (error \" + nErrorCode + \": \" + sURL + \")\");\n return;\n }\n\n Component.addMachineResource(this.idMachine, sURL, sFontData);\n\n try {\n /*\n * The most likely source of any exception will be here: parsing the JSON-encoded data.\n */\n var ab = eval(\"(\" + sFontData + \")\");\n\n var abFontData = ab['bytes'] || ab;\n\n if (!abFontData || !abFontData.length) {\n Component.error(\"Empty font ROM: \" + sURL);\n return;\n }\n else if (abFontData.length == 1) {\n Component.error(abFontData[0]);\n return;\n }\n\n /*\n * Minimal font data validation, just to make sure we're not getting garbage from the server.\n */\n if (abFontData.length == 2048) {\n this.abFontData = abFontData;\n this.createFonts();\n }\n else {\n this.notice(\"Unrecognized font data length (\" + abFontData.length + \")\");\n return;\n }\n\n } catch (e) {\n this.notice(\"Font ROM data error: \" + e.message);\n return;\n }\n\n /*\n * If we're still here, then we're ready!\n *\n * UPDATE: Per issue #21, I'm issuing setReady() *only* if a valid contextScreen exists *or* a Debugger is attached.\n *\n * TODO: Consider a more general-purpose solution for deciding whether or not the user wants to run in a \"headless\" mode.\n */\n if (this.contextScreen || this.dbg) this.setReady();\n }\n\n /**\n * createFonts()\n *\n * @this {Video8080}\n * @return {boolean}\n */\n createFonts()\n {\n /*\n * We retain abFontData in case we have to rebuild the fonts (eg, when we switch from 80 to 132 columns)\n */\n if (this.abFontData) {\n this.fDotStretcher = (this.nFormat == Video8080.FORMAT.VT100);\n this.aFonts[Video8080.VT100.FONT.NORML] = [\n this.createFontVariation(this.cxCell, this.cyCell),\n this.createFontVariation(this.cxCell, this.cyCell, this.fUnderline)\n ];\n this.aFonts[Video8080.VT100.FONT.DWIDE] = [\n this.createFontVariation(this.cxCell*2, this.cyCell),\n this.createFontVariation(this.cxCell*2, this.cyCell, this.fUnderline)\n ];\n this.aFonts[Video8080.VT100.FONT.DHIGH] = this.aFonts[Video8080.VT100.FONT.DHIGH_BOT] = [\n this.createFontVariation(this.cxCell*2, this.cyCell*2),\n this.createFontVariation(this.cxCell*2, this.cyCell*2, this.fUnderline)\n ];\n return true;\n }\n return false;\n }\n\n /**\n * createFontVariation(cxCell, cyCell, fUnderline)\n *\n * This creates a 16x16 character grid for the requested font variation. Variations include:\n *\n * 1) no variation (cell size is this.cxCell x this.cyCell)\n * 2) double-wide characters (cell size is this.cxCell*2 x this.cyCell)\n * 3) double-high double-wide characters (cell size is this.cxCell*2 x this.cyCell*2)\n * 4) any of the above with either reverse video or underline enabled (default is neither)\n *\n * @this {Video8080}\n * @param {number} cxCell is the target width of each character in the grid\n * @param {number} cyCell is the target height of each character in the grid\n * @param {boolean} [fUnderline] (null for unmodified font, false for reverse video, true for underline)\n * @return {Object}\n */\n createFontVariation(cxCell, cyCell, fUnderline)\n {\n /*\n * On a VT100, cxCell,cyCell is initially 10,10, but may change to 9,10 for 132-column mode.\n */\n\n\n\n /*\n * Create a font canvas that is both 16 times the target character width and the target character height,\n * ensuring that it will accommodate 16x16 characters (for a maximum of 256). Note that the VT100 font ROM\n * defines only 128 characters, so that canvas will contain only 16x8 entries.\n */\n var nFontBytesPerChar = this.cxCellDefault <= 8? 8 : 16;\n var nFontByteOffset = nFontBytesPerChar > 8? 15 : 0;\n var nChars = this.abFontData.length / nFontBytesPerChar;\n\n /*\n * The absence of a boolean for fUnderline means that both fReverse and fUnderline are \"falsey\". The presence\n * of a boolean means that fReverse will be true OR fUnderline will be true, but NOT both.\n */\n var fReverse = (fUnderline === false);\n\n var font = {cxCell: cxCell, cyCell: cyCell};\n font.canvas = document.createElement(\"canvas\");\n font.canvas.width = cxCell * 16;\n font.canvas.height = cyCell * (nChars / 16);\n font.context = font.canvas.getContext(\"2d\");\n\n var imageChar = font.context.createImageData(cxCell, cyCell);\n\n for (var iChar = 0; iChar < nChars; iChar++) {\n for (var y = 0, yDst = y; y < this.cyCell; y++) {\n var offFontData = iChar * nFontBytesPerChar + ((nFontByteOffset + y) & (nFontBytesPerChar - 1));\n var bits = (fUnderline && y == 8? 0xff : this.abFontData[offFontData]);\n for (var nRows = 0; nRows < (cyCell / this.cyCell); nRows++) {\n var bitPrev = 0;\n for (var x = 0, xDst = x; x < this.cxCell; x++) {\n /*\n * While x goes from 0 to cxCell-1, obviously we will run out of bits after x is 7;\n * since the final bit must be replicated all the way to the right edge of the cell\n * (so that line-drawing characters seamlessly connect), we ensure that the effective\n * shift count remains stuck at 7 once it reaches 7.\n */\n var bitReal = bits & (0x80 >> (x > 7? 7 : x));\n var bit = (this.fDotStretcher && !bitReal && bitPrev)? bitPrev : bitReal;\n for (var nCols = 0; nCols < (cxCell / this.cxCell); nCols++) {\n if (fReverse) bit = !bit;\n this.setPixel(imageChar, xDst, yDst, bit? 1 : 0);\n xDst++;\n }\n bitPrev = bitReal;\n }\n yDst++;\n }\n }\n /*\n * (iChar >> 4) performs the integer equivalent of Math.floor(iChar / 16), and (iChar & 0xf) is the equivalent of (iChar % 16).\n */\n font.context.putImageData(imageChar, (iChar & 0xf) * cxCell, (iChar >> 4) * cyCell);\n }\n return font;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {Video8080}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (data) {\n if (!this.restore(data)) return false;\n }\n }\n /*\n * Because the VT100 frame buffer can be located anywhere in RAM (above 0x2000), we must defer this\n * test code until the powerUp() notification handler is called, when all RAM has (hopefully) been allocated.\n *\n * NOTE: The following test screen was useful for early testing, but a *real* VT100 doesn't display a test screen,\n * so this code is no longer enabled by default. Remove MAXDEBUG if you want to see it again.\n */\n if (MAXDEBUG && this.nFormat == Video8080.FORMAT.VT100) {\n /*\n * Build a test screen in the VT100 frame buffer; we'll mimic the \"SET-UP A\" screen, since it uses\n * all the font variations. The process involves iterating over 0-based row numbers -2 (or -5 if 50Hz\n * operation is selected) through 24, checking aLineData for a matching row number, and converting the\n * corresponding string(s) to appropriate byte values. Negative row numbers correspond to \"fill lines\"\n * and do not require a row entry. If multiple strings are present for a given row, we invert the\n * default character attribute for subsequent strings. An empty array ends the screen build process.\n */\n var aLineData = {\n 0: [Video8080.VT100.FONT.DHIGH, 'SET-UP A'],\n 2: [Video8080.VT100.FONT.DWIDE, 'TO EXIT PRESS \"SET-UP\"'],\n 22: [Video8080.VT100.FONT.NORML, ' T T T T T T T T T'],\n 23: [Video8080.VT100.FONT.NORML, '1234567890', '1234567890', '1234567890', '1234567890', '1234567890', '1234567890', '1234567890', '1234567890'],\n 24: []\n };\n var addr = this.addrBuffer;\n var addrNext = -1, font = -1;\n var b, nFill = (this.rateMonitor == 60? 2 : 5);\n for (var iRow = -nFill; iRow < this.nRowsBuffer; iRow++) {\n var lineData = aLineData[iRow];\n if (addrNext >= 0) {\n var fBreak = false;\n addrNext = addr + 2;\n if (!lineData) {\n if (font == Video8080.VT100.FONT.DHIGH) {\n lineData = aLineData[iRow-1];\n font = Video8080.VT100.FONT.DHIGH_BOT;\n }\n }\n else {\n if (lineData.length) {\n font = lineData[0];\n } else {\n addrNext = addr - 1;\n fBreak = true;\n }\n }\n b = (font & Video8080.VT100.LINEATTR.FONTMASK) | ((addrNext >> 8) & Video8080.VT100.LINEATTR.ADDRMASK) | Video8080.VT100.LINEATTR.ADDRBIAS;\n this.bus.setByteDirect(addr++, b);\n this.bus.setByteDirect(addr++, addrNext & 0xff);\n if (fBreak) break;\n }\n if (lineData) {\n var attr = 0;\n for (var j = 1; j < lineData.length; j++) {\n var s = lineData[j];\n for (var k = 0; k < s.length; k++) {\n this.bus.setByteDirect(addr++, s.charCodeAt(k) | attr);\n }\n attr ^= 0x80;\n }\n }\n this.bus.setByteDirect(addr++, Video8080.VT100.LINETERM);\n addrNext = addr;\n }\n /*\n * NOTE: By calling updateVT100() directly, we are bypassing any checks that might block the update.\n */\n this.updateVT100();\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Video8080}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return !fSave || this.save();\n }\n\n /**\n * save()\n *\n * This implements save support for the Video8080 component.\n *\n * @this {Video8080}\n * @return {Object|null}\n */\n save()\n {\n var state = new State(this);\n state.set(0, []);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the Video8080 component.\n *\n * @this {Video8080}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n return true;\n }\n\n /**\n * updateDimensions(nCols, nRows)\n *\n * Called from the ChipSet component whenever the screen dimensions have been dynamically altered.\n *\n * @this {Video8080}\n * @param {number} nCols (should be either 80 or 132; 80 is the default)\n * @param {number} nRows (should be either 24 or 14; 24 is the default)\n */\n updateDimensions(nCols, nRows)\n {\n this.printMessage(\"updateDimensions(\" + nCols + \",\" + nRows + \")\");\n this.nColsBuffer = nCols;\n /*\n * Even when the number of effective rows is 14 (or 15 counting the scroll line buffer), we want\n * to leave the number of rows at 24 (or 25 counting the scroll line buffer), because the VT100 doesn't\n * actually change character height (only character width).\n *\n * this.nRowsBuffer = nRows+1; // +1 for scroll line buffer\n */\n this.cxCell = this.cxCellDefault;\n if (nCols > 80) this.cxCell--; // VT100 font cells are 9x10 instead of 10x10 in 132-column mode\n if (this.initBuffers()) {\n this.createFonts();\n }\n }\n\n /**\n * updateRate(nRate)\n *\n * Called from the ChipSet component whenever the monitor refresh rate has been dynamically altered.\n *\n * @this {Video8080}\n * @param {number} nRate (should be either 50 or 60; 60 is the default)\n */\n updateRate(nRate)\n {\n this.printMessage(\"updateRate(\" + nRate + \")\");\n this.rateMonitor = nRate;\n }\n\n /**\n * updateScrollOffset(bScroll)\n *\n * Called from the ChipSet component whenever the screen scroll offset has been dynamically altered.\n *\n * @this {Video8080}\n * @param {number} bScroll\n */\n updateScrollOffset(bScroll)\n {\n this.printMessage(\"updateScrollOffset(\" + bScroll + \")\");\n if (this.bScrollOffset !== bScroll) {\n this.bScrollOffset = bScroll;\n /*\n * WARNING: If we immediately redraw the screen on the first wrap of the scroll offset back to zero,\n * we end up \"slamming\" the screen's contents back down again, because it seems that the frame buffer\n * contents haven't actually been scrolled yet. So we redraw now ONLY if bScroll is non-zero, lest\n * we ruin the smooth-scroll effect.\n *\n * And this change, while necessary, is not sufficient, because another intervening updateScreen()\n * call could still occur before the frame buffer contents are actually scrolled; and ordinarily, if the\n * buffer hasn't changed, updateScreen() would do nothing, but alas, if the cursor happens to get toggled\n * in the interim, updateScreen() will want to update exactly ONE cell.\n *\n * So we deal with that by setting the fSkipSingleCellUpdate flag. Now of course, there's no guarantee\n * that the next update of only ONE cell will always be a cursor update, but even if it isn't, skipping\n * that update doesn't seem like a huge cause for concern.\n */\n if (bScroll) {\n this.updateScreen(true);\n } else {\n this.fSkipSingleCellUpdate = true;\n }\n }\n }\n\n /**\n * doFullScreen()\n *\n * @this {Video8080}\n * @return {boolean} true if request successful, false if not (eg, failed OR not supported)\n */\n doFullScreen()\n {\n var fSuccess = false;\n if (this.container) {\n if (this.container.doFullScreen) {\n /*\n * Styling the container with a width of \"100%\" and a height of \"auto\" works great when the aspect ratio\n * of our virtual screen is at least roughly equivalent to the physical screen's aspect ratio, but now that\n * we support virtual VGA screens with an aspect ratio of 1.33, that's very much out of step with modern\n * wide-screen monitors, which usually have an aspect ratio of 1.6 or greater.\n *\n * And unfortunately, none of the browsers I've tested appear to make any attempt to scale our container to\n * the physical screen's dimensions, so the bottom of our screen gets clipped. To prevent that, I reduce\n * the width from 100% to whatever percentage will accommodate the entire height of the virtual screen.\n *\n * NOTE: Mozilla recommends both a width and a height of \"100%\", but all my tests suggest that using \"auto\"\n * for height works equally well, so I'm sticking with it, because \"auto\" is also consistent with how I've\n * implemented a responsive canvas when the browser window is being resized.\n */\n var sWidth = \"100%\";\n var sHeight = \"auto\";\n if (screen && screen.width && screen.height) {\n var aspectPhys = screen.width / screen.height;\n var aspectVirt = this.cxScreen / this.cyScreen;\n if (aspectPhys > aspectVirt) {\n sWidth = Math.round(aspectVirt / aspectPhys * 100) + '%';\n }\n // TODO: We may need to someday consider the case of a physical screen with an aspect ratio < 1.0....\n }\n if (!this.fGecko) {\n this.container.style.width = sWidth;\n this.container.style.height = sHeight;\n } else {\n /*\n * Sadly, the above code doesn't work for Firefox, because as http://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode\n * explains:\n *\n * 'It's worth noting a key difference here between the Gecko and WebKit implementations at this time:\n * Gecko automatically adds CSS rules to the element to stretch it to fill the screen: \"width: 100%; height: 100%\".\n *\n * Which would be OK if Gecko did that BEFORE we're called, but apparently it does that AFTER, effectively\n * overwriting our careful calculations. So we style the inner element (canvasScreen) instead, which\n * requires even more work to ensure that the canvas is properly centered. FYI, this solution is consistent\n * with Mozilla's recommendation for working around their automatic CSS rules:\n *\n * '[I]f you're trying to emulate WebKit's behavior on Gecko, you need to place the element you want\n * to present inside another element, which you'll make fullscreen instead, and use CSS rules to adjust\n * the inner element to match the appearance you want.'\n */\n this.canvasScreen.style.width = sWidth;\n this.canvasScreen.style.width = sWidth;\n this.canvasScreen.style.display = \"block\";\n this.canvasScreen.style.margin = \"auto\";\n }\n this.container.style.backgroundColor = \"black\";\n this.container.doFullScreen();\n fSuccess = true;\n }\n this.setFocus();\n }\n return fSuccess;\n }\n\n /**\n * notifyFullScreen(fFullScreen)\n *\n * @this {Video8080}\n * @param {boolean|null} fFullScreen (null if there was a full-screen error)\n */\n notifyFullScreen(fFullScreen)\n {\n if (!fFullScreen && this.container) {\n if (!this.fGecko) {\n this.container.style.width = this.container.style.height = \"\";\n } else {\n this.canvasScreen.style.width = this.canvasScreen.style.height = \"\";\n }\n }\n this.printMessage(\"notifyFullScreen(\" + fFullScreen + \")\");\n }\n\n /**\n * setFocus()\n *\n * @this {Video8080}\n */\n setFocus()\n {\n if (this.inputScreen) this.inputScreen.focus();\n }\n\n /**\n * getRefreshTime()\n *\n * @this {Video8080}\n * @return {number} (number of milliseconds per refresh)\n */\n getRefreshTime()\n {\n return 1000 / Math.max(this.rateRefresh, this.rateInterrupt);\n }\n\n /**\n * initCellCache(nCells)\n *\n * Initializes the contents of our internal cell cache.\n *\n * @this {Video8080}\n * @param {number} nCells\n */\n initCellCache(nCells)\n {\n this.nCellCache = nCells;\n this.fCellCacheValid = false;\n if (this.aCellCache === undefined || this.aCellCache.length != this.nCellCache) {\n this.aCellCache = new Array(this.nCellCache);\n }\n }\n\n /**\n * initColors()\n *\n * This creates an array of nColors, with additional OVERLAY_TOTAL colors tacked on to the end of the array.\n *\n * @this {Video8080}\n */\n initColors()\n {\n var rgbBlack = [0x00, 0x00, 0x00, 0xff];\n var rgbWhite = [0xff, 0xff, 0xff, 0xff];\n this.nColors = (1 << this.nBitsPerPixel);\n this.aRGB = new Array(this.nColors + Video8080.COLORS.OVERLAY_TOTAL);\n this.aRGB[0] = rgbBlack;\n this.aRGB[1] = rgbWhite;\n if (this.nFormat == Video8080.FORMAT.SI1978) {\n var rgbGreen = [0x00, 0xff, 0x00, 0xff];\n //noinspection UnnecessaryLocalVariableJS\n var rgbYellow = [0xff, 0xff, 0x00, 0xff];\n this.aRGB[this.nColors + Video8080.COLORS.OVERLAY_TOP] = rgbYellow;\n this.aRGB[this.nColors + Video8080.COLORS.OVERLAY_BOTTOM] = rgbGreen;\n }\n }\n\n /**\n * setPixel(image, x, y, bPixel)\n *\n * @this {Video8080}\n * @param {Object} image\n * @param {number} x\n * @param {number} y\n * @param {number} bPixel (ie, an index into aRGB)\n */\n setPixel(image, x, y, bPixel)\n {\n var index;\n if (!this.rotateBuffer) {\n index = (x + y * image.width);\n } else {\n index = (image.height - x - 1) * image.width + y;\n }\n if (bPixel && this.nFormat == Video8080.FORMAT.SI1978) {\n if (x >= 208 && x < 236) {\n bPixel = this.nColors + Video8080.COLORS.OVERLAY_TOP;\n }\n else if (x >= 28 && x < 72) {\n bPixel = this.nColors + Video8080.COLORS.OVERLAY_BOTTOM;\n }\n }\n var rgb = this.aRGB[bPixel];\n index *= rgb.length;\n image.data[index] = rgb[0];\n image.data[index+1] = rgb[1];\n image.data[index+2] = rgb[2];\n image.data[index+3] = rgb[3];\n }\n\n /**\n * updateChar(idFont, col, row, data, context)\n *\n * Updates a particular character cell (row,col) in the associated window.\n *\n * @this {Video8080}\n * @param {number} idFont\n * @param {number} col\n * @param {number} row\n * @param {number} data\n * @param {Object} [context]\n */\n updateChar(idFont, col, row, data, context)\n {\n var bChar = data & 0x7f;\n var font = this.aFonts[idFont][(data & 0x80)? 1 : 0];\n if (!font) return;\n\n var xSrc = (bChar & 0xf) * font.cxCell;\n var ySrc = (bChar >> 4) * font.cyCell;\n\n var xDst, yDst, cxDst, cyDst;\n\n var cxSrc = font.cxCell;\n var cySrc = font.cyCell;\n\n if (context) {\n xDst = col * this.cxCell;\n yDst = row * this.cyCell;\n cxDst = this.cxCell;\n cyDst = this.cyCell;\n } else {\n xDst = col * this.cxScreenCell;\n yDst = row * this.cyScreenCell;\n cxDst = this.cxScreenCell;\n cyDst = this.cyScreenCell;\n }\n\n /*\n * If font.cxCell > this.cxCell, then we assume the caller wants to draw a double-wide character,\n * so we will double xDst and cxDst.\n */\n if (font.cxCell > this.cxCell) {\n xDst *= 2;\n cxDst *= 2;\n\n }\n\n /*\n * If font.cyCell > this.cyCell, then we rely on idFont to indicate whether the top half or bottom half\n * of the character should be drawn.\n */\n if (font.cyCell > this.cyCell) {\n if (idFont == Video8080.VT100.FONT.DHIGH_BOT) ySrc += this.cyCell;\n cySrc = this.cyCell;\n\n }\n\n if (context) {\n context.drawImage(font.canvas, xSrc, ySrc, cxSrc, cySrc, xDst, yDst, cxDst, cyDst);\n } else {\n xDst += this.xScreenOffset;\n yDst += this.yScreenOffset;\n this.contextScreen.drawImage(font.canvas, xSrc, ySrc, cxSrc, cySrc, xDst, yDst, cxDst, cyDst);\n }\n }\n\n /**\n * updateVT100(fForced)\n *\n * @this {Video8080}\n * @param {boolean} [fForced]\n */\n updateVT100(fForced)\n {\n var addrNext = this.addrBuffer, fontNext = -1;\n\n var nRows = 0;\n var nFill = (this.rateMonitor == 60? 2 : 5);\n var iCell = 0, cUpdated = 0, iCellUpdated = -1;\n\n\n\n while (nRows < this.nRowsBuffer) {\n /*\n * Populate the line buffer\n */\n var nCols = 0;\n var addr = addrNext;\n var font = fontNext;\n var nColsVisible = this.nColsBuffer;\n if (font != Video8080.VT100.FONT.NORML) nColsVisible >>= 1;\n while (true) {\n var data = this.bus.getByteDirect(addr++);\n if ((data & Video8080.VT100.LINETERM) == Video8080.VT100.LINETERM) {\n var b = this.bus.getByteDirect(addr++);\n fontNext = b & Video8080.VT100.LINEATTR.FONTMASK;\n addrNext = ((b & Video8080.VT100.LINEATTR.ADDRMASK) << 8) | this.bus.getByteDirect(addr);\n addrNext += (b & Video8080.VT100.LINEATTR.ADDRBIAS)? Video8080.VT100.ADDRBIAS_LO : Video8080.VT100.ADDRBIAS_HI;\n break;\n }\n if (nCols < nColsVisible) {\n this.abLineBuffer[nCols++] = data;\n } else {\n break; // ideally, we would wait for a LINETERM byte, but it's not safe to loop without limit\n }\n }\n\n /*\n * Skip the first few \"fill lines\"\n */\n if (nFill) {\n nFill--;\n continue;\n }\n\n /*\n * Pad the line buffer as needed\n */\n while (nCols < this.abLineBuffer.length) {\n this.abLineBuffer[nCols++] = 0; // character code 0 is a empty font character\n }\n\n /*\n * Display the line buffer; ordinarily, the font number would be valid after processing the \"fill lines\",\n * but if the buffer isn't initialized yet, those lines might be missing, so the font number might not be set.\n */\n if (font >= 0) {\n /*\n * Cell cache logic is complicated by the fact that a line may be single-width one frame and double-width\n * the next. So we store the visible line length at the start of each row in the cache, which must match if\n * the cache can be considered valid for the current line.\n */\n var fLineCacheValid = this.fCellCacheValid && (this.aCellCache[iCell] == nColsVisible);\n this.aCellCache[iCell++] = nColsVisible;\n for (var iCol = 0; iCol < nCols; iCol++) {\n data = this.abLineBuffer[iCol];\n if (!fLineCacheValid || data !== this.aCellCache[iCell]) {\n this.aCellCache[iCellUpdated = iCell] = data;\n this.updateChar(font, iCol, nRows, data, this.contextBuffer);\n cUpdated++;\n }\n iCell++;\n }\n }\n nRows++;\n }\n\n this.fCellCacheValid = true;\n\n\n\n if (!fForced && this.fSkipSingleCellUpdate && cUpdated == 1) {\n /*\n * We're going to blow off this update, since it comes on the heels of a smooth-scroll that *may*\n * not be completely finished yet, and at the same time, we're going to zap the only updated cell\n * cache entry, to guarantee that it's redrawn on the next update.\n */\n\n /*\n * TODO: If I change the RECV rate to 19200 and enable smooth scrolling, I sometimes see a spurious\n * \"H\" on the bottom line after a long series of \"HELLO WORLD!\\r\\n\" tests. Dumping video memory shows\n * \"HELLO WORLD!\" on 23 lines and an \"H\" on the 24th line, so it's really there. But strangely, if\n * I then press SET-UP two times, the restored screen does NOT have the spurious \"H\". So somehow the\n * firmware knows what should and shouldn't be on-screen.\n *\n * Possible VT100 firmware bug? I'm not sure. Anyway, this DEBUG-only code is here to help trap\n * that scenario, until I figure it out.\n */\n if (DEBUG && (this.aCellCache[iCellUpdated] & 0x7f) == 0x48) {\n console.log(\"spurious character?\");\n }\n this.aCellCache[iCellUpdated] = -1;\n cUpdated = 0;\n }\n this.fSkipSingleCellUpdate = false;\n\n if ((cUpdated || fForced) && this.contextBuffer) {\n /*\n * We must subtract cyCell from cyBuffer to avoid displaying the extra \"scroll line\" that we normally\n * buffer, in support of smooth scrolling. Speaking of which, we must also add bScrollOffset to ySrc\n * (well, ySrc is always relative to zero, so no add is actually required).\n */\n this.contextScreen.drawImage(\n this.canvasBuffer,\n 0, // xSrc\n this.bScrollOffset, // ySrc\n this.cxBuffer, // cxSrc\n this.cyBuffer - this.cyCell, // cySrc\n this.xScreenOffset, // xDst\n this.yScreenOffset, // yDst\n this.cxScreenOffset, // cxDst\n this.cyScreenOffset // cyDst\n );\n }\n }\n\n /**\n * updateScreen(fForced)\n *\n * Propagates the video buffer to the cell cache and updates the screen with any changes. Forced updates\n * are generally internal updates triggered by an I/O operation or other state change, while non-forced updates\n * are the periodic updates coming from the CPU.\n *\n * For every cell in the video buffer, compare it to the cell stored in the cell cache, render if it differs,\n * and then update the cell cache to match. Since initCellCache() sets every cell in the cell cache to an\n * invalid value, we're assured that the next call to updateScreen() will redraw the entire (visible) video buffer.\n *\n * @this {Video8080}\n * @param {boolean} [fForced]\n */\n updateScreen(fForced)\n {\n var fUpdate = true;\n\n if (!fForced) {\n if (this.rateInterrupt) {\n /*\n * TODO: Incorporate these hard-coded interrupt vector numbers into configuration blocks.\n */\n if (this.rateInterrupt == 120) {\n if (!(this.nUpdates & 1)) {\n /*\n * On even updates, call cpu.requestINTR(1), and also update our copy of the screen.\n */\n this.cpu.requestINTR(1);\n } else {\n /*\n * On odd updates, call cpu.requestINTR(2), but do NOT update our copy of the screen, because\n * the machine has presumably only updated the top half of the frame buffer at this point; it will\n * update the bottom half of the frame buffer after acknowledging this interrupt.\n */\n this.cpu.requestINTR(2);\n fUpdate = false;\n }\n } else {\n this.cpu.requestINTR(4);\n }\n }\n\n /*\n * Since this is not a forced update, if our cell cache is valid AND we allocated our own buffer AND the buffer\n * is clean, then there's nothing to do.\n */\n if (fUpdate && this.fCellCacheValid && this.sizeBuffer) {\n if (this.bus.cleanMemory(this.addrBuffer, this.sizeBuffer)) {\n fUpdate = false;\n }\n }\n this.cpu.setTimer(this.timerUpdateNext, this.getRefreshTime());\n this.nUpdates++;\n }\n\n if (!fUpdate) {\n return;\n }\n\n if (this.cxCell > 1) {\n this.updateScreenText(fForced);\n } else {\n this.updateScreenGraphics(fForced);\n }\n }\n\n /**\n * updateScreenText(fForced)\n *\n * @this {Video8080}\n * @param {boolean} [fForced]\n */\n updateScreenText(fForced)\n {\n switch(this.nFormat) {\n case Video8080.FORMAT.VT100:\n this.updateVT100(fForced);\n break;\n }\n }\n\n /**\n * updateScreenGraphics(fForced)\n *\n * @this {Video8080}\n * @param {boolean} [fForced]\n */\n updateScreenGraphics(fForced)\n {\n var addr = this.addrBuffer;\n var addrLimit = addr + this.sizeBuffer;\n\n var iCell = 0;\n var nPixelShift = 1;\n\n var xBuffer = 0, yBuffer = 0;\n var xDirty = this.cxBuffer, xMaxDirty = 0, yDirty = this.cyBuffer, yMaxDirty = 0;\n\n var nShiftInit = 0;\n var nShiftPixel = this.nBitsPerPixel;\n var nMask = (1 << nShiftPixel) - 1;\n if (this.iBitFirstPixel) {\n nShiftPixel = -nShiftPixel;\n nShiftInit = 16 + nShiftPixel;\n }\n\n while (addr < addrLimit) {\n var data = this.bus.getShortDirect(addr);\n\n if (this.fCellCacheValid && data === this.aCellCache[iCell]) {\n xBuffer += this.nPixelsPerCell;\n } else {\n this.aCellCache[iCell] = data;\n var nShift = nShiftInit;\n if (nShift) data = ((data >> 8) | ((data & 0xff) << 8));\n if (xBuffer < xDirty) xDirty = xBuffer;\n var cPixels = this.nPixelsPerCell;\n while (cPixels--) {\n var bPixel = (data >> nShift) & nMask;\n this.setPixel(this.imageBuffer, xBuffer++, yBuffer, bPixel);\n nShift += nShiftPixel;\n }\n if (xBuffer > xMaxDirty) xMaxDirty = xBuffer;\n if (yBuffer < yDirty) yDirty = yBuffer;\n if (yBuffer >= yMaxDirty) yMaxDirty = yBuffer + 1;\n }\n addr += 2; iCell++;\n if (xBuffer >= this.cxBuffer) {\n xBuffer = 0; yBuffer++;\n if (yBuffer > this.cyBuffer) break;\n }\n }\n\n this.fCellCacheValid = true;\n\n /*\n * Instead of blasting the ENTIRE imageBuffer into contextBuffer, and then blasting the ENTIRE\n * canvasBuffer onto contextScreen, even for the smallest change, let's try to be a bit smarter about\n * the update (well, to the extent that the canvas APIs permit).\n */\n if (xDirty < this.cxBuffer) {\n var cxDirty = xMaxDirty - xDirty;\n var cyDirty = yMaxDirty - yDirty;\n if (this.rotateBuffer) {\n /*\n * If rotateBuffer is set, then it must be -90, so we must \"rotate\" the dirty coordinates as well,\n * because they are relative to the frame buffer, not the rotated image buffer. Alternatively, you\n * can use the following call to blast the ENTIRE imageBuffer into contextBuffer instead:\n *\n * this.contextBuffer.putImageData(this.imageBuffer, 0, 0);\n */\n var xDirtyOrig = xDirty, cxDirtyOrig = cxDirty;\n //noinspection JSSuspiciousNameCombination\n xDirty = yDirty;\n cxDirty = cyDirty;\n yDirty = this.cxBuffer - (xDirtyOrig + cxDirtyOrig);\n cyDirty = cxDirtyOrig;\n }\n this.contextBuffer.putImageData(this.imageBuffer, 0, 0, xDirty, yDirty, cxDirty, cyDirty);\n /*\n * As originally noted in /modules/pcx86/lib/video.js, I would prefer to draw only the dirty portion of\n * canvasBuffer, but there usually isn't a 1-1 pixel mapping between canvasBuffer and contextScreen, so\n * if we draw interior rectangles, we can end up with subpixel artifacts along the edges of those rectangles.\n */\n this.contextScreen.drawImage(this.canvasBuffer, 0, 0, this.canvasBuffer.width, this.canvasBuffer.height, 0, 0, this.cxScreen, this.cyScreen);\n }\n }\n\n /**\n * Video8080.init()\n *\n * This function operates on every HTML element of class \"video\", extracting the\n * JSON-encoded parameters for the Video constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Video component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeVideo = Component.getElementsByClass(document, PC8080.APPCLASS, \"video\");\n for (var iVideo = 0; iVideo < aeVideo.length; iVideo++) {\n var eVideo = aeVideo[iVideo];\n var parmsVideo = Component.getComponentParms(eVideo);\n\n var eCanvas = document.createElement(\"canvas\");\n if (eCanvas === undefined || !eCanvas.getContext) {\n eVideo.innerHTML = \"<br/>Missing <canvas> support. Please try a newer web browser.\";\n return;\n }\n\n eCanvas.setAttribute(\"class\", \"pcjs-canvas\");\n eCanvas.setAttribute(\"width\", parmsVideo['screenWidth']);\n eCanvas.setAttribute(\"height\", parmsVideo['screenHeight']);\n eCanvas.style.backgroundColor = parmsVideo['screenColor'];\n\n /*\n * The \"contenteditable\" attribute on a canvas element NOTICEABLY slows down canvas drawing on\n * Safari as soon as you give the canvas focus (ie, click away from the canvas, and drawing speeds\n * up; click on the canvas, and drawing slows down). So the \"transparent textarea hack\" that we\n * once employed as only a work-around for Android devices is now our default.\n *\n * eCanvas.setAttribute(\"contenteditable\", \"true\");\n *\n * HACK: A canvas style of \"auto\" provides for excellent responsive canvas scaling in EVERY browser\n * except IE9/IE10, so I recalculate the appropriate CSS height every time the parent DIV is resized;\n * IE11 works without this hack, so we take advantage of the fact that IE11 doesn't identify as \"MSIE\".\n *\n * The other reason it's good to keep this particular hack limited to IE9/IE10 is that most other\n * browsers don't actually support an 'onresize' handler on anything but the window object.\n */\n eCanvas.style.height = \"auto\";\n if (Web.getUserAgent().indexOf(\"MSIE\") >= 0) {\n eVideo.onresize = function(eParent, eChild, cx, cy) {\n return function onResizeVideo() {\n eChild.style.height = (((eParent.clientWidth * cy) / cx) | 0) + \"px\";\n };\n }(eVideo, eCanvas, parmsVideo['screenWidth'], parmsVideo['screenHeight']);\n eVideo.onresize();\n }\n /*\n * The following is a related hack that allows the user to force the screen to use a particular aspect\n * ratio if an 'aspect' attribute or URL parameter is set. Initially, it's just for testing purposes\n * until we figure out a better UI. And note that we use our web.onPageEvent() helper function to make\n * sure we don't trample any other 'onresize' handler(s) attached to the window object.\n */\n var aspect = +(parmsVideo['aspect'] || Web.getURLParm('aspect'));\n /*\n * No 'aspect' parameter yields NaN, which is falsey, and anything else must satisfy my arbitrary\n * constraints of 0.3 <= aspect <= 3.33, to prevent any useless (or worse, browser-blowing) results.\n */\n if (aspect && aspect >= 0.3 && aspect <= 3.33) {\n Web.onPageEvent('onresize', function(eParent, eChild, aspectRatio) {\n return function onResizeWindow() {\n /*\n * Since aspectRatio is the target width/height, we have:\n *\n * eParent.clientWidth / eChild.style.height = aspectRatio\n *\n * which means that:\n *\n * eChild.style.height = eParent.clientWidth / aspectRatio\n *\n * so for example, if aspectRatio is 16:9, or 1.78, and clientWidth = 640,\n * then the calculated height should approximately 360.\n */\n eChild.style.height = ((eParent.clientWidth / aspectRatio)|0) + \"px\";\n };\n }(eVideo, eCanvas, aspect));\n window['onresize']();\n }\n eVideo.appendChild(eCanvas);\n\n /*\n * HACK: Android-based browsers, like the Silk (Amazon) browser and Chrome for Android, don't honor the\n * \"contenteditable\" attribute; that is, when the canvas receives focus, they don't activate the on-screen\n * keyboard. So my fallback is to create a transparent textarea on top of the canvas.\n *\n * The parent DIV must have a style of \"position:relative\" (alternatively, a class of \"pcjs-container\"),\n * so that we can position the textarea using absolute coordinates. Also, we don't want the textarea to be\n * visible, but we must use \"opacity:0\" instead of \"visibility:hidden\", because the latter seems to prevent\n * the element from receiving events. These styling requirements are taken care of in components.css\n * (see references to the \"pcjs-video-object\" class).\n *\n * UPDATE: Unfortunately, Android keyboards like to compose whole words before transmitting any of the\n * intervening characters; our textarea's keyDown/keyUp event handlers DO receive intervening key events,\n * but their keyCode property is ZERO. Virtually the only usable key event we receive is the Enter key.\n * Android users will have to use machines that include their own on-screen \"soft keyboard\", or use an\n * external keyboard.\n *\n * The following attempt to use a password-enabled input field didn't work any better on Android. You could\n * clearly see the overlaid semi-transparent input field, but none of the input characters were passed along,\n * with the exception of the \"Go\" (Enter) key.\n *\n * var eInput = document.createElement(\"input\");\n * eInput.setAttribute(\"type\", \"password\");\n * eInput.setAttribute(\"style\", \"position:absolute; left:0; top:0; width:100%; height:100%; opacity:0.5\");\n * eVideo.appendChild(eInput);\n *\n * See this Chromium issue for more information: https://code.google.com/p/chromium/issues/detail?id=118639\n */\n var eTextArea = document.createElement(\"textarea\");\n\n /*\n * As noted in keyboard.js, the keyboard on an iOS device tends to pop up with the SHIFT key depressed,\n * which is not the initial keyboard state that the Keyboard component expects, so hopefully turning off\n * these \"auto\" attributes will help.\n */\n if (Web.isUserAgent(\"iOS\")) {\n eTextArea.setAttribute(\"autocapitalize\", \"off\");\n eTextArea.setAttribute(\"autocorrect\", \"off\");\n /*\n * One of the problems on iOS devices is that after a soft-key control is clicked, we need to give\n * focus back to the above textarea, usually by calling cmp.updateFocus(), but in doing so, iOS may\n * also \"zoom\" the page rather jarringly. While it's a simple matter to completely disable zooming,\n * by fiddling with the page's viewport, that prevents the user from intentionally zooming. A bit of\n * Googling reveals that another way to prevent those jarring unintentional zooms is to simply set the\n * font-size of the text control to 16px. So that's what we do.\n */\n eTextArea.style.fontSize = \"16px\";\n }\n eVideo.appendChild(eTextArea);\n\n /*\n * Now we can create the Video object, record it, and wire it up to the associated document elements.\n */\n var eContext = eCanvas.getContext(\"2d\");\n var video = new Video8080(parmsVideo, eCanvas, eContext, eTextArea /* || eInput */, eVideo);\n\n /*\n * Bind any video-specific controls (eg, the Refresh button). There are no essential controls, however;\n * even the \"Refresh\" button is just a diagnostic tool, to ensure that the screen contents are up-to-date.\n */\n Component.bindComponentControls(video, eVideo, PC8080.APPCLASS);\n }\n }\n}\n\nVideo8080.COLORS = {\n OVERLAY_TOP: 0,\n OVERLAY_BOTTOM: 1,\n OVERLAY_TOTAL: 2\n};\n\nVideo8080.FORMAT = {\n UNKNOWN: 0,\n SI1978: 1,\n VT100: 2\n};\n\nVideo8080.FORMATS = {\n \"SI1978\": Video8080.FORMAT.SI1978,\n \"VT100\": Video8080.FORMAT.VT100\n};\n\n\nVideo8080.VT100 = {\n /*\n * The following font IDs are nothing more than all the possible LINEATTR values masked with FONTMASK;\n * also, note that double-high implies double-wide; the VT100 doesn't support a double-high single-wide font.\n */\n FONT: {\n NORML: 0x60, // normal font (eg, 10x10)\n DWIDE: 0x40, // double-wide, single-high font (eg, 20x10)\n DHIGH: 0x20, // technically, this means display only the TOP half of the double-high font (eg, 20x20)\n DHIGH_BOT: 0x00 // technically, this means display only the BOTTOM half of the double-high font (eg, 20x20)\n },\n LINETERM: 0x7F,\n LINEATTR: {\n ADDRMASK: 0x0F,\n ADDRBIAS: 0x10, // 0x10 == ADDRBIAS_LO, 0x00 = ADDRBIAS_HI\n FONTMASK: 0x60,\n SCROLL: 0x80\n },\n ADDRBIAS_LO: 0x2000,\n ADDRBIAS_HI: 0x4000\n};\n\n/*\n * Initialize every Video module on the page.\n */\nWeb.onInit(Video8080.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/serial.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * SerialPort8080 class\n *\n * The class property declarations below started as a way of informing the code inspector of the controlBuffer\n * property, which remained undefined until a setBinding() call set it later, but I've since decided that explicitly\n * initializing such properties in the constructor is a better way to go -- even though it's more code -- because\n * JavaScript compilers are supposed to be happier when the underlying object structures aren't constantly changing.\n *\n * Besides, I'm not sure I want to get into documenting every property this way, for this or any/every other class,\n * let alone getting into which ones should be considered private or protected, because PCjs isn't really a library\n * for third-party apps.\n * \n * @class SerialPort8080\n * @property {number} iAdapter\n * @property {number} portBase\n * @property {number} nIRQ\n * @property {Object} controlBuffer is a DOM element bound to the port (for rudimentary output; see transmitByte())\n * @unrestricted\n */\nclass SerialPort8080 extends Component {\n /**\n * SerialPort8080(parmsSerial)\n *\n * The SerialPort8080 component has the following component-specific (parmsSerial) properties:\n *\n * adapter: 0 if not defined\n *\n * binding: name of a control (based on its \"binding\" attribute) to bind to this port's I/O\n *\n * tabSize: set to a non-zero number to convert tabs to spaces (applies only to output to\n * the above binding); default is 0 (no conversion)\n *\n * In the future, we may support 'port' and 'irq' properties that allow the machine to define a\n * non-standard serial port configuration, instead of only our pre-defined 'adapter' configurations.\n *\n * NOTE: Since the XSL file defines 'adapter' as a number, not a string, there's no need to use\n * parseInt(), and as an added benefit, we don't need to worry about whether a hex or decimal format\n * was used.\n *\n * @this {SerialPort8080}\n * @param {Object} parmsSerial\n */\n constructor(parmsSerial)\n {\n super(\"SerialPort\", parmsSerial, Messages8080.SERIAL);\n\n this.iAdapter = +parmsSerial['adapter'];\n\n switch (this.iAdapter) {\n case 0:\n this.portBase = 0;\n this.nIRQ = 2;\n break;\n default:\n Component.warning(\"Unrecognized serial adapter #\" + this.iAdapter);\n return;\n }\n /**\n * consoleBuffer becomes a string that records serial port output if the 'binding' property is set to the\n * reserved name \"console\". Nothing is written to the console, however, until a linefeed (0x0A) is output\n * or the string length reaches a threshold (currently, 1024 characters).\n *\n * @type {string|null}\n */\n this.consoleBuffer = null;\n\n /**\n * controlBuffer is a DOM element bound to the port (currently used for output only; see transmitByte()).\n *\n * @type {Object}\n */\n this.controlBuffer = null;\n\n /*\n * If controlBuffer is being used AND 'tabSize' is set, then we make an attempt to monitor the characters\n * being echoed via transmitByte(), maintain a logical column position, and convert any tabs into the appropriate\n * number of spaces.\n *\n * charBOL, if nonzero, is a character to automatically output at the beginning of every line. This probably\n * isn't generally useful; I use it internally to preformat serial output.\n */\n this.tabSize = parmsSerial['tabSize'];\n this.charBOL = parmsSerial['charBOL'];\n this.iLogicalCol = 0;\n\n /*\n * fAutoXOFF enables some experimental auto-XOFF/XON processing. It assumes if the VT100 firmware\n * issues an XOFF, receiveByte() should stop accepting more data until the firmware issues an XOFF.\n *\n * The downside is that this doesn't really do anything to stem the flow of incoming data; it just\n * prevents the VT100's internal buffer from overflowing. TODO: Eliminate the need for this hack\n * and add some *real* flow-control interfaces between connected SerialPort components.\n */\n this.fAutoXOFF = true;\n this.fAutoStop = false;\n this.fNullModem = true;\n\n var sBinding = parmsSerial['binding'];\n if (sBinding == \"console\") {\n this.consoleBuffer = \"\";\n } else {\n /*\n * If the SerialPort wants to bind to a control (eg, \"print\") in a DIFFERENT component (eg, \"Panel\"),\n * then it specifies the name of that control with the 'binding' property. The SerialPort constructor\n * will then call bindExternalControl(), which looks up the control, and then passes it to our own\n * setBinding() handler.\n * \n * For bindExternalControl() to succeed, it also need to know the target component; for now, that's\n * been hard-coded to \"Panel\", in part because that's one of the few components we can rely upon\n * initializing before we do, but it would be a simple matter to include a component type or ID as part\n * of the 'binding' property as well, if we need more flexibility later.\n * \n * NOTE: If sBinding is not the name of a valid Control Panel DOM element, this call does nothing.\n */\n Component.bindExternalControl(this, sBinding);\n }\n\n /*\n * No connection until initConnection() is called.\n */\n this.sDataReceived = \"\";\n this.connection = this.sendData = this.updateStatus = null;\n\n /*\n * Export all functions required by initConnection().\n */\n this['exports'] = {\n 'connect': this.initConnection,\n 'receiveData': this.receiveData,\n 'receiveStatus': this.receiveStatus\n };\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {SerialPort8080}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"buffer\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var serial = this;\n \n if (!sHTMLType || sHTMLType == \"textarea\") {\n\n this.bindings[sBinding] = this.controlBuffer = control;\n\n /*\n * By establishing an onkeypress handler here, we make it possible for DOS commands like\n * \"CTTY COM1\" to more or less work (use \"CTTY CON\" to restore control to the DOS console).\n */\n control.onkeydown = function onKeyDown(event) {\n /*\n * This is required in addition to onkeypress, because it's the only way to prevent\n * BACKSPACE (keyCode 8) from being interpreted by the browser as a \"Back\" operation;\n * moreover, not all browsers generate an onkeypress notification for BACKSPACE.\n *\n * A related problem exists for Ctrl-key combinations in most Windows-based browsers\n * (eg, IE, Edge, Chrome for Windows, etc), because keys like Ctrl-C and Ctrl-S have\n * special meanings (eg, Copy, Save). To the extent the browser will allow it, we\n * attempt to disable that default behavior when this control receives an onkeydown\n * event for one of those keys (probably the only event the browser generates for them).\n */\n event = event || window.event;\n var keyCode = event.keyCode;\n if (keyCode === 0x08 || event.ctrlKey && keyCode >= 0x41 && keyCode <= 0x5A) {\n if (event.preventDefault) event.preventDefault();\n if (keyCode > 0x40) keyCode -= 0x40;\n serial.receiveByte(keyCode);\n }\n return true;\n };\n\n control.onkeypress = function onKeyPress(event) {\n /*\n * Browser-independent keyCode extraction; refer to onKeyPress() and the other key event\n * handlers in keyboard.js.\n */\n event = event || window.event;\n var keyCode = event.which || event.keyCode;\n serial.receiveByte(keyCode);\n /*\n * Since we're going to remove the \"readonly\" attribute from the <textarea> control\n * (so that the soft keyboard activates on iOS), instead of calling preventDefault() for\n * selected keys (eg, the SPACE key, whose default behavior is to scroll the page), we must\n * now call it for *all* keys, so that the keyCode isn't added to the control immediately,\n * on top of whatever the machine is echoing back, resulting in double characters.\n */\n if (event.preventDefault) event.preventDefault();\n return true;\n };\n\n /*\n * Now that we've added an onkeypress handler that calls preventDefault() for ALL keys, the control\n * itself no longer needs the \"readonly\" attribute; we primarily need to remove it for iOS browsers,\n * so that the soft keyboard will activate, but it shouldn't hurt to remove the attribute for all browsers.\n */\n control.removeAttribute(\"readonly\");\n return true;\n }\n \n if (sValue) {\n /*\n * Instead of just having a dedicated \"test\" control, we now treat any unrecognized control with\n * a \"value\" attribute as a test control. The only caveat is that such controls must have binding IDs\n * that do not conflict with predefined controls (which, of course, is the only way you can get here).\n */\n this.bindings[sBinding] = control;\n\n /*\n * Backslash sequences like \\n, \\r, and \\\\ have already been converted to LF, CR and backslash\n * characters, by virtue of the eval() function that all our component parameter strings pass through;\n * eval() treats strings like \"source code\", so any backslash sequence that JavaScript supports is\n * automatically converted.\n *\n * The complete list of backslash sequences supported by JavaScript:\n *\n * \\0 \\' \\\" \\\\ \\n \\r \\v \\t \\b \\f \\uXXXX \\xXX\n * ^J ^M ^K ^I ^H ^L\n *\n * To support any other non-printable 8-bit character, such as ESC, you should use \\xXX, where XX\n * is the ASCII code in hex. For ESC, that would \\x1B.\n */\n control.onclick = function onClickTest(event) {\n serial.receiveData(sValue);\n /*\n * Give focus back to the machine (since clicking the button takes focus away).\n *\n * if (serial.cmp) serial.cmp.updateFocus();\n *\n * iOS Usability Improvement: NOT calling updateFocus() keeps the soft keyboard down\n * (assuming it was already down).\n */\n return true;\n };\n return true;\n }\n \n return false;\n }\n\n /**\n * echoByte(b)\n *\n * @this {SerialPort8080}\n * @param {number} b\n * @return {boolean} true if echo, false if not\n */\n echoByte(b)\n {\n var fEchoed = false;\n\n if (this.controlBuffer) {\n if (b == 0x08) {\n this.controlBuffer.value = this.controlBuffer.value.slice(0, -1);\n /*\n * TODO: Back up the correct number of columns if the character erased was a tab.\n */\n if (this.iLogicalCol > 0) this.iLogicalCol--;\n }\n else {\n var s = Str.toASCIICode(b);\n var nChars = s.length;\n if (b == 0x09) {\n var tabSize = this.tabSize || 8;\n nChars = tabSize - (this.iLogicalCol % tabSize);\n if (this.tabSize) s = Str.pad(\"\", nChars);\n }\n else if (b == 0x0D) {\n this.iLogicalCol = nChars = 0;\n s = \"\\n\";\n }\n if (this.charBOL && !this.iLogicalCol && nChars) s = String.fromCharCode(this.charBOL) + s;\n this.controlBuffer.value += s;\n this.controlBuffer.scrollTop = this.controlBuffer.scrollHeight;\n this.iLogicalCol += nChars;\n }\n fEchoed = true;\n }\n else if (this.consoleBuffer != null) {\n if (b == 0x0A || this.consoleBuffer.length >= 1024) {\n this.println(this.consoleBuffer);\n this.consoleBuffer = \"\";\n }\n if (b != 0x0A) {\n this.consoleBuffer += String.fromCharCode(b);\n }\n fEchoed = true;\n }\n\n return fEchoed;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {SerialPort8080}\n * @param {Computer8080} cmp\n * @param {Bus8080} bus\n * @param {CPUState8080} cpu\n * @param {Debugger8080} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n var serial = this;\n this.timerReceiveNext = this.cpu.addTimer(this.id + \".receive\", function() {\n serial.receiveData();\n });\n this.timerTransmitNext = this.cpu.addTimer(this.id + \".transmit\", function() {\n serial.transmitData();\n });\n\n this.chipset = /** @type {ChipSet8080} */ (cmp.getMachineComponent(\"ChipSet\"));\n\n bus.addPortInputTable(this, SerialPort8080.aPortInput, this.portBase);\n bus.addPortOutputTable(this, SerialPort8080.aPortOutput, this.portBase);\n\n this.setReady();\n }\n\n /**\n * initConnection(fNullModem)\n *\n * If a machine 'connection' parameter exists of the form \"{sourcePort}->{targetMachine}.{targetPort}\",\n * and \"{sourcePort}\" matches our idComponent, then look for a component with id \"{targetMachine}.{targetPort}\".\n *\n * If the target component is found, then verify that it has exported functions with the following names:\n *\n * receiveData(data): called when we have data to transmit; aliased internally to sendData(data)\n * receiveStatus(pins): called when our control signals have changed; aliased internally to updateStatus(pins)\n *\n * For now, we're not going to worry about communication in the other direction, because when the target component\n * performs its own initConnection(), it will find our receiveData() and receiveStatus() functions, at which point\n * communication in both directions should be established, and the circle of life complete.\n *\n * For added robustness, if the target machine initializes much more slowly than we do, and our connection attempt\n * fails, that's OK, because when it finally initializes, its initConnection() will call our initConnection();\n * if we've already initialized, no harm done.\n *\n * @this {SerialPort8080}\n * @param {boolean} [fNullModem] (caller's null-modem setting, to ensure our settings are in agreement)\n */\n initConnection(fNullModem)\n {\n if (!this.connection) {\n var sConnection = this.cmp.getMachineParm(\"connection\");\n if (sConnection) {\n var asParts = sConnection.split('->');\n if (asParts.length == 2) {\n var sSourceID = Str.trim(asParts[0]);\n if (sSourceID != this.idComponent) return; // this connection string is intended for another instance\n var sTargetID = Str.trim(asParts[1]);\n this.connection = Component.getComponentByID(sTargetID);\n if (this.connection) {\n var exports = this.connection['exports'];\n if (exports) {\n var fnConnect = /** @function */ (exports['connect']);\n if (fnConnect) fnConnect.call(this.connection, this.fNullModem);\n this.sendData = exports['receiveData'];\n if (this.sendData) {\n this.fNullModem = fNullModem;\n this.updateStatus = exports['receiveStatus'];\n this.status(\"Connected \" + this.idMachine + '.' + sSourceID + \" to \" + sTargetID);\n return;\n }\n }\n }\n }\n /*\n * Changed from notice() to status() because sometimes a connection fails simply because one of us is a laggard.\n */\n this.status(\"Unable to establish connection: \" + sConnection);\n }\n }\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {SerialPort8080}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n\n /*\n * This is as late as we can currently wait to make our first inter-machine connection attempt;\n * even so, the target machine's initialization process may still be ongoing, so any connection\n * may be not fully resolved until the target machine performs its own initConnection(), which will\n * in turn invoke our initConnection() again.\n */\n this.initConnection(this.fNullModem);\n\n if (!data || !this.restore) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {SerialPort8080}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {SerialPort8080}\n */\n reset()\n {\n this.initState();\n }\n\n /**\n * save()\n *\n * This implements save support for the SerialPort8080 component.\n *\n * @this {SerialPort8080}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveRegisters());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the SerialPort8080 component.\n *\n * @this {SerialPort8080}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return this.initState(data[0]);\n }\n\n /**\n * initState(data)\n *\n * @this {SerialPort8080}\n * @param {Array} [data]\n * @return {boolean} true if successful, false if failure\n */\n initState(data)\n {\n var i = 0;\n if (data === undefined) {\n data = SerialPort8080.UART8251.INIT;\n }\n this.fReady = data[i++];\n this.bDataIn = data[i++];\n this.bDataOut = data[i++];\n this.bStatus = data[i++];\n this.bMode = data[i++];\n this.bCommand = data[i++];\n this.bBaudRates = data[i];\n return true;\n }\n\n /**\n * saveRegisters()\n *\n * @this {SerialPort8080}\n * @return {Array}\n */\n saveRegisters()\n {\n var i = 0;\n var data = [];\n data[i++] = this.fReady;\n data[i++] = this.bDataIn;\n data[i++] = this.bDataOut;\n data[i++] = this.bStatus;\n data[i++] = this.bMode;\n data[i++] = this.bCommand;\n data[i] = this.bBaudRates;\n return data;\n }\n\n /**\n * getBaudTimeout(maskRate)\n *\n * @this {SerialPort8080}\n * @param {number} maskRate (either SerialPort8080.UART8251.BAUDRATES.RECV_RATE or SerialPort8080.UART8251.BAUDRATES.XMIT_RATE)\n * @return {number} (number of milliseconds per byte)\n */\n getBaudTimeout(maskRate)\n {\n var indexRate = (this.bBaudRates & maskRate);\n if (!(maskRate & 0xf)) indexRate >>= 4;\n var nBaud = SerialPort8080.UART8251.BAUDTABLE[indexRate];\n var nBits = ((this.bMode & SerialPort8080.UART8251.MODE.DATA_BITS) >> 2) + 6; // includes an extra +1 for start bit\n if (this.bMode & SerialPort8080.UART8251.MODE.PARITY_ENABLE) nBits++;\n nBits += ((((this.bMode & SerialPort8080.UART8251.MODE.STOP_BITS) >> 6) + 1) >> 1);\n var nBytesPerSecond = nBaud / nBits;\n return (1000 / nBytesPerSecond)|0;\n }\n\n /**\n * receiveByte(b)\n *\n * @this {SerialPort8080}\n * @param {number} b\n * @return {boolean}\n */\n receiveByte(b)\n {\n if (MAXDEBUG) this.echoByte(b);\n this.printMessage(\"receiveByte(\" + Str.toHexByte(b) + \"), status=\" + Str.toHexByte(this.bStatus));\n if (!this.fAutoStop && !(this.bStatus & SerialPort8080.UART8251.STATUS.RECV_FULL)) {\n this.bDataIn = b;\n this.bStatus |= SerialPort8080.UART8251.STATUS.RECV_FULL;\n this.cpu.requestINTR(this.nIRQ);\n return true;\n }\n return false;\n }\n\n /**\n * receiveData(data)\n *\n * Helper for clocking received data at the expected RECV_RATE.\n *\n * When we're cramming test data down the terminal's throat, that data will typically be in the form\n * of a string. When we're called by another component, data will typically be a number (ie, byte). If no\n * data is specified at all, then all we do is \"clock\" any remaining data into the receiver.\n *\n * @this {SerialPort8080}\n * @param {number|string|undefined} [data]\n * @return {boolean} true if received, false if not\n */\n receiveData(data)\n {\n if (data != null) {\n if (typeof data != \"number\") {\n this.sDataReceived = data;\n } else {\n this.sDataReceived += String.fromCharCode(data);\n }\n }\n if (this.sDataReceived) {\n if (this.receiveByte(this.sDataReceived.charCodeAt(0))) {\n this.sDataReceived = this.sDataReceived.substr(1);\n }\n if (this.sDataReceived && this.cpu) {\n this.cpu.setTimer(this.timerReceiveNext, this.getBaudTimeout(SerialPort8080.UART8251.BAUDRATES.RECV_RATE));\n }\n }\n return true; // for now, return true regardless, since we're buffering everything anyway\n }\n\n /**\n * receiveStatus(pins)\n *\n * NOTE: Prior to the addition of this interface, the DSR bit was initialized set and remained set for the life\n * of the machine. It is entirely appropriate that this is the only way the bit can be changed, because it represents\n * an external control signal.\n *\n * @this {SerialPort8080}\n * @param {number} pins\n */\n receiveStatus(pins)\n {\n this.bStatus &= ~SerialPort8080.UART8251.STATUS.DSR;\n if (pins & RS232.DSR.MASK) this.bStatus |= SerialPort8080.UART8251.STATUS.DSR;\n }\n\n /**\n * transmitByte(b)\n *\n * @this {SerialPort8080}\n * @param {number} b\n * @return {boolean} true if transmitted, false if not\n */\n transmitByte(b)\n {\n var fTransmitted = false;\n\n this.printMessage(\"transmitByte(\" + Str.toHexByte(b) + \")\");\n\n if (this.fAutoXOFF) {\n if (b == 0x13) { // XOFF\n this.fAutoStop = true;\n return false;\n }\n if (b == 0x11) { // XON\n this.fAutoStop = false;\n return false;\n }\n }\n\n if (this.sendData && this.sendData.call(this.connection, b)) {\n fTransmitted = true;\n }\n\n if (this.echoByte(b)) {\n fTransmitted = true;\n }\n\n return fTransmitted;\n }\n\n /**\n * transmitData(sData)\n *\n * Helper for clocking transmitted data at the expected XMIT_RATE.\n *\n * When timerTransmitNext fires, we have honored the programmed XMIT_RATE period, so we can\n * set XMIT_READY (and XMIT_EMPTY), which signals the firmware that another byte can be transmitted.\n *\n * The sData parameter is not used when we're called via the timer; it's an optional parameter used by\n * the Keyboard component to deliver data pasted via the clipboard, and is currently only useful when\n * the SerialPort is connected to another machine. TODO: Define a separate interface for that feature.\n *\n * @this {SerialPort8080}\n * @param {string} [sData]\n * @return {boolean} true if successful, false if not\n */\n transmitData(sData)\n {\n this.bStatus |= (SerialPort8080.UART8251.STATUS.XMIT_READY | SerialPort8080.UART8251.STATUS.XMIT_EMPTY);\n if (sData) {\n return this.sendData? this.sendData.call(this.connection, sData) : false;\n }\n return true;\n }\n\n /**\n * isTransmitterReady()\n *\n * Called whenever a ChipSet circuit needs the SerialPort8080 UART's transmitter status.\n *\n * @this {SerialPort8080}\n * @return {boolean} (true if ready, false if not)\n */\n isTransmitterReady()\n {\n return !!(this.bStatus & SerialPort8080.UART8251.STATUS.XMIT_READY);\n }\n\n /**\n * inData(port, addrFrom)\n *\n * @this {SerialPort8080}\n * @param {number} port (0x0)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inData(port, addrFrom)\n {\n var b = this.bDataIn;\n this.printMessageIO(port, null, addrFrom, \"DATA\", b);\n this.bStatus &= ~SerialPort8080.UART8251.STATUS.RECV_FULL;\n return b;\n }\n\n /**\n * inControl(port, addrFrom)\n *\n * @this {SerialPort8080}\n * @param {number} port (0x1)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inControl(port, addrFrom)\n {\n var b = this.bStatus;\n this.printMessageIO(port, null, addrFrom, \"STATUS\", b);\n return b;\n }\n\n /**\n * outData(port, bOut, addrFrom)\n *\n * @this {SerialPort8080}\n * @param {number} port (0x0)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outData(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"DATA\");\n this.bDataOut = bOut;\n this.bStatus &= ~(SerialPort8080.UART8251.STATUS.XMIT_READY | SerialPort8080.UART8251.STATUS.XMIT_EMPTY);\n /*\n * If we're transmitting to a virtual device that has no measurable delay, this code may clear XMIT_READY\n * too quickly:\n *\n * if (this.transmitByte(bOut)) {\n * this.bStatus |= (SerialPort8080.UART8251.STATUS.XMIT_READY | SerialPort8080.UART8251.STATUS.XMIT_EMPTY);\n * }\n *\n * A better solution is to arm a timer based on the XMIT_RATE baud rate, and clear the above bits when that\n * timer fires. Consequently, we no longer care what transmitByte() reports.\n */\n this.transmitByte(bOut);\n if (this.cpu) {\n this.cpu.setTimer(this.timerTransmitNext, this.getBaudTimeout(SerialPort8080.UART8251.BAUDRATES.XMIT_RATE));\n }\n }\n\n /**\n * outControl(port, bOut, addrFrom)\n *\n * Writes to the CONTROL port (0x1) are either MODE or COMMAND bytes. If the device has just\n * been powered or reset, it is in a \"not ready\" state and is waiting for a MODE byte. Once it\n * has received that initial byte, the device is marked \"ready\", and all further bytes are\n * interpreted as COMMAND bytes (until/unless a COMMAND byte with the INTERNAL_RESET bit is set).\n *\n * @this {SerialPort8080}\n * @param {number} port (0x1)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outControl(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"CONTROL\");\n if (!this.fReady) {\n this.bMode = bOut;\n this.fReady = true;\n } else {\n /*\n * Whenever DTR or RTS changes, we also want to notify any connected machine, via updateStatus().\n */\n if (this.updateStatus) {\n var delta = (bOut ^ this.bCommand);\n if (delta & (SerialPort8080.UART8251.COMMAND.RTS | SerialPort8080.UART8251.COMMAND.DTR)) {\n var pins = 0;\n if (this.fNullModem) {\n pins |= (bOut & SerialPort8080.UART8251.COMMAND.RTS)? RS232.CTS.MASK : 0;\n pins |= (bOut & SerialPort8080.UART8251.COMMAND.DTR)? (RS232.DSR.MASK | RS232.CD.MASK): 0;\n } else {\n pins |= (bOut & SerialPort8080.UART8251.COMMAND.RTS)? RS232.RTS.MASK : 0;\n pins |= (bOut & SerialPort8080.UART8251.COMMAND.DTR)? RS232.DTR.MASK : 0;\n }\n this.updateStatus.call(this.connection, pins);\n }\n }\n this.bCommand = bOut;\n if (this.bCommand & SerialPort8080.UART8251.COMMAND.INTERNAL_RESET) {\n this.fReady = false;\n }\n }\n }\n\n /**\n * outBaudRates(port, bOut, addrFrom)\n *\n * @this {SerialPort8080}\n * @param {number} port (0x2)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outBaudRates(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"BAUDRATES\");\n this.bBaudRates = bOut;\n }\n\n /**\n * SerialPort8080.init()\n *\n * This function operates on every HTML element of class \"serial\", extracting the\n * JSON-encoded parameters for the SerialPort8080 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a SerialPort8080 component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeSerial = Component.getElementsByClass(document, PC8080.APPCLASS, \"serial\");\n for (var iSerial = 0; iSerial < aeSerial.length; iSerial++) {\n var eSerial = aeSerial[iSerial];\n var parmsSerial = Component.getComponentParms(eSerial);\n var serial = new SerialPort8080(parmsSerial);\n Component.bindComponentControls(serial, eSerial, PC8080.APPCLASS);\n }\n }\n}\n\nSerialPort8080.UART8251 = {\n /*\n * Format of MODE byte written to CONTROL port 0x1\n */\n MODE: {\n BAUD_FACTOR: 0x03, // 00=SYNC, 01=1x, 10=16x, 11=64x\n DATA_BITS: 0x0C, // 00=5, 01=6, 10=7, 11=8\n PARITY_ENABLE: 0x10,\n EVEN_PARITY: 0x20,\n STOP_BITS: 0xC0, // 00=invalid, 01=1, 10=1.5, 11=2\n INIT: 0x8E // 16x baud rate, 8 data bits, no parity, 1.5 stop bits\n },\n /*\n * Format of COMMAND byte written to CONTROL port 0x1\n */\n COMMAND: {\n XMIT_ENABLE: 0x01,\n DTR: 0x02, // Data Terminal Ready\n RECV_ENABLE: 0x04,\n SEND_BREAK: 0x08,\n ERROR_RESET: 0x10,\n RTS: 0x20, // Request To Send\n INTERNAL_RESET: 0x40,\n HUNT_MODE: 0x80,\n INIT: 0x27 // XMIT_ENABLE | DTR | RECV_ENABLE | RTS\n },\n /*\n * Format of STATUS byte read from CONTROL port 0x1\n */\n STATUS: {\n XMIT_READY: 0x01,\n RECV_FULL: 0x02,\n XMIT_EMPTY: 0x04,\n PARITY_ERROR: 0x08,\n OVERRUN_ERROR: 0x10,\n FRAMING_ERROR: 0x20,\n BREAK_DETECT: 0x40,\n DSR: 0x80, // Data Set Ready\n INIT: 0x85 // XMIT_READY | XMIT_EMPTY | DSR\n },\n /*\n * Format of BAUDRATES byte written to port 0x2\n *\n * Each nibble is an index (0x0-0xF) into a set of internal CPU clock divisors that yield the\n * following baud rates:\n *\n * Index Divisor Baud Rate\n * ----- ------- ---------\n * 0x0 3456 50\n * 0x1 2304 75\n * 0x2 1571 110\n * 0x3 1285 134.5\n * 0x4 1152 150\n * 0x5 864 200\n * 0x6 576 300\n * 0x7 288 600\n * 0x8 144 1200\n * 0x9 96 1800\n * 0xA 86 2000\n * 0xB 72 2400\n * 0xC 48 3600\n * 0xD 36 4800\n * 0xE 18 9600 (default)\n * 0xF 9 19200\n *\n * NOTE: This is a VT100-specific port and baud rate table.\n */\n BAUDRATES: {\n RECV_RATE: 0x0F,\n XMIT_RATE: 0xF0,\n INIT: 0xEE // default to 9600 (0xE) for both XMIT and RECV\n },\n BAUDTABLE: [\n 50, 75, 110, 134.5, 150, 200, 300, 600, 1200, 1800, 2000, 2400, 3600, 4800, 9600, 19200\n ]\n};\n\nSerialPort8080.UART8251.INIT = [\n false,\n 0,\n 0,\n SerialPort8080.UART8251.STATUS.INIT,\n SerialPort8080.UART8251.MODE.INIT,\n SerialPort8080.UART8251.COMMAND.INIT,\n SerialPort8080.UART8251.BAUDRATES.INIT\n];\n\n/*\n * Port input notification table\n */\nSerialPort8080.aPortInput = {\n 0x0: SerialPort8080.prototype.inData,\n 0x1: SerialPort8080.prototype.inControl\n\n};\n\n/*\n * Port output notification table\n */\nSerialPort8080.aPortOutput = {\n 0x0: SerialPort8080.prototype.outData,\n 0x1: SerialPort8080.prototype.outControl,\n 0x2: SerialPort8080.prototype.outBaudRates\n};\n\n/*\n * Initialize every SerialPort8080 module on the page.\n */\nWeb.onInit(SerialPort8080.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/debugger.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Debugger Address Object\n *\n * This is the basic structure; other debuggers may extend it.\n *\n * addr address\n * fTemporary true if this is a temporary breakpoint address\n * sCmd set for breakpoint addresses if there's an associated command string\n * aCmds preprocessed commands (from sCmd)\n *\n * @typedef {{\n * addr:(number|undefined),\n * fTemporary:(boolean|undefined),\n * sCmd:(string|undefined),\n * aCmds:(Array.<string>|undefined)\n * }}\n */\nvar DbgAddr;\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * subclass (eg, SerialPort), because otherwise the Compiler won't allow us to *reference*\n * the named property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass Debugger extends Component\n{\n /**\n * Debugger(parmsDbg)\n *\n * The Debugger component supports the following optional (parmsDbg) properties:\n *\n * base: the base to use for most numeric input/output (default is 16)\n *\n * The Debugger component is a shared component containing a subset of functionality used by\n * the other CPU-specific Debuggers (eg, DebuggerX86). Over time, the goal is to factor out as\n * much common debugging support as possible from those components into this one.\n *\n * @param {Object} parmsDbg\n */\n constructor(parmsDbg)\n {\n if (DEBUGGER) {\n\n super(\"Debugger\", parmsDbg);\n\n /*\n * Default base used to display all values; modified with the \"s base\" command.\n */\n this.nBase = +parmsDbg['base'] || 16;\n\n /*\n * Default number of bits of integer precision; it can be overridden by the Debugger\n * but there is no command to adjust it.\n */\n this.nBits = 32;\n\n this.achGroup = ['{','}'];\n this.achAddress = ['[',']'];\n\n /*\n * These keep track of instruction activity, but only when tracing or when Debugger checks\n * have been enabled (eg, one or more breakpoints have been set).\n *\n * They are zeroed by the reset() notification handler. cInstructions is advanced by\n * stepCPU() and checkInstruction() calls. nCycles is updated by every stepCPU() or stop()\n * call and simply represents the number of cycles performed by the last run of instructions.\n */\n this.nCycles = 0;\n this.cOpcodes = this.cOpcodesStart = 0;\n\n /*\n * fAssemble is true when \"assemble mode\" is active, false when not.\n */\n this.fAssemble = false;\n\n /*\n * This maintains command history. New commands are inserted at index 0 of the array.\n * When Enter is pressed on an empty input buffer, we default to the command at aPrevCmds[0].\n */\n this.iPrevCmd = -1;\n this.aPrevCmds = [];\n\n /*\n * aVariables is an object with properties that grow as setVariable() assigns more variables;\n * each property corresponds to one variable, where the property name is the variable name (ie,\n * a string beginning with a non-digit, followed by zero or more symbol characters and/or digits)\n * and the property value is the variable's numeric value. See doVar() and setVariable() for\n * details.\n *\n * Note that parseValue() parses variables before numbers, so any variable that looks like a\n * unprefixed hex value (eg, \"a5\" as opposed to \"0xa5\") will trump the numeric value. Unprefixed\n * hex values are a convenience of parseValue(), which always calls Str.parseInt() with a default\n * base of 16; however, that default be overridden with a variety of explicit prefixes or suffixes\n * (eg, a leading \"0o\" to indicate octal, a trailing period to indicate decimal, etc.)\n *\n * See Str.parseInt() for more details about supported numbers.\n */\n this.aVariables = {};\n\n } // endif DEBUGGER\n }\n\n /**\n * getRegIndex(sReg, off)\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {string} sReg\n * @param {number} [off] optional offset into sReg\n * @return {number} register index, or -1 if not found\n */\n getRegIndex(sReg, off)\n {\n return -1;\n }\n\n /**\n * getRegValue(iReg)\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {number} iReg\n * @return {number|undefined}\n */\n getRegValue(iReg)\n {\n return undefined;\n }\n\n /**\n * parseAddrReference(s, sAddr)\n *\n * Returns the given string with the given address reference replaced with the contents of that address.\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {string} s\n * @param {string} sAddr\n * @return {string}\n */\n parseAddrReference(s, sAddr)\n {\n return s.replace('[' + sAddr + ']', \"unimplemented\");\n }\n\n /**\n * getNextCommand()\n *\n * @this {Debugger}\n * @return {string}\n */\n getNextCommand()\n {\n var sCmd;\n if (this.iPrevCmd > 0) {\n sCmd = this.aPrevCmds[--this.iPrevCmd];\n } else {\n sCmd = \"\";\n this.iPrevCmd = -1;\n }\n return sCmd;\n }\n\n /**\n * getPrevCommand()\n *\n * @this {Debugger}\n * @return {string|null}\n */\n getPrevCommand()\n {\n var sCmd = null;\n if (this.iPrevCmd < this.aPrevCmds.length - 1) {\n sCmd = this.aPrevCmds[++this.iPrevCmd];\n }\n return sCmd;\n }\n\n /**\n * parseCommand(sCmd, fSave, chSep)\n *\n * @this {Debugger}\n * @param {string|undefined} sCmd\n * @param {boolean} [fSave] is true to save the command, false if not\n * @param {string} [chSep] is the command separator character (default is ';')\n * @return {Array.<string>}\n */\n parseCommand(sCmd, fSave, chSep)\n {\n if (fSave) {\n if (!sCmd) {\n if (this.fAssemble) {\n sCmd = \"end\";\n } else {\n sCmd = this.aPrevCmds[this.iPrevCmd+1];\n }\n } else {\n if (this.iPrevCmd < 0 && this.aPrevCmds.length) {\n this.iPrevCmd = 0;\n }\n if (this.iPrevCmd < 0 || sCmd != this.aPrevCmds[this.iPrevCmd]) {\n this.aPrevCmds.splice(0, 0, sCmd);\n this.iPrevCmd = 0;\n }\n this.iPrevCmd--;\n }\n }\n var a = [];\n if (sCmd) {\n /*\n * With the introduction of breakpoint commands (ie, quoted command sequences\n * associated with a breakpoint), we can no longer perform simplistic splitting.\n *\n * a = sCmd.split(chSep || ';');\n * for (var i = 0; i < a.length; i++) a[i] = Str.trim(a[i]);\n *\n * We may now split on semi-colons ONLY if they are outside a quoted sequence.\n *\n * Also, to allow quoted strings *inside* breakpoint commands, we first replace all\n * DOUBLE double-quotes with single quotes.\n */\n sCmd = sCmd.replace(/\"\"/g, \"'\");\n\n var iPrev = 0;\n var chQuote = null;\n chSep = chSep || ';';\n /*\n * NOTE: Processing charAt() up to and INCLUDING length is not a typo; we're taking\n * advantage of the fact that charAt() with an invalid index returns an empty string,\n * allowing us to use the same substring() call to capture the final portion of sCmd.\n *\n * In a sense, it allows us to pretend that the string ends with a zero terminator.\n */\n for (var i = 0; i <= sCmd.length; i++) {\n var ch = sCmd.charAt(i);\n if (ch == '\"' || ch == \"'\") {\n if (!chQuote) {\n chQuote = ch;\n } else if (ch == chQuote) {\n chQuote = null;\n }\n }\n else if (ch == chSep && !chQuote || !ch) {\n /*\n * Recall that substring() accepts starting (inclusive) and ending (exclusive)\n * indexes, whereas substr() accepts a starting index and a length. We need the former.\n */\n a.push(Str.trim(sCmd.substring(iPrev, i)));\n iPrev = i + 1;\n }\n }\n }\n return a;\n }\n\n /**\n * evalAND(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.AND().\n *\n * Performs the bitwise \"and\" (AND) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst & src)\n */\n evalAND(dst, src)\n {\n /*\n * We AND the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 AND 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst & src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) & ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst & src) >>> 0);\n }\n\n /**\n * evalIOR(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.IOR().\n *\n * Performs the logical \"inclusive-or\" (OR) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst | src)\n */\n evalIOR(dst, src)\n {\n /*\n * We OR the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 OR 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst | src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) | ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst | src) >>> 0);\n }\n\n /**\n * evalXOR(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.XOR().\n *\n * Performs the logical \"exclusive-or\" (XOR) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst ^ src)\n */\n evalXOR(dst, src)\n {\n /*\n * We XOR the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 XOR 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst | src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) ^ ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst ^ src) >>> 0);\n }\n\n /**\n * evalMUL(dst, src)\n *\n * I could have adapted the code from /modules/pdp10/lib/cpuops.js:PDP10.doMUL(), but it was simpler to\n * write this base method and let the PDP-10 Debugger override it with a call to the *actual* doMUL() method.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst * src)\n */\n evalMUL(dst, src)\n {\n return dst * src;\n }\n\n /**\n * truncate(v, nBits, fUnsigned)\n *\n * @this {Debugger}\n * @param {number} v\n * @param {number} [nBits]\n * @param {boolean} [fUnsigned]\n * @return {number}\n */\n truncate(v, nBits, fUnsigned)\n {\n var limit, vNew = v;\n nBits = nBits || this.nBits;\n\n if (fUnsigned) {\n if (nBits == 32) {\n vNew = v >>> 0;\n }\n else if (nBits < 32) {\n vNew = v & ((1 << nBits) - 1);\n }\n else {\n limit = Math.pow(2, nBits);\n if (v < 0 || v >= limit) {\n vNew = v % limit;\n if (vNew < 0) vNew += limit;\n }\n }\n }\n else {\n if (nBits <= 32) {\n vNew = (v << (32 - nBits)) >> (32 - nBits);\n }\n else {\n limit = Math.pow(2, nBits - 1);\n if (v >= limit) {\n vNew = (v % limit);\n if (((v / limit)|0) & 1) vNew -= limit;\n } else if (v < -limit) {\n vNew = (v % limit);\n if ((((-v - 1) / limit) | 0) & 1) {\n if (vNew) vNew += limit;\n }\n else {\n if (!vNew) vNew -= limit;\n }\n }\n }\n }\n if (v != vNew) {\n if (MAXDEBUG) this.println(\"warning: value \" + v + \" truncated to \" + vNew);\n v = vNew;\n }\n return v;\n }\n\n /**\n * evalOps(aVals, aOps, cOps)\n *\n * Some of our clients want a specific number of bits of integer precision. If that precision is\n * greater than 32, some of the operations below will fail; for example, JavaScript bitwise operators\n * always truncate the result to 32 bits, so beware when using shift operations. Similarly, it would\n * be wrong to always \"|0\" the final result, which is why we rely on truncate() now.\n *\n * Note that JavaScript integer precision is limited to 52 bits. For example, in Node, if you set a\n * variable to 0x80000001:\n *\n * foo=0x80000001|0\n *\n * then calculate foo*foo and display the result in binary using \"(foo*foo).toString(2)\":\n *\n * '11111111111111111111111111111100000000000000000000000000000000'\n *\n * which is slightly incorrect because it has overflowed JavaScript's floating-point precision.\n *\n * 0x80000001 in decimal is -2147483647, so the product is 4611686014132420609, which is 0x3FFFFFFF00000001.\n *\n * @this {Debugger}\n * @param {Array.<number>} aVals\n * @param {Array.<string>} aOps\n * @param {number} [cOps] (default is -1 for all)\n * @return {boolean} true if successful, false if error\n */\n evalOps(aVals, aOps, cOps = -1)\n {\n while (cOps-- && aOps.length) {\n var chOp = aOps.pop();\n if (aVals.length < 2) return false;\n var valNew;\n var val2 = aVals.pop();\n var val1 = aVals.pop();\n switch(chOp) {\n case '*':\n valNew = this.evalMUL(val1, val2);\n break;\n case '/':\n if (!val2) return false;\n valNew = Math.trunc(val1 / val2);\n break;\n case '^/':\n if (!val2) return false;\n valNew = val1 % val2;\n break;\n case '+':\n valNew = val1 + val2;\n break;\n case '-':\n valNew = val1 - val2;\n break;\n case '<<':\n valNew = val1 << val2;\n break;\n case '>>':\n valNew = val1 >> val2;\n break;\n case '>>>':\n valNew = val1 >>> val2;\n break;\n case '<':\n valNew = (val1 < val2? 1 : 0);\n break;\n case '<=':\n valNew = (val1 <= val2? 1 : 0);\n break;\n case '>':\n valNew = (val1 > val2? 1 : 0);\n break;\n case '>=':\n valNew = (val1 >= val2? 1 : 0);\n break;\n case '==':\n valNew = (val1 == val2? 1 : 0);\n break;\n case '!=':\n valNew = (val1 != val2? 1 : 0);\n break;\n case '&':\n valNew = this.evalAND(val1, val2);\n break;\n case '!': // alias for MACRO-10 to perform a bitwise inclusive-or (OR)\n case '|':\n valNew = this.evalIOR(val1, val2);\n break;\n case '^!': // since MACRO-10 uses '^' for base overrides, '^!' is used for bitwise exclusive-or (XOR)\n valNew = this.evalXOR(val1, val2);\n break;\n case '&&':\n valNew = (val1 && val2? 1 : 0);\n break;\n case '||':\n valNew = (val1 || val2? 1 : 0);\n break;\n case ',,':\n valNew = this.truncate(val1, 18, true) * Math.pow(2, 18) + this.truncate(val2, 18, true);\n break;\n case '_':\n case '^_':\n valNew = val1;\n /*\n * While we always try to avoid assuming any particular number of bits of precision, the 'B' shift\n * operator (which we've converted to '^_') is unique to the MACRO-10 environment, which imposes the\n * following restrictions on the shift count.\n */\n if (chOp == '^_') val2 = 35 - (val2 & 0xff);\n if (val2) {\n /*\n * Since binary shifting is a logical (not arithmetic) operation, and since shifting by division only\n * works properly with positive numbers, we call truncate() to produce an unsigned value.\n */\n valNew = this.truncate(valNew, 0, true);\n if (val2 > 0) {\n valNew *= Math.pow(2, val2);\n } else {\n valNew = Math.trunc(valNew / Math.pow(2, -val2));\n }\n }\n break;\n default:\n return false;\n }\n aVals.push(this.truncate(valNew));\n }\n return true;\n }\n\n /**\n * parseArray(asValues, iValue, iLimit, nBase, aUndefined)\n *\n * parseExpression() takes a complete expression and divides it into array elements, where even elements\n * are values (which may be empty if two or more operators appear consecutively) and odd elements are operators.\n *\n * For example, if the original expression was \"2*{3+{4/2}}\", parseExpression() would call parseArray() with:\n *\n * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14\n * - - - - - - - - - - -- -- -- -- --\n * 2 * { 3 + { 4 / 2 } }\n *\n * This function takes care of recursively processing grouped expressions, by processing subsets of the array,\n * as well as handling certain base overrides (eg, temporarily switching to base-10 for binary shift suffixes).\n *\n * @param {Array.<string>} asValues\n * @param {number} iValue\n * @param {number} iLimit\n * @param {number} nBase\n * @param {Array|undefined} [aUndefined]\n * @return {number|undefined}\n */\n parseArray(asValues, iValue, iLimit, nBase, aUndefined)\n {\n var value;\n var sValue, sOp;\n var fError = false;\n var nUnary = 0;\n var aVals = [], aOps = [];\n\n var nBasePrev = this.nBase;\n this.nBase = nBase;\n\n while (iValue < iLimit) {\n var v;\n sValue = asValues[iValue++].trim();\n sOp = (iValue < iLimit? asValues[iValue++] : \"\");\n\n if (sValue) {\n v = this.parseValue(sValue, null, aUndefined, nUnary);\n } else {\n if (sOp == '{') {\n var cOpen = 1;\n var iStart = iValue;\n while (iValue < iLimit) {\n sValue = asValues[iValue++].trim();\n sOp = (iValue < asValues.length? asValues[iValue++] : \"\");\n if (sOp == '{') {\n cOpen++;\n } else if (sOp == '}') {\n if (!--cOpen) break;\n }\n }\n v = this.parseArray(asValues, iStart, iValue-1, this.nBase, aUndefined);\n if (v != null && nUnary) {\n v = this.parseUnary(v, nUnary);\n }\n sValue = (iValue < iLimit? asValues[iValue++].trim() : \"\");\n sOp = (iValue < iLimit? asValues[iValue++] : \"\");\n }\n else {\n /*\n * When parseExpression() calls us, it has collapsed all runs of whitespace into single spaces,\n * and although it allows single spaces to divide the elements of the expression, a space is neither\n * a unary nor binary operator. It's essentially a no-op. If we encounter it here, then it followed\n * another operator and is easily ignored (although perhaps it should still trigger a reset of nBase\n * and nUnary -- TBD).\n */\n if (sOp == ' ') {\n continue;\n }\n if (sOp == '^B') {\n this.nBase = 2;\n continue;\n }\n if (sOp == '^O') {\n this.nBase = 8;\n continue;\n }\n if (sOp == '^D') {\n this.nBase = 10;\n continue;\n }\n if (!(nUnary & (0xC0000000|0))) {\n if (sOp == '+') {\n continue;\n }\n if (sOp == '-') {\n nUnary = (nUnary << 2) | 1;\n continue;\n }\n if (sOp == '~' || sOp == '^-') {\n nUnary = (nUnary << 2) | 2;\n continue;\n }\n if (sOp == '^L') {\n nUnary = (nUnary << 2) | 3;\n continue;\n }\n }\n fError = true;\n break;\n }\n }\n\n if (v === undefined) {\n if (aUndefined) {\n aUndefined.push(sValue);\n v = 0;\n } else {\n fError = true;\n aUndefined = [];\n break;\n }\n }\n\n aVals.push(this.truncate(v));\n\n /*\n * When parseExpression() calls us, it has collapsed all runs of whitespace into single spaces,\n * and although it allows single spaces to divide the elements of the expression, a space is neither\n * a unary nor binary operator. It's essentially a no-op. If we encounter it here, then it followed\n * a value, and since we don't want to misinterpret the next operator as a unary operator, we look\n * ahead and grab the next operator if it's not preceded by a value.\n */\n if (sOp == ' ') {\n if (iValue < asValues.length - 1 && !asValues[iValue]) {\n iValue++;\n sOp = asValues[iValue++]\n } else {\n fError = true;\n break;\n }\n }\n\n if (!sOp) break;\n\n var aBinOp = (this.achGroup[0] == '<'? Debugger.aDECOpPrecedence : Debugger.aBinOpPrecedence);\n if (!aBinOp[sOp]) {\n fError = true;\n break;\n }\n if (aOps.length && aBinOp[sOp] <= aBinOp[aOps[aOps.length - 1]]) {\n this.evalOps(aVals, aOps, 1);\n }\n aOps.push(sOp);\n\n /*\n * The MACRO-10 binary shifting operator assumes a base-10 shift count, regardless of the current\n * base, so we must override the current base to ensure the count is parsed correctly.\n */\n this.nBase = (sOp == '^_')? 10 : nBase;\n nUnary = 0;\n }\n\n if (fError || !this.evalOps(aVals, aOps) || aVals.length != 1) {\n fError = true;\n }\n\n if (!fError) {\n value = aVals.pop();\n\n } else if (!aUndefined) {\n this.println(\"parse error (\" + (sValue || sOp) + \")\");\n }\n\n this.nBase = nBasePrev;\n return value;\n }\n\n /**\n * parseASCII(sExp, chDelim, nBits, cchMax)\n *\n * @this {Debugger}\n * @param {string} sExp\n * @param {string} chDelim\n * @param {number} nBits\n * @param {number} cchMax\n * @return {string|undefined}\n */\n parseASCII(sExp, chDelim, nBits, cchMax)\n {\n var i;\n while ((i = sExp.indexOf(chDelim)) >= 0) {\n var v = 0;\n var j = i + 1;\n var cch = cchMax;\n while (j < sExp.length) {\n var ch = sExp[j++];\n if (ch == chDelim) {\n cch = -1;\n break;\n }\n if (!cch) break;\n cch--;\n var c = ch.charCodeAt(0);\n if (nBits == 7) {\n c &= 0x7F;\n } else {\n c = (c - 0x20) & 0x3F;\n }\n v = this.truncate(v * Math.pow(2, nBits) + c, nBits * cchMax, true);\n }\n if (cch >= 0) {\n this.println(\"parse error (\" + chDelim + sExp + chDelim + \")\");\n return undefined;\n } else {\n sExp = sExp.substr(0, i) + this.toStrBase(v, -1) + sExp.substr(j);\n }\n }\n return sExp;\n }\n\n /**\n * parseExpression(sExp, fQuiet)\n *\n * A quick-and-dirty expression parser. It takes an expression like:\n *\n * EDX+EDX*4+12345678\n *\n * and builds a value stack in aVals and a \"binop\" (binary operator) stack in aOps:\n *\n * aVals aOps\n * ----- ----\n * EDX +\n * EDX *\n * 4 +\n * ...\n *\n * We pop 1 \"binop\" from aOps and 2 values from aVals whenever a \"binop\" of lower priority than its\n * predecessor is encountered, evaluate, and push the result back onto aVals. Only selected unary\n * operators are supported (eg, negate and complement); no ternary operators like '?:' are supported.\n *\n * fQuiet can be used to pass an array that collects any undefined variables that parseExpression()\n * encounters; the value of an undefined variable is zero. This mode was added for components that need\n * to support expressions containing \"fixups\" (ie, values that must be determined later).\n *\n * @this {Debugger}\n * @param {string|undefined} sExp\n * @param {Array|undefined|boolean} [fQuiet]\n * @return {number|undefined} numeric value, or undefined if sExp contains any undefined or invalid values\n */\n parseExpression(sExp, fQuiet)\n {\n var value = undefined;\n var fPrint = (fQuiet === false);\n var aUndefined = Array.isArray(fQuiet)? fQuiet : undefined;\n\n if (sExp) {\n\n /*\n * The default delimiting characters for grouped expressions are braces; they can be changed by altering\n * achGroup, but when that happens, instead of changing our regular expressions and operator tables,\n * we simply replace all achGroup characters with braces in the given expression.\n *\n * Why not use parentheses for grouped expressions? Because some debuggers use parseReference() to perform\n * parenthetical value replacements in message strings, and they don't want parentheses taking on a different\n * meaning. And for some machines, like the PDP-10, the convention is to use parentheses for other things,\n * like indexed addressing, and to use angle brackets for grouped expressions.\n */\n if (this.achGroup[0] != '{') {\n sExp = sExp.split(this.achGroup[0]).join('{').split(this.achGroup[1]).join('}');\n }\n\n /*\n * Quoted ASCII characters can have a numeric value, too, which must be converted now, to avoid any\n * conflicts with the operators below.\n */\n sExp = this.parseASCII(sExp, '\"', 7, 5); // MACRO-10 packs up to 5 7-bit ASCII codes into a value\n if (!sExp) return value;\n sExp = this.parseASCII(sExp, \"'\", 6, 6); // MACRO-10 packs up to 6 6-bit ASCII (SIXBIT) codes into a value\n if (!sExp) return value;\n\n /*\n * All browsers (including, I believe, IE9 and up) support the following idiosyncrasy of a RegExp split():\n * when the RegExp uses a capturing pattern, the resulting array will include entries for all the pattern\n * matches along with the non-matches. This effectively means that, in the set of expressions that we\n * support, all even entries in asValues will contain \"values\" and all odd entries will contain \"operators\".\n *\n * Although I started listing the operators in the RegExp in \"precedential\" order, that's not important;\n * what IS important is listing operators than contain shorter operators first. For example, bitwise\n * shift operators must be listed BEFORE the logical less-than or greater-than operators. The aBinOp tables\n * (aBinOpPrecedence and aDECOpPrecedence) are what determine precedence, not the RegExp.\n *\n * Also, to better accommodate MACRO-10 syntax, I've replaced the single '^' for XOR with '^!', and I've\n * added '!' as an alias for '|' (bitwise inclusive-or), '^-' as an alias for '~' (one's complement operator),\n * and '_' as a shift operator (+/- values specify a left/right shift, and the count is not limited to 32).\n *\n * And to avoid conflicts with MACRO-10 syntax, I've replaced the original mod operator ('%') with '^/'.\n *\n * The MACRO-10 binary shifting suffix ('B') is a bit more problematic, since a capital B can also appear\n * inside symbols, or inside hex values. So if the default base is NOT 16, then I pre-scan for that suffix\n * and replace all non-symbolic occurrences with an internal shift operator ('^_').\n *\n * Note that Str.parseInt(), which parseValue() relies on, supports both the MACRO-10 base prefix overrides\n * and the binary shifting suffix ('B'), but since that suffix can also be a bracketed expression, we have to\n * support it here as well.\n *\n * MACRO-10 supports only a subset of all the PCjs operators; for example, MACRO-10 doesn't support any of\n * the boolean logical/compare operators. But unless we run into conflicts, I prefer sticking with this\n * common set of operators.\n *\n * All whitespace in the expression is collapsed to single spaces, and space has been added to the list\n * of \"operators\", but its sole function is as a separator, not as an operator. parseArray() will ignore\n * single spaces as long as they are preceded and/or followed by a \"real\" operator. It would be dangerous\n * to remove spaces entirely, because if an operator-less expression like \"A B\" was passed in, we would want\n * that to generate an error; if we converted it to \"AB\", evaluation might inadvertently succeed.\n */\n var regExp = /({|}|\\|\\||&&|\\||\\^!|\\^B|\\^O|\\^D|\\^L|\\^-|~|\\^_|_|&|!=|!|==|>=|>>>|>>|>|<=|<<|<|-|\\+|\\^\\/|\\/|\\*|,,| )/;\n if (this.nBase != 16) {\n sExp = sExp.replace(/(^|[^A-Z0-9$%.])([0-9]+)B/, \"$1$2^_\").replace(/\\s+/g, ' ');\n }\n var asValues = sExp.split(regExp);\n value = this.parseArray(asValues, 0, asValues.length, this.nBase, aUndefined);\n if (value !== undefined && fPrint) {\n this.printValue(null, value);\n }\n }\n return value;\n }\n\n /**\n * parseReference(s)\n *\n * Returns the given string with any \"{expression}\" sequences replaced with the value of the expression,\n * and any \"[address]\" references replaced with the contents of the address. Expressions are parsed BEFORE\n * addresses.\n *\n * @this {Debugger}\n * @param {string} s\n * @return {string|undefined}\n */\n parseReference(s)\n {\n var a;\n var chOpen = this.achGroup[0];\n var chClose = this.achGroup[1];\n var chEscape = (chOpen == '(' || chOpen == '{' || chOpen == '[')? '\\\\' : '';\n var chInnerEscape = (chOpen == '['? '\\\\' : '');\n var reSubExp = new RegExp(chEscape + chOpen + \"([^\" + chInnerEscape + chOpen + chInnerEscape + chClose + \"]+)\" + chEscape + chClose);\n while (a = s.match(reSubExp)) {\n var value = this.parseExpression(a[1]);\n if (value === undefined) return undefined;\n var sSearch = chOpen + a[1] + chClose;\n var sReplace = value != null? this.toStrBase(value) : \"undefined\";\n /*\n * Note that by default, the String replace() method only replaces the FIRST occurrence,\n * and there MIGHT be more than one occurrence of the expression we just parsed, so we could\n * do this instead:\n *\n * s = s.split(sSearch).join(sReplace);\n *\n * However, that's knd of an expensive (slow) solution, and it's not strictly necessary, since\n * any additional identical expressions will be picked up on a subsequent iteration through this loop.\n */\n s = s.replace(sSearch, sReplace);\n }\n if (this.achAddress.length) {\n chOpen = this.achAddress[0];\n chClose = this.achAddress[1];\n chEscape = (chOpen == '(' || chOpen == '{' || chOpen == '[')? '\\\\' : '';\n chInnerEscape = (chOpen == '['? '\\\\' : '');\n reSubExp = new RegExp(chEscape + chOpen + \"([^\" + chInnerEscape + chOpen + chInnerEscape + chClose + \"]+)\" + chEscape + chClose);\n while (a = s.match(reSubExp)) {\n s = this.parseAddrReference(s, a[1]);\n }\n }\n return this.parseSysVars(s);\n }\n\n /**\n * parseSysVars(s)\n *\n * Returns the given string with any recognized \"$var\" replaced with its value; eg:\n *\n * $ops: the number of opcodes executed since the last time it was displayed (or reset)\n *\n * @this {Debugger}\n * @param {string} s\n * @return {string}\n */\n parseSysVars(s)\n {\n var a;\n while (a = s.match(/\\$([a-z]+)/i)) {\n var v = null;\n switch(a[1].toLowerCase()) {\n case \"ops\":\n v = this.cOpcodes - this.cOpcodesStart;\n break;\n }\n if (v == null) break;\n s = s.replace(a[0], v.toString());\n }\n return s;\n }\n\n /**\n * parseUnary(value, nUnary)\n *\n * nUnary is actually a small \"stack\" of unary operations encoded in successive pairs of bits.\n * As parseExpression() encounters each unary operator, nUnary is shifted left 2 bits, and the\n * new unary operator is encoded in bits 0 and 1 (0b00 is none, 0b01 is negate, 0b10 is complement,\n * and 0b11 is reserved). Here, we process the bits in reverse order (hence the stack-like nature),\n * ensuring that we process the unary operators associated with this value right-to-left.\n *\n * Since bitwise operators see only 32 bits, more than 16 unary operators cannot be supported\n * using this method. We'll let parseExpression() worry about that; if it ever happens in practice,\n * then we'll have to switch to a more \"expensive\" approach (eg, an actual array of unary operators).\n *\n * @this {Debugger}\n * @param {number} value\n * @param {number} nUnary\n * @return {number}\n */\n parseUnary(value, nUnary)\n {\n while (nUnary) {\n switch(nUnary & 0o3) {\n case 1:\n value = -this.truncate(value);\n break;\n case 2:\n value = this.evalXOR(value, -1); // this is easier than adding an evalNOT()...\n break;\n case 3:\n var bit = 35; // simple left-to-right zero-bit-counting loop...\n while (bit >= 0 && !this.evalAND(value, Math.pow(2, bit))) bit--;\n value = 35 - bit;\n break;\n }\n nUnary >>>= 2;\n }\n return value;\n }\n\n /**\n * parseValue(sValue, sName, fQuiet, nUnary)\n *\n * @this {Debugger}\n * @param {string|undefined} sValue\n * @param {string|null|*} [sName] is the name of the value, if any\n * @param {Array|undefined|boolean} [fQuiet]\n * @param {number} [nUnary] (0 for none, 1 for negate, 2 for complement, 3 for leading zeros)\n * @return {number|undefined} numeric value, or undefined if sValue is either undefined or invalid\n */\n parseValue(sValue, sName, fQuiet, nUnary = 0)\n {\n var value;\n var aUndefined = Array.isArray(fQuiet)? fQuiet : undefined;\n\n if (sValue != null) {\n var iReg = this.getRegIndex(sValue);\n if (iReg >= 0) {\n value = this.getRegValue(iReg);\n } else {\n value = this.getVariable(sValue);\n if (value != null) {\n var sUndefined = this.getVariableFixup(sValue);\n if (sUndefined) {\n if (aUndefined) {\n aUndefined.push(sUndefined);\n } else {\n var valueUndefined = this.parseExpression(sUndefined, fQuiet);\n if (valueUndefined !== undefined) {\n value += valueUndefined;\n } else {\n if (!fQuiet) {\n this.println(\"undefined \" + (sName || \"value\") + \": \" + sValue + \" (\" + sUndefined + \")\");\n }\n value = undefined;\n }\n }\n }\n } else {\n /*\n * A feature of MACRO-10 is that any single-digit number is automatically interpreted as base-10.\n */\n value = Str.parseInt(sValue, sValue.length > 1 || this.nBase > 10? this.nBase : 10);\n }\n }\n if (value != null) {\n value = this.truncate(this.parseUnary(value, nUnary));\n } else {\n if (!fQuiet) {\n this.println(\"invalid \" + (sName || \"value\") + \": \" + sValue);\n }\n }\n } else {\n if (!fQuiet) {\n this.println(\"missing \" + (sName || \"value\"));\n }\n }\n return value;\n }\n\n /**\n * printValue(sVar, value)\n *\n * @this {Debugger}\n * @param {string|null} sVar\n * @param {number|undefined} value\n * @return {boolean} true if value defined, false if not\n */\n printValue(sVar, value)\n {\n var sValue;\n var fDefined = false;\n if (value !== undefined) {\n fDefined = true;\n if (this.nBase == 8) {\n sValue = this.toStrBase(value, this.nBits, 8, 1) + \" \" + value + '.';\n } else {\n sValue = this.toStrBase(value, this.nBits, 16, 1) + \" \" + this.toStrBase(value, this.nBits, 8, 1) + \" \" + this.toStrBase(value, this.nBits, 2, this.nBits <= 32? 8 : 6) + \" \" + value + '.';\n }\n if (value >= 0x20 && value < 0x7F) {\n sValue += \" '\" + String.fromCharCode(value) + \"'\";\n }\n }\n sVar = (sVar != null? (sVar + \": \") : \"\");\n this.println(sVar + sValue);\n return fDefined;\n }\n\n /**\n * resetVariables()\n *\n * @this {Debugger}\n * @return {Object}\n */\n resetVariables()\n {\n var a = this.aVariables;\n this.aVariables = {};\n return a;\n }\n\n /**\n * restoreVariables(a)\n *\n * @this {Debugger}\n * @param {Object} a (from previous resetVariables() call)\n */\n restoreVariables(a)\n {\n this.aVariables = a;\n }\n\n /**\n * printVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} [sVar]\n * @return {boolean} true if all value(s) defined, false if not\n */\n printVariable(sVar)\n {\n var cVariables = 0;\n if (this.aVariables) {\n if (sVar) {\n return this.printValue(sVar, this.aVariables[sVar] && this.aVariables[sVar].value);\n }\n var aVars = Object.keys(this.aVariables);\n aVars.sort();\n for (var i = 0; i < aVars.length; i++) {\n this.printValue(aVars[i], this.aVariables[aVars[i]].value);\n cVariables++;\n }\n }\n return cVariables > 0;\n }\n\n /**\n * delVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n */\n delVariable(sVar)\n {\n delete this.aVariables[sVar];\n }\n\n /**\n * getVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {number|undefined}\n */\n getVariable(sVar)\n {\n if (this.aVariables[sVar]) {\n return this.aVariables[sVar].value;\n }\n sVar = sVar.substr(0, 6);\n return this.aVariables[sVar] && this.aVariables[sVar].value;\n }\n\n /**\n * getVariableFixup(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {string|undefined}\n */\n getVariableFixup(sVar)\n {\n return this.aVariables[sVar] && this.aVariables[sVar].sUndefined;\n }\n\n /**\n * isVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {boolean}\n */\n isVariable(sVar)\n {\n return this.aVariables[sVar] !== undefined;\n }\n\n /**\n * setVariable(sVar, value, sUndefined)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @param {number} value\n * @param {string|undefined} [sUndefined]\n */\n setVariable(sVar, value, sUndefined)\n {\n this.aVariables[sVar] = {value, sUndefined};\n }\n\n /**\n * toStrBase(n, nBits, nBase, nGrouping)\n *\n * Use this instead of Str's toOct()/toDec()/toHex() to convert numbers to the Debugger's default base.\n *\n * @this {Debugger}\n * @param {number|null|undefined} n\n * @param {number} [nBits] (-1 to strip leading zeros, 0 to allow a variable number of digits)\n * @param {number} [nBase]\n * @param {number} [nGrouping] (if nBase is 2, this is a grouping; otherwise, it's a prefix condition)\n * @return {string}\n */\n toStrBase(n, nBits = 0, nBase = 0, nGrouping = 0)\n {\n var s;\n switch(nBase || this.nBase) {\n case 2:\n s = Str.toBin(n, nBits > 0? nBits : 0, nGrouping);\n break;\n case 8:\n s = Str.toOct(n, nBits > 0? ((nBits + 2)/3)|0 : 0, !!nGrouping);\n break;\n case 10:\n /*\n * The multiplier is actually Math.log(2)/Math.log(10), but an approximation is more than adequate.\n */\n s = Str.toDec(n, nBits > 0? Math.ceil(nBits * 0.3) : 0);\n break;\n case 16:\n default:\n s = Str.toHex(n, nBits > 0? ((nBits + 3) >> 2) : 0, !!nGrouping);\n break;\n }\n return (nBits < 0? Str.stripLeadingZeros(s) : s);\n }\n}\n\nif (DEBUGGER) {\n\n /*\n * These are our operator precedence tables. Operators toward the bottom (with higher values) have\n * higher precedence. aBinOpPrecedence was our original table; we had to add aDECOpPrecedence because\n * the precedence of operators in DEC's MACRO-10 expressions differ. Having separate tables also allows\n * us to remove operators that shouldn't be supported, but unless some operator creates a problem,\n * I prefer to keep as much commonality between the tables as possible.\n *\n * Missing from these tables are the (limited) set of unary operators we support (negate and complement),\n * since this is only a BINARY operator precedence, not a general-purpose precedence table. Assume that\n * all unary operators take precedence over all binary operators.\n */\n Debugger.aBinOpPrecedence = {\n '||': 5, // logical OR\n '&&': 6, // logical AND\n '!': 7, // bitwise OR (conflicts with logical NOT, but we never supported that)\n '|': 7, // bitwise OR\n '^!': 8, // bitwise XOR (added by MACRO-10 sometime between the 1972 and 1978 versions)\n '&': 9, // bitwise AND\n '!=': 10, // inequality\n '==': 10, // equality\n '>=': 11, // greater than or equal to\n '>': 11, // greater than\n '<=': 11, // less than or equal to\n '<': 11, // less than\n '>>>': 12, // unsigned bitwise right shift\n '>>': 12, // bitwise right shift\n '<<': 12, // bitwise left shift\n '-': 13, // subtraction\n '+': 13, // addition\n '^/': 14, // remainder\n '/': 14, // division\n '*': 14, // multiplication\n '_': 19, // MACRO-10 shift operator\n '^_': 19, // MACRO-10 internal shift operator (converted from 'B' suffix form that MACRO-10 uses)\n '{': 20, // open grouped expression (converted from achGroup[0])\n '}': 20 // close grouped expression (converted from achGroup[1])\n };\n Debugger.aDECOpPrecedence = {\n ',,': 1, // high-word,,low-word\n '||': 5, // logical OR\n '&&': 6, // logical AND\n '!=': 10, // inequality\n '==': 10, // equality\n '>=': 11, // greater than or equal to\n '>': 11, // greater than\n '<=': 11, // less than or equal to\n '<': 11, // less than\n '>>>': 12, // unsigned bitwise right shift\n '>>': 12, // bitwise right shift\n '<<': 12, // bitwise left shift\n '-': 13, // subtraction\n '+': 13, // addition\n '^/': 14, // remainder\n '/': 14, // division\n '*': 14, // multiplication\n '!': 15, // bitwise OR (conflicts with logical NOT, but we never supported that)\n '|': 15, // bitwise OR\n '^!': 15, // bitwise XOR (added by MACRO-10 sometime between the 1972 and 1978 versions)\n '&': 15, // bitwise AND\n '_': 19, // MACRO-10 shift operator\n '^_': 19, // MACRO-10 internal shift operator (converted from 'B' suffix form that MACRO-10 uses)\n '{': 20, // open grouped expression (converted from achGroup[0])\n '}': 20 // close grouped expression (converted from achGroup[1])\n };\n\n /*\n * Assorted constants\n */\n Debugger.TWO_POW32 = Math.pow(2, 32);\n\n} // endif DEBUGGER\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/debugger.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Debugger8080 Address Object\n *\n * addr address\n * fTemporary true if this is a temporary breakpoint address\n * sCmd set for breakpoint addresses if there's an associated command string\n * aCmds preprocessed commands (from sCmd)\n *\n * @typedef {{\n * addr:(number|undefined),\n * fTemporary:(boolean|undefined),\n * sCmd:(string|undefined),\n * aCmds:(Array.<string>|undefined)\n * }}\n */\nvar DbgAddr8080;\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass Debugger8080 extends Debugger {\n /**\n * Debugger8080(parmsDbg)\n *\n * The Debugger8080 component supports the following optional (parmsDbg) properties:\n *\n * commands: string containing zero or more commands, separated by ';'\n *\n * messages: string containing zero or more message categories to enable;\n * multiple categories must be separated by '|' or ';'. Parsed by messageInit().\n *\n * The Debugger8080 component is an optional component that implements a variety of user\n * commands for controlling the CPU, dumping and editing memory, etc.\n *\n * @this {Debugger8080}\n * @param {Object} parmsDbg\n */\n constructor(parmsDbg)\n {\n if (DEBUGGER) {\n\n super(parmsDbg);\n\n this.style = Debugger8080.STYLE_8080;\n\n /*\n * Most commands that require an address call parseAddr(), which defaults to dbgAddrNextCode\n * or dbgAddrNextData when no address has been given. doDump() and doUnassemble(), in turn,\n * update dbgAddrNextData and dbgAddrNextCode, respectively, when they're done.\n *\n * For TEMPORARY breakpoint addresses, we set fTemporary to true, so that they can be automatically\n * cleared when they're hit.\n */\n this.dbgAddrNextCode = this.newAddr();\n this.dbgAddrNextData = this.newAddr();\n this.dbgAddrAssemble = this.newAddr();\n\n /*\n * aSymbolTable is an array of SymbolTable objects, one per ROM or other chunk of address space,\n * where each object contains the following properties:\n *\n * sModule\n * addr (physical address, if any; eg, symbols for a ROM)\n * len\n * aSymbols\n * aOffsets\n *\n * See addSymbols() for more details, since that's how callers add sets of symbols to the table.\n */\n this.aSymbolTable = [];\n\n /*\n * clearBreakpoints() initializes the breakpoints lists: aBreakExec is a list of addresses\n * to halt on whenever attempting to execute an instruction at the corresponding address,\n * and aBreakRead and aBreakWrite are lists of addresses to halt on whenever a read or write,\n * respectively, occurs at the corresponding address.\n *\n * NOTE: Curiously, after upgrading the Google Closure Compiler from v20141215 to v20150609,\n * the resulting compiled code would crash in clearBreakpoints(), because the (renamed) aBreakRead\n * property was already defined. To eliminate whatever was confusing the Closure Compiler, I've\n * explicitly initialized all the properties that clearBreakpoints() (re)initializes.\n */\n this.aBreakExec = this.aBreakRead = this.aBreakWrite = [];\n this.clearBreakpoints();\n\n /*\n * The new \"bn\" command allows you to specify a number of instructions to execute and then stop;\n * \"bn 0\" disables any outstanding count.\n */\n this.nBreakIns = 0;\n\n /*\n * Execution history is allocated by historyInit() whenever checksEnabled() conditions change.\n * Execution history is updated whenever the CPU calls checkInstruction(), which will happen\n * only when checksEnabled() returns true (eg, whenever one or more breakpoints have been set).\n * This ensures that, by default, the CPU runs as fast as possible.\n */\n this.historyInit();\n\n /*\n * Initialize Debugger8080 message support\n */\n this.afnDumpers = {};\n this.messageInit(parmsDbg['messages']);\n\n this.sInitCommands = parmsDbg['commands'];\n\n /*\n * Make it easier to access Debugger commands from an external REPL, like the WebStorm \"live\" console\n * window; eg:\n *\n * pc8080('r')\n * pc8080('dw 0:0')\n * pc8080('h')\n * ...\n */\n var dbg = this;\n if (window) {\n if (window[PC8080.APPCLASS] === undefined) {\n window[PC8080.APPCLASS] = function(s) { return dbg.doCommands(s); };\n }\n } else {\n if (global[PC8080.APPCLASS] === undefined) {\n global[PC8080.APPCLASS] = function(s) { return dbg.doCommands(s); };\n }\n }\n\n } // endif DEBUGGER\n }\n\n /**\n * initBus(bus, cpu, dbg)\n *\n * @this {Debugger8080}\n * @param {Computer8080} cmp\n * @param {Bus8080} bus\n * @param {CPUState8080} cpu\n * @param {Debugger8080} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.cmp = cmp;\n\n /*\n * Re-initialize Debugger message support if necessary\n */\n var sMessages = cmp.getMachineParm('messages');\n if (sMessages) this.messageInit(sMessages);\n\n this.aaOpDescs = Debugger8080.aaOpDescs;\n\n this.messageDump(Messages8080.BUS, function onDumpBus(asArgs) { dbg.dumpBus(asArgs); });\n\n this.setReady();\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {Debugger8080}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"debugInput\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var dbg = this;\n switch (sBinding) {\n\n case \"debugInput\":\n this.bindings[sBinding] = control;\n this.controlDebug = /** @type {HTMLInputElement} */ (control);\n /*\n * For halted machines, this is fine, but for auto-start machines, it can be annoying.\n *\n * control.focus();\n */\n control.onkeydown = function onKeyDownDebugInput(event) {\n var sCmd;\n if (event.keyCode == Keys.KEYCODE.CR) {\n sCmd = dbg.controlDebug.value;\n dbg.controlDebug.value = \"\";\n dbg.doCommands(sCmd, true);\n }\n else if (event.keyCode == Keys.KEYCODE.ESC) {\n dbg.controlDebug.value = sCmd = \"\";\n }\n else {\n if (event.keyCode == Keys.KEYCODE.UP) {\n sCmd = dbg.getPrevCommand();\n }\n else if (event.keyCode == Keys.KEYCODE.DOWN) {\n sCmd = dbg.getNextCommand();\n }\n if (sCmd != null) {\n var cch = sCmd.length;\n dbg.controlDebug.value = sCmd;\n dbg.controlDebug.setSelectionRange(cch, cch);\n }\n }\n if (sCmd != null && event.preventDefault) event.preventDefault();\n };\n return true;\n\n case \"debugEnter\":\n this.bindings[sBinding] = control;\n Web.onClickRepeat(\n control,\n 500, 100,\n function onClickDebugEnter(fRepeat) {\n if (dbg.controlDebug) {\n var sCmds = dbg.controlDebug.value;\n dbg.controlDebug.value = \"\";\n dbg.doCommands(sCmds, true);\n return true;\n }\n if (DEBUG) dbg.log(\"no debugger input buffer\");\n return false;\n }\n );\n return true;\n\n case \"step\":\n this.bindings[sBinding] = control;\n Web.onClickRepeat(\n control,\n 500, 100,\n function onClickStep(fRepeat) {\n var fCompleted = false;\n if (!dbg.isBusy(true)) {\n dbg.setBusy(true);\n fCompleted = dbg.stepCPU(fRepeat? 1 : 0);\n dbg.setBusy(false);\n }\n return fCompleted;\n }\n );\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * updateFocus()\n *\n * @this {Debugger8080}\n */\n updateFocus()\n {\n if (this.controlDebug) this.controlDebug.focus();\n }\n\n /**\n * getAddr(dbgAddr, fWrite, nb)\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080|null|undefined} dbgAddr\n * @param {boolean} [fWrite]\n * @param {number} [nb] number of bytes to check (1 or 2); default is 1\n * @return {number} is the corresponding linear address, or CPUDef8080.ADDR_INVALID\n */\n getAddr(dbgAddr, fWrite, nb)\n {\n var addr = dbgAddr && dbgAddr.addr;\n if (addr == null) {\n addr = CPUDef8080.ADDR_INVALID;\n }\n return addr;\n }\n\n /**\n * getByte(dbgAddr, inc)\n *\n * We must route all our memory requests through the CPU now, in case paging is enabled.\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {number} [inc]\n * @return {number}\n */\n getByte(dbgAddr, inc)\n {\n var b = 0xff;\n var addr = this.getAddr(dbgAddr, false, 1);\n if (addr !== CPUDef8080.ADDR_INVALID) {\n b = this.bus.getByteDirect(addr);\n if (inc) this.incAddr(dbgAddr, inc);\n }\n return b;\n }\n\n /**\n * getWord(dbgAddr, fAdvance)\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {boolean} [fAdvance]\n * @return {number}\n */\n getWord(dbgAddr, fAdvance)\n {\n return this.getShort(dbgAddr, fAdvance? 2 : 0);\n }\n\n /**\n * getShort(dbgAddr, inc)\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {number} [inc]\n * @return {number}\n */\n getShort(dbgAddr, inc)\n {\n var w = 0xffff;\n var addr = this.getAddr(dbgAddr, false, 2);\n if (addr !== CPUDef8080.ADDR_INVALID) {\n w = this.bus.getShortDirect(addr);\n if (inc) this.incAddr(dbgAddr, inc);\n }\n return w;\n }\n\n /**\n * setByte(dbgAddr, b, inc)\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {number} b\n * @param {number} [inc]\n */\n setByte(dbgAddr, b, inc)\n {\n var addr = this.getAddr(dbgAddr, true, 1);\n if (addr !== CPUDef8080.ADDR_INVALID) {\n this.bus.setByteDirect(addr, b);\n if (inc) this.incAddr(dbgAddr, inc);\n this.cpu.updateCPU(true); // we set fForce to true in case video memory was the target\n }\n }\n\n /**\n * setShort(dbgAddr, w, inc)\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {number} w\n * @param {number} [inc]\n */\n setShort(dbgAddr, w, inc)\n {\n var addr = this.getAddr(dbgAddr, true, 2);\n if (addr !== CPUDef8080.ADDR_INVALID) {\n this.bus.setShortDirect(addr, w);\n if (inc) this.incAddr(dbgAddr, inc);\n this.cpu.updateCPU(true); // we set fForce to true in case video memory was the target\n }\n }\n\n /**\n * newAddr(addr)\n *\n * Returns a NEW DbgAddr8080 object, initialized with specified values and/or defaults.\n *\n * @this {Debugger8080}\n * @param {number} [addr]\n * @return {DbgAddr8080}\n */\n newAddr(addr)\n {\n return {addr: addr, fTemporary: false};\n }\n\n /**\n * setAddr(dbgAddr, addr)\n *\n * Updates an EXISTING DbgAddr8080 object, initialized with specified values and/or defaults.\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {number} addr\n * @return {DbgAddr8080}\n */\n setAddr(dbgAddr, addr)\n {\n dbgAddr.addr = addr;\n dbgAddr.fTemporary = false;\n return dbgAddr;\n }\n\n /**\n * packAddr(dbgAddr)\n *\n * Packs a DbgAddr8080 object into an Array suitable for saving in a machine state object.\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @return {Array}\n */\n packAddr(dbgAddr)\n {\n return [dbgAddr.addr, dbgAddr.fTemporary];\n }\n\n /**\n * unpackAddr(aAddr)\n *\n * Unpacks a DbgAddr8080 object from an Array created by packAddr() and restored from a saved machine state.\n *\n * @this {Debugger8080}\n * @param {Array} aAddr\n * @return {DbgAddr8080}\n */\n unpackAddr(aAddr)\n {\n return {addr: aAddr[0], fTemporary: aAddr[1]};\n }\n\n /**\n * parseAddr(sAddr, fCode, fNoChecks)\n *\n * Address evaluation and validation (eg, range checks) are no longer performed at this stage. That's\n * done later, by getAddr(), which returns CPUDef8080.ADDR_INVALID for invalid segments, out-of-range offsets,\n * etc. The Debugger's low-level get/set memory functions verify all getAddr() results, but even if an\n * invalid address is passed through to the Bus memory interfaces, the address will simply be masked with\n * Bus8080.nBusLimit; in the case of CPUDef8080.ADDR_INVALID, that will generally refer to the top of the physical\n * address space.\n *\n * @this {Debugger8080}\n * @param {string|undefined} sAddr\n * @param {boolean} [fCode] (true if target is code, false if target is data)\n * @param {boolean} [fNoChecks] (true when setting breakpoints that may not be valid now, but will be later)\n * @return {DbgAddr8080|null|undefined}\n */\n parseAddr(sAddr, fCode, fNoChecks)\n {\n var dbgAddr;\n var dbgAddrNext = (fCode? this.dbgAddrNextCode : this.dbgAddrNextData);\n var addr = dbgAddrNext.addr;\n if (sAddr !== undefined) {\n sAddr = this.parseReference(sAddr) || sAddr;\n dbgAddr = this.findSymbolAddr(sAddr);\n if (dbgAddr) return dbgAddr;\n addr = this.parseExpression(sAddr);\n }\n if (addr != null) {\n dbgAddr = this.newAddr(addr);\n }\n return dbgAddr;\n }\n\n /**\n * parseAddrOptions(dbdAddr, sOptions)\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {string} [sOptions]\n */\n parseAddrOptions(dbgAddr, sOptions)\n {\n if (sOptions) {\n var a = sOptions.match(/(['\"])(.*?)\\1/);\n if (a) {\n dbgAddr.aCmds = this.parseCommand(dbgAddr.sCmd = a[2]);\n }\n }\n }\n\n /**\n * incAddr(dbgAddr, inc)\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {number} [inc] contains value to increment dbgAddr by (default is 1)\n */\n incAddr(dbgAddr, inc)\n {\n if (dbgAddr.addr != null) {\n dbgAddr.addr += (inc || 1);\n }\n }\n\n /**\n * toHexOffset(off)\n *\n * @this {Debugger8080}\n * @param {number|null|undefined} [off]\n * @return {string} the hex representation of off\n */\n toHexOffset(off)\n {\n return Str.toHex(off, 4);\n }\n\n /**\n * toHexAddr(dbgAddr)\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @return {string} the hex representation of the address\n */\n toHexAddr(dbgAddr)\n {\n return this.toHexOffset(dbgAddr.addr);\n }\n\n /**\n * getSZ(dbgAddr, cchMax)\n *\n * Gets zero-terminated (aka \"ASCIIZ\") string from dbgAddr. It also stops at the first '$', in case this is\n * a '$'-terminated string -- mainly because I'm lazy and didn't feel like writing a separate get() function.\n * Yes, a zero-terminated string containing a '$' will be prematurely terminated, and no, I don't care.\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {number} [cchMax] (default is 256)\n * @return {string} (and dbgAddr advanced past the terminating zero)\n */\n getSZ(dbgAddr, cchMax)\n {\n var s = \"\";\n cchMax = cchMax || 256;\n while (s.length < cchMax) {\n var b = this.getByte(dbgAddr, 1);\n if (!b || b == 0x24 || b >= 127) break;\n s += (b >= 32? String.fromCharCode(b) : '.');\n }\n return s;\n }\n\n /**\n * dumpBlocks(aBlocks, sAddr)\n *\n * @this {Debugger8080}\n * @param {Array} aBlocks\n * @param {string} [sAddr] (optional block address)\n */\n dumpBlocks(aBlocks, sAddr)\n {\n var addr = 0, i = 0, n = aBlocks.length;\n\n if (sAddr) {\n addr = this.getAddr(this.parseAddr(sAddr));\n if (addr === CPUDef8080.ADDR_INVALID) {\n this.println(\"invalid address: \" + sAddr);\n return;\n }\n i = addr >>> this.bus.nBlockShift;\n n = 1;\n }\n\n this.println(\"blockid physical blockaddr used size type\");\n this.println(\"-------- --------- ---------- ------ ------ ----\");\n\n var typePrev = -1, cPrev = 0;\n while (n--) {\n var block = aBlocks[i];\n if (block.type == typePrev) {\n if (!cPrev++) this.println(\"...\");\n } else {\n typePrev = block.type;\n var sType = Memory8080.TYPE.NAMES[typePrev];\n if (block) {\n 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);\n }\n if (typePrev != Memory8080.TYPE.NONE) typePrev = -1;\n cPrev = 0;\n }\n addr += this.bus.nBlockSize;\n i++;\n }\n }\n\n /**\n * dumpBus(asArgs)\n *\n * Dumps Bus allocations.\n *\n * @this {Debugger8080}\n * @param {Array.<string>} asArgs (asArgs[0] is an optional block address)\n */\n dumpBus(asArgs)\n {\n this.dumpBlocks(this.bus.aMemBlocks, asArgs[0]);\n }\n\n /**\n * dumpHistory(sPrev, sLines)\n *\n * If sLines is not a number, it can be a instruction filter. However, for the moment, the only\n * supported filter is \"call\", which filters the history buffer for all CALL and RET instructions\n * from the specified previous point forward.\n *\n * @this {Debugger8080}\n * @param {string} [sPrev] is a (decimal) number of instructions to rewind to (default is 10)\n * @param {string} [sLines] is a (decimal) number of instructions to print (default is, again, 10)\n */\n dumpHistory(sPrev, sLines)\n {\n var sMore = \"\";\n var cHistory = 0;\n var iHistory = this.iOpcodeHistory;\n var aHistory = this.aOpcodeHistory;\n\n if (aHistory.length) {\n var nPrev = +sPrev || this.nextHistory;\n var nLines = +sLines || 10;\n\n if (isNaN(nPrev)) {\n nPrev = nLines;\n } else {\n sMore = \"more \";\n }\n\n if (nPrev > aHistory.length) {\n this.println(\"note: only \" + aHistory.length + \" available\");\n nPrev = aHistory.length;\n }\n\n iHistory -= nPrev;\n if (iHistory < 0) {\n /*\n * If the dbgAddr of the last aHistory element contains a valid selector, wrap around.\n */\n if (aHistory[aHistory.length - 1].addr == null) {\n nPrev = iHistory + nPrev;\n iHistory = 0;\n } else {\n iHistory += aHistory.length;\n }\n }\n\n var aFilters = [];\n if (sLines == \"call\") {\n nLines = 100000;\n aFilters = [\"CALL\"];\n }\n\n if (sPrev !== undefined) {\n this.println(nPrev + \" instructions earlier:\");\n }\n\n /*\n * TODO: The following is necessary to prevent dumpHistory() from causing additional (or worse, recursive)\n * faults due to segmented addresses that are no longer valid, but the only alternative is to dramatically\n * increase the amount of memory used to store instruction history (eg, storing copies of all the instruction\n * bytes alongside the execution addresses).\n *\n * For now, we're living dangerously, so that our history dumps actually work.\n *\n * this.nSuppressBreaks++;\n *\n * If you re-enable this protection, be sure to re-enable the decrement below, too.\n */\n while (nLines > 0 && iHistory != this.iOpcodeHistory) {\n\n var dbgAddr = aHistory[iHistory++];\n if (dbgAddr.addr == null) break;\n\n /*\n * We must create a new dbgAddr from the address in aHistory, because dbgAddr was\n * a reference, not a copy, and we don't want getInstruction() modifying the original.\n */\n var dbgAddrNew = this.newAddr(dbgAddr.addr);\n\n var sComment = \"history\";\n var nSequence = nPrev--;\n if (DEBUG && dbgAddr.cycleCount != null) {\n sComment = \"cycles\";\n nSequence = dbgAddr.cycleCount;\n }\n\n var sInstruction = this.getInstruction(dbgAddrNew, sComment, nSequence);\n\n if (!aFilters.length || sInstruction.indexOf(aFilters[0]) >= 0) {\n this.println(sInstruction);\n }\n\n /*\n * If there were OPERAND or ADDRESS overrides on the previous instruction, getInstruction()\n * will have automatically disassembled additional bytes, so skip additional history entries.\n */\n if (dbgAddrNew.cOverrides) {\n iHistory += dbgAddrNew.cOverrides; nLines -= dbgAddrNew.cOverrides; nPrev -= dbgAddrNew.cOverrides;\n }\n\n if (iHistory >= aHistory.length) iHistory = 0;\n this.nextHistory = nPrev;\n cHistory++;\n nLines--;\n }\n /*\n * See comments above.\n *\n * this.nSuppressBreaks--;\n */\n }\n\n if (!cHistory) {\n this.println(\"no \" + sMore + \"history available\");\n this.nextHistory = undefined;\n }\n }\n\n /**\n * messageInit(sEnable)\n *\n * @this {Debugger8080}\n * @param {string|undefined} sEnable contains zero or more message categories to enable, separated by '|'\n */\n messageInit(sEnable)\n {\n this.dbg = this;\n this.bitsMessage = this.bitsWarning = Messages8080.WARN;\n this.sMessagePrev = null;\n this.aMessageBuffer = [];\n /*\n * Internally, we use \"key\" instead of \"keys\", since the latter is a method on JavasScript objects,\n * but externally, we allow the user to specify \"keys\"; \"kbd\" is also allowed as shorthand for \"keyboard\".\n */\n var aEnable = this.parseCommand(sEnable.replace(\"keys\",\"key\").replace(\"kbd\",\"keyboard\"), false, '|');\n if (aEnable.length) {\n for (var m in Messages8080.CATEGORIES) {\n if (Usr.indexOf(aEnable, m) >= 0) {\n this.bitsMessage |= Messages8080.CATEGORIES[m];\n this.println(m + \" messages enabled\");\n }\n }\n }\n }\n\n /**\n * messageDump(bitMessage, fnDumper)\n *\n * @this {Debugger8080}\n * @param {number} bitMessage is one Messages category flag\n * @param {function(Array.<string>)} fnDumper is a function the Debugger can use to dump data for that category\n * @return {boolean} true if successfully registered, false if not\n */\n messageDump(bitMessage, fnDumper)\n {\n for (var m in Messages8080.CATEGORIES) {\n if (bitMessage == Messages8080.CATEGORIES[m]) {\n this.afnDumpers[m] = fnDumper;\n return true;\n }\n }\n return false;\n }\n\n /**\n * getRegIndex(sReg, off)\n *\n * @this {Debugger8080}\n * @param {string} sReg\n * @param {number} [off] optional offset into sReg\n * @return {number} register index, or -1 if not found\n */\n getRegIndex(sReg, off)\n {\n var i;\n sReg = sReg.toUpperCase();\n if (off == null) {\n i = Usr.indexOf(Debugger8080.REGS, sReg);\n } else {\n i = Usr.indexOf(Debugger8080.REGS, sReg.substr(off, 2));\n if (i < 0) i = Usr.indexOf(Debugger8080.REGS, sReg.substr(off, 1));\n }\n return i;\n }\n\n /**\n * getRegString(iReg)\n *\n * @this {Debugger8080}\n * @param {number} iReg\n * @return {string}\n */\n getRegString(iReg)\n {\n var cch = 0;\n var n = this.getRegValue(iReg);\n if (n !== undefined) {\n switch(iReg) {\n case Debugger8080.REG_A:\n case Debugger8080.REG_B:\n case Debugger8080.REG_C:\n case Debugger8080.REG_D:\n case Debugger8080.REG_E:\n case Debugger8080.REG_H:\n case Debugger8080.REG_L:\n case Debugger8080.REG_M:\n cch = 2;\n break;\n case Debugger8080.REG_BC:\n case Debugger8080.REG_DE:\n case Debugger8080.REG_HL:\n case Debugger8080.REG_SP:\n case Debugger8080.REG_PC:\n case Debugger8080.REG_PS:\n case Debugger8080.REG_PSW:\n cch = 4;\n break;\n }\n }\n return cch? Str.toHex(n, cch) : \"??\";\n }\n\n /**\n * getRegValue(iReg)\n *\n * @this {Debugger8080}\n * @param {number} iReg\n * @return {number|undefined}\n */\n getRegValue(iReg)\n {\n var n;\n if (iReg >= 0) {\n var cpu = this.cpu;\n switch(iReg) {\n case Debugger8080.REG_A:\n n = cpu.regA;\n break;\n case Debugger8080.REG_B:\n n = cpu.regB;\n break;\n case Debugger8080.REG_C:\n n = cpu.regC;\n break;\n case Debugger8080.REG_BC:\n n = cpu.getBC();\n break;\n case Debugger8080.REG_D:\n n = cpu.regD;\n break;\n case Debugger8080.REG_E:\n n = cpu.regE;\n break;\n case Debugger8080.REG_DE:\n n = cpu.getDE();\n break;\n case Debugger8080.REG_H:\n n = cpu.regH;\n break;\n case Debugger8080.REG_L:\n n = cpu.regL;\n break;\n case Debugger8080.REG_HL:\n n = cpu.getHL();\n break;\n case Debugger8080.REG_M:\n n = cpu.getByte(cpu.getHL());\n break;\n case Debugger8080.REG_SP:\n n = cpu.getSP();\n break;\n case Debugger8080.REG_PC:\n n = cpu.getPC();\n break;\n case Debugger8080.REG_PS:\n n = cpu.getPS();\n break;\n case Debugger8080.REG_PSW:\n n = cpu.getPSW();\n break;\n default:\n break;\n }\n }\n return n;\n }\n\n /**\n * replaceRegs(s)\n *\n * @this {Debugger8080}\n * @param {string} s\n * @return {string}\n */\n replaceRegs(s)\n {\n /*\n * Replace any references first; this means that register references inside the reference\n * do NOT need to be prefixed with '@'.\n */\n s = this.parseReference(s) || s;\n\n /*\n * Replace every @XX (or @XXX), where XX (or XXX) is a register, with the register's value.\n */\n var i = 0;\n var b, sChar, sAddr, dbgAddr, sReplace;\n while ((i = s.indexOf('@', i)) >= 0) {\n var iReg = this.getRegIndex(s, i + 1);\n if (iReg >= 0) {\n s = s.substr(0, i) + this.getRegString(iReg) + s.substr(i + 1 + Debugger8080.REGS[iReg].length);\n }\n i++;\n }\n /*\n * Replace every #XX, where XX is a hex byte value, with the corresponding ASCII character (if printable).\n */\n i = 0;\n while ((i = s.indexOf('#', i)) >= 0) {\n sChar = s.substr(i+1, 2);\n b = Str.parseInt(sChar, 16);\n if (b != null && b >= 32 && b < 127) {\n sReplace = sChar + \" '\" + String.fromCharCode(b) + \"'\";\n s = s.replace('#' + sChar, sReplace);\n i += sReplace.length;\n continue;\n }\n i++;\n }\n /*\n * Replace every $XXXX:XXXX, where XXXX:XXXX is a segmented address, with the zero-terminated string at that address.\n */\n i = 0;\n while ((i = s.indexOf('$', i)) >= 0) {\n sAddr = s.substr(i+1, 9);\n dbgAddr = this.parseAddr(sAddr);\n if (dbgAddr) {\n sReplace = sAddr + ' \"' + this.getSZ(dbgAddr) + '\"';\n s = s.replace('$' + sAddr, sReplace);\n i += sReplace.length;\n continue;\n }\n i++;\n }\n /*\n * Replace every ^XXXX:XXXX, where XXXX:XXXX is a segmented address, with the FCB filename stored at that address.\n */\n i = 0;\n while ((i = s.indexOf('^', i)) >= 0) {\n sAddr = s.substr(i+1, 9);\n dbgAddr = this.parseAddr(sAddr);\n if (dbgAddr) {\n this.incAddr(dbgAddr);\n sReplace = sAddr + ' \"' + this.getSZ(dbgAddr, 11) + '\"';\n s = s.replace('^' + sAddr, sReplace);\n i += sReplace.length;\n continue;\n }\n i++;\n }\n return s;\n }\n\n /**\n * message(sMessage, fAddress)\n *\n * @this {Debugger8080}\n * @param {string} sMessage is any caller-defined message string\n * @param {boolean} [fAddress] is true to display the current CS:IP\n */\n message(sMessage, fAddress)\n {\n if (fAddress) {\n sMessage += \" at \" + this.toHexAddr(this.newAddr(this.cpu.getPC()));\n }\n\n if (this.bitsMessage & Messages8080.BUFFER) {\n this.aMessageBuffer.push(sMessage);\n return;\n }\n\n if (this.sMessagePrev && sMessage == this.sMessagePrev) return;\n this.sMessagePrev = sMessage;\n\n if (this.bitsMessage & Messages8080.HALT) {\n this.stopCPU();\n sMessage += \" (cpu halted)\";\n }\n\n this.println(sMessage); // + \" (\" + this.cpu.getCycles() + \" cycles)\"\n\n /*\n * We have no idea what the frequency of println() calls might be; all we know is that they easily\n * screw up the CPU's careful assumptions about cycles per burst. So we call yieldCPU() after every\n * message, to effectively end the current burst and start fresh.\n *\n * TODO: See CPU8080.calcStartTime() for a discussion of why we might want to call yieldCPU() *before*\n * we display the message.\n */\n if (this.cpu) this.cpu.yieldCPU();\n }\n\n /**\n * messageIO(component, port, bOut, addrFrom, name, bIn, bitsMessage)\n *\n * Most (if not all) port handlers should provide a name for their respective ports, so if no name is provided,\n * we assume this is an unknown port, and display a message by default.\n *\n * @this {Debugger8080}\n * @param {Component} component\n * @param {number} port\n * @param {number|null} bOut if an output operation\n * @param {number|null} [addrFrom]\n * @param {string|null} [name] of the port, if any\n * @param {number|null} [bIn] is the input value, if known, on an input operation\n * @param {number} [bitsMessage] is one or more Messages category flag(s)\n */\n messageIO(component, port, bOut, addrFrom, name, bIn, bitsMessage)\n {\n bitsMessage |= Messages8080.PORT;\n if (name == null || (this.bitsMessage & bitsMessage) == bitsMessage) {\n this.message(component.idComponent + '.' + (bOut != null? \"outPort\" : \"inPort\") + '(' + Str.toHexWord(port) + ',' + (name? name : \"unknown\") + (bOut != null? ',' + Str.toHexByte(bOut) : \"\") + ')' + (bIn != null? (\": \" + Str.toHexByte(bIn)) : \"\") + (addrFrom != null? (\" at \" + this.toHexOffset(addrFrom)) : \"\"));\n }\n }\n\n /**\n * init()\n *\n * @this {Debugger8080}\n */\n init()\n {\n this.println(\"Type ? for help with PC8080 Debugger commands\");\n this.updateStatus();\n if (this.sInitCommands) {\n var sCmds = this.sInitCommands;\n this.sInitCommands = null;\n this.doCommands(sCmds);\n }\n }\n\n /**\n * historyInit(fQuiet)\n *\n * This function is intended to be called by the constructor, reset(), addBreakpoint(), findBreakpoint()\n * and any other function that changes the checksEnabled() criteria used to decide whether checkInstruction()\n * should be called.\n *\n * That is, if the history arrays need to be allocated and haven't already been allocated, then allocate them,\n * and if the arrays are no longer needed, then deallocate them.\n *\n * @this {Debugger8080}\n * @param {boolean} [fQuiet]\n */\n historyInit(fQuiet)\n {\n var i;\n if (!this.checksEnabled()) {\n if (this.aOpcodeHistory && this.aOpcodeHistory.length && !fQuiet) {\n this.println(\"instruction history buffer freed\");\n }\n this.iOpcodeHistory = 0;\n this.aOpcodeHistory = [];\n this.aaOpcodeCounts = [];\n return;\n }\n if (!this.aOpcodeHistory || !this.aOpcodeHistory.length) {\n this.aOpcodeHistory = new Array(Debugger8080.HISTORY_LIMIT);\n for (i = 0; i < this.aOpcodeHistory.length; i++) {\n /*\n * Preallocate dummy Addr (Array) objects in every history slot, so that\n * checkInstruction() doesn't need to call newAddr() on every slot update.\n */\n this.aOpcodeHistory[i] = this.newAddr();\n }\n this.iOpcodeHistory = 0;\n if (!fQuiet) {\n this.println(\"instruction history buffer allocated\");\n }\n }\n if (!this.aaOpcodeCounts || !this.aaOpcodeCounts.length) {\n this.aaOpcodeCounts = new Array(256);\n for (i = 0; i < this.aaOpcodeCounts.length; i++) {\n this.aaOpcodeCounts[i] = [i, 0];\n }\n }\n }\n\n /**\n * runCPU(fUpdateFocus)\n *\n * @this {Debugger8080}\n * @param {boolean} [fUpdateFocus] is true to update focus\n * @return {boolean} true if run request successful, false if not\n */\n runCPU(fUpdateFocus)\n {\n if (!this.isCPUAvail()) return false;\n this.cpu.runCPU(fUpdateFocus);\n return true;\n }\n\n /**\n * stepCPU(nCycles, fRegs, fUpdateCPU)\n *\n * @this {Debugger8080}\n * @param {number} nCycles (0 for one instruction without checking breakpoints)\n * @param {boolean} [fRegs] is true to display registers after step (default is false)\n * @param {boolean} [fUpdateCPU] is false to disable calls to updateCPU() (default is true)\n * @return {boolean}\n */\n stepCPU(nCycles, fRegs, fUpdateCPU)\n {\n if (!this.isCPUAvail()) return false;\n\n this.nCycles = 0;\n\n if (!nCycles) {\n /*\n * When single-stepping, the CPU won't call checkInstruction(), which is good for\n * avoiding breakpoints, but bad for instruction data collection if checks are enabled.\n * So we call checkInstruction() ourselves.\n */\n if (this.checksEnabled()) this.checkInstruction(this.cpu.getPC(), 0);\n }\n try {\n var nCyclesStep = this.cpu.stepCPU(nCycles);\n if (nCyclesStep > 0) {\n this.nCycles += nCyclesStep;\n this.cpu.addCycles(nCyclesStep, true);\n this.cpu.updateChecksum(nCyclesStep);\n this.cOpcodes++;\n }\n }\n catch(exception) {\n if (typeof exception != \"number\") {\n var e = exception;\n this.nCycles = 0;\n this.cpu.setError(e.stack || e.message);\n }\n }\n\n /*\n * Because we called cpu.stepCPU() and not cpu.runCPU(), we must nudge the cpu's update code,\n * and then update our own state. Normally, the only time fUpdateCPU will be false is when doTrace()\n * is calling us in a loop, in which case it will perform its own updateCPU() when it's done.\n */\n if (fUpdateCPU !== false) this.cpu.updateCPU();\n\n this.updateStatus(fRegs || false);\n return (this.nCycles > 0);\n }\n\n /**\n * stopCPU()\n *\n * @this {Debugger8080}\n * @param {boolean} [fComplete]\n */\n stopCPU(fComplete)\n {\n if (this.cpu) this.cpu.stopCPU(fComplete);\n }\n\n /**\n * updateStatus(fRegs)\n *\n * @this {Debugger8080}\n * @param {boolean} [fRegs] (default is true)\n */\n updateStatus(fRegs)\n {\n if (fRegs === undefined) fRegs = true;\n\n this.dbgAddrNextCode = this.newAddr(this.cpu.getPC());\n /*\n * this.nStep used to be a simple boolean, but now it's 0 (or undefined)\n * if inactive, 1 if stepping over an instruction without a register dump, or 2\n * if stepping over an instruction with a register dump.\n */\n if (!fRegs || this.nStep == 1)\n this.doUnassemble();\n else {\n this.doRegisters();\n }\n }\n\n /**\n * isCPUAvail()\n *\n * Make sure the CPU is ready (finished initializing), not busy (already running), and not in an error state.\n *\n * @this {Debugger8080}\n * @return {boolean}\n */\n isCPUAvail()\n {\n if (!this.cpu)\n return false;\n if (!this.cpu.isReady())\n return false;\n if (!this.cpu.isPowered())\n return false;\n if (this.cpu.isBusy())\n return false;\n return !this.cpu.isError();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {Debugger8080}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n /*\n * Because Debugger save/restore support is somewhat limited (and didn't always exist),\n * we deviate from the typical save/restore design pattern: instead of reset OR restore,\n * we always reset and then perform a (potentially limited) restore.\n */\n this.reset(true);\n\n // this.println(data? \"resuming\" : \"powering up\");\n\n if (data && this.restore) {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Debugger8080}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean}\n */\n powerDown(fSave, fShutdown)\n {\n if (fShutdown) this.println(fSave? \"suspending\" : \"shutting down\");\n return fSave? this.save() : true;\n }\n\n /**\n * reset(fQuiet)\n *\n * This is a notification handler, called by the Computer, to inform us of a reset.\n *\n * @this {Debugger8080}\n * @param {boolean} fQuiet (true only when called from our own powerUp handler)\n */\n reset(fQuiet)\n {\n this.historyInit();\n this.cOpcodes = this.cOpcodesStart = 0;\n this.sMessagePrev = null;\n this.nCycles = 0;\n this.dbgAddrNextCode = this.newAddr(this.cpu.getPC());\n /*\n * fRunning is set by start() and cleared by stop(). In addition, we clear\n * it here, so that if the CPU is reset while running, we can prevent stop()\n * from unnecessarily dumping the CPU state.\n */\n this.flags.running = false;\n this.clearTempBreakpoint();\n if (!fQuiet) this.updateStatus();\n }\n\n /**\n * save()\n *\n * This implements (very rudimentary) save support for the Debugger component.\n *\n * @this {Debugger8080}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.packAddr(this.dbgAddrNextCode));\n state.set(1, this.packAddr(this.dbgAddrAssemble));\n state.set(2, [this.aPrevCmds, this.fAssemble, this.bitsMessage]);\n state.set(3, this.aSymbolTable);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements (very rudimentary) restore support for the Debugger component.\n *\n * @this {Debugger8080}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var i = 0;\n if (data[2] !== undefined) {\n this.dbgAddrNextCode = this.unpackAddr(data[i++]);\n this.dbgAddrAssemble = this.unpackAddr(data[i++]);\n this.aPrevCmds = data[i][0];\n if (typeof this.aPrevCmds == \"string\") this.aPrevCmds = [this.aPrevCmds];\n this.fAssemble = data[i][1];\n this.bitsMessage |= data[i][2]; // keep our current message bits set, and simply \"add\" any extra bits defined by the saved state\n }\n if (data[3]) this.aSymbolTable = data[3];\n return true;\n }\n\n /**\n * start(ms, nCycles)\n *\n * This is a notification handler, called by the Computer, to inform us the CPU has started.\n *\n * @this {Debugger8080}\n * @param {number} ms\n * @param {number} nCycles\n */\n start(ms, nCycles)\n {\n if (!this.nStep) this.println(\"running\");\n this.flags.running = true;\n this.msStart = ms;\n this.nCyclesStart = nCycles;\n }\n\n /**\n * stop(ms, nCycles)\n *\n * This is a notification handler, called by the Computer, to inform us the CPU has now stopped.\n *\n * @this {Debugger8080}\n * @param {number} ms\n * @param {number} nCycles\n */\n stop(ms, nCycles)\n {\n if (this.flags.running) {\n this.flags.running = false;\n this.nCycles = nCycles - this.nCyclesStart;\n if (!this.nStep) {\n var sStopped = \"stopped\";\n if (this.nCycles) {\n var msTotal = ms - this.msStart;\n var nCyclesPerSecond = (msTotal > 0? Math.round(this.nCycles * 1000 / msTotal) : 0);\n sStopped += \" (\";\n if (this.checksEnabled()) {\n sStopped += this.cOpcodes + \" opcodes, \";\n /*\n * $ops displays progress by calculating cOpcodes - cOpcodesStart, so before\n * zeroing cOpcodes, we should subtract cOpcodes from cOpcodesStart (since we're\n * effectively subtracting cOpcodes from cOpcodes as well).\n */\n this.cOpcodesStart -= this.cOpcodes;\n this.cOpcodes = 0;\n }\n sStopped += this.nCycles + \" cycles, \" + msTotal + \" ms, \" + nCyclesPerSecond + \" hz)\";\n } else {\n if (this.messageEnabled(Messages8080.HALT)) {\n /*\n * It's possible the user is trying to 'g' past a fault that was blocked by helpCheckFault()\n * for the Debugger's benefit; if so, it will continue to be blocked, so try displaying a helpful\n * message (another helpful tip would be to simply turn off the \"halt\" message category).\n */\n sStopped += \" (use the 't' command to execute blocked faults)\";\n }\n }\n this.println(sStopped);\n }\n this.updateStatus(true);\n this.updateFocus();\n this.clearTempBreakpoint(this.cpu.getPC());\n }\n }\n\n /**\n * checksEnabled(fRelease)\n *\n * This \"check\" function is called by the CPU; we indicate whether or not every instruction needs to be checked.\n *\n * Originally, this returned true even when there were only read and/or write breakpoints, but those breakpoints\n * no longer require the intervention of checkInstruction(); the Bus component automatically swaps in/out appropriate\n * \"checked\" Memory access functions to deal with those breakpoints in the corresponding Memory blocks. So I've\n * simplified the test below.\n *\n * @this {Debugger8080}\n * @param {boolean} [fRelease] is true for release criteria only; default is false (any criteria)\n * @return {boolean} true if every instruction needs to pass through checkInstruction(), false if not\n */\n checksEnabled(fRelease)\n {\n return ((DEBUG && !fRelease)? true : (this.aBreakExec.length > 1 || !!this.nBreakIns));\n }\n\n /**\n * checkInstruction(addr, nState)\n *\n * This \"check\" function is called by the CPU to inform us about the next instruction to be executed,\n * giving us an opportunity to look for \"exec\" breakpoints and update opcode frequencies and instruction history.\n *\n * @this {Debugger8080}\n * @param {number} addr\n * @param {number} nState is < 0 if stepping, 0 if starting, or > 0 if running\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkInstruction(addr, nState)\n {\n var cpu = this.cpu;\n\n if (nState > 0) {\n if (this.nBreakIns && !--this.nBreakIns) {\n return true;\n }\n if (this.checkBreakpoint(addr, 1, this.aBreakExec)) {\n return true;\n }\n }\n\n /*\n * The rest of the instruction tracking logic can only be performed if historyInit() has allocated the\n * necessary data structures. Note that there is no explicit UI for enabling/disabling history, other than\n * adding/removing breakpoints, simply because it's breakpoints that trigger the call to checkInstruction();\n * well, OK, and a few other things now, like enabling Messages8080.INT messages.\n */\n if (nState >= 0 && this.aaOpcodeCounts.length) {\n this.cOpcodes++;\n var bOpcode = this.bus.getByteDirect(addr);\n if (bOpcode != null) {\n this.aaOpcodeCounts[bOpcode][1]++;\n var dbgAddr = this.aOpcodeHistory[this.iOpcodeHistory];\n this.setAddr(dbgAddr, cpu.getPC());\n if (DEBUG) dbgAddr.cycleCount = cpu.getCycles();\n if (++this.iOpcodeHistory == this.aOpcodeHistory.length) this.iOpcodeHistory = 0;\n }\n }\n return false;\n }\n\n /**\n * checkMemoryRead(addr, nb)\n *\n * This \"check\" function is called by a Memory block to inform us that a memory read occurred, giving us an\n * opportunity to track the read if we want, and look for a matching \"read\" breakpoint, if any.\n *\n * In the \"old days\", it would be an error for this call to fail to find a matching Debugger breakpoint, but now\n * Memory blocks have no idea whether the Debugger or the machine's Debug register(s) triggered this \"checked\" read.\n *\n * If we return true, we \"trump\" the machine's Debug register(s); false allows normal Debug register processing.\n *\n * @this {Debugger8080}\n * @param {number} addr\n * @param {number} [nb] (# of bytes; default is 1)\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkMemoryRead(addr, nb)\n {\n if (this.checkBreakpoint(addr, nb || 1, this.aBreakRead)) {\n this.stopCPU(true);\n return true;\n }\n return false;\n }\n\n /**\n * checkMemoryWrite(addr, nb)\n *\n * This \"check\" function is called by a Memory block to inform us that a memory write occurred, giving us an\n * opportunity to track the write if we want, and look for a matching \"write\" breakpoint, if any.\n *\n * In the \"old days\", it would be an error for this call to fail to find a matching Debugger breakpoint, but now\n * Memory blocks have no idea whether the Debugger or the machine's Debug register(s) triggered this \"checked\" write.\n *\n * If we return true, we \"trump\" the machine's Debug register(s); false allows normal Debug register processing.\n *\n * @this {Debugger8080}\n * @param {number} addr\n * @param {number} [nb] (# of bytes; default is 1)\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkMemoryWrite(addr, nb)\n {\n if (this.checkBreakpoint(addr, nb || 1, this.aBreakWrite)) {\n this.stopCPU(true);\n return true;\n }\n return false;\n }\n\n /**\n * checkPortInput(port, size, data)\n *\n * This \"check\" function is called by the Bus component to inform us that port input occurred.\n *\n * @this {Debugger8080}\n * @param {number} port\n * @param {number} size\n * @param {number} data\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkPortInput(port, size, data)\n {\n /*\n * We trust that the Bus component won't call us unless we told it to, so we halt unconditionally\n */\n this.println(\"break on input from port \" + Str.toHexWord(port) + \": \" + Str.toHex(data));\n this.stopCPU(true);\n return true;\n }\n\n /**\n * checkPortOutput(port, size, data)\n *\n * This \"check\" function is called by the Bus component to inform us that port output occurred.\n *\n * @this {Debugger8080}\n * @param {number} port\n * @param {number} size\n * @param {number} data\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkPortOutput(port, size, data)\n {\n /*\n * We trust that the Bus component won't call us unless we told it to, so we halt unconditionally\n */\n this.println(\"break on output to port \" + Str.toHexWord(port) + \": \" + Str.toHex(data));\n this.stopCPU(true);\n return true;\n }\n\n /**\n * clearBreakpoints()\n *\n * @this {Debugger8080}\n */\n clearBreakpoints()\n {\n var i, dbgAddr;\n this.aBreakExec = [\"bp\"];\n if (this.aBreakRead !== undefined) {\n for (i = 1; i < this.aBreakRead.length; i++) {\n dbgAddr = this.aBreakRead[i];\n this.bus.removeMemBreak(this.getAddr(dbgAddr), false);\n }\n }\n this.aBreakRead = [\"br\"];\n if (this.aBreakWrite !== undefined) {\n for (i = 1; i < this.aBreakWrite.length; i++) {\n dbgAddr = this.aBreakWrite[i];\n this.bus.removeMemBreak(this.getAddr(dbgAddr), true);\n }\n }\n this.aBreakWrite = [\"bw\"];\n /*\n * nSuppressBreaks ensures we can't get into an infinite loop where a breakpoint lookup requires\n * reading a segment descriptor via getSegment(), and that triggers more memory reads, which triggers\n * more breakpoint checks.\n */\n this.nSuppressBreaks = 0;\n }\n\n /**\n * addBreakpoint(aBreak, dbgAddr, fTemporary)\n *\n * In case you haven't already figured this out, all our breakpoint commands use the address\n * to identify a breakpoint, not an incrementally assigned breakpoint index like other debuggers;\n * see doBreak() for details.\n *\n * This has a few implications, one being that you CANNOT set more than one kind of breakpoint\n * on a single address. In practice, that's rarely a problem, because you can almost always set\n * a different breakpoint on a neighboring address.\n *\n * Also, there is one exception to the \"one address, one breakpoint\" rule, and that involves\n * temporary breakpoints (ie, one-time execution breakpoints that either a \"p\" or \"g\" command\n * may create to step over a chunk of code). Those breakpoints automatically clear themselves,\n * so there usually isn't any need to refer to them using breakpoint commands.\n *\n * TODO: Consider supporting the more \"traditional\" breakpoint index syntax; the current\n * address-based syntax was implemented solely for expediency and consistency. At the same time,\n * also consider a more WDEB386-like syntax, where \"br\" is used to set a variety of access-specific\n * breakpoints, using modifiers like \"r1\", \"r2\", \"w1\", \"w2, etc.\n *\n * @this {Debugger8080}\n * @param {Array} aBreak\n * @param {DbgAddr8080} dbgAddr\n * @param {boolean} [fTemporary]\n * @return {boolean} true if breakpoint added, false if already exists\n */\n addBreakpoint(aBreak, dbgAddr, fTemporary)\n {\n var fSuccess = true;\n\n // this.nSuppressBreaks++;\n\n /*\n * Instead of complaining that a breakpoint already exists (as we used to do), we now\n * allow breakpoints to be re-set; this makes it easier to update any commands that may\n * be associated with the breakpoint.\n *\n * The only exception: we DO allow a temporary breakpoint at an address where there may\n * already be a breakpoint, so that you can easily step (\"p\" or \"g\") over such addresses.\n */\n if (!fTemporary) {\n this.findBreakpoint(aBreak, dbgAddr, true, false, true);\n }\n\n if (aBreak != this.aBreakExec) {\n var addr = this.getAddr(dbgAddr);\n if (addr === CPUDef8080.ADDR_INVALID) {\n this.println(\"invalid address: \" + this.toHexAddr(dbgAddr));\n fSuccess = false;\n } else {\n this.bus.addMemBreak(addr, aBreak == this.aBreakWrite);\n }\n }\n\n if (fSuccess) {\n aBreak.push(dbgAddr);\n if (fTemporary) {\n dbgAddr.fTemporary = true;\n }\n else {\n this.printBreakpoint(aBreak, aBreak.length-1, \"set\");\n this.historyInit();\n }\n }\n\n // this.nSuppressBreaks--;\n\n return fSuccess;\n }\n\n /**\n * findBreakpoint(aBreak, dbgAddr, fRemove, fTemporary, fQuiet)\n *\n * @this {Debugger8080}\n * @param {Array} aBreak\n * @param {DbgAddr8080} dbgAddr\n * @param {boolean} [fRemove]\n * @param {boolean} [fTemporary]\n * @param {boolean} [fQuiet]\n * @return {boolean} true if found, false if not\n */\n findBreakpoint(aBreak, dbgAddr, fRemove, fTemporary, fQuiet)\n {\n var fFound = false;\n var addr = this.getAddr(dbgAddr);\n for (var i = 1; i < aBreak.length; i++) {\n var dbgAddrBreak = aBreak[i];\n if (addr == this.getAddr(dbgAddrBreak)) {\n if (!fTemporary || dbgAddrBreak.fTemporary) {\n fFound = true;\n if (fRemove) {\n if (!dbgAddrBreak.fTemporary && !fQuiet) {\n this.printBreakpoint(aBreak, i, \"cleared\");\n }\n aBreak.splice(i, 1);\n if (aBreak != this.aBreakExec) {\n this.bus.removeMemBreak(addr, aBreak == this.aBreakWrite);\n }\n /*\n * We'll mirror the logic in addBreakpoint() and leave the history buffer alone if this\n * was a temporary breakpoint.\n */\n if (!dbgAddrBreak.fTemporary) {\n this.historyInit();\n }\n break;\n }\n if (!fQuiet) this.printBreakpoint(aBreak, i, \"exists\");\n break;\n }\n }\n }\n return fFound;\n }\n\n /**\n * listBreakpoints(aBreak)\n *\n * @this {Debugger8080}\n * @param {Array} aBreak\n * @return {number} of breakpoints listed, 0 if none\n */\n listBreakpoints(aBreak)\n {\n for (var i = 1; i < aBreak.length; i++) {\n this.printBreakpoint(aBreak, i);\n }\n return aBreak.length - 1;\n }\n\n /**\n * printBreakpoint(aBreak, i, sAction)\n *\n * @this {Debugger8080}\n * @param {Array} aBreak\n * @param {number} i\n * @param {string} [sAction]\n */\n printBreakpoint(aBreak, i, sAction)\n {\n var dbgAddr = aBreak[i];\n this.println(aBreak[0] + ' ' + this.toHexAddr(dbgAddr) + (sAction? (' ' + sAction) : (dbgAddr.sCmd? (' \"' + dbgAddr.sCmd + '\"') : '')));\n }\n\n /**\n * setTempBreakpoint(dbgAddr)\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr of new temp breakpoint\n */\n setTempBreakpoint(dbgAddr)\n {\n this.addBreakpoint(this.aBreakExec, dbgAddr, true);\n }\n\n /**\n * clearTempBreakpoint(addr)\n *\n * @this {Debugger8080}\n * @param {number|undefined} [addr] clear all temp breakpoints if no address specified\n */\n clearTempBreakpoint(addr)\n {\n if (addr !== undefined) {\n this.checkBreakpoint(addr, 1, this.aBreakExec, true);\n this.nStep = 0;\n } else {\n for (var i = 1; i < this.aBreakExec.length; i++) {\n var dbgAddrBreak = this.aBreakExec[i];\n if (dbgAddrBreak.fTemporary) {\n if (!this.findBreakpoint(this.aBreakExec, dbgAddrBreak, true, true)) break;\n i = 0;\n }\n }\n }\n }\n\n /**\n * checkBreakpoint(addr, nb, aBreak, fTemporary)\n *\n * @this {Debugger8080}\n * @param {number} addr\n * @param {number} nb (# of bytes)\n * @param {Array} aBreak\n * @param {boolean} [fTemporary]\n * @return {boolean} true if breakpoint has been hit, false if not\n */\n checkBreakpoint(addr, nb, aBreak, fTemporary)\n {\n /*\n * Time to check for execution breakpoints; note that this should be done BEFORE updating frequency\n * or history data (see checkInstruction), since we might not actually execute the current instruction.\n */\n var fBreak = false;\n\n if (!this.nSuppressBreaks++) {\n\n for (var i = 1; !fBreak && i < aBreak.length; i++) {\n\n var dbgAddrBreak = aBreak[i];\n\n if (fTemporary && !dbgAddrBreak.fTemporary) continue;\n\n /*\n * We used to calculate the linear address of the breakpoint at the time the\n * breakpoint was added, so that a breakpoint set in one mode (eg, in real-mode)\n * would still work as intended if the mode changed later (eg, to protected-mode).\n *\n * However, that created difficulties setting protected-mode breakpoints in segments\n * that might not be defined yet, or that could move in physical memory.\n *\n * If you want to create a real-mode breakpoint that will break regardless of mode,\n * use the physical address of the real-mode memory location instead.\n */\n var addrBreak = this.getAddr(dbgAddrBreak);\n for (var n = 0; n < nb; n++) {\n if (addr + n == addrBreak) {\n var a;\n fBreak = true;\n if (dbgAddrBreak.fTemporary) {\n this.findBreakpoint(aBreak, dbgAddrBreak, true, true);\n fTemporary = true;\n }\n if (a = dbgAddrBreak.aCmds) {\n /*\n * When one or more commands are attached to a breakpoint, we don't halt by default.\n * Instead, we set fBreak to true only if, at the completion of all the commands, the\n * CPU is halted; in other words, you should include \"h\" as one of the breakpoint commands\n * if you want the breakpoint to stop execution.\n *\n * Another useful command is \"if\", which will return false if the expression is false,\n * at which point we'll jump ahead to the next \"else\" command, and if there isn't an \"else\",\n * we abort.\n */\n fBreak = false;\n for (var j = 0; j < a.length; j++) {\n if (!this.doCommand(a[j], true)) {\n if (a[j].indexOf(\"if\")) {\n fBreak = true; // the failed command wasn't \"if\", so abort\n break;\n }\n var k = j + 1;\n for (; k < a.length; k++) {\n if (!a[k].indexOf(\"else\")) break;\n j++;\n }\n if (k == a.length) { // couldn't find an \"else\" after the \"if\", so abort\n fBreak = true;\n break;\n }\n /*\n * If we're still here, we'll execute the \"else\" command (which is just a no-op),\n * followed by any remaining commands.\n */\n }\n }\n if (!this.cpu.isRunning()) fBreak = true;\n }\n if (fBreak) {\n if (!fTemporary) this.printBreakpoint(aBreak, i, \"hit\");\n break;\n }\n }\n }\n }\n }\n\n this.nSuppressBreaks--;\n\n return fBreak;\n }\n\n /**\n * getInstruction(dbgAddr, sComment, nSequence)\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {string} [sComment] is an associated comment\n * @param {number|null} [nSequence] is an associated sequence number, undefined if none\n * @return {string} (and dbgAddr is updated to the next instruction)\n */\n getInstruction(dbgAddr, sComment, nSequence)\n {\n var dbgAddrIns = this.newAddr(dbgAddr.addr);\n\n var bOpcode = this.getByte(dbgAddr, 1);\n\n var asOpcodes = this.style != Debugger8080.STYLE_8086? Debugger8080.INS_NAMES : Debugger8080.INS_NAMES_8086;\n var aOpDesc = this.aaOpDescs[bOpcode];\n var iIns = aOpDesc[0];\n\n var sOperands = \"\";\n var sOpcode = asOpcodes[iIns];\n var cOperands = aOpDesc.length - 1;\n var typeSizeDefault = Debugger8080.TYPE_NONE, type;\n\n for (var iOperand = 1; iOperand <= cOperands; iOperand++) {\n\n var disp, off, cch;\n var sOperand = \"\";\n\n type = aOpDesc[iOperand];\n if (type === undefined) continue;\n if ((type & Debugger8080.TYPE_OPT) && this.style == Debugger8080.STYLE_8080) continue;\n\n var typeMode = type & Debugger8080.TYPE_MODE;\n if (!typeMode) continue;\n\n var typeSize = type & Debugger8080.TYPE_SIZE;\n if (!typeSize) {\n type |= typeSizeDefault;\n } else {\n typeSizeDefault = typeSize;\n }\n\n var typeOther = type & Debugger8080.TYPE_OTHER;\n if (!typeOther) {\n type |= (iOperand == 1? Debugger8080.TYPE_OUT : Debugger8080.TYPE_IN);\n }\n\n if (typeMode & Debugger8080.TYPE_IMM) {\n sOperand = this.getImmOperand(type, dbgAddr);\n }\n else if (typeMode & Debugger8080.TYPE_REG) {\n sOperand = this.getRegOperand((type & Debugger8080.TYPE_IREG) >> 8, type, dbgAddr);\n }\n else if (typeMode & Debugger8080.TYPE_INT) {\n sOperand = ((bOpcode >> 3) & 0x7).toString();\n }\n\n if (!sOperand || !sOperand.length) {\n sOperands = \"INVALID\";\n break;\n }\n if (sOperands.length > 0) sOperands += ',';\n sOperands += (sOperand || \"???\");\n }\n\n var sBytes = \"\";\n var sLine = this.toHexAddr(dbgAddrIns) + ' ';\n if (dbgAddrIns.addr !== CPUDef8080.ADDR_INVALID && dbgAddr.addr !== CPUDef8080.ADDR_INVALID) {\n do {\n sBytes += Str.toHex(this.getByte(dbgAddrIns, 1), 2);\n if (dbgAddrIns.addr == null) break;\n } while (dbgAddrIns.addr != dbgAddr.addr);\n }\n\n sLine += Str.pad(sBytes, 10);\n sLine += (type & Debugger8080.TYPE_UNDOC)? '*' : ' ';\n sLine += Str.pad(sOpcode, 7);\n if (sOperands) sLine += ' ' + sOperands;\n\n if (sComment) {\n sLine = Str.pad(sLine, 40) + ';' + sComment;\n if (!this.cpu.flags.checksum) {\n sLine += (nSequence != null? '=' + nSequence.toString() : \"\");\n } else {\n var nCycles = this.cpu.getCycles();\n sLine += \"cycles=\" + nCycles.toString() + \" cs=\" + Str.toHex(this.cpu.nChecksum);\n }\n }\n return sLine;\n }\n\n /**\n * getImmOperand(type, dbgAddr)\n *\n * @this {Debugger8080}\n * @param {number} type\n * @param {DbgAddr8080} dbgAddr\n * @return {string} operand\n */\n getImmOperand(type, dbgAddr)\n {\n var sOperand = ' ';\n var typeSize = type & Debugger8080.TYPE_SIZE;\n\n switch (typeSize) {\n case Debugger8080.TYPE_BYTE:\n sOperand = Str.toHex(this.getByte(dbgAddr, 1), 2);\n break;\n case Debugger8080.TYPE_SBYTE:\n sOperand = Str.toHex((this.getByte(dbgAddr, 1) << 24) >> 24, 4);\n break;\n case Debugger8080.TYPE_WORD:\n sOperand = Str.toHex(this.getShort(dbgAddr, 2), 4);\n break;\n default:\n return \"imm(\" + Str.toHexWord(type) + ')';\n }\n if (this.style == Debugger8080.STYLE_8086 && (type & Debugger8080.TYPE_MEM)) {\n sOperand = '[' + sOperand + ']';\n } else if (!(type & Debugger8080.TYPE_REG)) {\n sOperand = (this.style == Debugger8080.STYLE_8080? '$' : \"0x\") + sOperand;\n }\n return sOperand;\n }\n\n /**\n * getRegOperand(iReg, type, dbgAddr)\n *\n * @this {Debugger8080}\n * @param {number} iReg\n * @param {number} type\n * @param {DbgAddr8080} dbgAddr\n * @return {string} operand\n */\n getRegOperand(iReg, type, dbgAddr)\n {\n /*\n * Although this breaks with 8080 assembler conventions, I'm going to experiment with some different\n * mnemonics; specifically, \"[HL]\" instead of \"M\". This is also more in keeping with how getImmOperand()\n * displays memory references (ie, by enclosing them in brackets).\n */\n var sOperand = Debugger8080.REGS[iReg];\n if (this.style == Debugger8080.STYLE_8086 && (type & Debugger8080.TYPE_MEM)) {\n if (iReg == Debugger8080.REG_M) {\n sOperand = \"HL\";\n }\n sOperand = '[' + sOperand + ']';\n }\n return sOperand;\n }\n\n /**\n * parseInstruction(sOp, sOperand, addr)\n *\n * TODO: Unimplemented. See parseInstruction() in modules/c1pjs/lib/debugger.js for a working implementation.\n *\n * @this {Debugger8080}\n * @param {string} sOp\n * @param {string|undefined} sOperand\n * @param {DbgAddr8080} dbgAddr of memory where this instruction is being assembled\n * @return {Array.<number>} of opcode bytes; if the instruction can't be parsed, the array will be empty\n */\n parseInstruction(sOp, sOperand, dbgAddr)\n {\n var aOpBytes = [];\n this.println(\"not supported yet\");\n return aOpBytes;\n }\n\n /**\n * getFlagOutput(sFlag)\n *\n * @this {Debugger8080}\n * @param {string} sFlag\n * @return {string} value of flag\n */\n getFlagOutput(sFlag)\n {\n var b;\n switch (sFlag) {\n case \"IF\":\n b = this.cpu.getIF();\n break;\n case \"SF\":\n b = this.cpu.getSF();\n break;\n case \"ZF\":\n b = this.cpu.getZF();\n break;\n case \"AF\":\n b = this.cpu.getAF();\n break;\n case \"PF\":\n b = this.cpu.getPF();\n break;\n case \"CF\":\n b = this.cpu.getCF();\n break;\n default:\n b = 0;\n break;\n }\n return sFlag.charAt(0) + (b? '1' : '0') + ' ';\n }\n\n /**\n * getRegOutput(iReg)\n *\n * @this {Debugger8080}\n * @param {number} iReg\n * @return {string}\n */\n getRegOutput(iReg)\n {\n var sReg = Debugger8080.REGS[iReg];\n return sReg + '=' + this.getRegString(iReg) + ' ';\n }\n\n /**\n * getRegDump()\n *\n * Sample 8080 register dump:\n *\n * A=00 BC=0000 DE=0000 HL=0000 SP=0000 I0 S0 Z0 A0 P0 C0\n * 0000 00 NOP\n *\n * @this {Debugger8080}\n * @return {string}\n */\n getRegDump()\n {\n var s;\n s = this.getRegOutput(Debugger8080.REG_A) +\n this.getRegOutput(Debugger8080.REG_BC) +\n this.getRegOutput(Debugger8080.REG_DE) +\n this.getRegOutput(Debugger8080.REG_HL) +\n this.getRegOutput(Debugger8080.REG_SP) +\n this.getFlagOutput(\"IF\") + this.getFlagOutput(\"SF\") + this.getFlagOutput(\"ZF\") +\n this.getFlagOutput(\"AF\") + this.getFlagOutput(\"PF\") + this.getFlagOutput(\"CF\");\n return s;\n }\n\n /**\n * comparePairs(p1, p2)\n *\n * @this {Debugger8080}\n * @param {number|string|Array|Object} p1\n * @param {number|string|Array|Object} p2\n * @return {number}\n */\n comparePairs(p1, p2)\n {\n return p1[0] > p2[0]? 1 : p1[0] < p2[0]? -1 : 0;\n }\n\n /**\n * addSymbols(sModule, addr, len, aSymbols)\n *\n * As filedump.js (formerly convrom.php) explains, aSymbols is a JSON-encoded object whose properties consist\n * of all the symbols (in upper-case), and the values of those properties are objects containing any or all of\n * the following properties:\n *\n * 'v': the value of an absolute (unsized) value\n * 'b': either 1, 2, 4 or undefined if an unsized value\n * 's': either a hard-coded segment or undefined\n * 'o': the offset of the symbol within the associated address space\n * 'l': the original-case version of the symbol, present only if it wasn't originally upper-case\n * 'a': annotation for the specified offset; eg, the original assembly language, with optional comment\n *\n * To that list of properties, we also add:\n *\n * 'p': the physical address (calculated whenever both 's' and 'o' properties are defined)\n *\n * Note that values for any 'v', 'b', 's' and 'o' properties are unquoted decimal values, and the values\n * for any 'l' or 'a' properties are quoted strings. Also, if double-quotes were used in any of the original\n * annotation ('a') values, they will have been converted to two single-quotes, so we're responsible for\n * converting them back to individual double-quotes.\n *\n * For example:\n * {\n * 'HF_PORT': {\n * 'v':800\n * },\n * 'HDISK_INT': {\n * 'b':4, 's':0, 'o':52\n * },\n * 'ORG_VECTOR': {\n * 'b':4, 's':0, 'o':76\n * },\n * 'CMD_BLOCK': {\n * 'b':1, 's':64, 'o':66\n * },\n * 'DISK_SETUP': {\n * 'o':3\n * },\n * '.40': {\n * 'o':40, 'a':\"MOV AX,WORD PTR ORG_VECTOR ;GET DISKETTE VECTOR\"\n * }\n * }\n *\n * If a symbol only has an offset, then that offset value can be assigned to the symbol property directly:\n *\n * 'DISK_SETUP': 3\n *\n * The last property is an example of an \"anonymous\" entry, for offsets where there is no associated symbol.\n * Such entries are identified by a period followed by a unique number (usually the offset of the entry), and\n * they usually only contain offset ('o') and annotation ('a') properties. I could eliminate the leading\n * period, but it offers a very convenient way of quickly discriminating among genuine vs. anonymous symbols.\n *\n * We add all these entries to our internal symbol table, which is an array of 4-element arrays, each of which\n * look like:\n *\n * [addr, len, aSymbols, aOffsets]\n *\n * There are two basic symbol operations: findSymbol(), which takes an address and finds the symbol, if any,\n * at that address, and findSymbolAddr(), which takes a string and attempts to match it to a non-anonymous\n * symbol with a matching offset ('o') property.\n *\n * To implement findSymbol() efficiently, addSymbols() creates an array of [offset, sSymbol] pairs\n * (aOffsets), one pair for each symbol that corresponds to an offset within the specified address space.\n *\n * We guarantee the elements of aOffsets are in offset order, because we build it using binaryInsert();\n * it's quite likely that the MAP file already ordered all its symbols in offset order, but since they're\n * hand-edited files, we can't assume that, and we need to ensure that findSymbol()'s binarySearch() operates\n * properly.\n *\n * @this {Debugger8080}\n * @param {string|null} sModule\n * @param {number|null} addr (physical address where the symbols are located, if the memory is physical; eg, ROM)\n * @param {number} len (the size of the region, in bytes)\n * @param {Object} aSymbols (collection of symbols in this group; the format of this collection is described below)\n */\n addSymbols(sModule, addr, len, aSymbols)\n {\n var dbgAddr = {};\n var aOffsets = [];\n for (var sSymbol in aSymbols) {\n var symbol = aSymbols[sSymbol];\n if (typeof symbol == \"number\") {\n aSymbols[sSymbol] = symbol = {'o': symbol};\n }\n var offSymbol = symbol['o'];\n var sAnnotation = symbol['a'];\n if (offSymbol !== undefined) {\n Usr.binaryInsert(aOffsets, [offSymbol >>> 0, sSymbol], this.comparePairs);\n }\n if (sAnnotation) symbol['a'] = sAnnotation.replace(/''/g, \"\\\"\");\n }\n var symbolTable = {\n sModule: sModule,\n addr: addr,\n len: len,\n aSymbols: aSymbols,\n aOffsets: aOffsets\n };\n this.aSymbolTable.push(symbolTable);\n }\n\n /**\n * dumpSymbols()\n *\n * TODO: Add \"numerical\" and \"alphabetical\" dump options. This is simply dumping them in whatever\n * order they appeared in the original MAP file.\n *\n * @this {Debugger8080}\n */\n dumpSymbols()\n {\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n for (var sSymbol in symbolTable.aSymbols) {\n if (sSymbol.charAt(0) == '.') continue;\n var symbol = symbolTable.aSymbols[sSymbol];\n var offSymbol = symbol['o'];\n if (offSymbol === undefined) continue;\n var sSymbolOrig = symbolTable.aSymbols[sSymbol]['l'];\n if (sSymbolOrig) sSymbol = sSymbolOrig;\n this.println(this.toHexOffset(offSymbol) + ' ' + sSymbol);\n }\n }\n }\n\n /**\n * findSymbol(dbgAddr, fNearest)\n *\n * Search aSymbolTable for dbgAddr, and return an Array for the corresponding symbol (empty if not found).\n *\n * If fNearest is true, and no exact match was found, then the Array returned will contain TWO sets of\n * entries: [0]-[3] will refer to closest preceding symbol, and [4]-[7] will refer to the closest subsequent symbol.\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @param {boolean} [fNearest]\n * @return {Array} where [0] == symbol name, [1] == symbol value, [2] == any annotation, and [3] == any associated comment\n */\n findSymbol(dbgAddr, fNearest)\n {\n var aSymbol = [];\n var addrSymbol = this.getAddr(dbgAddr) >>> 0;\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n var addr = symbolTable.addr >>> 0;\n var len = symbolTable.len;\n if (addrSymbol >= addr && addrSymbol < addr + len) {\n var offSymbol = addrSymbol - addr;\n var result = Usr.binarySearch(symbolTable.aOffsets, [offSymbol], this.comparePairs);\n if (result >= 0) {\n this.returnSymbol(iTable, result, aSymbol);\n }\n else if (fNearest) {\n result = ~result;\n this.returnSymbol(iTable, result-1, aSymbol);\n this.returnSymbol(iTable, result, aSymbol);\n }\n break;\n }\n }\n return aSymbol;\n }\n\n /**\n * findSymbolAddr(sSymbol)\n *\n * Search aSymbolTable for sSymbol, and if found, return a dbgAddr (same as parseAddr())\n *\n * @this {Debugger8080}\n * @param {string} sSymbol\n * @return {DbgAddr8080|undefined}\n */\n findSymbolAddr(sSymbol)\n {\n var dbgAddr;\n if (sSymbol.match(/^[a-z_][a-z0-9_]*$/i)) {\n var sUpperCase = sSymbol.toUpperCase();\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n var symbol = symbolTable.aSymbols[sUpperCase];\n if (symbol !== undefined) {\n var offSymbol = symbol['o'];\n if (offSymbol !== undefined) {\n /*\n * We assume that every ROM is ORG'ed at 0x0000, and therefore unless the symbol has an\n * explicitly-defined segment, we return the segment associated with the entire group; for\n * a ROM, that segment is normally \"addrROM >>> 4\". Down the road, we may want/need to\n * support a special symbol entry (eg, \".ORG\") that defines an alternate origin.\n */\n dbgAddr = this.newAddr(offSymbol);\n }\n /*\n * The symbol matched, but it wasn't for an address (no 'o' offset), and there's no point\n * looking any farther, since each symbol appears only once, so we indicate it's an unknown symbol.\n */\n break;\n }\n }\n }\n return dbgAddr;\n }\n\n /**\n * returnSymbol(iTable, iOffset, aSymbol)\n *\n * Helper function for findSymbol().\n *\n * @param {number} iTable\n * @param {number} iOffset\n * @param {Array} aSymbol is updated with the specified symbol, if it exists\n */\n returnSymbol(iTable, iOffset, aSymbol)\n {\n var symbol = {};\n var aOffsets = this.aSymbolTable[iTable].aOffsets;\n var offset = 0, sSymbol = null;\n if (iOffset >= 0 && iOffset < aOffsets.length) {\n offset = aOffsets[iOffset][0];\n sSymbol = aOffsets[iOffset][1];\n }\n if (sSymbol) {\n symbol = this.aSymbolTable[iTable].aSymbols[sSymbol];\n sSymbol = (sSymbol.charAt(0) == '.'? null : (symbol['l'] || sSymbol));\n }\n aSymbol.push(sSymbol);\n aSymbol.push(offset);\n aSymbol.push(symbol['a']);\n aSymbol.push(symbol['c']);\n }\n\n /**\n * doHelp()\n *\n * @this {Debugger8080}\n */\n doHelp()\n {\n var s = \"commands:\";\n for (var sCommand in Debugger8080.COMMANDS) {\n s += '\\n' + Str.pad(sCommand, 9) + Debugger8080.COMMANDS[sCommand];\n }\n if (!this.checksEnabled()) s += \"\\nnote: frequency/history disabled if no exec breakpoints\";\n this.println(s);\n }\n\n /**\n * doAssemble(asArgs)\n *\n * This always receives the complete argument array, where the order of the arguments is:\n *\n * [0]: the assemble command (assumed to be \"a\")\n * [1]: the target address (eg, \"200\")\n * [2]: the operation code, aka instruction name (eg, \"adc\")\n * [3]: the operation mode operand, if any (eg, \"14\", \"[1234]\", etc)\n *\n * The Debugger enters \"assemble mode\" whenever only the first (or first and second) arguments are present.\n * As long as \"assemble mode is active, the user can omit the first two arguments on all later assemble commands\n * until \"assemble mode\" is cancelled with an empty command line; the command processor automatically prepends \"a\"\n * and the next available target address to the argument array.\n *\n * Entering \"assemble mode\" is optional; one could enter a series of fully-qualified assemble commands; eg:\n *\n * a ff00 cld\n * a ff01 ldx 28\n * ...\n *\n * without ever entering \"assemble mode\", but of course, that requires more typing and doesn't take advantage\n * of automatic target address advancement (see dbgAddrAssemble).\n *\n * NOTE: As the previous example implies, you can even assemble new instructions into ROM address space;\n * as our setByte() function explains, the ROM write-notification handlers only refuse writes from the CPU.\n *\n * @this {Debugger8080}\n * @param {Array.<string>} asArgs is the complete argument array, beginning with the \"a\" command in asArgs[0]\n */\n doAssemble(asArgs)\n {\n var dbgAddr = this.parseAddr(asArgs[1], true);\n if (!dbgAddr) return;\n\n this.dbgAddrAssemble = dbgAddr;\n if (asArgs[2] === undefined) {\n this.println(\"begin assemble at \" + this.toHexAddr(dbgAddr));\n this.fAssemble = true;\n this.cpu.updateCPU();\n return;\n }\n\n var aOpBytes = this.parseInstruction(asArgs[2], asArgs[3], dbgAddr);\n if (aOpBytes.length) {\n for (var i = 0; i < aOpBytes.length; i++) {\n this.setByte(dbgAddr, aOpBytes[i], 1);\n }\n /*\n * Since getInstruction() also updates the specified address, dbgAddrAssemble is automatically advanced.\n */\n this.println(this.getInstruction(this.dbgAddrAssemble));\n }\n }\n\n /**\n * doBreak(sCmd, sAddr, sOptions)\n *\n * As the \"help\" output below indicates, the following breakpoint commands are supported:\n *\n * bp [a] set exec breakpoint on linear addr [a]\n * br [a] set read breakpoint on linear addr [a]\n * bw [a] set write breakpoint on linear addr [a]\n * bc [a] clear breakpoint on linear addr [a] (use \"*\" for all breakpoints)\n * bl list breakpoints\n *\n * to which we have recently added the following I/O breakpoint commands:\n *\n * bi [p] toggle input breakpoint on port [p] (use \"*\" for all input ports)\n * bo [p] toggle output breakpoint on port [p] (use \"*\" for all output ports)\n *\n * These two new commands operate as toggles so that if \"*\" is used to trap all input (or output),\n * you can also use these commands to NOT trap specific ports.\n *\n * bn [n] break after [n] instructions\n *\n * TODO: Update the \"bl\" command to include any/all I/O breakpoints, and the \"bc\" command to\n * clear them. Because \"bi\" and \"bo\" commands are piggy-backing on Bus functions, those breakpoints\n * are currently outside the realm of what the \"bl\" and \"bc\" commands are aware of.\n *\n * @this {Debugger8080}\n * @param {string} sCmd\n * @param {string|undefined} [sAddr]\n * @param {string} [sOptions] (the rest of the breakpoint command-line)\n */\n doBreak(sCmd, sAddr, sOptions)\n {\n if (sAddr == '?') {\n this.println(\"breakpoint commands:\");\n this.println(\"\\tbi [p]\\ttoggle break on input port [p]\");\n this.println(\"\\tbo [p]\\ttoggle break on output port [p]\");\n this.println(\"\\tbp [a]\\tset exec breakpoint at addr [a]\");\n this.println(\"\\tbr [a]\\tset read breakpoint at addr [a]\");\n this.println(\"\\tbw [a]\\tset write breakpoint at addr [a]\");\n this.println(\"\\tbc [a]\\tclear breakpoint at addr [a]\");\n this.println(\"\\tbl\\tlist all breakpoints\");\n this.println(\"\\tbn [n]\\tbreak after [n] instruction(s)\");\n return;\n }\n\n var sParm = sCmd.charAt(1);\n if (sParm == 'l') {\n var cBreaks = 0;\n cBreaks += this.listBreakpoints(this.aBreakExec);\n cBreaks += this.listBreakpoints(this.aBreakRead);\n cBreaks += this.listBreakpoints(this.aBreakWrite);\n if (!cBreaks) this.println(\"no breakpoints\");\n return;\n }\n\n if (sParm == 'n') {\n this.nBreakIns = this.parseValue(sAddr);\n this.println(\"break after \" + this.nBreakIns + \" instruction(s)\");\n return;\n }\n\n if (sAddr === undefined) {\n this.println(\"missing breakpoint address\");\n return;\n }\n\n var dbgAddr = this.newAddr();\n if (sAddr != '*') {\n dbgAddr = this.parseAddr(sAddr, true, true);\n if (!dbgAddr) return;\n }\n\n sAddr = Str.toHexWord(dbgAddr.addr);\n\n if (sParm == 'c') {\n if (dbgAddr.addr == null) {\n this.clearBreakpoints();\n this.println(\"all breakpoints cleared\");\n return;\n }\n if (this.findBreakpoint(this.aBreakExec, dbgAddr, true))\n return;\n if (this.findBreakpoint(this.aBreakRead, dbgAddr, true))\n return;\n if (this.findBreakpoint(this.aBreakWrite, dbgAddr, true))\n return;\n this.println(\"breakpoint missing: \" + this.toHexAddr(dbgAddr));\n return;\n }\n\n if (sParm == 'i') {\n this.println(\"breakpoint \" + (this.bus.addPortInputBreak(dbgAddr.addr)? \"enabled\" : \"cleared\") + \": port \" + sAddr + \" (input)\");\n return;\n }\n\n if (sParm == 'o') {\n this.println(\"breakpoint \" + (this.bus.addPortOutputBreak(dbgAddr.addr)? \"enabled\" : \"cleared\") + \": port \" + sAddr + \" (output)\");\n return;\n }\n\n if (dbgAddr.addr == null) return;\n\n this.parseAddrOptions(dbgAddr, sOptions);\n\n if (sParm == 'p') {\n this.addBreakpoint(this.aBreakExec, dbgAddr);\n return;\n }\n if (sParm == 'r') {\n this.addBreakpoint(this.aBreakRead, dbgAddr);\n return;\n }\n if (sParm == 'w') {\n this.addBreakpoint(this.aBreakWrite, dbgAddr);\n return;\n }\n this.println(\"unknown breakpoint command: \" + sParm);\n }\n\n /**\n * doClear(sCmd)\n *\n * @this {Debugger8080}\n * @param {string} [sCmd] (eg, \"cls\" or \"clear\")\n */\n doClear(sCmd)\n {\n this.cmp.clearPanel();\n }\n\n /**\n * doDump(asArgs)\n *\n * The length parameter is interpreted as a number of bytes, in hex, which we convert to the appropriate number\n * of lines, because we always display whole lines. If the length is omitted/undefined, it defaults to 0x80 (128.)\n * bytes, which normally translates to 8 lines.\n *\n * @this {Debugger8080}\n * @param {Array.<string>} asArgs (formerly sCmd, [sAddr], [sLen] and [sBytes])\n */\n doDump(asArgs)\n {\n var m;\n var sCmd = asArgs[0];\n var sAddr = asArgs[1];\n var sLen = asArgs[2];\n var sBytes = asArgs[3];\n\n if (sAddr == '?') {\n var sDumpers = \"\";\n for (m in Messages8080.CATEGORIES) {\n if (this.afnDumpers[m]) {\n if (sDumpers) sDumpers += ',';\n sDumpers = sDumpers + m;\n }\n }\n sDumpers += \",state,symbols\";\n this.println(\"dump memory commands:\");\n this.println(\"\\tdb [a] [#] dump # bytes at address a\");\n this.println(\"\\tdw [a] [#] dump # words at address a\");\n this.println(\"\\tdd [a] [#] dump # dwords at address a\");\n this.println(\"\\tdh [#] [#] dump # instructions from history\");\n if (sDumpers.length) this.println(\"dump extension commands:\\n\\t\" + sDumpers);\n return;\n }\n\n if (sAddr == \"state\") {\n var sState = this.cmp.powerOff(true);\n if (sLen == \"console\") {\n /*\n * Console buffers are notoriously small, and even the following code, which breaks the\n * data into parts (eg, \"d state console 1\", \"d state console 2\", etc) just isn't that helpful.\n *\n * var nPart = +sBytes;\n * if (nPart) sState = sState.substr(1000000 * (nPart-1), 1000000);\n *\n * So, the best way to capture a large machine state is to use the new \"Save Machine\" link\n * that downloads a machine's entire state. Alternatively, run your own local server and use\n * server-side storage. Take a look at the \"Save\" binding in computer.js, which binds an HTML\n * control to the computer.powerOff() and computer.saveServerState() functions.\n */\n console.log(sState);\n } else {\n this.doClear();\n if (sState) this.println(sState);\n }\n return;\n }\n\n if (sAddr == \"symbols\") {\n this.dumpSymbols();\n return;\n }\n\n if (sCmd == \"d\") {\n for (m in Messages8080.CATEGORIES) {\n if (asArgs[1] == m) {\n var fnDumper = this.afnDumpers[m];\n if (fnDumper) {\n asArgs.shift();\n asArgs.shift();\n fnDumper(asArgs);\n } else {\n this.println(\"no dump registered for \" + sAddr);\n }\n return;\n }\n }\n if (!sAddr) sCmd = this.sCmdDumpPrev || \"db\";\n } else {\n this.sCmdDumpPrev = sCmd;\n }\n\n if (sCmd == \"dh\") {\n this.dumpHistory(sAddr, sLen);\n return;\n }\n\n var dbgAddr = this.parseAddr(sAddr);\n if (!dbgAddr) return;\n\n var len = 0; // 0 is not a default; it triggers the appropriate default below\n if (sLen) {\n if (sLen.charAt(0) == 'l') {\n sLen = sLen.substr(1) || sBytes;\n }\n len = this.parseValue(sLen) >>> 0; // negative lengths not allowed\n if (len > 0x10000) len = 0x10000; // prevent bad user (or variable) input from producing excessive output\n }\n\n var sDump = \"\";\n var size = (sCmd == \"dd\"? 4 : (sCmd == \"dw\"? 2 : 1));\n var cb = (size * len) || 128;\n var cLines = ((cb + 15) >> 4) || 1;\n\n while (cLines-- && cb > 0) {\n var data = 0, iByte = 0, i;\n var sData = \"\", sChars = \"\";\n sAddr = this.toHexAddr(dbgAddr);\n for (i = 16; i > 0 && cb > 0; i--) {\n var b = this.getByte(dbgAddr, 1);\n data |= (b << (iByte++ << 3));\n if (iByte == size) {\n sData += Str.toHex(data, size * 2);\n sData += (size == 1? (i == 9? '-' : ' ') : \" \");\n data = iByte = 0;\n }\n sChars += (b >= 32 && b < 127? String.fromCharCode(b) : '.');\n cb--;\n }\n if (sDump) sDump += '\\n';\n sDump += sAddr + \" \" + sData + ((i == 0)? (' ' + sChars) : \"\");\n }\n\n if (sDump) this.println(sDump);\n this.dbgAddrNextData = dbgAddr;\n }\n\n /**\n * doEdit(asArgs)\n *\n * @this {Debugger8080}\n * @param {Array.<string>} asArgs\n */\n doEdit(asArgs)\n {\n var size = 1;\n var mask = 0xff;\n var fnGet = this.getByte;\n var fnSet = this.setByte;\n if (asArgs[0] == \"ew\") {\n size = 2;\n mask = 0xffff;\n fnGet = this.getShort;\n fnSet = this.setShort;\n }\n var cch = size << 1;\n\n var sAddr = asArgs[1];\n if (sAddr == null) {\n this.println(\"edit memory commands:\");\n this.println(\"\\teb [a] [...] edit bytes at address a\");\n this.println(\"\\tew [a] [...] edit words at address a\");\n return;\n }\n\n var dbgAddr = this.parseAddr(sAddr);\n if (!dbgAddr) return;\n\n for (var i = 2; i < asArgs.length; i++) {\n var vNew = this.parseExpression(asArgs[i]);\n if (vNew === undefined) {\n this.println(\"unrecognized value: \" + asArgs[i]);\n break;\n }\n if (vNew & ~mask) {\n this.println(\"warning: \" + Str.toHex(vNew) + \" exceeds \" + size + \"-byte value\");\n }\n var vOld = fnGet.call(this, dbgAddr);\n this.println(\"changing \" + this.toHexAddr(dbgAddr) + \" from \" + Str.toHex(vOld, cch, true) + \" to \" + Str.toHex(vNew, cch, true));\n fnSet.call(this, dbgAddr, vNew, size);\n }\n }\n\n /**\n * doFreqs(sParm)\n *\n * @this {Debugger8080}\n * @param {string|undefined} sParm\n */\n doFreqs(sParm)\n {\n if (sParm == '?') {\n this.println(\"frequency commands:\");\n this.println(\"\\tclear\\tclear all frequency counts\");\n return;\n }\n var i;\n var cData = 0;\n if (this.aaOpcodeCounts) {\n if (sParm == \"clear\") {\n for (i = 0; i < this.aaOpcodeCounts.length; i++)\n this.aaOpcodeCounts[i] = [i, 0];\n this.println(\"frequency data cleared\");\n cData++;\n }\n else if (sParm !== undefined) {\n this.println(\"unknown frequency command: \" + sParm);\n cData++;\n }\n else {\n var aaSortedOpcodeCounts = this.aaOpcodeCounts.slice();\n aaSortedOpcodeCounts.sort(function(p, q) {\n return q[1] - p[1];\n });\n var asOpcodes = this.style != Debugger8080.STYLE_8086? Debugger8080.INS_NAMES : Debugger8080.INS_NAMES_8086;\n for (i = 0; i < aaSortedOpcodeCounts.length; i++) {\n var bOpcode = aaSortedOpcodeCounts[i][0];\n var cFreq = aaSortedOpcodeCounts[i][1];\n if (cFreq) {\n this.println((asOpcodes[this.aaOpDescs[bOpcode][0]] + \" \").substr(0, 5) + \" (\" + Str.toHexByte(bOpcode) + \"): \" + cFreq + \" times\");\n cData++;\n }\n }\n }\n }\n if (!cData) {\n this.println(\"no frequency data available\");\n }\n }\n\n /**\n * doHalt(fQuiet)\n *\n * @this {Debugger8080}\n * @param {boolean} [fQuiet]\n */\n doHalt(fQuiet)\n {\n var sMsg;\n if (this.flags.running) {\n sMsg = \"halting\";\n this.stopCPU();\n } else {\n if (this.isBusy(true)) return;\n sMsg = \"already halted\";\n }\n if (!fQuiet) this.println(sMsg);\n }\n\n /**\n * doIf(sCmd, fQuiet)\n *\n * NOTE: Don't forget that the default base for all numeric constants is 16 (hex), so when you evaluate\n * an expression like \"a==10\", it will compare the value of the variable \"a\" to 0x10; use a trailing period\n * (eg, \"10.\") if you really intend decimal.\n *\n * Also, if no variable named \"a\" exists, \"a\" will evaluate to 0x0A, so the expression \"a==10\" becomes\n * \"0x0A==0x10\" (false), whereas the expression \"a==10.\" becomes \"0x0A==0x0A\" (true).\n *\n * @this {Debugger8080}\n * @param {string} sCmd\n * @param {boolean} [fQuiet]\n * @return {boolean} true if expression is non-zero, false if zero (or undefined due to a parse error)\n */\n doIf(sCmd, fQuiet)\n {\n sCmd = Str.trim(sCmd);\n if (!this.parseExpression(sCmd)) {\n if (!fQuiet) this.println(\"false: \" + sCmd);\n return false;\n }\n if (!fQuiet) this.println(\"true: \" + sCmd);\n return true;\n }\n\n /**\n * doInfo(asArgs)\n *\n * @this {Debugger8080}\n * @param {Array.<string>} asArgs\n * @return {boolean} true only if the instruction info command (\"n\") is supported\n */\n doInfo(asArgs)\n {\n if (DEBUG) {\n this.println(\"msPerYield: \" + this.cpu.msPerYield);\n this.println(\"nCyclesPerYield: \" + this.cpu.nCyclesPerYield);\n return true;\n }\n return false;\n }\n\n /**\n * doInput(sPort)\n *\n * Simulate a 1-byte port input operation.\n *\n * @this {Debugger8080}\n * @param {string|undefined} sPort\n */\n doInput(sPort)\n {\n if (!sPort || sPort == '?') {\n this.println(\"input commands:\");\n this.println(\"\\ti [p]\\tread port [p]\");\n /*\n * TODO: Regarding this warning, consider adding an \"unchecked\" version of\n * bus.checkPortInputNotify(), since all Debugger memory accesses are unchecked, too.\n *\n * All port I/O handlers ARE aware when the Debugger is calling (addrFrom is undefined),\n * but changing them all to be non-destructive would take time, and situations where you\n * actually want to affect the hardware state are just as likely as not....\n */\n this.println(\"warning: port accesses can affect hardware state\");\n return;\n }\n var port = this.parseValue(sPort);\n if (port !== undefined) {\n var bIn = this.bus.checkPortInputNotify(port, 1);\n this.println(Str.toHexWord(port) + \": \" + Str.toHexByte(bIn));\n }\n }\n\n /**\n * doInt(sLevel)\n *\n * @this {Debugger8080}\n * @param {string} sLevel\n * @return {boolean} true if success, false if error\n */\n doInt(sLevel)\n {\n if (!this.cpu.getIF()) {\n this.println(\"interrupts disabled (use rif=1 to enable)\");\n return false;\n }\n var nLevel = this.parseExpression(sLevel);\n if (nLevel == null) return false;\n this.println(\"requesting interrupt level \" + nLevel);\n this.cpu.requestINTR(nLevel);\n return true;\n }\n\n /**\n * doVar(sCmd)\n *\n * The command must be of the form \"{variable} = [{expression}]\", where expression may contain constants,\n * operators, registers, symbols, other variables, or nothing at all; in the latter case, the variable, if\n * any, is deleted.\n *\n * Other supported shorthand: \"var\" with no parameters prints the values of all variables, and \"var {variable}\"\n * prints the value of the specified variable.\n *\n * @this {Debugger8080}\n * @param {string} sCmd\n * @return {boolean} true if valid \"var\" assignment, false if not\n */\n doVar(sCmd)\n {\n var a = sCmd.match(/^\\s*([A-Z_]?[A-Z0-9_]*)\\s*(=?)\\s*(.*)$/i);\n if (a) {\n if (!a[1]) {\n if (!this.printVariable()) this.println(\"no variables\");\n return true; // it's not considered an error to print an empty list of variables\n }\n if (!a[2]) {\n return this.printVariable(a[1]);\n }\n if (!a[3]) {\n this.delVariable(a[1]);\n return true; // it's not considered an error to delete a variable that didn't exist\n }\n var v = this.parseExpression(a[3]);\n if (v !== undefined) {\n this.setVariable(a[1], v);\n return true;\n }\n return false;\n }\n this.println(\"invalid assignment:\" + sCmd);\n return false;\n }\n\n /**\n * doList(sAddr, fPrint)\n *\n * @this {Debugger8080}\n * @param {string} sAddr\n * @param {boolean} [fPrint]\n * @return {string|null}\n */\n doList(sAddr, fPrint)\n {\n var sSymbol = null;\n\n var dbgAddr = this.parseAddr(sAddr, true);\n if (dbgAddr) {\n var addr = this.getAddr(dbgAddr);\n var aSymbol = this.findSymbol(dbgAddr, true);\n if (aSymbol.length) {\n var nDelta, sDelta, s;\n if (aSymbol[0]) {\n sDelta = \"\";\n nDelta = dbgAddr.addr - aSymbol[1];\n if (nDelta) sDelta = \" + \" + Str.toHexWord(nDelta);\n s = aSymbol[0] + \" (\" + this.toHexOffset(aSymbol[1]) + ')' + sDelta;\n if (fPrint) this.println(s);\n sSymbol = s;\n }\n if (aSymbol.length > 4 && aSymbol[4]) {\n sDelta = \"\";\n nDelta = aSymbol[5] - dbgAddr.addr;\n if (nDelta) sDelta = \" - \" + Str.toHexWord(nDelta);\n s = aSymbol[4] + \" (\" + this.toHexOffset(aSymbol[5]) + ')' + sDelta;\n if (fPrint) this.println(s);\n if (!sSymbol) sSymbol = s;\n }\n } else {\n if (fPrint) this.println(\"no symbols\");\n }\n }\n return sSymbol;\n }\n\n /**\n * doMessages(asArgs)\n *\n * @this {Debugger8080}\n * @param {Array.<string>} asArgs\n */\n doMessages(asArgs)\n {\n var m;\n var fCriteria = null;\n var sCategory = asArgs[1];\n if (sCategory == '?') sCategory = undefined;\n\n if (sCategory !== undefined) {\n var bitsMessage = 0;\n if (sCategory == \"all\") {\n bitsMessage = (0xffffffff|0) & ~(Messages8080.HALT | Messages8080.KEYS | Messages8080.BUFFER);\n sCategory = null;\n } else if (sCategory == \"on\") {\n fCriteria = true;\n sCategory = null;\n } else if (sCategory == \"off\") {\n fCriteria = false;\n sCategory = null;\n } else {\n /*\n * Internally, we use \"key\" instead of \"keys\", since the latter is a method on JavasScript objects,\n * but externally, we allow the user to specify \"keys\"; \"kbd\" is also allowed as shorthand for \"keyboard\".\n */\n if (sCategory == \"keys\") sCategory = \"key\";\n if (sCategory == \"kbd\") sCategory = \"keyboard\";\n for (m in Messages8080.CATEGORIES) {\n if (sCategory == m) {\n bitsMessage = Messages8080.CATEGORIES[m];\n fCriteria = !!(this.bitsMessage & bitsMessage);\n break;\n }\n }\n if (!bitsMessage) {\n this.println(\"unknown message category: \" + sCategory);\n return;\n }\n }\n if (bitsMessage) {\n if (asArgs[2] == \"on\") {\n this.bitsMessage |= bitsMessage;\n fCriteria = true;\n }\n else if (asArgs[2] == \"off\") {\n this.bitsMessage &= ~bitsMessage;\n fCriteria = false;\n if (bitsMessage == Messages8080.BUFFER) {\n for (var i = 0; i < this.aMessageBuffer.length; i++) {\n this.println(this.aMessageBuffer[i]);\n }\n this.aMessageBuffer = [];\n }\n }\n }\n }\n\n /*\n * Display those message categories that match the current criteria (on or off)\n */\n var n = 0;\n var sCategories = \"\";\n for (m in Messages8080.CATEGORIES) {\n if (!sCategory || sCategory == m) {\n var bitMessage = Messages8080.CATEGORIES[m];\n var fEnabled = !!(this.bitsMessage & bitMessage);\n if (fCriteria !== null && fCriteria != fEnabled) continue;\n if (sCategories) sCategories += ',';\n if (!(++n % 10)) sCategories += \"\\n\\t\"; // jshint ignore:line\n /*\n * Internally, we use \"key\" instead of \"keys\", since the latter is a method on JavasScript objects,\n * but externally, we allow the user to specify \"keys\".\n */\n if (m == \"key\") m = \"keys\";\n sCategories += m;\n }\n }\n\n if (sCategory === undefined) {\n this.println(\"message commands:\\n\\tm [category] [on|off]\\tturn categories on/off\");\n }\n\n this.println((fCriteria !== null? (fCriteria? \"messages on: \" : \"messages off: \") : \"message categories:\\n\\t\") + (sCategories || \"none\"));\n\n this.historyInit(); // call this just in case Messages8080.INT was turned on\n }\n\n /**\n * doOptions(asArgs)\n *\n * @this {Debugger8080}\n * @param {Array.<string>} asArgs\n */\n doOptions(asArgs)\n {\n switch (asArgs[1]) {\n case \"8080\":\n this.style = Debugger8080.STYLE_8080;\n break;\n\n case \"8086\":\n this.style = Debugger8080.STYLE_8086;\n break;\n\n case \"cs\":\n var nCycles;\n if (asArgs[3] !== undefined) nCycles = +asArgs[3]; // warning: decimal instead of hex conversion\n switch (asArgs[2]) {\n case \"int\":\n this.cpu.nCyclesChecksumInterval = nCycles;\n break;\n case \"start\":\n this.cpu.nCyclesChecksumStart = nCycles;\n break;\n case \"stop\":\n this.cpu.nCyclesChecksumStop = nCycles;\n break;\n default:\n this.println(\"unknown cs option\");\n return;\n }\n if (nCycles !== undefined) {\n this.cpu.resetChecksum();\n }\n this.println(\"checksums \" + (this.cpu.flags.checksum? \"enabled\" : \"disabled\"));\n return;\n\n case \"sp\":\n if (asArgs[2] !== undefined) {\n if (!this.cpu.setSpeed(+asArgs[2])) {\n this.println(\"warning: using 1x multiplier, previous target not reached\");\n }\n }\n this.println(\"target speed: \" + this.cpu.getSpeedTarget() + \" (\" + this.cpu.getSpeed() + \"x)\");\n return;\n\n case \"?\":\n this.println(\"debugger options:\");\n this.println(\"\\t8080\\t\\tselect 8080-style mnemonics\");\n this.println(\"\\t8086\\t\\tselect 8086-style mnemonics\");\n this.println(\"\\tcs int #\\tset checksum cycle interval to #\");\n this.println(\"\\tcs start #\\tset checksum cycle start count to #\");\n this.println(\"\\tcs stop #\\tset checksum cycle stop count to #\");\n this.println(\"\\tsp #\\t\\tset speed multiplier to #\");\n break;\n\n default:\n if (asArgs[1]) {\n this.println(\"unknown option: \" + asArgs[1]);\n return;\n }\n break;\n }\n this.println(this.style + \"-style mnemonics enabled\");\n }\n\n /**\n * doOutput(sPort, sByte)\n *\n * Simulate a 1-byte port output operation.\n *\n * @this {Debugger8080}\n * @param {string|undefined} sPort\n * @param {string|undefined} sByte (string representation of 1 byte)\n */\n doOutput(sPort, sByte)\n {\n if (!sPort || sPort == '?') {\n this.println(\"output commands:\");\n this.println(\"\\to [p] [b]\\twrite byte [b] to port [p]\");\n /*\n * TODO: Regarding this warning, consider adding an \"unchecked\" version of\n * bus.checkPortOutputNotify(), since all Debugger memory accesses are unchecked, too.\n *\n * All port I/O handlers ARE aware when the Debugger is calling (addrFrom is undefined),\n * but changing them all to be non-destructive would take time, and situations where you\n * actually want to affect the hardware state are just as likely as not....\n */\n this.println(\"warning: port accesses can affect hardware state\");\n return;\n }\n var port = this.parseValue(sPort, \"port #\");\n var bOut = this.parseValue(sByte);\n if (port !== undefined && bOut !== undefined) {\n this.bus.checkPortOutputNotify(port, 1, bOut);\n this.println(Str.toHexWord(port) + \": \" + Str.toHexByte(bOut));\n }\n }\n\n /**\n * doRegisters(asArgs, fInstruction)\n *\n * @this {Debugger8080}\n * @param {Array.<string>} [asArgs]\n * @param {boolean} [fInstruction] (true to include the current instruction; default is true)\n */\n doRegisters(asArgs, fInstruction)\n {\n if (asArgs && asArgs[1] == '?') {\n this.println(\"register commands:\");\n this.println(\"\\tr\\tdump registers\");\n this.println(\"\\trx [#]\\tset flag or register x to [#]\");\n return;\n }\n\n var cpu = this.cpu;\n if (fInstruction == null) fInstruction = true;\n\n if (asArgs != null && asArgs.length > 1) {\n var sReg = asArgs[1];\n var sValue = null;\n var i = sReg.indexOf('=');\n if (i > 0) {\n sValue = sReg.substr(i + 1);\n sReg = sReg.substr(0, i);\n }\n else if (asArgs.length > 2) {\n sValue = asArgs[2];\n }\n else {\n this.println(\"missing value for \" + asArgs[1]);\n return;\n }\n\n var w = this.parseExpression(sValue);\n if (w === undefined) return;\n\n var sRegMatch = sReg.toUpperCase();\n switch (sRegMatch) {\n case \"A\":\n cpu.regA = w & 0xff;\n break;\n case \"B\":\n cpu.regB = w & 0xff;\n break;\n case \"BC\":\n cpu.regB = ((w >> 8) & 0xff);\n /* falls through */\n case \"C\":\n cpu.regC = w & 0xff;\n break;\n case \"D\":\n cpu.regD = w & 0xff;\n break;\n case \"DE\":\n cpu.regD = ((w >> 8) & 0xff);\n /* falls through */\n case \"E\":\n cpu.regE = w & 0xff;\n break;\n case \"H\":\n cpu.regH = w & 0xff;\n break;\n case \"HL\":\n cpu.regH = ((w >> 8) & 0xff);\n /* falls through */\n case \"L\":\n cpu.regL = w & 0xff;\n break;\n case \"SP\":\n cpu.setSP(w);\n break;\n case \"PC\":\n cpu.setPC(w);\n this.dbgAddrNextCode = this.newAddr(cpu.getPC());\n break;\n case \"PS\":\n cpu.setPS(w);\n break;\n case \"PSW\":\n cpu.setPSW(w);\n break;\n case \"CF\":\n if (w) cpu.setCF(); else cpu.clearCF();\n break;\n case \"PF\":\n if (w) cpu.setPF(); else cpu.clearPF();\n break;\n case \"AF\":\n if (w) cpu.setAF(); else cpu.clearAF();\n break;\n case \"ZF\":\n if (w) cpu.setZF(); else cpu.clearZF();\n break;\n case \"SF\":\n if (w) cpu.setSF(); else cpu.clearSF();\n break;\n case \"IF\":\n if (w) cpu.setIF(); else cpu.clearIF();\n break;\n default:\n this.println(\"unknown register: \" + sReg);\n return;\n }\n cpu.updateCPU();\n this.println(\"updated registers:\");\n }\n\n this.println(this.getRegDump());\n\n if (fInstruction) {\n this.dbgAddrNextCode = this.newAddr(cpu.getPC());\n this.doUnassemble(this.toHexAddr(this.dbgAddrNextCode));\n }\n }\n\n /**\n * doRun(sCmd, sAddr, sOptions, fQuiet)\n *\n * @this {Debugger8080}\n * @param {string} sCmd\n * @param {string|undefined} [sAddr]\n * @param {string} [sOptions] (the rest of the breakpoint command-line)\n * @param {boolean} [fQuiet]\n */\n doRun(sCmd, sAddr, sOptions, fQuiet)\n {\n if (sCmd == \"gt\") {\n this.fIgnoreNextCheckFault = true;\n }\n if (sAddr !== undefined) {\n var dbgAddr = this.parseAddr(sAddr, true);\n if (!dbgAddr) return;\n this.parseAddrOptions(dbgAddr, sOptions);\n this.setTempBreakpoint(dbgAddr);\n }\n if (!this.runCPU(true)) {\n if (!fQuiet) this.println(\"cpu busy or unavailable, run command ignored\");\n }\n }\n\n /**\n * doPrint(sCmd)\n *\n * NOTE: If the string to print is a quoted string, then we run it through replaceRegs(), so that\n * you can take advantage of all the special replacement options used for software interrupt logging.\n *\n * @this {Debugger8080}\n * @param {string} sCmd\n */\n doPrint(sCmd)\n {\n sCmd = Str.trim(sCmd);\n var a = sCmd.match(/^(['\"])(.*?)\\1$/);\n if (!a) {\n this.parseExpression(sCmd, false);\n } else {\n this.println(this.replaceRegs(a[2]));\n }\n }\n\n /**\n * doStep(sCmd)\n *\n * @this {Debugger8080}\n * @param {string} [sCmd] \"p\" or \"pr\"\n */\n doStep(sCmd)\n {\n var fCallStep = true;\n var fRegs = (sCmd == \"pr\"? 1 : 0);\n /*\n * Set up the value for this.nStep (ie, 1 or 2) depending on whether the user wants\n * a subsequent register dump (\"pr\") or not (\"p\").\n */\n var nStep = 1 + fRegs;\n if (!this.nStep) {\n var dbgAddr = this.newAddr(this.cpu.getPC());\n var bOpcode = this.getByte(dbgAddr);\n\n switch (bOpcode) {\n case CPUDef8080.OPCODE.CALL:\n if (fCallStep) {\n this.nStep = nStep;\n this.incAddr(dbgAddr, 3);\n }\n break;\n default:\n break;\n }\n\n if (this.nStep) {\n this.setTempBreakpoint(dbgAddr);\n if (!this.runCPU()) {\n if (this.cmp) this.cmp.updateFocus();\n this.nStep = 0;\n }\n /*\n * A successful run will ultimately call stop(), which will in turn call clearTempBreakpoint(),\n * which will clear nStep, so there's your assurance that nStep will be reset. Now we may have\n * stopped for reasons unrelated to the temporary breakpoint, but that's OK.\n */\n } else {\n this.doTrace(fRegs? \"tr\" : \"t\");\n }\n } else {\n this.println(\"step in progress\");\n }\n }\n\n /**\n * getCall(dbgAddr)\n *\n * Given a possible return address (typically from the stack), look for a matching CALL (or INT) that\n * immediately precedes that address.\n *\n * @this {Debugger8080}\n * @param {DbgAddr8080} dbgAddr\n * @return {string|null} CALL instruction at or near dbgAddr, or null if none\n */\n getCall(dbgAddr)\n {\n var sCall = null;\n var addr = dbgAddr.addr;\n var addrOrig = addr;\n for (var n = 1; n <= 6 && !!addr; n++) {\n if (n > 2) {\n dbgAddr.addr = addr;\n var s = this.getInstruction(dbgAddr);\n if (s.indexOf(\"CALL\") >= 0) {\n /*\n * Verify that the length of this CALL (or INT), when added to the address of the CALL (or INT),\n * matches the original return address. We do this by getting the string index of the opcode bytes,\n * subtracting that from the string index of the next space, and dividing that difference by two,\n * to yield the length of the CALL (or INT) instruction, in bytes.\n */\n var i = s.indexOf(' ');\n var j = s.indexOf(' ', i+1);\n if (addr + (j - i - 1)/2 == addrOrig) {\n sCall = s;\n break;\n }\n }\n }\n addr--;\n }\n dbgAddr.addr = addrOrig;\n return sCall;\n }\n\n /**\n * doStackTrace(sCmd, sAddr)\n *\n * Use \"k\" for a normal stack trace and \"ks\" for a stack trace with symbolic info.\n *\n * @this {Debugger8080}\n * @param {string} [sCmd]\n * @param {string} [sAddr] (not used yet)\n */\n doStackTrace(sCmd, sAddr)\n {\n if (sAddr == '?') {\n this.println(\"stack trace commands:\");\n this.println(\"\\tk\\tshow frame addresses\");\n this.println(\"\\tks\\tshow symbol information\");\n return;\n }\n\n var nFrames = 10, cFrames = 0;\n var dbgAddrCall = this.newAddr();\n var dbgAddrStack = this.newAddr(this.cpu.getSP());\n this.println(\"stack trace for \" + this.toHexAddr(dbgAddrStack));\n\n while (cFrames < nFrames) {\n var sCall = null, sCallPrev = null, cTests = 256;\n while ((dbgAddrStack.addr >>> 0) < 0x10000) {\n dbgAddrCall.addr = this.getWord(dbgAddrStack, true);\n /*\n * Because we're using the auto-increment feature of getWord(), and because that will automatically\n * wrap the offset around the end of the segment, we must also check the addr property to detect the wrap.\n */\n if (dbgAddrStack.addr == null || !cTests--) break;\n sCall = this.getCall(dbgAddrCall);\n if (sCall) break;\n }\n /*\n * The sCallPrev check eliminates duplicate sequential calls, which are usually (but not always)\n * indicative of a false positive, in which case the previous call is probably bogus as well, but\n * at least we won't duplicate that mistake. Of course, there are always exceptions, recursion\n * being one of them, but it's rare that we're debugging recursive code.\n */\n if (!sCall || sCall == sCallPrev) break;\n var sSymbol = null;\n if (sCmd == \"ks\") {\n var a = sCall.match(/[0-9A-F]+$/);\n if (a) sSymbol = this.doList(a[0]);\n }\n sCall = Str.pad(sCall, 50) + \" ;\" + (sSymbol || \"stack=\" + this.toHexAddr(dbgAddrStack)); // + \" return=\" + this.toHexAddr(dbgAddrCall));\n this.println(sCall);\n sCallPrev = sCall;\n cFrames++;\n }\n if (!cFrames) this.println(\"no return addresses found\");\n }\n\n /**\n * doTrace(sCmd, sCount)\n *\n * The \"t\" and \"tr\" commands interpret the count as a number of instructions, and since\n * we call the Debugger's stepCPU() for each iteration, a single instruction includes\n * any/all prefixes; the CPU's stepCPU() treats prefixes as discrete operations. The only\n * difference between \"t\" and \"tr\": the former displays only the next instruction, while\n * the latter also displays the (updated) registers.\n *\n * The \"tc\" command interprets the count as a number of cycles rather than instructions,\n * allowing you to quickly execute large chunks of instructions with a single command; it\n * doesn't display anything until the the chunk has finished.\n *\n * However, generally a more useful command is \"bn\", which allows you to break after some\n * number of instructions have been executed (as opposed to some number of cycles).\n *\n * @this {Debugger8080}\n * @param {string} [sCmd] (\"t\", \"tc\", or \"tr\")\n * @param {string} [sCount] # of instructions to step\n */\n doTrace(sCmd, sCount)\n {\n var dbg = this;\n var fRegs = (sCmd != \"t\");\n var nCount = this.parseValue(sCount, null, true) || 1;\n var nCycles = (nCount == 1? 0 : 1);\n if (sCmd == \"tc\") {\n nCycles = nCount;\n nCount = 1;\n }\n Web.onCountRepeat(\n nCount,\n function onCountStep() {\n return dbg.setBusy(true) && dbg.stepCPU(nCycles, fRegs, false);\n },\n function onCountStepComplete() {\n /*\n * We explicitly called stepCPU() with fUpdateCPU === false, because repeatedly\n * calling updateCPU() can be very slow, especially when fDisplayLiveRegs is true,\n * so once the repeat count has been exhausted, we must perform a final updateCPU().\n */\n dbg.cpu.updateCPU();\n dbg.setBusy(false);\n }\n );\n }\n\n /**\n * doUnassemble(sAddr, sAddrEnd, n)\n *\n * @this {Debugger8080}\n * @param {string} [sAddr]\n * @param {string} [sAddrEnd]\n * @param {number} [n]\n */\n doUnassemble(sAddr, sAddrEnd, n)\n {\n var dbgAddr = this.parseAddr(sAddr, true);\n if (!dbgAddr) return;\n\n if (n === undefined) n = 1;\n\n var cb = 0x100;\n if (sAddrEnd !== undefined) {\n\n var dbgAddrEnd = this.parseAddr(sAddrEnd, true);\n if (!dbgAddrEnd || dbgAddrEnd.addr < dbgAddr.addr) return;\n\n cb = dbgAddrEnd.addr - dbgAddr.addr;\n if (!DEBUG && cb > 0x100) {\n /*\n * Limiting the amount of disassembled code to 256 bytes in non-DEBUG builds is partly to\n * prevent the user from wedging the browser by dumping too many lines, but also a recognition\n * that, in non-DEBUG builds, this.println() keeps print output buffer truncated to 8Kb anyway.\n */\n this.println(\"range too large\");\n return;\n }\n n = -1;\n }\n\n var cLines = 0;\n var sInstruction;\n\n while (cb > 0 && n--) {\n\n var nSequence = (this.isBusy(false) || this.nStep)? this.nCycles : null;\n var sComment = (nSequence != null? \"cycles\" : null);\n var aSymbol = this.findSymbol(dbgAddr);\n\n var addr = dbgAddr.addr; // we snap dbgAddr.addr *after* calling findSymbol(), which re-evaluates it\n\n if (aSymbol[0] && n) {\n if (!cLines && n || aSymbol[0].indexOf('+') < 0) {\n var sLabel = aSymbol[0] + ':';\n if (aSymbol[2]) sLabel += ' ' + aSymbol[2];\n this.println(sLabel);\n }\n }\n\n if (aSymbol[3]) {\n sComment = aSymbol[3];\n nSequence = null;\n }\n\n sInstruction = this.getInstruction(dbgAddr, sComment, nSequence);\n\n this.println(sInstruction);\n this.dbgAddrNextCode = dbgAddr;\n cb -= dbgAddr.addr - addr;\n cLines++;\n }\n }\n\n /**\n * parseCommand(sCmd, fSave, chSep)\n *\n * @this {Debugger8080}\n * @param {string|undefined} sCmd\n * @param {boolean} [fSave] is true to save the command, false if not\n * @param {string} [chSep] is the command separator character (default is ';')\n * @return {Array.<string>}\n */\n parseCommand(sCmd, fSave, chSep)\n {\n if (fSave) {\n if (!sCmd) {\n if (this.fAssemble) {\n sCmd = \"end\";\n } else {\n sCmd = this.aPrevCmds[this.iPrevCmd+1];\n }\n } else {\n if (this.iPrevCmd < 0 && this.aPrevCmds.length) {\n this.iPrevCmd = 0;\n }\n if (this.iPrevCmd < 0 || sCmd != this.aPrevCmds[this.iPrevCmd]) {\n this.aPrevCmds.splice(0, 0, sCmd);\n this.iPrevCmd = 0;\n }\n this.iPrevCmd--;\n }\n }\n var a = [];\n if (sCmd) {\n /*\n * With the introduction of breakpoint commands (ie, quoted command sequences\n * associated with a breakpoint), we can no longer perform simplistic splitting.\n *\n * a = sCmd.split(chSep || ';');\n * for (var i = 0; i < a.length; i++) a[i] = str.trim(a[i]);\n *\n * We may now split on semi-colons ONLY if they are outside a quoted sequence.\n *\n * Also, to allow quoted strings *inside* breakpoint commands, we first replace all\n * DOUBLE double-quotes with single quotes.\n */\n sCmd = sCmd.toLowerCase().replace(/\"\"/g, \"'\");\n\n var iPrev = 0;\n var chQuote = null;\n chSep = chSep || ';';\n /*\n * NOTE: Processing charAt() up to and INCLUDING length is not a typo; we're taking\n * advantage of the fact that charAt() with an invalid index returns an empty string,\n * allowing us to use the same substring() call to capture the final portion of sCmd.\n *\n * In a sense, it allows us to pretend that the string ends with a zero terminator.\n */\n for (var i = 0; i <= sCmd.length; i++) {\n var ch = sCmd.charAt(i);\n if (ch == '\"' || ch == \"'\") {\n if (!chQuote) {\n chQuote = ch;\n } else if (ch == chQuote) {\n chQuote = null;\n }\n }\n else if (ch == chSep && !chQuote || !ch) {\n /*\n * Recall that substring() accepts starting (inclusive) and ending (exclusive)\n * indexes, whereas substr() accepts a starting index and a length. We need the former.\n */\n a.push(Str.trim(sCmd.substring(iPrev, i)));\n iPrev = i + 1;\n }\n }\n }\n return a;\n }\n\n /**\n * shiftArgs(asArgs)\n *\n * Used with any command (eg, \"r\") that allows but doesn't require whitespace between command and first argument.\n *\n * @this {Debugger8080}\n * @param {Array.<string>} asArgs\n * @return {Array.<string>}\n */\n shiftArgs(asArgs)\n {\n if (asArgs && asArgs.length) {\n var s0 = asArgs[0];\n var ch0 = s0.charAt(0);\n for (var i = 1; i < s0.length; i++) {\n var ch = s0.charAt(i);\n if (ch0 == '?' || ch0 == 'r' || ch < 'a' || ch > 'z') {\n asArgs[0] = s0.substr(i);\n asArgs.unshift(s0.substr(0, i));\n break;\n }\n }\n }\n return asArgs;\n }\n\n /**\n * doCommand(sCmd, fQuiet)\n *\n * @this {Debugger8080}\n * @param {string} sCmd\n * @param {boolean} [fQuiet]\n * @return {boolean} true if command processed, false if unrecognized\n */\n doCommand(sCmd, fQuiet)\n {\n var result = true;\n\n try {\n if (!sCmd.length || sCmd == \"end\") {\n if (this.fAssemble) {\n this.println(\"ended assemble at \" + this.toHexAddr(this.dbgAddrAssemble));\n this.dbgAddrNextCode = this.dbgAddrAssemble;\n this.fAssemble = false;\n }\n sCmd = \"\";\n }\n else if (!fQuiet) {\n var sPrompt = \">> \";\n this.println(sPrompt + sCmd);\n }\n\n var ch = sCmd.charAt(0);\n if (ch == '\"' || ch == \"'\") return true;\n\n /*\n * Zap the previous message buffer to ensure the new command's output is not tossed out as a repeat.\n */\n this.sMessagePrev = null;\n\n /*\n * I've relaxed the !isBusy() requirement, to maximize our ability to issue Debugger commands externally.\n */\n if (this.isReady() /* && !this.isBusy(true) */ && sCmd.length > 0) {\n\n if (this.fAssemble) {\n sCmd = \"a \" + this.toHexAddr(this.dbgAddrAssemble) + ' ' + sCmd;\n }\n\n var asArgs = this.shiftArgs(sCmd.replace(/ +/g, ' ').split(' '));\n\n switch (asArgs[0].charAt(0)) {\n case 'a':\n this.doAssemble(asArgs);\n break;\n case 'b':\n this.doBreak(asArgs[0], asArgs[1], sCmd);\n break;\n case 'c':\n this.doClear(asArgs[0]);\n break;\n case 'd':\n if (!COMPILED && sCmd == \"debug\") {\n window.DEBUG = true;\n this.println(\"DEBUG checks on\");\n break;\n }\n this.doDump(asArgs);\n break;\n case 'e':\n if (asArgs[0] == \"else\") break;\n this.doEdit(asArgs);\n break;\n case 'f':\n this.doFreqs(asArgs[1]);\n break;\n case 'g':\n this.doRun(asArgs[0], asArgs[1], sCmd, fQuiet);\n break;\n case 'h':\n this.doHalt(fQuiet);\n break;\n case 'i':\n if (asArgs[0] == \"if\") {\n if (!this.doIf(sCmd.substr(2), fQuiet)) {\n result = false;\n }\n break;\n }\n if (asArgs[0] == \"int\") {\n if (!this.doInt(asArgs[1])) {\n result = false;\n }\n break;\n }\n this.doInput(asArgs[1]);\n break;\n case 'k':\n this.doStackTrace(asArgs[0], asArgs[1]);\n break;\n case 'l':\n if (asArgs[0] == \"ln\") {\n this.doList(asArgs[1], true);\n break;\n }\n break;\n case 'm':\n this.doMessages(asArgs);\n break;\n case 'o':\n this.doOutput(asArgs[1], asArgs[2]);\n break;\n case 'p':\n if (asArgs[0] == \"print\") {\n this.doPrint(sCmd.substr(5));\n break;\n }\n this.doStep(asArgs[0]);\n break;\n case 'r':\n if (sCmd == \"reset\") {\n if (this.cmp) this.cmp.reset();\n break;\n }\n this.doRegisters(asArgs);\n break;\n case 's':\n this.doOptions(asArgs);\n break;\n case 't':\n this.doTrace(asArgs[0], asArgs[1]);\n break;\n case 'u':\n this.doUnassemble(asArgs[1], asArgs[2], 8);\n break;\n case 'v':\n if (asArgs[0] == \"var\") {\n if (!this.doVar(sCmd.substr(3))) {\n result = false;\n }\n break;\n }\n this.println((PC8080.APPNAME || \"PC8080\") + \" version \" + (XMLVERSION || PC8080.APPVERSION) + \" (\" + this.cpu.model + (PC8080.COMPILED? \",RELEASE\" : (PC8080.DEBUG? \",DEBUG\" : \",NODEBUG\")) + (PC8080.TYPEDARRAYS? \",TYPEDARRAYS\" : (PC8080.BYTEARRAYS? \",BYTEARRAYS\" : \",LONGARRAYS\")) + ')');\n this.println(Web.getUserAgent());\n break;\n case '?':\n if (asArgs[1]) {\n this.doPrint(sCmd.substr(1));\n break;\n }\n this.doHelp();\n break;\n case 'n':\n if (!COMPILED && sCmd == \"nodebug\") {\n window.DEBUG = false;\n this.println(\"DEBUG checks off\");\n break;\n }\n if (this.doInfo(asArgs)) break;\n /* falls through */\n default:\n this.println(\"unknown command: \" + sCmd);\n result = false;\n break;\n }\n }\n } catch(e) {\n this.println(\"debugger error: \" + (e.stack || e.message));\n result = false;\n }\n return result;\n }\n\n /**\n * doCommands(sCmds, fSave)\n *\n * @this {Debugger8080}\n * @param {string} sCmds\n * @param {boolean} [fSave]\n * @return {boolean} true if all commands processed, false if not\n */\n doCommands(sCmds, fSave)\n {\n var a = this.parseCommand(sCmds, fSave);\n for (var s in a) {\n if (!this.doCommand(a[+s])) return false;\n }\n return true;\n }\n\n /**\n * Debugger8080.init()\n *\n * This function operates on every HTML element of class \"debugger\", extracting the\n * JSON-encoded parameters for the Debugger constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Debugger component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeDbg = Component.getElementsByClass(document, PC8080.APPCLASS, \"debugger\");\n for (var iDbg = 0; iDbg < aeDbg.length; iDbg++) {\n var eDbg = aeDbg[iDbg];\n var parmsDbg = Component.getComponentParms(eDbg);\n var dbg = new Debugger8080(parmsDbg);\n Component.bindComponentControls(dbg, eDbg, PC8080.APPCLASS);\n }\n }\n}\n\nif (DEBUGGER) {\n\n /*\n * NOTE: Every Debugger8080 property from here to the first prototype function definition (initBus()) is\n * considered a \"class constant\"; most of them use our \"all-caps\" convention (and all of them SHOULD, but\n * that wouldn't help us catch any bugs).\n *\n * Technically, all of them should ALSO be preceded by a \"@const\" annotation, but that's a lot of work and it\n * really clutters the code. I wish the Closure Compiler had a way to annotate every definition with a given\n * section with a single annotation....\n *\n * Bugs can slip through the cracks without those annotations; for example, I unthinkingly redefined TYPE_SIZE\n * at one point, and if all the definitions had been preceded by an \"@const\", that mistake would have been\n * caught at compile-time.\n */\n\n Debugger8080.COMMANDS = {\n '?': \"help/print\",\n 'a [#]': \"assemble\", // TODO: Implement this command someday\n 'b [#]': \"breakpoint\", // multiple variations (use b? to list them)\n 'c': \"clear output\",\n 'd [#]': \"dump memory\", // additional syntax: d [#] [l#], where l# is a number of bytes to dump\n 'e [#]': \"edit memory\",\n 'f': \"frequencies\",\n 'g [#]': \"go [to #]\",\n 'h': \"halt\",\n 'i [#]': \"input port #\",\n 'if': \"eval expression\",\n 'int [#]': \"request interrupt\",\n 'k': \"stack trace\",\n \"ln\": \"list nearest symbol(s)\",\n 'm': \"messages\",\n 'o [#]': \"output port #\",\n 'p': \"step over\", // other variations: pr (step and dump registers)\n 'print': \"print expression\",\n 'r': \"dump/set registers\",\n 'reset': \"reset machine\",\n 's': \"set options\",\n 't [#]': \"trace\", // other variations: tr (trace and dump registers)\n 'u [#]': \"unassemble\",\n 'v': \"print version\",\n 'var': \"assign variable\"\n };\n\n Debugger8080.STYLE_8080 = 8080;\n Debugger8080.STYLE_8086 = 8086;\n\n /*\n * CPU instruction ordinals\n */\n Debugger8080.INS = {\n NONE: 0, ACI: 1, ADC: 2, ADD: 3, ADI: 4, ANA: 5, ANI: 6, CALL: 7,\n CC: 8, CM: 9, CNC: 10, CNZ: 11, CP: 12, CPE: 13, CPO: 14, CZ: 15,\n CMA: 16, CMC: 17, CMP: 18, CPI: 19, DAA: 20, DAD: 21, DCR: 22, DCX: 23,\n DI: 24, EI: 25, HLT: 26, IN: 27, INR: 28, INX: 29, JMP: 30, JC: 31,\n JM: 32, JNC: 33, JNZ: 34, JP: 35, JPE: 36, JPO: 37, JZ: 38, LDA: 39,\n LDAX: 40, LHLD: 41, LXI: 42, MOV: 43, MVI: 44, NOP: 45, ORA: 46, ORI: 47,\n OUT: 48, PCHL: 49, POP: 50, PUSH: 51, RAL: 52, RAR: 53, RET: 54, RC: 55,\n RM: 56, RNC: 57, RNZ: 58, RP: 59, RPE: 60, RPO: 61, RZ: 62, RLC: 63,\n RRC: 64, RST: 65, SBB: 66, SBI: 67, SHLD: 68, SPHL: 69, STA: 70, STAX: 71,\n STC: 72, SUB: 73, SUI: 74, XCHG: 75, XRA: 76, XRI: 77, XTHL: 78\n };\n\n /*\n * CPU instruction names (mnemonics), indexed by CPU instruction ordinal (above)\n *\n * If you change the default style, using the \"s\" command (eg, \"s 8086\"), then the 8086 table\n * will be used instead. TODO: Add a \"s z80\" command for Z80-style mnemonics.\n */\n Debugger8080.INS_NAMES = [\n \"NONE\", \"ACI\", \"ADC\", \"ADD\", \"ADI\", \"ANA\", \"ANI\", \"CALL\",\n \"CC\", \"CM\", \"CNC\", \"CNZ\", \"CP\", \"CPE\", \"CPO\", \"CZ\",\n \"CMA\", \"CMC\", \"CMP\", \"CPI\", \"DAA\", \"DAD\", \"DCR\", \"DCX\",\n \"DI\", \"EI\", \"HLT\", \"IN\", \"INR\", \"INX\", \"JMP\", \"JC\",\n \"JM\", \"JNC\", \"JNZ\", \"JP\", \"JPE\", \"JPO\", \"JZ\", \"LDA\",\n \"LDAX\", \"LHLD\", \"LXI\", \"MOV\", \"MVI\", \"NOP\", \"ORA\", \"ORI\",\n \"OUT\", \"PCHL\", \"POP\", \"PUSH\", \"RAL\", \"RAR\", \"RET\", \"RC\",\n \"RM\", \"RNC\", \"RNZ\", \"RP\", \"RPE\", \"RPO\", \"RZ\", \"RLC\",\n \"RRC\", \"RST\", \"SBB\", \"SBI\", \"SHLD\", \"SPHL\", \"STA\", \"STAX\",\n \"STC\", \"SUB\", \"SUI\", \"XCHG\", \"XRA\", \"XRI\", \"XTHL\"\n ];\n\n Debugger8080.INS_NAMES_8086 = [\n \"NONE\", \"ADC\", \"ADC\", \"ADD\", \"ADD\", \"AND\", \"AND\", \"CALL\",\n \"CALLC\", \"CALLS\", \"CALLNC\", \"CALLNZ\", \"CALLNS\", \"CALLP\", \"CALLNP\", \"CALLZ\",\n \"NOT\", \"CMC\", \"CMP\", \"CMP\", \"DAA\", \"ADD\", \"DEC\", \"DEC\",\n \"CLI\", \"STI\", \"HLT\", \"IN\", \"INC\", \"INC\", \"JMP\", \"JC\",\n \"JS\", \"JNC\", \"JNZ\", \"JNS\", \"JP\", \"JNP\", \"JZ\", \"MOV\",\n \"MOV\", \"MOV\", \"MOV\", \"MOV\", \"MOV\", \"NOP\", \"OR\", \"OR\",\n \"OUT\", \"JMP\", \"POP\", \"PUSH\", \"RCL\", \"RCR\", \"RET\", \"RETC\",\n \"RETS\", \"RETNC\", \"RETNZ\", \"RETNS\", \"RETP\", \"RETNP\", \"RETZ\", \"ROL\",\n \"ROR\", \"RST\", \"SBB\", \"SBB\", \"MOV\", \"MOV\", \"MOV\", \"MOV\",\n \"STC\", \"SUB\", \"SUB\", \"XCHG\", \"XOR\", \"XOR\", \"XCHG\"\n ];\n\n Debugger8080.REG_B = 0x00;\n Debugger8080.REG_C = 0x01;\n Debugger8080.REG_D = 0x02;\n Debugger8080.REG_E = 0x03;\n Debugger8080.REG_H = 0x04;\n Debugger8080.REG_L = 0x05;\n Debugger8080.REG_M = 0x06;\n Debugger8080.REG_A = 0x07;\n Debugger8080.REG_BC = 0x08;\n Debugger8080.REG_DE = 0x09;\n Debugger8080.REG_HL = 0x0A;\n Debugger8080.REG_SP = 0x0B;\n Debugger8080.REG_PC = 0x0C;\n Debugger8080.REG_PS = 0x0D;\n Debugger8080.REG_PSW = 0x0E; // aka AF if Z80-style mnemonics\n\n /*\n * NOTE: \"PS\" is the complete processor status, which includes bits like the Interrupt flag (IF),\n * which is NOT the same as \"PSW\", which is the low 8 bits of \"PS\" combined with \"A\" in the high byte.\n */\n Debugger8080.REGS = [\n \"B\", \"C\", \"D\", \"E\", \"H\", \"L\", \"M\", \"A\", \"BC\", \"DE\", \"HL\", \"SP\", \"PC\", \"PS\", \"PSW\"\n ];\n\n /*\n * Operand type descriptor masks and definitions\n */\n Debugger8080.TYPE_SIZE = 0x000F; // size field\n Debugger8080.TYPE_MODE = 0x00F0; // mode field\n Debugger8080.TYPE_IREG = 0x0F00; // implied register field\n Debugger8080.TYPE_OTHER = 0xF000; // \"other\" field\n\n /*\n * TYPE_SIZE values\n */\n Debugger8080.TYPE_NONE = 0x0000; // (all other TYPE fields ignored)\n Debugger8080.TYPE_BYTE = 0x0001; // byte, regardless of operand size\n Debugger8080.TYPE_SBYTE = 0x0002; // byte sign-extended to word\n Debugger8080.TYPE_WORD = 0x0003; // word (16-bit value)\n\n /*\n * TYPE_MODE values\n */\n Debugger8080.TYPE_REG = 0x0010; // register\n Debugger8080.TYPE_IMM = 0x0020; // immediate data\n Debugger8080.TYPE_ADDR = 0x0033; // immediate (word) address\n Debugger8080.TYPE_MEM = 0x0040; // memory reference\n Debugger8080.TYPE_INT = 0x0080; // interrupt level encoded in instruction (bits 3-5)\n\n /*\n * TYPE_IREG values, based on the REG_* constants.\n *\n * Note that TYPE_M isn't really a register, just an alternative form of TYPE_HL | TYPE_MEM.\n */\n Debugger8080.TYPE_A = (Debugger8080.REG_A << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_BYTE);\n Debugger8080.TYPE_B = (Debugger8080.REG_B << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_BYTE);\n Debugger8080.TYPE_C = (Debugger8080.REG_C << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_BYTE);\n Debugger8080.TYPE_D = (Debugger8080.REG_D << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_BYTE);\n Debugger8080.TYPE_E = (Debugger8080.REG_E << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_BYTE);\n Debugger8080.TYPE_H = (Debugger8080.REG_H << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_BYTE);\n Debugger8080.TYPE_L = (Debugger8080.REG_L << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_BYTE);\n Debugger8080.TYPE_M = (Debugger8080.REG_M << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_BYTE | Debugger8080.TYPE_MEM);\n Debugger8080.TYPE_BC = (Debugger8080.REG_BC << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_WORD);\n Debugger8080.TYPE_DE = (Debugger8080.REG_DE << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_WORD);\n Debugger8080.TYPE_HL = (Debugger8080.REG_HL << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_WORD);\n Debugger8080.TYPE_SP = (Debugger8080.REG_SP << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_WORD);\n Debugger8080.TYPE_PC = (Debugger8080.REG_PC << 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_WORD);\n Debugger8080.TYPE_PSW = (Debugger8080.REG_PSW<< 8 | Debugger8080.TYPE_REG | Debugger8080.TYPE_WORD);\n\n /*\n * TYPE_OTHER bit definitions\n */\n Debugger8080.TYPE_IN = 0x1000; // operand is input\n Debugger8080.TYPE_OUT = 0x2000; // operand is output\n Debugger8080.TYPE_BOTH = (Debugger8080.TYPE_IN | Debugger8080.TYPE_OUT);\n Debugger8080.TYPE_OPT = 0x4000; // optional operand (ie, normally omitted in 8080 assembly language)\n Debugger8080.TYPE_UNDOC = 0x8000; // opcode is an undocumented alternative encoding\n\n /*\n * The aaOpDescs array is indexed by opcode, and each element is a sub-array (aOpDesc) that describes\n * the corresponding opcode. The sub-elements are as follows:\n *\n * [0]: {number} of the opcode name (see INS.*)\n * [1]: {number} containing the destination operand descriptor bit(s), if any\n * [2]: {number} containing the source operand descriptor bit(s), if any\n * [3]: {number} containing the occasional third operand descriptor bit(s), if any\n *\n * These sub-elements are all optional. If [0] is not present, the opcode is undefined; if [1] is not\n * present (or contains zero), the opcode has no (or only implied) operands; if [2] is not present, the\n * opcode has only a single operand. And so on.\n *\n * Additional default rules:\n *\n * 1) If no TYPE_OTHER bits are specified for the first (destination) operand, TYPE_OUT is assumed;\n * 2) If no TYPE_OTHER bits are specified for the second (source) operand, TYPE_IN is assumed;\n * 3) If no size is specified for the second operand, the size is assumed to match the first operand.\n */\n Debugger8080.aaOpDescs = [\n /* 0x00 */ [Debugger8080.INS.NOP],\n /* 0x01 */ [Debugger8080.INS.LXI, Debugger8080.TYPE_BC, Debugger8080.TYPE_IMM],\n /* 0x02 */ [Debugger8080.INS.STAX, Debugger8080.TYPE_BC | Debugger8080.TYPE_MEM, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT],\n /* 0x03 */ [Debugger8080.INS.INX, Debugger8080.TYPE_BC],\n /* 0x04 */ [Debugger8080.INS.INR, Debugger8080.TYPE_B],\n /* 0x05 */ [Debugger8080.INS.DCR, Debugger8080.TYPE_B],\n /* 0x06 */ [Debugger8080.INS.MVI, Debugger8080.TYPE_B, Debugger8080.TYPE_IMM],\n /* 0x07 */ [Debugger8080.INS.RLC],\n /* 0x08 */ [Debugger8080.INS.NOP, Debugger8080.TYPE_UNDOC],\n /* 0x09 */ [Debugger8080.INS.DAD, Debugger8080.TYPE_HL | Debugger8080.TYPE_OPT, Debugger8080.TYPE_BC],\n /* 0x0A */ [Debugger8080.INS.LDAX, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_BC | Debugger8080.TYPE_MEM],\n /* 0x0B */ [Debugger8080.INS.DCX, Debugger8080.TYPE_BC],\n /* 0x0C */ [Debugger8080.INS.INR, Debugger8080.TYPE_C],\n /* 0x0D */ [Debugger8080.INS.DCR, Debugger8080.TYPE_C],\n /* 0x0E */ [Debugger8080.INS.MVI, Debugger8080.TYPE_C, Debugger8080.TYPE_IMM],\n /* 0x0F */ [Debugger8080.INS.RRC],\n /* 0x10 */ [Debugger8080.INS.NOP, Debugger8080.TYPE_UNDOC],\n /* 0x11 */ [Debugger8080.INS.LXI, Debugger8080.TYPE_DE, Debugger8080.TYPE_IMM],\n /* 0x12 */ [Debugger8080.INS.STAX, Debugger8080.TYPE_DE | Debugger8080.TYPE_MEM, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT],\n /* 0x13 */ [Debugger8080.INS.INX, Debugger8080.TYPE_DE],\n /* 0x14 */ [Debugger8080.INS.INR, Debugger8080.TYPE_D],\n /* 0x15 */ [Debugger8080.INS.DCR, Debugger8080.TYPE_D],\n /* 0x16 */ [Debugger8080.INS.MVI, Debugger8080.TYPE_D, Debugger8080.TYPE_IMM],\n /* 0x17 */ [Debugger8080.INS.RAL],\n /* 0x18 */ [Debugger8080.INS.NOP, Debugger8080.TYPE_UNDOC],\n /* 0x19 */ [Debugger8080.INS.DAD, Debugger8080.TYPE_HL | Debugger8080.TYPE_OPT, Debugger8080.TYPE_DE],\n /* 0x1A */ [Debugger8080.INS.LDAX, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_DE | Debugger8080.TYPE_MEM],\n /* 0x1B */ [Debugger8080.INS.DCX, Debugger8080.TYPE_DE],\n /* 0x1C */ [Debugger8080.INS.INR, Debugger8080.TYPE_E],\n /* 0x1D */ [Debugger8080.INS.DCR, Debugger8080.TYPE_E],\n /* 0x1E */ [Debugger8080.INS.MVI, Debugger8080.TYPE_E, Debugger8080.TYPE_IMM],\n /* 0x1F */ [Debugger8080.INS.RAR],\n /* 0x20 */ [Debugger8080.INS.NOP, Debugger8080.TYPE_UNDOC],\n /* 0x21 */ [Debugger8080.INS.LXI, Debugger8080.TYPE_HL, Debugger8080.TYPE_IMM],\n /* 0x22 */ [Debugger8080.INS.SHLD, Debugger8080.TYPE_ADDR | Debugger8080.TYPE_MEM, Debugger8080.TYPE_HL | Debugger8080.TYPE_OPT],\n /* 0x23 */ [Debugger8080.INS.INX, Debugger8080.TYPE_HL],\n /* 0x24 */ [Debugger8080.INS.INR, Debugger8080.TYPE_H],\n /* 0x25 */ [Debugger8080.INS.DCR, Debugger8080.TYPE_H],\n /* 0x26 */ [Debugger8080.INS.MVI, Debugger8080.TYPE_H, Debugger8080.TYPE_IMM],\n /* 0x27 */ [Debugger8080.INS.DAA],\n /* 0x28 */ [Debugger8080.INS.NOP, Debugger8080.TYPE_UNDOC],\n /* 0x29 */ [Debugger8080.INS.DAD, Debugger8080.TYPE_HL | Debugger8080.TYPE_OPT, Debugger8080.TYPE_HL],\n /* 0x2A */ [Debugger8080.INS.LHLD, Debugger8080.TYPE_HL | Debugger8080.TYPE_OPT, Debugger8080.TYPE_ADDR | Debugger8080.TYPE_MEM],\n /* 0x2B */ [Debugger8080.INS.DCX, Debugger8080.TYPE_HL],\n /* 0x2C */ [Debugger8080.INS.INR, Debugger8080.TYPE_L],\n /* 0x2D */ [Debugger8080.INS.DCR, Debugger8080.TYPE_L],\n /* 0x2E */ [Debugger8080.INS.MVI, Debugger8080.TYPE_L, Debugger8080.TYPE_IMM],\n /* 0x2F */ [Debugger8080.INS.CMA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT],\n /* 0x30 */ [Debugger8080.INS.NOP, Debugger8080.TYPE_UNDOC],\n /* 0x31 */ [Debugger8080.INS.LXI, Debugger8080.TYPE_SP, Debugger8080.TYPE_IMM],\n /* 0x32 */ [Debugger8080.INS.STA, Debugger8080.TYPE_ADDR | Debugger8080.TYPE_MEM, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT],\n /* 0x33 */ [Debugger8080.INS.INX, Debugger8080.TYPE_SP],\n /* 0x34 */ [Debugger8080.INS.INR, Debugger8080.TYPE_M],\n /* 0x35 */ [Debugger8080.INS.DCR, Debugger8080.TYPE_M],\n /* 0x36 */ [Debugger8080.INS.MVI, Debugger8080.TYPE_M, Debugger8080.TYPE_IMM],\n /* 0x37 */ [Debugger8080.INS.STC],\n /* 0x38 */ [Debugger8080.INS.NOP, Debugger8080.TYPE_UNDOC],\n /* 0x39 */ [Debugger8080.INS.DAD, Debugger8080.TYPE_HL | Debugger8080.TYPE_OPT, Debugger8080.TYPE_SP],\n /* 0x3A */ [Debugger8080.INS.LDA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_ADDR | Debugger8080.TYPE_MEM],\n /* 0x3B */ [Debugger8080.INS.DCX, Debugger8080.TYPE_SP],\n /* 0x3C */ [Debugger8080.INS.INR, Debugger8080.TYPE_A],\n /* 0x3D */ [Debugger8080.INS.DCR, Debugger8080.TYPE_A],\n /* 0x3E */ [Debugger8080.INS.MVI, Debugger8080.TYPE_A, Debugger8080.TYPE_IMM],\n /* 0x3F */ [Debugger8080.INS.CMC],\n /* 0x40 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_B, Debugger8080.TYPE_B],\n /* 0x41 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_B, Debugger8080.TYPE_C],\n /* 0x42 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_B, Debugger8080.TYPE_D],\n /* 0x43 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_B, Debugger8080.TYPE_E],\n /* 0x44 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_B, Debugger8080.TYPE_H],\n /* 0x45 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_B, Debugger8080.TYPE_L],\n /* 0x46 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_B, Debugger8080.TYPE_M],\n /* 0x47 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_B, Debugger8080.TYPE_A],\n /* 0x48 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_C, Debugger8080.TYPE_B],\n /* 0x49 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_C, Debugger8080.TYPE_C],\n /* 0x4A */ [Debugger8080.INS.MOV, Debugger8080.TYPE_C, Debugger8080.TYPE_D],\n /* 0x4B */ [Debugger8080.INS.MOV, Debugger8080.TYPE_C, Debugger8080.TYPE_E],\n /* 0x4C */ [Debugger8080.INS.MOV, Debugger8080.TYPE_C, Debugger8080.TYPE_H],\n /* 0x4D */ [Debugger8080.INS.MOV, Debugger8080.TYPE_C, Debugger8080.TYPE_L],\n /* 0x4E */ [Debugger8080.INS.MOV, Debugger8080.TYPE_C, Debugger8080.TYPE_M],\n /* 0x4F */ [Debugger8080.INS.MOV, Debugger8080.TYPE_C, Debugger8080.TYPE_A],\n /* 0x50 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_D, Debugger8080.TYPE_B],\n /* 0x51 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_D, Debugger8080.TYPE_C],\n /* 0x52 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_D, Debugger8080.TYPE_D],\n /* 0x53 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_D, Debugger8080.TYPE_E],\n /* 0x54 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_D, Debugger8080.TYPE_H],\n /* 0x55 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_D, Debugger8080.TYPE_L],\n /* 0x56 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_D, Debugger8080.TYPE_M],\n /* 0x57 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_D, Debugger8080.TYPE_A],\n /* 0x58 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_E, Debugger8080.TYPE_B],\n /* 0x59 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_E, Debugger8080.TYPE_C],\n /* 0x5A */ [Debugger8080.INS.MOV, Debugger8080.TYPE_E, Debugger8080.TYPE_D],\n /* 0x5B */ [Debugger8080.INS.MOV, Debugger8080.TYPE_E, Debugger8080.TYPE_E],\n /* 0x5C */ [Debugger8080.INS.MOV, Debugger8080.TYPE_E, Debugger8080.TYPE_H],\n /* 0x5D */ [Debugger8080.INS.MOV, Debugger8080.TYPE_E, Debugger8080.TYPE_L],\n /* 0x5E */ [Debugger8080.INS.MOV, Debugger8080.TYPE_E, Debugger8080.TYPE_M],\n /* 0x5F */ [Debugger8080.INS.MOV, Debugger8080.TYPE_E, Debugger8080.TYPE_A],\n /* 0x60 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_H, Debugger8080.TYPE_B],\n /* 0x61 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_H, Debugger8080.TYPE_C],\n /* 0x62 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_H, Debugger8080.TYPE_D],\n /* 0x63 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_H, Debugger8080.TYPE_E],\n /* 0x64 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_H, Debugger8080.TYPE_H],\n /* 0x65 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_H, Debugger8080.TYPE_L],\n /* 0x66 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_H, Debugger8080.TYPE_M],\n /* 0x67 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_H, Debugger8080.TYPE_A],\n /* 0x68 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_L, Debugger8080.TYPE_B],\n /* 0x69 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_L, Debugger8080.TYPE_C],\n /* 0x6A */ [Debugger8080.INS.MOV, Debugger8080.TYPE_L, Debugger8080.TYPE_D],\n /* 0x6B */ [Debugger8080.INS.MOV, Debugger8080.TYPE_L, Debugger8080.TYPE_E],\n /* 0x6C */ [Debugger8080.INS.MOV, Debugger8080.TYPE_L, Debugger8080.TYPE_H],\n /* 0x6D */ [Debugger8080.INS.MOV, Debugger8080.TYPE_L, Debugger8080.TYPE_L],\n /* 0x6E */ [Debugger8080.INS.MOV, Debugger8080.TYPE_L, Debugger8080.TYPE_M],\n /* 0x6F */ [Debugger8080.INS.MOV, Debugger8080.TYPE_L, Debugger8080.TYPE_A],\n /* 0x70 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_M, Debugger8080.TYPE_B],\n /* 0x71 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_M, Debugger8080.TYPE_C],\n /* 0x72 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_M, Debugger8080.TYPE_D],\n /* 0x73 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_M, Debugger8080.TYPE_E],\n /* 0x74 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_M, Debugger8080.TYPE_H],\n /* 0x75 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_M, Debugger8080.TYPE_L],\n /* 0x76 */ [Debugger8080.INS.HLT],\n /* 0x77 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_M, Debugger8080.TYPE_A],\n /* 0x78 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_A, Debugger8080.TYPE_B],\n /* 0x79 */ [Debugger8080.INS.MOV, Debugger8080.TYPE_A, Debugger8080.TYPE_C],\n /* 0x7A */ [Debugger8080.INS.MOV, Debugger8080.TYPE_A, Debugger8080.TYPE_D],\n /* 0x7B */ [Debugger8080.INS.MOV, Debugger8080.TYPE_A, Debugger8080.TYPE_E],\n /* 0x7C */ [Debugger8080.INS.MOV, Debugger8080.TYPE_A, Debugger8080.TYPE_H],\n /* 0x7D */ [Debugger8080.INS.MOV, Debugger8080.TYPE_A, Debugger8080.TYPE_L],\n /* 0x7E */ [Debugger8080.INS.MOV, Debugger8080.TYPE_A, Debugger8080.TYPE_M],\n /* 0x7F */ [Debugger8080.INS.MOV, Debugger8080.TYPE_A, Debugger8080.TYPE_A],\n /* 0x80 */ [Debugger8080.INS.ADD, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_B],\n /* 0x81 */ [Debugger8080.INS.ADD, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_C],\n /* 0x82 */ [Debugger8080.INS.ADD, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_D],\n /* 0x83 */ [Debugger8080.INS.ADD, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_E],\n /* 0x84 */ [Debugger8080.INS.ADD, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_H],\n /* 0x85 */ [Debugger8080.INS.ADD, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_L],\n /* 0x86 */ [Debugger8080.INS.ADD, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_M],\n /* 0x87 */ [Debugger8080.INS.ADD, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_A],\n /* 0x88 */ [Debugger8080.INS.ADC, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_B],\n /* 0x89 */ [Debugger8080.INS.ADC, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_C],\n /* 0x8A */ [Debugger8080.INS.ADC, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_D],\n /* 0x8B */ [Debugger8080.INS.ADC, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_E],\n /* 0x8C */ [Debugger8080.INS.ADC, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_H],\n /* 0x8D */ [Debugger8080.INS.ADC, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_L],\n /* 0x8E */ [Debugger8080.INS.ADC, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_M],\n /* 0x8F */ [Debugger8080.INS.ADC, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_A],\n /* 0x90 */ [Debugger8080.INS.SUB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_B],\n /* 0x91 */ [Debugger8080.INS.SUB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_C],\n /* 0x92 */ [Debugger8080.INS.SUB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_D],\n /* 0x93 */ [Debugger8080.INS.SUB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_E],\n /* 0x94 */ [Debugger8080.INS.SUB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_H],\n /* 0x95 */ [Debugger8080.INS.SUB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_L],\n /* 0x96 */ [Debugger8080.INS.SUB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_M],\n /* 0x97 */ [Debugger8080.INS.SUB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_A],\n /* 0x98 */ [Debugger8080.INS.SBB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_B],\n /* 0x99 */ [Debugger8080.INS.SBB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_C],\n /* 0x9A */ [Debugger8080.INS.SBB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_D],\n /* 0x9B */ [Debugger8080.INS.SBB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_E],\n /* 0x9C */ [Debugger8080.INS.SBB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_H],\n /* 0x9D */ [Debugger8080.INS.SBB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_L],\n /* 0x9E */ [Debugger8080.INS.SBB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_M],\n /* 0x9F */ [Debugger8080.INS.SBB, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_A],\n /* 0xA0 */ [Debugger8080.INS.ANA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_B],\n /* 0xA1 */ [Debugger8080.INS.ANA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_C],\n /* 0xA2 */ [Debugger8080.INS.ANA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_D],\n /* 0xA3 */ [Debugger8080.INS.ANA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_E],\n /* 0xA4 */ [Debugger8080.INS.ANA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_H],\n /* 0xA5 */ [Debugger8080.INS.ANA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_L],\n /* 0xA6 */ [Debugger8080.INS.ANA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_M],\n /* 0xA7 */ [Debugger8080.INS.ANA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_A],\n /* 0xA8 */ [Debugger8080.INS.XRA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_B],\n /* 0xA9 */ [Debugger8080.INS.XRA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_C],\n /* 0xAA */ [Debugger8080.INS.XRA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_D],\n /* 0xAB */ [Debugger8080.INS.XRA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_E],\n /* 0xAC */ [Debugger8080.INS.XRA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_H],\n /* 0xAD */ [Debugger8080.INS.XRA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_L],\n /* 0xAE */ [Debugger8080.INS.XRA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_M],\n /* 0xAF */ [Debugger8080.INS.XRA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_A],\n /* 0xB0 */ [Debugger8080.INS.ORA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_B],\n /* 0xB1 */ [Debugger8080.INS.ORA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_C],\n /* 0xB2 */ [Debugger8080.INS.ORA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_D],\n /* 0xB3 */ [Debugger8080.INS.ORA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_E],\n /* 0xB4 */ [Debugger8080.INS.ORA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_H],\n /* 0xB5 */ [Debugger8080.INS.ORA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_L],\n /* 0xB6 */ [Debugger8080.INS.ORA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_M],\n /* 0xB7 */ [Debugger8080.INS.ORA, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_A],\n /* 0xB8 */ [Debugger8080.INS.CMP, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_B],\n /* 0xB9 */ [Debugger8080.INS.CMP, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_C],\n /* 0xBA */ [Debugger8080.INS.CMP, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_D],\n /* 0xBB */ [Debugger8080.INS.CMP, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_E],\n /* 0xBC */ [Debugger8080.INS.CMP, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_H],\n /* 0xBD */ [Debugger8080.INS.CMP, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_L],\n /* 0xBE */ [Debugger8080.INS.CMP, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_M],\n /* 0xBF */ [Debugger8080.INS.CMP, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_A],\n /* 0xC0 */ [Debugger8080.INS.RNZ],\n /* 0xC1 */ [Debugger8080.INS.POP, Debugger8080.TYPE_BC],\n /* 0xC2 */ [Debugger8080.INS.JNZ, Debugger8080.TYPE_ADDR],\n /* 0xC3 */ [Debugger8080.INS.JMP, Debugger8080.TYPE_ADDR],\n /* 0xC4 */ [Debugger8080.INS.CNZ, Debugger8080.TYPE_ADDR],\n /* 0xC5 */ [Debugger8080.INS.PUSH, Debugger8080.TYPE_BC],\n /* 0xC6 */ [Debugger8080.INS.ADI, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_IMM | Debugger8080.TYPE_BYTE],\n /* 0xC7 */ [Debugger8080.INS.RST, Debugger8080.TYPE_INT],\n /* 0xC8 */ [Debugger8080.INS.RZ],\n /* 0xC9 */ [Debugger8080.INS.RET],\n /* 0xCA */ [Debugger8080.INS.JZ, Debugger8080.TYPE_ADDR],\n /* 0xCB */ [Debugger8080.INS.JMP, Debugger8080.TYPE_ADDR | Debugger8080.TYPE_UNDOC],\n /* 0xCC */ [Debugger8080.INS.CZ, Debugger8080.TYPE_ADDR],\n /* 0xCD */ [Debugger8080.INS.CALL, Debugger8080.TYPE_ADDR],\n /* 0xCE */ [Debugger8080.INS.ACI, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_IMM | Debugger8080.TYPE_BYTE],\n /* 0xCF */ [Debugger8080.INS.RST, Debugger8080.TYPE_INT],\n /* 0xD0 */ [Debugger8080.INS.RNC],\n /* 0xD1 */ [Debugger8080.INS.POP, Debugger8080.TYPE_DE],\n /* 0xD2 */ [Debugger8080.INS.JNC, Debugger8080.TYPE_ADDR],\n /* 0xD3 */ [Debugger8080.INS.OUT, Debugger8080.TYPE_IMM | Debugger8080.TYPE_BYTE,Debugger8080.TYPE_A | Debugger8080.TYPE_OPT],\n /* 0xD4 */ [Debugger8080.INS.CNC, Debugger8080.TYPE_ADDR],\n /* 0xD5 */ [Debugger8080.INS.PUSH, Debugger8080.TYPE_DE],\n /* 0xD6 */ [Debugger8080.INS.SUI, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_IMM | Debugger8080.TYPE_BYTE],\n /* 0xD7 */ [Debugger8080.INS.RST, Debugger8080.TYPE_INT],\n /* 0xD8 */ [Debugger8080.INS.RC],\n /* 0xD9 */ [Debugger8080.INS.RET, Debugger8080.TYPE_UNDOC],\n /* 0xDA */ [Debugger8080.INS.JC, Debugger8080.TYPE_ADDR],\n /* 0xDB */ [Debugger8080.INS.IN, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_IMM | Debugger8080.TYPE_BYTE],\n /* 0xDC */ [Debugger8080.INS.CC, Debugger8080.TYPE_ADDR],\n /* 0xDD */ [Debugger8080.INS.CALL, Debugger8080.TYPE_ADDR | Debugger8080.TYPE_UNDOC],\n /* 0xDE */ [Debugger8080.INS.SBI, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_IMM | Debugger8080.TYPE_BYTE],\n /* 0xDF */ [Debugger8080.INS.RST, Debugger8080.TYPE_INT],\n /* 0xE0 */ [Debugger8080.INS.RPO],\n /* 0xE1 */ [Debugger8080.INS.POP, Debugger8080.TYPE_HL],\n /* 0xE2 */ [Debugger8080.INS.JPO, Debugger8080.TYPE_ADDR],\n /* 0xE3 */ [Debugger8080.INS.XTHL, Debugger8080.TYPE_SP | Debugger8080.TYPE_MEM| Debugger8080.TYPE_OPT, Debugger8080.TYPE_HL | Debugger8080.TYPE_OPT],\n /* 0xE4 */ [Debugger8080.INS.CPO, Debugger8080.TYPE_ADDR],\n /* 0xE5 */ [Debugger8080.INS.PUSH, Debugger8080.TYPE_HL],\n /* 0xE6 */ [Debugger8080.INS.ANI, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_IMM | Debugger8080.TYPE_BYTE],\n /* 0xE7 */ [Debugger8080.INS.RST, Debugger8080.TYPE_INT],\n /* 0xE8 */ [Debugger8080.INS.RPE],\n /* 0xE9 */ [Debugger8080.INS.PCHL, Debugger8080.TYPE_HL],\n /* 0xEA */ [Debugger8080.INS.JPE, Debugger8080.TYPE_ADDR],\n /* 0xEB */ [Debugger8080.INS.XCHG, Debugger8080.TYPE_HL | Debugger8080.TYPE_OPT, Debugger8080.TYPE_DE | Debugger8080.TYPE_OPT],\n /* 0xEC */ [Debugger8080.INS.CPE, Debugger8080.TYPE_ADDR],\n /* 0xED */ [Debugger8080.INS.CALL, Debugger8080.TYPE_ADDR | Debugger8080.TYPE_UNDOC],\n /* 0xEE */ [Debugger8080.INS.XRI, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_IMM | Debugger8080.TYPE_BYTE],\n /* 0xEF */ [Debugger8080.INS.RST, Debugger8080.TYPE_INT],\n /* 0xF0 */ [Debugger8080.INS.RP],\n /* 0xF1 */ [Debugger8080.INS.POP, Debugger8080.TYPE_PSW],\n /* 0xF2 */ [Debugger8080.INS.JP, Debugger8080.TYPE_ADDR],\n /* 0xF3 */ [Debugger8080.INS.DI],\n /* 0xF4 */ [Debugger8080.INS.CP, Debugger8080.TYPE_ADDR],\n /* 0xF5 */ [Debugger8080.INS.PUSH, Debugger8080.TYPE_PSW],\n /* 0xF6 */ [Debugger8080.INS.ORI, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_IMM | Debugger8080.TYPE_BYTE],\n /* 0xF7 */ [Debugger8080.INS.RST, Debugger8080.TYPE_INT],\n /* 0xF8 */ [Debugger8080.INS.RM],\n /* 0xF9 */ [Debugger8080.INS.SPHL, Debugger8080.TYPE_SP | Debugger8080.TYPE_OPT, Debugger8080.TYPE_HL | Debugger8080.TYPE_OPT],\n /* 0xFA */ [Debugger8080.INS.JM, Debugger8080.TYPE_ADDR],\n /* 0xFB */ [Debugger8080.INS.EI],\n /* 0xFC */ [Debugger8080.INS.CM, Debugger8080.TYPE_ADDR],\n /* 0xFD */ [Debugger8080.INS.CALL, Debugger8080.TYPE_ADDR | Debugger8080.TYPE_UNDOC],\n /* 0xFE */ [Debugger8080.INS.CPI, Debugger8080.TYPE_A | Debugger8080.TYPE_OPT, Debugger8080.TYPE_IMM | Debugger8080.TYPE_BYTE],\n /* 0xFF */ [Debugger8080.INS.RST, Debugger8080.TYPE_INT]\n ];\n\n Debugger8080.HISTORY_LIMIT = DEBUG? 100000 : 1000;\n\n /*\n * Initialize every Debugger module on the page (as IF there's ever going to be more than one ;-))\n */\n Web.onInit(Debugger8080.init);\n\n} // endif DEBUGGER\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pc8080/lib/computer.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * TODO: The Closure Compiler treats ES6 classes as 'struct' rather than 'dict' by default,\n * which would force us to declare all class properties in the constructor, as well as prevent\n * us from defining any named properties. So, for now, we mark all our classes as 'unrestricted'.\n *\n * @unrestricted\n */\nclass Computer8080 extends Component {\n /**\n * Computer8080(parmsComputer, parmsMachine, fSuspended)\n *\n * The Computer8080 component has no required (parmsComputer) properties, but it does\n * support the following:\n *\n * autoPower: true to automatically power the computer (default), false to wait;\n * false is honored only if a \"power\" button binding exists.\n *\n * busWidth: number of memory address lines (address bits) on the computer's \"bus\";\n * 20 is the minimum (and the default), which implies 8086/8088 real-mode addressing,\n * while 24 is required for 80286 protected-mode addressing. This value is passed\n * directly through to the Bus component; see that component for more details.\n *\n * resume: one of the Computer8080.RESUME constants, which are as follows:\n * '0' if resume disabled (default)\n * '1' if enabled without prompting\n * '2' if enabled with prompting\n * '3' if enabled with prompting and auto-delete\n * or a string containing the path of a predefined JSON-encoded state\n *\n * state: the path to JSON-encoded state file (see details regarding 'state' below)\n *\n * The parmsMachine object, if provided, may contain any of:\n *\n * autoMount: if set, this should override any 'autoMount' property in the FDC's\n * parmsFDC object.\n *\n * autoPower: if set, this should override any 'autoPower' property in the Computer8080's\n * parmsComputer object.\n *\n * messages: if set, this should override any 'messages' property in the Debugger's\n * parmsDbg object.\n *\n * state: if set, this should override any 'state' property in the Computer8080's\n * parmsComputer object.\n *\n * url: the location of the machine XML file\n *\n * If a predefined state is supplied AND it's successfully loaded, then resume behavior\n * defaults to '1' (ie, resume enabled without prompting).\n *\n * This component insures that all components are ready before \"powering\" them.\n *\n * Different components become ready at different times, and initialization order (ie,\n * the order the scripts are combined on the page) only partially determines readiness.\n * This is because components like ROM and Video must finish loading their resource files\n * before they are ready. Other components become ready after we call their initBus()\n * function, because they have a Bus or CPU dependency, such as access to memory management\n * functions. And other components, like CPU and Panel, are ready as soon as their\n * constructor finishes.\n *\n * Once a component has indicated it's ready, we call its powerUp() notification\n * function (if it has one--it's optional). We call the CPU's powerUp() function last,\n * so that the CPU is assured that all other components are ready and \"powered\".\n *\n * @this {Computer8080}\n * @param {Object} parmsComputer\n * @param {Object} [parmsMachine]\n * @param {boolean} [fSuspended]\n */\n constructor(parmsComputer, parmsMachine, fSuspended)\n {\n super(\"Computer\", parmsComputer, Messages8080.COMPUTER);\n\n this.flags.powered = false;\n\n this.setMachineParms(parmsMachine);\n\n this.fAutoPower = this.getMachineParm('autoPower', parmsComputer);\n\n /*\n * nPowerChange is 0 while the power state is stable, 1 while power is transitioning\n * to \"on\", and -1 while power is transitioning to \"off\".\n */\n this.nPowerChange = 0;\n\n /*\n * TODO: Deprecate 'buswidth' (it should have always used camelCase)\n */\n this.nBusWidth = parmsComputer['busWidth'] || parmsComputer['buswidth'];\n\n this.resume = Computer8080.RESUME_NONE;\n this.sStateData = null;\n this.fStateData = false; // remembers if sStateData was loaded\n this.fServerState = false;\n\n this.url = this.getMachineParm('url') || \"\";\n\n /*\n * Generate a random number x (where 0 <= x < 1), add 0.1 so that it's guaranteed to be\n * non-zero, convert to base 36, and chop off the leading digit and \"decimal\" point.\n */\n this.sMachineID = (Math.random() + 0.1).toString(36).substr(2,12);\n this.sUserID = this.queryUserID();\n\n /*\n * Find the appropriate CPU (and Debugger and Control Panel, if any)\n *\n * CLOSURE COMPILER TIP: To override the type of a right-hand expression (as we need to do here,\n * where we know getComponentByType() will only return an CPUState object or null), wrap the expression\n * in parentheses. I never knew this until I stumbled across it in \"Closure: The Definitive Guide\".\n */\n this.cpu = /** @type {CPUState8080} */ (Component.getComponentByType(\"CPU\", this.id));\n if (!this.cpu) {\n Component.error(\"Unable to find CPU component\");\n return;\n }\n this.dbg = /** @type {Debugger8080} */ (Component.getComponentByType(\"Debugger\", this.id));\n\n /*\n * Enumerate all Video components for future updateVideo() calls.\n */\n this.aVideo = [];\n for (var video = null; (video = this.getMachineComponent(\"Video\", video));) {\n this.aVideo.push(video);\n }\n\n /*\n * Initialize the Bus component\n */\n this.bus = new Bus8080({'id': this.idMachine + '.bus', 'busWidth': this.nBusWidth}, this.cpu, this.dbg);\n\n /*\n * Iterate through all the components and connect them to the Control Panel, if any\n */\n var iComponent, component;\n var aComponents = Component.getComponents(this.id);\n\n this.panel = /** @type {Panel8080} */ (Component.getComponentByType(\"Panel\", this.id));\n this.controlPrint = this.panel && this.panel.bindings['print'];\n\n if (this.controlPrint) {\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n /*\n * I can think of many \"cleaner\" ways for the Control Panel component to pass its\n * notice(), println(), etc, overrides on to all the other components, but it's just\n * too darn convenient to slam those overrides into the components directly.\n */\n component.notice = this.panel.notice;\n component.print = this.panel.print;\n component.println = this.panel.println;\n }\n }\n\n this.println(PC8080.APPNAME + \" v\" + (XMLVERSION || PC8080.APPVERSION) + \"\\n\" + COPYRIGHT + \"\\n\" + LICENSE);\n\n if (DEBUG && this.messageEnabled()) this.printMessage(\"TYPEDARRAYS: \" + TYPEDARRAYS);\n\n /*\n * Iterate through all the components again and call their initBus() handler, if any\n */\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component.initBus) component.initBus(this, this.bus, this.cpu, this.dbg);\n }\n\n var sStatePath = null;\n var sResume = this.getMachineParm('resume', parmsComputer);\n if (sResume !== undefined) {\n /*\n * Decide whether the 'resume' property is a number or the path of a state file to resume.\n */\n if (sResume.length > 1) {\n sStatePath = this.sResumePath = sResume;\n } else {\n this.resume = parseInt(sResume, 10);\n }\n }\n\n /*\n * The Computer 'state' property allows a state file to be specified independent of the 'resume' feature;\n * previously, you could only use 'resume' to load a state file -- which we still support, but loading a state\n * file that way prevents the machine's state from being saved, since we always resume from the 'resume' file.\n *\n * The other wrinkle is on the restore side: we need to IGNORE the 'state' property if a saved state now exists.\n * So we have to peek at localStorage, and unfortunately, the only way to \"peek\" is to actually load the data,\n * but we're not ready to use it yet, so powerUp() has been changed to use any existing stateComputer that we've\n * already loaded.\n *\n * However, there's now a wrinkle to the wrinkle: if a 'state' parameter has been passed via the URL, then that\n * OVERRIDES everything; it overrides any 'state' Computer parameter AND it disables resume of any saved state in\n * localStorage (in other words, it prevents fAllowResume from being true, and forcing resume off).\n */\n var fAllowResume;\n var sState = this.getMachineParm('state') || (fAllowResume = true) && parmsComputer['state'];\n\n if (sState) {\n sStatePath = this.sStatePath = sState;\n if (!fAllowResume) {\n this.fServerState = true;\n this.resume = Computer8080.RESUME_NONE;\n }\n if (this.resume) {\n this.stateComputer = new State(this, PC8080.APPVERSION);\n if (this.stateComputer.load()) {\n sStatePath = null;\n } else {\n delete this.stateComputer;\n }\n }\n }\n\n /*\n * If sStatePath is set, we must use it. But if there's no sStatePath AND resume is set,\n * then we have the option of resuming from a server-side state, assuming a valid USERID.\n */\n if (!sStatePath && this.resume) {\n sStatePath = this.getServerStatePath();\n if (sStatePath) this.fServerState = true;\n }\n\n if (!sStatePath) {\n this.setReady();\n } else {\n var cmp = this;\n Web.getResource(sStatePath, null, true, function(sURL, sResource, nErrorCode) {\n cmp.doneLoad(sURL, sResource, nErrorCode);\n });\n }\n\n if (!this.bindings[\"power\"]) this.fAutoPower = true;\n\n /*\n * Power on the computer, giving every component the opportunity to reset or restore itself.\n */\n if (!fSuspended && this.fAutoPower) this.wait(this.powerOn);\n }\n\n /**\n * clearPanel()\n *\n * @this {Computer8080}\n */\n clearPanel()\n {\n if (this.controlPrint) {\n this.controlPrint.value = \"\";\n }\n }\n\n /**\n * getMachineID()\n *\n * @this {Computer8080}\n * @return {string}\n */\n getMachineID()\n {\n return this.sMachineID;\n }\n\n /**\n * setMachineParms(parmsMachine)\n *\n * If no explicit machine parms were provided, then we check for 'parms' in the bundled resources (if any).\n *\n * @this {Computer8080}\n * @param {Object} [parmsMachine]\n */\n setMachineParms(parmsMachine)\n {\n if (!parmsMachine) {\n var sParms;\n if (typeof resources == 'object' && (sParms = resources['parms'])) {\n try {\n parmsMachine = /** @type {Object} */ (eval(\"(\" + sParms + \")\"));\n } catch(e) {\n Component.error(e.message + \" (\" + sParms + \")\");\n }\n }\n }\n this.parmsMachine = parmsMachine;\n }\n\n /**\n * getMachineParm(sParm, parmsComponent)\n *\n * If the machine parameter doesn't exist, we check for a matching component parameter (if parmsComponent is provided),\n * and failing that, we check the bundled resources (if any).\n *\n * At the moment, the only bundled resource request we expect to encounter is 'state'; if it exists, then we return\n * 'state' back to the caller (ie, the name of the resource), so that the caller will then attempt to load the 'state'\n * resource to obtain the actual state.\n *\n * @this {Computer8080}\n * @param {string} sParm\n * @param {Object} [parmsComponent]\n * @return {string|undefined}\n */\n getMachineParm(sParm, parmsComponent)\n {\n /*\n * When using getURLParm(), the check is allowed be a bit looser, because URL parameters are\n * user-supplied, whereas most other parameters are developer-supplied. Granted, a developer\n * may also be sloppy and neglect to use correct case (eg, 'automount' instead of 'autoMount'),\n * but there are limits to my paranoia.\n */\n var sParmLC = sParm.toLowerCase();\n var value = Web.getURLParm(sParm) || Web.getURLParm(sParmLC);\n\n if (value === undefined && this.parmsMachine) {\n value = this.parmsMachine[sParm];\n }\n if (value === undefined && parmsComponent) {\n value = parmsComponent[sParm];\n }\n if (value === undefined && typeof resources == 'object' && resources[sParm]) {\n value = sParm;\n }\n return value;\n }\n\n /**\n * saveMachineParms()\n *\n * @this {Computer8080}\n * @return {string|null}\n */\n saveMachineParms()\n {\n return this.parmsMachine? JSON.stringify(this.parmsMachine) : null;\n }\n\n /**\n * getUserID()\n *\n * @this {Computer8080}\n * @return {string}\n */\n getUserID()\n {\n return this.sUserID || \"\";\n }\n\n /**\n * doneLoad(sURL, sStateData, nErrorCode)\n *\n * @this {Computer8080}\n * @param {string} sURL\n * @param {string} sStateData\n * @param {number} nErrorCode\n */\n doneLoad(sURL, sStateData, nErrorCode)\n {\n if (!nErrorCode) {\n this.sStateData = sStateData;\n this.fStateData = true;\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"loaded state file \" + sURL.replace(this.sUserID || \"xxx\", \"xxx\"));\n }\n } else {\n this.sResumePath = null;\n this.fServerState = false;\n this.notice('Unable to load machine state from server (error ' + nErrorCode + (sStateData? ': ' + Str.trim(sStateData) : '') + ')');\n }\n this.setReady();\n }\n\n /**\n * wait(fn, parms)\n *\n * wait() waits until every component is ready (including ourselves, the last component we check), then calls the\n * specified Computer method.\n *\n * TODO: The Closure Compiler makes it difficult for us to define a function type for \"fn\" that works in all cases;\n * sometimes we want to pass a function that takes only a \"number\", and other times we want to pass a function that\n * takes only an \"Array\" (the type will mirror that of the \"parms\" parameter). However, the Closure Compiler insists\n * that both functions must be declared as accepting both types of parameters. So once again, we must use an untyped\n * function declaration, instead of something stricter like:\n *\n * param {function(this:Computer, (number|Array|undefined)): undefined} fn\n *\n * @this {Computer8080}\n * @param {function(...)} fn\n * @param {number|Array} [parms] optional parameters\n */\n wait(fn, parms)\n {\n var computer = this;\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent <= aComponents.length; iComponent++) {\n var component = (iComponent < aComponents.length ? aComponents[iComponent] : this);\n if (!component.isReady()) {\n component.isReady(function onComponentReady() {\n computer.wait(fn, parms);\n });\n return;\n }\n }\n if (DEBUG && this.messageEnabled()) this.printMessage(\"Computer8080.wait(ready)\");\n fn.call(this, parms);\n }\n\n /**\n * validateState(stateComputer)\n *\n * NOTE: We clear() stateValidate only when there's no stateComputer.\n *\n * @this {Computer8080}\n * @param {State|null} [stateComputer]\n * @return {boolean} true if state passes validation, false if not\n */\n validateState(stateComputer)\n {\n var fValid = true;\n var stateValidate = new State(this, PC8080.APPVERSION, Computer8080.STATE_VALIDATE);\n if (stateValidate.load() && stateValidate.parse()) {\n var sTimestampValidate = stateValidate.get(Computer8080.STATE_TIMESTAMP);\n var sTimestampComputer = stateComputer? stateComputer.get(Computer8080.STATE_TIMESTAMP) : \"unknown\";\n if (sTimestampValidate != sTimestampComputer) {\n this.notice(\"Machine state may be out-of-date\\n(\" + sTimestampValidate + \" vs. \" + sTimestampComputer + \")\\nCheck your browser's local storage limits\");\n fValid = false;\n if (!stateComputer) stateValidate.clear();\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"Last state: \" + sTimestampComputer + \" (validate: \" + sTimestampValidate + \")\");\n }\n }\n }\n return fValid;\n }\n\n /**\n * powerOn(resume)\n *\n * Power every component \"up\", applying any previously available state information.\n *\n * @this {Computer8080}\n * @param {number} [resume] is a valid RESUME value; default is this.resume\n */\n powerOn(resume)\n {\n if (resume === undefined) {\n resume = this.resume || (this.sStateData? Computer8080.RESUME_AUTO : Computer8080.RESUME_NONE);\n }\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"Computer8080.powerOn(\" + (resume == Computer8080.RESUME_REPOWER ? \"repower\" : (resume ? \"resume\" : \"\")) + \")\");\n }\n\n if (this.nPowerChange) {\n return;\n }\n this.nPowerChange++;\n\n var fRepower = false;\n var fRestore = false;\n this.fRestoreError = false;\n var stateComputer = this.stateComputer || new State(this, PC8080.APPVERSION);\n\n if (resume == Computer8080.RESUME_REPOWER) {\n fRepower = true;\n }\n else if (resume > Computer8080.RESUME_NONE) {\n if (stateComputer.load(this.sStateData)) {\n /*\n * Since we're resuming something (either a predefined state or a state from localStorage), let's\n * create a \"failsafe\" checkpoint in localStorage, and destroy it at the end of a successful powerOn().\n * Which means, of course, that if a previous \"failsafe\" checkpoint already exists, something bad\n * may have happened the last time around.\n */\n this.stateFailSafe = new State(this, PC8080.APPVERSION, Computer8080.STATE_FAILSAFE);\n if (this.stateFailSafe.load()) {\n this.powerReport(stateComputer);\n /*\n * We already know resume is something other than RESUME_NONE, so we'll go ahead and bump it\n * all the way to RESUME_PROMPT, so that the user will be prompted, and if the user declines to\n * restore, the state will be removed.\n */\n resume = Computer8080.RESUME_PROMPT;\n /*\n * To ensure that the set() below succeeds, we need to call unload(), otherwise it may fail\n * with a \"read only\" error (eg, \"TypeError: Cannot assign to read only property 'timestamp'\").\n */\n this.stateFailSafe.unload();\n }\n\n this.stateFailSafe.set(Computer8080.STATE_TIMESTAMP, Usr.getTimestamp());\n this.stateFailSafe.store();\n\n var fValidate = this.resume && !this.fServerState;\n if (resume == Computer8080.RESUME_AUTO || Component.confirmUser(\"Click OK to restore the previous \" + PC8080.APPNAME + \" machine state, or CANCEL to reset the machine.\")) {\n fRestore = stateComputer.parse();\n if (fRestore) {\n var sCode = /** @type {string} */ (stateComputer.get(UserAPI.RES.CODE));\n var sData = /** @type {string} */ (stateComputer.get(UserAPI.RES.DATA));\n if (sCode) {\n if (sCode == UserAPI.CODE.OK) {\n stateComputer.load(sData);\n } else {\n /*\n * A missing (or not yet created) state file is no cause for alarm, but other errors might be\n */\n if (sCode == UserAPI.CODE.FAIL && sData != UserAPI.FAIL.NOSTATE) {\n this.notice(\"Error: \" + sData);\n if (sData == UserAPI.FAIL.VERIFY) this.resetUserID();\n } else {\n this.println(sCode + \": \" + sData);\n }\n /*\n * Try falling back to the state that we should have saved in localStorage, as a backup to the\n * server-side state.\n */\n stateComputer.unload(); // discard the invalid server-side state first\n if (stateComputer.load()) {\n fRestore = stateComputer.parse();\n fValidate = true;\n } else {\n fRestore = false; // hmmm, there was nothing in localStorage either\n }\n }\n }\n }\n /*\n * If the load/parse was successful, and it was from localStorage (not sStateData),\n * then we should to try verify that localStorage snapshot is current. One reason it may\n * NOT be current is if localStorage was full and we got a quota error during the last\n * powerOff().\n */\n if (fValidate) this.validateState(fRestore? stateComputer : null);\n } else {\n /*\n * RESUME_PROMPT indicates we should delete the state if they clicked Cancel to confirm() above.\n */\n if (resume == Computer8080.RESUME_PROMPT) stateComputer.clear();\n }\n } else {\n /*\n * If there's no state, then there should also be no validation timestamp; if there is, then once again,\n * we're probably dealing with a quota error.\n */\n this.validateState();\n }\n delete this.sStateData;\n delete this.stateComputer;\n }\n\n /*\n * Start powering all components, including any data they may need to restore their state;\n * we restore power to the CPU last.\n */\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component !== this && component != this.cpu) {\n fRestore = this.powerRestore(component, stateComputer, fRepower, fRestore);\n }\n }\n\n /*\n * Assuming this is not a repower, we must perform another wait, because some components may\n * have marked themselves as \"not ready\" again (eg, the FDC component, if the restore forced it\n * to mount one or more additional disk images).\n */\n var aParms = [stateComputer, resume, fRestore];\n\n if (resume != Computer8080.RESUME_REPOWER) {\n this.wait(this.donePowerOn, aParms);\n return;\n }\n this.donePowerOn(aParms);\n }\n\n /**\n * powerRestore(component, stateComputer, fRepower, fRestore)\n *\n * @this {Computer8080}\n * @param {Component} component\n * @param {State} stateComputer\n * @param {boolean} fRepower\n * @param {boolean} fRestore\n * @return {boolean} true if restore should continue, false if not\n */\n powerRestore(component, stateComputer, fRepower, fRestore)\n {\n if (!component.flags.powered) {\n\n component.flags.powered = true;\n\n if (component.powerUp) {\n\n var data = null;\n if (fRestore) {\n data = stateComputer.get(component.id);\n if (!data) {\n /*\n * This is a hack that makes it possible for a machine whose ID has been\n * supplemented with a hyphenated numeric suffix to find object IDs in states\n * created from a machine without such a suffix.\n *\n * For example, if a state file was created from a machine with ID \"ibm5160\"\n * but the current machine is \"ibm5160-1\", this attempts a second lookup with\n * \"ibm5160\", enabling us to find objects that match the original machine ID\n * (eg, \"ibm5160.romEGA\").\n *\n * See /devices/pcx86/machine/5160/ega/640kb/array/ for examples of this.\n */\n data = stateComputer.get(component.id.replace(/-[0-9]+\\./i, '.'));\n }\n }\n\n /*\n * State.get() will return whatever was originally passed to State.set() (eg, an\n * Object or a string), but components are supposed to store only Objects, so if a\n * string comes back, something went wrong. By explicitly eliminating \"string\" data,\n * the Closure Compiler stops complaining that we might be passing strings to our\n * powerUp() functions (even though we know we're not).\n *\n * TODO: Determine if there's some way to coerce the Closure Compiler into treating\n * data as Object or null, without having to include this runtime check. An assert\n * would be a good idea, but this is overkill.\n */\n if (typeof data === \"string\") data = null;\n\n /*\n * If computer is null, this is simply a repower notification, which most components\n * don't do anything with. Exceptions include: CPU (since it may be halted) and Video\n * (since its screen may be \"turned off\").\n */\n if (!component.powerUp(data, fRepower) && data) {\n\n Component.error(\"Unable to restore state for \" + component.type);\n /*\n * If this is a resume error for a machine that also has a predefined state\n * AND we're not restoring from that state, then throw away the current state,\n * prevent any new state from being created, and then force a reload, which will\n * hopefully restore us to the functioning predefined state.\n *\n * TODO: Considering doing this in ALL cases, not just in situations where a\n * 'state' exists but we're not actually resuming from it.\n */\n if (this.sStatePath && !this.fStateData) {\n stateComputer.clear();\n this.resume = Computer8080.RESUME_NONE;\n Web.reloadPage();\n } else {\n /*\n * In all other cases, we set fRestoreError, which should trigger a call to\n * powerReport() and then delete the offending state.\n */\n this.fRestoreError = true;\n }\n /*\n * Any failure triggers an automatic to call powerUp() again, without any state,\n * in the hopes that the component can recover by performing a reset.\n */\n component.powerUp(null);\n /*\n * We also disable the rest of the restore operation, because it's not clear\n * the remaining state information can be trusted; the machine is already in an\n * inconsistent state, so we're not likely to make things worse, and the only\n * alternative (starting over and performing a state-less reset) isn't likely to make\n * the user any happier. But, we'll see... we need some experience with the code.\n */\n fRestore = false;\n }\n }\n\n if (!fRepower && component.comment) {\n var asComments = component.comment.split(\"|\");\n for (var i = 0; i < asComments.length; i++) {\n component.status(asComments[i]);\n }\n }\n }\n return fRestore;\n }\n\n /**\n * donePowerOn(aParms)\n *\n * This is nothing more than a continuation of powerOn(), giving us the option of calling wait() one more time.\n *\n * @this {Computer8080}\n * @param {Array} aParms containing [stateComputer, resume, fRestore]\n */\n donePowerOn(aParms)\n {\n var stateComputer = aParms[0];\n var fRepower = (aParms[1] < 0);\n var fRestore = aParms[2];\n\n if (DEBUG && this.flags.powered && this.messageEnabled()) {\n this.printMessage(\"Computer8080.donePowerOn(): redundant\");\n }\n\n this.fInitialized = true;\n this.flags.powered = true;\n var controlPower = this.bindings[\"power\"];\n if (controlPower) controlPower.textContent = \"Shutdown\";\n\n /*\n * Once we get to this point, we're guaranteed that all components are ready, so it's safe to power the CPU;\n * the CPU should begin executing immediately, unless a debugger is attached.\n */\n if (this.cpu) {\n /*\n * TODO: Do we not care about the return value here? (ie, is checking fRestoreError sufficient)?\n */\n this.powerRestore(this.cpu, stateComputer, fRepower, fRestore);\n this.cpu.autoStart();\n }\n\n /*\n * If the state was bad, offer to report it and then delete it. Deleting may be moot, since invariably a new\n * state will be created on powerOff() before the next powerOn(), but it seems like good paranoia all the same.\n */\n if (this.fRestoreError) {\n this.powerReport(stateComputer);\n stateComputer.clear();\n }\n\n if (!fRepower && this.stateFailSafe) {\n this.stateFailSafe.clear();\n delete this.stateFailSafe;\n }\n\n this.nPowerChange = 0;\n }\n\n /**\n * checkPower()\n *\n * @this {Computer8080}\n * @return {boolean} true if the computer is fully powered, false otherwise\n */\n checkPower()\n {\n if (this.flags.powered) return true;\n\n var component = null, iComponent;\n var aComponents = Component.getComponents(this.id);\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component !== this && !component.flags.ready) break;\n }\n if (iComponent == aComponents.length) {\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component !== this && !component.flags.powered) break;\n }\n }\n if (iComponent == aComponents.length) component = this;\n var s = \"The \" + component.type + \" component (\" + component.id + \") is not \" + (!component.flags.ready? \"ready yet\" + (component.fnReady? \" (waiting for notification)\" : \"\") : \"powered yet\") + \".\";\n Component.alertUser(s);\n return false;\n }\n\n /**\n * powerReport(stateComputer)\n *\n * @this {Computer8080}\n * @param {State} stateComputer\n */\n powerReport(stateComputer)\n {\n if (Component.confirmUser(\"There may be a problem with your \" + PC8080.APPNAME + \" machine.\\n\\nTo help us diagnose it, click OK to send this \" + PC8080.APPNAME + \" machine state to http://\" + SITEHOST + \".\")) {\n Web.sendReport(PC8080.APPNAME, PC8080.APPVERSION, this.url, this.getUserID(), ReportAPI.TYPE.BUG, stateComputer.toString());\n }\n }\n\n /**\n * powerOff(fSave, fShutdown)\n *\n * Power every component \"down\" and optionally save the machine state.\n *\n * There's one scenario that powerOff() isn't currently able to deal with very effectively: what to do when\n * the user switches away while it's still being restored, causing Disk getResource() calls to fail. The\n * Disk component calls notify() when that happens -- see Disk.mount() -- but the FDC and HDC controllers don't\n * notify *us* of those problems, so Computer assumes that the restore was completely successful, when in fact\n * it was only partially successful.\n *\n * Then we immediately arrive here to perform a save, following that incomplete restore. It would be wrong to\n * deal with that incomplete restore by setting fRestoreError, because we don't want to trigger a powerReport()\n * and the deletion of the previous state, because the state itself was presumably OK. Unfortunately, the new\n * state we now save will no longer include manually mounted disk images whose remounts were interrupted, so future\n * restores won't remount them either.\n *\n * We could perhaps solve this by having the Disk component notify us in those situations, set a new flag\n * (fRestoreIncomplete?), and set fSave to false if that's ever set. Be careful though: when fSave is false,\n * that means MORE than not saving; it also means deleting any previous state, which is NOT what you'd want to\n * do in a \"fRestoreIncomplete\" situation. Also, we have to worry about Disk operations that fail for other reasons,\n * making sure those failures don't interfere with the save process in the same way.\n *\n * As it stands, the worst that happens is any manually mounted disk images might have to be manually remounted,\n * which doesn't seem like a huge problem.\n *\n * @this {Computer8080}\n * @param {boolean} [fSave] is true to request a saved state\n * @param {boolean} [fShutdown] is true if the machine is being shut down\n * @return {string|null} string representing the saved state (or null if error)\n */\n powerOff(fSave, fShutdown)\n {\n var data;\n var sState = \"none\";\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"Computer8080.powerOff(\" + (fSave ? \"save\" : \"nosave\") + (fShutdown ? \",shutdown\" : \"\") + \")\");\n }\n\n if (this.nPowerChange) {\n return null;\n }\n this.nPowerChange--;\n\n var stateComputer = new State(this, PC8080.APPVERSION);\n var stateValidate = new State(this, PC8080.APPVERSION, Computer8080.STATE_VALIDATE);\n\n var sTimestamp = Usr.getTimestamp();\n stateValidate.set(Computer8080.STATE_TIMESTAMP, sTimestamp);\n stateComputer.set(Computer8080.STATE_TIMESTAMP, sTimestamp);\n stateComputer.set(Computer8080.STATE_VERSION, APPVERSION);\n stateComputer.set(Computer8080.STATE_HOSTURL, Web.getHostURL());\n stateComputer.set(Computer8080.STATE_BROWSER, Web.getUserAgent());\n\n /*\n * Always power the CPU \"down\" first, just to help insure it doesn't ask other components to do anything\n * after they're no longer ready.\n */\n if (this.cpu && this.cpu.powerDown) {\n if (fShutdown) this.cpu.stopCPU();\n data = this.cpu.powerDown(fSave, fShutdown);\n if (typeof data === \"object\") stateComputer.set(this.cpu.id, data);\n if (fShutdown) {\n this.cpu.flags.powered = false;\n if (data === false) sState = null;\n }\n }\n\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.flags.powered) {\n if (component.powerDown) {\n data = component.powerDown(fSave, fShutdown);\n if (typeof data === \"object\") stateComputer.set(component.id, data);\n }\n if (fShutdown) {\n component.flags.powered = false;\n if (data === false) sState = null;\n }\n }\n }\n\n if (sState) {\n if (fShutdown) {\n var fClear = false;\n var fClearAll = false;\n if (fSave) {\n if (this.sUserID) {\n this.saveServerState(this.sUserID, stateComputer.toString());\n }\n if (!stateValidate.store() || !stateComputer.store()) {\n sState = null;\n /*\n * New behavior as of v1.13.2: if it appears that localStorage is full, we blow it ALL away.\n * Dedicated server-side storage is the only way we'll ever be able to reliably preserve a\n * particular machine's state. Historically, attempting to limp along with whatever localStorage\n * is left just generates the same useless and annoying warnings over and over.\n */\n fClear = fClearAll = true;\n }\n }\n else {\n /*\n * I used to ALWAYS clear (ie, delete) any associated computer state, but now I do this only if the\n * current machine is \"resumable\", because there are situations where I have two configurations\n * for the same machine -- one resumable and one not -- and I don't want the latter throwing away the\n * state of the former.\n *\n * So this code is here now strictly for callers to delete the state of a \"resumable\" machine, not as\n * some paranoid clean-up operation.\n *\n * An undocumented feature of this operation is that if your configuration uses the special 'resume=\"3\"'\n * value, and you click the \"Reset\" button, and then you click OK to reset the everything, this will\n * actually reset EVERYTHING (ie, all localStorage for ALL configs will be reclaimed).\n */\n if (this.resume) {\n fClear = true;\n fClearAll = (this.resume == Computer8080.RESUME_DELETE);\n }\n }\n if (fClear) {\n stateComputer.clear(fClearAll);\n }\n } else {\n sState = stateComputer.toString();\n }\n }\n\n if (fShutdown) {\n this.flags.powered = false;\n var controlPower = this.bindings[\"power\"];\n if (controlPower) controlPower.textContent = \"Power\";\n }\n\n this.nPowerChange = 0;\n\n return sState;\n }\n\n /**\n * reset()\n *\n * Notify all (other) components with a reset() method that the Computer is being reset.\n *\n * NOTE: We'd like to reset the Bus first (due to the importance of the A20 line), but since we\n * allocated the Bus object ourselves, after all the other components were allocated, it ends\n * up near the end of Component's list of components. Hence the special case for this.bus below.\n *\n * @this {Computer8080}\n */\n reset()\n {\n if (this.bus && this.bus.reset) {\n /*\n * TODO: Why does WebStorm think that this.bus.type is undefined? The base class (Component)\n * constructor defines it.\n */\n this.printMessage(\"Resetting \" + this.bus.type);\n this.bus.reset();\n }\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component !== this && component !== this.bus && component.reset) {\n this.printMessage(\"Resetting \" + component.type);\n component.reset();\n }\n }\n }\n\n /**\n * start(ms, nCycles)\n *\n * Notify all (other) components with a start() method that the CPU has started.\n *\n * Note that we're called by runCPU(), which is why we exclude the CPU component,\n * as well as ourselves.\n *\n * @this {Computer8080}\n * @param {number} ms\n * @param {number} nCycles\n */\n start(ms, nCycles)\n {\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.type == \"CPU\" || component === this) continue;\n if (component.start) {\n component.start(ms, nCycles);\n }\n }\n }\n\n /**\n * stop(ms, nCycles)\n *\n * Notify all (other) components with a stop() method that the CPU has stopped.\n *\n * Note that we're called by runCPU(), which is why we exclude the CPU component,\n * as well as ourselves.\n *\n * @this {Computer8080}\n * @param {number} ms\n * @param {number} nCycles\n */\n stop(ms, nCycles)\n {\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.type == \"CPU\" || component === this) continue;\n if (component.stop) {\n component.stop(ms, nCycles);\n }\n }\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {Computer8080}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var computer = this;\n\n switch (sBinding) {\n case \"power\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickPower() {\n computer.onPower();\n };\n return true;\n\n case \"reset\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickReset() {\n computer.onReset();\n };\n return true;\n\n /*\n * Technically, this binding should now be called \"saveState\", to clearly distinguish it from\n * the \"Save Machine\" control that's normally bound to the savePC() function in save.js. Saving\n * an entire machine includes everything needed to start/restore the machine; eg, the machine\n * XML configuration file(s) *and* the JSON-encoded machine state.\n */\n case \"save\":\n /*\n * Since this feature depends on the server supporting the PCjs User API (see userapi.js),\n * and since pcjs.org is no longer running a Node web server, we disable the feature for that\n * particular host.\n */\n if (Str.endsWith(Web.getHost(), \"pcjs.org\")) {\n if (DEBUG) this.log(\"Remote user API not available\");\n /*\n * We could also simply hide the control; eg:\n *\n * control.style.display = \"none\";\n *\n * but removing the control altogether seems better.\n */\n control.parentNode.removeChild(/** @type {Node} */ (control));\n return false;\n }\n this.bindings[sBinding] = control;\n control.onclick = function onClickSave() {\n var sUserID = computer.queryUserID(true);\n if (sUserID) {\n /*\n * I modified the test to include a check for sStatePath so that I could save new states\n * for machines with existing states; otherwise, I'd have no (easy) way of capturing and\n * updating their state. Making the machine (even temporarily) resumable would have been\n * one work-around, but it's not appropriate for some machines, as their state is simply\n * too large (for localStorage anyway, which is the default storage solution).\n */\n var fSave = !!(computer.resume && !computer.sResumePath || computer.sStatePath);\n var sState = computer.powerOff(fSave);\n if (fSave) {\n computer.saveServerState(sUserID, sState);\n } else {\n computer.notice(\"Resume disabled, machine state not saved\");\n }\n }\n /*\n * This seemed like a handy alternative, but it turned out to be a no-go, at least for large states:\n *\n * var sState = computer.powerOff(true);\n * if (sState) {\n * sState = \"data:text/json;charset=utf-8,\" + encodeURIComponent(sState);\n * window.open(sState);\n * }\n *\n * Perhaps if I embedded the data in a link on the current page instead; eg:\n *\n * $('<a href=\"' + sState + '\" download=\"state.json\">Download</a>').appendTo('#container');\n */\n };\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * resetUserID()\n */\n resetUserID()\n {\n Web.setLocalStorageItem(Computer8080.STATE_USERID, \"\");\n this.sUserID = null;\n }\n\n /**\n * queryUserID(fPrompt)\n *\n * @param {boolean} [fPrompt]\n * @returns {string|null|undefined}\n */\n queryUserID(fPrompt)\n {\n var sUserID = this.sUserID;\n if (!sUserID) {\n sUserID = Web.getLocalStorageItem(Computer8080.STATE_USERID);\n if (sUserID !== undefined) {\n if (!sUserID && fPrompt) {\n /*\n * NOTE: Warning the user here that \"Save\" operations are not currently supported by pcjs.org is\n * merely a precaution, because ordinarily, setBinding() should have already determined if we are\n * running from pcjs.org and disabled any \"Save\" button.\n */\n sUserID = Component.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.\");\n if (sUserID) {\n sUserID = this.verifyUserID(sUserID);\n if (!sUserID) this.notice(\"The user ID is invalid.\");\n }\n }\n } else if (fPrompt) {\n this.notice(\"Browser local storage is not available\");\n }\n }\n return sUserID;\n }\n\n /**\n * verifyUserID(sUserID)\n *\n * @this {Computer8080}\n * @param {string} sUserID\n * @return {string} validated user ID, or null if error\n */\n verifyUserID(sUserID)\n {\n this.sUserID = null;\n var fMessages = DEBUG && this.messageEnabled();\n if (fMessages) this.printMessage(\"verifyUserID(\" + sUserID + \")\");\n var sRequest = Web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.VERIFY + '&' + UserAPI.QUERY.USER + '=' + sUserID;\n var response = Web.getResource(sRequest);\n var nErrorCode = response[0];\n var sResponse = response[1];\n if (!nErrorCode && sResponse) {\n try {\n response = eval(\"(\" + sResponse + \")\");\n if (response.code && response.code == UserAPI.CODE.OK) {\n Web.setLocalStorageItem(Computer8080.STATE_USERID, response.data);\n if (fMessages) this.printMessage(Computer8080.STATE_USERID + \" updated: \" + response.data);\n this.sUserID = response.data;\n } else {\n if (fMessages) this.printMessage(response.code + \": \" + response.data);\n }\n } catch (e) {\n Component.error(e.message + \" (\" + sResponse + \")\");\n }\n } else {\n if (fMessages) this.printMessage(\"invalid response (error \" + nErrorCode + \")\");\n }\n return this.sUserID;\n }\n\n /**\n * getServerStatePath()\n *\n * @this {Computer8080}\n * @return {string|null} sStatePath (null if no localStorage or no USERID stored in localStorage)\n */\n getServerStatePath()\n {\n var sStatePath = null;\n if (this.sUserID) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(Computer8080.STATE_USERID + \" for load: \" + this.sUserID);\n }\n sStatePath = Web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.LOAD + '&' + UserAPI.QUERY.USER + '=' + this.sUserID + '&' + UserAPI.QUERY.STATE + '=' + State.key(this, PC8080.APPVERSION);\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(Computer8080.STATE_USERID + \" unavailable\");\n }\n }\n return sStatePath;\n }\n\n /**\n * saveServerState(sUserID, sState)\n *\n * @param {string} sUserID\n * @param {string|null} sState\n */\n saveServerState(sUserID, sState)\n {\n /*\n * We must pass fSync == true, because (as I understand it) browsers will blow off any async\n * requests when a page is being closed. Since our request is synchronous, storeServerState()\n * should also return a result, but there's not much we can do with it, since browsers ALSO\n * tend to blow off alerts() and the like when closing down.\n */\n if (sState) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"size of server state: \" + sState.length + \" bytes\");\n }\n var response = this.storeServerState(sUserID, sState, true);\n if (response && response[UserAPI.RES.CODE] == UserAPI.CODE.OK) {\n this.notice(\"Machine state saved to server\");\n } else if (sState) {\n var sError = (response && response[UserAPI.RES.DATA]) || UserAPI.FAIL.BADSTORE;\n if (response[UserAPI.RES.CODE] == UserAPI.CODE.FAIL) {\n sError = \"Error: \" + sError;\n } else {\n sError = \"Error \" + response[UserAPI.RES.CODE] + \": \" + sError;\n }\n this.notice(sError);\n this.resetUserID();\n }\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"no state to store\");\n }\n }\n }\n\n /**\n * storeServerState(sUserID, sState, fSync)\n *\n * @this {Computer8080}\n * @param {string} sUserID\n * @param {string} sState\n * @param {boolean} [fSync] is true if we're powering down and should perform a synchronous request (default is async)\n * @return {*} server response if fSync is true and a response was received; otherwise null\n */\n storeServerState(sUserID, sState, fSync)\n {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(Computer8080.STATE_USERID + \" for store: \" + sUserID);\n }\n /*\n * TODO: Determine whether or not any browsers cancel our request if we're called during a browser \"shutdown\" event,\n * and whether or not it matters if we do an async request (currently, we're not, to try to ensure the request goes through).\n */\n var dataPost = {};\n dataPost[UserAPI.QUERY.REQ] = UserAPI.REQ.STORE;\n dataPost[UserAPI.QUERY.USER] = sUserID;\n dataPost[UserAPI.QUERY.STATE] = State.key(this, PC8080.APPVERSION);\n dataPost[UserAPI.QUERY.DATA] = sState;\n var sRequest = Web.getHost() + UserAPI.ENDPOINT;\n if (!fSync) {\n Web.getResource(sRequest, dataPost, true);\n } else {\n var response = Web.getResource(sRequest, dataPost);\n var sResponse = response[0];\n if (response[1]) {\n if (sResponse) {\n var i = sResponse.indexOf('\\n');\n if (i > 0) sResponse = sResponse.substr(0, i);\n if (!sResponse.indexOf(\"Error: \")) sResponse = sResponse.substr(7);\n }\n sResponse = '{\"' + UserAPI.RES.CODE + '\":' + response[1] + ',\"' + UserAPI.RES.DATA + '\":\"' + sResponse + '\"}';\n }\n if (DEBUG && this.messageEnabled()) this.printMessage(sResponse);\n return JSON.parse(sResponse);\n }\n return null;\n }\n\n /**\n * onPower()\n *\n * This handles UI requests to toggle the computer's power (eg, see the \"power\" button binding).\n *\n * @this {Computer8080}\n */\n onPower()\n {\n if (!this.nPowerChange) {\n if (!this.flags.powered) {\n this.wait(this.powerOn);\n } else {\n this.powerOff(false, true);\n }\n }\n }\n\n /**\n * onReset()\n *\n * This handles UI requests to reset the computer's state (eg, see the \"reset\" button binding).\n *\n * @this {Computer8080}\n */\n onReset()\n {\n /*\n * I'm going to start with the presumption that it makes little sense for an \"unpowered\" computer to be \"reset\";\n * ditto if the power state is currently being changed.\n */\n if (!this.flags.powered || this.nPowerChange) return;\n\n /*\n * If this is a \"resumable\" machine (and it's not using a predefined state), then we overload the reset\n * operation to offer an explicit \"save or discard\" option first. This is currently the only UI we offer to\n * discard a machine's state, including any disk changes. The traditional \"reset\" operation is still available\n * for non-resumable machines.\n *\n * TODO: Break this behavior out into a separate \"discard\" operation, in case the designer of the machine really\n * wants to clutter the UI with confusing options. ;-)\n */\n if (this.resume && !this.sResumePath) {\n /*\n * I used to bypass the prompt if this.resume == Computer8080.RESUME_AUTO, setting fSave to true automatically,\n * but that gives the user no means of resetting a resumable machine that contains errors in its resume state.\n */\n var fSave = (/* this.resume == Computer8080.RESUME_AUTO || */ Component.confirmUser(\"Click OK to save changes to this \" + PC8080.APPNAME + \" machine.\\n\\nWARNING: If you CANCEL, all disk changes will be discarded.\"));\n this.powerOff(fSave, true);\n /*\n * Forcing the page to reload is an expedient option, but ugly. It's preferable to call powerOn()\n * and rely on all the components to reset themselves to their default state. The components with\n * the greatest burden here are FDC and HDC, which must rely on the fReload flag to determine whether\n * or not to unload/reload all their original auto-mounted disk images.\n *\n * However, if we started with a predefined state (ie, sStatePath is set), we take this shortcut, because\n * we don't (yet) have code in place to gracefully reload the initial state (requires calling getResource()\n * again); alternatively, we could avoid throwing that state away, but it seems better to save the memory.\n *\n * TODO: Make this more graceful, so that we can stop using the reloadPage() sledgehammer.\n */\n if (!fSave && this.sStatePath) {\n Web.reloadPage();\n return;\n }\n if (!fSave) this.fReload = true;\n this.powerOn(Computer8080.RESUME_NONE);\n this.fReload = false;\n } else {\n this.reset();\n if (this.cpu) this.cpu.autoStart();\n }\n }\n\n /**\n * getMachineComponent(sType, componentPrev)\n *\n * @this {Computer8080}\n * @param {string} sType\n * @param {Component|null} [componentPrev] of previously returned component, if any\n * @return {Component|null}\n */\n getMachineComponent(sType, componentPrev)\n {\n var componentLast = componentPrev;\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (componentPrev) {\n if (componentPrev == component) componentPrev = null;\n continue;\n }\n if (component.type == sType) return component;\n }\n if (!componentLast) Component.log(\"Machine component type '\" + sType + \"' not found\", \"warning\");\n return null;\n }\n\n /**\n * updateFocus(fScroll)\n *\n * NOTE: When soft keyboard buttons call us to return focus to the machine (and away from the button),\n * the browser's default behavior is to scroll the element into view, which can be annoying, especially on iOS,\n * where the display is more constrained, so we no longer do it by default (fScroll must be true).\n *\n * @this {Computer8080}\n * @param {boolean} [fScroll] (true if you really want the control scrolled into view)\n */\n updateFocus(fScroll)\n {\n if (this.aVideo.length) {\n /*\n * This seems to be recommended work-around to prevent the browser from scrolling the focused element\n * into view. The CPU is not a visual component, so when the CPU wants to set focus, the primary intent\n * is to ensure that keyboard input is fielded properly.\n */\n var x = 0, y = 0;\n if (!fScroll && window) {\n x = window.scrollX;\n y = window.scrollY;\n }\n\n /*\n * TODO: We need a mechanism to determine the \"active\" display, instead of hard-coding this to aVideo[0].\n */\n this.aVideo[0].setFocus();\n\n if (!fScroll && window) {\n window.scrollTo(x, y);\n }\n }\n }\n\n /**\n * updateStatus(fForce)\n *\n * If any DOM controls were bound to the CPU, then we need to call its updateStatus() handler; if there are no\n * such bindings, then cpu.updateStatus() does nothing.\n *\n * Similarly, if there's a Panel, then we need to call its updateStatus() handler, in case it created its own canvas\n * and implemented its own register display (eg, dumpRegisters()); if not, then panel.updateStatus() also does nothing.\n *\n * In practice, there will *either* be a Panel with a custom canvas *or* a set of DOM controls bound to the CPU *or*\n * neither. In theory, there could be BOTH, but that would be unusual.\n *\n * TODO: Consider alternate approaches to these largely register-oriented display updates. Ordinarily, we like to\n * separate logic from presentation, and currently the CPUState contains both, since it's the component that intimately\n * knows the names, number, sizes, etc, of all the active registers. The Panel component is the logical candidate,\n * but Panel is an optional component; generally, only machines that include Debugger also include Panel.\n *\n * @this {Computer8080}\n * @param {boolean} [fForce] (true will display registers even if the CPU is running and \"live\" registers are not enabled)\n */\n updateStatus(fForce)\n {\n /*\n * fForce is generally set to true whenever the CPU is transitioning to/from a running state, in which case\n * cpu.updateStatus() will definitely want to hide/show register contents; however, at other times, when the\n * CPU is running, constantly updating the DOM controls too frequently can adversely impact overall performance.\n *\n * So fForce serves as a hint to help cpu.updateStatus() make a more informed decision. panel.updateStatus()\n * currently doesn't care, on the theory that canvas updates should be significantly faster than DOM updates,\n * but we still pass fForce on.\n */\n if (this.cpu) this.cpu.updateStatus(fForce);\n if (this.panel) this.panel.updateStatus(fForce);\n }\n\n /**\n * updateVideo(fForced)\n *\n * Any high-frequency updates should be performed here (avoid updating DOM elements).\n *\n * @this {Computer8080}\n * @param {boolean} [fForced]\n */\n updateVideo(fForced)\n {\n for (var i = 0; i < this.aVideo.length; i++) {\n this.aVideo[i].updateScreen(fForced);\n }\n }\n\n /**\n * Computer8080.init()\n *\n * For every machine represented by an HTML element of class \"pc8080-machine\", this function\n * locates the HTML element of class \"computer\", extracting the JSON-encoded parameters for the\n * Computer constructor from the element's \"data-value\" attribute, invoking the constructor to\n * create a Computer component, and then binding any associated HTML controls to the new component.\n */\n static init()\n {\n /*\n * In non-COMPILED builds, embedMachine() may have set XMLVERSION.\n */\n if (!COMPILED && XMLVERSION) PC8080.APPVERSION = XMLVERSION;\n\n var aeMachines = Component.getElementsByClass(document, PC8080.APPCLASS + \"-machine\");\n\n for (var iMachine = 0; iMachine < aeMachines.length; iMachine++) {\n\n var eMachine = aeMachines[iMachine];\n var parmsMachine = Component.getComponentParms(eMachine);\n\n var aeComputers = Component.getElementsByClass(eMachine, PC8080.APPCLASS, \"computer\");\n\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n\n /*\n * We set fSuspended in the Computer constructor because we want to \"power up\" the\n * computer ourselves, after any/all bindings are in place.\n */\n var computer = new Computer8080(parmsComputer, parmsMachine, true);\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onInit(\" + computer.flags.powered + \")\");\n }\n\n /*\n * Bind any \"power\", \"reset\" and \"save\" buttons. An \"erase\" button was also considered,\n * but \"reset\" now provides a way to force the machine to start from scratch again, so \"erase\"\n * may be redundant now.\n */\n Component.bindComponentControls(computer, eComputer, PC8080.APPCLASS);\n\n /*\n * Power on the computer, giving every component the opportunity to reset or restore itself.\n */\n if (computer.fAutoPower) computer.wait(computer.powerOn);\n }\n }\n }\n\n /**\n * Computer8080.show()\n *\n * When exit() is using an \"onbeforeunload\" handler, this \"onpageshow\" handler allows us to repower everything,\n * without either resetting or restoring. We call powerOn() with a special resume value (RESUME_REPOWER) if the\n * computer is already marked as \"ready\", meaning the browser didn't change anything. This \"repower\" process\n * should be very quick, essentially just marking all components as powered again (so that, for example, the Video\n * component will start drawing again) and firing the CPU up again.\n */\n static show()\n {\n var aeComputers = Component.getElementsByClass(document, PC8080.APPCLASS, \"computer\");\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n var computer = /** @type {Computer8080} */ (Component.getComponentByType(\"Computer\", parmsComputer['id']));\n if (computer) {\n\n computer.flags.unloading = false;\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onShow(\" + computer.fInitialized + \",\" + computer.flags.powered + \")\");\n }\n\n /*\n * Note that the FIRST 'onpageshow' event, and therefore the first show() callback, occurs\n * AFTER the the initial 'onload' event, and at that point in time, fInitialized will not be set yet.\n * So, practically speaking, the first show() callback isn't all that useful.\n */\n if (computer.fInitialized && !computer.flags.powered) {\n /**\n * Repower the computer, notifying every component to continue running as-is.\n */\n computer.powerOn(Computer8080.RESUME_REPOWER);\n }\n }\n }\n }\n\n /**\n * Computer8080.exit()\n *\n * The Computer is currently the only component that uses an \"exit\" handler, which web.onExit() defines as\n * either an \"unload\" or \"onbeforeunload\" handler. This gives us the opportunity to save the machine state,\n * using our powerOff() function, before the page goes away.\n *\n * It's worth noting that \"onbeforeunload\" offers one nice feature when used instead of \"onload\": the entire\n * page (and therefore this entire application) is retained in its current state by the browser (well, some\n * browsers), so that if you go to a new URL, either by entering a new URL in the same window/tab, or by pressing\n * the FORWARD button, and then you press the BACK button, the page is immediately restored to its previous state.\n *\n * In fact, that's how some browsers operate whether you have an \"onbeforeunload\" handler or not; in other words,\n * an \"onbeforeunload\" handler doesn't change the page retention behavior of the browser. By contrast, the mere\n * presence of an \"onunload\" handler generally causes a browser to throw the page away once the handler returns.\n *\n * However, in order to safely use \"onbeforeunload\", we must add yet another handler (\"onpageshow\") to repower\n * everything, without either resetting or restoring. Hence, the Computer8080.show() function, which calls powerOn()\n * with a special resume value (RESUME_REPOWER) if the computer is already marked as \"ready\", meaning the browser\n * didn't change anything. This \"repower\" process should be very quick, essentially just marking all components as\n * powered again (so that, for example, the Video component will start drawing again) and firing the CPU up again.\n *\n * Reportedly, some browsers (eg, Opera) don't support \"onbeforeunload\", in which case Component will have to use\n * \"unload\" instead. But even when the page must be rebuilt from scratch, the combination of browser cache and\n * localStorage means the simulation should be restored and become operational almost immediately.\n */\n static exit()\n {\n var aeComputers = Component.getElementsByClass(document, PC8080.APPCLASS, \"computer\");\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n var computer = /** @type {Computer8080} */ (Component.getComponentByType(\"Computer\", parmsComputer['id']));\n if (computer) {\n\n /*\n * Added a new flag that Component functions (eg, notice()) should check before alerting the user.\n */\n computer.flags.unloading = true;\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onExit(\" + computer.flags.powered + \")\");\n }\n\n if (computer.flags.powered) {\n /**\n * Power off the computer, giving every component an opportunity to save its state,\n * but only if 'resume' has been set AND there is no valid resume path (because if a valid resume\n * path exists, we'll always load our state from there, and not from whatever we save here).\n */\n computer.powerOff(!!(computer.resume && !computer.sResumePath), true);\n }\n }\n }\n }\n}\n\nComputer8080.STATE_FAILSAFE = \"failsafe\";\nComputer8080.STATE_VALIDATE = \"validate\";\nComputer8080.STATE_TIMESTAMP = \"timestamp\";\nComputer8080.STATE_VERSION = \"version\";\nComputer8080.STATE_HOSTURL = \"url\";\nComputer8080.STATE_BROWSER = \"browser\";\nComputer8080.STATE_USERID = \"user\";\n\n/*\n * The following constants define all the resume options. Negative values (eg, RESUME_REPOWER) are for\n * internal use only, and RESUME_DELETE is not documented (it provides a way of deleting ALL saved states\n * whenever a resume is declined). As a result, the only \"end-user\" values are 0, 1 and 2.\n */\nComputer8080.RESUME_REPOWER = -1; // resume without changing any state (for internal use only)\nComputer8080.RESUME_NONE = 0; // default (no resume)\nComputer8080.RESUME_AUTO = 1; // automatically save/restore state\nComputer8080.RESUME_PROMPT = 2; // automatically save but conditionally restore (WARNING: if restore is declined, any state is discarded)\nComputer8080.RESUME_DELETE = 3; // same as RESUME_PROMPT but discards ALL machines states whenever ANY machine restore is declined (undocumented)\n\n/*\n * Initialize every Computer on the page.\n */\nWeb.onInit(Computer8080.init);\nWeb.onShow(Computer8080.show);\nWeb.onExit(Computer8080.exit);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/state.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass State {\n /**\n * State(component, sVersion, sSuffix)\n *\n * State objects are used by components to save/restore their state.\n *\n * During a save operation, components add data to a State object via set(), and then return\n * the resulting data using data().\n *\n * During a restore operation, the Computer component passes the results of each data() call\n * back to the originating component.\n *\n * WARNING: Since State objects are low-level objects that have no UI requirements, they do not\n * inherit from the Component class, so you should only use class methods of Component, such as\n * Component.assert() (or Debugger methods if the Debugger is available).\n *\n * NOTE: 1.01 is the first version to provide limited save/restore support using localStorage.\n * From that point on, care must be taken to insure that any new version that's incompatible with\n * previous localStorage data be released with a version number that is at least 1 greater,\n * since we're tagging the localStorage data with the integer portion of the version string.\n *\n * @param {Component} component\n * @param {string} [sVersion] is used to append a major version number to the key\n * @param {string} [sSuffix] is used to append any additional suffixes to the key\n */\n constructor(component, sVersion, sSuffix)\n {\n this.id = component.id;\n this.dbg = component.dbg;\n this.json = \"\";\n this.state = {};\n this.fLoaded = this.fParsed = false;\n this.key = State.key(component, sVersion, sSuffix);\n this.unload(component.parms);\n }\n\n /**\n * set(id, data)\n *\n * @this {State}\n * @param {number|string} id\n * @param {Object|string} data\n */\n set(id, data)\n {\n try {\n this.state[id] = data;\n } catch(e) {\n Component.log(e.message);\n }\n }\n\n /**\n * get(id)\n *\n * @this {State}\n * @param {number|string} id\n * @return {Object|string|null}\n */\n get(id)\n {\n return this.state[id] || null;\n }\n\n /**\n * data()\n *\n * @this {State}\n * @return {Object}\n */\n data()\n {\n return this.state;\n }\n\n /**\n * load(json)\n *\n * WARNING: Make sure you follow this call with either a call to parse() or unload(),\n * because any stringified data that we've loaded isn't usable until it's been parsed.\n *\n * @this {State}\n * @param {string|null} [json]\n * @return {boolean} true if state exists in localStorage, false if not\n */\n load(json)\n {\n if (json) {\n this.json = json;\n this.fLoaded = true;\n this.fParsed = false;\n return true;\n }\n if (this.fLoaded) {\n /*\n * This is assumed to be a redundant load().\n */\n return true;\n }\n if (Web.hasLocalStorage()) {\n var s = Web.getLocalStorageItem(this.key);\n if (s) {\n this.json = s;\n this.fLoaded = true;\n if (DEBUG) Component.log(\"localStorage(\" + this.key + \"): \" + s.length + \" bytes loaded\");\n return true;\n }\n }\n return false;\n }\n\n /**\n * parse()\n *\n * This completes the load() operation, by parsing what was loaded, on the assumption there\n * might be some benefit to deferring parsing until we've given the user a chance to confirm.\n * Otherwise, load() could have just as easily done this, too.\n *\n * @this {State}\n * @return {boolean} true if successful, false if error\n */\n parse()\n {\n var fSuccess = true;\n if (!this.fParsed) {\n try {\n this.state = JSON.parse(this.json);\n this.fParsed = true;\n } catch (e) {\n Component.error(e.message || e);\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * store()\n *\n * @this {State}\n * @return {boolean} true if successful, false if error\n */\n store()\n {\n var fSuccess = true;\n if (Web.hasLocalStorage()) {\n var s = JSON.stringify(this.state);\n if (Web.setLocalStorageItem(this.key, s)) {\n if (DEBUG) Component.log(\"localStorage(\" + this.key + \"): \" + s.length + \" bytes stored\");\n } else {\n /*\n * WARNING: Because browsers tend to disable all alerts() during an \"unload\" operation,\n * it's unlikely anyone will ever see the \"quota\" errors that occur at this point. Need to\n * think of some way to notify the user that there's a problem, and offer a way of cleaning\n * up old states.\n */\n Component.error(\"Unable to store \" + s.length + \" bytes in browser local storage\");\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * toString()\n *\n * @this {State}\n * @return {string} JSON-encoded state\n */\n toString()\n {\n return this.state? JSON.stringify(this.state) : this.json;\n }\n\n /**\n * unload(parms)\n *\n * This discards any data saved via set() or loaded via load(), creating an empty State object.\n * Note that you have to follow this call with an explicit call to store() if you want to remove\n * the state from localStorage as well.\n *\n * @this {State}\n * @param {Object} [parms]\n */\n unload(parms)\n {\n this.json = \"\";\n this.state = {};\n this.fLoaded = this.fParsed = false;\n if (parms) this.set(\"parms\", parms);\n }\n\n /**\n * clear(fAll)\n *\n * This unloads the current state, and then clears ALL localStorage for the current machine,\n * independent of version, to reduce the chance of orphaned states wasting part of our limited allocation.\n *\n * @this {State}\n * @param {boolean} [fAll] true to unconditionally clear ALL localStorage for the current domain\n */\n clear(fAll)\n {\n this.unload();\n var aKeys = Web.getLocalStorageKeys();\n for (var i = 0; i < aKeys.length; i++) {\n var sKey = aKeys[i];\n if (sKey && (fAll || sKey.substr(0, this.key.length) == this.key)) {\n Web.removeLocalStorageItem(sKey);\n if (DEBUG) Component.log(\"localStorage(\" + sKey + \") removed\");\n aKeys.splice(i, 1);\n i = 0;\n }\n }\n }\n\n /**\n * State.key(component, sVersion, sSuffix)\n *\n * This encapsulates the key generation code.\n *\n * @param {Component} component\n * @param {string} [sVersion] is used to append a major version number to the key\n * @param {string} [sSuffix] is used to append any additional suffixes to the key\n * @return {string} key\n */\n static key(component, sVersion, sSuffix)\n {\n var key = component.id;\n if (sVersion) {\n var i = sVersion.indexOf('.');\n if (i > 0) key += \".v\" + sVersion.substr(0, i);\n }\n if (sSuffix) {\n key += \".\" + sSuffix;\n }\n return key;\n }\n\n /**\n * State.compress(aSrc)\n *\n * @param {Array.<number>|null} aSrc\n * @return {Array.<number>|null} is either the original array (aSrc), or a smaller array of \"count, value\" pairs (aComp)\n */\n static compress(aSrc)\n {\n if (aSrc) {\n var iSrc = 0;\n var iComp = 0;\n var aComp = [];\n while (iSrc < aSrc.length) {\n var n = aSrc[iSrc];\n\n var iCompare = iSrc + 1;\n while (iCompare < aSrc.length && aSrc[iCompare] === n) iCompare++;\n aComp[iComp++] = iCompare - iSrc;\n aComp[iComp++] = n;\n iSrc = iCompare;\n }\n if (aComp.length < aSrc.length) return aComp;\n }\n return aSrc;\n }\n\n /**\n * State.decompress(aComp)\n *\n * @param {Array.<number>} aComp\n * @param {number} nLength is expected length of decompressed data\n * @return {Array.<number>}\n */\n static decompress(aComp, nLength)\n {\n var iDst = 0;\n var aDst = new Array(nLength);\n var iComp = 0;\n while (iComp < aComp.length - 1) {\n var c = aComp[iComp++];\n var n = aComp[iComp++];\n while (c--) {\n aDst[iDst++] = n;\n }\n }\n\n return aDst;\n }\n\n /**\n * State.compressEvenOdd(aSrc)\n *\n * This is a very simple variation on compress() that compresses all the EVEN elements of aSrc first,\n * followed by all the ODD elements. This tends to work better on EGA video memory, because when odd/even\n * addressing is enabled (eg, for text modes), the DWORD values tend to alternate, which is the worst case\n * for compress(), but the best case for compressEvenOdd().\n *\n * One wrinkle we support: if the first element is uninitialized, then we assume the entire array is undefined,\n * and return an empty compressed array. Conversely, decompressEvenOdd() will take an empty compressed array\n * and return an uninitialized array.\n *\n * @param {Array.<number>|null} aSrc\n * @return {Array.<number>|null} is either the original array (aSrc), or a smaller array of \"count, value\" pairs (aComp)\n */\n static compressEvenOdd(aSrc)\n {\n if (aSrc) {\n var iComp = 0, aComp = [];\n if (aSrc[0] !== undefined) {\n for (var off = 0; off < 2; off++) {\n var iSrc = off;\n while (iSrc < aSrc.length) {\n var n = aSrc[iSrc];\n var iCompare = iSrc + 2;\n while (iCompare < aSrc.length && aSrc[iCompare] === n) iCompare += 2;\n aComp[iComp++] = (iCompare - iSrc) >> 1;\n aComp[iComp++] = n;\n iSrc = iCompare;\n }\n }\n }\n if (aComp.length < aSrc.length) return aComp;\n }\n return aSrc;\n }\n\n /**\n * State.decompressEvenOdd(aComp, nLength)\n *\n * This is the counterpart to compressEvenOdd(). Note that because there's nothing in the compressed sequence\n * that differentiates a compress() sequence from a compressEvenOdd() sequence, you simply have to be consistent:\n * if you used even/odd compression, then you must use even/odd decompression.\n *\n * @param {Array.<number>} aComp\n * @param {number} nLength is expected length of decompressed data\n * @return {Array.<number>}\n */\n static decompressEvenOdd(aComp, nLength)\n {\n var iDst = 0;\n var aDst = new Array(nLength);\n var iComp = 0;\n while (iComp < aComp.length - 1) {\n var c = aComp[iComp++];\n var n = aComp[iComp++];\n while (c--) {\n aDst[iDst] = n;\n iDst += 2;\n }\n /*\n * The output of a \"count,value\" pair will never exceed the end of the output array, so as soon as we reach it\n * the first time, we know it's time to switch to ODD elements, and as soon as we reach it again, we should be\n * done.\n */\n\n if (iDst == nLength) iDst = 1;\n }\n\n return aDst;\n }\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/embed.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * We now support asynchronous XML and XSL file loads; simply set fAsync (below) to true.\n *\n * NOTE: For that support to work, we have to keep track of the number of machines on the page\n * (ie, how many embedMachine() calls were issued), reduce the count as each machine XML file\n * is fully transformed into HTML, and when the count finally returns to zero, notify all the\n * machine component init() handlers.\n *\n * Also, to prevent those init() handlers from running prematurely, we must disable all page\n * notification events at the start of the embedding process (Web.enablePageEvents(false)) and\n * re-enable them at the end (Web.enablePageEvents(true)).\n */\nvar fAsync = true;\nvar cAsyncMachines = 0;\n\n/**\n * loadXML(sFile, idMachine, sAppName, sAppClass, sParms, fResolve, display, done)\n *\n * This is the preferred way to load all XML and XSL files. It uses getResource()\n * to load them as strings, which parseXML() can massage before parsing/transforming them.\n *\n * For example, since I've been unable to get the XSLT document() function to work inside any\n * XSL document loaded by JavaScript's XSLT processor, that has prevented me from dynamically\n * loading any XML machine file that uses the \"ref\" attribute to refer to and incorporate\n * another XML document.\n *\n * To solve that, I've added an fResolve parameter that tells parseXML() to fetch any\n * referenced documents ITSELF and insert them into the XML string prior to parsing, instead\n * of relying on the XSLT template to pull them in. That fetching is handled by resolveXML(),\n * which iterates over the XML until all \"refs\" have been resolved (including any nested\n * references).\n *\n * Also, XSL files with a <!DOCTYPE [...]> cause MSIE's Microsoft.XMLDOM.loadXML() function\n * to choke, so I strip that out prior to parsing as well.\n *\n * TODO: Figure out why the XSLT document() function works great when the web browser loads an\n * XML file (and the associated XSL file) itself, but does not work when loading documents via\n * JavaScript XSLT support. Is it broken, is it a security issue, or am I just calling it wrong?\n *\n * @param {string} sXMLFile\n * @param {string|null|undefined} idMachine\n * @param {string|null|undefined} sAppName\n * @param {string|null|undefined} sAppClass\n * @param {string|null|undefined} sParms (machine parameters, if any)\n * @param {string|null|undefined} sClass (an optional machine class name used to style the machine)\n * @param {boolean} fResolve is true to resolve any \"ref\" attributes\n * @param {function(string)} display\n * @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)\n */\nfunction loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n{\n var doneLoadXML = function(sURLName, sXML, nErrorCode) {\n if (nErrorCode) {\n if (!sXML) sXML = \"unable to load \" + sXMLFile + \" (\" + nErrorCode + \")\";\n done(sXML, null);\n return;\n }\n parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done);\n };\n display(\"Loading \" + sXMLFile + \"...\");\n Web.getResource(sXMLFile, null, fAsync, doneLoadXML);\n}\n\n/**\n * parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n *\n * Generates an XML document from an XML string. This function also provides a work-around for XSLT's\n * lack of support for the document() function (at least on some browsers), by replacing every reference\n * tag (ie, a tag with a \"ref\" attribute) with the contents of the referenced file.\n *\n * @param {string} sXML\n * @param {string|null} sXMLFile\n * @param {string|null|undefined} idMachine\n * @param {string|null|undefined} sAppName\n * @param {string|null|undefined} sAppClass\n * @param {string|null|undefined} sParms (machine parameters, if any)\n * @param {string|null|undefined} sClass (an optional machine class name used to style the machine)\n * @param {boolean} fResolve is true to resolve any \"ref\" attributes; default is false\n * @param {function(string)} display\n * @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)\n */\nfunction parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n{\n var buildXML = function(sXML, sError) {\n if (sError) {\n done(sError, null);\n return;\n }\n if (idMachine) {\n\n /*\n * A more sensible place to record the machine XML would be embedMachine(), like we do for the\n * XSL file, but since we're about to modify the original machine XML, it's best to record it now.\n */\n Component.addMachineResource(idMachine, sXMLFile, sXML);\n\n var sURL = sXMLFile;\n if (sURL && sURL.indexOf('/') < 0 && window.location.pathname.slice(-1) == '/') {\n sURL = window.location.pathname + sURL;\n }\n /*\n * We embed the URL of the XML file both as a separate \"xml\" attribute for easy access from the\n * XSL file, and as part of the \"parms\" attribute for easy access from machines (see getMachineParm()).\n */\n if (!sParms) {\n sParms = '{';\n } else if (sParms.slice(-1) == '}') {\n sParms = sParms.slice(0, -1);\n if (sParms.length > 1) sParms += ',';\n } else { // sParms must just be a \"state\" file, so encode it as a \"state\" property\n sParms = '{state:\"' + sParms + '\",';\n }\n sParms += 'url:\"' + sURL + '\"}';\n /*\n * Note that while we no longer generate a machine XML file with a \"state\" attribute (because it's\n * encoded inside the \"parms\" attribute), the XSL file must still cope with \"state\" attributes inside\n * other XML files; for example, manifest XML files like /apps/pcx86/1981/visicalc/manifest.xml contain\n * machine elements with \"state\" attributes that must still be passed down to the computer element\n * \"the old fashioned way\".\n *\n * Until/unless that changes, components.xsl cannot be simplified as much as I might have hoped.\n */\n if (typeof resources == 'object') sURL = null; // turn off URL inclusion if we have embedded resources\n sParms = sParms.replace(/\\$/g, \"$$$$\");\n if (sClass) {\n /*\n * If there's no hard-coded \"class\" attribute in the machine tag, then we can set one in the final\n * replacement below, just like we do for sParms and sURL. However, if a \"class\" attribute already\n * exists, we need alter it and then zap the sClass variable.\n */\n var match = sXML.match(/(<machine[^>]*\\sclass=)(['\"])(.*?)(\\2.*?>)/);\n if (match) {\n sXML = sXML.replace(match[0], match[1] + match[2] + sClass + match[4]);\n sClass = null;\n }\n }\n sXML = sXML.replace(/(<machine[^>]*\\sid=)(['\"]).*?\\2/, \"$1$2\" + idMachine + \"$2\" + (sClass? ' class=\"' + sClass + '\"' : '') + (sParms? \" parms='\" + sParms + \"'\" : \"\") + (sURL? ' url=\"' + sURL + '\"' : ''));\n }\n\n if (!fResolve) {\n /*\n * I'm trying to switch to a shared components.xsl (at least for all PC-class machines),\n * but in the interim, that means hacking the XSL file on the fly to reflect the actual class.\n */\n sXML = sXML.replace(/(<xsl:variable name=\"APPNAME\">).*?(<\\/xsl:variable>)/, \"$1\" + sAppName + \"$2\");\n sXML = sXML.replace(/(<xsl:variable name=\"APPCLASS\">).*?(<\\/xsl:variable>)/, \"$1\" + sAppClass + \"$2\");\n\n /*\n * Non-COMPILED kludge to replace the version number template in the XSL file (which we assume we're reading,\n * since fResolve is false) with whatever XMLVERSION we extracted from the XML file (see corresponding kludge below).\n *\n * ES6 ALERT: Template strings.\n */\n if (!COMPILED && XMLVERSION) {\n sXML = sXML.replace(/<xsl:variable name=\"APPVERSION\"\\/>/, `<xsl:variable name=\"APPVERSION\">${XMLVERSION}</xsl:variable>`);\n }\n }\n\n /*\n * If the resource we requested is not really an XML file (or the file didn't exist and the server simply returned\n * a message like \"Cannot GET /devices/pc/machine/5150/cga/64kb/donkey/machine.xml\"), we'd like to display a more\n * meaningful message, because the XML DOM parsers will blithely return a document that contains nothing useful; eg:\n *\n * This page contains the following errors:error on line 1 at column 1:\n * Document is empty Below is a rendering of the page up to the first error.\n *\n * Supposedly, the IE XML DOM parser will throw an exception, but I haven't tested that, and unless all other\n * browsers do that, that's not helpful.\n *\n * The best I can do at this stage (assuming Web.getResource() didn't drop any error information on the floor)\n * is verify that the requested resource \"looks like\" valid XML (in other words, it begins with a '<').\n */\n var xmlDoc = null;\n if (sXML.charAt(0) == '<') {\n try {\n /*\n * Another hack for MSIE, which fails to load XSL documents containing a <!DOCTYPE [...]> tag.\n *\n * This is also why the XSLTProcessor 'transformToFragment' method in Microsoft Edge silently failed,\n * so I had pull this hack out of the \"ActiveXObject\" code. And rather than add yet-another Microsoft\n * browser check, I'm going to try doing this across the board, and hope that none of the other XSLT\n * processors fail *without* the DOCTYPE tag.\n */\n if (!fResolve) {\n sXML = sXML.replace(/<!DOCTYPE(.|[\\r\\n])*]>\\s*/g, \"\");\n }\n /*\n * Beginning with Microsoft Edge and the corresponding release of Windows 10, all the\n * 'ActiveXObject' crud has gone away; but of course, this code must remain in place if\n * we want to continue supporting older Internet Explorer browsers (ie, back to IE9).\n */\n /** @namespace window.ActiveXObject */\n if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1\n xmlDoc = new window.ActiveXObject(\"Microsoft.XMLDOM\");\n xmlDoc.async = false;\n xmlDoc['loadXML'](sXML);\n } else {\n /** @namespace window.DOMParser */\n xmlDoc = (new window.DOMParser()).parseFromString(sXML, \"text/xml\");\n }\n } catch(e) {\n xmlDoc = null;\n sXML = e.message;\n }\n } else {\n sXML = \"unrecognized XML: \" + (sXML.length > 255? sXML.substr(0, 255) + \"...\" : sXML);\n }\n done(sXML, xmlDoc);\n };\n if (sXML) {\n if (PRIVATE) sXML = sXML.replace(/\\/library.xml/, \"/private/library.xml\");\n if (fResolve) {\n resolveXML(sXML, display, buildXML);\n return;\n }\n buildXML(sXML, null);\n return;\n }\n done(\"no data\" + (sXMLFile? \" for file: \" + sXMLFile : \"\"), null);\n}\n\n/**\n * resolveXML(sXML, display, done)\n *\n * Replaces every tag with a \"ref\" attribute with the contents of the corresponding file.\n *\n * TODO: Fix some of the limitations of this code, such as: 1) requiring the \"ref\" attribute\n * to appear as the tag's first attribute, 2) requiring the \"ref\" attribute to be double-quoted,\n * and 3) requiring the \"ref\" tag to be self-closing.\n *\n * @param {string} sXML\n * @param {function(string)} display\n * @param {function(string,(string|null))} done (the first string contains the resolved XML data, the second is for any error message)\n */\nfunction resolveXML(sXML, display, done)\n{\n var matchRef;\n var reRef = /<([a-z]+)\\s+ref=\"(.*?)\"(.*?)\\/>/g;\n\n if ((matchRef = reRef.exec(sXML))) {\n\n var sRefFile = matchRef[2];\n\n var doneReadXML = function(sURLName, sXMLRef, nErrorCode) {\n if (nErrorCode || !sXMLRef) {\n done(sXML, \"unable to resolve XML reference: \" + matchRef[0] + \" (\" + nErrorCode + \")\");\n return;\n }\n /*\n * If there are additional attributes in the \"referring\" XML tag, we want to insert them\n * into the \"referred\" XML tag; attributes that don't exist in the referred tag should be\n * appended, and attributes that DO exist should be overwritten.\n */\n var sRefAttrs = matchRef[3];\n if (sRefAttrs) {\n var aXMLRefTag = sXMLRef.match(new RegExp(\"<\" + matchRef[1] + \"[^>]*>\"));\n if (aXMLRefTag) {\n var sXMLNewTag = aXMLRefTag[0];\n /*\n * Iterate over all the attributes in the \"referring\" XML tag (sRefAttrs)\n */\n var matchAttr;\n var reAttr = /( [a-z]+=)(['\"])(.*?)\\2/gi;\n while ((matchAttr = reAttr.exec(sRefAttrs))) {\n if (sXMLNewTag.toLowerCase().indexOf(matchAttr[1].toLowerCase()) < 0) {\n /*\n * This is the append case....\n */\n sXMLNewTag = sXMLNewTag.replace(\">\", matchAttr[0] + \">\");\n } else {\n /*\n * This is the overwrite case....\n */\n sXMLNewTag = sXMLNewTag.replace(new RegExp(matchAttr[1] + \"(['\\\"])(.*?)\\\\1\"), matchAttr[0]);\n }\n }\n if (aXMLRefTag[0] != sXMLNewTag) {\n sXMLRef = sXMLRef.replace(aXMLRefTag[0], sXMLNewTag);\n }\n } else {\n done(sXML, \"missing <\" + matchRef[1] + \"> in \" + sRefFile);\n return;\n }\n }\n\n /*\n * Apparently when a Windows Azure server delivers one of my XML files, it may modify the first line:\n *\n * <?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n\n *\n * I didn't determine exactly what it was doing at this point (probably just changing the \\n to \\r\\n),\n * but in any case, relaxing the following replace() solved it.\n */\n sXMLRef = sXMLRef.replace(/<\\?xml[^>]*>[\\r\\n]*/, \"\");\n\n sXML = sXML.replace(matchRef[0], sXMLRef);\n\n resolveXML(sXML, display, done);\n };\n\n display(\"Loading \" + sRefFile + \"...\");\n Web.getResource(sRefFile, null, fAsync, doneReadXML);\n return;\n }\n done(sXML, null);\n}\n\n/**\n * embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * This allows to you embed a machine on a web page, by transforming the machine XML into HTML.\n *\n * @param {string} sAppName is the app name (eg, \"PCx86\")\n * @param {string} sAppClass is the app class (eg, \"pcx86\"); also known as the machine class\n * @param {string} sVersion is the app version (eg, \"1.15.7\")\n * @param {string} idMachine\n * @param {string|undefined} sXMLFile\n * @param {string|undefined} sXSLFile\n * @param {string|undefined} sParms (machine parameters, if any)\n * @param {string|undefined} sClass (an optional machine class name used to style the machine)\n * @return {boolean} true if successful, false if error\n */\nfunction embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n var eMachine, eWarning, fSuccess = true;\n\n if (!sXMLFile) {\n sXMLFile = \"machine.xml\";\n if (!sXSLFile) sXSLFile = \"components.xsl\";\n }\n \n cAsyncMachines++;\n Component.addMachine(idMachine);\n\n var doneMachine = function() {\n\n if (!--cAsyncMachines) {\n if (fAsync) Web.enablePageEvents(true);\n }\n };\n\n var displayError = function(sError) {\n Component.log(sError);\n displayMessage(\"Error: \" + sError);\n if (fSuccess) doneMachine();\n fSuccess = false;\n };\n\n var displayMessage = function(sMessage) {\n if (eWarning === undefined) {\n /*\n * Our MarkOut module (in convertMDMachineLinks()) creates machine containers that look like:\n *\n * <div id=\"' + sMachineID + '\" class=\"machine-placeholder\"><p>Embedded PC</p><p class=\"machine-warning\">...</p></div>\n *\n * with the \"machine-warning\" paragraph pre-populated with a warning message that the user will\n * see if nothing at all happens. But hopefully, in the normal case (and especially the error case),\n * *something* will have happened.\n *\n * Note that it is the HTMLOut module (in processMachines()) that ultimately decides which scripts to\n * include and then generates the embedXXX() call.\n */\n var aeWarning = (eMachine && Component.getElementsByClass(eMachine, \"machine-warning\"));\n eWarning = (aeWarning && aeWarning[0]) || eMachine;\n }\n if (eWarning) eWarning.innerHTML = Str.escapeHTML(sMessage);\n };\n\n try {\n eMachine = document.getElementById(idMachine);\n if (eMachine) {\n\n /*\n * If we have a 'css' resource, add it to the page first.\n */\n var css;\n if (typeof resources == \"object\" && (css = resources['css'])) {\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n // noinspection JSDeprecatedSymbols\n if (style.styleSheet) {\n // noinspection JSDeprecatedSymbols\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n head.appendChild(style);\n }\n\n if (!sXSLFile) {\n /*\n * Now that PCjs is an open-source project, we can make the following test more flexible,\n * and revert to the internal template if DEBUG *or* internal version (instead of *and*).\n *\n * Third-party sites that don't use the PCjs server will ALWAYS want to specify a fully-qualified\n * path to the XSL file, unless they choose to mirror our folder structure.\n */\n var sAppFolder = sAppClass;\n if (DEBUG || !sVersion) {\n if (sAppClass != \"c1pjs\") sAppFolder = \"shared\";\n sXSLFile = \"/modules/\" + sAppFolder + \"/templates/components.xsl\";\n } else {\n if (sAppClass.substr(0, 3) == \"pdp\") sAppFolder = \"pdpjs\";\n sXSLFile = \"/versions/\" + sAppFolder + \"/\" + sVersion + \"/components.xsl\";\n }\n }\n\n var processXML = function(sXML, xml) {\n if (!xml) {\n displayError(sXML);\n return;\n }\n\n /*\n * Non-COMPILED kludge to extract the version number from the stylesheet path in the machine XML file;\n * we don't need this code in COMPILED (non-DEBUG) releases, because APPVERSION is hard-coded into them.\n */\n if (!COMPILED) {\n var aMatch = sXML.match(/<\\?xml-stylesheet[^>]* href=(['\"])[^'\"]*?\\/([0-9.]*)\\/([^'\"]*)\\1/);\n if (aMatch) {\n XMLVERSION = aMatch[2];\n }\n }\n\n var transformXML = function(sXSL, xsl) {\n if (!xsl) {\n displayError(sXSL);\n return;\n }\n\n /*\n * Record the XSL file, in case someone wants to save the entire machine later.\n * \n * NOTE: sXSLFile will never be undefined by this point, but apparently the Closure Compiler doesn't realize that. \n */\n Component.addMachineResource(idMachine, sXSLFile || \"\", sXSL);\n\n /*\n * The <machine> template in components.xsl now generates a \"machine div\" that makes\n * the div we required the caller of embedMachine() to provide redundant, so instead\n * of appending this fragment to the caller's node, we REPLACE the caller's node.\n * This works only because because we ALSO inject the caller's \"machine div\" ID into\n * the fragment's ID during parseXML().\n *\n * eMachine.innerHTML = sFragment;\n *\n * Also, if the transform function fails, make sure you're using the appropriate\n * \"components.xsl\" and not a \"machine.xsl\", because the latter will not produce valid\n * embeddable HTML (and is the most common cause of failure at this final stage).\n */\n displayMessage(\"Processing \" + sXMLFile + \"...\");\n\n /*\n * Beginning with Microsoft Edge and the corresponding release of Windows 10, all the\n * 'ActiveXObject' crud has gone away; but of course, this code must remain in place if\n * we want to continue supporting older Internet Explorer browsers (ie, back to IE9).\n */\n if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1\n var sFragment = xml['transformNode'](xsl);\n if (sFragment) {\n eMachine.outerHTML = sFragment;\n doneMachine();\n } else {\n displayError(\"transformNodeToObject failed\");\n }\n }\n else if (document.implementation && document.implementation.createDocument) {\n var xsltProcessor = new XSLTProcessor();\n xsltProcessor['importStylesheet'](xsl);\n var eFragment = xsltProcessor['transformToFragment'](xml, document);\n if (eFragment) {\n /*\n * This fails in Microsoft Edge...\n *\n var machine = eFragment.getElementById(idMachine);\n if (!machine) {\n displayError(\"machine generation failed: \" + idMachine);\n } else\n */\n if (eMachine.parentNode) {\n eMachine.parentNode.replaceChild(eFragment, eMachine);\n doneMachine();\n } else {\n /*\n * NOTE: This error can occur if our Node web server, when processing a folder with\n * both a manifest.xml with a machine.xml reference AND a README.md containing a\n * machine link, generates duplicate embedXXX() calls for the same machine; if the\n * first embedXXX() call finds its target, subsequent calls for the same target will\n * fail.\n *\n * Technically, such a folder is in a misconfigured state, but it happens, in part\n * because when we switched to the Jekyll web server, we had to add machine links to\n * all README.md files where we had previously relied on manifest.xml or machine.xml\n * processing. This is because the Jekyll web server currently doesn't process XML\n * files, nor is support for that likely to be added any time soon; it was a nice\n * feature of the Node web server, but it's not clear that it's worth doing for Jekyll.\n */\n displayError(\"invalid machine element: \" + idMachine);\n }\n } else {\n displayError(\"transformToFragment failed\");\n }\n } else {\n /*\n * Perhaps I should have performed this test at the outset; on the other hand, I'm\n * not aware of any browsers don't support one or both of the above XSLT transformation\n * methods, so treat this as a bug.\n */\n displayError(\"unable to transform XML: unsupported browser\");\n }\n };\n /*\n * NOTE: sXSLFile will never be undefined by this point, but apparently the Closure Compiler doesn't realize that. \n */\n loadXML(sXSLFile || \"\", null, sAppName, sAppClass, null, null, false, displayMessage, transformXML);\n };\n\n if (sXMLFile.charAt(0) != '<') {\n loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, true, displayMessage, processXML);\n } else {\n parseXML(sXMLFile, null, idMachine, sAppName, sAppClass, sParms, sClass, false, displayMessage, processXML);\n }\n } else {\n displayError(\"missing machine element: \" + idMachine);\n }\n } catch(e) {\n displayError(e.message);\n }\n return fSuccess;\n}\n\n/**\n * embedC1P(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedC1P(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"C1Pjs\", \"c1pjs\", APPVERSION, idMachine, sXMLFile, sXSLFile, undefined, sClass);\n}\n\n/**\n * embedPCx86(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPCx86(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PCx86\", \"pcx86\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPC8080(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPC8080(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PC8080\", \"pc8080\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPDP10(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPDP10(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PDPjs\", \"pdp10\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPDP11(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPDP11(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PDPjs\", \"pdp11\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * findMachineComponent(idMachine, sType)\n *\n * @param {string} idMachine\n * @param {string} sType\n * @return {Component|null}\n */\nfunction findMachineComponent(idMachine, sType)\n{\n return Component.getComponentByType(sType, idMachine + \".machine\");\n}\n\n/**\n * commandMachine(control, fSingle, idMachine, sComponent, sCommand, sValue)\n *\n * Use Component methods to find the requested component for a specific machine, and if the component is found,\n * then check its 'exports' table for an entry matching the specified command string, and if an entry is found, then\n * the corresponding function is called with the specified data.\n *\n * @param {Object} control\n * @param {boolean} fSingle\n * @param {string} idMachine\n * @param {string} sComponent\n * @param {string} sCommand\n * @param {string} [sValue]\n * @return {boolean}\n */\nfunction commandMachine(control, fSingle, idMachine, sComponent, sCommand, sValue)\n{\n if (sCommand == \"script\") {\n if (Component.processScript(idMachine, sValue)) {\n if (fSingle) control.disabled = true;\n return true;\n }\n return false;\n }\n if (sComponent) {\n var component = Component.getComponentByType(sComponent, idMachine + \".machine\");\n if (component) {\n var exports = component['exports'];\n if (exports) {\n var fnCommand = exports[sCommand];\n if (fnCommand) {\n if (fnCommand.call(component, sValue)) {\n if (fSingle) control.disabled = true;\n return true;\n }\n return false;\n }\n }\n }\n }\n console.log(\"unimplemented: commandMachine('\" + idMachine + \"','\" + sComponent + \"','\" + sCommand + \"','\" + sValue + \"')\");\n return false;\n}\n\n/**\n * Prevent the Closure Compiler from renaming functions we want to export, by adding them as global properties.\n *\n * TODO: Consider making all these functions properties on a single global object (eg, 'PCjs'), to minimize global\n * pollution and risk of name collision.\n */\nif (APPNAME == \"C1Pjs\") {\n window['embedC1P'] = embedC1P;\n}\nif (APPNAME == \"PCx86\") {\n window['embedPC'] = embedPCx86; // WARNING: embedPC() deprecated as of v1.23.0\n window['embedPCx86'] = embedPCx86;\n}\nif (APPNAME == \"PC8080\") {\n window['embedPC8080'] = embedPC8080;\n}\nif (APPNAME == \"PDPjs\") {\n window['embedPDP10'] = embedPDP10;\n window['embedPDP11'] = embedPDP11;\n}\n\nwindow['commandMachine'] = commandMachine;\n\nwindow['enableEvents'] = Web.enablePageEvents;\nwindow['sendEvent'] = Web.sendPageEvent;\n"]} \ No newline at end of file diff --git a/versions/pcx86/1.61.0/pcx86-uncompiled.js b/versions/pcx86/1.61.0/pcx86-uncompiled.js index 9c25676ef6..a0bf66caad 100644 --- a/versions/pcx86/1.61.0/pcx86-uncompiled.js +++ b/versions/pcx86/1.61.0/pcx86-uncompiled.js @@ -857,7 +857,7 @@ class Str { * * Displays the given number as an unsigned integer using the specified radix and number of digits. * - * @param {number|null|undefined} n + * @param {number|*} n * @param {number} radix (ie, the base) * @param {number} cch (the desired number of digits) * @param {string} [sPrefix] (default is none) @@ -867,17 +867,17 @@ class Str { static toBase(n, radix, cch, sPrefix = "", nGrouping = 0) { /* - * An initial "falsey" check for null takes care of both null and undefined; - * we can't rely entirely on isNaN(), because isNaN(null) returns false, oddly enough. + * We can't rely entirely on isNaN(), because isNaN(null) returns false, and we can't rely + * entirely on typeof either, because typeof Nan returns "number". Sigh. * * Alternatively, we could mask and shift n regardless of whether it's null/undefined/NaN, * since JavaScript coerces such operands to zero, but I think there's "value" in seeing those * values displayed differently. */ var s = ""; - if (isNaN(n)) { + if (isNaN(n) || typeof n != "number") { n = null; - } else if (n != null) { + } else { /* * Callers that produced an input by dividing by a power of two rather than shifting (in order * to access more than 32 bits) may produce a fractional result, which ordinarily we would simply @@ -920,7 +920,7 @@ class Str { * * Converts an integer to binary, with the specified number of digits (up to a maximum of 36). * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of binary digits (0 or undefined for default of either 8, 18, or 36) * @param {number} [nGrouping] * @return {string} the binary representation of n @@ -972,7 +972,7 @@ class Str { * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw * an exception, whereas this function will return '?' characters. * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of octal digits (0 or undefined for default of either 6, 8, or 12) * @param {boolean} [fPrefix] * @return {string} the octal representation of n @@ -1002,7 +1002,7 @@ class Str { * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw * an exception, whereas this function will return '?' characters. * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of decimal digits (0 or undefined for default of either 5 or 11) * @return {string} the decimal representation of n */ @@ -1037,7 +1037,7 @@ class Str { * s = "00000000".substr(0, 8 - s.length) + s; * s = s.substr(0, cch).toUpperCase(); * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of hex digits (0 or undefined for default of either 4, 8, or 9) * @param {boolean} [fPrefix] * @return {string} the hex representation of n @@ -3367,7 +3367,7 @@ class Component { if (target) { var control = target.bindings[sBinding]; if (control) { - component.setBinding(null, sBinding, control); + component.setBinding("", sBinding, control); } } } @@ -3855,7 +3855,7 @@ class Component { * Component's setBinding() method is intended to be overridden by subclasses. * * @this {Component} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, 'print') * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -4308,10 +4308,10 @@ class Component { * * @this {Component} * @param {number} port - * @param {number|null} bOut if an output operation - * @param {number|null} [addrFrom] - * @param {string|null} [name] of the port, if any - * @param {number|null} [bIn] is the input value, if known, on an input operation + * @param {number|null|*} bOut if an output operation + * @param {number|null|*} [addrFrom] + * @param {string|null|*} [name] of the port, if any + * @param {number|null|*} [bIn] is the input value, if known, on an input operation * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s) */ printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage) @@ -7861,7 +7861,7 @@ class Panel extends Component { * that doesn't recognize the specified binding should simply ignore it. * * @this {Panel} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -8505,7 +8505,7 @@ class Panel extends Component { * * @this {Panel} * @param {string} sText - * @param {number|null} [nValue] + * @param {number|null|*} [nValue] * @param {number} [nColsSkip] * @param {number} [nLinesSkip] */ @@ -12213,7 +12213,7 @@ class CPU extends Component { for (var i = 0; i < CPU.BUTTONS.length; i++) { var control = this.bindings[CPU.BUTTONS[i]]; - if (control) this.cmp.setBinding(null, CPU.BUTTONS[i], control); + if (control) this.cmp.setBinding("", CPU.BUTTONS[i], control); } this.fpu = cmp.getMachineComponent("FPU"); @@ -12518,7 +12518,7 @@ class CPU extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {CPU} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -16430,7 +16430,7 @@ class CPUX86 extends CPU { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {CPUX86} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -18031,7 +18031,7 @@ Web.onInit(CPUX86.init); */ /** - * class FPUX86 + * @class FPUX86 * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor) */ class FPUX86 extends Component { @@ -19509,1671 +19509,1671 @@ class FPUX86 extends Component { */ /** - * F2XM1() - * - * F2XM1 (2 to the x minus 1) calculates the function 2^x - 1 and returns the result to ST(0). - * - * On the 8087 and 80287, the value in ST(0) must satisfy the inequality 0 <= ST(0) <= 0.5. On the 80287XL and - * later coprocessors, the permissible range is greater, and ST(0) must satisfy the inequality -1 <= ST(0) <= 1. - * If ST(0) is out of range, the result is undefined, even though no exception is raised. - * - * The F2XM1 instruction is designed to provide an accurate result even when x is close to zero. To obtain 2^x, - * simply add 1.0 to the result returned by F2XM1. - * - * This instruction is useful in performing exponentiation of values other than 2 as shown in the following formulas: - * - * 10^x = 2^(x * log2(10)) - * e^x = 2^(x * log2(e)) - * y^x = 2^(x * log2(y)) - * - * Note that the NPX has dedicated instructions for loading the constants log2(10) and log2(e). The FYL2X instruction - * may be used to calculate x * log2(y). - * - * See also: FYL2X, FLDL2T, FLDL2E. + * FPUX86.init() * - * @this {FPUX86} + * This function operates on every HTML element of class "fpu", extracting the + * JSON-encoded parameters for the FPUX86 constructor from the element's "data-value" + * attribute, invoking the constructor to create an FPUX86 component, and then binding + * any associated HTML controls to the new component. */ - static F2XM1() + static init() { - this.setST(0, Math.pow(2, this.getST(0)) - 1); + var aeFPUs = Component.getElementsByClass(document, PCX86.APPCLASS, "fpu"); + for (var iFPU = 0; iFPU < aeFPUs.length; iFPU++) { + var eFPU = aeFPUs[iFPU]; + var parmsFPU = Component.getComponentParms(eFPU); + var fpu = new FPUX86(parmsFPU); + Component.bindComponentControls(fpu, eFPU, PCX86.APPCLASS); + } } +} - /** - * FABS() - * - * @this {FPUX86} - */ - static FABS() - { - /* - * TODO: This could be implemented more efficiently by simply clearing the sign bit of ST(0). - */ - this.setST(0, Math.abs(this.getST(0))); - } +/** + * F2XM1() + * + * F2XM1 (2 to the x minus 1) calculates the function 2^x - 1 and returns the result to ST(0). + * + * On the 8087 and 80287, the value in ST(0) must satisfy the inequality 0 <= ST(0) <= 0.5. On the 80287XL and + * later coprocessors, the permissible range is greater, and ST(0) must satisfy the inequality -1 <= ST(0) <= 1. + * If ST(0) is out of range, the result is undefined, even though no exception is raised. + * + * The F2XM1 instruction is designed to provide an accurate result even when x is close to zero. To obtain 2^x, + * simply add 1.0 to the result returned by F2XM1. + * + * This instruction is useful in performing exponentiation of values other than 2 as shown in the following formulas: + * + * 10^x = 2^(x * log2(10)) + * e^x = 2^(x * log2(e)) + * y^x = 2^(x * log2(y)) + * + * Note that the NPX has dedicated instructions for loading the constants log2(10) and log2(e). The FYL2X instruction + * may be used to calculate x * log2(y). + * + * See also: FYL2X, FLDL2T, FLDL2E. + * + * @this {FPUX86} + */ +FPUX86.F2XM1 = function() +{ + this.setST(0, Math.pow(2, this.getST(0)) - 1); +}; - /** - * FADDlr() - * - * @this {FPUX86} +/** + * FABS() + * + * @this {FPUX86} + */ +FPUX86.FABS = function() +{ + /* + * TODO: This could be implemented more efficiently by simply clearing the sign bit of ST(0). */ - static FADDlr() - { - this.setST(0, this.doAdd(this.getST(0), this.getLRFromEA())); - } + this.setST(0, Math.abs(this.getST(0))); +}; - /** - * FADDsr() - * - * Encoding 0xD8,reg=0x00 ("FADD short-real"): ST(0) <- ST(0) + REAL32 - * - * @this {FPUX86} - */ - static FADDsr() - { - this.setST(0, this.doAdd(this.getST(0), this.getSRFromEA())); - } +/** + * FADDlr() + * + * @this {FPUX86} + */ +FPUX86.FADDlr = function() +{ + this.setST(0, this.doAdd(this.getST(0), this.getLRFromEA())); +}; - /** - * FADDst() - * - * @this {FPUX86} - */ - static FADDst() - { - this.setST(0, this.doAdd(this.getST(0), this.getST(this.iStack))); - } +/** + * FADDsr() + * + * Encoding 0xD8,reg=0x00 ("FADD short-real"): ST(0) <- ST(0) + REAL32 + * + * @this {FPUX86} + */ +FPUX86.FADDsr = function() +{ + this.setST(0, this.doAdd(this.getST(0), this.getSRFromEA())); +}; - /** - * FADDsti() - * - * @this {FPUX86} - */ - static FADDsti() - { - this.setST(this.iStack, this.doAdd(this.getST(this.iStack), this.getST(0))); - } +/** + * FADDst() + * + * @this {FPUX86} + */ +FPUX86.FADDst = function() +{ + this.setST(0, this.doAdd(this.getST(0), this.getST(this.iStack))); +}; - /** - * FADDPsti() - * - * @this {FPUX86} - */ - static FADDPsti() - { - if (this.setST(this.iStack, this.doAdd(this.getST(this.iStack), this.getST(0)))) this.popValue(); - } +/** + * FADDsti() + * + * @this {FPUX86} + */ +FPUX86.FADDsti = function() +{ + this.setST(this.iStack, this.doAdd(this.getST(this.iStack), this.getST(0))); +}; - /** - * FBLDpd() - * - * @this {FPUX86} - */ - static FBLDpd() - { - var a = this.getTRFromEA(); - /* - * a[0] contains the 8 least-significant BCD digits, a[1] contains the next 8, and a[2] contains - * the next 2 (bit 15 of a[2] is the sign bit, and bits 8-14 of a[2] are unused). - */ - var v = this.decodeBCD(a[0], 8) + this.decodeBCD(a[1], 8) * 100000000 + this.decodeBCD(a[2], 2) * 10000000000000000; - if (a[2] & 0x8000) v = -v; - this.pushValue(v); - } +/** + * FADDPsti() + * + * @this {FPUX86} + */ +FPUX86.FADDPsti = function() +{ + if (this.setST(this.iStack, this.doAdd(this.getST(this.iStack), this.getST(0)))) this.popValue(); +}; - /** - * FBSTPpd() - * - * @this {FPUX86} +/** + * FBLDpd() + * + * @this {FPUX86} + */ +FPUX86.FBLDpd = function() +{ + var a = this.getTRFromEA(); + /* + * a[0] contains the 8 least-significant BCD digits, a[1] contains the next 8, and a[2] contains + * the next 2 (bit 15 of a[2] is the sign bit, and bits 8-14 of a[2] are unused). */ - static FBSTPpd() - { - /* - * TODO: Verify the operation of FBSTP (eg, does it signal an exception if abs(value) >= 1000000000000000000?) - */ - var v = this.roundValue(this.popValue()); - if (v != null) { - /* - * intTmpTR[0] will contain the 8 least-significant BCD digits, intTmpTR[1] will contain the next 8, - * and intTmpTR[2] will contain the next 2 (bit 15 of intTmpTR[2] will be the sign bit, and bits 8-14 of - * intTmpTR[2] will be unused). - */ - this.intTmpTR[0] = this.encodeBCD(v, 8); - this.intTmpTR[1] = this.encodeBCD(v / 100000000, 8); - this.intTmpTR[2] = this.encodeBCD(v / 10000000000000000, 2); - if (v < 0) this.intTmpTR[2] |= 0x8000; - this.setEAFromTR(); - } - } + var v = this.decodeBCD(a[0], 8) + this.decodeBCD(a[1], 8) * 100000000 + this.decodeBCD(a[2], 2) * 10000000000000000; + if (a[2] & 0x8000) v = -v; + this.pushValue(v); +}; - /** - * FCHS() - * - * @this {FPUX86} +/** + * FBSTPpd() + * + * @this {FPUX86} + */ +FPUX86.FBSTPpd = function() +{ + /* + * TODO: Verify the operation of FBSTP (eg, does it signal an exception if abs(value) >= 1000000000000000000?) */ - static FCHS() - { + var v = this.roundValue(this.popValue()); + if (v != null) { /* - * TODO: This could be implemented more efficiently by simply inverting the sign bit of ST(0). + * intTmpTR[0] will contain the 8 least-significant BCD digits, intTmpTR[1] will contain the next 8, + * and intTmpTR[2] will contain the next 2 (bit 15 of intTmpTR[2] will be the sign bit, and bits 8-14 of + * intTmpTR[2] will be unused). */ - this.setST(0, -this.getST(0)); + this.intTmpTR[0] = this.encodeBCD(v, 8); + this.intTmpTR[1] = this.encodeBCD(v / 100000000, 8); + this.intTmpTR[2] = this.encodeBCD(v / 10000000000000000, 2); + if (v < 0) this.intTmpTR[2] |= 0x8000; + this.setEAFromTR(); } +}; - /** - * FCLEX() - * - * NOTE: Although we explicitly clear the BUSY bit, there shouldn't be any code setting it, because - * we're never "busy" (all floating-point operations are performed synchronously). Conversely, there's - * no need to explicitly clear the ES bit, because clearStatus() will call checkException(), which - * updates ES and clears/sets FPU interrupt status as appropriate. - * - * @this {FPUX86} +/** + * FCHS() + * + * @this {FPUX86} + */ +FPUX86.FCHS = function() +{ + /* + * TODO: This could be implemented more efficiently by simply inverting the sign bit of ST(0). */ - static FCLEX() - { - this.clearStatus(X86.FPU.STATUS.EXC | X86.FPU.STATUS.BUSY); - } + this.setST(0, -this.getST(0)); +}; - /** - * FCOMlr() - * - * Encoding 0xDC,mod<3,reg=2 ("FCOM long-real"): Evaluate ST(0) - REAL64 - * - * @this {FPUX86} - */ - static FCOMlr() - { - this.doCompare(this.getST(0), this.getLRFromEA()); - } +/** + * FCLEX() + * + * NOTE: Although we explicitly clear the BUSY bit, there shouldn't be any code setting it, because + * we're never "busy" (all floating-point operations are performed synchronously). Conversely, there's + * no need to explicitly clear the ES bit, because clearStatus() will call checkException(), which + * updates ES and clears/sets FPU interrupt status as appropriate. + * + * @this {FPUX86} + */ +FPUX86.FCLEX = function() +{ + this.clearStatus(X86.FPU.STATUS.EXC | X86.FPU.STATUS.BUSY); +}; - /** - * FCOMsr() - * - * Encoding 0xD8,mod<3,reg=2 ("FCOM short-real"): Evaluate ST(0) - REAL32 - * - * @this {FPUX86} - */ - static FCOMsr() - { - this.doCompare(this.getST(0), this.getSRFromEA()); - } +/** + * FCOMlr() + * + * Encoding 0xDC,mod<3,reg=2 ("FCOM long-real"): Evaluate ST(0) - REAL64 + * + * @this {FPUX86} + */ +FPUX86.FCOMlr = function() +{ + this.doCompare(this.getST(0), this.getLRFromEA()); +}; - /** - * FCOMst() - * - * Encoding 0xD8,mod=3,reg=2 ("FCOM ST(i)"): Evaluate ST(0) - ST(i) - * - * @this {FPUX86} - */ - static FCOMst() - { - this.doCompare(this.getST(0), this.getST(this.iStack)); - } +/** + * FCOMsr() + * + * Encoding 0xD8,mod<3,reg=2 ("FCOM short-real"): Evaluate ST(0) - REAL32 + * + * @this {FPUX86} + */ +FPUX86.FCOMsr = function() +{ + this.doCompare(this.getST(0), this.getSRFromEA()); +}; - /** - * FCOM8087() - * - * NOTE: This is used with encoding(s) (0xDC,0xD0-0xD7) that were valid for the 8087 and 80287 - * but may no longer be valid as of the 80387. - * - * TODO: Determine if this form subtracted the operands in the same order, or if it requires an FCOMsti(), - * which, like the other *sti() functions, uses ST(0) as the second operand rather than the first. - * - * @this {FPUX86} - */ - static FCOM8087() - { - this.opObsolete(); - FPUX86.FCOMst.call(this); - } +/** + * FCOMst() + * + * Encoding 0xD8,mod=3,reg=2 ("FCOM ST(i)"): Evaluate ST(0) - ST(i) + * + * @this {FPUX86} + */ +FPUX86.FCOMst = function() +{ + this.doCompare(this.getST(0), this.getST(this.iStack)); +}; - /** - * FCOMPlr() - * - * Encoding 0xDC,mod<3,reg=3 ("FCOM long-real"): Evaluate ST(0) - REAL64, POP - * - * @this {FPUX86} - */ - static FCOMPlr() - { - if (this.doCompare(this.getST(0), this.getLRFromEA())) this.popValue(); - } +/** + * FCOM8087() + * + * NOTE: This is used with encoding(s) (0xDC,0xD0-0xD7) that were valid for the 8087 and 80287 + * but may no longer be valid as of the 80387. + * + * TODO: Determine if this form subtracted the operands in the same order, or if it requires an FCOMsti(), + * which, like the other *sti() functions, uses ST(0) as the second operand rather than the first. + * + * @this {FPUX86} + */ +FPUX86.FCOM8087 = function() +{ + this.opObsolete(); + FPUX86.FCOMst.call(this); +}; - /** - * FCOMPsr() - * - * Encoding 0xD8,mod<3,reg=3 ("FCOM short-real"): Evaluate ST(0) - REAL32, POP - * - * @this {FPUX86} - */ - static FCOMPsr() - { - if (this.doCompare(this.getST(0), this.getSRFromEA())) this.popValue(); - } +/** + * FCOMPlr() + * + * Encoding 0xDC,mod<3,reg=3 ("FCOM long-real"): Evaluate ST(0) - REAL64, POP + * + * @this {FPUX86} + */ +FPUX86.FCOMPlr = function() +{ + if (this.doCompare(this.getST(0), this.getLRFromEA())) this.popValue(); +}; - /** - * FCOMPst() - * - * Encoding 0xD8,mod=3,reg=3 ("FCOMP ST(i)"): Evaluate ST(0) - ST(i), POP - * - * @this {FPUX86} - */ - static FCOMPst() - { - if (this.doCompare(this.getST(0), this.getST(this.iStack))) this.popValue(); - } +/** + * FCOMPsr() + * + * Encoding 0xD8,mod<3,reg=3 ("FCOM short-real"): Evaluate ST(0) - REAL32, POP + * + * @this {FPUX86} + */ +FPUX86.FCOMPsr = function() +{ + if (this.doCompare(this.getST(0), this.getSRFromEA())) this.popValue(); +}; - /** - * FCOMP8087() - * - * NOTE: This is used with encodings (0xDC,0xD8-0xDF and 0xDE,0xD0-0xD7) that were valid for the 8087 - * and 80287 but may no longer be valid as of the 80387. - * - * TODO: Determine if this form subtracted the operands in the same order, or if it requires an FCOMPsti(), - * which, like the other *sti() functions, uses ST(0) as the second operand rather than the first. - * - * @this {FPUX86} - */ - static FCOMP8087() - { - this.opObsolete(); - FPUX86.FCOMPst.call(this); - } +/** + * FCOMPst() + * + * Encoding 0xD8,mod=3,reg=3 ("FCOMP ST(i)"): Evaluate ST(0) - ST(i), POP + * + * @this {FPUX86} + */ +FPUX86.FCOMPst = function() +{ + if (this.doCompare(this.getST(0), this.getST(this.iStack))) this.popValue(); +}; - /** - * FCOMPP() - * - * @this {FPUX86} - */ - static FCOMPP() - { - if (this.doCompare(this.getST(0), this.getST(1)) && this.popValue() != null) this.popValue(); - } +/** + * FCOMP8087() + * + * NOTE: This is used with encodings (0xDC,0xD8-0xDF and 0xDE,0xD0-0xD7) that were valid for the 8087 + * and 80287 but may no longer be valid as of the 80387. + * + * TODO: Determine if this form subtracted the operands in the same order, or if it requires an FCOMPsti(), + * which, like the other *sti() functions, uses ST(0) as the second operand rather than the first. + * + * @this {FPUX86} + */ +FPUX86.FCOMP8087 = function() +{ + this.opObsolete(); + FPUX86.FCOMPst.call(this); +}; - /** - * FDECSTP() - * - * @this {FPUX86} - */ - static FDECSTP() - { - this.iST = (this.iST - 1) & 0x7; - this.regStatus &= ~X86.FPU.STATUS.C1; - } +/** + * FCOMPP() + * + * @this {FPUX86} + */ +FPUX86.FCOMPP = function() +{ + if (this.doCompare(this.getST(0), this.getST(1)) && this.popValue() != null) this.popValue(); +}; - /** - * FDISI8087() - * - * @this {FPUX86} - */ - static FDISI8087() - { - if (this.isModel(X86.FPU.MODEL_8087)) { - this.regControl |= X86.FPU.CONTROL.IEM; - } - } +/** + * FDECSTP() + * + * @this {FPUX86} + */ +FPUX86.FDECSTP = function() +{ + this.iST = (this.iST - 1) & 0x7; + this.regStatus &= ~X86.FPU.STATUS.C1; +}; - /** - * FDIVlr() - * - * @this {FPUX86} - */ - static FDIVlr() - { - this.setST(0, this.doDivide(this.getST(0), this.getLRFromEA())); +/** + * FDISI8087() + * + * @this {FPUX86} + */ +FPUX86.FDISI8087 = function() +{ + if (this.isModel(X86.FPU.MODEL_8087)) { + this.regControl |= X86.FPU.CONTROL.IEM; } +}; - /** - * FDIVsr() - * - * @this {FPUX86} - */ - static FDIVsr() - { - this.setST(0, this.doDivide(this.getST(0), this.getSRFromEA())); - } +/** + * FDIVlr() + * + * @this {FPUX86} + */ +FPUX86.FDIVlr = function() +{ + this.setST(0, this.doDivide(this.getST(0), this.getLRFromEA())); +}; - /** - * FDIVst() - * - * Encoding 0xD8,0xF0-0xF7 ("FDIV ST,ST(i)"): ST(0) <- ST(0) / ST(i) - * - * @this {FPUX86} - */ - static FDIVst() - { - this.setST(0, this.doDivide(this.getST(0), this.getST(this.iStack))); - } +/** + * FDIVsr() + * + * @this {FPUX86} + */ +FPUX86.FDIVsr = function() +{ + this.setST(0, this.doDivide(this.getST(0), this.getSRFromEA())); +}; - /** - * FDIVsti() - * - * Encoding 0xDC,0xF8-0xFF ("FDIV ST(i),ST"): ST(i) <- ST(i) / ST(0) - * - * @this {FPUX86} - */ - static FDIVsti() - { - this.setST(this.iStack, this.doDivide(this.getST(this.iStack), this.getST(0))); - } +/** + * FDIVst() + * + * Encoding 0xD8,0xF0-0xF7 ("FDIV ST,ST(i)"): ST(0) <- ST(0) / ST(i) + * + * @this {FPUX86} + */ +FPUX86.FDIVst = function() +{ + this.setST(0, this.doDivide(this.getST(0), this.getST(this.iStack))); +}; - /** - * FDIVPsti() - * - * Encoding 0xDE,0xF8-0xFF ("FDIVP ST(i),ST"): ST(i) <- ST(i) / ST(0), POP - * - * @this {FPUX86} - */ - static FDIVPsti() - { - if (this.setST(this.iStack, this.doDivide(this.getST(this.iStack), this.getST(0)))) this.popValue(); - } +/** + * FDIVsti() + * + * Encoding 0xDC,0xF8-0xFF ("FDIV ST(i),ST"): ST(i) <- ST(i) / ST(0) + * + * @this {FPUX86} + */ +FPUX86.FDIVsti = function() +{ + this.setST(this.iStack, this.doDivide(this.getST(this.iStack), this.getST(0))); +}; - /** - * FDIVRlr() - * - * @this {FPUX86} - */ - static FDIVRlr() - { - this.setST(0, this.doDivide(this.getLRFromEA(), this.getST(0))); - } +/** + * FDIVPsti() + * + * Encoding 0xDE,0xF8-0xFF ("FDIVP ST(i),ST"): ST(i) <- ST(i) / ST(0), POP + * + * @this {FPUX86} + */ +FPUX86.FDIVPsti = function() +{ + if (this.setST(this.iStack, this.doDivide(this.getST(this.iStack), this.getST(0)))) this.popValue(); +}; - /** - * FDIVRsr() - * - * @this {FPUX86} - */ - static FDIVRsr() - { - this.setST(0, this.doDivide(this.getSRFromEA(), this.getST(0))); - } +/** + * FDIVRlr() + * + * @this {FPUX86} + */ +FPUX86.FDIVRlr = function() +{ + this.setST(0, this.doDivide(this.getLRFromEA(), this.getST(0))); +}; - /** - * FDIVRst() - * - * Encoding 0xD8,0xF8-0xFF ("FDIVR ST,ST(i)"): ST(0) <- ST(i) / ST(0) - * - * @this {FPUX86} - */ - static FDIVRst() - { - this.setST(0, this.doDivide(this.getST(this.iStack), this.getST(0))); - } +/** + * FDIVRsr() + * + * @this {FPUX86} + */ +FPUX86.FDIVRsr = function() +{ + this.setST(0, this.doDivide(this.getSRFromEA(), this.getST(0))); +}; - /** - * FDIVRsti() - * - * Encoding 0xDC,0xF0-0xF7 ("FDIVR ST(i),ST"): ST(i) <- ST(0) / ST(i) - * - * @this {FPUX86} - */ - static FDIVRsti() - { - this.setST(this.iStack, this.doDivide(this.getST(0), this.getST(this.iStack))); - } +/** + * FDIVRst() + * + * Encoding 0xD8,0xF8-0xFF ("FDIVR ST,ST(i)"): ST(0) <- ST(i) / ST(0) + * + * @this {FPUX86} + */ +FPUX86.FDIVRst = function() +{ + this.setST(0, this.doDivide(this.getST(this.iStack), this.getST(0))); +}; - /** - * FDIVRPsti() - * - * Encoding 0xDE,0xF0-0xE7 ("FDIVRP ST(i),ST"): ST(i) <- ST(0) / ST(i), POP - * - * @this {FPUX86} - */ - static FDIVRPsti() - { - if (this.setST(this.iStack, this.doDivide(this.getST(0), this.getST(this.iStack)))) this.popValue(); - } +/** + * FDIVRsti() + * + * Encoding 0xDC,0xF0-0xF7 ("FDIVR ST(i),ST"): ST(i) <- ST(0) / ST(i) + * + * @this {FPUX86} + */ +FPUX86.FDIVRsti = function() +{ + this.setST(this.iStack, this.doDivide(this.getST(0), this.getST(this.iStack))); +}; - /** - * FENI8087() - * - * @this {FPUX86} - */ - static FENI8087() - { - if (this.isModel(X86.FPU.MODEL_8087)) { - this.regControl &= ~X86.FPU.CONTROL.IEM; - } - } +/** + * FDIVRPsti() + * + * Encoding 0xDE,0xF0-0xE7 ("FDIVRP ST(i),ST"): ST(i) <- ST(0) / ST(i), POP + * + * @this {FPUX86} + */ +FPUX86.FDIVRPsti = function() +{ + if (this.setST(this.iStack, this.doDivide(this.getST(0), this.getST(this.iStack)))) this.popValue(); +}; - /** - * FFREEsti() - * - * @this {FPUX86} - */ - static FFREEsti() - { - this.setTag(this.iST, X86.FPU.TAGS.EMPTY); +/** + * FENI8087() + * + * @this {FPUX86} + */ +FPUX86.FENI8087 = function() +{ + if (this.isModel(X86.FPU.MODEL_8087)) { + this.regControl &= ~X86.FPU.CONTROL.IEM; } +}; - /** - * FFREEP8087() - * - * NOTE: This is used with an encoding (0xDF,0xC0-0xC7) that was valid for the 8087 and 80287 - * but may no longer be valid as of the 80387. Also, if the older documentation is to be believed, - * this instruction has no modern counterpart, as FFREE doesn't pop the stack. - * - * @this {FPUX86} - */ - static FFREEP8087() - { - this.opObsolete(); - FPUX86.FFREEsti.call(this); - this.popValue(); - } +/** + * FFREEsti() + * + * @this {FPUX86} + */ +FPUX86.FFREEsti = function() +{ + this.setTag(this.iST, X86.FPU.TAGS.EMPTY); +}; - /** - * FIADD16() - * - * @this {FPUX86} - */ - static FIADD16() - { - this.setST(0, this.doAdd(this.getST(0), this.getWIFromEA())); - } +/** + * FFREEP8087() + * + * NOTE: This is used with an encoding (0xDF,0xC0-0xC7) that was valid for the 8087 and 80287 + * but may no longer be valid as of the 80387. Also, if the older documentation is to be believed, + * this instruction has no modern counterpart, as FFREE doesn't pop the stack. + * + * @this {FPUX86} + */ +FPUX86.FFREEP8087 = function() +{ + this.opObsolete(); + FPUX86.FFREEsti.call(this); + this.popValue(); +}; - /** - * FIADD32() - * - * @this {FPUX86} - */ - static FIADD32() - { - this.setST(0, this.doAdd(this.getST(0), this.getSIFromEA())); - } +/** + * FIADD16() + * + * @this {FPUX86} + */ +FPUX86.FIADD16 = function() +{ + this.setST(0, this.doAdd(this.getST(0), this.getWIFromEA())); +}; - /** - * FICOM16() - * - * @this {FPUX86} - */ - static FICOM16() - { - this.doCompare(this.getST(0), this.getWIFromEA()); - } +/** + * FIADD32() + * + * @this {FPUX86} + */ +FPUX86.FIADD32 = function() +{ + this.setST(0, this.doAdd(this.getST(0), this.getSIFromEA())); +}; - /** - * FICOM32() - * - * @this {FPUX86} - */ - static FICOM32() - { - this.doCompare(this.getST(0), this.getSIFromEA()); - } +/** + * FICOM16() + * + * @this {FPUX86} + */ +FPUX86.FICOM16 = function() +{ + this.doCompare(this.getST(0), this.getWIFromEA()); +}; - /** - * FICOMP16() - * - * @this {FPUX86} - */ - static FICOMP16() - { - if (this.doCompare(this.getST(0), this.getWIFromEA())) this.popValue(); - } +/** + * FICOM32() + * + * @this {FPUX86} + */ +FPUX86.FICOM32 = function() +{ + this.doCompare(this.getST(0), this.getSIFromEA()); +}; - /** - * FICOMP32() - * - * @this {FPUX86} - */ - static FICOMP32() - { - if (this.doCompare(this.getST(0), this.getSIFromEA())) this.popValue(); - } +/** + * FICOMP16() + * + * @this {FPUX86} + */ +FPUX86.FICOMP16 = function() +{ + if (this.doCompare(this.getST(0), this.getWIFromEA())) this.popValue(); +}; - /** - * FIDIV16() - * - * @this {FPUX86} - */ - static FIDIV16() - { - this.setST(0, this.doDivide(this.getST(0), this.getWIFromEA())); - } +/** + * FICOMP32() + * + * @this {FPUX86} + */ +FPUX86.FICOMP32 = function() +{ + if (this.doCompare(this.getST(0), this.getSIFromEA())) this.popValue(); +}; - /** - * FIDIV32() - * - * @this {FPUX86} - */ - static FIDIV32() - { - this.setST(0, this.doDivide(this.getST(0), this.getSIFromEA())); - } +/** + * FIDIV16() + * + * @this {FPUX86} + */ +FPUX86.FIDIV16 = function() +{ + this.setST(0, this.doDivide(this.getST(0), this.getWIFromEA())); +}; - /** - * FIDIVR16() - * - * @this {FPUX86} - */ - static FIDIVR16() - { - this.setST(0, this.doDivide(this.getWIFromEA(), this.getST(0))); - } +/** + * FIDIV32() + * + * @this {FPUX86} + */ +FPUX86.FIDIV32 = function() +{ + this.setST(0, this.doDivide(this.getST(0), this.getSIFromEA())); +}; - /** - * FIDIVR32() - * - * @this {FPUX86} - */ - static FIDIVR32() - { - this.setST(0, this.doDivide(this.getSIFromEA(), this.getST(0))); - } +/** + * FIDIVR16() + * + * @this {FPUX86} + */ +FPUX86.FIDIVR16 = function() +{ + this.setST(0, this.doDivide(this.getWIFromEA(), this.getST(0))); +}; - /** - * FILD16() - * - * @this {FPUX86} - */ - static FILD16() - { - this.pushValue(this.getWIFromEA()); - } +/** + * FIDIVR32() + * + * @this {FPUX86} + */ +FPUX86.FIDIVR32 = function() +{ + this.setST(0, this.doDivide(this.getSIFromEA(), this.getST(0))); +}; - /** - * FILD32() - * - * @this {FPUX86} - */ - static FILD32() - { - this.pushValue(this.getSIFromEA()); - } +/** + * FILD16() + * + * @this {FPUX86} + */ +FPUX86.FILD16 = function() +{ + this.pushValue(this.getWIFromEA()); +}; - /** - * FILD64() - * - * @this {FPUX86} - */ - static FILD64() - { - this.pushValue(this.getLIFromEA()); - } +/** + * FILD32() + * + * @this {FPUX86} + */ +FPUX86.FILD32 = function() +{ + this.pushValue(this.getSIFromEA()); +}; - /** - * FIMUL16() - * - * @this {FPUX86} - */ - static FIMUL16() - { - this.setST(0, this.doMultiply(this.getST(0), this.getWIFromEA())); - } +/** + * FILD64() + * + * @this {FPUX86} + */ +FPUX86.FILD64 = function() +{ + this.pushValue(this.getLIFromEA()); +}; - /** - * FIMUL32() - * - * @this {FPUX86} - */ - static FIMUL32() - { - this.setST(0, this.doMultiply(this.getST(0), this.getSIFromEA())); - } +/** + * FIMUL16() + * + * @this {FPUX86} + */ +FPUX86.FIMUL16 = function() +{ + this.setST(0, this.doMultiply(this.getST(0), this.getWIFromEA())); +}; - /** - * FINCSTP() - * - * @this {FPUX86} - */ - static FINCSTP() - { - this.iST = (this.iST + 1) & 0x7; - this.regStatus &= ~X86.FPU.STATUS.C1; - } +/** + * FIMUL32() + * + * @this {FPUX86} + */ +FPUX86.FIMUL32 = function() +{ + this.setST(0, this.doMultiply(this.getST(0), this.getSIFromEA())); +}; - /** - * FINIT() - * - * @this {FPUX86} - */ - static FINIT() - { - this.resetFPU(); - } +/** + * FINCSTP() + * + * @this {FPUX86} + */ +FPUX86.FINCSTP = function() +{ + this.iST = (this.iST + 1) & 0x7; + this.regStatus &= ~X86.FPU.STATUS.C1; +}; - /** - * FIST16() - * - * @this {FPUX86} - */ - static FIST16() - { - if (this.getWI(0)) this.setEAFromWI(); - } +/** + * FINIT() + * + * @this {FPUX86} + */ +FPUX86.FINIT = function() +{ + this.resetFPU(); +}; - /** - * FIST32() - * - * @this {FPUX86} - */ - static FIST32() - { - if (this.getSI(0)) this.setEAFromSI(); - } +/** + * FIST16() + * + * @this {FPUX86} + */ +FPUX86.FIST16 = function() +{ + if (this.getWI(0)) this.setEAFromWI(); +}; - /** - * FISTP16() - * - * @this {FPUX86} - */ - static FISTP16() - { - if (this.getWI(0)) { - this.setEAFromWI(); - this.popValue(); - } - } +/** + * FIST32() + * + * @this {FPUX86} + */ +FPUX86.FIST32 = function() +{ + if (this.getSI(0)) this.setEAFromSI(); +}; - /** - * FISTP32() - * - * @this {FPUX86} - */ - static FISTP32() - { - if (this.getSI(0)) { - this.setEAFromSI(); - this.popValue(); - } +/** + * FISTP16() + * + * @this {FPUX86} + */ +FPUX86.FISTP16 = function() +{ + if (this.getWI(0)) { + this.setEAFromWI(); + this.popValue(); } +}; - /** - * FISTP64() - * - * @this {FPUX86} - */ - static FISTP64() - { - if (this.getLI(0)) { - this.setEAFromLI(); - this.popValue(); - } +/** + * FISTP32() + * + * @this {FPUX86} + */ +FPUX86.FISTP32 = function() +{ + if (this.getSI(0)) { + this.setEAFromSI(); + this.popValue(); } +}; - /** - * FISUB16() - * - * @this {FPUX86} - */ - static FISUB16() - { - this.setST(0, this.doSubtract(this.getST(0), this.getWIFromEA())); +/** + * FISTP64() + * + * @this {FPUX86} + */ +FPUX86.FISTP64 = function() +{ + if (this.getLI(0)) { + this.setEAFromLI(); + this.popValue(); } +}; - /** - * FISUB32() - * - * @this {FPUX86} - */ - static FISUB32() - { - this.setST(0, this.doSubtract(this.getST(0), this.getSIFromEA())); - } +/** + * FISUB16() + * + * @this {FPUX86} + */ +FPUX86.FISUB16 = function() +{ + this.setST(0, this.doSubtract(this.getST(0), this.getWIFromEA())); +}; - /** - * FISUBR16() - * - * @this {FPUX86} - */ - static FISUBR16() - { - this.setST(0, this.doSubtract(this.getWIFromEA(), this.getST(0))); - } +/** + * FISUB32() + * + * @this {FPUX86} + */ +FPUX86.FISUB32 = function() +{ + this.setST(0, this.doSubtract(this.getST(0), this.getSIFromEA())); +}; - /** - * FISUBR32() - * - * @this {FPUX86} - */ - static FISUBR32() - { - this.setST(0, this.doSubtract(this.getSIFromEA(), this.getST(0))); - } +/** + * FISUBR16() + * + * @this {FPUX86} + */ +FPUX86.FISUBR16 = function() +{ + this.setST(0, this.doSubtract(this.getWIFromEA(), this.getST(0))); +}; - /** - * FLDlr() - * - * The FLD instruction loads the source operand, converts it to temporary real format (if required), - * and pushes the resulting value onto the floating-point stack. - * - * The load operation is accomplished by decrementing the top-of-stack pointer (TOP) and copying the - * source operand to the new stack top. If the source operand is a float ing-point register, the index of - * the register is taken before TOP is changed. The source operand may also be a short real, long real, - * or temporary real memory operand. Short real and long real operands are converted automatically. - * - * Note that coding the instruction FLD ST(0) duplicates the value at the stack top. - * - * On the 8087 and 80287, the FLD real80 instruction will raise the denormal exception if the memory - * operand is a denormal. The 80287XL and later coprocessors will not, since the operation is not arithmetic. - * - * On the 8087 and 80287, a denormal will be converted to an unnormal by FLD; on the 80287XL and later - * coprocessors, the number will be converted to temporary real. If the next instruction is an FXTRACT or FXAM, - * the 8087/80827 and 80287XL/80387/ 80486 results will be different. - * - * On the 8087 and 80287, the FLD real32 and FLD real64 instructions will not raise an exception when loading - * a signaling NaN; on the 80287XL and later coprocessors, loading a signaling NaN raises the invalid operation - * exception. - * - * @this {FPUX86} - */ - static FLDlr() - { - this.pushValue(this.getLRFromEA()); - } +/** + * FISUBR32() + * + * @this {FPUX86} + */ +FPUX86.FISUBR32 = function() +{ + this.setST(0, this.doSubtract(this.getSIFromEA(), this.getST(0))); +}; - /** - * FLDsr() - * - * @this {FPUX86} - */ - static FLDsr() - { - this.pushValue(this.getSRFromEA()); - } +/** + * FLDlr() + * + * The FLD instruction loads the source operand, converts it to temporary real format (if required), + * and pushes the resulting value onto the floating-point stack. + * + * The load operation is accomplished by decrementing the top-of-stack pointer (TOP) and copying the + * source operand to the new stack top. If the source operand is a float ing-point register, the index of + * the register is taken before TOP is changed. The source operand may also be a short real, long real, + * or temporary real memory operand. Short real and long real operands are converted automatically. + * + * Note that coding the instruction FLD ST(0) duplicates the value at the stack top. + * + * On the 8087 and 80287, the FLD real80 instruction will raise the denormal exception if the memory + * operand is a denormal. The 80287XL and later coprocessors will not, since the operation is not arithmetic. + * + * On the 8087 and 80287, a denormal will be converted to an unnormal by FLD; on the 80287XL and later + * coprocessors, the number will be converted to temporary real. If the next instruction is an FXTRACT or FXAM, + * the 8087/80827 and 80287XL/80387/ 80486 results will be different. + * + * On the 8087 and 80287, the FLD real32 and FLD real64 instructions will not raise an exception when loading + * a signaling NaN; on the 80287XL and later coprocessors, loading a signaling NaN raises the invalid operation + * exception. + * + * @this {FPUX86} + */ +FPUX86.FLDlr = function() +{ + this.pushValue(this.getLRFromEA()); +}; - /** - * FLDsti() - * - * @this {FPUX86} - */ - static FLDsti() - { - this.pushValue(this.getST(this.iStack)); - } +/** + * FLDsr() + * + * @this {FPUX86} + */ +FPUX86.FLDsr = function() +{ + this.pushValue(this.getSRFromEA()); +}; - /** - * FLDtr() - * - * @this {FPUX86} - */ - static FLDtr() - { - this.pushValue(this.getLRFromTR(this.getTRFromEA())); - } +/** + * FLDsti() + * + * @this {FPUX86} + */ +FPUX86.FLDsti = function() +{ + this.pushValue(this.getST(this.iStack)); +}; - /** - * FLDCW() - * - * @this {FPUX86} - */ - static FLDCW() - { +/** + * FLDtr() + * + * @this {FPUX86} + */ +FPUX86.FLDtr = function() +{ + this.pushValue(this.getLRFromTR(this.getTRFromEA())); +}; - this.setControl(this.cpu.getShort(this.cpu.regEA)); - } +/** + * FLDCW() + * + * @this {FPUX86} + */ +FPUX86.FLDCW = function() +{ - /** - * FLDENV() - * - * @this {FPUX86} - */ - static FLDENV() - { + this.setControl(this.cpu.getShort(this.cpu.regEA)); +}; - this.loadEnv(this.cpu.regEA); - } +/** + * FLDENV() + * + * @this {FPUX86} + */ +FPUX86.FLDENV = function() +{ - /** - * FLD1() - * - * The FLD1 instruction loads the constant +1.0 from the NPX's constant ROM and pushes the value onto the - * floating-point stack. - * - * The constant is stored internally in temporary real format and is simply moved to the stack. - * - * See also: FLDLG2, FLDLN2, FLDL2E, FLDL2T, FLDPI, and FLD1. - * - * @this {FPUX86} - */ - static FLD1() - { - this.pushValue(1.0); - } + this.loadEnv(this.cpu.regEA); +}; - /** - * FLDL2T() - * - * The FLDL2T instruction loads the constant log2(10) from the NPX's constant ROM and pushes the value onto the - * floating-point stack. - * - * The constant is stored internally in temporary real format and is simply moved to the stack. - * - * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and - * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0), round down (toward - * -infinity), or round to nearest or even, the result will be the same as on the 8087 and 80287. If RC is set for - * round up (toward +infinity), the result will differ by one in the least significant bit of the mantissa. - * - * See also: FLDLG2, FLDLN2, FLDL2E, FLDPI, FLD1, and FLDZ. - * - * @this {FPUX86} - */ - static FLDL2T() - { - this.pushValue(FPUX86.regL2T); - } +/** + * FLD1() + * + * The FLD1 instruction loads the constant +1.0 from the NPX's constant ROM and pushes the value onto the + * floating-point stack. + * + * The constant is stored internally in temporary real format and is simply moved to the stack. + * + * See also: FLDLG2, FLDLN2, FLDL2E, FLDL2T, FLDPI, and FLD1. + * + * @this {FPUX86} + */ +FPUX86.FLD1 = function() +{ + this.pushValue(1.0); +}; - /** - * FLDL2E() - * - * The FLDL2E instruction loads the constant log2(e) from the NPX's constant ROM and pushes the value onto the - * floating-point stack. - * - * The constant is stored internally in temporary real format and is simply moved to the stack. - * - * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and - * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward - * -infinity), the result is the same as on the 8087 and 80827. If RC is set for round to nearest or even, or round - * up (toward +infinity), the result will differ by one in the least significant bit of the mantissa. - * - * See also: FLDLG2, FLDLN2, FLDL2T, FLDPI, FLD1, and FLDZ. - * - * @this {FPUX86} - */ - static FLDL2E() - { - this.pushValue(FPUX86.regL2E); - } +/** + * FLDL2T() + * + * The FLDL2T instruction loads the constant log2(10) from the NPX's constant ROM and pushes the value onto the + * floating-point stack. + * + * The constant is stored internally in temporary real format and is simply moved to the stack. + * + * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and + * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0), round down (toward + * -infinity), or round to nearest or even, the result will be the same as on the 8087 and 80287. If RC is set for + * round up (toward +infinity), the result will differ by one in the least significant bit of the mantissa. + * + * See also: FLDLG2, FLDLN2, FLDL2E, FLDPI, FLD1, and FLDZ. + * + * @this {FPUX86} + */ +FPUX86.FLDL2T = function() +{ + this.pushValue(FPUX86.regL2T); +}; - /** - * FLDPI() - * - * The FLDPI instruction loads the constant Pi from the NPX's constant ROM and pushes the value onto the - * floating-point stack. - * - * The constant is stored internally in temporary real format and is simply moved to the stack. - * - * On the 8087 and 80287, rounding control is not in effect for the loading of these constants. On the 80287XL and - * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward - * -infinity), the result is the same as on the 8087 and 80827. If RC is set for round to nearest or even, or round - * up (toward +infinity), the result will differ by one in the least significant bit of the mantissa. - * - * See also: FLDLG2, FLDLN2, FLDL2E, FLDL2T, FLD1, and FLDZ. - * - * @this {FPUX86} - */ - static FLDPI() - { - this.pushValue(FPUX86.regPI); - } +/** + * FLDL2E() + * + * The FLDL2E instruction loads the constant log2(e) from the NPX's constant ROM and pushes the value onto the + * floating-point stack. + * + * The constant is stored internally in temporary real format and is simply moved to the stack. + * + * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and + * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward + * -infinity), the result is the same as on the 8087 and 80827. If RC is set for round to nearest or even, or round + * up (toward +infinity), the result will differ by one in the least significant bit of the mantissa. + * + * See also: FLDLG2, FLDLN2, FLDL2T, FLDPI, FLD1, and FLDZ. + * + * @this {FPUX86} + */ +FPUX86.FLDL2E = function() +{ + this.pushValue(FPUX86.regL2E); +}; - /** - * FLDLG2() - * - * The FLDLG2 instruction loads the constant log10(2) from the NPX's constant ROM and pushes the value onto the - * floating-point stack. - * - * The constant is stored internally in temporary real format and is simply moved to the stack. - * - * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and - * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward - * -infinity), the result is the same as on the 8087 and 80827. If RC is set for round to nearest or even, or round - * up (toward +infinity), the result will differ by one in the least significant bit of the mantissa. - * - * See also: FLDLN2, FLDL2E, FLDL2T, FLDPI, FLD1, and FLDZ. - * - * @this {FPUX86} - */ - static FLDLG2() - { - this.pushValue(FPUX86.regLG2); - } +/** + * FLDPI() + * + * The FLDPI instruction loads the constant Pi from the NPX's constant ROM and pushes the value onto the + * floating-point stack. + * + * The constant is stored internally in temporary real format and is simply moved to the stack. + * + * On the 8087 and 80287, rounding control is not in effect for the loading of these constants. On the 80287XL and + * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward + * -infinity), the result is the same as on the 8087 and 80827. If RC is set for round to nearest or even, or round + * up (toward +infinity), the result will differ by one in the least significant bit of the mantissa. + * + * See also: FLDLG2, FLDLN2, FLDL2E, FLDL2T, FLD1, and FLDZ. + * + * @this {FPUX86} + */ +FPUX86.FLDPI = function() +{ + this.pushValue(FPUX86.regPI); +}; - /** - * FLDLN2() - * - * The FLDLN2 instruction loads the constant loge(2) from the NPX's constant ROM and pushes the value onto the - * floating-point stack. - * - * The constant is stored internally in temporary real format and is simply moved to the stack. - * - * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and - * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward - * -infinity), the result will be the same as on the 8087 and 80827. If RC is set for round to nearest or even, or - * round up (toward +infinity), the result will differ by one in the least significant bit of the mantissa. - * - * See also: FLDLG2, FLDL2E, FLDL2T, FLDPI, FLD1, and FLDZ. - * - * @this {FPUX86} - */ - static FLDLN2() - { - this.pushValue(FPUX86.regLN2); - } +/** + * FLDLG2() + * + * The FLDLG2 instruction loads the constant log10(2) from the NPX's constant ROM and pushes the value onto the + * floating-point stack. + * + * The constant is stored internally in temporary real format and is simply moved to the stack. + * + * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and + * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward + * -infinity), the result is the same as on the 8087 and 80827. If RC is set for round to nearest or even, or round + * up (toward +infinity), the result will differ by one in the least significant bit of the mantissa. + * + * See also: FLDLN2, FLDL2E, FLDL2T, FLDPI, FLD1, and FLDZ. + * + * @this {FPUX86} + */ +FPUX86.FLDLG2 = function() +{ + this.pushValue(FPUX86.regLG2); +}; - /** - * FLDZ() - * - * The FLDZ instruction loads the constant +0.0 from the NPX's constant ROM and pushes the value onto the - * floating-point stack. - * - * The constant is stored internally in temporary real format and is simply moved to the stack. - * - * See also: FLDLG2, FLDLN2, FLDL2E, FLDL2T, FLDPI, and FLD1. - * - * @this {FPUX86} - */ - static FLDZ() - { - this.pushValue(0.0); - } +/** + * FLDLN2() + * + * The FLDLN2 instruction loads the constant loge(2) from the NPX's constant ROM and pushes the value onto the + * floating-point stack. + * + * The constant is stored internally in temporary real format and is simply moved to the stack. + * + * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and + * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward + * -infinity), the result will be the same as on the 8087 and 80827. If RC is set for round to nearest or even, or + * round up (toward +infinity), the result will differ by one in the least significant bit of the mantissa. + * + * See also: FLDLG2, FLDL2E, FLDL2T, FLDPI, FLD1, and FLDZ. + * + * @this {FPUX86} + */ +FPUX86.FLDLN2 = function() +{ + this.pushValue(FPUX86.regLN2); +}; - /** - * FMULlr() - * - * @this {FPUX86} - */ - static FMULlr() - { - this.setST(0, this.doMultiply(this.getST(0), this.getLRFromEA())); - } +/** + * FLDZ() + * + * The FLDZ instruction loads the constant +0.0 from the NPX's constant ROM and pushes the value onto the + * floating-point stack. + * + * The constant is stored internally in temporary real format and is simply moved to the stack. + * + * See also: FLDLG2, FLDLN2, FLDL2E, FLDL2T, FLDPI, and FLD1. + * + * @this {FPUX86} + */ +FPUX86.FLDZ = function() +{ + this.pushValue(0.0); +}; - /** - * FMULsr() - * - * Encoding 0xD8,reg=0x01 ("FMUL short-real"): ST(0) <- ST(0) * REAL32 - * - * @this {FPUX86} - */ - static FMULsr() - { - this.setST(0, this.doMultiply(this.getST(0), this.getSRFromEA())); - } +/** + * FMULlr() + * + * @this {FPUX86} + */ +FPUX86.FMULlr = function() +{ + this.setST(0, this.doMultiply(this.getST(0), this.getLRFromEA())); +}; - /** - * FMULst() - * - * @this {FPUX86} - */ - static FMULst() - { - this.setST(0, this.doMultiply(this.getST(0), this.getST(this.iStack))); - } +/** + * FMULsr() + * + * Encoding 0xD8,reg=0x01 ("FMUL short-real"): ST(0) <- ST(0) * REAL32 + * + * @this {FPUX86} + */ +FPUX86.FMULsr = function() +{ + this.setST(0, this.doMultiply(this.getST(0), this.getSRFromEA())); +}; - /** - * FMULsti() - * - * @this {FPUX86} - */ - static FMULsti() - { - this.setST(this.iStack, this.doMultiply(this.getST(this.iStack), this.getST(0))); - } +/** + * FMULst() + * + * @this {FPUX86} + */ +FPUX86.FMULst = function() +{ + this.setST(0, this.doMultiply(this.getST(0), this.getST(this.iStack))); +}; - /** - * FMULPsti() - * - * @this {FPUX86} - */ - static FMULPsti() - { - if (this.setST(this.iStack, this.doMultiply(this.getST(this.iStack), this.getST(0)))) this.popValue(); - } +/** + * FMULsti() + * + * @this {FPUX86} + */ +FPUX86.FMULsti = function() +{ + this.setST(this.iStack, this.doMultiply(this.getST(this.iStack), this.getST(0))); +}; - /** - * FNOP() - * - * @this {FPUX86} - */ - static FNOP() - { - } +/** + * FMULPsti() + * + * @this {FPUX86} + */ +FPUX86.FMULPsti = function() +{ + if (this.setST(this.iStack, this.doMultiply(this.getST(this.iStack), this.getST(0)))) this.popValue(); +}; - /** - * FPATAN() - * - * FPATAN calculates the partial arctangent of ST(0) divided by ST(1): - * - * ST(1) = tan^-1( ST(1) / ST(0) ) - * - * On the 8087 and 80287, the arguments must satisfy the inequality 0 <= ST(1) < ST(0) < +infinity. - * On the 80287XL and later coprocessors, the range of the operands is unrestricted. The result is - * returned to ST(1), and the stack is popped, destroying both operands and leaving the result in ST(0). - * - * @this {FPUX86} - */ - static FPATAN() - { - if (this.setST(1, Math.atan2(this.getST(1), this.getST(0)))) this.popValue(); - } +/** + * FNOP() + * + * @this {FPUX86} + */ +FPUX86.FNOP = function() +{ +}; - /** - * FPTAN() - * - * FPTAN calculates the partial tangent of ST(0): - * - * y / x = tan( ST(0) ) - * - * The result of the operation is a ratio. y replaces the argument on the stack, and x is pushed onto the stack, - * where it becomes the new ST(0). - * - * On the 8087 and 80287, the FPTAN function assumes that its argument is valid and in-range. No argument checking - * is performed. The value of ST(0) must satisfy the inequality -pi/4 <= ST(0) <= pi/4. In the case of an invalid - * argument, the result is undefined and no error is signaled. - * - * On the 80287XL and later coprocessors, if value of ST(0) satisfies the condition -2^63 < ST(0) < 2^63, it will - * automatically be reduced to within range. If the operand is outside this range, however, C2 is set to 1 to indicate - * that the function is incomplete, and ST(0) is left unchanged. - * - * The 80287XL, 80387, and 80486 always push a value of +1.0 for x. The value of x pushed by the 8087 and 80287 may be - * any real number. In either case, the ratio is the same. The cotangent can be calculated by executing FDIVR immediately - * after FPTAN. The following code will leave the 8087 and 80287 in the same state as the later coprocessors: - * - * FDIV - * FLD1 - * - * ST(7) must be empty before this instruction is executed to avoid an invalid operation exception. If the invalid - * operation exception is masked, the 8087 and 80287 leave the original operand unchanged, but push it to ST(1). On the - * 80287XL and later coprocessors, both ST(0) and ST(1) will contain quiet NaNs. On the 80287XL and later coprocessors, - * if condition code bit C2 is 0 and the precision exception is raised, then C1=1 if the last bit was rounded up. C1 is - * undefined for the 8087 and 80287. - * - * @this {FPUX86} - */ - static FPTAN() - { - if (this.setST(0, Math.tan(this.getST(0)))) this.pushValue(1.0); - } +/** + * FPATAN() + * + * FPATAN calculates the partial arctangent of ST(0) divided by ST(1): + * + * ST(1) = tan^-1( ST(1) / ST(0) ) + * + * On the 8087 and 80287, the arguments must satisfy the inequality 0 <= ST(1) < ST(0) < +infinity. + * On the 80287XL and later coprocessors, the range of the operands is unrestricted. The result is + * returned to ST(1), and the stack is popped, destroying both operands and leaving the result in ST(0). + * + * @this {FPUX86} + */ +FPUX86.FPATAN = function() +{ + if (this.setST(1, Math.atan2(this.getST(1), this.getST(0)))) this.popValue(); +}; - /** - * FPREM() - * - * FPREM performs modulo division of ST(0) by ST(1) and returns the result to ST(0). - * - * The FPREM instruction is used to reduce the real operand in ST(0) to a value whose magnitude is less than the - * magnitude of ST(1). FPREM produces an exact result, so the precision exception is never raised and the rounding - * control has no effect. The sign of the remainder is the same as the sign of the original operand. - * - * The remaindering operation is performed by iterative scaled subtractions and can reduce the exponent of ST(0) by - * no more than 63 in one execution. If the remainder is less than ST(1) (the modulus), the function is complete and - * C2 in the status word is cleared. - * - * If the modulo function is incomplete, C2 is set to 1, and the result in ST(0) is termed the partial remainder. - * C2 can be inspected by storing the status word and re-executing the instruction until C2 is clear. Alternately, - * ST(0) can be compared to ST(1). If ST(0) > ST(1), then FPREM must be executed again. If ST(0) = ST(1), then the - * remainder is 0. - * - * FPREM is important for reducing arguments to the periodic transcendental functions such as FPTAN. Because FPREM - * produces an exact result, no round-off error is introduced into the calculation. - * - * When reduction is complete, the three least-significant bits of the quotient are stored in the condition code bits - * C3, C1, and C0, respectively. When arguments to the tangent function are reduced by pi/4, this result can be used - * to identify the octant that contained the original angle. - * - * The FPREM function operates differently than specified by the IEEE 754 standard when rounding the quotient to form - * a partial remainder (see the algorithm). The FPREM1 function (80287XL and up) is provided for compatibility with - * that standard. - * - * The FPREM instruction can also be used to normalize ST(0). If ST(0) is unnormal and ST(1) is greater than ST(0), - * FPREM will normalize ST(0). On the 8087 and 80287, operation on a denormal operand raises the invalid operation - * exception. Underflow is not possible. On the 80287XL and later coprocessors, operation on a denormal is supported - * and an underflow exception can occur. - * - * ALGORITHM: - * - * t = EXPONENT(ST) - EXPONENT(ST(1)) - * IF (t < 64) THEN - * q = R0UND(ST(0) / ST(1), CHOP) - * ST(0) = ST(0) - (ST(1) * q) - * C2 = 0 - * C0 = BIT 2 of q - * C1 = BIT 1 of q - * C3 = BIT 0 of q - * ELSE - * n = a number between 32 and 63 - * q = ROUND((ST(0) / ST(1)) / 2^(t-n), CHOP) - * ST(0) = ST(0) - (ST(1) * q * 2^(t-n)) - * C2 = 1 - * ENDIF - * - * TODO: Determine the extent to which the JavaScript MOD operator differs from the above algorithm. - * - * ERRATA: On the 8087 and 80287, the condition code bits C3, C1, and C0 are incorrect when performing a reduction of - * 64^n + m, where n >= 1, and m=1 or m=2. A bug fix should be implemented in software. - * - * @this {FPUX86} - */ - static FPREM() - { - this.setST(0, this.getST(0) % this.getST(1)); - } +/** + * FPTAN() + * + * FPTAN calculates the partial tangent of ST(0): + * + * y / x = tan( ST(0) ) + * + * The result of the operation is a ratio. y replaces the argument on the stack, and x is pushed onto the stack, + * where it becomes the new ST(0). + * + * On the 8087 and 80287, the FPTAN function assumes that its argument is valid and in-range. No argument checking + * is performed. The value of ST(0) must satisfy the inequality -pi/4 <= ST(0) <= pi/4. In the case of an invalid + * argument, the result is undefined and no error is signaled. + * + * On the 80287XL and later coprocessors, if value of ST(0) satisfies the condition -2^63 < ST(0) < 2^63, it will + * automatically be reduced to within range. If the operand is outside this range, however, C2 is set to 1 to indicate + * that the function is incomplete, and ST(0) is left unchanged. + * + * The 80287XL, 80387, and 80486 always push a value of +1.0 for x. The value of x pushed by the 8087 and 80287 may be + * any real number. In either case, the ratio is the same. The cotangent can be calculated by executing FDIVR immediately + * after FPTAN. The following code will leave the 8087 and 80287 in the same state as the later coprocessors: + * + * FDIV + * FLD1 + * + * ST(7) must be empty before this instruction is executed to avoid an invalid operation exception. If the invalid + * operation exception is masked, the 8087 and 80287 leave the original operand unchanged, but push it to ST(1). On the + * 80287XL and later coprocessors, both ST(0) and ST(1) will contain quiet NaNs. On the 80287XL and later coprocessors, + * if condition code bit C2 is 0 and the precision exception is raised, then C1=1 if the last bit was rounded up. C1 is + * undefined for the 8087 and 80287. + * + * @this {FPUX86} + */ +FPUX86.FPTAN = function() +{ + if (this.setST(0, Math.tan(this.getST(0)))) this.pushValue(1.0); +}; - /** - * FRSTOR() - * - * @this {FPUX86} - */ - static FRSTOR() - { - var cpu = this.cpu; - var addr = this.loadEnv(cpu.regEA); - var a = this.intTmpTR; - for (var i = 0; i < this.regStack.length; i++) { - a[0] = cpu.getLong(addr); - a[1] = cpu.getLong(addr += 4); - a[2] = cpu.getShort(addr += 4); - this.setTR(i, a); - addr += 2; - } - } +/** + * FPREM() + * + * FPREM performs modulo division of ST(0) by ST(1) and returns the result to ST(0). + * + * The FPREM instruction is used to reduce the real operand in ST(0) to a value whose magnitude is less than the + * magnitude of ST(1). FPREM produces an exact result, so the precision exception is never raised and the rounding + * control has no effect. The sign of the remainder is the same as the sign of the original operand. + * + * The remaindering operation is performed by iterative scaled subtractions and can reduce the exponent of ST(0) by + * no more than 63 in one execution. If the remainder is less than ST(1) (the modulus), the function is complete and + * C2 in the status word is cleared. + * + * If the modulo function is incomplete, C2 is set to 1, and the result in ST(0) is termed the partial remainder. + * C2 can be inspected by storing the status word and re-executing the instruction until C2 is clear. Alternately, + * ST(0) can be compared to ST(1). If ST(0) > ST(1), then FPREM must be executed again. If ST(0) = ST(1), then the + * remainder is 0. + * + * FPREM is important for reducing arguments to the periodic transcendental functions such as FPTAN. Because FPREM + * produces an exact result, no round-off error is introduced into the calculation. + * + * When reduction is complete, the three least-significant bits of the quotient are stored in the condition code bits + * C3, C1, and C0, respectively. When arguments to the tangent function are reduced by pi/4, this result can be used + * to identify the octant that contained the original angle. + * + * The FPREM function operates differently than specified by the IEEE 754 standard when rounding the quotient to form + * a partial remainder (see the algorithm). The FPREM1 function (80287XL and up) is provided for compatibility with + * that standard. + * + * The FPREM instruction can also be used to normalize ST(0). If ST(0) is unnormal and ST(1) is greater than ST(0), + * FPREM will normalize ST(0). On the 8087 and 80287, operation on a denormal operand raises the invalid operation + * exception. Underflow is not possible. On the 80287XL and later coprocessors, operation on a denormal is supported + * and an underflow exception can occur. + * + * ALGORITHM: + * + * t = EXPONENT(ST) - EXPONENT(ST(1)) + * IF (t < 64) THEN + * q = R0UND(ST(0) / ST(1), CHOP) + * ST(0) = ST(0) - (ST(1) * q) + * C2 = 0 + * C0 = BIT 2 of q + * C1 = BIT 1 of q + * C3 = BIT 0 of q + * ELSE + * n = a number between 32 and 63 + * q = ROUND((ST(0) / ST(1)) / 2^(t-n), CHOP) + * ST(0) = ST(0) - (ST(1) * q * 2^(t-n)) + * C2 = 1 + * ENDIF + * + * TODO: Determine the extent to which the JavaScript MOD operator differs from the above algorithm. + * + * ERRATA: On the 8087 and 80287, the condition code bits C3, C1, and C0 are incorrect when performing a reduction of + * 64^n + m, where n >= 1, and m=1 or m=2. A bug fix should be implemented in software. + * + * @this {FPUX86} + */ +FPUX86.FPREM = function() +{ + this.setST(0, this.getST(0) % this.getST(1)); +}; - /** - * FRNDINT() - * - * @this {FPUX86} - */ - static FRNDINT() - { - this.setST(0, this.roundValue(this.getST(0), FPUX86.MAX_INT64)); +/** + * FRSTOR() + * + * @this {FPUX86} + */ +FPUX86.FRSTOR = function() +{ + var cpu = this.cpu; + var addr = this.loadEnv(cpu.regEA); + var a = this.intTmpTR; + for (var i = 0; i < this.regStack.length; i++) { + a[0] = cpu.getLong(addr); + a[1] = cpu.getLong(addr += 4); + a[2] = cpu.getShort(addr += 4); + this.setTR(i, a); + addr += 2; } +}; - /** - * FSAVE() - * - * @this {FPUX86} - */ - static FSAVE() - { - var cpu = this.cpu; - var addr = this.saveEnv(cpu.regEA); - for (var i = 0; i < this.regStack.length; i++) { - var a = this.getTR(i, true); - cpu.setLong(addr, a[0]); - cpu.setLong(addr += 4, a[1]); - cpu.setShort(addr += 4, a[2]); - addr += 2; - } - this.resetFPU(); - } +/** + * FRNDINT() + * + * @this {FPUX86} + */ +FPUX86.FRNDINT = function() +{ + this.setST(0, this.roundValue(this.getST(0), FPUX86.MAX_INT64)); +}; - /** - * FSCALE() - * - * FSCALE interprets the value in ST(1) as an integer and adds this number to the exponent of the number in ST(0). - * - * The FSCALE instruction provides a means of quickly performing multiplication or division by powers of two. - * This operation is often required when scaling array indexes. - * - * On the 8087 and 80287, FSCALE assumes that the scale factor in ST(1) is an integer that satisfies the inequality - * -2^15 <= ST(1) < +2^15. If ST(1) is not an integer value, the value is chopped to the next smallest integer in - * magnitude (chopped toward zero). If the value is out of range or 0 < ST(1) < 1, FSCALE produces an undefined - * result and doesn't signal an exception. Typically, the value in ST(0) is unchanged but should not be depended on. - * - * On the 80287XL and later coprocessors, there is no limit on the range of the scale factor in ST(1). The value in - * ST(1) is still chopped toward zero. If ST(1) is 0, ST(0) is unchanged. - * - * @this {FPUX86} - */ - static FSCALE() - { - var x = this.getST(0); - var y = this.getST(1); - if (x != null && y != null) this.setST(0, x * Math.pow(2, this.truncateValue(y))); +/** + * FSAVE() + * + * @this {FPUX86} + */ +FPUX86.FSAVE = function() +{ + var cpu = this.cpu; + var addr = this.saveEnv(cpu.regEA); + for (var i = 0; i < this.regStack.length; i++) { + var a = this.getTR(i, true); + cpu.setLong(addr, a[0]); + cpu.setLong(addr += 4, a[1]); + cpu.setShort(addr += 4, a[2]); + addr += 2; } + this.resetFPU(); +}; - /** - * FSETPM287() - * - * @this {FPUX86} - */ - static FSETPM287() - { - if (this.isModel(X86.FPU.MODEL_80287)) { - this.opUnimplemented(); - } - } +/** + * FSCALE() + * + * FSCALE interprets the value in ST(1) as an integer and adds this number to the exponent of the number in ST(0). + * + * The FSCALE instruction provides a means of quickly performing multiplication or division by powers of two. + * This operation is often required when scaling array indexes. + * + * On the 8087 and 80287, FSCALE assumes that the scale factor in ST(1) is an integer that satisfies the inequality + * -2^15 <= ST(1) < +2^15. If ST(1) is not an integer value, the value is chopped to the next smallest integer in + * magnitude (chopped toward zero). If the value is out of range or 0 < ST(1) < 1, FSCALE produces an undefined + * result and doesn't signal an exception. Typically, the value in ST(0) is unchanged but should not be depended on. + * + * On the 80287XL and later coprocessors, there is no limit on the range of the scale factor in ST(1). The value in + * ST(1) is still chopped toward zero. If ST(1) is 0, ST(0) is unchanged. + * + * @this {FPUX86} + */ +FPUX86.FSCALE = function() +{ + var x = this.getST(0); + var y = this.getST(1); + if (x != null && y != null) this.setST(0, x * Math.pow(2, this.truncateValue(y))); +}; - /** - * FSINCOS387() - * - * @this {FPUX86} - */ - static FSINCOS387() - { - if (this.isAtLeastModel(X86.FPU.MODEL_80287XL)) { - this.opUnimplemented(); - } +/** + * FSETPM287() + * + * @this {FPUX86} + */ +FPUX86.FSETPM287 = function() +{ + if (this.isModel(X86.FPU.MODEL_80287)) { + this.opUnimplemented(); } +}; - /** - * FSQRT() - * - * @this {FPUX86} - */ - static FSQRT() - { - this.setST(0, this.doSquareRoot(this.getST(0))); +/** + * FSINCOS387() + * + * @this {FPUX86} + */ +FPUX86.FSINCOS387 = function() +{ + if (this.isAtLeastModel(X86.FPU.MODEL_80287XL)) { + this.opUnimplemented(); } +}; - /** - * FSTlr() - * - * @this {FPUX86} - */ - static FSTlr() - { - if (this.getLR(0)) this.setEAFromLR(); - } +/** + * FSQRT() + * + * @this {FPUX86} + */ +FPUX86.FSQRT = function() +{ + this.setST(0, this.doSquareRoot(this.getST(0))); +}; - /** - * FSTsr() - * - * @this {FPUX86} - */ - static FSTsr() - { - if (this.getSR(0)) this.setEAFromSR(); - } +/** + * FSTlr() + * + * @this {FPUX86} + */ +FPUX86.FSTlr = function() +{ + if (this.getLR(0)) this.setEAFromLR(); +}; - /** - * FSTsti() - * - * @this {FPUX86} - */ - static FSTsti() - { - this.setST(this.iStack, this.getST(0)); - } +/** + * FSTsr() + * + * @this {FPUX86} + */ +FPUX86.FSTsr = function() +{ + if (this.getSR(0)) this.setEAFromSR(); +}; - /** - * FSTENV() - * - * @this {FPUX86} - */ - static FSTENV() - { +/** + * FSTsti() + * + * @this {FPUX86} + */ +FPUX86.FSTsti = function() +{ + this.setST(this.iStack, this.getST(0)); +}; - this.saveEnv(this.cpu.regEA); - this.regControl |= X86.FPU.CONTROL.EXC; // mask all exceptions (but do not set IEM) - } +/** + * FSTENV() + * + * @this {FPUX86} + */ +FPUX86.FSTENV = function() +{ - /** - * FSTPlr() - * - * @this {FPUX86} - */ - static FSTPlr() - { - if (this.getLR(0)) { - this.setEAFromLR(); - this.popValue(); - } - } + this.saveEnv(this.cpu.regEA); + this.regControl |= X86.FPU.CONTROL.EXC; // mask all exceptions (but do not set IEM) +}; - /** - * FSTPsr() - * - * @this {FPUX86} - */ - static FSTPsr() - { - if (this.getSR(0)) { - this.setEAFromSR(); - this.popValue(); - } +/** + * FSTPlr() + * + * @this {FPUX86} + */ +FPUX86.FSTPlr = function() +{ + if (this.getLR(0)) { + this.setEAFromLR(); + this.popValue(); } +}; - /** - * FSTPsti() - * - * @this {FPUX86} - */ - static FSTPsti() - { - if (this.setST(this.iStack, this.getST(0))) this.popValue(); +/** + * FSTPsr() + * + * @this {FPUX86} + */ +FPUX86.FSTPsr = function() +{ + if (this.getSR(0)) { + this.setEAFromSR(); + this.popValue(); } +}; - /** - * FSTP8087() - * - * NOTE: This is used with encodings (0xD9,0xD8-0xDF and 0xDF,0xD0-0xDF) that were valid for the 8087 and 80287 - * but may no longer be valid as of the 80387. - * - * @this {FPUX86} - */ - static FSTP8087() - { - this.opObsolete(); - FPUX86.FSTPsti.call(this); - } +/** + * FSTPsti() + * + * @this {FPUX86} + */ +FPUX86.FSTPsti = function() +{ + if (this.setST(this.iStack, this.getST(0))) this.popValue(); +}; - /** - * FSTPtr() - * - * @this {FPUX86} - */ - static FSTPtr() - { - if (this.getTR(0)) { - this.setEAFromTR(); - this.popValue(); - } +/** + * FSTP8087() + * + * NOTE: This is used with encodings (0xD9,0xD8-0xDF and 0xDF,0xD0-0xDF) that were valid for the 8087 and 80287 + * but may no longer be valid as of the 80387. + * + * @this {FPUX86} + */ +FPUX86.FSTP8087 = function() +{ + this.opObsolete(); + FPUX86.FSTPsti.call(this); +}; + +/** + * FSTPtr() + * + * @this {FPUX86} + */ +FPUX86.FSTPtr = function() +{ + if (this.getTR(0)) { + this.setEAFromTR(); + this.popValue(); } +}; - /** - * FSTCW() - * - * @this {FPUX86} - */ - static FSTCW() - { +/** + * FSTCW() + * + * @this {FPUX86} + */ +FPUX86.FSTCW = function() +{ - this.cpu.setShort(this.cpu.regEA, this.regControl); - } + this.cpu.setShort(this.cpu.regEA, this.regControl); +}; - /** - * FSTSW() - * - * @this {FPUX86} - */ - static FSTSW() - { +/** + * FSTSW() + * + * @this {FPUX86} + */ +FPUX86.FSTSW = function() +{ - this.cpu.setShort(this.cpu.regEA, this.getStatus()); - } + this.cpu.setShort(this.cpu.regEA, this.getStatus()); +}; - /** - * FSTSWAX287() - * - * @this {FPUX86} - */ - static FSTSWAX287() - { - if (this.isAtLeastModel(X86.FPU.MODEL_80287)) { - this.cpu.regEAX = (this.cpu.regEAX & ~0xffff) | this.getStatus(); - } +/** + * FSTSWAX287() + * + * @this {FPUX86} + */ +FPUX86.FSTSWAX287 = function() +{ + if (this.isAtLeastModel(X86.FPU.MODEL_80287)) { + this.cpu.regEAX = (this.cpu.regEAX & ~0xffff) | this.getStatus(); } +}; - /** - * FSUBlr() - * - * @this {FPUX86} - */ - static FSUBlr() - { - this.setST(0, this.doSubtract(this.getST(0), this.getLRFromEA())); - } +/** + * FSUBlr() + * + * @this {FPUX86} + */ +FPUX86.FSUBlr = function() +{ + this.setST(0, this.doSubtract(this.getST(0), this.getLRFromEA())); +}; - /** - * FSUBsr() - * - * @this {FPUX86} - */ - static FSUBsr() - { - this.setST(0, this.doSubtract(this.getST(0), this.getSRFromEA())); - } +/** + * FSUBsr() + * + * @this {FPUX86} + */ +FPUX86.FSUBsr = function() +{ + this.setST(0, this.doSubtract(this.getST(0), this.getSRFromEA())); +}; - /** - * FSUBst() - * - * Encoding 0xD8,0xE0-0xE7 ("FSUB ST,ST(i)"): ST(0) <- ST(0) - ST(i) - * - * @this {FPUX86} - */ - static FSUBst() - { - this.setST(0, this.doSubtract(this.getST(0), this.getST(this.iStack))); - } +/** + * FSUBst() + * + * Encoding 0xD8,0xE0-0xE7 ("FSUB ST,ST(i)"): ST(0) <- ST(0) - ST(i) + * + * @this {FPUX86} + */ +FPUX86.FSUBst = function() +{ + this.setST(0, this.doSubtract(this.getST(0), this.getST(this.iStack))); +}; - /** - * FSUBsti() - * - * Encoding 0xDC,0xE8-0xEF ("FSUB ST(i),ST"): ST(i) <- ST(i) - ST(0) - * - * @this {FPUX86} - */ - static FSUBsti() - { - this.setST(this.iStack, this.doSubtract(this.getST(this.iStack), this.getST(0))); - } +/** + * FSUBsti() + * + * Encoding 0xDC,0xE8-0xEF ("FSUB ST(i),ST"): ST(i) <- ST(i) - ST(0) + * + * @this {FPUX86} + */ +FPUX86.FSUBsti = function() +{ + this.setST(this.iStack, this.doSubtract(this.getST(this.iStack), this.getST(0))); +}; - /** - * FSUBPsti() - * - * Encoding 0xDE,0xE8-0xEF ("FSUBP ST(i),ST"): ST(i) <- ST(i) - ST(0), POP - * - * @this {FPUX86} - */ - static FSUBPsti() - { - if (this.setST(this.iStack, this.doSubtract(this.getST(this.iStack), this.getST(0)))) this.popValue(); - } +/** + * FSUBPsti() + * + * Encoding 0xDE,0xE8-0xEF ("FSUBP ST(i),ST"): ST(i) <- ST(i) - ST(0), POP + * + * @this {FPUX86} + */ +FPUX86.FSUBPsti = function() +{ + if (this.setST(this.iStack, this.doSubtract(this.getST(this.iStack), this.getST(0)))) this.popValue(); +}; - /** - * FSUBRlr() - * - * @this {FPUX86} - */ - static FSUBRlr() - { - this.setST(0, this.doSubtract(this.getLRFromEA(), this.getST(0))); - } +/** + * FSUBRlr() + * + * @this {FPUX86} + */ +FPUX86.FSUBRlr = function() +{ + this.setST(0, this.doSubtract(this.getLRFromEA(), this.getST(0))); +}; - /** - * FSUBRsr() - * - * @this {FPUX86} - */ - static FSUBRsr() - { - this.setST(0, this.doSubtract(this.getSRFromEA(), this.getST(0))); - } +/** + * FSUBRsr() + * + * @this {FPUX86} + */ +FPUX86.FSUBRsr = function() +{ + this.setST(0, this.doSubtract(this.getSRFromEA(), this.getST(0))); +}; - /** - * FSUBRst() - * - * Encoding 0xD8,0xE8-0xEF ("FSUBR ST,ST(i)"): ST(0) <- ST(i) - ST(0) - * - * @this {FPUX86} - */ - static FSUBRst() - { - this.setST(0, this.doSubtract(this.getST(this.iStack), this.getST(0))); - } +/** + * FSUBRst() + * + * Encoding 0xD8,0xE8-0xEF ("FSUBR ST,ST(i)"): ST(0) <- ST(i) - ST(0) + * + * @this {FPUX86} + */ +FPUX86.FSUBRst = function() +{ + this.setST(0, this.doSubtract(this.getST(this.iStack), this.getST(0))); +}; - /** - * FSUBRsti() - * - * Encoding 0xDC,0xE0-0xE7 ("FSUBR ST(i),ST"): ST(i) <- ST(0) - ST(i) - * - * @this {FPUX86} - */ - static FSUBRsti() - { - this.setST(this.iStack, this.doSubtract(this.getST(0), this.getST(this.iStack))); - } +/** + * FSUBRsti() + * + * Encoding 0xDC,0xE0-0xE7 ("FSUBR ST(i),ST"): ST(i) <- ST(0) - ST(i) + * + * @this {FPUX86} + */ +FPUX86.FSUBRsti = function() +{ + this.setST(this.iStack, this.doSubtract(this.getST(0), this.getST(this.iStack))); +}; - /** - * FSUBRPsti() - * - * Encoding 0xDE,0xE0-0xE7 ("FSUBRP ST(i),ST"): ST(i) <- ST(0) - ST(i), POP - * - * @this {FPUX86} - */ - static FSUBRPsti() - { - if (this.setST(this.iStack, this.doSubtract(this.getST(0), this.getST(this.iStack)))) this.popValue(); - } +/** + * FSUBRPsti() + * + * Encoding 0xDE,0xE0-0xE7 ("FSUBRP ST(i),ST"): ST(i) <- ST(0) - ST(i), POP + * + * @this {FPUX86} + */ +FPUX86.FSUBRPsti = function() +{ + if (this.setST(this.iStack, this.doSubtract(this.getST(0), this.getST(this.iStack)))) this.popValue(); +}; - /** - * FTST() - * - * @this {FPUX86} - */ - static FTST() - { - this.doCompare(this.getST(0), 0); - } +/** + * FTST() + * + * @this {FPUX86} + */ +FPUX86.FTST = function() +{ + this.doCompare(this.getST(0), 0); +}; - /** - * FXAM() - * - * @this {FPUX86} - */ - static FXAM() - { - this.regStatus &= ~X86.FPU.STATUS.CC; +/** + * FXAM() + * + * @this {FPUX86} + */ +FPUX86.FXAM = function() +{ + this.regStatus &= ~X86.FPU.STATUS.CC; - if (this.getSTSign(0)) { - this.regStatus |= X86.FPU.STATUS.C1; + if (this.getSTSign(0)) { + this.regStatus |= X86.FPU.STATUS.C1; + } + if (this.getTag(this.iST) == X86.FPU.TAGS.EMPTY) { + this.regStatus |= X86.FPU.STATUS.C0 | X86.FPU.STATUS.C3; + } + else { + var v = this.getST(0); + if (isNaN(v)) { + this.regStatus |= X86.FPU.STATUS.C0; } - if (this.getTag(this.iST) == X86.FPU.TAGS.EMPTY) { - this.regStatus |= X86.FPU.STATUS.C0 | X86.FPU.STATUS.C3; + else if (v === 0) { // this equals -0, too (WTF, strict equality?) + this.regStatus |= X86.FPU.STATUS.C3; + } + else if (v === Infinity || v === -Infinity) { // these are so divergent that even non-strict equality doesn't consider them equal + this.regStatus |= X86.FPU.STATUS.C0 | X86.FPU.STATUS.C2; } else { - var v = this.getST(0); - if (isNaN(v)) { - this.regStatus |= X86.FPU.STATUS.C0; - } - else if (v === 0) { // this equals -0, too (WTF, strict equality?) - this.regStatus |= X86.FPU.STATUS.C3; - } - else if (v === Infinity || v === -Infinity) { // these are so divergent that even non-strict equality doesn't consider them equal - this.regStatus |= X86.FPU.STATUS.C0 | X86.FPU.STATUS.C2; - } - else { - this.regStatus |= X86.FPU.STATUS.C2; - } + this.regStatus |= X86.FPU.STATUS.C2; } } +}; - /** - * FXCHsti() - * - * @this {FPUX86} - */ - static FXCHsti() - { - var tmp = this.getST(0); - this.setST(0, this.getST(this.iStack)); - this.setST(this.iStack, tmp); - } - - /** - * FXCH8087() - * - * NOTE: This is used with encodings (0xDD,0xC8-0xCF and 0xDF,0xC8-0xCF) that were valid for the 8087 and 80287 - * but may no longer be valid as of the 80387. - * - * @this {FPUX86} - */ - static FXCH8087() - { - this.opObsolete(); - FPUX86.FXCHsti.call(this); - } +/** + * FXCHsti() + * + * @this {FPUX86} + */ +FPUX86.FXCHsti = function() +{ + var tmp = this.getST(0); + this.setST(0, this.getST(this.iStack)); + this.setST(this.iStack, tmp); +}; - /** - * FXTRACT() - * - * FXTRACT splits the value encoded in ST(0) into two separate numbers representing the actual value of the - * fraction (mantissa) and exponent fields. - * - * The FXTRACT instruction is used to decompose the two fields of the temporary real number in ST(0). The exponent - * replaces the value in ST(0), then the fraction is pushed onto the stack. When execution is complete, ST(0) - * contains the original fraction, expressed as a real number with a true exponent of 0 (0x3FFF in biased form), - * and ST(1) contains the value of the original operand's true (unbiased) exponent expressed as a real number. - * - * If ST(0) is 0, the 8087 and 80287 will leave zeros in both ST(0) and ST(1); both zeros will have the same sign as - * the original operand. If ST(0) is +infinity, the invalid operation exception is raised. - * - * On the 80287XL and later coprocessors, if ST(0) is 0, the zero-divide exception is reported and ST(1) is set to - * -infinity. If ST(0) is +infinity, no exception is reported. - * - * The FXTRACT instruction may be thought of as the complement to the FSCALE instruction, which combines a separate - * fraction and exponent into a single value. - * - * ALGORITHM: - * - * IF (ST(0) = 0) THEN - * DEC TOP - * ST(0) = ST(1) - * ELSE - * temp = ST(0) - * ST(0) = EXPONENT(ST(0)) ; stored as true exponent - * DEC TOP - * ST(0) = FRACTION(ST(0)) - * ENDIF - * - * @this {FPUX86} - */ - static FXTRACT() - { - var v = this.getST(0); - if (v != null) { - this.regTmpLR[0] = v; - this.setST(0, ((this.intTmpLR[1] >> 20) & 0x7ff) - 0x3ff); - this.intTmpLR[1] = (this.intTmpLR[1] | 0x3ff00000) & ~0x40000000; - this.pushValue(this.regTmpLR[0]); - } - } +/** + * FXCH8087() + * + * NOTE: This is used with encodings (0xDD,0xC8-0xCF and 0xDF,0xC8-0xCF) that were valid for the 8087 and 80287 + * but may no longer be valid as of the 80387. + * + * @this {FPUX86} + */ +FPUX86.FXCH8087 = function() +{ + this.opObsolete(); + FPUX86.FXCHsti.call(this); +}; - /** - * FYL2X() - * - * FYL2X (y log base 2 of x) calculates: - * - * ST(1) = ST(1) * log2(ST(0)) - * - * The operands must satisfy the inequalities 0 < ST(0) < +infinity and -infinity < ST(1) < +infinity. FYL2X pops - * the stack and returns the result to the new ST(0). Both original operands are destroyed. - * - * The FYL2X function is designed to optimize the calculation of a log to a base, n, other than two. In such a case, - * the following multiplication is required; ie: - * - * logn(x) = logn(2) * log2(x) - * - * @this {FPUX86} - */ - static FYL2X() - { - if (this.setST(1, this.getST(1) * Math.log(this.getST(0)) / Math.LN2)) this.popValue(); +/** + * FXTRACT() + * + * FXTRACT splits the value encoded in ST(0) into two separate numbers representing the actual value of the + * fraction (mantissa) and exponent fields. + * + * The FXTRACT instruction is used to decompose the two fields of the temporary real number in ST(0). The exponent + * replaces the value in ST(0), then the fraction is pushed onto the stack. When execution is complete, ST(0) + * contains the original fraction, expressed as a real number with a true exponent of 0 (0x3FFF in biased form), + * and ST(1) contains the value of the original operand's true (unbiased) exponent expressed as a real number. + * + * If ST(0) is 0, the 8087 and 80287 will leave zeros in both ST(0) and ST(1); both zeros will have the same sign as + * the original operand. If ST(0) is +infinity, the invalid operation exception is raised. + * + * On the 80287XL and later coprocessors, if ST(0) is 0, the zero-divide exception is reported and ST(1) is set to + * -infinity. If ST(0) is +infinity, no exception is reported. + * + * The FXTRACT instruction may be thought of as the complement to the FSCALE instruction, which combines a separate + * fraction and exponent into a single value. + * + * ALGORITHM: + * + * IF (ST(0) = 0) THEN + * DEC TOP + * ST(0) = ST(1) + * ELSE + * temp = ST(0) + * ST(0) = EXPONENT(ST(0)) ; stored as true exponent + * DEC TOP + * ST(0) = FRACTION(ST(0)) + * ENDIF + * + * @this {FPUX86} + */ +FPUX86.FXTRACT = function() +{ + var v = this.getST(0); + if (v != null) { + this.regTmpLR[0] = v; + this.setST(0, ((this.intTmpLR[1] >> 20) & 0x7ff) - 0x3ff); + this.intTmpLR[1] = (this.intTmpLR[1] | 0x3ff00000) & ~0x40000000; + this.pushValue(this.regTmpLR[0]); } +}; - /** - * FYL2XP1() - * - * FYL2XP1 (y log base 2 of x plus 1) calculates: - * - * ST(1) = ST(1) * log2(ST(0) + 1) - * - * The operands must satisfy the inequalities -(1-sqrt(2)/2) < ST(0) < (1-sqrt(2)/2) and -infinity < ST(1) < +infinity. - * FYL2XP1 pops the stack and returns the result to the new ST(0). Both original operands are destroyed. - * - * The FYL2XP1 function provides greater accuracy than FYL2X in computing the log of a number that is very close to 1. - * - * FYL2XP1 is typically used when computing compound interest, for example, which requires the calculation of a logarithm - * of 1.0 + n where 0 < n < 0.29. If 1.0 was added to n, significant digits might be lost. By using FYL2XP1, the result - * will be as accurate as n to within three units of temporary real precision. - * - * @this {FPUX86} - */ - static FYL2XP1() - { - if (this.setST(1, this.getST(1) * Math.log(this.getST(0) + 1.0) / Math.LN2)) this.popValue(); - } +/** + * FYL2X() + * + * FYL2X (y log base 2 of x) calculates: + * + * ST(1) = ST(1) * log2(ST(0)) + * + * The operands must satisfy the inequalities 0 < ST(0) < +infinity and -infinity < ST(1) < +infinity. FYL2X pops + * the stack and returns the result to the new ST(0). Both original operands are destroyed. + * + * The FYL2X function is designed to optimize the calculation of a log to a base, n, other than two. In such a case, + * the following multiplication is required; ie: + * + * logn(x) = logn(2) * log2(x) + * + * @this {FPUX86} + */ +FPUX86.FYL2X = function() +{ + if (this.setST(1, this.getST(1) * Math.log(this.getST(0)) / Math.LN2)) this.popValue(); +}; - /** - * FPUX86.init() - * - * This function operates on every HTML element of class "fpu", extracting the - * JSON-encoded parameters for the FPUX86 constructor from the element's "data-value" - * attribute, invoking the constructor to create an FPUX86 component, and then binding - * any associated HTML controls to the new component. - */ - static init() - { - var aeFPUs = Component.getElementsByClass(document, PCX86.APPCLASS, "fpu"); - for (var iFPU = 0; iFPU < aeFPUs.length; iFPU++) { - var eFPU = aeFPUs[iFPU]; - var parmsFPU = Component.getComponentParms(eFPU); - var fpu = new FPUX86(parmsFPU); - Component.bindComponentControls(fpu, eFPU, PCX86.APPCLASS); - } - } -} +/** + * FYL2XP1() + * + * FYL2XP1 (y log base 2 of x plus 1) calculates: + * + * ST(1) = ST(1) * log2(ST(0) + 1) + * + * The operands must satisfy the inequalities -(1-sqrt(2)/2) < ST(0) < (1-sqrt(2)/2) and -infinity < ST(1) < +infinity. + * FYL2XP1 pops the stack and returns the result to the new ST(0). Both original operands are destroyed. + * + * The FYL2XP1 function provides greater accuracy than FYL2X in computing the log of a number that is very close to 1. + * + * FYL2XP1 is typically used when computing compound interest, for example, which requires the calculation of a logarithm + * of 1.0 + n where 0 < n < 0.29. If 1.0 was added to n, significant digits might be lost. By using FYL2XP1, the result + * will be as accurate as n to within three units of temporary real precision. + * + * @this {FPUX86} + */ +FPUX86.FYL2XP1 = function() +{ + if (this.setST(1, this.getST(1) * Math.log(this.getST(0) + 1.0) / Math.LN2)) this.popValue(); +}; /* * Class constants @@ -38116,7 +38116,7 @@ class ChipSet extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {ChipSet} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, "sw1") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -45374,7 +45374,7 @@ class Keyboard extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {Keyboard} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -48863,7 +48863,7 @@ class Card extends Controller { if (this.nCard >= Video.CARD.EGA) { this.dbg.println(" LATCHES: " + Str.toHex(this.latches)); this.dbg.println(" ACCESS: " + Str.toHex(this.nAccess, 4)); - this.dbg.println("Use 'dump video [addr]' to dump video memory"); + this.dbg.println("Use 'd video [addr]' to dump video memory"); /* * There are few more EGA regs we could dump, like GRCPos1, GRCPos2, but does anyone care? */ @@ -48968,7 +48968,7 @@ class Card extends Controller { var sData = Str.toHex(this.addrBuffer + idw) + ":"; for (j = 0; j < n && idw < this.adwMemory.length; j++) { var dw = this.adwMemory[idw++]; - sData += ' ' + ((p < 0)? Str.toHex(dw) : Str.toBin((dw >> (p << 3)), 8)); + sData += ' ' + ((p < 0)? Str.toHex(dw, 8) : Str.toBin((dw >> (p << 3)), 8)); } if (fColAdjust) idw += w - n; if (sDump) sDump += "\n"; @@ -49463,8 +49463,9 @@ Card.ATC = { }; if (DEBUGGER) { - Card.ATC.REGS = ["PAL00","PAL01","PAL02","PAL03","PAL04","PAL05","PAL06","PAL07", - "PAL08","PAL09","PAL0A","PAL0B","PAL0C","PAL0D","PAL0E","PAL0F", "MODE","OVERSCAN","PLANES","HPAN"]; + Card.ATC.REGS = [ + "ATC00","ATC01","ATC02","ATC03","ATC04","ATC05","ATC06","ATC07", + "ATC08","ATC09","ATC0A","ATC0B","ATC0C","ATC0D","ATC0E","ATC0F", "ATCMODE","OVERSCAN","PLANES","HPAN"]; } /* @@ -49684,7 +49685,7 @@ Card.GRC = { TOTAL_REGS: 0x09 }; -if (DEBUGGER) Card.GRC.REGS = ["SRESET","ESRESET","COLORCMP","DATAROT","READMAP","MODE","MISC","COLORDC","BITMASK"]; +if (DEBUGGER) Card.GRC.REGS = ["SRESET","ESRESET","COLORCMP","DATAROT","READMAP","GRCMODE","GRCMISC","COLORDC","BITMASK"]; /* * EGA Memory Access Functions @@ -50535,13 +50536,13 @@ class Video extends Component { if (sEvent) { var sFullScreen = Web.findProperty(document, 'fullscreenElement') || Web.findProperty(document, 'fullScreenElement'); document.addEventListener(sEvent, function onFullScreenChange() { - video.notifyFullScreen(!!sFullScreen); + video.notifyFullScreen(document[sFullScreen] != null); }, false); } sEvent = Web.findProperty(document, 'on', 'fullscreenerror'); if (sEvent) { document.addEventListener(sEvent, function onFullScreenError() { - video.notifyFullScreen(null); + video.notifyFullScreen(); }, false); } } @@ -50711,7 +50712,7 @@ class Video extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {Video} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, "refresh") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -50886,7 +50887,7 @@ class Video extends Component { * notifyFullScreen(fFullScreen) * * @this {Video} - * @param {boolean|null} fFullScreen (null if there was a full-screen error) + * @param {boolean|undefined} [fFullScreen] (undefined if there was a full-screen error) */ notifyFullScreen(fFullScreen) { @@ -50897,8 +50898,8 @@ class Video extends Component { this.canvasScreen.style.width = this.canvasScreen.style.height = ""; } } - this.printMessage("notifyFullScreen(" + fFullScreen + ")", true); - if (this.kbd) this.kbd.notifyEscape(fFullScreen); + if (DEBUG) this.printMessage("notifyFullScreen(" + fFullScreen + ")", true); + if (this.kbd) this.kbd.notifyEscape(fFullScreen == true); } /** @@ -55914,7 +55915,7 @@ class ParallelPort extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {ParallelPort} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, "buffer") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -55922,7 +55923,7 @@ class ParallelPort extends Component { */ setBinding(sHTMLType, sBinding, control, sValue) { - if (sHTMLType == null || sHTMLType == "textarea") { + if (!sHTMLType || sHTMLType == "textarea") { this.bindings[sBinding] = this.controlBuffer = control; return true; } @@ -56546,7 +56547,7 @@ class SerialPort extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {SerialPort} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, "buffer") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -56554,7 +56555,7 @@ class SerialPort extends Component { */ setBinding(sHTMLType, sBinding, control, sValue) { - if (sHTMLType == null || sHTMLType == "textarea") { + if (!sHTMLType || sHTMLType == "textarea") { var serial = this; this.bindings[sBinding] = this.controlBuffer = /** @type {HTMLTextAreaElement} */ (control); @@ -57622,7 +57623,7 @@ class TestController extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {TestController} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, "buffer") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -58781,7 +58782,7 @@ class Mouse extends Component { * Byte 3 X 0 Y5 Y4 Y3 Y2 Y1 Y0 * * @this {Mouse} - * @param {string|null} [sDiag] diagnostic message + * @param {string|null|*} [sDiag] diagnostic message * @param {number} [xDiag] original x-coordinate (optional; for diagnostic use only) * @param {number} [yDiag] original y-coordinate (optional; for diagnostic use only) */ @@ -62278,7 +62279,7 @@ class FDC extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {FDC} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, "listDisks") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -65058,7 +65059,7 @@ class HDC extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {HDC} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, "listDisks") * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -66071,7 +66072,7 @@ class HDC extends Component { * simplistic MRU logic. If that fails, the worst that will (or should) happen is we'll burn through * more BackTrack wrapper objects than necessary, and risk running out. */ - var bto = hdc.bus.addBackTrackObject(obj, null, off); + var bto = hdc.bus.addBackTrackObject(obj, /** @type BackTrack */ (null), off); hdc.cpu.backTrack.btiIO = hdc.bus.getBackTrackIndex(bto, off); } }); @@ -69127,7 +69128,7 @@ class Debugger extends Component * * @this {Debugger} * @param {string|undefined} sValue - * @param {string|null} [sName] is the name of the value, if any + * @param {string|null|*} [sName] is the name of the value, if any * @param {Array|undefined|boolean} [fQuiet] * @param {number} [nUnary] (0 for none, 1 for negate, 2 for complement, 3 for leading zeros) * @return {number|undefined} numeric value, or undefined if sValue is either undefined or invalid @@ -70285,7 +70286,7 @@ class DebuggerX86 extends Debugger { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {DebuggerX86} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -73578,7 +73579,7 @@ class DebuggerX86 extends Debugger { * * @this {DebuggerX86} * @param {string} sName - * @param {number|null} sel + * @param {number|null|*} sel * @param {number} addr * @param {number} addrLimit * @return {string} @@ -73773,7 +73774,7 @@ class DebuggerX86 extends Debugger { * @param {number} nSegment (zero if undefined) * @param {number} sel (the default segment/selector for all symbols in this group) * @param {number} off (from the base of the given selector) - * @param {number|null} addr (physical address where the symbols are located, if the memory is physical; eg, ROM) + * @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) */ @@ -73829,7 +73830,7 @@ class DebuggerX86 extends Debugger { * removeSymbols(sModule, nSegment) * * @this {DebuggerX86} - * @param {string|null} sModule + * @param {string|null|*} sModule * @param {number} [nSegment] (segment # if sModule set, selector if sModule clear) * @return {string|null} name of the module removed, or null if no module was found */ @@ -78526,7 +78527,7 @@ class Computer extends Component { * setBinding(sHTMLType, sBinding, control, sValue) * * @this {Computer} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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 {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value diff --git a/versions/pcx86/1.61.0/pcx86.js b/versions/pcx86/1.61.0/pcx86.js index 6b75ff6325..d333d122b2 100644 --- a/versions/pcx86/1.61.0/pcx86.js +++ b/versions/pcx86/1.61.0/pcx86.js @@ -57,7 +57,7 @@ Xk:115,t:116,cl:117,dl:118,el:119,x:120,y:121,z:122,"{":123,"|":124,"}":125,"~": wa[188]=n["\x3c"];wa[189]=n._;wa[190]=n["\x3e"];wa[191]=n["?"];wa[192]=n["~"];wa[219]=n["{"];wa[220]=n["|"];wa[221]=n["}"];wa[222]=n['"'];wa[173]=n._;wa[61]=n["+"];wa[59]=n[":"];function xa(){} function ya(a,b){if(a){b||(b=10);var c,d=0<a.indexOf(",");d&&(a=a.replace(/,/g,""));var e=c=a.charAt(0);"#"==c?(b=8,c=""):"$"==c&&(b=16,c="");e!=c?a=a.substr(1):(e=c=a.substr(0,2),"0b"==c&&d||"^B"==c?(b=2,c=""):"0o"==c||"^O"==c?(b=8,c=""):"^D"==c?(b=10,c=""):"0x"==c&&(b=16,c=""),e!=c&&(a=a.substr(2)));e=c=a.slice(-1);"Y"==c||"y"==c?(b=2,c=""):"."==c?(b=10,c=""):"H"==c||"h"==c?(b=16,c=""):"K"==c?c="000":"M"==c?c="000000":"G"==c&&(c="000000000");e!=c&&(a=a.slice(0,-1)+c);var f;e=0;10>=b&&(c=a.match(/(-?[0-9]+)B([0-9]*)/))&& (a=c[1],e=35-((c[2]||35)&255));c=a;if(((d=b)&&10!=d?16==d?null!==c.match(/^-?[0-9a-f]+$/i):8==d?null!==c.match(/^-?[0-7]+$/):2==d&&null!==c.match(/^-?[01]+$/):null!==c.match(/^-?[0-9]+$/))&&!isNaN(f=parseInt(a,b))){e&&(0>f&&(f+=Math.pow(2,36)),f=0<e?f*Math.pow(2,e):Math.trunc(f/Math.pow(2,-e)));var g=f}}return g} -function za(a,b,c,d,e){e=void 0===e?0:e;var f="";isNaN(a)?a=null:null!=a&&(0>a&&-1<a&&(a=-1),0>a&&(a+=Math.pow(b,c)),a>=Math.pow(b,c)&&(c=Math.ceil(Math.log(a)/Math.log(b))));for(var g=e||-1;0<c--;){g||(f=","+f,g=e);if(null==a)f="?"+f;else{var h=a%b;h+=0<=h&&9>=h?48:55;f=String.fromCharCode(h)+f;a=Math.trunc(a/b)}g--}return(void 0===d?"":d)+f}function Aa(a,b,c){b?36<b&&(b=36):(b=Math.abs(a),b=255>=b?8:262143>=b?18:36);return za(a,2,b,"",c)} +function za(a,b,c,d,e){e=void 0===e?0:e;var f="";isNaN(a)||"number"!=typeof a?a=null:(0>a&&-1<a&&(a=-1),0>a&&(a+=Math.pow(b,c)),a>=Math.pow(b,c)&&(c=Math.ceil(Math.log(a)/Math.log(b))));for(var g=e||-1;0<c--;){g||(f=","+f,g=e);if(null==a)f="?"+f;else{var h=a%b;h+=0<=h&&9>=h?48:55;f=String.fromCharCode(h)+f;a=Math.trunc(a/b)}g--}return(void 0===d?"":d)+f}function Aa(a,b,c){b?36<b&&(b=36):(b=Math.abs(a),b=255>=b?8:262143>=b?18:36);return za(a,2,b,"",c)} function Ba(a,b,c){b?12<b&&(b=12):(b=Math.abs(a),b=262143>=b?6:16777215>=b?8:12);return za(a,8,b,c?"0o":"")}function q(a,b,c){b?9<b&&(b=9):(b=Math.abs(a),b=65535>=b?4:4294967295>=b?8:9);return za(a,16,b,c?"0x":"")}function Da(a){return q(a,2,!0)}function Ea(a){return q(a,4,!0)}function Fa(a,b){var c=a,d=a.lastIndexOf("/");0<=d&&(c=a.substr(d+1));d=c.indexOf("\x26");0<d&&(c=c.substr(0,d));b&&(d=c.lastIndexOf("."),0<d&&(c=c.substring(0,d)));return c} function Ga(a){var b="",c=a.lastIndexOf(".");0<=c&&(b=a.substr(c+1).toLowerCase());return b}function Ha(a,b){return-1!==a.indexOf(b,a.length-b.length)}function Ia(a){return a.replace(/[&<>"']/g,function(a){return Ja[a]})}function Ka(a,b,c){return c?(" "+a).slice(-b):(a+" ").slice(0,b)} function La(a,b){for(var c=[],d=1;d<arguments.length;++d)c[d-1]=arguments[d];d="";var e=a.split(/%([-+ 0#]?)([0-9]*)(\.?)([0-9]*)([hlL]?)([A-Za-z%])/),f=0,g;for(g=0;g<e.length-7;g+=7){d+=e[g];var h=c[f++],k=e[g+1],m=+e[g+2]||0,p=+e[g+4]||0,u=e[g+6],v=null;switch(u){case "d":h=Math.trunc(h);case "f":u=Math.trunc(h)+"";p&&(m-=p+1);u.length<m&&("0"==k?(0>h&&m--,u=("0000000000"+Math.abs(h)).slice(-m),0>h&&(u="-"+u)):u=(" "+u).slice(-m));p&&(h=Math.round((h-Math.trunc(h))*Math.pow(10,p)),u+="."+ @@ -80,7 +80,7 @@ function rb(a,b){function c(){b(100===d)&&(e=setTimeout(c,d),d=100)}var d=0,e=nu function vb(a){if(wb)try{for(var b=0;b<a.length;b++)a[b]()}catch(c){xb(""+("An unexpected error occurred: "+c.message+"\n\nIf it happens again, please send this information to support@pcjs.org. Thanks."))}}function zb(a){!wb&&a?(wb=!0,Ab&&Bb("init"),Cb&&Bb("show")):wb=a}function Bb(a){ub[a]&&vb(ub[a])}var ob=null,ub={init:[],show:[],exit:[]},nb=["","moz","ms","webkit"],Ab=!1,Cb=!1,wb=!0,eb=null;sb("onload",function(){Ab=!0;vb(ub.init)});sb("onpageshow",function(){Cb=!0;vb(ub.show)}); sb(ib("iOS")?"onpagehide":ib("Opera")?"onunload":"onbeforeunload",function(){vb(ub.exit)}); function Eb(a,b,c){this.type=a;b||(b={id:"",name:""});this.id=b.id||"";this.name=b.name;this.uj=b.comment;this.Nk=b;this.exports={};this.na=this.bindings={};a=this.id.indexOf(".");0>a?this.ee=this.id:(this.Pd=this.id.substr(0,a),this.ee=this.id.substr(a+1));this.flags={ready:!1,lf:!1,hh:!1,qf:!1,Zb:!1,we:!1,error:!1};this.qg=null;this.flags.error=!1;this.Jb=c||0;this.ca=this.G=this.oa=this.qa=null;Fb.push(this)}function Gb(a,b,c){Hb[a]&&b&&(Hb[a][b]=c)}function xb(a){window&&window.alert(a)} -function Ib(a){var b=!1;window&&(b=window.confirm(a));return b}function Jb(a,b){a.value+=b;b=a.value;8192<b.length&&(a.value=b.substr(b.length-4096));a.scrollTop=a.scrollHeight}function Kb(a,b,c){var d=a.value,e=d.lastIndexOf(b);0>e?d+=b+"\n":d=d.substr(0,e)+c+d.substr(e+b.length);8192<d.length&&(d=d.substr(d.length-4096));a.value=d;a.scrollTop=a.scrollHeight}function Lb(a,b){if(b){var c=Nb("Panel",a.id);c&&(c=c.na[b])&&a.wb(null,b,c)}} +function Ib(a){var b=!1;window&&(b=window.confirm(a));return b}function Jb(a,b){a.value+=b;b=a.value;8192<b.length&&(a.value=b.substr(b.length-4096));a.scrollTop=a.scrollHeight}function Kb(a,b,c){var d=a.value,e=d.lastIndexOf(b);0>e?d+=b+"\n":d=d.substr(0,e)+c+d.substr(e+b.length);8192<d.length&&(d=d.substr(d.length-4096));a.value=d;a.scrollTop=a.scrollHeight}function Lb(a,b){if(b){var c=Nb("Panel",a.id);c&&(c=c.na[b])&&a.wb("",b,c)}} function Qb(a,b){b=Rb(b.parentNode,"pcx86-control");for(var c=0;c<b.length;c++)for(var d=b[c].childNodes,e=0;e<d.length;e++){var f=d[e];if(1===f.nodeType){var g=f.getAttribute("class");if(g)for(var h=g.split(" "),k=0;k<h.length;k++)switch(g=h[k],g){case "pcx86-binding":(g=Sb(f))&&void 0!==g.binding&&a.wb(g.type,g.binding,f,g.value),k=h.length}}}}function Tb(a){var b,c=[];a&&(a=0<(b=a.indexOf("."))?a.substr(0,b+1):"");for(b=0;b<Fb.length;b++){var d=Fb[b];a&&d.id.indexOf(a)||c.push(d)}return c} function Ub(a,b){if(void 0!==a){var c;b&&0<(c=b.indexOf("."))&&(a=b.substr(0,c+1)+a);for(c=0;c<Fb.length;c++)if(Fb[c].id===a)return Fb[c]}return null}function Nb(a,b){var c;if(void 0!==a){var d;b&&(b=0<(d=b.indexOf("."))?b.substr(0,d+1):"");for(d=0;d<Fb.length;d++)if(c)c==Fb[d]&&(c=null);else if(!(a!=Fb[d].type||b&&Fb[d].id.indexOf(b)))return Fb[d]}return null}function Sb(a){var b=null;if(a=a.getAttribute("data-value"))try{b=eval("("+a+")")}catch(c){xb(c.message+" ("+a+")")}return b} function Rb(a,b,c){c&&(b+="-"+c+"-object");if(a.getElementsByClassName)return a.getElementsByClassName(b);var d;c=[];a=a.getElementsByTagName("*");var e=new RegExp("(^| )"+b+"( |$)");b=0;for(d=a.length;b<d;b++)e.test(a[b].className)&&c.push(a[b]);return c} @@ -143,7 +143,7 @@ l.Pp=function(a,b){a&3?(this.Qa[a]=b,this.Qa[a+1]=b>>8,this.Qa[a+2]=b>>16,this.Q var zd=0,Yc=2,Ad=5,Hd=6,Mc="NONE RAM ROM VIDEO H/W UNPAGED PAGED".split(" "),yd=0,Jd=[],dd=[w.prototype.jp,w.prototype.Ip,w.prototype.wp,w.prototype.Up,w.prototype.qp,w.prototype.Op],Md=[w.prototype.ip,w.prototype.Hp,w.prototype.vp,w.prototype.Tp,w.prototype.pp,w.prototype.Np],Id=[w.prototype.lp,w.prototype.Kp,w.prototype.yp,w.prototype.Wp,w.prototype.sp,w.prototype.Qp],Bd=[w.prototype.mp,w.prototype.Lp,w.prototype.zp,w.prototype.Xp,w.prototype.tp,w.prototype.Rp]; if(kc)var cd=[w.prototype.hp,w.prototype.Gp,w.prototype.up,w.prototype.Sp,w.prototype.np,w.prototype.Mp],bd=[w.prototype.Pk,w.prototype.fl,w.prototype.Uk,w.prototype.hl,w.prototype.Rk,w.prototype.gl],Td=[w.prototype.kp,w.prototype.Jp,w.prototype.xp,w.prototype.Vp,w.prototype.rp,w.prototype.Pp]; function Ud(a,b){Eb.call(this,"CPU",a,268435457);b=a.cycles||b;var c=a.multiplier||1;this.X={};this.X.$d=b;this.X.th=Math.round(1E3/Vd);this.X.Cj=this.X.xh=this.X.yd=c;this.X.ug=Math.round(this.X.$d/1E4)/100;this.X.Jd=this.X.oe=this.X.ug*this.X.yd;this.flags.ui=this.flags.Xa=this.flags.Tf=!1;this.flags.Ud=a.autoStart;this.flags.Yi=!1;this.flags.Je=!1;this.X.wf=this.X.Se=0;this.X.yf=a.csStart;this.X.Re=a.csInterval;this.X.Te=a.csStop;this.ma=[];this.Td=0;this.vj=this.Ap.bind(this)}ja(Ud,Eb);l=Ud.prototype; -l.qc=function(a,b,c,d){this.qa=a;this.oa=b;this.ca=d;for(b=0;b<Wd.length;b++)(d=this.na[Wd[b]])&&this.qa.wb(null,Wd[b],d);this.Gc=qc(a,"FPU");this.Y=qc(a,"ChipSet");a=Xd(a,"autoStart");null!=a&&(this.flags.Ud="true"==a?!0:"false"==a?!1:!!a);Yd(c,this.id,function(){c.flags.Tf=!0},this.X.th);ec(this)};l.reset=function(){};l.save=function(){return null};l.restore=function(){return!1}; +l.qc=function(a,b,c,d){this.qa=a;this.oa=b;this.ca=d;for(b=0;b<Wd.length;b++)(d=this.na[Wd[b]])&&this.qa.wb("",Wd[b],d);this.Gc=qc(a,"FPU");this.Y=qc(a,"ChipSet");a=Xd(a,"autoStart");null!=a&&(this.flags.Ud="true"==a?!0:"false"==a?!1:!!a);Yd(c,this.id,function(){c.flags.Tf=!0},this.X.th);ec(this)};l.reset=function(){};l.save=function(){return null};l.restore=function(){return!1}; l.Yb=function(a,b){if(!b){if(a&&this.restore){Zd(this);if(!this.restore(a))return!1;$d(this)}else this.reset();this.ca?this.ca.oh():this.O("No debugger detected")}ae(this);return!0};l.Xb=function(a,b){var c=this.flags.Xa;b&&be(this);return a?this.save(c):!0};l.Ud=function(){return this.flags.Xa?!0:this.flags.Ud||null==this.flags.Ud&&!this.ca?ce(this,!0,!0):!1};l.ij=function(){return 0}; function $d(a){void 0===a.X.yf&&(a.X.yf=0);void 0===a.X.Re&&(a.X.Re=-1);void 0===a.X.Te&&(a.X.Te=-1);a.flags.Je=0<=a.X.yf&&0<a.X.Re;a.flags.Je&&(a.X.wf=0,a.X.Se=a.X.yf-a.Fd)}function de(a,b){if(a.flags.Je){var c=!1;a.X.wf=a.X.wf+a.ij()|0;a.X.Se-=b;0>=a.X.Se&&(a.X.Se+=a.X.Re,c=!0);0<=a.X.Te&&a.X.Te<=ee(a)&&(a.X.Re=a.X.Te=-1,$d(a),be(a),c=!0);c&&a.O(ee(a)+" cycles: checksum\x3d"+q(a.X.wf))}} l.wb=function(a,b,c){var d=this;a=!1;switch(b){case "power":case "reset":this.na[b]=c;a=!0;break;case "run":this.na[b]=c;c.onclick=function(){var a=d.flags.Xa,b;if(b=d.qa)if(b=d.qa,b.flags.we&&(b.flags.we=!1,b.flags.qf&&!b.flags.Zb&&b.We(fe)),b.flags.Zb)b=!0;else{var c=null,h,k=Tb(b.id);for(h=0;h<k.length&&(c=k[h],c===b||c.flags.ready);h++);if(h==k.length)for(h=0;h<k.length&&(c=k[h],c===b||c.flags.Zb);h++);h==k.length&&(c=b);xb("The "+c.type+" component ("+c.id+") is not "+(c.flags.ready?"powered yet": @@ -562,8 +562,8 @@ c[16]=a.ji;c[17]=a.ib;c[18]=a.Oc;c[19]=a.Ab;c[20]=a.Gf;c[21]=a.Md;c[22]=a.ae;c[2 $s.prototype.rg=function(){return this.B};$s.prototype.Ng=function(a){if(null!=a&&a!=this.vg){var b=a&Ct,c=Dt[b];c||b&mt&&(c=Dt[mt]);b=a&Et;var d=Dt[b];d||b&ot&&(d=Dt[ot]);this.B||(this.B=Array(6));this.B[0]=c;this.B[1]=d;this.vg=a}}; function Bt(a,b){var c=a.Na[b];if(null!=c&&a.Ja>=Zq){var d=0,e=0,f=0;switch(b){case Ft:d=Gt;a.Ja==ar&&(e=Ht);break;case It:a.Ja==Zq&&(d=Jt);break;case Kt:d=Lt;a.Ja==ar&&(e=Mt);break;case Nt:d=Ot;a.Ja==ar&&(e=Pt);break;case Qt:d=Rt;a.Ja==ar&&(f=St);break;case Tt:d=Ut,a.Ja==ar&&(f=Vt)}d&&(c|=a.Na[Wt]&d?256:0,c|=a.Na[Wt]&e?512:0,c|=a.Na[Xt]&f?512:0)}return c} var ft=12,et=13,bt=18,Ft=6,Wt=7,Gt=1,Ot=2,Lt=4,Rt=8,Ut=16,Jt=32,Ht=32,Pt=64,Mt=128,Xt=9,St=32,Vt=64,It=10,Kt=16,Nt=18,Qt=21,Tt=24,ct=25,Yt={},Zt=(Yt[0]=255,Yt[1]=255,Yt[2]=255,Yt[3]=15,Yt[4]=127,Yt[5]=31,Yt[6]=127,Yt[7]=127,Yt[8]=3,Yt[9]=31,Yt[10]=127,Yt[11]=31,Yt[ft]=63,Yt[et]=255,Yt[14]=63,Yt[15]=255,Yt[16]=63,Yt[17]=255,Yt),dt="HTOTAL HDISP HSPOS HSWIDTH VTOTAL VTOTADJ VDISP VSPOS ILMODE MAXSCAN CURSCAN CURSCANB STARTHI STARTLO CURSORHI CURSORLO PENHI PENLO".split(" "),gt="HTOTAL HDEND HBSTART HBEND HRSTART HREND VTOTAL OVERFLOW PRESCAN MAXSCAN CURSCAN CURSCANB STARTHI STARTLO CURSORHI CURSORLO VRSTART VREND VDEND OFFSET UNDERLINE VBSTART VBEND MODECTRL LINECOMP".split(" "), -ht=20,ut="PAL00 PAL01 PAL02 PAL03 PAL04 PAL05 PAL06 PAL07 PAL08 PAL09 PAL0A PAL0B PAL0C PAL0D PAL0E PAL0F MODE OVERSCAN PLANES HPAN".split(" "),it=1,qt=1,jt=5,vt=["RESET","CLOCKING","MAPMASK","CHARMAP","MEMMODE"],rt=255,st=0,tt=256,kt=9,wt="SRESET ESRESET COLORCMP DATAROT READMAP MODE MISC COLORDC BITMASK".split(" "),lt=1024,mt=4096,Ct=65280,nt=0,ot=16,Et=255,pt=-2147483648,xt=[];xt[2]=lt;xt[3]=lt|mt;xt[16]=1280;xt[512]=nt;xt[1024]=nt|32;xt[1536]=nt|96;xt[2560]=nt|160;xt[3584]=nt|224;xt[768]=nt|ot; -xt[4096]=1;xt[8192]=2;xt[24576]=98;xt[40960]=162;xt[57344]=226;var Dt=[];Dt[lt]=function(a){a+=this.G;return(this.controller.A=this.V[a])>>this.controller.ji&255};Dt[lt|16384]=function(a){return(this.controller.A=this.V[(a&-4)+this.G])>>((a&3)<<3)&255};Dt[lt|mt]=function(a){a+=this.G;var b=this.controller.A=this.V[a&-2];return(a&1?b>>8:b)&255}; +ht=20,ut="ATC00 ATC01 ATC02 ATC03 ATC04 ATC05 ATC06 ATC07 ATC08 ATC09 ATC0A ATC0B ATC0C ATC0D ATC0E ATC0F ATCMODE OVERSCAN PLANES HPAN".split(" "),it=1,qt=1,jt=5,vt=["RESET","CLOCKING","MAPMASK","CHARMAP","MEMMODE"],rt=255,st=0,tt=256,kt=9,wt="SRESET ESRESET COLORCMP DATAROT READMAP GRCMODE GRCMISC COLORDC BITMASK".split(" "),lt=1024,mt=4096,Ct=65280,nt=0,ot=16,Et=255,pt=-2147483648,xt=[];xt[2]=lt;xt[3]=lt|mt;xt[16]=1280;xt[512]=nt;xt[1024]=nt|32;xt[1536]=nt|96;xt[2560]=nt|160;xt[3584]=nt|224; +xt[768]=nt|ot;xt[4096]=1;xt[8192]=2;xt[24576]=98;xt[40960]=162;xt[57344]=226;var Dt=[];Dt[lt]=function(a){a+=this.G;return(this.controller.A=this.V[a])>>this.controller.ji&255};Dt[lt|16384]=function(a){return(this.controller.A=this.V[(a&-4)+this.G])>>((a&3)<<3)&255};Dt[lt|mt]=function(a){a+=this.G;var b=this.controller.A=this.V[a&-2];return(a&1?b>>8:b)&255}; Dt[1280]=function(a){a+=this.G;a=this.controller.A=this.V[a];for(var b=this.controller.wh,c=this.controller.vh&b,d=0,e=128;e;)(a&b)==c&&(d|=e),c>>>=1,b>>>=1,e>>=1;return d};Dt[nt]=function(a,b){a+=this.G;b=(b|b<<8|b<<16|b<<24)&this.controller.Md|this.controller.ae;b=b&this.controller.Ab|this.controller.A&~this.controller.Ab;b=b&this.controller.ib|this.V[a]&~this.controller.ib;this.V[a]!=b&&(this.V[a]=b,this.Ma=!0)}; Dt[nt|32]=function(a,b){a+=this.G;b=b>>this.controller.Oc|b<<8-this.controller.Oc&255;b=(b|b<<8|b<<16|b<<24)&this.controller.Md|this.controller.ae;b=b&this.controller.Ab|this.controller.A&~this.controller.Ab;b=b&this.controller.ib|this.V[a]&~this.controller.ib;this.V[a]!=b&&(this.V[a]=b,this.Ma=!0)}; Dt[nt|96]=function(a,b){a+=this.G;b=b>>this.controller.Oc|b<<8-this.controller.Oc&255;b=(b|b<<8|b<<16|b<<24)&this.controller.Md|this.controller.ae;b&=this.controller.A;b=b&this.controller.Ab|this.controller.A&~this.controller.Ab;b=b&this.controller.ib|this.V[a]&~this.controller.ib;this.V[a]!=b&&(this.V[a]=b,this.Ma=!0)}; @@ -575,15 +575,15 @@ Dt[98]=function(a,b){a+=this.G;b=$t[b&15];b&=this.controller.A;b=b&this.controll Dt[226]=function(a,b){a+=this.G;b=$t[b&15];b^=this.controller.A;b=b&this.controller.Ab|this.controller.A&~this.controller.Ab;b=b&this.controller.ib|this.V[a]&~this.controller.ib;this.V[a]!=b&&(this.V[a]=b,this.Ma=!0)};Dt[3]=function(a,b){a+=this.G;b=b>>this.controller.Oc|b<<8-this.controller.Oc&255;b=(b|b<<8|b<<16|b<<24)&this.controller.Ab;b=this.controller.Gf&b|this.controller.A&~b;b=b&this.controller.ib|this.V[a]&~this.controller.ib;this.V[a]!=b&&(this.V[a]=b,this.Ma=!0)}; function P(a,b,c,d,e){Eb.call(this,"Video",a,570425344);var f=this,g;this.jd=ib("Gecko/");this.ba=a.model;var h=au[this.ba]||au.mda;this.Ja=h[0];this.ud=a.memory||0;this.nd=a.switches;this.Qb=a.randomize;null==this.Qb&&(this.Qb=1);this.da=a.mode;if(null==this.da||null==bu[this.da])this.da=h[1];this.zc=a.charCols;this.Fc=a.charRows;if(void 0===this.zc||void 0===this.Fc)this.zc=bu[this.da][0],this.Fc=bu[this.da][1];this.ma=a.screenWidth;this.ka=a.screenHeight;this.P=b;this.M=c;this.F=(this.sg=d)||b|| null;this.ic=a.screenColor||"black";this.md=(1-(kb("flicker")||a.flicker||0)).toString();this.Hb=!1;b&&(b.style.backgroundColor=this.ic);e&&(e.style.backgroundColor=this.ic);b=a.smoothing;(c=kb("smoothing"))&&(b="true"==c);null!=b&&(g=mb(this.M,"imageSmoothingEnabled"))&&(this.M[g]=b);this.od=a.touchScreen;this.kb=cu;this.H=null;this.Rd=a.autoLock;this.cb=this.Rb=0;this.va=[];this.fa=Array(this.Ja==ar?256:16);this.Ga=!1;if(this.T=e)if(g=mb(e,"requestFullscreen")||mb(e,"requestFullScreen")){this.T.A= -e[g];if(e=mb(document,"on","fullscreenchange")){var k=mb(document,"fullscreenElement")||mb(document,"fullScreenElement");document.addEventListener(e,function(){du(f,!!k)},!1)}(e=mb(document,"on","fullscreenerror"))&&document.addEventListener(e,function(){du(f,null)},!1)}if(this.F&&(this.F.onfocus=function(){return f.Eg(!0)},this.F.onblur=function(){return f.Eg(!1)},this.F.me=(g=mb(this.F,"requestPointerLock"))&&this.F[g],this.F.B=(g=mb(this.F,"exitPointerLock"))&&this.F[g],this.F.me&&(e=mb(document, -"on","pointerlockchange")))){var m=mb(document,"pointerLockElement");document.addEventListener(e,function(){f.If(!(!m||document[m]!==f.F))},!1)}(this.ra=a.fontROM)&&"json"!=Ga(this.ra)&&(this.ra=bb()+"/api/v1/dump?file\x3d"+this.ra+"\x26format\x3dbytes")}ja(P,Eb);l=P.prototype; +e[g];if(e=mb(document,"on","fullscreenchange")){var k=mb(document,"fullscreenElement")||mb(document,"fullScreenElement");document.addEventListener(e,function(){du(f,null!=document[k])},!1)}(e=mb(document,"on","fullscreenerror"))&&document.addEventListener(e,function(){du(f)},!1)}if(this.F&&(this.F.onfocus=function(){return f.Eg(!0)},this.F.onblur=function(){return f.Eg(!1)},this.F.me=(g=mb(this.F,"requestPointerLock"))&&this.F[g],this.F.B=(g=mb(this.F,"exitPointerLock"))&&this.F[g],this.F.me&&(e= +mb(document,"on","pointerlockchange")))){var m=mb(document,"pointerLockElement");document.addEventListener(e,function(){f.If(!(!m||document[m]!==f.F))},!1)}(this.ra=a.fontROM)&&"json"!=Ga(this.ra)&&(this.ra=bb()+"/api/v1/dump?file\x3d"+this.ra+"\x26format\x3dbytes")}ja(P,Eb);l=P.prototype; l.qc=function(a,b,c,d){var e=this;this.oa=b;this.G=c;this.ca=d;c=+Xd(a,"randomize");0<=c&&1>=c&&(this.Qb=c);c=(c=au[this.ba])&&c[0];c!==eu&&(ld(b,this,fu),pd(b,this,gu));c!==hu&&(ld(b,this,iu),pd(b,this,ju));this.Ja>=Zq&&(ld(b,this,ku),pd(b,this,lu));this.Ja==ar&&(ld(b,this,mu),pd(b,this,nu));d&&gm(d,570425344,function(a){var b=e.ca;if(e.D)if(a[0])if(b=e.D,b.bd){var c,d=!1,f=8,g=8,h=-1,J=b.video.B>>3;for(c=0;c<a.length;c++){var H=a[c];if(c){var I=H.charAt(0);var R=ya(H.substr(1),16);switch(I){case "l":f= -R;break;case "n":1<=R&&8>=R&&(g=R,d=!0);break;case "p":0<=R&&3>=R&&(h=R);break;case "w":R<J&&(J=R);break;default:b.ca.O("unrecognized argument: "+H)}}else var B=ya(H,16)}void 0===B?B=b.C||0:B>=b.cb&&(B-=b.cb);a="";for(c=0;c<f;c++){H=q(b.cb+B)+":";for(R=0;R<g&&B<b.bd.length;R++)I=b.bd[B++],H+=" "+(0>h?q(I):Aa(I>>(h<<3),8));d&&(B+=J-g);a&&(a+="\n");a+=H}a&&b.ca.O(a);b.C=B}else b.ca.O("no buffer");else b.O("BIOSMODE: "+Da(e.la)),B=e.D,At(B,"CRTC",B.Mb,B.Na,B.eg),B.Ja>=Zq&&(At(B," GRC",B.Cd,B.Bd,B.ah), -At(B," SEQ",B.Dd,B.ce,B.bh),At(B," ATC",B.Ad,B.Bc,B.$g),At(B," ATCINDX",B.Ad),B.ca.O(" ATCDATA: "+B.Ke),At(B," FEAT",B.Nf),At(B," MISC",B.Ze),At(B," STATUS0",B.Lg)),At(B," STATUS1",B.ga),B.Ja!=hu&&B.Ja!=eu||At(B," MODEREG",B.Rc),B.Ja==eu&&At(B," COLOR",B.Xe),B.Ja>=Zq&&(B.ca.O(" LATCHES: "+q(B.A)),B.ca.O(" ACCESS: "+q(B.vg,4)),B.ca.O("Use 'dump video [addr]' to dump video memory"));else b.O("no active video card")});if((this.C=qc(a,"Keyboard"))&&this.P){for(var f in this.na)0<f.indexOf("lock")&& +R;break;case "n":1<=R&&8>=R&&(g=R,d=!0);break;case "p":0<=R&&3>=R&&(h=R);break;case "w":R<J&&(J=R);break;default:b.ca.O("unrecognized argument: "+H)}}else var B=ya(H,16)}void 0===B?B=b.C||0:B>=b.cb&&(B-=b.cb);a="";for(c=0;c<f;c++){H=q(b.cb+B)+":";for(R=0;R<g&&B<b.bd.length;R++)I=b.bd[B++],H+=" "+(0>h?q(I,8):Aa(I>>(h<<3),8));d&&(B+=J-g);a&&(a+="\n");a+=H}a&&b.ca.O(a);b.C=B}else b.ca.O("no buffer");else b.O("BIOSMODE: "+Da(e.la)),B=e.D,At(B,"CRTC",B.Mb,B.Na,B.eg),B.Ja>=Zq&&(At(B," GRC",B.Cd,B.Bd,B.ah), +At(B," SEQ",B.Dd,B.ce,B.bh),At(B," ATC",B.Ad,B.Bc,B.$g),At(B," ATCINDX",B.Ad),B.ca.O(" ATCDATA: "+B.Ke),At(B," FEAT",B.Nf),At(B," MISC",B.Ze),At(B," STATUS0",B.Lg)),At(B," STATUS1",B.ga),B.Ja!=hu&&B.Ja!=eu||At(B," MODEREG",B.Rc),B.Ja==eu&&At(B," COLOR",B.Xe),B.Ja>=Zq&&(B.ca.O(" LATCHES: "+q(B.A)),B.ca.O(" ACCESS: "+q(B.vg,4)),B.ca.O("Use 'd video [addr]' to dump video memory"));else b.O("no active video card")});if((this.C=qc(a,"Keyboard"))&&this.P){for(var f in this.na)0<f.indexOf("lock")&& this.C.wb("led",f,this.na[f]);this.C.wb(this.sg?"textarea":"canvas","screen",this.F)}this.Cb=9;(this.Y=qc(a,"ChipSet"))&&this.nd&&this.Ja==Zq&&(this.Cb=Il(this.nd,this.Cb));"mouse"==this.od?(this.H=qc(a,"Mouse"))&&ou(this,pu):"keygrid"==this.od&&this.C&&ou(this,qu);this.kb||ou(this,ru);if(this.ra){var g="Loading "+this.ra+"...";ab(this.ra,null,!0,function(a,b,c){su(e,a,b,c)},function(){e.O(g,ac)})}Yd(this.G,this.id,function(){tu(e)},1E3/uu)}; l.wb=function(a,b,c){var d=this;if(!this.na[b])switch(this.na[b]=c,b){case "fullScreen":return this.T&&this.T.A?c.onclick=function(){if(d.T){if(d.T.A){var a="100%";if(screen&&screen.width&&screen.height){var b=screen.width/screen.height,c=d.ma/d.ka;b>c&&(a=Math.round(c/b*100)+"%")}d.jd?(d.P.style.width=a,d.P.style.width=a,d.P.style.display="block",d.P.style.margin="auto"):(d.T.style.width=a,d.T.style.height="auto");d.T.style.backgroundColor=d.ic;d.T.A()}d.F&&d.F.focus()}}:c.parentNode.removeChild(c), -!0;case "lockPointer":return this.Td=c.textContent,this.F&&this.F.me?c.onclick=function(){d.me(!0)}:c.parentNode.removeChild(c),!0;case "refresh":return c.onclick=function(){tu(d,!0)},!0}return!1};function du(a,b){!b&&a.T&&(a.jd?a.P.style.width=a.P.style.height="":a.T.style.width=a.T.style.height="");ic(a,"notifyFullScreen("+b+")",!0);a.C&&(a.C.kh=b)} -l.me=function(a){var b=!1;this.F&&this.H&&(a?this.F.me&&(this.F.me(),this.H.If(!0),b=!0):this.F.B&&(this.F.B(),this.H.If(!1),b=!0),this.F&&this.F.focus());return b};l.If=function(a){this.H&&(this.H.If(a),this.C&&(this.C.kh=a));var b=this.na.lockPointer;b&&(b.textContent=a?"Press Esc to Unlock Pointer":this.Td)}; +!0;case "lockPointer":return this.Td=c.textContent,this.F&&this.F.me?c.onclick=function(){d.me(!0)}:c.parentNode.removeChild(c),!0;case "refresh":return c.onclick=function(){tu(d,!0)},!0}return!1};function du(a,b){!b&&a.T&&(a.jd?a.P.style.width=a.P.style.height="":a.T.style.width=a.T.style.height="");a.C&&(a.C.kh=1==b)}l.me=function(a){var b=!1;this.F&&this.H&&(a?this.F.me&&(this.F.me(),this.H.If(!0),b=!0):this.F.B&&(this.F.B(),this.H.If(!1),b=!0),this.F&&this.F.focus());return b}; +l.If=function(a){this.H&&(this.H.If(a),this.C&&(this.C.kh=a));var b=this.na.lockPointer;b&&(b.textContent=a?"Press Esc to Unlock Pointer":this.Td)}; function ou(a,b){var c=a.F;if(c&&!a.kb){a.kb=b;var d=!1;if(b!=pu)try{var e=Object.defineProperty({},"passive",{get:function(){d=!0}});window.addEventListener("testPassive",null,e);window.removeEventListener("testPassive",null,e)}catch(f){}c.addEventListener("touchstart",function(b){Pq(a.Y,b);a.kb!=ru&&vu(a,b,!0)},d?{passive:!0}:!1);b!=ru&&(c.addEventListener("touchmove",function(b){vu(a,b)},d?{passive:!0}:!0),c.addEventListener("touchend",function(b){vu(a,b,!1)},!1),a.sb=a.tb=a.pd=-1,a.xc=!1,a.Ob= null,a.tc=!1,a.Sd=function(){a.tc=!0;a.H.Zd(wu,!0)})}}l.Eg=function(a){this.C&&this.C.Eg(a)}; function vu(a,b,c){var d=0,e=0;var f=a.P;do isNaN(f.offsetLeft)||(d+=f.offsetLeft,e+=f.offsetTop);while(f=f.offsetParent);var g=a.ma/a.P.offsetWidth,h=a.ka/a.P.offsetHeight;if(b.targetTouches&&b.targetTouches.length){f=b.targetTouches[0].pageX;var k=b.targetTouches[0].pageY}else f=b.pageX,k=b.pageY;f=(f-d)*g;k=(k-e)*h;if(a.kb==qu)c&&Ar(a.C,xu[k/(a.ka/3)|0][f/(a.ma/3)|0],!0);else if(a.H){e=a.xc;d=b.timeStamp-a.pd;!0===c?(a.xc=500<d,a.pd=b.timeStamp,a.Ob=setTimeout(a.Sd,500)):null!=a.Ob&&(clearTimeout(a.Ob), @@ -635,14 +635,14 @@ var cu=0,ru=1,qu=2,pu=3,xu=[[1036,1038,1033],[1037,1032,1039],[1035,1040,1034]], 974:P.prototype.gn,975:P.prototype.fn},lu={954:P.prototype.Ik,960:P.prototype.Hk,961:P.prototype.Hk,962:P.prototype.Yo,964:P.prototype.$o,965:P.prototype.Zo,970:P.prototype.Qo,972:P.prototype.Po,974:P.prototype.Oo,975:P.prototype.No,986:P.prototype.Ik},mu={963:P.prototype.zn,966:P.prototype.Zm,967:P.prototype.$m,969:P.prototype.Ym,970:P.prototype.An,972:P.prototype.Bn},nu={963:P.prototype.bp,966:P.prototype.Eo,967:P.prototype.Fo,968:P.prototype.Go,969:P.prototype.Do}; tb(function(){for(var a=Rb(document,"pcx86","video"),b=0;b<a.length;b++){var c=a[b],d=Sb(c),e=document.createElement("canvas");if(void 0===e||!e.getContext){c.innerHTML="\x3cbr/\x3eMissing \x26lt;canvas\x26gt; 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.height="auto";0<=cb().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(null));var f=+(kb("aspect")||d.aspect);f&&.3<=f&&3.33>=f&&(sb("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");ib("iOS")&&(f.setAttribute("autocapitalize","off"),f.setAttribute("autocorrect","off"),f.style.fontSize="16px");c.appendChild(f);var g=e.getContext("2d");d=new P(d,e,g,f,c);Qb(d,c)}}); -function ew(a){Eb.call(this,"ParallelPort",a,537919488);this.H=a.adapter;switch(this.H){case 1:this.D=956;this.C=7;break;case 2:this.D=888;this.C=7;break;case 3:this.D=632;this.C=5;break;default:xb("Unrecognized parallel adapter #"+this.H);return}this.A=this.B=null;a=a.binding;"console"==a?this.B="":Lb(this,a)}ja(ew,Eb);l=ew.prototype;l.wb=function(a,b,c){return null==a||"textarea"==a?(this.na[b]=this.A=c,!0):!1}; +function ew(a){Eb.call(this,"ParallelPort",a,537919488);this.H=a.adapter;switch(this.H){case 1:this.D=956;this.C=7;break;case 2:this.D=888;this.C=7;break;case 3:this.D=632;this.C=5;break;default:xb("Unrecognized parallel adapter #"+this.H);return}this.A=this.B=null;a=a.binding;"console"==a?this.B="":Lb(this,a)}ja(ew,Eb);l=ew.prototype;l.wb=function(a,b,c){return a&&"textarea"!=a?!1:(this.na[b]=this.A=c,!0)}; l.qc=function(a,b,c,d){this.oa=b;this.G=c;this.ca=d;this.Y=qc(a,"ChipSet");ld(b,this,fw,this.D);pd(b,this,gw,this.D);ec(this)};l.Yb=function(a,b){if(!b)if(!a||!this.restore)this.reset();else if(!this.restore(a))return!1;return!0};l.Xb=function(a){return a?this.save():!0};l.reset=function(){hw(this)};l.save=function(){var a=new kg(this),b=0,c=[];c[b++]=this.F;c[b++]=this.Fb;c[b]=this.jf;a.set(0,c);return a.data()};l.restore=function(a){return hw(this,a[0])}; function hw(a,b){var c=0;void 0===b&&(b=[0,iw,0]);a.F=b[c++];a.Fb=b[c++];a.jf=b[c];return!0}l.an=function(a,b){var c=this.F;t(this,a,null,b,"DATA",c);return c};l.xn=function(a,b){var c=this.Fb;this.Fb=this.Fb|jw|kw;t(this,a,null,b,"STAT",c);lw(this);return c};l.Xm=function(a,b){var c=this.jf;t(this,a,null,b,"CTRL",c);return c}; l.Ho=function(a,b,c){var d=this;t(this,a,b,c,"DATA");this.F=b;ve(this.G,function(){var a=b,c=!1;ic(d,"transmitByte("+Da(a)+")");if(d.A)13!=a&&(8==a?d.A.value=d.A.value.slice(0,-1):(128<=a&&(a=160>a?a-128:224>a?42:32),d.A.value+=Pa(a),d.A.scrollTop=d.A.scrollHeight)),c=!0;else if(null!=d.B){if(10==a||1024<=d.B.length)d.O(d.B),d.B="";10!=a&&(d.B+=String.fromCharCode(a));c=!0}return c?(d.Fb|=iw,d.Fb&=~(jw|kw),!0):!1});lw(this)};l.Co=function(a,b,c){t(this,a,b,c,"CTRL");this.jf=b;lw(this)}; function lw(a){a.Y&&a.C&&(a.jf&mw&&!(a.Fb&jw)?Fh(a.Y,a.C):rh(a.Y,a.C))}var iw=8,jw=64,kw=128,mw=16,fw={0:ew.prototype.an,1:ew.prototype.xn,2:ew.prototype.Xm},gw={0:ew.prototype.Ho,2:ew.prototype.Co};tb(function(){for(var a=Rb(document,"pcx86","parallel"),b=0;b<a.length;b++){var c=a[b],d=Sb(c);d=new ew(d);Qb(d,c)}}); function nw(a){Eb.call(this,"SerialPort",a,538968064);this.da=a.adapter;switch(this.da){case 1:this.ea=1016;this.P=Qq;break;case 2:this.ea=760;this.P=Rq;break;default:if("test"!=this.ee){xb("Unrecognized serial adapter #"+this.da);return}}this.F=this.L=null;this.pa=a.tabSize||0;this.ja=a.charBOL||0;this.M=this.ka=0;this.ra=ow|pw;this.Z=!0;a=a.binding;"console"==a?this.L="":Lb(this,a);this.D=this.C=this.aa=null;this.la=!1;this.exports={bind:this.lm,connect:this.sj,receiveData:this.zd,receiveStatus:this.am}} ja(nw,Eb);l=nw.prototype;l.lm=function(a,b,c){return this.D?!1:(this.D=a,this.C=b,this.la=void 0===c?!1:c,!0)};l.Mi=function(a,b,c){var d=null;a!=this.ee||this.D||(this.D=b,this.aa=c,this.Z=!1,d=this);return d}; -l.wb=function(a,b,c){if(null==a||"textarea"==a){var d=this;this.na[b]=this.F=c;this.F.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<b&&(b-=64),d.zd(b);return!0};this.F.onkeypress=function(a){a=a||window.event;d.zd(a.which||a.keyCode);a.preventDefault&&a.preventDefault();return!0};this.F.removeAttribute("readonly");return!0}return!1}; +l.wb=function(a,b,c){if(!a||"textarea"==a){var d=this;this.na[b]=this.F=c;this.F.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<b&&(b-=64),d.zd(b);return!0};this.F.onkeypress=function(a){a=a||window.event;d.zd(a.which||a.keyCode);a.preventDefault&&a.preventDefault();return!0};this.F.removeAttribute("readonly");return!0}return!1}; l.qc=function(a,b,c,d){this.qa=a;if(this.da){this.oa=b;this.G=c;this.ca=d;var e=this;this.va=Yd(this.G,this.id+".receive",function(){e.zd()});this.xa=Yd(this.G,this.id+".transmit",function(){e.A=e.A|qw|rw;sw(e)});this.Y=qc(a,"ChipSet");ld(b,this,tw,this.ea);pd(b,this,uw,this.ea)}ec(this)}; l.sj=function(a){if(!this.D){var b=Xd(this.qa,"connection");if(b){var c=b.split("-\x3e");if(2==c.length){var d=Oa(c[0]);if(d!=this.ee)return;c=Oa(c[1]);if(this.D=Ub(c)){var e=this.D.exports;if(e){var f=e.connect;f&&f.call(this.D,this.Z);if(this.C=e.receiveData){this.Z=a;this.aa=e.receiveStatus;this.status("Connected "+this.Pd+"."+d+" to "+c);return}}}}this.status("Unable to establish connection: "+b)}}}; l.Yb=function(a,b){if(!b)if(this.sj(this.Z),!a||!this.restore)this.reset();else if(!this.restore(a))return!1;return!0};l.Xb=function(a){return a?this.save():!0};l.reset=function(){vw(this)};l.save=function(){var a=new kg(this),b=0,c=[];c[b++]=this.fa;c[b++]=this.ma;c[b++]=this.I;c[b++]=this.N;c[b++]=this.K;c[b++]=this.H;c[b++]=this.T;c[b++]=this.A;c[b++]=this.B;c[b]=this.J;a.set(0,c);return a.data()};l.restore=function(a){return vw(this,a[0])}; diff --git a/versions/pcx86/1.61.0/pcx86.js.map b/versions/pcx86/1.61.0/pcx86.js.map index 3ecad499f6..81f276b983 100644 --- a/versions/pcx86/1.61.0/pcx86.js.map +++ b/versions/pcx86/1.61.0/pcx86.js.map @@ -1 +1 @@ -{"version":3,"file":"pcx86.js","lineCount":954,"mappings":"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","sources":["versions/pcx86/1.61.0/pcx86-uncompiled.js"," [synthetic:util/objectcreate] "," [synthetic:es6/util/setprototypeof] "," [synthetic:es6/util/inherits] "," [synthetic:util/defineproperty] "," [synthetic:util/global] "," [synthetic:es6/symbol] "," [synthetic:es6/util/arrayfromiterable] "," [synthetic:es6/util/makeiterator] "," [synthetic:es6/util/arrayfromiterator] "," [synthetic:util/polyfill] "," [synthetic:es6/math/trunc] "," [synthetic:es6/number/parseint] "," [synthetic:es6/math/sign] "],"names":["FDC.CMDS","$jscomp.objectCreate","$jscomp.setPrototypeOf","$jscomp.defineProperty","$jscomp.global","$jscomp.initSymbol","$jscomp.Symbol","$jscomp.SYMBOL_PREFIX","$jscomp.arrayIterator","$jscomp.initSymbolIterator","$jscomp.iteratorPrototype","$jscomp.polyfill","DiskAPI.GEOMETRIES","ASCII","BREAK","CTRL_A","CTRL_B","CTRL_C","CTRL_D","CTRL_E","CTRL_F","CTRL_G","CTRL_H","CTRL_I","CTRL_J","CTRL_K","CTRL_L","CTRL_M","CTRL_N","CTRL_O","CTRL_P","CTRL_Q","CTRL_R","CTRL_S","CTRL_T","CTRL_U","CTRL_V","CTRL_W","CTRL_X","CTRL_Y","CTRL_Z","ESC","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","DEL","Keys.NONASCII_KEYCODES","KEYCODE","Keys.ASCII","Keys.SHIFTED_KEYCODES","Str","parseInt","base","chPrefix","fCommas","indexOf","replace","ch","charAt","substr","chSuffix","slice","shift","match","isNaN","Math","pow","trunc","value","toBase","radix","cch","sPrefix","nGrouping","ceil","log","String","fromCharCode","toBin","abs","Str.toBase","toOct","fPrefix","toHex","toHexByte","Str.toHex","toHexWord","getBaseName","sFileName","fStripExt","sBaseName","lastIndexOf","substring","getExtension","sExtension","toLowerCase","endsWith","sSuffix","length","escapeHTML","sHTML","Str.HTMLEscapeMap","pad","fPadLeft","sPadding","sprintf","format","buffer","aParts","split","iArg","iPart","arg","args","flags","minimum","precision","conversion","ach","round","Str.HexUpperCase","Str.HexLowerCase","Number","trim","prototype","toASCIICode","Str.ASCII.CR","Str.ASCII.LF","Str.ASCIICodeMap","LF","CR","binarySearch","fnCompare","left","right","found","undefined","middle","compareResult","formatDate","sFormat","date","sDate","Date","iHour","getHours","iDay","getDate","iMonth","getMonth","Usr.asDays","getDay","Usr.asMonths","getMinutes","getSeconds","getFullYear","Array","Usr.aMonthDays","Usr.getTime","now","getResource","sURL","type","fAsync","done","progress","callback","request","readyState","resource","fArrayBuffer","response","responseText","err","status","window","location","protocol","nErrorCode","resources","XMLHttpRequest","ActiveXObject","fXHR2","responseType","onreadystatechange","sPost","hasOwnProperty","encodeURIComponent","open","setRequestHeader","send","overrideMimeType","getHost","host","SITEHOST","getUserAgent","navigator","userAgent","hasLocalStorage","Web.fLocalStorage","localStorage","setItem","Web.sLocalStorageTest","getItem","removeItem","getLocalStorageItem","sKey","sValue","setLocalStorageItem","isUserAgent","Web.getUserAgent","isMobile","sDevice","sMobile","Web.getURLParm","Web.isUserAgent","fInvert","findProperty","obj","sProp","Web.asBrowserPrefixes.length","sName","Web.asBrowserPrefixes","toUpperCase","getURLParm","sParm","Web.parmsURL","sParms","aParms","search","pl","exec","decodeURIComponent","downloadFile","sData","sType","fBase64","link","sURI","encodeURI","document","createElement","download","href","body","appendChild","click","removeChild","sAlert","onCountRepeat","fnRepeat","fnComplete","fnTimeout","doCountRepeat","setTimeout","onClickRepeat","fn","doClickRepeat","msRepeat","ms","timer","fIgnoreMouseEvents","onmousedown","e.onmousedown","msDelay","ontouchstart","e.ontouchstart","onmouseup","onmouseout","e.onmouseout","clearTimeout","ontouchend","ontouchcancel","e.ontouchcancel","onPageEvent","sFunc","fnPrev","onInit","Web.aPageEventHandlers","push","doPageEvent","afn","Web.fPageEventsEnabled","Component.alertUser","message","enablePageEvents","fEnable","Web.fPageLoaded","Web.sendPageEvent","Web.fPageShowed","sendPageEvent","sEvent","Web.doPageEvent","Web.onPageEvent","onPageLoad","onPageShow","onPageUnload","constructor","Component","parms","bitsMessage","id","name","comment","bindings","idComponent","idMachine","ready","busy","busyCancel","initDone","powered","unloading","error","fnReady","clearError","dbg","cpu","bus","cmp","Component.components.push","component","addMachineResource","data","Component.machines","alertUser","sMessage","alert","confirmUser","sPrompt","fResponse","confirm","appendControl","control","sText","scrollTop","scrollHeight","replaceControl","sSearch","sReplace","bindExternalControl","sBinding","target","Component.getComponentByType","setBinding","bindComponentControls","element","aeControls","Component.getElementsByClass","parentNode","iControl","aeChildNodes","childNodes","iNode","nodeType","sClass","getAttribute","aClasses","iClass","Component.getComponentParms","getComponents","idRelated","aComponents","Component.components.length","Component.components","getComponentByID","getComponentByType","componentPrev","getComponentParms","eval","getElementsByClass","sObjClass","getElementsByClassName","ae","aeAll","getElementsByTagName","re","RegExp","test","className","processScript","sScript","fSuccess","Component.commands","aCommands","aTokens","sToken","chQuote","Component.processCommands","processCommands","splice","sCommand","fnCallReady","Component.asyncCommands.indexOf","processNextCommand","fnCommand","Component.globalCommands","Component.componentCommands","exports","call","Component.prototype","?.prototype","toString","sHTMLType","onclick","clearControl","notice","this.notice","println","print","printControl","Component.appendControl","printlnControl","Component.PRINT.PROGRESS","Component.replaceControl","fPrintOnly","computer","console","setError","isError","isReady","setReady","fReady","isBusy","fCancel","setBusy","fBusy","powerUp","powerDown","fSave","fShutdown","messageEnabled","bitsEnabled","printf","Str.sprintf.apply","$jscomp.arrayFromIterable","printMessage","fAddress","printMessageIO","port","bOut","addrFrom","bIn","messageIO","PROGRESS","Component.asyncCommands","scriptAlert","scriptSleep","fnCallback","sDelay","scriptSelect","aBindings","options","textContent","selectedIndex","Array.prototype.indexOf","start","isArray","Array.isArray","Object","Function","bind","Function.prototype.bind","fnBound","fToBind","apply","fnNOP","concat","arguments","TypeError","TYPEDARRAYS","ArrayBuffer","CYCLES_8088","nWordCyclePenalty","nEACyclesBase","nEACyclesDisp","nEACyclesBaseIndex","nEACyclesBaseIndexExtra","nEACyclesBaseDisp","nEACyclesBaseIndexDisp","nEACyclesBaseIndexDispExtra","nOpCyclesAAA","nOpCyclesAAD","nOpCyclesAAM","nOpCyclesArithRR","nOpCyclesArithRM","nOpCyclesArithMR","nOpCyclesArithMID","nOpCyclesCall","nOpCyclesCallF","nOpCyclesCallWR","nOpCyclesCallWM","nOpCyclesCallDM","nOpCyclesCLI","nOpCyclesCompareRM","nOpCyclesCWD","nOpCyclesBound","nOpCyclesInP","nOpCyclesInDX","nOpCyclesIncR","nOpCyclesIncM","nOpCyclesInt","nOpCyclesInt3D","nOpCyclesIntOD","nOpCyclesIntOFall","nOpCyclesIRet","nOpCyclesJmp","nOpCyclesJmpF","nOpCyclesJmpC","nOpCyclesJmpCFall","nOpCyclesJmpWR","nOpCyclesJmpWM","nOpCyclesJmpDM","nOpCyclesLAHF","nOpCyclesLEA","nOpCyclesLS","nOpCyclesLoop","nOpCyclesLoopZ","nOpCyclesLoopNZ","nOpCyclesLoopFall","nOpCyclesLoopZFall","nOpCyclesMovRR","nOpCyclesMovRM","nOpCyclesMovMR","nOpCyclesMovRI","nOpCyclesMovMI","nOpCyclesMovAM","nOpCyclesMovMA","nOpCyclesDivBR","nOpCyclesDivWR","nOpCyclesDivBM","nOpCyclesDivWM","nOpCyclesIDivBR","nOpCyclesIDivWR","nOpCyclesIDivBM","nOpCyclesIDivWM","nOpCyclesMulBR","nOpCyclesMulWR","nOpCyclesMulBM","nOpCyclesMulWM","nOpCyclesIMulBR","nOpCyclesIMulWR","nOpCyclesIMulBM","nOpCyclesIMulWM","nOpCyclesNegR","nOpCyclesNegM","nOpCyclesOutP","nOpCyclesOutDX","nOpCyclesPopAll","nOpCyclesPopReg","nOpCyclesPopMem","nOpCyclesPushAll","nOpCyclesPushReg","nOpCyclesPushMem","nOpCyclesPushSeg","nOpCyclesPrefix","nOpCyclesCmpS","nOpCyclesCmpSr0","nOpCyclesCmpSrn","nOpCyclesLodS","nOpCyclesLodSr0","nOpCyclesLodSrn","nOpCyclesMovS","nOpCyclesMovSr0","nOpCyclesMovSrn","nOpCyclesScaS","nOpCyclesScaSr0","nOpCyclesScaSrn","nOpCyclesStoS","nOpCyclesStoSr0","nOpCyclesStoSrn","nOpCyclesRet","nOpCyclesRetn","nOpCyclesRetF","nOpCyclesRetFn","nOpCyclesShift1M","nOpCyclesShiftCR","nOpCyclesShiftCM","nOpCyclesShiftCS","nOpCyclesTestRR","nOpCyclesTestRM","nOpCyclesTestRI","nOpCyclesTestMI","nOpCyclesXchgRR","nOpCyclesXchgRM","nOpCyclesXLAT","CYCLES_80286","FUNCS","VIDEO","DISK","CASSETTE","DOS","WINDBG","Messages.CATEGORIES","CPU","SEG","DESC","PORT","TSS","IOPM","INT","NMI","FAULT","TRAP","BUS","IRQ","MEM","DMA","FDC","HDC","PIC","TIMER","CMOS","RTC","C8042","KBD","PARALLEL","SERIAL","MOUSE","SPEAKER","CHIPSET","COMPUTER","DATA","EVENT","KEY","WARN","HALT","BUFFER","Panel","parmsPanel","xMouse","yMouse","lockMouse","$jscomp.inherits","Panel.prototype","initBus","kbd","getMachineComponent","fRepower","Panel.init","clickMouse","event","fDown","button","updateMouse","moveMouse","xScale","Panel.LIVECANVAS.CX","canvas","offsetWidth","yScale","Panel.LIVECANVAS.CY","offsetHeight","rect","getBoundingClientRect","clientX","clientY","top","Panel.LIVEMEM.CX","findAddress","busInfo","aRects","contains","region","aRegions","bf","Bus.BlockInfo.num","num","aBlocks","iBlock","mask","addr","nBlockSize","addrLimit","cBlocks","cx","ratioMemoryToPixels","ADDR_INVALID","addrDumpLast","dumpMemory","context","canvasLiveRegs","contextLiveRegs","Panel.LIVEREGS.CY","Panel.LIVEDUMP.CY","width","fillStyle","Panel.LIVEREGS.COLOR","fillRect","Panel.LIVECANVAS.FONT.CY","sColor","style","color","sFontFace","xLeftMargin","xLeft","xText","yText","yTop","heightText","heightDefault","fontDefault","Panel.LIVECANVAS.FONT.FACE","fontText","canvasText","contextText","colorText","cxColumn","nCols","drawText","iLine","sChars","iCol","aMemBlocks","nBusMask","nBlockShift","readByteDirect","nBlockLimit","drawImage","xDump","yDump","cxDump","cyDump","nValue","nColsSkip","nLinesSkip","font","fillText","nDefaultBase","nDefaultDigits","skipCols","skipLines","init","aePanels","APPCLASS","iPanel","ePanel","panel","Component.getComponentByID","Component.bindComponentControls","CX","CY","FONT","FACE","COLOR","Web.onInit","Controller","getMemoryAccess","getMemoryBuffer","Bus","parmsBus","nBusWidth","addrTotal","nBusLimit","nBlockLen","nBlockTotal","nBlockMask","aPortInputNotify","aPortOutputNotify","fPortInputBreakAll","fPortOutputBreakAll","aPortInputWidth","aPortOutputWidth","block","Memory","copyBreakpoints","initMemory","aBusBlocks","nMemMask","reset","setA20","addMemory","size","controller","addrNext","sizeLeft","addrBlock","sizeBlock","used","sizeAvail","reportError","Bus.ERROR.ADD_MEM_INUSE","blockNew","flushPageBlocks","running","kb","sb","Memory.TYPE.NAMES","Bus.ERROR.ADD_MEM_BADRANGE","cleanMemory","fNoScrub","fClean","fDirty","fDirtyEver","aBlocks2Mb","setMemoryBlocks","getMemoryBlocks","addrMask","setMemoryAccess","fQuiet","Bus.ERROR.SET_MEM_BADRANGE","Bus.ERROR.SET_MEM_NOCTRL","setAccess","removeMemory","blockOld","Bus.ERROR.REM_MEM_BADRANGE","mem","fReadOnly","Memory.TYPE.ROM","dv","ab","aw","adw","littleEndian","Memory.afnArrayLE","Memory.afnArrayBE","Memory.afnMemory","getByte","readByte","getShortDirect","off","readShortDirect","setByte","writeByte","setByteDirect","writeByteDirect","setShortDirect","writeShortDirect","saveMemory","fAll","fA20","getA20","save","iSrc","iComp","aComp","aSrc","iCompare","addPortInputBreak","addPortInputTable","table","offset","addPortInputNotify","end","Str.toHexWord","checkPortInputNotify","addrLIP","aNotify","sizePort","maskPort","dataPort","checkPortInput","addPortOutputBreak","addPortOutputTable","addPortOutputNotify","checkPortOutputNotify","checkPortOutput","op","sError","Bus.BlockInfo","count","btmod","bit","bfs","ADD_MEM_INUSE","ADD_MEM_BADRANGE","SET_MEM_NOCTRL","SET_MEM_BADRANGE","REM_MEM_BADRANGE","setUint16","DataView","Uint16Array","Memory.idBlock","Memory.TYPE.NONE","Uint8Array","Int32Array","Memory.prototype","getInt32","restore","setInt32","fDirect","Memory.TYPE.UNPAGED","Memory.afnUnpaged","Memory.TYPE.PAGED","Memory.afnPaged","Memory.afnNone","setReadAccess","setWriteAccess","cReadBreakpoints","readNone","readShort","readShortDefault","readLong","readLongDefault","readLongDirect","cWriteBreakpoints","writeNone","writeShort","writeShortDefault","writeLong","writeLongDefault","writeLongDirect","addBreakpoint","fWrite","Memory.afnChecked","removeBreakpoint","resetWriteAccess","resetReadAccess","readByteMemory","readShortMemory","idw","nShift","dw","readLongMemory","writeByteMemory","writeShortMemory","writeLongMemory","readByteChecked","checkMemoryRead","checkMemoryException","readShortChecked","readLongChecked","writeByteChecked","checkMemoryWrite","writeShortChecked","writeLongChecked","readBytePaged","blockPDE","iPDE","bitPTEAccessed","blockPTE","iPTE","blockPhys","readShortPaged","readLongPaged","writeBytePaged","bitPTEDirty","writeShortPaged","writeLongPaged","readByteUnpaged","mapPageBlock","getPageBlock","readShortUnpaged","readLongUnpaged","writeByteUnpaged","writeShortUnpaged","writeLongUnpaged","readByteBE","readByteLE","readBytePLE","PTE","readShortBE","getUint16","readShortLE","readShortPLE","readLongBE","readLongLE","readLongPLE","writeByteBE","writeByteLE","writeBytePLE","writeShortBE","writeShortLE","writeShortPLE","writeLongBE","writeLongLE","writeLongPLE","adjustEndian","NONE","ROM","UNPAGED","PAGED","NAMES","Memory.afnPagedLE","parmsCPU","nCyclesDefault","nCycles","nMultiplier","counts","nBaseCyclesPerSecond","msPerYield","CPU.YIELDS_PER_SECOND","nBaseMultiplier","nCurrentMultiplier","nTargetMultiplier","mhzBase","mhzCurrent","mhzTarget","starting","yield","autoStart","displayLiveRegs","checksum","nChecksum","nCyclesChecksumNext","nCyclesChecksumStart","nCyclesChecksumInterval","nCyclesChecksumStop","aTimers","idRunTimeout","onRunTimeout","runCPU","CPU.prototype","CPU.BUTTONS.length","CPU.BUTTONS","fpu","chipset","sAutoStart","getMachineParm","addTimer","yieldTimer","resetCycles","resetChecksum","updateCPU","fRunning","stopCPU","startCPU","getChecksum","nTotalCycles","updateChecksum","fDisplay","getCycles","displayChecksum","fBound","control.onclick","powerOn","Computer.RESUME_REPOWER","iComponent","Component.getComponents","setSpeed","getSpeedTarget","toFixed","setBurstCycles","nDelta","nStepCycles","nBurstCycles","addCycles","fEndStep","calcCycles","nCyclesPerYield","floor","fScaled","nRunCycles","fUpdateFocus","sSpeed","controlSpeed","updateFocus","msStartRun","msEndThisRun","iTimer","resetTimers","setTimer","callBack","fReset","getMSCycles","endBurst","saveTimers","aTimerStates","nCyclesThisRun","calcStartTime","msDiscount","msStartThisRun","msDelta","getCurrentCyclesPerSecond","getBurstCycles","updateAllTimers","fCounting","ticksElapsed","nCyclesUpdate","fScaleTimers","nCyclesStart","nTicksDivisor","getTimerStart","countStart","mode","ChipSet.PIT_CTRL.MODE3","nCyclesRemain","abCMOSData","ChipSet.CMOS.ADDR.STATUSB","ChipSet.CMOS.STATUSB.PIE","nRTCCyclesNextUpdate","stepCPU","exception","updateTimers","stop","stack","calcRemainingTime","msYield","msRemainsThisRun","msElapsed","controlRun","updateStatus","CPU_prototype$stepCPU","fComplete","fStopped","complete","nonCPU","msStart","msStop","fForce","CPUX86","model","MODEL_8088","MODEL_80286","MODEL_80386","stepping","Str.parseInt","initProcessor","PS_SET","X86.PS_SET_8086","PS_DIRECT","X86.PS_DIRECT_8086","PS_CLEAR_RM","OPFLAG_NOINTR_8086","OPFLAG","nShiftCountMask","cycleCounts","X86.CYCLES_80286","X86.CYCLES_8088","aOps","X86.aOps","aOpGrp4b","X86.aOpGrp4b","aOpGrp4w","X86.aOpGrp4w","aOpGrp6","X86.aOpGrp6Real","MODEL_80186","X86.aOps.slice","X86.aOpGrp4b.slice","X86.aOpGrp4w.slice","X86.opInvalid","OPCODE","X86.opPUSHA","X86.opPOPA","X86.opBOUND","X86.opPUSHn","X86.opIMULn","X86.opPUSH8","X86.opIMUL8","X86.opINSb","X86.opINSw","X86.opOUTSb","X86.opOUTSw","X86.opGRP2bn","X86.opGRP2wn","X86.opENTER","X86.opLEAVE","X86.opINT1","X86.fnGRPInvalid","PS","X86.op0F","aOps0F","X86.aOps0F.slice","X86.opUndefined","X86.opPUSHSP","X86.opARPL","bOpcode","X86.opFS","X86.opGS","X86.opOS","X86.opAS","X86.aOps0F386","STEPPING_80386_A0","STEPPING_80386_B0","X86.opXBTS","X86.opIBTS","aIntNotify","aIntReturn","cIntReturn","debugCheck","cLiveRegs","resetRegs","removeMemBreak","fPhysical","enablePageBlocks","blockUnpaged","memEmpty","aCacheBlocks","CPUX86.PAGEBLOCKS_CACHE","iCacheBlocks","aBlocksPaged","releasePageBlock","regCR0","CR0","fSuppress","offPDE","LADDR","regCR3","pde","X86.helpPageFault.call","nCPL","offPTE","pte","acquirePageBlock","blockPage","Memory.adjustEndian","disablePageBlocks","CPUX86.prototype","getReg","reg","regEAX","regECX","regEDX","regEBX","getSP","regEBP","regESI","regEDI","setReg","setSP","regESP","fMDSet","regMDLo","regMDHi","r64Div","r64Rem","regXX","bModRM","addrIDT","addrIDTLimit","regPS","nIOPL","resultDst","resultSrc","resultArith","resultLogic","nFault","opCS","opSS","opLIP","opLSP","segCS","SegX86","SegX86.ID.CODE","segDS","SegX86.ID.DATA","segES","segSS","SegX86.ID.STACK","setSS","STEPPING_80386_B1","STEPPING_80386_C0","STEPPING_80386_D0","STEPPING_80386_D1","STEPPING_80386_D2","regCR1","regCR2","regDR","regTR","segFS","segGS","segNULL","SegX86.ID.NULL","segData","segStack","opFlags","opPrefixes","regEA","regEAWrite","segEA","intFlags","INTFLAG","setCSIP","addrGDT","addrGDTLimit","segLDT","SegX86.ID.LDT","segTSS","SegX86.ID.TSS","segVER","SegX86.ID.VER","regIP","getIP","setCSBase","regLIP","regLIPMax","limit","setPS","setProtMode","updateAddrSize","sizeAddr","getAddr","getShort","decodeModRegByte","X86.modRegByte16","decodeModMemByte","X86.modMemByte16","decodeModGrpByte","X86.modGrpByte16","sizeData","decodeModRegWord","X86.modRegShort16","decodeModMemWord","X86.modMemShort16","decodeModGrpWord","X86.modGrpShort16","X86.modRegLong16","X86.modMemLong16","X86.modGrpLong16","getLong","X86.modRegByte32","X86.modMemByte32","X86.modGrpByte32","X86.modRegShort32","X86.modMemShort32","X86.modGrpShort32","X86.modRegLong32","X86.modMemLong32","X86.modGrpLong32","setDataSize","maskData","updateDataSize","typeData","RESULT","getWord","setWord","setShort","setLong","resetSizes","maskAddr","sum","getCS","sel","getDS","getSS","getES","getPS","addIntNotify","nInt","addIntReturn","checkIntReturn","checkDebugRegisters","regDR7","bitsDR7","addMemCheck","removeMemCheck","nb","DR7","bitsRWRequired","bitsRWMask","len","fProt","fV86","isProtMode","isV86Mode","X86.aOpGrp6Prot","updateMode","state","State","set","saveProtMode","getSpeed","fPaging","isPagingEnabled","restoreProtMode","fRestored","iDst","aDst","getSeg","iTimerState","restoreTimers","setCS","setDS","load","fInterruptable","regLSP","fExpDown","regLSPLimit","regLSPLimitLow","min","setES","setIP","setLIP","cpl","fCall","offIP","fStackSwitch","checkIP","inc","newLIP","X86.helpFault.call","EXCEPTION","resetIP","setArithResult","dst","src","fSubtract","resultType","diff","getCF","getPF","getAF","getZF","getSF","getOF","setLogicResult","carry","overflow","setCF","clearCF","setOF","clearOF","setRotateResult","result","getCarry","clearAF","clearZF","setAF","setZF","setMSW","X86.PS_CACHED","checkIOPM","nPorts","fInput","bitsPorts","addrIOPM","addrIOPMLimit","bits","probeAddr","CPUX86_prototype$getShort","CPUX86_prototype$getLong","cb","cbBlock","CPUX86_prototype$setShort","CPUX86_prototype$setLong","getEAByte","seg","offEA","checkRead","getEAByteData","getEAByteStack","getEAWord","getEAShortData","getEAShortStack","getEALongData","getEALongStack","setEAByte","checkWrite","setEAShort","setEALong","getSOWord","setSOWord","getIPByte","getIPShort","getIPAddr","getIPWord","getIPDisp","popWord","delta","pushWord","pushData","updateReg","sReg","displayValue","sLabel","sVal","nMinCycles","fDebugCheck","checksEnabled","nDebugState","X86.OPFLAG_PREFIXES","checkINTR","iPriority","cPriorities","nIDT","getIRRVector","X86.helpInterrupt.call","DR6","X86.opHLT.call","checkInstruction","aeCPUs","iCPU","eCPU","FPUX86","parmsFPU","FPU","regStack","Float64Array","intStack","regTmpSR","Float32Array","intTmpSR","regTmpLR","intTmpLR","intTmpTR","regCodeSel","regDataSel","regCodeOff","regDataOff","regOpcode","iStack","regIndefinite","intIndefinite","resetFPU","setEAFromSR","setEAFromSI","setEAFromLR","setEAFromLI","FPUX86.prototype","regControl","getStatus","getTags","iReg","setControl","setStatus","regStatus","iST","checkException","setTags","regUsed","ChipSet.MODEL_5170","clearIRR","ChipSet.IRQ.FPU","setIRR","bNMI","ChipSet.NMI.ENABLE","setException","isAtLeastModel","checkResult","isFinite","Infinity","doAdd","operand1","operand2","doSubtract","doMultiply","doDivide","dividend","divisor","quotient","doCompare","cc","roundValue","operand","max","rc","FPUX86.MAX_INT32","getTag","tag","tags","bitUsed","getSR","getLR","getST","setST","checkOperand","getTR","fSafe","iInt","getTRFromLR","getWIFromEA","getSIFromEA","getSRFromEA","getLRFromEA","getTRFromEA","setEAFromTR","getLRFromTR","hiTR","signLR","expLR","loLR","loTR","hiLR","expTR","decodeBCD","encodeBCD","popValue","pushValue","NaN","loadEnv","saveEnv","FCLEX","clearStatus","FCOMst","FCOMPst","FCOMP8087","FPUX86.FCOMPst.call","FDIVsr","FFREEsti","setTag","FINIT","FLDCW","FLDENV","FRSTOR","setTR","FSAVE","FSTENV","FSTPsti","FSTP8087","FPUX86.FSTPsti.call","FSTCW","FSTSW","FSTSWAX287","FXCHsti","tmp","FXCH8087","FPUX86.FXCHsti.call","FPUX86.regL2T","LN2","FPUX86.regL2E","LOG2E","FPUX86.regPI","PI","FPUX86.regLG2","LN10","FPUX86.regLN2","FPUX86.MAX_INT64","FPUX86.aaOps","FADDsr","FMULsr","FCOMsr","FCOMPsr","FSUBsr","FSUBRsr","FPUX86.FDIVsr","FADDst","FMULst","FPUX86.FCOMst","FPUX86.FCOMPst","FSUBst","FSUBRst","FDIVst","FDIVRst","FLDsr","FSTsr","FSTPsr","FPUX86.FLDENV","FPUX86.FLDCW","FPUX86.FSTENV","FPUX86.FSTCW","FLDsti","FPUX86.FXCHsti","FNOP","FPUX86.FSTP8087","FCHS","FABS","FTST","FXAM","getSTSign","FLD1","FLDL2T","FLDL2E","FLDPI","FLDLG2","FLDLN2","FLDZ","F2XM1","FYL2X","FPTAN","tan","FPATAN","atan2","FXTRACT","FDECSTP","FINCSTP","FPREM","FYL2XP1","FSQRT","doSquareRoot","sqrt","FRNDINT","FSCALE","FIADD32","FIMUL32","FICOM32","FICOMP32","FISUB32","FISUBR32","FIDIV32","FIDIVR32","FILD32","FIST32","getSI","FISTP32","FLDtr","FSTPtr","FENI8087","isModel","FDISI8087","FPUX86.FCLEX","FPUX86.FINIT","FSETPM287","FSINCOS387","FADDlr","FMULlr","FCOMlr","FCOMPlr","FSUBlr","FSUBRlr","FDIVlr","FDIVRlr","FADDsti","FMULsti","FCOM8087","FPUX86.FCOMst.call","FPUX86.FCOMP8087","FSUBRsti","FSUBsti","FDIVRsti","FDIVsti","FLDlr","FSTlr","FSTPlr","FPUX86.FRSTOR","FPUX86.FSAVE","FPUX86.FSTSW","FPUX86.FFREEsti","FPUX86.FXCH8087","FSTsti","FPUX86.FSTPsti","FIADD16","FIMUL16","FICOM16","FICOMP16","FISUB16","FISUBR16","FIDIV16","FIDIVR16","FADDPsti","FMULPsti","FCOMPP","FSUBRPsti","FSUBPsti","FDIVRPsti","FDIVPsti","FILD16","FIST16","getWI","FPUX86.MAX_INT16","setEAFromWI","FISTP16","FBLDpd","FILD64","lo","getLIFromEA","hi","FBSTPpd","FISTP64","getLI","FFREEP8087","FPUX86.FFREEsti.call","FPUX86.FSTSWAX287","FPUX86.afnPreserveExceptions","aeFPUs","iFPU","eFPU","offMax","dpl","ext","acc","addrDesc","loadV86","loadReal","checkWriteV86","checkReadV86","checkReadWriteReal","probe","awParms","aCallBreaks","checkReadWriteNone","addCallBreak","SegX86.CALLBREAK_SEL","SegX86.prototype","loadProt","fProbe","SEL","addrDT","addrDTLimit","loadDesc8","ERRCODE","loadIDTReal","loadIDTProt","checkReadProt","checkReadProtDisallowed","checkReadProtDown","checkWriteProt","checkWriteProtDisallowed","checkWriteProtDown","loadDesc","loadDesc6","selMasked","limitOrig","fnCallBreak","rpl","sizeGate","regSP","switchTSS","regPSClear","cplOld","fIDT","selCode","offStack","selStack","cplNew","addrTSS","offSP","TSS386","lenSP","TSS286","nWords","regSSPrev","regSPPrev","typeTSS","selNew","fNest","selOld","addrOld","addrNew","offSS","fLoad","loadIDT","addrType","bType","NULL","CODE","STACK","LDT","VER","X86.fnADCb","X86.fnADCw","X86.fnADDb","X86.fnADDw","X86.fnANDb","X86.fnANDw","X86.fnARPL","X86.fnBOUND","wIndex","wLower","wUpper","X86.fnBSF","X86.fnBSR","X86.fnBT","X86.fnBTC","X86.fnBTR","X86.fnBTS","X86.fnBTMem","X86.fnBT.call","X86.fnBTCMem","X86.fnBTC.call","X86.fnBTRMem","X86.fnBTR.call","X86.fnBTSMem","X86.fnBTS.call","X86.fnCMPb","X86.fnCMPw","X86.fnESC","modReg","fnOp","FPUX86.afnPreserveExceptions.indexOf","X86.fnGRPFault","X86.fnGRPUndefined.call","X86.fnGRPUndefined","X86.opUndefined.call","X86.fnIMUL8","X86.fnIMULrw.call","X86.fnIMULn","X86.fnIMULrd.call","X86.fnIMUL32","fNeg","X86.fnMUL32.call","X86.fnIMULrw","X86.fnIMULrd","X86.fnIMUL32.call","X86.fnLAR","X86.fnLDS","X86.fnLEA","X86.fnLES","X86.fnLFS","setFS","X86.fnLGS","setGS","X86.fnLSL","X86.fnLSS","X86.fnMOV","X86.fnMOVXb","X86.fnMOVXw","X86.fnMOVsrw","X86.fnMOV.call","X86.fnMOVwsr","X86.fnMUL32","srcLo","srcHi","dstLo","dstHi","mul00","mul16","mul32","X86.fnORb","X86.fnORw","X86.fnSBBb","X86.fnSBBw","X86.fnSETO","X86.fnSETC","X86.fnSETNC","X86.fnSETZ","X86.fnSETNZ","X86.fnSETBE","X86.fnSETNBE","X86.fnSETS","X86.fnSETNS","X86.fnSETP","X86.fnSETNP","X86.fnSETL","X86.fnSETNL","X86.fnSETLE","X86.fnSETNLE","X86.fnSHLDwi","X86.helpSHLDw.call","X86.fnSHLDdi","X86.helpSHLDd.call","X86.fnSHLDwCL","X86.fnSHLDdCL","X86.fnSHRDwi","X86.helpSHRDw.call","X86.fnSHRDdi","X86.helpSHRDd.call","X86.fnSHRDwCL","X86.fnSHRDdCL","X86.fnSUBb","X86.fnSUBw","X86.fnTESTb","X86.fnTESTw","X86.fnIBTS","X86.fnXBTS","X86.fnXCHGrb","X86.fnXCHGrw","setEAWord","X86.fnXORb","X86.fnXORw","X86.helpCmp64","r64Dst","r64Src","X86.helpDECreg","X86.helpDIV32","X86.helpINCreg","X86.helpLoadCR0","X86.helpSETcc","fnSet","X86.helpSHLDw","X86.helpSHLDd","X86.helpSHRDw","X86.helpSHRDd","X86.helpSRC1","X86.helpSRCCL","X86.helpSRCByte","X86.helpSRCNone","X86.helpSRCxx","X86.helpCALLF","oldIP","oldSize","X86.helpINT","nError","oldPS","oldCS","X86.helpRETF","newIP","newCS","X86.zeroSeg.call","X86.helpDIVOverflow","MODEL_8086","X86.helpINT.call","X86.helpInterrupt","X86.helpFault","fHalt","fDispatch","Str.toHexByte","X86.helpPageFault","fPresent","X86.zeroSeg","afnGrp","fnSrc","X86.modSIB.call","X86.modSIB","mod","bSIB","scale","index","temp","nReps","setSOByte","getSOByte","X86.opJO","disp","X86.opJNO","X86.opJC","X86.opJNC","X86.opJZ","X86.opJNZ","X86.opJBE","X86.opJNBE","X86.opJS","X86.opJNS","X86.opJP","X86.opJNP","X86.opJL","X86.opJNL","X86.opJLE","X86.opJNLE","X86.opGRP1b","X86.aOpGrp1b","X86.opMOVmb","X86.opMOVmw","X86.opMOVrb","X86.opMOVrw","X86.aOpGrp2b","X86.aOpGrp2w","X86.aOpGrp2d","X86.opRETn","X86.opRET","wLocal","bLevel","wFrame","X86.opRETFn","X86.helpRETF.call","X86.opRETF","X86.opESC","X86.opLOCK","X86.opHLT","getIF","X86.opADDmb","X86.opADDmw","X86.opADDrb","X86.opADDrw","X86.opADDALb","X86.fnADDb.call","X86.opADDAX","X86.fnADDw.call","X86.opPUSHES","X86.opPOPES","X86.opORmb","X86.opORmw","X86.opORrb","X86.opORrw","X86.opORALb","X86.fnORb.call","X86.opORAX","X86.fnORw.call","X86.opPUSHCS","X86.opPOPCS","X86.opADCmb","X86.opADCmw","X86.opADCrb","X86.opADCrw","X86.opADCALb","X86.fnADCb.call","X86.opADCAX","X86.fnADCw.call","X86.opPUSHSS","X86.opPOPSS","X86.opSBBmb","X86.opSBBmw","X86.opSBBrb","X86.opSBBrw","X86.opSBBALb","X86.fnSBBb.call","X86.opSBBAX","X86.fnSBBw.call","X86.opPUSHDS","X86.opPOPDS","X86.opANDmb","X86.opANDmw","X86.opANDrb","X86.opANDrw","X86.opANDAL","X86.fnANDb.call","X86.opANDAX","X86.fnANDw.call","X86.opES","X86.opDAA","AL","AF","CF","X86.opSUBmb","X86.opSUBmw","X86.opSUBrb","X86.opSUBrw","X86.opSUBALb","X86.fnSUBb.call","X86.opSUBAX","X86.fnSUBw.call","X86.opCS","X86.opDAS","X86.opXORmb","X86.opXORmw","X86.opXORrb","X86.opXORrw","X86.opXORALb","X86.fnXORb.call","X86.opXORAX","X86.fnXORw.call","X86.opSS","X86.opAAA","AH","X86.opCMPmb","X86.opCMPmw","X86.opCMPrb","X86.opCMPrw","X86.opCMPALb","X86.fnCMPb.call","X86.opCMPAX","X86.fnCMPw.call","X86.opDS","X86.opAAS","X86.opINCAX","X86.helpINCreg.call","X86.opINCCX","X86.opINCDX","X86.opINCBX","X86.opINCSP","X86.opINCBP","X86.opINCSI","X86.opINCDI","X86.opDECAX","X86.helpDECreg.call","X86.opDECCX","X86.opDECDX","X86.opDECBX","X86.opDECSP","X86.opDECBP","X86.opDECSI","X86.opDECDI","X86.opPUSHAX","X86.opPUSHCX","X86.opPUSHDX","X86.opPUSHBX","X86.opPUSHSP_8086","X86.opPUSHBP","X86.opPUSHSI","X86.opPUSHDI","X86.opPOPAX","X86.opPOPCX","X86.opPOPDX","X86.opPOPBX","X86.opPOPSP","X86.opPOPBP","X86.opPOPSI","X86.opPOPDI","X86.opGRP1w","X86.aOpGrp1w","X86.opGRP1sw","X86.opTESTrb","X86.opTESTrw","X86.opXCHGrb","X86.opXCHGrw","X86.opMOVwsr","X86.opLEA","X86.opMOVsrw","X86.opPOPmw","X86.aOpGrpPOPw","X86.opNOP","X86.opXCHGCX","X86.opXCHGDX","X86.opXCHGBX","X86.opXCHGSP","X86.opXCHGBP","X86.opXCHGSI","X86.opXCHGDI","X86.opCBW","X86.opCWD","X86.opCALLF","X86.helpCALLF.call","X86.opWAIT","X86.opPUSHF","X86.opPOPF","newPS","X86.opSAHF","ah","setPF","clearPF","setSF","clearSF","X86.opLAHF","X86.PS_SAHF","X86.opMOVALm","X86.opMOVAXm","X86.opMOVmAL","X86.opMOVmAX","X86.opMOVSb","nInc","X86.opMOVSw","X86.opCMPSb","bDst","bSrc","X86.opCMPSw","wDst","wSrc","X86.opTESTALb","X86.opTESTAX","X86.opSTOSb","STEPPING_80386_B2","X86.opSTOSw","X86.opLODSb","X86.opLODSw","X86.opSCASb","X86.opSCASw","X86.opMOVALb","X86.opMOVCLb","X86.opMOVDLb","X86.opMOVBLb","X86.opMOVAHb","X86.opMOVCHb","X86.opMOVDHb","X86.opMOVBHb","X86.opMOVAX","X86.opMOVCX","X86.opMOVDX","X86.opMOVBX","X86.opMOVSP","X86.opMOVBP","X86.opMOVSI","X86.opMOVDI","X86.opLES","X86.opLDS","X86.opMOVb","X86.aOpGrpMOVn","X86.opMOVw","X86.opINT3","X86.opINTn","checkIntNotify","messageInt","X86.opINTO","X86.opIRET","newSP","newSS","newES","newDS","newFS","newGS","X86.opGRP2b1","X86.opGRP2w1","X86.opGRP2bCL","X86.opGRP2wCL","X86.opAAM","X86.helpDIVOverflow.call","X86.opAAD","X86.opSALC","X86.opXLAT","X86.opESC0","X86.opESC.call","X86.opESC1","X86.opESC2","X86.opESC3","X86.opESC4","X86.opESC5","X86.opESC6","X86.opESC7","X86.opLOOPNZ","X86.opLOOPZ","X86.opLOOP","X86.opJCXZ","X86.opINb","X86.opINw","X86.opOUTb","X86.opOUTw","X86.opCALL","X86.opJMP","X86.opJMPF","X86.opJMPs","X86.opINDXb","X86.opINDXw","X86.opOUTDXb","X86.opOUTDXw","X86.opREPNZ","X86.opREPZ","X86.opCMC","X86.opGRP3b","X86.aOpGrp3b","X86.opGRP3w","X86.aOpGrp3w","X86.opCLC","X86.opSTC","X86.opCLI","clearIF","X86.opSTI","setIF","X86.opCLD","clearDF","X86.opSTD","setDF","X86.opGRP4b","X86.opGRP4w","X86.fnPOPw","X86.fnMOVn","X86.fnROLb","X86.fnRORb","X86.fnRCLb","X86.fnRCRb","X86.fnSHLb","X86.fnSHRb","X86.fnSARb","X86.fnROLw","X86.fnRORw","X86.fnRCLw","X86.fnRCRw","X86.fnSHLw","X86.fnSHRw","X86.fnSARw","X86.fnROLd","X86.fnRORd","X86.fnRCLd","X86.fnRCRd","X86.fnSHLd","X86.fnSHRd","X86.fnSARd","X86.fnTESTib","X86.fnNOTb","X86.fnNEGb","X86.fnMULb","X86.fnIMULb","X86.fnDIVb","X86.fnIDIVb","div","X86.fnTESTiw","X86.fnNOTw","X86.fnNEGw","X86.fnMULw","X86.fnIMULw","fOverflow","X86.fnDIVw","X86.helpDIV32.call","X86.fnIDIVw","bNegLo","bNegHi","X86.fnINCb","X86.fnDECb","X86.fnINCw","X86.fnDECw","X86.fnCALLw","X86.fnCALLFdw","X86.fnJMPw","X86.fnJMPFdw","X86.fnPUSHw","X86.aOps0F","X86.opGRP6","peekIPByte","X86.opGRP7","X86.aOpGrp7","X86.opLAR","X86.opLSL","X86.opLOADALL286","X86.opCLTS","X86.opLOADALL386","X86.helpLoadCR0.call","accSS","X86.opMOVrc","X86.opMOVrd","X86.opMOVcr","X86.opMOVdr","X86.opMOVrt","X86.opMOVtr","X86.opJOw","X86.opJNOw","X86.opJCw","X86.opJNCw","X86.opJZw","X86.opJNZw","X86.opJBEw","X86.opJNBEw","X86.opJSw","X86.opJNSw","X86.opJPw","X86.opJNPw","X86.opJLw","X86.opJNLw","X86.opJLEw","X86.opJNLEw","X86.opSETO","X86.helpSETcc.call","X86.opSETNO","X86.opSETC","X86.opSETNC","X86.opSETZ","X86.opSETNZ","X86.opSETBE","X86.opSETNBE","X86.opSETS","X86.opSETNS","X86.opSETP","X86.opSETNP","X86.opSETL","X86.opSETNL","X86.opSETLE","X86.opSETNLE","X86.opPUSHFS","X86.opPOPFS","X86.opBT","X86.opSHLDn","X86.opSHLDcl","X86.opPUSHGS","X86.opPOPGS","X86.opBTS","X86.opSHRDn","X86.opSHRDcl","X86.opIMUL","X86.opLSS","X86.opBTR","X86.opLFS","X86.opLGS","X86.opMOVZXb","X86.opMOVZXw","X86.opGRP8","X86.aOpGrp8","X86.opBTC","X86.opBSF","X86.opBSR","X86.opMOVSXb","X86.opMOVSXw","X86.fnSLDT","X86.fnSTR","X86.fnLLDT","X86.fnLTR","X86.fnVERR","X86.fnVERW","X86.fnSGDT","X86.fnSIDT","X86.fnLGDT","X86.fnLIDT","X86.fnSMSW","X86.fnLMSW","ChipSet","parmsChipSet","ChipSet.MODELS","ChipSet.MODEL_5150_OTHER","aDIPSwitches","bSwitches","parseDIPSwitches","ChipSet.CONTROLS.SW1","aFloppyDrives","setDIPSwitches","ChipSet.SWITCH_TYPE.FLOPNUM","ChipSet.SWITCH_TYPE.MONITOR","ChipSet.CONTROLS.SW2","cDMACs","cPICs","sDateRTC","volumeInit","sound","classAudio","contextAudio","fSpeakerEnabled","fSpeakerOn","fUserSound","ChipSet.prototype","ChipSet.SWITCH_TYPE.FPU","volume","ChipSet.TIMER_TICKS_PER_SEC","ChipSet.aPortInput","ChipSet.aPortOutput","ChipSet.MODEL_4860","ChipSet.aPortInput4860","ChipSet.aPortOutput4860","ChipSet.aPortInput5xxx","ChipSet.aPortOutput5xxx","ChipSet.MODEL_ATT_6300","ChipSet.aPortInput6300","ChipSet.aPortOutput6300","ChipSet.aPortInput5150","ChipSet.aPortOutput5150","ChipSet.aPortInput5170","ChipSet.aPortOutput5170","ChipSet.MODEL_COMPAQ_DESKPRO386","ChipSet.aPortInputDeskPro386","ChipSet.aPortOutputDeskPro386","messageDump","onDumpPIC","iPIC","aPICs","pic","sDump","aICW","bIMR","bIRR","bISR","nDelay","onDumpTimer","asArgs","nTimer","updateTimer","countBytes","countCurrent","onDumpCMOS","iCMOS","ChipSet.CMOS.ADDR.TOTAL","ChipSet.CMOS.ADDR.STATUSD","getRTCByte","intBIOSRTC","addDIPSwitches","ChipSet.MODEL_5150","ChipSet.CONTROLS.SWDESC","fHard","updateDIPSwitches","aDMACs","initDMAController","initPIC","ChipSet.PIC0.INDEX","ChipSet.PIC0.PORT_LO","ChipSet.PIC1.INDEX","ChipSet.PIC1.PORT_LO","bPIT1Ctrl","bPIT0Ctrl","initTimer","bPPICtrl","bPPIC","bPPIB","bPPIA","ChipSet.NMI.RESET","bKbdData","b8041Status","b8042Status","ChipSet.C8042.STATUS.NO_INHIBIT","b8042InBuff","b8042CmdData","ChipSet.C8042.DATA.CMD.NO_CLOCK","b8042OutBuff","b8042InPort","ChipSet.C8042.INPORT.MFG_OFF","ChipSet.C8042.INPORT.KBD_UNLOCKED","getDIPMemorySize","ChipSet.C8042.INPORT.ENABLE_256KB","getDIPSwitches","getDIPVideoMonitor","fInit","ChipSet.MONITOR.MONO","ChipSet.C8042.INPORT.MONO","ChipSet.C8042.INPORT.COMPAQ_NO80387","ChipSet.C8042.INPORT.COMPAQ_NOWEITEK","b8042OutPort","ChipSet.C8042.OUTPORT.NO_RESET","ChipSet.C8042.OUTPORT.A20_ON","abDMAPageSpare","bCMOSAddr","initRTCTime","ChipSet.CMOS.ADDR.BASEMEM_LO","ChipSet.CMOS.ADDR.EXTMEM_HI","initCMOSData","ChipSet.CMOS.ADDR.DIAG","ChipSet.CMOS.ADDR.CHKSUM_HI","ChipSet.PPI_SW.MONITOR.SHIFT","SHIFT","ChipSet.PPI_SW.MONITOR.MASK","MASK","ChipSet.PPI_SW.FPU","nDrives","ChipSet.PPI_SW.FDRIVE.SHIFT","ChipSet.PPI_SW.FDRIVE.MASK","ChipSet.PPI_SW.FDRIVE.IPL","IPL","ChipSet.CMOS.ADDR.EQUIP","ChipSet.CMOS.ADDR.FDRIVE","getDIPFloppyDriveType","updateCMOSChecksum","getTime","ChipSet.CMOS.ADDR.RTC_SEC","ChipSet.CMOS.ADDR.RTC_SEC_ALRM","ChipSet.CMOS.ADDR.RTC_MIN","ChipSet.CMOS.ADDR.RTC_MIN_ALRM","ChipSet.CMOS.ADDR.RTC_HOUR","ChipSet.CMOS.ADDR.RTC_HOUR_ALRM","ChipSet.CMOS.ADDR.RTC_WEEK_DAY","ChipSet.CMOS.ADDR.RTC_MONTH_DAY","ChipSet.CMOS.ADDR.RTC_MONTH","nYear","ChipSet.CMOS.ADDR.RTC_YEAR","nCentury","ChipSet.CMOS.ADDR.CENTURY_DATE","ChipSet.CMOS.ADDR.STATUSA","ChipSet.CMOS.STATUSB.HOUR24","ChipSet.CMOS.ADDR.STATUSC","ChipSet.CMOS.STATUSD.VRB","nRTCCyclesLastUpdate","nRTCPeriodsPerSecond","nRTCCyclesPerPeriod","iRTC","f12HourValue","ChipSet.CMOS.STATUSB.BINARY","ChipSet.CMOS.STATUSA.UIP","setRTCCycleLimit","wChecksum","ChipSet.CMOS.ADDR.CHKSUM_LO","iDMAC","saveDMAControllers","iChannel","aChannels","channel","masked","addrInit","countInit","addrCurrent","bPage","sFunction","bStatus","bCmd","bReq","bIndex","bTemp","savePICs","nICW","bIRLow","bOCW3","countLatched","bcd","rw","countIndex","fOUT","fCountLatched","fStatusLatched","setSpeaker","aState","ChipSet.aDMAControllerInit","nChannelBase","initDMAChannel","ChipSet.aDMAChannelInit","initDMAFunction","fnTransfer","ChipSet.aPICInit","nIRQBase","ChipSet.aTimerInit","iDIP","sCellClasses","sCellClass","innerHTML","updateDIPSwitchControls","findDIPSwitch","iSwitch","switchTypes","switchDIPs","ChipSet.DIPSW","iType","switchGroup","VALUES","iDrive","getDIPFloppyDrives","ChipSet.CMOS.FDRIVE.FD360","ChipSet.CMOS.FDRIVE.FD720","ChipSet.CMOS.FDRIVE.FD1200","ChipSet.CMOS.FDRIVE.FD1440","ChipSet.CMOS.FDRIVE.NONE","nKBLowMem","ChipSet.SWITCH_TYPE.LOWMEM","nKBExpMem","ChipSet.SWITCH_TYPE.EXPMEM","sBits","bDefault","setDIPSwitchControl","setAttribute","backgroundColor","updateDIPSwitchDescriptions","aeCells","LABEL","eSwitch","onClickSwitch","asParts","sID","controlDesc","getDIPCoprocessor","asMonitorTypes","inDMAChannelAddr","ChipSet.DMA_REFRESH","outDMAChannelAddr","inDMAChannelCount","outDMAChannelCount","inDMAStatus","ChipSet.DMA_STATUS.CH0_TC","ChipSet.DMA_STATUS.ALL_TC","outDMAReq","outDMAMask","ChipSet.DMA_MASK.CHANNEL","ChipSet.DMA_MASK.CHANNEL_SET","requestDMA","outDMAMode","ChipSet.DMA_MODE.CHANNEL","inDMATemp","outDMAMasterClear","inDMAPageReg","outDMAPageReg","inDMAPageSpare","iSpare","outDMAPageSpare","connectDMA","iDMAChannel","advanceDMA","ChipSet.DMA_MODE.TYPE","fWarning","fError","fAsyncRequest","ChipSet.DMA_MODE.TYPE_WRITE","advanceDMAWrite","addrCur","onTransferDMA","updateDMA","ChipSet.DMA_MODE.TYPE_READ","ChipSet.DMA_MODE.TYPE_VERIFY","ChipSet.DMA_MODE.DECREMENT","ChipSet.DMA_MODE.AUTOINIT","inPICLo","ChipSet.PIC_LO.OCW3_READ_CMD","ChipSet.PIC_LO.OCW3_READ_IRR","ChipSet.PIC_LO.OCW3_READ_ISR","outPICLo","ChipSet.PIC_LO.ICW1","ChipSet.PIC_LO.OCW3","ChipSet.PIC_LO.OCW3_POLL_CMD","ChipSet.PIC_LO.OCW3_SMM_CMD","bOCW2","ChipSet.PIC_LO.OCW2_OP_MASK","ChipSet.PIC_LO.OCW2_EOI","bIREnd","ChipSet.PIC_LO.OCW2_EOI_SPEC","nIRL","ChipSet.PIC_LO.OCW2_IR_LVL","bIR","checkIRR","ChipSet.PIC_LO.OCW2_SET_ROTAUTO","ChipSet.PIC_LO.OCW2_SET_PRI","inPICHi","outPICHi","ChipSet.PIC_LO.ICW1_SNGL","ChipSet.PIC_LO.ICW1_ICW4","nIRQ","messageBitsIRQ","ChipSet.IRQ.SLAVE","bIRNext","inTimer","iPIT","iPITTimer","iBaseTimer","resetTimerIndex","outTimer","ChipSet.PIT_CTRL.MODE0","ChipSet.PIT_CTRL.MODE4","ChipSet.PIT0.INDEX","ChipSet.PIT0.TIMER0","ChipSet.IRQ.TIMER0","getTimerInit","ChipSet.PIT0.TIMER2","inTimerCtrl","outTimerCtrl","ChipSet.PIT_CTRL.SC","ChipSet.PIT_CTRL.SC_BACK","ChipSet.PIT_CTRL.RB_STATUS","ChipSet.PIT_CTRL.RB_CTR0","latchTimerStatus","ChipSet.PIT_CTRL.RB_NULL","ChipSet.PIT_CTRL.RB_OUT","ChipSet.PIT_CTRL.RB_COUNTS","latchTimerCount","ChipSet.PIT_CTRL.SC_SHIFT","ChipSet.PIT_CTRL.BCD","ChipSet.PIT_CTRL.MODE","ChipSet.PIT_CTRL.RW","ChipSet.PIT_CTRL.RW_LATCH","setTimerMode","ChipSet.PPI_B.CLK_TIMER2","ChipSet.PPI_B.ENABLE_SW2","ChipSet.PPI_B.CASS_MOTOR_OFF","ChipSet.PPI_B.CLK_KBD","ChipSet.PIT_CTRL.RW_MSB","ChipSet.PIT_CTRL.RW_BOTH","fCycleReset","ChipSet.PIT_CTRL.MODE2","nCyclesPerSecond","updateRTCTime","ChipSet.CMOS.STATUSC.PF","ChipSet.CMOS.STATUSC.IRQF","ChipSet.IRQ.RTC","ChipSet.CMOS.STATUSC.AF","ChipSet.CMOS.STATUSB.AIE","nCyclesDelta","nSecondsDelta","ChipSet.CMOS.STATUSB.SET","nDays","nMonth","nDayMax","ChipSet.CMOS.STATUSC.UF","ChipSet.CMOS.STATUSB.UIE","outMFGTest","inPPIA","ChipSet.PPI_CTRL.A_IN","ChipSet.PPI_B.CLEAR_KBD","outPPIA","inPPIB","outPPIB","updatePPIB","fNewSpeaker","ChipSet.PPI_B.SPK_TIMER2","fOldSpeaker","setEnabled","inPPIC","ChipSet.NMI.KBD_LATCH","ChipSet.PPI_C.NO_MODEM","ChipSet.PPI_C.NO_DISKETTE","ChipSet.PPI_C.NO_MEMEXP","ChipSet.PPI_C.KBD_DATA","ChipSet.PPI_C.SW","ChipSet.PPI_B.ENABLE_SW_HI","ChipSet.PPI_C.TIMER2_OUT","ChipSet.PPI_C.CASS_DATA_IN","outPPIC","inPPICtrl","outPPICtrl","in8041Kbd","ChipSet.C8042.STATUS.OUTBUFF_FULL","out8041Kbd","in8041Ctrl","out8041Ctrl","in8041Status","in8042OutBuff","ChipSet.C8042.STATUS.OUTBUFF_DELAY","checkBuffer","out8042InBuffData","ChipSet.C8042.STATUS.CMD_FLAG","ChipSet.C8042.CMD.WRITE_CMD","set8042CmdData","ChipSet.C8042.CMD.WRITE_OUTPORT","set8042OutPort","bCmdPending","Keyboard.CMD.RESET","Keyboard.CMDRES.ACK","resetDevice","Keyboard.CMD.SET_RATE","setResponse","Keyboard.CMD.SET_LEDS","set8042OutBuff","in8042RWReg","ChipSet.C8042.RWREG.NMI_ERROR","ChipSet.C8042.RWREG.REFRESH_BIT","out8042RWReg","in8042Status","out8042InBuffCmd","bPulseBits","ChipSet.C8042.CMD.PULSE_OUTPORT","ChipSet.C8042.CMD.READ_CMD","ChipSet.C8042.CMD.DISABLE_KBD","ChipSet.C8042.CMD.ENABLE_KBD","ChipSet.C8042.CMD.SELF_TEST","abBuffer","ChipSet.C8042.DATA.SELF_TEST.OK","ChipSet.C8042.CMD.INTF_TEST","ChipSet.C8042.DATA.INTF_TEST.OK","ChipSet.C8042.CMD.READ_INPORT","ChipSet.C8042.CMD.READ_OUTPORT","ChipSet.C8042.CMD.READ_TEST","ChipSet.C8042.TESTPORT.KBD_CLOCK","ChipSet.C8042.STATUS.SYS_FLAG","ChipSet.C8042.DATA.CMD.SYS_FLAG","ChipSet.C8042.DATA.CMD.NO_INHIBIT","fNoDelay","receiveKbdData","ChipSet.IRQ.KBD","in6300DIPSwitches","inCMOSAddr","outCMOSAddr","ChipSet.CMOS.ADDR.NMI_DISABLE","inCMOSData","bAddr","ChipSet.CMOS.ADDR.MASK","ChipSet.CMOS.STATUSC.RESERVED","outCMOSData","bDelta","fBCD","inNMI","outNMI","outFPUClear","outFPUReset","onBIOSRTCReturn","nLevel","CL","CH","DL","DH","sResult","fOn","freq","startAudio","oscillatorAudio","volumeAudio","ChipSet.IRQ.COM1","ChipSet.IRQ.COM2","ChipSet.IRQ.XTC","ChipSet.IRQ.FDC","ChipSet.IRQ.ATC","ChipSet.MODEL_5160","ChipSet.MODEL_CDP_MPC1600","ChipSet.MODEL_ZENITH_Z150","ChipSet.MODEL_COMPAQ_PORTABLE","SW1","SW2","SWDESC","MONO","CH0_TC","ALL_TC","CHANNEL","CHANNEL_SET","TYPE","TYPE_VERIFY","TYPE_WRITE","TYPE_READ","AUTOINIT","DECREMENT","INDEX","PORT_LO","ICW1","ICW1_ICW4","ICW1_SNGL","OCW2_IR_LVL","OCW2_OP_MASK","OCW2_EOI","OCW2_EOI_SPEC","OCW2_SET_ROTAUTO","OCW2_SET_PRI","OCW3","OCW3_READ_IRR","OCW3_READ_ISR","OCW3_READ_CMD","OCW3_POLL_CMD","OCW3_SMM_CMD","TIMER0","SLAVE","COM2","COM1","XTC","ATC","TIMER2","BCD","MODE","MODE0","MODE2","MODE3","MODE4","RW","RW_LATCH","RW_MSB","RW_BOTH","SC","SC_BACK","SC_SHIFT","RB_CTR0","RB_STATUS","RB_COUNTS","RB_NULL","RB_OUT","CLK_TIMER2","SPK_TIMER2","ENABLE_SW2","CASS_MOTOR_OFF","ENABLE_SW_HI","CLK_KBD","CLEAR_KBD","NO_MODEM","NO_DISKETTE","NO_MEMEXP","SW","CASS_DATA_IN","TIMER2_OUT","KBD_DATA","A_IN","FDRIVE","ONE","TWO","THREE","FOUR","MONITOR","TV","FLOPNUM","LOWMEM","EXPMEM","FLOPTYPE","SYS_FLAG","NO_INHIBIT","NO_CLOCK","OK","COMPAQ_NO80387","INPORT","COMPAQ_NOWEITEK","ENABLE_256KB","MFG_OFF","KBD_UNLOCKED","NO_RESET","OUTPORT","A20_ON","KBD_CLOCK","TESTPORT","REFRESH_BIT","RWREG","NMI_ERROR","READ_CMD","CMD","WRITE_CMD","SELF_TEST","INTF_TEST","DISABLE_KBD","ENABLE_KBD","READ_INPORT","READ_OUTPORT","WRITE_OUTPORT","READ_TEST","PULSE_OUTPORT","OUTBUFF_FULL","STATUS","CMD_FLAG","OUTBUFF_DELAY","RTC_SEC","ADDR","RTC_SEC_ALRM","RTC_MIN","RTC_MIN_ALRM","RTC_HOUR","RTC_HOUR_ALRM","RTC_WEEK_DAY","RTC_MONTH_DAY","RTC_MONTH","RTC_YEAR","STATUSA","STATUSB","STATUSC","STATUSD","DIAG","EQUIP","BASEMEM_LO","EXTMEM_HI","CHKSUM_HI","CHKSUM_LO","CENTURY_DATE","TOTAL","NMI_DISABLE","UIP","SET","PIE","AIE","UIE","BINARY","HOUR24","IRQF","PF","UF","RESERVED","VRB","FD360","FD1200","FD720","FD1440","ENABLE","KBD_LATCH","RESET","32","33","64","65","TIMER1","66","67","0","1","2","3","4","5","6","7","8","13","129","130","131","135","128","132","133","134","136","137","138","139","140","141","142","143","160","161","192","194","196","198","200","202","204","206","208","218","102","103","72","TIMER3","73","TIMER4","74","TIMER5","75","outDMACmd","9","10","11","12","outDMAResetFF","210","212","214","216","aeChipSet","iChip","eChipSet","ROMX86","parmsROM","abROM","addrROM","sizeROM","addrAlias","idNotify","aNotifyParms","sFileURL","sFilePath","sFileExt","Str.getExtension","Str.getBaseName","FORMAT","Web.getHost","rom","sProgress","Web.getResource","doneROMLoad","sResponse","doneLoad","aSymbols","addSymbols","sROMData","Component.addMachineResource","ib","asHexData","sHexData","copyROM","addROM","aliases","cloneROM","nCard","Video.CARD.EGA","setFontData","Video.CARD.VGA","aeROM","iROM","eROM","RAM","parmsRAM","addrRAM","sizeRAM","fTestRAM","fInstalled","fAllocated","RAM.prototype","baseRAM","CompaqController","CompaqController.ADDR","CTRL","RESET_FLAG","wKb","ram","wMappings","CompaqController.MAPPINGS.DEFAULT","wSettings","CompaqController.SETTINGS.DEFAULT","wRAMSetup","CompaqController.RAMSETUP.DEFAULT","aBlocksDst","CompaqController.MAPPINGS.UNMAPPED","CompaqController.MAP_DST","CompaqController.MAP_SIZE","CompaqController.MAP_SRC","CompaqController.MAPPINGS.READWRITE","CompaqController.ACCESS","CompaqController.BUFFER","UNMAPPED","READWRITE","DEFAULT","aeRAM","iRAM","eRAM","Keyboard","parmsKbd","setModel","fMobile","Web.isMobile","fMSWindows","cSoftCodes","fSoftKeyboard","controlTextKeyboard","controlSoftKeyboard","fToggleCapsLock","fEscapeDisabled","aKeysActive","msAutoRelease","msInjectDefault","cKeysPressed","msInjectDelay","softCodeKeys","keys","Keyboard.SOFTCODES","autoType","fDOSReady","fnDOSReady","fnInjectReady","nInjection","Keyboard.INJECTION.ON_INPUT","injectKeys","waitReady","Keyboard.prototype","parentElement","nextElementSibling","enableSoftKeyboard","display","controlSoftKeyboard.ontouchstart","preventDefault","onkeydown","controlText.onkeydown","onKeyChange","onkeypress","controlText.onkeypress","keyCode","which","notifyKbdEvent","sInjectBuffer","fPass","Keyboard.SIMCODES","bitsState","Keyboard.STATE.CMD","Keyboard.STATE.ALTS","Keyboard.SIMCODE.ALT","addActiveKey","onkeyup","controlText.onkeyup","Keyboard.SIMCODE.CAPS_LOCK","Keyboard.SIMCODE.NUM_LOCK","Keyboard.SIMCODE.SCROLL_LOCK","sCode","Keyboard.CLICKCODES","simCode","onKeyboardBindingClick","updateShiftState","msLastEvent","nClickState","fStateKey","Keyboard.KEYSTATES","Keyboard.STATE.ALL_MODIFIERS","fnDown","onKeyboardBindingDown","timeStamp","msDoubleClick","fnUp","onKeyboardBindingUp","removeActiveKey","findBinding","code","Keyboard.SIMCODE.CTRL_PAUSE","Keyboard.SIMCODE.CTRL_BREAK","Keyboard.SIMCODE.CTRL_ALT_DEL","Keyboard.SIMCODE.DEL","Keyboard.SIMCODE.CTRL_ALT_INS","Keyboard.SIMCODE.INS","Keyboard.SIMCODE.CTRL_ALT_ADD","Keyboard.SIMCODE.NUM_ADD","Keyboard.SIMCODE.CTRL_ALT_SUB","Keyboard.SIMCODE.NUM_SUB","Keys.ASCII.a","Keys.ASCII.z","Keys.ASCII.A","timerInject","injectKeysTimer","timerTransmit","transmitDataTimer","transmitData","softKeys","intDOS","injectInit","Keyboard.INJECTION.ON_START","Keyboard.CMDRES.BAT_OK","sModel","iModel","Keyboard.MODELS.indexOf","Keyboard.MODELS","modelKeys","msTransmit","fData","fClock","fResetOnEnable","unshift","initState","saveState","sStatePath","Keyboard.INJECTION.NONE","bitsStateSim","readOnly","nCondition","sKeys","reSpecial","Usr.formatDate","digits","shortName","charCode","charCodeAt","Keys.ASCII.CTRL_Z","Keys.ASCII.CTRL_I","Keys.ASCII.CTRL_J","Keys.ASCII.CTRL_M","fPress","Keyboard.MODIFIERS","clearActiveKeys","sOption","fSim","fRight","bitState","Keyboard.STATE.ALL_RIGHT","Keyboard.STATE.ALL_LOCKS","Keyboard.LEDSTATES","bitLED","updateLEDs","nRepeat","key","updateActiveKey","fModifiers","fFlush","fRemoved","keySimulate","msTimer","msAutoRepeat","msNextRepeat","onUpdateActiveKey","getSimCode","fShifted","Keys.ASCII.Z","Keyboard.STATE.SHIFT","Keyboard.STATE.RSHIFT","Keyboard.STATE.CAPS_LOCK","onFocusChange","fFocus","fIgnore","Component.processScript","nShiftState","LOCATION","Keyboard.STATE.CTRL","Keyboard.STATE.ALT","Keyboard.STATE.RALT","Keyboard.STATE.CTRLS","Keyboard.STATE.CMDS","fSimulated","wCode","abScanCodes","bCode","Keyboard.SCANCODE.BREAK","fAlpha","bShift","bScan","Keyboard.SCANCODE.EXTEND1","Keyboard.SCANCODE.EXTEND2","Keyboard.SCANCODE.SHIFT","Keyboard.SCANCODE.CTRL","Keyboard.STATE.RCTRL","Keyboard.SCANCODE.ALT","addScanCode","Keyboard.LIMIT.MAX_SCANCODES","COMPAQ_KEYCLICK","Keyboard.CMDRES.BUFF_FULL","ALT","CAPS_LOCK","NUM_LOCK","SCROLL_LOCK","NUM_ADD","NUM_SUB","INS","Keys.ASCII.CTRL_A","Keys.ASCII.CTRL_B","Keys.ASCII.CTRL_C","Keys.ASCII.CTRL_D","Keys.ASCII.CTRL_E","Keys.ASCII.CTRL_F","Keys.ASCII.CTRL_G","Keys.ASCII.CTRL_H","Keys.ASCII.CTRL_K","Keys.ASCII.CTRL_L","Keys.ASCII.CTRL_N","Keys.ASCII.CTRL_O","Keys.ASCII.CTRL_P","Keys.ASCII.CTRL_Q","Keys.ASCII.CTRL_R","Keys.ASCII.CTRL_S","Keys.ASCII.CTRL_T","Keys.ASCII.CTRL_U","Keys.ASCII.CTRL_V","Keys.ASCII.CTRL_W","Keys.ASCII.CTRL_X","Keys.ASCII.CTRL_Y","CTRL_PAUSE","CTRL_BREAK","CTRL_ALT_DEL","CTRL_ALT_INS","CTRL_ALT_ADD","CTRL_ALT_SUB","EXTEND1","EXTEND2","RSHIFT","RCTRL","CTRLS","RALT","ALTS","CMDS","ALL_RIGHT","ALL_MODIFIERS","ALL_LOCKS","RCMD","FF_CMD","TAB","F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","LEFT","UP","RIGHT","DOWN","HOME","END","PGUP","PGDN","SYS_REQ","Keyboard.SIMCODE.CTRL_C","CTRL_ALT_ENTER","BS","Keys.ASCII.q","Keys.ASCII.w","Keys.ASCII.e","Keys.ASCII.r","Keys.ASCII.t","Keys.ASCII.y","Keys.ASCII.u","Keys.ASCII.i","Keys.ASCII.o","Keys.ASCII.p","Keys.ASCII.s","Keys.ASCII.d","Keys.ASCII.f","Keys.ASCII.g","Keys.ASCII.h","Keys.ASCII.j","Keys.ASCII.k","Keys.ASCII.l","Keys.ASCII.x","Keys.ASCII.c","Keys.ASCII.v","Keys.ASCII.b","Keys.ASCII.n","Keys.ASCII.m","PRTSC","SPACE","NUM_CENTER","FIVE","SIX","SEVEN","EIGHT","NINE","ZERO","DASH","EQUALS","Keys.ASCII.Q","Keys.ASCII.W","Keys.ASCII.E","Keys.ASCII.R","Keys.ASCII.T","Keys.ASCII.Y","Keys.ASCII.U","Keys.ASCII.I","Keys.ASCII.O","Keys.ASCII.P","LBRACK","RBRACK","ENTER","Keys.ASCII.S","Keys.ASCII.D","Keys.ASCII.F","Keys.ASCII.G","Keys.ASCII.H","Keys.ASCII.J","Keys.ASCII.K","Keys.ASCII.L","SEMI","QUOTE","BQUOTE","BSLASH","Keys.ASCII.X","Keys.ASCII.C","Keys.ASCII.V","Keys.ASCII.B","Keys.ASCII.N","Keys.ASCII.M","COMMA","PERIOD","SLASH","NUM_HOME","NUM_UP","NUM_PGUP","NUM_LEFT","NUM_RIGHT","NUM_END","NUM_DOWN","NUM_PGDN","NUM_INS","NUM_DEL","F11","F12","WIN","MENU","Keyboard.SIMCODE.CTRL_A","Keyboard.SIMCODE.CTRL_B","Keyboard.SIMCODE.CTRL_D","Keyboard.SIMCODE.CTRL_E","Keyboard.SIMCODE.CTRL_F","Keyboard.SIMCODE.CTRL_G","Keyboard.SIMCODE.CTRL_H","Keyboard.SIMCODE.CTRL_I","Keyboard.SIMCODE.CTRL_J","Keyboard.SIMCODE.CTRL_K","Keyboard.SIMCODE.CTRL_L","Keyboard.SIMCODE.CTRL_M","Keyboard.SIMCODE.CTRL_N","Keyboard.SIMCODE.CTRL_O","Keyboard.SIMCODE.CTRL_P","Keyboard.SIMCODE.CTRL_Q","Keyboard.SIMCODE.CTRL_R","Keyboard.SIMCODE.CTRL_S","Keyboard.SIMCODE.CTRL_T","Keyboard.SIMCODE.CTRL_U","Keyboard.SIMCODE.CTRL_V","Keyboard.SIMCODE.CTRL_W","Keyboard.SIMCODE.CTRL_X","Keyboard.SIMCODE.CTRL_Y","Keyboard.SIMCODE.CTRL_Z","SET_RATE","SET_LEDS","BAT_OK","ACK","BUFF_FULL","MAX_SCANCODES","ON_START","ON_INPUT","aeKbd","iKbd","eKbd","Card","video","cbMemory","specs","Video.cardSpecs","nMonitorType","Card.CRTC.TOTAL_REGS","Card.CRTC.EGA.TOTAL_REGS","addrBuffer","sizeBuffer","fActive","regMode","regColor","regCRTIndx","regCRTPrev","regCRTData","nCRTCRegs","asCRTCRegs","Card.CRTC.REGS","offStartAddr","Card.CRTC.STARTLO","Card.CRTC.STARTHI","addrMaskHigh","Card.CRTC.EGA_REGS","Card.ATC.TOTAL_REGS","Card.MISC.IO_SELECT","Card.SEQ.TOTAL_REGS","Card.GRC.TOTAL_REGS","initEGA","Card.ACCESS.READ.MODE0","Card.ACCESS.READ.EVENODD","Card.ACCESS.WRITE.MODE0","Card.ACCESS.WRITE.EVENODD","Card.ACCESS.V2","Card.VGA_ENABLE.ENABLED","Card.DAC.MASK.DEFAULT","Card.DAC.STATE.MODE_WRITE","Card.DAC.TOTAL_REGS","fATCData","regATCIndx","regATCData","asATCRegs","Card.ATC.REGS","regStatus0","regMisc","regFeat","regSEQIndx","regSEQData","asSEQRegs","Card.SEQ.REGS","regGRCPos1","regGRCPos2","regGRCIndx","regGRCData","asGRCRegs","Card.GRC.REGS","latches","cdw","adwMemory","nAccess","Card.ACCESS.V1","nReadMapShift","nSeqMapMask","nDataRotate","nBitMapMask","nSetMapData","nSetMapMask","nSetMapBits","nColorCompare","nColorDontCare","nVertPeriods","nVertPeriodsStartAddr","regVGAEnable","regDACMask","regDACAddr","regDACShift","regDACState","regDACData","monitorSpecs","Video.monitorSpecs","nCyclesHorzPeriod","nHorzPeriodsPerSec","nCyclesHorzActive","percentHorzActive","nCyclesVertPeriod","nHorzPeriodsPerFrame","nCyclesVertActive","percentVertActive","nInitCycles","saveCard","saveEGA","dumpRegs","aRegs","asRegs","getCRTCReg","Str.pad","cchMax","afnAccess","nReadAccess","Card.ACCESS.READ.MASK","fnReadByte","Card.ACCESS.afn","nWriteAccess","Card.ACCESS.WRITE.MASK","fnWriteByte","bOverflowBit8","bOverflowBit9","bMaxScanBit9","Card.CRTC.EGA.VTOTAL","Card.CRTC.EGA.OVERFLOW.VTOTAL_BIT8","Card.CRTC.EGA.OVERFLOW.VTOTAL_BIT9","Card.CRTC.EGA.CURSCAN","Card.CRTC.EGA.OVERFLOW.CURSCAN_BIT8","Card.CRTC.EGA.VRSTART","Card.CRTC.EGA.OVERFLOW.VRSTART_BIT8","Card.CRTC.EGA.OVERFLOW.VRSTART_BIT9","Card.CRTC.EGA.VDEND","Card.CRTC.EGA.OVERFLOW.VDEND_BIT8","Card.CRTC.EGA.OVERFLOW.VDEND_BIT9","Card.CRTC.EGA.VBSTART","Card.CRTC.EGA.OVERFLOW.VBSTART_BIT8","Card.CRTC.EGA.MAXSCAN.VBSTART_BIT9","Card.CRTC.EGA.LINECOMP","Card.CRTC.EGA.OVERFLOW.LINECOMP_BIT8","Card.CRTC.EGA.MAXSCAN.LINECOMP_BIT9","Card.CRTC.EGA.OVERFLOW.INDX","Card.CRTC.EGA.MAXSCAN.INDX","STARTHI","STARTLO","TOTAL_REGS","VTOTAL","EGA","INDX","VTOTAL_BIT8","VDEND_BIT8","VRSTART_BIT8","VBSTART_BIT8","LINECOMP_BIT8","CURSCAN_BIT8","VTOTAL_BIT9","VDEND_BIT9","VRSTART_BIT9","VBSTART_BIT9","LINECOMP_BIT9","CURSCAN","VRSTART","VDEND","VBSTART","LINECOMP","Card.CRTCMASKS","HTOTAL","HDISP","HSPOS","HSWIDTH","VTOTADJ","VDISP","VSPOS","ILMODE","MAXSCAN","CURSCANB","CURSORHI","CURSORLO","PENHI","PENLO","IO_SELECT","ENABLED","MODE_WRITE","STATE","READ","EVENODD","WRITE","V2","Card.ACCESS.readByteMode0","Card.ACCESS.readByteMode0Chain4","Card.ACCESS.readByteMode0EvenOdd","Card.ACCESS.readByteMode1","Card.ACCESS.writeByteMode0","Card.ACCESS.writeByteMode0Rot","Card.ACCESS.writeByteMode0And","Card.ACCESS.writeByteMode0Or","Card.ACCESS.writeByteMode0Xor","Card.ACCESS.writeByteMode0Chain4","Card.ACCESS.writeByteMode0EvenOdd","maskMaps","Card.ACCESS.writeByteMode1","Card.ACCESS.writeByteMode1EvenOdd","Card.ACCESS.writeByteMode2","Video.aEGAByteToDW","Card.ACCESS.writeByteMode2And","Card.ACCESS.writeByteMode2Or","Card.ACCESS.writeByteMode2Xor","Card.ACCESS.writeByteMode3","dwMask","Video","parmsVideo","textarea","container","fGecko","aModelDefaults","Video.MODEL","sSwitches","nRandomize","nModeDefault","Video.aModeParms","nColsDefault","nRowsDefault","cxScreen","cyScreen","canvasScreen","contextScreen","inputScreen","inputTextArea","colorScreen","opacityFlicker","fOpacityReduced","fSmoothing","sSmoothing","Web.findProperty","sTouchScreen","nTouchConfig","Video.TOUCH.NONE","mouse","fAutoLock","aFonts","aRGB","fRGBValid","doFullScreen","sFullScreen","addEventListener","onFullScreenChange","notifyFullScreen","onFullScreenError","onfocus","lockPointer","this.inputScreen.onfocus","onblur","this.inputScreen.onblur","unlockPointer","sPointerLock","onPointerLockChange","notifyPointerLocked","fLocked","Video.prototype","aModel","Video.CARD.CGA","Video.aMDAPortInput","Video.aMDAPortOutput","Video.CARD.MDA","Video.aCGAPortInput","Video.aCGAPortOutput","Video.aEGAPortInput","Video.aEGAPortOutput","Video.aVGAPortInput","Video.aVGAPortOutput","onDumpVideo","cardActive","fColAdjust","prevDump","Str.toBin","nMode","bEGASwitches","captureTouch","Video.TOUCH.MOUSE","Video.TOUCH.KEYGRID","Video.TOUCH.DEFAULT","updateScreenTimer","updateScreen","Video.UPDATES_PER_SECOND","sWidth","screen","height","aspectPhys","aspectVirt","margin","sHeight","focus","sLockMessage","fFullScreen","fLock","setFocus","addPassive","opts","defineProperty","get","removeEventListener","onTouchStart","processTouchEvent","passive","onTouchMove","onTouchEnd","xTouch","yTouch","timeTouch","fTouchDefault","hLongTouch","fLongTouch","onLongTouch","this.onLongTouch","Mouse.BUTTON.LEFT","fStart","xTouchOffset","yTouchOffset","eCurrent","offsetLeft","offsetTop","offsetParent","targetTouches","pageX","pageY","Video.KEYGRID","timeDelta","endLongTouch","xDelta","yDelta","Video.MODE.CGA_80X25","VGACOLOR","aMonitors","Video.aEGAMonitorSwitches","EGACOLOR","Video.MODE.MDA_80X25","cardMono","cardMDA","cardColor","cardCGA","cardEGA","enableEGA","buildFonts","setMode","addrScreenLimit","cbScreen","addrScreen","dataRandom","random","bChar","bAttr","Video.ATTRS.BGND_BLINK","Video.ATTRS.FGND_WHITE","Video.ATTRS.BGND_BLACK","Video.ATTRS.FGND_BLACK","Video.ATTRS.BGND_WHITE","Video.ATTRS.FGND_BRIGHT","checkMode","checkCursor","sFontData","abFontData","getCardColors","nBitsPerPixel","Video.aCGAColors","bBackground","PALETTE","aColorSet","Video.aCGAColorSet2","Video.aCGAColorSet1","iColor","card","aDAC","bRed","bGreen","bBlue","fDAC","Video.aEGAPalDef","COLORSEL","aFontOffsets","cxFontChar","fRebuild","fChanges","nFont","offSplit","cxChar","aRGBColors","buildFont","Video.FONT.CGA","Video.FONT.MDA","Video.aMDAColors","Video.aMDAColorMap","iCellCursor","cBlinks","cBlinkVisible","offData","cyChar","aColorMap","createFont","nColors","cxCell","nDouble","cyCell","aCSSColors","aCanvas","rgbColor","rgbColorOrig","iChar","rgbOff","canvasFont","contextFont","getContext","cyLimit","imageChar","createImageData","fUnderline","offChar","nRowDoubler","xDst","yDst","rgb","setPixel","putImageData","checkBlink","bCursorFlags","bCursorStart","CURSCAN_SLMASK","bCursorEnd","bCursorMax","oCursorStart","oCursorEnd","CURSCAN_BLINKOFF","bCursorWrap","bCursorSize","removeCursor","yCursor","cyCursor","cyCursorWrap","cyCursorCell","aCellCache","drawCursor","Video.ATTRS.DRAW_CURSOR","col","row","contextBuffer","updateChar","getCardAccess","fColor256","regGRCMode","regDataRotate","DATAROT","regSEQMode","MEMMODE","setCardAccess","cbBuffer","cbBufferText","regGRCMisc","MISC","Video.MODE.UNKNOWN","Video.MODE.EGA_640X350_MONO","Video.MODE.EGA_640X350","Video.MODE.CGA_80X25_BW","fTextGraphicsHybrid","nCRTCVertTotal","nCRTCMaxScan","nCRTCModeCtrl","fSEQDotClock","CLOCKING","Video.MODE.VGA_320X200","Video.MODE.VGA_320X240","Video.MODE.VGA_320X400","Video.MODE.EGA_320X200","Video.MODE.EGA_640X200","Video.MODE.VGA_640X480_MONO","Video.MODE.VGA_640X480","Video.MODE.CGA_640X200","Video.MODE.CGA_320X200_BW","Video.MODE.CGA_40X25","opacity","cUpdates","setDimensions","nRows","nColsLogical","nCellsPerWord","cbPadding","modeParms","nCells","nCellCache","cbSplit","cxScreenCell","cyScreenCell","cxBuffer","cyBuffer","imageBuffer","canvasBuffer","xScreenOffset","yScreenOffset","cxScreenOffset","cyScreenOffset","cxBorder","cyBorder","invalidateCache","imageData","initCache","fCellCacheValid","fModified","iFgnd","iBgnd","Video.ATTRS.DRAW_FGND","xSrcFgnd","ySrcFgnd","fEnabled","INDX_PAL_ENABLE","fBlinkUpdate","getRetraceBits","cbScreenWrap","addrScreenWrap","cBlinkOrig","cCells","updateScreenCells","iCell","cBlinkNew","dataBlink","cUpdated","dataDraw","dataMask","fBlinkEnable","updateScreenText","nPixelsPerCell","wPixelMask","nPixelShift","aPixelColors","xDirty","xMaxDirty","yDirty","yMaxDirty","wPixels","wMask","iPixel","bPixel","cbInc","iPixelFirst","HPAN","nRowAdjust","nPixels","Video.aEGADWToByte","nElapsedCycles","inMDAIndx","inCRTCIndx","outMDAIndx","CRTC","outCRTCIndx","inMDAData","inCRTCData","outMDAData","outCRTCData","inMDAMode","inCardMode","outMDAMode","outCardMode","inMDAStatus","inCardStatus","outFeat","BITS","inATCIndx","Video_prototype$inATCData","inATCData","INDX_MASK","outATC","fPalEnabled","PALETTE_REGS","Video.TRAPALL","inStatus0","bSWBit","iBit","CLOCK_SELECT","SWSENSE_SHIFT","dwDAC","SWSENSE","outMisc","PORT_WRITE","inVGAEnable","outVGAEnable","inSEQIndx","outSEQIndx","inSEQData","outSEQData","MAPMASK","inDACMask","outDACMask","inDACState","outDACRead","outDACWrite","inDACData","outDACData","dwNew","inVGAFeat","PORT_READ","outGRCPos2","POS2_PORT","inVGAMisc","outGRCPos1","POS1_PORT","inGRCIndx","outGRCIndx","inGRCData","outGRCData","SRESET","ESRESET","COLORCMP","READMAP","COLORDC","BITMASK","inCGAIndx","outCGAIndx","inCGAData","outCGAData","inCGAMode","outCGAMode","inCGAColor","outCGAColor","inCGAStatus","bCur","bMax","DIAGNOSTIC","CGA_40X25","CGA_80X25_BW","CGA_80X25","CGA_320X200_BW","CGA_640X200","MDA_80X25","EGA_320X200","EGA_640X200","EGA_640X350_MONO","EGA_640X350","VGA_640X480_MONO","VGA_640X480","VGA_320X200","VGA_320X240","VGA_320X400","UNKNOWN","MDA","CGA","VGA","EGAEMULATION","CGA_320X200","CGA_40X25_BW","Video.ATTRS.FGND_GREEN","Video.ATTRS.FGND_RED","Video.ATTRS.FGND_BROWN","Video.ATTRS.FGND_CYAN","Video.ATTRS.FGND_MAGENTA","KEYGRID","aElement","iVideo","onresize","eParent","eChild","cy","onResizeVideo","clientWidth","aspect","aspectRatio","onResizeWindow","fontSize","ParallelPort","parmsParallel","iAdapter","portBase","LPT1","LPT2","controlBuffer","consoleBuffer","Component.bindExternalControl","ParallelPort.prototype","ParallelPort.aPortInput","ParallelPort.aPortOutput","saveRegisters","bData","bControl","ParallelPort.STATUS.NERR","inData","inStatus","ParallelPort.STATUS.NACK","ParallelPort.STATUS.NBUSY","updateIRR","inControl","outData","parallel","fTransmitted","Str.toASCIICode","outControl","ParallelPort.CONTROL.IRQ_ENABLE","NERR","NACK","NBUSY","IRQ_ENABLE","aeParallel","iParallel","eParallel","SerialPort","tabSize","charBOL","iLogicalCol","charPrev","bMSRInit","SerialPort.MSR.CTS","SerialPort.MSR.DSR","fNullModem","connection","sendData","fAutoFlow","bindConnection","initConnection","receiveData","receiveStatus","SerialPort.prototype","bindMouse","fnUpdate","serial","this.controlBuffer.onkeydown","ctrlKey","this.controlBuffer.onkeypress","removeAttribute","timerReceiveNext","receiveDataTimer","timerTransmitNext","bLSR","SerialPort.LSR.THRE","SerialPort.LSR.TSRE","updateIIR","SerialPort.aPortInput","SerialPort.aPortOutput","sConnection","sSourceID","Str.trim","sTargetID","fnConnect","bRBR","bTHR","wDL","bIER","bIIR","bLCR","bMCR","bMSR","abReceive","SerialPort.DL_DEFAULT","SerialPort.IIR.NO_INT","advanceRBR","SerialPort_prototype$receiveStatus","pins","bMSROld","CTS","SerialPort.MSR.DCTS","DSR","SerialPort.MSR.DDSR","SerialPort.LSR.DR","SerialPort.MCR.RTS","getBaudTimeout","inRBR","SerialPort.LCR.DLAB","inIER","inIIR","SerialPort.IIR.INT_THR","inLCR","inMCR","inLSR","inMSR","outTHR","nChars","outIER","outLCR","outMCR","SerialPort.MCR.DTR","RTS","DTR","SerialPort.IER.RBR_AVAIL","SerialPort.IIR.INT_RBR","SerialPort.IER.THR_EMPTY","SerialPort.IER.MSR_DELTA","SerialPort.IIR.INT_MSR","SerialPort.IIR.INT_BITS","RBR_AVAIL","THR_EMPTY","MSR_DELTA","NO_INT","INT_RBR","INT_THR","INT_MSR","INT_BITS","DLAB","DR","THRE","TSRE","DCTS","DDSR","aeSerial","iSerial","eSerial","TestController","tests","fLoading","urlTests","deliverData","deliverInput","deliverTests","serialPort","loadTests","JSON","parse","control.onkeydown","control.onkeypress","bindController","monitor","TestMonitor","sendOutput","aeTest","iTest","eTest","aOperations","idTimeout","fnRemoveOperation","removeOperation","fWaitPending","receiveInput","receiveTests","APPNAME","APPVERSION","TestMonitor.MODE.TERMINAL","addCommand","commandLine","commands","suite","category","commandParts","command","fExists","addForLoop","errorMessage","p1","p2","Str.sprintf","TestMonitor.COMMANDS.indexOf","addOperation","symbol","initial","final","nextOperation","flushOperations","TestMonitor.COMMAND.PRINTF","TestMonitor.COMMAND.WAIT","TestMonitor.MODE.PROMPT","aCategories","aPrompts","cchPromptLongest","prompt","promptBuffer","TestMonitor.MODE.COMMAND","commandBuffer","Keys.ASCII.DEL","TERMINAL","PROMPT","COMMAND","PRINTF","WAIT","TestMonitor.COMMANDS","Mouse","parmsMouse","idDevice","Mouse.TYPE.SERIAL","Mouse.TYPE.BUS","typeDevice","componentDevice","fCaptured","aVideo","aScreens","Mouse.prototype","Mouse.aBusInput","Mouse.BUS.DATA.PORT","Mouse.aBusOutput","getScreen","captureAll","releaseAll","fButton1","fButton2","setActive","captureMouse","onMouseMove","processMouseEvent","onMouseDown","onMouseUp","screenX","screenY","iButton","isActive","sDiag","sendPacket","Mouse.BUTTON.RIGHT","xDiag","yDiag","xScaled","sign","yScaled","b1","b2","b3","Mouse_prototype$receiveStatus","fIdentify","Mouse.SERIAL.ID","inBusData","inBusTPPI","inBusCtrl","inBusCPPI","outBusData","outBusTPPI","outBusCtrl","outBusCPPI","ID","aeMouse","iMouse","eMouse","Disk","drive","Disk.nDisks","sDiskName","fRemovable","fOnDemand","fRemote","create","nCylinders","nHeads","nSectors","cbSector","aDirtySectors","aDirtyTimestamps","timerWrite","msTimerWrite","fWriteInProgress","Disk.prototype","sDiskPath","donePowerUp","Component.confirmUser","findDirtySectors","disconnectRemoteDisk","getMachineID","getUserID","aDiskData","aCylinders","iCylinder","aHeads","iHead","aSectors","iSector","initSector","dwChecksum","file","fnNotify","sDiskURL","sDiskFile","disk","controllerNotify","reader","FileReader","onload","reader.onload","buildDisk","readAsArrayBuffer","ENDPOINT","sDiskExt","connectRemoteDisk","loadDone","cbDiskData","byteLength","diskFormat","cylinder","head","sector","dwPattern","cModify","diskData","fWriteProtected","buildFileTable","iEOL","sConfig","fill","dir","aFileTable","offFile","pbaVolume","lbaTotal","cbDisk","sectorBoot","getSector","getSectorData","SECTOR_BYTES","fValid","lbaFAT","nFATBits","lbaRoot","nClusterSecs","MEDIA_160KB","getClusterEntry","nEntries","MEDIA_320KB","PARTITIONS","TOTAL_SECS","LARGE_SECS","RESERVED_SECS","FAT_SECS","TOTAL_FATS","ROOT_DIRENTS","CLUSTER_SECS","lbaData","LENGTH","nClusters","MAX_CLUSTERS","iClusterMax","CLUSNUM_MAX","apba","lba","getDir","nSectorsPerCylinder","updateSector","nSectorsRemaining","pba","Str.endsWith","loadField","FileInfo.OE.oeSignature","FileInfo.OE.SIG","FileInfo.OE.oeRelocOffset","FileInfo.OE.NE_SIG","offNEHeader","FileInfo.OE.oeNEHeader","FileInfo.NE.neSignature","FileInfo.NE.SIG","FileInfo.NE.neSTEntries","offEntries","FileInfo.NE.neSTOffset","nSegOffShift","FileInfo.NE.neSegOffShift","loadSegmentTable","iSegment","aSegments","aOrdinals","offSegment","loadValue","lenSegment","offStart","offEnd","aEntries","FileInfo.NE.neETOffset","cbEntries","FileInfo.NE.neETSize","loadEntryTable","iOrdinal","offEntriesEnd","bEntries","bSegment","offEntry","FileInfo.NE.neRNTOffset","loadNameTable","FileInfo.NE.neNRNTOffset","FileInfo.NE.neNRNTSize","sDisk","sDir","iStart","nEntriesPerSector","iEntry","getDirEntry","sectorDirCache","pbaDirCache","UNUSED","INVALID","getSectorString","NAME","EXT","ATTR","cbSize","SIZE","iCluster","CLUSTER","CLUSNUM_MIN","FileInfo","iEnd","SUBDIR","iByte","cbitsSector","offBits","sectorFATCache","lbaFATCache","seek","read","iModify","readRemoteSectors","aRequest","abData","writeRemoteSectors","abSectors","dataPost","ACTION","stringify","queueDirtySector","updateWriteTimer","msWrite","Disk.REMOTE_WRITE_DELAY","msNow","sectorNext","toBytes","info","track","bFormatting","bSectorEnd","nBytes","onReadRemoteComplete","bSector","ibSector","write","encodeAsBase64","btoa","deltas","mods","iModifyLimit","nChanges","sReason","aDiskInfo","convertToJSON","deflateSector","cDupes","offSector","aField","cNames","bLength","loadString","sSymbol","tuple","sModule","SIG","oeSignature","oeRelocOffset","oeNEHeader","NE_SIG","neSignature","neETOffset","neETSize","neSTEntries","neNRNTSize","neSTOffset","neRNTOffset","neNRNTOffset","neSegOffShift","parmsFDC","doDMARead","doDMAWrite","doDMAFormat","configMount","parseConfig","sortBy","aDiskHistory","fLocalDisks","loadSelectedDisk","waitDrives","FDC.prototype","fdc","aOptions","sort","text","localeCompare","onchange","controlSelect.onchange","updateSelectedDiskette","displayDiskette","controlDrives","aDrives","Web.downloadFile","controlForm.onchange","fieldset","children","submit","disabled","files","onsubmit","controlForm.onsubmit","currentTarget","sDiskettePath","loadSelectedDrive","sDisketteName","initController","FDC.aPortInput","FDC.aPortOutput","addDiskette","autoMount","config","configMerge","sDrive","fReload","unloadAllDrives","unloadDrive","firstChild","controlOption","saveController","FDC.REG_STATUS.RQM","regDataArray","regDataIndex","regDataTotal","regOutput","dataDrives","nKb","initDrive","fLocal","FDC.REG_DATA.RES.RESET","FDC.DEFAULT_DRIVE_NAME","nDiskCylinders","nDiskHeads","nDiskSectors","resCode","bHead","bCylinderSeek","bCylinder","doneLoadDrive","loadDrive","addDiskHistory","regInput","FDC.REG_CONTROL.RATE500K","saveDrives","saveDeltas","updateDiskHistory","copyDrive","driveOld","driveNew","seekDrive","nSectorsPerTrack","FDC.REG_DATA.RES.NONE","fRemount","cAutoMount","configDrive","controlDisks","findDisketteByPath","removeDiskHistory","fAutoMount","FDC.REG_INPUT.DISK_CHANGE","sPath","fTop","insertBefore","iDriveSelected","sTargetPath","dataValue","sHRef","fAutoUnload","outFDCOutput","FDC.REG_OUTPUT.ENABLE","requestInterrupt","inFDCDiagnostic","inFDCStatus","inFDCData","FDC.REG_OUTPUT.INT_ENABLE","FDC.REG_STATUS.READ_DATA","FDC.REG_STATUS.BUSY","outFDCData","bCmdMasked","FDC.REG_DATA.CMD.MASK","FDC.aCmdInfo","cbReq","fIRQ","doCmd","popCmd","FDC.REG_DATA.CMD.SPECIFY","beginResult","FDC.REG_DATA.CMD.SENSE_DRIVE","bDrive","pushResult","FDC.REG_DATA.RES.ST3","FDC.REG_DATA.CMD.WRITE_DATA","FDC.REG_DATA.CMD.READ_DATA","FDC.REG_DATA.RES.NOT_READY","FDC.REG_DATA.RES.INCOMPLETE","ChipSet.DMA_FDC","FDC.REG_DATA.RES.NOT_WRITABLE","pushResults","FDC.REG_DATA.CMD.RECALIBRATE","FDC.REG_DATA.RES.SEEK_END","FDC.REG_DATA.RES.TRACK0","FDC.REG_DATA.CMD.SENSE_INT","FDC.REG_DATA.RES.ST0","FDC.REG_DATA.CMD.READ_ID","FDC.REG_DATA.CMD.FORMAT_TRACK","bFiller","cbFormat","abFormat","cSectorsFormatted","FDC.REG_DATA.CMD.SEEK","inFDCInput","outFDCControl","pushST0","pushST1","FDC.REG_DATA.RES.ST1","pushST2","FDC.REG_DATA.RES.ST2","FDC.REG_DATA.CMD.MT","fCondition","bResult","FDC_prototype$doDMARead","readData","FDC_prototype$doDMAWrite","writeData","FDC.REG_DATA.RES.NO_DATA","advanceSector","FDC.REG_DATA.RES.CRC_ERROR","bSectorStart","INT_ENABLE","BUSY","READ_DATA","RQM","SPECIFY","SENSE_DRIVE","WRITE_DATA","RECALIBRATE","SENSE_INT","READ_ID","FORMAT_TRACK","SEEK","MT","RES","NOT_READY","SEEK_END","INCOMPLETE","ST0","NOT_WRITABLE","NO_DATA","CRC_ERROR","ST1","ST2","TRACK0","ST3","DISK_CHANGE","RATE500K","cbRes","FDC.CMDS.SPECIFY","FDC.CMDS.SENSE_DRIVE","FDC.CMDS.WRITE_DATA","FDC.CMDS.READ_DATA","FDC.CMDS.RECALIBRATE","FDC.CMDS.SENSE_INT","FDC.CMDS.READ_ID","FDC.CMDS.FORMAT","FDC.CMDS.SEEK","aeFDC","iFDC","eFDC","parmsHDC","doDMAWriteBuffer","doDMAWriteFormat","aDriveConfigs","sDriveConfigs","fATC","HDC.prototype","hdc","onClickSaveDrive","iDriveTable","iDriveTypeDefault","HDC.aATCPortInput","HDC.aXTCPortInput","HDC.aATCPortOutput","HDC.aXTCPortOutput","HDC.ATC.DATA.PORT","intBIOSDisk","ALT_DISK","intBIOSDiskette","sMachineID","sUserID","HDC.ATC.STATUS.READY","regError","regWPreC","regSecCnt","regSecNum","regCylLo","regCylHi","regDrvHd","regCommand","regFDR","HDC.XTC.STATUS.NONE","regConfig","regReset","regPulse","regPattern","iDriveAllowFail","driveConfig","HDC.XTC.DATA.ERR.NONE","errorCode","senseCode","abDriveParms","abSector","wCylinder","bSectorBias","HDC.DEFAULT_DRIVE_NAME","path","HDC.aDriveTypes","driveType","bExt","bOrig","HDRIVE","iExt","setCMOSByte","verifyDrive","loadDisk","doneLoadDisk","HDC.aDriveTables","inXTCData","HDC.XTC.STATUS.INTERRUPT","HDC.XTC.STATUS.IOMODE","HDC.XTC.STATUS.BUS","HDC.XTC.STATUS.BUSY","outXTCData","cbCmd","HDC.XTC.DATA.CMD.INIT_DRIVE","HDC.XTC.STATUS.REQ","doXTC","inXTCStatus","outXTCReset","inXTCConfig","outXTCPulse","outXTCPattern","outXTCNoise","inATCByte","onATCReadData","HDC.ATC.STATUS.BUSY","onATCReadDataNext","setATCIRR","HDC.ATC.STATUS.SEEK_OK","HDC.ATC.STATUS.DATA_REQ","HDC.ATC.STATUS.ERROR","HDC.ATC.ERROR.NO_CHS","HDC_prototype$inATCData","outATCByte","outATCData","inATCError","outATCWPreC","inATCSecCnt","outATCSecCnt","inATCSecNum","outATCSecNum","inATCCylLo","outATCCylLo","inATCCylHi","outATCCylHi","inATCDrvHd","outATCDrvHd","HDC.ATC.DRVHD.DRIVE_MASK","inATCStatus","outATCCommand","doATC","outATCFDR","HDC.ATC.FDR.RESET","HDC.ATC.DIAG.NO_ERROR","fInterrupt","nHead","HDC.ATC.DRVHD.HEAD_MASK","nCylinder","HDC.ATC.CYLHI.MASK","nSector","HDC.ATC.ERROR.NONE","HDC.ATC.COMMAND.DIAGNOSE","HDC.ATC.COMMAND.MASK","HDC.ATC.COMMAND.RESTORE","HDC.ATC.COMMAND.READ_DATA","onATCReadDataFirst","HDC.ATC.COMMAND.WRITE_DATA","HDC.ATC.COMMAND.READ_VERF","HDC.ATC.COMMAND.SEEK","HDC.ATC.COMMAND.SETPARMS","HDC.ATC.FDR.INT_DISABLE","bCount","HDC.XTC.DATA.CMD.REQUEST_SENSE","HDC.XTC.DATA.ERR.NOT_READY","HDC.XTC.DATA.STATUS.OK","bParm","bDataStatus","HDC.XTC.DATA.STATUS.ERROR","HDC.XTC.DATA.CMD.RAM_DIAGNOSTIC","HDC.XTC.DATA.CMD.CTL_DIAGNOSTIC","HDC.XTC.DATA.CMD.TEST_READY","HDC.XTC.DATA.CMD.RECALIBRATE","HDC.XTC.DATA.CMD.READ_VERF","HDC.XTC.DATA.CMD.READ_DATA","doRead","onXTCReadDataCommand","HDC.XTC.DATA.CMD.WRITE_DATA","doWrite","onXTCWriteDataCommand","HDC.XTC.DATA.CMD.WRITE_BUFFER","doWriteBuffer","onXTCWriteBufferCommand","HDC_prototype$doDMARead","HDC_prototype$doDMAWrite","HDC.XTC.DATA.ERR.NO_SECTOR","ChipSet.DMA_HDC","onDMAReadRequest","onDMAWriteRequest","onDMAWriteBufferRequest","fAutoInc","onReadDataSeek","onWriteDataSeek","NO_ERROR","ERROR","NO_CHS","CYLHI","HEAD_MASK","DRVHD","DRIVE_MASK","DATA_REQ","SEEK_OK","READY","RESTORE","READ_VERF","DIAGNOSE","SETPARMS","INT_DISABLE","FDR","TEST_READY","REQUEST_SENSE","INIT_DRIVE","WRITE_BUFFER","RAM_DIAGNOSTIC","CTL_DIAGNOSTIC","NO_SECTOR","REQ","IOMODE","INTERRUPT","aeHDC","iHDC","eHDC","Debugger","parmsDbg","nBase","achGroup","achAddress","cOpcodes","cOpcodesStart","fAssemble","iPrevCmd","aPrevCmds","aVariables","getRegIndex","getRegValue","parseAddrReference","sAddr","parseCommand","sCmd","chSep","iPrev","truncate","nBits","fUnsigned","vNew","evalOps","aVals","cOps","chOp","pop","val2","val1","valNew","parseArray","asValues","iValue","iLimit","aUndefined","nUnary","nBasePrev","sOp","parseValue","cOpen","parseUnary","aBinOp","Debugger.aDECOpPrecedence","Debugger.aBinOpPrecedence","parseASCII","sExp","chDelim","toStrBase","parseExpression","fPrint","join","regExp","printValue","parseReference","chOpen","chClose","chEscape","chInnerEscape","reSubExp","parseSysVars","getVariable","sVar","sUndefined","getVariableFixup","valueUndefined","fDefined","printVariable","cVariables","aVars","Str.toOct","DebuggerX86","cchReg","cchAddr","dbgAddrNextCode","newAddr","dbgAddrNextData","dbgAddrAssemble","aSymbolTable","aBreakExec","aBreakRead","aBreakWrite","clearBreakpoints","nBreakIns","historyInit","afnDumpers","messageInit","sCommandsInit","doCommands","global","DebuggerX86.prototype","sMessages","segDebugger","DBG","aaOpDescs","DebuggerX86.aaOpDescs","DebuggerX86.aaOpDescs.slice","DebuggerX86.aOpDescUndefined","DebuggerX86.aOpDesc0F","onDumpBus","dumpBlocks","onDumpSel","sSel","getSegment","DebuggerX86.ADDRTYPE.PROT","fGate","sysDesc","DebuggerX86.SYSDESCS","getLimitString","onDumpDOS","mcb","sMCB","dbgAddr","bSig","wPID","wParas","toHexOffset","getSZ","onDumpMem","onDumpTSS","aTSSFields","DebuggerX86.TSS286","DebuggerX86.TSS386","sField","iPort","fWinDbg","cTrapFaults","fIgnoreNextCheckFault","WINCB","intWindowsCallBack","intWindowsDebugger","fWinDbgRM","WINDBGRM","intWindowsDebuggerRM","addSegmentInfo","nSegment","fCode","sSection","findModuleInfo","addSectionInfo","dbgAddrModule","dbgAddrParent","sParent","removeSectionInfo","removeSymbols","DX","SI","EAX","AX","BX","DI","ES","onInt41Return","removeSegmentInfo","findBreakpoint","toHexAddr","onInt68Return","callWindowsDebuggerPMInit","controlDebug","setSelectionRange","Web.onClickRepeat","onClickDebugEnter","sCommands","onClickStep","fRepeat","fCompleted","getCPUMode","typeDefault","getAddressType","DebuggerX86.ADDRTYPE.REAL","nSuppressBreaks","DebuggerX86_prototype$getByte","DebuggerX86.ADDRTYPE.PHYSICAL","incAddr","fAdvance","fData32","DebuggerX86_prototype$getShort","DebuggerX86_prototype$setByte","fNoUpdate","DebuggerX86_prototype$setShort","fAddr32","setAddr","fTempBreak","packAddr","cOverrides","unpackAddr","aAddr","checkLimit","fUpdate","parseAddr","fNoChecks","dbgAddrNext","DebuggerX86.ADDRTYPE.NONE","iColon","DebuggerX86.ADDRTYPE.LINEAR","sUpperCase","iTable","findSymbolAddr","symbolTable","offSymbol","selSymbol","parseAddrOptions","sOptions","aCmds","DebuggerX86.ADDRTYPE.V86","fLinear","typePrev","cPrev","getPageEntry","addrPE","lPE","fPTE","iFile","segment","entry","sEnable","sMessagePrev","aMessageBuffer","aEnable","Usr.indexOf","bitMessage","fnDumper","DebuggerX86.REGS","getRegString","DebuggerX86.REG_AL","DebuggerX86.REG_CL","DebuggerX86.REG_DL","DebuggerX86.REG_BL","DebuggerX86.REG_AH","DebuggerX86.REG_CH","DebuggerX86.REG_DH","DebuggerX86.REG_BH","DebuggerX86.REG_AX","DebuggerX86.REG_CX","DebuggerX86.REG_DX","DebuggerX86.REG_BX","DebuggerX86.REG_SP","DebuggerX86.REG_BP","DebuggerX86.REG_SI","DebuggerX86.REG_DI","DebuggerX86.REG_IP","DebuggerX86.REG_SEG","DebuggerX86.REG_ES","DebuggerX86.REG_CS","DebuggerX86.REG_SS","DebuggerX86.REG_DS","DebuggerX86.REG_FS","DebuggerX86.REG_GS","DebuggerX86.REG_EAX","DebuggerX86.REG_ECX","DebuggerX86.REG_EDX","DebuggerX86.REG_EBX","DebuggerX86.REG_ESP","DebuggerX86.REG_EBP","DebuggerX86.REG_ESI","DebuggerX86.REG_EDI","DebuggerX86.REG_CR0","DebuggerX86.REG_CR1","DebuggerX86.REG_CR2","DebuggerX86.REG_CR3","DebuggerX86.REG_EIP","DebuggerX86.REG_PS","replaceRegs","sChar","fMessage","DebuggerX86.INT_ANNOYING.indexOf","nCategory","DebuggerX86.INT_MESSAGES","aFuncs","Interrupts.FUNCS","selFrom","aOpcodeHistory","DebuggerX86.HISTORY_LIMIT","iOpcodeHistory","aaOpcodeCounts","fRegs","fUpdateCPU","checkCPU","nCyclesStep","nStep","doRegisters","doUnassemble","clearTempBreakpoint","restoreBreakpoints","sStopped","msTotal","nState","checkBreakpoint","cycleCount","aBreak","printBreakpoint","fFound","mapBreakpoint","dbgAddrBreak","listBreakpoints","sAction","aDbgAddr","fBreak","addrBreak","doCommand","getInstruction","sComment","nSequence","dbgAddrIns","cMaxOverrides","fDataPrefix","fAddrPrefix","asOpcodes","DebuggerX86.INS_NAMES","aOpDesc","iIns","DebuggerX86.INS.OP0F","DebuggerX86.aaOp0FDescs","DebuggerX86.INS.ESC","aaOpDesc","DebuggerX86.aaaOpFPUDescs","aOpFPUDesc","DebuggerX86.FINS_NAMES","DebuggerX86.aaGrpDescs","sOpcode","cOperands","sOperands","DebuggerX86.INS.CBW","DebuggerX86.INS.CWD","DebuggerX86.INS.POPA","DebuggerX86.INS.PUSHA","typeCPU","iOperand","sOperand","DebuggerX86.TYPE_CPU_SHIFT","DebuggerX86.INS.LOADALL","DebuggerX86.CPU_80286","DebuggerX86.CPU_80386","typeSize","DebuggerX86.TYPE_SIZE","DebuggerX86.TYPE_NONE","DebuggerX86.TYPE_PREFIX","typeMode","DebuggerX86.TYPE_MODE","DebuggerX86.TYPE_MODRM","DebuggerX86.TYPE_MODREG","bMod","bRM","fInteger","getSIBOperand","bScale","bBase","DebuggerX86.RMS","DebuggerX86.TYPE_WORD","DebuggerX86.TYPE_LONG","DebuggerX86.TYPE_SHORT","DebuggerX86.TYPE_FARP","DebuggerX86.TYPE_BYTE","DebuggerX86.TYPE_SINT","DebuggerX86.TYPE_SREAL","DebuggerX86.TYPE_LINT","DebuggerX86.TYPE_LREAL","DebuggerX86.TYPE_TREAL","DebuggerX86.TYPE_BCD80","getRegOperand","DebuggerX86.TYPE_ONE","DebuggerX86.TYPE_IMM","getImmOperand","DebuggerX86.TYPE_BOTH","DebuggerX86.TYPE_SBYTE","aSymbol","findSymbol","DebuggerX86.TYPE_IMMOFF","DebuggerX86.TYPE_IMMREL","DebuggerX86.TYPE_IMPREG","DebuggerX86.TYPE_ST","DebuggerX86.TYPE_STREG","DebuggerX86.TYPE_IREG","DebuggerX86.TYPE_IMPSEG","DebuggerX86.TYPE_SEGREG","DebuggerX86.TYPE_DSSI","DebuggerX86.TYPE_ESDI","sBytes","sLine","DebuggerX86.CPUS","initAddrSize","bReg","DebuggerX86.TYPE_CTLREG","DebuggerX86.TYPE_DBGREG","DebuggerX86.REG_DR0","DebuggerX86.TYPE_TSTREG","DebuggerX86.REG_TR0","getFlagOutput","sFlag","getRegOutput","getSegOutput","getDTROutput","getRegDump","sTR","sA20","comparePairs","aOffsets","sAnnotation","Usr.binarySearch","fNearest","addrSymbol","returnSymbol","iOffset","doFreqs","cData","aaSortedOpcodeCounts","cFreq","doVar","delVariable","setVariable","doList","sDelta","doLoad","fJSON","dc","clearPanel","doClear","fAbort","dbgAddrCur","fInstruction","doFPURegisters","wStatus","wControl","aTR","DebuggerX86.FPU_TAGS","sRegMatch","fUnknown","doPrint","getCall","fFar","sCall","offOrig","doTrace","sCount","nCount","Web.onCountRepeat","onCountStep","onCountStepComplete","fData32Orig","fAddr32Orig","sAddrEnd","dbgAddrEnd","cLines","sInstruction","s0","ch0","doAssemble","aOpBytes","doBreak","cBreaks","sLen","sDumpers","doDump","sState","powerOff","sSymbolOrig","pageInfo","addrPDE","lPDE","addrPTE","lPTE","addrPhys","sCmdDumpPrev","sMore","cHistory","iHistory","aHistory","nPrev","sPrev","nextHistory","nLines","sLines","aFilters","dbgAddrNew","sIDT","sInfo","fASCII","cbLine","fnGet","doEdit","vOld","doRun","doHalt","doIf","doInt","sInt","sPort","doInput","doStackTrace","cFrames","dbgAddrCall","dbgAddrStack","nFrames","cTests","sCallPrev","doMouse","fCriteria","sCategory","doMessages","sCategories","doOutput","sByte","nRegs","doStep","doExecOptions","DebuggerX86.COMMANDS","doHelp","DebuggerX86.INT_ANNOYING","ALT_TIMER","DOS_IDLE","DOS_NETBIOS","ALT_VIDEO","REAL","PROT","V86","LINEAR","PHYSICAL","CBW","CWD","LOADALL","POPA","PUSHA","OP0F","DebuggerX86.TYPE_AL","DebuggerX86.TYPE_CL","DebuggerX86.TYPE_AX","DebuggerX86.TYPE_CX","DebuggerX86.TYPE_DX","DebuggerX86.TYPE_BX","DebuggerX86.TYPE_SP","DebuggerX86.TYPE_BP","DebuggerX86.TYPE_SI","DebuggerX86.TYPE_DI","DebuggerX86.TYPE_ES","DebuggerX86.TYPE_CS","DebuggerX86.TYPE_SS","DebuggerX86.TYPE_DS","DebuggerX86.TYPE_FS","DebuggerX86.TYPE_GS","DebuggerX86.TYPE_80286","DebuggerX86.TYPE_80386","ADD","DebuggerX86.TYPE_IN","DebuggerX86.TYPE_REG","PUSH","POP","DebuggerX86.TYPE_OUT","OR","DebuggerX86.aOpDescPopCS","ADC","SBB","AND","DAA","SUB","CS","DAS","XOR","SS","AAA","CMP","DS","AAS","INC","DEC","BOUND","ARPL","FS","GS","OS","AS","IMUL","OUTS","JO","JNO","JC","JNC","JZ","JNZ","JBE","JA","JS","JNS","JP","JNP","JL","JGE","JLE","JG","GRP1B","GRP1W","GRP1SW","TEST","XCHG","MOV","LEA","DebuggerX86.TYPE_MODMEM","NOP","CALL","PUSHF","POPF","SAHF","LAHF","MOVSB","MOVSW","CMPSB","CMPSW","STOSB","STOSW","LODSB","LODSW","SCASB","SCASW","GRP2B","DebuggerX86.TYPE_80186","GRP2W","RET","LES","LDS","LEAVE","RETF","INT3","INTO","IRET","GRP2B1","GRP2W1","GRP2BC","GRP2WC","AAM","AAD","SALC","XLAT","LOOPNZ","LOOPZ","LOOP","JCXZ","IN","OUT","JMP","LOCK","REPNZ","REPZ","HLT","CMC","GRP3B","GRP3W","CLC","STC","CLI","STI","CLD","STD","GRP4B","GRP4W","GRP6","GRP7","LAR","LSL","CLTS","SETO","SETNO","SETC","SETNC","SETZ","SETNZ","SETBE","SETNBE","SETS","SETNS","SETP","SETNP","SETL","SETGE","SETLE","SETG","BT","SHLD","XBTS","IBTS","BTS","SHRD","LSS","BTR","LFS","LGS","MOVZX","GRP8","BTC","BSF","BSR","MOVSX","FADD","FMUL","FCOM","FCOMP","FSUB","FSUBR","FDIV","FDIVR","FLD","FST","FSTP","FXCH","FIADD","FIMUL","FICOM","FICOMP","FISUB","FISUBR","FIDIV","FIDIVR","FILD","FIST","FISTP","FENI","FDISI","FSETPM","FSINCOS","FFREE","FADDP","FMULP","FSUBRP","FSUBP","FDIVRP","FDIVP","FBLD","FBSTP","FFREEP","FSTSWAX","ROL","ROR","RCL","RCR","SHL","SHR","SAR","NOT","NEG","MUL","DIV","IDIV","SLDT","STR","LLDT","LTR","VERR","VERW","SGDT","SIDT","LGDT","LIDT","SMSW","LMSW","aeDbg","iDbg","eDbg","Computer","parmsComputer","parmsMachine","fSuspended","setMachineParms","fAutoPower","nDiagnostics","nPowerChange","resume","Computer.RESUME_NONE","sStateData","fServerState","fStateData","url","queryUserID","controlPanel","noticeComputer","printComputer","printlnComputer","outputDiagnostics","cDiagnosticScreens","enableDiagnostics","updateStatusTimer","Computer.UPDATES_PER_SECOND","sResume","sResumePath","fAllowResume","stateComputer","getServerStatePath","sStateURL","sResource","wait","lineHeight","parmsComponent","Computer.prototype","onComponentReady","validateState","stateValidate","Computer.STATE_VALIDATE","sTimestampValidate","Computer.STATE_TIMESTAMP","sTimestampComputer","clear","Computer.RESUME_AUTO","fRestore","fRestoreError","stateFailSafe","Computer.STATE_FAILSAFE","powerReport","Computer.RESUME_PROMPT","unload","store","fValidate","FAIL","Web.setLocalStorageItem","Computer.STATE_USERID","resetUserID","powerRestore","donePowerOn","reload","asComments","disableDiagnostics","controlPower","QUERY","sUser","sReport","sReportURL","sTimestamp","Computer.STATE_VERSION","Computer.STATE_HOSTURL","Computer.STATE_BROWSER","fClearAll","fClear","saveServerState","Computer.RESUME_DELETE","fPrompt","Web.getLocalStorageItem","verifyUserID","State.key","storeServerState","fScroll","scrollX","scrollY","scrollTo","getFS","getGS","getSpeedCurrent","aeMachines","iMachine","eMachine","aeComputers","iComputer","eComputer","show","exit","sVersion","json","fLoaded","fParsed","State.prototype","Web.hasLocalStorage","cAsyncMachines","loadXML","sXMLFile","fResolve","doneLoadXML","sURLName","sXML","parseXML","buildXML","pathname","xmlDoc","async","parseFromString","DOMParser","resolveXML","matchRef","reRef","sRefFile","doneReadXML","sXMLRef","sRefAttrs","aXMLRefTag","sXMLNewTag","matchAttr","reAttr","embedMachine","sXSLFile","displayMessage","eWarning","aeWarning","Str.escapeHTML","displayError","Web.enablePageEvents","getElementById","css","styleSheet","cssText","createTextNode","processXML","xml","transformXML","sXSL","xsl","sFragment","outerHTML","implementation","createDocument","xsltProcessor","XSLTProcessor","eFragment","replaceChild","embedPCx86","commandMachine","fSingle","sComponent","downloadCSS","sPCJS","aMachineInfo","res","sCSSFile","downloadPC","sCSS","matchScript","resOld","resNew","sExt","reDisk","matchDisk","sResources","savePC","sPCJSFile"],"sourcesContent":["\"use strict\";\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/defines.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @define {string}\n */\nvar APPVERSION = \"\"; // this @define is overridden by the Closure Compiler with the version in machines.json\n\nvar XMLVERSION = null; // this is set in non-COMPILED builds by embedMachine() if a version number was found in the machine XML\n\nvar COPYRIGHT = \"Copyright © 2012-2018 Jeff Parsons <Jeff@pcjs.org>\";\n\nvar LICENSE = \"License: GPL version 3 or later <http://gnu.org/licenses/gpl.html>\";\n\nvar CSSCLASS = \"pcjs\";\n\n/**\n * @define {string}\n */\nvar SITEHOST = \"localhost:8088\";// this @define is overridden by the Closure Compiler with \"www.pcjs.org\"\n\n/**\n * @define {boolean}\n */\nvar COMPILED = false; // this @define is overridden by the Closure Compiler (to true)\n\n/**\n * @define {boolean}\n */\nvar DEBUG = true; // this @define is overridden by the Closure Compiler (to false) to remove DEBUG-only code\n\n/**\n * @define {boolean}\n */\nvar MAXDEBUG = false; // this @define is overridden by the Closure Compiler (to false) to remove MAXDEBUG-only code\n\n/**\n * @define {boolean}\n */\nvar PRIVATE = false; // this @define is overridden by the Closure Compiler (to false) to enable PRIVATE code\n\n/*\n * RS-232 DB-25 Pin Definitions, mapped to bits 1-25 in a 32-bit status value.\n *\n * SerialPorts in PCjs machines are considered DTE (Data Terminal Equipment), which means they should be \"virtually\"\n * connected to each other via a null-modem cable, which assumes the following cross-wiring:\n *\n * G 1 <-> 1 G (Ground)\n * TD 2 <-> 3 RD (Received Data)\n * RD 3 <-> 2 TD (Transmitted Data)\n * RTS 4 <-> 5 CTS (Clear To Send)\n * CTS 5 <-> 4 RTS (Request To Send)\n * DSR 6+8 <-> 20 DTR (Data Terminal Ready)\n * SG 7 <-> 7 SG (Signal Ground)\n * DTR 20 <-> 6+8 DSR (Data Set Ready + Carrier Detect)\n * RI 22 <-> 22 RI (Ring Indicator)\n *\n * TODO: Move these definitions to a more appropriate shared file at some point.\n */\nvar RS232 = {\n RTS: {\n PIN: 4,\n MASK: 0x00000010\n },\n CTS: {\n PIN: 5,\n MASK: 0x00000020\n },\n DSR: {\n PIN: 6,\n MASK: 0x00000040\n },\n CD: {\n PIN: 8,\n MASK: 0x00000100\n },\n DTR: {\n PIN: 20,\n MASK: 0x00100000\n },\n RI: {\n PIN: 22,\n MASK: 0x00400000\n }\n};\n\n/*\n * NODE should be true if we're running under NodeJS (eg, command-line), false if not (eg, web browser)\n */\nvar NODE = false;\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/diskapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Our \"DiskIO API\" looks like:\n *\n * http://www.pcjs.org/api/v1/disk?action=open&volume=*10mb.img&mode=demandrw&chs=c:h:s&machine=xxx&user=yyy\n */\nvar DiskAPI = {\n ENDPOINT: \"/api/v1/disk\",\n QUERY: {\n ACTION: \"action\", // value is one of DiskAPI.ACTION.*\n VOLUME: \"volume\", // value is path of a disk image\n MODE: \"mode\", // value is one of DiskAPI.MODE.*\n CHS: \"chs\", // value is cylinders:heads:sectors:bytes\n ADDR: \"addr\", // value is cylinder:head:sector:count\n MACHINE: \"machine\", // value is machine token\n USER: \"user\", // value is user ID\n DATA: \"data\" // value is data to be written\n },\n ACTION: {\n OPEN: \"open\",\n READ: \"read\",\n WRITE: \"write\",\n CLOSE: \"close\"\n },\n MODE: {\n LOCAL: \"local\", // this mode implies no API (at best, localStorage backing only)\n PRELOAD: \"preload\", // this mode implies use of the DumpAPI\n DEMANDRW: \"demandrw\",\n DEMANDRO: \"demandro\"\n },\n FAIL: {\n BADACTION: \"invalid action\",\n BADUSER: \"invalid user\",\n BADVOL: \"invalid volume\",\n OPENVOL: \"unable to open volume\",\n CREATEVOL: \"unable to create volume\",\n WRITEVOL: \"unable to write volume\",\n REVOKED: \"access revoked\"\n }\n};\n\n/*\n * TODO: Eventually, our tools will need to support looking up disk formats by \"model\" rather than by raw disk size,\n * because obviously multiple disk geometries can yield the same raw disk size. For each conflict that arises, I'll\n * probably create a fake (approximate) disk size entry above, and then create a mapping to that approximate size below.\n */\nDiskAPI.MODELS = {\n \"RL01\": 5242880,\n \"RL02\": 10485760\n};\n\nDiskAPI.MBR = {\n PARTITIONS: {\n OFFSET: 0x1BE,\n ENTRY: {\n STATUS: 0x00, // 1-byte (0x80 if active)\n CHS_FIRST: 0x01, // 3-byte CHS specifier\n TYPE: 0x04, // 1-byte TYPE (see below)\n CHS_LAST: 0x05, // 3-byte CHS specifier\n LBA_FIRST: 0x08, // 4-byte Logical Block Address\n LBA_TOTAL: 0x0C, // 4-byte Logical Block Address\n },\n ENTRY_LENGTH: 0x10,\n STATUS: {\n ACTIVE: 0x80\n },\n TYPE: {\n EMPTY: 0x00,\n FAT12_PRIMARY: 0x01, // DOS 2.0 and up (12-bit FAT)\n FAT16_PRIMARY: 0x04 // DOS 3.0 and up (16-bit FAT)\n }\n },\n SIG_OFFSET: 0x1FE,\n SIGNATURE: 0xAA55 // to be clear, the low byte (at offset 0x1FE) is 0x55 and the high byte (at offset 0x1FF) is 0xAA\n};\n\n/*\n * Boot sector offsets (and assorted constants) in DOS-compatible boot sectors (DOS 2.0 and up)\n *\n * WARNING: I've heard apocryphal stories about SIGNATURE being improperly reversed on some systems\n * (ie, 0x55AA instead 0xAA55) -- perhaps by a dyslexic programmer -- so be careful out there.\n */\nDiskAPI.BOOT = {\n JMP_OPCODE: 0x000, // 1 byte for a JMP opcode, followed by a 1 or 2-byte offset\n OEM_STRING: 0x003, // 8 bytes\n SIG_OFFSET: 0x1FE,\n SIGNATURE: 0xAA55 // to be clear, the low byte (at offset 0x1FE) is 0x55 and the high byte (at offset 0x1FF) is 0xAA\n};\n\n/*\n * BIOS Parameter Block (BPB) offsets in DOS-compatible boot sectors (DOS 2.x and up)\n *\n * NOTE: DOS 2.x OEM documentation says that the words starting at offset 0x018 (TRACK_SECS, TOTAL_HEADS, and HIDDEN_SECS)\n * are optional, but even the DOS 2.0 FORMAT utility initializes all three of those words. There may be some OEM media out\n * there with BPBs that are only valid up to offset 0x018, but I've not run across any media like that.\n *\n * DOS 3.20 added LARGE_SECS, but unfortunately, it was added as a 2-byte value at offset 0x01E. DOS 3.31 decided\n * to make both HIDDEN_SECS and LARGE_SECS 4-byte values, which meant that LARGE_SECS had to move from 0x01E to 0x020.\n */\nDiskAPI.BPB = {\n SECTOR_BYTES: 0x00B, // 2 bytes: bytes per sector (eg, 0x200 or 512)\n CLUSTER_SECS: 0x00D, // 1 byte: sectors per cluster (eg, 1)\n RESERVED_SECS: 0x00E, // 2 bytes: reserved sectors; ie, # sectors preceding the first FAT--usually just the boot sector (eg, 1)\n TOTAL_FATS: 0x010, // 1 byte: FAT copies (eg, 2)\n ROOT_DIRENTS: 0x011, // 2 bytes: root directory entries (eg, 0x40 or 64) 0x40 * 0x20 = 0x800 (1 sector is 0x200 bytes, total of 4 sectors)\n TOTAL_SECS: 0x013, // 2 bytes: number of sectors (eg, 0x140 or 320); if zero, refer to LARGE_SECS\n MEDIA_ID: 0x015, // 1 byte: media ID (see DiskAPI.FAT.MEDIA_*); should also match the first byte of the FAT (aka FAT ID)\n FAT_SECS: 0x016, // 2 bytes: sectors per FAT (eg, 1)\n TRACK_SECS: 0x018, // 2 bytes: sectors per track (eg, 8)\n TOTAL_HEADS: 0x01A, // 2 bytes: number of heads (eg, 1)\n HIDDEN_SECS: 0x01C, // 2 bytes (DOS 2.x) or 4 bytes (DOS 3.31 and up): number of hidden sectors (always 0 for non-partitioned media)\n LARGE_SECS: 0x020 // 4 bytes (DOS 3.31 and up): number of sectors if TOTAL_SECS is zero\n};\n\n/*\n * Common (supported) diskette geometries.\n *\n * Each entry in GEOMETRIES is an array of values in \"CHS\" order:\n *\n * [# cylinders, # heads, # sectors/track, # bytes/sector, media ID]\n *\n * If the 4th value is omitted, the sector size is assumed to be 512. The order of these \"geometric\" values mirrors\n * the structure of our JSON-encoded disk images, which consist of an array of cylinders, each of which is an array of\n * heads, each of which is an array of sector objects.\n */\nDiskAPI.GEOMETRIES = {\n 163840: [40,1,8,,0xFE], // media ID 0xFE: 40 cylinders, 1 head (single-sided), 8 sectors/track, ( 320 total sectors x 512 bytes/sector == 163840)\n 184320: [40,1,9,,0xFC], // media ID 0xFC: 40 cylinders, 1 head (single-sided), 9 sectors/track, ( 360 total sectors x 512 bytes/sector == 184320)\n 327680: [40,2,8,,0xFF], // media ID 0xFF: 40 cylinders, 2 heads (double-sided), 8 sectors/track, ( 640 total sectors x 512 bytes/sector == 327680)\n 368640: [40,2,9,,0xFD], // media ID 0xFD: 40 cylinders, 2 heads (double-sided), 9 sectors/track, ( 720 total sectors x 512 bytes/sector == 368640)\n 737280: [80,2,9,,0xF9], // media ID 0xF9: 80 cylinders, 2 heads (double-sided), 9 sectors/track, (1440 total sectors x 512 bytes/sector == 737280)\n 1228800: [80,2,15,,0xF9], // media ID 0xF9: 80 cylinders, 2 heads (double-sided), 15 sectors/track, (2400 total sectors x 512 bytes/sector == 1228800)\n 1474560: [80,2,18,,0xF0], // media ID 0xF0: 80 cylinders, 2 heads (double-sided), 18 sectors/track, (2880 total sectors x 512 bytes/sector == 1474560)\n 2949120: [80,2,36,,0xF0], // media ID 0xF0: 80 cylinders, 2 heads (double-sided), 36 sectors/track, (5760 total sectors x 512 bytes/sector == 2949120)\n /*\n * The following are some common disk sizes and their CHS values, since missing or bogus MBR and/or BPB values\n * might mislead us when attempting to determine the exact disk geometry.\n */\n 10653696:[306,4,17], // PC XT 10Mb hard drive (type 3)\n 21411840:[615,4,17], // PC AT 20Mb hard drive (type 2)\n /*\n * Assorted DEC disk formats.\n */\n 256256: [77, 1,26,128], // RX01 single-platter diskette: 77 tracks, 1 head, 26 sectors/track, 128 bytes/sector, for a total of 256256 bytes\n 2494464: [203,2,12,512], // RK03 single-platter disk cartridge: 203 tracks, 2 heads, 12 sectors/track, 512 bytes/sector, for a total of 2494464 bytes\n 5242880: [256,2,40,256], // RL01K single-platter disk cartridge: 256 tracks, 2 heads, 40 sectors/track, 256 bytes/sector, for a total of 5242880 bytes\n 10485760:[512,2,40,256] // RL02K single-platter disk cartridge: 512 tracks, 2 heads, 40 sectors/track, 256 bytes/sector, for a total of 10485760 bytes\n};\n\n/*\n * Media ID (descriptor) bytes for DOS-compatible FAT-formatted disks (stored in the first byte of the FAT)\n */\nDiskAPI.FAT = {\n MEDIA_160KB: 0xFE, // 5.25-inch, 1-sided, 8-sector, 40-track\n MEDIA_180KB: 0xFC, // 5.25-inch, 1-sided, 9-sector, 40-track\n MEDIA_320KB: 0xFF, // 5.25-inch, 2-sided, 8-sector, 40-track\n MEDIA_360KB: 0xFD, // 5.25-inch, 2-sided, 9-sector, 40-track\n MEDIA_720KB: 0xF9, // 3.5-inch, 2-sided, 9-sector, 80-track\n MEDIA_1200KB: 0xF9, // 3.5-inch, 2-sided, 15-sector, 80-track\n MEDIA_FIXED: 0xF8, // fixed disk (aka hard drive)\n MEDIA_1440KB: 0xF0, // 3.5-inch, 2-sided, 18-sector, 80-track\n MEDIA_2880KB: 0xF0 // 3.5-inch, 2-sided, 36-sector, 80-track\n};\n\n/*\n * Cluster constants for 12-bit FATs (CLUSNUM_FREE, CLUSNUM_RES and CLUSNUM_MIN are the same for all FATs)\n */\nDiskAPI.FAT12 = {\n MAX_CLUSTERS: 4084,\n CLUSNUM_FREE: 0, // this should NEVER appear in cluster chain (except at the start of an empty chain)\n CLUSNUM_RES: 1, // reserved; this should NEVER appear in cluster chain\n CLUSNUM_MIN: 2, // smallest valid cluster number\n CLUSNUM_MAX: 0xFF6, // largest valid cluster number\n CLUSNUM_BAD: 0xFF7, // bad cluster; this should NEVER appear in cluster chain\n CLUSNUM_EOC: 0xFF8 // end of chain (actually, anything from 0xFF8-0xFFF indicates EOC)\n};\n\n/*\n * Cluster constants for 16-bit FATs (CLUSNUM_FREE, CLUSNUM_RES and CLUSNUM_MIN are the same for all FATs)\n */\nDiskAPI.FAT16 = {\n MAX_CLUSTERS: 65524,\n CLUSNUM_FREE: 0, // this should NEVER appear in cluster chain (except at the start of an empty chain)\n CLUSNUM_RES: 1, // reserved; this should NEVER appear in cluster chain\n CLUSNUM_MIN: 2, // smallest valid cluster number\n CLUSNUM_MAX: 0xFFF6, // largest valid cluster number\n CLUSNUM_BAD: 0xFFF7, // bad cluster; this should NEVER appear in cluster chain\n CLUSNUM_EOC: 0xFFF8 // end of chain (actually, anything from 0xFFF8-0xFFFF indicates EOC)\n};\n\n/*\n * Directory Entry offsets (and assorted constants) in FAT disk images\n *\n * NOTE: Versions of DOS prior to 2.0 used INVALID exclusively to mark available directory entries; any entry marked\n * UNUSED was actually considered USED. In DOS 2.0 and up, UNUSED was added to indicate that all remaining entries were\n * unused, relieving it from having to initialize the rest of the sectors in the directory cluster(s). And in fact,\n * you will likely encounter garbage in subsequent directory sectors if you read beyond the first UNUSED entry.\n */\nDiskAPI.DIRENT = {\n NAME: 0x000, // 8 bytes\n EXT: 0x008, // 3 bytes\n ATTR: 0x00B, // 1 byte\n MODTIME: 0x016, // 2 bytes\n MODDATE: 0x018, // 2 bytes\n CLUSTER: 0x01A, // 2 bytes\n SIZE: 0x01C, // 4 bytes (typically zero for subdirectories)\n LENGTH: 0x20, // 32 bytes total\n UNUSED: 0x00, // indicates this and all subsequent directory entries are unused\n INVALID: 0xE5 // indicates this directory entry is unused\n};\n\n/*\n * Possible values for DIRENT.ATTR\n */\nDiskAPI.ATTR = {\n READONLY: 0x01, // PC-DOS 2.0 and up\n HIDDEN: 0x02,\n SYSTEM: 0x04,\n LABEL: 0x08, // PC-DOS 2.0 and up\n SUBDIR: 0x10, // PC-DOS 2.0 and up\n ARCHIVE: 0x20 // PC-DOS 2.0 and up\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/dumpapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Our \"DiskDump API\", such as it was, used to look like:\n *\n * http://jsmachines.net/bin/convdisk.php?disk=/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json&format=img\n *\n * To make it (a bit) more \"REST-like\", the above request now looks like:\n *\n * http://www.pcjs.org/api/v1/dump?disk=/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json&format=img\n *\n * Similarly, our \"FileDump API\" used to look like:\n *\n * http://jsmachines.net/bin/convrom.php?rom=/devices/pc/rom/5150/1981-04-24/PCBIOS-REV1.rom&format=json\n *\n * and that request now looks like:\n *\n * http://www.pcjs.org/api/v1/dump?file=/devices/pc/rom/5150/1981-04-24/PCBIOS-REV1.rom&format=json\n *\n * I don't think it makes sense to avoid \"query\" parameters, because blending the path of a disk image with the\n * the rest of the URL would be (a) confusing, and (b) more work to parse.\n */\nvar DumpAPI = {\n ENDPOINT: \"/api/v1/dump\",\n QUERY: {\n DIR: \"dir\", // value is path of a directory (DiskDump only)\n DISK: \"disk\", // value is path of a disk image (DiskDump only)\n FILE: \"file\", // value is path of a ROM image file (FileDump only)\n IMG: \"img\", // alias for DISK\n PATH: \"path\", // value is path of a one or more files (DiskDump only)\n FORMAT: \"format\", // value is one of FORMAT values below\n COMMENTS: \"comments\", // value is either \"true\" or \"false\"\n DECIMAL: \"decimal\", // value is either \"true\" to force all numbers to decimal, \"false\" or undefined otherwise\n MBHD: \"mbhd\", // value is hard drive size in Mb (formerly \"mbsize\") (DiskDump only) (DEPRECATED)\n SIZE: \"size\" // value is target disk size in Kb (supersedes \"mbhd\") (DiskDump only)\n },\n FORMAT: {\n JSON: \"json\", // default\n JSON_GZ: \"gz\", // gzip is currently used ONLY for compressed JSON\n DATA: \"data\", // same as \"json\", but built without JSON.stringify() (DiskDump only)\n HEX: \"hex\", // deprecated\n OCTAL: \"octal\", // displays data as octal words\n BYTES: \"bytes\", // displays data as hex bytes; normally used only when comments are enabled\n WORDS: \"words\", // displays data as hex words; normally used only when comments are enabled\n LONGS: \"longs\", // displays data as dwords\n IMG: \"img\", // returns the raw disk data (ie, using a Buffer object) (DiskDump only)\n ROM: \"rom\" // returns the raw file data (ie, using a Buffer object) (FileDump only)\n }\n};\n\n/*\n * Because we use an overloaded API endpoint (ie, one that's shared with the FileDump module), we must\n * also provide a list of commands which, when combined with the endpoint, define a unique request.\n */\nDumpAPI.asDiskCommands = [DumpAPI.QUERY.DIR, DumpAPI.QUERY.DISK, DumpAPI.QUERY.PATH];\nDumpAPI.asFileCommands = [DumpAPI.QUERY.FILE];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/reportapi.js (C) Jeff Parsons 2012-2018\n */\n\nvar ReportAPI = {\n ENDPOINT: \"/api/v1/report\",\n QUERY: {\n APP: \"app\",\n VER: \"ver\",\n URL: \"url\",\n USER: \"user\",\n TYPE: \"type\",\n DATA: \"data\"\n },\n TYPE: {\n BUG: \"bug\"\n },\n RES: {\n OK: \"Thank you\"\n }\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/userapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Examples of User API requests:\n *\n * web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.VERIFY + '&' + UserAPI.QUERY.USER + '=' + sUser;\n */\nvar UserAPI = {\n ENDPOINT: \"/api/v1/user\",\n QUERY: {\n REQ: \"req\", // specifies a request\n USER: \"user\", // specifies a user ID\n STATE: \"state\", // specifies a state ID\n DATA: \"data\" // specifies state data\n },\n REQ: {\n CREATE: \"create\", // creates a user ID\n VERIFY: \"verify\", // requests verification of a user ID\n STORE: \"store\", // stores a machine state on the server\n LOAD: \"load\" // loads a machine state from the server\n },\n RES: {\n CODE: \"code\",\n DATA: \"data\"\n },\n CODE: {\n OK: \"ok\",\n FAIL: \"error\"\n },\n FAIL: {\n DUPLICATE: \"user already exists\",\n VERIFY: \"unable to verify user\",\n BADSTATE: \"invalid state parameter\",\n NOSTATE: \"no machine state\",\n BADLOAD: \"unable to load machine state\",\n BADSTORE: \"unable to save machine state\"\n }\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/keys.js (C) Jeff Parsons 2012-2018\n */\n\nvar Keys = {\n /*\n * Keys and/or key combinations that generate common ASCII codes.\n *\n * NOTE: If you're looking for a general-purpose ASCII code table, see Str.ASCII in strlib.js;\n * if something's missing, that's probably the more appropriate table to add it to.\n *\n * TODO: The Closure Compiler doesn't inline all references to these values, at least those with\n * quoted property names, which is why I've 'unquoted' as many of them as possible. One solution\n * would be to add mnemonics for all of them, not just the non-printable ones (eg, SPACE instead\n * of ' ', AMP instead of '&', etc.)\n */\n ASCII: {\n BREAK: 0, CTRL_A: 1, CTRL_B: 2, CTRL_C: 3, CTRL_D: 4, CTRL_E: 5, CTRL_F: 6, CTRL_G: 7,\n CTRL_H: 8, CTRL_I: 9, CTRL_J: 10, CTRL_K: 11, CTRL_L: 12, CTRL_M: 13, CTRL_N: 14, CTRL_O: 15,\n CTRL_P: 16, CTRL_Q: 17, CTRL_R: 18, CTRL_S: 19, CTRL_T: 20, CTRL_U: 21, CTRL_V: 22, CTRL_W: 23,\n CTRL_X: 24, CTRL_Y: 25, CTRL_Z: 26, ESC: 27,\n ' ': 32, '!': 33, '\"': 34, '#': 35, '$': 36, '%': 37, '&': 38, \"'\": 39,\n '(': 40, ')': 41, '*': 42, '+': 43, ',': 44, '-': 45, '.': 46, '/': 47,\n '0': 48, '1': 49, '2': 50, '3': 51, '4': 52, '5': 53, '6': 54, '7': 55,\n '8': 56, '9': 57, ':': 58, ';': 59, '<': 60, '=': 61, '>': 62, '?': 63,\n '@': 64, A: 65, B: 66, C: 67, D: 68, E: 69, F: 70, G: 71,\n H: 72, I: 73, J: 74, K: 75, L: 76, M: 77, N: 78, O: 79,\n P: 80, Q: 81, R: 82, S: 83, T: 84, U: 85, V: 86, W: 87,\n X: 88, Y: 89, Z: 90, '[': 91, '\\\\':92, ']': 93, '^': 94, '_': 95,\n '`': 96, a: 97, b: 98, c: 99, d: 100, e: 101, f: 102, g: 103,\n h: 104, i: 105, j: 106, k: 107, l: 108, m: 109, n: 110, o: 111,\n p: 112, q: 113, r: 114, s: 115, t: 116, u: 117, v: 118, w: 119,\n x: 120, y: 121, z: 122, '{':123, '|':124, '}':125, '~':126, DEL: 127\n },\n /*\n * Browser keyCodes we must pay particular attention to. For the most part, these are non-alphanumeric\n * or function keys, some which may require special treatment (eg, preventDefault() if returning false on\n * the initial keyDown event is insufficient).\n *\n * keyCodes for most common ASCII keys can simply use the appropriate ASCII code above.\n *\n * Most of these represent non-ASCII keys (eg, the LEFT arrow key), yet for some reason, browsers defined\n * them using ASCII codes (eg, the LEFT arrow key uses the ASCII code for '%' or 37).\n */\n KEYCODE: {\n /* 0x08 */ BS: 8, // BACKSPACE (ASCII.CTRL_H)\n /* 0x09 */ TAB: 9, // TAB (ASCII.CTRL_I)\n /* 0x0A */ LF: 10, // LINE-FEED (ASCII.CTRL_J) (Some Windows-based browsers used to generate this via CTRL-ENTER)\n /* 0x0D */ CR: 13, // CARRIAGE RETURN (ASCII.CTRL_M)\n /* 0x10 */ SHIFT: 16,\n /* 0x11 */ CTRL: 17,\n /* 0x12 */ ALT: 18,\n /* 0x13 */ PAUSE: 19, // PAUSE/BREAK\n /* 0x14 */ CAPS_LOCK: 20,\n /* 0x1B */ ESC: 27,\n /* 0x20 */ SPACE: 32,\n /* 0x21 */ PGUP: 33,\n /* 0x22 */ PGDN: 34,\n /* 0x23 */ END: 35,\n /* 0x24 */ HOME: 36,\n /* 0x25 */ LEFT: 37,\n /* 0x26 */ UP: 38,\n /* 0x27 */ RIGHT: 39,\n /* 0x27 */ FF_QUOTE: 39,\n /* 0x28 */ DOWN: 40,\n /* 0x2C */ FF_COMMA: 44,\n /* 0x2C */ PRTSC: 44,\n /* 0x2D */ INS: 45,\n /* 0x2E */ DEL: 46,\n /* 0x2E */ FF_PERIOD: 46,\n /* 0x2F */ FF_SLASH: 47,\n /* 0x30 */ ZERO: 48,\n /* 0x31 */ ONE: 49,\n /* 0x32 */ TWO: 50,\n /* 0x33 */ THREE: 51,\n /* 0x34 */ FOUR: 52,\n /* 0x35 */ FIVE: 53,\n /* 0x36 */ SIX: 54,\n /* 0x37 */ SEVEN: 55,\n /* 0x38 */ EIGHT: 56,\n /* 0x39 */ NINE: 57,\n /* 0x3B */ FF_SEMI: 59,\n /* 0x3D */ FF_EQUALS: 61,\n /* 0x5B */ CMD: 91, // aka WIN\n /* 0x5B */ FF_LBRACK: 91,\n /* 0x5C */ FF_BSLASH: 92,\n /* 0x5D */ RCMD: 93, // aka MENU\n /* 0x5D */ FF_RBRACK: 93,\n /* 0x60 */ NUM_0: 96,\n /* 0x60 */ NUM_INS: 96,\n /* 0x60 */ FF_BQUOTE: 96,\n /* 0x61 */ NUM_1: 97,\n /* 0x61 */ NUM_END: 97,\n /* 0x62 */ NUM_2: 98,\n /* 0x62 */ NUM_DOWN: 98,\n /* 0x63 */ NUM_3: 99,\n /* 0x63 */ NUM_PGDN: 99,\n /* 0x64 */ NUM_4: 100,\n /* 0x64 */ NUM_LEFT: 100,\n /* 0x65 */ NUM_5: 101,\n /* 0x65 */ NUM_CENTER: 101,\n /* 0x66 */ NUM_6: 102,\n /* 0x66 */ NUM_RIGHT: 102,\n /* 0x67 */ NUM_7: 103,\n /* 0x67 */ NUM_HOME: 103,\n /* 0x68 */ NUM_8: 104,\n /* 0x68 */ NUM_UP: 104,\n /* 0x69 */ NUM_9: 105,\n /* 0x69 */ NUM_PGUP: 105,\n /* 0x6A */ NUM_MUL: 106,\n /* 0x6B */ NUM_ADD: 107,\n /* 0x6D */ NUM_SUB: 109,\n /* 0x6E */ NUM_DEL: 110, // aka PERIOD\n /* 0x6F */ NUM_DIV: 111,\n /* 0x70 */ F1: 112,\n /* 0x71 */ F2: 113,\n /* 0x72 */ F3: 114,\n /* 0x73 */ F4: 115,\n /* 0x74 */ F5: 116,\n /* 0x75 */ F6: 117,\n /* 0x76 */ F7: 118,\n /* 0x77 */ F8: 119,\n /* 0x78 */ F9: 120,\n /* 0x79 */ F10: 121,\n /* 0x7A */ F11: 122,\n /* 0x7B */ F12: 123,\n /* 0x90 */ NUM_LOCK: 144,\n /* 0x91 */ SCROLL_LOCK: 145,\n /* 0xAD */ FF_DASH: 173,\n /* 0xBA */ SEMI: 186, // Firefox: 59 (FF_SEMI)\n /* 0xBB */ EQUALS: 187, // Firefox: 61 (FF_EQUALS)\n /* 0xBC */ COMMA: 188,\n /* 0xBD */ DASH: 189, // Firefox: 173 (FF_DASH)\n /* 0xBE */ PERIOD: 190,\n /* 0xBF */ SLASH: 191,\n /* 0xC0 */ BQUOTE: 192,\n /* 0xDB */ LBRACK: 219,\n /* 0xDC */ BSLASH: 220,\n /* 0xDD */ RBRACK: 221,\n /* 0xDE */ QUOTE: 222,\n /* 0xE0 */ FF_CMD: 224, // Firefox only (used for both CMD and RCMD)\n //\n // The following biases use what I'll call Decimal Coded Binary or DCB (the opposite of BCD),\n // where the thousands digit is used to store the sum of \"binary\" digits 1 and/or 2 and/or 4.\n //\n // Technically, that makes it DCO (Decimal Coded Octal), but then again, BCD should have really\n // been called HCD (Hexadecimal Coded Decimal), so if \"they\" can take liberties, so can I.\n //\n // ONDOWN is a bias we add to browser keyCodes that we want to handle on \"down\" rather than on \"press\".\n //\n ONDOWN: 1000,\n //\n // ONRIGHT is a bias we add to browser keyCodes that need to check for a \"right\" location (default is \"left\")\n //\n ONRIGHT: 2000,\n //\n // FAKE is a bias we add to signal these are fake keyCodes corresponding to internal keystroke combinations.\n // The actual values are for internal use only and merely need to be unique and used consistently.\n //\n FAKE: 4000\n },\n /*\n * The set of values that a browser may store in the 'location' property of a keyboard event object\n * which we also support.\n */\n LOCATION: {\n LEFT: 1,\n RIGHT: 2,\n NUMPAD: 3\n }\n};\n\n/*\n * Check the event object's 'location' property for a non-zero value for the following ONRIGHT keys.\n */\nKeys.KEYCODE.NUM_CR = Keys.KEYCODE.CR + Keys.KEYCODE.ONRIGHT;\n\n\n/*\n * Maps Firefox keyCodes to their more common keyCode counterparts; a number of entries in this table\n * are no longer valid (if indeed they ever were), so they've been commented out. It's likely that I\n * simply extended this table to resolve additional differences in other browsers (ie, Opera), but without\n * browser-specific checks, it's not safe to perform all the mappings shown below.\n */\nKeys.FF_KEYCODES = {};\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_SEMI] = Keys.KEYCODE.SEMI; // 59 -> 186\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_EQUALS] = Keys.KEYCODE.EQUALS; // 61 -> 187\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.KEYCODE.DASH; // 173 -> 189\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_CMD] = Keys.KEYCODE.CMD; // 224 -> 91\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_COMMA] = Keys.KEYCODE.COMMA; // 44 -> 188\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_PERIOD] = Keys.KEYCODE.PERIOD; // 46 -> 190\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_SLASH] = Keys.KEYCODE.SLASH; // 47 -> 191\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_BQUOTE] = Keys.KEYCODE.BQUOTE; // 96 -> 192\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_LBRACK = Keys.KEYCODE.LBRACK; // 91 -> 219\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_BSLASH] = Keys.KEYCODE.BSLASH; // 92 -> 220\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_RBRACK] = Keys.KEYCODE.RBRACK; // 93 -> 221\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_QUOTE] = Keys.KEYCODE.QUOTE; // 39 -> 222\n\n/*\n * Maps non-ASCII keyCodes to their ASCII counterparts\n */\nKeys.NONASCII_KEYCODES = {};\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.ASCII['-']; // 173 -> 45\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.SEMI] = Keys.ASCII[';']; // 186 -> 59\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.EQUALS] = Keys.ASCII['=']; // 187 -> 61\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.DASH] = Keys.ASCII['-']; // 189 -> 45\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.COMMA] = Keys.ASCII[',']; // 188 -> 44\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.PERIOD] = Keys.ASCII['.']; // 190 -> 46\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.SLASH] = Keys.ASCII['/']; // 191 -> 47\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.BQUOTE] = Keys.ASCII['`']; // 192 -> 96\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.LBRACK] = Keys.ASCII['[']; // 219 -> 91\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.BSLASH] = Keys.ASCII['\\\\']; // 220 -> 92\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.RBRACK] = Keys.ASCII[']']; // 221 -> 93\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.QUOTE] = Keys.ASCII[\"'\"]; // 222 -> 39\n\n/*\n * Maps unshifted keyCodes to their shifted counterparts; to be used when a shift-key is down.\n * Alphabetic characters are handled in code, since they must also take CAPS_LOCK into consideration.\n */\nKeys.SHIFTED_KEYCODES = {};\nKeys.SHIFTED_KEYCODES[Keys.ASCII['1']] = Keys.ASCII['!'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['2']] = Keys.ASCII['@'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['3']] = Keys.ASCII['#'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['4']] = Keys.ASCII['$'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['5']] = Keys.ASCII['%'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['6']] = Keys.ASCII['^'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['7']] = Keys.ASCII['&'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['8']] = Keys.ASCII['*'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['9']] = Keys.ASCII['('];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['0']] = Keys.ASCII[')'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.SEMI] = Keys.ASCII[':'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.EQUALS] = Keys.ASCII['+'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.COMMA] = Keys.ASCII['<'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.DASH] = Keys.ASCII['_'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.PERIOD] = Keys.ASCII['>'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.SLASH] = Keys.ASCII['?'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.BQUOTE] = Keys.ASCII['~'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.LBRACK] = Keys.ASCII['{'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.BSLASH] = Keys.ASCII['|'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.RBRACK] = Keys.ASCII['}'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.QUOTE] = Keys.ASCII['\"'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.ASCII['_'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_EQUALS] = Keys.ASCII['+'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_SEMI] = Keys.ASCII[':'];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/strlib.js (C) Jeff Parsons 2012-2018\n */\n\nclass Str {\n /**\n * isValidInt(s, base)\n *\n * The built-in parseInt() function has the annoying feature of returning a partial value (ie,\n * up to the point where it encounters an invalid character); eg, parseInt(\"foo\", 16) returns 0xf.\n *\n * So it's best to use our own Str.parseInt() function, which will in turn use this function to\n * validate the entire string.\n *\n * @param {string} s is the string representation of some number\n * @param {number} [base] is the radix to use (default is 10); only 2, 8, 10 and 16 are supported\n * @return {boolean} true if valid, false if invalid (or the specified base isn't supported)\n */\n static isValidInt(s, base)\n {\n if (!base || base == 10) return s.match(/^-?[0-9]+$/) !== null;\n if (base == 16) return s.match(/^-?[0-9a-f]+$/i) !== null;\n if (base == 8) return s.match(/^-?[0-7]+$/) !== null;\n if (base == 2) return s.match(/^-?[01]+$/) !== null;\n return false;\n }\n\n /**\n * parseInt(s, base)\n *\n * This is a wrapper around the built-in parseInt() function. Our wrapper recognizes certain prefixes\n * ('$' or \"0x\" for hex, '#' or \"0o\" for octal) and suffixes ('.' for decimal, 'h' for hex, 'y' for\n * binary), and then calls isValidInt() to ensure we don't convert strings that contain partial values;\n * see isValidInt() for details.\n *\n * The use of multiple prefix/suffix combinations is undefined (although for the record, we process\n * prefixes first). We do NOT support the \"0b\" prefix to indicate binary UNLESS one or more commas are\n * also present (because \"0b\" is also a valid hex sequence), and we do NOT support a single leading zero\n * to indicate octal (because such a number could also be decimal or hex). Any number of commas are\n * allowed; we remove them all before calling the built-in parseInt().\n *\n * More recently, we've added support for \"^D\", \"^O\", and \"^B\" prefixes to accommodate the base overrides\n * that the PDP-10's MACRO-10 assembly language supports (decimal, octal, and binary, respectively).\n * If this support turns out to adversely affect other debuggers, then it will have to be \"conditionalized\".\n * Similarly, we've added support for \"K\", \"M\", and \"G\" MACRO-10-style suffixes that add 3, 6, or 9 zeros\n * to the value to be parsed, respectively.\n *\n * @param {string} s is the string representation of some number\n * @param {number} [base] is the radix to use (default is 10); can be overridden by prefixes/suffixes\n * @return {number|undefined} corresponding value, or undefined if invalid\n */\n static parseInt(s, base)\n {\n var value;\n\n if (s) {\n if (!base) base = 10;\n\n var ch, chPrefix, chSuffix;\n var fCommas = (s.indexOf(',') > 0);\n if (fCommas) s = s.replace(/,/g, '');\n\n ch = chPrefix = s.charAt(0);\n if (chPrefix == '#') {\n base = 8;\n chPrefix = '';\n }\n else if (chPrefix == '$') {\n base = 16;\n chPrefix = '';\n }\n if (ch != chPrefix) {\n s = s.substr(1);\n }\n else {\n ch = chPrefix = s.substr(0, 2);\n if (chPrefix == '0b' && fCommas || chPrefix == '^B') {\n base = 2;\n chPrefix = '';\n }\n else if (chPrefix == '0o' || chPrefix == '^O') {\n base = 8;\n chPrefix = '';\n }\n else if (chPrefix == '^D') {\n base = 10;\n chPrefix = '';\n }\n else if (chPrefix == '0x') {\n base = 16;\n chPrefix = '';\n }\n if (ch != chPrefix) s = s.substr(2);\n }\n ch = chSuffix = s.slice(-1);\n if (chSuffix == 'Y' || chSuffix == 'y') {\n base = 2;\n chSuffix = '';\n }\n else if (chSuffix == '.') {\n base = 10;\n chSuffix = '';\n }\n else if (chSuffix == 'H' || chSuffix == 'h') {\n base = 16;\n chSuffix = '';\n }\n else if (chSuffix == 'K') {\n chSuffix = '000';\n }\n else if (chSuffix == 'M') {\n chSuffix = '000000';\n }\n else if (chSuffix == 'G') {\n chSuffix = '000000000';\n }\n if (ch != chSuffix) s = s.slice(0, -1) + chSuffix;\n /*\n * This adds support for the MACRO-10 binary shifting (Bn) suffix, which must be stripped from the\n * number before parsing, and then applied to the value after parsing. If n is omitted, 35 is assumed,\n * which is a net shift of zero. If n < 35, then a left shift of (35 - n) is required; if n > 35, then\n * a right shift of -(35 - n) is required.\n */\n var v, shift = 0;\n if (base <= 10) {\n var match = s.match(/(-?[0-9]+)B([0-9]*)/);\n if (match) {\n s = match[1];\n shift = 35 - ((match[2] || 35) & 0xff);\n }\n }\n if (Str.isValidInt(s, base) && !isNaN(v = parseInt(s, base))) {\n /*\n * With the need to support larger (eg, 36-bit) integers, truncating to 32 bits is no longer helpful.\n *\n * value = v|0;\n */\n if (shift) {\n /*\n * Since binary shifting is a logical operation, and since shifting by division only works properly\n * with positive numbers, we must convert a negative value to a positive value, by computing the two's\n * complement.\n */\n if (v < 0) v += Math.pow(2, 36);\n if (shift > 0) {\n v *= Math.pow(2, shift);\n } else {\n v = Math.trunc(v / Math.pow(2, -shift));\n }\n }\n value = v;\n }\n }\n return value;\n }\n\n /**\n * toBase(n, radix, cch, sPrefix, nGrouping)\n *\n * Displays the given number as an unsigned integer using the specified radix and number of digits.\n *\n * @param {number|null|undefined} n\n * @param {number} radix (ie, the base)\n * @param {number} cch (the desired number of digits)\n * @param {string} [sPrefix] (default is none)\n * @param {number} [nGrouping]\n * @return {string}\n */\n static toBase(n, radix, cch, sPrefix = \"\", nGrouping = 0)\n {\n /*\n * An initial \"falsey\" check for null takes care of both null and undefined;\n * we can't rely entirely on isNaN(), because isNaN(null) returns false, oddly enough.\n *\n * Alternatively, we could mask and shift n regardless of whether it's null/undefined/NaN,\n * since JavaScript coerces such operands to zero, but I think there's \"value\" in seeing those\n * values displayed differently.\n */\n var s = \"\";\n if (isNaN(n)) {\n n = null;\n } else if (n != null) {\n /*\n * Callers that produced an input by dividing by a power of two rather than shifting (in order\n * to access more than 32 bits) may produce a fractional result, which ordinarily we would simply\n * ignore, but if the integer portion is zero and the sign is negative, we should probably treat\n * this value as a sign-extension.\n */\n if (n < 0 && n > -1) n = -1;\n /*\n * Negative values should be two's complemented according to the number of digits; for example,\n * 12 octal digits implies an upper limit 8^12.\n */\n if (n < 0) {\n n += Math.pow(radix, cch);\n }\n if (n >= Math.pow(radix, cch)) {\n cch = Math.ceil(Math.log(n) / Math.log(radix));\n }\n }\n var g = nGrouping || -1;\n while (cch-- > 0) {\n if (!g) {\n s = ',' + s;\n g = nGrouping;\n }\n if (n == null) {\n s = '?' + s;\n } else {\n var d = n % radix;\n d += (d >= 0 && d <= 9? 0x30 : 0x41 - 10);\n s = String.fromCharCode(d) + s;\n n = Math.trunc(n / radix);\n }\n g--;\n }\n return sPrefix + s;\n }\n\n /**\n * toBin(n, cch, nGrouping)\n *\n * Converts an integer to binary, with the specified number of digits (up to a maximum of 36).\n *\n * @param {number|null|undefined} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of binary digits (0 or undefined for default of either 8, 18, or 36)\n * @param {number} [nGrouping]\n * @return {string} the binary representation of n\n */\n static toBin(n, cch, nGrouping)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.LN2) || 1;\n var v = Math.abs(n);\n if (v <= 0b11111111) {\n cch = 8;\n } else if (v <= 0b111111111111111111) {\n cch = 18;\n } else {\n cch = 36;\n }\n } else if (cch > 36) cch = 36;\n return Str.toBase(n, 2, cch, \"\", nGrouping);\n }\n\n /**\n * toBinBytes(n, cb, fPrefix)\n *\n * Converts an integer to binary, with the specified number of bytes (up to the default of 4).\n *\n * @param {number|null|undefined} n (interpreted as a 32-bit value)\n * @param {number} [cb] is the desired number of binary bytes (4 is both the default and the maximum)\n * @param {boolean} [fPrefix]\n * @return {string} the binary representation of n\n */\n static toBinBytes(n, cb, fPrefix)\n {\n var s = \"\";\n if (!cb || cb > 4) cb = 4;\n for (var i = 0; i < cb; i++) {\n if (s) s = ',' + s;\n s = Str.toBin(n & 0xff, 8) + s;\n n >>= 8;\n }\n return (fPrefix? \"0b\" : \"\") + s;\n }\n\n /**\n * toOct(n, cch, fPrefix)\n *\n * Converts an integer to octal, with the specified number of digits (default of 6; max of 12)\n *\n * You might be tempted to use the built-in n.toString(8) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw\n * an exception, whereas this function will return '?' characters.\n *\n * @param {number|null|undefined} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of octal digits (0 or undefined for default of either 6, 8, or 12)\n * @param {boolean} [fPrefix]\n * @return {string} the octal representation of n\n */\n static toOct(n, cch, fPrefix)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.log(8)) || 1;\n var v = Math.abs(n);\n if (v <= 0o777777) {\n cch = 6;\n } else if (v <= 0o77777777) {\n cch = 8;\n } else {\n cch = 12;\n }\n } else if (cch > 12) cch = 12;\n return Str.toBase(n, 8, cch, fPrefix? \"0o\" : \"\");\n }\n\n /**\n * toDec(n, cch)\n *\n * Converts an integer to decimal, with the specified number of digits (default of 5; max of 11)\n *\n * You might be tempted to use the built-in n.toString(10) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw\n * an exception, whereas this function will return '?' characters.\n *\n * @param {number|null|undefined} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of decimal digits (0 or undefined for default of either 5 or 11)\n * @return {string} the decimal representation of n\n */\n static toDec(n, cch)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.LN10) || 1;\n var v = Math.abs(n);\n if (v <= 99999) {\n cch = 5;\n } else {\n cch = 11;\n }\n } else if (cch > 11) cch = 11;\n return Str.toBase(n, 10, cch);\n }\n\n /**\n * toHex(n, cch, fPrefix)\n *\n * Converts an integer to hex, with the specified number of digits (default of 4 or 8, max of 9).\n *\n * You might be tempted to use the built-in n.toString(16) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values; for example, if n is -2147483647, then n.toString(16)\n * will return \"-7fffffff\" instead of \"80000001\". Moreover, if n is undefined, n.toString() will\n * throw an exception, whereas this function will return '?' characters.\n *\n * NOTE: The following work-around (adapted from code found on StackOverflow) would be another solution,\n * taking care of negative values, zero-padding, and upper-casing, but not null/undefined/NaN values:\n *\n * s = (n < 0? n + 0x100000000 : n).toString(16);\n * s = \"00000000\".substr(0, 8 - s.length) + s;\n * s = s.substr(0, cch).toUpperCase();\n *\n * @param {number|null|undefined} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of hex digits (0 or undefined for default of either 4, 8, or 9)\n * @param {boolean} [fPrefix]\n * @return {string} the hex representation of n\n */\n static toHex(n, cch, fPrefix)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.log(16)) || 1;\n var v = Math.abs(n);\n if (v <= 0xffff) {\n cch = 4;\n } else if (v <= 0xffffffff) {\n cch = 8;\n } else {\n cch = 9;\n }\n } else if (cch > 9) cch = 9;\n return Str.toBase(n, 16, cch, fPrefix? \"0x\" : \"\");\n }\n\n /**\n * toHexByte(b)\n *\n * Alias for Str.toHex(b, 2, true)\n *\n * @param {number|null|undefined} b is a byte value\n * @return {string} the hex representation of b\n */\n static toHexByte(b)\n {\n return Str.toHex(b, 2, true);\n }\n\n /**\n * toHexWord(w)\n *\n * Alias for Str.toHex(w, 4, true)\n *\n * @param {number|null|undefined} w is a word (16-bit) value\n * @return {string} the hex representation of w\n */\n static toHexWord(w)\n {\n return Str.toHex(w, 4, true);\n }\n\n /**\n * toHexLong(l)\n *\n * Alias for Str.toHex(l, 8, true)\n *\n * @param {number|null|undefined} l is a dword (32-bit) value\n * @return {string} the hex representation of w\n */\n static toHexLong(l)\n {\n return Str.toHex(l, 8, true);\n }\n\n /**\n * getBaseName(sFileName, fStripExt)\n *\n * This is a poor-man's version of Node's path.basename(), which Node-only components should use instead.\n *\n * Note that if fStripExt is true, this strips ANY extension, whereas path.basename() strips the extension only\n * if it matches the second parameter (eg, path.basename(\"/foo/bar/baz/asdf/quux.html\", \".html\") returns \"quux\").\n *\n * @param {string} sFileName\n * @param {boolean} [fStripExt]\n * @return {string}\n */\n static getBaseName(sFileName, fStripExt)\n {\n var sBaseName = sFileName;\n\n var i = sFileName.lastIndexOf('/');\n if (i >= 0) sBaseName = sFileName.substr(i + 1);\n\n /*\n * This next bit is a kludge to clean up names that are part of a URL that includes unsightly query parameters.\n */\n i = sBaseName.indexOf('&');\n if (i > 0) sBaseName = sBaseName.substr(0, i);\n\n if (fStripExt) {\n i = sBaseName.lastIndexOf(\".\");\n if (i > 0) {\n sBaseName = sBaseName.substring(0, i);\n }\n }\n return sBaseName;\n }\n\n /**\n * getExtension(sFileName)\n *\n * This is a poor-man's version of Node's path.extname(), which Node-only components should use instead.\n *\n * Note that we EXCLUDE the period from the returned extension, whereas path.extname() includes it.\n *\n * @param {string} sFileName\n * @return {string} the filename's extension (in lower-case and EXCLUDING the \".\"), or an empty string\n */\n static getExtension(sFileName)\n {\n var sExtension = \"\";\n var i = sFileName.lastIndexOf(\".\");\n if (i >= 0) {\n sExtension = sFileName.substr(i + 1).toLowerCase();\n }\n return sExtension;\n }\n\n /**\n * endsWith(s, sSuffix)\n *\n * @param {string} s\n * @param {string} sSuffix\n * @return {boolean} true if s ends with sSuffix, false if not\n */\n static endsWith(s, sSuffix)\n {\n return s.indexOf(sSuffix, s.length - sSuffix.length) !== -1;\n }\n\n /**\n * escapeHTML(sHTML)\n *\n * @param {string} sHTML\n * @return {string} with HTML entities \"escaped\", similar to PHP's htmlspecialchars()\n */\n static escapeHTML(sHTML)\n {\n return sHTML.replace(/[&<>\"']/g, function(m)\n {\n return Str.HTMLEscapeMap[m];\n });\n }\n\n /**\n * replace(sSearch, sReplace, s)\n *\n * The JavaScript replace() function ALWAYS interprets \"$\" specially in replacement strings, even when\n * the search string is NOT a RegExp; specifically:\n *\n * $$ Inserts a \"$\"\n * $& Inserts the matched substring\n * $` Inserts the portion of the string that precedes the matched substring\n * $' Inserts the portion of the string that follows the matched substring\n * $n Where n is a positive integer less than 100, inserts the nth parenthesized sub-match string,\n * provided the first argument was a RegExp object\n *\n * So, if a replacement string containing dollar signs passes through a series of replace() calls, untold\n * problems could result. Hence, this function, which simply uses the replacement string as-is.\n *\n * Similar to the JavaScript replace() method (when sSearch is a string), this replaces only ONE occurrence\n * (ie, the FIRST occurrence); it might be nice to add options to replace the LAST occurrence and/or ALL\n * occurrences, but we'll revisit that later.\n *\n * @param {string} sSearch\n * @param {string} sReplace\n * @param {string} s\n * @return {string}\n */\n static replace(sSearch, sReplace, s)\n {\n var i = s.indexOf(sSearch);\n if (i >= 0) {\n s = s.substr(0, i) + sReplace + s.substr(i + sSearch.length);\n }\n return s;\n }\n\n /**\n * replaceAll(sSearch, sReplace, s)\n *\n * @param {string} sSearch\n * @param {string} sReplace\n * @param {string} s\n * @return {string}\n */\n static replaceAll(sSearch, sReplace, s)\n {\n var a = {};\n a[sSearch] = sReplace;\n return Str.replaceArray(a, s);\n }\n\n /**\n * replaceArray(a, s)\n *\n * @param {Object} a\n * @param {string} s\n * @return {string}\n */\n static replaceArray(a, s)\n {\n var sMatch = \"\";\n for (var k in a) {\n /*\n * As noted in:\n *\n * http://www.regexguru.com/2008/04/escape-characters-only-when-necessary/\n *\n * inside character classes, only backslash, caret, hyphen and the closing bracket need to be\n * escaped. And in fact, if you ensure that the closing bracket is first, the caret is not first,\n * and the hyphen is last, you can avoid escaping those as well.\n */\n k = k.replace(/([\\\\[\\]*{}().+?|$])/g, \"\\\\$1\");\n sMatch += (sMatch? '|' : '') + k;\n }\n return s.replace(new RegExp('(' + sMatch + ')', \"g\"), function(m)\n {\n return a[m];\n });\n }\n\n /**\n * pad(s, cch, fPadLeft)\n *\n * NOTE: the maximum amount of padding currently supported is 40 spaces.\n *\n * @param {string} s is a string\n * @param {number} cch is desired length\n * @param {boolean} [fPadLeft] (default is padding on the right)\n * @return {string} the original string (s) with spaces padding it to the specified length\n */\n static pad(s, cch, fPadLeft)\n {\n var sPadding = \" \";\n return fPadLeft? (sPadding + s).slice(-cch) : (s + sPadding).slice(0, cch);\n }\n\n /**\n * sprintf(format, ...args)\n *\n * Copied from the CCjs project (https://github.com/jeffpar/ccjs/blob/master/lib/stdio.js) and extended.\n *\n * Far from complete, let alone sprintf-compatible, but it's adequate for the handful of sprintf-style format\n * specifiers that I use.\n *\n * @param {string} format\n * @param {...} args\n * @return {string}\n */\n static sprintf(format, ...args)\n {\n let buffer = \"\";\n let aParts = format.split(/%([-+ 0#]?)([0-9]*)(\\.?)([0-9]*)([hlL]?)([A-Za-z%])/);\n\n let iArg = 0, iPart;\n for (iPart = 0; iPart < aParts.length - 7; iPart += 7) {\n\n buffer += aParts[iPart];\n\n let arg = args[iArg++];\n let flags = aParts[iPart+1];\n let minimum = +aParts[iPart+2] || 0;\n let precision = +aParts[iPart+4] || 0;\n let conversion = aParts[iPart+6];\n let ach = null, s;\n\n switch(conversion) {\n case 'd':\n /*\n * We could use \"arg |= 0\", but there may be some value to supporting integers > 32 bits.\n * \n * Also, unlike the 'X' and 'x' hexadecimal cases, there's no need to explicitly check for a string\n * arguments, because the call to trunc() automatically coerces any string value to a (decimal) number.\n */\n arg = Math.trunc(arg);\n /* falls through */\n\n case 'f':\n s = Math.trunc(arg) + \"\";\n if (precision) {\n minimum -= (precision + 1);\n }\n if (s.length < minimum) {\n if (flags == '0') {\n if (arg < 0) minimum--;\n s = (\"0000000000\" + Math.abs(arg)).slice(-minimum);\n if (arg < 0) s = '-' + s;\n } else {\n s = (\" \" + s).slice(-minimum);\n }\n }\n if (precision) {\n arg = Math.round((arg - Math.trunc(arg)) * Math.pow(10, precision));\n s += '.' + (\"0000000000\" + Math.abs(arg)).slice(-precision);\n }\n buffer += s;\n break;\n\n case 'c':\n arg = String.fromCharCode(arg);\n /* falls through */\n\n case 's':\n if (typeof arg == \"string\") {\n while (arg.length < minimum) {\n if (flags == '-') {\n arg += ' ';\n } else {\n arg = ' ' + arg;\n }\n }\n }\n buffer += arg;\n break;\n\n case 'X':\n ach = Str.HexUpperCase;\n /* falls through */\n\n case 'x':\n if (!ach) ach = Str.HexLowerCase;\n s = \"\";\n if (typeof arg == \"string\") {\n /*\n * Since we're advised to ALWAYS pass a radix to parseInt(), we must detect explicitly\n * hex values ourselves, because using a radix of 10 with any \"0x...\" value always returns 0.\n * \n * And if the value CAN be interpreted as decimal, then we MUST interpret it as decimal, because\n * we have sprintf() calls in /modules/lib/testmon.js that depend on this code to perform decimal\n * to hex conversion. We're allowed to make our own rules here, since passing numbers in string\n * form isn't part of the sprintf \"spec\". \n */\n arg = Number.parseInt(arg, arg.match(/(^0x|[a-f])/i)? 16 : 10);\n } \n do {\n s = ach[arg & 0xf] + s;\n arg >>>= 4;\n } while (--minimum > 0 || arg);\n buffer += s;\n break;\n\n default:\n /*\n * The supported ANSI C set of conversions: \"dioxXucsfeEgGpn%\"\n */\n buffer += \"(unrecognized printf conversion %\" + conversion + \")\";\n break;\n }\n }\n\n buffer += aParts[iPart];\n return buffer;\n }\n\n /**\n * stripLeadingZeros(s, fPad)\n *\n * @param {string} s\n * @param {boolean} [fPad]\n * @return {string}\n */\n static stripLeadingZeros(s, fPad)\n {\n var cch = s.length;\n s = s.replace(/^0+([0-9A-F]+)$/i, \"$1\");\n if (fPad) s = Str.pad(s, cch, true);\n return s;\n }\n\n /**\n * trim(s)\n *\n * @param {string} s\n * @return {string}\n */\n static trim(s)\n {\n if (String.prototype.trim) {\n return s.trim();\n }\n return s.replace(/^\\s+|\\s+$/g, \"\");\n }\n\n /**\n * toASCIICode(b)\n *\n * @param {number} b\n * @return {string}\n */\n static toASCIICode(b)\n {\n var s;\n if (b != Str.ASCII.CR && b != Str.ASCII.LF) {\n s = Str.ASCIICodeMap[b];\n }\n if (s) {\n s = '<' + s + '>';\n } else {\n s = String.fromCharCode(b);\n }\n return s;\n }\n}\n\n/*\n * Map special characters to their HTML escape sequences.\n */\nStr.HTMLEscapeMap = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n};\n\n/*\n * Map \"unprintable\" ASCII codes to mnemonics, to more clearly see what's being printed.\n */\nStr.ASCIICodeMap = {\n 0x00: \"NUL\",\n 0x01: \"SOH\", // (CTRL_A) Start of Heading\n 0x02: \"STX\", // (CTRL_B) Start of Text\n 0x03: \"ETX\", // (CTRL_C) End of Text\n 0x04: \"EOT\", // (CTRL_D) End of Transmission\n 0x05: \"ENQ\", // (CTRL_E) Enquiry\n 0x06: \"ACK\", // (CTRL_F) Acknowledge\n 0x07: \"BEL\", // (CTRL_G) Bell\n 0x08: \"BS\", // (CTRL_H) Backspace\n 0x09: \"TAB\", // (CTRL_I) Horizontal Tab (aka HT)\n 0x0A: \"LF\", // (CTRL_J) Line Feed (New Line)\n 0x0B: \"VT\", // (CTRL_K) Vertical Tab\n 0x0C: \"FF\", // (CTRL_L) Form Feed (New Page)\n 0x0D: \"CR\", // (CTRL_M) Carriage Return\n 0x0E: \"SO\", // (CTRL_N) Shift Out\n 0x0F: \"SI\", // (CTRL_O) Shift In\n 0x10: \"DLE\", // (CTRL_P) Data Link Escape\n 0x11: \"XON\", // (CTRL_Q) Device Control 1 (aka DC1)\n 0x12: \"DC2\", // (CTRL_R) Device Control 2\n 0x13: \"XOFF\", // (CTRL_S) Device Control 3 (aka DC3)\n 0x14: \"DC4\", // (CTRL_T) Device Control 4\n 0x15: \"NAK\", // (CTRL_U) Negative Acknowledge\n 0x16: \"SYN\", // (CTRL_V) Synchronous Idle\n 0x17: \"ETB\", // (CTRL_W) End of Transmission Block\n 0x18: \"CAN\", // (CTRL_X) Cancel\n 0x19: \"EM\", // (CTRL_Y) End of Medium\n 0x1A: \"SUB\", // (CTRL_Z) Substitute\n 0x1B: \"ESC\", // Escape\n 0x1C: \"FS\", // File Separator\n 0x1D: \"GS\", // Group Separator\n 0x1E: \"RS\", // Record Separator\n 0x1F: \"US\", // Unit Separator\n 0x7F: \"DEL\"\n};\n\n/*\n * Refer to: https://en.wikipedia.org/wiki/Code_page_437\n */\nStr.CP437ToUnicode = [\n '\\u0000', '\\u263A', '\\u263B', '\\u2665', '\\u2666', '\\u2663', '\\u2660', '\\u2022',\n '\\u25D8', '\\u25CB', '\\u25D9', '\\u2642', '\\u2640', '\\u266A', '\\u266B', '\\u263C',\n '\\u25BA', '\\u25C4', '\\u2195', '\\u203C', '\\u00B6', '\\u00A7', '\\u25AC', '\\u21A8',\n '\\u2191', '\\u2193', '\\u2192', '\\u2190', '\\u221F', '\\u2194', '\\u25B2', '\\u25BC',\n '\\u0020', '\\u0021', '\\u0022', '\\u0023', '\\u0024', '\\u0025', '\\u0026', '\\u0027',\n '\\u0028', '\\u0029', '\\u002A', '\\u002B', '\\u002C', '\\u002D', '\\u002E', '\\u002F',\n '\\u0030', '\\u0031', '\\u0032', '\\u0033', '\\u0034', '\\u0035', '\\u0036', '\\u0037',\n '\\u0038', '\\u0039', '\\u003A', '\\u003B', '\\u003C', '\\u003D', '\\u003E', '\\u003F',\n '\\u0040', '\\u0041', '\\u0042', '\\u0043', '\\u0044', '\\u0045', '\\u0046', '\\u0047',\n '\\u0048', '\\u0049', '\\u004A', '\\u004B', '\\u004C', '\\u004D', '\\u004E', '\\u004F',\n '\\u0050', '\\u0051', '\\u0052', '\\u0053', '\\u0054', '\\u0055', '\\u0056', '\\u0057',\n '\\u0058', '\\u0059', '\\u005A', '\\u005B', '\\u005C', '\\u005D', '\\u005E', '\\u005F',\n '\\u0060', '\\u0061', '\\u0062', '\\u0063', '\\u0064', '\\u0065', '\\u0066', '\\u0067',\n '\\u0068', '\\u0069', '\\u006A', '\\u006B', '\\u006C', '\\u006D', '\\u006E', '\\u006F',\n '\\u0070', '\\u0071', '\\u0072', '\\u0073', '\\u0074', '\\u0075', '\\u0076', '\\u0077',\n '\\u0078', '\\u0079', '\\u007A', '\\u007B', '\\u007C', '\\u007D', '\\u007E', '\\u2302',\n '\\u00C7', '\\u00FC', '\\u00E9', '\\u00E2', '\\u00E4', '\\u00E0', '\\u00E5', '\\u00E7',\n '\\u00EA', '\\u00EB', '\\u00E8', '\\u00EF', '\\u00EE', '\\u00EC', '\\u00C4', '\\u00C5',\n '\\u00C9', '\\u00E6', '\\u00C6', '\\u00F4', '\\u00F6', '\\u00F2', '\\u00FB', '\\u00F9',\n '\\u00FF', '\\u00D6', '\\u00DC', '\\u00A2', '\\u00A3', '\\u00A5', '\\u20A7', '\\u0192',\n '\\u00E1', '\\u00ED', '\\u00F3', '\\u00FA', '\\u00F1', '\\u00D1', '\\u00AA', '\\u00BA',\n '\\u00BF', '\\u2310', '\\u00AC', '\\u00BD', '\\u00BC', '\\u00A1', '\\u00AB', '\\u00BB',\n '\\u2591', '\\u2592', '\\u2593', '\\u2502', '\\u2524', '\\u2561', '\\u2562', '\\u2556',\n '\\u2555', '\\u2563', '\\u2551', '\\u2557', '\\u255D', '\\u255C', '\\u255B', '\\u2510',\n '\\u2514', '\\u2534', '\\u252C', '\\u251C', '\\u2500', '\\u253C', '\\u255E', '\\u255F',\n '\\u255A', '\\u2554', '\\u2569', '\\u2566', '\\u2560', '\\u2550', '\\u256C', '\\u2567',\n '\\u2568', '\\u2564', '\\u2565', '\\u2559', '\\u2558', '\\u2552', '\\u2553', '\\u256B',\n '\\u256A', '\\u2518', '\\u250C', '\\u2588', '\\u2584', '\\u258C', '\\u2590', '\\u2580',\n '\\u03B1', '\\u00DF', '\\u0393', '\\u03C0', '\\u03A3', '\\u03C3', '\\u00B5', '\\u03C4',\n '\\u03A6', '\\u0398', '\\u03A9', '\\u03B4', '\\u221E', '\\u03C6', '\\u03B5', '\\u2229',\n '\\u2261', '\\u00B1', '\\u2265', '\\u2264', '\\u2320', '\\u2321', '\\u00F7', '\\u2248',\n '\\u00B0', '\\u2219', '\\u00B7', '\\u221A', '\\u207F', '\\u00B2', '\\u25A0', '\\u00A0'\n];\n\n/*\n * TODO: Future home of a complete ASCII table.\n */\nStr.ASCII = {\n LF: 0x0A,\n CR: 0x0D\n};\n\nStr.TYPES = {\n NULL: 0,\n BYTE: 1,\n WORD: 2,\n DWORD: 3,\n NUMBER: 4,\n STRING: 5,\n BOOLEAN: 6,\n OBJECT: 7,\n ARRAY: 8\n};\n\nStr.HexLowerCase = \"0123456789abcdef\";\nStr.HexUpperCase = \"0123456789ABCDEF\";\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/usrlib.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @typedef {{\n * mask: number,\n * shift: number\n * }}\n */\nvar BitField;\n\n/**\n * @typedef {Object.<BitField>}\n */\nvar BitFields;\n\nclass Usr {\n /**\n * binarySearch(a, v, fnCompare)\n *\n * @param {Array} a is an array\n * @param {number|string|Array|Object} v\n * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]\n * @return {number} the index of matching entry if non-negative, otherwise the index of the insertion point\n */\n static binarySearch(a, v, fnCompare)\n {\n var left = 0;\n var right = a.length;\n var found = 0;\n if (fnCompare === undefined) {\n fnCompare = function(a, b)\n {\n return a > b ? 1 : a < b ? -1 : 0;\n };\n }\n while (left < right) {\n var middle = (left + right) >> 1;\n var compareResult;\n compareResult = fnCompare(v, a[middle]);\n if (compareResult > 0) {\n left = middle + 1;\n } else {\n right = middle;\n found = !compareResult;\n }\n }\n return found ? left : ~left;\n }\n\n /**\n * binaryInsert(a, v, fnCompare)\n *\n * If element v already exists in array a, the array is unchanged (we don't allow duplicates); otherwise, the\n * element is inserted into the array at the appropriate index.\n *\n * @param {Array} a is an array\n * @param {number|string|Array|Object} v is the value to insert\n * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]\n */\n static binaryInsert(a, v, fnCompare)\n {\n var index = Usr.binarySearch(a, v, fnCompare);\n if (index < 0) {\n a.splice(-(index + 1), 0, v);\n }\n }\n\n /**\n * getTimestamp()\n *\n * @return {string} timestamp containing the current date and time (\"yyyy-mm-dd hh:mm:ss\")\n */\n static getTimestamp()\n {\n return Usr.formatDate(\"Y-m-d H:i:s\");\n }\n\n /**\n * getMonthDays(nMonth, nYear)\n *\n * Note that if we're being called on behalf of the RTC, its year is always truncated to two digits (mod 100),\n * so we have no idea what century the year 0 might refer to. When using the normal leap-year formula, 0 fails\n * the mod 100 test but passes the mod 400 test, so as far as the RTC is concerned, every century year is a leap\n * year. Since we're most likely dealing with the year 2000, that's fine, since 2000 was also a leap year.\n *\n * TODO: There IS a separate CMOS byte that's supposed to be set to CMOS_ADDR.CENTURY_DATE; it's always BCD,\n * so theoretically it will contain values like 0x19 or 0x20 (for the 20th and 21st centuries, respectively), and\n * we could add that as another parameter to this function, to improve the accuracy, but that would go beyond what\n * a real RTC actually does.\n *\n * @param {number} nMonth (1-12)\n * @param {number} nYear (normally a 4-digit year, but it may also be mod 100)\n * @return {number} the maximum (1-based) day allowed for the specified month and year\n */\n static getMonthDays(nMonth, nYear)\n {\n var nDays = Usr.aMonthDays[nMonth - 1];\n if (nDays == 28) {\n if ((nYear % 4) === 0 && ((nYear % 100) || (nYear % 400) === 0)) {\n nDays++;\n }\n }\n return nDays;\n }\n\n /**\n * formatDate(sFormat, date)\n *\n * @param {string} sFormat (eg, \"F j, Y\", \"Y-m-d H:i:s\")\n * @param {Date} [date] (default is the current time)\n * @return {string}\n *\n * Supported identifiers in sFormat include:\n *\n * a: lowercase ante meridiem and post meridiem (am or pm)\n * d: day of the month, 2 digits with leading zeros (01,02,...,31)\n * D: 3-letter day of the week (\"Sun\",\"Mon\",...,\"Sat\")\n * F: month (\"January\",\"February\",...,\"December\")\n * g: hour in 12-hour format, without leading zeros (1,2,...,12)\n * h: hour in 24-hour format, without leading zeros (0,1,...,23)\n * H: hour in 24-hour format, with leading zeros (00,01,...,23)\n * i: minutes, with leading zeros (00,01,...,59)\n * j: day of the month, without leading zeros (1,2,...,31)\n * l: day of the week (\"Sunday\",\"Monday\",...,\"Saturday\")\n * m: month, with leading zeros (01,02,...,12)\n * M: 3-letter month (\"Jan\",\"Feb\",...,\"Dec\")\n * n: month, without leading zeros (1,2,...,12)\n * s: seconds, with leading zeros (00,01,...,59)\n * y: 2-digit year (eg, 14)\n * Y: 4-digit year (eg, 2014)\n *\n * For more inspiration, see: http://php.net/manual/en/function.date.php (of which we support ONLY a subset).\n */\n static formatDate(sFormat, date)\n {\n var sDate = \"\";\n if (!date) date = new Date();\n var iHour = date.getHours();\n var iDay = date.getDate();\n var iMonth = date.getMonth() + 1;\n for (var i = 0; i < sFormat.length; i++) {\n var ch;\n switch ((ch = sFormat.charAt(i))) {\n case 'a':\n sDate += (iHour < 12 ? \"am\" : \"pm\");\n break;\n case 'd':\n sDate += ('0' + iDay).slice(-2);\n break;\n case 'D':\n sDate += Usr.asDays[date.getDay()].substr(0, 3);\n break;\n case 'F':\n sDate += Usr.asMonths[iMonth - 1];\n break;\n case 'g':\n sDate += (!iHour ? 12 : (iHour > 12 ? iHour - 12 : iHour));\n break;\n case 'h':\n sDate += iHour;\n break;\n case 'H':\n sDate += ('0' + iHour).slice(-2);\n break;\n case 'i':\n sDate += ('0' + date.getMinutes()).slice(-2);\n break;\n case 'j':\n sDate += iDay;\n break;\n case 'l':\n sDate += Usr.asDays[date.getDay()];\n break;\n case 'm':\n sDate += ('0' + iMonth).slice(-2);\n break;\n case 'M':\n sDate += Usr.asMonths[iMonth - 1].substr(0, 3);\n break;\n case 'n':\n sDate += iMonth;\n break;\n case 's':\n sDate += ('0' + date.getSeconds()).slice(-2);\n break;\n case 'y':\n sDate += (\"\" + date.getFullYear()).slice(-2);\n break;\n case 'Y':\n sDate += date.getFullYear();\n break;\n default:\n sDate += ch;\n break;\n }\n }\n return sDate;\n }\n\n /**\n * defineBitFields(bfs)\n *\n * Prepares a bit field definition for use with getBitField() and setBitField(); eg:\n *\n * var bfs = Usr.defineBitFields({num:20, count:8, btmod:1, type:3});\n *\n * The above defines a set of bit fields containing four fields: num (bits 0-19), count (bits 20-27), btmod (bit 28), and type (bits 29-31).\n *\n * Usr.setBitField(bfs.num, n, 1);\n *\n * The above set bit field \"bfs.num\" in numeric variable \"n\" to the value 1.\n *\n * @param {Object} bfs\n * @return {BitFields}\n */\n static defineBitFields(bfs)\n {\n var bit = 0;\n for (var f in bfs) {\n var width = bfs[f];\n var mask = ((1 << width) - 1) << bit;\n bfs[f] = {mask: mask, shift: bit};\n bit += width;\n }\n return bfs;\n }\n\n /**\n * initBitFields(bfs, ...)\n *\n * @param {BitFields} bfs\n * @param {...number} var_args\n * @return {number} a value containing all supplied bit fields\n */\n static initBitFields(bfs, var_args)\n {\n var v = 0, i = 1;\n for (var f in bfs) {\n if (i >= arguments.length) break;\n v = Usr.setBitField(bfs[f], v, arguments[i++]);\n }\n return v;\n }\n\n /**\n * getBitField(bf, v)\n *\n * @param {BitField} bf\n * @param {number} v is a value containing bit fields\n * @return {number} the value of the bit field in v defined by bf\n */\n static getBitField(bf, v)\n {\n return (v & bf.mask) >> bf.shift;\n }\n\n /**\n * setBitField(bf, v, n)\n *\n * @param {BitField} bf\n * @param {number} v is a value containing bit fields\n * @param {number} n is a value to store in v in the bit field defined by bf\n * @return {number} updated v\n */\n static setBitField(bf, v, n)\n {\n return (v & ~bf.mask) | ((n << bf.shift) & bf.mask);\n }\n\n /**\n * indexOf(a, t, i)\n *\n * Use this instead of Array.prototype.indexOf() if you can't be sure the browser supports it.\n *\n * @param {Array} a\n * @param {*} t\n * @param {number} [i]\n * @returns {number}\n */\n static indexOf(a, t, i)\n {\n if (Array.prototype.indexOf) {\n return a.indexOf(t, i);\n }\n i = i || 0;\n if (i < 0) i += a.length;\n if (i < 0) i = 0;\n for (var n = a.length; i < n; i++) {\n if (i in a && a[i] === t) return i;\n }\n return -1;\n }\n}\n\nUsr.asDays = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\nUsr.asMonths = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\nUsr.aMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\n/**\n * getTime()\n *\n * @return {number} the current time, in milliseconds\n */\nUsr.getTime = Date.now || function() { return +new Date(); };\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/weblib.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * According to http://www.w3schools.com/jsref/jsref_obj_global.asp, these are the *global* properties\n * and functions of JavaScript-in-the-Browser:\n *\n * Property Description\n * ---\n * Infinity A numeric value that represents positive/negative infinity\n * NaN \"Not-a-Number\" value\n * undefined Indicates that a variable has not been assigned a value\n *\n * Function Description\n * ---\n * decodeURI() Decodes a URI\n * decodeURIComponent() Decodes a URI component\n * encodeURI() Encodes a URI\n * encodeURIComponent() Encodes a URI component\n * escape() Deprecated in version 1.5. Use encodeURI() or encodeURIComponent() instead\n * eval() Evaluates a string and executes it as if it was script code\n * isFinite() Determines whether a value is a finite, legal number\n * isNaN() Determines whether a value is an illegal number\n * Number() Converts an object's value to a number\n * parseFloat() Parses a string and returns a floating point number\n * parseInt() Parses a string and returns an integer\n * String() Converts an object's value to a string\n * unescape() Deprecated in version 1.5. Use decodeURI() or decodeURIComponent() instead\n *\n * And according to http://www.w3schools.com/jsref/obj_window.asp, these are the properties and functions\n * of the *window* object.\n *\n * Property Description\n * ---\n * closed Returns a Boolean value indicating whether a window has been closed or not\n * defaultStatus Sets or returns the default text in the statusbar of a window\n * document Returns the Document object for the window (See Document object)\n * frames Returns an array of all the frames (including iframes) in the current window\n * history Returns the History object for the window (See History object)\n * innerHeight Returns the inner height of a window's content area\n * innerWidth Returns the inner width of a window's content area\n * length Returns the number of frames (including iframes) in a window\n * location Returns the Location object for the window (See Location object)\n * name Sets or returns the name of a window\n * navigator Returns the Navigator object for the window (See Navigator object)\n * opener Returns a reference to the window that created the window\n * outerHeight Returns the outer height of a window, including toolbars/scrollbars\n * outerWidth Returns the outer width of a window, including toolbars/scrollbars\n * pageXOffset Returns the pixels the current document has been scrolled (horizontally) from the upper left corner of the window\n * pageYOffset Returns the pixels the current document has been scrolled (vertically) from the upper left corner of the window\n * parent Returns the parent window of the current window\n * screen Returns the Screen object for the window (See Screen object)\n * screenLeft Returns the x coordinate of the window relative to the screen\n * screenTop Returns the y coordinate of the window relative to the screen\n * screenX Returns the x coordinate of the window relative to the screen\n * screenY Returns the y coordinate of the window relative to the screen\n * self Returns the current window\n * status Sets or returns the text in the statusbar of a window\n * top Returns the topmost browser window\n *\n * Method Description\n * ---\n * alert() Displays an alert box with a message and an OK button\n * atob() Decodes a base-64 encoded string\n * blur() Removes focus from the current window\n * btoa() Encodes a string in base-64\n * clearInterval() Clears a timer set with setInterval()\n * clearTimeout() Clears a timer set with setTimeout()\n * close() Closes the current window\n * confirm() Displays a dialog box with a message and an OK and a Cancel button\n * createPopup() Creates a pop-up window\n * focus() Sets focus to the current window\n * moveBy() Moves a window relative to its current position\n * moveTo() Moves a window to the specified position\n * open() Opens a new browser window\n * print() Prints the content of the current window\n * prompt() Displays a dialog box that prompts the visitor for input\n * resizeBy() Resizes the window by the specified pixels\n * resizeTo() Resizes the window to the specified width and height\n * scroll() This method has been replaced by the scrollTo() method.\n * scrollBy() Scrolls the content by the specified number of pixels\n * scrollTo() Scrolls the content to the specified coordinates\n * setInterval() Calls a function or evaluates an expression at specified intervals (in milliseconds)\n * setTimeout() Calls a function or evaluates an expression after a specified number of milliseconds\n * stop() Stops the window from loading\n */\n\nclass Web {\n /**\n * log(s, type)\n *\n * For diagnostic output only. DEBUG must be true (or \"--debug\" specified via the command-line)\n * for Component.log() to display anything.\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n static log(s, type)\n {\n Component.log(s, type);\n }\n\n /**\n * notice(s, fPrintOnly, id)\n *\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n */\n static notice(s, fPrintOnly, id)\n {\n Component.notice(s, fPrintOnly, id);\n }\n\n /**\n * alertUser(sMessage)\n * \n * NOTE: Legacy function for older modules (eg, DiskDump); see Component.alertUser().\n *\n * @param {string} sMessage\n */\n static alertUser(sMessage)\n {\n if (window) {\n window.alert(sMessage);\n } else {\n Web.log(sMessage);\n }\n }\n\n /**\n * getResource(sURL, type, fAsync, done, progress)\n *\n * Request the specified resource (sURL), and once the request is complete, notify done().\n *\n * If fAsync is true, a done() callback should ALWAYS be supplied; otherwise, you'll have no\n * idea when the request is complete or what the response was. done() is passed three parameters:\n *\n * done(sURL, resource, nErrorCode)\n *\n * If nErrorCode is zero, resource should contain the requested data; otherwise, an error occurred.\n *\n * If type is set to a string, that string can be used to control the response format;\n * by default, the response format is plain text, but you can specify \"arraybuffer\" to request arbitrary\n * binary data, in which case the returned resource will be a ArrayBuffer rather than a string.\n *\n * @param {string} sURL\n * @param {string|Object|null} [type] (object for POST request, otherwise type of GET request)\n * @param {boolean} [fAsync] is true for an asynchronous request; false otherwise (MUST be set for IE)\n * @param {function(string,string,number)} [done]\n * @param {function(number)} [progress]\n * @return {Array|null} Array containing [resource, nErrorCode], or null if no response available (yet)\n */\n static getResource(sURL, type = \"text\", fAsync = false, done, progress)\n {\n var nErrorCode = 0, resource = null, response = null;\n\n if (typeof resources == 'object' && (resource = resources[sURL])) {\n if (done) done(sURL, resource, nErrorCode);\n return [resource, nErrorCode];\n }\n else if (fAsync && typeof resources == 'function') {\n resources(sURL, function(resource, nErrorCode)\n {\n if (done) done(sURL, resource, nErrorCode);\n });\n return response;\n }\n\n if (!DEBUG && !NODE) {\n /*\n * TODO: Perhaps it's time for our code in netlib.js to finally add support for HTTPS; for now\n * though, it's just as well that the NODE environment assumes all resources are available locally.\n */\n sURL = sURL.replace(/^\\/(pcjs-disks|private-disks)\\//, \"https://jeffpar.github.io/$1/\");\n }\n else {\n /*\n * The larger resources we put on archive.pcjs.org should also be available locally.\n *\n * NOTE: \"http://archive.pcjs.org\" is now \"https://s3-us-west-2.amazonaws.com/archive.pcjs.org\"\n */\n sURL = sURL.replace(/^(http:\\/\\/archive\\.pcjs\\.org|https:\\/\\/s3-us-west-2\\.amazonaws\\.com\\/archive\\.pcjs\\.org)(\\/.*)\\/([^\\/]*)$/, \"$2/archive/$3\");\n sURL = sURL.replace(/^https:\\/\\/jeffpar\\.github\\.io\\/(pcjs-disks|private-disks)\\/(.*)$/, \"/$1/$2\");\n }\n\n\n var request = (window.XMLHttpRequest? new window.XMLHttpRequest() : new window.ActiveXObject(\"Microsoft.XMLHTTP\"));\n var fArrayBuffer = false, fXHR2 = (typeof request.responseType === 'string');\n \n var callback = function() {\n if (request.readyState !== 4) {\n if (progress) progress(1);\n return null;\n }\n /*\n * The following line was recommended for WebKit, as a work-around to prevent the handler firing multiple\n * times when debugging. Unfortunately, that's not the only XMLHttpRequest problem that occurs when\n * debugging, so I think the WebKit problem is deeper than that. When we have multiple XMLHttpRequests\n * pending, any debugging activity means most of them simply get dropped on floor, so what may actually be\n * happening are mis-notifications rather than redundant notifications.\n *\n * request.onreadystatechange = undefined;\n */\n /*\n * If the request failed due to, say, a CORS policy denial; eg:\n * \n * Failed to load http://www.allbootdisks.com/downloads/Disks/Windows_95_Boot_Disk_Download48/Diskette%20Images/Windows95a.img:\n * Redirect from 'http://www.allbootdisks.com/downloads/Disks/Windows_95_Boot_Disk_Download48/Diskette%20Images/Windows95a.img' to\n * 'http://www.allbootdisks.com/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.\n * Origin 'http://pcjs:8088' is therefore not allowed access.\n * \n * and our request type was \"arraybuffer\", attempting to access responseText may trigger an exception; eg:\n * \n * Uncaught DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's\n * 'responseType' is '' or 'text' (was 'arraybuffer').\n * \n * We could tiptoe around these potential landmines, but the safest thing to do is wrap this code with try/catch.\n */\n try {\n resource = fArrayBuffer? request.response : request.responseText;\n } catch(err) {\n if (MAXDEBUG) Web.log(\"xmlHTTPRequest(\" + sURL + \") exception: \" + err.message);\n }\n /*\n * The normal \"success\" case is a non-null resource and an HTTP status code of 200, but when loading files from the\n * local file system (ie, when using the \"file:\" protocol), we have to be a bit more flexible.\n */\n if (resource != null && (request.status == 200 || !request.status && resource.length && Web.getHostProtocol() == \"file:\")) {\n if (MAXDEBUG) Web.log(\"xmlHTTPRequest(\" + sURL + \"): returned \" + resource.length + \" bytes\");\n }\n else {\n nErrorCode = request.status || -1;\n Web.log(\"xmlHTTPRequest(\" + sURL + \"): error code \" + nErrorCode);\n }\n if (progress) progress(2);\n if (done) done(sURL, resource, nErrorCode);\n return [resource, nErrorCode];\n };\n \n if (fAsync) {\n request.onreadystatechange = callback;\n }\n\n if (progress) progress(0);\n\n if (type && typeof type == \"object\") {\n var sPost = \"\";\n for (var p in type) {\n if (!type.hasOwnProperty(p)) continue;\n if (sPost) sPost += \"&\";\n sPost += p + '=' + encodeURIComponent(type[p]);\n }\n sPost = sPost.replace(/%20/g, '+');\n if (MAXDEBUG) Web.log(\"Web.getResource(POST \" + sURL + \"): \" + sPost.length + \" bytes\");\n request.open(\"POST\", sURL, fAsync);\n request.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\n request.send(sPost);\n } else {\n if (MAXDEBUG) Web.log(\"Web.getResource(GET \" + sURL + \")\");\n request.open(\"GET\", sURL, fAsync);\n if (type == \"arraybuffer\") {\n if (fXHR2) {\n fArrayBuffer = true;\n request.responseType = type;\n } else {\n request.overrideMimeType(\"text/plain; charset=x-user-defined\");\n }\n }\n request.send();\n }\n\n if (!fAsync) {\n request.readyState = 4; // this may already be set for synchronous requests, but I don't want to take any chances \n response = callback();\n }\n return response;\n }\n\n /**\n * parseMemoryResource(sURL, sData)\n *\n * This converts a variety of JSON-style data streams into an Object with the following properties:\n *\n * aBytes\n * aSymbols\n * addrLoad\n * addrExec\n *\n * If the source data contains a 'bytes' array, it's passed through to 'aBytes'; alternatively, if\n * it contains a 'words' array, the values are converted from 16-bit to 8-bit and stored in 'aBytes',\n * and if it contains a 'longs' array, the values are converted from 32-bit longs into bytes and\n * stored in 'aBytes'.\n *\n * Alternatively, if the source data contains a 'data' array, we simply pass that through to the output\n * object as:\n *\n * aData\n *\n * @param {string} sURL\n * @param {string} sData\n * @return {Object|null} (resource)\n */\n static parseMemoryResource(sURL, sData)\n {\n var i;\n var resource = {\n aBytes: null,\n aSymbols: null,\n addrLoad: null,\n addrExec: null\n };\n\n if (sData.charAt(0) == \"[\" || sData.charAt(0) == \"{\") {\n try {\n var a, ib, data;\n\n if (sData.substr(0, 1) == \"<\") { // if the \"data\" begins with a \"<\"...\n /*\n * Early server configs reported an error (via the nErrorCode parameter) if a tape URL was invalid,\n * but more recent server configs now display a somewhat friendlier HTML error page. The downside,\n * however, is that the original error has been buried, and we've received \"data\" that isn't actually\n * tape data. So if the data we've received appears to be \"HTML-like\", we treat it as an error message.\n */\n throw new Error(sData);\n }\n\n /*\n * TODO: IE9 is rather unfriendly and restrictive with regard to how much data it's willing to\n * eval(). In particular, the 10Mb disk image we use for the Windows 1.01 demo config fails in\n * IE9 with an \"Out of memory\" exception. One work-around would be to chop the data into chunks\n * (perhaps one track per chunk, using regular expressions) and then manually re-assemble it.\n *\n * However, it turns out that using JSON.parse(sDiskData) instead of eval(\"(\" + sDiskData + \")\")\n * is a much easier fix. The only drawback is that we must first quote any unquoted property names\n * and remove any comments, because while eval() was cool with them, JSON.parse() is more particular;\n * the following RegExp replacements take care of those requirements.\n *\n * The use of hex values is something else that eval() was OK with, but JSON.parse() is not, and\n * while I've stopped using hex values in DumpAPI responses (at least when \"format=json\" is specified),\n * I can't guarantee they won't show up in \"legacy\" images, and there's no simple RegExp replacement\n * for transforming hex values into decimal values, so I cop out and fall back to eval() if I detect\n * any hex prefixes (\"0x\") in the sequence. Ditto for error messages, which appear like so:\n *\n * [\"unrecognized disk path: test.img\"]\n */\n if (sData.indexOf(\"0x\") < 0 && sData.indexOf(\"0o\") < 0 && sData.substr(0, 2) != '[\"') {\n data = JSON.parse(sData.replace(/([a-z]+):/gm, '\"$1\":').replace(/\\/\\/[^\\n]*/gm, \"\"));\n } else {\n data = eval(\"(\" + sData + \")\");\n }\n\n resource.addrLoad = data['load'];\n resource.addrExec = data['exec'];\n\n if (a = data['bytes']) {\n resource.aBytes = a;\n }\n else if (a = data['words']) {\n /*\n * Convert all words into bytes\n */\n resource.aBytes = new Array(a.length * 2);\n for (i = 0, ib = 0; i < a.length; i++) {\n resource.aBytes[ib++] = a[i] & 0xff;\n resource.aBytes[ib++] = (a[i] >> 8) & 0xff;\n\n }\n }\n else if (a = data['longs']) {\n /*\n * Convert all dwords (longs) into bytes\n */\n resource.aBytes = new Array(a.length * 4);\n for (i = 0, ib = 0; i < a.length; i++) {\n resource.aBytes[ib++] = a[i] & 0xff;\n resource.aBytes[ib++] = (a[i] >> 8) & 0xff;\n resource.aBytes[ib++] = (a[i] >> 16) & 0xff;\n resource.aBytes[ib++] = (a[i] >> 24) & 0xff;\n }\n }\n else if (a = data['data']) {\n resource.aData = a;\n }\n else {\n resource.aBytes = data;\n }\n\n if (resource.aBytes) {\n if (!resource.aBytes.length) {\n Component.error(\"Empty resource: \" + sURL);\n resource = null;\n }\n else if (resource.aBytes.length == 1) {\n Component.error(resource.aBytes[0]);\n resource = null;\n }\n }\n resource.aSymbols = data['symbols'];\n\n } catch (e) {\n Component.error(\"Resource data error (\" + sURL + \"): \" + e.message);\n resource = null;\n }\n }\n else {\n /*\n * Parse the data manually; we assume it's a series of hex byte-values separated by whitespace.\n */\n var ab = [];\n var sHexData = sData.replace(/\\n/gm, \" \").replace(/ +$/, \"\");\n var asHexData = sHexData.split(\" \");\n for (i = 0; i < asHexData.length; i++) {\n var n = parseInt(asHexData[i], 16);\n if (isNaN(n)) {\n Component.error(\"Resource data error (\" + sURL + \"): invalid hex byte (\" + asHexData[i] + \")\");\n break;\n }\n ab.push(n & 0xff);\n }\n if (i == asHexData.length) resource.aBytes = ab;\n }\n return resource;\n }\n\n /**\n * sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)\n *\n * Send a report (eg, bug report) to the server.\n *\n * @param {string} sApp (eg, \"PCjs\")\n * @param {string} sVer (eg, \"1.02\")\n * @param {string} sURL (eg, \"/devices/pc/machine/5150/mda/64kb/machine.xml\")\n * @param {string} sUser (ie, the user key, if any)\n * @param {string} sType (eg, \"bug\"); one of ReportAPI.TYPE.*\n * @param {string} sReport (eg, unparsed state data)\n * @param {string} [sHostName] (default is http://SITEHOST)\n */\n static sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)\n {\n var dataPost = {};\n dataPost[ReportAPI.QUERY.APP] = sApp;\n dataPost[ReportAPI.QUERY.VER] = sVer;\n dataPost[ReportAPI.QUERY.URL] = sURL;\n dataPost[ReportAPI.QUERY.USER] = sUser;\n dataPost[ReportAPI.QUERY.TYPE] = sType;\n dataPost[ReportAPI.QUERY.DATA] = sReport;\n var sReportURL = (sHostName? sHostName : \"http://\" + SITEHOST) + ReportAPI.ENDPOINT;\n Web.getResource(sReportURL, dataPost, true);\n }\n\n /**\n * getHost()\n *\n * @return {string}\n */\n static getHost()\n {\n return (\"http://\" + (window? window.location.host : SITEHOST));\n }\n\n /**\n * getHostURL()\n *\n * @return {string|null}\n */\n static getHostURL()\n {\n return (window? window.location.href : null);\n }\n\n /**\n * getHostProtocol()\n *\n * @return {string}\n */\n static getHostProtocol()\n {\n return (window? window.location.protocol : \"file:\");\n }\n\n /**\n * getUserAgent()\n *\n * @return {string}\n */\n static getUserAgent()\n {\n return (window? window.navigator.userAgent : \"\");\n }\n\n /**\n * hasLocalStorage\n *\n * true if localStorage support exists, is enabled, and works; false otherwise\n *\n * @return {boolean}\n */\n static hasLocalStorage()\n {\n if (Web.fLocalStorage == null) {\n var f = false;\n if (window) {\n try {\n window.localStorage.setItem(Web.sLocalStorageTest, Web.sLocalStorageTest);\n f = (window.localStorage.getItem(Web.sLocalStorageTest) == Web.sLocalStorageTest);\n window.localStorage.removeItem(Web.sLocalStorageTest);\n } catch (e) {\n Web.logLocalStorageError(e);\n f = false;\n }\n }\n Web.fLocalStorage = f;\n }\n return Web.fLocalStorage;\n }\n\n /**\n * logLocalStorageError(e)\n *\n * @param {Error} e is an exception\n */\n static logLocalStorageError(e)\n {\n Web.log(e.message, \"localStorage error\");\n }\n\n /**\n * getLocalStorageItem(sKey)\n *\n * Returns the requested key value, or null if the key does not exist, or undefined if localStorage is not available\n *\n * @param {string} sKey\n * @return {string|null|undefined} sValue\n */\n static getLocalStorageItem(sKey)\n {\n var sValue;\n if (window) {\n try {\n sValue = window.localStorage.getItem(sKey);\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n }\n return sValue;\n }\n\n /**\n * setLocalStorageItem(sKey, sValue)\n *\n * @param {string} sKey\n * @param {string} sValue\n * @return {boolean} true if localStorage is available, false if not\n */\n static setLocalStorageItem(sKey, sValue)\n {\n try {\n window.localStorage.setItem(sKey, sValue);\n return true;\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n return false;\n }\n\n /**\n * removeLocalStorageItem(sKey)\n *\n * @param {string} sKey\n */\n static removeLocalStorageItem(sKey)\n {\n try {\n window.localStorage.removeItem(sKey);\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n }\n\n /**\n * getLocalStorageKeys()\n *\n * @return {Array}\n */\n static getLocalStorageKeys()\n {\n var a = [];\n try {\n for (var i = 0, c = window.localStorage.length; i < c; i++) {\n a.push(window.localStorage.key(i));\n }\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n return a;\n }\n\n /**\n * reloadPage()\n */\n static reloadPage()\n {\n if (window) window.location.reload();\n }\n\n /**\n * isUserAgent(s)\n *\n * Check the browser's user-agent string for the given substring; \"iOS\" and \"MSIE\" are special values you can\n * use that will match any iOS or MSIE browser, respectively (even IE11, in the case of \"MSIE\").\n *\n * 2013-11-06: In a questionable move, MSFT changed the user-agent reported by IE11 on Windows 8.1, eliminating\n * the \"MSIE\" string (which MSDN calls a \"version token\"; see http://msdn.microsoft.com/library/ms537503.aspx);\n * they say \"public websites should rely on feature detection, rather than browser detection, in order to design\n * their sites for browsers that don't support the features used by the website.\" So, in IE11, we get a user-agent\n * that tries to fool apps into thinking the browser is more like WebKit or Gecko:\n *\n * Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko\n *\n * That's a nice idea, but in the meantime, they hosed the XSL transform code in embed.js, which contained\n * some very critical browser-specific code; turning on IE's \"Compatibility Mode\" didn't help either, because\n * that's a sledgehammer solution which restores the old user-agent string but also disables other features like\n * HTML5 canvas support. As an interim solution, I'm treating any \"MSIE\" check as a check for either \"MSIE\" or\n * \"Trident\".\n *\n * UPDATE: I've since found ways to make the code in embed.js more browser-agnostic, so for now, there's isn't\n * any code that cares about \"MSIE\", but I've left the change in place, because I wouldn't be surprised if I'll\n * need more IE-specific code in the future, perhaps for things like copy/paste functionality, or mouse capture.\n *\n * @param {string} s is a substring to search for in the user-agent; as noted above, \"iOS\" and \"MSIE\" are special values\n * @return {boolean} is true if the string was found, false if not\n */\n static isUserAgent(s)\n {\n if (window) {\n var userAgent = Web.getUserAgent();\n /*\n * Here's one case where we have to be careful with Component, because when isUserAgent() is called by\n * the init code below, component.js hasn't been loaded yet. The simple solution for now is to remove the call.\n *\n * Web.log(\"agent: \" + userAgent);\n *\n * And yes, it would be pointless to use the conditional (?) operator below, if not for the Google Closure\n * Compiler (v20130823) failing to detect the entire expression as a boolean.\n */\n return s == \"iOS\" && !!userAgent.match(/(iPod|iPhone|iPad)/) && !!userAgent.match(/AppleWebKit/) || s == \"MSIE\" && !!userAgent.match(/(MSIE|Trident)/) || (userAgent.indexOf(s) >= 0);\n }\n return false;\n }\n\n /**\n * isMobile(sDevice)\n *\n * Checks the URL for a \"mobile\" parameter, and failing that, checks the browser's user-agent string for the\n * substring \"Mobi\", as per Mozilla recommendation:\n *\n * https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent\n *\n * @param {string} [sDevice] (eg, \"iPad\" to check for iPad, or \"!iPad\" to specifically exclude it) \n * @return {boolean} is true if the browser appears to be a mobile (ie, non-desktop) web browser, false if not\n */\n static isMobile(sDevice)\n {\n var sMobile = Web.getURLParm(\"mobile\");\n if (sMobile) return sMobile == \"true\";\n if (Web.isUserAgent(\"Mobi\")) {\n if (!sDevice) return true;\n var fInvert = sDevice[0] == '!';\n if (fInvert) sDevice = sDevice.substr(1);\n return Web.isUserAgent(sDevice) != fInvert;\n }\n return false;\n }\n\n /**\n * findProperty(obj, sProp, sSuffix)\n *\n * If both sProp and sSuffix are set, then any browser-specific prefixes are inserted between sProp and sSuffix,\n * and if a match is found, it is returned without sProp.\n *\n * For example, if findProperty(document, 'on', 'fullscreenchange') discovers that 'onwebkitfullscreenchange' exists,\n * it will return 'webkitfullscreenchange', in preparation for an addEventListener() call.\n *\n * More commonly, sSuffix is not used, so whatever property is found is returned as-is.\n *\n * @param {Object|null|undefined} obj\n * @param {string} sProp\n * @param {string} [sSuffix]\n * @return {string|null}\n */\n static findProperty(obj, sProp, sSuffix)\n {\n if (obj) {\n for (var i = 0; i < Web.asBrowserPrefixes.length; i++) {\n var sName = Web.asBrowserPrefixes[i];\n if (sSuffix) {\n sName += sSuffix;\n var sEvent = sProp + sName;\n if (sEvent in obj) return sName;\n } else {\n if (!sName) {\n sName = sProp[0];\n } else {\n sName += sProp[0].toUpperCase();\n }\n sName += sProp.substr(1);\n if (sName in obj) return sName;\n }\n }\n }\n return null;\n }\n\n /**\n * getURLParm(sParm)\n *\n * First looks for sParm exactly as specified, then looks for the lower-case version.\n *\n * @param {string} sParm\n * @return {string|undefined}\n */\n static getURLParm(sParm)\n {\n if (!Web.parmsURL) {\n Web.parmsURL = Web.parseURLParms();\n }\n return Web.parmsURL[sParm] || Web.parmsURL[sParm.toLowerCase()];\n }\n\n /**\n * parseURLParms(sParms)\n *\n * @param {string} [sParms] containing the parameter portion of a URL (ie, after the '?')\n * @return {Object} containing properties for each parameter found\n */\n static parseURLParms(sParms)\n {\n var aParms = {};\n if (window) { // an alternative to \"if (typeof module === 'undefined')\" if require(\"defines\") was used\n if (!sParms) {\n /*\n * Note that window.location.href returns the entire URL, whereas window.location.search\n * returns only the parameters, if any (starting with the '?', which we skip over with a substr() call).\n */\n sParms = window.location.search.substr(1);\n }\n var match;\n var pl = /\\+/g; // RegExp for replacing addition symbol with a space\n var search = /([^&=]+)=?([^&]*)/g;\n var decode = function(s)\n {\n return decodeURIComponent(s.replace(pl, \" \"));\n };\n\n while ((match = search.exec(sParms))) {\n aParms[decode(match[1])] = decode(match[2]);\n }\n }\n return aParms;\n }\n\n /**\n * downloadFile(sData, sType, fBase64, sFileName)\n *\n * @param {string} sData\n * @param {string} sType\n * @param {boolean} [fBase64]\n * @param {string} [sFileName]\n */\n static downloadFile(sData, sType, fBase64, sFileName)\n {\n var link = null, sAlert;\n var sURI = \"data:application/\" + sType + (fBase64? \";base64\" : \"\") + \",\";\n\n if (!Web.isUserAgent(\"Firefox\")) {\n sURI += (fBase64? sData : encodeURI(sData));\n } else {\n sURI += (fBase64? sData : encodeURIComponent(sData));\n }\n if (sFileName) {\n link = document.createElement('a');\n if (typeof link.download != 'string') link = null;\n }\n if (link) {\n link.href = sURI;\n link.download = sFileName;\n document.body.appendChild(link); // Firefox allegedly requires the link to be in the body\n link.click();\n document.body.removeChild(link);\n sAlert = 'Check your Downloads folder for ' + sFileName + '.';\n if (Web.isUserAgent(\"Chrome\")) {\n sAlert += '\\n\\nIn Chrome, after clicking OK, you may ALSO have to select the \"Window\" menu, choose \"Downloads\", and then locate this download and select \"Keep\".';\n sAlert += '\\n\\nThis is part of Chrome\\'s \"Security By Jumping Through Extra Hoops\" technology, which is much easier for Google to implement than actually checking for something malicious.';\n sAlert += '\\n\\nAnd for the record, there is nothing malicious on the PCjs website.';\n }\n } else {\n window.open(sURI);\n sAlert = 'Check your browser for a new window/tab containing the requested data' + (sFileName? (' (' + sFileName + ')') : '') + '.';\n }\n return sAlert;\n }\n\n /**\n * onCountRepeat(n, fnRepeat, fnComplete, msDelay)\n *\n * Call fnRepeat() n times with an msDelay millisecond delay between calls,\n * then call fnComplete() when n has been exhausted OR fnRepeat() returns false.\n *\n * @param {number} n\n * @param {function()} fnRepeat\n * @param {function()} fnComplete\n * @param {number} [msDelay]\n */\n static onCountRepeat(n, fnRepeat, fnComplete, msDelay)\n {\n var fnTimeout = function doCountRepeat()\n {\n n -= 1;\n if (n >= 0) {\n if (!fnRepeat()) n = 0;\n }\n if (n > 0) {\n setTimeout(fnTimeout, msDelay || 0);\n return;\n }\n fnComplete();\n };\n fnTimeout();\n }\n\n /**\n * onClickRepeat(e, msDelay, msRepeat, fn)\n *\n * Repeatedly call fn() with an initial msDelay, and an msRepeat delay thereafter,\n * as long as HTML control Object e has an active \"down\" event and fn() returns true.\n *\n * @param {Object} e\n * @param {number} msDelay\n * @param {number} msRepeat\n * @param {function(boolean)} fn is passed false on the first call, true on all repeated calls\n */\n static onClickRepeat(e, msDelay, msRepeat, fn)\n {\n var ms = 0, timer = null, fIgnoreMouseEvents = false;\n\n var fnRepeat = function doClickRepeat()\n {\n if (fn(ms === msRepeat)) {\n timer = setTimeout(fnRepeat, ms);\n ms = msRepeat;\n }\n };\n e.onmousedown = function()\n {\n // Web.log(\"onMouseDown()\");\n if (!fIgnoreMouseEvents) {\n if (!timer) {\n ms = msDelay;\n fnRepeat();\n }\n }\n };\n e.ontouchstart = function()\n {\n // Web.log(\"onTouchStart()\");\n if (!timer) {\n ms = msDelay;\n fnRepeat();\n }\n };\n e.onmouseup = e.onmouseout = function()\n {\n // Web.log(\"onMouseUp()/onMouseOut()\");\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n };\n e.ontouchend = e.ontouchcancel = function()\n {\n // Web.log(\"onTouchEnd()/onTouchCancel()\");\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n /*\n * Devices that generate ontouch* events ALSO generate onmouse* events,\n * and generally do so immediately after all the touch events are complete,\n * so unless we want double the action, we need to ignore mouse events.\n */\n fIgnoreMouseEvents = true;\n };\n }\n\n /**\n * onPageEvent(sName, fn)\n *\n * For 'onload', 'onunload', and 'onpageshow' events, most callers should NOT use this function, but\n * instead use Web.onInit(), Web.onShow(), and Web.onExit(), respectively.\n *\n * The only components that should still use onPageEvent() are THIS component (see the bottom of this file)\n * and components that need to capture other events (eg, the 'onresize' event in the Video component).\n *\n * This function creates a chain of callbacks, allowing multiple JavaScript modules to define handlers\n * for the same event, which wouldn't be possible if everyone modified window['onload'], window['onunload'],\n * etc, themselves. However, that's less of a concern now, because assuming everyone else is now using\n * onInit(), onExit(), etc, then there really IS only one component setting the window callback: this one.\n *\n * NOTE: It's risky to refer to obscure event handlers with \"dot\" names, because the Closure Compiler may\n * erroneously replace them (eg, window.onpageshow is a good example).\n *\n * @param {string} sFunc\n * @param {function()} fn\n */\n static onPageEvent(sFunc, fn)\n {\n if (window) {\n var fnPrev = window[sFunc];\n if (typeof fnPrev !== 'function') {\n window[sFunc] = fn;\n } else {\n /*\n * TODO: Determine whether there's any value in receiving/sending the Event object that the\n * browser provides when it generates the original event.\n */\n window[sFunc] = function onWindowEvent()\n {\n if (fnPrev) fnPrev();\n fn();\n };\n }\n }\n };\n\n /**\n * onInit(fn)\n *\n * Use this instead of setting window.onload. Allows multiple JavaScript modules to define their own 'onload' event handler.\n *\n * @param {function()} fn\n */\n static onInit(fn)\n {\n Web.aPageEventHandlers['init'].push(fn);\n };\n\n /**\n * onShow(fn)\n *\n * @param {function()} fn\n *\n * Use this instead of setting window.onpageshow. Allows multiple JavaScript modules to define their own 'onpageshow' event handler.\n */\n static onShow(fn)\n {\n Web.aPageEventHandlers['show'].push(fn);\n };\n\n /**\n * onExit(fn)\n *\n * @param {function()} fn\n *\n * Use this instead of setting window.onunload. Allows multiple JavaScript modules to define their own 'onunload' event handler.\n */\n static onExit(fn)\n {\n Web.aPageEventHandlers['exit'].push(fn);\n };\n\n /**\n * doPageEvent(afn)\n *\n * @param {Array.<function()>} afn\n */\n static doPageEvent(afn)\n {\n if (Web.fPageEventsEnabled) {\n try {\n for (var i = 0; i < afn.length; i++) {\n afn[i]();\n }\n } catch (e) {\n Web.notice(\"An unexpected error occurred: \" + e.message + \"\\n\\nIf it happens again, please send this information to support@pcjs.org. Thanks.\");\n }\n }\n };\n\n /**\n * enablePageEvents(fEnable)\n *\n * @param {boolean} fEnable is true to enable page events, false to disable (they're enabled by default)\n */\n static enablePageEvents(fEnable)\n {\n if (!Web.fPageEventsEnabled && fEnable) {\n Web.fPageEventsEnabled = true;\n if (Web.fPageLoaded) Web.sendPageEvent('init');\n if (Web.fPageShowed) Web.sendPageEvent('show');\n return;\n }\n Web.fPageEventsEnabled = fEnable;\n }\n\n /**\n * sendPageEvent(sEvent)\n *\n * This allows us to manually trigger page events.\n *\n * @param {string} sEvent (one of 'init', 'show' or 'exit')\n */\n static sendPageEvent(sEvent)\n {\n if (Web.aPageEventHandlers[sEvent]) {\n Web.doPageEvent(Web.aPageEventHandlers[sEvent]);\n }\n }\n}\n\nWeb.parmsURL = null; // initialized on first call to parseURLParms()\n\nWeb.aPageEventHandlers = {\n 'init': [], // list of window 'onload' handlers\n 'show': [], // list of window 'onpageshow' handlers\n 'exit': [] // list of window 'onunload' handlers (although we prefer to use 'onbeforeunload' if possible)\n};\n\nWeb.asBrowserPrefixes = ['', 'moz', 'ms', 'webkit'];\n\nWeb.fPageLoaded = false; // set once the page's first 'onload' event has occurred\nWeb.fPageShowed = false; // set once the page's first 'onpageshow' event has occurred\nWeb.fPageEventsEnabled = true; // default is true, set to false (or true) by enablePageEvents()\n\n/**\n * fLocalStorage\n *\n * true if localStorage support exists, is enabled, and works; \"falsey\" otherwise\n *\n * @type {boolean|null}\n */\nWeb.fLocalStorage = null;\n\n/**\n * TODO: Is there any way to get the Closure Compiler to stop inlining this string? This isn't cutting it.\n *\n * @const {string}\n */\nWeb.sLocalStorageTest = \"PCjs.localStorage\";\n\nWeb.onPageEvent('onload', function onPageLoad() {\n Web.fPageLoaded = true;\n Web.doPageEvent(Web.aPageEventHandlers['init']);\n});\n\nWeb.onPageEvent('onpageshow', function onPageShow() {\n Web.fPageShowed = true;\n Web.doPageEvent(Web.aPageEventHandlers['show']);\n});\n\nWeb.onPageEvent(Web.isUserAgent(\"iOS\")? 'onpagehide' : (Web.isUserAgent(\"Opera\")? 'onunload' : 'onbeforeunload'), function onPageUnload() {\n Web.doPageEvent(Web.aPageEventHandlers['exit']);\n});\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/component.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * All PCjs components now use JSDoc types, primarily so that Google's Closure Compiler will compile\n * everything with zero warnings when ADVANCED_OPTIMIZATIONS are enabled. For more information about\n * the JSDoc types supported by the Closure Compiler:\n *\n * https://developers.google.com/closure/compiler/docs/js-for-compiler#types\n *\n * I also attempted to validate this code with JSLint, but it complained too much; eg, it didn't like\n * \"while (true)\", a tried and \"true\" programming convention for decades, and it wanted me to replace\n * all \"++\" and \"--\" operators with \"+= 1\" and \"-= 1\", use \"(s || '')\" instead of \"(s? s : '')\", etc.\n *\n * I prefer sticking with traditional C-style idioms, in part because they are more portable. That\n * does NOT mean I'm trying to write \"portable JavaScript,\" but some of this code was ported from C code\n * I'd written long ago, so portability is good, and I'm not going to throw that away if there's no need.\n *\n * UPDATE: I've since switched from JSLint to JSHint, which seems to have more reasonable defaults.\n * And for new code, I have adopted some popular JavaScript idioms, like \"(s || '')\", although the need\n * for those kinds of expressions will be reduced as I also start adopting some ES6 features, like\n * default parameters.\n */\n\n\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * subclass (eg, SerialPort), because otherwise the Compiler won't allow us to *reference*\n * the named property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass Component {\n /**\n * Component(type, parms, bitsMessage)\n *\n * A Component object requires:\n *\n * type: a user-defined type name (eg, \"CPU\")\n *\n * and accepts any or all of the following (parms) properties:\n *\n * id: component ID (default is \"\")\n * name: component name (default is \"\"; if blank, toString() will use the type name only)\n * comment: component comment string (default is undefined)\n *\n * Component subclasses will usually have additional (parms) properties.\n *\n * @param {string} type\n * @param {Object} [parms]\n * @param {number} [bitsMessage] selects message(s) that the component wants to enable (default is 0)\n */\n constructor(type, parms, bitsMessage)\n {\n this.type = type;\n\n if (!parms) parms = {'id': \"\", 'name': \"\"};\n\n this.id = parms['id'] || \"\";\n this.name = parms['name'];\n this.comment = parms['comment'];\n this.parms = parms;\n\n /*\n * The following Component properties need to be accessible by other machines and/or command scripts;\n * well, OK, or we could have exported some new functions to walk the contents of these properties, as we\n * did with findMachineComponent(), but this works just as well.\n *\n * Also, while the double-assignment looks silly (ie, using both dot and bracket property notation), it\n * resolves a complaint from the Closure Compiler, because if we use ONLY bracket notation here, then the\n * Compiler wants us to change all the other references to bracket notation as well.\n */\n this.exports = this['exports'] = {};\n this.bindings = this['bindings'] = {};\n\n var i = this.id.indexOf('.');\n if (i < 0) {\n this.idComponent = this.id;\n } else {\n this.idMachine = this.id.substr(0, i);\n this.idComponent = this.id.substr(i + 1);\n }\n\n /*\n * Gather all the various component flags (booleans) into a single \"flags\" object, and encourage\n * subclasses to do the same, to reduce the property clutter we have to wade through while debugging.\n */\n this.flags = {\n ready: false,\n busy: false,\n busyCancel: false,\n initDone: false,\n powered: false,\n unloading: false,\n error: false\n };\n\n this.fnReady = null;\n this.clearError();\n this.bitsMessage = bitsMessage || 0;\n\n this.cmp = null;\n this.bus = null;\n this.cpu = null;\n this.dbg = null;\n\n /*\n * TODO: Consider adding another parameter to the Component() constructor that allows components to tell\n * us if they support single or multiple instances per machine. For example, there can be multiple SerialPort\n * components per machine, but only one CPU component (some machines also support an FPU, but that component\n * is considered separate from the CPU).\n *\n * It's not critical, but it would help catch machine configuration errors; for example, a machine that mistakenly\n * includes two CPU components may, aside from wasting memory, end up with odd side-effects, like unresponsive\n * CPU controls.\n */\n Component.add(this);\n }\n\n /**\n * Component.add(component)\n *\n * @param {Component} component\n */\n static add(component)\n {\n /*\n * This just generates a lot of useless noise, handy in the early days, not so much these days....\n *\n * if (DEBUG) Component.log(\"Component.add(\" + component.type + \",\" + component.id + \")\");\n */\n Component.components.push(component);\n }\n\n /**\n * Component.addMachine(idMachine)\n *\n * @param {string} idMachine\n */\n static addMachine(idMachine)\n {\n Component.machines[idMachine] = {};\n }\n\n /**\n * Component.addMachineResource(idMachine, sName, data)\n *\n * @param {string} idMachine\n * @param {string|null} sName (name of the resource)\n * @param {*} data\n */\n static addMachineResource(idMachine, sName, data)\n {\n /*\n * I used to assert(Component.machines[idMachine]), but when we're running as a Node app, embed.js is not used,\n * so addMachine() is never called, so resources do not need to be recorded.\n */\n if (Component.machines[idMachine] && sName) {\n Component.machines[idMachine][sName] = data;\n }\n }\n\n /**\n * Component.getMachineResources(idMachine)\n *\n * @param {string} idMachine\n * @return {Object|undefined}\n */\n static getMachineResources(idMachine)\n {\n return Component.machines[idMachine];\n }\n\n /**\n * Component.getTime()\n *\n * @return {number} the current time, in milliseconds\n */\n static getTime()\n {\n return Date.now() || +new Date();\n }\n\n /**\n * Component.log(s, type)\n *\n * For diagnostic output only.\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n static log(s, type)\n {\n if (!COMPILED) {\n if (s) {\n var sElapsed = \"\", sMsg = (type? (type + \": \") : \"\") + s;\n if (typeof Usr != \"undefined\") {\n if (Component.msStart === undefined) {\n Component.msStart = Component.getTime();\n }\n sElapsed = (Component.getTime() - Component.msStart) + \"ms: \";\n }\n sMsg = sMsg.replace(/\\r/g, '\\\\r').replace(/\\n/g, ' ');\n if (window && window.console) console.log(sElapsed + sMsg);\n }\n }\n }\n\n /**\n * Component.assert(f, s)\n *\n * Verifies conditions that must be true (for DEBUG builds only).\n *\n * The Closure Compiler should automatically remove all references to Component.assert() in non-DEBUG builds.\n * TODO: Add a task to the build process that \"asserts\" there are no instances of \"assertion failure\" in RELEASE builds.\n *\n * @param {boolean} f is the expression we are asserting to be true\n * @param {string} [s] is description of the assertion on failure\n */\n static assert(f, s)\n {\n if (DEBUG) {\n if (!f) {\n if (!s) s = \"assertion failure\";\n Component.log(s);\n throw new Error(s);\n }\n }\n }\n\n /**\n * Component.print(s)\n *\n * Components that inherit from this class should use this.print(), rather than Component.print(), because\n * if a Control Panel is loaded, it will override only the instance method, not the class method (overriding the\n * class method would improperly affect any other machines loaded on the same page).\n *\n * @this {Component}\n * @param {string} s\n */\n static print(s)\n {\n if (!COMPILED) {\n var i = s.lastIndexOf('\\n');\n if (i >= 0) {\n Component.println(s.substr(0, i));\n s = s.substr(i + 1);\n }\n Component.printBuffer += s;\n }\n }\n\n /**\n * Component.println(s, type, id)\n *\n * Components that inherit from this class should use this.println(), rather than Component.println(), because\n * if a Control Panel is loaded, it will override only the instance method, not the class method (overriding the\n * class method would improperly affect any other machines loaded on the same page).\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n * @param {string} [id] is the caller's ID, if any\n */\n static println(s, type, id)\n {\n if (!COMPILED) {\n s = Component.printBuffer + (s || \"\");\n Component.log((id? (id + \": \") : \"\") + (s? (\"\\\"\" + s + \"\\\"\") : \"\"), type);\n Component.printBuffer = \"\";\n }\n }\n\n /**\n * Component.notice(s, fPrintOnly, id)\n *\n * notice() is like println() but implies a need for user notification, so we alert() as well.\n *\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n * @return {boolean}\n */\n static notice(s, fPrintOnly, id)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.NOTICE, id);\n }\n if (!fPrintOnly) Component.alertUser((id? (id + \": \") : \"\") + s);\n return true;\n }\n\n /**\n * Component.warning(s)\n *\n * @param {string} s describes the warning\n */\n static warning(s)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.WARNING);\n }\n Component.alertUser(s);\n }\n\n /**\n * Component.error(s)\n *\n * @param {string} s describes the error; an alert() is displayed as well\n */\n static error(s)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.ERROR);\n }\n Component.alertUser(s);\n }\n\n /**\n * Component.alertUser(sMessage)\n *\n * @param {string} sMessage\n */\n static alertUser(sMessage)\n {\n if (window) {\n window.alert(sMessage);\n } else {\n Component.log(sMessage);\n }\n }\n\n /**\n * Component.confirmUser(sPrompt)\n *\n * @param {string} sPrompt\n * @returns {boolean} true if the user clicked OK, false if Cancel/Close\n */\n static confirmUser(sPrompt)\n {\n var fResponse = false;\n if (window) {\n fResponse = window.confirm(sPrompt);\n }\n return fResponse;\n }\n\n /**\n * Component.promptUser()\n *\n * @param {string} sPrompt\n * @param {string} [sDefault]\n * @returns {string|null}\n */\n static promptUser(sPrompt, sDefault)\n {\n var sResponse = null;\n if (window) {\n sResponse = window.prompt(sPrompt, sDefault === undefined? \"\" : sDefault);\n }\n return sResponse;\n }\n\n /**\n * Component.appendControl(control, sText)\n *\n * @param {Object} control\n * @param {string} sText\n */\n static appendControl(control, sText)\n {\n control.value += sText;\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (COMPILED) {\n sText = control.value;\n if (sText.length > 8192) control.value = sText.substr(sText.length - 4096);\n }\n control.scrollTop = control.scrollHeight;\n }\n\n /**\n * Component.replaceControl(control, sSearch, sReplace)\n *\n * @param {Object} control\n * @param {string} sSearch\n * @param {string} sReplace\n */\n static replaceControl(control, sSearch, sReplace)\n {\n var sText = control.value;\n var i = sText.lastIndexOf(sSearch);\n if (i < 0) {\n sText += sSearch + '\\n';\n } else {\n sText = sText.substr(0, i) + sReplace + sText.substr(i + sSearch.length);\n }\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (COMPILED && sText.length > 8192) sText = sText.substr(sText.length - 4096);\n control.value = sText;\n control.scrollTop = control.scrollHeight;\n }\n\n /**\n * Component.bindExternalControl(component, sBinding, sType)\n *\n * @param {Component} component\n * @param {string} sBinding\n * @param {string} [sType] is the external component type (default is \"Panel\")\n */\n static bindExternalControl(component, sBinding, sType = \"Panel\")\n {\n if (sBinding) {\n var target = Component.getComponentByType(sType, component.id);\n if (target) {\n var control = target.bindings[sBinding];\n if (control) {\n component.setBinding(null, sBinding, control);\n }\n }\n }\n }\n\n /**\n * Component.bindComponentControls(component, element, sAppClass)\n *\n * @param {Component} component\n * @param {HTMLElement} element from the DOM\n * @param {string} sAppClass\n */\n static bindComponentControls(component, element, sAppClass)\n {\n var aeControls = Component.getElementsByClass(element.parentNode, sAppClass + \"-control\");\n\n for (var iControl = 0; iControl < aeControls.length; iControl++) {\n\n var aeChildNodes = aeControls[iControl].childNodes;\n\n for (var iNode = 0; iNode < aeChildNodes.length; iNode++) {\n var control = aeChildNodes[iNode];\n if (control.nodeType !== 1 /* document.ELEMENT_NODE */) {\n continue;\n }\n var sClass = control.getAttribute(\"class\");\n if (!sClass) continue;\n var aClasses = sClass.split(\" \");\n for (var iClass = 0; iClass < aClasses.length; iClass++) {\n var parms;\n sClass = aClasses[iClass];\n switch (sClass) {\n case sAppClass + \"-binding\":\n parms = Component.getComponentParms(/** @type {HTMLElement} */(control));\n if (parms && parms['binding'] !== undefined) {\n component.setBinding(parms['type'], parms['binding'], /** @type {HTMLElement} */(control), parms['value']);\n } else if (!parms || parms['type'] != \"description\") {\n Component.log(\"Component '\" + component.toString() + \"' missing binding\" + (parms? \" for \" + parms['type'] : \"\"), \"warning\");\n }\n iClass = aClasses.length;\n break;\n default:\n // if (DEBUG) Component.log(\"Component.bindComponentControls(\" + component.toString() + \"): unrecognized control class \\\"\" + sClass + \"\\\"\", \"warning\");\n break;\n }\n }\n }\n }\n }\n\n /**\n * Component.getComponents(idRelated)\n *\n * We could store components as properties, using the component's ID, and change\n * this linear lookup into a property lookup, but some components may have no ID.\n *\n * @param {string} [idRelated] of related component\n * @return {Array} of components\n */\n static getComponents(idRelated)\n {\n var i;\n var aComponents = [];\n /*\n * getComponentByID(id, idRelated)\n *\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated) {\n if ((i = idRelated.indexOf('.')) > 0)\n idRelated = idRelated.substr(0, i + 1);\n else\n idRelated = \"\";\n }\n for (i = 0; i < Component.components.length; i++) {\n var component = Component.components[i];\n if (!idRelated || !component.id.indexOf(idRelated)) {\n aComponents.push(component);\n }\n }\n return aComponents;\n }\n\n /**\n * Component.getComponentByID(id, idRelated)\n *\n * We could store components as properties, using the component's ID, and change\n * this linear lookup into a property lookup, but some components may have no ID.\n *\n * @param {string} id of the desired component\n * @param {string} [idRelated] of related component\n * @return {Component|null}\n */\n static getComponentByID(id, idRelated)\n {\n if (id !== undefined) {\n var i;\n /*\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated && (i = idRelated.indexOf('.')) > 0) {\n id = idRelated.substr(0, i + 1) + id;\n }\n for (i = 0; i < Component.components.length; i++) {\n if (Component.components[i].id === id) {\n return Component.components[i];\n }\n }\n if (Component.components.length) {\n Component.log(\"Component ID '\" + id + \"' not found\", \"warning\");\n }\n }\n return null;\n }\n\n /**\n * Component.getComponentByType(sType, idRelated, componentPrev)\n *\n * @param {string} sType of the desired component\n * @param {string} [idRelated] of related component\n * @param {Component|null} [componentPrev] of previously returned component, if any\n * @return {Component|null}\n */\n static getComponentByType(sType, idRelated, componentPrev)\n {\n if (sType !== undefined) {\n var i;\n /*\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated) {\n if ((i = idRelated.indexOf('.')) > 0) {\n idRelated = idRelated.substr(0, i + 1);\n } else {\n idRelated = \"\";\n }\n }\n for (i = 0; i < Component.components.length; i++) {\n if (componentPrev) {\n if (componentPrev == Component.components[i]) componentPrev = null;\n continue;\n }\n if (sType == Component.components[i].type && (!idRelated || !Component.components[i].id.indexOf(idRelated))) {\n return Component.components[i];\n }\n }\n Component.log(\"Component type '\" + sType + \"' not found\", \"warning\");\n }\n return null;\n }\n\n /**\n * Component.getComponentParms(element)\n *\n * @param {HTMLElement} element from the DOM\n */\n static getComponentParms(element)\n {\n var parms = null;\n var sParms = element.getAttribute(\"data-value\");\n if (sParms) {\n try {\n parms = eval('(' + sParms + ')'); // jshint ignore:line\n /*\n * We can no longer invoke removeAttribute() because some components (eg, Panel) need\n * to run their initXXX() code more than once, to avoid initialization-order dependencies.\n *\n * if (!DEBUG) {\n * element.removeAttribute(\"data-value\");\n * }\n */\n } catch(e) {\n Component.error(e.message + \" (\" + sParms + \")\");\n }\n }\n return parms;\n }\n\n /**\n * Component.getElementsByClass(element, sClass, sObjClass)\n *\n * This is a cross-browser helper function, since not all browser's support getElementsByClassName()\n *\n * TODO: This should probably be moved into weblib.js at some point, along with the control binding functions above,\n * to keep all the browser-related code together.\n *\n * @param {HTMLDocument|HTMLElement|Node} element from the DOM\n * @param {string} sClass\n * @param {string} [sObjClass]\n * @return {Array|NodeList}\n */\n static getElementsByClass(element, sClass, sObjClass)\n {\n if (sObjClass) sClass += '-' + sObjClass + \"-object\";\n /*\n * Use the browser's built-in getElementsByClassName() if it appears to be available\n * (for example, it's not available in IE8, but it should be available in IE9 and up)\n */\n if (element.getElementsByClassName) {\n return element.getElementsByClassName(sClass);\n }\n var i, j, ae = [];\n var aeAll = element.getElementsByTagName(\"*\");\n var re = new RegExp('(^| )' + sClass + '( |$)');\n for (i = 0, j = aeAll.length; i < j; i++) {\n if (re.test(aeAll[i].className)) {\n ae.push(aeAll[i]);\n }\n }\n if (!ae.length) {\n Component.log('No elements of class \"' + sClass + '\" found');\n }\n return ae;\n }\n\n /**\n * Component.getScriptCommands(sScript)\n *\n * This is a simple parser that breaks sScript into an array of commands, where each command\n * is an array of tokens, where tokens are sequences of characters separated by any of: tab, space,\n * carriage-return (CR), line-feed (LF), semicolon, single-quote, or double-quote; if a quote is\n * used, all characters up to the next matching quote become part of the token, allowing any of the\n * other separators to be part of the token. CR, LF and semicolon also serve to terminate a command,\n * with semicolon being preferred, because it's 1) more visible, and 2) essential when the entire\n * script is a multi-line string where all CR/LF were replaced by spaces (which is what Jekyll does,\n * and since we can't change Jekyll, it's what our own MarkDown Front Matter parser does as well;\n * see convertMD() in markout.js, where the aCommandDefs array is built).\n *\n * Backslash sequences like \\n, \\r, and \\\\ have already been converted to LF, CR and backslash\n * characters, since the entire script string is injected into a JavaScript function call, so any\n * backslash sequence that JavaScript supports is automatically converted:\n *\n * \\0 \\' \\\" \\\\ \\n \\r \\v \\t \\b \\f \\uXXXX \\xXX\n * ^J ^M ^K ^I ^H ^L\n *\n * To support any other non-printable 8-bit character, such as ESC, you should use \\xXX, where XX\n * is the ASCII code in hex. For ESC, that would be \\x1B.\n *\n * @param {string} sScript\n * @return {Array}\n */\n static getScriptCommands(sScript)\n {\n var cch = sScript.length;\n var aCommands = [], aTokens = [], sToken = \"\", chQuote = null;\n for (var i = 0; i < cch; i++) {\n var ch = sScript[i];\n if (ch == '\"' || ch == \"'\") {\n if (chQuote && ch != chQuote) {\n sToken += ch;\n continue;\n }\n if (!chQuote) {\n chQuote = ch;\n } else {\n chQuote = null;\n }\n if (sToken) {\n aTokens.push(sToken);\n sToken = \"\";\n }\n continue;\n }\n if (!chQuote) {\n if (ch == '\\r' || ch == '\\n') {\n ch = ';';\n }\n if (ch == ' ' || ch == '\\t' || ch == ';') {\n if (sToken) {\n aTokens.push(sToken);\n sToken = \"\";\n }\n if (ch == ';' && aTokens.length) {\n aCommands.push(aTokens);\n aTokens = [];\n }\n continue;\n }\n }\n sToken += ch;\n }\n if (sToken) {\n aTokens.push(sToken);\n }\n if (aTokens.length) {\n aCommands.push(aTokens);\n }\n return aCommands;\n }\n\n /**\n * Component.processScript(idMachine, sScript)\n *\n * @param {string} idMachine\n * @param {string} [sScript]\n * @return {boolean}\n */\n static processScript(idMachine, sScript)\n {\n var fSuccess = false;\n idMachine += \".machine\";\n if (!sScript) {\n delete Component.commands[idMachine];\n fSuccess = true;\n }\n else if (typeof sScript == \"string\" && !Component.commands[idMachine]) {\n fSuccess = true;\n Component.commands[idMachine] = Component.getScriptCommands(sScript);\n if (!Component.processCommands(idMachine)) {\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * Component.processCommands(idMachine)\n *\n * @param {string} idMachine\n * @return {boolean}\n */\n static processCommands(idMachine)\n {\n var fSuccess = true;\n var aCommands = Component.commands[idMachine];\n\n // var dbg = Component.getComponentByType(\"Debugger\", idMachine);\n\n while (aCommands && aCommands.length) {\n\n var aTokens = aCommands.splice(0, 1)[0];\n var sCommand = aTokens[0];\n\n /*\n * It's possible to route this output to the Debugger window with dbg.println()\n * instead, but it's a bit too confusing mingling script output in a window that\n * already mingles Debugger and machine output.\n */\n Component.println(aTokens.join(' '), Component.PRINT.SCRIPT);\n\n var fnCallReady = null;\n if (Component.asyncCommands.indexOf(sCommand) >= 0) {\n fnCallReady = function processNextCommand() {\n return function() {\n Component.processCommands(idMachine);\n }\n }();\n }\n\n var fnCommand = Component.globalCommands[sCommand];\n if (fnCommand) {\n if (!fnCallReady) {\n fSuccess = fnCommand(aTokens[1], aTokens[2], aTokens[3]);\n } else {\n if (!fnCommand(fnCallReady, aTokens[1], aTokens[2], aTokens[3])) break;\n }\n }\n else {\n fSuccess = false;\n var component = Component.getComponentByType(aTokens[1], idMachine);\n if (component) {\n fnCommand = Component.componentCommands[sCommand];\n if (fnCommand) {\n fSuccess = fnCommand(component, aTokens[2], aTokens[3]);\n }\n else {\n var exports = component['exports'];\n if (exports) {\n fnCommand = exports[sCommand];\n if (fnCommand) {\n fSuccess = true;\n if (!fnCallReady) {\n fSuccess = fnCommand.call(component, aTokens[2], aTokens[3]);\n } else {\n if (!fnCommand.call(component, fnCallReady, aTokens[2], aTokens[3])) break;\n }\n }\n }\n }\n }\n }\n\n if (!fSuccess) {\n Component.alertUser(\"Script error: '\" + sCommand + \"' command \" + (fnCommand? \" failed\" : \" not recognized\"));\n break;\n }\n }\n\n if (aCommands && !aCommands.length) {\n delete Component.commands[idMachine];\n }\n\n return fSuccess;\n }\n\n /**\n * Component.scriptAlert(sMessage)\n *\n * @param {string} sMessage\n * @return {boolean}\n */\n static scriptAlert(sMessage)\n {\n Component.alertUser(sMessage);\n return true;\n }\n\n /**\n * Component.scriptSelect(component, sBinding, sValue)\n *\n * @param {Component} component\n * @param {string} sBinding\n * @param {string} sValue\n * @return {boolean}\n */\n static scriptSelect(component, sBinding, sValue)\n {\n var fSuccess = false;\n var aBindings = component['bindings'];\n var control = aBindings[sBinding];\n if (control) {\n for (var i = 0; i < control.options.length; i++) {\n if (control.options[i].textContent == sValue) {\n if (control.selectedIndex != i) {\n control.selectedIndex = i;\n }\n fSuccess = true;\n break;\n }\n }\n }\n return fSuccess;\n }\n\n /**\n * Component.scriptSleep(fnCallback, sDelay)\n *\n * @param {function()} fnCallback\n * @param {string} sDelay (in milliseconds)\n * @return {boolean}\n */\n static scriptSleep(fnCallback, sDelay)\n {\n setTimeout(fnCallback, +sDelay);\n return false;\n }\n\n /**\n * toString()\n *\n * @this {Component}\n * @return {string}\n */\n toString()\n {\n return (this.name? this.name : (this.id || this.type));\n }\n\n /**\n * getMachineNum()\n *\n * @this {Component}\n * @return {number} unique machine number\n */\n getMachineNum()\n {\n var nMachine = 1;\n if (this.idMachine) {\n var aDigits = this.idMachine.match(/\\d+/);\n if (aDigits !== null)\n nMachine = parseInt(aDigits[0], 10);\n }\n return nMachine;\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * Component's setBinding() method is intended to be overridden by subclasses.\n *\n * @this {Component}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, 'print')\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n switch (sBinding) {\n case 'clear':\n if (!this.bindings[sBinding]) {\n this.bindings[sBinding] = control;\n control.onclick = (function(component) {\n return function clearControl() {\n if (component.bindings['print']) {\n component.bindings['print'].value = \"\";\n }\n };\n }(this));\n }\n return true;\n case 'print':\n if (!this.bindings[sBinding]) {\n var controlTextArea = /** @type {HTMLTextAreaElement} */(control);\n this.bindings[sBinding] = controlTextArea;\n /**\n * Override this.notice() with a replacement function that eliminates the Component.alertUser() call.\n *\n * @this {Component}\n * @param {string} s\n * @return {boolean}\n */\n this.notice = function noticeControl(s /*, fPrintOnly, id*/) {\n this.println(s, this.type);\n return true;\n };\n /*\n * This was added for Firefox (Safari will clear the <textarea> on a page reload, but Firefox does not).\n */\n controlTextArea.value = \"\";\n this.print = function(control) {\n return function printControl(s) {\n Component.appendControl(control, s);\n };\n }(controlTextArea);\n this.println = function(component, control) {\n return function printlnControl(s, type, id) {\n if (!s) s = \"\";\n if (type != Component.PRINT.PROGRESS || s.slice(-3) != \"...\") {\n if (type) s = type + \": \" + s;\n Component.appendControl(control, s + '\\n');\n } else {\n Component.replaceControl(control, s, s + '.');\n }\n if (!COMPILED && window && window.console) Component.println(s, type, id);\n };\n }(this, controlTextArea);\n }\n return true;\n default:\n return false;\n }\n }\n\n /**\n * log(s, type)\n *\n * For diagnostic output only.\n *\n * WARNING: Even though this function's body is completely wrapped in DEBUG, that won't prevent the Closure Compiler\n * from including it, so all calls must still be prefixed with \"if (DEBUG) ....\". For this reason, the class method,\n * Component.log(), is preferred, because the compiler IS smart enough to remove those calls.\n *\n * @this {Component}\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n log(s, type)\n {\n if (!COMPILED) {\n Component.log(s, type || this.id || this.type);\n }\n }\n\n /**\n * assert(f, s)\n *\n * Verifies conditions that must be true (for DEBUG builds only).\n *\n * WARNING: Make sure you preface all calls to this.assert() with \"if (DEBUG)\", because unlike Component.assert(),\n * the Closure Compiler can't be sure that this instance method hasn't been overridden, so it refuses to treat it as\n * dead code in non-DEBUG builds.\n *\n * TODO: Add a task to the build process that \"asserts\" there are no instances of \"assertion failure\" in RELEASE builds.\n *\n * @this {Component}\n * @param {boolean|number} f is the expression asserted to be true\n * @param {string} [s] is a description of the assertion to be displayed or logged on failure\n */\n assert(f, s)\n {\n if (DEBUG) {\n if (!f) {\n s = \"assertion failure in \" + (this.id || this.type) + (s? \": \" + s : \"\");\n if (DEBUGGER && this.dbg) {\n this.dbg.stopCPU();\n /*\n * Why do we throw an Error only to immediately catch and ignore it? Simply to give\n * any IDE the opportunity to inspect the application's state. Even when the IDE has\n * control, you should still be able to invoke Debugger commands from the IDE's REPL,\n * using the global function that the Debugger constructor defines; eg:\n *\n * pcx86('r')\n * pcx86('dw 0:0')\n * pcx86('h')\n * ...\n *\n * If you have no desire to stop on assertions, consider this a no-op. However, another\n * potential benefit of creating an Error object is that, for browsers like Chrome, we get\n * a stack trace, too.\n */\n try {\n throw new Error(s);\n } catch(e) {\n this.println(e.stack || e.message);\n }\n return;\n }\n this.log(s);\n throw new Error(s);\n }\n }\n }\n\n /**\n * print(s)\n *\n * Components using this.print() should wait until after their constructor has run to display any messages, because\n * if a Control Panel has been loaded, its override will not take effect until its own constructor has run.\n *\n * @this {Component}\n * @param {string} s\n */\n print(s)\n {\n Component.print(s);\n }\n\n /**\n * println(s, type, id)\n *\n * Components using this.println() should wait until after their constructor has run to display any messages, because\n * if a Control Panel has been loaded, its override will not take effect until its own constructor has run.\n *\n * @this {Component}\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n * @param {string} [id] is the caller's ID, if any\n */\n println(s, type, id)\n {\n Component.println(s, type, id || this.id);\n }\n\n /**\n * status(s)\n *\n * status() is like println() but it also includes information about the component (ie, the component type),\n * which is why there is no corresponding Component.status() function.\n *\n * @this {Component}\n * @param {string} s is the message text\n */\n status(s)\n {\n this.println(this.type + \": \" + s);\n }\n\n /**\n * notice(s, fPrintOnly, id)\n *\n * notice() is like println() but implies a need for user notification, so we alert() as well; however, if this.println()\n * is overridden, this.notice will be replaced with a similar override, on the assumption that the override is taking care\n * of alerting the user.\n *\n * @this {Component}\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n * @return {boolean}\n */\n notice(s, fPrintOnly, id)\n {\n if (!fPrintOnly) {\n /*\n * See if the associated computer, if any, is \"unloading\"....\n */\n var computer = Component.getComponentByType(\"Computer\", this.id);\n if (computer && computer.flags.unloading) {\n console.log(\"ignoring notice during unload: \" + s);\n return false;\n }\n }\n Component.notice(s, fPrintOnly, id || this.type);\n return true;\n }\n\n /**\n * setError(s)\n *\n * Set a fatal error condition\n *\n * @this {Component}\n * @param {string} s describes a fatal error condition\n */\n setError(s)\n {\n this.flags.error = true;\n this.notice(s); // TODO: Any cases where we should still prefix this string with \"Fatal error: \"?\n }\n\n /**\n * clearError()\n *\n * Clear any fatal error condition\n *\n * @this {Component}\n */\n clearError() {\n this.flags.error = false;\n }\n\n /**\n * isError()\n *\n * Report any fatal error condition\n *\n * @this {Component}\n * @return {boolean} true if a fatal error condition exists, false if not\n */\n isError()\n {\n if (this.flags.error) {\n this.println(this.toString() + \" error\");\n return true;\n }\n return false;\n }\n\n /**\n * isReady(fnReady)\n *\n * Return the \"ready\" state of the component; if the component is not ready, it will queue the optional\n * notification function, otherwise it will immediately call the notification function, if any, without queuing it.\n *\n * NOTE: Since only the Computer component actually cares about the \"readiness\" of other components, the so-called\n * \"queue\" of notification functions supports exactly one function. This keeps things nice and simple.\n *\n * @this {Component}\n * @param {function()} [fnReady]\n * @return {boolean} true if the component is in a \"ready\" state, false if not\n */\n isReady(fnReady)\n {\n if (fnReady) {\n if (this.flags.ready) {\n fnReady();\n } else {\n if (MAXDEBUG) this.log(\"NOT ready\");\n this.fnReady = fnReady;\n }\n }\n return this.flags.ready;\n }\n\n /**\n * setReady(fReady)\n *\n * Set the \"ready\" state of the component to true, and call any queued notification functions.\n *\n * @this {Component}\n * @param {boolean} [fReady] is assumed to indicate \"ready\" unless EXPLICITLY set to false\n */\n setReady(fReady)\n {\n if (!this.flags.error) {\n this.flags.ready = (fReady !== false);\n if (this.flags.ready) {\n if (MAXDEBUG /* || this.name */) this.log(\"ready\");\n var fnReady = this.fnReady;\n this.fnReady = null;\n if (fnReady) fnReady();\n }\n }\n }\n\n /**\n * isBusy(fCancel)\n *\n * Return the \"busy\" state of the component\n *\n * @this {Component}\n * @param {boolean} [fCancel] is set to true to cancel a \"busy\" state\n * @return {boolean} true if \"busy\", false if not\n */\n isBusy(fCancel)\n {\n if (this.flags.busy) {\n if (fCancel) {\n this.flags.busyCancel = true;\n } else if (fCancel === undefined) {\n this.println(this.toString() + \" busy\");\n }\n }\n return this.flags.busy;\n }\n\n /**\n * setBusy(fBusy)\n *\n * Update the current busy state; if a busyCancel request is pending, it will be honored now.\n *\n * @this {Component}\n * @param {boolean} fBusy\n * @return {boolean}\n */\n setBusy(fBusy)\n {\n if (this.flags.busyCancel) {\n this.flags.busy = false;\n this.flags.busyCancel = false;\n return false;\n }\n if (this.flags.error) {\n this.println(this.toString() + \" error\");\n return false;\n }\n this.flags.busy = fBusy;\n return this.flags.busy;\n }\n\n /**\n * powerUp(fSave)\n *\n * @this {Component}\n * @param {Object|null} data\n * @param {boolean} [fRepower] is true if this is \"repower\" notification\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n this.flags.powered = true;\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Component}\n * @param {boolean} fSave\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n if (fShutdown) this.flags.powered = false;\n return true;\n }\n\n /**\n * messageEnabled(bitsMessage)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n *\n * @this {Component}\n * @param {number} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n * @return {boolean} true if all specified message enabled, false if not\n */\n messageEnabled(bitsMessage = 0)\n {\n if (DEBUGGER && this.dbg) {\n if (this !== this.dbg) {\n bitsMessage = bitsMessage || this.bitsMessage;\n }\n var bitsEnabled = this.dbg.bitsMessage & bitsMessage;\n /*\n * This next \"bit\" of logic is for PCx86 and any other machine where we've expanded the set of\n * messages by reusing bits in the low nibbles in combination with different bits in the high nibble.\n * If the input bits adhere to that format, then the mask we just produced must adhere to it as well,\n * and if it doesn't, zero the mask, ensuring that the test will return false.\n */\n if ((bitsMessage & 0xf0000000) && (bitsMessage & 0x0fffffff)) {\n if (!(bitsEnabled & 0xf0000000) || !(bitsEnabled & 0x0fffffff)) bitsEnabled = 0;\n }\n if (bitsMessage && bitsEnabled === bitsMessage) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * printf(format, ...args)\n *\n * @this {Component}\n * @param {string} format\n * @param {...} args\n */\n printf(format, ...args)\n {\n if (DEBUGGER && this.dbg) {\n if (this.messageEnabled()) {\n let s = Str.sprintf(format, ...args);\n /*\n * Since dbg.message() calls println(), we strip any ending linefeed.\n * \n * We could bypass the Debugger and go straight to this.print(), but we would lose\n * the benefits of debugger messages (eg, automatic buffering, halting, yielding, etc).\n */\n if (s.slice(-1) == '\\n') s = s.slice(0, -1);\n this.dbg.message(s);\n }\n }\n }\n\n /**\n * printMessage(sMessage, bitsMessage, fAddress)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n * If bitsMessage is true, the message is displayed regardless.\n *\n * @this {Component}\n * @param {string} sMessage is any caller-defined message string\n * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n * @param {boolean} [fAddress] is true to display the current address\n */\n printMessage(sMessage, bitsMessage, fAddress)\n {\n if (DEBUGGER && this.dbg) {\n if (bitsMessage === true || this.messageEnabled(bitsMessage | 0)) {\n this.dbg.message(sMessage, fAddress);\n }\n }\n }\n\n /**\n * printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n * If bitsMessage is true, the message is displayed as long as MESSAGE.PORT is enabled.\n *\n * @this {Component}\n * @param {number} port\n * @param {number|null} bOut if an output operation\n * @param {number|null} [addrFrom]\n * @param {string|null} [name] of the port, if any\n * @param {number|null} [bIn] is the input value, if known, on an input operation\n * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n */\n printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage)\n {\n if (DEBUGGER && this.dbg) {\n if (bitsMessage === true) {\n bitsMessage = 0;\n } else if (bitsMessage == null) {\n bitsMessage = this.bitsMessage;\n }\n this.dbg.messageIO(this, port, bOut, addrFrom, name, bIn, bitsMessage);\n }\n }\n}\n\n/*\n * Types recognized and supported by selected functions (eg, Computer.getMachineParm())\n */\nComponent.TYPE = {\n NUMBER: \"number\",\n OBJECT: \"object\",\n STRING: \"string\"\n};\n\n/*\n * These are the standard PRINT values you can pass as an optional argument to println(); in reality,\n * you can pass anything you want, because they are simply prepended to the message, although PROGRESS\n * messages may also be merged with earlier similar messages to keep the output buffer under control.\n */\nComponent.PRINT = {\n ERROR: \"error\",\n NOTICE: \"notice\",\n PROGRESS: \"progress\",\n SCRIPT: \"script\",\n WARNING: \"warning\"\n};\n\n/*\n * Every component created on the current page is recorded in this array (see Component.add()),\n * enabling any component to locate another component by ID (see Component.getComponentByID())\n * or by type (see Component.getComponentByType()).\n *\n * Every machine on the page are now recorded as well, by their machine ID. We then record the\n * various resources used by that machine.\n *\n * Includes a fallback for non-browser-based environments (ie, Node). TODO: This will need to be\n * tailored to Node, probably using the global object instead of the window object, if we ever want\n * to support multi-machine configs in that environment.\n */\nif (window) {\n if (!window['PCjs']) window['PCjs'] = {};\n if (!window['PCjs']['Machines']) window['PCjs']['Machines'] = {};\n if (!window['PCjs']['Components']) window['PCjs']['Components'] = [];\n if (!window['PCjs']['Commands']) window['PCjs']['Commands'] = {};\n}\nComponent.machines = window? window['PCjs']['Machines'] : {};\nComponent.components = window? window['PCjs']['Components'] : [];\nComponent.commands = window? window['PCjs']['Commands'] : {};\n\nComponent.asyncCommands = [\n 'hold', 'sleep', 'wait'\n];\nComponent.globalCommands = {\n 'alert': Component.scriptAlert,\n 'sleep': Component.scriptSleep\n};\nComponent.componentCommands = {\n 'select': Component.scriptSelect\n};\nComponent.printBuffer = \"\";\n\n/*\n * The following polyfills provide ES5 functionality that's missing in older browsers (eg, IE8),\n * allowing PCjs apps to run without slamming into exceptions; however, due to the lack of HTML5 canvas\n * support in those browsers, all you're likely to see are \"soft\" errors (eg, \"Missing <canvas> support\").\n *\n * Perhaps we can implement a text-only faux video display for a fun retro-browser experience someday.\n *\n * TODO: Come up with a better place to put these polyfills. We will likely have more if we decide to\n * make the leap from ES5 to ES6 features.\n */\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf\n */\nif (!Array.prototype.indexOf) {\n Array.prototype.indexOf = function(obj, start) {\n for (var i = (start || 0), j = this.length; i < j; i++) {\n if (this[i] === obj) { return i; }\n }\n return -1;\n }\n}\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray\n */\nif (!Array.isArray) {\n Array.isArray = function(arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n };\n}\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind\n */\nif (!Function.prototype.bind) {\n Function.prototype.bind = function(obj) {\n if (typeof this != \"function\") {\n // Closest thing possible to the ECMAScript 5 internal IsCallable function\n throw new TypeError(\"Function.prototype.bind: non-callable object\");\n }\n var args = Array.prototype.slice.call(arguments, 1);\n var fToBind = this;\n var fnNOP = /** @constructor */ (function() {});\n var fnBound = function() {\n return fToBind.apply(this instanceof fnNOP && obj? this : obj, args.concat(/** @type {Array} */(Array.prototype.slice.call(arguments))));\n };\n fnNOP.prototype = this.prototype;\n fnBound.prototype = new fnNOP();\n return fnBound;\n };\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/defines.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @define {string}\n */\nvar APPCLASS = \"pcx86\"; // this @define is the default application class (eg, \"pcx86\", \"c1pjs\")\n\n/**\n * @define {string}\n */\nvar APPNAME = \"PCx86\"; // this @define is the default application name (eg, \"PCx86\", \"C1Pjs\")\n\n/**\n * @define {boolean}\n *\n * WARNING: DEBUGGER needs to accurately reflect whether or not the Debugger component is (or will be) loaded.\n * In the compiled case, we rely on the Closure Compiler to override DEBUGGER as appropriate. When it's *false*,\n * nearly all of debugger.js will be conditionally removed by the compiler, reducing it to little more than a\n * \"type skeleton\", which also solves some type-related warnings we would otherwise have if we tried to remove\n * debugger.js from the compilation process altogether.\n *\n * However, when we're in \"development mode\" and running uncompiled code in debugger-less configurations,\n * I would like to skip loading debugger.js altogether. When doing that, we must ALSO arrange for an additional file\n * (nodebugger.js) to be loaded immediately after this file, which *explicitly* overrides DEBUGGER with *false*.\n */\nvar DEBUGGER = true; // this @define is overridden by the Closure Compiler to remove Debugger-related support\n\n/**\n * @define {boolean}\n *\n * PREFETCH enables the use of a prefetch queue. As of v1.20.0, PREFETCH support has been updated and retested,\n * but as currently implemented, it does not yield as much improvement as I'd hoped when paging is enabled, so PREFETCH\n * is still off by default.\n */\nvar PREFETCH = false;\n\n/**\n * @define {boolean}\n *\n * BYTEARRAYS is a Closure Compiler compile-time option that allocates an Array of numbers for every Memory block,\n * where each a number represents ONE byte; very wasteful, but potentially slightly faster.\n *\n * See the Memory component for details.\n */\nvar BYTEARRAYS = false;\n\n/**\n * TYPEDARRAYS enables use of typed arrays for Memory blocks. This used to be a compile-time-only option, but I've\n * added Memory access functions for typed arrays (see Memory.afnTypedArray), so support can be enabled dynamically now.\n *\n * See the Memory component for details.\n */\nvar TYPEDARRAYS = (typeof ArrayBuffer !== 'undefined');\n\n/**\n * @define {boolean}\n *\n * BACKTRACK enables backtracking: a mechanism that allows us to tag every byte of incoming data and follow the\n * flow of that data.\n *\n * This is set to !COMPILED, disabling backtracking in all compiled versions, but we may eventually set it to\n * match the DEBUGGER setting -- unless it slows down machines using the built-in Debugger too much, in which case\n * we'll have to rethink that choice OR provide a Debugger command that dynamically enables/disables as much of\n * the backtracking support as possible.\n *\n * TODO: BACKTRACK support is currently completely disabled until we have a chance to investigate the problem\n * discussed in Bus.addBackTrackObject().\n */\nvar BACKTRACK = !COMPILED && DEBUGGER;\n\n/**\n * @define {boolean}\n *\n * SYMBOLS enables automatic symbol generation from known DLL, EXE and VXD file formats. It's currently\n * enabled whenever DEBUGGER support is enabled.\n */\nvar SYMBOLS = DEBUGGER;\n\n/**\n * @define {boolean}\n *\n * BUGS_8086 enables support for known 8086 bugs. It's turned off by default, because 1) it adds overhead, and\n * 2) it's hard to imagine any software actually being dependent on any of the bugs covered by this (eg, the failure\n * to properly restart string instructions with multiple prefixes, or the failure to inhibit hardware interrupts\n * following SS segment loads).\n */\nvar BUGS_8086 = false;\n\n/**\n * @define {boolean}\n *\n * I386 enables 80386 support. My preference continues to be one \"binary\" that supports all implemented CPUs, but\n * I'm providing this to enable a slimmed-down binary, at least until 80386 support is actually finished; at the\n * moment, there's just a lot of scaffolding that bloats the compiled version without adding any real functionality.\n */\nvar I386 = true;\n\n/**\n * @define {boolean}\n *\n * DESKPRO386 enables COMPAQ DeskPro 386 support. Requires I386 support as well (duh).\n */\nvar DESKPRO386 = I386;\n\n/**\n * @define {boolean}\n *\n * PAGEBLOCKS enables 80386 paging support with assistance from the Bus component. This affects how the Bus component\n * defines physical memory parameters for a 32-bit bus. With the 8086 and 80286 processors, the Bus component was free\n * to choose any block size for physical memory allocations that made sense for the bus width (eg, 4Kb blocks for a\n * 20-bit bus, or 16Kb blocks for a 24-bit bus).\n *\n * However, for the 80386 processor, it makes more sense to choose a block size that matches the page size (ie, 4Kb),\n * because then we have the option of altering the address-to-memory mapping for any block to match whatever page table\n * mapping is in effect for that address, if any, without requiring another layer of address translation.\n */\nvar PAGEBLOCKS = I386;\n\n/*\n * Combine all the shared globals and machine-specific globals into one machine-specific global object,\n * which all machine components should start using; eg: \"if (PCX86.DEBUG) ...\" instead of \"if (DEBUG) ...\".\n */\nvar PCX86 = {\n APPCLASS: APPCLASS,\n APPNAME: APPNAME,\n APPVERSION: APPVERSION, // shared\n BACKTRACK: BACKTRACK,\n BUGS_8086: BUGS_8086,\n BYTEARRAYS: BYTEARRAYS,\n COMPILED: COMPILED, // shared\n CSSCLASS: CSSCLASS, // shared\n DEBUG: DEBUG, // shared\n DEBUGGER: DEBUGGER,\n DESKPRO386: DESKPRO386,\n I386: I386,\n MAXDEBUG: MAXDEBUG, // shared\n PAGEBLOCKS: PAGEBLOCKS,\n PREFETCH: PREFETCH,\n PRIVATE: PRIVATE, // shared\n TYPEDARRAYS: TYPEDARRAYS,\n SITEHOST: SITEHOST, // shared\n SYMBOLS: SYMBOLS,\n XMLVERSION: XMLVERSION // shared\n};\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/x86.js (C) Jeff Parsons 2012-2018\n */\n\nvar X86 = {\n /*\n * CPU model numbers (supported)\n */\n MODEL_8086: 8086,\n MODEL_8088: 8088,\n MODEL_80186: 80186,\n MODEL_80188: 80188,\n MODEL_80286: 80286,\n MODEL_80386: 80386,\n\n /*\n * 80386 CPU stepping identifiers (supported)\n */\n STEPPING_80386_A0: (80386+0xA0), // we have very little information about this stepping...\n STEPPING_80386_A1: (80386+0xA1), // we know much more about the A1 stepping (see /blog/2015/02/23/README.md)\n STEPPING_80386_B0: (80386+0xB0), // for now, the only B0 difference in PCx86 is support for XBTS and IBTS\n STEPPING_80386_B1: (80386+0xB1), // our implementation of the B1 stepping also includes the infamous 32-bit multiplication bug\n STEPPING_80386_B2: (80386+0xB2), // this is an imaginary stepping that simply means \"B1 without the 32-bit multiplication bug\" (ie, a B1 with the \"double sigma\" stamp)\n STEPPING_80386_C0: (80386+0xC0), // this presumably fixed lots of B1 issues, but it seems to have been quickly superseded by the D0\n STEPPING_80386_D0: (80386+0xD0), // we don't have any detailed information (eg, errata) for these later steppings\n STEPPING_80386_D1: (80386+0xD1),\n STEPPING_80386_D2: (80386+0xD2),\n\n /*\n * This constant is used to mark points in the code where the physical address being returned\n * is invalid and should not be used. TODO: There are still functions that will use an invalid\n * address, which is why we've tried to choose a value that causes the least harm, but ultimately,\n * we must add checks to those functions or throw special JavaScript exceptions to bypass them.\n *\n * This value is also used to indicate non-existent EA address calculations, which are usually\n * detected with \"regEA === ADDR_INVALID\" and \"regEAWrite === ADDR_INVALID\" tests. In a 32-bit\n * CPU, -1 (ie, 0xffffffff) could actually be a valid address, so consider changing ADDR_INVALID\n * to NaN or null (which is also why all ADDR_INVALID tests should use strict equality operators).\n *\n * The main reason I'm NOT using NaN or null now is my concern that, by mixing non-numbers\n * (specifically, values outside the range of signed 32-bit integers), performance may suffer.\n *\n * WARNING: Like many of the properties defined here, ADDR_INVALID is a common constant, which the\n * Closure Compiler will happily inline (with or without @const annotations; in fact, I've yet to\n * see a @const annotation EVER improve automatic inlining). However, if you don't make ABSOLUTELY\n * certain that this file is included BEFORE the first reference to any of these properties, that\n * automatic inlining will no longer occur.\n */\n ADDR_INVALID: -1,\n\n /*\n * Processor Exception Interrupts\n *\n * Of the following exceptions, all are designed to be restartable, except for 0x08 and 0x09 (and 0x0D\n * after an attempt to write to a read-only segment).\n *\n * Error codes are pushed onto the stack for 0x08 (always 0) and 0x0A through 0x0E.\n *\n * Priority: Instruction exception, TRAP, NMI, Processor Extension Segment Overrun, and finally INTR.\n *\n * All exceptions can also occur in real-mode, except where noted. A GP_FAULT in real-mode can be triggered\n * by \"any memory reference instruction that attempts to reference [a] 16-bit word at offset 0xFFFF\".\n *\n * Interrupts beyond 0x10 (up through 0x1F) are reserved for future exceptions.\n *\n * Implementation Detail: For any opcode we know must generate a UD_FAULT interrupt, we invoke opInvalid(),\n * NOT opUndefined(). UD_FAULT is for INVALID opcodes, Intel's choice of term \"undefined\" notwithstanding.\n *\n * We reserve the term \"undefined\" for opcodes that require more investigation, and we invoke opUndefined()\n * ONLY until an opcode's behavior has finally been defined, at which point it becomes either valid or invalid.\n * The term \"illegal\" seems completely superfluous; we don't need a third way of describing invalid opcodes.\n *\n * The term \"undocumented\" should be limited to operations that are valid but Intel simply never documented.\n */\n EXCEPTION: {\n DE_EXC: 0x00, // Divide Error Exception (#DE: fault, no error code)\n DB_EXC: 0x01, // Debug (aka Single Step Trap) Exception (#DB: fault or trap)\n NMI: 0x02, // Non-Maskable Interrupt\n BP_TRAP: 0x03, // Breakpoint Exception (#BP: trap)\n OF_TRAP: 0x04, // INTO Overflow Exception (#OF: trap)\n BR_FAULT: 0x05, // BOUND Error Exception (#BR: fault, no error code)\n UD_FAULT: 0x06, // Invalid (aka Undefined/Illegal) Opcode (#UD: fault, no error code)\n NM_FAULT: 0x07, // No Math Unit Available; see ESC or WAIT (#NM: fault, no error code)\n DF_FAULT: 0x08, // Double Fault; see LIDT (#DF: fault, with error code)\n MP_FAULT: 0x09, // Math Unit Protection Fault; see ESC (#MP: fault, no error code)\n TS_FAULT: 0x0A, // Invalid Task State Segment Fault (#TS: fault, with error code; protected-mode only)\n NP_FAULT: 0x0B, // Not Present Fault (#NP: fault, with error code; protected-mode only)\n SS_FAULT: 0x0C, // Stack Fault (#SS: fault, with error code; protected-mode only)\n GP_FAULT: 0x0D, // General Protection Fault (#GP: fault, with error code)\n PF_FAULT: 0x0E, // Page Fault (#PF: fault, with error code)\n MF_FAULT: 0x10 // Math Fault; see ESC or WAIT (#MF: fault, no error code)\n },\n /*\n * Processor Status flag definitions (stored in regPS)\n */\n PS: {\n CF: 0x0001, // bit 0: Carry flag\n BIT1: 0x0002, // bit 1: reserved, always set\n PF: 0x0004, // bit 2: Parity flag\n BIT3: 0x0008, // bit 3: reserved, always clear\n AF: 0x0010, // bit 4: Auxiliary Carry flag (aka Arithmetic flag)\n BIT5: 0x0020, // bit 5: reserved, always clear\n ZF: 0x0040, // bit 6: Zero flag\n SF: 0x0080, // bit 7: Sign flag\n TF: 0x0100, // bit 8: Trap flag\n IF: 0x0200, // bit 9: Interrupt flag\n DF: 0x0400, // bit 10: Direction flag\n OF: 0x0800, // bit 11: Overflow flag\n IOPL: {\n MASK: 0x3000, // bits 12-13: I/O Privilege Level (always set on 8086/80186; clear on 80286 reset)\n SHIFT: 12\n },\n NT: 0x4000, // bit 14: Nested Task flag (always set on 8086/80186; clear on 80286 reset)\n BIT15: 0x8000, // bit 15: reserved (always set on 8086/80186; clear otherwise)\n RF: 0x10000, // bit 16: Resume Flag (temporarily disables debug exceptions; 80386 only)\n VM: 0x20000 // bit 17: Virtual 8086 Mode (80386 only)\n },\n CR0: {\n /*\n * Machine Status Word (MSW) bit definitions\n */\n MSW: {\n PE: 0x0001, // protected-mode enabled\n MP: 0x0002, // monitor processor extension (ie, coprocessor)\n EM: 0x0004, // emulate processor extension\n TS: 0x0008, // task switch indicator\n ON: 0xFFF0, // on the 80286, these bits are always on (TODO: Verify)\n MASK: 0xFFFF // these are the only (MSW) bits that the 80286 can access (within CR0)\n },\n ET: 0x00000010, // coprocessor type (80287 or 80387); always 1 on post-80386 CPUs\n PG: 0x80000000|0 // 0: paging disabled\n },\n DR7: { // Debug Control Register\n L0: 0x00000001,\n G0: 0x00000002,\n L1: 0x00000004,\n G1: 0x00000008,\n L2: 0x00000010,\n G2: 0x00000020,\n L3: 0x00000040,\n G3: 0x00000080,\n ENABLE: 0x000000FF,\n LE: 0x00000100,\n GE: 0x00000200,\n RW0: 0x00030000, // 00: exec-only 01: write-only 10: undefined 11: read/write-only\n LEN0: 0x000C0000, // 00: one-byte, 01: two-byte, 10: undefined 11: four-byte\n RW1: 0x00300000, // 00: exec-only 01: write-only 10: undefined 11: read/write-only\n LEN1: 0x00C00000, // 00: one-byte, 01: two-byte, 10: undefined 11: four-byte\n RW2: 0x03000000, // 00: exec-only 01: write-only 10: undefined 11: read/write-only\n LEN2: 0x0C000000, // 00: one-byte, 01: two-byte, 10: undefined 11: four-byte\n RW3: 0x30000000, // 00: exec-only 01: write-only 10: undefined 11: read/write-only\n LEN3: 0xC0000000|0// 00: one-byte, 01: two-byte, 10: undefined 11: four-byte\n },\n DR6: { // Debug Status Register\n B0: 0x00000001,\n B1: 0x00000002,\n B2: 0x00000004,\n B3: 0x00000008,\n BD: 0x00002000, // set if the next instruction will read or write one of the eight debug registers and ICE-386 is also using them\n BS: 0x00004000, // set if the debug handler is entered due to the TF (trap flag) bit set in the EFLAGS register\n BT: 0x00008000 // set before entering the DEBUG handler if a task switch has occurred and the T-bit of the new TSS is set\n },\n SEL: {\n RPL: 0x0003, // requested privilege level (0-3)\n LDT: 0x0004, // table indicator (0: GDT, 1: LDT)\n MASK: 0xFFF8 // table offset\n },\n DESC: { // Descriptor Table Entry\n LIMIT: { // LIMIT bits 0-15 (or OFFSET if this is an INTERRUPT or TRAP gate)\n OFFSET: 0x0\n },\n BASE: { // BASE bits 0-15 (or SELECTOR if this is a TASK, INTERRUPT or TRAP gate)\n OFFSET: 0x2\n },\n ACC: { // bit definitions for the access word (offset 0x4)\n OFFSET: 0x4,\n BASE1623: 0x00FF, // (not used if this a TASK, INTERRUPT or TRAP gate; bits 0-5 are parm count for CALL gates)\n TYPE: {\n OFFSET: 0x5,\n MASK: 0x1F00,\n SEG: 0x1000,\n NONSEG: 0x0F00,\n /*\n * The following bits apply only when SEG is set\n */\n CODE: 0x0800, // set for CODE, clear for DATA\n ACCESSED: 0x0100, // set if accessed, clear if not accessed\n READABLE: 0x0200, // CODE: set if readable, clear if exec-only\n WRITABLE: 0x0200, // DATA: set if writable, clear if read-only\n CONFORMING: 0x0400, // CODE: set if conforming, clear if not\n EXPDOWN: 0x0400, // DATA: set if expand-down, clear if not\n /*\n * Assorted bits that apply only within NONSEG values\n */\n TSS_BUSY: 0x0200,\n NONSEG_386: 0x0800, // 80386 and up\n /*\n * The following are all the possible (valid) types (well, except for the variations\n * of DATA and CODE where the ACCESSED bit (0x0100) may also be set)\n */\n TSS286: 0x0100,\n LDT: 0x0200,\n TSS286_BUSY: 0x0300,\n GATE_CALL: 0x0400,\n GATE_TASK: 0x0500,\n GATE286_INT: 0x0600,\n GATE286_TRAP: 0x0700,\n TSS386: 0x0900, // 80386 and up\n TSS386_BUSY: 0x0B00, // 80386 and up\n GATE386_CALL: 0x0C00, // 80386 and up\n GATE386_INT: 0x0E00, // 80386 and up\n GATE386_TRAP: 0x0F00, // 80386 and up\n CODE_OR_DATA: 0x1E00,\n DATA_READONLY: 0x1000,\n DATA_WRITABLE: 0x1200,\n DATA_EXPDOWN: 0x1400,\n DATA_EXPDOWN_WRITABLE: 0x1600,\n CODE_EXECONLY: 0x1800,\n CODE_READABLE: 0x1A00,\n CODE_CONFORMING: 0x1C00,\n CODE_CONFORMING_READABLE: 0x1E00\n },\n DPL: {\n MASK: 0x6000,\n SHIFT: 13\n },\n PRESENT: 0x8000,\n INVALID: 0 // use X86.DESC.ACC.INVALID for invalid ACC values\n },\n EXT: { // descriptor extension word (reserved on the 80286; \"must be zero\")\n OFFSET: 0x6,\n LIMIT1619: 0x000F,\n AVAIL: 0x0010, // NOTE: set in various descriptors in OS/2\n /*\n * The BIG bit is known as the D bit for code segments; when set, all addresses and operands\n * in that code segment are assumed to be 32-bit.\n *\n * The BIG bit is known as the B bit for data segments; when set, it indicates: 1) all pushes,\n * pops, calls and returns use ESP instead of SP, and 2) the upper bound of an expand-down segment\n * is 0xffffffff instead of 0xffff.\n */\n BIG: 0x0040, // clear if default operand/address size is 16-bit, set if 32-bit\n LIMITPAGES: 0x0080, // clear if limit granularity is bytes, set if limit granularity is 4Kb pages\n BASE2431: 0xFF00\n },\n INVALID: 0 // use X86.DESC.INVALID for invalid DESC values\n },\n LADDR: { // linear address\n PDE: { // index of page directory entry\n MASK: 0xFFC00000|0,\n SHIFT: 20 // (addr & DIR.MASK) >>> DIR.SHIFT yields a page directory offset (ie, index * 4)\n },\n PTE: { // index of page table entry\n MASK: 0x003FF000,\n SHIFT: 10 // (addr & PAGE.MASK) >>> PAGE.SHIFT yields a page table offset (ie, index * 4)\n },\n OFFSET: 0x00000FFF\n },\n PTE: {\n FRAME: 0xFFFFF000|0,\n DIRTY: 0x00000040, // page has been modified\n ACCESSED: 0x00000020, // page has been accessed\n USER: 0x00000004, // set for user level (CPL 3), clear for supervisor level (CPL 0-2)\n READWRITE: 0x00000002, // set for read/write, clear for read-only (affects CPL 3 only)\n PRESENT: 0x00000001 // set for present page, clear for not-present page\n },\n TSS286: {\n PREV_TSS: 0x00,\n CPL0_SP: 0x02, // start of values altered by task switches\n CPL0_SS: 0x04,\n CPL1_SP: 0x06,\n CPL1_SS: 0x08,\n CPL2_SP: 0x0A,\n CPL2_SS: 0x0C,\n TASK_IP: 0x0E,\n TASK_PS: 0x10,\n TASK_AX: 0x12,\n TASK_CX: 0x14,\n TASK_DX: 0x16,\n TASK_BX: 0x18,\n TASK_SP: 0x1A,\n TASK_BP: 0x1C,\n TASK_SI: 0x1E,\n TASK_DI: 0x20,\n TASK_ES: 0x22,\n TASK_CS: 0x24,\n TASK_SS: 0x26,\n TASK_DS: 0x28, // end of values altered by task switches\n TASK_LDT: 0x2A\n },\n TSS386: {\n PREV_TSS: 0x00,\n CPL0_ESP: 0x04, // start of values altered by task switches\n CPL0_SS: 0x08,\n CPL1_ESP: 0x0c,\n CPL1_SS: 0x10,\n CPL2_ESP: 0x14,\n CPL2_SS: 0x18,\n TASK_CR3: 0x1C, // (not in TSS286)\n TASK_EIP: 0x20,\n TASK_PS: 0x24,\n TASK_EAX: 0x28,\n TASK_ECX: 0x2C,\n TASK_EDX: 0x30,\n TASK_EBX: 0x34,\n TASK_ESP: 0x38,\n TASK_EBP: 0x3C,\n TASK_ESI: 0x40,\n TASK_EDI: 0x44,\n TASK_ES: 0x48,\n TASK_CS: 0x4C,\n TASK_SS: 0x50,\n TASK_DS: 0x54,\n TASK_FS: 0x58, // (not in TSS286)\n TASK_GS: 0x5C, // (not in TSS286) end of values altered by task switches\n TASK_LDT: 0x60,\n TASK_IOPM: 0x64 // (not in TSS286)\n },\n ERRCODE: {\n EXT: 0x0001,\n IDT: 0x0002,\n LDT: 0x0004,\n SELMASK: 0xFFFC\n },\n RESULT: {\n /*\n * Flags were originally computed using 16-bit result registers:\n *\n * CF: resultZeroCarry & resultSize (ie, 0x100 or 0x10000)\n * PF: resultParitySign & 0xff\n * AF: (resultParitySign ^ resultAuxOverflow) & 0x0010\n * ZF: resultZeroCarry & (resultSize - 1)\n * SF: resultParitySign & (resultSize >> 1)\n * OF: (resultParitySign ^ resultAuxOverflow ^ (resultParitySign >> 1)) & (resultSize >> 1)\n *\n * I386 support requires that we now rely on 32-bit result registers:\n *\n * resultDst, resultSrc, resultArith, resultLogic and resultType\n *\n * and flags are now computed as follows:\n *\n * CF: ((resultDst ^ ((resultDst ^ resultSrc) & (resultSrc ^ resultArith))) & resultType)\n * PF: (resultLogic & 0xff)\n * AF: ((resultArith ^ (resultDst ^ resultSrc)) & 0x0010)\n * ZF: (resultLogic & ((resultType - 1) | resultType))\n * SF: (resultLogic & resultType)\n * OF: (((resultDst ^ resultArith) & (resultSrc ^ resultArith)) & resultType)\n *\n * where resultType contains both a size, which must be one of BYTE (0x80), WORD (0x8000),\n * or DWORD (0x80000000), along with bits for each of the arithmetic and/or logical flags that\n * are currently \"cached\" in the result registers (eg, X86.RESULT.CF for carry, X86.RESULT.OF\n * for overflow, etc).\n *\n * WARNING: Do not confuse these RESULT flag definitions with the PS flag definitions. RESULT\n * flags are used only as \"cached\" flag indicators, packed into bits 0-5 of resultType; they do\n * not match the actual flag bit definitions within the Processor Status (PS) register.\n *\n * Arithmetic operations should call:\n *\n * setArithResult(dst, src, value, type)\n * eg:\n * setArithResult(dst, src, dst+src, X86.RESULT.BYTE | X86.RESULT.ALL)\n *\n * and logical operations should call:\n *\n * setLogicResult(value, type [, carry [, overflow]])\n *\n * Since most logical operations clear both CF and OF, most calls to setLogicResult() can omit the\n * last two optional parameters.\n *\n * The type parameter of these methods indicates both the size of the result (BYTE, WORD or DWORD)\n * and which of the flags should now be considered \"cached\" by the result registers. If the previous\n * resultType specifies any flags not present in the new type parameter, then those flags are\n * calculated and written to the appropriate regPS bit(s) *before* the result registers are updated.\n *\n * Arithmetic operations are assumed to represent an \"added\" result; if a \"subtracted\" result is\n * provided instead (eg, from CMP, DEC, SUB, etc), then setArithResult() must include a 5th parameter\n * (fSubtract); eg:\n *\n * setArithResult(dst, src, dst-src, X86.RESULT.BYTE | X86.RESULT.ALL, true)\n *\n * TODO: Consider separating setArithResult() into two functions: setAddResult() and setSubResult().\n */\n BYTE: 0x80, // result is byte value\n WORD: 0x8000, // result is word value\n DWORD: 0x80000000|0,\n TYPE: 0x80008080|0,\n CF: 0x01, // carry flag is cached\n PF: 0x02, // parity flag is cached\n AF: 0x04, // aux carry flag is cached\n ZF: 0x08, // zero flag is cached\n SF: 0x10, // sign flag is cached\n OF: 0x20, // overflow flag is cached\n ALL: 0x3F, // all result flags are cached\n LOGIC: 0x1A, // all logical flags are cached; see setLogicResult()\n NOTCF: 0x3E // all result flags EXCEPT carry are cached\n },\n /*\n * Bit values for opFlags, which are all reset to zero prior to each instruction\n */\n OPFLAG: {\n NOREAD: 0x0001, // disable memory reads for the remainder of the current instruction\n NOWRITE: 0x0002, // disable memory writes for the remainder of the current instruction\n NOINTR: 0x0004, // a segreg has been set, or a prefix, or an STI (delay INTR acknowledgement)\n WRAP: 0x0008, // a segment wrap-around has occurred (relevant to 8086/8088 only)\n SEG: 0x0010, // segment override\n LOCK: 0x0020, // lock prefix\n REPZ: 0x0040, // repeat while Z (NOTE: this value MUST match PS.ZF; see opCMPSb/opCMPSw/opSCASb/opSCASw)\n REPNZ: 0x0080, // repeat while NZ\n REPEAT: 0x0100, // an instruction is being repeated (ie, some iteration AFTER the first)\n PUSHSP: 0x0200, // the SP register is potentially being referenced by a PUSH SP opcode, adjustment may be required\n DATASIZE: 0x0400, // data size override\n ADDRSIZE: 0x0800, // address size override\n FAULT: 0x1000, // a fault occurred during the current instruction\n DBEXC: 0x2000 // a DB_EXC exception occurred during the current instruction\n },\n /*\n * Bit values for intFlags\n */\n INTFLAG: {\n NONE: 0x00,\n INTR: 0x01, // h/w interrupt requested\n TRAP: 0x02, // trap (INT 0x01) requested\n HALT: 0x04, // halt (HLT) requested\n DMA: 0x08 // async DMA operation in progress\n },\n /*\n * Common opcodes (and/or any opcodes we need to refer to explicitly)\n */\n OPCODE: {\n ES: 0x26, // opES()\n CS: 0x2E, // opCS()\n SS: 0x36, // opSS()\n DS: 0x3E, // opDS()\n PUSHSP: 0x54, // opPUSHSP()\n PUSHA: 0x60, // opPUSHA() (80186 and up)\n POPA: 0x61, // opPOPA() (80186 and up)\n BOUND: 0x62, // opBOUND() (80186 and up)\n ARPL: 0x63, // opARPL() (80286 and up)\n FS: 0x64, // opFS() (80386 and up)\n GS: 0x65, // opGS() (80386 and up)\n OS: 0x66, // opOS() (80386 and up)\n AS: 0x67, // opAS() (80386 and up)\n PUSHN: 0x68, // opPUSHn() (80186 and up)\n IMULN: 0x69, // opIMULn() (80186 and up)\n PUSH8: 0x6A, // opPUSH8() (80186 and up)\n IMUL8: 0x6B, // opIMUL8() (80186 and up)\n INSB: 0x6C, // opINSb() (80186 and up)\n INSW: 0x6D, // opINSw() (80186 and up)\n OUTSB: 0x6E, // opOUTSb() (80186 and up)\n OUTSW: 0x6F, // opOUTSw() (80186 and up)\n ENTER: 0xC8, // opENTER() (80186 and up)\n LEAVE: 0xC9, // opLEAVE() (80186 and up)\n CALLF: 0x9A, // opCALLF()\n MOVSB: 0xA4, // opMOVSb()\n MOVSW: 0xA5, // opMOVSw()\n CMPSB: 0xA6, // opCMPSb()\n CMPSW: 0xA7, // opCMPSw()\n STOSB: 0xAA, // opSTOSb()\n STOSW: 0xAB, // opSTOSw()\n LODSB: 0xAC, // opLODSb()\n LODSW: 0xAD, // opLODSw()\n SCASB: 0xAE, // opSCASb()\n SCASW: 0xAF, // opSCASw()\n INT3: 0xCC, // opINT3()\n INTN: 0xCD, // opINTn()\n INTO: 0xCE, // opINTO()\n IRET: 0xCF, // opIRET()\n ESC0: 0xD8, // opESC0()\n ESC1: 0xD9, // opESC1()\n ESC2: 0xDA, // opESC2()\n ESC3: 0xDB, // opESC3()\n ESC4: 0xDC, // opESC4()\n ESC5: 0xDD, // opESC5()\n ESC6: 0xDE, // opESC6()\n ESC7: 0xDF, // opESC7()\n LOOPNZ: 0xE0, // opLOOPNZ()\n LOOPZ: 0xE1, // opLOOPZ()\n LOOP: 0xE2, // opLOOP()\n CALL: 0xE8, // opCALL()\n JMP: 0xE9, // opJMP() (2-byte displacement)\n JMPF: 0xEA, // opJMPF()\n JMPS: 0xEB, // opJMPs() (1-byte displacement)\n LOCK: 0xF0, // opLOCK()\n REPNZ: 0xF2, // opREPNZ()\n REPZ: 0xF3, // opREPZ()\n GRP4W: 0xFF,\n CALLW: 0x10FF, // GRP4W: fnCALLw()\n CALLFDW: 0x18FF, // GRP4W: fnCALLFdw()\n CALLMASK: 0x38FF, // mask 2-byte GRP4W opcodes with this before comparing to CALLW or CALLFDW\n UD2: 0x0B0F // UD2 (invalid opcode \"guaranteed\" to generate UD_FAULT on all post-8086 processors)\n },\n /*\n * Floating Point Unit (FPU), aka Numeric Data Processor (NDP), aka Numeric Processor Extension (NPX), aka Coprocessor definitions\n */\n FPU: {\n MODEL_8087: 8087,\n MODEL_80287: 80287,\n MODEL_80287XL: 80387, // internally, the 80287XL was an 80387SX, so generally, we treat this as MODEL_80387\n MODEL_80387: 80387,\n CONTROL: { // FPU Control Word\n IM: 0x0001, // bit 0: Invalid Operation Mask\n DM: 0x0002, // bit 1: Denormalized Operand Mask\n ZM: 0x0004, // bit 2: Zero Divide Mask\n OM: 0x0008, // bit 3: Overflow Mask\n UM: 0x0010, // bit 4: Underflow Mask\n PM: 0x0020, // bit 5: Precision Mask\n EXC: 0x003F, // all of the above exceptions\n IEM: 0x0080, // bit 7: Interrupt Enable Mask (0 enables interrupts, 1 masks them; 8087 only)\n PC: 0x0300, // bits 8-9: Precision Control\n RC: { // bits 10-11: Rounding Control\n NEAR: 0x0000,\n DOWN: 0x0400,\n UP: 0x0800,\n CHOP: 0x0C00,\n MASK: 0x0C00\n },\n IC: 0x1000, // bit 12: Infinity Control (0 for Projective, 1 for Affine)\n UNUSED: 0xE040, // bits 6,13-15: unused\n INIT: 0x03BF // X86.FPU.CONTROL.IM | X86.FPU.CONTROL.DM | X86.FPU.CONTROL.ZM | X86.FPU.CONTROL.OM | X86.FPU.CONTROL.UM | X86.FPU.CONTROL.PM | X86.FPU.CONTROL.IEM | X86.FPU.CONTROL.PC\n },\n STATUS: { // FPU Status Word\n IE: 0x0001, // bit 0: Invalid Operation\n DE: 0x0002, // bit 1: Denormalized Operand\n ZE: 0x0004, // bit 2: Zero Divide\n OE: 0x0008, // bit 3: Overflow\n UE: 0x0010, // bit 4: Underflow\n PE: 0x0020, // bit 5: Precision\n SF: 0x0040, // bit 6: Stack Fault (80387 and later; triggers an Invalid Operation exception)\n EXC: 0x007F, // all of the above exceptions\n ES: 0x0080, // bit 7: Error/Exception Status/Summary (Interrupt Request on 8087)\n C0: 0x0100, // bit 8: Condition Code 0\n C1: 0x0200, // bit 9: Condition Code 1\n C2: 0x0400, // bit 10: Condition Code 2\n ST: 0x3800, // bits 11-13: Stack Top\n ST_SHIFT: 11,\n C3: 0x4000, // bit 14: Condition Code 3\n CC: 0x4700, // all condition code bits\n BUSY: 0x8000 // bit 15: Busy\n },\n TAGS: {\n VALID: 0x0,\n ZERO: 0x1,\n SPECIAL:0x2,\n EMPTY: 0x3,\n MASK: 0x3\n }\n /*\n C3 C2 C1 C0 Condition Code (CC) values following an Examine\n\n 0 0 0 0 Valid, positive unnormalized (+Unnormal)\n 0 0 0 1 Invalid, positive, exponent=0 (+NaN)\n 0 0 1 0 Valid, negative, unnormalized (-Unnormal)\n 0 0 1 1 Invalid, negative, exponent=0 (-NaN)\n 0 1 0 0 Valid, positive, normalized (+Normal)\n 0 1 0 1 Infinity, positive (+Infinity)\n 0 1 1 0 Valid, negative, normalized (-Normal)\n 0 1 1 1 Infinity, negative (-Infinity)\n 1 0 0 0 Zero, positive (+0)\n 1 0 0 1 Empty\n 1 0 1 0 Zero, negative (-0)\n 1 0 1 1 Empty\n 1 1 0 0 Invalid, positive, exponent=0 (+Denormal)\n 1 1 0 1 Empty\n 1 1 1 0 Invalid, negative, exponent=0 (-Denormal)\n 1 1 1 1 Empty\n\n Condition Code (CC) values following an FCOM or FTST\n\n 0 0 ? 0 ST > source operand (FCOM); ST > 0 (FTST)\n 0 0 ? 1 ST < source operand (FCOM); ST < 0 (FTST)\n 1 0 ? 0 ST = source operand (FCOM); ST = 0 (FTST)\n 1 1 ? 1 ST is not comparable\n\n Condition Code (CC) values following a Remainder\n\n Q1 0 Q0 Q2 Complete reduction (he three low bits of the quotient stored in C0, C3, and C1)\n ? 1 ? ? Incomplete reduction\n */\n },\n CYCLES_8088: {\n nWordCyclePenalty: 4, // NOTE: accurate for the 8088/80188 only (on the 8086/80186, it applies to odd addresses only)\n nEACyclesBase: 5, // base or index only (BX, BP, SI or DI)\n nEACyclesDisp: 6, // displacement only\n nEACyclesBaseIndex: 7, // base + index (BP+DI and BX+SI)\n nEACyclesBaseIndexExtra: 8, // base + index (BP+SI and BX+DI require an extra cycle)\n nEACyclesBaseDisp: 9, // base or index + displacement\n nEACyclesBaseIndexDisp: 11, // base + index + displacement (BP+DI+n and BX+SI+n)\n nEACyclesBaseIndexDispExtra:12, // base + index + displacement (BP+SI+n and BX+DI+n require an extra cycle)\n nOpCyclesAAA: 4, // AAA, AAS, DAA, DAS, TEST acc,imm\n nOpCyclesAAD: 60,\n nOpCyclesAAM: 83,\n nOpCyclesArithRR: 3, // ADC, ADD, AND, OR, SBB, SUB, XOR and CMP reg,reg cycle time\n nOpCyclesArithRM: 9, // ADC, ADD, AND, OR, SBB, SUB, and XOR reg,mem (and CMP mem,reg) cycle time\n nOpCyclesArithMR: 16, // ADC, ADD, AND, OR, SBB, SUB, and XOR mem,reg cycle time\n nOpCyclesArithMID: 1, // ADC, ADD, AND, OR, SBB, SUB, XOR and CMP mem,imm cycle delta\n nOpCyclesCall: 19,\n nOpCyclesCallF: 28,\n nOpCyclesCallWR: 16,\n nOpCyclesCallWM: 21,\n nOpCyclesCallDM: 37,\n nOpCyclesCLI: 2,\n nOpCyclesCompareRM: 9, // CMP reg,mem cycle time (same as nOpCyclesArithRM on an 8086 but not on a 80286)\n nOpCyclesCWD: 5,\n nOpCyclesBound: 33, // N/A if 8086/8088, 33-35 if 80186/80188 (TODO: Determine what the range means for an 80186/80188)\n nOpCyclesInP: 10,\n nOpCyclesInDX: 8,\n nOpCyclesIncR: 3, // INC reg, DEC reg\n nOpCyclesIncM: 15, // INC mem, DEC mem\n nOpCyclesInt: 51,\n nOpCyclesInt3D: 1,\n nOpCyclesIntOD: 2,\n nOpCyclesIntOFall: 4,\n nOpCyclesIRet: 32,\n nOpCyclesJmp: 15,\n nOpCyclesJmpF: 15,\n nOpCyclesJmpC: 16,\n nOpCyclesJmpCFall: 4,\n nOpCyclesJmpWR: 11,\n nOpCyclesJmpWM: 18,\n nOpCyclesJmpDM: 24,\n nOpCyclesLAHF: 4, // LAHF, SAHF, MOV reg,imm\n nOpCyclesLEA: 2,\n nOpCyclesLS: 16, // LDS, LES\n nOpCyclesLoop: 17, // LOOP, LOOPNZ\n nOpCyclesLoopZ: 18, // LOOPZ, JCXZ\n nOpCyclesLoopNZ: 19, // LOOPNZ\n nOpCyclesLoopFall: 5, // LOOP\n nOpCyclesLoopZFall: 6, // LOOPZ, JCXZ\n nOpCyclesMovRR: 2,\n nOpCyclesMovRM: 8,\n nOpCyclesMovMR: 9,\n nOpCyclesMovRI: 10,\n nOpCyclesMovMI: 10,\n nOpCyclesMovAM: 10,\n nOpCyclesMovMA: 10,\n nOpCyclesDivBR: 80, // range of 80-90\n nOpCyclesDivWR: 144, // range of 144-162\n nOpCyclesDivBM: 86, // range of 86-96\n nOpCyclesDivWM: 154, // range of 154-172\n nOpCyclesIDivBR: 101, // range of 101-112\n nOpCyclesIDivWR: 165, // range of 165-184\n nOpCyclesIDivBM: 107, // range of 107-118\n nOpCyclesIDivWM: 171, // range of 171-190\n nOpCyclesMulBR: 70, // range of 70-77\n nOpCyclesMulWR: 113, // range of 113-118\n nOpCyclesMulBM: 76, // range of 76-83\n nOpCyclesMulWM: 124, // range of 124-139\n nOpCyclesIMulBR: 80, // range of 80-98\n nOpCyclesIMulWR: 128, // range of 128-154\n nOpCyclesIMulBM: 86, // range of 86-104\n nOpCyclesIMulWM: 134, // range of 134-160\n nOpCyclesNegR: 3, // NEG reg, NOT reg\n nOpCyclesNegM: 16, // NEG mem, NOT mem\n nOpCyclesOutP: 10,\n nOpCyclesOutDX: 8,\n nOpCyclesPopAll: 51, // N/A if 8086/8088, 51 if 80186, 83 if 80188 (TODO: Verify)\n nOpCyclesPopReg: 8,\n nOpCyclesPopMem: 17,\n nOpCyclesPushAll: 36, // N/A if 8086/8088, 36 if 80186, 68 if 80188 (TODO: Verify)\n nOpCyclesPushReg: 11, // NOTE: \"The 8086 Book\" claims this is 10, but it's an outlier....\n nOpCyclesPushMem: 16,\n nOpCyclesPushSeg: 10,\n nOpCyclesPrefix: 2,\n nOpCyclesCmpS: 18,\n nOpCyclesCmpSr0: 9-2, // reduced by nOpCyclesPrefix\n nOpCyclesCmpSrn: 17-2, // reduced by nOpCyclesPrefix\n nOpCyclesLodS: 12,\n nOpCyclesLodSr0: 9-2, // reduced by nOpCyclesPrefix\n nOpCyclesLodSrn: 13-2, // reduced by nOpCyclesPrefix\n nOpCyclesMovS: 18,\n nOpCyclesMovSr0: 9-2, // reduced by nOpCyclesPrefix\n nOpCyclesMovSrn: 17-2, // reduced by nOpCyclesPrefix\n nOpCyclesScaS: 15,\n nOpCyclesScaSr0: 9-2, // reduced by nOpCyclesPrefix\n nOpCyclesScaSrn: 15-2, // reduced by nOpCyclesPrefix\n nOpCyclesStoS: 11,\n nOpCyclesStoSr0: 9-2, // reduced by nOpCyclesPrefix\n nOpCyclesStoSrn: 10-2, // reduced by nOpCyclesPrefix\n nOpCyclesRet: 8,\n nOpCyclesRetn: 12,\n nOpCyclesRetF: 18,\n nOpCyclesRetFn: 17,\n nOpCyclesShift1M: 15, // ROL/ROR/RCL/RCR/SHL/SHR/SAR reg,1\n nOpCyclesShiftCR: 8, // ROL/ROR/RCL/RCR/SHL/SHR/SAR reg,CL\n nOpCyclesShiftCM: 20, // ROL/ROR/RCL/RCR/SHL/SHR/SAR mem,CL\n nOpCyclesShiftCS: 2, // this is the left-shift value used to convert the count to the cycle cost\n nOpCyclesTestRR: 3,\n nOpCyclesTestRM: 9,\n nOpCyclesTestRI: 5,\n nOpCyclesTestMI: 11,\n nOpCyclesXchgRR: 4,\n nOpCyclesXchgRM: 17,\n nOpCyclesXLAT: 11\n },\n CYCLES_80286: {\n nWordCyclePenalty: 0,\n nEACyclesBase: 0,\n nEACyclesDisp: 0,\n nEACyclesBaseIndex: 0,\n nEACyclesBaseIndexExtra: 0,\n nEACyclesBaseDisp: 0,\n nEACyclesBaseIndexDisp: 1,\n nEACyclesBaseIndexDispExtra:1,\n nOpCyclesAAA: 3,\n nOpCyclesAAD: 14,\n nOpCyclesAAM: 16,\n nOpCyclesArithRR: 2,\n nOpCyclesArithRM: 7,\n nOpCyclesArithMR: 7,\n nOpCyclesArithMID: 0,\n nOpCyclesCall: 7, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesCallF: 13, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesCallWR: 7, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesCallWM: 11, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesCallDM: 16, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesCLI: 3,\n nOpCyclesCompareRM: 6,\n nOpCyclesCWD: 2,\n nOpCyclesBound: 13,\n nOpCyclesInP: 5,\n nOpCyclesInDX: 5,\n nOpCyclesIncR: 2,\n nOpCyclesIncM: 7,\n nOpCyclesInt: 23, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesInt3D: 0,\n nOpCyclesIntOD: 1,\n nOpCyclesIntOFall: 3,\n nOpCyclesIRet: 17, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesJmp: 7, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesJmpF: 11, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesJmpC: 7, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesJmpCFall: 3,\n nOpCyclesJmpWR: 7, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesJmpWM: 11, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesJmpDM: 15, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesLAHF: 2,\n nOpCyclesLEA: 3,\n nOpCyclesLS: 7,\n nOpCyclesLoop: 8, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesLoopZ: 8, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesLoopNZ: 8, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesLoopFall: 4,\n nOpCyclesLoopZFall: 4,\n nOpCyclesMovRR: 2, // this is actually the same as the 8086...\n nOpCyclesMovRM: 3,\n nOpCyclesMovMR: 5,\n nOpCyclesMovRI: 2,\n nOpCyclesMovMI: 3,\n nOpCyclesMovAM: 5, // this is actually slower than the MOD/RM form of MOV AX,mem (see nOpCyclesMovRM)\n nOpCyclesMovMA: 3,\n nOpCyclesDivBR: 14,\n nOpCyclesDivWR: 22,\n nOpCyclesDivBM: 17,\n nOpCyclesDivWM: 25,\n nOpCyclesIDivBR: 17,\n nOpCyclesIDivWR: 25,\n nOpCyclesIDivBM: 20,\n nOpCyclesIDivWM: 28,\n nOpCyclesMulBR: 13,\n nOpCyclesMulWR: 21,\n nOpCyclesMulBM: 16,\n nOpCyclesMulWM: 24,\n nOpCyclesIMulBR: 13,\n nOpCyclesIMulWR: 21,\n nOpCyclesIMulBM: 16,\n nOpCyclesIMulWM: 24,\n nOpCyclesNegR: 2,\n nOpCyclesNegM: 7,\n nOpCyclesOutP: 5,\n nOpCyclesOutDX: 5,\n nOpCyclesPopAll: 19,\n nOpCyclesPopReg: 5,\n nOpCyclesPopMem: 5,\n nOpCyclesPushAll: 17,\n nOpCyclesPushReg: 3,\n nOpCyclesPushMem: 5,\n nOpCyclesPushSeg: 3,\n nOpCyclesPrefix: 0,\n nOpCyclesCmpS: 8,\n nOpCyclesCmpSr0: 5,\n nOpCyclesCmpSrn: 9,\n nOpCyclesLodS: 5,\n nOpCyclesLodSr0: 5,\n nOpCyclesLodSrn: 4,\n nOpCyclesMovS: 5,\n nOpCyclesMovSr0: 5,\n nOpCyclesMovSrn: 4,\n nOpCyclesScaS: 7,\n nOpCyclesScaSr0: 5,\n nOpCyclesScaSrn: 8,\n nOpCyclesStoS: 3,\n nOpCyclesStoSr0: 4,\n nOpCyclesStoSrn: 3,\n nOpCyclesRet: 11, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesRetn: 11, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesRetF: 15, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesRetFn: 15, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesShift1M: 7,\n nOpCyclesShiftCR: 5,\n nOpCyclesShiftCM: 8,\n nOpCyclesShiftCS: 0,\n nOpCyclesTestRR: 2,\n nOpCyclesTestRM: 6,\n nOpCyclesTestRI: 3,\n nOpCyclesTestMI: 6,\n nOpCyclesXchgRR: 3,\n nOpCyclesXchgRM: 5,\n nOpCyclesXLAT: 5\n },\n /*\n * TODO: All 80386 cycle counts are based on 80286 counts until I have time to hand-generate an 80386-specific table;\n * the values below are used by selected 32-bit opcode handlers only.\n */\n CYCLES_80386: {\n nEACyclesBase: 0,\n nEACyclesDisp: 0,\n nEACyclesBaseIndex: 0,\n nEACyclesBaseIndexExtra: 0,\n nEACyclesBaseDisp: 0,\n nEACyclesBaseIndexDisp: 1,\n nEACyclesBaseIndexDispExtra:1\n }\n};\n\n/*\n * BACKTRACK-related definitions (used only if BACKTRACK is defined)\n */\nX86.BTINFO = {\n SP_LO: 0,\n SP_HI: 0\n};\n\n/*\n * These PS flags are always stored directly in regPS for the 8086/8088, hence the\n * \"direct\" designation; other processors must adjust these bits accordingly. The final\n * adjusted value is stored in PS_DIRECT (ie, 80286 and up also include PS.IOPL.MASK and\n * PS.NT in PS_DIRECT).\n */\nX86.PS_DIRECT_8086 = (X86.PS.TF | X86.PS.IF | X86.PS.DF);\n\n/*\n * These are the default \"always set\" PS bits for the 8086/8088; other processors must\n * adjust these bits accordingly. The final adjusted value is stored in PS_SET.\n */\nX86.PS_SET_8086 = (X86.PS.BIT1 | X86.PS.IOPL.MASK | X86.PS.NT | X86.PS.BIT15);\n\n/*\n * These PS arithmetic and logical flags may be \"cached\" across several result registers;\n * whether or not they're currently cached depends on the RESULT bits in resultType.\n */\nX86.PS_CACHED = (X86.PS.CF | X86.PS.PF | X86.PS.AF | X86.PS.ZF | X86.PS.SF | X86.PS.OF);\n\n/*\n * PS_SAHF is a subset of the arithmetic flags, and refers only to those flags that the\n * SAHF and LAHF \"8080 legacy\" opcodes affect.\n */\nX86.PS_SAHF = (X86.PS.CF | X86.PS.PF | X86.PS.AF | X86.PS.ZF | X86.PS.SF);\n\n/*\n * Before we zero opFlags, we first see if any of the following PREFIX bits were set. If any were set,\n * they are OR'ed into opPrefixes; otherwise, opPrefixes is zeroed as well. This gives prefix-conscious\n * instructions like LODS, MOVS, STOS, CMPS, etc, a way of determining which prefixes, if any, immediately\n * preceded them.\n */\nX86.OPFLAG_PREFIXES = (X86.OPFLAG.SEG | X86.OPFLAG.LOCK | X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ | X86.OPFLAG.DATASIZE | X86.OPFLAG.ADDRSIZE);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/interrupts.js (C) Jeff Parsons 2012-2018\n */\n\nvar Interrupts = {\n VIDEO: 0x10,\n DISK: 0x13,\n CASSETTE: 0x15,\n KBD: 0x16,\n RTC: 0x1A,\n ALT_TIMER: 0x1C, // invoked by the BIOS timer interrupt handler (vector 0x08)\n DOS: 0x21,\n DOS_IDLE: 0x28,\n DOS_NETBIOS:0x2A,\n MOUSE: 0x33,\n ALT_DISK: 0x40, // HDC BIOS saves original FDC BIOS vector here\n HD0_PARMS: 0x41, // parameter table for hard drive 0\n HD1_PARMS: 0x46, // parameter table for hard drive 1\n HD_PARMS: {\n MAX_CYL: 0x00, // maximum cylinders (2 bytes)\n MAX_HEADS: 0x02, // maximum heads (1 byte)\n WP_CYL: 0x05, // write precompensation cylinder (2 bytes)\n MAX_ECC: 0x07, // max ECC burst (1 byte)\n DRIVE_CTRL: 0x08, // drive control (1 byte)\n PARK_CYL: 0x0C, // landing zone cylinder (2 bytes)\n SEC_TRACK: 0x0E // sectors per track (1 byte)\n },\n ALT_VIDEO: 0x6D, // IBM VGA BIOS saves original video BIOS vector here\n WINCB: {\n VECTOR: 0x30 // Windows PM call-back interface (aka Transfer Space Fault)\n },\n WINDBG: { // Windows Debugger protected-mode interface\n VECTOR: 0x41, // (AX==command)\n IS_LOADED: 0x004F, // DS_DebLoaded\n LOADED: 0xF386, // DS_DebPresent (returned in AX if Windows Debugger loaded)\n LOADSEG: 0x0050, // DS_LoadSeg (SI==0 if code, 1 if data; BX==segnum-1; CX==selector; ES:[E]DI->module name)\n FREESEG: 0x0052, // DS_FreeSeg (BX==segment)\n KRNLVARS: 0x005A, // DS_Kernel_Vars\n RELSEG: 0x005C, // DS_ReleaseSeg (same as DS_FreeSeg but \"restores any breakpoints first\")\n LOADHIGH: 0x005D, // D386_LoadCodeDataHigh\n EXITCALL: 0x0062, // DS_EXITCALL\n LOADDLL: 0x0064, // DS_LOADDLL\n DELMODULE: 0x0065, // DS_DELMODULE\n UNKNOWN66: 0x0066, // Unknown (but I suspect it isn't good)\n UNKNOWN67: 0x0067, // Unknown (but I suspect it isn't good)\n REGDOTCMD: 0x0070, // DS_RegisterDotCommand\n CHECKFAULT: 0x007F, // DS_CheckFault (BX==fault #, CX==FAULTTYPE bits; return AX=0 to handle fault normally, 1 to issue TRAPFAULT)\n FAULTTYPE: {\n V86: 0x0001,\n PM: 0x0002,\n RING0: 0x0004,\n FIRST: 0x0008,\n LAST: 0x0010\n },\n TRAPFAULT: 0x0083, // DS_TrapFault (BX==fault #, CX==faulting CS, EDX==faulting EIP, ESI==fault error, EDI==fault flags)\n GETSYMBOL: 0x008D, // DS_GetSymbol (DS:ESI->symbol; return AX=0 if success, 1 if not found, 2 if memory not loaded yet)\n LOADSEG32: 0x0150, // DS_LoadSeg_32 (SI==0 if code, 1 if data; DX:EBX->D386_Device_Params)\n FREESEG32: 0x0152, // DS_FreeSeg_32 (BX==segment, DX:EDI->module name)\n CONDBP: 0xF001, // DS_CondBP (break here if WDEB386 was run with /B; ESI -> string to display)\n ENABLED: true // support for WINDBG interrupts can be disabled (but NOT if WINDBGRM is enabled)\n },\n WINDBGRM: { // Windows Debugger real-mode interface\n VECTOR: 0x68, // (AH==command)\n IS_LOADED: 0x43, // D386_Identify\n LOADED: 0xF386, // D386_Id (returned in AX if Windows Debugger loaded)\n PREP_PMODE: 0x44, // D386_Prepare_PMode (must return a 16:32 address in ES:EDI to a \"PMinit\" handler)\n FREESEG: 0x48, // D386_Free_Segment (BX==real-mode segment)\n REMOVESEGS: 0x4F, // D386_Remove_Segs (remove any undefined segments from the named module at ES:DI)\n LOADSEG: 0x50, // D386_Load_Segment (AL=segment type, ES:DI->D386_Device_Params)\n ENABLED: true // support for WINDBGRM interrupts can be disabled\n },\n FUNCS: {} // filled in only if DEBUGGER is true\n};\n\nif (DEBUGGER) {\n Interrupts.BIOS_DATA = {\n 0x400: [\"RS232_BASE\",8], // BASE ADDRESSES OF RS232 ADAPTERS\n 0x408: [\"PRINTER_BASE\",8], // BASE ADDRESSES OF PRINTER ADAPTERS\n 0x410: [\"EQUIP_FLAG\",2], // INSTALLED HARDWARE FLAGS\n 0x412: [\"MFG_TST\",1], // INITIALIZATION FLAGS\n 0x413: [\"MEMORY_SIZE\",2], // BASE MEMORY SIZE IN K BYTES (X 1024)\n 0x415: [\"MFG_ERR_FLAG\",2], // SCRATCHPAD FOR MANUFACTURING ERROR CODES\n 0x417: [\"KB_FLAG\",1], // KEYBOARD SHIFT STATE AND STATUS FLAGS\n 0x418: [\"KB_FLAG_1\",1], // SECOND BYTE OF KEYBOARD STATUS\n 0x419: [\"ALT_INPUT\",1], // STORAGE FOR ALTERNATE KEY PAD ENTRY\n 0x41A: [\"BUFFER_HEAD\",2], // POINTER TO HEAD OF KEYBOARD BUFFER\n 0x41C: [\"BUFFER_TAIL\",2], // POINTER TO TAIL OF KEYBOARD BUFFER\n 0x41E: [\"KB_BUFFER\",32], // ROOM FOR 15 SCAN CODE ENTRIES\n 0x43E: [\"SEEK_STATUS\",1], // DRIVE RECALIBRATION STATUS (BIT 3-0 = DRIVE 3-0 RECALIBRATION BEFORE NEXT SEEK IF BIT IS = 0)\n 0x43F: [\"MOTOR_STATUS\",1], // MOTOR STATUS (BIT 3-0 = DRIVE 3-0 CURRENTLY RUNNING, BIT 7 = CURRENT OPERATION IS A WRITE)\n 0x440: [\"MOTOR_COUNT\",1], // TIME OUT COUNTER FOR MOTOR(S) TURN OFF\n 0x441: [\"DISKETTE_STATUS\",1], // RETURN CODE STATUS BYTE\n 0x442: [\"NEC_STATUS\",7], // STATUS BYTES FROM DISKETTE OPERATION\n 0x449: [\"CRT_MODE\",1], // CURRENT DISPLAY MODE (TYPE)\n 0x44A: [\"CRT_COLS\",2], // NUMBER OF COLUMNS ON SCREEN\n 0x44C: [\"CRT_LEN\",2], // LENGTH OF REGEN BUFFER IN BYTES\n 0x44E: [\"CRT_START\",2], // STARTING ADDRESS IN REGEN BUFFER\n 0x450: [\"CURSOR_POSN\",16], // CURSOR FOR EACH OF UP TO 8 PAGES\n 0x460: [\"CURSOR_MODE\",2], // CURRENT CURSOR MODE SETTING\n 0x462: [\"ACTIVE_PAGE\",1], // CURRENT PAGE BEING DISPLAYED\n 0x463: [\"ADDR_6845\",2], // BASE ADDRESS FOR ACTIVE DISPLAY CARD\n 0x465: [\"CRT_MODE_SET\",1], // CURRENT SETTING OF THE 3X8 REGISTER\n 0x466: [\"CRT_PALETTE\",1], // CURRENT PALETTE SETTING - COLOR CARD\n 0x467: [\"IO_ROM_INIT\",2], // POINTER TO ROM INITIALIZATION ROUTINE\n 0x469: [\"IO_ROM_SEG\",2], // POINTER TO I/O ROM SEGMENT\n 0x46B: [\"INTR_FLAG\",1], // FLAG INDICATING AN INTERRUPT HAPPENED\n 0x46C: [\"TIMER_LOW\",2], // LOW WORD OF TIMER COUNT\n 0x46E: [\"TIMER_HIGH\",2], // HIGH WORD OF TIMER COUNT\n 0x470: [\"TIMER_OFL\",1], // TIMER HAS ROLLED OVER SINCE LAST READ\n 0x471: [\"BIOS_BREAK\",1], // BIT 7=1 IF BREAK KEY HAS BEEN PRESSED\n 0x472: [\"RESET_FLAG\",2], // WORD=1234H IF KEYBOARD RESET UNDERWAY\n 0x474: [\"DISK_STATUS1\",1], // FIXED DISK STATUS\n 0x475: [\"HF_NUM\",1], // COUNT OF FIXED DISK DRIVES\n 0x476: [\"CONTROL_BYTE\",1], // HEAD CONTROL BYTE\n 0x477: [\"PORT_OFF\",1], // RESERVED (PORT OFFSET)\n 0x478: [\"PRINT_TIM_OUT\",4], // TIME OUT COUNTERS FOR PRINTER RESPONSE\n 0x47C: [\"RS232_TIM_OUT\",4], // TIME OUT COUNTERS FOR RS232 RESPONSE\n 0x480: [\"BUFFER_START\",2], // OFFSET OF KEYBOARD BUFFER START\n 0x482: [\"BUFFER_END\",2], // OFFSET OF END OF BUFFER\n 0x484: [\"ROWS\",1], // ROWS ON THE ACTIVE SCREEN (LESS 1)\n 0x485: [\"POINTS\",2], // BYTES PER CHARACTER\n 0x487: [\"INFO\",1], // MODE OPTIONS\n 0x488: [\"INFO_3\",3], // FEATURE BIT SWITCHES\n 0x48B: [\"LASTRATE\",1], // LAST DISKETTE DATA RATE SELECTED\n 0x48C: [\"HF_STATUS\",1], // STATUS REGISTER\n 0x48D: [\"HF_ERROR\",1], // ERROR REGISTER\n 0x48E: [\"HF_INT_FLAG\",1], // FIXED DISK INTERRUPT FLAG\n 0x48F: [\"HF_CNTRL\",1], // COMBO FIXED DISK/DISKETTE CARD BIT 0=1\n 0x490: [\"DSK_STATE\",4], // DRIVE 0 MEDIA STATE, DRIVE 1 MEDIA STATE, DRIVE 0 OPERATION START STATE, DRIVE 1 OPERATION START STATE\n 0x494: [\"DSK_TRK\",2], // DRIVE 0 PRESENT CYLINDER, DRIVE 1 PRESENT CYLINDER\n 0x496: [\"KB_FLAG_3\",1], // KEYBOARD MODE STATE AND TYPE FLAGS\n 0x497: [\"KB_FLAG_2\",1], // KEYBOARD LED FLAGS\n 0x498: [\"USER_FLAG\",2], // OFFSET ADDRESS OF USERS WAIT FLAG\n 0x49A: [\"USER_FLAG_SEG\",2], // SEGMENT ADDRESS OF USER WAIT FLAG\n 0x49C: [\"RTC_LOW\",2], // LOW WORD OF USER WAIT FLAG\n 0x49E: [\"RTC_HIGH\",2], // HIGH WORD OF USER WAIT FLAG\n 0x4A0: [\"RTC_WAIT_FLAG\",1], // WAIT ACTIVE FLAG (01=BUSY, 80=POSTED) (00=POST ACKNOWLEDGED)\n 0x4A1: [\"NET\",7], // RESERVED FOR NETWORK ADAPTERS\n 0x4A8: [\"SAVE_PTR\",4] // POINTER TO EGA PARAMETER CONTROL BLOCK\n };\n \n /*\n * See DebuggerX86.prototype.replaceRegs() for the rules governing how register contents are replaced in the strings below.\n *\n * Replacements occur in the following order:\n *\n * Replace every @XX (or @XXX), where XX (or XXX) is a register, with the register's value.\n * Replace every #XX, where XX is a hex byte value, with the corresponding ASCII character (if printable).\n * Replace every $XXXX:XXXX, where XXXX:XXXX is a segmented address, with the zero-terminated string at that address.\n * Replace every ^XXXX:XXXX, where XXXX:XXXX is a segmented address, with the FCB filename stored at that address.\n *\n * The last replacement is obviously DOS-specific, since FCBs are DOS constructs.\n */\n Interrupts.FUNCS[Interrupts.VIDEO] = {\n 0x00: \"set mode (@AL)\",\n 0x01: \"set cursor type (start=@CH,end=@CL)\",\n 0x02: \"set cursor pos (row=@DH,col=@DL,page=@BH)\",\n 0x03: \"read cursor pos (page=@BH)\",\n 0x04: \"read light pen\",\n 0x05: \"set display page (@AL)\",\n 0x06: \"scroll up (lines=@AL)\",\n 0x07: \"scroll down (lines=@AL)\",\n 0x08: \"read character (page=@BH)\",\n 0x09: \"write char/attr (@AL,attr=@BL,count=@CX)\",\n 0x0A: \"write char (@AL,count=@CX)\",\n 0x0B: \"set palette (id=@BH,color=@BL)\",\n 0x0C: \"write dot (row=@DX,col=@CX)\",\n 0x0D: \"read dot (row=@DX,col=@CX)\",\n 0x0E: \"write tty (@AL)\"\n };\n \n Interrupts.FUNCS[Interrupts.DISK] = {\n 0x00: \"disk reset\",\n 0x01: \"get status\",\n 0x02: \"read drive @DL (@CH:@DH:@CL,@AL) into @ES:@BX\",\n 0x03: \"write drive @DL (@CH:@DH:@CL,@AL) from @ES:@BX\",\n 0x04: \"verify drive @DL (@CH:@DH:@CL,@AL)\",\n 0x05: \"format drive @DL using @ES:@BX\",\n 0x08: \"read drive @DL parameters\",\n 0x15: \"get drive @DL DASD type\",\n 0x16: \"get drive @DL change line status\",\n 0x17: \"set drive @DL DASD type\",\n 0x18: \"set drive @DL media type\"\n /*\n * Here's an additional function reference, previously in the HDC component, but moved here\n * because our components are hardware emulations, not BIOS emulations, so this information is\n * really only of interest to the Debugger (or the casual observer).\n *\n * RESET: 0x00,\n * GET_STATUS: 0x01,\n * READ_SECTORS: 0x02,\n * WRITE_SECTORS: 0x03,\n * VERIFY_SECTORS: 0x04,\n * FORMAT_TRK: 0x05,\n * FORMAT_BAD: 0x06,\n * FORMAT_DRIVE: 0x07,\n * GET_DRIVEPARMS: 0x08,\n * SET_DRIVEPARMS: 0x09,\n * READ_LONG: 0x0A,\n * WRITE_LONG: 0x0B,\n * SEEK: 0x0C,\n * ALT_RESET: 0x0D,\n * READ_BUFFER: 0x0E,\n * WRITE_BUFFER: 0x0F,\n * TEST_READY: 0x10,\n * RECALIBRATE: 0x11,\n * RAM_DIAGNOSTIC: 0x12,\n * DRV_DIAGNOSTIC: 0x13,\n * CTL_DIAGNOSTIC: 0x14\n */\n };\n \n Interrupts.FUNCS[Interrupts.CASSETTE] = {\n 0x80: \"open device\",\n 0x81: \"close device\",\n 0x82: \"program termination\",\n 0x83: \"wait @CX:@DXus for event\",\n 0x84: \"joystick support\",\n 0x85: \"SYSREQ pressed\",\n 0x86: \"wait @CX:@DXus\",\n 0x87: \"move block (@CX words)\",\n 0x88: \"get extended memory size\",\n 0x89: \"processor to virtual mode\",\n 0x90: \"device busy loop\",\n 0x91: \"interrupt complete flag set\"\n };\n \n Interrupts.FUNCS[Interrupts.DOS] = {\n 0x00: \"terminate program\",\n 0x01: \"read character (AL) from stdin with echo\",\n 0x02: \"write character #@DL to stdout\",\n 0x03: \"read character (AL) from stdaux\", // eg, COM1\n 0x04: \"write character #@DL to stdaux\", // eg, COM1\n 0x05: \"write character #@DL to stdprn\", // eg, LPT1\n 0x06: \"direct console output (input if @DL=FF)\",\n 0x07: \"direct console input without echo\",\n 0x08: \"read character (AL) from stdin without echo\",\n 0x09: \"write string $@DS:@DX to stdout\",\n 0x0A: \"buffered input (DS:DX)\", // byte 0 is maximum chars, byte 1 is number of previous characters, byte 2 is number of characters read\n 0x0B: \"get stdin status\",\n 0x0C: \"flush buffer and read stdin\", // AL is a function # (0x01, 0x06, 0x07, 0x08, or 0x0A)\n 0x0D: \"disk reset\",\n 0x0E: \"select default drive @DL\", // returns # of available drives in AL\n 0x0F: \"open file using FCB ^@DS:@DX\", // DS:DX -> unopened File Control Block\n 0x10: \"close file using FCB ^@DS:@DX\",\n 0x11: \"find first matching file using FCB ^@DS:@DX\",\n 0x12: \"find next matching file using FCB ^@DS:@DX\",\n 0x13: \"delete file using FCB ^@DS:@DX\",\n 0x14: \"sequential read from file using FCB ^@DS:@DX\",\n 0x15: \"sequential write to file using FCB ^@DS:@DX\",\n 0x16: \"create or truncate file using FCB ^@DS:@DX\",\n 0x17: \"rename file using FCB ^@DS:@DX\",\n 0x19: \"get current default drive (AL)\",\n 0x1A: \"set disk transfer area (DTA=@DS:@DX)\",\n 0x1B: \"get allocation information for default drive\",\n 0x1C: \"get allocation information for specific drive @DL\",\n 0x1F: \"get drive parameter block for default drive\",\n 0x21: \"read random record from file using FCB ^@DS:@DX\",\n 0x22: \"write random record to file using FCB ^@DS:@DX\",\n 0x23: \"get file size using FCB ^@DS:@DX\",\n 0x24: \"set random record number for FCB ^@DS:@DX\",\n 0x25: \"set address @DS:@DX of interrupt vector @AL\",\n 0x26: \"create new PSP at segment @DX\",\n 0x27: \"random block read from file using FCB ^@DS:@DX\",\n 0x28: \"random block write to file using FCB ^@DS:@DX\",\n 0x29: \"parse filename $@DS:@SI into FCB @ES:@DI using @AL\",\n 0x2A: \"get system date (year=CX, mon=DH, day=DL)\",\n 0x2B: \"set system date (year=@CX, mon=@DH, day=@DL)\",\n 0x2C: \"get system time (hour=CH, min=CL, sec=DH, 100ths=DL)\",\n 0x2D: \"set system time (hour=@CH, min=@CL, sec=@DH, 100ths=@DL)\",\n 0x2E: \"set verify flag @AL\",\n 0x2F: \"get disk transfer area (DTA=ES:BX)\", // DOS 2.00+\n 0x30: \"get DOS version (AL=major, AH=minor)\",\n 0x31: \"terminate and stay resident\",\n 0x32: \"get drive parameter block (DPB=DS:BX) for drive @DL\",\n 0x33: \"extended break check\",\n 0x34: \"get address (ES:BX) of InDOS flag\",\n 0x35: \"get address (ES:BX) of interrupt vector @AL\",\n 0x36: \"get free disk space of drive @DL\",\n 0x37: \"get(0)/set(1) switch character @DL (@AL)\",\n 0x38: \"get country-specific information\",\n 0x39: \"create subdirectory $@DS:@DX\",\n 0x3A: \"remove subdirectory $@DS:@DX\",\n 0x3B: \"set current directory $@DS:@DX\",\n 0x3C: \"create or truncate file $@DS:@DX with attributes @CX\",\n 0x3D: \"open file $@DS:@DX with mode @AL\",\n 0x3E: \"close file @BX\",\n 0x3F: \"read @CX bytes from file @BX into buffer @DS:@DX\",\n 0x40: \"write @CX bytes to file @BX from buffer @DS:@DX\",\n 0x41: \"delete file $@DS:@DX\",\n 0x42: \"set position @CX:@DX of file @BX relative to @AL\",\n 0x43: \"get(0)/set(1) attributes @CX of file $@DS:@DX (@AL)\",\n 0x44: \"get device information (IOCTL)\",\n 0x45: \"duplicate file handle @BX\",\n 0x46: \"force file handle @CX to duplicate file handle @BX\",\n 0x47: \"get current directory (DS:SI) for drive @DL\",\n 0x48: \"allocate memory segment with @BX paragraphs\",\n 0x49: \"free memory segment @ES\",\n 0x4A: \"resize memory segment @ES to @BX paragraphs\",\n 0x4B: \"load program $@DS:@DX using parameter block @ES:@BX\",\n 0x4C: \"terminate with return code @AL\",\n 0x4D: \"get return code (AL)\",\n 0x4E: \"find first matching file $@DS:@DX with attributes @CX\",\n 0x4F: \"find next matching file\",\n 0x50: \"set current PSP @BX\",\n 0x51: \"get current PSP (bx)\",\n 0x52: \"get system variables (ES:BX)\",\n 0x53: \"translate BPB @DS:@SI to DPB (ES:BP)\",\n 0x54: \"get verify flag (AL)\",\n 0x55: \"create child PSP at segment @DX\",\n 0x56: \"rename file $@DS:@DX to $@ES:@DI\",\n 0x57: \"get(0)/set(1) file @BX date @DX and time @CX (@AL)\",\n 0x58: \"get(0)/set(1) memory allocation strategy (@AL)\", // DOS 2.11+\n 0x59: \"get extended error information\", // DOS 3.00+\n 0x5A: \"create temporary file $@DS:@DX with attributes @CX\", // DOS 3.00+\n 0x5B: \"create file $@DS:@DX with attributes @CX\", // DOS 3.00+ (doesn't truncate existing files like 0x3C)\n 0x5C: \"lock(0)/unlock(1) file @BX region @CX:@DX length @SI:@DI (@AL)\", // DOS 3.00+\n 0x5D: \"critical error information (@AL)\", // DOS 3.00+ (undocumented)\n 0x60: \"get fully-qualified filename from $@DS:@SI\", // DOS 3.00+ (undocumented)\n 0x63: \"get lead byte table (@AL)\", // DOS 2.25 and 3.20+\n 0x6C: \"extended open file $@DS:@SI\" // DOS 4.00+\n };\n \n Interrupts.FUNCS[Interrupts.WINDBG.VECTOR] = {\n 0x004F: \"check debugger loaded\" // WINDBG.IS_LOADED returns WINDBG.LOADED (0xF386) if debugger loaded\n };\n}\n\n/*\n * DOS function reference (from https://sites.google.com/site/pcdosretro/dosfuncs)\n *\n * INT 20 Program terminate (1.0+)\n * Entry: CS=PSP\n * Exit: Does not return to caller\n *\n * INT 21 Execute DOS function\n * 00 Program terminate (1.0+)\n * Entry: CS=PSP\n * Exit: Does not return to caller\n * 01 Character input (1.0+)\n * Entry: None\n * Exit: AL=character\n * 02 Character output (1.0+)\n * Entry: DL=character\n * Exit: None\n * 03 Auxiliary input (1.0+)\n * Entry: None\n * Exit: AL=character\n * 04 Auxiliary output (1.0+)\n * Entry: DL=character\n * Exit: None\n * 05 Printer output (1.0+)\n * Entry: DL=character\n * Exit: None\n * 06 Direct console I/O (1.0+)\n * Entry: DL=FF for console input\n * DL=character for console output\n * Exit: ZF=0 if a character is ready, AL=character\n * ZF=1 if no character is ready\n * 07 Direct console input without echo (1.0+)\n * Entry: None\n * Exit: AL=character\n * 08 Console input without echo (1.0+)\n * Entry: None\n * Exit: AL=character\n * 09 Display string (1.0+)\n * Entry: DS:DX->string ending with $\n * Exit: None\n * 0A Buffered keyboard input (1.0+)\n * Entry: DS:DX->input buffer (first byte of buffer=maximum input length)\n * Exit: second byte of buffer=actual input length\n * 0B Get input status (1.0+)\n * Entry: None\n * Exit: AL=00 no character available\n * AL=FF character available\n * 0C Flush input buffer and input (1.0+)\n * Entry: AL=function number (01,06,07,08,or 0A otherwise flush only)\n * DS:DX->input buffer if function 0A\n * Exit: AL=character unless function 0A\n * 0D Disk reset (1.0+)\n * Entry: None\n * Exit: None\n * 0E Set default drive (1.0+)\n * Entry: DL=drive code (0=A)\n * Exit: AL=number of logical drives\n * 0F Open file (1.0+)\n * Entry: DS:DX->unopened FCB\n * Exit: AL=00 file opened\n * AL=FF file not found\n * 10 Close file (1.0+)\n * Entry: DS:DX->opened FCB\n * Exit: AL=00 file closed\n * AL=FF file not found\n * 11 Find first file (1.0+)\n * Entry: DS:DX->unopened FCB\n * Exit: AL=00 matching filename found\n * buffer at DTA receives an unopened FCB and directory entry\n * original FCB contents:\n * FCB search drive code (1=A)\n * FCB+1 specified filespec\n * FCB+12 search attribute byte\n * FCB+13 directory entry offset\n * FCB+15 directory cluster (0=root)\n * FCB+17 unused\n * FCB+21 actual drive code (1=A)\n * AL=FF matching filename not found\n * Note: The file's directory entry is returned after the FCB drive code.\n * If a character device is found then the directory attribute byte\n * is set to 40h.\n * 12 Find next file (1.0+)\n * Entry: DS:DX->unopened FCB from previous 11 or 12 call\n * Exit: AL=00 matching filename found\n * buffer at DTA receives an unopened FCB and directory entry\n * AL=FF matching filename not found\n * Note: The file's directory entry is returned after the FCB drive code.\n * 13 Delete file (1.0+)\n * Entry: DS:DX->unopened FCB\n * Exit: AL=00 file deleted\n * AL=FF matching filename not found or files are read-only\n * 14 Sequential read (1.0+)\n * Entry: DS:DX->opened FCB\n * Exit: AL=00 file was read\n * AL=01 EOF (no data read)\n * AL=02 segment wrap\n * AL=03 EOF (partial read)\n * 15 Sequential write (1.0+)\n * Entry: DS:DX->opened FCB\n * Exit: AL=00 file was written\n * AL=01 disk full\n * AL=02 segment wrap\n * 16 Create or truncate file (1.0+)\n * Entry: DS:DX->unopened FCB\n * Exit: AL=00 file created\n * AL=FF directory full\n * 17 Rename file (1.0+)\n * Entry: DS:DX->rename FCB (FCB+11h->new filename)\n * Exit: AL=00 file renamed\n * AL=FF no matching files found or new filename already exists\n * 18 Reserved\n * 19 Get default drive (1.0+)\n * Entry: None\n * Exit: AL=drive code (0=A)\n * 1A Set disk transfer address (1.0+)\n * Entry: DS:DX=new DTA\n * Exit: None\n * 1B Get allocation info for default drive (1.0+)\n * Entry: None\n * Exit: AL=sectors per cluster\n * CX=bytes per sector\n * DX=clusters per drive\n * DS:BX->media descriptor byte\n * AL=FF invalid drive\n * 1C Get allocation info for specified drive (1.1+)\n * Entry: DL=drive code (0=default)\n * Exit: Same as function 1B\n * 1D Reserved\n * 1E Reserved\n * 1F Get disk parameter block for default drive (1.1+)\n * Entry: None\n * Exit: AL=00 drive valid\n * DS:BX->disk parameter block\n * 0 drive code (0=A) 13 maximum cluster number\n * 1 unit code 15 sectors per FAT\n * 2 bytes per sector 17 first directory sector\n * 4 sectors per cluster-1 19 pointer to device driver\n * 5 cluster shift factor 23 media descriptor byte\n * 6 first FAT sector 24 access flag (0=accessed)\n * 8 number of FATs 25 pointer to next DPB\n * 9 number of directory entries 29 last cluster allocated\n * 11 first data sector 31 free clusters (-1=unknown)\n * AL=FF drive invalid\n * Note: (3.x) The sectors per FAT field is one byte and all following\n * fields are moved back one byte.\n * 20 Reserved\n * 21 Random read (1.0+)\n * Entry: DS:DX->opened FCB\n * Exit: AL=00 file was read\n * AL=01 EOF (no data read)\n * AL=02 segment wrap\n * AL=03 EOF (partial read)\n * 22 Random write (1.0+)\n * Entry: DS:DX->opened FCB\n * Exit: AL=00 file was written\n * AL=01 disk full\n * AL=02 segment wrap\n * 23 Get file size in records (1.0+)\n * Entry: DS:DX->unopened FCB\n * Exit: AL=00 random record field is set by dividing the file size by the\n * specified record size\n * AL=FF file not found\n * 24 Set random record number (1.0+)\n * Entry: DS:DX->opened FCB\n * Exit: random record field is set based on record size, current record,\n * and current block\n * 25 Set interrupt vector (1.0+)\n * Entry: DS:DX=new address\n * AL=interrupt number\n * Exit: None\n * 26 Create PSP (1.0+)\n * Entry: CS=PSP\n * DX=segment for new PSP\n * Exit: None\n * 27 Random block read (1.0+)\n * Entry: DS:DX->opened FCB\n * CX=number of records to read\n * Exit: AL=00 file was read\n * AL=01 EOF (no data read)\n * AL=02 segment wrap\n * AL=03 EOF (partial read)\n * CX=actual number of records read\n * 28 Random block write (1.0+)\n * Entry: DS:DX->opened FCB\n * CX=number of records to write\n * Exit: AL=00 file was written\n * AL=01 disk full\n * AL=02 segment wrap\n * CX=actual number of records written\n * 29 Parse filename (1.0+)\n * Entry: DS:SI->string to parse\n * ES:DI->buffer for unopened FCB\n * AL=flags\n * Bit 0 1=ignore leading separators\n * 1 1=modify FCB drive code byte only if a drive is specified\n * 2 1=modify FCB filename only if a filename is specified\n * 3 1=modify FCB extension only if an extension is specified\n * Exit: DS:SI->first character after parsed filename\n * AL=00 no wildcard characters in string\n * AL=01 wildcard characters in string\n * AL=FF invalid drive\n * 2A Get date (1.0+)\n * Entry: None\n * Exit: AL=weekday (0=Sunday)\n * CX=year\n * DH=month\n * DL=day\n * 2B Set date (1.0+)\n * Entry: CX=year\n * DH=month\n * DL=day\n * Exit: AL=00 date set\n * AL=FF invalid date\n * 2C Get time (1.0+)\n * Entry: None\n * Exit: CH=hours\n * CL=minutes\n * DH=seconds\n * DL=hundredths\n * 2D Set time (1.0+)\n * Entry: CH=hours\n * CL=minutes\n * DH=seconds\n * DL=hundredths\n * Exit: AL=00 time set\n * AL=FF invalid time\n * 2E Set verify flag (1.1+)\n * Entry: AL=verify flag (0=off,1=on)\n * Exit: None\n * 2F Get disk transfer address (2.0+)\n * Entry: None\n * Exit: ES:BX=DTA\n * 30 Get DOS version (2.0+)\n * Entry: AL=0 return OEM number (5.0+)\n * AL=1 return version flag (5.0+)\n * Exit: AL=major version number\n * AH=minor version number\n * BH=OEM number or version flag (00=RAM,08=ROM)\n * BL:CX=24-bit serial number or 0\n * 31 Terminate and stay resident (2.0+)\n * Entry: AL=return code\n * DX=memory size in paragraphs (minimum 6)\n * Exit: Does not return to caller\n * 32 Get disk parameter block for specified drive (2.0+)\n * Entry: DL=drive code (0=default)\n * Exit: Same as function 1F\n * 33 Get or set Ctrl-Break (2.0+)\n * Entry: AL=0 get break\n * AL=1 set break\n * AL=2 swap break (*) (3.1+)\n * AL=5 get boot drive (4.0+)\n * AL=6 get DOS version (5.0+)\n * DL=break flag if set or swap (0=off,1=on)\n * Exit: if function 00 or 02:\n * DL=break flag\n * if function 05:\n * DL=boot drive code (1=A)\n * if function 06:\n * BL=major version\n * BH=minor version\n * DL=revision (0=A)\n * DH=version flag (00=low,08=ROM,10=HMA)\n * 34 Get InDOS flag pointer (2.0+)\n * Entry: None\n * Exit: ES:BX->InDOS flag\n * Note: The DOS critical error flag immediately precedes this byte.\n * 35 Get interrupt vector (2.0+)\n * Entry: AL=interrupt number\n * Exit: ES:BX=interrupt address\n * 36 Get free disk space (2.0+)\n * Entry: DL=drive code (0=default)\n * Exit: AX=sectors per cluster\n * BX=free clusters\n * CX=bytes per sector\n * DX=clusters per drive\n * AX=FFFF if drive invalid\n * 37 Get or set switch character (*) (2.0+)\n * Entry: AL=0 get switch character\n * AL=1 set switch character\n * DL=switch character if set\n * Exit: DL=switch character if get\n * Note: (5.0+) Function 3701 has been disabled.\n * 38 Get or set country info (2.0+)\n * Entry: AL=country code (0=default)\n * BX=country code if AL=FF (3.0+)\n * DX=FFFF if set request (2.11+)\n * DS:DX->buffer if get request\n * Exit: CF=0 BX=country code if get request (3.0+)\n * buffer format:\n * 0 date format (0=USA,1=Europe,2=Japan)\n * 2 currency symbol string\n * 7 thousands separator\n * 9 decimal separator\n * 11 date separator\n * 13 time separator\n * 15 currency format\n * 0 symbol before amount, no space between\n * 1 symbol after amount, no space between\n * 2 symbol before amount, 1 space between\n * 3 symbol after amount, 1 space between\n * 4 symbol replaces decimal separator\n * 16 digits after decimal in currency\n * 17 time format (0=12-hour,1=24-hour)\n * 18 case map call address\n * 22 data list separator\n * 24 reserved (10 bytes)\n * CF=1 AX=error code\n * 39 Create directory (2.0+)\n * Entry: DS:DX->directory name\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 3A Remove directory (2.0+)\n * Entry: DS:DX->directory name\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 3B Change current directory (2.0+)\n * Entry: DS:DX->directory name\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 3C Create or truncate file (2.0+)\n * Entry: DS:DX->filename\n * CX=file attributes\n * Exit: CF=0 AX=file handle\n * CF=1 AX=error code\n * 3D Open file (2.0+)\n * Entry: DS:DX->filename\n * AL=open mode\n * Bit 0-2 access mode\n * 000=read\n * 001=write\n * 010=read/write\n * 4-6 sharing mode (3.0+)\n * 000=compatibility\n * 001=deny read/write access\n * 010=deny write access\n * 011=deny read access\n * 100=deny none access\n * 7 inheritance flag\n * 0=file inherited by EXECed programs\n * 1=file not inherited by EXECed programs\n * Exit: CF=0 AX=file handle\n * CF=1 AX=error code\n * 3E Close file (2.0+)\n * Entry: BX=file handle\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 3F Read file or device (2.0+)\n * Entry: BX=file handle\n * CX=bytes to read\n * DS:DX->input buffer\n * Exit: CF=0 AX=number of bytes read (0=EOF)\n * CF=1 AX=error code\n * 40 Write file or device (2.0+)\n * Entry: BX=file handle\n * CX=bytes to write (0=truncate file)\n * DS:DX->output buffer\n * Exit: CF=0 AX=number of bytes written (0=disk full)\n * CF=1 AX=error code\n * 41 Delete file (2.0+)\n * Entry: DS:DX->filename\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 42 Move file pointer (2.0+)\n * Entry: AL=code (0=absolute,1=relative,2=relative to EOF)\n * BX=file handle\n * CX:DX=offset\n * Exit: CF=0 DX:AX=new pointer\n * CF=1 AX=error code\n * 43 Get or set file attributes (2.0+)\n * Entry: AL=0 get attributes\n * AL=1 set attributes\n * CX=file attributes if set\n * Bit 0 1=read-only\n * 1 1=hidden\n * 2 1=system\n * 4 1=directory (get only)\n * 5 1=archive\n * DS:DX->filename\n * Exit: CF=0 CX=file attributes if get\n * CF=1 AX=error code\n * 44 I/O control for devices (2.0+)\n * Notes: 1) Functions 02-05 work only if bit 14 of the device driver\n * attribute word is set.\n * 2) Function 08 works only if bit 11 of the device driver\n * attribute word is set.\n * 3) Functions 0C-0F work only if bit 6 of the device driver\n * attribute word is set.\n * 4) Functions 10-11 work only if bit 7 of the device driver\n * attribute word is set.\n * 00 Get device attributes (2.0+)\n * Entry: BX=file handle\n * Exit: CF=0 DX=device attributes\n * Character devices:\n * Bit 0 1=console input\n * 1 1=console output\n * 2 1=NUL device\n * 3 1=CLOCK device\n * 4 1=INT 29 output (CON)\n * 5 0=ASCII,1=binary\n * 6 0=EOF on input\n * 7 1=character device\n * 11 1=open/close supported\n * 13 1=output until busy supported\n * 14 1=IOCTL supported\n * Block devices:\n * Bit 0-5 drive code (0=A)\n * 6 0=file has been written\n * 7 0=block device\n * CF=1 AX=error code\n * 01 Set device attributes (2.0+)\n * Entry: BX=file handle (character devices only)\n * DX=device attributes (DH must be 0)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 02 Read from character device (2.0+)\n * 03 Write to character device (2.0+)\n * Entry: BX=file handle\n * CX=number of bytes\n * DS:DX->buffer\n * Exit: CF=0 AX=number of bytes transferred\n * CF=1 AX=error code\n * 04 Read from block device (2.0+)\n * 05 Write to block device (2.0+)\n * Entry: BL=drive code (0=default)\n * CX=number of bytes\n * DS:DX->buffer\n * Exit: CF=0 AX=number of bytes transferred\n * CF=1 AX=error code\n * 06 Get input status (2.0+)\n * 07 Get output status (2.0+)\n * Entry: BX=file handle\n * Exit: CF=0 AL=status (00=not ready,FF=ready)\n * CF=1 AX=error code\n * 08 Removable media check (3.0+)\n * Entry: BL=drive code (0=default)\n * Exit: CF=0 AX=value (0=removable,1=fixed)\n * CF=1 AX=error code\n * 09 Local/remote drive check (3.0+)\n * Entry: BL=drive code (0=default)\n * Exit: CF=0 DX=device attributes\n * Bit 1 1=32-bit sectors supported\n * 6 1=generic IOCTL calls supported\n * 7 1=query IOCTL call supported\n * 9 1=shared drive; direct I/O not allowed\n * 11 1=removable media call supported\n * 12 1=remote drive\n * 13 1=media descriptor in FAT required\n * 14 1=IOCTL calls supported\n * 15 1=SUBSTed\n * CF=1 AX=error code\n * 0A Local/remote handle check (3.0+)\n * Entry: BX=file handle\n * Exit: CF=0 DX=device attributes from SFT\n * Character devices:\n * Bit 0 1=console input\n * 1 1=console output\n * 2 1=NUL device\n * 3 1=CLOCK device\n * 4 1=INT 29 output (CON)\n * 5 0=ASCII,1=binary\n * 6 0=EOF on input\n * 7 1=character device\n * 11 1=network spooler\n * 12 1=no inherit\n * 13 1=named pipe\n * 15 1=remote\n * Block devices:\n * Bit 0-5 drive code (0=A)\n * 6 0=file has been written\n * 7 0=block device\n * 12 1=no inherit\n * 14 1=date/time set\n * 15 1=remote\n * CF=1 AX=error code\n * 0B Change sharing retry count (3.0+)\n * Entry: CX=delay loop count\n * DX=retry count\n * Exit: None\n * 0C Generic IOCTL for handles (3.2+)\n * Entry: BX=file handle\n * CH=category code (01=AUX,03=CON,05=PRN)\n * CL=function code\n * 45 set printer retry count\n * 4A set code page (3.3+)\n * 4C prepare start (3.3+)\n * 4D prepare end (3.3+)\n * 5F set display info (4.0+)\n * 65 get printer retry count\n * 6A get code page (3.3+)\n * 6B get prepare list (3.3+)\n * 7F get display info (4.0+)\n * DS:DX->parameter block or retry count word\n * Exit: CF=0 None\n * CF=1 AX=error code\n * Get/set code page and prepare end parameter block format:\n * 0 length (2)\n * 2 code page\n * Prepare start parameter block format:\n * 0 flags (device specific)\n * 2 data length\n * 4 number of code pages\n * 6 code pages (-1=perform a refresh operation)\n * Get prepare list parameter block format:\n * 0 data length\n * 2 number of hardware code pages\n * 4 hardware code pages\n * n number of prepared code pages\n * n+2 prepared code pages\n * Display info parameter block format:\n * 0 info level (must be 0)\n * 1 reserved\n * 2 data length (14)\n * 4 flags\n * Bit 0 (0=blink,1=intensity)\n * 6 mode (1=text,2=graphics)\n * 7 reserved\n * 8 colors\n * 10 pixel columns\n * 12 pixel rows\n * 14 character columns\n * 16 character rows\n * 0D Generic IOCTL for drives (3.2+)\n * Entry: BL=drive code (0=default)\n * CH=category code (08=disk)\n * CL=function code\n * 40 set device parameters\n * 41 write track\n * 42 format track\n * 46 set media info (4.0+)\n * 47 set access flag (4.0+)\n * 60 get device parameters\n * 61 read track\n * 62 verify track\n * 66 get media info (4.0+)\n * 67 get access flag (4.0+)\n * 68 sense media type (5.0+)\n * DS:DX->parameter block\n * Exit: CF=0 None\n * CF=1 AX=error code\n * Get/set device parameter block format:\n * 0 flags (only bit 0 is used by get)\n * Bit 0 0=return default BPB/build new BPB\n * 1=return build BPB/use device BPB\n * 1 0=read all fields\n * 1=read track layout only\n * 2 0=sector sizes vary\n * 1=sector sizes equal\n * 1 drive type\n * 0=360K 5=fixed\n * 1=1.2M 6=tape\n * 2=720K 7=1.44M\n * 3=8\" single sided 8=read/write optical\n * 4=8\" double sided 9=2.88M\n * 2 attributes\n * Bit 0 1=non-removable\n * 1 1=changeline supported\n * 4 cylinders\n * 6 density (0=high,1=double)\n * 7 BIOS parameter block\n * 32 reserved\n * 38 track layout count\n * 40 track layout words (sector number,sector size)\n * Note: Track layout fields are used by set only.\n * Read/write parameter block format:\n * 0 reserved\n * 1 head\n * 3 cylinder\n * 5 sector\n * 7 number of sectors\n * 9 buffer address\n * Format/verify parameter block format:\n * 0 reserved\n * 1 head\n * 3 cylinder\n * Get/set media info parameter block format:\n * 0 info level (must be 0)\n * 2 volume serial number\n * 6 volume label\n * 17 8-byte file system type\n * Get/set access flag parameter block format:\n * 0 reserved\n * 1 access flag (0=disallow disk access,1=allow disk access)\n * Sense media type parameter block format:\n * 0 media type flag (0=other,1=default)\n * 1 media type (2=720K,7=1.44M,9=2.88M)\n * 0E Get logical drive map (3.2+)\n * 0F Set logical drive map (3.2+)\n * Entry: BL=logical drive code (0=default)\n * Exit: CF=0 AL=physical drive code (0=only 1 logical drive mapped)\n * CF=1 AX=error code\n * 10 Query IOCTL for handles (5.0+)\n * Entry: BX=file handle\n * CH=category code (01=AUX,03=CON,05=PRN)\n * CL=function code\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 11 Query IOCTL for drives (5.0+)\n * Entry: BL=drive code (0=default)\n * CH=category code (08=disk)\n * CL=function code\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 45 Duplicate handle (2.0+)\n * Entry: BX=file handle\n * Exit: CF=0 AX=new file handle\n * CF=1 AX=error code\n * 46 Redirect handle (2.0+)\n * Entry: BX=file handle\n * CX=file handle to redirect\n * Exit: CF=0 None\n * CF=1 AX=error code\n * Note: If the handle to redirect is opened then it is closed before\n * being redirected.\n * 47 Get current directory (2.0+)\n * Entry: DS:SI->64-byte buffer for pathname\n * DL=drive code (0=default)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 48 Allocate memory (2.0+)\n * Entry: BX=number of paragraphs to allocate\n * Exit: CF=0 AX=segment of allocated block\n * CF=1 AX=error code\n * BX=size of largest available block\n * 49 Release memory (2.0+)\n * Entry: ES=segment of block to release\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 4A Reallocate memory (2.0+)\n * Entry: BX=number of paragraphs to allocate\n * ES=segment of block to reallocate\n * Exit: CF=0 None\n * CF=1 AX=error code\n * BX=size of largest available block\n * 4B Execute program (2.0+)\n * Entry: AL=0 execute program\n * AL=1 load program\n * AL=3 load overlay\n * AL=5 enter exec state (5.0+)\n * DS:DX->filename or exec state parameter block\n * ES:BX->parameter block (unused by enter exec state)\n * if function 00 or 01:\n * 0 environment block segment or 0\n * 2 command tail pointer\n * 6 FCB1 pointer\n * 10 FCB2 pointer\n * if function 03:\n * 0 segment where file will be loaded\n * 2 relocation factor\n * if function 05:\n * 0 reserved\n * 2 flags (0=COM,1=EXE,2=overlay)\n * 4 program name pointer\n * 8 PSP\n * 10 program CS:IP\n * 14 doubleword program size\n * Exit: CF=0 BX and DX may be destroyed\n * parameter block if load only:\n * 14 SS:SP of loaded program\n * 18 CS:IP of loaded program\n * CF=1 AX=error code\n * Note: After calling function 4B01 the current PSP is set to that of\n * the loaded program. Before executing the program, DS and ES\n * should be set to the program's PSP and the INT 22 vector in the\n * program's PSP should be set to a valid return address.\n * 4C Terminate with return code (2.0+)\n * Entry: AL=return code\n * Exit: Does not return to caller\n * 4D Get program return code (2.0+)\n * Entry: None\n * Exit: AL=return code\n * AH=exit type (0=normal,1=Ctrl-C,2=critical error,3=TSR)\n * 4E Find first file (2.0+)\n * Entry: DS:DX->filespec\n * CX=file attributes\n * Exit: CF=0 DTA search drive code (1=A)\n * DTA+1 search filespec\n * DTA+12 search attribute byte\n * DTA+13 directory entry offset\n * DTA+15 directory cluster (0=root)\n * DTA+17 unused\n * DTA+21 attribute byte (40h=character device)\n * DTA+22 file time\n * DTA+24 file date\n * DTA+26 file size\n * DTA+30 filename\n * CF=1 AX=error code\n * 4F Find next file (2.0+)\n * Entry: Bytes 0-20 of buffer at DTA must be set from previous 4E or 4F call\n * Exit: Same as function 4E\n * 50 Set current PSP (2.0+)\n * Entry: BX=PSP segment\n * Exit: None\n * 51 Get current PSP (2.0+)\n * Entry: None\n * Exit: BX=PSP segment\n * 52 Get DOS internal pointers (*) (2.0+)\n * Entry: None\n * Exit: ES:BX->DOS internal pointers\n * -02h memory chain anchor\n * +00h pointer to disk parameter blocks\n * +04h pointer to system file tables\n * +08h pointer to CLOCK$ device header\n * +0Ch pointer to CON device header\n * +10h disk buffer size\n * +12h pointer to disk buffer chain (3.x)\n * pointer to disk buffer control block (4.0+)\n * +16h pointer to current directory structures\n * +1Ah pointer to FCB system file tables\n * +1Eh FCB keep count\n * +20h number of actual drives\n * +21h number of logical drives\n * +22h NUL device header\n * 53 Create disk parameter block (*) (2.0+)\n * Entry: DS:SI->BIOS parameter block\n * 0 bytes per sector\n * 2 sectors per cluster\n * 3 number of reserved sectors\n * 5 number of FATs\n * 6 number of root directory entries\n * 8 total number of sectors\n * 10 media descriptor byte\n * 11 sectors per FAT\n * 13 sectors per track\n * 15 number of heads\n * 17 number of hidden sectors\n * 21 32-bit number of sectors if word at 8=0\n * ES:BP->buffer for disk parameter block\n * Exit: None\n * 54 Get verify flag (2.0+)\n * Entry: None\n * Exit: AL=verify flag (0=off,1=on)\n * 55 Create program PSP (*) (2.0+)\n * Entry: DX=segment for new PSP\n * SI=new end of allocation\n * Exit: None\n * Note: After calling function 55 the current PSP is set to the new PSP.\n * 56 Rename file (2.0+)\n * Entry: DS:DX->old filename\n * ES:DI->new filename\n * Exit: CF=0 None\n * CF=1 AX=error code\n * Note: This function can also rename a directory or move a file from\n * one directory to another.\n * 57 Get or set file date and time (2.0+)\n * Entry: AL=0 get date and time\n * AL=1 set date and time\n * BX=file handle\n * CX=time if set\n * Bits 0-4 seconds/2 (0-29)\n * 5-10 minutes (0-59)\n * 11-15 hours (0-23)\n * DX=date if set\n * Bits 0-4 day (1-31)\n * 5-8 month (1-12)\n * 9-15 year-1980\n * Exit: CF=0 CX=time if get\n * DX=date if get\n * CF=1 AX=error code\n * 58 Get or set allocation strategy (2.11+)\n * Entry: AL=0 get strategy\n * AL=1 set strategy\n * AL=2 get UMB link state (5.0+)\n * AL=3 set UMB link state (5.0+)\n * BX=strategy code or UMB link state (0=unlink,1=link)\n * 00=first fit\n * 01=best fit\n * 02=last fit\n * 40=first fit, high only (5.0+)\n * 41=best fit, high only (5.0+)\n * 42=last fit, high only (5.0+)\n * 80=first fit, high first (5.0+)\n * 81=best fit, high first (5.0+)\n * 82=last fit, high first (5.0+)\n * Exit: CF=0 AX=strategy code or UMB link state if get\n * CF=1 AX=error code\n * 59 Get extended error info (3.0+)\n * Entry: None\n * Exit: AX=extended error code\n * BH=error class\n * BL=suggested action\n * CH=locus\n * ES:DI->volume label for invalid disk change error or 0\n * 5A Create unique file (3.0+)\n * Entry: DS:DX->pathname ending with \\\n * CX=file attributes\n * Exit: CF=0 AX=file handle (filename is appended to pathname)\n * CF=1 AX=error code\n * 5B Create new file (3.0+)\n * Entry: DS:DX->filename\n * CX=file attributes\n * Exit: CF=0 AX=file handle\n * CF=1 AX=error code\n * 5C Lock or unlock file (3.0+)\n * Entry: AL=0 lock\n * AL=1 unlock\n * BX=file handle\n * CX:DX=region offset\n * SI:DI=region length\n * Exit: CF=0 None\n * CF=1 AX=error code\n * Note: File sharing (SHARE.EXE) must be loaded to use this function.\n * 5D File sharing functions (*) (3.0+)\n * Notes: 1) Some functions use a parameter block with the following format:\n * AX,BX,CX,DX,SI,DI,DS,ES,reserved,machine #,process (PSP)\n * 2) Functions 02-05 work only if file sharing (SHARE.EXE) is loaded.\n * 3) Functions 07-09 work only if the redirector (REDIR.EXE) is loaded.\n * 00 Server DOS call (*) (3.0+)\n * Entry: DS:DX->parameter block (AX,BX,CX,DX,SI,DI,DS,ES,machine #,process)\n * Exit: Depends on called function\n * 01 Commit all local files (*) (3.0+)\n * Entry: None\n * Exit: None\n * 02 Close all occurrences of file (*) (3.0+)\n * Entry: DS:DX->parameter block (DS:DX->qualified filespec)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 03 Close all files for machine (*) (3.0+)\n * Entry: DS:DX->parameter block (machine #)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 04 Close all files for machine and process (*) (3.0+)\n * Entry: DS:DX->parameter block (machine #,process)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 05 Get shared file info (*) (3.0+)\n * Entry: DS:DX->parameter block (BX=share file table index,CX=SFT index)\n * Exit: CF=0 AX=device info from SFT\n * BX=machine #\n * CX=lock count\n * ES:DI->qualified filename\n * CF=1 AX=error code\n * 06 Get DOS swappable data area (*) (3.0+)\n * Entry: None\n * Exit: DS:SI->DOS swappable data area\n * CX=DOS swappable data area length\n * DX=DOS critical data area length\n * Note: The first byte of the data area is the critical error flag.\n * 07 Get print stream state (*) (3.1+)\n * Entry: None\n * Exit: DL=state (0=truncate off,1=truncate on)\n * 08 Set print stream state (*) (3.1+)\n * Entry DL=state (0=truncate off,1=truncate on)\n * Exit: None\n * 09 Truncate print stream (*) (3.1+)\n * Entry None\n * Exit: None\n * 0A Set extended error info (3.1+)\n * Entry: DS:DX->parameter block (see function 59 for affected registers)\n * Exit: None\n * 5E Network functions (3.0+)\n * Note: Functions 02-05 work only if the redirector (REDIR.EXE) is loaded.\n * 00 Get machine name (3.0+)\n * Entry: DS:DX->buffer for machine name\n * Exit: CH=validity flag (0=invalid,1=valid)\n * CL=netbios number\n * 01 Set machine name (*) (3.0+)\n * Entry: DS:DX->machine name\n * CH=validity flag (0=invalid,1=valid)\n * CL=netbios number\n * Exit: None\n * 02 Set printer string (3.1+)\n * Entry: DS:SI->printer setup string\n * BX=redirection list index\n * CX=printer setup string length\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 03 Get printer string (3.1+)\n * Entry: ES:DI->buffer for printer setup string\n * BX=redirection list index\n * Exit: CF=0 CX=printer setup string length\n * CF=1 AX=error code\n * 04 Set print mode (*) (3.1+)\n * Entry: BX=redirection list index\n * DX=print mode (0=text,1=binary)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 05 Get print mode (*) (3.1+)\n * Entry: BX=redirection list index\n * Exit: CF=0 DX=print mode (0=text,1=binary)\n * CF=1 AX=error code\n * 5F Network redirection functions (3.1+)\n * Notes: 1) Functions 00-05 work only if the redirector (REDIR.EXE) is loaded.\n * 2) Functions 07-08 work only on builtin drives.\n * 00 Get redirection mode (*) (3.1+)\n * Entry: BL=device type (3=printer,4=disk)\n * Exit: CF=0 BH=redirection mode (0=off,1=on)\n * CF=1 AX=error code\n * 01 Set redirection mode (*) (3.1+)\n * Entry: BL=device type (3=printer,4=disk)\n * BH=redirection mode (0=off,1=on)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 02 Get redirection list entry (3.1+)\n * Entry: DS:SI->16-byte buffer for local device name\n * ES:DI->128-byte buffer for remote device name\n * BX=redirection list index\n * Exit: CF=0 BH=status (0=valid,1=invalid)\n * BL=device type (3=printer,4=disk)\n * CX=user word\n * CF=1 AX=error code\n * 03 Set redirection list entry (3.1+)\n * Entry: DS:SI->local device name\n * ES:DI->remote device name\n * BL=device type (3=printer,4=disk)\n * CX=user word\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 04 Cancel redirection list entry (3.1+)\n * Entry: DS:SI->local device name\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 05 Get redirection list entry extended (*) (4.0+)\n * Entry: DS:SI->16-byte buffer for local device name\n * ES:DI->128-byte buffer for remote device name\n * BX=redirection list index\n * Exit: CF=0 BH=status (0=valid,1=invalid)\n * BL=device type (3=printer,4=disk)\n * CX=user word\n * BP=netbios session number\n * CF=1 AX=error code\n * 07 Enable drive (*) (4.0+)\n * Entry: DL=drive code (0=default)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 08 Disable drive (*) (4.0+)\n * Entry: DL=drive code (0=default)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 60 Qualify filename (*) (3.0+)\n * Entry: DS:SI->filespec\n * ES:DI->buffer for qualified filespec\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 61 Reserved\n * 62 Get current PSP (3.0+)\n * Entry: None\n * Exit: BX=PSP segment\n * 63 Get DBCS lead byte table pointer (*) (3.0+)\n * Entry: AL must be 0\n * Exit: DS:SI->DBCS lead byte table\n * 64 Set wait for external event flag (*) (3.2+)\n * Entry: AL=flag (0=enable,>0=disable)\n * Exit: None\n * Note: This function affects the PC Convertible only.\n * If enabled and the default console driver is being used then\n * INT 15 function 41 is issued while waiting for console input\n * during functions 01,08,0A,and 3F.\n * 65 Get extended country info (3.3+)\n * Entry: AL=01 get extended country info\n * 02 get country uppercase table\n * 03 get country lowercase table (reserved until 6.2)\n * 04 get country filename uppercase table\n * 05 get country filename character table\n * 06 get country collating table\n * 07 get DBCS vector table (4.0+)\n * 20 uppercase character (4.0+)\n * 21 uppercase string (4.0+)\n * 22 uppercase ASCIIZ string (4.0+)\n * 23 yes/no check (*) (4.0+)\n * A0 uppercase filename character (*) (4.0+)\n * A1 uppercase filename string (*) (4.0+)\n * A2 uppercase filename ASCIIZ string (*) (4.0+)\n * A3 yes/no check (*) (4.0+)\n * if function 01-07:\n * BX=code page (-1=active code page)\n * CX=length to return (must be at least 5)\n * DX=country code (-1=default)\n * ES:DI->return buffer\n * if function 20,23,A0,A3:\n * DL=character\n * if function 21,A1:\n * DS:DX->string\n * CX=string length\n * if function 22,A2:\n * DS:DX->string\n * Exit: CF=0 CX=data length if function 01-07\n * DL=character if function 20\n * AX=code if function 23,A3 (0=no,1=yes,2=neither)\n * CF=1 AX=error code\n * buffer format if function 01:\n * 0 info ID\n * 1 length\n * 3 country code\n * 5 code page\n * 7 country info (same format as function 38)\n * buffer format if function 02-07:\n * 0 info ID\n * 1 pointer to requested table (word length followed by data)\n * 66 Get or set code page (3.3+)\n * Entry: AL=1 get code page\n * AL=2 set code page\n * BX=active code page if set\n * Exit: CF=0 BX=active code page if get\n * DX=default code page if get\n * CF=1 AX=error code\n * 67 Set handle count (3.3+)\n * Entry: BX=handle count\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 68 Commit file (3.3+)\n * Entry: BX=file handle\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 69 Get or set media info (*) (4.0+)\n * Entry: AL=0 get media info\n * AL=1 set media info\n * BL=drive code (0=default)\n * DS:DX->media info\n * Exit: CF=0 None\n * CF=1 AX=error code\n * Media info format:\n * 0 info level (must be 0)\n * 2 volume serial number\n * 6 volume label\n * 17 8-byte file system type\n * 6A Commit file (*) (4.0+)\n * Entry: Same as function 68\n * Exit: Same as function 68\n * 6B Reserved\n * 6C Extended open/create file (4.0+)\n * Entry: DS:SI->filename\n * BX=open mode\n * Bit 0-2 access mode\n * 000=read\n * 001=write\n * 010=read/write\n * 4-6 sharing mode\n * 000=compatibility\n * 001=deny read/write access\n * 010=deny write access\n * 011=deny read access\n * 100=deny none access\n * 7 inheritance flag\n * 0=file inherited by EXECed programs\n * 1=file not inherited by EXECed programs\n * 13 critical error handling\n * 0=execute INT 24\n * 1=return error code\n * 14 buffering\n * 0=buffer writes\n * 1=don't buffer writes\n * CX=file attributes\n * DX=open flags\n * Bit 0-3 0000=fail if exists\n * 0001=open if exists\n * 0010=truncate if exists\n * 4-7 0000=fail if doesn't exist\n * 0001=create if doesn't exist\n * Exit: CF=0 AX=file handle\n * CX=action code (1=file opened,2=file created,3=file truncated)\n * CF=1 AX=error code\n *\n * INT 22 Terminate address (1.0+)\n * This is the address that DOS returns to after program termination.\n * It is set during execute program (function 4B) processing.\n *\n * INT 23 Ctrl-Break handler address (1.0+)\n * This routine is entered when Ctrl-Break is detected by DOS.\n * On entry the registers are set to the values they had at the start\n * of the interrupted function call. Control may be returned via\n * IRET or FAR RET, if FAR RET is used and the carry flag is set\n * then the program is aborted otherwise the function is restarted.\n * Note: Any DOS function may be issued from an INT 23 handler.\n *\n * INT 24 Critical error handler address (1.0+)\n * Entry: AH=error indicator\n * Bit 0 0=read error\n * 1=write error\n * 1-2 disk area\n * 00=DOS area\n * 01=FAT\n * 10=directory\n * 11=data area\n * 3 1=fail allowed\n * 4 1=retry allowed\n * 5 1=ignore allowed\n * 7 0=block device error\n * 1=character device error\n * AL=drive code (0=A)\n * DI=error code (lower half of DI)\n * 00=write-protect error 07=unknown media type\n * 01=unknown unit 08=sector not found\n * 02=drive not ready 09=printer out of paper\n * 03=unknown command 0A=write fault\n * 04=data error (CRC) 0B=read fault\n * 05=bad request structure length 0C=general failure\n * 06=seek error 0F=invalid disk change\n * BP:SI=pointer to device driver header\n * Exit: Control may be returned to DOS via IRET with an action code in AL\n * 0=ignore error (fail if ignore is unallowed)\n * 1=retry function (fail if retry is unallowed)\n * 2=abort program\n * 3=fail system call (abort if fail is unallowed)\n * Control may be returned directly to the program by removing the\n * INT 24 registers (IP,CS,flags) from the stack, restoring the\n * program's registers (AX,BX,CX,DX,SI,DI,BP,DS,ES) and issuing\n * an IRET. This will leave DOS in an unstable state because the\n * critical error flag is set until a DOS function other than 01-0C,\n * 33,50,51,59,62,or 64 is issued.\n * Note: Only DOS functions 01-0C,33,50,51,59,62,or 64 should be issued from\n * an INT 24 handler.\n *\n * INT 25 Absolute disk read (1.0+)\n * Entry: AL=drive number (0=A)\n * CX=number of sectors or -1 if >32M partition\n * DX=starting sector number\n * DS:BX->data buffer or parameter block\n * parameter block (3.31+)\n * 0 starting sector number\n * 4 number of sectors\n * 6 data buffer\n * Exit: CF=0 None\n * CF=1 AH=error code\n * 01=bad command\n * 02=bad address mark\n * 03=write-protect error\n * 04=sector not found\n * 08=DMA overrun\n * 10=data error (bad CRC)\n * 20=controller error\n * 40=seek error\n * 80=timed-out\n * AL=device error code (same as lower byte of DI for INT 24)\n * Notes: 1) The CPU flags are still on the stack after an INT 25 or INT 26.\n * 2) All registers except the segment registers and SP may be destroyed.\n *\n * INT 26 Absolute disk write (1.0+)\n * Entry: Same as INT 25\n * Exit: Same as INT 25\n *\n * INT 27 Terminate and stay resident (1.0+)\n * Entry: CS=PSP\n * DX=number of bytes to stay resident (minimum 96)\n * Exit: Does not return to caller\n *\n * INT 28 Idle handler (2.0+)\n * This interrupt is issued by DOS during functions 01-0C to indicate\n * that a TSR program may safely issue a non-character I/O DOS\n * function even though the InDOS flag is not zero.\n * DOS functions 01-0C should not be issued from a INT 28 handler\n * unless the critical error flag is set first.\n *\n * INT 29 Character output (2.0+)\n * Entry: AL=character\n * Exit: None\n * Note: This interrupt is called for character output if the console\n * device has bit 4 in the device attribute word set.\n *\n * INT 2A Network/critical section (*) (3.0+)\n * 00 Network installation check (3.0+)\n * Entry: None\n * Exit: AH=00 not installed\n * AH=FF installed\n * 01 Execute NETBIOS request with no error retry (*) (3.0+)\n * Entry: ES:BX->network control block\n * Exit: AH=0 no error\n * AH=1 AL=error code\n * 02 Set network printer parameters (*) (3.0+)\n * Entry: DS:SI->16-byte buffer for local device name\n * BX=characters per line (-1=use current)\n * CX=lines per inch (-1=use current)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 03 Check direct I/O (3.0+)\n * Entry: DS:SI->ASCIIZ disk name (d:)\n * Exit: CF=0 direct I/O allowed\n * CF=1 direct I/O not allowed\n * 04 Execute NETBIOS request (3.0+)\n * Entry: AL=error retry flag (0=retry,1=no retry)\n * ES:BX->network control block\n * Exit: AH=0 no error\n * AH=1 AL=error code\n * 05 Get network resource information (3.0+)\n * Entry: None\n * Exit: BX=available network name count\n * CX=available network control block count\n * DX=available network session count\n * 06 Network print stream control (3.0+)\n * Entry: AL=mode (1=concatenation,2=truncation,3=truncate stream)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 80 Begin critical section (*) (3.0+)\n * Entry: AL=critical section number\n * Exit: None\n * 81 End critical section (*) (3.0+)\n * Entry: AL=critical section number\n * Exit: None\n * 82 End all critical sections (*) (3.0+)\n * Entry: None\n * Exit: None\n * 84 Keyboard idle loop (*) (3.0+)\n * Entry: None\n * Exit: None\n *\n * INT 2E Execute command (*) (2.0+)\n * Entry: DS:SI->command string-1 followed by a carriage return\n * Exit: All registers except CS and IP are destroyed\n * Note: This function is not re-entrant and should not be issued from a\n * batch file.\n *\n * INT 2F Multiplex (3.0+)\n * Entry: AH=program identifier\n * AL=function code\n * Other registers depend on the function\n * Exit: Depends on the function\n *\n * Program identifier codes:\n * 01 Print queueing (PRINT) (3.0+)\n * 02 Network printer control (REDIR) (3.1+)\n * 05 Network error message lookup (REDIR) (3.0+)\n * 06 ASSIGN (3.1+)\n * 08 IBMBIO drive services (used by DRIVER.SYS) (3.2+)\n * 10 File sharing (SHARE) (3.0+)\n * 11 Redirector services (REDIR and MSCDEX) (3.0+)\n * 12 DOS internal services (used by REDIR and MSCDEX) (3.0+)\n * 13 Swap INT 13 vector (3.2+)\n * 14 NLS support (NLSFUNC) (3.3+)\n * 15 CD-ROM extensions (MSCDEX)\n * 16 Windows services\n * 17 Windows clipboard services\n * 1A ANSI.SYS (4.0+)\n * 43 XMS services (HIMEM.SYS)\n * 46 Windows support\n * 48 DOSKEY (5.0+)\n * 4A DOS services (HMA, RPL), SMARTDRV (5.0+)\n * 53 POWER (APM events broadcast) (5.02+)\n * 54 POWER (main API) (5.02+)\n * 55 COMMAND.COM (5.0+)\n * 56 INTERLNK (5.02+)\n * AC GRAPHICS (5.0+)\n * AD DISPLAY.SYS, KEYB (3.3+)\n * AE Installable command support (APPEND) (3.3+)\n * B0 GRAFTABL (3.3+)\n * B7 APPEND (3.2+)\n *\n * DOS extended error information:\n *\n * Extended error code: Error class:\n * 01 Invalid function number 01 Out of resource\n * 02 File not found 02 Temporary situation\n * 03 Path not found 03 Authorization error\n * 04 Too many open files 04 Internal DOS error\n * 05 Access denied 05 Hardware failure\n * 06 Invalid handle 06 System software failure\n * 07 Memory control blocks destroyed 07 Application program error\n * 08 Insufficient memory 08 Not found\n * 09 Invalid memory block address 09 Invalid format\n * 0A Invalid environment 0A File locked\n * 0B Invalid format 0B Media error\n * 0C Invalid access code 0C Already exists\n * 0D Invalid data 0D Unknown\n * 0E Reserved\n * 0F Invalid drive Suggested action:\n * 10 Attempt to remove current directory 01 Retry\n * 11 Not same device 02 Delay and retry\n * 12 No more files 03 Get corrected user input\n * 13 Write-protect error 04 Exit with cleanup\n * 14 Unknown unit 05 Exit without cleanup\n * 15 Drive not ready 06 Ignore error\n * 16 Unknown command 07 Retry after user intervention\n * 17 Data error (CRC)\n * 18 Bad request structure length Error locus:\n * 19 Seek error 01 Unknown\n * 1A Unknown medium type 02 Block device error\n * 1B Sector not found 03 Network error\n * 1C Printer out of paper 04 Character device error\n * 1D Write fault 05 Memory error\n * 1E Read fault\n * 1F General failure\n * 20 Sharing violation\n * 21 Lock violation\n * 22 Invalid disk change\n * 23 FCB unavailable\n * 24 Sharing buffer overflow\n * 25 Code page mismatch (4.0+)\n * 26 Out of input (4.0+)\n * 27 Insufficient disk space (4.0+)\n * 32 Function not supported\n * 41 Network access denied\n * 50 File exists\n * 51 Reserved\n * 52 Cannot make directory entry\n * 53 Fail on INT 24\n *\n * DOS table and structure reference (from https://sites.google.com/site/pcdosretro/dostables)\n *\n * Program Segment Prefix (100h bytes)\n * 00 INT 20\n * 02 End of allocation segment\n * 04 Reserved\n * 05 Far call to DOS\n * 0A Saved INT 22 vector\n * 0E Saved INT 23 vector\n * 12 Saved INT 24 vector (1.1+)\n * 16 Caller PSP segment (2.0+)\n * 18 File table (2.0+)\n * 2C Environment segment (2.0+)\n * 2E Stack pointer after last DOS call (2.0+)\n * 32 File table size (3.0+)\n * 34 Pointer to file table (3.0+)\n * 38 Pointer to next PSP (SHARE only) (3.0+)\n * 3C Reserved\n * 40 DOS version (4.0+)\n * 42 Reserved\n * 50 INT 21,RETF (2.0+)\n * 53 Reserved\n * 5C FCB 1\n * 6C FCB 2\n * 7C Unused\n * 80 Command tail\n *\n * File Control Block (25h bytes)\n * 00 Drive code (1=A)\n * 01 Filename\n * 09 Extension\n * 0C Current block number\n * 0E Record size\n * 10 File size\n * 14 Date\n * 16 Time\n * 18 Reserved\n * 20 Current record number\n * 21 Random record number\n *\n * Extended FCB (2Ch bytes)\n * 00 FF (Extended FCB indicator)\n * 01 Reserved\n * 06 Attribute byte\n * 07 Standard FCB\n *\n * Disk partition table entry (10h bytes)\n * 00 Status (00=non-bootable,80=bootable)\n * 01 Starting head\n * 02 Starting cylinder and sector (INT 13 format)\n * 04 Type (0=unknown,1=FAT12,4=FAT16,5=extended,6=BIGDOS)\n * 05 Ending head\n * 06 Ending cylinder and sector (INT 13 format)\n * 08 Starting absolute sector\n * 0C Number of sectors\n * Note: There are 4 entries starting at offset 1BE\n *\n * Disk boot sector (200h bytes)\n * 00 Jump to boot code\n * 03 OEM name\n * 0B Bytes per sector\n * 0D Sectors per cluster\n * 0E Number of reserved sectors\n * 10 Number of FATs\n * 11 Number of root directory entries\n * 13 Total number of sectors\n * 15 Media descriptor byte\n * F0 1.44M (2 sides,18 sectors/track,80 tracks)\n * 2.88M (2 sides,36 sectors/track,80 tracks)\n * F8 fixed disk\n * F9 720K (2 sides,9 sectors/track,80 tracks)\n * 1.2M (2 sides,15 sectors/track,80 tracks)\n * FC 180K (1 side,9 sectors/track,40 tracks)\n * FD 360K (2 sides,9 sectors/track,40 tracks)\n * FE 160K (1 side,8 sectors/track,40 tracks)\n * FF 320K (2 sides,8 sectors/track,40 tracks)\n * 16 Sectors per FAT\n * 18 Sectors per track\n * 1A Number of heads\n * 1C Number of hidden sectors\n * 20 32-bit number of sectors if word at 13=0 (3.31+)\n * 24 Drive number (4.0+)\n * 25 Reserved (4.0+)\n * 26 Extended boot record ID (29) (4.0+)\n * 27 Serial number (4.0+)\n * 2B Volume label (4.0+)\n * 36 8-byte file system name (4.0+)\n * Note: Bytes 0B-23 are the BIOS parameter block\n *\n * Directory entry (20h bytes)\n * 00 Filename\n * 08 Extension\n * 0B Attribute byte\n * 01=Read-only\n * 02=Hidden\n * 04=System\n * 08=Volume label (2.0+)\n * 10=Directory (2.0+)\n * 20=Archive (2.0+)\n * 0C Reserved\n * 16 Time\n * Bits 0-4 Seconds/2 (0-29)\n * 5-10 Minutes (0-59)\n * 11-15 Hours (0-23)\n * 18 Date\n * Bits 0-4 Day (1-31)\n * 5-8 Month (1-12)\n * 9-15 Year-1980\n * 1A Starting cluster number\n * 1C File size\n *\n * Disk parameter block (20h bytes in 3.x, 21h bytes in 4.0+)\n * 00 Drive code (0=A)\n * 01 Unit code\n * 02 Bytes per sector\n * 04 Sectors per cluster-1\n * 05 Cluster shift factor (2**n sectors per cluster)\n * 06 First FAT sector\n * 08 Number of FATs\n * 09 Number of directory entries\n * 0B First data sector\n * 0D Maximum cluster number\n * 0F Sectors per FAT\n * 11 First directory sector\n * 13 Pointer to device driver\n * 17 Media descriptor byte\n * 18 Access flag (00=accessed,FF=not accessed)\n * 19 Pointer to next DPB\n * 1D Last cluster allocated\n * 1F Number of free clusters (-1 if unknown)\n * Note: (3.x) The sectors per FAT field is one byte and all following\n * fields are moved back one byte.\n *\n * System file table (35h bytes in 3.x, 3Bh bytes in 4.0+)\n * 00 Open count\n * 02 Open mode\n * Bit 0-2 access mode\n * 000=read\n * 001=write\n * 010=read/write\n * 4-6 sharing mode\n * 000=compatibility\n * 001=deny read/write\n * 010=deny write\n * 011=deny read\n * 100=deny none\n * 13 critical error handling\n * 0=execute INT 24\n * 1=return error code\n * 14 buffering\n * 0=buffer writes\n * 1=don't buffer writes\n * 15 1=FCB SFT\n * 04 Attribute byte\n * 05 Device info\n * Character devices: Block devices:\n * Bit 0 1=console input Bit 0-5 drive code (0=A)\n * 1 1=console output 6 0=file has been written\n * 2 1=NUL device 7 0=block device\n * 3 1=CLOCK device 12 1=no inherit\n * 4 1=INT 29 output (CON) 14 1=date/time set\n * 5 0=ASCII,1=binary 15 1=redirected file\n * 6 0=EOF on input\n * 7 1=character device\n * 11 1=network spooler\n * 12 1=no inherit\n * 13 1=named pipe\n * 15 1=redirected device\n * 07 Pointer to device driver or disk parameter block\n * 0B First cluster number\n * 0D Time\n * 0F Date\n * 11 File size\n * 15 File pointer\n * 19 Current relative cluster number\n * 1B 32-bit directory entry sector (4.0+)\n * 1B Current absolute cluster number (3.x)\n * 1D Directory entry sector (3.x)\n * 1F Directory entry position in sector\n * 20 Filename\n * 28 Extension\n * 2B Pointer to next SFT for the same file (SHARE only)\n * 2F Machine number\n * 31 PSP of owner\n * 33 SHARE file table offset\n * 35 Current absolute cluster number (4.0+)\n * 37 Reserved (4.0+)\n *\n * SHARE file table\n * 00 Entry flag (1=open,0=unused,-1=end of list)\n * 01 Entry length\n * 03 Filespec checksum\n * 04 First lock table offset\n * 06 Pointer to system file table\n * 0A SHARE file number\n * 0C Filespec\n *\n * SHARE lock table (10h bytes)\n * 00 Offset to next lock table for file\n * 02 Start of lock region\n * 06 End of lock region\n * 0A Pointer to system file table\n * 0E PSP of owner\n *\n * Current directory structure (51h bytes in 3.x, 58h bytes in 4.0+)\n * 00 Current directory\n * 43 Drive type\n * 1000=SUBSTed drive\n * 2000=JOINed drive\n * 4000=valid drive\n * 8000=redirected drive\n * 45 Pointer to disk parameter block\n * 49 Cluster number of current directory (0=root)\n * 4B Reserved\n * 4F Length of root directory name starting at offset 0\n * 51 Reserved (4.0+)\n *\n * Disk buffer header (10h bytes) (3.x)\n * 00 Pointer to next buffer\n * 04 Drive code (0=A,FF=unused)\n * 05 Flags\n * Bit 0 reserved\n * 1 1=FAT sector\n * 2 1=directory sector\n * 3 1=data sector\n * 4 reserved\n * 5 1=buffer read\n * 6 1=buffer written\n * 7 reserved\n * 06 Sector number\n * 08 Number of FATs (if FAT) or 1\n * 09 Sectors per FAT (if FAT) or 0\n * 0A Pointer to DPB\n * 0E Reserved\n * 10 Buffered sector\n *\n * Disk buffer header (14h bytes) (4.0+)\n * 00 Pointer to next buffer\n * 02 Pointer to previous buffer\n * 04 Drive code (0=A,FF=unused)\n * 05 Flags\n * Bit 0 reserved\n * 1 1=FAT sector\n * 2 1=directory sector\n * 3 1=data sector\n * 4 reserved\n * 5 1=buffer read (4.0)\n * 6 1=buffer written\n * 7 reserved\n * 06 Sector number\n * 0A Number of FATs (if FAT) or 1\n * 0B Sectors per FAT (if FAT) or 0\n * 0D Pointer to DPB\n * 11 Reserved\n * 14 Buffered sector\n *\n * Disk buffer control block (4.0)\n * 00 Pointer to buffer chain array\n * 04 Number of chains\n * 06 Pointer to sector lookahead buffers\n * 0A Number of sector lookahead buffers\n * 0C Unknown\n *\n * Disk buffer control block (5.0+)\n * 00 Pointer to buffer chain\n * 04 Number of modified buffers\n * 06 Pointer to sector lookahead buffers\n * 0A Number of sector lookahead buffers\n * 0C HMA flag (1=buffers in HMA)\n * 0D Pointer to HMA transfer buffer\n *\n * Disk buffer chain array entry (8 bytes) (4.0)\n * 00 Reserved\n * 02 Pointer to last accessed buffer\n * 06 Number of modified buffers\n * 07 Reserved\n *\n * Stacks block header (12h bytes)\n * 00 Reserved\n * 02 Number of stacks\n * 04 Offset of stacks\n * 06 Stack size\n * 08 Pointer to stacks table (descriptors followed by stacks)\n * 0C Offset of first stacks descriptor\n * 0E Offset of last stacks descriptor\n * 10 Offset of current stacks descriptor\n *\n * Stacks descriptor (8 bytes)\n * 00 Flag (0=free,1=in use)\n * 02 Save area for SS:SP\n * 06 Offset of end of stack\n *\n * Device driver header (12h bytes)\n * 00 Pointer to next device driver or -1\n * 04 Attribute word\n * Bit 0 1=console input\n * 1 1=console output (character devices)\n * 1=32-bit sectors supported (block devices) (3.31+)\n * 2 1=NUL device\n * 3 1=CLOCK device\n * 4 1=INT 29 output (CON)\n * 6 1=extended functions supported (13,17,18) (3.2+)\n * 7 1=query IOCTL function supported (19) (5.0+)\n * 11 1=open/close/removable media supported (3.0+)\n * 13 1=output until busy supported (character devices) (3.0+)\n * 1=media descriptor in FAT required (block devices)\n * 14 1=IOCTL supported\n * 15 0=block device\n * 1=character device\n * 06 Strategy address\n * 08 Interrupt address\n * 0A Device name or number of units\n *\n * Device driver request header (common fields)\n * 00 Request header length\n * 01 Unit number\n * 02 Command code\n * 00=Init 0B=Flush output buffers\n * 01=Media check 0C=I/O control write\n * 02=Build BPB 0D=Open (3.0+)\n * 03=I/O control read 0E=Close (3.0+)\n * 04=Read 0F=Removable media check (3.0+)\n * 05=Non-destructive read 10=Output until busy (3.0+)\n * 06=Input status 13=Generic I/O control (3.2+)\n * 07=Flush input buffers 17=Get drive map (3.2+)\n * 08=Write 18=Set drive map (3.2+)\n * 09=Write with verify 19=Query I/O control (5.0+)\n * 0A=Output status\n * 03 Return status word\n * Bit 0-7 if error\n * 00=write-protect error 07=unknown medium\n * 01=unknown unit 08=sector not found\n * 02=drive not ready 09=printer out of paper\n * 03=unknown command 0A=write fault\n * 04=data error (CRC) 0B=read fault\n * 05=bad request length 0C=general failure\n * 06=seek error 0F=invalid disk change\n * 8 1=done\n * 9 1=busy\n * 15 1=error\n * 05 Reserved (8 bytes)\n *\n * Device driver request headers:\n * Init\n * 00 Common (length=17h in 3.x, 19h in 4.0+)\n * 0D Number of units (set by driver)\n * 0E End of available memory (5.0+)\n * End of resident code (set by driver)\n * 12 Pointer to string after DEVICE=\n * BPB array pointer (set by driver)\n * 16 Drive code of first unit (0=A)\n * 17 Error message flag (1=display message) (4.0+)\n *\n * Media check\n * 00 Common (length=13h)\n * 0D Media descriptor byte\n * 0E Status (set by driver: 1=unchanged,0=unknown,-1=changed)\n * 0F Pointer to previous disk label (set by driver if disk changed)\n *\n * Build BPB\n * 00 Common (length=16h)\n * 0D Media descriptor byte\n * 0E Pointer to sector buffer\n * 12 Pointer to BPB (set by driver)\n * Note: The sector buffer contains the first sector of the FAT if bit 13 in the\n * device attribute word is zero otherwise it may be used as scratch space.\n *\n * IOCTL read, Read, Write, Write with verify, IOCTL write, Output until busy\n * 00 Common (length=14h)\n * 0D Unused\n * 0E Pointer to data buffer\n * 12 Byte count (set by driver to number of bytes transferred)\n * Notes: 1) The IOCTL functions are called only if bit 14 in the device\n * attribute word is set.\n * 2) The output until busy function is called only if bit 13 in the\n * device attribute word is set.\n *\n * Read, Write, Write with verify\n * 00 Common (length=16h-1Eh)\n * 0D Media descriptor byte\n * 0E Pointer to data buffer\n * 12 Sector count (set by driver to number of sectors transferred)\n * 14 Starting sector number (-1=if 32-bit sectors)\n * 16 Pointer to previous disk label (set by driver if error 0F)\n * 1A 32-bit starting sector number\n * Note: The 32-bit starting sector number is used only if bit 1 in the\n * device attribute word is set.\n *\n * Non-destructive read\n * 00 Common (length=0Eh)\n * 0D Character (set by driver)\n * Note: This function sets the busy bit (bit 9) in the request header\n * if no character is ready.\n *\n * Input status, Output status\n * 00 Common (length=0Dh)\n * Note: These functions set the busy bit (bit 9) in the request header\n * to indicate device status.\n *\n * Flush input buffers, Flush output buffers\n * 00 Common (length=0Dh)\n *\n * Open, Close, Removable media check\n * 00 Common (length=0Dh)\n * Notes: 1) These functions are called only if bit 11 in the device\n * attribute word is set.\n * 2) The removable media check function sets bit 9 in the status word\n * if the device is non-removable.\n *\n * Generic IOCTL, Query IOCTL\n * 00 Common (length=17h)\n * 0D Category code\n * 0E Function code\n * 0F Unused\n * 13 Parameter buffer pointer\n * Notes: 1) The Generic IOCTL function is called only if bit 6 in the device\n * attribute word is set.\n * 2) The Query IOCTL function is called only if bit 7 in the device\n * attribute word is set.\n *\n * Get drive map, Set drive map\n * 00 Common (length=0Dh)\n * Notes: 1) These functions are called only if bit 6 in the device\n * attribute word is set.\n * 2) These functions set the unit field (byte 1) in the request\n * header to the physical drive code.\n *\n * Clock device info (6 bytes)\n * 00 Days since 1/1/80\n * 02 Minutes\n * 03 Hours\n * 04 Hundredths\n * 05 Seconds\n *\n * Memory Control Block (10h bytes)\n * 00 Type ('M' or 'Z' if last)\n * 01 PSP segment of owner (0=free,8=DOS)\n * 03 Size (paragraphs)\n * 05 Unused\n * 08 Program name (4.0+)\n *\n * EXE file header\n * 00 'MZ'\n * 02 Size of last page\n * 04 File size in 512-byte pages\n * 06 Relocation table count\n * 08 Header size (paragraphs)\n * 0A Minimum allocation (paragraphs)\n * 0C Maximum allocation (paragraphs)\n * 0E Initial SS\n * 10 Initial SP\n * 12 Checksum\n * 14 Initial IP\n * 16 Initial CS\n * 18 Offset of relocation table\n * Table entry format:\n * 0 offset of relocation\n * 2 segment of relocation\n * 1A Overlay number\n *\n * EXEPACK header\n * 00 Actual IP\n * 02 Actual CS\n * 04 0 (set to PSP+10h by unpack code)\n * 06 Unpack code and data size (including relocation table)\n * 08 Actual SP\n * 0A Actual SS\n * 0C Actual code and data size\n *\n * Note: If an EXE file is packed then CS:IP-2 points to 'RB' and CS:0\n * points to the EXEPACK header, this is followed by the unpack code\n * and a relocation table containing a word count and relocation\n * entries for 16 segments.\n */\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/messages.js (C) Jeff Parsons 2012-2018\n */\n\nvar Messages = {\n NONE: 0x00000000,\n CPU: 0x10000001,\n SEG: 0x10000002,\n DESC: 0x10000003,\n TSS: 0x10000004,\n PORT: 0x10000008,\n IOPM: 0x10000009,\n NMI: 0x10000010,\n TRAP: 0x10000020,\n FAULT: 0x10000030,\n INT: 0x10000040,\n IRQ: 0x20000080,\n BUS: 0x20000100,\n MEM: 0x20000200,\n DMA: 0x20000400,\n FDC: 0x20000800,\n HDC: 0x20001000,\n DISK: 0x20002000,\n PIC: 0x20004000,\n TIMER: 0x20008000,\n CMOS: 0x20010000,\n RTC: 0x20020000,\n C8042: 0x20040000,\n KBD: 0x20080000,\n PARALLEL: 0x20100000,\n SERIAL: 0x20200000,\n MOUSE: 0x20400000,\n SPEAKER: 0x20800000,\n CHIPSET: 0x21000000,\n VIDEO: 0x22000000,\n COMPUTER: 0x24000000,\n DOS: 0x40000001,\n DATA: 0x40000002,\n EVENT: 0x40000004,\n KEY: 0x40000010,\n WARN: 0x40000020,\n HALT: 0x84000000|0,\n BUFFER: 0x88000000|0\n};\n\n/*\n * Message categories supported by the messageEnabled() function and other assorted message\n * functions. Each category has a corresponding bit value that can be combined (ie, OR'ed) as\n * needed. The Debugger's message command (\"m\") is used to turn message categories on and off,\n * like so:\n *\n * m port on\n * m port off\n * ...\n *\n * NOTE: The order of these categories can be rearranged, alphabetized, etc, as desired; just be\n * aware that changing the bit values could break saved Debugger states (not a huge concern, just\n * something to be aware of).\n */\nMessages.CATEGORIES = {\n \"cpu\": Messages.CPU,\n \"seg\": Messages.SEG,\n \"desc\": Messages.DESC,\n \"port\": Messages.PORT,\n \"tss\": Messages.TSS,\n \"iopm\": Messages.IOPM,\n \"int\": Messages.INT,\n \"nmi\": Messages.NMI,\n \"fault\": Messages.FAULT,\n \"trap\": Messages.TRAP,\n \"bus\": Messages.BUS,\n \"irq\": Messages.IRQ,\n \"mem\": Messages.MEM,\n \"dma\": Messages.DMA,\n \"fdc\": Messages.FDC,\n \"hdc\": Messages.HDC,\n \"disk\": Messages.DISK,\n \"pic\": Messages.PIC,\n \"timer\": Messages.TIMER,\n \"cmos\": Messages.CMOS,\n \"rtc\": Messages.RTC,\n \"8042\": Messages.C8042,\n \"kbd\": Messages.KBD,\n \"parallel\": Messages.PARALLEL,\n \"serial\": Messages.SERIAL,\n \"mouse\": Messages.MOUSE,\n \"speaker\": Messages.SPEAKER,\n \"chipset\": Messages.CHIPSET,\n \"video\": Messages.VIDEO,\n \"computer\": Messages.COMPUTER,\n \"dos\": Messages.DOS,\n \"data\": Messages.DATA,\n \"event\": Messages.EVENT,\n \"key\": Messages.KEY,\n \"warn\": Messages.WARN,\n /*\n * Now we turn to message actions rather than message types; for example, setting \"halt\"\n * on or off doesn't enable \"halt\" messages, but rather halts the CPU on any message above.\n *\n * Similarly, \"m buffer on\" turns on message buffering, deferring the display of all messages\n * until \"m buffer off\" is issued.\n */\n \"halt\": Messages.HALT,\n \"buffer\": Messages.BUFFER\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/panel.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Region object definition\n *\n * iBlock: starting block number\n * cBlocks: number of blocks spanned by region\n * type: type of all blocks in the region (see Memory.TYPE.*)\n *\n * @typedef {{\n * iBlock: number,\n * cBlocks: number,\n * type: number\n * }} Region\n */\nvar Region;\n\nclass Color {\n /**\n * Color(r, g, b, a)\n *\n * @this {Color}\n * @param {number} [r]\n * @param {number} [g]\n * @param {number} [b]\n * @param {number} [a]\n */\n constructor(r, g, b, a)\n {\n this.rgb = [r, g, b, a];\n this.sValue = null;\n if (r === undefined) this.randomize();\n }\n\n /**\n * getRandom(nLimit)\n *\n * @this {Color}\n * @param {number} [nLimit]\n */\n getRandom(nLimit)\n {\n return (Math.random() * (nLimit || 0x100)) | 0;\n }\n\n /**\n * randomize()\n *\n * @this {Color}\n */\n randomize()\n {\n this.rgb[0] = this.getRandom(); this.rgb[1] = this.getRandom(); this.rgb[2] = this.getRandom(); this.rgb[3] = 0xff;\n this.sValue = null;\n }\n\n /**\n * toString()\n *\n * @this {Color}\n * @return {string}\n */\n toString()\n {\n if (!this.sValue) this.sValue = '#' + Str.toHex(this.rgb[0], 2) + Str.toHex(this.rgb[1], 2) + Str.toHex(this.rgb[2], 2);\n return this.sValue;\n }\n}\n\nclass Rectangle {\n /**\n * Rectangle(x, y, cx, cy)\n *\n * @this {Rectangle}\n * @param {number} x\n * @param {number} y\n * @param {number} cx\n * @param {number} cy\n */\n constructor(x, y, cx, cy)\n {\n this.x = x;\n this.y = y;\n this.cx = cx;\n this.cy = cy;\n }\n\n /**\n * contains(x, y)\n *\n * @param {number} x\n * @param {number} y\n * @return {boolean} true if (x,y) lies within the rectangle, false if not\n */\n contains(x, y)\n {\n return (x >= this.x && x < this.x + this.cx && y >= this.y && y < this.y + this.cy);\n }\n\n /**\n * subDivide(units, unitsTotal, fHorizontal)\n *\n * Return a new rectangle that is a subset of the current rectangle, based on the ratio of\n * units to unitsTotal, and then update the dimensions of the current rectangle. Whether the\n * original rectangle is divided horizontally or vertically is entirely arbitrary; currently,\n * the criteria is horizontal if the ratio is 1/4 or more, vertical otherwise.\n *\n * @this {Rectangle}\n * @param {number} units\n * @param {number} unitsTotal\n * @param {boolean} [fHorizontal]\n * @return {Rectangle}\n */\n subDivide(units, unitsTotal, fHorizontal)\n {\n var rect;\n if (fHorizontal === undefined) {\n fHorizontal = units >= (unitsTotal >> 2);\n }\n if (fHorizontal) {\n rect = new Rectangle(this.x, this.y, this.cx, ((this.cy * units) / unitsTotal) | 0);\n this.y += rect.cy;\n this.cy -= rect.cy;\n\n } else {\n rect = new Rectangle(this.x, this.y, ((this.cx * units) / unitsTotal) | 0, this.cy);\n this.x += rect.cx;\n this.cx -= rect.cx;\n\n }\n return rect;\n }\n\n /**\n * drawWith(context, color)\n *\n * @param {Object} context\n * @param {Color|string} [color]\n */\n drawWith(context, color)\n {\n if (!color) color = new Color();\n context.strokeStyle = \"black\";\n context.strokeRect(this.x, this.y, this.cx, this.cy);\n context.fillStyle = (typeof color == \"string\"? color : color.toString());\n context.fillRect(this.x, this.y, this.cx, this.cy);\n }\n}\n\n/**\n * class Panel\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass Panel extends Component {\n /**\n * Panel(parmsPanel)\n *\n * The Panel component has no required (parmsPanel) properties.\n *\n * @this {Panel}\n * @param {Object} parmsPanel\n */\n constructor(parmsPanel)\n {\n super(\"Panel\", parmsPanel);\n\n this.canvas = null;\n this.lockMouse = -1;\n this.fMouseDown = false;\n this.xMouse = this.yMouse = -1;\n this.timer = -1;\n if (BACKTRACK) {\n this.busInfo = null;\n this.fBackTrack = false;\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {Panel}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n var panel = this;\n\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.kbd = cmp.getMachineComponent(\"Keyboard\");\n this.startTimer();\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * Most panel layouts don't have bindings of their own, so we pass along all binding requests to the\n * Computer, CPU, Keyboard and Debugger components first. The order shouldn't matter, since any component\n * that doesn't recognize the specified binding should simply ignore it.\n *\n * @this {Panel}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n if (this.cmp && this.cmp.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (this.cpu && this.cpu.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (this.kbd && this.kbd.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (DEBUGGER && this.dbg && this.dbg.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n\n if (!this.canvas && sHTMLType == \"canvas\") {\n\n var panel = this;\n var fPanel = false;\n\n if (BACKTRACK && sBinding == \"btpanel\") {\n this.fBackTrack = fPanel = true;\n }\n\n if (fPanel) {\n this.canvas = /** @type {HTMLCanvasElement} */ (control);\n this.context = /** @type {CanvasRenderingContext2D} */ (this.canvas.getContext(\"2d\"));\n\n /*\n * Employ the same gross onresize() hack for IE9/IE10 that we had to use for the Video canvas\n */\n if (Web.getUserAgent().indexOf(\"MSIE\") >= 0) {\n this.canvas.onresize = function(canvas, cx, cy) {\n return function onResizeVideo() {\n canvas.style.height = (((canvas.clientWidth * cy) / cx) | 0) + \"px\";\n };\n }(this.canvas, this.canvas.width, this.canvas.height);\n this.canvas.onresize(null);\n }\n\n this.xMem = this.yMem = 0;\n this.cxMem = ((this.canvas.width * Panel.LIVEMEM.CX) / Panel.LIVECANVAS.CX) | 0;\n this.cyMem = this.canvas.height;\n\n this.xReg = this.cxMem;\n this.yReg = 0;\n this.cxReg = this.canvas.width - this.cxMem;\n this.cyReg = this.canvas.height;\n\n this.xDump = this.xReg;\n this.yDump = ((this.canvas.height * (Panel.LIVEREGS.CY - Panel.LIVEDUMP.CY)) / Panel.LIVECANVAS.CY) | 0;\n this.cxDump = this.cxReg;\n this.cyDump = ((this.canvas.height * Panel.LIVEDUMP.CY) / Panel.LIVECANVAS.CY) | 0;\n\n this.canvasLiveMem = document.createElement(\"canvas\");\n this.canvasLiveMem.width = Panel.LIVEMEM.CX;\n this.canvasLiveMem.height = Panel.LIVEMEM.CY;\n this.contextLiveMem = this.canvasLiveMem.getContext(\"2d\");\n this.imageLiveMem = this.contextLiveMem.createImageData(this.canvasLiveMem.width, this.canvasLiveMem.height);\n\n this.canvasLiveRegs = document.createElement(\"canvas\");\n this.canvasLiveRegs.width = Panel.LIVEREGS.CX;\n this.canvasLiveRegs.height = Panel.LIVEREGS.CY;\n this.contextLiveRegs = this.canvasLiveRegs.getContext(\"2d\");\n\n this.canvas.addEventListener(\n 'mousemove',\n function onMouseMove(event) {\n panel.moveMouse(event);\n },\n false // we'll specify false for the 'useCapture' parameter for now...\n );\n this.canvas.addEventListener(\n 'mousedown',\n function onMouseDown(event) {\n panel.clickMouse(event, true);\n },\n false // we'll specify false for the 'useCapture' parameter for now...\n );\n this.canvas.addEventListener(\n 'mouseup',\n function onMouseUp(event) {\n panel.clickMouse(event, false);\n },\n false // we'll specify false for the 'useCapture' parameter for now...\n );\n\n this.fRedraw = true;\n this.startTimer();\n return true;\n }\n }\n return super.setBinding(sHTMLType, sBinding, control, sValue);\n }\n\n /**\n * startTimer()\n *\n * This timer replaces the CPU's old dedicated VIDEO_UPDATES_PER_SECOND logic, which periodically called\n * the Computer's updateVideo() function, which in turn called our updateAnimation() function; periodic\n * animation updates are now our own responsibility.\n *\n * @this {Panel}\n */\n startTimer()\n {\n if (this.timer < 0 && this.canvas && this.cpu) {\n var panel = this;\n this.timer = this.cpu.addTimer(this.id, function updateAnimationTimer() {\n panel.updateAnimation();\n }, 1000 / Panel.UPDATES_PER_SECOND);\n }\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {Panel}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) Panel.init();\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Panel}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return true;\n }\n\n /**\n * clickMouse(event, fDown)\n *\n * @this {Panel}\n * @param {Object} event object from a 'mousedown' or 'mouseup' event\n * @param {boolean} fDown\n */\n clickMouse(event, fDown)\n {\n /*\n * event.button is 0 for the LEFT button and 2 for the RIGHT button\n */\n if (!event.button) {\n this.lockMouse = fDown? 0 : -1;\n this.fMouseDown = fDown;\n this.updateMouse(event, fDown);\n }\n }\n\n /**\n * moveMouse(event)\n *\n * @this {Panel}\n * @param {Object} event object from a 'mousemove' event\n */\n moveMouse(event)\n {\n this.updateMouse(event);\n }\n\n /**\n * updateMouse(event, fDown)\n *\n * MouseEvent objects contain, among other things, the following properties:\n *\n * clientX\n * clientY\n *\n * I've selected the above properties because they're widely supported, not because I need\n * client-area coordinates. In fact, layerX and layerY are probably closer to what I really want,\n * but I don't think they're available in all browsers. screenX and screenY would work as well.\n *\n * @this {Panel}\n * @param {Object} event object from a mouse event (specifically, a MouseEvent object)\n * @param {boolean} [fDown] is true or false if this was a click event, otherwise it's just a move event\n */\n updateMouse(event, fDown)\n {\n /*\n * Due to the responsive nature of our pages, the displayed size of the canvas may be smaller than the\n * allocated size, and the coordinates we receive from mouse events are based on the currently displayed size.\n */\n var xScale = Panel.LIVECANVAS.CX / this.canvas.offsetWidth;\n var yScale = Panel.LIVECANVAS.CY / this.canvas.offsetHeight;\n\n var rect = this.canvas.getBoundingClientRect();\n var x = ((event.clientX - rect.left) * xScale) | 0;\n var y = ((event.clientY - rect.top) * yScale) | 0;\n\n if (fDown == null) {\n if (!this.lockMouse) {\n this.lockMouse = Math.abs(this.xMouse - x) > Math.abs(this.yMouse - y)? 1 : 2;\n }\n if (this.lockMouse == 1) {\n y = this.yMouse;\n } else if (this.lockMouse == 2) {\n x = this.xMouse;\n }\n }\n\n this.xMouse = x;\n this.yMouse = y;\n\n if (MAXDEBUG) this.log(\"Panel.moveMouse(\" + x + \",\" + y + \")\");\n\n if (x >= 0 && x < Panel.LIVECANVAS.CX && y >= 0 && y < Panel.LIVECANVAS.CY) {\n /*\n * Convert the mouse position into the corresponding memory address, assuming it's over the live memory area\n */\n var addr = this.findAddress(x, y);\n if (addr !== X86.ADDR_INVALID) {\n addr &= ~0xf;\n if (addr != this.addrDumpLast) {\n this.dumpMemory(addr, true);\n this.addrDumpLast = addr;\n }\n }\n }\n }\n\n /**\n * findAddress(x, y)\n *\n * @this {Panel}\n * @param {number} x\n * @param {number} y\n * @return {number} address corresponding to (x,y) canvas coordinates, or ADDR_INVALID if none\n */\n findAddress(x, y)\n {\n if (x < Panel.LIVEMEM.CX && this.busInfo && this.busInfo.aRects) {\n var i, rect;\n for (i = 0; i < this.busInfo.aRects.length; i++) {\n rect = this.busInfo.aRects[i];\n if (rect.contains(x, y)) {\n x -= rect.x;\n y -= rect.y;\n var region = this.busInfo.aRegions[i];\n var iBlock = Usr.getBitField(/** @type {BitField} */ (Bus.BlockInfo.num), this.busInfo.aBlocks[region.iBlock]);\n var addr = iBlock * this.bus.nBlockSize;\n var addrLimit = (iBlock + region.cBlocks) * this.bus.nBlockSize - 1;\n\n /*\n * If you want memory to be arranged \"vertically\" instead of \"horizontally\", do this:\n *\n * if (x > 0) addr += rect.cy * (x - 1) * this.ratioMemoryToPixels;\n * addr += (y * this.ratioMemoryToPixels);\n */\n if (y > 0) addr += rect.cx * (y - 1) * this.ratioMemoryToPixels;\n addr += (x * this.ratioMemoryToPixels);\n\n addr |= 0;\n if (addr > addrLimit) addr = addrLimit;\n if (MAXDEBUG) this.log(\"Panel.findAddress(\" + x + \",\" + y + \") found type \" + Memory.TYPE.NAMES[region.type] + \", address %\" + Str.toHex(addr));\n return addr;\n }\n }\n }\n return X86.ADDR_INVALID;\n }\n\n /**\n * updateAnimation()\n *\n * If the given Control Panel contains a canvas requiring animation (eg, \"btpanel\"), then this is where that happens.\n *\n * @this {Panel}\n */\n updateAnimation()\n {\n if (this.fRedraw) {\n\n this.initPen(10, Panel.LIVECANVAS.FONT.CY, this.canvasLiveMem, this.contextLiveMem, this.canvas.style.color);\n\n if (this.fBackTrack) {\n if (DEBUG) this.log(\"begin scanMemory()\");\n this.busInfo = this.bus.scanMemory(this.busInfo);\n /*\n * Calculate the pixel-to-memory-address ratio\n */\n this.ratioMemoryToPixels = (this.busInfo.cBlocks * this.bus.nBlockSize) / (Panel.LIVEMEM.CX * Panel.LIVEMEM.CY);\n /*\n * Update the BusInfo object with region information (cRegions and aRegions); return true if region\n * information has changed since the last call.\n */\n if (this.findRegions()) {\n /*\n * For each region, I choose a slice of the LiveMem canvas and record the corresponding rectangle\n * within an aRects array (parallel to the aRegions array) in the BusInfo object.\n *\n * I don't need a sophisticated Treemap algorithm, because at this level, the data is not hierarchical.\n * subDivide() makes a simple horizontal or vertical slicing decision based on the ratio of region blocks\n * to remaining blocks.\n */\n var i, rect;\n var rectAvail = new Rectangle(0, 0, this.canvasLiveMem.width, this.canvasLiveMem.height);\n this.busInfo.aRects = [];\n var cBlocksRemaining = this.busInfo.cBlocks;\n\n for (i = 0; i < this.busInfo.cRegions; i++) {\n var cBlocksRegion = this.busInfo.aRegions[i].cBlocks;\n this.busInfo.aRects.push(rect = rectAvail.subDivide(cBlocksRegion, cBlocksRemaining, !i));\n if (MAXDEBUG) this.log(\"region \" + i + \" rectangle: (\" + rect.x + \",\" + rect.y + \" \" + rect.cx + \",\" + rect.cy + \")\");\n cBlocksRemaining -= cBlocksRegion;\n }\n\n /*\n * Assert that not only did all the specified regions account for all the specified blocks, but also that\n * the series of subDivide() calls exhausted the original rectangle to one of either zero width or zero height.\n */\n\n\n /*\n * Now draw all the rectangles produced by the series of subDivide() calls.\n */\n for (i = 0; i < this.busInfo.aRects.length; i++) {\n var region = this.busInfo.aRegions[i];\n rect = this.busInfo.aRects[i];\n rect.drawWith(this.contextLiveMem, Memory.TYPE.COLORS[region.type]);\n this.centerPen(rect);\n this.centerText(Memory.TYPE.NAMES[region.type] + \" (\" + (((region.cBlocks * this.bus.nBlockSize) / 1024) | 0) + \"Kb)\");\n }\n }\n if (DEBUG) this.log(\"end scanMemory(): total bytes: \" + this.busInfo.cbTotal + \", total blocks: \" + this.busInfo.cBlocks + \", total regions: \" + this.busInfo.cRegions);\n } else {\n this.drawText(\"This space intentionally left blank\");\n }\n this.context.drawImage(this.canvasLiveMem, 0, 0, this.canvasLiveMem.width, this.canvasLiveMem.height, this.xMem, this.yMem, this.cxMem, this.cyMem);\n this.fRedraw = false;\n }\n }\n\n /**\n * updateStatus(fForce)\n *\n * Update function for Panels containing elements with high-frequency display requirements.\n *\n * For older (and slower) DOM-based display elements, those are sill being managed by the CPUX86 component,\n * so it has its own updateStatus() handler.\n *\n * The Computer's updateStatus() handler is currently responsible for calling both our handler and the CPU's handler.\n *\n * @this {Panel}\n * @param {boolean} [fForce] (true will display registers even if the CPU is running and \"live\" registers are not enabled)\n */\n updateStatus(fForce)\n {\n if (this.canvas) this.dumpRegisters();\n }\n\n /**\n * findRegions()\n *\n * This takes the BusInfo object produced by scanMemory() and adds the following:\n *\n * cRegions: number of contiguous memory regions\n * aRegions: array of aBlocks [index, count, type] objects\n *\n * It calls addRegion() for each discrete region (set of contiguous blocks with the same type) that it finds.\n *\n * @this {Panel}\n * @return {boolean} true if current region checksum differed from previous checksum (ie, one or more regions changed)\n */\n findRegions()\n {\n var checksum = 0;\n this.busInfo.cRegions = 0;\n if (!this.busInfo.aRegions) this.busInfo.aRegions = [];\n\n var typeRegion = -1, iBlockRegion = 0, addrRegion = 0, nBlockPrev = -1;\n\n for (var iBlock = 0; iBlock < this.busInfo.cBlocks; iBlock++) {\n var blockInfo = this.busInfo.aBlocks[iBlock];\n var typeBlock = Usr.getBitField(/** @type {BitField} */ (Bus.BlockInfo.type), blockInfo);\n var nBlockCurr = Usr.getBitField(/** @type {BitField} */ (Bus.BlockInfo.num), blockInfo);\n if (typeBlock != typeRegion || nBlockCurr != nBlockPrev + 1) {\n var cBlocks = iBlock - iBlockRegion;\n if (cBlocks) {\n checksum += this.addRegion(addrRegion, iBlockRegion, cBlocks, typeRegion);\n }\n typeRegion = typeBlock;\n iBlockRegion = iBlock;\n addrRegion = nBlockCurr << this.bus.nBlockShift;\n }\n nBlockPrev = nBlockCurr;\n }\n\n checksum += this.addRegion(addrRegion, iBlockRegion, iBlock - iBlockRegion, typeRegion);\n\n var fChanged = (this.busInfo.checksumRegions != checksum);\n this.busInfo.checksumRegions = checksum;\n return fChanged;\n }\n\n /**\n * addRegion(addr, iBlock, cBlocks, type)\n *\n * @this {Panel}\n * @param {number} addr\n * @param {number} iBlock\n * @param {number} cBlocks\n * @param {number} type\n * @return {number} bitfield containing the above values (used for checksum)\n */\n addRegion(addr, iBlock, cBlocks, type)\n {\n if (DEBUG) this.log(\"region \" + this.busInfo.cRegions + \" (addr \" + Str.toHexLong(addr) + \", type \" + Memory.TYPE.NAMES[type] + \") contains \" + cBlocks + \" blocks\");\n this.busInfo.aRegions[this.busInfo.cRegions++] = {iBlock: iBlock, cBlocks: cBlocks, type: type};\n return Usr.initBitFields(Bus.BlockInfo, iBlock, cBlocks, 0, type);\n }\n\n /**\n * dumpRegisters()\n *\n * Updates the live register portion of the panel.\n *\n * @this {Panel}\n */\n dumpRegisters()\n {\n if (this.context && this.canvasLiveRegs && this.contextLiveRegs) {\n\n var cpu = this.cpu;\n var x = 0, y = 0, cx = this.canvasLiveRegs.width, cy = this.canvasLiveRegs.height;\n\n this.contextLiveRegs.fillStyle = Panel.LIVEREGS.COLOR;\n this.contextLiveRegs.fillRect(x, y, cx, cy);\n\n this.initPen(x + 10, y + Panel.LIVECANVAS.FONT.CY, this.canvasLiveRegs, this.contextLiveRegs, this.canvas.style.color);\n this.initCols(3);\n this.drawText(\"CPU\");\n this.drawText(\"Target\");\n this.drawText(\"Current\");\n this.skipLines();\n this.drawText(cpu.model);\n this.drawText(cpu.getSpeedTarget());\n this.drawText(cpu.getSpeedCurrent());\n this.skipLines(2);\n this.initCols(8);\n this.initNumberFormat(16, cpu.model < X86.MODEL_80386? 4 : 8);\n this.drawText(\"AX\", cpu.regEAX, 2);\n this.drawText(\"DS\", cpu.getDS(), 0, 1);\n this.drawText(\"DX\", cpu.regEDX, 2);\n this.drawText(\"SI\", cpu.regESI, 0, 1.5);\n this.drawText(\"BX\", cpu.regEBX, 2);\n this.drawText(\"ES\", cpu.getES(), 0, 1);\n this.drawText(\"CX\", cpu.regECX, 2);\n this.drawText(\"DI\", cpu.regEDI, 0, 1.5);\n this.drawText(\"CS\", cpu.getCS(), 2);\n this.drawText(\"SS\", cpu.getSS(), 0, 1);\n this.drawText(\"IP\", cpu.getIP(), 2);\n this.drawText(\"SP\", cpu.getSP(), 0, 1.5);\n var regPS;\n this.drawText(\"PS\", regPS = cpu.getPS(), 2);\n this.drawText(\"BP\", cpu.regEBP, 0, 1.5);\n if (cpu.model >= X86.MODEL_80386) {\n this.drawText(\"FS\", cpu.getFS(), 2);\n this.drawText(\"CR0\", cpu.regCR0, 0, 1);\n this.drawText(\"GS\", cpu.getGS(), 2);\n this.drawText(\"CR3\", cpu.regCR3, 0, 1.5);\n }\n this.initCols(9);\n this.drawText(\"V\" + ((regPS & X86.PS.OF)? 1 : 0));\n this.drawText(\"D\" + ((regPS & X86.PS.DF)? 1 : 0));\n this.drawText(\"I\" + ((regPS & X86.PS.IF)? 1 : 0));\n this.drawText(\"T\" + ((regPS & X86.PS.TF)? 1 : 0));\n this.drawText(\"S\" + ((regPS & X86.PS.SF)? 1 : 0));\n this.drawText(\"Z\" + ((regPS & X86.PS.ZF)? 1 : 0));\n this.drawText(\"A\" + ((regPS & X86.PS.AF)? 1 : 0));\n this.drawText(\"P\" + ((regPS & X86.PS.PF)? 1 : 0));\n this.drawText(\"C\" + ((regPS & X86.PS.CF)? 1 : 0), 0, 2);\n\n this.dumpMemory(this.addrDumpLast);\n\n this.context.drawImage(this.canvasLiveRegs, x, y, cx, cy, this.xReg, this.yReg, this.cxReg, this.cyReg);\n }\n }\n\n /**\n * dumpMemory(addr, fDraw)\n *\n * @this {Panel}\n * @param {number} addr\n * @param {boolean} [fDraw]\n */\n dumpMemory(addr, fDraw)\n {\n if (this.context && this.canvasLiveRegs && this.contextLiveRegs) {\n\n var x = 0, y = Panel.LIVEREGS.CY - Panel.LIVEDUMP.CY, cx = this.canvasLiveRegs.width, cy = Panel.LIVEDUMP.CY;\n\n this.contextLiveRegs.fillStyle = Panel.LIVEREGS.COLOR;\n this.contextLiveRegs.fillRect(x, y, cx, cy);\n\n this.initPen(x + 10, y + Panel.LIVECANVAS.FONT.CY, this.canvasLiveRegs, this.contextLiveRegs, this.canvas.style.color);\n this.initCols(24);\n if (addr == null) {\n this.drawText(\"Mouse over memory to dump\");\n } else {\n this.drawText(Str.toHexLong(addr), null, 0, 1);\n for (var iLine = 1; iLine <= 16; iLine++) {\n var sChars = \"\";\n for (var iCol = 1; iCol <= 8; iCol++) {\n var b = this.bus.getByteDirect(addr++);\n this.drawText(Str.toHex(b, 2), null, 1);\n sChars += (b >= 32 && b < 128? String.fromCharCode(b) : \".\");\n }\n this.drawText(sChars, null, 0, 1);\n }\n }\n\n if (fDraw) this.context.drawImage(this.canvasLiveRegs, x, y, cx, cy, this.xDump, this.yDump, this.cxDump, this.cyDump);\n }\n }\n\n /**\n * initPen(xLeft, yTop, canvas, context, sColor, cyFont, sFontFace)\n *\n * @this {Panel}\n * @param {number} xLeft\n * @param {number} yTop\n * @param {HTMLCanvasElement} [canvas]\n * @param {Object} [context]\n * @param {string} [sColor]\n * @param {number} [cyFont]\n * @param {string} [sFontFace]\n */\n initPen(xLeft, yTop, canvas, context, sColor, cyFont, sFontFace)\n {\n this.setPen(this.xLeftMargin = xLeft, yTop);\n this.heightText = this.heightDefault = cyFont || Panel.LIVECANVAS.FONT.CY;\n if (!sFontFace) sFontFace = this.fontDefault || (this.heightDefault + \"px \" + Panel.LIVECANVAS.FONT.FACE);\n this.fontText = this.fontDefault = sFontFace;\n if (canvas) {\n this.canvasText = canvas;\n }\n if (context) {\n this.contextText = context;\n this.colorText = sColor || \"white\";\n }\n }\n\n /**\n * setPen(x, y)\n *\n * @this {Panel}\n * @param {number} x\n * @param {number} y\n */\n setPen(x, y)\n {\n this.xText = x;\n this.yText = y;\n }\n\n /**\n * centerPen(rect)\n *\n * @this {Panel}\n * @param {Rectangle} rect\n */\n centerPen(rect)\n {\n this.fontText = this.fontDefault;\n this.heightText = this.heightDefault;\n var x = rect.x + (rect.cx >> 1);\n var y = rect.y + (rect.cy >> 1);\n var maxText = rect.cy;\n if (rect.cx < rect.cy) {\n maxText = rect.cx;\n this.fVerticalText = true;\n this.contextText.save();\n this.contextText.translate(x, y);\n this.contextText.rotate(-Math.PI/2);\n x = y = 0;\n }\n if (maxText < this.heightText) {\n this.heightText = maxText;\n this.fontText = this.heightText + \"px \" + Panel.LIVECANVAS.FONT.FACE;\n }\n this.setPen(x, y);\n }\n\n /**\n * initCols(nCols)\n *\n * @this {Panel}\n * @param {number} nCols\n */\n initCols(nCols)\n {\n this.cxColumn = (this.canvasText.width / nCols) | 0;\n }\n\n /**\n * skipCols(nCols)\n *\n * @this {Panel}\n * @param {number} nCols\n */\n skipCols(nCols)\n {\n this.xText += this.cxColumn * nCols;\n }\n\n /**\n * skipLines(nLines)\n *\n * @this {Panel}\n * @param {number} [nLines]\n */\n skipLines(nLines)\n {\n this.xText = this.xLeftMargin;\n this.yText += (this.heightText + 2) * (nLines || 1);\n }\n\n /**\n * initNumberFormat(nBase, nDigits)\n *\n * @this {Panel}\n * @param {number} nBase\n * @param {number} nDigits\n */\n initNumberFormat(nBase, nDigits)\n {\n this.nDefaultBase = nBase;\n this.nDefaultDigits = nDigits;\n }\n\n /**\n * drawText(sText)\n *\n * @this {Panel}\n * @param {string} sText\n * @param {number|null} [nValue]\n * @param {number} [nColsSkip]\n * @param {number} [nLinesSkip]\n */\n drawText(sText, nValue, nColsSkip, nLinesSkip)\n {\n this.contextText.font = this.fontText;\n this.contextText.fillStyle = this.colorText;\n this.contextText.fillText(sText, this.xText, this.yText);\n this.xText += this.cxColumn;\n if (nValue != null) {\n var sValue;\n if (this.nDefaultBase != 16) {\n sValue = nValue.toString();\n } else {\n sValue = this.nDefaultDigits < 8? \"0x\" : \"\";\n sValue += Str.toHex(nValue, this.nDefaultDigits);\n }\n this.contextText.fillText(sValue, this.xText, this.yText);\n this.xText += this.cxColumn;\n }\n if (nColsSkip) this.skipCols(nColsSkip);\n if (nLinesSkip) this.skipLines(nLinesSkip);\n }\n\n /**\n * centerText(sText)\n *\n * To center text within a given Rectangle:\n *\n * centerPen(rect)\n * centerText(sText)\n *\n * centerPen() sets xLeft and yTop to the center of the specified rectangle, and centerText() calculates\n * the width of the text, adjusting the horizontal centering by its width and the vertical centering by the\n * default font height. Then it calls drawText().\n *\n * @this {Panel}\n * @param {string} sText\n */\n centerText(sText)\n {\n this.contextText.font = this.fontText;\n var tm = this.contextText.measureText(sText);\n this.xText -= tm.width >> 1;\n this.yText += (this.heightText >> 1) - 2;\n this.drawText(sText);\n if (this.fVerticalText) {\n this.contextText.restore();\n this.fVerticalText = false;\n }\n }\n\n /**\n * Panel.init()\n *\n * This function operates on every HTML element of class \"panel\", extracting the\n * JSON-encoded parameters for the Panel constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Panel component, and then binding\n * any associated HTML controls to the new component.\n *\n * NOTE: Unlike most other component init() functions, this one is designed to be\n * called multiple times: once at load time, so that we can bind our print()\n * function to the panel's output control ASAP, and again when the Computer component\n * is verifying that all components are ready and invoking their powerUp() functions.\n *\n * Our powerUp() method gives us a second opportunity to notify any components that\n * that might care (eg, CPU, Keyboard, and Debugger) that we have some controls they\n * might want to use.\n */\n static init()\n {\n var fReady = false;\n var aePanels = Component.getElementsByClass(document, PCX86.APPCLASS, \"panel\");\n for (var iPanel=0; iPanel < aePanels.length; iPanel++) {\n var ePanel = aePanels[iPanel];\n var parmsPanel = Component.getComponentParms(ePanel);\n var panel = Component.getComponentByID(parmsPanel['id']);\n if (!panel) {\n fReady = true;\n panel = new Panel(parmsPanel);\n }\n Component.bindComponentControls(panel, ePanel, PCX86.APPCLASS);\n if (fReady) panel.setReady();\n }\n }\n}\n\n/*\n * The \"Live\" canvases that we create internally have the following fixed dimensions, to make drawing\n * simpler. We then render, via drawImage(), these canvases onto the supplied canvas, which will automatically\n * stretch the live images to fit.\n */\nPanel.LIVECANVAS = {\n CX: 1280,\n CY: 720,\n FONT: {\n CY: 18,\n FACE: \"Monaco, Lucida Console, Courier New\"\n }\n};\n\nPanel.LIVEMEM = {\n CX: (Panel.LIVECANVAS.CX * 3) >> 2,\n CY: (Panel.LIVECANVAS.CY)\n};\n\nPanel.LIVEREGS = {\n CX: (Panel.LIVECANVAS.CX - Panel.LIVEMEM.CX),\n CY: (Panel.LIVECANVAS.CY),\n COLOR: \"black\"\n};\n\nPanel.LIVEDUMP = {\n CX: (Panel.LIVECANVAS.CX - Panel.LIVEMEM.CX),\n CY: (Panel.LIVECANVAS.CY >> 1)\n};\n\n/*\n * findRegions() records block numbers in bits 0-14, a BackTrack \"mod\" bit in bit 15, and the block type at bit 16.\n */\nPanel.REGION = {\n MASK: 0x7fff,\n BTMOD_SHIFT: 15,\n TYPE_SHIFT: 16\n};\n\nPanel.UPDATES_PER_SECOND = 10;\n\n/*\n * Initialize every Panel module on the page.\n */\nWeb.onInit(Panel.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/bus.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Think of this Controller class definition as an interface definition, implemented by the Video Card\n * class and the RAM CompaqController class.\n * \n * class Controller\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass Controller {\n /**\n * getMemoryAccess()\n *\n * @this {Controller}\n * @return {Array.<function()>}\n */\n getMemoryAccess()\n {\n return [];\n }\n \n /**\n * getMemoryBuffer(addr)\n *\n * @this {Controller}\n * @param {number} addr\n * @return {Array} containing the buffer (and an offset within that buffer)\n */\n getMemoryBuffer(addr)\n {\n return [];\n }\n}\n\n/**\n * class Bus\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass Bus extends Component {\n /**\n * Bus(cpu, dbg)\n *\n * The Bus component manages physical memory and I/O address spaces.\n *\n * The Bus component has no UI elements, so it does not require an init() handler,\n * but it still inherits from the Component class and must be allocated like any\n * other device component. It's currently allocated by the Computer's init() handler,\n * which then calls the initBus() method of all the other components.\n *\n * When initMemory() initializes the entire address space, it also passes aMemBlocks\n * to the CPU object, so that the CPU can perform its own address-to-block calculations\n * (essential, for example, when the CPU enables paging).\n *\n * For memory beyond the simple needs of the ROM and RAM components (ie, memory-mapped\n * devices), the address space must still be allocated through the Bus component via\n * addMemory(). If the component needs something more than simple read/write storage,\n * it must provide a controller with getMemoryBuffer() and getMemoryAccess() methods.\n *\n * All port (I/O) operations are defined by external handlers; they register with us,\n * and we manage those registrations and provide support for I/O breakpoints, but the\n * only default I/O behavior we provide is ignoring writes to any unregistered output\n * ports and returning 0xff from any unregistered input ports.\n *\n * @this {Bus}\n * @param {Object} parmsBus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n constructor(parmsBus, cpu, dbg)\n {\n super(\"Bus\", parmsBus);\n\n this.cpu = cpu;\n this.dbg = dbg;\n\n this.nBusWidth = parmsBus['busWidth'] || 20;\n\n /*\n * Compute all Bus memory block parameters, based on the width of the bus.\n *\n * Regarding blockTotal, we want to avoid using block overflow expressions like:\n *\n * iBlock < this.nBlockTotal? iBlock : 0\n *\n * As long as we know that blockTotal is a power of two (eg, 256 or 0x100, in the case of\n * nBusWidth == 20 and blockSize == 4096), we can define blockMask as (blockTotal - 1) and\n * rewrite the previous expression as:\n *\n * iBlock & this.nBlockMask\n *\n * Similarly, we mask addresses with busMask to enforce \"A20 wrap\" on 20-bit buses.\n * For larger buses, A20 wrap can be simulated by either clearing bit 20 of busMask or by\n * changing all the block entries for the 2nd megabyte to match those in the 1st megabyte.\n *\n * Bus Property Old hard-coded values (when nBusWidth was always 20)\n * ------------ ----------------------------------------------------\n * this.nBusLimit 0xfffff\n * this.nBusMask [same as busLimit]\n * this.nBlockSize 4096\n * this.nBlockLen (this.nBlockSize >> 2)\n * this.nBlockShift 12\n * this.nBlockLimit 0xfff\n * this.nBlockTotal ((this.nBusLimit + this.nBlockSize) / this.nBlockSize) | 0\n * this.nBlockMask (this.nBlockTotal - 1) [ie, 0xff]\n *\n * Note that we choose a nBlockShift value (and thus a physical memory block size) based on \"buswidth\":\n *\n * Bus Width Block Shift Block Size\n * --------- ----------- ----------\n * 20 bits (1Mb address space): 12 4Kb (256 maximum blocks)\n * 24 bits (16Mb address space): 14 16Kb (1K maximum blocks)\n * 32 bits (4Gb address space); 15 32Kb (128K maximum blocks)\n *\n * The coarser block granularities (ie, 16Kb and 32Kb) may cause problems for certain RAM and/or ROM\n * allocations that are contiguous but are allocated out of order, or that have different controller\n * requirements. Your choices, for the moment, are either to ensure the allocations are performed in\n * order, or to choose smaller nBlockShift values (at the expense of a generating a larger block array).\n *\n * Note that if PAGEBLOCKS is set, then for a bus width of 32 bits, the block size is fixed at 4Kb.\n */\n this.addrTotal = Math.pow(2, this.nBusWidth);\n this.nBusLimit = this.nBusMask = (this.addrTotal - 1) | 0;\n this.nBlockShift = (PAGEBLOCKS && this.nBusWidth == 32 || this.nBusWidth <= 20)? 12 : (this.nBusWidth <= 24? 14 : 15);\n this.nBlockSize = 1 << this.nBlockShift;\n this.nBlockLen = this.nBlockSize >> 2;\n this.nBlockLimit = this.nBlockSize - 1;\n this.nBlockTotal = (this.addrTotal / this.nBlockSize) | 0;\n this.nBlockMask = this.nBlockTotal - 1;\n\n\n /*\n * Lists of I/O notification functions: aPortInputNotify and aPortOutputNotify are arrays, indexed by\n * port, of sub-arrays which contain:\n *\n * [0]: registered function to call for every I/O access\n *\n * The registered function is called with the port address, and if the access was triggered by the CPU,\n * the linear instruction pointer (LIP) at the point of access.\n *\n * WARNING: Unlike the (old) read and write memory notification functions, these support only one\n * pair of input/output functions per port. A more sophisticated architecture could support a list\n * of chained functions across multiple components, but I doubt that will be necessary here.\n *\n * UPDATE: The Debugger now piggy-backs on these arrays to indicate ports for which it wants notification\n * of I/O. In those cases, the registered component/function elements may or may not be set, but the\n * following additional element will be set:\n *\n * [1]: true to break on I/O, false to ignore I/O\n *\n * The false case is important if fPortInputBreakAll and/or fPortOutputBreakAll is set, because it allows the\n * Debugger to selectively ignore specific ports.\n */\n this.aPortInputNotify = [];\n this.aPortOutputNotify = [];\n this.fPortInputBreakAll = this.fPortOutputBreakAll = false;\n\n /*\n * By default, all I/O ports are 1 byte wide; ports that are wider must add themselves to one or both of\n * these lists, using addPortInputWidth() and/or addPortOutputWidth().\n */\n this.aPortInputWidth = [];\n this.aPortOutputWidth = [];\n\n /*\n * Allocate empty Memory blocks to span the entire physical address space.\n */\n this.initMemory();\n\n if (BACKTRACK) {\n this.abtObjects = [];\n this.cbtDeletions = 0;\n this.ibtLastAlloc = -1;\n this.ibtLastDelete = 0;\n }\n\n this.setReady();\n }\n\n /**\n * initMemory()\n *\n * Allocate enough (empty) Memory blocks to span the entire physical address space.\n *\n * @this {Bus}\n */\n initMemory()\n {\n var block = new Memory();\n block.copyBreakpoints(this.dbg);\n this.aMemBlocks = new Array(this.nBlockTotal);\n for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {\n this.aMemBlocks[iBlock] = block;\n }\n this.cpu.initMemory(this.aMemBlocks, this.nBlockShift);\n this.cpu.setAddressMask(this.nBusMask);\n }\n\n /**\n * reset()\n *\n * @this {Bus}\n */\n reset()\n {\n this.setA20(true);\n if (BACKTRACK) this.ibtLastDelete = 0;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * We don't need a powerDown() handler, because for largely historical reasons, our state (including the A20 state)\n * is saved by saveMemory(), which called by the CPU.\n *\n * However, we do need a powerUp() handler, because on resumable machines, the Computer's onReset() function calls\n * everyone's powerUp() handler rather than their reset() handler.\n *\n * TODO: Perhaps Computer should be smarter: if there's no powerUp() handler, then fallback to the reset() handler.\n * In that case, however, we'd either need to remove the powerUp() stub in Component, or detect the existence of the stub.\n *\n * @this {Bus}\n * @param {Object|null} data (always null because we supply no powerDown() handler)\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) this.reset();\n return true;\n }\n\n /**\n * addMemory(addr, size, type, controller)\n *\n * Adds new Memory blocks to the specified address range. Any Memory blocks previously\n * added to that range must first be removed via removeMemory(); otherwise, you'll get\n * an allocation conflict error. This helps prevent address calculation errors, redundant\n * allocations, etc.\n *\n * We've relaxed some of the original requirements (ie, that addresses must start at a\n * block-granular address, or that sizes must be equal to exactly one or more blocks),\n * because machines with large block sizes can make it impossible to load certain ROMs at\n * their required addresses. Every allocation still allocates a whole number of blocks.\n *\n * Even so, Bus memory management does NOT provide a general-purpose heap. Most memory\n * allocations occur during machine initialization and never change. In particular, there\n * is NO support for removing partial-block allocations. Typically, the only region that\n * changes post-initialization is the Video buffer, and only in the EGA/VGA implementation.\n *\n * Each Memory block keeps track of a start address (addr) and length (used), indicating\n * the used space within the block; any free space that precedes or follows that used space\n * can be allocated later, by simply extending the beginning or ending of the previously used\n * space. However, any holes that might have existed between the original allocation and an\n * extension are subsumed by the extension.\n *\n * @this {Bus}\n * @param {number} addr is the starting physical address of the request\n * @param {number} size of the request, in bytes\n * @param {number} type is one of the Memory.TYPE constants\n * @param {Controller} [controller] is an optional memory controller component\n * @return {boolean} true if successful, false if not\n */\n addMemory(addr, size, type, controller)\n {\n var addrNext = addr;\n var sizeLeft = size;\n var iBlock = addrNext >>> this.nBlockShift;\n\n while (sizeLeft > 0 && iBlock < this.aMemBlocks.length) {\n\n var block = this.aMemBlocks[iBlock];\n var addrBlock = iBlock * this.nBlockSize;\n var sizeBlock = this.nBlockSize - (addrNext - addrBlock);\n if (sizeBlock > sizeLeft) sizeBlock = sizeLeft;\n\n if (block && block.size) {\n if (block.type == type && block.controller == controller) {\n /*\n * Where there is already a similar block with a non-zero size, we allow the allocation only if:\n *\n * 1) addrNext + sizeLeft <= block.addr (the request precedes the used portion of the current block), or\n * 2) addrNext >= block.addr + block.used (the request follows the used portion of the current block)\n */\n if (addrNext + sizeLeft <= block.addr) {\n block.used += (block.addr - addrNext);\n block.addr = addrNext;\n return true;\n }\n if (addrNext >= block.addr + block.used) {\n var sizeAvail = block.size - (addrNext - addrBlock);\n if (sizeAvail > sizeLeft) sizeAvail = sizeLeft;\n block.used = addrNext - block.addr + sizeAvail;\n addrNext = addrBlock + this.nBlockSize;\n sizeLeft -= sizeAvail;\n iBlock++;\n continue;\n }\n }\n return this.reportError(Bus.ERROR.ADD_MEM_INUSE, addrNext, sizeLeft);\n }\n\n var blockNew = new Memory(addrNext, sizeBlock, this.nBlockSize, type, controller);\n blockNew.copyBreakpoints(this.dbg, block);\n this.aMemBlocks[iBlock++] = blockNew;\n\n addrNext = addrBlock + this.nBlockSize;\n sizeLeft -= sizeBlock;\n }\n if (sizeLeft <= 0) {\n /*\n * If all addMemory() calls happened ONLY during device initialization, the following code would not\n * be necessary; unfortunately, the Video component can add and remove physical memory blocks during video\n * mode changes, so we have to kick out any PAGED blocks that could have references to those physical memory\n * blocks. If paging isn't enabled (or supported by the current the CPU), this call has no effect.\n *\n * We could handle this case with a little more, um, precision, but Video mode changes aren't frequent enough\n * to warrant it.\n */\n this.cpu.flushPageBlocks();\n if (!this.cpu.isRunning()) { // allocation messages at \"run time\" are bit too much\n var kb = (size / 1024)|0;\n var sb = kb? (kb + \"Kb \") : (size + \" bytes \");\n this.status(sb + Memory.TYPE.NAMES[type] + \" at \" + Str.toHex(addr));\n }\n return true;\n }\n return this.reportError(Bus.ERROR.ADD_MEM_BADRANGE, addr, size);\n }\n\n /**\n * cleanMemory(addr, size, fNoScrub)\n *\n * @this {Bus}\n * @param {number} addr\n * @param {number} size\n * @param {boolean} [fNoScrub] (by default, all blocks are \"scrubbed\" in the process)\n * @return {boolean} (true if all blocks were clean, false if dirty)\n */\n cleanMemory(addr, size, fNoScrub)\n {\n var fClean = true;\n var iBlock = addr >>> this.nBlockShift;\n var sizeBlock = this.nBlockSize - (addr & this.nBlockLimit);\n while (size > 0 && iBlock < this.aMemBlocks.length) {\n if (this.aMemBlocks[iBlock].fDirty) {\n if (!fNoScrub) {\n this.aMemBlocks[iBlock].fDirty = false;\n this.aMemBlocks[iBlock].fDirtyEver = true;\n }\n fClean = false;\n }\n size -= sizeBlock;\n sizeBlock = this.nBlockSize;\n iBlock++;\n }\n return fClean;\n }\n\n /**\n * scanMemory(info, addr, size)\n *\n * Returns a BusInfo object for the specified address range.\n *\n * @this {Bus}\n * @param {Object} [info] previous BusInfo, if any\n * @param {number} [addr] starting address of range (0 if none provided)\n * @param {number} [size] size of range, in bytes (up to end of address space if none provided)\n * @return {Object} updated info (or new info if no previous info provided)\n */\n scanMemory(info, addr, size)\n {\n if (addr == null) addr = 0;\n if (size == null) size = (this.addrTotal - addr) | 0;\n if (info == null) info = {cbTotal: 0, cBlocks: 0, aBlocks: []};\n\n var iBlock = addr >>> this.nBlockShift;\n var iBlockMax = ((addr + size - 1) >>> this.nBlockShift);\n\n info.cbTotal = 0;\n info.cBlocks = 0;\n while (iBlock <= iBlockMax) {\n var block = this.aMemBlocks[iBlock];\n info.cbTotal += block.size;\n if (block.size) {\n var btmod = (BACKTRACK && block.modBackTrack(false)? 1 : 0);\n info.aBlocks.push(Usr.initBitFields(Bus.BlockInfo, iBlock, 0, btmod, block.type));\n info.cBlocks++\n }\n iBlock++;\n }\n return info;\n }\n\n /**\n * getA20()\n *\n * @this {Bus}\n * @return {boolean} true if enabled, false if disabled\n */\n getA20()\n {\n return !this.aBlocks2Mb && this.nBusLimit == this.nBusMask;\n }\n\n /**\n * setA20(fEnable)\n *\n * On 32-bit bus machines, I've adopted the approach that COMPAQ took with DeskPro 386 machines,\n * which is to map the 1st Mb to the 2nd Mb whenever A20 is disabled, rather than blindly masking\n * the A20 address bit from all addresses; in fact, this is what the DeskPro 386 ROM BIOS requires.\n *\n * For 24-bit bus machines, we take the same approach that most if not all 80286 systems took, which\n * is simply masking the A20 address bit. A lot of 32-bit machines probably took the same approach.\n *\n * TODO: On machines with a 32-bit bus, look into whether we can eliminate address masking altogether,\n * which seems feasible, provided all incoming addresses are already pre-truncated to 32 bits. Also,\n * confirm that DeskPro 386 machines mapped the ENTIRE 1st Mb to the 2nd, and not simply the first 64Kb,\n * which is technically all that 8086 address wrap-around compatibility would require.\n *\n * @this {Bus}\n * @param {boolean} fEnable is true to enable A20 (default), false to disable\n */\n setA20(fEnable)\n {\n if (this.nBusWidth == 32) {\n if (fEnable) {\n if (this.aBlocks2Mb) {\n this.setMemoryBlocks(0x100000, 0x100000, this.aBlocks2Mb);\n this.aBlocks2Mb = null;\n }\n } else {\n if (!this.aBlocks2Mb) {\n this.aBlocks2Mb = this.getMemoryBlocks(0x100000, 0x100000);\n this.setMemoryBlocks(0x100000, 0x100000, this.getMemoryBlocks(0x0, 0x100000));\n }\n }\n }\n else if (this.nBusWidth > 20) {\n var addrMask = (this.nBusMask & ~0x100000) | (fEnable? 0x100000 : 0);\n if (addrMask != this.nBusMask) {\n this.nBusMask = addrMask;\n if (this.cpu) this.cpu.setAddressMask(addrMask);\n }\n }\n }\n\n /**\n * getWidth()\n *\n * @this {Bus}\n * @return {number}\n */\n getWidth()\n {\n return this.nBusWidth;\n }\n\n /**\n * setMemoryAccess(addr, size, afn, fQuiet)\n *\n * Updates the access functions in every block of the specified address range. Since the only components\n * that should be dynamically modifying the memory access functions are those that use addMemory() with a custom\n * memory controller, we require that the block(s) being updated do in fact have a controller.\n *\n * @this {Bus}\n * @param {number} addr\n * @param {number} size\n * @param {Array.<function()>} [afn]\n * @param {boolean} [fQuiet] (true if any error should be quietly logged)\n * @return {boolean} true if successful, false if not\n */\n setMemoryAccess(addr, size, afn, fQuiet)\n {\n if (!(addr & this.nBlockLimit) && size && !(size & this.nBlockLimit)) {\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0) {\n var block = this.aMemBlocks[iBlock];\n if (!block.controller) {\n return this.reportError(Bus.ERROR.SET_MEM_NOCTRL, addr, size, fQuiet);\n }\n block.setAccess(afn, true);\n size -= this.nBlockSize;\n iBlock++;\n }\n return true;\n }\n return this.reportError(Bus.ERROR.SET_MEM_BADRANGE, addr, size);\n }\n\n /**\n * removeMemory(addr, size)\n *\n * Replaces every block in the specified address range with empty Memory blocks that ignore all reads/writes.\n *\n * TODO: Update the removeMemory() interface to reflect the relaxed requirements of the addMemory() interface.\n *\n * @this {Bus}\n * @param {number} addr\n * @param {number} size\n * @return {boolean} true if successful, false if not\n */\n removeMemory(addr, size)\n {\n if (!(addr & this.nBlockLimit) && size && !(size & this.nBlockLimit)) {\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0) {\n var blockOld = this.aMemBlocks[iBlock];\n var blockNew = new Memory(addr);\n blockNew.copyBreakpoints(this.dbg, blockOld);\n this.aMemBlocks[iBlock++] = blockNew;\n addr = iBlock * this.nBlockSize;\n size -= this.nBlockSize;\n }\n /*\n * If all removeMemory() calls happened ONLY during device initialization, the following code would not\n * be necessary; unfortunately, the Video component can add and remove physical memory blocks during video\n * mode changes, so we have to kick out any PAGED blocks that could have references to those physical memory\n * blocks. If paging isn't enabled (or supported by the current the CPU), this call has no effect.\n *\n * We could handle this case with a little more, um, precision, but Video mode changes aren't frequent enough\n * to warrant it.\n */\n this.cpu.flushPageBlocks();\n return true;\n }\n return this.reportError(Bus.ERROR.REM_MEM_BADRANGE, addr, size);\n }\n\n /**\n * getMemoryBlocks(addr, size)\n *\n * @this {Bus}\n * @param {number} addr is the starting physical address\n * @param {number} size of the request, in bytes\n * @return {Array} of Memory blocks\n */\n getMemoryBlocks(addr, size)\n {\n var aBlocks = [];\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0 && iBlock < this.aMemBlocks.length) {\n aBlocks.push(this.aMemBlocks[iBlock++]);\n size -= this.nBlockSize;\n }\n return aBlocks;\n }\n\n /**\n * setMemoryBlocks(addr, size, aBlocks, type)\n *\n * If no type is specified, then specified address range uses all the provided blocks as-is;\n * this form of setMemoryBlocks() is used for complete physical aliases.\n *\n * Otherwise, new blocks are allocated with the specified type; the underlying memory from the\n * provided blocks is still used, but the new blocks may have different access to that memory.\n *\n * @this {Bus}\n * @param {number} addr is the starting physical address\n * @param {number} size of the request, in bytes\n * @param {Array} aBlocks as returned by getMemoryBlocks()\n * @param {number} [type] is one of the Memory.TYPE constants\n */\n setMemoryBlocks(addr, size, aBlocks, type)\n {\n var i = 0;\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0 && iBlock < this.aMemBlocks.length) {\n var block = aBlocks[i++];\n\n if (!block) break;\n if (type !== undefined) {\n var blockNew = new Memory(addr);\n blockNew.clone(block, type, this.dbg);\n block = blockNew;\n }\n this.aMemBlocks[iBlock++] = block;\n size -= this.nBlockSize;\n }\n }\n\n /**\n * getByte(addr)\n *\n * For physical addresses only; for linear addresses, use cpu.getByte().\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @return {number} byte (8-bit) value at that address\n */\n getByte(addr)\n {\n return this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].readByte(addr & this.nBlockLimit, addr);\n }\n\n /**\n * getByteDirect(addr)\n *\n * This is useful for the Debugger and other components that want to bypass getByte() breakpoint detection.\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @return {number} byte (8-bit) value at that address\n */\n getByteDirect(addr)\n {\n return this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].readByteDirect(addr & this.nBlockLimit, addr);\n }\n\n /**\n * getShort(addr)\n *\n * For physical addresses only; for linear addresses, use cpu.getShort().\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @return {number} word (16-bit) value at that address\n */\n getShort(addr)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off != this.nBlockLimit) {\n return this.aMemBlocks[iBlock].readShort(off, addr);\n }\n return this.aMemBlocks[iBlock++].readByte(off, addr) | (this.aMemBlocks[iBlock & this.nBlockMask].readByte(0, addr + 1) << 8);\n }\n\n /**\n * getShortDirect(addr)\n *\n * This is useful for the Debugger and other components that want to bypass getShort() breakpoint detection.\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @return {number} word (16-bit) value at that address\n */\n getShortDirect(addr)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off != this.nBlockLimit) {\n return this.aMemBlocks[iBlock].readShortDirect(off, addr);\n }\n return this.aMemBlocks[iBlock++].readByteDirect(off, addr) | (this.aMemBlocks[iBlock & this.nBlockMask].readByteDirect(0, addr + 1) << 8);\n }\n\n /**\n * getLong(addr)\n *\n * For physical addresses only; for linear addresses, use cpu.getLong().\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @return {number} long (32-bit) value at that address\n */\n getLong(addr)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off < this.nBlockLimit - 2) {\n return this.aMemBlocks[iBlock].readLong(off, addr);\n }\n /*\n * I think the previous version of this function tried to be too clever (ie, reading the last\n * long in the current block and the first long in the next block and masking/combining the results),\n * which may have also created some undesirable side-effects for custom memory controllers.\n * This simpler (and probably more reliable) approach is to simply read the long as individual bytes.\n */\n var l = 0;\n var cb = 4, nShift = 0;\n var cbBlock = 4 - (off & 0x3); // (off & 0x3) will be 1, 2 or 3, so cbBlock will be 3, 2, or 1\n while (cb--) {\n l |= (this.aMemBlocks[iBlock].readByte(off++, addr++) << nShift);\n if (!--cbBlock) {\n iBlock = (iBlock + 1) & this.nBlockMask;\n off = 0;\n }\n nShift += 8;\n }\n return l;\n }\n\n /**\n * setByte(addr, b)\n *\n * For physical addresses only; for linear addresses, use cpu.setByte().\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @param {number} b is the byte (8-bit) value to write (we truncate it to 8 bits to be safe)\n */\n setByte(addr, b)\n {\n this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].writeByte(addr & this.nBlockLimit, b & 0xff, addr);\n }\n\n /**\n * setByteDirect(addr, b)\n *\n * This is useful for the Debugger and other components that want to bypass breakpoint detection AND read-only\n * memory protection (for example, this is an interface the ROM component could use to initialize ROM contents).\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @param {number} b is the byte (8-bit) value to write (we truncate it to 8 bits to be safe)\n */\n setByteDirect(addr, b)\n {\n this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].writeByteDirect(addr & this.nBlockLimit, b & 0xff, addr);\n }\n\n /**\n * setShort(addr, w)\n *\n * For physical addresses only; for linear addresses, use cpu.setShort().\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @param {number} w is the word (16-bit) value to write (we truncate it to 16 bits to be safe)\n */\n setShort(addr, w)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off != this.nBlockLimit) {\n this.aMemBlocks[iBlock].writeShort(off, w & 0xffff, addr);\n return;\n }\n this.aMemBlocks[iBlock++].writeByte(off, w & 0xff, addr);\n this.aMemBlocks[iBlock & this.nBlockMask].writeByte(0, (w >> 8) & 0xff, addr + 1);\n }\n\n /**\n * setShortDirect(addr, w)\n *\n * This is useful for the Debugger and other components that want to bypass breakpoint detection AND read-only\n * memory protection (for example, this is an interface the ROM component could use to initialize ROM contents).\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @param {number} w is the word (16-bit) value to write (we truncate it to 16 bits to be safe)\n */\n setShortDirect(addr, w)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off != this.nBlockLimit) {\n this.aMemBlocks[iBlock].writeShortDirect(off, w & 0xffff, addr);\n return;\n }\n this.aMemBlocks[iBlock++].writeByteDirect(off, w & 0xff, addr);\n this.aMemBlocks[iBlock & this.nBlockMask].writeByteDirect(0, (w >> 8) & 0xff, addr + 1);\n }\n\n /**\n * setLong(addr, l)\n *\n * For physical addresses only; for linear addresses, use cpu.setLong().\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @param {number} l is the long (32-bit) value to write\n */\n setLong(addr, l)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off < this.nBlockLimit - 2) {\n this.aMemBlocks[iBlock].writeLong(off, l);\n return;\n }\n /*\n * I think the previous version of this function tried to be too clever (ie, reading and rewriting\n * the last long in the current block, and then reading and rewriting the first long in the next\n * block), which may have also created some undesirable side-effects for custom memory controllers.\n * This simpler (and probably more reliable) approach is to simply write the long as individual bytes.\n */\n var cb = 4;\n var cbBlock = 4 - (off & 0x3); // (off & 0x3) will be 1, 2 or 3, so cbBlock will be 3, 2, or 1\n while (cb--) {\n this.aMemBlocks[iBlock].writeByte(off++, l & 0xff, addr++);\n if (!--cbBlock) {\n iBlock = (iBlock + 1) & this.nBlockMask;\n off = 0;\n }\n l >>>= 8;\n }\n }\n\n /**\n * addBackTrackObject(obj, bto, off)\n *\n * If bto is null, then we create bto (ie, an object that wraps obj and records off).\n *\n * If bto is NOT null, then we verify that off is within the given bto's range; if not,\n * then we must create a new bto and return that instead.\n *\n * @this {Bus}\n * @param {Object} obj\n * @param {BackTrack|null} bto\n * @param {number} off (the offset within obj that this wrapper object is relative to)\n * @return {BackTrack|null}\n */\n addBackTrackObject(obj, bto, off)\n {\n if (BACKTRACK && obj) {\n var cbtObjects = this.abtObjects.length;\n if (!bto) {\n /*\n * Try the most recently created bto, on the off-chance it's what the caller needs\n */\n if (this.ibtLastAlloc >= 0) bto = this.abtObjects[this.ibtLastAlloc];\n }\n if (!bto || bto.obj != obj || off < bto.off || off >= bto.off + Bus.BTINFO.OFF_MAX) {\n\n bto = {obj: obj, off: off, slot: 0, refs: 0};\n\n var slot;\n if (!this.cbtDeletions) {\n slot = cbtObjects;\n } else {\n for (slot = this.ibtLastDelete; slot < cbtObjects; slot++) {\n var btoTest = this.abtObjects[slot];\n if (!btoTest || !btoTest.refs && !this.isBackTrackWeak(slot << Bus.BTINFO.SLOT_SHIFT)) {\n this.ibtLastDelete = slot + 1;\n this.cbtDeletions--;\n break;\n }\n }\n /*\n * There's no longer any guarantee that simply because cbtDeletions was non-zero that there WILL\n * be an available (existing) slot, because cbtDeletions also counts weak references that may still\n * be weak.\n *\n *\n */\n }\n /*\n * I hit the following error after running in a machine with lots of disk activity:\n *\n * Error: assertion failure in deskpro386.bus\n * at Bus.Component.assert (http://pcjs:8088/modules/shared/lib/component.js:732:31)\n * at Bus.addBackTrackObject (http://pcjs:8088/modules/pcx86/lib/bus.js:980:18)\n * at onATCReadData (http://pcjs:8088/modules/pcx86/lib/hdc.js:1410:35)\n * at HDC.readData (http://pcjs:8088/modules/pcx86/lib/hdc.js:2573:23)\n * at HDC.inATCByte (http://pcjs:8088/modules/pcx86/lib/hdc.js:1398:20)\n * at HDC.inATCData (http://pcjs:8088/modules/pcx86/lib/hdc.js:1487:17)\n * at Bus.checkPortInputNotify (http://pcjs:8088/modules/pcx86/lib/bus.js:1457:38)\n * at CPUX86.INSw (http://pcjs:8088/modules/pcx86/lib/x86ops.js:1640:26)\n * at CPUX86.stepCPU (http://pcjs:8088/modules/pcx86/lib/cpux86.js:4637:37)\n * at CPUX86.CPU.runCPU (http://pcjs:8088/modules/pcx86/lib/cpu.js:1014:22)\n *\n * TODO: Investigate. For now, BACKTRACK is completely disabled (in part because it also needs\n * to be revamped for machines with paging enabled).\n */\n\n this.ibtLastAlloc = slot;\n bto.slot = slot + 1;\n if (slot == cbtObjects) {\n this.abtObjects.push(bto);\n } else {\n this.abtObjects[slot] = bto;\n }\n }\n return bto;\n }\n return null;\n }\n\n /**\n * getBackTrackIndex(bto, off)\n *\n * @this {Bus}\n * @param {BackTrack|null} bto\n * @param {number} off\n * @return {number}\n */\n getBackTrackIndex(bto, off)\n {\n var bti = 0;\n if (BACKTRACK && bto) {\n bti = (bto.slot << Bus.BTINFO.SLOT_SHIFT) | Bus.BTINFO.TYPE_DATA | (off - bto.off);\n }\n return bti;\n }\n\n /**\n * writeBackTrackObject(addr, bto, off)\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @param {BackTrack|null} bto\n * @param {number} off\n */\n writeBackTrackObject(addr, bto, off)\n {\n if (BACKTRACK && bto) {\n\n var bti = (bto.slot << Bus.BTINFO.SLOT_SHIFT) | Bus.BTINFO.TYPE_DATA | (off - bto.off);\n this.writeBackTrack(addr, bti);\n }\n }\n\n /**\n * readBackTrack(addr)\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @return {number}\n */\n readBackTrack(addr)\n {\n if (BACKTRACK) {\n return this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].readBackTrack(addr & this.nBlockLimit);\n }\n return 0;\n }\n\n /**\n * writeBackTrack(addr, bti)\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @param {number} bti\n */\n writeBackTrack(addr, bti)\n {\n if (BACKTRACK) {\n var slot = bti >>> Bus.BTINFO.SLOT_SHIFT;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n var btiPrev = this.aMemBlocks[iBlock].writeBackTrack(addr & this.nBlockLimit, bti);\n var slotPrev = btiPrev >>> Bus.BTINFO.SLOT_SHIFT;\n if (slot != slotPrev) {\n this.aMemBlocks[iBlock].modBackTrack(true);\n if (btiPrev && slotPrev) {\n var btoPrev = this.abtObjects[slotPrev-1];\n if (!btoPrev) {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages.WARN)) {\n this.dbg.message(\"writeBackTrack(%\" + Str.toHex(addr) + ',' + Str.toHex(bti) + \"): previous index (\" + Str.toHex(btiPrev) + \") refers to empty slot (\" + slotPrev + \")\");\n }\n }\n else if (btoPrev.refs <= 0) {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages.WARN)) {\n this.dbg.message(\"writeBackTrack(%\" + Str.toHex(addr) + ',' + Str.toHex(bti) + \"): previous index (\" + Str.toHex(btiPrev) + \") refers to object with bad ref count (\" + btoPrev.refs + \")\");\n }\n } else if (!--btoPrev.refs) {\n /*\n * We used to just slam a null into the previous slot and consider it gone, but there may still\n * be \"weak references\" to that slot (ie, it may still be associated with a register bti).\n *\n * The easiest way to handle weak references is to leave the slot allocated, with the object's ref\n * count sitting at zero, and change addBackTrackObject() to look for both empty slots AND non-empty\n * slots with a ref count of zero; in the latter case, it should again check for weak references,\n * after which we can re-use the slot if all its weak references are now gone.\n */\n if (!this.isBackTrackWeak(btiPrev)) this.abtObjects[slotPrev-1] = null;\n /*\n * TODO: Consider what the appropriate trigger should be for resetting ibtLastDelete to zero;\n * if we don't OCCASIONALLY set it to zero, we may never clear out obsolete weak references,\n * whereas if we ALWAYS set it to zero, we may be forcing addBackTrackObject() to scan the entire\n * table too often.\n *\n * I'd prefer to do something like this:\n *\n * if (this.ibtLastDelete > slotPrev-1) this.ibtLastDelete = slotPrev-1;\n *\n * or even this:\n *\n * if (this.ibtLastDelete > slotPrev-1) this.ibtLastDelete = 0;\n *\n * But neither one of those guarantees that we will at least occasionally scan the entire table.\n */\n this.ibtLastDelete = 0;\n this.cbtDeletions++;\n }\n }\n if (bti && slot) {\n var bto = this.abtObjects[slot-1];\n if (bto) {\n\n bto.refs++;\n }\n }\n }\n }\n }\n\n /**\n * isBackTrackWeak(bti)\n *\n * @param {number} bti\n * @returns {boolean} true if the given bti is still referenced by a register, false if not\n */\n isBackTrackWeak(bti)\n {\n var bt = this.cpu.backTrack;\n var slot = bti >> Bus.BTINFO.SLOT_SHIFT;\n return (bt.btiAL >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiAH >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiBL >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiBH >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiCL >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiCH >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiDL >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiDH >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiBPLo >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiBPHi >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiSILo >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiSIHi >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiDILo >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiDIHi >> Bus.BTINFO.SLOT_SHIFT == slot\n );\n }\n\n /**\n * updateBackTrackCode(addr, bti)\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @param {number} bti\n */\n updateBackTrackCode(addr, bti)\n {\n if (BACKTRACK) {\n if (bti & Bus.BTINFO.TYPE_DATA) {\n bti = (bti & ~Bus.BTINFO.TYPE_MASK) | Bus.BTINFO.TYPE_COUNT_INC;\n } else if ((bti & Bus.BTINFO.TYPE_MASK) < Bus.BTINFO.TYPE_COUNT_MAX) {\n bti += Bus.BTINFO.TYPE_COUNT_INC;\n } else {\n return;\n }\n this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].writeBackTrack(addr & this.nBlockLimit, bti);\n }\n }\n\n /**\n * getBackTrackObject(bti)\n *\n * @this {Bus}\n * @param {number} bti\n * @return {Object|null}\n */\n getBackTrackObject(bti)\n {\n if (BACKTRACK) {\n var slot = bti >>> Bus.BTINFO.SLOT_SHIFT;\n if (slot) return this.abtObjects[slot-1];\n }\n return null;\n }\n\n /**\n * getBackTrackInfo(bti, fSymbol, fNearest)\n *\n * @this {Bus}\n * @param {number} bti\n * @param {boolean} [fSymbol] (true to return only symbol)\n * @param {boolean} [fNearest] (true to return nearest symbol)\n * @return {string|null}\n */\n getBackTrackInfo(bti, fSymbol, fNearest)\n {\n if (BACKTRACK) {\n var bto = this.getBackTrackObject(bti);\n if (bto) {\n var off = bti & Bus.BTINFO.OFF_MASK;\n var file = bto.obj.file;\n if (file) {\n\n return file.getSymbol(bto.obj.offFile + off, fNearest);\n }\n if (!fSymbol || fNearest) {\n if (bto.obj.idComponent) {\n return bto.obj.idComponent + '+' + Str.toHex(bto.off + off, 0, true);\n }\n }\n }\n }\n return null;\n }\n\n /**\n * getSymbol(addr, fNearest)\n *\n * @this {Bus}\n * @param {number} addr\n * @param {boolean} [fNearest] (true to return nearest symbol)\n * @return {string|null}\n */\n getSymbol(addr, fNearest)\n {\n return BACKTRACK? this.getBackTrackInfo(this.readBackTrack(addr), true, fNearest) : null;\n }\n\n /**\n * saveMemory(fAll)\n *\n * The only memory blocks we save are those marked as dirty, but most likely all of RAM will have been marked dirty,\n * and even if our dirty-memory flags were as smart as our dirty-sector flags (ie, were set only when a write changed\n * what was already there), it's unlikely that would reduce the number of RAM blocks we must save/restore. At least\n * all the ROM blocks should be clean (except in the unlikely event that the Debugger was used to modify them).\n *\n * All dirty blocks will be stored in a single array, as pairs of block numbers and data arrays, like so:\n *\n * [iBlock0, [dw0, dw1, ...], iBlock1, [dw0, dw1, ...], ...]\n *\n * In a normal 4Kb block, there will be 1K DWORD values in the data array. Remember that each DWORD is a signed 32-bit\n * integer (because they are formed using bitwise operator rather than floating-point math operators), so don't be\n * surprised to see negative numbers in the data.\n *\n * The above example assumes \"uncompressed\" data arrays. If we choose to use \"compressed\" data arrays, the data arrays\n * will look like:\n *\n * [count0, dw0, count1, dw1, ...]\n *\n * where each count indicates how many times the following DWORD value occurs. A data array length less than 1K indicates\n * that it's compressed, since we'll only store them in compressed form if they actually shrank, and we'll use State\n * helper methods compress() and decompress() to create and expand the compressed data arrays.\n *\n * @this {Bus}\n * @param {boolean} [fAll] (true to save all non-ROM memory blocks, regardless of their dirty flags)\n * @return {Array} a\n */\n saveMemory(fAll)\n {\n var i = 0;\n var a = [];\n\n /*\n * A quick-and-dirty work-around for 32-bit bus machines, to ensure that all blocks in the 2nd Mb are\n * mapped in before we save. We do this by forcing A20 on, and then turning it off again before we leave.\n */\n var fA20 = this.getA20();\n if (!fA20) this.setA20(true);\n\n for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {\n var block = this.aMemBlocks[iBlock];\n /*\n * We have to check both fDirty and fDirtyEver, because we may have called cleanMemory() on some of\n * the memory blocks (eg, video memory), and while cleanMemory() will clear a dirty block's fDirty flag,\n * it also sets the dirty block's fDirtyEver flag, which is left set for the lifetime of the machine.\n */\n if (fAll && block.type != Memory.TYPE.ROM || block.fDirty || block.fDirtyEver) {\n a[i++] = iBlock;\n a[i++] = State.compress(block.save());\n }\n }\n\n if (!fA20) this.setA20(false);\n a[i] = fA20;\n\n return a;\n }\n\n /**\n * restoreMemory(a)\n *\n * This restores the contents of all Memory blocks; called by CPUX86.restore().\n *\n * In theory, we ONLY have to save/restore block contents. Other block attributes,\n * like the type, the memory controller (if any), and the active memory access functions,\n * should already be restored, since every component (re)allocates all the memory blocks\n * it was using when it's restored. And since the CPU is guaranteed to be the last\n * component to be restored, all those blocks (and their attributes) should be in place now.\n *\n * See saveMemory() for more information on how the memory block contents are saved.\n *\n * @this {Bus}\n * @param {Array} a\n * @return {boolean} true if successful, false if not\n */\n restoreMemory(a)\n {\n var i;\n for (i = 0; i < a.length - 1; i += 2) {\n var iBlock = a[i];\n var adw = a[i+1];\n if (adw && adw.length < this.nBlockLen) {\n adw = State.decompress(adw, this.nBlockLen);\n }\n var block = this.aMemBlocks[iBlock];\n if (!block || !block.restore(adw)) {\n /*\n * Either the block to restore hasn't been allocated, indicating a change in the machine\n * configuration since it was last saved (the most likely explanation) or there's some internal\n * inconsistency (eg, the block size is wrong).\n */\n Component.error(\"Unable to restore memory block \" + iBlock);\n return false;\n }\n }\n if (a[i] !== undefined) this.setA20(a[i]);\n return true;\n }\n\n /**\n * addPortInputBreak(port)\n *\n * @this {Bus}\n * @param {number|null} [port]\n * @return {boolean} true if break on port input enabled, false if disabled\n */\n addPortInputBreak(port)\n {\n if (port == null) {\n this.fPortInputBreakAll = !this.fPortInputBreakAll;\n return this.fPortInputBreakAll;\n }\n if (this.aPortInputNotify[port] === undefined) {\n this.aPortInputNotify[port] = [null, false];\n }\n this.aPortInputNotify[port][1] = !this.aPortInputNotify[port][1];\n return this.aPortInputNotify[port][1];\n }\n\n /**\n * addPortInputNotify(start, end, fn)\n *\n * Add a port input-notification handler to the list of such handlers.\n *\n * @this {Bus}\n * @param {number} start port address\n * @param {number} end port address\n * @param {function(number,number)} fn is called with the port and LIP values at the time of the input\n */\n addPortInputNotify(start, end, fn)\n {\n if (fn !== undefined) {\n for (var port = start; port <= end; port++) {\n if (this.aPortInputNotify[port] !== undefined) {\n Component.warning(\"Input port \" + Str.toHexWord(port) + \" already registered\");\n continue;\n }\n this.aPortInputNotify[port] = [fn, false];\n if (MAXDEBUG) this.log(\"addPortInputNotify(\" + Str.toHexWord(port) + \")\");\n }\n }\n }\n\n /**\n * addPortInputTable(component, table, offset)\n *\n * Add port input-notification handlers from the specified table (a batch version of addPortInputNotify)\n *\n * @this {Bus}\n * @param {Component} component\n * @param {Object} table\n * @param {number} [offset] is an optional port offset\n */\n addPortInputTable(component, table, offset)\n {\n if (offset === undefined) offset = 0;\n for (var port in table) {\n this.addPortInputNotify(+port + offset, +port + offset, table[port].bind(component));\n }\n }\n\n /**\n * addPortInputWidth(port, size)\n *\n * By default, all input ports are 1 byte wide; ports that are wider must call this function.\n *\n * @this {Bus}\n * @param {number} port\n * @param {number} size (1, 2 or 4)\n */\n addPortInputWidth(port, size)\n {\n this.aPortInputWidth[port] = size;\n }\n\n /**\n * checkPortInputNotify(port, size, addrLIP)\n *\n * @this {Bus}\n * @param {number} port\n * @param {number} size (1, 2 or 4)\n * @param {number} [addrLIP] is the LIP value at the time of the input\n * @return {number} simulated port data\n *\n * NOTE: It seems that parts of the ROM BIOS (like the RS-232 probes around F000:E5D7 in the 5150 BIOS)\n * assume that ports for non-existent hardware return 0xff rather than 0x00, hence my new default (0xff) below.\n */\n checkPortInputNotify(port, size, addrLIP)\n {\n var data = 0, shift = 0;\n\n while (size > 0) {\n\n var aNotify = this.aPortInputNotify[port];\n var sizePort = this.aPortInputWidth[port] || 1;\n var maskPort = (sizePort == 1? 0xff : (sizePort == 2? 0xffff : -1));\n var dataPort = maskPort;\n\n /*\n * TODO: We need to decide what to do about 8-bit I/O to a 16-bit port (ditto for 16-bit I/O\n * to a 32-bit port). We probably should pass the size through to the aNotify[0] handler,\n * and let it decide what to do, but I don't feel like changing all the I/O handlers right now.\n * The good news, at least, is that the 8-bit handlers would not have to do anything special.\n * This assert will warn us if this is a pressing need.\n */\n\n\n if (BACKTRACK) {\n this.cpu.backTrack.btiIO = 0;\n }\n\n if (aNotify !== undefined) {\n if (aNotify[0]) {\n dataPort = aNotify[0](port, addrLIP);\n if (dataPort == null) {\n dataPort = maskPort;\n } else {\n dataPort &= maskPort;\n }\n }\n if (DEBUGGER && this.dbg && this.fPortInputBreakAll != aNotify[1]) {\n this.dbg.checkPortInput(port, size, dataPort);\n }\n }\n else {\n if (DEBUGGER && this.dbg) {\n this.dbg.messageIO(this, port, null, addrLIP);\n if (this.fPortInputBreakAll) this.dbg.checkPortInput(port, size, dataPort);\n }\n }\n\n data |= dataPort << shift;\n shift += (sizePort << 3);\n port += sizePort;\n size -= sizePort;\n }\n\n\n return data;\n }\n\n /**\n * addPortOutputBreak(port)\n *\n * @this {Bus}\n * @param {number|null} [port]\n * @return {boolean} true if break on port output enabled, false if disabled\n */\n addPortOutputBreak(port)\n {\n if (port == null) {\n this.fPortOutputBreakAll = !this.fPortOutputBreakAll;\n return this.fPortOutputBreakAll;\n }\n if (this.aPortOutputNotify[port] === undefined) {\n this.aPortOutputNotify[port] = [null, false];\n }\n this.aPortOutputNotify[port][1] = !this.aPortOutputNotify[port][1];\n return this.aPortOutputNotify[port][1];\n }\n\n /**\n * addPortOutputNotify(start, end, fn)\n *\n * Add a port output-notification handler to the list of such handlers.\n *\n * @this {Bus}\n * @param {number} start port address\n * @param {number} end port address\n * @param {function(number,number)} fn is called with the port and LIP values at the time of the output\n */\n addPortOutputNotify(start, end, fn)\n {\n if (fn !== undefined) {\n for (var port = start; port <= end; port++) {\n if (this.aPortOutputNotify[port] !== undefined) {\n Component.warning(\"Output port \" + Str.toHexWord(port) + \" already registered\");\n continue;\n }\n this.aPortOutputNotify[port] = [fn, false];\n if (MAXDEBUG) this.log(\"addPortOutputNotify(\" + Str.toHexWord(port) + \")\");\n }\n }\n }\n\n /**\n * addPortOutputTable(component, table, offset)\n *\n * Add port output-notification handlers from the specified table (a batch version of addPortOutputNotify)\n *\n * @this {Bus}\n * @param {Component} component\n * @param {Object} table\n * @param {number} [offset] is an optional port offset\n */\n addPortOutputTable(component, table, offset)\n {\n if (offset === undefined) offset = 0;\n for (var port in table) {\n this.addPortOutputNotify(+port + offset, +port + offset, table[port].bind(component));\n }\n }\n\n /**\n * addPortOutputWidth(port, size)\n *\n * By default, all output ports are 1 byte wide; ports that are wider must call this function.\n *\n * @this {Bus}\n * @param {number} port\n * @param {number} size (1, 2 or 4)\n */\n addPortOutputWidth(port, size)\n {\n this.aPortOutputWidth[port] = size;\n }\n\n /**\n * checkPortOutputNotify(port, size, data, addrLIP)\n *\n * @this {Bus}\n * @param {number} port\n * @param {number} size\n * @param {number} data\n * @param {number} [addrLIP] is the LIP value at the time of the output\n */\n checkPortOutputNotify(port, size, data, addrLIP)\n {\n var shift = 0;\n\n while (size > 0) {\n\n var aNotify = this.aPortOutputNotify[port];\n var sizePort = this.aPortOutputWidth[port] || 1;\n var maskPort = (sizePort == 1? 0xff : (sizePort == 2? 0xffff : -1));\n var dataPort = (data >>>= shift) & maskPort;\n\n /*\n * TODO: We need to decide what to do about 8-bit I/O to a 16-bit port (ditto for 16-bit I/O\n * to a 32-bit port). We probably should pass the size through to the aNotify[0] handler,\n * and let it decide what to do, but I don't feel like changing all the I/O handlers right now.\n * The good news, at least, is that the 8-bit handlers would not have to do anything special.\n * This assert will warn us if this is a pressing need.\n */\n\n\n if (aNotify !== undefined) {\n if (aNotify[0]) {\n aNotify[0](port, dataPort, addrLIP);\n }\n if (DEBUGGER && this.dbg && this.fPortOutputBreakAll != aNotify[1]) {\n this.dbg.checkPortOutput(port, size, dataPort);\n }\n }\n else {\n if (DEBUGGER && this.dbg) {\n this.dbg.messageIO(this, port, dataPort, addrLIP);\n if (this.fPortOutputBreakAll) this.dbg.checkPortOutput(port, size, dataPort);\n }\n }\n\n shift += (sizePort << 3);\n port += sizePort;\n size -= sizePort;\n }\n\n }\n\n /**\n * reportError(op, addr, size, fQuiet)\n *\n * @this {Bus}\n * @param {number} op\n * @param {number} addr\n * @param {number} size\n * @param {boolean} [fQuiet] (true if any error should be quietly logged)\n * @return {boolean} false\n */\n reportError(op, addr, size, fQuiet)\n {\n var sError = \"Memory block error (\" + op + \": \" + Str.toHex(addr) + \",\" + Str.toHex(size) + \")\";\n if (fQuiet) {\n if (this.dbg) {\n this.dbg.message(sError);\n } else {\n this.log(sError);\n }\n } else {\n Component.error(sError);\n }\n return false;\n }\n\n /**\n * getLongDirect(addr)\n *\n * This is useful for the Debugger and other components that want to bypass getLong() breakpoint detection.\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @return {number} long (32-bit) value at that address\n *\n getLongDirect(addr)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off < this.nBlockLimit - 2) {\n return this.aMemBlocks[iBlock].readLongDirect(off, addr);\n }\n //\n // I think the previous version of this function tried to be too clever (ie, reading the last\n // long in the current block and the first long in the next block and masking/combining the results),\n // which may have also created some undesirable side-effects for custom memory controllers.\n // This simpler (and probably more reliable) approach is to simply read the long as individual bytes.\n //\n var l = 0;\n var cb = 4, nShift = 0;\n var cbBlock = 4 - (off & 0x3); // (off & 0x3) will be 1, 2 or 3, so cbBlock will be 3, 2, or 1\n while (cb--) {\n l |= (this.aMemBlocks[iBlock].readByteDirect(off++, addr++) << nShift);\n if (!--cbBlock) {\n iBlock = (iBlock + 1) & this.nBlockMask;\n off = 0;\n }\n nShift += 8;\n }\n return l;\n }\n */\n\n /**\n * setLongDirect(addr, l)\n *\n * This is useful for the Debugger and other components that want to bypass breakpoint detection AND read-only\n * memory protection (for example, this is an interface the ROM component could use to initialize ROM contents).\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @param {number} l is the long (32-bit) value to write\n *\n setLongDirect(addr, l)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off < this.nBlockLimit - 2) {\n this.aMemBlocks[iBlock].writeLongDirect(off, l, addr);\n return;\n }\n //\n // I think the previous version of this function tried to be too clever (ie, reading and rewriting\n // the last long in the current block, and then reading and rewriting the first long in the next\n // block), which may have also created some undesirable side-effects for custom memory controllers.\n // This simpler (and probably more reliable) approach is to simply write the long as individual bytes.\n //\n var cb = 4;\n var cbBlock = 4 - (off & 0x3); // (off & 0x3) will be 1, 2 or 3, so cbBlock will be 3, 2, or 1\n while (cb--) {\n this.aMemBlocks[iBlock].writeByteDirect(off++, l & 0xff, addr++);\n if (!--cbBlock) {\n iBlock = (iBlock + 1) & this.nBlockMask;\n off = 0;\n }\n l >>>= 8;\n }\n }\n */\n\n /**\n * getBackTrackObjectFromAddr(addr)\n *\n * @this {Bus}\n * @param {number} addr\n * @return {Object|null}\n *\n getBackTrackObjectFromAddr(addr)\n {\n return BACKTRACK? this.getBackTrackObject(this.readBackTrack(addr)) : null;\n }\n */\n\n /**\n * getBackTrackInfoFromAddr(addr)\n *\n * @this {Bus}\n * @param {number} addr\n * @return {string|null}\n *\n getBackTrackInfoFromAddr(addr)\n {\n return BACKTRACK? this.getBackTrackInfo(this.readBackTrack(addr)) : null;\n }\n */\n\n /**\n * removePortInputNotify(start, end)\n *\n * Remove port input-notification handler(s) (to be ENABLED later if needed)\n *\n * @this {Bus}\n * @param {number} start address\n * @param {number} end address\n *\n removePortInputNotify(start, end)\n {\n for (var port = start; port < end; port++) {\n if (this.aPortInputNotify[port]) {\n delete this.aPortInputNotify[port];\n }\n }\n }\n */\n\n /**\n * removePortOutputNotify(start, end)\n *\n * Remove port output-notification handler(s) (to be ENABLED later if needed)\n *\n * @this {Bus}\n * @param {number} start address\n * @param {number} end address\n *\n removePortOutputNotify(start, end)\n {\n for (var port = start; port < end; port++) {\n if (this.aPortOutputNotify[port]) {\n delete this.aPortOutputNotify[port];\n }\n }\n }\n */\n}\n\n/*\n * Data types used by scanMemory()\n */\n\n/**\n * @typedef {number}\n */\nvar BlockInfo;\n\n/**\n * This defines the BlockInfo bit fields used by scanMemory() when it creates the aBlocks array.\n *\n * @typedef {{\n * num: BitField,\n * count: BitField,\n * btmod: BitField,\n * type: BitField\n * }}\n */\nBus.BlockInfo = Usr.defineBitFields({num:20, count:8, btmod:1, type:3});\n\n/**\n * BusInfo object definition (returned by scanMemory())\n *\n * cbTotal: total bytes allocated\n * cBlocks: total Memory blocks allocated\n * aBlocks: array of allocated Memory block numbers\n *\n * @typedef {{\n * cbTotal: number,\n * cBlocks: number,\n * aBlocks: Array.<BlockInfo>\n * }}\n */\nvar BusInfo;\n\nif (BACKTRACK) {\n /**\n * BackTrack object definition\n *\n * obj: reference to the source object (eg, ROM object, Sector object)\n * off: the offset within the source object that this object refers to\n * slot: the slot (+1) in abtObjects which this object currently occupies\n * refs: the number of memory references, as recorded by writeBackTrack()\n *\n * @typedef {{\n * obj: Object,\n * off: number,\n * slot: number,\n * refs: number\n * }}\n */\n var BackTrack;\n\n /*\n * BackTrack indexes are 31-bit values, where bits 0-8 store an object offset (0-511) and bits 16-30 store\n * an object number (1-32767). Object number 0 is reserved for dynamic data (ie, data created independent\n * of any source); examples include zero values produced by instructions such as \"SUB AX,AX\" or \"XOR AX,AX\".\n * We must special-case instructions like that, because even though AX will almost certainly contain some source\n * data prior to the instruction, the result no longer has any connection to the source. Similarly, \"SBB AX,AX\"\n * may produce 0 or -1, depending on carry, but since we don't track the source of individual bits (including the\n * carry flag), AX is now source-less. TODO: This is an argument for maintaining source info on selected flags,\n * even though it would be rather expensive.\n *\n * The 7 middle bits (9-15) record type and access information, as follows:\n *\n * bit 15: set to indicate a \"data\" byte, clear to indicate a \"code\" byte\n *\n * All bytes start out as \"data\" bytes; only once they've been executed do they become \"code\" bytes. For code\n * bytes, the remaining 6 middle bits (9-14) represent an execution count that starts at 1 (on the byte's initial\n * transition from data to code) and tops out at 63.\n *\n * For data bytes, the remaining middle bits indicate any transformations the data has undergone; eg:\n *\n * bit 14: ADD/SUB/INC/DEC\n * bit 13: MUL/DIV\n * bit 12: OR/AND/XOR/NOT\n *\n * We make no attempt to record the original data or the transformation data, only that the transformation occurred.\n *\n * Other middle bits indicate whether the data was ever read and/or written:\n *\n * bit 11: READ\n * bit 10: WRITE\n *\n * Bit 9 is reserved for now.\n */\n Bus.BTINFO = {\n SLOT_MAX: 32768,\n SLOT_SHIFT: 16,\n TYPE_DATA: 0x8000,\n TYPE_ADDSUB: 0x4000,\n TYPE_MULDIV: 0x2000,\n TYPE_LOGICAL: 0x1000,\n TYPE_READ: 0x0800,\n TYPE_WRITE: 0x0400,\n TYPE_COUNT_INC: 0x0200,\n TYPE_COUNT_MAX: 0x7E00,\n TYPE_MASK: 0xFE00,\n TYPE_SHIFT: 9,\n OFF_MAX: 512,\n OFF_MASK: 0x1FF\n };\n}\n\nBus.ERROR = {\n ADD_MEM_INUSE: 1,\n ADD_MEM_BADRANGE: 2,\n SET_MEM_NOCTRL: 3,\n SET_MEM_BADRANGE: 4,\n REM_MEM_BADRANGE: 5\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/memory.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * @class DataView\n * @property {function(number,boolean):number} getUint8\n * @property {function(number,number,boolean)} setUint8\n * @property {function(number,boolean):number} getUint16\n * @property {function(number,number,boolean)} setUint16\n * @property {function(number,boolean):number} getInt32\n * @property {function(number,number,boolean)} setInt32\n */\n\nvar littleEndian = (TYPEDARRAYS? (function() {\n var buffer = new ArrayBuffer(2);\n new DataView(buffer).setUint16(0, 256, true);\n return new Uint16Array(buffer)[0] === 256;\n})() : false);\n\n/**\n * class Memory\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass Memory {\n /**\n * Memory(addr, used, size, type, controller)\n *\n * The Bus component allocates Memory objects so that each has a memory buffer with a\n * block-granular starting address and an address range equal to bus.nBlockSize; however,\n * the size of any given Memory object's underlying buffer can be either zero or bus.nBlockSize;\n * memory read/write functions for empty (buffer-less) blocks are mapped to readNone/writeNone.\n *\n * The Bus allocates empty blocks for the entire address space during initialization, so that\n * any reads/writes to undefined addresses will have no effect. Later, the ROM and RAM\n * components will ask the Bus to allocate memory for specific ranges, and the Bus will allocate\n * as many new blockSize Memory objects as the ranges require. Partial Memory blocks could\n * also be supported in theory, but in practice, they're not.\n *\n * Because Memory blocks now allow us to have a \"sparse\" address space, we could choose to\n * take the memory hit of allocating 4K arrays per block, where each element stores only one byte,\n * instead of the more frugal but slightly slower approach of allocating arrays of 32-bit dwords\n * (LONGARRAYS) and shifting/masking bytes/words to/from dwords; in theory, byte accesses would\n * be faster and word accesses somewhat less faster.\n *\n * However, preliminary testing of that feature (BYTEARRAYS) did not yield significantly faster\n * performance, so it is OFF by default to minimize our memory consumption. Using TYPEDARRAYS\n * would seem best, but as discussed in defines.js, it's off by default, because it doesn't perform\n * as well as LONGARRAYS; the other advantage of TYPEDARRAYS is that it should theoretically use\n * about 1/2 the memory of LONGARRAYS (32-bit elements vs 64-bit numbers), but I value speed over\n * size at this point. Also, not all JavaScript implementations support TYPEDARRAYS (IE9 is probably\n * the only real outlier: it lacks typed arrays but otherwise has all the necessary HTML5 support).\n *\n * WARNING: Since Memory blocks are low-level objects that have no UI requirements, they\n * do not inherit from the Component class, so if you want to use any Component class methods,\n * such as Component.assert(), use the corresponding Debugger methods instead (assuming a debugger\n * is available).\n *\n * @this {Memory}\n * @param {number|null} [addr] of lowest used address in block\n * @param {number} [used] portion of block in bytes (0 for none); must be a multiple of 4\n * @param {number} [size] of block's buffer in bytes (0 for none); must be a multiple of 4\n * @param {number} [type] is one of the Memory.TYPE constants (default is Memory.TYPE.NONE)\n * @param {Controller} [controller] is an optional memory controller component\n * @param {CPUX86} [cpu] is required for UNPAGED memory blocks, so that the CPU can map it to a PAGED block\n */\n constructor(addr, used, size, type, controller, cpu)\n {\n var i;\n this.id = (Memory.idBlock += 2);\n this.adw = null;\n this.offset = 0;\n this.addr = addr;\n this.used = used;\n this.size = size || 0;\n this.type = type || Memory.TYPE.NONE;\n this.fReadOnly = (type == Memory.TYPE.ROM);\n this.controller = null;\n this.cpu = cpu; // if a CPU reference is provided, then this must be an UNPAGED Memory block allocation\n this.copyBreakpoints(); // initialize the block's Debugger info (eg, breakpoint totals); the caller will reinitialize\n\n /*\n * TODO: Study the impact of dirty block tracking. As noted in the paged block handlers (eg, writeBytePLE),\n * the original purposes were to allow saveMemory() to save only dirty blocks, and to enable the Video component\n * to quickly detect changes to the video buffer. But the benefit to saveMemory() is minimal, and the Video\n * component has other options; for example, it now uses a custom memory controller for all EGA/VGA video modes,\n * which performs its own dirty block tracking, and that could easily be extended to the older MDA/CGA video modes,\n * which still use conventional memory blocks. Alternatively, we could restrict the use of dirty block tracking\n * to certain memory types (eg, VIDEO memory).\n *\n * However, a quick test with dirty block tracking disabled didn't yield a noticeable improvement in performance,\n * so I think the overhead of our block-based architecture is swamping the impact of these micro-updates.\n */\n this.fDirty = this.fDirtyEver = false;\n\n if (BACKTRACK) {\n if (!size || controller) {\n this.fModBackTrack = false;\n this.readBackTrack = this.readBackTrackNone;\n this.writeBackTrack = this.writeBackTrackNone;\n this.modBackTrack = this.modBackTrackNone;\n } else {\n this.fModBackTrack = true;\n this.readBackTrack = this.readBackTrackIndex;\n this.writeBackTrack = this.writeBackTrackIndex;\n this.modBackTrack = this.modBackTrackIndex;\n this.abtIndexes = new Array(size);\n for (i = 0; i < size; i++) this.abtIndexes[i] = 0;\n }\n }\n\n /*\n * For empty memory blocks, all we need to do is ensure all access functions\n * are mapped to \"none\" handlers (or \"unpaged\" handlers if paging is enabled).\n */\n if (!size) {\n this.setAccess();\n return;\n }\n\n /*\n * When a controller is specified, the controller must provide a buffer,\n * via getMemoryBuffer(), and memory access functions, via getMemoryAccess().\n */\n if (controller) {\n this.controller = controller;\n var a = controller.getMemoryBuffer(addr|0);\n this.adw = a[0];\n this.offset = a[1];\n this.setAccess(controller.getMemoryAccess());\n return;\n }\n\n /*\n * This is the normal case: allocate a buffer that provides 8 bits of data per address;\n * no controller is required because our default memory access functions (see afnMemory)\n * know how to deal with this simple 1-1 mapping of addresses to bytes and words.\n *\n * TODO: Consider initializing the memory array to random (or pseudo-random) values in DEBUG\n * mode; pseudo-random might be best, to help make any bugs reproducible.\n */\n if (TYPEDARRAYS) {\n this.buffer = new ArrayBuffer(size);\n this.dv = new DataView(this.buffer, 0, size);\n /*\n * If littleEndian is true, we can use ab[], aw[] and adw[] directly; well, we can use them\n * whenever the offset is a multiple of 1, 2 or 4, respectively. Otherwise, we must fallback to\n * dv.getUint8()/dv.setUint8(), dv.getUint16()/dv.setUint16() and dv.getInt32()/dv.setInt32().\n */\n this.ab = new Uint8Array(this.buffer, 0, size);\n this.aw = new Uint16Array(this.buffer, 0, size >> 1);\n this.adw = new Int32Array(this.buffer, 0, size >> 2);\n this.setAccess(littleEndian? Memory.afnArrayLE : Memory.afnArrayBE);\n } else {\n if (BYTEARRAYS) {\n this.ab = new Array(size);\n } else {\n /*\n * NOTE: This is the default mode of operation (!TYPEDARRAYS && !BYTEARRAYS), because it\n * seems to provide the best performance; and although in theory, that performance might\n * come at twice the overhead of TYPEDARRAYS, it's increasingly likely that the JavaScript\n * runtime will notice that all we ever store are 32-bit values, and optimize accordingly.\n */\n this.adw = new Array(size >> 2);\n for (i = 0; i < this.adw.length; i++) this.adw[i] = 0;\n }\n this.setAccess(Memory.afnMemory);\n }\n }\n\n /**\n * init(addr)\n *\n * Quick reinitializer when reusing a Memory block.\n *\n * @this {Memory}\n * @param {number} addr\n */\n init(addr)\n {\n this.addr = addr;\n }\n\n /**\n * clone(mem, type)\n *\n * Converts the current Memory block (this) into a clone of the given Memory block (mem),\n * and optionally overrides the current block's type with the specified type.\n *\n * @this {Memory}\n * @param {Memory} mem\n * @param {number} [type]\n * @param {DebuggerX86} [dbg]\n */\n clone(mem, type, dbg)\n {\n /*\n * Original memory block IDs are even; cloned memory block IDs are odd;\n * the original ID of the current block is lost, but that's OK, since it was presumably\n * produced merely to become a clone.\n */\n this.id = mem.id | 0x1;\n this.used = mem.used;\n this.size = mem.size;\n if (type) {\n this.type = type;\n this.fReadOnly = (type == Memory.TYPE.ROM);\n }\n if (TYPEDARRAYS) {\n this.buffer = mem.buffer;\n this.dv = mem.dv;\n this.ab = mem.ab;\n this.aw = mem.aw;\n this.adw = mem.adw;\n this.setAccess(littleEndian? Memory.afnArrayLE : Memory.afnArrayBE);\n } else {\n if (BYTEARRAYS) {\n this.ab = mem.ab;\n } else {\n this.adw = mem.adw;\n }\n this.setAccess(Memory.afnMemory);\n }\n this.copyBreakpoints(dbg, mem);\n }\n\n /**\n * save()\n *\n * This gets the contents of a Memory block as an array of 32-bit values; used by Bus.saveMemory(),\n * which in turn is called by CPUX86.save().\n *\n * Memory blocks with custom memory controllers do NOT save their contents; that's the responsibility\n * of the controller component.\n *\n * @this {Memory}\n * @return {Array|Int32Array|null}\n */\n save()\n {\n var adw, i;\n if (this.controller) {\n adw = null;\n }\n else if (BYTEARRAYS) {\n adw = new Array(this.size >> 2);\n var off = 0;\n for (i = 0; i < adw.length; i++) {\n adw[i] = this.ab[off] | (this.ab[off + 1] << 8) | (this.ab[off + 2] << 16) | (this.ab[off + 3] << 24);\n off += 4;\n }\n }\n else if (TYPEDARRAYS) {\n /*\n * It might be tempting to just return a copy of Int32Array(this.buffer, 0, this.size >> 2),\n * but we can't be sure of the \"endianness\" of an Int32Array -- which would be OK if the array\n * was always saved/restored on the same machine, but there's no guarantee of that, either.\n * So we use getInt32() and require little-endian values.\n *\n * Moreover, an Int32Array isn't treated by JSON.stringify() and JSON.parse() exactly like\n * a normal array; it's serialized as an Object rather than an Array, so it lacks a \"length\"\n * property and causes problems for State.store() and State.parse().\n */\n adw = new Array(this.size >> 2);\n for (i = 0; i < adw.length; i++) {\n adw[i] = this.dv.getInt32(i << 2, true);\n }\n }\n else {\n adw = this.adw;\n }\n return adw;\n }\n\n /**\n * restore(adw)\n *\n * This restores the contents of a Memory block from an array of 32-bit values;\n * used by Bus.restoreMemory(), which is called by CPUX86.restore(), after all other\n * components have been restored and thus all Memory blocks have been allocated\n * by their respective components.\n *\n * @this {Memory}\n * @param {Array|null} adw\n * @return {boolean} true if successful, false if block size mismatch\n */\n restore(adw)\n {\n if (this.controller) {\n return (adw == null);\n }\n /*\n * At this point, it's a consistency error for adw to be null; it's happened once already,\n * when there was a restore bug in the Video component that added the frame buffer at the video\n * card's \"spec'ed\" address instead of the programmed address, so there were no controller-owned\n * memory blocks installed at the programmed address, and so we arrived here at a block with\n * no controller AND no data.\n */\n\n\n if (adw && this.size == adw.length << 2) {\n var i;\n if (BYTEARRAYS) {\n var off = 0;\n for (i = 0; i < adw.length; i++) {\n this.ab[off] = adw[i] & 0xff;\n this.ab[off + 1] = (adw[i] >> 8) & 0xff;\n this.ab[off + 2] = (adw[i] >> 16) & 0xff;\n this.ab[off + 3] = (adw[i] >> 24) & 0xff;\n off += 4;\n }\n } else if (TYPEDARRAYS) {\n for (i = 0; i < adw.length; i++) {\n this.dv.setInt32(i << 2, adw[i], true);\n }\n } else {\n this.adw = adw;\n }\n this.fDirty = true;\n return true;\n }\n return false;\n }\n\n /**\n * setAccess(afn, fDirect)\n *\n * The afn parameter should be a 6-entry function table containing two byte handlers, two\n * short handlers, and two long handlers. See the static afnMemory table for an example.\n *\n * If no function table is specified, a default is selected based on the Memory type;\n * similarly, any undefined entries in the table are filled with default handlers that fall\n * back to the byte handlers, and if one or both byte handlers are undefined, they default\n * to handlers that simply ignore the access.\n *\n * fDirect indicates that both the default AND the direct handlers should be updated. Direct\n * handlers normally match the default handlers, except when \"checked\" handlers are installed;\n * this allows \"checked\" handlers to know where to dispatch the call after performing checks.\n * Examples of checks are read/write breakpoints, but it's really up to the Debugger to decide\n * what the check consists of.\n *\n * @this {Memory}\n * @param {Array.<function()>} [afn] function table\n * @param {boolean} [fDirect] (true to update direct access functions as well; default is true)\n */\n setAccess(afn, fDirect)\n {\n if (!afn) {\n if (this.type == Memory.TYPE.UNPAGED) {\n afn = Memory.afnUnpaged;\n }\n else if (this.type == Memory.TYPE.PAGED) {\n afn = Memory.afnPaged;\n } else {\n\n afn = Memory.afnNone;\n }\n }\n this.setReadAccess(afn, fDirect);\n this.setWriteAccess(afn, fDirect);\n }\n\n /**\n * setReadAccess(afn, fDirect)\n *\n * @this {Memory}\n * @param {Array.<function()>} afn\n * @param {boolean} [fDirect]\n */\n setReadAccess(afn, fDirect)\n {\n if (!fDirect || !this.cReadBreakpoints) {\n this.readByte = afn[0] || this.readNone;\n this.readShort = afn[2] || this.readShortDefault;\n this.readLong = afn[4] || this.readLongDefault;\n }\n if (fDirect || fDirect === undefined) {\n this.readByteDirect = afn[0] || this.readNone;\n this.readShortDirect = afn[2] || this.readShortDefault;\n this.readLongDirect = afn[4] || this.readLongDefault;\n }\n }\n\n /**\n * setWriteAccess(afn, fDirect)\n *\n * @this {Memory}\n * @param {Array.<function()>} afn\n * @param {boolean} [fDirect]\n */\n setWriteAccess(afn, fDirect)\n {\n if (!fDirect || !this.cWriteBreakpoints) {\n this.writeByte = !this.fReadOnly && afn[1] || this.writeNone;\n this.writeShort = !this.fReadOnly && afn[3] || this.writeShortDefault;\n this.writeLong = !this.fReadOnly && afn[5] || this.writeLongDefault;\n }\n if (fDirect || fDirect === undefined) {\n this.writeByteDirect = afn[1] || this.writeNone;\n this.writeShortDirect = afn[3] || this.writeShortDefault;\n this.writeLongDirect = afn[5] || this.writeLongDefault;\n }\n }\n\n /**\n * resetReadAccess()\n *\n * @this {Memory}\n */\n resetReadAccess()\n {\n this.readByte = this.readByteDirect;\n this.readShort = this.readShortDirect;\n this.readLong = this.readLongDirect;\n }\n\n /**\n * resetWriteAccess()\n *\n * @this {Memory}\n */\n resetWriteAccess()\n {\n this.writeByte = this.fReadOnly? this.writeNone : this.writeByteDirect;\n this.writeShort = this.fReadOnly? this.writeShortDefault : this.writeShortDirect;\n this.writeLong = this.fReadOnly? this.writeLongDefault : this.writeLongDirect;\n }\n\n /**\n * getPageBlock(addr, fWrite)\n *\n * Called for UNPAGED Memory blocks only.\n *\n * @this {Memory}\n * @param {number} addr\n * @param {boolean} fWrite (true if called for a write, false if for a read)\n * @return {Memory}\n */\n getPageBlock(addr, fWrite)\n {\n /*\n * Even when mapPageBlock() fails (ie, when the page is not present or has insufficient privileges), it\n * will trigger a fault (since we don't set fSuppress), but it will still return a block (ie, an empty block).\n */\n return this.cpu.mapPageBlock(addr, fWrite);\n }\n\n /**\n * setPhysBlock(blockPhys, blockPDE, offPDE, blockPTE, offPTE)\n *\n * @this {Memory}\n * @param {Memory} blockPhys\n * @param {Memory} blockPDE\n * @param {number} offPDE\n * @param {Memory} blockPTE\n * @param {number} offPTE\n */\n setPhysBlock(blockPhys, blockPDE, offPDE, blockPTE, offPTE)\n {\n this.blockPhys = blockPhys;\n this.blockPDE = blockPDE;\n this.iPDE = offPDE >> 2; // convert offPDE into iPDE (an adw index)\n this.blockPTE = blockPTE;\n this.iPTE = offPTE >> 2; // convert offPTE into iPTE (an adw index)\n /*\n * This is an optimization for \"normal\" pages, installing paged memory handlers that mimic\n * normal memory but also know how to update page tables. If any of the criteria are not met\n * for these special handlers, we fall back to the slower default \"paged\" memory handlers.\n */\n if (TYPEDARRAYS && littleEndian && blockPhys.adw && !blockPhys.controller && !blockPhys.cReadBreakpoints && !blockPhys.cWriteBreakpoints) {\n this.ab = blockPhys.ab;\n this.aw = blockPhys.aw;\n this.adw = blockPhys.adw;\n this.setAccess(Memory.afnPagedLE);\n } else {\n this.bitPTEAccessed = blockPhys? Memory.adjustEndian(X86.PTE.ACCESSED) : 0;\n this.bitPTEDirty = blockPhys? Memory.adjustEndian(X86.PTE.ACCESSED | X86.PTE.DIRTY) : 0;\n this.setAccess(Memory.afnPaged);\n }\n }\n\n /**\n * printAddr(sMessage)\n *\n * @this {Memory}\n * @param {string} sMessage\n */\n printAddr(sMessage)\n {\n if (DEBUG && this.dbg && this.dbg.messageEnabled(Messages.MEM)) {\n this.dbg.printMessage(sMessage + ' ' + (this.addr != null? ('%' + Str.toHex(this.addr)) : '#' + this.id), true);\n }\n }\n\n /**\n * addBreakpoint(off, fWrite, cpu)\n *\n * NOTE: Some Memory blocks already require access to the CPU (eg, UNPAGED blocks that need to call cpu.mapPageBlock()),\n * while others require access only if the CPU has set a read or write breakpoint in one of its Debug registers; the latter\n * case is handled here by virtue of the CPU parameter.\n *\n * @this {Memory}\n * @param {number} off\n * @param {boolean} fWrite\n * @param {CPUX86} [cpu] (required for breakpoints set by the CPU, as opposed to the Debugger)\n */\n addBreakpoint(off, fWrite, cpu)\n {\n if (!fWrite) {\n if (this.cReadBreakpoints++ === 0) {\n if (cpu) this.cpu = cpu;\n this.setReadAccess(Memory.afnChecked, false);\n }\n if (DEBUG) this.printAddr(\"read breakpoint added to memory block\");\n }\n else {\n if (this.cWriteBreakpoints++ === 0) {\n if (cpu) this.cpu = cpu;\n this.setWriteAccess(Memory.afnChecked, false);\n }\n if (DEBUG) this.printAddr(\"write breakpoint added to memory block\");\n }\n }\n\n /**\n * removeBreakpoint(off, fWrite)\n *\n * NOTE: If this Memory block is not an UNPAGED block that might need to call cpu.mapPageBlock()), and it no\n * longer has any read or write breakpoints associated with it, then it no longer needs a CPU reference. The\n * existence of a CPU reference only impacts the performance of the \"checked\" memory access functions, so it's\n * not critical to eliminate it.\n *\n * TODO: Another option would be to count CPU references separately from Debugger references, so that when\n * the former goes to zero, we can unconditionally remove the CPU reference; UNPAGED blocks would automatically\n * increment that reference count, so their CPU reference would never go away.\n *\n * @this {Memory}\n * @param {number} off\n * @param {boolean} fWrite\n */\n removeBreakpoint(off, fWrite)\n {\n if (!fWrite) {\n if (--this.cReadBreakpoints === 0) {\n this.resetReadAccess();\n if (DEBUG) this.printAddr(\"all read breakpoints removed from memory block\");\n }\n\n }\n else {\n if (--this.cWriteBreakpoints === 0) {\n this.resetWriteAccess();\n if (DEBUG) this.printAddr(\"all write breakpoints removed from memory block\");\n }\n\n }\n }\n\n /**\n * copyBreakpoints(dbg, mem)\n *\n * @this {Memory}\n * @param {DebuggerX86} [dbg]\n * @param {Memory} [mem] (outgoing Memory block to copy breakpoints from, if any)\n */\n copyBreakpoints(dbg, mem)\n {\n this.dbg = dbg;\n this.cReadBreakpoints = this.cWriteBreakpoints = 0;\n if (mem) {\n if (mem.cpu) this.cpu = mem.cpu;\n if ((this.cReadBreakpoints = mem.cReadBreakpoints)) {\n this.setReadAccess(Memory.afnChecked, false);\n }\n if ((this.cWriteBreakpoints = mem.cWriteBreakpoints)) {\n this.setWriteAccess(Memory.afnChecked, false);\n }\n }\n }\n\n /**\n * readNone(off)\n *\n * Previously, this always returned 0x00, but the initial memory probe by the COMPAQ DeskPro 386 ROM BIOS\n * writes 0x0000 to the first word of every 64Kb block in the nearly 16Mb address space it supports, and\n * if it reads back 0x0000, it will initially think that LOTS of RAM exists, only to be disappointed later\n * when it performs a more exhaustive memory test, generating unwanted error messages in the process.\n *\n * TODO: Determine if we should have separate readByteNone(), readShortNone() and readLongNone() functions\n * to return 0xff, 0xffff and 0xffffffff|0, respectively. This seems sufficient for now, as it seems unlikely\n * that a system would require nonexistent memory locations to return ALL bits set.\n *\n * Also, I'm reluctant to address that potential issue by simply returning -1, because to date, the above\n * Memory interfaces have always returned values that are properly masked to 8, 16 or 32 bits, respectively.\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readNone(off, addr)\n {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages.CPU | Messages.MEM) /* && !off */) {\n this.dbg.message(\"attempt to read invalid block %\" + Str.toHex(addr), true);\n }\n return 0xff;\n }\n\n /**\n * writeNone(off, v, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} v (could be either a byte or word value, since we use the same handler for both kinds of accesses)\n * @param {number} addr\n */\n writeNone(off, v, addr)\n {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages.CPU | Messages.MEM) /* && !off */) {\n this.dbg.message(\"attempt to write \" + Str.toHexWord(v) + \" to invalid block %\" + Str.toHex(addr), true);\n }\n }\n\n /**\n * readShortDefault(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortDefault(off, addr)\n {\n return this.readByte(off++, addr++) | (this.readByte(off, addr) << 8);\n }\n\n /**\n * readLongDefault(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readLongDefault(off, addr)\n {\n return this.readByte(off++, addr++) | (this.readByte(off++, addr++) << 8) | (this.readByte(off++, addr++) << 16) | (this.readByte(off, addr) << 24);\n }\n\n /**\n * writeShortDefault(off, w, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeShortDefault(off, w, addr)\n {\n this.writeByte(off++, w & 0xff, addr++);\n this.writeByte(off, w >> 8, addr);\n }\n\n /**\n * writeLongDefault(off, w, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeLongDefault(off, w, addr)\n {\n this.writeByte(off++, w & 0xff, addr++);\n this.writeByte(off++, (w >> 8) & 0xff, addr++);\n this.writeByte(off++, (w >> 16) & 0xff, addr++);\n this.writeByte(off, (w >>> 24), addr);\n }\n\n /**\n * readByteMemory(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteMemory(off, addr)\n {\n if (BYTEARRAYS) {\n return this.ab[off];\n }\n return ((this.adw[off >> 2] >>> ((off & 0x3) << 3)) & 0xff);\n }\n\n /**\n * readShortMemory(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortMemory(off, addr)\n {\n if (BYTEARRAYS) {\n return this.ab[off] | (this.ab[off + 1] << 8);\n }\n var w;\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n var dw = (this.adw[idw] >> nShift);\n if (nShift < 24) {\n w = dw & 0xffff;\n } else {\n w = (dw & 0xff) | ((this.adw[idw + 1] & 0xff) << 8);\n }\n return w;\n }\n\n /**\n * readLongMemory(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readLongMemory(off, addr)\n {\n if (BYTEARRAYS) {\n return this.ab[off] | (this.ab[off + 1] << 8) | (this.ab[off + 2] << 16) | (this.ab[off + 3] << 24);\n }\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n var l = this.adw[idw];\n if (nShift) {\n l >>>= nShift;\n l |= this.adw[idw + 1] << (32 - nShift);\n }\n return l;\n }\n\n /**\n * writeByteMemory(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b\n * @param {number} addr\n */\n writeByteMemory(off, b, addr)\n {\n if (BYTEARRAYS) {\n this.ab[off] = b;\n } else {\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n this.adw[idw] = (this.adw[idw] & ~(0xff << nShift)) | (b << nShift);\n }\n this.fDirty = true;\n }\n\n /**\n * writeShortMemory(off, w, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeShortMemory(off, w, addr)\n {\n if (BYTEARRAYS) {\n this.ab[off] = (w & 0xff);\n this.ab[off + 1] = (w >> 8);\n } else {\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n if (nShift < 24) {\n this.adw[idw] = (this.adw[idw] & ~(0xffff << nShift)) | (w << nShift);\n } else {\n this.adw[idw] = (this.adw[idw] & 0x00ffffff) | (w << 24);\n idw++;\n this.adw[idw] = (this.adw[idw] & (0xffffff00|0)) | (w >> 8);\n }\n }\n this.fDirty = true;\n }\n\n /**\n * writeLongMemory(off, l, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} l\n * @param {number} addr\n */\n writeLongMemory(off, l, addr)\n {\n if (BYTEARRAYS) {\n this.ab[off] = (l & 0xff);\n this.ab[off + 1] = (l >> 8) & 0xff;\n this.ab[off + 2] = (l >> 16) & 0xff;\n this.ab[off + 3] = (l >> 24) & 0xff;\n } else {\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n if (!nShift) {\n this.adw[idw] = l;\n } else {\n var mask = (0xffffffff|0) << nShift;\n this.adw[idw] = (this.adw[idw] & ~mask) | (l << nShift);\n idw++;\n this.adw[idw] = (this.adw[idw] & mask) | (l >>> (32 - nShift));\n }\n }\n this.fDirty = true;\n }\n\n /**\n * readByteChecked(off, addr)\n *\n * NOTE: When we're called in the context of a PAGED block (eg, with one or more DEBUGGER breakpoints set),\n * the checkMemory functions need \"this.addr + off\" rather than \"addr\", because the former will be the physical\n * address rather than the linear address.\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteChecked(off, addr)\n {\n if (!DEBUGGER || !this.dbg || this.addr == null || !this.dbg.checkMemoryRead(this.addr + off)) {\n if (I386 && this.cpu) this.cpu.checkMemoryException(addr, 1, false);\n }\n return this.readByteDirect(off, addr);\n }\n\n /**\n * readShortChecked(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortChecked(off, addr)\n {\n if (!DEBUGGER || !this.dbg || this.addr == null || !this.dbg.checkMemoryRead(this.addr + off, 2)) {\n if (I386 && this.cpu) this.cpu.checkMemoryException(addr, 2, false);\n }\n return this.readShortDirect(off, addr);\n }\n\n /**\n * readLongChecked(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readLongChecked(off, addr)\n {\n if (!DEBUGGER || !this.dbg || this.addr == null || !this.dbg.checkMemoryRead(this.addr + off, 4)) {\n if (I386 && this.cpu) this.cpu.checkMemoryException(addr, 4, false);\n }\n return this.readLongDirect(off, addr);\n }\n\n /**\n * writeByteChecked(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @param {number} b\n */\n writeByteChecked(off, b, addr)\n {\n if (!DEBUGGER || !this.dbg || this.addr == null || !this.dbg.checkMemoryWrite(this.addr + off)) {\n if (I386 && this.cpu) this.cpu.checkMemoryException(addr, 1, true);\n }\n if (this.fReadOnly) this.writeNone(off, b, addr); else this.writeByteDirect(off, b, addr);\n }\n\n /**\n * writeShortChecked(off, w, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @param {number} w\n */\n writeShortChecked(off, w, addr)\n {\n if (!DEBUGGER || !this.dbg || this.addr == null || !this.dbg.checkMemoryWrite(this.addr + off, 2)) {\n if (I386 && this.cpu) this.cpu.checkMemoryException(addr, 2, true);\n }\n if (this.fReadOnly) this.writeNone(off, w, addr); else this.writeShortDirect(off, w, addr);\n }\n\n /**\n * writeLongChecked(off, l, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} l\n * @param {number} addr\n */\n writeLongChecked(off, l, addr)\n {\n if (!DEBUGGER || !this.dbg || this.addr == null || !this.dbg.checkMemoryWrite(this.addr + off, 4)) {\n if (I386 && this.cpu) this.cpu.checkMemoryException(addr, 4, true);\n }\n if (this.fReadOnly) this.writeNone(off, l, addr); else this.writeLongDirect(off, l, addr);\n }\n\n /**\n * readBytePaged(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readBytePaged(off, addr)\n {\n this.blockPDE.adw[this.iPDE] |= this.bitPTEAccessed;\n this.blockPTE.adw[this.iPTE] |= this.bitPTEAccessed;\n return this.blockPhys.readByte(off, addr);\n }\n\n /**\n * readShortPaged(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortPaged(off, addr)\n {\n this.blockPDE.adw[this.iPDE] |= this.bitPTEAccessed;\n this.blockPTE.adw[this.iPTE] |= this.bitPTEAccessed;\n return this.blockPhys.readShort(off, addr);\n }\n\n /**\n * readLongPaged(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readLongPaged(off, addr)\n {\n this.blockPDE.adw[this.iPDE] |= this.bitPTEAccessed;\n this.blockPTE.adw[this.iPTE] |= this.bitPTEAccessed;\n return this.blockPhys.readLong(off, addr);\n }\n\n /**\n * writeBytePaged(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b\n * @param {number} addr\n */\n writeBytePaged(off, b, addr)\n {\n this.blockPDE.adw[this.iPDE] |= this.bitPTEAccessed;\n this.blockPTE.adw[this.iPTE] |= this.bitPTEDirty;\n this.blockPhys.writeByte(off, b, addr);\n }\n\n /**\n * writeShortPaged(off, w, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeShortPaged(off, w, addr)\n {\n this.blockPDE.adw[this.iPDE] |= this.bitPTEAccessed;\n this.blockPTE.adw[this.iPTE] |= this.bitPTEDirty;\n this.blockPhys.writeShort(off, w, addr);\n }\n\n /**\n * writeLongPaged(off, l, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} l\n * @param {number} addr\n */\n writeLongPaged(off, l, addr)\n {\n this.blockPDE.adw[this.iPDE] |= this.bitPTEAccessed;\n this.blockPTE.adw[this.iPTE] |= this.bitPTEDirty;\n this.blockPhys.writeLong(off, l, addr);\n }\n\n /**\n * readByteUnpaged(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteUnpaged(off, addr)\n {\n return this.getPageBlock(addr, false).readByte(off, addr);\n }\n\n /**\n * readShortUnpaged(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortUnpaged(off, addr)\n {\n return this.getPageBlock(addr, false).readShort(off, addr);\n }\n\n /**\n * readLongUnpaged(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readLongUnpaged(off, addr)\n {\n return this.getPageBlock(addr, false).readLong(off, addr);\n }\n\n /**\n * writeByteUnpaged(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b\n * @param {number} addr\n */\n writeByteUnpaged(off, b, addr)\n {\n this.getPageBlock(addr, true).writeByte(off, b, addr);\n }\n\n /**\n * writeShortUnpaged(off, w, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeShortUnpaged(off, w, addr)\n {\n this.getPageBlock(addr, true).writeShort(off, w, addr);\n }\n\n /**\n * writeLongUnpaged(off, l, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} l\n * @param {number} addr\n */\n writeLongUnpaged(off, l, addr)\n {\n this.getPageBlock(addr, true).writeLong(off, l, addr);\n }\n\n /**\n * readByteBE(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteBE(off, addr)\n {\n return this.ab[off];\n }\n\n /**\n * readByteLE(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteLE(off, addr)\n {\n return this.ab[off];\n }\n\n /**\n * readBytePLE(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readBytePLE(off, addr)\n {\n this.blockPDE.adw[this.iPDE] |= X86.PTE.ACCESSED;\n this.blockPTE.adw[this.iPTE] |= X86.PTE.ACCESSED;\n /*\n * TODO: Review this performance hack. Basically, after the first read of a page,\n * we redirect the default read handler to a faster handler. However, if operating\n * systems clear the PDE/PTE bits without reloading CR3, they won't get set again.\n *\n * We should look into creating special write handlers for pages containing PDE/PTE\n * entries, and whenever those entries are written, reset the read/write handlers\n * for the corresponding pages.\n */\n this.readByte = this.readByteLE;\n return this.ab[off];\n }\n\n /**\n * readShortBE(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortBE(off, addr)\n {\n return this.dv.getUint16(off, true);\n }\n\n /**\n * readShortLE(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortLE(off, addr)\n {\n /*\n * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned read\n * vs. always reading the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.\n */\n return (off & 0x1)? (this.ab[off] | (this.ab[off+1] << 8)) : this.aw[off >> 1];\n }\n\n /**\n * readShortPLE(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortPLE(off, addr)\n {\n /*\n * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned read\n * vs. always reading the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.\n */\n this.blockPDE.adw[this.iPDE] |= X86.PTE.ACCESSED;\n this.blockPTE.adw[this.iPTE] |= X86.PTE.ACCESSED;\n /*\n * TODO: Review this performance hack. Basically, after the first read of a page,\n * we redirect the default read handler to a faster handler. However, if operating\n * systems clear the PDE/PTE bits without reloading CR3, they won't get set again.\n *\n * We should look into creating special write handlers for pages containing PDE/PTE\n * entries, and whenever those entries are written, reset the read/write handlers\n * for the corresponding pages.\n */\n this.readShort = this.readShortLE;\n return (off & 0x1)? (this.ab[off] | (this.ab[off+1] << 8)) : this.aw[off >> 1];\n }\n\n /**\n * readLongBE(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readLongBE(off, addr)\n {\n return this.dv.getInt32(off, true);\n }\n\n /**\n * readLongLE(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readLongLE(off, addr)\n {\n /*\n * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned read\n * vs. always reading the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.\n */\n return (off & 0x3)? (this.ab[off] | (this.ab[off+1] << 8) | (this.ab[off+2] << 16) | (this.ab[off+3] << 24)) : this.adw[off >> 2];\n }\n\n /**\n * readLongPLE(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readLongPLE(off, addr)\n {\n /*\n * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned read\n * vs. always reading the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.\n */\n this.blockPDE.adw[this.iPDE] |= X86.PTE.ACCESSED;\n this.blockPTE.adw[this.iPTE] |= X86.PTE.ACCESSED;\n /*\n * TODO: Review this performance hack. Basically, after the first read of a page,\n * we redirect the default read handler to a faster handler. However, if operating\n * systems clear the PDE/PTE bits without reloading CR3, they won't get set again.\n *\n * We should look into creating special write handlers for pages containing PDE/PTE\n * entries, and whenever those entries are written, reset the read/write handlers\n * for the corresponding pages.\n */\n this.readLong = this.readLongLE;\n return (off & 0x3)? (this.ab[off] | (this.ab[off+1] << 8) | (this.ab[off+2] << 16) | (this.ab[off+3] << 24)) : this.adw[off >> 2];\n }\n\n /**\n * writeByteBE(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b\n * @param {number} addr\n */\n writeByteBE(off, b, addr)\n {\n this.ab[off] = b;\n this.fDirty = true;\n }\n\n /**\n * writeByteLE(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @param {number} b\n */\n writeByteLE(off, b, addr)\n {\n this.ab[off] = b;\n this.fDirty = true;\n }\n\n /**\n * writeBytePLE(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @param {number} b\n */\n writeBytePLE(off, b, addr)\n {\n this.ab[off] = b;\n this.blockPDE.adw[this.iPDE] |= X86.PTE.ACCESSED;\n this.blockPTE.adw[this.iPTE] |= X86.PTE.ACCESSED | X86.PTE.DIRTY;\n /*\n * TODO: Review this performance hack. Basically, after the first write of a page,\n * we redirect the default write handler to a faster handler. However, if operating\n * systems clear the PDE/PTE bits without reloading CR3, they won't get set again.\n *\n * We should look into creating special write handlers for pages containing PDE/PTE\n * entries, and whenever those entries are written, reset the read/write handlers\n * for the corresponding pages.\n */\n this.writeByte = this.writeByteLE;\n /*\n * NOTE: Technically, we should be setting the fDirty flag on blockPDE and blockPTE as well, but let's\n * consider the two sole uses of fDirty. First, we have cleanMemory(), which is currently used only by\n * the Video component, and video memory should never contain page directories or page tables, so no\n * worries there. Second, we have saveMemory(), but the CPU now asks that function to save all physical\n * memory blocks whenever paging is enabled, so no worries there either.\n */\n this.blockPhys.fDirty = true;\n }\n\n /**\n * writeShortBE(off, w, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @param {number} w\n */\n writeShortBE(off, w, addr)\n {\n this.dv.setUint16(off, w, true);\n this.fDirty = true;\n }\n\n /**\n * writeShortLE(off, w, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @param {number} w\n */\n writeShortLE(off, w, addr)\n {\n /*\n * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned write\n * vs. always writing the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.\n */\n if (off & 0x1) {\n this.ab[off] = w;\n this.ab[off+1] = w >> 8;\n } else {\n this.aw[off >> 1] = w;\n }\n this.fDirty = true;\n }\n\n /**\n * writeShortPLE(off, w, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @param {number} w\n */\n writeShortPLE(off, w, addr)\n {\n /*\n * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned write\n * vs. always writing the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.\n */\n if (off & 0x1) {\n this.ab[off] = w;\n this.ab[off+1] = w >> 8;\n } else {\n this.aw[off >> 1] = w;\n }\n this.blockPDE.adw[this.iPDE] |= X86.PTE.ACCESSED;\n this.blockPTE.adw[this.iPTE] |= X86.PTE.ACCESSED | X86.PTE.DIRTY;\n /*\n * TODO: Review this performance hack. Basically, after the first write of a page,\n * we redirect the default write handler to a faster handler. However, if operating\n * systems clear the PDE/PTE bits without reloading CR3, they won't get set again.\n *\n * We should look into creating special write handlers for pages containing PDE/PTE\n * entries, and whenever those entries are written, reset the read/write handlers\n * for the corresponding pages.\n */\n this.writeShort = this.writeShortLE;\n /*\n * NOTE: Technically, we should be setting the fDirty flag on blockPDE and blockPTE as well, but let's\n * consider the two sole uses of fDirty. First, we have cleanMemory(), which is currently used only by\n * the Video component, and video memory should never contain page directories or page tables, so no\n * worries there. Second, we have saveMemory(), but the CPU now asks that function to save all physical\n * memory blocks whenever paging is enabled, so no worries there either.\n */\n this.blockPhys.fDirty = true;\n }\n\n /**\n * writeLongBE(off, l, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} l\n * @param {number} addr\n */\n writeLongBE(off, l, addr)\n {\n this.dv.setInt32(off, l, true);\n this.fDirty = true;\n }\n\n /**\n * writeLongLE(off, l, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} l\n * @param {number} addr\n */\n writeLongLE(off, l, addr)\n {\n /*\n * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned write\n * vs. always writing the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.\n */\n if (off & 0x3) {\n this.ab[off] = l;\n this.ab[off+1] = (l >> 8);\n this.ab[off+2] = (l >> 16);\n this.ab[off+3] = (l >> 24);\n } else {\n this.adw[off >> 2] = l;\n }\n this.fDirty = true;\n }\n\n /**\n * writeLongPLE(off, l, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} l\n * @param {number} addr\n */\n writeLongPLE(off, l, addr)\n {\n /*\n * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned write\n * vs. always writing the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.\n */\n if (off & 0x3) {\n this.ab[off] = l;\n this.ab[off+1] = (l >> 8);\n this.ab[off+2] = (l >> 16);\n this.ab[off+3] = (l >> 24);\n } else {\n this.adw[off >> 2] = l;\n }\n this.blockPDE.adw[this.iPDE] |= X86.PTE.ACCESSED;\n this.blockPTE.adw[this.iPTE] |= X86.PTE.ACCESSED | X86.PTE.DIRTY;\n /*\n * TODO: Review this performance hack. Basically, after the first write of a page,\n * we redirect the default write handler to a faster handler. However, if operating\n * systems clear the PDE/PTE bits without reloading CR3, they won't get set again.\n *\n * We should look into creating special write handlers for pages containing PDE/PTE\n * entries, and whenever those entries are written, reset the read/write handlers\n * for the corresponding pages.\n */\n this.writeLong = this.writeLongLE;\n /*\n * NOTE: Technically, we should be setting the fDirty flag on blockPDE and blockPTE as well, but let's\n * consider the two sole uses of fDirty. First, we have cleanMemory(), which is currently used only by\n * the Video component, and video memory should never contain page directories or page tables, so no\n * worries there. Second, we have saveMemory(), but the CPU now asks that function to save all physical\n * memory blocks whenever paging is enabled, so no worries there either.\n */\n this.blockPhys.fDirty = true;\n }\n\n /**\n * readBackTrackNone(off)\n *\n * @this {Memory}\n * @param {number} off\n * @return {number}\n */\n readBackTrackNone(off)\n {\n return 0;\n }\n\n /**\n * writeBackTrackNone(off, bti)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} bti\n */\n writeBackTrackNone(off, bti)\n {\n }\n\n /**\n * modBackTrackNone(fMod)\n *\n * @this {Memory}\n * @param {boolean} fMod\n */\n modBackTrackNone(fMod)\n {\n return false;\n }\n\n /**\n * readBackTrackIndex(off)\n *\n * @this {Memory}\n * @param {number} off\n * @return {number}\n */\n readBackTrackIndex(off)\n {\n return this.abtIndexes[off];\n }\n\n /**\n * writeBackTrackIndex(off, bti)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} bti\n * @return {number} previous bti (0 if none)\n */\n writeBackTrackIndex(off, bti)\n {\n var btiPrev;\n btiPrev = this.abtIndexes[off];\n this.abtIndexes[off] = bti;\n return btiPrev;\n }\n\n /**\n * modBackTrackIndex(fMod)\n *\n * @this {Memory}\n * @param {boolean} fMod\n * @return {boolean} previous value\n */\n modBackTrackIndex(fMod)\n {\n var fModPrev = this.fModBackTrack;\n this.fModBackTrack = fMod;\n return fModPrev;\n }\n\n /**\n * adjustEndian(dw)\n *\n * @param {number} dw\n * @return {number}\n */\n static adjustEndian(dw)\n {\n if (TYPEDARRAYS && !littleEndian) {\n dw = (dw << 24) | ((dw << 8) & 0x00ff0000) | ((dw >> 8) & 0x0000ff00) | (dw >>> 24);\n }\n return dw;\n }\n}\n\n/*\n * Basic memory types\n *\n * RAM is the most conventional memory type, providing full read/write capability to x86-compatible (ie,\n * 'little endian\") storage. ROM is equally conventional, except that the fReadOnly property is set,\n * disabling writes. VIDEO is treated exactly like RAM, unless a controller is provided. Both RAM and\n * VIDEO memory are always considered writable, and even ROM can be written using the Bus setByteDirect()\n * interface (which in turn uses the Memory writeByteDirect() interface), allowing the ROM component to\n * initialize its own memory. The CTRL type is used to identify memory-mapped devices that do not need\n * any default storage and always provide their own controller.\n *\n * UNPAGED and PAGED blocks are created by the CPU when paging is enabled; the role of an UNPAGED block\n * is simply to perform page translation and replace itself with a PAGED block, which redirects read/write\n * requests to the physical page located during translation. UNPAGED and PAGED blocks are considered\n * \"logical\" blocks that don't contain any storage of their own; all other block types represent \"physical\"\n * memory (or a memory-mapped device).\n *\n * Unallocated regions of the address space contain a special memory block of type NONE that contains\n * no storage. Mapping every addressible location to a memory block allows all accesses to be routed in\n * exactly the same manner, without resorting to any range or processor checks.\n *\n * Originally, the Debugger always went through the Bus interfaces, and could therefore modify ROMs as well,\n * but with the introduction of protected mode memory segmentation (and later paging), where logical and\n * physical addresses were no longer the same, that is no longer true. For coherency, all Debugger memory\n * accesses now go through SegX86 and CPUX86 memory interfaces, so that the user sees the same segment\n * and page translation that the CPU sees. However, the Debugger uses a special probeAddr() interface to\n * read memory, along with a special \"fSuppress\" flag to mapPageBlock(), to prevent its memory accesses\n * from triggering segment and/or page faults when invalid or not-present segments or pages are accessed.\n *\n * These types are not mutually exclusive. For example, VIDEO memory could be allocated as RAM, with or\n * without a custom controller (the original Monochrome and CGA video cards used read/write storage that\n * was indistinguishable from RAM), and CTRL memory could be allocated as an empty block of any type, with\n * a custom controller. A few types are required for certain features (eg, ROM is required if you want\n * read-only memory), but the larger purpose of these types is to help document the caller's intent and to\n * provide the Control Panel with the ability to highlight memory regions accordingly.\n */\nMemory.TYPE = {\n NONE: 0,\n RAM: 1,\n ROM: 2,\n VIDEO: 3,\n CTRL: 4,\n UNPAGED: 5,\n PAGED: 6,\n COLORS: [\"black\", \"blue\", \"green\", \"cyan\"],\n NAMES: [\"NONE\", \"RAM\", \"ROM\", \"VIDEO\", \"H/W\", \"UNPAGED\", \"PAGED\"]\n};\n\n/*\n * Last used block ID (used for debugging only)\n */\nMemory.idBlock = 0;\n\n\n/*\n * This is the effective definition of afnNone, but we need not fully define it, because setAccess() uses these\n * defaults when any of the 6 handlers (ie, 2 byte handlers, 2 short handlers, and 2 long handlers) are undefined.\n *\nMemory.afnNone = [\n Memory.prototype.readNone,\n Memory.prototype.writeNone,\n Memory.prototype.readShortDefault,\n Memory.prototype.writeShortDefault,\n Memory.prototype.readLongDefault,\n Memory.prototype.writeLongDefault\n];\n */\nMemory.afnNone = [];\n\nMemory.afnMemory = [\n Memory.prototype.readByteMemory,\n Memory.prototype.writeByteMemory,\n Memory.prototype.readShortMemory,\n Memory.prototype.writeShortMemory,\n Memory.prototype.readLongMemory,\n Memory.prototype.writeLongMemory\n];\n\nMemory.afnChecked = [\n Memory.prototype.readByteChecked,\n Memory.prototype.writeByteChecked,\n Memory.prototype.readShortChecked,\n Memory.prototype.writeShortChecked,\n Memory.prototype.readLongChecked,\n Memory.prototype.writeLongChecked\n];\n\nif (PAGEBLOCKS) {\n Memory.afnPaged = [\n Memory.prototype.readBytePaged,\n Memory.prototype.writeBytePaged,\n Memory.prototype.readShortPaged,\n Memory.prototype.writeShortPaged,\n Memory.prototype.readLongPaged,\n Memory.prototype.writeLongPaged\n ];\n\n Memory.afnUnpaged = [\n Memory.prototype.readByteUnpaged,\n Memory.prototype.writeByteUnpaged,\n Memory.prototype.readShortUnpaged,\n Memory.prototype.writeShortUnpaged,\n Memory.prototype.readLongUnpaged,\n Memory.prototype.writeLongUnpaged\n ];\n}\n\nif (TYPEDARRAYS) {\n Memory.afnArrayBE = [\n Memory.prototype.readByteBE,\n Memory.prototype.writeByteBE,\n Memory.prototype.readShortBE,\n Memory.prototype.writeShortBE,\n Memory.prototype.readLongBE,\n Memory.prototype.writeLongBE\n ];\n\n Memory.afnArrayLE = [\n Memory.prototype.readByteLE,\n Memory.prototype.writeByteLE,\n Memory.prototype.readShortLE,\n Memory.prototype.writeShortLE,\n Memory.prototype.readLongLE,\n Memory.prototype.writeLongLE\n ];\n\n Memory.afnPagedLE = [\n Memory.prototype.readBytePLE,\n Memory.prototype.writeBytePLE,\n Memory.prototype.readShortPLE,\n Memory.prototype.writeShortPLE,\n Memory.prototype.readLongPLE,\n Memory.prototype.writeLongPLE\n ];\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/cpu.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * class CPU\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass CPU extends Component {\n /**\n * CPU(parmsCPU, nCyclesDefault)\n *\n * The CPU class supports the following (parmsCPU) properties:\n *\n * cycles: the machine's base cycles per second; the CPUX86 constructor will provide us with a default\n * (based on the CPU model) to use as a fallback.\n *\n * multiplier: base cycle multiplier; default is 1.\n *\n * autoStart: true to automatically start, false to not, or null if \"it depends\"; null is the default,\n * which means autostart UNLESS there is a Debugger present.\n *\n * csStart: the number of cycles that runCPU() must wait before generating checksum records;\n * -1 if disabled. checksum records are a diagnostic aid used to help compare one CPU run to another.\n *\n * csInterval: the number of cycles that runCPU() must execute before generating a checksum record;\n * -1 if disabled.\n *\n * csStop: the number of cycles to stop generating checksum records.\n *\n * This component is primarily responsible for interfacing the CPU with the outside world (eg, Panel and Debugger\n * components), and managing overall CPU operation.\n *\n * It is extended by the CPUX86 component, where all the x86-specific logic resides.\n *\n * @this {CPU}\n * @param {Object} parmsCPU\n * @param {number} nCyclesDefault\n */\n constructor(parmsCPU, nCyclesDefault)\n {\n super(\"CPU\", parmsCPU, Messages.CPU);\n\n var nCycles = parmsCPU['cycles'] || nCyclesDefault;\n\n var nMultiplier = parmsCPU['multiplier'] || 1;\n\n this.counts = {};\n this.counts.nBaseCyclesPerSecond = nCycles;\n this.counts.msPerYield = Math.round(1000 / CPU.YIELDS_PER_SECOND);\n\n /*\n * nTargetMultiplier replaces the old \"speed\" variable (0, 1, 2) and eliminates the need for\n * the constants (SPEED_SLOW, SPEED_FAST and SPEED_MAX). The UI simply doubles the target multiplier\n * until we've exceeded the host's speed limit (ie, the current value is unable to reach the target),\n * at which point we reset the target back to the default.\n */\n this.counts.nBaseMultiplier = this.counts.nCurrentMultiplier = this.counts.nTargetMultiplier = nMultiplier;\n this.counts.mhzBase = Math.round(this.counts.nBaseCyclesPerSecond / 10000) / 100;\n this.counts.mhzCurrent = this.counts.mhzTarget = this.counts.mhzBase * this.counts.nTargetMultiplier;\n\n /*\n * We add a number of flags to those initialized by Component.\n */\n this.flags.starting = this.flags.running = this.flags.yield = false;\n this.flags.autoStart = parmsCPU['autoStart'];\n\n /*\n * TODO: Add some UI for displayLiveRegs (either an XML property, or a UI checkbox, or both)\n */\n this.flags.displayLiveRegs = false;\n\n /*\n * Get checksum parameters, if any. runCPU() behavior is not affected until fChecksum\n * is true, which won't happen until resetChecksum() is called with nCyclesChecksumInterval\n * (\"csInterval\") set to a positive value.\n *\n * As above, any of these parameters can also be set with the Debugger's execution options\n * command (\"x\"); for example, \"x cs int 5000\" will set nCyclesChecksumInterval to 5000\n * and call resetChecksum().\n */\n this.flags.checksum = false;\n this.counts.nChecksum = this.counts.nCyclesChecksumNext = 0;\n this.counts.nCyclesChecksumStart = parmsCPU[\"csStart\"];\n this.counts.nCyclesChecksumInterval = parmsCPU[\"csInterval\"];\n this.counts.nCyclesChecksumStop = parmsCPU[\"csStop\"];\n\n /*\n * Array of countdown timers managed by addTimer() and setTimer().\n *\n * See also: getMSCycles(), getBurstCycles(), saveTimers(), restoreTimers(), and updateTimers()\n */\n this.aTimers = [];\n\n this.idRunTimeout = 0;\n this.onRunTimeout = this.runCPU.bind(this); // function onRunTimeout() { cpu.runCPU(); };\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {CPU}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPU} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.dbg = dbg;\n\n for (var i = 0; i < CPU.BUTTONS.length; i++) {\n var control = this.bindings[CPU.BUTTONS[i]];\n if (control) this.cmp.setBinding(null, CPU.BUTTONS[i], control);\n }\n\n this.fpu = cmp.getMachineComponent(\"FPU\");\n\n /*\n * Attach the ChipSet component to the CPU so that it can obtain the IDT vector number\n * of pending hardware interrupts in response to the ChipSet's updateINTR() notifications.\n *\n * We must also call chipset.updateAllTimers() periodically; stepCPU() takes care of that.\n */\n this.chipset = cmp.getMachineComponent(\"ChipSet\");\n\n /*\n * We've already saved the parmsCPU 'autoStart' setting, but there may be a machine (or URL) override.\n */\n var sAutoStart = cmp.getMachineParm('autoStart');\n if (sAutoStart != null) {\n this.flags.autoStart = (sAutoStart == \"true\"? true : (sAutoStart == \"false\"? false : !!sAutoStart));\n }\n\n this.timerYield = cpu.addTimer(this.id, function yieldTimer() {\n cpu.flags.yield = true;\n }, this.counts.msPerYield);\n\n this.setReady();\n }\n\n /**\n * reset()\n *\n * This is a placeholder for reset (overridden by the CPUX86 component).\n *\n * @this {CPU}\n */\n reset()\n {\n }\n\n /**\n * save(fRunning)\n *\n * This is a placeholder for save support (overridden by the CPUX86 component).\n *\n * @this {CPU}\n * @param {boolean} [fRunning]\n * @return {Object|null}\n */\n save(fRunning)\n {\n return null;\n }\n\n /**\n * restore(data)\n *\n * This is a placeholder for restore support (overridden by the CPUX86 component).\n *\n * @this {CPU}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n return false;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {CPU}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data || !this.restore) {\n this.reset();\n } else {\n this.resetCycles();\n if (!this.restore(data)) return false;\n this.resetChecksum();\n }\n /*\n * Give the Debugger a chance to do/print something once we've powered up\n */\n if (DEBUGGER && this.dbg) {\n this.dbg.init();\n } else {\n this.println(\"No debugger detected\");\n }\n }\n /*\n * The Computer component (which is responsible for all powerDown and powerUp notifications)\n * is now responsible for managing a component's fPowered flag, not us.\n *\n * this.flags.powered = true;\n */\n this.updateCPU();\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {CPU}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n /*\n * The Computer component (which is responsible for all powerDown and powerUp notifications)\n * is now responsible for managing a component's fPowered flag, not us.\n *\n * this.flags.powered = false;\n */\n var fRunning = this.flags.running;\n if (fShutdown) this.stopCPU();\n return fSave? this.save(fRunning) : true;\n }\n\n /**\n * autoStart()\n *\n * @this {CPU}\n * @return {boolean} true if started, false if not\n */\n autoStart()\n {\n if (this.flags.running) {\n return true;\n }\n /*\n * Start running automatically on power-up, assuming there's no Debugger. \n */\n if (this.flags.autoStart || this.flags.autoStart == null && !this.dbg) {\n /*\n * Automatically updating focus when calling startCPU() is a double-edged sword, potentially interfering\n * with the user's attention, which is why we also set fQuiet, to try to prevent the page from \"auto-scrolling\"\n * the newly focused machine into view. \n */\n return this.startCPU(true, true);\n }\n return false;\n }\n\n /**\n * isPowered()\n *\n * @this {CPU}\n * @return {boolean}\n */\n isPowered()\n {\n if (!this.flags.powered) {\n this.println(this.toString() + \" not powered\");\n return false;\n }\n return true;\n }\n\n /**\n * isRunning()\n *\n * @this {CPU}\n * @return {boolean}\n */\n isRunning()\n {\n return this.flags.running;\n }\n\n /**\n * getChecksum()\n *\n * This will be implemented by the CPUX86 component.\n *\n * @this {CPU}\n * @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code)\n */\n getChecksum()\n {\n return 0;\n }\n\n /**\n * resetChecksum()\n *\n * If checksum generation is enabled (fChecksum is true), this resets the running 32-bit checksum and the\n * cycle counter that will trigger the next displayChecksum(); called by resetCycles(), which is called whenever\n * the CPU is reset or restored.\n *\n * @this {CPU}\n * @return {boolean} true if checksum generation enabled, false if not\n */\n resetChecksum()\n {\n if (this.counts.nCyclesChecksumStart === undefined) this.counts.nCyclesChecksumStart = 0;\n if (this.counts.nCyclesChecksumInterval === undefined) this.counts.nCyclesChecksumInterval = -1;\n if (this.counts.nCyclesChecksumStop === undefined) this.counts.nCyclesChecksumStop = -1;\n this.flags.checksum = (this.counts.nCyclesChecksumStart >= 0 && this.counts.nCyclesChecksumInterval > 0);\n if (this.flags.checksum) {\n this.counts.nChecksum = 0;\n this.counts.nCyclesChecksumNext = this.counts.nCyclesChecksumStart - this.nTotalCycles;\n /*\n * this.counts.nCyclesChecksumNext = this.counts.nCyclesChecksumStart + this.counts.nCyclesChecksumInterval -\n * (this.nTotalCycles % this.counts.nCyclesChecksumInterval);\n */\n return true;\n }\n return false;\n }\n\n /**\n * updateChecksum(nCycles)\n *\n * When checksum generation is enabled (fChecksum is true), runCPU() asks stepCPU() to execute a minimum\n * number of cycles (1), effectively limiting execution to a single instruction, and then we're called with\n * the exact number cycles that were actually executed. This should give us instruction-granular checksums\n * at precise intervals that are 100% repeatable.\n *\n * @this {CPU}\n * @param {number} nCycles\n */\n updateChecksum(nCycles)\n {\n if (this.flags.checksum) {\n /*\n * Get a 32-bit summation of the current CPU state and add it to our running 32-bit checksum\n */\n var fDisplay = false;\n this.counts.nChecksum = (this.counts.nChecksum + this.getChecksum())|0;\n this.counts.nCyclesChecksumNext -= nCycles;\n if (this.counts.nCyclesChecksumNext <= 0) {\n this.counts.nCyclesChecksumNext += this.counts.nCyclesChecksumInterval;\n fDisplay = true;\n }\n if (this.counts.nCyclesChecksumStop >= 0) {\n if (this.counts.nCyclesChecksumStop <= this.getCycles()) {\n this.counts.nCyclesChecksumInterval = this.counts.nCyclesChecksumStop = -1;\n this.resetChecksum();\n this.stopCPU();\n fDisplay = true;\n }\n }\n if (fDisplay) this.displayChecksum();\n }\n }\n\n /**\n * displayChecksum()\n *\n * When checksum generation is enabled (fChecksum is true), this is called to provide a crude log of all\n * checksums generated at the specified cycle intervals, as specified by the \"csStart\" and \"csInterval\" parmsCPU\n * properties).\n *\n * @this {CPU}\n */\n displayChecksum()\n {\n this.println(this.getCycles() + \" cycles: \" + \"checksum=\" + Str.toHex(this.counts.nChecksum));\n }\n\n /**\n * displayValue(sLabel, nValue, cch)\n *\n * This is principally for displaying register values, but in reality, it can be used to display any\n * numeric (hex) value bound to the given label.\n *\n * @this {CPU}\n * @param {string} sLabel\n * @param {number} nValue\n * @param {number} cch\n */\n displayValue(sLabel, nValue, cch)\n {\n if (this.bindings[sLabel]) {\n if (nValue === undefined) {\n this.setError(\"Value for \" + sLabel + \" is invalid\");\n this.stopCPU();\n }\n var sVal;\n if (!this.flags.running || this.flags.displayLiveRegs) {\n sVal = Str.toHex(nValue, cch);\n } else {\n sVal = \"--------\".substr(0, cch);\n }\n /*\n * TODO: Determine if this test actually avoids any redrawing when a register hasn't changed, and/or if\n * we should maintain our own (numeric) cache of displayed register values (to avoid creating these temporary\n * string values that will have to garbage-collected), and/or if this is actually slower, and/or if I'm being\n * too obsessive.\n */\n if (this.bindings[sLabel].textContent != sVal) this.bindings[sLabel].textContent = sVal;\n }\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {CPU}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"run\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var cpu = this;\n var fBound = false;\n\n switch (sBinding) {\n case \"power\":\n case \"reset\":\n /*\n * The \"power\" and \"reset\" buttons are functions of the entire computer, not just the CPU,\n * but it's not always convenient to stick a power button in the Computer component definition,\n * so we record those bindings here and pass them on to the Computer component in initBus().\n */\n this.bindings[sBinding] = control;\n fBound = true;\n break;\n\n case \"run\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickRun() {\n var fRunning = cpu.flags.running;\n if (!cpu.cmp || !cpu.cmp.checkPower()) return;\n /*\n * We snapped the CPU's running flag before calling checkPower() because there are rare (REPOWER)\n * situations where checkPower() will have started the CPU as well. So toggle the CPU state ONLY\n * if the running flag remains unchanged.\n */\n if (fRunning == cpu.flags.running) {\n if (!cpu.flags.running) {\n cpu.startCPU(true);\n } else {\n cpu.stopCPU(true);\n }\n }\n };\n fBound = true;\n break;\n\n case \"speed\":\n this.bindings[sBinding] = control;\n fBound = true;\n break;\n\n case \"setSpeed\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickSetSpeed() {\n cpu.setSpeed(cpu.counts.nTargetMultiplier << 1, true);\n };\n control.textContent = this.getSpeedTarget();\n fBound = true;\n break;\n\n default:\n break;\n }\n return fBound;\n }\n\n /**\n * setBurstCycles(nCycles)\n *\n * This function is used by the ChipSet component whenever a very low timer count is set.\n *\n * @this {CPU}\n * @param {number} nCycles is the target number of cycles to drop the current burst to\n * @return {boolean}\n */\n setBurstCycles(nCycles)\n {\n if (this.flags.running) {\n var nDelta = this.nStepCycles - nCycles;\n /*\n * NOTE: If nDelta is negative, we will actually be increasing nStepCycles and nBurstCycles.\n * Which is OK, but if we're also taking snapshots of the cycle counts, to make sure that instruction\n * costs are being properly assessed, then we need to update nSnapCycles as well.\n *\n * TODO: If the delta is negative, we could simply ignore the request, but we must first carefully\n * consider the impact on the ChipSet timers.\n */\n this.nStepCycles -= nDelta;\n this.nBurstCycles -= nDelta;\n return true;\n }\n return false;\n }\n\n /**\n * addCycles(nCycles, fEndStep)\n *\n * @this {CPU}\n * @param {number} nCycles\n * @param {boolean} [fEndStep]\n */\n addCycles(nCycles, fEndStep)\n {\n this.nTotalCycles += nCycles;\n if (fEndStep) {\n this.nBurstCycles = this.nStepCycles = 0;\n }\n }\n\n /**\n * calcCycles()\n *\n * Calculate the maximum number of cycles we should attempt to process before the next yield.\n *\n * @this {CPU}\n */\n calcCycles()\n {\n var nMultiplier = this.counts.mhzCurrent / this.counts.mhzBase;\n if (!nMultiplier || nMultiplier > this.counts.nTargetMultiplier) {\n nMultiplier = this.counts.nTargetMultiplier;\n }\n this.counts.nCyclesPerYield = Math.floor(this.counts.nBaseCyclesPerSecond / CPU.YIELDS_PER_SECOND * nMultiplier);\n this.counts.nCurrentMultiplier = nMultiplier;\n }\n\n /**\n * getCycles(fScaled)\n *\n * getCycles() returns the number of cycles executed so far. Note that we can be called after\n * runCPU() OR during runCPU(), perhaps from a handler triggered during the current run's stepCPU(),\n * so nRunCycles must always be adjusted by number of cycles stepCPU() was asked to run (nBurstCycles),\n * less the number of cycles it has yet to run (nStepCycles).\n *\n * nRunCycles is zeroed whenever the CPU is halted or the CPU speed is changed, which is why we also\n * have nTotalCycles, which accumulates all nRunCycles before we zero it. However, nRunCycles and\n * nTotalCycles eventually get reset by calcSpeed(), to avoid overflow, so components that rely on\n * getCycles() returning steadily increasing values should also be prepared for a reset at any time.\n *\n * @this {CPU}\n * @param {boolean} [fScaled] is true if the caller wants a cycle count relative to a multiplier of 1\n * @return {number}\n */\n getCycles(fScaled)\n {\n var nCycles = this.nTotalCycles + this.nRunCycles + this.nBurstCycles - this.nStepCycles;\n if (fScaled && this.counts.nTargetMultiplier > 1 && this.counts.mhzCurrent > this.counts.mhzBase) {\n /*\n * We could scale the current cycle count by the current speed (this.counts.mhzCurrent); eg:\n *\n * nCycles = Math.round(nCycles / (this.counts.mhzCurrent / this.counts.mhzBase));\n *\n * but that speed will fluctuate somewhat: large fluctuations at first, but increasingly smaller\n * fluctuations after each burst of instructions that runCPU() executes.\n *\n * Alternatively, we can scale the cycle count by the multiplier, which is good in that the\n * multiplier doesn't vary once the user changes it, but a potential downside is that the\n * multiplier might be set too high, resulting in a target speed that's higher than the effective\n * speed is able to reach.\n *\n * Also, if multipliers were always limited to a power-of-two, then this could be calculated\n * with a simple shift. However, only the \"setSpeed\" UI binding limits it that way; the Debugger\n * interface allows any value, as does the CPU \"multiplier\" parmsCPU property (from the machine's\n * XML file).\n */\n nCycles = Math.round(nCycles / this.counts.nTargetMultiplier);\n }\n return nCycles;\n }\n\n /**\n * getBaseCyclesPerSecond()\n *\n * This returns the CPU's base speed (ie, the original cycles per second defined for the machine)\n *\n * @this {CPU}\n * @return {number}\n */\n getBaseCyclesPerSecond()\n {\n return this.counts.nBaseCyclesPerSecond;\n }\n\n /**\n * getCurrentCyclesPerSecond()\n *\n * This returns the CPU's current speed (ie, the actual cycles per second, according the current multiplier)\n *\n * @this {CPU}\n * @return {number}\n */\n getCurrentCyclesPerSecond()\n {\n return (this.counts.nBaseCyclesPerSecond * this.counts.nCurrentMultiplier)|0;\n }\n\n /**\n * resetCycles()\n *\n * Resets speed and cycle information as part of any reset() or restore(); this typically occurs during powerUp().\n * It's important that this be called BEFORE the actual restore() call, because restore() may want to call setSpeed(),\n * which in turn assumes that all the cycle counts have been initialized to sensible values.\n *\n * @this {CPU}\n */\n resetCycles()\n {\n this.nTotalCycles = this.nRunCycles = this.nBurstCycles = this.nStepCycles = 0;\n this.resetChecksum();\n this.setSpeed(this.counts.nBaseMultiplier);\n }\n\n /**\n * getSpeed()\n *\n * @this {CPU}\n * @return {number} the current speed multiplier\n */\n getSpeed()\n {\n return this.counts.nTargetMultiplier;\n }\n\n /**\n * getSpeedCurrent()\n *\n * @this {CPU}\n * @return {string} the current speed, in mhz, as a string formatted to two decimal places\n */\n getSpeedCurrent()\n {\n return ((this.flags.running && this.counts.mhzCurrent)? (this.counts.mhzCurrent.toFixed(2) + \"Mhz\") : \"Stopped\");\n }\n\n /**\n * getSpeedTarget()\n *\n * @this {CPU}\n * @return {string} the target speed, in mhz, as a string formatted to two decimal places\n */\n getSpeedTarget()\n {\n return this.counts.mhzTarget.toFixed(2) + \"Mhz\";\n }\n\n /**\n * setSpeed(nMultiplier, fUpdateFocus)\n *\n * @this {CPU}\n * @param {number} [nMultiplier] is the new proposed multiplier (reverts to default if target was too high)\n * @param {boolean} [fUpdateFocus] is true to update Computer focus\n * @return {boolean} true if successful, false if not\n *\n * @desc Whenever the speed is changed, the running cycle count and corresponding start time must be reset,\n * so that the next effective speed calculation obtains sensible results. In fact, when runCPU() initially calls\n * setSpeed() with no parameters, that's all this function does (it doesn't change the current speed setting).\n */\n setSpeed(nMultiplier, fUpdateFocus)\n {\n var fSuccess = true;\n if (nMultiplier !== undefined) {\n /*\n * If we haven't reached 90% (0.9) of the current target speed, revert to the default multiplier.\n */\n if (this.counts.mhzCurrent > 0 && this.counts.mhzCurrent < this.counts.mhzTarget * 0.9) {\n nMultiplier = this.counts.nBaseMultiplier;\n fSuccess = false;\n }\n this.counts.mhzCurrent = 0;\n this.counts.nTargetMultiplier = nMultiplier;\n var mhzTarget = this.counts.mhzBase * this.counts.nTargetMultiplier;\n if (this.counts.mhzTarget != mhzTarget) {\n this.counts.mhzTarget = mhzTarget;\n var sSpeed = this.getSpeedTarget();\n var controlSpeed = this.bindings[\"setSpeed\"];\n if (controlSpeed) controlSpeed.textContent = sSpeed;\n this.println(\"target speed: \" + sSpeed);\n }\n if (fUpdateFocus && this.cmp) this.cmp.updateFocus();\n }\n this.addCycles(this.nRunCycles);\n this.nRunCycles = 0;\n this.counts.msStartRun = this.counts.msEndThisRun = 0;\n this.calcCycles(); // calculate a new value for the current cycle multiplier\n this.resetTimers(); // and then update all the fixed-period timers using the new cycle multiplier\n return fSuccess;\n }\n\n /**\n * calcSpeed(nCycles, msElapsed)\n *\n * @this {CPU}\n * @param {number} nCycles\n * @param {number} msElapsed\n */\n calcSpeed(nCycles, msElapsed)\n {\n if (msElapsed) {\n this.counts.mhzCurrent = Math.round(nCycles / (msElapsed * 10)) / 100;\n if (msElapsed >= 86400000) {\n this.nTotalCycles = 0;\n if (this.chipset) this.chipset.updateAllTimers(true);\n this.setSpeed(); // reset all counters once per day so that we never have to worry about overflow\n }\n }\n }\n\n /**\n * calcStartTime()\n *\n * @this {CPU}\n */\n calcStartTime()\n {\n this.calcCycles();\n\n this.counts.nCyclesThisRun = 0;\n this.counts.msDiscount = 0;\n this.counts.msStartThisRun = Usr.getTime();\n if (!this.counts.msStartRun) {\n this.counts.msStartRun = this.counts.msStartThisRun;\n }\n\n /*\n * Try to detect situations where the browser may have throttled us, such as when the user switches\n * to a different tab; in those situations, Chrome and Safari may restrict setTimeout() callbacks\n * to roughly one per second.\n *\n * Another scenario: the user resizes the browser window. setTimeout() callbacks are not throttled,\n * but there can still be enough of a lag between the callbacks that CPU speed will be noticeably\n * erratic if we don't compensate for it here.\n *\n * We can detect throttling/lagging by verifying that msEndThisRun (which was set at the end of the\n * previous run and includes any requested sleep time) is comparable to the current msStartThisRun;\n * if the delta is significant, we compensate by bumping msStartRun forward by that delta.\n *\n * This shouldn't be triggered when the Debugger halts the CPU, because setSpeed() -- which is called\n * whenever the CPU starts running again -- zeroes msEndThisRun.\n *\n * This also won't do anything about other internal delays; for example, Debugger message() calls.\n * By the time the message() function has called yieldCPU(), the cost of the message has already been\n * incurred, so it will be end up being charged against the instruction(s) that triggered it.\n *\n * TODO: Consider calling yieldCPU() sooner from message(), so that it can arrange for the msEndThisRun\n * \"snapshot\" to occur sooner; it's unclear, however, whether that will really improve the CPU's ability\n * to hit its target speed, since any instruction that displays a message is unavoidably slooooow.\n */\n var msDelta = 0;\n if (this.counts.msEndThisRun) {\n msDelta = this.counts.msStartThisRun - this.counts.msEndThisRun;\n if (msDelta > this.counts.msPerYield) {\n this.counts.msStartRun += msDelta;\n /*\n * Bumping msStartRun forward should NEVER cause it to exceed msStartThisRun; however, just\n * in case, I make absolutely sure it cannot happen, since doing so could result in negative\n * speed calculations.\n */\n\n if (this.counts.msStartRun > this.counts.msStartThisRun) {\n this.counts.msStartRun = this.counts.msStartThisRun;\n }\n }\n }\n }\n\n /**\n * calcRemainingTime()\n *\n * @this {CPU}\n * @return {number}\n */\n calcRemainingTime()\n {\n this.counts.msEndThisRun = Usr.getTime();\n\n if (this.counts.msDiscount) {\n this.counts.msStartRun += this.counts.msDiscount;\n this.counts.msStartThisRun += this.counts.msDiscount;\n }\n\n var msYield = this.counts.msPerYield;\n if (this.counts.nCyclesThisRun) {\n /*\n * Normally, we would assume we executed a full quota of work over msPerYield, but since the CPU\n * now has the option of calling yieldCPU(), that might not be true. If nCyclesThisRun is correct, then\n * the ratio of nCyclesThisRun/nCyclesPerYield should represent the percentage of work we performed,\n * and so applying that percentage to msPerYield should give us a better estimate of work vs. time.\n */\n msYield = Math.round(msYield * this.counts.nCyclesThisRun / this.counts.nCyclesPerYield);\n }\n\n var msElapsedThisRun = this.counts.msEndThisRun - this.counts.msStartThisRun;\n var msRemainsThisRun = msYield - msElapsedThisRun;\n\n /*\n * We could pass only \"this run\" results to calcSpeed():\n *\n * nCycles = this.counts.nCyclesThisRun;\n * msElapsed = msElapsedThisRun;\n *\n * but it seems preferable to use longer time periods and hopefully get a more accurate speed.\n */\n var nCycles = this.nRunCycles;\n var msElapsed = this.counts.msEndThisRun - this.counts.msStartRun;\n\n if (MAXDEBUG && msRemainsThisRun < 0 && this.counts.nTargetMultiplier > 1) {\n this.println(\"warning: updates @\" + msElapsedThisRun + \"ms (prefer \" + Math.round(msYield) + \"ms)\");\n }\n\n this.calcSpeed(nCycles, msElapsed);\n\n if (msRemainsThisRun < 0) {\n /*\n * Try \"throwing out\" the effects of large anomalies, by moving the overall run start time up;\n * ordinarily, this should only happen when the someone is using an external Debugger or some other\n * tool or feature that is interfering with our overall execution.\n */\n if (msRemainsThisRun < -1000) {\n this.counts.msStartRun -= msRemainsThisRun;\n }\n /*\n * If the last burst took MORE time than we allotted (ie, it's taking more than 1 second to simulate\n * nBaseCyclesPerSecond), all we can do is yield for as little time as possible (ie, 0ms) and hope\n * that the simulation is at least usable.\n */\n msRemainsThisRun = 0;\n }\n else if (this.counts.mhzCurrent < this.counts.mhzTarget) {\n msRemainsThisRun = 0;\n }\n\n if (DEBUG && this.messageEnabled(Messages.CPU)) {\n /*\n * Every time the browser gives us another chance to run, we want to display our targets for that run\n * here, followed by what we accomplished in that run.\n */\n this.printMessage(Str.sprintf(\"%3dms run %3dms wait %6dcy %6.2fmhz %6dms total %8dcy total %6.2fmhz total\",\n msElapsedThisRun,\n msRemainsThisRun,\n this.counts.nCyclesThisRun,\n Math.round(this.counts.nCyclesThisRun / (msElapsedThisRun * 10)) / 100,\n msElapsed,\n nCycles,\n this.counts.mhzCurrent\n ));\n }\n\n this.counts.msEndThisRun += msRemainsThisRun;\n\n return msRemainsThisRun;\n }\n\n /**\n * addTimer(id, callBack, ms)\n *\n * Components that want to have timers that fire after some number of milliseconds call addTimer() to create\n * the timer, and then setTimer() when they want to arm it. Alternatively, they can specify an automatic timeout\n * value (in milliseconds) to have the timer fire automatically at regular intervals. There is currently\n * no removeTimer() because these are generally used for the entire lifetime of a component.\n *\n * Internally, each timer entry is a preallocated Array with the following entries:\n *\n * [0]: timer ID\n * [1]: countdown value, in cycles\n * [2]: automatic setTimer value, if any, in milliseconds\n * [3]: callback function\n *\n * A timer is initially dormant; dormant timers have a countdown value of -1 (although any negative number\n * will suffice) and active timers have a non-negative value.\n *\n * Why not use JavaScript's setTimeout() instead? Good question. For a good answer, see setTimer() below.\n *\n * @this {CPU}\n * @param {string} id\n * @param {function()} callBack\n * @param {number} [ms] (if set, enables automatic setTimer calls)\n * @return {number} timer index\n */\n addTimer(id, callBack, ms = -1)\n {\n var iTimer = this.aTimers.length;\n this.aTimers.push([id, -1, ms, callBack]);\n if (ms >= 0) this.setTimer(iTimer, ms);\n return iTimer;\n }\n\n /**\n * clearTimer(iTimer)\n *\n * Using the timer index from a previous addTimer() call, this clears that timer.\n *\n * @this {CPU}\n * @param {number} iTimer\n * @return {boolean}\n */\n clearTimer(iTimer)\n {\n if (iTimer >= 0 && iTimer < this.aTimers.length) {\n this.aTimers[iTimer][1] = -1;\n return true;\n }\n return false;\n }\n\n /**\n * findTimer(id)\n *\n * @this {CPU}\n * @param {string} id\n * @return {Array|null}\n */\n findTimer(id)\n {\n for (var iTimer = 0; iTimer < this.aTimers.length; iTimer++) {\n var timer = this.aTimers[iTimer];\n if (timer[0] == id) return timer;\n }\n return null;\n }\n\n /**\n * isTimerSet(iTimer)\n *\n * @this {CPU}\n * @param {number} iTimer\n * @return {boolean}\n */\n isTimerSet(iTimer)\n {\n if (iTimer >= 0 && iTimer < this.aTimers.length) {\n return this.aTimers[iTimer][1] >= 0;\n }\n return false;\n }\n\n /**\n * setTimer(iTimer, ms, fReset)\n *\n * Using the timer index from a previous addTimer() call, this sets that timer to fire after the\n * specified number of milliseconds.\n *\n * This is preferred over JavaScript's setTimeout(), because all our timers are effectively paused when\n * the CPU is paused (eg, when the Debugger halts execution). Moreover, setTimeout() handlers only run after\n * runCPU() yields, which is far too granular for some components (eg, when the SerialPort tries to simulate\n * interrupts at 9600 baud).\n *\n * Ideally, the only function that would use setTimeout() is runCPU(), while the rest of the components\n * use setTimer(); however, due to legacy code (ie, code that predates these functions) and/or laziness,\n * that may not be the case.\n *\n * @this {CPU}\n * @param {number} iTimer\n * @param {number} ms (converted into a cycle countdown internally)\n * @param {boolean} [fReset] (true if the timer should be reset even if already armed)\n * @return {number} (number of cycles used to arm timer, or -1 if error)\n */\n setTimer(iTimer, ms, fReset)\n {\n var nCycles = -1;\n if (iTimer >= 0 && iTimer < this.aTimers.length) {\n var timer = this.aTimers[iTimer];\n if (fReset || timer[1] < 0) {\n nCycles = this.getMSCycles(ms);\n /*\n * If the CPU is currently executing a burst of cycles, the number of cycles it has executed in\n * that burst so far must NOT be charged against the cycle timeout we're about to set. The simplest\n * way to resolve that is to immediately call endBurst() and bias the cycle timeout by the number\n * of cycles that the burst executed.\n */\n if (this.flags.running) {\n nCycles += this.endBurst();\n }\n timer[1] = nCycles;\n }\n }\n return nCycles;\n }\n\n /**\n * setTimerCycles(iTimer, nCycles)\n *\n * A cycle-based version of setTimer(), used to help wean components off of functions like setBurstCycles().\n *\n * @this {CPU}\n * @param {number} iTimer\n * @param {number} nCycles\n * @return {boolean}\n */\n setTimerCycles(iTimer, nCycles)\n {\n if (iTimer >= 0 && iTimer < this.aTimers.length) {\n var timer = this.aTimers[iTimer];\n /*\n * If the CPU is currently executing a burst of cycles, the number of cycles it has executed in\n * that burst so far must NOT be charged against the cycle timeout we're about to set. The simplest\n * way to resolve that is to immediately call endBurst() and bias the cycle timeout by the number\n * of cycles that the burst executed.\n */\n if (this.flags.running) {\n nCycles += this.endBurst();\n }\n timer[1] = nCycles;\n return true;\n }\n return false;\n }\n\n /**\n * getMSCycles(ms)\n *\n * @this {CPU}\n * @param {number} ms\n * @return {number} number of corresponding cycles\n */\n getMSCycles(ms)\n {\n return ((this.counts.nBaseCyclesPerSecond * this.counts.nCurrentMultiplier) / 1000 * ms)|0;\n }\n\n /**\n * getBurstCycles(nCycles)\n *\n * @this {CPU}\n * @param {number} nCycles (maximum number of cycles to execute)\n * @return {number}\n */\n getBurstCycles(nCycles)\n {\n for (var iTimer = this.aTimers.length - 1; iTimer >= 0; iTimer--) {\n var timer = this.aTimers[iTimer];\n\n if (timer[1] < 0) continue;\n if (nCycles > timer[1]) {\n nCycles = timer[1];\n }\n }\n return nCycles;\n }\n\n /**\n * saveTimers()\n *\n * @this {CPU}\n * @return {Array}\n */\n saveTimers()\n {\n var aTimerStates = [];\n for (var iTimer = 0; iTimer < this.aTimers.length; iTimer++) {\n var timer = this.aTimers[iTimer];\n aTimerStates.push([timer[0], timer[1], timer[2]]);\n }\n return aTimerStates;\n }\n\n /**\n * restoreTimers(aTimerStates)\n *\n * @this {CPU}\n * @param {Array} aTimerStates\n */\n restoreTimers(aTimerStates)\n {\n for (var iTimerState = 0; iTimerState < aTimerStates.length; iTimerState++) {\n var state = aTimerStates[iTimerState];\n var timer = this.findTimer(state[0]);\n if (timer) {\n timer[1] = state[1];\n timer[2] = state[2];\n }\n }\n }\n\n /**\n * resetTimers()\n *\n * When the target CPU speed multiplier is altered, it's a good idea to run through all the timers that\n * have a fixed millisecond period and re-arm them, because the timers are using cycle counts that were based\n * on a previous multiplier.\n *\n * @this {CPU}\n */\n resetTimers()\n {\n for (var iTimer = this.aTimers.length - 1; iTimer >= 0; iTimer--) {\n var timer = this.aTimers[iTimer];\n if (timer[2] >= 0) this.setTimer(iTimer, timer[2], true);\n }\n }\n\n /**\n * updateTimers(nCycles)\n *\n * Used by runCPU() to reduce all active timer countdown values by the number of cycles just executed;\n * this is the function that actually \"fires\" any timer(s) whose countdown has reached (or dropped below)\n * zero, invoking their callback function.\n *\n * @this {CPU}\n * @param {number} nCycles (number of cycles actually executed)\n */\n updateTimers(nCycles)\n {\n for (var iTimer = this.aTimers.length - 1; iTimer >= 0; iTimer--) {\n var timer = this.aTimers[iTimer];\n\n if (timer[1] < 0) continue;\n timer[1] -= nCycles;\n if (timer[1] <= 0) {\n if (DEBUG && this.messageEnabled(Messages.CPU | Messages.TIMER)) { // CPU TIMER message (as opposed to CHIPSET TIMER message)\n this.printMessage(\"updateTimer(\" + nCycles + \"): firing \" + timer[0] + \" with only \" + (timer[1] + nCycles) + \" cycles left\");\n }\n timer[1] = -1; // zero is technically an \"active\" value, so ensure the timer is dormant now\n timer[3](); // safe to invoke the callback function now\n if (timer[2] >= 0) {\n this.setTimer(iTimer, timer[2]);\n if (DEBUG && this.messageEnabled(Messages.CPU | Messages.TIMER)) { // CPU TIMER message (as opposed to CHIPSET TIMER message)\n this.printMessage(\"updateTimer(\" + nCycles + \"): rearming \" + timer[0] + \" for \" + timer[2] + \"ms (\" + timer[1] + \" cycles)\");\n }\n }\n }\n }\n }\n\n /**\n * endBurst()\n *\n * @this {CPU}\n * @return {number} (number of cycles executed in the most recent burst)\n */\n endBurst()\n {\n var nCycles = this.nBurstCycles - this.nStepCycles;\n this.nBurstCycles = this.nStepCycles = 0;\n this.counts.nCyclesThisRun += nCycles;\n this.nRunCycles += nCycles;\n return nCycles;\n }\n\n /**\n * runCPU()\n *\n * @this {CPU}\n */\n runCPU()\n {\n this.idRunTimeout = 0;\n if (!this.flags.running) return;\n\n /*\n * calcStartTime() initializes the cycle counter and timestamp for this runCPU() invocation.\n */\n this.calcStartTime();\n\n try {\n this.flags.yield = false;\n do {\n /*\n * getBurstCycles() tells us how many cycles to execute as a burst. The answer will always\n * be less than getCurrentCyclesPerSecond(), because at the very least, our own timer fires more than\n * once per second.\n */\n var nCycles = this.getBurstCycles(this.flags.checksum? 1 : this.getCurrentCyclesPerSecond());\n\n if (this.chipset) {\n this.chipset.updateAllTimers();\n nCycles = this.chipset.getTimerCycleLimit(0, nCycles);\n nCycles = this.chipset.getRTCCycleLimit(nCycles);\n }\n\n /*\n * Execute the burst.\n */\n try {\n this.stepCPU(nCycles);\n }\n catch(exception) {\n if (typeof exception != \"number\") throw exception;\n if (MAXDEBUG) this.println(\"CPU exception \" + Str.toHexByte(exception));\n /*\n * TODO: If we ever get into a situation where every single instruction is generating a fault\n * (eg, if an 8088 executes opcode 0xFF 0xFF, which is incorrectly routed to helpFault() instead\n * of fnGRPUndefined()), the browser may hang because we're failing to yield often enough.\n * This is likely because the thrown exceptions are taking MUCH longer than normal instructions,\n * throwing off our burst calculations. We need to either adjust the burst or break out of the\n * DO-WHILE loop on every exception.\n */\n }\n\n /*\n * Terminate the burst, returning the number of cycles that stepCPU() actually ran.\n */\n nCycles = this.endBurst();\n\n /*\n * Update all timers, firing those whose cycle countdowns have reached (or dropped below) zero.\n */\n this.updateTimers(nCycles);\n this.updateChecksum(nCycles);\n\n } while (this.flags.running && !this.flags.yield);\n }\n catch (e) {\n this.stopCPU();\n this.updateCPU();\n if (this.cmp) this.cmp.stop(Usr.getTime(), this.getCycles());\n this.setError(e.stack || e.message);\n return;\n }\n\n if (this.flags.running) {\n\n this.idRunTimeout = setTimeout(this.onRunTimeout, this.calcRemainingTime());\n }\n }\n\n /**\n * startCPU(fUpdateFocus)\n *\n * For use by any component that wants to start the CPU.\n *\n * @param {boolean} [fUpdateFocus]\n * @param {boolean} [fQuiet]\n * @return {boolean}\n */\n startCPU(fUpdateFocus, fQuiet)\n {\n if (this.isError()) {\n return false;\n }\n if (this.flags.running) {\n if (!fQuiet) this.println(this.toString() + \" busy\");\n return false;\n }\n if (this.idRunTimeout) {\n clearTimeout(this.idRunTimeout);\n this.idRunTimeout = 0;\n }\n /*\n * setSpeed() without a speed parameter leaves the selected speed in place, but also resets the\n * cycle counter and timestamp for the current series of runCPU() calls, and calculates the maximum number\n * of cycles for each burst based on the last known effective CPU speed.\n */\n this.setSpeed();\n this.flags.running = true;\n this.flags.starting = true;\n if (this.chipset) this.chipset.start();\n var controlRun = this.bindings[\"run\"];\n if (controlRun) controlRun.textContent = \"Halt\";\n if (this.cmp) {\n this.cmp.updateStatus(true);\n if (fUpdateFocus) this.cmp.updateFocus(!fQuiet);\n this.cmp.start(this.counts.msStartRun, this.getCycles());\n }\n\n this.idRunTimeout = setTimeout(this.onRunTimeout, 0);\n return true;\n }\n\n /**\n * stepCPU(nMinCycles)\n *\n * This will be implemented by the CPUX86 component.\n *\n * @this {CPU}\n * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored)\n * @return {number} of cycles executed; 0 indicates that the last instruction was not executed\n */\n stepCPU(nMinCycles)\n {\n return 0;\n }\n\n /**\n * stopCPU(fComplete)\n *\n * For use by any component that wants to stop the CPU.\n *\n * @this {CPU}\n * @param {boolean} [fComplete]\n * @return {boolean} true if the CPU was stopped, false if it was already stopped\n */\n stopCPU(fComplete)\n {\n var fStopped = false;\n if (this.flags.running) {\n this.endBurst();\n this.addCycles(this.nRunCycles);\n this.nRunCycles = 0;\n this.flags.running = false;\n if (this.chipset) this.chipset.stop();\n var controlRun = this.bindings[\"run\"];\n if (controlRun) controlRun.textContent = \"Run\";\n if (this.cmp) {\n this.cmp.stop(Component.getTime(), this.getCycles());\n this.cmp.updateStatus(true);\n }\n if (!this.dbg) this.status(\"Stopped\");\n fStopped = true;\n }\n this.flags.complete = fComplete;\n return fStopped;\n }\n\n /**\n * nonCPU(fn)\n *\n * Use this function to perform any work outside the scope of the CPU (eg, DOM updates),\n * to prevent that work from disrupting our speed calculations.\n *\n * @this {CPU}\n * @param {function()} fn (should return true only if the function actually performed any work)\n * @return {boolean}\n */\n nonCPU(fn)\n {\n var msStart = Usr.getTime();\n if (fn()) {\n var msStop = Usr.getTime();\n this.counts.msDiscount += msStop - msStart;\n return true;\n }\n return false;\n }\n\n /**\n * updateCPU(fForce)\n *\n * This used to be performed at the end of every stepCPU(), but runCPU() -- which relies upon\n * stepCPU() -- needed to have more control over when these updates are performed. However, for\n * other callers of stepCPU(), such as the Debugger, the combination of stepCPU() + updateCPU()\n * provides the old behavior.\n *\n * @this {CPU}\n * @param {boolean} [fForce] (true to force a Computer update; used by the Debugger)\n */\n updateCPU(fForce)\n {\n if (this.cmp) this.cmp.updateStatus(fForce);\n }\n\n /**\n * yieldCPU()\n *\n * Similar to stopCPU() with regard to how it resets various cycle countdown values, but the CPU\n * remains in a \"running\" state.\n *\n * @this {CPU}\n */\n yieldCPU()\n {\n this.flags.yield = true;\n /*\n * The Debugger calls yieldCPU() after every message() to ensure browser responsiveness, but it looks\n * odd for those messages to show CPU state changes but for the CPU's own status display to not (ditto\n * for the Video display), so I've added this call to try to keep things looking synchronized.\n */\n this.updateCPU();\n }\n}\n\nCPU.YIELDS_PER_SECOND = 30;\n\nCPU.BUTTONS = [\"power\", \"reset\"];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/cpux86.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * class CPUX86\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass CPUX86 extends CPU {\n /**\n * CPUX86(parmsCPU)\n *\n * The CPUX86 class uses the following (parmsCPU) properties:\n *\n * model: a string (eg, \"8088\") that should match one of the X86.MODEL values (default is \"8088\")\n * stepping: a string (eg, \"B1\") that should match one of the X86.STEPPING values (default is \"\")\n *\n * This extends the CPU class and passes any remaining parmsCPU properties to the CPU class\n * constructor, along with a default speed (cycles per second) based on the specified (or default)\n * CPU model number.\n *\n * The CPUX86 class was initially written to simulate a 8086/8088 microprocessor, although over time\n * it has evolved to support later microprocessors (eg, the 80186/80188 and the 80286, including\n * protected-mode support).\n *\n * This is a logical simulation, not a physical simulation, and performance is critical, second only\n * to the accuracy of the simulation when running real-world x86 software. Consequently, it takes a\n * few liberties with the operation of the simulated hardware, especially with regard to timings,\n * little-used features, etc. We do make an effort to maintain approximate instruction cycle counts,\n * but there are many other obstacles (eg, prefetch queue, wait states) to achieving accurate timings.\n *\n * For example, our 8237 DMA controller performs all DMA transfers immediately, since internally\n * they are all memory-to-memory, and attempting to interleave DMA cycles with instruction execution\n * cycles would hurt overall performance. Similarly, 8254 timer counters are updated only on-demand.\n *\n * The 8237 and 8254, along with the 8259 interrupt controller and several other \"chips\", are combined\n * into a single ChipSet component, to keep the number of components we juggle to a minimum.\n *\n * All that being said, this does not change the overall goal: to produce as accurate a simulation as\n * possible, within the limits of what JavaScript allows and how precisely/predictably it behaves.\n *\n * @this {CPUX86}\n * @param {Object} parmsCPU\n */\n constructor(parmsCPU)\n {\n var nCyclesDefault;\n var model = +parmsCPU['model'] || X86.MODEL_8088;\n\n switch(model) {\n case X86.MODEL_8088:\n default:\n nCyclesDefault = 4772727;\n break;\n case X86.MODEL_80286:\n nCyclesDefault = 6000000;\n break;\n case X86.MODEL_80386:\n nCyclesDefault = 16000000;\n break;\n }\n\n super(parmsCPU, nCyclesDefault);\n\n this.model = model;\n\n /*\n * We take the 'stepping' value, convert it to a hex value, and then add that to the model to provide\n * a single value that's unique for any given CPU stepping. If no stepping is provided, then stepping\n * is equal to model.\n */\n var stepping = parmsCPU['stepping'];\n this.stepping = model + (stepping? Str.parseInt(stepping, 16) : 0);\n\n /*\n * Initialize processor operation to match the requested model\n */\n this.initProcessor();\n\n /*\n * List of software interrupt notification functions: aIntNotify is an array, indexed by\n * interrupt number, where each element contains:\n *\n * registered function to call for every software interrupt\n *\n * The registered function is called with the linear address (LIP) following the software interrupt;\n * if any function returns false, the software interrupt will be skipped (presumed to be emulated),\n * and no further notification functions will be called.\n *\n * NOTE: Registered functions are called only for INT N instructions -- *not* INT 0x03 or INTO or the\n * INT 0x00 generated by a divide-by-zero or any other kind of interrupt (nor any interrupt simulated\n * with PUSHF/CALLF).\n *\n * aIntReturn is a hash of return address notifications set up by software interrupt notification\n * functions that want to receive return notifications. A software interrupt function must call\n * cpu.addIntReturn(fn).\n *\n * WARNING: There's no mechanism in place to insure that software interrupt return notifications don't\n * get \"orphaned\" if an interrupt handler bypasses the normal return path (INT 0x24 is one example of an\n * \"evil\" software interrupt).\n */\n this.aIntNotify = [];\n this.aIntReturn = [];\n\n /*\n * Since aReturnNotify is a \"sparse array\", this global count gives the CPU a quick way of knowing whether\n * or not RETF or IRET instructions need to bother calling checkIntReturn().\n */\n this.cIntReturn = 0;\n\n /*\n * A variety of stepCPU() state variables that don't strictly need to be initialized before the first\n * stepCPU() call, but it's good form to do so.\n */\n this.resetCycles();\n this.flags.complete = this.flags.debugCheck = false;\n\n /*\n * If there are no live registers to display, then updateStatus() can skip a bit....\n */\n this.cLiveRegs = 0;\n\n /*\n * We're just declaring aMemBlocks and associated Bus parameters here; they'll be initialized by initMemory()\n * when the Bus is initialized.\n */\n this.aBusBlocks = this.aMemBlocks = [];\n this.nBusMask = this.nMemMask = -1;\n this.nBlockShift = this.nBlockSize = this.nBlockLimit = this.nBlockTotal = this.nBlockMask = 0;\n\n if (PREFETCH) {\n this.cbPrefetch = 0;\n this.adwPrefetch = null;\n }\n\n /*\n * This initial resetRegs() call is important to create all the registers (eg, the SegX86 registers),\n * so that if/when we call restore(), it will have something to fill in.\n */\n this.resetRegs();\n }\n\n /**\n * initMemory(aMemBlocks, nBlockShift)\n *\n * Notification from Bus.initMemory(), giving us direct access to the entire memory space\n * (aMemBlocks). Since the CPU must perform additional layers of address decoding depending\n * on the mode (real-mode, protected-mode, paging), it's best if the CPU can avoid going\n * through the Bus component for every memory access.\n *\n * We also initialize a 32-bit prefetch queue, containing dword-aligned values; the queue is\n * an array of dwords indexed by a masked regLIP; for example, a queue of 4 dwords is indexed\n * by \"regLIP & 0xC\"; we use a sparse array to avoid right-shifting the index, like so:\n *\n * 0: [dword]\n * 4: [dword]\n * 8: [dword]\n * 12: [dword]\n *\n * The actual regLIP mask is CPUX86.PFINFO.IP_MASK; ie, (CPUX86.PFINFO.LENGTH - 1) & ~0x3.\n *\n * On refilling, the queue is always filled to capacity, and cbPrefetch is set to its maximum\n * value (eg, a value from 16 to 13, depending on whether \"regLIP & 0x3\" is 0, 1, 2 or 3).\n *\n * When a byte is requested from the queue, the dword is extracted from index \"regLIP & 0xC\"\n * and then shifted by 0, 8, 16, or 24, depending on whether \"regLIP & 0x3\" is 0, 1, 2 or 3\n * (ie, \"(regLIP & 0x3) << 3\").\n *\n * TODO: Consider how/whether to simulate an effective prefetch queue size of 4 bytes for an 8088,\n * 6 bytes for an 8086, 12 for an 80386, etc.\n *\n * @this {CPUX86}\n * @param {Array} aMemBlocks\n * @param {number} nBlockShift\n */\n initMemory(aMemBlocks, nBlockShift)\n {\n /*\n * aBusBlocks preserves the Bus block array for the life of the machine, whereas aMemBlocks\n * will be altered if/when the CPU enables paging. PAGEBLOCKS must be true when using Memory\n * blocks to simulate paging, ensuring that physical blocks and pages have the same size (4Kb).\n */\n this.aBusBlocks = this.aMemBlocks = aMemBlocks;\n this.nBlockShift = nBlockShift;\n this.nBlockSize = 1 << this.nBlockShift;\n this.nBlockLimit = this.nBlockSize - 1;\n this.nBlockTotal = aMemBlocks.length;\n this.nBlockMask = this.nBlockTotal - 1;\n if (PREFETCH) {\n // this.nBusCycles = 0;\n this.adwPrefetch = new Array(CPUX86.PFINFO.LENGTH);\n }\n }\n\n /**\n * setAddressMask(nBusMask)\n *\n * Notification from Bus.initMemory() and Bus.setA20(); the latter calls us whenever the physical\n * A20 line changes (note that on a 20-bit bus machine, address lines A20 and higher are always zero).\n *\n * For 32-bit bus machines (eg, 80386), nBusMask is never changed after the initial call, because A20\n * wrap-around is simulated by changing the physical memory map rather than altering the A20 bit in nBusMask.\n *\n * We maintain nMemMask separate from nBusMask, because when paging is enabled on the 80386, the CPU memory\n * functions are now dealing with linear addresses rather than physical addresses, so it would be incorrect\n * to apply nBusMask to those addresses; nMemMask must remain 0xffffffff (-1) for the duration. If we change\n * how A20 is simulated on the 80386, then enablePageBlocks() and disablePageBlocks() will need to override\n * nMemMask appropriately.\n *\n * TODO: Ideally, we would eliminate masking altogether of 32-bit addresses, but that would require different\n * sets of memory access functions for different machines (ie, those with 20-bit or 24-bit buses).\n *\n * @this {CPUX86}\n * @param {number} nBusMask\n */\n setAddressMask(nBusMask)\n {\n this.nBusMask = this.nMemMask = nBusMask;\n }\n\n /**\n * addMemBreak(addr, fWrite, fPhysical)\n *\n * NOTE: addMemBreak() could be merged with addMemCheck(), but the new merged interface would\n * have to provide one additional parameter indicating whether the Debugger or the CPU is the client.\n *\n * For now, this is simply a DEBUGGER-only interface.\n *\n * @this {CPUX86}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint\n * @param {boolean} [fPhysical] (true for physical breakpoint, false for linear)\n */\n addMemBreak(addr, fWrite, fPhysical)\n {\n if (DEBUGGER) {\n var iBlock = addr >>> this.nBlockShift;\n var aBlocks = (fPhysical? this.aBusBlocks : this.aMemBlocks);\n aBlocks[iBlock].addBreakpoint(addr & this.nBlockLimit, fWrite);\n /*\n * When a physical memory breakpoint is added, a fresh setPhysBlock() call is REQUIRED for any\n * linear mappings to that address. This is a bit of a sledgehammer solution, but at least it's a solution.\n */\n if (fPhysical) this.flushPageBlocks();\n }\n }\n\n /**\n * removeMemBreak(addr, fWrite, fPhysical)\n *\n * NOTE: removeMemBreak() could be merged with removeMemCheck(), but the new merged interface would\n * have to provide one additional parameter indicating whether the Debugger or the CPU is the client.\n *\n * For now, this is simply a DEBUGGER-only interface.\n *\n * @this {CPUX86}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint\n * @param {boolean} [fPhysical] (true for physical breakpoint, false for linear)\n */\n removeMemBreak(addr, fWrite, fPhysical)\n {\n if (DEBUGGER) {\n var iBlock = addr >>> this.nBlockShift;\n var aBlocks = (fPhysical? this.aBusBlocks : this.aMemBlocks);\n aBlocks[iBlock].removeBreakpoint(addr & this.nBlockLimit, fWrite);\n /*\n * When a physical memory breakpoint is removed, a fresh setPhysBlock() call is RECOMMENDED for any\n * linear mappings to that address. This is a bit of a sledgehammer solution, but at least it's a solution.\n */\n if (fPhysical) this.flushPageBlocks();\n }\n }\n\n /**\n * addMemCheck(addr, fWrite)\n *\n * These functions provide Debug register functionality to the CPU by leveraging the same Memory block-based\n * breakpoint support originally created for our built-in Debugger. Only minimal changes were required to the\n * Memory component, by adding additional checkMemoryException() call-outs from the \"checked\" Memory access\n * functions.\n *\n * Note that those call-outs occur only AFTER our own Debugger (if present) has checked the address and has\n * passed on it, because we want our own Debugger's breakpoints to take precedence over any breakpoints that\n * the emulated machine may have enabled.\n *\n * @this {CPUX86}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write check, false for a memory read check\n */\n addMemCheck(addr, fWrite)\n {\n var iBlock = addr >>> this.nBlockShift;\n this.aMemBlocks[iBlock].addBreakpoint(addr & this.nBlockLimit, fWrite, this);\n }\n\n /**\n * removeMemCheck(addr, fWrite)\n *\n * @this {CPUX86}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write check, false for a memory read check\n */\n removeMemCheck(addr, fWrite)\n {\n var iBlock = addr >>> this.nBlockShift;\n this.aMemBlocks[iBlock].removeBreakpoint(addr & this.nBlockLimit, fWrite);\n }\n\n /**\n * enablePageBlocks()\n *\n * Whenever the CPU turns on paging and/or updates CR3, this function is called to update our copy\n * of the Bus block array, to simulate paging. Whenever the CPU turns paging off, disablePageBlocks()\n * must be called to restore our copy of the Bus block array to its original (physical) mapping.\n *\n * This also requires PAGEBLOCKS be enabled, to ensure the Bus is configured with a 4Kb block size.\n *\n * The first time this function is called, aMemBlocks and aBusBlocks are identical, so aMemBlocks is\n * reinitialized with special UNPAGED Memory blocks that know how to perform page directory/page table\n * lookup and replace themselves with special PAGED Memory blocks that reference memory from the\n * appropriate block in aBusBlocks. A parallel array, aBlocksPaged, keeps track (by block number) of\n * which blocks have been PAGED, so that whenever CR3 is updated, those blocks can be quickly UNPAGED.\n *\n * @this {CPUX86}\n */\n enablePageBlocks()\n {\n if (!PAGEBLOCKS) {\n this.setError(\"PAGEBLOCKS support required\");\n return;\n }\n var iBlock;\n if (this.aMemBlocks === this.aBusBlocks) {\n this.aMemBlocks = new Array(this.nBlockTotal);\n /*\n * TODO: Currently we allocate only one UNPAGED block for the entire linear address space;\n * only when a block is touched and becomes PAGED do we allocate a dedicated Memory block\n * for that slot. One potential downside to using a single UNPAGED block, however, is that\n * it will accumulate all breakpoints for all UNPAGED blocks, requiring copyBreakpoints() to\n * do extra work to figure out which breakpoints should be copied (ie, removed) from the\n * outgoing block -- which it can't currently do, because blocks only keep track of the total\n * number of breakpoints, not the actual breakpoint addresses.\n *\n * So, Memory blocks either need to start maintaining their own breakpoint address lists,\n * or we need to allocate separate (empty) UNPAGED blocks for every slot. I've not tackled\n * this yet, because it's largely just a debugging issue.\n *\n * Notice that when we call copyBreakpoints() here, it's merely to initialize the new block;\n * we make no attempt to copy any breakpoints from physical blocks to linear blocks, although\n * perhaps we should. The plan for our Debugger is to maintain separate physical and linear\n * breakpoint address lists, but what about CPU Debug registers? If the CPU sets the Debug\n * registers, then enables paging, do all the previous Debug register addresses automatically\n * become linear addresses? I'm guessing they do.\n */\n this.blockUnpaged = new Memory(null, 0, 0, Memory.TYPE.UNPAGED, null, this);\n this.blockUnpaged.copyBreakpoints(this.dbg);\n for (iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {\n this.aMemBlocks[iBlock] = this.blockUnpaged;\n }\n /*\n * We also use a special \"empty\" Memory block that mapPageBlock() can pass back to callers\n * whenever a valid block cannot be found for an UNPAGED block. Under normal conditions,\n * an invalid block will trigger a fault, so memEmpty will never actually be returned, but\n * if the Debugger is suppressing faults or calling probeAddr(), returning memEmpty is helpful.\n */\n this.memEmpty = new Memory();\n\n /*\n * Initialize our PAGEBLOCKS cache (see acquirePageBlock() and releasePageBlock()).\n */\n this.aCacheBlocks = new Array(CPUX86.PAGEBLOCKS_CACHE);\n this.iCacheBlocks = 0;\n } else {\n /*\n * Our equivalent of a TLB flush. NOTE: We do not attempt to simulate an actual TLB; our\n * aMemBlocks array will \"cache\" as many pages (ie, allow as many PAGED block) as there are\n * entries in the array. I'm assuming we won't run into any system software that relies on\n * a constrained TLB -- at least not from the 80386 era, which is all we're emulating.\n */\n for (var i = 0; i < this.aBlocksPaged.length; i++) {\n iBlock = this.aBlocksPaged[i];\n this.releasePageBlock(this.aMemBlocks[iBlock]);\n this.aMemBlocks[iBlock] = this.blockUnpaged;\n }\n }\n this.aBlocksPaged = [];\n }\n\n /**\n * flushPageBlocks()\n *\n * @this {CPUX86}\n */\n flushPageBlocks()\n {\n if (this.regCR0 & X86.CR0.PG) this.enablePageBlocks();\n }\n\n /**\n * acquirePageBlock(addr)\n *\n * This implements a simple paged memory block cache. Candidates for caching must be released via\n * releasePageBlock().\n *\n * After acquiring a block from this cache, the caller MUST use setPhysBlock() to properly reinitialize\n * it for the new given linear address.\n *\n * @this {CPUX86}\n * @param {number} addr\n * @return {Memory}\n */\n acquirePageBlock(addr)\n {\n var block;\n if (this.iCacheBlocks > 0) {\n block = this.aCacheBlocks[--this.iCacheBlocks];\n /*\n * Paged memory blocks are all very generic and contain no memory of their own, so the fact\n * that we're not calling the Memory constructor to reinitialize it is OK. setPhysBlock() is\n * what's critical, and the caller will take care of that. However, to avoid any confusion,\n * especially when debugging, there are a few properties we should reinitialize, hence init().\n */\n block.init(addr);\n } else {\n block = new Memory(addr, 0, 0, Memory.TYPE.PAGED);\n }\n return block;\n }\n\n /**\n * releasePageBlock(block)\n *\n * Instead of simply tossing Memory blocks onto the garbage collector's heap, we'll retain a maximum\n * number (CPUX86.PAGEBLOCKS_CACHE) in aCacheBlocks, with iCacheBlocks pointing to the next free element.\n *\n * @this {CPUX86}\n * @param {Memory} block\n */\n releasePageBlock(block)\n {\n\n if (this.iCacheBlocks < CPUX86.PAGEBLOCKS_CACHE) {\n this.aCacheBlocks[this.iCacheBlocks++] = block;\n }\n }\n\n /**\n * mapPageBlock(addr, fWrite, fSuppress)\n *\n * Locate the corresponding physical PDE, PTE and memory blocks for the given linear address, and then\n * upgrade the block from an UNPAGED Memory block to a new PAGED Memory block; all future accesses to\n * the current page will go directly to that block, instead of coming here through the UNPAGED block\n * handlers.\n *\n * Note that since the incoming address (addr) is a linear address, we never need to mask it with nBusMask,\n * but all the intermediate (PDE, PTE) and final physical addresses we calculate should still be masked.\n *\n * Granted, nBusMask on a 32-bit bus is generally going to be 0xffffffff (-1), so masking might seem like\n * a waste of time; however, if we decide to once again rely on nBusMask for emulating A20 wrap-around\n * (instead of changing the physical memory map to alias the 2nd Mb to the 1st Mb), then performing\n * consistent masking will be important.\n *\n * Also, addrPDE, addrPTE and addrPhys do not need any offsets added to them, because we immediately shift\n * the offset portion of those addresses out. But for now, at least for debugging and documentation purposes,\n * my preference is to include the offset in the address calculations.\n *\n * Besides, this should not be a performance-critical function; it's normally called only once per UNPAGED\n * page. Obviously, if CR3 is constantly being updated, that will trigger repeated calls to enablePageBlocks(),\n * which will perform our equivalent of a TLB flush (ie, resetting all PAGED blocks back to UNPAGED blocks).\n * That would hurt our performance, but it would hurt performance on a real machine as well, so presumably\n * CR3 updates will be minimal.\n *\n * @this {CPUX86}\n * @param {number} addr is a linear address\n * @param {boolean} fWrite (true if called for a write, false if for a read)\n * @param {boolean} [fSuppress] (true if any faults, remapping, etc should be suppressed)\n * @return {Memory}\n */\n mapPageBlock(addr, fWrite, fSuppress)\n {\n var offPDE = (addr & X86.LADDR.PDE.MASK) >>> X86.LADDR.PDE.SHIFT;\n var addrPDE = this.regCR3 + offPDE;\n\n /*\n * bus.getLong(addrPDE) would be simpler, but setPhysBlock() needs to know blockPDE and offPDE, too.\n * TODO: Since we're immediately shifting addrPDE by nBlockShift, then we could also skip adding offPDE.\n */\n var blockPDE = this.aBusBlocks[(addrPDE & this.nBusMask) >>> this.nBlockShift];\n var pde = blockPDE.readLong(offPDE);\n\n if (!(pde & X86.PTE.PRESENT)) {\n if (!fSuppress) X86.helpPageFault.call(this, addr, false, fWrite);\n return this.memEmpty;\n }\n\n if (!(pde & X86.PTE.USER) && this.nCPL == 3) {\n if (!fSuppress) X86.helpPageFault.call(this, addr, true, fWrite);\n return this.memEmpty;\n }\n\n var offPTE = (addr & X86.LADDR.PTE.MASK) >>> X86.LADDR.PTE.SHIFT;\n var addrPTE = (pde & X86.PTE.FRAME) + offPTE;\n\n /*\n * bus.getLong(addrPTE) would be simpler, but setPhysBlock() needs to know blockPTE and offPTE, too.\n * TODO: Since we're immediately shifting addrPDE by nBlockShift, then we could also skip adding offPTE.\n */\n var blockPTE = this.aBusBlocks[(addrPTE & this.nBusMask) >>> this.nBlockShift];\n var pte = blockPTE.readLong(offPTE);\n\n if (!(pte & X86.PTE.PRESENT)) {\n if (!fSuppress) X86.helpPageFault.call(this, addr, false, fWrite);\n return this.memEmpty;\n }\n\n if (!(pte & X86.PTE.USER) && this.nCPL == 3) {\n if (!fSuppress) X86.helpPageFault.call(this, addr, true, fWrite);\n return this.memEmpty;\n }\n\n var addrPhys = (pte & X86.PTE.FRAME) + (addr & X86.LADDR.OFFSET);\n /*\n * TODO: Since we're immediately shifting addrPhys by nBlockShift, we could also skip adding the addr's offset.\n */\n var blockPhys = this.aBusBlocks[(addrPhys & this.nBusMask) >>> this.nBlockShift];\n if (fSuppress) return blockPhys;\n\n var iBlock = addr >>> this.nBlockShift;\n var block = this.aMemBlocks[iBlock];\n\n /*\n * So we have the block containing the physical memory corresponding to the given linear address.\n *\n * Now we can create a new PAGED Memory block and record the physical block info using setPhysBlock().\n */\n var blockPage = this.acquirePageBlock(addr & ~X86.LADDR.OFFSET);\n blockPage.setPhysBlock(blockPhys, blockPDE, offPDE, blockPTE, offPTE);\n blockPage.copyBreakpoints(this.dbg, block);\n\n this.aMemBlocks[iBlock] = blockPage;\n this.aBlocksPaged.push(iBlock);\n\n return blockPage;\n }\n\n /**\n * disablePageBlocks()\n *\n * Whenever the CPU turns off paging, this function restores the CPU's original aMemBlocks.\n *\n * @this {CPUX86}\n */\n disablePageBlocks()\n {\n if (this.aMemBlocks !== this.aBusBlocks) {\n this.aMemBlocks = this.aBusBlocks;\n this.blockUnpaged = null;\n this.aBlocksPaged = null;\n this.memEmpty = null;\n }\n }\n\n /**\n * isPagingEnabled()\n *\n * @this {CPUX86}\n * @return {boolean}\n */\n isPagingEnabled()\n {\n var fPaging = !!(this.regCR0 & X86.CR0.PG);\n\n return fPaging;\n }\n\n /**\n * initProcessor()\n *\n * This isolates 80186/80188/80286/80386 support, so that it can be selectively enabled/tested.\n *\n * Here's a summary of 80186/80188 differences according to \"AP-186: Introduction to the 80186\n * Microprocessor, March 1983\" (pp.55-56). \"The iAPX 86,88 and iAPX 186,188 User's Manual Programmer's\n * Reference\", p.3-38, apparently contains the same information, but I've not seen that document.\n *\n * Undefined [Invalid] Opcodes:\n *\n * When the opcodes 63H, 64H, 65H, 66H, 67H, F1H, FEH/xx111xxxB and FFH/xx111xxxB are executed,\n * the 80186 will execute an illegal [invalid] instruction exception, interrupt 0x06.\n * The 8086 will ignore the opcode.\n *\n * 0FH opcode:\n *\n * When the opcode 0FH is encountered, the 8086 will execute a POP CS, while the 80186 will\n * execute an illegal [invalid] instruction exception, interrupt 0x06.\n *\n * Word Write at Offset FFFFH:\n *\n * When a word write is performed at offset FFFFH in a segment, the 8086 will write one byte\n * at offset FFFFH, and the other at offset 0, while the 80186 will write one byte at offset\n * FFFFH, and the other at offset 10000H (one byte beyond the end of the segment). One byte segment\n * underflow will also occur (on the 80186) if a stack PUSH is executed and the Stack Pointer\n * contains the value 1.\n *\n * Shift/Rotate by Value Greater Then [sic] 31:\n *\n * Before the 80186 performs a shift or rotate by a value (either in the CL register, or by an\n * immediate value) it ANDs the value with 1FH, limiting the number of bits rotated to less than 32.\n * The 8086 does not do this.\n *\n * LOCK prefix:\n *\n * The 8086 activates its LOCK signal immediately after executing the LOCK prefix. The 80186 does\n * not activate the LOCK signal until the processor is ready to begin the data cycles associated\n * with the LOCKed instruction.\n *\n * Interrupted String Move Instructions:\n *\n * If an 8086 is interrupted during the execution of a repeated string move instruction, the return\n * value it will push on the stack will point to the last prefix instruction before the string move\n * instruction. If the instruction had more than one prefix (e.g., a segment override prefix in\n * addition to the repeat prefix), it will not be re-executed upon returning from the interrupt.\n * The 80186 will push the value of the first prefix to the repeated instruction, so long as prefixes\n * are not repeated, allowing the string instruction to properly resume.\n *\n * Conditions causing divide error with an integer divide:\n *\n * The 8086 will cause a divide error whenever the absolute value of the quotient is greater then\n * [sic] 7FFFH (for word operations) or if the absolute value of the quotient is greater than 7FH\n * (for byte operations). The 80186 has expanded the range of negative numbers allowed as a quotient\n * by 1 to include 8000H and 80H. These numbers represent the most negative numbers representable\n * using 2's complement arithmetic (equaling -32768 and -128 in decimal, respectively).\n *\n * ESC Opcode:\n *\n * The 80186 may be programmed to cause an interrupt type 7 whenever an ESCape instruction (used for\n * co-processors like the 8087) is executed. The 8086 has no such provision. Before the 80186 performs\n * this trap, it must be programmed to do so. [The details of this \"programming\" are not included.]\n *\n * Here's a summary of 80286 differences according to \"80286 and 80287 Programmer's Reference Manual\",\n * Appendix C, p.C-1 (p.329):\n *\n * 1. Add Six Interrupt Vectors\n *\n * The 80286 adds six interrupts which arise only if the 8086 program has a hidden bug. These interrupts\n * occur only for instructions which were undefined on the 8086/8088 or if a segment wraparound is attempted.\n * It is recommended that you add an interrupt handler to the 8086 software that is to be run on the 80286,\n * which will treat these interrupts as invalid operations.\n *\n * This additional software does not significantly effect [sic] the existing 8086 software because the interrupts\n * do not normally occur and should not already have been used since they are in the interrupt group reserved\n * by Intel. [NOTE: IBM ignored Intel's admonishments.]\n *\n * 2. Do not Rely on 8086/8088 Instruction Clock Counts\n *\n * The 80286 takes fewer clocks for most instructions than the 8086/8088. The areas to look into are delays\n * between I/0 operations, and assumed delays in 8086/8088 operating in parallel with an 8087.\n *\n * 3. Divide Exceptions Point at the DIV Instruction\n *\n * Any interrupt on the 80286 will always leave the saved CS:IP value pointing at the beginning of the\n * instruction that failed (including prefixes). On the 8086, the CS:IP value saved for a divide exception\n * points at the next instruction.\n *\n * 4. Use Interrupt 16 (0x10) for Numeric Exceptions\n *\n * Any 80287 system must use interrupt vector 16 for the numeric error interrupt. If an 8086/8087 or 8088/8087\n * system uses another vector for the 8087 interrupt, both vectors should point at the numeric error interrupt\n * handler.\n *\n * 5. Numeric Exception Handlers Should allow Prefixes\n *\n * The saved CS:IP value in the NPX environment save area will point at any leading prefixes before an ESC\n * instruction. On 8086/8088 systems, this value points only at the ESC instruction.\n *\n * 6. Do Not Attempt Undefined 8086/8088 Operations\n *\n * Instructions like POP CS or MOV CS,op will either cause exception 6 (undefined [invalid] opcode) or perform\n * a protection setup operation like LIDT on the 80286. Undefined bit encodings for bits 5-3 of the second byte\n * of POP MEM or PUSH MEM will cause exception 13 on the 80286.\n *\n * 7. Place a Far JMP Instruction at FFFF0H\n *\n * After reset, CS:IP = F000:FFF0 on the 80286 (versus FFFF:0000 on the 8086/8088). This change was made to allow\n * sufficient code space to enter protected mode without reloading CS. Placing a far JMP instruction at FFFF0H\n * will avoid this difference. Note that the BOOTSTRAP option of LOC86 will automatically generate this jump\n * instruction.\n *\n * 8. Do not Rely on the Value Written by PUSH SP\n *\n * The 80286 will push a different value on the stack for PUSH SP than the 8086/8088. If the value pushed is\n * important [and when would it NOT be?], replace PUSH SP instructions with the following three instructions:\n *\n * PUSH BP\n * MOV BP,SP\n * XCHG BP,[BP]\n *\n * This code functions as the 8086/8088 PUSH SP instruction on the 80286.\n *\n * 9. Do not Shift or Rotate by More than 31 Bits\n *\n * The 80286 masks all shift/rotate counts to the low 5 bits. This MOD 32 operation limits the count to a maximum\n * of 31 bits. With this change, the longest shift/rotate instruction is 39 clocks. Without this change, the longest\n * shift/rotate instruction would be 264 clocks, which delays interrupt response until the instruction completes\n * execution.\n *\n * 10. Do not Duplicate Prefixes\n *\n * The 80286 sets an instruction length limit of 10 bytes. The only way to violate this limit is by duplicating\n * a prefix two or more times before an instruction. Exception 6 occurs if the instruction length limit is violated.\n * The 8086/8088 has no instruction length limit.\n *\n * 11. Do not Rely on Odd 8086/8088 LOCK Characteristics\n *\n * The LOCK prefix and its corresponding output signal should only be used to prevent other bus masters from\n * interrupting a data movement operation. The 80286 will always assert LOCK during an XCHG instruction with memory\n * (even if the LOCK prefix was not used). LOCK should only be used with the XCHG, MOV, MOVS, INS, and OUTS instructions.\n *\n * The 80286 LOCK signal will not go active during an instruction prefetch.\n *\n * 12. Do not Single Step External Interrupt Handlers\n *\n * The priority of the 80286 single step interrupt is different from that of the 8086/8088. This change was made\n * to prevent an external interrupt from being single-stepped if it occurs while single stepping through a program.\n * The 80286 single step interrupt has higher priority than any external interrupt.\n *\n * The 80286 will still single step through an interrupt handler invoked by INT instructions or an instruction\n * exception.\n *\n * 13. Do not Rely on IDIV Exceptions for Quotients of 80H or 8000H\n *\n * The 80286 can generate the largest negative number as a quotient for IDIV instructions. The 8086 will instead\n * cause exception O.\n *\n * 14. Do not Rely on NMI Interrupting NMI Handlers\n *\n * After an NMI is recognized, the NMI input and processor extension limit error interrupt is masked until the\n * first IRET instruction is executed.\n *\n * 15. The NPX error signal does not pass through an interrupt controller (an 8087 INT signal does). Any interrupt\n * controller-oriented instructions for the 8087 may have to be deleted.\n *\n * 16. If any real-mode program relies on address space wrap-around (e.g., FFF0:0400=0000:0300), then external hardware\n * should be used to force the upper 4 addresses to zero during real mode.\n *\n * 17. Do not use I/O ports 00F8-00FFH. These are reserved for controlling 80287 and future processor extensions.\n *\n * @this {CPUX86}\n */\n initProcessor()\n {\n this.PS_SET = X86.PS_SET_8086;\n this.PS_DIRECT = X86.PS_DIRECT_8086;\n this.PS_CLEAR_RM = X86.PS.IOPL.MASK | X86.PS.NT;\n\n this.OPFLAG_NOINTR_8086 = X86.OPFLAG.NOINTR;\n this.nShiftCountMask = 0xff; // on an 8086/8088, all shift counts are used as-is\n\n this.cycleCounts = (this.model >= X86.MODEL_80286? X86.CYCLES_80286 : X86.CYCLES_8088);\n\n this.aOps = X86.aOps;\n this.aOpGrp4b = X86.aOpGrp4b;\n this.aOpGrp4w = X86.aOpGrp4w;\n this.aOpGrp6 = X86.aOpGrp6Real; // setProtMode() will ensure that aOpGrp6 is switched\n\n if (this.model >= X86.MODEL_80186) {\n /*\n * I don't go out of my way to make 80186/80188 cycle times accurate, since I'm not aware of any\n * IBM PC models that used those processors; beyond the 8086, my next priorities are the 80286 and\n * 80386, but I might revisit the 80186 someday.\n *\n * Instruction handlers that contain \"hard-coded\" 80286 cycle times include: opINSb, opINSw, opOUTSb,\n * opOUTSw, opENTER, and opLEAVE.\n */\n this.aOps = X86.aOps.slice(); // make copies of opcode tables before modifying\n this.aOpGrp4b = X86.aOpGrp4b.slice();\n this.aOpGrp4w = X86.aOpGrp4w.slice();\n this.nShiftCountMask = 0x1f; // on newer processors, all shift counts are MOD 32\n this.aOps[0x0F] = X86.opInvalid;\n this.aOps[X86.OPCODE.PUSHA] = X86.opPUSHA; // 0x60\n this.aOps[X86.OPCODE.POPA] = X86.opPOPA; // 0x61\n this.aOps[X86.OPCODE.BOUND] = X86.opBOUND; // 0x62\n this.aOps[X86.OPCODE.ARPL] = X86.opInvalid; // 0x63\n this.aOps[X86.OPCODE.FS] = X86.opInvalid; // 0x64\n this.aOps[X86.OPCODE.GS] = X86.opInvalid; // 0x65\n this.aOps[X86.OPCODE.OS] = X86.opInvalid; // 0x66\n this.aOps[X86.OPCODE.AS] = X86.opInvalid; // 0x67\n this.aOps[X86.OPCODE.PUSHN] = X86.opPUSHn; // 0x68\n this.aOps[X86.OPCODE.IMULN] = X86.opIMULn; // 0x69\n this.aOps[X86.OPCODE.PUSH8] = X86.opPUSH8; // 0x6A\n this.aOps[X86.OPCODE.IMUL8] = X86.opIMUL8; // 0x6B\n this.aOps[X86.OPCODE.INSB] = X86.opINSb; // 0x6C\n this.aOps[X86.OPCODE.INSW] = X86.opINSw; // 0x6D\n this.aOps[X86.OPCODE.OUTSB] = X86.opOUTSb; // 0x6E\n this.aOps[X86.OPCODE.OUTSW] = X86.opOUTSw; // 0x6F\n this.aOps[0xC0] = X86.opGRP2bn; // 0xC0\n this.aOps[0xC1] = X86.opGRP2wn; // 0xC1\n this.aOps[X86.OPCODE.ENTER] = X86.opENTER; // 0xC8\n this.aOps[X86.OPCODE.LEAVE] = X86.opLEAVE; // 0xC9\n this.aOps[0xF1] = X86.opINT1; // 0xF1\n this.aOpGrp4b[0x07] = X86.fnGRPInvalid;\n this.aOpGrp4w[0x07] = X86.fnGRPInvalid;\n\n if (this.model >= X86.MODEL_80286) {\n\n this.PS_SET = X86.PS.BIT1; // on the 80286, only BIT1 of Processor Status (flags) is always set\n this.PS_DIRECT |= X86.PS.IOPL.MASK | X86.PS.NT;\n\n this.OPFLAG_NOINTR_8086 = 0; // for instructions that do *not* set NOINTR on an 80286 (eg, non-SS segment loads)\n\n this.aOps[0x0F] = X86.op0F;\n this.aOps0F = X86.aOps0F.slice();\n for (var i = 0; i < this.aOps0F.length; i++) {\n if (!this.aOps0F[i]) this.aOps0F[i] = X86.opUndefined;\n }\n this.aOps[X86.OPCODE.PUSHSP] = X86.opPUSHSP; // 0x54\n this.aOps[X86.OPCODE.ARPL] = X86.opARPL; // 0x63\n\n if (I386 && this.model >= X86.MODEL_80386) {\n var bOpcode;\n this.PS_CLEAR_RM = 0; // NOTE: This allows the 80386 to modify X86.PS.NT in real-mode (which is presumably OK)\n this.PS_DIRECT |= X86.PS.RF | X86.PS.VM;\n this.aOps[X86.OPCODE.FS] = X86.opFS; // 0x64\n this.aOps[X86.OPCODE.GS] = X86.opGS; // 0x65\n this.aOps[X86.OPCODE.OS] = X86.opOS; // 0x66\n this.aOps[X86.OPCODE.AS] = X86.opAS; // 0x67\n for (bOpcode in X86.aOps0F386) {\n this.aOps0F[+bOpcode] = X86.aOps0F386[+bOpcode];\n }\n if (this.stepping >= X86.STEPPING_80386_A0 && this.stepping <= X86.STEPPING_80386_B0) {\n this.aOps0F[0xA6] = X86.opXBTS;\n this.aOps0F[0xA7] = X86.opIBTS;\n }\n }\n }\n }\n }\n\n /**\n * reset()\n *\n * @this {CPUX86}\n */\n reset()\n {\n this.resetRegs();\n this.resetCycles();\n this.clearError(); // clear any fatal error/exception that setError() may have flagged\n }\n\n /**\n * getReg(i)\n *\n * @this {CPUX86}\n * @param {number} i (0-7)\n * @return {number}\n */\n getReg(i)\n {\n var reg;\n switch(i) {\n case 0x0:\n reg = this.regEAX;\n break;\n case 0x1:\n reg = this.regECX;\n break;\n case 0x2:\n reg = this.regEDX;\n break;\n case 0x3:\n reg = this.regEBX;\n break;\n case 0x4:\n reg = this.getSP();\n break;\n case 0x5:\n reg = this.regEBP;\n break;\n case 0x6:\n reg = this.regESI;\n break;\n case 0x7:\n reg = this.regEDI;\n break;\n }\n return reg;\n }\n\n /**\n * setReg(i, reg)\n *\n * @this {CPUX86}\n * @param {number} i (0-7)\n * @param {number} reg\n */\n setReg(i, reg)\n {\n switch(i) {\n case 0x0:\n this.regEAX = reg;\n break;\n case 0x1:\n this.regECX = reg;\n break;\n case 0x2:\n this.regEDX = reg;\n break;\n case 0x3:\n this.regEBX = reg;\n break;\n case 0x4:\n this.setSP(reg);\n break;\n case 0x5:\n this.regEBP = reg;\n break;\n case 0x6:\n this.regESI = reg;\n break;\n case 0x7:\n this.regEDI = reg;\n break;\n }\n }\n\n /**\n * resetRegs()\n *\n * According to \"The 8086 Book\", p.7-5, a RESET signal initializes the following registers:\n *\n * PS = 0x0000 (which has the important side-effect of disabling interrupts and traps)\n * IP = 0x0000\n * CS = 0xFFFF\n * DS/ES/SS = 0x0000\n *\n * It is silent as to whether the remaining registers are initialized to any particular values.\n *\n * According to the \"80286 and 80287 Programmer's Reference Manual\", these 80286 registers are reset:\n *\n * PS = 0x0002\n * MSW = 0xFFF0\n * IP = 0xFFF0\n * CS Selector = 0xF000 DS/ES/SS Selector = 0x0000\n * CS Base = 0xFF0000 DS/ES/SS Base = 0x000000 IDT Base = 0x000000\n * CS Limit = 0xFFFF DS/ES/SS Limit = 0xFFFF IDT Limit = 0x03FF\n *\n * And from the \"INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986\", section 10.1:\n *\n * The contents of EAX depend upon the results of the power-up self test. The self-test may be requested\n * externally by assertion of BUSY# at the end of RESET. The EAX register holds zero if the 80386 passed\n * the test. A nonzero value in EAX after self-test indicates that the particular 80386 unit is faulty.\n * If the self-test is not requested, the contents of EAX after RESET is undefined.\n *\n * DX holds a component identifier and revision number after RESET as Figure 10-1 illustrates. DH contains\n * 3, which indicates an 80386 component. DL contains a unique identifier of the revision level.\n *\n * EFLAGS = 0x00000002\n * IP = 0x0000FFF0\n * CS selector = 0xF000 (base of 0xFFFF0000 and limit of 0xFFFF)\n * DS selector = 0x0000\n * ES selector = 0x0000\n * SS selector = 0x0000\n * FS selector = 0x0000\n * GS selector = 0x0000\n * IDTR = base of 0 and limit of 0x3FF\n *\n * All other 80386 registers are undefined after a reset (ie, Intel did not document how or if they are set).\n *\n * We've elected to set DX to 0x0308 on a reset, the highest known 80386 revision, since we have no desire to\n * try to emulate all the bugs in older (eg, B1) steppings -- at least not initially. We leave stepping-accurate\n * emulation for another day. It's also known that the B1 (and possibly B0) reported 0x0303 in DX, and that\n * the D0 stepping reported 0x0305; beyond that, it's not known exactly what revision numbers Intel used for all\n * 80386 revisions.\n *\n * We define some additional \"registers\", such as regLIP, which mirrors the linear address corresponding to\n * CS:IP (the address of the next opcode byte). In fact, regLIP functions as our internal IP register, so any\n * code that needs the real IP must call getIP(). This, in turn, means that whenever CS or IP must be modified,\n * regLIP must be recalculated, so you must use either setCSIP(), which takes both an offset and a segment,\n * or setIP(), whichever is appropriate; in unusual cases where only segCS is changing (eg, undocumented 8086\n * opcodes), use setCS().\n *\n * Similarly, regLSP mirrors the linear address corresponding to SS:SP, and therefore you must rely on getSP()\n * to read the current SP, and setSP() and setSS() to update SP and SS.\n *\n * The other segment registers, such as segDS and segES, have similar getters and setters, but we do not mirror\n * any other segment:offset values in the same way that regLIP mirrors CS:IP, or that regLSP mirrors SS:SP.\n *\n * @this {CPUX86}\n */\n resetRegs()\n {\n this.regEAX = 0;\n this.regEBX = 0;\n this.regECX = 0;\n this.regEDX = 0;\n this.regESP = 0; // this isn't needed in a 16-bit environment, but is required for I386\n this.regEBP = 0;\n this.regESI = 0;\n this.regEDI = 0;\n\n /*\n * The following are internal \"registers\" used to capture intermediate values inside selected helper\n * functions and use them if they've been modified (or are known to change); for example, the MUL and DIV\n * instructions perform calculations that must be propagated to specific registers (eg, AX and/or DX), which\n * the ModRM decoder functions don't know about. We initialize them here mainly for documentation purposes.\n */\n this.fMDSet = false; // regMDHi and/or regMDLo are invalid unless fMDSet is true\n this.regMDLo = this.regMDHi = 0;\n this.r64Div = [0, 0];\n this.r64Rem = [0, 0];\n this.regXX = 0; // for internal use only (eg, assists with ModRM helper functions)\n\n /*\n * This internal \"register\" is set in selected opcode handlers to record the original opcode; ordinarily,\n * we dispatch on the opcode but never save it, because it's rarely needed.\n */\n this.bOpcode = 0;\n\n /*\n * Another internal \"register\" we occasionally need is an interim copy of bModRM, set inside selected opcode\n * handlers so that the helper function can have access to the instruction's bModRM without resorting to a\n * closure (which, in the Chrome V8 engine, for example, may cause constant recompilation).\n */\n this.bModRM = 0;\n\n /*\n * NOTE: Even though the 8086 doesn't have CR0 (aka MSW) and IDTR, we initialize them for ALL CPUs, so\n * that functions like X86.helpINT() can use the same code for both. The 8086/8088 have no direct way\n * of accessing or changing them, so this is an implementation detail those processors are unaware of.\n */\n this.regCR0 = X86.CR0.MSW.ON;\n this.addrIDT = 0;\n this.addrIDTLimit = 0x03FF;\n this.regPS = this.nIOPL = 0;// these should be set before the first setPS() call\n\n /*\n * Define all the result registers that can be used to \"cache\" arithmetic and logical flags.\n *\n * In addition, setPS() will initialize resultType, which keeps track of which flags are cached,\n * and resultSize, which maintains the size of the last result; initially, no flags are cached.\n */\n this.resultDst = this.resultSrc = this.resultArith = this.resultLogic = 0;\n\n /*\n * nFault is set by helpFault() and reset (to -1) by resetRegs() and opIRET(). Its initial purpose was to\n * help helpFault() determine when a nested fault should be converted into either a double-fault (DF_FAULT)\n * or a triple-fault (ie, a processor reset).\n *\n * It has since evolved into another important role: helping segCS.loadIDT() know when an exception\n * is occurring, as opposed to a software interrupt (eg, INT3, INT n or INTO). The former must set nFault\n * to the corresponding fault #, whereas the latter must set it to -1, so that if the IDT contains a gate\n * whose DPL < CPL, a GP fault will be generated instead.\n *\n * The former always call helpFault(), and the latter call helpTrap(), so nFault is updated automatically.\n * However, there are also intermediate cases, like hardware interrupts, which call helpINT() after manually\n * setting nFault to the IDT #. TODO: Review all those \"intermediate\" cases.\n */\n this.nFault = -1;\n\n /*\n * These are used to snapshot regLIP and regLSP, to help make instructions restartable;\n * currently opLIP is updated prior to every instruction, but opLSP is updated only for instructions\n * that modify the stack pointer (eg, RETF) and should otherwise remain set to X86.ADDR_INVALID.\n *\n * More recently, opCS was added to selectively snapshot an instruction's original CS in case an\n * exception occurs accessing the stack after a new CS has been loaded, allowing the exception handler\n * to recover the old CS and make instructions like CALLF restartable; otherwise, opCS should remain -1.\n *\n * Ditto for opSS and the SS register.\n */\n this.opCS = this.opSS = -1;\n this.opLIP = this.opLSP = X86.ADDR_INVALID;\n\n /*\n * Segment registers used to be defined as separate selector and base variables (eg, regCS and regCS0),\n * but now they are defined as SegX86 objects.\n */\n this.segCS = new SegX86(this, SegX86.ID.CODE, \"CS\");\n this.segDS = new SegX86(this, SegX86.ID.DATA, \"DS\");\n this.segES = new SegX86(this, SegX86.ID.DATA, \"ES\");\n this.segSS = new SegX86(this, SegX86.ID.STACK, \"SS\");\n this.setSP(0);\n this.setSS(0);\n\n if (I386 && this.model >= X86.MODEL_80386) {\n /*\n * Here lies everything I currently know about 80386 stepping revision numbers...\n */\n switch(this.stepping) {\n case X86.STEPPING_80386_B0:\n case X86.STEPPING_80386_B1:\n this.regEDX = 0x0303;\n break;\n case X86.STEPPING_80386_C0:\n this.regEDX = 0x0304;\n break;\n case X86.STEPPING_80386_D0:\n this.regEDX = 0x0305;\n break;\n case X86.STEPPING_80386_D1:\n case X86.STEPPING_80386_D2:\n this.regEDX = 0x0308;\n break;\n default:\n break; // in the absence of a specific stepping, we leave DX set to zero\n }\n this.regCR0 = X86.CR0.ET; // formerly MSW\n this.regCR1 = 0; // reserved\n this.regCR2 = 0; // page fault linear address (PFLA)\n this.regCR3 = 0; // page directory base register (PDBR)\n this.regDR = [0,0,0,0,null,null,0,0]; // Debug Registers DR0-DR7 (DR4-DR5 are undefined)\n this.regTR = [null,null,null,null,null,null,0,0]; // Test Registers TR0-TR7 (TR0-TR5 are undefined)\n this.segFS = new SegX86(this, SegX86.ID.DATA, \"FS\");\n this.segGS = new SegX86(this, SegX86.ID.DATA, \"GS\");\n /*\n * Synchronize the fact that paging is initially disabled with our PAGEBLOCKS functions\n */\n this.disablePageBlocks();\n }\n\n this.segNULL = new SegX86(this, SegX86.ID.NULL, \"NULL\");\n\n /*\n * The next few initializations mirror what we must do prior to each instruction (ie, inside the stepCPU() function);\n * note that opPrefixes, along with segData and segStack, are reset only after we've executed a non-prefix instruction.\n */\n this.segData = this.segDS;\n this.segStack = this.segSS;\n this.opFlags = this.opPrefixes = 0;\n this.regEA = this.regEAWrite = X86.ADDR_INVALID;\n\n this.segEA = this.segNULL;\n\n /*\n * intFlags contains some internal states we use to indicate whether a hardware interrupt (INTFLAG.INTR) or\n * Trap software interrupt (INTR.TRAP) has been requested, as well as when we're in a \"HLT\" state (INTFLAG.HALT)\n * that requires us to wait for a hardware interrupt (INTFLAG.INTR) before continuing execution.\n *\n * intFlags must be cleared only by checkINTR(), whereas opFlags must be cleared prior to every CPU operation.\n */\n this.intFlags = X86.INTFLAG.NONE;\n\n if (BACKTRACK) {\n /*\n * Initialize the backtrack indexes for all registers to zero. And while, yes, it IS possible\n * for raw data to flow through segment registers as well, it's not common enough in real-mode\n * (and too difficult in protected-mode) to merit the overhead. Ditto for SP, which can't really\n * be considered a general-purpose register.\n *\n * Every time getByte() is called, btiMem0 is filled with the matching backtrack info; similarly,\n * every time getWord() is called, btiMem0 and btiMem1 are filled with the matching backtrack info\n * for the low and high bytes, respectively.\n */\n this.backTrack = {\n btiAL: 0,\n btiAH: 0,\n btiBL: 0,\n btiBH: 0,\n btiCL: 0,\n btiCH: 0,\n btiDL: 0,\n btiDH: 0,\n btiBPLo: 0,\n btiBPHi: 0,\n btiSILo: 0,\n btiSIHi: 0,\n btiDILo: 0,\n btiDIHi: 0,\n btiMem0: 0,\n btiMem1: 0,\n btiMem2: 0,\n btiMem3: 0,\n btiEALo: 0,\n btiEAHi: 0,\n btiIO: 0\n };\n }\n\n /*\n * Set the initial CS:IP appropriate for the processor; this should be done before the first setPS() call,\n * in part so that CPL will be set properly.\n */\n if (this.model < X86.MODEL_80286) {\n this.setCSIP(0, 0xffff);\n } else {\n /*\n * Assorted 80286-specific registers. The GDTR and IDTR registers are stored as the following pieces:\n *\n * GDTR: addrGDT (24 bits) and addrGDTLimit (24 bits)\n * IDTR: addrIDT (24 bits) and addrIDTLimit (24 bits)\n *\n * while the LDTR and TR are stored as special segment registers: segLDT and segTSS.\n *\n * So, yes, our GDTR and IDTR \"registers\" differ from other segment registers in that we do NOT record\n * the 16-bit limit specified by the LGDT or LIDT instructions; instead, we immediately calculate the limiting\n * address, and record that instead.\n *\n * In addition to different CS:IP reset values, the CS base address must be set to the top of the 16Mb\n * address space rather than the top of the first 1Mb (which is why the MODEL_5170 ROM must be addressable\n * at both 0x0F0000 and 0xFF0000; see the ROM component's \"alias\" parameter).\n *\n * TODO: Verify what the 80286 actually sets addrGDT and addrGDTLimit to on reset (or if it leaves them alone).\n */\n this.addrGDT = 0; this.addrGDTLimit = 0xffff; // GDTR\n this.segLDT = new SegX86(this, SegX86.ID.LDT, \"LDT\", true); // LDTR\n this.segTSS = new SegX86(this, SegX86.ID.TSS, \"TSS\", true); // TR\n this.segVER = new SegX86(this, SegX86.ID.VER, \"VER\", true); // a scratch segment register for VERR and VERW instructions\n this.setCSIP(0xfff0, 0xf000); // on an 80286 or 80386, the default CS:IP is 0xF000:0xFFF0 instead of 0xFFFF:0x0000\n this.setCSBase(0xffff0000|0); // on an 80286 or 80386, all CS base address bits above bit 15 must be set\n }\n\n /*\n * This resets the Processor Status flags (regPS), along with all the internal \"result registers\";\n * we've taken care to ensure that both CPL and IOPL are initialized before this first setPS() call.\n */\n this.setPS(0);\n\n /*\n * Now that all the segment registers have been created, it's safe to set the current addressing mode.\n */\n this.setProtMode();\n }\n\n /**\n * updateAddrSize()\n *\n * Select the appropriate ModRM dispatch tables, based on the current ADDRESS size (addrSize), which\n * is based foremost on segCS.sizeAddr, but can also be overridden by an ADDRESS size instruction prefix.\n *\n * There used to be six primary ModRM dispatch table pointers:\n *\n * aOpModRegByte\n * aOpModMemByte\n * aOpModGrpByte\n * aOpModRegWord\n * aOpModMemWord\n * aOpModGrpWord\n *\n * However, when support for the 80386 was added, the number of dispatch tables doubled, and since each entry\n * in the table was a discrete function, decoding was fast, but it also required a LOT of code.\n *\n * So we have now replaced the above table pointers with function pointers:\n *\n * decodeModRegByte (set to one of: modRegByte16, modRegByte32)\n * decodeModMemByte (set to one of: modMemByte16, modMemByte32)\n * decodeModGrpByte (set to one of: modGrpByte16, modGrpByte32)\n * decodeModRegWord (set to one of: modRegShort16, modRegLong16, modRegShort32, modRegLong32)\n * decodeModMemWord (set to one of: modMemShort16, modMemLong16, modMemShort32, modMemLong32)\n * decodeModGrpWord (set to one of: modGrpShort16, modGrpLong16, modGrpShort32, modGrpLong32)\n *\n * So opcode handlers that used to do this:\n *\n * this.aOpModMemByte[b].call(this, X86.fnADDb);\n *\n * now do this:\n *\n * this.decodeModMemByte.call(this, X86.fnADDb);\n *\n * Decoding of ModRM bytes is now slightly slower, but the previous code is still in the repository\n * (look for x86modb.js and x86modw.js for the pre-80386 dispatch tables, and x86modb16.js, x86modb32.js,\n * x86modw16.js, x86modw32.js, and x86modsib.js for the post-80386 dispatch tables).\n *\n * @this {CPUX86}\n */\n updateAddrSize()\n {\n if (!I386) {\n this.getAddr = (PREFETCH? this.getShortPrefetch : this.getShort);\n this.decodeModRegByte = X86.modRegByte16;\n this.decodeModMemByte = X86.modMemByte16;\n this.decodeModGrpByte = X86.modGrpByte16;\n this.decodeModRegWord = X86.modRegShort16;\n this.decodeModMemWord = X86.modMemShort16;\n this.decodeModGrpWord = X86.modGrpShort16;\n } else {\n if (this.sizeAddr == 2) {\n this.getAddr = (PREFETCH? this.getShortPrefetch : this.getShort);\n this.decodeModRegByte = X86.modRegByte16;\n this.decodeModMemByte = X86.modMemByte16;\n this.decodeModGrpByte = X86.modGrpByte16;\n if (this.sizeData == 2) {\n this.decodeModRegWord = X86.modRegShort16;\n this.decodeModMemWord = X86.modMemShort16;\n this.decodeModGrpWord = X86.modGrpShort16;\n } else {\n this.decodeModRegWord = X86.modRegLong16;\n this.decodeModMemWord = X86.modMemLong16;\n this.decodeModGrpWord = X86.modGrpLong16;\n }\n } else {\n this.getAddr = (PREFETCH? this.getLongPrefetch : this.getLong);\n this.decodeModRegByte = X86.modRegByte32;\n this.decodeModMemByte = X86.modMemByte32;\n this.decodeModGrpByte = X86.modGrpByte32;\n if (this.sizeData == 2) {\n this.decodeModRegWord = X86.modRegShort32;\n this.decodeModMemWord = X86.modMemShort32;\n this.decodeModGrpWord = X86.modGrpShort32;\n } else {\n this.decodeModRegWord = X86.modRegLong32;\n this.decodeModMemWord = X86.modMemLong32;\n this.decodeModGrpWord = X86.modGrpLong32;\n }\n }\n }\n }\n\n /**\n * setDataSize(size)\n *\n * This is used by opcodes that require a particular OPERAND size, which we enforce by internally\n * simulating an OPERAND size override, if needed.\n *\n * @this {CPUX86}\n * @param {number} size (2 for 2-byte/16-bit operands, or 4 for 4-byte/32-bit operands)\n */\n setDataSize(size)\n {\n if (this.sizeData != size) {\n this.opPrefixes |= X86.OPFLAG.DATASIZE;\n this.sizeData = size;\n this.maskData = (size == 2? 0xffff : (0xffffffff|0));\n this.updateDataSize();\n }\n }\n\n /**\n * updateDataSize()\n *\n * @this {CPUX86}\n */\n updateDataSize()\n {\n if (this.sizeData == 2) {\n this.typeData = X86.RESULT.WORD;\n this.getWord = this.getShort;\n this.setWord = this.setShort;\n if (this.sizeAddr == 2) {\n this.decodeModRegWord = X86.modRegShort16;\n this.decodeModMemWord = X86.modMemShort16;\n this.decodeModGrpWord = X86.modGrpShort16;\n } else {\n this.decodeModRegWord = X86.modRegShort32;\n this.decodeModMemWord = X86.modMemShort32;\n this.decodeModGrpWord = X86.modGrpShort32;\n }\n } else {\n this.typeData = X86.RESULT.DWORD;\n this.getWord = this.getLong;\n this.setWord = this.setLong;\n if (this.sizeAddr == 2) {\n this.decodeModRegWord = X86.modRegLong16;\n this.decodeModMemWord = X86.modMemLong16;\n this.decodeModGrpWord = X86.modGrpLong16;\n } else {\n this.decodeModRegWord = X86.modRegLong32;\n this.decodeModMemWord = X86.modMemLong32;\n this.decodeModGrpWord = X86.modGrpLong32;\n }\n }\n }\n\n /**\n * resetSizes()\n *\n * @this {CPUX86}\n */\n resetSizes()\n {\n /*\n * The following contain the (default) ADDRESS size (2 for 16 bits, 4 for 32 bits), and the corresponding\n * masks for isolating the (src) bits of an address and clearing the (dst) bits of an address. Like the\n * OPERAND size properties, these are reset to their segCS counterparts at the start of every new instruction.\n */\n this.sizeAddr = this.segCS.sizeAddr;\n this.maskAddr = this.segCS.maskAddr;\n\n /*\n * It's also worth noting that instructions that implicitly use the stack also rely on STACK size,\n * which is based on the BIG bit of the last descriptor loaded into SS; use the following segSS properties:\n *\n * segSS.sizeAddr (2 or 4)\n * segSS.maskAddr (0xffff or 0xffffffff)\n *\n * As there is no STACK size instruction prefix override, there's no need to propagate these segSS properties\n * to separate CPUX86 properties, as we do for the OPERAND size and ADDRESS size properties.\n */\n\n this.updateAddrSize();\n\n /*\n * The following contain the (default) OPERAND size (2 for 16 bits, 4 for 32 bits), and the corresponding masks\n * for isolating the (src) bits of an OPERAND and clearing the (dst) bits of an OPERAND. These are reset to\n * their segCS counterparts at the start of every new instruction, but are also set here for documentation purposes.\n */\n this.sizeData = this.segCS.sizeData;\n this.maskData = this.segCS.maskData;\n\n this.updateDataSize();\n\n this.opPrefixes &= ~(X86.OPFLAG.ADDRSIZE | X86.OPFLAG.DATASIZE);\n }\n\n /**\n * getChecksum()\n *\n * @this {CPUX86}\n * @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code)\n */\n getChecksum()\n {\n var sum = (this.regEAX + this.regEBX + this.regECX + this.regEDX + this.getSP() + this.regEBP + this.regESI + this.regEDI)|0;\n sum = (sum + this.getIP() + this.getCS() + this.getDS() + this.getSS() + this.getES() + this.getPS())|0;\n return sum;\n }\n\n /**\n * addIntNotify(nInt, fn)\n *\n * Add a software interrupt notification handler to the CPU's list of such handlers.\n *\n * TODO: Consider adding removeIntNotify(). Example use case: if the Debugger's intWindowsDebugger() function\n * detects that an INT 0x41 client is loaded, it would be quite happy to uninstall itself.\n *\n * @this {CPUX86}\n * @param {number} nInt\n * @param {function(number)} fn is called with the LIP value following the software interrupt\n */\n addIntNotify(nInt, fn)\n {\n if (this.aIntNotify[nInt] === undefined) {\n this.aIntNotify[nInt] = [];\n }\n this.aIntNotify[nInt].push(fn);\n }\n\n /**\n * checkIntNotify(nInt)\n *\n * NOTE: This is called ONLY for \"INT N\" instructions -- not \"INTO\" or breakpoint or single-step interrupts\n * or divide exception interrupts, or hardware interrupts, or any simulation of an interrupt (eg, \"PUSHF/CALLF\").\n *\n * @this {CPUX86}\n * @param {number} nInt\n * @return {boolean} true if software interrupt may proceed, false if software interrupt should be skipped\n */\n checkIntNotify(nInt)\n {\n var aNotify = this.aIntNotify[nInt];\n if (aNotify !== undefined) {\n for (var i = 0; i < aNotify.length; i++) {\n if (!aNotify[i](this.regLIP)) {\n return false;\n }\n }\n }\n /*\n * The enabling of INT messages is one of the criteria that's also included in the Debugger's checksEnabled()\n * function, and therefore included in fDebugCheck, so for maximum speed, we check fDebugCheck first.\n *\n * NOTE: We've added MAXDEBUG to the test below, because onIntReturn() generates a lot of noise, via\n * dbg.messageIntReturn(), and because there's no way to be sure we'll catch the return (or for some interrupts,\n * *whether* they will return), so it's safer to disable this feature unless you really want it.\n *\n * For most purposes, just having dbg.messageInt(), and the Debugger's ability to selectively turn categories\n * of messages on and off, is good enough.\n */\n if (DEBUGGER && this.flags.debugCheck) {\n if (this.messageEnabled(Messages.INT) && this.dbg.messageInt(nInt, this.regLIP) && MAXDEBUG) {\n this.addIntReturn(this.regLIP, function(cpu, nCycles) {\n return function onIntReturn(nLevel) {\n cpu.dbg.messageIntReturn(nInt, nLevel, cpu.getCycles() - nCycles);\n };\n }(this, this.getCycles()));\n }\n }\n return true;\n }\n\n /**\n * addIntReturn(addr, fn)\n *\n * Add a return notification handler to the CPU's list of such handlers.\n *\n * When fn(n) is called, it's passed a \"software interrupt level\", which will normally be 0,\n * unless it's a return from a nested software interrupt (eg, return from INT 0x10 Video BIOS\n * call issued inside another INT 0x10 Video BIOS call).\n *\n * Note that the nesting could be due to a completely different software interrupt that\n * another interrupt notification function is intercepting, so use it as an advisory value only.\n *\n * @this {CPUX86}\n * @param {number} addr is a linear address\n * @param {function(number)} fn is an interrupt-return notification function\n */\n addIntReturn(addr, fn)\n {\n if (fn !== undefined) {\n if (this.aIntReturn[addr] == null) {\n this.cIntReturn++;\n }\n this.aIntReturn[addr] = fn;\n }\n }\n\n /**\n * checkIntReturn(addr)\n *\n * We check for possible \"INT n\" software interrupt returns in the cases of \"IRET\" (helpIRET), \"RETF 2\"\n * (helpRETF) and \"JMPF [DWORD]\" (fnJMPFdw).\n *\n * \"JMPF [DWORD]\" is an unfortunate choice that newer versions of DOS (as of at least 3.20, and probably\n * earlier) employed in their INT 0x13 hooks; I would have preferred not making this call for that opcode.\n *\n * It is expected (though not required) that callers will check cIntReturn and avoid calling this function\n * if the count is zero, for maximum performance.\n *\n * @this {CPUX86}\n * @param {number} addr is a linear address\n */\n checkIntReturn(addr)\n {\n var fn = this.aIntReturn[addr];\n if (fn != null) {\n fn(--this.cIntReturn);\n delete this.aIntReturn[addr];\n }\n }\n\n /**\n * checkDebugRegisters(fEnable)\n *\n * opMOVdr() simplifies its life by doing work ONLY if the contents of a Debug register is actually changing.\n *\n * Whenever a single register is about to change, it calls this function with fEnable set to false to REMOVE any\n * active checks, then updates the Debug register, then calls us again with fEnable set to true to (re)ADD active\n * checks.\n *\n * @this {CPUX86}\n * @param {boolean} fEnable\n */\n checkDebugRegisters(fEnable)\n {\n /*\n * We use a constant mask for the enable bits (X86.DR7.L0 | X86.DR7.G0) and shift our copy of regDR7\n * right 2 bits after each Debug register check.\n *\n * Similarly, we make a copy of regDR7 in bitsDR7 and shift the latter right 4 bits at a time, so that\n * the RW and LEN bits for the next Debug register are always in positions 1-0 and 3-2, respectively.\n */\n var regDR7 = this.regDR[7];\n var bitsDR7 = regDR7 >> 16;\n\n for (var i = 0; i < 4; i++) {\n if (regDR7 & (X86.DR7.L0 | X86.DR7.G0)) {\n /*\n * We look only to the low bit of the RW field to determine if we should be watching for a write.\n * FYI, if the low bit is clear but the high bit is set, that's \"undefined\"; we treat it as a read.\n */\n var fWrite = !!(bitsDR7 & 0x1);\n /*\n * The address in regDR[i] should already be masked with ~0x1 for 2-byte accesses (LEN == 0x1) or\n * with ~0x3 for 4-byte accesses (LEN == 0x3), but if the client forgets, the hardware supposedly\n * enforces it, so that's what we do here, too.\n *\n * FYI, if LEN is set to the \"undefined\" value of (0x2), we still apply a mask to the address, albeit\n * a nonsensical mask of ~0x2 or 0xfffffffd. That's how we define that particular \"undefined\" LEN.\n */\n var addr = this.regDR[i];\n var len = ((bitsDR7 >> 2) & 0x3);\n addr &= ~len; // NOTE: if LEN == 0x0, we don't need to mask, but ~0x0 is equivalent to no mask\n if (fEnable) {\n this.addMemCheck(addr, fWrite);\n } else {\n this.removeMemCheck(addr, fWrite);\n }\n }\n regDR7 >>= 2; bitsDR7 >>= 4;\n }\n }\n\n /**\n * checkMemoryException(addr, nb, fWrite)\n *\n * This \"check\" function is called by a Memory block to inform us that a memory read or write is occurring,\n * giving us the opportunity look for a matching \"read\" or \"write\" breakpoint enabled in one of the DRn registers.\n *\n * TODO: This currently does not discriminate between data reads and execution reads. When we switch to a true\n * \"prefetch\" model, that would also be a good time to include a signal to this function indicating which \"read\"\n * accesses are are actually \"exec\" accesses.\n *\n * @this {CPUX86}\n * @param {number} addr\n * @param {number} nb (# of bytes)\n * @param {boolean|null} [fWrite] (false if read, true if write, null if exec)\n */\n checkMemoryException(addr, nb, fWrite)\n {\n /*\n * NOTE: We're preventing redundant X86.EXCEPTION.DB_EXC exceptions for a single instruction by checking\n * X86.OPFLAG.DBEXC. I decided not to rely on the generic X86.OPFLAG.FAULT, because if an instruction\n * first triggers a DIFFERENT exception which then triggers a DEBUG exception (eg, because a Debug register\n * was set on the IDT entry of the first exception), then presumably we'd like to see that DEBUG exception,\n * as opposed to, say, a double fault. TODO: Determine whether that SHOULD generate a double-fault.\n */\n if (!(this.opFlags & X86.OPFLAG.DBEXC) && (this.regDR[7] & X86.DR7.ENABLE)) {\n nb--;\n /*\n * We use a constant mask for the enable bits (X86.DR7.L0 | X86.DR7.G0) and shift our copy of regDR7\n * right 2 bits after each Debug register check.\n *\n * Similarly, we make a copy of regDR7 in bitsDR7 and shift the latter right 4 bits at a time, so that\n * the RW and LEN bits for the next Debug register are always in positions 1-0 and 3-2, respectively.\n */\n var regDR7 = this.regDR[7];\n var bitsDR7 = regDR7 >> 16;\n\n var bitsRWMask = X86.DR7.RW0 >> 16;\n var bitsRWRequired = (fWrite? 0x1 : (fWrite == false? 0x3 : 0x0));\n\n for (var i = 0; i < 4; i++) {\n if ((regDR7 & (X86.DR7.L0 | X86.DR7.G0)) && (bitsDR7 & bitsRWMask) == bitsRWRequired) {\n /*\n * NOTE: We reduced nb from 1-4 to 0-3 above, so we don't need to add 1 to len either.\n */\n var len = (bitsDR7 >> 2);\n /*\n * Time to determine if addr through addr + nb overlaps regDR[i] through regDR[i] + len.\n */\n if (addr + nb >= this.regDR[i] && addr <= this.regDR[i] + len) {\n this.regDR[6] |= (1 << i);\n /*\n * Data access breakpoints are not faults; they must generate a trap at the end of the\n * instruction, so we use the X86.INTFLAG.TRAP flag to generate the X86.EXCEPTION.DB_EXC trap.\n *\n * X86.helpFault.call(this, X86.EXCEPTION.DB_EXC);\n */\n this.intFlags |= X86.INTFLAG.TRAP;\n return;\n }\n }\n regDR7 >>= 2; bitsDR7 >>= 4;\n }\n }\n }\n\n /**\n * isProtMode()\n *\n * @this {CPUX86}\n * @return {boolean} true if protected-mode, false if not\n */\n isProtMode()\n {\n return !!(this.regCR0 & X86.CR0.MSW.PE);\n }\n\n /**\n * isV86Mode()\n *\n * @this {CPUX86}\n * @return {boolean} true if V86-mode, false if not\n */\n isV86Mode()\n {\n return !!(this.regPS & X86.PS.VM);\n }\n\n /**\n * setProtMode(fProt, fV86)\n *\n * Update any opcode handlers that operate significantly differently in real-mode vs. protected-mode, and\n * notify all the segment registers about the mode change as well -- but only those that are \"bi-modal\"; internal\n * segment registers like segLDT and segTSS do not need to be notified, because they cannot be accessed in real-mode\n * (ie, LLDT, LTR, SLDT, STR are invalid instructions in real-mode, and are among the opcode handlers that we\n * update here).\n *\n * NOTE: Ideally, this function would do its work ONLY on mode *transitions*, but we assume calls to setProtMode()\n * are sufficiently infrequent that it doesn't really matter.\n *\n * @this {CPUX86}\n * @param {boolean} [fProt] (use the current MSW PE bit if not specified)\n * @param {boolean} [fV86] true if the X86.PS.VM (V86-mode) flag is set (or is about to be)\n */\n setProtMode(fProt, fV86)\n {\n if (fProt === undefined) {\n fProt = this.isProtMode();\n }\n if (fV86 === undefined) {\n fV86 = this.isV86Mode();\n }\n if (DEBUG && (fProt != this.isProtMode() || fV86 != this.isV86Mode()) && this.messageEnabled()) {\n this.printMessage(\"CPU switching to \" + (fProt? (fV86? \"v86\" : \"protected\") : \"real\") + \"-mode\", this.bitsMessage, true);\n }\n this.aOpGrp6 = (fProt && !fV86? X86.aOpGrp6Prot : X86.aOpGrp6Real);\n this.segCS.updateMode(false, fProt, fV86);\n this.segDS.updateMode(false, fProt, fV86);\n this.segSS.updateMode(false, fProt, fV86);\n this.segES.updateMode(false, fProt, fV86);\n if (I386 && this.model >= X86.MODEL_80386) {\n this.segFS.updateMode(false, fProt, fV86);\n this.segGS.updateMode(false, fProt, fV86);\n }\n /*\n * This function used to be called only when I386 is true, but it's probably best if we ALWAYS call it, even\n * for 16-bit-only CPUs like the 8086 and 80286; this allows us to write opcode logic by either checking I386\n * and using appropriate hard-coded sizes, or NOT checking I386 and simply using the \"soft-coded\" sizes in\n * sizeData and sizeAddr.\n */\n this.resetSizes();\n }\n\n /**\n * saveProtMode()\n *\n * Save CPU state related to protected-mode, for save()\n *\n * @this {CPUX86}\n * @return {Array}\n */\n saveProtMode()\n {\n if (this.addrGDT != null) {\n var a = [\n this.regCR0,\n this.addrGDT,\n this.addrGDTLimit,\n this.addrIDT,\n this.addrIDTLimit,\n this.segLDT.save(),\n this.segTSS.save(),\n this.nIOPL\n ];\n if (I386 && this.model >= X86.MODEL_80386) {\n a.push(this.regCR1);\n a.push(this.regCR2);\n a.push(this.regCR3);\n a.push(this.regDR);\n a.push(this.regTR);\n }\n return a;\n }\n return null;\n }\n\n /**\n * restoreProtMode()\n *\n * Restore CPU state related to protected-mode, for restore()\n *\n * @this {CPUX86}\n * @param {Array} a\n */\n restoreProtMode(a)\n {\n if (a && a.length) {\n this.regCR0 = a[0];\n this.addrGDT = a[1];\n this.addrGDTLimit = a[2];\n this.addrIDT = a[3];\n this.addrIDTLimit = a[4];\n this.segLDT.restore(a[5]);\n this.segTSS.restore(a[6]);\n this.nIOPL = a[7];\n if (I386 && this.model >= X86.MODEL_80386) {\n this.regCR1 = a[8];\n this.regCR2 = a[9];\n this.regCR3 = a[10];\n this.regDR = a[11];\n this.regTR = a[12];\n }\n this.setProtMode();\n }\n }\n\n /**\n * save(fRunning)\n *\n * This implements save support for the X86 component.\n *\n * NOTE: When the Computer starts issuing powerDown() calls, it always calls the CPU first, and the CPU's\n * powerDown() handler has the added responsibility of:\n *\n * 1) recording whether or not the CPU is currently running\n * 2) stopping the CPU if the powerDown is part of a shutDown\n * 3) passing the original running state to us\n *\n * UPDATES: The current speed multiplier from getSpeed() is now saved in group #3, so that your speed is preserved.\n *\n * @this {CPUX86}\n * @param {boolean} [fRunning]\n * @return {Object|null}\n */\n save(fRunning)\n {\n var state = new State(this);\n state.set(0, [this.regEAX, this.regEBX, this.regECX, this.regEDX, this.getSP(), this.regEBP, this.regESI, this.regEDI]);\n var a = [this.getIP(), this.segCS.save(), this.segDS.save(), this.segSS.save(), this.segES.save(), this.saveProtMode(), this.getPS()];\n if (I386 && this.model >= X86.MODEL_80386) {\n a.push(this.segFS.save());\n a.push(this.segGS.save());\n }\n state.set(1, a);\n state.set(2, [this.segData.sName, this.segStack.sName, this.opFlags, this.opPrefixes, this.intFlags, this.regEA, this.regEAWrite]);\n state.set(3, [0, this.nTotalCycles, this.getSpeed(), fRunning, this.saveTimers()]);\n state.set(4, this.bus.saveMemory(this.isPagingEnabled()));\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the X86 component.\n *\n * @this {CPUX86}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n var a = data[0];\n this.regEAX = a[0];\n this.regEBX = a[1];\n this.regECX = a[2];\n this.regEDX = a[3];\n var regESP = a[4];\n this.regEBP = a[5];\n this.regESI = a[6];\n this.regEDI = a[7];\n\n a = data[1];\n this.segCS.restore(a[1]);\n this.segDS.restore(a[2]);\n this.segSS.restore(a[3]);\n this.segES.restore(a[4]);\n this.restoreProtMode(a[5]);\n this.setPS(a[6]);\n\n /*\n * The introduction of protected-mode requires us to restore memory contents sooner than we used to\n * (ie, before we load any segment registers).\n */\n var fRestored = false;\n\n if (this.bus.restoreMemory(data[4])) {\n /*\n * It's important to call setCSIP(), both to ensure that the CPU's linear IP register (regLIP) is updated\n * properly AND to ensure the CPU's default ADDRESS and OPERAND sizes are set properly.\n */\n this.setCSIP(a[0], this.segCS.sel);\n\n /*\n * It's also important to call setSP(), so that the linear SP register (regLSP) will be updated properly;\n * we also need to call setSS(), to ensure that the lower and upper stack limits are properly initialized.\n */\n this.setSP(regESP);\n this.setSS(this.segSS.sel);\n\n if (I386 && this.model >= X86.MODEL_80386) {\n this.segFS.restore(a[7]);\n this.segGS.restore(a[8]);\n }\n fRestored = true;\n }\n\n a = data[2];\n this.segData = a[0] != null && this.getSeg(a[0]) || this.segDS;\n this.segStack = a[1] != null && this.getSeg(a[1]) || this.segSS;\n this.opFlags = a[2];\n this.opPrefixes = a[3];\n this.intFlags = a[4];\n this.regEA = a[5]; // save/restore of last EA calculation(s) isn't strictly necessary,\n this.regEAWrite = a[6]; // but they may be of some interest to, say, the Debugger\n\n a = data[3];\n this.nTotalCycles = a[1]; // a[0] was previously nBurstDivisor (no longer used)\n this.setSpeed(a[2]); // old states didn't contain a value from getSpeed(), but setSpeed() checks\n if (a[3] != null) { // less old states didn't preserve the original running state, so we must check it\n this.flags.autoStart = a[3];\n }\n if (a[4] != null) {\n this.restoreTimers(a[4]);\n }\n return fRestored;\n }\n\n /**\n * getSeg(sName)\n *\n * @param {string} sName\n * @return {SegX86|Array}\n */\n getSeg(sName)\n {\n switch(sName) {\n case \"CS\":\n return this.segCS;\n case \"DS\":\n return this.segDS;\n case \"SS\":\n return this.segSS;\n case \"ES\":\n return this.segES;\n case \"NULL\":\n return this.segNULL;\n default:\n /*\n * HACK: We return a fake segment register object in which only the base linear address is valid,\n * because that's all the caller provided (ie, we must be restoring from an older state).\n */\n\n return [0, sName, 0, 0, \"\"];\n }\n }\n\n /**\n * getCS()\n *\n * @this {CPUX86}\n * @return {number}\n */\n getCS()\n {\n return this.segCS.sel;\n }\n\n /**\n * setCS(sel)\n *\n * NOTE: This is used ONLY by those few undocumented 8086/8088/80186/80188 instructions that \"MOV\" or \"POP\" a value\n * into CS, which we assume have the same behavior as any other instruction that moves or pops a segment register\n * (ie, suppresses h/w interrupts for one instruction). Instructions that \"JMP\" or \"CALL\" or \"INT\" or \"IRET\" a new\n * value into CS are always accompanied by a new IP value, so they use setCSIP() instead, which does NOT suppress\n * h/w interrupts.\n *\n * @this {CPUX86}\n * @param {number} sel\n * @return {boolean}\n */\n setCS(sel)\n {\n if (this.setCSIP(this.getIP(), sel) != null) {\n if (!BUGS_8086) this.opFlags |= this.OPFLAG_NOINTR_8086;\n return true;\n }\n return false;\n }\n\n /**\n * getDS()\n *\n * @this {CPUX86}\n * @return {number}\n */\n getDS()\n {\n return this.segDS.sel;\n }\n\n /**\n * setDS(sel)\n *\n * @this {CPUX86}\n * @param {number} sel\n */\n setDS(sel)\n {\n if (this.segDS.load(sel) !== X86.ADDR_INVALID) {\n if (!BUGS_8086) this.opFlags |= this.OPFLAG_NOINTR_8086;\n return true;\n }\n return false;\n }\n\n /**\n * getSS()\n *\n * @this {CPUX86}\n * @return {number}\n */\n getSS()\n {\n return this.segSS.sel;\n }\n\n /**\n * setSS(sel)\n *\n * @this {CPUX86}\n * @param {number} sel\n * @param {boolean} [fInterruptable]\n * @return {boolean}\n */\n setSS(sel, fInterruptable)\n {\n var regESP = this.getSP();\n var regLSP = this.segSS.load(sel);\n if (regLSP !== X86.ADDR_INVALID) {\n /*\n * The safest way to update regLSP after a potential change to segSS.base is to call setSP() with the\n * original stack pointer retrieved above via getSP(). When I tried to be clever and do this instead:\n *\n * this.regLSP = (regLSP + regESP)|0;\n *\n * 16-bit stacks began inadvertently using ESP instead of SP. The moral: don't be needlessly clever.\n */\n this.setSP(regESP);\n \n /*\n * The desire to use a linear stack pointer (regLSP) for internal stack operations has some pitfalls;\n * one involves these upper and lower limit calculations. Example: Xenix 386 creates a (non-expand-down)\n * 32-bit data segment for all of DS, ES, and SS, which uses a limit of \"-1\"; ie:\n * \n * SS=0018[ED800000,FFFFFFFF] DS=0018[ED800000,FFFFFFFF] ES=0018[ED800000,FFFFFFFF]\n *\n * so we end up calculating an upper limit of 0xED7FFFFF, which is lower than the lower limit of 0xED800000.\n * \n * For now, these \"limit wrap-around\" situations are resolved by using unsigned values and then applying\n * a linear address ceiling. TODO: Come up with a simple solution for properly dealing with limit wrap-around.\n */\n if (this.segSS.fExpDown) {\n this.regLSPLimit = (this.segSS.base >>> 0) + (this.segSS.maskAddr >>> 0);\n this.regLSPLimitLow = (this.segSS.base >>> 0) + (this.segSS.limit >>> 0);\n } else {\n this.regLSPLimit = (this.segSS.base >>> 0) + (this.segSS.limit >>> 0);\n this.regLSPLimitLow = (this.segSS.base >>> 0);\n }\n \n this.regLSPLimit = Math.min(this.regLSPLimit, this.nMemMask >>> 0);\n this.regLSPLimitLow = Math.min(this.regLSPLimitLow, this.nMemMask >>> 0);\n \n if (!BUGS_8086 && !fInterruptable) this.opFlags |= X86.OPFLAG.NOINTR;\n return true;\n }\n return false;\n }\n\n /**\n * getES()\n *\n * @this {CPUX86}\n * @return {number}\n */\n getES()\n {\n return this.segES.sel;\n }\n\n /**\n * setES(sel)\n *\n * @this {CPUX86}\n * @param {number} sel\n * @return {boolean}\n */\n setES(sel)\n {\n if (this.segES.load(sel) !== X86.ADDR_INVALID) {\n if (!BUGS_8086) this.opFlags |= this.OPFLAG_NOINTR_8086;\n return true;\n }\n return false;\n }\n\n /**\n * getFS()\n *\n * NOTE: segFS is defined for I386 only.\n *\n * @this {CPUX86}\n * @return {number}\n */\n getFS()\n {\n return this.segFS.sel;\n }\n\n /**\n * setFS(sel)\n *\n * NOTE: segFS is defined for I386 only.\n *\n * @this {CPUX86}\n * @param {number} sel\n * @return {boolean}\n */\n setFS(sel)\n {\n return this.segFS.load(sel) !== X86.ADDR_INVALID;\n }\n\n /**\n * getGS()\n *\n * NOTE: segGS is defined for I386 only.\n *\n * @this {CPUX86}\n * @return {number}\n */\n getGS()\n {\n return this.segGS.sel;\n }\n\n /**\n * setGS(sel)\n *\n * NOTE: segGS is defined for I386 only.\n *\n * @this {CPUX86}\n * @param {number} sel\n * @return {boolean}\n */\n setGS(sel)\n {\n return this.segGS.load(sel) !== X86.ADDR_INVALID;\n }\n\n /**\n * getIP()\n *\n * @this {CPUX86}\n * @return {number}\n */\n getIP()\n {\n return (this.regLIP - this.segCS.base)|0;\n }\n\n /**\n * setIP(off)\n *\n * @this {CPUX86}\n * @param {number} off\n */\n setIP(off)\n {\n this.regLIP = (this.segCS.base + (off & (I386? this.maskData : 0xffff)))|0;\n if (PREFETCH) this.refillPrefetch();\n }\n\n /**\n * setLIP(addr)\n *\n * @this {CPUX86}\n * @param {number} addr\n */\n setLIP(addr)\n {\n this.regLIP = addr;\n this.regLIPMax = (this.segCS.base >>> 0) + (this.segCS.limit >>> 0) + 1;\n\n /*\n * TODO: Verify the proper source for CPL. Should it come from segCS.cpl or segCS.dpl?\n * Also, note that LOADALL386 wants it to come from segSS.dpl.\n */\n this.nCPL = this.segCS.cpl; // cache the current CPL where it's more convenient\n\n if (I386) this.resetSizes();\n /*\n * Here, we need to additionally test whether the prefetch buffer (adwPrefetch) has been allocated yet,\n * because when resetRegs() is first called, the Bus hasn't been initialized yet, so there's nothing to fetch.\n *\n * We'll allocate the prefetch buffer when the Bus calls initMemory().\n */\n if (PREFETCH && this.adwPrefetch) this.refillPrefetch();\n }\n\n /**\n * setCSIP(off, sel, fCall)\n *\n * This function is a little different from the other segment setters, only because it turns out that CS is\n * never set without an accompanying IP (well, except for a few undocumented instructions, like POP CS, which\n * were available ONLY on the 8086/8088/80186/80188; see setCS() for details).\n *\n * And even though this function is called setCSIP(), please note the order of the parameters is [IP,CS],\n * which matches the order that CS:IP values are normally stored in memory, allowing us to make calls like this:\n *\n * this.setCSIP(this.popWord(), this.popWord());\n *\n * @this {CPUX86}\n * @param {number} off\n * @param {number} sel\n * @param {boolean} [fCall] is true if CALLF in progress, false if RETF/IRET in progress, undefined otherwise\n * @return {boolean|null} true if a stack switch occurred; the only operation that needs to pay attention is opRETFn()\n */\n setCSIP(off, sel, fCall)\n {\n /*\n * Setting IP needs to occur AFTER loadCode(), because it may differ from the given IP if sel refers to a gate.\n */\n var base = this.segCS.loadCode(off, sel, fCall);\n if (base !== X86.ADDR_INVALID) {\n this.setLIP(base + (this.segCS.offIP & (I386? this.segCS.maskData : 0xffff)));\n return this.segCS.fStackSwitch;\n }\n return null;\n }\n\n /**\n * setCSBase(addr)\n *\n * Since the CPU must maintain regLIP as the sum of the CS base and the current IP, all calls to setBase()\n * for segCS need to go through here.\n *\n * @param {number} addr\n */\n setCSBase(addr)\n {\n var regIP = this.getIP();\n addr = this.segCS.setBase(addr);\n this.regLIP = (addr + regIP)|0;\n this.regLIPMax = (addr >>> 0) + (this.segCS.limit >>> 0) + 1;\n }\n\n /**\n * checkIP(inc)\n *\n * TODO: If we didn't care about compatibility, we could just return:\n *\n * (this.regLIP + inc)|0\n *\n * and be done with it, because there probably isn't any \"good\" code that triggers the\n * \"newLIP > this.regLIPMax\" condition. This check costs us about 2Mhz performance on an 80386.\n *\n * Turning PREFETCH on tends to offset this performance hit, but PREFETCH *without* this hit would\n * probably perform even better.\n *\n * @this {CPUX86}\n * @param {number} inc (positive)\n * @return {number} new LIP\n */\n checkIP(inc)\n {\n var newLIP = (this.regLIP >>> 0) + inc;\n if (newLIP > this.regLIPMax) {\n /*\n * There's no such thing as a GP fault on the 8086/8088, and I'm now assuming that,\n * on newer processors, all attempts to fetch opcodes beyond the limit trigger a fault.\n */\n if (this.model <= X86.MODEL_8088 /* || this.segCS.limit == this.segCS.maskAddr */) {\n newLIP = this.segCS.base + ((newLIP - this.regLIPMax) & (I386? this.maskData : 0xffff));\n if (inc == 2) this.opFlags |= X86.OPFLAG.WRAP;\n } else {\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n }\n }\n return newLIP|0;\n }\n\n /**\n * resetIP(dec)\n *\n * This \"rewinds\" IP to the beginning of the current instruction (eg, an instruction with a REP prefix)\n *\n * @this {CPUX86}\n * @param {number} dec (negative)\n */\n resetIP(dec)\n {\n if (BUGS_8086) {\n this.regLIP = (this.regLIP + dec)|0;\n /*\n * This assertion is intended to fail if/when we encounter a \"buggy\" instruction (see BUGS_8086)\n */\n\n } else {\n if (PREFETCH) {\n this.cbPrefetch += this.regLIP - this.opLIP;\n this.regLIP = this.opLIP;\n /*\n * If \"rewinding\" produces a prefetch total greater than the allocated amount, then we must have\n * refilled the queue somewhere in the middle of the rewound instruction, so we need to refill the\n * queue all over again; otherwise, the next repetition may fetch future data instead of past data.\n *\n * That's the bad news; the good news is that this extra refill should only hurt performance of the\n * first repetition.\n */\n if (this.cbPrefetch > CPUX86.PFINFO.LENGTH) this.refillPrefetch();\n } else {\n this.regLIP = this.opLIP;\n }\n }\n }\n\n /**\n * getSP()\n *\n * @this {CPUX86}\n * @return {number}\n */\n getSP()\n {\n if (I386) {\n // assert(!((this.regLSP - this.segSS.base) & ~this.segSS.maskAddr));\n return (this.regESP & ~this.segSS.maskAddr) | (this.regLSP - this.segSS.base);\n }\n return (this.regLSP - this.segSS.base)|0;\n }\n\n /**\n * setSP(off)\n *\n * @this {CPUX86}\n * @param {number} off\n */\n setSP(off)\n {\n if (I386) {\n this.regESP = off;\n this.regLSP = (this.segSS.base + (off & this.segSS.maskAddr))|0;\n } else {\n this.regLSP = (this.segSS.base + off)|0;\n }\n }\n\n /**\n * setArithResult(dst, src, value, type, fSubtract)\n *\n * Updates the flags for arithmetic instructions; use setLogicResult() for logical instructions.\n *\n * The type parameter indicates both the size of the result (BYTE, WORD or DWORD) and which of the\n * flags should now be considered \"cached\" by the new result variables. If the previous resultType\n * specifies any flags not contained in the new type parameter, then those flags must be immediately\n * calculated and written to the appropriate bit(s) in regPS.\n *\n * The default assumes an \"addition\" (eg, ADD, ADC, INC), where value = dst + src. The fSubtract\n * parameter is used to indicate a \"subtraction\" (eg, CMP, DEC, SUB, SBB), where value = dst - src;\n * We can transform a subtraction into an addition, since it's also true that dst = value + src,\n * by swapping swap dst and value -- which is exactly what we do below. This allows all downstream\n * flag calculations (eg, getCF(), getOF()) to remain the same.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @param {number} value\n * @param {number} type\n * @param {boolean} [fSubtract]\n */\n setArithResult(dst, src, value, type, fSubtract)\n {\n if ((type & X86.RESULT.ALL) != X86.RESULT.ALL && type != this.resultType) {\n var diff = ((type ^ this.resultType) & this.resultType);\n if (diff) {\n if (diff & X86.RESULT.CF) this.getCF();\n if (diff & X86.RESULT.PF) this.getPF();\n if (diff & X86.RESULT.AF) this.getAF();\n if (diff & X86.RESULT.ZF) this.getZF();\n if (diff & X86.RESULT.SF) this.getSF();\n if (diff & X86.RESULT.OF) this.getOF();\n }\n }\n if (!fSubtract) {\n this.resultDst = dst;\n this.resultArith = value;\n } else {\n this.resultDst = value;\n this.resultArith = dst;\n }\n this.resultSrc = src;\n this.resultLogic = value;\n this.resultType = type;\n }\n\n /**\n * setLogicResult(value, type, carry, overflow)\n *\n * Updates the flags for logical instructions (eg, AND, OR, TEST, XOR); ie, instructions\n * that update PF, ZF, and SF, while clearing CF and OF (although CF and OF can be explicitly\n * set via the carry and overflow parameters as needed). AF is always considered undefined.\n *\n * TODO: We should observe the behavior of AF on real CPUs, and determine if there is a\n * well-defined behavior, even though none is documented. Ditto for OF on shift instructions\n * when the shift count > 1.\n *\n * @this {CPUX86}\n * @param {number} value\n * @param {number} type\n * @param {number} [carry]\n * @param {number} [overflow]\n * @return {number} value\n */\n setLogicResult(value, type, carry, overflow)\n {\n this.resultType = type | X86.RESULT.LOGIC;\n this.resultLogic = value;\n if (carry) this.setCF(); else this.clearCF();\n if (overflow) this.setOF(); else this.clearOF();\n return value;\n }\n\n /**\n * setRotateResult(result, carry, size)\n *\n * Used by all rotate instructions (ie, RCL, RCR, ROL, ROR) to update CF and OF.\n *\n * TODO: We should observe the behavior of OF on real CPUs whenever the rotate count > 1,\n * and determine if there is a well-defined behavior, even though none is documented.\n *\n * @this {CPUX86}\n * @param {number} result\n * @param {number} carry\n * @param {number} size\n */\n setRotateResult(result, carry, size)\n {\n if (carry & size) this.setCF(); else this.clearCF();\n if ((result ^ carry) & size) this.setOF(); else this.clearOF();\n }\n\n /**\n * getCarry()\n *\n * @this {CPUX86}\n * @return {number} 0 or 1, depending on whether CF is clear or set\n */\n getCarry()\n {\n return this.getCF()? 1 : 0;\n }\n\n /**\n * getCF()\n *\n * The following table summarizes bit 31 of the dst (D) and src (S) operands, bit 31 of the\n * addition (A), along with the expected carry bit (C):\n *\n * D S A C\n * - - - -\n * 0 0 0 0 no\n * 0 0 1 0 no (there must have been a carry out of bit 30, but it was \"absorbed\")\n * 0 1 0 1 yes (there must have been a carry out of bit 30, but it was NOT \"absorbed\")\n * 0 1 1 0 no\n * 1 0 0 1 yes (same as the preceding \"yes\" case)\n * 1 0 1 0 no\n * 1 1 0 1 yes (since the addition of two ones must always produce a carry)\n * 1 1 1 1 yes (since the addition of two ones must always produce a carry)\n *\n * So, we use the following calculation:\n *\n * (resultDst ^ ((resultDst ^ resultSrc) & (resultSrc ^ resultArith))) & resultType\n *\n * NOTE: The above table assumes that the resultDst (D) and resultSrc (S) operands were ADDED to\n * produce resultArith (A); if they were SUBTRACTED instead (D - S), then D and A must be swapped\n * after the subtraction, so that the above truth table still applies; see setArithResult().\n *\n * @this {CPUX86}\n * @return {number} 0 or X86.PS.CF\n */\n getCF()\n {\n if (this.resultType & X86.RESULT.CF) {\n this.regPS &= ~X86.PS.CF;\n if ((this.resultDst ^ ((this.resultDst ^ this.resultSrc) & (this.resultSrc ^ this.resultArith))) & (this.resultType & X86.RESULT.TYPE)) {\n this.regPS |= X86.PS.CF;\n }\n this.resultType &= ~X86.RESULT.CF;\n }\n return this.regPS & X86.PS.CF;\n }\n\n /**\n * getPF()\n *\n * From http://graphics.stanford.edu/~seander/bithacks.html#ParityParallel:\n *\n * unsigned int v; // word value to compute the parity of\n * v ^= v >> 16;\n * v ^= v >> 8;\n * v ^= v >> 4;\n * v &= 0xf;\n * return (0x6996 >> v) & 1;\n *\n * The method above takes around 9 operations, and works for 32-bit words. It may be optimized to work just on\n * bytes in 5 operations by removing the two lines immediately following \"unsigned int v;\". The method first shifts\n * and XORs the eight nibbles of the 32-bit value together, leaving the result in the lowest nibble of v. Next,\n * the binary number 0110 1001 1001 0110 (0x6996 in hex) is shifted to the right by the value represented in the\n * lowest nibble of v. This number is like a miniature 16-bit parity-table indexed by the low four bits in v.\n * The result has the parity of v in bit 1, which is masked and returned.\n *\n * The x86 parity flag (PF) is based exclusively on the low 8 bits of resultParitySign, so our calculation is bit\n * simpler. Note that PF must be SET if that byte has EVEN parity, and CLEAR if it has ODD parity.\n *\n * @this {CPUX86}\n * @return {number} 0 or X86.PS.PF\n */\n getPF()\n {\n if (this.resultType & X86.RESULT.PF) {\n this.regPS &= ~X86.PS.PF;\n if ((0x9669 >> ((this.resultLogic ^ (this.resultLogic >> 4)) & 0xf)) & 1) {\n this.regPS |= X86.PS.PF;\n }\n this.resultType &= ~X86.RESULT.PF;\n }\n return this.regPS & X86.PS.PF;\n }\n\n /**\n * getAF()\n *\n * To determine if there's been a carry out of the low 4 bits of an arithmetic operation,\n * we look at all the possible inputs for bit 4, and calculate AF = A^(D^S).\n *\n * D S A D^S AF\n * - - - --- --\n * 0 0 0 0 0\n * 0 0 1 0 1\n * 0 1 0 1 1\n * 0 1 1 1 0\n * 1 0 0 1 1\n * 1 0 1 1 0\n * 1 1 0 0 0\n * 1 1 1 0 1\n *\n * The final calculation looks like:\n *\n * (resultArith ^ (resultDst ^ resultSrc)) & 0x0010\n *\n * @this {CPUX86}\n * @return {number} 0 or X86.PS.AF\n */\n getAF()\n {\n if (this.resultType & X86.RESULT.AF) {\n this.regPS &= ~X86.PS.AF;\n if ((this.resultArith ^ (this.resultDst ^ this.resultSrc)) & 0x0010) {\n this.regPS |= X86.PS.AF;\n }\n this.resultType &= ~X86.RESULT.AF;\n }\n return this.regPS & X86.PS.AF;\n }\n\n /**\n * getZF()\n *\n * @this {CPUX86}\n * @return {number} 0 or X86.PS.ZF\n */\n getZF()\n {\n if (this.resultType & X86.RESULT.ZF) {\n this.regPS &= ~X86.PS.ZF;\n if (!(this.resultLogic & (((this.resultType & X86.RESULT.TYPE) - 1) | (this.resultType & X86.RESULT.TYPE)))) {\n this.regPS |= X86.PS.ZF;\n }\n this.resultType &= ~X86.RESULT.ZF;\n }\n return this.regPS & X86.PS.ZF;\n }\n\n /**\n * getSF()\n *\n * @this {CPUX86}\n * @return {number} 0 or X86.PS.SF\n */\n getSF()\n {\n if (this.resultType & X86.RESULT.SF) {\n this.regPS &= ~X86.PS.SF;\n if (this.resultLogic & (this.resultType & X86.RESULT.TYPE)) {\n this.regPS |= X86.PS.SF;\n }\n this.resultType &= ~X86.RESULT.SF;\n }\n return this.regPS & X86.PS.SF;\n }\n\n /**\n * getOF()\n *\n * Overflow was originally calculated as:\n *\n * (resultParitySign ^ resultAuxOverflow ^ (resultParitySign >> 1)) & (resultSize >> 1)\n *\n * but as you can see, that calculation depends on the carry out of the 8/16/32-bit result in\n * resultParitySign, which we don't have access to for 32-bit results. So we fall-back to the\n * following:\n *\n * ((resultDst ^ resultArith) & (resultSrc ^ resultArith)) & resultType\n *\n * which you can verify from the following table of sign bits, where x1 is resultDst ^ resultArith,\n * and x2 is resultSrc ^ resultArith:\n *\n * D S A x1 x2 OF\n * - - - -- -- --\n * 0 0 0 0 0 0\n * 0 0 1 1 1 1 (adding two positive values yielded a negative value)\n * 0 1 0 0 1 0\n * 0 1 1 1 0 0\n * 1 0 0 1 0 0\n * 1 0 1 0 1 0\n * 1 1 0 1 1 1 (adding two negative values yielded a positive value)\n * 1 1 1 0 0 0\n *\n * NOTE: The above table assumes that the resultDst (D) and resultSrc (S) operands were ADDED to\n * produce resultArith (A); if they were SUBTRACTED instead (D - S), then D and A must be swapped\n * after the subtraction, so that the above truth table still applies; see setArithResult().\n *\n * @this {CPUX86}\n * @return {number} 0 or X86.PS.OF\n */\n getOF()\n {\n if (this.resultType & X86.RESULT.OF) {\n this.regPS &= ~X86.PS.OF;\n if (((this.resultDst ^ this.resultArith) & (this.resultSrc ^ this.resultArith)) & (this.resultType & X86.RESULT.TYPE)) {\n this.regPS |= X86.PS.OF;\n }\n this.resultType &= ~X86.RESULT.OF;\n }\n return this.regPS & X86.PS.OF;\n }\n\n /**\n * getTF()\n *\n * @this {CPUX86}\n * @return {number} 0 or X86.PS.TF\n */\n getTF()\n {\n return (this.regPS & X86.PS.TF);\n }\n\n /**\n * getIF()\n *\n * @this {CPUX86}\n * @return {number} 0 or X86.PS.IF\n */\n getIF()\n {\n return (this.regPS & X86.PS.IF);\n }\n\n /**\n * getDF()\n *\n * @this {CPUX86}\n * @return {number} 0 or X86.PS.DF\n */\n getDF()\n {\n return (this.regPS & X86.PS.DF);\n }\n\n /**\n * clearCF()\n *\n * @this {CPUX86}\n */\n clearCF()\n {\n this.resultType &= ~X86.RESULT.CF;\n this.regPS &= ~X86.PS.CF;\n }\n\n /**\n * clearPF()\n *\n * @this {CPUX86}\n */\n clearPF()\n {\n this.resultType &= ~X86.RESULT.PF;\n this.regPS &= ~X86.PS.PF;\n }\n\n /**\n * clearAF()\n *\n * @this {CPUX86}\n */\n clearAF()\n {\n this.resultType &= ~X86.RESULT.AF;\n this.regPS &= ~X86.PS.AF;\n }\n\n /**\n * clearZF()\n *\n * @this {CPUX86}\n */\n clearZF()\n {\n this.resultType &= ~X86.RESULT.ZF;\n this.regPS &= ~X86.PS.ZF;\n }\n\n /**\n * clearSF()\n *\n * @this {CPUX86}\n */\n clearSF()\n {\n this.resultType &= ~X86.RESULT.SF;\n this.regPS &= ~X86.PS.SF;\n }\n\n /**\n * clearIF()\n *\n * @this {CPUX86}\n */\n clearIF()\n {\n this.regPS &= ~X86.PS.IF;\n }\n\n /**\n * clearDF()\n *\n * @this {CPUX86}\n */\n clearDF()\n {\n this.regPS &= ~X86.PS.DF;\n }\n\n /**\n * clearOF()\n *\n * @this {CPUX86}\n */\n clearOF()\n {\n this.resultType &= ~X86.RESULT.OF;\n this.regPS &= ~X86.PS.OF;\n }\n\n /**\n * setCF()\n *\n * @this {CPUX86}\n */\n setCF()\n {\n this.resultType &= ~X86.RESULT.CF;\n this.regPS |= X86.PS.CF;\n }\n\n /**\n * setPF()\n *\n * @this {CPUX86}\n */\n setPF()\n {\n this.resultType &= ~X86.RESULT.PF;\n this.regPS |= X86.PS.PF;\n }\n\n /**\n * setAF()\n *\n * @this {CPUX86}\n */\n setAF()\n {\n this.resultType &= ~X86.RESULT.AF;\n this.regPS |= X86.PS.AF;\n }\n\n /**\n * setZF()\n *\n * @this {CPUX86}\n */\n setZF()\n {\n this.resultType &= ~X86.RESULT.ZF;\n this.regPS |= X86.PS.ZF;\n }\n\n /**\n * setSF()\n *\n * @this {CPUX86}\n */\n setSF()\n {\n this.resultType &= ~X86.RESULT.SF;\n this.regPS |= X86.PS.SF;\n }\n\n /**\n * setIF()\n *\n * @this {CPUX86}\n */\n setIF()\n {\n this.regPS |= X86.PS.IF;\n }\n\n /**\n * setDF()\n *\n * @this {CPUX86}\n */\n setDF()\n {\n this.regPS |= X86.PS.DF;\n }\n\n /**\n * setOF()\n *\n * @this {CPUX86}\n */\n setOF()\n {\n this.resultType &= ~X86.RESULT.OF;\n this.regPS |= X86.PS.OF;\n }\n\n /**\n * getPS()\n *\n * @this {CPUX86}\n * @return {number}\n */\n getPS()\n {\n return (this.regPS & ~X86.PS_CACHED) | (this.getCF() | this.getPF() | this.getAF() | this.getZF() | this.getSF() | this.getOF());\n }\n\n /**\n * setMSW(w)\n *\n * Factored out of x86op0f.js, since both opLMSW and opLOADALL are capable of setting a new MSW.\n * The caller is responsible for assessing the appropriate cycle cost.\n *\n * @this {CPUX86}\n * @param {number} w\n */\n setMSW(w)\n {\n /*\n * This instruction is always allowed to set MSW.PE, but it cannot clear MSW.PE once set;\n * therefore, we always OR the previous value of MSW.PE into the new value before loading.\n */\n w |= (this.regCR0 & X86.CR0.MSW.PE) | X86.CR0.MSW.ON;\n this.regCR0 = (this.regCR0 & ~X86.CR0.MSW.MASK) | (w & X86.CR0.MSW.MASK);\n /*\n * Since the 80286 cannot return to real-mode via this instruction, the only transition we\n * must worry about is to protected-mode. And there's no harm calling setProtMode() if the\n * CPU is already in protected-mode; we could certainly optimize out the call in that case,\n * but the instruction isn't used frequently enough to warrant it.\n */\n if (this.regCR0 & X86.CR0.MSW.PE) this.setProtMode(true);\n }\n\n /**\n * setPS(regPS)\n *\n * @this {CPUX86}\n * @param {number} regPS\n * @param {number} [cpl]\n */\n setPS(regPS, cpl)\n {\n /*\n * OS/2 1.0 discriminates between an 80286 and an 80386 based on whether an IRET in real-mode that\n * pops 0xF000 into the flags is able to set *any* of flag bits 12-15: if it can, then OS/2 declares\n * the CPU an 80386.\n *\n * So, if the CPU is an 80286, we clear incoming bits 12-14 in real-mode (bit 15 is never allowed to\n * be modified, so there's no need to mask it). And if the CPU is an 80386, no bits are automatically\n * cleared in real-mode (PS_CLEAR_RM is zero); although that allows the IOPL bits to change, it doesn't\n * affect real-mode operation, since CPL is always zero, making IOPL irrelevant.\n */\n if (!(this.regCR0 & X86.CR0.MSW.PE)) regPS &= ~this.PS_CLEAR_RM;\n\n /*\n * There are some cases (eg, an IRET returning to a less privileged code segment) where the CPL\n * we compare against should come from the outgoing code segment, so if the caller provided it, use it.\n */\n if (cpl === undefined) cpl = this.nCPL;\n\n /*\n * Since PS.IOPL and PS.IF are part of PS_DIRECT, we need to take care of any 80286-specific behaviors\n * before setting the PS_DIRECT bits from the incoming regPS bits.\n *\n * Specifically, PS.IOPL is unchanged if CPL > 0, and PS.IF is unchanged if CPL > IOPL.\n */\n if (!cpl) {\n this.nIOPL = (regPS & X86.PS.IOPL.MASK) >> X86.PS.IOPL.SHIFT; // IOPL allowed to change\n } else {\n regPS = (regPS & ~X86.PS.IOPL.MASK) | (this.regPS & X86.PS.IOPL.MASK); // IOPL not allowed to change\n }\n\n if (cpl > this.nIOPL) {\n regPS = (regPS & ~X86.PS.IF) | (this.regPS & X86.PS.IF); // IF not allowed to change\n }\n\n this.resultType = X86.RESULT.BYTE;\n this.regPS = (this.regPS & ~(this.PS_DIRECT|X86.PS_CACHED)) | (regPS & (this.PS_DIRECT|X86.PS_CACHED)) | this.PS_SET;\n\n if (this.regPS & X86.PS.TF) {\n this.intFlags |= X86.INTFLAG.TRAP;\n this.opFlags |= X86.OPFLAG.NOINTR;\n }\n }\n\n /**\n * checkIOPM(port, nPorts, fInput)\n *\n * @this {CPUX86}\n * @param {number} port (0x0000 to 0xffff)\n * @param {number} nPorts (1 to 4)\n * @param {boolean} [fInput] (true if input, false if output; output assumed if not specified)\n * @return {boolean} true if allowed, false if not\n */\n checkIOPM(port, nPorts, fInput)\n {\n var bitsPorts = 0;\n if (I386 && (this.regCR0 & X86.CR0.MSW.PE) && (this.nCPL > this.nIOPL || (this.regPS & X86.PS.VM)) && this.segTSS.addrIOPM) {\n var offIOPM = port >>> 3;\n var addrIOPM = this.segTSS.addrIOPM + offIOPM;\n bitsPorts = ((1 << nPorts) - 1) << (port & 0x7);\n while (bitsPorts && addrIOPM <= this.segTSS.addrIOPMLimit) {\n var bits = this.getByte(addrIOPM);\n if (bits & bitsPorts) break;\n bitsPorts >>>= 8;\n addrIOPM++;\n }\n }\n if (bitsPorts) {\n if (this.messageEnabled(Messages.IOPM)) this.printMessage(\"checkIOPM(\" + Str.toHexWord(port) + \",\" + nPorts + \",\" + (fInput? \"input\" : \"output\") + \"): trapped\", true, true);\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return false;\n }\n return true;\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {CPUX86}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"AX\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var fBound = false;\n switch (sBinding) {\n case \"EAX\":\n case \"EBX\":\n case \"ECX\":\n case \"EDX\":\n case \"ESP\":\n case \"EBP\":\n case \"ESI\":\n case \"EDI\":\n case \"EIP\":\n case \"AX\":\n case \"BX\":\n case \"CX\":\n case \"DX\":\n case \"SP\":\n case \"BP\":\n case \"SI\":\n case \"DI\":\n case \"IP\":\n case \"PC\": // deprecated as an alias for \"IP\" (still used by older XML files, like the one at http://tpoindex.github.io/crobots/)\n case \"CS\":\n case \"DS\":\n case \"SS\":\n case \"ES\":\n case \"FS\":\n case \"GS\":\n case \"CR0\":\n case \"CR2\":\n case \"CR3\":\n case \"PS\": // this refers to \"Processor Status\", aka the 16-bit flags register (although DEBUG.COM refers to this as \"PC\", surprisingly)\n case \"C\":\n case \"P\":\n case \"A\":\n case \"Z\":\n case \"S\":\n case \"T\":\n case \"I\":\n case \"D\":\n case \"V\":\n this.bindings[sBinding] = control;\n this.cLiveRegs++;\n fBound = true;\n break;\n default:\n fBound = super.setBinding(sHTMLType, sBinding, control);\n break;\n }\n return fBound;\n }\n\n /**\n * probeAddr(addr, size, fPhysical)\n *\n * Used by the Debugger to probe addresses without risk of triggering a page fault, and by internal\n * functions, like helpCheckFault(), that must also avoid triggering faults, since they're not part of\n * standard CPU operation.\n *\n * Since originally written, I've also relaxed the requirement that the request be contained entirely\n * within a single block; this was never a problem for any size-aligned request, but unfortunately, it\n * was difficult for the Debugger to guarantee that every 2 or 4-byte request would be always be word or\n * dword-aligned. So now requests that straddle blocks will be broken into smaller probeAddr() requests.\n *\n * @this {CPUX86}\n * @param {number} addr is a linear address\n * @param {number} [size] is a length (default is 1; if specified, must be 1, 2 or 4)\n * @param {boolean} [fPhysical] (true for physical probe, false for linear; linear is the default)\n * @return {number|null} value at the specified address, or null if invalid\n */\n probeAddr(addr, size, fPhysical)\n {\n var aBlocks = (fPhysical? this.aBusBlocks : this.aMemBlocks);\n var block = aBlocks[(addr & this.nMemMask) >>> this.nBlockShift];\n if (block && block.type == Memory.TYPE.UNPAGED) block = this.mapPageBlock(addr, false, true);\n\n if (block) {\n var off = addr & this.nBlockLimit;\n if (!size || size == 1) {\n return block.readByteDirect(off, addr);\n }\n if (size == 2) {\n if (off < this.nBlockLimit) {\n return block.readShortDirect(off, addr);\n }\n return block.readByteDirect(off, addr) | (this.probeAddr(addr + 1, 1, fPhysical) << 8);\n }\n if (size == 4) {\n if (off < this.nBlockLimit - 2) {\n return block.readLongDirect(off, addr);\n }\n if (off == this.nBlockLimit - 1) {\n return block.readShortDirect(off, addr) | (this.probeAddr(addr + 2, 2, fPhysical) << 16);\n }\n return block.readByteDirect(off, addr) | (this.probeAddr(addr + 1, 1, fPhysical) << 8) | (this.probeAddr(addr + 2, 1, fPhysical) << 16) | (this.probeAddr(addr + 3, 1, fPhysical) << 24);\n }\n }\n\n /*\n * Since the Bus component initializes all unused portions of physical address space with an empty\n * block, we have also written mapPageBlock() to return an empty block (memEmpty) whenever there is\n * no valid mapping. So if we ever end up here, this may represent a hole that needs plugging.\n *\n * It's also possible the caller passed a bogus parameter, such as an invalid size (must be 1, 2 or 4).\n */\n\n return null;\n }\n\n /**\n * getByte(addr)\n *\n * Use bus.getByte() for physical addresses, and cpu.getByte() for linear addresses; the latter takes care\n * of paging, cycle counts, and BACKTRACK states, if any.\n *\n * @this {CPUX86}\n * @param {number} addr is a linear address\n * @return {number} byte (8-bit) value at that address\n */\n getByte(addr)\n {\n if (BACKTRACK) this.backTrack.btiMem0 = this.bus.readBackTrack(addr);\n return this.aMemBlocks[(addr & this.nMemMask) >>> this.nBlockShift].readByte(addr & this.nBlockLimit, addr);\n }\n\n /**\n * getShort(addr)\n *\n * Use bus.getShort() for physical addresses, and cpu.getShort() for linear addresses; the latter takes care\n * of paging, cycle counts, and BACKTRACK states, if any.\n *\n * @this {CPUX86}\n * @param {number} addr is a linear address\n * @return {number} word (16-bit) value at that address\n */\n getShort(addr)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nMemMask) >>> this.nBlockShift;\n /*\n * On the 8088, it takes 4 cycles to read the additional byte REGARDLESS whether the address is odd or even.\n * TODO: For the 8086, the penalty is actually \"(addr & 0x1) << 2\" (4 additional cycles only when the address is odd).\n */\n this.nStepCycles -= this.cycleCounts.nWordCyclePenalty;\n\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.bus.readBackTrack(addr);\n this.backTrack.btiMem1 = this.bus.readBackTrack(addr + 1);\n }\n if (off < this.nBlockLimit) {\n return this.aMemBlocks[iBlock].readShort(off, addr);\n }\n var w = this.aMemBlocks[iBlock].readByte(off, addr);\n if (!(this.opFlags & X86.OPFLAG.FAULT)) {\n w |= this.aMemBlocks[(iBlock + 1) & this.nBlockMask].readByte(0, addr + 1) << 8;\n }\n return w;\n }\n\n /**\n * getLong(addr)\n *\n * Use bus.getLong() for physical addresses, and cpu.getLong() for linear addresses; the latter takes care\n * of paging, cycle counts, and BACKTRACK states, if any.\n *\n * @this {CPUX86}\n * @param {number} addr is a linear address\n * @return {number} long (32-bit) value at that address\n */\n getLong(addr)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nMemMask) >>> this.nBlockShift;\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.bus.readBackTrack(addr);\n this.backTrack.btiMem1 = this.bus.readBackTrack(addr + 1);\n this.backTrack.btiMem2 = this.bus.readBackTrack(addr + 2);\n this.backTrack.btiMem3 = this.bus.readBackTrack(addr + 3);\n }\n if (off < this.nBlockLimit - 2) {\n return this.aMemBlocks[iBlock].readLong(off, addr);\n }\n /*\n * I think the previous version of this function tried to be too clever (ie, reading the last\n * long in the current block and the first long in the next block and masking/combining the results),\n * which may have also created some undesirable side-effects for custom memory controllers.\n * This simpler (and probably more reliable) approach is to simply read the long as individual bytes.\n */\n var l = 0;\n var cb = 4, nShift = 0;\n var cbBlock = 4 - (off & 0x3); // (off & 0x3) will be 1, 2 or 3, so cbBlock will be 3, 2, or 1\n while (cb--) {\n l |= (this.aMemBlocks[iBlock].readByte(off++, addr++) << nShift);\n if (this.opFlags & X86.OPFLAG.FAULT) break;\n if (!--cbBlock) {\n iBlock = (iBlock + 1) & this.nBlockMask;\n off = 0;\n }\n nShift += 8;\n }\n return l;\n }\n\n /**\n * setByte(addr, b)\n *\n * Use bus.setByte() for physical addresses, and cpu.setByte() for linear addresses; the latter takes care\n * of paging, cycle counts, and BACKTRACK states, if any.\n *\n * @this {CPUX86}\n * @param {number} addr is a linear address\n * @param {number} b is the byte (8-bit) value to write (which we truncate to 8 bits; required by opSTOSb)\n */\n setByte(addr, b)\n {\n if (BACKTRACK) this.bus.writeBackTrack(addr, this.backTrack.btiMem0);\n this.aMemBlocks[(addr & this.nMemMask) >>> this.nBlockShift].writeByte(addr & this.nBlockLimit, b & 0xff, addr);\n }\n\n /**\n * setShort(addr, w)\n *\n * Use bus.setShort() for physical addresses, and cpu.setShort() for linear addresses; the latter takes care\n * of paging, cycle counts, and BACKTRACK states, if any.\n *\n * @this {CPUX86}\n * @param {number} addr is a linear address\n * @param {number} w is the word (16-bit) value to write (which we truncate to 16 bits to be safe)\n */\n setShort(addr, w)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nMemMask) >>> this.nBlockShift;\n /*\n * On the 8088, it takes 4 cycles to write the additional byte REGARDLESS whether the address is odd or even.\n * TODO: For the 8086, the penalty is actually \"(addr & 0x1) << 2\" (4 additional cycles only when the address is odd).\n */\n this.nStepCycles -= this.cycleCounts.nWordCyclePenalty;\n\n if (BACKTRACK) {\n this.bus.writeBackTrack(addr, this.backTrack.btiMem0);\n this.bus.writeBackTrack(addr + 1, this.backTrack.btiMem1);\n }\n if (off < this.nBlockLimit) {\n this.aMemBlocks[iBlock].writeShort(off, w & 0xffff, addr);\n return;\n }\n this.aMemBlocks[iBlock++].writeByte(off, w & 0xff, addr);\n if (this.opFlags & X86.OPFLAG.FAULT) return;\n this.aMemBlocks[iBlock & this.nBlockMask].writeByte(0, (w >> 8) & 0xff, addr + 1);\n }\n\n /**\n * setLong(addr, l)\n *\n * Use bus.setLong() for physical addresses, and cpu.setLong() for linear addresses; the latter takes care\n * of paging, cycle counts, and BACKTRACK states, if any.\n *\n * @this {CPUX86}\n * @param {number} addr is a linear address\n * @param {number} l is the long (32-bit) value to write\n */\n setLong(addr, l)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nMemMask) >>> this.nBlockShift;\n this.nStepCycles -= this.cycleCounts.nWordCyclePenalty;\n\n if (BACKTRACK) {\n this.bus.writeBackTrack(addr, this.backTrack.btiMem0);\n this.bus.writeBackTrack(addr + 1, this.backTrack.btiMem1);\n this.bus.writeBackTrack(addr + 2, this.backTrack.btiMem2);\n this.bus.writeBackTrack(addr + 3, this.backTrack.btiMem3);\n }\n if (off < this.nBlockLimit - 2) {\n this.aMemBlocks[iBlock].writeLong(off, l, addr);\n return;\n }\n /*\n * I think the previous version of this function tried to be too clever (ie, reading and rewriting\n * the last long in the current block, and then reading and rewriting the first long in the next\n * block), which may have also created some undesirable side-effects for custom memory controllers.\n * This simpler (and probably more reliable) approach is to simply write the long as individual bytes.\n */\n var cb = 4;\n var cbBlock = 4 - (off & 0x3); // (off & 0x3) will be 1, 2 or 3, so cbBlock will be 3, 2, or 1\n while (cb--) {\n this.aMemBlocks[iBlock].writeByte(off++, l & 0xff, addr++);\n if (this.opFlags & X86.OPFLAG.FAULT) return;\n if (!--cbBlock) {\n iBlock = (iBlock + 1) & this.nBlockMask;\n off = 0;\n }\n l >>>= 8;\n }\n }\n\n /**\n * getEAByte(seg, off)\n *\n * @this {CPUX86}\n * @param {SegX86} seg register (eg, segDS)\n * @param {number} off is a segment-relative offset\n * @return {number} byte (8-bit) value at that address\n */\n getEAByte(seg, off)\n {\n this.segEA = seg;\n this.offEA = off & (I386? this.maskAddr : 0xffff);\n this.regEA = seg.checkRead(this.offEA, 1);\n if (this.opFlags & X86.OPFLAG.NOREAD) return 0;\n var b = this.getByte(this.regEA);\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiMem0;\n return b;\n }\n\n /**\n * getEAByteData(off)\n *\n * @this {CPUX86}\n * @param {number} off is a segment-relative offset\n * @return {number} byte (8-bit) value at that address\n */\n getEAByteData(off)\n {\n return this.getEAByte(this.segData, off);\n }\n\n /**\n * getEAByteStack(off)\n *\n * @this {CPUX86}\n * @param {number} off is a segment-relative offset\n * @return {number} byte (8-bit) value at that address\n */\n getEAByteStack(off)\n {\n return this.getEAByte(this.segStack, off);\n }\n\n /**\n * getEAWord(seg, off)\n *\n * @this {CPUX86}\n * @param {SegX86} seg register (eg, segDS)\n * @param {number} off is a segment-relative offset\n * @return {number} word (16-bit or 32-bit) value at that address\n */\n getEAWord(seg, off)\n {\n var w;\n this.segEA = seg;\n this.offEA = off & (I386? this.maskAddr : 0xffff);\n this.regEA = seg.checkRead(this.offEA, (I386? this.sizeData : 2));\n if (this.opFlags & (X86.OPFLAG.NOREAD | X86.OPFLAG.WRAP)) {\n if (this.opFlags & X86.OPFLAG.NOREAD) return 0;\n /*\n * The WRAP flag must have been set by checkReadReal(), so we also know that we're dealing with\n * a 16-bit read, which allows us to make some simplifications here.\n */\n w = this.getByte(this.regEA) | (this.getByte(seg.checkRead(0, 1)) << 8);\n }\n else {\n w = this.getWord(this.regEA);\n }\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiMem0;\n this.backTrack.btiEAHi = this.backTrack.btiMem1;\n }\n return w;\n }\n\n /**\n * getEAShortData(off)\n *\n * @this {CPUX86}\n * @param {number} off is a segment-relative offset\n * @return {number} short (16-bit) value at that address\n */\n getEAShortData(off)\n {\n var w;\n this.segEA = this.segData;\n this.offEA = off & (I386? this.maskAddr : 0xffff);\n this.regEA = this.segEA.checkRead(this.offEA, 2);\n if (this.opFlags & (X86.OPFLAG.NOREAD | X86.OPFLAG.WRAP)) {\n if (this.opFlags & X86.OPFLAG.NOREAD) return 0;\n /*\n * The WRAP flag must have been set by checkReadReal(), so we also know that we're dealing with\n * a 16-bit read, which allows us to make some simplifications here.\n */\n w = this.getByte(this.regEA) | (this.getByte(this.segEA.checkRead(0, 1)) << 8);\n this.opFlags &= ~X86.OPFLAG.WRAP;\n }\n else {\n w = this.getShort(this.regEA);\n }\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiMem0;\n this.backTrack.btiEAHi = this.backTrack.btiMem1;\n }\n return w;\n }\n\n /**\n * getEAShortStack(off)\n *\n * @this {CPUX86}\n * @param {number} off is a segment-relative offset\n * @return {number} short (16-bit) value at that address\n */\n getEAShortStack(off)\n {\n var w;\n this.segEA = this.segStack;\n this.offEA = off & (I386? this.maskAddr : 0xffff);\n this.regEA = this.segEA.checkRead(this.offEA, 2);\n if (this.opFlags & (X86.OPFLAG.NOREAD | X86.OPFLAG.WRAP)) {\n if (this.opFlags & X86.OPFLAG.NOREAD) return 0;\n /*\n * The WRAP flag must have been set by checkReadReal(), so we also know that we're dealing with\n * a 16-bit read, which allows us to make some simplifications here.\n */\n w = this.getByte(this.regEA) | (this.getByte(this.segEA.checkRead(0, 1)) << 8);\n this.opFlags &= ~X86.OPFLAG.WRAP;\n }\n else {\n w = this.getShort(this.regEA);\n }\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiMem0;\n this.backTrack.btiEAHi = this.backTrack.btiMem1;\n }\n return w;\n }\n\n /**\n * getEALongData(off)\n *\n * @this {CPUX86}\n * @param {number} off is a segment-relative offset\n * @return {number} long (32-bit) value at that address\n */\n getEALongData(off)\n {\n this.segEA = this.segData;\n this.offEA = off & (I386? this.maskAddr : 0xffff);\n this.regEA = this.segEA.checkRead(this.offEA, 4);\n if (this.opFlags & X86.OPFLAG.NOREAD) return 0;\n var w = this.getLong(this.regEA);\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiMem0;\n this.backTrack.btiEAHi = this.backTrack.btiMem1;\n }\n return w;\n }\n\n /**\n * getEALongStack(off)\n *\n * @this {CPUX86}\n * @param {number} off is a segment-relative offset\n * @return {number} long (32-bit) value at that address\n */\n getEALongStack(off)\n {\n this.segEA = this.segStack;\n this.offEA = off & (I386? this.maskAddr : 0xffff);\n this.regEA = this.segEA.checkRead(this.offEA, 4);\n if (this.opFlags & X86.OPFLAG.NOREAD) return 0;\n var w = this.getLong(this.regEA);\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiMem0;\n this.backTrack.btiEAHi = this.backTrack.btiMem1;\n }\n return w;\n }\n\n /**\n * setEAByte(b)\n *\n * @this {CPUX86}\n * @param {number} b is the byte (8-bit) value to write\n */\n setEAByte(b)\n {\n if (this.opFlags & X86.OPFLAG.NOWRITE) return;\n if (BACKTRACK) this.backTrack.btiMem0 = this.backTrack.btiEALo;\n this.setByte(this.segEA.checkWrite(this.offEA, 1), b);\n }\n\n /**\n * setEAShort(w)\n *\n * @this {CPUX86}\n * @param {number} w is the short (16-bit) value to write\n */\n setEAShort(w)\n {\n if (this.opFlags & X86.OPFLAG.NOWRITE) return;\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiEALo;\n this.backTrack.btiMem1 = this.backTrack.btiEAHi;\n }\n var addr = this.segEA.checkWrite(this.offEA, 2);\n if (this.opFlags & X86.OPFLAG.WRAP) {\n /*\n * The WRAP flag must have been set by checkWriteReal(), so we also know that we're dealing with\n * a 16-bit write, which allows us to make some simplifications here.\n */\n this.setByte(addr, w);\n this.setByte(this.segEA.checkWrite(0, 1), w >> 8);\n this.opFlags &= ~X86.OPFLAG.WRAP;\n }\n else {\n this.setShort(addr, w);\n }\n }\n\n /**\n * setEALong(l)\n *\n * @this {CPUX86}\n * @param {number} l is the long (32-bit) value to write\n */\n setEALong(l)\n {\n if (this.opFlags & X86.OPFLAG.NOWRITE) return;\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiEALo;\n this.backTrack.btiMem1 = this.backTrack.btiEAHi;\n }\n this.setLong(this.segEA.checkWrite(this.offEA, 4), l);\n }\n\n /**\n * setEAWord(w)\n *\n * @this {CPUX86}\n * @param {number} w is the word (16-bit or 32-bit) value to write\n */\n setEAWord(w)\n {\n if (this.opFlags & X86.OPFLAG.NOWRITE) return;\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiEALo;\n this.backTrack.btiMem1 = this.backTrack.btiEAHi;\n }\n var addr = this.segEA.checkWrite(this.offEA, this.sizeData);\n if (this.opFlags & X86.OPFLAG.WRAP) {\n /*\n * The WRAP flag must have been set by checkWriteReal(), so we also know that we're dealing with\n * a 16-bit write, which allows us to make some simplifications here.\n */\n this.setByte(addr, w);\n this.setByte(this.segEA.checkWrite(0, 1), w >> 8);\n this.opFlags &= ~X86.OPFLAG.WRAP;\n }\n else {\n this.setWord(addr, w);\n }\n }\n\n /**\n * getSOByte(seg, off)\n *\n * This is like getEAByte(), but it does NOT update regEA.\n *\n * @this {CPUX86}\n * @param {SegX86} seg register (eg, segDS)\n * @param {number} off is a segment-relative offset\n * @return {number} byte (8-bit) value at that address\n */\n getSOByte(seg, off)\n {\n return this.getByte(seg.checkRead(off, 1));\n }\n\n /**\n * getSOWord(seg, off)\n *\n * This is like getEAWord(), but it does NOT update regEA.\n *\n * @this {CPUX86}\n * @param {SegX86} seg register (eg, segDS)\n * @param {number} off is a segment-relative offset\n * @return {number} word (16-bit) value at that address\n */\n getSOWord(seg, off)\n {\n var w;\n var addr = seg.checkRead(off, this.sizeData);\n if (this.opFlags & X86.OPFLAG.WRAP) {\n /*\n * The WRAP flag must have been set by checkReadReal(), so we also know that we're dealing with\n * a 16-bit read, which allows us to make some simplifications here.\n */\n w = this.getByte(addr) | (this.getByte(seg.checkRead(0, 1)) << 8);\n this.opFlags &= ~X86.OPFLAG.WRAP;\n }\n else {\n w = this.getWord(addr);\n }\n return w;\n }\n\n /**\n * setSOByte(seg, off, b)\n *\n * This is like setEAByte(), but it does NOT update regEAWrite.\n *\n * @this {CPUX86}\n * @param {SegX86} seg register (eg, segDS)\n * @param {number} off is a segment-relative offset\n * @param {number} b is the byte (8-bit) value to write\n */\n setSOByte(seg, off, b)\n {\n this.setByte(seg.checkWrite(off, 1), b);\n }\n\n /**\n * setSOWord(seg, off, w)\n *\n * This is like setEAWord(), but it does NOT update regEAWrite.\n *\n * @this {CPUX86}\n * @param {SegX86} seg register (eg, segDS)\n * @param {number} off is a segment-relative offset\n * @param {number} w is the word (16-bit) value to write\n */\n setSOWord(seg, off, w)\n {\n var addr = seg.checkWrite(off, this.sizeData);\n if (this.opFlags & X86.OPFLAG.WRAP) {\n /*\n * The WRAP flag must have been set by checkWriteReal(), so we also know that we're dealing with\n * a 16-bit write, which allows us to make some simplifications here.\n */\n this.setByte(addr, w);\n this.setByte(seg.checkWrite(0, 1), w >> 8);\n this.opFlags &= ~X86.OPFLAG.WRAP;\n }\n else {\n this.setWord(addr, w);\n }\n }\n\n /**\n * getBytePrefetch()\n *\n * @this {CPUX86}\n * @return {number} byte (8-bit) value at regLIP\n */\n getBytePrefetch()\n {\n if (!this.cbPrefetch) {\n this.refillPrefetch();\n if (!this.cbPrefetch) return this.getByte(this.regLIP);\n }\n var b = (this.adwPrefetch[this.regLIP & CPUX86.PFINFO.IP_MASK] >> ((this.regLIP & 0x3) << 3)) & 0xff;\n\n this.cbPrefetch--;\n return b;\n }\n\n /**\n * getShortPrefetch()\n *\n * @this {CPUX86}\n * @return {number} short (16-bit) value at regLIP\n */\n getShortPrefetch()\n {\n if (this.cbPrefetch < 2) {\n this.refillPrefetch();\n if (this.cbPrefetch < 2) {\n this.cbPrefetch = 0;\n return this.getShort(this.regLIP);\n }\n }\n var shift = (this.regLIP & 0x3) << 3;\n var w = (this.adwPrefetch[this.regLIP & CPUX86.PFINFO.IP_MASK] >>> shift) & 0xffff;\n if (shift > 16) w |= (this.adwPrefetch[(this.regLIP + 4) & CPUX86.PFINFO.IP_MASK] & 0xff) << 8;\n\n this.cbPrefetch -= 2;\n return w;\n }\n\n /**\n * getLongPrefetch()\n *\n * @this {CPUX86}\n * @return {number} long (32-bit) value at regLIP\n */\n getLongPrefetch()\n {\n if (this.cbPrefetch < 4) {\n this.refillPrefetch();\n if (this.cbPrefetch < 4) {\n this.cbPrefetch = 0;\n return this.getLong(this.regLIP);\n }\n }\n var shift = (this.regLIP & 0x3) << 3;\n var l = (this.adwPrefetch[this.regLIP & CPUX86.PFINFO.IP_MASK] >>> shift)|0;\n if (shift) l |= this.adwPrefetch[(this.regLIP + 4) & CPUX86.PFINFO.IP_MASK] << (32 - shift);\n\n this.cbPrefetch -= 4;\n return l;\n }\n\n /**\n * getWordPrefetch()\n *\n * @this {CPUX86}\n * @return {number} short (16-bit) or long (32-bit) value as appropriate\n */\n getWordPrefetch()\n {\n return (I386 && this.sizeData == 4? this.getLongPrefetch() : this.getShortPrefetch());\n }\n\n /**\n * refillPrefetch()\n *\n * This function is similar to probeAddr() in that must NOT trigger a fault, because prefetching\n * inherently runs the risk of fetching more bytes that may actually be executed. Also, to keep it\n * simple, we limit prefetching to whatever bytes (if any) are available in the current page. If the\n * page is not present, or there are insufficient bytes in the current page to completely fill the\n * queue, then the caller must request byte(s) \"the old-fashioned way\", to ensure proper fault handling.\n *\n * For example, if getShortPrefetch() finds there are only 0 or 1 bytes in the prefetch queue, and\n * if it is unable to obtain any more bytes via refillPrefetch(), then getShortPrefetch() must call\n * getShort(this.regLIP) (which is also what would be called if PREFETCH was disabled completely).\n *\n * @this {CPUX86}\n */\n refillPrefetch()\n {\n var aBlocks = this.aMemBlocks;\n var regLIP = this.regLIP & ~0x3;\n var block = aBlocks[(regLIP & this.nMemMask) >>> this.nBlockShift];\n if (block && block.type == Memory.TYPE.UNPAGED) {\n block = this.mapPageBlock(regLIP, false, true);\n if (block === this.memEmpty) block = null;\n }\n if (block) {\n var off = regLIP & this.nBlockLimit;\n var cbMax = this.nBlockSize - off;\n if (cbMax > CPUX86.PFINFO.LENGTH) cbMax = CPUX86.PFINFO.LENGTH;\n for (var i = 0; i < cbMax; i += 4) {\n this.adwPrefetch[regLIP & CPUX86.PFINFO.IP_MASK] = block.readLongDirect(off, regLIP);\n off += 4; regLIP += 4;\n }\n this.cbPrefetch = i - (this.regLIP & 0x3);\n // this.nBusCycles += 4;\n } else {\n this.cbPrefetch = 0;\n }\n }\n\n /**\n * getIPByte()\n *\n * @this {CPUX86}\n * @return {number} byte at the current IP; IP advanced by 1\n */\n getIPByte()\n {\n var newLIP = this.checkIP(1);\n var b = (PREFETCH? this.getBytePrefetch() : this.getByte(this.regLIP));\n if (BACKTRACK) this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMem0);\n this.regLIP = newLIP;\n return b;\n }\n\n /**\n * getIPShort()\n *\n * @this {CPUX86}\n * @return {number} short at the current IP; IP advanced by 2\n */\n getIPShort()\n {\n var w;\n var newLIP = this.checkIP(2);\n if (PREFETCH) {\n w = this.getShortPrefetch();\n } else if (!(this.opFlags & X86.OPFLAG.WRAP)) {\n w = this.getShort(this.regLIP);\n } else {\n /*\n * The WRAP flag must have been set by checkIP(2), so we also know that we're dealing with\n * a 16-bit read, which allows us to make some simplifications here.\n */\n w = this.getByte(this.regLIP) | (this.getByte(newLIP - 1) << 8);\n this.opFlags &= ~X86.OPFLAG.WRAP;\n }\n if (BACKTRACK) {\n this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMem0);\n this.bus.updateBackTrackCode(this.regLIP + 1, this.backTrack.btiMem1);\n }\n this.regLIP = newLIP;\n return w;\n }\n\n /**\n * getIPAddr()\n *\n * @this {CPUX86}\n * @return {number} word at the current IP; IP advanced by 2 or 4, depending on address size\n */\n getIPAddr()\n {\n var w;\n var newLIP = this.checkIP(this.sizeAddr);\n if (PREFETCH) {\n w = this.getAddr();\n } else if (!(this.opFlags & X86.OPFLAG.WRAP)) {\n w = this.getAddr(this.regLIP);\n } else {\n /*\n * The WRAP flag must have been set by checkIP(), so we also know that we're dealing with\n * a 16-bit read, which allows us to make some simplifications here.\n */\n w = this.getByte(this.regLIP) | (this.getByte(newLIP - 1) << 8);\n this.opFlags &= ~X86.OPFLAG.WRAP;\n }\n if (BACKTRACK) {\n this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMem0);\n this.bus.updateBackTrackCode(this.regLIP + 1, this.backTrack.btiMem1);\n }\n this.regLIP = newLIP;\n return w;\n }\n\n /**\n * getIPWord()\n *\n * @this {CPUX86}\n * @return {number} word at the current IP; IP advanced by 2 or 4, depending on operand size\n */\n getIPWord()\n {\n var w;\n var newLIP = this.checkIP(this.sizeData);\n if (PREFETCH) {\n w = this.getWordPrefetch();\n } else if (!(this.opFlags & X86.OPFLAG.WRAP)) {\n w = this.getWord(this.regLIP);\n } else {\n /*\n * The WRAP flag must have been set by checkIP(), so we also know that we're dealing with\n * a 16-bit read, which allows us to make some simplifications here.\n */\n w = this.getByte(this.regLIP) | (this.getByte(newLIP - 1) << 8);\n this.opFlags &= ~X86.OPFLAG.WRAP;\n }\n if (BACKTRACK) {\n this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMem0);\n this.bus.updateBackTrackCode(this.regLIP + 1, this.backTrack.btiMem1);\n }\n this.regLIP = newLIP;\n return w;\n }\n\n /**\n * getIPDisp()\n *\n * @this {CPUX86}\n * @return {number} sign-extended (32-bit) value from the byte at the current IP; IP advanced by 1\n */\n getIPDisp()\n {\n var newLIP = this.checkIP(1);\n var w = ((PREFETCH? this.getBytePrefetch() : this.getByte(this.regLIP)) << 24) >> 24;\n if (BACKTRACK) this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMem0);\n this.regLIP = newLIP;\n return w;\n }\n\n /**\n * peekIPByte()\n *\n * @this {CPUX86}\n * @return {number} byte at the current IP\n */\n peekIPByte()\n {\n return (PREFETCH? this.getBytePrefetch() : this.getByte(this.regLIP));\n }\n\n /**\n * popWord()\n *\n * @this {CPUX86}\n * @return {number} word popped from the current SP; SP increased by 2 or 4\n */\n popWord()\n {\n var data = this.getWord(this.regLSP);\n var width = I386? this.sizeData : 2;\n this.regLSP = (this.regLSP + width)|0;\n \n var delta = this.regLSPLimit - (this.regLSP >>> 0);\n if (delta < 0) {\n /*\n * There's no such thing as an SS fault on the 8086/8088, and in fact, we have to support the\n * operation even when the address straddles the wrap boundary; other emulators tend to barf on\n * a wrap, usually because they're running in V86 mode instead of real mode.\n */\n if (this.model <= X86.MODEL_8088) {\n this.setSP((this.regLSP - this.segSS.base) & this.segSS.maskAddr);\n if (delta < -1) {\n data = (data & 0xff) | (this.getByte(this.regLSP - 1) << 8);\n }\n }\n else {\n /*\n * I'm assuming that, on newer processors, when the stack segment limit is set to the maximum,\n * it's OK for the stack to wrap, unless the new address is straddling the wrap boundary (ie, when\n * delta is < -1).\n *\n * NOTE: This combines the old 8088 address-wrap check with the new segment-limit check, even though\n * the correct time to do the latter is immediately BEFORE the fetch, not AFTER.\n */\n if (delta < -1) {\n X86.helpFault.call(this, X86.EXCEPTION.SS_FAULT, 0);\n }\n else if (!this.segSS.fExpDown && this.segSS.limit == this.segSS.maskAddr || this.segSS.fExpDown && !this.segSS.limit) {\n this.setSP((this.regLSP - this.segSS.base) & this.segSS.maskAddr);\n }\n }\n }\n return data;\n }\n\n /**\n * pushWord(w)\n *\n * NOTE: pushWord() used to do a simplified version of pushData(), and while that might have made the emulator\n * slightly faster, it was woefully duplicative. Let's trust the combination of the Closure Compiler and the\n * JavaScript engines to automatically inline instead.\n *\n * @this {CPUX86}\n * @param {number} w is the word (16-bit) value to push at current SP; SP decreased by 2 or 4\n */\n pushWord(w)\n {\n this.pushData(w, I386? this.sizeData : 2);\n }\n\n /**\n * pushData(data, width, size)\n *\n * The size parameter serves two very limited purposes: 1) the ability to push data according to a previous\n * operand size, and 2) the ability to write fewer bytes than the width if necessary.\n *\n * The former occurs when a 32-bit code segment performs a 16:32 call to a 16-bit code segment; after the\n * new 16-bit code segment is loaded (and possible stack switch occurs), the return address (both segment\n * and offset) must still be pushed as 32-bit values.\n *\n * The latter occurs with segment register pushes. When a 32-bit operand size is in effect (ie, width is 4),\n * only the low 16 bits should be written (size must be 2).\n *\n * For all other kinds of pushes, width and size are impliedly the same.\n *\n * @this {CPUX86}\n * @param {number} data is the data to push at current SP; SP decreased by size\n * @param {number} width is the width of the data to push, in bytes (must be either 2 or 4)\n * @param {number} [size] is the size of the data to push, in bytes (must be 1, 2, or 4, and <= width)\n */\n pushData(data, width, size = width)\n {\n\n\n var regLSP = (this.regLSP - width)|0;\n \n var delta = (regLSP >>> 0) - this.regLSPLimitLow;\n if (delta < 0) {\n /*\n * There's no such thing as an SS fault on the 8086/8088, and in fact, we have to support the\n * operation even when the address straddles the wrap boundary (ie, when delta is -1); other\n * emulators tend to barf on a wrap, usually because they're running in V86 mode instead of real mode.\n */\n if (this.model <= X86.MODEL_8088) {\n if (delta == -1) {\n this.setByte(regLSP + 1, data >> 8);\n this.setSP((regLSP - this.segSS.base) & this.segSS.maskAddr);\n this.setByte(this.regLSP, data);\n return;\n }\n\n }\n /*\n * I'm assuming that, on newer processors, when the stack segment limit is set to the maximum,\n * it's OK for the stack to wrap, unless the new address is straddling the wrap boundary (ie, when\n * delta is < 0 and > -width).\n */\n if (!this.segSS.fExpDown && this.segSS.limit == this.segSS.maskAddr || this.segSS.fExpDown && !this.segSS.limit) {\n if (delta > -width) {\n X86.helpFault.call(this, X86.EXCEPTION.SS_FAULT, 0);\n return;\n }\n this.setSP((regLSP - this.segSS.base) & this.segSS.maskAddr);\n regLSP = this.regLSP;\n } else {\n X86.helpFault.call(this, X86.EXCEPTION.SS_FAULT, 0);\n return;\n }\n }\n\n switch(size) {\n case 1:\n this.setByte(regLSP, data);\n break;\n case 2:\n this.setShort(regLSP, data);\n break;\n case 4:\n this.setLong(regLSP, data);\n break;\n default:\n\n break;\n }\n\n /*\n * We update this.regLSP at the end to make life simpler for opcode handlers that perform only one\n * pushWord() operation, relieving them from having to snapshot this.regLSP into this.opLSP needlessly.\n */\n this.regLSP = regLSP;\n }\n\n /**\n * checkINTR()\n *\n * This must only be called when intFlags (containing the simulated INTFLAG.INTR signal) is known to be set.\n * Note that it's perfectly possible that between the time updateINTR(true) was called and we request the\n * interrupt vector number below, the interrupt could have been cleared or masked, in which case getIRRVector()\n * will return -1 and we'll simply clear INTFLAG.INTR.\n *\n * intFlags has been overloaded with the INTFLAG.TRAP bit as well, since the acknowledgment of h/w interrupts\n * and the Trap flag are similar; they must both honor the NOINTR suppression flag, and stepCPU() shouldn't\n * have to check multiple variables when deciding whether to simulate an interrupt.\n *\n * This function also includes a check for the new async INTFLAG.DMA flag, which is triggered by a ChipSet call\n * to setDMA(). This DMA flag actually has nothing to do with interrupts; it's simply an expedient way to\n * piggy-back on the CPU's execution logic, to help drive async DMA requests.\n *\n * Originally, DMA requests (eg, FDC or HDC I/O operations) were all handled synchronously, since no actual\n * I/O was required to satisfy the request; from the CPU's perspective, this meant DMA operations were virtually\n * instantaneous. However, with the introduction of remote disk connections, some actual I/O may now be required;\n * in practice, this means that the FIRST byte requested as part of a DMA operation may require a callback to\n * finish, while all remaining bytes will be retrieved during subsequent checkINTR() calls -- unless of course\n * additional remote I/O operations are required to complete the DMA operation.\n *\n * As a result, the CPU will run slightly slower while an async DMA request is in progress, but the slowdown\n * should be negligible. One downside is that this slowdown will be in effect for the entire duration of the\n * I/O (ie, even while we're waiting for the remote I/O to finish), so the ChipSet component should avoid\n * calling setDMA() whenever possible.\n *\n * TODO: While comparing SYMDEB tracing in both PCx86 and VMware, I noticed that after single-stepping ANY\n * segment-load instruction, SYMDEB would get control immediately after that instruction in VMware, whereas\n * I delay acknowledgment of the Trap flag until the *following* instruction, so in PCx86, SYMDEB doesn't get\n * control until the following instruction. I think PCx86 behavior is correct, at least for SS.\n *\n * ERRATA: Early revisions of the 8086/8088 failed to suppress hardware interrupts (and possibly also Trap\n * acknowledgements) after an SS load, but Intel corrected the problem at some point; however, I don't know when\n * that change was made or which IBM PC models may have been affected, if any. TODO: More research required.\n *\n * WARNING: There is also a priority consideration here. On the 8086/8088, hardware interrupts have higher\n * priority than Trap interrupts (which is why the code below is written the way it is). A potentially\n * undesirable side-effect is that a hardware interrupt handler could end up being single-stepped if an\n * external interrupt occurs immediately after the Trap flag is set. This is why some 8086 debuggers temporarily\n * mask all hardware interrupts during a single-step operation (although that doesn't help with NMIs generated\n * by a coprocessor). As of the 80286, those priorities were inverted, giving the Trap interrupt higher priority\n * than external interrupts.\n *\n * TODO: Determine the priorities for the 80186.\n *\n * @this {CPUX86}\n * @return {boolean} true if h/w interrupt (or trap) has just been acknowledged, false if not\n */\n checkINTR()\n {\n // DEBUG:\n\n if (!(this.opFlags & X86.OPFLAG.NOINTR)) {\n /*\n * As discussed above, the 8086/8088 give hardware interrupts higher priority than the TRAP interrupt,\n * whereas the 80286 and up give TRAPs higher priority.\n */\n var iPriority = (this.model < X86.MODEL_80286? 0 : 1);\n for (var cPriorities = 0; cPriorities < 2; cPriorities++) {\n switch(iPriority) {\n case 0:\n if ((this.intFlags & X86.INTFLAG.INTR) && (this.regPS & X86.PS.IF)) {\n var nIDT = this.chipset.getIRRVector();\n if (nIDT >= -1) {\n this.intFlags &= ~X86.INTFLAG.INTR;\n if (nIDT >= 0) {\n this.intFlags &= ~X86.INTFLAG.HALT;\n X86.helpInterrupt.call(this, nIDT);\n return true;\n }\n }\n }\n break;\n case 1:\n if ((this.intFlags & X86.INTFLAG.TRAP)) {\n this.intFlags &= ~X86.INTFLAG.TRAP;\n if (I386 && this.model >= X86.MODEL_80386) this.regDR[6] |= X86.DR6.BS;\n X86.helpInterrupt.call(this, X86.EXCEPTION.DB_EXC);\n return true;\n }\n break;\n }\n iPriority = 1 - iPriority;\n }\n }\n /*\n * As long as the ChipSet component isn't calling setDMA(), we don't need to test INTFLAG.DMA...\n *\n if (this.intFlags & X86.INTFLAG.DMA) {\n if (!this.chipset.checkDMA()) {\n this.intFlags &= ~X86.INTFLAG.DMA;\n }\n }\n */\n return false;\n }\n\n /**\n * updateINTR(fRaise)\n *\n * This is called by the ChipSet component whenever a h/w interrupt needs to be simulated.\n * This is how the PIC component simulates raising the INTFLAG.INTR signal. We will honor the request\n * only if we have a reference back to the ChipSet component. The CPU will then \"respond\" by calling\n * checkINTR() and request the corresponding interrupt vector from the ChipSet.\n *\n * @this {CPUX86}\n * @param {boolean} fRaise is true to raise INTFLAG.INTR, false to lower\n */\n updateINTR(fRaise)\n {\n if (this.chipset) {\n if (fRaise) {\n this.intFlags |= X86.INTFLAG.INTR;\n } else {\n this.intFlags &= ~X86.INTFLAG.INTR;\n }\n }\n }\n\n /**\n * delayINTR()\n *\n * This is called by the ChipSet component whenever the IMR register is being unmasked, to avoid\n * interrupts being simulated too quickly. This works around a problem in the ROM BIOS \"KBD_RESET\"\n * (F000:E688) function, which is called with interrupts enabled by the \"TST8\" (F000:E30D) code.\n *\n * \"KBD_RESET\" appears to be written with the assumption that CLI is in effect, because it issues an\n * STI immediately after unmasking the keyboard IRQ. And normally, the STI would delay INTFLAG.INTR\n * long enough to allow AH to be set to 0. But if interrupts are already enabled, an interrupt could\n * theoretically occur before the STI. And since AH isn't initialized until after the STI, such an\n * interrupt would be missed.\n *\n * I'm assuming this never happens in practice because the PIC isn't that fast. But for us to\n * guarantee that, we need to provide this function to the ChipSet component.\n *\n * @this {CPUX86}\n */\n delayINTR()\n {\n this.opFlags |= X86.OPFLAG.NOINTR;\n }\n\n /**\n * updateReg(sReg, nValue)\n *\n * This function helps updateStatus() by massaging the register names and values according to\n * CPU type before passing the call to displayValue(); in the \"old days\", updateStatus() called\n * displayValue() directly (although then it was called displayReg()).\n *\n * @this {CPUX86}\n * @param {string} sReg\n * @param {number} nValue\n */\n updateReg(sReg, nValue)\n {\n var cch = 4;\n if (sReg.length == 1) {\n cch = 1;\n nValue = nValue? 1 : 0;\n }\n if (this.model < 80386) {\n if (sReg.length > 2) {\n sReg = sReg.substr(1, 2);\n }\n } else {\n if (sReg == \"PS\" || sReg.length > 2) {\n cch = 8;\n }\n }\n this.displayValue(sReg, nValue, cch);\n }\n\n /**\n * updateStatus(fForce)\n *\n * This provides periodic Control Panel updates (eg, a few times per second; see Computer.UPDATES_PER_SECOND).\n * this is where we take care of any DOM updates (eg, register values) while the CPU is running.\n *\n * @this {CPUX86}\n * @param {boolean} [fForce] (true will display registers even if the CPU is running and \"live\" registers are not enabled)\n */\n updateStatus(fForce)\n {\n if (this.cLiveRegs) {\n if (fForce || !this.flags.running || this.flags.displayLiveRegs) {\n this.updateReg(\"EAX\", this.regEAX);\n this.updateReg(\"EBX\", this.regEBX);\n this.updateReg(\"ECX\", this.regECX);\n this.updateReg(\"EDX\", this.regEDX);\n this.updateReg(\"ESP\", this.getSP());\n this.updateReg(\"EBP\", this.regEBP);\n this.updateReg(\"ESI\", this.regESI);\n this.updateReg(\"EDI\", this.regEDI);\n this.updateReg(\"CS\", this.getCS());\n this.updateReg(\"DS\", this.getDS());\n this.updateReg(\"SS\", this.getSS());\n this.updateReg(\"ES\", this.getES());\n this.updateReg(\"EIP\", this.getIP());\n var regPS = this.getPS();\n this.updateReg(\"PS\", regPS);\n this.updateReg(\"V\", (regPS & X86.PS.OF));\n this.updateReg(\"D\", (regPS & X86.PS.DF));\n this.updateReg(\"I\", (regPS & X86.PS.IF));\n this.updateReg(\"T\", (regPS & X86.PS.TF));\n this.updateReg(\"S\", (regPS & X86.PS.SF));\n this.updateReg(\"Z\", (regPS & X86.PS.ZF));\n this.updateReg(\"A\", (regPS & X86.PS.AF));\n this.updateReg(\"P\", (regPS & X86.PS.PF));\n this.updateReg(\"C\", (regPS & X86.PS.CF));\n if (this.model == X86.MODEL_80386) {\n this.updateReg(\"FS\", this.getFS());\n this.updateReg(\"GS\", this.getGS());\n this.updateReg(\"CR0\", this.regCR0);\n this.updateReg(\"CR2\", this.regCR2);\n this.updateReg(\"CR3\", this.regCR3);\n }\n }\n }\n\n var controlSpeed = this.bindings[\"speed\"];\n if (controlSpeed) controlSpeed.textContent = this.getSpeedCurrent();\n }\n\n /**\n * stepCPU(nMinCycles)\n *\n * NOTE: Single-stepping should not be confused with the Trap flag; single-stepping is a Debugger\n * operation that's completely independent of Trap status. The CPU can go in and out of Trap mode,\n * in and out of h/w interrupt service routines (ISRs), etc, but from the Debugger's perspective,\n * they're all one continuous stream of instructions that can be stepped or run at will. Moreover,\n * stepping vs. running should never change the behavior of the simulation.\n *\n * Similarly, the Debugger's execution breakpoints have no involvement with the x86 breakpoint instruction\n * (0xCC); the Debugger monitors changes to the regLIP register to implement its own execution breakpoints.\n *\n * As a result, the Debugger's complete independence means you can run other 8086/8088 debuggers\n * (eg, DEBUG) inside the simulation without interference; you can even \"debug\" them with the Debugger.\n *\n * @this {CPUX86}\n * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored)\n * @return {number} of cycles executed; 0 indicates a pre-execution condition (ie, an execution breakpoint\n * was hit), -1 indicates a post-execution condition (eg, a read or write breakpoint was hit), and a positive\n * number indicates successful completion of that many cycles (which should always be >= nMinCycles).\n */\n stepCPU(nMinCycles)\n {\n /*\n * The Debugger uses fComplete to determine if the instruction completed (true) or was interrupted\n * by a breakpoint or some other exceptional condition (false). NOTE: this does NOT include JavaScript\n * exceptions, which stepCPU() expects the caller to catch using its own exception handler.\n *\n * The CPU relies on the use of stopCPU() rather than fComplete, because the CPU never single-steps\n * (ie, nMinCycles is always some large number), whereas the Debugger does. And conversely, when the\n * Debugger is single-stepping (even when performing multiple single-steps), fRunning is never set,\n * so stopCPU() would have no effect as far as the Debugger is concerned.\n */\n this.flags.complete = true;\n\n /*\n * fDebugCheck is true if we need to \"check\" every instruction with the Debugger.\n */\n var fDebugCheck = this.flags.debugCheck = (DEBUGGER && this.dbg && this.dbg.checksEnabled());\n\n /*\n * nDebugState is checked only when fDebugCheck is true, and its sole purpose is to tell the first call\n * to checkInstruction() that it can skip breakpoint checks, and that will be true ONLY when fStarting is\n * true OR nMinCycles is zero (the latter means the Debugger is single-stepping).\n *\n * Once we snap fStarting, we clear it, because technically, we've moved beyond \"starting\" and have\n * officially \"started\" now.\n */\n var nDebugState = (!nMinCycles)? -1 : (this.flags.starting? 0 : 1);\n this.flags.starting = false;\n\n /*\n * We move the minimum cycle count to nStepCycles (the number of cycles left to step), so that other\n * functions have the ability to force that number to zero (eg, stopCPU()), and thus we don't have to check\n * any other criteria to determine whether we should continue stepping or not.\n */\n this.nBurstCycles = this.nStepCycles = nMinCycles;\n\n /*\n * NOTE: Even though runCPU() calls updateAllTimers(), we need an additional call here if we're being\n * called from the Debugger, so that any single-stepping will update the timers as well.\n */\n if (this.chipset && !nMinCycles) this.chipset.updateAllTimers();\n\n /*\n * Let's also suppress h/w interrupts whenever the Debugger is single-stepping an instruction; I'm loathe\n * to allow Debugger interactions to affect the behavior of the virtual machine in ANY way, but I'm making\n * this small concession to avoid the occasional and sometimes unexpected Debugger command that ends up\n * stepping into a hardware interrupt service routine (ISR).\n *\n * Note that this is similar to the problem discussed in checkINTR() regarding the priority of external h/w\n * interrupts vs. Trap interrupts, but they require different solutions, because our Debugger operates\n * independently of the CPU.\n *\n * One exception I make here is when you've asked the Debugger to display PIC messages, the idea being that\n * if you're watching the PIC that closely, then you want to hardware interrupts to occur regardless.\n */\n if (!nMinCycles && !this.messageEnabled(Messages.PIC)) this.opFlags |= X86.OPFLAG.NOINTR;\n\n do {\n var opPrefixes = this.opFlags & X86.OPFLAG_PREFIXES;\n if (opPrefixes) {\n this.opPrefixes |= opPrefixes;\n } else {\n /*\n * opLIP is used, among other things, to help string instructions rewind to the first prefix\n * byte whenever the instruction needs to be repeated. Repeating string instructions in this\n * manner (essentially restarting them) is a bit heavy-handed, but ultimately it's more compatible,\n * because it allows hardware interrupts (as well as Trap processing and Debugger single-stepping)\n * to occur at any point during the string operation, without any additional effort.\n *\n * NOTE: The way we restart string instructions actually fixes an 8086/8088 flaw, because string\n * instructions with multiple prefixes (eg, a REP and a segment override) would not be restarted\n * properly following a hardware interrupt. The recommended workarounds were to either turn off\n * interrupts or to follow the string instruction with a LOOPNZ back to the first prefix byte.\n * To emulate the flawed behavior, turn on BUGS_8086.\n */\n this.opLIP = this.regLIP;\n this.segData = this.segDS;\n this.segStack = this.segSS;\n this.regEA = this.regEAWrite = X86.ADDR_INVALID;\n\n if (I386 && (this.opPrefixes & (X86.OPFLAG.ADDRSIZE | X86.OPFLAG.DATASIZE))) {\n this.resetSizes();\n }\n\n this.opPrefixes = this.opFlags & X86.OPFLAG.REPEAT;\n\n if (this.intFlags) {\n if (this.checkINTR()) {\n if (!nMinCycles) {\n\n if (DEBUGGER) {\n this.println(\"interrupt dispatched\");\n this.opFlags = 0;\n break;\n }\n }\n }\n if (this.intFlags & X86.INTFLAG.HALT) {\n /*\n * As discussed in opHLT(), the CPU is never REALLY halted by a HLT instruction, because the\n * entire machine relies on the steady advance of the overall cycle count, to ensure that timer\n * updates, video updates, etc, all continue to occur at the expected rates.\n * \n * So opHLT() sets X86.INTFLAG.HALT, signalling that we should not execute any more instructions\n * until checkINTR() detects a hardware interrupt and clears X86.INTFLAG.HALT. \n * \n * Ideally, we would also end the current burst; ie:\n *\n * this.nStepCycles = 0;\n * this.opFlags = 0;\n * break;\n * \n * and save the browser a bunch of work, which would translate into power savings for the host\n * operating system, just as HLT was intended to do for the guest operating system. Unfortunately,\n * that screws up up our dynamic speed recalculations, because it makes it appear that a single\n * instruction (HLT) performed the work of many.\n *\n * We could certainly add more cycle bookkeeping to compensate for HLT's lack of work, but for now,\n * it's simpler to re-execute the HLT as long as X86.INTFLAG.HALT is set. \n */\n X86.opHLT.call(this);\n continue;\n }\n }\n }\n\n if (DEBUGGER && fDebugCheck) {\n if (this.dbg.checkInstruction(this.regLIP, nDebugState)) {\n this.stopCPU();\n break;\n }\n nDebugState = 1;\n }\n\n this.opFlags = 0;\n\n /*\n if (DEBUG || PREFETCH) {\n this.nBusCycles = 0;\n this.nSnapCycles = this.nStepCycles;\n }\n */\n\n this.aOps[this.getIPByte()].call(this);\n\n /*\n if (PREFETCH) {\n var nSpareCycles = (this.nSnapCycles - this.nStepCycles) - this.nBusCycles;\n if (nSpareCycles >= 4) {\n this.fillPrefetch(nSpareCycles >> 2); // for every 4 spare cycles, fetch 1 instruction byte\n }\n }\n */\n\n /*\n if (DEBUG) {\n //\n // Make sure that every instruction is assessing a cycle cost, and that the cost is a net positive.\n //\n if (this.flags.complete && this.nStepCycles >= this.nSnapCycles && !(this.opFlags & X86.OPFLAG_PREFIXES)) {\n this.println(\"cycle miscount: \" + (this.nSnapCycles - this.nStepCycles));\n this.setIP(this.opLIP - this.segCS.base);\n this.stopCPU();\n break;\n }\n }\n */\n\n } while (this.nStepCycles > 0);\n\n return (this.flags.complete? this.nBurstCycles - this.nStepCycles : (this.flags.complete === undefined? 0 : -1));\n }\n\n /**\n * setAddrSize(size)\n *\n * This is used by opcodes that require a particular ADDRESS size, which we enforce by\n * internally simulating an ADDRESS size override, if needed.\n *\n * @this {CPUX86}\n * @param {number} size (2 for 2-byte/16-bit operands, or 4 for 4-byte/32-bit operands)\n *\n setAddrSize(size)\n {\n if (this.sizeAddr != size) {\n this.opPrefixes |= X86.OPFLAG.ADDRSIZE;\n this.sizeAddr = size;\n this.maskAddr = (size == 2? 0xffff : (0xffffffff|0));\n this.updateAddrSize();\n }\n }\n */\n\n /**\n * getIPLong()\n *\n * @this {CPUX86}\n * @return {number} long at the current IP; IP advanced by 4\n *\n getIPLong()\n {\n var newLIP = this.checkIP(4);\n var l = (PREFETCH? this.getLongPrefetch() : this.getLong(this.regLIP));\n if (BACKTRACK) {\n this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMem0);\n this.bus.updateBackTrackCode(this.regLIP + 1, this.backTrack.btiMem1);\n this.bus.updateBackTrackCode(this.regLIP + 2, this.backTrack.btiMem2);\n this.bus.updateBackTrackCode(this.regLIP + 3, this.backTrack.btiMem3);\n }\n this.regLIP = newLIP;\n return l;\n }\n */\n\n /**\n * setDMA(fActive)\n *\n * This is called by the ChipSet component to update DMA status.\n *\n * @this {CPUX86}\n * @param {boolean} fActive is true to set INTFLAG.DMA, false to clear\n *\n setDMA(fActive)\n {\n if (this.chipset) {\n if (fActive) {\n this.intFlags |= X86.INTFLAG.DMA;\n } else {\n this.intFlags &= ~X86.INTFLAG.DMA;\n }\n }\n }\n */\n\n /**\n * CPUX86.init()\n *\n * This function operates on every HTML element of class \"cpu\", extracting the\n * JSON-encoded parameters for the CPUX86 constructor from the element's \"data-value\"\n * attribute, invoking the constructor (which in turn invokes the CPU constructor)\n * to create a CPUX86 component, and then binding any associated HTML controls to the\n * new component.\n */\n static init()\n {\n var aeCPUs = Component.getElementsByClass(document, PCX86.APPCLASS, \"cpu\");\n for (var iCPU = 0; iCPU < aeCPUs.length; iCPU++) {\n var eCPU = aeCPUs[iCPU];\n var parmsCPU = Component.getComponentParms(eCPU);\n var cpu = new CPUX86(parmsCPU);\n Component.bindComponentControls(cpu, eCPU, PCX86.APPCLASS);\n }\n }\n}\n\nif (PREFETCH) {\n /*\n * NOTE: CPUX86.PFINFO.LENGTH must be set to a power of two, so that LENGTH - 1 will form a mask\n * (IP_MASK) we can use to create a sliding prefetch window of LENGTH bytes. We also zero the low\n * 2 bits of IP_MASK so that the sliding window always starts on a 32-bit (long) boundary. Finally,\n * instead breaking breaking all the longs we prefetch into bytes, we simply store the longs as-is\n * into every 4th element of the queue (the queue is sparse array).\n */\n CPUX86.PFINFO = {\n LENGTH: 16 // 16 generates a 16-byte prefetch queue consisting of 4 32-bit entries\n };\n CPUX86.PFINFO.IP_MASK = ((CPUX86.PFINFO.LENGTH - 1) & ~0x3);\n}\n\nCPUX86.PAGEBLOCKS_CACHE = 512; // TODO: This seems adequate for 4Mb of RAM, but it should be dynamically reconfigured\n\n/*\n * Initialize every CPU module on the page\n */\nWeb.onInit(CPUX86.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/fpux86.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * Operand Type Reference\n *\n * ST(0), ST stack top; the register currently at the top of the stack\n * ST(i) register in the stack i (0<=i<=7) stack elements from the top\n * SR (short-real) short real (32 bits) number in memory; exponent bias is 127 (0x7f)\n * LR (long-real) long real (64 bits) number in memory; exponent bias is 1023 (0x3ff)\n * TR (temp-real) temporary real (80 bits) number in memory; exponent bias is 16383 (0x3fff)\n * PD (packed-decimal) packed decimal integer (18 digits, 10 bytes) in memory\n * WI (word-integer) word binary integer (16 bits) in memory\n * SI (short-integer) short binary integer (32 bits) in memory\n * LI (long-integer) long binary integer (64 bits) in memory\n * NN (nn-bytes) memory area nn bytes long\n *\n * FPU Coprocessor Trivia\n *\n * Microsoft C 4.00 libraries executed software interrupts in the range 0x34-0x3B immediately after\n * FPU operations, to assist with floating-point emulation when no coprocessor was present, since\n * processors prior to the 80286 had no mechanism for generating a fault when an unsupported FPU\n * instruction was executed.\n *\n * In short, INT 0x34 through INT 0x3B was used after ESC opcodes 0xD8 through 0xDF, INT 0x3C was\n * used for FPU instructions containing a segment override, and INT 0x3D was used for FWAIT.\n *\n * A sample piece of code is available in x86ops.js, because it also highlights the Microsoft C 4.00\n * library's dependency on the 8086/8088 behavior of \"PUSH SP\" (see the opPUSHSP_8086() function).\n */\n\n/**\n * class FPUX86\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass FPUX86 extends Component {\n /**\n * FPUX86(parmsFPU)\n *\n * The FPUX86 class uses the following (parmsFPU) properties:\n *\n * model: a number (eg, 8087) that should match one of the X86.FPU.MODEL values (default is 8087)\n * stepping: a string (eg, \"B1\") that should match one of the X86.FPU.STEPPING values (default is \"\")\n *\n * @this {FPUX86}\n * @param {Object} parmsFPU\n */\n constructor(parmsFPU)\n {\n super(\"FPU\", parmsFPU);\n\n this.model = parmsFPU['model'] || X86.FPU.MODEL_8087;\n\n /*\n * We take the 'stepping' value, convert it to a hex value, and then add that to the model to provide\n * a single value that's unique for any given CPU stepping. If no stepping is provided, then stepping\n * is equal to model.\n */\n var stepping = parmsFPU['stepping'];\n this.stepping = this.model + (stepping? Str.parseInt(stepping, 16) : 0);\n\n /*\n * Perform a one-time allocation of all floating-point registers.\n * NOTE: The FPU's internal registers are supposed to be 80-bit, but JavaScript gives us only 64-bit floats.\n */\n this.regStack = new Float64Array(8);\n this.intStack = new Int32Array(this.regStack.buffer);\n\n /*\n * Used for \"short-real\" (SR) 32-bit floating-point operations.\n */\n this.regTmpSR = new Float32Array(1);\n this.intTmpSR = new Int32Array(this.regTmpSR.buffer);\n\n /*\n * Used for \"long-real\" (LR) 64-bit floating-point operations. We also use intTmpLR as temporary storage\n * for all \"word-integer\" (WI or INT16), \"short-integer\" (SI or INT32) and \"long-integer\" (LI or INT64) values,\n * since it's just large enough to accommodate all three integer sizes.\n */\n this.regTmpLR = new Float64Array(1);\n this.intTmpLR = new Int32Array(this.regTmpLR.buffer);\n\n /*\n * Used for conversion to/from the 80-bit \"temp-real\" (TR) format; used as three 32-bit integers,\n * where [0] contains TR bits 0-31, [1] contains TR bits 32-63, and [2] contains TR bits 64-79; the\n * upper 16 bits of [2] are not used and should remain zero.\n */\n this.intTmpTR = new Array(3);\n\n /*\n * Initialize other (non-floating-point) coprocessor registers that resetFPU() doesn't touch,\n * such as the \"exception\" registers: regCodeSel, regCodeOff, regDataSel, regDataOff, and regOpcode.\n *\n * Note that regCodeSel and regDataSel are NEVER set in real-mode and are ALWAYS set in protected-mode,\n * so we set them to -1 in their \"unset\" state; if those values ever show up in an exception block,\n * something may have gone amiss (it's not impossible though, because if an exception occurs before any\n * memory operands have been used, regDataSel may still be \"unset\").\n *\n * NOTE: iStack is the low 3 bits of the bModRM byte, for instructions that have an explicit stack operand.\n */\n this.regCodeSel = this.regDataSel = -1;\n this.regCodeOff = this.regDataOff = this.regOpcode = this.iStack = 0;\n\n /*\n * Initialize special floating-point constants, as if they were internal read-only registers;\n * all other simple (non-special) constants are \"statically\" initialized below, as class constants.\n */\n this.regIndefinite = new Float64Array(1);\n this.intIndefinite = new Int32Array(this.regIndefinite.buffer);\n this.intIndefinite[0] = 0x00000000; this.intIndefinite[1] = 0xFFF8000;\n\n /*\n * Initialize all other coprocessor registers (control word, tag word, status word, etc) by resetting them.\n */\n this.resetFPU();\n /**\n * setEAFromSR()\n *\n * Stores the (32-bit) \"short-real\" value in the internal regTmpSR register to the address in regEA.\n *\n * @this {FPUX86}\n */\n this.setEAFromSR = FPUX86.prototype.setEAFromSI;\n /**\n * setEAFromLR()\n *\n * Stores the (64-bit) \"long-real\" value in the internal regTmpLR register to the address in regEA.\n *\n * @this {FPUX86}\n */\n this.setEAFromLR = FPUX86.prototype.setEAFromLI;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {FPUX86}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cpu = cpu;\n this.chipset = cmp.getMachineComponent(\"ChipSet\");\n this.setReady();\n }\n\n /**\n * clearBusy()\n *\n * The ChipSet calls us whenever an I/O operation that clears the coprocessor's \"busy\" state is performed.\n *\n * @this {FPUX86}\n */\n clearBusy()\n {\n /*\n * We're never \"busy\" as far as other components are concerned, because we perform all FPU operations\n * synchronously, so there's nothing to do here.\n */\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {FPUX86}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data || !this.restore) {\n this.resetFPU();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {FPUX86}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * save()\n *\n * This implements save support for the FPUX86 component.\n *\n * @this {FPUX86}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n var a = [], i = 0;\n a[i++] = this.regControl;\n a[i++] = this.getStatus();\n a[i++] = this.getTags();\n /*\n * Note that, unlike the FSAVE() and FRSTOR() operations, we save the registers in regStack in their physical\n * order (0-7) rather than their logical order (ST0-ST7). Moreover, FSAVE() and FRSTOR() use the \"temp-real\" (TR)\n * format, whereas we use the current native format -- which, sadly, is only a 64-bit \"long-real\" (LR) format.\n */\n for (var iReg = 0; iReg < this.regStack.length; iReg++) {\n a[i++] = this.regStack[iReg];\n }\n state.set(0, a);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the FPUX86 component.\n *\n * @this {FPUX86}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var a = data[0], i = 0;\n this.setControl(a[i++]);\n this.setStatus(a[i++]);\n this.setTags(a[i++]);\n for (var iReg = 0; iReg < this.regStack.length; iReg++) {\n this.regStack[iReg] = a[i++];\n }\n return true;\n }\n\n /**\n * resetFPU()\n *\n * Aside from calling this internally (eg, during initialization and FINIT operations), the ChipSet may also call\n * us whenever an I/O operation that resets the coprocessor is performed. Only 80487 coprocessors and higher will\n * also clear the \"exception\" registers, but the 80487 is currently beyond my planned level of support.\n *\n * TODO: Add support for X86.FPU.CONTROL.PC (Precision Control) and X86.FPU.CONTROL.IC (Infinity Control)\n *\n * @this {FPUX86}\n */\n resetFPU()\n {\n this.regUsed = 0; // bits 0-7 are set as regs 0-7 are used\n this.regControl = X86.FPU.CONTROL.INIT;\n this.regStatus = 0; // contains all status register bits EXCEPT for ST\n this.iST = 0; // the ST bits for regStatus are actually stored here\n if (DEBUG) {\n /*\n * All the registers were tagged \"unused\" above, which is all that would normally happen, but debugging is\n * a little easier if we zero all the registers as well.\n */\n for (var iReg = 0; iReg < this.regStack.length; iReg++) {\n this.regStack[iReg] = 0.0;\n }\n }\n if (this.chipset) this.chipset.clearFPUInterrupt();\n }\n\n /**\n * isModel(model)\n *\n * If the current model is equal to the specified model, then it's assumed the current operation\n * is supported, and we return true.\n *\n * @this {FPUX86}\n * @param {number} model\n * @return {boolean}\n */\n isModel(model)\n {\n return this.model == model;\n }\n\n /**\n * isAtLeastModel(model)\n *\n * If the current model is greater than or equal to the specified model, then it's assumed that the\n * current operation is supported, and we return true.\n *\n * @this {FPUX86}\n * @param {number} model\n * @return {boolean}\n */\n isAtLeastModel(model)\n {\n return this.model >= model;\n }\n\n /**\n * opStop(fError)\n *\n * Place this inside any opcode handler to stop the CPU from running the current instruction; eg:\n *\n * if (this.opStop()) return;\n *\n * You can still use the Debugger to single-step over the instruction; opStop() will return false in that case.\n *\n * @this {FPUX86}\n * @param {boolean} [fError]\n * @return {boolean} (true if there was an error or the CPU was running, false if not)\n */\n opStop(fError)\n {\n if (DEBUG) {\n var cpu = this.cpu;\n if (fError || cpu.isRunning()) {\n cpu.setIP(cpu.opLIP - cpu.segCS.base);\n cpu.stopCPU();\n return true;\n }\n }\n return false;\n }\n\n /**\n * opNone()\n *\n * Used for any coprocessor opcode that has no known operation for the given model.\n *\n * @this {FPUX86}\n */\n opNone()\n {\n if (DEBUG) this.println(this.idComponent + \".opNone(\" + Str.toHexByte(this.cpu.bOpcode) + \",\" + Str.toHexByte(this.cpu.bModRM) + \")\");\n this.opStop(true);\n }\n\n /**\n * opObsolete()\n *\n * Used for any coprocessor opcodes that are redundant and potentially obsolete.\n *\n * @this {FPUX86}\n */\n opObsolete()\n {\n if (DEBUG) this.println(this.idComponent + \".opObsolete(\" + Str.toHexByte(this.cpu.bOpcode) + \",\" + Str.toHexByte(this.cpu.bModRM) + \")\");\n this.opStop(true);\n }\n\n /**\n * opUnimplemented()\n *\n * Used for any coprocessor opcode that DOES have a known operation, we just haven't implemented it yet.\n *\n * @this {FPUX86}\n */\n opUnimplemented()\n {\n if (DEBUG) this.println(this.idComponent + \".opUnimplemented(\" + Str.toHexByte(this.cpu.bOpcode) + \",\" + Str.toHexByte(this.cpu.bModRM) + \")\");\n this.opStop(true);\n }\n\n /**\n * checkException()\n *\n * @this {FPUX86}\n * @return {boolean} (true if unmasked exception exists, false if not)\n */\n checkException()\n {\n this.regStatus &= ~X86.FPU.STATUS.ES;\n /*\n * NOTE: The \"Stack Fault\" (SF) status bit wasn't introduced until the 80387, so it triggers the pre-existing\n * \"Invalid Operation\" (IE) exception; there is no corresponding \"Stack Fault\" (SE) exception, and the matching\n * control bit is still reserved. Consequently, X86.FPU.CONTROL.EXC is a *subset* of X86.FPU.STATUS.EXC (0x3F\n * instead of 0x7F).\n *\n * However, we shouldn't have to do anything special when SF is set, because any setException() call that sets\n * SF should ALSO set IE.\n */\n if (this.regStatus & (~this.regControl & X86.FPU.CONTROL.EXC)) {\n this.regStatus |= X86.FPU.STATUS.ES; // set ES whenever one or more unmasked EXC bits are set\n }\n if ((this.regStatus & X86.FPU.STATUS.ES) && !(this.regControl & X86.FPU.CONTROL.IEM)) {\n this.chipset.setFPUInterrupt();\n return true;\n }\n this.chipset.clearFPUInterrupt();\n return false;\n }\n\n /**\n * setException(n)\n *\n * Sets one or more of the FPU.STATUS.ECX bits; ie:\n *\n * IE (0x0001 bit 0: Invalid Operation)\n * DE (0x0002 bit 1: Denormalized Operand)\n * ZE (0x0004 bit 2: Zero Divide)\n * OE (0x0008 bit 3: Overflow)\n * UE (0x0010 bit 4: Underflow)\n * PE (0x0020 bit 5: Precision)\n * SF (0x0040 bit 6: Stack Fault; 80387 and later)\n *\n * Also, as noted in checkException(), any time you set the SF bit, you should also set the IE bit, because\n * Stack Fault is a subset of Invalid Operation. TODO: We should include a test for that in the assertion below.\n *\n * @this {FPUX86}\n * @param {number} n (one or more of the above error status bits)\n * @return {boolean} (true if unmasked exception exists, false if not)\n */\n setException(n)\n {\n if (DEBUG) this.println(this.idComponent + \".setException(\" + Str.toHexWord(n) + \")\");\n\n if (!this.isAtLeastModel(X86.FPU.MODEL_80387)) {\n n &= ~X86.FPU.STATUS.SF; // the SF bit didn't exist on pre-80387 coprocessors\n }\n\n this.regStatus |= n;\n return this.checkException();\n }\n\n /**\n * getControl()\n *\n * @this {FPUX86}\n * @return {number}\n */\n getControl()\n {\n return this.regControl;\n }\n\n /**\n * setControl(n)\n *\n * NOTE: Be sure to use this function for all \"wholesale\" regControl updates, because it ensures that\n * unused bits cannot be set -- including bit 6, which could otherwise inadvertently mask the SF error\n * condition on 80387 and newer coprocessors.\n *\n * @this {FPUX86}\n * @param {number} n\n */\n setControl(n)\n {\n this.regControl = n & ~X86.FPU.CONTROL.UNUSED;\n }\n\n /**\n * clearStatus(n)\n *\n * @this {FPUX86}\n * @param {number} n\n */\n clearStatus(n)\n {\n this.regStatus &= ~n;\n this.checkException();\n }\n\n /**\n * getStatus()\n *\n * @this {FPUX86}\n * @return {number} regStatus merged with iST\n */\n getStatus()\n {\n /*\n * As long as we never store any ST bits in regStatus, they should always be zero, so in\n * order to return the complete regStatus, all we need to do is shift and \"or\" the bits from iST.\n */\n return this.regStatus | (this.iST << X86.FPU.STATUS.ST_SHIFT);\n }\n\n /**\n * setStatus(n)\n *\n * NOTE: Be sure to use this function for all \"wholesale\" regStatus updates, because it ensures that\n * the ST bits get propagated to the internal iST register. Setting individual EXC bits should be done\n * through the fault() interface, and clearing individual EXC or BUSY bits should be done through\n * clearStatus(). Both functions, including this function, call checkException() after updating regStatus.\n *\n * @this {FPUX86}\n * @param {number} n\n */\n setStatus(n)\n {\n this.regStatus = n & ~X86.FPU.STATUS.ST;\n this.iST = (n & X86.FPU.STATUS.ST) >> X86.FPU.STATUS.ST_SHIFT;\n this.checkException();\n }\n\n /**\n * checkOperand(v)\n *\n * @this {FPUX86}\n * @param {number|null} v\n * @return {boolean} (true if no exception, false otherwise)\n */\n checkOperand(v)\n {\n return isNaN(v)? !this.setException(X86.FPU.STATUS.IE) : true;\n }\n\n /**\n * checkResult(v)\n *\n * @this {FPUX86}\n * @param {number} v\n * @return {boolean} (true if no exception, false otherwise)\n */\n checkResult(v)\n {\n return !isFinite(v)? !this.setException(v === Infinity? X86.FPU.STATUS.OE : X86.FPU.STATUS.UE) : true;\n }\n\n /**\n * doAdd(operand1, operand2)\n *\n * @this {FPUX86}\n * @param {number|null} operand1\n * @param {number|null} operand2\n * @return {number|null}\n */\n doAdd(operand1, operand2)\n {\n var result = null;\n if (operand1 != null && operand2 != null) {\n result = operand1 + operand2;\n if (!this.checkResult(result)) result = null;\n }\n return result;\n }\n\n /**\n * doSubtract(operand1, operand2)\n *\n * @this {FPUX86}\n * @param {number|null} operand1\n * @param {number|null} operand2\n * @return {number|null}\n */\n doSubtract(operand1, operand2)\n {\n var result = null;\n if (operand1 != null && operand2 != null) {\n result = operand1 - operand2;\n if (!this.checkResult(result)) result = null;\n }\n return result;\n }\n\n /**\n * doMultiply(operand1, operand2)\n *\n * @this {FPUX86}\n * @param {number|null} operand1\n * @param {number|null} operand2\n * @return {number|null}\n */\n doMultiply(operand1, operand2)\n {\n var result = null;\n if (operand1 != null && operand2 != null) {\n result = operand1 * operand2;\n if (!this.checkResult(result)) result = null;\n }\n return result;\n }\n\n /**\n * doDivide(dividend, divisor)\n *\n * TODO: IE exceptions: infinity / infinity, 0 / 0, 0 / pseudo-zero, or divisor is denormal or unnormal.\n *\n * @this {FPUX86}\n * @param {number|null} dividend\n * @param {number|null} divisor\n * @return {number|null}\n */\n doDivide(dividend, divisor)\n {\n var quotient = null;\n if (dividend != null && divisor != null) {\n if (divisor || !this.setException(X86.FPU.STATUS.DE)) {\n quotient = dividend / divisor;\n if (!this.checkResult(quotient)) quotient = null;\n }\n }\n return quotient;\n }\n\n /**\n * doCompare(operand1, operand2)\n *\n * @this {FPUX86}\n * @param {number|null} operand1\n * @param {number|null} operand2\n * @return {boolean}\n */\n doCompare(operand1, operand2)\n {\n if (operand1 != null && operand2 != null) {\n var cc = 0; // default value used when result > 0\n if (!isNaN(operand1) && !isNaN(operand2)) {\n var result = operand1 - operand2;\n if (result < 0) {\n cc = X86.FPU.STATUS.C0;\n } else if (result === 0) {\n cc = X86.FPU.STATUS.C3;\n }\n } else {\n cc = X86.FPU.STATUS.C0 | X86.FPU.STATUS.C2 | X86.FPU.STATUS.C3;\n }\n this.regStatus = (this.regStatus & ~X86.FPU.STATUS.CC) | cc;\n return true;\n }\n return false;\n }\n\n /**\n * doSquareRoot(operand)\n *\n * @this {FPUX86}\n * @param {number|null} operand\n * @return {number|null}\n */\n doSquareRoot(operand)\n {\n var result = null;\n /*\n * Happily, -0 is ALSO >= 0. Also happily, Math.sqrt(-0) returns -0.\n */\n if (operand >= 0 || !this.setException(X86.FPU.STATUS.IE)) {\n result = Math.sqrt(operand);\n if (!this.checkResult(result)) result = null;\n }\n return result;\n }\n\n /**\n * roundValue(operand, max)\n *\n * NOTE: The max parameter is EXCLUSIVE, not inclusive (ie, the maximum positive value is < max).\n *\n * Also, callers that expect intTmpLR[] to be loaded with the result *must* also specify a max parameter;\n * callers performing internal rounding and using just the return value may omit max to skip loading intTmpLR[].\n *\n * @this {FPUX86}\n * @param {number|null} operand\n * @param {number} [max] (ie, 0x8000, 0x80000000, or 0x8000000000000000)\n * @return {number|null} (rounded result, or null if there was an unmasked exception)\n */\n roundValue(operand, max)\n {\n if (operand == null) return null;\n\n var rc = (this.regControl & X86.FPU.CONTROL.RC.MASK), result;\n\n if (rc == X86.FPU.CONTROL.RC.NEAR) {\n result = Math.round(operand);\n if (result - operand === 0.5 && (result % 2)) result--;\n }\n else if (rc == X86.FPU.CONTROL.RC.DOWN || rc == X86.FPU.CONTROL.RC.CHOP && operand > 0) {\n result = Math.floor(operand);\n }\n else { // X86.FPU.CONTROL.RC.UP or X86.FPU.CONTROL.RC.CHOP && operand <= 0\n result = Math.ceil(operand);\n }\n\n if (max) {\n if (result >= max) {\n if (this.setException(X86.FPU.STATUS.IE)) return null;\n result = -max; // apparently, the masked response is to return the most negative integer (not max - 1)\n }\n else if (result < -max) {\n if (this.setException(X86.FPU.STATUS.IE)) return null;\n result = -max;\n }\n this.intTmpLR[0] = result|0;\n if (max > FPUX86.MAX_INT32) {\n this.intTmpLR[1] = (result / 0x100000000)|0;\n if (!this.intTmpLR[1] && result < 0) this.intTmpLR[1] = -1;\n }\n }\n return result;\n }\n\n /**\n * truncateValue(v)\n *\n * @this {FPUX86}\n * @param {number} v\n * @return {number}\n */\n truncateValue(v)\n {\n return v > 0? Math.floor(v) : Math.ceil(v);\n }\n\n /**\n * getTag(iReg)\n *\n * @this {FPUX86}\n * @param {number} iReg (register index)\n * @return {number} tag value for register\n */\n getTag(iReg)\n {\n var bitUsed = (1 << iReg);\n var tag = X86.FPU.TAGS.EMPTY;\n if (this.regUsed & bitUsed) {\n var f = this.regStack[iReg];\n tag = X86.FPU.TAGS.VALID;\n if (f === 0.0) {\n tag = X86.FPU.TAGS.ZERO;\n }\n else if (!isFinite(f)) {\n tag = X86.FPU.TAGS.SPECIAL;\n }\n }\n return tag;\n }\n\n /**\n * getTags()\n *\n * @this {FPUX86}\n * @return {number} tag values for all registers\n */\n getTags()\n {\n var tags = 0;\n for (var iReg = this.regStack.length - 1; iReg >= 0; iReg--) {\n tags <<= 2;\n tags |= this.getTag(iReg);\n }\n return tags;\n }\n\n /**\n * setTag(iReg, tag)\n *\n * @this {FPUX86}\n * @param {number} iReg (register index)\n * @param {number} tag value for register (EMPTY is the only supported value)\n */\n setTag(iReg, tag)\n {\n\n this.regUsed &= ~(1 << iReg);\n }\n\n /**\n * setTags(n)\n *\n * All we need to update here are which physical registers are marked \"empty\"; the rest of the tags\n * are generated on the fly based on actual values in the registers.\n *\n * @this {FPUX86}\n * @param {number} n (16-bit tag word, containing 8 2-bit tags)\n */\n setTags(n)\n {\n this.regUsed = 0;\n for (var bitUsed = 0x1; bitUsed <= 0x80; bitUsed <<= 1) {\n var tag = n & X86.FPU.TAGS.MASK;\n if (tag != X86.FPU.TAGS.EMPTY) {\n this.regUsed |= bitUsed;\n }\n n >>= 2;\n }\n }\n\n /**\n * getWI(i)\n *\n * Gets a \"word-integer\" (WI aka INT16) from ST(i)\n *\n * @this {FPUX86}\n * @param {number} i (eg, 0 for top-of-stack)\n * @return {boolean} true if intTmpLR was loaded, false if not\n */\n getWI(i)\n {\n return this.roundValue(this.getST(i), FPUX86.MAX_INT16) != null;\n }\n\n /**\n * getSI(i)\n *\n * Gets a \"short-integer\" (SI aka INT32) from ST(i)\n *\n * @this {FPUX86}\n * @param {number} i (eg, 0 for top-of-stack)\n * @return {boolean} true if intTmpLR was loaded, false if not\n */\n getSI(i)\n {\n return this.roundValue(this.getST(i), FPUX86.MAX_INT32) != null;\n }\n\n /**\n * getLI(i)\n *\n * Gets a \"long-integer\" (LI aka INT64) from ST(i)\n *\n * @this {FPUX86}\n * @param {number} i (eg, 0 for top-of-stack)\n * @return {boolean} true if intTmpLR was loaded, false if not\n */\n getLI(i)\n {\n return this.roundValue(this.getST(i), FPUX86.MAX_INT64) != null;\n }\n\n /**\n * getSR(i)\n *\n * @this {FPUX86}\n * @param {number} i (eg, 0 for top-of-stack)\n * @return {boolean} true if regTmpSR was loaded, false if not\n */\n getSR(i)\n {\n var iReg = (this.iST + i) & 7;\n if (this.regUsed & (1 << iReg)) {\n this.regTmpSR[0] = this.regStack[iReg];\n return true;\n } else if (!this.setException(X86.FPU.STATUS.IE)) {\n this.regTmpSR[0] = this.regIndefinite[0];\n return true;\n }\n return false;\n }\n\n /**\n * getLR(i)\n *\n * @this {FPUX86}\n * @param {number} i (eg, 0 for top-of-stack)\n * @return {boolean} true if regTmpLR was loaded, false if not\n */\n getLR(i)\n {\n var iReg = (this.iST + i) & 7;\n if (this.regUsed & (1 << iReg)) {\n this.regTmpLR[0] = this.regStack[iReg];\n return true;\n } else if (!this.setException(X86.FPU.STATUS.IE)) {\n this.regTmpLR[0] = this.regIndefinite[0];\n return true;\n }\n return false;\n }\n\n /**\n * getST(i)\n *\n * @this {FPUX86}\n * @param {number} i (eg, 0 for top-of-stack)\n * @return {number|null} v\n */\n getST(i)\n {\n var v = null;\n var iReg = (this.iST + i) & 7;\n if (this.regUsed & (1 << iReg)) {\n v = this.regStack[iReg];\n } else if (!this.setException(X86.FPU.STATUS.IE)) {\n v = this.regIndefinite[0];\n }\n return v;\n }\n\n /**\n * getSTSign(i)\n *\n * Returns zero if sign bit clear, and non-zero (negative) if sign bit set. This is safer\n * than comparing getST() to zero, because JavaScript comparisons involving NaNs are meaningless.\n *\n * For internal use only; ignores whether the register is empty, and performs no exception checks.\n *\n * @this {FPUX86}\n * @param {number} i (eg, 0 for top-of-stack)\n * @return {number}\n */\n getSTSign(i)\n {\n var iInt = ((this.iST + i) & 7) << 1;\n return this.intStack[iInt + 1] & (0x80000000|0);\n }\n\n /**\n * setST(i, v)\n *\n * @this {FPUX86}\n * @param {number} i (eg, 0 for top-of-stack)\n * @param {number|null} v\n * @return {boolean}\n */\n setST(i, v)\n {\n if (v != null && this.checkOperand(v)) {\n var iReg = (this.iST + i) & 7;\n this.regStack[iReg] = v;\n this.regUsed |= (1 << iReg);\n return true;\n }\n return false;\n }\n\n /**\n * getTR(i, fSafe)\n *\n * @this {FPUX86}\n * @param {number} i (stack index, 0-7)\n * @param {boolean} [fSafe] (true to ignore all exception criteria; used by FSAVE)\n * @return {Array.<number>|null} (\"temp-real\" aka TR, as an array of three 32-bit integers)\n */\n getTR(i, fSafe)\n {\n var a = null;\n var iReg = (this.iST + i) & 7;\n if (fSafe || this.regUsed & (1 << iReg) || !this.setException(X86.FPU.STATUS.IE)) {\n var iInt = iReg << 1;\n a = this.getTRFromLR(this.intStack[iInt], this.intStack[iInt + 1]);\n }\n return a;\n }\n\n /**\n * setTR(i, a)\n *\n * Sets ST(i) to the TR (\"long-real\") in a[].\n *\n * @this {FPUX86}\n * @param {number} i (stack index, 0-7)\n * @param {Array.<number>|null} a\n */\n setTR(i, a)\n {\n if (a) this.setST(i, this.getLRFromTR(a));\n }\n\n /**\n * getWIFromEA()\n *\n * Returns the (16-bit) \"word-integer\" value located at regEA.\n *\n * @this {FPUX86}\n * @return {number} v\n */\n getWIFromEA()\n {\n\n return (this.cpu.getShort(this.cpu.regEA) << 16) >> 16;\n }\n\n /**\n * getSIFromEA()\n *\n * Returns the (32-bit) \"short-integer\" value located at regEA.\n *\n * @this {FPUX86}\n * @return {number} v\n */\n getSIFromEA()\n {\n\n return this.cpu.getLong(this.cpu.regEA);\n }\n\n /**\n * getLIFromEA()\n *\n * Returns the (64-bit) \"long-integer\" value located at regEA.\n *\n * @this {FPUX86}\n * @return {number} v\n */\n getLIFromEA()\n {\n\n var lo = this.cpu.getLong(this.cpu.regEA);\n var hi = this.cpu.getLong(this.cpu.regEA + 4);\n return (hi * 0x100000000) + (lo >>> 0);\n }\n\n /**\n * getSRFromEA()\n *\n * Sets the internal regTmpSR register to the (32-bit) \"short-real\" value located at regEA.\n *\n * @this {FPUX86}\n * @return {number} v\n */\n getSRFromEA()\n {\n\n this.intTmpSR[0] = this.cpu.getLong(this.cpu.regEA);\n return this.regTmpSR[0];\n }\n\n /**\n * getLRFromEA()\n *\n * Sets the internal regTmpLR register to the (64-bit) \"long-real\" value located at regEA.\n *\n * @this {FPUX86}\n * @return {number} v\n */\n getLRFromEA()\n {\n\n this.intTmpLR[0] = this.cpu.getLong(this.cpu.regEA);\n this.intTmpLR[1] = this.cpu.getLong(this.cpu.regEA + 4);\n return this.regTmpLR[0];\n }\n\n /**\n * getTRFromEA()\n *\n * Sets the internal intTmpTR register to the (80-bit) \"temp-real\" value located at regEA.\n *\n * @this {FPUX86}\n * @return {Array.<number>} intTmpTR\n */\n getTRFromEA()\n {\n\n this.intTmpTR[0] = this.cpu.getLong(this.cpu.regEA);\n this.intTmpTR[1] = this.cpu.getLong(this.cpu.regEA + 4);\n this.intTmpTR[2] = this.cpu.getShort(this.cpu.regEA + 8);\n return this.intTmpTR;\n }\n\n /**\n * setEAFromWI()\n *\n * Stores the (16-bit) \"word-integer\" value in the internal intTmpLR register to the address in regEA.\n *\n * @this {FPUX86}\n */\n setEAFromWI()\n {\n\n this.cpu.setShort(this.cpu.regEA, this.intTmpLR[0]);\n }\n\n /**\n * setEAFromSI()\n *\n * Stores the (32-bit) \"short-integer\" value in the internal intTmpLR register to the address in regEA.\n *\n * @this {FPUX86}\n */\n setEAFromSI()\n {\n\n this.cpu.setLong(this.cpu.regEA, this.intTmpLR[0]);\n }\n\n /**\n * setEAFromLI()\n *\n * Stores the (64-bit) \"long-integer\" value in the internal intTmpLR register to the address in regEA.\n *\n * @this {FPUX86}\n */\n setEAFromLI()\n {\n\n this.cpu.setLong(this.cpu.regEA, this.intTmpLR[0]);\n this.cpu.setLong(this.cpu.regEA + 4, this.intTmpLR[1]);\n }\n\n /**\n * setEAFromTR()\n *\n * Stores the (80-bit) \"temp-real\" value in the internal intTmpTR register to the address in regEA.\n *\n * @this {FPUX86}\n */\n setEAFromTR()\n {\n\n this.cpu.setLong(this.cpu.regEA, this.intTmpTR[0]);\n this.cpu.setLong(this.cpu.regEA + 4, this.intTmpTR[1]);\n this.cpu.setShort(this.cpu.regEA + 8, this.intTmpTR[2]);\n }\n\n /**\n * getLRFromTR(a)\n *\n * Since we must use the \"long-real\" (64-bit) format internally, rather than the \"temp-real\" (80-bit) format,\n * this function converts a 64-bit value to an 80-bit value. The major differences: 1) the former uses a 52-bit\n * fraction and 11-bit exponent, while the latter uses a 64-bit fraction and 15-bit exponent; 2) the former\n * does NOT store a leading 1 with the fraction, whereas the latter does.\n *\n * @this {FPUX86}\n * @param {Array.<number>} a (eg, intTmpTR)\n * @return {number} v\n */\n getLRFromTR(a)\n {\n var loTR = a[0], hiTR = a[1];\n var signLR = (a[2] & 0x8000) >> 4, expLR = a[2] & 0x7fff;\n /*\n * We have no choice but to chop off the bottom 11 TR bits in order to fit in an LR....\n */\n var loLR = (loTR >>> 11) | (hiTR << 21), hiLR = (hiTR >> 11) & 0xfffff;\n\n if (expLR == 0x7fff) {\n /*\n * Convert an TR NaN to a LR NaN.\n */\n expLR = 0x7ff;\n }\n else if (expLR) {\n /*\n * We have a normal (biased) TR exponent which we must now convert to a (biased) LR exponent;\n * subtract the TR bias (0x3fff) and add the LR bias (0x3ff); additionally, we have a problem\n * that getTRFromLR() did not: if the TR exponent is too large to fit in an LR exponent, then we\n * have convert the result to +/- infinity.\n */\n expLR += 0x3ff - 0x3fff;\n if (expLR <= 0) {\n expLR = 0x7ff;\n loLR = hiLR = 0;\n }\n }\n\n this.intTmpLR[0] = loLR;\n this.intTmpLR[1] = hiLR | ((signLR | expLR) << 20);\n return this.regTmpLR[0];\n }\n\n /**\n * getTRFromLR(loLR, hiLR)\n *\n * Since we must use the \"long-real\" (64-bit) format internally, rather than the \"temp-real\" (80-bit) format,\n * this function converts a 64-bit value to an 80-bit value. The major differences: 1) the former uses a 52-bit\n * fraction and 11-bit exponent, while the latter uses a 64-bit fraction and 15-bit exponent; 2) the former\n * does NOT store a leading 1 with the fraction, whereas the latter does.\n *\n * @this {FPUX86}\n * @param {number} loLR\n * @param {number} hiLR\n * @return {Array.<number>} (intTmpTR)\n */\n getTRFromLR(loLR, hiLR)\n {\n var expTR = (hiLR >> 20) & 0x07ff;\n var signTR = (hiLR >> 16) & 0x8000;\n var loTR = loLR << 11, hiTR = 0x80000000 | ((hiLR & 0x000fffff) << 11) | (loLR >>> 21);\n\n if (expTR == 0x07ff) {\n /*\n * Convert an LR NaN to a TR NaN. NaNs encompass +/- infinity, which in the LR\n * world are fractions of all zeros. NaNs also encompass indefinite, which in the LR\n * world are negative numbers with only the high fraction bit set. So, in both cases,\n * our default TR value (ie, with zeros shifted into the bottom 11 bits) should be fine;\n * we simply need to change the exponent to the maximum TR value.\n */\n expTR = 0x7fff;\n }\n else if (!expTR) {\n /*\n * An LR with an exponent of zero could be an actual +/- zero, if the fraction is zero,\n * or it could be a denormal, if the fraction is non-zero. In both cases, the only\n * change we need to make the TR form is clearing the leading 1 bit.\n */\n hiTR &= 0x7fffffff;\n }\n else {\n /*\n * We have a normal (biased) LR exponent which we must now convert to a (biased) TR exponent;\n * subtract the LR bias (0x3ff) and add the TR bias (0x3fff).\n */\n expTR += 0x3fff - 0x3ff;\n }\n\n this.intTmpTR[0] = loTR;\n this.intTmpTR[1] = hiTR;\n this.intTmpTR[2] = signTR | expTR;\n return this.intTmpTR;\n }\n\n /**\n * decodeBCD()\n *\n * @this {FPUX86}\n * @param {number} i (32-bit integer containing n BCD digits)\n * @param {number} n (number of BCD digits to decode)\n * @return {number} (binary value representing the specified number of BCD digits)\n */\n decodeBCD(i, n)\n {\n var v = 0, m = 1;\n\n while (n--) {\n var d = i & 0xf;\n\n v += d * m;\n m *= 10;\n i >>= 4;\n }\n return v;\n }\n\n /**\n * encodeBCD()\n *\n * @this {FPUX86}\n * @param {number} v (binary value from which to extract n BCD digits)\n * @param {number} n (number of BCD digits to extract)\n * @return {number} (integer containing the requested number of BCD digits)\n */\n encodeBCD(v, n)\n {\n var i = 0, s = 0;\n\n while (n--) {\n i |= (v % 10) << s;\n v /= 10;\n s += 4;\n }\n return i;\n }\n\n /**\n * popValue()\n *\n * @this {FPUX86}\n * @return {number|null} v\n */\n popValue()\n {\n var v = null;\n var bitUsed = (1 << this.iST);\n if (!(this.regUsed & bitUsed)) {\n this.regStatus &= ~X86.FPU.STATUS.C1; // clear C1 to indicate stack underflow (80287XL and up)\n if (this.setException(X86.FPU.STATUS.SF | X86.FPU.STATUS.IE)) return v;\n }\n this.regUsed &= ~bitUsed;\n v = this.regStack[this.iST];\n this.iST = (this.iST + 1) & 7;\n return v;\n }\n\n /**\n * pushValue(v)\n *\n * @this {FPUX86}\n * @param {number|null} v\n */\n pushValue(v)\n {\n if (v == null) return;\n var iReg = (this.iST - 1) & 7;\n var bitUsed = (1 << iReg);\n if (this.regUsed & bitUsed) {\n this.regStatus |= X86.FPU.STATUS.C1; // set C1 to indicate stack overflow (80287XL and up)\n if (this.setException(X86.FPU.STATUS.SF | X86.FPU.STATUS.IE)) return;\n }\n if (!this.checkOperand(v)) {\n if (this.setException(X86.FPU.STATUS.IE)) return;\n v = NaN;\n }\n this.regStack[this.iST = iReg] = v;\n this.regUsed |= bitUsed;\n }\n\n /**\n * loadEnv(addr)\n *\n * @this {FPUX86}\n * @param {number} addr\n * @return {number} updated addr\n */\n loadEnv(addr)\n {\n var w;\n var cpu = this.cpu;\n\n this.setControl(cpu.getWord(addr));\n this.setStatus(cpu.getWord(addr += cpu.sizeData));\n this.setTags(cpu.getWord(addr += cpu.sizeData));\n\n if (!(cpu.regCR0 & X86.CR0.MSW.PE) || (cpu.regPS & X86.PS.VM)) {\n this.regCodeOff = cpu.getWord(addr += cpu.sizeData);\n w = cpu.getWord(addr += cpu.sizeData);\n this.regOpcode = w & 0x7ff;\n this.regCodeOff |= (w & ~0xfff) << 4;\n this.regCodeSel = -1;\n this.regDataOff = cpu.getWord(addr += cpu.sizeData);\n this.regDataOff |= (cpu.getWord(addr += cpu.sizeData) & ~0xfff) << 4;\n this.regDataSel = -1;\n } else {\n this.regCodeOff = cpu.getWord(addr += cpu.sizeData);\n w = cpu.getWord(addr += cpu.sizeData);\n this.regCodeSel = w & 0xffff;\n this.regOpcode = (w >> 16) & 0x7ff;\n this.regDataOff = cpu.getWord(addr += cpu.sizeData);\n this.regDataSel = cpu.getWord(addr += cpu.sizeData) & 0xffff;\n }\n return addr + cpu.sizeData;\n }\n\n /**\n * saveEnv(addr)\n *\n * @this {FPUX86}\n * @param {number} addr\n * @return {number} updated addr\n */\n saveEnv(addr)\n {\n var cpu = this.cpu;\n\n cpu.setWord(addr, this.regControl);\n cpu.setWord(addr += cpu.sizeData, this.getStatus());\n cpu.setWord(addr += cpu.sizeData, this.getTags());\n\n if (!(cpu.regCR0 & X86.CR0.MSW.PE) || (cpu.regPS & X86.PS.VM)) {\n var off = (this.regCodeSel << 4) + this.regCodeOff;\n cpu.setWord(addr += cpu.sizeData, off);\n cpu.setWord(addr += cpu.sizeData, ((off >> 4) & ~0xfff) | this.regOpcode);\n off = (this.regDataSel << 4) + this.regDataOff;\n cpu.setWord(addr += cpu.sizeData, off);\n cpu.setWord(addr += cpu.sizeData, ((off >> 4) & ~0xfff));\n } else {\n cpu.setWord(addr += cpu.sizeData, this.regCodeOff);\n cpu.setWord(addr += cpu.sizeData, this.regCodeSel | (this.regOpcode << 16));\n cpu.setWord(addr += cpu.sizeData, this.regDataOff);\n cpu.setWord(addr += cpu.sizeData, this.regDataSel);\n }\n return addr + cpu.sizeData;\n }\n\n /**\n * opFPU(bOpcode, bModRM, dst, src)\n *\n * This is called by the CPU's ESC opcode handlers, after each instruction has been fully decoded.\n *\n * @this {FPUX86}\n * @param {number} bOpcode (0xD8-0xDF)\n * @param {number} bModRM\n * @param {number} dst\n * @param {number} src\n */\n opFPU(bOpcode, bModRM, dst, src)\n {\n var mod = (bModRM >> 6) & 3;\n var reg = (bModRM >> 3) & 7;\n this.iStack = (bModRM & 7);\n\n /*\n * Combine mod and reg into one decodable value: put mod in the high nibble\n * and reg in the low nibble, after first collapsing all mod values < 3 to zero.\n */\n var modReg = (mod < 3? 0 : 0x30) + reg;\n\n /*\n * All values >= 0x34 imply mod == 3 and reg >= 4, so now we shift reg into the high\n * nibble and iStack into the low, yielding values >= 0x40.\n */\n if ((bOpcode == X86.OPCODE.ESC1 || bOpcode == X86.OPCODE.ESC3) && modReg >= 0x34) {\n modReg = (reg << 4) | this.iStack;\n }\n\n var fnOp = FPUX86.aaOps[bOpcode][modReg];\n if (fnOp) {\n /*\n * A handful of FPU instructions must preserve (at least some of) the \"exception\" registers,\n * so if the current function is NOT one of those, then update all the \"exception\" registers.\n */\n if (FPUX86.afnPreserveExceptions.indexOf(fnOp) < 0) {\n var cpu = this.cpu;\n var off = cpu.opLIP;\n /*\n * WARNING: opLIP points to any prefixes preceding the ESC instruction, but the 8087 always\n * points to the ESC instruction. Technically, that's a bug, but it's also a reality, so we\n * check for preceding prefixes and bump the instruction pointer accordingly. This isn't a\n * perfect solution, because it doesn't account for multiple (redundant) prefixes, but it\n * should be adequate.\n */\n if (this.isModel(X86.FPU.MODEL_8087)) {\n if (cpu.opPrefixes & X86.OPFLAG.SEG) off++;\n if (cpu.opPrefixes & X86.OPFLAG.LOCK) off++;\n }\n this.regCodeSel = cpu.segCS.sel;\n this.regCodeOff = off - cpu.segCS.base;\n if (cpu.regEA !== X86.ADDR_INVALID) {\n this.regDataSel = cpu.segEA.sel;\n this.regDataOff = cpu.regEA - cpu.segEA.base;\n }\n this.regOpcode = ((bOpcode & 7) << 8) | bModRM;\n }\n /*\n * Finally, perform the FPU operation.\n */\n fnOp.call(this);\n }\n else {\n /*\n * This is a gray area, at least until aaOps has been filled in for all supported coprocessors;\n * but for now, we'll treat all unrecognized operations as \"no operation\", as opposed to unimplemented.\n */\n this.opNone();\n }\n }\n\n /**\n * opWAIT()\n *\n * This is called by the CPU's WAIT opcode handler, giving us the opportunity to synchronize the FPU with the CPU,\n * charge an appropriate number of cycles, and return true. In this context, it's considered an FWAIT instruction,\n * but technically, it's the same opcode.\n *\n * If we choose to do nothing, then we must return false, so that the CPU can charge a default number of cycles.\n *\n * @this {FPUX86}\n * @return {boolean} true if implemented, false if not\n */\n opWAIT()\n {\n return false;\n }\n\n /**\n * readFPUStack(i)\n *\n * Returns the following information for the requested FPU stack element, relative to ST:\n *\n * a[0]: physical stack position (0-7)\n * a[1]: corresponding tag value\n * a[2]: 64-bit \"long-real\" (LR) value\n * a[3]: bits 0-31 of 64-bit \"long-real\" (LR)\n * a[4]: bits 32-63 of 64-bit \"long-real\" (LR)\n * a[5]: bits 0-31 of 80-bit \"temp-real\" (TR)\n * a[6]: bits 32-63 of 80-bit \"temp-real\" (TR)\n * a[7]: bits 64-79 of 80-bit \"temp-real\" (TR) (in bits 0-15)\n *\n * Used by the Debugger for its floating-point register (\"rfp\") command. For other FPU registers,\n * the Debugger calls getStatus() and getControl() directly.\n *\n * NOTE: The \"temp-real\" values are fake; we manufacture them on demand from 64-bit \"long-real\" values\n * actually stored in the stack; see getTRFromLR().\n *\n * @this {FPUX86}\n * @param {number} i (stack index, relative to ST)\n * @return {Array.<number>|null} (an array of information as described above, or null if invalid element)\n */\n readFPUStack(i)\n {\n var a = null;\n if (i < this.regStack.length) {\n a = [];\n var iReg = (this.iST + i) & 7;\n a[0] = iReg;\n a[1] = this.getTag(iReg);\n a[2] = this.regStack[iReg];\n var iInt = iReg << 1;\n a[3] = this.intStack[iInt];\n a[4] = this.intStack[iInt + 1];\n var aTR = this.getTRFromLR(a[3], a[4]);\n a[5] = aTR[0]; a[6] = aTR[1]; a[7] = aTR[2];\n }\n return a;\n }\n\n /**\n * getRandomInt(min, max)\n *\n * Used with old test code to verify that any randomly-constructed \"long-real\" (REAL64) could be converted\n * to a \"temp-real\" (REAL80) and back again losslessly, otherwise a bug in either getTRFromLR() or getLRFromTR()\n * might exist. That test code can be resurrected from the repo; this code is being retained for future tests.\n *\n * NOTE: If either min or max is a value containing 32 or more significant bits AND bit 31 is set AND it has passed\n * through some bitwise operation(s), then that value may end up being negative, so you may end up with an inverted\n * range, or a range that's smaller or larger than intended.\n *\n * @this {FPUX86}\n * @param {number} min (inclusive)\n * @param {number} max (inclusive)\n * @return {number}\n *\n getRandomInt(min, max)\n {\n max -= min;\n if (max < 0) { // compensate for inverted ranges (ie, where min > max)\n min += max;\n max = -max;\n }\n return Math.floor(Math.random() * (max + 1)) + min;\n }\n */\n\n /**\n * F2XM1()\n *\n * F2XM1 (2 to the x minus 1) calculates the function 2^x - 1 and returns the result to ST(0).\n *\n * On the 8087 and 80287, the value in ST(0) must satisfy the inequality 0 <= ST(0) <= 0.5. On the 80287XL and\n * later coprocessors, the permissible range is greater, and ST(0) must satisfy the inequality -1 <= ST(0) <= 1.\n * If ST(0) is out of range, the result is undefined, even though no exception is raised.\n *\n * The F2XM1 instruction is designed to provide an accurate result even when x is close to zero. To obtain 2^x,\n * simply add 1.0 to the result returned by F2XM1.\n *\n * This instruction is useful in performing exponentiation of values other than 2 as shown in the following formulas:\n *\n * 10^x = 2^(x * log2(10))\n * e^x = 2^(x * log2(e))\n * y^x = 2^(x * log2(y))\n *\n * Note that the NPX has dedicated instructions for loading the constants log2(10) and log2(e). The FYL2X instruction\n * may be used to calculate x * log2(y).\n *\n * See also: FYL2X, FLDL2T, FLDL2E.\n *\n * @this {FPUX86}\n */\n static F2XM1()\n {\n this.setST(0, Math.pow(2, this.getST(0)) - 1);\n }\n\n /**\n * FABS()\n *\n * @this {FPUX86}\n */\n static FABS()\n {\n /*\n * TODO: This could be implemented more efficiently by simply clearing the sign bit of ST(0).\n */\n this.setST(0, Math.abs(this.getST(0)));\n }\n\n /**\n * FADDlr()\n *\n * @this {FPUX86}\n */\n static FADDlr()\n {\n this.setST(0, this.doAdd(this.getST(0), this.getLRFromEA()));\n }\n\n /**\n * FADDsr()\n *\n * Encoding 0xD8,reg=0x00 (\"FADD short-real\"): ST(0) <- ST(0) + REAL32\n *\n * @this {FPUX86}\n */\n static FADDsr()\n {\n this.setST(0, this.doAdd(this.getST(0), this.getSRFromEA()));\n }\n\n /**\n * FADDst()\n *\n * @this {FPUX86}\n */\n static FADDst()\n {\n this.setST(0, this.doAdd(this.getST(0), this.getST(this.iStack)));\n }\n\n /**\n * FADDsti()\n *\n * @this {FPUX86}\n */\n static FADDsti()\n {\n this.setST(this.iStack, this.doAdd(this.getST(this.iStack), this.getST(0)));\n }\n\n /**\n * FADDPsti()\n *\n * @this {FPUX86}\n */\n static FADDPsti()\n {\n if (this.setST(this.iStack, this.doAdd(this.getST(this.iStack), this.getST(0)))) this.popValue();\n }\n\n /**\n * FBLDpd()\n *\n * @this {FPUX86}\n */\n static FBLDpd()\n {\n var a = this.getTRFromEA();\n /*\n * a[0] contains the 8 least-significant BCD digits, a[1] contains the next 8, and a[2] contains\n * the next 2 (bit 15 of a[2] is the sign bit, and bits 8-14 of a[2] are unused).\n */\n var v = this.decodeBCD(a[0], 8) + this.decodeBCD(a[1], 8) * 100000000 + this.decodeBCD(a[2], 2) * 10000000000000000;\n if (a[2] & 0x8000) v = -v;\n this.pushValue(v);\n }\n\n /**\n * FBSTPpd()\n *\n * @this {FPUX86}\n */\n static FBSTPpd()\n {\n /*\n * TODO: Verify the operation of FBSTP (eg, does it signal an exception if abs(value) >= 1000000000000000000?)\n */\n var v = this.roundValue(this.popValue());\n if (v != null) {\n /*\n * intTmpTR[0] will contain the 8 least-significant BCD digits, intTmpTR[1] will contain the next 8,\n * and intTmpTR[2] will contain the next 2 (bit 15 of intTmpTR[2] will be the sign bit, and bits 8-14 of\n * intTmpTR[2] will be unused).\n */\n this.intTmpTR[0] = this.encodeBCD(v, 8);\n this.intTmpTR[1] = this.encodeBCD(v / 100000000, 8);\n this.intTmpTR[2] = this.encodeBCD(v / 10000000000000000, 2);\n if (v < 0) this.intTmpTR[2] |= 0x8000;\n this.setEAFromTR();\n }\n }\n\n /**\n * FCHS()\n *\n * @this {FPUX86}\n */\n static FCHS()\n {\n /*\n * TODO: This could be implemented more efficiently by simply inverting the sign bit of ST(0).\n */\n this.setST(0, -this.getST(0));\n }\n\n /**\n * FCLEX()\n *\n * NOTE: Although we explicitly clear the BUSY bit, there shouldn't be any code setting it, because\n * we're never \"busy\" (all floating-point operations are performed synchronously). Conversely, there's\n * no need to explicitly clear the ES bit, because clearStatus() will call checkException(), which\n * updates ES and clears/sets FPU interrupt status as appropriate.\n *\n * @this {FPUX86}\n */\n static FCLEX()\n {\n this.clearStatus(X86.FPU.STATUS.EXC | X86.FPU.STATUS.BUSY);\n }\n\n /**\n * FCOMlr()\n *\n * Encoding 0xDC,mod<3,reg=2 (\"FCOM long-real\"): Evaluate ST(0) - REAL64\n *\n * @this {FPUX86}\n */\n static FCOMlr()\n {\n this.doCompare(this.getST(0), this.getLRFromEA());\n }\n\n /**\n * FCOMsr()\n *\n * Encoding 0xD8,mod<3,reg=2 (\"FCOM short-real\"): Evaluate ST(0) - REAL32\n *\n * @this {FPUX86}\n */\n static FCOMsr()\n {\n this.doCompare(this.getST(0), this.getSRFromEA());\n }\n\n /**\n * FCOMst()\n *\n * Encoding 0xD8,mod=3,reg=2 (\"FCOM ST(i)\"): Evaluate ST(0) - ST(i)\n *\n * @this {FPUX86}\n */\n static FCOMst()\n {\n this.doCompare(this.getST(0), this.getST(this.iStack));\n }\n\n /**\n * FCOM8087()\n *\n * NOTE: This is used with encoding(s) (0xDC,0xD0-0xD7) that were valid for the 8087 and 80287\n * but may no longer be valid as of the 80387.\n *\n * TODO: Determine if this form subtracted the operands in the same order, or if it requires an FCOMsti(),\n * which, like the other *sti() functions, uses ST(0) as the second operand rather than the first.\n *\n * @this {FPUX86}\n */\n static FCOM8087()\n {\n this.opObsolete();\n FPUX86.FCOMst.call(this);\n }\n\n /**\n * FCOMPlr()\n *\n * Encoding 0xDC,mod<3,reg=3 (\"FCOM long-real\"): Evaluate ST(0) - REAL64, POP\n *\n * @this {FPUX86}\n */\n static FCOMPlr()\n {\n if (this.doCompare(this.getST(0), this.getLRFromEA())) this.popValue();\n }\n\n /**\n * FCOMPsr()\n *\n * Encoding 0xD8,mod<3,reg=3 (\"FCOM short-real\"): Evaluate ST(0) - REAL32, POP\n *\n * @this {FPUX86}\n */\n static FCOMPsr()\n {\n if (this.doCompare(this.getST(0), this.getSRFromEA())) this.popValue();\n }\n\n /**\n * FCOMPst()\n *\n * Encoding 0xD8,mod=3,reg=3 (\"FCOMP ST(i)\"): Evaluate ST(0) - ST(i), POP\n *\n * @this {FPUX86}\n */\n static FCOMPst()\n {\n if (this.doCompare(this.getST(0), this.getST(this.iStack))) this.popValue();\n }\n\n /**\n * FCOMP8087()\n *\n * NOTE: This is used with encodings (0xDC,0xD8-0xDF and 0xDE,0xD0-0xD7) that were valid for the 8087\n * and 80287 but may no longer be valid as of the 80387.\n *\n * TODO: Determine if this form subtracted the operands in the same order, or if it requires an FCOMPsti(),\n * which, like the other *sti() functions, uses ST(0) as the second operand rather than the first.\n *\n * @this {FPUX86}\n */\n static FCOMP8087()\n {\n this.opObsolete();\n FPUX86.FCOMPst.call(this);\n }\n\n /**\n * FCOMPP()\n *\n * @this {FPUX86}\n */\n static FCOMPP()\n {\n if (this.doCompare(this.getST(0), this.getST(1)) && this.popValue() != null) this.popValue();\n }\n\n /**\n * FDECSTP()\n *\n * @this {FPUX86}\n */\n static FDECSTP()\n {\n this.iST = (this.iST - 1) & 0x7;\n this.regStatus &= ~X86.FPU.STATUS.C1;\n }\n\n /**\n * FDISI8087()\n *\n * @this {FPUX86}\n */\n static FDISI8087()\n {\n if (this.isModel(X86.FPU.MODEL_8087)) {\n this.regControl |= X86.FPU.CONTROL.IEM;\n }\n }\n\n /**\n * FDIVlr()\n *\n * @this {FPUX86}\n */\n static FDIVlr()\n {\n this.setST(0, this.doDivide(this.getST(0), this.getLRFromEA()));\n }\n\n /**\n * FDIVsr()\n *\n * @this {FPUX86}\n */\n static FDIVsr()\n {\n this.setST(0, this.doDivide(this.getST(0), this.getSRFromEA()));\n }\n\n /**\n * FDIVst()\n *\n * Encoding 0xD8,0xF0-0xF7 (\"FDIV ST,ST(i)\"): ST(0) <- ST(0) / ST(i)\n *\n * @this {FPUX86}\n */\n static FDIVst()\n {\n this.setST(0, this.doDivide(this.getST(0), this.getST(this.iStack)));\n }\n\n /**\n * FDIVsti()\n *\n * Encoding 0xDC,0xF8-0xFF (\"FDIV ST(i),ST\"): ST(i) <- ST(i) / ST(0)\n *\n * @this {FPUX86}\n */\n static FDIVsti()\n {\n this.setST(this.iStack, this.doDivide(this.getST(this.iStack), this.getST(0)));\n }\n\n /**\n * FDIVPsti()\n *\n * Encoding 0xDE,0xF8-0xFF (\"FDIVP ST(i),ST\"): ST(i) <- ST(i) / ST(0), POP\n *\n * @this {FPUX86}\n */\n static FDIVPsti()\n {\n if (this.setST(this.iStack, this.doDivide(this.getST(this.iStack), this.getST(0)))) this.popValue();\n }\n\n /**\n * FDIVRlr()\n *\n * @this {FPUX86}\n */\n static FDIVRlr()\n {\n this.setST(0, this.doDivide(this.getLRFromEA(), this.getST(0)));\n }\n\n /**\n * FDIVRsr()\n *\n * @this {FPUX86}\n */\n static FDIVRsr()\n {\n this.setST(0, this.doDivide(this.getSRFromEA(), this.getST(0)));\n }\n\n /**\n * FDIVRst()\n *\n * Encoding 0xD8,0xF8-0xFF (\"FDIVR ST,ST(i)\"): ST(0) <- ST(i) / ST(0)\n *\n * @this {FPUX86}\n */\n static FDIVRst()\n {\n this.setST(0, this.doDivide(this.getST(this.iStack), this.getST(0)));\n }\n\n /**\n * FDIVRsti()\n *\n * Encoding 0xDC,0xF0-0xF7 (\"FDIVR ST(i),ST\"): ST(i) <- ST(0) / ST(i)\n *\n * @this {FPUX86}\n */\n static FDIVRsti()\n {\n this.setST(this.iStack, this.doDivide(this.getST(0), this.getST(this.iStack)));\n }\n\n /**\n * FDIVRPsti()\n *\n * Encoding 0xDE,0xF0-0xE7 (\"FDIVRP ST(i),ST\"): ST(i) <- ST(0) / ST(i), POP\n *\n * @this {FPUX86}\n */\n static FDIVRPsti()\n {\n if (this.setST(this.iStack, this.doDivide(this.getST(0), this.getST(this.iStack)))) this.popValue();\n }\n\n /**\n * FENI8087()\n *\n * @this {FPUX86}\n */\n static FENI8087()\n {\n if (this.isModel(X86.FPU.MODEL_8087)) {\n this.regControl &= ~X86.FPU.CONTROL.IEM;\n }\n }\n\n /**\n * FFREEsti()\n *\n * @this {FPUX86}\n */\n static FFREEsti()\n {\n this.setTag(this.iST, X86.FPU.TAGS.EMPTY);\n }\n\n /**\n * FFREEP8087()\n *\n * NOTE: This is used with an encoding (0xDF,0xC0-0xC7) that was valid for the 8087 and 80287\n * but may no longer be valid as of the 80387. Also, if the older documentation is to be believed,\n * this instruction has no modern counterpart, as FFREE doesn't pop the stack.\n *\n * @this {FPUX86}\n */\n static FFREEP8087()\n {\n this.opObsolete();\n FPUX86.FFREEsti.call(this);\n this.popValue();\n }\n\n /**\n * FIADD16()\n *\n * @this {FPUX86}\n */\n static FIADD16()\n {\n this.setST(0, this.doAdd(this.getST(0), this.getWIFromEA()));\n }\n\n /**\n * FIADD32()\n *\n * @this {FPUX86}\n */\n static FIADD32()\n {\n this.setST(0, this.doAdd(this.getST(0), this.getSIFromEA()));\n }\n\n /**\n * FICOM16()\n *\n * @this {FPUX86}\n */\n static FICOM16()\n {\n this.doCompare(this.getST(0), this.getWIFromEA());\n }\n\n /**\n * FICOM32()\n *\n * @this {FPUX86}\n */\n static FICOM32()\n {\n this.doCompare(this.getST(0), this.getSIFromEA());\n }\n\n /**\n * FICOMP16()\n *\n * @this {FPUX86}\n */\n static FICOMP16()\n {\n if (this.doCompare(this.getST(0), this.getWIFromEA())) this.popValue();\n }\n\n /**\n * FICOMP32()\n *\n * @this {FPUX86}\n */\n static FICOMP32()\n {\n if (this.doCompare(this.getST(0), this.getSIFromEA())) this.popValue();\n }\n\n /**\n * FIDIV16()\n *\n * @this {FPUX86}\n */\n static FIDIV16()\n {\n this.setST(0, this.doDivide(this.getST(0), this.getWIFromEA()));\n }\n\n /**\n * FIDIV32()\n *\n * @this {FPUX86}\n */\n static FIDIV32()\n {\n this.setST(0, this.doDivide(this.getST(0), this.getSIFromEA()));\n }\n\n /**\n * FIDIVR16()\n *\n * @this {FPUX86}\n */\n static FIDIVR16()\n {\n this.setST(0, this.doDivide(this.getWIFromEA(), this.getST(0)));\n }\n\n /**\n * FIDIVR32()\n *\n * @this {FPUX86}\n */\n static FIDIVR32()\n {\n this.setST(0, this.doDivide(this.getSIFromEA(), this.getST(0)));\n }\n\n /**\n * FILD16()\n *\n * @this {FPUX86}\n */\n static FILD16()\n {\n this.pushValue(this.getWIFromEA());\n }\n\n /**\n * FILD32()\n *\n * @this {FPUX86}\n */\n static FILD32()\n {\n this.pushValue(this.getSIFromEA());\n }\n\n /**\n * FILD64()\n *\n * @this {FPUX86}\n */\n static FILD64()\n {\n this.pushValue(this.getLIFromEA());\n }\n\n /**\n * FIMUL16()\n *\n * @this {FPUX86}\n */\n static FIMUL16()\n {\n this.setST(0, this.doMultiply(this.getST(0), this.getWIFromEA()));\n }\n\n /**\n * FIMUL32()\n *\n * @this {FPUX86}\n */\n static FIMUL32()\n {\n this.setST(0, this.doMultiply(this.getST(0), this.getSIFromEA()));\n }\n\n /**\n * FINCSTP()\n *\n * @this {FPUX86}\n */\n static FINCSTP()\n {\n this.iST = (this.iST + 1) & 0x7;\n this.regStatus &= ~X86.FPU.STATUS.C1;\n }\n\n /**\n * FINIT()\n *\n * @this {FPUX86}\n */\n static FINIT()\n {\n this.resetFPU();\n }\n\n /**\n * FIST16()\n *\n * @this {FPUX86}\n */\n static FIST16()\n {\n if (this.getWI(0)) this.setEAFromWI();\n }\n\n /**\n * FIST32()\n *\n * @this {FPUX86}\n */\n static FIST32()\n {\n if (this.getSI(0)) this.setEAFromSI();\n }\n\n /**\n * FISTP16()\n *\n * @this {FPUX86}\n */\n static FISTP16()\n {\n if (this.getWI(0)) {\n this.setEAFromWI();\n this.popValue();\n }\n }\n\n /**\n * FISTP32()\n *\n * @this {FPUX86}\n */\n static FISTP32()\n {\n if (this.getSI(0)) {\n this.setEAFromSI();\n this.popValue();\n }\n }\n\n /**\n * FISTP64()\n *\n * @this {FPUX86}\n */\n static FISTP64()\n {\n if (this.getLI(0)) {\n this.setEAFromLI();\n this.popValue();\n }\n }\n\n /**\n * FISUB16()\n *\n * @this {FPUX86}\n */\n static FISUB16()\n {\n this.setST(0, this.doSubtract(this.getST(0), this.getWIFromEA()));\n }\n\n /**\n * FISUB32()\n *\n * @this {FPUX86}\n */\n static FISUB32()\n {\n this.setST(0, this.doSubtract(this.getST(0), this.getSIFromEA()));\n }\n\n /**\n * FISUBR16()\n *\n * @this {FPUX86}\n */\n static FISUBR16()\n {\n this.setST(0, this.doSubtract(this.getWIFromEA(), this.getST(0)));\n }\n\n /**\n * FISUBR32()\n *\n * @this {FPUX86}\n */\n static FISUBR32()\n {\n this.setST(0, this.doSubtract(this.getSIFromEA(), this.getST(0)));\n }\n\n /**\n * FLDlr()\n *\n * The FLD instruction loads the source operand, converts it to temporary real format (if required),\n * and pushes the resulting value onto the floating-point stack.\n *\n * The load operation is accomplished by decrementing the top-of-stack pointer (TOP) and copying the\n * source operand to the new stack top. If the source operand is a float ing-point register, the index of\n * the register is taken before TOP is changed. The source operand may also be a short real, long real,\n * or temporary real memory operand. Short real and long real operands are converted automatically.\n *\n * Note that coding the instruction FLD ST(0) duplicates the value at the stack top.\n *\n * On the 8087 and 80287, the FLD real80 instruction will raise the denormal exception if the memory\n * operand is a denormal. The 80287XL and later coprocessors will not, since the operation is not arithmetic.\n *\n * On the 8087 and 80287, a denormal will be converted to an unnormal by FLD; on the 80287XL and later\n * coprocessors, the number will be converted to temporary real. If the next instruction is an FXTRACT or FXAM,\n * the 8087/80827 and 80287XL/80387/ 80486 results will be different.\n *\n * On the 8087 and 80287, the FLD real32 and FLD real64 instructions will not raise an exception when loading\n * a signaling NaN; on the 80287XL and later coprocessors, loading a signaling NaN raises the invalid operation\n * exception.\n *\n * @this {FPUX86}\n */\n static FLDlr()\n {\n this.pushValue(this.getLRFromEA());\n }\n\n /**\n * FLDsr()\n *\n * @this {FPUX86}\n */\n static FLDsr()\n {\n this.pushValue(this.getSRFromEA());\n }\n\n /**\n * FLDsti()\n *\n * @this {FPUX86}\n */\n static FLDsti()\n {\n this.pushValue(this.getST(this.iStack));\n }\n\n /**\n * FLDtr()\n *\n * @this {FPUX86}\n */\n static FLDtr()\n {\n this.pushValue(this.getLRFromTR(this.getTRFromEA()));\n }\n\n /**\n * FLDCW()\n *\n * @this {FPUX86}\n */\n static FLDCW()\n {\n\n this.setControl(this.cpu.getShort(this.cpu.regEA));\n }\n\n /**\n * FLDENV()\n *\n * @this {FPUX86}\n */\n static FLDENV()\n {\n\n this.loadEnv(this.cpu.regEA);\n }\n\n /**\n * FLD1()\n *\n * The FLD1 instruction loads the constant +1.0 from the NPX's constant ROM and pushes the value onto the\n * floating-point stack.\n *\n * The constant is stored internally in temporary real format and is simply moved to the stack.\n *\n * See also: FLDLG2, FLDLN2, FLDL2E, FLDL2T, FLDPI, and FLD1.\n *\n * @this {FPUX86}\n */\n static FLD1()\n {\n this.pushValue(1.0);\n }\n\n /**\n * FLDL2T()\n *\n * The FLDL2T instruction loads the constant log2(10) from the NPX's constant ROM and pushes the value onto the\n * floating-point stack.\n *\n * The constant is stored internally in temporary real format and is simply moved to the stack.\n *\n * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and\n * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0), round down (toward\n * -infinity), or round to nearest or even, the result will be the same as on the 8087 and 80287. If RC is set for\n * round up (toward +infinity), the result will differ by one in the least significant bit of the mantissa.\n *\n * See also: FLDLG2, FLDLN2, FLDL2E, FLDPI, FLD1, and FLDZ.\n *\n * @this {FPUX86}\n */\n static FLDL2T()\n {\n this.pushValue(FPUX86.regL2T);\n }\n\n /**\n * FLDL2E()\n *\n * The FLDL2E instruction loads the constant log2(e) from the NPX's constant ROM and pushes the value onto the\n * floating-point stack.\n *\n * The constant is stored internally in temporary real format and is simply moved to the stack.\n *\n * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and\n * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward\n * -infinity), the result is the same as on the 8087 and 80827. If RC is set for round to nearest or even, or round\n * up (toward +infinity), the result will differ by one in the least significant bit of the mantissa.\n *\n * See also: FLDLG2, FLDLN2, FLDL2T, FLDPI, FLD1, and FLDZ.\n *\n * @this {FPUX86}\n */\n static FLDL2E()\n {\n this.pushValue(FPUX86.regL2E);\n }\n\n /**\n * FLDPI()\n *\n * The FLDPI instruction loads the constant Pi from the NPX's constant ROM and pushes the value onto the\n * floating-point stack.\n *\n * The constant is stored internally in temporary real format and is simply moved to the stack.\n *\n * On the 8087 and 80287, rounding control is not in effect for the loading of these constants. On the 80287XL and\n * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward\n * -infinity), the result is the same as on the 8087 and 80827. If RC is set for round to nearest or even, or round\n * up (toward +infinity), the result will differ by one in the least significant bit of the mantissa.\n *\n * See also: FLDLG2, FLDLN2, FLDL2E, FLDL2T, FLD1, and FLDZ.\n *\n * @this {FPUX86}\n */\n static FLDPI()\n {\n this.pushValue(FPUX86.regPI);\n }\n\n /**\n * FLDLG2()\n *\n * The FLDLG2 instruction loads the constant log10(2) from the NPX's constant ROM and pushes the value onto the\n * floating-point stack.\n *\n * The constant is stored internally in temporary real format and is simply moved to the stack.\n *\n * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and\n * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward\n * -infinity), the result is the same as on the 8087 and 80827. If RC is set for round to nearest or even, or round\n * up (toward +infinity), the result will differ by one in the least significant bit of the mantissa.\n *\n * See also: FLDLN2, FLDL2E, FLDL2T, FLDPI, FLD1, and FLDZ.\n *\n * @this {FPUX86}\n */\n static FLDLG2()\n {\n this.pushValue(FPUX86.regLG2);\n }\n\n /**\n * FLDLN2()\n *\n * The FLDLN2 instruction loads the constant loge(2) from the NPX's constant ROM and pushes the value onto the\n * floating-point stack.\n *\n * The constant is stored internally in temporary real format and is simply moved to the stack.\n *\n * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and\n * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward\n * -infinity), the result will be the same as on the 8087 and 80827. If RC is set for round to nearest or even, or\n * round up (toward +infinity), the result will differ by one in the least significant bit of the mantissa.\n *\n * See also: FLDLG2, FLDL2E, FLDL2T, FLDPI, FLD1, and FLDZ.\n *\n * @this {FPUX86}\n */\n static FLDLN2()\n {\n this.pushValue(FPUX86.regLN2);\n }\n\n /**\n * FLDZ()\n *\n * The FLDZ instruction loads the constant +0.0 from the NPX's constant ROM and pushes the value onto the\n * floating-point stack.\n *\n * The constant is stored internally in temporary real format and is simply moved to the stack.\n *\n * See also: FLDLG2, FLDLN2, FLDL2E, FLDL2T, FLDPI, and FLD1.\n *\n * @this {FPUX86}\n */\n static FLDZ()\n {\n this.pushValue(0.0);\n }\n\n /**\n * FMULlr()\n *\n * @this {FPUX86}\n */\n static FMULlr()\n {\n this.setST(0, this.doMultiply(this.getST(0), this.getLRFromEA()));\n }\n\n /**\n * FMULsr()\n *\n * Encoding 0xD8,reg=0x01 (\"FMUL short-real\"): ST(0) <- ST(0) * REAL32\n *\n * @this {FPUX86}\n */\n static FMULsr()\n {\n this.setST(0, this.doMultiply(this.getST(0), this.getSRFromEA()));\n }\n\n /**\n * FMULst()\n *\n * @this {FPUX86}\n */\n static FMULst()\n {\n this.setST(0, this.doMultiply(this.getST(0), this.getST(this.iStack)));\n }\n\n /**\n * FMULsti()\n *\n * @this {FPUX86}\n */\n static FMULsti()\n {\n this.setST(this.iStack, this.doMultiply(this.getST(this.iStack), this.getST(0)));\n }\n\n /**\n * FMULPsti()\n *\n * @this {FPUX86}\n */\n static FMULPsti()\n {\n if (this.setST(this.iStack, this.doMultiply(this.getST(this.iStack), this.getST(0)))) this.popValue();\n }\n\n /**\n * FNOP()\n *\n * @this {FPUX86}\n */\n static FNOP()\n {\n }\n\n /**\n * FPATAN()\n *\n * FPATAN calculates the partial arctangent of ST(0) divided by ST(1):\n *\n * ST(1) = tan^-1( ST(1) / ST(0) )\n *\n * On the 8087 and 80287, the arguments must satisfy the inequality 0 <= ST(1) < ST(0) < +infinity.\n * On the 80287XL and later coprocessors, the range of the operands is unrestricted. The result is\n * returned to ST(1), and the stack is popped, destroying both operands and leaving the result in ST(0).\n *\n * @this {FPUX86}\n */\n static FPATAN()\n {\n if (this.setST(1, Math.atan2(this.getST(1), this.getST(0)))) this.popValue();\n }\n\n /**\n * FPTAN()\n *\n * FPTAN calculates the partial tangent of ST(0):\n *\n * y / x = tan( ST(0) )\n *\n * The result of the operation is a ratio. y replaces the argument on the stack, and x is pushed onto the stack,\n * where it becomes the new ST(0).\n *\n * On the 8087 and 80287, the FPTAN function assumes that its argument is valid and in-range. No argument checking\n * is performed. The value of ST(0) must satisfy the inequality -pi/4 <= ST(0) <= pi/4. In the case of an invalid\n * argument, the result is undefined and no error is signaled.\n *\n * On the 80287XL and later coprocessors, if value of ST(0) satisfies the condition -2^63 < ST(0) < 2^63, it will\n * automatically be reduced to within range. If the operand is outside this range, however, C2 is set to 1 to indicate\n * that the function is incomplete, and ST(0) is left unchanged.\n *\n * The 80287XL, 80387, and 80486 always push a value of +1.0 for x. The value of x pushed by the 8087 and 80287 may be\n * any real number. In either case, the ratio is the same. The cotangent can be calculated by executing FDIVR immediately\n * after FPTAN. The following code will leave the 8087 and 80287 in the same state as the later coprocessors:\n *\n * FDIV\n * FLD1\n *\n * ST(7) must be empty before this instruction is executed to avoid an invalid operation exception. If the invalid\n * operation exception is masked, the 8087 and 80287 leave the original operand unchanged, but push it to ST(1). On the\n * 80287XL and later coprocessors, both ST(0) and ST(1) will contain quiet NaNs. On the 80287XL and later coprocessors,\n * if condition code bit C2 is 0 and the precision exception is raised, then C1=1 if the last bit was rounded up. C1 is\n * undefined for the 8087 and 80287.\n *\n * @this {FPUX86}\n */\n static FPTAN()\n {\n if (this.setST(0, Math.tan(this.getST(0)))) this.pushValue(1.0);\n }\n\n /**\n * FPREM()\n *\n * FPREM performs modulo division of ST(0) by ST(1) and returns the result to ST(0).\n *\n * The FPREM instruction is used to reduce the real operand in ST(0) to a value whose magnitude is less than the\n * magnitude of ST(1). FPREM produces an exact result, so the precision exception is never raised and the rounding\n * control has no effect. The sign of the remainder is the same as the sign of the original operand.\n *\n * The remaindering operation is performed by iterative scaled subtractions and can reduce the exponent of ST(0) by\n * no more than 63 in one execution. If the remainder is less than ST(1) (the modulus), the function is complete and\n * C2 in the status word is cleared.\n *\n * If the modulo function is incomplete, C2 is set to 1, and the result in ST(0) is termed the partial remainder.\n * C2 can be inspected by storing the status word and re-executing the instruction until C2 is clear. Alternately,\n * ST(0) can be compared to ST(1). If ST(0) > ST(1), then FPREM must be executed again. If ST(0) = ST(1), then the\n * remainder is 0.\n *\n * FPREM is important for reducing arguments to the periodic transcendental functions such as FPTAN. Because FPREM\n * produces an exact result, no round-off error is introduced into the calculation.\n *\n * When reduction is complete, the three least-significant bits of the quotient are stored in the condition code bits\n * C3, C1, and C0, respectively. When arguments to the tangent function are reduced by pi/4, this result can be used\n * to identify the octant that contained the original angle.\n *\n * The FPREM function operates differently than specified by the IEEE 754 standard when rounding the quotient to form\n * a partial remainder (see the algorithm). The FPREM1 function (80287XL and up) is provided for compatibility with\n * that standard.\n *\n * The FPREM instruction can also be used to normalize ST(0). If ST(0) is unnormal and ST(1) is greater than ST(0),\n * FPREM will normalize ST(0). On the 8087 and 80287, operation on a denormal operand raises the invalid operation\n * exception. Underflow is not possible. On the 80287XL and later coprocessors, operation on a denormal is supported\n * and an underflow exception can occur.\n *\n * ALGORITHM:\n *\n * t = EXPONENT(ST) - EXPONENT(ST(1))\n * IF (t < 64) THEN\n * q = R0UND(ST(0) / ST(1), CHOP)\n * ST(0) = ST(0) - (ST(1) * q)\n * C2 = 0\n * C0 = BIT 2 of q\n * C1 = BIT 1 of q\n * C3 = BIT 0 of q\n * ELSE\n * n = a number between 32 and 63\n * q = ROUND((ST(0) / ST(1)) / 2^(t-n), CHOP)\n * ST(0) = ST(0) - (ST(1) * q * 2^(t-n))\n * C2 = 1\n * ENDIF\n *\n * TODO: Determine the extent to which the JavaScript MOD operator differs from the above algorithm.\n *\n * ERRATA: On the 8087 and 80287, the condition code bits C3, C1, and C0 are incorrect when performing a reduction of\n * 64^n + m, where n >= 1, and m=1 or m=2. A bug fix should be implemented in software.\n *\n * @this {FPUX86}\n */\n static FPREM()\n {\n this.setST(0, this.getST(0) % this.getST(1));\n }\n\n /**\n * FRSTOR()\n *\n * @this {FPUX86}\n */\n static FRSTOR()\n {\n var cpu = this.cpu;\n var addr = this.loadEnv(cpu.regEA);\n var a = this.intTmpTR;\n for (var i = 0; i < this.regStack.length; i++) {\n a[0] = cpu.getLong(addr);\n a[1] = cpu.getLong(addr += 4);\n a[2] = cpu.getShort(addr += 4);\n this.setTR(i, a);\n addr += 2;\n }\n }\n\n /**\n * FRNDINT()\n *\n * @this {FPUX86}\n */\n static FRNDINT()\n {\n this.setST(0, this.roundValue(this.getST(0), FPUX86.MAX_INT64));\n }\n\n /**\n * FSAVE()\n *\n * @this {FPUX86}\n */\n static FSAVE()\n {\n var cpu = this.cpu;\n var addr = this.saveEnv(cpu.regEA);\n for (var i = 0; i < this.regStack.length; i++) {\n var a = this.getTR(i, true);\n cpu.setLong(addr, a[0]);\n cpu.setLong(addr += 4, a[1]);\n cpu.setShort(addr += 4, a[2]);\n addr += 2;\n }\n this.resetFPU();\n }\n\n /**\n * FSCALE()\n *\n * FSCALE interprets the value in ST(1) as an integer and adds this number to the exponent of the number in ST(0).\n *\n * The FSCALE instruction provides a means of quickly performing multiplication or division by powers of two.\n * This operation is often required when scaling array indexes.\n *\n * On the 8087 and 80287, FSCALE assumes that the scale factor in ST(1) is an integer that satisfies the inequality\n * -2^15 <= ST(1) < +2^15. If ST(1) is not an integer value, the value is chopped to the next smallest integer in\n * magnitude (chopped toward zero). If the value is out of range or 0 < ST(1) < 1, FSCALE produces an undefined\n * result and doesn't signal an exception. Typically, the value in ST(0) is unchanged but should not be depended on.\n *\n * On the 80287XL and later coprocessors, there is no limit on the range of the scale factor in ST(1). The value in\n * ST(1) is still chopped toward zero. If ST(1) is 0, ST(0) is unchanged.\n *\n * @this {FPUX86}\n */\n static FSCALE()\n {\n var x = this.getST(0);\n var y = this.getST(1);\n if (x != null && y != null) this.setST(0, x * Math.pow(2, this.truncateValue(y)));\n }\n\n /**\n * FSETPM287()\n *\n * @this {FPUX86}\n */\n static FSETPM287()\n {\n if (this.isModel(X86.FPU.MODEL_80287)) {\n this.opUnimplemented();\n }\n }\n\n /**\n * FSINCOS387()\n *\n * @this {FPUX86}\n */\n static FSINCOS387()\n {\n if (this.isAtLeastModel(X86.FPU.MODEL_80287XL)) {\n this.opUnimplemented();\n }\n }\n\n /**\n * FSQRT()\n *\n * @this {FPUX86}\n */\n static FSQRT()\n {\n this.setST(0, this.doSquareRoot(this.getST(0)));\n }\n\n /**\n * FSTlr()\n *\n * @this {FPUX86}\n */\n static FSTlr()\n {\n if (this.getLR(0)) this.setEAFromLR();\n }\n\n /**\n * FSTsr()\n *\n * @this {FPUX86}\n */\n static FSTsr()\n {\n if (this.getSR(0)) this.setEAFromSR();\n }\n\n /**\n * FSTsti()\n *\n * @this {FPUX86}\n */\n static FSTsti()\n {\n this.setST(this.iStack, this.getST(0));\n }\n\n /**\n * FSTENV()\n *\n * @this {FPUX86}\n */\n static FSTENV()\n {\n\n this.saveEnv(this.cpu.regEA);\n this.regControl |= X86.FPU.CONTROL.EXC; // mask all exceptions (but do not set IEM)\n }\n\n /**\n * FSTPlr()\n *\n * @this {FPUX86}\n */\n static FSTPlr()\n {\n if (this.getLR(0)) {\n this.setEAFromLR();\n this.popValue();\n }\n }\n\n /**\n * FSTPsr()\n *\n * @this {FPUX86}\n */\n static FSTPsr()\n {\n if (this.getSR(0)) {\n this.setEAFromSR();\n this.popValue();\n }\n }\n\n /**\n * FSTPsti()\n *\n * @this {FPUX86}\n */\n static FSTPsti()\n {\n if (this.setST(this.iStack, this.getST(0))) this.popValue();\n }\n\n /**\n * FSTP8087()\n *\n * NOTE: This is used with encodings (0xD9,0xD8-0xDF and 0xDF,0xD0-0xDF) that were valid for the 8087 and 80287\n * but may no longer be valid as of the 80387.\n *\n * @this {FPUX86}\n */\n static FSTP8087()\n {\n this.opObsolete();\n FPUX86.FSTPsti.call(this);\n }\n\n /**\n * FSTPtr()\n *\n * @this {FPUX86}\n */\n static FSTPtr()\n {\n if (this.getTR(0)) {\n this.setEAFromTR();\n this.popValue();\n }\n }\n\n /**\n * FSTCW()\n *\n * @this {FPUX86}\n */\n static FSTCW()\n {\n\n this.cpu.setShort(this.cpu.regEA, this.regControl);\n }\n\n /**\n * FSTSW()\n *\n * @this {FPUX86}\n */\n static FSTSW()\n {\n\n this.cpu.setShort(this.cpu.regEA, this.getStatus());\n }\n\n /**\n * FSTSWAX287()\n *\n * @this {FPUX86}\n */\n static FSTSWAX287()\n {\n if (this.isAtLeastModel(X86.FPU.MODEL_80287)) {\n this.cpu.regEAX = (this.cpu.regEAX & ~0xffff) | this.getStatus();\n }\n }\n\n /**\n * FSUBlr()\n *\n * @this {FPUX86}\n */\n static FSUBlr()\n {\n this.setST(0, this.doSubtract(this.getST(0), this.getLRFromEA()));\n }\n\n /**\n * FSUBsr()\n *\n * @this {FPUX86}\n */\n static FSUBsr()\n {\n this.setST(0, this.doSubtract(this.getST(0), this.getSRFromEA()));\n }\n\n /**\n * FSUBst()\n *\n * Encoding 0xD8,0xE0-0xE7 (\"FSUB ST,ST(i)\"): ST(0) <- ST(0) - ST(i)\n *\n * @this {FPUX86}\n */\n static FSUBst()\n {\n this.setST(0, this.doSubtract(this.getST(0), this.getST(this.iStack)));\n }\n\n /**\n * FSUBsti()\n *\n * Encoding 0xDC,0xE8-0xEF (\"FSUB ST(i),ST\"): ST(i) <- ST(i) - ST(0)\n *\n * @this {FPUX86}\n */\n static FSUBsti()\n {\n this.setST(this.iStack, this.doSubtract(this.getST(this.iStack), this.getST(0)));\n }\n\n /**\n * FSUBPsti()\n *\n * Encoding 0xDE,0xE8-0xEF (\"FSUBP ST(i),ST\"): ST(i) <- ST(i) - ST(0), POP\n *\n * @this {FPUX86}\n */\n static FSUBPsti()\n {\n if (this.setST(this.iStack, this.doSubtract(this.getST(this.iStack), this.getST(0)))) this.popValue();\n }\n\n /**\n * FSUBRlr()\n *\n * @this {FPUX86}\n */\n static FSUBRlr()\n {\n this.setST(0, this.doSubtract(this.getLRFromEA(), this.getST(0)));\n }\n\n /**\n * FSUBRsr()\n *\n * @this {FPUX86}\n */\n static FSUBRsr()\n {\n this.setST(0, this.doSubtract(this.getSRFromEA(), this.getST(0)));\n }\n\n /**\n * FSUBRst()\n *\n * Encoding 0xD8,0xE8-0xEF (\"FSUBR ST,ST(i)\"): ST(0) <- ST(i) - ST(0)\n *\n * @this {FPUX86}\n */\n static FSUBRst()\n {\n this.setST(0, this.doSubtract(this.getST(this.iStack), this.getST(0)));\n }\n\n /**\n * FSUBRsti()\n *\n * Encoding 0xDC,0xE0-0xE7 (\"FSUBR ST(i),ST\"): ST(i) <- ST(0) - ST(i)\n *\n * @this {FPUX86}\n */\n static FSUBRsti()\n {\n this.setST(this.iStack, this.doSubtract(this.getST(0), this.getST(this.iStack)));\n }\n\n /**\n * FSUBRPsti()\n *\n * Encoding 0xDE,0xE0-0xE7 (\"FSUBRP ST(i),ST\"): ST(i) <- ST(0) - ST(i), POP\n *\n * @this {FPUX86}\n */\n static FSUBRPsti()\n {\n if (this.setST(this.iStack, this.doSubtract(this.getST(0), this.getST(this.iStack)))) this.popValue();\n }\n\n /**\n * FTST()\n *\n * @this {FPUX86}\n */\n static FTST()\n {\n this.doCompare(this.getST(0), 0);\n }\n\n /**\n * FXAM()\n *\n * @this {FPUX86}\n */\n static FXAM()\n {\n this.regStatus &= ~X86.FPU.STATUS.CC;\n\n if (this.getSTSign(0)) {\n this.regStatus |= X86.FPU.STATUS.C1;\n }\n if (this.getTag(this.iST) == X86.FPU.TAGS.EMPTY) {\n this.regStatus |= X86.FPU.STATUS.C0 | X86.FPU.STATUS.C3;\n }\n else {\n var v = this.getST(0);\n if (isNaN(v)) {\n this.regStatus |= X86.FPU.STATUS.C0;\n }\n else if (v === 0) { // this equals -0, too (WTF, strict equality?)\n this.regStatus |= X86.FPU.STATUS.C3;\n }\n else if (v === Infinity || v === -Infinity) { // these are so divergent that even non-strict equality doesn't consider them equal\n this.regStatus |= X86.FPU.STATUS.C0 | X86.FPU.STATUS.C2;\n }\n else {\n this.regStatus |= X86.FPU.STATUS.C2;\n }\n }\n }\n\n /**\n * FXCHsti()\n *\n * @this {FPUX86}\n */\n static FXCHsti()\n {\n var tmp = this.getST(0);\n this.setST(0, this.getST(this.iStack));\n this.setST(this.iStack, tmp);\n }\n\n /**\n * FXCH8087()\n *\n * NOTE: This is used with encodings (0xDD,0xC8-0xCF and 0xDF,0xC8-0xCF) that were valid for the 8087 and 80287\n * but may no longer be valid as of the 80387.\n *\n * @this {FPUX86}\n */\n static FXCH8087()\n {\n this.opObsolete();\n FPUX86.FXCHsti.call(this);\n }\n\n /**\n * FXTRACT()\n *\n * FXTRACT splits the value encoded in ST(0) into two separate numbers representing the actual value of the\n * fraction (mantissa) and exponent fields.\n *\n * The FXTRACT instruction is used to decompose the two fields of the temporary real number in ST(0). The exponent\n * replaces the value in ST(0), then the fraction is pushed onto the stack. When execution is complete, ST(0)\n * contains the original fraction, expressed as a real number with a true exponent of 0 (0x3FFF in biased form),\n * and ST(1) contains the value of the original operand's true (unbiased) exponent expressed as a real number.\n *\n * If ST(0) is 0, the 8087 and 80287 will leave zeros in both ST(0) and ST(1); both zeros will have the same sign as\n * the original operand. If ST(0) is +infinity, the invalid operation exception is raised.\n *\n * On the 80287XL and later coprocessors, if ST(0) is 0, the zero-divide exception is reported and ST(1) is set to\n * -infinity. If ST(0) is +infinity, no exception is reported.\n *\n * The FXTRACT instruction may be thought of as the complement to the FSCALE instruction, which combines a separate\n * fraction and exponent into a single value.\n *\n * ALGORITHM:\n *\n * IF (ST(0) = 0) THEN\n * DEC TOP\n * ST(0) = ST(1)\n * ELSE\n * temp = ST(0)\n * ST(0) = EXPONENT(ST(0)) ; stored as true exponent\n * DEC TOP\n * ST(0) = FRACTION(ST(0))\n * ENDIF\n *\n * @this {FPUX86}\n */\n static FXTRACT()\n {\n var v = this.getST(0);\n if (v != null) {\n this.regTmpLR[0] = v;\n this.setST(0, ((this.intTmpLR[1] >> 20) & 0x7ff) - 0x3ff);\n this.intTmpLR[1] = (this.intTmpLR[1] | 0x3ff00000) & ~0x40000000;\n this.pushValue(this.regTmpLR[0]);\n }\n }\n\n /**\n * FYL2X()\n *\n * FYL2X (y log base 2 of x) calculates:\n *\n * ST(1) = ST(1) * log2(ST(0))\n *\n * The operands must satisfy the inequalities 0 < ST(0) < +infinity and -infinity < ST(1) < +infinity. FYL2X pops\n * the stack and returns the result to the new ST(0). Both original operands are destroyed.\n *\n * The FYL2X function is designed to optimize the calculation of a log to a base, n, other than two. In such a case,\n * the following multiplication is required; ie:\n *\n * logn(x) = logn(2) * log2(x)\n *\n * @this {FPUX86}\n */\n static FYL2X()\n {\n if (this.setST(1, this.getST(1) * Math.log(this.getST(0)) / Math.LN2)) this.popValue();\n }\n\n /**\n * FYL2XP1()\n *\n * FYL2XP1 (y log base 2 of x plus 1) calculates:\n *\n * ST(1) = ST(1) * log2(ST(0) + 1)\n *\n * The operands must satisfy the inequalities -(1-sqrt(2)/2) < ST(0) < (1-sqrt(2)/2) and -infinity < ST(1) < +infinity.\n * FYL2XP1 pops the stack and returns the result to the new ST(0). Both original operands are destroyed.\n *\n * The FYL2XP1 function provides greater accuracy than FYL2X in computing the log of a number that is very close to 1.\n *\n * FYL2XP1 is typically used when computing compound interest, for example, which requires the calculation of a logarithm\n * of 1.0 + n where 0 < n < 0.29. If 1.0 was added to n, significant digits might be lost. By using FYL2XP1, the result\n * will be as accurate as n to within three units of temporary real precision.\n *\n * @this {FPUX86}\n */\n static FYL2XP1()\n {\n if (this.setST(1, this.getST(1) * Math.log(this.getST(0) + 1.0) / Math.LN2)) this.popValue();\n }\n\n /**\n * FPUX86.init()\n *\n * This function operates on every HTML element of class \"fpu\", extracting the\n * JSON-encoded parameters for the FPUX86 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create an FPUX86 component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeFPUs = Component.getElementsByClass(document, PCX86.APPCLASS, \"fpu\");\n for (var iFPU = 0; iFPU < aeFPUs.length; iFPU++) {\n var eFPU = aeFPUs[iFPU];\n var parmsFPU = Component.getComponentParms(eFPU);\n var fpu = new FPUX86(parmsFPU);\n Component.bindComponentControls(fpu, eFPU, PCX86.APPCLASS);\n }\n }\n}\n\n/*\n * Class constants\n *\n * TODO: When loading any of the following 5 constants, the 80287XL and newer coprocessors apply rounding control.\n */\n\n/** @const */\nFPUX86.regL2T = Math.log(10) / Math.LN2; // log2(10) (use Math.log2() if we ever switch to ES6)\n\n/** @const */\nFPUX86.regL2E = Math.LOG2E; // log2(e)\n\n/** @const */\nFPUX86.regPI = Math.PI; // pi\n\n/** @const */\nFPUX86.regLG2 = Math.log(2) / Math.LN10; // log10(2) (use Math.log10() if we ever switch to ES6)\n\n/** @const */\nFPUX86.regLN2 = Math.LN2; // log(2)\n\n/** @const */\nFPUX86.MAX_INT16 = 0x8000;\n\n/** @const */\nFPUX86.MAX_INT32 = 0x80000000;\n\n/** @const */\nFPUX86.MAX_INT64 = Math.pow(2, 63);\n\n\n/*\n * FPU operation lookup table (be sure to keep the following table in sync with Debugger.aaaOpFPUDescs).\n *\n * The second lookup value corresponds to bits in the ModRegRM byte that follows the ESC byte (0xD8-0xDF).\n *\n * Here's a little cheat-sheet for how the 2nd lookup values relate to ModRegRM values; see opFPU() for details.\n *\n * Lookup ModRegRM value(s)\n * ------ -------------------------------\n * 0x00: 0x00-0x07, 0x40-0x47, 0x80-0x87\n * 0x01: 0x08-0x0F, 0x48-0x4F, 0x88-0x8F\n * 0x02: 0x10-0x17, 0x50-0x57, 0x90-0x97\n * 0x03: 0x18-0x1F, 0x58-0x5F, 0x98-0x9F\n * 0x04: 0x20-0x27, 0x60-0x67, 0xA0-0xA7\n * 0x05: 0x28-0x2F, 0x68-0x6F, 0xA8-0xAF\n * 0x06: 0x30-0x37, 0x70-0x77, 0xB0-0xB7\n * 0x07: 0x38-0x3F, 0x78-0x7F, 0xB8-0xBF\n * 0x30: 0xC0-0xC7\n * 0x31: 0xC8-0xCF\n * 0x32: 0xD0-0xD7\n * 0x33: 0xD8-0xDF\n * 0x34: 0xE0-0xE7\n * 0x35: 0xE8-0xEF\n * 0x36: 0xF0-0xF7\n * 0x37: 0xF8-0xFF\n *\n * ESC bytes 0xD9 and 0xDB use the RM field to further describe the operation when the ModRegRM value >= 0xE0.\n * In those cases, we shift the Reg value into the high nibble and the RM value into the low nibble, resulting in\n * the following lookup values (which look a lot like hex-encoded octal):\n *\n * 0x40: 0xE0\n * 0x41: 0xE1\n * ... ...\n * 0x46: 0xE6\n * 0x47: 0xE7\n *\n * 0x50: 0xE8\n * 0x51: 0xE9\n * ... ...\n * 0x56: 0xEE\n * 0x57: 0xEF\n *\n * 0x60: 0xF0\n * 0x61: 0xF1\n * ... ...\n * 0x66: 0xF6\n * 0x67: 0xF7\n *\n * 0x70: 0xF8\n * 0x71: 0xF9\n * ... ...\n * 0x76: 0xFE\n * 0x77: 0xFF\n */\nFPUX86.aaOps = {\n 0xD8: {\n 0x00: FPUX86.FADDsr, 0x01: FPUX86.FMULsr, 0x02: FPUX86.FCOMsr, 0x03: FPUX86.FCOMPsr,\n 0x04: FPUX86.FSUBsr, 0x05: FPUX86.FSUBRsr, 0x06: FPUX86.FDIVsr, 0x07: FPUX86.FDIVsr,\n 0x30: FPUX86.FADDst, 0x31: FPUX86.FMULst, 0x32: FPUX86.FCOMst, 0x33: FPUX86.FCOMPst,\n 0x34: FPUX86.FSUBst, 0x35: FPUX86.FSUBRst, 0x36: FPUX86.FDIVst, 0x37: FPUX86.FDIVRst\n },\n 0xD9: {\n 0x00: FPUX86.FLDsr, 0x02: FPUX86.FSTsr, 0x03: FPUX86.FSTPsr,\n 0x04: FPUX86.FLDENV, 0x05: FPUX86.FLDCW, 0x06: FPUX86.FSTENV, 0x07: FPUX86.FSTCW,\n 0x30: FPUX86.FLDsti, 0x31: FPUX86.FXCHsti, 0x32: FPUX86.FNOP, 0x33: FPUX86.FSTP8087,\n 0x40: FPUX86.FCHS, 0x41: FPUX86.FABS,\n 0x44: FPUX86.FTST, 0x45: FPUX86.FXAM,\n 0x50: FPUX86.FLD1, 0x51: FPUX86.FLDL2T, 0x52: FPUX86.FLDL2E, 0x53: FPUX86.FLDPI,\n 0x54: FPUX86.FLDLG2, 0x55: FPUX86.FLDLN2, 0x56: FPUX86.FLDZ,\n 0x60: FPUX86.F2XM1, 0x61: FPUX86.FYL2X, 0x62: FPUX86.FPTAN, 0x63: FPUX86.FPATAN,\n 0x64: FPUX86.FXTRACT, 0x66: FPUX86.FDECSTP, 0x67: FPUX86.FINCSTP,\n 0x70: FPUX86.FPREM, 0x71: FPUX86.FYL2XP1, 0x72: FPUX86.FSQRT,\n 0x74: FPUX86.FRNDINT, 0x75: FPUX86.FSCALE\n },\n 0xDA: {\n 0x00: FPUX86.FIADD32, 0x01: FPUX86.FIMUL32, 0x02: FPUX86.FICOM32, 0x03: FPUX86.FICOMP32,\n 0x04: FPUX86.FISUB32, 0x05: FPUX86.FISUBR32, 0x06: FPUX86.FIDIV32, 0x07: FPUX86.FIDIVR32\n },\n 0xDB: {\n 0x00: FPUX86.FILD32, 0x02: FPUX86.FIST32, 0x03: FPUX86.FISTP32,\n 0x05: FPUX86.FLDtr, 0x07: FPUX86.FSTPtr,\n 0x40: FPUX86.FENI8087, 0x41: FPUX86.FDISI8087, 0x42: FPUX86.FCLEX, 0x43: FPUX86.FINIT,\n 0x44: FPUX86.FSETPM287,\n 0x73: FPUX86.FSINCOS387\n },\n 0xDC: {\n 0x00: FPUX86.FADDlr, 0x01: FPUX86.FMULlr, 0x02: FPUX86.FCOMlr, 0x03: FPUX86.FCOMPlr,\n 0x04: FPUX86.FSUBlr, 0x05: FPUX86.FSUBRlr, 0x06: FPUX86.FDIVlr, 0x07: FPUX86.FDIVRlr,\n 0x30: FPUX86.FADDsti, 0x31: FPUX86.FMULsti, 0x32: FPUX86.FCOM8087, 0x33: FPUX86.FCOMP8087,\n /*\n * Intel's original 8087 datasheet had these forms of SUB and SUBR (and DIV and DIVR) swapped.\n */\n 0x34: FPUX86.FSUBRsti, 0x35: FPUX86.FSUBsti, 0x36: FPUX86.FDIVRsti, 0x37: FPUX86.FDIVsti\n },\n 0xDD: {\n 0x00: FPUX86.FLDlr, 0x02: FPUX86.FSTlr, 0x03: FPUX86.FSTPlr,\n 0x04: FPUX86.FRSTOR, 0x06: FPUX86.FSAVE, 0x07: FPUX86.FSTSW,\n 0x30: FPUX86.FFREEsti, 0x31: FPUX86.FXCH8087, 0x32: FPUX86.FSTsti, 0x33: FPUX86.FSTPsti\n },\n 0xDE: {\n 0x00: FPUX86.FIADD16, 0x01: FPUX86.FIMUL16, 0x02: FPUX86.FICOM16, 0x03: FPUX86.FICOMP16,\n 0x04: FPUX86.FISUB16, 0x05: FPUX86.FISUBR16, 0x06: FPUX86.FIDIV16, 0x07: FPUX86.FIDIVR16,\n 0x30: FPUX86.FADDPsti, 0x31: FPUX86.FMULPsti, 0x32: FPUX86.FCOMP8087, 0x33: FPUX86.FCOMPP,\n /*\n * Intel's original 8087 datasheet had these forms of SUBP and SUBRP (and DIVP and DIVRP) swapped.\n */\n 0x34: FPUX86.FSUBRPsti, 0x35: FPUX86.FSUBPsti, 0x36: FPUX86.FDIVRPsti, 0x37: FPUX86.FDIVPsti\n },\n 0xDF: {\n 0x00: FPUX86.FILD16, 0x02: FPUX86.FIST16, 0x03: FPUX86.FISTP16,\n 0x04: FPUX86.FBLDpd, 0x05: FPUX86.FILD64, 0x06: FPUX86.FBSTPpd, 0x07: FPUX86.FISTP64,\n 0x30: FPUX86.FFREEP8087,0x31: FPUX86.FXCH8087, 0x32: FPUX86.FSTP8087, 0x33: FPUX86.FSTP8087,\n 0x34: FPUX86.FSTSWAX287\n }\n};\n\n/*\n * An array of FPUX86 functions documented as preserving the \"exception\" registers.\n */\nFPUX86.afnPreserveExceptions = [\n FPUX86.FCLEX, FPUX86.FINIT, FPUX86.FLDCW, FPUX86.FLDENV, FPUX86.FRSTOR,\n FPUX86.FSAVE, FPUX86.FSTCW, FPUX86.FSTENV, FPUX86.FSTSW, FPUX86.FSTSWAX287\n];\n\n/*\n * Initialize every FPU module on the page\n */\nWeb.onInit(FPUX86.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/segx86.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * NOTE: The protected-mode support in this module was initially added for 80286 support, and is\n * currently being upgraded for 80386 support. In a perfect world, all 80386-related support would\n * be disabled/skipped whenever the processor is merely an 80286. And in fact, that's the case\n * with some of the early changes (eg, skipping X86.DESC.EXT.BASE2431 and X86.DESC.EXT.LIMIT1619\n * fields unless the processor is an 80386).\n *\n * However, the reality is that I won't always be that strict, either because I'm lazy or I don't\n * want to risk a run-time performance hit or (more pragmatically) because any 80286 code you're likely\n * to run probably won't attempt to use descriptor types or other features unique to the 80386 anyway,\n * so the extra paranoia may not be worth the effort. Ultimately, I would like to see the code tailor\n * itself to the current CPU model, generally with model-specific functions, but that's a lot of work.\n */\n\n/**\n * class SegX86\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass SegX86 {\n /**\n * SegX86(cpu, sName)\n *\n * @this {SegX86}\n * @param {CPUX86} cpu\n * @param {number} id\n * @param {string} [sName] segment register name\n * @param {boolean} [fProt] true if segment register used exclusively in protected-mode (eg, segLDT)\n */\n constructor(cpu, id, sName, fProt)\n {\n this.cpu = cpu;\n /**\n * @type {DebuggerX86}\n */\n this.dbg = cpu.dbg;\n this.id = id;\n this.sName = sName || \"\";\n this.sel = 0;\n this.limit = 0xffff;\n this.offMax = this.limit + 1;\n this.base = 0;\n this.acc = this.type = 0;\n this.ext = 0;\n this.cpl = this.dpl = 0;\n this.addrDesc = X86.ADDR_INVALID;\n this.sizeData = this.sizeAddr = 2;\n this.maskData = this.maskAddr = 0xffff;\n\n this.loadV86 = this.loadReal;\n this.checkReadV86 = this.checkReadWriteReal;\n this.checkWriteV86 = this.checkReadWriteReal;\n\n /*\n * Preallocated object for \"probed\" segment loads\n */\n this.probe = {\n sel: -1, base: 0, limit: 0, acc: 0, type: 0, ext: 0, addrDesc: X86.ADDR_INVALID\n };\n\n /*\n * The following properties are used for CODE segments only (ie, segCS); if the process of loading\n * CS also requires a stack switch, then fStackSwitch will be set to true; additionally, if the stack\n * switch was the result of a CALL (ie, fCall is true) and one or more (up to 32) parameters are on\n * the old stack, they will be copied to awParms, and then once the stack is switched, the parameters\n * will be pushed from awParms onto the new stack.\n *\n * The typical ways of loading a new segment into CS are JMPF, CALLF (or INT), and RETF (or IRET),\n * via CPU functions setCSIP() and helpINT(), which use segCS.loadCode() and segCS.loadIDT(), respectively.\n *\n * loadCode() requires an fCall value: null means NO privilege level transition may occur, true\n * allows a stack switch and a privilege transition to a numerically lower privilege, and false allows\n * a stack restore and a privilege transition to a numerically greater privilege.\n *\n * loadIDT() sets fCall to true unconditionally in protected-mode (fCall has no meaning in real-mode).\n */\n if (this.id == 1 /* SegX86.ID.CODE */) { // don't use SegX86.ID.CODE until it's defined, or the Closure Compiler won't inline it\n this.offIP = 0;\n this.fCall = null;\n this.fStackSwitch = false;\n this.awParms = new Array(32);\n this.aCallBreaks = [];\n }\n\n this.updateMode(true, fProt);\n\n if (this.id == 0 /* SegX86.ID.NULL */) {\n this.checkRead = this.checkReadWriteNone;\n this.checkWrite = this.checkReadWriteNone;\n }\n }\n\n /**\n * addCallBreak(fn)\n *\n * Returns a \"call break\" address in an [off, sel] array. The given function, fn(), is called\n * whenever that address is called, and if fn() returns false, then the call is skipped. Otherwise,\n * the call is performed (ie, the old CS:[E]IP is pushed on the stack, and CS:[E]IP is set to the\n * \"call break\" address. Which is probably a bad idea, so your function should probably always\n * return false. Just sayin'. TODO: Should probably just force all \"call break\" calls to be skipped.\n *\n * @this {SegX86}\n * @param {function()} fn\n * @return {Array.<number>} containing offset and selector of call-break address\n */\n addCallBreak(fn)\n {\n this.aCallBreaks.push(fn);\n return [this.aCallBreaks.length, SegX86.CALLBREAK_SEL];\n }\n\n /**\n * loadCode(off, sel, fCall)\n *\n * A simple wrapper function that encapsulates setting offIP and fCall for segCS loads.\n *\n * @this {SegX86}\n * @param {number} off\n * @param {number} sel\n * @param {boolean|undefined} fCall is true if CALLF in progress, false if RETF/IRET in progress, undefined otherwise\n * @return {number} base address of selected segment, or X86.ADDR_INVALID if error\n */\n loadCode(off, sel, fCall)\n {\n this.offIP = off;\n this.fCall = fCall;\n return this.load(sel);\n }\n\n /**\n * loadReal(sel, fProbe)\n *\n * The default segment load() function for real-mode.\n *\n * @this {SegX86}\n * @param {number} sel\n * @param {boolean} [fProbe] (here only to make the function signatures of loadReal() and loadProt() match)\n * @return {number} base address of selected segment\n */\n loadReal(sel, fProbe)\n {\n this.sel = sel & 0xffff;\n /*\n * Loading a new value into a segment register in real-mode alters ONLY the selector and the base;\n * all other attributes (eg, limit, operand size, address size, etc) are unchanged. If you run any\n * code that switches to protected-mode, loads a 32-bit code segment, and then switches back to\n * real-mode, it is THAT code's responsibility to load a 16-bit segment into CS before returning to\n * real-mode; otherwise, your machine will probably be toast.\n */\n return this.base = this.sel << 4;\n }\n\n /**\n * loadProt(sel, fProbe)\n *\n * This replaces the segment's default load() function whenever the segment is notified via updateMode() by the\n * CPU's setProtMode() that the processor is now in protected-mode.\n *\n * Segments in protected-mode are referenced by selectors, which are indexes into descriptor tables (GDT or LDT)\n * whose descriptors are 4-word (8-byte) entries:\n *\n * word 0: segment limit (0-15)\n * word 1: base address low\n * word 2: base address high (0-7), segment type (8-11), descriptor type (12), DPL (13-14), present bit (15)\n * word 3: used only on 80386 and up (should be set to zero for upward compatibility)\n *\n * See X86.DESC for offset and bit definitions.\n *\n * IDT descriptor entries are handled separately by loadIDT(), which is mapped to loadIDTReal() or loadIDTProt().\n *\n * @this {SegX86}\n * @param {number} sel\n * @param {boolean} [fProbe]\n * @return {number} base address of selected segment, or X86.ADDR_INVALID if error\n */\n loadProt(sel, fProbe)\n {\n var addrDT;\n var addrDTLimit;\n var cpu = this.cpu;\n\n /*\n * Some instructions (eg, CALLF) load a 32-bit value for the selector, while others (eg, LDS) do not;\n * however, in ALL cases, only the low 16 bits are significant.\n */\n sel &= 0xffff;\n\n if (!(sel & X86.SEL.LDT)) {\n addrDT = cpu.addrGDT;\n addrDTLimit = cpu.addrGDTLimit;\n } else {\n addrDT = cpu.segLDT.base;\n addrDTLimit = (addrDT + cpu.segLDT.limit)|0;\n }\n /*\n * The ROM BIOS POST executes some test code in protected-mode without properly initializing the LDT,\n * which has no bearing on the ROM's own code, because it never loads any LDT selectors, but if at the same\n * time our Debugger attempts to validate a selector in one of its breakpoints, that could cause some grief.\n *\n * Fortunately, the Debugger now has its own interface, probeDesc(), so that should no longer be a concern.\n */\n if (addrDT) {\n var addrDesc = (addrDT + (sel & X86.SEL.MASK))|0;\n if ((addrDTLimit - addrDesc)|0 >= 7) {\n /*\n * TODO: This is the first of many steps toward accurately counting cycles in protected mode;\n * I simply noted that \"POP segreg\" takes 5 cycles in real mode and 20 in protected mode, so I'm\n * starting with a 15-cycle difference. Obviously the difference will vary with the instruction,\n * and will be much greater whenever the load fails.\n */\n cpu.nStepCycles -= 15;\n return this.loadDesc8(addrDesc, sel, fProbe);\n }\n if (this.id < SegX86.ID.VER) {\n X86.helpFault.call(cpu, fProbe && this.id == SegX86.ID.STACK? X86.EXCEPTION.TS_FAULT : X86.EXCEPTION.GP_FAULT, sel & X86.ERRCODE.SELMASK);\n }\n }\n return X86.ADDR_INVALID;\n }\n\n /**\n * loadIDTReal(nIDT)\n *\n * @this {SegX86}\n * @param {number} nIDT\n * @return {number} address from selected vector\n */\n loadIDTReal(nIDT)\n {\n var cpu = this.cpu;\n /*\n * NOTE: The COMPAQ DeskPro 386 ROM loads the IDTR for the real-mode IDT with a limit of 0xffff instead\n * of the normal 0x3ff. A limit higher than 0x3ff is OK, since all real-mode IDT entries are 4 bytes, and\n * there's no way to issue an interrupt with a vector > 0xff. Just something to be aware of.\n */\n\n /*\n * Intel documentation for INT/INTO under \"REAL ADDRESS MODE EXCEPTIONS\" says:\n *\n * \"[T]he 80286 will shut down if the SP = 1, 3, or 5 before executing the INT or INTO instruction--due to lack of stack space\"\n *\n * TODO: Verify that 80286 real-mode actually enforces the above. See http://www.pcjs.org/pubs/pc/reference/intel/80286/progref/#page-260\n */\n var addrIDT = cpu.addrIDT + (nIDT << 2);\n var off = cpu.getShort(addrIDT);\n cpu.regPS &= ~(X86.PS.TF | X86.PS.IF);\n return (this.load(cpu.getShort(addrIDT + 2)) + off)|0;\n }\n\n /**\n * loadIDTProt(nIDT)\n *\n * @this {SegX86}\n * @param {number} nIDT\n * @return {number} address from selected vector, or X86.ADDR_INVALID if error\n */\n loadIDTProt(nIDT)\n {\n var cpu = this.cpu;\n\n\n nIDT <<= 3;\n var addrDesc = (cpu.addrIDT + nIDT)|0;\n if (((cpu.addrIDTLimit - addrDesc)|0) >= 7) {\n this.fCall = true;\n var addr = this.loadDesc8(addrDesc, nIDT);\n if (addr !== X86.ADDR_INVALID) addr += this.offIP;\n return addr;\n }\n X86.helpFault.call(cpu, X86.EXCEPTION.GP_FAULT, nIDT | X86.ERRCODE.IDT);\n return X86.ADDR_INVALID;\n }\n\n /**\n * checkReadWriteNone(off, cb)\n *\n * @this {SegX86}\n * @param {number} off is a segment-relative offset\n * @param {number} cb is number of bytes to check (1, 2 or 4)\n * @return {number} corresponding linear address\n */\n checkReadWriteNone(off, cb)\n {\n return (this.base + off)|0;\n }\n\n /**\n * checkReadWriteReal(off, cb)\n *\n * @this {SegX86}\n * @param {number} off is a segment-relative offset\n * @param {number} cb is number of bytes to check (1, 2 or 4)\n * @return {number} corresponding linear address\n */\n checkReadWriteReal(off, cb)\n {\n /*\n * Since off could be a 32-bit value with the sign bit (bit 31) set, we must convert\n * it to an unsigned value using \">>>\"; offMax was already converted at segment load time.\n */\n if ((off >>> 0) + cb > this.offMax) {\n if (this.cpu.model <= X86.MODEL_8088) {\n this.cpu.opFlags |= X86.OPFLAG.WRAP;\n } else {\n X86.helpFault.call(this.cpu, X86.EXCEPTION.GP_FAULT);\n }\n }\n return (this.base + off)|0;\n }\n\n /**\n * checkReadProt(off, cb)\n *\n * @this {SegX86}\n * @param {number} off is a segment-relative offset\n * @param {number} cb is number of bytes to check (1, 2 or 4)\n * @return {number} corresponding linear address if valid, or X86.ADDR_INVALID if not\n */\n checkReadProt(off, cb)\n {\n /*\n * Since off could be a 32-bit value with the sign bit (bit 31) set, we must convert\n * it to an unsigned value using \">>>\"; offMax was already converted at segment load time.\n */\n if ((off >>> 0) + cb <= this.offMax) {\n return (this.base + off)|0;\n }\n return this.checkReadProtDisallowed(off, cb);\n }\n\n /**\n * checkReadProtDown(off, cb)\n *\n * @this {SegX86}\n * @param {number} off is a segment-relative offset\n * @param {number} cb is number of bytes to check (1, 2 or 4)\n * @return {number} corresponding linear address if valid, X86.ADDR_INVALID if not\n */\n checkReadProtDown(off, cb)\n {\n /*\n * Since off could be a 32-bit value with the sign bit (bit 31) set, we must convert\n * it to an unsigned value using \">>>\"; offMax was already converted at segment load time.\n */\n if ((off >>> 0) + cb > this.offMax) {\n return (this.base + off)|0;\n }\n return this.checkReadProtDisallowed(off, cb);\n }\n\n /**\n * checkReadProtDisallowed(off, cb)\n *\n * @this {SegX86}\n * @param {number} off is a segment-relative offset\n * @param {number} cb is number of bytes to check (1, 2 or 4)\n * @return {number} corresponding linear address if valid, X86.ADDR_INVALID if not\n */\n checkReadProtDisallowed(off, cb)\n {\n X86.helpFault.call(this.cpu, X86.EXCEPTION.GP_FAULT, 0);\n return X86.ADDR_INVALID;\n }\n\n /**\n * checkWriteProt(off, cb)\n *\n * @this {SegX86}\n * @param {number} off is a segment-relative offset\n * @param {number} cb is number of bytes to check (1, 2 or 4)\n * @return {number} corresponding linear address if valid, X86.ADDR_INVALID if not\n */\n checkWriteProt(off, cb)\n {\n /*\n * Since off could be a 32-bit value with the sign bit (bit 31) set, we must convert\n * it to an unsigned value using \">>>\"; offMax was already converted at segment load time.\n */\n if ((off >>> 0) + cb <= this.offMax) {\n return (this.base + off)|0;\n }\n return this.checkWriteProtDisallowed(off, cb);\n }\n\n /**\n * checkWriteProtDown(off, cb)\n *\n * @this {SegX86}\n * @param {number} off is a segment-relative offset\n * @param {number} cb is number of bytes to check (1, 2 or 4)\n * @return {number} corresponding linear address if valid, X86.ADDR_INVALID if not\n */\n checkWriteProtDown(off, cb)\n {\n /*\n * Since off could be a 32-bit value with the sign bit (bit 31) set, we must convert\n * it to an unsigned value using \">>>\"; offMax was already converted at segment load time.\n */\n if ((off >>> 0) + cb > this.offMax) {\n return (this.base + off)|0;\n }\n return this.checkWriteProtDisallowed(off, cb);\n }\n\n /**\n * checkWriteProtDisallowed(off, cb)\n *\n * @this {SegX86}\n * @param {number} off is a segment-relative offset\n * @param {number} cb is number of bytes to check (1, 2 or 4)\n * @return {number} corresponding linear address if valid, X86.ADDR_INVALID if not\n */\n checkWriteProtDisallowed(off, cb)\n {\n X86.helpFault.call(this.cpu, X86.EXCEPTION.GP_FAULT, 0);\n return X86.ADDR_INVALID;\n }\n\n /**\n * checkReadDebugger(off, cb)\n *\n * @this {SegX86}\n * @param {number} off is a segment-relative offset\n * @param {number} cb is number of bytes to check (1, 2 or 4)\n * @return {number} corresponding linear address if valid, or X86.ADDR_INVALID if error\n */\n checkReadDebugger(off, cb)\n {\n /*\n * The Debugger doesn't have separate \"check\" interfaces for real and protected mode,\n * since it's not performance-critical. If addrDesc is invalid, then we assume real mode.\n *\n * TODO: This doesn't actually check the segment for readability.\n */\n if (DEBUGGER) {\n if (this.addrDesc === X86.ADDR_INVALID ||\n this.fExpDown && (off >>> 0) + cb > this.offMax ||\n !this.fExpDown && (off >>> 0) + cb <= this.offMax) {\n return (this.base + off)|0;\n }\n }\n return X86.ADDR_INVALID;\n }\n\n /**\n * checkWriteDebugger(off, cb)\n *\n * @this {SegX86}\n * @param {number} off is a segment-relative offset\n * @param {number} cb is number of bytes to check (1, 2 or 4)\n * @return {number} corresponding linear address if valid, or X86.ADDR_INVALID if error\n */\n checkWriteDebugger(off, cb)\n {\n /*\n * The Debugger doesn't have separate \"check\" interfaces for real and protected mode,\n * since it's not performance-critical. If addrDesc is invalid, then we assume real mode.\n *\n * TODO: This doesn't actually check the segment for writability.\n */\n if (DEBUGGER) {\n if (this.addrDesc === X86.ADDR_INVALID ||\n this.fExpDown && (off >>> 0) + cb > this.offMax ||\n !this.fExpDown && (off >>> 0) + cb <= this.offMax) {\n return (this.base + off)|0;\n }\n }\n return X86.ADDR_INVALID;\n }\n\n /**\n * loadDesc(sel, acc, base, limit)\n *\n * Used to manually load a segment register from the data provided (see LOADALL386).\n *\n * @this {SegX86}\n * @param {number} sel\n * @param {number} acc\n * @param {number} base\n * @param {number} limit\n */\n loadDesc(sel, acc, base, limit)\n {\n this.sel = sel;\n this.base = base;\n this.limit = limit;\n this.offMax = (limit >>> 0) + 1;\n this.acc = acc;\n this.type = (acc & X86.DESC.ACC.TYPE.MASK);\n this.ext = (acc >> 16) & (X86.DESC.EXT.BIG | X86.DESC.EXT.LIMITPAGES);\n\n var addrDT = (sel & X86.SEL.LDT)? this.cpu.segLDT.base : this.cpu.addrGDT;\n this.addrDesc = (addrDT + (sel & X86.SEL.MASK))|0;\n\n /*\n * NOTE: This code must take care to leave the mode of the TSS, LDT, and VER segment registers alone;\n * in particular, we must not allow a real-mode LOADALL to modify their mode, because the rest of PCx86\n * assumes that their mode will never change (they were allocated with fProt set to true).\n */\n if (this.id < SegX86.ID.TSS) this.updateMode(true);\n\n if (DEBUG) this.messageSeg(sel, base, limit, this.type);\n }\n\n /**\n * loadDesc6(addrDesc, sel)\n *\n * Used to load a protected-mode selector that refers to a 6-byte \"descriptor cache\" entry (see LOADALL286):\n *\n * word 0: base address low\n * word 1: base address high (0-7), segment type (8-11), descriptor type (12), DPL (13-14), present bit (15)\n * word 2: segment limit (0-15)\n *\n * @this {SegX86}\n * @param {number} addrDesc is the descriptor address\n * @param {number} sel is the associated selector\n * @return {number} base address of selected segment\n */\n loadDesc6(addrDesc, sel)\n {\n var cpu = this.cpu;\n var acc = cpu.getShort(addrDesc + 2);\n var base = cpu.getShort(addrDesc) | ((acc & 0xff) << 16);\n var limit = cpu.getShort(addrDesc + 4);\n\n this.sel = sel;\n this.base = base;\n this.limit = limit;\n this.offMax = (limit >>> 0) + 1;\n this.acc = acc;\n this.type = (acc & X86.DESC.ACC.TYPE.MASK);\n this.ext = 0;\n this.addrDesc = addrDesc;\n\n /*\n * NOTE: This code must take care to leave the mode of the TSS, LDT, and VER segment registers alone;\n * in particular, we must not allow a real-mode LOADALL to modify their mode, because the rest of PCx86\n * assumes that their mode will never change (they were allocated with fProt set to true).\n */\n if (this.id < SegX86.ID.TSS) this.updateMode(true);\n\n if (DEBUG) this.messageSeg(sel, base, limit, this.type);\n\n return base;\n }\n\n /**\n * loadDesc8(addrDesc, sel, fProbe)\n *\n * Used to load a protected-mode selector that refers to an 8-byte \"descriptor table\" (GDT, LDT, IDT) entry:\n *\n * word 0: segment limit (0-15)\n * word 1: base address low\n * word 2: base address high (0-7), segment type (8-11), descriptor type (12), DPL (13-14), present bit (15)\n * word 3: used only on 80386 and up (should be set to zero for upward compatibility)\n *\n * See X86.DESC for offset and bit definitions.\n *\n * When fProbe is set, we do NOT modify the public properties of the SegX86 object (see class SegX86 above).\n * We will generate a fault if any of the usual error conditions are detected (and return X86.ADDR_INVALID), but\n * otherwise, we merely stash all the descriptor values it reads in the SegX86's private \"probe\" object.\n *\n * Probed loads allow us to deal with complex segment load operations (ie, those involving an implied stack-switch\n * or task-switch), by allowing us to probe all the new selectors and generate the necessary faults before modifying\n * any segment registers; if all the probes succeed, then the original load can proceed.\n *\n * The next non-probed load of a probed selector will move those probed descriptor values into the SegX86 object,\n * saving us from having to reload and reparse the descriptor. However, if a different selector is loaded between\n * the probed and non-probed loads, the probed data is tossed.\n *\n * @this {SegX86}\n * @param {number} addrDesc is the descriptor address\n * @param {number} sel is the associated selector, or nIDT*8 if IDT descriptor\n * @param {boolean} [fProbe] (true if this is a probe)\n * @return {number} base address of selected segment, or X86.ADDR_INVALID if error\n */\n loadDesc8(addrDesc, sel, fProbe)\n {\n var cpu = this.cpu;\n\n /*\n * If the previous load was a successful \"probed\" load of the same segment, then we simply load\n * up all the cached descriptor values from the probe and return.\n */\n if (!fProbe && sel === this.probe.sel) {\n this.sel = sel;\n this.base = this.probe.base;\n this.limit = this.probe.limit;\n this.offMax = (this.probe.limit >>> 0) + 1;\n this.acc = this.probe.acc;\n this.type = this.probe.type;\n this.ext = this.probe.ext;\n this.addrDesc = this.probe.addrDesc;\n this.probe.sel = -1;\n this.updateMode(true, true, false);\n return this.base;\n }\n\n /*\n * Any other load, probed or otherwise, should \"flush\" the probe cache, by setting probe.sel to -1.\n */\n this.probe.sel = -1;\n\n /*\n * Load the descriptor from memory.\n */\n var limit = cpu.getShort(addrDesc + X86.DESC.LIMIT.OFFSET);\n var acc = cpu.getShort(addrDesc + X86.DESC.ACC.OFFSET);\n var type = (acc & X86.DESC.ACC.TYPE.MASK);\n var base = cpu.getShort(addrDesc + X86.DESC.BASE.OFFSET) | ((acc & X86.DESC.ACC.BASE1623) << 16);\n var ext = cpu.getShort(addrDesc + X86.DESC.EXT.OFFSET);\n var selMasked = sel & X86.SEL.MASK;\n\n if (I386 && cpu.model >= X86.MODEL_80386) {\n var limitOrig = limit;\n base |= (ext & X86.DESC.EXT.BASE2431) << 16;\n limit |= (ext & X86.DESC.EXT.LIMIT1619) << 16;\n if (ext & X86.DESC.EXT.LIMITPAGES) limit = (limit << 12) | 0xfff;\n }\n\n switch (this.id) {\n\n case SegX86.ID.CODE:\n\n /*\n * NOTE: Since we are SegX86.ID.CODE, we can use this.cpl instead of the more convoluted\n * this.cpu.segCS.cpl.\n */\n var fCall = this.fCall;\n this.fStackSwitch = false;\n\n /*\n * This special bit of code is currently used only by the Debugger, when it needs to inject\n * a 16:32 callback address into the machine that it can intercept calls to. We call these\n * \"call break\" addresses, because they're essentially breakpoints that only operate when\n * a particular address is called; specifically, an address with selector 0x0001 and an offset\n * that forms a (1-based) index into the aCallBreaks function table.\n *\n * In protected-mode, any null selector, including 0x0001 (null with an RPL of 1), is\n * an invalid CS selector, and while it's not inconceivable that an operating system might\n * use such a selector for some strange purpose, I've not seen such an operating system.\n * And in any case, those operating systems are not likely to trigger the Debugger's call to\n * addCallBreak(), so no call breaks will be generated, and this code will never execute.\n *\n * TODO: If we ever need this to be mode-independent, it can be moved somewhere where it will\n * trigger for both real and protected-mode code segment loads, because CALLBREAK_SEL (0x0001)\n * is also a very unlikely real-mode CS value (but again, not inconceivable). I think this is\n * a reasonable solution, and it's likely the best we can do without injecting code into the\n * machine that we could address -- and even then, it would not be a mode-independent address.\n */\n if (fCall && sel == SegX86.CALLBREAK_SEL && this.aCallBreaks.length) {\n var iBreak = this.offIP - 1;\n var fnCallBreak = this.aCallBreaks[iBreak];\n\n if (fnCallBreak && !fnCallBreak()) {\n return X86.ADDR_INVALID;\n }\n }\n\n var rpl = sel & X86.SEL.RPL;\n var dpl = (acc & X86.DESC.ACC.DPL.MASK) >> X86.DESC.ACC.DPL.SHIFT;\n\n var sizeGate = -1, selCode, cplOld, cplNew, fIDT;\n var addrTSS, offSP, lenSP, regSPPrev, regSSPrev, regPSClear, regSP;\n\n if (!selMasked) {\n /*\n * selMasked is really the descriptor table offset, and a zero offset is fine for the IDT,\n * and it's probably fine for the LDT, but it's definitely NOT fine for the GDT, because\n * that's a reference to the null selector. A null selector is allowed in DS, ES, FS, or GS,\n * but never CS or SS. Since there's no parameter that tells us which table we're using,\n * we have to check manually.\n *\n * If we ARE attempting to load a null selector from the GDT, then we zero type, ensuring that\n * sizeGate will remain invalid (-1), triggering a GP_FAULT below.\n */\n if (addrDesc >= cpu.addrGDT && addrDesc < cpu.addrGDTLimit) type = 0;\n }\n\n if (type >= X86.DESC.ACC.TYPE.CODE_EXECONLY) {\n /*\n * There are three basic ways to load a new code segment (ignoring special cases like LOADALL):\n *\n * 1) CALLF (fCall is true)\n * 2) RETF (fCall is false)\n * 3) JMPF (fCall is undefined)\n *\n * Also, note that if fProbe is set, we're being called on behalf of a gate, in which case the\n * gate logic will examine the relative privileges.\n */\n if (fProbe != null) {\n sizeGate = 0;\n }\n else if (fCall !== false) {\n /*\n * We deal with CALLF/JMPF first. We've already ascertained that the selector type is a\n * segment, not a gate, so the next important distinction is CONFORMING vs. non-CONFORMING.\n *\n * For a CONFORMING target, we must verify that its DPL <= CPL. For a non-CONFORMING target,\n * we must verify that RPL <= CPL and DPL == CPL. Assuming both those tests pass, we must also\n * ensure that the current CPL is recorded as the new RPL (that is, the RPL bits of sel must be\n * updated).\n */\n if (type & X86.DESC.ACC.TYPE.CONFORMING) {\n if (dpl <= this.cpl) {\n sizeGate = 0;\n }\n } else {\n if (rpl <= this.cpl && dpl == this.cpl) {\n sizeGate = 0;\n }\n }\n if (!sizeGate) {\n sel = (sel & ~X86.SEL.RPL) | (this.cpl & X86.SEL.RPL);\n }\n }\n else {\n /*\n * We deal with RETF next. For starters, we must verify that RPL >= CPL. Moreover, if\n * RPL > CPL, then we have a privilege level change that requires a stack switch, assuming\n * the stack selector is acceptable.\n */\n if (rpl >= this.cpl) {\n if (rpl > this.cpl) {\n /*\n * TODO: See if we can defer calling setSS() and setSP() until AFTER the final checks\n * below, because if, for example, the new CS is not PRESENT, we must generate a fault,\n * which in turn must restore the original stack, which means helpRETF() must snapshot\n * the stack registers.\n */\n regSP = cpu.popWord();\n cpu.setSS(cpu.popWord(), true);\n cpu.setSP(regSP);\n this.fStackSwitch = true;\n }\n sizeGate = 0;\n }\n }\n }\n else if (type == X86.DESC.ACC.TYPE.TSS286 || type == X86.DESC.ACC.TYPE.TSS386) {\n if (!this.switchTSS(sel, fCall)) {\n return X86.ADDR_INVALID;\n }\n return this.base;\n }\n else if (type == X86.DESC.ACC.TYPE.GATE_CALL) {\n sizeGate = 2;\n regPSClear = 0;\n if (rpl < this.cpl) rpl = this.cpl; // set RPL to max(RPL,CPL) for call gates\n }\n else if (type == X86.DESC.ACC.TYPE.GATE386_CALL) {\n sizeGate = 4;\n regPSClear = 0;\n if (rpl < this.cpl) rpl = this.cpl; // set RPL to max(RPL,CPL) for call gates\n }\n else if (type == X86.DESC.ACC.TYPE.GATE286_INT) {\n sizeGate = 2;\n regPSClear = (X86.PS.VM | X86.PS.NT | X86.PS.TF | X86.PS.IF);\n\n }\n else if (type == X86.DESC.ACC.TYPE.GATE386_INT) {\n sizeGate = 4;\n regPSClear = (X86.PS.VM | X86.PS.NT | X86.PS.TF | X86.PS.IF);\n\n }\n else if (type == X86.DESC.ACC.TYPE.GATE286_TRAP) {\n sizeGate = 2;\n regPSClear = (X86.PS.VM | X86.PS.NT | X86.PS.TF);\n\n }\n else if (type == X86.DESC.ACC.TYPE.GATE386_TRAP) {\n sizeGate = 4;\n regPSClear = (X86.PS.VM | X86.PS.NT | X86.PS.TF);\n\n }\n else if (type == X86.DESC.ACC.TYPE.GATE_TASK) {\n if (!this.switchTSS(base & 0xffff, fCall)) {\n return X86.ADDR_INVALID;\n }\n return this.base;\n }\n\n if (sizeGate > 0 && !(acc & X86.DESC.ACC.PRESENT)) sizeGate = 0;\n\n if (sizeGate > 0) {\n /*\n * Note that since GATE_INT/GATE_TRAP descriptors should appear in the IDT only, that means sel\n * will actually be nIDT * 8, which means the rpl will always be zero; additionally, the nWords\n * portion of ACC should always be zero, but that's really dependent on the descriptor being properly\n * set (which we assert above).\n */\n cplOld = this.cpl;\n fIDT = (addrDesc == cpu.addrIDT + sel);\n\n /*\n * Software interrupts (where fIDT is true and cpu.nFault < 0) require an additional test:\n * if DPL < CPL, then we must fall into the GP_FAULT code at the end of this case.\n */\n if (rpl <= dpl && (!fIDT || cpu.nFault >= 0 || cplOld <= dpl)) {\n\n /*\n * For gates, there is no \"base\" and \"limit\", but rather \"selector\" and \"offset\"; the selector\n * is located where the first 16 bits of base are normally stored, and the offset comes from the\n * original limit and ext fields.\n *\n * TODO: Verify the PRESENT bit of the gate descriptor, and issue NP_FAULT as appropriate.\n */\n selCode = base & 0xffff;\n if (I386 && (type & X86.DESC.ACC.TYPE.NONSEG_386)) {\n limit = limitOrig | (ext << 16);\n }\n\n var selStack = 0, offStack = 0;\n cplNew = (selCode & X86.SEL.RPL);\n\n /*\n * If a stack switch is required, we must perform \"probed\" loads of both the new selCode\n * and selStack segments, so that if either probe fails, a fault will be generated while the\n * old code segment is still loaded.\n */\n if (cplNew < cplOld) {\n /*\n * Intel pseudo-code suggests that selStack should be \"probed\" before selCode, but it also\n * implies that we need to have the DPL of selCode in order to select the correct selStack,\n * so who knows...?\n */\n if (this.loadProt(selCode, true) === X86.ADDR_INVALID) {\n return X86.ADDR_INVALID;\n }\n /*\n * Intel pseudo-code suggests that the TSS stack pointer offset is based on the DPL of selCode\n * rather than the RPL of selCode. TODO: Check for instances where DPL and RPL of selCode differ,\n * and then figure out which should really be used.\n */\n addrTSS = cpu.segTSS.base;\n if (!I386 || !(cpu.segTSS.type & X86.DESC.ACC.TYPE.NONSEG_386)) {\n offSP = (cplNew << 2) + X86.TSS286.CPL0_SP;\n lenSP = 2;\n } else {\n offSP = (cplNew << 3) + X86.TSS386.CPL0_ESP;\n lenSP = 4;\n }\n selStack = cpu.getShort(addrTSS + offSP + lenSP);\n\n /*\n * Intel pseudo-code indicates at least FIVE discrete selStack tests that could trigger\n * a TS_FAULT at this point:\n *\n * 1) Selector must not be null else #TS(O)\n * 2) Selector index must be within its descriptor table limits else #TS (SS selector)\n * 3) Selector's RPL must equal DPL of code segment else #TS (SS selector)\n * 4) Stack segment DPL must equal DPL of code segment else #TS (SS selector)\n * 5) Descriptor must indicate writable data segment else #TS (SS selector)\n */\n if (!selStack) {\n X86.helpFault.call(cpu, X86.EXCEPTION.TS_FAULT, selStack);\n return X86.ADDR_INVALID;\n }\n\n if (cpu.segSS.loadProt(selStack, true) === X86.ADDR_INVALID) {\n return X86.ADDR_INVALID;\n }\n /*\n * Both probes succeeded, so we can proceed with \"normal\" loads for both selCode and\n * selStack (which should automatically use the values cached by the \"probed\" loads above).\n */\n offStack = (lenSP == 2)? cpu.getShort(addrTSS + offSP) : cpu.getLong(addrTSS + offSP);\n }\n\n /*\n * Now that we're past all the probes, it should be safe to clear all flags that need clearing.\n */\n var regPS = cpu.regPS;\n cpu.regPS &= ~regPSClear;\n if (regPS & X86.PS.VM) {\n cpu.setProtMode(true, false);\n }\n\n /*\n * TODO: Consider whether we can skip this loadProt() call if this.sel already contains selCode\n * (and the previous mode matches, which might require we cache the mode in the SegX86 object, too).\n */\n if (this.loadProt(selCode, false) === X86.ADDR_INVALID) {\n return X86.ADDR_INVALID;\n }\n\n cpu.setDataSize(sizeGate);\n\n this.offIP = limit;\n\n //\n\n if (cplNew < cplOld) {\n\n if (fCall !== true) {\n\n return X86.ADDR_INVALID;\n }\n\n regSP = cpu.getSP();\n var i = 0, nWords = (acc & 0x1f);\n while (nWords--) {\n this.awParms[i++] = cpu.getSOWord(cpu.segSS, regSP);\n regSP += 2;\n }\n\n regSSPrev = cpu.getSS();\n regSPPrev = cpu.getSP();\n\n cpu.setSS(selStack, true);\n cpu.setSP(offStack);\n\n if (regPS & X86.PS.VM) {\n /*\n * Frames coming from V86-mode ALWAYS contain 32-bit values, and look like this:\n *\n * low: EIP\n * CS (upper 16 bits undefined)\n * EFLAGS\n * ESP\n * SS (upper 16 bits undefined)\n * ES (upper 16 bits undefined)\n * DS (upper 16 bits undefined)\n * FS (upper 16 bits undefined)\n * high: GS (upper 16 bits undefined)\n *\n * Our caller (eg, helpINT()) will take care of pushing the final bits (EFLAGS, CS, and EIP).\n */\n cpu.setDataSize(4);\n\n cpu.pushData(cpu.segGS.sel, 4, 2);\n cpu.setGS(0);\n cpu.pushData(cpu.segFS.sel, 4, 2);\n cpu.setFS(0);\n cpu.pushData(cpu.segDS.sel, 4, 2);\n cpu.setDS(0);\n cpu.pushData(cpu.segES.sel, 4, 2);\n cpu.setES(0);\n }\n cpu.pushData(regSSPrev, cpu.sizeData, 2);\n cpu.pushWord(regSPPrev);\n while (i) cpu.pushWord(this.awParms[--i]);\n this.fStackSwitch = true;\n }\n return this.base;\n }\n }\n\n if (sizeGate != 0) {\n X86.helpFault.call(cpu, X86.EXCEPTION.GP_FAULT, (sel & X86.ERRCODE.SELMASK) | (fIDT? X86.ERRCODE.IDT : 0));\n return X86.ADDR_INVALID;\n }\n\n if (!(acc & X86.DESC.ACC.PRESENT)) {\n X86.helpFault.call(cpu, X86.EXCEPTION.NP_FAULT, (sel & X86.ERRCODE.SELMASK) | (fIDT? X86.ERRCODE.IDT : 0));\n return X86.ADDR_INVALID;\n }\n break;\n\n case SegX86.ID.DATA:\n if (selMasked) {\n /*\n * OS/2 1.0 faults on segments with \"empty descriptors\" multiple times during boot; for example:\n *\n * Fault 0x0B (0x002C) on opcode 0x8E at 3190:3A05 (%112625)\n * AX=0000 BX=0970 CX=0300 DX=0300 SP=0ABE BP=0ABA SI=0000 DI=001A\n * SS=0038[175CE0,0B5F] DS=19C0[177300,2C5F] ES=001F[1743A0,07FF] A20=ON\n * CS=3190[10EC20,B89F] LD=0028[174BC0,003F] GD=[11A4E0,490F] ID=[11F61A,03FF]\n * TR=0010 MS=0000FFF3 PS=3256 V0 D0 I1 T0 S0 Z1 A1 P1 C0\n * 3190:3A05 8E4604 MOV ES,[BP+04]\n * ## dw ss:bp+4 l1\n * 0038:0ABE 002F 19C0 0000 067C 07FC 0AD2 0010 C420 /.....|....... .\n * ## ds 2f\n * dumpDesc(0x002F): %174BE8\n * base=000000 limit=0000 type=0x00 (undefined) ext=0x0000 dpl=0x00\n *\n * And Windows 95 Setup, during the \"Analyzing Your Computer\" phase, will fault on an attempt to load\n * a GDT selector of type LDT (why it does this is a mystery I've not yet investigated):\n *\n * Fault 0x0D (0x26F0) on opcode 0x8E @039F:039B (%199E9B)\n * EAX=0000149F EBX=00000100 ECX=000026F3 EDX=0020149F\n * ESP=0000AA34 EBP=0000AA3C ESI=000026E7 EDI=00000080\n * SS=155F[002AC9D0,C0BF] DS=149F[0031B470,9B1F] ES=0237[000C0000,FFFF]\n * CS=039F[00199B00,2ABF] FS=0000[00000000,0000] GS=0000[00000000,0000]\n * LD=0038[00FA4C50,FFEF] GD=[00FA0800,011F] ID=[00FA0000,07FF] TR=0088 A20=ON\n * CR0=0000FFF1 CR2=00000000 CR3=00000000 PS=00003246 V0 D0 I1 T0 S0 Z1 A0 P1 C0\n * 039F:039B 8EC1 MOV ES,CX\n * ## ds cx\n * dumpDesc(0x26F3): %00FA2EF0\n * base=0006C726 limit=0000 type=0x02 (ldt,not present) ext=0x0000 dpl=0x00\n *\n * In both cases, the segment type is not valid for the target segment register *and* the PRESENT bit\n * is clear. OS/2 doesn't seem to care whether I report an NP_FAULT or GP_FAULT, but Windows 95 definitely\n * cares: it will resolve the fault only if a GP_FAULT is reported. And Intel's 80386 Programmers Reference\n * implies that, yes, GP_FAULT checks are supposed to be performed *before* NP_FAULT checks.\n */\n if (type < X86.DESC.ACC.TYPE.SEG || (type & (X86.DESC.ACC.TYPE.CODE | X86.DESC.ACC.TYPE.READABLE)) == X86.DESC.ACC.TYPE.CODE) {\n X86.helpFault.call(cpu, X86.EXCEPTION.GP_FAULT, sel & X86.ERRCODE.SELMASK);\n return X86.ADDR_INVALID;\n }\n /*\n * TODO: This would be a good place to perform some additional access rights checks, too.\n */\n if (!(acc & X86.DESC.ACC.PRESENT)) {\n X86.helpFault.call(cpu, X86.EXCEPTION.NP_FAULT, sel & X86.ERRCODE.SELMASK);\n return X86.ADDR_INVALID;\n }\n }\n break;\n\n case SegX86.ID.STACK:\n if (!selMasked || type < X86.DESC.ACC.TYPE.SEG || (type & (X86.DESC.ACC.TYPE.CODE | X86.DESC.ACC.TYPE.WRITABLE)) != X86.DESC.ACC.TYPE.WRITABLE) {\n X86.helpFault.call(cpu, X86.EXCEPTION.GP_FAULT, sel & X86.ERRCODE.SELMASK);\n return X86.ADDR_INVALID;\n }\n if (!(acc & X86.DESC.ACC.PRESENT)) {\n X86.helpFault.call(cpu, X86.EXCEPTION.SS_FAULT, sel & X86.ERRCODE.SELMASK);\n return X86.ADDR_INVALID;\n }\n break;\n\n case SegX86.ID.TSS:\n var typeTSS = type & ~X86.DESC.ACC.TYPE.TSS_BUSY;\n if (!selMasked || typeTSS != X86.DESC.ACC.TYPE.TSS286 && typeTSS != X86.DESC.ACC.TYPE.TSS386) {\n X86.helpFault.call(cpu, X86.EXCEPTION.GP_FAULT, sel & X86.ERRCODE.SELMASK);\n return X86.ADDR_INVALID;\n }\n /*\n * For more efficient IOPM lookups, we cache the starting linear address in segTSS.addrIOPM, and the\n * last valid address in segTSS.addrIOPMLimit.\n */\n if (typeTSS == X86.DESC.ACC.TYPE.TSS386) {\n this.addrIOPM = (base + cpu.getShort(base + X86.TSS386.TASK_IOPM + 2))|0;\n this.addrIOPMLimit = (base + this.limit)|0;\n }\n break;\n\n case SegX86.ID.VER:\n /*\n * For LSL, we must support any descriptor marked X86.DESC.ACC.TYPE.SEG, as well as TSS and LDT descriptors.\n */\n if (!(type & X86.DESC.ACC.TYPE.SEG) && type > X86.DESC.ACC.TYPE.TSS286_BUSY && type != X86.DESC.ACC.TYPE.TSS386 && type != X86.DESC.ACC.TYPE.TSS386_BUSY) {\n return X86.ADDR_INVALID;\n }\n break;\n\n default:\n /*\n * The only other cases are:\n *\n * SegX86.ID.NULL, SegX86.ID.LDT, and SegX86.ID.DBG\n *\n * which correspond to segNULL, segLDT and segDebugger; however, segLDT is the only one that might require further validation (TODO: Investigate).\n */\n break;\n }\n\n if (fProbe) {\n this.probe.sel = sel;\n this.probe.base = base;\n this.probe.limit = limit;\n this.probe.acc = acc;\n this.probe.type = type;\n this.probe.ext = ext;\n this.probe.addrDesc = addrDesc;\n } else {\n this.sel = sel;\n this.base = base;\n this.limit = limit;\n this.offMax = (limit >>> 0) + 1;\n this.acc = acc;\n this.type = type;\n this.ext = ext;\n this.addrDesc = addrDesc;\n /*\n * A quick recap of what updateMode(fLoad=true, fProt=true, fV86=false) actually updates:\n *\n * cpl\n * dpl\n * dataSize\n * dataMask\n * addrSize\n * addrMask\n * fExpDown\n * load()\n * loadIDT()\n * checkRead()\n * checkWrite()\n */\n this.updateMode(true, true, false);\n }\n\n if (DEBUG) this.messageSeg(sel, base, limit, type, ext);\n\n return base;\n }\n\n /**\n * switchTSS(selNew, fNest)\n *\n * Implements TSS (Task State Segment) task switching.\n *\n * NOTES: This typically occurs during double-fault processing, because the IDT entry for DF_FAULT normally\n * contains a task gate. Interestingly, if we force a GP_FAULT to occur at a sufficiently early point in the\n * OS/2 1.0 initialization code, OS/2 does a nice job of displaying the GP fault and then shutting down:\n *\n * 0090:067B FB STI\n * 0090:067C EBFD JMP 067B\n *\n * but it may not have yet reprogrammed the master PIC to re-vector hardware interrupts to IDT entries 0x50-0x57,\n * so when the next timer interrupt (IRQ 0) occurs, it vectors through IDT entry 0x08, which is the DF_FAULT\n * vector. A spurious double-fault is generated, and a clean shutdown turns into a messy crash.\n *\n * Of course, that all could have been avoided if IBM had heeded Intel's advice and not used Intel-reserved IDT\n * entries for PC interrupts.\n *\n * TODO: Add TSS validity checks and appropriate generation of TS_FAULT exceptions; the only rudimentary checks\n * we currently perform are of the GP_FAULT variety.\n *\n * @this {SegX86}\n * @param {number} selNew\n * @param {boolean|null} [fNest] is true if nesting, false if un-nesting, null if neither\n * @return {boolean} true if successful, false if error\n */\n switchTSS(selNew, fNest)\n {\n var cpu = this.cpu;\n\n\n var cplOld = this.cpl;\n var selOld = cpu.segTSS.sel;\n var addrOld = cpu.segTSS.base;\n\n if (!fNest) {\n /*\n * TODO: Verify that it is (always) correct to require that the BUSY bit be currently set.\n */\n if (!(cpu.segTSS.type & X86.DESC.ACC.TYPE.TSS_BUSY)) {\n X86.helpFault.call(cpu, X86.EXCEPTION.GP_FAULT, selNew & X86.ERRCODE.SELMASK);\n return false;\n }\n /*\n * TODO: Should I be more paranoid about writing our cached ACC value back into the descriptor?\n */\n cpu.setShort(cpu.segTSS.addrDesc + X86.DESC.ACC.OFFSET, cpu.segTSS.acc &= ~X86.DESC.ACC.TYPE.TSS_BUSY);\n }\n\n if (cpu.segTSS.load(selNew) === X86.ADDR_INVALID) {\n return false;\n }\n\n var addrNew = cpu.segTSS.base;\n if (DEBUG && DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages.TSS)) {\n this.dbg.message((fNest? \"Task switch\" : \"Task return\") + \": TR \" + Str.toHexWord(selOld) + \" (%\" + Str.toHex(addrOld, 6) + \"), new TR \" + Str.toHexWord(selNew) + \" (%\" + Str.toHex(addrNew, 6) + \")\");\n }\n\n if (fNest !== false) {\n if (cpu.segTSS.type & X86.DESC.ACC.TYPE.TSS_BUSY) {\n X86.helpFault.call(cpu, X86.EXCEPTION.GP_FAULT, selNew & X86.ERRCODE.SELMASK);\n return false;\n }\n cpu.setShort(cpu.segTSS.addrDesc + X86.DESC.ACC.OFFSET, cpu.segTSS.acc |= X86.DESC.ACC.TYPE.TSS_BUSY);\n }\n\n /*\n * Now that we're done checking the TSS_BUSY bit in the TYPE field (which is a subset of the ACC field),\n * sync any changes made above in the ACC field to the TYPE field.\n */\n cpu.segTSS.type = (cpu.segTSS.type & ~X86.DESC.ACC.TYPE.TSS_BUSY) | (cpu.segTSS.acc & X86.DESC.ACC.TYPE.TSS_BUSY);\n\n /*\n * Update the old TSS\n */\n var offSS, offSP;\n if (cpu.segTSS.type == X86.DESC.ACC.TYPE.TSS286 || cpu.segTSS.type == X86.DESC.ACC.TYPE.TSS286_BUSY) {\n cpu.setShort(addrOld + X86.TSS286.TASK_IP, cpu.getIP());\n cpu.setShort(addrOld + X86.TSS286.TASK_PS, cpu.getPS());\n cpu.setShort(addrOld + X86.TSS286.TASK_AX, cpu.regEAX);\n cpu.setShort(addrOld + X86.TSS286.TASK_CX, cpu.regECX);\n cpu.setShort(addrOld + X86.TSS286.TASK_DX, cpu.regEDX);\n cpu.setShort(addrOld + X86.TSS286.TASK_BX, cpu.regEBX);\n cpu.setShort(addrOld + X86.TSS286.TASK_SP, cpu.getSP());\n cpu.setShort(addrOld + X86.TSS286.TASK_BP, cpu.regEBP);\n cpu.setShort(addrOld + X86.TSS286.TASK_SI, cpu.regESI);\n cpu.setShort(addrOld + X86.TSS286.TASK_DI, cpu.regEDI);\n cpu.setShort(addrOld + X86.TSS286.TASK_ES, cpu.segES.sel);\n cpu.setShort(addrOld + X86.TSS286.TASK_CS, cpu.segCS.sel);\n cpu.setShort(addrOld + X86.TSS286.TASK_SS, cpu.segSS.sel);\n cpu.setShort(addrOld + X86.TSS286.TASK_DS, cpu.segDS.sel);\n /*\n * Reload all registers from the new TSS; it's important to reload the LDTR sooner\n * rather than later, so that as segment registers are reloaded, any LDT selectors will\n * will be located in the correct table.\n */\n cpu.segLDT.load(cpu.getShort(addrNew + X86.TSS286.TASK_LDT));\n cpu.setPS(cpu.getShort(addrNew + X86.TSS286.TASK_PS) | (fNest? X86.PS.NT : 0));\n\n cpu.regEAX = cpu.getShort(addrNew + X86.TSS286.TASK_AX);\n cpu.regECX = cpu.getShort(addrNew + X86.TSS286.TASK_CX);\n cpu.regEDX = cpu.getShort(addrNew + X86.TSS286.TASK_DX);\n cpu.regEBX = cpu.getShort(addrNew + X86.TSS286.TASK_BX);\n cpu.regEBP = cpu.getShort(addrNew + X86.TSS286.TASK_BP);\n cpu.regESI = cpu.getShort(addrNew + X86.TSS286.TASK_SI);\n cpu.regEDI = cpu.getShort(addrNew + X86.TSS286.TASK_DI);\n cpu.segES.load(cpu.getShort(addrNew + X86.TSS286.TASK_ES));\n cpu.segDS.load(cpu.getShort(addrNew + X86.TSS286.TASK_DS));\n cpu.setCSIP(cpu.getShort(addrNew + X86.TSS286.TASK_IP), cpu.getShort(addrNew + X86.TSS286.TASK_CS));\n offSS = X86.TSS286.TASK_SS;\n offSP = X86.TSS286.TASK_SP;\n if (this.cpl < cplOld) {\n offSP = (this.cpl << 2) + X86.TSS286.CPL0_SP;\n offSS = offSP + 2;\n }\n cpu.setSS(cpu.getShort(addrNew + offSS), true);\n cpu.setSP(cpu.getShort(addrNew + offSP));\n } else {\n\n cpu.setLong(addrOld + X86.TSS386.TASK_CR3, cpu.regCR3);\n cpu.setLong(addrOld + X86.TSS386.TASK_EIP, cpu.getIP());\n cpu.setLong(addrOld + X86.TSS386.TASK_PS, cpu.getPS());\n cpu.setLong(addrOld + X86.TSS386.TASK_EAX, cpu.regEAX);\n cpu.setLong(addrOld + X86.TSS386.TASK_ECX, cpu.regECX);\n cpu.setLong(addrOld + X86.TSS386.TASK_EDX, cpu.regEDX);\n cpu.setLong(addrOld + X86.TSS386.TASK_EBX, cpu.regEBX);\n cpu.setLong(addrOld + X86.TSS386.TASK_ESP, cpu.getSP());\n cpu.setLong(addrOld + X86.TSS386.TASK_EBP, cpu.regEBP);\n cpu.setLong(addrOld + X86.TSS386.TASK_ESI, cpu.regESI);\n cpu.setLong(addrOld + X86.TSS386.TASK_EDI, cpu.regEDI);\n cpu.setLong(addrOld + X86.TSS386.TASK_ES, cpu.segES.sel);\n cpu.setLong(addrOld + X86.TSS386.TASK_CS, cpu.segCS.sel);\n cpu.setLong(addrOld + X86.TSS386.TASK_SS, cpu.segSS.sel);\n cpu.setLong(addrOld + X86.TSS386.TASK_DS, cpu.segDS.sel);\n\n /*\n * segFS and segGS exist only on 80386 machines\n */\n\n cpu.setLong(addrOld + X86.TSS386.TASK_FS, cpu.segFS.sel);\n cpu.setLong(addrOld + X86.TSS386.TASK_GS, cpu.segGS.sel);\n\n /*\n * Reload all registers from the new TSS; it's important to reload the LDTR sooner\n * rather than later, so that as segment registers are reloaded, any LDT selectors will\n * will be located in the correct table.\n */\n X86.helpLoadCR3.call(cpu, cpu.getLong(addrNew + X86.TSS386.TASK_CR3));\n cpu.segLDT.load(cpu.getShort(addrNew + X86.TSS386.TASK_LDT));\n cpu.setPS(cpu.getLong(addrNew + X86.TSS386.TASK_PS) | (fNest? X86.PS.NT : 0));\n\n cpu.regEAX = cpu.getLong(addrNew + X86.TSS386.TASK_EAX);\n cpu.regECX = cpu.getLong(addrNew + X86.TSS386.TASK_ECX);\n cpu.regEDX = cpu.getLong(addrNew + X86.TSS386.TASK_EDX);\n cpu.regEBX = cpu.getLong(addrNew + X86.TSS386.TASK_EBX);\n cpu.regEBP = cpu.getLong(addrNew + X86.TSS386.TASK_EBP);\n cpu.regESI = cpu.getLong(addrNew + X86.TSS386.TASK_ESI);\n cpu.regEDI = cpu.getLong(addrNew + X86.TSS386.TASK_EDI);\n cpu.segES.load(cpu.getShort(addrNew + X86.TSS386.TASK_ES));\n cpu.segDS.load(cpu.getShort(addrNew + X86.TSS386.TASK_DS));\n\n /*\n * segFS and segGS exist only on 80386 machines\n */\n\n cpu.segFS.load(cpu.getShort(addrNew + X86.TSS386.TASK_FS));\n cpu.segGS.load(cpu.getShort(addrNew + X86.TSS386.TASK_GS));\n\n cpu.setCSIP(cpu.getLong(addrNew + X86.TSS386.TASK_EIP), cpu.getShort(addrNew + X86.TSS386.TASK_CS));\n offSS = X86.TSS386.TASK_SS;\n offSP = X86.TSS386.TASK_ESP;\n if (this.cpl < cplOld) {\n offSP = (this.cpl << 3) + X86.TSS386.CPL0_ESP;\n offSS = offSP + 4;\n }\n cpu.setSS(cpu.getShort(addrNew + offSS), true);\n cpu.setSP(cpu.getLong(addrNew + offSP));\n }\n\n /*\n * Fortunately, X86.TSS286.PREV_TSS and X86.TSS386.PREV_TSS refer to the same TSS offset.\n */\n if (fNest) cpu.setShort(addrNew + X86.TSS286.PREV_TSS, selOld);\n\n cpu.regCR0 |= X86.CR0.MSW.TS;\n return true;\n }\n\n /**\n * setBase(addr)\n *\n * This is used in unusual situations where the base must be set independently; normally, the base is\n * set according to the selector provided to load(), but there are a few cases where setBase() is required.\n *\n * For example, in resetRegs(), the real-mode CS selector must be reset to 0xF000 for an 80286 or 80386,\n * but the CS base must be set to 0x00FF0000 or 0xFFFF0000, respectively. To simplify life for setBase()\n * callers, we allow them to specify 32-bit bases, which we then truncate to 24 bits as needed.\n *\n * WARNING: Since the CPU must maintain regLIP as the sum of the CS base and the current IP, all calls\n * to segCS.setBase() need to go through cpu.setCSBase().\n *\n * @this {SegX86}\n * @param {number} addr\n * @return {number} addr, truncated as needed\n */\n setBase(addr)\n {\n if (this.cpu.model < X86.MODEL_80386) addr &= 0xffffff;\n return this.base = addr;\n }\n\n /**\n * save()\n *\n * Early versions of PCx86 saved only segment selectors, since that's all that mattered in real-mode;\n * newer versions need to save/restore all the \"core\" properties of the SegX86 object (ie, properties other\n * than those that updateMode() will take care of restoring later).\n *\n * @this {SegX86}\n * @return {Array}\n */\n save()\n {\n return [\n this.sel,\n this.base,\n this.limit,\n this.acc,\n this.id,\n this.sName,\n this.cpl,\n this.dpl,\n this.addrDesc,\n this.sizeAddr,\n this.maskAddr,\n this.sizeData,\n this.maskData,\n this.type,\n this.offMax\n ];\n }\n\n /**\n * restore(a)\n *\n * Early versions of PCx86 saved only segment selectors, since that's all that mattered in real-mode;\n * newer versions need to save/restore all the \"core\" properties of the SegX86 object (ie, properties other\n * than those that updateMode() will take care of restoring later).\n *\n * @this {SegX86}\n * @param {Array|number} a\n */\n restore(a)\n {\n if (typeof a == \"number\") {\n this.load(a);\n } else {\n this.sel = a[0];\n this.base = a[1];\n this.limit = a[2];\n this.acc = a[3];\n this.id = a[4];\n this.sName = a[5];\n this.cpl = a[6];\n this.dpl = a[7];\n this.addrDesc = a[8];\n this.sizeAddr = a[9] || 2;\n this.maskAddr = a[10] || 0xffff;\n this.sizeData = a[11] || 2;\n this.maskData = a[12] || 0xffff;\n this.type = a[13] || (this.acc & X86.DESC.ACC.TYPE.MASK);\n this.offMax = a[14] || (this.limit >>> 0) + 1;\n }\n }\n\n /**\n * updateMode(fLoad, fProt, fV86)\n *\n * Ensures that the segment register's access (ie, load and check methods) matches the specified (or current)\n * operating mode (real or protected).\n *\n * @this {SegX86}\n * @param {boolean} [fLoad] true if the segment was just (re)loaded, false if not\n * @param {boolean} [fProt] true for protected-mode access, false for real-mode access, undefined for current mode\n * @param {boolean} [fV86] true for V86-mode access, false for protected-mode access, undefined for current mode\n */\n updateMode(fLoad, fProt, fV86)\n {\n if (fProt === undefined) {\n fProt = !!(this.cpu.regCR0 & X86.CR0.MSW.PE);\n }\n\n /*\n * The fExpDown property is used for STACK segments only (ie, segSS); we want to make it easier for\n * setSS() to set stack lower and upper limits, which requires knowing whether or not the segment is\n * marked as EXPDOWN.\n */\n this.fExpDown = false;\n\n if (fProt) {\n this.load = this.loadProt;\n this.loadIDT = this.loadIDTProt;\n this.checkRead = this.checkReadProt;\n this.checkWrite = this.checkWriteProt;\n\n if (fV86 === undefined) {\n fV86 = !!(this.cpu.regPS & X86.PS.VM);\n }\n\n if (fV86) {\n this.load = this.loadV86;\n this.checkRead = this.checkReadV86;\n this.checkWrite = this.checkWriteV86;\n /*\n * One important feature of V86-mode (as compared to real-mode) are that other segment attributes\n * (eg, limit, operand size, address size, etc) ARE updated, whereas in real-mode, segment attributes\n * remain set to whatever was in effect in protected-mode.\n */\n this.cpl = this.dpl = 3;\n this.sizeData = this.sizeAddr = 2;\n this.maskData = this.maskAddr = 0xffff;\n this.limit = 0xffff;\n this.offMax = this.limit + 1;\n this.sizeAddr = this.sizeData;\n this.addrDesc = X86.ADDR_INVALID;\n this.fStackSwitch = false;\n return;\n }\n\n /*\n * TODO: For null GDT selectors, should we rely on the descriptor being invalid, or should we assume that\n * the null descriptor might contain uninitialized (or other) data? I'm assuming the latter, hence the\n * following null selector test. However, if we're not going to consult the descriptor, is there anything\n * else we should (or should not) be doing for null GDT selectors?\n */\n if (!(this.sel & ~X86.SEL.RPL)) {\n this.checkRead = this.checkReadProtDisallowed;\n this.checkWrite = this.checkWriteProtDisallowed;\n\n }\n else if (this.type & X86.DESC.ACC.TYPE.SEG) {\n /*\n * If the READABLE bit of CODE_READABLE is not set, then disallow reads.\n */\n if ((this.type & X86.DESC.ACC.TYPE.CODE_READABLE) == X86.DESC.ACC.TYPE.CODE_EXECONLY) {\n this.checkRead = this.checkReadProtDisallowed;\n }\n /*\n * If the CODE bit is set, or the the WRITABLE bit is not set, then disallow writes.\n */\n if ((this.type & X86.DESC.ACC.TYPE.CODE) || !(this.type & X86.DESC.ACC.TYPE.WRITABLE)) {\n this.checkWrite = this.checkWriteProtDisallowed;\n }\n /*\n * If the CODE bit is not set *and* the EXPDOWN bit is set, then invert the limit check.\n */\n if ((this.type & (X86.DESC.ACC.TYPE.CODE | X86.DESC.ACC.TYPE.EXPDOWN)) == X86.DESC.ACC.TYPE.EXPDOWN) {\n if (this.checkRead == this.checkReadProt) this.checkRead = this.checkReadProtDown;\n if (this.checkWrite == this.checkWriteProt) this.checkWrite = this.checkWriteProtDown;\n this.fExpDown = true;\n }\n if (fLoad && this.id < SegX86.ID.VER) {\n /*\n * We must update the descriptor's ACCESSED bit whenever the segment is \"accessed\" (ie,\n * loaded); unlike the ACCESSED and DIRTY bits in PTEs, a descriptor ACCESSED bit is only\n * updated on loads, not on every memory access.\n *\n * We compute the address of the descriptor byte containing the ACCESSED bit (offset 0x5);\n * note that it's perfectly normal for addrDesc to occasionally be invalid (eg, when the CPU\n * is creating protected-mode-only segment registers like LDT and TSS, or when the CPU has\n * transitioned from real-mode to protected-mode and new selector(s) have not been loaded yet).\n *\n * NOTE: I do NOT update the ACCESSED bit for null GDT selectors, because I'm assuming the\n * hardware does not update it either. In fact, I've seen code that uses the null GDT descriptor\n * for other purposes, on the assumption that that descriptor is completely unused.\n */\n if ((this.sel & ~X86.SEL.RPL) && this.addrDesc !== X86.ADDR_INVALID) {\n var addrType = this.addrDesc + X86.DESC.ACC.TYPE.OFFSET;\n var bType = this.cpu.getByte(addrType);\n /*\n * This code used to ALWAYS call setByte(), but that's a waste of time if ACCESSED is already\n * set. TODO: It would also be nice if we could simply use the cached type value, and eliminate\n * the getByte() call; that seems a bit risky, but I think we should still try it someday.\n */\n if (!(bType & (X86.DESC.ACC.TYPE.ACCESSED >> 8))) {\n this.cpu.setByte(addrType, bType | (X86.DESC.ACC.TYPE.ACCESSED >> 8));\n }\n }\n }\n }\n\n /*\n * TODO: For non-SEG descriptors, are there other checks or functions we should establish?\n */\n\n /*\n * Any update to the following properties must occur only on segment loads, not simply when\n * we're updating segment registers as part of a mode change.\n */\n if (fLoad) {\n this.cpl = this.sel & X86.SEL.RPL;\n this.dpl = (this.acc & X86.DESC.ACC.DPL.MASK) >> X86.DESC.ACC.DPL.SHIFT;\n if (this.cpu.model < X86.MODEL_80386 || !(this.ext & X86.DESC.EXT.BIG)) {\n this.sizeData = 2;\n this.maskData = 0xffff;\n } else {\n this.sizeData = 4;\n this.maskData = (0xffffffff|0);\n }\n this.sizeAddr = this.sizeData;\n this.maskAddr = this.maskData;\n }\n return;\n }\n /*\n * One important feature of real-mode (as compared to V86-mode) are that other segment attributes\n * (eg, limit, operand size, address size, etc) are NOT updated, enabling features like \"big real-mode\"\n * (aka \"unreal mode\"), which is used by system software like HIMEM.SYS to access extended memory from\n * real-mode.\n */\n this.load = this.loadReal;\n this.loadIDT = this.loadIDTReal;\n this.checkRead = this.checkReadWriteReal;\n this.checkWrite = this.checkReadWriteReal;\n this.cpl = this.dpl = 0;\n this.addrDesc = X86.ADDR_INVALID;\n this.fStackSwitch = false;\n }\n\n /**\n * messageSeg(sel, base, limit, type, ext)\n *\n * @this {SegX86}\n * @param {number} sel\n * @param {number} base\n * @param {number} limit\n * @param {number} type\n * @param {number} [ext]\n */\n messageSeg(sel, base, limit, type, ext)\n {\n if (DEBUG) {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages.SEG)) {\n var ch = (this.sName.length < 3? \" \" : \"\");\n var sDPL = \" dpl=\" + this.dpl;\n if (this.id == SegX86.ID.CODE) sDPL += \" cpl=\" + this.cpl;\n this.dbg.message(\"loadSeg(\" + this.sName + \"):\" + ch + \"sel=\" + Str.toHexWord(sel) + \" base=\" + Str.toHex(base) + \" limit=\" + Str.toHexWord(limit) + \" type=\" + Str.toHexWord(type) + sDPL, true);\n }\n /*\n * Unless I've got a bug that's causing descriptor corruption, it appears that Windows 3.0 may be setting the\n * EXT field of descriptors, even when the processor is an 80286; eg, the EXT field below has been set to 0x000F:\n *\n * ## ds 1bd\n * dumpSel(0x01BD): %1101B8\n * %001101B8 FFFF C090 B317 000F\n *\n * So I've disabled this assert (I had already disabled the \"base !== X86.ADDR_INVALID\" check).\n *\n *\n */\n }\n }\n\n /**\n * probeDesc(sel)\n *\n * This is a neutered version of loadProt() designed for the Debugger.\n *\n * @this {SegX86}\n * @param {number} sel\n * @return {number} base address of selected segment, or X86.ADDR_INVALID if error\n */\n probeDesc(sel)\n {\n if (DEBUGGER) {\n var addrDT;\n var addrDTLimit;\n var cpu = this.cpu;\n\n sel &= 0xffff;\n\n if (!(sel & X86.SEL.LDT)) {\n addrDT = cpu.addrGDT;\n addrDTLimit = cpu.addrGDTLimit;\n } else {\n addrDT = cpu.segLDT.base;\n addrDTLimit = (addrDT + cpu.segLDT.limit)|0;\n }\n\n var addrDesc = (addrDT + (sel & X86.SEL.MASK))|0;\n\n if ((addrDTLimit - addrDesc)|0 >= 7) {\n\n /*\n * Load the descriptor from memory using probeAddr().\n */\n var limit = cpu.probeAddr(addrDesc + X86.DESC.LIMIT.OFFSET, 2);\n var acc = cpu.probeAddr(addrDesc + X86.DESC.ACC.OFFSET, 2);\n var type = (acc & X86.DESC.ACC.TYPE.MASK);\n var base = cpu.probeAddr(addrDesc + X86.DESC.BASE.OFFSET, 2) | ((acc & X86.DESC.ACC.BASE1623) << 16);\n var ext = cpu.probeAddr(addrDesc + X86.DESC.EXT.OFFSET, 2);\n\n if (I386 && cpu.model >= X86.MODEL_80386) {\n base |= (ext & X86.DESC.EXT.BASE2431) << 16;\n limit |= (ext & X86.DESC.EXT.LIMIT1619) << 16;\n if (ext & X86.DESC.EXT.LIMITPAGES) limit = (limit << 12) | 0xfff;\n }\n\n this.sel = sel;\n this.base = base;\n this.limit = limit;\n this.offMax = (limit >>> 0) + 1;\n this.acc = acc;\n this.type = type;\n this.ext = ext;\n this.addrDesc = addrDesc;\n this.updateMode(true, true, false);\n return base;\n }\n }\n return X86.ADDR_INVALID;\n }\n\n /**\n * loadAcc(sel, fGDT)\n *\n * this {SegX86}\n * param {number} sel (protected-mode only)\n * param {boolean} [fGDT] is true if sel must be in the GDT\n * return {number} ACC field from descriptor, or X86.DESC.ACC.INVALID if error\n *\n loadAcc(sel, fGDT)\n {\n var addrDT;\n var addrDTLimit;\n var cpu = this.cpu;\n\n if (!(sel & X86.SEL.LDT)) {\n addrDT = cpu.addrGDT;\n addrDTLimit = cpu.addrGDTLimit;\n } else if (!fGDT) {\n addrDT = cpu.segLDT.base;\n addrDTLimit = (addrDT + cpu.segLDT.limit)|0;\n }\n if (addrDT !== undefined) {\n var addrDesc = (addrDT + (sel & X86.SEL.MASK))|0;\n if (((addrDTLimit - addrDesc)|0) >= 7) {\n return cpu.getShort(addrDesc + X86.DESC.ACC.OFFSET);\n }\n }\n X86.helpFault.call(cpu, X86.EXCEPTION.GP_FAULT, sel & X86.ERRCODE.SELMASK);\n return X86.DESC.ACC.INVALID;\n }\n */\n}\n\nSegX86.ID = {\n NULL: 0, // \"NULL\"\n CODE: 1, // \"CS\"\n DATA: 2, // \"DS\", \"ES\", \"FS\", \"GS\"\n STACK: 3, // \"SS\"\n TSS: 4, // \"TSS\"\n LDT: 5, // \"LDT\"\n VER: 6, // \"VER\"\n DBG: 7 // \"DBG\"\n};\n\nSegX86.CALLBREAK_SEL = 0x0001;\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/x86func.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * fnADCb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnADCb = function(dst, src)\n{\n var b = (dst + src + this.getCarry())|0;\n this.setArithResult(dst, src, b, X86.RESULT.BYTE | X86.RESULT.ALL);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return b & 0xff;\n};\n\n/**\n * fnADCw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnADCw = function(dst, src)\n{\n var w = (dst + src + this.getCarry())|0;\n this.setArithResult(dst, src, w, this.typeData | X86.RESULT.ALL);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return w & this.maskData;\n};\n\n/**\n * fnADDb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnADDb = function(dst, src)\n{\n var b = (dst + src)|0;\n this.setArithResult(dst, src, b, X86.RESULT.BYTE | X86.RESULT.ALL);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return b & 0xff;\n};\n\n/**\n * fnADDw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnADDw = function(dst, src)\n{\n var w = (dst + src)|0;\n this.setArithResult(dst, src, w, this.typeData | X86.RESULT.ALL);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return w & this.maskData;\n};\n\n/**\n * fnANDb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnANDb = function(dst, src)\n{\n var b = dst & src;\n this.setLogicResult(b, X86.RESULT.BYTE);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return b;\n};\n\n/**\n * fnANDw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnANDw = function(dst, src)\n{\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return this.setLogicResult(dst & src, this.typeData) & this.maskData;\n};\n\n/**\n * fnARPL(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnARPL = function(dst, src)\n{\n this.nStepCycles -= (10 + (this.regEA === X86.ADDR_INVALID? 0 : 1));\n if ((dst & X86.SEL.RPL) < (src & X86.SEL.RPL)) {\n dst = (dst & ~X86.SEL.RPL) | (src & X86.SEL.RPL);\n this.setZF();\n return dst;\n }\n this.clearZF();\n return dst;\n};\n\n/**\n * fnBOUND(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBOUND = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n /*\n * Generate UD_FAULT (INT 0x06: Invalid Opcode) if src is not a memory operand.\n */\n X86.opInvalid.call(this);\n return dst;\n }\n /*\n * Note that BOUND performs signed comparisons, so we must transform all arguments into signed values.\n */\n var wIndex = dst;\n var wLower = this.getWord(this.regEA);\n var wUpper = this.getWord(this.regEA + this.sizeData);\n if (this.sizeData == 2) {\n wIndex = (dst << 16) >> 16;\n wLower = (wLower << 16) >> 16;\n wUpper = (wUpper << 16) >> 16;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesBound;\n if (wIndex < wLower || wIndex > wUpper) {\n /*\n * The INT 0x05 handler must be called with CS:IP pointing to the BOUND instruction.\n *\n * TODO: Determine the cycle cost when a BOUND exception is triggered, over and above nCyclesBound,\n * and then call X86.helpFault(X86.EXCEPTION.BR_FAULT, null, nCycles).\n */\n X86.helpFault.call(this, X86.EXCEPTION.BR_FAULT);\n }\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnBSF(dst, src)\n *\n * Scan src starting at bit 0. If a set bit is found, the bit index is stored in dst and ZF is cleared;\n * otherwise, ZF is set and dst is unchanged.\n *\n * NOTES: Early versions of the 80386 manuals misstated how ZF was set/cleared. Also, Intel insists that\n * dst is undefined whenever ZF is set, but in fact, the 80386 leaves dst unchanged when that happens;\n * unfortunately, some early 80486s would always modify dst, so it is unsafe to rely on dst when ZF is set.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBSF = function(dst, src)\n{\n var n = 0;\n if (!src) {\n this.setZF();\n } else {\n this.clearZF();\n var bit = 0x1;\n while (bit & this.maskData) {\n if (src & bit) {\n dst = n;\n break;\n }\n bit <<= 1;\n n++; // TODO: Determine if n should be incremented before the bailout for an accurate cycle count\n }\n }\n this.nStepCycles -= 11 + n * 3;\n return dst;\n};\n\n/**\n * fnBSR(dst, src)\n *\n * Scan src starting from the highest bit. If a set bit is found, the bit index is stored in dst and ZF is\n * cleared; otherwise, ZF is set and dst is unchanged.\n *\n * NOTES: Early versions of the 80386 manuals misstated how ZF was set/cleared. Also, Intel insists that\n * dst is undefined whenever ZF is set, but in fact, the 80386 leaves dst unchanged when that happens;\n * unfortunately, some early 80486s would always modify dst, so it is unsafe to rely on dst when ZF is set.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBSR = function(dst, src)\n{\n var n = 0;\n if (!src) {\n this.setZF();\n } else {\n this.clearZF();\n var i = (this.sizeData == 2? 15 : 31), bit = 1 << i;\n while (bit) {\n if (src & bit) {\n dst = i;\n break;\n }\n bit >>>= 1;\n n++; i--; // TODO: Determine if n should be incremented before the bailout for an accurate cycle count\n }\n\n }\n this.nStepCycles -= 11 + n * 3;\n return dst;\n};\n\n/**\n * fnBT(dst, src)\n *\n * In this form of BT, src is an immediate operand (OR dst is register operand); immediate operands\n * are supposed to be masked with either 0xf or 0x1f for 16-bit or 32-bit operands, respectively.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBT = function(dst, src)\n{\n var bit = 1 << (src & (this.sizeData == 2? 0xf : 0x1f));\n if (dst & bit) this.setCF(); else this.clearCF();\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 6);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnBTC(dst, src)\n *\n * In this form of BTC, src is an immediate operand (OR dst is register operand); immediate operands\n * are supposed to be masked with either 0xf or 0x1f for 16-bit or 32-bit operands, respectively.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBTC = function(dst, src)\n{\n var bit = 1 << (src & (this.sizeData == 2? 0xf : 0x1f));\n if (dst & bit) this.setCF(); else this.clearCF();\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 6 : 8);\n return dst ^ bit;\n};\n\n/**\n * fnBTR(dst, src)\n *\n * In this form of BTR, src is an immediate operand (OR dst is register operand); immediate operands\n * are supposed to be masked with either 0xf or 0x1f for 16-bit or 32-bit operands, respectively.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBTR = function(dst, src)\n{\n var bit = 1 << (src & (this.sizeData == 2? 0xf : 0x1f));\n if (dst & bit) this.setCF(); else this.clearCF();\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 6 : 8);\n return dst & ~bit;\n};\n\n/**\n * fnBTS(dst, src)\n *\n * In this form of BTS, src is an immediate operand (OR dst is register operand); immediate operands\n * are supposed to be masked with either 0xf or 0x1f for 16-bit or 32-bit operands, respectively.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBTS = function(dst, src)\n{\n var bit = 1 << (src & (this.sizeData == 2? 0xf : 0x1f));\n if (dst & bit) this.setCF(); else this.clearCF();\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 6 : 8);\n return dst | bit;\n};\n\n/**\n * fnBTMem(dst, src)\n *\n * In this form of BT, src is a register operand, which is NOT truncated if dst is a memory operand;\n * however, if dst is also a register operand, then we defer to the simpler function, fnBT().\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBTMem = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n return X86.fnBT.call(this, dst, src);\n }\n /*\n * TODO: Consider a worker function that performs the following block of code for: BT, BTC, BTR, and BTS.\n * It's somewhat inconvenient, because it needs to provide two results: an updated src AND an updated dst.\n *\n * src is usually positive BUT can also be negative (as the IA32 spec says: \"The offset operand then selects\n * a bit position within the range −231 to 231 − 1 for a register offset and 0 to 31 for an immediate offset.\")\n */\n var max = this.sizeData << 3;\n if (src >= max || src < -max) {\n /*\n * Now we need to divide src by 16 or 32, according to the OPERAND size, which means shifting it right\n * by either 4 or 5 bits. That gives us a short or long INDEX, which we then multiply by the OPERAND size\n * to obtain to the corresponding short or long OFFSET that we must add to the original EA offset.\n */\n var i = src >> (this.sizeData == 2? 4 : 5);\n dst = this.getEAWord(this.segEA, this.offEA + i * this.sizeData);\n }\n /*\n * Now we convert src from a bit index to a bit mask.\n */\n src = 1 << (src & (this.sizeData == 2? 0xf : 0x1f));\n if (dst & src) this.setCF(); else this.clearCF();\n\n this.nStepCycles -= 6;\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnBTCMem(dst, src)\n *\n * In this form of BTC, src is a register operand, which is NOT truncated if dst is a memory operand;\n * however, if dst is also a register operand, then we defer to the simpler function, fnBTC().\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBTCMem = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n return X86.fnBTC.call(this, dst, src);\n }\n /*\n * src is usually positive BUT can also be negative (as the IA32 spec says: \"The offset operand then selects\n * a bit position within the range −231 to 231 − 1 for a register offset and 0 to 31 for an immediate offset.\")\n */\n var max = this.sizeData << 3;\n if (src >= max || src < -max) {\n /*\n * Now we need to divide src by 16 or 32, according to the OPERAND size, which means shifting it right\n * by either 4 or 5 bits. That gives us a short or long INDEX, which we then multiply by the OPERAND size\n * to obtain to the corresponding short or long OFFSET that we must add to the original EA offset.\n */\n var i = src >> (this.sizeData == 2? 4 : 5);\n dst = this.getEAWord(this.segEA, this.offEA + i * this.sizeData);\n }\n /*\n * Now we convert src from a bit index to a bit mask.\n */\n src = 1 << (src & (this.sizeData == 2? 0xf : 0x1f));\n if (dst & src) this.setCF(); else this.clearCF();\n\n this.nStepCycles -= 8;\n return dst ^ src;\n};\n\n/**\n * fnBTRMem(dst, src)\n *\n * In this form of BTR, src is a register operand, which is NOT truncated if dst is a memory operand;\n * however, if dst is also a register operand, then we defer to the simpler function, fnBTR().\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBTRMem = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n return X86.fnBTR.call(this, dst, src);\n }\n /*\n * src is usually positive BUT can also be negative (as the IA32 spec says: \"The offset operand then selects\n * a bit position within the range −231 to 231 − 1 for a register offset and 0 to 31 for an immediate offset.\")\n */\n var max = this.sizeData << 3;\n if (src >= max || src < -max) {\n /*\n * Now we need to divide src by 16 or 32, according to the OPERAND size, which means shifting it right\n * by either 4 or 5 bits. That gives us a short or long INDEX, which we then multiply by the OPERAND size\n * to obtain to the corresponding short or long OFFSET that we must add to the original EA offset.\n */\n var i = src >> (this.sizeData == 2? 4 : 5);\n dst = this.getEAWord(this.segEA, this.offEA + i * this.sizeData);\n }\n /*\n * Now we convert src from a bit index to a bit mask.\n */\n src = 1 << (src & (this.sizeData == 2? 0xf : 0x1f));\n if (dst & src) this.setCF(); else this.clearCF();\n\n this.nStepCycles -= 8;\n return dst & ~src;\n};\n\n/**\n * fnBTSMem(dst, src)\n *\n * In this form of BTS, src is a register operand, which is NOT truncated if dst is a memory operand;\n * however, if dst is also a register operand, then we defer to the simpler function, fnBTS().\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBTSMem = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n return X86.fnBTS.call(this, dst, src);\n }\n /*\n * src is usually positive BUT can also be negative (as the IA32 spec says: \"The offset operand then selects\n * a bit position within the range −231 to 231 − 1 for a register offset and 0 to 31 for an immediate offset.\")\n */\n var max = this.sizeData << 3;\n if (src >= max || src < -max) {\n /*\n * Now we need to divide src by 16 or 32, according to the OPERAND size, which means shifting it right\n * by either 4 or 5 bits. That gives us a short or long INDEX, which we then multiply by the OPERAND size\n * to obtain to the corresponding short or long OFFSET that we must add to the original EA offset.\n */\n var i = src >> (this.sizeData == 2? 4 : 5);\n dst = this.getEAWord(this.segEA, this.offEA + i * this.sizeData);\n }\n /*\n * Now we convert src from a bit index to a bit mask.\n */\n src = 1 << (src & (this.sizeData == 2? 0xf : 0x1f));\n if (dst & src) this.setCF(); else this.clearCF();\n\n this.nStepCycles -= 8;\n return dst | src;\n};\n\n/**\n * fnCALLw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnCALLw = function(dst, src)\n{\n this.pushWord(this.getIP());\n this.setIP(dst);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesCallWR : this.cycleCounts.nOpCyclesCallWM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnCALLFdw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnCALLFdw = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n return X86.fnGRPUndefined.call(this, dst, src);\n }\n /*\n * Originally, we would snapshot regLSP into opLSP because helpCALLF() could trigger a segment fault,\n * but additionally, the stack segment could trigger either a segment fault or a page fault; indeed,\n * any operation that performs multiple stack modifications must take this precaution and snapshot regLSP.\n */\n this.opLSP = this.regLSP;\n\n X86.helpCALLF.call(this, dst, this.getShort(this.regEA + this.sizeData));\n this.nStepCycles -= this.cycleCounts.nOpCyclesCallDM;\n this.opFlags |= X86.OPFLAG.NOWRITE;\n\n this.opLSP = X86.ADDR_INVALID;\n return dst;\n};\n\n/**\n * fnCMPb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number} dst unchanged\n */\nX86.fnCMPb = function(dst, src)\n{\n var b = (dst - src)|0;\n this.setArithResult(dst, src, b, X86.RESULT.BYTE | X86.RESULT.ALL, true);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesCompareRM) : this.cycleCounts.nOpCyclesArithRM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnCMPw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number} dst unchanged\n */\nX86.fnCMPw = function(dst, src)\n{\n var w = (dst - src)|0;\n this.setArithResult(dst, src, w, this.typeData | X86.RESULT.ALL, true);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesCompareRM) : this.cycleCounts.nOpCyclesArithRM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnDECb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnDECb = function(dst, src)\n{\n var b = (dst - 1)|0;\n this.setArithResult(dst, 1, b, X86.RESULT.BYTE | X86.RESULT.NOTCF, true);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIncR : this.cycleCounts.nOpCyclesIncM);\n return b & 0xff;\n};\n\n/**\n * fnDECw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnDECw = function(dst, src)\n{\n var w = (dst - 1)|0;\n this.setArithResult(dst, 1, w, this.typeData | X86.RESULT.NOTCF, true);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIncR : this.cycleCounts.nOpCyclesIncM);\n return w & this.maskData;\n};\n\n/**\n * fnDIVb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (the divisor)\n * @param {number} src (null; AX is the implied src)\n * @return {number} (we return dst unchanged, since it's actually AX that's modified)\n */\nX86.fnDIVb = function(dst, src)\n{\n /*\n * Detect zero divisor\n */\n if (!dst) {\n X86.helpDIVOverflow.call(this);\n return dst;\n }\n\n /*\n * Detect too-small divisor (quotient overflow)\n */\n var result = ((src = this.regEAX & 0xffff) / dst);\n if (result > 0xff) {\n X86.helpDIVOverflow.call(this);\n return dst;\n }\n\n this.regMDLo = (result & 0xff) | (((src % dst) & 0xff) << 8);\n this.fMDSet = true;\n\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesDivBR : this.cycleCounts.nOpCyclesDivBM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnDIVw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (the divisor)\n * @param {number} src (null; DX:AX or EDX:EAX is the implied src)\n * @return {number} (we return dst unchanged, since it's actually DX:AX that's modified)\n */\nX86.fnDIVw = function(dst, src)\n{\n if (this.sizeData == 2) {\n /*\n * Detect zero divisor\n */\n if (!dst) {\n X86.helpDIVOverflow.call(this);\n return dst;\n }\n /*\n * Detect too-small divisor (quotient overflow)\n *\n * WARNING: We CANNOT simply do \"src = (this.regEDX << 16) | this.regEAX\", because if bit 15 of DX\n * is set, JavaScript will create a negative 32-bit number. So we instead use non-bitwise operators\n * to force JavaScript to create a floating-point value that won't suffer from 32-bit-math side-effects.\n */\n src = (this.regEDX & 0xffff) * 0x10000 + (this.regEAX & 0xffff);\n var result = (src / dst);\n if (result >= 0x10000) {\n X86.helpDIVOverflow.call(this);\n return dst;\n }\n this.regMDLo = (result & 0xffff);\n this.regMDHi = (src % dst) & 0xffff;\n }\n else {\n if (!X86.helpDIV32.call(this, this.regEAX, this.regEDX, dst)) {\n X86.helpDIVOverflow.call(this);\n return dst;\n }\n this.regMDLo |= 0;\n this.regMDHi |= 0;\n }\n\n this.fMDSet = true;\n\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesDivWR : this.cycleCounts.nOpCyclesDivWM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnESC(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number} dst unchanged\n */\nX86.fnESC = function(dst, src)\n{\n if (this.fpu) {\n this.fpu.opFPU(this.bOpcode, this.bModRM, dst, src);\n }\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 2 : 8);\n return dst;\n};\n\n/**\n * fnGRPFault(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnGRPFault = function(dst, src)\n{\n /*\n * This should NEVER be called on 8086/8088 CPUs, and yet we preset some of the handlers in aOpGrpPOPw,\n * aOpGrp4b, and aOpGrp4w to call it. initProcessor() DOES patch aOpGrp4b[0x07] and aOpGrp4w[0x07] to\n * fnGRPInvalid, but that's it.\n *\n * However, given the infrequency of this call, it's simpler to continue presetting all the handlers in\n * aOpGrpPOPw to their post-8086 default, and deal with the appropriate 8086 behavior here (which for now,\n * is to call fnGRPUndefined instead).\n */\n if (this.model < X86.MODEL_80186) {\n return X86.fnGRPUndefined.call(this, dst, src);\n }\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return dst;\n};\n\n/**\n * fnGRPInvalid(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnGRPInvalid = function(dst, src)\n{\n X86.opInvalid.call(this);\n return dst;\n};\n\n/**\n * fnGRPUndefined(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnGRPUndefined = function(dst, src)\n{\n X86.opUndefined.call(this);\n return dst;\n};\n\n/**\n * fnIDIVb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (the divisor)\n * @param {number} src (null; AX is the implied src)\n * @return {number} (we return dst unchanged, since it's actually AX that's modified)\n */\nX86.fnIDIVb = function(dst, src)\n{\n /*\n * Detect zero divisor\n */\n if (!dst) {\n X86.helpDIVOverflow.call(this);\n return dst;\n }\n\n /*\n * Detect too-small divisor (quotient overflow)\n */\n var div = ((dst << 24) >> 24);\n var result = ((src = (this.regEAX << 16) >> 16) / div)|0;\n\n /*\n * Note the following difference, from \"AP-186: Introduction to the 80186 Microprocessor, March 1983\":\n *\n * \"The 8086 will cause a divide error whenever the absolute value of the quotient is greater then 7FFFH\n * (for word operations) or if the absolute value of the quotient is greater than 7FH (for byte operations).\n * The 80186 has expanded the range of negative numbers allowed as a quotient by 1 to include 8000H and 80H.\n * These numbers represent the most negative numbers representable using 2's complement arithmetic (equaling\n * -32768 and -128 in decimal, respectively).\"\n */\n if (result != ((result << 24) >> 24) || this.model == X86.MODEL_8086 && result == -128) {\n X86.helpDIVOverflow.call(this);\n return dst;\n }\n\n this.regMDLo = (result & 0xff) | (((src % div) & 0xff) << 8);\n this.fMDSet = true;\n\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIDivBR : this.cycleCounts.nOpCyclesIDivBM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnIDIVw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (the divisor)\n * @param {number} src (null; DX:AX or EDX:EAX is the implied src)\n * @return {number} (we return dst unchanged, since it's actually DX:AX that's modified)\n */\nX86.fnIDIVw = function(dst, src)\n{\n if (this.sizeData == 2) {\n /*\n * Detect zero divisor\n */\n if (!dst) {\n X86.helpDIVOverflow.call(this);\n return dst;\n }\n\n /*\n * Detect too-small divisor (quotient overflow)\n */\n var div = ((dst << 16) >> 16);\n var result = ((src = (this.regEDX << 16) | (this.regEAX & 0xffff)) / div)|0;\n\n /*\n * Note the following difference, from \"AP-186: Introduction to the 80186 Microprocessor, March 1983\":\n *\n * \"The 8086 will cause a divide error whenever the absolute value of the quotient is greater then 7FFFH\n * (for word operations) or if the absolute value of the quotient is greater than 7FH (for byte operations).\n * The 80186 has expanded the range of negative numbers allowed as a quotient by 1 to include 8000H and 80H.\n * These numbers represent the most negative numbers representable using 2's complement arithmetic (equaling\n * -32768 and -128 in decimal, respectively).\"\n */\n if (result != ((result << 16) >> 16) || this.model == X86.MODEL_8086 && result == -32768) {\n X86.helpDIVOverflow.call(this);\n return dst;\n }\n\n this.regMDLo = (result & 0xffff);\n this.regMDHi = (src % div) & 0xffff;\n }\n else {\n if (!X86.helpIDIV32.call(this, this.regEAX, this.regEDX, dst)) {\n X86.helpDIVOverflow.call(this);\n return dst;\n }\n this.regMDLo |= 0;\n this.regMDHi |= 0;\n }\n\n this.fMDSet = true;\n\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIDivWR : this.cycleCounts.nOpCyclesIDivWM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnIMUL8(dst, src)\n *\n * 80286_and_80287_Programmers_Reference_Manual_1987.pdf, p.B-44 (p.254) notes that:\n *\n * \"The low 16 bits of the product of a 16-bit signed multiply are the same as those of an\n * unsigned multiply. The three operand IMUL instruction can be used for unsigned operands as well.\"\n *\n * However, we still sign-extend the operands before multiplying, making it easier to range-check the result.\n *\n * (80186/80188 and up)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnIMUL8 = function(dst, src)\n{\n /*\n * NOTE: getIPDisp() already sign-extends the dst parameter, so fnIMULrw() needlessly sign-extends it again;\n * a small price to pay for a common function.\n */\n var result = X86.fnIMULrw.call(this, this.getIPDisp(), src);\n\n /*\n * NOTE: The above function already accounted for the 80386 cycle count, so we are simply accounting for the\n * increased time on an 80286; the 80186/80188 have even larger values, but we'll worry about that another day.\n */\n if (this.model < X86.MODEL_80386) this.nStepCycles -= 12;\n return result;\n};\n\n/**\n * fnIMULn(dst, src)\n *\n * 80286_and_80287_Programmers_Reference_Manual_1987.pdf, p.B-44 (p.254) notes that:\n *\n * \"The low 16 bits of the product of a 16-bit signed multiply are the same as those of an\n * unsigned multiply. The three operand IMUL instruction can be used for unsigned operands as well.\"\n *\n * However, we still sign-extend the operands before multiplying, making it easier to range-check the result.\n *\n * (80186/80188 and up)\n *\n * @this {CPUX86}\n * @param {number} dst (not used)\n * @param {number} src\n * @return {number}\n */\nX86.fnIMULn = function(dst, src)\n{\n var result;\n dst = this.getIPWord();\n\n if (this.sizeData == 2) {\n result = X86.fnIMULrw.call(this, dst, src);\n } else {\n result = X86.fnIMULrd.call(this, dst, src);\n }\n\n /*\n * NOTE: The above functions already accounted for 80386 cycle counts, so we are simply accounting for the\n * increased time on an 80286; the 80186/80188 have even larger values, but we'll worry about that another day.\n */\n if (this.model < X86.MODEL_80386) this.nStepCycles -= 12;\n return result;\n};\n\n/**\n * fnIMUL32(dst, src)\n *\n * This sets regMDHi:regMDLo to the 64-bit result of dst * src, both of which are treated as signed.\n *\n * @this {CPUX86}\n * @param {number} dst (any 32-bit number, treated as signed)\n * @param {number} src (any 32-bit number, treated as signed)\n */\nX86.fnIMUL32 = function(dst, src)\n{\n var fNeg = false;\n if (src < 0) {\n src = -src|0;\n fNeg = !fNeg;\n }\n if (dst < 0) {\n dst = -dst|0;\n fNeg = !fNeg;\n }\n X86.fnMUL32.call(this, dst, src);\n if (fNeg) {\n this.regMDLo = (~this.regMDLo + 1)|0;\n this.regMDHi = (~this.regMDHi + (this.regMDLo? 0 : 1))|0;\n }\n};\n\n/**\n * fnIMULb(dst, src)\n *\n * This 16-bit multiplication must indicate when the upper 8 bits are simply a sign-extension of the\n * lower 8 bits (carry clear) and when the upper 8 bits contain significant bits (carry set). The latter\n * will occur whenever a positive result is > 127 (0x007f) and whenever a negative result is < -128\n * (0xff80).\n *\n * Example 1: 16 * 4 = 64 (0x0040): carry is clear\n * Example 2: 16 * 8 = 128 (0x0080): carry is set (the sign bit no longer fits in the lower 8 bits)\n * Example 3: 16 * -8 (0xf8) = -128 (0xff80): carry is clear (the sign bit *still* fits in the lower 8 bits)\n * Example 4: 16 * -16 (0xf0) = -256 (0xff00): carry is set (the sign bit no longer fits in the lower 8 bits)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null; AL is the implied src)\n * @return {number} (we return dst unchanged, since it's actually AX that's modified)\n */\nX86.fnIMULb = function(dst, src)\n{\n var result = (((this.regEAX << 24) >> 24) * ((dst << 24) >> 24))|0;\n\n this.regMDLo = result & 0xffff;\n\n if (result > 127 || result < -128) {\n this.setCF(); this.setOF();\n } else {\n this.clearCF(); this.clearOF();\n }\n\n this.fMDSet = true;\n\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIMulBR : this.cycleCounts.nOpCyclesIMulBM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnIMULw(dst, src)\n *\n * regMDHi:regMDLo = dst * regEAX\n *\n * This 32-bit multiplication must indicate when the upper 16 bits are simply a sign-extension of the\n * lower 16 bits (carry clear) and when the upper 16 bits contain significant bits (carry set). The latter\n * will occur whenever a positive result is > 32767 (0x00007fff) and whenever a negative result is < -32768\n * (0xffff8000).\n *\n * Example 1: 256 * 64 = 16384 (0x00004000): carry is clear\n * Example 2: 256 * 128 = 32768 (0x00008000): carry is set (the sign bit no longer fits in the lower 16 bits)\n * Example 3: 256 * -128 (0xff80) = -32768 (0xffff8000): carry is clear (the sign bit *still* fits in the lower 16 bits)\n * Example 4: 256 * -256 (0xff00) = -65536 (0xffff0000): carry is set (the sign bit no longer fits in the lower 16 bits)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null; AX or EAX is the implied src)\n * @return {number} (we return dst unchanged, since it's actually DX:AX or EDX:EAX that's modified)\n */\nX86.fnIMULw = function(dst, src)\n{\n var fOverflow;\n if (this.sizeData == 2) {\n src = this.regEAX & 0xffff;\n var result = (((src << 16) >> 16) * ((dst << 16) >> 16))|0;\n this.regMDLo = result & 0xffff;\n this.regMDHi = (result >> 16) & 0xffff;\n fOverflow = (result > 32767 || result < -32768);\n } else {\n X86.fnIMUL32.call(this, dst, this.regEAX);\n fOverflow = (this.regMDHi != (this.regMDLo >> 31));\n }\n\n if (fOverflow) {\n this.setCF(); this.setOF();\n } else {\n this.clearCF(); this.clearOF();\n }\n\n this.fMDSet = true;\n\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIMulWR : this.cycleCounts.nOpCyclesIMulWM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnIMULrw(dst, src)\n *\n * This function exists for 16-bit IMUL instructions that produce a 16-bit result instead of a 32-bit result\n * (and don't implicitly use the accumulator).\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnIMULrw = function(dst, src)\n{\n /*\n * Unlike fnIMULrd() below, we can use normal JavaScript multiplication, because there's no danger of\n * overflowing the floating-point result and losing accuracy in the bottom 16 bits.\n */\n var result = (((dst << 16) >> 16) * ((src << 16) >> 16))|0;\n if (result > 32767 || result < -32768) {\n this.setCF(); this.setOF();\n } else {\n this.clearCF(); this.clearOF();\n }\n result &= 0xffff;\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 9 : 12);\n return result;\n};\n\n/**\n * fnIMULrd(dst, src)\n *\n * This function exists for 32-bit IMUL instructions that produce a 32-bit result instead of a 64-bit result\n * (and don't implicitly use the accumulator).\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnIMULrd = function(dst, src)\n{\n /*\n * The following code works, but I've stopped using it because it produces different results from an actual CPU\n * when overflow occurs; the bottom 32 bits of the result are still supposed to be accurate.\n *\n * And unfortunately, we cannot achieve that level of compatibility using normal JavaScript multiplication,\n * because the result may be too large to fit in a JavaScript floating-point variable, which means we could lose\n * accuracy in the bottom 32 bits, which would defeat what we're trying to achieve here. So we must use the\n * slower fnIMUL32() function.\n *\n * var result = dst * src;\n * if (result > 2147483647 || result < -2147483648) {\n * this.setCF(); this.setOF();\n * } else {\n * this.clearCF(); this.clearOF();\n * }\n * result |= 0;\n */\n X86.fnIMUL32.call(this, dst, src);\n var fOverflow = (this.regMDHi != (this.regMDLo >> 31));\n if (fOverflow) {\n this.setCF(); this.setOF();\n } else {\n this.clearCF(); this.clearOF();\n }\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 9 : 12);\n return this.regMDLo;\n};\n\n/**\n * fnINCb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnINCb = function(dst, src)\n{\n var b = (dst + 1)|0;\n this.setArithResult(dst, 1, b, X86.RESULT.BYTE | X86.RESULT.NOTCF);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIncR : this.cycleCounts.nOpCyclesIncM);\n return b & 0xff;\n};\n\n/**\n * fnINCw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnINCw = function(dst, src)\n{\n var w = (dst + 1)|0;\n this.setArithResult(dst, 1, w, this.typeData | X86.RESULT.NOTCF);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIncR : this.cycleCounts.nOpCyclesIncM);\n return w & this.maskData;\n};\n\n/**\n * fnJMPw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnJMPw = function(dst, src)\n{\n this.setIP(dst);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesJmpWR : this.cycleCounts.nOpCyclesJmpWM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnJMPFdw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnJMPFdw = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n return X86.fnGRPUndefined.call(this, dst, src);\n }\n this.setCSIP(dst, this.getShort(this.regEA + this.sizeData));\n if (MAXDEBUG && this.cIntReturn) this.checkIntReturn(this.regLIP);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpDM;\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnLAR(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnLAR = function(dst, src)\n{\n this.nStepCycles -= (14 + (this.regEA === X86.ADDR_INVALID? 0 : 2));\n /*\n * Currently, segVER.load() will return an error only if the selector is beyond the bounds of the\n * descriptor table or the descriptor is not for a segment.\n *\n * TODO: This instruction's 80286 documentation does not discuss conforming code segments; determine\n * if we need a special check for them.\n */\n this.clearZF();\n if (this.segVER.load(src) !== X86.ADDR_INVALID) {\n if (this.segVER.dpl >= this.nCPL && this.segVER.dpl >= (src & X86.SEL.RPL)) {\n this.setZF();\n dst = this.segVER.acc & ~X86.DESC.ACC.BASE1623;\n if (this.sizeData > 2) {\n dst |= ((this.segVER.ext & ~X86.DESC.EXT.BASE2431) << 16);\n }\n }\n }\n return dst;\n};\n\n/**\n * fnLDS(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnLDS = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n X86.opUndefined.call(this);\n return dst;\n }\n this.setDS(this.getShort(this.regEA + this.sizeData));\n this.nStepCycles -= this.cycleCounts.nOpCyclesLS;\n return src;\n};\n\n/**\n * fnLEA(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnLEA = function(dst, src)\n{\n /*\n * TODO: Until I bite the bullet and choose a truly invalid value for X86.ADDR_INVALID (eg, null),\n * this code must be disabled, because otherwise an instruction like \"LEA ECX,[EAX-1]\" will fail when\n * EAX is zero. And we can't have that.\n *\n if (this.regEA === X86.ADDR_INVALID) {\n //\n // TODO: After reading http://www.os2museum.com/wp/undocumented-8086-opcodes/, it seems that this\n // form of LEA (eg, \"LEA AX,DX\") simply returns the last calculated EA. Since we always reset regEA\n // at the start of a new instruction, we would need to preserve the previous EA if we want to mimic\n // that (undocumented) behavior.\n //\n // And for completeness, we would have to extend EA tracking beyond the usual ModRM instructions\n // (eg, XLAT, instructions that modify the stack pointer, and string instructions). Anything else?\n //\n X86.opUndefined.call(this);\n return dst;\n }\n */\n this.nStepCycles -= this.cycleCounts.nOpCyclesLEA;\n return this.regEA;\n};\n\n/**\n * fnLES(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnLES = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n X86.opUndefined.call(this);\n return dst;\n }\n this.setES(this.getShort(this.regEA + this.sizeData));\n this.nStepCycles -= this.cycleCounts.nOpCyclesLS;\n return src;\n};\n\n/**\n * fnLFS(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnLFS = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n X86.opUndefined.call(this);\n return dst;\n }\n this.setFS(this.getShort(this.regEA + this.sizeData));\n this.nStepCycles -= this.cycleCounts.nOpCyclesLS;\n return src;\n};\n\n/**\n * fnLGDT(dst, src)\n *\n * op=0x0F,0x01,reg=0x2 (GRP7:LGDT)\n *\n * The 80286 LGDT instruction assumes a 40-bit operand: a 16-bit limit followed by a 24-bit base address;\n * the ModRM decoder has already supplied the first word of the operand (in dst), which corresponds to\n * the limit, so we must fetch the remaining bits ourselves.\n *\n * The 80386 LGDT instruction assumes a 48-bit operand: a 16-bit limit followed by a 32-bit base address,\n * but it ignores the last 8 bits of the base address if the OPERAND size is 16 bits; we interpret that to\n * mean that the 24-bit base address should be zero-extended to 32 bits.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnLGDT = function(dst, src)\n{\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to V86-mode.\n */\n if (this.regEA === X86.ADDR_INVALID || I386 && (this.regPS & X86.PS.VM)) {\n X86.opInvalid.call(this);\n } else {\n /*\n * Hopefully it won't hurt to always fetch a 32-bit base address (even on an 80286), which we then\n * mask appropriately.\n */\n this.addrGDT = this.getLong(this.regEA + 2) & (this.maskData | (this.maskData << 8));\n /*\n * An idiosyncrasy of our ModRM decoders is that, if the OPERAND size is 32 bits, then it will have\n * fetched a 32-bit dst operand; we mask off those extra bits now.\n */\n dst &= 0xffff;\n this.addrGDTLimit = this.addrGDT + dst;\n this.opFlags |= X86.OPFLAG.NOWRITE;\n this.nStepCycles -= 11;\n }\n return dst;\n};\n\n/**\n * fnLGS(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnLGS = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n X86.opUndefined.call(this);\n return dst;\n }\n this.setGS(this.getShort(this.regEA + this.sizeData));\n this.nStepCycles -= this.cycleCounts.nOpCyclesLS;\n return src;\n};\n\n/**\n * fnLIDT(dst, src)\n *\n * op=0x0F,0x01,reg=0x3 (GRP7:LIDT)\n *\n * The 80286 LIDT instruction assumes a 40-bit operand: a 16-bit limit followed by a 24-bit base address;\n * the ModRM decoder has already supplied the first word of the operand (in dst), which corresponds to\n * the limit, so we must fetch the remaining bits ourselves.\n *\n * The 80386 LIDT instruction assumes a 48-bit operand: a 16-bit limit followed by a 32-bit base address,\n * but it ignores the last 8 bits of the base address if the OPERAND size is 16 bits; we interpret that to\n * mean that the 24-bit base address should be zero-extended to 32 bits.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnLIDT = function(dst, src)\n{\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to V86-mode.\n */\n if (this.regEA === X86.ADDR_INVALID || I386 && (this.regPS & X86.PS.VM)) {\n X86.opInvalid.call(this);\n } else {\n /*\n * Hopefully it won't hurt to always fetch a 32-bit base address (even on an 80286), which we then\n * mask appropriately.\n */\n this.addrIDT = this.getLong(this.regEA + 2) & (this.maskData | (this.maskData << 8));\n /*\n * An idiosyncrasy of our ModRM decoders is that, if the OPERAND size is 32 bits, then it will have\n * fetched a 32-bit dst operand; we mask off those extra bits now.\n */\n dst &= 0xffff;\n this.addrIDTLimit = this.addrIDT + dst;\n this.opFlags |= X86.OPFLAG.NOWRITE;\n this.nStepCycles -= 12;\n }\n return dst;\n};\n\n/**\n * fnLLDT(dst, src)\n *\n * op=0x0F,0x00,reg=0x2 (GRP6:LLDT)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnLLDT = function(dst, src)\n{\n this.opFlags |= X86.OPFLAG.NOWRITE;\n this.segLDT.load(dst);\n this.nStepCycles -= (17 + (this.regEA === X86.ADDR_INVALID? 0 : 2));\n return dst;\n};\n\n/**\n * fnLMSW(dst, src)\n *\n * op=0x0F,0x01,reg=0x6 (GRP7:LMSW)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnLMSW = function(dst, src)\n{\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to V86-mode.\n */\n if (I386 && (this.regPS & X86.PS.VM)) {\n X86.opInvalid.call(this);\n } else {\n this.setMSW(dst);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 6);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n }\n return dst;\n};\n\n/**\n * fnLSL(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (the selector)\n * @return {number}\n */\nX86.fnLSL = function(dst, src)\n{\n /*\n * TODO: Is this an invalid operation if regEAWrite is set? dst is required to be a register.\n */\n this.nStepCycles -= (14 + (this.regEA === X86.ADDR_INVALID? 0 : 2));\n /*\n * Currently, segVER.load() will return an error only if the selector is beyond the bounds of the\n * descriptor table or the descriptor is not for a segment.\n *\n * TODO: LSL is explicitly documented as ALSO requiring a non-null selector, so we check X86.SEL.MASK;\n * are there any other instructions that were, um, less explicit but also require a non-null selector?\n */\n if ((src & X86.SEL.MASK) && this.segVER.load(src) !== X86.ADDR_INVALID) {\n var fConforming = ((this.segVER.acc & X86.DESC.ACC.TYPE.CODE_CONFORMING) == X86.DESC.ACC.TYPE.CODE_CONFORMING);\n if ((fConforming || this.segVER.dpl >= this.nCPL) && this.segVER.dpl >= (src & X86.SEL.RPL)) {\n this.setZF();\n return this.segVER.limit;\n }\n }\n this.clearZF();\n return dst;\n};\n\n/**\n * fnLSS(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnLSS = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n X86.opUndefined.call(this);\n return dst;\n }\n this.setSS(this.getShort(this.regEA + this.sizeData));\n this.nStepCycles -= this.cycleCounts.nOpCyclesLS;\n return src;\n};\n\n/**\n * fnLTR(dst, src)\n *\n * op=0x0F,0x00,reg=0x3 (GRP6:LTR)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnLTR = function(dst, src)\n{\n this.opFlags |= X86.OPFLAG.NOWRITE;\n if (this.segTSS.load(dst) !== X86.ADDR_INVALID) {\n this.setShort(this.segTSS.addrDesc + X86.DESC.ACC.OFFSET, this.segTSS.acc |= X86.DESC.ACC.TYPE.TSS_BUSY);\n this.segTSS.type |= X86.DESC.ACC.TYPE.TSS_BUSY;\n }\n this.nStepCycles -= (17 + (this.regEA === X86.ADDR_INVALID? 0 : 2));\n return dst;\n};\n\n/**\n * fnMOV(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (current value, ignored)\n * @param {number} src (new value)\n * @return {number} dst (updated value, from src)\n */\nX86.fnMOV = function(dst, src)\n{\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesMovRR : this.cycleCounts.nOpCyclesMovRM) : this.cycleCounts.nOpCyclesMovMR);\n return src;\n};\n\n/**\n * fnMOVXb(dst, src)\n *\n * Helper for opMOVSXb() and opMOVZXb() (which also take care of updating nStepCycles, so we don't have to)\n *\n * @this {CPUX86}\n * @param {number} dst (current value, ignored)\n * @param {number} src (new value)\n * @return {number} dst (updated value, from src)\n */\nX86.fnMOVXb = function(dst, src)\n{\n /*\n * The ModRegByte handlers update the registers in the 1st column, but we need to update those in the 2nd column.\n *\n * 000: AL -> 000: AX\n * 001: CL -> 001: CX\n * 010: DL -> 010: DX\n * 011: BL -> 011: BX\n * 100: AH -> 100: SP\n * 101: CH -> 101: BP\n * 110: DH -> 110: SI\n * 111: BH -> 111: DI\n */\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x4:\n this.regXX = this.regEAX;\n break;\n case 0x5:\n this.regXX = this.regECX;\n break;\n case 0x6:\n this.regXX = this.regEDX;\n break;\n case 0x7:\n this.regXX = this.regEBX;\n break;\n }\n return src;\n};\n\n/**\n * fnMOVXw(dst, src)\n *\n * Helper for opMOVSXw() and opMOVZXw() (which also take care of updating nStepCycles, so we don't have to)\n *\n * @this {CPUX86}\n * @param {number} dst (current value, ignored)\n * @param {number} src (new value)\n * @return {number} dst (updated value, from src)\n */\nX86.fnMOVXw = function(dst, src)\n{\n return src;\n};\n\n/**\n * fnMOVn(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (current value, ignored)\n * @param {number} src (new value)\n * @return {number} dst (updated value, from src)\n */\nX86.fnMOVn = function(dst, src)\n{\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesMovRI : this.cycleCounts.nOpCyclesMovMI);\n return src;\n};\n\n/**\n * fnMOVsrw(dst, src)\n *\n * This helper saves the contents of the general-purpose register that will be overwritten, so that the caller\n * can restore it after moving the updated value to the correct segment register.\n *\n * @this {CPUX86}\n * @param {number} dst (current value, ignored)\n * @param {number} src (new value)\n * @return {number} dst (updated value, from src)\n */\nX86.fnMOVsrw = function(dst, src)\n{\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n this.regXX = this.regEAX;\n break;\n case 0x2:\n this.regXX = this.regEDX;\n break;\n case 0x3:\n this.regXX = this.regEBX;\n break;\n default:\n if (this.model == X86.MODEL_80286 || this.model == X86.MODEL_80386 && reg != 0x4 && reg != 0x5) {\n X86.opInvalid.call(this);\n break;\n }\n switch(reg) {\n case 0x1: // MOV to CS is undocumented on 8086/8088/80186/80188, and invalid on 80286 and up\n this.regXX = this.regECX;\n break;\n case 0x4: // this form of MOV to ES is undocumented on 8086/8088/80186/80188, invalid on 80286, and uses FS starting with 80386\n this.regXX = this.getSP();\n break;\n case 0x5: // this form of MOV to CS is undocumented on 8086/8088/80186/80188, invalid on 80286, and uses GS starting with 80386\n this.regXX = this.regEBP;\n break;\n case 0x6: // this form of MOV to SS is undocumented on 8086/8088/80186/80188, invalid on 80286 and up\n this.regXX = this.regESI;\n break;\n case 0x7: // this form of MOV to DS is undocumented on 8086/8088/80186/80188, invalid on 80286 and up\n this.regXX = this.regEDI;\n break;\n default:\n break;\n }\n break;\n }\n /*\n * We could just return src, but nStepCycles needs to be updated, too.\n */\n return X86.fnMOV.call(this, dst, src);\n};\n\n/**\n * fnMOVwsr(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (current value, ignored)\n * @param {number} src (new value)\n * @return {number} dst\n */\nX86.fnMOVwsr = function(dst, src)\n{\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch (reg) {\n case 0x0:\n src = this.segES.sel;\n break;\n case 0x1:\n src = this.segCS.sel;\n break;\n case 0x2:\n src = this.segSS.sel;\n break;\n case 0x3:\n src = this.segDS.sel;\n break;\n case 0x4:\n if (I386 && this.model >= X86.MODEL_80386) {\n src = this.segFS.sel;\n break;\n }\n X86.opInvalid.call(this);\n src = dst;\n break;\n case 0x5:\n if (I386 && this.model >= X86.MODEL_80386) {\n src = this.segGS.sel;\n break;\n }\n /* falls through */\n default:\n X86.opInvalid.call(this);\n src = dst;\n break;\n }\n\n /*\n * When a 32-bit OPERAND size is in effect, segment register writes via opMOVwsr() must write 32 bits\n * (zero-extended) if the destination is a register, but only 16 bits if the destination is memory,\n * hence the setDataSize(2) below.\n *\n * The only other caller, opMOVrc(), is not affected, because it writes only to register destinations.\n */\n if (this.regEAWrite !== X86.ADDR_INVALID) {\n this.setDataSize(2);\n }\n /*\n * We could just return src, but nStepCycles needs to be updated, too.\n */\n return X86.fnMOV.call(this, dst, src);\n};\n\n/**\n * fnMULb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number} (we return dst unchanged, since it's actually AX that's modified)\n */\nX86.fnMULb = function(dst, src)\n{\n this.regMDLo = ((this.regEAX & 0xff) * dst) & 0xffff;\n\n if (this.regMDLo & 0xff00) {\n this.setCF(); this.setOF();\n } else {\n this.clearCF(); this.clearOF();\n }\n\n this.fMDSet = true;\n\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesMulBR : this.cycleCounts.nOpCyclesMulBM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnMUL32(dst, src)\n *\n * This sets regMDHi:regMDLo to the 64-bit result of dst * src, both of which are treated as unsigned.\n *\n * The algorithm is based on the traditional \"by hand\" multiplication method, by treating the two inputs\n * (dst and src) as two 2-digit numbers, where each digit is a base-65536 digit.\n *\n * @this {CPUX86}\n * @param {number} dst (any 32-bit number, treated as unsigned)\n * @param {number} src (any 32-bit number, treated as unsigned)\n */\nX86.fnMUL32 = function(dst, src)\n{\n if (!(dst & ~0xffff) && !(src & ~0xffff)) {\n this.regMDLo = (dst * src)|0;\n this.regMDHi = 0;\n }\n else {\n var srcLo = src & 0xffff;\n var srcHi = src >>> 16;\n var dstLo = dst & 0xffff;\n var dstHi = dst >>> 16;\n\n var mul00 = srcLo * dstLo;\n var mul16 = ((mul00 >>> 16) + (srcHi * dstLo));\n var mul32 = mul16 >>> 16;\n mul16 = ((mul16 & 0xffff) + (srcLo * dstHi));\n mul32 += ((mul16 >>> 16) + (srcHi * dstHi));\n\n this.regMDLo = (mul16 << 16) | (mul00 & 0xffff);\n this.regMDHi = mul32|0;\n }\n};\n\n/**\n * fnMULw(dst, src)\n *\n * regMDHi:regMDLo = dst * regEAX\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null; AX or EAX is the implied src)\n * @return {number} (we return dst unchanged, since it's actually DX:AX that's modified)\n */\nX86.fnMULw = function(dst, src)\n{\n if (this.sizeData == 2) {\n src = this.regEAX & 0xffff;\n var result = (src * dst)|0;\n this.regMDLo = result & 0xffff;\n this.regMDHi = (result >> 16) & 0xffff;\n } else {\n X86.fnMUL32.call(this, dst, this.regEAX);\n if (this.stepping == X86.STEPPING_80386_B1) {\n if (this.regEAX == 0x0417A000 && dst == 0x00000081) {\n /*\n * Normally, the result should be 0x20FE7A000 (ie, regMDHi should be 0x2).\n * I'm not sure what a typical B1 stepping failure looked like, so I'll set regMDHi to 0.\n *\n * If you want a B1 stepping without this 32-bit multiplication flaw, select the B2 stepping.\n */\n\n this.regMDHi = 0;\n }\n }\n }\n\n if (this.regMDHi) {\n this.setCF(); this.setOF();\n } else {\n this.clearCF(); this.clearOF();\n }\n\n this.fMDSet = true;\n\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesMulWR : this.cycleCounts.nOpCyclesMulWM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnNEGb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnNEGb = function(dst, src)\n{\n var b = (-dst)|0;\n this.setArithResult(0, dst, b, X86.RESULT.BYTE | X86.RESULT.ALL, true);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesNegR : this.cycleCounts.nOpCyclesNegM);\n return b & 0xff;\n};\n\n/**\n * fnNEGw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnNEGw = function(dst, src)\n{\n var w = (-dst)|0;\n this.setArithResult(0, dst, w, this.typeData | X86.RESULT.ALL, true);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesNegR : this.cycleCounts.nOpCyclesNegM);\n return w & this.maskData;\n};\n\n/**\n * fnNOTb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnNOTb = function(dst, src)\n{\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesNegR : this.cycleCounts.nOpCyclesNegM);\n return dst ^ 0xff;\n};\n\n/**\n * fnNOTw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnNOTw = function(dst, src)\n{\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesNegR : this.cycleCounts.nOpCyclesNegM);\n return dst ^ this.maskData;\n};\n\n/**\n * fnORb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnORb = function(dst, src)\n{\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return this.setLogicResult(dst | src, X86.RESULT.BYTE);\n};\n\n/**\n * fnORw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnORw = function(dst, src)\n{\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return this.setLogicResult(dst | src, this.typeData) & this.maskData;\n};\n\n/**\n * fnPOPw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (current value, ignored)\n * @param {number} src (new value)\n * @return {number} dst (updated value, from src)\n */\nX86.fnPOPw = function(dst, src)\n{\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesPopReg : this.cycleCounts.nOpCyclesPopMem);\n return src;\n};\n\n/**\n * fnPUSHw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnPUSHw = function(dst, src)\n{\n var w = dst;\n if (this.opFlags & X86.OPFLAG.PUSHSP) {\n /*\n * This is the one case where must actually modify dst, so that the ModRM function will\n * not put a stale value back into the SP register.\n */\n dst = (dst - 2) & 0xffff;\n /*\n * And on the 8086/8088, the value we just calculated also happens to be the value that must\n * be pushed.\n */\n if (this.model < X86.MODEL_80286) w = dst;\n }\n this.pushWord(w);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesPushReg : this.cycleCounts.nOpCyclesPushMem);\n /*\n * The PUSH is the only write that needs to occur; dst was the source operand and does not need to be rewritten.\n */\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnRCLb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnRCLb = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = this.getCarry();\n count %= 9;\n if (!count) {\n carry <<= 7;\n } else {\n result = ((dst << count) | (carry << (count - 1)) | (dst >> (9 - count))) & 0xff;\n carry = dst << (count - 1);\n }\n this.setRotateResult(result, carry, X86.RESULT.BYTE);\n }\n return result;\n};\n\n/**\n * fnRCLw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnRCLw = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = this.getCarry();\n count %= 17;\n if (!count) {\n carry <<= 15;\n } else {\n result = ((dst << count) | (carry << (count - 1)) | (dst >> (17 - count))) & 0xffff;\n carry = dst << (count - 1);\n }\n this.setRotateResult(result, carry, X86.RESULT.WORD);\n }\n return result;\n};\n\n/**\n * fnRCLd(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnRCLd = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask; // this 32-bit-only function could mask with 0x1f directly\n if (count) {\n var carry = this.getCarry();\n /*\n * JavaScript Alert: much like a post-8086 Intel CPU, JavaScript shift counts are mod 32,\n * so \"dst >>> 32\" is equivalent to \"dst >>> 0\", which doesn't shift any bits at all. To\n * compensate, we shift one bit less than the maximum, and then shift one bit farther.\n */\n result = (dst << count) | (carry << (count - 1)) | ((dst >>> (32 - count)) >>> 1);\n carry = dst << (count - 1);\n this.setRotateResult(result, carry, X86.RESULT.DWORD);\n }\n return result;\n};\n\n/**\n * fnRCRb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnRCRb = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = this.getCarry();\n count %= 9;\n if (!count) {\n carry <<= 7;\n } else {\n result = ((dst >> count) | (carry << (8 - count)) | (dst << (9 - count))) & 0xff;\n carry = dst << (8 - count);\n }\n this.setRotateResult(result, carry, X86.RESULT.BYTE);\n }\n return result;\n};\n\n/**\n * fnRCRw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnRCRw = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = this.getCarry();\n count %= 17;\n if (!count) {\n carry <<= 15;\n } else {\n result = ((dst >> count) | (carry << (16 - count)) | (dst << (17 - count))) & 0xffff;\n carry = dst << (16 - count);\n }\n this.setRotateResult(result, carry, X86.RESULT.WORD);\n }\n return result;\n};\n\n/**\n * fnRCRd(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnRCRd = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask; // this 32-bit-only function could mask with 0x1f directly\n if (count) {\n var carry = this.getCarry();\n /*\n * JavaScript Alert: much like a post-8086 Intel CPU, JavaScript shift counts are mod 32,\n * so \"dst << 32\" is equivalent to \"dst << 0\", which doesn't shift any bits at all. To\n * compensate, we shift one bit less than the maximum, and then shift one bit farther.\n */\n result = (dst >>> count) | (carry << (32 - count)) | ((dst << (32 - count)) << 1);\n carry = dst << (32 - count);\n this.setRotateResult(result, carry, X86.RESULT.DWORD);\n }\n return result;\n};\n\n/**\n * fnROLb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnROLb = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry;\n count &= 0x7;\n if (!count) {\n carry = dst << 7;\n } else {\n carry = dst << (count - 1);\n result = ((dst << count) | (dst >> (8 - count))) & 0xff;\n }\n this.setRotateResult(result, carry, X86.RESULT.BYTE);\n }\n return result;\n};\n\n/**\n * fnROLw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnROLw = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry;\n count &= 0xf;\n if (!count) {\n carry = dst << 15;\n } else {\n carry = dst << (count - 1);\n result = ((dst << count) | (dst >> (16 - count))) & 0xffff;\n }\n this.setRotateResult(result, carry, X86.RESULT.WORD);\n }\n return result;\n};\n\n/**\n * fnROLd(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnROLd = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = dst << (count - 1);\n result = (dst << count) | (dst >>> (32 - count));\n this.setRotateResult(result, carry, X86.RESULT.DWORD);\n }\n return result;\n};\n\n/**\n * fnRORb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnRORb = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry;\n count &= 0x7;\n if (!count) {\n carry = dst;\n } else {\n carry = dst << (8 - count);\n result = ((dst >>> count) | carry) & 0xff;\n }\n this.setRotateResult(result, carry, X86.RESULT.BYTE);\n }\n return result;\n};\n\n/**\n * fnRORw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnRORw = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry;\n count &= 0xf;\n if (!count) {\n carry = dst;\n } else {\n carry = dst << (16 - count);\n result = ((dst >>> count) | carry) & 0xffff;\n }\n this.setRotateResult(result, carry, X86.RESULT.WORD);\n }\n return result;\n};\n\n/**\n * fnRORd(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnRORd = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = dst << (32 - count);\n result = (dst >>> count) | carry;\n this.setRotateResult(result, carry, X86.RESULT.DWORD);\n }\n return result;\n};\n\n/**\n * fnSARb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)\n * @return {number}\n */\nX86.fnSARb = function(dst, src)\n{\n var count = src & this.nShiftCountMask;\n if (count) {\n if (count > 9) count = 9;\n var carry = ((dst << 24) >> 24) >> (count - 1);\n dst = (carry >> 1) & 0xff;\n this.setLogicResult(dst, X86.RESULT.BYTE, carry & 0x1);\n }\n return dst;\n};\n\n/**\n * fnSARw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)\n * @return {number}\n */\nX86.fnSARw = function(dst, src)\n{\n var count = src & this.nShiftCountMask;\n if (count) {\n if (count > 17) count = 17;\n var carry = ((dst << 16) >> 16) >> (count - 1);\n dst = (carry >> 1) & 0xffff;\n this.setLogicResult(dst, X86.RESULT.WORD, carry & 0x1);\n }\n return dst;\n};\n\n/**\n * fnSARd(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)\n * @return {number}\n */\nX86.fnSARd = function(dst, src)\n{\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = dst >> (count - 1);\n dst = (carry >> 1);\n this.setLogicResult(dst, X86.RESULT.DWORD, carry & 0x1);\n }\n return dst;\n};\n\n/**\n * fnSBBb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSBBb = function(dst, src)\n{\n var b = (dst - src - this.getCarry())|0;\n this.setArithResult(dst, src, b, X86.RESULT.BYTE | X86.RESULT.ALL, true);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return b & 0xff;\n};\n\n/**\n * fnSBBw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSBBw = function(dst, src)\n{\n var w = (dst - src - this.getCarry())|0;\n this.setArithResult(dst, src, w, this.typeData | X86.RESULT.ALL, true);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return w & this.maskData;\n};\n\n/**\n * fnSETO(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETO = function(dst, src)\n{\n return (this.getOF()? 1 : 0);\n};\n\n/**\n * fnSETNO(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETNO = function(dst, src)\n{\n return (this.getOF()? 0 : 1);\n};\n\n/**\n * fnSETC(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETC = function(dst, src)\n{\n return (this.getCF()? 1 : 0);\n};\n\n/**\n * fnSETNC(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETNC = function(dst, src)\n{\n return (this.getCF()? 0 : 1);\n};\n\n/**\n * fnSETZ(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETZ = function(dst, src)\n{\n return (this.getZF()? 1 : 0);\n};\n\n/**\n * fnSETNZ(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETNZ = function(dst, src)\n{\n return (this.getZF()? 0 : 1);\n};\n\n/**\n * fnSETBE(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETBE = function(dst, src)\n{\n return (this.getCF() || this.getZF()? 1 : 0);\n};\n\n/**\n * fnSETNBE(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETNBE = function(dst, src)\n{\n return (this.getCF() || this.getZF()? 0 : 1);\n};\n\n/**\n * fnSETS(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETS = function(dst, src)\n{\n return (this.getSF()? 1 : 0);\n};\n\n/**\n * fnSETNS(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETNS = function(dst, src)\n{\n return (this.getSF()? 0 : 1);\n};\n\n/**\n * fnSETP(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETP = function(dst, src)\n{\n return (this.getPF()? 1 : 0);\n};\n\n/**\n * fnSETNP(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETNP = function(dst, src)\n{\n return (this.getPF()? 0 : 1);\n};\n\n/**\n * fnSETL(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETL = function(dst, src)\n{\n return (!this.getSF() != !this.getOF()? 1 : 0);\n};\n\n/**\n * fnSETNL(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETNL = function(dst, src)\n{\n return (!this.getSF() != !this.getOF()? 0 : 1);\n};\n\n/**\n * fnSETLE(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETLE = function(dst, src)\n{\n return (this.getZF() || !this.getSF() != !this.getOF()? 1 : 0);\n};\n\n/**\n * fnSETNLE(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETNLE = function(dst, src)\n{\n return (this.getZF() || !this.getSF() != !this.getOF()? 0 : 1);\n};\n\n/**\n * fnSGDT(dst, src)\n *\n * op=0x0F,0x01,reg=0x0 (GRP7:SGDT)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnSGDT = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n X86.opInvalid.call(this);\n } else {\n /*\n * We don't need to set the first word of the operand, because the ModRM group decoder that calls us\n * does that automatically with the value we return (dst).\n */\n dst = this.addrGDTLimit - this.addrGDT;\n\n\n var addr = this.addrGDT;\n if (this.model == X86.MODEL_80286) {\n /*\n * We previously left the 6th byte of the target operand \"undefined\". But it turns out we have to set\n * it to *something*, because there's processor detection in PC-DOS 7.0 (at least in the SETUP portion)\n * that looks like this:\n *\n * 145E:4B84 9C PUSHF\n * 145E:4B85 55 PUSH BP\n * 145E:4B86 8BEC MOV BP,SP\n * 145E:4B88 B80000 MOV AX,0000\n * 145E:4B8B 50 PUSH AX\n * 145E:4B8C 9D POPF\n * 145E:4B8D 9C PUSHF\n * 145E:4B8E 58 POP AX\n * 145E:4B8F 2500F0 AND AX,F000\n * 145E:4B92 3D00F0 CMP AX,F000\n * 145E:4B95 7511 JNZ 4BA8\n * 145E:4BA8 C8060000 ENTER 0006,00\n * 145E:4BAC 0F0146FA SGDT [BP-06]\n * 145E:4BB0 807EFFFF CMP [BP-01],FF\n * 145E:4BB4 C9 LEAVE\n * 145E:4BB5 BA8603 MOV DX,0386\n * 145E:4BB8 7503 JNZ 4BBD\n * 145E:4BBA BA8602 MOV DX,0286\n * 145E:4BBD 89163004 MOV [0430],DX\n * 145E:4BC1 5D POP BP\n * 145E:4BC2 9D POPF\n * 145E:4BC3 CB RETF\n *\n * This code is expecting SGDT on an 80286 to set the 6th \"undefined\" byte to 0xFF, so that's what we do.\n */\n addr |= (0xff000000|0);\n }\n else if (this.model >= X86.MODEL_80386) {\n /*\n * The 80386 added another wrinkle: Intel's documentation claimed that the 6th byte is either set to zero\n * or the high byte of the BASE field, depending on the OPERAND size; from the \"INTEL 80386 PROGRAMMER'S\n * REFERENCE MANUAL 1986\":\n *\n * The LIMIT field of the [GDTR or IDTR] register is assigned to the first word at the effective address.\n * If the operand-size attribute is 32 bits, the next three bytes are assigned the BASE field of the\n * register, and the fourth byte is written with zero. The last byte is undefined. Otherwise, if the\n * operand-size attribute is 16 bits, the next 4 bytes are assigned the 32-bit BASE field of the register.\n *\n * However, Intel obviously meant the reverse (ie, that the BASE field is truncated when using a 16-bit\n * OPERAND size, not when using a 32-bit OPERAND size).\n */\n if (this.sizeData == 2) {\n /*\n * Thanks to Michal Necasek, we now know that the: \"386 in reality does not pay attention to the operand\n * size (despite Intel's claims to the contrary). In fact Windows 3.11/Win32s relies on it -- at least in\n * some configurations, it will execute SGDT in 16-bit code and will crash if all 6 bytes aren't stored.\"\n *\n * Based on the above information, we no longer mask the 6th byte on the 80386 when the OPERAND size is 2.\n *\n * addr &= 0x00ffffff;\n */\n } else {\n /*\n * When the OPERAND size is 4, our ModRM group decoder will call setLong(dst) rather than setShort(dst);\n * we could fix that by calling setDataSize(2), but it seems safer/simpler to set the high bits (16-31)\n * of dst to match the low bits (0-15) of addr, so that the caller will harmlessly rewrite what we are\n * already writing with the setLong() below.\n */\n dst |= (addr << 16);\n }\n }\n this.setLong(this.regEA + 2, addr);\n this.nStepCycles -= 11;\n }\n return dst;\n};\n\n/**\n * fnSHLb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)\n * @return {number}\n */\nX86.fnSHLb = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = 0;\n if (count > 8) {\n result = 0;\n } else {\n carry = dst << (count - 1);\n result = (carry << 1) & 0xff;\n }\n this.setLogicResult(result, X86.RESULT.BYTE, carry & X86.RESULT.BYTE, (result ^ carry) & X86.RESULT.BYTE);\n }\n return result;\n};\n\n/**\n * fnSHLw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)\n * @return {number}\n */\nX86.fnSHLw = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = 0;\n if (count > 16) {\n result = 0;\n } else {\n carry = dst << (count - 1);\n result = (carry << 1) & 0xffff;\n }\n this.setLogicResult(result, X86.RESULT.WORD, carry & X86.RESULT.WORD, (result ^ carry) & X86.RESULT.WORD);\n }\n return result;\n};\n\n/**\n * fnSHLd(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)\n * @return {number}\n */\nX86.fnSHLd = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask; // this 32-bit-only function could mask with 0x1f directly\n if (count) {\n var carry = dst << (count - 1);\n result = (carry << 1);\n this.setLogicResult(result, X86.RESULT.DWORD, carry & X86.RESULT.DWORD, (result ^ carry) & X86.RESULT.DWORD);\n }\n return result;\n};\n\n/**\n * fnSHLDwi(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSHLDwi = function(dst, src)\n{\n return X86.helpSHLDw.call(this, dst, src, this.getIPByte());\n};\n\n/**\n * fnSHLDdi(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSHLDdi = function(dst, src)\n{\n return X86.helpSHLDd.call(this, dst, src, this.getIPByte());\n};\n\n/**\n * fnSHLDwCL(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSHLDwCL = function(dst, src)\n{\n return X86.helpSHLDw.call(this, dst, src, this.regECX & 0x1f);\n};\n\n/**\n * fnSHLDdCL(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSHLDdCL = function(dst, src)\n{\n return X86.helpSHLDd.call(this, dst, src, this.regECX & 0x1f);\n};\n\n/**\n * fnSHRb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)\n * @return {number}\n */\nX86.fnSHRb = function(dst, src)\n{\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = (count > 8? 0 : (dst >>> (count - 1)));\n dst = (carry >>> 1) & 0xff;\n this.setLogicResult(dst, X86.RESULT.BYTE, carry & 0x1, dst & X86.RESULT.BYTE);\n }\n return dst;\n};\n\n/**\n * fnSHRw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)\n * @return {number}\n */\nX86.fnSHRw = function(dst, src)\n{\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = (count > 16? 0 : (dst >>> (count - 1)));\n dst = (carry >>> 1) & 0xffff;\n this.setLogicResult(dst, X86.RESULT.WORD, carry & 0x1, dst & X86.RESULT.WORD);\n }\n return dst;\n};\n\n/**\n * fnSHRd(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)\n * @return {number}\n */\nX86.fnSHRd = function(dst, src)\n{\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = (dst >>> (count - 1));\n dst = (carry >>> 1);\n this.setLogicResult(dst, X86.RESULT.DWORD, carry & 0x1, dst & X86.RESULT.DWORD);\n }\n return dst;\n};\n\n/**\n * fnSHRDwi(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSHRDwi = function(dst, src)\n{\n return X86.helpSHRDw.call(this, dst, src, this.getIPByte());\n};\n\n/**\n * fnSHRDdi(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSHRDdi = function(dst, src)\n{\n return X86.helpSHRDd.call(this, dst, src, this.getIPByte());\n};\n\n/**\n * fnSHRDwCL(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSHRDwCL = function(dst, src)\n{\n return X86.helpSHRDw.call(this, dst, src, this.regECX & 0x1f);\n};\n\n/**\n * fnSHRDdCL(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSHRDdCL = function(dst, src)\n{\n return X86.helpSHRDd.call(this, dst, src, this.regECX & 0x1f);\n};\n\n/**\n * fnSIDT(dst, src)\n *\n * op=0x0F,0x01,reg=0x1 (GRP7:SIDT)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnSIDT = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n X86.opInvalid.call(this);\n } else {\n /*\n * We don't need to set the first word of the operand, because the ModRM group decoder that calls us\n * does that automatically with the value we return (dst).\n */\n dst = this.addrIDTLimit - this.addrIDT;\n\n /*\n * As with SGDT, the 6th byte is technically \"undefined\" on an 80286, but we now set it to 0xFF, for the\n * same reasons discussed in SGDT (above).\n */\n var addr = this.addrIDT;\n if (this.model == X86.MODEL_80286) {\n addr |= (0xff000000|0);\n }\n else if (this.model >= X86.MODEL_80386) {\n if (this.sizeData == 2) {\n /*\n * Based on the SGDT information above, we no longer mask the 6th byte when the OPERAND size is 2.\n *\n * addr &= 0x00ffffff;\n */\n } else {\n dst |= (addr << 16);\n }\n }\n this.setLong(this.regEA + 2, addr);\n this.nStepCycles -= 12;\n }\n return dst;\n};\n\n/**\n * fnSLDT(dst, src)\n *\n * op=0x0F,0x00,reg=0x0 (GRP6:SLDT)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnSLDT = function(dst, src)\n{\n this.nStepCycles -= (2 + (this.regEA === X86.ADDR_INVALID? 0 : 1));\n return this.segLDT.sel;\n};\n\n/**\n * fnSMSW(dst, src)\n *\n * TODO: I've seen a claim that SMSW can be used with an operand size override to obtain the entire CR0.\n * I don't dispute that, and since I don't mask the return value, that should be possible here; however, it\n * should still be confirmed on real hardware at some point. Note that this differs from LMSW, which is\n * REQUIRED to mask the source operand.\n *\n * op=0x0F,0x01,reg=0x4 (GRP7:SMSW)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnSMSW = function(dst, src)\n{\n this.nStepCycles -= (2 + (this.regEA === X86.ADDR_INVALID? 0 : 1));\n return this.regCR0;\n};\n\n/**\n * fnSTR(dst, src)\n *\n * op=0x0F,0x00,reg=0x1 (GRP6:STR)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnSTR = function(dst, src)\n{\n this.nStepCycles -= (2 + (this.regEA === X86.ADDR_INVALID? 0 : 1));\n return this.segTSS.sel;\n};\n\n/**\n * fnSUBb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSUBb = function(dst, src)\n{\n var b = (dst - src)|0;\n this.setArithResult(dst, src, b, X86.RESULT.BYTE | X86.RESULT.ALL, true);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return b & 0xff;\n};\n\n/**\n * fnSUBw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSUBw = function(dst, src)\n{\n var w = (dst - src)|0;\n this.setArithResult(dst, src, w, this.typeData | X86.RESULT.ALL, true);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return w & this.maskData;\n};\n\n/**\n * fnTESTib(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null; we have to supply the source ourselves)\n * @return {number}\n */\nX86.fnTESTib = function(dst, src)\n{\n src = this.getIPByte();\n this.setLogicResult(dst & src, X86.RESULT.BYTE);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesTestRI : this.cycleCounts.nOpCyclesTestMI);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnTESTiw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null; we have to supply the source ourselves)\n * @return {number}\n */\nX86.fnTESTiw = function(dst, src)\n{\n src = this.getIPWord();\n this.setLogicResult(dst & src, this.typeData);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesTestRI : this.cycleCounts.nOpCyclesTestMI);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnTESTb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnTESTb = function(dst, src)\n{\n this.setLogicResult(dst & src, X86.RESULT.BYTE);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesTestRR : this.cycleCounts.nOpCyclesTestRM) : this.cycleCounts.nOpCyclesTestRM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnTESTw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnTESTw = function(dst, src)\n{\n this.setLogicResult(dst & src, this.typeData);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesTestRR : this.cycleCounts.nOpCyclesTestRM) : this.cycleCounts.nOpCyclesTestRM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnVERR(dst, src)\n *\n * op=0x0F,0x00,reg=0x4 (GRP6:VERR)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnVERR = function(dst, src)\n{\n this.opFlags |= X86.OPFLAG.NOWRITE;\n /*\n * Currently, segVER.load() will return an error only if the selector is beyond the bounds of the\n * descriptor table or the descriptor is not for a segment.\n */\n this.nStepCycles -= (14 + (this.regEA === X86.ADDR_INVALID? 0 : 2));\n if (this.segVER.load(dst) !== X86.ADDR_INVALID) {\n /*\n * Verify that this is a readable segment; that is, of these four combinations (code+readable,\n * code+nonreadable, data+writable, date+nonwritable), make sure we're not the second combination.\n */\n if ((this.segVER.acc & (X86.DESC.ACC.TYPE.READABLE | X86.DESC.ACC.TYPE.CODE)) != X86.DESC.ACC.TYPE.CODE) {\n /*\n * For VERR, if the code segment is readable and conforming, the descriptor privilege level\n * (DPL) can be any value.\n *\n * Otherwise, DPL must be greater than or equal to (have less or the same privilege as) both the\n * current privilege level and the selector's RPL.\n */\n if (this.segVER.dpl >= this.nCPL && this.segVER.dpl >= (dst & X86.SEL.RPL) ||\n (this.segVER.acc & X86.DESC.ACC.TYPE.CODE_CONFORMING) == X86.DESC.ACC.TYPE.CODE_CONFORMING) {\n this.setZF();\n return dst;\n }\n }\n }\n this.clearZF();\n if (DEBUG && (this.sizeData > 2 || this.sizeAddr > 2)) this.stopCPU();\n return dst;\n};\n\n/**\n * fnVERW(dst, src)\n *\n * op=0x0F,0x00,reg=0x5 (GRP6:VERW)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnVERW = function(dst, src)\n{\n this.opFlags |= X86.OPFLAG.NOWRITE;\n /*\n * Currently, segVER.load() will return an error only if the selector is beyond the bounds of the\n * descriptor table or the descriptor is not for a segment.\n */\n this.nStepCycles -= (14 + (this.regEA === X86.ADDR_INVALID? 0 : 2));\n if (this.segVER.load(dst) !== X86.ADDR_INVALID) {\n /*\n * Verify that this is a writable data segment\n */\n if ((this.segVER.acc & (X86.DESC.ACC.TYPE.WRITABLE | X86.DESC.ACC.TYPE.CODE)) == X86.DESC.ACC.TYPE.WRITABLE) {\n /*\n * DPL must be greater than or equal to (have less or the same privilege as) both the current\n * privilege level and the selector's RPL.\n */\n if (this.segVER.dpl >= this.nCPL && this.segVER.dpl >= (dst & X86.SEL.RPL)) {\n this.setZF();\n return dst;\n }\n }\n }\n this.clearZF();\n if (DEBUG && (this.sizeData > 2 || this.sizeAddr > 2)) this.stopCPU();\n return dst;\n};\n\n/**\n * fnIBTS(dst, src)\n *\n * As best I can determine, this function copies the specified bits from src (starting at bit 0 for CL\n * bits) to dst (starting at bit offset in AX). For register operands, that's simple enough.\n *\n * TODO: If dst refers to a memory location, then the bit index may refer to higher memory locations, just\n * like the BT/BTC/BTR/BTS instructions. For an instruction that no one was really able to use, except\n * as a CPU stepping discriminator, that doesn't seem worth the effort.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnIBTS = function(dst, src)\n{\n var shift = (this.regEAX & this.maskData);\n var mask = ((1 << (this.regECX & 0x1f)) - 1);\n return (dst & ~(mask << shift)) | ((src & mask) << shift);\n};\n\n/**\n * fnXBTS(dst, src)\n *\n * As best I can determine, this function copies the specified bits from src (starting at the bit offset\n * in AX, for the bit length in CL) to dst (starting at bit 0). For register operands, that's simple enough.\n *\n * TODO: If src refers to a memory location, then the bit index may refer to higher memory locations, just\n * like the BT/BTC/BTR/BTS instructions. For an instruction that no one was really able to use, except\n * as a CPU stepping discriminator, that doesn't seem worth the effort.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnXBTS = function(dst, src)\n{\n /*\n * Shift src right by the bit offset in [E]AX, then apply a mask equal to the number of bits in CL,\n * then mask the resulting bit string with the current OPERAND size.\n */\n return ((src >> (this.regEAX & this.maskData)) & ((1 << (this.regECX & 0x1f)) - 1)) & this.maskData;\n};\n\n/**\n * fnXCHGrb(dst, src)\n *\n * If an instruction like \"XCHG AL,AH\" was a traditional \"op dst,src\" instruction, dst would contain AL,\n * src would contain AH, and we would return src, which the caller would then store in AL, and we'd be done.\n *\n * However, that's only half of what XCHG does, so THIS function must perform the other half; in the previous\n * example, that means storing the original AL (dst) into AH (src).\n *\n * BACKTRACK support is incomplete without also passing bti values as parameters, because the caller will\n * store btiAH in btiAL, but the original btiAL will be lost. Similarly, if src is a memory operand, the\n * caller will store btiEALo in btiAL, but again, the original btiAL will be lost.\n *\n * BACKTRACK support for memory operands could be fixed by decoding the dst register in order to determine the\n * corresponding bti and then temporarily storing it in btiEALo around the setEAByte() call below. Register-only\n * XCHGs would require a more extensive hack. For now, I'm going to live with one-way BACKTRACK support here.\n *\n * TODO: Implement full BACKTRACK support for XCHG instructions.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnXCHGrb = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n /*\n * Decode which register was src\n */\n\n switch (this.bModRM & 0x7) {\n case 0x0: // AL\n this.regEAX = (this.regEAX & ~0xff) | dst;\n break;\n case 0x1: // CL\n this.regECX = (this.regECX & ~0xff) | dst;\n break;\n case 0x2: // DL\n this.regEDX = (this.regEDX & ~0xff) | dst;\n break;\n case 0x3: // BL\n this.regEBX = (this.regEBX & ~0xff) | dst;\n break;\n case 0x4: // AH\n this.regEAX = (this.regEAX & ~0xff00) | (dst << 8);\n break;\n case 0x5: // CH\n this.regECX = (this.regECX & ~0xff00) | (dst << 8);\n break;\n case 0x6: // DH\n this.regEDX = (this.regEDX & ~0xff00) | (dst << 8);\n break;\n case 0x7: // BH\n this.regEBX = (this.regEBX & ~0xff00) | (dst << 8);\n break;\n default:\n break; // there IS no other case, but JavaScript inspections don't know that\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesXchgRR;\n } else {\n /*\n * This is a case where the ModRM decoder that's calling us didn't know it should have set regEAWrite,\n * so we compensate by updating regEAWrite. However, setEAWord() has since been changed to revalidate\n * the write using segEA:offEA, so updating regEAWrite here isn't strictly necessary.\n */\n this.regEAWrite = this.regEA;\n this.setEAByte(dst);\n this.nStepCycles -= this.cycleCounts.nOpCyclesXchgRM;\n }\n return src;\n};\n\n/**\n * fnXCHGrw(dst, src)\n *\n * If an instruction like \"XCHG AX,DX\" was a traditional \"op dst,src\" instruction, dst would contain AX,\n * src would contain DX, and we would return src, which the caller would then store in AX, and we'd be done.\n *\n * However, that's only half of what XCHG does, so THIS function must perform the other half; in the previous\n * example, that means storing the original AX (dst) into DX (src).\n *\n * TODO: Implement full BACKTRACK support for XCHG instructions (see fnXCHGrb comments).\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnXCHGrw = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n /*\n * Decode which register was src\n */\n\n switch (this.bModRM & 0x7) {\n case 0x0: // [E]AX\n this.regEAX = (this.regEAX & ~this.maskData) | dst;\n break;\n case 0x1: // [E]CX\n this.regECX = (this.regECX & ~this.maskData) | dst;\n break;\n case 0x2: // [E]DX\n this.regEDX = (this.regEDX & ~this.maskData) | dst;\n break;\n case 0x3: // [E]BX\n this.regEBX = (this.regEBX & ~this.maskData) | dst;\n break;\n case 0x4: // [E]SP\n this.setSP((this.getSP() & ~this.maskData) | dst);\n break;\n case 0x5: // [E]BP\n this.regEBP = (this.regEBX & ~this.maskData) | dst;\n break;\n case 0x6: // [E]SI\n this.regESI = (this.regESI & ~this.maskData) | dst;\n break;\n case 0x7: // [E]DI\n this.regEDI = (this.regEDI & ~this.maskData) | dst;\n break;\n default:\n break; // there IS no other case, but JavaScript inspections don't know that\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesXchgRR;\n } else {\n /*\n * This is a case where the ModRM decoder that's calling us didn't know it should have set regEAWrite,\n * so we compensate by updating regEAWrite. However, setEAWord() has since been changed to revalidate\n * the write using segEA:offEA, so updating regEAWrite here isn't strictly necessary.\n */\n this.regEAWrite = this.regEA;\n this.setEAWord(dst);\n this.nStepCycles -= this.cycleCounts.nOpCyclesXchgRM;\n }\n return src;\n};\n\n/**\n * fnXORb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnXORb = function(dst, src)\n{\n var b = dst ^ src;\n this.setLogicResult(b, X86.RESULT.BYTE);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return b;\n};\n\n/**\n * fnXORw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnXORw = function(dst, src)\n{\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return this.setLogicResult(dst ^ src, this.typeData) & this.maskData;\n};\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/x86help.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * helpAdd64(r64Dst, r64Src)\n *\n * Adds r64Src to r64Dst.\n *\n * @param {Array.<number>} r64Dst is a 64-bit value\n * @param {Array.<number>} r64Src is a 64-bit value\n */\nX86.helpAdd64 = function(r64Dst, r64Src)\n{\n r64Dst[0] += r64Src[0];\n r64Dst[1] += r64Src[1];\n if (r64Dst[0] > 0xffffffff) {\n r64Dst[0] >>>= 0; // truncate r64Dst[0] to 32 bits AND keep it unsigned\n r64Dst[1]++;\n }\n};\n\n/**\n * helpCmp64(r64Dst, r64Src)\n *\n * Compares r64Dst to r64Src, by computing r64Dst - r64Src.\n *\n * @param {Array.<number>} r64Dst is a 64-bit value\n * @param {Array.<number>} r64Src is a 64-bit value\n * @return {number} > 0 if r64Dst > r64Src, == 0 if r64Dst == r64Src, < 0 if r64Dst < r64Src\n */\nX86.helpCmp64 = function(r64Dst, r64Src)\n{\n var result = r64Dst[1] - r64Src[1];\n if (!result) result = r64Dst[0] - r64Src[0];\n return result;\n};\n\n/**\n * helpSet64(r64Dst, lo, hi)\n *\n * @param {Array.<number>} r64Dst\n * @param {number} lo\n * @param {number} hi\n * @return {Array.<number>}\n */\nX86.helpSet64 = function(r64Dst, lo, hi)\n{\n r64Dst[0] = lo >>> 0;\n r64Dst[1] = hi >>> 0;\n return r64Dst;\n};\n\n/**\n * helpShr64(r64Dst)\n *\n * Shifts r64Dst right one bit.\n *\n * @param {Array.<number>} r64Dst is a 64-bit value\n */\nX86.helpShr64 = function(r64Dst)\n{\n r64Dst[0] >>>= 1;\n if (r64Dst[1] & 0x1) {\n r64Dst[0] = (r64Dst[0] | 0x80000000) >>> 0;\n }\n r64Dst[1] >>>= 1;\n};\n\n/**\n * helpSub64(r64Dst, r64Src)\n *\n * Subtracts r64Src from r64Dst.\n *\n * @param {Array.<number>} r64Dst is a 64-bit value\n * @param {Array.<number>} r64Src is a 64-bit value\n */\nX86.helpSub64 = function(r64Dst, r64Src)\n{\n r64Dst[0] -= r64Src[0];\n r64Dst[1] -= r64Src[1];\n if (r64Dst[0] < 0) {\n r64Dst[0] >>>= 0; // truncate r64Dst[0] to 32 bits AND keep it unsigned\n r64Dst[1]--;\n }\n};\n\n/**\n * helpDECreg(w)\n *\n * @this {CPUX86}\n * @param {number} w\n * @return {number}\n */\nX86.helpDECreg = function(w)\n{\n var result = (w - 1)|0;\n this.setArithResult(w, 1, result, this.typeData | X86.RESULT.NOTCF, true);\n this.nStepCycles -= 2; // the register form of DEC takes 2 cycles on all CPUs\n return (w & ~this.maskData) | (result & this.maskData);\n};\n\n/**\n * helpDIV32(dstLo, dstHi, src)\n *\n * This sets regMDLo to dstHi:dstLo / src, and regMDHi to dstHi:dstLo % src; all inputs are treated as unsigned.\n *\n * Refer to: http://lxr.linux.no/linux+v2.6.22/lib/div64.c\n *\n * @this {CPUX86}\n * @param {number} dstLo (low 32-bit portion of dividend)\n * @param {number} dstHi (high 32-bit portion of dividend)\n * @param {number} src (32-bit divisor)\n * @return {boolean} true if successful, false if overflow (ie, the divisor was either zero or too small)\n */\nX86.helpDIV32 = function(dstLo, dstHi, src)\n{\n src >>>= 0;\n\n if (!src || src <= (dstHi >>> 0)) {\n return false;\n }\n\n var result = 0, bit = 1;\n\n var r64Div = X86.helpSet64(this.r64Div, src, 0);\n var r64Rem = X86.helpSet64(this.r64Rem, dstLo, dstHi);\n\n while (X86.helpCmp64(r64Rem, r64Div) > 0) {\n X86.helpAdd64(r64Div, r64Div);\n bit += bit;\n }\n do {\n if (X86.helpCmp64(r64Rem, r64Div) >= 0) {\n X86.helpSub64(r64Rem, r64Div);\n result += bit;\n }\n X86.helpShr64(r64Div);\n bit /= 2;\n } while (bit >= 1);\n\n\n\n this.regMDLo = result; // result is the quotient, which callers expect in the low MD register\n this.regMDHi = r64Rem[0]; // r64Rem[0] is the remainder, which callers expect in the high MD register\n return true;\n};\n\n/**\n * helpIDIV32(dstLo, dstHi, src)\n *\n * This sets regMDLo to dstHi:dstLo / src, and regMDHi to dstHi:dstLo % src; all inputs are treated as signed.\n *\n * Refer to: http://lxr.linux.no/linux+v2.6.22/lib/div64.c\n *\n * @this {CPUX86}\n * @param {number} dstLo (low 32-bit portion of dividend)\n * @param {number} dstHi (high 32-bit portion of dividend)\n * @param {number} src (32-bit divisor)\n * @return {boolean} true if successful, false if overflow (ie, the divisor was either zero or too small)\n */\nX86.helpIDIV32 = function(dstLo, dstHi, src)\n{\n var bNegLo = 0, bNegHi = 0;\n /*\n * dividend divisor quotient remainder\n * (dst) (src) (lo) (hi)\n * -------- ------- -------- ---------\n * + + -> + +\n * + - -> - +\n * - + -> - -\n * - - -> + -\n */\n if (src < 0) {\n src = -src|0;\n bNegLo = 1 - bNegLo;\n }\n if (dstHi < 0) {\n dstLo = -dstLo|0;\n dstHi = (~dstHi + (dstLo? 0 : 1))|0;\n bNegHi = 1;\n bNegLo = 1 - bNegLo;\n }\n if (!X86.helpDIV32.call(this, dstLo, dstHi, src) || this.regMDLo > 0x7fffffff+bNegLo || this.regMDHi > 0x7fffffff+bNegHi) {\n return false;\n }\n if (bNegLo) this.regMDLo = -this.regMDLo;\n if (bNegHi) this.regMDHi = -this.regMDHi;\n return true;\n};\n\n/**\n * helpINCreg(w)\n *\n * @this {CPUX86}\n * @param {number} w\n * @return {number}\n */\nX86.helpINCreg = function(w)\n{\n var result = (w + 1)|0;\n this.setArithResult(w, 1, result, this.typeData | X86.RESULT.NOTCF);\n this.nStepCycles -= 2; // the register form of INC takes 2 cycles on all CPUs\n return (w & ~this.maskData) | (result & this.maskData);\n};\n\n/**\n * helpLoadCR0(l)\n *\n * This is called by an 80386 control instruction (ie, MOV CR0,reg).\n *\n * TODO: Determine which CR0 bits, if any, cannot be modified by MOV CR0,reg.\n *\n * @this {CPUX86}\n * @param {number} l\n */\nX86.helpLoadCR0 = function(l)\n{\n this.regCR0 = l;\n this.setProtMode();\n if (this.regCR0 & X86.CR0.PG) {\n /*\n * TODO: Determine if setting X86.CR0.PG when already set should really act as a flush;\n * I'm not currently worried about it, because I'm assuming CR0 is not rewritten that often.\n */\n this.enablePageBlocks();\n } else {\n this.disablePageBlocks();\n }\n};\n\n/**\n * helpLoadCR3(l)\n *\n * This is called by an 80386 control instruction (ie, MOV CR3,reg) or an 80386 task switch.\n *\n * @this {CPUX86}\n * @param {number} l\n */\nX86.helpLoadCR3 = function(l)\n{\n this.regCR3 = l;\n /*\n * Normal use of regCR3 involves adding a 0-4K (12-bit) offset to obtain a page directory entry,\n * so let's ensure that the low 12 bits of regCR3 are always zero.\n */\n\n this.flushPageBlocks();\n};\n\n/**\n * helpSETcc()\n *\n * @this {CPUX86}\n * @param {function(number,number)} fnSet\n */\nX86.helpSETcc = function(fnSet)\n{\n this.opFlags |= X86.OPFLAG.NOREAD;\n this.decodeModMemByte.call(this, fnSet);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 4 : 5);\n};\n\n/**\n * helpSHLDw(dst, src, count)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @param {number} count (0-31)\n * @return {number}\n */\nX86.helpSHLDw = function(dst, src, count)\n{\n if (count) {\n if (count > 16) {\n dst = src;\n count -= 16;\n }\n var carry = dst << (count - 1);\n dst = ((carry << 1) | (src >>> (16 - count))) & 0xffff;\n this.setLogicResult(dst, X86.RESULT.WORD, carry & X86.RESULT.WORD);\n }\n return dst;\n};\n\n/**\n * helpSHLDd(dst, src, count)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @param {number} count\n * @return {number}\n */\nX86.helpSHLDd = function(dst, src, count)\n{\n if (count) {\n var carry = dst << (count - 1);\n dst = (carry << 1) | (src >>> (32 - count));\n this.setLogicResult(dst, X86.RESULT.DWORD, carry & X86.RESULT.DWORD);\n }\n return dst;\n};\n\n/**\n * helpSHRDw(dst, src, count)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @param {number} count (0-31)\n * @return {number}\n */\nX86.helpSHRDw = function(dst, src, count)\n{\n if (count) {\n if (count > 16) {\n dst = src;\n count -= 16;\n }\n var carry = dst >>> (count - 1);\n dst = ((carry >>> 1) | (src << (16 - count))) & 0xffff;\n this.setLogicResult(dst, X86.RESULT.WORD, carry & 0x1);\n }\n return dst;\n};\n\n/**\n * helpSHRDd(dst, src, count)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @param {number} count\n * @return {number}\n */\nX86.helpSHRDd = function(dst, src, count)\n{\n if (count) {\n var carry = dst >>> (count - 1);\n dst = (carry >>> 1) | (src << (32 - count));\n this.setLogicResult(dst, X86.RESULT.DWORD, carry & 0x1);\n }\n return dst;\n};\n\n/**\n * helpSRC1()\n *\n * @this {CPUX86}\n * @return {number}\n */\nX86.helpSRC1 = function()\n{\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 2 : this.cycleCounts.nOpCyclesShift1M);\n return 1;\n};\n\n/**\n * helpSRCCL()\n *\n * @this {CPUX86}\n * @return {number}\n */\nX86.helpSRCCL = function()\n{\n var count = this.regECX & 0xff;\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesShiftCR : this.cycleCounts.nOpCyclesShiftCM) + (count << this.cycleCounts.nOpCyclesShiftCS);\n return count;\n};\n\n/**\n * helpSRCByte()\n *\n * @this {CPUX86}\n * @return {number}\n */\nX86.helpSRCByte = function()\n{\n var count = this.getIPByte();\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesShiftCR : this.cycleCounts.nOpCyclesShiftCM) + (count << this.cycleCounts.nOpCyclesShiftCS);\n return count;\n};\n\n/**\n * helpSRCNone()\n *\n * @this {CPUX86}\n * @return {number|null}\n */\nX86.helpSRCNone = function()\n{\n return null;\n};\n\n/**\n * helpSRCxx()\n *\n * This is used by opPOPmw(), because the actual pop must occur BEFORE the effective address (EA)\n * calculation. So opPOPmw() does the pop, saves the popped value in regXX, and this passes src function\n * to the EA worker.\n *\n * @this {CPUX86}\n * @return {number} regXX\n */\nX86.helpSRCxx = function()\n{\n return this.regXX;\n};\n\n/**\n * helpCALLF(off, sel)\n *\n * For protected-mode, this function must attempt to load the new code segment first, because if the new segment\n * requires a change in privilege level, the return address must be pushed on the NEW stack, not the current stack.\n *\n * Also, we rely on a new function, pushData(), instead of pushWord(), to accommodate the outgoing segment size,\n * which may differ from the incoming segment. For example, when a 32-bit code segment performs a 16:32 call to a\n * 16-bit code segment, we must push 32-bit segment and offset values.\n *\n * TODO: Since setCSIP() already informs the segCS load() function when it's making a call, the load() function\n * could automatically push the old CS and IP values *before* segCS is updated -- which would be a better time to do\n * those pushes AND eliminate the need for pushData(). Unfortunately, load() is also used by loadIDT(), and loadIDT()\n * has different requirements (eg, pushing flags first), so it's not a trivial change.\n *\n * @this {CPUX86}\n * @param {number} off\n * @param {number} sel\n */\nX86.helpCALLF = function(off, sel)\n{\n /*\n * Since we always push the return address AFTER calling setCSIP(), and since either push could trigger\n * a fault (eg, segment fault, page fault, etc), we must not only snapshot regSS and regLSP, but also regCS,\n * so that helpFault() can always make CALLF restartable.\n */\n this.opCS = this.getCS();\n this.opSS = this.getSS();\n this.opLSP = this.regLSP;\n var oldIP = this.getIP();\n var oldSize = (I386? this.sizeData : 2);\n if (this.setCSIP(off, sel, true) != null) {\n /*\n * When the OPERAND size is 32 bits, the 80386 will decrement the stack pointer by 4, write the selector\n * into the 2 lower bytes, and leave the 2 upper bytes untouched; at least, that's the case for all other\n * segment register writes, so we assume this case is no different. Hence, the hard-coded size of 2.\n */\n this.pushData(this.opCS, oldSize, 2);\n this.pushData(oldIP, oldSize, oldSize);\n }\n this.opLSP = X86.ADDR_INVALID;\n this.opCS = this.opSS = -1;\n};\n\n/**\n * helpINT(nIDT, nError, nCycles)\n *\n * NOTE: We no longer use setCSIP(), because it always loads the new CS using segCS.load(), which only knows\n * how to load GDT and LDT descriptors, whereas interrupts must use setCS.loadIDT(), which deals exclusively\n * with IDT descriptors.\n *\n * @this {CPUX86}\n * @param {number} nIDT\n * @param {number|null} [nError]\n * @param {number} [nCycles] (in addition to the default of nOpCyclesInt)\n */\nX86.helpINT = function(nIDT, nError, nCycles)\n{\n /*\n * TODO: We assess the cycle cost up front, because otherwise, if loadIDT() fails, no cost may be assessed.\n */\n this.nStepCycles -= this.cycleCounts.nOpCyclesInt + (nCycles || 0);\n var oldPS = this.getPS();\n var oldCS = this.getCS();\n var oldIP = this.getIP();\n var addr = this.segCS.loadIDT(nIDT);\n if (addr !== X86.ADDR_INVALID) {\n /*\n * TODO: Determine if we should use pushData() instead of pushWord() for oldCS and nError, to deal with\n * the same 32-bit 80386 compatibility issue that helpCALLF(), opPUSHCS(), et al must deal with; namely, that\n * 32-bit segment register writes (and, reportedly, 32-bit error codes) don't modify the upper 16 bits.\n *\n * Also, note that helpCALLF() is using the OPERAND size in effect *before* CS is loaded, whereas here we're\n * using the OPERAND size in effect *after* CS is loaded. Is that correct? And does an explicit OPERAND\n * size override on an \"INT\" instruction have any effect on that behavior? Is that even allowed?\n */\n this.pushWord(oldPS);\n this.pushWord(oldCS);\n this.pushWord(oldIP);\n if (nError != null) this.pushWord(nError);\n this.nFault = -1;\n this.setLIP(addr);\n }\n};\n\n/**\n * helpIRET()\n *\n * @this {CPUX86}\n */\nX86.helpIRET = function()\n{\n this.opSS = this.getSS();\n this.opLSP = this.regLSP;\n\n this.nStepCycles -= this.cycleCounts.nOpCyclesIRet;\n\n if ((this.regCR0 & X86.CR0.MSW.PE) && (this.regPS & X86.PS.NT)) {\n var addrNew = this.segTSS.base;\n /*\n * Fortunately, X86.TSS286.PREV_TSS and X86.TSS386.PREV_TSS refer to the same TSS offset.\n * TODO: Update switchTS() to assess a cycle cost; currently, all we assess is what's shown above.\n */\n var sel = this.getShort(addrNew + X86.TSS286.PREV_TSS);\n this.segCS.switchTSS(sel, false);\n }\n else {\n var cpl = this.nCPL;\n var newIP = this.popWord();\n var newCS = this.popWord();\n var newPS = this.popWord();\n\n if (I386) {\n if (this.regPS & X86.PS.VM) {\n /*\n * On the 80386, in V86-mode, RF is the only defined EFLAGS bit above bit 15 that may be changed by IRETD.\n * This is less restrictive than POPFD, which cannot change ANY bits above bit 15; see opPOPF() for details.\n */\n newPS = (newPS & (0xffff | X86.PS.RF)) | (this.regPS & ~(0xffff | X86.PS.RF));\n }\n else {\n if (newPS & X86.PS.VM) {\n /*\n * As noted in loadDesc8(), where the V86-mode frame we're about to pop was originally pushed,\n * these frames ALWAYS contain 32-bit values, so make sure that sizeData reflects that.\n */\n\n /*\n * We have to assume that a full V86-mode interrupt frame was on the protected-mode stack; namely:\n *\n * low: EIP\n * CS (padded to 32 bits)\n * EFLAGS\n * ESP\n * SS (padded to 32 bits)\n * ES (padded to 32 bits)\n * DS (padded to 32 bits)\n * FS (padded to 32 bits)\n * high: GS (padded to 32 bits)\n *\n * We've already popped EIP, CS, and EFLAGS into newIP, newCS and newPS, respectively, so we must now\n * pop the rest, while we're still in protected-mode, before the switch to V86-mode alters the current\n * operand size (among other things).\n */\n var newSP = this.popWord();\n var newSS = this.popWord();\n var newES = this.popWord();\n var newDS = this.popWord();\n var newFS = this.popWord();\n var newGS = this.popWord();\n this.setProtMode(true, true); // flip the switch to V86-mode now\n this.setSS(newSS);\n this.setSP(newSP);\n this.setES(newES);\n this.setDS(newDS);\n this.setFS(newFS);\n this.setGS(newGS);\n }\n }\n }\n\n if (this.setCSIP(newIP, newCS, false) != null) {\n this.setPS(newPS, cpl);\n if (this.cIntReturn) this.checkIntReturn(this.regLIP);\n }\n }\n\n this.opLSP = X86.ADDR_INVALID;\n this.opSS = -1;\n};\n\n/**\n * helpRETF(n)\n *\n * For protected-mode, this function must pop any arguments off the current stack AND whatever stack\n * we may have switched to; setCSIP() returns true if a stack switch occurred, false if not, and null\n * if an error occurred.\n *\n * @this {CPUX86}\n * @param {number} n\n */\nX86.helpRETF = function(n)\n{\n this.opSS = this.getSS();\n this.opLSP = this.regLSP;\n\n var newIP = this.popWord();\n var newCS = this.popWord();\n\n if (n) this.setSP(this.getSP() + n); // TODO: optimize\n\n if (this.setCSIP(newIP, newCS, false)) { // returns true if a stack switch occurred\n /*\n * Fool me once, shame on... whatever. If setCSIP() indicates a stack switch occurred,\n * make sure we're in protected mode, because automatic stack switches can't occur in real mode.\n */\n\n\n if (n) this.setSP(this.getSP() + n); // TODO: optimize\n\n /*\n * As per Intel documentation: \"If any of [the DS or ES] registers refer to segments whose DPL is\n * less than the new CPL (excluding conforming code segments), the segment register is loaded with\n * the null selector.\"\n *\n * TODO: I'm not clear on whether a conforming code segment must also be marked readable, so I'm playing\n * it safe and using CODE_CONFORMING instead of CODE_CONFORMING_READABLE. Also, for the record, I've not\n * seen this situation occur yet (eg, in OS/2 1.0).\n */\n X86.zeroSeg.call(this, this.segDS);\n X86.zeroSeg.call(this, this.segES);\n if (I386 && this.model >= X86.MODEL_80386) {\n X86.zeroSeg.call(this, this.segFS);\n X86.zeroSeg.call(this, this.segGS);\n }\n }\n if (n == 2 && this.cIntReturn) this.checkIntReturn(this.regLIP);\n\n this.opLSP = X86.ADDR_INVALID;\n this.opSS = -1;\n};\n\n/**\n * helpDIVOverflow()\n *\n * @this {CPUX86}\n */\nX86.helpDIVOverflow = function()\n{\n /*\n * Divide error exceptions are traps on the 8086 and faults on later processors. I question the value of that\n * change, because it implies that someone might actually want to restart a failing divide. The only reasonable\n * explanation I can see for the change is to enable the exception handler to accurately record the address of\n * the failing divide, which seems like a very minor benefit. It doesn't change the fact that, on any processor,\n * the exception handler's only reasonable recourse is to unwind execution to a safe point (or terminate the app).\n *\n * TODO: Determine the proper cycle cost.\n */\n if (this.model == X86.MODEL_8086) {\n X86.helpTrap.call(this, X86.EXCEPTION.DE_EXC, 2);\n } else {\n X86.helpFault.call(this, X86.EXCEPTION.DE_EXC, null, 2);\n }\n};\n\n/**\n * helpInterrupt(nIDT, nCycles)\n *\n * Helper to dispatch external interrupts. nCycles defaults to 11 for the 8086/8088\n * if no alternate value is specified.\n *\n * @this {CPUX86}\n * @param {number} nIDT\n * @param {number} [nCycles] (number of cycles in addition to the default of nOpCyclesInt)\n */\nX86.helpInterrupt = function(nIDT, nCycles)\n{\n this.nFault = nIDT;\n if (nCycles === undefined) nCycles = 11;\n X86.helpINT.call(this, nIDT, null, nCycles);\n};\n\n/**\n * helpTrap(nIDT, nCycles)\n *\n * Helper to dispatch traps (ie, exceptions that occur AFTER the instruction, with NO error code)\n *\n * @this {CPUX86}\n * @param {number} nIDT\n * @param {number} [nCycles] (number of cycles in addition to the default of nOpCyclesInt)\n */\nX86.helpTrap = function(nIDT, nCycles)\n{\n this.nFault = -1;\n X86.helpINT.call(this, nIDT, null, nCycles);\n};\n\n/**\n * helpFault(nFault, nError, nCycles, fHalt)\n *\n * Helper to dispatch faults (ie, exceptions that occur DURING an instruction and MAY generate an error code)\n *\n * @this {CPUX86}\n * @param {number} nFault\n * @param {number|null} [nError] (if omitted, no error code will be pushed)\n * @param {number} [nCycles] cycle count to pass through to helpINT(), if any\n * @param {boolean} [fHalt] (true to halt the CPU, false to not, undefined if \"it depends\")\n */\nX86.helpFault = function(nFault, nError, nCycles, fHalt)\n{\n var fDispatch = false;\n\n if (!this.flags.complete) {\n /*\n * Prior to each new burst of instructions, stepCPU() sets fComplete to true, and the only (normal) way\n * for fComplete to become false is through stopCPU(), which isn't ordinarily called, except by the Debugger.\n */\n this.setLIP(this.opLIP);\n }\n else if (this.model >= X86.MODEL_80186) {\n\n fDispatch = true;\n\n if (this.nFault < 0) {\n /*\n * Single-fault (error code is passed through, and the responsible instruction is restartable.\n *\n * TODO: The following opCS/opLIP/opSS/opLSP checks are primarily required for 80386-based machines\n * with paging enabled, because page faults introduce a new set of complex faults that our current\n * segment load \"probes\" are insufficient to catch. So as a stop-gap measure, we rely on these four\n * \"snapshot\" registers to resolve the general instruction restartability problem (for now).\n *\n * If you want to closely examine the underlying causes of these more complex faults, set breakpoints\n * where indicated below, and examine the stack trace.\n */\n if (this.opCS != -1) {\n if (this.opCS !== this.segCS.sel) {\n /*\n * HACK: We slam the RPL into this.segCS.cpl to ensure that loading the original CS segment doesn't\n * fail. For example, if we faulted in the middle of a ring transition that loaded CS with a higher\n * privilege (lower CPL) code segment, then our attempt here to reload the lower privilege (higher CPL)\n * code segment could be viewed as a privilege violation (which it would be outside this context).\n */\n this.segCS.cpl = this.opCS & 0x3; // set breakpoint here to inspect complex faults\n this.setCS(this.opCS);\n }\n this.opCS = -1;\n }\n if (this.opLIP !== this.regLIP) {\n this.setLIP(this.opLIP); // set breakpoint here to inspect complex faults\n\n }\n if (this.opSS != -1) {\n if (this.opSS !== this.segSS.sel) {\n this.setSS(this.opSS); // set breakpoint here to inspect complex faults\n }\n this.opSS = -1;\n }\n if (this.opLSP !== X86.ADDR_INVALID) {\n if (this.opLSP !== this.regLSP) { // set breakpoint below to inspect complex faults\n this.setSP((this.regESP & ~this.segSS.maskAddr) | (this.opLSP - this.segSS.base));\n\n }\n this.opLSP = X86.ADDR_INVALID;\n }\n }\n else if (this.nFault != X86.EXCEPTION.DF_FAULT) {\n /*\n * Double-fault (error code is always zero, and the responsible instruction is not restartable).\n */\n nError = 0;\n nFault = X86.EXCEPTION.DF_FAULT;\n }\n else {\n /*\n * This is a triple-fault (usually referred to in Intel literature as a \"shutdown\", but it's actually a\n * \"reset\"). There's nothing to \"dispatch\" in this case, but we still want to let helpCheckFault() see\n * the triple-fault. However, regardless what helpCheckFault() returns, we must leave via \"throw -1\",\n * because we need to blow off whatever context triggered the triple-fault; that was less critical when\n * all we dealt with were 80286-based triple-faults (at least the \"normal\" triple-faults that OS/2 would\n * generate), but for any other unexpected triple-faults, \"dispatching\" a throw is critical. \n */\n nError = 0;\n nFault = -1;\n fHalt = false;\n this.resetRegs();\n }\n }\n\n if (X86.helpCheckFault.call(this, nFault, nError, fHalt) || nFault < 0) {\n /*\n * If this is a fault that would normally be dispatched BUT helpCheckFault() wants us to halt,\n * then we throw a bogus fault number (-1), simply to interrupt the current instruction in exactly\n * the same way that a dispatched fault would interrupt it.\n */\n if (fDispatch) throw -1;\n }\n\n if (fDispatch) {\n\n this.nFault = nFault;\n X86.helpINT.call(this, nFault, nError, nCycles);\n\n /*\n * REP'eated instructions that rewind regLIP to opLIP used to screw up this dispatch,\n * so now we slip the new regLIP into opLIP, effectively turning their action into a no-op.\n */\n this.opLIP = this.regLIP;\n\n /*\n * X86.OPFLAG.FAULT flag is used by selected opcodes to provide an early exit, restore register(s),\n * or whatever is needed to help ensure instruction restartability; there is currently no general\n * mechanism for snapping and restoring all registers for any instruction that might fault.\n *\n * X86.EXCEPTION.DB_EXC exceptions set their own special flag, X86.OPFLAG.DBEXC, to prevent redundant\n * DEBUG exceptions, so we don't need to set OPFLAG.FAULT in that case, because a DEBUG exception\n * doesn't actually prevent an instruction from executing (and therefore doesn't need to be restarted).\n */\n if (nFault == X86.EXCEPTION.DB_EXC) {\n this.opFlags |= X86.OPFLAG.DBEXC;\n } else {\n\n this.opFlags |= X86.OPFLAG.FAULT;\n }\n\n /*\n * Since this fault is likely being issued in the context of an instruction that hasn't finished\n * executing, if we don't do anything to interrupt that execution (eg, throw a JavaScript exception),\n * then we would need to shut off all further reads/writes for the current instruction.\n *\n * That's easy for any EA-based memory accesses: simply set both the NOREAD and NOWRITE flags.\n * However, there are also direct, non-EA-based memory accesses to consider. A perfect example is\n * opPUSHA(): if a GP fault occurs on any PUSH other than the last, a subsequent PUSH is likely to\n * cause another fault, which we will misinterpret as a double-fault -- unless the handler for\n * such an opcode checks this.opFlags for X86.OPFLAG.FAULT after each step of the operation.\n *\n * this.opFlags |= (X86.OPFLAG.NOREAD | X86.OPFLAG.NOWRITE);\n *\n * Fortunately, we now throw an exception that terminates the current instruction, so the above hack\n * should no longer be necessary.\n */\n throw nFault;\n }\n};\n\n/**\n * helpPageFault(addr, fPresent, fWrite)\n *\n * Helper to dispatch page faults.\n *\n * @this {CPUX86}\n * @param {number} addr\n * @param {boolean} fPresent\n * @param {boolean} fWrite\n */\nX86.helpPageFault = function(addr, fPresent, fWrite)\n{\n this.regCR2 = addr;\n var nError = 0;\n if (fPresent) nError |= X86.PTE.PRESENT;\n if (fWrite) nError |= X86.PTE.READWRITE;\n if (this.nCPL == 3) nError |= X86.PTE.USER;\n X86.helpFault.call(this, X86.EXCEPTION.PF_FAULT, nError);\n};\n\n/**\n * helpCheckFault(nFault, nError, fHalt)\n *\n * Aside from giving the Debugger an opportunity to report every fault, this also gives us the ability to\n * halt exception processing in tracks: return true to prevent the fault handler from being dispatched.\n *\n * At the moment, the only Debugger control you have over fault interception is setting MESSAGE.FAULT, which\n * will display faults as they occur, and MESSAGE.HALT, which will halt after any Debugger message, including\n * MESSAGE.FAULT. If you want execution to continue after halting, clear MESSAGE.FAULT and/or MESSAGE.HALT,\n * or single-step over the offending instruction, which will allow the fault to be dispatched.\n *\n * @this {CPUX86}\n * @param {number} nFault\n * @param {number|null} [nError] (if omitted, no error code will be reported)\n * @param {boolean} [fHalt] (true to halt the CPU, false to not, undefined if \"it depends\")\n * @return {boolean|undefined} true to block the fault (often desirable when fHalt is true), otherwise dispatch it\n */\nX86.helpCheckFault = function(nFault, nError, fHalt)\n{\n var bitsMessage = Messages.FAULT;\n\n var bOpcode = this.probeAddr(this.regLIP);\n\n /*\n * OS/2 1.0 uses an INT3 (0xCC) opcode in conjunction with an invalid IDT to trigger a triple-fault\n * reset and return to real-mode, and these resets happen quite frequently during boot; for example,\n * OS/2 startup messages are displayed using a series of INT 0x10 BIOS calls for each character, and\n * each series of BIOS calls requires a round-trip mode switch.\n *\n * Since we really only want to halt on \"bad\" faults, not \"good\" (ie, intentional) faults, we take\n * advantage of the fact that all 3 faults comprising the triple-fault point to an INT3 (0xCC) opcode,\n * and so whenever we see that opcode, we ignore the caller's fHalt flag, and suppress FAULT messages\n * unless CPU messages are also enabled.\n *\n * When a triple fault shows up, nFault is -1; it displays as 0xff only because we use toHexByte().\n */\n if (bOpcode == X86.OPCODE.INT3 && !this.addrIDTLimit) {\n fHalt = false;\n }\n\n /*\n * There are a number of V86-mode exceptions we don't need to know about. For starters, Windows 3.00\n * (and other versions of enhanced-mode Windows) use an ARPL to switch out of V86-mode, so we can ignore\n * those UD_FAULTs.\n *\n * Ditto for software interrupts, which will generate a GP_FAULT when the interrupt number (eg, 0x6D)\n * exceeds the protected-mode IDT's limit (eg, a limit of 0x2FF corresponds to a maximum interrupt number\n * of 0x5F). Windows doesn't really care if its IDT is too small, because it has to simulate all software\n * interrupts in V86-mode regardless (they generate a GP_FAULT if IOPL < 3, and even when IOPL == 3, only\n * the protected-mode IDT handler gets to run).\n */\n if (this.regPS & X86.PS.VM) {\n if (nFault == X86.EXCEPTION.UD_FAULT && bOpcode == X86.OPCODE.ARPL ||\n nFault == X86.EXCEPTION.GP_FAULT && bOpcode == X86.OPCODE.INTN) {\n fHalt = false;\n }\n }\n // else if (DEBUG && nFault == X86.EXCEPTION.GP_FAULT && fHalt === undefined) fHalt = true;\n\n /*\n * If fHalt has been explicitly set to false, we also take that as a cue to disable fault messages\n * (which you can override by turning on CPU messages).\n */\n if (fHalt === false) {\n bitsMessage |= Messages.CPU;\n }\n\n /*\n * Similarly, the PC AT ROM BIOS deliberately generates a couple of GP faults as part of the POST\n * (Power-On Self Test); we don't want to ignore those, but we don't want to halt on them either. We\n * detect those faults by virtue of the LIP being in the range 0x0F0000 to 0x0FFFFF.\n *\n * TODO: Be aware that this test can trigger false positives, such as when a V86-mode ARPL is hit; eg:\n *\n * &FD82:22F7 6338 ARPL [BX+SI],DI\n */\n if (this.regLIP >= 0x0F0000 && this.regLIP <= 0x0FFFFF) {\n fHalt = false;\n }\n\n /*\n * However, the foregoing notwithstanding, if MESSAGE.HALT is enabled along with all the other required\n * MESSAGE bits, then we want to halt regardless.\n */\n if (this.messageEnabled(bitsMessage | Messages.HALT)) {\n fHalt = true;\n }\n\n if (this.messageEnabled(bitsMessage) || fHalt) {\n\n var fRunning = this.flags.running;\n var sMessage = \"Fault \" + Str.toHexByte(nFault) + (nError != null? \" (\" + Str.toHexWord(nError) + \")\" : \"\") + \" on opcode \" + Str.toHexByte(bOpcode);\n if (fHalt && fRunning) sMessage += \" (blocked)\";\n\n if (DEBUGGER && this.dbg) {\n this.printMessage(sMessage, fHalt || bitsMessage, true);\n if (fHalt) {\n /*\n * By setting fHalt to fRunning (which is true while running but false while single-stepping),\n * this allows a fault to be dispatched when you single-step over a faulting instruction; you can\n * then continue single-stepping into the fault handler, or start running again.\n *\n * Note that we had to capture fRunning before calling printMessage(), because if MESSAGE.HALT\n * is set, printMessage() will have already halted the CPU.\n */\n fHalt = fRunning;\n this.dbg.stopCPU();\n }\n } else {\n /*\n * If there's no Debugger, then messageEnabled() must have returned false, which means that fHalt must\n * be true. Which means we should shut the machine down.\n */\n\n this.notice(sMessage);\n this.stopCPU();\n }\n }\n return fHalt;\n};\n\n/**\n * zeroSeg(seg)\n *\n * Helper to zero a segment register whenever transitioning to a less privileged (numerically higher) level.\n *\n * @this {CPUX86}\n * @param {SegX86} seg\n */\nX86.zeroSeg = function(seg)\n{\n var acc = seg.acc & X86.DESC.ACC.TYPE.CODE_OR_DATA;\n if (seg.sel & X86.SEL.MASK) {\n if (acc == X86.DESC.ACC.TYPE.CODE_EXECONLY || // non-readable code segment (not allowed)\n acc == X86.DESC.ACC.TYPE.CODE_CONFORMING || // non-readable code segment (not allowed)\n acc < X86.DESC.ACC.TYPE.CODE_CONFORMING && seg.dpl < this.nCPL && seg.dpl < (seg.sel & X86.SEL.RPL)) {\n seg.load(0);\n }\n }\n};\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/x86mods.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * Before 80386 support was added to PCx86, the approach to decoding ModRegRM bytes (which I usually\n * just call ModRM bytes) used one generated function per ModRM value. This was optimal for 16-bit processors,\n * because the functions were small, and it was maximally efficient, turning the entire ModRM decoding operation\n * into one table lookup and function call.\n *\n * However, that approach didn't scale well for 32-bit processors, which had extended ModRM capabilities in both\n * the addressing mode dimension and the operand size dimension. So I've rewritten ModRM decoding as 18 functions.\n * The first 9 are for 16-bit addressing modes, and the second 9 are for 32-bit addressing modes. Within each\n * group of 9, there are 3 for 8-bit operands, 3 for 16-bit operands, and 3 for 32-bit operands. And each group of 3\n * contains functions for register-source, memory-source, and group-source.\n *\n * Each of the 18 functions must do additional work to examine the ModRM bits, which makes decoding slightly slower,\n * but it's not really noticeable, and the speed difference didn't justify the additional generated code. So one much\n * smaller file (x86mods.js) replaces a host of older files (x86modb.js, x86modw.js, x86modb16.js, x86modw16.js,\n * x86modb32.js, x86modw32.js, and x86modsib.js).\n *\n * You can dig up the older files from the repository if you're curious, or you can run /modules/pcx86/bin/x86gen.js to\n * get a sense of what they contained (x86gen.js created most of the code, but it still had to be massaged afterward).\n */\n\n/**\n * modRegByte16(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modRegByte16 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n src = this.getEAByteData(this.regEBX + this.regESI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x01:\n src = this.getEAByteData(this.regEBX + this.regEDI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x02:\n src = this.getEAByteStack(this.regEBP + this.regESI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x03:\n src = this.getEAByteStack(this.regEBP + this.regEDI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x04:\n src = this.getEAByteData(this.regESI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x05:\n src = this.getEAByteData(this.regEDI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x06:\n src = this.getEAByteData(this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesDisp;\n break;\n case 0x07:\n src = this.getEAByteData(this.regEBX);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x40:\n src = this.getEAByteData(this.regEBX + this.regESI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x41:\n src = this.getEAByteData(this.regEBX + this.regEDI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x42:\n src = this.getEAByteStack(this.regEBP + this.regESI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x43:\n src = this.getEAByteStack(this.regEBP + this.regEDI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x44:\n src = this.getEAByteData(this.regESI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x45:\n src = this.getEAByteData(this.regEDI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x46:\n src = this.getEAByteStack(this.regEBP + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x47:\n src = this.getEAByteData(this.regEBX + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x80:\n src = this.getEAByteData(this.regEBX + this.regESI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x81:\n src = this.getEAByteData(this.regEBX + this.regEDI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x82:\n src = this.getEAByteStack(this.regEBP + this.regESI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x83:\n src = this.getEAByteStack(this.regEBP + this.regEDI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x84:\n src = this.getEAByteData(this.regESI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x85:\n src = this.getEAByteData(this.regEDI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x86:\n src = this.getEAByteStack(this.regEBP + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x87:\n src = this.getEAByteData(this.regEBX + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0xC0:\n src = this.regEAX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiAL;\n break;\n case 0xC1:\n src = this.regECX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiCL;\n break;\n case 0xC2:\n src = this.regEDX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiDL;\n break;\n case 0xC3:\n src = this.regEBX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiBL;\n break;\n case 0xC4:\n src = (this.regEAX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiAH;\n break;\n case 0xC5:\n src = (this.regECX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiCH;\n break;\n case 0xC6:\n src = (this.regEDX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiDH;\n break;\n case 0xC7:\n src = (this.regEBX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiBH;\n break;\n default:\n src = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n dst = this.regEAX & 0xff;\n break;\n case 0x1:\n dst = this.regECX & 0xff;\n break;\n case 0x2:\n dst = this.regEDX & 0xff;\n break;\n case 0x3:\n dst = this.regEBX & 0xff;\n break;\n case 0x4:\n dst = (this.regEAX >> 8) & 0xff;\n break;\n case 0x5:\n dst = (this.regECX >> 8) & 0xff;\n break;\n case 0x6:\n dst = (this.regEDX >> 8) & 0xff;\n break;\n case 0x7:\n dst = (this.regEBX >> 8) & 0xff;\n break;\n default:\n dst = 0;\n break;\n }\n\n var b = fn.call(this, dst, src);\n\n switch(reg) {\n case 0x0:\n this.regEAX = (this.regEAX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiEALo;\n break;\n case 0x1:\n this.regECX = (this.regECX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiCL = this.backTrack.btiEALo;\n break;\n case 0x2:\n this.regEDX = (this.regEDX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiDL = this.backTrack.btiEALo;\n break;\n case 0x3:\n this.regEBX = (this.regEBX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiBL = this.backTrack.btiEALo;\n break;\n case 0x4:\n this.regEAX = (this.regEAX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiAH = this.backTrack.btiEALo;\n break;\n case 0x5:\n this.regECX = (this.regECX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiCH = this.backTrack.btiEALo;\n break;\n case 0x6:\n this.regEDX = (this.regEDX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiDH = this.backTrack.btiEALo;\n break;\n case 0x7:\n this.regEBX = (this.regEBX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiBH = this.backTrack.btiEALo;\n break;\n }\n};\n\n/**\n * modMemByte16(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modMemByte16 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEAByteData(this.regEBX + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEAByteData(this.regEBX + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEAByteStack(this.regEBP + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEAByteStack(this.regEBP + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEAByteData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEAByteData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEAByteData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEAByteData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEAByteData(this.regEBX + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEAByteData(this.regEBX + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEAByteStack(this.regEBP + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEAByteStack(this.regEBP + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEAByteData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEAByteData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEAByteStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEAByteData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEAByteData(this.regEBX + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEAByteData(this.regEBX + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEAByteStack(this.regEBP + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEAByteStack(this.regEBP + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEAByteData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEAByteData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEAByteStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEAByteData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX & 0xff;\n break;\n case 0xC1:\n dst = this.regECX & 0xff;\n break;\n case 0xC2:\n dst = this.regEDX & 0xff;\n break;\n case 0xC3:\n dst = this.regEBX & 0xff;\n break;\n case 0xC4:\n dst = (this.regEAX >> 8) & 0xff;\n break;\n case 0xC5:\n dst = (this.regECX >> 8) & 0xff;\n break;\n case 0xC6:\n dst = (this.regEDX >> 8) & 0xff;\n break;\n case 0xC7:\n dst = (this.regEBX >> 8) & 0xff;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n src = this.regEAX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiAL;\n break;\n case 0x1:\n src = this.regECX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiCL;\n break;\n case 0x2:\n src = this.regEDX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiDL;\n break;\n case 0x3:\n src = this.regEBX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiBL;\n break;\n case 0x4:\n src = (this.regEAX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiAH;\n break;\n case 0x5:\n src = (this.regECX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiCH;\n break;\n case 0x6:\n src = (this.regEDX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiDH;\n break;\n case 0x7:\n src = (this.regEBX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiBH;\n break;\n default:\n src = 0;\n break;\n }\n\n var b = fn.call(this, dst, src);\n\n switch(bModRM) {\n case 0x00:\n case 0x03:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x01:\n case 0x02:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x04:\n case 0x05:\n case 0x07:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x06:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesDisp;\n break;\n case 0x40:\n case 0x43:\n case 0x80:\n case 0x83:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x41:\n case 0x42:\n case 0x81:\n case 0x82:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x44:\n case 0x45:\n case 0x46:\n case 0x47:\n case 0x84:\n case 0x85:\n case 0x86:\n case 0x87:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0xC0:\n this.regEAX = (this.regEAX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiEALo;\n break;\n case 0xC1:\n this.regECX = (this.regECX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiCL = this.backTrack.btiEALo;\n break;\n case 0xC2:\n this.regEDX = (this.regEDX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiDL = this.backTrack.btiEALo;\n break;\n case 0xC3:\n this.regEBX = (this.regEBX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiBL = this.backTrack.btiEALo;\n break;\n case 0xC4:\n this.regEAX = (this.regEAX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiAH = this.backTrack.btiEALo;\n break;\n case 0xC5:\n this.regECX = (this.regECX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiCH = this.backTrack.btiEALo;\n break;\n case 0xC6:\n this.regEDX = (this.regEDX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiDH = this.backTrack.btiEALo;\n break;\n case 0xC7:\n this.regEBX = (this.regEBX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiBH = this.backTrack.btiEALo;\n break;\n default:\n\n break;\n }\n};\n\n/**\n * modGrpByte16(afnGrp, fnSrc)\n *\n * @this {CPUX86}\n * @param {Array.<function(number,number)>} afnGrp\n * @param {function()} fnSrc\n */\nX86.modGrpByte16 = function(afnGrp, fnSrc) {\n var dst;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEAByteData(this.regEBX + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEAByteData(this.regEBX + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEAByteStack(this.regEBP + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEAByteStack(this.regEBP + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEAByteData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEAByteData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEAByteData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEAByteData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEAByteData(this.regEBX + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEAByteData(this.regEBX + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEAByteStack(this.regEBP + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEAByteStack(this.regEBP + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEAByteData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEAByteData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEAByteStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEAByteData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEAByteData(this.regEBX + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEAByteData(this.regEBX + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEAByteStack(this.regEBP + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEAByteStack(this.regEBP + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEAByteData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEAByteData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEAByteStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEAByteData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX & 0xff;\n break;\n case 0xC1:\n dst = this.regECX & 0xff;\n break;\n case 0xC2:\n dst = this.regEDX & 0xff;\n break;\n case 0xC3:\n dst = this.regEBX & 0xff;\n break;\n case 0xC4:\n dst = (this.regEAX >> 8) & 0xff;\n break;\n case 0xC5:\n dst = (this.regECX >> 8) & 0xff;\n break;\n case 0xC6:\n dst = (this.regEDX >> 8) & 0xff;\n break;\n case 0xC7:\n dst = (this.regEBX >> 8) & 0xff;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n var b = afnGrp[reg].call(this, dst, fnSrc.call(this));\n\n switch(bModRM) {\n case 0x00:\n case 0x03:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x01:\n case 0x02:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x04:\n case 0x05:\n case 0x07:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x06:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesDisp;\n break;\n case 0x40:\n case 0x43:\n case 0x80:\n case 0x83:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x41:\n case 0x42:\n case 0x81:\n case 0x82:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x44:\n case 0x45:\n case 0x46:\n case 0x47:\n case 0x84:\n case 0x85:\n case 0x86:\n case 0x87:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0xC0:\n this.regEAX = (this.regEAX & ~0xff) | b;\n break;\n case 0xC1:\n this.regECX = (this.regECX & ~0xff) | b;\n break;\n case 0xC2:\n this.regEDX = (this.regEDX & ~0xff) | b;\n break;\n case 0xC3:\n this.regEBX = (this.regEBX & ~0xff) | b;\n break;\n case 0xC4:\n this.regEAX = (this.regEAX & ~0xff00) | (b << 8);\n break;\n case 0xC5:\n this.regECX = (this.regECX & ~0xff00) | (b << 8);\n break;\n case 0xC6:\n this.regEDX = (this.regEDX & ~0xff00) | (b << 8);\n break;\n case 0xC7:\n this.regEBX = (this.regEBX & ~0xff00) | (b << 8);\n break;\n }\n};\n\n/**\n * modRegShort16(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modRegShort16 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n src = this.getEAShortData(this.regEBX + this.regESI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x01:\n src = this.getEAShortData(this.regEBX + this.regEDI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x02:\n src = this.getEAShortStack(this.regEBP + this.regESI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x03:\n src = this.getEAShortStack(this.regEBP + this.regEDI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x04:\n src = this.getEAShortData(this.regESI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x05:\n src = this.getEAShortData(this.regEDI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x06:\n src = this.getEAShortData(this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesDisp;\n break;\n case 0x07:\n src = this.getEAShortData(this.regEBX);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x40:\n src = this.getEAShortData(this.regEBX + this.regESI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x41:\n src = this.getEAShortData(this.regEBX + this.regEDI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x42:\n src = this.getEAShortStack(this.regEBP + this.regESI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x43:\n src = this.getEAShortStack(this.regEBP + this.regEDI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x44:\n src = this.getEAShortData(this.regESI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x45:\n src = this.getEAShortData(this.regEDI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x46:\n src = this.getEAShortStack(this.regEBP + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x47:\n src = this.getEAShortData(this.regEBX + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x80:\n src = this.getEAShortData(this.regEBX + this.regESI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x81:\n src = this.getEAShortData(this.regEBX + this.regEDI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x82:\n src = this.getEAShortStack(this.regEBP + this.regESI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x83:\n src = this.getEAShortStack(this.regEBP + this.regEDI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x84:\n src = this.getEAShortData(this.regESI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x85:\n src = this.getEAShortData(this.regEDI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x86:\n src = this.getEAShortStack(this.regEBP + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x87:\n src = this.getEAShortData(this.regEBX + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0xC0:\n src = this.regEAX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiAL; this.backTrack.btiEAHi = this.backTrack.btiAH;\n }\n break;\n case 0xC1:\n src = this.regECX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiCL; this.backTrack.btiEAHi = this.backTrack.btiCH;\n }\n break;\n case 0xC2:\n src = this.regEDX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDL; this.backTrack.btiEAHi = this.backTrack.btiDH;\n }\n break;\n case 0xC3:\n src = this.regEBX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBL; this.backTrack.btiEAHi = this.backTrack.btiBH;\n }\n break;\n case 0xC4:\n src = this.getSP() & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = X86.BTINFO.SP_LO; this.backTrack.btiEAHi = X86.BTINFO.SP_HI;\n }\n break;\n case 0xC5:\n src = this.regEBP & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBPLo; this.backTrack.btiEAHi = this.backTrack.btiBPHi;\n }\n break;\n case 0xC6:\n src = this.regESI & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiSILo; this.backTrack.btiEAHi = this.backTrack.btiSIHi;\n }\n break;\n case 0xC7:\n src = this.regEDI & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDILo; this.backTrack.btiEAHi = this.backTrack.btiDIHi;\n }\n break;\n default:\n src = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n dst = this.regEAX & 0xffff;\n break;\n case 0x1:\n dst = this.regECX & 0xffff;\n break;\n case 0x2:\n dst = this.regEDX & 0xffff;\n break;\n case 0x3:\n dst = this.regEBX & 0xffff;\n break;\n case 0x4:\n dst = this.getSP() & 0xffff;\n break;\n case 0x5:\n dst = this.regEBP & 0xffff;\n break;\n case 0x6:\n dst = this.regESI & 0xffff;\n break;\n case 0x7:\n dst = this.regEDI & 0xffff;\n break;\n default:\n dst = 0;\n break;\n }\n\n var w = fn.call(this, dst, src);\n\n switch(reg) {\n case 0x0:\n this.regEAX = (this.regEAX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiEALo; this.backTrack.btiAH = this.backTrack.btiEAHi;\n }\n break;\n case 0x1:\n this.regECX = (this.regECX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiEALo; this.backTrack.btiCH = this.backTrack.btiEAHi;\n }\n break;\n case 0x2:\n this.regEDX = (this.regEDX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiEALo; this.backTrack.btiDH = this.backTrack.btiEAHi;\n }\n break;\n case 0x3:\n this.regEBX = (this.regEBX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiEALo; this.backTrack.btiBH = this.backTrack.btiEAHi;\n }\n break;\n case 0x4:\n this.setSP((this.getSP() & ~0xffff) | w);\n break;\n case 0x5:\n this.regEBP = (this.regEBP & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiEALo; this.backTrack.btiBPHi = this.backTrack.btiEAHi;\n }\n break;\n case 0x6:\n this.regESI = (this.regESI & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiEALo; this.backTrack.btiSIHi = this.backTrack.btiEAHi;\n }\n break;\n case 0x7:\n this.regEDI = (this.regEDI & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiEALo; this.backTrack.btiDIHi = this.backTrack.btiEAHi;\n }\n break;\n }\n};\n\n/**\n * modMemShort16(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modMemShort16 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEAShortData(this.regEBX + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEAShortData(this.regEBX + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEAShortStack(this.regEBP + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEAShortStack(this.regEBP + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEAShortData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEAShortData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEAShortData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEAShortData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEAShortData(this.regEBX + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEAShortData(this.regEBX + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEAShortStack(this.regEBP + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEAShortStack(this.regEBP + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEAShortData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEAShortData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEAShortStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEAShortData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEAShortData(this.regEBX + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEAShortData(this.regEBX + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEAShortStack(this.regEBP + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEAShortStack(this.regEBP + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEAShortData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEAShortData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEAShortStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEAShortData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX & 0xffff;\n break;\n case 0xC1:\n dst = this.regECX & 0xffff;\n break;\n case 0xC2:\n dst = this.regEDX & 0xffff;\n break;\n case 0xC3:\n dst = this.regEBX & 0xffff;\n break;\n case 0xC4:\n dst = this.getSP() & 0xffff;\n break;\n case 0xC5:\n dst = this.regEBP & 0xffff;\n break;\n case 0xC6:\n dst = this.regESI & 0xffff;\n break;\n case 0xC7:\n dst = this.regEDI & 0xffff;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n src = this.regEAX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiAL; this.backTrack.btiEAHi = this.backTrack.btiAH;\n }\n break;\n case 0x1:\n src = this.regECX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiCL; this.backTrack.btiEAHi = this.backTrack.btiCH;\n }\n break;\n case 0x2:\n src = this.regEDX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDL; this.backTrack.btiEAHi = this.backTrack.btiDH;\n }\n break;\n case 0x3:\n src = this.regEBX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBL; this.backTrack.btiEAHi = this.backTrack.btiBH;\n }\n break;\n case 0x4:\n src = this.getSP() & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = X86.BTINFO.SP_LO; this.backTrack.btiEAHi = X86.BTINFO.SP_HI;\n }\n break;\n case 0x5:\n src = this.regEBP & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBPLo; this.backTrack.btiEAHi = this.backTrack.btiBPHi;\n }\n break;\n case 0x6:\n src = this.regESI & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiSILo; this.backTrack.btiEAHi = this.backTrack.btiSIHi;\n }\n break;\n case 0x7:\n src = this.regEDI & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDILo; this.backTrack.btiEAHi = this.backTrack.btiDIHi;\n }\n break;\n default:\n src = 0;\n break;\n }\n\n var w = fn.call(this, dst, src);\n\n switch(bModRM) {\n case 0x00:\n case 0x03:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x01:\n case 0x02:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x04:\n case 0x05:\n case 0x07:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x06:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesDisp;\n break;\n case 0x40:\n case 0x43:\n case 0x80:\n case 0x83:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x41:\n case 0x42:\n case 0x81:\n case 0x82:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x44:\n case 0x45:\n case 0x46:\n case 0x47:\n case 0x84:\n case 0x85:\n case 0x86:\n case 0x87:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0xC0:\n this.regEAX = (this.regEAX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiEALo; this.backTrack.btiAH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC1:\n this.regECX = (this.regECX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiEALo; this.backTrack.btiCH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC2:\n this.regEDX = (this.regEDX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiEALo; this.backTrack.btiDH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC3:\n this.regEBX = (this.regEBX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiEALo; this.backTrack.btiBH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC4:\n this.setSP((this.getSP() & ~0xffff) | w);\n break;\n case 0xC5:\n this.regEBP = (this.regEBP & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiEALo; this.backTrack.btiBPHi = this.backTrack.btiEAHi;\n }\n break;\n case 0xC6:\n this.regESI = (this.regESI & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiEALo; this.backTrack.btiSIHi = this.backTrack.btiEAHi;\n }\n break;\n case 0xC7:\n this.regEDI = (this.regEDI & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiEALo; this.backTrack.btiDIHi = this.backTrack.btiEAHi;\n }\n break;\n default:\n\n break;\n }\n};\n\n/**\n * modGrpShort16(afnGrp, fnSrc)\n *\n * @this {CPUX86}\n * @param {Array.<function(number,number)>} afnGrp\n * @param {function()} fnSrc\n */\nX86.modGrpShort16 = function(afnGrp, fnSrc) {\n var dst;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEAShortData(this.regEBX + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEAShortData(this.regEBX + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEAShortStack(this.regEBP + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEAShortStack(this.regEBP + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEAShortData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEAShortData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEAShortData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEAShortData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEAShortData(this.regEBX + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEAShortData(this.regEBX + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEAShortStack(this.regEBP + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEAShortStack(this.regEBP + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEAShortData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEAShortData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEAShortStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEAShortData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEAShortData(this.regEBX + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEAShortData(this.regEBX + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEAShortStack(this.regEBP + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEAShortStack(this.regEBP + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEAShortData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEAShortData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEAShortStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEAShortData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX & 0xffff;\n break;\n case 0xC1:\n dst = this.regECX & 0xffff;\n break;\n case 0xC2:\n dst = this.regEDX & 0xffff;\n break;\n case 0xC3:\n dst = this.regEBX & 0xffff;\n break;\n case 0xC4:\n dst = this.getSP() & 0xffff;\n break;\n case 0xC5:\n dst = this.regEBP & 0xffff;\n break;\n case 0xC6:\n dst = this.regESI & 0xffff;\n break;\n case 0xC7:\n dst = this.regEDI & 0xffff;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n var w = afnGrp[reg].call(this, dst, fnSrc.call(this));\n\n switch(bModRM) {\n case 0x00:\n case 0x03:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x01:\n case 0x02:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x04:\n case 0x05:\n case 0x07:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x06:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesDisp;\n break;\n case 0x40:\n case 0x43:\n case 0x80:\n case 0x83:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x41:\n case 0x42:\n case 0x81:\n case 0x82:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x44:\n case 0x45:\n case 0x46:\n case 0x47:\n case 0x84:\n case 0x85:\n case 0x86:\n case 0x87:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0xC0:\n this.regEAX = (this.regEAX & ~0xffff) | w;\n break;\n case 0xC1:\n this.regECX = (this.regECX & ~0xffff) | w;\n break;\n case 0xC2:\n this.regEDX = (this.regEDX & ~0xffff) | w;\n break;\n case 0xC3:\n this.regEBX = (this.regEBX & ~0xffff) | w;\n break;\n case 0xC4:\n this.setSP((this.getSP() & ~0xffff) | w);\n break;\n case 0xC5:\n this.regEBP = (this.regEBP & ~0xffff) | w;\n break;\n case 0xC6:\n this.regESI = (this.regESI & ~0xffff) | w;\n break;\n case 0xC7:\n this.regEDI = (this.regEDI & ~0xffff) | w;\n break;\n }\n};\n\n/**\n * modRegLong16(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modRegLong16 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n src = this.getEALongData(this.regEBX + this.regESI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x01:\n src = this.getEALongData(this.regEBX + this.regEDI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x02:\n src = this.getEALongStack(this.regEBP + this.regESI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x03:\n src = this.getEALongStack(this.regEBP + this.regEDI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x04:\n src = this.getEALongData(this.regESI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x05:\n src = this.getEALongData(this.regEDI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x06:\n src = this.getEALongData(this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesDisp;\n break;\n case 0x07:\n src = this.getEALongData(this.regEBX);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x40:\n src = this.getEALongData(this.regEBX + this.regESI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x41:\n src = this.getEALongData(this.regEBX + this.regEDI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x42:\n src = this.getEALongStack(this.regEBP + this.regESI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x43:\n src = this.getEALongStack(this.regEBP + this.regEDI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x44:\n src = this.getEALongData(this.regESI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x45:\n src = this.getEALongData(this.regEDI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x46:\n src = this.getEALongStack(this.regEBP + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x47:\n src = this.getEALongData(this.regEBX + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x80:\n src = this.getEALongData(this.regEBX + this.regESI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x81:\n src = this.getEALongData(this.regEBX + this.regEDI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x82:\n src = this.getEALongStack(this.regEBP + this.regESI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x83:\n src = this.getEALongStack(this.regEBP + this.regEDI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x84:\n src = this.getEALongData(this.regESI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x85:\n src = this.getEALongData(this.regEDI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x86:\n src = this.getEALongStack(this.regEBP + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x87:\n src = this.getEALongData(this.regEBX + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0xC0:\n src = this.regEAX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiAL; this.backTrack.btiEAHi = this.backTrack.btiAH;\n }\n break;\n case 0xC1:\n src = this.regECX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiCL; this.backTrack.btiEAHi = this.backTrack.btiCH;\n }\n break;\n case 0xC2:\n src = this.regEDX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDL; this.backTrack.btiEAHi = this.backTrack.btiDH;\n }\n break;\n case 0xC3:\n src = this.regEBX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBL; this.backTrack.btiEAHi = this.backTrack.btiBH;\n }\n break;\n case 0xC4:\n src = this.getSP();\n if (BACKTRACK) {\n this.backTrack.btiEALo = X86.BTINFO.SP_LO; this.backTrack.btiEAHi = X86.BTINFO.SP_HI;\n }\n break;\n case 0xC5:\n src = this.regEBP;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBPLo; this.backTrack.btiEAHi = this.backTrack.btiBPHi;\n }\n break;\n case 0xC6:\n src = this.regESI;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiSILo; this.backTrack.btiEAHi = this.backTrack.btiSIHi;\n }\n break;\n case 0xC7:\n src = this.regEDI;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDILo; this.backTrack.btiEAHi = this.backTrack.btiDIHi;\n }\n break;\n default:\n src = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n dst = this.regEAX;\n break;\n case 0x1:\n dst = this.regECX;\n break;\n case 0x2:\n dst = this.regEDX;\n break;\n case 0x3:\n dst = this.regEBX;\n break;\n case 0x4:\n dst = this.getSP();\n break;\n case 0x5:\n dst = this.regEBP;\n break;\n case 0x6:\n dst = this.regESI;\n break;\n case 0x7:\n dst = this.regEDI;\n break;\n default:\n dst = 0;\n break;\n }\n\n var l = fn.call(this, dst, src);\n\n switch(reg) {\n case 0x0:\n this.regEAX = l;\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiEALo; this.backTrack.btiAH = this.backTrack.btiEAHi;\n }\n break;\n case 0x1:\n this.regECX = l;\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiEALo; this.backTrack.btiCH = this.backTrack.btiEAHi;\n }\n break;\n case 0x2:\n this.regEDX = l;\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiEALo; this.backTrack.btiDH = this.backTrack.btiEAHi;\n }\n break;\n case 0x3:\n this.regEBX = l;\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiEALo; this.backTrack.btiBH = this.backTrack.btiEAHi;\n }\n break;\n case 0x4:\n this.setSP(l);\n break;\n case 0x5:\n this.regEBP = l;\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiEALo; this.backTrack.btiBPHi = this.backTrack.btiEAHi;\n }\n break;\n case 0x6:\n this.regESI = l;\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiEALo; this.backTrack.btiSIHi = this.backTrack.btiEAHi;\n }\n break;\n case 0x7:\n this.regEDI = l;\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiEALo; this.backTrack.btiDIHi = this.backTrack.btiEAHi;\n }\n break;\n }\n};\n\n/**\n * modMemLong16(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modMemLong16 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEALongData(this.regEBX + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEALongData(this.regEBX + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEALongStack(this.regEBP + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEALongStack(this.regEBP + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEALongData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEALongData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEALongData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEALongData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEALongData(this.regEBX + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEALongData(this.regEBX + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEALongStack(this.regEBP + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEALongStack(this.regEBP + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEALongData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEALongData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEALongStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEALongData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEALongData(this.regEBX + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEALongData(this.regEBX + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEALongStack(this.regEBP + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEALongStack(this.regEBP + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEALongData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEALongData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEALongStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEALongData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX;\n break;\n case 0xC1:\n dst = this.regECX;\n break;\n case 0xC2:\n dst = this.regEDX;\n break;\n case 0xC3:\n dst = this.regEBX;\n break;\n case 0xC4:\n dst = this.getSP();\n break;\n case 0xC5:\n dst = this.regEBP;\n break;\n case 0xC6:\n dst = this.regESI;\n break;\n case 0xC7:\n dst = this.regEDI;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n src = this.regEAX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiAL; this.backTrack.btiEAHi = this.backTrack.btiAH;\n }\n break;\n case 0x1:\n src = this.regECX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiCL; this.backTrack.btiEAHi = this.backTrack.btiCH;\n }\n break;\n case 0x2:\n src = this.regEDX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDL; this.backTrack.btiEAHi = this.backTrack.btiDH;\n }\n break;\n case 0x3:\n src = this.regEBX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBL; this.backTrack.btiEAHi = this.backTrack.btiBH;\n }\n break;\n case 0x4:\n src = this.getSP();\n if (BACKTRACK) {\n this.backTrack.btiEALo = X86.BTINFO.SP_LO; this.backTrack.btiEAHi = X86.BTINFO.SP_HI;\n }\n break;\n case 0x5:\n src = this.regEBP;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBPLo; this.backTrack.btiEAHi = this.backTrack.btiBPHi;\n }\n break;\n case 0x6:\n src = this.regESI;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiSILo; this.backTrack.btiEAHi = this.backTrack.btiSIHi;\n }\n break;\n case 0x7:\n src = this.regEDI;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDILo; this.backTrack.btiEAHi = this.backTrack.btiDIHi;\n }\n break;\n default:\n src = 0;\n break;\n }\n\n var l = fn.call(this, dst, src);\n\n switch(bModRM) {\n case 0x00:\n case 0x03:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x01:\n case 0x02:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x04:\n case 0x05:\n case 0x07:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x06:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesDisp;\n break;\n case 0x40:\n case 0x43:\n case 0x80:\n case 0x83:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x41:\n case 0x42:\n case 0x81:\n case 0x82:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x44:\n case 0x45:\n case 0x46:\n case 0x47:\n case 0x84:\n case 0x85:\n case 0x86:\n case 0x87:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0xC0:\n this.regEAX = l;\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiEALo; this.backTrack.btiAH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC1:\n this.regECX = l;\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiEALo; this.backTrack.btiCH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC2:\n this.regEDX = l;\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiEALo; this.backTrack.btiDH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC3:\n this.regEBX = l;\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiEALo; this.backTrack.btiBH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC4:\n this.setSP(l);\n break;\n case 0xC5:\n this.regEBP = l;\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiEALo; this.backTrack.btiBPHi = this.backTrack.btiEAHi;\n }\n break;\n case 0xC6:\n this.regESI = l;\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiEALo; this.backTrack.btiSIHi = this.backTrack.btiEAHi;\n }\n break;\n case 0xC7:\n this.regEDI = l;\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiEALo; this.backTrack.btiDIHi = this.backTrack.btiEAHi;\n }\n break;\n default:\n\n break;\n }\n};\n\n/**\n * modGrpLong16(afnGrp, fnSrc)\n *\n * @this {CPUX86}\n * @param {Array.<function(number,number)>} afnGrp\n * @param {function()} fnSrc\n */\nX86.modGrpLong16 = function(afnGrp, fnSrc) {\n var dst;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEALongData(this.regEBX + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEALongData(this.regEBX + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEALongStack(this.regEBP + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEALongStack(this.regEBP + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEALongData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEALongData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEALongData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEALongData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEALongData(this.regEBX + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEALongData(this.regEBX + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEALongStack(this.regEBP + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEALongStack(this.regEBP + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEALongData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEALongData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEALongStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEALongData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEALongData(this.regEBX + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEALongData(this.regEBX + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEALongStack(this.regEBP + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEALongStack(this.regEBP + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEALongData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEALongData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEALongStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEALongData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX;\n break;\n case 0xC1:\n dst = this.regECX;\n break;\n case 0xC2:\n dst = this.regEDX;\n break;\n case 0xC3:\n dst = this.regEBX;\n break;\n case 0xC4:\n dst = this.getSP();\n break;\n case 0xC5:\n dst = this.regEBP;\n break;\n case 0xC6:\n dst = this.regESI;\n break;\n case 0xC7:\n dst = this.regEDI;\n break;\n default:\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n var l = afnGrp[reg].call(this, dst, fnSrc.call(this));\n\n switch(bModRM) {\n case 0x00:\n case 0x03:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x01:\n case 0x02:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x04:\n case 0x05:\n case 0x07:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x06:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesDisp;\n break;\n case 0x40:\n case 0x43:\n case 0x80:\n case 0x83:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x41:\n case 0x42:\n case 0x81:\n case 0x82:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x44:\n case 0x45:\n case 0x46:\n case 0x47:\n case 0x84:\n case 0x85:\n case 0x86:\n case 0x87:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0xC0:\n this.regEAX = l;\n break;\n case 0xC1:\n this.regECX = l;\n break;\n case 0xC2:\n this.regEDX = l;\n break;\n case 0xC3:\n this.regEBX = l;\n break;\n case 0xC4:\n this.setSP(l);\n break;\n case 0xC5:\n this.regEBP = l;\n break;\n case 0xC6:\n this.regESI = l;\n break;\n case 0xC7:\n this.regEDI = l;\n break;\n }\n};\n\n/**\n * modRegByte32(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modRegByte32 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n src = this.getEAByteData(this.regEAX);\n break;\n case 0x01:\n src = this.getEAByteData(this.regECX);\n break;\n case 0x02:\n src = this.getEAByteData(this.regEDX);\n break;\n case 0x03:\n src = this.getEAByteData(this.regEBX);\n break;\n case 0x04:\n src = this.getEAByteData(X86.modSIB.call(this, 0));\n break;\n case 0x05:\n src = this.getEAByteData(this.getIPAddr());\n break;\n case 0x06:\n src = this.getEAByteData(this.regESI);\n break;\n case 0x07:\n src = this.getEAByteData(this.regEDI);\n break;\n case 0x40:\n src = this.getEAByteData(this.regEAX + this.getIPDisp());\n break;\n case 0x41:\n src = this.getEAByteData(this.regECX + this.getIPDisp());\n break;\n case 0x42:\n src = this.getEAByteData(this.regEDX + this.getIPDisp());\n break;\n case 0x43:\n src = this.getEAByteData(this.regEBX + this.getIPDisp());\n break;\n case 0x44:\n src = this.getEAByteData(X86.modSIB.call(this, 1) + this.getIPDisp());\n break;\n case 0x45:\n src = this.getEAByteStack(this.regEBP + this.getIPDisp());\n break;\n case 0x46:\n src = this.getEAByteData(this.regESI + this.getIPDisp());\n break;\n case 0x47:\n src = this.getEAByteData(this.regEDI + this.getIPDisp());\n break;\n case 0x80:\n src = this.getEAByteData(this.regEAX + this.getIPAddr());\n break;\n case 0x81:\n src = this.getEAByteData(this.regECX + this.getIPAddr());\n break;\n case 0x82:\n src = this.getEAByteData(this.regEDX + this.getIPAddr());\n break;\n case 0x83:\n src = this.getEAByteData(this.regEBX + this.getIPAddr());\n break;\n case 0x84:\n src = this.getEAByteData(X86.modSIB.call(this, 2) + this.getIPAddr());\n break;\n case 0x85:\n src = this.getEAByteStack(this.regEBP + this.getIPAddr());\n break;\n case 0x86:\n src = this.getEAByteData(this.regESI + this.getIPAddr());\n break;\n case 0x87:\n src = this.getEAByteData(this.regEDI + this.getIPAddr());\n break;\n case 0xC0:\n src = this.regEAX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiAL;\n break;\n case 0xC1:\n src = this.regECX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiCL;\n break;\n case 0xC2:\n src = this.regEDX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiDL;\n break;\n case 0xC3:\n src = this.regEBX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiBL;\n break;\n case 0xC4:\n src = (this.regEAX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiAH;\n break;\n case 0xC5:\n src = (this.regECX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiCH;\n break;\n case 0xC6:\n src = (this.regEDX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiDH;\n break;\n case 0xC7:\n src = (this.regEBX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiBH;\n break;\n default:\n src = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n dst = this.regEAX & 0xff;\n break;\n case 0x1:\n dst = this.regECX & 0xff;\n break;\n case 0x2:\n dst = this.regEDX & 0xff;\n break;\n case 0x3:\n dst = this.regEBX & 0xff;\n break;\n case 0x4:\n dst = (this.regEAX >> 8) & 0xff;\n break;\n case 0x5:\n dst = (this.regECX >> 8) & 0xff;\n break;\n case 0x6:\n dst = (this.regEDX >> 8) & 0xff;\n break;\n case 0x7:\n dst = (this.regEBX >> 8) & 0xff;\n break;\n default:\n dst = 0;\n break;\n }\n\n var b = fn.call(this, dst, src);\n\n switch(reg) {\n case 0x0:\n this.regEAX = (this.regEAX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiEALo;\n break;\n case 0x1:\n this.regECX = (this.regECX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiCL = this.backTrack.btiEALo;\n break;\n case 0x2:\n this.regEDX = (this.regEDX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiDL = this.backTrack.btiEALo;\n break;\n case 0x3:\n this.regEBX = (this.regEBX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiBL = this.backTrack.btiEALo;\n break;\n case 0x4:\n this.regEAX = (this.regEAX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiAH = this.backTrack.btiEALo;\n break;\n case 0x5:\n this.regECX = (this.regECX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiCH = this.backTrack.btiEALo;\n break;\n case 0x6:\n this.regEDX = (this.regEDX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiDH = this.backTrack.btiEALo;\n break;\n case 0x7:\n this.regEBX = (this.regEBX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiBH = this.backTrack.btiEALo;\n break;\n }\n};\n\n/**\n * modMemByte32(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modMemByte32 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEAByteData(this.regEAX);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEAByteData(this.regECX);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEAByteData(this.regEDX);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEAByteData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEAByteData(X86.modSIB.call(this, 0));\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEAByteData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEAByteData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEAByteData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEAByteData(this.regEAX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEAByteData(this.regECX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEAByteData(this.regEDX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEAByteData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEAByteData(X86.modSIB.call(this, 1) + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEAByteStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEAByteData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEAByteData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEAByteData(this.regEAX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEAByteData(this.regECX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEAByteData(this.regEDX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEAByteData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEAByteData(X86.modSIB.call(this, 2) + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEAByteStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEAByteData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEAByteData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX & 0xff;\n break;\n case 0xC1:\n dst = this.regECX & 0xff;\n break;\n case 0xC2:\n dst = this.regEDX & 0xff;\n break;\n case 0xC3:\n dst = this.regEBX & 0xff;\n break;\n case 0xC4:\n dst = (this.regEAX >> 8) & 0xff;\n break;\n case 0xC5:\n dst = (this.regECX >> 8) & 0xff;\n break;\n case 0xC6:\n dst = (this.regEDX >> 8) & 0xff;\n break;\n case 0xC7:\n dst = (this.regEBX >> 8) & 0xff;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n src = this.regEAX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiAL;\n break;\n case 0x1:\n src = this.regECX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiCL;\n break;\n case 0x2:\n src = this.regEDX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiDL;\n break;\n case 0x3:\n src = this.regEBX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiBL;\n break;\n case 0x4:\n src = (this.regEAX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiAH;\n break;\n case 0x5:\n src = (this.regECX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiCH;\n break;\n case 0x6:\n src = (this.regEDX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiDH;\n break;\n case 0x7:\n src = (this.regEBX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiBH;\n break;\n default:\n src = 0;\n break;\n }\n\n var b = fn.call(this, dst, src);\n\n switch(bModRM) {\n case 0xC0:\n this.regEAX = (this.regEAX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiEALo;\n break;\n case 0xC1:\n this.regECX = (this.regECX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiCL = this.backTrack.btiEALo;\n break;\n case 0xC2:\n this.regEDX = (this.regEDX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiDL = this.backTrack.btiEALo;\n break;\n case 0xC3:\n this.regEBX = (this.regEBX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiBL = this.backTrack.btiEALo;\n break;\n case 0xC4:\n this.regEAX = (this.regEAX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiAH = this.backTrack.btiEALo;\n break;\n case 0xC5:\n this.regECX = (this.regECX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiCH = this.backTrack.btiEALo;\n break;\n case 0xC6:\n this.regEDX = (this.regEDX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiDH = this.backTrack.btiEALo;\n break;\n case 0xC7:\n this.regEBX = (this.regEBX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiBH = this.backTrack.btiEALo;\n break;\n default:\n this.setEAByte(b);\n break;\n }\n};\n\n/**\n * modGrpByte32(afnGrp, fnSrc)\n *\n * @this {CPUX86}\n * @param {Array.<function(number,number)>} afnGrp\n * @param {function()} fnSrc\n */\nX86.modGrpByte32 = function(afnGrp, fnSrc) {\n var dst;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEAByteData(this.regEAX);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEAByteData(this.regECX);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEAByteData(this.regEDX);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEAByteData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEAByteData(X86.modSIB.call(this, 0));\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEAByteData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEAByteData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEAByteData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEAByteData(this.regEAX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEAByteData(this.regECX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEAByteData(this.regEDX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEAByteData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEAByteData(X86.modSIB.call(this, 1) + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEAByteStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEAByteData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEAByteData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEAByteData(this.regEAX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEAByteData(this.regECX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEAByteData(this.regEDX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEAByteData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEAByteData(X86.modSIB.call(this, 2) + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEAByteStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEAByteData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEAByteData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX & 0xff;\n break;\n case 0xC1:\n dst = this.regECX & 0xff;\n break;\n case 0xC2:\n dst = this.regEDX & 0xff;\n break;\n case 0xC3:\n dst = this.regEBX & 0xff;\n break;\n case 0xC4:\n dst = (this.regEAX >> 8) & 0xff;\n break;\n case 0xC5:\n dst = (this.regECX >> 8) & 0xff;\n break;\n case 0xC6:\n dst = (this.regEDX >> 8) & 0xff;\n break;\n case 0xC7:\n dst = (this.regEBX >> 8) & 0xff;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n var b = afnGrp[reg].call(this, dst, fnSrc.call(this));\n\n switch(bModRM) {\n case 0xC0:\n this.regEAX = (this.regEAX & ~0xff) | b;\n break;\n case 0xC1:\n this.regECX = (this.regECX & ~0xff) | b;\n break;\n case 0xC2:\n this.regEDX = (this.regEDX & ~0xff) | b;\n break;\n case 0xC3:\n this.regEBX = (this.regEBX & ~0xff) | b;\n break;\n case 0xC4:\n this.regEAX = (this.regEAX & ~0xff00) | (b << 8);\n break;\n case 0xC5:\n this.regECX = (this.regECX & ~0xff00) | (b << 8);\n break;\n case 0xC6:\n this.regEDX = (this.regEDX & ~0xff00) | (b << 8);\n break;\n case 0xC7:\n this.regEBX = (this.regEBX & ~0xff00) | (b << 8);\n break;\n default:\n this.setEAByte(b);\n break;\n }\n};\n\n/**\n * modRegShort32(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modRegShort32 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n src = this.getEAShortData(this.regEAX);\n break;\n case 0x01:\n src = this.getEAShortData(this.regECX);\n break;\n case 0x02:\n src = this.getEAShortData(this.regEDX);\n break;\n case 0x03:\n src = this.getEAShortData(this.regEBX);\n break;\n case 0x04:\n src = this.getEAShortData(X86.modSIB.call(this, 0));\n break;\n case 0x05:\n src = this.getEAShortData(this.getIPAddr());\n break;\n case 0x06:\n src = this.getEAShortData(this.regESI);\n break;\n case 0x07:\n src = this.getEAShortData(this.regEDI);\n break;\n case 0x40:\n src = this.getEAShortData(this.regEAX + this.getIPDisp());\n break;\n case 0x41:\n src = this.getEAShortData(this.regECX + this.getIPDisp());\n break;\n case 0x42:\n src = this.getEAShortData(this.regEDX + this.getIPDisp());\n break;\n case 0x43:\n src = this.getEAShortData(this.regEBX + this.getIPDisp());\n break;\n case 0x44:\n src = this.getEAShortData(X86.modSIB.call(this, 1) + this.getIPDisp());\n break;\n case 0x45:\n src = this.getEAShortStack(this.regEBP + this.getIPDisp());\n break;\n case 0x46:\n src = this.getEAShortData(this.regESI + this.getIPDisp());\n break;\n case 0x47:\n src = this.getEAShortData(this.regEDI + this.getIPDisp());\n break;\n case 0x80:\n src = this.getEAShortData(this.regEAX + this.getIPAddr());\n break;\n case 0x81:\n src = this.getEAShortData(this.regECX + this.getIPAddr());\n break;\n case 0x82:\n src = this.getEAShortData(this.regEDX + this.getIPAddr());\n break;\n case 0x83:\n src = this.getEAShortData(this.regEBX + this.getIPAddr());\n break;\n case 0x84:\n src = this.getEAShortData(X86.modSIB.call(this, 2) + this.getIPAddr());\n break;\n case 0x85:\n src = this.getEAShortStack(this.regEBP + this.getIPAddr());\n break;\n case 0x86:\n src = this.getEAShortData(this.regESI + this.getIPAddr());\n break;\n case 0x87:\n src = this.getEAShortData(this.regEDI + this.getIPAddr());\n break;\n case 0xC0:\n src = this.regEAX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiAL; this.backTrack.btiEAHi = this.backTrack.btiAH;\n }\n break;\n case 0xC1:\n src = this.regECX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiCL; this.backTrack.btiEAHi = this.backTrack.btiCH;\n }\n break;\n case 0xC2:\n src = this.regEDX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDL; this.backTrack.btiEAHi = this.backTrack.btiDH;\n }\n break;\n case 0xC3:\n src = this.regEBX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBL; this.backTrack.btiEAHi = this.backTrack.btiBH;\n }\n break;\n case 0xC4:\n src = this.getSP() & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = X86.BTINFO.SP_LO; this.backTrack.btiEAHi = X86.BTINFO.SP_HI;\n }\n break;\n case 0xC5:\n src = this.regEBP & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBPLo; this.backTrack.btiEAHi = this.backTrack.btiBPHi;\n }\n break;\n case 0xC6:\n src = this.regESI & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiSILo; this.backTrack.btiEAHi = this.backTrack.btiSIHi;\n }\n break;\n case 0xC7:\n src = this.regEDI & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDILo; this.backTrack.btiEAHi = this.backTrack.btiDIHi;\n }\n break;\n default:\n src = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n dst = this.regEAX & 0xffff;\n break;\n case 0x1:\n dst = this.regECX & 0xffff;\n break;\n case 0x2:\n dst = this.regEDX & 0xffff;\n break;\n case 0x3:\n dst = this.regEBX & 0xffff;\n break;\n case 0x4:\n dst = this.getSP() & 0xffff;\n break;\n case 0x5:\n dst = this.regEBP & 0xffff;\n break;\n case 0x6:\n dst = this.regESI & 0xffff;\n break;\n case 0x7:\n dst = this.regEDI & 0xffff;\n break;\n default:\n dst = 0;\n break;\n }\n\n var w = fn.call(this, dst, src);\n\n switch(reg) {\n case 0x0:\n this.regEAX = (this.regEAX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiEALo; this.backTrack.btiAH = this.backTrack.btiEAHi;\n }\n break;\n case 0x1:\n this.regECX = (this.regECX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiEALo; this.backTrack.btiCH = this.backTrack.btiEAHi;\n }\n break;\n case 0x2:\n this.regEDX = (this.regEDX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiEALo; this.backTrack.btiDH = this.backTrack.btiEAHi;\n }\n break;\n case 0x3:\n this.regEBX = (this.regEBX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiEALo; this.backTrack.btiBH = this.backTrack.btiEAHi;\n }\n break;\n case 0x4:\n this.setSP((this.getSP() & ~0xffff) | w);\n break;\n case 0x5:\n this.regEBP = (this.regEBP & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiEALo; this.backTrack.btiBPHi = this.backTrack.btiEAHi;\n }\n break;\n case 0x6:\n this.regESI = (this.regESI & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiEALo; this.backTrack.btiSIHi = this.backTrack.btiEAHi;\n }\n break;\n case 0x7:\n this.regEDI = (this.regEDI & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiEALo; this.backTrack.btiDIHi = this.backTrack.btiEAHi;\n }\n break;\n }\n};\n\n/**\n * modMemShort32(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modMemShort32 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEAShortData(this.regEAX);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEAShortData(this.regECX);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEAShortData(this.regEDX);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEAShortData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEAShortData(X86.modSIB.call(this, 0));\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEAShortData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEAShortData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEAShortData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEAShortData(this.regEAX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEAShortData(this.regECX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEAShortData(this.regEDX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEAShortData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEAShortData(X86.modSIB.call(this, 1) + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEAShortStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEAShortData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEAShortData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEAShortData(this.regEAX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEAShortData(this.regECX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEAShortData(this.regEDX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEAShortData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEAShortData(X86.modSIB.call(this, 2) + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEAShortStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEAShortData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEAShortData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX & 0xffff;\n break;\n case 0xC1:\n dst = this.regECX & 0xffff;\n break;\n case 0xC2:\n dst = this.regEDX & 0xffff;\n break;\n case 0xC3:\n dst = this.regEBX & 0xffff;\n break;\n case 0xC4:\n dst = this.getSP() & 0xffff;\n break;\n case 0xC5:\n dst = this.regEBP & 0xffff;\n break;\n case 0xC6:\n dst = this.regESI & 0xffff;\n break;\n case 0xC7:\n dst = this.regEDI & 0xffff;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n src = this.regEAX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiAL; this.backTrack.btiEAHi = this.backTrack.btiAH;\n }\n break;\n case 0x1:\n src = this.regECX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiCL; this.backTrack.btiEAHi = this.backTrack.btiCH;\n }\n break;\n case 0x2:\n src = this.regEDX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDL; this.backTrack.btiEAHi = this.backTrack.btiDH;\n }\n break;\n case 0x3:\n src = this.regEBX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBL; this.backTrack.btiEAHi = this.backTrack.btiBH;\n }\n break;\n case 0x4:\n src = this.getSP() & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = X86.BTINFO.SP_LO; this.backTrack.btiEAHi = X86.BTINFO.SP_HI;\n }\n break;\n case 0x5:\n src = this.regEBP & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBPLo; this.backTrack.btiEAHi = this.backTrack.btiBPHi;\n }\n break;\n case 0x6:\n src = this.regESI & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiSILo; this.backTrack.btiEAHi = this.backTrack.btiSIHi;\n }\n break;\n case 0x7:\n src = this.regEDI & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDILo; this.backTrack.btiEAHi = this.backTrack.btiDIHi;\n }\n break;\n default:\n src = 0;\n break;\n }\n\n var w = fn.call(this, dst, src);\n\n switch(bModRM) {\n case 0xC0:\n this.regEAX = (this.regEAX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiEALo; this.backTrack.btiAH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC1:\n this.regECX = (this.regECX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiEALo; this.backTrack.btiCH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC2:\n this.regEDX = (this.regEDX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiEALo; this.backTrack.btiDH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC3:\n this.regEBX = (this.regEBX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiEALo; this.backTrack.btiBH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC4:\n this.setSP((this.getSP() & ~0xffff) | w);\n break;\n case 0xC5:\n this.regEBP = (this.regEBP & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiEALo; this.backTrack.btiBPHi = this.backTrack.btiEAHi;\n }\n break;\n case 0xC6:\n this.regESI = (this.regESI & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiEALo; this.backTrack.btiSIHi = this.backTrack.btiEAHi;\n }\n break;\n case 0xC7:\n this.regEDI = (this.regEDI & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiEALo; this.backTrack.btiDIHi = this.backTrack.btiEAHi;\n }\n break;\n default:\n this.setEAShort(w);\n break;\n }\n};\n\n/**\n * modGrpShort32(afnGrp, fnSrc)\n *\n * @this {CPUX86}\n * @param {Array.<function(number,number)>} afnGrp\n * @param {function()} fnSrc\n */\nX86.modGrpShort32 = function(afnGrp, fnSrc) {\n var dst;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEAShortData(this.regEAX);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEAShortData(this.regECX);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEAShortData(this.regEDX);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEAShortData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEAShortData(X86.modSIB.call(this, 0));\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEAShortData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEAShortData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEAShortData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEAShortData(this.regEAX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEAShortData(this.regECX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEAShortData(this.regEDX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEAShortData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEAShortData(X86.modSIB.call(this, 1) + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEAShortStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEAShortData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEAShortData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEAShortData(this.regEAX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEAShortData(this.regECX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEAShortData(this.regEDX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEAShortData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEAShortData(X86.modSIB.call(this, 2) + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEAShortStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEAShortData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEAShortData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX & 0xffff;\n break;\n case 0xC1:\n dst = this.regECX & 0xffff;\n break;\n case 0xC2:\n dst = this.regEDX & 0xffff;\n break;\n case 0xC3:\n dst = this.regEBX & 0xffff;\n break;\n case 0xC4:\n dst = this.getSP() & 0xffff;\n break;\n case 0xC5:\n dst = this.regEBP & 0xffff;\n break;\n case 0xC6:\n dst = this.regESI & 0xffff;\n break;\n case 0xC7:\n dst = this.regEDI & 0xffff;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n var w = afnGrp[reg].call(this, dst, fnSrc.call(this));\n\n switch(bModRM) {\n case 0xC0:\n this.regEAX = (this.regEAX & ~0xffff) | w;\n break;\n case 0xC1:\n this.regECX = (this.regECX & ~0xffff) | w;\n break;\n case 0xC2:\n this.regEDX = (this.regEDX & ~0xffff) | w;\n break;\n case 0xC3:\n this.regEBX = (this.regEBX & ~0xffff) | w;\n break;\n case 0xC4:\n this.setSP((this.getSP() & ~0xffff) | w);\n break;\n case 0xC5:\n this.regEBP = (this.regEBP & ~0xffff) | w;\n break;\n case 0xC6:\n this.regESI = (this.regESI & ~0xffff) | w;\n break;\n case 0xC7:\n this.regEDI = (this.regEDI & ~0xffff) | w;\n break;\n default:\n this.setEAShort(w);\n break;\n }\n};\n\n/**\n * modRegLong32(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modRegLong32 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n src = this.getEALongData(this.regEAX);\n break;\n case 0x01:\n src = this.getEALongData(this.regECX);\n break;\n case 0x02:\n src = this.getEALongData(this.regEDX);\n break;\n case 0x03:\n src = this.getEALongData(this.regEBX);\n break;\n case 0x04:\n src = this.getEALongData(X86.modSIB.call(this, 0));\n break;\n case 0x05:\n src = this.getEALongData(this.getIPAddr());\n break;\n case 0x06:\n src = this.getEALongData(this.regESI);\n break;\n case 0x07:\n src = this.getEALongData(this.regEDI);\n break;\n case 0x40:\n src = this.getEALongData(this.regEAX + this.getIPDisp());\n break;\n case 0x41:\n src = this.getEALongData(this.regECX + this.getIPDisp());\n break;\n case 0x42:\n src = this.getEALongData(this.regEDX + this.getIPDisp());\n break;\n case 0x43:\n src = this.getEALongData(this.regEBX + this.getIPDisp());\n break;\n case 0x44:\n src = this.getEALongData(X86.modSIB.call(this, 1) + this.getIPDisp());\n break;\n case 0x45:\n src = this.getEALongStack(this.regEBP + this.getIPDisp());\n break;\n case 0x46:\n src = this.getEALongData(this.regESI + this.getIPDisp());\n break;\n case 0x47:\n src = this.getEALongData(this.regEDI + this.getIPDisp());\n break;\n case 0x80:\n src = this.getEALongData(this.regEAX + this.getIPAddr());\n break;\n case 0x81:\n src = this.getEALongData(this.regECX + this.getIPAddr());\n break;\n case 0x82:\n src = this.getEALongData(this.regEDX + this.getIPAddr());\n break;\n case 0x83:\n src = this.getEALongData(this.regEBX + this.getIPAddr());\n break;\n case 0x84:\n src = this.getEALongData(X86.modSIB.call(this, 2) + this.getIPAddr());\n break;\n case 0x85:\n src = this.getEALongStack(this.regEBP + this.getIPAddr());\n break;\n case 0x86:\n src = this.getEALongData(this.regESI + this.getIPAddr());\n break;\n case 0x87:\n src = this.getEALongData(this.regEDI + this.getIPAddr());\n break;\n case 0xC0:\n src = this.regEAX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiAL; this.backTrack.btiEAHi = this.backTrack.btiAH;\n }\n break;\n case 0xC1:\n src = this.regECX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiCL; this.backTrack.btiEAHi = this.backTrack.btiCH;\n }\n break;\n case 0xC2:\n src = this.regEDX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDL; this.backTrack.btiEAHi = this.backTrack.btiDH;\n }\n break;\n case 0xC3:\n src = this.regEBX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBL; this.backTrack.btiEAHi = this.backTrack.btiBH;\n }\n break;\n case 0xC4:\n src = this.getSP();\n if (BACKTRACK) {\n this.backTrack.btiEALo = X86.BTINFO.SP_LO; this.backTrack.btiEAHi = X86.BTINFO.SP_HI;\n }\n break;\n case 0xC5:\n src = this.regEBP;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBPLo; this.backTrack.btiEAHi = this.backTrack.btiBPHi;\n }\n break;\n case 0xC6:\n src = this.regESI;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiSILo; this.backTrack.btiEAHi = this.backTrack.btiSIHi;\n }\n break;\n case 0xC7:\n src = this.regEDI;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDILo; this.backTrack.btiEAHi = this.backTrack.btiDIHi;\n }\n break;\n default:\n src = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n dst = this.regEAX;\n break;\n case 0x1:\n dst = this.regECX;\n break;\n case 0x2:\n dst = this.regEDX;\n break;\n case 0x3:\n dst = this.regEBX;\n break;\n case 0x4:\n dst = this.getSP();\n break;\n case 0x5:\n dst = this.regEBP;\n break;\n case 0x6:\n dst = this.regESI;\n break;\n case 0x7:\n dst = this.regEDI;\n break;\n default:\n dst = 0;\n break;\n }\n\n var l = fn.call(this, dst, src);\n\n switch(reg) {\n case 0x0:\n this.regEAX = l;\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiEALo; this.backTrack.btiAH = this.backTrack.btiEAHi;\n }\n break;\n case 0x1:\n this.regECX = l;\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiEALo; this.backTrack.btiCH = this.backTrack.btiEAHi;\n }\n break;\n case 0x2:\n this.regEDX = l;\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiEALo; this.backTrack.btiDH = this.backTrack.btiEAHi;\n }\n break;\n case 0x3:\n this.regEBX = l;\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiEALo; this.backTrack.btiBH = this.backTrack.btiEAHi;\n }\n break;\n case 0x4:\n this.setSP(l);\n break;\n case 0x5:\n this.regEBP = l;\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiEALo; this.backTrack.btiBPHi = this.backTrack.btiEAHi;\n }\n break;\n case 0x6:\n this.regESI = l;\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiEALo; this.backTrack.btiSIHi = this.backTrack.btiEAHi;\n }\n break;\n case 0x7:\n this.regEDI = l;\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiEALo; this.backTrack.btiDIHi = this.backTrack.btiEAHi;\n }\n break;\n }\n};\n\n/**\n * modMemLong32(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modMemLong32 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEALongData(this.regEAX);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEALongData(this.regECX);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEALongData(this.regEDX);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEALongData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEALongData(X86.modSIB.call(this, 0));\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEALongData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEALongData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEALongData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEALongData(this.regEAX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEALongData(this.regECX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEALongData(this.regEDX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEALongData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEALongData(X86.modSIB.call(this, 1) + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEALongStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEALongData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEALongData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEALongData(this.regEAX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEALongData(this.regECX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEALongData(this.regEDX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEALongData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEALongData(X86.modSIB.call(this, 2) + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEALongStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEALongData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEALongData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX;\n break;\n case 0xC1:\n dst = this.regECX;\n break;\n case 0xC2:\n dst = this.regEDX;\n break;\n case 0xC3:\n dst = this.regEBX;\n break;\n case 0xC4:\n dst = this.getSP();\n break;\n case 0xC5:\n dst = this.regEBP;\n break;\n case 0xC6:\n dst = this.regESI;\n break;\n case 0xC7:\n dst = this.regEDI;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n src = this.regEAX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiAL; this.backTrack.btiEAHi = this.backTrack.btiAH;\n }\n break;\n case 0x1:\n src = this.regECX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiCL; this.backTrack.btiEAHi = this.backTrack.btiCH;\n }\n break;\n case 0x2:\n src = this.regEDX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDL; this.backTrack.btiEAHi = this.backTrack.btiDH;\n }\n break;\n case 0x3:\n src = this.regEBX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBL; this.backTrack.btiEAHi = this.backTrack.btiBH;\n }\n break;\n case 0x4:\n src = this.getSP();\n if (BACKTRACK) {\n this.backTrack.btiEALo = X86.BTINFO.SP_LO; this.backTrack.btiEAHi = X86.BTINFO.SP_HI;\n }\n break;\n case 0x5:\n src = this.regEBP;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBPLo; this.backTrack.btiEAHi = this.backTrack.btiBPHi;\n }\n break;\n case 0x6:\n src = this.regESI;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiSILo; this.backTrack.btiEAHi = this.backTrack.btiSIHi;\n }\n break;\n case 0x7:\n src = this.regEDI;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDILo; this.backTrack.btiEAHi = this.backTrack.btiDIHi;\n }\n break;\n default:\n src = 0;\n break;\n }\n\n var l = fn.call(this, dst, src);\n\n switch(bModRM) {\n case 0xC0:\n this.regEAX = l;\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiEALo; this.backTrack.btiAH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC1:\n this.regECX = l;\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiEALo; this.backTrack.btiCH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC2:\n this.regEDX = l;\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiEALo; this.backTrack.btiDH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC3:\n this.regEBX = l;\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiEALo; this.backTrack.btiBH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC4:\n this.setSP(l);\n break;\n case 0xC5:\n this.regEBP = l;\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiEALo; this.backTrack.btiBPHi = this.backTrack.btiEAHi;\n }\n break;\n case 0xC6:\n this.regESI = l;\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiEALo; this.backTrack.btiSIHi = this.backTrack.btiEAHi;\n }\n break;\n case 0xC7:\n this.regEDI = l;\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiEALo; this.backTrack.btiDIHi = this.backTrack.btiEAHi;\n }\n break;\n default:\n this.setEALong(l);\n break;\n }\n};\n\n/**\n * modGrpLong32(afnGrp, fnSrc)\n *\n * @this {CPUX86}\n * @param {Array.<function(number,number)>} afnGrp\n * @param {function()} fnSrc\n */\nX86.modGrpLong32 = function(afnGrp, fnSrc) {\n var dst;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEALongData(this.regEAX);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEALongData(this.regECX);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEALongData(this.regEDX);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEALongData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEALongData(X86.modSIB.call(this, 0));\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEALongData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEALongData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEALongData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEALongData(this.regEAX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEALongData(this.regECX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEALongData(this.regEDX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEALongData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEALongData(X86.modSIB.call(this, 1) + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEALongStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEALongData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEALongData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEALongData(this.regEAX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEALongData(this.regECX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEALongData(this.regEDX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEALongData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEALongData(X86.modSIB.call(this, 2) + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEALongStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEALongData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEALongData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX;\n break;\n case 0xC1:\n dst = this.regECX;\n break;\n case 0xC2:\n dst = this.regEDX;\n break;\n case 0xC3:\n dst = this.regEBX;\n break;\n case 0xC4:\n dst = this.getSP();\n break;\n case 0xC5:\n dst = this.regEBP;\n break;\n case 0xC6:\n dst = this.regESI;\n break;\n case 0xC7:\n dst = this.regEDI;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n var l = afnGrp[reg].call(this, dst, fnSrc.call(this));\n\n switch(bModRM) {\n case 0xC0:\n this.regEAX = l;\n break;\n case 0xC1:\n this.regECX = l;\n break;\n case 0xC2:\n this.regEDX = l;\n break;\n case 0xC3:\n this.regEBX = l;\n break;\n case 0xC4:\n this.setSP(l);\n break;\n case 0xC5:\n this.regEBP = l;\n break;\n case 0xC6:\n this.regESI = l;\n break;\n case 0xC7:\n this.regEDI = l;\n break;\n default:\n this.setEALong(l);\n break;\n }\n};\n\n/**\n * modSIB(mod)\n *\n * @this {CPUX86}\n * @param {number} mod\n * @return {number}\n */\nX86.modSIB = function(mod)\n{\n var bSIB = this.getIPByte();\n var scale = bSIB >> 6, index, base;\n\n switch((bSIB >> 3) & 0x7) {\n case 0:\n index = this.regEAX;\n break;\n case 1:\n index = this.regECX;\n break;\n case 2:\n index = this.regEDX;\n break;\n case 3:\n index = this.regEBX;\n break;\n case 4:\n index = 0;\n break;\n case 5:\n index = this.regEBP;\n break;\n case 6:\n index = this.regESI;\n break;\n case 7:\n index = this.regEDI;\n break;\n }\n\n switch(bSIB & 0x07) {\n case 0:\n base = this.regEAX;\n break;\n case 1:\n base = this.regECX;\n break;\n case 2:\n base = this.regEDX;\n break;\n case 3:\n base = this.regEBX;\n break;\n case 4:\n base = this.getSP();\n this.segData = this.segStack;\n break;\n case 5:\n if (mod) {\n base = this.regEBP;\n this.segData = this.segStack;\n } else {\n base = this.getIPAddr();\n }\n break;\n case 6:\n base = this.regESI;\n break;\n case 7:\n base = this.regEDI;\n break;\n }\n\n return ((index << scale) + base)|0;\n};\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/x86ops.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * op=0x00 (ADD byte,reg)\n *\n * @this {CPUX86}\n */\nX86.opADDmb = function()\n{\n this.decodeModMemByte.call(this, X86.fnADDb);\n /*\n * Opcode bytes 0x00 0x00 are sufficiently uncommon that it's more likely we've started\n * executing in the weeds, so if you're in DEBUG mode, we'll print a warning and stop the\n * CPU if a Debugger is available.\n *\n * Notice that we also test fRunning: this allows the Debugger to step over the instruction,\n * because its trace (\"t\") command doesn't \"run\" the CPU; it merely \"steps\" the CPU.\n */\n if (DEBUG && !this.bModRM && this.flags.running) {\n this.printMessage(\"suspicious opcode: 0x00 0x00\", DEBUGGER || this.bitsMessage);\n if (DEBUGGER && this.dbg) this.dbg.stopCPU();\n }\n};\n\n/**\n * op=0x01 (ADD word,reg)\n *\n * @this {CPUX86}\n */\nX86.opADDmw = function()\n{\n this.decodeModMemWord.call(this, X86.fnADDw);\n};\n\n/**\n * op=0x02 (ADD reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opADDrb = function()\n{\n this.decodeModRegByte.call(this, X86.fnADDb);\n};\n\n/**\n * op=0x03 (ADD reg,word)\n *\n * @this {CPUX86}\n */\nX86.opADDrw = function()\n{\n this.decodeModRegWord.call(this, X86.fnADDw);\n};\n\n/**\n * op=0x04 (ADD AL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opADDALb = function()\n{\n this.regEAX = (this.regEAX & ~0xff) | X86.fnADDb.call(this, this.regEAX & 0xff, this.getIPByte());\n /*\n * NOTE: Whenever the result is \"blended\" value (eg, of btiAL and btiMem0), a new bti should be\n * allocated to reflect that fact; however, I'm leaving \"perfect\" BACKTRACK support for another day.\n */\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiMem0;\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x05 (ADD AX,imm16 or ADD EAX,imm32)\n *\n * @this {CPUX86}\n */\nX86.opADDAX = function()\n{\n this.regEAX = (this.regEAX & ~this.maskData) | X86.fnADDw.call(this, this.regEAX & this.maskData, this.getIPWord());\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x06 (PUSH ES)\n *\n * @this {CPUX86}\n */\nX86.opPUSHES = function()\n{\n /*\n * When the OPERAND size is 32 bits, the 80386 will decrement the stack pointer by 4, write the selector\n * into the 2 lower bytes, and leave the 2 upper bytes untouched; to properly emulate that, we must use the\n * more generic pushData() instead of pushWord().\n */\n if (!I386) {\n this.pushWord(this.segES.sel);\n } else {\n this.pushData(this.segES.sel, this.sizeData, 2);\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushSeg;\n};\n\n/**\n * op=0x07 (POP ES)\n *\n * @this {CPUX86}\n */\nX86.opPOPES = function()\n{\n /*\n * Any operation that modifies the stack before loading a new segment must snapshot regLSP first.\n */\n this.opLSP = this.regLSP;\n this.setES(this.popWord());\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n this.opLSP = X86.ADDR_INVALID;\n};\n\n/**\n * op=0x08 (OR byte,reg)\n *\n * @this {CPUX86}\n */\nX86.opORmb = function()\n{\n this.decodeModMemByte.call(this, X86.fnORb);\n};\n\n/**\n * op=0x09 (OR word,reg)\n *\n * @this {CPUX86}\n */\nX86.opORmw = function()\n{\n this.decodeModMemWord.call(this, X86.fnORw);\n};\n\n/**\n * op=0x0A (OR reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opORrb = function()\n{\n this.decodeModRegByte.call(this, X86.fnORb);\n};\n\n/**\n * op=0x0B (OR reg,word)\n *\n * @this {CPUX86}\n */\nX86.opORrw = function()\n{\n this.decodeModRegWord.call(this, X86.fnORw);\n};\n\n/**\n * op=0x0C (OR AL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opORALb = function()\n{\n this.regEAX = (this.regEAX & ~0xff) | X86.fnORb.call(this, this.regEAX & 0xff, this.getIPByte());\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiMem0;\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x0D (OR AX,imm16 or OR EAX,imm32)\n *\n * @this {CPUX86}\n */\nX86.opORAX = function()\n{\n this.regEAX = (this.regEAX & ~this.maskData) | X86.fnORw.call(this, this.regEAX & this.maskData, this.getIPWord());\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x0E (PUSH CS)\n *\n * @this {CPUX86}\n */\nX86.opPUSHCS = function()\n{\n /*\n * When the OPERAND size is 32 bits, the 80386 will decrement the stack pointer by 4, write the selector\n * into the 2 lower bytes, and leave the 2 upper bytes untouched; to properly emulate that, we must use the\n * more generic pushData() instead of pushWord().\n */\n if (!I386) {\n this.pushWord(this.segCS.sel);\n } else {\n this.pushData(this.segCS.sel, this.sizeData, 2);\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushSeg;\n};\n\n/**\n * op=0x0F (POP CS) (undocumented on 8086/8088; replaced with opInvalid() on 80186/80188, and op0F() on 80286 and up)\n *\n * @this {CPUX86}\n */\nX86.opPOPCS = function()\n{\n /*\n * Because this is an 8088-only operation, we don't have to worry about taking a snapshot of regLSP first.\n */\n this.setCS(this.popWord());\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n};\n\n/**\n * op=0x0F (handler for two-byte opcodes; 80286 and up)\n *\n * @this {CPUX86}\n */\nX86.op0F = function()\n{\n this.aOps0F[this.getIPByte()].call(this);\n};\n\n/**\n * op=0x10 (ADC byte,reg)\n *\n * @this {CPUX86}\n */\nX86.opADCmb = function()\n{\n this.decodeModMemByte.call(this, X86.fnADCb);\n};\n\n/**\n * op=0x11 (ADC word,reg)\n *\n * @this {CPUX86}\n */\nX86.opADCmw = function()\n{\n this.decodeModMemWord.call(this, X86.fnADCw);\n};\n\n/**\n * op=0x12 (ADC reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opADCrb = function()\n{\n this.decodeModRegByte.call(this, X86.fnADCb);\n};\n\n/**\n * op=0x13 (ADC reg,word)\n *\n * @this {CPUX86}\n */\nX86.opADCrw = function()\n{\n this.decodeModRegWord.call(this, X86.fnADCw);\n};\n\n/**\n * op=0x14 (ADC AL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opADCALb = function()\n{\n this.regEAX = (this.regEAX & ~0xff) | X86.fnADCb.call(this, this.regEAX & 0xff, this.getIPByte());\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiMem0;\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x15 (ADC AX,imm16 or ADC EAX,imm32)\n *\n * @this {CPUX86}\n */\nX86.opADCAX = function()\n{\n this.regEAX = (this.regEAX & ~this.maskData) | X86.fnADCw.call(this, this.regEAX & this.maskData, this.getIPWord());\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x16 (PUSH SS)\n *\n * @this {CPUX86}\n */\nX86.opPUSHSS = function()\n{\n /*\n * When the OPERAND size is 32 bits, the 80386 will decrement the stack pointer by 4, write the selector\n * into the 2 lower bytes, and leave the 2 upper bytes untouched; to properly emulate that, we must use the\n * more generic pushData() instead of pushWord().\n */\n if (!I386) {\n this.pushWord(this.segSS.sel);\n } else {\n this.pushData(this.segSS.sel, this.sizeData, 2);\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushSeg;\n};\n\n/**\n * op=0x17 (POP SS)\n *\n * @this {CPUX86}\n */\nX86.opPOPSS = function()\n{\n /*\n * Any operation that modifies the stack before loading a new segment must snapshot regLSP first.\n */\n this.opLSP = this.regLSP;\n this.setSS(this.popWord());\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n this.opLSP = X86.ADDR_INVALID;\n};\n\n/**\n * op=0x18 (SBB byte,reg)\n *\n * @this {CPUX86}\n */\nX86.opSBBmb = function()\n{\n this.decodeModMemByte.call(this, X86.fnSBBb);\n};\n\n/**\n * op=0x19 (SBB word,reg)\n *\n * @this {CPUX86}\n */\nX86.opSBBmw = function()\n{\n this.decodeModMemWord.call(this, X86.fnSBBw);\n};\n\n/**\n * op=0x1A (SBB reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opSBBrb = function()\n{\n this.decodeModRegByte.call(this, X86.fnSBBb);\n};\n\n/**\n * op=0x1B (SBB reg,word)\n *\n * @this {CPUX86}\n */\nX86.opSBBrw = function()\n{\n this.decodeModRegWord.call(this, X86.fnSBBw);\n};\n\n/**\n * op=0x1C (SBB AL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opSBBALb = function()\n{\n this.regEAX = (this.regEAX & ~0xff) | X86.fnSBBb.call(this, this.regEAX & 0xff, this.getIPByte());\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiMem0;\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x1D (SBB AX,imm16 or SBB EAX,imm32)\n *\n * @this {CPUX86}\n */\nX86.opSBBAX = function()\n{\n this.regEAX = (this.regEAX & ~this.maskData) | X86.fnSBBw.call(this, this.regEAX & this.maskData, this.getIPWord());\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x1E (PUSH DS)\n *\n * @this {CPUX86}\n */\nX86.opPUSHDS = function()\n{\n /*\n * When the OPERAND size is 32 bits, the 80386 will decrement the stack pointer by 4, write the selector\n * into the 2 lower bytes, and leave the 2 upper bytes untouched; to properly emulate that, we must use the\n * more generic pushData() instead of pushWord().\n */\n if (!I386) {\n this.pushWord(this.segDS.sel);\n } else {\n this.pushData(this.segDS.sel, this.sizeData, 2);\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushSeg;\n};\n\n/**\n * op=0x1F (POP DS)\n *\n * @this {CPUX86}\n */\nX86.opPOPDS = function()\n{\n /*\n * Any operation that modifies the stack before loading a new segment must snapshot regLSP first.\n */\n this.opLSP = this.regLSP;\n this.setDS(this.popWord());\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n this.opLSP = X86.ADDR_INVALID;\n};\n\n/**\n * op=0x20 (AND byte,reg)\n *\n * @this {CPUX86}\n */\nX86.opANDmb = function()\n{\n this.decodeModMemByte.call(this, X86.fnANDb);\n};\n\n/**\n * op=0x21 (AND word,reg)\n *\n * @this {CPUX86}\n */\nX86.opANDmw = function()\n{\n this.decodeModMemWord.call(this, X86.fnANDw);\n};\n\n/**\n * op=0x22 (AND reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opANDrb = function()\n{\n this.decodeModRegByte.call(this, X86.fnANDb);\n};\n\n/**\n * op=0x23 (AND reg,word)\n *\n * @this {CPUX86}\n */\nX86.opANDrw = function()\n{\n this.decodeModRegWord.call(this, X86.fnANDw);\n};\n\n/**\n * op=0x24 (AND AL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opANDAL = function()\n{\n this.regEAX = (this.regEAX & ~0xff) | X86.fnANDb.call(this, this.regEAX & 0xff, this.getIPByte());\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiMem0;\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x25 (AND AX,imm16 or AND EAX,imm32)\n *\n * @this {CPUX86}\n */\nX86.opANDAX = function()\n{\n this.regEAX = (this.regEAX & ~this.maskData) | X86.fnANDw.call(this, this.regEAX & this.maskData, this.getIPWord());\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x26 (ES:)\n *\n * @this {CPUX86}\n */\nX86.opES = function()\n{\n this.opFlags |= X86.OPFLAG.SEG | X86.OPFLAG.NOINTR;\n this.segData = this.segStack = this.segES;\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n};\n\n/**\n * op=0x27 (DAA)\n *\n * @this {CPUX86}\n */\nX86.opDAA = function()\n{\n var AL = this.regEAX & 0xff;\n var AF = this.getAF();\n var CF = this.getCF();\n if ((AL & 0xf) > 9 || AF) {\n AL += 0x6;\n AF = X86.PS.AF;\n } else {\n AF = 0;\n }\n if (AL > 0x9f || CF) {\n AL += 0x60;\n CF = X86.PS.CF;\n } else {\n CF = 0;\n }\n var b = (AL & 0xff);\n this.regEAX = (this.regEAX & ~0xff) | b;\n this.setLogicResult(b, X86.RESULT.BYTE);\n if (CF) this.setCF(); else this.clearCF();\n if (AF) this.setAF(); else this.clearAF();\n this.nStepCycles -= this.cycleCounts.nOpCyclesAAA; // AAA and DAA have the same cycle times\n};\n\n/**\n * op=0x28 (SUB byte,reg)\n *\n * @this {CPUX86}\n */\nX86.opSUBmb = function()\n{\n this.decodeModMemByte.call(this, X86.fnSUBb);\n};\n\n/**\n * op=0x29 (SUB word,reg)\n *\n * @this {CPUX86}\n */\nX86.opSUBmw = function()\n{\n this.decodeModMemWord.call(this, X86.fnSUBw);\n};\n\n/**\n * op=0x2A (SUB reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opSUBrb = function()\n{\n this.decodeModRegByte.call(this, X86.fnSUBb);\n};\n\n/**\n * op=0x2B (SUB reg,word)\n *\n * @this {CPUX86}\n */\nX86.opSUBrw = function()\n{\n this.decodeModRegWord.call(this, X86.fnSUBw);\n};\n\n/**\n * op=0x2C (SUB AL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opSUBALb = function()\n{\n this.regEAX = (this.regEAX & ~0xff) | X86.fnSUBb.call(this, this.regEAX & 0xff, this.getIPByte());\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiMem0;\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x2D (SUB AX,imm16 or SUB EAX,imm32)\n *\n * @this {CPUX86}\n */\nX86.opSUBAX = function()\n{\n this.regEAX = (this.regEAX & ~this.maskData) | X86.fnSUBw.call(this, this.regEAX & this.maskData, this.getIPWord());\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x2E (CS:)\n *\n * @this {CPUX86}\n */\nX86.opCS = function()\n{\n this.opFlags |= X86.OPFLAG.SEG | X86.OPFLAG.NOINTR;\n this.segData = this.segStack = this.segCS;\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n};\n\n/**\n * op=0x2F (DAS)\n *\n * @this {CPUX86}\n */\nX86.opDAS = function()\n{\n var AL = this.regEAX & 0xff;\n var AF = this.getAF();\n var CF = this.getCF();\n if ((AL & 0xf) > 9 || AF) {\n AL -= 0x6;\n AF = X86.PS.AF;\n } else {\n AF = 0;\n }\n if (AL > 0x9f || CF) {\n AL -= 0x60;\n CF = X86.PS.CF;\n } else {\n CF = 0;\n }\n var b = (AL & 0xff);\n this.regEAX = (this.regEAX & ~0xff) | b;\n this.setLogicResult(b, X86.RESULT.BYTE);\n if (CF) this.setCF(); else this.clearCF();\n if (AF) this.setAF(); else this.clearAF();\n this.nStepCycles -= this.cycleCounts.nOpCyclesAAA; // AAA and DAS have the same cycle times\n};\n\n/**\n * op=0x30 (XOR byte,reg)\n *\n * @this {CPUX86}\n */\nX86.opXORmb = function()\n{\n this.decodeModMemByte.call(this, X86.fnXORb);\n};\n\n/**\n * op=0x31 (XOR word,reg)\n *\n * @this {CPUX86}\n */\nX86.opXORmw = function()\n{\n this.decodeModMemWord.call(this, X86.fnXORw);\n};\n\n/**\n * op=0x32 (XOR reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opXORrb = function()\n{\n this.decodeModRegByte.call(this, X86.fnXORb);\n};\n\n/**\n * op=0x33 (XOR reg,word)\n *\n * @this {CPUX86}\n */\nX86.opXORrw = function()\n{\n this.decodeModRegWord.call(this, X86.fnXORw);\n};\n\n/**\n * op=0x34 (XOR AL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opXORALb = function()\n{\n this.regEAX = (this.regEAX & ~0xff) | X86.fnXORb.call(this, this.regEAX & 0xff, this.getIPByte());\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiMem0;\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x35 (XOR AX,imm16 or XOR EAX,imm32)\n *\n * @this {CPUX86}\n */\nX86.opXORAX = function()\n{\n this.regEAX = (this.regEAX & ~this.maskData) | X86.fnXORw.call(this, this.regEAX & this.maskData, this.getIPWord());\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x36 (SS:)\n *\n * @this {CPUX86}\n */\nX86.opSS = function()\n{\n this.opFlags |= X86.OPFLAG.SEG | X86.OPFLAG.NOINTR;\n this.segData = this.segStack = this.segSS; // QUESTION: Is there a case where segStack would not already be segSS? (eg, multiple segment overrides?)\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n};\n\n/**\n * op=0x37 (AAA)\n *\n * @this {CPUX86}\n */\nX86.opAAA = function()\n{\n var CF, AF;\n var AL = this.regEAX & 0xff;\n var AH = (this.regEAX >> 8) & 0xff;\n if ((AL & 0xf) > 9 || this.getAF()) {\n AL += 6;\n /*\n * Simulate the fact that the 80286 and higher add 6 to AX rather than AL.\n */\n if (this.model >= X86.MODEL_80286 && AL > 0xff) AH++;\n AH++;\n CF = AF = 1;\n } else {\n CF = AF = 0;\n }\n this.regEAX = (this.regEAX & ~0xffff) | (((AH << 8) | AL) & 0xff0f);\n if (CF) this.setCF(); else this.clearCF();\n if (AF) this.setAF(); else this.clearAF();\n this.nStepCycles -= this.cycleCounts.nOpCyclesAAA;\n};\n\n/**\n * op=0x38 (CMP byte,reg)\n *\n * @this {CPUX86}\n */\nX86.opCMPmb = function()\n{\n this.decodeModMemByte.call(this, X86.fnCMPb);\n};\n\n/**\n * op=0x39 (CMP word,reg)\n *\n * @this {CPUX86}\n */\nX86.opCMPmw = function()\n{\n this.decodeModMemWord.call(this, X86.fnCMPw);\n};\n\n/**\n * op=0x3A (CMP reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opCMPrb = function()\n{\n this.decodeModRegByte.call(this, X86.fnCMPb);\n};\n\n/**\n * op=0x3B (CMP reg,word)\n *\n * @this {CPUX86}\n */\nX86.opCMPrw = function()\n{\n this.decodeModRegWord.call(this, X86.fnCMPw);\n};\n\n/**\n * op=0x3C (CMP AL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opCMPALb = function()\n{\n X86.fnCMPb.call(this, this.regEAX & 0xff, this.getIPByte());\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x3D (CMP AX,imm16 or CMP EAX,imm32)\n *\n * @this {CPUX86}\n */\nX86.opCMPAX = function()\n{\n X86.fnCMPw.call(this, this.regEAX & this.maskData, this.getIPWord());\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x3E (DS:)\n *\n * @this {CPUX86}\n */\nX86.opDS = function()\n{\n this.opFlags |= X86.OPFLAG.SEG | X86.OPFLAG.NOINTR;\n this.segData = this.segStack = this.segDS; // QUESTION: Is there a case where segData would not already be segDS? (eg, multiple segment overrides?)\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n};\n\n/**\n * op=0x3D (AAS)\n *\n * @this {CPUX86}\n */\nX86.opAAS = function()\n{\n var CF, AF;\n var AL = this.regEAX & 0xff;\n var AH = (this.regEAX >> 8) & 0xff;\n if ((AL & 0xf) > 9 || this.getAF()) {\n AL = (AL - 0x6) & 0xf;\n AH = (AH - 1) & 0xff;\n CF = AF = 1;\n } else {\n CF = AF = 0;\n }\n this.regEAX = (this.regEAX & ~0xffff) | ((AH << 8) | AL);\n if (CF) this.setCF(); else this.clearCF();\n if (AF) this.setAF(); else this.clearAF();\n this.nStepCycles -= this.cycleCounts.nOpCyclesAAA; // AAA and AAS have the same cycle times\n};\n\n/**\n * op=0x40 (INC [E]AX)\n *\n * @this {CPUX86}\n */\nX86.opINCAX = function()\n{\n this.regEAX = X86.helpINCreg.call(this, this.regEAX);\n};\n\n/**\n * op=0x41 (INC [E]CX)\n *\n * @this {CPUX86}\n */\nX86.opINCCX = function()\n{\n this.regECX = X86.helpINCreg.call(this, this.regECX);\n};\n\n/**\n * op=0x42 (INC [E]DX)\n *\n * @this {CPUX86}\n */\nX86.opINCDX = function()\n{\n this.regEDX = X86.helpINCreg.call(this, this.regEDX);\n};\n\n/**\n * op=0x43 (INC [E]BX)\n *\n * @this {CPUX86}\n */\nX86.opINCBX = function()\n{\n this.regEBX = X86.helpINCreg.call(this, this.regEBX);\n};\n\n/**\n * op=0x44 (INC [E]SP)\n *\n * @this {CPUX86}\n */\nX86.opINCSP = function()\n{\n this.setSP(X86.helpINCreg.call(this, this.getSP()));\n};\n\n/**\n * op=0x45 (INC [E]BP)\n *\n * @this {CPUX86}\n */\nX86.opINCBP = function()\n{\n this.regEBP = X86.helpINCreg.call(this, this.regEBP);\n};\n\n/**\n * op=0x46 (INC [E]SI)\n *\n * @this {CPUX86}\n */\nX86.opINCSI = function()\n{\n this.regESI = X86.helpINCreg.call(this, this.regESI);\n};\n\n/**\n * op=0x47 (INC [E]DI)\n *\n * @this {CPUX86}\n */\nX86.opINCDI = function()\n{\n this.regEDI = X86.helpINCreg.call(this, this.regEDI);\n};\n\n/**\n * op=0x48 (DEC [E]AX)\n *\n * @this {CPUX86}\n */\nX86.opDECAX = function()\n{\n this.regEAX = X86.helpDECreg.call(this, this.regEAX);\n};\n\n/**\n * op=0x49 (DEC [E]CX)\n *\n * @this {CPUX86}\n */\nX86.opDECCX = function()\n{\n this.regECX = X86.helpDECreg.call(this, this.regECX);\n};\n\n/**\n * op=0x4A (DEC [E]DX)\n *\n * @this {CPUX86}\n */\nX86.opDECDX = function()\n{\n this.regEDX = X86.helpDECreg.call(this, this.regEDX);\n};\n\n/**\n * op=0x4B (DEC [E]BX)\n *\n * @this {CPUX86}\n */\nX86.opDECBX = function()\n{\n this.regEBX = X86.helpDECreg.call(this, this.regEBX);\n};\n\n/**\n * op=0x4C (DEC [E]SP)\n *\n * @this {CPUX86}\n */\nX86.opDECSP = function()\n{\n this.setSP(X86.helpDECreg.call(this, this.getSP()));\n};\n\n/**\n * op=0x4D (DEC [E]BP)\n *\n * @this {CPUX86}\n */\nX86.opDECBP = function()\n{\n this.regEBP = X86.helpDECreg.call(this, this.regEBP);\n};\n\n/**\n * op=0x4E (DEC [E]SI)\n *\n * @this {CPUX86}\n */\nX86.opDECSI = function()\n{\n this.regESI = X86.helpDECreg.call(this, this.regESI);\n};\n\n/**`\n * op=0x4F (DEC [E]DI)\n *\n * @this {CPUX86}\n */\nX86.opDECDI = function()\n{\n this.regEDI = X86.helpDECreg.call(this, this.regEDI);\n};\n\n/**\n * op=0x50 (PUSH [E]AX)\n *\n * @this {CPUX86}\n */\nX86.opPUSHAX = function()\n{\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiAL; this.backTrack.btiMem1 = this.backTrack.btiAH;\n }\n this.pushWord(this.regEAX & this.maskData);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x51 (PUSH [E]CX)\n *\n * @this {CPUX86}\n */\nX86.opPUSHCX = function()\n{\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiCL; this.backTrack.btiMem1 = this.backTrack.btiCH;\n }\n this.pushWord(this.regECX & this.maskData);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x52 (PUSH [E]DX)\n *\n * @this {CPUX86}\n */\nX86.opPUSHDX = function()\n{\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiDL; this.backTrack.btiMem1 = this.backTrack.btiDH;\n }\n this.pushWord(this.regEDX & this.maskData);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x53 (PUSH [E]BX)\n *\n * @this {CPUX86}\n */\nX86.opPUSHBX = function()\n{\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiBL; this.backTrack.btiMem1 = this.backTrack.btiBH;\n }\n this.pushWord(this.regEBX & this.maskData);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x54 (PUSH SP)\n *\n * NOTE: Having an accurate implementation of \"PUSH SP\" for the 8086/8088 isn't just a nice idea, it affects real\n * code. Case in point: early Microsoft C floating-point libraries relied on \"PUSH SP\" behavior to quickly determine\n * whether an 8088 (and therefore presumably an 8087) or an 80286 (and presumably an 80287) was being used; eg:\n *\n * &0910:1E82 D93E1709 FSTCW WORD [0917]\n * &0910:1E86 CD3D INT 3D\n * &0E4E:06D3 50 PUSH AX\n * &0E4E:06D4 B83DA2 MOV AX,A23D\n * &0E4E:06D7 EB04 JMP 06DD\n * &0E4E:06DD 55 PUSH BP\n * &0E4E:06DE 1E PUSH DS\n * &0E4E:06DF 56 PUSH SI\n * &0E4E:06E0 8BEC MOV BP,SP\n * &0E4E:06E2 C57608 LDS SI,[BP+08]\n * &0E4E:06E5 4E DEC SI\n * &0E4E:06E6 4E DEC SI\n * &0E4E:06E7 897608 MOV [BP+08],SI\n * &0E4E:06EA 2904 SUB [SI],AX\n * &0E4E:06EC 53 PUSH BX\n * &0E4E:06ED 33DB XOR BX,BX\n * &0E4E:06EF 54 PUSH SP ; beginning of processor check\n * &0E4E:06F0 58 POP AX\n * &0E4E:06F1 3BC4 CMP AX,SP\n * &0E4E:06F3 7528 JNZ 071D ; jump if 8086/8088/80186/80188, no jump if 80286 or later\n * &0E4E:06F5 8B4001 MOV AX,[BX+SI+01]\n * &0E4E:06F8 25FB30 AND AX,30FB\n * &0E4E:06FB 3DD930 CMP AX,30D9\n * &0E4E:06FE 7507 JNZ 0707\n * &0E4E:0700 8A4002 MOV AL,[BX+SI+02]\n * &0E4E:0703 3CF0 CMP AL,F0\n * &0E4E:0705 7216 JC 071D\n * &0E4E:0707 8B4001 MOV AX,[BX+SI+01]\n * &0E4E:070A 25FFFE AND AX,FEFF\n * &0E4E:070D 3DDBE2 CMP AX,E2DB\n * &0E4E:0710 740B JZ 071D\n * &0E4E:0712 8B4001 MOV AX,[BX+SI+01]\n * &0E4E:0715 3DDFE0 CMP AX,E0DF\n * &0E4E:0718 7403 JZ 071D\n * &0E4E:071A C60490 MOV [SI],90\n * &0E4E:071D 5B POP BX\n * &0E4E:071E 5E POP SI\n * &0E4E:071F 1F POP DS\n * &0E4E:0720 5D POP BP\n * &0E4E:0721 58 POP AX\n * &0E4E:0722 CF IRET\n *\n * @this {CPUX86}\n */\nX86.opPUSHSP_8086 = function()\n{\n var w = (this.getSP() - 2) & 0xffff;\n this.pushWord(w);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x54 (PUSH [E]SP)\n *\n * @this {CPUX86}\n */\nX86.opPUSHSP = function()\n{\n this.pushWord(this.getSP() & this.maskData);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x55 (PUSH [E]BP)\n *\n * @this {CPUX86}\n */\nX86.opPUSHBP = function()\n{\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiBPLo; this.backTrack.btiMem1 = this.backTrack.btiBPHi;\n }\n this.pushWord(this.regEBP & this.maskData);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x56 (PUSH [E]SI)\n *\n * @this {CPUX86}\n */\nX86.opPUSHSI = function()\n{\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiSILo; this.backTrack.btiMem1 = this.backTrack.btiSIHi;\n }\n this.pushWord(this.regESI & this.maskData);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x57 (PUSH [E]DI)\n *\n * @this {CPUX86}\n */\nX86.opPUSHDI = function()\n{\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiDILo; this.backTrack.btiMem1 = this.backTrack.btiDIHi;\n }\n this.pushWord(this.regEDI & this.maskData);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x58 (POP [E]AX)\n *\n * @this {CPUX86}\n */\nX86.opPOPAX = function()\n{\n this.regEAX = (this.regEAX & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n};\n\n/**\n * op=0x59 (POP [E]CX)\n *\n * @this {CPUX86}\n */\nX86.opPOPCX = function()\n{\n this.regECX = (this.regECX & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiMem0; this.backTrack.btiCH = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n};\n\n/**\n * op=0x5A (POP [E]DX)\n *\n * @this {CPUX86}\n */\nX86.opPOPDX = function()\n{\n this.regEDX = (this.regEDX & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiMem0; this.backTrack.btiDH = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n};\n\n/**\n * op=0x5B (POP [E]BX)\n *\n * @this {CPUX86}\n */\nX86.opPOPBX = function()\n{\n this.regEBX = (this.regEBX & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiMem0; this.backTrack.btiBH = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n};\n\n/**\n * op=0x5C (POP [E]SP)\n *\n * @this {CPUX86}\n */\nX86.opPOPSP = function()\n{\n this.setSP((this.getSP() & ~this.maskData) | this.popWord());\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n};\n\n/**\n * op=0x5D (POP [E]BP)\n *\n * @this {CPUX86}\n */\nX86.opPOPBP = function()\n{\n this.regEBP = (this.regEBP & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiMem0; this.backTrack.btiBPHi = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n};\n\n/**\n * op=0x5E (POP [E]SI)\n *\n * @this {CPUX86}\n */\nX86.opPOPSI = function()\n{\n this.regESI = (this.regESI & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiMem0; this.backTrack.btiSIHi = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n};\n\n/**\n * op=0x5F (POP [E]DI)\n *\n * @this {CPUX86}\n */\nX86.opPOPDI = function()\n{\n this.regEDI = (this.regEDI & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiMem0; this.backTrack.btiDIHi = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n};\n\n/**\n * op=0x60 (PUSHA) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opPUSHA = function()\n{\n /*\n * Any operation that performs multiple stack modifications must snapshot regLSP first.\n */\n this.opLSP = this.regLSP;\n\n /*\n * TODO: regLSP needs to be pre-bounds-checked against regLSPLimitLow\n */\n var temp = this.getSP() & this.maskData;\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiAL; this.backTrack.btiMem1 = this.backTrack.btiAH;\n }\n this.pushWord(this.regEAX & this.maskData);\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiCL; this.backTrack.btiMem1 = this.backTrack.btiCH;\n }\n this.pushWord(this.regECX & this.maskData);\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiDL; this.backTrack.btiMem1 = this.backTrack.btiDH;\n }\n this.pushWord(this.regEDX & this.maskData);\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiBL; this.backTrack.btiMem1 = this.backTrack.btiBH;\n }\n this.pushWord(this.regEBX & this.maskData);\n this.pushWord(temp);\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiBPLo; this.backTrack.btiMem1 = this.backTrack.btiBPHi;\n }\n this.pushWord(this.regEBP & this.maskData);\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiSILo; this.backTrack.btiMem1 = this.backTrack.btiSIHi;\n }\n this.pushWord(this.regESI & this.maskData);\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiDILo; this.backTrack.btiMem1 = this.backTrack.btiDIHi;\n }\n this.pushWord(this.regEDI & this.maskData);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushAll;\n\n this.opLSP = X86.ADDR_INVALID;\n};\n\n/**\n * op=0x61 (POPA) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opPOPA = function()\n{\n /*\n * Any operation that performs multiple stack modifications must snapshot regLSP first.\n */\n this.opLSP = this.regLSP;\n\n this.regEDI = (this.regEDI & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiMem0; this.backTrack.btiDIHi = this.backTrack.btiMem1;\n }\n this.regESI = (this.regESI & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiMem0; this.backTrack.btiSIHi = this.backTrack.btiMem1;\n }\n this.regEBP = (this.regEBP & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiMem0; this.backTrack.btiBPHi = this.backTrack.btiMem1;\n }\n /*\n * TODO: regLSP needs to be pre-bounds-checked against regLSPLimit at the start\n */\n this.setSP(this.getSP() + this.sizeData);\n // this.regLSP += (I386? this.sizeData : 2);\n this.regEBX = (this.regEBX & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiMem0; this.backTrack.btiBH = this.backTrack.btiMem1;\n }\n this.regEDX = (this.regEDX & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiMem0; this.backTrack.btiDH = this.backTrack.btiMem1;\n }\n this.regECX = (this.regECX & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiMem0; this.backTrack.btiCH = this.backTrack.btiMem1;\n }\n this.regEAX = (this.regEAX & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopAll;\n\n this.opLSP = X86.ADDR_INVALID;\n};\n\n/**\n * op=0x62 (BOUND reg,word) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opBOUND = function()\n{\n this.decodeModRegWord.call(this, X86.fnBOUND);\n};\n\n/**\n * op=0x63 (ARPL word,reg) (80286 and up)\n *\n * @this {CPUX86}\n */\nX86.opARPL = function()\n{\n /*\n * ARPL is one of several protected-mode instructions that are meaningless and not allowed in either real-mode\n * or V86-mode; others include LAR, LSL, VERR and VERW. More meaningful but potentially harmful protected-mode\n * instructions that ARE allowed in real-mode but NOT in V86-mode include LIDT, LGDT, LMSW, CLTS, HLT, and\n * control register MOV instructions.\n *\n * ARPL is somewhat more noteworthy because enhanced-mode Windows (going back to at least Windows 3.00, and\n * possibly even the earliest versions of Windows/386) selected the ARPL opcode as a controlled means of exiting\n * V86-mode via the UD_FAULT exception. Windows would use the same ARPL for all controlled exits, using different\n * segment:offset pointers to the ARPL to differentiate them. ARPL was probably chosen because it could trigger\n * a UD_FAULT with a single byte (0x63); any subsequent address bytes would be irrelevant.\n *\n * Which is WHY we must perform the CPU mode tests below rather than in the fnARPL() worker; otherwise we could\n * generate additional (bogus) faults, based on the address of the first operand.\n *\n * TODO: You may have noticed that setProtMode() already swaps out a 0x0F opcode dispatch table for another based\n * on the mode, because none of the \"GRP6\" 0x0F opcodes (eg, SLDT, STR, LLDT, LTR, VERR and VERW) are allowed in\n * real-mode, and it was easy to swap all those handlers in/out with a single update. We've extended that particular\n * swap to include V86-mode as well, but we might want to consider swapping out more opcode handlers in a similar\n * fashion, instead of using these in-line mode tests.\n */\n if (!(this.regCR0 & X86.CR0.MSW.PE) || I386 && (this.regPS & X86.PS.VM)) {\n X86.opInvalid.call(this);\n return;\n }\n this.decodeModMemWord.call(this, X86.fnARPL);\n};\n\n/**\n * op=0x64 (FS:)\n *\n * @this {CPUX86}\n */\nX86.opFS = function()\n{\n this.opFlags |= X86.OPFLAG.SEG | X86.OPFLAG.NOINTR;\n this.segData = this.segStack = this.segFS;\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n};\n\n/**\n * op=0x65 (GS:)\n *\n * @this {CPUX86}\n */\nX86.opGS = function()\n{\n this.opFlags |= X86.OPFLAG.SEG | X86.OPFLAG.NOINTR;\n this.segData = this.segStack = this.segGS;\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n};\n\n/**\n * op=0x66 (OS:) (80386 and up)\n *\n * TODO: Review other effective operand-size criteria, cycle count, etc.\n *\n * @this {CPUX86}\n */\nX86.opOS = function()\n{\n if (I386) {\n /*\n * See opAS() for a discussion of multiple prefixes, which applies equally to both\n * operand-size and address-size prefixes.\n *\n * The simple fix here is to skip the bulk of the operation if the prefix is redundant.\n */\n this.opFlags |= X86.OPFLAG.DATASIZE;\n if (!(this.opPrefixes & X86.OPFLAG.DATASIZE)) {\n this.sizeData ^= 0x6; // that which is 2 shall become 4, and vice versa\n this.maskData ^= (0xffff0000|0); // that which is 0x0000ffff shall become 0xffffffff, and vice versa\n this.updateDataSize();\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n }\n};\n\n/**\n * op=0x67 (AS:) (80386 and up)\n *\n * TODO: Review other effective address-size criteria, cycle count, etc.\n *\n * @this {CPUX86}\n */\nX86.opAS = function()\n{\n if (I386) {\n /*\n * Live and learn: multiple address-size prefixes can and do occur on a single instruction,\n * and contrary to my original assumption that the prefixes act independently, they do not.\n * During Windows 95 SETUP, the following instruction is executed:\n *\n * 06AF:1B4D 67672E CS:\n * 06AF:1B50 FFA25A1B JMP [BP+SI+1B5A]\n *\n * which is in fact:\n *\n * 06AF:1B4D 67672E CS:\n * 06AF:1B50 FFA25A1B0000 JMP [EDX+00001B5A]\n *\n * The other interesting question is: why/how did this instruction get encoded that way?\n * All I can say is, there were no explicit prefixes in the source (BSG.ASM), so we'll chalk\n * it up to a glitch in MASM.\n *\n * The simple fix here is to skip the bulk of the operation if the prefix is redundant.\n */\n this.opFlags |= X86.OPFLAG.ADDRSIZE;\n if (!(this.opPrefixes & X86.OPFLAG.ADDRSIZE)) {\n this.sizeAddr ^= 0x06; // that which is 2 shall become 4, and vice versa\n this.maskAddr ^= (0xffff0000|0); // that which is 0x0000ffff shall become 0xffffffff, and vice versa\n this.updateAddrSize();\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n }\n};\n\n/**\n * op=0x68 (PUSH imm) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opPUSHn = function()\n{\n this.pushWord(this.getIPWord());\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x69 (IMUL reg,word,imm) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opIMULn = function()\n{\n this.decodeModRegWord.call(this, X86.fnIMULn);\n};\n\n/**\n * op=0x6A (PUSH imm8) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opPUSH8 = function()\n{\n if (BACKTRACK) this.backTrack.btiMem1 = 0;\n this.pushWord(this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x6B (IMUL reg,word,imm8) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opIMUL8 = function()\n{\n this.decodeModRegWord.call(this, X86.fnIMUL8);\n};\n\n/**\n * op=0x6C (INSB) (80186/80188 and up)\n *\n * NOTE: Segment overrides are ignored for this instruction, so we must use segES instead of segData.\n *\n * @this {CPUX86}\n */\nX86.opINSb = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n /*\n * NOTE: 5 + 4n is the cycle time for the 80286; the 80186/80188 has different values: 14 cycles for\n * an unrepeated INS, and 8 + 8n for a repeated INS. However, accurate cycle times for the 80186/80188 is\n * low priority.\n */\n var nCycles = 5;\n\n /*\n * The (normal) REP prefix, if used, is REPNZ (0xf2), but either one works....\n */\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n if (this.opPrefixes & X86.OPFLAG.REPEAT) nCycles = 4;\n }\n\n if (nReps--) {\n var port = this.regEDX & 0xffff;\n if (!this.checkIOPM(port, 1, true)) return;\n var b = this.bus.checkPortInputNotify(port, 1, this.regLIP - nDelta - 1);\n this.setSOByte(this.segES, this.regEDI & maskAddr, b);\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n if (BACKTRACK) this.backTrack.btiMem0 = this.backTrack.btiIO;\n this.regEDI = (this.regEDI & ~maskAddr) | ((this.regEDI + ((this.regPS & X86.PS.DF)? -1 : 1)) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n this.nStepCycles -= nCycles;\n if (nReps) {\n this.resetIP(-2);\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0x6D (INSW) (80186/80188 and up)\n *\n * NOTE: Segment overrides are ignored for this instruction, so we must use segDS instead of segData.\n *\n * @this {CPUX86}\n */\nX86.opINSw = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n /*\n * NOTE: 5 + 4n is the cycle time for the 80286; the 80186/80188 has different values: 14 cycles for\n * an unrepeated INS, and 8 + 8n for a repeated INS. However, accurate cycle times for the 80186/80188 is\n * low priority.\n */\n var nCycles = 5;\n\n /*\n * The (normal) REP prefix, if used, is REPNZ (0xf2), but either one works....\n */\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n if (this.opPrefixes & X86.OPFLAG.REPEAT) nCycles = 4;\n }\n if (nReps--) {\n var port = this.regEDX & 0xffff;\n if (!this.checkIOPM(port, this.sizeData, true)) return;\n var w = this.bus.checkPortInputNotify(port, this.sizeData, this.regLIP - nDelta - 1);\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiIO;\n this.backTrack.btiMem1 = this.backTrack.btiIO;\n }\n this.setSOWord(this.segES, this.regEDI & maskAddr, w);\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n this.regEDI = (this.regEDI & ~maskAddr) | ((this.regEDI + ((this.regPS & X86.PS.DF)? -this.sizeData : this.sizeData)) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n this.nStepCycles -= nCycles;\n if (nReps) {\n this.resetIP(-2);\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0x6E (OUTSB) (80186/80188 and up)\n *\n * NOTE: Segment overrides are ignored for this instruction, so we must use segDS instead of segData.\n *\n * @this {CPUX86}\n */\nX86.opOUTSb = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n /*\n * NOTE: 5 + 4n is the cycle time for the 80286; the 80186/80188 has different values: 14 cycles for\n * an unrepeated INS, and 8 + 8n for a repeated INS. TODO: Fix this someday.\n */\n var nCycles = 5;\n\n /*\n * The (normal) REP prefix, if used, is REPNZ (0xf2), but either one works....\n */\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n if (this.opPrefixes & X86.OPFLAG.REPEAT) nCycles = 4;\n }\n if (nReps--) {\n var port = this.regEDX & 0xffff;\n if (!this.checkIOPM(port, 1, false)) return;\n var b = this.getSOByte(this.segDS, this.regESI & maskAddr);\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n if (BACKTRACK) this.backTrack.btiIO = this.backTrack.btiMem0;\n this.bus.checkPortOutputNotify(port, 1, b, this.regLIP - nDelta - 1);\n this.regESI = (this.regESI & ~maskAddr) | ((this.regESI + ((this.regPS & X86.PS.DF)? -1 : 1)) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n this.nStepCycles -= nCycles;\n if (nReps) {\n this.resetIP(-2);\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0x6F (OUTSW) (80186/80188 and up)\n *\n * NOTE: Segment overrides are ignored for this instruction, so we must use segDS instead of segData.\n *\n * @this {CPUX86}\n */\nX86.opOUTSw = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n /*\n * NOTE: 5 + 4n is the cycle time for the 80286; the 80186/80188 has different values: 14 cycles for\n * an unrepeated INS, and 8 + 8n for a repeated INS. TODO: Fix this someday.\n */\n var nCycles = 5;\n\n /*\n * The (normal) REP prefix, if used, is REPNZ (0xf2), but either one works....\n */\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n if (this.opPrefixes & X86.OPFLAG.REPEAT) nCycles = 4;\n }\n if (nReps--) {\n var w = this.getSOWord(this.segDS, this.regESI & maskAddr);\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n var port = this.regEDX & 0xffff;\n if (!this.checkIOPM(port, this.sizeData, false)) return;\n if (BACKTRACK) {\n this.backTrack.btiIO = this.backTrack.btiMem0;\n this.backTrack.btiIO = this.backTrack.btiMem1;\n }\n this.bus.checkPortOutputNotify(port, this.sizeData, w, this.regLIP - nDelta - 1);\n this.regESI = (this.regESI & ~maskAddr) | ((this.regESI + ((this.regPS & X86.PS.DF)? -this.sizeData : this.sizeData)) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n this.nStepCycles -= nCycles;\n if (nReps) {\n this.resetIP(-2);\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0x70 (JO disp)\n *\n * @this {CPUX86}\n */\nX86.opJO = function()\n{\n var disp = this.getIPDisp();\n if (this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x71 (JNO disp)\n *\n * @this {CPUX86}\n */\nX86.opJNO = function()\n{\n var disp = this.getIPDisp();\n if (!this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x72 (JC disp, aka JB disp)\n *\n * @this {CPUX86}\n */\nX86.opJC = function()\n{\n var disp = this.getIPDisp();\n if (this.getCF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x73 (JNC disp, aka JAE disp)\n *\n * @this {CPUX86}\n */\nX86.opJNC = function()\n{\n var disp = this.getIPDisp();\n if (!this.getCF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x74 (JZ disp)\n *\n * @this {CPUX86}\n */\nX86.opJZ = function()\n{\n var disp = this.getIPDisp();\n if (this.getZF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x75 (JNZ disp)\n *\n * @this {CPUX86}\n */\nX86.opJNZ = function()\n{\n var disp = this.getIPDisp();\n if (!this.getZF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x76 (JBE disp)\n *\n * @this {CPUX86}\n */\nX86.opJBE = function()\n{\n var disp = this.getIPDisp();\n if (this.getCF() || this.getZF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x77 (JNBE disp, JA disp)\n *\n * @this {CPUX86}\n */\nX86.opJNBE = function()\n{\n var disp = this.getIPDisp();\n if (!this.getCF() && !this.getZF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x78 (JS disp)\n *\n * @this {CPUX86}\n */\nX86.opJS = function()\n{\n var disp = this.getIPDisp();\n if (this.getSF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x79 (JNS disp)\n *\n * @this {CPUX86}\n */\nX86.opJNS = function()\n{\n var disp = this.getIPDisp();\n if (!this.getSF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x7A (JP disp)\n *\n * @this {CPUX86}\n */\nX86.opJP = function()\n{\n var disp = this.getIPDisp();\n if (this.getPF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x7B (JNP disp)\n *\n * @this {CPUX86}\n */\nX86.opJNP = function()\n{\n var disp = this.getIPDisp();\n if (!this.getPF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x7C (JL disp)\n *\n * @this {CPUX86}\n */\nX86.opJL = function()\n{\n var disp = this.getIPDisp();\n if (!this.getSF() != !this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x7D (JNL disp, aka JGE disp)\n *\n * @this {CPUX86}\n */\nX86.opJNL = function()\n{\n var disp = this.getIPDisp();\n if (!this.getSF() == !this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x7E (JLE disp)\n *\n * @this {CPUX86}\n */\nX86.opJLE = function()\n{\n var disp = this.getIPDisp();\n if (this.getZF() || !this.getSF() != !this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x7F (JNLE disp, aka JG disp)\n *\n * @this {CPUX86}\n */\nX86.opJNLE = function()\n{\n var disp = this.getIPDisp();\n if (!this.getZF() && !this.getSF() == !this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x80/0x82 (GRP1 byte,imm8)\n *\n * @this {CPUX86}\n */\nX86.opGRP1b = function()\n{\n this.decodeModGrpByte.call(this, X86.aOpGrp1b, this.getIPByte);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? 1 : this.cycleCounts.nOpCyclesArithMID);\n};\n\n/**\n * op=0x81 (GRP1 word,imm)\n *\n * @this {CPUX86}\n */\nX86.opGRP1w = function()\n{\n this.decodeModGrpWord.call(this, X86.aOpGrp1w, this.getIPWord);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? 1 : this.cycleCounts.nOpCyclesArithMID);\n};\n\n/**\n * op=0x83 (GRP1 word,disp)\n *\n * WARNING: This passes getIPDisp() as the fnSrc parameter, which returns a 32-bit signed value,\n * so the worker functions (ie, the functions listed in aOpGrp1w[]) MUST mask their result with maskData,\n * to avoid setting bits beyond the current operand size.\n *\n * @this {CPUX86}\n */\nX86.opGRP1sw = function()\n{\n this.decodeModGrpWord.call(this, X86.aOpGrp1w, this.getIPDisp);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? 1 : this.cycleCounts.nOpCyclesArithMID);\n};\n\n/**\n * op=0x84 (TEST reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opTESTrb = function()\n{\n this.decodeModMemByte.call(this, X86.fnTESTb);\n};\n\n/**\n * op=0x85 (TEST reg,word)\n *\n * @this {CPUX86}\n */\nX86.opTESTrw = function()\n{\n this.decodeModMemWord.call(this, X86.fnTESTw);\n};\n\n/**\n * op=0x86 (XCHG reg,byte)\n *\n * NOTE: The XCHG instruction is unique in that both src and dst are both read and written;\n * see fnXCHGrb() for how we deal with this special case.\n *\n * @this {CPUX86}\n */\nX86.opXCHGrb = function()\n{\n /*\n * If the second operand is a register, then the ModRegByte decoder must use separate \"get\" and\n * \"set\" assignments, otherwise instructions like \"XCHG DH,DL\" will end up using a stale DL instead of\n * the updated DL.\n *\n * To be clear, a single assignment like this will fail:\n *\n * opModRegByteF2: function(fn)\n * {\n * this.regEDX = (this.regEDX & 0xff) | (fn.call(this, this.regEDX >> 8, this.regEDX & 0xff) << 8);\n * }\n *\n * which is why all affected decoders now use separate assignments; eg:\n *\n * opModRegByteF2: function(fn)\n * {\n * var b = fn.call(this, this.regEDX >> 8, this.regEDX & 0xff);\n * this.regEDX = (this.regEDX & 0xff) | (b << 8);\n * }\n */\n this.decodeModRegByte.call(this, X86.fnXCHGrb);\n};\n\n/**\n * op=0x87 (XCHG reg,word)\n *\n * NOTE: The XCHG instruction is unique in that both src and dst are both read and written;\n * see fnXCHGrw() for how we deal with this special case.\n *\n * @this {CPUX86}\n */\nX86.opXCHGrw = function()\n{\n this.decodeModRegWord.call(this, X86.fnXCHGrw);\n};\n\n/**\n * op=0x88 (MOV byte,reg)\n *\n * @this {CPUX86}\n */\nX86.opMOVmb = function()\n{\n /*\n * Like other MOV operations, the destination does not need to be read, just written.\n */\n this.opFlags |= X86.OPFLAG.NOREAD;\n this.decodeModMemByte.call(this, X86.fnMOV);\n};\n\n/**\n * op=0x89 (MOV word,reg)\n *\n * @this {CPUX86}\n */\nX86.opMOVmw = function()\n{\n /*\n * Like other MOV operations, the destination does not need to be read, just written.\n */\n this.opFlags |= X86.OPFLAG.NOREAD;\n this.decodeModMemWord.call(this, X86.fnMOV);\n};\n\n/**\n * op=0x8A (MOV reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opMOVrb = function()\n{\n this.decodeModRegByte.call(this, X86.fnMOV);\n};\n\n/**\n * op=0x8B (MOV reg,word)\n *\n * @this {CPUX86}\n */\nX86.opMOVrw = function()\n{\n this.decodeModRegWord.call(this, X86.fnMOV);\n};\n\n/**\n * op=0x8C (MOV word,sreg)\n *\n * NOTE: Since the ModRM decoders deal only with general-purpose registers, we rely on our helper\n * function (fnMOVwsr) to select the appropriate segment register and replace the decoder's src operand.\n *\n * @this {CPUX86}\n */\nX86.opMOVwsr = function()\n{\n /*\n * Like other MOV operations, the destination does not need to be read, just written.\n */\n this.opFlags |= X86.OPFLAG.NOREAD;\n this.decodeModMemWord.call(this, X86.fnMOVwsr);\n};\n\n/**\n * op=0x8D (LEA reg,word)\n *\n * @this {CPUX86}\n */\nX86.opLEA = function()\n{\n this.opFlags |= X86.OPFLAG.NOREAD;\n this.segData = this.segStack = this.segNULL; // we can't have the EA calculation, if any, \"polluted\" by segment arithmetic\n this.decodeModRegWord.call(this, X86.fnLEA);\n};\n\n/**\n * op=0x8E (MOV sreg,word)\n *\n * NOTE: Since the ModRM decoders deal only with general-purpose registers, we rely on our\n * helper function (fnMOVsrw) to make a note of which general-purpose register will be overwritten,\n * so that we can restore it after moving the updated value to the correct segment register.\n *\n * @this {CPUX86}\n */\nX86.opMOVsrw = function()\n{\n var sel;\n this.decodeModRegWord.call(this, X86.fnMOVsrw);\n switch ((this.bModRM >> 3) & 0x7) {\n case 0x0:\n sel = this.regEAX;\n this.regEAX = this.regXX;\n this.setES(sel);\n break;\n case 0x1:\n sel = this.regECX;\n this.regECX = this.regXX;\n this.setCS(sel);\n break;\n case 0x2:\n sel = this.regEDX;\n this.regEDX = this.regXX;\n this.setSS(sel);\n break;\n case 0x3:\n sel = this.regEBX;\n this.regEBX = this.regXX;\n this.setDS(sel);\n break;\n case 0x4:\n sel = this.getSP();\n this.setSP(this.regXX);\n if (I386 && this.model >= X86.MODEL_80386) {\n this.setFS(sel);\n } else {\n this.setES(sel);\n }\n break;\n case 0x5:\n sel = this.regEBP;\n this.regEBP = this.regXX;\n if (I386 && this.model >= X86.MODEL_80386) {\n this.setGS(sel);\n } else {\n this.setCS(sel);\n }\n break;\n case 0x6:\n sel = this.regESI;\n this.regESI = this.regXX;\n this.setSS(sel);\n break;\n case 0x7:\n sel = this.regEDI;\n this.regEDI = this.regXX;\n this.setDS(sel);\n break;\n }\n};\n\n/**\n * op=0x8F (POP word)\n *\n * @this {CPUX86}\n */\nX86.opPOPmw = function()\n{\n /*\n * Like other MOV operations, the destination does not need to be read, just written.\n */\n this.opFlags |= X86.OPFLAG.NOREAD;\n\n /*\n * If the word we're about to pop FROM the stack gets popped INTO a not-present page, this\n * instruction will not be restartable unless we snapshot regLSP first.\n */\n this.opLSP = this.regLSP;\n\n /*\n * A \"clever\" instruction like this:\n *\n * #0117:651C 67668F442408 POP DWORD [ESP+08]\n *\n * pops the DWORD from the top of the stack and places it at ESP+08, where ESP is the value\n * AFTER the pop, not before. We used to (incorrectly) pass \"popWord\" as the fnSrc parameter\n * below; we now pop the word first, saving it in regXX, and then pass \"helpSRCxx\" as fnSrc,\n * which simply returns the contents of regXX.\n *\n * Also, in case you're wondering, fnPUSHw() (in aOpGrp4w) is the complement to this instruction,\n * but it doesn't require a similar work-around, because a push from memory accesses that memory\n * BEFORE the push, which occurs through our normal ModRM processing.\n */\n this.regXX = this.popWord();\n\n this.decodeModGrpWord.call(this, X86.aOpGrpPOPw, X86.helpSRCxx);\n\n this.opLSP = X86.ADDR_INVALID;\n};\n\n/**\n * op=0x90 (NOP, aka XCHG AX,AX)\n *\n * @this {CPUX86}\n */\nX86.opNOP = function()\n{\n this.nStepCycles -= 3; // this form of XCHG takes 3 cycles on all CPUs\n};\n\n/**\n * op=0x91 (XCHG AX,CX)\n *\n * @this {CPUX86}\n */\nX86.opXCHGCX = function()\n{\n var temp = this.regEAX;\n this.regEAX = (I386? (this.regEAX & ~this.maskData) | (this.regECX & this.maskData) : this.regECX);\n this.regECX = (I386? (this.regECX & ~this.maskData) | (temp & this.maskData) : temp);\n if (BACKTRACK) {\n temp = this.backTrack.btiAL; this.backTrack.btiAL = this.backTrack.btiCL; this.backTrack.btiCL = temp;\n temp = this.backTrack.btiAH; this.backTrack.btiAH = this.backTrack.btiCH; this.backTrack.btiCH = temp;\n }\n this.nStepCycles -= 3; // this form of XCHG takes 3 cycles on all CPUs\n};\n\n/**\n * op=0x92 (XCHG AX,DX)\n *\n * @this {CPUX86}\n */\nX86.opXCHGDX = function()\n{\n var temp = this.regEAX;\n this.regEAX = (I386? (this.regEAX & ~this.maskData) | (this.regEDX & this.maskData) : this.regEDX);\n this.regEDX = (I386? (this.regEDX & ~this.maskData) | (temp & this.maskData) : temp);\n if (BACKTRACK) {\n temp = this.backTrack.btiAL; this.backTrack.btiAL = this.backTrack.btiDL; this.backTrack.btiDL = temp;\n temp = this.backTrack.btiAH; this.backTrack.btiAH = this.backTrack.btiDH; this.backTrack.btiDH = temp;\n }\n this.nStepCycles -= 3; // this form of XCHG takes 3 cycles on all CPUs\n};\n\n/**\n * op=0x93 (XCHG AX,BX)\n *\n * @this {CPUX86}\n */\nX86.opXCHGBX = function()\n{\n var temp = this.regEAX;\n this.regEAX = (I386? (this.regEAX & ~this.maskData) | (this.regEBX & this.maskData) : this.regEBX);\n this.regEBX = (I386? (this.regEBX & ~this.maskData) | (temp & this.maskData) : temp);\n if (BACKTRACK) {\n temp = this.backTrack.btiAL; this.backTrack.btiAL = this.backTrack.btiBL; this.backTrack.btiBL = temp;\n temp = this.backTrack.btiAH; this.backTrack.btiAH = this.backTrack.btiBH; this.backTrack.btiBH = temp;\n }\n this.nStepCycles -= 3; // this form of XCHG takes 3 cycles on all CPUs\n};\n\n/**\n * op=0x94 (XCHG AX,SP)\n *\n * @this {CPUX86}\n */\nX86.opXCHGSP = function()\n{\n var temp = this.regEAX;\n var regESP = this.getSP();\n this.regEAX = (I386? (this.regEAX & ~this.maskData) | (regESP & this.maskData) : regESP);\n this.setSP((I386? (regESP & ~this.maskData) | (temp & this.maskData) : temp));\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiAH = 0;\n this.nStepCycles -= 3; // this form of XCHG takes 3 cycles on all CPUs\n};\n\n/**\n * op=0x95 (XCHG AX,BP)\n *\n * @this {CPUX86}\n */\nX86.opXCHGBP = function()\n{\n var temp = this.regEAX;\n this.regEAX = (I386? (this.regEAX & ~this.maskData) | (this.regEBP & this.maskData) : this.regEBP);\n this.regEBP = (I386? (this.regEBP & ~this.maskData) | (temp & this.maskData) : temp);\n if (BACKTRACK) {\n temp = this.backTrack.btiAL; this.backTrack.btiAL = this.backTrack.btiBPLo; this.backTrack.btiBPLo = temp;\n temp = this.backTrack.btiAH; this.backTrack.btiAH = this.backTrack.btiBPHi; this.backTrack.btiBPHi = temp;\n }\n this.nStepCycles -= 3; // this form of XCHG takes 3 cycles on all CPUs\n};\n\n/**\n * op=0x96 (XCHG AX,SI)\n *\n * @this {CPUX86}\n */\nX86.opXCHGSI = function()\n{\n var temp = this.regEAX;\n this.regEAX = (I386? (this.regEAX & ~this.maskData) | (this.regESI & this.maskData) : this.regESI);\n this.regESI = (I386? (this.regESI & ~this.maskData) | (temp & this.maskData) : temp);\n if (BACKTRACK) {\n temp = this.backTrack.btiAL; this.backTrack.btiAL = this.backTrack.btiSILo; this.backTrack.btiSILo = temp;\n temp = this.backTrack.btiAH; this.backTrack.btiAH = this.backTrack.btiSIHi; this.backTrack.btiSIHi = temp;\n }\n this.nStepCycles -= 3; // this form of XCHG takes 3 cycles on all CPUs\n};\n\n/**\n * op=0x97 (XCHG AX,DI)\n *\n * @this {CPUX86}\n */\nX86.opXCHGDI = function()\n{\n var temp = this.regEAX;\n this.regEAX = (I386? (this.regEAX & ~this.maskData) | (this.regEDI & this.maskData) : this.regEDI);\n this.regEDI = (I386? (this.regEDI & ~this.maskData) | (temp & this.maskData) : temp);\n if (BACKTRACK) {\n temp = this.backTrack.btiAL; this.backTrack.btiAL = this.backTrack.btiDILo; this.backTrack.btiDILo = temp;\n temp = this.backTrack.btiAH; this.backTrack.btiAH = this.backTrack.btiDIHi; this.backTrack.btiDIHi = temp;\n }\n this.nStepCycles -= 3; // this form of XCHG takes 3 cycles on all CPUs\n};\n\n/**\n * op=0x98 (CBW/CWDE)\n *\n * NOTE: The 16-bit form (CBW) sign-extends AL into AX, whereas the 32-bit form (CWDE) sign-extends AX into EAX;\n * CWDE is similar to CWD, except that the destination is EAX rather than DX:AX.\n *\n * @this {CPUX86}\n */\nX86.opCBW = function()\n{\n if (this.sizeData == 2) { // CBW\n this.regEAX = (this.regEAX & ~0xffff) | (((this.regEAX << 24) >> 24) & 0xffff);\n if (BACKTRACK) this.backTrack.btiAH = this.backTrack.btiAL;\n }\n else { // CWDE\n this.regEAX = ((this.regEAX << 16) >> 16);\n }\n this.nStepCycles -= 2; // CBW takes 2 cycles on all CPUs through 80286\n};\n\n/**\n * op=0x99 (CWD/CDQ)\n *\n * NOTE: The 16-bit form (CWD) sign-extends AX, producing a 32-bit result in DX:AX, while the 32-bit form (CDQ)\n * sign-extends EAX, producing a 64-bit result in EDX:EAX.\n *\n * @this {CPUX86}\n */\nX86.opCWD = function()\n{\n if (this.sizeData == 2) { // CWD\n this.regEDX = (this.regEDX & ~0xffff) | ((this.regEAX & 0x8000)? 0xffff : 0);\n if (BACKTRACK) this.backTrack.btiDL = this.backTrack.btiDH = this.backTrack.btiAH;\n }\n else { // CDQ\n this.regEDX = (this.regEAX & (0x80000000|0))? -1 : 0;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesCWD;\n};\n\n/**\n * op=0x9A (CALL seg:off)\n *\n * @this {CPUX86}\n */\nX86.opCALLF = function()\n{\n X86.helpCALLF.call(this, this.getIPWord(), this.getIPShort());\n this.nStepCycles -= this.cycleCounts.nOpCyclesCallF;\n};\n\n/**\n * op=0x9B (WAIT)\n *\n * @this {CPUX86}\n */\nX86.opWAIT = function()\n{\n if (!this.fpu || !this.fpu.opWAIT()) {\n this.nStepCycles -= 3; // FPUX86.opWAIT() is required to charge some number of cycles if it returns true\n }\n};\n\n/**\n * op=0x9C (PUSHF/PUSHFD)\n *\n * @this {CPUX86}\n */\nX86.opPUSHF = function()\n{\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to V86-mode.\n */\n var regPS = this.getPS();\n if (I386) {\n if ((regPS & X86.PS.VM) && this.nIOPL < 3) {\n if (DEBUG) this.printMessage(\"PUSHF in v86-mode (IOPL < 3)\", this.bitsMessage, true);\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n /*\n * It doesn't matter whether this is PUSHF or PUSHFD: the VM and RF flags are never pushed, so\n * we should always clear them. NOTE: This contradicts what the \"INTEL 80386 PROGRAMMER'S REFERENCE\n * MANUAL 1986\" says on page 81 (which we assume is wrong):\n *\n * SYSTEMS FLAGS (INCLUDING THE IOPL FIELD, AND THE VM, RF, AND IF FLAGS) ARE PUSHED AND ARE\n * VISIBLE TO APPLICATIONS PROGRAMS. HOWEVER, WHEN AN APPLICATIONS PROGRAM POPS THE FLAGS,\n * THESE ITEMS ARE NOT CHANGED, REGARDLESS OF THE VALUES POPPED INTO THEM.\n *\n * This does, however, beg the question: how does code running in V86-mode detect that's in V86-mode\n * and not real-mode? By using the SMSW instruction and checking the PE (protected-mode enabled) bit.\n * The SMSW instruction returns a subset of the CR0 bits, and unlike the MOV reg,CR0 instruction, is\n * allowed in V86-mode. See fnSMSW() for more information.\n */\n regPS &= ~(X86.PS.VM | X86.PS.RF);\n }\n this.pushWord(regPS);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x9D (POPF/POPFD)\n *\n * @this {CPUX86}\n */\nX86.opPOPF = function()\n{\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to V86-mode.\n */\n if (I386 && (this.regPS & X86.PS.VM) && this.nIOPL < 3) {\n if (DEBUG) this.printMessage(\"POPF in v86-mode (IOPL < 3)\", this.bitsMessage, true);\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n /*\n * Regardless of mode, VM and RF (the only defined EFLAGS bit above bit 15) are never changed by POPFD.\n */\n var newPS = this.popWord();\n if (I386) newPS = (newPS & 0xffff) | (this.regPS & ~0xffff);\n this.setPS(newPS);\n /*\n * NOTE: I'm assuming that neither POPF nor IRET are required to set NOINTR like STI does.\n */\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n};\n\n/**\n * op=0x9E (SAHF)\n *\n * @this {CPUX86}\n */\nX86.opSAHF = function()\n{\n /*\n * NOTE: While it make seem more efficient to do this:\n *\n * this.setPS((this.getPS() & ~X86.PS_SAHF) | ((this.regEAX >> 8) & X86.PS_SAHF));\n *\n * getPS() forces any \"cached\" flags to be resolved first, and setPS() must do extra work above\n * and beyond setting the arithmetic and logical flags, so on balance, the code below may be more\n * efficient, and may also avoid unexpected side-effects of updating the entire PS register.\n */\n var ah = (this.regEAX >> 8) & 0xff;\n if (ah & X86.PS.CF) this.setCF(); else this.clearCF();\n if (ah & X86.PS.PF) this.setPF(); else this.clearPF();\n if (ah & X86.PS.AF) this.setAF(); else this.clearAF();\n if (ah & X86.PS.ZF) this.setZF(); else this.clearZF();\n if (ah & X86.PS.SF) this.setSF(); else this.clearSF();\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n\n};\n\n/**\n * op=0x9F (LAHF)\n *\n * @this {CPUX86}\n */\nX86.opLAHF = function()\n{\n this.regEAX = (this.regEAX & ~0xff00) | (this.getPS() & X86.PS_SAHF) << 8;\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xA0 (MOV AL,mem)\n *\n * @this {CPUX86}\n */\nX86.opMOVALm = function()\n{\n this.regEAX = (this.regEAX & ~0xff) | this.getSOByte(this.segData, this.getIPAddr());\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiMem0;\n this.nStepCycles -= this.cycleCounts.nOpCyclesMovAM;\n};\n\n/**\n * op=0xA1 (MOV [E]AX,mem)\n *\n * @this {CPUX86}\n */\nX86.opMOVAXm = function()\n{\n this.regEAX = (this.regEAX & ~this.maskData) | this.getSOWord(this.segData, this.getIPAddr());\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesMovAM;\n};\n\n/**\n * op=0xA2 (MOV mem,AL)\n *\n * @this {CPUX86}\n */\nX86.opMOVmAL = function()\n{\n if (BACKTRACK) this.backTrack.btiMem0 = this.backTrack.btiAL;\n /*\n * setSOByte() truncates the value as appropriate\n */\n this.setSOByte(this.segData, this.getIPAddr(), this.regEAX);\n this.nStepCycles -= this.cycleCounts.nOpCyclesMovMA;\n};\n\n/**\n * op=0xA3 (MOV mem,AX)\n *\n * @this {CPUX86}\n */\nX86.opMOVmAX = function()\n{\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiAL; this.backTrack.btiMem1 = this.backTrack.btiAH;\n }\n /*\n * setSOWord() truncates the value as appropriate\n */\n this.setSOWord(this.segData, this.getIPAddr(), this.regEAX);\n this.nStepCycles -= this.cycleCounts.nOpCyclesMovMA;\n};\n\n/**\n * op=0xA4 (MOVSB)\n *\n * @this {CPUX86}\n */\nX86.opMOVSb = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n var nCycles = this.cycleCounts.nOpCyclesMovS;\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n nCycles = this.cycleCounts.nOpCyclesMovSrn;\n if (!(this.opPrefixes & X86.OPFLAG.REPEAT)) this.nStepCycles -= this.cycleCounts.nOpCyclesMovSr0;\n }\n if (nReps--) {\n this.setSOByte(this.segES, this.regEDI & maskAddr, this.getSOByte(this.segData, this.regESI & maskAddr));\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n var nInc = ((this.regPS & X86.PS.DF)? -1 : 1);\n this.regESI = (this.regESI & ~maskAddr) | ((this.regESI + nInc) & maskAddr);\n this.regEDI = (this.regEDI & ~maskAddr) | ((this.regEDI + nInc) & maskAddr);\n this.nStepCycles -= nCycles;\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n if (nReps) {\n this.resetIP(((this.opPrefixes & X86.OPFLAG.SEG)? -3 : -2));\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0xA5 (MOVSW)\n *\n * @this {CPUX86}\n */\nX86.opMOVSw = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n var nCycles = this.cycleCounts.nOpCyclesMovS;\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n nCycles = this.cycleCounts.nOpCyclesMovSrn;\n if (!(this.opPrefixes & X86.OPFLAG.REPEAT)) this.nStepCycles -= this.cycleCounts.nOpCyclesMovSr0;\n }\n if (nReps--) {\n this.setSOWord(this.segES, this.regEDI & maskAddr, this.getSOWord(this.segData, this.regESI & maskAddr));\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n var nInc = ((this.regPS & X86.PS.DF)? -this.sizeData : this.sizeData);\n this.regESI = (this.regESI & ~maskAddr) | ((this.regESI + nInc) & maskAddr);\n this.regEDI = (this.regEDI & ~maskAddr) | ((this.regEDI + nInc) & maskAddr);\n this.nStepCycles -= nCycles;\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n if (nReps) {\n this.resetIP(((this.opPrefixes & X86.OPFLAG.SEG)? -3 : -2));\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0xA6 (CMPSB)\n *\n * @this {CPUX86}\n */\nX86.opCMPSb = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n var nCycles = this.cycleCounts.nOpCyclesCmpS;\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n nCycles = this.cycleCounts.nOpCyclesCmpSrn;\n if (!(this.opPrefixes & X86.OPFLAG.REPEAT)) this.nStepCycles -= this.cycleCounts.nOpCyclesCmpSr0;\n }\n if (nReps--) {\n var bDst = this.getEAByte(this.segData, this.regESI);\n var bSrc = this.getEAByte(this.segES, this.regEDI);\n this.regEAWrite = this.regEA; // TODO: Is this necessary?\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n X86.fnCMPb.call(this, bDst, bSrc);\n var nInc = ((this.regPS & X86.PS.DF)? -1 : 1);\n this.regESI = (this.regESI & ~maskAddr) | ((this.regESI + nInc) & maskAddr);\n this.regEDI = (this.regEDI & ~maskAddr) | ((this.regEDI + nInc) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n /*\n * NOTE: As long as we're calling fnCMPb(), all our cycle times must be reduced by nOpCyclesArithRM\n */\n this.nStepCycles -= nCycles - this.cycleCounts.nOpCyclesArithRM;\n /*\n * Repetition continues while ZF matches bit 0 of the REP prefix. getZF() returns 0x40 if ZF is\n * set, and OP_REPZ (which represents the REP prefix whose bit 0 is set) is 0x40 as well, so when those\n * two values are equal, we must continue.\n */\n if (nReps && this.getZF() == (this.opPrefixes & X86.OPFLAG.REPZ)) {\n this.resetIP(((this.opPrefixes & X86.OPFLAG.SEG)? -3 : -2));\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0xA7 (CMPSW)\n *\n * @this {CPUX86}\n */\nX86.opCMPSw = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n var nCycles = this.cycleCounts.nOpCyclesCmpS;\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n nCycles = this.cycleCounts.nOpCyclesCmpSrn;\n if (!(this.opPrefixes & X86.OPFLAG.REPEAT)) this.nStepCycles -= this.cycleCounts.nOpCyclesCmpSr0;\n }\n if (nReps--) {\n var wDst = this.getEAWord(this.segData, this.regESI & maskAddr);\n var wSrc = this.getEAWord(this.segES, this.regEDI & maskAddr);\n this.regEAWrite = this.regEA; // TODO: Is this necessary?\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n X86.fnCMPw.call(this, wDst, wSrc);\n var nInc = ((this.regPS & X86.PS.DF)? -this.sizeData : this.sizeData);\n this.regESI = (this.regESI & ~maskAddr) | ((this.regESI + nInc) & maskAddr);\n this.regEDI = (this.regEDI & ~maskAddr) | ((this.regEDI + nInc) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n /*\n * NOTE: As long as we're calling fnCMPw(), all our cycle times must be reduced by nOpCyclesArithRM\n */\n this.nStepCycles -= nCycles - this.cycleCounts.nOpCyclesArithRM;\n /*\n * Repetition continues while ZF matches bit 0 of the REP prefix. getZF() returns 0x40 if ZF is\n * set, and OP_REPZ (which represents the REP prefix whose bit 0 is set) is 0x40 as well, so when those\n * two values are equal, we must continue.\n */\n if (nReps && this.getZF() == (this.opPrefixes & X86.OPFLAG.REPZ)) {\n this.resetIP(((this.opPrefixes & X86.OPFLAG.SEG)? -3 : -2));\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0xA8 (TEST AL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opTESTALb = function()\n{\n this.setLogicResult(this.regEAX & this.getIPByte(), X86.RESULT.BYTE);\n this.nStepCycles -= this.cycleCounts.nOpCyclesAAA;\n};\n\n/**\n * op=0xA9 (TEST [E]AX,imm)\n *\n * @this {CPUX86}\n */\nX86.opTESTAX = function()\n{\n this.setLogicResult(this.regEAX & this.getIPWord(), this.typeData);\n this.nStepCycles -= this.cycleCounts.nOpCyclesAAA;\n};\n\n/**\n * op=0xAA (STOSB)\n *\n * NOTES: Segment overrides are ignored for this instruction, so we must use segES instead of segData.\n *\n * @this {CPUX86}\n */\nX86.opSTOSb = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n var nCycles = this.cycleCounts.nOpCyclesStoS;\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n nCycles = this.cycleCounts.nOpCyclesStoSrn;\n if (!(this.opPrefixes & X86.OPFLAG.REPEAT)) this.nStepCycles -= this.cycleCounts.nOpCyclesStoSr0;\n }\n if (nReps--) {\n this.setSOByte(this.segES, this.regEDI & maskAddr, this.regEAX);\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n if (BACKTRACK) this.backTrack.btiMem0 = this.backTrack.btiAL;\n\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n \n /*\n * Implement 80386 B1 Errata #7, to the extent that Windows 95 checked for it. This test doesn't\n * detect every possible variation (for example, the ADDRESS override on the next instruction, if\n * it exists, may not be the first prefix byte), but it's adequate for our limited purpose.\n *\n * Note that this code alters maskAddr AFTER it's been used to update ECX, because in the case\n * of STOS, the errata reportedly affects only EDI. The other instructions mentioned in the errata\n * trash different registers, so read the errata carefully.\n *\n * TODO: Extend this errata to STOSW, as well as MOVSB, MOVSW, INSB, and INSW. Also, verify the\n * extent to which this errata existed on earlier 80386 steppings (I'm currently assuming A0-B1).\n */\n if (this.stepping >= X86.STEPPING_80386_A0 && this.stepping <= X86.STEPPING_80386_B2) {\n if (!(this.opPrefixes & X86.OPFLAG.ADDRSIZE) != (this.getByte(this.regLIP) != X86.OPCODE.AS)) {\n maskAddr ^= (0xffff0000|0);\n }\n }\n this.regEDI = (this.regEDI & ~maskAddr) | ((this.regEDI + ((this.regPS & X86.PS.DF)? -1 : 1)) & maskAddr);\n\n this.nStepCycles -= nCycles;\n if (nReps) {\n this.resetIP(-2);\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0xAB (STOSW)\n *\n * NOTES: Segment overrides are ignored for this instruction, so we must use segES instead of segData.\n *\n * @this {CPUX86}\n */\nX86.opSTOSw = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n var nCycles = this.cycleCounts.nOpCyclesStoS;\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n nCycles = this.cycleCounts.nOpCyclesStoSrn;\n if (!(this.opPrefixes & X86.OPFLAG.REPEAT)) this.nStepCycles -= this.cycleCounts.nOpCyclesStoSr0;\n }\n if (nReps--) {\n this.setSOWord(this.segES, this.regEDI & maskAddr, this.regEAX);\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiAL; this.backTrack.btiMem1 = this.backTrack.btiAH;\n }\n this.regEDI = (this.regEDI & ~maskAddr) | ((this.regEDI + ((this.regPS & X86.PS.DF)? -this.sizeData : this.sizeData)) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n this.nStepCycles -= nCycles;\n if (nReps) {\n this.resetIP(-2);\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0xAC (LODSB)\n *\n * @this {CPUX86}\n */\nX86.opLODSb = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n var nCycles = this.cycleCounts.nOpCyclesLodS;\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n nCycles = this.cycleCounts.nOpCyclesLodSrn;\n if (!(this.opPrefixes & X86.OPFLAG.REPEAT)) this.nStepCycles -= this.cycleCounts.nOpCyclesLodSr0;\n }\n if (nReps--) {\n var b = this.getSOByte(this.segData, this.regESI & maskAddr);\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n this.regEAX = (this.regEAX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiMem0;\n this.regESI = (this.regESI & ~maskAddr) | ((this.regESI + ((this.regPS & X86.PS.DF)? -1 : 1)) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n this.nStepCycles -= nCycles;\n if (nReps) {\n this.resetIP(((this.opPrefixes & X86.OPFLAG.SEG)? -3 : -2));\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0xAD (LODSW)\n *\n * @this {CPUX86}\n */\nX86.opLODSw = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n var nCycles = this.cycleCounts.nOpCyclesLodS;\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n nCycles = this.cycleCounts.nOpCyclesLodSrn;\n if (!(this.opPrefixes & X86.OPFLAG.REPEAT)) this.nStepCycles -= this.cycleCounts.nOpCyclesLodSr0;\n }\n if (nReps--) {\n var w = this.getSOWord(this.segData, this.regESI & maskAddr);\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n this.regEAX = (this.regEAX & ~this.maskData) | w;\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.regESI = (this.regESI & ~maskAddr) | ((this.regESI + ((this.regPS & X86.PS.DF)? -this.sizeData : this.sizeData)) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n this.nStepCycles -= nCycles;\n if (nReps) {\n this.resetIP(((this.opPrefixes & X86.OPFLAG.SEG)? -3 : -2));\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0xAE (SCASB)\n *\n * @this {CPUX86}\n */\nX86.opSCASb = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n var nCycles = this.cycleCounts.nOpCyclesScaS;\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n nCycles = this.cycleCounts.nOpCyclesScaSrn;\n if (!(this.opPrefixes & X86.OPFLAG.REPEAT)) this.nStepCycles -= this.cycleCounts.nOpCyclesScaSr0;\n }\n if (nReps--) {\n var bDst = this.regEAX & 0xff;\n var bSrc = this.getEAByte(this.segES, this.regEDI);\n this.regEAWrite = this.regEA; // TODO: Is this necessary?\n X86.fnCMPb.call(this, bDst, bSrc);\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n this.regEDI = (this.regEDI & ~maskAddr) | ((this.regEDI + ((this.regPS & X86.PS.DF)? -1 : 1)) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n /*\n * NOTE: As long as we're calling fnCMPb(), all our cycle times must be reduced by nOpCyclesArithRM\n */\n this.nStepCycles -= nCycles - this.cycleCounts.nOpCyclesArithRM;\n /*\n * Repetition continues while ZF matches bit 0 of the REP prefix. getZF() returns 0x40 if ZF is\n * set, and OP_REPZ (which represents the REP prefix whose bit 0 is set) is 0x40 as well, so when those\n * two values are equal, we must continue.\n */\n if (nReps && this.getZF() == (this.opPrefixes & X86.OPFLAG.REPZ)) {\n this.resetIP(-2);\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0xAF (SCASW)\n *\n * @this {CPUX86}\n */\nX86.opSCASw = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n var nCycles = this.cycleCounts.nOpCyclesScaS;\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n nCycles = this.cycleCounts.nOpCyclesScaSrn;\n if (!(this.opPrefixes & X86.OPFLAG.REPEAT)) this.nStepCycles -= this.cycleCounts.nOpCyclesScaSr0;\n }\n if (nReps--) {\n var wDst = this.regEAX & this.maskData;\n var wSrc = this.getEAWord(this.segES, this.regEDI & maskAddr);\n this.regEAWrite = this.regEA; // TODO: Is this necessary?\n X86.fnCMPw.call(this, wDst, wSrc);\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n this.regEDI = (this.regEDI & ~maskAddr) | ((this.regEDI + ((this.regPS & X86.PS.DF)? -this.sizeData : this.sizeData)) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n /*\n * NOTE: As long as we're calling fnCMPw(), all our cycle times must be reduced by nOpCyclesArithRM\n */\n this.nStepCycles -= nCycles - this.cycleCounts.nOpCyclesArithRM;\n /*\n * Repetition continues while ZF matches bit 0 of the REP prefix. getZF() returns 0x40 if ZF is\n * set, and OP_REPZ (which represents the REP prefix whose bit 0 is set) is 0x40 as well, so when those\n * two values are equal, we must continue.\n */\n if (nReps && this.getZF() == (this.opPrefixes & X86.OPFLAG.REPZ)) {\n this.resetIP(-2);\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0xB0 (MOV AL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opMOVALb = function()\n{\n this.regEAX = (this.regEAX & ~0xff) | this.getIPByte();\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiMem0;\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xB1 (MOV CL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opMOVCLb = function()\n{\n this.regECX = (this.regECX & ~0xff) | this.getIPByte();\n if (BACKTRACK) this.backTrack.btiCL = this.backTrack.btiMem0;\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xB2 (MOV DL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opMOVDLb = function()\n{\n this.regEDX = (this.regEDX & ~0xff) | this.getIPByte();\n if (BACKTRACK) this.backTrack.btiDL = this.backTrack.btiMem0;\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xB3 (MOV BL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opMOVBLb = function()\n{\n this.regEBX = (this.regEBX & ~0xff) | this.getIPByte();\n if (BACKTRACK) this.backTrack.btiBL = this.backTrack.btiMem0;\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xB4 (MOV AH,imm8)\n *\n * @this {CPUX86}\n */\nX86.opMOVAHb = function()\n{\n this.regEAX = (this.regEAX & ~0xff00) | (this.getIPByte() << 8);\n if (BACKTRACK) this.backTrack.btiAH = this.backTrack.btiMem0;\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xB5 (MOV CH,imm8)\n *\n * @this {CPUX86}\n */\nX86.opMOVCHb = function()\n{\n this.regECX = (this.regECX & ~0xff00) | (this.getIPByte() << 8);\n if (BACKTRACK) this.backTrack.btiCH = this.backTrack.btiMem0;\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xB6 (MOV DH,imm8)\n *\n * @this {CPUX86}\n */\nX86.opMOVDHb = function()\n{\n this.regEDX = (this.regEDX & ~0xff00) | (this.getIPByte() << 8);\n if (BACKTRACK) this.backTrack.btiDH = this.backTrack.btiMem0;\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xB7 (MOV BH,imm8)\n *\n * @this {CPUX86}\n */\nX86.opMOVBHb = function()\n{\n this.regEBX = (this.regEBX & ~0xff00) | (this.getIPByte() << 8);\n if (BACKTRACK) this.backTrack.btiBH = this.backTrack.btiMem0;\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xB8 (MOV [E]AX,imm)\n *\n * @this {CPUX86}\n */\nX86.opMOVAX = function()\n{\n this.regEAX = (this.regEAX & ~this.maskData) | this.getIPWord();\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xB9 (MOV [E]CX,imm)\n *\n * @this {CPUX86}\n */\nX86.opMOVCX = function()\n{\n this.regECX = (this.regECX & ~this.maskData) | this.getIPWord();\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiMem0; this.backTrack.btiCH = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xBA (MOV [E]DX,imm)\n *\n * @this {CPUX86}\n */\nX86.opMOVDX = function()\n{\n this.regEDX = (this.regEDX & ~this.maskData) | this.getIPWord();\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiMem0; this.backTrack.btiDH = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xBB (MOV [E]BX,imm)\n *\n * @this {CPUX86}\n */\nX86.opMOVBX = function()\n{\n this.regEBX = (this.regEBX & ~this.maskData) | this.getIPWord();\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiMem0; this.backTrack.btiBH = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xBC (MOV [E]SP,imm)\n *\n * @this {CPUX86}\n */\nX86.opMOVSP = function()\n{\n this.setSP((this.getSP() & ~this.maskData) | this.getIPWord());\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xBD (MOV [E]BP,imm)\n *\n * @this {CPUX86}\n */\nX86.opMOVBP = function()\n{\n this.regEBP = (this.regEBP & ~this.maskData) | this.getIPWord();\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiMem0; this.backTrack.btiBPHi = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xBE (MOV [E]SI,imm)\n *\n * @this {CPUX86}\n */\nX86.opMOVSI = function()\n{\n this.regESI = (this.regESI & ~this.maskData) | this.getIPWord();\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiMem0; this.backTrack.btiSIHi = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xBF (MOV [E]DI,imm)\n *\n * @this {CPUX86}\n */\nX86.opMOVDI = function()\n{\n this.regEDI = (this.regEDI & ~this.maskData) | this.getIPWord();\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiMem0; this.backTrack.btiDIHi = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xC0 (GRP2 byte,imm8) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opGRP2bn = function()\n{\n this.decodeModGrpByte.call(this, X86.aOpGrp2b, X86.helpSRCByte);\n};\n\n/**\n * op=0xC1 (GRP2 word,imm) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opGRP2wn = function()\n{\n this.decodeModGrpWord.call(this, this.sizeData == 2? X86.aOpGrp2w : X86.aOpGrp2d, X86.helpSRCByte);\n};\n\n/**\n * op=0xC2 (RET n)\n *\n * @this {CPUX86}\n */\nX86.opRETn = function()\n{\n var n = this.getIPShort();\n var newIP = this.popWord();\n this.setIP(newIP);\n if (n) this.setSP(this.getSP() + n); // TODO: optimize\n this.nStepCycles -= this.cycleCounts.nOpCyclesRetn;\n};\n\n/**\n * op=0xC3 (RET)\n *\n * @this {CPUX86}\n */\nX86.opRET = function()\n{\n var newIP = this.popWord();\n this.setIP(newIP);\n this.nStepCycles -= this.cycleCounts.nOpCyclesRet;\n};\n\n/**\n * op=0xC4 (LES reg,word)\n *\n * This is like a \"MOV reg,rm\" operation, but it also loads ES from the next word.\n *\n * @this {CPUX86}\n */\nX86.opLES = function()\n{\n this.decodeModRegWord.call(this, X86.fnLES);\n};\n\n/**\n * op=0xC5 (LDS reg,word)\n *\n * This is like a \"MOV reg,rm\" operation, but it also loads DS from the next word.\n *\n * @this {CPUX86}\n */\nX86.opLDS = function()\n{\n this.decodeModRegWord.call(this, X86.fnLDS);\n};\n\n/**\n * op=0xC6 (MOV byte,imm8)\n *\n * @this {CPUX86}\n */\nX86.opMOVb = function()\n{\n /*\n * Like other MOV operations, the destination does not need to be read, just written.\n */\n this.opFlags |= X86.OPFLAG.NOREAD;\n this.decodeModGrpByte.call(this, X86.aOpGrpMOVn, this.getIPByte);\n};\n\n/**\n * op=0xC7 (MOV word,imm)\n *\n * @this {CPUX86}\n */\nX86.opMOVw = function()\n{\n /*\n * Like other MOV operations, the destination does not need to be read, just written.\n */\n this.opFlags |= X86.OPFLAG.NOREAD;\n this.decodeModGrpWord.call(this, X86.aOpGrpMOVn, this.getIPWord);\n};\n\n/**\n * op=0xC8 (ENTER imm16,imm8) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opENTER = function()\n{\n /*\n * Any operation that performs multiple stack modifications must snapshot regLSP first.\n */\n this.opLSP = this.regLSP;\n\n var wLocal = this.getIPShort();\n var bLevel = this.getIPByte() & 0x1f;\n /*\n * NOTE: 11 is the minimum cycle time for the 80286; the 80186/80188 has different cycle times: 15, 25 and\n * 22 + 16 * (bLevel - 1) for bLevel 0, 1 and > 1, respectively. TODO: Fix this someday.\n */\n this.nStepCycles -= 11;\n this.pushWord(this.regEBP);\n var wFrame = this.getSP() & this.maskData;\n if (bLevel > 0) {\n this.nStepCycles -= (bLevel << 2) + (bLevel > 1? 1 : 0);\n while (--bLevel) {\n this.regEBP = (this.regEBP & ~this.maskData) | ((this.regEBP - this.sizeData) & this.maskData);\n this.pushWord(this.getSOWord(this.segSS, this.regEBP & this.maskData));\n }\n this.pushWord(wFrame);\n }\n this.regEBP = (this.regEBP & ~this.maskData) | wFrame;\n this.setSP((this.getSP() & ~this.segSS.maskAddr) | ((this.getSP() - wLocal) & this.segSS.maskAddr));\n\n this.opLSP = X86.ADDR_INVALID;\n};\n\n/**\n * op=0xC9 (LEAVE) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opLEAVE = function()\n{\n /*\n * Any operation that performs multiple stack modifications must snapshot regLSP first.\n */\n this.opLSP = this.regLSP;\n\n this.setSP((this.getSP() & ~this.segSS.maskAddr) | (this.regEBP & this.segSS.maskAddr));\n\n this.regEBP = (this.regEBP & ~this.maskData) | (this.popWord() & this.maskData);\n /*\n * NOTE: 5 is the cycle time for the 80286; the 80186/80188 has a cycle time of 8. TODO: Fix this someday.\n */\n this.nStepCycles -= 5;\n\n this.opLSP = X86.ADDR_INVALID;\n};\n\n/**\n * op=0xCA (RETF n)\n *\n * @this {CPUX86}\n */\nX86.opRETFn = function()\n{\n X86.helpRETF.call(this, this.getIPShort());\n this.nStepCycles -= this.cycleCounts.nOpCyclesRetFn;\n};\n\n/**\n * op=0xCB (RETF)\n *\n * @this {CPUX86}\n */\nX86.opRETF = function()\n{\n X86.helpRETF.call(this, 0);\n this.nStepCycles -= this.cycleCounts.nOpCyclesRetF;\n};\n\n/**\n * op=0xCC (INT 3)\n *\n * @this {CPUX86}\n */\nX86.opINT3 = function()\n{\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to V86-mode.\n */\n if (I386 && (this.regPS & X86.PS.VM) && this.nIOPL < 3) {\n if (DEBUG) this.printMessage(\"INT 0x03 in v86-mode (IOPL < 3)\", this.bitsMessage, true);\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n /*\n * Because INT3 is a trap, not a fault, we must use helpTrap() rather than helpFault(). Unfortunately, that\n * means you can't rely on the Debugger logic instead helpFault() to conditionally stop execution on an INT3,\n * so I've changed the Debugger's checkBreakpoint() function to stop execution on INT3 whenever both the\n * INT and HALT message bits are set; a simple \"g\" command allows you to continue.\n */\n X86.helpTrap.call(this, X86.EXCEPTION.BP_TRAP, this.cycleCounts.nOpCyclesInt3D);\n};\n\n/**\n * op=0xCD (INT n)\n *\n * @this {CPUX86}\n */\nX86.opINTn = function()\n{\n var nInt = this.getIPByte();\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to V86-mode.\n */\n if (I386 && (this.regPS & X86.PS.VM) && this.nIOPL < 3) {\n if (DEBUG && this.messageEnabled()) this.printMessage(\"INT \" + Str.toHexByte(nInt) + \" in v86-mode (IOPL < 3)\", true, true);\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n /*\n * checkIntNotify() checks for any notification handlers registered via addIntNotify(), calls them,\n * and returns false ONLY if a notification handler returned false (ie, requesting the interrupt be skipped).\n */\n if (this.checkIntNotify(nInt)) {\n X86.helpTrap.call(this, nInt, 0);\n return;\n }\n this.nStepCycles--; // we don't need to assess the full cost of nOpCyclesInt, but we need to assess something...\n};\n\n/**\n * op=0xCE (INTO: INT 4 if OF set)\n *\n * @this {CPUX86}\n */\nX86.opINTO = function()\n{\n if (this.getOF()) {\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to V86-mode.\n */\n if (I386 && (this.regPS & X86.PS.VM) && this.nIOPL < 3) {\n if (DEBUG) this.printMessage(\"INTO in v86-mode (IOPL < 3)\", this.bitsMessage, true);\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n X86.helpTrap.call(this, X86.EXCEPTION.OF_TRAP, this.cycleCounts.nOpCyclesIntOD);\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesIntOFall;\n};\n\n/**\n * op=0xCF (IRET)\n *\n * @this {CPUX86}\n */\nX86.opIRET = function()\n{\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to V86-mode.\n */\n if (I386 && (this.regPS & X86.PS.VM) && this.nIOPL < 3) {\n if (DEBUG) this.printMessage(\"IRET in v86-mode (IOPL < 3)\", this.bitsMessage, true);\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n X86.helpIRET.call(this);\n};\n\n/**\n * op=0xD0 (GRP2 byte,1)\n *\n * @this {CPUX86}\n */\nX86.opGRP2b1 = function()\n{\n this.decodeModGrpByte.call(this, X86.aOpGrp2b, X86.helpSRC1);\n};\n\n/**\n * op=0xD1 (GRP2 word,1)\n *\n * @this {CPUX86}\n */\nX86.opGRP2w1 = function()\n{\n this.decodeModGrpWord.call(this, this.sizeData == 2? X86.aOpGrp2w : X86.aOpGrp2d, X86.helpSRC1);\n};\n\n/**\n * op=0xD2 (GRP2 byte,CL)\n *\n * @this {CPUX86}\n */\nX86.opGRP2bCL = function()\n{\n this.decodeModGrpByte.call(this, X86.aOpGrp2b, X86.helpSRCCL);\n};\n\n/**\n * op=0xD3 (GRP2 word,CL)\n *\n * @this {CPUX86}\n */\nX86.opGRP2wCL = function()\n{\n this.decodeModGrpWord.call(this, this.sizeData == 2? X86.aOpGrp2w : X86.aOpGrp2d, X86.helpSRCCL);\n};\n\n/**\n * op=0xD4 0x0A (AAM)\n *\n * From \"The 8086 Book\":\n *\n * 1. Divide AL by 0x0A; store the quotient in AH and the remainder in AL\n * 2. Set PF, SF, and ZF based on the AL register (CF, OF, and AF are undefined)\n *\n * From \"Undocumented Opcodes\" (http://www.rcollins.org/secrets/opcodes/AAM.html):\n *\n * AAM is shown as a two byte encoding used to divide AL by 10, putting the quotient in AH, and the remainder in AL.\n * However, AAM is listed in the op code map as a single byte instruction. This leads one to wonder why a two-byte\n * opcode is listed in the single-byte opcode map. In reality, the second byte is an undocumented operand to AAM.\n * The operand is the divisor. In its documented incarnation, AAM is encoded as D4 0A. The operand 0A is the divisor.\n * This divisor can be changed to any value between 0 and FF.\n *\n * Using AAM in this manner is useful -- as it extends the CPU instruction set to include a DIV IMM8 instruction\n * that is not available from any other form of the DIV instruction. The extended form of the AAM instruction is also\n * useful because it sets the flags register according to the results, unlike the DIV or IDIV instruction.\n *\n * According to Intel documentation, SF, ZF, and PF flags are set according to the result, while OF, AF, and CF\n * are undefined. However, if AAM were used strictly as documented, then the Sign Flag (SF) could not be set under\n * any circumstances, since anything divided by 10 will leave a remainder between 0 and 9. Obviously the remainder\n * could never be between 128 and 255 (or -1 and -128 if you prefer) if used only as documented. Since AAM divides\n * an 8 bit number by another 8-bit number, a carry or overflow could never occur. Therefore CF and OF always=0.\n * Intel claims they are undefined, but my observations are consistent with my theory.\n *\n * Contrary to documentation, AAM will generate exceptions in real mode, protected mode, and V86 mode. AAM can only\n * generate Exception 0 -- divide by 0.\n *\n * Finally, in the Pentium User's Manual, this heretofore undocumented form of AMM is described. Intel says:\n *\n * Note: imm8 has the value of the instruction's second byte. The second byte under normally assembly [sic] of\n * this instruction will be 0A, however, explicit modification of this byte will result in the operation described\n * above and may alter results.\n *\n * This instruction exists in this form on all Intel x86 processors. See the file [AAM.ASM](/docs/x86/ops/AAM/AAM.ASM)\n * for diagnostics source code for this instruction.\n *\n * @this {CPUX86}\n */\nX86.opAAM = function()\n{\n var b = this.getIPByte();\n if (!b) {\n X86.helpDIVOverflow.call(this);\n return;\n }\n var AL = this.regEAX & 0xff;\n this.regEAX = (this.regEAX & ~0xffff) | ((AL / b) << 8) | (AL % b);\n /*\n * setLogicResult() is perfect, because it ensures that CF and OF are cleared as well (see above for why).\n */\n this.setLogicResult(this.regEAX, X86.RESULT.BYTE);\n this.nStepCycles -= this.cycleCounts.nOpCyclesAAM;\n};\n\n/**\n * op=0xD5 (AAD)\n *\n * From \"The 8086 Book\":\n *\n * 1. Multiply AH by 0x0A, add AH to AL, and store 0x00 in AH\n * 2. Set PF, SF, and ZF based on the AL register (CF, OF, and AF are undefined)\n *\n * From \"Undocumented Opcodes\" (http://www.rcollins.org/secrets/opcodes/AAD.html):\n *\n * This instruction is the multiplication counterpart to AAM. As is the case with AAM, AAD uses the second\n * byte as an operand. This operand is the multiplicand for AAD. Like AAM, AAD provides a way to execute a MUL\n * IMM8 that is unavailable through any other means in the CPU.\n *\n * Unlike MUL, or IMUL, AAD sets all of the CPU status flags according to the result. Intel states that the\n * Overflow Flag (OF), Auxiliary carry Flag (AF), and Carry Flag (CF) are undefined. This assertion is incorrect.\n * These flags are fully defined, and are set consistently with respect to any other integer operations.\n *\n * And again, like AMM, beginning with the Pentium, Intel has finally acknowledged the existence of the second\n * byte of this instruction as its operand. Intel says:\n *\n * Note: imm8 has the value of the instruction's second byte. The second byte under normally assembly [sic]\n * of this instruction will be 0A, however, explicit modification of this byte will result in the operation\n * described above and may alter results.\n *\n * This instruction exists in this form on all Intel x86 processors. See the file [AAD.ASM](/docs/x86/ops/AAD/AAD.ASM)\n * for diagnostics source code for this instruction.\n *\n * TODO: Confirm on real hardware that flags reflect the result of the final addition (ie, that the result of the\n * intermediate multiplication is irrelevant); it also might be nice to confirm that an operand override has no effect.\n *\n * @this {CPUX86}\n */\nX86.opAAD = function()\n{\n var dst = (this.regEAX & 0xff);\n var src = (((this.regEAX >> 8) & 0xff) * this.getIPByte())|0;\n var result = (dst + src)|0;\n this.regEAX = (this.regEAX & ~0xffff) | (result & 0xff);\n this.setArithResult(dst, src, result, X86.RESULT.BYTE | X86.RESULT.ALL);\n this.nStepCycles -= this.cycleCounts.nOpCyclesAAD;\n};\n\n/**\n * op=0xD6 (SALC aka SETALC) (undocumented until Pentium Pro)\n *\n * Sets AL to 0xFF if CF=1, 0x00 otherwise; no flags are affected (similar to SBB AL,AL, but without side-effects)\n *\n * WARNING: I have no idea how many clocks this instruction originally required, so for now, I'm going with a minimum of 2.\n *\n * @this {CPUX86}\n */\nX86.opSALC = function()\n{\n this.regEAX = (this.regEAX & ~0xff) | (this.getCF()? 0xFF : 0);\n this.nStepCycles -= 2;\n};\n\n/**\n * op=0xD7 (XLAT)\n *\n * @this {CPUX86}\n */\nX86.opXLAT = function()\n{\n /*\n * TODO: Verify whether XLAT wraps its address calculation....\n */\n this.regEAX = (this.regEAX & ~0xff) | this.getEAByte(this.segData, (this.regEBX + (this.regEAX & 0xff)));\n this.nStepCycles -= this.cycleCounts.nOpCyclesXLAT;\n};\n\n/**\n * opESC()\n *\n * @this {CPUX86}\n * @param {number} bOpcode\n */\nX86.opESC = function(bOpcode)\n{\n this.bOpcode = bOpcode;\n this.decodeModRegWord.call(this, X86.fnESC);\n};\n\n/**\n * op=0xD8 (ESC0)\n *\n * @this {CPUX86}\n */\nX86.opESC0 = function()\n{\n X86.opESC.call(this, X86.OPCODE.ESC0);\n};\n\n/**\n * op=0xD9 (ESC1)\n *\n * @this {CPUX86}\n */\nX86.opESC1 = function()\n{\n X86.opESC.call(this, X86.OPCODE.ESC1);\n};\n\n/**\n * op=0xDA (ESC2)\n *\n * @this {CPUX86}\n */\nX86.opESC2 = function()\n{\n X86.opESC.call(this, X86.OPCODE.ESC2);\n};\n\n/**\n * op=0xDB (ESC3)\n *\n * @this {CPUX86}\n */\nX86.opESC3 = function()\n{\n X86.opESC.call(this, X86.OPCODE.ESC3);\n};\n\n/**\n * op=0xDC (ESC4)\n *\n * @this {CPUX86}\n */\nX86.opESC4 = function()\n{\n X86.opESC.call(this, X86.OPCODE.ESC4);\n};\n\n/**\n * op=0xDD (ESC5)\n *\n * @this {CPUX86}\n */\nX86.opESC5 = function()\n{\n X86.opESC.call(this, X86.OPCODE.ESC5);\n};\n\n/**\n * op=0xDE (ESC6)\n *\n * @this {CPUX86}\n */\nX86.opESC6 = function()\n{\n X86.opESC.call(this, X86.OPCODE.ESC6);\n};\n\n/**\n * op=0xDF (ESC7)\n *\n * @this {CPUX86}\n */\nX86.opESC7 = function()\n{\n X86.opESC.call(this, X86.OPCODE.ESC7);\n};\n\n/**\n * op=0xE0 (LOOPNZ disp)\n *\n * NOTE: All the instructions in this group (LOOPNZ, LOOPZ, LOOP, and JCXZ) actually\n * rely on the ADDRESS override setting for determining whether CX or ECX will be used,\n * even though it seems counter-intuitive; ditto for the REP prefix.\n *\n * @this {CPUX86}\n */\nX86.opLOOPNZ = function()\n{\n var disp = this.getIPDisp();\n var n = (this.regECX - 1) & this.maskAddr;\n this.regECX = (this.regECX & ~this.maskAddr) | n;\n if (n && !this.getZF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesLoopNZ;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLoopFall;\n};\n\n/**\n * op=0xE1 (LOOPZ disp)\n *\n * NOTE: All the instructions in this group (LOOPNZ, LOOPZ, LOOP, and JCXZ) actually\n * rely on the ADDRESS override setting for determining whether CX or ECX will be used,\n * even though it seems counter-intuitive; ditto for the REP prefix.\n *\n * @this {CPUX86}\n */\nX86.opLOOPZ = function()\n{\n var disp = this.getIPDisp();\n var n = (this.regECX - 1) & this.maskAddr;\n this.regECX = (this.regECX & ~this.maskAddr) | n;\n if (n && this.getZF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesLoopZ;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLoopZFall;\n};\n\n/**\n * op=0xE2 (LOOP disp)\n *\n * NOTE: All the instructions in this group (LOOPNZ, LOOPZ, LOOP, and JCXZ) actually\n * rely on the ADDRESS override setting for determining whether CX or ECX will be used,\n * even though it seems counter-intuitive; ditto for the REP prefix.\n *\n * @this {CPUX86}\n */\nX86.opLOOP = function()\n{\n var disp = this.getIPDisp();\n var n = (this.regECX - 1) & this.maskAddr;\n this.regECX = (this.regECX & ~this.maskAddr) | n;\n if (n) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesLoop;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLoopFall;\n};\n\n/**\n * op=0xE3 (JCXZ/JECXZ disp)\n *\n * NOTE: All the instructions in this group (LOOPNZ, LOOPZ, LOOP, and JCXZ) actually\n * rely on the ADDRESS override setting for determining whether CX or ECX will be used,\n * even though it seems counter-intuitive; ditto for the REP prefix.\n *\n * @this {CPUX86}\n */\nX86.opJCXZ = function()\n{\n var disp = this.getIPDisp();\n if (!(this.regECX & this.maskAddr)) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesLoopZ;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLoopZFall;\n};\n\n/**\n * op=0xE4 (IN AL,port)\n *\n * @this {CPUX86}\n */\nX86.opINb = function()\n{\n var port = this.getIPByte();\n if (!this.checkIOPM(port, 1, true)) return;\n this.regEAX = (this.regEAX & ~0xff) | (this.bus.checkPortInputNotify(port, 1, this.regLIP - 2) & 0xff);\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiIO;\n this.nStepCycles -= this.cycleCounts.nOpCyclesInP;\n};\n\n/**\n * op=0xE5 (IN AX,port)\n *\n * @this {CPUX86}\n */\nX86.opINw = function()\n{\n var port = this.getIPByte();\n if (!this.checkIOPM(port, this.sizeData, true)) return;\n this.regEAX = (this.regEAX & ~this.maskData) | (this.bus.checkPortInputNotify(port, this.sizeData, this.regLIP - 2) & this.maskData);\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiIO;\n this.backTrack.btiAH = this.backTrack.btiIO;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesInP;\n};\n\n/**\n * op=0xE6 (OUT port,AL)\n *\n * @this {CPUX86}\n */\nX86.opOUTb = function()\n{\n var port = this.getIPByte();\n if (!this.checkIOPM(port, 1, false)) return;\n this.bus.checkPortOutputNotify(port, 1, this.regEAX & 0xff, this.regLIP - 2);\n this.nStepCycles -= this.cycleCounts.nOpCyclesOutP;\n};\n\n/**\n * op=0xE7 (OUT port,AX)\n *\n * @this {CPUX86}\n */\nX86.opOUTw = function()\n{\n var port = this.getIPByte();\n if (!this.checkIOPM(port, this.sizeData, false)) return;\n this.bus.checkPortOutputNotify(port, this.sizeData, this.regEAX & this.maskData, this.regLIP - 2);\n this.nStepCycles -= this.cycleCounts.nOpCyclesOutP;\n};\n\n/**\n * op=0xE8 (CALL disp16)\n *\n * @this {CPUX86}\n */\nX86.opCALL = function()\n{\n var disp = this.getIPWord();\n var oldIP = this.getIP();\n var newIP = oldIP + disp;\n this.pushWord(oldIP);\n this.setIP(newIP);\n this.nStepCycles -= this.cycleCounts.nOpCyclesCall;\n};\n\n/**\n * op=0xE9 (JMP disp16)\n *\n * @this {CPUX86}\n */\nX86.opJMP = function()\n{\n var disp = this.getIPWord();\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmp;\n};\n\n/**\n * op=0xEA (JMP seg:off)\n *\n * @this {CPUX86}\n */\nX86.opJMPF = function()\n{\n this.setCSIP(this.getIPWord(), this.getIPShort());\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpF;\n};\n\n/**\n * op=0xEB (JMP short disp8)\n *\n * @this {CPUX86}\n */\nX86.opJMPs = function()\n{\n var disp = this.getIPDisp();\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmp;\n};\n\n/**\n * op=0xEC (IN AL,dx)\n *\n * @this {CPUX86}\n */\nX86.opINDXb = function()\n{\n var port = this.regEDX & 0xffff;\n if (!this.checkIOPM(port, 1, true)) return;\n this.regEAX = (this.regEAX & ~0xff) | (this.bus.checkPortInputNotify(port, 1, this.regLIP - 1) & 0xff);\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiIO;\n this.nStepCycles -= this.cycleCounts.nOpCyclesInDX;\n};\n\n/**\n * op=0xED (IN AX,dx)\n *\n * @this {CPUX86}\n */\nX86.opINDXw = function()\n{\n var port = this.regEDX & 0xffff;\n if (!this.checkIOPM(port, this.sizeData, true)) return;\n this.regEAX = (this.regEAX & ~this.maskData) | (this.bus.checkPortInputNotify(port, this.sizeData, this.regLIP - 1) & this.maskData);\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiIO;\n this.backTrack.btiAH = this.backTrack.btiIO;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesInDX;\n};\n\n/**\n * op=0xEE (OUT dx,AL)\n *\n * @this {CPUX86}\n */\nX86.opOUTDXb = function()\n{\n var port = this.regEDX & 0xffff;\n if (!this.checkIOPM(port, 1, false)) return;\n if (BACKTRACK) this.backTrack.btiIO = this.backTrack.btiAL;\n this.bus.checkPortOutputNotify(port, 1, this.regEAX & 0xff, this.regLIP - 1);\n this.nStepCycles -= this.cycleCounts.nOpCyclesOutDX;\n};\n\n/**\n * op=0xEF (OUT dx,AX)\n *\n * @this {CPUX86}\n */\nX86.opOUTDXw = function()\n{\n var port = this.regEDX & 0xffff;\n if (!this.checkIOPM(port, 2, false)) return;\n if (BACKTRACK) {\n this.backTrack.btiIO = this.backTrack.btiAL;\n this.backTrack.btiIO = this.backTrack.btiAH;\n }\n this.bus.checkPortOutputNotify(port, this.sizeData, this.regEAX & this.maskData, this.regLIP - 1);\n this.nStepCycles -= this.cycleCounts.nOpCyclesOutDX;\n};\n\n/**\n * op=0xF0 (LOCK:)\n *\n * @this {CPUX86}\n */\nX86.opLOCK = function()\n{\n this.opFlags |= X86.OPFLAG.LOCK | X86.OPFLAG.NOINTR;\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n};\n\n/**\n * op=0xF1 (INT1; undocumented; 80186/80188 and up; TODO: Verify)\n *\n * Note that this handler is assigned to opcode 0xF1 only on 80186 processors and up, because on 8086/8086\n * processors, we treat that opcode as an alias for LOCK (0xF0).\n *\n * For the 80186 and up, and we treat it as undefined. Starting with the 80386, this opcode is known as INT1\n * or ICEBP, since it effectively performs an INT 0x01 but is normally only performed with an ICE.\n *\n * @this {CPUX86}\n */\nX86.opINT1 = function()\n{\n X86.opUndefined.call(this);\n};\n\n/**\n * op=0xF2 (REPNZ:) (repeat CMPS or SCAS until NZ; repeat MOVS, LODS, or STOS unconditionally)\n *\n * @this {CPUX86}\n */\nX86.opREPNZ = function()\n{\n this.opFlags |= X86.OPFLAG.REPNZ | X86.OPFLAG.NOINTR;\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n};\n\n/**\n * op=0xF3 (REPZ:) (repeat CMPS or SCAS until Z; repeat MOVS, LODS, or STOS unconditionally)\n *\n * @this {CPUX86}\n */\nX86.opREPZ = function()\n{\n this.opFlags |= X86.OPFLAG.REPZ | X86.OPFLAG.NOINTR;\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n};\n\n/**\n * op=0xF4 (HLT)\n *\n * @this {CPUX86}\n */\nX86.opHLT = function()\n{\n if (I386 && (this.regPS & X86.PS.VM)) {\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n /*\n * The CPU is never REALLY halted by a HLT instruction; instead, by setting X86.INTFLAG.HALT,\n * we are signalling to stepCPU() that it's free to end the current burst AND that it should not\n * execute any more instructions until checkINTR() indicates a hardware interrupt is requested.\n */\n this.intFlags |= X86.INTFLAG.HALT;\n this.nStepCycles -= 2;\n /*\n * If a Debugger is present and both the CPU and HALT message categories are enabled, then we\n * REALLY halt the CPU, on the theory that whoever's using the Debugger would like to see HLTs.\n */\n if (DEBUGGER && this.dbg && this.messageEnabled(Messages.CPU | Messages.HALT)) {\n this.resetIP(-1); // this is purely for the Debugger's benefit, to show the HLT\n this.dbg.stopCPU();\n return;\n }\n /*\n * We also REALLY halt the machine if interrupts have been disabled, since that means it's dead in\n * the water (yes, we support NMIs, but none of our devices are going to generate an NMI at this point).\n */\n if (!this.getIF()) {\n if (DEBUGGER && this.dbg) this.resetIP(-1);\n this.stopCPU();\n }\n};\n\n/**\n * op=0xF5 (CMC)\n *\n * @this {CPUX86}\n */\nX86.opCMC = function()\n{\n if (this.getCF()) this.clearCF(); else this.setCF();\n this.nStepCycles -= 2; // CMC takes 2 cycles on all CPUs\n};\n\n/**\n * op=0xF6 (GRP3 byte)\n *\n * The MUL byte instruction is problematic in two cases:\n *\n * 0xF6 0xE0: MUL AL\n * 0xF6 0xE4: MUL AH\n *\n * because the OpModGrpByte decoder function will attempt to put the fnMULb() function's\n * return value back into AL or AH, undoing fnMULb's update of AX. And since fnMULb doesn't\n * know what the target is (only the target's value), it cannot easily work around the problem.\n *\n * A simple, albeit kludgy, solution is for fnMULb to always save its result in a special\n * \"register\" (eg, regMDLo), which we will then put back into regEAX if it's been updated.\n * This also relieves us from having to decode any part of the ModRM byte, so maybe it's not\n * such a bad work-around after all.\n *\n * Similar issues with IMUL (and DIV and IDIV) are resolved using the same special variable(s).\n *\n * @this {CPUX86}\n */\nX86.opGRP3b = function()\n{\n this.fMDSet = false;\n this.decodeModGrpByte.call(this, X86.aOpGrp3b, X86.helpSRCNone);\n if (this.fMDSet) this.regEAX = (this.regEAX & ~this.maskData) | (this.regMDLo & this.maskData);\n};\n\n/**\n * op=0xF7 (GRP3 word)\n *\n * The MUL word instruction is problematic in two cases:\n *\n * 0xF7 0xE0: MUL AX\n * 0xF7 0xE2: MUL DX\n *\n * because the OpModGrpWord decoder function will attempt to put the fnMULw() function's\n * return value back into AX or DX, undoing fnMULw's update of DX:AX. And since fnMULw doesn't\n * know what the target is (only the target's value), it cannot easily work around the problem.\n *\n * A simple, albeit kludgy, solution is for fnMULw to always save its result in a special\n * \"register\" (eg, regMDLo/regMDHi), which we will then put back into regEAX/regEDX if it's been\n * updated. This also relieves us from having to decode any part of the ModRM byte, so maybe\n * it's not such a bad work-around after all.\n *\n * @this {CPUX86}\n */\nX86.opGRP3w = function()\n{\n this.fMDSet = false;\n this.decodeModGrpWord.call(this, X86.aOpGrp3w, X86.helpSRCNone);\n if (this.fMDSet) {\n this.regEAX = (this.regEAX & ~this.maskData) | (this.regMDLo & this.maskData);\n this.regEDX = (this.regEDX & ~this.maskData) | (this.regMDHi & this.maskData);\n }\n};\n\n/**\n * op=0xF8 (CLC)\n *\n * @this {CPUX86}\n */\nX86.opCLC = function()\n{\n this.clearCF();\n this.nStepCycles -= 2; // CLC takes 2 cycles on all CPUs\n};\n\n/**\n * op=0xF9 (STC)\n *\n * @this {CPUX86}\n */\nX86.opSTC = function()\n{\n this.setCF();\n this.nStepCycles -= 2; // STC takes 2 cycles on all CPUs\n};\n\n/**\n * op=0xFA (CLI)\n *\n * @this {CPUX86}\n */\nX86.opCLI = function()\n{\n /*\n * The following code should be sufficient for all modes, because in real-mode, CPL is always zero,\n * and in V86-mode, CPL is always 3.\n */\n if (this.nCPL > this.nIOPL) {\n if (DEBUG && (this.regPS & X86.PS.VM)) this.printMessage(\"CLI in v86-mode (IOPL < 3)\", this.bitsMessage, true);\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n this.clearIF();\n this.nStepCycles -= this.cycleCounts.nOpCyclesCLI; // CLI takes LONGER on an 80286\n};\n\n/**\n * op=0xFB (STI)\n *\n * @this {CPUX86}\n */\nX86.opSTI = function()\n{\n /*\n * The following code should be sufficient for all modes, because in real-mode, CPL is always zero,\n * and in V86-mode, CPL is always 3.\n */\n if (this.nCPL > this.nIOPL) {\n if (DEBUG && (this.regPS & X86.PS.VM)) this.printMessage(\"STI in v86-mode (IOPL < 3)\", this.bitsMessage, true);\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n this.setIF();\n this.opFlags |= X86.OPFLAG.NOINTR;\n this.nStepCycles -= 2; // STI takes 2 cycles on all CPUs\n};\n\n/**\n * op=0xFC (CLD)\n *\n * @this {CPUX86}\n */\nX86.opCLD = function()\n{\n this.clearDF();\n this.nStepCycles -= 2; // CLD takes 2 cycles on all CPUs\n};\n\n/**\n * op=0xFD (STD)\n *\n * @this {CPUX86}\n */\nX86.opSTD = function()\n{\n this.setDF();\n this.nStepCycles -= 2; // STD takes 2 cycles on all CPUs\n};\n\n/**\n * op=0xFE (GRP4 byte)\n *\n * @this {CPUX86}\n */\nX86.opGRP4b = function()\n{\n this.decodeModGrpByte.call(this, X86.aOpGrp4b, X86.helpSRCNone);\n};\n\n/**\n * op=0xFF (GRP4 word)\n *\n * @this {CPUX86}\n */\nX86.opGRP4w = function()\n{\n this.decodeModGrpWord.call(this, X86.aOpGrp4w, X86.helpSRCNone);\n};\n\n/**\n * opInvalid()\n *\n * @this {CPUX86}\n */\nX86.opInvalid = function()\n{\n X86.helpFault.call(this, X86.EXCEPTION.UD_FAULT);\n};\n\n/**\n * opUndefined()\n *\n * @this {CPUX86}\n */\nX86.opUndefined = function()\n{\n this.setIP(this.opLIP - this.segCS.base);\n this.setError(\"Undefined opcode \" + Str.toHexByte(this.getByte(this.regLIP)) + \" at \" + Str.toHexLong(this.regLIP));\n this.stopCPU();\n};\n\n/**\n * opTBD()\n *\n * @this {CPUX86}\n */\nX86.opTBD = function()\n{\n this.setIP(this.opLIP - this.segCS.base);\n this.printMessage(\"unimplemented 80386 opcode\", true);\n this.stopCPU();\n};\n\n/*\n * This 256-entry array of opcode functions is at the heart of the CPU engine: stepCPU(n).\n *\n * It might be worth trying a switch() statement instead, to see how the performance compares,\n * but I suspect that would vary quite a bit across JavaScript engines; for now, I'm putting my\n * money on array lookup.\n */\nX86.aOps = [\n X86.opADDmb, X86.opADDmw, X86.opADDrb, X86.opADDrw, // 0x00-0x03\n X86.opADDALb, X86.opADDAX, X86.opPUSHES, X86.opPOPES, // 0x04-0x07\n X86.opORmb, X86.opORmw, X86.opORrb, X86.opORrw, // 0x08-0x0B\n X86.opORALb, X86.opORAX, X86.opPUSHCS, X86.opPOPCS, // 0x0C-0x0F\n X86.opADCmb, X86.opADCmw, X86.opADCrb, X86.opADCrw, // 0x10-0x13\n X86.opADCALb, X86.opADCAX, X86.opPUSHSS, X86.opPOPSS, // 0x14-0x17\n X86.opSBBmb, X86.opSBBmw, X86.opSBBrb, X86.opSBBrw, // 0x18-0x1B\n X86.opSBBALb, X86.opSBBAX, X86.opPUSHDS, X86.opPOPDS, // 0x1C-0x1F\n X86.opANDmb, X86.opANDmw, X86.opANDrb, X86.opANDrw, // 0x20-0x23\n X86.opANDAL, X86.opANDAX, X86.opES, X86.opDAA, // 0x24-0x27\n X86.opSUBmb, X86.opSUBmw, X86.opSUBrb, X86.opSUBrw, // 0x28-0x2B\n X86.opSUBALb, X86.opSUBAX, X86.opCS, X86.opDAS, // 0x2C-0x2F\n X86.opXORmb, X86.opXORmw, X86.opXORrb, X86.opXORrw, // 0x30-0x33\n X86.opXORALb, X86.opXORAX, X86.opSS, X86.opAAA, // 0x34-0x37\n X86.opCMPmb, X86.opCMPmw, X86.opCMPrb, X86.opCMPrw, // 0x38-0x3B\n X86.opCMPALb, X86.opCMPAX, X86.opDS, X86.opAAS, // 0x3C-0x3F\n X86.opINCAX, X86.opINCCX, X86.opINCDX, X86.opINCBX, // 0x40-0x43\n X86.opINCSP, X86.opINCBP, X86.opINCSI, X86.opINCDI, // 0x44-0x47\n X86.opDECAX, X86.opDECCX, X86.opDECDX, X86.opDECBX, // 0x48-0x4B\n X86.opDECSP, X86.opDECBP, X86.opDECSI, X86.opDECDI, // 0x4C-0x4F\n X86.opPUSHAX, X86.opPUSHCX, X86.opPUSHDX, X86.opPUSHBX, // 0x50-0x53\n X86.opPUSHSP_8086, X86.opPUSHBP, X86.opPUSHSI, X86.opPUSHDI, // 0x54-0x57\n X86.opPOPAX, X86.opPOPCX, X86.opPOPDX, X86.opPOPBX, // 0x58-0x5B\n X86.opPOPSP, X86.opPOPBP, X86.opPOPSI, X86.opPOPDI, // 0x5C-0x5F\n /*\n * On an 8086/8088, opcodes 0x60-0x6F are aliases for the conditional jumps 0x70-0x7F. Sometimes you'll see\n * references to these opcodes (like 0x60) being a \"two-byte NOP\" and using them differentiate an 8088 from newer\n * CPUs, but they're only a \"two-byte NOP\" if the second byte is zero, resulting in zero displacement.\n */\n X86.opJO, X86.opJNO, X86.opJC, X86.opJNC, // 0x60-0x63\n X86.opJZ, X86.opJNZ, X86.opJBE, X86.opJNBE, // 0x64-0x67\n X86.opJS, X86.opJNS, X86.opJP, X86.opJNP, // 0x68-0x6B\n X86.opJL, X86.opJNL, X86.opJLE, X86.opJNLE, // 0x6C-0x6F\n X86.opJO, X86.opJNO, X86.opJC, X86.opJNC, // 0x70-0x73\n X86.opJZ, X86.opJNZ, X86.opJBE, X86.opJNBE, // 0x74-0x77\n X86.opJS, X86.opJNS, X86.opJP, X86.opJNP, // 0x78-0x7B\n X86.opJL, X86.opJNL, X86.opJLE, X86.opJNLE, // 0x7C-0x7F\n /*\n * On all processors, opcode groups 0x80 and 0x82 perform identically (0x82 opcodes sign-extend their\n * immediate data, but since both 0x80 and 0x82 are byte operations, the sign extension has no effect).\n *\n * WARNING: Intel's \"Pentium Processor User's Manual (Volume 3: Architecture and Programming Manual)\" refers\n * to opcode 0x82 as a \"reserved\" instruction, but also cryptically refers to it as \"MOVB AL,imm\". This is\n * assumed to be an error in the manual, because as far as I know, 0x82 has always mirrored 0x80.\n */\n X86.opGRP1b, X86.opGRP1w, X86.opGRP1b, X86.opGRP1sw, // 0x80-0x83\n X86.opTESTrb, X86.opTESTrw, X86.opXCHGrb, X86.opXCHGrw, // 0x84-0x87\n X86.opMOVmb, X86.opMOVmw, X86.opMOVrb, X86.opMOVrw, // 0x88-0x8B\n X86.opMOVwsr, X86.opLEA, X86.opMOVsrw, X86.opPOPmw, // 0x8C-0x8F\n X86.opNOP, X86.opXCHGCX, X86.opXCHGDX, X86.opXCHGBX, // 0x90-0x93\n X86.opXCHGSP, X86.opXCHGBP, X86.opXCHGSI, X86.opXCHGDI, // 0x94-0x97\n X86.opCBW, X86.opCWD, X86.opCALLF, X86.opWAIT, // 0x98-0x9B\n X86.opPUSHF, X86.opPOPF, X86.opSAHF, X86.opLAHF, // 0x9C-0x9F\n X86.opMOVALm, X86.opMOVAXm, X86.opMOVmAL, X86.opMOVmAX, // 0xA0-0xA3\n X86.opMOVSb, X86.opMOVSw, X86.opCMPSb, X86.opCMPSw, // 0xA4-0xA7\n X86.opTESTALb, X86.opTESTAX, X86.opSTOSb, X86.opSTOSw, // 0xA8-0xAB\n X86.opLODSb, X86.opLODSw, X86.opSCASb, X86.opSCASw, // 0xAC-0xAF\n X86.opMOVALb, X86.opMOVCLb, X86.opMOVDLb, X86.opMOVBLb, // 0xB0-0xB3\n X86.opMOVAHb, X86.opMOVCHb, X86.opMOVDHb, X86.opMOVBHb, // 0xB4-0xB7\n X86.opMOVAX, X86.opMOVCX, X86.opMOVDX, X86.opMOVBX, // 0xB8-0xBB\n X86.opMOVSP, X86.opMOVBP, X86.opMOVSI, X86.opMOVDI, // 0xBC-0xBF\n /*\n * On an 8086/8088, opcodes 0xC0 -> 0xC2, 0xC1 -> 0xC3, 0xC8 -> 0xCA and 0xC9 -> 0xCB.\n */\n X86.opRETn, X86.opRET, X86.opRETn, X86.opRET, // 0xC0-0xC3\n X86.opLES, X86.opLDS, X86.opMOVb, X86.opMOVw, // 0xC4-0xC7\n X86.opRETFn, X86.opRETF, X86.opRETFn, X86.opRETF, // 0xC8-0xCB\n X86.opINT3, X86.opINTn, X86.opINTO, X86.opIRET, // 0xCC-0xCF\n X86.opGRP2b1, X86.opGRP2w1, X86.opGRP2bCL, X86.opGRP2wCL, // 0xD0-0xD3\n /*\n * Even as of the Pentium, opcode 0xD6 is still marked as \"reserved\", but it's always been SALC (aka SETALC).\n */\n X86.opAAM, X86.opAAD, X86.opSALC, X86.opXLAT, // 0xD4-0xD7\n X86.opESC0, X86.opESC1, X86.opESC2, X86.opESC3, // 0xD8-0xDB\n X86.opESC4, X86.opESC5, X86.opESC6, X86.opESC7, // 0xDC-0xDF\n X86.opLOOPNZ, X86.opLOOPZ, X86.opLOOP, X86.opJCXZ, // 0xE0-0xE3\n X86.opINb, X86.opINw, X86.opOUTb, X86.opOUTw, // 0xE4-0xE7\n X86.opCALL, X86.opJMP, X86.opJMPF, X86.opJMPs, // 0xE8-0xEB\n X86.opINDXb, X86.opINDXw, X86.opOUTDXb, X86.opOUTDXw, // 0xEC-0xEF\n /*\n * On an 8086/8088, opcode 0xF1 is believed to be an alias for 0xF0; in any case, it definitely behaves like\n * a prefix on those processors, so we treat it as such. On the 80186 and up, we treat as opINT1().\n *\n * As of the Pentium, opcode 0xF1 is still marked \"reserved\".\n */\n X86.opLOCK, X86.opLOCK, X86.opREPNZ, X86.opREPZ, // 0xF0-0xF3\n X86.opHLT, X86.opCMC, X86.opGRP3b, X86.opGRP3w, // 0xF4-0xF7\n X86.opCLC, X86.opSTC, X86.opCLI, X86.opSTI, // 0xF8-0xFB\n X86.opCLD, X86.opSTD, X86.opGRP4b, X86.opGRP4w // 0xFC-0xFF\n];\n\n/*\n * A word (or two) on instruction groups (eg, Grp1, Grp2), which are groups of instructions that\n * use a mod/reg/rm byte, where the reg field of that byte selects a function rather than a register.\n *\n * I start with the groupings used by Intel's \"Pentium Processor User's Manual (Volume 3: Architecture\n * and Programming Manual)\", but I deviate slightly, mostly by subdividing their groups with letter suffixes:\n *\n * Opcodes Intel PCx86 PC Mag TechRef\n * ------- ----- ---- --------------\n * 0x80-0x83 Grp1 Grp1b and Grp1w Group A\n * 0xC0-0xC1 Grp2 Grp2b and Grp2w (opGRP2bn/wn) Group B\n * 0xD0-0xD3 Grp2 Grp2b and Grp2w (opGRP2b1/w1 and opGRP2bCL/wCL) Group B\n * 0xF6-0xF7 Grp3 Grp3b and Grp3w Group C\n * 0xFE Grp4 Grp4b Group D\n * 0xFF Grp5 Grp4w Group E\n * 0x0F,0x00 Grp6 Grp6 (SLDT, STR, LLDT, LTR, VERR, VERW) Group F\n * 0x0F,0x01 Grp7 Grp7 (SGDT, SIDT, LGDT, LIDT, SMSW, LMSW, INVLPG) Group G\n * 0x0F,0xBA Grp8 Grp8 (BT, BTS, BTR, BTC) Group H\n * 0x0F,0xC7 Grp9 Grp9 (CMPXCH) (N/A, 80486 and up)\n *\n * My only serious deviation is Grp5, which I refer to as Grp4w, because it contains word forms of\n * the INC and DEC instructions found in Grp4b. Granted, Grp4w also contains versions of the CALL,\n * JMP and PUSH instructions, which are not in Grp4b, but there's nothing in Grp4b that conflicts with\n * Grp4w, so I think my nomenclature makes more sense. To compensate, I don't use Grp5, so that the\n * remaining group numbers remain in sync with Intel's.\n *\n * To the above list, I've added a few \"single-serving\" groups: opcode 0x8F uses GrpPOPw, and opcodes 0xC6/0xC7\n * use GrpMOVn. In both of these groups, the only valid (documented) instruction is where reg=0x0.\n *\n * TODO: Test what happens on real hardware when the reg field is non-zero for opcodes 0x8F and 0xC6/0xC7.\n */\nX86.aOpGrp1b = [\n X86.fnADDb, X86.fnORb, X86.fnADCb, X86.fnSBBb, // 0x80/0x82(reg=0x0-0x3)\n X86.fnANDb, X86.fnSUBb, X86.fnXORb, X86.fnCMPb // 0x80/0x82(reg=0x4-0x7)\n];\n\nX86.aOpGrp1w = [\n X86.fnADDw, X86.fnORw, X86.fnADCw, X86.fnSBBw, // 0x81/0x83(reg=0x0-0x3)\n X86.fnANDw, X86.fnSUBw, X86.fnXORw, X86.fnCMPw // 0x81/0x83(reg=0x4-0x7)\n];\n\nX86.aOpGrpPOPw = [\n X86.fnPOPw, X86.fnGRPFault, X86.fnGRPFault, X86.fnGRPFault, // 0x8F(reg=0x0-0x3)\n X86.fnGRPFault, X86.fnGRPFault, X86.fnGRPFault, X86.fnGRPFault // 0x8F(reg=0x4-0x7)\n];\n\nX86.aOpGrpMOVn = [\n X86.fnMOVn, X86.fnGRPUndefined, X86.fnGRPUndefined, X86.fnGRPUndefined, // 0xC6/0xC7(reg=0x0-0x3)\n X86.fnGRPUndefined, X86.fnGRPUndefined, X86.fnGRPUndefined, X86.fnGRPUndefined // 0xC6/0xC7(reg=0x4-0x7)\n];\n\nX86.aOpGrp2b = [\n X86.fnROLb, X86.fnRORb, X86.fnRCLb, X86.fnRCRb, // 0xC0/0xD0/0xD2(reg=0x0-0x3)\n X86.fnSHLb, X86.fnSHRb, X86.fnGRPUndefined, X86.fnSARb // 0xC0/0xD0/0xD2(reg=0x4-0x7)\n];\n\nX86.aOpGrp2w = [\n X86.fnROLw, X86.fnRORw, X86.fnRCLw, X86.fnRCRw, // 0xC1/0xD1/0xD3(reg=0x0-0x3)\n X86.fnSHLw, X86.fnSHRw, X86.fnGRPUndefined, X86.fnSARw // 0xC1/0xD1/0xD3(reg=0x4-0x7)\n];\n\nX86.aOpGrp2d = [\n X86.fnROLd, X86.fnRORd, X86.fnRCLd, X86.fnRCRd, // 0xC1/0xD1/0xD3(reg=0x0-0x3)\n X86.fnSHLd, X86.fnSHRd, X86.fnGRPUndefined, X86.fnSARd // 0xC1/0xD1/0xD3(reg=0x4-0x7)\n];\n\nX86.aOpGrp3b = [\n X86.fnTESTib, X86.fnGRPUndefined, X86.fnNOTb, X86.fnNEGb, // 0xF6(reg=0x0-0x3)\n X86.fnMULb, X86.fnIMULb, X86.fnDIVb, X86.fnIDIVb // 0xF6(reg=0x4-0x7)\n];\n\nX86.aOpGrp3w = [\n X86.fnTESTiw, X86.fnGRPUndefined, X86.fnNOTw, X86.fnNEGw, // 0xF7(reg=0x0-0x3)\n X86.fnMULw, X86.fnIMULw, X86.fnDIVw, X86.fnIDIVw // 0xF7(reg=0x4-0x7)\n];\n\nX86.aOpGrp4b = [\n X86.fnINCb, X86.fnDECb, X86.fnGRPUndefined, X86.fnGRPUndefined, // 0xFE(reg=0x0-0x3)\n X86.fnGRPUndefined, X86.fnGRPUndefined, X86.fnGRPUndefined, X86.fnGRPUndefined // 0xFE(reg=0x4-0x7)\n];\n\nX86.aOpGrp4w = [\n X86.fnINCw, X86.fnDECw, X86.fnCALLw, X86.fnCALLFdw, // 0xFF(reg=0x0-0x3)\n X86.fnJMPw, X86.fnJMPFdw, X86.fnPUSHw, X86.fnGRPUndefined // 0xFF(reg=0x4-0x7)\n];\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/x86op0f.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * op=0x0F,0x00 (GRP6 mem/reg)\n *\n * @this {CPUX86}\n */\nX86.opGRP6 = function()\n{\n var bModRM = this.peekIPByte();\n if ((bModRM & 0x38) < 0x10) { // possible reg values: 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38\n this.opFlags |= X86.OPFLAG.NOREAD;\n }\n this.decodeModGrpWord.call(this, this.aOpGrp6, X86.helpSRCNone);\n};\n\n/**\n * op=0x0F,0x01 (GRP7 mem/reg)\n *\n * @this {CPUX86}\n */\nX86.opGRP7 = function()\n{\n var bModRM = this.peekIPByte();\n if (!(bModRM & 0x10)) {\n this.opFlags |= X86.OPFLAG.NOREAD;\n }\n this.decodeModGrpWord.call(this, X86.aOpGrp7, X86.helpSRCNone);\n};\n\n/**\n * opLAR()\n *\n * op=0x0F,0x02 (LAR reg,mem/reg)\n *\n * @this {CPUX86}\n */\nX86.opLAR = function()\n{\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to real-mode or V86-mode.\n */\n if (!(this.regCR0 & X86.CR0.MSW.PE) || I386 && (this.regPS & X86.PS.VM)) {\n X86.opInvalid.call(this);\n return;\n }\n this.decodeModRegWord.call(this, X86.fnLAR);\n};\n\n/**\n * opLSL()\n *\n * op=0x0F,0x03 (LSL reg,mem/reg)\n *\n * @this {CPUX86}\n */\nX86.opLSL = function()\n{\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to real-mode or V86-mode.\n */\n if (!(this.regCR0 & X86.CR0.MSW.PE) || I386 && (this.regPS & X86.PS.VM)) {\n X86.opInvalid.call(this);\n return;\n }\n this.decodeModRegWord.call(this, X86.fnLSL);\n};\n\n/**\n * opLOADALL286()\n *\n * op=0x0F,0x05 (LOADALL)\n *\n * From the \"Undocumented iAPX 286 Test Instruction\" document at http://www.pcjs.org/pubs/pc/reference/intel/80286/loadall/:\n *\n * Physical Address (Hex) Associated CPU Register\n * 800-805 None\n * 806-807 MSW\n * 808-815 None\n * 816-817 TR\n * 818-819 Flag word\n * 81A-81B IP\n * 81C-81D LDT\n * 81E-81F DS\n * 820-821 SS\n * 822-823 CS\n * 824-825 ES\n * 826-827 DI\n * 828-829 SI\n * 82A-82B BP\n * 82C-82D SP\n * 82E-82F BX\n * 830-831 DX\n * 832-833 CX\n * 834-835 AX\n * 836-83B ES descriptor cache\n * 83C-841 CS descriptor cache\n * 842-847 SS descriptor cache\n * 848-84D DS descriptor cache\n * 84E-853 GDTR\n * 854-859 LDT descriptor cache\n * 85A-85F IDTR\n * 860-865 TSS descriptor cache\n *\n * @this {CPUX86}\n */\nX86.opLOADALL286 = function()\n{\n if (this.nCPL) {\n /*\n * To use LOADALL, CPL must be zero.\n */\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0, 0, true);\n return;\n }\n this.setMSW(this.getShort(0x806));\n this.regEDI = this.getShort(0x826);\n this.regESI = this.getShort(0x828);\n this.regEBP = this.getShort(0x82A);\n this.regEBX = this.getShort(0x82E);\n this.regEDX = this.getShort(0x830);\n this.regECX = this.getShort(0x832);\n this.regEAX = this.getShort(0x834);\n this.segES.loadDesc6(0x836, this.getShort(0x824));\n this.segCS.loadDesc6(0x83C, this.getShort(0x822));\n this.segSS.loadDesc6(0x842, this.getShort(0x820));\n this.segDS.loadDesc6(0x848, this.getShort(0x81E));\n /*\n * Unlike LOADALL386, there's no requirement for calling setPS() before loading segment registers;\n * in fact, since we're not passing a CPL to setPS(), it may be preferable to have CS (and perhaps SS)\n * already loaded, so that setPS() can query the CPL. TODO: Verify that CPL is set correctly.\n */\n this.setPS(this.getShort(0x818));\n /*\n * It's important to call setIP() and setSP() *after* the segCS and segSS loads, so that the CPU's\n * linear IP and SP registers (regLIP and regLSP) will be updated properly. Ordinarily that would be\n * taken care of by simply using the CPU's setCS() and setSS() functions, but those functions call the\n * default descriptor load() functions, and obviously here we must use loadDesc6() instead.\n */\n this.setIP(this.getShort(0x81A));\n this.setSP(this.getShort(0x82C));\n /*\n * The bytes at 0x851 and 0x85D \"should be zeroes\", as per the \"Undocumented iAPX 286 Test Instruction\"\n * document, but the LOADALL issued by RAMDRIVE in PC-DOS 7.0 contains 0xFF in both of those bytes, resulting\n * in very large addrGDT and addrIDT values. Obviously, we can't have that, so we load only the low byte\n * of the second word for both of those registers.\n */\n this.addrGDT = this.getShort(0x84E) | (this.getByte(0x850) << 16);\n this.addrGDTLimit = this.addrGDT + this.getShort(0x852);\n this.addrIDT = this.getShort(0x85A) | (this.getByte(0x85C) << 16);\n this.addrIDTLimit = this.addrIDT + this.getShort(0x85E);\n this.segLDT.loadDesc6(0x854, this.getShort(0x81C));\n this.segTSS.loadDesc6(0x860, this.getShort(0x816));\n\n /*\n * Oddly, the above Intel document gives two contradictory cycle counts for LOADALL: 190 and 195.\n * I'm going with 195, since both the PC Magazine Programmer's Technical Reference and Robert Collins\n * (http://www.rcollins.org/articles/loadall/tspec_a3_doc.html) agree.\n */\n this.nStepCycles -= 195;\n\n /*\n * TODO: LOADALL operation still needs to be verified in protected mode....\n */\n if (DEBUG && DEBUGGER && (this.regCR0 & X86.CR0.MSW.PE)) this.stopCPU();\n};\n\n/**\n * opCLTS()\n *\n * op=0x0F,0x06 (CLTS)\n *\n * @this {CPUX86}\n */\nX86.opCLTS = function()\n{\n /*\n * NOTE: The following code shouldn't need to also test X86.PS.VM, because V86-mode is CPL 3.\n */\n if (this.nCPL) {\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n this.regCR0 &= ~X86.CR0.MSW.TS;\n this.nStepCycles -= 2;\n};\n\n/**\n * opLOADALL386()\n *\n * op=0x0F,0x07 (LOADALL ES:[EDI])\n *\n * Excerpt from Intel Internal Correspondence on \"386 LOADALL Instruction\" (undated), available as part of the\n * PCjs Project at http://www.pcjs.org/pubs/pc/reference/intel/80386/loadall/\n *\n * 1.5. 386 LOADALL Memory Format\n *\n * The following tables define the LOADALL memory format. The LOADALL instruction uses a 512-byte block of\n * memory, where the lowest addressed byte is given in ES:[(E)DI]. The area above offset CC hex is used for\n * processor dependent registers (temporaries, invisible registers). These are loaded into the processor,\n * but will not affect normal program execution. All values in the memory area are read from a four byte field,\n * to keep the memory format DWORD aligned, but it is possible to locate memory area at a non-aligned address.\n * In this case, the execution time of LOADALL will DOUBLE For this reason, the memory dump area should always\n * be DWORD aligned.\n *\n * Offset Register\n * ------ --------\n * 0x00 CR0\n * 0x04 EFLAGS\n * 0x08 EIP\n * 0x0C EDI\n * 0x10 ESI\n * 0x14 EBP\n * 0x18 ESP\n * 0x1C EBX\n * 0x20 EDX\n * 0x24 ECX\n * 0x28 EAX\n * 0x2C DR6\n * 0x30 DR7\n * 0x34 TSSR(TSSSelector-Word)\n * 0x38 LDTR(LDTSelector-Word)\n * 0x3C GS\n * 0x40 FS\n * 0x44 DS\n * 0x48 SS\n * 0x4C CS\n * 0x50 ES\n * 0x54 TSS(AR)\n * 0x58 TSS(BASE)\n * 0x5C TSS(LIMIT)\n * 0x60 IDT(AR)\n * 0x64 IDT(BASE)\n * 0x68 IDT(LIMIT)\n * 0x6C GDT(AR)\n * 0x70 GDT(BASE)\n * 0x74 GDT(LIMIT)\n * 0x78 LDT(AR)\n * 0x7C LDT(BASE)\n * 0x80 LDT(LIMIT)\n * 0x84 GS(AR)\n * 0x88 GS(BASE)\n * 0x8C GS(LIMIT)\n * 0x90 FS(AR)\n * 0x94 FS(BASE)\n * 0x98 FS(LIMIT)\n * 0x9C DS(AR)\n * 0xA0 DS(BASE)\n * 0xA4 DS(LIMIT)\n * 0xA8 SS(AR)\n * 0xAC SS(BASE)\n * 0xB0 SS(LIMIT)\n * 0xB4 CS(AR)\n * 0xB8 CS(BASE)\n * 0xBC CS(LIMIT)\n * 0xC0 ES(AR)\n * 0xC4 ES(BASE)\n * 0xC8 ES(LIMIT)\n *\n * Each descriptor entry consists of 3 pieces:\n *\n * AR\n * BASE\n * LIMIT\n *\n * The AR part has the same format as the second dword of a segment descriptor except that only the AR byte\n * (bits 8-15) and the G and B/D bits (bits 23 and 22) are used. All other bits in the AR field are ignored.\n * The BASE and LIMIT parts contain full 32-bit values, fully expanded and unscrambled from the 386 descriptor.\n * In particular, the LIMIT field loaded for a page granular segment gives a byte granular limit, so should\n * contain the page limit*4096 plus 4095.\n *\n * @this {CPUX86}\n */\nX86.opLOADALL386 = function()\n{\n if (this.nCPL) {\n /*\n * To use LOADALL, CPL must be zero.\n */\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0, 0, true);\n return;\n }\n var addr = this.segES.checkRead(this.regEDI & this.maskAddr, 0xCC);\n if (addr !== X86.ADDR_INVALID) {\n X86.helpLoadCR0.call(this, this.getLong(addr));\n /*\n * We need to call setPS() before loading any segment registers, because if the Virtual 8086 Mode (VM)\n * bit is set in EFLAGS, the segment registers need to know that.\n */\n var accSS = this.getLong(addr + 0xA8);\n var cpl = (accSS & X86.DESC.ACC.DPL.MASK) >> X86.DESC.ACC.DPL.SHIFT;\n this.setPS(this.getLong(addr + 0x04), cpl);\n /*\n * TODO: We have no use for the GDT(AR) at offset 0x6C or the IDT(AR) at offset 0x60, because\n * we don't manage them as segment registers. Should we?\n */\n this.addrGDT = this.getLong(addr + 0x70);\n this.addrGDTLimit = this.addrGDT + this.getLong(addr + 0x74);\n this.addrIDT = this.getLong(addr + 0x64);\n this.addrIDTLimit = this.addrIDT + this.getLong(addr + 0x68);\n this.segLDT.loadDesc(this.getLong(addr + 0x38), this.getLong(addr + 0x78), this.getLong(addr + 0x7C), this.getLong(addr + 0x80));\n this.segTSS.loadDesc(this.getLong(addr + 0x34), this.getLong(addr + 0x54), this.getLong(addr + 0x58), this.getLong(addr + 0x5C));\n this.regEDI = this.getLong(addr + 0x0C);\n this.regESI = this.getLong(addr + 0x10);\n this.regEBP = this.getLong(addr + 0x14);\n this.regEBX = this.getLong(addr + 0x1C);\n this.regEDX = this.getLong(addr + 0x20);\n this.regECX = this.getLong(addr + 0x24);\n this.regEAX = this.getLong(addr + 0x28);\n this.segGS.loadDesc(this.getLong(addr + 0x3C), this.getLong(addr + 0x84), this.getLong(addr + 0x88), this.getLong(addr + 0x8C));\n this.segFS.loadDesc(this.getLong(addr + 0x40), this.getLong(addr + 0x90), this.getLong(addr + 0x94), this.getLong(addr + 0x98));\n this.segDS.loadDesc(this.getLong(addr + 0x44), this.getLong(addr + 0x9C), this.getLong(addr + 0xA0), this.getLong(addr + 0xA4));\n this.segSS.loadDesc(this.getLong(addr + 0x48), accSS, this.getLong(addr + 0xAC), this.getLong(addr + 0xB0));\n this.segCS.loadDesc(this.getLong(addr + 0x4C), this.getLong(addr + 0xB4), this.getLong(addr + 0xB8), this.getLong(addr + 0xBC));\n this.segES.loadDesc(this.getLong(addr + 0x50), this.getLong(addr + 0xC0), this.getLong(addr + 0xC4), this.getLong(addr + 0xC8));\n /*\n * It's important to call setIP() and setSP() *after* the segCS and segSS loads, so that the CPU's\n * linear IP and SP registers (regLIP and regLSP) will be updated properly. Ordinarily that would be\n * taken care of by simply using the CPU's setCS() and setSS() functions, but those functions call the\n * default descriptor load() functions, and obviously here we must use loadDesc() instead.\n */\n this.setIP(this.getLong(addr + 0x08));\n this.setSP(this.getLong(addr + 0x18));\n /*\n * TODO: We need to factor out the code that updates DR6 and DR7 from X86.opMOVdr(), so that we can\n * more easily update DR6 and DR7 (which we're simply ignoring for now).\n */\n }\n\n /*\n * According to Robert Collins (http://www.rcollins.org/articles/loadall/tspec_a3_doc.html), the 80386 LOADALL\n * takes 122 cycles. Also, according the above-mentioned Intel document, if the memory buffer is not DWORD aligned,\n * execution time will DOUBLE.\n */\n this.nStepCycles -= (122 << ((addr & 0x3)? 1 : 0));\n};\n\n/**\n * opMOVrc()\n *\n * op=0x0F,0x20 (MOV reg,ctlreg)\n *\n * NOTE: Since this instruction uses only 32-bit general-purpose registers, our ModRM decoders\n * are going to be more hindrance than help, so we fully decode and execute the instruction ourselves.\n *\n * From PCMag_Prog_TechRef, p.476: \"The 80386 executes the MOV to/from control registers (CRn) regardless\n * of the setting of the MOD field. The MOD field should be set to 11, but an early 80386 documentation\n * error indicated that the MOD field value was a don't care. Early versions of the 80486 detect\n * a MOD != 11 as an illegal opcode. This was changed in later versions to ignore the value of MOD.\n * Assemblers that generate MOD != 11 for these instructions will fail on some 80486s.\"\n *\n * And in fact, the COMPAQ DeskPro 386 ROM BIOS executes this instruction with MOD set to 00, so we have\n * to ignore it.\n *\n * @this {CPUX86}\n */\nX86.opMOVrc = function()\n{\n /*\n * NOTE: The following code shouldn't need to also test X86.PS.VM, because V86-mode is CPL 3.\n */\n if (this.nCPL) {\n /*\n * You're not allowed to read control registers if the current privilege level is not zero.\n */\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n\n var reg;\n var bModRM = this.getIPByte();\n switch((bModRM & 0x38) >> 3) {\n case 0x0:\n reg = this.regCR0;\n break;\n case 0x2:\n reg = this.regCR2;\n break;\n case 0x3:\n reg = this.regCR3;\n break;\n default:\n X86.opUndefined.call(this);\n return;\n }\n\n this.setReg(bModRM & 0x7, reg);\n\n this.nStepCycles -= 6;\n\n /*\n * TODO: Implement BACKTRACK for this instruction (although Control registers are not likely to be a conduit for interesting data).\n */\n};\n\n/**\n * opMOVrd()\n *\n * op=0x0F,0x21 (MOV reg,dbgreg)\n *\n * NOTE: Since this instruction uses only 32-bit general-purpose registers, our ModRM decoders\n * are going to be more hindrance than help, so we fully decode and execute the instruction ourselves.\n *\n * @this {CPUX86}\n */\nX86.opMOVrd = function()\n{\n /*\n * NOTE: The following code shouldn't need to also test X86.PS.VM, because V86-mode is CPL 3.\n */\n if (this.nCPL) {\n /*\n * You're not allowed to read control registers if the current privilege level is not zero.\n */\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n\n var bModRM = this.getIPByte();\n var iSrc = (bModRM & 0x38) >> 3;\n\n if (iSrc == 4 || iSrc == 5) {\n X86.opUndefined.call(this);\n return;\n }\n\n this.setReg(bModRM & 0x7, this.regDR[iSrc]);\n\n this.nStepCycles -= 22;\n\n /*\n * TODO: Implement BACKTRACK for this instruction (although Debug registers are not likely to be a conduit for interesting data).\n */\n};\n\n/**\n * opMOVcr()\n *\n * op=0x0F,0x22 (MOV ctlreg,reg)\n *\n * NOTE: Since this instruction uses only 32-bit general-purpose registers, our ModRM decoders\n * are going to be more hindrance than help, so we fully decode and execute the instruction ourselves.\n *\n * From PCMag_Prog_TechRef, p.476: \"The 80386 executes the MOV to/from control registers (CRn) regardless\n * of the setting of the MOD field. The MOD field should be set to 11, but an early 80386 documentation\n * error indicated that the MOD field value was a don't care. Early versions of the 80486 detect\n * a MOD != 11 as an illegal opcode. This was changed in later versions to ignore the value of MOD.\n * Assemblers that generate MOD != 11 for these instructions will fail on some 80486s.\"\n *\n * And in fact, the COMPAQ DeskPro 386 ROM BIOS executes this instruction with MOD set to 00, so we have\n * to ignore it.\n *\n * @this {CPUX86}\n */\nX86.opMOVcr = function()\n{\n /*\n * NOTE: The following code shouldn't need to also test X86.PS.VM, because V86-mode is CPL 3.\n */\n if (this.nCPL) {\n /*\n * You're not allowed to write control registers if the current privilege level is not zero.\n */\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n\n var bModRM = this.getIPByte();\n var reg = this.getReg(bModRM & 0x7);\n\n switch((bModRM & 0x38) >> 3) {\n case 0x0:\n X86.helpLoadCR0.call(this, reg);\n this.nStepCycles -= 10;\n break;\n case 0x2:\n this.regCR2 = reg;\n this.nStepCycles -= 4;\n break;\n case 0x3:\n X86.helpLoadCR3.call(this, reg);\n this.nStepCycles -= 5;\n break;\n default:\n X86.opUndefined.call(this);\n return;\n }\n\n /*\n * TODO: Implement BACKTRACK for this instruction (although Control registers are not likely to be a conduit for interesting data).\n */\n};\n\n/**\n * opMOVdr()\n *\n * op=0x0F,0x23 (MOV dbgreg,reg)\n *\n * NOTE: Since this instruction uses only 32-bit general-purpose registers, our ModRM decoders\n * are going to be more hindrance than help, so we fully decode and execute the instruction ourselves.\n *\n * @this {CPUX86}\n */\nX86.opMOVdr = function()\n{\n /*\n * NOTE: The following code shouldn't need to also test X86.PS.VM, because V86-mode is CPL 3.\n */\n if (this.nCPL) {\n /*\n * You're not allowed to write control registers if the current privilege level is not zero.\n */\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n\n var bModRM = this.getIPByte();\n var iDst = (bModRM & 0x38) >> 3;\n\n if (iDst == 4 || iDst == 5) {\n X86.opUndefined.call(this);\n return;\n }\n\n var regDR = this.getReg(bModRM & 0x7);\n\n if (regDR != this.regDR[iDst]) {\n this.checkDebugRegisters(false);\n this.regDR[iDst] = regDR;\n this.checkDebugRegisters(true);\n }\n\n this.nStepCycles -= (iDst < 4? 22 : 14);\n\n /*\n * TODO: Implement BACKTRACK for this instruction (although Debug registers are not likely to be a conduit for interesting data).\n */\n};\n\n/**\n * opMOVrt()\n *\n * op=0x0F,0x24 (MOV reg,tstreg)\n *\n * NOTE: Since this instruction uses only 32-bit general-purpose registers, our ModRM decoders\n * are going to be more hindrance than help, so we fully decode and execute the instruction ourselves.\n *\n * @this {CPUX86}\n */\nX86.opMOVrt = function()\n{\n /*\n * NOTE: The following code shouldn't need to also test X86.PS.VM, because V86-mode is CPL 3.\n */\n if (this.nCPL) {\n /*\n * You're not allowed to read control registers if the current privilege level is not zero.\n */\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n\n var bModRM = this.getIPByte();\n var iSrc = (bModRM & 0x38) >> 3;\n\n /*\n * Only TR6 and TR7 are defined, and only for the 80386 and 80486. From the PC Magazine Prog. TechRef, p.64:\n *\n * \"The 80386 provides two 32-bit test registers, TR6 and TR7, as a mechanism for programmers to verify proper\n * operation of the Translation Lookaside Buffer (TLB) when power is applied to the chip. The TLB is a cache used\n * internally by the 80386 to translate linear addresses to physical addresses.\"\n */\n if (iSrc < 6) {\n X86.opUndefined.call(this);\n return;\n }\n\n this.setReg(bModRM & 0x7, this.regTR[iSrc]);\n this.nStepCycles -= 12;\n\n /*\n * TODO: Implement BACKTRACK for this instruction (although Test registers are not likely to be a conduit for interesting data).\n */\n};\n\n/**\n * opMOVtr()\n *\n * op=0x0F,0x26 (MOV tstreg,reg)\n *\n * NOTE: Since this instruction uses only 32-bit general-purpose registers, our ModRM decoders\n * are going to be more hindrance than help, so we fully decode and execute the instruction ourselves.\n *\n * @this {CPUX86}\n */\nX86.opMOVtr = function()\n{\n /*\n * NOTE: The following code shouldn't need to also test X86.PS.VM, because V86-mode is CPL 3.\n */\n if (this.nCPL) {\n /*\n * You're not allowed to write control registers if the current privilege level is not zero.\n */\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n\n var bModRM = this.getIPByte();\n var iDst = (bModRM & 0x38) >> 3;\n\n /*\n * Only TR6 and TR7 are defined, and only for the 80386 and 80486. From the PC Magazine Prog. TechRef, p.64:\n *\n * \"The 80386 provides two 32-bit test registers, TR6 and TR7, as a mechanism for programmers to verify proper\n * operation of the Translation Lookaside Buffer (TLB) when power is applied to the chip. The TLB is a cache used\n * internally by the 80386 to translate linear addresses to physical addresses.\"\n */\n if (iDst < 6) {\n X86.opUndefined.call(this);\n return;\n }\n\n /*\n * TODO: Do something useful with the Test registers.\n */\n this.regTR[iDst] = this.getReg(bModRM & 0x7);\n\n this.nStepCycles -= 12;\n\n /*\n * TODO: Implement BACKTRACK for this instruction (although Test registers are not likely to be a conduit for interesting data).\n */\n};\n\n/*\n * NOTE: The following 16 new conditional jumps actually rely on the OPERAND override setting\n * for determining whether a signed 16-bit or 32-bit displacement will be fetched, even though\n * the ADDRESS override might seem more intuitive. Think of them as instructions that are loading\n * a new operand into IP/EIP.\n *\n * Also, in 16-bit code, even though a signed rel16 value would seem to imply a range of -32768\n * to +32767, any location within a 64Kb code segment outside that range can be reached by choosing\n * a displacement in the opposite direction, causing the 16-bit value in EIP to underflow or overflow;\n * any underflow or overflow doesn't matter, because only the low 16 bits of EIP are updated when a\n * 16-bit OPERAND size is in effect.\n *\n * In fact, for 16-bit jumps, it's simpler to always think of rel16 as an UNSIGNED value added to\n * the current EIP, where the result is then truncated to a 16-bit value. This is why we don't have\n * to sign-extend rel16 before adding it to the current EIP.\n */\n\n/**\n * opJOw()\n *\n * op=0x0F,0x80 (JO rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJOw = function()\n{\n var disp = this.getIPWord();\n if (this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJNOw()\n *\n * op=0x0F,0x81 (JNO rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJNOw = function()\n{\n var disp = this.getIPWord();\n if (!this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJCw()\n *\n * op=0x0F,0x82 (JC rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJCw = function()\n{\n var disp = this.getIPWord();\n if (this.getCF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJNCw()\n *\n * op=0x0F,0x83 (JNC rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJNCw = function()\n{\n var disp = this.getIPWord();\n if (!this.getCF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJZw()\n *\n * op=0x0F,0x84 (JZ rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJZw = function()\n{\n var disp = this.getIPWord();\n if (this.getZF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJNZw()\n *\n * op=0x0F,0x85 (JNZ rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJNZw = function()\n{\n var disp = this.getIPWord();\n if (!this.getZF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJBEw()\n *\n * op=0x0F,0x86 (JBE rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJBEw = function()\n{\n var disp = this.getIPWord();\n if (this.getCF() || this.getZF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJNBEw()\n *\n * op=0x0F,0x87 (JNBE rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJNBEw = function()\n{\n var disp = this.getIPWord();\n if (!this.getCF() && !this.getZF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJSw()\n *\n * op=0x0F,0x88 (JS rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJSw = function()\n{\n var disp = this.getIPWord();\n if (this.getSF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJNSw()\n *\n * op=0x0F,0x89 (JNS rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJNSw = function()\n{\n var disp = this.getIPWord();\n if (!this.getSF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJPw()\n *\n * op=0x0F,0x8A (JP rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJPw = function()\n{\n var disp = this.getIPWord();\n if (this.getPF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJNPw()\n *\n * op=0x0F,0x8B (JNP rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJNPw = function()\n{\n var disp = this.getIPWord();\n if (!this.getPF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJLw()\n *\n * op=0x0F,0x8C (JL rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJLw = function()\n{\n var disp = this.getIPWord();\n if (!this.getSF() != !this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJNLw()\n *\n * op=0x0F,0x8D (JNL rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJNLw = function()\n{\n var disp = this.getIPWord();\n if (!this.getSF() == !this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJLEw()\n *\n * op=0x0F,0x8E (JLE rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJLEw = function()\n{\n var disp = this.getIPWord();\n if (this.getZF() || !this.getSF() != !this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJNLEw()\n *\n * op=0x0F,0x8F (JNLE rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJNLEw = function()\n{\n var disp = this.getIPWord();\n if (!this.getZF() && !this.getSF() == !this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opSETO()\n *\n * op=0x0F,0x90 (SETO b)\n *\n * @this {CPUX86}\n */\nX86.opSETO = function()\n{\n X86.helpSETcc.call(this, X86.fnSETO);\n};\n\n/**\n * opSETNO()\n *\n * op=0x0F,0x91 (SETNO b)\n *\n * @this {CPUX86}\n */\nX86.opSETNO = function()\n{\n X86.helpSETcc.call(this, X86.fnSETO);\n};\n\n/**\n * opSETC()\n *\n * op=0x0F,0x92 (SETC b)\n *\n * @this {CPUX86}\n */\nX86.opSETC = function()\n{\n X86.helpSETcc.call(this, X86.fnSETC);\n};\n\n/**\n * opSETNC()\n *\n * op=0x0F,0x93 (SETNC b)\n *\n * @this {CPUX86}\n */\nX86.opSETNC = function()\n{\n X86.helpSETcc.call(this, X86.fnSETNC);\n};\n\n/**\n * opSETZ()\n *\n * op=0x0F,0x94 (SETZ b)\n *\n * @this {CPUX86}\n */\nX86.opSETZ = function()\n{\n X86.helpSETcc.call(this, X86.fnSETZ);\n};\n\n/**\n * opSETNZ()\n *\n * op=0x0F,0x95 (SETNZ b)\n *\n * @this {CPUX86}\n */\nX86.opSETNZ = function()\n{\n X86.helpSETcc.call(this, X86.fnSETNZ);\n};\n\n/**\n * opSETBE()\n *\n * op=0x0F,0x96 (SETBE b)\n *\n * @this {CPUX86}\n */\nX86.opSETBE = function()\n{\n X86.helpSETcc.call(this, X86.fnSETBE);\n};\n\n/**\n * opSETNBE()\n *\n * op=0x0F,0x97 (SETNBE b)\n *\n * @this {CPUX86}\n */\nX86.opSETNBE = function()\n{\n X86.helpSETcc.call(this, X86.fnSETNBE);\n};\n\n/**\n * opSETS()\n *\n * op=0x0F,0x98 (SETS b)\n *\n * @this {CPUX86}\n */\nX86.opSETS = function()\n{\n X86.helpSETcc.call(this, X86.fnSETS);\n};\n\n/**\n * opSETNS()\n *\n * op=0x0F,0x99 (SETNS b)\n *\n * @this {CPUX86}\n */\nX86.opSETNS = function()\n{\n X86.helpSETcc.call(this, X86.fnSETNS);\n};\n\n/**\n * opSETP()\n *\n * op=0x0F,0x9A (SETP b)\n *\n * @this {CPUX86}\n */\nX86.opSETP = function()\n{\n X86.helpSETcc.call(this, X86.fnSETP);\n};\n\n/**\n * opSETNP()\n *\n * op=0x0F,0x9B (SETNP b)\n *\n * @this {CPUX86}\n */\nX86.opSETNP = function()\n{\n X86.helpSETcc.call(this, X86.fnSETNP);\n};\n\n/**\n * opSETL()\n *\n * op=0x0F,0x9C (SETL b)\n *\n * @this {CPUX86}\n */\nX86.opSETL = function()\n{\n X86.helpSETcc.call(this, X86.fnSETL);\n};\n\n/**\n * opSETNL()\n *\n * op=0x0F,0x9D (SETNL b)\n *\n * @this {CPUX86}\n */\nX86.opSETNL = function()\n{\n X86.helpSETcc.call(this, X86.fnSETNL);\n};\n\n/**\n * opSETLE()\n *\n * op=0x0F,0x9E (SETLE b)\n *\n * @this {CPUX86}\n */\nX86.opSETLE = function()\n{\n X86.helpSETcc.call(this, X86.fnSETLE);\n};\n\n/**\n * opSETNLE()\n *\n * op=0x0F,0x9F (SETNLE b)\n *\n * @this {CPUX86}\n */\nX86.opSETNLE = function()\n{\n X86.helpSETcc.call(this, X86.fnSETNLE);\n};\n\n/**\n * opPUSHFS()\n *\n * op=0x0F,0xA0 (PUSH FS)\n *\n * @this {CPUX86}\n */\nX86.opPUSHFS = function()\n{\n /*\n * When the OPERAND size is 32 bits, the 80386 will decrement the stack pointer by 4, write the selector\n * into the 2 lower bytes, and leave the 2 upper bytes untouched; to properly emulate that, we must use the\n * more generic pushData() instead of pushWord().\n */\n if (!I386) {\n this.pushWord(this.segFS.sel);\n } else {\n this.pushData(this.segFS.sel, this.sizeData, 2);\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushSeg;\n};\n\n/**\n * opPOPFS()\n *\n * op=0x0F,0xA1 (POP FS)\n *\n * @this {CPUX86}\n */\nX86.opPOPFS = function()\n{\n /*\n * Any operation that modifies the stack before loading a new segment must snapshot regLSP first.\n */\n this.opLSP = this.regLSP;\n this.setFS(this.popWord());\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n this.opLSP = X86.ADDR_INVALID;\n};\n\n/**\n * opBT()\n *\n * op=0x0F,0xA3 (BT mem/reg,reg)\n *\n * @this {CPUX86}\n */\nX86.opBT = function()\n{\n this.decodeModMemWord.call(this, X86.fnBTMem);\n if (this.regEA !== X86.ADDR_INVALID) this.nStepCycles -= 6;\n};\n\n/**\n * opSHLDn()\n *\n * op=0x0F,0xA4 (SHLD mem/reg,reg,imm8)\n *\n * @this {CPUX86}\n */\nX86.opSHLDn = function()\n{\n this.decodeModMemWord.call(this, this.sizeData == 2? X86.fnSHLDwi : X86.fnSHLDdi);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 7);\n};\n\n/**\n * opSHLDcl()\n *\n * op=0x0F,0xA5 (SHLD mem/reg,reg,CL)\n *\n * @this {CPUX86}\n */\nX86.opSHLDcl = function()\n{\n this.decodeModMemWord.call(this, this.sizeData == 2? X86.fnSHLDwCL : X86.fnSHLDdCL);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 7);\n};\n\n/**\n * opXBTS()\n *\n * op=0x0F,0xA6 (XBTS reg,mem/reg,[E]AX,CL)\n *\n * @this {CPUX86}\n */\nX86.opXBTS = function()\n{\n this.decodeModRegWord.call(this, X86.fnXBTS);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 6 : 13);\n};\n\n/**\n * opIBTS()\n *\n * op=0x0F,0xA7 (IBTS mem/reg,[E]AX,CL,reg)\n *\n * @this {CPUX86}\n */\nX86.opIBTS = function()\n{\n this.decodeModMemWord.call(this, X86.fnIBTS);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 12 : 19);\n};\n\n/**\n * opPUSHGS()\n *\n * op=0x0F,0xA8 (PUSH GS)\n *\n * @this {CPUX86}\n */\nX86.opPUSHGS = function()\n{\n /*\n * When the OPERAND size is 32 bits, the 80386 will decrement the stack pointer by 4, write the selector\n * into the 2 lower bytes, and leave the 2 upper bytes untouched; to properly emulate that, we must use the\n * more generic pushData() instead of pushWord().\n */\n if (!I386) {\n this.pushWord(this.segGS.sel);\n } else {\n this.pushData(this.segGS.sel, this.sizeData, 2);\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushSeg;\n};\n\n/**\n * opPOPGS()\n *\n * op=0x0F,0xA9 (POP GS)\n *\n * @this {CPUX86}\n */\nX86.opPOPGS = function()\n{\n /*\n * Any operation that modifies the stack before loading a new segment must snapshot regLSP first.\n */\n this.opLSP = this.regLSP;\n this.setGS(this.popWord());\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n this.opLSP = X86.ADDR_INVALID;\n};\n\n/**\n * opBTS()\n *\n * op=0x0F,0xAB (BTC mem/reg,reg)\n *\n * @this {CPUX86}\n */\nX86.opBTS = function()\n{\n this.decodeModMemWord.call(this, X86.fnBTSMem);\n if (this.regEA !== X86.ADDR_INVALID) this.nStepCycles -= 5;\n};\n\n/**\n * opSHRDn()\n *\n * op=0x0F,0xAC (SHRD mem/reg,reg,imm8)\n *\n * @this {CPUX86}\n */\nX86.opSHRDn = function()\n{\n this.decodeModMemWord.call(this, this.sizeData == 2? X86.fnSHRDwi : X86.fnSHRDdi);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 7);\n};\n\n/**\n * opSHRDcl()\n *\n * op=0x0F,0xAD (SHRD mem/reg,reg,CL)\n *\n * @this {CPUX86}\n */\nX86.opSHRDcl = function()\n{\n this.decodeModMemWord.call(this, this.sizeData == 2? X86.fnSHRDwCL : X86.fnSHRDdCL);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 7);\n};\n\n/**\n * opIMUL()\n *\n * op=0x0F,0xAF (IMUL reg,mem/reg) (80386 and up)\n *\n * @this {CPUX86}\n */\nX86.opIMUL = function()\n{\n this.decodeModRegWord.call(this, this.sizeData == 2? X86.fnIMULrw : X86.fnIMULrd);\n};\n\n/**\n * opLSS()\n *\n * op=0x0F,0xB2 (LSS reg,word)\n *\n * This is like a \"MOV reg,rm\" operation, but it also loads SS from the next word.\n *\n * @this {CPUX86}\n */\nX86.opLSS = function()\n{\n this.decodeModRegWord.call(this, X86.fnLSS);\n};\n\n/**\n * opBTR()\n *\n * op=0x0F,0xB3 (BTC mem/reg,reg) (80386 and up)\n *\n * @this {CPUX86}\n */\nX86.opBTR = function()\n{\n this.decodeModMemWord.call(this, X86.fnBTRMem);\n if (this.regEA !== X86.ADDR_INVALID) this.nStepCycles -= 5;\n};\n\n/**\n * opLFS()\n *\n * op=0x0F,0xB4 (LFS reg,word)\n *\n * This is like a \"MOV reg,rm\" operation, but it also loads FS from the next word.\n *\n * @this {CPUX86}\n */\nX86.opLFS = function()\n{\n this.decodeModRegWord.call(this, X86.fnLFS);\n};\n\n/**\n * opLGS()\n *\n * op=0x0F,0xB5 (LGS reg,word)\n *\n * This is like a \"MOV reg,rm\" operation, but it also loads GS from the next word.\n *\n * @this {CPUX86}\n */\nX86.opLGS = function()\n{\n this.decodeModRegWord.call(this, X86.fnLGS);\n};\n\n/**\n * opMOVZXb()\n *\n * op=0x0F,0xB6 (MOVZX reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opMOVZXb = function()\n{\n this.decodeModRegByte.call(this, X86.fnMOVXb);\n var reg = (this.bModRM >> 3) & 0x7;\n switch(reg) {\n case 0x0:\n this.regEAX = (this.regEAX & ~this.maskData) | (this.regEAX & 0xff);\n break;\n case 0x1:\n this.regECX = (this.regECX & ~this.maskData) | (this.regECX & 0xff);\n break;\n case 0x2:\n this.regEDX = (this.regEDX & ~this.maskData) | (this.regEDX & 0xff);\n break;\n case 0x3:\n this.regEBX = (this.regEBX & ~this.maskData) | (this.regEBX & 0xff);\n break;\n case 0x4:\n this.regESP = (this.regESP & ~this.maskData) | ((this.regEAX >> 8) & 0xff);\n this.regEAX = this.regXX;\n break;\n case 0x5:\n this.regEBP = (this.regEBP & ~this.maskData) | ((this.regECX >> 8) & 0xff);\n this.regECX = this.regXX;\n break;\n case 0x6:\n this.regESI = (this.regESI & ~this.maskData) | ((this.regEDX >> 8) & 0xff);\n this.regEDX = this.regXX;\n break;\n case 0x7:\n this.regEDI = (this.regEDI & ~this.maskData) | ((this.regEBX >> 8) & 0xff);\n this.regEBX = this.regXX;\n break;\n }\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 6);\n};\n\n/**\n * opMOVZXw()\n *\n * op=0x0F,0xB7 (MOVZX reg,word)\n *\n * @this {CPUX86}\n */\nX86.opMOVZXw = function()\n{\n this.setDataSize(2);\n this.decodeModRegWord.call(this, X86.fnMOVXw);\n switch((this.bModRM >> 3) & 0x7) {\n case 0x0:\n this.regEAX = (this.regEAX & 0xffff);\n break;\n case 0x1:\n this.regECX = (this.regECX & 0xffff);\n break;\n case 0x2:\n this.regEDX = (this.regEDX & 0xffff);\n break;\n case 0x3:\n this.regEBX = (this.regEBX & 0xffff);\n break;\n case 0x4:\n this.regESP = (this.regESP & 0xffff);\n break;\n case 0x5:\n this.regEBP = (this.regEBP & 0xffff);\n break;\n case 0x6:\n this.regESI = (this.regESI & 0xffff);\n break;\n case 0x7:\n this.regEDI = (this.regEDI & 0xffff);\n break;\n }\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 6);\n};\n\n/**\n * op=0x0F,0xBA (GRP8 mem/reg) (80386 and up)\n *\n * @this {CPUX86}\n */\nX86.opGRP8 = function()\n{\n this.decodeModGrpWord.call(this, X86.aOpGrp8, this.getIPByte);\n};\n\n/**\n * opBTC()\n *\n * op=0x0F,0xBB (BTC mem/reg,reg)\n *\n * @this {CPUX86}\n */\nX86.opBTC = function()\n{\n this.decodeModMemWord.call(this, X86.fnBTCMem);\n if (this.regEA !== X86.ADDR_INVALID) this.nStepCycles -= 5;\n};\n\n/**\n * opBSF()\n *\n * op=0x0F,0xBC (BSF reg,mem/reg)\n *\n * @this {CPUX86}\n */\nX86.opBSF = function()\n{\n this.decodeModRegWord.call(this, X86.fnBSF);\n};\n\n/**\n * opBSR()\n *\n * op=0x0F,0xBD (BSR reg,mem/reg)\n *\n * @this {CPUX86}\n */\nX86.opBSR = function()\n{\n this.decodeModRegWord.call(this, X86.fnBSR);\n};\n\n/**\n * opMOVSXb()\n *\n * op=0x0F,0xBE (MOVSX reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opMOVSXb = function()\n{\n this.decodeModRegByte.call(this, X86.fnMOVXb);\n var reg = (this.bModRM >> 3) & 0x7;\n switch(reg) {\n case 0x0:\n this.regEAX = (this.regEAX & ~this.maskData) | ((((this.regEAX & 0xff) << 24) >> 24) & this.maskData);\n break;\n case 0x1:\n this.regECX = (this.regECX & ~this.maskData) | ((((this.regECX & 0xff) << 24) >> 24) & this.maskData);\n break;\n case 0x2:\n this.regEDX = (this.regEDX & ~this.maskData) | ((((this.regEDX & 0xff) << 24) >> 24) & this.maskData);\n break;\n case 0x3:\n this.regEBX = (this.regEBX & ~this.maskData) | ((((this.regEBX & 0xff) << 24) >> 24) & this.maskData);\n break;\n case 0x4:\n this.regESP = (this.regESP & ~this.maskData) | (((this.regEAX << 16) >> 24) & this.maskData);\n this.regEAX = this.regXX;\n break;\n case 0x5:\n this.regEBP = (this.regEBP & ~this.maskData) | (((this.regECX << 16) >> 24) & this.maskData);\n this.regECX = this.regXX;\n break;\n case 0x6:\n this.regESI = (this.regESI & ~this.maskData) | (((this.regEDX << 16) >> 24) & this.maskData);\n this.regEDX = this.regXX;\n break;\n case 0x7:\n this.regEDI = (this.regEDI & ~this.maskData) | (((this.regEBX << 16) >> 24) & this.maskData);\n this.regEBX = this.regXX;\n break;\n }\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 6);\n};\n\n/**\n * opMOVSXw()\n *\n * op=0x0F,0xBF (MOVSX reg,word)\n *\n * @this {CPUX86}\n */\nX86.opMOVSXw = function()\n{\n this.setDataSize(2);\n this.decodeModRegWord.call(this, X86.fnMOVXw);\n switch((this.bModRM >> 3) & 0x7) {\n case 0x0:\n this.regEAX = ((this.regEAX << 16) >> 16);\n break;\n case 0x1:\n this.regECX = ((this.regECX << 16) >> 16);\n break;\n case 0x2:\n this.regEDX = ((this.regEDX << 16) >> 16);\n break;\n case 0x3:\n this.regEBX = ((this.regEBX << 16) >> 16);\n break;\n case 0x4:\n this.regESP = ((this.regESP << 16) >> 16);\n break;\n case 0x5:\n this.regEBP = ((this.regEBP << 16) >> 16);\n break;\n case 0x6:\n this.regESI = ((this.regESI << 16) >> 16);\n break;\n case 0x7:\n this.regEDI = ((this.regEDI << 16) >> 16);\n break;\n }\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 6);\n};\n\nX86.aOps0F = new Array(256);\n\nX86.aOps0F[0x00] = X86.opGRP6;\nX86.aOps0F[0x01] = X86.opGRP7;\nX86.aOps0F[0x02] = X86.opLAR;\nX86.aOps0F[0x03] = X86.opLSL;\nX86.aOps0F[0x05] = X86.opLOADALL286;\nX86.aOps0F[0x06] = X86.opCLTS;\n\n/*\n * On all processors (except the 8086/8088, of course), X86.OPCODE.UD2 (0x0F,0x0B), aka \"UD2\", is an\n * instruction guaranteed to raise a #UD (Invalid Opcode) exception (INT 0x06) on all post-8086 processors.\n */\nX86.aOps0F[0x0B] = X86.opInvalid;\n\n/*\n * The following 0x0F opcodes are of no consequence to us, since they were all introduced post-80386;\n * 0x0F,0xA6 and 0x0F,0xA7 were introduced on some 80486 processors (and then deprecated), while 0x0F,0xB0\n * and 0x0F,0xB1 were introduced on 80586 (aka Pentium) processors.\n *\n * CMPXCHG r/m8,reg8 ; 0F B0 /r [PENT]\n * CMPXCHG r/m16,reg16 ; o16 0F B1 /r [PENT]\n * CMPXCHG r/m32,reg32 ; o32 0F B1 /r [PENT]\n * CMPXCHG486 r/m8,reg8 ; 0F A6 /r [486,UNDOC]\n * CMPXCHG486 r/m16,reg16 ; o16 0F A7 /r [486,UNDOC]\n * CMPXCHG486 r/m32,reg32 ; o32 0F A7 /r [486,UNDOC]\n *\n * So why are we even mentioning them here? Only because some software (eg, Windows 3.00) attempts to execute\n * 0x0F,0xA6, so we need to explicitly mark it as invalid. TODO: Purely out of curiosity, I would like to\n * eventually learn *why* Windows 3.00 does this; is it hoping to use the CMPXCHG486 opcode, or is it performing\n * a CPU/stepping check to detect/work-around some errata, or....?\n */\nX86.aOps0F[0xA6] = X86.opInvalid;\n\n/*\n * When Windows 95 Setup initializes in protected-mode, it sets a DPMI exception handler for UD_FAULT and\n * then attempts to generate that exception with undefined opcode 0x0F,0xFF. Apparently, whoever wrote that code\n * didn't get the Intel memo regarding the preferred invalid opcode (0x0F,0x0B, aka UD2), or perhaps Intel hadn't\n * written that memo yet -- although if that's the case, then Intel should have followed Microsoft's lead and\n * selected 0x0F,0xFF instead of 0x0F,0x0B.\n *\n * In any case, this means we need to explicitly set the handler for that opcode to opInvalid(), too.\n */\nX86.aOps0F[0xFF] = X86.opInvalid;\n\n/*\n * NOTE: Any other opcode slots NOT explicitly initialized above with either a dedicated function OR opInvalid()\n * will be set to opUndefined() when initProcessor() finalizes the opcode tables. If the processor is an 80386,\n * initProcessor() will also incorporate all the handlers listed below in aOps0F386.\n *\n * A call to opUndefined() implies something serious has occurred that merits our attention (eg, perhaps someone\n * is using an undocumented opcode that we haven't implemented yet), whereas a call to opInvalid() may or may not.\n */\n\nif (I386) {\n X86.aOps0F386 = [];\n X86.aOps0F386[0x05] = X86.opInvalid; // the 80286 LOADALL opcode (LOADALL286) is invalid on the 80386\n X86.aOps0F386[0x07] = X86.opLOADALL386;\n X86.aOps0F386[0x10] = X86.opMOVmb; // see the undocumented [UMOV](/docs/x86/ops/UMOV/) instruction\n X86.aOps0F386[0x11] = X86.opMOVmw; // see the undocumented [UMOV](/docs/x86/ops/UMOV/) instruction\n X86.aOps0F386[0x12] = X86.opMOVrb; // see the undocumented [UMOV](/docs/x86/ops/UMOV/) instruction\n X86.aOps0F386[0x13] = X86.opMOVrw; // see the undocumented [UMOV](/docs/x86/ops/UMOV/) instruction\n X86.aOps0F386[0x20] = X86.opMOVrc;\n X86.aOps0F386[0x21] = X86.opMOVrd;\n X86.aOps0F386[0x22] = X86.opMOVcr;\n X86.aOps0F386[0x23] = X86.opMOVdr;\n X86.aOps0F386[0x24] = X86.opMOVrt;\n X86.aOps0F386[0x26] = X86.opMOVtr;\n X86.aOps0F386[0x80] = X86.opJOw;\n X86.aOps0F386[0x81] = X86.opJNOw;\n X86.aOps0F386[0x82] = X86.opJCw;\n X86.aOps0F386[0x83] = X86.opJNCw;\n X86.aOps0F386[0x84] = X86.opJZw;\n X86.aOps0F386[0x85] = X86.opJNZw;\n X86.aOps0F386[0x86] = X86.opJBEw;\n X86.aOps0F386[0x87] = X86.opJNBEw;\n X86.aOps0F386[0x88] = X86.opJSw;\n X86.aOps0F386[0x89] = X86.opJNSw;\n X86.aOps0F386[0x8A] = X86.opJPw;\n X86.aOps0F386[0x8B] = X86.opJNPw;\n X86.aOps0F386[0x8C] = X86.opJLw;\n X86.aOps0F386[0x8D] = X86.opJNLw;\n X86.aOps0F386[0x8E] = X86.opJLEw;\n X86.aOps0F386[0x8F] = X86.opJNLEw;\n X86.aOps0F386[0x90] = X86.opSETO;\n X86.aOps0F386[0x91] = X86.opSETNO;\n X86.aOps0F386[0x92] = X86.opSETC;\n X86.aOps0F386[0x93] = X86.opSETNC;\n X86.aOps0F386[0x94] = X86.opSETZ;\n X86.aOps0F386[0x95] = X86.opSETNZ;\n X86.aOps0F386[0x96] = X86.opSETBE;\n X86.aOps0F386[0x97] = X86.opSETNBE;\n X86.aOps0F386[0x98] = X86.opSETS;\n X86.aOps0F386[0x99] = X86.opSETNS;\n X86.aOps0F386[0x9A] = X86.opSETP;\n X86.aOps0F386[0x9B] = X86.opSETNP;\n X86.aOps0F386[0x9C] = X86.opSETL;\n X86.aOps0F386[0x9D] = X86.opSETNL;\n X86.aOps0F386[0x9E] = X86.opSETLE;\n X86.aOps0F386[0x9F] = X86.opSETNLE;\n X86.aOps0F386[0xA0] = X86.opPUSHFS;\n X86.aOps0F386[0xA1] = X86.opPOPFS;\n X86.aOps0F386[0xA3] = X86.opBT;\n X86.aOps0F386[0xA4] = X86.opSHLDn;\n X86.aOps0F386[0xA5] = X86.opSHLDcl;\n X86.aOps0F386[0xA8] = X86.opPUSHGS;\n X86.aOps0F386[0xA9] = X86.opPOPGS;\n X86.aOps0F386[0xAB] = X86.opBTS;\n X86.aOps0F386[0xAC] = X86.opSHRDn;\n X86.aOps0F386[0xAD] = X86.opSHRDcl;\n X86.aOps0F386[0xAF] = X86.opIMUL;\n X86.aOps0F386[0xB2] = X86.opLSS;\n X86.aOps0F386[0xB3] = X86.opBTR;\n X86.aOps0F386[0xB4] = X86.opLFS;\n X86.aOps0F386[0xB5] = X86.opLGS;\n X86.aOps0F386[0xB6] = X86.opMOVZXb;\n X86.aOps0F386[0xB7] = X86.opMOVZXw;\n X86.aOps0F386[0xBA] = X86.opGRP8;\n X86.aOps0F386[0xBB] = X86.opBTC;\n X86.aOps0F386[0xBC] = X86.opBSF;\n X86.aOps0F386[0xBD] = X86.opBSR;\n X86.aOps0F386[0xBE] = X86.opMOVSXb;\n X86.aOps0F386[0xBF] = X86.opMOVSXw;\n}\n\n/*\n * These instruction groups are not as orthogonal as the original 8086/8088 groups (Grp1 through Grp4); some of\n * the instructions in Grp6 and Grp7 only read their dst operand (eg, LLDT), which means the ModRM helper function\n * must insure that setEAWord() is disabled, while others only write their dst operand (eg, SLDT), which means that\n * getEAWord() should be disabled *prior* to calling the ModRM helper function. This latter case requires that\n * we decode the reg field of the ModRM byte before dispatching.\n */\nX86.aOpGrp6Prot = [\n X86.fnSLDT, X86.fnSTR, X86.fnLLDT, X86.fnLTR, // 0x0F,0x00(reg=0x0-0x3)\n X86.fnVERR, X86.fnVERW, X86.fnGRPUndefined, X86.fnGRPUndefined // 0x0F,0x00(reg=0x4-0x7)\n];\n\nX86.aOpGrp6Real = [\n X86.fnGRPInvalid, X86.fnGRPInvalid, X86.fnGRPInvalid, X86.fnGRPInvalid, // 0x0F,0x00(reg=0x0-0x3)\n X86.fnGRPInvalid, X86.fnGRPInvalid, X86.fnGRPUndefined, X86.fnGRPUndefined // 0x0F,0x00(reg=0x4-0x7)\n];\n\n/*\n * Unlike Grp6, Grp7 and Grp8 do not require separate real-mode and protected-mode dispatch tables, because\n * all Grp7 and Grp8 instructions are valid in both modes.\n */\nX86.aOpGrp7 = [\n X86.fnSGDT, X86.fnSIDT, X86.fnLGDT, X86.fnLIDT, // 0x0F,0x01(reg=0x0-0x3)\n X86.fnSMSW, X86.fnGRPUndefined, X86.fnLMSW, X86.fnGRPUndefined // 0x0F,0x01(reg=0x4-0x7)\n];\n\nX86.aOpGrp8 = [\n X86.fnGRPUndefined, X86.fnGRPUndefined, X86.fnGRPUndefined, X86.fnGRPUndefined, // 0x0F,0xBA(reg=0x0-0x3)\n X86.fnBT, X86.fnBTS, X86.fnBTR, X86.fnBTC // 0x0F,0xBA(reg=0x4-0x7)\n];\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/chipset.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * class ChipSet\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass ChipSet extends Component {\n /**\n * ChipSet(parmsChipSet)\n *\n * The ChipSet component has the following component-specific (parmsChipSet) properties:\n *\n * model: eg, \"5150\", \"5160\", \"5170\", \"deskpro386\" (should be a member of ChipSet.MODELS)\n * sw1: 8-character binary string representing the SW1 DIP switches (SW1[1-8]); see Switches Overview\n * sw2: 8-character binary string representing the SW2 DIP switches (SW2[1-8]) (MODEL_5150 only)\n * sound: true (or non-zero) to enable sounds (default), false (or 0) to disable; number used as initial volume\n * scaleTimers: true to divide timer cycle counts by the CPU's cycle multiplier (default is false)\n * floppies: array of floppy drive sizes in Kb (default is \"[360, 360]\" if no sw1 value provided)\n * monitor: none|tv|color|mono|ega|vga (if no sw1 value provided, default is \"ega\" for 5170, \"mono\" otherwise)\n * dateRTC: optional RTC date/time (in GMT) to use on reset; use the ISO 8601 format; eg: \"2014-10-01T08:00:00\"\n *\n * TODO: As support for IBM-compatible machines grows, we should refrain from adding new model strings (eg, \"att6300\")\n * and corresponding model checks, and instead add more ChipSet configuration properties, such as:\n *\n * portPIT1: 0x48 to enable PIT1 at base port 0x48 (as used by COMPAQ_DESKPRO386); default to undefined\n * chipKBD: 8041 to select 8041 emulation (eg, for ATT_6300); default to 8255 for MODEL_5150/MODEL_5160, 8042 for MODEL_5170\n *\n * @this {ChipSet}\n * @param {Object} parmsChipSet\n */\n constructor(parmsChipSet)\n {\n super(\"ChipSet\", parmsChipSet, Messages.CHIPSET);\n\n let model = parmsChipSet['model'];\n\n /*\n * this.model is a numeric version of the 'model' string; when comparing this.model to standard IBM\n * model numbers, you should generally compare (this.model|0) to the target value, which truncates it.\n */\n if (model && !ChipSet.MODELS[model]) {\n Component.notice(\"Unrecognized ChipSet model: \" + model);\n }\n\n this.model = ChipSet.MODELS[model] || ChipSet.MODEL_5150_OTHER;\n\n let bSwitches;\n this.aDIPSwitches = [];\n\n /*\n * SW1 describes the number of floppy drives, the amount of base memory, the primary monitor type,\n * and (on the MODEL_5160) whether or not a coprocessor is installed. If no SW1 settings are provided,\n * we look for individual 'floppies' and 'monitor' settings and build a default SW1 value.\n *\n * The defaults below select max memory, monochrome monitor (EGA monitor for MODEL_5170), and two floppies.\n * Don't get too excited about \"max memory\" either: on a MODEL_5150, the max was 64Kb, and on a MODEL_5160,\n * the max was 256Kb. However, the RAM component is free to install as much base memory as it likes,\n * overriding the SW1 memory setting.\n *\n * Given that the ROM BIOS is hard-coded to load boot sectors @0000:7C00, the minimum amount of system RAM\n * required to boot is therefore 32Kb. Whether that's actually enough to run any or all versions of PC-DOS is\n * a separate question. FYI, with only 16Kb, the ROM BIOS will still try to boot, and fail miserably.\n */\n bSwitches = this.parseDIPSwitches(parmsChipSet[ChipSet.CONTROLS.SW1]);\n this.aDIPSwitches[0] = [bSwitches, bSwitches];\n\n if (bSwitches == null) {\n this.aFloppyDrives = [360, 360];\n let aFloppyDrives = parmsChipSet['floppies'];\n if (aFloppyDrives && aFloppyDrives.length) this.aFloppyDrives = aFloppyDrives;\n this.setDIPSwitches(ChipSet.SWITCH_TYPE.FLOPNUM, this.aFloppyDrives.length);\n\n let sMonitor = parmsChipSet['monitor'] || (this.model < ChipSet.MODEL_5170? \"mono\" : \"ega\");\n this.setDIPSwitches(ChipSet.SWITCH_TYPE.MONITOR, sMonitor);\n }\n\n /*\n * SW2 describes the number of 32Kb blocks of I/O expansion RAM that's present in the system. The MODEL_5150\n * ROM BIOS only checked/supported the first four switches, so the maximum amount of additional RAM specifiable\n * was 15 * 32Kb, or 480Kb. So with a 16Kb-64Kb motherboard, the MODEL_5150 ROM BIOS could support a grand\n * total of 544Kb. With the 64Kb-256Kb motherboard revision, a 5150 could use the first FIVE SW2 switches,\n * allowing for a grand total as high as 640Kb.\n *\n * For MODEL_5160 (PC XT) and up, memory expansion cards had their own switches, and the motherboard\n * SW2 switches for I/O expansion RAM were eliminated. Instead, the ROM BIOS scans the entire address space\n * (up to 0xA0000) looking for additional memory. As a result, the only mechanism we provide for adding RAM\n * (above the maximum of 256Kb supported on the motherboard) is the \"size\" parameter of the RAM component.\n *\n * NOTE: If you use the \"size\" parameter, you will not be able to dynamically alter the memory configuration;\n * the RAM component will ignore any changes to SW1.\n */\n bSwitches = this.parseDIPSwitches(parmsChipSet[ChipSet.CONTROLS.SW2]);\n this.aDIPSwitches[1] = [bSwitches, bSwitches];\n\n this.sCellClass = PCX86.CSSCLASS + \"-bitCell\";\n\n this.cDMACs = this.cPICs = 1;\n if (this.model >= ChipSet.MODEL_5170) {\n this.cDMACs = this.cPICs = 2;\n }\n\n this.fScaleTimers = parmsChipSet['scaleTimers'] || false;\n this.sDateRTC = parmsChipSet['dateRTC'];\n\n /*\n * Here, I'm finally getting around to trying the Web Audio API. Fortunately, based on what little\n * I know about sound generation, using the API to make the same noises as the IBM PC speaker seems\n * straightforward.\n *\n * To start, we create an audio context, unless the 'sound' parameter has been explicitly set to false\n * or 0; the boolean value true (along with any illegal number) now defaults to 0.5 instead of 1.0.\n */\n this.volumeInit = 0;\n let sound = parmsChipSet['sound'];\n if (sound) {\n this.volumeInit = (typeof sound != \"number\" || sound < 0 || sound > 1)? 0.5 : sound;\n this.classAudio = this.contextAudio = null;\n if (window) {\n this.classAudio = window['AudioContext'] || window['webkitAudioContext'];\n }\n if (this.classAudio) {\n this.contextAudio = new this.classAudio();\n } else {\n if (DEBUG) this.log(\"AudioContext not available\");\n }\n }\n /*\n * fSpeakerEnabled indicates whether the speaker is *logically* on, whereas fSpeakerOn indicates\n * whether we have ACTUALLY turned the speaker on. And finally, fUserSound is set to true only after\n * we have have created the audio oscillator in the context of a user event (a requirement for most\n * browsers before they'll actually emit any sound).\n */\n this.fSpeakerEnabled = this.fSpeakerOn = this.fUserSound = false;\n\n /*\n * I used to defer ChipSet's reset() to powerUp(), which then gave us the option of doing either\n * reset() OR restore(), instead of both. However, on MODEL_5170 machines, the initial CMOS data\n * needs to be created earlier, so that when other components are initializing their state (eg, when\n * HDC calls setCMOSDriveType() or RAM calls addCMOSMemory()), the CMOS will be ready to take their calls.\n */\n this.reset(true);\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {ChipSet}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.cmp = cmp;\n\n this.fpu = cmp.getMachineComponent(\"FPU\");\n this.setDIPSwitches(ChipSet.SWITCH_TYPE.FPU, this.fpu? 1 : 0, true);\n\n this.kbd = cmp.getMachineComponent(\"Keyboard\");\n\n let sound = cmp.getMachineParm(\"sound\");\n if (sound != null) {\n let volume = +sound || 0;\n this.volumeInit = (sound == \"true\" || volume < 0 || volume > 1? 0.5 : volume);\n }\n if (!this.volumeInit) this.println(\"note: speaker disabled\");\n\n /*\n * This divisor is invariant, so we calculate it as soon as we're able to query the CPU's base speed.\n */\n this.nTicksDivisor = (cpu.getBaseCyclesPerSecond() / ChipSet.TIMER_TICKS_PER_SEC);\n\n bus.addPortInputTable(this, ChipSet.aPortInput);\n bus.addPortOutputTable(this, ChipSet.aPortOutput);\n if (this.model == ChipSet.MODEL_4860) {\n bus.addPortInputTable(this, ChipSet.aPortInput4860);\n bus.addPortOutputTable(this, ChipSet.aPortOutput4860);\n }\n else {\n bus.addPortInputTable(this, ChipSet.aPortInput5xxx);\n bus.addPortOutputTable(this, ChipSet.aPortOutput5xxx);\n if (this.model < ChipSet.MODEL_5170) {\n if (this.model == ChipSet.MODEL_ATT_6300) {\n bus.addPortInputTable(this, ChipSet.aPortInput6300);\n bus.addPortOutputTable(this, ChipSet.aPortOutput6300);\n } else {\n bus.addPortInputTable(this, ChipSet.aPortInput5150);\n bus.addPortOutputTable(this, ChipSet.aPortOutput5150);\n }\n } else {\n bus.addPortInputTable(this, ChipSet.aPortInput5170);\n bus.addPortOutputTable(this, ChipSet.aPortOutput5170);\n if (DESKPRO386 && (this.model|0) == ChipSet.MODEL_COMPAQ_DESKPRO386) {\n bus.addPortInputTable(this, ChipSet.aPortInputDeskPro386);\n bus.addPortOutputTable(this, ChipSet.aPortOutputDeskPro386);\n }\n }\n }\n if (DEBUGGER) {\n if (dbg) {\n let chipset = this;\n /*\n * TODO: Add more \"dumpers\" (eg, for DMA, RTC, 8042, etc)\n */\n dbg.messageDump(Messages.PIC, function onDumpPIC() {\n chipset.dumpPIC();\n });\n dbg.messageDump(Messages.TIMER, function onDumpTimer(asArgs) {\n chipset.dumpTimer(asArgs);\n });\n if (this.model >= ChipSet.MODEL_5170) {\n dbg.messageDump(Messages.CMOS, function onDumpCMOS() {\n chipset.dumpCMOS();\n });\n }\n }\n cpu.addIntNotify(Interrupts.RTC, this.intBIOSRTC.bind(this));\n }\n this.setReady();\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {ChipSet}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"sw1\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n switch (sBinding) {\n\n case ChipSet.CONTROLS.SW1:\n this.bindings[sBinding] = control;\n this.addDIPSwitches(0, sBinding);\n return true;\n\n case ChipSet.CONTROLS.SW2:\n if ((this.model|0) == ChipSet.MODEL_5150 || this.model == ChipSet.MODEL_ATT_6300) {\n this.bindings[sBinding] = control;\n this.addDIPSwitches(1, sBinding);\n return true;\n }\n break;\n\n case ChipSet.CONTROLS.SWDESC:\n this.bindings[sBinding] = control;\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {ChipSet}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {ChipSet}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset(fHard)\n *\n * @this {ChipSet}\n * @param {boolean} [fHard] true on the initial reset (not a normal \"soft\" reset)\n */\n reset(fHard)\n {\n /*\n * We propagate the initial DIP switch values to the current DIP switch values on reset;\n * the user is only allowed to tweak the initial values, which require a reset to take effect.\n */\n let i;\n this.updateDIPSwitches();\n\n /*\n * DMA (Direct Memory Access) Controller initialization\n */\n this.aDMACs = new Array(this.cDMACs);\n for (i = 0; i < this.cDMACs; i++) {\n this.initDMAController(i);\n }\n\n /*\n * PIC (Programmable Interupt Controller) initialization\n */\n this.aPICs = new Array(this.cPICs);\n this.initPIC(ChipSet.PIC0.INDEX, ChipSet.PIC0.PORT_LO);\n if (this.cPICs > 1) {\n this.initPIC(ChipSet.PIC1.INDEX, ChipSet.PIC1.PORT_LO);\n }\n\n /*\n * PIT (Programmable Interval Timer) initialization\n *\n * Although the DeskPro 386 refers to the timers in the first PIT as \"Timer 1, Counter 0\",\n * \"Timer 1, Counter 1\" and \"Timer 1, Counter 2\", we're sticking with IBM's nomenclature:\n * TIMER0, TIMER1 and TIMER2. Which means that we refer to the \"counters\" in the second PIT\n * as TIMER3, TIMER4 and TIMER5; that numbering also matches their indexes in the aTimers array.\n */\n this.bPIT0Ctrl = null; // tracks writes to port 0x43\n this.bPIT1Ctrl = null; // tracks writes to port 0x4B (MODEL_COMPAQ_DESKPRO386 only)\n this.aTimers = new Array((this.model|0) == ChipSet.MODEL_COMPAQ_DESKPRO386? 6 : 3);\n for (i = 0; i < this.aTimers.length; i++) {\n this.initTimer(i);\n }\n\n /*\n * PPI and other misc ports\n */\n this.bPPIA = null; // tracks writes to port 0x60, in case PPI_CTRL.A_IN is not set\n this.bPPIB = null; // tracks writes to port 0x61, in case PPI_CTRL.B_IN is not set\n this.bPPIC = null; // tracks writes to port 0x62, in case PPI_CTRL.C_IN_LO or PPI_CTRL.C_IN_HI is not set\n this.bPPICtrl = null; // tracks writes to port 0x63 (eg, 0x99); read-only\n this.bNMI = ChipSet.NMI.RESET; // tracks writes to the NMI Mask Register\n this.bKbdData = 0; // records last byte received via receiveKbdData(); for machines without an 8042 (eg, PC/PC XT/PCjr)\n\n if (this.model == ChipSet.MODEL_ATT_6300) {\n this.b8041Status = 0; // similar to b8042Status (but apparently only bits 0 and 1 are used)\n }\n\n /*\n * ChipSet state introduced by the MODEL_5170\n */\n if (this.model >= ChipSet.MODEL_5170) {\n /*\n * The 8042 input buffer is treated as a \"command byte\" when written via port 0x64 and as a \"data byte\"\n * when written via port 0x60. So, whenever the C8042.CMD.WRITE_CMD \"command byte\" is written to the input\n * buffer, the subsequent command data byte is saved in b8042CmdData. Similarly, for C8042.CMD.WRITE_OUTPORT,\n * the subsequent data byte is saved in b8042OutPort.\n *\n * TODO: Consider a UI for the Keyboard INHIBIT switch. By default, our keyboard is never inhibited\n * (ie, locked). Also, note that the hardware changes this bit only when new data is sent to b8042OutBuff.\n */\n this.b8042Status = ChipSet.C8042.STATUS.NO_INHIBIT;\n this.b8042InBuff = 0;\n this.b8042CmdData = ChipSet.C8042.DATA.CMD.NO_CLOCK;\n this.b8042OutBuff = 0;\n\n /*\n * TODO: Provide more control over these 8042 \"Input Port\" bits (eg, the keyboard lock)\n */\n this.b8042InPort = ChipSet.C8042.INPORT.MFG_OFF | ChipSet.C8042.INPORT.KBD_UNLOCKED;\n\n if (this.getDIPMemorySize() >= 512) {\n this.b8042InPort |= ChipSet.C8042.INPORT.ENABLE_256KB;\n }\n\n if (this.getDIPVideoMonitor() == ChipSet.MONITOR.MONO) {\n this.b8042InPort |= ChipSet.C8042.INPORT.MONO;\n }\n\n if (DESKPRO386 && (this.model|0) == ChipSet.MODEL_COMPAQ_DESKPRO386) {\n this.b8042InPort |= ChipSet.C8042.INPORT.COMPAQ_NO80387 | ChipSet.C8042.INPORT.COMPAQ_NOWEITEK;\n }\n\n this.b8042OutPort = ChipSet.C8042.OUTPORT.NO_RESET | ChipSet.C8042.OUTPORT.A20_ON;\n\n this.abDMAPageSpare = new Array(8);\n\n this.bCMOSAddr = 0; // NMI is enabled, since the ChipSet.CMOS.ADDR.NMI_DISABLE bit is not set in bCMOSAddr\n\n /*\n * Now that we call reset() from the ChipSet constructor, enabling other components to update\n * their own CMOS information as needed, we must distinguish between the initial (\"hard\") reset\n * and any later (\"soft\") resets (eg, from powerUp() calls), and make sure the latter preserves\n * existing CMOS information.\n */\n if (fHard) {\n this.abCMOSData = new Array(ChipSet.CMOS.ADDR.TOTAL);\n }\n\n this.initRTCTime(this.sDateRTC);\n\n /*\n * initCMOSData() will initialize a variety of \"legacy\" CMOS bytes, but it will NOT overwrite any memory\n * size or hard drive type information that might have been set, via addCMOSMemory() or setCMOSDriveType().\n */\n this.initCMOSData();\n }\n\n if (DEBUGGER && MAXDEBUG) {\n /*\n * Arrays for interrupt counts (one count per IRQ) and timer data\n */\n this.acInterrupts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n this.acTimersFired = [0, 0, 0];\n this.acTimer0Counts = [];\n }\n }\n\n /**\n * initRTCTime(sDate)\n *\n * Initialize the RTC portion of the CMOS registers to match the specified date/time (or if none is specified,\n * the current date/time). The date/time should be expressed in the ISO 8601 format; eg: \"2011-10-10T14:48:00\".\n *\n * NOTE: There are two approaches we could take here: always store the RTC bytes in binary, and convert them\n * to/from BCD on-demand (ie, as the simulation reads/writes the CMOS RTC registers); or init/update them in the\n * format specified by CMOS.STATUSB.BINARY (1 for binary, 0 for BCD). Both approaches require BCD conversion\n * functions, but the former seems more efficient, in part because the periodic calls to updateRTCTime() won't\n * require any conversions.\n *\n * We take the same approach with the CMOS.STATUSB.HOUR24 setting: internally, we always operate in 24-hour mode,\n * but externally, we convert the RTC hour values to the 12-hour format as needed.\n *\n * Thus, all I/O to the RTC bytes must be routed through the getRTCByte() and setRTCByte() functions, to ensure\n * that all the necessary on-demand conversions occur.\n *\n * @this {ChipSet}\n * @param {string} [sDate]\n */\n initRTCTime(sDate)\n {\n /*\n * NOTE: I've already been burned once by a JavaScript library function that did NOT treat an undefined\n * parameter (ie, a parameter === undefined) the same as an omitted parameter (eg, the async parameter in\n * xmlHTTP.open() in IE), so I'm taking no chances here: if sDate is undefined, then explicitly call Date()\n * with no parameters.\n */\n let date = sDate? new Date(sDate) : new Date();\n\n /*\n * Example of a valid Date string:\n *\n * 2014-10-01T08:00:00 (interpreted as GMT, resulting in \"Wed Oct 01 2014 01:00:00 GMT-0700 (PDT)\")\n *\n * Examples of INVALID Date strings:\n *\n * 2014-10-01T08:00:00PST\n * 2014-10-01T08:00:00-0700 (actually, this DOES work in Chrome, but NOT in Safari)\n *\n * In the case of INVALID Date strings, the Date object is invalid, but there's no obvious test for an \"invalid\"\n * object, so I've adapted the following test from StackOverflow.\n *\n * See http://stackoverflow.com/questions/1353684/detecting-an-invalid-date-date-instance-in-javascript\n */\n if (Object.prototype.toString.call(date) !== \"[object Date]\" || isNaN(date.getTime())) {\n date = new Date();\n this.println(\"CMOS date invalid (\" + sDate + \"), using \" + date);\n } else if (sDate) {\n this.println(\"CMOS date: \" + date);\n }\n\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_SEC] = date.getSeconds();\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_SEC_ALRM] = 0;\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MIN] = date.getMinutes();\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MIN_ALRM] = 0;\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_HOUR] = date.getHours();\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_HOUR_ALRM] = 0;\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_WEEK_DAY] = date.getDay() + 1;\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MONTH_DAY] = date.getDate();\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MONTH] = date.getMonth() + 1;\n let nYear = date.getFullYear();\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_YEAR] = nYear % 100;\n let nCentury = (nYear / 100);\n this.abCMOSData[ChipSet.CMOS.ADDR.CENTURY_DATE] = (nCentury % 10) | ((nCentury / 10) << 4);\n\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSA] = 0x26; // hard-coded default; refer to ChipSet.CMOS.STATUSA.DV and ChipSet.CMOS.STATUSA.RS\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] = ChipSet.CMOS.STATUSB.HOUR24; // default to BCD mode (ChipSet.CMOS.STATUSB.BINARY not set)\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSC] = 0x00;\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSD] = ChipSet.CMOS.STATUSD.VRB;\n\n this.nRTCCyclesLastUpdate = this.nRTCCyclesNextUpdate = 0;\n this.nRTCPeriodsPerSecond = this.nRTCCyclesPerPeriod = null;\n }\n\n /**\n * getRTCByte(iRTC)\n *\n * @param {number} iRTC\n * @return {number} b\n */\n getRTCByte(iRTC)\n {\n\n\n let b = this.abCMOSData[iRTC];\n\n if (iRTC < ChipSet.CMOS.ADDR.STATUSA) {\n let f12HourValue = false;\n if (iRTC == ChipSet.CMOS.ADDR.RTC_HOUR || iRTC == ChipSet.CMOS.ADDR.RTC_HOUR_ALRM) {\n if (!(this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.HOUR24)) {\n if (b < 12) {\n b = (!b? 12 : b);\n } else {\n b -= 12;\n b = (!b? 0x8c : b + 0x80);\n }\n f12HourValue = true;\n }\n }\n if (!(this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.BINARY)) {\n /*\n * We're in BCD mode, so we must convert b from BINARY to BCD. But first:\n *\n * If b is a 12-hour value (ie, we're in 12-hour mode) AND the hour is a PM value\n * (ie, in the range 0x81-0x8C), then it must be adjusted to yield 81-92 in BCD.\n *\n * AM hour values (0x01-0x0C) need no adjustment; they naturally convert to 01-12 in BCD.\n */\n if (f12HourValue && b > 0x80) {\n b -= (0x81 - 81);\n }\n b = (b % 10) | ((b / 10) << 4);\n }\n } else {\n if (iRTC == ChipSet.CMOS.ADDR.STATUSA) {\n /*\n * Make sure that the \"Update-In-Progress\" bit we set in updateRTCTime() doesn't stay set for\n * more than one read.\n */\n this.abCMOSData[iRTC] &= ~ChipSet.CMOS.STATUSA.UIP;\n }\n }\n return b;\n }\n\n /**\n * setRTCByte(iRTC, b)\n *\n * @param {number} iRTC\n * @param {number} b proposed byte to write\n * @return {number} actual byte to write\n */\n setRTCByte(iRTC, b)\n {\n\n\n if (iRTC < ChipSet.CMOS.ADDR.STATUSA) {\n let fBCD = false;\n if (!(this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.BINARY)) {\n /*\n * We're in BCD mode, so we must convert b from BCD to BINARY (we assume it's valid\n * BCD; ie, that both nibbles contain only 0-9, not A-F).\n */\n b = (b >> 4) * 10 + (b & 0xf);\n fBCD = true;\n }\n if (iRTC == ChipSet.CMOS.ADDR.RTC_HOUR || iRTC == ChipSet.CMOS.ADDR.RTC_HOUR_ALRM) {\n if (fBCD) {\n /*\n * If the original BCD hour was 0x81-0x92, then the previous BINARY-to-BCD conversion\n * transformed it to 0x51-0x5C, so we must add 0x30.\n */\n if (b > 23) {\n\n b += 0x30;\n }\n }\n if (!(this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.HOUR24)) {\n if (b <= 12) {\n b = (b == 12? 0 : b);\n } else {\n b -= (0x80 - 12);\n b = (b == 24? 12 : b);\n }\n }\n }\n }\n return b;\n }\n\n /**\n * calcRTCCyclePeriod()\n *\n * This should be called whenever the timings in STATUSA may have changed.\n *\n * TODO: 1024 is a hard-coded number of periods per second based on the default interrupt rate of 976.562us\n * (ie, 1000000 / 976.562). Calculate the actual number based on the values programmed in the STATUSA register.\n *\n * @this {ChipSet}\n */\n calcRTCCyclePeriod()\n {\n this.nRTCCyclesLastUpdate = this.cpu.getCycles(this.fScaleTimers);\n this.nRTCPeriodsPerSecond = 1024;\n this.nRTCCyclesPerPeriod = Math.floor(this.cpu.getBaseCyclesPerSecond() / this.nRTCPeriodsPerSecond);\n this.setRTCCycleLimit();\n }\n\n /**\n * getRTCCycleLimit(nCycles)\n *\n * This is called by the CPU to determine the maximum number of cycles it can process for the current burst.\n *\n * @this {ChipSet}\n * @param {number} nCycles desired\n * @return {number} maximum number of cycles (<= nCycles)\n */\n getRTCCycleLimit(nCycles)\n {\n if (this.abCMOSData && this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.PIE) {\n let nCyclesUpdate = this.nRTCCyclesNextUpdate - this.cpu.getCycles(this.fScaleTimers);\n if (nCyclesUpdate > 0) {\n if (nCycles > nCyclesUpdate) {\n if (DEBUG && this.messageEnabled(Messages.RTC)) {\n this.printMessage(\"getRTCCycleLimit(\" + nCycles + \"): reduced to \" + nCyclesUpdate + \" cycles\", true);\n }\n nCycles = nCyclesUpdate;\n } else {\n if (DEBUG && this.messageEnabled(Messages.RTC)) {\n this.printMessage(\"getRTCCycleLimit(\" + nCycles + \"): already less than \" + nCyclesUpdate + \" cycles\", true);\n }\n }\n } else {\n if (DEBUG && this.messageEnabled(Messages.RTC)) {\n this.printMessage(\"RTC next update has passed by \" + nCyclesUpdate + \" cycles\", true);\n }\n }\n }\n return nCycles;\n }\n\n /**\n * setRTCCycleLimit()\n *\n * This should be called when PIE becomes set in STATUSB (and whenever PF is cleared in STATUSC while PIE is still set).\n *\n * @this {ChipSet}\n */\n setRTCCycleLimit()\n {\n let nCycles = this.nRTCCyclesPerPeriod;\n this.nRTCCyclesNextUpdate = this.cpu.getCycles(this.fScaleTimers) + nCycles;\n if (this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.PIE) {\n this.cpu.setBurstCycles(nCycles);\n }\n }\n\n /**\n * updateRTCTime()\n *\n * @this {ChipSet}\n */\n updateRTCTime()\n {\n let nCyclesPerSecond = this.cpu.getBaseCyclesPerSecond();\n let nCyclesUpdate = this.cpu.getCycles(this.fScaleTimers);\n\n /*\n * We must arrange for the very first calcRTCCyclePeriod() call to occur here, on the very first\n * updateRTCTime() call, because this is the first point we can be guaranteed that CPU cycle counts\n * are initialized (the CPU is the last component to be powered up/restored).\n *\n * TODO: A side-effect of this is that it undermines the save/restore code's preservation of last\n * and next RTC cycle counts, which may affect when the next RTC event is delivered.\n */\n if (this.nRTCCyclesPerPeriod == null) this.calcRTCCyclePeriod();\n\n /*\n * Step 1: Deal with Periodic Interrupts\n */\n if (nCyclesUpdate >= this.nRTCCyclesNextUpdate) {\n let bPrev = this.abCMOSData[ChipSet.CMOS.ADDR.STATUSC];\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSC] |= ChipSet.CMOS.STATUSC.PF;\n if (this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.PIE) {\n /*\n * When PIE is set, setBurstCycles() should be getting called as needed to ensure\n * that updateRTCTime() is called more frequently, so let's assert that we don't have\n * an excess of cycles and thus possibly some missed Periodic Interrupts.\n */\n if (DEBUG) {\n if (nCyclesUpdate - this.nRTCCyclesNextUpdate > this.nRTCCyclesPerPeriod) {\n if (bPrev & ChipSet.CMOS.STATUSC.PF) {\n this.printMessage(\"RTC interrupt handler failed to clear STATUSC\", Messages.RTC);\n } else {\n this.printMessage(\"CPU took too long trigger new RTC periodic interrupt\", Messages.RTC);\n }\n }\n }\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSC] |= ChipSet.CMOS.STATUSC.IRQF;\n this.setIRR(ChipSet.IRQ.RTC);\n /*\n * We could also call setRTCCycleLimit() at this point, but I don't think there's any\n * benefit until the interrupt had been acknowledged and STATUSC has been read, thereby\n * clearing the way for another Periodic Interrupt; it seems to me that when STATUSC\n * is read, that's the more appropriate time to call setRTCCycleLimit().\n */\n }\n this.nRTCCyclesNextUpdate = nCyclesUpdate + this.nRTCCyclesPerPeriod;\n }\n\n /*\n * Step 2: Deal with Alarm Interrupts\n */\n if (this.abCMOSData[ChipSet.CMOS.ADDR.RTC_SEC] == this.abCMOSData[ChipSet.CMOS.ADDR.RTC_SEC_ALRM]) {\n if (this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MIN] == this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MIN_ALRM]) {\n if (this.abCMOSData[ChipSet.CMOS.ADDR.RTC_HOUR] == this.abCMOSData[ChipSet.CMOS.ADDR.RTC_HOUR_ALRM]) {\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSC] |= ChipSet.CMOS.STATUSC.AF;\n if (this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.AIE) {\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSC] |= ChipSet.CMOS.STATUSC.IRQF;\n this.setIRR(ChipSet.IRQ.RTC);\n }\n }\n }\n }\n\n /*\n * Step 3: Update the RTC date/time and deal with Update Interrupts\n */\n let nCyclesDelta = nCyclesUpdate - this.nRTCCyclesLastUpdate;\n // DEBUG:\n let nSecondsDelta = Math.floor(nCyclesDelta / nCyclesPerSecond);\n\n /*\n * We trust that updateRTCTime() is being called as part of updateAllTimers(), and is therefore\n * being called often enough to ensure that nSecondsDelta will never be greater than one. In fact,\n * it would always be LESS than one if it weren't also for the fact that we plow any \"unused\" cycles\n * (nCyclesDelta % nCyclesPerSecond) back into nRTCCyclesLastUpdate, so that we will eventually\n * see a one-second delta.\n */\n // DEBUG:\n\n /*\n * Make sure that CMOS.STATUSB.SET isn't set; if it is, then the once-per-second RTC updates must be\n * disabled so that software can write new RTC date/time values without interference.\n */\n if (nSecondsDelta && !(this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.SET)) {\n while (nSecondsDelta--) {\n if (++this.abCMOSData[ChipSet.CMOS.ADDR.RTC_SEC] >= 60) {\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_SEC] = 0;\n if (++this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MIN] >= 60) {\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MIN] = 0;\n if (++this.abCMOSData[ChipSet.CMOS.ADDR.RTC_HOUR] >= 24) {\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_HOUR] = 0;\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_WEEK_DAY] = (this.abCMOSData[ChipSet.CMOS.ADDR.RTC_WEEK_DAY] % 7) + 1;\n let nDayMax = Usr.getMonthDays(this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MONTH], this.abCMOSData[ChipSet.CMOS.ADDR.RTC_YEAR]);\n if (++this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MONTH_DAY] > nDayMax) {\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MONTH_DAY] = 1;\n if (++this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MONTH] > 12) {\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MONTH] = 1;\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_YEAR] = (this.abCMOSData[ChipSet.CMOS.ADDR.RTC_YEAR] + 1) % 100;\n }\n }\n }\n }\n }\n }\n\n /*\n * Obviously, setting the \"Update-In-Progress\" bit now might seem rather pointless, since we just\n * updated the RTC \"atomically\" as far as the machine is concerned; however, the bit must be set at\n * at some point, in order to make the MODEL_5170 BIOS (\"POST2_RTCUP\") happy.\n */\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSA] |= ChipSet.CMOS.STATUSA.UIP;\n\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSC] |= ChipSet.CMOS.STATUSC.UF;\n if (this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.UIE) {\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSC] |= ChipSet.CMOS.STATUSC.IRQF;\n this.setIRR(ChipSet.IRQ.RTC);\n }\n }\n\n this.nRTCCyclesLastUpdate = nCyclesUpdate - (nCyclesDelta % nCyclesPerSecond);\n }\n\n /**\n * initCMOSData()\n *\n * Initialize all the CMOS configuration bytes in the range 0x0E-0x2F (TODO: Decide what to do about 0x30-0x3F)\n *\n * Note that the MODEL_5170 \"SETUP\" utility is normally what sets all these bytes, including the checksum, and then\n * the BIOS verifies it, but since we want our machines to pass BIOS verification \"out of the box\", we go the extra\n * mile here, even though it's not really our responsibility.\n *\n * @this {ChipSet}\n */\n initCMOSData()\n {\n /*\n * On all reset() calls, the RAM component(s) will (re)add their totals, so we have to make sure that\n * the addition always starts with 0. That also means that ChipSet must always be initialized before RAM.\n */\n let iCMOS;\n for (iCMOS = ChipSet.CMOS.ADDR.BASEMEM_LO; iCMOS <= ChipSet.CMOS.ADDR.EXTMEM_HI; iCMOS++) {\n this.abCMOSData[iCMOS] = 0;\n }\n\n /*\n * Make sure all the \"checksummed\" CMOS bytes are initialized (not just the handful we set below) to ensure\n * that the checksum will be valid.\n */\n for (iCMOS = ChipSet.CMOS.ADDR.DIAG; iCMOS < ChipSet.CMOS.ADDR.CHKSUM_HI; iCMOS++) {\n if (this.abCMOSData[iCMOS] === undefined) this.abCMOSData[iCMOS] = 0;\n }\n\n /*\n * We propagate all compatible \"legacy\" SW1 bits to the CMOS.EQUIP byte using the old SW masks, but any further\n * access to CMOS.ADDR.EQUIP should use the new CMOS_EQUIP flags (eg, CMOS.EQUIP.FPU, CMOS.EQUIP.MONITOR.CGA80, etc).\n */\n this.abCMOSData[ChipSet.CMOS.ADDR.EQUIP] = this.getDIPLegacyBits(0);\n this.abCMOSData[ChipSet.CMOS.ADDR.FDRIVE] = (this.getDIPFloppyDriveType(0) << 4) | this.getDIPFloppyDriveType(1);\n\n /*\n * The final step is calculating the CMOS checksum, which we then store into the CMOS as a courtesy, so that the\n * user doesn't get unnecessary CMOS errors.\n */\n this.updateCMOSChecksum();\n }\n\n /**\n * setCMOSByte(iCMOS, b)\n *\n * This is ONLY for use by components that need to update CMOS configuration bytes to match their internal configuration.\n *\n * @this {ChipSet}\n * @param {number} iCMOS\n * @param {number} b\n * @return {boolean} true if successful, false if not (eg, CMOS not initialized yet, or no CMOS on this machine)\n */\n setCMOSByte(iCMOS, b)\n {\n if (this.abCMOSData) {\n\n this.abCMOSData[iCMOS] = b;\n this.updateCMOSChecksum();\n return true;\n }\n return false;\n }\n\n /**\n * addCMOSMemory(addr, size)\n *\n * For use by the RAM component, to dynamically update the CMOS memory configuration.\n *\n * @this {ChipSet}\n * @param {number} addr (if 0, BASEMEM_LO/BASEMEM_HI is updated; if >= 0x100000, then EXTMEM_LO/EXTMEM_HI is updated)\n * @param {number} size (in bytes; we convert to Kb)\n * @return {boolean} true if successful, false if not (eg, CMOS not initialized yet, or no CMOS on this machine)\n */\n addCMOSMemory(addr, size)\n {\n if (this.abCMOSData) {\n let iCMOS = (addr < 0x100000? ChipSet.CMOS.ADDR.BASEMEM_LO : ChipSet.CMOS.ADDR.EXTMEM_LO);\n let wKb = this.abCMOSData[iCMOS] | (this.abCMOSData[iCMOS+1] << 8);\n wKb += (size >> 10);\n this.abCMOSData[iCMOS] = wKb & 0xff;\n this.abCMOSData[iCMOS+1] = wKb >> 8;\n this.updateCMOSChecksum();\n return true;\n }\n return false;\n }\n\n /**\n * setCMOSDriveType(iDrive, bType)\n *\n * For use by the HDC component, to update the CMOS drive configuration to match HDC's internal configuration.\n *\n * TODO: Consider extending this to support FDC drive updates, so that the FDC can specify diskette drive types\n * (ie, FD360 or FD1200) in the same way that HDC does. However, historically, the ChipSet has been responsible for\n * floppy drive configuration, at least in terms of *number* of drives, through the use of SW1 settings, and we've\n * continued that tradition with the addition of the ChipSet 'floppies' parameter, which allows both the number *and*\n * capacity of drives to be specified with a simple array (eg, [360, 360] for two 360Kb drives).\n *\n * @this {ChipSet}\n * @param {number} iDrive (0 or 1)\n * @param {number} bType (0 for none, 1-14 for original drive type, 16-255 for extended drive type; 15 reserved)\n * @return {boolean} true if successful, false if not (eg, CMOS not initialized yet, or no CMOS on this machine)\n */\n setCMOSDriveType(iDrive, bType)\n {\n if (this.abCMOSData) {\n let bExt = null, iExt;\n let bOrig = this.abCMOSData[ChipSet.CMOS.ADDR.HDRIVE];\n if (bType > 15) {\n bExt = bType; bType = 15;\n }\n if (iDrive) {\n bOrig = (bOrig & ChipSet.CMOS.HDRIVE.D0_MASK) | bType;\n iExt = ChipSet.CMOS.ADDR.EXTHDRIVE1;\n } else {\n bOrig = (bOrig & ChipSet.CMOS.HDRIVE.D1_MASK) | (bType << 4);\n iExt = ChipSet.CMOS.ADDR.EXTHDRIVE0;\n }\n this.setCMOSByte(ChipSet.CMOS.ADDR.HDRIVE, bOrig);\n if (bExt != null) this.setCMOSByte(iExt, bExt);\n return true;\n }\n return false;\n }\n\n /**\n * updateCMOSChecksum()\n *\n * This sums all the CMOS bytes from 0x10-0x2D, creating a 16-bit checksum. That's a total of 30 (unsigned) 8-bit\n * values which could sum to at most 30*255 or 7650 (0x1DE2). Since there's no way that can overflow 16 bits, we don't\n * worry about masking it with 0xffff.\n *\n * WARNING: The IBM PC AT TechRef, p.1-53 (p.75) claims that the checksum is on bytes 0x10-0x20, but that's simply wrong.\n *\n * @this {ChipSet}\n */\n updateCMOSChecksum()\n {\n let wChecksum = 0;\n for (let iCMOS = ChipSet.CMOS.ADDR.FDRIVE; iCMOS < ChipSet.CMOS.ADDR.CHKSUM_HI; iCMOS++) {\n wChecksum += this.abCMOSData[iCMOS];\n }\n this.abCMOSData[ChipSet.CMOS.ADDR.CHKSUM_LO] = wChecksum & 0xff;\n this.abCMOSData[ChipSet.CMOS.ADDR.CHKSUM_HI] = wChecksum >> 8;\n }\n\n /**\n * save()\n *\n * This implements save support for the ChipSet component.\n *\n * @this {ChipSet}\n * @return {Object}\n */\n save()\n {\n let state = new State(this);\n state.set(0, [this.aDIPSwitches]);\n state.set(1, [this.saveDMAControllers()]);\n state.set(2, [this.savePICs()]);\n state.set(3, [this.bPIT0Ctrl, this.saveTimers(), this.bPIT1Ctrl]);\n state.set(4, [this.bPPIA, this.bPPIB, this.bPPIC, this.bPPICtrl, this.bNMI]);\n if (this.model >= ChipSet.MODEL_5170) {\n state.set(5, [this.b8042Status, this.b8042InBuff, this.b8042CmdData,\n this.b8042OutBuff, this.b8042InPort, this.b8042OutPort]);\n state.set(6, [this.abDMAPageSpare[7], this.abDMAPageSpare, this.bCMOSAddr, this.abCMOSData, this.nRTCCyclesLastUpdate, this.nRTCCyclesNextUpdate]);\n }\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the ChipSet component.\n *\n * @this {ChipSet}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n let a, i;\n a = data[0];\n\n if (Array.isArray(a[0])) {\n this.aDIPSwitches = a[0];\n } else {\n this.aDIPSwitches[0][0] = a[0];\n this.aDIPSwitches[1][0] = a[1] & 0x0F; // we do honor SW2[5] now, but it was erroneously set on some machines\n this.aDIPSwitches[0][1] = a[2];\n this.aDIPSwitches[1][1] = a[3] & 0x0F; // we do honor SW2[5] now, but it was erroneously set on some machines\n }\n this.updateDIPSwitches();\n\n a = data[1];\n for (i = 0; i < this.cDMACs; i++) {\n this.initDMAController(i, a.length == 1? a[0][i] : a);\n }\n\n a = data[2];\n for (i = 0; i < this.cPICs; i++) {\n this.initPIC(i, i === 0? ChipSet.PIC0.PORT_LO : ChipSet.PIC1.PORT_LO, a[0][i]);\n }\n\n a = data[3];\n this.bPIT0Ctrl = a[0];\n this.bPIT1Ctrl = a[2];\n for (i = 0; i < this.aTimers.length; i++) {\n this.initTimer(i, a[1][i]);\n }\n\n a = data[4];\n this.bPPIA = a[0];\n this.bPPIB = a[1];\n this.bPPIC = a[2];\n this.bPPICtrl = a[3];\n this.bNMI = a[4];\n\n a = data[5];\n if (a) {\n\n this.b8042Status = a[0];\n this.b8042InBuff = a[1];\n this.b8042CmdData = a[2];\n this.b8042OutBuff = a[3];\n this.b8042InPort = a[4];\n this.b8042OutPort = a[5];\n }\n\n a = data[6];\n if (a) {\n\n this.abDMAPageSpare = a[1];\n this.abDMAPageSpare[7] = a[0]; // formerly bMFGData\n this.bCMOSAddr = a[2];\n this.abCMOSData = a[3];\n this.nRTCCyclesLastUpdate = a[4];\n this.nRTCCyclesNextUpdate = a[5];\n /*\n * TODO: Decide whether restore() should faithfully preserve the RTC date/time that save() saved,\n * or always reinitialize the date/time, or give the user (or the machine configuration) the option.\n *\n * For now, we're always reinitializing the RTC date. Alternatively, we could selectively update\n * the CMOS bytes above, instead of overwriting them all, in which case this extra call to initRTCTime()\n * could be avoided.\n */\n this.initRTCTime();\n }\n return true;\n }\n\n /**\n * start()\n *\n * Notification from the Computer that it's starting.\n *\n * @this {ChipSet}\n */\n start()\n {\n /*\n * Currently, all we do with this notification is allow the speaker to make noise.\n */\n this.setSpeaker();\n }\n\n /**\n * stop()\n *\n * Notification from the Computer that it's stopping.\n *\n * @this {ChipSet}\n */\n stop()\n {\n /*\n * Currently, all we do with this notification is prevent the speaker from making noise.\n */\n this.setSpeaker();\n }\n\n /**\n * initDMAController(iDMAC, aState)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {Array} [aState]\n */\n initDMAController(iDMAC, aState)\n {\n let controller = this.aDMACs[iDMAC];\n if (!controller) {\n\n controller = {\n aChannels: new Array(4)\n };\n }\n let a = aState && aState.length >= 5? aState : ChipSet.aDMAControllerInit;\n controller.bStatus = a[0];\n controller.bCmd = a[1];\n controller.bReq = a[2];\n controller.bIndex = a[3];\n controller.nChannelBase = iDMAC << 2;\n for (let iChannel = 0; iChannel < controller.aChannels.length; iChannel++) {\n this.initDMAChannel(controller, iChannel, a[4][iChannel]);\n }\n controller.bTemp = a[5] || 0; // not present in older states\n this.aDMACs[iDMAC] = controller;\n }\n\n /**\n * initDMAChannel(controller, iChannel, aState)\n *\n * @this {ChipSet}\n * @param {Object} controller\n * @param {number} iChannel\n * @param {Array} [aState]\n */\n initDMAChannel(controller, iChannel, aState)\n {\n let channel = controller.aChannels[iChannel];\n if (!channel) {\n\n channel = {\n addrInit: [0,0],\n countInit: [0,0],\n addrCurrent: [0,0],\n countCurrent: [0,0]\n };\n }\n let a = aState && aState.length == 8? aState : ChipSet.aDMAChannelInit;\n channel.masked = a[0];\n channel.addrInit[0] = a[1][0]; channel.addrInit[1] = a[1][1];\n channel.countInit[0] = a[2][0]; channel.countInit[1] = a[2][1];\n channel.addrCurrent[0] = a[3][0]; channel.addrCurrent[1] = a[3][1];\n channel.countCurrent[0] = a[4][0]; channel.countCurrent[1] = a[4][1];\n channel.mode = a[5];\n channel.bPage = a[6];\n // a[7] is deprecated\n channel.controller = controller;\n channel.iChannel = iChannel;\n this.initDMAFunction(channel, a[8], a[9]);\n controller.aChannels[iChannel] = channel;\n }\n\n /**\n * initDMAFunction(channel)\n *\n * @param {Object} channel\n * @param {Component|string} [component]\n * @param {string} [sFunction]\n * @param {Object} [obj]\n * @return {*}\n */\n initDMAFunction(channel, component, sFunction, obj)\n {\n if (typeof component == \"string\") {\n component = Component.getComponentByID(component);\n }\n if (component) {\n channel.done = null;\n channel.sDevice = component.id;\n channel.sFunction = sFunction;\n channel.component = component;\n channel.fnTransfer = component[sFunction];\n channel.obj = obj;\n }\n return channel.fnTransfer;\n }\n\n /**\n * saveDMAControllers()\n *\n * @this {ChipSet}\n * @return {Array}\n */\n saveDMAControllers()\n {\n let data = [];\n for (let iDMAC = 0; iDMAC < this.aDMACs; iDMAC++) {\n let controller = this.aDMACs[iDMAC];\n data[iDMAC] = [\n controller.bStatus,\n controller.bCmd,\n controller.bReq,\n controller.bIndex,\n this.saveDMAChannels(controller),\n controller.bTemp\n ];\n }\n return data;\n }\n\n /**\n * saveDMAChannels(controller)\n *\n * @this {ChipSet}\n * @param {Object} controller\n * @return {Array}\n */\n saveDMAChannels(controller)\n {\n let data = [];\n for (let iChannel = 0; iChannel < controller.aChannels.length; iChannel++) {\n let channel = controller.aChannels[iChannel];\n data[iChannel] = [\n channel.masked,\n channel.addrInit,\n channel.countInit,\n channel.addrCurrent,\n channel.countCurrent,\n channel.mode,\n channel.bPage,\n channel.sDevice,\n channel.sFunction\n ];\n }\n return data;\n }\n\n /**\n * initPIC(iPIC, port, aState)\n *\n * @this {ChipSet}\n * @param {number} iPIC\n * @param {number} port\n * @param {Array} [aState]\n */\n initPIC(iPIC, port, aState)\n {\n let pic = this.aPICs[iPIC];\n if (!pic) {\n pic = {\n aICW: [null,null,null,null]\n };\n }\n let a = aState && aState.length == 8? aState : ChipSet.aPICInit;\n pic.port = port;\n pic.nIRQBase = iPIC << 3;\n pic.nDelay = a[0];\n pic.aICW[0] = a[1][0]; pic.aICW[1] = a[1][1]; pic.aICW[2] = a[1][2]; pic.aICW[3] = a[1][3];\n pic.nICW = a[2];\n pic.bIMR = a[3];\n pic.bIRR = a[4];\n pic.bISR = a[5];\n pic.bIRLow = a[6];\n pic.bOCW3 = a[7];\n this.aPICs[iPIC] = pic;\n }\n\n /**\n * savePICs()\n *\n * @this {ChipSet}\n * @return {Array}\n */\n savePICs()\n {\n let data = [];\n for (let iPIC = 0; iPIC < this.aPICs.length; iPIC++) {\n let pic = this.aPICs[iPIC];\n data[iPIC] = [\n pic.nDelay,\n pic.aICW,\n pic.nICW,\n pic.bIMR,\n pic.bIRR,\n pic.bISR,\n pic.bIRLow,\n pic.bOCW3\n ];\n }\n return data;\n }\n\n /**\n * initTimer(iTimer, aState)\n *\n * @this {ChipSet}\n * @param {number} iTimer\n * @param {Array} [aState]\n */\n initTimer(iTimer, aState)\n {\n let timer = this.aTimers[iTimer];\n if (!timer) {\n timer = {\n countInit: [0,0],\n countStart: [0,0],\n countCurrent: [0,0],\n countLatched: [0,0]\n };\n }\n let a = aState && aState.length >= 13? aState : ChipSet.aTimerInit;\n timer.countInit[0] = a[0][0]; timer.countInit[1] = a[0][1];\n timer.countStart[0] = a[1][0]; timer.countStart[1] = a[1][1];\n timer.countCurrent[0] = a[2][0]; timer.countCurrent[1] = a[2][1];\n timer.countLatched[0] = a[3][0]; timer.countLatched[1] = a[3][1];\n timer.bcd = a[4];\n timer.mode = a[5];\n timer.rw = a[6];\n timer.countIndex = a[7];\n timer.countBytes = a[8];\n timer.fOUT = a[9];\n timer.fCountLatched = a[10];\n timer.fCounting = a[11];\n timer.nCyclesStart = a[12];\n timer.bStatus = a[13] || 0;\n timer.fStatusLatched = a[14] || false;\n this.aTimers[iTimer] = timer;\n }\n\n /**\n * saveTimers()\n *\n * @this {ChipSet}\n * @return {Array}\n */\n saveTimers()\n {\n let data = [];\n for (let iTimer = 0; iTimer < this.aTimers.length; iTimer++) {\n let timer = this.aTimers[iTimer];\n data[iTimer] = [\n timer.countInit,\n timer.countStart,\n timer.countCurrent,\n timer.countLatched,\n timer.bcd,\n timer.mode,\n timer.rw,\n timer.countIndex,\n timer.countBytes,\n timer.fOUT,\n timer.fCountLatched,\n timer.fCounting,\n timer.nCyclesStart,\n timer.bStatus,\n timer.fStatusLatched\n ];\n }\n return data;\n }\n\n /**\n * addDIPSwitches(iDIP, sBinding)\n *\n * @this {ChipSet}\n * @param {number} iDIP (0 or 1)\n * @param {string} sBinding is the name of the control\n */\n addDIPSwitches(iDIP, sBinding)\n {\n let sHTML = \"\";\n let control = this.bindings[sBinding];\n for (let i = 1; i <= 8; i++) {\n let sCellClasses = this.sCellClass;\n if (!i) sCellClasses += \" \" + this.sCellClass + \"Left\";\n let sCellID = sBinding + \"-\" + i;\n sHTML += \"<div id=\\\"\" + sCellID + \"\\\" class=\\\"\" + sCellClasses + \"\\\" data-value=\\\"0\\\">\" + i + \"</div>\\n\";\n }\n control.innerHTML = sHTML;\n this.updateDIPSwitchControls(iDIP, sBinding, true);\n }\n\n /**\n * findDIPSwitch(iDIP, iSwitch)\n *\n * @this {ChipSet}\n * @param {number} iDIP\n * @param {number} iSwitch\n * @return {Object|null} DIPSW switchGroup containing the DIP switch's MASK, VALUES, and LABEL, or null if none\n */\n findDIPSwitch(iDIP, iSwitch)\n {\n let switchDIPs = ChipSet.DIPSW[this.model|0];\n let switchTypes = switchDIPs && switchDIPs[iDIP];\n if (switchTypes) {\n for (let iType in switchTypes) {\n let switchGroup = switchTypes[iType];\n if (switchGroup.MASK & (1 << iSwitch)) {\n return switchGroup;\n }\n }\n }\n return null;\n }\n\n /**\n * getDIPLegacyBits(iDIP)\n *\n * @this {ChipSet}\n * @param {number} iDIP\n * @return {number|undefined}\n */\n getDIPLegacyBits(iDIP)\n {\n let b;\n if (!iDIP) {\n b = 0;\n b |= (this.getDIPVideoMonitor() << ChipSet.PPI_SW.MONITOR.SHIFT) & ChipSet.PPI_SW.MONITOR.MASK;\n b |= (this.getDIPCoprocessor()? ChipSet.PPI_SW.FPU : 0);\n let nDrives = this.getDIPFloppyDrives();\n b |= (nDrives? ((((nDrives - 1) << ChipSet.PPI_SW.FDRIVE.SHIFT) & ChipSet.PPI_SW.FDRIVE.MASK) | ChipSet.PPI_SW.FDRIVE.IPL) : 0);\n }\n return b;\n }\n\n /**\n * getDIPSwitches(iType, fInit)\n *\n * @this {ChipSet}\n * @param {number} iType\n * @param {boolean} [fInit] is true for initial switch value, current value otherwise\n * @return {*|null}\n */\n getDIPSwitches(iType, fInit)\n {\n let value = null;\n let switchDIPs = ChipSet.DIPSW[this.model] || ChipSet.DIPSW[this.model|0] || ChipSet.DIPSW[ChipSet.MODEL_5150];\n for (let iDIP = 0; iDIP < switchDIPs.length; iDIP++) {\n let switchTypes = switchDIPs[iDIP];\n if (switchTypes) {\n let switchGroup = switchTypes[iType];\n if (switchGroup) {\n let bits = this.aDIPSwitches[iDIP][fInit?0:1] & switchGroup.MASK;\n for (let v in switchGroup.VALUES) {\n if (switchGroup.VALUES[v] == bits) {\n value = v;\n /*\n * We prefer numeric properties, and all switch definitions must provide them\n * if their helper functions (eg, getDIPVideoMonitor()) expect numeric properties.\n */\n if (typeof +value == 'number') break;\n }\n }\n break;\n }\n }\n }\n return value;\n }\n\n /**\n * getDIPCoprocessor(fInit)\n *\n * @this {ChipSet}\n * @param {boolean} [fInit] is true for init switch value(s) only, current value(s) otherwise\n * @return {number} 1 if installed, 0 if not\n */\n getDIPCoprocessor(fInit)\n {\n let n = /** @type {number} */ (this.getDIPSwitches(ChipSet.SWITCH_TYPE.FPU, fInit));\n return +n;\n }\n\n /**\n * getDIPFloppyDrives(fInit)\n *\n * @this {ChipSet}\n * @param {boolean} [fInit] is true for init switch value(s) only, current value(s) otherwise\n * @return {number} number of floppy drives specified by SW1 (range is 0 to 4)\n */\n getDIPFloppyDrives(fInit)\n {\n let n = /** @type {number} */ (this.getDIPSwitches(ChipSet.SWITCH_TYPE.FLOPNUM, fInit));\n return +n;\n }\n\n /**\n * getDIPFloppyDriveType(iDrive)\n *\n * @this {ChipSet}\n * @param {number} iDrive (0-based)\n * @return {number} one of the ChipSet.CMOS.FDRIVE.FD* values (FD360, FD1200, etc)\n */\n getDIPFloppyDriveType(iDrive)\n {\n if (iDrive < this.getDIPFloppyDrives()) {\n if (!this.aFloppyDrives) {\n return ChipSet.CMOS.FDRIVE.FD360;\n }\n if (iDrive < this.aFloppyDrives.length) {\n switch(this.aFloppyDrives[iDrive]) {\n case 160:\n case 180:\n case 320:\n case 360:\n return ChipSet.CMOS.FDRIVE.FD360;\n case 720:\n return ChipSet.CMOS.FDRIVE.FD720;\n case 1200:\n return ChipSet.CMOS.FDRIVE.FD1200;\n case 1440:\n return ChipSet.CMOS.FDRIVE.FD1440;\n }\n }\n\n }\n return ChipSet.CMOS.FDRIVE.NONE;\n }\n\n /**\n * getDIPFloppyDriveSize(iDrive)\n *\n * @this {ChipSet}\n * @param {number} iDrive (0-based)\n * @return {number} capacity of drive in Kb (eg, 360, 1200, 1440, etc), or 0 if none\n */\n getDIPFloppyDriveSize(iDrive)\n {\n if (iDrive < this.getDIPFloppyDrives()) {\n if (!this.aFloppyDrives) {\n return 360;\n }\n if (iDrive < this.aFloppyDrives.length) {\n return this.aFloppyDrives[iDrive];\n }\n\n }\n return 0;\n }\n\n /**\n * getDIPMemorySize(fInit)\n *\n * @this {ChipSet}\n * @param {boolean} [fInit] is true for init switch value(s) only, current value(s) otherwise\n * @return {number} number of Kb of specified memory (NOT necessarily the same as installed memory; see RAM component)\n */\n getDIPMemorySize(fInit)\n {\n let nKBLowMem = /** @type {number} */ (this.getDIPSwitches(ChipSet.SWITCH_TYPE.LOWMEM, fInit));\n let nKBExpMem = /** @type {number} */ (this.getDIPSwitches(ChipSet.SWITCH_TYPE.EXPMEM, fInit));\n return +nKBLowMem + +nKBExpMem;\n }\n\n /**\n * getDIPVideoMonitor(fInit)\n *\n * @this {ChipSet}\n * @param {boolean} [fInit] is true for init switch value(s) only, current value(s) otherwise\n * @return {number} one of ChipSet.MONITOR.*\n */\n getDIPVideoMonitor(fInit)\n {\n let n = /** @type {number} */ (this.getDIPSwitches(ChipSet.SWITCH_TYPE.MONITOR, fInit));\n return +n;\n }\n\n /**\n * parseDIPSwitches(sBits, bDefault)\n *\n * @this {ChipSet}\n * @param {string} sBits describing switch settings\n * @param {number} [bDefault]\n * @return {number|undefined}\n */\n parseDIPSwitches(sBits, bDefault)\n {\n let b = bDefault;\n if (sBits) {\n /*\n * NOTE: We can't use parseInt() with a base of 2, because both bit order and bit sense are reversed.\n */\n b = 0;\n let bit = 0x1;\n for (let i = 0; i < sBits.length; i++) {\n if (sBits.charAt(i) == \"0\") b |= bit;\n bit <<= 1;\n }\n }\n return b;\n }\n\n /**\n * setDIPSwitches(iType, value, fInit)\n *\n * @this {ChipSet}\n * @param {number} iType\n * @param {*} value\n * @param {boolean} [fInit]\n * @return {boolean} true if successful, false if unrecognized type and/or value\n */\n setDIPSwitches(iType, value, fInit)\n {\n let switchDIPs = ChipSet.DIPSW[this.model] || ChipSet.DIPSW[this.model|0] || ChipSet.DIPSW[ChipSet.MODEL_5150];\n for (let iDIP = 0; iDIP < switchDIPs.length; iDIP++) {\n let switchTypes = switchDIPs[iDIP];\n if (switchTypes) {\n let switchGroup = switchTypes[iType];\n if (switchGroup) {\n for (let v in switchGroup.VALUES) {\n if (v == value) {\n this.aDIPSwitches[iDIP][fInit?0:1] &= ~switchGroup.MASK;\n this.aDIPSwitches[iDIP][fInit?0:1] |= switchGroup.VALUES[v];\n return true;\n }\n }\n }\n }\n }\n return false;\n }\n\n /**\n * getDIPSwitchControl(control)\n *\n * @this {ChipSet}\n * @param {HTMLElement} control is an HTML control DOM object\n * @return {boolean} true if the switch represented by e is \"on\", false if \"off\"\n */\n getDIPSwitchControl(control)\n {\n return control.getAttribute(\"data-value\") == \"1\";\n }\n\n /**\n * setDIPSwitchControl(control, f)\n *\n * @this {ChipSet}\n * @param {HTMLElement} control is an HTML control DOM object\n * @param {boolean} f is true if the switch represented by control should be \"on\", false if \"off\"\n */\n setDIPSwitchControl(control, f)\n {\n control.setAttribute(\"data-value\", f? \"1\" : \"0\");\n control.style.color = (f? \"#ffffff\" : \"#000000\");\n control.style.backgroundColor = (f? \"#000000\" : \"#ffffff\");\n }\n\n /**\n * toggleDIPSwitchControl(control)\n *\n * @this {ChipSet}\n * @param {HTMLElement} control is an HTML control DOM object\n */\n toggleDIPSwitchControl(control)\n {\n let f = !this.getDIPSwitchControl(control);\n this.setDIPSwitchControl(control, f);\n let sID = control.getAttribute(\"id\");\n let asParts = sID.split(\"-\");\n let b = (0x1 << (+asParts[1] - 1));\n switch (asParts[0]) {\n case ChipSet.CONTROLS.SW1:\n this.aDIPSwitches[0][0] = (this.aDIPSwitches[0][0] & ~b) | (f? 0 : b);\n break;\n case ChipSet.CONTROLS.SW2:\n this.aDIPSwitches[1][0] = (this.aDIPSwitches[1][0] & ~b) | (f? 0 : b);\n break;\n default:\n break;\n }\n this.updateDIPSwitchDescriptions();\n }\n\n /**\n * updateDIPSwitches()\n *\n * @this {ChipSet}\n */\n updateDIPSwitches()\n {\n this.updateDIPSwitchControls(0, ChipSet.CONTROLS.SW1);\n this.updateDIPSwitchControls(1, ChipSet.CONTROLS.SW2);\n this.updateDIPSwitchDescriptions();\n }\n\n /**\n * updateDIPSwitchControls(iDIP, sBinding, fInit)\n *\n * @this {ChipSet}\n * @param {number} iDIP (0 or 1)\n * @param {string} sBinding is the name of the control\n * @param {boolean} [fInit]\n */\n updateDIPSwitchControls(iDIP, sBinding, fInit)\n {\n let control = this.bindings[sBinding];\n if (control) {\n let v;\n if (fInit) {\n v = this.aDIPSwitches[iDIP][0];\n } else {\n v = this.aDIPSwitches[iDIP][1] = this.aDIPSwitches[iDIP][0];\n }\n let aeCells = Component.getElementsByClass(control, this.sCellClass);\n for (let i = 0; i < aeCells.length; i++) {\n let switchGroup = this.findDIPSwitch(iDIP, i);\n let sLabel = switchGroup && switchGroup.LABEL || \"Reserved\";\n aeCells[i].setAttribute(\"title\", sLabel);\n this.setDIPSwitchControl(aeCells[i], !(v & (0x1 << i)));\n aeCells[i].onclick = function(chipset, eSwitch) {\n /*\n * If we define the onclick handler below as \"function(e)\" instead of simply \"function()\", then we will\n * also receive an Event object; however, IE reportedly requires that we examine a global (window.event)\n * instead. If that's true, and if we ever care to get more details about the click event, then define\n * a local var; eg:\n * \n * let event = window.event || e;\n */\n return function onClickSwitch() {\n chipset.toggleDIPSwitchControl(eSwitch);\n };\n }(this, aeCells[i]);\n }\n }\n }\n\n /**\n * updateDIPSwitchDescriptions()\n *\n * @this {ChipSet}\n */\n updateDIPSwitchDescriptions()\n {\n let controlDesc = this.bindings[ChipSet.CONTROLS.SWDESC];\n if (controlDesc != null) {\n let sText = \"\";\n /*\n * TODO: Monitor type 0 used to be \"None\" (ie, \"No Monitor\"), which was correct in a pre-EGA world,\n * but in the post-EGA world, it depends. We should ask the Video component for a definitive answer.\n */\n let asMonitorTypes = {\n 0: \"Enhanced Color\",\n 1: \"TV\",\n 2: \"Color\",\n 3: \"Monochrome\"\n };\n sText += this.getDIPMemorySize(true) + \"Kb\";\n sText += \", \" + (+this.getDIPCoprocessor(true)? \"\" : \"No \") + \"FPU\";\n sText += \", \" + asMonitorTypes[this.getDIPVideoMonitor(true)] + \" Monitor\";\n sText += \", \" + this.getDIPFloppyDrives(true) + \" Floppy Drives\";\n if (this.aDIPSwitches[0][1] != null && this.aDIPSwitches[0][1] != this.aDIPSwitches[0][0] ||\n this.aDIPSwitches[1][1] != null && this.aDIPSwitches[1][1] != this.aDIPSwitches[1][0]) {\n sText += \" (Reset required)\";\n }\n controlDesc.textContent = sText;\n }\n }\n\n /**\n * dumpPIC()\n *\n * @this {ChipSet}\n */\n dumpPIC()\n {\n if (DEBUGGER) {\n for (let iPIC = 0; iPIC < this.aPICs.length; iPIC++) {\n let pic = this.aPICs[iPIC];\n let sDump = \"PIC\" + iPIC + \":\";\n for (let i = 0; i < pic.aICW.length; i++) {\n let b = pic.aICW[i];\n sDump += \" IC\" + (i + 1) + '=' + Str.toHexByte(b);\n }\n sDump += \" IMR=\" + Str.toHexByte(pic.bIMR) + \" IRR=\" + Str.toHexByte(pic.bIRR) + \" ISR=\" + Str.toHexByte(pic.bISR) + \" DELAY=\" + pic.nDelay;\n this.dbg.println(sDump);\n }\n }\n }\n\n /**\n * dumpTimer(asArgs)\n *\n * Use \"d timer\" to dump all timers, or \"d timer n\" to dump only timer n.\n *\n * @this {ChipSet}\n * @param {Array.<string>} asArgs\n */\n dumpTimer(asArgs)\n {\n if (DEBUGGER) {\n let sParm = asArgs[0];\n let nTimer = (sParm? +sParm : null);\n for (let iTimer = 0; iTimer < this.aTimers.length; iTimer++) {\n if (nTimer != null && iTimer != nTimer) continue;\n this.updateTimer(iTimer);\n let timer = this.aTimers[iTimer];\n let sDump = \"TIMER\" + iTimer + \":\";\n let count = 0;\n if (timer.countBytes != null) {\n for (let i = 0; i <= timer.countBytes; i++) {\n count |= (timer.countCurrent[i] << (i * 8));\n }\n }\n sDump += \" mode=\" + (timer.mode >> 1) + \" bytes=\" + timer.countBytes + \" count=\" + Str.toHexWord(count);\n this.dbg.println(sDump);\n }\n }\n }\n\n /**\n * dumpCMOS()\n *\n * @this {ChipSet}\n */\n dumpCMOS()\n {\n if (DEBUGGER) {\n let sDump = \"\";\n for (let iCMOS = 0; iCMOS < ChipSet.CMOS.ADDR.TOTAL; iCMOS++) {\n let b = (iCMOS <= ChipSet.CMOS.ADDR.STATUSD? this.getRTCByte(iCMOS) : this.abCMOSData[iCMOS]);\n if (sDump) sDump += '\\n';\n sDump += \"CMOS[\" + Str.toHexByte(iCMOS) + \"]: \" + Str.toHexByte(b);\n }\n this.dbg.println(sDump);\n }\n }\n\n /**\n * inDMAChannelAddr(iDMAC, iChannel, port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} iChannel\n * @param {number} port (0x00, 0x02, 0x04, 0x06 for DMAC 0, 0xC0, 0xC4, 0xC8, 0xCC for DMAC 1)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inDMAChannelAddr(iDMAC, iChannel, port, addrFrom)\n {\n let controller = this.aDMACs[iDMAC];\n let channel = controller.aChannels[iChannel];\n let b = channel.addrCurrent[controller.bIndex];\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, null, addrFrom, \"DMA\" + iDMAC + \".CHANNEL\" + iChannel + \".ADDR[\" + controller.bIndex + \"]\", b, true);\n }\n controller.bIndex ^= 0x1;\n /*\n * Technically, aTimers[1].fOut is what drives DMA requests for DMA channel 0 (ChipSet.DMA_REFRESH),\n * every 15us, once the BIOS has initialized the channel's \"mode\" with MODE_SINGLE, INCREMENT, AUTOINIT,\n * and TYPE_READ (0x58) and initialized TIMER1 appropriately.\n *\n * However, we don't need to be that particular. Simply simulate an ever-increasing address after every\n * read of the full DMA channel 0 address.\n */\n if (!iDMAC && iChannel == ChipSet.DMA_REFRESH && !controller.bIndex) {\n channel.addrCurrent[0]++;\n if (channel.addrCurrent[0] > 0xff) {\n channel.addrCurrent[0] = 0;\n channel.addrCurrent[1]++;\n if (channel.addrCurrent[1] > 0xff) {\n channel.addrCurrent[1] = 0;\n }\n }\n }\n return b;\n }\n\n /**\n * outDMAChannelAddr(iDMAC, iChannel, port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} iChannel\n * @param {number} port (0x00, 0x02, 0x04, 0x06 for DMAC 0, 0xC0, 0xC4, 0xC8, 0xCC for DMAC 1)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outDMAChannelAddr(iDMAC, iChannel, port, bOut, addrFrom)\n {\n let controller = this.aDMACs[iDMAC];\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"DMA\" + iDMAC + \".CHANNEL\" + iChannel + \".ADDR[\" + controller.bIndex + \"]\", null, true);\n }\n let channel = controller.aChannels[iChannel];\n channel.addrCurrent[controller.bIndex] = channel.addrInit[controller.bIndex] = bOut;\n controller.bIndex ^= 0x1;\n }\n\n /**\n * inDMAChannelCount(iDMAC, iChannel, port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} iChannel\n * @param {number} port (0x01, 0x03, 0x05, 0x07 for DMAC 0, 0xC2, 0xC6, 0xCA, 0xCE for DMAC 1)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inDMAChannelCount(iDMAC, iChannel, port, addrFrom)\n {\n let controller = this.aDMACs[iDMAC];\n let channel = controller.aChannels[iChannel];\n let b = channel.countCurrent[controller.bIndex];\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, null, addrFrom, \"DMA\" + iDMAC + \".CHANNEL\" + iChannel + \".COUNT[\" + controller.bIndex + \"]\", b, true);\n }\n controller.bIndex ^= 0x1;\n /*\n * Technically, aTimers[1].fOut is what drives DMA requests for DMA channel 0 (ChipSet.DMA_REFRESH),\n * every 15us, once the BIOS has initialized the channel's \"mode\" with MODE_SINGLE, INCREMENT, AUTOINIT,\n * and TYPE_READ (0x58) and initialized TIMER1 appropriately.\n *\n * However, we don't need to be that particular. Simply simulate an ever-decreasing count after every\n * read of the full DMA channel 0 count.\n */\n if (!iDMAC && iChannel == ChipSet.DMA_REFRESH && !controller.bIndex) {\n channel.countCurrent[0]--;\n if (channel.countCurrent[0] < 0) {\n channel.countCurrent[0] = 0xff;\n channel.countCurrent[1]--;\n if (channel.countCurrent[1] < 0) {\n channel.countCurrent[1] = 0xff;\n /*\n * This is the logical point to indicate Terminal Count (TC), but again, there's no need to be\n * so particular; inDMAStatus() has its own logic for periodically signalling TC.\n */\n }\n }\n }\n return b;\n }\n\n /**\n * outDMAChannelCount(iDMAC, iChannel, port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} iChannel (ports 0x01, 0x03, 0x05, 0x07)\n * @param {number} port (0x01, 0x03, 0x05, 0x07 for DMAC 0, 0xC2, 0xC6, 0xCA, 0xCE for DMAC 1)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outDMAChannelCount(iDMAC, iChannel, port, bOut, addrFrom)\n {\n let controller = this.aDMACs[iDMAC];\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"DMA\" + iDMAC + \".CHANNEL\" + iChannel + \".COUNT[\" + controller.bIndex + \"]\", null, true);\n }\n let channel = controller.aChannels[iChannel];\n channel.countCurrent[controller.bIndex] = channel.countInit[controller.bIndex] = bOut;\n controller.bIndex ^= 0x1;\n }\n\n /**\n * inDMAStatus(iDMAC, port, addrFrom)\n *\n * From the 8237A spec:\n *\n * \"The Status register is available to be read out of the 8237A by the microprocessor.\n * It contains information about the status of the devices at this point. This information includes\n * which channels have reached Terminal Count (TC) and which channels have pending DMA requests.\n *\n * Bits 0–3 are set every time a TC is reached by that channel or an external EOP is applied.\n * These bits are cleared upon Reset and on each Status Read.\n *\n * Bits 4–7 are set whenever their corresponding channel is requesting service.\"\n *\n * TRIVIA: This hook wasn't installed when I was testing with the MODEL_5150 ROM BIOS, and it\n * didn't matter, but the MODEL_5160 ROM BIOS checks it several times, including @F000:E156, where\n * it verifies that TIMER1 didn't request service on channel 0.\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} port (0x08 for DMAC 0, 0xD0 for DMAC 1)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inDMAStatus(iDMAC, port, addrFrom)\n {\n /*\n * HACK: Unlike the MODEL_5150, the MODEL_5160 ROM BIOS checks DMA channel 0 for TC (@F000:E4DF)\n * after running a number of unrelated tests, since enough time would have passed for channel 0 to\n * have reached TC at least once. So I simply OR in a hard-coded TC bit for channel 0 every time\n * status is read.\n */\n let controller = this.aDMACs[iDMAC];\n let b = controller.bStatus | ChipSet.DMA_STATUS.CH0_TC;\n controller.bStatus &= ~ChipSet.DMA_STATUS.ALL_TC;\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, null, addrFrom, \"DMA\" + iDMAC + \".STATUS\", b, true);\n }\n return b;\n }\n\n /**\n * outDMACmd(iDMAC, port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} port (0x08 for DMAC 0, 0xD0 for DMAC 1)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outDMACmd(iDMAC, port, bOut, addrFrom)\n {\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"DMA\" + iDMAC + \".CMD\", null, true);\n }\n this.aDMACs[iDMAC].bCmd = bOut;\n }\n\n /**\n * outDMAReq(iDMAC, port, bOut, addrFrom)\n *\n * From the 8237A spec:\n *\n * \"The 8237A can respond to requests for DMA service which are initiated by software as well as by a DREQ.\n * Each channel has a request bit associated with it in the 4-bit Request register. These are non-maskable and subject\n * to prioritization by the Priority Encoder network. Each register bit is set or reset separately under software\n * control or is cleared upon generation of a TC or external EOP. The entire register is cleared by a Reset.\n *\n * To set or reset a bit the software loads the proper form of the data word.... In order to make a software request,\n * the channel must be in Block Mode.\"\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} port (0x09 for DMAC 0, 0xD2 for DMAC 1)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outDMAReq(iDMAC, port, bOut, addrFrom)\n {\n let controller = this.aDMACs[iDMAC];\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"DMA\" + iDMAC + \".REQ\", null, true);\n }\n /*\n * Bits 0-1 contain the channel number\n */\n let iChannel = (bOut & 0x3);\n /*\n * Bit 2 is the request bit (0 to reset, 1 to set), which must be propagated to the corresponding bit (4-7) in the status register\n */\n let iChannelBit = ((bOut & 0x4) << (iChannel + 2));\n controller.bStatus = (controller.bStatus & ~(0x10 << iChannel)) | iChannelBit;\n controller.bReq = bOut;\n }\n\n /**\n * outDMAMask(iDMAC, port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} port (0x0A for DMAC 0, 0xD4 for DMAC 1)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outDMAMask(iDMAC, port, bOut, addrFrom)\n {\n let controller = this.aDMACs[iDMAC];\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"DMA\" + iDMAC + \".MASK\", null, true);\n }\n let iChannel = bOut & ChipSet.DMA_MASK.CHANNEL;\n let channel = controller.aChannels[iChannel];\n channel.masked = !!(bOut & ChipSet.DMA_MASK.CHANNEL_SET);\n if (!channel.masked) this.requestDMA(controller.nChannelBase + iChannel);\n }\n\n /**\n * outDMAMode(iDMAC, port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} port (0x0B for DMAC 0, 0xD6 for DMAC 1)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outDMAMode(iDMAC, port, bOut, addrFrom)\n {\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"DMA\" + iDMAC + \".MODE\", null, true);\n }\n let iChannel = bOut & ChipSet.DMA_MODE.CHANNEL;\n this.aDMACs[iDMAC].aChannels[iChannel].mode = bOut;\n }\n\n /**\n * outDMAResetFF(iDMAC, port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} port (0x0C for DMAC 0, 0xD8 for DMAC 1)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n *\n * Any write to this port simply resets the controller's \"first/last flip-flop\", which determines whether\n * the even or odd byte of a DMA address or count register will be accessed next.\n */\n outDMAResetFF(iDMAC, port, bOut, addrFrom)\n {\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"DMA\" + iDMAC + \".RESET_FF\", null, true);\n }\n this.aDMACs[iDMAC].bIndex = 0;\n }\n\n /**\n * inDMATemp(iDMAC, port, addrFrom)\n *\n * From the 8237A spec:\n *\n * \"The Temporary register is used to hold data during memory-to-memory transfers Following the\n * completion of the transfers, the last word moved can be read by the microprocessor in the Program Condition.\n * The Temporary register always contains the last byte transferred in the previous memory-to-memory operation,\n * unless cleared by a Reset.\"\n *\n * TRIVIA: This hook wasn't installed when I was testing with ANY of the IBM ROMs, but it's required\n * by the AT&T 6300 (aka Olivetti M24) ROM.\n *\n * TODO: When support is added for memory-to-memory transfers, bTemp needs to be updated according to spec.\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} port (0x0D for DMAC 0, 0xDA for DMAC 1)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inDMATemp(iDMAC, port, addrFrom)\n {\n let controller = this.aDMACs[iDMAC];\n let b = controller.bTemp;\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, null, addrFrom, \"DMA\" + iDMAC + \".TEMP\", b, true);\n }\n return b;\n }\n\n /**\n * outDMAMasterClear(iDMAC, port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} port (0x0D for DMAC 0, 0xDA for DMAC 1)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outDMAMasterClear(iDMAC, port, bOut, addrFrom)\n {\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"DMA\" + iDMAC + \".MASTER_CLEAR\", null, true);\n }\n /*\n * The value written to this port doesn't matter; any write triggers a \"master clear\" operation\n *\n * TODO: Can't we just call initDMAController(), which would also take care of clearing controller.bStatus?\n */\n let controller = this.aDMACs[iDMAC];\n for (let i = 0; i < controller.aChannels.length; i++) {\n this.initDMAChannel(controller, i);\n }\n }\n\n /**\n * inDMAPageReg(iDMAC, iChannel, port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} iChannel\n * @param {number} port\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inDMAPageReg(iDMAC, iChannel, port, addrFrom)\n {\n let bIn = this.aDMACs[iDMAC].aChannels[iChannel].bPage;\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, null, addrFrom, \"DMA\" + iDMAC + \".CHANNEL\" + iChannel + \".PAGE\", bIn, true);\n }\n return bIn;\n }\n\n /**\n * outDMAPageReg(iDMAC, iChannel, port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} iChannel\n * @param {number} port\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outDMAPageReg(iDMAC, iChannel, port, bOut, addrFrom)\n {\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"DMA\" + iDMAC + \".CHANNEL\" + iChannel + \".PAGE\", null, true);\n }\n this.aDMACs[iDMAC].aChannels[iChannel].bPage = bOut;\n }\n\n /**\n * inDMAPageSpare(iSpare, port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iSpare\n * @param {number} port\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inDMAPageSpare(iSpare, port, addrFrom)\n {\n let bIn = this.abDMAPageSpare[iSpare];\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, null, addrFrom, \"DMA.SPARE\" + iSpare + \".PAGE\", bIn, true);\n }\n return bIn;\n }\n\n /**\n * outDMAPageSpare(iSpare, port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iSpare\n * @param {number} port\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outDMAPageSpare(iSpare, port, bOut, addrFrom)\n {\n /*\n * TODO: Remove this DEBUG-only DESKPRO386 code once we're done debugging DeskPro 386 ROMs;\n * it enables logging of all DeskPro 386 ROM checkpoint I/O to port 0x84.\n */\n if (this.messageEnabled(Messages.DMA | Messages.PORT) || DEBUG && (this.model|0) == ChipSet.MODEL_COMPAQ_DESKPRO386 && port == 0x84) {\n this.printMessageIO(port, bOut, addrFrom, \"DMA.SPARE\" + iSpare + \".PAGE\", null, true);\n }\n this.abDMAPageSpare[iSpare] = bOut;\n }\n\n /**\n * connectDMA(iDMAChannel, component, sFunction, obj)\n *\n * @param {number} iDMAChannel\n * @param {Component|string} component\n * @param {string} sFunction\n * @param {Object} obj (eg, when the HDC connects, it passes a drive object)\n */\n connectDMA(iDMAChannel, component, sFunction, obj)\n {\n let iDMAC = iDMAChannel >> 2;\n let controller = this.aDMACs[iDMAC];\n\n let iChannel = iDMAChannel & 0x3;\n let channel = controller.aChannels[iChannel];\n\n this.initDMAFunction(channel, component, sFunction, obj);\n }\n\n /**\n * requestDMA(iDMAChannel, done)\n *\n * @this {ChipSet}\n * @param {number} iDMAChannel\n * @param {function(boolean)} [done]\n *\n * For DMA_MODE.TYPE_WRITE transfers, fnTransfer(-1) must return bytes as long as we request them (although it may\n * return -1 if it runs out of bytes prematurely).\n *\n * Similarly, for DMA_MODE.TYPE_READ transfers, fnTransfer(b) must accept bytes as long as we deliver them (although\n * it is certainly free to ignore bytes it no longer wants).\n */\n requestDMA(iDMAChannel, done)\n {\n let iDMAC = iDMAChannel >> 2;\n let controller = this.aDMACs[iDMAC];\n\n let iChannel = iDMAChannel & 0x3;\n let channel = controller.aChannels[iChannel];\n\n if (!channel.component || !channel.fnTransfer || !channel.obj) {\n if (DEBUG && this.messageEnabled(Messages.DMA | Messages.DATA)) {\n this.printMessage(\"requestDMA(\" + iDMAChannel + \"): not connected to a component\", true);\n }\n if (done) done(true);\n return;\n }\n\n /*\n * We can't simply slam done into channel.done; that would be fine if requestDMA() was called only by functions\n * like HDC.doRead() and HDC.doWrite(), but we're also called whenever a DMA channel is unmasked, and in those cases,\n * we need to preserve whatever handler may have been previously set.\n *\n * However, in an effort to ensure we don't end up with stale done handlers, connectDMA() will reset channel.done.\n */\n if (done) channel.done = done;\n\n if (channel.masked) {\n if (DEBUG && this.messageEnabled(Messages.DMA | Messages.DATA)) {\n this.printMessage(\"requestDMA(\" + iDMAChannel + \"): channel masked, request queued\", true);\n }\n return;\n }\n\n /*\n * Let's try to do async DMA without asking the CPU for help...\n *\n * this.cpu.setDMA(true);\n */\n this.advanceDMA(channel, true);\n }\n\n /**\n * advanceDMA(channel, fInit)\n *\n * @this {ChipSet}\n * @param {Object} channel\n * @param {boolean} [fInit]\n */\n advanceDMA(channel, fInit)\n {\n if (fInit) {\n channel.count = (channel.countCurrent[1] << 8) | channel.countCurrent[0];\n channel.type = (channel.mode & ChipSet.DMA_MODE.TYPE);\n channel.fWarning = channel.fError = false;\n if (DEBUG && DEBUGGER) {\n channel.cbDebug = channel.count + 1;\n channel.sAddrDebug = (DEBUG && DEBUGGER? null : undefined);\n }\n }\n /*\n * To support async DMA without requiring help from the CPU (ie, without relying upon cpu.setDMA()), we require that\n * the data transfer functions provide an fAsync parameter to their callbacks; fAsync must be true if the callback was\n * truly asynchronous (ie, it had to wait for a remote I/O request to finish), or false if the data was already available\n * and the callback was performed synchronously.\n *\n * Whenever a callback is issued asynchronously, we will immediately daisy-chain another pair of updateDMA()/advanceDMA()\n * calls, which will either finish the DMA operation if no more remote I/O requests are required, or will queue up another\n * I/O request, which will in turn trigger another async callback. Thus, the DMA request keeps itself going without\n * requiring any special assistance from the CPU via setDMA().\n */\n let bto = null;\n let chipset = this;\n let fAsyncRequest = false;\n let controller = channel.controller;\n let iDMAChannel = controller.nChannelBase + channel.iChannel;\n\n while (true) {\n if (channel.count >= 0) {\n let b;\n let addr = (channel.bPage << 16) | (channel.addrCurrent[1] << 8) | channel.addrCurrent[0];\n if (DEBUG && DEBUGGER && channel.sAddrDebug === null) {\n channel.sAddrDebug = Str.toHex(addr >> 4, 4) + \":\" + Str.toHex(addr & 0xf, 4);\n if (this.messageEnabled(this.messageBitsDMA(iDMAChannel)) && channel.type != ChipSet.DMA_MODE.TYPE_WRITE) {\n this.printMessage(\"advanceDMA(\" + iDMAChannel + \") transferring \" + channel.cbDebug + \" bytes from \" + channel.sAddrDebug, true);\n this.dbg.doDump([\"db\", channel.sAddrDebug, 'l', channel.cbDebug]);\n }\n }\n if (channel.type == ChipSet.DMA_MODE.TYPE_WRITE) {\n fAsyncRequest = true;\n (function advanceDMAWrite(addrCur) {\n channel.fnTransfer.call(channel.component, channel.obj, -1, function onTransferDMA(b, fAsync, obj, off) {\n if (b < 0) {\n if (!channel.fWarning) {\n if (DEBUG && chipset.messageEnabled(Messages.DMA)) {\n chipset.printMessage(\"advanceDMA(\" + iDMAChannel + \") ran out of data, assuming 0xff\", true);\n }\n channel.fWarning = true;\n }\n /*\n * TODO: Determine whether to abort, as we do for DMA_MODE.TYPE_READ.\n */\n b = 0xff;\n }\n if (!channel.masked) {\n chipset.bus.setByte(addrCur, b);\n /*\n * WARNING: Do NOT assume that obj is valid; if the sector data was not found, there will be no obj.\n */\n if (BACKTRACK && obj) {\n if (!off && obj.file) {\n if (chipset.messageEnabled(Messages.DISK)) {\n chipset.printMessage(\"loading \" + obj.file.sPath + '[' + obj.offFile + \"] at %\" + Str.toHex(addrCur), true);\n }\n /*\n if (obj.file.sPath == \"\\\\SYSBAS.EXE\" && obj.offFile == 512) {\n chipset.cpu.stopCPU();\n }\n */\n }\n bto = chipset.bus.addBackTrackObject(obj, bto, off);\n chipset.bus.writeBackTrackObject(addrCur, bto, off);\n }\n }\n fAsyncRequest = fAsync;\n if (fAsync) {\n setTimeout(function() {\n if (!chipset.updateDMA(channel)) chipset.advanceDMA(channel);\n }, 0);\n }\n });\n }(addr));\n }\n else if (channel.type == ChipSet.DMA_MODE.TYPE_READ) {\n /*\n * TODO: Determine whether we should support async dmaWrite() functions (currently not required)\n */\n b = chipset.bus.getByte(addr);\n if (channel.fnTransfer.call(channel.component, channel.obj, b) < 0) {\n /*\n * In this case, I think I have no choice but to terminate the DMA operation in response to a failure,\n * because the ROM BIOS FDC.REG_DATA.CMD.FORMAT_TRACK command specifies a count that is MUCH too large\n * (a side-effect of the ROM BIOS using the same \"DMA_SETUP\" code for reads, writes AND formats).\n */\n channel.fError = true;\n }\n }\n else if (channel.type == ChipSet.DMA_MODE.TYPE_VERIFY) {\n /*\n * Nothing to read or write; just call updateDMA()\n */\n }\n else {\n if (DEBUG && this.messageEnabled(Messages.DMA | Messages.WARN)) {\n this.printMessage(\"advanceDMA(\" + iDMAChannel + \") unsupported transfer type: \" + Str.toHexWord(channel.type), true);\n }\n channel.fError = true;\n }\n }\n if (fAsyncRequest || this.updateDMA(channel)) break;\n }\n }\n\n /**\n * updateDMA(channel)\n *\n * @this {ChipSet}\n * @param {Object} channel\n * @return {boolean} true if DMA operation complete, false if not\n */\n updateDMA(channel)\n {\n if (!channel.fError && --channel.count >= 0) {\n if (channel.mode & ChipSet.DMA_MODE.DECREMENT) {\n channel.addrCurrent[0]--;\n if (channel.addrCurrent[0] < 0) {\n channel.addrCurrent[0] = 0xff;\n channel.addrCurrent[1]--;\n if (channel.addrCurrent[1] < 0) channel.addrCurrent[1] = 0xff;\n }\n } else {\n channel.addrCurrent[0]++;\n if (channel.addrCurrent[0] > 0xff) {\n channel.addrCurrent[0] = 0x00;\n channel.addrCurrent[1]++;\n if (channel.addrCurrent[1] > 0xff) channel.addrCurrent[1] = 0x00;\n }\n }\n /*\n * In situations where an HDC DMA operation took too long, the Fixed Disk BIOS would give up, but the DMA operation would continue.\n *\n * TODO: Verify that the Fixed Disk BIOS shuts down (ie, re-masks) a DMA channel for failed requests, and that this handles those failures.\n */\n if (!channel.masked) return false;\n }\n\n let controller = channel.controller;\n let iDMAChannel = controller.nChannelBase + channel.iChannel;\n controller.bStatus = (controller.bStatus & ~(0x10 << channel.iChannel)) | (0x1 << channel.iChannel);\n\n /*\n * EOP is supposed to automatically (re)mask the channel, unless it's set for auto-initialize.\n */\n if (!(channel.mode & ChipSet.DMA_MODE.AUTOINIT)) {\n channel.masked = true;\n channel.component = channel.obj = null;\n }\n\n if (DEBUG && this.messageEnabled(this.messageBitsDMA(iDMAChannel)) && channel.type == ChipSet.DMA_MODE.TYPE_WRITE && channel.sAddrDebug) {\n this.printMessage(\"updateDMA(\" + iDMAChannel + \") transferred \" + channel.cbDebug + \" bytes to \" + channel.sAddrDebug, true);\n this.dbg.doDump([\"db\", channel.sAddrDebug, 'l', channel.cbDebug]);\n }\n\n if (channel.done) {\n channel.done(!channel.fError);\n channel.done = null;\n }\n\n /*\n * While it might make sense to call cpu.setDMA() here, it's simpler to let the CPU issue one more call\n * to chipset.checkDMA() and let the CPU update INTR.DMA on its own, based on the return value from checkDMA().\n */\n return true;\n }\n\n /**\n * inPICLo(iPIC, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iPIC\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inPICLo(iPIC, addrFrom)\n {\n let b = 0;\n let pic = this.aPICs[iPIC];\n if (pic.bOCW3 != null) {\n let bReadReg = pic.bOCW3 & ChipSet.PIC_LO.OCW3_READ_CMD;\n switch (bReadReg) {\n case ChipSet.PIC_LO.OCW3_READ_IRR:\n b = pic.bIRR;\n break;\n case ChipSet.PIC_LO.OCW3_READ_ISR:\n b = pic.bISR;\n break;\n default:\n break;\n }\n }\n if (this.messageEnabled(Messages.PIC | Messages.PORT)) {\n this.printMessageIO(pic.port, null, addrFrom, \"PIC\" + iPIC, b, true);\n }\n return b;\n }\n\n /**\n * outPICLo(iPIC, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iPIC\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outPICLo(iPIC, bOut, addrFrom)\n {\n let pic = this.aPICs[iPIC];\n if (this.messageEnabled(Messages.PIC | Messages.PORT)) {\n this.printMessageIO(pic.port, bOut, addrFrom, \"PIC\" + iPIC, null, true);\n }\n if (bOut & ChipSet.PIC_LO.ICW1) {\n /*\n * This must be an ICW1...\n */\n pic.nICW = 0;\n pic.aICW[pic.nICW++] = bOut;\n /*\n * I used to do the rest of this initialization in outPICHi(), once all the ICW commands had been received,\n * but a closer reading of the 8259A spec indicates that that should happen now, on receipt on ICW1.\n *\n * Also, on p.10 of that spec, it says \"The Interrupt Mask Register is cleared\". I originally took that to\n * mean that all interrupts were masked, but based on what MS-DOS 4.0M expects to happen after this code runs:\n *\n * 0070:44C6 B013 MOV AL,13\n * 0070:44C8 E620 OUT 20,AL\n * 0070:44CA B050 MOV AL,50\n * 0070:44CC E621 OUT 21,AL\n * 0070:44CE B009 MOV AL,09\n * 0070:44D0 E621 OUT 21,AL\n *\n * (ie, it expects its next call to INT 0x13 will still generate an interrupt), I've decided the spec\n * must be read literally, meaning that all IMR bits must be zeroed. Unmasking all possible interrupts by\n * default seems unwise to me, but who am I to judge....\n */\n pic.bIMR = 0x00;\n pic.bIRLow = 7;\n /*\n * TODO: I'm also zeroing both IRR and ISR, even though that's not actually mentioned as part of the ICW\n * sequence, because they need to be (re)initialized at some point. However, if some component is currently\n * requesting an interrupt, what should I do about that? Originally, I had decided to clear them ONLY if they\n * were still undefined, but that change appeared to break the ROM BIOS handling of CTRL-ALT-DEL, so I'm back\n * to unconditionally zeroing them.\n */\n pic.bIRR = pic.bISR = 0;\n /*\n * The spec also says that \"Special Mask Mode is cleared and Status Read is set to IRR\". I attempt to insure\n * the latter, but as for special mask mode... well, that mode isn't supported yet.\n */\n pic.bOCW3 = ChipSet.PIC_LO.OCW3 | ChipSet.PIC_LO.OCW3_READ_IRR;\n }\n else if (!(bOut & ChipSet.PIC_LO.OCW3)) {\n /*\n * This must be an OCW2...\n */\n let bOCW2 = bOut & ChipSet.PIC_LO.OCW2_OP_MASK;\n if (bOCW2 & ChipSet.PIC_LO.OCW2_EOI) {\n /*\n * This OCW2 must be an EOI command...\n */\n let nIRL, bIREnd = 0;\n if ((bOCW2 & ChipSet.PIC_LO.OCW2_EOI_SPEC) == ChipSet.PIC_LO.OCW2_EOI_SPEC) {\n /*\n * More \"specifically\", a specific EOI command...\n */\n nIRL = bOut & ChipSet.PIC_LO.OCW2_IR_LVL;\n bIREnd = 1 << nIRL;\n } else {\n /*\n * Less \"specifically\", a non-specific EOI command. The search for the highest priority in-service\n * interrupt must start with whichever interrupt is opposite the lowest priority interrupt (normally 7,\n * but technically whatever bIRLow is currently set to). For example:\n *\n * If bIRLow is 7, then the priority order is: 0, 1, 2, 3, 4, 5, 6, 7.\n * If bIRLow is 6, then the priority order is: 7, 0, 1, 2, 3, 4, 5, 6.\n * If bIRLow is 5, then the priority order is: 6, 7, 0, 1, 2, 3, 4, 5.\n * etc.\n */\n nIRL = pic.bIRLow + 1;\n while (true) {\n nIRL &= 0x7;\n let bIR = 1 << nIRL;\n if (pic.bISR & bIR) {\n bIREnd = bIR;\n break;\n }\n if (nIRL++ == pic.bIRLow) break;\n }\n if (DEBUG && !bIREnd) nIRL = null; // for unexpected non-specific EOI commands, there's no IRQ to report\n }\n let nIRQ = (nIRL == null? undefined : pic.nIRQBase + nIRL);\n if (pic.bISR & bIREnd) {\n if (DEBUG && this.messageEnabled(this.messageBitsIRQ(nIRQ))) {\n this.printMessage(\"outPIC\" + iPIC + '(' + Str.toHexByte(pic.port) + \"): IRQ \" + nIRQ + \" ending @\" + this.dbg.toHexOffset(this.cpu.getIP(), this.cpu.getCS()) + \" stack=\" + this.dbg.toHexOffset(this.cpu.getSP(), this.cpu.getSS()), true);\n }\n pic.bISR &= ~bIREnd;\n this.checkIRR();\n } else {\n if (DEBUG && this.messageEnabled(Messages.PIC | Messages.WARN)) {\n this.printMessage(\"outPIC\" + iPIC + '(' + Str.toHexByte(pic.port) + \"): unexpected EOI for IRQ \" + nIRQ, true, true);\n if (MAXDEBUG) this.dbg.stopCPU();\n }\n }\n /*\n * TODO: Support EOI commands with automatic rotation (eg, ChipSet.PIC_LO.OCW2_EOI_ROT and ChipSet.PIC_LO.OCW2_EOI_ROTSPEC)\n */\n if (bOCW2 & ChipSet.PIC_LO.OCW2_SET_ROTAUTO) {\n if (this.messageEnabled(Messages.PIC | Messages.WARN)) {\n this.printMessage(\"PIC\" + iPIC + '(' + Str.toHexByte(pic.port) + \"): unsupported OCW2 rotate \" + Str.toHexByte(bOut), true, true);\n }\n }\n }\n else if (bOCW2 == ChipSet.PIC_LO.OCW2_SET_PRI) {\n /*\n * This OCW2 changes the lowest priority interrupt to the specified level (the default is 7)\n */\n pic.bIRLow = bOut & ChipSet.PIC_LO.OCW2_IR_LVL;\n }\n else {\n /*\n * TODO: Remaining commands to support: ChipSet.PIC_LO.OCW2_SET_ROTAUTO and ChipSet.PIC_LO.OCW2_CLR_ROTAUTO\n */\n if (this.messageEnabled(Messages.PIC | Messages.WARN)) {\n this.printMessage(\"PIC\" + iPIC + '(' + Str.toHexByte(pic.port) + \"): unsupported OCW2 automatic EOI \" + Str.toHexByte(bOut), true, true);\n }\n }\n } else {\n /*\n * This must be an OCW3 request. If it's a \"Read Register\" command (PIC_LO.OCW3_READ_CMD), inPICLo() will take care it.\n *\n * TODO: If OCW3 specified a \"Poll\" command (PIC_LO.OCW3_POLL_CMD) or a \"Special Mask Mode\" command (PIC_LO.OCW3_SMM_CMD),\n * that's unfortunate, because I don't support them yet.\n */\n if (bOut & (ChipSet.PIC_LO.OCW3_POLL_CMD | ChipSet.PIC_LO.OCW3_SMM_CMD)) {\n if (this.messageEnabled(Messages.PIC | Messages.WARN)) {\n this.printMessage(\"PIC\" + iPIC + '(' + Str.toHexByte(pic.port) + \"): unsupported OCW3 \" + Str.toHexByte(bOut), true, true);\n }\n }\n pic.bOCW3 = bOut;\n }\n }\n\n /**\n * inPICHi(iPIC, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iPIC\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inPICHi(iPIC, addrFrom)\n {\n let pic = this.aPICs[iPIC];\n let b = pic.bIMR;\n if (this.messageEnabled(Messages.PIC | Messages.PORT)) {\n this.printMessageIO(pic.port+1, null, addrFrom, \"PIC\" + iPIC, b, true);\n }\n return b;\n }\n\n /**\n * outPICHi(iPIC, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iPIC\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outPICHi(iPIC, bOut, addrFrom)\n {\n let pic = this.aPICs[iPIC];\n if (this.messageEnabled(Messages.PIC | Messages.PORT)) {\n this.printMessageIO(pic.port+1, bOut, addrFrom, \"PIC\" + iPIC, null, true);\n }\n if (pic.nICW < pic.aICW.length) {\n pic.aICW[pic.nICW++] = bOut;\n if (pic.nICW == 2 && (pic.aICW[0] & ChipSet.PIC_LO.ICW1_SNGL))\n pic.nICW++;\n if (pic.nICW == 3 && !(pic.aICW[0] & ChipSet.PIC_LO.ICW1_ICW4))\n pic.nICW++;\n }\n else {\n /*\n * We have all our ICW \"words\" (ie, bytes), so this must be an OCW1 write (which is simply an IMR write)\n */\n pic.bIMR = bOut;\n /*\n * See the CPU's delayINTR() function for an explanation of why this explicit delay is necessary.\n */\n this.cpu.delayINTR();\n /*\n * Alas, we need a longer delay for the MODEL_5170's \"KBD_RESET\" function (F000:17D2), which must drop\n * into a loop and decrement CX at least once after unmasking the KBD IRQ. The \"KBD_RESET\" function on\n * previous models could be handled with a 4-instruction delay provided by the Keyboard.resetDevice() call\n * to setIRR(), but the MODEL_5170 needs a roughly 6-instruction delay after it unmasks the KBD IRQ.\n */\n this.checkIRR(!iPIC && bOut == 0xFD? 6 : 0);\n }\n }\n\n /**\n * checkIMR(nIRQ)\n *\n * @this {ChipSet}\n * @param {number} nIRQ\n * @return {boolean} true if the specified IRQ is masked, false if not\n */\n checkIMR(nIRQ)\n {\n let iPIC = nIRQ >> 3;\n let nIRL = nIRQ & 0x7;\n let pic = this.aPICs[iPIC];\n return !!(pic.bIMR & (0x1 << nIRL));\n }\n\n /**\n * setIRR(nIRQ, nDelay)\n *\n * @this {ChipSet}\n * @param {number} nIRQ (IRQ 0-7 implies iPIC 0, and IRQ 8-15 implies iPIC 1)\n * @param {number} [nDelay] is an optional number of instructions to delay acknowledgment of the IRQ (see getIRRVector)\n */\n setIRR(nIRQ, nDelay)\n {\n let iPIC = nIRQ >> 3;\n let nIRL = nIRQ & 0x7;\n let pic = this.aPICs[iPIC];\n let bIRR = (1 << nIRL);\n if (!(pic.bIRR & bIRR)) {\n pic.bIRR |= bIRR;\n if (this.messageEnabled(this.messageBitsIRQ(nIRQ))) this.printMessage(\"set IRQ \" + nIRQ, true);\n pic.nDelay = nDelay || 0;\n this.checkIRR();\n }\n }\n\n /**\n * clearIRR(nIRQ)\n *\n * @this {ChipSet}\n * @param {number} nIRQ (IRQ 0-7 implies iPIC 0, and IRQ 8-15 implies iPIC 1)\n */\n clearIRR(nIRQ)\n {\n let iPIC = nIRQ >> 3;\n let nIRL = nIRQ & 0x7;\n let pic = this.aPICs[iPIC];\n let bIRR = (1 << nIRL);\n if (pic.bIRR & bIRR) {\n pic.bIRR &= ~bIRR;\n if (this.messageEnabled(this.messageBitsIRQ(nIRQ))) this.printMessage(\"clear IRQ \" + nIRQ, true);\n this.checkIRR();\n }\n }\n\n /**\n * checkIRR(nDelay)\n *\n * @this {ChipSet}\n * @param {number} [nDelay] is an optional number of instructions to delay acknowledgment of a pending interrupt\n */\n checkIRR(nDelay)\n {\n /*\n * Look for any IRR bits that aren't masked and aren't already in service; in theory, all we'd have to\n * check is the master PIC (which is the *only* PIC on pre-5170 models), because when any IRQs are set or\n * cleared on the slave, that would automatically be reflected in IRQ.SLAVE on the master; that's what\n * setIRR() and clearIRR() used to do.\n *\n * Unfortunately, despite setIRR() and clearIRR()'s efforts, whenever a slave interrupt is acknowledged,\n * getIRRVector() ends up clearing the IRR bits for BOTH the slave's IRQ and the master's IRQ.SLAVE.\n * So if another lower-priority slave IRQ is waiting to be dispatched, that fact is no longer reflected\n * in IRQ.SLAVE.\n *\n * Since checkIRR() is called on every EOI, we can resolve that problem here, by first checking the slave\n * PIC for any unmasked, unserviced interrupts and updating the master's IRQ.SLAVE.\n *\n * And since this is ALSO called by both setIRR() and clearIRR(), those functions no longer need to perform\n * their own IRQ.SLAVE updates. This function consolidates the propagation of slave interrupts to the master.\n */\n let pic;\n let bIR = -1;\n\n if (this.cPICs > 1) {\n pic = this.aPICs[1];\n bIR = ~(pic.bISR | pic.bIMR) & pic.bIRR;\n }\n\n pic = this.aPICs[0];\n\n if (bIR >= 0) {\n if (bIR) {\n pic.bIRR |= (1 << ChipSet.IRQ.SLAVE);\n } else {\n pic.bIRR &= ~(1 << ChipSet.IRQ.SLAVE);\n }\n }\n\n bIR = ~(pic.bISR | pic.bIMR) & pic.bIRR;\n\n this.cpu.updateINTR(!!bIR);\n\n if (bIR && nDelay) pic.nDelay = nDelay;\n }\n\n /**\n * getIRRVector()\n *\n * getIRRVector() is called by the CPU whenever PS_IF is set and OP_NOINTR is clear. Ordinarily, an immediate\n * response would seem perfectly reasonable, but unfortunately, there are places in the original ROM BIOS like\n * \"KBD_RESET\" (F000:E688) that enable interrupts but still expect nothing to happen for several more instructions.\n *\n * So, in addition to the two normal responses (an IDT vector #, or -1 indicating no pending interrupts), we must\n * support a third response (-2) that basically means: don't change the CPU interrupt state, just keep calling until\n * we return one of the first two responses. The number of times we delay our normal response is determined by the\n * component that originally called setIRR with an optional delay parameter.\n *\n * @this {ChipSet}\n * @param {number} [iPIC]\n * @return {number} IDT vector # of the next highest-priority interrupt, -1 if none, or -2 for \"please try your call again later\"\n */\n getIRRVector(iPIC)\n {\n if (iPIC === undefined) iPIC = 0;\n\n /*\n * Look for any IRR bits that aren't masked and aren't already in service...\n */\n let nIDT = -1;\n let pic = this.aPICs[iPIC];\n if (!pic.nDelay) {\n let bIR = pic.bIRR & ((pic.bISR | pic.bIMR) ^ 0xff);\n /*\n * The search for the next highest priority requested interrupt (that's also not in-service and not masked)\n * must start with whichever interrupt is opposite the lowest priority interrupt (normally 7, but technically\n * whatever bIRLow is currently set to). For example:\n *\n * If bIRLow is 7, then the priority order is: 0, 1, 2, 3, 4, 5, 6, 7.\n * If bIRLow is 6, then the priority order is: 7, 0, 1, 2, 3, 4, 5, 6.\n * If bIRLow is 5, then the priority order is: 6, 7, 0, 1, 2, 3, 4, 5.\n * etc.\n *\n * This process is similar to the search performed by non-specific EOIs, except those apply only to a single\n * PIC (which is why a slave interrupt must be EOI'ed twice: once for the slave PIC and again for the master),\n * whereas here we must search across all PICs.\n */\n let nIRL = pic.bIRLow + 1;\n while (true) {\n\n nIRL &= 0x7;\n let bIRNext = 1 << nIRL;\n\n /*\n * If we encounter an interrupt that's still in-service BEFORE we encounter a requested interrupt,\n * then we're done; we must allow a higher priority in-service interrupt to finish before acknowledging\n * any lower priority interrupts.\n */\n if (pic.bISR & bIRNext) break;\n\n if (bIR & bIRNext) {\n\n if (!iPIC && nIRL == ChipSet.IRQ.SLAVE) {\n /*\n * Slave interrupts are tied to the master PIC on IRQ2; query the slave PIC for the vector #\n */\n nIDT = this.getIRRVector(1);\n } else {\n /*\n * Get the starting IDT vector # from ICW2 and add the IR level to obtain the target IDT vector #\n */\n nIDT = pic.aICW[1] + nIRL;\n }\n\n if (nIDT >= 0) {\n pic.bISR |= bIRNext;\n\n /*\n * Setting the ISR implies clearing the IRR, but clearIRR() has side-effects we don't want\n * (eg, clearing the slave IRQ, notifying the CPU, etc), so we clear the IRR ourselves.\n */\n pic.bIRR &= ~bIRNext;\n\n let nIRQ = pic.nIRQBase + nIRL;\n if (DEBUG && this.messageEnabled(this.messageBitsIRQ(nIRQ))) {\n this.printMessage(\"getIRRVector(): IRQ \" + nIRQ + \" interrupting stack \" + this.dbg.toHexOffset(this.cpu.getSP(), this.cpu.getSS()), true, true);\n }\n if (MAXDEBUG && DEBUGGER) {\n this.acInterrupts[nIRQ]++;\n }\n }\n break;\n }\n\n if (nIRL++ == pic.bIRLow) break;\n }\n } else {\n nIDT = -2;\n pic.nDelay--;\n }\n return nIDT;\n }\n\n /**\n * setFPUInterrupt()\n *\n * @this {ChipSet}\n */\n setFPUInterrupt()\n {\n if (this.model >= ChipSet.MODEL_5170) {\n this.setIRR(ChipSet.IRQ.FPU);\n } else {\n /*\n * TODO: Determine whether we need to maintain an \"Active NMI\" state; ie, if NMI.DISABLE is cleared\n * later, and the FPU coprocessor is still indicating an error condition, should we then generate an NMI?\n */\n if (this.bNMI & ChipSet.NMI.ENABLE) {\n X86.helpInterrupt.call(this.cpu, X86.EXCEPTION.NMI);\n }\n }\n }\n\n /**\n * clearFPUInterrupt(fSet)\n *\n * @this {ChipSet}\n */\n clearFPUInterrupt()\n {\n if (this.model >= ChipSet.MODEL_5170) {\n this.clearIRR(ChipSet.IRQ.FPU);\n } else {\n /*\n * TODO: If we maintain an \"Active NMI\" state, then we will need code here to clear that state, as well\n * as code in outNMI() to clear that state and generate an NMI as needed.\n */\n }\n }\n\n /**\n * inTimer(iPIT, iPITTimer, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iPIT (0 or 1)\n * @param {number} iPITTimer (0, 1, or 2)\n * @param {number} port (0x40, 0x41, 0x42, etc)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inTimer(iPIT, iPITTimer, port, addrFrom)\n {\n let b;\n let iBaseTimer = (iPIT? 3 : 0);\n let timer = this.aTimers[iBaseTimer + iPITTimer];\n\n if (timer.fStatusLatched) {\n b = timer.bStatus;\n timer.fStatusLatched = false;\n }\n else {\n if (timer.countIndex == timer.countBytes) {\n this.resetTimerIndex(iBaseTimer + iPITTimer);\n }\n if (timer.fCountLatched) {\n b = timer.countLatched[timer.countIndex++];\n if (timer.countIndex == timer.countBytes) {\n timer.fCountLatched = false\n }\n }\n else {\n this.updateTimer(iBaseTimer + iPITTimer);\n b = timer.countCurrent[timer.countIndex++];\n }\n }\n if (this.messageEnabled(Messages.TIMER | Messages.PORT)) {\n this.printMessageIO(port, null, addrFrom, \"PIT\" + iPIT + \".TIMER\" + iPITTimer, b, true);\n }\n return b;\n }\n\n /**\n * outTimer(iPIT, iPITTimer, port, bOut, addrFrom)\n *\n * We now rely EXCLUSIVELY on setBurstCycles() to address situations where quick timer interrupt turn-around\n * is expected; eg, by the ROM BIOS POST when it sets TIMER0 to a low test count (0x16); since we typically\n * don't update any of the timers until after we've finished a burst of CPU cycles, we must reduce the current\n * burst cycle count, so that the current instruction burst will end at the same time a timer interrupt is expected.\n *\n * Note that in some cases, if the number of cycles remaining in the current burst is less than the target,\n * this may have the effect of *lengthening* the current burst instead of shortening it, but stepCPU() should be\n * OK with that.\n *\n * @this {ChipSet}\n * @param {number} iPIT (0 or 1)\n * @param {number} iPITTimer (0, 1, or 2)\n * @param {number} port (0x40, 0x41, 0x42, etc)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outTimer(iPIT, iPITTimer, port, bOut, addrFrom)\n {\n if (this.messageEnabled(Messages.TIMER | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"PIT\" + iPIT + \".TIMER\" + iPITTimer, null, true);\n }\n\n let iBaseTimer = (iPIT? 3 : 0);\n let timer = this.aTimers[iBaseTimer + iPITTimer];\n\n if (timer.countIndex == timer.countBytes) {\n this.resetTimerIndex(iBaseTimer + iPITTimer);\n }\n\n timer.countInit[timer.countIndex++] = bOut;\n\n if (timer.countIndex == timer.countBytes) {\n /*\n * In general, writing a new count to a timer that's already counting isn't supposed to affect the current\n * count, with the notable exceptions of MODE0 and MODE4.\n */\n if (!timer.fCounting || timer.mode == ChipSet.PIT_CTRL.MODE0 || timer.mode == ChipSet.PIT_CTRL.MODE4) {\n timer.fCountLatched = false;\n timer.countCurrent[0] = timer.countStart[0] = timer.countInit[0];\n timer.countCurrent[1] = timer.countStart[1] = timer.countInit[1];\n timer.nCyclesStart = this.cpu.getCycles(this.fScaleTimers);\n timer.fCounting = true;\n\n /*\n * I believe MODE0 is the only mode where OUT (fOUT) starts out low (false); for the rest of the modes,\n * OUT (fOUT) starts high (true). It's also my understanding that the way edge-triggered interrupts work\n * on the original PC is that an interrupt is requested only when the corresponding OUT transitions from\n * low to high.\n */\n timer.fOUT = (timer.mode != ChipSet.PIT_CTRL.MODE0);\n\n if (iPIT == ChipSet.PIT0.INDEX && iPITTimer == ChipSet.PIT0.TIMER0) {\n /*\n * TODO: Determine if there are situations/modes where I should NOT automatically clear IRQ0 on behalf of TIMER0.\n */\n this.clearIRR(ChipSet.IRQ.TIMER0);\n let countInit = this.getTimerInit(ChipSet.PIT0.TIMER0);\n let nCyclesRemain = (countInit * this.nTicksDivisor) | 0;\n if (timer.mode == ChipSet.PIT_CTRL.MODE3) nCyclesRemain >>= 1;\n this.cpu.setBurstCycles(nCyclesRemain);\n }\n }\n\n if (iPIT == ChipSet.PIT0.INDEX && iPITTimer == ChipSet.PIT0.TIMER2) this.setSpeaker();\n }\n }\n\n /**\n * inTimerCtrl(iPIT, port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iPIT (0 or 1)\n * @param {number} port (0x43 or 0x4B)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number|null} simulated port value\n */\n inTimerCtrl(iPIT, port, addrFrom)\n {\n this.printMessageIO(port, null, addrFrom, \"PIT\" + iPIT + \".CTRL\", null, Messages.TIMER);\n /*\n * NOTE: Even though reads to port 0x43 are undefined (I think), I'm going to \"define\" it\n * as returning the last value written, purely for the Debugger's benefit.\n */\n return iPIT? this.bPIT1Ctrl : this.bPIT0Ctrl;\n }\n\n /**\n * outTimerCtrl(iPIT, port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iPIT (0 or 1)\n * @param {number} port (0x43)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outTimerCtrl(iPIT, port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"PIT\" + iPIT + \".CTRL\", null, Messages.TIMER);\n\n /*\n * Extract the SC (Select Counter) bits.\n */\n let iBaseTimer = 0;\n let iPITTimer = (bOut & ChipSet.PIT_CTRL.SC);\n if (!iPIT) {\n this.bPIT0Ctrl = bOut;\n } else {\n iBaseTimer = 3;\n this.bPIT1Ctrl = bOut;\n }\n\n /*\n * Check for the Read-Back command and process as needed.\n */\n if (iPITTimer == ChipSet.PIT_CTRL.SC_BACK) {\n if (!(bOut & ChipSet.PIT_CTRL.RB_STATUS)) {\n for (iPITTimer = 0; iPITTimer <= 2; iPITTimer++) {\n if (bOut & (ChipSet.PIT_CTRL.RB_CTR0 << iPITTimer)) {\n this.latchTimerStatus(iBaseTimer + iPITTimer);\n }\n }\n }\n if (!(bOut & ChipSet.PIT_CTRL.RB_COUNTS)) {\n for (iPITTimer = 0; iPITTimer <= 2; iPITTimer++) {\n if (bOut & (ChipSet.PIT_CTRL.RB_CTR0 << iPITTimer)) {\n this.latchTimerCount(iBaseTimer + iPITTimer);\n }\n }\n }\n return;\n }\n\n /*\n * Convert the SC (Select Counter) bits into an iPITTimer index (0-2).\n */\n iPITTimer >>= ChipSet.PIT_CTRL.SC_SHIFT;\n\n /*\n * Extract BCD (bit 0), MODE (bits 1-3), and RW (bits 4-5), which we simply store as-is (see setTimerMode).\n */\n let bcd = (bOut & ChipSet.PIT_CTRL.BCD);\n let mode = (bOut & ChipSet.PIT_CTRL.MODE);\n let rw = (bOut & ChipSet.PIT_CTRL.RW);\n\n if (rw == ChipSet.PIT_CTRL.RW_LATCH) {\n /*\n * Of all the RW bit combinations, this is the only one that \"countermands\" normal control register\n * processing (the BCD and MODE bits are \"don't care\").\n */\n this.latchTimerCount(iBaseTimer + iPITTimer);\n }\n else {\n this.setTimerMode(iBaseTimer + iPITTimer, bcd, mode, rw);\n\n /*\n * The 5150 ROM BIOS code @F000:E285 (\"TEST.7\") would fail after a warm boot (eg, after a CTRL-ALT-DEL) because\n * it assumed that no TIMER0 interrupt would occur between the point it unmasked the TIMER0 interrupt and the\n * point it started reprogramming TIMER0.\n *\n * Similarly, the 5160 ROM BIOS @F000:E35D (\"8253 TIMER CHECKOUT\") would fail after initializing the EGA BIOS,\n * because the EGA BIOS uses TIMER0 during its diagnostics; as in the previous example, by the time the 8253\n * test code runs later, there's now a pending TIMER0 interrupt, which triggers an interrupt as soon as IRQ0 is\n * unmasked @F000:E364.\n *\n * After looking at this problem at bit more closely the second time around (while debugging the EGA BIOS),\n * it turns out I missed an important 8253 feature: whenever a new MODE0 control word OR a new MODE0 count\n * is written, fOUT (which is what drives IRQ0) goes low. So, by simply adding an appropriate clearIRR() call\n * both here and in outTimer(), this annoying problem seems to be gone.\n *\n * TODO: Determine if there are situations/modes where I should NOT automatically clear IRQ0 on behalf of TIMER0.\n */\n if (iPIT == ChipSet.PIT0.INDEX && iPITTimer == ChipSet.PIT0.TIMER0) this.clearIRR(ChipSet.IRQ.TIMER0);\n\n /*\n * Another TIMER0 HACK: The \"CASSETTE DATA WRAP TEST\" @F000:E51E occasionally reports an error when the second of\n * two TIMER0 counts it latches is greater than the first. You would think the ROM BIOS would expect this, since\n * TIMER0 can reload its count at any time. Is the ROM BIOS assuming that TIMER0 was initialized sufficiently\n * recently that this should never happen? I'm not sure, but for now, let's try resetting TIMER0's count immediately\n * after TIMER2 has been reprogrammed for the test in question (ie, when interrupts are masked and PPIB is set as\n * shown below).\n *\n * FWIW, I believe the cassette hardware was discontinued after MODEL_5150, and even if the test fails, it's non-fatal;\n * the ROM BIOS displays an error (131) and moves on.\n */\n if (iPIT == ChipSet.PIT0.INDEX && iPITTimer == ChipSet.PIT0.TIMER2) {\n let pic = this.aPICs[0];\n if (pic.bIMR == 0xff && this.bPPIB == (ChipSet.PPI_B.CLK_TIMER2 | ChipSet.PPI_B.ENABLE_SW2 | ChipSet.PPI_B.CASS_MOTOR_OFF | ChipSet.PPI_B.CLK_KBD)) {\n let timer = this.aTimers[0];\n timer.countStart[0] = timer.countInit[0];\n timer.countStart[1] = timer.countInit[1];\n timer.nCyclesStart = this.cpu.getCycles(this.fScaleTimers);\n if (DEBUG && this.messageEnabled(Messages.TIMER)) {\n this.printMessage(\"PIT0.TIMER0 count reset @\" + timer.nCyclesStart + \" cycles\", true);\n }\n }\n }\n }\n }\n\n /**\n * getTimerInit(iTimer)\n *\n * @this {ChipSet}\n * @param {number} iTimer\n * @return {number} initial timer count\n */\n getTimerInit(iTimer)\n {\n let timer = this.aTimers[iTimer];\n let countInit = (timer.countInit[1] << 8) | timer.countInit[0];\n if (!countInit) countInit = (timer.countBytes == 1? 0x100 : 0x10000);\n return countInit;\n }\n\n /**\n * getTimerStart(iTimer)\n *\n * @this {ChipSet}\n * @param {number} iTimer\n * @return {number} starting timer count (from the initial timer count for the current countdown)\n */\n getTimerStart(iTimer)\n {\n let timer = this.aTimers[iTimer];\n let countStart = (timer.countStart[1] << 8) | timer.countStart[0];\n if (!countStart) countStart = (timer.countBytes == 1? 0x100 : 0x10000);\n return countStart;\n }\n\n /**\n * getTimerCycleLimit(iTimer, nCycles)\n *\n * This is called by the CPU to determine the maximum number of cycles it can process for the current burst.\n * It's presumed that no instructions have been executed since the last updateTimer(iTimer) call.\n *\n * @this {ChipSet}\n * @param {number} iTimer\n * @param {number} nCycles desired\n * @return {number} maximum number of cycles remaining for the specified timer (<= nCycles)\n */\n getTimerCycleLimit(iTimer, nCycles)\n {\n let timer = this.aTimers[iTimer];\n if (timer.fCounting) {\n let nCyclesUpdate = this.cpu.getCycles(this.fScaleTimers);\n let ticksElapsed = ((nCyclesUpdate - timer.nCyclesStart) / this.nTicksDivisor) | 0;\n // DEBUG:\n let countStart = this.getTimerStart(iTimer);\n let count = countStart - ticksElapsed;\n if (timer.mode == ChipSet.PIT_CTRL.MODE3) count -= ticksElapsed;\n // DEBUG:\n let nCyclesRemain = (count * this.nTicksDivisor) | 0;\n if (timer.mode == ChipSet.PIT_CTRL.MODE3) nCyclesRemain >>= 1;\n if (nCycles > nCyclesRemain) nCycles = nCyclesRemain;\n }\n return nCycles;\n }\n\n /**\n * latchTimerCount(iTimer)\n *\n * @this {ChipSet}\n * @param {number} iTimer\n */\n latchTimerCount(iTimer)\n {\n /*\n * Update the timer's current count.\n */\n this.updateTimer(iTimer);\n\n /*\n * Now we can latch it.\n */\n let timer = this.aTimers[iTimer];\n timer.countLatched[0] = timer.countCurrent[0];\n timer.countLatched[1] = timer.countCurrent[1];\n timer.fCountLatched = true;\n\n /*\n * VERIFY: That a latch request resets the timer index.\n */\n this.resetTimerIndex(iTimer);\n }\n\n /**\n * latchTimerStatus(iTimer)\n *\n * @this {ChipSet}\n * @param {number} iTimer\n */\n latchTimerStatus(iTimer)\n {\n let timer = this.aTimers[iTimer];\n if (!timer.fStatusLatched) {\n this.updateTimer(iTimer);\n timer.bStatus = timer.bcd | timer.mode | timer.rw | (timer.countIndex < timer.countBytes? ChipSet.PIT_CTRL.RB_NULL : 0) | (timer.fOUT? ChipSet.PIT_CTRL.RB_OUT : 0);\n timer.fStatusLatched = true;\n }\n }\n\n /**\n * setTimerMode(iTimer, bcd, mode, rw)\n *\n * FYI: After setting a timer's mode, the CPU must set the timer's count before it becomes operational;\n * ie, before fCounting becomes true.\n *\n * @this {ChipSet}\n * @param {number} iTimer\n * @param {number} bcd\n * @param {number} mode\n * @param {number} rw\n */\n setTimerMode(iTimer, bcd, mode, rw)\n {\n let timer = this.aTimers[iTimer];\n timer.rw = rw;\n timer.mode = mode;\n timer.bcd = bcd;\n timer.countInit = [0, 0];\n timer.countCurrent = [0, 0];\n timer.countLatched = [0, 0];\n timer.fOUT = false;\n timer.fCountLatched = false;\n timer.fCounting = false;\n timer.fStatusLatched = false;\n this.resetTimerIndex(iTimer);\n }\n\n /**\n * resetTimerIndex(iTimer)\n *\n * @this {ChipSet}\n * @param {number} iTimer\n */\n resetTimerIndex(iTimer)\n {\n let timer = this.aTimers[iTimer];\n timer.countIndex = (timer.rw == ChipSet.PIT_CTRL.RW_MSB? 1 : 0);\n timer.countBytes = (timer.rw == ChipSet.PIT_CTRL.RW_BOTH? 2 : 1);\n }\n\n /**\n * updateTimer(iTimer, fCycleReset)\n *\n * updateTimer() calculates and updates a timer's current count purely on an \"on-demand\" basis; we don't\n * actually adjust timer counters every 4 CPU cycles on a 4.77Mhz PC, since updating timers that frequently\n * would be prohibitively slow. If you're single-stepping the CPU, then yes, updateTimer() will be called\n * after every stepCPU(), via updateAllTimers(), but if we're doing our job correctly here, the frequency\n * of calls to updateTimer() should not affect timer counts across otherwise identical runs.\n *\n * TODO: Implement support for all TIMER modes, and verify that all the modes currently implemented are\n * \"up to spec\"; they're close enough to make the ROM BIOS happy, but beyond that, I've done very little.\n *\n * @this {ChipSet}\n * @param {number} iTimer\n * 0: Time-of-Day interrupt (~18.2 interrupts/second)\n * 1: DMA refresh\n * 2: Sound/Cassette\n * @param {boolean} [fCycleReset] is true if a cycle-count reset is about to occur\n * @return {Object} timer\n */\n updateTimer(iTimer, fCycleReset)\n {\n let timer = this.aTimers[iTimer];\n\n /*\n * Every timer's counting state is gated by its own fCounting flag; TIMER2 is further gated by PPI_B's\n * CLK_TIMER2 bit.\n */\n if (timer.fCounting && (iTimer != ChipSet.PIT0.TIMER2 || (this.bPPIB & ChipSet.PPI_B.CLK_TIMER2))) {\n /*\n * We determine the current timer count based on how many instruction cycles have elapsed since we started\n * the timer. Timers are supposed to be \"ticking\" at a rate of 1193181.8181 times per second, which is\n * the system clock of 14.31818Mhz, divided by 12.\n *\n * Similarly, for an 8088, there are supposed to be 4.77Mhz instruction cycles per second, which comes from\n * the system clock of 14.31818Mhz, divided by 3.\n *\n * If we divide 4,772,727 CPU cycles per second by 1,193,181 ticks per second, we get 4 cycles per tick,\n * which agrees with the ratio of the clock divisors: 12 / 3 == 4.\n *\n * However, if getCycles() is being called with fScaleTimers == true AND the CPU is running faster than its\n * base cycles-per-second setting, then getCycles() will divide the cycle count by the CPU's cycle multiplier,\n * so that the timers fire with the same real-world frequency that the user expects. However, that will\n * break any code (eg, the ROM BIOS diagnostics) that assumes that the timers are ticking once every 4 cycles\n * (or more like every 5 cycles on a 6Mhz 80286).\n *\n * So, when using a machine with the ChipSet \"scaleTimers\" property set, make sure you reset the machine's\n * speed prior to rebooting, otherwise you're likely to see ROM BIOS errors. Ditto for any application code\n * that makes similar assumptions about the relationship between CPU and timer speeds.\n *\n * In general, you're probably better off NOT using the \"scaleTimers\" property, and simply allowing the timers\n * to tick faster as you increase CPU speed (which is why fScaleTimers defaults to false).\n */\n let nCycles = this.cpu.getCycles(this.fScaleTimers);\n\n /*\n * Instead of maintaining partial tick counts, we calculate a fresh countCurrent from countStart every\n * time we're called, using the cycle count recorded when the timer was initialized. countStart is set\n * to countInit when fCounting is first set, and then it is refreshed from countInit at the expiration of\n * every count, so that if someone loaded a new countInit in the meantime (eg, BASICA), we'll pick it up.\n *\n * For the original MODEL_5170, the number of cycles per tick is approximately 6,000,000 / 1,193,181,\n * or 5.028575, so we can no longer always divide cycles by 4 with a simple right-shift by 2. The proper\n * divisor (eg, 4 for MODEL_5150 and MODEL_5160, 5 for MODEL_5170, etc) is nTicksDivisor, which initBus()\n * calculates using the base CPU speed returned by cpu.getBaseCyclesPerSecond().\n */\n let ticksElapsed = ((nCycles - timer.nCyclesStart) / this.nTicksDivisor) | 0;\n\n if (ticksElapsed < 0) {\n if (DEBUG && this.messageEnabled(Messages.TIMER)) {\n this.printMessage(\"updateTimer(\" + iTimer + \"): negative tick count (\" + ticksElapsed + \")\", true);\n }\n timer.nCyclesStart = nCycles;\n ticksElapsed = 0;\n }\n\n let countInit = this.getTimerInit(iTimer);\n let countStart = this.getTimerStart(iTimer);\n\n let fFired = false;\n let count = countStart - ticksElapsed;\n\n /*\n * NOTE: This mode is used by ROM BIOS test code that wants to verify timer interrupts are arriving\n * neither too slowly nor too quickly. As a result, I've had to add some corresponding trickery\n * in outTimer() to force interrupt simulation immediately after a low initial count (0x16) has been set.\n */\n if (timer.mode == ChipSet.PIT_CTRL.MODE0) {\n if (count <= 0) count = 0;\n if (DEBUG && this.messageEnabled(Messages.TIMER)) {\n this.printMessage(\"updateTimer(\" + iTimer + \"): MODE0 timer count=\" + count, true);\n }\n if (!count) {\n timer.fOUT = true;\n timer.fCounting = false;\n if (!iTimer) {\n fFired = true;\n this.setIRR(ChipSet.IRQ.TIMER0);\n if (MAXDEBUG && DEBUGGER) this.acTimersFired[iTimer]++;\n }\n }\n }\n /*\n * Early implementation of this mode was minimal because when using this mode, the ROM BIOS simply wanted\n * to see the count changing; it wasn't looking for interrupts. See ROM BIOS \"TEST.03\" code @F000:E0DE,\n * where TIMER1 is programmed for MODE2, LSB (the same settings, incidentally, used immediately afterward\n * for TIMER1 in conjunction with DMA channel 0 memory refreshes).\n *\n * Now this mode generates interrupts. Note that OUT goes low when the count reaches 1, then high\n * one tick later, at which point the count is reloaded and counting continues.\n *\n * Chances are, we will often miss the exact point at which the count becomes 1 (or more importantly,\n * one tick later, when the count *would* become 0, since that's when OUT transitions from low to high),\n * but as with MODE3, hopefully no one will mind.\n *\n * FYI, technically, it appears that the count is never supposed to reach 0, and that an initial count of 1\n * is \"illegal\", whatever that means.\n */\n else if (timer.mode == ChipSet.PIT_CTRL.MODE2) {\n timer.fOUT = (count != 1); // yes, this line does seem rather pointless....\n if (count <= 0) {\n count = countInit + count;\n if (count <= 0) {\n /*\n * TODO: Consider whether we ever care about TIMER1 or TIMER2 underflow\n */\n if (DEBUG && this.messageEnabled(Messages.TIMER) && !iTimer) {\n this.printMessage(\"updateTimer(\" + iTimer + \"): mode=2, underflow=\" + count, true);\n }\n count = countInit;\n }\n timer.countStart[0] = count & 0xff;\n timer.countStart[1] = (count >> 8) & 0xff;\n timer.nCyclesStart = nCycles;\n if (!iTimer && timer.fOUT) {\n fFired = true;\n this.setIRR(ChipSet.IRQ.TIMER0);\n if (MAXDEBUG && DEBUGGER) this.acTimersFired[iTimer]++;\n }\n }\n }\n /*\n * NOTE: This is the normal mode for TIMER0, which the ROM BIOS uses to generate h/w interrupts roughly\n * 18.2 times per second. In this mode, the count must be decremented twice as fast (hence the extra ticks\n * subtraction below, in addition to the subtraction above), but IRQ_TIMER0 is raised only on alternate\n * iterations; ie, only when fOUT transitions to true (\"high\"). The equal alternating fOUT states is why\n * this mode is referred to as \"square wave\" mode.\n *\n * TODO: Implement the correct behavior for this mode when the count is ODD. In that case, fOUT is supposed\n * to be \"high\" for (N + 1) / 2 ticks and \"low\" for (N - 1) / 2 ticks.\n */\n else if (timer.mode == ChipSet.PIT_CTRL.MODE3) {\n count -= ticksElapsed;\n if (count <= 0) {\n timer.fOUT = !timer.fOUT;\n count = countInit + count;\n if (count <= 0) {\n /*\n * TODO: Consider whether we ever care about TIMER1 or TIMER2 underflow\n */\n if (DEBUG && this.messageEnabled(Messages.TIMER) && !iTimer) {\n this.printMessage(\"updateTimer(\" + iTimer + \"): mode=3, underflow=\" + count, true);\n }\n count = countInit;\n }\n if (MAXDEBUG && DEBUGGER && !iTimer) {\n let nCycleDelta = 0;\n if (this.acTimer0Counts.length > 0) nCycleDelta = nCycles - this.acTimer0Counts[0][1];\n this.acTimer0Counts.push([count, nCycles, nCycleDelta]);\n }\n timer.countStart[0] = count & 0xff;\n timer.countStart[1] = (count >> 8) & 0xff;\n timer.nCyclesStart = nCycles;\n if (!iTimer && timer.fOUT) {\n fFired = true;\n this.setIRR(ChipSet.IRQ.TIMER0);\n if (MAXDEBUG && DEBUGGER) this.acTimersFired[iTimer]++;\n }\n }\n }\n\n if (MAXDEBUG && this.messageEnabled(Messages.TIMER | Messages.WARN)) {\n this.log(\"TIMER\" + iTimer + \" count: \" + count + \", ticks: \" + ticksElapsed + \", fired: \" + (fFired? \"true\" : \"false\"));\n }\n\n timer.countCurrent[0] = count & 0xff;\n timer.countCurrent[1] = (count >> 8) & 0xff;\n if (fCycleReset) this.nCyclesStart = 0;\n }\n return timer;\n }\n\n /**\n * updateAllTimers(fCycleReset)\n *\n * @this {ChipSet}\n * @param {boolean} [fCycleReset] is true if a cycle-count reset is about to occur\n */\n updateAllTimers(fCycleReset)\n {\n for (let iTimer = 0; iTimer < this.aTimers.length; iTimer++) {\n this.updateTimer(iTimer, fCycleReset);\n }\n if (this.model >= ChipSet.MODEL_5170) this.updateRTCTime();\n }\n\n /**\n * outMFGTest(port, bOut, addrFrom)\n * \n * This is test port on the PCjr (MODEL_4860) only.\n *\n * @this {ChipSet}\n * @param {number} port (0x10)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outMFGTest(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"MFG_TEST\");\n }\n\n /**\n * inPPIA(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x60)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inPPIA(port, addrFrom)\n {\n let b = this.bPPIA;\n if (this.bPPICtrl & ChipSet.PPI_CTRL.A_IN) {\n if (this.bPPIB & ChipSet.PPI_B.CLEAR_KBD) {\n b = this.aDIPSwitches[0][1];\n } else {\n b = this.bKbdData;\n this.printMessageIO(port, null, addrFrom, \"PPI_A\", b, Messages.KBD);\n return b;\n }\n }\n this.printMessageIO(port, null, addrFrom, \"PPI_A\", b);\n return b;\n }\n\n /**\n * outPPIA(port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x60)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outPPIA(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"PPI_A\");\n this.bPPIA = bOut;\n }\n\n /**\n * inPPIB(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x61)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inPPIB(port, addrFrom)\n {\n let b = this.bPPIB;\n this.printMessageIO(port, null, addrFrom, \"PPI_B\", b);\n return b;\n }\n\n /**\n * outPPIB(port, bOut, addrFrom)\n *\n * This is the original (MODEL_5150 and MODEL_5160) handler for port 0x61. Functionality common\n * to all models must be placed in updatePPIB().\n *\n * @this {ChipSet}\n * @param {number} port (0x61)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outPPIB(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"PPI_B\");\n this.updatePPIB(bOut);\n }\n\n /**\n * updatePPIB(bOut)\n *\n * On MODEL_5170 and up, this updates the \"simulated\" PPI_B. The only common (and well-documented) PPI_B bits\n * across all models are PPI_B.CLK_TIMER2 and PPI_B.SPK_TIMER2, so its possible that this function may need to\n * limit its updates to just those bits, and move any model-specific requirements back into the appropriate I/O\n * handlers (PPIB or 8042RWReg). We'll see.\n *\n * UPDATE: The WOLF3D keyboard interrupt handler toggles the CLEAR_KBD bit of port 0x61 (ie, it sets and then\n * clears the bit) after reading the scan code from port 0x60; assuming that they use the same interrupt handler\n * for all machine models (which I haven't verified), the clear implication is that updatePPIB() also needs to\n * support CLEAR_KBD and CLK_KBD, so I've moved that code from outPPIB() to updatePPIB().\n *\n * @this {ChipSet}\n * @param {number} bOut\n */\n updatePPIB(bOut)\n {\n let fNewSpeaker = !!(bOut & ChipSet.PPI_B.SPK_TIMER2);\n let fOldSpeaker = !!(this.bPPIB & ChipSet.PPI_B.SPK_TIMER2);\n this.bPPIB = bOut;\n if (this.kbd) this.kbd.setEnabled(!(bOut & ChipSet.PPI_B.CLEAR_KBD), !!(bOut & ChipSet.PPI_B.CLK_KBD));\n if (fNewSpeaker != fOldSpeaker) {\n /*\n * Originally, this code didn't catch the \"ERROR_BEEP\" case @F000:EC34, which first turns both PPI_B.CLK_TIMER2 (0x01)\n * and PPI_B.SPK_TIMER2 (0x02) off, then turns on only PPI_B.SPK_TIMER2 (0x02), then restores the original port value.\n *\n * So, when the ROM BIOS keyboard buffer got full, we didn't issue a BEEP alert. I've fixed that by limiting the test\n * to PPI_B.SPK_TIMER2 and ignoring PPI_B.CLK_TIMER2.\n */\n this.setSpeaker(fNewSpeaker);\n }\n }\n\n /**\n * inPPIC(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x62)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inPPIC(port, addrFrom)\n {\n let b = 0;\n\n /*\n * If you ever wanted to simulate I/O channel errors or R/W memory parity errors, you could\n * add either PPI_C.IO_CHANNEL_CHK (0x40) or PPI_C.RW_PARITY_CHK (0x80) to the return value (b).\n */\n if ((this.model|0) == ChipSet.MODEL_4860) {\n b |= this.bNMI & ChipSet.NMI.KBD_LATCH;\n /*\n * We're going to hard-code the rest of the PCjr settings for now, including NOT setting the NO_KBD_CABLE\n * bit, on the theory that if we don't have to deal with IR hardware emulation, so much the better.\n */\n b |= ChipSet.PPI_C.NO_MODEM | ChipSet.PPI_C.NO_DISKETTE | ChipSet.PPI_C.NO_MEMEXP;\n /*\n * I'm just guessing at how keyboard data is \"clocked\" into the the KBD_DATA bit; this will be revisited.\n */\n b |= (this.bKbdData & 0x1)? ChipSet.PPI_C.KBD_DATA : 0;\n this.bKbdData >>>= 1;\n }\n else if ((this.model|0) == ChipSet.MODEL_5150) {\n if (this.bPPIB & ChipSet.PPI_B.ENABLE_SW2) {\n b |= this.aDIPSwitches[1][1] & ChipSet.PPI_C.SW;\n } else {\n b |= (this.aDIPSwitches[1][1] >> 4) & 0x1;\n }\n } else {\n if (this.bPPIB & ChipSet.PPI_B.ENABLE_SW_HI) {\n b |= this.aDIPSwitches[0][1] >> 4;\n } else {\n b |= this.aDIPSwitches[0][1] & 0xf;\n }\n }\n\n if (this.bPPIB & ChipSet.PPI_B.CLK_TIMER2) {\n let timer = this.updateTimer(ChipSet.PIT0.TIMER2);\n if (timer.fOUT) {\n if (this.bPPIB & ChipSet.PPI_B.SPK_TIMER2)\n b |= ChipSet.PPI_C.TIMER2_OUT;\n else\n b |= ChipSet.PPI_C.CASS_DATA_IN;\n }\n }\n\n /*\n * The ROM BIOS polls this port incessantly during its memory tests, checking for memory parity errors\n * (which of course we never report), so you must use both Messages.PORT and Messages.CHIPSET.\n */\n this.printMessageIO(port, null, addrFrom, \"PPI_C\", b, Messages.CHIPSET);\n return b;\n }\n\n /**\n * outPPIC(port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x62)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outPPIC(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"PPI_C\");\n this.bPPIC = bOut;\n }\n\n /**\n * inPPICtrl(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x63)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inPPICtrl(port, addrFrom)\n {\n let b = this.bPPICtrl;\n this.printMessageIO(port, null, addrFrom, \"PPI_CTRL\", b);\n return b;\n }\n\n /**\n * outPPICtrl(port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x63)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outPPICtrl(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"PPI_CTRL\");\n this.bPPICtrl = bOut;\n }\n\n /**\n * in8041Kbd(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x60)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n in8041Kbd(port, addrFrom)\n {\n let b = this.bKbdData;\n this.printMessageIO(port, null, addrFrom, \"8041_KBD\", b, Messages.KBD);\n this.b8041Status &= ~ChipSet.C8042.STATUS.OUTBUFF_FULL;\n return b;\n }\n\n /**\n * out8041Kbd(port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x60)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n out8041Kbd(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"8041_KBD\");\n // if (this.kbd) this.kbd.receiveCmd(bOut);\n }\n\n /**\n * in8041Ctrl(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x61)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n in8041Ctrl(port, addrFrom)\n {\n let b = this.bPPIB;\n this.printMessageIO(port, null, addrFrom, \"8041_CTRL\", b);\n return b;\n }\n\n /**\n * out8041Ctrl(port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x61)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n out8041Ctrl(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"8041_CTRL\");\n this.updatePPIB(bOut);\n }\n\n /**\n * in8041Status(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x64)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n in8041Status(port, addrFrom)\n {\n let b = this.b8041Status;\n this.printMessageIO(port, null, addrFrom, \"8041_STATUS\", b);\n return b;\n }\n\n /**\n * in8042OutBuff(port, addrFrom)\n *\n * Return the contents of the OUTBUFF register and clear the OUTBUFF_FULL status bit.\n *\n * Moreover, we also call kbd.checkBuffer() to let the Keyboard know that we just pulled\n * data, so that it can reset its internal timer controlling the delivery of additional data.\n * \n * Note that there are applications like BASICA that install a keyboard interrupt handler\n * that reads OUTBUFF, does some scan code preprocessing, and then passes control on to the\n * ROM's interrupt handler. As a result, OUTBUFF is read multiple times during a single\n * interrupt, so we need to avoid filling it with new data after every read; otherwise,\n * scan codes will get dropped.\n *\n * The safest thing to do is to wait until kbd.setEnabled() is called, and let that call supply\n * more data to receiveKbdData(). That will happen as soon as the ROM re-enables the controller,\n * and is why C8042.CMD.ENABLE_KBD processing ends with a call to kbd.checkBuffer(). However,\n * not all software (eg, Xenix 286, and the Windows 95 VMM) does that, so we have to rely on\n * the Keyboard's internal timer.\n *\n * Also note that, the foregoing notwithstanding, I still clear the OUTBUFF_FULL bit here\n * (as I believe I should); fortunately, none of the interrupt handlers I've seen rely on\n * OUTBUFF_FULL as a prerequisite for reading OUTBUFF (certainly not BASICA or the ROM).\n * The assumption seems to be that if an interrupt occurred, OUTBUFF must contain data,\n * regardless of the state of OUTBUFF_FULL.\n *\n * @this {ChipSet}\n * @param {number} port (0x60)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n in8042OutBuff(port, addrFrom)\n {\n let b = this.b8042OutBuff;\n this.printMessageIO(port, null, addrFrom, \"8042_OUTBUFF\", b, Messages.C8042);\n this.b8042Status &= ~(ChipSet.C8042.STATUS.OUTBUFF_FULL | ChipSet.C8042.STATUS.OUTBUFF_DELAY);\n if (this.kbd) this.kbd.checkBuffer(b);\n return b;\n }\n\n /**\n * out8042InBuffData(port, bOut, addrFrom)\n *\n * This writes to the 8042's input buffer; using this port (ie, 0x60 instead of 0x64) designates the\n * the byte as a C8042.DATA.CMD \"data byte\". Before clearing C8042.STATUS.CMD_FLAG, however, we see if it's set,\n * and then based on the previous C8042.CMD \"command byte\", we do whatever needs to be done with this \"data byte\".\n *\n * @this {ChipSet}\n * @param {number} port (0x60)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n out8042InBuffData(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"8042_INBUF.DATA\", null, Messages.C8042);\n\n if (this.b8042Status & ChipSet.C8042.STATUS.CMD_FLAG) {\n\n switch (this.b8042InBuff) {\n\n case ChipSet.C8042.CMD.WRITE_CMD:\n this.set8042CmdData(bOut);\n break;\n\n case ChipSet.C8042.CMD.WRITE_OUTPORT:\n this.set8042OutPort(bOut);\n break;\n\n /*\n * This case is reserved for command bytes that the 8042 is not expecting, which should therefore be passed\n * on to the Keyboard itself.\n *\n * Here's some relevant MODEL_5170 ROM BIOS code, \"XMIT_8042\" (missing from the original MODEL_5170 ROM BIOS\n * listing), which sends a command code in AL to the Keyboard and waits for a response, returning it in AL.\n * Note that the only \"success\" exit path from this function involves LOOPing 64K times before finally reading\n * the Keyboard's response; either the hardware and/or this code seems a bit brain-damaged if that's REALLY\n * what you had to do to ensure a valid response....\n *\n * F000:1B25 86E0 XCHG AH,AL\n * F000:1B27 2BC9 SUB CX,CX\n * F000:1B29 E464 IN AL,64\n * F000:1B2B A802 TEST AL,02 ; WAIT FOR INBUFF_FULL TO BE CLEAR\n * F000:1B2D E0FA LOOPNZ 1B29\n * F000:1B2F E334 JCXZ 1B65 ; EXIT WITH ERROR (CX == 0)\n * F000:1B31 86E0 XCHG AH,AL\n * F000:1B33 E660 OUT 60,AL ; SAFE TO WRITE KEYBOARD CMD TO INBUFF NOW\n * F000:1B35 2BC9 SUB CX,CX\n * F000:1B37 E464 IN AL,64\n * F000:1B39 8AE0 MOV AH,AL\n * F000:1B3B A801 TEST AL,01\n * F000:1B3D 7402 JZ 1B41\n * F000:1B3F E460 IN AL,60 ; READ PORT 0x60 IF OUTBUFF_FULL SET (\"FLUSH\"?)\n * F000:1B41 F6C402 TEST AH,02\n * F000:1B44 E0F1 LOOPNZ 1B37\n * F000:1B46 751D JNZ 1B65 ; EXIT WITH ERROR (CX == 0)\n * F000:1B48 B306 MOV BL,06\n * F000:1B4A 2BC9 SUB CX,CX\n * F000:1B4C E464 IN AL,64\n * F000:1B4E A801 TEST AL,01\n * F000:1B50 E1FA LOOPZ 1B4C\n * F000:1B52 7508 JNZ 1B5C ; PROCEED TO EXIT NOW THAT OUTBUFF_FULL IS SET\n * F000:1B54 FECB DEC BL\n * F000:1B56 75F4 JNZ 1B4C\n * F000:1B58 FEC3 INC BL\n * F000:1B5A EB09 JMP 1B65 ; EXIT WITH ERROR (CX == 0)\n * F000:1B5C 2BC9 SUB CX,CX\n * F000:1B5E E2FE LOOP 1B5E ; LOOOOOOPING....\n * F000:1B60 E460 IN AL,60\n * F000:1B62 83E901 SUB CX,0001 ; EXIT WITH SUCCESS (CX != 0)\n * F000:1B65 C3 RET\n *\n * But WAIT, the FUN doesn't end there. After this function returns, \"KBD_RESET\" waits for a Keyboard\n * interrupt to occur, hoping for scan code 0xAA as the Keyboard's final response. \"KBD_RESET\" also returns\n * CX to the caller, and the caller (\"TEST.21\") assumes there was no interrupt if CX is zero.\n *\n * MOV AL,0FDH\n * OUT INTA01,AL\n * MOV INTR_FLAG,0\n * STI\n * MOV BL,10\n * SUB CX,CX\n * G11: TEST [1NTR_FLAG],02H\n * JNZ G12\n * LOOP G11\n * DEC BL\n * JNZ G11\n * ...\n *\n * However, if [INTR_FLAG] is set immediately, the above code will exit immediately, without ever decrementing\n * CX. CX can be zero not only if the loop exhausted it, but also if no looping was required; the latter is not\n * an error, but \"TEST.21\" assumes that it is.\n */\n default:\n this.set8042CmdData(this.b8042CmdData & ~ChipSet.C8042.DATA.CMD.NO_CLOCK);\n if (this.kbd) this.set8042OutBuff(this.kbd.receiveCmd(bOut));\n break;\n }\n }\n this.b8042InBuff = bOut;\n this.b8042Status &= ~ChipSet.C8042.STATUS.CMD_FLAG;\n }\n\n /**\n * in8042RWReg(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x61)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n in8042RWReg(port, addrFrom)\n {\n /*\n * Normally, we return whatever was last written to this port, but we do need to mask the\n * two upper-most bits (C8042.RWREG.NMI_ERROR), as those are output-only bits used to signal\n * parity errors.\n *\n * Also, \"TEST.09\" of the MODEL_5170 BIOS expects the REFRESH_BIT to alternate, so we used to\n * do this:\n *\n * this.bPPIB ^= ChipSet.C8042.RWREG.REFRESH_BIT;\n *\n * However, the MODEL_5170_REV3 BIOS not only checks REFRESH_BIT in \"TEST.09\", but includes\n * an additional test right before \"TEST.11A\", which requires the bit change \"a bit less\"\n * frequently. This new test sets CX to zero, and at the end of the test (@F000:05B8), CX\n * must be in the narrow range of 0xF600 through 0xF9FD.\n *\n * In fact, the new \"WAITF\" function @F000:1A3A tells us exactly how frequently REFRESH_BIT\n * is expected to change now. That function performs a \"FIXED TIME WAIT\", where CX is a\n * \"COUNT OF 15.085737us INTERVALS TO WAIT\".\n *\n * So we now tie the state of the REFRESH_BIT to bit 6 of the current CPU cycle count,\n * effectively toggling the bit after every 64 cycles. On an 8Mhz CPU that can do 8 cycles\n * in 1us, 64 cycles represents 8us, so that might be a bit fast for \"WAITF\", but bit 6\n * is the only choice that also satisfies the pre-\"TEST.11A\" test as well.\n */\n let b = this.bPPIB & ~(ChipSet.C8042.RWREG.NMI_ERROR | ChipSet.C8042.RWREG.REFRESH_BIT) | ((this.cpu.getCycles() & 0x40)? ChipSet.C8042.RWREG.REFRESH_BIT : 0);\n /*\n * Thanks to the WAITF function, this has become a very \"busy\" port, so if this generates too\n * many messages, try adding Messages.WARN to the criteria.\n */\n this.printMessageIO(port, null, addrFrom, \"8042_RWREG\", b, Messages.C8042 | Messages.WARN);\n return b;\n }\n\n /**\n * out8042RWReg(port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x61)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n out8042RWReg(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"8042_RWREG\", null, Messages.C8042);\n this.updatePPIB(bOut);\n }\n\n /**\n * in8042Status(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x64)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n in8042Status(port, addrFrom)\n {\n this.printMessageIO(port, null, addrFrom, \"8042_STATUS\", this.b8042Status, Messages.C8042);\n let b = this.b8042Status & 0xff;\n /*\n * There's code in the 5170 BIOS (F000:03BF) that writes an 8042 command (0xAA), waits for\n * C8042.STATUS.INBUFF_FULL to go clear (which it always is, because we always accept commands\n * immediately), then checks C8042.STATUS.OUTBUFF_FULL and performs a \"flush\" on port 0x60 if\n * it's set, then waits for C8042.STATUS.OUTBUFF_FULL *again*. Unfortunately, the \"flush\" throws\n * away our response if we respond immediately.\n *\n * So now when out8042InBuffCmd() has a response, it sets C8042.STATUS.OUTBUFF_DELAY instead\n * (which is outside the 0xff range of bits we return); when we see C8042.STATUS.OUTBUFF_DELAY,\n * we clear it and set C8042.STATUS.OUTBUFF_FULL, which will be returned on the next read.\n *\n * This provides a single poll delay, so that the aforementioned \"flush\" won't toss our response.\n * If longer delays are needed down the road, we may need to set a delay count in the upper (unused)\n * bits of b8042Status, instead of using a single delay bit.\n */\n if (this.b8042Status & ChipSet.C8042.STATUS.OUTBUFF_DELAY) {\n this.b8042Status |= ChipSet.C8042.STATUS.OUTBUFF_FULL;\n this.b8042Status &= ~ChipSet.C8042.STATUS.OUTBUFF_DELAY;\n }\n /*\n * I added this for Windows 95's VMM keyboard driver for DOS sessions, which differs from the keyboard\n * driver for protected-mode applications (see the keyboard's setEnabled() function for more details).\n * \n * The Windows 95 VMM driver doesn't do what EITHER the ROM or the protected-mode driver typically does\n * after receiving a scan code (ie, toggle the keyboard's enable state). Instead, the VMM simply checks\n * this status port one more time, perhaps to confirm that the OUTBUFF_FULL bit is clear. It then\n * expects another keyboard interrupt to arrive when the next scan code is available. Very minimalistic.\n */\n if (!(this.b8042Status & ChipSet.C8042.STATUS.OUTBUFF_FULL) && this.kbd) {\n this.kbd.checkBuffer();\n }\n return b;\n }\n\n /**\n * out8042InBuffCmd(port, bOut, addrFrom)\n *\n * This writes to the 8042's input buffer; using this port (ie, 0x64 instead of 0x60) designates the\n * the byte as a \"command byte\". We immediately set C8042.STATUS.CMD_FLAG, and then see if we can act upon\n * the command immediately (some commands requires us to wait for a \"data byte\").\n *\n * @this {ChipSet}\n * @param {number} port (0x64)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n out8042InBuffCmd(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"8042_INBUFF.CMD\", null, Messages.C8042);\n\n this.b8042InBuff = bOut;\n\n this.b8042Status |= ChipSet.C8042.STATUS.CMD_FLAG;\n\n let bPulseBits = 0;\n if (this.b8042InBuff >= ChipSet.C8042.CMD.PULSE_OUTPORT) {\n bPulseBits = (this.b8042InBuff ^ 0xf);\n /*\n * Now that we have isolated the bit(s) to pulse, map all pulse commands to C8042.CMD.PULSE_OUTPORT\n */\n this.b8042InBuff = ChipSet.C8042.CMD.PULSE_OUTPORT;\n }\n\n switch (this.b8042InBuff) {\n case ChipSet.C8042.CMD.READ_CMD: // 0x20\n this.set8042OutBuff(this.b8042CmdData);\n break;\n\n case ChipSet.C8042.CMD.WRITE_CMD: // 0x60\n /*\n * No further action required for this command; more data is expected via out8042InBuffData()\n */\n break;\n\n case ChipSet.C8042.CMD.DISABLE_KBD: // 0xAD\n this.set8042CmdData(this.b8042CmdData | ChipSet.C8042.DATA.CMD.NO_CLOCK);\n if (!COMPILED) this.printMessage(\"keyboard disabled\", Messages.KBD | Messages.PORT);\n /*\n * NOTE: The MODEL_5170 BIOS calls \"KBD_RESET\" (F000:17D2) while the keyboard interface is disabled,\n * yet we must still deliver the Keyboard's CMDRES.BAT_OK response code? Seems like an odd thing for\n * a \"disabled interface\" to do.\n */\n break;\n\n case ChipSet.C8042.CMD.ENABLE_KBD: // 0xAE\n this.set8042CmdData(this.b8042CmdData & ~ChipSet.C8042.DATA.CMD.NO_CLOCK);\n if (!COMPILED) this.printMessage(\"keyboard re-enabled\", Messages.KBD | Messages.PORT);\n if (this.kbd) this.kbd.checkBuffer();\n break;\n\n case ChipSet.C8042.CMD.SELF_TEST: // 0xAA\n if (this.kbd) this.kbd.flushBuffer();\n this.set8042CmdData(this.b8042CmdData | ChipSet.C8042.DATA.CMD.NO_CLOCK);\n if (!COMPILED) this.printMessage(\"keyboard disabled on reset\", Messages.KBD | Messages.PORT);\n this.set8042OutBuff(ChipSet.C8042.DATA.SELF_TEST.OK);\n this.set8042OutPort(ChipSet.C8042.OUTPORT.NO_RESET | ChipSet.C8042.OUTPORT.A20_ON);\n break;\n\n case ChipSet.C8042.CMD.INTF_TEST: // 0xAB\n /*\n * TODO: Determine all the side-effects of the Interface Test, if any.\n */\n this.set8042OutBuff(ChipSet.C8042.DATA.INTF_TEST.OK);\n break;\n\n case ChipSet.C8042.CMD.READ_INPORT: // 0xC0\n this.set8042OutBuff(this.b8042InPort);\n break;\n\n case ChipSet.C8042.CMD.READ_OUTPORT: // 0xD0\n this.set8042OutBuff(this.b8042OutPort);\n break;\n\n case ChipSet.C8042.CMD.WRITE_OUTPORT: // 0xD1\n /*\n * No further action required for this command; more data is expected via out8042InBuffData()\n */\n break;\n\n case ChipSet.C8042.CMD.READ_TEST: // 0xE0\n this.set8042OutBuff((this.b8042CmdData & ChipSet.C8042.DATA.CMD.NO_CLOCK)? 0 : ChipSet.C8042.TESTPORT.KBD_CLOCK);\n break;\n\n case ChipSet.C8042.CMD.PULSE_OUTPORT: // 0xF0-0xFF\n if (bPulseBits & 0x1) {\n /*\n * Bit 0 of the 8042's output port is connected to RESET. If it's pulsed, the processor resets.\n * We don't want to clear *all* CPU state (eg, cycle counts), so we call cpu.resetRegs() instead\n * of cpu.reset().\n */\n this.cpu.resetRegs();\n }\n break;\n\n default:\n if (!COMPILED && this.messageEnabled(Messages.C8042)) {\n this.printMessage(\"unrecognized 8042 command: \" + Str.toHexByte(this.b8042InBuff), true);\n this.dbg.stopCPU();\n }\n break;\n }\n }\n\n /**\n * set8042CmdData(b)\n *\n * @this {ChipSet}\n * @param {number} b\n */\n set8042CmdData(b)\n {\n this.b8042CmdData = b;\n\n this.b8042Status = (this.b8042Status & ~ChipSet.C8042.STATUS.SYS_FLAG) | (b & ChipSet.C8042.DATA.CMD.SYS_FLAG);\n if (this.kbd) {\n /*\n * This seems to be what the doctor ordered for the MODEL_5170_REV3 BIOS @F000:0A6D, where it\n * sends ChipSet.C8042.CMD.WRITE_CMD to port 0x64, followed by 0x4D to port 0x60, which clears NO_CLOCK\n * and enables the keyboard. The BIOS then waits for OUTBUFF_FULL to be set, at which point it seems\n * to be anticipating an 0xAA response in the output buffer.\n *\n * And indeed, if we call the original MODEL_5150/MODEL_5160 setEnabled() Keyboard interface here,\n * and both the data and clock lines have transitioned high (ie, both parameters are true), then it\n * will call resetDevice(), generating a Keyboard.CMDRES.BAT_OK response.\n *\n * This agrees with my understanding of what happens when the 8042 toggles the clock line high\n * (ie, clears NO_CLOCK): the TechRef's \"Basic Assurance Test\" section says that when the Keyboard is\n * powered on, it performs the BAT, and then when the clock and data lines go high, the keyboard sends\n * a completion code (eg, 0xAA for success, or 0xFC or something else for failure).\n */\n this.kbd.setEnabled(!!(b & ChipSet.C8042.DATA.CMD.NO_INHIBIT), !(b & ChipSet.C8042.DATA.CMD.NO_CLOCK));\n }\n }\n\n /**\n * set8042OutBuff(b, fNoDelay)\n *\n * The 5170 ROM BIOS assumed there would be a slight delay after certain 8042 commands, like SELF_TEST\n * (0xAA), before there was an OUTBUFF response; in fact, there is BIOS code that will fail without such\n * a delay. This is discussed in greater detail in in8042Status().\n *\n * So we default to a \"single poll\" delay, setting OUTBUFF_DELAY instead of OUTBUFF_FULL, unless the caller\n * explicitly asks for no delay. The fNoDelay parameter was added later, so that receiveKbdData() could\n * request immediate delivery of keyboard scan codes, because some operating systems (eg, Microport's 1986\n * version of Unix for PC AT machines) poll the status port only once, immediately giving up if no data is\n * available.\n *\n * TODO: Determine if we should invert the fNoDelay default (from false to true) and delay only in specific\n * cases; ie, perhaps only the SELF_TEST command required a delay.\n *\n * @this {ChipSet}\n * @param {number} b\n * @param {boolean} [fNoDelay]\n */\n set8042OutBuff(b, fNoDelay)\n {\n if (b >= 0) {\n this.b8042OutBuff = b;\n if (fNoDelay) {\n this.b8042Status |= ChipSet.C8042.STATUS.OUTBUFF_FULL;\n } else {\n this.b8042Status &= ~ChipSet.C8042.STATUS.OUTBUFF_FULL;\n this.b8042Status |= ChipSet.C8042.STATUS.OUTBUFF_DELAY;\n }\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.PORT)) {\n this.printMessage(\"chipset.set8042OutBuff(\" + Str.toHexByte(b) + ',' + (fNoDelay? \"no\" : \"\") + \"delay)\", true);\n }\n }\n }\n\n /**\n * set8042OutPort(b)\n *\n * When ChipSet.C8042.CMD.WRITE_OUTPORT (0xD1) is written to port 0x64, the next byte written to port 0x60 comes here,\n * to the KBC's OUTPORT. One of the most important bits in the OUTPORT is the A20_ON bit (0x02): set it to turn A20 on,\n * clear it to turn A20 off.\n *\n * @this {ChipSet}\n * @param {number} b\n */\n set8042OutPort(b)\n {\n this.b8042OutPort = b;\n\n this.bus.setA20(!!(b & ChipSet.C8042.OUTPORT.A20_ON));\n\n if (!(b & ChipSet.C8042.OUTPORT.NO_RESET)) {\n /*\n * Bit 0 of the 8042's output port is connected to RESET. Normally, it's \"pulsed\" with the\n * C8042.CMD.PULSE_OUTPORT command, so if a RESET is detected via this command, we should try to\n * determine if that's what the caller intended.\n */\n if (!COMPILED && this.messageEnabled(Messages.C8042)) {\n this.printMessage(\"unexpected 8042 output port reset: \" + Str.toHexByte(b), true);\n this.dbg.stopCPU();\n }\n this.cpu.resetRegs();\n }\n }\n\n /**\n * receiveKbdData(b)\n *\n * In the old days of PCx86, the Keyboard component would simply call setIRR() when it had some data for the\n * keyboard controller. However, the Keyboard's sole responsibility is to emulate an actual keyboard and call\n * receiveKbdData() whenever it has some data; it's not allowed to mess with IRQ lines.\n *\n * If there's an 8042, we check (this.b8042CmdData & ChipSet.C8042.DATA.CMD.NO_CLOCK); if NO_CLOCK is clear,\n * we can raise the IRQ immediately. Well, not quite immediately....\n *\n * Notes regarding the MODEL_5170 (eg, /devices/pc/machine/5170/ega/1152kb/rev3/machine.xml):\n *\n * The \"Rev3\" BIOS, dated 11-Nov-1985, contains the following code in the keyboard interrupt handler at K26A:\n *\n * F000:3704 FA CLI\n * F000:3705 B020 MOV AL,20\n * F000:3707 E620 OUT 20,AL\n * F000:3709 B0AE MOV AL,AE\n * F000:370B E88D02 CALL SHIP_IT\n * F000:370E FA CLI <-- window of opportunity\n * F000:370F 07 POP ES\n * F000:3710 1F POP DS\n * F000:3711 5F POP DI\n * F000:3712 5E POP SI\n * F000:3713 5A POP DX\n * F000:3714 59 POP CX\n * F000:3715 5B POP BX\n * F000:3716 58 POP AX\n * F000:3717 5D POP BP\n * F000:3718 CF IRET\n *\n * and SHIP_IT looks like this:\n *\n * F000:399B 50 PUSH AX\n * F000:399C FA CLI\n * F000:399D 2BC9 SUB CX,CX\n * F000:399F E464 IN AL,64\n * F000:39A1 A802 TEST AL,02\n * F000:39A3 E0FA LOOPNZ 399F\n * F000:39A5 58 POP AX\n * F000:39A6 E664 OUT 64,AL\n * F000:39A8 FB STI\n * F000:39A9 C3 RET\n *\n * This code *appears* to be trying to ensure that another keyboard interrupt won't occur until after the IRET,\n * but sadly, it looks to me like the CLI following the call to SHIP_IT is too late. SHIP_IT should have been\n * written with PUSHF/CLI and POPF intro/outro sequences, thereby honoring the first CLI at the top of K26A and\n * eliminating the need for the second CLI (@F000:370E).\n *\n * Of course, in \"real life\", this was probably never a problem, because the 8042 probably wasn't fast enough to\n * generate another interrupt so soon after receiving the ChipSet.C8042.CMD.ENABLE_KBD command. In my case, I ran\n * into this problem by 1) turning on \"kbd\" Debugger messages and 2) rapidly typing lots of keys. The Debugger\n * messages bogged the machine down enough for me to hit the \"window of opportunity\", generating this message in\n * PC-DOS 3.20:\n *\n * \"FATAL: Internal Stack Failure, System Halted.\"\n *\n * and halting the system @0070:0923 (JMP 0923).\n *\n * That wasn't the only spot in the BIOS where I hit this problem; here's another \"window of opportunity\":\n *\n * F000:3975 FA CLI\n * F000:3976 B020 MOV AL,20\n * F000:3978 E620 OUT 20,AL\n * F000:397A B0AE MOV AL,AE\n * F000:397C E81C00 CALL SHIP_IT\n * F000:397F B80291 MOV AX,9102 <-- window of opportunity\n * F000:3982 CD15 INT 15\n * F000:3984 80269600FC AND [0096],FC\n * F000:3989 E982FD JMP 370E\n *\n * In this second, lengthier, example, I counted about 60 instructions being executed from the EOI @F000:3978 to\n * the final IRET @F000:3718, most of them in the INT 0x15 handler. So, I'm going to double that count to 120\n * instructions, just to be safe, and pass that along to every setIRR() call we make here.\n *\n * @this {ChipSet}\n * @param {number} b\n * @return {boolean} (true if data accepted, false if declined)\n */\n receiveKbdData(b)\n {\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.PORT)) {\n this.printMessage(\"chipset.receiveKbdData(\" + Str.toHexByte(b) + ')', true);\n }\n if (this.model == ChipSet.MODEL_4860) {\n if (!(this.bNMI & ChipSet.NMI.KBD_LATCH)) {\n this.bNMI |= ChipSet.NMI.KBD_LATCH;\n this.bKbdData = b;\n if (b && (this.bNMI & ChipSet.NMI.ENABLE)) {\n X86.helpInterrupt.call(this.cpu, X86.EXCEPTION.NMI);\n }\n return true;\n }\n return false;\n }\n if (this.model < ChipSet.MODEL_5170) {\n if (this.bPPIB & ChipSet.PPI_B.CLK_KBD) {\n this.bKbdData = b;\n if (b) {\n this.setIRR(ChipSet.IRQ.KBD, 120);\n this.b8041Status |= ChipSet.C8042.STATUS.OUTBUFF_FULL;\n }\n return true;\n }\n return false;\n }\n if (b) {\n if (!(this.b8042CmdData & ChipSet.C8042.DATA.CMD.NO_CLOCK)) {\n /*\n * The next in8042OutBuff() will clear both of these bits and call kbd.checkBuffer(),\n * which will call receiveKbdData() again if there's still keyboard data to process.\n */\n if (!(this.b8042Status & (ChipSet.C8042.STATUS.OUTBUFF_FULL | ChipSet.C8042.STATUS.OUTBUFF_DELAY))) {\n this.set8042OutBuff(b, true);\n /*\n * A delay of 4 instructions was originally requested as part of the the Keyboard's resetDevice()\n * response, but a larger delay (120) is now needed for MODEL_5170 machines, per the discussion above.\n */\n this.setIRR(ChipSet.IRQ.KBD, 120);\n return true;\n }\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.PORT)) {\n this.printMessage(\"chipset.receiveKbdData(\" + Str.toHexByte(b) + \"): output buffer full\", true);\n }\n return false;\n }\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.PORT)) {\n this.printMessage(\"chipset.receiveKbdData(\" + Str.toHexByte(b) + \"): disabled\", true);\n }\n }\n return false;\n }\n\n /**\n * in6300DIPSwitches(iDIP, port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDIP (0 or 1)\n * @param {number} port (0x66 or 0x67)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n in6300DIPSwitches(iDIP, port, addrFrom)\n {\n let b = this.aDIPSwitches[iDIP][1];\n this.printMessageIO(port, null, addrFrom, \"DIPSW-\" + iDIP, b, Messages.CHIPSET);\n return b;\n }\n\n /**\n * inCMOSAddr(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x70)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inCMOSAddr(port, addrFrom)\n {\n this.printMessageIO(port, null, addrFrom, \"CMOS.ADDR\", this.bCMOSAddr, Messages.CMOS);\n return this.bCMOSAddr;\n }\n\n /**\n * outCMOSAddr(port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x70)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outCMOSAddr(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"CMOS.ADDR\", null, Messages.CMOS);\n this.bCMOSAddr = bOut;\n this.bNMI = (this.bNMI & ~ChipSet.NMI.ENABLE) | ((bOut & ChipSet.CMOS.ADDR.NMI_DISABLE)? 0 : ChipSet.NMI.ENABLE);\n }\n\n /**\n * inCMOSData(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x71)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inCMOSData(port, addrFrom)\n {\n let bAddr = this.bCMOSAddr & ChipSet.CMOS.ADDR.MASK;\n let bIn = (bAddr <= ChipSet.CMOS.ADDR.STATUSD? this.getRTCByte(bAddr) : this.abCMOSData[bAddr]);\n if (this.messageEnabled(Messages.CMOS | Messages.PORT)) {\n this.printMessageIO(port, null, addrFrom, \"CMOS.DATA[\" + Str.toHexByte(bAddr) + \"]\", bIn, true);\n }\n if (addrFrom != null) {\n if (bAddr == ChipSet.CMOS.ADDR.STATUSC) {\n /*\n * When software reads the STATUSC port, all interrupt bits (PF, AF, and UF) are automatically\n * cleared, which in turn clears the IRQF bit, which in turn clears the IRQ.\n */\n this.abCMOSData[bAddr] &= ChipSet.CMOS.STATUSC.RESERVED;\n if (bIn & ChipSet.CMOS.STATUSC.IRQF) this.clearIRR(ChipSet.IRQ.RTC);\n /*\n * If we just cleared PF, and PIE is still set, then we need to make sure the next Periodic Interrupt\n * occurs in a timely manner, too.\n */\n if ((bIn & ChipSet.CMOS.STATUSC.PF) && (this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.PIE)) {\n if (!COMPILED) this.printMessage(\"RTC periodic interrupt cleared\", Messages.RTC);\n this.setRTCCycleLimit();\n }\n }\n }\n return bIn;\n }\n\n /**\n * outCMOSData(port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x71)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outCMOSData(port, bOut, addrFrom)\n {\n let bAddr = this.bCMOSAddr & ChipSet.CMOS.ADDR.MASK;\n if (this.messageEnabled(Messages.CMOS | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"CMOS.DATA[\" + Str.toHexByte(bAddr) + \"]\", null, true);\n }\n let bDelta = bOut ^ this.abCMOSData[bAddr];\n this.abCMOSData[bAddr] = (bAddr <= ChipSet.CMOS.ADDR.STATUSD? this.setRTCByte(bAddr, bOut) : bOut);\n if (bAddr == ChipSet.CMOS.ADDR.STATUSB && (bDelta & ChipSet.CMOS.STATUSB.PIE)) {\n if (bOut & ChipSet.CMOS.STATUSB.PIE) {\n if (!COMPILED) this.printMessage(\"RTC periodic interrupts enabled\", Messages.RTC);\n this.setRTCCycleLimit();\n } else {\n if (!COMPILED) this.printMessage(\"RTC periodic interrupts disabled\", Messages.RTC);\n }\n }\n }\n\n /**\n * inNMI(port, addrFrom)\n *\n * This handler is installed only for models before MODEL_5170; technically, this port is not readable,\n * except on the MODEL_4860, and even there, all a read is required to do is clear KBD_LATCH, but we go ahead\n * and return all the bits.\n *\n * @this {ChipSet}\n * @param {number} port (0xA0)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inNMI(port, addrFrom)\n {\n let bIn = this.bNMI;\n this.printMessageIO(port, null, addrFrom, \"NMI\", bIn);\n this.bNMI &= ~ChipSet.NMI.KBD_LATCH;\n return bIn;\n }\n\n /**\n * outNMI(port, bOut, addrFrom)\n *\n * This handler is installed only for models before MODEL_5170.\n *\n * @this {ChipSet}\n * @param {number} port (0xA0)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outNMI(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"NMI\");\n this.bNMI = bOut;\n }\n\n /**\n * outFPUClear(port, bOut, addrFrom)\n *\n * This handler is installed only for MODEL_5170.\n *\n * @this {ChipSet}\n * @param {number} port (0xF0)\n * @param {number} bOut (0x00 is the only expected output)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outFPUClear(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"FPU.CLEAR\");\n\n if (this.fpu) this.fpu.clearBusy();\n }\n\n /**\n * outFPUReset(port, bOut, addrFrom)\n *\n * This handler is installed only for MODEL_5170.\n *\n * @this {ChipSet}\n * @param {number} port (0xF1)\n * @param {number} bOut (0x00 is the only expected output)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outFPUReset(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"FPU.RESET\");\n\n if (this.fpu) this.fpu.resetFPU();\n }\n\n /**\n * intBIOSRTC(addr)\n *\n * INT 0x1A Quick Reference:\n *\n * AH\n * ----\n * 0x00 Get current clock count in CX:DX\n * 0x01 Set current clock count from CX:DX\n * 0x02 Get real-time clock using BCD (CH=hours, CL=minutes, DH=seconds)\n * 0x03 Set real-time clock using BCD (CH=hours, CL=minutes, DH=seconds, DL=1 if Daylight Savings Time option)\n * 0x04 Get real-time date using BCD (CH=century, CL=year, DH=month, DL=day)\n * 0x05 Set real-time date using BCD (CH=century, CL=year, DH=month, DL=day)\n * 0x06 Set alarm using BCD (CH=hours, CL=minutes, DH=seconds)\n * 0x07 Reset alarm\n *\n * @this {ChipSet}\n * @param {number} addr\n * @return {boolean} true to proceed with the INT 0x1A software interrupt, false to skip\n */\n intBIOSRTC(addr)\n {\n if (DEBUGGER) {\n if (this.messageEnabled(Messages.INT) && this.dbg.messageInt(Interrupts.RTC, addr)) {\n /*\n * By computing AH now, we get the incoming AH value; if we computed it below, along with\n * the rest of the register values, we'd get the outgoing AH value, which is not what we want.\n */\n let chipset = this;\n let AH = this.cpu.regEAX >> 8;\n let nCycles = this.cpu.getCycles();\n this.cpu.addIntReturn(addr, function onBIOSRTCReturn(nLevel) {\n let sResult;\n let CL = chipset.cpu.regEDX & 0xff;\n let CH = chipset.cpu.regEDX >> 8;\n let DL = chipset.cpu.regEDX & 0xff;\n let DH = chipset.cpu.regEDX >> 8;\n if (AH == 0x02 || AH == 0x03) {\n sResult = \" CH(hour)=\" + Str.toHexWord(CH) + \" CL(min)=\" + Str.toHexByte(CL) + \" DH(sec)=\" + Str.toHexByte(DH);\n } else if (AH == 0x04 || AH == 0x05) {\n sResult = \" CX(year)=\" + Str.toHexWord(chipset.cpu.regECX) + \" DH(month)=\" + Str.toHexByte(DH) + \" DL(day)=\" + Str.toHexByte(DL);\n }\n let nCyclesDelta = -nCycles + (nCycles = chipset.cpu.getCycles());\n chipset.dbg.messageIntReturn(Interrupts.RTC, nLevel, nCyclesDelta, sResult);\n });\n }\n }\n return true;\n }\n\n /**\n * setSpeaker(fEnable)\n *\n * @this {ChipSet}\n * @param {boolean} [fEnable] true to enable speaker, false to disable it, otherwise update it as appropriate\n */\n setSpeaker(fEnable)\n {\n let fOn;\n if (fEnable !== undefined) {\n fOn = fEnable;\n if (fOn != this.fSpeakerEnabled) {\n // \n // Yielding doesn't seem to help the simulation of sound via rapid speaker toggling.\n //\n // if (this.cpu) {\n // this.cpu.yieldCPU();\n // }\n this.fSpeakerEnabled = fOn;\n }\n } else {\n fOn = !!(this.fSpeakerEnabled && this.cpu && this.cpu.isRunning());\n }\n let freq = Math.round(ChipSet.TIMER_TICKS_PER_SEC / this.getTimerInit(ChipSet.PIT0.TIMER2));\n if (freq < 20 || freq > 20000) {\n /*\n * Treat frequencies outside the normal hearing range (below 20hz or above 20Khz) as a clever\n * attempt to turn sound off.\n */\n fOn = false;\n }\n if (this.contextAudio) {\n if (fOn && this.startAudio()) {\n /*\n * Instead of setting the frequency's 'value' property directly, as we used to do, we use the\n * setValueAtTime() method, with a time of zero, as a work-around to avoid the \"easing\" (aka\n * \"de-zippering\") of the frequency that browsers like to do. Supposedly de-zippering is an\n * attempt to avoid \"pops\" if the frequency is altered while the wave is still rising or falling.\n * \n * Ditto for the gain's 'value'.\n */\n // this.oscillatorAudio['frequency']['value'] = freq;\n this.oscillatorAudio['frequency']['setValueAtTime'](freq, 0);\n // this.volumeAudio['gain']['value'] = this.volumeInit;\n this.volumeAudio['gain']['setValueAtTime'](this.volumeInit, 0);\n if (this.messageEnabled(Messages.SPEAKER)) this.printMessage(\"speaker on at \" + freq + \"hz\", true);\n } else if (this.volumeAudio) {\n this.volumeAudio['gain']['setValueAtTime'](0, 0);\n if (this.messageEnabled(Messages.SPEAKER)) this.printMessage(\"speaker off at \" + freq + \"hz\", true);\n }\n } else if (fOn && this.fSpeakerOn != fOn) {\n this.printMessage(\"BEEP\", Messages.SPEAKER);\n }\n this.fSpeakerOn = fOn;\n }\n\n /**\n * startAudio(event)\n *\n * NOTE: We currently use named properties rather than \"dot\" properties to access all the AudioContext\n * properties and methods, because we don't have any built-in declarations or externs for them, so neither\n * WebStorm nor the Closure Compiler recognize them. We could live with the WebStorm inspection warnings,\n * but we definitely can't have the Closure Compiler renaming any of the properties -- and since it\n * automatically converts them all to \"dot\" properties, there's no incentive for us to do anything more.\n *\n * @this {ChipSet}\n * @param {Event} [event] object from a 'touch' event, if any\n * @return {boolean}\n */\n startAudio(event)\n {\n if (this.contextAudio) {\n /*\n * NOTE: If the machine happened to enable its speaker *before* the user generated an event\n * (eg, touchstart) that resulted in a call here, then we're too late -- at least as far as iOS\n * devices are concerned, because those devices require the oscillator's start() method to be\n * called in the context of a user-initiated event.\n *\n * So, for the benefit of iOS devices, when we finally receive a user-generated call, we will\n * simply recreate the oscillator. This is a one-time work-around for the life of the machine.\n *\n * TODO: Consider adding a \"Sound On/Off\" button to all machines (probably in the top right corner,\n * where \"Full Screen\" and \"Lock Pointer\" buttons typically appear), at least on iOS devices.\n */\n if (event) {\n if (this.fUserSound) return true;\n this.oscillatorAudio = null;\n this.fUserSound = true;\n }\n if (this.oscillatorAudio) return true;\n try {\n this.oscillatorAudio = this.contextAudio['createOscillator']();\n if ('start' in this.oscillatorAudio) { // early versions of Web Audio used noteOn() instead of start()\n this.volumeAudio = this.contextAudio['createGain']();\n this.oscillatorAudio['connect'](this.volumeAudio);\n this.volumeAudio['connect'](this.contextAudio['destination']);\n this.volumeAudio['gain']['setValueAtTime'](0, 0);\n this.oscillatorAudio['type'] = \"square\";\n this.oscillatorAudio['start'](0);\n return true;\n }\n } catch(e) {\n this.notice(\"AudioContext exception: \" + e.message);\n this.contextAudio = null;\n }\n }\n return false;\n }\n\n /**\n * messageBitsDMA(iChannel)\n *\n * @this {ChipSet}\n * @param {number} [iChannel] if the message is associated with a particular IRQ #\n * @return {number}\n */\n messageBitsDMA(iChannel)\n {\n let bitsMessage = 0;\n if (DEBUG) {\n bitsMessage = Messages.DATA;\n if (iChannel == ChipSet.DMA_FDC) {\n bitsMessage |= Messages.FDC;\n } else if (iChannel == ChipSet.DMA_HDC) {\n bitsMessage |= Messages.HDC;\n }\n }\n return bitsMessage;\n }\n\n /**\n * messageBitsIRQ(nIRQ)\n *\n * @this {ChipSet}\n * @param {number|undefined} [nIRQ] if the message is associated with a particular IRQ #\n * @return {number}\n */\n messageBitsIRQ(nIRQ)\n {\n let bitsMessage = Messages.IRQ;\n if (nIRQ == ChipSet.IRQ.TIMER0) { // IRQ 0\n bitsMessage |= Messages.TIMER;\n } else if (nIRQ == ChipSet.IRQ.KBD) { // IRQ 1\n bitsMessage |= Messages.KBD;\n } else if (nIRQ == ChipSet.IRQ.SLAVE) { // IRQ 2\n bitsMessage = Messages.NONE; // (we're not really interested in IRQ 2 itself, just the slaves)\n } else if (nIRQ == ChipSet.IRQ.COM1 || nIRQ == ChipSet.IRQ.COM2) {\n bitsMessage |= Messages.SERIAL;\n } else if (nIRQ == ChipSet.IRQ.XTC) { // IRQ 5 (MODEL_5160)\n bitsMessage |= Messages.HDC;\n } else if (nIRQ == ChipSet.IRQ.FDC) { // IRQ 6\n bitsMessage |= Messages.FDC;\n } else if (nIRQ == ChipSet.IRQ.RTC) { // IRQ 8 (MODEL_5170 and up)\n bitsMessage |= Messages.RTC;\n } else if (nIRQ == ChipSet.IRQ.ATC) { // IRQ 14 (MODEL_5170 and up)\n bitsMessage |= Messages.HDC;\n }\n return bitsMessage;\n }\n\n /**\n * checkDMA()\n *\n * Called by the CPU whenever INTR.DMA is set.\n *\n * @return {boolean} true if one or more async DMA channels are still active (unmasked), false to reset INTR.DMA\n *\n checkDMA()\n {\n let fActive = false;\n for (let iDMAC = 0; iDMAC < this.aDMACs; iDMAC++) {\n let controller = this.aDMACs[iDMAC];\n for (let iChannel = 0; iChannel < controller.aChannels.length; iChannel++) {\n let channel = controller.aChannels[iChannel];\n if (!channel.masked) {\n this.advanceDMA(channel);\n if (!channel.masked) fActive = true;\n }\n }\n }\n return fActive;\n }\n */\n\n /**\n * ChipSet.init()\n *\n * This function operates on every HTML element of class \"chipset\", extracting the\n * JSON-encoded parameters for the ChipSet constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a ChipSet component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n let aeChipSet = Component.getElementsByClass(document, PCX86.APPCLASS, \"chipset\");\n for (let iChip = 0; iChip < aeChipSet.length; iChip++) {\n let eChipSet = aeChipSet[iChip];\n let parmsChipSet = Component.getComponentParms(eChipSet);\n let chipset = new ChipSet(parmsChipSet);\n Component.bindComponentControls(chipset, eChipSet, PCX86.APPCLASS);\n chipset.updateDIPSwitchDescriptions();\n }\n }\n}\n\n/*\n * Ports Overview\n * --------------\n *\n * This module provides support for many of the following components (except where a separate component is noted).\n * This list is taken from p.1-8 (\"System Unit\") of the IBM 5160 (PC XT) Technical Reference Manual (as revised\n * April 1983), only because I didn't see a similar listing in the original 5150 Technical Reference.\n *\n * Port(s) Description\n * ------- -----------\n * 000-00F DMA Chip 8237A-5 [see below]\n * 020-021 Interrupt 8259A [see below]\n * 040-043 Timer 8253-5 [see below]\n * 060-063 PPI 8255A-5 [see below]\n * 080-083 DMA Page Registers [see below]\n * 0Ax [1] NMI Mask Register [see below]\n * 0Cx Reserved\n * 0Ex Reserved\n * 200-20F Game Control\n * 210-217 Expansion Unit\n * 220-24F Reserved\n * 278-27F Reserved\n * 2F0-2F7 Reserved\n * 2F8-2FF Asynchronous Communications (Secondary) [see the SerialPort component]\n * 300-31F Prototype Card\n * 320-32F Hard Drive Controller (XTC) [see the HDC component]\n * 378-37F Printer\n * 380-38C [2] SDLC Communications\n * 380-389 [2] Binary Synchronous Communications (Secondary)\n * 3A0-3A9 Binary Synchronous Communications (Primary)\n * 3B0-3BF IBM Monochrome Display/Printer [see the Video component]\n * 3C0-3CF Reserved\n * 3D0-3DF Color/Graphics (Motorola 6845) [see the Video component]\n * 3EO-3E7 Reserved\n * 3FO-3F7 Floppy Drive Controller [see the FDC component]\n * 3F8-3FF Asynchronous Communications (Primary) [see the SerialPort component]\n *\n * [1] At power-on time, NMI is masked off, perhaps because models 5150 and 5160 also tie coprocessor\n * (FPU) interrupts to NMI. Suppressing NMI by default seems odd, because that would also suppress memory\n * parity errors. TODO: Determine whether \"power-on time\" refers to the initial power-on state of the\n * NMI Mask Register or the state that the BIOS \"POST\" (Power-On Self-Test) sets.\n *\n * [2] These devices cannot be used together since their port addresses overlap.\n *\n * MODEL_5170 Description\n * ---------- -----------\n * 070 [3] CMOS Address ChipSet.CMOS.ADDR.PORT\n * 071 CMOS Data ChipSet.CMOS.DATA.PORT\n * 0F0 FPU Coprocessor Clear Busy (output 0x00)\n * 0F1 FPU Coprocessor Reset (output 0x00)\n * 1F0-1F7 Hard Drive Controller (ATC) [see the HDC component]\n *\n * [3] Port 0x70 doubles as the NMI Mask Register: output a CMOS address with bit 7 clear to enable NMI\n * or with bit 7 set to disable NMI (apparently the inverse of the older NMI Mask Register at port 0xA0).\n * Also, apparently unlike previous models, the MODEL_5170 POST leaves NMI enabled. And fortunately, the\n * FPU coprocessor interrupt line is no longer tied to NMI (it uses IRQ 13).\n */\n\n/*\n * Supported model numbers\n *\n * In general, when comparing this.model to \"base\" model numbers (ie, non-REV numbers), you should use\n * (this.model|0), which truncates the current model number.\n *\n * Note that there were two 5150 motherboard revisions: the \"REV A\" 16Kb-64Kb motherboard and the\n * \"REV B\" 64Kb-256Kb motherboard. There may have been a manufacturing correlation between motherboard\n * revisions (\"REV A\" and \"REV B\") and the ROM BIOS revisions shown below, but in general, we can't assume\n * any correlation, because newer ROMs could be installed with either motherboard.\n *\n * I do know that, for \"REV A\" motherboards, the Apr 1984 5150 TechRef says that \"To expand the memory\n * of your system beyond 544K requires your IBM Personal Computer System Unit to have a BIOS ROM module\n * dated 10/27/82 or later.\" Which suggests that SW2[5] was not used until the REV3 5150 ROM BIOS.\n *\n * For now, we treat all our MODEL_5150 systems as 16Kb-64Kb motherboards; if you want a 64Kb-256Kb motherboard,\n * then step up to a MODEL_5160 system. We use a multiplier of 16 for 5150 LOWMEM values, and a multiplier\n * of 64 for 5160 LOWMEM values.\n */\nChipSet.MODEL_4860 = 4860; // PCjr\n\nChipSet.MODEL_5150 = 5150; // used in reference to the 1st 5150 ROM BIOS, dated Apr 24, 1981\nChipSet.MODEL_5150_REV2 = 5150.2; // used in reference to the 2nd 5150 ROM BIOS, dated Oct 19, 1981\nChipSet.MODEL_5150_REV3 = 5150.3; // used in reference to the 3rd 5150 ROM BIOS, dated Oct 27, 1982\nChipSet.MODEL_5150_OTHER = 5150.9;\n\nChipSet.MODEL_5160 = 5160; // used in reference to the 1st 5160 ROM BIOS, dated Nov 08, 1982\nChipSet.MODEL_5160_REV2 = 5160.2; // used in reference to the 1st 5160 ROM BIOS, dated Jan 10, 1986\nChipSet.MODEL_5160_REV3 = 5160.3; // used in reference to the 1st 5160 ROM BIOS, dated May 09, 1986\nChipSet.MODEL_5160_OTHER = 5160.9;\n\nChipSet.MODEL_5170 = 5170; // used in reference to the 1st 5170 ROM BIOS, dated Jan 10, 1984\nChipSet.MODEL_5170_REV2 = 5170.2; // used in reference to the 2nd 5170 ROM BIOS, dated Jun 10, 1985\nChipSet.MODEL_5170_REV3 = 5170.3; // used in reference to the 3rd 5170 ROM BIOS, dated Nov 15, 1985\nChipSet.MODEL_5170_OTHER = 5170.9;\n\n/*\n * Assorted non-IBM models (we don't put \"IBM\" in the IBM models, but non-IBM models should include the company name).\n */\nChipSet.MODEL_CDP_MPC1600 = 5150.101; // Columbia Data Products MPC 1600 (\"Copyright Columbia Data Products 1983, ROM/BIOS Ver 4.34\")\nChipSet.MODEL_COMPAQ_PORTABLE = 5150.102; // COMPAQ Portable (COMPAQ's first PC)\n\nChipSet.MODEL_ATT_6300 = 5160.101; // AT&T Personal Computer 6300/Olivetti M24 (\"COPYRIGHT (C) OLIVETTI 1984\",\"04/03/86\",v1.43)\nChipSet.MODEL_ZENITH_Z150 = 5160.150; // Zenith Data Systems Z-150 (\"08/11/88 (C)ZDS CORP\")\n\nChipSet.MODEL_COMPAQ_DESKPRO386 = 5180; // COMPAQ DeskPro 386 (COMPAQ's first 80386-based PC); should be > MODEL_5170\n\n/*\n * Last but not least, a complete list of supported model strings, and corresponding internal model numbers.\n */\nChipSet.MODELS = {\n \"4860\": ChipSet.MODEL_4860, // IBM PCjr\n \"5150\": ChipSet.MODEL_5150, // IBM PC\n \"5160\": ChipSet.MODEL_5160, // IBM PC XT\n \"5170\": ChipSet.MODEL_5170, // IBM PC AT\n \"att6300\": ChipSet.MODEL_ATT_6300,\n \"mpc1600\": ChipSet.MODEL_CDP_MPC1600,\n \"z150\": ChipSet.MODEL_ZENITH_Z150,\n \"compaq\": ChipSet.MODEL_COMPAQ_PORTABLE,\n \"other\": ChipSet.MODEL_5150_OTHER\n};\n\nif (DESKPRO386) {\n ChipSet.MODELS[\"deskpro386\"] = ChipSet.MODEL_COMPAQ_DESKPRO386;\n}\n\nChipSet.CONTROLS = {\n SW1: \"sw1\",\n SW2: \"sw2\",\n SWDESC: \"swdesc\"\n};\n\n/*\n * Values returned by ChipSet.getDIPVideoMonitor()\n */\nChipSet.MONITOR = {\n NONE: 0,\n TV: 1, // Composite monitor (lower resolution; no support)\n COLOR: 2, // Color Display (5153)\n MONO: 3, // Monochrome Display (5151)\n EGACOLOR: 4, // Enhanced Color Display (5154) in High-Res Mode\n EGAEMULATION: 6, // Enhanced Color Display (5154) in Emulation Mode\n VGACOLOR: 7 // VGA Color Display\n};\n\n/*\n * 8237A DMA Controller (DMAC) I/O ports\n *\n * MODEL_5150 and up uses DMA channel 0 for memory refresh cycles and channel 2 for the FDC.\n *\n * MODEL_5160 and up uses DMA channel 3 for HDC transfers (XTC only).\n *\n * DMA0 refers to the original DMA controller found on all models, and DMA1 refers to the additional\n * controller found on MODEL_5170 and up; channel 4 on DMA1 is used to \"cascade\" channels 0-3 from DMA0,\n * so only channels 5-7 are available on DMA1.\n *\n * For FDC DMA notes, refer to http://wiki.osdev.org/ISA_DMA\n * For general DMA notes, refer to http://www.freebsd.org/doc/en/books/developers-handbook/dma.html\n *\n * TODO: Determine why the MODEL_5150 ROM BIOS sets the DMA channel 1 page register (port 0x83) to zero.\n */\nChipSet.DMA0 = {\n INDEX: 0,\n PORT: {\n CH0_ADDR: 0x00, // OUT: starting address IN: current address\n CH0_COUNT: 0x01, // OUT: starting word count IN: remaining word count\n CH1_ADDR: 0x02, // OUT: starting address IN: current address\n CH1_COUNT: 0x03, // OUT: starting word count IN: remaining word count\n CH2_ADDR: 0x04, // OUT: starting address IN: current address\n CH2_COUNT: 0x05, // OUT: starting word count IN: remaining word count\n CH3_ADDR: 0x06, // OUT: starting address IN: current address\n CH3_COUNT: 0x07, // OUT: starting word count IN: remaining word count\n CMD_STATUS: 0x08, // OUT: command register IN: status register\n REQUEST: 0x09,\n MASK: 0x0A,\n MODE: 0x0B,\n RESET_FF: 0x0C, // reset flip-flop\n MASTER_CLEAR: 0x0D, // OUT: master clear IN: temporary register\n MASK_CLEAR: 0x0E, // TODO: Provide handlers\n MASK_ALL: 0x0F, // TODO: Provide handlers\n CH2_PAGE: 0x81, // OUT: DMA channel 2 page register\n CH3_PAGE: 0x82, // OUT: DMA channel 3 page register\n CH1_PAGE: 0x83, // OUT: DMA channel 1 page register\n CH0_PAGE: 0x87 // OUT: DMA channel 0 page register (unusable; See \"The Inside Out\" book, p.246)\n }\n};\nChipSet.DMA1 = {\n INDEX: 1,\n PORT: {\n CH6_PAGE: 0x89, // OUT: DMA channel 6 page register (MODEL_5170)\n CH7_PAGE: 0x8A, // OUT: DMA channel 7 page register (MODEL_5170)\n CH5_PAGE: 0x8B, // OUT: DMA channel 5 page register (MODEL_5170)\n CH4_PAGE: 0x8F, // OUT: DMA channel 4 page register (MODEL_5170; unusable; aka \"Refresh\" page register?)\n CH4_ADDR: 0xC0, // OUT: starting address IN: current address\n CH4_COUNT: 0xC2, // OUT: starting word count IN: remaining word count\n CH5_ADDR: 0xC4, // OUT: starting address IN: current address\n CH5_COUNT: 0xC6, // OUT: starting word count IN: remaining word count\n CH6_ADDR: 0xC8, // OUT: starting address IN: current address\n CH6_COUNT: 0xCA, // OUT: starting word count IN: remaining word count\n CH7_ADDR: 0xCC, // OUT: starting address IN: current address\n CH7_COUNT: 0xCE, // OUT: starting word count IN: remaining word count\n CMD_STATUS: 0xD0, // OUT: command register IN: status register\n REQUEST: 0xD2,\n MASK: 0xD4,\n MODE: 0xD6,\n RESET_FF: 0xD8, // reset flip-flop\n MASTER_CLEAR: 0xDA, // master clear\n MASK_CLEAR: 0xDC, // TODO: Provide handlers\n MASK_ALL: 0xDE // TODO: Provide handlers\n }\n};\n\nChipSet.DMA_CMD = {\n M2M_ENABLE: 0x01,\n CH0HOLD_ENABLE: 0x02,\n CTRL_DISABLE: 0x04,\n COMP_TIMING: 0x08,\n ROT_PRIORITY: 0x10,\n EXT_WRITE_SEL: 0x20,\n DREQ_ACTIVE_LO: 0x40,\n DACK_ACTIVE_HI: 0x80\n};\n\nChipSet.DMA_STATUS = {\n CH0_TC: 0x01, // Channel 0 has reached Terminal Count (TC)\n CH1_TC: 0x02, // Channel 1 has reached Terminal Count (TC)\n CH2_TC: 0x04, // Channel 2 has reached Terminal Count (TC)\n CH3_TC: 0x08, // Channel 3 has reached Terminal Count (TC)\n ALL_TC: 0x0f, // all TC bits are cleared whenever DMA_STATUS is read\n CH0_REQ: 0x10, // Channel 0 DMA requested\n CH1_REQ: 0x20, // Channel 1 DMA requested\n CH2_REQ: 0x40, // Channel 2 DMA requested\n CH3_REQ: 0x80 // Channel 3 DMA requested\n};\n\nChipSet.DMA_MASK = {\n CHANNEL: 0x03,\n CHANNEL_SET: 0x04\n};\n\nChipSet.DMA_MODE = {\n CHANNEL: 0x03, // bits 0-1 select 1 of 4 possible channels\n TYPE: 0x0C, // bits 2-3 select 1 of 3 valid (4 possible) transfer types\n TYPE_VERIFY: 0x00, // pseudo transfer (generates addresses, responds to EOP, but nothing is moved)\n TYPE_WRITE: 0x04, // write to memory (move data FROM an I/O device; eg, reading a sector from a disk)\n TYPE_READ: 0x08, // read from memory (move data TO an I/O device; eg, writing a sector to a disk)\n AUTOINIT: 0x10,\n DECREMENT: 0x20, // clear for INCREMENT\n MODE: 0xC0, // bits 6-7 select 1 of 4 possible transfer modes\n MODE_DEMAND: 0x00,\n MODE_SINGLE: 0x40,\n MODE_BLOCK: 0x80,\n MODE_CASCADE: 0xC0\n};\n\nChipSet.DMA_REFRESH = 0x00; // DMA channel assigned to memory refresh\nChipSet.DMA_FDC = 0x02; // DMA channel assigned to the Floppy Drive Controller (FDC)\nChipSet.DMA_HDC = 0x03; // DMA channel assigned to the Hard Drive Controller (HDC; XTC only)\n\n/*\n * 8259A Programmable Interrupt Controller (PIC) I/O ports\n *\n * Internal registers:\n *\n * ICW1 Initialization Command Word 1 (sent to port ChipSet.PIC_LO)\n * ICW2 Initialization Command Word 2 (sent to port ChipSet.PIC_HI)\n * ICW3 Initialization Command Word 3 (sent to port ChipSet.PIC_HI)\n * ICW4 Initialization Command Word 4 (sent to port ChipSet.PIC_HI)\n * IMR Interrupt Mask Register\n * IRR Interrupt Request Register\n * ISR Interrupt Service Register\n * IRLow (IR having lowest priority; IR+1 will have highest priority; default is 7)\n *\n * Note that ICW2 effectively contains the starting IDT vector number (ie, for IRQ 0),\n * which must be multiplied by 4 to calculate the vector offset, since every vector is 4 bytes long.\n *\n * Also, since the low 3 bits of ICW2 are ignored in 8086/8088 mode (ie, they are effectively\n * treated as zeros), this means that the starting IDT vector can only be a multiple of 8.\n *\n * So, if ICW2 is set to 0x08, the starting vector number (ie, for IRQ 0) will be 0x08, and the\n * 4-byte address for the corresponding ISR will be located at offset 0x20 in the real-mode IDT.\n *\n * ICW4 is typically set to 0x09, indicating 8086 mode, non-automatic EOI, buffered/slave mode.\n *\n * TODO: Determine why the original ROM BIOS chose buffered/slave over buffered/master.\n * Did it simply not matter in pre-AT systems with only one PIC, or am I misreading something?\n *\n * TODO: Consider support for level-triggered PIC interrupts, even though the original IBM PCs\n * (up through MODEL_5170) used only edge-triggered interrupts.\n */\nChipSet.PIC0 = { // all models: the \"master\" PIC\n INDEX: 0,\n PORT_LO: 0x20,\n PORT_HI: 0x21\n};\n\nChipSet.PIC1 = { // MODEL_5170 and up: the \"slave\" PIC\n INDEX: 1,\n PORT_LO: 0xA0,\n PORT_HI: 0xA1\n};\n\nChipSet.PIC_LO = { // ChipSet.PIC1.PORT_LO or ChipSet.PIC2.PORT_LO\n ICW1: 0x10, // set means ICW1\n ICW1_ICW4: 0x01, // ICW4 needed (otherwise ICW4 must be sent)\n ICW1_SNGL: 0x02, // single PIC (and therefore no ICW3; otherwise there is another \"cascaded\" PIC)\n ICW1_ADI: 0x04, // call address interval is 4 (otherwise 8; presumably ignored in 8086/8088 mode)\n ICW1_LTIM: 0x08, // level-triggered interrupt mode (otherwise edge-triggered mode, which is what PCs use)\n OCW2: 0x00, // bit 3 (PIC_LO.OCW3) and bit 4 (ChipSet.PIC_LO.ICW1) are clear in an OCW2 command byte\n OCW2_IR_LVL: 0x07,\n OCW2_OP_MASK: 0xE0, // of the following valid OCW2 operations, the first 4 are EOI commands (all have ChipSet.PIC_LO.OCW2_EOI set)\n OCW2_EOI: 0x20, // non-specific EOI (end-of-interrupt)\n OCW2_EOI_SPEC: 0x60, // specific EOI\n OCW2_EOI_ROT: 0xA0, // rotate on non-specific EOI\n OCW2_EOI_ROTSPEC: 0xE0, // rotate on specific EOI\n OCW2_SET_ROTAUTO: 0x80, // set rotate in automatic EOI mode\n OCW2_CLR_ROTAUTO: 0x00, // clear rotate in automatic EOI mode\n OCW2_SET_PRI: 0xC0, // bits 0-2 specify the lowest priority interrupt\n OCW3: 0x08, // bit 3 (PIC_LO.OCW3) is set and bit 4 (PIC_LO.ICW1) clear in an OCW3 command byte (bit 7 should be clear, too)\n OCW3_READ_IRR: 0x02, // read IRR register\n OCW3_READ_ISR: 0x03, // read ISR register\n OCW3_READ_CMD: 0x03,\n OCW3_POLL_CMD: 0x04, // poll\n OCW3_SMM_RESET: 0x40, // special mask mode: reset\n OCW3_SMM_SET: 0x60, // special mask mode: set\n OCW3_SMM_CMD: 0x60\n};\n\nChipSet.PIC_HI = { // ChipSet.PIC1.PORT_HI or ChipSet.PIC2.PORT_HI\n ICW2_VECTOR: 0xF8, // starting vector number (bits 0-2 are effectively treated as zeros in 8086/8088 mode)\n ICW4_8086: 0x01,\n ICW4_AUTO_EOI: 0x02,\n ICW4_MASTER: 0x04,\n ICW4_BUFFERED: 0x08,\n ICW4_FULLY_NESTED: 0x10,\n OCW1_IMR: 0xFF\n};\n\n/*\n * The priorities of IRQs 0-7 are normally high to low, unless the master PIC has been reprogrammed.\n * Also, if a slave PIC is present, the priorities of IRQs 8-15 fall between the priorities of IRQs 1 and 3.\n *\n * As the MODEL_5170 TechRef states:\n *\n * \"Interrupt requests are prioritized, with IRQ9 through IRQ12 and IRQ14 through IRQ15 having the\n * highest priority (IRQ9 is the highest) and IRQ3 through IRQ7 having the lowest priority (IRQ7 is\n * the lowest).\n *\n * Interrupt 13 (IRQ.FPU) is used on the system board and is not available on the I/O channel.\n * Interrupt 8 (IRQ.RTC) is used for the real-time clock.\"\n *\n * This priority scheme is a byproduct of IRQ8 through IRQ15 (slave PIC interrupts) being tied to IRQ2 of\n * the master PIC. As a result, the two other system board interrupts, IRQ0 and IRQ1, continue to have the\n * highest priority, by default.\n */\nChipSet.IRQ = {\n TIMER0: 0x00,\n KBD: 0x01,\n SLAVE: 0x02, // MODEL_5170\n COM2: 0x03,\n COM1: 0x04,\n XTC: 0x05, // MODEL_5160 uses IRQ 5 for HDC (XTC version)\n LPT2: 0x05, // MODEL_5170 uses IRQ 5 for LPT2\n FDC: 0x06,\n LPT1: 0x07,\n RTC: 0x08, // MODEL_5170\n IRQ2: 0x09, // MODEL_5170\n FPU: 0x0D, // MODEL_5170\n ATC: 0x0E // MODEL_5170 uses IRQ 14 for HDC (ATC version)\n};\n\n/*\n * 8253 Programmable Interval Timer (PIT) I/O ports\n *\n * Although technically, a PIT provides 3 \"counters\" rather than 3 \"timers\", we have\n * adopted IBM's TechRef nomenclature, which refers to the PIT's counters as TIMER0,\n * TIMER1, and TIMER2. For machines with a second PIT (eg, the DeskPro 386), we refer\n * to those additional counters as TIMER3, TIMER4, and TIMER5.\n *\n * In addition, if there's a need to refer to a specific PIT, use PIT0 for the first PIT\n * and PIT1 for the second. This mirrors how we refer to multiple DMA controllers\n * (eg, DMA0 and DMA1) and multiple PICs (eg, PIC0 and PIC1).\n *\n * This differs from COMPAQ's nomenclature, which used \"Timer 1\" to refer to the first\n * PIT, and \"Timer 2\" for the second PIT, and then referred to \"Counter 0\", \"Counter 1\",\n * and \"Counter 2\" within each PIT.\n */\nChipSet.PIT0 = {\n PORT: 0x40,\n INDEX: 0,\n TIMER0: 0, // used for time-of-day (prior to MODEL_5170)\n TIMER1: 1, // used for memory refresh\n TIMER2: 2 // used for speaker tone generation\n};\n\nChipSet.PIT1 = {\n PORT: 0x48, // MODEL_COMPAQ_DESKPRO386 only\n INDEX: 1,\n TIMER3: 0, // used for fail-safe clock\n TIMER4: 1, // N/A\n TIMER5: 2 // used for refresher request extend/speed control\n};\n\nChipSet.PIT_CTRL = {\n PORT1: 0x43, // write-only control register (use the Read-Back command to get status)\n PORT2: 0x4B, // write-only control register (use the Read-Back command to get status)\n BCD: 0x01,\n MODE: 0x0E,\n MODE0: 0x00, // interrupt on Terminal Count (TC)\n MODE1: 0x02, // programmable one-shot\n MODE2: 0x04, // rate generator\n MODE3: 0x06, // square wave generator\n MODE4: 0x08, // software-triggered strobe\n MODE5: 0x0A, // hardware-triggered strobe\n RW: 0x30,\n RW_LATCH: 0x00,\n RW_LSB: 0x10,\n RW_MSB: 0x20,\n RW_BOTH: 0x30,\n SC: 0xC0,\n SC_CTR0: 0x00,\n SC_CTR1: 0x40,\n SC_CTR2: 0x80,\n SC_BACK: 0xC0,\n SC_SHIFT: 6,\n RB_CTR0: 0x02,\n RB_CTR1: 0x04,\n RB_CTR2: 0x08,\n RB_STATUS: 0x10, // if this bit is CLEAR, then latch the current status of the selected counter(s)\n RB_COUNTS: 0x20, // if this bit is CLEAR, then latch the current count(s) of the selected counter(s)\n RB_NULL: 0x40, // bit set in Read-Back status byte if the counter has not been \"fully loaded\" yet\n RB_OUT: 0x80 // bit set in Read-Back status byte if fOUT is true\n};\n\nChipSet.TIMER_TICKS_PER_SEC = 1193181;\n\n/*\n * 8255A Programmable Peripheral Interface (PPI) I/O ports, for Cassette/Speaker/Keyboard/SW1/etc\n *\n * Normally, 0x99 is written to PPI_CTRL.PORT, indicating that PPI_A.PORT and PPI_C.PORT are INPUT ports\n * and PPI_B.PORT is an OUTPUT port.\n *\n * However, the MODEL_5160 ROM BIOS initially writes 0x89 instead, making PPI_A.PORT an OUTPUT port.\n * I'm guessing that's just part of some \"diagnostic mode\", because all it writes to PPI_A.PORT are a series\n * of \"checkpoint\" values (ie, 0x01, 0x02, and 0x03) before updating PPI_CTRL.PORT with the usual 0x99.\n */\nChipSet.PPI_A = { // this.bPPIA (port 0x60)\n PORT: 0x60 // INPUT: keyboard scan code (PPI_B.CLEAR_KBD must be clear)\n};\n\nChipSet.PPI_B = { // this.bPPIB (port 0x61)\n PORT: 0x61, // OUTPUT (although it has to be treated as INPUT, too; the keyboard interrupt handler reads it, OR's PPI_B.CLEAR_KBD, writes it, and then rewrites the original read value)\n CLK_TIMER2: 0x01, // ALL: set to enable clock to TIMER2\n SPK_TIMER2: 0x02, // ALL: set to connect output of TIMER2 to speaker (MODEL_5150: clear for cassette)\n ENABLE_SW2: 0x04, // MODEL_5150: set to enable SW2[1-4] through PPI_C.PORT, clear to enable SW2[5]; MODEL_5160: unused (there is no SW2 switch block on the MODEL_5160 motherboard)\n CASS_MOTOR_OFF: 0x08, // MODEL_5150: cassette motor off\n ENABLE_SW_HI: 0x08, // MODEL_5160: clear to read SW1[1-4], set to read SW1[5-8]\n DISABLE_RW_MEM: 0x10, // ALL: clear to enable RAM parity check, set to disable\n DISABLE_IO_CHK: 0x20, // ALL: clear to enable I/O channel check, set to disable\n CLK_KBD: 0x40, // ALL: clear to force keyboard clock low\n CLEAR_KBD: 0x80 // ALL: clear to enable keyboard scan codes (MODEL_5150: set to enable SW1 through PPI_A.PORT)\n};\n\nChipSet.PPI_C = { // this.bPPIC (port 0x62)\n PORT: 0x62, // INPUT (see below)\n KBD_LATCH: 0x01, // MODEL_4860 only (set if keyboard data latched)\n NO_MODEM: 0x02, // MODEL_4860 only (set if no Internal Model Card installed)\n NO_DISKETTE: 0x04, // MODEL_4860 only (set if no Diskette Drive Adapter installed)\n NO_MEMEXP: 0x08, // MODEL_4860 only (set if no 64Kb Memory Expansion installed)\n SW: 0x0F, // MODEL_5150: SW2[1-4] or SW2[5], depending on whether PPI_B.ENABLE_SW2 is set or clear; MODEL_5160: SW1[1-4] or SW1[5-8], depending on whether PPI_B.ENABLE_SW_HI is clear or set\n CASS_DATA_IN: 0x10, // MODEL_4860 and MODEL_5150 \n TIMER2_OUT: 0x20, // MODEL_4860 and up (timer 2 output)\n KBD_DATA: 0x40, // MODEL_4860 only: data from either the keyboard cable or the IR receiver\n NO_KBD_CABLE: 0x80, // MODEL_4860 only: (set if keyboard cable not connected)\n IO_CHANNEL_CHK: 0x40, // used by NMI handler to detect I/O channel errors\n RW_PARITY_CHK: 0x80 // used by NMI handler to detect R/W memory parity errors\n};\n\nChipSet.PPI_CTRL = { // this.bPPICtrl (port 0x63)\n PORT: 0x63, // OUTPUT: initialized to 0x99, defining PPI_A and PPI_C as INPUT and PPI_B as OUTPUT\n A_IN: 0x10,\n B_IN: 0x02,\n C_IN_LO: 0x01,\n C_IN_HI: 0x08,\n B_MODE: 0x04,\n A_MODE: 0x60\n};\n\n/*\n * Switches Overview\n * -----------------\n *\n * The conventions used for the sw1 and sw2 strings are that the left-most character represents DIP switch [1],\n * the right-most character represents DIP switch [8], and \"1\" means the DIP switch is ON and \"0\" means it is OFF.\n *\n * Internally, we convert the above strings into binary values that the 8255A PPI returns, where DIP switch [1]\n * is bit 0 and DIP switch [8] is bit 7, and 0 indicates the switch is ON and 1 indicates it is OFF.\n *\n * For reference, here's how the SW1 and SW2 switches correspond to the internal 8255A PPI bit values:\n *\n * SW1[1] (bit 0) \"0xxxxxxx\" (1): IPL, \"1xxxxxxx\" (0): No IPL\n * SW1[2] (bit 1) reserved on the 5150; OFF (1) if FPU installed in a 5160\n * SW1[3,4] (bits 3-2) \"xx11xxxx\" (00): 16Kb, \"xx01xxxx\" (10): 32Kb, \"xx10xxxx\" (01): 48Kb, \"xx00xxxx\" (11): 64Kb\n * SW1[5,6] (bits 5-4) \"xxxx11xx\" (00): none, \"xxxx01xx\" (10): tv, \"xxxx10xx\" (01): color, \"xxxx00xx\" (11): mono\n * SW1[7,8] (bits 7-6) \"xxxxxx11\" (00): 1 FD, \"xxxxxx01\" (10): 2 FD, \"xxxxxx10\" (01): 3 FD, \"xxxxxx00\" (11): 4 FD\n *\n * Note: FD refers to floppy drive, and IPL refers to an \"Initial Program Load\" floppy drive.\n *\n * SW2[1-5] (bits 4-0) \"NNNxxxxx\": number of 32Kb blocks of I/O expansion RAM present\n *\n * For example, sw1=\"01110011\" indicates that all SW1 DIP switches are ON, except for SW1[1], SW1[5] and SW1[6],\n * which are OFF. Internally, the order of these bits must reversed (to 11001110) and then inverted (to 00110001)\n * to yield the value that the 8255A PPI returns. Reading the final value right-to-left, 00110001 indicates an\n * IPL floppy drive, 1X of RAM (where X is 16Kb on a MODEL_5150 and 64Kb on a MODEL_5160), MDA, and 1 floppy drive.\n *\n * WARNING: It is possible to set SW1 to indicate more memory than the RAM component has been configured to provide.\n * This is a configuration error which will cause the machine to crash after reporting a \"201\" error code (memory\n * test failure), which is presumably what a real machine would do if it was similarly misconfigured. Surprisingly,\n * the BIOS forges ahead, setting SP to the top of the memory range indicated by SW1 (via INT 0x12), but the lack of\n * a valid stack causes the system to crash after the next IRET. The BIOS should have either halted or modified\n * the actual memory size to match the results of the memory test.\n *\n * MODEL 5150 Switches\n * -------------------\n *\n * PPI_SW bits are exposed via port PPI_A.\n *\n * MODEL 5160 Switches\n * ------------------------\n *\n * PPI_SW bits 0-3 are exposed via PPI_C.SW if PPI_B.ENABLE_SW_HI is clear; bits 4-7 if PPI_B.ENABLE_SW_HI is set.\n *\n * AT&T 6300 Switches\n * ------------------\n *\n * Based on ATT_PC_6300_Service_Manual.pdf, there are two 8-switch blocks, DIPSW-0 and DIPSW-1, where:\n *\n * DIPSW-0[1-4] Total RAM\n * DIPSW-0[5] - ON if 8087 not installed, OFF if installed\n * DIPSW-0[6] - ON if 8250 ACE serial interface present, OFF if Z-8530 SCC interface present\n * DIPSW-0[7] - Not used\n * DIPSW-0[8] - Type of EPROM chip for ROM 1.21 or lower, or presence of RAM in bank 1 for ROM 1.43 or higher\n *\n * and:\n *\n * DIPSW-1[1] - Floppy Type (ON for 48TPI, OFF for 96TPI)\n * DIPSW-1[2] - Floppy Speed (ON for slow startup, OFF for fast startup)\n * DIPSW-1[3] - HDU ROM (ON for indigenous, OFF for external)\n * DIPSW-1[4] - Not used (ROM 1.21 or lower) or Scroll Speed (ROM 1.43 or higher: ON for fast, OFF for slow)\n * DIPSW-1[5-6] - Display Type (11=EGA or none, 01=color 40x25, 10=color 80x25, 00=monochrome 80x25)\n * DIPSW-1[7-8] - Number of Floppy Drives (11=one, 01=two, 10=three, 00=four)\n *\n * For AT&T 6300 ROM 1.43 and up, DIPSW-0 supports the following RAM combinations:\n *\n * 0111xxx1: 128Kb on motherboard\n * 1011xxx0: 256Kb on motherboard\n * 1101xxx0: 256Kb on motherboard, 256Kb on expansion board (512Kb total)\n * 1110xxx1: 512Kb on motherboard\n * 0101xxx0: 256Kb on motherboard, 384Kb on expansion board (640Kb total)\n * 0100xxx0: 640Kb on motherboard (128Kb bank 0, 512Kb bank 1)\n * 0110xxx0: 640Kb on motherboard (512Kb bank 0, 128Kb bank 1)\n *\n * Inspection of the AT&T 6300 Plus ROM BIOS reveals that DIPSW-0[1-8] are obtained from bits 0-7\n * of port 0x66 (\"sys_conf_a\") and DIPSW-1[1-8] are obtained from bits 0-7 of port 0x67 (\"sys_conf_b\").\n */\n\nChipSet.PPI_SW = {\n FDRIVE: {\n IPL: 0x01, // MODEL_5150: IPL (\"Initial Program Load\") floppy drive attached; MODEL_5160: \"Loop on POST\"\n ONE: 0x00, // 1 floppy drive attached (or 0 drives if PPI_SW.FDRIVE_IPL is not set -- MODEL_5150 only)\n TWO: 0x40, // 2 floppy drives attached\n THREE: 0x80, // 3 floppy drives attached\n FOUR: 0xC0, // 4 floppy drives attached\n MASK: 0xC0,\n SHIFT: 6\n },\n FPU: 0x02, // MODEL_5150: reserved; MODEL_5160: FPU coprocessor installed\n MEMORY: { // MODEL_5150: \"X\" is 16Kb; MODEL_5160: \"X\" is 64Kb\n X1: 0x00, // 16Kb or 64Kb\n X2: 0x04, // 32Kb or 128Kb\n X3: 0x08, // 48Kb or 192Kb\n X4: 0x0C, // 64Kb or 256Kb\n MASK: 0x0C,\n SHIFT: 2\n },\n MONITOR: {\n TV: 0x10,\n COLOR: 0x20,\n MONO: 0x30,\n MASK: 0x30,\n SHIFT: 4\n }\n};\n\n/*\n * Some models have completely different DIP switch implementations from the MODEL_5150, which, being\n * the first IBM PC, was the model that we, um, modeled our DIP switch support on. So, to support other\n * implementations, we now get and set DIP switch values according to SWITCH_TYPE, and rely on the\n * tables that follow to define which DIP switch(es) correspond to each SWITCH_TYPE.\n *\n * Not every model needs its own tables. The getDIPSwitches() and setDIPSwitches() functions look first\n * for an *exact* model match, then a \"truncated\" model match, and failing that, they fall back to the\n * MODEL_5150 switch definitions.\n */\nChipSet.SWITCH_TYPE = {\n FLOPNUM: 1,\n FLOPTYPE: 2,\n FPU: 3,\n MONITOR: 4,\n LOWMEM: 5,\n EXPMEM: 6\n};\n\nChipSet.DIPSW = {};\nChipSet.DIPSW[ChipSet.MODEL_5150] = [{},{}];\nChipSet.DIPSW[ChipSet.MODEL_5150][0][ChipSet.SWITCH_TYPE.FLOPNUM] = {\n MASK: 0xC0,\n VALUES: {\n 1: 0x00,\n 2: 0x40,\n 3: 0x80,\n 4: 0xC0\n },\n LABEL: \"Number of Floppy Drives\"\n};\n/*\n * NOTE: Both the Aug 1981 and the Apr 1984 IBM 5150 Technical Reference Manuals list SW1[2] as \"RESERVED\",\n * but the Aug 1981 edition (p. 2-28) also says SW1[2] \"MUST BE ON (RESERVED FOR CO-PROCESSOR)\". Contemporary\n * articles discussing 8087 support in early PCs all indicate that switch SW1[2] must OFF if a coprocessor\n * is installed, and the 1984 5150 Guide to Operations (p. 5-34) confirms it.\n *\n * The Aug 1981 5150 TechRef makes no further mention of coprocessor support, whereas the Apr 1984 5150 TechRef\n * discusses it in a fair bit of detail, including the fact that 8087 exceptions generate an NMI, despite Intel's\n * warning in their iAPX 86,88 User's Manual, p. S-27, that \"[t]he 8087 should not be tied to the CPU's NMI\n * (non-maskable interrupt) line.\")\n */\nChipSet.DIPSW[ChipSet.MODEL_5150][0][ChipSet.SWITCH_TYPE.FPU] = {\n MASK: 0x02,\n VALUES: {\n 0: 0x00, // 0 means an FPU is NOT installed\n 1: 0x02 // 1 means an FPU is installed\n },\n LABEL: \"FPU\"\n};\nChipSet.DIPSW[ChipSet.MODEL_5150][0][ChipSet.SWITCH_TYPE.MONITOR] = {\n MASK: 0x30,\n VALUES: {\n 0: 0x00,\n 1: 0x10,\n 2: 0x20,\n 3: 0x30,\n \"none\": 0x00,\n \"tv\": 0x10, // aka composite\n \"color\":0x20,\n \"cga\": 0x20, // alias for color\n \"mda\": 0x30, // alias for mono\n \"mono\": 0x30,\n \"ega\": 0x00,\n \"vga\": 0x00\n },\n LABEL: \"Monitor Type\"\n};\nChipSet.DIPSW[ChipSet.MODEL_5150][0][ChipSet.SWITCH_TYPE.LOWMEM] = {\n MASK: 0x0C,\n VALUES: {\n 16: 0x00,\n 32: 0x04,\n 48: 0x08,\n 64: 0x0C\n },\n LABEL: \"Base Memory (16Kb Increments)\"\n};\nChipSet.DIPSW[ChipSet.MODEL_5150][1][ChipSet.SWITCH_TYPE.EXPMEM] = {\n MASK: 0x1F, // technically, this mask should be 0x0F for ROM revisions prior to 5150_REV3, and 0x1F on 5150_REV3\n VALUES: {\n 0: 0x00,\n 32: 0x01,\n 64: 0x02,\n 96: 0x03,\n 128: 0x04,\n 160: 0x05,\n 192: 0x06,\n 224: 0x07,\n 256: 0x08,\n 288: 0x09,\n 320: 0x0A,\n 352: 0x0B,\n 384: 0x0C,\n 416: 0x0D,\n 448: 0x0E,\n 480: 0x0F,\n 512: 0x10,\n 544: 0x11,\n 576: 0x12\n /*\n * Obviously, more bit combinations are possible here (up to 0x1F), but assuming a minimum of 64Kb already on\n * the motherboard, any amount of expansion memory above 576Kb would break the 640Kb barrier. Yes, if you used\n * only MDA or CGA video cards, you could go as high as 704Kb in a real system. But in our happy little world,\n * this is where we stop.\n *\n * TODO: A value larger than 0x12 usually comes from a misconfigured machine (ie, it forgot to leave SW2[5] ON).\n * To compensate, when getDIPMemorySize() gets null back from its EXPMEM request, perhaps it should try truncating\n * the DIP switch value. However, that would introduce a machine-specific hack into a function that's supposed\n * be machine-independent now.\n */\n },\n LABEL: \"Expansion Memory (32Kb Increments)\"\n};\n\nChipSet.DIPSW[ChipSet.MODEL_5160] = [{},{}];\nChipSet.DIPSW[ChipSet.MODEL_5160][0][ChipSet.SWITCH_TYPE.FLOPNUM] = ChipSet.DIPSW[ChipSet.MODEL_5150][0][ChipSet.SWITCH_TYPE.FLOPNUM];\nChipSet.DIPSW[ChipSet.MODEL_5160][0][ChipSet.SWITCH_TYPE.FPU] = ChipSet.DIPSW[ChipSet.MODEL_5150][0][ChipSet.SWITCH_TYPE.FPU];\nChipSet.DIPSW[ChipSet.MODEL_5160][0][ChipSet.SWITCH_TYPE.MONITOR] = ChipSet.DIPSW[ChipSet.MODEL_5150][0][ChipSet.SWITCH_TYPE.MONITOR];\nChipSet.DIPSW[ChipSet.MODEL_5160][0][ChipSet.SWITCH_TYPE.LOWMEM] = {\n MASK: 0x0C,\n VALUES: {\n 64: 0x00,\n 128: 0x04,\n 192: 0x08,\n 256: 0x0C\n },\n LABEL: \"Base Memory (64Kb Increments)\"\n};\nChipSet.DIPSW[ChipSet.MODEL_5160][1][ChipSet.SWITCH_TYPE.EXPMEM] = ChipSet.DIPSW[ChipSet.MODEL_5150][1][ChipSet.SWITCH_TYPE.EXPMEM];\n\nChipSet.DIPSW[ChipSet.MODEL_ATT_6300] = [{},{}];\nChipSet.DIPSW[ChipSet.MODEL_ATT_6300][0][ChipSet.SWITCH_TYPE.LOWMEM] = {\n MASK: 0x8F,\n VALUES: {\n 128: 0x01, // \"0111xxx1\"\n 256: 0x82, // \"1011xxx0\"\n 512: 0x08, // \"1110xxx1\"\n 640: 0x8D // \"0100xxx0\"\n },\n LABEL: \"Base Memory (128Kb Increments)\"\n};\nChipSet.DIPSW[ChipSet.MODEL_ATT_6300][0][ChipSet.SWITCH_TYPE.FPU] = {\n MASK: 0x10,\n VALUES: {\n 0: 0x00,\n 1: 0x10\n },\n LABEL: \"FPU\"\n};\nChipSet.DIPSW[ChipSet.MODEL_ATT_6300][1][ChipSet.SWITCH_TYPE.FLOPTYPE] = {\n MASK: 0x01,\n VALUES: {\n 0: 0x00,\n 1: 0x01\n },\n LABEL: \"Floppy Type\"\n};\nChipSet.DIPSW[ChipSet.MODEL_ATT_6300][1][ChipSet.SWITCH_TYPE.FLOPNUM] = ChipSet.DIPSW[ChipSet.MODEL_5150][0][ChipSet.SWITCH_TYPE.FLOPNUM];\nChipSet.DIPSW[ChipSet.MODEL_ATT_6300][1][ChipSet.SWITCH_TYPE.MONITOR] = ChipSet.DIPSW[ChipSet.MODEL_5150][0][ChipSet.SWITCH_TYPE.MONITOR];\n\n/*\n * 8041 Keyboard Controller I/O ports (MODEL_ATT_6300)\n *\n * The AT&T 6300 uses an 8041 for its Keyboard Controller, which has the following ports:\n *\n * Port Description\n * ---- -----------\n * 0x60 Keyboard Scan Code (input)\n * 0x61 Keyboard Control Port (output)\n * 0x64 Keyboard Status Port (input)\n *\n * And the Keyboard Control Port (0x61) has the following bit definitions:\n *\n * 0x01 Speaker gate to 8253 (counter 2)\n * 0x02 Speaker data\n * 0x0C Not used\n * 0x10 RAM Parity (NMI) Enable\n * 0x20 I/O Channel (NMI) Enable\n * 0x40 Keyboard Clock Reset\n * 0x80 Reset Interrupt Pending\n */\n\n/*\n * 8042 Keyboard Controller I/O ports (MODEL_5170)\n *\n * On the MODEL_5170, port 0x60 is designated C8042.DATA rather than PPI_A, although the BIOS also refers to it\n * as \"PORT_A: 8042 KEYBOARD SCAN/DIAG OUTPUTS\"). This is the 8042's output buffer and should be read only when\n * C8042.STATUS.OUTBUFF_FULL is set.\n *\n * Similarly, port 0x61 is designated C8042.RWREG rather than PPI_B; the BIOS also refers to it as \"PORT_B: 8042\n * READ WRITE REGISTER\", but it is not otherwise discussed in the MODEL_5170 TechRef's 8042 documentation.\n *\n * There are brief references to bits 0 and 1 (C8042.RWREG.CLK_TIMER2 and C8042.RWREG.SPK_TIMER2), and the BIOS sets\n * bits 2-7 to \"DISABLE PARITY CHECKERS\" (principally C8042.RWREG.DISABLE_NMI, which are bits 2 and 3); why the BIOS\n * also sets bits 4-7 (or if those bits are even settable) is unclear, since it uses 11111100b rather than defined\n * constants.\n *\n * The bottom line: on a MODEL_5170, port 0x61 is still used for speaker control and parity checking, so we use\n * the same register (bPPIB) but install different I/O handlers. It's also bi-directional: at one point, the BIOS\n * reads C8042.RWREG.REFRESH_BIT (bit 4) to verify that it's alternating.\n *\n * PPI_C and PPI_CTRL don't seem to be documented or used by the MODEL_5170 BIOS, so I'm assuming they're obsolete.\n *\n * NOTE: For more information on the 8042 Controller, including information on undocumented commands, refer to the\n * documents in /devices/pc/keyboard, as well as the following websites:\n *\n * http://halicery.com/8042/8042_INTERN_TXT.htm\n * http://www.os2museum.com/wp/ibm-pcat-8042-keyboard-controller-commands/\n */\nChipSet.C8042 = {\n DATA: { // this.b8042OutBuff (PPI_A on previous models, still referred to as \"PORT A\" by the MODEL_5170 BIOS)\n PORT: 0x60,\n CMD: { // this.b8042CmdData (C8042.DATA.CMD \"data bytes\" written to port 0x60, after writing a C8042.CMD byte to port 0x64)\n INT_ENABLE: 0x01, // generate an interrupt when the controller places data in the output buffer\n SYS_FLAG: 0x04, // this value is propagated to ChipSet.C8042.STATUS.SYS_FLAG\n NO_INHIBIT: 0x08, // disable inhibit function\n NO_CLOCK: 0x10, // disable keyboard by driving \"clock\" line low\n PC_MODE: 0x20,\n PC_COMPAT: 0x40 // generate IBM PC-compatible scan codes\n },\n SELF_TEST: { // result of ChipSet.C8042.CMD.SELF_TEST command (0xAA)\n OK: 0x55\n },\n INTF_TEST: { // result of ChipSet.C8042.CMD.INTF_TEST command (0xAB)\n OK: 0x00, // no error\n CLOCK_LO: 0x01, // keyboard clock line stuck low\n CLOCK_HI: 0x02, // keyboard clock line stuck high\n DATA_LO: 0x03, // keyboard data line stuck low\n DATA_HI: 0x04 // keyboard data line stuck high\n }\n },\n INPORT: { // this.b8042InPort\n COMPAQ_50MHZ: 0x01, // 50Mhz system clock enabled (0=48Mhz); see COMPAQ 386/25 TechRef p2-106\n UNDEFINED: 0x02, // undefined\n COMPAQ_NO80387: 0x04, // 80387 coprocessor NOT installed; see COMPAQ 386/25 TechRef p2-106\n COMPAQ_NOWEITEK:0x08, // Weitek coprocessor NOT installed; see COMPAQ 386/25 TechRef p2-106\n ENABLE_256KB: 0x10, // enable 2nd 256Kb of system board RAM\n COMPAQ_HISPEED: 0x10, // high-speed enabled (0=auto); see COMPAQ 386/25 TechRef p2-106\n MFG_OFF: 0x20, // manufacturing jumper not installed\n COMPAQ_DIP5OFF: 0x20, // system board DIP switch #5 OFF (0=ON); see COMPAQ 386/25 TechRef p2-106\n MONO: 0x40, // monochrome monitor is primary display\n COMPAQ_NONDUAL: 0x40, // COMPAQ Dual-Mode monitor NOT installed; see COMPAQ 386/25 TechRef p2-106\n KBD_UNLOCKED: 0x80 // keyboard not inhibited (in COMPAQ parlance: security lock is unlocked)\n },\n OUTPORT: { // this.b8042OutPort\n NO_RESET: 0x01, // set by default\n A20_ON: 0x02, // set by default\n COMPAQ_SLOWD: 0x08, // SL0WD* NOT asserted (refer to timer 2, counter 2); see COMPAQ 386/25 TechRef p2-105\n OUTBUFF_FULL: 0x10, // output buffer full\n INBUFF_EMPTY: 0x20, // input buffer empty\n KBD_CLOCK: 0x40, // keyboard clock (output)\n KBD_DATA: 0x80 // keyboard data (output)\n },\n TESTPORT: { // generated \"on the fly\"\n KBD_CLOCK: 0x01, // keyboard clock (input)\n KBD_DATA: 0x02 // keyboard data (input)\n },\n RWREG: { // this.bPPIB (since CLK_TIMER2 and SPK_TIMER2 are in both PPI_B and RWREG)\n PORT: 0x61,\n CLK_TIMER2: 0x01, // set to enable clock to TIMER2 (R/W)\n SPK_TIMER2: 0x02, // set to connect output of TIMER2 to speaker (R/W)\n COMPAQ_FSNMI: 0x04, // set to disable RAM/FS NMI (R/W, DESKPRO386)\n COMPAQ_IONMI: 0x08, // set to disable IOCHK NMI (R/W, DESKPRO386)\n DISABLE_NMI: 0x0C, // set to disable IOCHK and RAM/FS NMI, clear to enable (R/W)\n REFRESH_BIT: 0x10, // 0 if RAM refresh occurring, 1 if RAM not in refresh cycle (R/O)\n OUT_TIMER2: 0x20, // state of TIMER2 output signal (R/O, DESKPRO386)\n IOCHK_NMI: 0x40, // IOCHK NMI (R/O); to reset, pulse bit 3 (0x08)\n RAMFS_NMI: 0x80, // RAM/FS (parity or fail-safe) NMI (R/O); to reset, pulse bit 2 (0x04)\n NMI_ERROR: 0xC0\n },\n CMD: { // this.b8042InBuff (on write to port 0x64, interpret this as a CMD)\n PORT: 0x64,\n READ_CMD: 0x20, // sends the current CMD byte (this.b8042CmdData) to C8042.DATA.PORT\n WRITE_CMD: 0x60, // followed by a command byte written to C8042.DATA.PORT (see C8042.DATA.CMD)\n COMPAQ_SLOWD: 0xA3, // enable system slow down; see COMPAQ 386/25 TechRef p2-111\n COMPAQ_TOGGLE: 0xA4, // toggle speed-control bit; see COMPAQ 386/25 TechRef p2-111\n COMPAQ_SPCREAD: 0xA5, // special read of \"port 2\"; see COMPAQ 386/25 TechRef p2-111\n SELF_TEST: 0xAA, // self-test (C8042.DATA.SELF_TEST.OK is placed in the output buffer if no errors)\n INTF_TEST: 0xAB, // interface test\n DIAG_DUMP: 0xAC, // diagnostic dump\n DISABLE_KBD: 0xAD, // disable keyboard\n ENABLE_KBD: 0xAE, // enable keyboard\n READ_INPORT: 0xC0, // read input port and place data in output buffer (use only if output buffer empty)\n READ_OUTPORT: 0xD0, // read output port and place data in output buffer (use only if output buffer empty)\n WRITE_OUTPORT: 0xD1, // next byte written to C8042.DATA.PORT (port 0x60) is placed in the output port (see C8042.OUTPORT)\n READ_TEST: 0xE0,\n PULSE_OUTPORT: 0xF0 // this is the 1st of 16 commands (0xF0-0xFF) that pulse bits 0-3 of the output port\n },\n STATUS: { // this.b8042Status (on read from port 0x64)\n PORT: 0x64,\n OUTBUFF_FULL: 0x01,\n INBUFF_FULL: 0x02, // set if the controller has received but not yet read data from the input buffer (not normally set)\n SYS_FLAG: 0x04,\n CMD_FLAG: 0x08, // set on write to C8042.CMD (port 0x64), clear on write to C8042.DATA (port 0x60)\n NO_INHIBIT: 0x10, // (in COMPAQ parlance: security lock not engaged)\n XMT_TIMEOUT: 0x20,\n RCV_TIMEOUT: 0x40,\n PARITY_ERR: 0x80, // last byte of data received had EVEN parity (ODD parity is normally expected)\n OUTBUFF_DELAY: 0x100\n }\n};\n\n/*\n * MC146818A RTC/CMOS Ports (MODEL_5170)\n *\n * Write a CMOS address to ChipSet.CMOS.ADDR.PORT, then read/write data from/to ChipSet.CMOS.DATA.PORT.\n *\n * The ADDR port also controls NMI: write an address with bit 7 clear to enable NMI or set to disable NMI.\n */\nChipSet.CMOS = {\n ADDR: { // this.bCMOSAddr\n PORT: 0x70,\n RTC_SEC: 0x00,\n RTC_SEC_ALRM: 0x01,\n RTC_MIN: 0x02,\n RTC_MIN_ALRM: 0x03,\n RTC_HOUR: 0x04,\n RTC_HOUR_ALRM: 0x05,\n RTC_WEEK_DAY: 0x06,\n RTC_MONTH_DAY: 0x07,\n RTC_MONTH: 0x08,\n RTC_YEAR: 0x09, // 2-digit year (eg, 0x82 for 1982 if BCD mode)\n STATUSA: 0x0A,\n STATUSB: 0x0B,\n STATUSC: 0x0C,\n STATUSD: 0x0D,\n DIAG: 0x0E,\n SHUTDOWN: 0x0F,\n FDRIVE: 0x10,\n HDRIVE: 0x12, // bits 4-7 contain type of drive 0, bits 0-3 contain type of drive 1 (type 0 means none)\n EQUIP: 0x14,\n BASEMEM_LO: 0x15,\n BASEMEM_HI: 0x16, // the BASEMEM values indicate the total Kb of base memory, up to 0x280 (640Kb)\n EXTMEM_LO: 0x17,\n EXTMEM_HI: 0x18, // the EXTMEM values indicate the total Kb of extended memory, up to 0x3C00 (15Mb)\n EXTHDRIVE0: 0x19, // if bits 4-7 of HDRIVE contains 15, then the type of drive 0 is stored here (16-255)\n EXTHDRIVE1: 0x1A, // if bits 0-3 of HDRIVE contains 15, then the type of drive 1 is stored here (16-255)\n CHKSUM_HI: 0x2E,\n CHKSUM_LO: 0x2F, // CMOS bytes included in the checksum calculation: 0x10-0x2D\n EXTMEM2_LO: 0x30,\n EXTMEM2_HI: 0x31,\n CENTURY_DATE: 0x32, // 2-digit century value in BCD (eg, 0x19 for 20th century, 0x20 for 21st century)\n BOOT_INFO: 0x33, // 0x80 if 128Kb expansion memory installed, 0x40 if Setup Utility wants an initial setup message\n MASK: 0x3F,\n TOTAL: 0x40,\n NMI_DISABLE: 0x80\n },\n DATA: { // this.abCMOSData\n PORT: 0x71\n },\n STATUSA: { // abCMOSData[ChipSet.CMOS.ADDR.STATUSA]\n UIP: 0x80, // bit 7: 1 indicates Update-In-Progress, 0 indicates date/time ready to read\n DV: 0x70, // bits 6-4 (DV2-DV0) are programmed to 010 to select a 32.768Khz time base\n RS: 0x0F // bits 3-0 (RS3-RS0) are programmed to 0110 to select a 976.562us interrupt rate\n },\n STATUSB: { // abCMOSData[ChipSet.CMOS.ADDR.STATUSB]\n SET: 0x80, // bit 7: 1 to set any/all of the 14 time-bytes\n PIE: 0x40, // bit 6: 1 for Periodic Interrupt Enable\n AIE: 0x20, // bit 5: 1 for Alarm Interrupt Enable\n UIE: 0x10, // bit 4: 1 for Update Interrupt Enable\n SQWE: 0x08, // bit 3: 1 for Square Wave Enabled (as set by the STATUSA rate selection bits)\n BINARY: 0x04, // bit 2: 1 for binary Date Mode, 0 for BCD Date Mode\n HOUR24: 0x02, // bit 1: 1 for 24-hour mode, 0 for 12-hour mode\n DST: 0x01 // bit 0: 1 for Daylight Savings Time enabled\n },\n STATUSC: { // abCMOSData[ChipSet.CMOS.ADDR.STATUSC]\n IRQF: 0x80, // bit 7: 1 indicates one or more of the following bits (PF, AF, UF) are set\n PF: 0x40, // bit 6: 1 indicates Periodic Interrupt\n AF: 0x20, // bit 5: 1 indicates Alarm Interrupt\n UF: 0x10, // bit 4: 1 indicates Update Interrupt\n RESERVED: 0x0F\n },\n STATUSD: { // abCMOSData[ChipSet.CMOS.ADDR.STATUSD]\n VRB: 0x80, // bit 7: 1 indicates Valid RAM Bit (0 implies power was and/or is lost)\n RESERVED: 0x7F\n },\n DIAG: { // abCMOSData[ChipSet.CMOS.ADDR.DIAG]\n RTCFAIL: 0x80, // bit 7: 1 indicates RTC lost power\n CHKSUMFAIL: 0x40, // bit 6: 1 indicates bad CMOS checksum\n CONFIGFAIL: 0x20, // bit 5: 1 indicates bad CMOS configuration info\n MEMSIZEFAIL: 0x10, // bit 4: 1 indicates memory size miscompare\n HDRIVEFAIL: 0x08, // bit 3: 1 indicates hard drive controller or drive init failure\n TIMEFAIL: 0x04, // bit 2: 1 indicates time failure\n RESERVED: 0x03\n },\n FDRIVE: { // abCMOSData[ChipSet.CMOS.ADDR.FDRIVE]\n D0_MASK: 0xF0, // Drive 0 type in high nibble\n D1_MASK: 0x0F, // Drive 1 type in lower nibble\n NONE: 0, // no drive\n /*\n * There's at least one floppy drive type that IBM didn't bother defining a CMOS drive type for:\n * single-sided drives that were only capable of storing 160Kb (or 180Kb when using 9 sectors/track).\n * So, as you can see in getDIPFloppyDriveType(), we lump all standard diskette capacities <= 360Kb\n * into the FD360 bucket.\n */\n FD360: 1, // 5.25-inch double-sided double-density (DSDD 48TPI) drive: 40 tracks, 9 sectors/track, 360Kb max\n FD1200: 2, // 5.25-inch double-sided high-density (DSHD 96TPI) drive: 80 tracks, 15 sectors/track, 1200Kb max\n FD720: 3, // 3.5-inch drive capable of storing 80 tracks and up to 9 sectors/track, 720Kb max\n FD1440: 4 // 3.5-inch drive capable of storing 80 tracks and up to 18 sectors/track, 1440Kb max\n },\n /*\n * HDRIVE types are defined by table in the HDC component, which uses setCMOSDriveType() to update the CMOS\n */\n HDRIVE: { // abCMOSData[ChipSet.CMOS.ADDR.HDRIVE]\n D0_MASK: 0xF0, // Drive 0 type in high nibble\n D1_MASK: 0x0F // Drive 1 type in lower nibble\n },\n /*\n * The CMOS equipment flags use the same format as the older PPI equipment flags\n */\n EQUIP: { // abCMOSData[ChipSet.CMOS.ADDR.EQUIP]\n MONITOR: ChipSet.PPI_SW.MONITOR, // PPI_SW.MONITOR.MASK == 0x30\n FPU: ChipSet.PPI_SW.FPU, // PPI_SW.FPU == 0x02\n FDRIVE: ChipSet.PPI_SW.FDRIVE // PPI_SW.FDRIVE.IPL == 0x01 and PPI_SW.FDRIVE.MASK = 0xC0\n }\n};\n\n/*\n * DMA Page Registers\n *\n * The MODEL_5170 TechRef lists 0x80-0x9F as the range for DMA page registers, but that may be a bit\n * overbroad. There are a total of 8 (7 usable) DMA channels on the MODEL_5170, each of which has the\n * following assigned DMA page registers:\n *\n * Channel # Page Reg\n * --------- --------\n * 0 0x87\n * 1 0x83\n * 2 0x81\n * 3 0x82\n * 4 0x8F (not usable; the 5170 TechRef refers to this as the \"Refresh\" page register)\n * 5 0x8B\n * 6 0x89\n * 7 0x8A\n *\n * That leaves 0x80, 0x84, 0x85, 0x86, 0x88, 0x8C, 0x8D and 0x8E unaccounted for in the range 0x80-0x8F.\n * (I'm saving the question of what, if anything, is available in the range 0x90-0x9F for another day.)\n *\n * As for port 0x80, the TechRef says:\n *\n * \"I/O address hex 080 is used as a diagnostic-checkpoint port or register.\n * This port corresponds to a read/write register in the DMA page register (74LS612).\"\n *\n * so I used to have dedicated handlers and storage (bMFGData) for the register at port 0x80, but I've since\n * appended it to abDMAPageSpare, an 8-element array that captures all I/O to the 8 unassigned (aka \"spare\")\n * DMA page registers. The 5170 BIOS uses 0x80 as a \"checkpoint\" register, and the DESKPRO386 uses 0x84 in a\n * similar fashion. The 5170 also contains \"MFG_TST\" code that uses other unassigned DMA page registers as\n * scratch registers, which come in handy when RAM hasn't been tested/initialized yet.\n *\n * Here's our mapping of entries in the abDMAPageSpare array to the unassigned (\"spare\") DMA page registers:\n *\n * Index # Page Reg\n * -------- --------\n * 0 0x84\n * 1 0x85\n * 2 0x86\n * 3 0x88\n * 4 0x8C\n * 5 0x8D\n * 6 0x8E\n * 7 0x80\n *\n * The only reason port 0x80 is out of sequence (ie, at the end of the array, at index 7 instead of index 0) is\n * because it was added the array later, and the entire array gets written to our save/restore data structures, so\n * reordering the elements would be a bad idea.\n */\n\n/*\n * NMI Mask Register (port 0xA0)\n * \n * On the MODEL_5150 and MODEL_5160, this is a write-only register, and the only valid bit is ENABLE.\n * \n * On the MODEL_4860, this is a read-write register; the following bit definitions apply to writes, whereas\n * reads are defined as merely clearing the PCjr's keyboard NMI latch (which we maintain here in bit 0). \n */\nChipSet.NMI = { // this.bNMI\n PORT: 0xA0, //\n ENABLE: 0x80, // enables NMI\n IRTEST: 0x40, // enables 8253 timer 2 output into an IR diode on the IR receiver board\n SELCLK1: 0x20, // selects timer 0 output to be used as CLK input to timer 1\n DISHRQ: 0x10, // not implemented on the system board; for use with external bus-master devices\n KBD_LATCH: 0x01, // keyboard latch (we maintain it here for convenience; it gets propagated to PPI_C bit 0)\n RESET: 0x00 // default value on reset (TODO: Is NMI really disabled by default on reset?)\n};\n\n/*\n * FPU Coprocessor Control Registers (MODEL_5170)\n */\nChipSet.FPU = { // TODO: Define a variable for this?\n PORT_CLEAR: 0xF0, // clear the FPU's \"busy\" state\n PORT_RESET: 0xF1 // reset the FPU\n};\n\nChipSet.aDMAControllerInit = [0, null, null, 0, new Array(4), 0];\n\nChipSet.aDMAChannelInit = [true, [0,0], [0,0], [0,0], [0,0]];\n\nChipSet.aPICInit = [0, new Array(4)];\n\nChipSet.aTimerInit = [[0,0], [0,0], [0,0], [0,0]];\n\n/*\n * Port input notification tables, starting with the one that's common to all models (aPortInput)\n */\nChipSet.aPortInput = {\n 0x20: /** @this {ChipSet} */ function(port, addrFrom) { return this.inPICLo(ChipSet.PIC0.INDEX, addrFrom); },\n 0x21: /** @this {ChipSet} */ function(port, addrFrom) { return this.inPICHi(ChipSet.PIC0.INDEX, addrFrom); },\n 0x40: /** @this {ChipSet} */ function(port, addrFrom) { return this.inTimer(ChipSet.PIT0.INDEX, ChipSet.PIT0.TIMER0, port, addrFrom); },\n 0x41: /** @this {ChipSet} */ function(port, addrFrom) { return this.inTimer(ChipSet.PIT0.INDEX, ChipSet.PIT0.TIMER1, port, addrFrom); },\n 0x42: /** @this {ChipSet} */ function(port, addrFrom) { return this.inTimer(ChipSet.PIT0.INDEX, ChipSet.PIT0.TIMER2, port, addrFrom); },\n 0x43: /** @this {ChipSet} */ function(port, addrFrom) { return this.inTimerCtrl(ChipSet.PIT0.INDEX, port, addrFrom); },\n};\n\nChipSet.aPortInput4860 = {\n 0x60: ChipSet.prototype.inPPIA,\n 0x61: ChipSet.prototype.inPPIB,\n 0x62: ChipSet.prototype.inPPIC,\n 0x63: ChipSet.prototype.inPPICtrl, // technically, not actually readable, but I want the Debugger to be able to read it\n 0xA0: ChipSet.prototype.inNMI\n};\n\nChipSet.aPortInput5150 = {\n 0x60: ChipSet.prototype.inPPIA,\n 0x61: ChipSet.prototype.inPPIB,\n 0x62: ChipSet.prototype.inPPIC,\n 0x63: ChipSet.prototype.inPPICtrl, // technically, not actually readable, but I want the Debugger to be able to read it\n};\n\nChipSet.aPortInput5xxx = {\n 0x00: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelAddr(ChipSet.DMA0.INDEX, 0, port, addrFrom); },\n 0x01: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelCount(ChipSet.DMA0.INDEX, 0, port, addrFrom); },\n 0x02: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelAddr(ChipSet.DMA0.INDEX, 1, port, addrFrom); },\n 0x03: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelCount(ChipSet.DMA0.INDEX, 1, port, addrFrom); },\n 0x04: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelAddr(ChipSet.DMA0.INDEX, 2, port, addrFrom); },\n 0x05: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelCount(ChipSet.DMA0.INDEX, 2, port, addrFrom); },\n 0x06: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelAddr(ChipSet.DMA0.INDEX, 3, port, addrFrom); },\n 0x07: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelCount(ChipSet.DMA0.INDEX, 3, port, addrFrom); },\n 0x08: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAStatus(ChipSet.DMA0.INDEX, port, addrFrom); },\n 0x0D: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMATemp(ChipSet.DMA0.INDEX, port, addrFrom); },\n 0x81: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageReg(ChipSet.DMA0.INDEX, 2, port, addrFrom); },\n 0x82: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageReg(ChipSet.DMA0.INDEX, 3, port, addrFrom); },\n 0x83: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageReg(ChipSet.DMA0.INDEX, 1, port, addrFrom); },\n 0x87: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageReg(ChipSet.DMA0.INDEX, 0, port, addrFrom); }\n};\n\nChipSet.aPortInput5170 = {\n 0x60: ChipSet.prototype.in8042OutBuff,\n 0x61: ChipSet.prototype.in8042RWReg,\n 0x64: ChipSet.prototype.in8042Status,\n 0x70: ChipSet.prototype.inCMOSAddr,\n 0x71: ChipSet.prototype.inCMOSData,\n 0x80: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageSpare(7, port, addrFrom); },\n 0x84: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageSpare(0, port, addrFrom); },\n 0x85: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageSpare(1, port, addrFrom); },\n 0x86: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageSpare(2, port, addrFrom); },\n 0x88: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageSpare(3, port, addrFrom); },\n 0x89: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageReg(ChipSet.DMA1.INDEX, 2, port, addrFrom); },\n 0x8A: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageReg(ChipSet.DMA1.INDEX, 3, port, addrFrom); },\n 0x8B: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageReg(ChipSet.DMA1.INDEX, 1, port, addrFrom); },\n 0x8C: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageSpare(4, port, addrFrom); },\n 0x8D: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageSpare(5, port, addrFrom); },\n 0x8E: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageSpare(6, port, addrFrom); },\n 0x8F: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageReg(ChipSet.DMA1.INDEX, 0, port, addrFrom); },\n 0xA0: /** @this {ChipSet} */ function(port, addrFrom) { return this.inPICLo(ChipSet.PIC1.INDEX, addrFrom); },\n 0xA1: /** @this {ChipSet} */ function(port, addrFrom) { return this.inPICHi(ChipSet.PIC1.INDEX, addrFrom); },\n 0xC0: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelAddr(ChipSet.DMA1.INDEX, 0, port, addrFrom); },\n 0xC2: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelCount(ChipSet.DMA1.INDEX, 0, port, addrFrom); },\n 0xC4: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelAddr(ChipSet.DMA1.INDEX, 1, port, addrFrom); },\n 0xC6: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelCount(ChipSet.DMA1.INDEX, 1, port, addrFrom); },\n 0xC8: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelAddr(ChipSet.DMA1.INDEX, 2, port, addrFrom); },\n 0xCA: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelCount(ChipSet.DMA1.INDEX, 2, port, addrFrom); },\n 0xCC: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelAddr(ChipSet.DMA1.INDEX, 3, port, addrFrom); },\n 0xCE: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelCount(ChipSet.DMA1.INDEX, 3, port, addrFrom); },\n 0xD0: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAStatus(ChipSet.DMA1.INDEX, port, addrFrom); },\n 0xDA: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMATemp(ChipSet.DMA1.INDEX, port, addrFrom); }\n};\n\nChipSet.aPortInput6300 = {\n 0x60: ChipSet.prototype.in8041Kbd,\n 0x61: ChipSet.prototype.in8041Ctrl,\n 0x64: ChipSet.prototype.in8041Status,\n 0x66: /** @this {ChipSet} */ function(port, addrFrom) { return this.in6300DIPSwitches(0, port, addrFrom); },\n 0x67: /** @this {ChipSet} */ function(port, addrFrom) { return this.in6300DIPSwitches(1, port, addrFrom); }\n};\n\nif (DESKPRO386) {\n ChipSet.aPortInputDeskPro386 = {\n 0x48: /** @this {ChipSet} */ function(port, addrFrom) { return this.inTimer(ChipSet.PIT1.INDEX, ChipSet.PIT1.TIMER3, port, addrFrom); },\n 0x49: /** @this {ChipSet} */ function(port, addrFrom) { return this.inTimer(ChipSet.PIT1.INDEX, ChipSet.PIT1.TIMER4, port, addrFrom); },\n 0x4A: /** @this {ChipSet} */ function(port, addrFrom) { return this.inTimer(ChipSet.PIT1.INDEX, ChipSet.PIT1.TIMER5, port, addrFrom); },\n 0x4B: /** @this {ChipSet} */ function(port, addrFrom) { return this.inTimerCtrl(ChipSet.PIT1.INDEX, port, addrFrom); }\n };\n}\n\n/*\n * Port output notification tables, starting with the one that's common to all models (aPortOutput)\n */\nChipSet.aPortOutput = {\n 0x20: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outPICLo(ChipSet.PIC0.INDEX, bOut, addrFrom); },\n 0x21: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outPICHi(ChipSet.PIC0.INDEX, bOut, addrFrom); },\n 0x40: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outTimer(ChipSet.PIT0.INDEX, ChipSet.PIT0.TIMER0, port, bOut, addrFrom); },\n 0x41: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outTimer(ChipSet.PIT0.INDEX, ChipSet.PIT0.TIMER1, port, bOut, addrFrom); },\n 0x42: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outTimer(ChipSet.PIT0.INDEX, ChipSet.PIT0.TIMER2, port, bOut, addrFrom); },\n 0x43: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outTimerCtrl(ChipSet.PIT0.INDEX, port, bOut, addrFrom); },\n};\n\nChipSet.aPortOutput4860 = {\n 0x10: ChipSet.prototype.outMFGTest, // a manufacturing test port that we don't really care about \n 0x60: ChipSet.prototype.outPPIA,\n 0x61: ChipSet.prototype.outPPIB,\n 0x62: ChipSet.prototype.outPPIC,\n 0x63: ChipSet.prototype.outPPICtrl,\n 0xA0: ChipSet.prototype.outNMI\n};\n\nChipSet.aPortOutput5150 = {\n 0x60: ChipSet.prototype.outPPIA,\n 0x61: ChipSet.prototype.outPPIB,\n 0x62: ChipSet.prototype.outPPIC,\n 0x63: ChipSet.prototype.outPPICtrl,\n 0xA0: ChipSet.prototype.outNMI\n};\n\nChipSet.aPortOutput5xxx = {\n 0x00: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelAddr(ChipSet.DMA0.INDEX, 0, port, bOut, addrFrom); },\n 0x01: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelCount(ChipSet.DMA0.INDEX, 0, port, bOut, addrFrom); },\n 0x02: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelAddr(ChipSet.DMA0.INDEX, 1, port, bOut, addrFrom); },\n 0x03: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelCount(ChipSet.DMA0.INDEX, 1, port, bOut, addrFrom); },\n 0x04: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelAddr(ChipSet.DMA0.INDEX, 2, port, bOut, addrFrom); },\n 0x05: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelCount(ChipSet.DMA0.INDEX, 2, port, bOut, addrFrom); },\n 0x06: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelAddr(ChipSet.DMA0.INDEX, 3, port, bOut, addrFrom); },\n 0x07: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelCount(ChipSet.DMA0.INDEX, 3, port, bOut, addrFrom); },\n 0x08: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMACmd(ChipSet.DMA0.INDEX, port, bOut, addrFrom); },\n 0x09: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAReq(ChipSet.DMA0.INDEX, port, bOut, addrFrom); },\n 0x0A: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAMask(ChipSet.DMA0.INDEX, port, bOut, addrFrom); },\n 0x0B: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAMode(ChipSet.DMA0.INDEX, port, bOut, addrFrom); },\n 0x0C: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAResetFF(ChipSet.DMA0.INDEX, port, bOut, addrFrom); },\n 0x0D: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAMasterClear(ChipSet.DMA0.INDEX, port, bOut, addrFrom); },\n 0x81: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageReg(ChipSet.DMA0.INDEX, 2, port, bOut, addrFrom); },\n 0x82: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageReg(ChipSet.DMA0.INDEX, 3, port, bOut, addrFrom); },\n 0x83: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageReg(ChipSet.DMA0.INDEX, 1, port, bOut, addrFrom); },\n 0x87: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageReg(ChipSet.DMA0.INDEX, 0, port, bOut, addrFrom); }\n};\n\nChipSet.aPortOutput5170 = {\n 0x60: ChipSet.prototype.out8042InBuffData,\n 0x61: ChipSet.prototype.out8042RWReg,\n 0x64: ChipSet.prototype.out8042InBuffCmd,\n 0x70: ChipSet.prototype.outCMOSAddr,\n 0x71: ChipSet.prototype.outCMOSData,\n 0x80: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageSpare(7, port, bOut, addrFrom); },\n 0x84: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageSpare(0, port, bOut, addrFrom); },\n 0x85: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageSpare(1, port, bOut, addrFrom); },\n 0x86: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageSpare(2, port, bOut, addrFrom); },\n 0x88: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageSpare(3, port, bOut, addrFrom); },\n 0x89: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageReg(ChipSet.DMA1.INDEX, 2, port, bOut, addrFrom); },\n 0x8A: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageReg(ChipSet.DMA1.INDEX, 3, port, bOut, addrFrom); },\n 0x8B: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageReg(ChipSet.DMA1.INDEX, 1, port, bOut, addrFrom); },\n 0x8C: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageSpare(4, port, bOut, addrFrom); },\n 0x8D: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageSpare(5, port, bOut, addrFrom); },\n 0x8E: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageSpare(6, port, bOut, addrFrom); },\n 0x8F: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageReg(ChipSet.DMA1.INDEX, 0, port, bOut, addrFrom); },\n 0xA0: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outPICLo(ChipSet.PIC1.INDEX, bOut, addrFrom); },\n 0xA1: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outPICHi(ChipSet.PIC1.INDEX, bOut, addrFrom); },\n 0xC0: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelAddr(ChipSet.DMA1.INDEX, 0, port, bOut, addrFrom); },\n 0xC2: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelCount(ChipSet.DMA1.INDEX, 0, port, bOut, addrFrom); },\n 0xC4: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelAddr(ChipSet.DMA1.INDEX, 1, port, bOut, addrFrom); },\n 0xC6: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelCount(ChipSet.DMA1.INDEX, 1, port, bOut, addrFrom); },\n 0xC8: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelAddr(ChipSet.DMA1.INDEX, 2, port, bOut, addrFrom); },\n 0xCA: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelCount(ChipSet.DMA1.INDEX, 2, port, bOut, addrFrom); },\n 0xCC: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelAddr(ChipSet.DMA1.INDEX, 3, port, bOut, addrFrom); },\n 0xCE: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelCount(ChipSet.DMA1.INDEX, 3, port, bOut, addrFrom); },\n 0xD0: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMACmd(ChipSet.DMA1.INDEX, port, bOut, addrFrom); },\n 0xD2: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAReq(ChipSet.DMA1.INDEX, port, bOut, addrFrom); },\n 0xD4: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAMask(ChipSet.DMA1.INDEX, port, bOut, addrFrom); },\n 0xD6: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAMode(ChipSet.DMA1.INDEX, port, bOut, addrFrom); },\n 0xD8: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAResetFF(ChipSet.DMA1.INDEX, port, bOut, addrFrom); },\n 0xDA: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAMasterClear(ChipSet.DMA1.INDEX, port, bOut, addrFrom); },\n 0xF0: ChipSet.prototype.outFPUClear,\n 0xF1: ChipSet.prototype.outFPUReset\n};\n\nChipSet.aPortOutput6300 = {\n 0x60: ChipSet.prototype.out8041Kbd,\n 0x61: ChipSet.prototype.out8041Ctrl,\n 0xA0: ChipSet.prototype.outNMI\n};\n\nif (DESKPRO386) {\n ChipSet.aPortOutputDeskPro386 = {\n 0x48: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outTimer(ChipSet.PIT1.INDEX, ChipSet.PIT1.TIMER3, port, bOut, addrFrom); },\n 0x49: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outTimer(ChipSet.PIT1.INDEX, ChipSet.PIT1.TIMER4, port, bOut, addrFrom); },\n 0x4A: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outTimer(ChipSet.PIT1.INDEX, ChipSet.PIT1.TIMER5, port, bOut, addrFrom); },\n 0x4B: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outTimerCtrl(ChipSet.PIT1.INDEX, port, bOut, addrFrom); }\n };\n}\n\n/*\n * Initialize every ChipSet module on the page.\n */\nWeb.onInit(ChipSet.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/rom.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * class ROMX86\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass ROMX86 extends Component {\n /**\n * ROMX86(parmsROM)\n *\n * The ROMX86 component expects the following (parmsROM) properties:\n *\n * addr: physical address of ROM\n * size: amount of ROM, in bytes\n * alias: physical alias address (null if none)\n * file: name of ROM data file\n * notify: ID of a component to notify once the ROM is in place (optional)\n *\n * NOTE: The ROM data will not be copied into place until the Bus is ready (see initBus()) AND the\n * ROM data file has finished loading (see doneLoad()).\n *\n * Also, while the size parameter may seem redundant, I consider it useful to confirm that the ROM you received\n * is the ROM you expected.\n *\n * @this {ROMX86}\n * @param {Object} parmsROM\n */\n constructor(parmsROM)\n {\n super(\"ROMX86\", parmsROM);\n\n this.abROM = null;\n this.addrROM = parmsROM['addr'];\n this.sizeROM = parmsROM['size'];\n\n /*\n * The new 'alias' property can now be EITHER a single physical address (like 'addr') OR an array of\n * physical addresses; eg:\n *\n * [0xf0000,0xffff0000,0xffff8000]\n *\n * We could have overloaded 'addr' to accomplish the same thing, but I think it's better to have any\n * aliased locations listed under a separate property.\n *\n * Most ROMs are not aliased, in which case the 'alias' property should have the default value of null.\n */\n this.addrAlias = parmsROM['alias'];\n\n /*\n * The 'notify' property can now (as of v1.18.2) contain an array of parameters that the notified\n * component (typically Video) may use as it sees fit. For example, the Video component is generally\n * interested in knowing the offsets of specific font tables within the ROM, which used to be hard-coded\n * when all we supported were a few specific IBM video cards, but that's no longer feasible as we move\n * beyond the original handful of IBM cards.\n *\n * It's up to the notified component to decide how to interpret the parameters it receives, if any.\n */\n this.idNotify = parmsROM['notify'];\n this.aNotifyParms = null;\n if (this.idNotify) {\n var i = this.idNotify.indexOf('[');\n if (i > 0) {\n try {\n this.aNotifyParms = eval(this.idNotify.substr(i));\n } catch (e) {}\n this.idNotify = this.idNotify.substr(0, i);\n }\n }\n\n this.sFileURL = this.sFilePath = parmsROM['file'];\n\n if (this.sFileURL) {\n var sFileName = Str.getBaseName(this.sFileURL);\n if (DEBUG) this.log('load(\"' + this.sFileURL + '\")');\n /*\n * If the selected ROM file has a \".json\" extension, then we assume it's pre-converted\n * JSON-encoded ROM data, so we load it as-is; ditto for ROM files with a \".hex\" extension.\n * Otherwise, we ask our server-side ROM converter to return the file in a JSON-compatible format.\n */\n var sFileExt = Str.getExtension(sFileName);\n if (sFileExt != DumpAPI.FORMAT.JSON && sFileExt != DumpAPI.FORMAT.HEX) {\n this.sFileURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFilePath + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES + '&' + DumpAPI.QUERY.DECIMAL + '=true';\n }\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {ROMX86}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n if (this.sFileURL) {\n var rom = this;\n var sProgress = \"Loading \" + this.sFileURL + \"...\";\n Web.getResource(this.sFileURL, null, true, function doneROMLoad(sURL, sResponse, nErrorCode) {\n rom.doneLoad(sURL, sResponse, nErrorCode);\n }, function(nState) {\n rom.println(sProgress, Component.PRINT.PROGRESS);\n });\n }\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {ROMX86}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (this.aSymbols) {\n if (this.dbg) {\n this.dbg.addSymbols(this.id, 0, this.addrROM >>> 4, 0, this.addrROM, this.sizeROM, this.aSymbols);\n }\n /*\n * Our only role in the handling of symbols is to hand them off to the Debugger at our\n * first opportunity. Now that we've done that, our copy of the symbols, if any, are toast.\n */\n delete this.aSymbols;\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * Since we have nothing to do on powerDown(), and no state to return, we could simply omit\n * this function. But it doesn't hurt anything, and maybe we'll use our state to save something\n * useful down the road, like user-defined symbols (ie, symbols that the Debugger may have\n * created, above and beyond those symbols we automatically loaded, if any, along with the ROM).\n *\n * @this {ROMX86}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return true;\n }\n\n /**\n * doneLoad(sURL, sROMData, nErrorCode)\n *\n * @this {ROMX86}\n * @param {string} sURL\n * @param {string} sROMData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n doneLoad(sURL, sROMData, nErrorCode)\n {\n if (nErrorCode) {\n this.notice(\"Unable to load system ROM (error \" + nErrorCode + \": \" + sURL + \")\", nErrorCode < 0);\n return;\n }\n\n Component.addMachineResource(this.idMachine, sURL, sROMData);\n\n if (sROMData.charAt(0) == \"[\" || sROMData.charAt(0) == \"{\") {\n try {\n /*\n * The most likely source of any exception will be here: parsing the JSON-encoded ROM data.\n */\n var rom = eval(\"(\" + sROMData + \")\");\n var ab = rom['bytes'];\n /*\n * Resource 'longs' should always be 32-bit DWORD values, whereas 'data' bit lengths\n * will vary according to the machine architecture for which the resource was designed.\n */\n var adw = rom['longs'] || rom['data'];\n\n if (ab) {\n this.abROM = ab;\n }\n else if (adw) {\n /*\n * Convert all the DWORDs into BYTEs, so that subsequent code only has to deal with abROM.\n */\n this.abROM = new Array(adw.length * 4);\n for (var idw = 0, ib = 0; idw < adw.length; idw++) {\n this.abROM[ib++] = adw[idw] & 0xff;\n this.abROM[ib++] = (adw[idw] >> 8) & 0xff;\n this.abROM[ib++] = (adw[idw] >> 16) & 0xff;\n this.abROM[ib++] = (adw[idw] >> 24) & 0xff;\n }\n }\n else {\n this.abROM = rom;\n }\n\n this.aSymbols = rom['symbols'];\n\n if (!this.abROM.length) {\n Component.error(\"Empty ROM: \" + sURL);\n return;\n }\n else if (this.abROM.length == 1) {\n Component.error(this.abROM[0]);\n return;\n }\n } catch (e) {\n this.notice(\"ROM data error: \" + e.message);\n return;\n }\n }\n else {\n /*\n * Parse the ROM data manually; we assume it's in \"simplified\" hex form (a series of hex byte-values\n * separated by whitespace).\n */\n var sHexData = sROMData.replace(/\\n/gm, \" \").replace(/ +$/, \"\");\n var asHexData = sHexData.split(\" \");\n this.abROM = new Array(asHexData.length);\n for (var i = 0; i < asHexData.length; i++) {\n this.abROM[i] = Str.parseInt(asHexData[i], 16);\n }\n }\n this.copyROM();\n }\n\n /**\n * copyROM()\n *\n * This function is called by both initBus() and doneLoad(), but it cannot copy the the ROM data into place\n * until after initBus() has received the Bus component AND doneLoad() has received the abROM data. When both\n * those criteria are satisfied, the component becomes \"ready\".\n *\n * @this {ROMX86}\n */\n copyROM()\n {\n if (!this.isReady()) {\n if (!this.sFilePath) {\n this.setReady();\n }\n else if (this.abROM && this.bus) {\n /*\n * If no explicit size was specified, then use whatever the actual size is.\n */\n if (!this.sizeROM) {\n this.sizeROM = this.abROM.length;\n }\n if (this.abROM.length != this.sizeROM) {\n /*\n * Note that setError() sets the component's fError flag, which in turn prevents setReady() from\n * marking the component ready. TODO: Revisit this decision. On the one hand, it sounds like a\n * good idea to stop the machine in its tracks whenever a setError() occurs, but there may also be\n * times when we'd like to forge ahead anyway.\n */\n this.setError(\"ROM size (\" + Str.toHexLong(this.abROM.length) + \") does not match specified size (\" + Str.toHexLong(this.sizeROM) + \")\");\n }\n else if (this.addROM(this.addrROM)) {\n\n var aliases = [];\n if (typeof this.addrAlias == \"number\") {\n aliases.push(this.addrAlias);\n } else if (this.addrAlias != null && this.addrAlias.length) {\n aliases = this.addrAlias;\n }\n for (var i = 0; i < aliases.length; i++) {\n this.cloneROM(aliases[i]);\n }\n /*\n * If there's a component we should notify, notify it now, and give it the internal byte array, so that\n * it doesn't have to ask the CPU for the data. Currently, the only component that uses this notification\n * option is the Video component, and only when the associated ROM contains font data that it needs.\n */\n if (this.idNotify) {\n var component = Component.getComponentByID(this.idNotify, this.id);\n if (component) {\n component.onROMLoad(this.abROM, this.aNotifyParms);\n } else {\n this.notice(\"Unable to find component: \" + this.idNotify);\n }\n }\n /*\n * We used to hang onto the original ROM data so that we could restore any bytes the CPU overwrote,\n * using memory write-notification handlers, but with the introduction of read-only memory blocks, that's\n * no longer necessary.\n *\n * TODO: Consider an option to retain the ROM data, and give the user some way of restoring ROMs.\n * That may be useful for \"resumable\" machines that save/restore all dirty block of memory, regardless\n * whether they're ROM or RAM. However, the only way to modify a machine's ROM is with the Debugger,\n * and Debugger users should know better.\n */\n delete this.abROM;\n }\n this.setReady();\n }\n }\n }\n\n /**\n * addROM(addr)\n *\n * @this {ROMX86}\n * @param {number} addr\n * @return {boolean}\n */\n addROM(addr)\n {\n if (this.bus.addMemory(addr, this.sizeROM, Memory.TYPE.ROM)) {\n if (DEBUG) this.log(\"addROM(): copying ROM to \" + Str.toHexLong(addr) + \" (\" + Str.toHexLong(this.abROM.length) + \" bytes)\");\n var bto = null;\n for (var off = 0; off < this.abROM.length; off++) {\n this.bus.setByteDirect(addr + off, this.abROM[off]);\n if (BACKTRACK) {\n bto = this.bus.addBackTrackObject(this, bto, off);\n this.bus.writeBackTrackObject(addr + off, bto, off);\n }\n }\n return true;\n }\n /*\n * We don't need to report an error here, because addMemory() already takes care of that.\n */\n return false;\n }\n\n /**\n * cloneROM(addr)\n *\n * For ROMs with one or more alias addresses, we used to call addROM() for each address. However,\n * that obviously wasted memory, since each alias was an independent copy, and if you used the\n * Debugger to edit the ROM in one location, the changes would not appear in the other location(s).\n *\n * Now that the Bus component provides low-level getMemoryBlocks() and setMemoryBlocks() methods\n * to manually get and set the blocks of any memory range, it is now possible to create true aliases.\n *\n * @this {ROMX86}\n * @param {number} addr\n */\n cloneROM(addr)\n {\n var aBlocks = this.bus.getMemoryBlocks(this.addrROM, this.sizeROM);\n this.bus.setMemoryBlocks(addr, this.sizeROM, aBlocks);\n }\n\n /**\n * ROMX86.init()\n *\n * This function operates on every HTML element of class \"rom\", extracting the\n * JSON-encoded parameters for the ROM constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a ROM component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeROM = Component.getElementsByClass(document, PCX86.APPCLASS, \"rom\");\n for (var iROM = 0; iROM < aeROM.length; iROM++) {\n var eROM = aeROM[iROM];\n var parmsROM = Component.getComponentParms(eROM);\n var rom = new ROMX86(parmsROM);\n Component.bindComponentControls(rom, eROM, PCX86.APPCLASS);\n }\n }\n}\n\n/*\n * ROM BIOS Data Area (RBDA) definitions, in physical address form, using the same CAPITALIZED names\n * found in the original IBM PC ROM BIOS listing.\n */\nROMX86.BIOS = {\n RS232_BASE: 0x400, // ADDRESSES OF RS232 ADAPTERS (4 words)\n PRINTER_BASE: 0x408, // ADDRESSES OF PRINTERS (4 words)\n EQUIP_FLAG: { // INSTALLED HARDWARE (word)\n ADDR: 0x410,\n NUM_PRINT: 0xC000, // NUMBER OF PRINTERS ATTACHED\n GAME_CTRL: 0x1000, // GAME I/O ATTACHED\n NUM_RS232: 0x0E00, // NUMBER OF RS232 CARDS ATTACHED\n NUM_DRIVES: 0x00C0, // NUMBER OF DISKETTE DRIVES (00=1, 01=2, 10=3, 11=4) ONLY IF IPL_DRIVE SET\n VIDEO_MODE: 0x0030, // INITIAL VIDEO MODE (00=UNUSED, 01=40X25 COLOR, 10=80X25 COLOR, 11=80X25 MONO)\n RAM_SIZE: 0x000C, // PLANAR RAM SIZE (00=16K,01=32K,10=48K,11=64K)\n IPL_DRIVE: 0x0001 // IPL (Initial Program Load) FROM DISKETTE (ie, diskette drives exist)\n },\n MFG_TEST: 0x412, // INITIALIZATION FLAG (byte)\n MEMORY_SIZE: 0x413, // MEMORY SIZE IN K BYTES (word)\n IO_RAM_SIZE: 0x415, // PC: MEMORY IN I/O CHANNEL (word)\n MFG_ERR_FLAG: 0x415, // PC AT: SCRATCHPAD FOR MANUFACTURING ERROR CODES (2 bytes)\n COMPAQ_PREV_SC: 0x415, // COMPAQ DESKPRO 386: PREVIOUS SCAN CODE (byte)\n COMPAQ_KEYCLICK:0x416, // COMPAQ DESKPRO 386: KEYCLICK LOUDNESS (byte)\n /*\n * KEYBOARD DATA AREAS\n */\n KB_FLAG: { // FIRST BYTE OF KEYBOARD STATUS (byte)\n ADDR: 0x417, //\n INS_STATE: 0x80, // INSERT STATE IS ACTIVE\n CAPS_STATE: 0x40, // CAPS LOCK STATE HAS BEEN TOGGLED\n NUM_STATE: 0x20, // NUM LOCK STATE HAS BEEN TOGGLED\n SCROLL_STATE: 0x10, // SCROLL LOCK STATE HAS BEEN TOGGLED\n ALT_SHIFT: 0x08, // ALTERNATE SHIFT KEY DEPRESSED\n CTL_SHIFT: 0x04, // CONTROL SHIFT KEY DEPRESSED\n LEFT_SHIFT: 0x02, // LEFT SHIFT KEY DEPRESSED\n RIGHT_SHIFT: 0x01 // RIGHT SHIFT KEY DEPRESSED\n },\n KB_FLAG_1: { // SECOND BYTE OF KEYBOARD STATUS (byte)\n ADDR: 0x418, //\n INS_SHIFT: 0x80, // INSERT KEY IS DEPRESSED\n CAPS_SHIFT: 0x40, // CAPS LOCK KEY IS DEPRESSED\n NUM_SHIFT: 0x20, // NUM LOCK KEY IS DEPRESSED\n SCROLL_SHIFT: 0x10, // SCROLL LOCK KEY IS DEPRESSED\n HOLD_STATE: 0x08 // SUSPEND KEY HAS BEEN TOGGLED\n },\n ALT_INPUT: 0x419, // STORAGE FOR ALTERNATE KEYPAD ENTRY (byte)\n BUFFER_HEAD: 0x41A, // POINTER TO HEAD OF KEYBOARD BUFFER (word)\n BUFFER_TAIL: 0x41C, // POINTER TO TAIL OF KEYBOARD BUFFER (word)\n KB_BUFFER: 0x41E, // ROOM FOR 15 ENTRIES (16 words)\n KB_BUFFER_END: 0x43E, // HEAD = TAIL INDICATES THAT THE BUFFER IS EMPTY\n /*\n * DISKETTE DATA AREAS\n */\n SEEK_STATUS: { // DRIVE RECALIBRATION STATUS (byte)\n ADDR: 0x43E, //\n // BIT 3-0 = DRIVE 3-0 NEEDS RECAL BEFORE\n // NEXT SEEK IF BIT IS = 0\n INT_FLAG: 0x80, // INTERRUPT OCCURRENCE FLAG\n },\n MOTOR_STATUS: 0x43F, // MOTOR STATUS (byte)\n // BIT 3-0 = DRIVE 3-0 IS CURRENTLY RUNNING\n // BIT 7 = CURRENT OPERATION IS A WRITE, REQUIRES DELAY\n MOTOR_COUNT: 0x440, // TIME OUT COUNTER FOR DRIVE TURN OFF\n // 37 == TWO SECONDS OF COUNTS FOR MOTOR TURN OFF\n DISKETTE_STATUS: { // SINGLE BYTE OF RETURN CODE INFO FOR STATUS\n ADDR: 0x441,\n TIME_OUT: 0x80, // ATTACHMENT FAILED TO RESPOND\n BAD_SEEK: 0x40, // SEEK OPERATION FAILED\n BAD_NEC: 0x20, // NEC CONTROLLER HAS FAILED\n BAD_CRC: 0x10, // BAD CRC ON DISKETTE READ\n DMA_BOUNDARY: 0x09, // ATTEMPT TO DMA ACROSS 64K BOUNDARY\n BAD_DMA: 0x08, // DMA OVERRUN ON OPERATION\n RECORD_NOT_FND: 0x04, // REQUESTED SECTOR NOT FOUND\n WRITE_PROTECT: 0x03, // WRITE ATTEMPTED ON WRITE PROT DISK\n BAD_ADDR_MARK: 0x02, // ADDRESS MARK NOT FOUND\n BAD_CMD: 0x01 // BAD COMMAND PASSED TO DISKETTE I/O\n },\n NEC_STATUS: 0x442, // STATUS BYTES FROM NEC (7 bytes)\n /*\n * VIDEO DISPLAY DATA AREA\n */\n CRT_MODE: 0x449, // CURRENT CRT MODE (byte)\n CRT_COLS: 0x44A, // NUMBER OF COLUMNS ON SCREEN (word)\n CRT_LEN: 0x44C, // LENGTH OF REGEN IN BYTES (word)\n CRT_START: 0x44E, // STARTING ADDRESS IN REGEN BUFFER (word)\n CURSOR_POSN: 0x450, // CURSOR FOR EACH OF UP TO 8 PAGES (8 words)\n CURSOR_MODE: 0x460, // CURRENT CURSOR MODE SETTING (word)\n ACTIVE_PAGE: 0x462, // CURRENT PAGE BEING DISPLAYED (byte)\n ADDR_6845: 0x463, // BASE ADDRESS FOR ACTIVE DISPLAY CARD (word)\n CRT_MODE_SET: 0x465, // CURRENT SETTING OF THE 3X8 REGISTER (byte)\n CRT_PALLETTE: 0x466, // CURRENT PALLETTE SETTING COLOR CARD (byte)\n /*\n * CASSETTE DATA AREA\n */\n EDGE_CNT: 0x467, // PC: TIME COUNT AT DATA EDGE (word)\n CRC_REG: 0x469, // PC: CRC REGISTER (word)\n LAST_VAL: 0x46B, // PC: LAST INPUT VALUE (byte)\n IO_ROM_INIT: 0x467, // PC AT: POINTER TO ROM INITIALIZATION ROUTINE\n IO_ROM_SEG: 0x469, // PC AT: POINTER TO I/O ROM SEGMENT\n INTR_FLAG: 0x46B, // PC AT: FLAG INDICATING AN INTERRUPT HAPPENED\n /*\n * TIMER DATA AREA\n */\n TIMER_LOW: 0x46C, // LOW WORD OF TIMER COUNT (word)\n TIMER_HIGH: 0x46E, // HIGH WORD OF TIMER COUNT (word)\n TIMER_OFL: 0x470, // TIMER HAS ROLLED OVER SINCE LAST READ (byte)\n /*\n * SYSTEM DATA AREA\n */\n BIOS_BREAK: 0x471, // BIT 7 = 1 IF BREAK KEY HAS BEEN DEPRESSED (byte)\n /*\n * RESET_FLAG is the traditional end of the RBDA, as originally defined by the IBM PC\n */\n RESET_FLAG: {\n ADDR: 0x472, // SET TO 0x1234 IF KEYBOARD RESET UNDERWAY (word)\n WARMBOOT: 0x1234 // this value indicates a \"warm boot\", bypassing memory tests\n },\n /*\n * FIXED DISK DATA AREAS\n */\n DISK_STATUS1: 0x474, // PC AT: FIXED DISK STATUS (byte)\n HF_NUM: 0x475, // PC AT: COUNT OF FIXED DISK DRIVES (byte)\n CONTROL_BYTE: 0x476, // PC AT: HEAD CONTROL BYTE (byte)\n PORT_OFF: 0x477, // PC AT: RESERVED (PORT OFFSET) (byte)\n /*\n * TIME-OUT VARIABLES\n */\n PRINT_TIM_OUT: 0x478, // PC AT: TIME OUT COUNTERS FOR PRINTER RESPONSE (4 bytes)\n RS232_TIM_OUT: 0x47C, // PC AT: TIME OUT COUNTERS FOR RS232 RESPONSE (4 bytes)\n /*\n * ADDITIONAL KEYBOARD DATA AREA\n */\n BUFFER_START: 0x480, // PC AT: OFFSET OF KEYBOARD BUFFER START WITHIN SEGMENT 40H\n BUFFER_END: 0x482, // PC AT: OFFSET OF END OF BUFFER\n /*\n * EGA/PGA DISPLAY WORK AREA\n */\n ROWS: 0x484, // PC AT: ROWS ON THE ACTIVE SCREEN (LESS 1) (byte)\n POINTS: 0x485, // PC AT: BYTES PER CHARACTER (word)\n INFO: 0x487, // PC AT: MODE OPTIONS (byte)\n /*\n * INFO BITS:\n * \n * 0x80: HIGH BIT OF MODE SET, CLEAR/NOT CLEAR REGEN\n * 0x60: 256K OF VRAM\n * 0x40: 192K OF VRAM\n * 0x20: 128K OF VRAM\n * 0x10: RESERVED\n * 0x08: EGA ACTIVE MONITOR (0), EGA NOT ACTIVE (1)\n * 0x04: WAIT FOR DISPLAY ENABLE (1)\n * 0x02: EGA HAS A MONOCHROME ATTACHED\n * 0x01: SET C_TYPE EMULATE ACTIVE (0)\n */\n INFO_3: 0x488, // PC AT: FEATURE BIT SWITCHES (1 byte, plus 2 reserved bytes)\n /*\n * ADDITIONAL MEDIA DATA\n */\n LASTRATE: 0x48B, // PC AT: LAST DISKETTE DATA RATE SELECTED (byte)\n HF_STATUS: 0x48C, // PC AT: STATUS REGISTER (byte)\n HF_ERROR: 0x48D, // PC AT: ERROR REGISTER (byte)\n HF_INT_FLAG: 0x48E, // PC AT: FIXED DISK INTERRUPT FLAG (byte)\n HF_CNTRL: 0x48F, // PC AT: COMBO FIXED DISK/DISKETTE CARD BIT 0=1 (byte)\n DSK_STATE: 0x490, // PC AT: DRIVE 0/1 MEDIA/OPERATION STATES (4 bytes)\n DSK_TRK: 0x494, // PC AT: DRIVE 0/1 PRESENT CYLINDER (2 bytes)\n /*\n * ADDITIONAL KEYBOARD FLAGS\n */\n KB_FLAG_3: {\n ADDR: 0x496, // PC AT: KEYBOARD MODE STATE AND TYPE FLAGS (byte)\n LC_E1: 0b00000001, // LAST CODE WAS THE E1 HIDDEN CODE\n LC_E0: 0b00000010, // LAST CODE WAS THE E0 HIDDEN CODE\n R_CTL_SHIFT: 0b00000100, // RIGHT CTL KEY DOWN\n R_ALT_SHIFT: 0b00001000, // RIGHT ALT KEY DOWN\n GRAPH_ON: 0b00001000, // ALT GRAPHICS KEY DOWN (WT ONLY)\n KBX: 0b00010000, // ENHANCED KEYBOARD INSTALLED\n SET_NUM_LK: 0b00100000, // FORCE NUM LOCK IF READ ID AND KBX\n LC_AB: 0b01000000, // LAST CHARACTER WAS FIRST ID CHARACTER\n RD_ID: 0b10000000 // DOING A READ ID (MUST BE BIT0)\n },\n KB_FLAG_2: {\n ADDR: 0x497, // PC AT: KEYBOARD LED FLAGS (byte)\n KB_LEDS: 0b00000111, // KEYBOARD LED STATE BITS\n SCROLL_LOCK: 0b00000001, // SCROLL LOCK INDICATOR\n NUM_LOCK: 0b00000010, // NUM LOCK INDICATOR\n CAPS_LOCK: 0b00000100, // CAPS LOCK INDICATOR\n KB_FA: 0b00010000, // ACKNOWLEDGMENT RECEIVED\n KB_FE: 0b00100000, // RESEND RECEIVED FLAG\n KB_PR_LED: 0b01000000, // MODE INDICATOR UPDATE\n KB_ERR: 0b10000000 // KEYBOARD TRANSMIT ERROR FLAG\n },\n /*\n * REAL TIME CLOCK DATA AREA\n */\n USER_FLAG: 0x498, // PC AT: OFFSET ADDRESS OF USERS WAIT FLAG (word)\n USER_FLAG_SEG: 0x49A, // PC AT: SEGMENT ADDRESS OF USER WAIT FLAG (word)\n RTC_LOW: 0x49C, // PC AT: LOW WORD OF USER WAIT FLAG (word)\n RTC_HIGH: 0x49E, // PC AT: HIGH WORD OF USER WAIT FLAG (word)\n RTC_WAIT_FLAG: 0x4A0, // PC AT: WAIT ACTIVE FLAG (01=BUSY, 80=POSTED, 00=POST ACKNOWLEDGED) (byte)\n /*\n * AREA FOR NETWORK ADAPTER\n */\n NET: 0x4A1, // PC AT: RESERVED FOR NETWORK ADAPTERS (7 bytes)\n /*\n * EGA/PGA PALETTE POINTER\n */\n SAVE_PTR: 0x4A8, // PC AT: POINTER TO EGA PARAMETER CONTROL BLOCK (2 words)\n /*\n * DATA AREA - PRINT SCREEN\n */\n STATUS_BYTE: 0x500 // PRINT SCREEN STATUS BYTE (00=READY/OK, 01=BUSY, FF=ERROR) (byte)\n};\n\n/*\n * NOTE: There's currently no need for this component to have a reset() function, since\n * once the ROM data is loaded, it can't be changed, so there's nothing to reinitialize.\n *\n * OK, well, I take that back, because the Debugger, if installed, has the ability to modify\n * ROM contents, so in that case, having a reset() function that restores the original ROM data\n * might be useful; then again, it might not, depending on what you're trying to debug.\n *\n * If we do add reset(), then we'll want to change copyROM() to hang onto the original\n * ROM data; currently, we release it after copying it into the read-only memory allocated\n * via bus.addMemory().\n */\n\n/*\n * Initialize all the ROM modules on the page.\n */\nWeb.onInit(ROMX86.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/ram.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * class RAM\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass RAM extends Component {\n /**\n * RAM(parmsRAM)\n *\n * The RAM component expects the following (parmsRAM) properties:\n *\n * addr: starting physical address of RAM (default is 0)\n * size: amount of RAM, in bytes (default is 0, which means defer to motherboard switch settings)\n * test: true (default) means don't interfere with any BIOS memory tests, false means \"fake a warm boot\"\n *\n * NOTE: We make a note of the specified size, but no memory is initially allocated for the RAM until the\n * Computer component calls powerUp().\n *\n * @this {RAM}\n * @param {Object} parmsRAM\n */\n constructor(parmsRAM)\n {\n super(\"RAM\", parmsRAM);\n\n this.addrRAM = parmsRAM['addr'];\n this.sizeRAM = parmsRAM['size'];\n this.fTestRAM = parmsRAM['test'];\n this.fInstalled = (!!this.sizeRAM); // 0 is the default value for 'size' when none is specified\n this.fAllocated = false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {RAM}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.chipset = cmp.getMachineComponent(\"ChipSet\");\n this.setReady();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {RAM}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n /*\n * The Computer powers up the CPU last, at which point CPUX86 state is restored,\n * which includes the Bus state, and since we use the Bus to allocate all our memory,\n * memory contents are already restored for us, so we don't need the usual restore\n * logic. We just need to call reset(), to allocate memory for the RAM.\n *\n * The only exception is when there's a custom Memory controller (eg, CompaqController).\n */\n this.reset();\n if (data && this.controller) {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {RAM}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n /*\n * The Computer powers down the CPU first, at which point CPUX86 state is saved,\n * which includes the Bus state, and since we use the Bus component to allocate all\n * our memory, memory contents are already saved for us, so we don't need the usual\n * save logic.\n *\n * The only exception is when there's a custom Memory controller (eg, CompaqController).\n */\n return (fSave && this.controller)? this.save() : true;\n }\n\n /**\n * reset()\n *\n * NOTE: When we were initialized, we were given an amount of INSTALLED memory (see sizeRAM above).\n * The ChipSet component, on the other hand, tells us how much SPECIFIED memory there is -- which,\n * like a real PC, may not match the amount of installed memory (due to either user error or perhaps\n * an attempt to prevent some portion of the installed memory from being used).\n *\n * However, since we're a virtual machine, we can defer allocation of RAM until we're able to query the\n * ChipSet component, and then allocate an amount of memory that matches the SPECIFIED memory, making\n * it easy to reconfigure the machine on the fly and prevent mismatches.\n *\n * But, we do that ONLY for the RAM instance configured with an addrRAM of 0x0000, and ONLY if that RAM\n * object was not given a specific size (see fInstalled). If there are other RAM objects in the system,\n * they must necessarily specify a non-conflicting, non-zero start address, in which case their sizeRAM\n * value will never be affected by the ChipSet settings.\n *\n * @this {RAM}\n */\n reset()\n {\n if (!this.addrRAM && !this.fInstalled && this.chipset) {\n var baseRAM = this.chipset.getDIPMemorySize() * 1024;\n if (this.sizeRAM && baseRAM != this.sizeRAM) {\n this.bus.removeMemory(this.addrRAM, this.sizeRAM);\n this.fAllocated = false;\n }\n this.sizeRAM = baseRAM;\n }\n if (!this.fAllocated && this.sizeRAM) {\n if (this.bus.addMemory(this.addrRAM, this.sizeRAM, Memory.TYPE.RAM)) {\n this.fAllocated = true;\n\n /*\n * NOTE: I'm specifying MAXDEBUG for status() messages because I'm not yet sure I want these\n * messages buried in the app, since they're seen only when a Control Panel is active. Another\n * and perhaps better alternative is to add \"comment\" attributes to the XML configuration file\n * for these components, which the Computer component will display as it \"powers up\" components.\n */\n if (MAXDEBUG && !this.addrRAM && this.fInstalled) this.status(\"specified size overrides SW1\");\n\n /*\n * Memory with an ID of \"ramCPQ\" is reserved for built-in memory located just below the 16Mb\n * boundary on COMPAQ DeskPro 386 machines.\n *\n * Technically, that memory is part of the first 1Mb of memory that also provides up to 640Kb\n * of conventional memory (ie, memory below 1Mb).\n *\n * However, PCx86 doesn't support individual memory allocations that (a) are discontiguous\n * or (b) dynamically change location. Components must simulate those features by performing\n * a separate allocation for each starting address, and removing/adding memory allocations\n * whenever their starting address changes.\n *\n * Therefore, a DeskPro 386's first 1Mb of physical memory is allocated by PCx86 in two pieces,\n * and the second piece must have an ID of \"ramCPQ\", triggering the additional allocation of\n * COMPAQ-specific memory-mapped registers.\n *\n * See CompaqController for more details.\n */\n if (DESKPRO386) {\n if (this.idComponent == \"ramCPQ\") {\n this.controller = new CompaqController(this);\n this.bus.addMemory(CompaqController.ADDR, 4, Memory.TYPE.CTRL, this.controller);\n }\n }\n }\n }\n if (this.fAllocated) {\n if (!this.addrRAM && !this.fTestRAM) {\n /*\n * HACK: Set the word at 40:72 in the ROM BIOS Data Area (RBDA) to 0x1234 to bypass the ROM BIOS\n * memory storage tests. See rom.js for all RBDA definitions.\n */\n if (MAXDEBUG) this.status(\"ROM BIOS memory test has been disabled\");\n this.bus.setShortDirect(ROMX86.BIOS.RESET_FLAG.ADDR, ROMX86.BIOS.RESET_FLAG.WARMBOOT);\n }\n /*\n * Don't add the \"ramCPQ\" memory to the CMOS total, because addCMOSMemory() will add it to the extended\n * memory total, which will just confuse the COMPAQ BIOS.\n */\n if (!DESKPRO386 || this.idComponent != \"ramCPQ\") {\n if (this.chipset) this.chipset.addCMOSMemory(this.addrRAM, this.sizeRAM);\n }\n } else {\n Component.error(\"No RAM allocated\");\n }\n }\n \n /**\n * save()\n *\n * This implements save support for the RAM component.\n *\n * @this {RAM}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n if (this.controller) state.set(0, this.controller.save());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the RAM component.\n *\n * @this {RAM}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n if (this.controller) return this.controller.restore(data[0]);\n return true;\n }\n\n /**\n * RAM.init()\n *\n * This function operates on every HTML element of class \"ram\", extracting the\n * JSON-encoded parameters for the RAM constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a RAM component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeRAM = Component.getElementsByClass(document, PCX86.APPCLASS, \"ram\");\n for (var iRAM = 0; iRAM < aeRAM.length; iRAM++) {\n var eRAM = aeRAM[iRAM];\n var parmsRAM = Component.getComponentParms(eRAM);\n var ram = new RAM(parmsRAM);\n Component.bindComponentControls(ram, eRAM, PCX86.APPCLASS);\n }\n }\n}\n\n/**\n * class CompaqController\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass CompaqController extends Controller {\n /**\n * CompaqController(ram)\n *\n * DeskPro 386 machines came with a minimum of 1Mb of RAM, which could be configured (via jumpers)\n * for 256Kb, 512Kb or 640Kb of conventional memory, starting at address 0x00000000, with the\n * remainder (768Kb, 512Kb, or 384Kb) accessible only at an address just below 0x01000000. In PCx86,\n * this second chunk of RAM must be separately allocated, with an ID of \"ramCPQ\".\n *\n * The typical configuration was 640Kb of conventional memory, leaving 384Kb accessible at 0x00FA0000.\n * Presumably, the other configurations (256Kb and 512Kb) would leave 768Kb and 512Kb accessible at\n * 0x00F40000 and 0x00F80000, respectively.\n *\n * The DeskPro 386 also contained two memory-mapped registers at 0x80C00000. The first is a write-only\n * mapping register that provides the ability to map the 128Kb at 0x00FE0000 to 0x000E0000, replacing\n * any ROMs in the range 0x000E0000-0x000FFFFF, and optionally write-protecting that 128Kb; internally,\n * this register corresponds to wMappings.\n *\n * The second register is a read-only diagnostics register that indicates jumper configuration and\n * parity errors; internally, this register corresponds to wSettings.\n *\n * To emulate the memory-mapped registers at 0x80C00000, the RAM component allocates a block at that\n * address using this custom controller once it sees an allocation for \"ramCPQ\".\n *\n * Later, when the addressability of \"ramCPQ\" memory is altered, we record the blocks in all the\n * memory slots spanning 0x000E0000-0x000FFFFF, and then update those slots with the blocks from\n * 0x00FE0000-0x00FFFFFF. Note that only the top 128Kb of \"ramCPQ\" addressability is affected; the\n * rest of that memory, ranging anywhere from 256Kb to 640Kb, remains addressable at its original\n * location. COMPAQ's CEMM and VDISK utilities were generally the only software able to access that\n * remaining memory (what COMPAQ refers to as \"Compaq Built-in Memory\").\n *\n * @this {CompaqController}\n * @param {RAM} ram\n */\n constructor(ram)\n {\n super();\n \n this.ram = ram;\n this.wMappings = CompaqController.MAPPINGS.DEFAULT;\n /*\n * TODO: wSettings needs to reflect the actual amount of configured memory....\n */\n this.wSettings = CompaqController.SETTINGS.DEFAULT;\n this.wRAMSetup = CompaqController.RAMSETUP.DEFAULT;\n this.aBlocksDst = null;\n }\n\n /**\n * save()\n *\n * This implements save support for the CompaqController component.\n *\n * @this {CompaqController}\n * @return {Array}\n */\n save()\n {\n return [this.wMappings, this.wRAMSetup];\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the CompaqController component.\n *\n * @this {CompaqController}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n this.setByte(0, data[0] & 0xff);\n this.setByte(2, data[1] & 0xff);\n return true;\n }\n\n /**\n * getByte(off)\n *\n * @this {CompaqController}\n * @param {number} off\n * @return {number}\n */\n getByte(off)\n {\n /*\n * Offsets 0-3 correspond to reads from 0x80C00000-0x80C00003; anything outside that range\n * returns our standard non-responsive value of 0xff.\n */\n var b = 0xff;\n if (off < 0x02) {\n b = (off & 0x1)? (this.wSettings >> 8) : (this.wSettings & 0xff);\n }\n else if (off < 0x4) {\n b = (off & 0x1)? (this.wRAMSetup >> 8) : (this.wRAMSetup & 0xff);\n }\n return b;\n }\n\n /**\n * setByte(off, b)\n *\n * @this {CompaqController}\n * @param {number} off (relative to 0x80C00000)\n * @param {number} b\n */\n setByte(off, b)\n {\n if (!off) {\n /*\n * This is a write to 0x80C00000\n */\n if (b != (this.wMappings & 0xff)) {\n var bus = this.ram.bus;\n if (!(b & CompaqController.MAPPINGS.UNMAPPED)) {\n if (!this.aBlocksDst) {\n this.aBlocksDst = bus.getMemoryBlocks(CompaqController.MAP_DST, CompaqController.MAP_SIZE);\n }\n /*\n * You might think that the next three lines could ALSO be moved to the preceding IF,\n * but it's possible for the write-protection feature to be enabled/disabled separately\n * from the mapping feature. We could avoid executing this code as well by checking the\n * current read-write state, but this is an infrequent operation, so there's no point.\n */\n var aBlocks = bus.getMemoryBlocks(CompaqController.MAP_SRC, CompaqController.MAP_SIZE);\n var type = (b & CompaqController.MAPPINGS.READWRITE)? Memory.TYPE.RAM : Memory.TYPE.ROM;\n bus.setMemoryBlocks(CompaqController.MAP_DST, CompaqController.MAP_SIZE, aBlocks, type);\n }\n else {\n if (this.aBlocksDst) {\n bus.setMemoryBlocks(CompaqController.MAP_DST, CompaqController.MAP_SIZE, this.aBlocksDst);\n this.aBlocksDst = null;\n }\n }\n this.wMappings = (this.wMappings & ~0xff) | b;\n }\n }\n else if (off == 0x2) {\n /*\n * This is a write to 0x80C00002\n */\n this.wRAMSetup = (this.wRAMSetup & ~0xff) | b;\n }\n }\n\n /**\n * getMemoryAccess()\n *\n * @this {CompaqController}\n * @return {Array.<function()>}\n */\n getMemoryAccess()\n {\n return CompaqController.ACCESS;\n }\n\n /**\n * getMemoryBuffer(addr)\n *\n * @this {CompaqController}\n * @param {number} addr\n * @return {Array} containing the buffer (and an offset within that buffer)\n */\n getMemoryBuffer(addr)\n {\n return CompaqController.BUFFER;\n }\n\n /**\n * readByte(off, addr)\n *\n * NOTE: Even though we asked bus.addMemory() for only 4 bytes, corresponding to the 4 memory-mapped register\n * locations we must manage, we're at the mercy of the Bus component's physical block allocation granularity,\n * which, on 80386-based machines, is fixed at 4K (the same as the 80386 page size, to simplify emulation of paging).\n *\n * So we must allow for requests outside that 4-byte range.\n *\n * @this {Memory}\n * @param {number} off (relative to 0x80C00000)\n * @param {number} [addr]\n * @return {number}\n */\n static readByte(off, addr)\n {\n var b = this.controller.getByte(off);\n if (DEBUG) {\n this.controller.ram.printMessage(\"CompaqController.readByte(\" + Str.toHexWord(off) + \") returned \" + Str.toHexByte(b), 0, true);\n }\n return b;\n }\n\n /**\n * writeByte(off, b, addr)\n *\n * NOTE: Even though we asked bus.addMemory() for only 4 bytes, corresponding to the 4 memory-mapped register\n * locations we must manage, we're at the mercy of the Bus component's physical memory allocation granularity,\n * which, on 80386-based machines, is fixed at 4K (the same as the 80386 page size, to simplify emulation of paging).\n *\n * So we must allow for requests outside that 4-byte range.\n *\n * @this {Memory}\n * @param {number} off (relative to 0x80C00000)\n * @param {number} b\n * @param {number} [addr]\n */\n static writeByte(off, b, addr)\n {\n this.controller.setByte(off, b);\n /*\n * All bits in 0x80C00001 and 0x80C00003 are reserved, so we can simply ignore those writes.\n */\n if (DEBUG) {\n this.controller.ram.printMessage(\"CompaqController.writeByte(\" + Str.toHexWord(off) + \",\" + Str.toHexByte(b) + \")\", 0, true);\n }\n }\n}\n\nCompaqController.ADDR = 0x80C00000|0;\nCompaqController.MAP_SRC = 0x00FE0000;\nCompaqController.MAP_DST = 0x000E0000;\nCompaqController.MAP_SIZE = 0x00020000;\n\n/*\n * Bit definitions for the 16-bit write-only memory-mapping register (wMappings)\n *\n * NOTE: Although COMPAQ says the memory at %FE0000 is \"relocated\", it actually remains addressable\n * at %FE0000; it simply becomes addressable at %0E0000 as well, displacing any ROMs that used to be\n * addressable at %0E0000 through %0FFFFF.\n */\nCompaqController.MAPPINGS = {\n UNMAPPED: 0x0001, // is this bit is CLEAR, the last 128Kb (at 0x00FE0000) is mapped to 0x000E0000\n READWRITE: 0x0002, // if this bit is CLEAR, the last 128Kb (at 0x00FE0000) is read-only (ie, write-protected)\n RESERVED: 0xFFFC, // the remaining 6 bits are reserved and should always be SET\n DEFAULT: 0xFFFF // our default settings (no mapping, no write-protection)\n};\n\n/*\n * Bit definitions for the 16-bit read-only settings/diagnostics register (wSettings)\n *\n * SW1-7 and SW1-8 are mapped to bits 5 and 4 of wSettings, respectively, as follows:\n *\n * SW1-7 SW1-8 Bit5 Bit4 Amount (of base memory provided by the COMPAQ 32-bit memory board)\n * ----- ----- ---- ---- ------\n * ON ON 0 0 640Kb\n * ON OFF 0 1 Invalid\n * OFF ON 1 0 512Kb\n * OFF OFF 1 1 256Kb\n *\n * Other SW1 switches include:\n *\n * SW1-1: ON enables fail-safe timer\n * SW1-2: ON indicates 80387 coprocessor installed\n * SW1-3: ON sets memory from 0xC00000 to 0xFFFFFF (between 12 and 16 megabytes) non-cacheable\n * SW1-4: ON selects AUTO system speed (OFF selects HIGH system speed)\n * SW1-5: RESERVED (however, the system can read its state; see below)\n * SW1-6: COMPAQ Dual-Mode Monitor or Color Monitor (OFF selects Monochrome monitor other than COMPAQ)\n *\n * While SW1-7 and SW1-8 are connected to this memory-mapped register, other SW1 DIP switches are accessible\n * through the 8042 Keyboard Controller's KBC.INPORT register, as follows:\n *\n * SW1-1: TODO: Determine\n * SW1-2: ChipSet.KC8042.INPORT.COMPAQ_NO80387 clear if ON, set (0x04) if OFF\n * SW1-3: TODO: Determine\n * SW1-4: ChipSet.KC8042.INPORT.COMPAQ_HISPEED clear if ON, set (0x10) if OFF\n * SW1-5: ChipSet.KC8042.INPORT.COMPAQ_DIP5OFF clear if ON, set (0x20) if OFF\n * SW1-6: ChipSet.KC8042.INPORT.COMPAQ_NONDUAL clear if ON, set (0x40) if OFF\n */\nCompaqController.SETTINGS = {\n B0_PARITY: 0x0001, // parity OK in byte 0\n B1_PARITY: 0x0002, // parity OK in byte 1\n B2_PARITY: 0x0004, // parity OK in byte 2\n B3_PARITY: 0x0008, // parity OK in byte 3\n BASE_640KB: 0x0000, // SW1-7,8: ON ON Bits 5,4: 00\n BASE_ERROR: 0x0010, // SW1-7,8: ON OFF Bits 5,4: 01\n BASE_512KB: 0x0020, // SW1-7,8: OFF ON Bits 5,4: 10\n BASE_256KB: 0x0030, // SW1-7,8: OFF OFF Bits 5,4: 11\n /*\n * TODO: The DeskPro 386/25 TechRef says bit 6 (0x40) is always set,\n * but setting it results in memory configuration errors; review.\n */\n ADDED_1MB: 0x0040,\n /*\n * TODO: The DeskPro 386/25 TechRef says bit 7 (0x80) is always clear; review.\n */\n PIGGYBACK: 0x0080,\n SYS_4MB: 0x0100, // 4Mb on system board\n SYS_1MB: 0x0200, // 1Mb on system board\n SYS_NONE: 0x0300, // no memory on system board\n MODA_4MB: 0x0400, // 4Mb on module A board\n MODA_1MB: 0x0800, // 1Mb on module A board\n MODA_NONE: 0x0C00, // no memory on module A board\n MODB_4MB: 0x1000, // 4Mb on module B board\n MODB_1MB: 0x2000, // 1Mb on module B board\n MODB_NONE: 0x3000, // no memory on module B board\n MODC_4MB: 0x4000, // 4Mb on module C board\n MODC_1MB: 0x8000, // 1Mb on module C board\n MODC_NONE: 0xC000, // no memory on module C board\n /*\n * NOTE: It doesn't seem to matter to the ROM whether I set any of bits 8-15 or not....\n */\n DEFAULT: 0x0A0F // our default settings (ie, parity OK, 640Kb base memory, 1Mb system memory, 1Mb module A memory)\n};\n\nCompaqController.RAMSETUP = {\n SETUP: 0x000F,\n CACHE: 0x0040,\n RESERVED: 0xFFB0,\n DEFAULT: 0x0002 // our default settings (ie, 2Mb, cache disabled)\n};\n\nCompaqController.BUFFER = [null, 0];\nCompaqController.ACCESS = [CompaqController.readByte, null, null, CompaqController.writeByte, null, null];\n\n/*\n * Initialize all the RAM modules on the page.\n */\nWeb.onInit(RAM.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/keyboard.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * class Keyboard\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass Keyboard extends Component {\n /**\n * Keyboard(parmsKbd)\n *\n * The Keyboard component can be configured with the following (parmsKbd) properties:\n *\n * model: keyboard model string, which must match one of the values listed in Keyboard.MODELS:\n *\n * \"US83\" (default)\n * \"US84\"\n * \"US101\" (not fully supported yet) \n *\n * autoType: string of keys to automatically inject when the machine is ready (undefined if none)\n * \n * softKeys: boolean set to true to enable the machine's soft keyboard, if any (default is false)\n *\n * Its main purpose is to receive binding requests for various keyboard events, and to use those events\n * to simulate the PC's keyboard hardware.\n * \n * TODO: Consider finishing 101-key keyboard support, even though that's sort of a \"PS/2\" thing, and I'm not\n * really interested in taking PCjs into the PS/2 line (that's also why we still support only serial mice, not\n * \"PS/2\" mice). In addition, all keyboards *after* the original PC 83-key keyboard supported their own unique\n * scan code sets, which the 8042 controller would then convert to PC-compatible scan codes. That's probably\n * more important to implement, because that feature was introduced with the 84-key keyboard on the PC AT.\n *\n * @this {Keyboard}\n * @param {Object} parmsKbd\n */\n constructor(parmsKbd)\n {\n super(\"Keyboard\", parmsKbd, Messages.KBD);\n\n this.setModel(parmsKbd['model']);\n\n this.fMobile = Web.isMobile(\"!iPad\");\n this.printMessage(\"mobile keyboard support: \" + (this.fMobile? \"true\" : \"false\"));\n \n /*\n * This flag (formerly fMSIE, for all versions of Microsoft Internet Explorer, up to and including v11)\n * has been updated to reflect the Microsoft Windows *platform* rather than the *browser*, because it appears\n * that all Windows-based browsers (at least now, as of 2018) have the same behavior with respect to \"lock\"\n * keys: keys like CAPS-LOCK generate both UP and DOWN events on every press. On other platforms (eg, macOS),\n * those keys generate only a DOWN event when \"locking\" and only an UP event when \"unlocking\".\n */\n this.fMSWindows = Web.isUserAgent(\"Windows\");\n\n /*\n * This is count of the number of \"soft keyboard\" keys present. At the moment, its only\n * purpose is to signal findBinding() whether to waste any time looking for SOFTCODE matches.\n */\n this.cSoftCodes = 0;\n this.fSoftKeyboard = parmsKbd['softKeys'];\n this.controlSoftKeyboard = null;\n this.controlTextKeyboard = null;\n\n /*\n * Updated by onFocusChange()\n */\n this.fHasFocus = true;\n\n /*\n * This is true whenever the physical Escape key is disabled (eg, by pointer locking code),\n * giving us the opportunity to map a different physical key to machine's virtual Escape key.\n */\n this.fEscapeDisabled = false;\n\n /*\n * This is set whenever we notice a discrepancy between our internal CAPS_LOCK state and its\n * apparent state; we check whenever aKeysActive has been emptied.\n */\n this.fToggleCapsLock = false;\n\n /*\n * New unified approach to key event processing: When we process a key on the \"down\" event,\n * we check the aKeysActive array: if the key is already active, do nothing; otherwise, insert\n * it into the table, generate the \"make\" scan code(s), and set a timeout for \"repeat\" if it's\n * a repeatable key (most are).\n *\n * Similarly, when a key goes \"up\", if it's already not active, do nothing; otherwise, generate\n * the \"break\" scan code(s), cancel any pending timeout, and remove it from the active key table.\n *\n * If a \"press\" event is received, then if the key is already active, remove it and (re)insert\n * it at the head of the table, generate the \"make\" scan code(s), set nRepeat to -1, and set a\n * timeout for \"break\".\n *\n * This requires an aKeysActive array that keeps track of the status of every active key; only the\n * first entry in the array is allowed to repeat. Each entry is a key object with the following\n * properties:\n *\n * simCode: our simulated keyCode from onKeyChange or onKeyPress\n * bitsState: snapshot of the current bitsState when the key is added (currently not used)\n * fDown: next state to simulate (true for down, false for up)\n * nRepeat: > 0 if timer should generate more \"make\" scan code(s), -1 for \"break\" scan code(s)\n * timer: timer for next key operation, if any\n *\n * Keys are inserted at the head of aKeysActive, using splice(0, 0, key), but not before zeroing\n * nRepeat of any repeating key that already occupies the head (index 0), so that at most only one\n * key (ie, the most recent) will ever be in a repeating state.\n *\n * IBM PC keyboard repeat behavior: when pressing CTRL, then C, and then releasing CTRL while still\n * holding C, the repeated CTRL_C characters turn into 'c' characters. We emulate that behavior.\n * However, when pressing C, then CTRL, all repeating stops: not a single CTRL_C is generated, and\n * even if the CTRL is released before the C, no more more 'c' characters are generated either.\n * We do NOT fully emulate that behavior -- we DO stop the repeating, but we also generate one CTRL_C.\n * More investigation is required, because I need to confirm whether the IBM keyboard automatically\n * \"breaks\" all non-shift keys before it \"makes\" the CTRL.\n */\n this.aKeysActive = [];\n\n this.msTransmit = 10; // minimum number of milliseconds between data transmissions\n this.msAutoRepeat = 500;\n this.msNextRepeat = 100;\n this.msAutoRelease = 50;\n this.msInjectDefault = 100; // number of milliseconds between injected keystrokes\n this.msInjectDelay = 0; // set by the initial injectKeys() call\n this.msDoubleClick = 250; // used by mousedown/mouseup handlers to soft-lock modifier keys\n this.cKeysPressed = 0; // count of keys pressed since the last time it was reset\n this.softCodeKeys = Object.keys(Keyboard.SOFTCODES);\n \n /*\n * Remove all single-character SOFTCODE keys from the softCodeKeys array, because those SOFTCODES\n * are not supported by injectKeys(); they can be specified normally using their single-character identity.\n */\n for (var i = 0; i < this.softCodeKeys.length; i++) {\n if (this.softCodeKeys[i].length < 2) {\n this.softCodeKeys.splice(i, 1);\n i--;\n }\n }\n \n /*\n * autoType records the machine's specified autoType sequence, if any, and when injectInit() is called\n * with the appropriate INJECTION signal, injectInit() pass autoType to injectKeys().\n */\n this.autoType = parmsKbd['autoType'];\n this.fDOSReady = false;\n this.fnDOSReady = this.fnInjectReady = null;\n this.nInjection = Keyboard.INJECTION.ON_INPUT;\n\n /*\n * HACK: We set fAllDown to false to ignore all down/up events for keys not explicitly marked as ONDOWN;\n * even though that prevents those keys from being repeated properly (ie, at the simulation's repeat rate\n * rather than the browser's repeat rate), it's the safest thing to do when dealing with international keyboards,\n * because our mapping tables are designed for US keyboards, and testing all the permutations of international\n * keyboards and web browsers is more work than I can take on right now. TODO: Dig into this some day.\n */\n this.fAllDown = false;\n\n this['exports'] = {\n 'type': this.injectKeys,\n 'wait': this.waitReady\n };\n\n this.setReady();\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {Keyboard}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"esc\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var kbd = this;\n var className;\n var id = sHTMLType + '-' + sBinding;\n var controlText = /** @type {HTMLTextAreaElement} */ (control);\n\n if (this.bindings[id] === undefined) {\n switch (sBinding) {\n case \"keyboard\":\n try {\n /*\n * TODO: Fix this rather fragile code, which depends on the current structure of the given xxxx-softkeys.xml\n */\n var controlSoftKeyboard = control.parentElement.parentElement.nextElementSibling;\n className = controlSoftKeyboard.className;\n if (this.fMobile != (className.indexOf('mobile') >= 0)) {\n controlSoftKeyboard = controlSoftKeyboard.nextElementSibling;\n }\n if (controlSoftKeyboard) {\n this.controlSoftKeyboard = controlSoftKeyboard;\n if (this.fSoftKeyboard != null) {\n this.enableSoftKeyboard(this.fSoftKeyboard);\n } else {\n this.fSoftKeyboard = (controlSoftKeyboard.style.display != \"none\");\n }\n control.onclick = function onToggleKeyboard(event) {\n kbd.enableSoftKeyboard(!kbd.fSoftKeyboard);\n };\n /*\n * This is added simply to prevent the page from \"zooming\" around if you accidentally touch between the keys.\n */\n if ('ontouchstart' in window) {\n controlSoftKeyboard.ontouchstart = function onTouchKeyboard(event) {\n event.preventDefault();\n };\n }\n }\n } catch(err) {}\n return true;\n \n case \"screen\":\n /*\n * This is a special binding that the Video component uses to effectively bind its screen to the\n * entire keyboard; eg:\n * \n * this.kbd.setBinding(this.inputTextArea? \"textarea\" : \"canvas\", \"screen\", this.inputScreen);\n *\n * Recording the binding ID prevents multiple controls (or components) from attempting to erroneously\n * bind a control to the same ID, but in the case of a \"dual display\" configuration, we actually want\n * to allow BOTH video components to call setBinding() for \"screen\", so that it doesn't matter which\n * display the user gives focus to.\n *\n * this.bindings[id] = control;\n */\n if (sHTMLType == \"textarea\") {\n this.controlTextKeyboard = controlText;\n }\n controlText.onkeydown = function onKeyDown(event) {\n return kbd.onKeyChange(event, true);\n };\n controlText.onkeypress = function onKeyPressKbd(event) {\n return kbd.onKeyPress(event);\n };\n controlText.onkeyup = function onKeyUp(event) {\n return kbd.onKeyChange(event, false);\n };\n return true;\n\n case \"caps-lock\":\n if (sHTMLType == 'led') {\n this.bindings[id] = control;\n control.onclick = function onClickCapsLock(event) {\n event.preventDefault();\n if (kbd.cmp) kbd.cmp.updateFocus();\n return kbd.toggleCapsLock();\n };\n return true;\n }\n /* falls through */\n\n case \"num-lock\":\n if (sHTMLType == 'led') {\n this.bindings[id] = control;\n control.onclick = function onClickNumLock(event) {\n event.preventDefault();\n if (kbd.cmp) kbd.cmp.updateFocus();\n return kbd.toggleNumLock();\n };\n return true;\n }\n /* falls through */\n\n case \"scroll-lock\":\n if (sHTMLType == 'led') {\n this.bindings[id] = control;\n control.onclick = function onClickScrollLock(event) {\n event.preventDefault();\n if (kbd.cmp) kbd.cmp.updateFocus();\n return kbd.toggleScrollLock();\n };\n return true;\n }\n /* falls through */\n\n default:\n /*\n * Maintain support for older button codes; eg, map button code \"ctrl-c\" to CLICKCODE \"CTRL_C\"\n */\n var sCode = sBinding.toUpperCase().replace(/-/g, '_');\n if (Keyboard.CLICKCODES[sCode] !== undefined && sHTMLType == \"button\") {\n this.bindings[id] = controlText;\n if (MAXDEBUG) console.log(\"binding click-code '\" + sCode + \"'\");\n controlText.onclick = function(kbd, sKey, simCode) {\n return function onKeyboardBindingClick(event) {\n if (kbd.messageEnabled()) kbd.printMessage(sKey + \" clicked\", Messages.EVENT | Messages.KEY);\n event.preventDefault(); // preventDefault() is necessary...\n if (kbd.cmp) kbd.cmp.updateFocus(); // ...for the updateFocus() call to actually work\n kbd.sInjectBuffer = \"\"; // key events should stop any injection currently in progress\n kbd.updateShiftState(simCode, true); // future-proofing if/when any LOCK keys are added to CLICKCODES\n kbd.addActiveKey(simCode, true);\n };\n }(this, sCode, Keyboard.CLICKCODES[sCode]);\n return true;\n }\n else if (Keyboard.SOFTCODES[sBinding] !== undefined) {\n /*\n * TODO: Fix this rather fragile code, which depends on the current structure of the given xxxx-softkeys.xml\n */\n className = control.parentElement.parentElement.className;\n if (className && this.fMobile != (className.indexOf('mobile') >= 0)) {\n break;\n }\n this.cSoftCodes++;\n this.bindings[id] = controlText;\n if (MAXDEBUG) console.log(\"binding soft-code '\" + sBinding + \"'\");\n var msLastEvent = 0, nClickState = 0;\n var fStateKey = (Keyboard.KEYSTATES[Keyboard.SOFTCODES[sBinding]] <= Keyboard.STATE.ALL_MODIFIERS);\n var fnDown = function(kbd, sKey, simCode) {\n return function onKeyboardBindingDown(event) {\n var msDelta = event.timeStamp - msLastEvent;\n nClickState = (nClickState && msDelta < kbd.msDoubleClick? (nClickState << 1) : 1);\n msLastEvent = event.timeStamp;\n event.preventDefault(); // preventDefault() is necessary to avoid \"zooming\" when you type rapidly\n kbd.sInjectBuffer = \"\"; // key events should stop any injection currently in progress\n kbd.addActiveKey(simCode);\n };\n }(this, sBinding, Keyboard.SOFTCODES[sBinding]);\n var fnUp = function(kbd, sKey, simCode) {\n return function onKeyboardBindingUp(event) {\n if (nClickState) {\n var msDelta = event.timeStamp - msLastEvent;\n nClickState = (fStateKey && msDelta < kbd.msDoubleClick? (nClickState << 1) : 0);\n msLastEvent = event.timeStamp;\n if (nClickState < 8) {\n kbd.removeActiveKey(simCode);\n } else {\n if (MAXDEBUG) console.log(\"soft-locking '\" + sBinding + \"'\");\n nClickState = 0;\n }\n }\n };\n }(this, sBinding, Keyboard.SOFTCODES[sBinding]);\n if ('ontouchstart' in window) {\n controlText.ontouchstart = fnDown;\n controlText.ontouchend = fnUp;\n } else {\n controlText.onmousedown = fnDown;\n controlText.onmouseup = controlText.onmouseout = fnUp;\n }\n return true;\n }\n else if (sValue) {\n /*\n * Instead of just having a dedicated \"test\" control, we now treat any unrecognized control with\n * a \"value\" attribute as a test control. The only caveat is that such controls must have binding IDs\n * that do not conflict with predefined controls (which, of course, is the only way you can get here).\n */\n this.bindings[id] = control;\n control.onclick = function onClickTest(event) {\n event.preventDefault(); // preventDefault() is necessary...\n if (kbd.cmp) kbd.cmp.updateFocus(); // ...for the updateFocus() call to actually work\n return kbd.injectKeys(sValue);\n };\n return true;\n }\n break;\n }\n }\n return false;\n }\n\n /**\n * findBinding(simCode, sType, fDown)\n *\n * TODO: This function is woefully inefficient, because the SOFTCODES table is designed for converting\n * soft key presses into SIMCODES, whereas this function is doing the reverse: looking for the soft key,\n * if any, that corresponds to a SIMCODE, simply so we can provide visual feedback of keys activated\n * by other means (eg, real keyboard events, button clicks that generate key sequences like CTRL-ALT-DEL,\n * etc).\n *\n * To minimize this function's cost, we would want to dynamically create a reverse-lookup table after\n * all the setBinding() calls for the soft keys have been established; note that the reverse-lookup table\n * would contain MORE entries than the SOFTCODES table, because there are multiple simCodes that correspond\n * to a given soft key (eg, '1' and '!' both map to the same soft key).\n *\n * @this {Keyboard}\n * @param {number} simCode\n * @param {string} sType is the type of control (eg, \"button\" or \"key\")\n * @param {boolean} [fDown] is true if the key is going down, false if up, or undefined if unchanged\n * @return {Object} is the HTML control DOM object (eg, HTMLButtonElement), or undefined if no such control exists\n */\n findBinding(simCode, sType, fDown)\n {\n var control;\n if (this.cSoftCodes && this.fSoftKeyboard) {\n for (var code in Keys.SHIFTED_KEYCODES) {\n if (simCode == Keys.SHIFTED_KEYCODES[code]) {\n simCode = +code;\n code = Keys.NONASCII_KEYCODES[code];\n if (code) simCode = +code;\n break;\n }\n }\n /*\n * TODO: Create a table that maps these SIMCODEs to the corresponding entries in the SOFTCODES table;\n * these SIMCODEs can be generated by CLICKCODEs or by the special key remapping HACKs in onKeyChange().\n */\n if (simCode == Keyboard.SIMCODE.CTRL_PAUSE) {\n simCode = Keyboard.SIMCODE.NUM_LOCK;\n }\n else if (simCode == Keyboard.SIMCODE.CTRL_BREAK) {\n simCode = Keyboard.SIMCODE.SCROLL_LOCK;\n }\n else if (simCode == Keyboard.SIMCODE.CTRL_ALT_DEL) {\n simCode = Keyboard.SIMCODE.DEL;\n }\n else if (simCode == Keyboard.SIMCODE.CTRL_ALT_INS) {\n simCode = Keyboard.SIMCODE.INS;\n }\n else if (simCode == Keyboard.SIMCODE.CTRL_ALT_ADD) {\n simCode = Keyboard.SIMCODE.NUM_ADD;\n }\n else if (simCode == Keyboard.SIMCODE.CTRL_ALT_SUB) {\n simCode = Keyboard.SIMCODE.NUM_SUB;\n }\n for (var sBinding in Keyboard.SOFTCODES) {\n if (Keyboard.SOFTCODES[sBinding] == simCode || Keyboard.SOFTCODES[sBinding] == this.toUpperKey(simCode)) {\n var id = sType + '-' + sBinding;\n control = this.bindings[id];\n if (control && fDown !== undefined) {\n this.setSoftKeyState(control, fDown);\n }\n break;\n }\n }\n }\n return control;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {Keyboard}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n var kbd = this;\n this.timerInject = this.cpu.addTimer(this.id + \".inject\", function injectKeysTimer() {\n kbd.injectKeys();\n });\n \n this.timerTransmit = this.cpu.addTimer(this.id + \".transmit\", function transmitDataTimer() {\n kbd.transmitData();\n });\n\n this.chipset = cmp.getMachineComponent(\"ChipSet\");\n this.autoType = cmp.getMachineParm('autoType') || this.autoType;\n\n var softKeys = cmp.getMachineParm('softKeys');\n if (softKeys) this.enableSoftKeyboard(softKeys != \"false\");\n\n cpu.addIntNotify(Interrupts.DOS, this.intDOS.bind(this));\n }\n\n /**\n * start()\n *\n * Notification from the Computer that it's starting.\n *\n * @this {Keyboard}\n */\n start()\n {\n this.injectInit(Keyboard.INJECTION.ON_START);\n }\n\n /**\n * intDOS()\n *\n * Monitors selected DOS interrupts for signals to initialize 'autoType' injection.\n *\n * @this {Keyboard}\n * @param {number} addr\n * @return {boolean} true to proceed with the INT 0x21 software interrupt, false to skip\n */\n intDOS(addr)\n {\n var AH = (this.cpu.regEAX >> 8) & 0xff;\n if (AH == 0x0A) {\n this.fDOSReady = true;\n if (this.fnDOSReady) {\n this.fnDOSReady();\n this.fnDOSReady = null;\n this.fDOSReady = false;\n } else {\n this.injectInit(Keyboard.INJECTION.ON_INPUT);\n }\n }\n return true;\n }\n\n /**\n * notifyEscape(fDisabled, fAllDown)\n *\n * When ESC is used by the browser to disable pointer lock, this gives us the option of mapping a different key to ESC.\n *\n * @this {Keyboard}\n * @param {boolean} fDisabled\n * @param {boolean} [fAllDown] (an experimental option to re-enable processing of all onkeydown/onkeyup events)\n */\n notifyEscape(fDisabled, fAllDown)\n {\n this.fEscapeDisabled = fDisabled;\n if (fAllDown !== undefined) this.fAllDown = fAllDown;\n }\n\n /**\n * resetDevice()\n *\n * @this {Keyboard}\n */\n resetDevice()\n {\n /*\n * TODO: There's more to reset, like LED indicators, default type rate, and emptying the scan code buffer.\n */\n this.printMessage(\"keyboard reset\", Messages.KBD | Messages.PORT);\n this.abBuffer = [];\n this.setResponse(Keyboard.CMDRES.BAT_OK);\n }\n\n /**\n * setModel(sModel)\n *\n * This breaks a model string (eg, \"US83\") into two parts: modelCountry (eg, \"US\") and modelKeys (eg, 83).\n * If the model string isn't recognized, we use Keyboard.MODELS[0] (ie, the first entry in the model array).\n *\n * @this {Keyboard}\n * @param {string|undefined} sModel\n */\n setModel(sModel)\n {\n var iModel = 0;\n this.model = null;\n if (typeof sModel == \"string\") {\n this.model = sModel.toUpperCase();\n iModel = Keyboard.MODELS.indexOf(this.model);\n if (iModel < 0) iModel = 0;\n }\n sModel = Keyboard.MODELS[iModel];\n if (sModel) {\n this.modelCountry = sModel.substr(0, 2);\n this.modelKeys = parseInt(sModel.substr(2), 10);\n }\n }\n\n /**\n * checkBuffer(b)\n *\n * This is the ChipSet's interface to let us know it's ready.\n *\n * @this {Keyboard}\n * @param {number} [b] (set to the data, if any, that the ChipSet just delivered)\n */\n checkBuffer(b)\n {\n var fReady = false;\n if (b) {\n /*\n * The following hack is for the 5170 ROM BIOS keyboard diagnostic, which expects the keyboard\n * to report BAT_OK immediately after the ACK from a RESET command. The BAT_OK response should already\n * be in the keyboard's buffer; we just need to give it a little nudge.\n */\n if (b == Keyboard.CMDRES.ACK) {\n fReady = true;\n }\n if (this.cpu) {\n this.cpu.setTimer(this.timerTransmit, this.msTransmit, true);\n }\n }\n this.transmitData(fReady);\n }\n\n /**\n * flushBuffer()\n *\n * This is the ChipSet's interface to flush any buffered keyboard data.\n *\n * @this {Keyboard}\n */\n flushBuffer()\n {\n this.abBuffer = [];\n if (!COMPILED && this.messageEnabled()) this.printMessage(\"keyboard data flushed\");\n }\n\n /**\n * receiveCmd(bCmd)\n *\n * This is the ChipSet's interface for controlling \"Model M\" keyboards (ie, those used with MODEL_5170\n * machines). Commands are delivered through the ChipSet's 8042 Keyboard Controller.\n *\n * @this {Keyboard}\n * @param {number} bCmd should be one of the Keyboard.CMD.* command codes (Model M keyboards only)\n * @return {number} response should be one of the Keyboard.CMDRES.* response codes, or -1 if unrecognized\n */\n receiveCmd(bCmd)\n {\n var b = -1;\n\n if (!COMPILED && this.messageEnabled()) this.printMessage(\"receiveCmd(\" + Str.toHexByte(bCmd) + \")\");\n\n switch(this.bCmdPending || bCmd) {\n\n case Keyboard.CMD.RESET: // 0xFF\n b = Keyboard.CMDRES.ACK;\n this.resetDevice();\n break;\n\n case Keyboard.CMD.SET_RATE: // 0xF3\n if (this.bCmdPending) {\n this.setRate(bCmd);\n bCmd = 0;\n }\n this.setResponse(Keyboard.CMDRES.ACK);\n this.bCmdPending = bCmd;\n break;\n\n case Keyboard.CMD.SET_LEDS: // 0xED\n if (this.bCmdPending) {\n this.setLEDs(bCmd);\n bCmd = 0;\n }\n this.setResponse(Keyboard.CMDRES.ACK);\n this.bCmdPending = bCmd;\n break;\n\n default:\n if (!COMPILED) this.printMessage(\"receiveCmd(): unrecognized command\");\n break;\n }\n\n return b;\n }\n\n /**\n * setEnabled(fData, fClock)\n *\n * This is the ChipSet's interface for toggling keyboard \"data\" and \"clock\" lines.\n * \n * For MODEL_5150 and MODEL_5160 machines, this function is called from the ChipSet's PPI_B\n * output handler. For MODEL_5170 machines, this function is called when selected CMD\n * \"data bytes\" have been written.\n *\n * @this {Keyboard}\n * @param {boolean} fData is true if the keyboard simulated data line should be enabled\n * @param {boolean} fClock is true if the keyboard's simulated clock line should be enabled\n * @return {boolean} true if keyboard was re-enabled, false if not (or no change)\n */\n setEnabled(fData, fClock)\n {\n var fReset = false;\n if (this.fClock !== fClock) {\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.PORT)) {\n this.printMessage(\"keyboard clock line changing to \" + fClock, true);\n }\n /*\n * Toggling the clock line low and then high signals a \"reset\", which we acknowledge once the\n * data line is high as well.\n */\n this.fClock = this.fResetOnEnable = fClock;\n }\n if (this.fData !== fData) {\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.PORT)) {\n this.printMessage(\"keyboard data line changing to \" + fData, true);\n }\n this.fData = fData;\n if (fData && !this.fResetOnEnable) {\n this.transmitData(true);\n }\n }\n if (this.fData && this.fResetOnEnable) {\n this.resetDevice();\n this.fResetOnEnable = false;\n fReset = true;\n }\n return fReset;\n }\n\n /**\n * setLEDs(b)\n *\n * This processes the option byte received after a SET_LEDS command byte.\n *\n * @this {Keyboard}\n * @param {number} b\n */\n setLEDs(b)\n {\n this.bLEDs = b; // TODO: Implement\n }\n\n /**\n * setRate(b)\n *\n * This processes the rate parameter byte received after a SET_RATE command byte.\n *\n * @this {Keyboard}\n * @param {number} b\n */\n setRate(b)\n {\n this.bRate = b; // TODO: Implement\n }\n\n /**\n * setResponse(b)\n *\n * @this {Keyboard}\n * @param {number} b\n */\n setResponse(b)\n {\n if (this.chipset) {\n this.abBuffer.unshift(b);\n if (!COMPILED && this.messageEnabled()) this.printMessage(\"keyboard response \" + Str.toHexByte(b) + \" buffered\");\n this.transmitData();\n }\n }\n\n /**\n * transmitData(fReady)\n *\n * This manages communication with the ChipSet's receiveKbdData() interface.\n *\n * @this {Keyboard}\n * @param {boolean} [fReady]\n */\n transmitData(fReady)\n {\n if (this.chipset) {\n if (fReady || !this.cpu.isTimerSet(this.timerTransmit)) {\n /*\n * The original IBM PC BIOS performs a \"stuck key\" test by resetting the keyboard\n * (by toggling the CLOCK line), then checking for a BAT_OK response (0xAA), and then\n * clocking in the next byte (by toggling the DATA line); if that next byte isn't 0x00,\n * then the BIOS reports a \"301\" error, along with \"AA\" if we failed to properly flush\n * the BAT_OK response. \n */\n var b = this.abBuffer.length? this.abBuffer[0] : 0; \n if (this.chipset.receiveKbdData(b)) {\n if (!COMPILED && this.messageEnabled()) this.printMessage(\"keyboard data \" + Str.toHexByte(b) + \" delivered\");\n this.abBuffer.shift();\n }\n if (b) this.cpu.setTimer(this.timerTransmit, this.msTransmit);\n }\n }\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {Keyboard}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n /*\n * TODO: Save/restore support for Keyboard is the barest minimum. In fact, originally, I wasn't\n * saving/restoring anything, and that was OK, but if we don't at least re-initialize fClock/fData,\n * we can get a spurious reset following a restore. In an ideal world, we might choose to save/restore\n * abBuffer as well, but realistically, I think it's going to be safer to always start with an\n * empty buffer--and who's going to notice anyway?\n *\n * So, like Debugger, we deviate from the typical save/restore pattern: instead of reset OR restore,\n * we always reset and then perform a (very limited) restore.\n */\n this.reset();\n if (data && this.restore) {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Keyboard}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {Keyboard}\n */\n reset()\n {\n /*\n * If no keyboard model was specified, our initial setModel() call will select the \"US83\" keyboard as the\n * default, but now that the ChipSet is initialized, we can pick a better default, based on the ChipSet model.\n */\n if (!this.model && this.chipset) {\n switch(this.chipset.model) {\n case ChipSet.MODEL_5150:\n case ChipSet.MODEL_5160:\n this.setModel(Keyboard.MODELS[0]);\n break;\n case ChipSet.MODEL_5170:\n default:\n this.setModel(Keyboard.MODELS[1]);\n break;\n }\n }\n this.initState();\n }\n\n /**\n * save()\n *\n * This implements save support for the Keyboard component.\n *\n * @this {Keyboard}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveState());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the Keyboard component.\n *\n * @this {Keyboard}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return this.initState(data[0]);\n }\n\n /**\n * initState(data)\n *\n * @this {Keyboard}\n * @param {Array} [data]\n * @return {boolean} true if successful, false if failure\n */\n initState(data)\n {\n /*\n * Empty the injection buffer (an injection could have been in progress on any reset after the first).\n */\n this.sInjectBuffer = \"\";\n this.nInjection = Keyboard.INJECTION.ON_INPUT;\n\n if (!data) {\n data = [];\n } else {\n /*\n * If there is a predefined state for this machine, then the assumption is that any injection\n * sequence can be injected as soon as the machine starts. Any other kind of state must disable\n * injection, because injection depends on the machine being in a known state.\n */\n this.nInjection = this.cmp.sStatePath? Keyboard.INJECTION.ON_START : Keyboard.INJECTION.NONE;\n }\n\n var i = 0;\n this.fClock = data[i++];\n this.fData = data[i];\n this.bCmdPending = 0; // when non-zero, a command is pending (eg, SET_LED or SET_RATE)\n\n /*\n * The current (assumed) physical (and simulated) states of the various shift/lock keys.\n *\n * TODO: Determine how (or whether) we can query the browser's initial shift/lock key states.\n */\n this.bitsState = this.bitsStateSim = 0;\n\n /*\n * New scan codes are \"pushed\" onto abBuffer and then \"shifted\" off.\n */\n this.abBuffer = [];\n\n return true;\n }\n\n /**\n * saveState()\n *\n * @this {Keyboard}\n * @return {Array}\n */\n saveState()\n {\n var data = [];\n data[0] = this.fClock;\n data[1] = this.fData;\n return data;\n }\n\n /**\n * enableSoftKeyboard(fEnable)\n *\n * In addition to enabling or disabling our own soft keyboard (if any), this also attempts to disable or enable\n * (as appropriate) the textarea control (if any) that machines use to trigger a touch device's built-in keyboard.\n * \n * @this {Keyboard}\n * @param {boolean} fEnable\n */\n enableSoftKeyboard(fEnable)\n {\n if (this.controlSoftKeyboard) {\n if (!fEnable) {\n this.controlSoftKeyboard.style.display = \"none\";\n if (this.controlTextKeyboard) {\n this.controlTextKeyboard.readOnly = false;\n }\n } else {\n this.controlSoftKeyboard.style.display = \"block\";\n if (this.controlTextKeyboard) {\n this.controlTextKeyboard.readOnly = true;\n }\n }\n }\n this.fSoftKeyboard = fEnable;\n }\n \n /**\n * setSoftKeyState(control, f)\n *\n * @this {Keyboard}\n * @param {HTMLElement} control is an HTML control DOM object\n * @param {boolean} f is true if the key represented by e should be \"on\", false if \"off\"\n */\n setSoftKeyState(control, f)\n {\n control.style.color = (f? \"#ffffff\" : \"#000000\");\n control.style.backgroundColor = (f? \"#000000\" : \"#ffffff\");\n }\n\n /**\n * addScanCode(bScan)\n *\n * @this {Keyboard}\n * @param {number} bScan\n */\n addScanCode(bScan)\n {\n /*\n * Prepare for the possibility that our reset() function may not have been called yet.\n *\n * TODO: Determine whether we need to reset() the Keyboard sooner (ie, in the constructor),\n * or if we need to protect other methods from prematurely accessing certain Keyboard structures,\n * as a result of calls from any of the key event handlers established by setBinding().\n */\n if (this.abBuffer) {\n if (this.abBuffer.length < Keyboard.LIMIT.MAX_SCANCODES) {\n if (DESKPRO386) {\n if (this.chipset && this.chipset.model == ChipSet.MODEL_COMPAQ_DESKPRO386) {\n /*\n * COMPAQ keyclick support is being disabled because we are currently unable to properly\n * simulate the keyclick sound, due to the way the COMPAQ DeskPro 386 ROM rapidly toggles\n * the speaker bit. And there isn't really a better time to disable it, because the\n * COMPAQ_KEYCLICK byte is set by IBMBIO.COM initialization code in COMPAQ MS-DOS, if the\n * machine model byte is FC (indicating PC AT):\n * \n * &0070:2EF7 2E CS:\n * &0070:2EF8 803E442DFC CMP [2D44],FC\n * &0070:2EFD 750C JNZ 2F0B (IBMBIO.COM+0x3174)\n * &0070:2EFF 26 ES:\n * &0070:2F00 C606160401 MOV [0416],01\n */\n if (!this.cpu.isProtMode()) {\n this.bus.setByteDirect(ROMX86.BIOS.COMPAQ_KEYCLICK, 0);\n }\n }\n }\n this.abBuffer.push(bScan);\n if (!COMPILED && this.messageEnabled()) this.printMessage(\"keyboard data \" + Str.toHexByte(bScan) + \" buffered\");\n this.transmitData();\n return;\n }\n if (this.abBuffer.length == Keyboard.LIMIT.MAX_SCANCODES) {\n this.abBuffer.push(Keyboard.CMDRES.BUFF_FULL);\n }\n this.printMessage(\"keyboard buffer overflow\");\n }\n }\n\n /**\n * injectInit(nCondition)\n *\n * @this {Keyboard}\n * @param {number} nCondition\n */\n injectInit(nCondition)\n {\n if (this.nInjection == nCondition) {\n this.nInjection = Keyboard.INJECTION.NONE;\n if (this.autoType) this.injectKeys(this.autoType);\n }\n }\n\n /**\n * injectKeys(sKeys, msDelay)\n *\n * @this {Keyboard}\n * @param {string} [sKeys]\n * @param {number} [msDelay] is an optional injection delay (default is msInjectDefault)\n * @return {boolean}\n */\n injectKeys(sKeys, msDelay)\n {\n if (sKeys) {\n var sInjectBuffer = this.parseKeys(sKeys);\n if (sInjectBuffer) {\n this.nInjection = Keyboard.INJECTION.NONE;\n this.sInjectBuffer = sInjectBuffer;\n if (!COMPILED) this.log(\"injectKeys(\\\"\" + this.sInjectBuffer.split(\"\\n\").join(\"\\\\n\") + \"\\\")\");\n this.msInjectDelay = msDelay || this.msInjectDefault;\n this.injectKeys();\n return true;\n }\n return false;\n }\n /*\n * Any delay of one second or more ($10 and up) is automatically reverted to the default.\n */\n if (this.msInjectDelay >= 1000) {\n this.msInjectDelay = this.msInjectDefault;\n }\n var simCode = 0;\n while (this.sInjectBuffer.length > 0 && !simCode) {\n var ch = this.sInjectBuffer.charAt(0);\n if (ch == '$') {\n /*\n * $<number> pauses injection by the specified number of tenths of a second; eg,\n * $5 pauses for 1/2 second. $0 reverts the default injection delay (eg, 100ms).\n * Also, you may end the number with a period if you need to avoid an injected digit\n * being misinterpreted as part of the delay (eg, $5.1) pauses for 1/2 second and\n * then injects \"1\").\n */\n var digits = this.sInjectBuffer.match(/^\\$([0-9]+)\\.?/);\n if (digits) {\n this.msInjectDelay = (+digits[1] * 100) || this.msInjectDefault;\n this.sInjectBuffer = this.sInjectBuffer.substr(digits[0].length);\n break;\n }\n /*\n * Yes, this code is slow and gross, but it's simple, and key injection doesn't have\n * to be that fast anyway. The added check for SOFTCODES that have omitted the 'num-'\n * prefix adds to the slowness, but it's a nice convenience, allowing you to specify\n * non-ASCII keys like 'num-right' or 'num-up' more succinctly as \"$right\" or \"$up\". \n */\n for (var i = 0; i < this.softCodeKeys.length; i++) {\n var name = this.softCodeKeys[i];\n if (this.sInjectBuffer.indexOf(name) == 1) {\n simCode = Keyboard.SOFTCODES[name];\n this.sInjectBuffer = this.sInjectBuffer.substr(name.length + 1);\n break;\n }\n var shortName = (name.indexOf('num-') == 0? name.substr(4) : \"\");\n if (shortName && this.sInjectBuffer.indexOf(shortName) == 1) {\n simCode = Keyboard.SOFTCODES[name];\n this.sInjectBuffer = this.sInjectBuffer.substr(shortName.length + 1);\n break;\n }\n }\n }\n if (simCode) break;\n this.sInjectBuffer = this.sInjectBuffer.substr(1);\n var charCode = ch.charCodeAt(0);\n /*\n * charCodes 0x01-0x1A correspond to key combinations CTRL-A through CTRL-Z, unless they\n * are \\t, \\n, or \\r, which are reserved for TAB, LINE-FEED, and RETURN, respectively, so if\n * you need to simulate CTRL-I, CTRL-J, or CTRL-M, those must be specified using \\x1C, \\x1D,\n * or \\x1E, respectively. Also, since PCs have no dedicated LINE-FEED key, and since \\n is\n * often used instead of \\r, we map LINE-FEED (LF) to RETURN (CR) below.\n */\n if (charCode <= Keys.ASCII.CTRL_Z) {\n simCode = charCode;\n /*\n * I could require all callers to supply CRs instead of LFs, but this is friendlier; besides,\n * PCs don't have a dedicated LINE-FEED key, so the LF charCode is somewhat meaningless.\n */\n if (charCode == 0x0A) simCode = 0x0D;\n if (charCode != Keys.ASCII.CTRL_I && charCode != Keys.ASCII.CTRL_J && charCode != Keys.ASCII.CTRL_M) {\n simCode += Keys.KEYCODE.FAKE;\n }\n }\n else if (charCode == 0x1C) {\n simCode = Keys.ASCII.CTRL_I + Keys.KEYCODE.FAKE;\n }\n else if (charCode == 0x1D) {\n simCode = Keys.ASCII.CTRL_J + Keys.KEYCODE.FAKE;\n }\n else if (charCode == 0x1E) {\n simCode = Keys.ASCII.CTRL_M + Keys.KEYCODE.FAKE;\n }\n else if (charCode == 0x1F) {\n simCode = Keys.ASCII['$'];\n }\n else if (charCode <= 0x7F) {\n simCode = charCode;\n }\n }\n \n if (simCode) {\n var fPress = (Keyboard.MODIFIERS[simCode] === undefined); \n this.addActiveKey(simCode, fPress);\n if (fPress) this.clearActiveKeys(true);\n }\n \n if (!this.sInjectBuffer.length) {\n if (this.fnInjectReady) {\n this.fnInjectReady();\n this.fnInjectReady = null;\n }\n } else {\n this.cpu.setTimer(this.timerInject, this.msInjectDelay);\n }\n return true;\n }\n\n /**\n * parseKeys(sKeys)\n *\n * The following special \"macro\" sequences are recognized:\n *\n * $date: converted to MM-DD-YYYY\n * $time: converted to HH:MM\n *\n * In addition, property keys in the SOFTCODES tables can be prefixed with \"$\" if you want to specify\n * a key by its SOFTCODE; eg:\n *\n * $f1: the F1 function key\n * $alt: the ALT key\n *\n * Not all SOFTCODES are allowed; for example, SOFTCODES that begin with a digit or other non-alpha symbol,\n * or that contain only one letter, because those SOFTCODES can already be specified as-is, WITHOUT a leading\n * \"$\". Also, all we replace here are the \"macro\" sequences, leaving any prefixed SOFTCODES in place so that\n * injectKeys() can convert them on the fly.\n *\n * If you want any of those sequences to be typed as-is, then you must specify two \"$\" (eg, \"$$date\").\n * Pairs of dollar signs will be automatically converted to single dollar signs, and single dollar signs\n * will be used as-is, provided they don't precede any of the above \"macro\" or SOFTCODE sequences.\n *\n * WARNING: the JavaScript replace() function ALWAYS interprets \"$\" specially in replacement strings,\n * even when the search string is NOT a RegExp; specifically:\n *\n * $$ Inserts a \"$\"\n * $& Inserts the matched substring\n * $` Inserts the portion of the string that precedes the matched substring\n * $' Inserts the portion of the string that follows the matched substring\n * $n Where n is a positive integer less than 100, inserts the nth parenthesized sub-match string,\n * provided the first argument was a RegExp object\n *\n * Since we build machine definitions on a page from a potentially indeterminate number of string replace()\n * operations, multiple dollar signs could eventually get reduced to a single dollar sign BEFORE we get here.\n *\n * To compensate, I've changed a few replace() methods, like MarkOut's convertMDMachineLinks() and HTMLOut's\n * addFilesToHTML(), from the conventional string replace() to my own Str.replace(), and for situations like the\n * embed.js parseXML() function, which needs to use a RegExp-style replace(), I've added a preliminary\n * replace(/\\$/g, \"$$$$\") to the replacement string.\n *\n * Unfortunately, this is something that will be extremely difficult to prevent from breaking down the road.\n * So, heads up to future me....\n *\n * @this {Keyboard}\n * @param {string|undefined} sKeys\n * @return {string|undefined}\n */\n parseKeys(sKeys)\n {\n if (sKeys) {\n var match, reSpecial = /(?:^|[^$])\\$([a-z0-9][a-z0-9-]+)/g;\n while (match = reSpecial.exec(sKeys)) {\n var sReplace = \"\";\n switch (match[1]) {\n case 'date':\n sReplace = Usr.formatDate(\"n-j-Y\");\n break;\n case 'time':\n sReplace = Usr.formatDate(\"h:i:s\");\n break;\n default:\n continue;\n }\n sKeys = sKeys.replace('$' + match[1], sReplace);\n /*\n * Even though we did just modify the string that reSpecial is iterating over, we aren't\n * going to muck with lastIndex, because 1) the replacement strings are always longer than\n * original strings, and 2) any unrecognized sequences that we now leave in place would cause\n * us to loop indefinitely. So, if you really want to do this, you will have to carefully\n * set lastIndex to the next unexamined character, not back to the beginning.\n *\n * reSpecial.lastIndex = 0;\n */\n }\n /*\n * Any lingering \"$$\" sequences are now converted to a special code (\\x1F) that injectKeys() knows about.\n */\n sKeys = sKeys.replace(/\\$\\$/g, '\\x1F');\n }\n return sKeys;\n }\n\n /**\n * waitReady(fnCallReady, sOption)\n *\n * @this {Keyboard}\n * @param {function()|null} fnCallReady\n * @param {string} [sOption]\n * @return {boolean} false if wait required, true otherwise\n */\n waitReady(fnCallReady, sOption)\n {\n var fReady = false;\n\n switch(sOption) {\n case \"DOS\":\n if (this.fDOSReady) {\n fReady = true;\n } else {\n this.fnDOSReady = fnCallReady;\n }\n break;\n\n default:\n if (!this.sInjectBuffer.length) {\n fReady = true;\n } else {\n this.fnInjectReady = fnCallReady;\n }\n break;\n }\n return fReady;\n }\n\n /**\n * setLED(control, f)\n *\n * @this {Keyboard}\n * @param {HTMLElement} control is an HTML control DOM object\n * @param {boolean} f is true if the LED represented by control should be \"on\", false if \"off\"\n */\n setLED(control, f)\n {\n /*\n * TODO: Add support for user-definable LED colors\n */\n control.style.backgroundColor = (f? \"#00ff00\" : \"#000000\");\n }\n\n /**\n * updateLEDs(bitState)\n *\n * Updates any and all shift-related LEDs with the corresponding state in bitsStateSim.\n *\n * @this {Keyboard}\n * @param {number} [bitState] is the bit in bitsStateSim that may have changed, if known; undefined if not\n */\n updateLEDs(bitState)\n {\n var control;\n for (var sBinding in Keyboard.LEDSTATES) {\n var id = \"led-\" + sBinding;\n var bitLED = Keyboard.LEDSTATES[sBinding];\n if ((!bitState || bitState == bitLED) && (control = this.bindings[id])) {\n this.setLED(control, !!(this.bitsStateSim & bitLED));\n }\n }\n }\n\n /**\n * toggleCapsLock()\n *\n * @this {Keyboard}\n */\n toggleCapsLock()\n {\n this.addActiveKey(Keyboard.SIMCODE.CAPS_LOCK, true);\n }\n\n /**\n * toggleNumLock()\n *\n * @this {Keyboard}\n */\n toggleNumLock()\n {\n this.addActiveKey(Keyboard.SIMCODE.NUM_LOCK, true);\n }\n\n /**\n * toggleScrollLock()\n *\n * @this {Keyboard}\n */\n toggleScrollLock()\n {\n this.addActiveKey(Keyboard.SIMCODE.SCROLL_LOCK, true);\n }\n\n /**\n * updateShiftState(simCode, fSim, fDown)\n *\n * For non-locking shift keys, this function is straightforward: when fDown is true, the corresponding bitState\n * is set, and when fDown is false, it's cleared. However, for LOCK keys, fDown true means toggle, and fDown false\n * means no change.\n *\n * @this {Keyboard}\n * @param {number} simCode (includes any ONDOWN and/or ONRIGHT modifiers)\n * @param {boolean} [fSim] is true to update simulated state only\n * @param {boolean|null} [fDown] is true for down, false for up, undefined for toggle\n * @return {number} 0 if not a shift key, 1 if shift key down, -1 if shift key up\n */\n updateShiftState(simCode, fSim, fDown)\n {\n var result = 0;\n if (Keyboard.SIMCODES[simCode]) {\n var fRight = (Math.floor(simCode / 1000) & 2);\n var bitState = Keyboard.KEYSTATES[simCode] || 0;\n if (bitState) {\n if (fRight && !(bitState & Keyboard.STATE.ALL_RIGHT)) {\n bitState >>= 1;\n }\n if (bitState & Keyboard.STATE.ALL_LOCKS) {\n if (fDown === false) return -1;\n fDown = null;\n }\n if (fDown == null) { // ie, null or undefined\n fDown = !((fSim? this.bitsStateSim : this.bitsState) & bitState);\n }\n else if (!fDown && !fSim) {\n /*\n * In current webkit browsers, pressing and then releasing both left and right shift keys together\n * (or both ALT keys, or both CMD/Windows keys, or presumably both CTRL keys) results in 4 events,\n * as you would expect, but 3 of the 4 are \"down\" events; only the last of the 4 is an \"up\" event.\n *\n * Perhaps this is a browser accessibility feature (ie, deliberately suppressing the \"up\" event\n * of one of the shift keys to implement a \"sticky shift mode\"?), but in any case, to maintain our\n * internal consistency, if this is an \"up\" event and the shift state bit is any of ALL_MODIFIERS,\n * then we set it to ALL_MODIFIERS, so that we'll automatically clear ALL shift states.\n *\n * TODO: The only downside to this work-around is that the simulation will still think a shift key is\n * down. So in effect, we have enabled a \"sticky shift mode\" inside the simulation, whether or not that\n * was the browser's intent. To fix that, we would have to identify the shift key that never went up\n * and simulate the \"up\". That's more work than I think the problem merits. The user just needs to tap\n * a single shift key to get out that mode.\n */\n if (bitState & Keyboard.STATE.ALL_MODIFIERS) bitState = Keyboard.STATE.ALL_MODIFIERS;\n }\n if (!fSim) {\n this.bitsState &= ~bitState;\n if (fDown) this.bitsState |= bitState;\n } else {\n /*\n * This next line reflects the fact that we don't want to modify any simulated LOCK states if a simulated\n * shift state (ie, CTRL, ALT, SHIFT, etc) is also active. For example, CTRL-NUM-LOCK is a special sequence\n * (Pause) that isn't supposed to alter the NUM-LOCK state; similarly, CTRL-SCROLL-LOCK (aka Ctrl-Break)\n * isn't supposed to alter the SCROLL-LOCK state.\n */\n if (!(this.bitsStateSim & Keyboard.STATE.ALL_MODIFIERS) || !(bitState & Keyboard.STATE.ALL_LOCKS)) {\n this.bitsStateSim &= ~bitState;\n if (fDown) this.bitsStateSim |= bitState;\n this.updateLEDs(bitState);\n }\n }\n result = fDown? 1 : -1;\n }\n }\n return result;\n }\n\n /**\n * addActiveKey(simCode, fPress)\n *\n * @this {Keyboard}\n * @param {number} simCode\n * @param {boolean} [fPress]\n * @return {boolean} true if added, false if not (eg, not recognized, already added, etc)\n */\n addActiveKey(simCode, fPress)\n {\n var wCode = Keyboard.SIMCODES[simCode] || Keyboard.SIMCODES[simCode += Keys.KEYCODE.ONDOWN];\n\n if (!wCode) {\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.KEY)) {\n this.printMessage(\"addActiveKey(\" + simCode + \",\" + (fPress? \"press\" : \"down\") + \"): unrecognized\", true);\n }\n return false;\n }\n\n /*\n * Ignore all active keys if the CPU is not running.\n */\n if (!this.cpu || !this.cpu.isRunning()) return false;\n\n /*\n * If this simCode is in the KEYSTATE table, then stop all repeating.\n */\n if (Keyboard.KEYSTATES[simCode] && this.aKeysActive.length) {\n if (this.aKeysActive[0].nRepeat > 0) this.aKeysActive[0].nRepeat = 0;\n }\n\n var key;\n for (var i = 0; i < this.aKeysActive.length; i++) {\n key = this.aKeysActive[i];\n if (key.simCode == simCode) {\n /*\n * This key is already active, so if this a \"down\" request (or a \"press\" for a key we already\n * processed as a \"down\"), ignore it.\n */\n if (!fPress || key.nRepeat >= 0) {\n i = -1;\n break;\n }\n if (i > 0) {\n if (this.aKeysActive[0].nRepeat > 0) this.aKeysActive[0].nRepeat = 0;\n this.aKeysActive.splice(i, 1);\n }\n break;\n }\n }\n\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.KEY)) {\n this.printMessage(\"addActiveKey(\" + simCode + \",\" + (fPress? \"press\" : \"down\") + \"): \" + (i < 0? \"already active\" : (i == this.aKeysActive.length? \"adding\" : \"updating\")), true);\n }\n\n if (i < 0) return false;\n\n if (i == this.aKeysActive.length) {\n key = {simCode}; // create a new Key object\n // key.bitsState = this.bitsState; // not needed unless we revive checkActiveKeyShift()\n this.findBinding(simCode, \"key\", true);\n i++;\n }\n \n if (i > 0) {\n this.aKeysActive.splice(0, 0, key); // aka aKeysActive.unshift(key)\n }\n\n key.fDown = true;\n key.nRepeat = (fPress? -1: (Keyboard.KEYSTATES[simCode]? 0 : 1));\n\n this.updateActiveKey(key);\n return true;\n }\n\n /**\n * checkActiveKey()\n *\n * @this {Keyboard}\n * @return {number} simCode of active key, 0 if none\n */\n checkActiveKey()\n {\n return this.aKeysActive.length? this.aKeysActive[0].simCode : 0;\n }\n\n /**\n * isAlphaKey(code)\n *\n * @this {Keyboard}\n * @param {number} code\n * @returns {boolean} true if alpha key, false if not\n */\n isAlphaKey(code)\n {\n return (code >= Keys.ASCII.A && code <= Keys.ASCII.Z || code >= Keys.ASCII.a && code <= Keys.ASCII.z);\n }\n\n /**\n * toUpperKey(code)\n *\n * @this {Keyboard}\n * @param {number} code\n * @returns {number}\n */\n toUpperKey(code)\n {\n if (code >= Keys.ASCII.a && code <= Keys.ASCII.z) {\n code -= (Keys.ASCII.a - Keys.ASCII.A);\n }\n return code;\n }\n\n /**\n * clearActiveKeys(fModifiers)\n *\n * Force all active keys to \"deactivate\" (or, optionally, just any modifiers)\n *\n * @this {Keyboard}\n * @param {boolean} [fModifiers] (true to clear modifier keys only; default is ALL keys)\n */\n clearActiveKeys(fModifiers)\n {\n for (var i = 0; i < this.aKeysActive.length; i++) {\n var key = this.aKeysActive[i];\n if (fModifiers && !Keyboard.MODIFIERS[key.simCode]) continue;\n if (this.removeActiveKey(key.simCode)) i--;\n }\n }\n\n /**\n * removeActiveKey(simCode, fFlush)\n *\n * @param {number} simCode\n * @param {boolean} [fFlush] is true whenever the key must be removed, independent of other factors\n * @return {boolean} true if successfully removed, false if not\n */\n removeActiveKey(simCode, fFlush)\n {\n if (!Keyboard.SIMCODES[simCode]) {\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.KEY)) {\n this.printMessage(\"removeActiveKey(\" + simCode + \"): unrecognized\", true);\n }\n return false;\n }\n\n /*\n * Ignore all active keys if the CPU is not running.\n */\n if (!fFlush && (!this.cpu || !this.cpu.isRunning())) return false;\n\n var fRemoved = false;\n for (var i = 0; i < this.aKeysActive.length; i++) {\n var key = this.aKeysActive[i];\n if (key.simCode == simCode || key.simCode == Keys.SHIFTED_KEYCODES[simCode]) {\n this.aKeysActive.splice(i, 1);\n if (key.timer) clearTimeout(key.timer);\n if (key.fDown && !fFlush) this.keySimulate(key.simCode, false);\n this.findBinding(simCode, \"key\", false);\n fRemoved = true;\n break;\n }\n }\n if (!COMPILED && !fFlush && this.messageEnabled(Messages.KBD | Messages.KEY)) {\n this.printMessage(\"removeActiveKey(\" + simCode + \"): \" + (fRemoved? \"removed\" : \"not active\"), true);\n }\n if (!this.aKeysActive.length && this.fToggleCapsLock) {\n if (!COMPILED) this.printMessage(\"removeActiveKey(): inverting caps-lock now\", Messages.KBD | Messages.KEY);\n this.updateShiftState(Keyboard.SIMCODE.CAPS_LOCK);\n this.fToggleCapsLock = false;\n }\n return fRemoved;\n }\n\n /**\n * updateActiveKey(key, msTimer)\n *\n * When called by addActiveKey(), msTimer is undefined; that's used only when we're called by our own timeout handler.\n *\n * @param {Object} key\n * @param {number} [msTimer]\n */\n updateActiveKey(key, msTimer)\n {\n /*\n * All active keys are automatically removed once the CPU stops running.\n */\n if (!this.cpu || !this.cpu.isRunning()) {\n this.removeActiveKey(key.simCode, true);\n return;\n }\n\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.KEY)) {\n this.printMessage(\"updateActiveKey(\" + key.simCode + (msTimer? \",\" + msTimer + \"ms\" : \"\") + \"): \" + (key.fDown? \"down\" : \"up\"), true);\n }\n\n if (msTimer && key.nRepeat < 0) {\n key.fDown = false;\n }\n \n if (!this.keySimulate(key.simCode, key.fDown) || !key.nRepeat) {\n /*\n * Why isn't there a simple return here? In order to set breakpoints on two different return conditions, of course!\n */\n if (!msTimer) {\n return;\n }\n return;\n }\n\n var ms;\n if (key.nRepeat < 0) {\n if (!key.fDown) {\n this.removeActiveKey(key.simCode);\n return;\n }\n ms = this.msAutoRelease;\n }\n else {\n ms = (key.nRepeat++ == 1? this.msAutoRepeat : this.msNextRepeat);\n }\n \n if (key.timer) {\n clearTimeout(key.timer);\n }\n \n key.timer = setTimeout(function(kbd) {\n return function onUpdateActiveKey() {\n kbd.updateActiveKey(key, ms);\n };\n }(this), ms);\n }\n\n /**\n * getSimCode(keyCode)\n *\n * @this {Keyboard}\n * @param {number} keyCode\n * @param {boolean} fShifted\n * @return {number} simCode\n */\n getSimCode(keyCode, fShifted)\n {\n var code;\n var simCode = keyCode;\n\n if (keyCode >= Keys.ASCII.A && keyCode <= Keys.ASCII.Z) {\n if (!(this.bitsState & (Keyboard.STATE.SHIFT | Keyboard.STATE.RSHIFT | Keyboard.STATE.CAPS_LOCK)) == fShifted) {\n simCode = keyCode + (Keys.ASCII.a - Keys.ASCII.A);\n }\n }\n else if (keyCode >= Keys.ASCII.a && keyCode <= Keys.ASCII.z) {\n if (!!(this.bitsState & (Keyboard.STATE.SHIFT | Keyboard.STATE.RSHIFT | Keyboard.STATE.CAPS_LOCK)) == fShifted) {\n simCode = keyCode - (Keys.ASCII.a - Keys.ASCII.A);\n }\n }\n else if (!!(this.bitsState & (Keyboard.STATE.SHIFT | Keyboard.STATE.RSHIFT)) == fShifted) {\n if (code = Keys.SHIFTED_KEYCODES[keyCode]) {\n simCode = code;\n }\n }\n else {\n if (code = Keys.NONASCII_KEYCODES[keyCode]) {\n simCode = code;\n }\n }\n return simCode;\n }\n\n /**\n * onFocusChange(fFocus)\n *\n * @this {Keyboard}\n * @param {boolean} fFocus is true if gaining focus, false if losing it\n */\n onFocusChange(fFocus)\n {\n if (!COMPILED && this.fHasFocus != fFocus && this.messageEnabled(Messages.EVENT)) {\n this.printMessage(\"onFocusChange(\" + (fFocus? \"true\" : \"false\") + \")\", true);\n }\n this.fHasFocus = fFocus;\n /*\n * Since we can't be sure of any shift states after losing focus, we clear them all.\n */\n if (!fFocus) {\n this.bitsState &= ~Keyboard.STATE.ALL_MODIFIERS;\n this.clearActiveKeys(true);\n }\n }\n\n /**\n * onKeyChange(event, fDown)\n *\n * @this {Keyboard}\n * @param {Object} event\n * @param {boolean} fDown is true for a keyDown event, false for a keyUp event\n * @return {boolean} true to pass the event along, false to consume it\n */\n onKeyChange(event, fDown)\n {\n var fPass = true;\n var fPress = false;\n var fIgnore = false;\n var keyCode = event.keyCode;\n\n if (!this.cmp.notifyKbdEvent(event, fDown)) {\n return false;\n }\n \n if (fDown) this.cKeysPressed++;\n this.sInjectBuffer = \"\"; // actual key events should stop any injection in progress\n Component.processScript(this.idMachine); // and any script, too\n\n /*\n * Although it would be nice to pay attention ONLY to these \"up\" and \"down\" events, and ignore \"press\"\n * events, iOS devices force us to process \"press\" events, because they don't give us shift-key events,\n * so we have to infer the shift state from the character code in the \"press\" event.\n *\n * So, to seamlessly blend \"up\" and \"down\" events with \"press\" events, we must convert any keyCodes we\n * receive here to a compatibly shifted simCode.\n */\n var simCode = this.getSimCode(keyCode, true);\n\n if (this.fEscapeDisabled && simCode == Keys.ASCII['`']) {\n keyCode = simCode = Keys.KEYCODE.ESC;\n }\n\n if (Keyboard.SIMCODES[keyCode + Keys.KEYCODE.ONDOWN]) {\n\n simCode += Keys.KEYCODE.ONDOWN;\n if (event.location == Keys.LOCATION.RIGHT) {\n simCode += Keys.KEYCODE.ONRIGHT;\n }\n\n var nShiftState = this.updateShiftState(simCode, false, fDown);\n if (nShiftState) {\n\n if (keyCode == Keys.KEYCODE.CAPS_LOCK || keyCode == Keys.KEYCODE.NUM_LOCK || keyCode == Keys.KEYCODE.SCROLL_LOCK) {\n /*\n * FYI, \"lock\" keys generate a DOWN event ONLY when getting locked and an UP event ONLY\n * when getting unlocked--which is a little odd, since the key did go UP and DOWN each time.\n *\n * We must treat each event like a \"down\", and also as a \"press\", so that addActiveKey() will\n * automatically generate both the \"make\" and \"break\".\n *\n * Of course, there have to be exceptions, most notably both Microsoft Internet Explorer and Edge\n * (and, apparently, pretty much any other browser running on the Windows platform), which send both\n * UP and DOWN events on every press, so there's no need for this trickery.\n */\n if (!this.fMSWindows) {\n fDown = fPress = true;\n }\n }\n \n /*\n * HACK for Windows (as the host operating system): the ALT key is often used with key combinations\n * not meant for our machine (eg, Alt-Tab to switch to a different window, or simply tapping the ALT\n * key by itself to switch focus to the browser's menubar). And sadly, browsers are quite happy to\n * give us the DOWN event for the ALT key, but not an UP event, leaving our machine with the impression\n * that the ALT key is still down, which the user user has no easy way to detect OR correct.\n * \n * So we still record the ALT state in bitsState as best we can, and clear it whenever we lose focus\n * in onFocusChange(), but we no longer pass through DOWN events to our machine. Instead, we now\n * check bitsState prior to simulating any other key, and if the ALT bit is set, we simulate an\n * active ALT key first; you'll find that check at the end of both onKeyChange() and onKeyPress().\n * \n * NOTE: Even though this is a hack intended largely for browsers running on Windows, I'm implementing\n * it for all platforms, for consistency.\n */\n if (keyCode == Keys.KEYCODE.ALT) {\n if (fDown) {\n /*\n * One exception to this hack is the \"Sidekick\" exception: if the CTRL key is also down,\n * we'll still simulate ALT immediately, for those users who press CTRL and then ALT to pop up\n * Sidekick (as opposed to pressing ALT and then CTRL, which should also work, regardless).\n */\n if (!(this.bitsState & Keyboard.STATE.CTRL)) fIgnore = true;\n /*\n * Reset cKeysPressed so that we can detect the mere \"tapping\" of the ALT key, which some PCjs\n * demos depend on (eg, Multi-tasking MS-DOS 4.0).\n */\n this.cKeysPressed = 0;\n }\n else {\n if (!this.cKeysPressed) {\n /*\n * Since cKeysPressed is zero, the assumption here is that the ALT key (and the Alt key ALONE)\n * was just tapped, so as long the ALT key was not already \"soft-locked\" (based on bitsStateSim),\n * we will transform this \"up\" event into a \"fake press\" event. \n */\n if (!(this.bitsStateSim & (Keyboard.STATE.ALT | Keyboard.STATE.RALT))) {\n fDown = fPress = true;\n }\n }\n }\n }\n \n /*\n * As a safeguard, whenever the CMD key goes up, clear all active keys, because there appear to be\n * cases where we don't always get notification of a CMD key's companion key going up (this probably\n * overlaps with most if not all situations where we also lose focus).\n */\n if (!fDown && (keyCode == Keys.KEYCODE.CMD || keyCode == Keys.KEYCODE.RCMD)) {\n this.clearActiveKeys();\n }\n }\n else {\n /*\n * Here we have all the non-shift keys in the ONDOWN category; eg, BS, TAB, ESC, UP, DOWN, LEFT, RIGHT,\n * and many more.\n *\n * For various reasons (some of which are discussed below), we don't want to pass these on (ie, we want\n * to suppress their \"press\" event), which means we must perform all key simulation on the \"up\" and \"down\"\n * events.\n *\n * Regarding BS: I never want the browser to act on BS, since it does double-duty as the BACK button,\n * leaving the current page.\n *\n * Regarding TAB: If I don't consume TAB on the \"down\" event, then that's all I'll see, because the browser\n * acts on it by giving focus to the next control.\n *\n * Regarding ESC: This key generates \"down\" and \"up\" events (LOTS of \"down\" events for that matter), but no\n * \"press\" event.\n */\n\n /*\n * HACKs for mapping CTRL-BACKSPACE and CTRL-ALT-BACKSPACE to CTRL-BREAK and CTRL-ALT-DEL, respectively.\n */\n if (keyCode == Keys.KEYCODE.BS && (this.bitsState & (Keyboard.STATE.CTRL|Keyboard.STATE.ALT)) == Keyboard.STATE.CTRL) {\n simCode = Keyboard.SIMCODE.CTRL_BREAK;\n }\n if (keyCode == Keys.KEYCODE.BS && (this.bitsState & (Keyboard.STATE.CTRL|Keyboard.STATE.ALT)) == (Keyboard.STATE.CTRL|Keyboard.STATE.ALT)) {\n simCode = Keyboard.SIMCODE.CTRL_ALT_DEL;\n }\n\n /*\n * There are a number of other common key sequences that interfere with our machines; for example,\n * the up/down arrows have a \"default\" behavior of scrolling the web page up and down, which is\n * definitely NOT a behavior we want. Since we mark those keys as ONDOWN, we'll catch them all here.\n */\n fPass = false;\n }\n }\n else {\n /*\n * HACKs for mapping assorted CTRL-ALT sequences involving \"normal\" keys (eg, PERIOD, EQUALS, and DASH).\n */\n if ((this.bitsState & (Keyboard.STATE.CTRL|Keyboard.STATE.ALT)) == (Keyboard.STATE.CTRL|Keyboard.STATE.ALT)) {\n if (keyCode == Keys.KEYCODE.PERIOD) {\n simCode = Keyboard.SIMCODE.CTRL_ALT_DEL; // in case your operating system won't let you type CTRL-ALT-BACKSPACE either\n }\n if (keyCode == Keys.KEYCODE.EQUALS) {\n simCode = Keyboard.SIMCODE.CTRL_ALT_ADD; // in case your keyboard doesn't have a numeric keypad '+'\n }\n else if (keyCode == Keys.KEYCODE.DASH) {\n simCode = Keyboard.SIMCODE.CTRL_ALT_SUB; // in case your keyboard doesn't have a numeric keypad '-'\n }\n }\n \n /*\n * When I have defined system-wide CTRL-key sequences to perform common editing operations (eg, CTRL_W\n * and CTRL_Z to scroll pages of text), the browser likes to act on those operations, so let's set fPass\n * to false to prevent that.\n *\n * Also, we don't want to set fIgnore in such cases, because the browser may not give us a press event for\n * these CTRL-key sequences, so we can't risk ignoring them.\n */\n if (Keyboard.SIMCODES[simCode] && (this.bitsState & (Keyboard.STATE.CTRLS | Keyboard.STATE.ALTS))) {\n fPass = false;\n }\n\n /*\n * Don't simulate any key not explicitly marked ONDOWN, as well as any key sequence with the CMD key held.\n */\n if (!this.fAllDown && fPass && fDown || (this.bitsState & Keyboard.STATE.CMDS)) {\n fIgnore = true;\n }\n }\n\n if (!fPass) {\n event.preventDefault();\n }\n\n if (this.messageEnabled(Messages.EVENT | Messages.KEY)) {\n this.printMessage(\"onKeyChange(\" + keyCode + \"): \" + (fDown? \"down\" : \"up\") + (fIgnore? \",ignore\" : (fPass? \"\" : \",consume\")), true);\n }\n\n /*\n * Mobile (eg, iOS) keyboards don't fully support onkeydown/onkeyup events; for example, they usually\n * don't generate ANY events when a shift key is pressed, and even for normal keys, they seem to generate\n * rapid (ie, fake) \"up\" and \"down\" events around \"press\" events, probably more to satisfy compatibility\n * issues rather than making a serious effort to indicate when a key ACTUALLY went down or up.\n */\n if (!fIgnore && (!this.fMobile || !fPass)) {\n if (fDown) {\n /*\n * This is the companion code to the onKeyChange() hack for Windows that suppresses DOWN events\n * for ALT keys: if we're about to activate another key and we believe that an ALT key is still down,\n * we fake an ALT activation first. \n */\n if (this.bitsState & Keyboard.STATE.ALTS) {\n var simCodeAlt = Keyboard.SIMCODE.ALT;\n this.printMessage(\"onKeyChange(\" + simCodeAlt + \"): simulating ALT down\", Messages.EVENT);\n this.addActiveKey(simCodeAlt);\n }\n this.addActiveKey(simCode, fPress);\n } else {\n if (!this.removeActiveKey(simCode)) {\n var code = this.getSimCode(keyCode, false);\n if (code != simCode) this.removeActiveKey(code);\n }\n }\n }\n\n return fPass;\n }\n\n /**\n * onKeyPress(event)\n *\n * @this {Keyboard}\n * @param {Object} event\n * @return {boolean} true to pass the event along, false to consume it\n */\n onKeyPress(event)\n {\n event = event || window.event;\n var keyCode = event.which || event.keyCode;\n\n if (!this.cmp.notifyKbdEvent(event)) {\n return false;\n }\n\n this.cKeysPressed++;\n this.sInjectBuffer = \"\"; // actual key events should stop any injection currently in progress\n\n if (this.fAllDown) {\n var simCode = this.checkActiveKey();\n if (simCode && this.isAlphaKey(simCode) && this.isAlphaKey(keyCode) && simCode != keyCode) {\n if (!COMPILED && this.messageEnabled(Messages.EVENT | Messages.KEY)) {\n this.printMessage(\"onKeyPress(\" + keyCode + \") out of sync with \" + simCode + \", invert caps-lock\", true);\n }\n this.fToggleCapsLock = true;\n keyCode = simCode;\n }\n }\n\n var fPass = !Keyboard.SIMCODES[keyCode] || !!(this.bitsState & Keyboard.STATE.CMD);\n\n if (this.messageEnabled(Messages.EVENT | Messages.KEY)) {\n this.printMessage(\"onKeyPress(\" + keyCode + \"): \" + (fPass? \"true\" : \"false\"), true);\n }\n\n if (!fPass) {\n /*\n * This is the companion code to the onKeyChange() hack for Windows that suppresses DOWN events\n * for ALT keys: if we're about to activate another key and we believe that an ALT key is still down,\n * we fake an ALT activation first.\n */\n if (this.bitsState & Keyboard.STATE.ALTS) {\n var simCodeAlt = Keyboard.SIMCODE.ALT;\n this.printMessage(\"onKeyPress(\" + simCodeAlt + \"): simulating ALT down\", Messages.EVENT);\n this.addActiveKey(simCodeAlt);\n }\n this.addActiveKey(keyCode, true);\n }\n\n return fPass;\n }\n\n /**\n * keySimulate(simCode, fDown)\n *\n * @this {Keyboard}\n * @param {number} simCode\n * @param {boolean} fDown\n * @return {boolean} true if successfully simulated, false if unrecognized/unsupported key\n */\n keySimulate(simCode, fDown)\n {\n var fSimulated = false;\n\n this.updateShiftState(simCode, true, fDown);\n\n var wCode = Keyboard.SIMCODES[simCode] || Keyboard.SIMCODES[simCode + Keys.KEYCODE.ONDOWN];\n\n if (wCode !== undefined) {\n\n var abScanCodes = [];\n var bCode = wCode & 0xff;\n\n /*\n * TODO: Update the following restrictions to address 84-key and 101-key keyboard limitations.\n */\n if (bCode > 83 && this.modelKeys == 83) {\n return false;\n }\n\n abScanCodes.push(bCode | (fDown? 0 : Keyboard.SCANCODE.BREAK));\n\n var fAlpha = (simCode >= Keys.ASCII.A && simCode <= Keys.ASCII.Z || simCode >= Keys.ASCII.a && simCode <= Keys.ASCII.z);\n\n while (wCode >>>= 8) {\n var bShift = 0;\n var bScan = wCode & 0xff;\n /*\n * TODO: The handling of SIMCODE entries with \"extended\" codes still needs to be tested, and\n * moreover, if any of them need to perform any shift-state modifications, those modifications\n * may need to be encoded differently.\n */\n if (bCode == Keyboard.SCANCODE.EXTEND1 || bCode == Keyboard.SCANCODE.EXTEND2) {\n abScanCodes.push(bCode | (fDown? 0 : Keyboard.SCANCODE.BREAK));\n continue;\n }\n if (bScan == Keyboard.SCANCODE.SHIFT) {\n if (!(this.bitsStateSim & (Keyboard.STATE.SHIFT | Keyboard.STATE.RSHIFT))) {\n if (!(this.bitsStateSim & Keyboard.STATE.CAPS_LOCK) || !fAlpha) {\n bShift = bScan;\n }\n }\n } else if (bScan == Keyboard.SCANCODE.CTRL) {\n if (!(this.bitsStateSim & (Keyboard.STATE.CTRL | Keyboard.STATE.RCTRL))) {\n bShift = bScan;\n }\n } else if (bScan == Keyboard.SCANCODE.ALT) {\n if (!(this.bitsStateSim & (Keyboard.STATE.ALT | Keyboard.STATE.RALT))) {\n bShift = bScan;\n }\n } else {\n abScanCodes.push(bCode | (fDown? 0 : Keyboard.SCANCODE.BREAK));\n\n }\n if (bShift) {\n if (fDown)\n abScanCodes.unshift(bShift);\n else\n abScanCodes.push(bShift | Keyboard.SCANCODE.BREAK);\n }\n }\n\n for (var i = 0; i < abScanCodes.length; i++) {\n this.addScanCode(abScanCodes[i]);\n }\n\n fSimulated = true;\n }\n\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.KEY)) {\n this.printMessage(\"keySimulate(\" + simCode + \",\" + (fDown? \"down\" : \"up\") + \"): \" + (fSimulated? \"true\" : \"false\"), true);\n }\n\n return fSimulated;\n }\n\n /**\n * checkActiveKeyShift()\n *\n * @this {Keyboard}\n * @return {number|null} bitsState for active key, null if none\n *\n checkActiveKeyShift()\n {\n return this.aKeysActive.length? this.aKeysActive[0].bitsState : null;\n }\n */\n\n /**\n * Keyboard.init()\n *\n * This function operates on every HTML element of class \"keyboard\", extracting the\n * JSON-encoded parameters for the Keyboard constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Keyboard component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeKbd = Component.getElementsByClass(document, PCX86.APPCLASS, \"keyboard\");\n for (var iKbd = 0; iKbd < aeKbd.length; iKbd++) {\n var eKbd = aeKbd[iKbd];\n var parmsKbd = Component.getComponentParms(eKbd);\n var kbd = new Keyboard(parmsKbd);\n Component.bindComponentControls(kbd, eKbd, PCX86.APPCLASS);\n }\n }\n}\n\n/*\n * Supported keyboard models (the first entry is the default if the specified model isn't recognized)\n */\nKeyboard.MODELS = [\"US83\", \"US84\", \"US101\"];\n\nKeyboard.SIMCODE = {\n BS: Keys.KEYCODE.BS + Keys.KEYCODE.ONDOWN,\n TAB: Keys.KEYCODE.TAB + Keys.KEYCODE.ONDOWN,\n SHIFT: Keys.KEYCODE.SHIFT + Keys.KEYCODE.ONDOWN,\n RSHIFT: Keys.KEYCODE.SHIFT + Keys.KEYCODE.ONDOWN + Keys.KEYCODE.ONRIGHT,\n CTRL: Keys.KEYCODE.CTRL + Keys.KEYCODE.ONDOWN,\n ALT: Keys.KEYCODE.ALT + Keys.KEYCODE.ONDOWN,\n RALT: Keys.KEYCODE.ALT + Keys.KEYCODE.ONDOWN + Keys.KEYCODE.ONRIGHT,\n CAPS_LOCK: Keys.KEYCODE.CAPS_LOCK + Keys.KEYCODE.ONDOWN,\n ESC: Keys.KEYCODE.ESC + Keys.KEYCODE.ONDOWN,\n /*\n * It seems that a recent change to Safari on iOS (first noticed in iOS 9.1) treats SPACE\n * differently now, at least with regard to <textarea> controls, and possibly only readonly\n * or hidden controls, like the hidden <textarea> we overlay on the Video <canvas> element.\n *\n * Whatever the exact criteria are, Safari on iOS now performs SPACE's default behavior\n * after the onkeydown event but before the onkeypress event. So we must now process SPACE\n * as an ONDOWN key, so that we can call preventDefault() and properly simulate the key at\n * the time the key goes down.\n */\n SPACE: Keys.KEYCODE.SPACE + Keys.KEYCODE.ONDOWN,\n F1: Keys.KEYCODE.F1 + Keys.KEYCODE.ONDOWN,\n F2: Keys.KEYCODE.F2 + Keys.KEYCODE.ONDOWN,\n F3: Keys.KEYCODE.F3 + Keys.KEYCODE.ONDOWN,\n F4: Keys.KEYCODE.F4 + Keys.KEYCODE.ONDOWN,\n F5: Keys.KEYCODE.F5 + Keys.KEYCODE.ONDOWN,\n F6: Keys.KEYCODE.F6 + Keys.KEYCODE.ONDOWN,\n F7: Keys.KEYCODE.F7 + Keys.KEYCODE.ONDOWN,\n F8: Keys.KEYCODE.F8 + Keys.KEYCODE.ONDOWN,\n F9: Keys.KEYCODE.F9 + Keys.KEYCODE.ONDOWN,\n F10: Keys.KEYCODE.F10 + Keys.KEYCODE.ONDOWN,\n F11: Keys.KEYCODE.F11 + Keys.KEYCODE.ONDOWN,\n F12: Keys.KEYCODE.F12 + Keys.KEYCODE.ONDOWN,\n NUM_LOCK: Keys.KEYCODE.NUM_LOCK + Keys.KEYCODE.ONDOWN,\n SCROLL_LOCK: Keys.KEYCODE.SCROLL_LOCK + Keys.KEYCODE.ONDOWN,\n PRTSC: Keys.KEYCODE.PRTSC + Keys.KEYCODE.ONDOWN,\n HOME: Keys.KEYCODE.HOME + Keys.KEYCODE.ONDOWN,\n UP: Keys.KEYCODE.UP + Keys.KEYCODE.ONDOWN,\n PGUP: Keys.KEYCODE.PGUP + Keys.KEYCODE.ONDOWN,\n LEFT: Keys.KEYCODE.LEFT + Keys.KEYCODE.ONDOWN,\n NUM_INS: Keys.KEYCODE.NUM_INS + Keys.KEYCODE.ONDOWN,\n NUM_END: Keys.KEYCODE.NUM_END + Keys.KEYCODE.ONDOWN,\n NUM_DOWN: Keys.KEYCODE.NUM_DOWN + Keys.KEYCODE.ONDOWN,\n NUM_PGDN: Keys.KEYCODE.NUM_PGDN + Keys.KEYCODE.ONDOWN,\n NUM_LEFT: Keys.KEYCODE.NUM_LEFT + Keys.KEYCODE.ONDOWN,\n NUM_CENTER: Keys.KEYCODE.NUM_CENTER + Keys.KEYCODE.ONDOWN,\n NUM_RIGHT: Keys.KEYCODE.NUM_RIGHT + Keys.KEYCODE.ONDOWN,\n NUM_HOME: Keys.KEYCODE.NUM_HOME + Keys.KEYCODE.ONDOWN,\n NUM_UP: Keys.KEYCODE.NUM_UP + Keys.KEYCODE.ONDOWN,\n NUM_PGUP: Keys.KEYCODE.NUM_PGUP + Keys.KEYCODE.ONDOWN,\n NUM_ADD: Keys.KEYCODE.NUM_ADD + Keys.KEYCODE.ONDOWN,\n NUM_SUB: Keys.KEYCODE.NUM_SUB + Keys.KEYCODE.ONDOWN,\n NUM_DEL: Keys.KEYCODE.NUM_DEL + Keys.KEYCODE.ONDOWN,\n RIGHT: Keys.KEYCODE.RIGHT + Keys.KEYCODE.ONDOWN,\n END: Keys.KEYCODE.END + Keys.KEYCODE.ONDOWN,\n DOWN: Keys.KEYCODE.DOWN + Keys.KEYCODE.ONDOWN,\n PGDN: Keys.KEYCODE.PGDN + Keys.KEYCODE.ONDOWN,\n INS: Keys.KEYCODE.INS + Keys.KEYCODE.ONDOWN,\n DEL: Keys.KEYCODE.DEL + Keys.KEYCODE.ONDOWN,\n CMD: Keys.KEYCODE.CMD + Keys.KEYCODE.ONDOWN,\n RCMD: Keys.KEYCODE.RCMD + Keys.KEYCODE.ONDOWN,\n FF_CMD: Keys.KEYCODE.FF_CMD + Keys.KEYCODE.ONDOWN,\n CTRL_A: Keys.ASCII.CTRL_A + Keys.KEYCODE.FAKE,\n CTRL_B: Keys.ASCII.CTRL_B + Keys.KEYCODE.FAKE,\n CTRL_C: Keys.ASCII.CTRL_C + Keys.KEYCODE.FAKE,\n CTRL_D: Keys.ASCII.CTRL_D + Keys.KEYCODE.FAKE,\n CTRL_E: Keys.ASCII.CTRL_E + Keys.KEYCODE.FAKE,\n CTRL_F: Keys.ASCII.CTRL_F + Keys.KEYCODE.FAKE,\n CTRL_G: Keys.ASCII.CTRL_G + Keys.KEYCODE.FAKE,\n CTRL_H: Keys.ASCII.CTRL_H + Keys.KEYCODE.FAKE,\n CTRL_I: Keys.ASCII.CTRL_I + Keys.KEYCODE.FAKE,\n CTRL_J: Keys.ASCII.CTRL_J + Keys.KEYCODE.FAKE,\n CTRL_K: Keys.ASCII.CTRL_K + Keys.KEYCODE.FAKE,\n CTRL_L: Keys.ASCII.CTRL_L + Keys.KEYCODE.FAKE,\n CTRL_M: Keys.ASCII.CTRL_M + Keys.KEYCODE.FAKE,\n CTRL_N: Keys.ASCII.CTRL_N + Keys.KEYCODE.FAKE,\n CTRL_O: Keys.ASCII.CTRL_O + Keys.KEYCODE.FAKE,\n CTRL_P: Keys.ASCII.CTRL_P + Keys.KEYCODE.FAKE,\n CTRL_Q: Keys.ASCII.CTRL_Q + Keys.KEYCODE.FAKE,\n CTRL_R: Keys.ASCII.CTRL_R + Keys.KEYCODE.FAKE,\n CTRL_S: Keys.ASCII.CTRL_S + Keys.KEYCODE.FAKE,\n CTRL_T: Keys.ASCII.CTRL_T + Keys.KEYCODE.FAKE,\n CTRL_U: Keys.ASCII.CTRL_U + Keys.KEYCODE.FAKE,\n CTRL_V: Keys.ASCII.CTRL_V + Keys.KEYCODE.FAKE,\n CTRL_W: Keys.ASCII.CTRL_W + Keys.KEYCODE.FAKE,\n CTRL_X: Keys.ASCII.CTRL_X + Keys.KEYCODE.FAKE,\n CTRL_Y: Keys.ASCII.CTRL_Y + Keys.KEYCODE.FAKE,\n CTRL_Z: Keys.ASCII.CTRL_Z + Keys.KEYCODE.FAKE,\n SYS_REQ: Keys.KEYCODE.ESC + Keys.KEYCODE.FAKE,\n CTRL_PAUSE: Keys.KEYCODE.NUM_LOCK + Keys.KEYCODE.FAKE,\n CTRL_BREAK: Keys.KEYCODE.SCROLL_LOCK + Keys.KEYCODE.FAKE,\n CTRL_ALT_DEL: Keys.KEYCODE.DEL + Keys.KEYCODE.FAKE,\n CTRL_ALT_INS: Keys.KEYCODE.INS + Keys.KEYCODE.FAKE,\n CTRL_ALT_ADD: Keys.KEYCODE.NUM_ADD + Keys.KEYCODE.FAKE,\n CTRL_ALT_SUB: Keys.KEYCODE.NUM_SUB + Keys.KEYCODE.FAKE,\n CTRL_ALT_ENTER: Keys.KEYCODE.NUM_CR + Keys.KEYCODE.FAKE\n};\n\n/*\n * Scan code constants\n */\nKeyboard.SCANCODE = {\n /* 0x01 */ ESC: 1,\n /* 0x02 */ ONE: 2,\n /* 0x03 */ TWO: 3,\n /* 0x04 */ THREE: 4,\n /* 0x05 */ FOUR: 5,\n /* 0x06 */ FIVE: 6,\n /* 0x07 */ SIX: 7,\n /* 0x08 */ SEVEN: 8,\n /* 0x09 */ EIGHT: 9,\n /* 0x0A */ NINE: 10,\n /* 0x0B */ ZERO: 11,\n /* 0x0C */ DASH: 12,\n /* 0x0D */ EQUALS: 13,\n /* 0x0E */ BS: 14,\n /* 0x0F */ TAB: 15,\n /* 0x10 */ Q: 16,\n /* 0x11 */ W: 17,\n /* 0x12 */ E: 18,\n /* 0x13 */ R: 19,\n /* 0x14 */ T: 20,\n /* 0x15 */ Y: 21,\n /* 0x16 */ U: 22,\n /* 0x17 */ I: 23,\n /* 0x18 */ O: 24,\n /* 0x19 */ P: 25,\n /* 0x1A */ LBRACK: 26,\n /* 0x1B */ RBRACK: 27,\n /* 0x1C */ ENTER: 28,\n /* 0x1D */ CTRL: 29,\n /* 0x1E */ A: 30,\n /* 0x1F */ S: 31,\n /* 0x20 */ D: 32,\n /* 0x21 */ F: 33,\n /* 0x22 */ G: 34,\n /* 0x23 */ H: 35,\n /* 0x24 */ J: 36,\n /* 0x25 */ K: 37,\n /* 0x26 */ L: 38,\n /* 0x27 */ SEMI: 39,\n /* 0x28 */ QUOTE: 40,\n /* 0x29 */ BQUOTE: 41,\n /* 0x2A */ SHIFT: 42,\n /* 0x2B */ BSLASH: 43,\n /* 0x2C */ Z: 44,\n /* 0x2D */ X: 45,\n /* 0x2E */ C: 46,\n /* 0x2F */ V: 47,\n /* 0x30 */ B: 48,\n /* 0x31 */ N: 49,\n /* 0x32 */ M: 50,\n /* 0x33 */ COMMA: 51,\n /* 0x34 */ PERIOD: 52,\n /* 0x35 */ SLASH: 53,\n /* 0x36 */ RSHIFT: 54,\n /* 0x37 */ PRTSC: 55, // unshifted '*'; becomes dedicated 'Print Screen' key on 101-key keyboards\n /* 0x38 */ ALT: 56,\n /* 0x39 */ SPACE: 57,\n /* 0x3A */ CAPS_LOCK: 58,\n /* 0x3B */ F1: 59,\n /* 0x3C */ F2: 60,\n /* 0x3D */ F3: 61,\n /* 0x3E */ F4: 62,\n /* 0x3F */ F5: 63,\n /* 0x40 */ F6: 64,\n /* 0x41 */ F7: 65,\n /* 0x42 */ F8: 66,\n /* 0x43 */ F9: 67,\n /* 0x44 */ F10: 68,\n /* 0x45 */ NUM_LOCK: 69,\n /* 0x46 */ SCROLL_LOCK: 70,\n /* 0x47 */ NUM_HOME: 71,\n /* 0x48 */ NUM_UP: 72,\n /* 0x49 */ NUM_PGUP: 73,\n /* 0x4A */ NUM_SUB: 74,\n /* 0x4B */ NUM_LEFT: 75,\n /* 0x4C */ NUM_CENTER: 76,\n /* 0x4D */ NUM_RIGHT: 77,\n /* 0x4E */ NUM_ADD: 78,\n /* 0x4F */ NUM_END: 79,\n /* 0x50 */ NUM_DOWN: 80,\n /* 0x51 */ NUM_PGDN: 81,\n /* 0x52 */ NUM_INS: 82,\n /* 0x53 */ NUM_DEL: 83,\n /* 0x54 */ SYS_REQ: 84, // 84-key keyboard only (simulated with 'alt'+'prtsc' on 101-key keyboards)\n /* 0x54 */ PAUSE: 84, // 101-key keyboard only\n /* 0x57 */ F11: 87,\n /* 0x58 */ F12: 88,\n /* 0x5B */ WIN: 91, // aka CMD\n /* 0x5C */ RWIN: 92,\n /* 0x5D */ MENU: 93, // aka CMD + ONRIGHT\n /* 0x7F */ MAKE: 127,\n /* 0x80 */ BREAK: 128,\n /* 0xE0 */ EXTEND1: 224,\n /* 0xE1 */ EXTEND2: 225\n};\n\n/**\n * These internal \"shift key\" states are used to indicate BOTH the physical shift-key states (in bitsState)\n * and the simulated shift-key states (in bitsStateSim). The LOCK keys are problematic in both cases: the\n * browsers give us no way to query the LOCK key states, so we can only infer them, and because they are \"soft\"\n * locks, the machine's notion of their state is subject to change at any time as well. Granted, the IBM PC\n * ROM BIOS will store its LOCK states in the ROM BIOS Data Area (@0040:0017), but that's just a BIOS convention.\n *\n * Also, because this is purely for internal use, don't make the mistake of thinking that these bits have any\n * connection to the ROM BIOS bits @0040:0017 (they don't). We emulate hardware, not ROMs.\n *\n * TODO: Consider taking notice of the ROM BIOS Data Area state anyway, even though I'd rather remain ROM-agnostic;\n * at the very least, it would help us keep our LOCK LEDs in sync with the machine's LOCK states. However, the LED\n * issue will be largely moot (at least for MODEL_5170 machines) once we add support for PC AT keyboard LED commands.\n *\n * Note that right-hand state bits are equal to the left-hand bits shifted right 1 bit; makes sense, \"right\"? ;-)\n *\n * @enum {number}\n */\nKeyboard.STATE = {\n RSHIFT: 0x0001,\n SHIFT: 0x0002,\n SHIFTS: 0x0003,\n RCTRL: 0x0004, // 101-key keyboard only\n CTRL: 0x0008,\n CTRLS: 0x000C,\n RALT: 0x0010, // 101-key keyboard only\n ALT: 0x0020,\n ALTS: 0x0030,\n RCMD: 0x0040, // 101-key keyboard only\n CMD: 0x0080, // 101-key keyboard only\n CMDS: 0x00C0,\n ALL_RIGHT: 0x0055, // RSHIFT | RCTRL | RALT | RCMD\n ALL_MODIFIERS: 0x00FF, // SHIFT | RSHIFT | CTRL | RCTRL | ALT | RALT | CMD | RCMD\n INSERT: 0x0100, // TODO: Placeholder (we currently have no notion of any \"insert\" states)\n CAPS_LOCK: 0x0200,\n NUM_LOCK: 0x0400,\n SCROLL_LOCK: 0x0800,\n ALL_LOCKS: 0x0E00 // CAPS_LOCK | NUM_LOCK | SCROLL_LOCK\n};\n\n/*\n * Maps KEYCODES of modifier keys to their corresponding (default) STATES bit above.\n */\nKeyboard.MODIFIERS = {\n [Keyboard.SIMCODE.RSHIFT]: Keyboard.STATE.RSHIFT,\n [Keyboard.SIMCODE.SHIFT]: Keyboard.STATE.SHIFT,\n [Keyboard.SIMCODE.CTRL]: Keyboard.STATE.CTRL,\n [Keyboard.SIMCODE.ALT]: Keyboard.STATE.ALT,\n [Keyboard.SIMCODE.RALT]: Keyboard.STATE.ALT,\n [Keyboard.SIMCODE.CMD]: Keyboard.STATE.CMD,\n [Keyboard.SIMCODE.RCMD]: Keyboard.STATE.RCMD,\n [Keyboard.SIMCODE.FF_CMD]: Keyboard.STATE.CMD\n};\n\n/*\n * Maps KEYCODES of all modifier and lock keys to their corresponding (default) STATES bit above.\n */\nKeyboard.KEYSTATES = {\n [Keyboard.SIMCODE.RSHIFT]: Keyboard.STATE.RSHIFT,\n [Keyboard.SIMCODE.SHIFT]: Keyboard.STATE.SHIFT,\n [Keyboard.SIMCODE.CTRL]: Keyboard.STATE.CTRL,\n [Keyboard.SIMCODE.ALT]: Keyboard.STATE.ALT,\n [Keyboard.SIMCODE.RALT]: Keyboard.STATE.ALT,\n [Keyboard.SIMCODE.CMD]: Keyboard.STATE.CMD,\n [Keyboard.SIMCODE.RCMD]: Keyboard.STATE.RCMD,\n [Keyboard.SIMCODE.FF_CMD]: Keyboard.STATE.CMD,\n [Keyboard.SIMCODE.CAPS_LOCK]: Keyboard.STATE.CAPS_LOCK,\n [Keyboard.SIMCODE.NUM_LOCK]: Keyboard.STATE.NUM_LOCK,\n [Keyboard.SIMCODE.SCROLL_LOCK]: Keyboard.STATE.SCROLL_LOCK\n};\n\n/*\n * Maps CLICKCODE (string) to SIMCODE (number).\n *\n * NOTE: Unlike SOFTCODES, CLICKCODES are upper-case and use underscores instead of dashes, so that this\n * and other components can reference them using \"dot\" property syntax; using upper-case merely adheres to\n * our convention for constants. setBinding() will automatically convert any incoming CLICKCODE bindings\n * that use lower-case and dashes to upper-case and underscores before performing property lookup.\n */\nKeyboard.CLICKCODES = {\n 'TAB': Keyboard.SIMCODE.TAB,\n 'ESC': Keyboard.SIMCODE.ESC,\n 'F1': Keyboard.SIMCODE.F1,\n 'F2': Keyboard.SIMCODE.F2,\n 'F3': Keyboard.SIMCODE.F3,\n 'F4': Keyboard.SIMCODE.F4,\n 'F5': Keyboard.SIMCODE.F5,\n 'F6': Keyboard.SIMCODE.F6,\n 'F7': Keyboard.SIMCODE.F7,\n 'F8': Keyboard.SIMCODE.F8,\n 'F9': Keyboard.SIMCODE.F9,\n 'F10': Keyboard.SIMCODE.F10,\n 'LEFT': Keyboard.SIMCODE.LEFT,\n 'UP': Keyboard.SIMCODE.UP,\n 'RIGHT': Keyboard.SIMCODE.RIGHT,\n 'DOWN': Keyboard.SIMCODE.DOWN,\n 'NUM_HOME': Keyboard.SIMCODE.HOME,\n 'NUM_END': Keyboard.SIMCODE.END,\n 'NUM_PGUP': Keyboard.SIMCODE.PGUP,\n 'NUM_PGDN': Keyboard.SIMCODE.PGDN,\n 'ALT': Keyboard.SIMCODE.ALT,\n 'SYS_REQ': Keyboard.SIMCODE.SYS_REQ,\n /*\n * These bindings are for convenience (common key combinations that can be bound to a single control)\n */\n 'CTRL_C': Keyboard.SIMCODE.CTRL_C,\n 'CTRL_PAUSE': Keyboard.SIMCODE.CTRL_PAUSE,\n 'CTRL_BREAK': Keyboard.SIMCODE.CTRL_BREAK,\n 'CTRL_ALT_DEL': Keyboard.SIMCODE.CTRL_ALT_DEL,\n 'CTRL_ALT_INS': Keyboard.SIMCODE.CTRL_ALT_INS,\n 'CTRL_ALT_ADD': Keyboard.SIMCODE.CTRL_ALT_ADD,\n 'CTRL_ALT_SUB': Keyboard.SIMCODE.CTRL_ALT_SUB,\n 'CTRL_ALT_ENTER': Keyboard.SIMCODE.CTRL_ALT_ENTER\n};\n\n/*\n * Maps SOFTCODE (string) to SIMCODE (number) -- which may be the same as KEYCODE for ASCII keys.\n *\n * We define identifiers for all possible keys, based on their primary (unshifted) character or function.\n * This also serves as a definition of all supported keys, making it possible to create full-featured\n * \"soft keyboards\".\n *\n * One exception to the (unshifted) rule above is 'prtsc': on the original IBM 83-key and 84-key keyboards,\n * its primary (unshifted) character was '*', but on 101-key keyboards, it became a separate key ('prtsc',\n * now labeled \"Print Screen\"), as did the num-pad '*' ('num-mul'), so 'prtsc' seems worthy of an exception\n * to the rule.\n *\n * On 83-key and 84-key keyboards, 'ctrl'+'num-lock' triggered a \"pause\" operation and 'ctrl'+'scroll-lock'\n * triggered a \"break\" operation.\n *\n * On 101-key keyboards, IBM decided to move both those special operations to a new 'pause' (\"Pause/Break\")\n * key, near the new dedicated 'prtsc' (\"Print Screen/SysRq\") key -- and to drop the \"e\" from \"Sys Req\".\n * Those keys behave as follows:\n *\n * When 'pause' is pressed alone, it generates 0xe1 0x1d 0x45 0xe1 0x9d 0xc5 on make (nothing on break),\n * which essentially simulates the make-and-break of the 'ctrl' and 'num-lock' keys (ignoring the 0xe1),\n * triggering a \"pause\" operation.\n *\n * When 'pause' is pressed with 'ctrl', it generates 0xe0 0x46 0xe0 0xc6 on make (nothing on break) and\n * does not repeat, which essentially simulates the make-and-break of 'scroll-lock', which, in conjunction\n * with the separate make-and-break of 'ctrl', triggers a \"break\" operation.\n *\n * When 'prtsc' is pressed alone, it generates 0xe0 0x2a 0xe0 0x37, simulating the make of both 'shift'\n * and 'prtsc'; when pressed with 'shift' or 'ctrl', it generates only 0xe0 0x37; and when pressed with\n * 'alt', it generates only 0x54 (to simulate 'sys-req').\n *\n * TODO: Implement the above behaviors, whenever we get around to actually supporting 101-key keyboards.\n *\n * All key identifiers must be quotable using single-quotes, because that's how components.xsl will encode them\n * *inside* the \"data-value\" attribute of the corresponding HTML control. Which, in turn, is why the single-quote\n * key is defined as 'quote' rather than \"'\". Similarly, if there was unshifted \"double-quote\" key, it could\n * not be called '\"', because components.xsl quotes the *entire* \"data-value\" attribute using double-quotes.\n *\n * The (commented) numbering of keys below is purely for my own reference. Two keys are deliberately numbered 84,\n * reflecting the fact that the 'sys-req' key was added to the 84-key keyboard but later dropped from the 101-key\n * keyboard (as a stand-alone key, that is).\n * \n * With the introduction of the PC AT and the 84-key keyboard, IBM developed a new key numbering scheme and\n * key code generation; the 8042 keyboard controller would then convert those key codes into the PC scan codes\n * defined by the older 83-key keyboard. That's a layer of complexity we currently bypass; instead, we continue\n * to convert browser key codes directly into PC scan codes, which is what our 8042 controller implementation\n * assumes we're doing.\n */\nKeyboard.SOFTCODES = {\n /* 1 */ 'esc': Keyboard.SIMCODE.ESC,\n /* 2 */ '1': Keys.ASCII['1'],\n /* 3 */ '2': Keys.ASCII['2'],\n /* 4 */ '3': Keys.ASCII['3'],\n /* 5 */ '4': Keys.ASCII['4'],\n /* 6 */ '5': Keys.ASCII['5'],\n /* 7 */ '6': Keys.ASCII['6'],\n /* 8 */ '7': Keys.ASCII['7'],\n /* 9 */ '8': Keys.ASCII['8'],\n /* 10 */ '9': Keys.ASCII['9'],\n /* 11 */ '0': Keys.ASCII['0'],\n /* 12 */ '-': Keys.ASCII['-'],\n /* 13 */ '=': Keys.ASCII['='],\n /* 14 */ 'bs': Keyboard.SIMCODE.BS,\n /* 15 */ 'tab': Keyboard.SIMCODE.TAB,\n /* 16 */ 'q': Keys.ASCII.q,\n /* 17 */ 'w': Keys.ASCII.w,\n /* 18 */ 'e': Keys.ASCII.e,\n /* 19 */ 'r': Keys.ASCII.r,\n /* 20 */ 't': Keys.ASCII.t,\n /* 21 */ 'y': Keys.ASCII.y,\n /* 22 */ 'u': Keys.ASCII.u,\n /* 23 */ 'i': Keys.ASCII.i,\n /* 24 */ 'o': Keys.ASCII.o,\n /* 25 */ 'p': Keys.ASCII.p,\n /* 26 */ '[': Keys.ASCII['['],\n /* 27 */ ']': Keys.ASCII[']'],\n /* 28 */ 'enter': Keys.KEYCODE.CR,\n /* 29 */ 'ctrl': Keyboard.SIMCODE.CTRL,\n /* 30 */ 'a': Keys.ASCII.a,\n /* 31 */ 's': Keys.ASCII.s,\n /* 32 */ 'd': Keys.ASCII.d,\n /* 33 */ 'f': Keys.ASCII.f,\n /* 34 */ 'g': Keys.ASCII.g,\n /* 35 */ 'h': Keys.ASCII.h,\n /* 36 */ 'j': Keys.ASCII.j,\n /* 37 */ 'k': Keys.ASCII.k,\n /* 38 */ 'l': Keys.ASCII.l,\n /* 39 */ ';': Keys.ASCII[';'],\n /* 40 */ 'quote': Keys.ASCII[\"'\"], // formerly \"squote\"\n /* 41 */ '`': Keys.ASCII['`'], // formerly \"bquote\"\n /* 42 */ 'shift': Keyboard.SIMCODE.SHIFT, // formerly \"lshift\"\n /* 43 */ '\\\\': Keys.ASCII['\\\\'], // formerly \"bslash\"\n /* 44 */ 'z': Keys.ASCII.z,\n /* 45 */ 'x': Keys.ASCII.x,\n /* 46 */ 'c': Keys.ASCII.c,\n /* 47 */ 'v': Keys.ASCII.v,\n /* 48 */ 'b': Keys.ASCII.b,\n /* 49 */ 'n': Keys.ASCII.n,\n /* 50 */ 'm': Keys.ASCII.m,\n /* 51 */ ',': Keys.ASCII[','],\n /* 52 */ '.': Keys.ASCII['.'],\n /* 53 */ '/': Keys.ASCII['/'],\n /* 54 */ 'right-shift': Keyboard.SIMCODE.RSHIFT, // formerly \"rshift\"\n /* 55 */ 'prtsc': Keyboard.SIMCODE.PRTSC, // unshifted '*'; becomes dedicated 'Print Screen' key on 101-key keyboards\n /* 56 */ 'alt': Keyboard.SIMCODE.ALT,\n /* 57 */ 'space': Keyboard.SIMCODE.SPACE,\n /* 58 */ 'caps-lock': Keyboard.SIMCODE.CAPS_LOCK,\n /* 59 */ 'f1': Keyboard.SIMCODE.F1,\n /* 60 */ 'f2': Keyboard.SIMCODE.F2,\n /* 61 */ 'f3': Keyboard.SIMCODE.F3,\n /* 62 */ 'f4': Keyboard.SIMCODE.F4,\n /* 63 */ 'f5': Keyboard.SIMCODE.F5,\n /* 64 */ 'f6': Keyboard.SIMCODE.F6,\n /* 65 */ 'f7': Keyboard.SIMCODE.F7,\n /* 66 */ 'f8': Keyboard.SIMCODE.F8,\n /* 67 */ 'f9': Keyboard.SIMCODE.F9,\n /* 68 */ 'f10': Keyboard.SIMCODE.F10,\n /* 69 */ 'num-lock': Keyboard.SIMCODE.NUM_LOCK,\n /* 70 */ 'scroll-lock': Keyboard.SIMCODE.SCROLL_LOCK, // TODO: 0xe046 on 101-key keyboards?\n \n /*\n * Yes, distinguishing keys 71 through 83 with the 'num-' prefix seems like overkill, but it was\n * intended to be future-proofing, for the day when we might eventually add support for 101-key keyboards,\n * because they have their own dedicated non-numeric-keypad versions of these keys (in other words, they\n * account for most of the bloat on the 101-key keyboard, a trend that more modern keyboards have gradually\n * been reversing).\n * \n * To offset 'num-' prefix overkill, injectKeys() allows SOFTCODES to be used with or without the prefix,\n * on the theory that key injection users won't really care precisely which version of the key is used.\n */\n \n /* 71 */ 'num-home': Keyboard.SIMCODE.HOME, // formerly \"home\"\n /* 72 */ 'num-up': Keyboard.SIMCODE.UP, // formerly \"up-arrow\"\n /* 73 */ 'num-pgup': Keyboard.SIMCODE.PGUP, // formerly \"page-up\"\n /* 74 */ 'num-sub': Keyboard.SIMCODE.NUM_SUB, // formerly \"num-minus\"\n /* 75 */ 'num-left': Keyboard.SIMCODE.LEFT, // formerly \"left-arrow\"\n /* 76 */ 'num-center': Keyboard.SIMCODE.NUM_CENTER, // formerly \"center\"\n /* 77 */ 'num-right': Keyboard.SIMCODE.RIGHT, // formerly \"right-arrow\"\n /* 78 */ 'num-add': Keyboard.SIMCODE.NUM_ADD, // formerly \"num-plus\"\n /* 79 */ 'num-end': Keyboard.SIMCODE.END, // formerly \"end\"\n /* 80 */ 'num-down': Keyboard.SIMCODE.DOWN, // formerly \"down-arrow\"\n /* 81 */ 'num-pgdn': Keyboard.SIMCODE.PGDN, // formerly \"page-down\"\n /* 82 */ 'num-ins': Keyboard.SIMCODE.INS, // formerly \"ins\"\n /* 83 */ 'num-del': Keyboard.SIMCODE.DEL, // formerly \"del\"\n /* 84 */ 'sys-req': Keyboard.SIMCODE.SYS_REQ // 84-key keyboard only (simulated with 'alt'+'prtsc' on 101-key keyboards)\n \n /*\n * If I ever add 101-key keyboard support (and it's not clear that I will), then the following entries\n * will have to be converted to SIMCODE indexes, and each SIMCODE index will need an entry in the SIMCODES\n * table that defines the appropriate SCANCODE(S); as this component has evolved, SOFTCODES are no longer\n * mapped directly to SCANCODES.\n */\n \n// /* 84 */ 'pause': Keyboard.SCANCODE.PAUSE, // 101-key keyboard only\n// /* 85 */ 'f11': Keyboard.SCANCODE.F11,\n// /* 86 */ 'f12': Keyboard.SCANCODE.F12,\n// /* 87 */ 'num-enter': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.ENTER << 8),\n// /* 88 */ 'right-ctrl': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.CTRL << 8),\n// /* 89 */ 'num-div': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.SLASH << 8),\n// /* 90 */ 'num-mul': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.PRTSC << 8),\n// /* 91 */ 'right-alt': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.ALT << 8),\n// /* 92 */ 'home': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.NUM_HOME << 8),\n// /* 93 */ 'up': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.NUM_UP << 8),\n// /* 94 */ 'pgup': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.NUM_PGUP << 8),\n// /* 95 */ 'left': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.NUM_LEFT << 8),\n// /* 96 */ 'right': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.NUM_RIGHT << 8),\n// /* 97 */ 'end': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.NUM_END << 8),\n// /* 98 */ 'down': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.NUM_DOWN << 8),\n// /* 99 */ 'pgdn': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.NUM_PGDN << 8),\n// /*100 */ 'ins': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.NUM_INS << 8),\n// /*101 */ 'del': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.NUM_DEL << 8),\n \n// /*102 */ 'win': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.WIN << 8),\n// /*103 */ 'right-win': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.RWIN << 8),\n// /*104 */ 'menu': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.MENU << 8)\n};\n\n/*\n * Maps \"soft-key\" definitions (above) of shift/modifier keys to their corresponding (default) STATES bit.\n */\nKeyboard.LEDSTATES = {\n 'caps-lock': Keyboard.STATE.CAPS_LOCK,\n 'num-lock': Keyboard.STATE.NUM_LOCK,\n 'scroll-lock': Keyboard.STATE.SCROLL_LOCK\n};\n\n/*\n * Maps SIMCODE (number) to SCANCODE (number(s)).\n *\n * This array is used by keySimulate() to lookup a given SIMCODE and convert it to a SCANCODE\n * (lower byte), plus any required shift key SCANCODES (upper bytes).\n *\n * Using keyCodes from keyPress events proved to be more robust than using keyCodes from keyDown and\n * keyUp events, in part because of differences in the way browsers generate the keyDown and keyUp events.\n * For example, Safari on iOS devices will not generate up/down events for shift keys, and for other keys,\n * the up/down events are usually generated after the actual press is complete, and in rapid succession.\n *\n * The other problem (which is more of a problem with keyboards like the C1P than any IBM keyboards) is\n * that the shift/modifier state for a character on the \"source\" keyboard may not match the shift/modifier\n * state for the same character on the \"target\" keyboard. And since this code is inherited from C1Pjs,\n * we've inherited the same solution: keySimulate() has the ability to \"undo\" any states in bitsState\n * that conflict with the state(s) required for the character in question.\n */\nKeyboard.SIMCODES = {\n [Keyboard.SIMCODE.ESC]: Keyboard.SCANCODE.ESC,\n [Keys.ASCII['1']]: Keyboard.SCANCODE.ONE,\n [Keys.ASCII['!']]: Keyboard.SCANCODE.ONE | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['2']]: Keyboard.SCANCODE.TWO,\n [Keys.ASCII['@']]: Keyboard.SCANCODE.TWO | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['3']]: Keyboard.SCANCODE.THREE,\n [Keys.ASCII['#']]: Keyboard.SCANCODE.THREE | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['4']]: Keyboard.SCANCODE.FOUR,\n [Keys.ASCII['$']]: Keyboard.SCANCODE.FOUR | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['5']]: Keyboard.SCANCODE.FIVE,\n [Keys.ASCII['%']]: Keyboard.SCANCODE.FIVE | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['6']]: Keyboard.SCANCODE.SIX,\n [Keys.ASCII['^']]: Keyboard.SCANCODE.SIX | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['7']]: Keyboard.SCANCODE.SEVEN,\n [Keys.ASCII['&']]: Keyboard.SCANCODE.SEVEN | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['8']]: Keyboard.SCANCODE.EIGHT,\n [Keys.ASCII['*']]: Keyboard.SCANCODE.EIGHT | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['9']]: Keyboard.SCANCODE.NINE,\n [Keys.ASCII['(']]: Keyboard.SCANCODE.NINE | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['0']]: Keyboard.SCANCODE.ZERO,\n [Keys.ASCII[')']]: Keyboard.SCANCODE.ZERO | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['-']]: Keyboard.SCANCODE.DASH,\n [Keys.ASCII['_']]: Keyboard.SCANCODE.DASH | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['=']]: Keyboard.SCANCODE.EQUALS,\n [Keys.ASCII['+']]: Keyboard.SCANCODE.EQUALS | (Keyboard.SCANCODE.SHIFT << 8),\n [Keyboard.SIMCODE.BS]: Keyboard.SCANCODE.BS,\n [Keyboard.SIMCODE.TAB]: Keyboard.SCANCODE.TAB,\n [Keys.ASCII.q]: Keyboard.SCANCODE.Q,\n [Keys.ASCII.Q]: Keyboard.SCANCODE.Q | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.w]: Keyboard.SCANCODE.W,\n [Keys.ASCII.W]: Keyboard.SCANCODE.W | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.e]: Keyboard.SCANCODE.E,\n [Keys.ASCII.E]: Keyboard.SCANCODE.E | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.r]: Keyboard.SCANCODE.R,\n [Keys.ASCII.R]: Keyboard.SCANCODE.R | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.t]: Keyboard.SCANCODE.T,\n [Keys.ASCII.T]: Keyboard.SCANCODE.T | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.y]: Keyboard.SCANCODE.Y,\n [Keys.ASCII.Y]: Keyboard.SCANCODE.Y | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.u]: Keyboard.SCANCODE.U,\n [Keys.ASCII.U]: Keyboard.SCANCODE.U | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.i]: Keyboard.SCANCODE.I,\n [Keys.ASCII.I]: Keyboard.SCANCODE.I | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.o]: Keyboard.SCANCODE.O,\n [Keys.ASCII.O]: Keyboard.SCANCODE.O | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.p]: Keyboard.SCANCODE.P,\n [Keys.ASCII.P]: Keyboard.SCANCODE.P | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['[']]: Keyboard.SCANCODE.LBRACK,\n [Keys.ASCII['{']]: Keyboard.SCANCODE.LBRACK | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII[']']]: Keyboard.SCANCODE.RBRACK,\n [Keys.ASCII['}']]: Keyboard.SCANCODE.RBRACK | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.KEYCODE.CR]: Keyboard.SCANCODE.ENTER,\n [Keyboard.SIMCODE.CTRL]: Keyboard.SCANCODE.CTRL,\n [Keys.ASCII.a]: Keyboard.SCANCODE.A,\n [Keys.ASCII.A]: Keyboard.SCANCODE.A | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.s]: Keyboard.SCANCODE.S,\n [Keys.ASCII.S]: Keyboard.SCANCODE.S | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.d]: Keyboard.SCANCODE.D,\n [Keys.ASCII.D]: Keyboard.SCANCODE.D | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.f]: Keyboard.SCANCODE.F,\n [Keys.ASCII.F]: Keyboard.SCANCODE.F | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.g]: Keyboard.SCANCODE.G,\n [Keys.ASCII.G]: Keyboard.SCANCODE.G | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.h]: Keyboard.SCANCODE.H,\n [Keys.ASCII.H]: Keyboard.SCANCODE.H | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.j]: Keyboard.SCANCODE.J,\n [Keys.ASCII.J]: Keyboard.SCANCODE.J | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.k]: Keyboard.SCANCODE.K,\n [Keys.ASCII.K]: Keyboard.SCANCODE.K | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.l]: Keyboard.SCANCODE.L,\n [Keys.ASCII.L]: Keyboard.SCANCODE.L | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII[';']]: Keyboard.SCANCODE.SEMI,\n [Keys.ASCII[':']]: Keyboard.SCANCODE.SEMI | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII[\"'\"]]: Keyboard.SCANCODE.QUOTE,\n [Keys.ASCII['\"']]: Keyboard.SCANCODE.QUOTE | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['`']]: Keyboard.SCANCODE.BQUOTE,\n [Keys.ASCII['~']]: Keyboard.SCANCODE.BQUOTE | (Keyboard.SCANCODE.SHIFT << 8),\n [Keyboard.SIMCODE.SHIFT]: Keyboard.SCANCODE.SHIFT,\n [Keys.ASCII['\\\\']]: Keyboard.SCANCODE.BSLASH,\n [Keys.ASCII['|']]: Keyboard.SCANCODE.BSLASH | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.z]: Keyboard.SCANCODE.Z,\n [Keys.ASCII.Z]: Keyboard.SCANCODE.Z | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.x]: Keyboard.SCANCODE.X,\n [Keys.ASCII.X]: Keyboard.SCANCODE.X | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.c]: Keyboard.SCANCODE.C,\n [Keys.ASCII.C]: Keyboard.SCANCODE.C | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.v]: Keyboard.SCANCODE.V,\n [Keys.ASCII.V]: Keyboard.SCANCODE.V | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.b]: Keyboard.SCANCODE.B,\n [Keys.ASCII.B]: Keyboard.SCANCODE.B | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.n]: Keyboard.SCANCODE.N,\n [Keys.ASCII.N]: Keyboard.SCANCODE.N | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.m]: Keyboard.SCANCODE.M,\n [Keys.ASCII.M]: Keyboard.SCANCODE.M | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII[',']]: Keyboard.SCANCODE.COMMA,\n [Keys.ASCII['<']]: Keyboard.SCANCODE.COMMA | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['.']]: Keyboard.SCANCODE.PERIOD,\n [Keys.ASCII['>']]: Keyboard.SCANCODE.PERIOD | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['/']]: Keyboard.SCANCODE.SLASH,\n [Keys.ASCII['?']]: Keyboard.SCANCODE.SLASH | (Keyboard.SCANCODE.SHIFT << 8),\n [Keyboard.SIMCODE.RSHIFT]: Keyboard.SCANCODE.RSHIFT,\n [Keyboard.SIMCODE.PRTSC]: Keyboard.SCANCODE.PRTSC,\n [Keyboard.SIMCODE.ALT]: Keyboard.SCANCODE.ALT,\n [Keyboard.SIMCODE.RALT]: Keyboard.SCANCODE.ALT,\n [Keyboard.SIMCODE.SPACE]: Keyboard.SCANCODE.SPACE,\n [Keyboard.SIMCODE.CAPS_LOCK]: Keyboard.SCANCODE.CAPS_LOCK,\n [Keyboard.SIMCODE.F1]: Keyboard.SCANCODE.F1,\n [Keyboard.SIMCODE.F2]: Keyboard.SCANCODE.F2,\n [Keyboard.SIMCODE.F3]: Keyboard.SCANCODE.F3,\n [Keyboard.SIMCODE.F4]: Keyboard.SCANCODE.F4,\n [Keyboard.SIMCODE.F5]: Keyboard.SCANCODE.F5,\n [Keyboard.SIMCODE.F6]: Keyboard.SCANCODE.F6,\n [Keyboard.SIMCODE.F7]: Keyboard.SCANCODE.F7,\n [Keyboard.SIMCODE.F8]: Keyboard.SCANCODE.F8,\n [Keyboard.SIMCODE.F9]: Keyboard.SCANCODE.F9,\n [Keyboard.SIMCODE.F10]: Keyboard.SCANCODE.F10,\n [Keyboard.SIMCODE.NUM_LOCK]: Keyboard.SCANCODE.NUM_LOCK,\n [Keyboard.SIMCODE.SCROLL_LOCK]: Keyboard.SCANCODE.SCROLL_LOCK,\n [Keyboard.SIMCODE.HOME]: Keyboard.SCANCODE.NUM_HOME,\n [Keyboard.SIMCODE.NUM_HOME]: Keyboard.SCANCODE.NUM_HOME,\n [Keyboard.SIMCODE.UP]: Keyboard.SCANCODE.NUM_UP,\n [Keyboard.SIMCODE.NUM_UP]: Keyboard.SCANCODE.NUM_UP,\n [Keyboard.SIMCODE.PGUP]: Keyboard.SCANCODE.NUM_PGUP,\n [Keyboard.SIMCODE.NUM_PGUP]: Keyboard.SCANCODE.NUM_PGUP,\n [Keyboard.SIMCODE.LEFT]: Keyboard.SCANCODE.NUM_LEFT,\n [Keyboard.SIMCODE.NUM_LEFT]: Keyboard.SCANCODE.NUM_LEFT,\n [Keyboard.SIMCODE.NUM_CENTER]: Keyboard.SCANCODE.NUM_CENTER,\n [Keyboard.SIMCODE.RIGHT]: Keyboard.SCANCODE.NUM_RIGHT,\n [Keyboard.SIMCODE.NUM_RIGHT]: Keyboard.SCANCODE.NUM_RIGHT,\n [Keyboard.SIMCODE.END]: Keyboard.SCANCODE.NUM_END,\n [Keyboard.SIMCODE.NUM_END]: Keyboard.SCANCODE.NUM_END,\n [Keyboard.SIMCODE.DOWN]: Keyboard.SCANCODE.NUM_DOWN,\n [Keyboard.SIMCODE.NUM_DOWN]: Keyboard.SCANCODE.NUM_DOWN,\n [Keyboard.SIMCODE.PGDN]: Keyboard.SCANCODE.NUM_PGDN,\n [Keyboard.SIMCODE.NUM_PGDN]: Keyboard.SCANCODE.NUM_PGDN,\n [Keyboard.SIMCODE.INS]: Keyboard.SCANCODE.NUM_INS,\n [Keyboard.SIMCODE.NUM_INS]: Keyboard.SCANCODE.NUM_INS,\n [Keyboard.SIMCODE.NUM_ADD]: Keyboard.SCANCODE.NUM_ADD,\n [Keyboard.SIMCODE.NUM_SUB]: Keyboard.SCANCODE.NUM_SUB,\n [Keyboard.SIMCODE.DEL]: Keyboard.SCANCODE.NUM_DEL,\n [Keyboard.SIMCODE.NUM_DEL]: Keyboard.SCANCODE.NUM_DEL,\n [Keyboard.SIMCODE.SYS_REQ]: Keyboard.SCANCODE.SYS_REQ,\n /*\n * Entries beyond this point are for keys that existed only on 101-key keyboards (well, except for 'sys-req',\n * which also existed on the 84-key keyboard), which ALSO means that these keys essentially did not exist\n * for a MODEL_5150 or MODEL_5160 machine, because those machines could use only 83-key keyboards. Remember\n * that IBM machines and IBM keyboards are our reference point here, so while there were undoubtedly 5150/5160\n * clones that could use newer keyboards, as well as 3rd-party keyboards that could work with older machines,\n * support for non-IBM configurations is left for another day.\n *\n * TODO: The only relevance of newer keyboards to older machines is the fact that you're probably using a newer\n * keyboard with your browser, which raises the question of what to do with newer keys that older machines\n * wouldn't understand. I don't attempt to filter out any of the entries below based on machine model, but that\n * would seem like a wise thing to do.\n *\n * TODO: Add entries for 'num-mul', 'num-div', 'num-enter', the stand-alone arrow keys, etc, AND at the same time,\n * make sure that keys with multi-byte sequences (eg, 0xe0 0x1c) work properly.\n */\n [Keyboard.SIMCODE.F11]: Keyboard.SCANCODE.F11,\n [Keyboard.SIMCODE.F12]: Keyboard.SCANCODE.F12,\n [Keyboard.SIMCODE.CMD]: Keyboard.SCANCODE.WIN,\n [Keyboard.SIMCODE.RCMD]: Keyboard.SCANCODE.MENU,\n [Keyboard.SIMCODE.FF_CMD]: Keyboard.SCANCODE.WIN,\n \n [Keyboard.SIMCODE.CTRL_A]: Keyboard.SCANCODE.A | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_B]: Keyboard.SCANCODE.B | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_C]: Keyboard.SCANCODE.C | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_D]: Keyboard.SCANCODE.D | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_E]: Keyboard.SCANCODE.E | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_F]: Keyboard.SCANCODE.F | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_G]: Keyboard.SCANCODE.G | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_H]: Keyboard.SCANCODE.H | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_I]: Keyboard.SCANCODE.I | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_J]: Keyboard.SCANCODE.J | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_K]: Keyboard.SCANCODE.K | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_L]: Keyboard.SCANCODE.L | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_M]: Keyboard.SCANCODE.M | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_N]: Keyboard.SCANCODE.N | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_O]: Keyboard.SCANCODE.O | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_P]: Keyboard.SCANCODE.P | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_Q]: Keyboard.SCANCODE.Q | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_R]: Keyboard.SCANCODE.R | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_S]: Keyboard.SCANCODE.S | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_T]: Keyboard.SCANCODE.T | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_U]: Keyboard.SCANCODE.U | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_V]: Keyboard.SCANCODE.V | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_W]: Keyboard.SCANCODE.W | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_X]: Keyboard.SCANCODE.X | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_Y]: Keyboard.SCANCODE.Y | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_Z]: Keyboard.SCANCODE.Z | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_BREAK]: Keyboard.SCANCODE.SCROLL_LOCK | (Keyboard.SCANCODE.CTRL << 8),\n \n [Keyboard.SIMCODE.CTRL_ALT_DEL]: Keyboard.SCANCODE.NUM_DEL | (Keyboard.SCANCODE.CTRL << 8) | (Keyboard.SCANCODE.ALT << 16),\n [Keyboard.SIMCODE.CTRL_ALT_INS]: Keyboard.SCANCODE.NUM_INS | (Keyboard.SCANCODE.CTRL << 8) | (Keyboard.SCANCODE.ALT << 16),\n [Keyboard.SIMCODE.CTRL_ALT_ADD]: Keyboard.SCANCODE.NUM_ADD | (Keyboard.SCANCODE.CTRL << 8) | (Keyboard.SCANCODE.ALT << 16),\n [Keyboard.SIMCODE.CTRL_ALT_SUB]: Keyboard.SCANCODE.NUM_SUB | (Keyboard.SCANCODE.CTRL << 8) | (Keyboard.SCANCODE.ALT << 16),\n [Keyboard.SIMCODE.CTRL_ALT_ENTER]: Keyboard.SCANCODE.ENTER | (Keyboard.SCANCODE.CTRL << 8) | (Keyboard.SCANCODE.ALT << 16)\n};\n\n/**\n * Commands that can be sent to the Keyboard via the 8042; see receiveCmd()\n *\n * Aside from the commands listed below, 0xEF-0xF2 and 0xF7-0xFD are expressly documented as NOPs; ie:\n *\n * These commands are reserved and are effectively no-operation or NOP. The system does not use these codes.\n * If sent, the keyboard will acknowledge the command and continue in its prior scanning state. No other\n * operation will occur.\n *\n * However, IBM's documentation is silent with regard to 0x00-0xEC. It's likely that most if not all of those\n * commands are NOPs as well.\n *\n * @enum {number}\n */\nKeyboard.CMD = {\n /*\n * RESET (0xFF)\n *\n * The system issues a RESET command to start a program reset and a keyboard internal self-test. The keyboard\n * acknowledges the command with an 'acknowledge' signal (ACK) and ensures the system accepts the ACK before\n * executing the command. The system signals acceptance of the ACK by raising the clock and data for a minimum\n * of 500 microseconds. The keyboard is disabled from the time it receives the RESET command until the ACK is\n * accepted or until another command overrides the previous one. Following acceptance of the ACK, the keyboard\n * begins the reset operation, which is similar to a power-on reset. The keyboard clears the output buffer and\n * sets up default values for typematic and delay rates.\n */\n RESET: 0xFF,\n\n /*\n * RESEND (0xFE)\n *\n * The system can send this command when it detects an error in any transmission from the keyboard. It can be\n * sent only after a keyboard transmission and before the system enables the interface to allow the next keyboard\n * output. Upon receipt of RESEND, the keyboard sends the previous output again unless the previous output was\n * RESEND. In this case, the keyboard will resend the last byte before the RESEND command.\n */\n RESEND: 0xFE,\n\n /*\n * SET DEFAULT (0xF6)\n *\n * The SET DEFAULT command resets all conditions to the power-on default state. The keyboard responds with ACK,\n * clears its output buffer, sets default conditions, and continues scanning (only if the keyboard was previously\n * enabled).\n */\n DEF_ON: 0xF6,\n\n /*\n * DEFAULT DISABLE (0xF5)\n *\n * This command is similar to SET DEFAULT, except the keyboard stops scanning and awaits further instructions.\n */\n DEF_OFF: 0xF5,\n\n /*\n * ENABLE (0xF4)\n *\n * Upon receipt of this command, the keyboard responds with ACK, clears its output buffer, and starts scanning.\n */\n ENABLE: 0xF4,\n\n /*\n * SET TYPEMATIC RATE/DELAY (0xF3)\n *\n * The system issues this command, followed by a parameter, to change the typematic rate and delay. The typematic\n * rate and delay parameters are determined by the value of the byte following the command. Bits 6 and 5 serve as\n * the delay parameter and bits 4,3,2, 1, and 0 (the least-significant bit) are the rate parameter. Bit 7, the\n * most-significant bit, is always 0. The delay is equal to 1 plus the binary value of bits 6 and 5 multiplied by\n * 250 milliseconds ±20%.\n */\n SET_RATE: 0xF3,\n\n /*\n * ECHO (0xEE)\n *\n * ECHO is a diagnostic aid. When the keyboard receives this command, it issues a 0xEE response and continues\n * scanning if the keyboard was previously enabled.\n */\n ECHO: 0xEE,\n\n /*\n * SET/RESET MODE INDICATORS (0xED)\n *\n * Three mode indicators on the keyboard are accessible to the system. The keyboard activates or deactivates\n * these indicators when it receives a valid command from the system. They can be activated or deactivated in\n * any combination.\n *\n * The system remembers the previous state of an indicator so that its setting does not change when a command\n * sequence is issued to change the state of another indicator.\n *\n * A SET/RESET MODE INDICATORS command consists of 2 bytes. The first is the command byte and has the following\n * bit setup:\n *\n * 11101101 - 0xED\n *\n * The second byte is an option byte. It has a list of the indicators to be acted upon. The bit assignments for\n * this option byte are as follows:\n *\n * Bit Indicator\n * --- ---------\n * 0 Scroll Lock Indicator\n * 1 Num Lock Indicator\n * 2 Caps Lock Indicator\n * 3-7 Reserved (must be 0's)\n *\n * NOTE: Bit 7 is the most-significant bit; bit 0 is the least-significant.\n *\n * The keyboard will respond to the set/reset mode indicators command with an ACK, discontinue scanning, and wait\n * for the option byte. The keyboard will respond to the option byte with an ACK, set the indicators, and continue\n * scanning if the keyboard was previously enabled. If another command is received in place of the option byte,\n * execution of the function of the SET/RESET MODE INDICATORS command is stopped with no change to the indicator\n * states, and the new command is processed. Then scanning is resumed.\n */\n SET_LEDS: 0xED\n};\n\n/**\n * Command responses returned to the Keyboard via the 8042; see receiveCmd()\n *\n * @enum {number}\n */\nKeyboard.CMDRES = {\n /*\n * OVERRUN (0x00)\n *\n * An overrun character is placed in position 17 of the keyboard buffer, overlaying the last code if the\n * buffer becomes full. The code is sent to the system as an overrun when it reaches the top of the buffer.\n */\n OVERRUN: 0x00,\n\n LOAD_TEST: 0x65, // undocumented \"LOAD MANUFACTURING TEST REQUEST\" response code\n\n /*\n * BAT Completion Code (0xAA)\n *\n * Following satisfactory completion of the BAT, the keyboard sends 0xAA. 0xFC (or any other code)\n * means the keyboard microprocessor check failed.\n */\n BAT_OK: 0xAA,\n\n /*\n * ECHO Response (0xEE)\n *\n * This is sent in response to an ECHO command (also 0xEE) from the system.\n */\n ECHO: 0xEE,\n\n /*\n * BREAK CODE PREFIX (0xF0)\n *\n * This code is sent as the first byte of a 2-byte sequence to indicate the release of a key.\n */\n BREAK_PREF: 0xF0,\n\n /*\n * ACK (0xFA)\n *\n * The keyboard issues an ACK response to any valid input other than an ECHO or RESEND command.\n * If the keyboard is interrupted while sending ACK, it will discard ACK and accept and respond\n * to the new command.\n */\n ACK: 0xFA,\n\n /*\n * BASIC ASSURANCE TEST FAILURE (0xFC)\n */\n BAT_FAIL: 0xFC, // TODO: Verify this response code (is this just for older 83-key keyboards?)\n\n /*\n * DIAGNOSTIC FAILURE (0xFD)\n *\n * The keyboard periodically tests the sense amplifier and sends a diagnostic failure code if it detects\n * any problems. If a failure occurs during BAT, the keyboard stops scanning and waits for a system command\n * or power-down to restart. If a failure is reported after scanning is enabled, scanning continues.\n */\n DIAG_FAIL: 0xFD,\n\n /*\n * RESEND (0xFE)\n *\n * The keyboard issues a RESEND command following receipt of an invalid input, or any input with incorrect parity.\n * If the system sends nothing to the keyboard, no response is required.\n */\n RESEND: 0xFE,\n\n BUFF_FULL: 0xFF // TODO: Verify this response code (is this just for older 83-key keyboards?)\n};\n\nKeyboard.LIMIT = {\n MAX_SCANCODES: 20 // TODO: Verify this limit for newer keyboards (84-key and up)\n};\n\nKeyboard.INJECTION = {\n NONE: 0,\n ON_START: 1,\n ON_INPUT: 2\n};\n\n/*\n * Initialize every Keyboard module on the page.\n */\nWeb.onInit(Keyboard.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/video.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * MDA/CGA Support\n * ---------------\n *\n * Since there's a lot of similarity between the MDA and CGA (eg, their text-mode video buffer\n * format, and their use of the 6845 CRT controller), since the MDA ROM contains the fonts used\n * by both devices, and since the same ROM BIOS supports both (in fact, the BIOS indiscriminately\n * initializes both, regardless which is actually installed), this same component emulates both\n * devices.\n *\n * When no model is specified, this component supports the ability to dynamically switch between\n * MDA and CGA emulation, by simply toggling the SW1 motherboard \"monitor type\" switch settings\n * and resetting the machine. In that model-less configuration, we install I/O port handlers for\n * both MDA and CGA cards, regardless which monitor type is initially selected.\n *\n * To simulate an IBM PC containing both an MDA and CGA (ie, a \"dual display\" system), the machine\n * configuration simply defines two video components, one with model \"mda\" and the other with model\n * \"cga\", resulting in two displays; setting a specific model forces each instance of this component\n * to register only those I/O ports belonging to that model.\n *\n * In a single-display system, dynamically switching cards (ie, between MDA and CGA) creates some\n * visual challenges. For one, the MDA prefers a native screen size of 720x350, as it supports only\n * one video mode, 80x25, with a 9x14 cell size. The CGA, on the other hand, has an 8x8 cell size,\n * so when using an MDA-size screen, an 80x25 CGA screen will end up with 40-pixel borders on the\n * left and right, and 75-pixel borders on the top and bottom. The result is a rather tiny CGA font\n * surrounded by lots of wasted space, so it's best to turn on font scaling (see the \"scale\" property)\n * and go with a larger screen size of, say, 960x400 (50% larger in width, 100% larger in height).\n *\n * I've also added support for font-doubling in createFont(). We use the 8x8 font for 80-column\n * modes and the \"doubled\" 16x16 font for 40-column modes OR whenever the screen is large enough\n * to use the 16x16 font, since font rendering without scaling provides the sharpest results.\n * In fact, there's special logic in setDimensions() to ignore fScaleFont in certain cases (eg,\n * 40-column modes, to improve sharpness and avoid stretching the font beyond readability).\n *\n * Graphics modes, on the other hand, are always scaled to the screen size. Pixels are captured\n * in an off-screen buffer, which is then drawn to match the size of the virtual screen.\n *\n * TODO: Whenever there are borders, they should be filled with the CGA's overscan colors. However,\n * in the case of graphics modes (and text modes whenever font scaling is enabled), we don't reserve\n * any space for borders, so if borders are important, explicit border support will be required.\n *\n * EGA Support\n * -----------\n *\n * EGA support piggy-backs on the existing MDA/CGA support. All the existing MDA/CGA port handlers\n * now refer to either cardMono or cardColor (instead of directly to cardMDA or cardCGA), enabling\n * the handlers to be redirected to cardMDA, cardCGA or cardEGA as appropriate.\n *\n * Note that an MDA card supported only a Monochrome Display and a CGA card supported only a Color\n * Display (well, OK, *or* a TV monitor, which we don't currently support), but the EGA is much\n * more flexible: the Enhanced Color Display was the preferred display, but the EGA also supported\n * older displays; a Color Display on EGA wasn't ideal (same low resolutions but with more colors),\n * but the EGA also brought high-resolution graphics to Monochrome displays, which was nice. Anyway,\n * while all those EGA/monitor combinations will be nice to support, our virtual display support\n * will focus initially on the Enhanced Color Display.\n *\n * TODO: Add support for jumpers P1 and P3 (see EGA TechRef p.85). P1 selects either 5-color-output\n * for a CGA monitor or 6-color-output for an EGA monitor; we would presumably use this only to\n * control certain assumptions about the virtual display's capabilities (ie, Color Display vs. Enhanced\n * Color Display). P3 can switch all the I/O ports from 0x3nn to 0x2nn; the default is 0x3nn, and\n * that's the only port range the EGA ROM supports as well.\n *\n * VGA Support\n * -----------\n *\n * VGA support further piggy-backs on the existing EGA support, by adding the extra registers, I/O port\n * handlers, etc, that the VGA requires; any differences in registers common to both EGA and VGA are handled on\n * a case-by-case basis, usually according to the Video.CARD value stored in nCard.\n * \n * More will be said here about PCjs VGA support later. But first, a word from IBM: \"Video Graphics Array [VGA]\n * Programming Considerations\":\n *\n * Certain internal timings must be guaranteed by the user, in order to have the CRTC perform properly.\n * This is due to the physical design of the chip. These timings can be guaranteed by ensuring that the\n * rules listed below are followed when programming the CRTC.\n *\n * 1. The Horizontal Total [HTOTAL] register (R0) must be greater than or equal to a value of\n * 25 decimal.\n *\n * 2. The minimum positive pulse width of the HSYNC output must be four character clock units.\n *\n * 3. Register R5, Horizontal Sync End [HREND], must be programmed such that the HSYNC\n * output goes to a logic 0 a minimum of one character clock time before the 'horizontal display enable'\n * signal goes to a logical 1.\n *\n * 4. Register R16, Vsync Start [VRSTART], must be a minimum of one horizontal scan line greater\n * than register R18 [VDEND]. Register R18 defines where the 'vertical display enable' signal ends.\n *\n * When bit 5 of the Attribute Mode Control register equals 1, a successful line compare (see Line Compare\n * [LINECOMP] register) in the CRT Controller forces the output of the PEL Panning register to 0's until Vsync\n * occurs. When Vsync occurs, the output returns to the programmed value. This allows the portion of the screen\n * indicated by the Line Compare register to be operated on by the PEL Panning register.\n *\n * A write to the Character Map Select register becomes valid on the next whole character line. No deformed\n * characters are displayed by changing character generators in the middle of a character scan line.\n *\n * For 256-color 320 x 200 graphics mode hex 13, the attribute controller is configured so that the 8-bit attribute\n * stored in video memory for each PEL becomes the 8-bit address (P0 - P7) into the integrated DAC. The user should\n * not modify the contents of the internal Palette registers when using this mode.\n *\n * The following sequence should be followed when accessing any of the Attribute Data registers pointed to by the\n * Attribute Index register:\n *\n * 1. Disable interrupts\n * 2. Reset read/write flip/flop\n * 3. Write to Index register\n * 4. Read from or write to a data register\n * 5. Enable interrupts\n *\n * The Color Select register in the Attribute Controller section may be used to rapidly switch between sets of colors\n * in the video DAC. When bit 7 of the Attribute Mode Control register equals 0, the 8-bit color value presented to the\n * video DAC is composed of 6 bits from the internal Palette registers and bits 2 and 3 from the Color Select register.\n * When bit 7 of the Attribute Mode Control register equals 1, the 8-bit color value presented to the video DAC is\n * composed of the lower four bits from the internal Palette registers and the four bits in the Color Select register.\n * By changing the value in the Color Select register, software rapidly switches between sets of colors in the video DAC.\n * Note that BIOS does not support multiple sets of colors in the video DAC. The user must load these colors if this\n * function is to be used. Also see the Attribute Controller block diagram on page 4-26. Note that the above discussion\n * applies to all modes except 256 Color Graphics mode. In this mode the Color Select register is not used to switch\n * between sets of colors.\n *\n * An application that saves the \"Video State\" must store the 4 bytes of information contained in the system microprocessor\n * latches in the graphics controller subsection. These latches are loaded with 32 bits from video memory (8 bits per map)\n * each time the system microprocessor does a read from video memory. The application needs to:\n *\n * 1. Use write mode 1 to write the values in the latches to a location in video memory that is not part of\n * the display buffer. The last location in the address range is a good choice.\n *\n * 2. Save the values of the latches by reading them back from video memory.\n *\n * Note: If in a chain 4 or odd/even mode, it will be necessary to reconfigure the memory organization as four\n * sequential maps prior to performing the sequence above. BIOS provides support for completely saving and\n * restoring video state. See the IBM Personal System/2 and Personal Computer BIOS Interface Technical Reference\n * for more information.\n *\n * The description of the Horizontal PEL Panning register includes a figure showing the number of PELs shifted left\n * for each valid value of the PEL Panning register and each valid video mode. Further panning beyond that shown in\n * the figure may be accomplished by changing the start address in the CRT Controller registers, Start Address High\n * and Start Address Low. The sequence involved in further panning would be as follows:\n *\n * 1. Use the PEL Panning register to shift the maximum number of bits to the left. See Figure 4-103 on page\n * 4-106 for the appropriate values.\n *\n * 2. Increment the start address.\n *\n * 3. If you are not using Modes 0 + , 1 + , 2 + , 3 + ,7, or7 + , set the PEL Panning register to 0. If you\n * are using these modes, set the PEL Panning register to 8. The screen will now be shifted one PEL left\n * of the position it was in at the end of step 1. Step 1 through Step 3 may be repeated as desired.\n *\n * The Line Compare register (CRTC register hex 18) should be programmed with even values in 200 line modes when\n * used in split screen applications that scroll a second screen on top of a first screen. This is a requirement\n * imposed by the scan doubling logic in the CRTC.\n *\n * If the Cursor Start register (CRTC register hex 0A) is programmed with a value greater than that in the Cursor End\n * register (CRTC register hex 0B), then no cursor is displayed. A split cursor is not possible.\n *\n * In 8-dot character modes, the underline attribute produces a solid line across adjacent characters, as in the IBM\n * Color/Graphics Monitor Adapter, Monochrome Display Adapter and the Enhanced Graphics Adapter. In 9-dot modes, the\n * underline across adjacent characters is dashed, as in the IBM 327X display terminals. In 9-dot modes, the line\n * graphics characters (C0 - DF character codes) have solid underlines.\n *\n * For compatibility with the IBM Enhanced Graphics Adapter (EGA), the internal VGA palette is programmed the same\n * as the EGA. The video DAC is programmed by BIOS so that the compatible values in the internal VGA palette produce\n * a color compatible with what was produced by EGA. Mode hex 13 (256 colors) is programmed so that the first 16\n * locations in the DAC produce compatible colors.\n *\n * Summing: When BIOS is used to load the video DAC palette for a color mode and a monochrome display is connected\n * to the system unit, the color palette is changed. The colors are summed to produce shades of gray that allow\n * color applications to produce a readable screen.\n *\n * There are 4 bits that should not be modified unless the sequencer is reset by setting bit 1 of the Reset register\n * to 0. These bits are:\n *\n * • Bit 3, or bit 0 of the Clocking Mode register\n * • Bit 3, or bit 2 of the Miscellaneous Output register\n *\n * Also, for quick reference, IBM VGA register values for the standard VGA modes (from http://www.pcjs.org/blog/2015/06/01/):\n *\n * INT 0x10 Mode Requested: 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x0D 0x0E 0x10 0x12 0x13\n *\n * BIOSMODE: 0x01 0x01 0x03 0x03 0x04 0x04 0x06 0x0D 0x0E 0x10 0x12 0x13\n * CRTC[0x00]: HTOTAL 0x2D 0x2D 0x5F 0x5F 0x2D 0x2D 0x5F 0x2D 0x5F 0x5F 0x5F 0x5F\n * CRTC[0x01]: HDEND 0x27 0x27 0x4F 0x4F 0x27 0x27 0x4F 0x27 0x4F 0x4F 0x4F 0x4F\n * CRTC[0x02]: HBSTART 0x28 0x28 0x50 0x50 0x28 0x28 0x50 0x28 0x50 0x50 0x50 0x50\n * CRTC[0x03]: HBEND 0x90 0x90 0x82 0x82 0x90 0x90 0x82 0x90 0x82 0x82 0x82 0x82\n * CRTC[0x04]: HRSTART 0x2B 0x2B 0x55 0x55 0x2B 0x2B 0x54 0x2B 0x54 0x54 0x54 0x54\n * CRTC[0x05]: HREND 0xA0 0xA0 0x81 0x81 0x80 0x80 0x80 0x80 0x80 0x80 0x80 0x80\n * CRTC[0x06]: VTOTAL 0xBF 0xBF 0xBF 0xBF 0xBF 0xBF 0xBF 0xBF 0xBF 0xBF 0x0B 0xBF\n * CRTC[0x07]: OVERFLOW 0x1F 0x1F 0x1F 0x1F 0x1F 0x1F 0x1F 0x1F 0x1F 0x1F 0x3E 0x1F\n * CRTC[0x08]: PRESCAN 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * CRTC[0x09]: MAXSCAN 0x4F 0x4F 0x4F 0x4F 0xC1 0xC1 0xC1 0xC0 0xC0 0x40 0x40 0x41\n * CRTC[0x0A]: CURSCAN 0x0D 0x0D 0x0D 0x0D 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * CRTC[0x0B]: CURSCANB 0x0E 0x0E 0x0E 0x0E 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * CRTC[0x0C]: STARTHI 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * CRTC[0x0D]: STARTLO 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * CRTC[0x0E]: CURSORHI 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x00\n * CRTC[0x0F]: CURSORLO 0x19 0x19 0x41 0x41 0x19 0x19 0x41 0x19 0x41 0x41 0xE1 0xA2\n * CRTC[0x10]: VRSTART 0x9C 0x9C 0x9C 0x9C 0x9C 0x9C 0x9C 0x9C 0x9C 0x83 0xEA 0x9C\n * CRTC[0x11]: VREND 0x8E 0x8E 0x8E 0x8E 0x8E 0x8E 0x8E 0x8E 0x8E 0x85 0x8C 0x8E\n * CRTC[0x12]: VDEND 0x8F 0x8F 0x8F 0x8F 0x8F 0x8F 0x8F 0x8F 0x8F 0x5D 0xDF 0x8F\n * CRTC[0x13]: OFFSET 0x14 0x14 0x28 0x28 0x14 0x14 0x28 0x14 0x28 0x28 0x28 0x28\n * CRTC[0x14]: UNDERLINE 0x1F 0x1F 0x1F 0x1F 0x00 0x00 0x00 0x00 0x00 0x0F 0x00 0x40\n * CRTC[0x15]: VBSTART 0x96 0x96 0x96 0x96 0x96 0x96 0x96 0x96 0x96 0x63 0xE7 0x96\n * CRTC[0x16]: VBEND 0xB9 0xB9 0xB9 0xB9 0xB9 0xB9 0xB9 0xB9 0xB9 0xBA 0x04 0xB9\n * CRTC[0x17]: MODECTRL 0xA3 0xA3 0xA3 0xA3 0xA2 0xA2 0xC2 0xE3 0xE3 0xE3 0xE3 0xA3\n * CRTC[0x18]: LINECOMP 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF\n * GRC[0x00]: SRESET 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * GRC[0x01]: ESRESET 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * GRC[0x02]: COLORCMP 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * GRC[0x03]: DATAROT 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * GRC[0x04]: READMAP 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * GRC[0x05]: MODE 0x10 0x10 0x10 0x10 0x30 0x30 0x00 0x00 0x00 0x00 0x00 0x40\n * GRC[0x06]: MISC 0x0E 0x0E 0x0E 0x0E 0x0F 0x0F 0x0D 0x05 0x05 0x05 0x05 0x05\n * GRC[0x07]: COLORDC 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0F 0x0F 0x0F 0x0F 0x0F\n * GRC[0x08]: BITMASK 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF\n * SEQ[0x00]: RESET 0x03 0x03 0x03 0x03 0x03 0x03 0x03 0x03 0x03 0x03 0x03 0x03\n * SEQ[0x01]: CLOCKING 0x08 0x08 0x00 0x00 0x09 0x09 0x01 0x09 0x01 0x01 0x01 0x01\n * SEQ[0x02]: MAPMASK 0x03 0x03 0x03 0x03 0x03 0x03 0x01 0x0F 0x0F 0x0F 0x0F 0x0F\n * SEQ[0x03]: CHARMAP 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * SEQ[0x04]: MEMMODE 0x03 0x03 0x03 0x03 0x02 0x02 0x06 0x06 0x06 0x06 0x06 0x0E\n * ATC[0x00]: PAL00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * ATC[0x01]: PAL01 0x01 0x01 0x01 0x01 0x13 0x13 0x17 0x01 0x01 0x01 0x01 0x01\n * ATC[0x02]: PAL02 0x02 0x02 0x02 0x02 0x15 0x15 0x17 0x02 0x02 0x02 0x02 0x02\n * ATC[0x03]: PAL03 0x03 0x03 0x03 0x03 0x17 0x17 0x17 0x03 0x03 0x03 0x03 0x03\n * ATC[0x04]: PAL04 0x04 0x04 0x04 0x04 0x02 0x02 0x17 0x04 0x04 0x04 0x04 0x04\n * ATC[0x05]: PAL05 0x05 0x05 0x05 0x05 0x04 0x04 0x17 0x05 0x05 0x05 0x05 0x05\n * ATC[0x06]: PAL06 0x14 0x14 0x14 0x14 0x06 0x06 0x17 0x06 0x06 0x14 0x14 0x06\n * ATC[0x07]: PAL07 0x07 0x07 0x07 0x07 0x07 0x07 0x17 0x07 0x07 0x07 0x07 0x07\n * ATC[0x08]: PAL08 0x38 0x38 0x38 0x38 0x10 0x10 0x17 0x10 0x10 0x38 0x38 0x08\n * ATC[0x09]: PAL09 0x39 0x39 0x39 0x39 0x11 0x11 0x17 0x11 0x11 0x39 0x39 0x09\n * ATC[0x0A]: PAL0A 0x3A 0x3A 0x3A 0x3A 0x12 0x12 0x17 0x12 0x12 0x3A 0x3A 0x0A\n * ATC[0x0B]: PAL0B 0x3B 0x3B 0x3B 0x3B 0x13 0x13 0x17 0x13 0x13 0x3B 0x3B 0x0B\n * ATC[0x0C]: PAL0C 0x3C 0x3C 0x3C 0x3C 0x14 0x14 0x17 0x14 0x14 0x3C 0x3C 0x0C\n * ATC[0x0D]: PAL0D 0x3D 0x3D 0x3D 0x3D 0x15 0x15 0x17 0x15 0x15 0x3D 0x3D 0x0D\n * ATC[0x0E]: PAL0E 0x3E 0x3E 0x3E 0x3E 0x16 0x16 0x17 0x16 0x16 0x3E 0x3E 0x0E\n * ATC[0x0F]: PAL0F 0x3F 0x3F 0x3F 0x3F 0x17 0x17 0x17 0x17 0x17 0x3F 0x3F 0x0F\n * ATC[0x10]: MODE 0x0C 0x0C 0x0C 0x0C 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x41\n * ATC[0x11]: OVERSCAN 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * ATC[0x12]: PLANES 0x0F 0x0F 0x0F 0x0F 0x03 0x03 0x01 0x0F 0x0F 0x0F 0x0F 0x0F\n * ATC[0x13]: HPAN 0x08 0x08 0x08 0x08 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n *\n * TODO: Build a similar table for the IBM EGA, and then work on rationalizing the mode detection logic in checkMode().\n */\n\n/**\n * @class Card\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass Card extends Controller {\n /**\n * Card(video, nCard, data, cbMemory)\n *\n * Creates an object representing an initial video card state;\n * can also restore a video card from state data created by saveCard().\n *\n * WARNING: Since Card objects are low-level objects that have no UI requirements,\n * they do not inherit from the Component class, so you should only use class methods\n * of Component, such as Component.assert(), or methods of the parent (video) object.\n *\n * @this {Card}\n * @param {Video} [video]\n * @param {number} [nCard] (see Video.CARD.*)\n * @param {Array|null} [data]\n * @param {number} [cbMemory] is specified if the card must allocate its own memory buffer\n */\n constructor(video, nCard, data, cbMemory)\n {\n super();\n \n /*\n * If a card was originally not present (eg, EGA), then the state will be empty,\n * so we need to detect that case and continue indicating that the card is not present.\n */\n if (nCard !== undefined && (!data || data.length)) {\n\n this.video = video;\n\n var specs = Video.cardSpecs[nCard];\n var nMonitorType = video.nMonitorType || specs[5];\n\n if (!data || data.length < 6) {\n data = [false, 0, null, null, 0, new Array(nCard < Video.CARD.EGA? Card.CRTC.TOTAL_REGS : Card.CRTC.EGA.TOTAL_REGS)];\n }\n\n /*\n * If a Debugger is present, we want to stash a bit more info in each Card.\n */\n if (DEBUGGER) {\n this.dbg = /** @type {DebuggerX86} */ (video.dbg);\n this.type = specs[0];\n this.port = specs[1];\n }\n\n this.nCard = nCard;\n this.addrBuffer = specs[2]; // default (physical) video buffer address\n this.sizeBuffer = specs[3]; // default video buffer length (this is the total size, not the current visible size; this.cbScreen is calculated on the fly to reflect the latter)\n\n /*\n * If no memory size is specified, then setMode() will use addMemory() to automatically add enough\n * memory blocks to cover the video buffer specified above; otherwise, it instructs addMemory() to call\n * getMemoryBuffer(), which will return a portion of the buffer (adwMemory) allocated below. This allows\n * a card like the EGA to move/resize its video buffer as needed, as well as giving it total control over\n * the underlying memory.\n */\n this.cbMemory = cbMemory || specs[4];\n\n /*\n * All of our cardSpec video buffer sizes are based on the default text mode (eg, 4Kb for an MDA, 16Kb for\n * a CGA), but for a card with 64Kb or more of memory (ie, any EGA card), the default text mode video buffer\n * size should be dynamically recalculated as the smaller of: cbMemory divided by 4, or 32Kb.\n */\n if (this.cbMemory >= 0x10000 && this.addrBuffer >= 0xB0000) {\n this.sizeBuffer = Math.min(this.cbMemory >> 2, 0x8000);\n }\n\n this.fActive = data[0];\n this.regMode = data[1]; // see MDA.MODE* or CGA.MODE_* (use (MDA.MODE.HIRES | MDA.MODE.VIDEO_ENABLE | MDA.MODE.BLINK_ENABLE) if you want to test blinking immediately after the initial power-on reset)\n this.regColor = data[2]; // see CGA.COLOR.* (undefined on MDA)\n this.regStatus = data[3]; // see MDA.STATUS.* or CGA.STATUS.*\n this.regCRTIndx = data[4] & 0xff;\n this.regCRTPrev = (data[4] >> 8) & 0xff;\n this.regCRTData = data[5];\n this.nCRTCRegs = Card.CRTC.TOTAL_REGS;\n this.asCRTCRegs = DEBUGGER? Card.CRTC.REGS : [];\n this.offStartAddr = this.regCRTData[Card.CRTC.STARTLO] | (this.regCRTData[Card.CRTC.STARTHI] << 8);\n this.addrMaskHigh = 0x3F; // card-specific mask for the high (bits 8 and up) of CRTC address registers\n\n if (nCard >= Video.CARD.EGA) {\n this.addrMaskHigh = 0xFF;\n this.nCRTCRegs = Card.CRTC.EGA.TOTAL_REGS;\n this.asCRTCRegs = DEBUGGER? Card.CRTC.EGA_REGS : [];\n this.initEGA(data[6], nMonitorType);\n }\n\n var monitorSpecs = Video.monitorSpecs[nMonitorType] || Video.monitorSpecs[ChipSet.MONITOR.MONO];\n\n var nCyclesDefault = video.cpu.getBaseCyclesPerSecond(); // eg, 4772727\n this.nCyclesHorzPeriod = (nCyclesDefault / monitorSpecs.nHorzPeriodsPerSec)|0;\n this.nCyclesHorzActive = (this.nCyclesHorzPeriod * monitorSpecs.percentHorzActive / 100)|0;\n this.nCyclesVertPeriod = (this.nCyclesHorzPeriod * monitorSpecs.nHorzPeriodsPerFrame)|0;\n this.nCyclesVertActive = (this.nCyclesVertPeriod * monitorSpecs.percentVertActive / 100)|0;\n this.nInitCycles = (data[7] || 0);\n }\n }\n\n /**\n * initEGA(data)\n *\n * Another one of my frustrations with JSON is that it encodes empty arrays with non-zero lengths as\n * arrays of nulls, which means that any uninitialized register arrays whose elements were all originally\n * undefined come back via the JSON round-trip as *initialized* arrays whose elements are now all null.\n *\n * I'm a bit surprised, because JavaScript purists tell us to always use the '===' operator (eg, use\n * 'aReg[i] === undefined' to determine if an element is initialized), but because of this JSON stupidity,\n * that would require all such tests to become 'aReg[i] === undefined || aReg[i] === null'. I'm puzzled\n * why the coercion of '==' is considered evil but JSON's coercion of undefined to null is perfectly fine.\n *\n * The simple solution is to change such comparisons to 'aReg[i] == null', because undefined is coerced\n * to null, whereas numeric values are not.\n *\n * [What do I mean by \"another\" frustration? Let me talk to you some day about disallowing hex constants,\n * or insisting that property names be quoted, or refusing to allow comments. I think it's fine for\n * JSON.stringify() to produce output that adheres to rules like that -- although some parameters to control\n * the output would be nice -- but it's completely unnecessary for JSON.parse() to refuse to parse objects\n * that are perfectly valid.]\n *\n * @this {Card}\n * @param {Array|undefined} data\n * @param {number} nMonitorType\n */\n initEGA(data, nMonitorType)\n {\n if (data === undefined) {\n data = [\n /* 0*/ false,\n /* 1*/ 0,\n /* 2*/ new Array(Card.ATC.TOTAL_REGS),\n /* 3*/ 0,\n /* 4*/ (nMonitorType == ChipSet.MONITOR.MONO? 0: Card.MISC.IO_SELECT),\n /* 5*/ 0,\n /* 6*/ 0,\n /* 7*/ new Array(Card.SEQ.TOTAL_REGS),\n /* 8*/ 0,\n /* 9*/ 0,\n /*10*/ 0,\n /*11*/ new Array(Card.GRC.TOTAL_REGS),\n /*12*/ 0,\n /*13*/ [this.addrBuffer, this.sizeBuffer, this.cbMemory],\n /*14*/ new Array(this.cbMemory >> 2), // divide cbMemory by 4 since this is an array of DWORDs (8 bits for each of 4 planes)\n /*\n * Card.ACCESS.WRITE.MODE0 by itself is a pretty good default, but if we choose to \"randomize\" the screen with\n * text characters prior to starting the machine, defaulting to Card.ACCESS.WRITE.EVENODD is more faithful to how\n * characters and attributes are typically stored (ie, in planes 0 and 1, respectively). As soon as the machine\n * starts up and initializes the hardware itself, these defaults won't matter.\n */\n /*15*/ Card.ACCESS.READ.MODE0 | Card.ACCESS.READ.EVENODD | Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.EVENODD | Card.ACCESS.V2,\n /*16*/ 0,\n /*17*/ 0xffffffff|0,\n /*18*/ 0,\n /*19*/ 0xffffffff|0,\n /*20*/ 0,\n /*21*/ 0xffffffff|0,\n /*22*/ 0,\n /*23*/ 0,\n /*24*/ 0,\n /*25*/ 0,\n /*26*/ Card.VGA_ENABLE.ENABLED,\n /*27*/ Card.DAC.MASK.DEFAULT,\n /*28*/ 0,\n /*29*/ 0,\n /*30*/ Card.DAC.STATE.MODE_WRITE,\n /*31*/ new Array(Card.DAC.TOTAL_REGS)\n ];\n }\n\n this.fATCData = data[0];\n this.regATCIndx = data[1];\n this.regATCData = data[2];\n this.asATCRegs = DEBUGGER? Card.ATC.REGS : [];\n this.regStatus0 = data[3]; // aka STATUS0 (not to be confused with this.regStatus, which the EGA refers to as STATUS1)\n this.regMisc = data[4];\n this.regFeat = data[5]; // for feature control bits, see Card.FEAT_CTRL.BITS; for feature status bits, see Card.STATUS0.FEAT\n this.regSEQIndx = data[6];\n this.regSEQData = data[7];\n this.asSEQRegs = DEBUGGER? Card.SEQ.REGS : [];\n this.regGRCPos1 = data[8];\n this.regGRCPos2 = data[9];\n this.regGRCIndx = data[10];\n this.regGRCData = data[11];\n this.asGRCRegs = DEBUGGER? Card.GRC.REGS : [];\n this.latches = data[12];\n\n /*\n * Since we originally neglected to save/restore the card's active video buffer address and length,\n * we're now stashing all that information in data[13]. So if we're presented with an old data entry\n * that contains only the card's memory size, fix it up.\n *\n * TODO: This code just creates the required array; the correct video buffer address and length would\n * still need to be calculated from the current GRC registers; checkMode() knows how to do that, but I'm\n * not prepared to shoehorn in a call to checkMode() here, and potentially create more issues, for an\n * old problem that will eventually disappear anyway.\n */\n var a = data[13];\n if (typeof a == \"number\") {\n a = [this.addrBuffer, this.sizeBuffer, a];\n }\n this.addrBuffer = a[0];\n this.sizeBuffer = a[1];\n\n\n var cdw = this.cbMemory >> 2;\n this.adwMemory = data[14];\n if (this.adwMemory && this.adwMemory.length < cdw) {\n this.adwMemory = State.decompressEvenOdd(this.adwMemory, cdw);\n }\n\n var nAccess = data[15];\n if (nAccess) {\n if (nAccess & Card.ACCESS.V2) {\n nAccess &= ~Card.ACCESS.V2;\n } else {\n\n nAccess = Card.ACCESS.V1[nAccess & 0xff00] | Card.ACCESS.V1[nAccess & 0xff];\n }\n }\n this.setMemoryAccess(nAccess);\n\n /*\n * nReadMapShift must perfectly track how the GRC.READMAP register is programmed, so that Card.ACCESS.READ.MODE0\n * memory read functions read the appropriate plane. This default is not terribly critical, unless Card.ACCESS.WRITE.MODE0\n * is chosen as our default AND you want the screen randomizer to work.\n */\n this.nReadMapShift = data[16];\n\n /*\n * Similarly, nSeqMapMask must perfectly track how the SEQ.MAPMASK register is programmed, so that memory write\n * functions write the appropriate plane(s). Again, this default is not terribly critical, unless Card.ACCESS.WRITE.MODE0\n * is chosen as our default AND you want the screen randomizer to work.\n */\n this.nSeqMapMask = data[17];\n this.nDataRotate = data[18];\n this.nBitMapMask = data[19];\n this.nSetMapData = data[20];\n this.nSetMapMask = data[21];\n this.nSetMapBits = data[22];\n this.nColorCompare = data[23];\n this.nColorDontCare = data[24];\n this.offStartAddr = data[25]; // this is the last CRTC start address latched from CRTC.STARTHI,CRTC.STARTLO\n\n this.nVertPeriods = this.nVertPeriodsStartAddr = 0;\n\n if (this.nCard == Video.CARD.VGA) {\n this.regVGAEnable = data[26];\n this.regDACMask = data[27];\n this.regDACAddr = data[28];\n this.regDACShift = data[29];\n this.regDACState = data[30];\n this.regDACData = data[31];\n }\n }\n\n /**\n * saveCard()\n *\n * @this {Card}\n * @return {Array}\n */\n saveCard()\n {\n var data = [];\n if (this.nCard !== undefined) {\n data[0] = this.fActive;\n data[1] = this.regMode;\n data[2] = this.regColor;\n data[3] = this.regStatus;\n data[4] = this.regCRTIndx | (this.regCRTPrev << 8);\n data[5] = this.regCRTData;\n if (this.nCard >= Video.CARD.EGA) {\n data[6] = this.saveEGA();\n }\n data[7] = this.nInitCycles;\n }\n return data;\n }\n\n /**\n * saveEGA()\n *\n * @this {Card}\n * @return {Array}\n */\n saveEGA()\n {\n var data = [];\n data[0] = this.fATCData;\n data[1] = this.regATCIndx;\n data[2] = this.regATCData;\n data[3] = this.regStatus0;\n data[4] = this.regMisc;\n data[5] = this.regFeat;\n data[6] = this.regSEQIndx;\n data[7] = this.regSEQData;\n data[8] = this.regGRCPos1;\n data[9] = this.regGRCPos2;\n data[10] = this.regGRCIndx;\n data[11] = this.regGRCData;\n data[12] = this.latches;\n data[13] = [this.addrBuffer, this.sizeBuffer, this.cbMemory];\n data[14] = State.compressEvenOdd(this.adwMemory);\n data[15] = this.nAccess | Card.ACCESS.V2;\n data[16] = this.nReadMapShift;\n data[17] = this.nSeqMapMask;\n data[18] = this.nDataRotate;\n data[19] = this.nBitMapMask;\n data[20] = this.nSetMapData;\n data[21] = this.nSetMapMask;\n data[22] = this.nSetMapBits;\n data[23] = this.nColorCompare;\n data[24] = this.nColorDontCare;\n data[25] = this.offStartAddr;\n\n if (this.nCard == Video.CARD.VGA) {\n data[26] = this.regVGAEnable;\n data[27] = this.regDACMask;\n data[28] = this.regDACAddr;\n data[29] = this.regDACShift;\n data[30] = this.regDACState;\n data[31] = this.regDACData;\n }\n return data;\n }\n\n /**\n * dumpRegs()\n *\n * Since we don't pre-allocate the register arrays (eg, ATC, CRTC, GRC, etc) on a Card, we can't\n * rely on their array length, so we instead rely on the number of register names supplied in asRegs.\n *\n * @this {Card}\n * @param {string} sName\n * @param {number} iReg\n * @param {Array} [aRegs]\n * @param {Array} [asRegs]\n */\n dumpRegs(sName, iReg, aRegs, asRegs)\n {\n if (DEBUGGER) {\n if (!aRegs) {\n this.dbg.println(sName + \": \" + Str.toHex(iReg, 2));\n return;\n }\n var i, cchMax = 18, s = \"\";\n for (i = 0; i < asRegs.length; i++) {\n var reg = (aRegs === this.regCRTData)? this.getCRTCReg(i) : aRegs[i];\n if (s) s += '\\n';\n s += sName + \"[\" + Str.toHex(i, 2) + \"]: \" + Str.pad(asRegs[i], cchMax) + (i === iReg? '*' : ' ') + Str.toHex(reg, reg > 0xff? 4 : 2);\n if (reg != null) s += \" (\" + reg + \".)\";\n }\n this.dbg.println(s);\n }\n }\n\n /**\n * dumpVideoCard()\n *\n * @this {Card}\n */\n dumpVideoCard()\n {\n if (DEBUGGER) {\n /*\n * Start with registers that are common to all cards....\n */\n this.dumpRegs(\"CRTC\", this.regCRTIndx, this.regCRTData, this.asCRTCRegs);\n\n if (this.nCard >= Video.CARD.EGA) {\n this.dumpRegs(\" GRC\", this.regGRCIndx, this.regGRCData, this.asGRCRegs);\n this.dumpRegs(\" SEQ\", this.regSEQIndx, this.regSEQData, this.asSEQRegs);\n this.dumpRegs(\" ATC\", this.regATCIndx, this.regATCData, this.asATCRegs);\n this.dumpRegs(\" ATCINDX\", this.regATCIndx);\n this.dbg.println(\" ATCDATA: \" + this.fATCData);\n this.dumpRegs(\" FEAT\", this.regFeat);\n this.dumpRegs(\" MISC\", this.regMisc);\n this.dumpRegs(\" STATUS0\", this.regStatus0);\n /*\n * There are few more EGA regs we could dump, like GRCPos1, GRCPos2, but does anyone care?\n */\n }\n\n /*\n * TODO: This simply dumps the last value read from the STATUS1 register, not necessarily\n * its current state; consider dumping getRetraceBits() instead of (or in addition to) this.\n */\n this.dumpRegs(\" STATUS1\", this.regStatus);\n\n if (this.nCard == Video.CARD.MDA || this.nCard == Video.CARD.CGA) {\n this.dumpRegs(\" MODEREG\", this.regMode);\n }\n\n if (this.nCard == Video.CARD.CGA) {\n this.dumpRegs(\" COLOR\", this.regColor);\n }\n\n if (this.nCard >= Video.CARD.EGA) {\n this.dbg.println(\" LATCHES: \" + Str.toHex(this.latches));\n this.dbg.println(\" ACCESS: \" + Str.toHex(this.nAccess, 4));\n this.dbg.println(\"Use 'dump video [addr]' to dump video memory\");\n /*\n * There are few more EGA regs we could dump, like GRCPos1, GRCPos2, but does anyone care?\n */\n }\n }\n }\n\n /**\n * dumpVideoBuffer(asArgs)\n *\n * Rather than requiring the first parameter to ALWAYS be a frame buffer address OR a frame buffer\n * offset, we'll just make a guess as to what the user intended and support BOTH; basically, if the\n * value is less than the frame buffer address, we'll assume it's an offset.\n *\n * Also, we allow some special options to be encoded in asArgs: 'l' followed by a number means\n * print that many rows of data. 'n' followed by a number (1-8) means print only that number of\n * memory locations per row, and then adjust the starting address of the next row by the number\n * of bytes per row (or whatever is specified by the 'w' option) so that the dump reflects a\n * rectangular chunk of video data. Finally, if asArgs contains 'p' followed by a number (0-3),\n * we display only the bits from that plane for each memory location, in binary instead of hex.\n *\n * For example, assuming a standard VGA frame buffer with 640x480 pixels across 38400 (0x9600) memory\n * locations, the following command will dump a vertical swath of bits from plane 0 that is 32 (0x20)\n * rows tall and 8 columns wide, from roughly the center of the screen (0x4B00 + 0x28 - 2 = 0x4B26).\n *\n * d video 4b26 l20 n8 p0\n *\n * Subsequent commands that omit a starting address or offset will continue where the last dump\n * left off; eg:\n *\n * d video n8 p0\n *\n * To dump a chunk of off-screen memory starting at 0x9600, where the Windows VGA driver typically\n * stores a copy of the video memory containing the current mouse pointer:\n *\n * d video 9600 l20 n5 w5 p0\n *\n * Alternatively, you could use decimal values:\n *\n * d video 9600 l32. n5. w5. p0.\n *\n * NOTE: If these commands look suspiciously like weird Hayes modem command strings, trust me,\n * that is ENTIRELY coincidental (but mildly amusing).\n *\n * TODO: Make these options more general-purpose (it currently assumes a conventional VGA planar layout).\n *\n * @this {Card}\n * @param {Array.<string>} asArgs (all numeric arguments default to base 16 unless otherwise specified)\n */\n dumpVideoBuffer(asArgs)\n {\n if (DEBUGGER) {\n if (!this.adwMemory) {\n this.dbg.println(\"no buffer\");\n return;\n }\n\n var i, j, idw, fColAdjust = false;\n var l = 8, n = 8, p = -1, w = this.video.nCols >> 3;\n\n for (i = 0; i < asArgs.length; i++) {\n\n var s = asArgs[i];\n if (!i) {\n idw = Str.parseInt(s, 16);\n continue;\n }\n\n var ch = s.charAt(0);\n j = Str.parseInt(s.substr(1), 16);\n\n switch(ch) {\n case 'l':\n l = j;\n break;\n case 'n':\n if (j >= 1 && j <= 8) {\n n = j;\n fColAdjust = true;\n }\n break;\n case 'p':\n if (j >= 0 && j <= 3) p = j;\n break;\n case 'w':\n if (j < w) w = j;\n break;\n default:\n this.dbg.println(\"unrecognized argument: \" + s);\n break;\n }\n }\n\n if (idw === undefined) {\n idw = this.prevDump || 0;\n } else if (idw >= this.addrBuffer) {\n idw -= this.addrBuffer;\n }\n\n var sDump = \"\";\n for (i = 0; i < l; i++) {\n var sData = Str.toHex(this.addrBuffer + idw) + \":\";\n for (j = 0; j < n && idw < this.adwMemory.length; j++) {\n var dw = this.adwMemory[idw++];\n sData += ' ' + ((p < 0)? Str.toHex(dw) : Str.toBin((dw >> (p << 3)), 8));\n }\n if (fColAdjust) idw += w - n;\n if (sDump) sDump += \"\\n\";\n sDump += sData;\n }\n\n if (sDump) this.dbg.println(sDump);\n this.prevDump = idw;\n }\n }\n\n /**\n * getMemoryBuffer(addr)\n *\n * If we passed a controller object (ie, this card) to addMemory(), then each allocated Memory block\n * will call this function to obtain a buffer.\n *\n * @this {Card}\n * @param {number} addr\n * @return {Array} containing the buffer (and the offset within that buffer that corresponds to the requested block)\n */\n getMemoryBuffer(addr)\n {\n return [this.adwMemory, addr - this.addrBuffer];\n }\n\n /**\n * getMemoryAccess()\n *\n * WARNING: This is a public method, whereas most Card methods are private to the Video component;\n * because a Card also acts as a Memory controller, it must provide getMemoryAccess() to the Memory component.\n *\n * Return the last set of memory access functions recorded by setMemoryAccess().\n *\n * @this {Card}\n * @return {Array.<function()>}\n */\n getMemoryAccess()\n {\n return this.afnAccess;\n }\n\n /**\n * setMemoryAccess(nAccess)\n *\n * This transforms the memory access value that getCardAccess() returns into the best available set of\n * memory access functions, which are then returned via getMemoryAccess() to any memory blocks we allocate\n * or modify.\n *\n * @this {Card}\n * @param {number|undefined} nAccess\n */\n setMemoryAccess(nAccess)\n {\n if (nAccess != null && nAccess != this.nAccess) {\n\n var nReadAccess = nAccess & Card.ACCESS.READ.MASK;\n var fnReadByte = Card.ACCESS.afn[nReadAccess];\n if (!fnReadByte) {\n if (DEBUG && this.dbg && this.dbg.messageEnabled(Messages.VIDEO)) {\n this.dbg.message(\"Card.setMemoryAccess(\" + Str.toHexWord(nAccess) + \"): missing readByte handler\");\n /*\n * I've taken a look, and the cases I've seen so far stem from the order in which the IBM VGA BIOS\n * reprograms registers during a mode change: it reprograms the Sequencer registers BEFORE the Graphics\n * Controller registers, so if GRC.MODE was set to READ.MODE1 prior to the mode change and the new mode\n * clears SEQ.MEMMODE.SEQUENTIAL, we will briefly be in an \"odd\" (unsupported) state.\n *\n * This didn't used to occur when we relied on the GRC.MODE register instead of the SEQ.MEMMODE for\n * determining the EVENODD state. But, as explained in getCardAccess(), we've run into inconsistencies in\n * how GRC.MODE.EVENODD is programmed, so we must live with this warning.\n *\n * The ultimate solution is to provide a EVENODD handler for READ.MODE1, since there is the remote\n * possibility of third-party software that relies on that \"odd\" combination.\n *\n * this.dbg.stopCPU(); // let's take a look\n */\n }\n if (nReadAccess & Card.ACCESS.READ.EVENODD) {\n fnReadByte = Card.ACCESS.afn[Card.ACCESS.READ.EVENODD];\n }\n }\n var nWriteAccess = nAccess & Card.ACCESS.WRITE.MASK;\n var fnWriteByte = Card.ACCESS.afn[nWriteAccess];\n if (!fnWriteByte) {\n if (DEBUG && this.dbg && this.dbg.messageEnabled(Messages.VIDEO)) {\n this.dbg.message(\"Card.setMemoryAccess(\" + Str.toHexWord(nAccess) + \"): missing writeByte handler\");\n /*\n * I've taken a look, and the cases I've seen so far stem from the order in which the IBM VGA BIOS\n * reprograms registers during a mode change: it reprograms the Sequencer registers BEFORE the Graphics\n * Controller registers, so if GRC.MODE was set to WRITE.MODE2 prior to the mode change and the new mode\n * clears SEQ.MEMMODE.SEQUENTIAL, we will briefly be in an \"odd\" (unsupported) state.\n *\n * This didn't used to occur when we relied on the GRC.MODE register instead of the SEQ.MEMMODE for\n * determining the EVENODD state. But, as explained in getCardAccess(), we've run into inconsistencies in\n * how GRC.MODE.EVENODD is programmed, so we must live with this warning.\n *\n * The ultimate solution is to provide EVENODD handlers for all modes other than WRITE.MODE0, since there\n * is the remote possibility of third-party software that relies on one of those \"odd\" combinations.\n *\n * this.dbg.stopCPU(); // let's take a look\n */\n }\n if (nWriteAccess & Card.ACCESS.WRITE.EVENODD) {\n fnWriteByte = Card.ACCESS.afn[Card.ACCESS.WRITE.EVENODD];\n }\n }\n if (!this.afnAccess) this.afnAccess = new Array(6);\n this.afnAccess[0] = fnReadByte;\n this.afnAccess[1] = fnWriteByte;\n this.nAccess = nAccess;\n }\n }\n\n /**\n * getCRTCReg()\n *\n * @this {Card}\n * @param {number} iReg\n * @return {number}\n */\n getCRTCReg(iReg)\n {\n var reg = this.regCRTData[iReg];\n if (reg != null && this.nCard >= Video.CARD.EGA) {\n var bOverflowBit8 = 0, bOverflowBit9 = 0, bMaxScanBit9 = 0;\n switch(iReg) {\n case Card.CRTC.EGA.VTOTAL: // 0x06\n bOverflowBit8 = Card.CRTC.EGA.OVERFLOW.VTOTAL_BIT8; // 0x01\n if (this.nCard == Video.CARD.VGA) bOverflowBit9 = Card.CRTC.EGA.OVERFLOW.VTOTAL_BIT9;\n break;\n case Card.CRTC.EGA.CURSCAN: // 0x0A\n if (this.nCard == Video.CARD.EGA) bOverflowBit8 = Card.CRTC.EGA.OVERFLOW.CURSCAN_BIT8;\n break;\n case Card.CRTC.EGA.VRSTART: // 0x10\n bOverflowBit8 = Card.CRTC.EGA.OVERFLOW.VRSTART_BIT8; // 0x04\n if (this.nCard == Video.CARD.VGA) bOverflowBit9 = Card.CRTC.EGA.OVERFLOW.VRSTART_BIT9;\n break;\n case Card.CRTC.EGA.VDEND: // 0x12\n bOverflowBit8 = Card.CRTC.EGA.OVERFLOW.VDEND_BIT8; // 0x02\n if (this.nCard == Video.CARD.VGA) bOverflowBit9 = Card.CRTC.EGA.OVERFLOW.VDEND_BIT9;\n break;\n case Card.CRTC.EGA.VBSTART: // 0x15\n bOverflowBit8 = Card.CRTC.EGA.OVERFLOW.VBSTART_BIT8; // 0x08\n if (this.nCard == Video.CARD.VGA) bMaxScanBit9 = Card.CRTC.EGA.MAXSCAN.VBSTART_BIT9;\n break;\n case Card.CRTC.EGA.LINECOMP: // 0x18\n bOverflowBit8 = Card.CRTC.EGA.OVERFLOW.LINECOMP_BIT8; // 0x10\n if (this.nCard == Video.CARD.VGA) bMaxScanBit9 = Card.CRTC.EGA.MAXSCAN.LINECOMP_BIT9;\n break;\n }\n if (bOverflowBit8) {\n reg |= ((this.regCRTData[Card.CRTC.EGA.OVERFLOW.INDX] & bOverflowBit8)? 0x100 : 0);\n reg |= ((this.regCRTData[Card.CRTC.EGA.OVERFLOW.INDX] & bOverflowBit9)? 0x200 : 0);\n reg |= ((this.regCRTData[Card.CRTC.EGA.MAXSCAN.INDX] & bMaxScanBit9)? 0x200 : 0);\n }\n }\n return reg;\n }\n}\n\n/*\n * MDA Registers (ports 0x3B4, 0x3B5, 0x3B8, and 0x3BA)\n */\nCard.MDA = {\n CRTC: {\n INDX: {\n PORT: 0x3B4, // NOTE: the low byte of this port address (0xB4) is mirrored at 40:0063 (0x0463)\n MASK: 0x1F\n },\n DATA: {\n PORT: 0x3B5\n }\n },\n MODE: {\n PORT: 0x3B8, // Mode Select Register, aka CRT Control Port 1 (write-only); the BIOS mirrors this register at 40:0065 (0x0465)\n HIRES: 0x01,\n VIDEO_ENABLE: 0x08,\n BLINK_ENABLE: 0x20\n },\n STATUS: {\n PORT: 0x3BA,\n HDRIVE: 0x01,\n BWVIDEO: 0x08\n },\n /*\n * TODO: Add support for parallel port(s) someday....\n */\n PRT_DATA: {\n PORT: 0x3BC\n },\n PRT_STATUS: {\n PORT: 0x3BD\n },\n PRT_CTRL: {\n PORT: 0x3BE\n }\n};\n\n/*\n * CGA Registers (ports 0x3D4, 0x3D5, 0x3D8, 0x3D9, and 0x3DA)\n */\nCard.CGA = {\n CRTC: {\n INDX: {\n PORT: 0x3D4, // NOTE: the low byte of this port address (0xB4) is mirrored at 40:0063 (0x0463)\n MASK: 0x1F\n },\n DATA: {\n PORT: 0x3D5\n }\n },\n MODE: {\n PORT: 0x3D8, // Mode Select Register (write-only); the BIOS mirrors this register at 40:0065 (0x0465)\n _80X25: 0x01,\n GRAPHIC_SEL: 0x02,\n BW_SEL: 0x04,\n VIDEO_ENABLE: 0x08, // same as MDA.MODE.VIDEO_ENABLE\n HIRES_BW: 0x10,\n BLINK_ENABLE: 0x20 // same as MDA.MODE.BLINK_ENABLE\n },\n COLOR: {\n PORT: 0x3D9, // write-only\n BORDER: 0x07,\n BRIGHT: 0x08,\n BGND_ALT: 0x10, // alternate, intensified background colors in text mode\n COLORSET2: 0x20 // selects aCGAColorSet2 colors for 320x200 graphics mode; aCGAColorSet1 otherwise\n },\n STATUS: {\n PORT: 0x3DA, // read-only; same for EGA (although the EGA calls this STATUS1, to distinguish it from STATUS0)\n RETRACE: 0x01,\n PEN_TRIGGER: 0x02,\n PEN_ON: 0x04,\n VRETRACE: 0x08 // when set, this indicates the CGA is performing a vertical retrace\n },\n /*\n * TODO: Add support for light pen port(s) someday....\n */\n CLEAR_PEN: {\n PORT: 0x3DB\n },\n PRESET_PEN: {\n PORT: 0x3DC\n }\n};\n\n/*\n * Common CRT hardware registers (ports 0x3B4/0x3B5 or 0x3D4/0x3D5)\n *\n * NOTE: In this implementation, because we have to make at least two of the registers readable (CURSORHI and CURSORLO),\n * we end up making ALL the registers readable, otherwise we would have to explicitly block any register marked write-only.\n * I don't think making the CRT registers fully readable presents any serious compatibility issues, and it actually offers\n * some benefits (eg, improved debugging).\n *\n * However, some things are broken: the (readable) light pen registers on the EGA are overloaded as (writable) vertical retrace\n * registers, so the vertical retrace registers cannot actually be read that way. I'm sure the VGA solved that problem, but I haven't\n * looked into it yet.\n */\nCard.CRTC = {\n HTOTAL: 0x00, // Horizontal Total\n HDISP: 0x01, // Horizontal Displayed\n HSPOS: 0x02, // Horizontal Sync Position\n HSWIDTH: 0x03, // Horizontal Sync Width\n VTOTAL: 0x04, // Vertical Total\n VTOTADJ: 0x05, // Vertical Total Adjust\n VDISP: 0x06, // Vertical Displayed\n VSPOS: 0x07, // Vertical Sync Position\n ILMODE: 0x08, // Interlace Mode\n MAXSCAN: 0x09, // Max Scan Line Address\n CURSCAN: 0x0A, // Cursor Scan Line Top\n CURSCAN_SLMASK: 0x1F, // Scan Line Mask\n /*\n * I don't entirely understand the cursor blink control bits. Here's what the MC6845 datasheet says:\n *\n * Bit 5 is the blink timing control. When bit 5 is low, the blink frequency is 1/16 of the vertical field rate,\n * and when bit 5 is high, the blink frequency is 1/32 of the vertical field rate. Bit 6 is used to enable a blink.\n */\n CURSCAN_BLINKON: 0x00, // (supposedly, 0x40 has the same effect as 0x00?)\n CURSCAN_BLINKOFF: 0x20, // if blinking is disabled, the cursor is effectively hidden (TODO: CGA and VGA only?)\n CURSCAN_BLINKFAST: 0x60, // default is 1/16 of the frame rate; this switches to 1/32 of the frame rate (TODO: CGA only?)\n CURSCANB: 0x0B, // Cursor Scan Line Bottom\n STARTHI: 0x0C, // Start Address High\n STARTLO: 0x0D, // Start Address Low\n CURSORHI: 0x0E, // Cursor Address High\n CURSORLO: 0x0F, // Cursor Address Low\n PENHI: 0x10, // Light Pen High\n PENLO: 0x11, // Light Pen Low\n TOTAL_REGS: 0x12, // total CRT registers on MDA/CGA\n EGA: {\n HDEND: 0x01,\n HBSTART: 0x02,\n HBEND: 0x03,\n HRSTART: 0x04,\n HREND: 0x05,\n VTOTAL: 0x06,\n OVERFLOW: {\n INDX: 0x07,\n VTOTAL_BIT8: 0x01, // bit 8 of register 0x06\n VDEND_BIT8: 0x02, // bit 8 of register 0x12\n VRSTART_BIT8: 0x04, // bit 8 of register 0x10\n VBSTART_BIT8: 0x08, // bit 8 of register 0x15\n LINECOMP_BIT8: 0x10, // bit 8 of register 0x18\n CURSCAN_BIT8: 0x20, // bit 8 of register 0x0A (EGA only; TODO: What is this for? The CURSCAN register doesn't even use bit 7, so why would it need a bit 8?)\n VTOTAL_BIT9: 0x20, // bit 9 of register 0x06 (VGA only)\n VDEND_BIT9: 0x40, // bit 9 of register 0x12 (VGA only, unused on EGA)\n VRSTART_BIT9: 0x80 // bit 9 of register 0x10 (VGA only, unused on EGA)\n },\n PRESCAN: 0x08,\n /*\n * NOTE: EGA/VGA CRTC registers 0x09-0x0F are the same as the MDA/CGA CRTC registers defined above\n */\n MAXSCAN: {\n INDX: 0x09, // (same as MDA/CGA)\n SLMASK: 0x1F, // Scan Line Mask\n VBSTART_BIT9: 0x20, // (VGA only)\n LINECOMP_BIT9: 0x40, // (VGA only)\n CONVERT400: 0x80 // 200-to-400 scan-line conversion is in effect (VGA only)\n },\n CURSCAN: 0x0A, // (same as MDA/CGA)\n CURSCANB: 0x0B, // (same as MDA/CGA)\n STARTHI: 0x0C, // (same as MDA/CGA)\n STARTLO: 0x0D, // (same as MDA/CGA)\n CURSORHI: 0x0E, // (same as MDA/CGA)\n CURSORLO: 0x0F, // (same as MDA/CGA)\n VRSTART: 0x10, // (formerly PENHI on MDA/CGA)\n VREND: 0x11, // (formerly PENLO on MDA/CGA; last register on the original 6845 controller)\n VDEND: 0x12,\n /*\n * The OFFSET register (bits 0-7) specifies the logical line width of the screen. The starting memory address\n * for the next character row is larger than the current character row by two or four times this amount.\n * The OFFSET register is programmed with a word address. Depending on the method of clocking the CRT Controller,\n * this word address is [effectively] either a word or double-word address. #IBMVGATechRef\n */\n OFFSET: 0x13,\n UNDERLINE: {\n INDX: 0x14,\n ROWSCAN: 0x1F,\n COUNT_BY_4: 0x20, // (VGA only)\n DWORD: 0x40 // (VGA only)\n },\n VBSTART: 0x15,\n VBEND: 0x16,\n MODECTRL: {\n INDX: 0x17,\n COMPAT_MODE: 0x01, // Compatibility Mode Support (CGA A13 control)\n SEL_ROW_SCAN: 0x02, // Select Row Scan Counter\n SEL_HRETRACE: 0x04, // Horizontal Retrace Select\n COUNT_BY_2: 0x08, // Count By Two\n OUTPUT_CTRL: 0x10, // Output Control\n ADDR_WRAP: 0x20, // Address Wrap (in Word mode, 1 maps A15 to A0 and 0 maps A13; use the latter when only 64Kb is installed)\n BYTE_MODE: 0x40, // Byte Mode (1 selects Byte Mode; 0 selects Word Mode)\n HARD_RESET: 0x80 // Hardware Reset\n },\n LINECOMP: 0x18,\n TOTAL_REGS: 0x19 // total CRT registers on EGA/VGA\n }\n};\n\n/*\n * TODO: These mask tables need to be card-specific. For example, the STARTHI and CURSORHI registers used to be\n * limited to 0x3F, because the MC6845 controller used with the original MDA and CGA cards was limited to 16Kb of RAM,\n * whereas later cards like the EGA and VGA had anywhere from 64Kb to 256Kb, so all the bits of those registers were\n * significant. Currently, I'm doing very little masking, which means most CRTC registers are treated as full 8-bit\n * registers (and fully readable as well), which might cause some compatibility problems for any MDA/CGA apps that\n * were sloppy about how they programmed registers.\n *\n * I do make an exception, however, in the case of STARTHI and CURSORHI, due to the way the MC6845 controller wraps\n * addresses around to the beginning of the buffer, because that seems like a high-risk case. See the card-specific\n * variable addrMaskHigh.\n */\nCard.CRTCMASKS = {\n [Card.CRTC.HTOTAL]: 0xFF, // R0\n [Card.CRTC.HDISP]: 0xFF, // R1\n [Card.CRTC.HSPOS]: 0xFF, // R2\n [Card.CRTC.HSWIDTH]: 0x0F, // R3\n [Card.CRTC.VTOTAL]: 0x7F, // R4\n [Card.CRTC.VTOTADJ]: 0x1F, // R5\n [Card.CRTC.VDISP]: 0x7F, // R6\n [Card.CRTC.VSPOS]: 0x7F, // R7\n [Card.CRTC.ILMODE]: 0x03, // R8\n [Card.CRTC.MAXSCAN]: 0x1F, // R9\n [Card.CRTC.CURSCAN]: 0x7F, // R10\n [Card.CRTC.CURSCANB]: 0x1F, // R11\n [Card.CRTC.STARTHI]: 0x3F, // R12\n [Card.CRTC.STARTLO]: 0xFF, // R13\n [Card.CRTC.CURSORHI]: 0x3F, // R14\n [Card.CRTC.CURSORLO]: 0xFF, // R15\n [Card.CRTC.PENHI]: 0x3F, // R16\n [Card.CRTC.PENLO]: 0xFF // R17\n};\n\nif (DEBUGGER) {\n Card.CRTC.REGS = [\n \"HTOTAL\",\"HDISP\",\"HSPOS\",\"HSWIDTH\",\"VTOTAL\",\"VTOTADJ\",\n \"VDISP\",\"VSPOS\",\"ILMODE\",\"MAXSCAN\",\"CURSCAN\",\"CURSCANB\",\n \"STARTHI\",\"STARTLO\",\"CURSORHI\",\"CURSORLO\",\"PENHI\",\"PENLO\"];\n\n Card.CRTC.EGA_REGS = [\n \"HTOTAL\",\"HDEND\",\"HBSTART\",\"HBEND\",\"HRSTART\",\"HREND\",\n \"VTOTAL\",\"OVERFLOW\",\"PRESCAN\",\"MAXSCAN\",\"CURSCAN\",\"CURSCANB\",\n \"STARTHI\",\"STARTLO\",\"CURSORHI\",\"CURSORLO\",\"VRSTART\",\"VREND\",\n \"VDEND\",\"OFFSET\",\"UNDERLINE\",\"VBSTART\",\"VBEND\",\"MODECTRL\",\"LINECOMP\"];\n}\n\n/*\n * EGA/VGA Input Status 1 Register (port 0x3DA)\n *\n * STATUS1 bit 0 has confusing documentation: the EGA Tech Ref says \"Logical 0 indicates the CRT raster is in a\n * horizontal or vertical retrace interval\", whereas the VGA Tech Ref says \"Logical 1 indicates a horizontal or\n * vertical retrace interval,\" but then clarifies: \"This bit is the real-time status of the INVERTED display enable\n * signal\". So, instead of calling bit 0 DISP_ENABLE (or more precisely, DISP_ENABLE_INVERTED), it's simply RETRACE.\n *\n * STATUS1 diagnostic bits 5 and 4 are set according to the Card.ATC.PLANES.MUX bits:\n *\n * MUX Bit 5 Bit 4\n * --- ---- ----\n * 00: Red Blue\n * 01: SecBlue Green\n * 10: SecRed SecGreen\n * 11: unused unused\n */\nCard.STATUS1 = {\n PORT: 0x3DA,\n RETRACE: 0x01, // bit 0: logical OR of horizontal and vertical retrace\n VRETRACE: 0x08, // bit 3: set during vertical retrace interval\n DIAGNOSTIC: 0x30, // bits 5,4 are controlled by the Card.ATC.PLANES.MUX bits\n RESERVED: 0xC6\n};\n\n/*\n * EGA/VGA Attribute Controller Registers (port 0x3C0: regATCIndx and regATCData)\n *\n * The current ATC INDX value is stored in cardEGA.regATCIndx (including the Card.ATC.INDX_ENABLE bit), and the\n * ATC DATA values are stored in cardEGA.regATCData. The state of the ATC INDX/DATA flip-flop is stored in fATCData.\n *\n * Note that the ATC palette registers (0x0-0xf) all use the following 6 bit assignments, with bits 6 and 7 unused:\n *\n * 0: Blue\n * 1: Green\n * 2: Red\n * 3: SecBlue (or mono video)\n * 4: SecGreen (or intensity)\n * 5: SecRed\n */\nCard.ATC = {\n PORT: 0x3C0, // ATC Index/Data Port\n INDX_MASK: 0x1F,\n INDX_PAL_ENABLE: 0x20, // must be clear when loading palette registers\n PALETTE: {\n INDX: 0x00, // 16 registers: 0x00 - 0x0F\n MASK: 0x3f,\n BLUE: 0x01,\n GREEN: 0x02,\n RED: 0x04,\n SECBLUE: 0x08,\n BRIGHT: 0x10, // NOTE: The IBM EGA manual (p.56) also calls this the \"intensity\" bit\n SECGREEN: 0x10,\n SECRED: 0x20\n },\n PALETTE_REGS: 0x10, // 16 total palette registers\n MODE: {\n INDX: 0x10, // ATC Mode Control Register\n GRAPHICS: 0x01, // bit 0: set for graphics mode, clear for alphanumeric mode\n MONOEM: 0x02, // bit 1: set for monochrome emulation mode, clear for color emulation\n TEXT_9DOT: 0x04, // bit 2: set for 9-dot replication in character codes 0xC0-0xDF\n BLINK_ENABLE: 0x08, // bit 3: set for text/graphics blink, clear for background intensity\n RESERVED: 0x10, // bit 4: reserved\n PANCOMPAT: 0x20, // bit 5: set for pixel-panning compatibility\n PELWIDTH: 0x40, // bit 6: set for 256-color modes, clear for all other modes\n COLORSEL_ALL: 0x80 // bit 7: set to enable all COLORSEL bits (ie, COLORSEL.DAC_BIT5 and COLORSEL.DAC_BIT4)\n },\n OVERSCAN: {\n INDX: 0x11 // ATC Overscan Color Register\n },\n PLANES: {\n INDX: 0x12, // ATC Color Plane Enable Register\n MASK: 0x0F,\n MUX: 0x30,\n RESERVED: 0xC0\n },\n HPAN: {\n INDX: 0x13, // ATC Horizontal PEL Panning Register\n SHIFT_LEFT: 0x0F // bits 0-3 indicate # of pixels to shift left\n },\n COLORSEL: {\n INDX: 0x14, // ATC Color Select Register (VGA only)\n DAC_BIT7: 0x08, // specifies bit 7 of DAC values (ignored in 256-color modes)\n DAC_BIT6: 0x04, // specifies bit 6 of DAC values (ignored in 256-color modes)\n DAC_BIT5: 0x02, // specifies bit 5 of DAC values (if ATC.MODE.COLORSEL_ALL is set; ignored in 256-color modes)\n DAC_BIT4: 0x01 // specifies bit 4 of DAC values (if ATC.MODE.COLORSEL_ALL is set; ignored in 256-color modes)\n },\n TOTAL_REGS: 0x14\n};\n\nif (DEBUGGER) {\n Card.ATC.REGS = [\"PAL00\",\"PAL01\",\"PAL02\",\"PAL03\",\"PAL04\",\"PAL05\",\"PAL06\",\"PAL07\",\n \"PAL08\",\"PAL09\",\"PAL0A\",\"PAL0B\",\"PAL0C\",\"PAL0D\",\"PAL0E\",\"PAL0F\", \"MODE\",\"OVERSCAN\",\"PLANES\",\"HPAN\"];\n}\n\n/*\n * EGA/VGA Feature Control Register (port 0x3BA or 0x3DA: regFeat)\n *\n * The EGA BIOS writes 0x1 to Card.FEAT_CTRL.BITS and reads Card.STATUS0.FEAT, then writes 0x2 to\n * Card.FEAT_CTRL.BITS and reads Card.STATUS0.FEAT. The bits from the first and second reads are shifted\n * into the high nibble of the byte at 40:88h.\n */\nCard.FEAT_CTRL = {\n PORT_MONO: 0x3BA, // write port address (other than the two bits below, the rest are reserved and/or unused)\n PORT_COLOR: 0x3DA, // write port address (other than the two bits below, the rest are reserved and/or unused)\n PORT_READ: 0x3CA, // read port address (VGA only)\n BITS: 0x03 // feature control bits\n};\n\n/*\n * EGA/VGA Miscellaneous Output Register (port 0x3C2: regMisc)\n */\nCard.MISC = {\n PORT_WRITE: 0x3C2, // write port address (EGA and VGA)\n PORT_READ: 0x3CC, // read port address (VGA only)\n IO_SELECT: 0x01, // 0 sets CRT ports to 0x3Bn, 1 sets CRT ports to 0x3Dn\n ENABLE_RAM: 0x02, // 0 disables video RAM, 1 enables\n CLOCK_SELECT: 0x0C, // 0x0: 14Mhz I/O clock, 0x4: 16Mhz on-board clock, 0x8: external clock, 0xC: unused\n DISABLE_DRV: 0x10, // 0 activates internal video drivers, 1 activates feature connector direct drive outputs\n PAGE_ODD_EVEN: 0x20, // 0 selects the low 64Kb page of video RAM for text modes, 1 selects the high page\n HPOLARITY: 0x40, // 0 selects positive horizontal retrace\n VPOLARITY: 0x80 // 0 selects positive vertical retrace\n};\n\n/*\n * EGA/VGA Input Status 0 Register (port 0x3C2: regStatus0)\n */\nCard.STATUS0 = {\n PORT: 0x3C2, // read-only (aka STATUS0, to distinguish it from PORT_CGA_STATUS)\n RESERVED: 0x0F,\n SWSENSE: 0x10,\n SWSENSE_SHIFT: 4,\n FEAT: 0x60, // VGA: reserved\n INTERRUPT: 0x80 // 1: video is being displayed; 0: vertical retrace is occurring\n};\n\n/*\n * VGA Subsystem Enable Register (port 0x3C3: regVGAEnable)\n */\nCard.VGA_ENABLE = {\n PORT: 0x3C3,\n ENABLED: 0x01, // when set, all VGA I/O and memory decoding is enabled; otherwise disabled (TODO: Implement)\n RESERVED: 0xFE\n};\n\n/*\n * EGA/VGA Sequencer Registers (ports 0x3C4/0x3C5: regSEQIndx and regSEQData)\n */\nCard.SEQ = {\n INDX: {\n PORT: 0x3C4, // Sequencer Index Port\n MASK: 0x07\n },\n DATA: {\n PORT: 0x3C5 // Sequencer Data Port\n },\n RESET: {\n INDX: 0x00, // Sequencer Reset Register\n ASYNC: 0x01,\n SYNC: 0x02\n },\n CLOCKING: {\n INDX: 0x01, // Sequencer Clocking Mode Register\n DOTS8: 0x01, // 1: 8 dots; 0: 9 dots\n BANDWIDTH: 0x02, // 0: CRTC has access 4 out of every 5 cycles (for high-res modes); 1: CRTC has access 2 out of 5 (VGA: reserved)\n SHIFTLOAD: 0x04,\n DOTCLOCK: 0x08, // 0: normal dot clock; 1: master clock divided by two (used for 320x200 modes: 0, 1, 4, 5, and D)\n SHIFT4: 0x10, // VGA only\n SCREEN_OFF: 0x20, // VGA only\n RESERVED: 0xC0\n },\n MAPMASK: {\n INDX: 0x02, // Sequencer Map Mask Register\n PL0: 0x01,\n PL1: 0x02,\n PL2: 0x04,\n PL3: 0x08,\n MAPS: 0x0F,\n RESERVED: 0xF0\n },\n CHARMAP: {\n INDX: 0x03, // Sequencer Character Map Select Register\n SELB: 0x03, // 0x0: 1st 8Kb of plane 2; 0x1: 2nd 8Kb; 0x2: 3rd 8Kb; 0x3: 4th 8Kb\n SELA: 0x0C, // 0x0: 1st 8Kb of plane 2; 0x4: 2nd 8Kb; 0x8: 3rd 8Kb; 0xC: 4th 8Kb\n SELB_HI: 0x10, // VGA only\n SELA_HI: 0x20 // VGA only\n },\n MEMMODE: {\n INDX: 0x04, // Sequencer Memory Mode Register\n ALPHA: 0x01, // set for alphanumeric (A/N) mode, clear for graphics (APA or \"All Points Addressable\") mode (EGA only)\n EXT: 0x02, // set if memory expansion installed, clear if not installed\n SEQUENTIAL: 0x04, // set for sequential memory access, clear for mapping even addresses to planes 0/2, odd addresses to planes 1/3\n CHAIN4: 0x08 // VGA only: set to select memory map (plane) based on low 2 bits of address\n },\n TOTAL_REGS: 0x05\n};\n\nif (DEBUGGER) Card.SEQ.REGS = [\"RESET\",\"CLOCKING\",\"MAPMASK\",\"CHARMAP\",\"MEMMODE\"];\n\n/*\n * VGA Digital-to-Analog Converter (DAC) Registers (regDACMask, regDACState, regDACAddr, and regDACData)\n *\n * To write DAC data, write an address to DAC.ADDR.PORT_WRITE, then write 3 bytes to DAC.DATA.PORT; the low 6 bits\n * of each byte will be concatenated to form an 18-bit DAC value (red is least significant, followed by green, then blue).\n * When the final byte is received, the 18-bit DAC value is updated and regDACAddr is auto-incremented.\n *\n * To read DAC data, the process is similar, but the initial address is written to DAC.ADDR.PORT_READ instead.\n *\n * DAC.STATE.PORT and DAC.ADDR.PORT_WRITE can be read at any time and will not interfere with a read or write operation\n * in progress. To prevent \"snow\", reading or writing DAC values should be limited to retrace intervals (see regStatus1),\n * or by using the SCREEN_OFF bit in the SEQ.CLOCKING register.\n */\nCard.DAC = {\n MASK: {\n PORT: 0x3C6, // initialized to 0xFF and should not be changed\n DEFAULT: 0xFF\n },\n STATE: {\n PORT: 0x3C7,\n MODE_WRITE: 0x00, // the DAC is in write mode if bits 0 and 1 are clear\n MODE_READ: 0x03 // the DAC is in read mode if bits 0 and 1 are set\n },\n ADDR: {\n PORT_READ: 0x3C7, // write to initiate a read\n PORT_WRITE: 0x3C8 // write to initiate a write; read to determine the current ADDR\n },\n DATA: {\n PORT: 0x3C9\n },\n TOTAL_REGS: 0x100\n};\n\n/*\n * EGA/VGA Graphics Controller Registers (ports 0x3CE/0x3CF: regGRCIndx and regGRCData)\n *\n * The VGA added Write Mode 3, which is described as follows:\n *\n * \"Each map is written with 8 bits of the value contained in the Set/Reset register for that map\n * (the Enable Set/Reset register has no effect). Rotated system microprocessor data is ANDed with the\n * Bit Mask register data to form an 8-bit value that performs the same function as the Bit Mask register\n * does in write modes 0 and 2.\"\n */\nCard.GRC = {\n POS1_PORT: 0x3CC, // EGA only, write-only\n POS2_PORT: 0x3CA, // EGA only, write-only\n INDX: {\n PORT: 0x3CE, // GRC Index Port\n MASK: 0x0F\n },\n DATA: {\n PORT: 0x3CF // GRC Data Port\n },\n SRESET: {\n INDX: 0x00 // GRC Set/Reset Register (write-only; each bit used only if WRITE.MODE0 and corresponding ESR bit set)\n },\n ESRESET: {\n INDX: 0x01 // GRC Enable Set/Reset Register\n },\n COLORCMP: {\n INDX: 0x02 // GRC Color Compare Register\n },\n DATAROT: {\n INDX: 0x03, // GRC Data Rotate Register\n COUNT: 0x07,\n AND: 0x08,\n OR: 0x10,\n XOR: 0x18,\n FUNC: 0x18,\n MASK: 0x1F\n },\n READMAP: {\n INDX: 0x04, // GRC Read Map Select Register\n NUM: 0x03\n },\n MODE: {\n INDX: 0x05, // GRC Mode Register\n WRITE: {\n MODE0: 0x00, // write mode 0: each plane written with CPU data, rotated as needed, unless SR enabled\n MODE1: 0x01, // write mode 1: each plane written with contents of the processor latches (loaded by a read)\n MODE2: 0x02, // write mode 2: memory plane N is written with 8 bits matching data bit N\n MODE3: 0x03, // write mode 3: VGA only\n MASK: 0x03\n },\n TEST: 0x04,\n READ: {\n MODE0: 0x00, // read mode 0: read map mode\n MODE1: 0x08, // read mode 1: color compare mode\n MASK: 0x08\n },\n EVENODD: 0x10,\n SHIFT: 0x20,\n COLOR256: 0x40 // VGA only\n },\n MISC: {\n INDX: 0x06, // GRC Miscellaneous Register\n GRAPHICS: 0x01, // set for graphics mode addressing, clear for text mode addressing\n CHAIN: 0x02, // set for odd/even planes selected with odd/even values of the processor AO bit\n MAPMEM: 0x0C, //\n MAPA0128: 0x00, //\n MAPA064: 0x04, //\n MAPB032: 0x08, //\n MAPB832: 0x0C //\n },\n COLORDC: {\n INDX: 0x07 // GRC Color \"Don't Care\" Register\n },\n BITMASK: {\n INDX: 0x08 // GRC Bit Mask Register\n },\n TOTAL_REGS: 0x09\n};\n\nif (DEBUGGER) Card.GRC.REGS = [\"SRESET\",\"ESRESET\",\"COLORCMP\",\"DATAROT\",\"READMAP\",\"MODE\",\"MISC\",\"COLORDC\",\"BITMASK\"];\n\n/*\n * EGA Memory Access Functions\n *\n * Here's where we define all the getMemoryAccess() functions that know how to deal with \"planar\" EGA memory,\n * which consists of 32-bit values for every byte of address space, allowing us to internally store plane 0\n * bytes in bits 0-7, plane 1 bytes in bits 8-15, plane 2 bytes in bits 16-23, and plane 3 bytes in bits 24-31.\n *\n * All our functions have slightly more overhead than the standard Bus memory access functions, because the\n * offset (off) parameter is block-relative, which we must transform into a buffer-relative offset. Fortunately,\n * all our Memory objects know this and have already recorded their buffer-relative offset in \"this.offset\".\n *\n * Also, the EGA includes a set of latches, one for each plane, which must be updated on most reads/writes;\n * we rely on the Memory object's \"this.controller\" property to give us access to the Card's state.\n *\n * And we take a little extra time to conditionally set fDirty on writes, meaning if a write did not actually\n * change the value of the memory, we will not set fDirty. The default write functions in memory.js don't take\n * that performance hit, but here, it may be worthwhile, because if it results in fewer dirty blocks, display\n * updates may be faster.\n *\n * Note that we don't have to worry about dealing with word accesses that straddle block boundaries, because\n * the Bus component automatically breaks those accesses into separate byte requests. Similarly, byte and word\n * values for the write functions have already been pre-masked by the Bus component to 8 and 16 bits, respectively.\n *\n * My motto: Be paranoid, but also be careful not to do any more work than you absolutely have to.\n *\n *\n * CGA Emulation on the EGA\n *\n * Modes 4/5 (320x200 low-res graphics) emulate the same buffer format that the CGA uses. To recap: 1 byte contains\n * 4 pixels (pixel 0 in bits 7-6, pixel 1 in bits 5-4, etc), and thus one row of pixels is 80 (0x50) bytes long.\n * Moreover, all even rows are stored in the first 8K of the video buffer (at 0xB8000), and all odd rows are stored\n * in the second 8K (at 0xBA000). Of each 8K, only 8000 (0x1F40) bytes are used (80 bytes X 100 rows); the remaining\n * 192 bytes of each 8K are unused.\n *\n * For these modes, the EGA's GRC.MODE is programmed with 0x30: Card.GRC.MODE.EVENODD and Card.GRC.MODE.SHIFT.\n * The latter claims to work by forming each 2-bit pixel with even bits from plane 0 and odd bits from plane 1;\n * however, I'm unclear how that works if even bytes are only written to plane 0 and odd bytes are only written to\n * plane 1, as Card.GRC.MODE.EVENODD implies, because plane 0 would never have any bits for the odd bytes, and\n * plane 1 would never have any bits for the even bytes. TODO: Figure this out.\n *\n *\n * Even/Odd Memory Access Functions\n *\n * The \"EVENODD\" functions deal with the EGA's default text-mode addressing, where EVEN addresses are mapped to\n * plane 0 (and 2) and ODD addresses are mapped to plane 1 (and 3). This occurs when SEQ.MEMMODE.SEQUENTIAL is\n * clear (and GRC.MODE.EVENODD is set), turning address bit 0 (A0) into a \"plane select\" bit. Whether A0 is also\n * used as a memory address bit depends on CRTC.MODECTRL.BYTE_MODE: if it's set, then we're in \"Byte Mode\" and A0 is\n * used as-is; if it's clear, then we're in \"Word Mode\", and either A15 (when CRTC.MODECTRL.ADDR_WRAP is set) or A13\n * (when CRTC.MODECTRL.ADDR_WRAP is clear, typically when only 64Kb of EGA memory is installed) is substituted for A0.\n *\n * Note that A13 remains clear until addresses reach 8K, at which point we've spanned 32Kb of EGA memory, so it makes\n * sense to propagate A13 to A0 at that point, so that the next 8K of addresses start using ODD instead of EVEN bytes,\n * and no memory is wasted on a 64Kb EGA card.\n *\n * These functions, however, don't yet deal with all those subtleties: A0 is currently used only as a \"plane select\"\n * bit and set to zero for addressing purposes, meaning that only the EVEN bytes in EGA memory will ever be used.\n * TODO: Implement the subtleties.\n */\n\n/*\n * Values returned by getCardAccess(); the high byte describes the read mode, and the low byte describes the write mode.\n *\n * V2 should never appear in any values used by getCardAccess() or setCardAccess(); the sole purpose of V2 is to\n * distinguish newer (V2) access values from older (V1) access values in saved contexts. It's set when the context\n * is saved, and cleared when the context is restored. Thus, if V2 is not set on restore, we assume we're dealing with\n * a V1 value, so we run it through the V1 table (below) to produce a V2 value. Hopefully at some point V1 contexts\n * can be deprecated, and the V2 bit can be eliminated/repurposed.\n */\nCard.ACCESS = {\n READ: { // READ values are designed to be OR'ed with WRITE values\n MODE0: 0x0400,\n MODE1: 0x0500,\n EVENODD: 0x1000,\n CHAIN4: 0x4000,\n MASK: 0xFF00\n },\n WRITE: { // and WRITE values are designed to be OR'ed with READ values\n MODE0: 0x0000,\n MODE1: 0x0001,\n MODE2: 0x0002,\n MODE3: 0x0003, // VGA only\n CHAIN4: 0x0004,\n EVENODD: 0x0010,\n ROT: 0x0020,\n AND: 0x0060,\n OR: 0x00A0,\n XOR: 0x00E0,\n MASK: 0x00FF\n },\n V2: (0x80000000|0) // this is a signature bit used ONLY to differentiate V2 access values from V1\n};\n\n/*\n * Table of older (V1) access values and their corresponding new values; the new values are similar but more orthogonal\n */\nCard.ACCESS.V1 = [];\nCard.ACCESS.V1[0x0002] = Card.ACCESS.READ.MODE0;\nCard.ACCESS.V1[0x0003] = Card.ACCESS.READ.MODE0 | Card.ACCESS.READ.EVENODD;\nCard.ACCESS.V1[0x0010] = Card.ACCESS.READ.MODE1;\nCard.ACCESS.V1[0x0200] = Card.ACCESS.WRITE.MODE0;\nCard.ACCESS.V1[0x0400] = Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.ROT;\nCard.ACCESS.V1[0x0600] = Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.AND;\nCard.ACCESS.V1[0x0A00] = Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.OR;\nCard.ACCESS.V1[0x0E00] = Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.XOR;\nCard.ACCESS.V1[0x0300] = Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.EVENODD;\nCard.ACCESS.V1[0x1000] = Card.ACCESS.WRITE.MODE1;\nCard.ACCESS.V1[0x2000] = Card.ACCESS.WRITE.MODE2;\nCard.ACCESS.V1[0x6000] = Card.ACCESS.WRITE.MODE2 | Card.ACCESS.WRITE.AND;\nCard.ACCESS.V1[0xA000] = Card.ACCESS.WRITE.MODE2 | Card.ACCESS.WRITE.OR;\nCard.ACCESS.V1[0xE000] = Card.ACCESS.WRITE.MODE2 | Card.ACCESS.WRITE.XOR;\n\n/**\n * readByteMode0(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} [addr]\n * @return {number}\n */\nCard.ACCESS.readByteMode0 = function readByteMode0(off, addr)\n{\n off += this.offset;\n var dw = this.controller.latches = this.adw[off];\n return (dw >> this.controller.nReadMapShift) & 0xff;\n};\n\n/**\n * readByteMode0Chain4(off, addr)\n *\n * See writeByteMode0Chain4 for a description of how writes are distributed across planes.\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} [addr]\n * @return {number}\n */\nCard.ACCESS.readByteMode0Chain4 = function readByteMode0Chain4(off, addr)\n{\n var idw = (off & ~0x3) + this.offset;\n var shift = (off & 0x3) << 3;\n return ((this.controller.latches = this.adw[idw]) >> shift) & 0xff;\n};\n\n/**\n * readByteMode0EvenOdd(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} [addr]\n * @return {number}\n */\nCard.ACCESS.readByteMode0EvenOdd = function readByteMode0EvenOdd(off, addr)\n{\n /*\n * TODO: As discussed in getCardAccess(), we need to run some tests on real EGA/VGA hardware to determine\n * exactly what gets latched (ie, from which address) when EVENODD is in effect. Whatever we learn may\n * also dictate a special EVENODD function for READ.MODE1 as well.\n */\n off += this.offset;\n var idw = off & ~0x1;\n var dw = this.controller.latches = this.adw[idw];\n return (!(off & 1)? dw : (dw >> 8)) & 0xff;\n};\n\n/**\n * readByteMode1(off, addr)\n *\n * This mode requires us to step through each of the 8 sets of 4 bits in the specified DWORD of video memory,\n * returning a 1 wherever all 4 match the Color Compare (COLORCMP) Register and a 0 otherwise. An added wrinkle\n * is that the Color Don't Care (COLORDC) Register can specify that any/all/none of the 4 bits must be ignored.\n *\n * We perform the comparison from most to least significant bit, because that matches how the nColorCompare and\n * nColorDontCare masks are initialized; we could have gone either way, but this is more consistent with the rest\n * of the component (eg, pixels are drawn across the screen from left to right, starting with the most significant\n * bit of each byte).\n *\n * Also note that, while not well-documented, this mode also affects the internal latches, so we make sure those\n * are updated as well.\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} [addr]\n * @return {number}\n */\nCard.ACCESS.readByteMode1 = function readByteMode1(off, addr)\n{\n off += this.offset;\n var dw = this.controller.latches = this.adw[off];\n /*\n * Minor optimization: we could pre-mask nColorCompare with nColorDontCare, whenever either register\n * is updated, but that's a drop in the bucket compared to all the other work this function must do.\n */\n var mask = this.controller.nColorDontCare;\n var color = this.controller.nColorCompare & mask;\n var b = 0, bit = 0x80;\n while (bit) {\n if ((dw & mask) == color) b |= bit;\n color >>>= 1; mask >>>= 1; bit >>= 1;\n }\n return b;\n};\n\n/**\n * writeByteMode0(off, b, addr)\n *\n * Supporting Set/Reset means that for every plane for which Set/Reset is enabled, we must\n * replace the corresponding byte in dw with a byte of zeros or ones. This is accomplished with\n * nSetMapMask, nSetMapData, and nSetMapBits. nSetMapMask is the inverse of the ESRESET bits,\n * because we use it to mask the processor data, nSetMapData records the desired SRESET bits,\n * and nSetMapBits contains the bits to replace those that we masked in the processor data.\n *\n * We could have done this:\n *\n * dw = (dw & this.controller.nSetMapMask) | (this.controller.nSetMapData & ~this.controller.nSetMapMask)\n *\n * but by maintaining nSetMapBits equal to (nSetMapData & ~nSetMapMask), we are able to make\n * the writes slightly more efficient.\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode0 = function writeByteMode0(off, b, addr)\n{\n var idw = off + this.offset;\n var dw = b | (b << 8) | (b << 16) | (b << 24);\n dw = (dw & this.controller.nSetMapMask) | this.controller.nSetMapBits;\n dw = (dw & this.controller.nBitMapMask) | (this.controller.latches & ~this.controller.nBitMapMask);\n dw = (dw & this.controller.nSeqMapMask) | (this.adw[idw] & ~this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode0(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode0Chain4(off, b, addr)\n *\n * This is how we distribute writes of 0xff across the address space to the planes (assuming that all\n * planes are enabled by the Sequencer's MAPMASK register):\n *\n * off idw adw[idw]\n * ------ ------ ----------\n * 0x0000: 0x0000 0x000000ff\n * 0x0001: 0x0000 0x0000ff00\n * 0x0002: 0x0000 0x00ff0000\n * 0x0003: 0x0000 0xff000000\n * 0x0004: 0x0004 0x000000ff\n * 0x0005: 0x0004 0x0000ff00\n * 0x0006: 0x0004 0x00ff0000\n * 0x0007: 0x0004 0xff000000\n * ...\n *\n * Some VGA emulations calculate the video buffer index (idw) by shifting the offset (off) right 2 bits,\n * instead of simply masking off the low 2 bits, as we do here. That would be a more \"pleasing\" arrangement,\n * because we would be using sequential video buffer locations, instead of multiples of 4, and would match how\n * pixels are stored in \"Mode X\". However, I don't think that's how CHAIN4 modes operate (although that still\n * needs to be confirmed, because multiple sources conflict on this point). TODO: Confirm CHAIN4 operation on\n * actual VGA hardware, including the extent to which ALU and other writeByteMode0() functionality needs to\n * be folded into this.\n *\n * Address decoding may not matter that much, as long as both the read and write CHAIN4 functions decode their\n * addresses in exactly the same manner; we'd only get into trouble with software that \"unchained\" or otherwise\n * reconfigured the planes and then made assumptions about existing data in the video buffer.\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode0Chain4 = function writeByteMode0Chain4(off, b, addr)\n{\n var idw = (off & ~0x3) + this.offset;\n var shift = (off & 0x3) << 3;\n /*\n * TODO: Consider adding a separate \"unmasked\" version of this CHAIN4 write function when nSeqMapMask is -1\n * (or removing nSeqMapMask from the equation altogether, if CHAIN4 is never used with any planes disabled).\n */\n var dw = ((b << shift) & this.controller.nSeqMapMask) | (this.adw[idw] & ~((0xff << shift) & this.controller.nSeqMapMask));\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode0Chain4(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode0EvenOdd(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode0EvenOdd = function writeByteMode0EvenOdd(off, b, addr)\n{\n off += this.offset;\n var dw = b | (b << 8) | (b << 16) | (b << 24);\n /*\n * When even/odd addressing is enabled, nSeqMapMask must be cleared for planes 1\n * and 3 if the address is even, and cleared for planes 0 and 2 if the address is odd.\n */\n var idw = off & ~0x1;\n dw = (dw & this.controller.nBitMapMask) | (this.controller.latches & ~this.controller.nBitMapMask);\n var maskMaps = this.controller.nSeqMapMask & (idw == off? 0x00ff00ff : (0xff00ff00|0));\n dw = (dw & maskMaps) | (this.adw[idw] & ~maskMaps);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode0EvenOdd(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode0Rot(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode0Rot = function writeByteMode0Rot(off, b, addr)\n{\n var idw = off + this.offset;\n b = ((b >> this.controller.nDataRotate) | (b << (8 - this.controller.nDataRotate)) & 0xff);\n var dw = b | (b << 8) | (b << 16) | (b << 24);\n dw = (dw & this.controller.nSetMapMask) | this.controller.nSetMapBits;\n dw = (dw & this.controller.nBitMapMask) | (this.controller.latches & ~this.controller.nBitMapMask);\n dw = (dw & this.controller.nSeqMapMask) | (this.adw[idw] & ~this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode0Rot(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode0And(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode0And = function writeByteMode0And(off, b, addr)\n{\n var idw = off + this.offset;\n b = ((b >> this.controller.nDataRotate) | (b << (8 - this.controller.nDataRotate)) & 0xff);\n var dw = b | (b << 8) | (b << 16) | (b << 24);\n dw = (dw & this.controller.nSetMapMask) | this.controller.nSetMapBits;\n dw &= this.controller.latches;\n dw = (dw & this.controller.nBitMapMask) | (this.controller.latches & ~this.controller.nBitMapMask);\n dw = (dw & this.controller.nSeqMapMask) | (this.adw[idw] & ~this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode0And(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode0Or(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode0Or = function writeByteMode0Or(off, b, addr)\n{\n var idw = off + this.offset;\n b = ((b >> this.controller.nDataRotate) | (b << (8 - this.controller.nDataRotate)) & 0xff);\n var dw = b | (b << 8) | (b << 16) | (b << 24);\n dw = (dw & this.controller.nSetMapMask) | this.controller.nSetMapBits;\n dw |= this.controller.latches;\n dw = (dw & this.controller.nBitMapMask) | (this.controller.latches & ~this.controller.nBitMapMask);\n dw = (dw & this.controller.nSeqMapMask) | (this.adw[idw] & ~this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode0Or(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode0Xor(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode0Xor = function writeByteMode0Xor(off, b, addr)\n{\n var idw = off + this.offset;\n b = ((b >> this.controller.nDataRotate) | (b << (8 - this.controller.nDataRotate)) & 0xff);\n var dw = b | (b << 8) | (b << 16) | (b << 24);\n dw = (dw & this.controller.nSetMapMask) | this.controller.nSetMapBits;\n dw ^= this.controller.latches;\n dw = (dw & this.controller.nBitMapMask) | (this.controller.latches & ~this.controller.nBitMapMask);\n dw = (dw & this.controller.nSeqMapMask) | (this.adw[idw] & ~this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode0Xor(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode1(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (ignored; the EGA latches provide the source data)\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode1 = function writeByteMode1(off, b, addr)\n{\n var idw = off + this.offset;\n var dw = (this.adw[idw] & ~this.controller.nSeqMapMask) | (this.controller.latches & this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode1(\" + Str.toHexLong(addr) + \"): \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode1EvenOdd(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (ignored; the EGA latches provide the source data)\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode1EvenOdd = function writeByteMode1EvenOdd(off, b, addr)\n{\n /*\n * TODO: As discussed in getCardAccess(), we need to run some tests on real EGA/VGA hardware to\n * determine exactly where latches are written (ie, to which address) when EVENODD is in effect.\n */\n off += this.offset;\n //\n // When even/odd addressing is enabled, nSeqMapMask must be cleared for planes 1 and 3 if\n // the address is even, and cleared for planes 0 and 2 if the address is odd.\n //\n var idw = off & ~0x1;\n var maskMaps = this.controller.nSeqMapMask & (idw == off? 0x00ff00ff : (0xff00ff00|0));\n var dw = (this.adw[idw] & ~maskMaps) | (this.controller.latches & maskMaps);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode1EvenOdd(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(dw));\n }\n};\n\n/**\n * writeByteMode2(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode2 = function writeByteMode2(off, b, addr)\n{\n var idw = off + this.offset;\n var dw = Video.aEGAByteToDW[b & 0xf];\n dw = (dw & this.controller.nBitMapMask) | (this.controller.latches & ~this.controller.nBitMapMask);\n dw = (dw & this.controller.nSeqMapMask) | (this.adw[idw] & ~this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode2(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode2And(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode2And = function writeByteMode2And(off, b, addr)\n{\n var idw = off + this.offset;\n var dw = Video.aEGAByteToDW[b & 0xf];\n dw &= this.controller.latches;\n dw = (dw & this.controller.nBitMapMask) | (this.controller.latches & ~this.controller.nBitMapMask);\n dw = (dw & this.controller.nSeqMapMask) | (this.adw[idw] & ~this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode2And(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode2Or(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode2Or = function writeByteMode2Or(off, b, addr)\n{\n var idw = off + this.offset;\n var dw = Video.aEGAByteToDW[b & 0xf];\n dw |= this.controller.latches;\n dw = (dw & this.controller.nBitMapMask) | (this.controller.latches & ~this.controller.nBitMapMask);\n dw = (dw & this.controller.nSeqMapMask) | (this.adw[idw] & ~this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode2Or(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode2Xor(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode2Xor = function writeByteMode2Xor(off, b, addr)\n{\n var idw = off + this.offset;\n var dw = Video.aEGAByteToDW[b & 0xf];\n dw ^= this.controller.latches;\n dw = (dw & this.controller.nBitMapMask) | (this.controller.latches & ~this.controller.nBitMapMask);\n dw = (dw & this.controller.nSeqMapMask) | (this.adw[idw] & ~this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode2Xor(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode3(off, b, addr)\n *\n * In MODE3, Set/Reset is always enabled, so the ESRESET bits (and therefore nSetMapMask and nSetMapBits)\n * are ignored; we look only at the SRESET bits, which are stored in nSetMapData.\n *\n * Unlike MODE0, we currently have no non-rotate function for MODE3. If performance dictates, we can add one;\n * ditto for other features like the Sequencer's MAPMASK register (nSeqMapMask).\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode3 = function writeByteMode3(off, b, addr)\n{\n var idw = off + this.offset;\n b = ((b >> this.controller.nDataRotate) | (b << (8 - this.controller.nDataRotate)) & 0xff);\n var dw = b | (b << 8) | (b << 16) | (b << 24);\n var dwMask = (dw & this.controller.nBitMapMask);\n dw = (this.controller.nSetMapData & dwMask) | (this.controller.latches & ~dwMask);\n dw = (dw & this.controller.nSeqMapMask) | (this.adw[idw] & ~this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode3(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/*\n * Mappings from getCardAccess() values to access functions above\n */\nCard.ACCESS.afn = [];\n\nCard.ACCESS.afn[Card.ACCESS.READ.MODE0] = Card.ACCESS.readByteMode0;\nCard.ACCESS.afn[Card.ACCESS.READ.MODE0 | Card.ACCESS.READ.CHAIN4] = Card.ACCESS.readByteMode0Chain4;\nCard.ACCESS.afn[Card.ACCESS.READ.MODE0 | Card.ACCESS.READ.EVENODD] = Card.ACCESS.readByteMode0EvenOdd;\nCard.ACCESS.afn[Card.ACCESS.READ.MODE1] = Card.ACCESS.readByteMode1;\n\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE0] = Card.ACCESS.writeByteMode0;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.ROT] = Card.ACCESS.writeByteMode0Rot;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.AND] = Card.ACCESS.writeByteMode0And;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.OR] = Card.ACCESS.writeByteMode0Or;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.XOR] = Card.ACCESS.writeByteMode0Xor;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.CHAIN4] = Card.ACCESS.writeByteMode0Chain4;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.EVENODD] = Card.ACCESS.writeByteMode0EvenOdd;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE1] = Card.ACCESS.writeByteMode1;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE1 | Card.ACCESS.WRITE.EVENODD] = Card.ACCESS.writeByteMode1EvenOdd;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE2] = Card.ACCESS.writeByteMode2;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE2 | Card.ACCESS.WRITE.AND] = Card.ACCESS.writeByteMode2And;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE2 | Card.ACCESS.WRITE.OR] = Card.ACCESS.writeByteMode2Or;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE2 | Card.ACCESS.WRITE.XOR] = Card.ACCESS.writeByteMode2Xor;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE3] = Card.ACCESS.writeByteMode3;\n\n/**\n * @class Video\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass Video extends Component {\n /**\n * Video(parmsVideo, canvas, context, textarea, container)\n *\n * The Video component can be configured with the following (parmsVideo) properties:\n *\n * model: model (eg, \"mda\" for Monochrome Display Adapter)\n * mode: initial video mode (default is null, which selects a mode based on model)\n * screenWidth: width of the screen canvas, in pixels\n * screenHeight: height of the screen canvas, in pixels\n * screenColor: background color of the screen canvas (default is black)\n * flicker: 1 enables screen flicker, 0 disables (default is 0)\n * scale: true for font scaling, false (default) to center the display on the screen\n * charCols: number of character columns\n * charRows: number of character rows\n * fontROM: path to .rom file (or a JSON representation) containing the character set\n * touchScreen: string specifying desired touch-screen support (default is none)\n * autoLock: true to (attempt to) auto-lock the mouse to the canvas (default is false)\n * randomize: 1 enables screen randomization, 0 disables (default is 1)\n *\n * An EGA/VGA may specify the following additional properties:\n *\n * switches: string representing EGA switches (see \"SW1-SW4\" documentation below)\n * memory: the size of the EGA's on-board memory (overrides EGA's Video.cardSpecs)\n *\n * This calls the Bus to allocate a video buffer at the appropriate memory location whenever\n * a reset() or setMode() occurs; setMode() is called whenever a mode change is detected at\n * the port level, and whenever reset() is called. setMode() also invokes updateScreen(true),\n * which forces reallocation of our internal buffer (aCellCache) that mirrors the video buffer.\n *\n * Our initBus() handler defines a timer that periodically calls updateScreen() for each Video\n * instance. These updates should occur at a rate of 60 times/second, to update any blinking\n * elements (the cursor and any cells with the blink attribute), to compare/update the contents\n * of our internal buffer with the video buffer, and to render any differences between the two\n * buffers into the associated screen canvas, via either updateChar() or setPixel().\n *\n * Thanks to the Bus' new block-based memory manager that allows us to sparse-allocate memory\n * (in 4Kb increments on 20-bit buses, 16Kb increments on 24-bit buses), updateScreen()\n * can also ask the CPU for the \"dirty\" state of all the blocks underlying the video buffer,\n * bypassing the update completely if the buffer is still clean.\n *\n * Sadly, that optimization is defeated if the count of active blink elements is non-zero,\n * because we must rescan the entire buffer to locate and redraw them all; I'm assuming for now\n * that, more often than not, very few (if any) blink attributes will be present, and therefore\n * they're not worth a separate caching mechanism. If the only blinking element is the cursor,\n * that's no problem, as we redraw only the one cell containing the cursor (assuming the buffer\n * is otherwise clean).\n *\n * @this {Video}\n * @param {Object} parmsVideo\n * @param {HTMLCanvasElement} [canvas]\n * @param {CanvasRenderingContext2D} [context]\n * @param {HTMLTextAreaElement} [textarea]\n * @param {HTMLElement} [container]\n */\n constructor(parmsVideo, canvas, context, textarea, container)\n {\n super(\"Video\", parmsVideo, Messages.VIDEO);\n\n var video = this, sProp, sEvent;\n this.fGecko = Web.isUserAgent(\"Gecko/\");\n\n /*\n * This records the model specified (eg, \"mda\", \"cga\", \"ega\", \"vga\" or \"\" if none specified);\n * when a model is specified, it overrides whatever model we infer from the ChipSet's switches\n * (since those motherboard switches tell us only the type of monitor, not the type of card).\n */\n this.model = parmsVideo['model'];\n var aModelDefaults = Video.MODEL[this.model] || Video.MODEL['mda'];\n\n this.nCard = aModelDefaults[0];\n this.cbMemory = parmsVideo['memory'] || 0; // zero means fallback to the cardSpec's default size\n this.sSwitches = parmsVideo['switches'];\n this.nRandomize = parmsVideo['randomize'];\n if (this.nRandomize == null) this.nRandomize = 1;\n\n /*\n * powerUp() uses the default mode ONLY if ChipSet doesn't give us a default.\n */\n this.nModeDefault = parmsVideo['mode'];\n if (this.nModeDefault == null || Video.aModeParms[this.nModeDefault] == null) {\n this.nModeDefault = aModelDefaults[1];\n }\n\n /*\n * setDimensions() uses these values ONLY if it doesn't recognize the video mode.\n */\n this.nColsDefault = parmsVideo['charCols'];\n this.nRowsDefault = parmsVideo['charRows'];\n if (this.nColsDefault === undefined || this.nRowsDefault === undefined) {\n this.nColsDefault = Video.aModeParms[this.nModeDefault][0];\n this.nRowsDefault = Video.aModeParms[this.nModeDefault][1];\n }\n\n /*\n * setDimensions() uses these values unconditionally, as the machine has no idea what the\n * physical screen size should be.\n */\n this.cxScreen = parmsVideo['screenWidth'];\n this.cyScreen = parmsVideo['screenHeight'];\n\n /*\n * The font 'scale' parameter is deprecated (we ALWAYS scale now), and the internal fDoubleFont\n * setting is now always true, but it is retained in case we want to revisit the benefits (or lack\n * thereof) of font-doubling.\n * \n * When fScaleFont was false, one key difference was these additional lines in setDimensions():\n * \n * if (!this.fScaleFont) {\n * this.cxScreenCell = font.cxCell;\n * this.cyScreenCell = font.cyCell;\n * }\n * \n * which meant that if the font was only 8 pixels wide (instead of 16), then 40-column mode would\n * simply display normal size characters with large black borders on either of the screen.\n *\n * this.fScaleFont = parmsVideo['scale'];\n */\n this.fDoubleFont = true;\n\n this.canvasScreen = canvas;\n this.contextScreen = context;\n this.inputTextArea = textarea;\n this.inputScreen = textarea || canvas || null;\n\n /*\n * We now ensure that a colorScreen property is always set (to \"black\" if nothing else), and\n * set BOTH the canvas element's AND the container element's backgroundColor to match that color.\n *\n * This gives us option of doing \"cute\" things like flipping the canvas element's opacity from\n * 1 to 0 briefly, alternately revealing and hiding the underlying container element, to simulate\n * screen \"flicker\".\n */\n this.colorScreen = parmsVideo['screenColor'] || \"black\";\n this.opacityFlicker = (1 - (Web.getURLParm('flicker') || parmsVideo['flicker'] || 0)).toString();\n this.fOpacityReduced = false;\n if (canvas) canvas.style.backgroundColor = this.colorScreen;\n if (container) container.style.backgroundColor = this.colorScreen;\n\n /*\n * Support for disabling (or, less commonly, enabling) image smoothing, which all browsers\n * seem to support now (well, OK, I still have to test the latest MS Edge browser), despite\n * it still being labelled \"experimental technology\". Let's hope the browsers standardize\n * on this. I see other options emerging, like the CSS property \"image-rendering: pixelated\"\n * that's apparently been added to Chrome. Sigh.\n */\n var fSmoothing = parmsVideo['smoothing'];\n var sSmoothing = Web.getURLParm('smoothing');\n if (sSmoothing) fSmoothing = (sSmoothing == \"true\");\n if (fSmoothing != null) {\n sProp = Web.findProperty(this.contextScreen, 'imageSmoothingEnabled');\n if (sProp) this.contextScreen[sProp] = fSmoothing;\n }\n\n /*\n * initBus() will determine touch-screen support; for now, just record values and set defaults.\n */\n this.sTouchScreen = parmsVideo['touchScreen'];\n this.nTouchConfig = Video.TOUCH.NONE;\n\n /*\n * If a Mouse exists, we'll be notified when it requests our canvas, and we make a note of it\n * so that if lockPointer() is ever invoked, we can notify the Mouse.\n */\n this.mouse = null;\n this.fAutoLock = parmsVideo['autoLock'];\n\n /*\n * Originally, setMode() would map/unmap the video buffer ONLY when the active card changed,\n * because as long as an MDA or CGA remained active, its video buffer never changed. However,\n * since the EGA can change its video buffer on the fly, setMode() must also compare the card's\n * hard-coded and/or programmed buffer address/size to the \"active\" address/size; the latter\n * is recorded here.\n */\n this.addrBuffer = this.sizeBuffer = 0;\n\n /*\n * aFonts is an array of font objects indexed by FONT ID. Font characters are arranged\n * in 16x16 grids, with one grid per canvas object in the aCanvas array of each font object.\n *\n * Each element is a Font object that describes the font size and provides bitmaps for all the font\n * color permutations. aFonts.length will be non-zero if ANY fonts are loaded, but do NOT assume\n * that EVERY font has been loaded; check for the existence of a font by checking for its unique ID\n * within this sparse array.\n */\n this.aFonts = [];\n\n /*\n * Instead of (re)allocating a new color array every time getCardColors() is called, we preallocate\n * an array and simply update the entries as needed. Note that for an EGA (or a VGA operating in an\n * EGA-compatible mode), only the first 16 entries get used (derived from the ATC); only when a VGA\n * is operating in an 8bpp mode are 256 entries used (derived from the DAC rather than the ATC).\n */\n this.aRGB = new Array(this.nCard == Video.CARD.VGA? 256 : 16);\n this.fRGBValid = false; // whenever this is false, it signals getCardColors() to rebuild aRGB\n\n /*\n * Since I've not found clear documentation on a reliable way to check whether a particular DOM element\n * (other than the BODY element) has focus at any given time, I've added onfocus() and onblur() handlers\n * to the screen to maintain my own focus state.\n */\n this.fHasFocus = false;\n\n /*\n * Here's the gross code to handle full-screen support across all supported browsers. The lack of standards\n * is exasperating; browsers can't agree on 'Fullscreen' (most common) or 'FullScreen' (least common), and while\n * some browsers honor other browser prefixes, most don't. Event handlers tend to be more consistent (ie, all\n * lower-case).\n */\n this.container = container;\n if (this.container) {\n sProp = Web.findProperty(container, 'requestFullscreen') || Web.findProperty(container, 'requestFullScreen');\n if (sProp) {\n this.container.doFullScreen = container[sProp];\n sEvent = Web.findProperty(document, 'on', 'fullscreenchange');\n if (sEvent) {\n var sFullScreen = Web.findProperty(document, 'fullscreenElement') || Web.findProperty(document, 'fullScreenElement');\n document.addEventListener(sEvent, function onFullScreenChange() {\n video.notifyFullScreen(!!sFullScreen);\n }, false);\n }\n sEvent = Web.findProperty(document, 'on', 'fullscreenerror');\n if (sEvent) {\n document.addEventListener(sEvent, function onFullScreenError() {\n video.notifyFullScreen(null);\n }, false);\n }\n }\n }\n\n /*\n * More gross code to handle pointer-locking support across all supported browsers.\n */\n if (this.inputScreen) {\n this.inputScreen.onfocus = function onFocusScreen() {\n return video.onFocusChange(true);\n };\n this.inputScreen.onblur = function onBlurScreen() {\n return video.onFocusChange(false);\n };\n this.inputScreen.lockPointer = (sProp = Web.findProperty(this.inputScreen, 'requestPointerLock')) && this.inputScreen[sProp];\n this.inputScreen.unlockPointer = (sProp = Web.findProperty(this.inputScreen, 'exitPointerLock')) && this.inputScreen[sProp];\n if (this.inputScreen.lockPointer) {\n sEvent = Web.findProperty(document, 'on', 'pointerlockchange');\n if (sEvent) {\n var sPointerLock = Web.findProperty(document, 'pointerLockElement');\n document.addEventListener(sEvent, function onPointerLockChange() {\n var fLocked = !!(sPointerLock && document[sPointerLock] === video.inputScreen);\n video.notifyPointerLocked(fLocked);\n }, false);\n }\n }\n }\n\n this.sFileURL = parmsVideo['fontROM'];\n\n if (this.sFileURL) {\n var sFileExt = Str.getExtension(this.sFileURL);\n if (sFileExt != \"json\") {\n this.sFileURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFileURL + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES;\n }\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * This is a notification issued by the Computer component, after all the other components (notably the CPU)\n * have had a chance to initialize.\n *\n * @this {Video}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n var video = this;\n\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n var nRandomize = +cmp.getMachineParm('randomize');\n if (nRandomize >= 0 && nRandomize <= 1) this.nRandomize = nRandomize;\n\n /*\n * nCard will be undefined if no model was explicitly set (whereas this.nCard is ALWAYS defined).\n */\n var aModel = Video.MODEL[this.model], nCard = aModel && aModel[0];\n\n /*\n * The only time we do NOT want to trap MDA ports is when the model has been explicitly set to CGA.\n */\n if (nCard !== Video.CARD.CGA) {\n bus.addPortInputTable(this, Video.aMDAPortInput);\n bus.addPortOutputTable(this, Video.aMDAPortOutput);\n }\n\n /*\n * Similarly, the only time we do NOT want to trap CGA ports is when the model is explicitly set to MDA.\n */\n if (nCard !== Video.CARD.MDA) {\n bus.addPortInputTable(this, Video.aCGAPortInput);\n bus.addPortOutputTable(this, Video.aCGAPortOutput);\n }\n\n /*\n * Note that in the case of EGA and VGA models, the above code ensures that we will trap both MDA and CGA\n * port ranges -- which is good, because both the EGA and VGA can be reprogrammed to respond to those ports,\n * but also potentially bad if you want to simulate a \"dual display\" system, where one of the displays is\n * driven by either an MDA or CGA.\n *\n * However, you should still be able to make that work by loading the MDA or CGA video component first, because\n * components should be initialized in the order they appear in the machine configuration file. Any attempt\n * by another component to trap the same ports should be ignored.\n */\n if (this.nCard >= Video.CARD.EGA) {\n bus.addPortInputTable(this, Video.aEGAPortInput);\n bus.addPortOutputTable(this, Video.aEGAPortOutput);\n }\n\n if (this.nCard == Video.CARD.VGA) {\n bus.addPortInputTable(this, Video.aVGAPortInput);\n bus.addPortOutputTable(this, Video.aVGAPortOutput);\n }\n\n if (DEBUGGER && dbg) {\n dbg.messageDump(Messages.VIDEO, function onDumpVideo(asArgs) {\n video.dumpVideo(asArgs);\n });\n }\n\n /*\n * If we have an associated keyboard, then ensure that the keyboard will be notified whenever the canvas\n * gets focus and receives input.\n */\n this.kbd = cmp.getMachineComponent(\"Keyboard\");\n if (this.kbd && this.canvasScreen) {\n for (var s in this.bindings) {\n if (s.indexOf(\"lock\") > 0) this.kbd.setBinding(\"led\", s, this.bindings[s]);\n }\n this.kbd.setBinding(this.inputTextArea? \"textarea\" : \"canvas\", \"screen\", this.inputScreen);\n }\n\n this.bEGASwitches = 0x09; // our default \"switches\" setting (see aEGAMonitorSwitches)\n this.chipset = cmp.getMachineComponent(\"ChipSet\");\n if (this.chipset && this.sSwitches) {\n if (this.nCard == Video.CARD.EGA) {\n this.bEGASwitches = this.chipset.parseDIPSwitches(this.sSwitches, this.bEGASwitches);\n }\n }\n\n /*\n * The default value for the 'touchScreen' parameter is an empty string; machine configs must explicitly\n * select one of the following values, via the 'touchscreen' attribute in the <video> element, to enable any\n * touch-screen support.\n */\n if (this.sTouchScreen == \"mouse\") {\n this.mouse = cmp.getMachineComponent(\"Mouse\");\n if (this.mouse) this.captureTouch(Video.TOUCH.MOUSE);\n }\n else if (this.sTouchScreen == \"keygrid\") {\n if (this.kbd) this.captureTouch(Video.TOUCH.KEYGRID);\n }\n\n /*\n * If no touch support was required or requested, we still want to do some minimal touch event processing;\n * eg, notifying the ChipSet component whenever a touchstart occurs, so that it can enable audio in response\n * to a user action on iOS devices.\n */\n if (!this.nTouchConfig) {\n this.captureTouch(Video.TOUCH.DEFAULT);\n }\n\n if (this.sFileURL) {\n var sProgress = \"Loading \" + this.sFileURL + \"...\";\n Web.getResource(this.sFileURL, null, true, function(sURL, sResponse, nErrorCode) {\n video.doneLoad(sURL, sResponse, nErrorCode);\n }, function(nState) {\n video.println(sProgress, Component.PRINT.PROGRESS);\n });\n }\n\n this.cpu.addTimer(this.id, function updateScreenTimer() {\n video.updateScreen();\n }, 1000 / Video.UPDATES_PER_SECOND);\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {Video}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"refresh\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var video = this;\n\n if (!this.bindings[sBinding]) {\n\n /*\n * We now save every binding that comes in, so that if there are bindings for \"caps-lock' and the like,\n * we can forward them to the Keyboard. TODO: Perhaps we should limit this to sHTMLType == \"led\", and collect\n * them in a separate object (eg, ledBindings), so that initBus() can safely enumerate JUST the LEDs. This\n * is what we do in PC8080. Be aware that's there's also sHTMLType == \"rled\" now, too.\n */\n this.bindings[sBinding] = control;\n\n switch (sBinding) {\n\n case \"fullScreen\":\n if (this.container && this.container.doFullScreen) {\n control.onclick = function onClickFullScreen() {\n if (DEBUG) video.printMessage(\"fullScreen()\");\n video.goFullScreen();\n };\n } else {\n if (DEBUG) this.log(\"FullScreen API not available\");\n control.parentNode.removeChild(/** @type {Node} */ (control));\n }\n return true;\n\n case \"lockPointer\":\n this.sLockMessage = control.textContent;\n if (this.inputScreen && this.inputScreen.lockPointer) {\n control.onclick = function onClickLockPointer() {\n if (DEBUG) video.printMessage(\"lockPointer()\");\n video.lockPointer(true);\n };\n } else {\n if (DEBUG) this.log(\"Pointer Lock API not available\");\n control.parentNode.removeChild(/** @type {Node} */ (control));\n }\n return true;\n\n case \"refresh\":\n control.onclick = function onClickRefresh() {\n if (DEBUG) video.printMessage(\"refreshScreen()\");\n video.updateScreen(true);\n };\n return true;\n\n default:\n break;\n }\n }\n return false;\n }\n\n /**\n * setFocus()\n *\n * @this {Video}\n */\n setFocus()\n {\n if (this.inputScreen) this.inputScreen.focus();\n }\n\n /**\n * getScreen()\n *\n * This is an interface used by the Mouse component, so that it can capture mouse events from the screen.\n *\n * @this {Video}\n * @param {Mouse} [mouse]\n * @return {Object|undefined}\n */\n getScreen(mouse)\n {\n this.mouse = mouse;\n return this.inputScreen;\n }\n\n /**\n * getTextArea()\n *\n * This is an interface used by the Computer component, so that it can display resource status messages.\n *\n * @this {Video}\n * @return {HTMLTextAreaElement|undefined}\n */\n getTextArea()\n {\n return this.inputTextArea;\n }\n\n /**\n * goFullScreen()\n *\n * @this {Video}\n * @return {boolean} true if request successful, false if not (eg, failed OR not supported)\n */\n goFullScreen()\n {\n var fSuccess = false;\n if (this.container) {\n if (this.container.doFullScreen) {\n /*\n * Styling the container with a width of \"100%\" and a height of \"auto\" works great when the aspect ratio\n * of our virtual screen is at least roughly equivalent to the physical screen's aspect ratio, but now that\n * we support virtual VGA screens with an aspect ratio of 1.33, that's very much out of step with modern\n * wide-screen monitors, which usually have an aspect ratio of 1.6 or greater.\n *\n * And unfortunately, none of the browsers I've tested appear to make any attempt to scale our container to\n * the physical screen's dimensions, so the bottom of our screen gets clipped. To prevent that, I reduce\n * the width from 100% to whatever percentage will accommodate the entire height of the virtual screen.\n *\n * NOTE: Mozilla recommends both a width and a height of \"100%\", but all my tests suggest that using \"auto\"\n * for height works equally well, so I'm sticking with it, because \"auto\" is also consistent with how I've\n * implemented a responsive canvas when the browser window is being resized.\n */\n var sWidth = \"100%\";\n var sHeight = \"auto\";\n if (screen && screen.width && screen.height) {\n var aspectPhys = screen.width / screen.height;\n var aspectVirt = this.cxScreen / this.cyScreen;\n if (aspectPhys > aspectVirt) {\n sWidth = Math.round(aspectVirt / aspectPhys * 100) + '%';\n }\n // TODO: We may need to someday consider the case of a physical screen with an aspect ratio < 1.0....\n }\n if (!this.fGecko) {\n this.container.style.width = sWidth;\n this.container.style.height = sHeight;\n } else {\n /*\n * Sadly, the above code doesn't work for Firefox, because as:\n *\n * http://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode\n *\n * explains:\n *\n * 'It's worth noting a key difference here between the Gecko and WebKit implementations at this time:\n * Gecko automatically adds CSS rules to the element to stretch it to fill the screen: \"width: 100%; height: 100%\".\n *\n * Which would be OK if Gecko did that BEFORE we're called, but apparently it does that AFTER, effectively\n * overwriting our careful calculations. So we style the inner element (canvasScreen) instead, which\n * requires even more work to ensure that the canvas is properly centered. FYI, this solution is consistent\n * with Mozilla's recommendation for working around their automatic CSS rules:\n *\n * '[I]f you're trying to emulate WebKit's behavior on Gecko, you need to place the element you want\n * to present inside another element, which you'll make fullscreen instead, and use CSS rules to adjust\n * the inner element to match the appearance you want.'\n */\n this.canvasScreen.style.width = sWidth;\n this.canvasScreen.style.width = sWidth;\n this.canvasScreen.style.display = \"block\";\n this.canvasScreen.style.margin = \"auto\";\n }\n this.container.style.backgroundColor = this.colorScreen;\n this.container.doFullScreen();\n fSuccess = true;\n }\n this.setFocus();\n }\n return fSuccess;\n }\n\n /**\n * notifyFullScreen(fFullScreen)\n *\n * @this {Video}\n * @param {boolean|null} fFullScreen (null if there was a full-screen error)\n */\n notifyFullScreen(fFullScreen)\n {\n if (!fFullScreen && this.container) {\n if (!this.fGecko) {\n this.container.style.width = this.container.style.height = \"\";\n } else {\n this.canvasScreen.style.width = this.canvasScreen.style.height = \"\";\n }\n }\n this.printMessage(\"notifyFullScreen(\" + fFullScreen + \")\", true);\n if (this.kbd) this.kbd.notifyEscape(fFullScreen);\n }\n\n /**\n * lockPointer()\n *\n * @this {Video}\n * @param {boolean} fLock\n * @return {boolean} true if request successful, false if not (eg, failed OR not supported)\n */\n lockPointer(fLock)\n {\n var fSuccess = false;\n if (this.inputScreen && this.mouse) {\n if (fLock) {\n if (this.inputScreen.lockPointer) {\n this.inputScreen.lockPointer();\n this.mouse.notifyPointerLocked(true);\n fSuccess = true;\n }\n } else {\n if (this.inputScreen.unlockPointer) {\n this.inputScreen.unlockPointer();\n this.mouse.notifyPointerLocked(false);\n fSuccess = true;\n }\n }\n this.setFocus();\n }\n return fSuccess;\n }\n\n /**\n * notifyPointerActive(fActive)\n *\n * @this {Video}\n * @param {boolean} fActive\n * @return {boolean} true if autolock enabled AND pointer lock supported, false if not\n */\n notifyPointerActive(fActive)\n {\n if (this.fAutoLock) {\n return this.lockPointer(fActive);\n }\n return false;\n }\n\n /**\n * notifyPointerLocked(fLocked)\n *\n * @this {Video}\n * @param {boolean} fLocked\n */\n notifyPointerLocked(fLocked)\n {\n if (this.mouse) {\n this.mouse.notifyPointerLocked(fLocked);\n if (this.kbd) this.kbd.notifyEscape(fLocked);\n }\n var control = this.bindings[\"lockPointer\"];\n if (control) control.textContent = (fLocked? \"Press Esc to Unlock Pointer\" : this.sLockMessage);\n }\n\n /**\n * captureTouch(nTouchConfig)\n *\n * @this {Video}\n * @param {number} nTouchConfig (must be one of the supported Video.TOUCH values)\n */\n captureTouch(nTouchConfig)\n {\n var control = this.inputScreen;\n if (control) {\n var video = this;\n if (!this.nTouchConfig) {\n\n this.nTouchConfig = nTouchConfig;\n \n var addPassive = false;\n if (nTouchConfig != Video.TOUCH.MOUSE) {\n /*\n * If we're not capturing touch events for mouse event simulation, then we won't be calling\n * preventDefault(), which means we should tell Chrome and any other browser that supports\n * passive event listeners that we're installing a \"passive\" event listener, so that the browser\n * won't suspend us during `touchstart` and `touchmove` events. But in order to know whether\n * the browser supports that feature, we have to probe for it first.\n */\n try {\n var opts = Object.defineProperty({}, 'passive', {\n get: function() {\n addPassive = true;\n }\n });\n window.addEventListener(\"testPassive\", null, opts);\n window.removeEventListener(\"testPassive\", null, opts);\n } catch (e) {}\n }\n\n control.addEventListener(\n 'touchstart',\n function onTouchStart(event) { video.onTouchStart(event); },\n addPassive? {passive: true} : false\n );\n\n if (nTouchConfig == Video.TOUCH.DEFAULT) {\n return;\n }\n\n control.addEventListener(\n 'touchmove',\n function onTouchMove(event) { video.onTouchMove(event); },\n addPassive? {passive: true} : true\n );\n\n control.addEventListener(\n 'touchend',\n function onTouchEnd(event) { video.onTouchEnd(event); },\n false // we'll specify false for the 'useCapture' parameter for now...\n );\n\n /*\n * Using desktop mouse events to simulate touch events should only be enabled as needed.\n */\n if (MAXDEBUG) {\n control.addEventListener(\n 'mousedown',\n function onMouseDown(event) { video.onTouchStart(event); },\n false // we'll specify false for the 'useCapture' parameter for now...\n );\n control.addEventListener(\n 'mousemove',\n function onMouseMove(event) { video.onTouchMove(event); },\n true\n );\n control.addEventListener(\n 'mouseup',\n function onMouseUp(event) { video.onTouchEnd(event); },\n false // we'll specify false for the 'useCapture' parameter for now...\n );\n }\n\n // this.log(\"touch events captured\");\n\n this.xTouch = this.yTouch = this.timeTouch = -1;\n\n /*\n * As long as fTouchDefault is false, we call preventDefault() on every touch event, to prevent\n * the page from moving/scrolling while the canvas is processing touch events. However, there must\n * also be exceptions to permit the soft keyboard to activate; see processTouchEvent() for details.\n */\n this.fTouchDefault = false;\n\n /*\n * I also need to come up with some rules for when the simulated mouse's primary button stays down.\n * Let's try setting a timeout handler whenever a touchstart is received, which we'll immediately cancel\n * as soon as a touchmove or touchend event is received, and if the timeout handler fires, we'll set\n * fLongTouch to true.\n */\n this.hLongTouch = null;\n this.fLongTouch = false;\n this.onLongTouch = function onLongTouch() { video.startLongTouch(); };\n }\n }\n }\n\n /**\n * onFocusChange(fFocus)\n *\n * @this {Video}\n * @param {boolean} fFocus is true if gaining focus, false if losing it\n */\n onFocusChange(fFocus)\n {\n /*\n * As per http://stackoverflow.com/questions/6740253/disable-scrolling-when-changing-focus-form-elements-ipad-web-app,\n * I decided to try this work-around to prevent the webpage from scrolling around whenever the canvas is given\n * focus. That sort of scrolling-into-view sounds great in principle, but in practice, if you were reading some other\n * portion of the page, it can be irritating to be scrolled away from that portion when refreshing/returning to the page.\n *\n * However, this work-around doesn't seem to work with the latest version of Safari (or else I misunderstood something).\n *\n * if (fFocus) {\n * window.scrollTo(0, 0);\n * document.body.scrollTop = 0;\n * }\n */\n this.fHasFocus = fFocus;\n if (this.kbd) this.kbd.onFocusChange(fFocus);\n }\n\n /**\n * onTouchStart(event)\n *\n * @this {Video}\n * @param {Event} event object from a 'touch' event\n */\n onTouchStart(event)\n {\n if (DEBUG) this.printMessage(\"onTouchStart()\");\n this.chipset.startAudio(event);\n if (this.nTouchConfig == Video.TOUCH.DEFAULT) return;\n this.processTouchEvent(event, true);\n }\n\n /**\n * onTouchMove(event)\n *\n * @this {Video}\n * @param {Event} event object from a 'touch' event\n */\n onTouchMove(event)\n {\n if (DEBUG) this.printMessage(\"onTouchMove()\");\n this.processTouchEvent(event);\n }\n\n /**\n * onTouchEnd(event)\n *\n * @this {Video}\n * @param {Event} event object from a 'touch' event\n */\n onTouchEnd(event)\n {\n if (DEBUG) this.printMessage(\"onTouchEnd()\");\n this.processTouchEvent(event, false);\n }\n\n /**\n * processTouchEvent(event, fStart)\n *\n * If nTouchConfig is non-zero, touch event handlers are installed, which pass their events to this function.\n *\n * What we do with those events here depends on the value of nTouchConfig. Originally, the only supported\n * configuration was the experimental conversion of touch events into arrow keys, based on an invisible grid\n * that divided the screen into thirds; that configuration is now identified as Video.TOUCH.KEYGRID.\n *\n * The new preferred configuration is Video.TOUCH.MOUSE, which does little more than allow you to \"push\" the\n * simulated mouse around. If Video.TOUCH.MOUSE is enabled, it's already been confirmed the machine has a mouse.\n *\n * @this {Video}\n * @param {Event|MouseEvent|TouchEvent} event object from a 'touch' event\n * @param {boolean} [fStart] (true if 'touchstart', false if 'touchend', undefined if 'touchmove')\n */\n processTouchEvent(event, fStart)\n {\n var xTouch, yTouch;\n\n // if (!event) event = window.event;\n\n /*\n * Touch coordinates (that is, the pageX and pageY properties) are relative to the page, so to make\n * them relative to the canvas, we must subtract the canvas's left and top positions. This Apple web page:\n *\n * https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/AddingMouseandTouchControlstoCanvas/AddingMouseandTouchControlstoCanvas.html\n *\n * makes it sound simple, but it turns out we have to walk the canvas' entire \"parentage\" of DOM elements\n * to get the exact offsets.\n *\n * TODO: Determine whether the getBoundingClientRect() code used in panel.js for mouse events can also\n * be used here to simplify this annoyingly complicated code for touch events.\n */\n var xTouchOffset = 0;\n var yTouchOffset = 0;\n var eCurrent = this.canvasScreen;\n\n do {\n if (!isNaN(eCurrent.offsetLeft)) {\n xTouchOffset += eCurrent.offsetLeft;\n yTouchOffset += eCurrent.offsetTop;\n }\n } while ((eCurrent = eCurrent.offsetParent));\n\n /*\n * Due to the responsive nature of our pages, the displayed size of the canvas may be smaller than the\n * allocated size, and the coordinates we receive from touch events are based on the currently displayed size.\n */\n var xScale = this.cxScreen / this.canvasScreen.offsetWidth;\n var yScale = this.cyScreen / this.canvasScreen.offsetHeight;\n\n /**\n * @name Event\n * @property {Array} targetTouches\n */\n if (!event.targetTouches || !event.targetTouches.length) {\n xTouch = event.pageX;\n yTouch = event.pageY;\n } else {\n xTouch = event.targetTouches[0].pageX;\n yTouch = event.targetTouches[0].pageY;\n }\n\n xTouch = ((xTouch - xTouchOffset) * xScale);\n yTouch = ((yTouch - yTouchOffset) * yScale);\n\n if (this.nTouchConfig == Video.TOUCH.KEYGRID) {\n\n /*\n * We don't want to simulate a key on EVERY touch event; preferably, only touchstart or touchend. And\n * I probably would have preferred triggering key presses on touchend, so that if you decided to move\n * your finger off-screen before releasing, you could avoid a key press, but sadly (as I've documented in\n * the Mandelbot project; see https://github.com/jeffpar/mandelbot/blob/master/src/mandelbot.js),\n * touchend doesn't reliably provide coordinates on all platforms, so we're going to go with touchstart.\n */\n if (fStart) {\n\n var xThird = (xTouch / (this.cxScreen / 3)) | 0;\n var yThird = (yTouch / (this.cyScreen / 3)) | 0;\n\n /*\n * At this point, xThird and yThird should both be one of 0, 1 or 2, indicating which horizontal and\n * vertical third of the virtual screen the touch event occurred.\n */\n this.kbd.addActiveKey(Video.KEYGRID[yThird][xThird], true);\n }\n } else {\n\n if (this.mouse) {\n /*\n * As long as fTouchDefault is false, we call preventDefault() on every touch event, to keep\n * the page stable. However, we must allow some touch event(s) to perform their default action,\n * otherwise the soft keyboard can never be activated. So if a touchstart occurs at least 1/2\n * second (500ms) after the last touchstart, with no intervening touchmove events, fTouchDefault\n * is allowed to become true.\n */\n var fTouchDefault = this.fTouchDefault;\n var timeDelta = event.timeStamp - this.timeTouch;\n\n if (fStart === true) {\n this.fTouchDefault = (timeDelta > 500);\n this.timeTouch = event.timeStamp;\n this.hLongTouch = setTimeout(this.onLongTouch, 500);\n } else {\n if (this.hLongTouch != null) {\n clearTimeout(this.hLongTouch);\n this.hLongTouch = null;\n }\n }\n if (fStart === undefined) {\n this.fTouchDefault = false;\n }\n\n if (DEBUG) {\n this.log(\"processTouchEvent(\" + (fStart? \"touchStart\" : (fStart === false? \"touchEnd\" : \"touchMove\")) + \",\" + timeDelta + \"ms,\" + fTouchDefault + \")\");\n }\n\n if (!fTouchDefault) {\n event.preventDefault();\n }\n\n if (fStart === false) {\n /*\n * NOTE: 200ms is merely my initial stab at a reasonable number of milliseconds to interpret a\n * start/end touch sequence as a \"tap\"; I also make no note of any intervening move events (ie,\n * events where fStart is undefined), and perhaps I should....\n */\n if (this.endLongTouch()) {\n return;\n }\n if (timeDelta < 200) {\n this.mouse.clickMouse(Mouse.BUTTON.LEFT, true);\n this.mouse.clickMouse(Mouse.BUTTON.LEFT, false);\n return;\n }\n }\n /*\n * This 'touchmove\" code mimics the 'mousemove' event processing in processMouseEvent() in mouse.js, with\n * one important difference: every time touching \"restarts\", we need to reset the variables used to calculate\n * the deltas, so that the mere act of lifting and replacing your finger doesn't generate a delta by itself.\n */\n if (fStart || this.xTouch < 0 || this.yTouch < 0) {\n this.xTouch = xTouch;\n this.yTouch = yTouch;\n }\n var xDelta = Math.round(xTouch - this.xTouch);\n var yDelta = Math.round(yTouch - this.yTouch);\n this.xTouch = xTouch;\n this.yTouch = yTouch;\n // this.println(\"moveMouse(\" + xDelta + \",\" + yDelta + \")\");\n this.mouse.moveMouse(xDelta, yDelta, this.xTouch, this.yTouch);\n }\n }\n }\n\n /**\n * startLongTouch()\n *\n * @this {Video}\n */\n startLongTouch()\n {\n this.fLongTouch = true;\n this.mouse.clickMouse(Mouse.BUTTON.LEFT, true);\n }\n\n /**\n * endLongTouch()\n *\n * @this {Video}\n * @return {boolean} true if long touch was active, false if not\n */\n endLongTouch()\n {\n if (this.fLongTouch) {\n this.mouse.clickMouse(Mouse.BUTTON.LEFT, false);\n this.fLongTouch = false;\n return true;\n }\n return false;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {Video}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data || !this.restore) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * This is where we might add some method of blanking the display, without the disturbing the video\n * buffer contents, and blocking all further updates to the display.\n *\n * @this {Video}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {Video}\n */\n reset()\n {\n var nMonitorType = ChipSet.MONITOR.NONE;\n\n /*\n * We'll ask the ChipSet what SW1 indicates for monitor type, but we may override it if a specific\n * video card model is set. For EGA, SW1 is supposed to be set to indicate NO monitor, and we rely\n * on the EGA's own switch settings instead.\n */\n if (this.chipset) {\n nMonitorType = this.chipset.getDIPVideoMonitor();\n }\n\n /*\n * As we noted in the constructor, when a model is specified, that takes precedence over any monitor\n * switch settings. Conversely, when no model is specified, the nCard setting is considered provisional,\n * so the monitor switch settings, if any, are allowed to determine the card type.\n */\n if (!this.model) {\n this.nCard = (nMonitorType == ChipSet.MONITOR.MONO? Video.CARD.MDA : Video.CARD.CGA);\n }\n\n this.nModeDefault = Video.MODE.CGA_80X25;\n\n switch (this.nCard) {\n case Video.CARD.VGA:\n nMonitorType = ChipSet.MONITOR.VGACOLOR;\n break;\n case Video.CARD.EGA:\n var aMonitors = Video.aEGAMonitorSwitches[this.bEGASwitches];\n /*\n * TODO: Figure out how to deal with aMonitors[2], the boolean which indicates\n * whether the EGA is driving the primary monitor (true) or the secondary monitor (false).\n */\n if (aMonitors) nMonitorType = aMonitors[0];\n if (!nMonitorType) nMonitorType = ChipSet.MONITOR.EGACOLOR;\n break;\n case Video.CARD.MDA:\n nMonitorType = ChipSet.MONITOR.MONO;\n this.nModeDefault = Video.MODE.MDA_80X25;\n break;\n case Video.CARD.CGA:\n /* falls through */\n default:\n nMonitorType = ChipSet.MONITOR.COLOR;\n break;\n }\n\n if (this.nMonitorType !== nMonitorType) {\n this.nMonitorType = nMonitorType;\n }\n\n this.cardActive = null;\n this.cardMono = this.cardMDA = new Card(this, Video.CARD.MDA);\n this.cardColor = this.cardCGA = new Card(this, Video.CARD.CGA);\n\n if (this.nCard < Video.CARD.EGA) {\n this.cardEGA = new Card(); // define a dummy (uninitialized) EGA card for now\n }\n else {\n this.cardEGA = new Card(this, this.nCard, null, this.cbMemory);\n this.enableEGA();\n }\n\n /*\n * We need to call buildFonts() *after* the card(s) are initialized but *before* setMode() is called.\n */\n this.buildFonts();\n\n this.nMode = null;\n this.setMode(this.nModeDefault);\n\n if (this.cardActive.addrBuffer && this.nRandomize) {\n /*\n * On the initial power-on, we initialize the video buffer to random characters, as a way of testing\n * whether our font(s) were successfully loaded. It's assumed that our default display mode is a text mode,\n * and that since this is a reset, the CRTC.START_ADDR registers are zero as well.\n *\n * If this is an MDA device, then the buffer should reside at 0xB0000 through 0xB0FFF, for a total length\n * of 4Kb (0x1000), where every even byte contains a character code, and every odd byte contains an attribute\n * code. See the ATTR bit definitions above for applicable color, intensity, and blink values. On a CGA\n * device, the buffer resides at 0xB8000 through 0xBBFFF, for a total length of 16Kb.\n *\n * Note that the only valid MDA display mode (7) is the 80x25 text mode, which uses 4000 bytes (2000 character\n * bytes + 2000 attribute bytes), not all 4096 bytes; addrScreenLimit reflects the visible limit, not the\n * physical limit. Also, as noted in updateScreen(), this simplistic calculation of the extent of visible\n * screen memory is valid only for text modes; in general, it's safer to use cardActive.sizeBuffer as the extent.\n */\n var addrScreenLimit = this.cardActive.addrBuffer + this.cbScreen;\n for (var addrScreen = this.cardActive.addrBuffer; addrScreen < addrScreenLimit; addrScreen += 2) {\n var dataRandom = (Math.random() * 0x10000)|0;\n var bChar, bAttr;\n if (this.nMonitorType == ChipSet.MONITOR.EGACOLOR || this.nMonitorType == ChipSet.MONITOR.VGACOLOR) {\n /*\n * For the EGA, we choose sequential characters; for random characters, copy the MDA/CGA code below.\n */\n bChar = (addrScreen >> 1) & 0xff;\n bAttr = (dataRandom >> 8) & ~Video.ATTRS.BGND_BLINK; // TODO: turn blink attributes off unless we can ensure blinking is initially disabled\n if ((bAttr >> 4) == (bAttr & 0xf)) {\n bAttr ^= 0x0f; // if background matches foreground, invert foreground to ensure character visibility\n }\n } else {\n bChar = dataRandom & 0xff;\n bAttr = ((dataRandom & 0x100)? (Video.ATTRS.FGND_WHITE | Video.ATTRS.BGND_BLACK) : (Video.ATTRS.FGND_BLACK | Video.ATTRS.BGND_WHITE)) | ((Video.ATTRS.FGND_BRIGHT /* | Video.ATTRS.BGND_BLINK */) & (dataRandom >> 8));\n }\n this.bus.setShortDirect(addrScreen, bChar | (bAttr << 8));\n }\n this.updateScreen(true);\n }\n }\n\n /**\n * enableEGA()\n *\n * Redirect cardMono or cardColor to cardEGA as appropriate.\n *\n * @this {Video}\n */\n enableEGA()\n {\n if (!(this.cardEGA.regMisc & Card.MISC.IO_SELECT)) {\n this.cardMono = this.cardEGA;\n this.cardColor = this.cardCGA; // this is done mainly to siphon away any CGA I/O\n } else {\n this.cardMono = this.cardMDA; // similarly, this is done to siphon away any MDA I/O\n this.cardColor = this.cardEGA;\n }\n }\n\n /**\n * save()\n *\n * This implements save support for the Video component.\n *\n * @this {Video}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.cardMDA.saveCard());\n state.set(1, this.cardCGA.saveCard());\n state.set(2, [this.nMonitorType, this.nModeDefault, this.nMode]);\n state.set(3, this.cardEGA.saveCard());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the Video component.\n *\n * @this {Video}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var a = data[2];\n this.nMonitorType = a[0];\n this.nModeDefault = a[1];\n this.nMode = a[2];\n\n this.cardActive = null;\n this.cardMono = this.cardMDA = new Card(this, Video.CARD.MDA, data[0]);\n this.cardColor = this.cardCGA = new Card(this, Video.CARD.CGA, data[1]);\n\n /*\n * If no EGA was originally initialized, then cardEGA will remain uninitialized.\n */\n this.cardEGA = new Card(this, this.nCard, data[3], this.cbMemory);\n if (this.cardEGA.fActive) this.enableEGA();\n\n /*\n * We need to call buildFonts() *after* the card(s) are initialized but *before* setMode() is called.\n */\n this.buildFonts();\n\n /*\n * While I could restore the active card here, it's better for setMode() to do it, because\n * setMode() will also take care of mapping the appropriate video buffer. So, after restore() has\n * finished, we call checkMode(), because the current video mode (nMode) is determined by the\n * active card state.\n *\n * Unfortunately, that creates a chicken-and-egg problem, since I just said I didn't want to select\n * the active card here.\n *\n * So, we'll add some \"cop-out\" code to checkMode(): if there's no active card, then fall-back\n * to the last known video mode (nMode) and force a call to setMode().\n *\n * this.cardActive = (this.cardMDA.fActive? this.cardMDA : (this.cardCGA.fActive? this.cardCGA : undefined));\n */\n if (!this.checkMode()) return false;\n\n this.checkCursor();\n return true;\n }\n\n /**\n * doneLoad(sURL, sFontData, nErrorCode)\n *\n * @this {Video}\n * @param {string} sURL\n * @param {string} sFontData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n doneLoad(sURL, sFontData, nErrorCode)\n {\n if (nErrorCode) {\n this.notice(\"Unable to load font ROM (error \" + nErrorCode + \": \" + sURL + \")\", nErrorCode < 0);\n return;\n }\n\n Component.addMachineResource(this.idMachine, sURL, sFontData);\n\n try {\n /*\n * The most likely source of any exception will be right here, where we're parsing the JSON-encoded data.\n */\n var abFontData = eval(\"(\" + sFontData + \")\");\n\n var ab = abFontData['bytes'] || abFontData;\n\n if (!ab.length) {\n Component.error(\"Empty font ROM: \" + sURL);\n return;\n }\n else if (ab.length == 1) {\n Component.error(ab[0]);\n return;\n }\n /*\n * Translate the character data into separate \"fonts\", each of which will be a separate canvas object, with all\n * 256 characters arranged in a 16x16 grid.\n */\n if (ab.length == 8192) {\n /*\n * The assumption here is that we're dealing with the original (IBM) MDA/CGA font data, which apparently\n * was identical on both MDA and CGA cards (even though the former had no use for the latter, and vice versa).\n *\n * First, let's take a look at the MDA portion of the data. Here are the first few rows of MDA font data,\n * at the 0K and 2K boundaries:\n *\n * 00000000 00 00 00 00 00 00 00 00 00 00 7e 81 a5 81 81 bd |..........~.....|\n * 00000010 00 00 7e ff db ff ff c3 00 00 00 36 7f 7f 7f 7f |..~........6....|\n * ...\n * 00000800 00 00 00 00 00 00 00 00 99 81 7e 00 00 00 00 00 |..........~.....|\n * 00000810 e7 ff 7e 00 00 00 00 00 3e 1c 08 00 00 00 00 00 |..~.....>.......|\n *\n * 8 bytes of data from a row in each of the 2K chunks are combined to form a 8-bit wide character with\n * a maximum height of 16 bits. Assembling the bits for character 0x01 (a happy face), we observe the following:\n *\n * 0 0 0 0 0 0 0 0 <== 00 from offset 0x0008\n * 0 0 0 0 0 0 0 0 <== 00 from offset 0x0009\n * 0 1 1 1 1 1 1 0 <== 7e from offset 0x000A\n * 1 0 0 0 0 0 0 1 <== 81 from offset 0x000B\n * 1 0 1 0 0 1 0 1 <== a5 from offset 0x000C\n * 1 0 0 0 0 0 0 1 <== 81 from offset 0x000D\n * 1 0 0 0 0 0 0 1 <== 81 from offset 0x000E\n * 1 0 1 1 1 1 0 1 <== bd from offset 0x000F\n * 1 0 0 1 1 0 0 1 <== 99 from offset 0x0808\n * 1 0 0 0 0 0 0 1 <== 81 from offset 0x0809\n * 0 1 1 1 1 1 1 0 <== 7e from offset 0x080A\n * 0 0 0 0 0 0 0 0 <== 00 from offset 0x080B\n * 0 0 0 0 0 0 0 0 <== 00 from offset 0x080C\n * 0 0 0 0 0 0 0 0 <== 00 from offset 0x080D\n * 0 0 0 0 0 0 0 0 <== 00 from offset 0x080E\n * 0 0 0 0 0 0 0 0 <== 00 from offset 0x080F\n *\n * In the second 2K chunk, we observe that the last two bytes of every font cell definition are zero;\n * this confirms our understanding that MDA font cell size is 8x14.\n *\n * Finally, there's the issue of screen cell size, which is actually 9x14 on the MDA. We compensate for that\n * by building a 9x14 font, even though there's only 8x14 bits of data. As http://www.seasip.info/VintagePC/mda.html\n * explains:\n *\n * \"For characters C0h-DFh, the ninth pixel column is a duplicate of the eighth; for others, it's blank.\"\n *\n * This last point is confirmed by \"The IBM Personal Computer From The Inside Out\", p.295:\n *\n * \"Another unique feature of the monochrome adapter is a set of line-drawing and area-fill characters\n * that give continuous lines and filled areas. This is unusual for a display with a 9x14 character box\n * because the character generator provides a row only eight dots wide. On most displays, a blank 9th\n * dot is then inserted between characters. On the monochrome display, there is circuitry that duplicates\n * the 8th dot into the 9th dot position for characters whose ASCII codes are 0xB0 [sic] through 0xDF.\"\n *\n * However, the above text is mistaken about the start of the range. While there ARE line-drawing characters\n * in the range 0xB0-0xBF, none of them extend all the way to the right edge; IBM carefully segregated them.\n * And in fact, characters 0xB0-0xB2 contain hash patterns that you would NOT want extended into the 9th column.\n *\n * The CGA font is part of the same ROM. In fact, there are TWO CGA fonts in the ROM: a thin 5x7 \"single dot\"\n * font located at offset 0x1000, and a thick 7x7 \"double dot\" font at offset 0x1800. The latter is the default\n * font, unless overridden by a jumper setting on the CGA card, so it is our default CGA font as well (although\n * someday we may provide a virtual jumper setting that allows you to select the thinner font).\n *\n * The first offset we must pass to setFontData() is the offset of the CGA font; we choose the thicker \"double dot\"\n * CGA font at 0x1800 (which was the PC's default font as well), instead of the thinner \"single dot\" font at 0x1000.\n * The second offset is for the MDA font.\n */\n this.setFontData(ab, [0x1800, 0x0000]);\n }\n else if (ab.length == 2048) {\n /*\n * The assumption here is that we're dealing strictly with CGA (8x8) font data, like the font data found\n * in the Columbia Data Products (CDP) Font ROM.\n */\n this.setFontData(ab, [0x0000]);\n }\n else {\n this.notice(\"Unrecognized font data length (\" + ab.length + \")\");\n return;\n }\n\n } catch (e) {\n this.notice(\"Font ROM data error: \" + e.message);\n return;\n }\n /*\n * If we're still here, then we're ready!\n *\n * UPDATE: Per issue #21, I'm issuing setReady() *only* if a valid contextScreen exists *or* a Debugger is attached.\n *\n * TODO: Consider a more general-purpose solution for deciding whether or not the user wants to run in a \"headless\" mode.\n */\n if (this.contextScreen || this.dbg) this.setReady();\n }\n\n /**\n * onROMLoad(abRom, aParms)\n *\n * Called by the ROM's copyROM() function whenever a ROM component with a 'notify' attribute containing\n * our component ID has been loaded.\n *\n * @this {Video}\n * @param {Array.<number>} abROM\n * @param {Array.<number>} [aParms]\n */\n onROMLoad(abROM, aParms)\n {\n if (this.nCard == Video.CARD.EGA) {\n /*\n * TODO: Unlike the MDA/CGA font data, we may want to hang onto this data, so that we can\n * regenerate the color font(s) whenever the foreground and/or background colors have changed.\n */\n if (DEBUG) this.printMessage(\"onROMLoad(): EGA fonts loaded\");\n /*\n * For EGA cards, in the absence of any parameters, we assume that we're receiving the original\n * IBM EGA ROM, which stores its 8x14 font data at 0x2230 as one continuous sequence; the total size\n * of the 8x14 font is 0xE00 bytes.\n *\n * At 0x3030, there is an \"ALPHA SUPPLEMENT\" table, which contains 15 bytes per row instead of 14,\n * because each row is preceded by one byte containing the corresponding ASCII code; there are 20\n * entries in the supplemental table, for a total size of 0x12C bytes.\n *\n * Finally, at 0x3160, we have the 8x8 font data (also known as the thicker \"double dot\" CGA font);\n * the total size of the 8x8 font is 0x800 bytes. No other font data is present in the EGA ROM;\n * the thin 5x7 \"single dot\" CGA font is notably absent, which is fine, because we never loaded it for\n * the MDA/CGA either.\n *\n * TODO: Determine how the supplemental table is used and whether we need to add some \"run-time\"\n * font generation to support it (as opposed to \"init-time\" generation, which is all we do now).\n * There's probably a similar need for user-defined fonts; for now, they're simply not supported.\n */\n this.setFontData(abROM, aParms || [0x3160, 0x2230], 8);\n }\n else if (this.nCard == Video.CARD.VGA) {\n if (DEBUG) this.printMessage(\"onROMLoad(): VGA fonts loaded\");\n /*\n * For VGA cards, in the absence of any parameters, we assume that we're receiving the original\n * IBM VGA ROM, which contains an 8x14 font at 0x3F8D (and corresponding supplemental table at 0x4D8D)\n * and an 8x8 font at 0x378D; however, it also contains an 8x16 font at 0x4EBA (and corresponding\n * supplemental table at 0x5EBA). See our reconstructed source code in ibm-vga.nasm.\n */\n this.setFontData(abROM, aParms || [0x378d, 0x3f8d], 8);\n }\n this.setReady();\n }\n\n /**\n * getCardColors(nBitsPerPixel)\n *\n * @this {Video}\n * @param {number} [nBitsPerPixel]\n * @returns {Array}\n */\n getCardColors(nBitsPerPixel)\n {\n if (nBitsPerPixel == 1) {\n /*\n * Only 2 total colors.\n */\n this.aRGB[0] = Video.aCGAColors[Video.ATTRS.FGND_BLACK];\n this.aRGB[1] = Video.aCGAColors[Video.ATTRS.FGND_WHITE];\n return this.aRGB;\n }\n\n if (nBitsPerPixel == 2) {\n /*\n * Of the 4 colors returned, the first color comes from regColor and the other 3 come from one of\n * the two hard-coded CGA color sets:\n *\n * Color Set 1 Color Set 2\n * ----------- -----------\n * Background (0x00) Background (0x00)\n * Green (0x12) Cyan (0x13)\n * Red (0x14) Magenta (0x15)\n * Brown (0x16) White (0x17)\n *\n * The numbers in parentheses are the EGA ATC palette register values that the EGA BIOS uses for each\n * color set; on an EGA, I synthesize a fake CGA regColor value, until I (TODO:) figure out exactly how\n * the EGA simulates the CGA color palette.\n */\n var regColor = this.cardActive.regColor;\n if (this.cardActive === this.cardEGA) {\n var bBackground = this.cardEGA.regATCData[0];\n regColor = bBackground & Card.CGA.COLOR.BORDER;\n if (bBackground & Card.ATC.PALETTE.BRIGHT) regColor |= Card.CGA.COLOR.BRIGHT;\n if (this.cardEGA.regATCData[1] != 0x12) regColor |= Card.CGA.COLOR.COLORSET2;\n }\n this.aRGB[0] = Video.aCGAColors[regColor & (Card.CGA.COLOR.BORDER | Card.CGA.COLOR.BRIGHT)];\n var aColorSet = (regColor & Card.CGA.COLOR.COLORSET2)? Video.aCGAColorSet2 : Video.aCGAColorSet1;\n for (var iColor = 0; iColor < aColorSet.length; iColor++) {\n this.aRGB[iColor+1] = Video.aCGAColors[aColorSet[iColor]];\n }\n return this.aRGB;\n }\n\n if (this.cardColor === this.cardCGA) {\n /*\n * There's no need to update this.aRGB if we simply want to return a hard-coded set of 16 colors.\n */\n return Video.aCGAColors;\n }\n\n\n\n if (this.fRGBValid && nBitsPerPixel && !this.aRGB[16]) {\n this.fRGBValid = false;\n }\n\n if (!this.fRGBValid) {\n\n var card = this.cardEGA;\n var aDAC = card.regDACData;\n var aRegs, i, dw, b, bRed, bGreen, bBlue;\n\n if (nBitsPerPixel == 8) {\n /*\n * The card must be a VGA, and it's using an (8bpp) mode that bypasses the ATC, so we need to pull\n * RGB data exclusively from the 256-entry DAC; each entry contains 6-bit red, green, and blue values\n * packed into bits 0-5, 6-11, and 12-17, respectively, each of which we effectively shift left 2 bits:\n * a crude 6-to-8-bit color conversion.\n */\n for (i = 0; i < 256; i++) {\n dw = aDAC[i] || 0;\n\n bRed = (dw << 2) & 0xfc;\n bGreen = (dw >> 4) & 0xfc;\n bBlue = (dw >> 10) & 0xfc;\n this.aRGB[i] = [bRed, bGreen, bBlue, 0xff];\n }\n } else {\n /*\n * We need to pull RGB data from the ATC; moreover, if the ATC hasn't been initialized yet,\n * we go with a default EGA-compatible 16-color palette. We'll also use the DAC if there is one\n * (ie, this is actually a VGA) and it appears to be initialized (ie, the VGA BIOS has been run).\n */\n var fDAC = (aDAC && aDAC[255]);\n aRegs = (card.regATCData[15] != null? card.regATCData : Video.aEGAPalDef);\n for (i = 0; i < 16; i++) {\n b = aRegs[i] & Card.ATC.PALETTE.MASK;\n /*\n * If the DAC is valid, we need to supplement the 6 bits of each ATC palette entry with the values\n * for bits 6 and 7 from the ATC COLORSEL register (and overwrite bits 4 and 5 if ATC.MODE.COLORSEL_ALL\n * is set as well).\n *\n * The only reasons the DAC wouldn't be valid are if 1) we're trying to display an image before the machine\n * and its BIOS have had a chance to initialize the DAC (because we don't preset it to anything, although\n * perhaps we should), or 2) this is an EGA, which doesn't have a DAC.\n */\n if (fDAC) {\n b |= (card.regATCData[Card.ATC.COLORSEL.INDX] & (Card.ATC.COLORSEL.DAC_BIT7 | Card.ATC.COLORSEL.DAC_BIT6)) << 4;\n if (card.regATCData[Card.ATC.MODE.INDX] & Card.ATC.MODE.COLORSEL_ALL) {\n b &= ~0x30;\n b |= (card.regATCData[Card.ATC.COLORSEL.INDX] & (Card.ATC.COLORSEL.DAC_BIT5 | Card.ATC.COLORSEL.DAC_BIT4)) << 4;\n }\n\n dw = aDAC[b];\n\n bRed = (dw << 2) & 0xfc;\n bGreen = (dw >> 4) & 0xfc;\n bBlue = (dw >> 10) & 0xfc;\n } else {\n bRed = (((b & 0x04)? 0xaa : 0) | ((b & 0x20)? 0x55 : 0));\n bGreen = (((b & 0x02)? 0xaa : 0) | ((b & 0x10)? 0x55 : 0));\n bBlue = (((b & 0x01)? 0xaa : 0) | ((b & 0x08)? 0x55 : 0));\n }\n this.aRGB[i] = [bRed, bGreen, bBlue, 0xff];\n }\n }\n this.fRGBValid = true;\n }\n\n return this.aRGB;\n }\n\n /**\n * setFontData(abFontData, aFontOffsets, cxFontChar)\n *\n * To support partial font rebuilds (required for the EGA), we now preserve the original font data (abFontData),\n * font offsets (aFontOffsets), and font character width (8 for the EGA, undefined for the MDA/CGA).\n *\n * TODO: Ultimately, we want to have exactly one dedicated font for the EGA, the data for which we'll read directly\n * from plane 2 of video memory, instead of relying on the original font data in ROM. Relying on the ROM data was\n * originally just a crutch to help get EGA support bootstrapped.\n *\n * Also, for the MDA/CGA, we should be discarding the font data after the first buildFonts() call, because we\n * should not need to ever rebuild the fonts for those cards (both their font patterns and colors were hard-coded).\n *\n * @this {Video}\n * @param {*} abFontData is the raw font data, from the ROM font file\n * @param {Array.<number>} aFontOffsets contains offsets into abFontData: [0] for CGA, [1] for MDA\n * @param {number} [cxFontChar] is a fixed character width to use for all fonts; undefined to use MDA/CGA defaults\n */\n setFontData(abFontData, aFontOffsets, cxFontChar)\n {\n this.abFontData = abFontData;\n this.aFontOffsets = aFontOffsets;\n this.cxFontChar = cxFontChar;\n }\n\n /**\n * buildFonts()\n *\n * buildFonts() is called whenever the Video component is reset or restored; we used to build the fonts as soon\n * as the ROM containing them was loaded, and then throw away the underlying font data, but with the EGA's ability\n * to change the color of any font, font building must now be deferred until the reset or restore notifications,\n * ensuring we have access to all the colors the card is currently programmed to use.\n *\n * We're also called whenever EGA palette registers are modified, since one or more fonts will likely need\n * to be rebuilt (this is because our fonts contain pre-rendered images of all glyphs for all 16 active colors).\n * Calls to buildFonts() should not be expensive though: the underlying createFont() function rebuilds a font only\n * if its color has actually changed.\n *\n * TODO: Our font code is still written with the assumption that, like the MDA/CGA, the underlying font data never\n * changes. The EGA, however, stores its fonts in plane 2, which means fonts are dynamic; this needs to be fixed.\n *\n * Supporting dynamic EGA fonts should not be hard though. We can get rid of abFontData and simply build a\n * temporary snapshot of all the font bytes in plane 2 of the EGA's video buffer (adwMemory), and pass that on to\n * buildFont() instead. We'll also need to either invalidate the existing font's color (to trigger a rebuild) or\n * pass a new \"force rebuild\" flag.\n *\n * Once that's done, an added benefit will be that we can build just the font(s) that have been loaded into plane 2,\n * instead of the multitude of fonts that we now build on a just-in-case basis (eg, the MDA font, the 8x8 CGA font\n * for 43-line mode, and so on).\n *\n * @this {Video}\n * @param {boolean} [fRebuild] (true if this is a rebuild, not an initial build)\n * @return {boolean} true if any or all fonts were (re)built, false if nothing changed\n */\n buildFonts(fRebuild)\n {\n var fChanges = false;\n\n /*\n * There's no point building fonts if this is a non-windowed (command-line) environment\n * OR no font data is available (OR this is a rebuild AND we're currently in a graphics mode).\n *\n * In other words, build fonts if this IS a windowed environment AND font data is available\n * AND this is not a rebuild, OR it IS a rebuild but we're in a graphics mode (ie, nFont is zero).\n */\n if (window && this.abFontData && (!fRebuild || this.nFont)) {\n\n var offSplit = 0x0000;\n var cxChar = this.cxFontChar? this.cxFontChar : 8;\n var aRGBColors = this.getCardColors();\n\n if (this.aFontOffsets[0] != null) {\n if (this.buildFont(Video.FONT.CGA, this.aFontOffsets[0], offSplit, cxChar, 8, this.abFontData, aRGBColors)) {\n fChanges = true;\n }\n }\n\n offSplit = this.cxFontChar? 0 : 0x0800;\n cxChar = this.cxFontChar? this.cxFontChar : 9;\n\n if (this.aFontOffsets[1] != null) {\n if (this.buildFont(Video.FONT.MDA, this.aFontOffsets[1], offSplit, cxChar, 14, this.abFontData, Video.aMDAColors, Video.aMDAColorMap)) {\n fChanges = true;\n }\n if (this.cxFontChar) {\n if (this.buildFont(this.nCard, this.aFontOffsets[1], 0, this.cxFontChar, 14, this.abFontData, aRGBColors)) {\n fChanges = true;\n }\n }\n }\n }\n if (!fRebuild) {\n /*\n * Perform some additional initialization common to both reset() and restore() sequences.\n */\n this.iCellCursor = -1; // initially, there is no visible cursor cell\n this.cBlinks = -1; // initially, blinking is not active\n this.cBlinkVisible = 0; // no visible blinking characters (yet)\n }\n return fChanges;\n }\n\n /**\n * buildFont(nFont, offData, offSplit, cxChar, cyChar, abFontData, aRGBColors, aColorMap)\n *\n * This is a wrapper for createFont() which also takes care loading double-size fonts when fDoubleFont is set.\n *\n * @this {Video}\n * @param {number} nFont\n * @param {number|null} offData is the offset of the font data, null if none\n * @param {number} offSplit is the offset of any split font data, or zero if not split\n * @param {number} cxChar is the width of the font characters\n * @param {number} cyChar is the height of the font characters\n * @param {*} abFontData is the raw font data, from the ROM font file\n * @param {Array} aRGBColors is an array of color RGB variations, corresponding to supported FGND attribute values\n * @param {Array} [aColorMap] contains color indexes corresponding to attribute values (if not supplied, the mapping is assumed to be 1-1)\n * @return {boolean} true if any or all fonts were (re)built, false if nothing changed\n */\n buildFont(nFont, offData, offSplit, cxChar, cyChar, abFontData, aRGBColors, aColorMap)\n {\n var fChanges = false;\n\n if (offData != null) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"buildFont(\" + nFont + \"): building \" + Video.cardSpecs[nFont][0] + \" font\");\n }\n if (this.createFont(nFont, offData, offSplit, cxChar, cyChar, abFontData, aRGBColors, aColorMap)) {\n fChanges = true;\n }\n }\n return fChanges;\n }\n\n /**\n * createFont(nFont, offData, offSplit, cxChar, cyChar, abFontData, aRGBColors, aColorMap)\n *\n * All color variations are stored on the same font canvas, arranged vertically as a series of grids, where each\n * grid is a 16x16 character glyph array.\n *\n * Since every character must be drawn first with its background color and then with the foreground shape on top,\n * I used to include a series of empty cells at the top every font canvas containing all supported background colors\n * (ie, before the character grids). But now createFont() also creates an aCSSColors array that is saved alongside\n * the font canvas, and updateChar() uses that array in conjunction with fillRect() to draw character backgrounds.\n *\n * @this {Video}\n * @param {number} nFont\n * @param {number} offData is the offset of the font data\n * @param {number} offSplit is the offset of any split font data, or zero if not split\n * @param {number} cxChar is the width of the font characters\n * @param {number} cyChar is the height of the font characters\n * @param {*} abFontData is the raw font data, from the ROM font file\n * @param {Array} aRGBColors is an array of color RGB variations, corresponding to supported FGND attribute values\n * @param {Array|undefined} aColorMap contains color indexes corresponding to attribute values (if not supplied, the mapping is assumed to be 1-1)\n * @return {boolean} true if any or all fonts were (re)created, false if nothing changed\n */\n createFont(nFont, offData, offSplit, cxChar, cyChar, abFontData, aRGBColors, aColorMap)\n {\n var fChanges = false;\n var nDouble = (this.fDoubleFont? 1 : 0);\n var font = this.aFonts[nFont];\n var nColors = (aRGBColors.length < 16? aRGBColors.length : 16);\n if (!font) {\n font = {\n cxCell: cxChar << nDouble,\n cyCell: cyChar << nDouble,\n aCSSColors: new Array(nColors),\n aRGBColors: aRGBColors.slice(0, nColors), // using the Array slice() method to simply make a copy\n aColorMap: aColorMap,\n aCanvas: new Array(nColors)\n };\n }\n for (var iColor = 0; iColor < nColors; iColor++) {\n var rgbColor = aRGBColors[iColor];\n var rgbColorOrig = font.aCSSColors[iColor]? font.aRGBColors[iColor] : [];\n if (rgbColor[0] !== rgbColorOrig[0] || rgbColor[1] !== rgbColorOrig[1] || rgbColor[2] !== rgbColorOrig[2]) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"creating font color \" + iColor + \" for font \" + nFont);\n }\n this.createFontColor(font, iColor, rgbColor, nDouble, offData, offSplit, cxChar, cyChar, abFontData);\n fChanges = true;\n }\n }\n this.aFonts[nFont] = font;\n return fChanges;\n }\n\n /**\n * createFontColor(font, iColor, rgbColor, nDouble, offData, offSplit, cxChar, cyChar, abFontData)\n *\n * Now we're ready to create a 16x16 character grid for the specified color. Note that all\n * the character bits are opaque (alpha=0xff) while all the surrounding bits are transparent\n * (alpha=0x00, as specified in the 4th byte of rgbOff).\n *\n * Originally, I created 256 ImageData objects, using context.createImageData(cxChar,cyChar),\n * then setting its pixels to match those of an individual character, and then drawing characters\n * with contextFont.putImageData(). But putImageData() is relatively slow....\n *\n * Now I create a new canvas, with dimensions that allow me to arrange all 256 characters in an\n * 16x16 grid -- much like the \"chargen.png\" bitmap used in the C1Pjs version of the Video component.\n * Then drawing becomes much the same as before, because it turns out that drawImage() accepts either\n * an image object OR a canvas object.\n *\n * This also yields better performance, since drawImage() is much faster than putImageData().\n * We still have to use putImageData() to build the font canvas, but that's a one-time operation.\n * \n * @this {Video}\n * @param {Font} font\n * @param {number} iColor\n * @param {Array} rgbColor contains the RGB values for iColor\n * @param {number} nDouble is 1 to double output font dimensions, 0 to match input dimensions\n * @param {number} offData is the offset of the font data\n * @param {number} offSplit is the offset of any split font data, or zero if not split\n * @param {number} cxChar is the width of the font characters\n * @param {number} cyChar is the height of the font characters\n * @param {*} abFontData is the raw font data, from the ROM font file\n */\n createFontColor(font, iColor, rgbColor, nDouble, offData, offSplit, cxChar, cyChar, abFontData)\n {\n var rgbOff = [0x00, 0x00, 0x00, 0x00];\n var canvasFont = document.createElement(\"canvas\");\n canvasFont.width = font.cxCell << 4;\n canvasFont.height = (font.cyCell << 4);\n var contextFont = canvasFont.getContext(\"2d\");\n\n var iChar, x, y;\n var cyLimit = (cyChar < 8 || !offSplit)? cyChar : 8;\n var imageChar = contextFont.createImageData(font.cxCell, font.cyCell);\n\n for (iChar = 0; iChar < 256; iChar++) {\n for (y = 0; y < cyChar; y++) {\n /*\n * fUnderline should be true only in the FONT_MDA case, and only for the odd color variations\n * (1 and 3, out of variations 0 to 4), and only for the two bottom-most rows of the character cell\n * (which I still need to confirm).\n */\n var fUnderline = (font.aColorMap && (iColor & 0x1) && y >= cyChar - 2);\n var offChar = (y < cyLimit? offData + iChar * cyLimit + y : offSplit + iChar * cyLimit + y - cyLimit);\n var b = abFontData[offChar];\n for (var nRowDoubler = 0; nRowDoubler <= nDouble; nRowDoubler++) {\n for (x = 0; x < cxChar; x++) {\n /*\n * This \"bit\" of logic takes care of those characters (0xC0-0xDF) whose 9th bit must mirror the 8th bit;\n * in all other cases, any bit past the 8th bit is automatically zero. It also takes care of embedding a\n * solid row of bits whenever fUnderline is true.\n *\n * TODO: For EGA/VGA, replication of the 9th dot needs to be based on the TEXT_9DOT bit of the ATC.MODE\n * register, which is particularly important for user-defined fonts that do not want that bit replicated.\n */\n var bit = (fUnderline? 1 : (b & (0x80 >> (x >= 8 && iChar >= 0xC0 && iChar <= 0xDF? 7 : x))));\n var xDst = (x << nDouble);\n var yDst = (y << nDouble) + nRowDoubler;\n var rgb = (bit? rgbColor : rgbOff);\n this.setPixel(imageChar, xDst, yDst, rgb);\n if (nDouble) this.setPixel(imageChar, xDst + 1, yDst, rgb);\n }\n }\n }\n /*\n * (iChar >> 4) performs the integer equivalent of Math.floor(iChar / 16), and (iChar & 0xf) is the equivalent of (iChar % 16).\n */\n contextFont.putImageData(imageChar, x = (iChar & 0xf) * font.cxCell, y = (iChar >> 4) * font.cyCell);\n }\n\n /*\n * The colors for cell backgrounds and cursor elements must be converted to CSS color strings.\n */\n font.aCSSColors[iColor] = \"#\" + Str.toHex(rgbColor[0], 2) + Str.toHex(rgbColor[1], 2) + Str.toHex(rgbColor[2], 2);\n font.aRGBColors[iColor] = rgbColor;\n\n /*\n * Enable this code if you want to see what the generated font looks like....\n *\n if (MAXDEBUG) {\n var iSrcColor = (iColor == 15? 0 : iColor + 1);\n this.contextScreen.fillStyle = aCSSColors[iSrcColor];\n this.contextScreen.fillRect(iColor*(font.cxCell<<2), 0, canvasFont.width>>2, font.cyCell<<4);\n this.contextScreen.drawImage(canvasFont, 0, iColor*(font.cyCell<<4), canvasFont.width>>2, font.cyCell<<4, iColor*(font.cxCell<<2), 0, canvasFont.width>>2, font.cyCell<<4);\n }\n */\n\n font.aCanvas[iColor] = canvasFont;\n }\n\n /**\n * checkBlink()\n *\n * Called at the end of every updateScreenText(), which may have updated cBlinkVisible to a non-zero value.\n *\n * Also called at the end of every checkCursor(); ie, whenever the CRT register(s) affecting the position or shape\n * of the hardware cursor have been modified, and any of iCellCursor, yCursor or cyCursor have been modified as a result.\n *\n * Note that the cursor always blinks when it's ON; it can only be turned OFF, moved off-screen, or its rate set to half\n * the normal blink rate (by default, it blinks at the normal blink rate). Bits 5-6 of the CRTC.CURSCAN register can\n * be set as follows:\n *\n * 00: Cursor blinks at normal blink rate\n * 01: Cursor is off\n * 10: (Same as 00)\n * 11: Cursor blinks at half the normal blink rate\n *\n * According to documentation, the normal blink rate is 1/16 of the frame rate (8 frames on, 8 off).\n *\n * TODO: As an aside, I've observed in the \"real world\" that the MDA cursor cycles about 3 times per second, and by \"cycle\"\n * I mean one full off-and-on-again cycle. I'm assuming that's the normal rate (00), not the slower \"half rate\" (11).\n * Since that's faster than our current cursor blink rate, we should look into an option to boost our rate, without adversely\n * affecting the attribute blink rate (which is currently hard-coded at half the cursor blink rate), and we should look into\n * supporting \"half rate\" blinking, too.\n *\n * @this {Video}\n * @return {boolean} true if there are things to blink, false if not\n */\n checkBlink()\n {\n if (this.cBlinkVisible > 0 || this.iCellCursor >= 0) {\n if (this.cBlinks < 0) {\n this.cBlinks = 0;\n /*\n * At this point, we can either fire up our own timer (doBlink), or rely on updateScreen() being\n * called by the CPU at regular bursts (eg, Video.UPDATES_PER_SECOND = 60) and advance cBlinks at\n * the start of updateScreen() accordingly.\n *\n * doBlink() wants to increment cBlinks every 266ms. On the other hand, if updateScreen() is being\n * called 60 times per second, that's about once every 16ms, so if every 16th updateScreen() increments\n * cBlinks, cBlinks should advance at the same rate.\n *\n * One side-effect of relying on the CPU driving our blink count is that whenever the CPU is halted\n * (eg, by our Debugger) all blinking stops -- all characters with the blink attribute AND the cursor.\n *\n * But that's more consistent with how we halt everything else (eg, the PITs, RTC, etc); our Debugger\n * halts the entire machine, not just the CPU.\n *\n * this.doBlink(true);\n */\n }\n return true;\n }\n this.cBlinks = -1;\n return false;\n }\n\n /**\n * checkCursor()\n *\n * Called whenever a CRT data register is updated, since there are multiple registers that can affect the\n * visibility of the cursor (more than these, actually, but I'm going to limit my initial support to standard\n * ROM BIOS controller settings):\n *\n * CRTC.MAXSCAN\n * CRTC.CURSCAN\n * CRTC.CURSCANB\n * CRTC.STARTHI\n * CRTC.STARTLO\n * CRTC.CURSORHI\n * CRTC.CURSORLO\n * \n * The top of the cursor starts at CURSCAN, and the bottom is CURSCANB - 1, except that if CURSCAN == CURSCANB\n * (or more precisely, if CURSCAN == CURSCANB mod 16), then a single scan line is still drawn. Also, on the EGA,\n * if CURSCANB < CURSCAN, a split cursor is drawn.\n * \n * Also, at least on the EGA, if CURSCANB is set to a value > MAXSCAN (typically 13 on an EGA), cursor scan line\n * drawing wraps around to zero and does not stop until we reach CURSCAN again. However, this happens only when\n * CURSCAN is <= MAXSCAN; if CURSCAN > MAXSCAN, then nothing is drawn, regardless of CURSCANB.\n *\n * @this {Video}\n * @return {boolean} true if the cursor is visible, false if not\n */\n checkCursor()\n {\n /*\n * The \"hardware cursor\" is never visible in graphics modes.\n */\n if (!this.nFont) return false;\n \n var card = this.cardActive;\n for (var i = Card.CRTC.CURSCAN; i <= Card.CRTC.CURSORLO; i++) {\n if (card.regCRTData[i] == null)\n return false;\n }\n\n var bCursorFlags = card.regCRTData[Card.CRTC.CURSCAN];\n var bCursorStart = bCursorFlags & Card.CRTC.CURSCAN_SLMASK;\n var bCursorEnd = card.regCRTData[Card.CRTC.CURSCANB] & Card.CRTCMASKS[Card.CRTC.CURSCANB];\n var bCursorMax = card.regCRTData[Card.CRTC.MAXSCAN] & Card.CRTCMASKS[Card.CRTC.MAXSCAN];\n var oCursorStart = bCursorStart, oCursorEnd = bCursorEnd;\n \n /*\n * Before range-checking CURSCAN and CURSCANB, let's see if the cursor is disabled by a starting value\n * outside the visible range; if so, simulate the condition by pretending the CURSCAN_BLINKOFF bit is set.\n * \n * For example, on a CGA, ThinkTank sets both CURSCAN and CURSCANB to 15, WordStar for PCjr sets CURSCAN and\n * CURSCANB to 12 and 13, respectively, and Rogue sets CURSCAN and CURSCANB to 15 and 0, respectively.\n */\n if (bCursorStart > bCursorMax) {\n bCursorFlags |= Card.CRTC.CURSCAN_BLINKOFF;\n }\n\n var bCursorWrap = 0;\n \n if (this.nCard != Video.CARD.EGA) {\n /*\n * Live and learn: I originally thought that the EGA introduced funky split cursors, but it turns\n * out that older cards did it, too (well, I've confirmed it on an actual MDA anyway; haven't tried\n * the CGA). I've also confirmed that the MDA did NOT have the \"mod 16\" EGA anomaly described below. \n */\n if (bCursorEnd < bCursorStart) {\n bCursorWrap = bCursorEnd + 1;\n bCursorEnd = bCursorMax;\n /*\n * The VGA didn't support funky split (aka wrap-around) cursors, so as above, we pretend that the\n * cursor has simply been disabled.\n */\n if (this.nCard == Video.CARD.VGA) {\n bCursorFlags |= Card.CRTC.CURSCAN_BLINKOFF;\n bCursorWrap = 0;\n }\n }\n else if (bCursorEnd > bCursorMax) {\n bCursorStart = 0;\n bCursorEnd = bCursorMax;\n }\n bCursorEnd++;\n }\n else {\n /*\n * HACK: The original EGA BIOS has a cursor emulation bug when 43-line mode is enabled; we used to\n * detect that particular combination of bad values and automatically fix them (we're so thoughtful),\n * but in retrospect, that doesn't seem very faithful. Better to fix things like this 1) only if\n * the user asks, and 2) preferably with a BIOS patch rather than monkeying with the hardware registers.\n *\n * if (this.nCard == Video.CARD.EGA) {\n * if (bCursorMax == 7 && bCursorStart == 4 && !bCursorEnd) bCursorEnd = 7;\n * }\n */\n /*\n * Here's another strange EGA anomaly: if CURSCAN == CURSCANB mod 16, then it's treated the same as if\n * CURSCAN == CURSCANB. For example, if you set (CURSCAN,CURSCANB) to either the decimal values\n * (4,19) or (4,21), you'll get a full block cursor, but if you set it to (4,20), you get a single line\n * cursor at row 4. Go figure!\n */\n if (bCursorStart == bCursorEnd % 16) {\n bCursorEnd = bCursorStart + 1;\n }\n else if (bCursorEnd < bCursorStart) {\n bCursorWrap = bCursorEnd;\n bCursorEnd = bCursorMax + 1;\n }\n else if (bCursorEnd > bCursorMax) {\n bCursorStart = 0;\n bCursorEnd = bCursorMax + 1;\n }\n }\n \n var bCursorSize = bCursorEnd - bCursorStart;\n\n /*\n * One way of disabling the cursor is to set bit 5 (Card.CRTC.CURSCAN_BLINKOFF) of the CRTC.CURSCAN flags;\n * another way is setting bCursorStart > bCursorEnd, which implies that bCursorSize <= 0.\n */\n if ((bCursorFlags & Card.CRTC.CURSCAN_BLINKOFF) || bCursorSize <= 0) {\n this.removeCursor();\n return false;\n }\n\n /*\n * The least tricky way of disabling (ie, hiding) the cursor is to simply move it to an off-screen position.\n */\n var iCellCursor = card.regCRTData[Card.CRTC.CURSORLO];\n iCellCursor |= (card.regCRTData[Card.CRTC.CURSORHI] & card.addrMaskHigh) << 8;\n\n var offStartAddr = card.regCRTData[Card.CRTC.STARTLO];\n offStartAddr |= (card.regCRTData[Card.CRTC.STARTHI] & card.addrMaskHigh) << 8;\n \n iCellCursor -= offStartAddr;\n \n if (this.iCellCursor != iCellCursor) {\n //\n // let rowFrom = (this.iCellCursor / this.nCols)|0;\n // let colFrom = (this.iCellCursor % this.nCols);\n // let rowTo = (iCellCursor / this.nCols)|0;\n // let colTo = (iCellCursor % this.nCols);\n // this.printf(\"checkCursor(): cursor moved from %d,%d to %d,%d\\n\", rowFrom, colFrom, rowTo, colTo);\n // this.removeCursor();\n //\n this.iCellCursor = iCellCursor;\n /*\n * We invalidate cBlinkVisible on a cursor position change to ensure the cursor will be redrawn on the\n * next call to updateScreenCells(). It has the downside of requiring ALL cells to be re-examined, not\n * just the old and new cursor cells, but the cell cache should prevent any unnecessary redrawing.\n */\n this.cBlinkVisible = -1;\n }\n\n /*\n * yCursor and cyCursor are no longer scaled at this point, because the necessary scaling will depend on\n * whether we're drawing the cursor to the on-screen or off-screen buffer, and updateChar() is in the best\n * position to determine that.\n *\n * We also record cyCursorCell, the hardware cell height, since we'll need to know what the yCursor and\n * cyCursor values are relative to when it's time to scale them.\n */\n if (this.yCursor !== bCursorStart || this.cyCursor !== bCursorSize || this.cyCursorWrap !== bCursorWrap) {\n this.printf(\"checkCursor(): cursor shape changed from %d,%d to %d,%d (0x%02x-0x%02x)\\n\", this.yCursor, this.cyCursor, bCursorStart, bCursorSize, oCursorStart, oCursorEnd);\n this.yCursor = bCursorStart;\n this.cyCursor = bCursorSize;\n this.cyCursorWrap = bCursorWrap;\n /*\n * TODO: Consider our redraw options for cursor shape changes, because invalidating cBlinkVisible won't\n * have the desired effect if the cursor is still in the same location. The only existing mechanism for\n * making this happen would be to invalidate the cell cache (reset fCellCacheValid), which is rather drastic.\n * Note that we don't have to worry about this if the cursor has ALSO just moved (ie, this.cBlinkVisible < 0).\n */\n // if (this.cBlinkVisible >= 0) this.fCellCacheValid = false;\n }\n \n this.cyCursorCell = bCursorMax + 1;\n\n /*\n * This next condition is critical; WordStar for PCjr (designed for the CGA) would program CURSCANB to 31,\n * whereas MAXSCAN was 7. This resulted in cyCursorCell of 8 and cyCursor of 32, producing elongated cursors\n * in updateChar(). By range-checking CURSCAN and CURSCANB against MAXSCAN above, that should no longer happen.\n * \n * This condition can also happen while the CRT controller is in an inconsistent state (ie, in the middle of\n * being completely reprogrammed), so we mustn't freak out.\n */\n if (this.cyCursor > this.cyCursorCell) {\n this.cyCursor = this.cyCursorCell;\n }\n \n this.checkBlink();\n return true;\n }\n\n /**\n * removeCursor()\n *\n * @this {Video}\n */\n removeCursor()\n {\n if (this.iCellCursor >= 0) {\n if (this.aCellCache !== undefined && this.iCellCursor < this.aCellCache.length) {\n var drawCursor = (Video.ATTRS.DRAW_CURSOR << 8);\n var data = this.aCellCache[this.iCellCursor];\n if (data & drawCursor) {\n data &= ~drawCursor;\n var col = this.iCellCursor % this.nCols;\n var row = (this.iCellCursor / this.nCols)|0;\n if (this.nFont && this.aFonts[this.nFont]) {\n /*\n * If we're using an off-screen buffer in text mode, then we need to keep it in sync with \"reality\".\n */\n if (this.contextBuffer) {\n this.updateChar(col, row, data, this.contextBuffer);\n }\n /*\n * While updating the on-screen canvas directly could open us up to potential subpixel artifacts again,\n * I'm hopeful that won't be the case, since removeCursor() is called only during certain well-defined\n * events. The alternative to this simple updateChar() call is unappealing: redrawing the ENTIRE off-screen\n * buffer to the on-screen canvas, just as updateScreen() does.\n */\n this.updateChar(col, row, data);\n }\n this.printf(\"removeCursor(): removed from %d,%d\\n\", row, col);\n this.aCellCache[this.iCellCursor] = data;\n }\n }\n this.iCellCursor = -1;\n }\n }\n\n /**\n * getCardAccess()\n *\n * @this {Video}\n * @return {number|undefined} current memory access setting, or undefined if unknown\n */\n getCardAccess()\n {\n var nAccess;\n var card = this.cardActive;\n\n this.fColor256 = false;\n var regGRCMode = card.regGRCData[Card.GRC.MODE.INDX];\n if (regGRCMode != null) {\n var nReadAccess = Card.ACCESS.READ.MODE0;\n var nWriteAccess = Card.ACCESS.WRITE.MODE0;\n var nWriteMode = regGRCMode & Card.GRC.MODE.WRITE.MASK;\n var regDataRotate = card.regGRCData[Card.GRC.DATAROT.INDX] & Card.GRC.DATAROT.MASK;\n switch (nWriteMode) {\n case Card.GRC.MODE.WRITE.MODE0:\n if (regDataRotate) {\n nWriteAccess = Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.ROT;\n switch (regDataRotate & Card.GRC.DATAROT.FUNC) {\n case Card.GRC.DATAROT.AND:\n nWriteAccess = Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.AND;\n break;\n case Card.GRC.DATAROT.OR:\n nWriteAccess = Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.OR;\n break;\n case Card.GRC.DATAROT.XOR:\n nWriteAccess = Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.XOR;\n break;\n default:\n break;\n }\n card.nDataRotate = regDataRotate & Card.GRC.DATAROT.COUNT;\n }\n break;\n case Card.GRC.MODE.WRITE.MODE1:\n nWriteAccess = Card.ACCESS.WRITE.MODE1;\n break;\n case Card.GRC.MODE.WRITE.MODE2:\n switch (regDataRotate & Card.GRC.DATAROT.FUNC) {\n default:\n nWriteAccess = Card.ACCESS.WRITE.MODE2;\n break;\n case Card.GRC.DATAROT.AND:\n nWriteAccess = Card.ACCESS.WRITE.MODE2 | Card.ACCESS.WRITE.AND;\n break;\n case Card.GRC.DATAROT.OR:\n nWriteAccess = Card.ACCESS.WRITE.MODE2 | Card.ACCESS.WRITE.OR;\n break;\n case Card.GRC.DATAROT.XOR:\n nWriteAccess = Card.ACCESS.WRITE.MODE2 | Card.ACCESS.WRITE.XOR;\n break;\n }\n break;\n case Card.GRC.MODE.WRITE.MODE3:\n if (this.nCard == Video.CARD.VGA) {\n nWriteAccess = Card.ACCESS.WRITE.MODE3;\n card.nDataRotate = regDataRotate & Card.GRC.DATAROT.COUNT;\n }\n break;\n default:\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"getCardAccess(): invalid GRC mode (\" + Str.toHexByte(regGRCMode) + \")\");\n }\n break;\n }\n if (regGRCMode & Card.GRC.MODE.READ.MODE1) {\n nReadAccess = Card.ACCESS.READ.MODE1;\n }\n /*\n * I discovered that when the IBM EGA ROM scrolls the screen in graphics modes 0x0D and 0x0E, it\n * reprograms this register for WRITE.MODE1 (which is fine) *and* EVENODD (which is, um, very odd).\n * Moreover, it does NOT make the complementary change to the SEQ.MEMMODE.SEQUENTIAL bit; under\n * normal circumstances, those two bits are always supposed to programmed oppositely.\n *\n * Until I can perform some tests on real hardware, I have to assume that the EGA scroll operation\n * is supposed to actually WORK in modes 0x0D and 0x0E, so I've decided to tie the trigger for my own\n * EVENODD functions to SEQ.MEMMODE.SEQUENTIAL being clear, instead of GRC.MODE.EVENODD being set.\n *\n * It's also possible that my EVENODD read/write functions are not implemented properly; when EVENODD\n * is in effect, which addresses get latched by a read, and to which addresses are latches written?\n * If EVENODD has no effect on the effective address used with the latches, then I should change the\n * EVENODD read/write functions accordingly.\n *\n * However, I've also done some limited testing with an emulated VGA running in text mode, and I've\n * discovered that toggling the GRC.MODE.EVENODD bit *alone* doesn't seem to affect the delivery of\n * text mode attributes from plane 1. So maybe this is the wiser change after all.\n *\n * TODO: Perform some tests on actual EGA/VGA hardware, to determine the proper course of action.\n *\n * if (regGRCMode & Card.GRC.MODE.EVENODD) {\n * nReadAccess |= Card.ACCESS.READ.EVENODD;\n * nWriteAccess |= Card.ACCESS.WRITE.EVENODD;\n * }\n */\n var regSEQMode = card.regSEQData[Card.SEQ.MEMMODE.INDX];\n if (regSEQMode != null) {\n if (!(regSEQMode & Card.SEQ.MEMMODE.SEQUENTIAL)) {\n nReadAccess |= Card.ACCESS.READ.EVENODD;\n nWriteAccess |= Card.ACCESS.WRITE.EVENODD;\n }\n if (regGRCMode & Card.GRC.MODE.COLOR256) {\n if (regSEQMode & Card.SEQ.MEMMODE.CHAIN4) {\n nReadAccess |= Card.ACCESS.READ.CHAIN4;\n nWriteAccess |= Card.ACCESS.WRITE.CHAIN4;\n }\n this.fColor256 = true;\n }\n }\n nAccess = nReadAccess | nWriteAccess;\n }\n return nAccess;\n }\n\n /**\n * setCardAccess(nAccess)\n *\n * @this {Video}\n * @param {number|undefined} nAccess (one of the Card.ACCESS.* constants)\n * @return {boolean} true if access may have changed, false if not\n */\n setCardAccess(nAccess)\n {\n var card = this.cardActive;\n if (card && nAccess != null && nAccess != card.nAccess) {\n\n this.printf(\"setCardAccess(0x%04x)\\n\", nAccess);\n\n card.setMemoryAccess(nAccess);\n\n /*\n * Note that setMemoryAccess() can fail, in which case it will an report error, indicating either a\n * misconfiguration or some sort of internal inconsistency; in any case, there's not much we can do about\n * it at this point, other than possibly reverting the current access setting. There's probably not much\n * point, however, because there's no guarantee that setMemoryAccess() didn't modify one or more blocks\n * before choking.\n */\n this.bus.setMemoryAccess(card.addrBuffer, card.sizeBuffer, card.getMemoryAccess(), true);\n return true;\n }\n return false;\n }\n\n /**\n * setDimensions()\n *\n * This is the workhorse of setMode()\n *\n * @this {Video}\n */\n setDimensions()\n {\n this.nFont = 0;\n this.nCols = this.nColsDefault;\n this.nRows = this.nRowsDefault;\n this.nColsLogical = this.nCols;\n this.nCellsPerWord = Video.aModeParms[Video.MODE.MDA_80X25][2];\n\n var cbPadding = 0;\n var modeParms = Video.aModeParms[this.nMode];\n if (modeParms) {\n\n this.nCols = modeParms[0];\n this.nRows = modeParms[1];\n this.nCellsPerWord = modeParms[2];\n cbPadding = modeParms[3]; // undefined for EGA/VGA graphics modes only\n this.nFont = modeParms[4]; // this will be undefined for all graphics modes\n\n if (this.nMonitorType == ChipSet.MONITOR.EGACOLOR || this.nMonitorType == ChipSet.MONITOR.VGACOLOR) {\n /*\n * When an EGA is connected to a CGA monitor, the old aModeParms table is correct: we must\n * use the hard-coded 8x8 \"CGA_80\" font. But when it's connected to an EGA monitor, we want\n * to use the 9x14 \"EGA\" color font instead.\n *\n * TODO: Can an EGA with a monochrome monitor be programmed for 43-line mode as well? If so,\n * then we'll need to load another MDA font variation, because we only load the 9x14 font for MDA.\n */\n if (this.cardActive === this.cardEGA && this.nFont == Video.FONT.CGA) {\n if ((this.cardEGA.regCRTData[Card.CRTC.EGA.MAXSCAN.INDX] & Card.CRTC.EGA.MAXSCAN.SLMASK) == 7) {\n /*\n * Vertical resolution of 350 divided by 8 (ie, scan lines 0-7) yields 43 whole rows.\n */\n this.nRows = this.cardEGA.getCRTCReg(Card.CRTC.EGA.VDEND) < 350? 43 : 50;\n }\n /*\n * Since we can also be called before any hardware registers have been initialized,\n * it may be best to not perform the following test (which is why it's commented out).\n */\n else /* if (this.cardEGA.regCRTData[Card.CRTC.EGA.MAXSCAN.INDX] == 13) */ {\n /*\n * Vertical resolution of 350 divided by 14 (ie, scan lines 0-13) yields exactly 25 rows.\n *\n * Note that a card's default font matches its card ID (eg, Video.CARD.EGA == Video.FONT.EGA,\n * and Video.CARD.VGA == Video.FONT.VGA)\n */\n this.nFont = this.nCard;\n }\n }\n }\n }\n\n this.nCells = (this.nCols * this.nRows)|0;\n this.nCellCache = (this.nCells / this.nCellsPerWord)|0;\n this.cbScreen = this.nCellCache;\n this.cbSplit = 0;\n\n if (cbPadding !== undefined) {\n this.cbScreen = ((this.cbScreen << 1) + cbPadding)|0;\n this.cbSplit = (this.cbScreen + cbPadding) >> 1;\n }\n\n /*\n * If no fonts were successfully loaded, there's no point in initializing the remaining drawing parameters.\n */\n if (!this.aFonts.length) return;\n\n this.cxScreenCell = (this.cxScreen / this.nCols)|0;\n this.cyScreenCell = (this.cyScreen / this.nRows)|0;\n\n if (this.nFont) {\n var font = this.aFonts[this.nFont];\n if (!font) {\n\n return;\n }\n /*\n * In text modes, we have the option of setting all the *Buffer variables to null instead of\n * allocating them, because updateChar(), as currently written, is capable of writing characters to\n * either an off-screen or on-screen context.\n *\n * this.imageBuffer = this.canvasBuffer = this.contextBuffer = null;\n */\n this.cxBuffer = this.cyBuffer = 0;\n if (font) {\n this.cxBuffer = this.nCols * font.cxCell;\n this.cyBuffer = this.nRows * font.cyCell;\n }\n } else {\n /*\n * CGA graphics modes have their \"cells\" (pixels) split evenly across two halves of the video buffer, with\n * EVEN scan lines in the first half and ODD scan lines in the second half, so unlike text modes, we can't set a\n * limit of what's visible on-screen to \"columns * rows\", so the screen limit is set to match the buffer limit.\n *\n * In addition, updateScreen() requires an off-screen imageData buffer that matches the size of the entire screen,\n * so that updateScreen() can set all pixels that have changed and then update the screen with a single drawImage().\n *\n * An alternative approach, with a smaller footprint, would be to allocate an off-screen buffer large enough for a\n * single scan line, and redraw one scan line at a time, but given how EVEN and ODD scan lines are spread across the\n * entire buffer, it's not clear there would be enough unchanged scan lines on average to make that approach faster.\n */\n this.cxScreenCell = this.cyScreenCell = 1; // in graphics mode, a cell is exactly one pixel\n this.cxBuffer = this.nCols;\n this.cyBuffer = this.nRows;\n }\n\n /*\n * Allocate the off-screen buffers\n */\n this.imageBuffer = this.contextScreen.createImageData(this.cxBuffer, this.cyBuffer);\n this.canvasBuffer = document.createElement(\"canvas\");\n this.canvasBuffer.width = this.cxBuffer;\n this.canvasBuffer.height = this.cyBuffer;\n this.contextBuffer = this.canvasBuffer.getContext(\"2d\");\n\n /*\n * Since cxCell and cyCell were originally defined in terms of cxScreen/nCols and cyScreen/nRows, you might think\n * these border calculations would always be zero, but that would mean you overlooked the code above which tries to\n * avoid stretching 40-column modes into an unpleasantly wide shape.\n */\n this.xScreenOffset = this.yScreenOffset = 0;\n this.cxScreenOffset = this.cxScreen;\n this.cyScreenOffset = this.cyScreen;\n\n var cxBorder = this.cxScreen - (this.nCols * this.cxScreenCell);\n var cyBorder = this.cyScreen - (this.nRows * this.cyScreenCell);\n if (cxBorder > 0) {\n this.xScreenOffset = (cxBorder >> 1);\n this.cxScreenOffset -= cxBorder;\n }\n if (cyBorder > 0) {\n this.yScreenOffset = (cyBorder >> 1);\n this.cyScreenOffset -= cyBorder;\n }\n if (cxBorder || cyBorder) {\n this.contextScreen.fillStyle = this.canvasScreen.style.backgroundColor;\n this.contextScreen.fillRect(0, 0, this.cxScreen, this.cyScreen);\n }\n }\n\n /**\n * checkMode(fForce)\n *\n * Called whenever the MDA/CGA's mode register (eg, Card.MDA.MODE.PORT, Card.CGA.MODE.PORT) is updated,\n * or whenever the EGA/VGA's GRC.MISC register is updated, or when we've just finished a restore().\n *\n * @this {Video}\n * @param {boolean} [fForce] is used to force a mode update, if we recognize the current mode\n * @return {boolean} true if successful, false if not\n */\n checkMode(fForce)\n {\n var nAccess;\n var nMode = this.nMode;\n var card = this.cardActive;\n\n if (!card) {\n /*\n * We are likely being called after a restore(), which needs us to call setMode() to insure the proper video\n * buffer is mapped in. So we unset this.nMode to guarantee that setMode() will be called, and if it wasn't set\n * to anything before, then we fall-back to the default mode.\n */\n this.nMode = null;\n if (nMode == null) nMode = this.nModeDefault;\n }\n else {\n if (card.nCard == Video.CARD.MDA) {\n nMode = Video.MODE.MDA_80X25;\n }\n else if (card.nCard >= Video.CARD.EGA) {\n /*\n * The sizeBuffer we choose reflects the amount of physical address space that all 4 planes\n * of EGA memory normally span, NOT the total amount of EGA memory. So for a 64Kb EGA card,\n * we would set card.sizeBuffer to 16Kb (0x4000).\n *\n * TODO: Need to take into account modes that \"chain\" planes together (eg, mode 0x0F, and\n * presumably mode 0x10, on an EGA card with only 64Kb).\n */\n nMode = null;\n var cbBuffer = card.cbMemory >> 2;\n var cbBufferText = (cbBuffer > 0x8000? 0x8000 : cbBuffer);\n\n var regGRCMisc = card.regGRCData[Card.GRC.MISC.INDX];\n if (regGRCMisc != null) {\n\n switch(regGRCMisc & Card.GRC.MISC.MAPMEM) {\n case Card.GRC.MISC.MAPA0128:\n card.addrBuffer = 0xA0000;\n card.sizeBuffer = cbBuffer; // 0x20000\n nMode = Video.MODE.UNKNOWN; // no BIOS mode uses this mapping, but we don't want to leave nMode null if we've come this far\n break;\n case Card.GRC.MISC.MAPA064:\n card.addrBuffer = 0xA0000;\n card.sizeBuffer = cbBuffer; // 0x10000\n nMode = (this.nMonitorType == ChipSet.MONITOR.MONO? Video.MODE.EGA_640X350_MONO : Video.MODE.EGA_640X350);\n break;\n case Card.GRC.MISC.MAPB032:\n card.addrBuffer = 0xB0000;\n card.sizeBuffer = cbBufferText;\n nMode = Video.MODE.MDA_80X25;\n break;\n case Card.GRC.MISC.MAPB832:\n card.addrBuffer = 0xB8000;\n card.sizeBuffer = cbBufferText;\n nMode = (this.nMonitorType == ChipSet.MONITOR.MONO? Video.MODE.CGA_80X25_BW : Video.MODE.CGA_80X25);\n break;\n default:\n break;\n }\n /*\n * TODO: The following mode discrimination code is all a bit haphazard, a byproduct of its slow evolution\n * from increasingly greater EGA support to increasingly greater VGA support. Make it more rational someday,\n * so that as support is added for even more modes (eg, \"Mode X\" variations, monochrome modes, etc), it\n * doesn't get totally out of control.\n *\n * One of the problems with the current approach is that it depends on the card's registers being programmed\n * in at least roughly the same order that the IBM EGA and VGA ROMs program them.\n */\n var regGRCMode = card.regGRCData[Card.GRC.MODE.INDX];\n\n /*\n * This text/graphics hybrid test detects the way Windows 95 reprograms the VGA on boot; ie, switching\n * to graphics mode 0x13 (320x200) without disturbing the text buffer contents, then reprogramming it\n * to enable graphics mode 0x15 (320x400), then drawing a logo in the 2nd half of the video memory, and\n * finally reprogramming regGRCMode and regGRCMisc to move the frame buffer back to its original text mode\n * location.\n */\n var fTextGraphicsHybrid = (regGRCMode & (Card.GRC.MODE.COLOR256 | Card.GRC.MODE.EVENODD)) == (Card.GRC.MODE.COLOR256 | Card.GRC.MODE.EVENODD);\n if (fTextGraphicsHybrid) {\n /*\n * When fTextGraphicsHybrid is true, we should be at the end of the above process, so addrBuffer\n * will have changed. Since we don't (yet) assign a special mode to that configuration, we must at\n * least set fForce to true, so that setMode() will notice the buffer address change and remap it.\n */\n if (card.addrBuffer != this.addrBuffer || card.sizeBuffer != this.sizeBuffer) {\n fForce = true;\n }\n }\n\n var nCRTCVertTotal = card.getCRTCReg(Card.CRTC.EGA.VTOTAL);\n var nCRTCMaxScan = card.regCRTData[Card.CRTC.EGA.MAXSCAN.INDX];\n var nCRTCModeCtrl = card.regCRTData[Card.CRTC.EGA.MODECTRL.INDX];\n\n var fSEQDotClock = (card.regSEQData[Card.SEQ.CLOCKING.INDX] & Card.SEQ.CLOCKING.DOTCLOCK);\n\n if (nMode != Video.MODE.UNKNOWN) {\n if (!(regGRCMisc & Card.GRC.MISC.GRAPHICS)) {\n /*\n * Here's where we handle text modes; since nMode will have been assigned a default\n * of either 0x02 or 0x03, convert that to either 0x05 or 0x04 if we're in a low-res\n * graphics mode, 0x06 otherwise.\n */\n nMode -= (fSEQDotClock? 2 : 0);\n }\n else if (card.addrBuffer != 0xA0000 && !fTextGraphicsHybrid && !(nCRTCModeCtrl & Card.CRTC.EGA.MODECTRL.COMPAT_MODE)) {\n /*\n * Here's where we handle CGA graphics modes; since nMode will have been assigned a\n * default of either 0x02 or 0x03, convert that to either 0x05 or 0x04 if we're in a\n * low-res graphics mode, 0x06 otherwise.\n *\n * For Windows 95, I've had to add BOTH the fTextGraphicsHybrid test, to avoid misdetecting\n * the logo display mode, AND the COMPAT_MODE test, to avoid misinterpreting the VDD's physical\n * (NOT logical) card reprogramming during windowed VM creation; the latter seems like a VDD bug,\n * because only the Windows display driver should be *physically* reprogramming the card then.\n */\n nMode = fSEQDotClock? (7 - nMode) : Video.MODE.CGA_640X200;\n } else {\n /*\n * Here's where we handle EGA/VGA graphics modes, discriminating among modes 0x0D and up;\n * we've already defaulted to either 0x0F or 0x10. If COLOR256 is set, then select mode\n * 0x13 (or greater), else if 200-to-400 scan-line conversion is in effect, select either\n * mode 0x0D or 0x0E, else if VGA resolution is set, select either mode 0x11 or 0x12.\n */\n if (card.regGRCData[Card.GRC.MODE.INDX] & Card.GRC.MODE.COLOR256) {\n if (nCRTCMaxScan & Card.CRTC.EGA.MAXSCAN.SLMASK) {\n /*\n * NOTE: Technically, VDEND is one of those CRTC registers that should be read using\n * card.getCRTCReg(), because there are overflow bits (8 and 9). However, all known modes\n * always SET bit 8 and CLEAR bit 9, so examining only bits 0-7 is sorta OK.\n */\n if (card.regCRTData[Card.CRTC.EGA.VDEND] <= 0x8F) {\n nMode = Video.MODE.VGA_320X200;\n }\n else { /* (card.regCRTData[Card.CRTC.EGA.VDEND] == 0xDF) */\n nMode = Video.MODE.VGA_320X240;\n }\n } else {\n nMode = Video.MODE.VGA_320X400;\n }\n }\n else if ((nCRTCMaxScan & Card.CRTC.EGA.MAXSCAN.CONVERT400) || nCRTCVertTotal < 350) {\n nMode = (fSEQDotClock? Video.MODE.EGA_320X200 : Video.MODE.EGA_640X200);\n } else if (nCRTCVertTotal >= 480) {\n nMode = (this.nMonitorType == ChipSet.MONITOR.MONO? Video.MODE.VGA_640X480_MONO : Video.MODE.VGA_640X480);\n }\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"checkMode(): nCRTCVertTotal=\" + nCRTCVertTotal + \", mode=\" + Str.toHexByte(nMode));\n }\n }\n }\n nAccess = this.getCardAccess();\n }\n }\n else if (card.regMode & Card.CGA.MODE.VIDEO_ENABLE) {\n /*\n * NOTE: For the CGA, we precondition any mode change on CGA.MODE.VIDEO_ENABLE being set, otherwise\n * we'll get spoofed by the ROM BIOS scroll code, which waits for vertical retrace and then turns CGA.MODE.VIDEO_ENABLE\n * off, using a hard-coded mode value (0x25) that does NOT necessarily match the the CGA video mode currently in effect.\n */\n if (!(card.regMode & Card.CGA.MODE.GRAPHIC_SEL)) {\n nMode = ((card.regMode & Card.CGA.MODE._80X25)? Video.MODE.CGA_80X25 : Video.MODE.CGA_40X25);\n if (card.regMode & Card.CGA.MODE.BW_SEL) {\n nMode -= 1;\n }\n } else {\n nMode = ((card.regMode & Card.CGA.MODE.HIRES_BW)? Video.MODE.CGA_640X200 : Video.MODE.CGA_320X200_BW);\n if (!(card.regMode & Card.CGA.MODE.BW_SEL)) {\n nMode -= 1;\n }\n }\n if (this.fOpacityReduced) {\n this.canvasScreen.style.opacity = \"1\";\n this.fOpacityReduced = false;\n }\n }\n else {\n /*\n * This code is responsible for simulating flicker on a CGA screen. Note that we have to also\n * call yieldCPU() to ensure that the browser \"comes up for air\" and honors the new opacity, otherwise\n * you'll see very intermittent flicker (which is actually more annoying than regular flicker, believe\n * it or not).\n *\n * You also have the option of setting opacityFlicker to something greater than zero (eg, \"0.5\") to\n * make the flicker less obtrusive; in fact, that might be more faithful to the persistence of a CGA\n * screen's phosphor. The downside is that if the VIDEO_ENABLE bit is ever turned for off a \"long time\",\n * then you'll be treated to a very unnatural persistence effect.\n */\n if (!this.fOpacityReduced && +this.opacityFlicker < 1) {\n this.fOpacityReduced = true;\n this.canvasScreen.style.opacity = this.opacityFlicker;\n this.cpu.yieldCPU();\n }\n }\n }\n\n /*\n * NOTE: If setMode() remaps the video memory, that will trigger calls to setCardAccess() to also update the\n * memory's access functions. However, if the memory access setting (nAccess) is about to change as well, those\n * changes will be moot until the setCardAccess() call that follows. Basically, whenever both memory mapping AND\n * access functions are changing, the memory will be in an inconsistent state until both setMode() and setCardAccess()\n * are finished.\n *\n * The setMode() call takes precedence; if we called setCardAccess() first, it might attempt to modify memory access\n * functions based on the card's addrBuffer setting, and if that doesn't match what's currently mapped, assertions\n * will be triggered (probably not fatal, but it would defeat the point of the assertions).\n */\n if (!this.setMode(nMode, fForce)) return false;\n\n this.setCardAccess(nAccess);\n\n return true;\n }\n\n /**\n * setMode(nMode, fForce)\n *\n * Set fForce to true to update the mode regardless of previous mode, or false to perform a normal update\n * that bypasses updateScreen() but still calls initCache().\n *\n * @this {Video}\n * @param {number|null} nMode\n * @param {boolean|undefined} [fForce] is set when checkMode() wants to force a mode update\n * @return {boolean} true if successful, false if failure\n */\n setMode(nMode, fForce)\n {\n if (nMode != null && (nMode != this.nMode || fForce)) {\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"setMode(\" + Str.toHexByte(nMode) + (fForce? \",force\" : \"\") + \")\", true, true);\n }\n\n this.cUpdates = 0; // count updateScreen() calls as a means of driving blink updates\n this.nMode = nMode;\n this.fRGBValid = false;\n\n /*\n * On an EGA, it's CRITICAL that a reset() invalidate cardActive, to ensure that the code below\n * releases the previous video buffer and installs a new one, even if there was no change in the\n * video buffer address or size, because otherwise the Memory blocks installed at the video buffer\n * address may still be using blocks of the EGA's previous memory buffer.\n *\n * When the EGA is reinitialized, a new memory buffer (adwMemory) is allocated (see initEGA()), and\n * this is where the mapping of that EGA memory buffer to the video buffer occurs. Other cards\n * (MDA or CGA) don't allocate/manage their own memory buffer, but even then, it's still a good idea\n * to always force this operation (eg, in case a switch setting changed the active video card).\n */\n var card = this.cardActive || (nMode == Video.MODE.MDA_80X25? this.cardMono : this.cardColor);\n\n if (card != this.cardActive || card.addrBuffer != this.addrBuffer || card.sizeBuffer != this.sizeBuffer) {\n\n this.removeCursor();\n\n if (this.addrBuffer) {\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"setMode(\" + Str.toHexByte(nMode) + \"): removing \" + Str.toHexLong(this.sizeBuffer) + \" bytes from \" + Str.toHexLong(this.addrBuffer));\n }\n\n if (!this.bus.removeMemory(this.addrBuffer, this.sizeBuffer)) {\n /*\n * TODO: Force this failure case and see how well the Video component deals with it.\n */\n return false;\n }\n if (this.cardActive) this.cardActive.fActive = false;\n }\n\n this.cardActive = card;\n card.fActive = true;\n\n this.addrBuffer = card.addrBuffer;\n this.sizeBuffer = card.sizeBuffer;\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"setMode(\" + Str.toHexByte(nMode) + \"): adding \" + Str.toHexLong(this.sizeBuffer) + \" bytes to \" + Str.toHexLong(this.addrBuffer));\n }\n\n var controller = (card === this.cardEGA? card : null);\n\n if (!this.bus.addMemory(card.addrBuffer, card.sizeBuffer, Memory.TYPE.VIDEO, controller)) {\n /*\n * TODO: Force this failure case and see how well the Video component deals with it.\n */\n return false;\n }\n }\n this.setDimensions();\n this.invalidateCache(true);\n this.updateScreen();\n }\n return true;\n }\n\n /**\n * setPixel(imageData, x, y, rgb)\n *\n * Worker function used by createFontColor() and updateScreen() (graphics modes only).\n *\n * @this {Video}\n * @param {Object} imageData\n * @param {number} x\n * @param {number} y\n * @param {Array.<number>} rgb is a 4-element array containing the red, green, blue and alpha values\n */\n setPixel(imageData, x, y, rgb)\n {\n var index = (x + y * imageData.width) * rgb.length;\n imageData.data[index] = rgb[0];\n imageData.data[index+1] = rgb[1];\n imageData.data[index+2] = rgb[2];\n imageData.data[index+3] = rgb[3];\n }\n\n /**\n * initCache()\n *\n * Initializes the contents of our internal cell cache.\n *\n * TODO: Consider changing this to a cache of RGB values, so that when the buffer is merely being color-cycled,\n * we don't have to update the entire screen. This will also allow invalidateCache() to honor the fModified flag,\n * bypassing initCache() when it is false.\n *\n * @this {Video}\n */\n initCache()\n {\n this.cBlinkVisible = -1; // force updateScreen() to recount visible blinking characters \n this.fCellCacheValid = false;\n var nCells = this.nCellCache;\n if (this.aCellCache === undefined || this.aCellCache.length != nCells) {\n this.aCellCache = new Array(nCells);\n }\n }\n\n /**\n * invalidateCache(fModified)\n *\n * Ensure that the next updateScreen() will update every cell; intended for situations where the entire screen needs\n * to be redrawn, even though the underlying data in the video buffer has not changed (and therefore cleanMemory() will\n * report that the buffer is still clean, and/or all the video data still matches everything in our cell cache).\n *\n * For example, when the palette is being cycled, the screen is being panned, the page is being flipped, etc.\n *\n * @this {Video}\n * @param {boolean} [fModified] (true if the buffer may have been modified, false if only color(s) may have changed)\n */\n invalidateCache(fModified)\n {\n if (!fModified) this.fRGBValid = false;\n this.initCache();\n }\n\n /**\n * updateChar(col, row, data, context)\n *\n * Updates a particular character cell (row,col) in the associated window.\n *\n * The data parameter is the attribute byte from the display buffer (fgnd attribute in the low nibble,\n * bgnd attribute in the high nibble), but updateScreen() supplements data with a couple internal attribute bits:\n *\n * ATTRS.DRAW_FGND: set for every cell whose fgnd element is currently on (ie, non-blinking, or whenever blink is on)\n * ATTRS.DRAW_CURSOR: set only for the cell containing the cursor, if any\n *\n * To make a character blink, we alternately draw its cell with ATTRS.DRAW_FGND set, and then again with\n * ATTRS.DRAW_FGND clear (meaning only the cell background is drawn).\n *\n * To make the cursor blink, we must alternately draw its entire cell with ATTRS.DRAW_CURSOR set, and then\n * draw it again with ATTRS.DRAW_CURSOR clear.\n *\n * @this {Video}\n * @param {number} col\n * @param {number} row\n * @param {number} data (if text mode, character code in low byte, attribute code in high byte)\n * @param {CanvasRenderingContext2D} [context]\n */\n updateChar(col, row, data, context)\n {\n /*\n * The caller MUST promise this.nFont is defined, and that the font in this.aFonts[this.nFont] has been loaded.\n */\n var bChar = data & 0xff;\n var bAttr = data >> 8;\n var iFgnd = bAttr & 0xf;\n var font = this.aFonts[this.nFont];\n if (font.aColorMap) iFgnd = font.aColorMap[iFgnd];\n\n /*\n * Just as aColorMap maps the foreground attribute to the appropriate foreground character grid,\n * it also maps the background attribute to the appropriate background color.\n */\n var xDst, yDst;\n var iBgnd = (bAttr >> 4) & 0xf;\n if (font.aColorMap) iBgnd = font.aColorMap[iBgnd];\n\n if (context) {\n xDst = col * font.cxCell;\n yDst = row * font.cyCell;\n context.fillStyle = font.aCSSColors[iBgnd];\n context.fillRect(xDst, yDst, font.cxCell, font.cyCell);\n } else {\n xDst = col * this.cxScreenCell + this.xScreenOffset;\n yDst = row * this.cyScreenCell + this.yScreenOffset;\n this.contextScreen.fillStyle = font.aCSSColors[iBgnd];\n this.contextScreen.fillRect(xDst, yDst, this.cxScreenCell, this.cyScreenCell);\n }\n\n if (MAXDEBUG && this.messageEnabled(Messages.VIDEO | Messages.BUFFER)) {\n this.log(\"updateCharBgnd(\" + col + \",\" + row + \",\" + bChar + \"): filled \" + xDst + \",\" + yDst);\n }\n\n if (bAttr & Video.ATTRS.DRAW_FGND) {\n /*\n * (bChar & 0xf) is the equivalent of (bChar % 16), and (bChar >> 4) is the equivalent of Math.floor(bChar / 16)\n */\n var xSrcFgnd = (bChar & 0xf) * font.cxCell;\n var ySrcFgnd = (bChar >> 4) * font.cyCell;\n\n if (MAXDEBUG && this.messageEnabled(Messages.VIDEO | Messages.BUFFER)) {\n this.log(\"updateCharFgnd(\" + col + \",\" + row + \",\" + bChar + \"): draw from \" + xSrcFgnd + \",\" + ySrcFgnd + \" (\" + font.cxCell + \",\" + font.cyCell + \") to \" + xDst + \",\" + yDst);\n }\n\n if (context) {\n context.drawImage(font.aCanvas[iFgnd], xSrcFgnd, ySrcFgnd, font.cxCell, font.cyCell, xDst, yDst, font.cxCell, font.cyCell);\n } else {\n this.contextScreen.drawImage(font.aCanvas[iFgnd], xSrcFgnd, ySrcFgnd, font.cxCell, font.cyCell, xDst, yDst, this.cxScreenCell, this.cyScreenCell);\n }\n }\n\n if (bAttr & Video.ATTRS.DRAW_CURSOR) {\n if (this.cyCursorWrap) {\n this.drawCursor(0, this.cyCursorWrap, xDst, yDst, iFgnd, font, context);\n }\n this.drawCursor(this.yCursor, this.cyCursor, xDst, yDst, iFgnd, font, context);\n }\n }\n\n /**\n * drawCursor(yCursor, cyCursor, xDst, yDst, iFgnd, font, context)\n *\n * We have factored the cursor-drawing code out of updateChar() so that we can call this function multiple times,\n * in case we have to draw a \"split cursor\" (something that only happens on the EGA).\n *\n * @this {Video}\n * @param {number} yCursor\n * @param {number} cyCursor\n * @param {number} xDst\n * @param {number} yDst\n * @param {number} iFgnd\n * @param {Font} font\n * @param {CanvasRenderingContext2D} [context]\n */\n drawCursor(yCursor, cyCursor, xDst, yDst, iFgnd, font, context)\n {\n /*\n * Drawing the cursor with lineTo() seemed logical, but it was complicated by the fact that the\n * TOP of the line must appear at \"yDst + this.yCursor\", whereas lineTo() wants to know the CENTER\n * of the line. So it's simpler to draw the cursor with another fillRect(). Here's the old code:\n *\n * this.contextScreen.strokeStyle = font.aCSSColors[iFgnd];\n * this.contextScreen.lineWidth = this.cyCursor;\n * this.contextScreen.beginPath();\n * this.contextScreen.moveTo(xDst, yDst + this.yCursor);\n * this.contextScreen.lineTo(xDst + this.cxScreenCell, yDst + this.yCursor);\n * this.contextScreen.stroke();\n *\n * Also, note that we're scaling the yCursor and cyCursor values here, instead of in checkCursor(), because\n * this is where we have all the required information: in the first case (off-screen buffer), the scaling must\n * be based on the font cell size (cxCell, cyCell), whereas in the second case (on-screen buffer), the scaling\n * must be based on the screen cell size (cxScreenCell,cyScreenCell).\n *\n * yCursor and cyCursor are actual hardware values, both relative to another hardware value: cyCursorCell.\n */\n if (context) {\n if (this.cyCursorCell && this.cyCursorCell !== font.cyCell) {\n yCursor = Math.round((yCursor * font.cyCell) / this.cyCursorCell);\n cyCursor = Math.round((cyCursor * font.cyCell) / this.cyCursorCell);\n }\n context.fillStyle = font.aCSSColors[iFgnd];\n context.fillRect(xDst, yDst + yCursor, font.cxCell, cyCursor);\n } else {\n if (this.cyCursorCell && this.cyCursorCell !== this.cyScreenCell) {\n yCursor = Math.round((yCursor * this.cyScreenCell) / this.cyCursorCell);\n cyCursor = Math.round((cyCursor * this.cyScreenCell) / this.cyCursorCell);\n }\n this.contextScreen.fillStyle = font.aCSSColors[iFgnd];\n this.contextScreen.fillRect(xDst, yDst + yCursor, this.cxScreenCell, cyCursor);\n }\n }\n\n /**\n * updateScreen(fForce)\n *\n * Propagates the video buffer to the cell cache and updates the screen with any changes. Forced updates\n * are generally internal updates triggered by an I/O operation or other state change, while non-forced updates\n * are the periodic updates coming from the CPU.\n *\n * @this {Video}\n * @param {boolean} [fForce] is used by setMode() to reset the cell cache and force a redraw\n */\n updateScreen(fForce = false)\n {\n /*\n * The Computer component maintains the fPowered setting on our behalf, so we use it.\n */\n if (!this.flags.powered) return;\n\n /*\n * If the card's video signal is disabled (eg, during a mode change), then skip the update,\n * unless fForce is set.\n */\n var fEnabled = false;\n var card = this.cardActive;\n\n if (card) {\n if (card !== this.cardEGA) {\n if (card.regMode & Card.CGA.MODE.VIDEO_ENABLE) fEnabled = true;\n }\n else {\n if (card.regATCIndx & Card.ATC.INDX_PAL_ENABLE) fEnabled = true;\n }\n }\n\n if (!fEnabled && !fForce) return;\n\n if (fForce) {\n this.initCache();\n }\n else {\n /*\n * This should never happen, but since updateScreen() is also called by Computer.updateStatus(),\n * better safe than sorry.\n */\n if (this.aCellCache === undefined) return;\n }\n\n /*\n * If cBlinks is \"enabled\" (ie, >= 0), then advance it once every 16 updateScreen() calls\n * (assuming an updateScreen() frequency of 60 per second; see Video.UPDATES_PER_SECOND).\n *\n * We assume that the CPU is calling us whenever fForce is undefined.\n */\n var fBlinkUpdate = false;\n if (!fForce && !(++this.cUpdates & 0xf) && this.cBlinks >= 0) {\n this.cBlinks++;\n fBlinkUpdate = true;\n }\n\n var iCell = 0;\n var nCells = this.nCells;\n\n /*\n * Calculate the VISIBLE start of screen memory (addrScreen), not merely the PHYSICAL start,\n * as well as the extent of it (cbScreen) and use those values for all addressing operations to follow.\n * FYI, in these calculations, offScreen does not refer to \"off-screen\" memory, but rather the \"offset\"\n * of the start of visible screen memory.\n */\n var addrBuffer = this.addrBuffer;\n var addrScreen = addrBuffer;\n var addrScreenLimit = addrScreen + this.sizeBuffer;\n\n /*\n * HACK: To deal with the fTextGraphicsHybrid 320x400 mode that Windows 95 uses (ie, when the buffer\n * is mapped to B800:0000 instead of A000:0000 and is configured for text mode access, but graphics are\n * still being displayed from the second half of video memory), we must ignore the programmed address.\n *\n * In that case, the hard-coded address range below isn't actually active either, but it doesn't matter;\n * we just have to get through the rest of this function and make it to the updateScreenGraphicsVGA() call,\n * which will draw from our video buffer (adwMemory) directly; these addresses are only used for bounds\n * checking.\n */\n if (this.nMode >= Video.MODE.VGA_320X200) {\n addrBuffer = addrScreen = 0xA0000;\n addrScreenLimit = addrScreen + 0x10000;\n }\n\n /*\n * HACK: The CRTC's STARTHI and STARTLO registers are supposed to be \"latched\" into offStartAddr\n * ONLY at the start of every VRETRACE interval; this is an attempt to honor that behavior,\n * but unfortunately, updateScreen() is currently called at the CPU's discretion, not necessarily in\n * sync with nCyclesVertPeriod. As a result, we must rely on other criteria, like the number of vertical\n * periods that have elapsed since the last CRTC write, writes to the ATC (see outATC()), etc.\n *\n * TODO: Consider matching the CPU's nCyclesNextVideoUpdate to the card's nCyclesVertPeriod, ensuring\n * that CPU bursts are in sync with VRETRACE. Note, however, that that will be complicated by other\n * factors, such as the horizontal retrace interval, and the timing requirements of other cards in a\n * multi-display configuration.\n */\n if ((this.getRetraceBits(card) & Card.CGA.STATUS.VRETRACE) || card.nVertPeriodsStartAddr && card.nVertPeriodsStartAddr < card.nVertPeriods) {\n /*\n * PARANOIA: Don't call invalidateCache() unless the address we're about to \"latch\" actually changed.\n */\n var offStartAddr = card.regCRTData[Card.CRTC.STARTLO];\n offStartAddr |= (card.regCRTData[Card.CRTC.STARTHI] & card.addrMaskHigh) << 8;\n if (card.offStartAddr !== offStartAddr) {\n card.offStartAddr = offStartAddr;\n this.invalidateCache();\n }\n card.nVertPeriodsStartAddr = 0;\n }\n\n /*\n * Any screen (aka \"page\") offset must be doubled for text modes, due to the attribute bytes.\n * TODO: Come up with a more robust method of deciding when any screen offset should be doubled.\n */\n addrScreen += card.offStartAddr << (this.nFont? 1 : 0);\n var cbScreen = this.cbScreen;\n\n if (this.nCard >= Video.CARD.EGA && card.regCRTData[Card.CRTC.EGA.OFFSET] && (card.regCRTData[Card.CRTC.EGA.OFFSET] << 1) != card.regCRTData[Card.CRTC.EGA.HDEND] + 1) {\n /*\n * Pre-EGA, the extent of visible screen memory (cbScreen) was derived from nCols * nRows, but since\n * then, the logical width of screen memory (nColsLogical) can differ from the visible width (nCols).\n * We now calculate the logical width, and the compute a new cbScreen in much the same way the original\n * cbScreen was computed (but without any CGA-related padding considerations).\n *\n * TODO: I'm taking a lot of shortcuts in this calculation (eg, relying on nFont to detect text modes,\n * ignoring MODECTRL.BYTE_MODE, etc); generalize this someday. In addition, dividing the total number of\n * cells by nCellsPerWord yields total WORDS, not BYTES, so we need to double cbScreen -- EXCEPT that the\n * notion of cell has a slightly different meaning for EGA and VGA-specific modes. nCellsPerWord should\n * not be overloaded like that.\n */\n this.nColsLogical = card.regCRTData[Card.CRTC.EGA.OFFSET] << (this.nFont? 1 : (card.regCRTData[Card.CRTC.EGA.UNDERLINE.INDX] & Card.CRTC.EGA.UNDERLINE.DWORD)? 3 : 4);\n cbScreen = ((this.nColsLogical * (this.nRows-1) + this.nCols) / this.nCellsPerWord)|0;\n if (this.nMode <= Video.MODE.MDA_80X25) cbScreen <<= 1;\n }\n\n /*\n * If the amount of data (cbScreen) we need to display goes beyond the end of the screen buffer\n * (addrScreenLimit), then the assumption is that we will have to do a second update operation that\n * wraps around to addrBuffer.\n */\n var addrScreenWrap = 0, cbScreenWrap = 0;\n if (addrScreen + cbScreen > addrScreenLimit) {\n /*\n * There are two possibilities here: addrScreen itself is at or beyond addrScreenLimit, or just a\n * portion of cbScreen goes beyond the limit. We'll deal with the first case first.\n */\n cbScreenWrap = cbScreen;\n if (addrScreen >= addrScreenLimit) {\n addrScreenWrap = addrBuffer + (addrScreen - addrScreenLimit);\n cbScreen = 0;\n } else {\n addrScreenWrap = addrBuffer;\n cbScreen = addrScreenLimit - addrScreen;\n cbScreenWrap -= cbScreen;\n }\n }\n /*\n * updateScreenCells() no longer \"scrubs\" the screen buffer itself; we call cleanMemory() afterward\n * to take care of that. This has two benefits: 1) if this was a \"forced\" updated (or an update to make\n * the cell cache valid), cleaning the screen buffer ourselves reflects the fact that both it and our\n * display are now \"in sync\"; 2) if screen wrap-around is in effect, we don't want to scrub either subset\n * of the screen until both subsets have been updated, otherwise the second update may erroneously think\n * that nothing changed if it happens to share any blocks with the first.\n */\n var cBlinkOrig = this.cBlinkVisible;\n var cCells = this.updateScreenCells(addrBuffer, addrScreen, cbScreen, iCell, nCells, fForce, fBlinkUpdate);\n if (cbScreenWrap) {\n iCell += cCells;\n var cBlinkNew = this.cBlinkVisible;\n if (cBlinkOrig < 0) this.cBlinkVisible = -1;\n cCells += this.updateScreenCells(addrBuffer, addrScreenWrap, cbScreenWrap, iCell, nCells, fForce, fBlinkUpdate);\n this.cBlinkVisible += cBlinkNew;\n this.bus.cleanMemory(addrScreenWrap, cbScreenWrap);\n }\n this.bus.cleanMemory(addrScreen, cbScreen);\n if (cCells) this.fCellCacheValid = true;\n }\n\n /**\n * updateScreenCells(addrBuffer, addrScreen, cbScreen, iCell, nCells, fForce, fBlinkUpdate)\n *\n * @this {Video}\n * @param {number} addrBuffer\n * @param {number} addrScreen\n * @param {number} cbScreen\n * @param {number} iCell\n * @param {number} nCells\n * @param {boolean} fForce\n * @param {boolean} fBlinkUpdate\n * @return {number} (number of cells processed)\n */\n updateScreenCells(addrBuffer, addrScreen, cbScreen, iCell, nCells, fForce, fBlinkUpdate)\n {\n var cCells = cbScreen >> 1;\n if (cCells > nCells) cCells = nCells;\n var addrScreenLimit = addrScreen + cbScreen;\n\n /*\n * This next bit of code can be completely disabled if we discover problems with the dirty\n * memory block tracking feature, or if we need to remove or disable that feature in the future.\n *\n * We use cleanMemory() to check the video buffer's dirty state. If the buffer is clean\n * AND there are no visible blinking characters (as of the last updateScreen) AND there is\n * no visible cursor, then we're done; simply return. Otherwise, if there's only a blinking\n * cursor, then update JUST that one cell.\n */\n if (!fForce && this.fCellCacheValid && this.bus.cleanMemory(addrScreen, cbScreen, true)) {\n if (!fBlinkUpdate && this.cBlinkVisible >= 0) {\n return cCells;\n }\n if (!this.cBlinkVisible) {\n /*\n * iCellCursor may be negative if the cursor is hidden or if it's not on the visible screen.\n */\n var iCellCursor = this.iCellCursor - iCell;\n if (iCellCursor < 0) {\n return cCells;\n }\n addrScreen += (iCellCursor << 1);\n iCell += iCellCursor;\n nCells = iCell + 1;\n }\n // else if (this.cBlinks & 0x1) return;\n }\n\n if (this.nFont) {\n /*\n * This is the text-mode update case. We're required to FIRST verify that the current font\n * has been successfully loaded, because we're not allowed to call updateChar() if there's no font.\n */\n if (this.aFonts[this.nFont]) {\n this.updateScreenText(addrScreen, addrScreenLimit, iCell, nCells);\n }\n }\n else if (this.cbSplit) {\n /*\n * All CGA graphics modes have the goofy split-buffer layout, hence the simple test above.\n */\n cCells = this.updateScreenGraphicsCGA(addrScreen, addrScreenLimit);\n }\n else if (!this.fColor256) {\n /*\n * All EGA graphics modes are taken care of here, including all 16-color VGA graphics modes.\n */\n cCells = this.updateScreenGraphicsEGA(addrBuffer, addrScreen, addrScreenLimit);\n }\n else {\n /*\n * Finally, all 256-color VGA modes are processed here.\n */\n cCells = this.updateScreenGraphicsVGA(addrBuffer, addrScreen, addrScreenLimit);\n }\n return cCells;\n }\n\n /**\n * updateScreenText(addrScreen, addrScreenLimit, iCell, nCells)\n *\n * @this {Video}\n * @param {number} addrScreen\n * @param {number} addrScreenLimit\n * @param {number} iCell\n * @param {number} nCells\n * @return {number} (number of cells processed)\n */\n updateScreenText(addrScreen, addrScreenLimit, iCell, nCells)\n {\n /*\n * If MDA.MODE.BLINK_ENABLE is set and a cell's blink bit is set, then if (cBlinks & 0x2) != 0,\n * we want the foreground element of the cell to be drawn; otherwise we don't. So every 16-bit\n * data word we pull from the video buffer will be supplemented with our own special attribute bit\n * (ATTRS.DRAW_FGND = 0x100) accordingly; and to simplify the drawing code, we will also mask the\n * blink bit from the cell's attribute bits.\n *\n * If MDA.MODE.BLINK_ENABLE is clear, then we always set ATTRS.DRAW_FGND and never mask the blink\n * bit in a cell's attributes bits, since it's actually an intensity bit in that case.\n */\n var cCells = 0, cUpdated = 0;\n var dataBlink = 0;\n var dataDraw = (Video.ATTRS.DRAW_FGND << 8);\n var dataMask = 0xfffff;\n var fBlinkEnable = (this.cardActive.regMode & Card.MDA.MODE.BLINK_ENABLE);\n if (this.nCard >= Video.CARD.EGA) {\n fBlinkEnable = (this.cardActive.regATCData[Card.ATC.MODE.INDX] & Card.ATC.MODE.BLINK_ENABLE);\n }\n\n if (fBlinkEnable) {\n dataBlink = (Video.ATTRS.BGND_BLINK << 8);\n dataMask &= ~dataBlink;\n if (!(this.cBlinks & 0x2)) dataMask &= ~dataDraw;\n }\n\n this.cBlinkVisible = 0;\n while (addrScreen < addrScreenLimit && iCell < nCells) {\n var data = this.bus.getShortDirect(addrScreen);\n data |= dataDraw;\n if (data & dataBlink) {\n this.cBlinkVisible++;\n data &= dataMask;\n }\n if (iCell == this.iCellCursor) {\n data |= ((this.cBlinks & 0x1)? (Video.ATTRS.DRAW_CURSOR << 8) : 0);\n }\n\n if (!this.fCellCacheValid || data !== this.aCellCache[iCell]) {\n var col = iCell % this.nCols;\n var row = (iCell / this.nCols)|0;\n /*\n * The following code is useful for setting a breakpoint (on the non-destructive \"cUpdated |= 0\" line)\n * when debugging the \"FlickerFree\" utility while doing a series of \"DIR\" listings on the screen. When\n * unusual data gets rendered past column 40, we've caught the utility clearing memory revealed by a\n * scroll.\n *\n * if (col > 40 && data != 106272) {\n * cUpdated |= 0;\n * }\n *\n * TODO: How do we prevent that data from being displayed until the code has finished clearing it?\n * One trick would be to extend the current CPU burst slightly every time the STATUS register is read\n * with the RETRACE bit set, since it's only at the end of those bursts that we do other things like\n * update timers, update the screen, etc.\n *\n * FYI, to see what that \"FlickerFree\" code looks like, see the inCardStatus() function.\n */\n this.updateChar(col, row, data, this.contextBuffer);\n this.aCellCache[iCell] = data;\n cUpdated++;\n }\n addrScreen += 2;\n cCells++;\n iCell++;\n }\n\n if (cUpdated && this.contextBuffer) {\n this.contextScreen.drawImage(this.canvasBuffer, 0, 0, this.cxBuffer, this.cyBuffer, this.xScreenOffset, this.yScreenOffset, this.cxScreenOffset, this.cyScreenOffset);\n }\n \n this.checkBlink();\n return cCells;\n }\n\n /**\n * updateScreenGraphicsCGA(addrScreen, addrScreenLimit)\n *\n * @this {Video}\n * @param {number} addrScreen\n * @param {number} addrScreenLimit\n * @return {number} (number of cells processed)\n */\n updateScreenGraphicsCGA(addrScreen, addrScreenLimit)\n {\n /*\n * This is the CGA graphics-mode update case, where cells are pixels spread across two halves of the buffer.\n */\n var cCells = (addrScreenLimit - addrScreen) >> 1;\n var iCell = 0, nPixelsPerCell = this.nCellsPerWord;\n var addr = addrScreen;\n var wPixelMask = (nPixelsPerCell == 16? 0x10000 : 0x30000);\n var nPixelShift = (nPixelsPerCell == 16? 1 : 2);\n var aPixelColors = this.getCardColors(nPixelShift);\n\n var x = 0, y = 0;\n var xDirty = this.nCols, xMaxDirty = 0, yDirty = this.nRows, yMaxDirty = 0;\n\n this.cBlinkVisible = 0;\n while (addr < addrScreenLimit) {\n var data = this.bus.getShortDirect(addr);\n\n if (this.fCellCacheValid && data === this.aCellCache[iCell]) {\n x += nPixelsPerCell;\n } else {\n this.aCellCache[iCell] = data;\n var wPixels = (data >> 8) | ((data & 0xff) << 8);\n var wMask = wPixelMask, nShift = 16;\n if (x < xDirty) xDirty = x;\n for (var iPixel = 0; iPixel < nPixelsPerCell; iPixel++) {\n var bPixel = (wPixels & (wMask >>= nPixelShift)) >> (nShift -= nPixelShift);\n this.setPixel(this.imageBuffer, x++, y, aPixelColors[bPixel]);\n }\n if (x > xMaxDirty) xMaxDirty = x;\n if (y < yDirty) yDirty = y;\n if (y >= yMaxDirty) yMaxDirty = y + 1;\n }\n addr += 2;\n iCell++;\n if (x >= this.nCols) {\n x = 0;\n y += 2;\n if (y > this.nRows)\n break;\n if (y == this.nRows) {\n y = 1;\n addr = addrScreen + this.cbSplit;\n }\n }\n }\n\n /*\n * Instead of blasting the ENTIRE imageBuffer into contextBuffer, and then blasting the ENTIRE\n * canvasBuffer onto contextScreen, even for the smallest change, let's try to be a bit smarter about\n * the update (well, to the extent that the canvas APIs permit).\n */\n if (xDirty < this.nCols) {\n var cxDirty = xMaxDirty - xDirty;\n var cyDirty = yMaxDirty - yDirty;\n // this.contextBuffer.putImageData(this.imageBuffer, 0, 0);\n this.contextBuffer.putImageData(this.imageBuffer, 0, 0, xDirty, yDirty, cxDirty, cyDirty);\n /*\n * While ideally I would draw only the dirty portion of canvasBuffer, there usually isn't a 1-1 pixel mapping\n * between canvasBuffer and contextScreen. In fact, the WHOLE POINT of the canvasBuffer is to leverage\n * drawImage()'s scaling ability; for example, a CGA graphics mode might be 640x200, whereas the canvas representing\n * the screen might be 960x400. In those situations, if we draw interior rectangles, we often end up with subpixel\n * artifacts along the edges of those rectangles. So it appears I must continue to redraw the entire canvasBuffer\n * on every change.\n *\n var xScreen = (((xDirty * this.cxScreen) / this.nCols) | 0);\n var yScreen = (((yDirty * this.cyScreen) / this.nRows) | 0);\n var cxScreen = (((cxDirty * this.cxScreen) / this.nCols) | 0);\n var cyScreen = (((cyDirty * this.cyScreen) / this.nRows) | 0);\n this.contextScreen.drawImage(this.canvasBuffer, xDirty, yDirty, cxDirty, cyDirty, xScreen, yScreen, cxScreen, cyScreen);\n */\n this.contextScreen.drawImage(this.canvasBuffer, 0, 0, this.nCols, this.nRows, 0, 0, this.cxScreen, this.cyScreen);\n }\n return cCells;\n }\n\n /**\n * updateScreenGraphicsEGA(addrBuffer, addrScreen, addrScreenLimit)\n *\n * TODO: Add support for blinking graphics (ATC.MODE.BLINK_ENABLE)\n *\n * @this {Video}\n * @param {number} addrBuffer\n * @param {number} addrScreen\n * @param {number} addrScreenLimit\n * @return {number} (number of cells processed)\n */\n updateScreenGraphicsEGA(addrBuffer, addrScreen, addrScreenLimit)\n {\n var iCell = 0;\n var cCells = addrScreenLimit - addrScreen;\n var addr = addrScreen;\n var aPixelColors = this.getCardColors();\n var adwMemory = this.cardActive.adwMemory;\n\n var x = 0, y = 0;\n var xDirty = this.nCols, xMaxDirty = 0, yDirty = this.nRows, yMaxDirty = 0;\n var iPixelFirst = this.cardActive.regATCData[Card.ATC.HPAN.INDX] & Card.ATC.HPAN.SHIFT_LEFT;\n\n /*\n * TODO: What should happen if the card is programmed such that nColsLogical is LESS THAN nCols?\n */\n var nRowAdjust = (this.nColsLogical > this.nCols? ((this.nColsLogical - this.nCols - iPixelFirst) >> 3) : 0);\n\n this.cBlinkVisible = 0;\n while (addr < addrScreenLimit) {\n var idw = addr++ - addrBuffer;\n\n var data = adwMemory[idw];\n\n /*\n * Figure out how many visible pixels this data represents; usually 8, unless panning is being used.\n */\n var iPixel, nPixels = 8;\n\n if (iPixelFirst) {\n /*\n * Notice that we're not using the cell cache when panning is active, because the cached cell data no\n * longer aligns with the data we're pulling out of the video buffer, and it's not clear that the effort\n * to realign the data and make a valid cache comparison would save enough work to make it worthwhile.\n */\n if (!x) {\n data <<= iPixelFirst;\n nPixels -= iPixelFirst;\n /*\n * This is as good a place as any to invalidate the cell cache when panning is active; this ensures\n * we don't rely on stale cache contents once panning stops.\n */\n this.fCellCacheValid = false;\n } else {\n iPixel = this.nCols - x;\n if (nPixels > iPixel) nPixels = iPixel;\n }\n } else {\n\n if (this.fCellCacheValid && data === this.aCellCache[iCell]) {\n x += nPixels;\n nPixels = 0;\n } else {\n this.aCellCache[iCell] = data;\n }\n iCell++;\n }\n\n if (nPixels) {\n if (x < xDirty) xDirty = x;\n for (iPixel = 0; iPixel < nPixels; iPixel++) {\n /*\n * 0x80808080 may LOOK like a 32-bit value, but it is not, because JavaScript treats it as a POSITIVE\n * number, and therefore outside the normal 32-bit integer range; however, the AND operator guarantees\n * that the result will be a 32-bit value, so it doesn't matter.\n */\n var dwPixel = data & 0x80808080;\n\n /*\n * Since assertions don't fix problems (only catch them, and only in DEBUG builds), I'm also ensuring\n * that bPixel will default to 0 if an undefined value ever slips through again.\n *\n * How did an undefined value slip through? We had (incorrectly) initialized entries in aEGADWToByte;\n * for example, we used to set aEGADWToByte[0x80808080] instead of aEGADWToByte[0x80808080|0]. The\n * former is a POSITIVE index that is outside the 32-bit integer range, whereas the latter is a NEGATIVE\n * index, which is what this code requires.\n */\n var bPixel = Video.aEGADWToByte[dwPixel] || 0;\n this.setPixel(this.imageBuffer, x++, y, aPixelColors[bPixel]);\n data <<= 1;\n }\n if (x > xMaxDirty) xMaxDirty = x;\n if (y < yDirty) yDirty = y;\n if (y >= yMaxDirty) yMaxDirty = y + 1;\n }\n\n\n\n if (x >= this.nCols) {\n x = 0;\n if (++y > this.nRows) break;\n addr += nRowAdjust;\n }\n }\n\n if (iPixelFirst) cCells = 0; // zero the cell count to inhibit setting fCellCacheValid\n\n /*\n * For a fascinating discussion of the best way to update the screen canvas at this point, see updateScreenGraphicsCGA().\n */\n if (xDirty < this.nCols) {\n var cxDirty = xMaxDirty - xDirty;\n var cyDirty = yMaxDirty - yDirty;\n this.contextBuffer.putImageData(this.imageBuffer, 0, 0, xDirty, yDirty, cxDirty, cyDirty);\n this.contextScreen.drawImage(this.canvasBuffer, 0, 0, this.nCols, this.nRows, 0, 0, this.cxScreen, this.cyScreen);\n }\n return cCells;\n }\n\n /**\n * updateScreenGraphicsVGA(addrBuffer, addrScreen, addrScreenLimit)\n *\n * This function name is a slight misnomer: updateScreenGraphicsEGA() takes care of all the 4bpp video modes\n * (first introduced by the EGA and later expanded by the VGA), where each pixel's bits are spread across the 4\n * planes, whereas this function takes care of just the 8bpp video modes introduced by the VGA, such as mode 0x13\n * (320x200x256), where each pixel's bits are contained within a single plane. This is essentially all 256-color\n * modes (CHAIN4, \"Mode X\", etc), hence the hard-coded call to getCardColors(8).\n *\n * TODO: Add support for blinking graphics (ATC.MODE.BLINK_ENABLE)\n *\n * @this {Video}\n * @param {number} addrBuffer\n * @param {number} addrScreen\n * @param {number} addrScreenLimit\n * @return {number} (number of cells processed)\n */\n updateScreenGraphicsVGA(addrBuffer, addrScreen, addrScreenLimit)\n {\n var iCell = 0;\n var cCells = addrScreenLimit - addrScreen;\n var addr = addrScreen;\n var aPixelColors = this.getCardColors(8);\n var adwMemory = this.cardActive.adwMemory;\n\n var x = 0, y = 0;\n var xDirty = this.nCols, xMaxDirty = 0, yDirty = this.nRows, yMaxDirty = 0;\n var cbInc = (this.cardActive.regSEQData[Card.SEQ.MEMMODE.INDX] & Card.SEQ.MEMMODE.CHAIN4)? 4 : 1;\n var iPixelFirst = this.cardActive.regATCData[Card.ATC.HPAN.INDX] & Card.ATC.HPAN.SHIFT_LEFT;\n\n /*\n * TODO: What should happen if the card is programmed such that nColsLogical is LESS THAN nCols?\n */\n var nRowAdjust = (this.nColsLogical > this.nCols? ((this.nColsLogical - this.nCols - iPixelFirst) >> 3) : 0);\n\n this.cBlinkVisible = 0;\n while (addr < addrScreenLimit) {\n var idw = addr - addrBuffer;\n\n var data = adwMemory[idw];\n\n /*\n * Figure out how many visible pixels this data represents; usually 4, unless panning is being used.\n */\n var iPixel, nPixels = 4;\n\n if (iPixelFirst) {\n /*\n * TODO: Implement support for 8bpp panning\n */\n } else {\n\n if (this.fCellCacheValid && data === this.aCellCache[iCell]) {\n x += nPixels;\n nPixels = 0;\n } else {\n this.aCellCache[iCell] = data;\n }\n iCell++;\n }\n\n if (nPixels) {\n if (x < xDirty) xDirty = x;\n for (iPixel = 0; iPixel < nPixels; iPixel++) {\n this.setPixel(this.imageBuffer, x++, y, aPixelColors[data & 0xff]);\n data >>= 8;\n }\n if (x > xMaxDirty) xMaxDirty = x;\n if (y < yDirty) yDirty = y;\n if (y >= yMaxDirty) yMaxDirty = y + 1;\n }\n\n\n\n addr += cbInc;\n\n if (x >= this.nCols) {\n x = 0;\n if (++y > this.nRows) break;\n addr += nRowAdjust;\n }\n }\n\n if (iPixelFirst) cCells = 0; // zero the cell count to inhibit setting fCellCacheValid\n\n /*\n * For a fascinating discussion of the best way to update the screen canvas at this point, see updateScreenGraphicsCGA().\n */\n if (xDirty < this.nCols) {\n var cxDirty = xMaxDirty - xDirty;\n var cyDirty = yMaxDirty - yDirty;\n this.contextBuffer.putImageData(this.imageBuffer, 0, 0, xDirty, yDirty, cxDirty, cyDirty);\n this.contextScreen.drawImage(this.canvasBuffer, 0, 0, this.nCols, this.nRows, 0, 0, this.cxScreen, this.cyScreen);\n }\n return cCells;\n }\n\n /**\n * getRetraceBits(card)\n *\n * This returns a byte value with two bits set or clear as appropriate: RETRACE and VRETRACE.\n *\n * @this {Video}\n * @param {Object} card\n * @return {number}\n */\n getRetraceBits(card)\n {\n /*\n * NOTE: The CGA bits CGA.STATUS.RETRACE (0x01) and CGA.STATUS.VRETRACE (0x08) match the EGA definitions,\n * and they also correspond to the MDA bits MDA.STATUS.HDRIVE (0x01) and MDA.STATUS.BWVIDEO (0x08); I'm not sure\n * why the MDA uses different designations, but the bits appear to serve the same purpose.\n *\n * TODO: Verify that when a saved machine state is restored, both the CPU's cycle count AND the card's nInitCycles\n * are properly restored. It's probably not a big deal, but details like that bother me.\n */\n var b = 0;\n var nCycles = this.cpu.getCycles();\n var nElapsedCycles = nCycles - card.nInitCycles;\n if (nElapsedCycles < 0) { // perhaps the CPU decided to reset its cycle count?\n card.nInitCycles = nElapsedCycles;\n nElapsedCycles = -nElapsedCycles|0;\n }\n var nCyclesHorzRemain = nElapsedCycles % card.nCyclesHorzPeriod;\n if (nCyclesHorzRemain > card.nCyclesHorzActive) b |= Card.CGA.STATUS.RETRACE;\n var nCyclesVertRemain = nElapsedCycles % card.nCyclesVertPeriod;\n if (nCyclesVertRemain > card.nCyclesVertActive) b |= Card.CGA.STATUS.VRETRACE | Card.CGA.STATUS.RETRACE;\n /*\n * Some callers also want to know how many vertical retrace periods have occurred since the last time they checked,\n * so we compute that now.\n */\n card.nVertPeriods = (nElapsedCycles / card.nCyclesVertPeriod)|0;\n return b;\n }\n\n /**\n * inMDAIndx(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3B4)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number|undefined}\n */\n inMDAIndx(port, addrFrom)\n {\n return this.inCRTCIndx(this.cardMono, port, addrFrom);\n }\n\n /**\n * outMDAIndx(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3B4)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outMDAIndx(port, bOut, addrFrom)\n {\n this.outCRTCIndx(this.cardMono, port, bOut, addrFrom);\n }\n\n /**\n * inMDAData(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3B5)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number|undefined}\n */\n inMDAData(port, addrFrom)\n {\n return this.inCRTCData(this.cardMono, port, addrFrom);\n }\n\n /**\n * outMDAData(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3B5)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outMDAData(port, bOut, addrFrom)\n {\n this.outCRTCData(this.cardMono, port, bOut, addrFrom);\n }\n\n /**\n * inMDAMode(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3B8)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inMDAMode(port, addrFrom)\n {\n return this.inCardMode(this.cardMono, addrFrom);\n }\n\n /**\n * outMDAMode(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3B8)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outMDAMode(port, bOut, addrFrom)\n {\n this.outCardMode(this.cardMono, bOut, addrFrom);\n }\n\n /**\n * inMDAStatus(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3BA)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inMDAStatus(port, addrFrom)\n {\n return this.inCardStatus(this.cardMono, addrFrom);\n }\n\n /**\n * outFeat(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3BA or 0x3DA)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n *\n * NOTE: While this port also existed on the MDA and CGA, it existed only as an INPUT port, not an OUTPUT port.\n */\n outFeat(port, bOut, addrFrom)\n {\n this.cardEGA.regFeat = (this.cardEGA.regFeat & ~Card.FEAT_CTRL.BITS) | (bOut & Card.FEAT_CTRL.BITS);\n this.printMessageIO(port, bOut, addrFrom, \"FEAT\");\n }\n\n /**\n * inATCIndx(port, addrFrom)\n *\n * Technically, port 0x3C0 is readable only on a VGA, but we allow reads on an EGA as well,\n * primarily for debugging purposes. Moreover, ATC port reads do NOT toggle the ATC address/data\n * flip-flop; only writes have that effect.\n *\n * @this {Video}\n * @param {number} port (0x3C0)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inATCIndx(port, addrFrom)\n {\n var b = this.cardEGA.regATCIndx;\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.ATC.PORT, null, addrFrom, \"ATC.INDX\", b);\n }\n return b;\n }\n\n /**\n * inATCData(port, addrFrom)\n *\n * Technically, port 0x3C0 is readable only on a VGA, but we allow reads on an EGA as well,\n * primarily for debugging purposes. Moreover, ATC port reads do NOT toggle the ATC address/data\n * flip-flop; only writes have that effect.\n *\n * @this {Video}\n * @param {number} port (0x3C1)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inATCData(port, addrFrom)\n {\n var b = this.cardEGA.regATCData[this.cardEGA.regATCIndx & Card.ATC.INDX_MASK];\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.ATC.PORT, null, addrFrom, \"ATC.\" + this.cardEGA.asATCRegs[this.cardEGA.regATCIndx & Card.ATC.INDX_MASK], b);\n }\n return b;\n }\n\n /**\n * outATC(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C0)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outATC(port, bOut, addrFrom)\n {\n var card = this.cardEGA;\n var fPalEnabled = (card.regATCIndx & Card.ATC.INDX_PAL_ENABLE);\n if (!card.fATCData) {\n card.regATCIndx = bOut;\n this.printMessageIO(port, bOut, addrFrom, \"ATC.INDX\");\n card.fATCData = true;\n if ((bOut & Card.ATC.INDX_PAL_ENABLE) && !fPalEnabled) {\n if (!this.buildFonts(true)) {\n if (DEBUG && (!addrFrom || this.messageEnabled())) {\n this.printMessage(\"outATC(\" + Str.toHexByte(bOut) + \"): no font changes required\");\n }\n } else {\n if (DEBUG && (!addrFrom || this.messageEnabled())) {\n this.printMessage(\"outATC(\" + Str.toHexByte(bOut) + \"): redraw screen for font changes\");\n }\n this.updateScreen(true);\n }\n }\n else {\n /*\n * TODO: We might want a screen blanking function, suitable for any mode, when INDX_PAL_ENABLE is cleared.\n * powerDown() might like to use such a function, too. updateScreen() already disables any further screen\n * updates while INDX_PAL_ENABLE is clear (except when fForce is true), but that's all we currently do.\n *\n * if (!(bOut & Card.ATC.INDX_PAL_ENABLE) && fPalEnabled) this.blankScreen();\n *\n * However, there also needs to be a delay, because when the IBM VGA BIOS changes the mode, it updates\n * the ATC palette registers in such a way that INDX_PAL_ENABLE is constantly toggled; here's one iteration:\n *\n * C000:2B39 EC IN AL,DX\n * C000:2B3A B2C0 MOV DL,C0\n * C000:2B3C 8BC3 MOV AX,BX\n * C000:2B3E 86C4 XCHG AL,AH\n * C000:2B40 EE OUT DX,AL <-- this ATC index value does NOT contain 0x20\n * C000:2B41 86C4 XCHG AL,AH\n * C000:2B43 EE OUT DX,AL\n * C000:2B44 B020 MOV AL,20\n * C000:2B46 EE OUT DX,AL <-- this ATC index value obviously DOES contain 0x20\n *\n * I'm not sure there are any situations where deliberately flickering the screen is a good thing -- unless\n * someone REALLY wants to recreate the ugly flickering scroll of a CGA...?\n */\n }\n /*\n * HACK: offStartAddr is supposed to be \"latched\" ONLY at the start of every VRETRACE interval, but\n * other \"triggers\" are helpful; see updateScreen() for details.\n *\n * PARANOIA: Don't call invalidateCache() unless the start address we just \"latched\" actually changed.\n */\n var offStartAddr = card.regCRTData[Card.CRTC.STARTLO];\n offStartAddr |= (card.regCRTData[Card.CRTC.STARTHI] & card.addrMaskHigh) << 8;\n if (card.offStartAddr != offStartAddr) {\n card.offStartAddr = offStartAddr;\n this.invalidateCache();\n }\n card.nVertPeriodsStartAddr = 0;\n } else {\n card.fATCData = false;\n var iReg = card.regATCIndx & Card.ATC.INDX_MASK;\n if (iReg >= Card.ATC.PALETTE_REGS || !fPalEnabled) {\n if (Video.TRAPALL || card.regATCData[iReg] !== bOut) {\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(port, bOut, addrFrom, \"ATC.\" + card.asATCRegs[iReg]);\n }\n card.regATCData[iReg] = bOut;\n this.invalidateCache(false);\n }\n }\n }\n }\n\n /**\n * inStatus0(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C2)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inStatus0(port, addrFrom)\n {\n var bSWBit = 0;\n if (this.nCard == Video.CARD.EGA) {\n var iBit = 3 - ((this.cardEGA.regMisc & Card.MISC.CLOCK_SELECT) >> 2); // this is the desired SW # (0-3)\n bSWBit = (this.bEGASwitches & (1 << iBit)) << (Card.STATUS0.SWSENSE_SHIFT - iBit);\n } else {\n /*\n * The IBM VGA ROM expects the SWSENSE bit to change according to how the DAC is programmed.\n *\n * At C000:0391, the ROM selects the following array at 0x0454:\n *\n * db 0x12,0x12,0x12,0x10\n *\n * and writes the first 3 bytes to DAC register #0, and then compares SWSENSE to the 4th byte (0x10).\n *\n * If the 4th byte matches, then the ROM clears the BIOS \"monochrome monitor\" bit, and does the same\n * thing again with 5 more arrays, expecting the 4th byte in all 5 arrays to match SWSENSE, and being\n * very unhappy if they don't:\n *\n * db 0x14,0x14,0x14,0x10\n * db 0x2D,0x14,0x14,0x00\n * db 0x14,0x2D,0x14,0x00\n * db 0x14,0x14,0x2D,0x00\n * db 0x2D,0x2D,0x2D,0x00\n *\n * I ensure much happiness by setting SWSENSE unless any of the three 6-bit DAC values contain 0x2D.\n *\n * This hard-coded behavior assumes a color monitor. If you really want to simulate a monochrome monitor,\n * then the 1st array (above) must mismatch, and a different set of arrays must all match:\n *\n * db 0x04,0x12,0x04,0x10\n * db 0x1E,0x12,0x04,0x00\n * db 0x04,0x2D,0x04,0x00\n * db 0x04,0x16,0x15,0x00\n * db 0x00,0x00,0x00,0x10\n *\n * In other words, for a monochrome monitor, set SWSENSE only when DAC register #0 matches the first and last\n * sets of values.\n */\n var dwDAC = this.cardEGA.regDACData[0];\n if ((dwDAC & 0x3f) != 0x2d && (dwDAC & (0x3f << 6)) != (0x2d << 6) && (dwDAC & (0x3f << 12)) != (0x2d << 12)) {\n bSWBit |= Card.STATUS0.SWSENSE;\n }\n }\n var b = ((this.cardEGA.regStatus0 & ~Card.STATUS0.SWSENSE) | bSWBit);\n /*\n * TODO: Figure out where Card.STATUS0.FEAT bits should come from....\n */\n this.cardEGA.regStatus0 = b;\n this.printMessageIO(Card.STATUS0.PORT, null, addrFrom, \"STATUS0\", b);\n return b;\n }\n\n /**\n * @this {Video}\n * @param {number} port (0x3C2)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outMisc(port, bOut, addrFrom)\n {\n this.cardEGA.regMisc = bOut;\n this.enableEGA();\n this.printMessageIO(Card.MISC.PORT_WRITE, bOut, addrFrom, \"MISC\");\n }\n\n /**\n * inVGAEnable(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C3)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inVGAEnable(port, addrFrom)\n {\n var b = this.cardEGA.regVGAEnable;\n this.printMessageIO(Card.VGA_ENABLE.PORT, null, addrFrom, \"VGA_ENABLE\", b);\n return b;\n }\n\n /**\n * outVGAEnable(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C3)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outVGAEnable(port, bOut, addrFrom)\n {\n this.cardEGA.regVGAEnable = bOut;\n this.printMessageIO(Card.VGA_ENABLE.PORT, bOut, addrFrom, \"VGA_ENABLE\");\n }\n\n /**\n * inSEQIndx(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C4)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inSEQIndx(port, addrFrom)\n {\n var b = this.cardEGA.regSEQIndx;\n this.printMessageIO(Card.SEQ.INDX.PORT, null, addrFrom, \"SEQ.INDX\", b);\n return b;\n }\n\n /**\n * outSEQIndx(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C4)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outSEQIndx(port, bOut, addrFrom)\n {\n this.cardEGA.regSEQIndx = bOut;\n this.printMessageIO(Card.SEQ.INDX.PORT, bOut, addrFrom, \"SEQ.INDX\");\n }\n\n /**\n * inSEQData(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C5)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inSEQData(port, addrFrom)\n {\n var b = this.cardEGA.regSEQData[this.cardEGA.regSEQIndx];\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.SEQ.DATA.PORT, null, addrFrom, \"SEQ.\" + this.cardEGA.asSEQRegs[this.cardEGA.regSEQIndx], b);\n }\n return b;\n }\n\n /**\n * outSEQData(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C5)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outSEQData(port, bOut, addrFrom)\n {\n if (Video.TRAPALL || this.cardEGA.regSEQData[this.cardEGA.regSEQIndx] !== bOut) {\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.SEQ.DATA.PORT, bOut, addrFrom, \"SEQ.\" + this.cardEGA.asSEQRegs[this.cardEGA.regSEQIndx]);\n }\n this.cardEGA.regSEQData[this.cardEGA.regSEQIndx] = bOut;\n }\n switch(this.cardEGA.regSEQIndx) {\n case Card.SEQ.MAPMASK.INDX:\n this.cardEGA.nSeqMapMask = Video.aEGAByteToDW[bOut & Card.SEQ.MAPMASK.MAPS];\n break;\n case Card.SEQ.MEMMODE.INDX:\n if (this.setCardAccess(this.getCardAccess())) {\n /*\n * When switching screens (via SysReq) on early revisions of OS/2 (eg, FOOTBALL), the screen would go\n * blank; this appeared to be because when the card is reprogrammed, we first think the card is going into\n * graphics mode, then we reverse course when it becomes clear that the card is going back into text mode,\n * but unfortunately, at that precise moment, the Sequencer hasn't been fully reprogrammed, so when we're\n * reading screen memory, we're getting back ZEROS for every odd byte (which are the text attribute bytes),\n * so the screen is redrawn as black-on-black.\n *\n * My solution was to change setCardAccess() to indicate whether it actually altered the video buffer\n * address and/or format, and if so, then force another screen update.\n *\n * TODO: This scenario does not seem unique; it suggests that we should generally force a screen update\n * whenever the video buffer has undergone a significant change.\n *\n * UPDATE: This change was NOT sufficient to resolve the OS/2 screen-switching bug described above; in fact,\n * it's apparently not even necessary, because the REAL problem was caused by PAGED blocks with stale\n * physical video memory blocks; the solution was for the Bus addMemory() and removeMemory() functions to\n * call the the CPU flushPageBlocks() function. With that change in place, the window now stays in sync\n * with the buffer.\n *\n * However, calling updateScreen() here still seems like a good idea, and it shouldn't hurt performance,\n * since we're doing it only when setCardAccess() indicates a change, so I'm leaving this addition in place.\n */\n this.updateScreen(true);\n }\n break;\n default:\n break;\n }\n }\n\n /**\n * inDACMask(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C6)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inDACMask(port, addrFrom)\n {\n var b = this.cardEGA.regDACMask;\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.DAC.MASK.PORT, null, addrFrom, \"DAC.MASK\", b);\n }\n return b;\n }\n\n /**\n * outDACMask(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C6)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outDACMask(port, bOut, addrFrom)\n {\n if (Video.TRAPALL || this.cardEGA.regDACMask !== bOut) {\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.DAC.MASK.PORT, bOut, addrFrom, \"DAC.MASK\");\n }\n this.cardEGA.regDACMask = bOut;\n }\n }\n\n /**\n * inDACState(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C7)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inDACState(port, addrFrom)\n {\n var b = this.cardEGA.regDACState;\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.DAC.STATE.PORT, null, addrFrom, \"DAC.STATE\", b);\n }\n return b;\n }\n\n /**\n * outDACRead(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C7)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outDACRead(port, bOut, addrFrom)\n {\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.DAC.ADDR.PORT_READ, bOut, addrFrom, \"DAC.READ\");\n }\n this.cardEGA.regDACAddr = bOut;\n this.cardEGA.regDACState = Card.DAC.STATE.MODE_READ;\n this.cardEGA.regDACShift = 0;\n }\n\n /**\n * outDACWrite(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C8)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outDACWrite(port, bOut, addrFrom)\n {\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.DAC.ADDR.PORT_WRITE, bOut, addrFrom, \"DAC.WRITE\");\n }\n this.cardEGA.regDACAddr = bOut;\n this.cardEGA.regDACState = Card.DAC.STATE.MODE_WRITE;\n this.cardEGA.regDACShift = 0;\n }\n\n /**\n * inDACData(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C9)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inDACData(port, addrFrom)\n {\n var b = (this.cardEGA.regDACData[this.cardEGA.regDACAddr] >> this.cardEGA.regDACShift) & 0x3f;\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.DAC.DATA.PORT, null, addrFrom, \"DAC.DATA[\" + Str.toHexByte(this.cardEGA.regDACAddr) + \"][\" + Str.toHexByte(this.cardEGA.regDACShift) + \"]\", b);\n }\n this.cardEGA.regDACShift += 6;\n if (this.cardEGA.regDACShift > 12) {\n this.cardEGA.regDACShift = 0;\n this.cardEGA.regDACAddr = (this.cardEGA.regDACAddr + 1) & (Card.DAC.TOTAL_REGS-1);\n }\n return b;\n }\n\n /**\n * outDACData(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C9)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outDACData(port, bOut, addrFrom)\n {\n var dw = this.cardEGA.regDACData[this.cardEGA.regDACAddr];\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.DAC.DATA.PORT, bOut, addrFrom, \"DAC.DATA[\" + Str.toHexByte(this.cardEGA.regDACAddr) + \"][\" + Str.toHexByte(this.cardEGA.regDACShift) + \"]\");\n }\n var dwNew = (dw & ~(0x3f << this.cardEGA.regDACShift)) | ((bOut & 0x3f) << this.cardEGA.regDACShift);\n if (dw !== dwNew) {\n this.cardEGA.regDACData[this.cardEGA.regDACAddr] = dwNew;\n this.invalidateCache(false);\n }\n this.cardEGA.regDACShift += 6;\n if (this.cardEGA.regDACShift > 12) {\n this.cardEGA.regDACShift = 0;\n this.cardEGA.regDACAddr = (this.cardEGA.regDACAddr + 1) & (Card.DAC.TOTAL_REGS-1);\n }\n }\n\n /**\n * inVGAFeat(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3CA)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inVGAFeat(port, addrFrom)\n {\n var b = this.cardEGA.regFeat;\n this.printMessageIO(Card.FEAT_CTRL.PORT_READ, null, addrFrom, \"FEAT\", b);\n return b;\n }\n\n /**\n * outGRCPos2(port, bOut, addrFrom)\n *\n * \"The EGA was originally implemented by IBM using two Graphics Controller Chips. This register is used to program\n * the Graphics #2 chip. See the Graphics #1 Position Register for details.\"\n *\n * \"A one should be loaded into this location to map host data bus bits 2 and 3 to display planes 2 and 3, respectively.\"\n *\n * @this {Video}\n * @param {number} port (0x3CA)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outGRCPos2(port, bOut, addrFrom)\n {\n this.cardEGA.regGRCPos2 = bOut;\n this.printMessageIO(Card.GRC.POS2_PORT, bOut, addrFrom, \"GRC2\");\n }\n\n /**\n * inVGAMisc(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3CC)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inVGAMisc(port, addrFrom)\n {\n var b = this.cardEGA.regMisc;\n this.printMessageIO(Card.MISC.PORT_READ, null, addrFrom, \"MISC\", b);\n return b;\n }\n\n /**\n * outGRCPos1(port, bOut, addrFrom)\n *\n * \"The EGA was originally implemented by IBM using two Graphics Controller Chips. It was necessary to program\n * each to respond to a different set of two consecutive bits of the 8-bit host data bus. In the IBM EGA implementation,\n * a 0 must be loaded into this register. In the VGA, there is no analogous register.\"\n *\n * \"A zero should be loaded into this location to map host data bus bits 0 and 1 to display planes 0 and 1 respectively.\"\n *\n * Note that this register was not readable on the EGA, and when the VGA came along, reads of this port read the Misc reg.\n *\n * @this {Video}\n * @param {number} port (0x3CC)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outGRCPos1(port, bOut, addrFrom)\n {\n this.cardEGA.regGRCPos1 = bOut;\n this.printMessageIO(Card.GRC.POS1_PORT, bOut, addrFrom, \"GRC1\");\n }\n\n /**\n * inGRCIndx(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3CE)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inGRCIndx(port, addrFrom)\n {\n var b = this.cardEGA.regGRCIndx;\n this.printMessageIO(Card.GRC.INDX.PORT, null, addrFrom, \"GRC.INDX\", b);\n return b;\n }\n\n /**\n * outGRCIndx(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3CE)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outGRCIndx(port, bOut, addrFrom)\n {\n this.cardEGA.regGRCIndx = bOut;\n this.printMessageIO(Card.GRC.INDX.PORT, bOut, addrFrom, \"GRC.INDX\");\n }\n\n /**\n * inGRCData(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3CF)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inGRCData(port, addrFrom)\n {\n var b = this.cardEGA.regGRCData[this.cardEGA.regGRCIndx];\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.GRC.DATA.PORT, null, addrFrom, \"GRC.\" + this.cardEGA.asGRCRegs[this.cardEGA.regGRCIndx], b);\n }\n return b;\n }\n\n /**\n * outGRCData(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3CF)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outGRCData(port, bOut, addrFrom)\n {\n if (Video.TRAPALL || this.cardEGA.regGRCData[this.cardEGA.regGRCIndx] !== bOut) {\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.GRC.DATA.PORT, bOut, addrFrom, \"GRC.\" + this.cardEGA.asGRCRegs[this.cardEGA.regGRCIndx]);\n }\n this.cardEGA.regGRCData[this.cardEGA.regGRCIndx] = bOut;\n }\n switch(this.cardEGA.regGRCIndx) {\n case Card.GRC.SRESET.INDX:\n this.cardEGA.nSetMapData = Video.aEGAByteToDW[bOut & 0xf];\n this.cardEGA.nSetMapBits = this.cardEGA.nSetMapData & ~this.cardEGA.nSetMapMask;\n break;\n case Card.GRC.ESRESET.INDX:\n this.cardEGA.nSetMapMask = ~Video.aEGAByteToDW[bOut & 0xf];\n this.cardEGA.nSetMapBits = this.cardEGA.nSetMapData & ~this.cardEGA.nSetMapMask;\n break;\n case Card.GRC.COLORCMP.INDX:\n this.cardEGA.nColorCompare = Video.aEGAByteToDW[bOut & 0xf] & (0x80808080|0);\n break;\n case Card.GRC.DATAROT.INDX:\n case Card.GRC.MODE.INDX:\n this.setCardAccess(this.getCardAccess());\n break;\n case Card.GRC.READMAP.INDX:\n this.cardEGA.nReadMapShift = (bOut & Card.GRC.READMAP.NUM) << 3;\n break;\n case Card.GRC.MISC.INDX:\n this.checkMode(false);\n break;\n case Card.GRC.COLORDC.INDX:\n this.cardEGA.nColorDontCare = Video.aEGAByteToDW[bOut & 0xf] & (0x80808080|0);\n break;\n case Card.GRC.BITMASK.INDX:\n this.cardEGA.nBitMapMask = bOut | (bOut << 8) | (bOut << 16) | (bOut << 24);\n break;\n default:\n break;\n }\n }\n\n /**\n * inCGAIndx(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3D4)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number|undefined}\n */\n inCGAIndx(port, addrFrom)\n {\n return this.inCRTCIndx(this.cardColor, port, addrFrom);\n }\n\n /**\n * outCGAIndx(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3D4)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outCGAIndx(port, bOut, addrFrom)\n {\n this.outCRTCIndx(this.cardColor, port, bOut, addrFrom);\n }\n\n /**\n * inCGAData(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3D5)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number|undefined}\n */\n inCGAData(port, addrFrom)\n {\n return this.inCRTCData(this.cardColor, port, addrFrom);\n }\n\n /**\n * outCGAData(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3D5)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outCGAData(port, bOut, addrFrom)\n {\n this.outCRTCData(this.cardColor, port, bOut, addrFrom);\n }\n\n /**\n * inCGAMode(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3D8)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inCGAMode(port, addrFrom)\n {\n return this.inCardMode(this.cardColor, addrFrom);\n }\n\n /**\n * outCGAMode(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3D8)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outCGAMode(port, bOut, addrFrom)\n {\n this.outCardMode(this.cardColor, bOut, addrFrom);\n }\n\n /**\n * inCGAColor(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3D9)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inCGAColor(port, addrFrom)\n {\n var b = this.cardColor.regColor;\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(port /* this.cardColor.port + 5 */, null, addrFrom, this.cardColor.type + \".COLOR\", b);\n }\n return b;\n }\n\n /**\n * outCGAColor(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3D9)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outCGAColor(port, bOut, addrFrom)\n {\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(port /* this.cardColor.port + 5 */, bOut, addrFrom, this.cardColor.type + \".COLOR\");\n }\n if (this.cardColor.regColor !== bOut) {\n this.cardColor.regColor = bOut;\n this.invalidateCache(false);\n }\n }\n\n /**\n * inCGAStatus(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3DA)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inCGAStatus(port, addrFrom)\n {\n return this.inCardStatus(this.cardColor, addrFrom);\n }\n\n /**\n * inCRTCIndx(card, port, addrFrom)\n *\n * @this {Video}\n * @param {Object} card\n * @param {number} port\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number|undefined}\n */\n inCRTCIndx(card, port, addrFrom)\n {\n var b;\n /*\n * The IBM VGA ROM makes some hardware determinations based on how the CRTC controller responds when\n * the IO_SELECT bit in the Miscellaneous Output Register is cleared; normally, that would mean ports\n * 0x3B? are decoded and ports 0x3D? are ignored. We didn't used to bother ignoring them, but the\n * VGA ROM's logic requires it, so now we also check fActive. However, we ignore only CRTC reads;\n * we retain any writes in case that information proves useful later.\n *\n * Note that returning an undefined value now signals the Bus component to return whatever default value\n * it prefers (normally 0xff).\n */\n if (card.fActive) b = card.regCRTIndx;\n this.printMessageIO(port, null, addrFrom, \"CRTC.INDX\", b);\n return b;\n }\n\n /**\n * outCRTCIndx(card, port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {Object} card\n * @param {number} port\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outCRTCIndx(card, port, bOut, addrFrom)\n {\n card.regCRTPrev = card.regCRTIndx;\n card.regCRTIndx = bOut & Card.CGA.CRTC.INDX.MASK;\n this.printMessageIO(port /* card.port */, bOut, addrFrom, \"CRTC.INDX\");\n }\n\n /**\n * inCRTCData(card, port, addrFrom)\n *\n * @this {Video}\n * @param {Object} card\n * @param {number} port\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number|undefined}\n */\n inCRTCData(card, port, addrFrom)\n {\n var b;\n /*\n * The IBM VGA ROM makes some hardware determinations based on how the CRTC controller responds when\n * the IO_SELECT bit in the Miscellaneous Output Register is cleared; normally, that would mean ports\n * 0x3B? are decoded and ports 0x3D? are ignored. We didn't used to bother ignoring them, but the\n * VGA ROM's logic requires it, so now we also check fActive. However, we ignore only CTRC reads;\n * we retain any writes in case that information proves useful later.\n *\n * Note that returning an undefined value now signals the Bus component to return whatever default value\n * it prefers (normally 0xff).\n */\n if (card.fActive && card.regCRTIndx < card.nCRTCRegs) b = card.regCRTData[card.regCRTIndx];\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(port /* card.port + 1 */, null, addrFrom, \"CRTC.\" + card.asCRTCRegs[card.regCRTIndx], b);\n }\n return b;\n }\n\n /**\n * outCRTCData(card, port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {Object} card\n * @param {number} port\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outCRTCData(card, port, bOut, addrFrom)\n {\n if (card.regCRTIndx < card.nCRTCRegs) {\n /*\n * To simulate how the 6845 effectively ignores changes to CURSCAN or CURSCANB whenever one is written\n * while the other is currently > MAXSCAN, we check for those writes now, and ignore the write as appropriate.\n * \n * Since CURSCAN == 0xA and CURSCANB == 0xB, we can get the complementary register by XOR'ing the index with 0x1.\n */\n if (card.regCRTIndx == Card.CRTC.CURSCAN || card.regCRTIndx == Card.CRTC.CURSCANB) {\n var bCur = bOut & Card.CRTCMASKS[Card.CRTC.MAXSCAN];\n var bMax = card.regCRTData[Card.CRTC.MAXSCAN] & Card.CRTCMASKS[Card.CRTC.MAXSCAN];\n if (bCur > bMax) {\n bCur = card.regCRTData[card.regCRTIndx ^ 0x1] & Card.CRTCMASKS[Card.CRTC.MAXSCAN];\n if (bCur > bMax) {\n if (DEBUG) {\n this.printf(\"outCRTCData(0x%02x): ignoring write to CRTC[0x%02x] since 0x%02x > 0x%02x\\n\", bOut, card.regCRTIndx, bCur, bMax);\n }\n return;\n }\n }\n }\n if (Video.TRAPALL || card.regCRTData[card.regCRTIndx] !== bOut) {\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(port /* card.port + 1 */, bOut, addrFrom, \"CRTC.\" + card.asCRTCRegs[card.regCRTIndx]);\n }\n card.regCRTData[card.regCRTIndx] = bOut;\n }\n if (card.regCRTIndx == Card.CRTC.STARTHI || card.regCRTIndx == Card.CRTC.STARTLO) {\n /*\n * Both STARTHI and STARTLO are supposed to be latched at the start of every VRETRACE interval.\n * However, since we don't have an interrupt that tells us exactly when that occurs, we used to latch\n * them now, whenever either one was written during any RETRACE interval. Unfortunately, one problem\n * with that approach is that we might latch only *one* of the registers, depending on timing.\n *\n * So now, we still call getRetraceBits(card), but only to recalculate the card's nVertPeriods value,\n * which we then snapshot in card.nVertPeriodsStartAddr.\n */\n this.getRetraceBits(card);\n card.nVertPeriodsStartAddr = card.nVertPeriods;\n }\n /*\n * During mode changes on the EGA, all the CRTC regs are typically programmed in sequence,\n * and if that's all that's happening with Card.CRTC.MAXSCAN, then we don't want to treat\n * it special; let the mode change be detected normally (eg, when the GRC regs are written later).\n *\n * On the other hand, if this was an out-of-sequence write to Card.CRTC.MAXSCAN, then\n * yes, we want to force setMode() to call setDimensions(), which is key to setting the proper\n * number of screen rows.\n *\n * The second part of the check is required to promptly detect a switch to \"Mode X\"; if we assume\n * that anyone switching to \"Mode X\" will first switch to mode 0x13, then it's a given that they\n * must reprogram the VDEND register, and that they will probably change it from 0x8F to 0xDF.\n *\n * Originally, I wasn't going to check specifically for 0xDF, to help catch other \"Mode X\" variations,\n * but if I don't, then some spurious mode changes are triggered (eg, when Windows 1.0 switches from\n * CGA graphics mode 0x06 to an EGA graphics mode).\n */\n if (card.regCRTIndx == Card.CRTC.MAXSCAN && card.regCRTPrev != Card.CRTC.MAXSCAN-1 || card.regCRTIndx == Card.CRTC.EGA.VDEND && bOut == 0xDF) {\n this.checkMode(true);\n }\n this.checkCursor();\n }\n else if (DEBUG) {\n this.printf(\"outCRTCData(0x%02x): ignoring unexpected write to CRTC[0x%02x]\\n\", bOut, card.regCRTIndx);\n }\n }\n\n /**\n * inCardMode(card, addrFrom)\n *\n * @this {Video}\n * @param {Object} card\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inCardMode(card, addrFrom)\n {\n var b = card.regMode;\n this.printMessageIO(card.port + 4, null, addrFrom, \"MODE\", b);\n return b;\n }\n\n /**\n * outCardMode(card, bOut, addrFrom)\n *\n * @this {Video}\n * @param {Object} card\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outCardMode(card, bOut, addrFrom)\n {\n this.printMessageIO(card.port + 4, bOut, addrFrom, \"MODE\");\n card.regMode = bOut;\n this.checkMode(false);\n }\n\n /**\n * inCardStatus(card, addrFrom)\n *\n * On an EGA, this register is called \"Status Register One\" (0x3BA/0x3DA aka STATUS1), to distinguish it from\n * \"Status Register Zero\" (0x3C2 aka STATUS0). One of the side-effects of reading STATUS1 is that it resets the\n * ATC address/data flip-flop to \"address\" mode, which we emulate by setting cardEGA.fATCData to false, indicating\n * that the ATC is not in \"data\" mode.\n *\n * @this {Video}\n * @param {Object} card\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inCardStatus(card, addrFrom)\n {\n var b = this.getRetraceBits(card);\n\n if (card === this.cardEGA) {\n /*\n * STATUS1 diagnostic bits 5 and 4 are set according to the Card.ATC.PLANES.MUX bits:\n *\n * MUX Bit 5 Bit 4\n * --- ---- ----\n * 00: Red Blue\n * 01: SecBlue Green\n * 10: SecRed SecGreen\n * 11: unused unused\n *\n * Depending on where we are in the horizontal and vertical periods (which can be inferred from the\n * same elapsed cycle count that we used to simulate the retrace bits above), we could extract 4 bits\n * from a corresponding region of the video buffer, \"and\" them with Card.ATC.PLANES.MASK, use\n * that to index into the palette registers (cardEGA.regATCData), and use the resulting palette register\n * bits to set these diagnostics bits. However, that's all rather tedious, and the process of extracting\n * 4 appropriate bits from the video buffer varies depending on the video mode.\n *\n * Why are we even considering this? Because the EGA BIOS diagnostic code draws a bright reverse-video\n * line of text blocks across the top of the screen, writes 0x3F to palette register 0x0f, and then\n * monitors the STATUS1 diagnostic bits, waiting for those palette bits to show up. It turns out, however,\n * that we can easily fool the EGA BIOS by simply toggling the diagnostic bits. So we take the easy way out.\n *\n * TODO: Faithful emulation of these bits is certainly doable, so consider doing that at some point.\n */\n b |= ((card.regStatus & Card.STATUS1.DIAGNOSTIC) ^ Card.STATUS1.DIAGNOSTIC);\n\n /*\n * Last but not least, we must reset the EGA's ATC flip-flop whenever this register is read.\n */\n card.fATCData = false;\n }\n else {\n /*\n * On the MDA/CGA, to satisfy ROM BIOS testing (\"TEST.10\"), it's sufficient to do a simple toggle of\n * bits 0 and 3 on every read.\n *\n * Also, according to http://www.seasip.info/VintagePC/mda.html, on an MDA, bits 7-4 are always ON and\n * bits 2-1 are always OFF, hence the \"OR\" of 0xF0.\n *\n * Alternatively, I *could* use the retrace bits from getRetraceBits() as-is:\n *\n * b |= 0xF0;\n *\n * but doing so hurts the performance of code like this in the \"FlickerFree\" utility:\n *\n * &0600:079A EC IN AL,DX\n * &0600:079B D0E8 SHR AL,1\n * &0600:079D 72FB JC 079A\n * &0600:079F FA CLI\n * &0600:07A0 EC IN AL,DX\n * &0600:07A1 D0E8 SHR AL,1\n * &0600:07A3 73FB JNC 07A0\n * &0600:07A5 8BC3 MOV AX,BX\n * &0600:07A7 AB STOSW\n * &0600:07A8 FB STI\n * &0600:07A9 E2EF LOOP 079A\n *\n * which, oddly, appears to want to write only ONE word to video memory per retrace interval. Sticking\n * with our older, cruder, toggling code, makes that code run faster and reduce the odds that you'll see\n * old data on appear on the screen before the above code has the chance to store new data over it.\n */\n b = (card.regStatus ^= (Card.CGA.STATUS.RETRACE | Card.CGA.STATUS.VRETRACE)) | 0xF0;\n }\n\n card.regStatus = b;\n this.printMessageIO(card.port + 6, null, addrFrom, (card === this.cardEGA? \"STATUS1\" : \"STATUS\"), b);\n return b;\n }\n\n /**\n * dumpVideo(asArgs)\n *\n * @this {Video}\n * @param {Array.<string>} asArgs\n */\n dumpVideo(asArgs)\n {\n if (DEBUGGER) {\n var component = /** @type {Component} */ (this.dbg);\n if (!this.cardActive) {\n component.println(\"no active video card\");\n return;\n }\n if (asArgs[0]) {\n this.cardActive.dumpVideoBuffer(asArgs);\n return;\n }\n component.println(\"BIOSMODE: \" + Str.toHexByte(this.nMode));\n this.cardActive.dumpVideoCard();\n }\n }\n\n /**\n * doBlink()\n *\n * This function is obsolete, now that the checkBlink() function is called on every updateScreen()\n * and checkCursor() call. updateScreen() is driven by CPU bursts, so piggy-backing on that to drive\n * blink updates seems preferable to having another active timer in the system.\n *\n * @this {Video}\n * @param {boolean} [fStart]\n *\n doBlink(fStart)\n {\n if (this.cBlinks >= 0) {\n this.cBlinks++;\n if (this.cBlinkVisible || this.iCellCursor >= 0) {\n if (!fStart && !this.cpu.isRunning()) {\n this.updateScreen();\n }\n setTimeout(function(video) { return function onBlinkTimeout() {video.doBlink();}; }(this), 266);\n return;\n }\n this.cBlinks = -1;\n }\n },\n */\n\n /**\n * Video.init()\n *\n * This function operates on every HTML element of class \"video\", extracting the\n * JSON-encoded parameters for the Video constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Video component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aElement = Component.getElementsByClass(document, PCX86.APPCLASS, \"video\");\n for (var iVideo = 0; iVideo < aElement.length; iVideo++) {\n var element = aElement[iVideo];\n var parmsVideo = Component.getComponentParms(element);\n\n var canvas = /** @type {HTMLCanvasElement} */ (document.createElement(\"canvas\"));\n if (canvas === undefined || !canvas.getContext) {\n element.innerHTML = \"<br/>Missing <canvas> support. Please try a newer web browser.\";\n return;\n }\n\n canvas.setAttribute(\"class\", \"pcjs-canvas\");\n canvas.setAttribute(\"width\", parmsVideo['screenWidth']);\n canvas.setAttribute(\"height\", parmsVideo['screenHeight']);\n\n /*\n * The \"contenteditable\" attribute on a canvas element NOTICEABLY slows down canvas drawing on\n * Safari as soon as you give the canvas focus (ie, click away from the canvas, and drawing speeds\n * up; click on the canvas, and drawing slows down). So the \"transparent textarea hack\" that we\n * once employed as only a work-around for Android devices is now our default.\n *\n * canvas.setAttribute(\"contenteditable\", \"true\");\n *\n * HACK: A canvas style of \"auto\" provides for excellent responsive canvas scaling in EVERY browser\n * except IE9/IE10, so I recalculate the appropriate CSS height every time the parent DIV is resized;\n * IE11 works without this hack, so we take advantage of the fact that IE11 doesn't identify as \"MSIE\".\n *\n * The other reason it's good to keep this particular hack limited to IE9/IE10 is that most other\n * browsers don't actually support an 'onresize' handler on anything but the window object.\n */\n canvas.style.height = \"auto\";\n if (Web.getUserAgent().indexOf(\"MSIE\") >= 0) {\n element.onresize = function(eParent, eChild, cx, cy) {\n return function onResizeVideo() {\n eChild.style.height = (((eParent.clientWidth * cy) / cx) | 0) + \"px\";\n };\n }(element, canvas, parmsVideo['screenWidth'], parmsVideo['screenHeight']);\n element.onresize(null);\n }\n /*\n * The following is a related hack that allows the user to force the screen to use a particular aspect\n * ratio if an 'aspect' attribute or URL parameter is set. Initially, it's just for testing purposes\n * until we figure out a better UI. And note that we use our Web.onPageEvent() helper function to make\n * sure we don't trample any other 'onresize' handler(s) attached to the window object.\n */\n var aspect = +(Web.getURLParm('aspect') || parmsVideo['aspect']);\n /*\n * No 'aspect' parameter yields NaN, which is falsey, and anything else must satisfy my arbitrary\n * constraints of 0.3 <= aspect <= 3.33, to prevent any useless (or worse, browser-blowing) results.\n */\n if (aspect && aspect >= 0.3 && aspect <= 3.33) {\n Web.onPageEvent('onresize', function(eParent, eChild, aspectRatio) {\n return function onResizeWindow() {\n /*\n * Since aspectRatio is the target width/height, we have:\n *\n * eParent.clientWidth / eChild.style.height = aspectRatio\n *\n * which means that:\n *\n * eChild.style.height = eParent.clientWidth / aspectRatio\n *\n * so for example, if aspectRatio is 16:9, or 1.78, and clientWidth = 640,\n * then the calculated height should approximately 360.\n */\n eChild.style.height = ((eParent.clientWidth / aspectRatio)|0) + \"px\";\n };\n }(element, canvas, aspect));\n window['onresize']();\n }\n element.appendChild(canvas);\n\n /*\n * HACK: Android-based browsers, like the Silk (Amazon) browser and Chrome for Android, don't honor the\n * \"contenteditable\" attribute; that is, when the canvas receives focus, they don't activate the on-screen\n * keyboard. So my fallback is to create a transparent textarea on top of the canvas.\n *\n * The parent DIV must have a style of \"position:relative\" (alternatively, a class of \"pcjs-container\"),\n * so that we can position the textarea using absolute coordinates. Also, we don't want the textarea to be\n * visible, but we must use \"opacity:0\" instead of \"visibility:hidden\", because the latter seems to prevent\n * the element from receiving events. These styling requirements are taken care of in components.css\n * (see references to the \"pcjs-video-object\" class).\n *\n * UPDATE: Unfortunately, Android keyboards like to compose whole words before transmitting any of the\n * intervening characters; our textarea's keyDown/keyUp event handlers DO receive intervening key events,\n * but their keyCode property is ZERO. Virtually the only usable key event we receive is the Enter key.\n * Android users will have to use machines that include their own on-screen \"soft keyboard\", or use an\n * external keyboard.\n *\n * The following attempt to use a password-enabled input field didn't work any better on Android. You could\n * clearly see the overlaid semi-transparent input field, but none of the input characters were passed along,\n * with the exception of the \"Go\" (Enter) key.\n *\n * var input = document.createElement(\"input\");\n * input.setAttribute(\"type\", \"password\");\n * input.setAttribute(\"style\", \"position:absolute; left:0; top:0; width:100%; height:100%; opacity:0.5\");\n * element.appendChild(input);\n *\n * See this Chromium issue for more information: https://code.google.com/p/chromium/issues/detail?id=118639\n */\n var textarea = /** @type {HTMLTextAreaElement} */ (document.createElement(\"textarea\"));\n\n /*\n * As noted in keyboard.js, the keyboard on an iOS device tends to pop up with the SHIFT key depressed,\n * which is not the initial keyboard state that the Keyboard component expects, so hopefully turning off\n * these \"auto\" attributes will help.\n */\n if (Web.isUserAgent(\"iOS\")) {\n textarea.setAttribute(\"autocapitalize\", \"off\");\n textarea.setAttribute(\"autocorrect\", \"off\");\n /*\n * One of the problems on iOS devices is that after a soft-key control is clicked, we need to give\n * focus back to the above textarea, usually by calling cmp.updateFocus(), but in doing so, iOS may\n * also \"zoom\" the page rather jarringly. While it's a simple matter to completely disable zooming,\n * by fiddling with the page's viewport, that prevents the user from intentionally zooming. A bit of\n * Googling reveals that another way to prevent those jarring unintentional zooms is to simply set the\n * font-size of the text control to 16px. So that's what we do.\n */\n textarea.style.fontSize = \"16px\";\n }\n element.appendChild(textarea);\n\n /*\n * Now we can create the Video object, record it, and wire it up to the associated document elements.\n */\n var context = /** @type {CanvasRenderingContext2D} */ (canvas.getContext(\"2d\"));\n var video = new Video(parmsVideo, canvas, context, textarea /* || input */, element);\n\n /*\n * Bind any video-specific controls (eg, the Refresh button). There are no essential controls, however;\n * even the \"Refresh\" button is just a diagnostic tool, to ensure that the screen contents are up-to-date.\n */\n Component.bindComponentControls(video, element, PCX86.APPCLASS);\n }\n }\n}\n\nVideo.TRAPALL = true; // monitor all I/O by default (not just deltas)\n\n/*\n * Supported Modes\n *\n * Although this component is designed to be a video hardware emulation, not a BIOS simulation, we DO\n * look for changes to the hardware state that correspond to standard BIOS mode settings, so our internal\n * mode setting will normally match the current BIOS mode setting; however, this a debugging convenience,\n * not an attempt to monitor or emulate the BIOS.\n *\n * We do have some BIOS awareness (eg, when loading ROM-based fonts, and some special code to ensure all\n * the BIOS diagnostics pass), but for the most part, we treat the BIOS like any other application code.\n *\n * As we expand support to include more programmable cards like the EGA, it becomes quite easy for the card\n * to enter a \"mode\" that has no BIOS counterpart (eg, non-standard combinations of video buffer address,\n * memory access modes, fonts, display regions, etc). Our hardware emulation routines will cope with those\n * situations as best they can (and when they don't, it should be considered a bug if some application is\n * broken as a result), but realistically, our hardware emulation is never likely to be 100% accurate.\n */\nVideo.MODE = {\n CGA_40X25_BW: 0,\n CGA_40X25: 1,\n CGA_80X25_BW: 2,\n CGA_80X25: 3,\n CGA_320X200: 4,\n CGA_320X200_BW: 5,\n CGA_640X200: 6,\n MDA_80X25: 7,\n EGA_320X200: 0x0D, // mapped at A000:0000, color, 4bpp, planar\n EGA_640X200: 0x0E, // mapped at A000:0000, color, 4bpp, planar\n EGA_640X350_MONO: 0x0F, // mapped at A000:0000, mono, 2bpp, planar\n EGA_640X350: 0x10, // mapped at A000:0000, color, 4bpp, planar\n VGA_640X480_MONO: 0x11, // mapped at A000:0000, mono, 2bpp, planar\n VGA_640X480: 0x12, // mapped at A000:0000, color, 4bpp, planar\n VGA_320X200: 0x13, // mapped at A000:0000, color, 8bpp, linear\n /*\n * The remaining mode identifiers are for internal use only; there is no correlation with any\n * publicly defined BIOS modes, and overlap with any third-party mode numbers is purely coincidental.\n */\n VGA_320X240: 0x14, // mapped at A000:0000, color, 8bpp, planar (\"Mode X\")\n VGA_320X400: 0x15, // mapped at A000:0000, color, 8bpp, planar\n /*\n * Here's where we might assign additional identifiers to certain unique combinations, like the\n * fTextGraphicsHybrid 320x400 mode that Windows 95 uses (ie, when the buffer is mapped to B800:0000\n * instead of A000:0000 and is configured for text mode access, but graphics are still being displayed\n * from the second half of video memory).\n */\n UNKNOWN: 0xFF\n};\n\nVideo.UPDATES_PER_SECOND = 60;\n\n/*\n * Supported Fonts\n *\n * Once we've finished loading the standard 8K font file, aFonts[] should contain one or more of the\n * entries listed below. For the standard MDA/CGA font ROM, the first (MDA) font resides in the first 4Kb,\n * and the second and third (CGA) fonts reside in the two 2K halves of the second 4Kb.\n *\n * It may seem odd that the cell size for FONT_CGAD is *larger* than the cell size for FONT_CGA,\n * since 40-column mode is actually lower resolution, but since we don't shrink the screen canvas when we\n * shrink the mode, the characters must be drawn larger, and they look better if we don't have to scale them.\n *\n * From the IBM EGA Manual (p.5):\n *\n * \"In alphanumeric modes, characters are formed from one of two ROM (Read Only Memory) character\n * generators on the adapter. One character generator defines 7x9 characters in a 9x14 character box.\n * For Enhanced Color Display support, the 9x14 character set is modified to provide an 8x14 character set.\n * The second character generator defines 7x7 characters in an 8x8 character box. These generators contain\n * dot patterns for 256 different characters. The character sets are identical to those provided by the\n * IBM Monochrome Display Adapter and the IBM Color/Graphics Monitor Adapter.\"\n */\nVideo.FONT = {\n MDA: 1, // 9x14 monochrome font\n CGA: 2, // 8x8 color font\n EGA: 3, // 8x14 color font\n VGA: 4 // 8x16 color font\n};\n\n/*\n * Supported Cards\n *\n * Note that we choose card IDs that match the default font ID for each card as well, for convenience.\n */\nVideo.CARD = {\n MDA: Video.FONT.MDA,\n CGA: Video.FONT.CGA,\n EGA: Video.FONT.EGA,\n VGA: Video.FONT.VGA\n};\n\n/*\n * Supported Models\n *\n * Each model refers to an array where [0] is the card ID, and [1] is the default mode.\n */\nVideo.MODEL = {\n \"mda\": [Video.CARD.MDA, Video.MODE.MDA_80X25],\n \"cga\": [Video.CARD.CGA, Video.MODE.CGA_80X25],\n \"ega\": [Video.CARD.EGA, Video.MODE.CGA_80X25],\n \"vga\": [Video.CARD.VGA, Video.MODE.CGA_80X25]\n};\n\n/*\n * Supported Monitors\n *\n * The MDA monitor displays 350 lines of vertical resolution, 720 lines of horizontal resolution, and refreshes\n * at ~50Hz. The CGA monitor displays 200 lines vertically, 640 horizontally, and refreshes at ~60Hz.\n *\n * Based on actual MDA timings (see http://diylab.atwebpages.com/pressureDev.htm), the total horizontal\n * period (drawing a line and retracing) is ~54.25uSec (1000000uSec / 18432) and the horizontal retrace interval\n * is about 15% of that, or ~8.14uSec. Vertical sync occurs once every 370 horizontal periods. Of those 370,\n * only 354 represent actively drawn lines (and of those, only 350 are visible); the remaining 16 horizontal\n * periods, or 4% of the 370 total, represent the vertical retrace interval.\n *\n * I don't have similar numbers for the CGA or EGA, so for now, I assume similar percentages; ie, 15% of\n * the horizontal period will represent horizontal retrace, and 4% of the vertical pixel maximum (262) will\n * represent vertical retrace. However, 24% of the CGA's 262 vertical maximum represents non-visible lines,\n * whereas only 5% of the MDA's 370 maximum represents non-visible lines; is there really that much \"overscan\"\n * on the CGA?\n *\n * For each monitor type, there's a Video.monitorSpecs object that describes the horizontal and vertical\n * timings, along with my assumptions about the percentage of time that drawing is \"active\" within those periods,\n * and then based on the selected monitor type, I compute the number of CPU cycles that each period lasts,\n * as well as the number of CPU cycles that drawing lasts within each period, so that the horizontal and vertical\n * retrace status flags can be quickly calculated.\n *\n * For reference, here are some important numbers to know (from https://github.com/reenigne/reenigne/blob/master/8088/cga/register_values.txt):\n *\n * CGA MDA\n * Pixel clock 14.318 MHz 16.257 MHz (aka \"maximum video bandwidth\", as IBM Tech Refs sometimes call it)\n * Horizontal 15.700 KHz 18.432 KHz (aka \"horizontal drive\", as IBM Tech Refs sometimes call it)\n * Vertical 59.923 Hz 49.816 Hz\n * Usage 53.69% 77.22%\n * H pix 912 = 114*8 882 = 98*9\n * V pix 262 370\n * Dots 238944 326340\n */\n\n/** @typedef {{ nHorzPeriodsPerSec: number, nHorzPeriodsPerFrame: number, percentHorzActive: number, percentVertActive: number }} */\nvar MonitorSpecs;\n\n/**\n * @type {Object}\n */\nVideo.monitorSpecs = {};\n\n/**\n * NOTE: Based on trial-and-error, 208 is the magic number of horizontal syncs per vertical sync that\n * yielded the necessary number of \"horizontal enables\" (200 or 0xC8) in the EGA ROM BIOS at C000:03D0.\n *\n * @type {{MonitorSpecs}}\n */\nVideo.monitorSpecs[ChipSet.MONITOR.COLOR] = {\n nHorzPeriodsPerSec: 15700,\n nHorzPeriodsPerFrame: 208,\n percentHorzActive: 85,\n percentVertActive: 96\n};\n\n/**\n * NOTE: Based on trial-and-error, 364 is the magic number of horizontal syncs per vertical sync that\n * yielded the necessary number of \"horizontal enables\" (350 or 0x15E) in the EGA ROM BIOS at C000:03D0.\n *\n * @type {{MonitorSpecs}}\n */\nVideo.monitorSpecs[ChipSet.MONITOR.MONO] = {\n nHorzPeriodsPerSec: 18432,\n nHorzPeriodsPerFrame: 364,\n percentHorzActive: 85,\n percentVertActive: 96\n};\n\n/**\n * @type {{MonitorSpecs}}\n */\nVideo.monitorSpecs[ChipSet.MONITOR.EGACOLOR] = {\n nHorzPeriodsPerSec: 21850,\n nHorzPeriodsPerFrame: 364,\n percentHorzActive: 85,\n percentVertActive: 96\n};\n\n/**\n * NOTE: As above, the following values are based purely on trial-and-error, to yield results that fall\n * squarely within the bounds of the IBM VGA ROM timing requirements; see the IBM VGA ROM code at C000:024A.\n *\n * @type {{MonitorSpecs}}\n */\nVideo.monitorSpecs[ChipSet.MONITOR.VGACOLOR] = {\n nHorzPeriodsPerSec: 16700,\n nHorzPeriodsPerFrame: 480,\n percentHorzActive: 85,\n percentVertActive: 83\n};\n\n/*\n * EGA Miscellaneous ports and SW1-Sw4\n *\n * The Card.MISC.CLOCK_SELECT bits determine which of the EGA board's 4 configuration switches are\n * returned via Card.STATUS0.SWSENSE (when SWSENSE is zero, the switch is closed):\n *\n * 0xC: return SW1\n * 0x8: return SW2\n * 0x4: return SW3\n * 0x0: return SW4\n *\n * These 4 bits are also copied to the byte at 40:88h by the EGA BIOS, where bit 0 is SW1, bit 1 is SW2,\n * bit 2 is SW3 and bit 3 is SW4. Our switch settings come from bEGASwitches, which in turn comes from\n * sSwitches, which in turn comes from the \"switches\" property passed to the Video component, if any.\n *\n * As usual, the switch settings are reversed in both direction and sense from the switch settings; the\n * good news, however, is that we can use the parseSwitches() method in the ChipSet component to parse them.\n *\n * The set of valid EGA switch values, after conversion, is stored in the table below. For each value,\n * there is an array that defines the corresponding monitor type(s) for the EGA adapter and any secondary\n * adapter. The third value is a boolean indicating whether the EGA is the primary adapter.\n */\nVideo.aEGAMonitorSwitches = {\n 0x06: [ChipSet.MONITOR.TV, ChipSet.MONITOR.MONO, true], // \"1001\"\n 0x07: [ChipSet.MONITOR.COLOR, ChipSet.MONITOR.MONO, true], // \"0001\"\n 0x08: [ChipSet.MONITOR.EGAEMULATION, ChipSet.MONITOR.MONO, true], // \"1110\"\n 0x09: [ChipSet.MONITOR.EGACOLOR, ChipSet.MONITOR.MONO, true], // \"0110\" [our default; see bEGASwitches below]\n 0x0a: [ChipSet.MONITOR.MONO, ChipSet.MONITOR.TV, true], // \"1010\"\n 0x0b: [ChipSet.MONITOR.MONO, ChipSet.MONITOR.COLOR, true], // \"0010\"\n 0x00: [ChipSet.MONITOR.TV, ChipSet.MONITOR.MONO, false], // \"1111\"\n 0x01: [ChipSet.MONITOR.COLOR, ChipSet.MONITOR.MONO, false], // \"0111\"\n 0x02: [ChipSet.MONITOR.EGAEMULATION, ChipSet.MONITOR.MONO, false], // \"1011\"\n 0x03: [ChipSet.MONITOR.EGACOLOR, ChipSet.MONITOR.MONO, false], // \"0011\"\n 0x04: [ChipSet.MONITOR.MONO, ChipSet.MONITOR.TV, false], // \"1101\"\n 0x05: [ChipSet.MONITOR.MONO, ChipSet.MONITOR.COLOR, false] // \"0101\"\n};\n\n/** @typedef {{ cxCell: number, cyCell: number, aCSSColors: Array, aRGBColors: Array, aColorMap: Array, aCanvas: Array }} */\nvar Font;\n\n/*\n * For each video mode, we need to know the following pieces of information:\n *\n * 0: # of columns (nCols)\n * 1: # of rows (nRows)\n * 2: # cells per word (nCellsPerWord: # of characters or pixels per word)\n * 3: # bytes of visible screen padding, if any (used for CGA graphics modes only)\n * 4: font ID (nFont: undefined if graphics mode)\n *\n * For MDA and CGA modes, a \"word\" of memory is 16 bits of CPU-addressable data, so by calculating\n * ([0] * [1]) / [2], we obtain the number of words that mode actively displays; for example, the\n * amount of visible memory used by mode 0x04 is (320 * 200) / 4, or 16000.\n *\n * However, for EGA and VGA graphics modes, a \"word\" of memory is a single element in the video buffer\n * containing 32 bits of pixel data.\n */\nVideo.aModeParms = []; // Mode\nVideo.aModeParms[Video.MODE.CGA_40X25] = [ 40, 25, 1, 0, Video.FONT.CGA]; // 0x01\nVideo.aModeParms[Video.MODE.CGA_80X25] = [ 80, 25, 1, 0, Video.FONT.CGA]; // 0x03\nVideo.aModeParms[Video.MODE.CGA_320X200] = [320, 200, 8, 192]; // 0x04\nVideo.aModeParms[Video.MODE.CGA_640X200] = [640, 200, 16, 192]; // 0x06\nVideo.aModeParms[Video.MODE.MDA_80X25] = [ 80, 25, 1, 0, Video.FONT.MDA]; // 0x07\nVideo.aModeParms[Video.MODE.EGA_320X200] = [320, 200, 8]; // 0x0D\nVideo.aModeParms[Video.MODE.EGA_640X200] = [640, 200, 8]; // 0x0E\nVideo.aModeParms[Video.MODE.EGA_640X350_MONO] = [640, 350, 8]; // 0x0F\nVideo.aModeParms[Video.MODE.EGA_640X350] = [640, 350, 8]; // 0x10\nVideo.aModeParms[Video.MODE.VGA_640X480_MONO] = [640, 480, 8]; // 0x11\nVideo.aModeParms[Video.MODE.VGA_640X480] = [640, 480, 8]; // 0x12\nVideo.aModeParms[Video.MODE.VGA_320X200] = [320, 200, 1]; // 0x13\nVideo.aModeParms[Video.MODE.VGA_320X240] = [320, 240, 4]; // 0x14\nVideo.aModeParms[Video.MODE.VGA_320X400] = [320, 400, 4]; // 0x15\nVideo.aModeParms[Video.MODE.CGA_40X25_BW] = Video.aModeParms[Video.MODE.CGA_40X25]; // 0x00\nVideo.aModeParms[Video.MODE.CGA_80X25_BW] = Video.aModeParms[Video.MODE.CGA_80X25]; // 0x02\nVideo.aModeParms[Video.MODE.CGA_320X200_BW] = Video.aModeParms[Video.MODE.CGA_320X200]; // 0x05\n\n/*\n * MDA attribute byte definitions\n *\n * For MDA, only the following group of ATTR definitions are supported; any FGND/BGND value combinations\n * outside this group will be treated as \"normal\" (ATTR_FGND_WHITE | ATTR_BGND_BLACK).\n *\n * NOTE: Assuming MDA.MODE.BLINK_ENABLE is set (which the ROM BIOS sets by default), ATTR_BGND_BLINK will\n * cause the *foreground* element of the cell to blink, even though it is part of the *background* attribute bits.\n *\n * Regarding blink rate, characters are supposed to blink every 16 vertical frames, which amounts to .26667 blinks\n * per second, assuming a 60Hz vertical refresh rate. So roughly every 267ms, we need to take care of any blinking\n * characters. updateScreen() maintains a global count (cBlinkVisible) of blinking characters, to simplify the\n * decision of when to redraw the screen.\n */\nVideo.ATTRS = {};\nVideo.ATTRS.FGND_BLACK = 0x00;\nVideo.ATTRS.FGND_ULINE = 0x01;\nVideo.ATTRS.FGND_WHITE = 0x07;\nVideo.ATTRS.FGND_BRIGHT = 0x08;\nVideo.ATTRS.BGND_BLACK = 0x00;\nVideo.ATTRS.BGND_WHITE = 0x70;\nVideo.ATTRS.BGND_BLINK = 0x80;\nVideo.ATTRS.BGND_BRIGHT = 0x80;\nVideo.ATTRS.DRAW_FGND = 0x100; // this is an internal attribute bit, indicating the foreground should be drawn\nVideo.ATTRS.DRAW_CURSOR = 0x200; // this is an internal attribute bit, indicating when the cursor should be drawn\n\n/*\n * Here's a \"cheat sheet\" for attribute byte combinations that the IBM MDA could have supported. The original (Aug 1981)\n * IBM Tech Ref is very terse and implies that only those marked with * are actually supported.\n *\n * *0x00: non-display ATTR_FGND_BLACK | ATTR_BGND_BLACK\n * *0x01: underline ATTR_FGND_ULINE | ATTR_BGND_BLACK\n * *0x07: normal (white on black) ATTR_FGND_WHITE | ATTR_BGND_BLACK\n * **0x09: bright underline ATTR_FGND_ULINE | ATTR_FGND_BRIGHT | ATTR_BGND_BLACK\n * **0x0F: bold (bright white on black) ATTR_FGND_WHITE | ATTR_FGND_BRIGHT | ATTR_BGND_BLACK\n * *0x70: reverse (black on white) ATTR_FGND_BLACK | | ATTR_BGND_WHITE\n * 0x81: blinking underline ATTR_FGND_ULINE | | ATTR_BGND_BLINK (or dim background if blink disabled)\n * **0x87: blinking normal ATTR_FGND_WHITE | | ATTR_BGND_BLINK (or dim background if blink disabled)\n * 0x89: blinking bright underline ATTR_FGND_ULINE | ATTR_FGND_BRIGHT | ATTR_BGND_BLINK (or dim background if blink disabled)\n * **0x8F: blinking bold ATTR_FGND_WHITE | ATTR_FGND_BRIGHT | ATTR_BGND_BLINK (or dim background if blink disabled)\n * **0xF0: blinking reverse ATTR_FGND_WHITE | ATTR_FGND_BRIGHT | ATTR_BGND_BLINK (or bright background if blink disabled)\n *\n * Unsupported attributes reportedly display as \"normal\" (ATTR_FGND_WHITE | ATTR_BGND_BLACK). However, precisely which\n * attributes are unsupported on the MDA varies depending on the source. Some sources (eg, the IBM Tech Ref) imply that\n * only those marked by * are supported, while others (eg, some--but not all--Peter Norton guides) include those marked\n * by **, and still others include ALL the combinations listed above.\n *\n * Furthermore, according to http://www.seasip.info/VintagePC/mda.html:\n *\n * Attributes 0x00, 0x08, 0x80 and 0x88 display as black space;\n * Attribute 0x78 displays as dark green on green; depending on the monitor, there may be a green \"halo\" where the dark and bright bits meet;\n * Attribute 0xF0 displays as a blinking version of 0x70 if blink enabled, and black on bright green otherwise;\n * Attribute 0xF8 displays as a blinking version of 0x78 if blink enabled, and as dark green on bright green otherwise.\n *\n * However, I'm rather skeptical about supporting 0x78 and 0xF8, until I see some evidence that \"bright black\" actually\n * produced dark green on IBM equipment; it also doesn't sound like a combination many people would have used. I'll probably\n * treat all of 0x08, 0x80 and 0x88 the same as 0x00, only because it seems logical (they're all \"black on black\" combinations\n * with only BRIGHT and/or BLINK bits set). Beyond that, I'll likely treat any other combination not listed in the above cheat\n * sheet as \"normal\".\n *\n * All the discrepancies/disagreements I've found are probably due in part to the proliferation of IBM and non-IBM MDA\n * cards, combined with IBM and non-IBM monochrome monitors, and people assuming that their non-IBM card and/or monitor\n * behaved exactly like the original IBM equipment, which probably wasn't true in all cases.\n *\n * I would like to limit my MDA display support to EXACTLY everything that the IBM MDA supported and nothing more, but\n * since there will be combinations that will logically \"fall out\" unless I specifically exclude them, it's very likely\n * this implementation will end up being a superset.\n */\n\n/*\n * CGA attribute byte definitions; these simply extend the set of MDA attributes, with the exception of ATTR_FNGD_ULINE,\n * which the CGA can treat only as ATTR_FGND_BLUE.\n */\nVideo.ATTRS.FGND_BLUE = 0x01;\nVideo.ATTRS.FGND_GREEN = 0x02;\nVideo.ATTRS.FGND_CYAN = 0x03;\nVideo.ATTRS.FGND_RED = 0x04;\nVideo.ATTRS.FGND_MAGENTA = 0x05;\nVideo.ATTRS.FGND_BROWN = 0x06;\n\nVideo.ATTRS.BGND_BLUE = 0x10;\nVideo.ATTRS.BGND_GREEN = 0x20;\nVideo.ATTRS.BGND_CYAN = 0x30;\nVideo.ATTRS.BGND_RED = 0x40;\nVideo.ATTRS.BGND_MAGENTA = 0x50;\nVideo.ATTRS.BGND_BROWN = 0x60;\n\n/*\n * For the MDA, the number of unique \"colors\" is 5, based on the following supported FGND attribute values:\n *\n * 0x0: black font (attribute value 0x8 is mapped to 0x0)\n * 0x1: green font with underline\n * 0x7: green font without underline (attribute values 0x2-0x6 are mapped to 0x7)\n * 0x9: bright green font with underline\n * 0xf: bright green font without underline (attribute values 0xa-0xe are mapped to 0xf)\n *\n * I'm still not sure about 0x8 (dark green?); for now, I'm mapping it to 0x0, but it may become a 6th supported color.\n *\n * MDA attributes form an index into aMDAColorMap, which in turn provides an index (0-4) into aMDAColors.\n */\nVideo.aMDAColors = [\n [0x00, 0x00, 0x00, 0xff],\n [0x7f, 0xc0, 0x7f, 0xff],\n [0x7f, 0xc0, 0x7f, 0xff],\n [0x7f, 0xff, 0x7f, 0xff],\n [0x7f, 0xff, 0x7f, 0xff]\n];\nVideo.aMDAColorMap = [0x0, 0x1, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x0, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4];\n\nVideo.aCGAColors = [\n [0x00, 0x00, 0x00, 0xff], // 0x00: ATTR_FGND_BLACK\n [0x00, 0x00, 0xaa, 0xff], // 0x01: ATTR_FGND_BLUE\n [0x00, 0xaa, 0x00, 0xff], // 0x02: ATTR_FGND_GREEN\n [0x00, 0xaa, 0xaa, 0xff], // 0x03: ATTR_FGND_CYAN\n [0xaa, 0x00, 0x00, 0xff], // 0x04: ATTR_FGND_RED\n [0xaa, 0x00, 0xaa, 0xff], // 0x05: ATTR_FGND_MAGENTA\n [0xaa, 0x55, 0x00, 0xff], // 0x06: ATTR_FGND_BROWN\n [0xaa, 0xaa, 0xaa, 0xff], // 0x07: ATTR_FGND_WHITE (aka light gray)\n [0x55, 0x55, 0x55, 0xff], // 0x08: ATTR_FGND_BLACK | ATTR_FGND_BRIGHT (aka gray)\n [0x55, 0x55, 0xff, 0xff], // 0x09: ATTR_FGND_BLUE | ATTR_FGND_BRIGHT\n [0x55, 0xff, 0x55, 0xff], // 0x0A: ATTR_FGND_GREEN | ATTR_FGND_BRIGHT\n [0x55, 0xff, 0xff, 0xff], // 0x0B: ATTR_FGND_CYAN | ATTR_FGND_BRIGHT\n [0xff, 0x55, 0x55, 0xff], // 0x0C: ATTR_FGND_RED | ATTR_FGND_BRIGHT\n [0xff, 0x55, 0xff, 0xff], // 0x0D: ATTR_FGND_MAGENTA | ATTR_FGND_BRIGHT\n [0xff, 0xff, 0x55, 0xff], // 0x0E: ATTR_FGND_BROWN | ATTR_FGND_BRIGHT (aka yellow)\n [0xff, 0xff, 0xff, 0xff] // 0x0F: ATTR_FGND_WHITE | ATTR_FGND_BRIGHT (aka white)\n];\n\nVideo.aCGAColorSet1 = [Video.ATTRS.FGND_GREEN, Video.ATTRS.FGND_RED, Video.ATTRS.FGND_BROWN];\nVideo.aCGAColorSet2 = [Video.ATTRS.FGND_CYAN, Video.ATTRS.FGND_MAGENTA, Video.ATTRS.FGND_WHITE];\n\n/*\n * Here is the EGA BIOS default ATC palette register set for color text modes, from which getCardColors()\n * builds a default RGB array, similar to aCGAColors above.\n */\nVideo.aEGAPalDef = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F];\n\nVideo.aEGAByteToDW = [\n 0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,\n 0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,\n 0xff000000|0, 0xff0000ff|0, 0xff00ff00|0, 0xff00ffff|0,\n 0xffff0000|0, 0xffff00ff|0, 0xffffff00|0, 0xffffffff|0\n];\n\nVideo.aEGADWToByte = [];\nVideo.aEGADWToByte[0x00000000] = 0x0;\nVideo.aEGADWToByte[0x00000080] = 0x1;\nVideo.aEGADWToByte[0x00008000] = 0x2;\nVideo.aEGADWToByte[0x00008080] = 0x3;\nVideo.aEGADWToByte[0x00800000] = 0x4;\nVideo.aEGADWToByte[0x00800080] = 0x5;\nVideo.aEGADWToByte[0x00808000] = 0x6;\nVideo.aEGADWToByte[0x00808080] = 0x7;\nVideo.aEGADWToByte[0x80000000|0] = 0x8;\nVideo.aEGADWToByte[0x80000080|0] = 0x9;\nVideo.aEGADWToByte[0x80008000|0] = 0xa;\nVideo.aEGADWToByte[0x80008080|0] = 0xb;\nVideo.aEGADWToByte[0x80800000|0] = 0xc;\nVideo.aEGADWToByte[0x80800080|0] = 0xd;\nVideo.aEGADWToByte[0x80808000|0] = 0xe;\nVideo.aEGADWToByte[0x80808080|0] = 0xf;\n\n/*\n * Card Specifications\n *\n * We support dynamically switching between MDA and CGA cards by simply flipping switches on\n * the virtual SW1 switch block and resetting the machine. However, I'm not sure I'll support\n * dynamically switching the EGA card the same way; there's certainly no UI for it at this point.\n *\n * For each supported card, there is a cardSpec array that the Card class uses to initialize the\n * card's defaults:\n *\n * [0]: card descriptor\n * [1]: default CRTC port address\n * [2]: default video buffer address\n * [3]: default video buffer size\n * [4]: total on-board memory (if no \"memory\" parm was specified)\n * [5]: default monitor type\n *\n * If total on-board memory is zero, then addMemory() will simply add the specified video buffer\n * to the address space; otherwise, we will allocate an internal buffer (adwMemory) and tell addMemory()\n * to map it to the video buffer address. The latter approach gives us total control over the buffer;\n * refer to getMemoryAccess().\n *\n * TODO: Consider allocating our own buffer for all video cards, not just EGA/VGA. For MDA/CGA, I'm not\n * sure it would offer any benefits, other than allowing our internal update functions, like updateScreen(),\n * to access the buffer directly, instead of going through the Bus memory interface.\n */\nVideo.cardSpecs = [];\nVideo.cardSpecs[Video.CARD.MDA] = [\"MDA\", Card.MDA.CRTC.INDX.PORT, 0xB0000, 0x01000, 0, ChipSet.MONITOR.MONO];\nVideo.cardSpecs[Video.CARD.CGA] = [\"CGA\", Card.CGA.CRTC.INDX.PORT, 0xB8000, 0x04000, 0, ChipSet.MONITOR.COLOR];\nVideo.cardSpecs[Video.CARD.EGA] = [\"EGA\", Card.CGA.CRTC.INDX.PORT, 0xB8000, 0x04000, 0x10000, ChipSet.MONITOR.EGACOLOR];\nVideo.cardSpecs[Video.CARD.VGA] = [\"VGA\", Card.CGA.CRTC.INDX.PORT, 0xB8000, 0x04000, 0x40000, ChipSet.MONITOR.VGACOLOR];\n\n/*\n * Values for nTouchConfig; a value will be selected based on the sTouchScreen configuration parameter.\n */\nVideo.TOUCH = {\n NONE: 0,\n DEFAULT: 1,\n KEYGRID: 2,\n MOUSE: 3\n};\n\n/*\n * Why simulate a SPACE if the tap is in the middle third (center) of the screen? Well, apparently\n * I didn't explain earlier that the WHOLE reason I originally added KEYGRID support (before it was\n * even called KEYGRID support) was to make the 1985 game \"Rogue\" (pcjs.org/apps/pcx86/1985/rogue)\n * more fun to play on an iPad (the space-bar is a commonly required key).\n */\nVideo.KEYGRID = [\n [Keyboard.SIMCODE.HOME, Keyboard.SIMCODE.UP, Keyboard.SIMCODE.PGUP],\n [Keyboard.SIMCODE.LEFT, Keyboard.SIMCODE.SPACE, Keyboard.SIMCODE.RIGHT],\n [Keyboard.SIMCODE.END, Keyboard.SIMCODE.DOWN, Keyboard.SIMCODE.PGDN],\n];\n\n/*\n * Port input/output notification tables\n *\n * TODO: At one point, I'd added some \"duplicate\" entries for the MDA because, according to docs I'd read,\n * MDA ports are decoded at multiple addresses. However, if this is important, then it should be verified\n * and implemented consistently (eg, for CGA as well). For now, I'm decoding only the standard port addresses.\n *\n * For example, 0x3B5 is apparently also decoded at 0x3B1, 0x3B3, and 0x3B7, while 0x3B4 is also decoded at\n * 0x3B0, 0x3B2, and 0x3B6.\n */\nVideo.aMDAPortInput = {\n 0x3B4: Video.prototype.inMDAIndx, // technically, not actually readable, but I want the Debugger to be able to read this\n 0x3B5: Video.prototype.inMDAData, // technically, the only CRTC Data registers that are readable are R14-R17\n 0x3B8: Video.prototype.inMDAMode, // technically, not actually readable, but I want the Debugger to be able to read this\n 0x3BA: Video.prototype.inMDAStatus\n};\n\nVideo.aMDAPortOutput = {\n 0x3B4: Video.prototype.outMDAIndx,\n 0x3B5: Video.prototype.outMDAData,\n 0x3B8: Video.prototype.outMDAMode\n};\n\nVideo.aCGAPortInput = {\n 0x3D4: Video.prototype.inCGAIndx, // technically, not actually readable, but I want the Debugger to be able to read this\n 0x3D5: Video.prototype.inCGAData, // technically, the only CRTC Data registers that are readable are R14-R17\n 0x3D8: Video.prototype.inCGAMode, // technically, not actually readable, but I want the Debugger to be able to read this\n 0x3D9: Video.prototype.inCGAColor, // technically, not actually readable, but I want the Debugger to be able to read this\n 0x3DA: Video.prototype.inCGAStatus\n};\n\nVideo.aCGAPortOutput = {\n 0x3D4: Video.prototype.outCGAIndx,\n 0x3D5: Video.prototype.outCGAData,\n 0x3D8: Video.prototype.outCGAMode,\n 0x3D9: Video.prototype.outCGAColor\n};\n\nVideo.aEGAPortInput = {\n 0x3C0: Video.prototype.inATCIndx, // technically, only readable on a VGA, but I want the Debugger to be able to read this, too\n 0x3C1: Video.prototype.inATCData, // technically, only readable on a VGA, but I want the Debugger to be able to read this, too\n 0x3C2: Video.prototype.inStatus0,\n 0x3C4: Video.prototype.inSEQIndx, // technically, only readable on a VGA, but I want the Debugger to be able to read this, too\n 0x3C5: Video.prototype.inSEQData, // technically, only readable on a VGA, but I want the Debugger to be able to read this, too\n 0x3CE: Video.prototype.inGRCIndx, // technically, only readable on a VGA, but I want the Debugger to be able to read this, too\n 0x3CF: Video.prototype.inGRCData // technically, only readable on a VGA, but I want the Debugger to be able to read this, too\n};\n\n/*\n * WARNING: Unlike the EGA, a standard VGA does not support writes to 0x3C1, but it's easier for me to leave that\n * ability in place, treating the VGA as a superset of the EGA as much as possible; will any code break because word\n * OUTs to port 0x3C0 (and/or byte OUTs to port 0x3C1) actually work? Possibly, but highly unlikely.\n */\nVideo.aEGAPortOutput = {\n 0x3BA: Video.prototype.outFeat,\n 0x3C0: Video.prototype.outATC,\n 0x3C1: Video.prototype.outATC, // the EGA BIOS writes to this port (see C000:0416), implying that 0x3C0 and 0x3C1 both decode the same register\n 0x3C2: Video.prototype.outMisc, // FYI, since this overlaps with STATUS0.PORT, there's currently no way for the Debugger to read the Misc register\n 0x3C4: Video.prototype.outSEQIndx,\n 0x3C5: Video.prototype.outSEQData,\n 0x3CA: Video.prototype.outGRCPos2,\n 0x3CC: Video.prototype.outGRCPos1,\n 0x3CE: Video.prototype.outGRCIndx,\n 0x3CF: Video.prototype.outGRCData,\n 0x3DA: Video.prototype.outFeat\n};\n\nVideo.aVGAPortInput = {\n 0x3C3: Video.prototype.inVGAEnable,\n 0x3C6: Video.prototype.inDACMask,\n 0x3C7: Video.prototype.inDACState,\n 0x3C9: Video.prototype.inDACData,\n 0x3CA: Video.prototype.inVGAFeat,\n 0x3CC: Video.prototype.inVGAMisc\n};\n\nVideo.aVGAPortOutput = {\n 0x3C3: Video.prototype.outVGAEnable,\n 0x3C6: Video.prototype.outDACMask,\n 0x3C7: Video.prototype.outDACRead,\n 0x3C8: Video.prototype.outDACWrite,\n 0x3C9: Video.prototype.outDACData\n};\n\n/*\n * Initialize every Video module on the page.\n */\nWeb.onInit(Video.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/parallel.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * class ParallelPort\n * property {number} iAdapter\n * property {number} portBase\n * property {number} nIRQ\n * property {Object} controlBuffer is a DOM element bound to the port (for rudimentary output; see transmitByte())\n *\n * NOTE: This class declaration started as a way of informing the code inspector of the controlBuffer property,\n * which remained undefined until a setBinding() call set it later, but I've since decided that explicitly\n * initializing such properties in the constructor is a better way to go -- even though it's more code -- because\n * JavaScript compilers are supposed to be happier when the underlying object structures aren't constantly changing.\n *\n * Besides, I'm not sure I want to get into documenting every property this way, for this or any/every other class,\n * let alone getting into which ones should be considered private or protected, because PCjs isn't really a library\n * for third-party apps.\n */\n\n/**\n * class ParallelPort\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass ParallelPort extends Component {\n /**\n * ParallelPort(parmsParallel)\n *\n * The ParallelPort component has the following component-specific (parmsParallel) properties:\n *\n * adapter: 1 (port 0x3BC), 2 (port 0x378), or 3 (port 0x278); 0 if not defined\n *\n * binding: name of a control (based on its \"binding\" attribute) to bind to this port's I/O\n *\n * In the future, we may support 'port' and 'irq' properties that allow the machine to define a\n * non-standard parallel port configuration, instead of only our pre-defined 'adapter' configurations.\n *\n * NOTE: Since the XSL file defines 'adapter' as a number, not a string, there's no need to use\n * parseInt(), and as an added benefit, we don't need to worry about whether a hex or decimal format\n * was used.\n *\n * DOS typically names the Primary adapter \"LPT1\" and the Secondary adapter \"LPT2\", but I prefer\n * to stick to adapter numbers, since not all operating systems follow those naming conventions.\n *\n * @this {ParallelPort}\n * @param {Object} parmsParallel\n */\n constructor(parmsParallel)\n {\n super(\"ParallelPort\", parmsParallel, Messages.PARALLEL);\n\n this.iAdapter = parmsParallel['adapter'];\n\n switch (this.iAdapter) {\n case 1:\n this.portBase = 0x3BC;\n this.nIRQ = ChipSet.IRQ.LPT1;\n break;\n case 2:\n this.portBase = 0x378;\n this.nIRQ = ChipSet.IRQ.LPT1;\n break;\n case 3:\n this.portBase = 0x278;\n this.nIRQ = ChipSet.IRQ.LPT2;\n break;\n default:\n Component.warning(\"Unrecognized parallel adapter #\" + this.iAdapter);\n return;\n }\n /**\n * consoleBuffer becomes a string that records parallel port output if the 'binding' property is set to the\n * reserved name \"console\". Nothing is written to the console, however, until a linefeed (0x0A) is output\n * or the string length reaches a threshold (currently, 1024 characters).\n *\n * @type {string|null}\n */\n this.consoleBuffer = null;\n\n /**\n * controlBuffer is a DOM element bound to the port (currently used for output only; see transmitByte()).\n *\n * @type {Object}\n */\n this.controlBuffer = null;\n\n var sBinding = parmsParallel['binding'];\n if (sBinding == \"console\") {\n this.consoleBuffer = \"\";\n } else {\n /*\n * If the ParallelPort wants to bind to a control (eg, \"print\") in a DIFFERENT component (eg, \"Panel\"),\n * then it specifies the name of that control with the 'binding' property. The ParallelPort constructor\n * will then call bindExternalControl(), which looks up the control, and then passes it to our own\n * setBinding() handler.\n * \n * For bindExternalControl() to succeed, it also need to know the target component; for now, that's\n * been hard-coded to \"Panel\", in part because that's one of the few components we can rely upon\n * initializing before we do, but it would be a simple matter to include a component type or ID as part\n * of the 'binding' property as well, if we need more flexibility later.\n * \n * NOTE: If sBinding is not the name of a valid Control Panel DOM element, this call does nothing.\n */\n Component.bindExternalControl(this, sBinding);\n }\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {ParallelPort}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"buffer\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n if (sHTMLType == null || sHTMLType == \"textarea\") {\n this.bindings[sBinding] = this.controlBuffer = control;\n return true;\n }\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {ParallelPort}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.chipset = cmp.getMachineComponent(\"ChipSet\");\n bus.addPortInputTable(this, ParallelPort.aPortInput, this.portBase);\n bus.addPortOutputTable(this, ParallelPort.aPortOutput, this.portBase);\n this.setReady();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {ParallelPort}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data || !this.restore) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {ParallelPort}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {ParallelPort}\n */\n reset()\n {\n this.initState();\n }\n\n /**\n * save()\n *\n * This implements save support for the ParallelPort component.\n *\n * @this {ParallelPort}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveRegisters());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the ParallelPort component.\n *\n * @this {ParallelPort}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return this.initState(data[0]);\n }\n\n /**\n * initState(data)\n *\n * @this {ParallelPort}\n * @param {Array} [data]\n * @return {boolean} true if successful, false if failure\n */\n initState(data)\n {\n var i = 0;\n if (data === undefined) {\n data = [0, ParallelPort.STATUS.NERR, 0];\n }\n this.bData = data[i++];\n this.bStatus = data[i++];\n this.bControl = data[i];\n return true;\n }\n\n /**\n * saveRegisters()\n *\n * @this {ParallelPort}\n * @return {Array}\n */\n saveRegisters()\n {\n var i = 0;\n var data = [];\n data[i++] = this.bData;\n data[i++] = this.bStatus;\n data[i] = this.bControl;\n return data;\n }\n\n /**\n * inData(port, addrFrom)\n *\n * @this {ParallelPort}\n * @param {number} port (0x3BC, 0x378, or 0x278)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inData(port, addrFrom)\n {\n var b = this.bData;\n this.printMessageIO(port, null, addrFrom, \"DATA\", b);\n return b;\n }\n\n /**\n * inStatus(port, addrFrom)\n *\n * @this {ParallelPort}\n * @param {number} port (0x3BD, 0x379, or 0x279)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inStatus(port, addrFrom)\n {\n var b = this.bStatus;\n this.bStatus |= (ParallelPort.STATUS.NACK | ParallelPort.STATUS.NBUSY);\n this.printMessageIO(port, null, addrFrom, \"STAT\", b);\n this.updateIRR();\n return b;\n }\n\n /**\n * inControl(port, addrFrom)\n *\n * @this {ParallelPort}\n * @param {number} port (0x3BE, 0x37A, or 0x27A)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inControl(port, addrFrom)\n {\n var b = this.bControl;\n this.printMessageIO(port, null, addrFrom, \"CTRL\", b);\n return b;\n }\n\n /**\n * outData(port, bOut, addrFrom)\n *\n * @this {ParallelPort}\n * @param {number} port (0x3BC, 0x378, or 0x278)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outData(port, bOut, addrFrom)\n {\n var parallel = this;\n this.printMessageIO(port, bOut, addrFrom, \"DATA\");\n this.bData = bOut;\n this.cpu.nonCPU(function() {\n if (parallel.transmitByte(bOut)) {\n parallel.bStatus |= ParallelPort.STATUS.NERR;\n parallel.bStatus &= ~(ParallelPort.STATUS.NACK | ParallelPort.STATUS.NBUSY);\n return true;\n }\n return false;\n });\n this.updateIRR();\n }\n\n /**\n * outControl(port, bOut, addrFrom)\n *\n * @this {ParallelPort}\n * @param {number} port (0x3BE, 0x37A, or 0x27A)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outControl(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"CTRL\");\n this.bControl = bOut;\n this.updateIRR();\n }\n\n /**\n * updateIRR()\n *\n * @this {ParallelPort}\n */\n updateIRR()\n {\n if (this.chipset && this.nIRQ) {\n if ((this.bControl & ParallelPort.CONTROL.IRQ_ENABLE) && !(this.bStatus & ParallelPort.STATUS.NACK)) {\n this.chipset.setIRR(this.nIRQ);\n } else {\n this.chipset.clearIRR(this.nIRQ);\n }\n }\n }\n\n /**\n * transmitByte(b)\n *\n * @this {ParallelPort}\n * @param {number} b\n * @return {boolean} true if transmitted, false if not\n */\n transmitByte(b)\n {\n var fTransmitted = false;\n\n this.printMessage(\"transmitByte(\" + Str.toHexByte(b) + \")\");\n\n if (this.controlBuffer) {\n if (b == 0x0D) {\n // this.iLogicalCol = 0;\n }\n else if (b == 0x08) {\n this.controlBuffer.value = this.controlBuffer.value.slice(0, -1);\n }\n else {\n /*\n * If we assume that the printer being used was the original IBM 80 CPS Matrix Printer,\n * characters 0x80-0x9F mirror control codes 0x00-0x1F, and characters 0xA0-0xDF are various\n * block shapes, sort of in the spirit of the line-drawing characters 0xC0-0xDF defined by\n * IBM Code Page 437, but, no, completely different. And apparently, characters 0xE0-0xFF\n * printed nothing at all (see Table 11 on page 2-78 of the original IBM PC 5150 TechRef).\n *\n * The only control character we care about is LINE-FEED; for all other control characters,\n * we'll display the ASCII mnemonic, to make it clear what the software intended. And as for\n * any block characters, we'll print an asterisk and call it good, for now. Beyond that,\n * we'll just print spaces.\n */\n if (b >= 0x80) {\n if (b < 0xA0) {\n b -= 0x80;\n } else if (b < 0xE0) {\n b = 0x2A; // ASCII code for an asterisk\n } else {\n b = 0x20; // ASCII code for a space\n }\n }\n this.controlBuffer.value += Str.toASCIICode(b);\n this.controlBuffer.scrollTop = this.controlBuffer.scrollHeight;\n }\n fTransmitted = true;\n }\n else if (this.consoleBuffer != null) {\n if (b == 0x0A || this.consoleBuffer.length >= 1024) {\n this.println(this.consoleBuffer);\n this.consoleBuffer = \"\";\n }\n if (b != 0x0A) {\n this.consoleBuffer += String.fromCharCode(b);\n }\n fTransmitted = true;\n }\n\n return fTransmitted;\n }\n\n /**\n * ParallelPort.init()\n *\n * This function operates on every HTML element of class \"parallel\", extracting the\n * JSON-encoded parameters for the ParallelPort constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a ParallelPort component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeParallel = Component.getElementsByClass(document, PCX86.APPCLASS, \"parallel\");\n for (var iParallel = 0; iParallel < aeParallel.length; iParallel++) {\n var eParallel = aeParallel[iParallel];\n var parmsParallel = Component.getComponentParms(eParallel);\n var parallel = new ParallelPort(parmsParallel);\n Component.bindComponentControls(parallel, eParallel, PCX86.APPCLASS);\n }\n }\n}\n\n/*\n * The \"Data Register\" is an input/output register at offset 0 from portBase. The bit-to-pin mappings are:\n *\n * Bit Pin\n * --- ---\n * 0 2 // 0x01 (DATA 1)\n * 1 3 // 0x02 (DATA 2)\n * 2 4 // 0x04 (DATA 3)\n * 3 5 // 0x08 (DATA 4)\n * 4 6 // 0x10 (DATA 5)\n * 5 7 // 0x20 (DATA 6)\n * 6 8 // 0x40 (DATA 7)\n * 7 9 // 0x80 (DATA 8)\n */\nParallelPort.DATA = { // (read/write)\n REG: 0\n};\n\n/*\n * The \"Status Register\" is an input register at offset 1 from portBase. The bit-to-pin mappings are:\n *\n * Bit Pin\n * --- ---\n * 0 - // 0x01\n * 1 - // 0x02\n * 2 - // 0x04\n * 3 !15 // 0x08 (Error)\n * 4 13 // 0x10 (Select)\n * 5 12 // 0x20 (Out of Paper)\n * 6 !10 // 0x40 (Acknowledged)\n * 7 11 // 0x80 (Busy; eg, printer off-line or operation in progress)\n */\nParallelPort.STATUS = { // (read)\n REG: 1,\n NERR: 0x08, // when this bit is clear, I/O error (inverted by the ROM BIOS INT 17h Status function)\n SELECT: 0x10, // when this bit is set, printer selected\n PAPER: 0x20, // when this bit is set, out of paper\n NACK: 0x40, // when this bit is clear, data acknowledged (and optionally, interrupt requested; inverted by the ROM BIOS INT 17h Status function)\n NBUSY: 0x80 // when this bit is clear, printer busy\n};\n\n/*\n * The \"Control Register\" is an input/output register at offset 2 from portBase. The bit-to-pin mappings are:\n *\n * Bit Pin\n * --- ---\n * 0 !1 // 0x01 (read input data)\n * 1 !14 // 0x02 (automatically feed paper one line)\n * 2 16 // 0x04\n * 3 !17 // 0x08\n *\n * Additionally, bit 4 is the IRQ ENABLE bit, which allows interrupts when pin 10 transitions high to low.\n */\nParallelPort.CONTROL = { // (read/write)\n REG: 2,\n IRQ_ENABLE: 0x10 // set to enable interrupts\n};\n\n/*\n * Port input notification table\n */\nParallelPort.aPortInput = {\n 0x0: ParallelPort.prototype.inData,\n 0x1: ParallelPort.prototype.inStatus,\n 0x2: ParallelPort.prototype.inControl\n};\n\n/*\n * Port output notification table\n */\nParallelPort.aPortOutput = {\n 0x0: ParallelPort.prototype.outData,\n 0x2: ParallelPort.prototype.outControl\n};\n\n/*\n * Initialize every ParallelPort module on the page.\n */\nWeb.onInit(ParallelPort.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/serial.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * SerialPort class\n *\n * The class property declarations below started as a way of informing the code inspector of the controlBuffer\n * property, which remained undefined until a setBinding() call set it later, but I've since decided that explicitly\n * initializing such properties in the constructor is a better way to go -- even though it's more code -- because\n * JavaScript compilers are supposed to be happier when the underlying object structures aren't constantly changing.\n *\n * Besides, I'm not sure I want to get into documenting every property this way, for this or any/every other class,\n * let alone getting into which ones should be considered private or protected, because PCjs isn't really a library\n * for third-party apps.\n *\n * @class SerialPort\n * @property {number} iAdapter\n * @property {number} portBase\n * @property {number} nIRQ\n * @property {string|null} consoleBuffer\n * @property {HTMLTextAreaElement} controlBuffer (DOM element bound to the port for rudimentary output; see transmitByte())\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass SerialPort extends Component {\n /**\n * SerialPort(parms)\n *\n * The SerialPort component has the following component-specific (parms) properties:\n *\n * adapter: 1 (port 0x3F8) or 2 (port 0x2F8); 0 if not defined\n *\n * binding: name of a control (based on its \"binding\" attribute) to bind to this port's I/O;\n * as a special case, it can be set to \"console\" to direct all output to the component's default\n * println() handler (eg, the Control Panel's \"print\" control, if any, or console.log() if using\n * a DEBUG or non-COMPILED machine)\n *\n * tabSize: a non-zero number specifies the tab-stop multiple to use for automatic tab-to-space\n * conversion; it applies only to the above binding, and the default is 0 (no tab conversion)\n *\n * charBOL: a non-zero number specifies the ASCII code of a character to display at the beginning\n * of every line; it applies only to the above binding, and the default is 0 (no BOL character)\n *\n * In the future, we may support 'port' and 'irq' properties that allow the machine to define a non-standard\n * serial port configuration, instead of only our pre-defined 'adapter' configurations.\n *\n * NOTE: Since the XSL file defines 'adapter' as a number, not a string, there's no need to use parseInt(),\n * and as an added benefit, we don't need to worry about whether a hex or decimal format was used.\n *\n * This hard-coded approach mimics the original IBM PC Asynchronous Adapter configuration, which contained\n * a pair of \"shunt modules\" that allowed the user to select a port address/IRQ combo of either 0x3F8/IRQ4\n * (\"Primary\") or 0x2F8/IRQ3 (\"Secondary\").\n *\n * DOS names the first adapter listed by the ROM BIOS as \"COM1\", even if that adapter is a secondary adapter,\n * so don't assume that COM1 always maps to port 0x3F8/IRQ4. Internally, I try avoid confusion by always\n * starting with a primary adapter and giving that adapter an ID of \"com1\". But different operating systems\n * may follow different device enumeration and naming conventions, so don't make too much of my internally\n * assigned IDs.\n *\n * @this {SerialPort}\n * @param {Object} parms\n */\n constructor(parms)\n {\n super(\"SerialPort\", parms, Messages.SERIAL);\n\n this.iAdapter = parms['adapter'];\n\n switch (this.iAdapter) {\n case 1:\n this.portBase = 0x3F8;\n this.nIRQ = ChipSet.IRQ.COM1;\n break;\n case 2:\n this.portBase = 0x2F8;\n this.nIRQ = ChipSet.IRQ.COM2;\n break;\n default:\n if (this.idComponent != \"test\") {\n Component.warning(\"Unrecognized serial adapter #\" + this.iAdapter);\n return;\n }\n break;\n }\n \n /*\n * consoleBuffer becomes a string that records serial port output if the 'binding' property is set to the\n * reserved name \"console\". Nothing is written to the console, however, until a linefeed (0x0A) is output\n * or the string length reaches a threshold (currently, 1024 characters).\n */\n this.consoleBuffer = null;\n\n /*\n * controlBuffer is a DOM element bound to the port (currently used for output only; see transmitByte()).\n *\n * Example: CTTY COM2\n *\n * The CTTY DOS command redirects all CON I/O to the specified serial port (eg, COM2), which it assumes is\n * connected to a serial terminal, and therefore anything it *transmits* via COM2 will be displayed by the\n * terminal. It further assumes that anything typed on such a terminal is NOT displayed, so as DOS *receives*\n * serial input, DOS *transmits* the appropriate characters back to the terminal via COM2.\n *\n * As a result, controlBuffer only needs to be updated by the transmitByte() function.\n */\n this.controlBuffer = null;\n\n /*\n * If controlBuffer is being used AND 'tabSize' is set, then we make an attempt to monitor the characters\n * being echoed via transmitByte(), maintain a logical column position, and convert any tabs into the appropriate\n * number of spaces.\n *\n * Another controlBuffer feature is charBOL, which, if nonzero, specifies a character to automatically output\n * at the beginning of every line. This probably isn't generally useful; I use it internally to preformat serial\n * output.\n */\n this.tabSize = parms['tabSize'] || 0;\n this.charBOL = parms['charBOL'] || 0;\n this.charPrev = 0;\n this.iLogicalCol = 0;\n\n this.bMSRInit = SerialPort.MSR.CTS | SerialPort.MSR.DSR;\n this.fNullModem = true;\n\n /*\n * Normally, any HTML controls defined within the scope of the component's XML element are *implicitly*\n * bound to us. For example, in the XML below, the textarea control will automatically trigger a call to\n * setBinding() with sBinding set to \"serialWindow\" and control set to an HTMLTextAreaElement.\n * \n\t * <serial id=\"com1\">\n\t * <control type=\"container\" class=\"pcjs-textarea\">\n\t * \t <control type=\"textarea\" binding=\"serialWindow\"/>\n\t * </control>\n\t * </serial>\n\t * \n\t * However, this component also supports an *explicit* binding attribute, which can either be the hard-coded\n\t * name \"console\" (for routing all output to the system console) or the name of a control binding that has\n\t * been defined in another component (eg, an HTMLTextAreaElement defined as part of the Control Panel layout).\n */\n var sBinding = parms['binding'];\n if (sBinding == \"console\") {\n this.consoleBuffer = \"\";\n } else {\n /*\n * If the SerialPort wants to bind to a control (eg, \"print\") in a DIFFERENT component (eg, \"Panel\"),\n * then it specifies the name of that control with the 'binding' property. The SerialPort constructor\n * will then call bindExternalControl(), which looks up the control, and then passes it to our own\n * setBinding() handler.\n * \n * For bindExternalControl() to succeed, it also need to know the target component; for now, that's\n * been hard-coded to \"Panel\", in part because that's one of the few components we can rely upon\n * initializing before we do, but it would be a simple matter to include a component type or ID as part\n * of the 'binding' property as well, if we need more flexibility later.\n * \n * NOTE: If sBinding is not the name of a valid Control Panel DOM element, this call does nothing.\n */\n Component.bindExternalControl(this, sBinding);\n }\n\n /*\n * No connection until initConnection() is called.\n */\n this.sDataReceived = \"\";\n this.connection = this.sendData = this.updateStatus = null;\n this.fAutoFlow = false;\n\n /*\n * Export all functions required by bindConnection() or initConnection(), whichever is required.\n */\n this['exports'] = {\n 'bind': this.bindConnection,\n 'connect': this.initConnection,\n 'receiveData': this.receiveData,\n 'receiveStatus': this.receiveStatus\n };\n }\n\n /**\n * bindConnection(connection, receiveData, fAutoFlow)\n * \n * This is basically a lighter-weight version of initConnection(), used by built-in components\n * like TestController, as opposed to components in external machines, which require more work to connect.\n *\n * @this {SerialPort}\n * @param {Component} connection\n * @param {function()} receiveData\n * @param {boolean} [fAutoFlow] (true to enable automatic flow control; default is false)\n * @return {boolean}\n */\n bindConnection(connection, receiveData, fAutoFlow = false)\n {\n if (!this.connection) {\n this.connection = connection;\n this.sendData = receiveData;\n this.fAutoFlow = fAutoFlow;\n return true;\n }\n return false;\n }\n\n /**\n * bindMouse(id, mouse, fnUpdate)\n *\n * @this {SerialPort}\n * @param {string} id\n * @param {Mouse} mouse\n * @param {function(number)} fnUpdate\n * @return {Component|null}\n */\n bindMouse(id, mouse, fnUpdate)\n {\n var component = null;\n if (id == this.idComponent && !this.connection) {\n this.connection = mouse;\n this.updateStatus = fnUpdate;\n this.fNullModem = false;\n component = this;\n }\n return component;\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {SerialPort}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"buffer\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n if (sHTMLType == null || sHTMLType == \"textarea\") {\n\n var serial = this;\n this.bindings[sBinding] = this.controlBuffer = /** @type {HTMLTextAreaElement} */ (control);\n\n /*\n * By establishing an onkeypress handler here, we make it possible for DOS commands like\n * \"CTTY COM1\" to more or less work (use \"CTTY CON\" to restore control to the DOS console).\n */\n this.controlBuffer.onkeydown = function onKeyDown(event) {\n /*\n * This is required in addition to onkeypress, because it's the only way to prevent\n * BACKSPACE (keyCode 8) from being interpreted by the browser as a \"Back\" operation;\n * moreover, not all browsers generate an onkeypress notification for BACKSPACE.\n *\n * A related problem exists for Ctrl-key combinations in most Windows-based browsers\n * (eg, IE, Edge, Chrome for Windows, etc), because keys like Ctrl-C and Ctrl-S have\n * special meanings (eg, Copy, Save). To the extent the browser will allow it, we\n * attempt to disable that default behavior when this control receives an onkeydown\n * event for one of those keys (probably the only event the browser generates for them).\n */\n event = event || window.event;\n var keyCode = event.keyCode;\n if (keyCode === 0x08 || event.ctrlKey && keyCode >= 0x41 && keyCode <= 0x5A) {\n if (event.preventDefault) event.preventDefault();\n if (keyCode > 0x40) keyCode -= 0x40;\n serial.receiveData(keyCode);\n }\n return true;\n };\n\n this.controlBuffer.onkeypress = function onKeyPress(event) {\n /*\n * Browser-independent keyCode extraction; refer to onKeyPress() and the other key event\n * handlers in keyboard.js.\n */\n event = event || window.event;\n var keyCode = event.which || event.keyCode;\n serial.receiveData(keyCode);\n /*\n * Since we're going to remove the \"readonly\" attribute from the <textarea> control\n * (so that the soft keyboard activates on iOS), instead of calling preventDefault() for\n * selected keys (eg, the SPACE key, whose default behavior is to scroll the page), we must\n * now call it for *all* keys, so that the keyCode isn't added to the control immediately,\n * on top of whatever the machine is echoing back, resulting in double characters.\n */\n if (event.preventDefault) event.preventDefault();\n return true;\n };\n\n /*\n * Now that we've added an onkeypress handler that calls preventDefault() for ALL keys, the control\n * itself no longer needs the \"readonly\" attribute; we primarily need to remove it for iOS browsers,\n * so that the soft keyboard will activate, but it shouldn't hurt to remove the attribute for all browsers.\n */\n this.controlBuffer.removeAttribute(\"readonly\");\n return true;\n }\n\n // default:\n // if (!this.iAdapter) {\n // control.removeAttribute(\"readonly\");\n // }\n // break;\n // }\n \n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {SerialPort}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n \n if (this.iAdapter) {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n var serial = this;\n this.timerReceiveNext = this.cpu.addTimer(this.id + \".receive\", function receiveDataTimer() {\n serial.receiveData();\n });\n this.timerTransmitNext = this.cpu.addTimer(this.id + \".transmit\", function transmitDataTimer() {\n serial.transmitData();\n });\n\n this.chipset = cmp.getMachineComponent(\"ChipSet\");\n\n bus.addPortInputTable(this, SerialPort.aPortInput, this.portBase);\n bus.addPortOutputTable(this, SerialPort.aPortOutput, this.portBase);\n }\n this.setReady();\n }\n\n /**\n * initConnection(fNullModem)\n *\n * If a machine 'connection' parameter exists of the form \"{sourcePort}->{targetMachine}.{targetPort}\",\n * and \"{sourcePort}\" matches our idComponent, then look for a component with id \"{targetMachine}.{targetPort}\".\n *\n * If the target component is found, then verify that it has exported functions with the following names:\n *\n * receiveData(data): called when we have data to transmit; aliased internally to sendData(data)\n * receiveStatus(pins): called when our control signals have changed; aliased internally to updateStatus(pins)\n *\n * For now, we're not going to worry about communication in the other direction, because when the target component\n * performs its own initConnection(), it will find our receiveData() and receiveStatus() functions, at which point\n * communication in both directions should be established, and the circle of life is complete.\n *\n * For added robustness, if the target machine initializes much more slowly than we do, and our connection attempt\n * fails, that's OK, because when it finally initializes, its initConnection() will call our initConnection();\n * if we've already initialized, no harm done.\n *\n * @this {SerialPort}\n * @param {boolean} [fNullModem] (caller's null-modem setting, to ensure our settings are in agreement)\n */\n initConnection(fNullModem)\n {\n if (!this.connection) {\n var sConnection = this.cmp.getMachineParm(\"connection\");\n if (sConnection) {\n var asParts = sConnection.split('->');\n if (asParts.length == 2) {\n var sSourceID = Str.trim(asParts[0]);\n if (sSourceID != this.idComponent) return; // this connection string is intended for another instance\n var sTargetID = Str.trim(asParts[1]);\n this.connection = Component.getComponentByID(sTargetID);\n if (this.connection) {\n var exports = this.connection['exports'];\n if (exports) {\n var fnConnect = /** @function */ (exports['connect']);\n if (fnConnect) fnConnect.call(this.connection, this.fNullModem);\n this.sendData = exports['receiveData'];\n if (this.sendData) {\n this.fNullModem = fNullModem;\n this.updateStatus = exports['receiveStatus'];\n this.status(\"Connected \" + this.idMachine + '.' + sSourceID + \" to \" + sTargetID);\n return;\n }\n }\n }\n }\n /*\n * Changed from notice() to status() because sometimes a connection fails simply because one of us is a laggard.\n */\n this.status(\"Unable to establish connection: \" + sConnection);\n }\n }\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {SerialPort}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n /*\n * This is as late as we can currently wait to make our first inter-machine connection attempt;\n * even so, the target machine's initialization process may still be ongoing, so any connection\n * may be not fully resolved until the target machine performs its own initConnection(), which will\n * in turn invoke our initConnection() again.\n */\n this.initConnection(this.fNullModem);\n\n if (!data || !this.restore) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {SerialPort}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {SerialPort}\n */\n reset()\n {\n this.initState();\n }\n\n /**\n * save()\n *\n * This implements save support for the SerialPort component.\n *\n * @this {SerialPort}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveRegisters());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the SerialPort component.\n *\n * @this {SerialPort}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return this.initState(data[0]);\n }\n\n /**\n * initState(data)\n *\n * @this {SerialPort}\n * @param {Array} [data]\n * @return {boolean} true if successful, false if failure\n */\n initState(data)\n {\n /*\n * The NS8250A spec doesn't explicitly say what the RBR and THR are initialized to on a reset,\n * but I think we can safely assume zeros. Similarly, we reset the baud rate Divisor Latch (wDL)\n * to an arbitrary but consistent default (DL_DEFAULT).\n */\n var i = 0;\n if (data === undefined) {\n data = [\n 0, // RBR\n 0, // THR\n SerialPort.DL_DEFAULT, // DL\n 0, // IER\n SerialPort.IIR.NO_INT, // IIR\n 0, // LCR\n 0, // MCR\n SerialPort.LSR.THRE | SerialPort.LSR.TSRE, // LSR\n this.bMSRInit, // MSR\n []\n ];\n }\n this.bRBR = data[i++];\n this.bTHR = data[i++];\n this.wDL = data[i++];\n this.bIER = data[i++];\n this.bIIR = data[i++];\n this.bLCR = data[i++];\n this.bMCR = data[i++];\n this.bLSR = data[i++];\n this.bMSR = data[i++];\n this.abReceive = data[i];\n return true;\n }\n\n /**\n * saveRegisters()\n *\n * @this {SerialPort}\n * @return {Array}\n */\n saveRegisters()\n {\n var i = 0;\n var data = [];\n data[i++] = this.bRBR;\n data[i++] = this.bTHR;\n data[i++] = this.wDL;\n data[i++] = this.bIER;\n data[i++] = this.bIIR;\n data[i++] = this.bLCR;\n data[i++] = this.bMCR;\n data[i++] = this.bLSR;\n data[i++] = this.bMSR;\n data[i] = this.abReceive;\n return data;\n }\n\n /**\n * getBaudTimeout()\n *\n * The 16-bit Divisor Latch is stored in wDL. If we take the frequency value 1843200 and divide it by wDL*128,\n * we get the maximum number of bytes per second that the SerialPort interface should generate. For example,\n * if a baud rate of 1200 is being used, the divisor will be 0x60 (96), so we calculate 1843200/(96*128) = 150,\n * which means there should be a 1000ms/150 or 6.667ms delay between bytes delivered.\n *\n * @this {SerialPort}\n * @return {number} (number of milliseconds per byte)\n */\n getBaudTimeout()\n {\n var nBytesPerSecond = 1843200 / ((this.wDL || 1) << 7);\n return (1000 / nBytesPerSecond)|0;\n }\n\n /**\n * receiveData(data)\n *\n * This replaces the old sendRBR() function, which expected an Array of bytes. We still support that,\n * but in order to support connections with other SerialPort components (ie, the PC8080 SerialPort), we\n * have added support for numbers and strings as well. If no data is specified at all, then all we do\n * is \"clock\" any remaining data into the receiver.\n *\n * @this {SerialPort}\n * @param {number|string|Array} [data]\n * @return {boolean} true if received, false if not\n */\n receiveData(data)\n {\n if (data != null) {\n if (typeof data == \"number\") {\n this.abReceive.push(data);\n }\n else if (typeof data == \"string\") {\n for (var i = 0; i < data.length; i++) {\n this.abReceive.push(data.charCodeAt(i));\n }\n }\n else {\n this.abReceive = this.abReceive.concat(data);\n }\n }\n this.advanceRBR();\n return true; // for now, return true regardless, since we're buffering everything anyway\n }\n\n /**\n * receiveStatus(pins)\n *\n * NOTE: Prior to the addition of this interface, the CTS and DSR bits were initialized set and remained set\n * for the life of the machine. It is entirely appropriate that this is the only way those bits can be changed,\n * because they represent external control signals.\n *\n * @this {SerialPort}\n * @param {number} pins\n */\n receiveStatus(pins)\n {\n var bMSROld = this.bMSR;\n this.bMSR &= ~(SerialPort.MSR.CTS | SerialPort.MSR.DSR);\n if (pins & RS232.CTS.MASK) {\n this.bMSR |= SerialPort.MSR.CTS | SerialPort.MSR.DCTS;\n }\n if (pins & RS232.DSR.MASK) {\n this.bMSR |= SerialPort.MSR.DSR | SerialPort.MSR.DDSR;\n }\n if (bMSROld != this.bMSR) this.updateIIR();\n }\n\n /**\n * advanceRBR()\n *\n * @this {SerialPort}\n */\n advanceRBR()\n {\n if (this.abReceive.length > 0 && !(this.bLSR & SerialPort.LSR.DR)) {\n if (!this.fAutoFlow || (this.bMCR & SerialPort.MCR.RTS)) {\n this.bRBR = this.abReceive.shift();\n this.bLSR |= SerialPort.LSR.DR;\n if (this.abReceive.length && this.cpu) {\n this.cpu.setTimer(this.timerReceiveNext, this.getBaudTimeout());\n }\n }\n }\n this.updateIIR();\n }\n\n /**\n * inRBR(port, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3F8 or 0x2F8)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inRBR(port, addrFrom)\n {\n var b = ((this.bLCR & SerialPort.LCR.DLAB) ? (this.wDL & 0xff) : this.bRBR);\n this.printMessageIO(port, null, addrFrom, (this.bLCR & SerialPort.LCR.DLAB) ? \"DLL\" : \"RBR\", b);\n this.bLSR &= ~SerialPort.LSR.DR;\n this.advanceRBR();\n return b;\n }\n\n /**\n * inIER(port, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3F9 or 0x2F9)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inIER(port, addrFrom)\n {\n var b = ((this.bLCR & SerialPort.LCR.DLAB) ? (this.wDL >> 8) : this.bIER);\n this.printMessageIO(port, null, addrFrom, (this.bLCR & SerialPort.LCR.DLAB) ? \"DLM\" : \"IER\", b);\n return b;\n }\n\n /**\n * inIIR(port, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3FA or 0x2FA)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inIIR(port, addrFrom)\n {\n var b = this.bIIR;\n /*\n * Reading the IIR is supposed to clear the INT_THR condition (as is another write to the THR).\n */\n if (b == SerialPort.IIR.INT_THR) {\n this.bIIR = SerialPort.IIR.NO_INT;\n }\n this.printMessageIO(port, null, addrFrom, \"IIR\", b);\n return b;\n }\n\n /**\n * inLCR(port, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3FB or 0x2FB)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inLCR(port, addrFrom)\n {\n var b = this.bLCR;\n this.printMessageIO(port, null, addrFrom, \"LCR\", b);\n return b;\n }\n\n /**\n * inMCR(port, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3FC or 0x2FC)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inMCR(port, addrFrom)\n {\n var b = this.bMCR;\n this.printMessageIO(port, null, addrFrom, \"MCR\", b);\n return b;\n }\n\n /**\n * inLSR(port, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3FD or 0x2FD)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inLSR(port, addrFrom)\n {\n var b = this.bLSR;\n this.printMessageIO(port, null, addrFrom, \"LSR\", b);\n return b;\n }\n\n /**\n * inMSR(port, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3FE or 0x2FE)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inMSR(port, addrFrom)\n {\n var b = this.bMSR;\n this.bMSR &= ~(SerialPort.MSR.DCTS | SerialPort.MSR.DDSR);\n this.printMessageIO(port, null, addrFrom, \"MSR\", b);\n return b;\n }\n\n /**\n * outTHR(port, bOut, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3F8 or 0x2F8)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outTHR(port, bOut, addrFrom)\n {\n var serial = this;\n this.printMessageIO(port, bOut, addrFrom, (this.bLCR & SerialPort.LCR.DLAB) ? \"DLL\" : \"THR\");\n if (this.bLCR & SerialPort.LCR.DLAB) {\n this.wDL = (this.wDL & ~0xff) | bOut;\n } else {\n this.bTHR = bOut;\n this.bLSR &= ~(SerialPort.LSR.THRE | SerialPort.LSR.TSRE);\n /*\n * If transmitByte() returned success, we used to immediately re-set the transmitter empty bits:\n *\n * this.bLSR |= (SerialPort.LSR.THRE | SerialPort.LSR.TSRE);\n *\n * But when we're connected to a virtual device that has no measurable delay, that sets the bits\n * too quickly. We now arm a timer based on the programmed baud rate, and set the above bits only\n * when that timer fires.\n *\n * Additionally, we no longer care if transmitByte() succeeds, because whether or not a connected\n * device or component received the data is irrelevant to the internal mechanics of the serial port.\n *\n * TODO: Determine if we should also flush/zero bTHR after transmission.\n */\n this.cpu.nonCPU(function() {\n return serial.transmitByte(bOut);\n });\n this.cpu.setTimer(this.timerTransmitNext, this.getBaudTimeout());\n this.updateIIR();\n }\n }\n\n /**\n * outIER(port, bOut, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3F9 or 0x2F9)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outIER(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, (this.bLCR & SerialPort.LCR.DLAB) ? \"DLM\" : \"IER\");\n if (this.bLCR & SerialPort.LCR.DLAB) {\n this.wDL = (this.wDL & 0xff) | (bOut << 8);\n } else {\n this.bIER = bOut;\n }\n }\n\n /**\n * outLCR(port, bOut, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3FB or 0x2FB)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outLCR(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"LCR\");\n this.bLCR = bOut;\n }\n\n /**\n * outMCR(port, bOut, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3FC or 0x2FC)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outMCR(port, bOut, addrFrom)\n {\n var delta = (bOut ^ this.bMCR);\n this.printMessageIO(port, bOut, addrFrom, \"MCR\");\n this.bMCR = bOut;\n /*\n * Whenever DTR or RTS changes, we also need to notify any connected machine or mouse, via updateStatus().\n */\n if (delta & (SerialPort.MCR.DTR | SerialPort.MCR.RTS)) {\n if (this.updateStatus) {\n var pins = 0;\n if (this.fNullModem) {\n pins |= (bOut & SerialPort.MCR.RTS)? RS232.CTS.MASK : 0;\n pins |= (bOut & SerialPort.MCR.DTR)? (RS232.DSR.MASK | RS232.CD.MASK): 0;\n } else {\n pins |= (bOut & SerialPort.MCR.RTS)? RS232.RTS.MASK : 0;\n pins |= (bOut & SerialPort.MCR.DTR)? RS232.DTR.MASK : 0;\n }\n this.updateStatus.call(this.connection, pins);\n }\n /*\n * Throw in a call to advanceRBR() for good measure, in case fAutoFlow is set and RTS was just enabled.\n */\n this.advanceRBR();\n }\n }\n\n /**\n * updateIIR()\n *\n * @this {SerialPort}\n */\n updateIIR()\n {\n var bIIR = -1;\n /*\n * We check all the interrupt conditions in priority order. TODO: Add INT_LSR.\n */\n if ((this.bLSR & SerialPort.LSR.DR) && (this.bIER & SerialPort.IER.RBR_AVAIL)) {\n bIIR = SerialPort.IIR.INT_RBR;\n }\n else if ((this.bLSR & SerialPort.LSR.THRE) && (this.bIER & SerialPort.IER.THR_EMPTY)) {\n bIIR = SerialPort.IIR.INT_THR;\n }\n else if ((this.bMSR & (SerialPort.MSR.DCTS | SerialPort.MSR.DDSR)) && (this.bIER & SerialPort.IER.MSR_DELTA)) {\n bIIR = SerialPort.IIR.INT_MSR;\n }\n if (bIIR >= 0) {\n this.bIIR &= ~(SerialPort.IIR.NO_INT | SerialPort.IIR.INT_BITS);\n this.bIIR |= bIIR;\n /*\n * I still throttle SerialPort interrupts by passing a hard-coded delay of 100 instructions to setIRR(),\n * even though we are now (theoretically) honoring the programmed baud rate. The setIRR() delay does not\n * ensure any particular baud rate, it simply gives the underlying Interrupt Service Routine (ISR) some\n * breathing room.\n *\n * The Microsoft Windows 1.01 serial mouse driver ISR issues an EOI before it has safely exited, presumably\n * relying on the fact that a 1200 baud serial device would not normally interrupt frequently enough to\n * blow the stack. However, in PCx86, all you have to do is remove the delay below and enable Debugger\n * messages on every serial interrupt and mouse event, eg:\n *\n * m serial on;m pic on;m mouse on\n *\n * to slow the machine down to the point where serial mouse interrupts overwhelm the ISR. The Debugger\n * messages display the current stack pointer, which you can watch drop to zero and then wrap around, no\n * doubt trampling lots of code and data along the way.\n *\n * This problem could also occur without being forced by the Debugger; eg, if your physical machine's mouse\n * was configured for a high interrupt rate, and your browser generated mouse events at a comparable rate.\n */\n if (this.chipset && this.nIRQ) this.chipset.setIRR(this.nIRQ, 100);\n } else {\n this.bIIR = SerialPort.IIR.NO_INT;\n if (this.chipset && this.nIRQ) this.chipset.clearIRR(this.nIRQ);\n }\n }\n\n /**\n * transmitByte(b)\n *\n * @this {SerialPort}\n * @param {number} b\n * @return {boolean} true if transmitted, false if not\n */\n transmitByte(b)\n {\n var fTransmitted = false;\n\n this.printMessage(\"transmitByte(\" + Str.toHexByte(b) + \")\");\n\n if (this.sendData) {\n if (this.sendData.call(this.connection, b)) {\n fTransmitted = true;\n }\n }\n\n if (this.controlBuffer) {\n if (b == 0x0D) {\n this.iLogicalCol = 0;\n }\n else if (b == 0x08) {\n this.controlBuffer.value = this.controlBuffer.value.slice(0, -1);\n /*\n * TODO: Back up the correct number of columns if the character erased was a tab.\n */\n if (this.iLogicalCol > 0) this.iLogicalCol--;\n }\n else {\n var s = Str.toASCIICode(b); // formerly: String.fromCharCode(b);\n var nChars = s.length; // formerly: (b >= 0x20? 1 : 0);\n if (b < 0x20 && nChars == 1) nChars = 0;\n if (b == 0x09) {\n var tabSize = this.tabSize || 8;\n nChars = tabSize - (this.iLogicalCol % tabSize);\n if (this.tabSize) s = Str.pad(\"\", nChars);\n }\n if (!this.iLogicalCol && nChars) {\n /*\n * When BASIC.COM outputs a listing to a serial port, it ends every line with a CR (0x0D)\n * but no LF (0x0A), which seems a bit odd. We fix that here.\n */\n if (this.charPrev != 0x0A) s = \"\\n\" + s;\n if (this.charBOL) s = String.fromCharCode(this.charBOL) + s;\n }\n this.controlBuffer.value += s;\n this.controlBuffer.scrollTop = this.controlBuffer.scrollHeight;\n this.iLogicalCol += nChars;\n }\n this.charPrev = b;\n fTransmitted = true;\n }\n else if (this.consoleBuffer != null) {\n if (b == 0x0A || this.consoleBuffer.length >= 1024) {\n this.println(this.consoleBuffer);\n this.consoleBuffer = \"\";\n }\n if (b != 0x0A) {\n this.consoleBuffer += String.fromCharCode(b);\n }\n fTransmitted = true;\n }\n\n return fTransmitted;\n }\n\n /**\n * transmitData()\n *\n * Helper for clocking transmitted data at the expected baud rate.\n *\n * @this {SerialPort}\n */\n transmitData()\n {\n this.bLSR |= (SerialPort.LSR.THRE | SerialPort.LSR.TSRE);\n this.updateIIR();\n }\n\n /**\n * SerialPort.init()\n *\n * This function operates on every HTML element of class \"serial\", extracting the\n * JSON-encoded parameters for the SerialPort constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a SerialPort component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeSerial = Component.getElementsByClass(document, PCX86.APPCLASS, \"serial\");\n for (var iSerial = 0; iSerial < aeSerial.length; iSerial++) {\n var eSerial = aeSerial[iSerial];\n var parms = Component.getComponentParms(eSerial);\n var serial = new SerialPort(parms);\n Component.bindComponentControls(serial, eSerial, PCX86.APPCLASS);\n }\n }\n}\n\n/*\n * 8250 I/O register offsets (add these to a I/O base address to obtain an I/O port address)\n *\n * NOTE: DLL.REG and DLM.REG form a 16-bit divisor into a clock input frequency of 1.8432Mhz. The following\n * values should be used for the corresponding baud rates. Rates above 9600 are discouraged by the IBM Tech Ref,\n * but rates as high as 128000 are listed on the NS8250A data sheet.\n *\n * Divisor Rate Percent Error\n * 0x0900 50\n * 0x0600 75\n * 0x0417 110 0.026%\n * 0x0359 134.5 0.058%\n * 0x0300 150\n * 0x0180 300\n * 0x00C0 600\n * 0x0060 1200\n * 0x0040 1800\n * 0x003A 2000 0.69%\n * 0x0030 2400\n * 0x0020 3600\n * 0x0018 4800\n * 0x0010 7200\n * 0x000C 9600\n * 0x0006 19200\n * 0x0003 38400\n * 0x0002 56000 2.86%\n * 0x0001 128000\n */\nSerialPort.DLL = {REG: 0}; // Divisor Latch LSB (only when SerialPort.LCR.DLAB is set)\nSerialPort.THR = {REG: 0}; // Transmitter Holding Register (write)\nSerialPort.DL_DEFAULT = 0x180; // we select an arbitrary default Divisor Latch equivalent to 300 baud\n\n/*\n * Receiver Buffer Register (RBR.REG, offset 0; eg, 0x3F8 or 0x2F8) on read, Transmitter Holding Register on write\n */\nSerialPort.RBR = {REG: 0}; // (read)\n\n/*\n * Interrupt Enable Register (IER.REG, offset 1; eg, 0x3F9 or 0x2F9)\n */\nSerialPort.IER = {\n REG: 1, // Interrupt Enable Register\n RBR_AVAIL: 0x01,\n THR_EMPTY: 0x02,\n LSR_DELTA: 0x04,\n MSR_DELTA: 0x08,\n UNUSED: 0xF0 // always zero\n};\n\nSerialPort.DLM = {REG: 1}; // Divisor Latch MSB (only when SerialPort.LCR.DLAB is set)\n\n/*\n * Interrupt ID Register (IIR.REG, offset 2; eg, 0x3FA or 0x2FA)\n *\n * All interrupt conditions cleared by reading the corresponding register (or, in the case of IIR.INT_THR, writing a new value to THR.REG)\n */\nSerialPort.IIR = {\n REG: 2, // Interrupt ID Register (read-only)\n NO_INT: 0x01,\n INT_LSR: 0x06, // Line Status (highest priority: Overrun error, Parity error, Framing error, or Break Interrupt)\n INT_RBR: 0x04, // Receiver Data Available\n INT_THR: 0x02, // Transmitter Holding Register Empty\n INT_MSR: 0x00, // Modem Status Register (lowest priority: Clear To Send, Data Set Ready, Ring Indicator, or Data Carrier Detect)\n INT_BITS: 0x06,\n UNUSED: 0xF8 // always zero (the ROM BIOS relies on these bits \"floating to 1\" when no SerialPort is present)\n};\n\n/*\n * Line Control Register (LCR.REG, offset 3; eg, 0x3FB or 0x2FB)\n */\nSerialPort.LCR = {\n REG: 3, // Line Control Register\n DATA_5BITS: 0x00,\n DATA_6BITS: 0x01,\n DATA_7BITS: 0x02,\n DATA_8BITS: 0x03,\n STOP_BITS: 0x04, // clear: 1 stop bit; set: 1.5 stop bits for LCR_DATA_5BITS, 2 stop bits for all other data lengths\n PARITY_BIT: 0x08, // if set, a parity bit is inserted/expected between the last data bit and the first stop bit; no parity bit if clear\n PARITY_EVEN: 0x10, // if set, even parity is selected (ie, the parity bit insures an even number of set bits); if clear, odd parity\n PARITY_STICK: 0x20, // if set, parity bit is transmitted inverted; if clear, parity bit is transmitted normally\n BREAK: 0x40, // if set, serial output (SOUT) signal is forced to logical 0 for the duration\n DLAB: 0x80 // Divisor Latch Access Bit; if set, DLL.REG and DLM.REG can be read or written\n};\n\n/*\n * Modem Control Register (MCR.REG, offset 4; eg, 0x3FC or 0x2FC)\n */\nSerialPort.MCR = {\n REG: 4, // Modem Control Register\n DTR: 0x01, // when set, DTR goes high, indicating ready to establish link (looped back to DSR in loop-back mode)\n RTS: 0x02, // when set, RTS goes high, indicating ready to exchange data (looped back to CTS in loop-back mode)\n OUT1: 0x04, // when set, OUT1 goes high (looped back to RI in loop-back mode)\n OUT2: 0x08, // when set, OUT2 goes high (looped back to RLSD in loop-back mode); must also be set for most UARTs to enable interrupts (but not ours)\n LOOPBACK: 0x10, // when set, enables loop-back mode\n UNUSED: 0xE0 // always zero\n};\n\n/*\n * Line Status Register (LSR.REG, offset 5; eg, 0x3FD or 0x2FD)\n *\n * NOTE: I've seen different specs for the LSR_TSRE. I'm following the IBM Tech Ref's lead here, but the data sheet\n * I have calls it TEMT instead of TSRE, and claims that it is set whenever BOTH the THR and TSR are empty, and clear\n * whenever EITHER the THR or TSR contain data.\n */\nSerialPort.LSR = {\n REG: 5, // Line Status Register\n DR: 0x01, // Data Ready (set when new data in RBR.REG; cleared when RBR.REG read)\n OE: 0x02, // Overrun Error (set when new data arrives in RBR.REG before previous data read; cleared when LSR.REG read)\n PE: 0x04, // Parity Error (set when new data has incorrect parity; cleared when LSR.REG read)\n FE: 0x08, // Framing Error (set when new data has invalid stop bit; cleared when LSR.REG read)\n BI: 0x10, // Break Interrupt (set when new data exceeded normal transmission time; cleared LSR.REG when read)\n THRE: 0x20, // Transmitter Holding Register Empty (set when UART ready to accept new data; cleared when THR.REG written)\n TSRE: 0x40, // Transmitter Shift Register Empty (set when the TSR is empty; cleared when the THR is transferred to the TSR)\n UNUSED: 0x80 // always zero\n};\n\n/*\n * Modem Status Register (MSR.REG, offset 6; eg, 0x3FE or 0x2FE)\n */\nSerialPort.MSR = {\n REG: 6, // Modem Status Register\n DCTS: 0x01, // when set, CTS (Clear To Send) has changed since last read\n DDSR: 0x02, // when set, DSR (Data Set Ready) has changed since last read\n TERI: 0x04, // when set, TERI (Trailing Edge Ring Indicator) indicates RI has changed from 1 to 0\n DRLSD: 0x08, // when set, RLSD (Received Line Signal Detector) has changed\n CTS: 0x10, // when set, the modem or data set is ready to exchange data (complement of the Clear To Send input signal)\n DSR: 0x20, // when set, the modem or data set is ready to establish link (complement of the Data Set Ready input signal)\n RI: 0x40, // complement of the RI (Ring Indicator) input\n RLSD: 0x80 // complement of the RLSD (Received Line Signal Detect) input\n};\n\n/*\n * Scratch Register (SCR.REG, offset 7; eg, 0x3FF or 0x2FF)\n */\nSerialPort.SCR = {REG: 7};\n\n/*\n * Port input notification table\n */\nSerialPort.aPortInput = {\n 0x0: SerialPort.prototype.inRBR, // or DLL if DLAB set\n 0x1: SerialPort.prototype.inIER, // or DLM if DLAB set\n 0x2: SerialPort.prototype.inIIR,\n 0x3: SerialPort.prototype.inLCR,\n 0x4: SerialPort.prototype.inMCR,\n 0x5: SerialPort.prototype.inLSR,\n 0x6: SerialPort.prototype.inMSR\n};\n\n/*\n * Port output notification table\n */\nSerialPort.aPortOutput = {\n 0x0: SerialPort.prototype.outTHR, // or DLL if DLAB set\n 0x1: SerialPort.prototype.outIER, // or DLM if DLAB set\n 0x3: SerialPort.prototype.outLCR,\n 0x4: SerialPort.prototype.outMCR\n};\n\n/*\n * Initialize every SerialPort module on the page.\n */\nWeb.onInit(SerialPort.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/testctl.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * This module provides connectivity between the TestMonitor component and whichever PCx86 SerialPort\n * our 'binding' property indicates, if any.\n */\n\n\n/**\n * TestController class\n *\n * @class TestController\n * @property {string|undefined urlTests\n * @property {Object|null} tests\n * @property {string|null} consoleBuffer\n * @property {HTMLTextAreaElement|null} controlBuffer\n * @property {function(...)|null} sendData\n * @property {function(number)|null} deliverData\n * @property {function(number)|null} deliverInput\n * @property {function(Object)|null} deliverTests\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass TestController extends Component {\n /**\n * TestController(parms)\n *\n * @this {TestController}\n * @param {Object} parms\n */\n constructor(parms)\n {\n super(\"TestController\", parms);\n\n this.tests = null;\n let fLoading = false;\n this.urlTests = parms['tests'];\n \n this.consoleBuffer = \"\";\n this.controlBuffer = null;\n this.sendData = null;\n this.deliverData = this.deliverInput = this.deliverTests = null;\n \n this.sBinding = parms['binding'];\n if (this.sBinding) {\n this.serialPort = Component.getComponentByID(this.sBinding, this.id);\n if (this.serialPort) {\n let exports = this.serialPort['exports'];\n if (exports) {\n let bind = /** @function */ (exports['bind']);\n if (bind && bind.call(this.serialPort, this, this.receiveData, true)) {\n this.sendData = exports['receiveData'].bind(this.serialPort);\n if (this.urlTests) {\n this.loadTests(this.urlTests);\n fLoading = true;\n }\n }\n }\n }\n if (!this.sendData) {\n Component.warning(this.id + \": binding '\" + this.sBinding + \"' unavailable\");\n }\n }\n if (!fLoading) this.setReady();\n }\n\n /**\n * loadTests(sURL)\n *\n * @this {TestController}\n * @param {string} sURL\n */\n loadTests(sURL)\n {\n let controller = this;\n let sProgress = \"Loading \" + sURL + \"...\";\n Web.getResource(sURL, null, true, function(sURL, sResponse, nErrorCode) {\n controller.doneLoad(sURL, sResponse, nErrorCode);\n }, function(nState) {\n controller.println(sProgress, Component.PRINT.PROGRESS);\n });\n \n }\n \n /**\n * doneLoad(sURL, sTestData, nErrorCode)\n *\n * @this {TestController}\n * @param {string} sURL\n * @param {string} sTestData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n doneLoad(sURL, sTestData, nErrorCode)\n {\n if (nErrorCode) {\n this.notice(\"Unable to load tests (error \" + nErrorCode + \": \" + sURL + \")\", nErrorCode < 0);\n }\n else {\n try {\n this.tests = /** @type {Object} */ (JSON.parse(sTestData));\n if (this.deliverTests) {\n this.deliverTests(this.tests);\n this.tests = null;\n }\n Component.addMachineResource(this.idMachine, sURL, sTestData);\n } catch (err) {\n this.notice(\"Test parsing error: \" + err.message);\n }\n }\n this.setReady();\n }\n\n /**\n * bindMonitor(monitor, deliverData, deliverInput, deliverTests)\n *\n * @this {TestController}\n * @param {TestMonitor} monitor\n * @param {function(number)} deliverData\n * @param {function(number)} deliverInput\n * @param {function(Object)} deliverTests\n */\n bindMonitor(monitor, deliverData, deliverInput, deliverTests)\n {\n this.deliverData = deliverData.bind(monitor);\n this.deliverInput = deliverInput.bind(monitor);\n this.deliverTests = deliverTests.bind(monitor);\n if (this.tests && this.deliverTests) {\n this.deliverTests(this.tests);\n this.tests = null;\n }\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {TestController}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"buffer\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n let controller = this;\n\n if (sHTMLType == \"textarea\" && !this.controlBuffer) {\n\n this.bindings[sBinding] = control;\n this.controlBuffer = /** @type {HTMLTextAreaElement} */ (control);\n this.consoleBuffer = null; // we currently use one or the other: control or console\n\n /*\n * By establishing an onkeypress handler here, we make it possible for DOS commands like\n * \"CTTY COM1\" to more or less work (use \"CTTY CON\" to restore control to the DOS console).\n */\n control.onkeydown = function onKeyDown(event) {\n /*\n * This is required in addition to onkeypress, because it's the only way to prevent\n * BACKSPACE (keyCode 8) from being interpreted by the browser as a \"Back\" operation;\n * moreover, not all browsers generate an onkeypress notification for BACKSPACE.\n *\n * A related problem exists for Ctrl-key combinations in most Windows-based browsers\n * (eg, IE, Edge, Chrome for Windows, etc), because keys like Ctrl-C and Ctrl-S have\n * special meanings (eg, Copy, Save). To the extent the browser will allow it, we\n * attempt to disable that default behavior when this control receives an onkeydown\n * event for one of those keys (probably the only event the browser generates for them).\n */\n event = event || window.event;\n let keyCode = event.keyCode;\n if (keyCode === 0x08 || event.ctrlKey && keyCode >= 0x41 && keyCode <= 0x5A) {\n if (event.preventDefault) event.preventDefault();\n if (keyCode > 0x40) keyCode -= 0x40;\n if (controller.deliverInput) controller.deliverInput(keyCode);\n }\n return true;\n };\n\n control.onkeypress = function onKeyPress(event) {\n /*\n * Browser-independent keyCode extraction; refer to onKeyPress() and the other key event\n * handlers in keyboard.js.\n */\n event = event || window.event;\n let keyCode = event.which || event.keyCode;\n if (controller.deliverInput) controller.deliverInput(keyCode);\n /*\n * Since we're going to remove the \"readonly\" attribute from the <textarea> control\n * (so that the soft keyboard activates on iOS), instead of calling preventDefault() for\n * selected keys (eg, the SPACE key, whose default behavior is to scroll the page), we must\n * now call it for *all* keys, so that the keyCode isn't added to the control immediately,\n * on top of whatever the machine is echoing back, resulting in double characters.\n */\n if (event.preventDefault) event.preventDefault();\n return true;\n };\n\n /*\n * Now that we've added an onkeypress handler that calls preventDefault() for ALL keys, the control\n * itself no longer needs the \"readonly\" attribute; we primarily need to remove it for iOS browsers,\n * so that the soft keyboard will activate, but it shouldn't hurt to remove the attribute for all browsers.\n */\n control.removeAttribute(\"readonly\");\n\n if (this.sendData) {\n let monitor = new TestMonitor();\n monitor.bindController(this, this.sendData, this.sendOutput, this.printf, this.sBinding);\n }\n return true;\n }\n return false;\n }\n\n /**\n * sendOutput(data)\n *\n * @this {TestController}\n * @param {number|string|Array} data\n */\n sendOutput(data)\n {\n if (typeof data == \"number\") {\n this.printf(\"%c\", data);\n }\n else if (typeof data == \"string\") {\n this.printf(\"%s\", data);\n }\n else {\n for (let i = 0; i < data.length; i++) this.printf(\"[0x%02x]\", data[i]);\n }\n }\n\n /**\n * printf(format, ...args)\n *\n * @this {TestController}\n * @param {string} format\n * @param {...} args\n */\n printf(format, ...args)\n {\n let s = Str.sprintf(format, ...args);\n \n if (this.controlBuffer != null) {\n if (s != '\\r') {\n if (s == '\\b' || s == \"\\b \\b\") {\n this.controlBuffer.value = this.controlBuffer.value.slice(0, -1);\n } else {\n this.controlBuffer.value += s;\n }\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (!DEBUG && this.controlBuffer.value.length > 8192) {\n this.controlBuffer.value = this.controlBuffer.value.substr(this.controlBuffer.value.length - 4096);\n }\n this.controlBuffer.scrollTop = this.controlBuffer.scrollHeight;\n }\n }\n \n if (this.consoleBuffer != null) {\n let i = s.lastIndexOf('\\n');\n if (i >= 0) {\n console.log(this.consoleBuffer + s.substr(0, i));\n this.consoleBuffer = \"\";\n s = s.substr(i + 1);\n }\n this.consoleBuffer += s;\n }\n }\n\n /**\n * receiveData(data)\n *\n * @this {TestController}\n * @param {number|string|Array} data\n */\n receiveData(data)\n {\n if (typeof data == \"number\") {\n this.deliverData(data);\n }\n else if (typeof data == \"string\") {\n for (let i = 0; i < data.length; i++) this.deliverData(data.charCodeAt(i));\n }\n else {\n for (let i = 0; i < data.length; i++) this.deliverData(data[i]);\n }\n }\n \n /**\n * TestController.init()\n *\n * This function operates on every HTML element of class \"TestController\", extracting the\n * JSON-encoded parameters for the TestController constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a TestController component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n let aeTest = Component.getElementsByClass(document, PCX86.APPCLASS, \"testctl\");\n for (let iTest = 0; iTest < aeTest.length; iTest++) {\n let eTest = aeTest[iTest];\n let parms = Component.getComponentParms(eTest);\n let test = new TestController(parms);\n Component.bindComponentControls(test, eTest, PCX86.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize every TestController module on the page.\n */\nWeb.onInit(TestController.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/testmon.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Overview\n * --------\n * \n * TestMonitor monitors activity on the bound SerialPort and a user I/O device (eg, a terminal,\n * a console window, etc). It operates in several modes:\n * \n * 1) TERMINAL mode: all data received from the SerialPort is routed the user output device,\n * and all data received from the user input device is routed to the SerialPort. No special actions\n * are taken, until/unless the ATTENTION key is detected from the user input device (ie, Ctrl-T).\n * \n * 2) PROMPT mode: data from the SerialPort is monitored for specific prompts (eg, \"A>\"), and\n * when one of those prompts is detected, we enter COMMAND mode, with category set to the appropriate\n * collection of tests.\n * \n * 3) COMMAND mode: CR-terminated lines of user input are checked against the current set of test\n * commands, and if a match is found, the corresponding request is sent to the SerialPort.\n */\n\n\n/**\n * TestMonitor class\n *\n * @class TestMonitor\n * @property {string} mode\n * @property {string} promptActive\n * @property {string} promptBuffer\n * @property {Object|undefined} tests\n * @property {Object|undefined} category (eg, \"DOS\")\n * @property {string} commandBuffer\n * @property {function(...)} sendData\n * @property {function(...)} sendOutput\n * @property {function(string,...)} printf\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass TestMonitor {\n /**\n * TestMonitor()\n *\n * @this {TestMonitor}\n */\n constructor()\n {\n if (DEBUG) console.log(\"TestMonitor()\");\n /*\n * Operations are added to the following queue by addOperation(), which ensures that as soon as it\n * transitions from empty to non-empty, a timeout handler is established to begin draining the queue.\n * \n * While this approach is more complicated than simply sending operations (via sendData()) as they\n * arrive, it has at least one important advantage: special operations, such as \"wait\" (eg, wait for a\n * key to be pressed), are easier to implement, because control of the draining process can be switched\n * from a timeout handler to an appropriate event handler.\n */\n this.aOperations = [];\n this.idTimeout = 0;\n this.fnRemoveOperation = this.removeOperation.bind(this);\n this.fWaitPending = false;\n }\n\n /**\n * bindController(controller, sendData, sendOutput, printf, sBinding)\n *\n * @this {TestMonitor}\n * @param {Object} controller\n * @param {function(...)} sendData\n * @param {function(...)} sendOutput\n * @param {function(string,...)} printf\n * @param {string} [sBinding]\n */\n bindController(controller, sendData, sendOutput, printf, sBinding)\n {\n this.sendData = sendData.bind(controller);\n this.sendOutput = sendOutput.bind(controller);\n this.printf = printf.bind(controller);\n controller.bindMonitor(this, this.receiveData, this.receiveInput, this.receiveTests);\n this.printf(\"%s TestMonitor v%s\\n\", APPNAME, APPVERSION || XMLVERSION);\n this.printf(\"Use Ctrl-T to toggle terminal mode%s\\n\", (sBinding? \" (\" + sBinding.toUpperCase() + \")\" : \"\"));\n this.setMode(TestMonitor.MODE.TERMINAL);\n }\n\n /**\n * addCommand(commandLine)\n *\n * @this {TestMonitor}\n * @param {string} commandLine\n * @return {boolean} (true if successful, false if error)\n */\n addCommand(commandLine)\n {\n if (!commandLine) return true;\n \n let suite = this.tests[this.category];\n let commands = suite['commands'];\n let commandParts = commandLine.split(' ');\n let command = commandParts[0];\n \n /*\n * Check for a matching command in the current \"test suite\" category.\n */\n let fExists = false;\n if (commands[command]) {\n fExists = true;\n command = commands[command];\n }\n \n let op, mode;\n if (typeof command == \"string\") {\n op = command;\n /*\n * If you don't want any special op processing (eg, for-loop), then use an explicit 'op' property.\n */\n if (this.addForLoop(op)) return true;\n } else {\n op = command['op'];\n mode = command['mode'];\n }\n \n if (op) {\n let errorMessage = \"\";\n op = op.replace(/([$%])([0-9]+)/g, function(match, p1, p2, offset, s) {\n let i = +p2;\n let result = \"\";\n if (i >= commandParts.length) {\n result = p1 + p2;\n errorMessage = \"missing value for \" + result;\n } else if (!i) {\n result = commandLine;\n } else if (p1 == '$') {\n result = commandParts[i];\n } else { // p1 must be '%', which means convert the value to hex\n result = Str.sprintf(\"%x\", commandParts[i]);\n }\n return result;\n });\n if (errorMessage) {\n this.printf(\"%s\\n\", errorMessage);\n } else {\n let i = op.indexOf('(');\n command = (i > 0? op.substr(0, i) : \"\");\n if (TestMonitor.COMMANDS.indexOf(command) >= 0) {\n if (!fExists) op = commandLine;\n fExists = true;\n let j = op.lastIndexOf(')');\n if (j > 0) {\n mode = op.substr(i+1, j-i-1);\n op = command;\n }\n }\n else if (TestMonitor.COMMANDS.indexOf(op) >= 0) {\n fExists = true;\n mode = commandParts[1];\n }\n if (fExists) {\n if (DEBUG) console.log(\"TestMonitor.addCommand(\" + commandLine + \"): op '\" + op + \"'\");\n this.addOperation(op, mode);\n return true;\n }\n this.printf(\"unrecognized command: %s\\n\", commandLine);\n }\n } else {\n this.printf(\"missing operation for command: %s\\n\", commandParts[0]);\n }\n return false;\n }\n\n /**\n * addForLoop(commandLine)\n * \n * @this {TestMonitor}\n * @param {string} commandLine\n * @return {boolean}\n */\n addForLoop(commandLine)\n {\n let fSuccess = false;\n let match = commandLine.match(/^\\s*for\\s+([a-z]+)\\s*=\\s*([0-9]+)\\s+to\\s+([0-9]+)\\s*{\\s*([\\s\\S]*?)\\s*}\\s*$/i);\n if (match) {\n fSuccess = true;\n let symbol = match[1];\n let initial = +match[2];\n let final = +match[3];\n let commands = match[4].split(';');\n for (let value = initial; value <= final && fSuccess; value++) {\n for (let i = 0; i < commands.length; i++) {\n let commandLine = commands[i].trim();\n if (!commandLine) continue;\n commandLine = commandLine.replace(new RegExp(\"\\\\$\" + symbol, 'g'), value.toString());\n if (!this.addCommand(commandLine)) {\n fSuccess = false;\n break;\n }\n }\n }\n }\n return fSuccess;\n }\n\n /**\n * addOperation(op, mode)\n * \n * @this {TestMonitor}\n * @param {string} op\n * @param {string} [mode]\n */\n addOperation(op, mode)\n {\n this.aOperations.push(mode? [op, mode] : op);\n this.nextOperation();\n }\n\n /**\n * flushOperations()\n *\n * @this {TestMonitor}\n */\n flushOperations()\n {\n if (this.idTimeout) {\n clearTimeout(this.idTimeout);\n this.idTimeout = 0;\n }\n this.aOperations = [];\n this.fWaitPending = false;\n }\n\n /**\n * nextOperation(msDelay)\n *\n * @this {TestMonitor}\n * @param {number} [msDelay]\n * @return {boolean}\n */\n nextOperation(msDelay)\n {\n this.fWaitPending = false;\n if (this.aOperations.length) {\n if (!this.idTimeout) {\n this.idTimeout = setTimeout(this.fnRemoveOperation, msDelay || 0);\n }\n return true;\n }\n this.printf(\"done\\n\");\n return false;\n }\n \n /**\n * removeOperation()\n *\n * @this {TestMonitor}\n */\n removeOperation()\n {\n this.idTimeout = 0;\n let op = this.aOperations.shift();\n if (op) {\n let mode;\n if (typeof op != \"string\") {\n mode = op[1]; op = op[0];\n }\n if (op == TestMonitor.COMMAND.PRINTF) {\n let format = \"nothing to print\", args = [];\n if (mode) {\n let parms = mode.match(/^\\s*([\"'])([\\s\\S]*?)\\1\\s*,?\\s*([\\s\\S]*)$/);\n if (parms) {\n format = parms[2];\n args = parms[3].split(',');\n }\n }\n this.printf(format, ...args);\n }\n else if (op == TestMonitor.COMMAND.WAIT) {\n if (mode) {\n this.nextOperation(+mode);\n return;\n }\n this.printf(\"press a key to continue...\");\n this.fWaitPending = true;\n return;\n }\n else {\n this.sendData(op);\n if (mode) {\n this.flushOperations();\n this.setMode(mode);\n return;\n }\n }\n this.nextOperation();\n }\n }\n \n /**\n * setMode(mode, category)\n * \n * @this {TestMonitor}\n * @param {string} mode\n * @param {string} [category]\n */\n setMode(mode, category)\n {\n if (mode != this.mode) {\n switch (mode) {\n case TestMonitor.MODE.TERMINAL:\n this.category = null;\n break;\n\n case TestMonitor.MODE.PROMPT:\n this.aCategories = [];\n this.aPrompts = [];\n this.cchPromptLongest = 0;\n for (let category in this.tests) {\n let suite = this.tests[category];\n let prompt = suite[TestMonitor.MODE.PROMPT];\n if (prompt) {\n /*\n * The 'prompt' property is allowed to contain a string or array of strings.\n */\n if (typeof prompt == \"string\") {\n prompt = [prompt];\n }\n for (let i = 0; i < prompt.length; i++) {\n this.aCategories.push(category);\n this.aPrompts.push(prompt[i]);\n if (this.cchPromptLongest < prompt[i].length) {\n this.cchPromptLongest = prompt[i].length;\n }\n }\n }\n }\n this.promptActive = this.promptBuffer = \"\";\n this.category = null;\n break;\n\n case TestMonitor.MODE.COMMAND:\n if (category) this.category = category;\n this.commandBuffer = \"\";\n break;\n\n default:\n this.printf(\"unrecognized mode: %s\\n\", mode);\n return;\n }\n\n this.mode = mode;\n this.printf(\"mode: %s\\n\", this.category || this.mode);\n }\n }\n \n /**\n * receiveTests(tests)\n *\n * @this {TestMonitor}\n * @param {Object} tests\n */\n receiveTests(tests)\n {\n if (DEBUG) console.log(\"TestMonitor.receiveTests(\" + JSON.stringify(tests) + \")\");\n this.tests = tests;\n this.setMode(TestMonitor.MODE.PROMPT);\n }\n\n /**\n * receiveData(data)\n *\n * @this {TestMonitor}\n * @param {number} data\n */\n receiveData(data)\n {\n if (this.mode == TestMonitor.MODE.PROMPT) {\n if (this.promptBuffer.length >= this.cchPromptLongest) {\n this.promptBuffer = this.promptBuffer.slice(-(this.cchPromptLongest - 1));\n }\n if (data == 10) this.promptBuffer = \"\";\n this.promptBuffer += String.fromCharCode(data);\n if (DEBUG) console.log(\"TestMonitor.receiveData(\" + data + \"): checking prompts for '\" + this.promptBuffer + \"'\");\n let i = this.aPrompts.indexOf(this.promptBuffer);\n if (i >= 0) {\n this.setMode(TestMonitor.MODE.COMMAND, this.aCategories[i]);\n }\n } else if (this.mode == TestMonitor.MODE.TERMINAL) {\n this.sendOutput(data);\n } else {\n /*\n * TODO: This is where we need to collect the response to any commands we have issued.\n */\n // this.sendOutput(data);\n if (DEBUG) console.log(\"TestMonitor.receiveData(\" + data + \"): ignored while mode is '\" + this.mode + \"'\");\n }\n }\n\n /**\n * receiveInput(charCode)\n *\n * @this {TestMonitor}\n * @param {number} charCode\n */\n receiveInput(charCode)\n {\n if (DEBUG) console.log(\"TestMonitor.receiveInput(\" + charCode + \")\");\n if (charCode == Keys.ASCII.CTRL_T) {\n this.setMode(this.mode == TestMonitor.MODE.TERMINAL? (this.category? TestMonitor.MODE.COMMAND : TestMonitor.MODE.PROMPT) : TestMonitor.MODE.TERMINAL);\n return;\n }\n if (this.mode == TestMonitor.MODE.TERMINAL || this.mode == TestMonitor.MODE.PROMPT) {\n this.sendData(charCode);\n } else if (this.mode == TestMonitor.MODE.COMMAND) {\n if (this.fWaitPending) {\n this.sendOutput(Keys.KEYCODE.LF);\n this.nextOperation();\n return;\n }\n if (charCode == Keys.KEYCODE.CR) {\n this.sendOutput(Keys.KEYCODE.LF);\n this.flushOperations();\n this.addCommand(this.commandBuffer.replace(/\\\\n/g, \"\\n\"));\n this.commandBuffer = \"\";\n } else {\n if (charCode == Keys.ASCII.CTRL_H || charCode == Keys.ASCII.DEL) {\n if (this.commandBuffer.length) {\n this.commandBuffer = this.commandBuffer.slice(0, -1);\n this.sendOutput(\"\\b \\b\");\n }\n } else if (charCode >= 32 && charCode < 127) {\n this.commandBuffer += String.fromCharCode(charCode);\n this.sendOutput(charCode);\n }\n }\n }\n }\n}\n\nTestMonitor.MODE = {\n TERMINAL: \"terminal\",\n PROMPT: \"prompt\",\n COMMAND: \"command\"\n};\n\nTestMonitor.COMMAND = {\n PRINTF: \"printf\",\n WAIT: \"wait\"\n};\n\nTestMonitor.COMMANDS = [\n TestMonitor.COMMAND.PRINTF,\n TestMonitor.COMMAND.WAIT\n];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/mouse.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * class Mouse\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass Mouse extends Component {\n /**\n * Mouse(parmsMouse)\n *\n * The Mouse component has the following component-specific (parmsMouse) properties:\n *\n * adapter: 1 (primary) or 2 (secondary); 0 if not defined\n *\n * binding: name of a corresponding device component (implies type=\"serial\")\n *\n * scaleMouse: a floating-point number used to scale incoming mouse coordinates; the default is 0.5\n *\n * serial: the ID of a corresponding serial component (used in lieu of type=\"serial\" and binding=\"ID\")\n *\n * type: one of \"bus\", \"inport\", or \"serial\"; the default is \"serial\" if serial or binding properties are set\n *\n * The first version of this component supported ONLY emulation of the original Microsoft serial mouse,\n * so a valid SerialPort component ID using the 'serial' property was required. Now, using the 'type' property,\n * it's possible to enable support for other types of mouse hardware (eg, 'bus' for the original Microsoft\n * Bus Mouse interface or 'inport' for the Microsoft InPort Mouse interface). The 'adapter' property is used\n * only when the selected type supports different configurations (eg, primary vs. secondary InPort adapters).\n *\n * If the 'type' property is set to \"serial\" (or 'type' is not set and either the original 'serial' property\n * or the new 'binding' property is set), then serial communication will be established with the specified\n * SerialPort component, requesting access to the corresponding serial component ID. If the SerialPort component\n * is not installed and/or the specified serial component ID is not present, a configuration error will be reported.\n *\n * To recap, the following machine XML syntax is still supported:\n *\n * <mouse serial=\"com2\"/>\n *\n * but going forward, you should stop using the serial attribute and use syntax like this instead:\n *\n * <mouse type=\"serial\" binding=\"com2\"/>\n *\n * @this {Mouse}\n * @param {Object} parmsMouse\n */\n constructor(parmsMouse)\n {\n super(\"Mouse\", parmsMouse, Messages.MOUSE);\n\n this.iAdapter = parmsMouse['adapter'] || 0;\n this.idDevice = parmsMouse['serial'] || parmsMouse['binding'];\n this.sType = parmsMouse['type'] || (this.idDevice? Mouse.TYPE.SERIAL : Mouse.TYPE.BUS);\n this.typeDevice = (this.sType == Mouse.TYPE.SERIAL? \"SerialPort\" : null);\n this.componentDevice = null;\n\n this.scale = parmsMouse['scaleMouse'];\n this.setActive(false);\n this.fActive = this.fCaptured = this.fLocked = false;\n\n /*\n * Initially, no video devices, and therefore no screens, are attached. initBus() will update aVideo,\n * and powerUp() will update aScreens.\n */\n this.aVideo = [];\n this.aScreens = [];\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {Mouse}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.scale = cmp.getMachineParm('scaleMouse') || this.scale;\n /*\n * Enumerate all the Video components that we may need to interact with.\n */\n for (var video = null; (video = cmp.getMachineComponent(\"Video\", video));) {\n this.aVideo.push(video);\n }\n if (this.sType == Mouse.TYPE.BUS) {\n bus.addPortInputTable(this, Mouse.aBusInput, Mouse.BUS.DATA.PORT);\n bus.addPortOutputTable(this, Mouse.aBusOutput, Mouse.BUS.DATA.PORT);\n }\n this.setReady();\n }\n\n /**\n * isActive()\n *\n * @this {Mouse}\n * @return {boolean} true if active, false if not\n */\n isActive()\n {\n return this.fActive && (this.cpu? this.cpu.isRunning() : false);\n }\n\n /**\n * setActive(fActive)\n *\n * @this {Mouse}\n * @param {boolean} fActive is true if active, false if not\n */\n setActive(fActive)\n {\n this.fActive = fActive;\n /*\n * It's currently not possible to automatically lock the pointer outside the context of a user action\n * (eg, a button or screen click), so this code is for naught.\n *\n * if (this.aVideo.length) this.aVideo[0].notifyPointerActive(fActive);\n *\n * We now rely on similar code in clickMouse().\n */\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {Mouse}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data || !this.restore) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n if (this.typeDevice && !this.componentDevice) {\n var componentDevice = null;\n while ((componentDevice = this.cmp.getMachineComponent(this.typeDevice, componentDevice))) {\n if (componentDevice.bindMouse) {\n this.componentDevice = componentDevice.bindMouse(this.idDevice, this, this.receiveStatus);\n if (this.componentDevice) {\n /*\n * It's possible that the SerialPort we've just attached to might want to bring us \"up to speed\"\n * on the device's state, which is why I envisioned a subsequent syncMouse() call. And you would\n * want to do that as a separate call, not as part of bindMouse(), because componentDevice\n * isn't set until bindMouse() returns.\n *\n * However, syncMouse() seems unnecessary, given that SerialPort initializes its MCR to an \"inactive\"\n * state, and even when restoring a previous state, if we've done our job properly, both SerialPort\n * and Mouse should be restored in sync, making any explicit attempt at sync'ing unnecessary (or so I hope).\n *\n * this.componentDevice.syncMouse();\n */\n break;\n }\n }\n }\n if (this.componentDevice) {\n this.aScreens = []; // ensure the screen array is empty before (re)filling it\n for (var i = 0; i < this.aVideo.length; i++) {\n var screen = this.aVideo[i].getScreen(this);\n if (screen) this.aScreens.push(screen);\n }\n } else {\n Component.warning(this.id + \": \" + this.typeDevice + \" \" + this.idDevice + \" unavailable\");\n }\n }\n if (this.fActive) {\n this.captureAll();\n } else {\n this.releaseAll();\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Mouse}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {Mouse}\n */\n reset()\n {\n this.initState();\n }\n\n /**\n * save()\n *\n * This implements save support for the Mouse component.\n *\n * @this {Mouse}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveState());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the Mouse component.\n *\n * @this {Mouse}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return this.initState(data[0]);\n }\n\n /**\n * initState(data)\n *\n * @this {Mouse}\n * @param {Array} [data]\n * @return {boolean} true if successful, false if failure\n */\n initState(data)\n {\n var i = 0;\n if (data === undefined) data = [false, -1, -1, 0, 0, false, false, 0];\n this.setActive(data[i++]);\n this.xMouse = data[i++];\n this.yMouse = data[i++];\n this.xDelta = data[i++];\n this.yDelta = data[i++];\n this.fButton1 = data[i++]; // FYI, we consider button1 to be the LEFT button\n this.fButton2 = data[i++]; // FYI, we consider button2 to be the RIGHT button\n this.pins = data[i];\n /*\n * Convert old UART \"MCR\" data to new RS-232 \"pins\" data, in case we're loading an old state;\n * detection and conversion relies on the fact that the MCR bits don't overlap with any RS-232 bits.\n */\n if (this.pins & (SerialPort.MCR.DTR | SerialPort.MCR.RTS)) {\n this.pins = ((this.pins & SerialPort.MCR.DTR)? RS232.DTR.MASK : 0) | ((this.pins & SerialPort.MCR.RTS)? RS232.RTS.MASK : 0);\n }\n return true;\n }\n\n /**\n * saveState()\n *\n * @this {Mouse}\n * @return {Array}\n */\n saveState()\n {\n var i = 0;\n var data = [];\n data[i++] = this.fActive;\n data[i++] = this.xMouse;\n data[i++] = this.yMouse;\n data[i++] = this.xDelta;\n data[i++] = this.yDelta;\n data[i++] = this.fButton1;\n data[i++] = this.fButton2;\n data[i] = this.pins;\n return data;\n }\n\n /**\n * notifyPointerLocked()\n *\n * @this {Mouse}\n * @param {boolean} fLocked\n */\n notifyPointerLocked(fLocked)\n {\n this.fLocked = fLocked;\n }\n\n /**\n * captureAll()\n *\n * @this {Mouse}\n */\n captureAll()\n {\n if (!this.fCaptured) {\n for (var i = 0; i < this.aScreens.length; i++) {\n if (this.captureMouse(this.aScreens[i])) this.fCaptured = true;\n }\n }\n }\n\n /**\n * releaseAll()\n *\n * @this {Mouse}\n */\n releaseAll()\n {\n if (this.fCaptured) {\n for (var i = 0; i < this.aScreens.length; i++) {\n if (this.releaseMouse(this.aScreens[i])) this.fCaptured = false;\n }\n }\n }\n\n /**\n * captureMouse(control)\n *\n * NOTE: addEventListener() wasn't supported in Internet Explorer until IE9, but that's OK, because\n * IE9 is the oldest IE we support anyway (since versions prior to IE9 lack the necessary HTML5 support).\n *\n * @this {Mouse}\n * @param {HTMLElement} control from the HTML DOM (eg, the control for the simulated screen)\n * @return {boolean} true if event handlers were actually added, false if not\n */\n captureMouse(control)\n {\n if (control) {\n var mouse = this;\n control.addEventListener(\n 'mousemove',\n function onMouseMove(event) {\n mouse.processMouseEvent(event);\n },\n false // we'll specify false for the 'useCapture' parameter for now...\n );\n control.addEventListener(\n 'mousedown',\n function onMouseDown(event) {\n mouse.processMouseEvent(event, true);\n },\n false // we'll specify false for the 'useCapture' parameter for now...\n );\n control.addEventListener(\n 'mouseup',\n function onMouseUp(event) {\n mouse.processMouseEvent(event, false);\n },\n false // we'll specify false for the 'useCapture' parameter for now...\n );\n /*\n * None of these tricks seemed to work for IE10, so I'm giving up hiding the browser's mouse pointer in IE for now.\n *\n * control['style']['cursor'] = \"url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjbQg61aAAAADUlEQVQYV2P4//8/IwAI/QL/+TZZdwAAAABJRU5ErkJggg=='), url('/versions/images/current/blank.cur'), none\";\n *\n * Setting the cursor style to \"none\" may not be a standard, but it works in Safari, Firefox and Chrome, so that's pretty\n * good for a non-standard!\n *\n * TODO: The reference to '/versions/images/current/blank.cur' is also problematic for anyone who might want\n * to run this app from a different server, so think about that as well.\n */\n control['style']['cursor'] = \"none\";\n return true;\n }\n return false;\n }\n\n /**\n * releaseMouse(control)\n *\n * TODO: Use removeEventListener() to clean up our handlers; since I'm currently using anonymous functions,\n * and since I'm not seeing any compelling reason to remove the handlers once they've been established, it's\n * less code to leave them in place.\n *\n * @this {Mouse}\n * @param {HTMLElement} control from the HTML DOM\n * @return {boolean} true if event handlers were actually released, false if not\n */\n releaseMouse(control)\n {\n if (control) {\n control['style']['cursor'] = \"auto\";\n }\n return false;\n }\n\n /**\n * processMouseEvent(event, fDown)\n *\n * @this {Mouse}\n * @param {Object} event object from a 'mousemove', 'mousedown' or 'mouseup' event (ie, a MouseEvent object)\n * @param {boolean} [fDown] (undefined if neither a down nor up event)\n */\n processMouseEvent(event, fDown)\n {\n if (fDown !== undefined) {\n if (this.fLocked === false) {\n /*\n * If there's no support for automatic pointer locking in the Video component, notifyPointerActive()\n * will return false, and we will set fLocked to null, ensuring that we never attempt this again.\n */\n if (!this.aVideo.length || !this.aVideo[0].notifyPointerActive(true)) {\n this.fLocked = null;\n }\n }\n this.clickMouse(event.button, fDown);\n } else {\n /*\n * All we really care about are deltas. We record screenX and screenY (as xMouse and yMouse)\n * merely to calculate xDelta and yDelta.\n */\n var xDelta, yDelta;\n if (this.xMouse < 0 || this.yMouse < 0) {\n this.xMouse = event.screenX;\n this.yMouse = event.screenY;\n }\n if (this.fLocked) {\n xDelta = event['movementX'] || event['mozMovementX'] || event['webkitMovementX'] || 0;\n yDelta = event['movementY'] || event['mozMovementY'] || event['webkitMovementY'] || 0;\n } else {\n xDelta = event.screenX - this.xMouse;\n yDelta = event.screenY - this.yMouse;\n }\n this.xMouse = event.screenX;\n this.yMouse = event.screenY;\n this.moveMouse(xDelta, yDelta, this.xMouse, this.yMouse);\n }\n }\n\n /**\n * clickMouse(iButton, fDown)\n *\n * @this {Mouse}\n * @param {number} iButton is Mouse.BUTTON.LEFT (0) for fButton1, Mouse.BUTTON.RIGHT (2) for fButton2\n * @param {boolean} fDown\n */\n clickMouse(iButton, fDown)\n {\n if (this.isActive()) {\n var sDiag = DEBUGGER? (\"mouse button\" + iButton + ' ' + (fDown? \"dn\" : \"up\")) : null;\n switch (iButton) {\n case Mouse.BUTTON.LEFT:\n if (this.fButton1 != fDown) {\n this.fButton1 = fDown;\n this.sendPacket(sDiag);\n return;\n }\n break;\n case Mouse.BUTTON.RIGHT:\n if (this.fButton2 != fDown) {\n this.fButton2 = fDown;\n this.sendPacket(sDiag);\n return;\n }\n break;\n default:\n break;\n }\n this.printMessage(sDiag + \": ignored\");\n }\n }\n\n /**\n * moveMouse(xDelta, yDelta, xDiag, yDiag)\n *\n * @this {Mouse}\n * @param {number} xDelta\n * @param {number} yDelta\n * @param {number} [xDiag]\n * @param {number} [yDiag]\n */\n moveMouse(xDelta, yDelta, xDiag, yDiag)\n {\n if (this.isActive()) {\n /*\n * I would prefer to simply say \"Math.round(xDelta * this.scale)\", but JavaScript's round() function\n * rounds negative numbers toward +infinity if the fraction is exactly 0.5. All positive numbers are\n * rounded correctly, so we convert the value to positive and restore its sign afterward. Additionally,\n * if the scaling factor turns a non-zero value into zero, we restore the value to its smallest legal\n * non-zero value (thanks to Math.sign() again). This ensures that tiniest movement of the physical\n * mouse always results in at least the tiniest movement of the virtual mouse.\n */\n var xScaled = (Math.round(Math.abs(xDelta) * this.scale) * Math.sign(xDelta)) || Math.sign(xDelta);\n var yScaled = (Math.round(Math.abs(yDelta) * this.scale) * Math.sign(yDelta)) || Math.sign(yDelta);\n if (xScaled || yScaled) {\n if (this.messageEnabled(Messages.MOUSE)) {\n this.printMessage(\"moveMouse(\" + xScaled + \",\" + yScaled + \")\");\n }\n /*\n * As sendPacket() indicates, any x and y coordinates we supply are for diagnostic purposes only.\n * sendPacket() only cares about the xDelta and yDelta properties we provide above, which it then zeroes\n * on completion.\n */\n this.xDelta = xScaled;\n this.yDelta = yScaled;\n this.sendPacket(null, xDiag, yDiag);\n }\n }\n }\n\n /**\n * sendPacket(sDiag, xDiag, yDiag)\n *\n * If we're called, something changed.\n *\n * Let's review the 3-byte packet format:\n *\n * D7 D6 D5 D4 D3 D2 D1 D0\n * Byte 1 X 1 LB RB Y7 Y6 X7 X6\n * Byte 2 X 0 X5 X4 X3 X2 X1 X0\n * Byte 3 X 0 Y5 Y4 Y3 Y2 Y1 Y0\n *\n * @this {Mouse}\n * @param {string|null} [sDiag] diagnostic message\n * @param {number} [xDiag] original x-coordinate (optional; for diagnostic use only)\n * @param {number} [yDiag] original y-coordinate (optional; for diagnostic use only)\n */\n sendPacket(sDiag, xDiag, yDiag)\n {\n var b1 = 0x40 | (this.fButton1? 0x20 : 0) | (this.fButton2? 0x10 : 0) | ((this.yDelta & 0xC0) >> 4) | ((this.xDelta & 0xC0) >> 6);\n var b2 = this.xDelta & 0x3F;\n var b3 = this.yDelta & 0x3F;\n if (this.messageEnabled(Messages.SERIAL)) {\n this.printMessage((sDiag? (sDiag + \": \") : \"\") + (yDiag !== undefined? (\"mouse (\" + xDiag + \",\" + yDiag + \"): \") : \"\") + \"serial packet [\" + Str.toHexByte(b1) + \",\" + Str.toHexByte(b2) + \",\" + Str.toHexByte(b3) + \"]\", 0, true);\n }\n this.componentDevice.receiveData([b1, b2, b3]);\n this.xDelta = this.yDelta = 0;\n }\n\n /**\n * receiveStatus(pins)\n *\n * The SerialPort notifies us whenever SerialPort.MCR.DTR or SerialPort.MCR.RTS changes.\n *\n * During normal serial mouse operation, both RTS and DTR must be \"positive\".\n *\n * Setting RTS \"negative\" for 100ms resets the mouse. Toggling DTR requests an identification byte (SERIAL.ID).\n *\n * NOTES: The above 3rd-party information notwithstanding, I've observed that Windows v1.01 initially writes 0x01\n * to the MCR (DTR on, RTS off), spins in a loop that reads the RBR (probably to avoid a bogus identification byte\n * sitting in the RBR), and then writes 0x0B to the MCR (DTR on, RTS on). This last step is consistent with making\n * the mouse \"active\", but it is NOT consistent with \"toggling DTR\", so I conclude that a reset is ALSO sufficient\n * for sending the identification byte. Right or wrong, this gets the ball rolling for Windows v1.01.\n *\n * @this {Mouse}\n * @param {number} pins\n */\n receiveStatus(pins)\n {\n var fActive = ((pins & (RS232.DTR.MASK | RS232.RTS.MASK)) == (RS232.DTR.MASK | RS232.RTS.MASK));\n if (fActive) {\n if (!this.fActive) {\n var fIdentify = false;\n if (!(this.pins & RS232.RTS.MASK)) {\n this.reset();\n this.printMessage(\"serial mouse reset\");\n fIdentify = true;\n }\n if (!(this.pins & RS232.DTR.MASK)) {\n this.printMessage(\"serial mouse ID requested\");\n fIdentify = true;\n }\n if (fIdentify) {\n /*\n * HEADS UP: Everything I'd read about the (original) Microsoft Serial Mouse \"reset\" protocol says\n * that the device sends a single byte (0x4D aka 'M'). It's not surprising to think that newer mice\n * might send additional bytes, but you would think that newer mouse drivers (eg, MOUSE.COM v8.20)\n * would always be able to deal with mice that sent only one byte.\n *\n * You would be wrong. On an INT 0x33 reset, the v8.20 driver looks for an 'M', then it waits for\n * another byte (0x42 aka 'B'). If it doesn't receive a 'B', it will accept another 'M'. But if it\n * receives something else (or nothing at all), it will spend a long time waiting for it, and then\n * return an error.\n *\n * It's entirely possible that I've done something wrong and inadvertently \"tricked\" MOUSE.COM into\n * using the wrong detection logic. But given the other problems I've seen in MOUSE.COM v8.20, including\n * its failure to properly terminate-and-stay-resident when its initial INT 0x33 reset returns an error,\n * I'm not in the mood to give it the benefit of the doubt.\n *\n * So, anyway, I solve the terminate-and-stay-resident bug in MOUSE.COM v8.20 by feeding it *two* SERIAL.ID\n * bytes on a reset. This doesn't seem to adversely affect serial mouse emulation for Windows 1.01, so\n * I'm calling this good enough for now.\n */\n this.componentDevice.receiveData([Mouse.SERIAL.ID, Mouse.SERIAL.ID]);\n this.printMessage(\"serial mouse ID sent\");\n }\n this.captureAll();\n this.setActive(fActive);\n }\n } else {\n if (this.fActive) {\n /*\n * Although this would seem nice (ie, for the Windows v1.01 mouse driver to turn RTS off when its mouse\n * driver shuts down and Windows exits, since it DID turn RTS on), that doesn't appear to actually happen.\n * At the very least, Windows will have (re)masked the serial port's IRQ, so what does it matter? Not much,\n * I just would have preferred that fActive properly reflect whether we should continue dispatching mouse\n * events, displaying MOUSE messages, etc.\n *\n * We could ask the ChipSet component to notify the SerialPort component whenever its IRQ is masked/unmasked,\n * and then have the SerialPort pass that notification on to us, but I'm assuming that in the real world,\n * a mouse device that's still powered may still send event data to the serial port, and if there was software\n * polling the serial port, it might expect to see that data. Unlikely, but not impossible.\n */\n this.printMessage(\"serial mouse inactive\");\n this.releaseAll();\n this.setActive(fActive);\n }\n }\n this.pins = pins;\n }\n\n /**\n * inBusData(port, addrFrom)\n *\n * @this {Mouse}\n * @param {number} port (eg, 0x23C)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inBusData(port, addrFrom)\n {\n var b = 0;\n this.printMessageIO(port, null, addrFrom, \"DATA\", b);\n return b;\n }\n\n /**\n * inBusTPPI(port, addrFrom)\n *\n * @this {Mouse}\n * @param {number} port (eg, 0x23D)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inBusTPPI(port, addrFrom)\n {\n var b = 0;\n this.printMessageIO(port, null, addrFrom, \"TPPI\", b);\n return b;\n }\n\n /**\n * inBusCtrl(port, addrFrom)\n *\n * @this {Mouse}\n * @param {number} port (eg, 0x23E)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inBusCtrl(port, addrFrom)\n {\n var b = 0;\n this.printMessageIO(port, null, addrFrom, \"CTRL\", b);\n return b;\n }\n\n /**\n * inBusCPPI(port, addrFrom)\n *\n * @this {Mouse}\n * @param {number} port (eg, 0x23F)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inBusCPPI(port, addrFrom)\n {\n var b = 0;\n this.printMessageIO(port, null, addrFrom, \"CPPI\", b);\n return b;\n }\n\n /**\n * outBusData(port, bOut, addrFrom)\n *\n * @this {Mouse}\n * @param {number} port (eg, 0x23C)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outBusData(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"DATA\");\n }\n\n /**\n * outBusTPPI(port, bOut, addrFrom)\n *\n * @this {Mouse}\n * @param {number} port (eg, 0x23D)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outBusTPPI(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"TPPI\");\n }\n\n /**\n * outBusCtrl(port, bOut, addrFrom)\n *\n * @this {Mouse}\n * @param {number} port (eg, 0x23E)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outBusCtrl(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"CTRL\");\n }\n\n /**\n * outBusCPPI(port, bOut, addrFrom)\n *\n * @this {Mouse}\n * @param {number} port (eg, 0x23F)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outBusCPPI(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"CPPI\");\n }\n\n /**\n * Mouse.init()\n *\n * This function operates on every HTML element of class \"mouse\", extracting the\n * JSON-encoded parameters for the Mouse constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Mouse component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeMouse = Component.getElementsByClass(document, PCX86.APPCLASS, \"mouse\");\n for (var iMouse = 0; iMouse < aeMouse.length; iMouse++) {\n var eMouse = aeMouse[iMouse];\n var parmsMouse = Component.getComponentParms(eMouse);\n var mouse = new Mouse(parmsMouse);\n Component.bindComponentControls(mouse, eMouse, PCX86.APPCLASS);\n }\n }\n}\n\nMouse.TYPE = {\n BUS: \"bus\",\n INPORT: \"inport\",\n SERIAL: \"serial\"\n};\n\nMouse.BUTTON = {\n LEFT: 0,\n RIGHT: 2\n};\n\n/*\n * The Microsoft Bus Mouse supported only one base address: 0x23C.\n *\n * NOTE: Windows v1.01 probes ports 0x23D and 0x23F immediately prior to probing COM2 (and then COM1)\n * for a serial mouse.\n */\nMouse.BUS = {\n DATA: { // Mouse Data Register\n PORT: 0x23C\n },\n TPPI: { // 8255 (PPI) Test Register\n PORT: 0x23D\n },\n CTRL: { // Mouse Control Register\n PORT: 0x23E\n },\n CPPI: { // 8255 (PPI) Control Register\n PORT: 0x23F\n }\n};\n\nMouse.aBusInput = {\n 0x0: Mouse.prototype.inBusData,\n 0x1: Mouse.prototype.inBusTPPI,\n 0x2: Mouse.prototype.inBusCtrl,\n 0x3: Mouse.prototype.inBusCPPI\n};\n\nMouse.aBusOutput = {\n 0x0: Mouse.prototype.outBusData,\n 0x1: Mouse.prototype.outBusTPPI,\n 0x2: Mouse.prototype.outBusCtrl,\n 0x3: Mouse.prototype.outBusCPPI\n};\n\n/*\n * The retail Microsoft InPort card supported two base addresses, 0x23C and 0x238, through the primary and\n * secondary jumpers, respectively. However, OEMs may have had InPorts on other base addresses.\n *\n * Here's a typical InPort Mouse detection sequence:\n *\n * S = IN(Mouse.INPORT.ID.PORT)\n * ...\n * VERIFY THAT S EQUALS Mouse.INPORT.ID.CHIP\n * T = IN(Mouse.INPORT.ID.PORT)\n * ...\n * VERIFY ADDITIONAL PAIRS OF READS RETURN MATCHING S AND T VALUES\n *\n * Here's a typical InPort Mouse interrupt sequence:\n *\n * OUT(Mouse.INPORT.ADDR.PORT, Mouse.INPORT.ADDR.MODE)\n * OUT(Mouse.INPORT.DATA.PORT, IN(Mouse.INPORT.DATA.PORT) | Mouse.INPORT.DATA.MODE.HOLD)\n * ...\n * OUT(Mouse.INPORT.ADDR.PORT, Mouse.INPORT.ADDR.X)\n * X = IN(Mouse.INPORT.DATA.PORT)\n * OUT(Mouse.INPORT.ADDR.PORT, Mouse.INPORT.ADDR.Y)\n * Y = IN(Mouse.INPORT.DATA.PORT)\n * OUT(Mouse.INPORT.ADDR.PORT, Mouse.INPORT.ADDR.STATUS)\n * B = IN(Mouse.INPORT.DATA.PORT) & (Mouse.INPORT.DATA.STATUS.B1 | Mouse.INPORT.DATA.STATUS.B2 | Mouse.INPORT.DATA.STATUS.B3)\n * ...\n * OUT(Mouse.INPORT.ADDR.PORT, Mouse.INPORT.ADDR.MODE)\n * OUT(Mouse.INPORT.DATA.PORT, IN(Mouse.INPORT.DATA.PORT) & ~Mouse.INPORT.DATA.MODE.HOLD)\n */\nMouse.INPORT = {\n ADDR: {\n PORT: 0x23C,\n STATUS: 0x00, // InPort Status Register\n X: 0x01, // InPort X Movement Register\n Y: 0x02, // InPort Y Movement Register\n ISTAT: 0x05, // InPort Interface Status Register\n ICTRL: 0x06, // InPort Interface Control Register\n MODE: 0x07 // InPort Mode Register\n },\n DATA: {\n /*\n * The internal register read or written via this port is determined by the value written to ADDR.PORT\n */\n PORT: 0x23D,\n STATUS: { // InPort Status Register (0)\n B3: 0x01, // Status button 3\n B2: 0x02, // Status button 2\n B1: 0x04, // Status button 1\n DB3: 0x08, // Delta button 3\n DB2: 0x10, // Delta button 2\n DB1: 0x20, // Delta button 1\n MOVE: 0x40, // Movement\n PACKET: 0x80 // Packet complete\n },\n MODE: { // InPort Mode Register (7)\n HOLD: 0x20 // hold the status for reading\n }\n },\n ID: {\n /*\n * The initial read returns the Chip ID; alternate reads return a byte containing the InPort revision number\n * in the low nibble and the InPort version number in the high nibble.\n */\n PORT: 0x23E,\n CHIP: 0xDE // InPort Chip ID\n },\n TEST: {\n PORT: 0x23F\n }\n};\n\n/*\n * From http://paulbourke.net/dataformats/serialmouse:\n *\n * The old MicroSoft serial mouse, while no longer in general use, can be employed to provide a low cost input device,\n * for example, coupling the internal mechanism to other moving objects. The serial protocol for the mouse is:\n *\n * 1200 baud, 7 bit, 1 stop bit, no parity.\n *\n * The pinout of the connector follows the standard serial interface, as shown below:\n *\n * Pin Abbr Description\n * 1 DCD Data Carrier Detect\n * 2 RD Receive Data [serial data from mouse to host]\n * 3 TD Transmit Data\n * 4 DTR Data Terminal Ready [used to provide positive voltage to mouse, plus reset/detection]\n * 5 SG Signal Ground\n * 6 DSR Data Set Ready\n * 7 RTS Request To Send [used to provide positive voltage to mouse]\n * 8 CTS Clear To Send\n * 9 RI Ring\n *\n * Every time the mouse changes state (moved or button pressed) a three byte \"packet\" is sent to the serial interface.\n * For reasons known only to the engineers, the data is arranged as follows, most notably the two high order bits for the\n * x and y coordinates share the first byte with the button status.\n *\n * D6 D5 D4 D3 D2 D1 D0\n * 1st byte 1 LB RB Y7 Y6 X7 X6\n * 2nd byte 0 X5 X4 X3 X2 X1 X0\n * 3rd byte 0 Y5 Y4 Y3 Y2 Y1 Y0\n *\n * where:\n *\n * LB is the state of the left button, 1 = pressed, 0 = released.\n * RB is the state of the right button, 1 = pressed, 0 = released\n * X0-7 is movement of the mouse in the X direction since the last packet. Positive movement is toward the right.\n * Y0-7 is movement of the mouse in the Y direction since the last packet. Positive movement is back, toward the user.\n *\n * From http://www.kryslix.com/nsfaq/Q.12.html:\n *\n * The Microsoft serial mouse is the most popular 2-button mouse. It is supported by all major operating systems.\n * The maximum tracking rate for a Microsoft mouse is 40 reports/second * 127 counts per report, in other words, 5080 counts\n * per second. The most common range for mice is is 100 to 400 CPI (counts per inch) but can be up to 1000 CPI. A 100 CPI mouse\n * can discriminate motion up to 50.8 inches/second while a 400 CPI mouse can only discriminate motion up to 12.7 inches/second.\n *\n * 9-pin 25-pin Line Comments\n * shell 1 GND\n * 3 2 TD Serial data from host to mouse (only for power)\n * 2 3 RD Serial data from mouse to host\n * 7 4 RTS Positive voltage to mouse\n * 8 5 CTS\n * 6 6 DSR\n * 5 7 SGND\n * 4 20 DTR Positive voltage to mouse and reset/detection\n *\n * To function correctly, both the RTS and DTR lines must be positive. DTR/DSR and RTS/CTS must NOT be shorted.\n * RTS may be toggled negative for at least 100ms to reset the mouse. (After a cold boot, the RTS line is usually negative.\n * This provides an automatic toggle when RTS is brought positive). When DTR is toggled the mouse should send a single byte\n * (0x4D, ASCII 'M').\n *\n * Serial data parameters: 1200bps, 7 data bits, 1 stop bit\n *\n * Data is sent in 3 byte packets for each event (a button is pressed or released, or the mouse moves):\n *\n * D7 D6 D5 D4 D3 D2 D1 D0\n * Byte 1 X 1 LB RB Y7 Y6 X7 X6\n * Byte 2 X 0 X5 X4 X3 X2 X1 X0\n * Byte 3 X 0 Y5 Y4 Y3 Y2 Y1 Y0\n *\n * LB is the state of the left button (1 means down).\n * RB is the state of the right button (1 means down).\n * X7-X0 movement in X direction since last packet (signed byte).\n * Y7-Y0 movement in Y direction since last packet (signed byte).\n * The high order bit of each byte (D7) is ignored. Bit D6 indicates the start of an event, which allows the software to\n * synchronize with the mouse.\n */\nMouse.SERIAL = {\n ID: 0x4D\n};\n\n/*\n * Initialize every Mouse module on the page.\n */\nWeb.onInit(Mouse.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/disk.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * The Disk component provides methods for:\n *\n * 1) creating an empty disk: create()\n * 2) loading a disk image: load()\n * 3) getting disk information: info()\n * 4) seeking a disk sector: seek()\n * 5) reading data from a sector: read()\n * 6) writing data to a sector: write()\n * 7) save disk deltas: save()\n * 8) restore disk deltas: restore()\n * 9) converting disk contents: convertToJSON()\n *\n * More functionality may be factored out of the FDC and HDC components later and moved here, to\n * further reduce some of the duplication between them, but the above functionality is a good start.\n */\n\n/*\n * Client/Server Disk I/O\n *\n * To support large disks without consuming large amounts of client-side memory, and to push\n * client-side disk changes back the server, we need a DiskIO API that can be used in place of\n * the DiskDump API.\n *\n * Use of the DiskIO API and any associated disk images must be tightly coupled to per-user\n * storage and specific machine configurations, to prevent the disk images from being corrupted\n * by inconsistent I/O operations. Our basic User API (userapi.js) already provides some\n * per-user storage that we can use to get the design rolling.\n *\n * The DiskIO API must also provide the ability to create new (empty) hard disk images in per-user\n * storage and automatically associate them with the machine configurations that requested them.\n */\n\n/*\n * Principles\n *\n * Originally, when the Disk class was given a disk image to load and mount, it would request the\n * ENTIRE disk image from the DiskDump module. That works well for small (floppy) disk images, but\n * for larger disks -- let's just say anything stored on the server as an \"img\" file -- we'd prefer\n * to interact with that disk using \"On-Demand I/O\". Any \"img\" file on the same server as the PCjs\n * application should be a candidate for on-demand access.\n *\n * On-Demand I/O means that nothing is initially transferred from the server. As sectors are\n * requested by the PCx86 machine, PCx86 requests them from the server, and maintains an MRU cache\n * of sectors, periodically discarding the least-used clean sectors above a certain memory limit.\n * Dirty sectors (ie, those that the PCx86 machine has written to) must be periodically sent\n * back to the server and then marked as clean, so that they can be discarded like any other\n * sector.\n *\n * We also support \"local\" init-only disk images, which means that dirty sectors are never sent\n * back to the server and are instead retained by the client for the lifetime of the app; such\n * images are \"read-only\" as far as the server is concerned, but \"read-write\" as far as the client\n * is concerned. Reloading/restarting an app with an \"local\" disk will return the disk to its\n * initial state.\n *\n * Practice\n * ---\n * Let's first look at what we *already* do for the HDC component:\n *\n * 1) Creating new (empty) disk images\n * 2) Pre-loading pre-built JSON-encoded disk images (converting them to JSON on the fly as needed)\n *\n * An example of #1 is in /devices/pc/machine/5160/cga/256kb/demo/machine.xml:\n *\n * <hdc id=\"hdcXT\" drives='[{name:\"10Mb Hard Drive\",type:3}]'/>\n *\n * and an example of #2 is in /disks/pc/fixed/win101.xml:\n *\n * <hdc id=\"hdcXT\" drives='[{name:\"10Mb Hard Drive\",path:\"/disks/pc/fixed/win101/10mb.json\",type:3}]'/>\n *\n * The HDC component expects an array of drive entries. Array position determines drive numbering\n * (the first entry is drive 0, the second is drive 1, etc), and each entry contains the following\n * properties:\n *\n * 'name': user-friendly name for the disk, if any\n * 'path': URL of the disk image, if any\n * 'type': a drive type\n *\n * Of those properties, only 'type' is required, which provides an index into an HDC \"Drive Type\"\n * table that determines disk geometry and therefore disk size. As we add support for larger disks and\n * newer disk controllers, the 'type' parameter will be superseded by either a user-defined 'geometry'\n * parameter that will define number of heads, cylinders, tracks, sectors per track, and (max) bytes per\n * sector, or perhaps a generic 'size' parameter that leaves geometry choices to the HDC component,\n * which will then pass those decisions on to the Disk component.\n *\n * We will enable on-demand I/O for a disk image with a new 'mode' parameter that looks like:\n *\n * 'mode': one of \"local\", \"preload\", \"demandrw\", \"demandro\"\n *\n * \"preload\" means the disk image will be completely preloaded, exactly as before; \"demandrw\" enables\n * full on-demand I/O support; and \"demandro\" enables on-demand I/O for reads only (all writes are retained\n * and never written back to the server).\n *\n * \"ro\" will be the fallback for \"rw\" unless TWO other important criteria are met: 1) the user has a\n * private user key, and therefore per-user storage; and 2) the disk image 'path' contains an asterisk (*)\n * that the server can internally remap to a directory in the user's storage; eg:\n *\n * 'path': <asterisk>/10mb.img (path components following the asterisk are optional)\n *\n * If the disk image does not already exist, it will be created (but not formatted).\n *\n * This preserves the promise that EVERYTHING a user does within a PCx86 machine is private (ie, not\n * visible to any other PCjs users). I don't want to be in the business of saving any user machine\n * states or disk changes, but at least those operations are limited to users who have asked for (and\n * received) a private user key.\n *\n * Another important consideration at this stage is dealing with multiple machines writing to the same\n * disk image; even though we're limiting the \"demandrw\" mode to per-user images, a single user may still\n * inadvertently start up multiple machines that refer to the same disk image.\n *\n * So, every PCx86 machine needs to generate a unique token and include that token with every Disk I/O API\n * operation, so that the server can revoke a previous machine's \"rw\" access to a disk image when a new\n * machine requests \"rw\" access to the same disk image.\n *\n * From the client's perspective, revocation can be quietly dealt with by reverting to \"demandro\" mode;\n * that client becomes stuck with all their dirty sectors until they can reclaim \"rw\" access, which should\n * only happen if no intervening writes to the disk image on the server have occurred (if I bother allowing\n * reclamation at all).\n *\n * The real challenge here is avoiding revocation of a machine that still has critical changes to commit,\n * but since we can't even solve the problem of a user closing their browser at an inopportune time\n * and potentially leaving a disk image in an inconsistent state, premature revocation is the least of\n * our problems. Since a real hard drive could suffer the same fate if the machine's power was turned off\n * at the wrong time, you could say that we're simply providing a faithful simulation of reality.\n */\n\n/**\n * class Disk\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass Disk extends Component {\n /**\n * Disk(controller, drive, mode)\n *\n * Disk contents are stored as an array (aDiskData) of cylinders, each of which is an array of\n * heads, each of which is an array of sector objects; the latter contain sector numbers and\n * sector data, where sector data is an array of dwords. The format does not impose any\n * limitations on number of cylinders, number of heads, sectors per track, or bytes per sector.\n *\n * WARNING: All accesses to disk sector properties must be via their string names, not their\n * \"dot\" names, otherwise code will break after it's been processed by the Closure Compiler,\n * and any dumped disks may be unmountable. This is a side-effect of how we mount and dump\n * disk images (ie, as JSON-encoded streams).\n *\n * This means, for example, that all references to \"track[iSector].data\" must actually appear as\n * \"track[iSector]['data']\".\n *\n * @this {Disk}\n * @param {HDC|FDC} controller\n * @param {Object} drive\n * @param {string} mode\n */\n constructor(controller, drive, mode)\n {\n super(\"Disk\", {'id': controller.idMachine + \".disk\" + Str.toHex(++Disk.nDisks, 4)}, Messages.DISK);\n\n this.controller = controller;\n\n /*\n * Route all non-Debugger messages (eg, notice() and println() calls) through\n * this.controller (eg, controller.notice() and controller.println()), because\n * the Computer component is unaware of any Disk objects and therefore will not\n * set up the usual overrides when a Control Panel is installed.\n */\n this.notice = controller.notice;\n this.println = controller.println;\n\n this.cmp = controller.cmp;\n this.dbg = controller.dbg;\n this.drive = drive;\n\n /*\n * We pull out a number of drive properties that we may or may not need as defaults\n */\n this.sDiskName = drive.name;\n this.fRemovable = drive.fRemovable;\n this.fOnDemand = this.fRemote = false;\n\n /*\n * Initialize the disk contents\n */\n this.create(mode, drive.nCylinders, drive.nHeads, drive.nSectors, drive.cbSector);\n\n /*\n * The following dirty sector and timer properties are used only with fOnDemand disks,\n * assuming fRemote was successfully set.\n */\n this.aDirtySectors = [];\n this.aDirtyTimestamps = []; // this array is parallel to aDirtySectors\n this.timerWrite = null; // REMOTE_WRITE_DELAY timer in effect, if any\n this.msTimerWrite = 0; // the time that the write timer, if any, is set to fire\n this.fWriteInProgress = false;\n\n this.setReady();\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * We have no real interest in this notification, other than to obtain a reference to the Debugger\n * for every disk loaded BEFORE the initBus() phase; any disk loaded AFTER that point will get its Debugger\n * reference, if any, from the disk controller passed to the Disk() constructor.\n *\n * @this {Disk}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.dbg = dbg;\n }\n\n /**\n * isRemote()\n *\n * @this {Disk}\n * @return {boolean} true if remote disk, false if not\n */\n isRemote()\n {\n /*\n * Ironically, we can't rely on fRemote, because that is cleared and set across disconnect and\n * reconnect operations. fOnDemand is the next best thing.\n */\n return this.fOnDemand;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * As with powerDown(), our sole concern here is for REMOTE disks: if a powerDown() call disconnected an\n * \"on-demand\" disk, we need to get reconnected. Calling our own load() function should get the job done.\n *\n * The HDC component could have triggered this as well, but its powerUp() function only calls autoMount()\n * in case of page (ie, application) reload, which is fine for local disks but insufficient for remote disks,\n * which have a server connection that must be re-established.\n *\n * @this {Disk}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (this.fOnDemand && !this.fRemote) {\n this.setReady(false);\n this.load(this.sDiskName, this.sDiskPath, null, this.donePowerUp, this);\n }\n }\n return true;\n }\n\n /**\n * donePowerUp(drive, disk, sDiskName, sDiskPath)\n *\n * This is a callback issued by the Disk component once the load() from powerUp() has finished.\n *\n * @this {Disk}\n * @param {Object} drive\n * @param {Disk} disk is set if the disk was successfully mounted, null if not\n * @param {string} sDiskName\n * @param {string} sDiskPath\n */\n donePowerUp(drive, disk, sDiskName, sDiskPath)\n {\n this.setReady(true);\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * Our sole concern here is for REMOTE disks, making sure any unwritten changes get flushed to\n * the server during a shutdown. No local state is ever returned, so fSave is ignored.\n *\n * Local disks are managed by the controller (ie, FDC or HDC) that mounted them; the controller's\n * powerDown() handler will take care of calling save() as needed.\n *\n * TODO: Consider taking responsibility for saving the state of local disks as well; the only reason\n * the controllers still take care of them is historical, because this component originally didn't\n * exist, and even after it was created, it didn't originally receive powerDown() notifications.\n *\n * @this {Disk}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean}\n */\n powerDown(fSave, fShutdown)\n {\n /*\n * If we're connected to a remote disk, take this opportunity to flush any remaining unwritten\n * changes and then close the connection.\n */\n if (this.fRemote) {\n var response;\n var nErrorCode = 0;\n if (this.fWriteInProgress) {\n /*\n * TODO: Verify that the Computer's powerOff() handler will actually honor a false return value.\n */\n if (!Component.confirmUser(\"Disk writes are still in progress, shut down anyway?\")) {\n return false;\n }\n }\n while ((response = this.findDirtySectors(false))) {\n if ((nErrorCode = response[0])) {\n this.notice('Unable to save \"' + this.sDiskName + '\" (error ' + nErrorCode + ')');\n break;\n }\n }\n if (fShutdown) {\n this.disconnectRemoteDisk();\n }\n /*\n * I only report that changes to the disk have been \"saved\" if fSave is true, to avoid confusing\n * users who might not understand the difference between discarding local changes (which should restore\n * all diskettes to their original state) and discarding remote changes (which could leave the remote disk\n * in a bad state).\n */\n if (!nErrorCode && fSave) this.notice(this.sDiskName + \" saved\");\n }\n return true;\n }\n\n /**\n * create()\n *\n * @this {Disk}\n * @param {string} mode\n * @param {number} nCylinders\n * @param {number} nHeads\n * @param {number} nSectors (per track)\n * @param {number} cbSector\n *\n * Initializes the disk contents according to the current drive mode and parameters.\n */\n create(mode, nCylinders, nHeads, nSectors, cbSector)\n {\n this.mode = mode;\n this.nCylinders = nCylinders;\n this.nHeads = nHeads;\n this.nSectors = nSectors;\n this.cbSector = cbSector;\n this.aDiskData = [];\n /*\n * If the drive is using PRELOAD mode, then it will use the load()/mount() process to initialize the disk contents;\n * it wouldn't hurt to let create() do its thing, too, but it's a waste of time.\n */\n if (this.mode != DiskAPI.MODE.PRELOAD) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"blank disk for \\\"\" + this.sDiskName + \"\\\": \" + this.nCylinders + \" cylinders, \" + this.nHeads + \" head(s)\");\n }\n var aCylinders = new Array(this.nCylinders);\n for (var iCylinder = 0; iCylinder < aCylinders.length; iCylinder++) {\n var aHeads = new Array(this.nHeads);\n for (var iHead = 0; iHead < aHeads.length; iHead++) {\n var aSectors = new Array(this.nSectors);\n for (var iSector = 1; iSector <= aSectors.length; iSector++) {\n /*\n * Now that our read() and write() functions can deal with unallocated data\n * arrays, and can read/write the specified pattern on-the-fly, we no longer need\n * to pre-allocate and pre-initialize the 'data' array.\n *\n * For \"local\" disks, we can assume a 'pattern' of 0, but for \"demandrw\" and \"demandro\"\n * disks, 'pattern' is set to null, as yet another indication that I/O is required to load\n * the sector from the server (or to write it back to the server).\n */\n aSectors[iSector - 1] = this.initSector(null, iCylinder, iHead, iSector, this.cbSector, (this.mode == DiskAPI.MODE.LOCAL? 0 : null));\n }\n aHeads[iHead] = aSectors;\n }\n aCylinders[iCylinder] = aHeads;\n }\n this.aDiskData = aCylinders;\n }\n this.dwChecksum = null;\n }\n\n /**\n * load(sDiskName, sDiskPath, file, fnNotify)\n *\n * TODO: Figure out how we can strongly type fnNotify, because the Closure Compiler has issues with:\n *\n * param {function(Component,Object,Disk,string,string)} fnNotify\n *\n * for:\n *\n * this.fnNotify.call(this.controller, this.drive, disk, this.sDiskName, this.sDiskPath);\n *\n * Also, while we're at it, learn if there are ways to:\n *\n * 1) declare a function taking NO parameters (ie, generate a warning if any parameters are specified)\n * 2) declare a type for a function's return value\n *\n * @this {Disk}\n * @param {string} sDiskName\n * @param {string} sDiskPath\n * @param {File} [file] is set if there's an associated File object\n * @param {function(...)} [fnNotify]\n * @param {Component} [controller]\n * @return {boolean} true if load completed (successfully or not), false if queued\n */\n load(sDiskName, sDiskPath, file, fnNotify, controller)\n {\n var sDiskURL = sDiskPath;\n\n /*\n * We could use this.log() as well, but it wouldn't display which component initiated the load.\n */\n if (DEBUG) {\n var sMessage = 'load(\"' + sDiskName + '\",\"' + sDiskPath + '\")';\n this.controller.log(sMessage);\n this.printMessage(sMessage);\n }\n\n if (this.fnNotify) {\n if (DEBUG) this.controller.log('too many load requests for \"' + sDiskName + '\" (' + sDiskPath + ')');\n return true;\n }\n\n this.sDiskName = sDiskName;\n this.sDiskPath = sDiskPath;\n this.sDiskFile = Str.getBaseName(sDiskPath);\n this.sFormat = \"json\";\n\n var disk = this;\n this.fnNotify = fnNotify;\n this.controllerNotify = controller || this.controller;\n\n if (file) {\n var reader = new FileReader();\n reader.onload = function() {\n disk.buildDisk(reader.result, true);\n };\n reader.readAsArrayBuffer(file);\n return true;\n }\n\n /*\n * If there's an occurrence of API_ENDPOINT anywhere in the path, we assume we can use it as-is;\n * ie, that the user has already formed a URL of the type we use ourselves for unconverted disk images.\n */\n if (sDiskPath.indexOf(DumpAPI.ENDPOINT) < 0) {\n /*\n * If the selected disk image has a \"json\" extension, then we assume it's a pre-converted\n * JSON-encoded disk image, so we load it as-is; otherwise, we ask our server-side disk image\n * converter to return the corresponding JSON-encoded data.\n */\n var sDiskExt = Str.getExtension(sDiskPath);\n if (sDiskExt == DumpAPI.FORMAT.JSON || sDiskExt == DumpAPI.FORMAT.JSON_GZ) {\n sDiskURL = encodeURI(sDiskPath);\n } else {\n if (this.mode == DiskAPI.MODE.DEMANDRW || this.mode == DiskAPI.MODE.DEMANDRO) {\n sDiskURL = this.connectRemoteDisk(sDiskPath);\n this.fOnDemand = true;\n } else {\n this.sFormat = \"arraybuffer\";\n }\n // else {\n // var sDiskParm = DumpAPI.QUERY.PATH;\n // var sSizeParm = '&' + DumpAPI.QUERY.MBHD + \"=10\";\n // /*\n // * 'mbhd' is a new parm added for hard drive support. In the case of 'file' or 'dir' requests,\n // * 'mbhd' informs DumpAPI.ENDPOINT that it should create a hard disk image, and one not larger than\n // * the specified size (eg, 10mb). In fact, until DumpAPI.ENDPOINT is changed to create custom hard\n // * disk BPBs, you'll always get a standard PC XT 10mb disk image, so if the 'file' or 'dir' contains\n // * more than 10mb of data, the request will fail. Ultimately, I want to honor the controller's\n // * driveConfig 'size' parm, or to match the capacity required by the driveConfig 'type' parameter.\n // *\n // * If a 'disk' is specified, we pass mbhd=0, because the actual size will depend on the image.\n // * However, I don't currently have any \"dsk\" or \"img\" files containing hard disk images; those formats\n // * were really intended for floppy disk images. If I never create any hard disk image files, then\n // * we can simply eliminate sSizeParm in the 'disk' case.\n // *\n // * Added more extensions to the list of paths-treated-as-disk-images, so that URLs to files located here:\n // *\n // * ftp://ftp.oldskool.org/pub/TOPBENCH/dskimage/\n // *\n // * can be used as-is. TODO: There's a TODO in netlib.getFile() regarding remote support that needs\n // * to be resolved first; DiskDump relies on that function for its remote requests, and it currently\n // * supports only HTTP.\n // */\n // if (!sDiskPath.indexOf(\"http:\") || !sDiskPath.indexOf(\"ftp:\") || [\"dsk\", \"ima\", \"img\", \"360\", \"720\", \"12\", \"144\"].indexOf(sDiskExt) >= 0) {\n // sDiskParm = DumpAPI.QUERY.DISK;\n // sSizeParm = '&' + DumpAPI.QUERY.MBHD + \"=0\";\n // } else if (Str.endsWith(sDiskPath, '/')) {\n // sDiskParm = DumpAPI.QUERY.DIR;\n // }\n // sDiskURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + sDiskParm + '=' + encodeURIComponent(sDiskPath) + (this.fRemovable ? \"\" : sSizeParm) + \"&\" + DumpAPI.QUERY.FORMAT + \"=\" + DumpAPI.FORMAT.JSON;\n // }\n }\n }\n var sProgress = \"Loading \" + sDiskURL + \"...\";\n return !!Web.getResource(sDiskURL, this.sFormat, true, function loadDone(sURL, sResponse, nErrorCode) {\n disk.doneLoad(sURL, sResponse, nErrorCode);\n }, function(nState) {\n disk.println(sProgress, Component.PRINT.PROGRESS);\n });\n }\n\n /**\n * buildDisk(buffer, fModified)\n *\n * Builds a disk image from an ArrayBuffer (eg, from a FileReader object), rather than from JSON-encoded data.\n *\n * @this {Disk}\n * @param {?} buffer (technically, this is always an ArrayBuffer, because we tell FileReader to use readAsArrayBuffer, but the Closure Compiler doesn't realize that) \n * @param {boolean} [fModified] is true if we should mark the entire disk modified (to ensure that we save/restore it)\n */\n buildDisk(buffer, fModified)\n {\n var disk;\n var cbDiskData = buffer? buffer.byteLength : 0;\n var diskFormat = DiskAPI.GEOMETRIES[cbDiskData];\n\n if (diskFormat) {\n this.nCylinders = diskFormat[0];\n this.nHeads = diskFormat[1];\n this.nSectors = diskFormat[2];\n this.cbSector = (diskFormat[3] || 512);\n\n var cdw = this.cbSector >> 2, dwPattern = 0, dwChecksum = 0;\n var ib = 0;\n var dv = new DataView(buffer, 0, cbDiskData);\n\n this.aDiskData = new Array(this.nCylinders);\n for (var iCylinder = 0; iCylinder < this.aDiskData.length; iCylinder++) {\n var cylinder = this.aDiskData[iCylinder] = new Array(this.nHeads);\n for (var iHead = 0; iHead < cylinder.length; iHead++) {\n var head = cylinder[iHead] = new Array(this.nSectors);\n for (var iSector = 0; iSector < head.length; iSector++) {\n var sector = this.initSector(null, iCylinder, iHead, iSector + 1, this.cbSector, dwPattern);\n var adw = sector['data'];\n for (var idw = 0; idw < cdw; idw++, ib += 4) {\n var dw = adw[idw] = dv.getInt32(ib, true);\n dwChecksum = (dwChecksum + dw) & (0xffffffff|0);\n }\n if (fModified) sector.cModify = cdw;\n head[iSector] = sector;\n }\n }\n }\n this.dwChecksum = dwChecksum;\n disk = this;\n } else {\n this.notice(\"Unrecognized disk format (\" + cbDiskData + \" bytes)\");\n }\n\n if (this.fnNotify) {\n this.fnNotify.call(this.controller, this.drive, disk, this.sDiskName, this.sDiskPath);\n this.fnNotify = null;\n }\n }\n\n /**\n * doneLoad(sURL, diskData, nErrorCode)\n *\n * This function was originally called mount(). If the mount is successful, we pass the Disk object to the\n * caller's fnNotify handler; otherwise, we pass null.\n *\n * @this {Disk}\n * @param {string} sURL\n * @param {string|ArrayBuffer} diskData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n doneLoad(sURL, diskData, nErrorCode)\n {\n var disk = null;\n this.fWriteProtected = false;\n var fPrintOnly = !!(nErrorCode < 0 && this.cmp && !this.cmp.flags.powered);\n\n if (this.fOnDemand) {\n if (!nErrorCode) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage('doneLoad(\"' + this.sDiskPath + '\")');\n }\n this.fRemote = true;\n if (BACKTRACK || SYMBOLS) this.buildFileTable();\n disk = this;\n } else {\n this.notice('Unable to connect to disk \"' + this.sDiskPath + '\" (error ' + nErrorCode + ': ' + diskData + ')', fPrintOnly);\n }\n }\n else if (nErrorCode) {\n /*\n * This can happen for innocuous reasons, such as the user switching away too quickly, forcing\n * the request to be cancelled. And unfortunately, the browser cancels XMLHttpRequest requests\n * BEFORE it notifies any page event handlers, so if the Computer's being powered down, we won't know\n * that yet. For now, we rely on the lack of a specific error (nErrorCode < 0), and suppress the\n * notify() alert if there's no specific error AND the computer is not powered up yet.\n */\n this.notice(\"Unable to load disk \\\"\" + this.sDiskName + \"\\\" (error \" + nErrorCode + \": \" + sURL + \")\", fPrintOnly);\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage('doneLoad(\"' + this.sDiskPath + '\")');\n }\n\n /*\n * If we received binary data instead of JSON, we can use the same buildDisk() function that our FileReader\n * code uses.\n */\n if (typeof diskData != \"string\") {\n this.buildDisk(diskData);\n return;\n }\n \n try {\n /*\n * The following code was a hack to turn on write-protection for a disk image if there was\n * an initial comment line containing the string \"write-protected\". However, since comments\n * are technically not allowed in JSON, I needed an alternative solution. So, if the basename\n * contains the suffix \"-readonly\", then I'll turn on write-protection for that disk as well.\n *\n * TODO: Provide some UI for turning write-protection on/off for disks at will, and provide\n * an XML-based solution (ie, a per-disk XML configuration option) for controlling it as well.\n */\n var sBaseName = Str.getBaseName(this.sDiskFile, true).toLowerCase();\n if (sBaseName.indexOf(\"-readonly\") > 0) {\n this.fWriteProtected = true;\n } else {\n var iEOL = diskData.indexOf(\"\\n\");\n if (iEOL > 0 && iEOL < 1024) {\n var sConfig = diskData.substring(0, iEOL);\n if (sConfig.indexOf(\"write-protected\") > 0) {\n this.fWriteProtected = true;\n }\n }\n }\n /*\n * The most likely source of any exception will be here, where we're parsing the disk data.\n */\n var aDiskData;\n if (diskData.substr(0, 1) == \"<\") { // if the \"data\" begins with a \"<\"...\n /*\n * Early server configs reported an error (via the nErrorCode parameter) if a disk URL was invalid,\n * but more recent server configs now display a somewhat friendlier HTML error page. The downside,\n * however, is that the original error has been buried, and we've received \"data\" that isn't actually\n * disk data.\n *\n * So, if the data we've received appears to be \"HTML-like\", all we can really do is assume that the\n * disk image is missing. And so we pretend we received an error message to that effect.\n */\n aDiskData = [\"Missing disk image: \" + this.sDiskName];\n } else {\n /*\n * TODO: IE9 is rather unfriendly and restrictive with regard to how much data it's willing to\n * eval(). In particular, the 10Mb disk image we use for the Windows 1.01 demo config fails in\n * IE9 with an \"Out of memory\" exception. One work-around would be to chop the data into chunks\n * (perhaps one track per chunk, using regular expressions) and then manually re-assemble it.\n *\n * However, it turns out that using JSON.parse(diskData) instead of eval(\"(\" + diskData + \")\")\n * is a much easier fix. The only drawback is that we must first quote any unquoted property names\n * and remove any comments, because while eval() was cool with them, JSON.parse() is more particular;\n * the following RegExp replacements take care of those requirements.\n *\n * The use of hex values is something else that eval() was OK with, but JSON.parse() is not, and\n * while I've stopped using hex values in DumpAPI responses (at least when \"format=json\" is specified),\n * I can't guarantee they won't show up in \"legacy\" images, and there's no simple RegExp replacement\n * for transforming hex values into decimal values, so I cop out and fall back to eval() if I detect\n * any hex prefixes (\"0x\") in the sequence. Ditto for error messages, which appear like so:\n *\n * [\"unrecognized disk path: test.img\"]\n */\n if (diskData.indexOf(\"0x\") < 0 && diskData.substr(0, 2) != \"[\\\"\") {\n aDiskData = JSON.parse(diskData.replace(/([a-z]+):/gm, \"\\\"$1\\\":\").replace(/\\/\\/[^\\n]*/gm, \"\"));\n } else {\n aDiskData = eval(\"(\" + diskData + \")\");\n }\n }\n\n if (!aDiskData.length) {\n Component.error(\"Empty disk image: \" + this.sDiskName);\n }\n else if (aDiskData.length == 1) {\n Component.error(aDiskData[0]);\n }\n /*\n * aDiskData is an array of cylinders, each of which is an array of heads, each of which\n * is an array of sector objects. The format does not impose any limitations on number of\n * cylinders, number of heads, or number of bytes in any of the sector object byte-arrays.\n *\n * WARNING: All accesses to sector object properties must be via their string names, not their\n * \"dot\" names, otherwise code will break after it's been processed by the Closure Compiler.\n *\n * Sector object properties include:\n *\n * 'sector' the sector number (1-based, not required to be sequential)\n * 'length' the byte-length (ie, formatted length) of the sector\n * 'data' the dword-array containing the sector data\n * 'pattern' if the dword-array length is less than 'length'/4, this value must be used\n * to pad out the sector; if no 'pattern' is specified, it's assumed to be zero\n *\n * We still support the older JSON encoding, where sector data was encoded as an array of 'bytes'\n * rather than a dword 'data' array. However, our support is strictly limited to an on-the-fly\n * conversion to a forward-compatible 'data' array.\n */\n else {\n if (DEBUG && this.messageEnabled(Messages.DISK | Messages.DATA)) {\n var sCylinders = aDiskData.length + \" track\" + (aDiskData.length > 1 ? \"s\" : \"\");\n var nHeads = aDiskData[0].length;\n var sHeads = nHeads + \" head\" + (nHeads > 1 ? \"s\" : \"\");\n var nSectorsPerTrack = aDiskData[0][0].length;\n var sSectorsPerTrack = nSectorsPerTrack + \" sector\" + (nSectorsPerTrack > 1 ? \"s\" : \"\") + \"/track\";\n this.printMessage(sCylinders + \", \" + sHeads + \", \" + sSectorsPerTrack);\n }\n /*\n * Before the image is usable, we must \"normalize\" all the sectors. In the past, this meant\n * \"inflating\" them all. However, that's no longer strictly necessary. Mainly, it just means\n * setting 'length', 'data', and 'pattern' properties, so that all the sectors are well-defined.\n * This includes detecting sector data in older formats (eg, the old array of 'bytes' instead\n * of the new 'data' array of dwords) and converting them on-the-fly to the current format.\n */\n this.nCylinders = aDiskData.length;\n this.nHeads = aDiskData[0].length;\n this.nSectors = aDiskData[0][0].length;\n var sector = aDiskData[0][0][0];\n this.cbSector = (sector && sector['length']) || 512;\n\n var dwChecksum = 0;\n for (var iCylinder = 0; iCylinder < this.nCylinders; iCylinder++) {\n for (var iHead = 0; iHead < this.nHeads; iHead++) {\n for (var iSector = 0; iSector < this.nSectors; iSector++) {\n sector = aDiskData[iCylinder][iHead][iSector];\n if (!sector) continue; // non-standard (eg, XDF) disk images may have \"unused\" (null) sectors\n var length = sector['length'];\n if (length === undefined) { // provide backward-compatibility with older JSON...\n length = sector['length'] = 512;\n }\n length >>= 2; // convert length from a byte-length to a dword-length\n var dwPattern = sector['pattern'];\n if (dwPattern === undefined) {\n dwPattern = sector['pattern'] = 0;\n }\n var adw = sector['data'];\n if (adw === undefined) {\n var ab = sector['bytes'];\n if (ab === undefined || !ab.length) {\n /*\n * If there is neither a 'bytes' nor 'data' array, then our job is simple:\n * create an empty 'data' array; it will be filled in with the dword pattern\n * as needed later.\n *\n * The only wrinkle is if there *is* a 'bytes' array but it's empty, in which\n * case we must assume that the pattern was a byte pattern, so convert it to a\n * dword pattern.\n */\n sector['data'] = adw = [];\n if (ab) {\n\n sector['pattern'] = (dwPattern | (dwPattern << 8) | (dwPattern << 16) | (dwPattern << 24));\n }\n }\n else {\n /*\n * To keep the conversion code simple, we'll do any necessary pattern-filling first,\n * to fully \"inflate\" the sector, eliminating the possibility of partial dwords and\n * saving any code downstream from dealing with byte-size patterns.\n */\n var cb = length << 2;\n\n for (var ib = ab.length; ib < cb; ib++) {\n ab[ib] = dwPattern; // the pattern for byte-arrays was only a byte\n }\n this.fill(sector, ab, 0);\n }\n delete sector['bytes'];\n }\n this.initSector(sector, iCylinder, iHead);\n /*\n * For the disk as a whole, we maintain a checksum of the original unmodified data:\n *\n * dwChecksum: summation of all dwords in all non-empty sectors\n *\n * Pattern-filling of sectors is deferred until absolutely necessary (eg, when a sector is\n * being written). So all we need to do at this point is checksum all the initial sector data.\n */\n for (var idw = 0; idw < adw.length; idw++) {\n dwChecksum = (dwChecksum + adw[idw]) & (0xffffffff|0);\n }\n }\n }\n }\n this.aDiskData = aDiskData;\n this.dwChecksum = dwChecksum;\n if (BACKTRACK || SYMBOLS) this.buildFileTable();\n disk = this;\n }\n } catch (e) {\n Component.error(\"Disk image error (\" + sURL + \"): \" + e.message);\n diskData = null;\n }\n \n if (diskData) {\n Component.addMachineResource(this.controller.idMachine, sURL, diskData);\n }\n }\n\n if (this.fnNotify) {\n this.fnNotify.call(this.controllerNotify, this.drive, disk, this.sDiskName, this.sDiskPath);\n this.fnNotify = null;\n }\n }\n\n /**\n * buildFileTable()\n *\n * This function builds (or rebuilds) a complete file table from the (first) FAT volume found on the current\n * disk, and then updates all the sector objects to point back to the corresponding file. Used for BACKTRACK\n * and SYMBOLS support. Because this is an expensive operation, in terms of both time and memory, it should\n * only be called when a disk is mounted or has been modified (eg, by applying deltas from a saved machine state).\n *\n * More recently, the FileInfo objects in the table have been enhanced to include debugging information if\n * the file is an EXE or DLL, which we determine merely by checking the file extension.\n *\n * Note that while most of the methods in this module use CHS-style parameters, because our primary clients\n * are old disk controllers that deal exclusively with cylinder/head/sector values, here we use 0-based\n * \"logical\" sector numbers for volume-relative block addresses (aka LBAs or Logical Block Addresses), and\n * 0-based \"physical\" sector numbers for disk-relative block addresses (aka PBAs or Physical Block Addresses).\n *\n * Also, our use of the term LBA differs from that of more modern disk controllers; in the pre-modern world\n * of PCx86, what we call PBA numbers are what those controllers would later call LBA numbers.\n *\n * @this {Disk}\n * @return {Array.<FileInfo>|undefined}\n */\n buildFileTable()\n {\n if (BACKTRACK || SYMBOLS) {\n\n var i, off, dir = {}, iSector;\n\n if (this.aFileTable && this.aFileTable.length) {\n /*\n * In order for buildFileTable() to rebuild an existing table (eg, after deltas have been\n * applied), we need to zap any and all existing file table references in the sector data.\n */\n var aDiskData = this.aDiskData;\n for (var iCylinder = 0; iCylinder < aDiskData.length; iCylinder++) {\n for (var iHead = 0; iHead < aDiskData[iCylinder].length; iHead++) {\n for (iSector = 0; iSector < aDiskData[iCylinder][iHead].length; iSector++) {\n var sector = aDiskData[iCylinder][iHead][iSector];\n if (sector) {\n delete sector['file'];\n delete sector.offFile;\n }\n }\n }\n }\n }\n\n this.aFileTable = [];\n\n dir.pbaVolume = dir.lbaTotal = 0;\n\n var cbDisk = this.nCylinders * this.nHeads * this.nSectors * this.cbSector;\n\n /*\n * At this point, if this is a remote disk, you may see some warning messages in your browser's console,\n * like this message from Chrome:\n *\n * \"Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects\n * to the end user's experience. For more help, check http://xhr.spec.whatwg.org/.\"\n *\n * This is because I was lazy and made the buildFileTable() worker function getSector() use the synchronous\n * form of seek(). For development purposes, that was fine, but... TODO: Eventually change buildFileTable()\n * to use async I/O.\n */\n if (this.fRemote) this.log(\"ignore any synchronous XMLHttpRequest warnings here (for now)\");\n\n var sectorBoot = this.getSector(0);\n if (!sectorBoot) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"buildFileTable(): unable to read boot sector\");\n }\n return;\n }\n\n dir.cbSector = this.getSectorData(sectorBoot, DiskAPI.BPB.SECTOR_BYTES, 2);\n\n var fValid = true;\n if (dir.cbSector != this.cbSector) {\n /*\n * When the first sector doesn't appear to contain a valid BPB, the most likely explanations are:\n *\n * 1. The image is from a diskette formatted by DOS 1.xx, which didn't use BPBs\n * 2. The image is a fixed (partitioned) disk and the first sector is actually an MBR\n * 3. The image is from a diskette that used a non-standard sector size (ie, not 512)\n *\n * To start, if this is an 160Kb disk (circa DOS 1.00) or a 320Kb disk (circa DOS 1.10), then we'll\n * assume it's a 12-bit FAT, set assorted BPB values accordingly, and see if our assumption holds up.\n */\n fValid = false;\n dir.lbaFAT = 1;\n dir.nFATBits = 12;\n dir.lbaRoot = dir.lbaFAT + 2; // both 160Kb and 320Kb disks contained 2 FATs, each containing 1 sector\n dir.nClusterSecs = 1;\n dir.cbSector = this.cbSector;\n\n if (cbDisk == 160 * 1024 && this.getClusterEntry(dir, 0, 0) == DiskAPI.FAT.MEDIA_160KB) {\n dir.lbaTotal = 320;\n dir.nEntries = 64;\n fValid = true;\n }\n else if (cbDisk == 320 * 1024 && this.getClusterEntry(dir, 0, 0) == DiskAPI.FAT.MEDIA_320KB) {\n dir.lbaTotal = 640;\n dir.nEntries = 112;\n\n dir.nClusterSecs++; // 320Kb disks use 2 sectors/cluster\n fValid = true;\n }\n else {\n /*\n * So, this is either a fixed (partitioned) disk, or a disk using a non-standard sector size; let's assume\n * the former and check for an MBR. For now, we're only going to process the first active partition we find.\n */\n off = DiskAPI.MBR.PARTITIONS.OFFSET;\n for (i = 0; i < 4; i++) {\n var bStatus = this.getSectorData(sectorBoot, off + DiskAPI.MBR.PARTITIONS.ENTRY.STATUS, 1);\n if (bStatus == DiskAPI.MBR.PARTITIONS.STATUS.ACTIVE) {\n dir.pbaVolume = this.getSectorData(sectorBoot, off + DiskAPI.MBR.PARTITIONS.ENTRY.LBA_FIRST, 4);\n sectorBoot = this.getSector(dir.pbaVolume);\n if (sectorBoot && this.getSectorData(sectorBoot, DiskAPI.BPB.SECTOR_BYTES, 2) == this.cbSector) {\n fValid = true;\n }\n break;\n }\n off += DiskAPI.MBR.PARTITIONS.ENTRY_LENGTH;\n }\n }\n if (!fValid) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"buildFileTable(): unrecognized \" + cbDisk + \"-byte disk image with \" + this.cbSector + \"-byte sectors\");\n }\n return;\n }\n }\n\n if (!dir.lbaTotal) {\n dir.lbaTotal = this.getSectorData(sectorBoot, DiskAPI.BPB.TOTAL_SECS, 2) || this.getSectorData(sectorBoot, DiskAPI.BPB.LARGE_SECS, 4);\n dir.lbaFAT = this.getSectorData(sectorBoot, DiskAPI.BPB.RESERVED_SECS, 2);\n dir.lbaRoot = dir.lbaFAT + this.getSectorData(sectorBoot, DiskAPI.BPB.FAT_SECS, 2) * this.getSectorData(sectorBoot, DiskAPI.BPB.TOTAL_FATS, 1);\n dir.nEntries = this.getSectorData(sectorBoot, DiskAPI.BPB.ROOT_DIRENTS, 2);\n dir.nClusterSecs = this.getSectorData(sectorBoot, DiskAPI.BPB.CLUSTER_SECS, 1);\n }\n\n dir.lbaData = dir.lbaRoot + (((dir.nEntries * DiskAPI.DIRENT.LENGTH + (dir.cbSector - 1)) / dir.cbSector) | 0);\n dir.nClusters = (((dir.lbaTotal - dir.lbaData) / dir.nClusterSecs) | 0);\n\n /*\n * In all FATs, the first valid cluster number is 2, as 0 is used to indicate a free cluster and 1 is reserved.\n *\n * In a 12-bit FAT chain, the largest valid cluster number (iClusterMax) is 0xFF6; 0xFF7 is reserved for marking\n * bad clusters and should NEVER appear in a cluster chain, and 0xFF8-0xFFF are used to indicate the end of a chain.\n * Reports that cluster numbers 0xFF0-0xFF6 are \"reserved\" (eg, http://support.microsoft.com/KB/65541) should be\n * ignored; those numbers may have been considered \"reserved\" at some early point in FAT's history, but no longer.\n *\n * Since 12 bits yield 4096 possible values, and since 11 of the values (0, 1, and 0xFF7-0xFFF) cannot be used to\n * refer to an actual cluster, that leaves a theoretical maximum of 4085 clusters for a 12-bit FAT. However, for\n * reasons that only a small (and shrinking -- RIP AAR) number of people know, the actual cut-off is 4084.\n *\n * So, a FAT volume with 4084 or fewer clusters uses a 12-bit FAT, a FAT volume with 4085 to 65524 clusters uses\n * a 16-bit FAT, and a FAT volume with more than 65524 clusters uses a 32-bit FAT.\n *\n * TODO: Eventually add support for FAT32.\n */\n dir.nFATBits = (dir.nClusters <= DiskAPI.FAT12.MAX_CLUSTERS? 12 : 16);\n dir.iClusterMax = (dir.nFATBits == 12? DiskAPI.FAT12.CLUSNUM_MAX : DiskAPI.FAT16.CLUSNUM_MAX);\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"buildFileTable()\\n\\tlbaFAT: \" + dir.lbaFAT + \"\\n\\tlbaRoot: \" + dir.lbaRoot + \"\\n\\tlbaData: \" + dir.lbaData + \"\\n\\tlbaTotal: \" + dir.lbaTotal + \"\\n\\tnClusterSecs: \" + dir.nClusterSecs + \"\\n\\tnClusters: \" + dir.nClusters);\n }\n\n /*\n * The following assertion is here only to catch anomalies; it is NOT a requirement that the number of data sectors\n * be a perfect multiple of nClusterSecs, but if it ever happens, it's worth verifying we didn't miscalculate something.\n */\n i = (dir.lbaTotal - dir.lbaData) % dir.nClusterSecs;\n if (i) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"buildFileTable(): \" + cbDisk + \"-byte disk image wasting \" + i + \" sectors\");\n }\n }\n\n /*\n * Similarly, it is NOT a requirement that the size of all root directory entries be a perfect multiple of the sector\n * size (cbSector), but it may indicate a problem if it's not. Note that when it comes time to read the root directory,\n * we treat it exactly like any other directory; that is, we ignore the nEntries value and scan the entire contents of\n * every sector allocated to the directory. TODO: Determine whether DOS reads all root sector contents or only nEntries\n * (ie, create a test volume where nEntries * 32 is NOT a multiple of cbSector and watch what happens).\n */\n\n\n var apba = [];\n for (var lba = dir.lbaRoot; lba < dir.lbaData; lba++) apba.push(dir.pbaVolume + lba);\n this.getDir(dir, this.sDiskFile, \"\", apba);\n\n /*\n * Create the sector-to-file mappings now.\n */\n for (i = 0; i < this.aFileTable.length; i++) {\n var file = this.aFileTable[i];\n off = 0;\n for (iSector = 0; iSector < file.apba.length; iSector++) {\n this.updateSector(file, file.apba[iSector], off);\n off += this.cbSector;\n }\n file.loadSymbols();\n }\n }\n return this.aFileTable;\n }\n\n /**\n * getModuleInfo(sModule, nSegment)\n *\n * If the given module and segment number is found, we return an Array of symbol offsets, indexed by symbol name.\n *\n * @this {Disk}\n * @param {string} sModule\n * @param {number} nSegment\n * @return {Object}\n */\n getModuleInfo(sModule, nSegment)\n {\n var aSymbols = {};\n if (SYMBOLS && this.aFileTable) {\n for (var iFile = 0; iFile < this.aFileTable.length; iFile++) {\n var file = this.aFileTable[iFile];\n if (file.sModule != sModule) continue;\n var segment = file.aSegments[nSegment];\n if (!segment) continue;\n for (var iOrdinal in segment.aEntries) {\n var entry = segment.aEntries[iOrdinal];\n /*\n * entry[1] is the symbol name, which becomes the index, and entry[0] is the offset.\n */\n aSymbols[entry[1]] = entry[0];\n }\n break;\n }\n }\n return aSymbols;\n }\n\n /**\n * getSymbolInfo(sSymbol)\n *\n * For all whole or partial symbol matches, return them in an Array of entries:\n *\n * [symbol, file name, segment number, segment offset, segment size].\n *\n * TODO: This function has many limitations (ie, slow, case-sensitive), but it gets the job done for now.\n *\n * @this {Disk}\n * @param {string} sSymbol\n * @return {Array}\n */\n getSymbolInfo(sSymbol)\n {\n var aInfo = [];\n if (SYMBOLS && this.aFileTable) {\n var sSymbolUpper = sSymbol.toUpperCase();\n for (var iFile = 0; iFile < this.aFileTable.length; iFile++) {\n var file = this.aFileTable[iFile];\n for (var iSegment in file.aSegments) {\n var segment = file.aSegments[iSegment];\n for (var iOrdinal in segment.aEntries) {\n var entry = segment.aEntries[iOrdinal];\n if (entry[1] && entry[1].indexOf(sSymbolUpper) >= 0) {\n aInfo.push([entry[1], file.sName, iSegment, entry[0], segment.offEnd - segment.offStart]);\n }\n }\n }\n }\n }\n return aInfo;\n }\n\n /**\n * getDir(dir, sDisk, sDir, apba)\n *\n * @this {Disk}\n * @param {Object} dir\n * @param {string} sDisk\n * @param {string} sDir\n * @param {Array.<number>} apba\n */\n getDir(dir, sDisk, sDir, apba)\n {\n var file;\n var iStart = this.aFileTable.length;\n var nEntriesPerSector = (dir.cbSector / DiskAPI.DIRENT.LENGTH) | 0;\n\n dir.sDir = sDir + \"\\\\\";\n\n if (DEBUG && this.messageEnabled()) this.printMessage('getDir(\"' + sDisk + '\",\"' + dir.sDir + '\")');\n\n for (var iSector = 0; iSector < apba.length; iSector++) {\n var pba = apba[iSector];\n for (var iEntry = 0; iEntry < nEntriesPerSector; iEntry++) {\n if (!this.getDirEntry(dir, pba, iEntry)) {\n iSector = apba.length;\n break;\n }\n if (dir.sName == null || dir.sName == \".\" || dir.sName == \"..\") continue;\n var sPath = dir.sDir + dir.sName;\n if (DEBUG && this.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.printMessage('\"' + sPath + '\" size=' + dir.cbSize + ' cluster=' + dir.iCluster + ' sectors=' + JSON.stringify(dir.apba));\n if (dir.apba.length) this.printMessage(this.dumpSector(this.getSector(dir.apba[0]), dir.apba[0], sPath));\n }\n file = new FileInfo(this, sPath, dir.sName, dir.bAttr, dir.cbSize, dir.apba);\n this.aFileTable.push(file);\n }\n }\n\n var iEnd = this.aFileTable.length;\n\n for (var i = iStart; i < iEnd; i++) {\n file = this.aFileTable[i];\n if (file.bAttr & DiskAPI.ATTR.SUBDIR && file.apba.length) this.getDir(dir, sDisk, sDir + \"\\\\\" + file.sName, file.apba);\n }\n }\n\n /**\n * getDirEntry(dir, pba, i)\n *\n * This sets the following properties on the 'dir' object:\n *\n * sName (null if invalid/deleted entry)\n * bAttr\n * cbSize\n * iCluster\n * apba (ie, array of physical block addresses)\n *\n * On return, it's the caller's responsibility to copy out any data into a new object\n * if it wants to preserve any of the above information.\n *\n * This function also caches the following properties in the 'dir' object:\n *\n * pbaDirCache (of the last directory sector read, if any)\n * sectorDirCache (of the last directory sector read, if any)\n *\n * Also, the caller must also set the following 'dir' helper properties, so that clusters\n * can be located and converted to sectors (see convertClusterToSectors):\n *\n * lbaFAT\n * lbaData\n * cbSector\n * iClusterMax\n * nClusterSecs\n * nFATBits\n *\n * @this {Disk}\n * @param {Object} dir (to be filled in)\n * @param {number} pba (a sector of the directory)\n * @param {number} i (an entry in the directory sector, 0-based)\n * @returns {boolean} true if entry was returned (even if invalid/deleted), false if no more entries\n */\n getDirEntry(dir, pba, i)\n {\n if (!dir.sectorDirCache || !dir.pbaDirCache || dir.pbaDirCache != pba) {\n dir.pbaDirCache = pba;\n dir.sectorDirCache = this.getSector(dir.pbaDirCache);\n if (DEBUG && this.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.printMessage(this.dumpSector(dir.sectorDirCache, dir.pbaDirCache, dir.sDir));\n }\n }\n if (dir.sectorDirCache) {\n var off = i * DiskAPI.DIRENT.LENGTH;\n var b = this.getSectorData(dir.sectorDirCache, off, 1);\n if (b == DiskAPI.DIRENT.UNUSED) {\n return false;\n }\n if (b == DiskAPI.DIRENT.INVALID) {\n dir.sName = null;\n return true;\n }\n dir.sName = Str.trim(this.getSectorString(dir.sectorDirCache, off + DiskAPI.DIRENT.NAME, 8));\n var s = Str.trim(this.getSectorString(dir.sectorDirCache, off + DiskAPI.DIRENT.EXT, 3));\n if (s.length) dir.sName += '.' + s;\n dir.bAttr = this.getSectorData(dir.sectorDirCache, off + DiskAPI.DIRENT.ATTR, 1);\n dir.cbSize = this.getSectorData(dir.sectorDirCache, off + DiskAPI.DIRENT.SIZE, 2);\n dir.iCluster = this.getSectorData(dir.sectorDirCache, off + DiskAPI.DIRENT.CLUSTER, 2);\n dir.apba = this.convertClusterToSectors(dir);\n return true;\n }\n return false;\n }\n\n /**\n * convertClusterToSectors(dir)\n *\n * @this {Disk}\n * @param {Object} dir\n * @return {Array.<number>} of PBAs (physical block addresses)\n */\n convertClusterToSectors(dir)\n {\n var apba = [];\n var iCluster = dir.iCluster;\n if (iCluster) {\n do {\n if (iCluster < DiskAPI.FAT12.CLUSNUM_MIN) {\n\n break;\n }\n var lba = dir.lbaData + ((iCluster - DiskAPI.FAT12.CLUSNUM_MIN) * dir.nClusterSecs);\n for (var i = 0; i < dir.nClusterSecs; i++) {\n apba.push(dir.pbaVolume + lba++);\n }\n iCluster = this.getClusterEntry(dir, iCluster, 0) | this.getClusterEntry(dir, iCluster, 1);\n } while (iCluster <= dir.iClusterMax);\n\n }\n return apba;\n }\n\n /**\n * getClusterEntry(dir, iCluster, iByte)\n *\n * @this {Disk}\n * @param {Object} dir\n * @param {number} iCluster\n * @param {number} iByte (0 for low byte of cluster entry, 1 for high byte)\n * @return {number}\n */\n getClusterEntry(dir, iCluster, iByte)\n {\n var w = 0;\n var cbitsSector = dir.cbSector * 8;\n var offBits = dir.nFATBits * iCluster + (iByte? 8 : 0);\n var iSector = (offBits / cbitsSector) | 0;\n if (!dir.sectorFATCache || !dir.lbaFATCache || dir.lbaFATCache != dir.lbaFAT + iSector) {\n dir.lbaFATCache = dir.lbaFAT + iSector;\n dir.sectorFATCache = this.getSector(dir.pbaVolume + dir.lbaFATCache);\n }\n if (dir.sectorFATCache) {\n offBits = (offBits % cbitsSector) | 0;\n var off = (offBits >> 3);\n w = this.getSectorData(dir.sectorFATCache, off, 1);\n if (!iByte) {\n if (offBits & 0x7) w >>= 4;\n } else {\n if (dir.nFATBits == 16) {\n w <<= 8;\n } else {\n\n if (offBits & 0x7) {\n w <<= 4;\n } else {\n w = (w & 0xf) << 8;\n }\n }\n }\n }\n return w;\n }\n\n /**\n * getSector(pba)\n *\n * @this {Disk}\n * @param {number} pba (physical block address)\n * @return {Object|null} sector\n */\n getSector(pba)\n {\n var nSectorsPerCylinder = this.nHeads * this.nSectors;\n var iCylinder = (pba / nSectorsPerCylinder) | 0;\n if (iCylinder < this.nCylinders) {\n var nSectorsRemaining = (pba % nSectorsPerCylinder);\n var iHead = (nSectorsRemaining / this.nSectors) | 0;\n /*\n * PBA numbers are 0-based, but the sector numbers in CHS addressing are 1-based, so add one to iSector\n */\n var iSector = (nSectorsRemaining % this.nSectors) + 1;\n return this.seek(iCylinder, iHead, iSector);\n }\n return null;\n }\n\n /**\n * getSectorData(sector, off, len)\n *\n * WARNING: This function is restricted to reading data contained ENTIRELY within the specified sector.\n *\n * NOTE: Yes, this function is not the most efficient way to read a byte/word/dword value from within a sector,\n * but given the different states a sector may be in, it's certainly the simplest and safest, and since this is\n * only used by buildFileTable() and its progeny, it's not clear that we need to be superfast anyway.\n *\n * @this {Disk}\n * @param {Object} sector\n * @param {number} off (byte offset)\n * @param {number} len (1 to 4 bytes)\n * @return {number}\n */\n getSectorData(sector, off, len)\n {\n var dw = 0;\n var nShift = 0;\n\n while (len--) {\n\n var b = this.read(sector, off++);\n\n if (b < 0) break;\n dw |= (b << nShift);\n nShift += 8;\n }\n return dw;\n }\n\n /**\n * getSectorString(sector, off, len)\n *\n * WARNING: This function is restricted to reading a string contained ENTIRELY within the specified sector.\n *\n * @this {Disk}\n * @param {Object} sector\n * @param {number} off (byte offset)\n * @param {number} len (use -1 to read a null-terminated string)\n * @return {string}\n */\n getSectorString(sector, off, len)\n {\n var s = \"\";\n while (len--) {\n var b = this.read(sector, off++);\n if (b <= 0) break;\n s += String.fromCharCode(b);\n }\n return s;\n }\n\n /**\n * updateSector(file, pba, off)\n *\n * Like getSector(), this must convert a PBA into CHS values; consider factoring that conversion code out.\n *\n * @this {Disk}\n * @param {FileInfo} file\n * @param {number} pba (physical block address from the file's apba)\n * @param {number} off (file offset corresponding to the given pba of the given file)\n * @return {boolean} true if successfully updated, false if not\n */\n updateSector(file, pba, off)\n {\n var nSectorsPerCylinder = this.nHeads * this.nSectors;\n var iCylinder = (pba / nSectorsPerCylinder) | 0;\n var nSectorsRemaining = (pba % nSectorsPerCylinder);\n var iHead = (nSectorsRemaining / this.nSectors) | 0;\n var iSector = (nSectorsRemaining % this.nSectors);\n var cylinder, head, sector;\n if ((cylinder = this.aDiskData[iCylinder]) && (head = cylinder[iHead]) && (sector = head[iSector])) {\n\n if (sector['file']) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage('\"' + sector['file'].sPath + '\" cross-linked at offset ' + sector['file'].offFile + ' with \"' + file.sPath + '\" at offset ' + off);\n }\n return false;\n }\n sector['file'] = file;\n sector.offFile = off;\n return true;\n }\n if (DEBUG && this.messageEnabled()) this.printMessage(\"unable to map PBA \" + pba + \" to CHS\");\n return false;\n }\n\n /**\n * initSector(sector, iCylinder, iHead, iSector, cbSector, dwPattern)\n *\n * Ensures every sector has ALL the properties of a proper Sector object; ie:\n *\n * 'sector': sector number\n * 'length': size of the sector, in bytes\n * 'data': array of dwords\n * 'pattern': dword pattern to use for empty or partial sectors (null for unread remote sectors)\n *\n * In addition, we will maintain the following information on a per-sector basis,\n * as sectors are modified:\n *\n * iModify: index of first modified dword in sector\n * cModify: number of modified dwords in sector\n * fDirty: true if sector is dirty, false if clean (or cleaning in progress)\n *\n * @this {Disk}\n * @param {Object} sector\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} [iSector]\n * @param {number} [cbSector]\n * @param {number|null} [dwPattern]\n * @return {Object}\n */\n initSector(sector, iCylinder, iHead, iSector, cbSector, dwPattern)\n {\n if (!sector) {\n sector = {'sector': iSector, 'length': cbSector, 'data': [], 'pattern': dwPattern};\n }\n sector.iCylinder = iCylinder;\n sector.iHead = iHead;\n sector.iModify = sector.cModify = 0;\n sector.fDirty = false;\n return sector;\n }\n\n /**\n * connectRemoteDisk(sDiskPath)\n *\n * Unlike disconnect(), we don't issue the connect request ourselves; instead, we piggyback on the existing\n * preload code in load() to establish the connection. That, in turn, will trigger a call to mount(), which\n * will check fOnDemand and set fRemote if the connection was successful.\n *\n * @this {Disk}\n * @param {string} sDiskPath\n * @return {string} is the URL connection string required to connect to sDiskPath\n */\n connectRemoteDisk(sDiskPath)\n {\n var sParms = DiskAPI.QUERY.ACTION + '=' + DiskAPI.ACTION.OPEN;\n sParms += '&' + DiskAPI.QUERY.VOLUME + '=' + sDiskPath;\n sParms += '&' + DiskAPI.QUERY.MODE + '=' + this.mode;\n sParms += '&' + DiskAPI.QUERY.CHS + '=' + this.nCylinders + ':' + this.nHeads + ':' + this.nSectors + ':' + this.cbSector;\n sParms += '&' + DiskAPI.QUERY.MACHINE + '=' + this.controller.getMachineID();\n sParms += '&' + DiskAPI.QUERY.USER + '=' + this.controller.getUserID();\n return Web.getHost() + DiskAPI.ENDPOINT + '?' + sParms;\n }\n\n /**\n * readRemoteSectors(iCylinder, iHead, iSector, nSectors, fAsync, done)\n *\n * @this {Disk}\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nSectors (to read)\n * @param {boolean} fAsync\n * @param {function(number,boolean)} [done]\n */\n readRemoteSectors(iCylinder, iHead, iSector, nSectors, fAsync, done)\n {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"readRemoteSectors(CHS=\" + iCylinder + ':' + iHead + ':' + iSector + \",N=\" + nSectors + \")\");\n }\n\n if (this.fRemote) {\n var sParms = DiskAPI.QUERY.ACTION + '=' + DiskAPI.ACTION.READ;\n sParms += '&' + DiskAPI.QUERY.VOLUME + '=' + this.sDiskPath;\n sParms += '&' + DiskAPI.QUERY.CHS + '=' + this.nCylinders + ':' + this.nHeads + ':' + this.nSectors + ':' + this.cbSector;\n sParms += '&' + DiskAPI.QUERY.ADDR + '=' + iCylinder + ':' + iHead + ':' + iSector + ':' + nSectors;\n sParms += '&' + DiskAPI.QUERY.MACHINE + '=' + this.controller.getMachineID();\n sParms += '&' + DiskAPI.QUERY.USER + '=' + this.controller.getUserID();\n var disk = this;\n var sDiskURL = Web.getHost() + DiskAPI.ENDPOINT + '?' + sParms;\n Web.getResource(sDiskURL, null, fAsync, function(sURL, sResponse, nErrorCode) {\n disk.doneReadRemoteSectors(sURL, sResponse, nErrorCode, [iCylinder, iHead, iSector, nSectors, fAsync, done]);\n });\n return;\n }\n if (done) done(-1, false);\n }\n\n /**\n * doneReadRemoteSectors(sURLName, sURLData, nErrorCode, aRequest)\n *\n * @this {Disk}\n * @param {string} sURLName\n * @param {string} sURLData\n * @param {number} nErrorCode\n * @param {Array} aRequest ([iCylinder, iHead, iSector, nSectors, fAsync, done])\n */\n doneReadRemoteSectors(sURLName, sURLData, nErrorCode, aRequest)\n {\n var fAsync = false;\n\n var iCylinder = aRequest[0];\n var iHead = aRequest[1];\n var iSector = aRequest[2];\n var nSectors = aRequest[3];\n\n if (!nErrorCode) {\n var abData = JSON.parse(sURLData);\n var offData = 0;\n while (nSectors--) {\n /*\n * We call seek with fWrite == true to prevent seek() from triggering another call\n * to readRemoteSectors() and endlessly recursing. That also forces seek() to:\n *\n * 1) zero the sector's 'pattern'\n * 2) disable warning about reading an uninitialized sector\n *\n * We KNOW this is an uninitialized sector, because we're about to initialize it.\n */\n var sector = this.seek(iCylinder, iHead, iSector, true);\n if (!sector) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"doneReadRemoteSectors(): seek(CHS=\" + iCylinder + ':' + iHead + ':' + iSector + \") failed\");\n }\n break;\n }\n this.fill(sector, abData, offData);\n offData += sector['length'];\n /*\n * We happen to know that when seek() calls readRemoteSectors(), it limits the number of sectors\n * to the current track, so the only variable we need to advance is iSector.\n */\n iSector++;\n }\n fAsync = aRequest[4];\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"doneReadRemoteSectors(CHS=\" + iCylinder + ':' + iHead + ':' + iSector + \",N=\" + nSectors + \") returned error \" + nErrorCode);\n }\n }\n var done = aRequest[5];\n if (done) done(nErrorCode, fAsync);\n }\n\n /**\n * writeRemoteSectors(iCylinder, iHead, iSector, nSectors, abSectors, fAsync)\n *\n * Writes to a remote disk are performed on a timer-driven basis. When a sector is modified for the first time,\n * a reference to that sector is \"pushed\" onto (ie, appended to the end of) aDirtySectors, and if aDirtySectors was\n * originally empty, then a REMOTE_WRITE_DELAY timer is set.\n *\n * When the timer fires, the first batch of contiguous sectors is sent off the server, and when the server responds\n * (ie, when cleanDirtySectors() is called), if the response indicates success, every sector that was sent is marked\n * clean -- unless one or more writes to the sector occurred in the meantime, which we track through a per-sector\n * fDirty flag.\n *\n * @this {Disk}\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nSectors (to write)\n * @param {Array.<number>} abSectors\n * @param {boolean} fAsync\n * @return {boolean|Array}\n */\n writeRemoteSectors(iCylinder, iHead, iSector, nSectors, abSectors, fAsync)\n {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"writeRemoteSectors(CHS=\" + iCylinder + ':' + iHead + ':' + iSector + \",N=\" + nSectors + \")\");\n }\n\n if (this.fRemote) {\n var dataPost = {};\n this.fWriteInProgress = true;\n dataPost[DiskAPI.QUERY.ACTION] = DiskAPI.ACTION.WRITE;\n dataPost[DiskAPI.QUERY.VOLUME] = this.sDiskPath;\n dataPost[DiskAPI.QUERY.CHS] = this.nCylinders + ':' + this.nHeads + ':' + this.nSectors + ':' + this.cbSector;\n dataPost[DiskAPI.QUERY.ADDR] = iCylinder + ':' + iHead + ':' + iSector + ':' + nSectors;\n dataPost[DiskAPI.QUERY.MACHINE] = this.controller.getMachineID();\n dataPost[DiskAPI.QUERY.USER] = this.controller.getUserID();\n dataPost[DiskAPI.QUERY.DATA] = JSON.stringify(abSectors);\n var disk = this;\n var sDiskURL = Web.getHost() + DiskAPI.ENDPOINT;\n Web.getResource(sDiskURL, dataPost, fAsync, function(sURL, sResponse, nErrorCode) {\n disk.doneWriteRemoteSectors(sURL, sResponse, nErrorCode, [iCylinder, iHead, iSector, nSectors, fAsync]);\n });\n }\n return false;\n }\n\n /**\n * doneWriteRemoteSectors(sURLName, sURLData, nErrorCode, aRequest)\n *\n * @this {Disk}\n * @param {string} sURLName\n * @param {string} sURLData\n * @param {number} nErrorCode\n * @param {Array} aRequest ([iCylinder, iHead, iSector, nSectors, fAsync])\n */\n doneWriteRemoteSectors(sURLName, sURLData, nErrorCode, aRequest)\n {\n var iCylinder = aRequest[0];\n var iHead = aRequest[1];\n var iSector = aRequest[2];\n var nSectors = aRequest[3];\n var fAsync = aRequest[4];\n this.fWriteInProgress = false;\n\n if (iCylinder >= 0 && iCylinder < this.aDiskData.length && iHead >= 0 && iHead < this.aDiskData[iCylinder].length) {\n for (var i = iSector - 1; nSectors-- > 0 && i >= 0 && i < this.aDiskData[iCylinder][iHead].length; i++) {\n var sector = this.aDiskData[iCylinder][iHead][i];\n\n if (!nErrorCode) {\n if (!sector.fDirty) {\n sector.iModify = sector.cModify = 0;\n }\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"doneWriteRemoteSectors(CHS=\" + iCylinder + ':' + iHead + ':' + sector['sector'] + \") returned error \" + nErrorCode);\n }\n this.queueDirtySector(sector, false);\n }\n }\n }\n if (fAsync) this.updateWriteTimer();\n }\n\n /**\n * disconnectRemoteDisk()\n *\n * This is called by our powerDown() notification handler. If fRemote is true, we issue the disconnect\n * request and then immediately set fRemote to false; we don't wait for (or test) the response.\n *\n * @this {Disk}\n */\n disconnectRemoteDisk()\n {\n if (this.fRemote) {\n var sParms = DiskAPI.QUERY.ACTION + '=' + DiskAPI.ACTION.CLOSE;\n sParms += '&' + DiskAPI.QUERY.VOLUME + '=' + this.sDiskPath;\n sParms += '&' + DiskAPI.QUERY.MACHINE + '=' + this.controller.getMachineID();\n sParms += '&' + DiskAPI.QUERY.USER + '=' + this.controller.getUserID();\n var sDiskURL = Web.getHost() + DiskAPI.ENDPOINT + '?' + sParms;\n Web.getResource(sDiskURL, null, true);\n this.fRemote = false;\n }\n }\n\n /**\n * queueDirtySector(sector, fAsync)\n *\n * Mark the specified sector as dirty, add it to the queue (aDirtySectors) if not already added,\n * and establish a timeout handler (findDirtySectors) if not already established.\n *\n * A freshly dirtied sector should sit in the queue for a short period of time (eg, 2 seconds)\n * before we attempt to write it; that is, a REMOTE_WRITE_DELAY timer should start ticking again\n * for any sector that is rewritten. However, there will be exceptions; for example, when a sector\n * is finally written, we want to take advantage of the write request to write any additional dirty\n * sectors that follow it, even if those additional sectors were written less than 2 seconds ago.\n *\n * @this {Disk}\n * @param {Object} sector\n * @param {boolean} fAsync (true to update write timer, false to not)\n * @return {boolean} true if write timer set, false if not\n */\n queueDirtySector(sector, fAsync)\n {\n sector.fDirty = true;\n\n var j = this.aDirtySectors.indexOf(sector);\n if (j >= 0) {\n this.aDirtySectors.splice(j, 1);\n this.aDirtyTimestamps.splice(j, 1);\n }\n this.aDirtySectors.push(sector);\n this.aDirtyTimestamps.push(Usr.getTime());\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"queueDirtySector(CHS=\" + sector.iCylinder + ':' + sector.iHead + ':' + sector['sector'] + \"): \" + this.aDirtySectors.length + \" dirty\");\n }\n\n return fAsync && this.updateWriteTimer();\n }\n\n /**\n * updateWriteTimer()\n *\n * If a timer is already active, make sure it's still valid (ie, the time the timer is scheduled to fire is\n * >= the timestamp of the next dirty sector + REMOTE_WRITE_DELAY); if not, cancel the timer and start a new one.\n *\n * @this {Disk}\n * @return {boolean} true if write timer set, false if not\n */\n updateWriteTimer()\n {\n if (this.aDirtySectors.length) {\n var msWrite = this.aDirtyTimestamps[0] + Disk.REMOTE_WRITE_DELAY;\n if (this.timerWrite) {\n if (this.msTimerWrite < msWrite) {\n clearTimeout(this.timerWrite);\n this.timerWrite = null;\n }\n }\n if (!this.timerWrite) {\n var obj = this;\n var msNow = Usr.getTime();\n var msDelay = msWrite - msNow;\n if (msDelay < 0) msDelay = 0;\n if (msDelay > Disk.REMOTE_WRITE_DELAY) msDelay = Disk.REMOTE_WRITE_DELAY;\n this.timerWrite = setTimeout(function() {\n obj.findDirtySectors(true);\n }, msDelay);\n this.msTimerWrite = msNow + msDelay;\n }\n } else {\n if (this.timerWrite) {\n clearTimeout(this.timerWrite);\n this.timerWrite = null;\n }\n }\n return this.timerWrite !== null;\n }\n\n /**\n * findDirtySectors(fAsync)\n *\n * Starting with the oldest dirty sector in the queue (aDirtySectors), determine the longest contiguous stretch of\n * dirty sectors (currently limited to the same track), mark them all as not dirty, and then call writeRemoteSectors().\n *\n * @this {Disk}\n * @param {boolean} fAsync is true if this function is being called asynchronously, false otherwise\n * @return {boolean|Array} false if no dirty sectors, otherwise true (or a response array if not fAsync)\n */\n findDirtySectors(fAsync)\n {\n if (fAsync) {\n this.timerWrite = null;\n }\n var sector = this.aDirtySectors[0];\n if (sector) {\n var iCylinder = sector.iCylinder;\n var iHead = sector.iHead;\n var iSector = sector['sector'];\n var nSectors = 0;\n var abSectors = [];\n for (var i = iSector - 1; i < this.aDiskData[iCylinder][iHead].length; i++) {\n var sectorNext = this.aDiskData[iCylinder][iHead][i];\n if (!sectorNext.fDirty) break;\n var j = this.aDirtySectors.indexOf(sectorNext);\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"findDirtySectors(CHS=\" + iCylinder + ':' + iHead + ':' + sectorNext['sector'] + \")\");\n }\n this.aDirtySectors.splice(j, 1);\n this.aDirtyTimestamps.splice(j, 1);\n abSectors = abSectors.concat(this.toBytes(sectorNext));\n sectorNext.fDirty = false;\n nSectors++;\n }\n\n var response = this.writeRemoteSectors(iCylinder, iHead, iSector, nSectors, abSectors, fAsync);\n return fAsync || response;\n }\n return false;\n }\n\n /**\n * info()\n *\n * @this {Disk}\n * @return {Array} containing: [nCylinders, nHeads, nSectorsPerTrack, nBytesPerSector]\n */\n info()\n {\n if (!this.aDiskData.length) {\n return [0, 0, 0, 0];\n }\n return [this.aDiskData.length, this.aDiskData[0].length, this.aDiskData[0][0].length, this.aDiskData[0][0][0]['length']];\n }\n\n /**\n * seek(iCylinder, iHead, iSector, fWrite, done)\n *\n * TODO: There's some dodgy code in seek() that allows floppy images to be dynamically\n * reconfigured with more heads and/or sectors/track, and it does so by peeking at more drive\n * properties. That code used to be in the FDC component, where it was perfectly reasonable\n * to access those properties. We need a cleaner interface back to the drive, similar to the\n * info() interface we provide to the controller.\n *\n * Whether or not the \"dynamic reconfiguration\" feature itself is perfectly reasonable is,\n * of course, a separate question.\n *\n * @this {Disk}\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {boolean} [fWrite]\n * @param {function(Object,boolean)} [done]\n * @return {Object|null} is the requested sector, or null if not found (or not available yet)\n */\n seek(iCylinder, iHead, iSector, fWrite, done)\n {\n var sector = null;\n var drive = this.drive;\n var cylinder = this.aDiskData[iCylinder];\n if (cylinder) {\n var i;\n var track = cylinder[iHead];\n /*\n * The following code allows a single-sided diskette image to be reformatted (ie, \"expanded\")\n * as a double-sided image, provided the drive has more than one head (see drive.nHeads).\n */\n if (!track && drive.bFormatting && iHead < drive.nHeads) {\n track = cylinder[iHead] = new Array(drive.bSectorEnd);\n for (i = 0; i < track.length; i++) {\n track[i] = this.initSector(null, iCylinder, iHead, i + 1, drive.nBytes, 0);\n }\n /*\n * TODO: This is more dodginess, because we can't be certain that every cylinder on the disk\n * will receive the same \"expanded\" treatment, but functions like getSector() rely on instance\n * properties (eg, this.nHeads), on the assumption that the disk's geometry is homogeneous.\n */\n if (this.nHeads <= iHead) this.nHeads = iHead + 1;\n }\n if (track) {\n for (i = 0; i < track.length; i++) {\n if (track[i] && track[i]['sector'] == iSector) {\n /*\n * If the sector's pattern is null, then this sector's true contents have not yet\n * been fetched from the server.\n */\n sector = track[i];\n if (sector['pattern'] === null) {\n if (fWrite) {\n /*\n * Optimization: if the caller has explicitly told us that they're about to WRITE to the\n * sector, then we shouldn't need to read it from the server; assume a zero pattern and return.\n */\n sector['pattern'] = 0;\n } else {\n var nSectors = 1;\n /*\n * We know we need to read at least 1 sector, but let's count the number of trailing sectors\n * on the same track that may also be required.\n */\n while (++i < track.length) {\n if (track[i]['pattern'] === null) nSectors++;\n }\n this.readRemoteSectors(iCylinder, iHead, iSector, nSectors, done != null, function onReadRemoteComplete(err, fAsync) {\n if (err) sector = null;\n if (done) { //noinspection JSReferencingMutableVariableFromClosure\n done(sector, fAsync);\n }\n });\n return done? null : sector;\n }\n }\n break;\n }\n }\n /*\n * The following code allows an 8-sector track to be reformatted (ie, \"expanded\") as a 9-sector track.\n */\n if (!sector && drive.bFormatting && drive.bSector == 9) {\n sector = track[i] = this.initSector(null, iCylinder, iHead, drive.bSector, drive.nBytes, 0);\n /*\n * TODO: This is more dodginess, because we can't be certain that every track on the disk\n * will receive the same \"expanded\" treatment, but functions like getSector() rely on instance\n * properties (eg, this.nSectors), on the assumption that the disk's geometry is homogeneous.\n */\n if (this.nSectors < drive.bSector) this.nSectors = drive.bSector;\n }\n }\n }\n if (done) done(sector, false);\n return sector;\n }\n\n /**\n * fill(sector, ab, off)\n *\n * @this {Disk}\n * @param {Object} sector\n * @param {*} ab (technically, this should be typed as Array.<number> but I'm having trouble coercing JSON.parse() to that)\n * @param {number} off\n */\n fill(sector, ab, off)\n {\n var cdw = sector['length'] >> 2;\n var adw = new Array(cdw);\n for (var idw = 0; idw < cdw; idw++) {\n adw[idw] = ab[off] | (ab[off + 1] << 8) | (ab[off + 2] << 16) | (ab[off + 3] << 24);\n off += 4;\n }\n sector['data'] = adw;\n /*\n * TODO: Consider taking this opportunity to shrink 'data' down by the number of dwords at the end of the buffer that\n * contain the same pattern, and setting 'pattern' accordingly.\n */\n }\n\n /**\n * toBytes(sector)\n *\n * @this {Disk}\n * @param {Object} sector\n * @return {Array.<number>} is an array of bytes\n */\n toBytes(sector)\n {\n var cb = sector['length'];\n var ab = new Array(cb);\n var ib = 0;\n var cdw = cb >> 2;\n var adw = sector['data'];\n var dwPattern = sector['pattern'];\n for (var idw = 0; idw < cdw; idw++) {\n var dw = (idw < adw.length? adw[idw] : dwPattern);\n ab[ib++] = dw & 0xff;\n ab[ib++] = (dw >> 8) & 0xff;\n ab[ib++] = (dw >> 16) & 0xff;\n ab[ib++] = (dw >> 24) & 0xff;\n }\n return ab;\n }\n\n /**\n * read(sector, ibSector, fCompare)\n *\n * @this {Disk}\n * @param {Object} sector (returned from a previous seek)\n * @param {number} ibSector a byte index within the given sector\n * @param {boolean} [fCompare] is true if this write-compare read\n * @return {number} the specified (unsigned) byte, or -1 if no more data in the sector\n */\n read(sector, ibSector, fCompare)\n {\n var b = -1;\n if (sector) {\n if (DEBUG && !ibSector && !fCompare && this.messageEnabled()) {\n this.printMessage('read(\"' + this.sDiskFile + '\",CHS=' + sector.iCylinder + ':' + sector.iHead + ':' + sector['sector'] + ')');\n }\n if (ibSector < sector['length']) {\n var adw = sector['data'];\n var idw = ibSector >> 2;\n var dw = (idw < adw.length ? adw[idw] : sector['pattern']);\n b = ((dw >> ((ibSector & 0x3) << 3)) & 0xff);\n }\n }\n return b;\n }\n\n /**\n * write(sector, ibSector, b)\n *\n * @this {Disk}\n * @param {Object} sector (returned from a previous seek)\n * @param {number} ibSector a byte index within the given sector\n * @param {number} b the byte value to write\n * @return {boolean|null} true if write successful, false if write-protected, null if out of bounds\n */\n write(sector, ibSector, b)\n {\n if (this.fWriteProtected)\n return false;\n\n if (DEBUG && !ibSector && this.messageEnabled()) {\n this.printMessage('write(\"' + this.sDiskFile + '\",CHS=' + sector.iCylinder + ':' + sector.iHead + ':' + sector['sector'] + ')');\n }\n\n if (ibSector < sector['length']) {\n if (b != this.read(sector, ibSector, true)) {\n var adw = sector['data'];\n var dwPattern = sector['pattern'];\n var idw = ibSector >> 2;\n var nShift = (ibSector & 0x3) << 3;\n\n /*\n * Ensure every byte up to the specified byte is properly initialized.\n */\n for (var i = adw.length; i <= idw; i++) adw[i] = dwPattern;\n\n if (!sector.cModify) {\n sector.iModify = idw;\n sector.cModify = 1;\n } else if (idw < sector.iModify) {\n sector.cModify += sector.iModify - idw;\n sector.iModify = idw;\n } else if (idw >= sector.iModify + sector.cModify) {\n sector.cModify += idw - (sector.iModify + sector.cModify) + 1;\n }\n adw[idw] = (adw[idw] & ~(0xff << nShift)) | (b << nShift);\n\n if (this.fRemote) this.queueDirtySector(sector, true);\n }\n return true;\n }\n return null;\n }\n\n /**\n * encodeAsBase64()\n *\n * @this {Disk}\n * @return {string}\n */\n encodeAsBase64()\n {\n /*\n * Gross, but simple; more importantly, it works -- at least for disks of typical floppy magnitude.\n */\n var s = \"\", pba = 0, sector;\n while ((sector = this.getSector(pba++))) {\n for (var off = 0, len = sector['length']; off < len; off++) {\n s += String.fromCharCode(this.getSectorData(sector, off, 1));\n }\n }\n return btoa(s);\n }\n\n /**\n * save()\n *\n * The first array entry contains some disk information:\n *\n * [sDiskPath, dwChecksum, nCylinders, nHeads, nSectors, cbSector]\n *\n * Each subsequent entry in the returned array contains the following:\n *\n * [iCylinder, iHead, iSector, iModify, [...]]\n *\n * where [...] is an array of modified dword(s) in the corresponding sector.\n *\n * @this {Disk}\n * @return {Array} of modified sectors\n */\n save()\n {\n var i = 0;\n var deltas = [];\n deltas[i++] = [this.sDiskPath, this.dwChecksum, this.nCylinders, this.nHeads, this.nSectors, this.cbSector];\n if (!this.fRemote && !this.fWriteProtected) {\n var aDiskData = this.aDiskData;\n for (var iCylinder = 0; iCylinder < aDiskData.length; iCylinder++) {\n for (var iHead = 0; iHead < aDiskData[iCylinder].length; iHead++) {\n for (var iSector = 0; iSector < aDiskData[iCylinder][iHead].length; iSector++) {\n var sector = aDiskData[iCylinder][iHead][iSector];\n if (sector && sector.cModify) {\n var mods = [], n = 0;\n var iModify = sector.iModify, iModifyLimit = sector.iModify + sector.cModify;\n while (iModify < iModifyLimit) {\n mods[n++] = sector['data'][iModify++];\n }\n deltas[i++] = [iCylinder, iHead, iSector, sector.iModify, mods];\n }\n }\n }\n }\n }\n if (DEBUG && this.messageEnabled()) {\n this.printMessage('save(\"' + this.sDiskName + '\"): saved ' + (deltas.length - 1) + ' change(s)');\n }\n return deltas;\n }\n\n /**\n * restore(deltas)\n *\n * The first array entry contains some disk information:\n *\n * [sDiskPath, dwChecksum, nCylinders, nHeads, nSectors, cbSector]\n *\n * Each subsequent entry in the supplied array contains the following:\n *\n * [iCylinder, iHead, iSector, iModify, [...]]\n *\n * where [...] is an array of modified dword(s) in the corresponding sector.\n *\n * @this {Disk}\n * @param {Array} deltas\n * @return {number} 0 if no changes applied, -1 if an error occurred, otherwise the number of sectors modified\n */\n restore(deltas)\n {\n /*\n * If deltas is undefined, that's not necessarily an error; the controller may simply be (re)initializing\n * itself (although neither controller should be calling restore() under those conditions anymore).\n */\n var nChanges = 0;\n var sReason = \"unsupported restore format\";\n /*\n * I originally added a check for aDiskData here on the assumption that if there was an error loading\n * a disk image, we will have already notified the user, so any additional errors about differing checksums,\n * failure to restore the disk state, etc, would just be annoying. HOWEVER, HDC will create an empty disk\n * image if its initialization code discovers that no disk was loaded earlier (see verifyDrive). So while\n * checking aDiskData is still a good idea, be aware that it won't necessarily avoid redundant error messages\n * (at least in the case of HDC).\n */\n if (deltas && deltas.length > 0) {\n\n var i = 0;\n var aDiskInfo = deltas[i++];\n\n if (aDiskInfo && aDiskInfo.length >= 2) {\n /*\n * Before getting to the checksum, we have to deal with a new situation: restoring an uninitialized\n * disk image from a complete set of deltas. And that is only possible if the disk was saved with the\n * original disk geometry.\n */\n if (!this.aDiskData.length && aDiskInfo.length >= 6) {\n this.create(DiskAPI.MODE.LOCAL, aDiskInfo[2], aDiskInfo[3], aDiskInfo[4], aDiskInfo[5]);\n /*\n * TODO: Consider setting a flag here that we can check at the end of the restore() function\n * that indicates we should recalculate dwChecksum, because we currently have an inconsistency\n * between local disks that are mounted via buildDisk() and the same disks that are \"remounted\"\n * later by this code; the former has the correct checksum, while the latter has a null checksum.\n *\n * As you can see below, we currently deal with this by simply ignoring null checksums....\n */\n }\n /*\n * v1.01 failed to indicate an error if either one of these failure conditions occurred. Although maybe\n * that's just as well, since v1.01 also failed to properly deal with situations where the user mounted\n * different diskette(s) prior to exiting (hopefully fixed in v1.02).\n *\n * UPDATE: We also check aDiskInfo[0] first, because if it's null, then presumably there was no previous\n * disk, and I'd like the addition of a disk to a machine to not be fatal to the restoration process.\n */\n else if (aDiskInfo[0] != null) {\n if (aDiskInfo[1] != null && this.dwChecksum != null && aDiskInfo[1] != this.dwChecksum) {\n sReason = \"original checksum (\" + aDiskInfo[1] + \") differs from current checksum (\" + this.dwChecksum + \")\";\n nChanges = -2;\n }\n /*\n * Checksum is more important than disk path, and for now, I want the flexibility to move disk images.\n *\n * else if (aDiskInfo[0] != this.sDiskPath) {\n * sReason = \"original path '\" + aDiskInfo[0] + \"' differs from current path '\" + this.sDiskPath + \"'\";\n * nChanges = -1;\n * }\n */\n }\n }\n\n if (!this.aDiskData.length) nChanges = -1;\n\n while (i < deltas.length && nChanges >= 0) {\n var m = 0;\n var mod = deltas[i++];\n var iCylinder = mod[m++];\n var iHead = mod[m++];\n var iSector = mod[m++];\n /*\n * Note the buried test for write-protection. Yes, an invariant condition should be tested\n * outside the loop, not inside, but (a) it's a trivial test, (b) the test should never fail\n * because save() should never generate any mods for a write-protected disk, and (c) it\n * centralizes all the failure conditions we're currently checking (which, admittedly, ain't much).\n */\n if (iCylinder >= this.aDiskData.length || iHead >= this.aDiskData[iCylinder].length || iSector >= this.aDiskData[iCylinder][iHead].length) {\n sReason = \"sector (CHS=\" + iCylinder + ':' + iHead + ':' + iSector + \") out of range (\" + nChanges + \" changes applied)\";\n nChanges = -1;\n break;\n }\n if (this.fWriteProtected) {\n sReason = \"unable to modify write-protected disk\";\n nChanges = -1;\n break;\n }\n var iModify = mod[m++];\n var mods = mod[m++];\n var iModifyLimit = iModify + mods.length;\n var sector = this.aDiskData[iCylinder][iHead][iSector];\n if (!sector) continue;\n /*\n * Since write() now deals with empty/partial sectors, we no longer need to completely \"inflate\"\n * the sector prior to applying modifications. So let's just make sure that the sector is \"inflated\"\n * up to iModify.\n */\n var idw = sector['data'].length;\n while (idw < iModify) {\n sector['data'][idw++] = sector['pattern'];\n }\n var n = 0;\n sector.iModify = iModify;\n sector.cModify = mods.length;\n while (iModify < iModifyLimit) {\n sector['data'][iModify++] = mods[n++];\n }\n nChanges++;\n }\n }\n\n if (nChanges < 0) {\n /*\n * We're suppressing checksum messages for the general public for now....\n */\n if (DEBUG || nChanges != -2) {\n this.notice(\"Unable to restore disk '\" + this.sDiskName + \": \" + sReason);\n }\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage('restore(\"' + this.sDiskName + '\"): restored ' + nChanges + ' change(s)');\n }\n /*\n * Last but not least, rebuild the disk's file table if BACKTRACK or SYMBOLS support is enabled.\n */\n if (BACKTRACK || SYMBOLS) this.buildFileTable();\n }\n return nChanges;\n }\n\n /**\n * convertToJSON(fFormatted)\n *\n * We perform some RegExp massaging on the JSON data to eliminate unnecessary properties\n * (eg, 'length' values of 512, 'pattern' values of 0, and empty 'data' arrays, since those\n * are defaults).\n *\n * In addition, we first check every sector to see if it can be \"deflated\". Sectors that were\n * initially \"deflated\" should remain that way unless/until they were modified, so technically,\n * we could call deflateSector() just for modified sectors, but this isn't a common operation,\n * so it doesn't hurt to check every sector.\n *\n * @this {Disk}\n * @param {boolean} [fFormatted]\n * @return {string} containing the entire disk image as JSON-encoded data\n */\n convertToJSON(fFormatted)\n {\n var s, pba = 0, sector, sectorLast;\n\n while ((sector = this.getSector(pba++))) {\n this.deflateSector(sector);\n }\n\n s = JSON.stringify(this.aDiskData, function(key, value) {\n /*\n * If BACKTRACK support is enabled, we have to filter out any 'file' properties that may\n * be attached to the sector objects, lest we risk blowing the stack due to circular references.\n */\n if (key == 'file') {\n return undefined;\n }\n return value;\n });\n\n /*\n * Eliminate unnecessary default properties (eg, 'length' values of 512, 'pattern' values of 0, etc).\n */\n s = s.replace(/,\"length\":512/g, \"\").replace(/,\"pattern\":0/g, \"\").replace(/,\"data\":\\[]/g, \"\");\n\n /*\n * I don't really want to strip quotes from disk image property names, since I would have to put them\n * back again during mount() -- or whenever JSON.parse() is used instead of eval(). But I still remove\n * them temporarily, so that any remaining property names (eg, \"iModify\", \"cModify\", \"fDirty\") can\n * easily be stripped out, by virtue of their being the only quoted properties left. We then \"requote\"\n * all the property names that remain.\n */\n s = s.replace(/\"(sector|length|data|pattern)\":/g, \"$1:\");\n\n /*\n * The next line will remove any other numeric or boolean properties that were added at runtime, although\n * they may have completely different (\"minified\") names if the code has been compiled.\n */\n s = s.replace(/,\"[^\"]*\":([0-9]+|true|false)/g, \"\");\n s = s.replace(/(sector|length|data|pattern):/g, \"\\\"$1\\\":\");\n\n /*\n * Last but not least, insert line breaks after every object definition, to improve human readability\n * (but only if the caller asks for it).\n */\n if (fFormatted) s = s.replace(/([\\]}]),/g, \"$1,\\n\");\n return s;\n }\n\n /**\n * deflateSector(sector)\n *\n * This is just the first revision: it currently looks only at fully inflated sectors.\n *\n * @this {Disk}\n * @param {Object} sector\n */\n deflateSector(sector)\n {\n var adw = sector['data'];\n var cdw = adw.length;\n if ((cdw << 2) == sector['length']) {\n var idw = cdw - 1;\n var dwPattern = adw[idw], cDupes = 0;\n while (idw--) {\n if (adw[idw] !== dwPattern) break;\n cDupes++;\n }\n if (cDupes++) {\n adw.length = cdw - cDupes;\n sector['pattern'] = dwPattern;\n }\n }\n }\n\n /**\n * dumpSector(sector, pba, sDesc)\n *\n * @this {Disk}\n * @param {Object} sector (returned from a previous seek)\n * @param {number} [pba]\n * @param {string} [sDesc]\n * @return {string}\n */\n dumpSector(sector, pba, sDesc)\n {\n var sDump = \"\";\n if (DEBUG && sector) {\n if (pba != null) sDump += \"sector \" + pba + (sDesc? (\" for \" + sDesc) : \"\") + ':';\n var sBytes = \"\", sChars = \"\";\n var cbSector = sector['length'];\n var cdwData = sector['data'].length;\n var dw = 0;\n for (var i = 0; i < cbSector; i++) {\n if ((i % 16) === 0) {\n if (sDump) sDump += sBytes + ' ' + sChars + '\\n';\n sDump += Str.toHex(i, 4) + \": \";\n sBytes = sChars = \"\";\n }\n if ((i % 4) === 0) {\n var idw = i >> 2;\n dw = (idw < cdwData? sector['data'][idw] : sector['pattern']);\n }\n var b = dw & 0xff;\n dw >>>= 8;\n sBytes += Str.toHex(b, 2) + (i % 16 == 7? \"-\" : \" \");\n sChars += (b >= 32 && b < 128? String.fromCharCode(b) : \".\");\n }\n if (sBytes) sDump += sBytes + ' ' + sChars;\n }\n return sDump;\n }\n}\n\n/**\n * The default number of milliseconds to wait before writing a dirty sector back to a remote disk image\n *\n * @const {number}\n */\nDisk.REMOTE_WRITE_DELAY = 2000; // 2-second delay\n\n/*\n * A global disk count, used to form unique Disk component IDs (totally optional; for debugging purposes only)\n */\nDisk.nDisks = 0;\n\n/**\n * class FileInfo\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass FileInfo {\n /**\n * FileInfo(disk, sPath, sName, bAttr, cbSize, apba)\n *\n * To the basic file information below, loadSymbols() may also add:\n *\n * sModule\n * sDescription\n * aSegments[]\n *\n * which is indexed by 1-based segment numbers, where each aSegments[] element is an object\n * containing:\n *\n * offStart (file-relative offset of start of segment data)\n * offEnd (file-relative offset of end of segment data)\n * aEntries[]\n *\n * where aEntries is an array indexed by 1-based ordinals, where each aEntries[] element contains:\n *\n * [offset, symbol]\n *\n * where offset is relative to the segment's offStart value, and symbol is a string describing the\n * entry.\n *\n * NOTE: Although aEntries arrays are similar to the Debugger's aOffsets arrays, they are not\n * interchangeable data structures, because ours is ordered by ordinal, whereas aOffsets is\n * ordered by offset. We provide an interface, getModuleInfo(), to the Debugger that converts\n * our data into an intermediate array, aSymbols, which the Debugger then uses to build aOffsets.\n * It would be nice to avoid building that intermediate representation, but it's a side-effect of\n * the Debugger's earlier support for JSON-encoded MAP files.\n *\n * There will always be an offset at index 0 of an aEntries[] element, but some error or incomplete\n * symbolic information could result in a missing symbol at index 1, because symbol name processing is\n * separate from entry table processing.\n *\n * @param {Disk} disk\n * @param {string} sPath\n * @param {string} sName\n * @param {number} bAttr\n * @param {number} cbSize\n * @param {Array.<number>} apba\n */\n constructor(disk, sPath, sName, bAttr, cbSize, apba)\n {\n this.disk = disk;\n this.sPath = sPath;\n this.sName = sName;\n this.bAttr = bAttr;\n this.cbSize = cbSize;\n this.apba = apba;\n }\n\n /**\n * loadValue(offset, length)\n *\n * @this {FileInfo}\n * @param {number} offset\n * @param {number} [length] (1, 2 or 4 bytes; default is 2)\n * @return {number|undefined}\n */\n loadValue(offset, length)\n {\n var l;\n length = length || 2;\n var iSector = offset >> 9;\n var offSector = offset & 0x1ff;\n var sector = this.disk.getSector(this.apba[iSector]);\n if (sector) {\n /*\n * If the read is wholly contained within a sector, read it with one call.\n */\n if (offSector + length <= sector['length']) {\n return this.disk.getSectorData(sector, offSector, length);\n }\n /*\n * The spans a sector boundary, so we just call ourselves one byte at a time.\n */\n l = 0;\n var shift = 0;\n while (length--) {\n l |= this.loadValue(offset++, 1) << shift;\n shift += 8;\n }\n }\n return l;\n }\n\n /**\n * loadString(offset, length)\n *\n * @this {FileInfo}\n * @param {number} offset\n * @param {number} [length] (if omitted, then string must be zero-terminated)\n * @return {string}\n */\n loadString(offset, length)\n {\n var s = \"\";\n if (!length) length = -1;\n while (length--) {\n var b = this.loadValue(offset++, 1);\n if (!b) break;\n s += String.fromCharCode(b);\n }\n return s;\n }\n\n /**\n * loadField(aField, offset)\n *\n * @this {FileInfo}\n * @param {Array.<number>} aField\n * @param {number} [offset] (0 if not specified)\n * @return {number|undefined}\n */\n loadField(aField, offset)\n {\n return this.loadValue(aField[0] + (offset || 0), aField[1]);\n }\n\n /**\n * loadSegmentTable(offEntries, nEntries, nSegOffShift)\n *\n * @this {FileInfo}\n * @param {number} offEntries\n * @param {number} nEntries\n * @param {number} nSegOffShift\n */\n loadSegmentTable(offEntries, nEntries, nSegOffShift)\n {\n /*\n * Read the Segment Table entries now.\n */\n var iSegment = 1;\n this.aSegments = [];\n this.aOrdinals = []; // this is an optional array for quick ordinal-to-segment lookup\n\n if (DEBUG && this.disk.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.disk.printMessage(\"loadSegmentTable(\" + this.sPath + \",\" + Str.toHexLong(offEntries) + \",\" + Str.toHexWord(nEntries) + \")\");\n }\n\n while (nEntries--) {\n var offSegment = this.loadValue(offEntries) << nSegOffShift;\n if (offSegment) {\n var lenSegment = this.loadValue(offEntries + 2) || 0x10000; // 0 means 64K\n\n if (DEBUG && this.disk.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.disk.printMessage(\"segment \" + iSegment + \": offStart=\" + Str.toHexLong(offSegment) + \" offEnd=\" + Str.toHexLong(offSegment + lenSegment));\n }\n\n this.aSegments[iSegment++] = {offStart: offSegment, offEnd: offSegment + lenSegment - 1, aEntries: []};\n }\n offEntries += 8;\n }\n /*\n * Although not documented (at least not in any of the early Windows \"New Executable\" documents I've seen),\n * the Entry Table may also contain entries whose bSegment field is 0xFE, which doesn't correspond to a valid\n * segment number. That pseudo-segment number appears to be reserved for constants. Here are some examples\n * from a 3.1-vintage KRNL386.EXE:\n *\n * cannot find segment 254 (offset 0xF000) for symbol __ROMBIOS with ordinal 173\n * cannot find segment 254 (offset 0x0000) for symbol __0000H with ordinal 183\n * cannot find segment 254 (offset 0x0040) for symbol __0040H with ordinal 193\n * cannot find segment 254 (offset 0x0008) for symbol __AHINCR with ordinal 114\n * cannot find segment 254 (offset 0x0003) for symbol __AHSHIFT with ordinal 113\n * cannot find segment 254 (offset 0xA000) for symbol __A000H with ordinal 174\n * cannot find segment 254 (offset 0xB000) for symbol __B000H with ordinal 181\n * cannot find segment 254 (offset 0xC000) for symbol __C000H with ordinal 195\n * cannot find segment 254 (offset 0xB800) for symbol __B800H with ordinal 182\n * cannot find segment 254 (offset 0xD000) for symbol __D000H with ordinal 179\n * cannot find segment 254 (offset 0xE000) for symbol __E000H with ordinal 190\n * cannot find segment 254 (offset 0xF000) for symbol __F000H with ordinal 194\n * cannot find segment 254 (offset 0x0001) for symbol __WINFLAGS with ordinal 178\n *\n * The simplest way to handle those Entry Table entries is creating an additional (fake) aSegments table entry.\n */\n this.aSegments[0xFE] = {offStart: 0, offEnd: 0, aEntries: []};\n }\n\n /**\n * loadEntryTable(offEntries, offEntriesEnd)\n *\n * @this {FileInfo}\n * @param {number} offEntries\n * @param {number} offEntriesEnd\n */\n loadEntryTable(offEntries, offEntriesEnd)\n {\n var iOrdinal = 1;\n\n if (DEBUG && this.disk.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.disk.printMessage(\"loadEntryTable(\" + Str.toHexLong(offEntries) + \",\" + Str.toHexLong(offEntriesEnd) + \")\");\n }\n\n while (offEntries < offEntriesEnd) {\n\n var w = this.loadValue(offEntries);\n var bEntries = w & 0xff;\n if (!bEntries) break;\n var bSegment = w >> 8, iSegment;\n\n if (DEBUG && this.disk.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.disk.printMessage(\"bundle for segment \" + bSegment + \": \" + bEntries + \" entries @\" + Str.toHex(offEntries));\n }\n\n offEntries += 2;\n\n /*\n * bSegment 0x00 means all the entries spanned by bEntries are unused, so move on.\n */\n if (!bSegment) {\n iOrdinal += bEntries;\n continue;\n }\n while (bEntries--) {\n /*\n * bSegment 0x01-0xFE means the next 3 bytes describe a fixed segment entry; the next\n * byte contains flags indicating exported (0x1) and/or global/shared (0x2) data, and the\n * next word is the offset within the segment.\n */\n var offEntry;\n var offDebug = offEntries;\n var bFlags = this.loadValue(offEntries, 1);\n\n if (bSegment <= 0xFE) {\n iSegment = bSegment;\n offEntry = this.loadValue(offEntries + 1);\n offEntries += 3;\n } else {\n /*\n * bSegment 0xFF means a movable segment entry, which is 6 bytes long: flags byte (which\n * we've already read), an INT 0x3F (0xCD,0x3F), a 1-byte segment number, and a 2-byte offset.\n */\n iSegment = this.loadValue(offEntries + 3, 1);\n offEntry = this.loadValue(offEntries + 4);\n offEntries += 6;\n }\n if (!this.aSegments[iSegment]) {\n if (DEBUG && this.disk.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.disk.printMessage(\"invalid segment: \" + iSegment);\n }\n } else {\n this.aSegments[iSegment].aEntries[iOrdinal] = [offEntry];\n if (DEBUG && this.disk.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.disk.printMessage(\"ordinal \" + iOrdinal + \": segment=\" + iSegment + \" offset=\" + Str.toHexLong(offEntry) + \" @\" + Str.toHex(offDebug));\n }\n }\n this.aOrdinals[iOrdinal] = [iSegment, offEntry];\n iOrdinal++;\n }\n }\n }\n\n /**\n * loadNameTable(aField, offset)\n *\n * NOTE: If offset is omitted, we assume we're reading the Resident Name Table, and therefore\n * the first name is the module name; otherwise, we assume it is the Non-Resident Name Table, and\n * that the first name is the module description.\n *\n * @this {FileInfo}\n * @param {number} offEntries\n * @param {number} [offEntriesEnd] (if omitted, then the table must be null-terminated)\n */\n loadNameTable(offEntries, offEntriesEnd)\n {\n var cNames = 0;\n\n if (DEBUG && this.disk.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.disk.printMessage(\"loadNameTable(\" + Str.toHexLong(offEntries) + (offEntriesEnd? (\",\" + Str.toHexLong(offEntriesEnd)) : \"\") + \")\");\n }\n\n while (!offEntriesEnd || offEntries < offEntriesEnd) {\n\n var offDebug = offEntries;\n var bLength = this.loadValue(offEntries, 1);\n if (!bLength) break;\n\n var sSymbol = this.loadString(offEntries + 1, bLength);\n if (!sSymbol) break; // an error must have occurred (this is not a natural way to end)\n offEntries += 1 + bLength;\n\n if (!cNames) {\n if (!offEntriesEnd) {\n this.sModule = sSymbol;\n } else {\n this.sDescription = sSymbol;\n }\n }\n else {\n var iOrdinal = this.loadValue(offEntries);\n var tuple = this.aOrdinals[iOrdinal];\n if (tuple) {\n var iSegment = tuple[0]; // tuple[0] is the segment number and tuple[1] is the corresponding offEntry\n if (this.aSegments[iSegment]) {\n var aEntries = this.aSegments[iSegment].aEntries[iOrdinal];\n\n aEntries.push(sSymbol);\n if (DEBUG && this.disk.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.disk.printMessage(\"segment \" + iSegment + \" offset \" + Str.toHexWord(aEntries[0]) + \" ordinal \" + iOrdinal + \": \" + sSymbol + \" @\" + Str.toHex(offDebug));\n }\n } else {\n if (DEBUG && this.disk.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.disk.printMessage(this.sPath + \": cannot find segment \" + iSegment + \" (offset \" + Str.toHexWord(tuple[1]) + \") for symbol \" + sSymbol + \" with ordinal \" + iOrdinal + \" @\" + Str.toHex(offDebug));\n }\n }\n } else {\n if (DEBUG && this.disk.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.disk.printMessage(this.sPath + \": cannot find ordinal \" + iOrdinal + \" for symbol \" + sSymbol + \" @\" + Str.toHex(offDebug));\n }\n }\n }\n offEntries += 2;\n cNames++;\n }\n }\n\n /**\n * loadSymbols()\n *\n * For files with NE headers, extract all available symbolic information from the file.\n *\n * @this {FileInfo}\n */\n loadSymbols()\n {\n if (!Str.endsWith(this.sName, \".EXE\") && !Str.endsWith(this.sName, \".DLL\") && !Str.endsWith(this.sName, \".DRV\")) {\n return;\n }\n\n if (this.loadField(FileInfo.OE.oeSignature) != FileInfo.OE.SIG) {\n return;\n }\n\n if (this.loadField(FileInfo.OE.oeRelocOffset) != FileInfo.OE.NE_SIG) {\n return;\n }\n\n var offNEHeader = this.loadField(FileInfo.OE.oeNEHeader);\n if (this.loadField(FileInfo.NE.neSignature, offNEHeader) != FileInfo.NE.SIG) {\n return;\n }\n\n var nEntries = this.loadField(FileInfo.NE.neSTEntries, offNEHeader);\n var offEntries = this.loadField(FileInfo.NE.neSTOffset, offNEHeader);\n var nSegOffShift = this.loadField(FileInfo.NE.neSegOffShift, offNEHeader);\n\n if (offEntries && nEntries) {\n this.loadSegmentTable(offEntries + offNEHeader, nEntries, nSegOffShift || 0);\n }\n\n offEntries = this.loadField(FileInfo.NE.neETOffset, offNEHeader);\n var cbEntries = this.loadField(FileInfo.NE.neETSize, offNEHeader);\n if (offEntries && cbEntries) {\n this.loadEntryTable(offEntries += offNEHeader, offEntries + cbEntries);\n }\n\n /*\n * Time to walk the Resident Name Table and update the corresponding ordinals.\n */\n offEntries = this.loadField(FileInfo.NE.neRNTOffset, offNEHeader);\n if (offEntries) {\n this.loadNameTable(offEntries + offNEHeader);\n }\n\n /*\n * Ditto for the Non-Resident Name Table, which for some reason, uses a file-relative offset rather than\n * an NE header-relative offset, and which is both sized AND null-terminated; we check both terminating\n * conditions to be safe.\n */\n offEntries = this.loadField(FileInfo.NE.neNRNTOffset, offNEHeader);\n cbEntries = this.loadField(FileInfo.NE.neNRNTSize, offNEHeader);\n if (offEntries && cbEntries) {\n this.loadNameTable(offEntries, offEntries + cbEntries);\n }\n }\n\n /**\n * getSymbol(off, fNearest)\n *\n * @this {FileInfo}\n * @param {number} off (offset relative to start of file)\n * @param {boolean} [fNearest] (true to return nearest symbol if a segment with symbols is found)\n * @return {string} symbol corresponding to file offset (of the file name + offset if no symbol found)\n */\n getSymbol(off, fNearest)\n {\n var sSymbol = null;\n if (this.aSegments) {\n for (var iSegment in this.aSegments) {\n var segment = this.aSegments[iSegment];\n if (off >= segment.offStart && off <= segment.offEnd) {\n /*\n * This is the one and only segment we need to check, so we can make off segment-relative now.\n */\n off -= segment.offStart;\n /*\n * To support fNearest, save the entry where (off - entry[0]) yields the smallest positive result.\n */\n var cbNearest = off, entryNearest;\n for (var iOrdinal in segment.aEntries) {\n var entry = segment.aEntries[iOrdinal];\n var cb = off - entry[0];\n if (!cb) {\n sSymbol = this.sModule + '!' + entry[1];\n break;\n }\n if (fNearest && cb > 0 && cb < cbNearest) {\n entryNearest = entry;\n cbNearest = cb;\n }\n }\n if (!sSymbol && entryNearest) {\n sSymbol = this.sModule + '!' + entryNearest[1] + \"+\" + Str.toHex(cbNearest, 0, true);\n }\n break;\n }\n }\n }\n return sSymbol || this.sName + '+' + Str.toHex(off, 0, true);\n }\n}\n\n/*\n * Original (aka \"Old\") Executable MS-DOS File Format\n *\n * Relocation entries are pairs of 16-bit words:\n *\n * wOffset\n * wSegment\n *\n * I've noticed that a \"PKLITE\" EXE may have a oeRelocOffset of 0x52, where the word at 0x001C is 0x210F and the\n * bytes from 0x001E through 0x0051 are:\n *\n * \"PKLITE Copr. 1990-92 PKWARE Inc. All Rights Reserved\"\n *\n * Other EXEs have a oeRelocOffset of 0x1E, which begs the question: what is the word at 0x001C typically used for?\n *\n * It was not uncommon for there to be wasted space in the header; even an EXE with, say, 20 (0x14) entries would\n * likely have a wHeaderParas value of 0x20, which is 512 (0x200) bytes. The desire, no doubt, was to align the\n * start of the EXE segment(s) to a traditional sector boundary.\n */\nFileInfo.OE = {\n SIG: 0x5A4D,\n oeSignature: [0x0000, 2], // \"MZ\" (0x4D,0x5A)\n oeLastBytes: [0x0002, 2], // 0-511 (0 means the entire last block is used)\n oeBlocks: [0x0004, 2], // number of blocks in the file\n oeRelocEntries: [0x0006, 2], // number of relocation entries in the header\n oeHeaderParas: [0x0008, 2], // number of (16-byte) paragraphs in the header\n oeExtraParas: [0x000A, 2], // minimum number of additional paragraphs required at load-time\n oeMaxParas: [0x000C, 2], // maximum number of additional paragraphs required at load-time\n oeSSRel: [0x000E, 2], // relative value of SS\n oeSPInit: [0x0010, 2], // initial value of SP\n oeChecksum: [0x0012, 2], // checksum if non-zero (sum of all words, including this, should be zero)\n oeIPInit: [0x0014, 2], // initial value of IP\n oeCSRel: [0x0016, 2], // relative value of CS\n oeRelocOffset: [0x0018, 2], // offset of first relocation item\n oeOverlay: [0x001A, 2], // overlay number (normally zero, implying main program)\n /*\n * The following fields are accommodated by the NE format, but they were actually defined by \"the DOS 4.0 group\"\n * as extensions to the OE format.\n */\n oeDOS40Bits: [0x0020, 2], // DOS 4.0 behavior bits\n oeUnusedBits: [0x0022, 2], // unused behavior bits\n /*\n * If oeRelocOffset (0x0018) is 0x40, then the file is considered an NE (New Executable) MS-DOS file, and\n * the offset of the NE header (from the start of the file) is a 32-bit value stored at 0x003C. Note that early\n * versions of Windows (aka \"DOS 2.0 Windows\") originally defined the NE header offset as a 16-bit value stored\n * at 0x003E. And before that, it may have been a 16-bit value stored at 0x0024, which would have been immediately\n * after the \"behavior bits\" fields shown above).\n */\n oeNEHeader: [0x003C, 4], // offset from start of file to NE header\n NE_SIG: 0x40\n};\n\n/*\n * New Executable MS-DOS File Format\n *\n * Unless otherwise specified, all *Offset fields are relative to the start of the NE header, and all *Size fields\n * are in bytes.\n */\nFileInfo.NE = {\n SIG: 0x454E,\n neSignature: [0x0000, 2], // \"NE\" (0x4E,0x45)\n neLinkerVer: [0x0002, 2], // (low byte is version, high byte is revision)\n neETOffset: [0x0004, 2], // Entry Table offset\n neETSize: [0x0006, 2], // Entry Table size\n neChecksum: [0x0008, 4], // checksum (sum of all DWORDs in the file, excluding this one)\n neFlags: [0x000C, 2],\n neDataSeg: [0x000E, 2],\n neHeapSize: [0x0010, 2],\n neStackSize: [0x0012, 2],\n neCSIP: [0x0014, 4],\n neSSSP: [0x0018, 4],\n neSTEntries: [0x001C, 2], // Segment Table entries\n neMRTEntries: [0x001E, 2], // Module Reference Table entries\n neNRNTSize: [0x0020, 2], // Non-Resident Name Table size\n neSTOffset: [0x0022, 2], // Segment Table offset\n neRTOffset: [0x0024, 2], // Resource Table offset\n neRNTOffset: [0x0026, 2], // Resident Name Table offset\n neMRTOffset: [0x0028, 2], // Module Reference Table offset\n neINTOffset: [0x002A, 2], // Imported Names Table offset\n neNRNTOffset: [0x002C, 4], // Non-Resident Name Table offset (relative to start of file)\n neETMovable: [0x0030, 2], // number of movable entries in the Entry Table\n neSegOffShift: [0x0032, 2], // logical sector alignment shift count, log(base 2) of the segment sector size (default 9)\n /*\n * Fields after this point are post \"DOS 2.0 Windows\"...\n */\n neRTEntries: [0x0034, 2], // Resource Table entries\n neEXEType: [0x0036, 1] // executable type (0x02 for Windows)\n /*\n * 0x37 through 0x3F is reserved.\n */\n};\n\n/**\n * Every Sector object (once loaded, parsed, and \"normalized\") should have ALL of the following named properties:\n *\n * 'sector': sector number\n * 'length': size of the sector, in bytes\n * 'data': array of dwords\n * 'pattern': dword pattern to use for empty or partial sectors (or null if sector still needs to be loaded)\n *\n * initSector() also sets the following properties, to help us quickly identify its location within aDiskData:\n *\n * iCylinder\n * iHead\n *\n * In addition, we will maintain the following information on a per-sector basis, as sectors are modified:\n *\n * iModify: index of first modified dword in sector\n * cModify: number of modified dwords in sector\n * fDirty: true if sector is dirty, false if clean (or cleaning in progress)\n *\n * fDirty is used in conjunction with \"demandrw\" disks; it is set to true whenever the sector is modified, and is\n * set to false whenever the sector has been sent to the server. If the server write succeeds and fDirty is still\n * false, then the sector modifications are removed (cModify is set to zero). If the write succeeds but fDirty was\n * set to true again in the meantime, then all the sector modifications (even those that were just written) remain\n * in place (since we don't keep track of more than one modification range within a sector). And if the write failed,\n * then fDirty is set back to true and again all modifications remain in place; the best we can do is schedule another\n * write attempt.\n *\n * TODO: Perhaps we should also maintain a failure count and stop trying to write sectors that reach a certain\n * threshold. Error-handling, as usual, is the thorniest problem.\n *\n * @typedef {{\n * sector: number,\n * length: number,\n * data: Array.<number>,\n * pattern: (number|null),\n * iCylinder: number,\n * iHead: number,\n * iModify: number,\n * cModify: number,\n * file: FileInfo,\n * offFile: number\n * }}\n */\nvar SectorInfo;\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/fdc.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * FDC Terms (see FDC.TERMS)\n *\n * C Cylinder Number the current or selected cylinder number\n *\n * D Data the data pattern to be written to a sector\n *\n * DS Drive Select the selected driver number encoded the same as bits 0 and 1 of the Digital Output\n * Register (DOR); eg, DS0, DS1, DS2, or DS3\n *\n * DTL Data Length when N is 00, DTL is the data length to be read from or written to a sector\n *\n * EOT End Of Track the final sector number on a cylinder\n *\n * GPL Gap Length the length of gap 3 (spacing between sectors excluding the VCO synchronous field)\n *\n * H Head Address the head number, either 0 or 1, as specified in the ID field\n *\n * HD Head the selected head number, 0 or 1 (H = HD in all command words)\n *\n * HLT Head Load Time the head load time in the selected drive (2 to 256 milliseconds in 2-millisecond\n * increments for the 1.2M-byte drive and 4 to 512 milliseconds in 4 millisecond increments\n * for the 320K-byte drive)\n *\n * HUT Head Unload Time the head unload time after a read or write operation (0 to 240 milliseconds in\n * 16-millisecond increments for the 1.2M-byte drive and 0 to 480 milliseconds in\n * 32-millisecond increments for the 320K-byte drive)\n *\n * MF FM or MFM Mode 0 selects FM mode and 1 selects MFM (MFM is selected only if it is implemented)\n *\n * MT Multitrack 1 selects multitrack operation (both HD0 and HD1 will be read or written)\n *\n * N Number the number of data bytes written in a sector\n *\n * NCN New Cylinder Number the new cylinder number for a SEEK operation\n *\n * ND Non-Data Mode indicates an operation in the non-data mode\n *\n * PCN Present Cylinder Number the cylinder number at the completion of a SENSE INTERRUPT STATUS command\n * (present position of the head)\n *\n * R Record the sector number to be read or written\n *\n * SC Sectors Per Cylinder the number of sectors per cylinder\n *\n * SK Skip this stands for skip deleted-data address mark\n *\n * SRT Stepping Rate this 4 bit byte indicates the stepping rate for the diskette drive as follows:\n * 1.2M-Byte Diskette Drive: 1111=1ms, 1110=2ms, 1101=3ms\n * 320K-Byte Diskette Drive: 1111=2ms, 1110=4ms, 1101=6ms\n *\n * STP STP Scan Test if STP is 1, the data in contiguous sectors is compared with the data sent\n * by the processor during a scan operation; if STP is 2, then alternate sections\n * are read and compared\n */\n\n/**\n * class FDC\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass FDC extends Component {\n /**\n * FDC(parmsFDC)\n *\n * The FDC component simulates a NEC µPD765A or Intel 8272A compatible floppy disk controller, and has one\n * component-specific property:\n *\n * autoMount: one or more JSON-encoded objects, each containing 'name' and 'path' properties\n *\n * sortBy: \"name\" to sort disks by name, \"path\" to sort by path, or \"none\" to leave as-is (default is \"name\")\n *\n * Regarding early diskette drives: the IBM PC Model 5150 originally shipped with single-sided drives,\n * and therefore supported only 160Kb diskettes. That's the only diskette format PC-DOS 1.00 supported, too.\n *\n * At some point, 5150's started shipping with double-sided drives, but I'm not sure whether the ROMs changed;\n * they probably did NOT change, because the original ROM BIOS already supported drives with multiple heads.\n * However, what the ROM BIOS did NOT do was provide any indication of drive type, which as far as I can tell,\n * meant you had to simply read/write/format tracks with the second head and check for errors.\n *\n * Presumably at the same time double-sided drives started shipping, PC-DOS 1.10 shipped, which added\n * support for 320Kb diskettes. And the FORMAT command changed as well, defaulting to a double-sided format\n * operation UNLESS you specified \"FORMAT /1\". If I run PC-DOS 1.10 and try to simulate a single-sided drive\n * (by setting drive.nHeads = 1 in initDrive), FORMAT will balk with \"Track 0 bad - disk unusable\". I have to\n * wonder if everyone with single-sided drives who upgraded to PC-DOS 1.10 also got that error, forcing them\n * to always specify \"FORMAT /1\", or if I'm doing something wrong wrt single-sided drive simulation.\n *\n * I've noticed that if I turn FDC messages on (\"m fdc on\"), and then run \"FORMAT B:/1\", the command still\n * tries to format head 1/track 0, followed by head 0/track 0, and then the FDC is reset, and the format operation\n * proceeds with only head 0 for all tracks 0 through 39. FORMAT successfully creates a 160Kb single-sided diskette,\n * but why it also tries to initially format track 0 using the second head remains a bit of a mystery.\n *\n * @this {FDC}\n * @param {Object} parmsFDC\n */\n constructor(parmsFDC)\n {\n /*\n * TODO: Indicate the type of diskette image being loaded (this might help folks understand what's going\n * on when they try to load a diskette image that's larger than what the selected operating system supports).\n */\n super(\"FDC\", parmsFDC, Messages.FDC);\n\n this['dmaRead'] = FDC.prototype.doDMARead;\n this['dmaWrite'] = FDC.prototype.doDMAWrite;\n this['dmaFormat'] = FDC.prototype.doDMAFormat;\n\n /*\n * We record any 'autoMount' object now, but we no longer parse it until initBus(), because the Computer's\n * getMachineParm() service may have an override for us.\n */\n this.configMount = this.parseConfig(parmsFDC['autoMount']);\n\n /*\n * This establishes \"name\" as the default; if we decide we'd prefer \"none\" to be the default (ie, the order\n * to use when no sortBy value is specified), we can just drop the '|| \"name\"', because an undefined value is\n * just as falsey as null.\n *\n * The code that actually performs the sorting (in setBinding()) first checks that sortBy is not falsey, and\n * then assumes that the non-falsey value must be either \"path\" or \"name\", and since it explicitly checks for\n * \"path\" first, any non-sensical value will be treated as \"name\" (which is fine, since that's our current default).\n */\n this.sortBy = parmsFDC['sortBy'] || \"name\";\n if (this.sortBy == \"none\") this.sortBy = null;\n\n /*\n * The following array keeps track of every disk image we've ever mounted. Each entry in the\n * array is another array whose elements are:\n *\n * [0]: name of disk\n * [1]: path of disk\n * [2]: array of deltas, uninitialized until the disk is unmounted and/or all state is saved\n *\n * See functions addDiskHistory() and updateDiskHistory().\n */\n this.aDiskHistory = [];\n\n /*\n * Support for local disk images is currently limited to desktop browsers with FileReader support;\n * when this flag is set, setBinding() allows local disk bindings and informs initBus() to update the\n * \"listDisks\" binding accordingly.\n */\n this.fLocalDisks = (!Web.isMobile() && window && 'FileReader' in window);\n\n /*\n * The remainder of FDC initialization now takes place in our initBus() handler, largely because we\n * want initController() to have access to the ChipSet component, so that it can query switches and/or CMOS\n * settings that determine the number of drives and their characteristics (eg, 40-track vs. 80-track),\n * which it can then pass on to initDrive().\n */\n\n this['exports'] = {\n 'loadDisk': this.loadSelectedDisk,\n 'wait': this.waitDrives\n };\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {FDC}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"listDisks\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var fdc = this;\n /*\n * TODO: Making copies of control that are simply cast to different types seems silly, but it doesn't\n * really cost anything and it's cleaner than doing a lot MORE type overrides inline. However, it still\n * doesn't solve all my problems: controlForm should really be cast as HTMLFormElement, but JavaScript\n * inspections refuse to believe there's an 'onsubmit' property on an HTMLFormElement that I can override.\n */\n var controlForm = /** @type {Object} */ (control);\n var controlSelect = /** @type {HTMLSelectElement} */ (control);\n\n switch (sBinding) {\n\n case \"listDisks\":\n this.bindings[sBinding] = controlSelect;\n /*\n * Since binding is a one-time initialization operation, it's also the perfect time to\n * perform whatever sorting (if any) is indicated by the FDC component's \"sortBy\" property.\n *\n * And since setBinding() is called before initBus(), that means any \"special\" disk entries\n * will be added after the sorting, so we won't be \"burying\" those entries somewhere in the\n * middle.\n */\n if (this.sortBy) {\n var i, aOptions = [];\n /*\n * NOTE: All this monkeying around with copying the elements from control.options to aOptions\n * and then back again is necessary because control.options isn't a *real* Array (at least not\n * in all browsers); consequently, it may have no sort() method. It has a length property,\n * along with numeric properties 0 to length-1, but it's still probably just an Object, not\n * an Array.\n *\n * Also note that changing the order of the control's options would ordinarily mean that the\n * control's selectedIndex may now be incorrect, but in our case, it doesn't matter, because\n * we have a special function, displayDiskette(), that will be called at LEAST once during\n * initialization, ensuring that selectedIndex is set correctly.\n */\n for (i = 0; i < controlSelect.options.length; i++) {\n aOptions.push(controlSelect.options[i]);\n }\n aOptions.sort(function(a, b) {\n /*\n * I've switched to localeCompare() because it offers case-insensitivity by default;\n * I'm still a little concerned that we could somehow end up with list elements whose text\n * and/or value properties are undefined (because calling a method on an undefined variable\n * will throw an exception), but maybe I'm being overly paranoid....\n */\n if (fdc.sortBy != \"path\") {\n return a.text.localeCompare(b.text);\n } else {\n return a.value.localeCompare(b.value);\n }\n });\n for (i = 0; i < aOptions.length; i++) {\n try {\n /*\n * TODO: Determine why this line blows up in IE8; are the properties of an options object not settable in IE8?\n */\n controlSelect.options[i] = aOptions[i];\n } catch(e) {\n break;\n }\n }\n }\n controlSelect.onchange = function onChangeListDisks(event) {\n fdc.updateSelectedDiskette();\n };\n return true;\n\n case \"descDisk\":\n case \"listDrives\":\n this.bindings[sBinding] = controlSelect;\n /*\n * I tried going with onclick instead of onchange, so that if you wanted to confirm what's\n * loaded in a particular drive, you could click the drive control without having to change it.\n * However, that doesn't seem to work for all browsers, so I've reverted to onchange.\n */\n controlSelect.onchange = function onChangeListDrives(event) {\n var iDrive = Str.parseInt(controlSelect.value, 10);\n if (iDrive != null) fdc.displayDiskette(iDrive);\n };\n return true;\n\n case \"loadDisk\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickLoadDisk(event) {\n fdc.loadSelectedDisk();\n };\n return true;\n\n case \"saveDisk\":\n /*\n * Yes, technically, this feature does not require \"Local disk support\" (which is really a reference\n * to FileReader support), but since fLocalDisks is also false for all mobile devices, and since there\n * is an \"orthogonality\" to disabling both features in tandem, let's just let it slide, OK?\n */\n if (!this.fLocalDisks) {\n if (DEBUG) this.log(\"Local disk support not available\");\n /*\n * We could also simply hide the control; eg:\n *\n * control.style.display = \"none\";\n *\n * but removing the control altogether seems better.\n */\n control.parentNode.removeChild(/** @type {Node} */ (control));\n return false;\n }\n this.bindings[sBinding] = control;\n control.onclick = function onClickSaveDisk(event) {\n var controlDrives = fdc.bindings[\"listDrives\"];\n if (controlDrives && controlDrives.options && fdc.aDrives) {\n var iDriveSelected = Str.parseInt(controlDrives.value, 10) || 0;\n var drive = fdc.aDrives[iDriveSelected];\n if (drive) {\n /*\n * Note the similarity (and hence factoring opportunity) between this code and the HDC's\n * \"saveHD*\" binding.\n */\n var disk = drive.disk;\n if (disk) {\n if (DEBUG) fdc.println(\"saving diskette \" + disk.sDiskPath + \"...\");\n var sAlert = Web.downloadFile(disk.encodeAsBase64(), \"octet-stream\", true, disk.sDiskFile.replace(\".json\", \".img\"));\n Component.alertUser(sAlert);\n } else {\n fdc.notice(\"No diskette loaded in drive.\");\n }\n } else {\n fdc.notice(\"No diskette drive selected.\");\n }\n }\n };\n return true;\n\n case \"mountDisk\":\n if (!this.fLocalDisks) {\n if (DEBUG) this.log(\"Local disk support not available\");\n /*\n * We could also simply hide the control; eg:\n *\n * controlForm.style.display = \"none\";\n *\n * but removing the control altogether seems better.\n */\n controlForm.parentNode.removeChild(/** @type {Node} */ (controlForm));\n return false;\n }\n this.bindings[sBinding] = controlForm;\n /*\n * Enable \"Mount\" button only if a file is actually selected\n */\n controlForm.onchange = function onChangeMountDisk() {\n var fieldset = controlForm.children[0];\n var files = fieldset.children[0].files;\n var submit = fieldset.children[1];\n submit.disabled = !files.length;\n };\n controlForm.onsubmit = function onSubmitMountDisk(event) {\n var file = event.currentTarget[1].files[0];\n if (file) {\n var sDiskettePath = file.name;\n var sDisketteName = Str.getBaseName(sDiskettePath, true);\n fdc.loadSelectedDrive(sDisketteName, sDiskettePath, file);\n }\n /*\n * Prevent reloading of web page after form submission\n */\n return false;\n };\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {FDC}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.cmp = cmp;\n\n this.chipset = cmp.getMachineComponent(\"ChipSet\");\n this.parseConfig(this.cmp.getMachineParm('autoMount'), this.configMount);\n\n /*\n * If we didn't need auto-mount support, we could defer controller initialization until we received a powerUp() notification,\n * at which point reset() would call initController(), or restore() would restore the controller; in that case, all we'd need\n * to do here is call setReady().\n */\n this.initController();\n\n bus.addPortInputTable(this, FDC.aPortInput);\n bus.addPortOutputTable(this, FDC.aPortOutput);\n\n this.addDiskette(\"None\", \"\", true);\n if (this.fLocalDisks) this.addDiskette(\"Local Disk\", \"?\");\n this.addDiskette(\"Remote Disk\", \"??\");\n\n if (!this.autoMount()) this.setReady();\n }\n\n /**\n * parseConfig(config, configMerge)\n *\n * @this {FDC}\n * @param {Object|string|undefined} config\n * @param {Object} [configMerge]\n * @return {Object}\n */\n parseConfig(config, configMerge)\n {\n if (config) {\n if (typeof config == \"string\") {\n try {\n /*\n * We must take care when parsing user-supplied JSON-encoded diskette data.\n */\n config = /** @type {Object} */ (eval(\"(\" + config + \")\"));\n } catch (e) {\n Component.error(\"FDC auto-mount error: \" + e.message + \" (\" + config + \")\");\n config = {};\n }\n }\n } else {\n config = {};\n }\n for (var sDrive in config) {\n if (configMerge) configMerge[sDrive] = config[sDrive];\n }\n return config;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {FDC}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.reset();\n if (this.cmp.fReload) {\n /*\n * If the computer's fReload flag is set, we're required to toss all currently\n * loaded disks and remount all disks specified in the auto-mount configuration.\n */\n this.unloadAllDrives(true);\n this.autoMount(true);\n }\n } else {\n if (!this.restore(data)) return false;\n }\n /*\n * Populate the HTML controls to match the actual (well, um, specified) number of floppy drives.\n */\n var controlDrives;\n if ((controlDrives = this.bindings['listDrives'])) {\n while (controlDrives.firstChild) {\n controlDrives.removeChild(controlDrives.firstChild);\n }\n controlDrives.value = \"\";\n for (var iDrive = 0; iDrive < this.nDrives; iDrive++) {\n var controlOption = document.createElement(\"option\");\n controlOption.value = iDrive.toString();\n /*\n * TODO: This conversion of drive number to drive letter, starting with A:, is very simplistic\n * and will NOT match the drive mappings that DOS ultimately uses. We'll need to spiff this up at\n * some point.\n */\n controlOption.text = String.fromCharCode(0x41 + iDrive) + \":\";\n controlDrives.appendChild(controlOption);\n }\n if (this.nDrives > 0) {\n controlDrives.value = \"0\";\n this.displayDiskette(0);\n }\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {FDC}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * NOTE: initController() establishes the maximum possible number of drives, but it's not until\n * we interrogate the current SW1 settings that we will have an ACTUAL number of drives (nDrives),\n * at which point we can also update the contents of the \"listDrives\" HTML control, if any.\n *\n * @this {FDC}\n */\n reset()\n {\n /*\n * NOTE: The controller is also initialized by the constructor, to assist with auto-mount support,\n * so think about whether we can skip powerUp initialization.\n */\n this.initController();\n }\n\n /**\n * save()\n *\n * This implements save support for the FDC component.\n *\n * @this {FDC}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveController());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the FDC component.\n *\n * @this {FDC}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return this.initController(data[0]);\n }\n\n /**\n * initController(data)\n *\n * @this {FDC}\n * @param {Array} [data]\n * @return {boolean} true if successful, false if failure\n */\n initController(data)\n {\n var i = 0, iDrive;\n var fSuccess = true;\n\n if (!data) {\n data = [0, 0, FDC.REG_STATUS.RQM, new Array(9), 0, 0, 0, []];\n }\n\n /*\n * Selected drive (from regOutput), which can only be selected if its motor is on (see regOutput).\n */\n this.iDrive = data[i++];\n i++; // unused slot (if reused, bias by +4, since it was formerly a unit #)\n\n /*\n * Defaults to FDC.REG_STATUS.RQM set (ready for command) and FDC.REG_STATUS.READ_DATA clear (data direction\n * is from processor to the FDC Data Register).\n */\n this.regStatus = data[i++];\n\n /*\n * There can be up to 9 command bytes, and 7 result bytes, so 9 data registers are sufficient for communicating\n * in both directions (hence, the new Array(9) default above).\n */\n this.regDataArray = data[i++];\n\n /*\n * Determines the next data byte to be received.\n */\n this.regDataIndex = data[i++];\n\n /*\n * Determines the next data byte to be sent (internally, we use regDataIndex to read data bytes, up to this total).\n */\n this.regDataTotal = data[i++];\n this.regOutput = data[i++];\n var dataDrives = data[i++];\n\n /*\n * Initialize the disk history (if available) before initializing the drives, so that any disk deltas can be\n * applied to disk images that are already loaded.\n */\n var aDiskHistory = data[i++];\n if (aDiskHistory != null) this.aDiskHistory = aDiskHistory;\n\n if (this.aDrives === undefined) {\n this.nDrives = 4; // default to the maximum number of drives\n if (this.chipset) this.nDrives = this.chipset.getDIPFloppyDrives();\n /*\n * I would prefer to allocate only nDrives, but as discussed in the handling of the FDC.REG_DATA.CMD.SENSE_INT\n * command, we're faced with situations where the controller must respond to any drive in the range 0-3, regardless\n * how many drives are actually installed. We still rely upon nDrives to determine the number of drives displayed\n * to the user, however.\n */\n this.aDrives = new Array(4);\n }\n\n for (iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n var drive = this.aDrives[iDrive];\n if (drive === undefined) {\n /*\n * The first time each drive is initialized, we query its capacity (based on switches or CMOS) and set\n * the drive's physical limits accordingly (ie, max tracks, max heads, and max sectors/track).\n */\n drive = this.aDrives[iDrive] = {};\n var nKb = (this.chipset? this.chipset.getDIPFloppyDriveSize(iDrive) : 0);\n switch(nKb) {\n case 160:\n case 180:\n drive.nHeads = 1; // required for single-sided drives only (all others default to double-sided)\n /* falls through */\n case 320:\n case 360:\n /* falls through */\n default: // drives that don't have a recognized capacity default to 360\n drive.nCylinders = 40;\n drive.nSectors = 9; // drives capable of writing 8 sectors/track can also write 9 sectors/track\n break;\n case 720:\n drive.nCylinders = 80;\n drive.nSectors = 9;\n break;\n case 1200:\n drive.nCylinders = 80;\n drive.nSectors = 15;\n break;\n case 1440:\n drive.nCylinders = 80;\n drive.nSectors = 18;\n break;\n }\n }\n if (!this.initDrive(drive, iDrive, dataDrives[iDrive])) {\n fSuccess = false;\n }\n }\n\n /*\n * regInput and regControl (port 0x3F7) were not present on controllers prior to MODEL_5170, which is why\n * we don't include initializers for them in the default data array; we could eliminate them on older models,\n * but we don't have access to the model info right now, and there's no real cost to always including them\n * in the FDC state.\n *\n * The bigger compatibility question is whether to always include hooks for them (see aPortInput and aPortOutput).\n */\n this.regInput = data[i++] || 0; // TODO: Determine if we should default to FDC.REG_INPUT.DISK_CHANGE instead of 0\n this.regControl = data[i] || FDC.REG_CONTROL.RATE500K; // default to maximum data rate\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"FDC initialized for \" + this.aDrives.length + \" drive(s)\");\n }\n return fSuccess;\n }\n\n /**\n * saveController()\n *\n * @this {FDC}\n * @return {Array}\n */\n saveController()\n {\n var i = 0;\n var data = [];\n data[i++] = this.iDrive;\n data[i++] = 0;\n data[i++] = this.regStatus;\n data[i++] = this.regDataArray;\n data[i++] = this.regDataIndex;\n data[i++] = this.regDataTotal;\n data[i++] = this.regOutput;\n data[i++] = this.saveDrives();\n data[i++] = this.saveDeltas();\n data[i++] = this.regInput;\n data[i] = this.regControl;\n return data;\n }\n\n /**\n * initDrive(drive, iDrive, data)\n *\n * TODO: Consider a separate Drive class that both FDC and HDC can use, since there's a lot of commonality\n * between the drive objects created by both controllers. This will clean up overall drive management and allow\n * us to factor out some common Drive methods (eg, advanceSector()).\n *\n * @this {FDC}\n * @param {Object} drive\n * @param {number} iDrive\n * @param {Array|undefined} data\n * @return {boolean} true if successful, false if failure\n */\n initDrive(drive, iDrive, data)\n {\n var i = 0;\n var fSuccess = true;\n\n drive.iDrive = iDrive;\n drive.fBusy = drive.fLocal = false;\n drive.fnCallReady = null;\n\n if (data === undefined) {\n /*\n * We set a default of two heads (MODEL_5150 PCs originally shipped with single-sided drives,\n * but the ROM BIOS appears to have always supported both drive types).\n */\n data = [FDC.REG_DATA.RES.RESET, true, 0, 2, 0];\n }\n\n if (typeof data[1] == \"boolean\") {\n /*\n * Note that when no data is provided (eg, when the controller is being reinitialized), we now take\n * care to preserve any drive defaults that initController() already obtained for us, falling back to\n * bare minimums only when all else fails.\n */\n data[1] = [\n FDC.DEFAULT_DRIVE_NAME, // a[0]\n drive.nCylinders || 40, // a[1]\n drive.nHeads || data[3],// a[2]\n drive.nSectors || 9, // a[3]\n drive.cbSector || 512, // a[4]\n data[1], // a[5]\n drive.nDiskCylinders, // a[6]\n drive.nDiskHeads, // a[7]\n drive.nDiskSectors // a[8]\n ];\n }\n\n /*\n * resCode used to be an FDC global, but in order to insulate FDC state from the operation of various functions\n * that operate on drive objects (eg, readData and writeData), I've made it a per-drive variable. This choice,\n * similar to my choice for handling PCN, may be contrary to how the actual hardware works, but I prefer this\n * approach, as long as it doesn't expose any incompatibilities that any software actually cares about.\n */\n drive.resCode = data[i++];\n\n /*\n * Some additional drive properties/defaults that are largely for the Disk component's benefit.\n */\n var a = data[i++];\n drive.name = a[0];\n drive.nCylinders = a[1]; // cylinders\n drive.nHeads = a[2]; // heads/cylinders\n drive.nSectors = a[3]; // sectors/track\n drive.cbSector = a[4]; // bytes/sector\n drive.fRemovable = a[5];\n /*\n * If we have current media parameters, restore them; otherwise, default to the drive's physical parameters.\n */\n if (drive.nDiskCylinders = a[6]) {\n drive.nDiskHeads = a[7];\n drive.nDiskSectors = a[8];\n } else {\n drive.nDiskCylinders = drive.nCylinders;\n drive.nDiskHeads = drive.nHeads;\n drive.nDiskSectors = drive.nSectors;\n }\n\n /*\n * The next group of properties are set by various FDC command sequences.\n *\n * We initialize this.iDrive (above) and drive.bHead and drive.bCylinder (below) to zero, but leave the rest undefined,\n * awaiting their first FDC command. We do this because the initial SENSE_INT command returns a PCN, which will also\n * be undefined unless we have at least zeroed both the current drive and the \"present\" cylinder on that drive.\n *\n * Alternatively, I could make PCN a global FDC variable. That may be closer to how the actual hardware operates,\n * but I'm using per-drive variables so that the FDC component can be a good client to both the CPU and other components.\n *\n * COMPATIBILITY ALERT: The MODEL_5170 BIOS (\"DSKETTE_SETUP\") attempts to discern the drive type (double-density vs.\n * high-capacity) by \"slapping\" the heads around -- \"litrally\" (it uses a constant named \"TRK_SLAP\" equal to 48).\n * After seeking to \"TRK_SLAP\", the BIOS performs a series of seeks, looking for the precise point where the heads\n * return to track 0.\n *\n * Here's how it works: the BIOS seeks to track 48 (which is fine on an 80-track 1.2Mb high-capacity drive, but 9 tracks\n * too far on a 40-track 360Kb double-density drive), then seeks to track 10, and then seeks in single-track increments\n * up to 10 more times until the SENSE_DRIVE command returns ST3 with the TRACK0 bit set.\n *\n * This implies that SEEK isn't really seeking to a specified cylinder, but rather it is calculating a delta from\n * the previous cylinder to the specified cylinder, and stepping over that number of tracks. Which means that SEEK\n * is updating a \"logical\" cylinder number, not the \"physical\" (actual) cylinder number. Presumably a RECALIBRATE\n * command will bring the logical and physical values into sync, but once an out-of-bounds cylinder is requested, they\n * will be out of sync.\n *\n * To simulate this, bCylinder is now treated as the \"physical\" cylinder (since that's how it's ALWAYS been used here),\n * and bCylinderSeek will now track (pun intended) the \"logical\" cylinder that's programmed via SEEK commands.\n */\n drive.bHead = data[i++];\n drive.bCylinderSeek = data[i++]; // the data[] slot where we used to store drive.nHeads (or -1)\n drive.bCylinder = data[i++];\n if (drive.bCylinderSeek >= 100) { // verify that the saved bCylinderSeek is valid, otherwise sync it with bCylinder\n drive.bCylinderSeek -= 100;\n } else {\n drive.bCylinderSeek -= drive.bCylinder;\n }\n drive.bSector = data[i++];\n drive.bSectorEnd = data[i++]; // aka EOT\n drive.nBytes = data[i++];\n\n /*\n * We no longer reinitialize drive.disk, in order to retain previously mounted diskette across resets.\n */\n\n /*\n * The next group of properties are managed by worker functions (eg, doRead()) to maintain state across DMA requests.\n */\n drive.ibSector = data[i++]; // location of the next byte to be accessed in the current sector\n drive.sector = null;\n\n if (!drive.disk) {\n drive.sDiskettePath = \"\"; // ensure this is initialized to a default that displayDiskette() can deal with\n }\n\n var deltas = data[i++];\n if (deltas == 102) deltas = false; // v1.02 backward-compatibility\n\n if (typeof deltas == \"boolean\") {\n var fLocal = deltas;\n var sDisketteName = data[i++];\n var sDiskettePath = data[i];\n /*\n * If we're restoring a local disk image, then the entire disk contents should be captured in aDiskHistory,\n * so all we have to do is mount a blank diskette and let disk.restore() do the rest; ie, there's nothing to\n * \"load\" (it's a purely synchronous operation).\n *\n * Otherwise, we must call loadDrive(); in the common case, loadDrive() will have already \"auto-mounted\"\n * the diskette, so it will return true, and then we restore any deltas to the current image.\n *\n * However, if loadDrive() returns false, then it has initiated the load for a *different* disk image,\n * so we must mark ourselves as \"not ready\" again, and add another \"wait for ready\" test in Computer before\n * finally powering the CPU.\n */\n if (fLocal) {\n this.mountDrive(iDrive, sDisketteName, sDiskettePath);\n }\n else if (this.loadDrive(iDrive, sDisketteName, sDiskettePath, true)) {\n if (drive.disk) {\n if (sDiskettePath) {\n this.addDiskHistory(sDisketteName, sDiskettePath, drive.disk);\n } else {\n if (MAXDEBUG) Component.warning(\"Disk '\" + (drive.disk.sDiskName || sDisketteName) + \"' not recorded properly in drive \" + iDrive);\n }\n }\n } else {\n this.setReady(false);\n }\n } else if (deltas !== undefined) {\n /*\n * If there's any data at all (ie, if this is a restore and not a reset), then it must be in the\n * pre-v1.02 save/restore format, so we'll restore as best we can, but be aware that if disk.restore()\n * notices that the currently mounted disk image differs from the disk image that these deltas belong to,\n * it will return false, and the restore operation will be aborted.\n */\n if (drive.disk && drive.disk.restore(deltas) < 0) {\n fSuccess = false;\n }\n }\n\n /*\n * TODO: If loadDrive() returned true, then this can happen immediately. Otherwise, loadDrive()\n * will have merely \"queued up\" the load request and drive.disk won't be ready yet, so figure out how/when\n * we can properly restore drive.sector in that case.\n */\n if (fSuccess && drive.disk && drive.ibSector !== undefined) {\n drive.sector = drive.disk.seek(drive.bCylinder, drive.bHead, drive.bSector);\n }\n return fSuccess;\n }\n\n /**\n * saveDrives()\n *\n * @this {FDC}\n * @return {Array}\n */\n saveDrives()\n {\n var i = 0;\n var data = [];\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n data[i++] = this.saveDrive(this.aDrives[iDrive]);\n }\n return data;\n }\n\n /**\n * saveDrive(drive)\n *\n * @this {FDC}\n * @param {Object} drive\n * @return {Array}\n */\n saveDrive(drive)\n {\n var i = 0;\n var data = [];\n data[i++] = drive.resCode;\n data[i++] = [drive.name, drive.nCylinders, drive.nHeads, drive.nSectors, drive.cbSector, drive.fRemovable, drive.nDiskCylinders, drive.nDiskHeads, drive.nDiskSectors];\n data[i++] = drive.bHead;\n /*\n * We used to store drive.nHeads in the next slot, but now we store bCylinderSeek,\n * and we bias it by +100 so that initDrive() can distinguish it from older values.\n */\n data[i++] = drive.bCylinderSeek + 100;\n data[i++] = drive.bCylinder;\n data[i++] = drive.bSector;\n data[i++] = drive.bSectorEnd;\n data[i++] = drive.nBytes;\n data[i++] = drive.ibSector;\n /*\n * Now we deviate from the 1.01a save format: instead of next storing all the deltas for the\n * currently mounted disk (if any), we store only the name and path of the currently mounted disk\n * (if any). Deltas for ALL disks, both currently mounted and previously mounted, are stored later.\n *\n * data[i++] = drive.disk? drive.disk.save() : null;\n *\n * To indicate this deviation, we store neither a null nor a delta array, but a boolean (fLocal);\n * if that boolean is not present, then the restore code will know it's dealing with a pre-v1.02 state.\n */\n data[i++] = drive.fLocal;\n data[i++] = drive.sDisketteName;\n data[i] = drive.sDiskettePath;\n if (DEBUG && !drive.sDiskettePath && drive.disk && drive.disk.sDiskPath) {\n Component.warning(\"Disk '\" + drive.disk.sDiskName + \"' not saved properly in drive \" + drive.iDrive);\n }\n return data;\n }\n\n /**\n * saveDeltas()\n *\n * This returns an array of entries, one for each disk image we've ever mounted, including any deltas; ie:\n *\n * [name, path, deltas]\n *\n * aDiskHistory contains exactly that, except that deltas may not be up-to-date for any currently mounted\n * disk image(s), so we call updateHistory() for all those disks, and then aDiskHistory is ready to be saved.\n *\n * @this {FDC}\n * @return {Array}\n */\n saveDeltas()\n {\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n var drive = this.aDrives[iDrive];\n if (drive.disk) {\n this.updateDiskHistory(drive.sDisketteName, drive.sDiskettePath, drive.disk);\n }\n }\n return this.aDiskHistory;\n }\n\n /**\n * copyDrive(iDrive)\n *\n * @this {FDC}\n * @param {number} iDrive\n * @return {Object|undefined} drive (which may be undefined if the requested drive does not exist)\n */\n copyDrive(iDrive)\n {\n var driveNew;\n var driveOld = this.aDrives[iDrive];\n if (driveOld !== undefined) {\n driveNew = {};\n for (var p in driveOld) {\n driveNew[p] = driveOld[p];\n }\n }\n return driveNew;\n }\n\n /**\n * seekDrive(drive, iSector, nSectors)\n *\n * The FDC doesn't need this function, since all FDC requests from the CPU are handled by doCmd(). This function\n * is used by other components (eg, Debugger) to mimic an FDC request, using a drive object obtained from copyDrive(),\n * to avoid disturbing the internal state of the FDC's drive objects.\n *\n * Also note that in an actual FDC request, drive.nBytes is initialized to the size of a single sector; the extent\n * of the entire transfer is actually determined by a count that has been pre-loaded into the DMA controller. The FDC\n * isn't even aware of the extent of the transfer, so in the case of a read request, all readData() can do is return\n * bytes until the current track (or, in the case of a multi-track request, the current cylinder) has been exhausted.\n *\n * Since seekDrive() is for use with non-DMA requests, we use nBytes to specify the length of the entire transfer.\n *\n * @this {FDC}\n * @param {Object} drive\n * @param {number} iSector (a \"logical\" sector number, relative to the entire disk, NOT a physical sector number)\n * @param {number} nSectors\n * @return {boolean} true if successful, false if invalid position request\n */\n seekDrive(drive, iSector, nSectors)\n {\n if (drive.disk) {\n var aDiskInfo = drive.disk.info();\n var nCylinders = aDiskInfo[0];\n var nHeads = aDiskInfo[1];\n var nSectorsPerTrack = aDiskInfo[2];\n var nSectorsPerCylinder = nHeads * nSectorsPerTrack;\n var nSectorsPerDisk = nCylinders * nSectorsPerCylinder;\n if (iSector + nSectors <= nSectorsPerDisk) {\n drive.bCylinder = Math.floor(iSector / nSectorsPerCylinder);\n iSector %= nSectorsPerCylinder;\n drive.bHead = Math.floor(iSector / nSectorsPerTrack);\n drive.bSector = (iSector % nSectorsPerTrack) + 1;\n drive.nBytes = nSectors * aDiskInfo[3];\n /*\n * NOTE: We don't set bSectorEnd, as an FDC command would, but it's irrelevant, because we don't actually\n * do anything with bSectorEnd at this point. Perhaps someday, when we faithfully honor/restrict requests\n * to a single track (or a single cylinder, in the case of multi-track requests).\n */\n drive.resCode = FDC.REG_DATA.RES.NONE;\n /*\n * At this point, we've finished simulating what an FDC.REG_DATA.CMD.READ_DATA command would have performed,\n * up through doRead(). Now it's the caller responsibility to call readData(), just like the DMA Controller would.\n */\n return true;\n }\n }\n return false;\n }\n\n /**\n * autoMount(fRemount)\n *\n * @this {FDC}\n * @param {boolean} [fRemount] is true if we're remounting all auto-mounted diskettes\n * @return {boolean} true if one or more diskette images are being auto-mounted, false if none\n */\n autoMount(fRemount)\n {\n if (!fRemount) this.cAutoMount = 0;\n for (var sDrive in this.configMount) {\n var configDrive = this.configMount[sDrive];\n var sDiskettePath = configDrive['path'] || this.findDisketteByName(configDrive['name']);\n if (sDiskettePath) {\n /*\n * WARNING: This conversion of drive letter to drive number, starting with A:, is very simplistic\n * and is not guaranteed to match the drive mapping that DOS ultimately uses.\n */\n var iDrive = sDrive.charCodeAt(0) - 0x41;\n if (iDrive >= 0 && iDrive < this.aDrives.length) {\n var sDisketteName = configDrive['name'] || this.findDisketteByPath(sDiskettePath) || Str.getBaseName(sDiskettePath, true);\n if (!this.loadDrive(iDrive, sDisketteName, sDiskettePath, true) && fRemount) {\n this.setReady(false);\n }\n continue;\n }\n this.notice(\"Incorrect auto-mount settings for drive \" + sDrive + \" (\" + JSON.stringify(configDrive) + \")\");\n }\n }\n return !!this.cAutoMount;\n }\n\n /**\n * loadSelectedDisk()\n *\n * NOTE: Since this can be called via script command (eg, 'loadDisk FDC'), additional parameters can be\n * passed; use the arguments array to access them if necessary.\n *\n * @this {FDC}\n * @return {boolean}\n */\n loadSelectedDisk()\n {\n var controlDisks = this.bindings[\"listDisks\"];\n if (controlDisks) {\n var sDisketteName = controlDisks.options[controlDisks.selectedIndex].text;\n var sDiskettePath = controlDisks.value;\n return this.loadSelectedDrive(sDisketteName, sDiskettePath);\n }\n return false;\n }\n\n /**\n * loadSelectedDrive(sDisketteName, sDiskettePath, file)\n *\n * @this {FDC}\n * @param {string} sDisketteName\n * @param {string} sDiskettePath\n * @param {File} [file] is set if there's an associated File object\n * @return {boolean}\n */\n loadSelectedDrive(sDisketteName, sDiskettePath, file)\n {\n var iDrive;\n var controlDrives = this.bindings[\"listDrives\"];\n if (controlDrives && !isNaN(iDrive = Str.parseInt(controlDrives.value, 10)) && iDrive >= 0 && iDrive < this.aDrives.length) {\n\n if (!sDiskettePath) {\n this.unloadDrive(iDrive);\n return true;\n }\n\n if (sDiskettePath == \"?\") {\n this.notice('Use \"Choose File\" and \"Mount\" to select and load a local disk.');\n return false;\n }\n\n /*\n * If the special path of \"??\" is selected, then we want to prompt the user for a URL. Oh, and\n * make sure we pass an empty string as the 2nd parameter to prompt(), so that IE won't display\n * \"undefined\" -- because after all, undefined and \"undefined\" are EXACTLY the same thing, right?\n *\n * TODO: This is literally all I've done to support remote disk images. There's probably more\n * I should do, like dynamically updating \"listDisks\" to include new entries, and adding new entries\n * to the save/restore data.\n */\n if (sDiskettePath == \"??\") {\n sDiskettePath = window.prompt(\"Enter the URL of a remote disk image.\", \"\") || \"\";\n if (!sDiskettePath) return false;\n sDisketteName = Str.getBaseName(sDiskettePath);\n if (DEBUG) this.println(\"Attempting to load \" + sDiskettePath + \" as \\\"\" + sDisketteName + \"\\\"\");\n }\n\n while (this.loadDrive(iDrive, sDisketteName, sDiskettePath, false, file) < 0) {\n if (!window.confirm(\"Click OK to reload the original disk and discard any changes.\")) {\n if (DEBUG) this.println(\"load cancelled\");\n return false;\n }\n /*\n * So here's the story: loadDrive() returned true, which it does ONLY if the specified disk is already\n * mounted, AND the user clicked OK to reload the original disk image. So we must toss any history we have\n * for the disk, unload it, and then loop back around to loadDrive().\n *\n * loadDrive() should NEVER return true the second time, since no disk is loaded. In other words,\n * this isn't really a loop so much as a one-time retry operation.\n */\n this.removeDiskHistory(sDisketteName, sDiskettePath);\n this.unloadDrive(iDrive, false, true);\n }\n return true;\n }\n this.notice(\"Unable to load the selected drive\");\n return false;\n }\n\n /**\n * mountDrive(iDrive, sDisketteName, sDiskettePath)\n *\n * @this {FDC}\n * @param {number} iDrive\n * @param {string} sDisketteName\n * @param {string} sDiskettePath\n */\n mountDrive(iDrive, sDisketteName, sDiskettePath)\n {\n var drive = this.aDrives[iDrive];\n this.unloadDrive(iDrive, true, true);\n drive.fLocal = true;\n var disk = new Disk(this, drive, DiskAPI.MODE.PRELOAD);\n this.doneLoadDrive(drive, disk, sDisketteName, sDiskettePath, true);\n }\n\n /**\n * loadDrive(iDrive, sDisketteName, sDiskettePath, fAutoMount, file)\n *\n * NOTE: If sDiskettePath is already loaded in the drive, nothing needs to be done.\n *\n * @this {FDC}\n * @param {number} iDrive\n * @param {string} sDisketteName\n * @param {string} sDiskettePath\n * @param {boolean} [fAutoMount]\n * @param {File} [file] is set if there's an associated File object\n * @return {number} 1 if diskette loaded, 0 if queued up (or busy), -1 if already loaded\n */\n loadDrive(iDrive, sDisketteName, sDiskettePath, fAutoMount, file)\n {\n var drive = this.aDrives[iDrive];\n if (sDiskettePath) {\n /*\n * The following hacks should only be necessary for (old) saved states, since all our disk manifests\n * should no longer be using any of these old paths.\n */\n sDiskettePath = sDiskettePath.replace(\"/disks/pc/\", \"/disks/pcx86/\");\n sDiskettePath = sDiskettePath.replace(\"/disks/pcx86/private/\", \"/private-disks/pcx86/\");\n sDiskettePath = sDiskettePath.replace(\"/disks/pcx86/\", \"/pcjs-disks/pcx86/\");\n /*\n * TODO: Machines with saved states may be using lower-case disk image names, whereas we now use\n * UPPER-CASE names for disk images, so we lower-case both before comparing. The only problem with\n * removing these hacks is that we can never be sure when all saved states in the wild have been updated.\n */\n if (drive.sDiskettePath.toLowerCase() != sDiskettePath.toLowerCase()) {\n this.unloadDrive(iDrive, fAutoMount, true);\n if (drive.fBusy) {\n this.notice(\"Drive \" + iDrive + \" busy\");\n return 0;\n }\n drive.fBusy = true;\n if (fAutoMount) {\n drive.fAutoMount = true;\n this.cAutoMount++;\n if (this.messageEnabled()) this.printMessage(\"loading diskette '\" + sDisketteName + \"'\");\n }\n drive.fLocal = !!file;\n var disk = new Disk(this, drive, DiskAPI.MODE.PRELOAD);\n if (!disk.load(sDisketteName, sDiskettePath, file, this.doneLoadDrive)) {\n return 0;\n }\n return 1;\n }\n }\n return -1;\n }\n\n /**\n * doneLoadDrive(drive, disk, sDisketteName, sDiskettePath, fAutoMount)\n *\n * @this {FDC}\n * @param {Object} drive\n * @param {Disk} disk is set if the disk was successfully loaded, null if not\n * @param {string} sDisketteName\n * @param {string} sDiskettePath\n * @param {boolean} [fAutoMount]\n */\n doneLoadDrive(drive, disk, sDisketteName, sDiskettePath, fAutoMount)\n {\n var aDiskInfo;\n\n drive.fBusy = false;\n\n if (disk) {\n /*\n * We shouldn't mount the diskette unless the drive is able to handle it; for example, FD360 (40-track)\n * drives cannot read FD1200 (80-track) diskettes. However, I no longer require that the diskette's\n * sectors/track fall within the drive's standard maximum, because XDF diskettes use 19 physical sectors/track\n * on the first cylinder (1 more than the typical 18 sectors/track found on 1.44Mb diskettes) but declare\n * a larger logical size (23 512-byte sectors/track) to reflect the actual capacity of XDF tracks beyond the\n * first cylinder (ie, one 8Kb sector, one 2Kb sector, one 1Kb sector, and one 512-byte sector).\n */\n aDiskInfo = disk.info();\n if (disk && aDiskInfo[0] > drive.nCylinders || aDiskInfo[1] > drive.nHeads /* || aDiskInfo[2] > drive.nSectors */) {\n this.notice(\"Diskette \\\"\" + sDisketteName + \"\\\" too large for drive \" + String.fromCharCode(0x41 + drive.iDrive));\n disk = null;\n }\n }\n\n if (disk) {\n drive.disk = disk;\n drive.sDisketteName = sDisketteName;\n drive.sDiskettePath = sDiskettePath;\n\n /*\n * Since we allow a diskette image to be auto-mounted even if it isn't in the machine's list of disks,\n * let's add it to the list now, since the disk apparently exists.\n */\n if (!this.findDisketteByPath(sDiskettePath)) {\n this.addDiskette(sDisketteName, sDiskettePath);\n }\n\n /*\n * Adding local disk image names to the disk list seems like a nice idea, but it's too confusing,\n * because then it looks like the \"Mount\" button should be able to (re)load them, and that can NEVER\n * happen, for security reasons; local disk images can ONLY be loaded via the \"Mount\" button after\n * the user has selected them via the \"Choose File\" button.\n *\n * this.addDiskette(sDisketteName, sDiskettePath);\n *\n * So we're going to take a different approach: when displayDiskette() is asked to display the name\n * of a local disk image, it will map all such disks to \"Local Disk\", and any attempt to \"Mount\" such\n * a disk, will essentially result in a \"Disk not found\" error.\n */\n this.addDiskHistory(sDisketteName, sDiskettePath, disk);\n\n /*\n * For a local disk (ie, one loaded via mountDrive()), the disk.restore() performed by addDiskHistory()\n * may have altered the disk geometry, so refresh the disk info.\n */\n aDiskInfo = disk.info();\n\n /*\n * Clearly, a successful mount implies a disk change, and I suppose that, technically, an *unsuccessful*\n * mount should imply the same, but what would the real-world analog be? Inserting a piece of cardboard\n * instead of an actual diskette? In any case, if we can do the user a favor by pretending (as far as the\n * disk change line is concerned) that an unsuccessful mount never happened, let's do it.\n *\n * Successful unmounts are a different story, however; those *do* trigger a change. See unloadDrive().\n */\n this.regInput |= FDC.REG_INPUT.DISK_CHANGE;\n\n /*\n * With the addition of notify(), users are now \"alerted\" whenever a diskette has finished loading;\n * notify() is selective about its output, using print() if a print window is open, alert() otherwise.\n *\n * WARNING: This conversion of drive number to drive letter, starting with A:, is very simplistic\n * and will not match the drive mappings that DOS ultimately uses (ie, for drives beyond B:).\n */\n if (!drive.fnCallReady) this.notice(\"Mounted diskette \\\"\" + sDisketteName + \"\\\" in drive \" + String.fromCharCode(0x41 + drive.iDrive), drive.fAutoMount || fAutoMount);\n\n /*\n * Update the drive's current media parameters to match the disk's.\n */\n drive.nDiskCylinders = aDiskInfo[0];\n drive.nDiskHeads = aDiskInfo[1];\n drive.nDiskSectors = aDiskInfo[2];\n\n /*\n * Since you usually want the Computer to have focus again after loading a new diskette, let's try automatically\n * updating the focus after a successful load.\n */\n if (this.cmp) this.cmp.updateFocus();\n }\n else {\n drive.fLocal = false;\n }\n\n if (drive.fAutoMount) {\n drive.fAutoMount = false;\n if (!--this.cAutoMount) this.setReady();\n }\n\n this.displayDiskette(drive.iDrive);\n\n if (drive.fnCallReady) {\n drive.fnCallReady();\n drive.fnCallReady = null;\n }\n }\n\n /**\n * addDiskette(sName, sPath, fTop)\n *\n * @this {FDC}\n * @param {string} sName\n * @param {string} sPath\n * @param {boolean} [fTop] (default is bottom)\n */\n addDiskette(sName, sPath, fTop)\n {\n var controlDisks = this.bindings[\"listDisks\"];\n if (controlDisks && controlDisks.options) {\n for (var i = 0; i < controlDisks.options.length; i++) {\n if (controlDisks.options[i].value == sPath) return;\n }\n var controlOption = document.createElement(\"option\");\n controlOption.text = sName;\n controlOption.value = sPath;\n if (fTop && controlDisks.childNodes[0]) {\n controlDisks.insertBefore(controlOption, controlDisks.childNodes[0]);\n } else {\n controlDisks.appendChild(controlOption);\n }\n }\n }\n\n /**\n * findDisketteByPath(sPath)\n *\n * This is used to deal with mount requests (eg, autoMount) that supply a path without a name;\n * if we can find the path in the \"listDisks\" control, then we return the associated disk name.\n *\n * @this {FDC}\n * @param {string} sPath\n * @return {string|null}\n */\n findDisketteByPath(sPath)\n {\n var controlDisks = this.bindings[\"listDisks\"];\n if (controlDisks && controlDisks.options) {\n for (var i = 0; i < controlDisks.options.length; i++) {\n var control = controlDisks.options[i];\n if (control.value == sPath) return control.text;\n }\n }\n return null;\n }\n\n /**\n * findDisketteByName(sName)\n *\n * This is used to deal with mount requests (eg, autoMount) that supply a name without a path;\n * if we can find the name in the \"listDisks\" control, then we return the associated disk path.\n *\n * @this {FDC}\n * @param {string|undefined} sName\n * @return {string}\n */\n findDisketteByName(sName)\n {\n if (sName) {\n var controlDisks = this.bindings[\"listDisks\"];\n if (controlDisks && controlDisks.options) {\n for (var i = 0; i < controlDisks.options.length; i++) {\n var control = controlDisks.options[i];\n if (control.text == sName) return control.value;\n }\n }\n }\n return \"\";\n }\n\n /**\n * displayDiskette(iDrive, fUpdateDrive)\n *\n * @this {FDC}\n * @param {number} iDrive (unvalidated)\n * @param {boolean} [fUpdateDrive] is true to update the drive list to match the specified drive (eg, the auto-mount case)\n */\n displayDiskette(iDrive, fUpdateDrive)\n {\n /*\n * First things first: validate iDrive.\n */\n if (iDrive >= 0 && iDrive < this.aDrives.length) {\n var drive = this.aDrives[iDrive];\n var controlDisks = this.bindings[\"listDisks\"];\n var controlDrives = this.bindings[\"listDrives\"];\n /*\n * Next, make sure controls for both drives and disks exist.\n */\n if (controlDisks && controlDrives && controlDisks.options && controlDrives.options) {\n /*\n * Next, make sure the drive whose disk we're updating is the currently selected drive.\n */\n var i;\n var iDriveSelected = Str.parseInt(controlDrives.value, 10);\n var sTargetPath = (drive.fLocal? \"?\" : drive.sDiskettePath);\n if (!isNaN(iDriveSelected) && iDriveSelected == iDrive) {\n for (i = 0; i < controlDisks.options.length; i++) {\n if (controlDisks.options[i].value == sTargetPath) {\n if (controlDisks.selectedIndex != i) {\n controlDisks.selectedIndex = i;\n }\n break;\n }\n }\n if (i == controlDisks.options.length) controlDisks.selectedIndex = 0;\n }\n if (fUpdateDrive) {\n for (i = 0; i < controlDrives.options.length; i++) {\n if (Str.parseInt(controlDrives.options[i].value, 10) == drive.iDrive) {\n if (controlDrives.selectedIndex != i) {\n controlDrives.selectedIndex = i;\n }\n break;\n }\n }\n }\n }\n }\n }\n\n /**\n * updateSelectedDiskette()\n *\n * @this {FDC}\n */\n updateSelectedDiskette()\n {\n var control = this.bindings[\"listDisks\"];\n var controlDesc = this.bindings[\"descDisk\"];\n var controlOption = control.options[control.selectedIndex];\n if (controlDesc && controlOption) {\n var dataValue = {};\n var sValue = controlOption.getAttribute(\"data-value\");\n if (sValue) {\n try {\n dataValue = eval(\"(\" + sValue + \")\");\n } catch (e) {\n Component.error(this.type + \" option error: \" + e.message);\n }\n }\n var sHTML = dataValue['desc'];\n if (sHTML === undefined) sHTML = \"\";\n var sHRef = dataValue['href'];\n if (sHRef !== undefined) sHTML = \"<a href=\\\"\" + sHRef + \"\\\" target=\\\"_blank\\\">\" + sHTML + \"</a>\";\n controlDesc.innerHTML = sHTML;\n }\n }\n\n /**\n * waitDrives(fnCallReady)\n *\n * @this {FDC}\n * @param {function()|null} fnCallReady\n * @return {boolean} false if wait required, true otherwise\n */\n waitDrives(fnCallReady)\n {\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n var drive = this.aDrives[iDrive];\n if (drive && drive.fBusy) {\n if (!drive.fnCallReady) drive.fnCallReady = fnCallReady;\n return false;\n }\n }\n return true;\n }\n\n /**\n * unloadDrive(iDrive, fAutoUnload, fQuiet)\n *\n * @this {FDC}\n * @param {number} iDrive (pre-validated)\n * @param {boolean} [fAutoUnload] is true if this unload is being forced as part of an automount and/or restored mount\n * @param {boolean} [fQuiet]\n */\n unloadDrive(iDrive, fAutoUnload, fQuiet)\n {\n var drive = this.aDrives[iDrive];\n if (drive.disk) {\n /*\n * Before we toss the disk's information, capture any deltas that may have occurred.\n */\n this.updateDiskHistory(drive.sDisketteName, drive.sDiskettePath, drive.disk);\n drive.sDisketteName = \"\";\n drive.sDiskettePath = \"\";\n drive.disk = null;\n drive.fLocal = false;\n\n this.regInput |= FDC.REG_INPUT.DISK_CHANGE;\n\n /*\n * WARNING: This conversion of drive number to drive letter, starting with A:, is very simplistic\n * and is not guaranteed to match the drive mapping that DOS ultimately uses.\n */\n if (!fQuiet) {\n this.notice(\"Drive \" + String.fromCharCode(0x41 + iDrive) + \" unloaded\", fAutoUnload);\n }\n /*\n * Try to avoid any unnecessary hysteresis regarding the diskette display if this unload is merely\n * a prelude to another load.\n */\n if (!fAutoUnload && !fQuiet) {\n this.displayDiskette(iDrive);\n }\n }\n }\n\n /**\n * unloadAllDrives(fDiscard)\n *\n * @this {FDC}\n * @param {boolean} fDiscard to discard all disk history before unloading\n */\n unloadAllDrives(fDiscard)\n {\n if (fDiscard) {\n this.aDiskHistory = [];\n }\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n this.unloadDrive(iDrive, true);\n }\n }\n\n /**\n * addDiskHistory(sDisketteName, sDiskettePath, disk)\n *\n * @this {FDC}\n * @param {string} sDisketteName\n * @param {string} sDiskettePath\n * @param {Disk} disk containing corresponding disk image\n */\n addDiskHistory(sDisketteName, sDiskettePath, disk)\n {\n var i;\n //\n for (i = 0; i < this.aDiskHistory.length; i++) {\n if (this.aDiskHistory[i][1] == sDiskettePath) {\n var nChanges = disk.restore(this.aDiskHistory[i][2]);\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"disk '\" + sDisketteName + \"' restored from history (\" + nChanges + \" changes)\");\n }\n return;\n }\n }\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"disk '\" + sDisketteName + \"' added to history (nothing to restore)\");\n }\n this.aDiskHistory[i] = [sDisketteName, sDiskettePath, []];\n }\n\n /**\n * removeDiskHistory(sDisketteName, sDiskettePath)\n *\n * @this {FDC}\n * @param {string} sDisketteName\n * @param {string} sDiskettePath\n */\n removeDiskHistory(sDisketteName, sDiskettePath)\n {\n var i;\n for (i = 0; i < this.aDiskHistory.length; i++) {\n if (this.aDiskHistory[i][1] == sDiskettePath) {\n this.aDiskHistory.splice(i, 1);\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"disk '\" + sDisketteName + \"' removed from history\");\n }\n return;\n }\n }\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"unable to remove disk '\" + sDisketteName + \"' from history (\" + sDiskettePath + \")\");\n }\n }\n\n /**\n * updateDiskHistory(sDisketteName, sDiskettePath, disk)\n *\n * @this {FDC}\n * @param {string} sDisketteName\n * @param {string} sDiskettePath\n * @param {Disk} disk containing corresponding disk image, with possible deltas\n */\n updateDiskHistory(sDisketteName, sDiskettePath, disk)\n {\n var i;\n for (i = 0; i < this.aDiskHistory.length; i++) {\n if (this.aDiskHistory[i][1] == sDiskettePath) {\n this.aDiskHistory[i][2] = disk.save();\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"disk '\" + sDisketteName + \"' updated in history\");\n }\n return;\n }\n }\n /*\n * I used to report this as an error (at least in the DEBUG release), but it's no longer really\n * an error, because if we're trying to re-mount a clean copy of a disk, we toss its history, then\n * unload, and then reload/remount. And since unloadDrive's normal behavior is to call updateDiskHistory()\n * before unloading, the fact that the disk is no longer listed here can't be treated as an error.\n */\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"unable to update disk '\" + sDisketteName + \"' in history (\" + sDiskettePath + \")\");\n }\n }\n\n /**\n * outFDCOutput(port, bOut, addrFrom)\n *\n * @this {FDC}\n * @param {number} port (0x3F2, output only)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outFDCOutput(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"OUTPUT\");\n if (!(bOut & FDC.REG_OUTPUT.ENABLE)) {\n this.initController();\n /*\n * initController() resets, among other things, the selected drive (this.iDrive), so if we were\n * still updating this.iDrive below based on the \"drive select\" bits in regOutput, we would want\n * to make sure those bits now match what initController() set. But since we no longer do that\n * (see below), this is no longer needed either.\n *\n * bOut = (bOut & ~FDC.REG_OUTPUT.DS) | this.iDrive;\n */\n }\n else if (!(this.regOutput & FDC.REG_OUTPUT.ENABLE)) {\n /*\n * When FDC.REG_OUTPUT.ENABLE transitions from 0 to 1, generate an interrupt (assuming INT_ENABLE is set).\n */\n this.requestInterrupt();\n }\n /*\n * This no longer updates the internally selected drive (this.iDrive) based on regOutput, because (a) there seems\n * to be no point, as all drive-related commands include their own \"drive select\" bits, and (b) it breaks the\n * MODEL_5170 boot code. Here's why:\n *\n * Unlike previous models, the MODEL_5170 BIOS probes all installed diskette drives to determine drive type;\n * ie, FD360 (40-track) or FD1200 (80-track). So if there are two drives, the last selected drive will be drive 1.\n * Immediately before booting, the BIOS issues an INT 0x13/AH=0 reset, which writes regOutput two times: first\n * with FDC.REG_OUTPUT.ENABLE clear, and then with it set. However, both times, it ALSO loads the last selected\n * drive number into regOutput's \"drive select\" bits.\n *\n * If we switched our selected drive to match regOutput, then the ST0 value we returned on an SENSE_INT command\n * following the regOutput reset operation would indicate drive 1 instead of drive 0. But the BIOS requires\n * the ST0 result from the SENSE_INT command ALWAYS be 0xC0 (not 0xC1), so the controller must not be propagating\n * regOutput's \"drive select\" bits in the way I originally assumed.\n *\n * var iDrive = bOut & FDC.REG_OUTPUT.DS;\n * if (bOut & (FDC.REG_OUTPUT.MOTOR_D0 << iDrive)) this.iDrive = iDrive;\n */\n this.regOutput = bOut;\n }\n\n /**\n * inFDCDiagnostic(port, addrFrom)\n *\n * It turns out that any 5170 configuration without an HDC component that attempts to use either the REV2 or REV3\n * PC AT ROM BIOS will fail with error \"601-Diskette Error\", unless we also provide this \"D/S/P DIAGNOSTIC REGISTER\".\n * The original 5170 REV1 BIOS didn't have this requirement.\n *\n * I'm unable to find any documentation on this so-called \"D/S/P DIAGNOSTIC REGISTER\" (port 0x3F1) or the \"D/S/P CARD\"\n * to which the ROM BIOS refers. But it seems clear that if we don't provide the expected response from the DIAGNOSTIC\n * REGISTER, and there's no HDC to respond to the MULTIPLE DATA RATE CAPABLE test that follows, then an error is\n * inevitable. Clearly, there is a very intimate relationship between the FDC and HDC portions of this card.\n *\n * Here's the relevant code from the REV3 PC AT ROM BIOS (TEST2.ASM):\n *\n * ;----- CHECK FOR MULTIPLE DATA RATE CAPABILITY\n *\n * J_OK:\n * MOV DX,03F1H ; D/S/P DIAGNOSTIC REGISTER\n * IN AL,DX ; READ D/S/P TYPE CODE\n * AND AL,11111000B ; KEEP ONLY UNIQUE CODE FOR D/S/P\n * CMP AL,01010000B ; D/S/P CARD - MULTIPLE DATA RATE?\n * JZ J_OK3 ; IF SO JUMP\n *\n * MOV DX,05F7H ; FIXED DISK DIAGNOSTIC REGISTER\n * IN AL,DX ; READ FIXED DISK TYPE CODE\n * AND AL,11110000B ; KEEP ONLY UNIQUE CODE FOR F/D\n * CMP AL,10100000B ; FIXED DISK ADAPTER ?\n * JZ J_FAIL ; MUST BE COMBO ELSE ERROR\n *\n * MOV BL,0FH ; OUTER LOOP COUNT WAIT FOR BUSY OFF\n * SUB CX,CX\n * MOV DX,01F7H ; HARD FILE STATUS PORT\n * J_OK1:\n * IN AL,DX ; GET THE STATUS\n * TEST AL,080H ; IS THE CONTROLLER BUSY?\n * JZ J_OK2 ; CONTINUE IF NOT\n * LOOP J_OK1 ; TRY AGAIN\n * DEC BL ; DECREMENT OUTER LOOP\n * JNZ J_OK1 ; TRY AGAIN IF NOT ZERO\n * AND AL,0CH ; BITS 2 & 3 = 0 IF MULTI DATA CAPABLE\n * JZ J_OK3 ; GO IF YES\n * JMP SHORT J_FAIL ; NO MULTIPLE DATA RATE CAPABILITY\n * J_OK2:\n * MOV DX,1F4H ; VERIFY MULTIPLE DATA RATE CAPABLE\n * MOV AL,055H ; WRITE TO THE CYLINDER BYTE\n * OUT DX,AL\n * JMP $+2 ; I/O DELAY\n * IN AL,DX ; CHECK DATA WRITTEN = DATA READ\n * CMP AL,055H\n * JNZ J_FAIL ; GO IF NOT\n * MOV AL,0AAH ; WRITE ANOTHER PATTERN\n * OUT DX,AL\n * JMP $+2 ; I/O DELAY\n * IN AL,DX\n * CMP AL,0AAH ; IS DATA PATTERN THE SAME?\n * JZ J_OK3 ; GO IF SO\n *\n * J_FAIL:\n * OR @MFG_ERR_FLAG+1,DSK_FAIL; <><><><><><><><><><><><><>\n * ; <><> DISKETTE FAILED <><>\n * MOV SI,OFFSET E601 ; GET ADDRESS OF MESSAGE\n * CALL E_MSG ; GO PRINT ERROR MESSAGE\n * JMP SHORT F15C ; SKIP SETUP IF ERROR\n *\n * J_OK3:\n * OR @LASTRATE,DUAL ; TURN ON DSP/COMBO FLAG\n *\n * @this {FDC}\n * @param {number} port (0x3F1, input only)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inFDCDiagnostic(port, addrFrom)\n {\n var b = 0x50; // we simply return the expected pattern (01010000B); see code excerpt above\n this.printMessageIO(port, null, addrFrom, \"DIAG\", b);\n return b;\n }\n\n /**\n * inFDCStatus(port, addrFrom)\n *\n * @this {FDC}\n * @param {number} port (0x3F4, input only)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inFDCStatus(port, addrFrom)\n {\n this.printMessageIO(port, null, addrFrom, \"STATUS\", this.regStatus);\n return this.regStatus;\n }\n\n /**\n * inFDCData(port, addrFrom)\n *\n * @this {FDC}\n * @param {number} port (0x3F5, input/output)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inFDCData(port, addrFrom)\n {\n var bIn = 0;\n if (this.regDataIndex < this.regDataTotal) {\n bIn = this.regDataArray[this.regDataIndex];\n }\n /*\n * As per the discussion in doCmd(), once the first byte of the Result Phase has been read, the interrupt must be cleared.\n */\n if (this.regOutput & FDC.REG_OUTPUT.INT_ENABLE) {\n if (this.chipset) this.chipset.clearIRR(ChipSet.IRQ.FDC);\n }\n if (this.messageEnabled()) {\n this.printMessageIO(port, null, addrFrom, \"DATA[\" + this.regDataIndex + \"]\", bIn);\n }\n if (++this.regDataIndex >= this.regDataTotal) {\n this.regStatus &= ~(FDC.REG_STATUS.READ_DATA | FDC.REG_STATUS.BUSY);\n this.regDataIndex = this.regDataTotal = 0;\n }\n return bIn;\n }\n\n /**\n * outFDCData(port, bOut, addrFrom)\n *\n * @this {FDC}\n * @param {number} port (0x3F5, input/output)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outFDCData(port, bOut, addrFrom)\n {\n if (this.messageEnabled()) {\n this.printMessageIO(port, bOut, addrFrom, \"DATA[\" + this.regDataTotal + \"]\");\n }\n\n if (this.regDataTotal < this.regDataArray.length) {\n this.regDataArray[this.regDataTotal++] = bOut;\n }\n var bCmd = this.regDataArray[0];\n var bCmdMasked = bCmd & FDC.REG_DATA.CMD.MASK;\n if (FDC.aCmdInfo[bCmdMasked] !== undefined) {\n if (this.regDataTotal >= FDC.aCmdInfo[bCmdMasked].cbReq) {\n this.doCmd();\n }\n return;\n }\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"unsupported FDC command: \" + Str.toHexByte(bCmd));\n if (MAXDEBUG) this.dbg.stopCPU();\n }\n }\n\n /**\n * inFDCInput(port, addrFrom)\n *\n * @this {FDC}\n * @param {number} port (0x3F7, input only, MODEL_5170 only)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inFDCInput(port, addrFrom)\n {\n var bIn = this.regInput;\n /*\n * TODO: Determine when the DISK_CHANGE bit is *really* cleared (this is just a guess)\n */\n this.regInput &= ~FDC.REG_INPUT.DISK_CHANGE;\n this.printMessageIO(port, null, addrFrom, \"INPUT\", bIn);\n return bIn;\n }\n\n /**\n * outFDCControl(port, bOut, addrFrom)\n *\n * @this {FDC}\n * @param {number} port (0x3F7, output only, MODEL_5170 only)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outFDCControl(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"CONTROL\");\n this.regControl = bOut;\n }\n\n /**\n * doCmd()\n *\n * @this {FDC}\n */\n doCmd()\n {\n var fIRQ = false;\n this.regDataIndex = 0;\n var bCmd = this.popCmd();\n var drive, bDrive, bHead, c, h, r, n;\n\n /*\n * NOTE: We currently ignore the FDC.REG_DATA.CMD.SK, FDC.REG_DATA.CMD.MF and FDC.REG_DATA.CMD.MT bits of every command.\n * The only command bit of possible interest down the road might be the FDC.REG_DATA.CMD.MT (Multi-Track); the rest relate\n * to storage format details that we cannot emulate as long as our diskette images contain nothing more than sector\n * data without any formatting data.\n *\n * Similarly, we ignore parameters like SRT, HUT, HLT and the like, since our \"motors\" don't require physical delays;\n * however, if timing issues become compatibility issues, we'll have to revisit those delays. In any case, the maximum\n * speed of the simulation will still be limited by various spin-loops in the ROM BIOS that wait prescribed times, so even\n * with infinitely fast hardware, the simulation will never run as fast as it theoretically could, unless we opt to identify\n * those spin-loops and either patch them or skip over them.\n */\n var bCmdMasked = bCmd & FDC.REG_DATA.CMD.MASK;\n\n switch (bCmdMasked) {\n case FDC.REG_DATA.CMD.SPECIFY: // 0x03\n this.popSRT(); // SRT and HUT (encodings?)\n this.popHLT(); // HLT and ND (encodings?)\n this.beginResult();\n /*\n * No results are provided by this command, and fIRQ should remain false\n */\n break;\n\n case FDC.REG_DATA.CMD.SENSE_DRIVE: // 0x04\n bDrive = this.popCmd(FDC.TERMS.DS);\n bHead = (bDrive >> 2) & 0x1;\n this.iDrive = (bDrive & 0x3);\n drive = this.aDrives[this.iDrive];\n this.beginResult();\n this.pushST3(drive);\n break;\n\n case FDC.REG_DATA.CMD.WRITE_DATA: // 0x05\n case FDC.REG_DATA.CMD.READ_DATA: // 0x06\n bDrive = this.popCmd(FDC.TERMS.DS); // Drive Select\n bHead = (bDrive >> 2) & 0x1; // isolate HD (Head Select) bits\n this.iDrive = (bDrive & 0x3); // isolate DS (Drive Select, aka Unit Select) bits\n drive = this.aDrives[this.iDrive];\n drive.bHead = bHead;\n c = drive.bCylinder = this.popCmd(FDC.TERMS.C); // C\n h = this.popCmd(FDC.TERMS.H); // H\n /*\n * Controller docs say that H should always match HD, so I assert that, but what if someone\n * made a mistake and didn't program them identically -- what would happen? Which should we honor?\n */\n\n r = drive.bSector = this.popCmd(FDC.TERMS.R); // R\n n = this.popCmd(FDC.TERMS.N); // N\n drive.nBytes = 128 << n; // 0 => 128, 1 => 256, 2 => 512, 3 => 1024\n drive.bSectorEnd = this.popCmd(FDC.TERMS.EOT); // EOT (final sector number on a cylinder)\n this.popCmd(FDC.TERMS.GPL); // GPL (spacing between sectors, excluding VCO Sync Field; 3)\n this.popCmd(FDC.TERMS.DTL); // DTL (when N is 0, DTL stands for the data length to read out or write into the sector)\n if (bCmdMasked == FDC.REG_DATA.CMD.READ_DATA)\n this.doRead(drive);\n else\n this.doWrite(drive);\n this.pushResults(drive, bCmd, bHead, c, h, r, n);\n fIRQ = true;\n break;\n\n case FDC.REG_DATA.CMD.RECALIBRATE: // 0x07\n bDrive = this.popCmd(FDC.TERMS.DS);\n this.iDrive = (bDrive & 0x3);\n drive = this.aDrives[this.iDrive];\n drive.bCylinder = drive.bCylinderSeek = 0;\n drive.resCode = FDC.REG_DATA.RES.SEEK_END | FDC.REG_DATA.RES.TRACK0;\n this.beginResult(); // no results provided; this command is typically followed by FDC.REG_DATA.CMD.SENSE_INT\n fIRQ = true;\n break;\n\n case FDC.REG_DATA.CMD.SENSE_INT: // 0x08\n drive = this.aDrives[this.iDrive];\n drive.bHead = 0; // this command is documented as ALWAYS returning a head address of 0 in ST0; see pushST0()\n this.beginResult();\n this.pushST0(drive);\n this.pushResult(drive.bCylinder, FDC.TERMS.PCN);\n /*\n * For some strange reason, the \"DISK_RESET\" function in the MODEL_5170_REV3 BIOS resets the\n * adapter and then issues FOUR -- that's right, not ONE but FOUR -- SENSE INTERRUPT STATUS commands\n * in a row, and expects ST0 to contain a different drive number after each command (first 0, then 1,\n * then 2, and finally 3). What makes this doubly weird is SENSE INTERRUPT STATUS (unlike SENSE\n * DRIVE STATUS) is a drive-agnostic command.\n *\n * Didn't the original PC AT \"HFCOMBO\" controller limit support to TWO diskette drives max?\n * And even if the PC AT supported other FDC controllers that DID support up to FOUR diskette drives,\n * why should \"DISK_RESET\" hard-code a 4-drive loop?\n *\n * Well, whatever. All this head-scratching doesn't change the fact that I apparently have to\n * \"auto-increment\" the internal drive number (this.iDrive) after each SENSE INTERRUPT STATUS command.\n */\n this.iDrive = (this.iDrive + 1) & 0x3;\n /*\n * No interrupt is generated by this command, so fIRQ should remain false.\n */\n break;\n\n case FDC.REG_DATA.CMD.READ_ID: // 0x0A\n /*\n * This command is used by \"SETUP_DBL\" in the MODEL_5170_REV3 BIOS to determine if a double-density\n * (40-track) diskette has been inserted in a high-density (80-track) drive; ie, whether \"double stepping\"\n * is required, since only 40 of the 80 possible \"steps\" are valid for a double-density diskette.\n *\n * To start, we'll focus on making this work in the normal case (80-track diskette in 80-track drive).\n */\n bDrive = this.popCmd(FDC.TERMS.DS);\n bHead = (bDrive >> 2) & 0x1;\n this.iDrive = (bDrive & 0x3);\n drive = this.aDrives[this.iDrive];\n c = drive.bCylinder;\n h = drive.bHead = bHead;\n r = drive.bSector = 1;\n n = 0;\n drive.resCode = FDC.REG_DATA.RES.NONE;\n if (drive.disk && (drive.sector = drive.disk.seek(drive.bCylinder, drive.bHead, drive.bSector))) {\n n = (drive.sector['length'] >> 8);\n } else {\n /*\n * TODO: Determine the appropriate response code(s) for the possible errors that can occur here.\n */\n drive.resCode = FDC.REG_DATA.RES.NOT_READY | FDC.REG_DATA.RES.INCOMPLETE;\n }\n this.pushResults(drive, bCmd, bHead, c, h, r, n);\n fIRQ = true;\n break;\n\n case FDC.REG_DATA.CMD.FORMAT_TRACK: // 0x0D\n bDrive = this.popCmd(FDC.TERMS.DS);\n bHead = (bDrive >> 2) & 0x1;\n this.iDrive = (bDrive & 0x3);\n drive = this.aDrives[this.iDrive];\n c = drive.bCylinder;\n h = drive.bHead = bHead;\n r = 1;\n n = this.popCmd(FDC.TERMS.N); // N\n drive.nBytes = 128 << n; // 0 => 128, 1 => 256, 2 => 512, 3 => 1024 (bytes/sector)\n drive.bSectorEnd = this.popCmd(FDC.TERMS.SC); // SC (sectors/track)\n this.popCmd(FDC.TERMS.GPL); // GPL (spacing between sectors, excluding VCO Sync Field; 3)\n drive.bFiller = this.popCmd(FDC.TERMS.D); // D (filler byte)\n this.doFormat(drive);\n this.pushResults(drive, bCmd, bHead, c, h, r, n);\n fIRQ = true;\n break;\n\n case FDC.REG_DATA.CMD.SEEK: // 0x0F\n bDrive = this.popCmd(FDC.TERMS.DS);\n bHead = (bDrive >> 2) & 0x1;\n this.iDrive = (bDrive & 0x3);\n drive = this.aDrives[this.iDrive];\n drive.bHead = bHead;\n /*\n * As discussed in initDrive(), we can no longer simply set bCylinder to the specified NCN;\n * instead, we must calculate the delta between bCylinderSeek and the NCN, and adjust bCylinder\n * by that amount. Then we simply move the NCN into bCylinderSeek without any range checking.\n *\n * Since bCylinder is now expressly defined as the \"physical\" cylinder number, it must never\n * be allowed to exceed the physical boundaries of the drive (ie, never lower than 0, and never\n * greater than or equal to nCylinders).\n */\n c = this.popCmd(FDC.TERMS.NCN);\n drive.bCylinder += c - drive.bCylinderSeek;\n if (drive.bCylinder < 0) drive.bCylinder = 0;\n if (drive.bCylinder >= drive.nCylinders) drive.bCylinder = drive.nCylinders - 1;\n drive.bCylinderSeek = c;\n drive.resCode = FDC.REG_DATA.RES.SEEK_END;\n /*\n * TODO: To properly support ALL the ST3 result bits (not just TRACK0), we need a resCode\n * update() function that all FDC commands can use. This code is merely sufficient to get us\n * through the \"DSKETTE_SETUP\" gauntlet in the MODEL_5170 BIOS.\n */\n if (!drive.bCylinder) {\n drive.resCode |= FDC.REG_DATA.RES.TRACK0;\n }\n this.beginResult(); // like FDC.REG_DATA.CMD.RECALIBRATE, no results are provided\n fIRQ = true;\n break;\n\n default:\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"unsupported FDC operation: \" + Str.toHexByte(bCmd));\n if (MAXDEBUG) this.dbg.stopCPU();\n }\n break;\n }\n\n if (this.regDataTotal > 0) {\n this.regStatus |= (FDC.REG_STATUS.READ_DATA | FDC.REG_STATUS.BUSY);\n }\n\n /*\n * After the Execution Phase (eg, DMA Terminal Count has occurred, or the EOT sector has been read/written),\n * an interrupt is supposed to occur, signaling the beginning of the Result Phase. Once the first byte of the\n * result has been read, the interrupt is cleared (see inFDCData).\n *\n * TODO: Technically, interrupt request status should be cleared by the FDC.REG_DATA.CMD.SENSE_INT command; in fact,\n * if that command is issued and no interrupt was pending, then FDC.REG_DATA.RES.INVALID should be returned (via ST0).\n */\n \n /*\n * When the Windows 95 HSFLOP (\"High-Speed Floppy\") VxD performs its diskette change-line detection logic\n * (\"determine_changeline\"), it sets a special callback (\"dcl_callback_int_entry\") for its interrupt handler\n * to invoke, then issues a READ_ID command, and then sets a bit telling its interrupt handler to expect an\n * interrupt (\"FLP_NEC_INT_EXPECTED\").\n * \n * Technically, it should have set *both* \"dcl_callback_int_entry\" *and* \"FLP_NEC_INT_EXPECTED\" *before*\n * issuing the READ_ID command, but I imagine the author assumed all was fine, since interrupts had been\n * disabled with a \"cli\" beforehand and had not been re-enabled with an \"sti\" yet. But alas, the function\n * used to the issue the READ_ID command (\"NecOut\") immediately re-enabled interrupts.\n * \n * So, if we request an interrupt immediately after the READ_ID command, the interrupt handler will think\n * our interrupt is spurious (ie, not EXPECTED). In this particular case, there are only about 10 instructions\n * executed from the time READ_ID is issued until the \"FLP_NEC_INT_EXPECTED\" bit is set, but I'm going to\n * add a little padding to that, in part because I wouldn't be surprised if there are other places where a\n * similar assumption exists (ie, either that \"NecOut\" leaves interrupts disabled, or simply that the floppy\n * controller is an inherently slow device).\n * \n * TODO: Determine why the Football prototype disk fails to boot if we specify a larger delay (eg, 32) and\n * why TopView 1.10 hangs when the delay is set to 16. I've worked around those questions for now, by simply\n * limiting the delay\n */\n this.requestInterrupt(drive && fIRQ && !(drive.resCode & FDC.REG_DATA.RES.NOT_READY), bCmdMasked == FDC.REG_DATA.CMD.READ_ID? 16 : 0);\n }\n\n /**\n * pushResults(drive, bCmd, bHead, c, h, r, n)\n *\n * @param {Object} drive\n * @param {number} bCmd\n * @param {number} bHead\n * @param {number} c\n * @param {number} h\n * @param {number} r\n * @param {number} n\n */\n pushResults(drive, bCmd, bHead, c, h, r, n)\n {\n this.beginResult();\n this.pushST0(drive);\n this.pushST1(drive);\n this.pushST2(drive);\n /*\n * NOTE: I used to set the following C/H/R/N results using the values that advanceSector() had \"advanced\"\n * them to, which seemed logical but was technically incorrect. For non-multi-track reads, they should match\n * the programmed C/H/R/N values, except when EOT has been reached, in which case C = C + 1 and R = 1.\n *\n * For multi-track, the LSB of H should be complemented whenever EOT has been reached, which I \"informally\"\n * detect by testing if the drive's current bCylinder and/or bHead positions advanced to a new cylinder or head,\n * and apparently, C should never be advanced if H was initially 0.\n *\n * I don't do strict EOT comparisons here or elsewhere, because it allows the controller to work with a wider\n * range of disks (eg, \"fake\" XDF disk images that contain 23 512-byte sectors/track).\n */\n var i = 0;\n if (c != drive.bCylinder || h != drive.bHead) {\n i = r = 1;\n }\n if (bCmd & FDC.REG_DATA.CMD.MT) {\n h ^= i;\n if (!bHead) i = 0;\n }\n c += i;\n this.pushResult(c, FDC.TERMS.C); // formerly drive.bCylinder\n this.pushResult(h, FDC.TERMS.H); // formerly drive.bHead\n this.pushResult(r, FDC.TERMS.R); // formerly drive.bSector\n this.pushResult(n, FDC.TERMS.N);\n }\n\n /**\n * popCmd(name)\n *\n * @this {FDC}\n * @param {string|undefined} [name]\n * @return {number}\n */\n popCmd(name)\n {\n\n var bCmd = this.regDataArray[this.regDataIndex];\n if (DEBUG && this.messageEnabled(Messages.PORT | Messages.FDC)) {\n var bCmdMasked = bCmd & FDC.REG_DATA.CMD.MASK;\n if (!name && !this.regDataIndex && FDC.aCmdInfo[bCmdMasked]) name = FDC.aCmdInfo[bCmdMasked].name;\n this.printMessage(this.idComponent + \".popCmd(\" + (name || this.regDataIndex) + \"): \" + Str.toHexByte(bCmd), true);\n }\n this.regDataIndex++;\n return bCmd;\n }\n\n /**\n * popHLT()\n *\n * NOTE: This byte is actually a combination of HLT (Head Load Time) and ND (Non-DMA Mode)\n *\n * @this {FDC}\n */\n popHLT()\n {\n this.popCmd(FDC.TERMS.HLT);\n // this.nHLT = this.popCmd(FDC.TERMS.HLT);\n }\n\n /**\n * popSRT()\n *\n * NOTE: This byte is actually a combination of SRT (Step Rate Time) and HUT (Head Unload Time)\n *\n * @this {FDC}\n */\n popSRT()\n {\n this.popCmd(FDC.TERMS.SRT);\n // this.nSRT = this.popCmd(FDC.TERMS.SRT);\n }\n\n /**\n * requestInterrupt(fCondition, nDelay)\n * \n * Request an FDC interrupt, as long as INT_ENABLE is set (and the optional supplied condition, if any, is true).\n * \n * @this {FDC}\n * @param {boolean} [fCondition]\n * @param {number} [nDelay]\n */\n requestInterrupt(fCondition = true, nDelay = 0)\n {\n if (fCondition && (this.regOutput & FDC.REG_OUTPUT.INT_ENABLE)) {\n if (this.chipset) this.chipset.setIRR(ChipSet.IRQ.FDC, nDelay);\n }\n }\n \n /**\n * beginResult()\n *\n * @this {FDC}\n */\n beginResult()\n {\n this.regDataIndex = this.regDataTotal = 0;\n }\n\n /**\n * pushResult(bResult, name)\n *\n * @this {FDC}\n * @param {number} bResult\n * @param {string|undefined} [name]\n */\n pushResult(bResult, name)\n {\n if (DEBUG && this.messageEnabled(Messages.PORT | Messages.FDC)) {\n this.printMessage(this.idComponent + \".pushResult(\" + (name || this.regDataTotal) + \"): \" + Str.toHexByte(bResult), true);\n }\n\n this.regDataArray[this.regDataTotal++] = bResult;\n }\n\n /**\n * pushST0(drive)\n *\n * @this {FDC}\n * @param {Object} drive\n */\n pushST0(drive)\n {\n this.pushResult(drive.iDrive | (drive.bHead << 2) | (drive.resCode & FDC.REG_DATA.RES.ST0), FDC.TERMS.ST0);\n }\n\n /**\n * pushST1(drive)\n *\n * @this {FDC}\n * @param {Object} drive\n */\n pushST1(drive)\n {\n this.pushResult((drive.resCode & FDC.REG_DATA.RES.ST1) >>> 8, FDC.TERMS.ST1);\n }\n\n /**\n * pushST2(drive)\n *\n * @this {FDC}\n * @param {Object} drive\n */\n pushST2(drive)\n {\n this.pushResult((drive.resCode & FDC.REG_DATA.RES.ST2) >>> 16, FDC.TERMS.ST2);\n }\n\n /**\n * pushST3(drive)\n *\n * @this {FDC}\n * @param {Object} drive\n */\n pushST3(drive)\n {\n this.pushResult((drive.resCode & FDC.REG_DATA.RES.ST3) >>> 24, FDC.TERMS.ST3);\n }\n\n /**\n * doDMARead(drive, b, done)\n *\n * @this {FDC}\n * @param {Object} drive\n * @param {number} b\n * @param {function(number,boolean)} done\n */\n doDMARead(drive, b, done)\n {\n if (b === undefined || b < 0) {\n this.readData(drive, done);\n return;\n }\n /*\n * The DMA controller should be ASKING for data, not GIVING us data; this suggests an internal DMA miscommunication\n */\n if (DEBUG) this.printMessage(this.idComponent + \".doDMARead(): invalid DMA acknowledgement\");\n done(-1, false);\n }\n\n /**\n * doDMAWrite(drive, b)\n *\n * @this {FDC}\n * @param {Object} drive\n * @param {number} b\n * @return {number}\n */\n doDMAWrite(drive, b)\n {\n if (b !== undefined && b >= 0)\n return this.writeData(drive, b);\n /*\n * The DMA controller should be GIVING us data, not ASKING for data; this suggests an internal DMA miscommunication\n */\n if (DEBUG) this.printMessage(this.idComponent + \".doDMAWrite(): invalid DMA acknowledgement\");\n return -1;\n }\n\n /**\n * doDMAFormat(drive, b)\n *\n * @this {FDC}\n * @param {Object} drive\n * @param {number} b\n * @returns {number}\n */\n doDMAFormat(drive, b)\n {\n if (b !== undefined && b >= 0)\n return this.writeFormat(drive, b);\n /*\n * The DMA controller should be GIVING us data, not ASKING for data; this suggests an internal DMA miscommunication\n */\n if (DEBUG) this.printMessage(this.idComponent + \".doDMAFormat(): invalid DMA acknowledgement\");\n return -1;\n }\n\n /**\n * doRead(drive)\n *\n * @this {FDC}\n * @param {Object} drive\n */\n doRead(drive)\n {\n /*\n * With only NOT_READY and INCOMPLETE set, an empty drive causes DOS to report \"General Failure\";\n * with the addition of NO_DATA, DOS reports \"Sector not found\". The traditional \"Drive not ready\"\n * error message is not triggered by anything we return here, but simply by BIOS commands timing out.\n */\n drive.resCode = FDC.REG_DATA.RES.NOT_READY | FDC.REG_DATA.RES.INCOMPLETE;\n\n if (drive.disk) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".doRead(CHS=\" + drive.bCylinder + ':' + drive.bHead + ':' + drive.bSector + \",PBA=\" + (drive.bCylinder * (drive.disk.nHeads * drive.disk.nSectors) + drive.bHead * drive.disk.nSectors + drive.bSector-1) + ')');\n }\n drive.sector = null;\n drive.resCode = FDC.REG_DATA.RES.NONE;\n if (this.chipset) {\n this.chipset.connectDMA(ChipSet.DMA_FDC, this, 'dmaRead', drive);\n this.chipset.requestDMA(ChipSet.DMA_FDC);\n }\n }\n }\n\n /**\n * doWrite(drive)\n *\n * @this {FDC}\n * @param {Object} drive\n */\n doWrite(drive)\n {\n drive.resCode = FDC.REG_DATA.RES.NOT_READY | FDC.REG_DATA.RES.INCOMPLETE;\n\n if (drive.disk) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".doWrite(CHS=\" + drive.bCylinder + ':' + drive.bHead + ':' + drive.bSector + \",PBA=\" + (drive.bCylinder * (drive.disk.nHeads * drive.disk.nSectors) + drive.bHead * drive.disk.nSectors + drive.bSector-1) + ')');\n }\n if (drive.disk.fWriteProtected) {\n drive.resCode = FDC.REG_DATA.RES.NOT_WRITABLE | FDC.REG_DATA.RES.INCOMPLETE;\n return;\n }\n drive.sector = null;\n drive.resCode = FDC.REG_DATA.RES.NONE;\n if (this.chipset) {\n this.chipset.connectDMA(ChipSet.DMA_FDC, this, 'dmaWrite', drive);\n this.chipset.requestDMA(ChipSet.DMA_FDC);\n }\n }\n }\n\n /**\n * doFormat(drive)\n *\n * drive is initialized by doCmd() to the following extent:\n *\n * drive.bHead (ignored)\n * drive.nBytes (bytes/sector)\n * drive.bSectorEnd (sectors/track)\n * drive.bFiller (fill byte)\n *\n * and we expect the DMA controller to provide C, H, R and N (ie, 4 bytes) for each sector to be formatted.\n *\n * @this {FDC}\n * @param {Object} drive\n */\n doFormat(drive)\n {\n drive.resCode = FDC.REG_DATA.RES.NOT_READY | FDC.REG_DATA.RES.INCOMPLETE;\n\n if (drive.disk) {\n drive.sector = null;\n drive.resCode = FDC.REG_DATA.RES.NONE;\n if (this.chipset) {\n drive.cbFormat = 0;\n drive.abFormat = new Array(4);\n drive.bFormatting = true;\n drive.cSectorsFormatted = 0;\n this.chipset.connectDMA(ChipSet.DMA_FDC, this, 'dmaFormat', drive);\n this.chipset.requestDMA(ChipSet.DMA_FDC);\n drive.bFormatting = false;\n }\n }\n }\n\n /**\n * readData(drive, done)\n *\n * The following drive properties must have been setup prior to our first call:\n *\n * drive.bHead\n * drive.bCylinder\n * drive.bSector\n * drive.sector (initialized to null)\n *\n * On the first readData() request, since drive.sector will be null, we ask the Disk object to look\n * up the first sector of the request. We then ask the Disk for bytes from that sector until the sector\n * is exhausted, and then we look up the next sector and continue the process.\n *\n * NOTE: Since the FDC isn't aware of the extent of the transfer, all readData() can do is return bytes\n * until the current track (or, in the case of a multi-track request, the current cylinder) has been exhausted.\n *\n * TODO: Research the requirements, if any, for multi-track I/O and determine what else needs to be done.\n *\n * @this {FDC}\n * @param {Object} drive\n * @param {function(number,boolean,Object,number)} done (number is next available byte from drive, or -1 if no more bytes available)\n */\n readData(drive, done)\n {\n var b = -1;\n var obj = null, off = 0; // these variables are purely for BACKTRACK purposes\n\n if (!drive.resCode && drive.disk) {\n do {\n if (drive.sector) {\n off = drive.ibSector;\n if ((b = drive.disk.read(drive.sector, drive.ibSector++)) >= 0) {\n obj = drive.sector;\n break;\n }\n }\n /*\n * Locate the next sector, and then try reading again.\n */\n drive.sector = drive.disk.seek(drive.bCylinder, drive.bHead, drive.bSector);\n if (!drive.sector) {\n drive.resCode = FDC.REG_DATA.RES.NO_DATA | FDC.REG_DATA.RES.INCOMPLETE;\n break;\n }\n drive.ibSector = 0;\n /*\n * We \"pre-advance\" bSector et al now, instead of waiting to advance it right before the seek().\n * This allows the initial call to readData() to perform a seek without triggering an unwanted advance.\n */\n this.advanceSector(drive);\n } while (true);\n }\n done(b, false, obj, off);\n }\n\n /**\n * writeData(drive, b)\n *\n * The following drive properties must have been setup prior to our first call:\n *\n * drive.bHead\n * drive.bCylinder\n * drive.bSector\n * drive.sector (initialized to null)\n *\n * On the first writeData() request, since drive.sector will be null, we ask the Disk object to look\n * up the first sector of the request. We then send the Disk bytes for that sector until the sector\n * is full, and then we look up the next sector and continue the process.\n *\n * NOTE: Since the FDC isn't aware of the extent of the transfer, all writeData() can do is accept bytes\n * until the current track (or, in the case of a multi-track request, the current cylinder) has been exhausted.\n *\n * TODO: Research the requirements, if any, for multi-track I/O and determine what else needs to be done.\n *\n * @this {FDC}\n * @param {Object} drive\n * @param {number} b containing next byte to write\n * @return {number} (b unchanged; return -1 if command should be terminated)\n */\n writeData(drive, b)\n {\n if (drive.resCode || !drive.disk) return -1;\n do {\n if (drive.sector) {\n if (drive.disk.write(drive.sector, drive.ibSector++, b))\n break;\n }\n /*\n * Locate the next sector, and then try writing again.\n */\n drive.sector = drive.disk.seek(drive.bCylinder, drive.bHead, drive.bSector);\n if (!drive.sector) {\n /*\n * TODO: Determine whether this should be FDC.REG_DATA.RES.CRC_ERROR or FDC.REG_DATA.RES.DATA_FIELD\n */\n drive.resCode = FDC.REG_DATA.RES.CRC_ERROR | FDC.REG_DATA.RES.INCOMPLETE;\n b = -1;\n break;\n }\n drive.ibSector = 0;\n /*\n * We \"pre-advance\" bSector et al now, instead of waiting to advance it right before the seek().\n * This allows the initial call to writeData() to perform a seek without triggering an unwanted advance.\n */\n this.advanceSector(drive);\n } while (true);\n return b;\n }\n\n /**\n * advanceSector(drive)\n *\n * This increments the sector number; when the sector number reaches drive.nDiskSectors on the current track, we\n * increment drive.bHead and reset drive.bSector, and when drive.bHead reaches drive.nDiskHeads, we reset drive.bHead\n * and increment drive.bCylinder.\n *\n * @this {FDC}\n * @param {Object} drive\n */\n advanceSector(drive)\n {\n\n drive.bSector++;\n var bSectorStart = 1;\n if (drive.bSector >= drive.nDiskSectors + bSectorStart) {\n drive.bSector = bSectorStart;\n drive.bHead++;\n if (drive.bHead >= drive.nDiskHeads) {\n drive.bHead = 0;\n drive.bCylinder++;\n }\n }\n }\n\n /**\n * writeFormat(drive, b)\n *\n * @this {FDC}\n * @param {Object} drive\n * @param {number} b containing a format command byte\n * @return {number} (b if successful, -1 if command should be terminated)\n */\n writeFormat(drive, b)\n {\n if (drive.resCode) return -1;\n drive.abFormat[drive.cbFormat++] = b;\n if (drive.cbFormat == drive.abFormat.length) {\n drive.bCylinder = drive.abFormat[0]; // C\n drive.bHead = drive.abFormat[1]; // H\n drive.bSector = drive.abFormat[2]; // R\n drive.nBytes = 128 << drive.abFormat[3];// N (0 => 128, 1 => 256, 2 => 512, 3 => 1024)\n drive.cbFormat = 0;\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".writeFormat(head=\" + Str.toHexByte(drive.bHead) + \",cyl=\" + Str.toHexByte(drive.bCylinder) + \",sec=\" + Str.toHexByte(drive.bSector) + \",len=\" + Str.toHexWord(drive.nBytes) + \")\");\n }\n for (var i = 0; i < drive.nBytes; i++) {\n if (this.writeData(drive, drive.bFiller) < 0) {\n return -1;\n }\n }\n drive.cSectorsFormatted++;\n }\n if (drive.cSectorsFormatted >= drive.bSectorEnd) b = -1;\n return b;\n }\n\n /**\n * FDC.init()\n *\n * This function operates on every HTML element of class \"fdc\", extracting the\n * JSON-encoded parameters for the FDC constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a FDC component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeFDC = Component.getElementsByClass(document, PCX86.APPCLASS, \"fdc\");\n for (var iFDC = 0; iFDC < aeFDC.length; iFDC++) {\n var eFDC = aeFDC[iFDC];\n var parmsFDC = Component.getComponentParms(eFDC);\n var fdc = new FDC(parmsFDC);\n Component.bindComponentControls(fdc, eFDC, PCX86.APPCLASS);\n }\n }\n}\n\nFDC.DEFAULT_DRIVE_NAME = \"Floppy Drive\";\n\nif (DEBUG) {\n FDC.TERMS = {\n C: \"C\", // Cylinder Number\n D: \"D\", // Data (eg, pattern to be written to a sector)\n H: \"H\", // Head Address\n R: \"R\", // Record (ie, sector number to be read or written)\n N: \"N\", // Number (ie, number of data bytes to write)\n DS: \"DS\", // Drive Select\n SC: \"SC\", // Sectors per Cylinder\n DTL: \"DTL\", // Data Length\n EOT: \"EOT\", // End of Track\n GPL: \"GPL\", // Gap Length\n HLT: \"HLT\", // Head Load Time\n NCN: \"NCN\", // New Cylinder Number\n PCN: \"PCN\", // Present Cylinder Number\n SRT: \"SRT\", // Stepping Rate\n ST0: \"ST0\", // Status Register 0\n ST1: \"ST1\", // Status Register 1\n ST2: \"ST2\", // Status Register 2\n ST3: \"ST3\" // Status Register 3\n };\n} else {\n FDC.TERMS = {};\n}\n\n/*\n * FDC Digital Output Register (DOR) (0x3F2, write-only)\n *\n * NOTE: Reportedly, a drive's MOTOR had to be ON before the drive could be selected; however, outFDCOutput() no\n * longer verifies that. Also, motor start time for original drives was 500ms, but we make no attempt to simulate that.\n *\n * On the MODEL_5170 \"PC AT Fixed Disk and Diskette Drive Adapter\", this port is called the Digital Output Register\n * or DOR. It uses the same bit definitions as the original FDC Output Register, except that only two diskette drives\n * are supported, hence bit 1 is always 0 (ie, FDC.REG_OUTPUT.DS2 and FDC.REG_OUTPUT.DS3 are not supported) and bits\n * 6 and 7 are unused (FDC.REG_OUTPUT.MOTOR_D2 and FDC.REG_OUTPUT.MOTOR_D3 are not supported).\n */\nFDC.REG_OUTPUT = {\n PORT: 0x3F2,\n DS: 0x03, // drive select bits\n DS0: 0x00,\n DS1: 0x01,\n DS2: 0x02, // reserved on the MODEL_5170\n DS3: 0x03, // reserved on the MODEL_5170\n ENABLE: 0x04, // clearing this bit resets the FDC\n INT_ENABLE: 0x08, // enables both FDC and DMA (Channel 2) interrupt requests (IRQ 6)\n MOTOR_D0: 0x10,\n MOTOR_D1: 0x20,\n MOTOR_D2: 0x40, // reserved on the MODEL_5170\n MOTOR_D3: 0x80 // reserved on the MODEL_5170\n};\n\n/*\n * FDC Main Status Register (0x3F4, read-only)\n *\n * On the MODEL_5170 \"PC AT Fixed Disk and Diskette Drive Adapter\", bits 2 and 3 are reserved, since that adapter\n * supported a maximum of two diskette drives.\n */\nFDC.REG_STATUS = {\n PORT: 0x3F4,\n BUSY_A: 0x01,\n BUSY_B: 0x02,\n BUSY_C: 0x04, // reserved on the MODEL_5170\n BUSY_D: 0x08, // reserved on the MODEL_5170\n BUSY: 0x10, // a read or write command is in progress\n NON_DMA: 0x20, // FDC is in non-DMA mode\n READ_DATA: 0x40, // transfer is from FDC Data Register to processor (if clear, then transfer is from processor to the FDC Data Register)\n RQM: 0x80 // indicates FDC Data Register is ready to send or receive data to or from the processor (Request for Master)\n};\n\n/*\n * FDC Data Register (0x3F5, read-write)\n */\nFDC.REG_DATA = {\n PORT: 0x3F5,\n /*\n * FDC Commands\n *\n * NOTE: FDC command bytes need to be masked with FDC.REG_DATA.CMD.MASK before comparing to the values below, since a\n * number of commands use the following additional bits as follows:\n *\n * SK (0x20): Skip Deleted Data Address Mark\n * MF (0x40): Modified Frequency Modulation (as opposed to FM or Frequency Modulation)\n * MT (0x80): multi-track operation (ie, data processed under both head 0 and head 1)\n *\n * We don't support MT (Multi-Track) operations at this time, and the MF and SK designations cannot be supported as long\n * as our diskette images contain only the original data bytes without any formatting information.\n */\n CMD: {\n READ_TRACK: 0x02,\n SPECIFY: 0x03,\n SENSE_DRIVE: 0x04,\n WRITE_DATA: 0x05,\n READ_DATA: 0x06,\n RECALIBRATE: 0x07,\n SENSE_INT: 0x08, // this command is used to clear the FDC interrupt following the clearing/setting of FDC.REG_OUTPUT.ENABLE\n WRITE_DEL_DATA: 0x09,\n READ_ID: 0x0A,\n READ_DEL_DATA: 0x0C,\n FORMAT_TRACK: 0x0D,\n SEEK: 0x0F,\n SCAN_EQUAL: 0x11,\n SCAN_LO_EQUAL: 0x19,\n SCAN_HI_EQUAL: 0x1D,\n MASK: 0x1F,\n SK: 0x20, // SK (Skip Deleted Data Address Mark)\n MF: 0x40, // MF (Modified Frequency Modulation)\n MT: 0x80 // MT (Multi-Track; ie, data under both heads will be processed)\n },\n /*\n * FDC status/error results, generally assigned according to the corresponding ST0, ST1, ST2 or ST3 status bit.\n *\n * TODO: Determine when EQUIP_CHECK is *really* set; also, \"77 step pulses\" sounds suspiciously like a typo (it's not 79?)\n */\n RES: {\n NONE: 0x00000000, // ST0 (IC): Normal termination of command (NT)\n NOT_READY: 0x00000008, // ST0 (NR): When the FDD is in the not-ready state and a read or write command is issued, this flag is set; if a read or write command is issued to side 1 of a single sided drive, then this flag is set\n EQUIP_CHECK: 0x00000010, // ST0 (EC): If a fault signal is received from the FDD, or if the track 0 signal fails to occur after 77 step pulses (recalibrate command), then this flag is set\n SEEK_END: 0x00000020, // ST0 (SE): When the FDC completes the Seek command, this flag is set to 1 (high)\n INCOMPLETE: 0x00000040, // ST0 (IC): Abnormal termination of command (AT); execution of command was started, but was not successfully completed\n RESET: 0x000000C0, // ST0 (IC): Abnormal termination because during command execution the ready signal from the drive changed state\n INVALID: 0x00000080, // ST0 (IC): Invalid command issue (IC); command which was issued was never started\n ST0: 0x000000FF,\n NO_ID_MARK: 0x00000100, // ST1 (MA): If the FDC cannot detect the ID Address Mark, this flag is set; at the same time, the MD (Missing Address Mark in Data Field) of Status Register 2 is set\n NOT_WRITABLE: 0x00000200, // ST1 (NW): During Execution of a Write Data, Write Deleted Data, or Format a Cylinder command, if the FDC detects a write protect signal from the FDD, then this flag is set\n NO_DATA: 0x00000400, // ST1 (ND): FDC cannot find specified sector (or specified ID if READ_ID command)\n DMA_OVERRUN: 0x00001000, // ST1 (OR): If the FDC is not serviced by the main systems during data transfers within a certain time interval, this flag is set\n CRC_ERROR: 0x00002000, // ST1 (DE): When the FDC detects a CRC error in either the ID field or the data field, this flag is set\n END_OF_CYL: 0x00008000, // ST1 (EN): When the FDC tries to access a sector beyond the final sector of a cylinder, this flag is set\n ST1: 0x0000FF00,\n NO_DATA_MARK: 0x00010000, // ST2 (MD): When data is read from the medium, if the FDC cannot find a Data Address Mark or Deleted Data Address Mark, then this flag is set\n BAD_CYL: 0x00020000, // ST2 (BC): This bit is related to the ND bit, and when the contents of C on the medium are different from that stored in the ID Register, and the content of C is FF, then this flag is set\n SCAN_FAILED: 0x00040000, // ST2 (SN): During execution of the Scan command, if the FDC cannot find a sector on the cylinder which meets the condition, then this flag is set\n SCAN_EQUAL: 0x00080000, // ST2 (SH): During execution of the Scan command, if the condition of \"equal\" is satisfied, this flag is set\n WRONG_CYL: 0x00100000, // ST2 (WC): This bit is related to the ND bit, and when the contents of C on the medium are different from that stored in the ID Register, this flag is set\n DATA_FIELD: 0x00200000, // ST2 (DD): If the FDC detects a CRC error in the data, then this flag is set\n STRL_MARK: 0x00400000, // ST2 (CM): During execution of the Read Data or Scan command, if the FDC encounters a sector which contains a Deleted Data Address Mark, this flag is set\n ST2: 0x00FF0000,\n DRIVE: 0x03000000, // ST3 (Ux): Status of the \"Drive Select\" signals from the diskette drive\n HEAD: 0x04000000, // ST3 (HD): Status of the \"Side Select\" signal from the diskette drive\n TWOSIDE: 0x08000000, // ST3 (TS): Status of the \"Two Side\" signal from the diskette drive\n TRACK0: 0x10000000, // ST3 (T0): Status of the \"Track 0\" signal from the diskette drive\n READY: 0x20000000, // ST3 (RY): Status of the \"Ready\" signal from the diskette drive\n WRITEPROT: 0x40000000, // ST3 (WP): Status of the \"Write Protect\" signal from the diskette drive\n FAULT: 0x80000000|0, // ST3 (FT): Status of the \"Fault\" signal from the diskette drive\n ST3: 0xFF000000|0\n }\n};\n\n/*\n * FDC \"Fixed Disk\" Register (0x3F6, write-only)\n *\n * Since this register's functions are all specific to the Hard Drive Controller, see the HDC component for details.\n * The fact that this HDC register is in the middle of the FDC I/O port range is an oddity of the \"HFCOMBO\" controller.\n */\n\n/*\n * FDC Digital Input Register (0x3F7, read-only, MODEL_5170 only)\n *\n * Bit 7 indicates a diskette change (the MODEL_5170 introduced change-line support). Bits 0-6 are for the selected\n * hard drive, so this port must be shared with the HDC; bits 0-6 are valid for 50 microseconds after a write to the\n * Drive Head Register.\n */\nFDC.REG_INPUT = {\n PORT: 0x3F7,\n DS0: 0x01, // Drive Select 0\n DS1: 0x02, // Drive Select 1\n HS0: 0x04, // Head Select 0\n HS1: 0x08, // Head Select 1\n HS2: 0x10, // Head Select 2\n HS3: 0x20, // Head Select 3\n WRITE_GATE: 0x40, // Write Gate\n DISK_CHANGE:0x80 // Diskette Change\n};\n\n/*\n * FDC Diskette Control Register (0x3F7, write-only, MODEL_5170 only)\n *\n * Only bits 0-1 are used; bits 2-7 are reserved.\n */\nFDC.REG_CONTROL = {\n PORT: 0x3F7,\n RATE500K: 0x00, // 500,000 bps\n RATE300K: 0x02, // 300,000 bps\n RATE250K: 0x01, // 250,000 bps\n RATEUNUSED: 0x03\n};\n\n/*\n * FDC Command Sequences\n *\n * For each command, cbReq indicates the total number of bytes in the command request sequence,\n * including the first (command) byte; cbRes indicates total number of bytes in the response sequence.\n */\nif (DEBUG) {\n FDC.CMDS = {\n SPECIFY: \"SPECIFY\",\n SENSE_DRIVE: \"SENSE DRIVE\",\n WRITE_DATA: \"WRITE DATA\",\n READ_DATA: \"READ DATA\",\n RECALIBRATE: \"RECALIBRATE\",\n SENSE_INT: \"SENSE INTERRUPT\",\n READ_ID: \"READ ID\",\n FORMAT: \"FORMAT\",\n SEEK: \"SEEK\"\n };\n} else {\n FDC.CMDS = {};\n}\n\nFDC.aCmdInfo = {\n 0x03: {cbReq: 3, cbRes: 0, name: FDC.CMDS.SPECIFY},\n 0x04: {cbReq: 2, cbRes: 1, name: FDC.CMDS.SENSE_DRIVE},\n 0x05: {cbReq: 9, cbRes: 7, name: FDC.CMDS.WRITE_DATA},\n 0x06: {cbReq: 9, cbRes: 7, name: FDC.CMDS.READ_DATA},\n 0x07: {cbReq: 2, cbRes: 0, name: FDC.CMDS.RECALIBRATE},\n 0x08: {cbReq: 1, cbRes: 2, name: FDC.CMDS.SENSE_INT},\n 0x0A: {cbReq: 2, cbRes: 7, name: FDC.CMDS.READ_ID},\n 0x0D: {cbReq: 6, cbRes: 7, name: FDC.CMDS.FORMAT},\n 0x0F: {cbReq: 3, cbRes: 0, name: FDC.CMDS.SEEK}\n};\n\n/*\n * Port input notification table\n *\n * TODO: Even though port 0x3F7 was not present on controllers prior to MODEL_5170, I'm taking the easy\n * way out and always emulating it. So, consider an FDC parameter to disable that feature for stricter compatibility.\n */\nFDC.aPortInput = {\n 0x3F1: FDC.prototype.inFDCDiagnostic,\n 0x3F4: FDC.prototype.inFDCStatus,\n 0x3F5: FDC.prototype.inFDCData,\n 0x3F7: FDC.prototype.inFDCInput\n};\n\n/*\n * Port output notification table\n *\n * TODO: Even though port 0x3F7 was not present on controllers prior to MODEL_5170, I'm taking the easy\n * way out and always emulating it. So, consider an FDC parameter to disable that feature for stricter compatibility.\n */\nFDC.aPortOutput = {\n 0x3F2: FDC.prototype.outFDCOutput,\n 0x3F5: FDC.prototype.outFDCData,\n 0x3F7: FDC.prototype.outFDCControl\n};\n\n/*\n * Initialize every Floppy Drive Controller (FDC) module on the page.\n */\nWeb.onInit(FDC.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/hdc.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * class HDC\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass HDC extends Component {\n /**\n * HDC(parmsHDC)\n *\n * The HDC component simulates an STC-506/412 interface to an IBM-compatible fixed disk drive. The first\n * such drive was a 10Mb 5.25-inch drive containing two platters and 4 heads. Data spanned 306 cylinders\n * for a total of 1224 tracks, with 17 sectors/track and 512 bytes/sector. Support has since been expanded\n * to include the original PC AT Western Digital controller.\n *\n * HDC supports the following component-specific properties:\n *\n * drives: an array of driveConfig objects, each containing 'name', 'path', 'size' and 'type' properties\n * type: either 'XT' (for the PC XT Xebec controller) or 'AT' (for the PC AT Western Digital controller)\n *\n * The 'type' parameter defaults to 'XT'. All ports for the PC XT controller are referred to as XTC ports,\n * and similarly, all PC AT controller ports are referred to as ATC ports.\n *\n * If 'path' is empty, a scratch disk image is created; otherwise, we make a note of the path, but we will NOT\n * pre-load it like we do for floppy disk images.\n *\n * My current plan is to read all disk data on-demand, keeping a cache of what we've read, and possibly adding\n * some read-ahead as well. Any portions of the disk image that are written before being read will never be read.\n *\n * TRIVIA: On p.1-179 of the PC XT Technical Reference Manual (revised APR83), it reads:\n *\n * \"WARNING: The last cylinder on the fixed disk drive is reserved for diagnostic use.\n * Diagnostic write tests will destroy any data on this cylinder.\"\n *\n * Does FDISK insure that the last cylinder is reserved? I'm sure we'll eventually find out.\n *\n * @this {HDC}\n * @param {Object} parmsHDC\n */\n constructor(parmsHDC)\n {\n super(\"HDC\", parmsHDC, Messages.HDC);\n\n this['dmaRead'] = HDC.prototype.doDMARead;\n this['dmaWrite'] = HDC.prototype.doDMAWrite;\n this['dmaWriteBuffer'] = HDC.prototype.doDMAWriteBuffer;\n this['dmaWriteFormat'] = HDC.prototype.doDMAWriteFormat;\n\n this.aDriveConfigs = [];\n\n /*\n * We used to eval() sDriveConfigs immediately, but now we wait until initBus() is called, so that\n * we can check for any machine overrides.\n */\n this.sDriveConfigs = parmsHDC['drives'];\n\n /*\n * Set fATC (AT Controller flag) according to the 'type' parameter. This in turn determines other\n * defaults. For example, the default XT drive type is 3 (for a 10Mb disk drive), whereas the default\n * AT drive type is 2 (for a 20Mb disk drive).\n */\n var sType = parmsHDC['type'];\n this.fATC = sType && sType.toUpperCase() == \"AT\" || false;\n\n /*\n * Support for local disk images is currently limited to desktop browsers with FileReader support;\n * when this flag is set, setBinding() allows local disk bindings and informs initBus() to update the\n * \"listDisks\" binding accordingly.\n */\n this.fLocalDisks = (!Web.isMobile() && window && 'FileReader' in window);\n\n /*\n * The remainder of HDC initialization now takes place in our initBus() handler.\n */\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {HDC}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"listDisks\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var hdc = this;\n\n switch (sBinding) {\n\n case \"saveHD0\":\n case \"saveHD1\":\n /*\n * Yes, technically, this feature does not require \"Local disk support\" (which is really a reference\n * to FileReader support), but since fLocalDisks is also false for all mobile devices, and since there\n * is an \"orthogonality\" to disabling both features in tandem, let's just let it slide, OK?\n */\n if (!this.fLocalDisks) {\n if (DEBUG) this.log(\"Local disk support not available\");\n /*\n * We could also simply hide the control; eg:\n *\n * control.style.display = \"none\";\n *\n * but removing the control altogether seems better.\n */\n control.parentNode.removeChild(/** @type {Node} */ (control));\n return false;\n }\n this.bindings[sBinding] = control;\n control.onclick = function(iDrive) {\n return function onClickSaveDrive(event) {\n var drive = hdc.aDrives && hdc.aDrives[iDrive];\n if (drive && drive.disk) {\n /*\n * Note the similarity (and hence factoring opportunity) between this code and the FDC's\n * \"saveDisk\" binding.\n *\n * One important difference between the FDC and the HDC is that an FDC may or may not contain\n * a disk, whereas an HDC always contains a disk. However, the contents of an HDC's disk may\n * never have been initialized with the contents of an external disk image, and therefore the\n * disk's sDiskFile/sDiskPath properties may be undefined. sDiskName should always be defined\n * though, defaulting to the name of the drive (eg, \"10Mb Hard Disk\").\n */\n var disk = drive.disk;\n var sDiskName = disk.sDiskFile || disk.sDiskName;\n var i = sDiskName.lastIndexOf('.');\n if (i >= 0) sDiskName = sDiskName.substr(0, i);\n sDiskName += \".img\";\n if (DEBUG) hdc.println(\"saving disk \" + sDiskName + \"...\");\n var sAlert = Web.downloadFile(disk.encodeAsBase64(), \"octet-stream\", true, sDiskName);\n Component.alertUser(sAlert);\n } else {\n hdc.notice(\"Hard drive \" + iDrive + \" is not available.\");\n }\n };\n }(+sBinding.slice(-1));\n return true;\n }\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {HDC}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.cmp = cmp;\n\n var aDriveConfigs = cmp.getMachineParm('drives');\n if (aDriveConfigs) {\n if (typeof aDriveConfigs == \"string\") {\n this.sDriveConfigs = aDriveConfigs;\n } else {\n this.aDriveConfigs = aDriveConfigs;\n this.sDriveConfigs = \"\";\n }\n }\n \n if (this.sDriveConfigs) {\n try {\n /*\n * We must take care when parsing user-supplied JSON-encoded drive data.\n */\n this.aDriveConfigs = eval(\"(\" + this.sDriveConfigs + \")\");\n /*\n * Nothing more to do with aDriveConfigs now. initController() and autoMount() (if there are\n * any disk image \"path\" properties to process) will take care of the rest.\n */\n this.sDriveConfigs = \"\";\n } catch (e) {\n Component.error(\"HDC drive configuration error: \" + e.message + \" (\" + this.sDriveConfigs + \")\");\n }\n }\n\n /*\n * We need access to the ChipSet component, because we need to communicate with\n * the PIC and DMA controller.\n */\n this.chipset = cmp.getMachineComponent(\"ChipSet\");\n\n this.iDriveTable = 0;\n this.iDriveTypeDefault = 3;\n\n bus.addPortInputTable(this, this.fATC? HDC.aATCPortInput : HDC.aXTCPortInput);\n bus.addPortOutputTable(this, this.fATC? HDC.aATCPortOutput : HDC.aXTCPortOutput);\n\n if (this.fATC) {\n this.iDriveTable++;\n if (this.chipset && this.chipset.model == ChipSet.MODEL_COMPAQ_DESKPRO386) this.iDriveTable++;\n this.iDriveTypeDefault = 2;\n bus.addPortInputWidth(HDC.ATC.DATA.PORT, 2);\n bus.addPortOutputWidth(HDC.ATC.DATA.PORT, 2);\n }\n\n cpu.addIntNotify(Interrupts.DISK, this.intBIOSDisk.bind(this));\n cpu.addIntNotify(Interrupts.ALT_DISK, this.intBIOSDiskette.bind(this));\n\n /*\n * The following code used to be performed in the HDC constructor, but now we need to wait for information\n * about the Computer to be available (eg, getMachineID() and getUserID()) before we start loading and/or\n * connecting to disk images.\n *\n * If we didn't need auto-mount support, we could defer controller initialization until we received a powerUp()\n * notification, at which point reset() would call initController(), or restore() would restore the controller;\n * in that case, all we'd need to do here is call setReady().\n */\n this.reset();\n\n if (!this.autoMount()) this.setReady();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {HDC}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.initController();\n if (this.cmp.fReload) {\n /*\n * If the computer's fReload flag is set, we're required to toss all currently\n * loaded disks and remount all disks specified in the auto-mount configuration.\n */\n this.autoMount(true);\n }\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {HDC}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean}\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * getMachineID()\n *\n * @return {string}\n */\n getMachineID()\n {\n return this.cmp? this.cmp.getMachineID() : \"\";\n }\n\n /**\n * getUserID()\n *\n * @return {string}\n */\n getUserID()\n {\n return this.cmp? this.cmp.getUserID() : \"\";\n }\n\n /**\n * reset()\n *\n * @this {HDC}\n */\n reset()\n {\n /*\n * TODO: The controller is also initialized by the constructor, to assist with auto-mount support,\n * so think about whether we can skip powerUp initialization.\n */\n this.initController(null, true);\n }\n\n /**\n * save()\n *\n * This implements save support for the HDC component.\n *\n * @this {HDC}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveController());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the HDC component.\n *\n * @this {HDC}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return this.initController(data[0]);\n }\n\n /**\n * initController(data, fHard)\n *\n * @this {HDC}\n * @param {Array} [data]\n * @param {boolean} [fHard] true if a machine reset (not just a controller reset)\n * @return {boolean} true if successful, false if failure\n */\n initController(data, fHard)\n {\n var i = 0;\n var fSuccess = true;\n\n /*\n * TODO: This is used to re-select the controller's active drive whenever the machine is restored, but alas,\n * we currently only update it and save it for the ATC, not the XTC.\n */\n this.iDrive = -1;\n\n /*\n * At this point, it's worth calling into question my decision to NOT split the HDC component into separate XTC\n * and ATC components, given all the differences, and given that I'm about to write some \"if (ATC) else (XTC) ...\"\n * code. And all I can say in my defense is, yes, it's definitely worth calling that into question.\n *\n * However, there's also some common code, mostly in the area of disk management rather than controller management,\n * and if the components were split, then I'd have to create a third component for that common code (although again,\n * disk management probably belongs in its own component anyway).\n *\n * However, let's not forget that since my overall plan is to have only one PCx86 \"binary\", everything's going to end\n * up in the same bucket anyway, so let's not be too obsessive about organizational details. As long as the number\n * of these conditionals is small and they're not performance-critical, this seems much ado about nothing.\n */\n if (this.fATC) {\n /*\n * Since there's no way (and never will be a way) for an HDC to change its \"personality\" (from 'xt' to 'at'\n * or vice versa), we're under no obligation to use the same number of registers, or save/restore format, etc,\n * as the original XT controller.\n */\n if (data == null) data = [0, 0, 0, 0, 0, 0, 0, HDC.ATC.STATUS.READY, 0, [0, -1]];\n this.regError = data[i++];\n this.regWPreC = data[i++];\n this.regSecCnt = data[i++];\n this.regSecNum = data[i++];\n this.regCylLo = data[i++];\n this.regCylHi = data[i++];\n this.regDrvHd = data[i++];\n this.regStatus = data[i++];\n this.regCommand = data[i++];\n this.regFDR = data[i++];\n if (typeof this.regFDR == \"object\") {\n var a = this.regFDR;\n this.regFDR = a[0];\n this.iDrive = a[1];\n }\n /*\n * Additional state is maintained by the Drive object (eg, abSector, ibSector)\n */\n } else {\n if (data == null) data = [0, HDC.XTC.STATUS.NONE, new Array(14), 0, 0];\n this.regConfig = data[i++];\n this.regStatus = data[i++];\n this.regDataArray = data[i++]; // there can be up to 14 command bytes (6 for normal commands, plus 8 more for HDC.XTC.DATA.CMD.INIT_DRIVE)\n this.regDataIndex = data[i++]; // used to control the next data byte to be received\n this.regDataTotal = data[i++]; // used to control the next data byte to be sent (internally, we use regDataIndex to read data bytes, up to this total)\n this.regReset = data[i++];\n this.regPulse = data[i++];\n this.regPattern = data[i++];\n /*\n * Initialize iDriveAllowFail only if it's never been initialized, otherwise its entire purpose will be defeated.\n * See the related HACK in intBIOSDisk() for more details.\n */\n var iDriveAllowFail = data[i++];\n if (iDriveAllowFail !== undefined) {\n this.iDriveAllowFail = iDriveAllowFail;\n } else {\n if (this.iDriveAllowFail === undefined) this.iDriveAllowFail = -1;\n }\n }\n\n if (this.aDrives === undefined) {\n this.aDrives = new Array(this.aDriveConfigs.length);\n }\n\n var dataDrives = data[i];\n if (dataDrives === undefined) dataDrives = [];\n\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n if (this.aDrives[iDrive] === undefined) {\n this.aDrives[iDrive] = {};\n }\n var drive = this.aDrives[iDrive];\n var driveConfig = this.aDriveConfigs[iDrive];\n if (!this.initDrive(iDrive, drive, driveConfig, dataDrives[iDrive], fHard)) {\n fSuccess = false;\n }\n /*\n * XTC only: the original STC-506/412 controller had two pairs of DIP switches to indicate a drive\n * type (0, 1, 2 or 3) for drives 0 and 1. Those switch settings are recorded in regConfig, now that\n * drive.type has been validated by initDrive().\n */\n if (this.regConfig != null && iDrive <= 1) {\n this.regConfig |= (drive.type & 0x3) << ((1 - iDrive) << 1);\n }\n }\n\n if (this.iDrive >= 0) {\n this.drive = this.aDrives[this.iDrive];\n }\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"HDC initialized for \" + this.aDrives.length + \" drive(s)\");\n }\n return fSuccess;\n }\n\n /**\n * saveController()\n *\n * @this {HDC}\n * @return {Array}\n */\n saveController()\n {\n var i = 0;\n var data = [];\n if (this.fATC) {\n data[i++] = this.regError;\n data[i++] = this.regWPreC;\n data[i++] = this.regSecCnt;\n data[i++] = this.regSecNum;\n data[i++] = this.regCylLo;\n data[i++] = this.regCylHi;\n data[i++] = this.regDrvHd;\n data[i++] = this.regStatus;\n data[i++] = this.regCommand;\n data[i++] = [this.regFDR, this.iDrive];\n } else {\n data[i++] = this.regConfig;\n data[i++] = this.regStatus;\n data[i++] = this.regDataArray;\n data[i++] = this.regDataIndex;\n data[i++] = this.regDataTotal;\n data[i++] = this.regReset;\n data[i++] = this.regPulse;\n data[i++] = this.regPattern;\n data[i++] = this.iDriveAllowFail;\n }\n data[i] = this.saveDrives();\n return data;\n }\n\n /**\n * initDrive(iDrive, drive, driveConfig, data, fHard)\n *\n * TODO: Consider a separate Drive class that both FDC and HDC can use, since there's a lot of commonality\n * between the drive objects created by both controllers. This will clean up overall drive management and allow\n * us to factor out some common Drive methods (eg, advanceSector()).\n *\n * @this {HDC}\n * @param {number} iDrive\n * @param {Object} drive\n * @param {Object} driveConfig (contains one or more of the following properties: 'name', 'path', 'size', 'type')\n * @param {Array} [data]\n * @param {boolean} [fHard] true if a machine reset (not just a controller reset)\n * @return {boolean} true if successful, false if failure\n */\n initDrive(iDrive, drive, driveConfig, data, fHard)\n {\n var i = 0;\n var fSuccess = true;\n if (data === undefined) data = [HDC.XTC.DATA.ERR.NONE, 0, false, new Array(8)];\n\n drive.iDrive = iDrive;\n\n /*\n * errorCode could be an HDC global, but in order to insulate HDC state from the operation of various functions\n * that operate on drive objects (eg, readData and writeData), I've made it a per-drive variable. This choice may\n * be contrary to how the actual hardware works, but I prefer this approach, as long as it doesn't expose any\n * incompatibilities that any software actually cares about.\n */\n drive.errorCode = data[i++];\n drive.senseCode = data[i++];\n drive.fRemovable = data[i++];\n drive.abDriveParms = data[i++]; // captures drive parameters programmed via HDC.XTC.DATA.CMD.INIT_DRIVE\n\n /*\n * TODO: Make abSector a DWORD array rather than a BYTE array (we could even allocate a Memory block for it);\n * alternatively, eliminate the buffer entirely and re-establish a reference to the appropriate Disk sector object.\n */\n drive.abSector = data[i++];\n\n /*\n * The next group of properties are set by various HDC command sequences.\n */\n drive.bHead = data[i++];\n drive.nHeads = data[i++];\n drive.wCylinder = data[i++];\n drive.bSector = data[i++];\n drive.bSectorEnd = data[i++]; // aka EOT\n drive.nBytes = data[i++];\n drive.bSectorBias = (this.fATC? 0: 1);\n\n drive.name = driveConfig['name'];\n if (drive.name === undefined) drive.name = HDC.DEFAULT_DRIVE_NAME;\n drive.path = driveConfig['path'];\n\n /*\n * If no 'mode' is specified, we fall back to the original behavior, which is to completely preload\n * any specific disk image, or create an empty (purely local) disk image.\n */\n drive.mode = driveConfig['mode'] || (drive.path? DiskAPI.MODE.PRELOAD : DiskAPI.MODE.LOCAL);\n\n /*\n * On-demand I/O of raw disk images is supported only if there's a valid user ID; fall back to an empty\n * local disk image if there's not.\n */\n if (drive.mode == DiskAPI.MODE.DEMANDRO || drive.mode == DiskAPI.MODE.DEMANDRW) {\n if (!this.getUserID()) drive.mode = DiskAPI.MODE.LOCAL;\n }\n\n drive.type = driveConfig['type'];\n if (drive.type === undefined || HDC.aDriveTypes[this.iDriveTable][drive.type] === undefined) drive.type = this.iDriveTypeDefault;\n\n var driveType = HDC.aDriveTypes[this.iDriveTable][drive.type];\n drive.nSectors = driveType[2] || 17; // sectors/track\n drive.cbSector = driveType[3] || 512; // bytes/sector (default is 512 if unspecified in the table)\n\n /*\n * On a full machine reset, pass the current drive type to setCMOSDriveType() (a no-op on pre-CMOS machines)\n */\n if (fHard && this.chipset) {\n this.chipset.setCMOSDriveType(iDrive, drive.type);\n }\n\n /*\n * The next group of properties are set by user requests to load/unload disk images.\n *\n * We no longer reinitialize drive.disk, in order to retain previously mounted disk across resets.\n */\n if (drive.disk === undefined) {\n drive.disk = null;\n this.notice(\"Type \" + drive.type + \" \\\"\" + drive.name + \"\\\" is fixed disk \" + iDrive, true);\n }\n\n /*\n * With the advent of save/restore, we need to verify every drive at initialization, not just whenever\n * drive characteristics are initialized. Thus, if we've restored a sensible set of drive characteristics,\n * then verifyDrive will create an empty disk if none has been provided, insuring we are ready for\n * disk.restore().\n */\n this.verifyDrive(drive);\n\n /*\n * The next group of properties are managed by worker functions (eg, doRead()) to maintain state across DMA requests.\n */\n drive.ibSector = data[i++]; // location of the next byte to be accessed in the above sector\n drive.sector = null; // initialized to null by worker, and then set to the next sector satisfying the request\n\n if (drive.disk) {\n var deltas = data[i];\n if (deltas !== undefined && drive.disk.restore(deltas) < 0) {\n fSuccess = false;\n }\n if (fSuccess && drive.ibSector !== undefined) {\n drive.sector = drive.disk.seek(drive.wCylinder, drive.bHead, drive.bSector + drive.bSectorBias);\n }\n }\n return fSuccess;\n }\n\n /**\n * saveDrives()\n *\n * @this {HDC}\n * @return {Array}\n */\n saveDrives()\n {\n var i = 0;\n var data = [];\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n data[i++] = this.saveDrive(this.aDrives[iDrive]);\n }\n return data;\n }\n\n /**\n * saveDrive(drive)\n *\n * @this {HDC}\n * @return {Array}\n */\n saveDrive(drive)\n {\n var i = 0;\n var data = [];\n data[i++] = drive.errorCode;\n data[i++] = drive.senseCode;\n data[i++] = drive.fRemovable;\n data[i++] = drive.abDriveParms;\n data[i++] = drive.abSector;\n data[i++] = drive.bHead;\n data[i++] = drive.nHeads;\n data[i++] = drive.wCylinder;\n data[i++] = drive.bSector;\n data[i++] = drive.bSectorEnd;\n data[i++] = drive.nBytes;\n data[i++] = drive.ibSector;\n data[i] = drive.disk? drive.disk.save() : null;\n return data;\n }\n\n /**\n * copyDrive(iDrive)\n *\n * @this {HDC}\n * @param {number} iDrive\n * @return {Object|undefined} (undefined if the requested drive does not exist)\n */\n copyDrive(iDrive)\n {\n var driveNew;\n var driveOld = this.aDrives[iDrive];\n if (driveOld !== undefined) {\n driveNew = {};\n for (var p in driveOld) {\n driveNew[p] = driveOld[p];\n }\n }\n return driveNew;\n }\n\n /**\n * verifyDrive(drive, type)\n *\n * If no disk image is attached, create an empty disk with the specified drive characteristics.\n * Normally, we'd rely on the drive characteristics programmed via the HDC.XTC.DATA.CMD.INIT_DRIVE\n * command, but if an explicit drive type is specified, then we use the characteristics (geometry)\n * associated with that type.\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {number} [type] to create a disk of the specified type, if no disk exists yet\n */\n verifyDrive(drive, type)\n {\n if (drive) {\n var nHeads = 0, nCylinders = 0;\n if (type == null) {\n /*\n * If the caller wants us to use the programmed drive parameters, we use those,\n * but if there aren't any drive parameters (yet), then use default parameters based\n * on drive.type.\n *\n * We used to do the last step ONLY if there was no drive.path -- otherwise, we'd waste\n * time creating an empty disk if autoMount() was going to load an image from drive.path;\n * but hopefully the Disk component is smarter now.\n */\n nHeads = drive.abDriveParms[2];\n if (nHeads) {\n nCylinders = (drive.abDriveParms[0] << 8) | drive.abDriveParms[1];\n } else {\n type = drive.type;\n }\n }\n if (type != null && !nHeads) {\n nHeads = HDC.aDriveTypes[this.iDriveTable][type][1];\n nCylinders = HDC.aDriveTypes[this.iDriveTable][type][0];\n }\n if (nHeads) {\n /*\n * The assumption here is that if the 3rd drive parameter byte (abDriveParms[2]) has been set\n * (ie, if nHeads is valid) then the first two bytes (ie, the low and high cylinder byte values)\n * must have been set as well.\n *\n * Do these values agree with those for the given drive type? Even if they don't, all we do is warn.\n */\n var driveType = HDC.aDriveTypes[this.iDriveTable][drive.type];\n if (driveType) {\n if (nCylinders != driveType[0] && nHeads != driveType[1]) {\n this.notice(\"Warning: drive parameters (\" + nCylinders + \",\" + nHeads + \") do not match drive type \" + drive.type + \" (\" + driveType[0] + \",\" + driveType[1] + \")\");\n }\n }\n drive.nCylinders = nCylinders;\n drive.nHeads = nHeads;\n if (drive.disk == null) {\n drive.disk = new Disk(this, drive, drive.mode);\n }\n }\n }\n }\n\n /**\n * seekDrive(drive, iSector, nSectors)\n *\n * The HDC doesn't need this function, since all HDC requests from the CPU are handled by doXTCmd(). This function\n * is used by other components (eg, Debugger) to mimic an HDC request, using a drive object obtained from copyDrive(),\n * to avoid disturbing the internal state of the HDC's drive objects.\n *\n * Also note that in an actual HDC request, drive.nBytes is initialized to the size of a single sector; the extent\n * of the entire transfer is actually determined by a count that has been pre-loaded into the DMA controller. The HDC\n * isn't aware of the extent of the transfer, so in the case of a read request, all readData() can do is return bytes\n * until the current track (or, in the case of a multi-track request, the current cylinder) has been exhausted.\n *\n * Since seekDrive() is for use with non-DMA requests, we use nBytes to specify the length of the entire transfer.\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {number} iSector (a \"logical\" sector number, relative to the entire disk, NOT a physical sector number)\n * @param {number} nSectors\n * @return {boolean} true if successful, false if invalid position request\n */\n seekDrive(drive, iSector, nSectors)\n {\n if (drive.disk) {\n var aDiskInfo = drive.disk.info();\n var nCylinders = aDiskInfo[0];\n /*\n * If nCylinders is zero, we probably have an empty disk image, awaiting initialization (see verifyDrive())\n */\n if (nCylinders) {\n var nHeads = aDiskInfo[1];\n var nSectorsPerTrack = aDiskInfo[2];\n var nSectorsPerCylinder = nHeads * nSectorsPerTrack;\n var nSectorsPerDisk = nCylinders * nSectorsPerCylinder;\n if (iSector + nSectors <= nSectorsPerDisk) {\n drive.wCylinder = Math.floor(iSector / nSectorsPerCylinder);\n iSector %= nSectorsPerCylinder;\n drive.bHead = Math.floor(iSector / nSectorsPerTrack);\n /*\n * Important difference between the FDC and the XTC: the XTC uses 0-based sector numbers, so unlike\n * FDC.seekDrive(), we must NOT add 1 to bSector below. I could change how sector numbers are stored in\n * hard drive images, but it seems preferable to keep the image format consistent and controller-independent.\n */\n drive.bSector = (iSector % nSectorsPerTrack);\n drive.nBytes = nSectors * aDiskInfo[3];\n /*\n * NOTE: We don't set nSectorEnd, as an HDC command would, but it's irrelevant, because we don't actually\n * do anything with nSectorEnd at this point. Perhaps someday, when we faithfully honor/restrict requests\n * to a single track (or a single cylinder, in the case of multi-track requests).\n */\n drive.errorCode = HDC.XTC.DATA.ERR.NONE;\n /*\n * At this point, we've finished simulating what an HDC.XTC.DATA.CMD.READ_DATA command would have performed,\n * up through doRead(). Now it's the caller responsibility to call readData(), like the DMA Controller would.\n */\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * autoMount(fRemount)\n *\n * @this {HDC}\n * @param {boolean} [fRemount] is true if we're remounting all auto-mounted disks\n * @return {boolean} true if one or more disk images are being auto-mounted, false if none\n */\n autoMount(fRemount)\n {\n if (!fRemount) this.cAutoMount = 0;\n\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n var drive = this.aDrives[iDrive];\n if (drive.name && drive.path) {\n\n if (fRemount && drive.disk && drive.disk.isRemote()) {\n /*\n * The Disk component has its own logic for remounting remote disks, so skip this disk.\n *\n * TODO: Consider rewriting how ALL disks are automounted/remounted, now that the Disk component\n * is receiving its own powerDown() and powerUp() notifications (originally, it didn't receive them).\n */\n continue;\n }\n\n if (!this.loadDisk(iDrive, drive.name, drive.path, true) && fRemount)\n this.setReady(false);\n continue;\n }\n if (fRemount && drive.type !== undefined) {\n drive.disk = null;\n this.verifyDrive(drive, drive.type);\n }\n }\n return !!this.cAutoMount;\n }\n\n /**\n * loadDisk(iDrive, sDiskName, sDiskPath, fAutoMount)\n *\n * @this {HDC}\n * @param {number} iDrive\n * @param {string} sDiskName\n * @param {string} sDiskPath\n * @param {boolean} fAutoMount\n * @return {boolean} true if disk (already) loaded, false if queued up (or busy)\n */\n loadDisk(iDrive, sDiskName, sDiskPath, fAutoMount)\n {\n var drive = this.aDrives[iDrive];\n if (drive.fBusy) {\n this.notice(\"Drive \" + iDrive + \" busy\");\n return true;\n }\n drive.fBusy = true;\n if (fAutoMount) {\n drive.fAutoMount = true;\n this.cAutoMount++;\n if (this.messageEnabled()) this.printMessage(\"loading \" + sDiskName);\n }\n var disk = drive.disk || new Disk(this, drive, drive.mode);\n /*\n * The following hacks should only be necessary for (old) saved states, since all our disk manifests\n * should no longer be using any of these old paths.\n */\n sDiskPath = sDiskPath.replace(\"/disks/pc/\", \"/disks/pcx86/\");\n sDiskPath = sDiskPath.replace(\"/disks/pcx86/private/\", \"/private-disks/pcx86/\");\n sDiskPath = sDiskPath.replace(\"/disks/pcx86/\", \"/pcjs-disks/pcx86/\");\n sDiskPath = sDiskPath.replace(\"/fixed/\", \"/drives/\");\n disk.load(sDiskName, sDiskPath, null, this.doneLoadDisk);\n return false;\n }\n\n /**\n * doneLoadDisk(drive, disk, sDiskName, sDiskPath)\n *\n * This is a callback issued by the Disk component once the load() operation has finished.\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {Disk} disk is set if the disk was successfully mounted, null if not\n * @param {string} sDiskName\n * @param {string} sDiskPath\n */\n doneLoadDisk(drive, disk, sDiskName, sDiskPath)\n {\n drive.fBusy = false;\n if ((drive.disk = disk)) {\n /*\n * With the addition of notice(), users are now \"alerted\" whenever a diskette has finished loading;\n * notice() is selective about its output, using print() if a print window is open, otherwise alert().\n *\n * WARNING: This conversion of drive number to drive letter, starting with \"C:\" (0x43), is very simplistic\n * and is not guaranteed to match the drive mapping that DOS ultimately uses.\n */\n this.notice(\"Mounted disk \\\"\" + sDiskName + \"\\\" in drive \" + String.fromCharCode(0x43 + drive.iDrive), drive.fAutoMount);\n\n var aDiskInfo = disk.info();\n if (aDiskInfo[0] != drive.nCylinders || aDiskInfo[1] != drive.nHeads || aDiskInfo[2] != drive.nSectors || aDiskInfo[3] != drive.cbSector) {\n /*\n * TODO: Decide how to deal with this problem; ie, either disallow disk access altogether, or automatically\n * map the controller's I/O requests to the disk's geometry. Also, we should provide a way to reformat such a\n * disk so that its geometry matches the controller requirements.\n */\n this.notice(\"Warning: disk geometry (\" + aDiskInfo[0] + ':' + aDiskInfo[1] + ':' + aDiskInfo[2] + \") does not match \" + HDC.aDriveTables[this.iDriveTable] + \" drive type \" + drive.type + \" (\" + drive.nCylinders + ':' + drive.nHeads + ':' + drive.nSectors + \")\");\n }\n }\n if (drive.fAutoMount) {\n drive.fAutoMount = false;\n if (!--this.cAutoMount) this.setReady();\n }\n }\n\n /**\n * intXTCData(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x320)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inXTCData(port, addrFrom)\n {\n var bIn = 0;\n if (this.regDataIndex < this.regDataTotal) {\n bIn = this.regDataArray[this.regDataIndex];\n }\n if (this.chipset) this.chipset.clearIRR(ChipSet.IRQ.XTC);\n this.regStatus &= ~HDC.XTC.STATUS.INTERRUPT;\n\n this.printMessageIO(port, null, addrFrom, \"DATA[\" + this.regDataIndex + \"]\", bIn);\n if (++this.regDataIndex >= this.regDataTotal) {\n this.regDataIndex = this.regDataTotal = 0;\n this.regStatus &= ~(HDC.XTC.STATUS.IOMODE | HDC.XTC.STATUS.BUS | HDC.XTC.STATUS.BUSY);\n }\n return bIn;\n }\n\n /**\n * outXTCData(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x320)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outXTCData(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"DATA[\" + this.regDataTotal + \"]\");\n if (this.regDataTotal < this.regDataArray.length) {\n this.regDataArray[this.regDataTotal++] = bOut;\n }\n var bCmd = this.regDataArray[0];\n var cbCmd = (bCmd != HDC.XTC.DATA.CMD.INIT_DRIVE? 6 : this.regDataArray.length);\n if (this.regDataTotal == 6) {\n /*\n * XTC.STATUS.REQ must be CLEAR following any 6-byte command sequence that the HDC BIOS \"COMMAND\" function outputs,\n * yet it must also be SET before the HDC BIOS will proceed with the remaining the 8-byte sequence that's part of\n * HDC.XTC.DATA.CMD.INIT_DRIVE command. See inXTCStatus() for HACK details.\n */\n this.regStatus &= ~HDC.XTC.STATUS.REQ;\n }\n if (this.regDataTotal >= cbCmd) {\n /*\n * It's essential that XTC.STATUS.IOMODE be set here, at least after the final 8-byte HDC.XTC.DATA.CMD.INIT_DRIVE sequence.\n */\n this.regStatus |= HDC.XTC.STATUS.IOMODE;\n this.regStatus &= ~HDC.XTC.STATUS.REQ;\n this.doXTC();\n }\n }\n\n /**\n * inXTCStatus(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x321)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inXTCStatus(port, addrFrom)\n {\n var b = this.regStatus;\n this.printMessageIO(port, null, addrFrom, \"STATUS\", b);\n /*\n * HACK: The HDC BIOS will not finish the HDC.XTC.DATA.CMD.INIT_DRIVE sequence unless it sees XTC.STATUS.REQ set again, nor will\n * it read any of the XTC.DATA bytes returned from a HDC.XTC.DATA.CMD.REQUEST_SENSE command unless XTC.STATUS.REQ is set again, so\n * we turn it back on if there are unprocessed data bytes.\n */\n if (this.regDataIndex < this.regDataTotal) {\n this.regStatus |= HDC.XTC.STATUS.REQ;\n }\n return b;\n }\n\n /**\n * outXTCReset(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x321)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outXTCReset(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"RESET\");\n /*\n * Not sure what to do with this value, and the value itself may be \"don't care\", but we'll save it anyway.\n */\n this.regReset = bOut;\n if (this.chipset) this.chipset.clearIRR(ChipSet.IRQ.XTC);\n this.initController();\n }\n\n /**\n * inXTCConfig(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x322)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inXTCConfig(port, addrFrom)\n {\n this.printMessageIO(port, null, addrFrom, \"CONFIG\", this.regConfig);\n return this.regConfig;\n }\n\n /**\n * outXTCPulse(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x322)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outXTCPulse(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"PULSE\");\n /*\n * Not sure what to do with this value, and the value itself may be \"don't care\", but we'll save it anyway.\n */\n this.regPulse = bOut;\n /*\n * The HDC BIOS \"COMMAND\" function (@C800:0562) waits for these ALL status bits after writing to both regPulse\n * and regPattern, so we must oblige it.\n *\n * TODO: Figure out exactly when either XTC.STATUS.BUS or XTC.STATUS.BUSY are supposed to be cleared.\n * The HDC BIOS doesn't care much about them, except for the one location mentioned above. However, MS-DOS 4.0\n * (aka the unreleased \"multitasking\" version of MS-DOS) cares, so I'm going to start by clearing them at the\n * same point I clear XTC.STATUS.IOMODE.\n */\n this.regStatus = HDC.XTC.STATUS.REQ | HDC.XTC.STATUS.BUS | HDC.XTC.STATUS.BUSY;\n }\n\n /**\n * outXTCPattern(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x323)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outXTCPattern(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"PATTERN\");\n this.regPattern = bOut;\n }\n\n /**\n * outXTCNoise(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x327, 0x32B or 0x32F)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outXTCNoise(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"NOISE\");\n }\n\n /**\n * inATCByte(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F0)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inATCByte(port, addrFrom)\n {\n var bIn = -1;\n\n if (this.drive) {\n /*\n * We use the synchronous form of readData() at this point because we have no choice; an I/O instruction\n * has just occurred and cannot be delayed. The good news is that doATCommand() should have already primed\n * the pump; all we can do is assert that the pump has something in it. If bIn is inexplicably negative,\n * well, then the caller will get 0xff.\n */\n var hdc = this;\n bIn = this.readData(this.drive, function onATCReadData(b, fAsync, obj, off) {\n\n if (BACKTRACK) {\n if (!off && obj.file && hdc.messageEnabled(Messages.DISK)) {\n hdc.printMessage(\"loading \" + obj.file.sPath + '[' + obj.offFile + \"] via port \" + Str.toHexWord(port), true);\n }\n /*\n * TODO: We could define a cached BTO that's reset prior to a new ATC command, and then pass that\n * to addBackTrackObject() here instead of null; but for now, we're going to rely on that function's\n * simplistic MRU logic. If that fails, the worst that will (or should) happen is we'll burn through\n * more BackTrack wrapper objects than necessary, and risk running out.\n */\n var bto = hdc.bus.addBackTrackObject(obj, null, off);\n hdc.cpu.backTrack.btiIO = hdc.bus.getBackTrackIndex(bto, off);\n }\n });\n\n\n if (this.drive.ibSector == 1 || this.drive.ibSector == this.drive.cbSector) {\n /*\n * printMessageIO() calls, if enabled, can be overwhelming for this port, so limit them to the first\n * and last bytes of each sector.\n */\n if (this.messageEnabled(Messages.PORT | Messages.HDC)) {\n this.printMessageIO(port, null, addrFrom, \"DATA[\" + this.drive.ibSector + \"]\", bIn);\n }\n if (this.drive.ibSector > 1) { // in other words, if this.drive.ibSector == this.drive.cbSector...\n if (this.messageEnabled(Messages.DATA | Messages.HDC)) {\n var sDump = this.drive.disk.dumpSector(this.drive.sector);\n if (sDump) this.dbg.message(sDump);\n }\n /*\n * Now that we've supplied a full sector of data, see if the caller's expecting additional sectors;\n * if so, prime the pump again. The caller should not poll us again until another interrupt's delivered.\n */\n this.drive.nBytes -= this.drive.cbSector;\n this.regSecCnt = (this.regSecCnt - 1) & 0xff;\n /*\n * TODO: If the WITH_ECC bit is set in the READ_DATA command, then we need to support \"stuffing\" 4\n * additional bytes into the inATCByte() stream. And we must first set DATA_REQ in the STATUS register.\n */\n if (this.drive.nBytes >= this.drive.cbSector) {\n /*\n * FYI, with regard to regStatus, I'm simply aping what the ATC.COMMAND.READ_DATA setup code does\n * for the first sector, which may not strictly be necessary for subsequent sectors....\n */\n hdc.regStatus = HDC.ATC.STATUS.BUSY;\n this.readData(this.drive, function onATCReadDataNext(b, fAsync) {\n if (b >= 0) {\n hdc.setATCIRR();\n /*\n * Due to the way I'm immediately triggering an interrupt whenever more data is available,\n * I must take a \"shotgun approach' to regStatus bits in order to make the MODEL_5170_REV1,\n * MODEL_5170_REV3, and MODEL_COMPAQ_DESKPRO386 all happy.\n *\n * In general, it's fine for all of STATUS.READY, STATUS.SEEK_OK and STATUS.DATA_REQ to be\n * set now; the MODEL_5170_REV3 requires at least the first two, and the MODEL_COMPAQ_DESKPRO386\n * requires the third. Unfortunately, the outlier is the MODEL_5170_REV1, which also needs\n * the STATUS.BUSY to be set on the first regStatus read after it finishes reading a sector;\n * otherwise, the MODEL_5170_REV1 BIOS will never read any remaining sectors.\n *\n * Technically, it doesn't make sense for both BUSY and READY to be set at the same time,\n * so we fix that in inATCStatus() by clearing BUSY whenever READY is detected *after* that\n * first read. In addition, since this hack is really only needed for the MODEL_5170_REV1,\n * we clear BUSY immediately on the MODEL_COMPAQ_DESKPRO386 (which makes the Windows 95\n * protected-mode disk driver much happier).\n */\n if (hdc.chipset && hdc.chipset.model == ChipSet.MODEL_COMPAQ_DESKPRO386) hdc.regStatus = 0;\n hdc.regStatus |= HDC.ATC.STATUS.READY | HDC.ATC.STATUS.SEEK_OK | HDC.ATC.STATUS.DATA_REQ;\n } else {\n /*\n * TODO: It would be nice to be a bit more specific about the error (if any) that just occurred.\n * Consult drive.errorCode (it uses older XTC error codes, but mapping those codes should be trivial).\n */\n hdc.regStatus = HDC.ATC.STATUS.ERROR;\n hdc.regError = HDC.ATC.ERROR.NO_CHS;\n if (DEBUG) hdc.printMessage(this.idComponent + \".inATCByte(): read failed\");\n }\n }, false);\n } else {\n\n this.regStatus = HDC.ATC.STATUS.READY | HDC.ATC.STATUS.SEEK_OK;\n }\n }\n }\n }\n return bIn;\n }\n\n /**\n * inATCData(port, addrFrom)\n *\n * Wrapper around inATCByte() to treat this as a 16-bit port; see addPortInputWidth(HDC.ATC.DATA.PORT, 2).\n *\n * @this {HDC}\n * @param {number} port (0x1F0)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port data\n */\n inATCData(port, addrFrom)\n {\n return this.inATCByte(port, addrFrom) | (this.inATCByte(port, addrFrom) << 8);\n }\n\n /**\n * outATCByte(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F0)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outATCByte(port, bOut, addrFrom)\n {\n if (this.drive) {\n if (this.drive.nBytes >= this.drive.cbSector) {\n if (this.writeData(this.drive, bOut) < 0) {\n /*\n * TODO: It would be nice to be a bit more specific about the error (if any) that just occurred.\n * Consult drive.errorCode (it uses older XTC error codes, but mapping those codes should be trivial).\n */\n this.regStatus = HDC.ATC.STATUS.ERROR;\n this.regError = HDC.ATC.ERROR.NO_CHS;\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".outATCByte(\" + Str.toHexByte(bOut) + \"): write failed\");\n }\n }\n else if (this.drive.ibSector == 1 || this.drive.ibSector == this.drive.cbSector) {\n /*\n * printMessageIO() calls, if enabled, can be overwhelming for this port, so limit them to the first\n * and last bytes of each sector.\n */\n if (this.messageEnabled(Messages.PORT | Messages.HDC)) {\n this.printMessageIO(port, bOut, addrFrom, \"DATA[\" + this.drive.ibSector + \"]\");\n }\n if (this.drive.ibSector > 1) { // in other words, if this.drive.ibSector == this.drive.cbSector...\n if (this.messageEnabled(Messages.DATA | Messages.HDC)) {\n var sDump = this.drive.disk.dumpSector(this.drive.sector);\n if (sDump) this.dbg.message(sDump);\n }\n this.drive.nBytes -= this.drive.cbSector;\n this.regSecCnt = (this.regSecCnt - 1) & 0xff;\n this.setATCIRR(true);\n this.regStatus = HDC.ATC.STATUS.READY | HDC.ATC.STATUS.SEEK_OK;\n if (this.drive.nBytes >= this.drive.cbSector) {\n this.regStatus |= HDC.ATC.STATUS.DATA_REQ;\n } else {\n\n }\n }\n }\n } else {\n /*\n * TODO: What to do about unexpected writes? The number of bytes has exceeded what the command specified.\n */\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".outATCByte(\" + Str.toHexByte(bOut) + \"): write exceeds count (\" + this.drive.nBytes + \")\");\n }\n }\n } else {\n /*\n * TODO: What to do about unexpected writes? No command was specified.\n */\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".outATCByte(\" + Str.toHexByte(bOut) + \"): write without command\");\n }\n }\n }\n\n /**\n * outATCData(port, data, addrFrom)\n *\n * Wrapper around outATCByte() to treat this as a 16-bit port; see addPortOutputWidth(HDC.ATC.DATA.PORT, 2)\n *\n * @this {HDC}\n * @param {number} port (0x1F0)\n * @param {number} data\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outATCData(port, data, addrFrom)\n {\n this.outATCByte(port, data & 0xff, addrFrom);\n this.outATCByte(port, (data >> 8) & 0xff, addrFrom);\n }\n\n /**\n * inATCError(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F1)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inATCError(port, addrFrom)\n {\n var bIn = this.regError;\n this.printMessageIO(port, null, addrFrom, \"ERROR\", bIn);\n return bIn;\n }\n\n /**\n * outATCWPreC(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F1)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outATCWPreC(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"WPREC\");\n this.regWPreC = bOut;\n }\n\n /**\n * inATCSecCnt(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F2)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inATCSecCnt(port, addrFrom)\n {\n var bIn = this.regSecCnt;\n this.printMessageIO(port, null, addrFrom, \"SECCNT\", bIn);\n return bIn;\n }\n\n /**\n * outATCSecCnt(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F2)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outATCSecCnt(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"SECCNT\");\n this.regSecCnt = bOut;\n }\n\n /**\n * inATCSecNum(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F3)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inATCSecNum(port, addrFrom)\n {\n var bIn = this.regSecNum;\n this.printMessageIO(port, null, addrFrom, \"SECNUM\", bIn);\n return bIn;\n }\n\n /**\n * outATCSecNum(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F3)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outATCSecNum(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"SECNUM\");\n this.regSecNum = bOut;\n }\n\n /**\n * inATCCylLo(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F4)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inATCCylLo(port, addrFrom)\n {\n var bIn = this.regCylLo;\n this.printMessageIO(port, null, addrFrom, \"CYLLO\", bIn);\n return bIn;\n }\n\n /**\n * outATCCylLo(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F4)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outATCCylLo(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"CYLLO\");\n this.regCylLo = bOut;\n }\n\n /**\n * inATCCylHi(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F5)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inATCCylHi(port, addrFrom)\n {\n var bIn = this.regCylHi;\n this.printMessageIO(port, null, addrFrom, \"CYLHI\", bIn);\n return bIn;\n }\n\n /**\n * outATCCylHi(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F5)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outATCCylHi(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"CYLHI\");\n this.regCylHi = bOut;\n }\n\n /**\n * inATCDrvHd(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F6)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inATCDrvHd(port, addrFrom)\n {\n var bIn = this.regDrvHd;\n this.printMessageIO(port, null, addrFrom, \"DRVHD\", bIn);\n return bIn;\n }\n\n /**\n * outATCDrvHd(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F6)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outATCDrvHd(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"DRVHD\");\n this.regDrvHd = bOut;\n /*\n * The MODEL_5170_REV3 BIOS (see \"POST2_CHK_HF2\" @F000:14FC) probes for a 2nd hard drive when the number\n * of configured hard drives is something other than 2, using INT 0x13/AH=0x10. This in turn calls the\n * BIOS \"TST_RDY\" function, which selects the drive in this register (see DRIVE_MASK), and then immediately\n * expects regStatus to reflect success or failure.\n *\n * We were always returning success, because no ATC command was actually issued, and so the user would\n * always get a spurious CMOS configuration error: \"System Options Not Set-(Run SETUP)\".\n *\n * So now we update regStatus here. I'm not sure which status bits are normally set to indicate failure,\n * but it should be sufficient to set or clear the READY bit according to whether the drive exists or not.\n *\n * TODO: Dig into the ATC documentation some more, and determine what other situations, if any, regStatus\n * needs to be updated.\n *\n * UPDATE: The COMPAQ DeskPro 386 ROM BIOS requires setting STATUS.SEEK_OK in addition to STATUS.READY;\n * a quick retest of the MODEL_5170_REV3 BIOS suggests that it's happy with that change, so it's quite likely\n * that was the appropriate change all along.\n */\n var iDrive = (this.regDrvHd & HDC.ATC.DRVHD.DRIVE_MASK? 1 : 0);\n if (this.aDrives[iDrive]) {\n this.regStatus |= HDC.ATC.STATUS.READY | HDC.ATC.STATUS.SEEK_OK;\n } else {\n this.regStatus &= ~HDC.ATC.STATUS.READY;\n }\n }\n\n /**\n * inATCStatus(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F7)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inATCStatus(port, addrFrom)\n {\n var bIn = this.regStatus;\n this.printMessageIO(port, null, addrFrom, \"STATUS\", bIn);\n /*\n * Despite what IBM's documentation for the \"Personal Computer AT Fixed Disk and Diskette Drive Adapter\"\n * (August 31, 1984) says (ie, \"A read of the status register clears interrupt request 14\"), we cannot\n * unilaterally clear the IRQ on any read of STATUS. For starters, that would completely break the PC AT\n * ROM BIOS; here's what it does for multi-sector reads:\n *\n * (1) read sector (REP INSW)\n * (2) check STATUS\n * (3) check sector count, exit if done\n * (4) wait for interrupt\n * (5) repeat\n *\n * Since we set the IRR immediately after (1), we cannot immediately clear the IRR at (2), otherwise the\n * interrupt at (4) never happens. So, maybe there are SOME situations where IRR should be cleared on\n * a read, but I don't know what they are.\n *\n * if (this.chipset) this.chipset.clearIRR(ChipSet.IRQ.ATC);\n */\n if (this.regStatus & HDC.ATC.STATUS.READY) this.regStatus &= ~HDC.ATC.STATUS.BUSY;\n return bIn;\n }\n\n /**\n * outATCCommand(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F7)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outATCCommand(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"COMMAND\");\n this.regCommand = bOut;\n if (this.chipset) this.chipset.clearIRR(ChipSet.IRQ.ATC);\n this.doATC();\n }\n\n /**\n * outATCFDR(port, bOut, addrFrom)\n *\n * This is referred to in IBM's docs as the \"Fixed Disk Register\" (write-only)\n *\n * @this {HDC}\n * @param {number} port (0x3F6)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outATCFDR(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"FDR\");\n /*\n * I'm not really sure if I should set HDC.ATC.DIAG.NO_ERROR in regError after *every* write where\n * HDC.ATC.FDR.RESET is clear, or only after it has transitioned from set to clear; since the BIOS only\n * requires the latter, I'm going to be conservative and restrict regError updates to the latter.\n */\n if ((this.regFDR & HDC.ATC.FDR.RESET) && !(bOut & HDC.ATC.FDR.RESET)) this.regError = HDC.ATC.DIAG.NO_ERROR;\n this.regFDR = bOut;\n }\n\n /**\n * doATC()\n *\n * Handles ATC (AT Controller) commands\n *\n * @this {HDC}\n */\n doATC()\n {\n var hdc = this;\n var fInterrupt = false;\n var bCmd = this.regCommand;\n var iDrive = (this.regDrvHd & HDC.ATC.DRVHD.DRIVE_MASK? 1 : 0);\n var nHead = this.regDrvHd & HDC.ATC.DRVHD.HEAD_MASK;\n var nCylinder = this.regCylLo | ((this.regCylHi & HDC.ATC.CYLHI.MASK) << 8);\n var nSector = this.regSecNum;\n var nSectors = this.regSecCnt || 256;\n\n this.iDrive = -1;\n this.drive = null;\n this.regError = HDC.ATC.ERROR.NONE;\n this.regStatus = HDC.ATC.STATUS.READY | HDC.ATC.STATUS.SEEK_OK;\n\n var drive = this.aDrives[iDrive];\n if (!drive) {\n bCmd = -1;\n } else {\n /*\n * Update the Drive object with the new positional information associated with this command.\n */\n drive.wCylinder = nCylinder;\n drive.bHead = nHead;\n drive.bSector = nSector;\n drive.nBytes = nSectors * drive.cbSector;\n bCmd = (bCmd >= HDC.ATC.COMMAND.DIAGNOSE? bCmd : (bCmd & HDC.ATC.COMMAND.MASK));\n /*\n * Since the ATC doesn't use DMA, we must now set some additional Drive state for the benefit of any\n * follow-up I/O instructions. For example, any subsequent inATCByte() and outATCByte() calls need to\n * know which drive to talk to (\"this.drive\"), to issue their own readData() and writeData() calls.\n *\n * The XTC didn't need this, because it used doRead(), doWrite(), doFormat() helper functions,\n * which reset the current drive's \"sector\" and \"errorCode\" properties themselves and then used DMA\n * functions that delivered drive data with direct calls to readData() and writeData().\n */\n drive.sector = null;\n drive.ibSector = 0;\n drive.errorCode = 0;\n this.iDrive = iDrive;\n this.drive = drive;\n }\n\n if (DEBUG && this.messageEnabled(Messages.HDC)) {\n this.printMessage(this.idComponent + \".doATC(\" + Str.toHexByte(bCmd) + \"): \" + HDC.aATCCommands[bCmd], true);\n }\n\n switch (bCmd & HDC.ATC.COMMAND.MASK) {\n\n case HDC.ATC.COMMAND.RESTORE: // 0x10\n /*\n * Physically, this retracts the heads to cylinder 0, but logically, there isn't anything to do.\n */\n fInterrupt = true;\n break;\n\n case HDC.ATC.COMMAND.READ_DATA: // 0x20\n if (DEBUG && this.messageEnabled(Messages.HDC)) {\n this.printMessage(this.idComponent + \".doATCRead(\" + iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + nSectors + \")\", true);\n }\n /*\n * We're using a call to readData() that disables auto-increment, so that once we've got the first\n * byte of the next sector, we can signal an interrupt without also consuming the first byte, allowing\n * inATCByte() to begin with that byte.\n */\n hdc.regStatus = HDC.ATC.STATUS.BUSY;\n this.readData(drive, function onATCReadDataFirst(b, fAsync) {\n if (b >= 0 && hdc.chipset) {\n hdc.setATCIRR();\n /*\n * Bytes from the requested sector(s) will now be delivered via inATCByte().\n *\n * FYI, I'm taking a shotgun approach to these status bits: I need to clear STATUS.BUSY and\n * set STATUS.DATA_REQ, because otherwise COMPAQ DeskPro 386 reads will fail, and I need to set\n * the STATUS.READY and STATUS.SEEK_OK bits, because otherwise MODEL_5170_REV3 reads will fail.\n */\n hdc.regStatus = HDC.ATC.STATUS.READY | HDC.ATC.STATUS.SEEK_OK | HDC.ATC.STATUS.DATA_REQ;\n } else {\n /*\n * TODO: It would be nice to be a bit more specific about the error (if any) that just occurred.\n * Consult drive.errorCode (it uses older XTC error codes, but mapping those codes should be trivial).\n */\n hdc.regStatus = HDC.ATC.STATUS.ERROR;\n hdc.regError = HDC.ATC.ERROR.NO_CHS;\n }\n }, false);\n break;\n\n case HDC.ATC.COMMAND.WRITE_DATA: // 0x30\n if (DEBUG && this.messageEnabled(Messages.HDC)) {\n this.printMessage(this.idComponent + \".doATCWrite(\" + iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + nSectors + \")\", true);\n }\n this.regStatus = HDC.ATC.STATUS.DATA_REQ;\n break;\n\n case HDC.ATC.COMMAND.READ_VERF: // 0x40\n /*\n * Since the READ VERIFY command returns no data, once again, logically, there isn't much we HAVE to\n * to do, but... TODO: Verify that all the disk parameters are valid, and return an error if they're not.\n */\n fInterrupt = true;\n break;\n\n case HDC.ATC.COMMAND.SEEK: // 0x70\n /*\n * Physically, this moves the head(s) to the requested cylinder, but logically, there isn't anything to do;\n * in fact, we didn't even need this command for the MODEL_5170 ROM BIOS (the COMPAQ DeskPro 386 ROM BIOS was\n * another story).\n */\n fInterrupt = true;\n break;\n\n case HDC.ATC.COMMAND.DIAGNOSE: // 0x90\n this.regError = HDC.ATC.DIAG.NO_ERROR;\n fInterrupt = true;\n break;\n\n case HDC.ATC.COMMAND.SETPARMS: // 0x91\n /*\n * The documentation implies that the only parameters this command really affects are the number\n * of heads (from regDrvHd) and sectors/track (from regSecCnt) -- this despite the fact that the BIOS\n * programs all the other registers. For a type 2 drive, that includes:\n *\n * WPREC: 0x4B\n * SECCNT: 0x11 (for 17 sectors per track)\n * CYL: 0x100 (256 -- huh?)\n * SECNUM: 0x0C (12 -- huh?)\n * DRVHD: 0xA3 (max head of 0x03, for 4 total heads)\n *\n * The importance of SECCNT (nSectors) and DRVHD (nHeads) is controlling how multi-sector operations\n * advance to the next sector; see advanceSector().\n */\n\n\n drive.nHeads = nHead + 1;\n drive.nSectors = nSectors;\n fInterrupt = true;\n break;\n\n default:\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".doATC(\" + Str.toHexByte(this.regCommand) + \"): \" + (bCmd < 0? (\"invalid drive (\" + iDrive + \")\") : \"unsupported operation\"));\n if (MAXDEBUG && bCmd >= 0) this.dbg.stopCPU();\n }\n break;\n }\n\n if (fInterrupt) this.setATCIRR();\n }\n\n /**\n * setATCIRR(fWrite)\n *\n * Raise the ATC's IRQ, provided ATC interrupts are enabled.\n *\n * @this {HDC}\n * @param {boolean} [fWrite] is true on completion of a write to the sector buffer\n */\n setATCIRR(fWrite)\n {\n if (this.chipset) {\n if (!(this.regFDR & HDC.ATC.FDR.INT_DISABLE)) {\n /*\n * TODO: Determine what the \"correct\" instruction delay should be here. When the OS/2 1.0 Install Disk\n * begins copying files to the hard drive, at one point it performs the following 125-sector write (use the\n * Debugger's \"m hdc on\" and \"m pic on\" commands to enable HDC and PIC messages, along with \"m data on\"\n * if you also want to see the actual sector data being written):\n *\n * HDC.doATC(0x30): Write\n * HDC.doATCWrite(0,2:0:5,125)\n *\n * As the write progresses, you'll notice that the HDC interrupt after each sector occurs at decreasingly\n * lower points in the stack, until we eventually start overwriting non-stack data:\n *\n * getIRRVector(): IRQ 14 interrupting @0090:52A6 stack=0050:1906\n * getIRRVector(): IRQ 14 interrupting @0318:196B stack=0050:18D6\n * getIRRVector(): IRQ 14 interrupting @0318:196B stack=0050:18A6\n * ...\n * getIRRVector(): IRQ 14 interrupting @0318:196B stack=0050:1156\n *\n * At roughly this point, very bad things start happening. I decided to try an arbitrarily large delay\n * on the setIRR() call here (120), and the problem vanished, so it seems likely that the OS/2 disk driver\n * has a low tolerance for fast controller interrupts during multi-sector operations.\n */\n this.chipset.setIRR(ChipSet.IRQ.ATC, 120);\n if (DEBUG) this.printMessage(this.idComponent + \".setATCIRR(): enabled\", Messages.PIC | Messages.HDC);\n } else {\n if (DEBUG) this.printMessage(this.idComponent + \".setATCIRR(): disabled\", Messages.PIC | Messages.HDC);\n }\n }\n }\n\n /**\n * doXTC()\n *\n * Handles XTC (XT Controller) commands\n *\n * @this {HDC}\n */\n doXTC()\n {\n var hdc = this;\n this.regDataIndex = 0;\n\n var bCmd = this.popCmd();\n var bCmdOrig = bCmd;\n var b1 = this.popCmd();\n var bDrive = b1 & 0x20;\n var iDrive = (bDrive >> 5);\n\n var bHead = b1 & 0x1f;\n var b2 = this.popCmd();\n var b3 = this.popCmd();\n var wCylinder = ((b2 << 2) & 0x300) | b3;\n var bSector = b2 & 0x3f;\n var bCount = this.popCmd(); // block count or interleave count, depending on the command\n var bControl = this.popCmd();\n var bParm, bDataStatus;\n\n var drive = this.aDrives[iDrive];\n if (drive) {\n drive.wCylinder = wCylinder;\n drive.bHead = bHead;\n drive.bSector = bSector;\n drive.nBytes = bCount * drive.cbSector;\n }\n\n /*\n * I tried to save normal command processing from having to deal with invalid drives,\n * but the HDC BIOS initializes both drive 0 AND drive 1 on a HDC.XTC.DATA.CMD.INIT_DRIVE command,\n * and apparently that particular command has no problem with non-existent drives.\n *\n * So I've separated the commands into two groups: drive-ambivalent commands should be\n * processed in the first group, and all the rest should be processed in the second group.\n */\n switch (bCmd) {\n\n case HDC.XTC.DATA.CMD.REQUEST_SENSE: // 0x03\n this.beginResult(drive? drive.errorCode : HDC.XTC.DATA.ERR.NOT_READY);\n this.pushResult(b1);\n this.pushResult(b2);\n this.pushResult(b3);\n /*\n * Although not terribly clear from IBM's \"Fixed Disk Adapter\" documentation, a data \"status byte\"\n * also follows the 4 \"sense bytes\". Interestingly, The HDC BIOS checks that data status byte for\n * XTC.DATA.STATUS.ERROR, but I have to wonder if it would have ever been set for this command....\n *\n * The whole point of the HDC.XTC.DATA.CMD.REQUEST_SENSE command is to obtain details about a\n * previous error, so if HDC.XTC.DATA.CMD.REQUEST_SENSE itself reports an error, what would that mean?\n */\n this.pushResult(HDC.XTC.DATA.STATUS.OK | bDrive);\n bCmd = -1; // mark the command as complete\n break;\n\n case HDC.XTC.DATA.CMD.INIT_DRIVE: // 0x0C\n /*\n * Pop off all the extra \"Initialize Drive Characteristics\" bytes and store them, for the benefit of\n * other functions, like verifyDrive().\n */\n var i = 0;\n while ((bParm = this.popCmd()) >= 0) {\n if (drive && i < drive.abDriveParms.length) {\n drive.abDriveParms[i++] = bParm;\n }\n }\n if (drive) this.verifyDrive(drive);\n bDataStatus = HDC.XTC.DATA.STATUS.OK;\n if (!drive && this.iDriveAllowFail == iDrive) {\n this.iDriveAllowFail = -1;\n if (DEBUG) this.printMessage(this.idComponent + \".doXTC(): fake failure triggered\");\n bDataStatus = HDC.XTC.DATA.STATUS.ERROR;\n }\n this.beginResult(bDataStatus | bDrive);\n bCmd = -1; // mark the command as complete\n break;\n\n case HDC.XTC.DATA.CMD.RAM_DIAGNOSTIC: // 0xE0\n case HDC.XTC.DATA.CMD.CTL_DIAGNOSTIC: // 0xE4\n this.beginResult(HDC.XTC.DATA.STATUS.OK | bDrive);\n bCmd = -1; // mark the command as complete\n break;\n\n default:\n break;\n }\n\n if (bCmd >= 0) {\n if (drive === undefined) {\n bCmd = -1;\n } else {\n /*\n * In preparation for this command, zero out the drive's errorCode and senseCode.\n * Commands that require a disk address should update senseCode with HDC.XTC.DATA.SENSE_ADDR_VALID.\n * And of course, any command that encounters an error should set the appropriate error code.\n */\n drive.errorCode = HDC.XTC.DATA.ERR.NONE;\n drive.senseCode = 0;\n }\n switch (bCmd) {\n case HDC.XTC.DATA.CMD.TEST_READY: // 0x00\n this.beginResult(HDC.XTC.DATA.STATUS.OK | bDrive);\n break;\n\n case HDC.XTC.DATA.CMD.RECALIBRATE: // 0x01\n drive.bControl = bControl;\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".doXTC(): drive \" + iDrive + \" control byte: \" + Str.toHexByte(bControl));\n }\n this.beginResult(HDC.XTC.DATA.STATUS.OK | bDrive);\n break;\n\n case HDC.XTC.DATA.CMD.READ_VERF: // 0x05\n /*\n * This is a non-DMA operation, so we simply pretend everything is OK for now. TODO: Revisit.\n */\n this.beginResult(HDC.XTC.DATA.STATUS.OK | bDrive);\n break;\n\n case HDC.XTC.DATA.CMD.READ_DATA: // 0x08\n this.doRead(drive, function onXTCReadDataCommand(bStatus) {\n hdc.beginResult(bStatus | bDrive);\n });\n break;\n\n case HDC.XTC.DATA.CMD.WRITE_DATA: // 0x0A\n /*\n * QUESTION: The IBM TechRef (p.1-188) implies that bCount is used as part of HDC.XTC.DATA.CMD.WRITE_DATA command,\n * but it is omitted from the HDC.XTC.DATA.CMD.READ_DATA command. Is that correct? Note that, as far as the length\n * of the transfer is concerned, we rely exclusively on the DMA controller being programmed with the appropriate byte count.\n */\n this.doWrite(drive, function onXTCWriteDataCommand(bStatus) {\n hdc.beginResult(bStatus | bDrive);\n });\n break;\n\n case HDC.XTC.DATA.CMD.WRITE_BUFFER: // 0x0F\n this.doWriteBuffer(drive, function onXTCWriteBufferCommand(bStatus) {\n hdc.beginResult(bStatus | bDrive);\n });\n break;\n\n default:\n this.beginResult(HDC.XTC.DATA.STATUS.ERROR | bDrive);\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".doXTC(\" + Str.toHexByte(bCmdOrig) + \"): \" + (bCmd < 0? (\"invalid drive (\" + iDrive + \")\") : \"unsupported operation\"));\n if (MAXDEBUG && bCmd >= 0) this.dbg.stopCPU();\n }\n break;\n }\n }\n }\n\n /**\n * popCmd()\n *\n * @this {HDC}\n * @return {number}\n */\n popCmd()\n {\n var bCmd = -1;\n var bCmdIndex = this.regDataIndex;\n if (bCmdIndex < this.regDataTotal) {\n bCmd = this.regDataArray[this.regDataIndex++];\n if (DEBUG && this.messageEnabled((bCmdIndex > 0? Messages.PORT : 0) | Messages.HDC)) {\n this.printMessage(this.idComponent + \".popCmd(\" + bCmdIndex + \"): \" + Str.toHexByte(bCmd) + (!bCmdIndex && HDC.aXTCCommands[bCmd]? (\" (\" + HDC.aXTCCommands[bCmd] + \")\") : \"\"), true);\n }\n }\n return bCmd;\n }\n\n /**\n * beginResult(bResult)\n *\n * @this {HDC}\n * @param {number} [bResult]\n */\n beginResult(bResult)\n {\n this.regDataIndex = this.regDataTotal = 0;\n if (bResult !== undefined) this.pushResult(bResult);\n /*\n * After the Execution phase (eg, DMA Terminal Count has occurred, or the EOT sector has been read/written),\n * an interrupt is supposed to occur, signaling the beginning of the Result Phase. Once the data \"status byte\"\n * has been read from XTC.DATA, the interrupt is cleared (see inXTCData).\n */\n if (this.chipset) this.chipset.setIRR(ChipSet.IRQ.XTC);\n this.regStatus |= HDC.XTC.STATUS.INTERRUPT;\n }\n\n /**\n * pushResult(bResult)\n *\n * @this {HDC}\n * @param {number} bResult\n */\n pushResult(bResult)\n {\n if (DEBUG && this.messageEnabled((this.regDataTotal > 0? Messages.PORT : 0) | Messages.HDC)) {\n this.printMessage(this.idComponent + \".pushResult(\" + this.regDataTotal + \"): \" + Str.toHexByte(bResult), true);\n }\n this.regDataArray[this.regDataTotal++] = bResult;\n }\n\n /**\n * doDMARead(drive, b, done)\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {number} b\n * @param {function(number,boolean)} done\n */\n doDMARead(drive, b, done)\n {\n if (b === undefined || b < 0) {\n this.readData(drive, done);\n return;\n }\n /*\n * The DMA controller should be ASKING for data, not GIVING us data; this suggests an internal DMA miscommunication\n */\n if (DEBUG) this.printMessage(this.idComponent + \".doDMARead(): invalid DMA acknowledgement\");\n done(-1, false);\n }\n\n /**\n * doDMAWrite(drive, b)\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {number} b\n * @return {number}\n */\n doDMAWrite(drive, b)\n {\n if (b !== undefined && b >= 0)\n return this.writeData(drive, b);\n /*\n * The DMA controller should be GIVING us data, not ASKING for data; this suggests an internal DMA miscommunication\n */\n if (DEBUG) this.printMessage(this.idComponent + \".doDMAWrite(): invalid DMA acknowledgement\");\n return -1;\n }\n\n /**\n * doDMAWriteBuffer(drive, b)\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {number} b\n * @return {number}\n */\n doDMAWriteBuffer(drive, b)\n {\n if (b !== undefined && b >= 0)\n return this.writeBuffer(drive, b);\n /*\n * The DMA controller should be GIVING us data, not ASKING for data; this suggests an internal DMA miscommunication\n */\n if (DEBUG) this.printMessage(this.idComponent + \".doDMAWriteBuffer(): invalid DMA acknowledgement\");\n return -1;\n }\n\n /**\n * doDMAWriteFormat(drive, b)\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {number} b\n * @returns {number}\n */\n doDMAWriteFormat(drive, b)\n {\n if (b !== undefined && b >= 0)\n return this.writeFormat(drive, b);\n /*\n * The DMA controller should be GIVING us data, not ASKING for data; this suggests an internal DMA miscommunication\n */\n if (DEBUG) this.printMessage(this.idComponent + \".doDMAWriteFormat(): invalid DMA acknowledgement\");\n return -1;\n }\n\n /**\n * doRead(drive, done)\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {function(number)} done (dataStatus is XTC.DATA.STATUS.OK or XTC.DATA.STATUS.ERROR; if error, then drive.errorCode should be set as well)\n */\n doRead(drive, done)\n {\n drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".doRead(\" + drive.iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + ((drive.nBytes / drive.cbSector)|0) + \")\");\n }\n\n if (drive.disk) {\n drive.sector = null;\n if (this.chipset) {\n /*\n * We need to reverse the original logic, and default to success unless/until an actual error occurs;\n * otherwise doDMARead()/readData() will bail on us. The original approach used to work because requestDMA()\n * would immediately call us back with fComplete set to true EVEN if the DMA channel was not yet unmasked;\n * now the callback is deferred until the DMA channel has been unmasked and the DMA request has finished.\n */\n drive.errorCode = HDC.XTC.DATA.ERR.NONE;\n this.chipset.connectDMA(ChipSet.DMA_HDC, this, 'dmaRead', drive);\n this.chipset.requestDMA(ChipSet.DMA_HDC, function onDMAReadRequest(fComplete) {\n if (!fComplete) {\n /*\n * If an incomplete request wasn't triggered by an explicit error, then let's make explicit\n * (ie, revert to the default failure code that we originally set above).\n */\n if (drive.errorCode == HDC.XTC.DATA.ERR.NONE) {\n drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;\n }\n }\n done(drive.errorCode? HDC.XTC.DATA.STATUS.ERROR : HDC.XTC.DATA.STATUS.OK);\n });\n return;\n }\n }\n done(drive.errorCode? HDC.XTC.DATA.STATUS.ERROR : HDC.XTC.DATA.STATUS.OK);\n }\n\n /**\n * doWrite(drive, done)\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {function(number)} done (dataStatus is XTC.DATA.STATUS.OK or XTC.DATA.STATUS.ERROR; if error, then drive.errorCode should be set as well)\n */\n doWrite(drive, done)\n {\n drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".doWrite(\" + drive.iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + ((drive.nBytes / drive.cbSector)|0) + \")\");\n }\n\n if (drive.disk) {\n drive.sector = null;\n if (this.chipset) {\n /*\n * We need to reverse the original logic, and default to success unless/until an actual error occurs;\n * otherwise doDMAWrite()/writeData() will bail on us. The original approach would work because requestDMA()\n * would immediately call us back with fComplete set to true EVEN if the DMA channel was not yet unmasked;\n * now the callback is deferred until the DMA channel has been unmasked and the DMA request has finished.\n */\n drive.errorCode = HDC.XTC.DATA.ERR.NONE;\n this.chipset.connectDMA(ChipSet.DMA_HDC, this, 'dmaWrite', drive);\n this.chipset.requestDMA(ChipSet.DMA_HDC, function onDMAWriteRequest(fComplete) {\n if (!fComplete) {\n /*\n * If an incomplete request wasn't triggered by an explicit error, then let's make explicit\n * (ie, revert to the default failure code that we originally set above).\n */\n if (drive.errorCode == HDC.XTC.DATA.ERR.NONE) {\n drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;\n }\n /*\n * Mask any error that's the result of an attempt to write beyond the end of the track (which is\n * something the MS-DOS 4.0M's FORMAT utility seems to like to do).\n */\n if (drive.errorCode == HDC.XTC.DATA.ERR.NO_SECTOR) {\n drive.errorCode = HDC.XTC.DATA.ERR.NONE;\n }\n }\n done(drive.errorCode? HDC.XTC.DATA.STATUS.ERROR : HDC.XTC.DATA.STATUS.OK);\n });\n return;\n }\n }\n done(drive.errorCode? HDC.XTC.DATA.STATUS.ERROR : HDC.XTC.DATA.STATUS.OK);\n }\n\n /**\n * doWriteBuffer(drive, done)\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {function(number)} done (dataStatus is XTC.DATA.STATUS.OK or XTC.DATA.STATUS.ERROR; if error, then drive.errorCode should be set as well)\n */\n doWriteBuffer(drive, done)\n {\n drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;\n\n if (DEBUG) this.printMessage(this.idComponent + \".doWriteBuffer()\");\n\n if (!drive.abSector || drive.abSector.length != drive.nBytes) {\n drive.abSector = new Array(drive.nBytes);\n }\n drive.ibSector = 0;\n if (this.chipset) {\n /*\n * We need to reverse the original logic, and default to success unless/until an actual error occurs;\n * otherwise doDMAWriteBuffer() will bail on us. The original approach would work because requestDMA()\n * would immediately call us back with fComplete set to true EVEN if the DMA channel was not yet unmasked;\n * now the callback is deferred until the DMA channel has been unmasked and the DMA request has finished.\n */\n drive.errorCode = HDC.XTC.DATA.ERR.NONE;\n this.chipset.connectDMA(ChipSet.DMA_HDC, this, 'dmaWriteBuffer', drive);\n this.chipset.requestDMA(ChipSet.DMA_HDC, function onDMAWriteBufferRequest(fComplete) {\n if (!fComplete) {\n /*\n * If an incomplete request wasn't triggered by an explicit error, then let's make explicit\n * (ie, revert to the default failure code that we originally set above).\n */\n if (drive.errorCode == HDC.XTC.DATA.ERR.NONE) {\n drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;\n }\n }\n done(drive.errorCode? HDC.XTC.DATA.STATUS.ERROR : HDC.XTC.DATA.STATUS.OK);\n });\n return;\n }\n done(drive.errorCode? HDC.XTC.DATA.STATUS.ERROR : HDC.XTC.DATA.STATUS.OK);\n }\n\n /**\n * readData(drive, done)\n *\n * The following drive variable properties must have been setup prior to our first call:\n *\n * drive.wCylinder\n * drive.bHead\n * drive.bSector\n * drive.sector (initialized to null)\n *\n * On the first readData() request, since drive.sector will be null, we ask the Disk object to look\n * up the first sector of the request. We then ask the Disk for bytes from that sector until the sector\n * is exhausted, and then we look up the next sector and continue the process.\n *\n * NOTE: Since the HDC isn't aware of the extent of the transfer, all readData() can do is return bytes\n * until the current track (or, in the case of a multi-track request, the current cylinder) has been exhausted.\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {function(number,boolean,Object,number)} [done] (number is next available byte from drive, or -1 if no more bytes available)\n * @param {boolean} [fAutoInc] (default is true to auto-increment)\n * @return {number} the requested byte, or -1 if unavailable\n */\n readData(drive, done, fAutoInc)\n {\n var b = -1;\n var obj = null, off = 0; // these variables are purely for BACKTRACK purposes\n\n if (drive.errorCode) {\n if (done) done(b, false, obj, off);\n return b;\n }\n\n var inc = (fAutoInc !== false? 1 : 0);\n\n if (drive.sector) {\n off = drive.ibSector;\n b = drive.disk.read(drive.sector, drive.ibSector);\n drive.ibSector += inc;\n if (b >= 0) {\n obj = drive.sector;\n if (done) done(b, false, obj, off);\n return b;\n }\n }\n\n /*\n * Locate the next sector, and then try reading again.\n *\n * Important difference between the FDC and the XTC: the XTC uses 0-based sector numbers,\n * hence the bSectorBias below. I could change how sector numbers are stored in the image,\n * but it seems preferable to keep the image format consistent and controller-independent.\n */\n if (done) {\n var hdc = this;\n if (drive.disk) {\n drive.disk.seek(drive.wCylinder, drive.bHead, drive.bSector + drive.bSectorBias, false, function onReadDataSeek(sector, fAsync) {\n if ((drive.sector = sector)) {\n obj = sector;\n off = drive.ibSector = 0;\n /*\n * We \"pre-advance\" bSector et al now, instead of waiting to advance it right before the seek().\n * This allows the initial call to readData() to perform a seek without triggering an unwanted advance.\n */\n hdc.advanceSector(drive);\n b = drive.disk.read(drive.sector, drive.ibSector);\n drive.ibSector += inc;\n } else {\n drive.errorCode = HDC.XTC.DATA.ERR.NO_SECTOR;\n }\n done(b, fAsync, obj, off);\n });\n return b;\n }\n drive.errorCode = HDC.XTC.DATA.ERR.NO_SECTOR;\n done(b, false, obj, off);\n }\n return b;\n }\n\n /**\n * writeData(drive, b)\n *\n * The following drive variable properties must have been setup prior to our first call:\n *\n * drive.wCylinder\n * drive.bHead\n * drive.bSector\n * drive.sector (initialized to null)\n *\n * On the first writeData() request, since drive.sector will be null, we ask the Disk object to look\n * up the first sector of the request. We then send the Disk bytes for that sector until the sector\n * is full, and then we look up the next sector and continue the process.\n *\n * NOTE: Since the HDC isn't aware of the extent of the transfer, all writeData() can do is accept bytes\n * until the current track (or, in the case of a multi-track request, the current cylinder) has been exhausted.\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {number} b containing next byte to write\n * @return {number} (b unchanged; return -1 if command should be terminated)\n */\n writeData(drive, b)\n {\n if (drive.errorCode) return -1;\n do {\n if (drive.sector) {\n if (drive.disk.write(drive.sector, drive.ibSector++, b))\n break;\n }\n /*\n * Locate the next sector, and then try writing again.\n *\n * Important difference between the FDC and the XTC: the XTC uses 0-based sector numbers,\n * hence the bSectorBias below. I could change how sector numbers are stored in the image,\n * but it seems preferable to keep the image format consistent and controller-independent.\n */\n if (drive.disk) {\n drive.disk.seek(drive.wCylinder, drive.bHead, drive.bSector + drive.bSectorBias, true, function onWriteDataSeek(sector, fAsync) {\n drive.sector = sector;\n });\n }\n if (!drive.sector) {\n drive.errorCode = HDC.XTC.DATA.ERR.NO_SECTOR;\n b = -1;\n break;\n }\n drive.ibSector = 0;\n /*\n * We \"pre-advance\" bSector et al now, instead of waiting to advance it right before the seek().\n * This allows the initial call to writeData() to perform a seek without triggering an unwanted advance.\n */\n this.advanceSector(drive);\n } while (true);\n return b;\n }\n\n /**\n * advanceSector(drive)\n *\n * This increments the sector number; when the sector number reaches drive.nSectors on the current track, we\n * increment drive.bHead and reset drive.bSector, and when drive.bHead reaches drive.nHeads, we reset drive.bHead\n * and increment drive.wCylinder.\n *\n * One wrinkle is that the ATC uses 1-based sector numbers (bSectorBias is 0), whereas the XTC uses 0-based sector\n * numbers (bSectorBias is 1). Thus, the correct \"reset\" value for bSector is (1 - bSectorBias), and the correct\n * limit for bSector is (nSectors + bSectorStart).\n *\n * @this {HDC}\n * @param {Object} drive\n */\n advanceSector(drive)\n {\n\n drive.bSector++;\n var bSectorStart = (1 - drive.bSectorBias);\n if (drive.bSector >= drive.nSectors + bSectorStart) {\n drive.bSector = bSectorStart;\n drive.bHead++;\n if (drive.bHead >= drive.nHeads) {\n drive.bHead = 0;\n drive.wCylinder++;\n }\n }\n }\n\n /**\n * writeBuffer(drive, b)\n *\n * NOTE: Since the HDC isn't aware of the extent of the transfer, all writeBuffer() can do is accept bytes\n * until the buffer is full.\n *\n * TODO: Support for HDC.XTC.DATA.CMD.READ_BUFFER is missing, and support for HDC.XTC.DATA.CMD.WRITE_BUFFER may not be complete;\n * tests required.\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {number} b containing next byte to write\n * @return {number} (b unchanged; return -1 if command should be terminated)\n */\n writeBuffer(drive, b)\n {\n if (drive.ibSector < drive.abSector.length) {\n drive.abSector[drive.ibSector++] = b;\n } else {\n /*\n * TODO: Determine the proper error code to return here.\n */\n drive.errorCode = HDC.XTC.DATA.ERR.NO_SECTOR;\n b = -1;\n }\n return b;\n }\n\n /**\n * writeFormat(drive, b)\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {number} b containing a format command byte\n * @return {number} (b if successful, -1 if command should be terminated)\n */\n writeFormat(drive, b)\n {\n if (drive.errorCode) return -1;\n drive.abFormat[drive.cbFormat++] = b;\n if (drive.cbFormat == drive.abFormat.length) {\n drive.wCylinder = drive.abFormat[0]; // C\n drive.bHead = drive.abFormat[1]; // H\n drive.bSector = drive.abFormat[2]; // R\n drive.nBytes = 128 << drive.abFormat[3];// N (0 => 128, 1 => 256, 2 => 512, 3 => 1024)\n drive.cbFormat = 0;\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".writeFormat(\" + drive.wCylinder + \":\" + drive.bHead + \":\" + drive.bSector + \":\" + drive.nBytes + \")\");\n }\n\n for (var i = 0; i < drive.nBytes; i++) {\n if (this.writeData(drive, drive.bFiller) < 0) {\n return -1;\n }\n }\n drive.cSectorsFormatted++;\n }\n if (drive.cSectorsFormatted >= drive.bSectorEnd) b = -1;\n return b;\n }\n\n /**\n * intBIOSDisk(addr)\n *\n * NOTE: This function differentiates HDC requests from FDC requests, based on whether the INT 0x13 drive number\n * in DL is >= 0x80.\n *\n * HACK: The HDC BIOS code for both INT 0x13/AH=0x00 and INT 0x13/AH=0x09 calls \"INIT_DRV\" @C800:0427, which is\n * hard-coded to issue the HDC.XTC.DATA.CMD.INIT_DRIVE command for BOTH drives 0 and 1 (aka drive numbers 0x80 and\n * 0x81), regardless of the drive number specified in DL; this means that the HDC.XTC.DATA.CMD.INIT_DRIVE command\n * must always succeed for drive 1 if it also succeeds for drive 0 -- even if there is no drive 1. Bizarre, but OK,\n * whatever.\n *\n * So assuming we a have drive 0, when the power-on diagnostics in \"DISK_SETUP\" @C800:0003 call INT 0x13/AH=0x09\n * (@C800:00DB) for drive 0, it must succeed. No problem. But when \"DISK_SETUP\" starts probing for additional drives,\n * it first issues INT 0x13/AH=0x00, followed by INT 0x13/AH=0x11, and finally INT 0x13/AH=0x09. If the first\n * (AH=0x00) or third (AH=0x09) INT 0x13 fails, it quickly moves on (ie, it jumps to \"POD_DONE\"). But as we just\n * discussed, both those operations call \"INIT_DRV\", which can't return an error. This means the only function that\n * can return an error in this context is the recalibrate function (AH=0x11). That sucks, because the way the HDC\n * BIOS is written, it will loop for anywhere from 1.5 seconds to 25 seconds (depending on whether the controller\n * is part of the \"System Unit\" or not; see port 0x213), attempting to recalibrate drive 1 until it finally times out.\n *\n * Normally, you'll only experience the 1.5 second delay, but even so, it's a ridiculous waste of time and a lot of\n * useless INT 0x13 calls. So I monitor INT 0x13/AH=0x00 for DL >= 0x80 and set a special HDC.XTC.DATA.CMD.INIT_DRIVE\n * override flag (iDriveAllowFail) that will allow that command to fail, and in theory, make the the HDC BIOS\n * \"DISK_SETUP\" code much more efficient.\n *\n * @this {HDC}\n * @param {number} addr\n * @return {boolean} true to proceed with the INT 0x13 software interrupt, false to skip\n */\n intBIOSDisk(addr)\n {\n var AH = this.cpu.regEAX >> 8;\n var DL = this.cpu.regEDX & 0xff;\n if (!AH && DL > 0x80) this.iDriveAllowFail = DL - 0x80;\n return true;\n }\n\n /**\n * intBIOSDiskette(addr)\n *\n * When the HDC BIOS overwrites the ROM BIOS INT 0x13 address, it saves the original INT 0x13 address\n * in the INT 0x40 vector. This function intercepts calls to that vector to work around a minor nuisance.\n *\n * The HDC BIOS's plan was simple, albeit slightly flawed: assign fixed disks drive numbers >= 0x80,\n * and whenever someone calls INT 0x13 with a drive number < 0x80, invoke the original INT 0x13 diskette\n * code via INT 0x40 and return via RET 2.\n *\n * Unfortunately, not all original INT 0x13 functions required a drive number in DL (eg, the \"reset\"\n * function, where AH=0). And the HDC BIOS knew this, which is why, in the case of the \"reset\" function,\n * the HDC BIOS performs BOTH an INT 0x40 diskette reset AND an HDC reset -- it can't be sure which\n * controller the caller really wants to reset.\n *\n * An unfortunate side-effect of this behavior: when the HDC BIOS is initialized for the first time, it may\n * issue several resets internally, depending on whether there are 0, 1 or 2 hard drives installed, and each\n * of those resets also triggers completely useless diskette resets, each wasting up to two seconds waiting\n * for the FDC to interrupt. The FDC tries to interrupt, but it can't, because at this early stage of\n * ROM BIOS initialization, IRQ.FDC hasn't been unmasked yet.\n *\n * My work-around: have the HDC component hook INT 0x40, and every time an INT 0x40 is issued with AH=0 and\n * IRQ.FDC masked, bypass the INT 0x40 interrupt. This is as close as PCx86 has come to patching any BIOS code\n * (something I've refused to do), and even here, I'm not doing it out of necessity, just annoyance.\n *\n * @this {HDC}\n * @param {number} addr\n * @return {boolean} true to proceed with the INT 0x40 software interrupt, false to skip\n */\n intBIOSDiskette(addr)\n {\n var AH = this.cpu.regEAX >> 8;\n if ((!AH && this.chipset && this.chipset.checkIMR(ChipSet.IRQ.FDC))) {\n if (DEBUG) this.printMessage(this.idComponent + \".intBIOSDiskette(): skipping useless INT 0x40 diskette reset\");\n return false;\n }\n return true;\n }\n\n /**\n * unloadDrive(iDrive)\n *\n * NOTE: At the moment, we support only auto-mounts; there is no user interface for selecting hard drive\n * images, let alone unloading them, so there is currently no need for the following function.\n *\n * @this {HDC}\n * @param {number} iDrive\n *\n unloadDrive(iDrive)\n {\n this.aDrives[iDrive].disk = null;\n //\n // WARNING: This conversion of drive number to drive letter, starting with \"C:\" (0x43), is very simplistic\n // and is not guaranteed to match the drive mapping that DOS ultimately uses.\n //\n this.notice(\"Drive \" + String.fromCharCode(0x43 + iDrive) + \" unloaded\");\n }\n */\n\n /**\n * doFormat(drive, done)\n *\n * The drive variable is initialized by doXTC() to the following extent:\n *\n * drive.bHead (ignored)\n * drive.nBytes (bytes/sector)\n * drive.bSectorEnd (sectors/track)\n * drive.bFiller (fill byte)\n *\n * and we expect the DMA controller to provide C, H, R and N (ie, 4 bytes) for each sector to be formatted.\n *\n * NOTE: This function is not currently used.\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {function(number)} done (dataStatus is XTC.DATA.STATUS.OK or XTC.DATA.STATUS.ERROR; if error, then drive.errorCode should be set as well)\n *\n doFormat(drive, done)\n {\n drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;\n\n if (drive.disk) {\n drive.sector = null;\n if (this.chipset) {\n drive.cbFormat = 0;\n drive.abFormat = new Array(4);\n drive.bFormatting = true;\n drive.cSectorsFormatted = 0;\n //\n // We need to reverse the original logic, and default to success unless/until an actual error occurs;\n // otherwise doDMAWriteFormat() will bail on us. The original approach would work because requestDMA()\n // would immediately call us back with fComplete set to true EVEN if the DMA channel was not yet unmasked;\n // now the callback is deferred until the DMA channel has been unmasked and the DMA request has finished.\n //\n drive.errorCode = HDC.XTC.DATA.ERR.NONE;\n this.chipset.connectDMA(ChipSet.DMA_HDC, this, 'dmaWriteFormat', drive);\n this.chipset.requestDMA(ChipSet.DMA_HDC, function onDMAFormat(fComplete) {\n if (!fComplete) {\n //\n // If an incomplete request wasn't triggered by an explicit error, then let's make explicit\n // (ie, revert to the default failure code that we originally set above).\n //\n if (drive.errorCode == HDC.XTC.DATA.ERR.NONE) {\n drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;\n }\n }\n drive.bFormatting = false;\n done(drive.errorCode? HDC.XTC.DATA.STATUS.ERROR : HDC.XTC.DATA.STATUS.OK);\n });\n return;\n }\n }\n done(drive.errorCode? HDC.XTC.DATA.STATUS.ERROR : HDC.XTC.DATA.STATUS.OK);\n }\n */\n\n /**\n * HDC.init()\n *\n * This function operates on every HTML element of class \"hdc\", extracting the\n * JSON-encoded parameters for the HDC constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a HDC component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeHDC = Component.getElementsByClass(document, PCX86.APPCLASS, \"hdc\");\n for (var iHDC = 0; iHDC < aeHDC.length; iHDC++) {\n var eHDC = aeHDC[iHDC];\n var parmsHDC = Component.getComponentParms(eHDC);\n var hdc = new HDC(parmsHDC);\n Component.bindComponentControls(hdc, eHDC, PCX86.APPCLASS);\n }\n }\n}\n\n/*\n * HDC defaults, in case drive parameters weren't specified\n */\nHDC.DEFAULT_DRIVE_NAME = \"Hard Drive\";\n\n/*\n * Starting with the IBM PC XT, the ROM defined a \"Fixed Disk Parameter Table\" (FD_TBL) that contained 16 bytes\n * at the following offsets for each of 4 drive types (see IBM 5160 Tech Ref, April 1983, p. A-94):\n * \n * 0: maximum number of cylinders (word)\n * 2: maximum number of heads\n * 3: starting reduced write current cylinder (word)\n * 5: starting write precompensation cylinder (word)\n * 7: maximum ECC data burst length\n * 8: control byte (drive step option)\n * bit 7: disable disk-access retries\n * bit 6: disable ECC retries\n * bits 5-3: zero\n * bits 2-0: drive option\n * 9: standard time-out value\n * A: time-out value for format drive\n * B: time-out value for check drive\n * C: reserved\n * D: reserved\n * E: reserved\n * F: reserved\n * \n * Starting with the IBM PC AT, the ROM defined a \"Fixed Disk Parameter Table\" (FD_TBL) that contained 16 bytes\n * at the following offsets for each of 47 drive types (see IBM 5170 Tech Ref, March 1986, p. 5-185):\n * \n * 0: maximum number of cylinders (word)\n * 2: maximum number of heads\n * 3: not used\n * 5: starting write precompensation cylinder (word)\n * 7: not used\n * 8: control byte (drive step option)\n * bit 7: disable retries -OR-\n * bit 6: disable retries\n * bit 3: more than 8 heads\n * 9: not used\n * A: not used\n * B: not used\n * C: landing zone (word)\n * E: number of sectors/track (NOTE: all PC AT drive types specified 17 sectors/track)\n * F: reserved\n * \n * NOTE: While drive type 0 was a valid type in the PC XT, it was NOT a valid drive type in the PC AT; zero was used\n * to indicate that no hard drive was installed.\n * \n * Of the 47 PC AT drive types, the first 14 (1-E) could be selected by 4 bits in CMOS byte 0x12. Drive type 15 was not\n * a valid type but rather an indicator that CMOS byte 0x19 (or 0x1A) contained the actual drive type, which technically\n * could contain any value from 0-255, but was documented as being limited to values 16-255. And in fact, the ROM only\n * contained entries for drive types 1-47, and of those, only drive types 1-14 and 16-23 were valid; the rest (15 and 24-47)\n * were marked \"RESERVED\" and contained zeros.\n * \n * If a system needed a drive type that wasn't defined by the ROM, it could be placed in RAM, as the ROM explained:\n * \n * To dynamically define a set of parameters, build a table for up to 15 types and place\n * the corresponding vector into interrupt 0x41 for drive 0 and interrupt 0x46 for drive 1.\n * \n * To make PCjs easier to configure, we have three drive tables (for XT, AT, and COMPAQ machines), each of which\n * contains DriveArrays for the various DriveTypes supported by each machine. Each DriveArray contains the following\n * subset of \"Fixed Disk Parameter Table\" information:\n *\n * [0]: total cylinders\n * [1]: total heads\n * [2]: total sectors/tracks (optional; default is 17)\n * [3]: total bytes/sector (optional; default is 512)\n *\n * verifyDrive() attempts to confirm that these values agree with the programmed drive characteristics.\n *\n * NOTE: For the record, PCjs considers 1Kb to be 1 kilobyte (1,024 bytes, not 1,000 bytes) and 1Mb to be 1 megabyte\n * (1024*1024 or 1,048,576 bytes, not 1,000,000 bytes).\n *\n * Apparently, in 1998, it was decided that a kilobyte should be 1,000 bytes and a megabyte should be 1,000,000 bytes,\n * and that if you really meant 2^10 (1,024) or 2^20 (1,048,576), you should use \"kibibyte\" (KiB) or \"mebibyte\" (MiB)\n * instead. But since PCjs simulates machines that pre-date 1998, I have chosen to retain the more \"traditional\"\n * understanding of Kb and Mb; I never use KiB or MiB. \n */\n\n/*\n * Drive type tables differed across IBM controller models (XTC drive types don't match ATC drive types) and across OEMs\n * (eg, COMPAQ drive types only match a few IBM drive types), so you must use iDriveTable to index the correct table type\n * inside both aDriveTables and aDriveTypes.\n */\nHDC.aDriveTables = [\"XTC\", \"ATC\", \"COMPAQ\"];\n\nHDC.aDriveTypes = [\n /*\n * aDriveTypes[0] is for the IBM PC XT (XTC) controller.\n */\n {\n 0: [306, 2],\n 1: [375, 8],\n 2: [306, 6],\n 3: [306, 4] // 10Mb (10.16Mb: 306*4*17*512 or 10,653,696 bytes) (default XTC drive type: 3)\n },\n /*\n * aDriveTypes[1] is for the IBM PC AT (ATC) controller.\n *\n * The following is a more complete description of the drive types supported by the MODEL_5170, where C is\n * Cylinders, H is Heads, WP is Write Pre-Comp, and LZ is Landing Zone (in practice, we don't need WP or LZ).\n *\n * Type C H WP LZ\n * ---- --- -- --- ---\n * 1 306 4 128 305\n * 2 615 4 300 615\n * 3 615 6 300 615\n * 4 940 8 512 940\n * 5 940 6 512 940\n * 6 615 4 no 615\n * 7 462 8 256 511\n * 8 733 5 no 733\n * 9 900 15 no 901\n * 10 820 3 no 820\n * 11 855 5 no 855\n * 12 855 7 no 855\n * 13 306 8 128 319\n * 14 733 7 no 733\n * 15 (reserved--all zeros)\n * 16 612 4 all 663\n * 17 977 5 300 977\n * 18 977 7 no 977\n * 19 1024 7 512 1023\n * 20 733 5 300 732\n * 21 733 7 300 732\n * 22 733 5 300 733\n * 23 306 4 no 336\n */\n {\n 1: [306, 4], // 10Mb (10.16Mb: 306*4*17*512 or 10,653,696 bytes)\n 2: [615, 4], // 20Mb (20.42Mb: 615*4*17*512 or 21,411,840 bytes) (default ATC drive type)\n 3: [615, 6], // 31Mb (30.63Mb: 615*6*17*512 or 32,117,760 bytes)\n 4: [940, 8], // 62Mb (62.42Mb: 940*8*17*512 or 65,454,080 bytes)\n 5: [940, 6], // 47Mb (46.82Mb: 940*6*17*512 or 49,090,560 bytes)\n 6: [615, 4],\n 7: [462, 8],\n 8: [733, 5],\n 9: [900, 15],\n 10: [820, 3],\n 11: [855, 5],\n 12: [855, 7],\n 13: [306, 8],\n 14: [733, 7],\n /*\n * Since the remaining drive types are > 14, they must be stored in either EXTHDRIVE0 or EXTHDRIVE1 CMOS bytes (0x19 or 0x1A)\n */\n 16: [612, 4],\n 17: [977, 5],\n 18: [977, 7],\n 19: [1024, 7],\n 20: [733, 5],\n 21: [733, 7],\n 22: [733, 5],\n 23: [306, 4]\n },\n /*\n * aDriveTypes[2] is for the COMPAQ DeskPro (ATC) controller.\n *\n * NOTE: According to COMPAQ, drive type 25 (0x19) must be used with their 130Mb drive when using MS-DOS 3.1\n * or earlier, or when using any [unspecified] application software that supports only 17 sectors per track;\n * otherwise, use drive type 35 (0x23), which uses the drive's full capacity of 34 sectors per track.\n */\n {\n 1: [306, 4], // 10Mb (10.16Mb: 306*4*17*512 or 10,653,696 bytes) (same as IBM)\n 2: [615, 4], // 20Mb (20.42Mb: 615*4*17*512 or 21,411,840 bytes) (same as IBM)\n 3: [615, 6], // 31Mb (30.63Mb: 615*6*17*512 or 32,117,760 bytes) (same as IBM)\n 4: [1023, 8], // 68Mb (67.93Mb: 1023*8*17*512 or 71,233,536 bytes) (TODO: Cylinders is listed as 1024 in the COMPAQ TechRef; confirm)\n 5: [940, 6], // 47Mb (46.82Mb: 940*6*17*512 or 49,090,560 bytes) (same as IBM)\n 6: [697, 5],\n 7: [462, 8], // same as IBM\n 8: [925, 5],\n 9: [900, 15], // same as IBM\n 10: [980, 5],\n 11: [925, 7],\n 12: [925, 9], // 70Mb (69.10Mb: 925*9*17*512 or 72,460,800 bytes)\n 13: [612, 8],\n 14: [980, 4],\n /*\n * Since the remaining drive types are > 14, they must be stored in either EXTHDRIVE0 or EXTHDRIVE1 CMOS bytes (0x19 or 0x1A)\n */\n 16: [612, 4], // same as IBM\n 17: [980, 5], // 40Mb (40.67Mb: 980*5*17*512 or 42,649,600 bytes)\n 18: [966, 6],\n 19: [1023, 8],\n 20: [733, 5], // same as IBM\n 21: [733, 7], // same as IBM\n 22: [524, 4, 40],\n 23: [924, 8],\n 24: [966, 14],\n 25: [966, 16], // 130Mb (128.30Mb: 966*16*17*512 or 134,529,024 bytes)\n 26: [1023,14],\n 27: [832, 6, 33],\n 28: [1222,15, 34],\n 29: [1240, 7, 34],\n 30: [615, 4, 25],\n 31: [615, 8, 25],\n 32: [905, 9, 25],\n 33: [832, 8, 33], // 110Mb (107.25Mb: 832*8*33*512 or 112,459,776 bytes)\n 34: [966, 7, 34],\n 35: [966, 8, 34], // 130Mb (128.30Mb: 966*8*34*512 or 134,529,024 bytes)\n 36: [966, 9, 34],\n 37: [966, 5, 34],\n 38: [612, 16, 63], // 300Mb (301.22Mb: 612*16*63*512 or 315,850,752 bytes) (TODO: Cylinders is listed as 611 in the COMPAQ TechRef; confirm)\n 39: [1023,11, 33],\n 40: [1023,15, 34],\n 41: [1630,15, 52],\n 42: [1023,16, 63],\n 43: [805, 4, 26],\n 44: [805, 2, 26],\n 45: [748, 8, 33],\n 46: [748, 6, 33],\n 47: [966, 5, 25]\n }\n];\n\n/*\n * ATC (AT Controller) Registers\n *\n * The \"IBM Personal Computer AT Fixed Disk and Diskette Drive Adapter\", aka the HFCOMBO card, contains what we refer\n * to here as the ATC (AT Controller). Even though that card contains both Fixed Disk and Diskette Drive controllers,\n * this component (HDC) still deals only with the \"Fixed Disk\" portion. Fortunately, the \"Diskette Drive Adapter\"\n * portion of the card is compatible with the existing FDC component, so that component continues to be responsible\n * for all diskette operations.\n *\n * ATC ports default to their primary addresses; secondary port addresses are 0x80 lower (eg, 0x170 instead of 0x1F0).\n *\n * It's important to know that the MODEL_5170 BIOS has a special relationship with the \"Combo Hard File/Diskette\n * (HFCOMBO) Card\" (see @F000:144C). Initially, the ChipSet component intercepted reads for HFCOMBO's STATUS port\n * and returned the BUSY bit clear to reduce boot time; however, it turned out that was also a prerequisite for the\n * BIOS to write test patterns to the CYLLO port (0x1F4) and set the \"DUAL\" bit (bit 0) of the \"HFCNTRL\" byte at 40:8Fh\n * if those CYLLO operations succeeded (now that the HDC is \"ATC-aware\", the ChipSet port intercepts have been removed).\n *\n * Without the \"DUAL\" bit set, when it came time later to report the diskette drive type, the \"DISK_TYPE\" function\n * (@F000:273D) would branch to one of two almost-identical blocks of code -- specifically, a block that disallowed\n * diskette drive types >= 2 (ChipSet.CMOS.FDRIVE.FD360) instead of >= 3 (ChipSet.CMOS.FDRIVE.FD1200).\n *\n * In other words, the \"Fixed Disk\" portion of the HFCOMBO controller has to be present and operational if the user\n * wants to use high-capacity (80-track) diskettes with \"Diskette Drive\" portion of the controller. This may not be\n * immediately obvious to anyone creating a 5170 machine configuration with the FDC component but no HDC component.\n *\n * TODO: Investigate what a MODEL_5170 can do, if anything, with diskettes if an \"HFCOMBO card\" was NOT installed;\n * eg, was there Diskette-only Controller that could be installed, and if so, did it support high-capacity diskette\n * drives? Also, consider making the FDC component able to detect when the HDC is missing and provide the same minimal\n * HFCOMBO port intercepts that ChipSet once provided (this is not a requirement, just a usability improvement).\n *\n * UPDATE: I later discovered that newer (ie, REV2 and REV3) 5170 ROMs are even less happy when no HDC is installed,\n * *unless* an undocumented FDC \"DIAGNOSTIC\" register (port 0x3F1) provides a \"MULTIPLE DATA RATE\" response, bypassing\n * the HDC port tests described above. This may also imply that those newer 5170 revisions are incompatible with FD360\n * diskette drives, because if none of the \"MULTIPLE DATA RATE\" tests succeed, a \"601-Diskette Error\" always occurs.\n */\nHDC.ATC = {\n DATA: { PORT: 0x1F0}, // no register (read-write)\n DIAG: { // this.regError (read-only)\n PORT: 0x1F1,\n NO_ERROR: 0x01,\n CTRL_ERROR: 0x02,\n SEC_ERROR: 0x03,\n ECC_ERROR: 0x04,\n PROC_ERROR: 0x05\n },\n ERROR: { // this.regError (read-only)\n PORT: 0x1F1,\n NONE: 0x00,\n NO_DAM: 0x01, // Data Address Mark (DAM) not found\n NO_TRK0: 0x02, // Track 0 not detected\n CMD_ABORT: 0x04, // Aborted Command\n NO_CHS: 0x10, // ID field with the specified C:H:S not found\n ECC_ERR: 0x40, // Data ECC Error\n BAD_BLOCK: 0x80 // Bad Block Detect\n },\n WPREC: { PORT: 0x1F1}, // this.regWPreC (write-only)\n SECCNT: { PORT: 0x1F2}, // this.regSecCnt (read-write; 0 implies a 256-sector request)\n SECNUM: { PORT: 0x1F3}, // this.regSecNum (read-write)\n CYLLO: { PORT: 0x1F4}, // this.regCylLo (read-write; all 8 bits are used)\n CYLHI: { // this.regCylHi (read-write; only bits 0-1 are used, for a total of 10 bits, or 1024 max cylinders)\n PORT: 0x1F5,\n MASK: 0x03\n },\n DRVHD: { // this.regDrvHd (read-write)\n PORT: 0x1F6,\n HEAD_MASK: 0x0F, // set this to the max number of heads before issuing a SET PARAMETERS command\n DRIVE_MASK: 0x10,\n SET_MASK: 0xE0,\n SET_BITS: 0xA0 // for whatever reason, these bits must always be set\n },\n STATUS: { // this.regStatus (read-only; reading clears IRQ.ATC)\n PORT: 0x1F7,\n ERROR: 0x01, // set when the previous command ended in an error; one or more bits are set in the ERROR register (the next command to the controller resets the ERROR bit)\n INDEX: 0x02, // set once for every revolution of the disk\n CORRECTED: 0x04,\n DATA_REQ: 0x08, // indicates that \"the sector buffer requires servicing during a Read or Write command. If either bit 7 (BUSY) or this bit is active, a command is being executed. Upon receipt of any command, this bit is reset.\"\n SEEK_OK: 0x10, // seek operation complete\n WFAULT: 0x20, // write fault\n READY: 0x40, // if this is set (along with the SEEK_OK bit), the drive is ready to read/write/seek again\n BUSY: 0x80 // if this is set, no other STATUS bits are valid\n },\n COMMAND: { // this.regCommand (write-only)\n PORT: 0x1F7,\n RESTORE: 0x10, // low nibble x 500us equal stepping rate (except for 0, which corresponds to 35us) (aka RECALIBRATE)\n READ_DATA: 0x20, // also supports NO_RETRIES and WITH_ECC\n WRITE_DATA: 0x30, // also supports NO_RETRIES and WITH_ECC\n READ_VERF: 0x40, // also supports NO_RETRIES\n FORMAT_TRK: 0x50, // TODO\n SEEK: 0x70, // low nibble x 500us equal stepping rate (except for 0, which corresponds to 35us)\n DIAGNOSE: 0x90,\n SETPARMS: 0x91,\n NO_RETRIES: 0x01,\n WITH_ECC: 0x02,\n MASK: 0xF0\n },\n FDR: { // this.regFDR\n PORT: 0x3F6,\n INT_DISABLE: 0x02, // a logical 0 enables fixed disk interrupts\n RESET: 0x04, // a logical 1 enables reset fixed disk function\n HS3: 0x08, // a logical 1 enables head select 3 (a logical 0 enables reduced write current)\n RESERVED: 0xF1\n }\n};\n\n/*\n * XTC (XT Controller) Registers\n */\nHDC.XTC = {\n /*\n * XTC Data Register (0x320, read-write)\n *\n * Writes to this register are discussed below; see HDC Commands.\n *\n * Reads from this register after a command has been executed retrieve a \"status byte\",\n * which must NOT be confused with the Status Register (see below). This data \"status byte\"\n * contains only two bits of interest: XTC.DATA.STATUS.ERROR and XTC.DATA.STATUS.UNIT.\n */\n DATA: {\n PORT: 0x320, // port address\n STATUS: {\n OK: 0x00, // no error\n ERROR: 0x02, // error occurred during command execution\n UNIT: 0x20 // logical unit number of the drive\n },\n /*\n * XTC Commands, as issued to XTC_DATA\n *\n * Commands are multi-byte sequences sent to XTC_DATA, starting with a XTC_DATA.CMD byte,\n * and followed by 5 more bytes, for a total of 6 bytes, which collectively are called a\n * Device Control Block (DCB). Not all commands use all 6 bytes, but all 6 bytes must be present;\n * unused bytes are simply ignored.\n *\n * XTC_DATA.CMD (3-bit class code, 5-bit operation code)\n * XTC_DATA.HEAD (1-bit drive number, 5-bit head number)\n * XTC_DATA.CLSEC (upper bits of 10-bit cylinder number, 6-bit sector number)\n * XTC_DATA.CH (lower bits of 10-bit cylinder number)\n * XTC_DATA.COUNT (8-bit interleave or block count)\n * XTC_DATA.CTRL (8-bit control field)\n *\n * One command, HDC.XTC.DATA.CMD.INIT_DRIVE, must include 8 additional bytes following the DCB:\n *\n * maximum number of cylinders (high)\n * maximum number of cylinders (low)\n * maximum number of heads\n * start reduced write current cylinder (high)\n * start reduced write current cylinder (low)\n * start write precompensation cylinder (high)\n * start write precompensation cylinder (low)\n * maximum ECC data burst length\n *\n * Note that the 3 word values above are stored in \"big-endian\" format (high byte followed by low byte),\n * rather than the more typical \"little-endian\" format (low byte followed by high byte).\n */\n CMD: {\n TEST_READY: 0x00, // Test Drive Ready\n RECALIBRATE: 0x01, // Recalibrate\n REQUEST_SENSE: 0x03, // Request Sense Status\n FORMAT_DRIVE: 0x04, // Format Drive\n READ_VERF: 0x05, // Read Verify\n FORMAT_TRK: 0x06, // Format Track\n FORMAT_BAD: 0x07, // Format Bad Track\n READ_DATA: 0x08, // Read\n WRITE_DATA: 0x0A, // Write\n SEEK: 0x0B, // Seek\n INIT_DRIVE: 0x0C, // Initialize Drive Characteristics\n READ_ECC_BURST: 0x0D, // Read ECC Burst Error Length\n READ_BUFFER: 0x0E, // Read Data from Sector Buffer\n WRITE_BUFFER: 0x0F, // Write Data to Sector Buffer\n RAM_DIAGNOSTIC: 0xE0, // RAM Diagnostic\n DRV_DIAGNOSTIC: 0xE3, // HDC BIOS: CHK_DRV_CMD\n CTL_DIAGNOSTIC: 0xE4, // HDC BIOS: CNTLR_DIAG_CMD\n READ_LONG: 0xE5, // HDC BIOS: RD_LONG_CMD\n WRITE_LONG: 0xE6 // HDC BIOS: WR_LONG_CMD\n },\n ERR: {\n /*\n * HDC error conditions, as returned in byte 0 of the (4) bytes returned by the Request Sense Status command\n */\n NONE: 0x00,\n NO_INDEX: 0x01, // no index signal detected\n SEEK_INCOMPLETE:0x02, // no seek-complete signal\n WRITE_FAULT: 0x03,\n NOT_READY: 0x04, // after the controller selected the drive, the drive did not respond with a ready signal\n NO_TRACK: 0x06, // after stepping the max number of cylinders, the controller did not receive the track 00 signal from the drive\n STILL_SEEKING: 0x08,\n ECC_ID_ERROR: 0x10,\n ECC_DATA_ERROR: 0x11,\n NO_ADDR_MARK: 0x12,\n NO_SECTOR: 0x14,\n BAD_SEEK: 0x15, // seek error: the cylinder and/or head address did not compare with the expected target address\n ECC_CORRECTABLE:0x18, // correctable data error\n BAD_TRACK: 0x19,\n BAD_CMD: 0x20,\n BAD_DISK_ADDR: 0x21,\n RAM: 0x30,\n CHECKSUM: 0x31,\n POLYNOMIAL: 0x32,\n MASK: 0x3F\n },\n SENSE: {\n ADDR_VALID: 0x80\n }\n },\n /*\n * XTC Status Register (0x321, read-only)\n *\n * WARNING: The IBM Technical Reference Manual *badly* confuses the XTC_DATA \"status byte\" (above)\n * that the controller sends following an HDC.XTC.DATA.CMD operation with the Status Register (below).\n * In fact, it's so badly confused that it completely fails to document any of the Status Register\n * bits below; I'm forced to guess at their meanings from the HDC BIOS listing.\n */\n STATUS: {\n PORT: 0x321, // port address\n NONE: 0x00,\n REQ: 0x01, // HDC BIOS: request bit\n IOMODE: 0x02, // HDC BIOS: mode bit (GUESS: set whenever XTC_DATA contains a response?)\n BUS: 0x04, // HDC BIOS: command/data bit (GUESS: set whenever XTC_DATA ready for request?)\n BUSY: 0x08, // HDC BIOS: busy bit\n INTERRUPT: 0x20 // HDC BIOS: interrupt bit\n }\n};\n\n/*\n * XTC Config Register (0x322, read-only)\n *\n * This register is used to read HDC card switch settings that defined the \"Drive Type\" for\n * drives 0 and 1. SW[1],SW[2] (for drive 0) and SW[3],SW[4] (for drive 1) are set as follows:\n *\n * ON, ON Drive Type 0 (306 cylinders, 2 heads)\n * ON, OFF Drive Type 1 (375 cylinders, 8 heads)\n * OFF, ON Drive Type 2 (306 cylinders, 6 heads)\n * OFF, OFF Drive Type 3 (306 cylinders, 4 heads)\n */\n\n/*\n * HDC Command Sequences\n *\n * Unlike the FDC, all the HDC commands have fixed-length command request sequences (well, OK, except for\n * HDC.XTC.DATA.CMD.INIT_DRIVE) and fixed-length response sequences (well, OK, except for HDC.XTC.DATA.CMD.REQUEST_SENSE),\n * so a table of byte-lengths isn't much use, but having names for all the commands is still handy for debugging.\n */\nif (DEBUG) {\n HDC.aATCCommands = {\n 0x10: \"Restore (Recalibrate)\",\n 0x20: \"Read\",\n 0x30: \"Write\",\n 0x40: \"Read Verify\",\n 0x50: \"Format Track\",\n 0x70: \"Seek\",\n 0x90: \"Diagnose\",\n 0x91: \"Set Parameters\"\n };\n HDC.aXTCCommands = {\n 0x00: \"Test Drive Ready\",\n 0x01: \"Recalibrate\",\n 0x03: \"Request Sense Status\",\n 0x04: \"Format Drive\",\n 0x05: \"Read Verify\",\n 0x06: \"Format Track\",\n 0x07: \"Format Bad Track\",\n 0x08: \"Read\",\n 0x0A: \"Write\",\n 0x0B: \"Seek\",\n 0x0C: \"Initialize Drive Characteristics\",\n 0x0D: \"Read ECC Burst Error Length\",\n 0x0E: \"Read Data from Sector Buffer\",\n 0x0F: \"Write Data to Sector Buffer\",\n 0xE0: \"RAM Diagnostic\",\n 0xE3: \"Drive Diagnostic\",\n 0xE4: \"Controller Diagnostic\",\n 0xE5: \"Read Long\",\n 0xE6: \"Write Long\"\n };\n}\n\n/*\n * Port input notification tables\n */\nHDC.aXTCPortInput = {\n 0x320: HDC.prototype.inXTCData,\n 0x321: HDC.prototype.inXTCStatus,\n 0x322: HDC.prototype.inXTCConfig\n};\n\n/*\n * For future reference, the REV2 and REV3 PC AT ROM BIOS also refer to a \"FIXED DISK DIAGNOSTIC REGISTER\" at\n * port 0x5F7, but I have no documentation on it, and failure to respond is non-fatal. See the discussion of the\n * FDC diagnostic register in inFDCDiagnostic() for more details.\n */\nHDC.aATCPortInput = {\n 0x1F0: HDC.prototype.inATCData,\n 0x1F1: HDC.prototype.inATCError,\n 0x1F2: HDC.prototype.inATCSecCnt,\n 0x1F3: HDC.prototype.inATCSecNum,\n 0x1F4: HDC.prototype.inATCCylLo,\n 0x1F5: HDC.prototype.inATCCylHi,\n 0x1F6: HDC.prototype.inATCDrvHd,\n 0x1F7: HDC.prototype.inATCStatus\n};\n\n/*\n * Port output notification tables\n */\nHDC.aXTCPortOutput = {\n 0x320: HDC.prototype.outXTCData,\n 0x321: HDC.prototype.outXTCReset,\n 0x322: HDC.prototype.outXTCPulse,\n 0x323: HDC.prototype.outXTCPattern,\n /*\n * The PC XT Fixed Disk BIOS includes some additional \"housekeeping\" that it performs\n * not only on port 0x323 but also on three additional ports, at increments of 4 (see all\n * references to \"RESET INT/DMA MASK\" in the Fixed Disk BIOS). It's not clear to me if\n * those ports refer to additional HDC controllers, and I haven't seen other references to\n * them, but in any case, they represent a lot of \"I/O noise\" that we simply squelch here.\n */\n 0x327: HDC.prototype.outXTCNoise,\n 0x32B: HDC.prototype.outXTCNoise,\n 0x32F: HDC.prototype.outXTCNoise\n};\n\nHDC.aATCPortOutput = {\n 0x1F0: HDC.prototype.outATCData,\n 0x1F1: HDC.prototype.outATCWPreC,\n 0x1F2: HDC.prototype.outATCSecCnt,\n 0x1F3: HDC.prototype.outATCSecNum,\n 0x1F4: HDC.prototype.outATCCylLo,\n 0x1F5: HDC.prototype.outATCCylHi,\n 0x1F6: HDC.prototype.outATCDrvHd,\n 0x1F7: HDC.prototype.outATCCommand,\n 0x3F6: HDC.prototype.outATCFDR\n};\n\n/*\n * Initialize every Hard Drive Controller (HDC) module on the page.\n */\nWeb.onInit(HDC.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/debugger.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Debugger Address Object\n *\n * This is the basic structure; other debuggers may extend it.\n *\n * addr address\n * fTemporary true if this is a temporary breakpoint address\n * sCmd set for breakpoint addresses if there's an associated command string\n * aCmds preprocessed commands (from sCmd)\n *\n * @typedef {{\n * addr:(number|undefined),\n * fTemporary:(boolean|undefined),\n * sCmd:(string|undefined),\n * aCmds:(Array.<string>|undefined)\n * }}\n */\nvar DbgAddr;\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * subclass (eg, SerialPort), because otherwise the Compiler won't allow us to *reference*\n * the named property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass Debugger extends Component\n{\n /**\n * Debugger(parmsDbg)\n *\n * The Debugger component supports the following optional (parmsDbg) properties:\n *\n * base: the base to use for most numeric input/output (default is 16)\n *\n * The Debugger component is a shared component containing a subset of functionality used by\n * the other CPU-specific Debuggers (eg, DebuggerX86). Over time, the goal is to factor out as\n * much common debugging support as possible from those components into this one.\n *\n * @param {Object} parmsDbg\n */\n constructor(parmsDbg)\n {\n if (DEBUGGER) {\n\n super(\"Debugger\", parmsDbg);\n\n /*\n * Default base used to display all values; modified with the \"s base\" command.\n */\n this.nBase = +parmsDbg['base'] || 16;\n\n /*\n * Default number of bits of integer precision; it can be overridden by the Debugger\n * but there is no command to adjust it.\n */\n this.nBits = 32;\n\n this.achGroup = ['{','}'];\n this.achAddress = ['[',']'];\n\n /*\n * These keep track of instruction activity, but only when tracing or when Debugger checks\n * have been enabled (eg, one or more breakpoints have been set).\n *\n * They are zeroed by the reset() notification handler. cInstructions is advanced by\n * stepCPU() and checkInstruction() calls. nCycles is updated by every stepCPU() or stop()\n * call and simply represents the number of cycles performed by the last run of instructions.\n */\n this.nCycles = 0;\n this.cOpcodes = this.cOpcodesStart = 0;\n\n /*\n * fAssemble is true when \"assemble mode\" is active, false when not.\n */\n this.fAssemble = false;\n\n /*\n * This maintains command history. New commands are inserted at index 0 of the array.\n * When Enter is pressed on an empty input buffer, we default to the command at aPrevCmds[0].\n */\n this.iPrevCmd = -1;\n this.aPrevCmds = [];\n\n /*\n * aVariables is an object with properties that grow as setVariable() assigns more variables;\n * each property corresponds to one variable, where the property name is the variable name (ie,\n * a string beginning with a non-digit, followed by zero or more symbol characters and/or digits)\n * and the property value is the variable's numeric value. See doVar() and setVariable() for\n * details.\n *\n * Note that parseValue() parses variables before numbers, so any variable that looks like a\n * unprefixed hex value (eg, \"a5\" as opposed to \"0xa5\") will trump the numeric value. Unprefixed\n * hex values are a convenience of parseValue(), which always calls Str.parseInt() with a default\n * base of 16; however, that default be overridden with a variety of explicit prefixes or suffixes\n * (eg, a leading \"0o\" to indicate octal, a trailing period to indicate decimal, etc.)\n *\n * See Str.parseInt() for more details about supported numbers.\n */\n this.aVariables = {};\n\n } // endif DEBUGGER\n }\n\n /**\n * getRegIndex(sReg, off)\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {string} sReg\n * @param {number} [off] optional offset into sReg\n * @return {number} register index, or -1 if not found\n */\n getRegIndex(sReg, off)\n {\n return -1;\n }\n\n /**\n * getRegValue(iReg)\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {number} iReg\n * @return {number|undefined}\n */\n getRegValue(iReg)\n {\n return undefined;\n }\n\n /**\n * parseAddrReference(s, sAddr)\n *\n * Returns the given string with the given address reference replaced with the contents of that address.\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {string} s\n * @param {string} sAddr\n * @return {string}\n */\n parseAddrReference(s, sAddr)\n {\n return s.replace('[' + sAddr + ']', \"unimplemented\");\n }\n\n /**\n * getNextCommand()\n *\n * @this {Debugger}\n * @return {string}\n */\n getNextCommand()\n {\n var sCmd;\n if (this.iPrevCmd > 0) {\n sCmd = this.aPrevCmds[--this.iPrevCmd];\n } else {\n sCmd = \"\";\n this.iPrevCmd = -1;\n }\n return sCmd;\n }\n\n /**\n * getPrevCommand()\n *\n * @this {Debugger}\n * @return {string|null}\n */\n getPrevCommand()\n {\n var sCmd = null;\n if (this.iPrevCmd < this.aPrevCmds.length - 1) {\n sCmd = this.aPrevCmds[++this.iPrevCmd];\n }\n return sCmd;\n }\n\n /**\n * parseCommand(sCmd, fSave, chSep)\n *\n * @this {Debugger}\n * @param {string|undefined} sCmd\n * @param {boolean} [fSave] is true to save the command, false if not\n * @param {string} [chSep] is the command separator character (default is ';')\n * @return {Array.<string>}\n */\n parseCommand(sCmd, fSave, chSep)\n {\n if (fSave) {\n if (!sCmd) {\n if (this.fAssemble) {\n sCmd = \"end\";\n } else {\n sCmd = this.aPrevCmds[this.iPrevCmd+1];\n }\n } else {\n if (this.iPrevCmd < 0 && this.aPrevCmds.length) {\n this.iPrevCmd = 0;\n }\n if (this.iPrevCmd < 0 || sCmd != this.aPrevCmds[this.iPrevCmd]) {\n this.aPrevCmds.splice(0, 0, sCmd);\n this.iPrevCmd = 0;\n }\n this.iPrevCmd--;\n }\n }\n var a = [];\n if (sCmd) {\n /*\n * With the introduction of breakpoint commands (ie, quoted command sequences\n * associated with a breakpoint), we can no longer perform simplistic splitting.\n *\n * a = sCmd.split(chSep || ';');\n * for (var i = 0; i < a.length; i++) a[i] = Str.trim(a[i]);\n *\n * We may now split on semi-colons ONLY if they are outside a quoted sequence.\n *\n * Also, to allow quoted strings *inside* breakpoint commands, we first replace all\n * DOUBLE double-quotes with single quotes.\n */\n sCmd = sCmd.replace(/\"\"/g, \"'\");\n\n var iPrev = 0;\n var chQuote = null;\n chSep = chSep || ';';\n /*\n * NOTE: Processing charAt() up to and INCLUDING length is not a typo; we're taking\n * advantage of the fact that charAt() with an invalid index returns an empty string,\n * allowing us to use the same substring() call to capture the final portion of sCmd.\n *\n * In a sense, it allows us to pretend that the string ends with a zero terminator.\n */\n for (var i = 0; i <= sCmd.length; i++) {\n var ch = sCmd.charAt(i);\n if (ch == '\"' || ch == \"'\") {\n if (!chQuote) {\n chQuote = ch;\n } else if (ch == chQuote) {\n chQuote = null;\n }\n }\n else if (ch == chSep && !chQuote || !ch) {\n /*\n * Recall that substring() accepts starting (inclusive) and ending (exclusive)\n * indexes, whereas substr() accepts a starting index and a length. We need the former.\n */\n a.push(Str.trim(sCmd.substring(iPrev, i)));\n iPrev = i + 1;\n }\n }\n }\n return a;\n }\n\n /**\n * evalAND(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.AND().\n *\n * Performs the bitwise \"and\" (AND) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst & src)\n */\n evalAND(dst, src)\n {\n /*\n * We AND the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 AND 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst & src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) & ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst & src) >>> 0);\n }\n\n /**\n * evalIOR(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.IOR().\n *\n * Performs the logical \"inclusive-or\" (OR) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst | src)\n */\n evalIOR(dst, src)\n {\n /*\n * We OR the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 OR 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst | src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) | ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst | src) >>> 0);\n }\n\n /**\n * evalXOR(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.XOR().\n *\n * Performs the logical \"exclusive-or\" (XOR) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst ^ src)\n */\n evalXOR(dst, src)\n {\n /*\n * We XOR the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 XOR 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst | src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) ^ ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst ^ src) >>> 0);\n }\n\n /**\n * evalMUL(dst, src)\n *\n * I could have adapted the code from /modules/pdp10/lib/cpuops.js:PDP10.doMUL(), but it was simpler to\n * write this base method and let the PDP-10 Debugger override it with a call to the *actual* doMUL() method.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst * src)\n */\n evalMUL(dst, src)\n {\n return dst * src;\n }\n\n /**\n * truncate(v, nBits, fUnsigned)\n *\n * @this {Debugger}\n * @param {number} v\n * @param {number} [nBits]\n * @param {boolean} [fUnsigned]\n * @return {number}\n */\n truncate(v, nBits, fUnsigned)\n {\n var limit, vNew = v;\n nBits = nBits || this.nBits;\n\n if (fUnsigned) {\n if (nBits == 32) {\n vNew = v >>> 0;\n }\n else if (nBits < 32) {\n vNew = v & ((1 << nBits) - 1);\n }\n else {\n limit = Math.pow(2, nBits);\n if (v < 0 || v >= limit) {\n vNew = v % limit;\n if (vNew < 0) vNew += limit;\n }\n }\n }\n else {\n if (nBits <= 32) {\n vNew = (v << (32 - nBits)) >> (32 - nBits);\n }\n else {\n limit = Math.pow(2, nBits - 1);\n if (v >= limit) {\n vNew = (v % limit);\n if (((v / limit)|0) & 1) vNew -= limit;\n } else if (v < -limit) {\n vNew = (v % limit);\n if ((((-v - 1) / limit) | 0) & 1) {\n if (vNew) vNew += limit;\n }\n else {\n if (!vNew) vNew -= limit;\n }\n }\n }\n }\n if (v != vNew) {\n if (MAXDEBUG) this.println(\"warning: value \" + v + \" truncated to \" + vNew);\n v = vNew;\n }\n return v;\n }\n\n /**\n * evalOps(aVals, aOps, cOps)\n *\n * Some of our clients want a specific number of bits of integer precision. If that precision is\n * greater than 32, some of the operations below will fail; for example, JavaScript bitwise operators\n * always truncate the result to 32 bits, so beware when using shift operations. Similarly, it would\n * be wrong to always \"|0\" the final result, which is why we rely on truncate() now.\n *\n * Note that JavaScript integer precision is limited to 52 bits. For example, in Node, if you set a\n * variable to 0x80000001:\n *\n * foo=0x80000001|0\n *\n * then calculate foo*foo and display the result in binary using \"(foo*foo).toString(2)\":\n *\n * '11111111111111111111111111111100000000000000000000000000000000'\n *\n * which is slightly incorrect because it has overflowed JavaScript's floating-point precision.\n *\n * 0x80000001 in decimal is -2147483647, so the product is 4611686014132420609, which is 0x3FFFFFFF00000001.\n *\n * @this {Debugger}\n * @param {Array.<number>} aVals\n * @param {Array.<string>} aOps\n * @param {number} [cOps] (default is -1 for all)\n * @return {boolean} true if successful, false if error\n */\n evalOps(aVals, aOps, cOps = -1)\n {\n while (cOps-- && aOps.length) {\n var chOp = aOps.pop();\n if (aVals.length < 2) return false;\n var valNew;\n var val2 = aVals.pop();\n var val1 = aVals.pop();\n switch(chOp) {\n case '*':\n valNew = this.evalMUL(val1, val2);\n break;\n case '/':\n if (!val2) return false;\n valNew = Math.trunc(val1 / val2);\n break;\n case '^/':\n if (!val2) return false;\n valNew = val1 % val2;\n break;\n case '+':\n valNew = val1 + val2;\n break;\n case '-':\n valNew = val1 - val2;\n break;\n case '<<':\n valNew = val1 << val2;\n break;\n case '>>':\n valNew = val1 >> val2;\n break;\n case '>>>':\n valNew = val1 >>> val2;\n break;\n case '<':\n valNew = (val1 < val2? 1 : 0);\n break;\n case '<=':\n valNew = (val1 <= val2? 1 : 0);\n break;\n case '>':\n valNew = (val1 > val2? 1 : 0);\n break;\n case '>=':\n valNew = (val1 >= val2? 1 : 0);\n break;\n case '==':\n valNew = (val1 == val2? 1 : 0);\n break;\n case '!=':\n valNew = (val1 != val2? 1 : 0);\n break;\n case '&':\n valNew = this.evalAND(val1, val2);\n break;\n case '!': // alias for MACRO-10 to perform a bitwise inclusive-or (OR)\n case '|':\n valNew = this.evalIOR(val1, val2);\n break;\n case '^!': // since MACRO-10 uses '^' for base overrides, '^!' is used for bitwise exclusive-or (XOR)\n valNew = this.evalXOR(val1, val2);\n break;\n case '&&':\n valNew = (val1 && val2? 1 : 0);\n break;\n case '||':\n valNew = (val1 || val2? 1 : 0);\n break;\n case ',,':\n valNew = this.truncate(val1, 18, true) * Math.pow(2, 18) + this.truncate(val2, 18, true);\n break;\n case '_':\n case '^_':\n valNew = val1;\n /*\n * While we always try to avoid assuming any particular number of bits of precision, the 'B' shift\n * operator (which we've converted to '^_') is unique to the MACRO-10 environment, which imposes the\n * following restrictions on the shift count.\n */\n if (chOp == '^_') val2 = 35 - (val2 & 0xff);\n if (val2) {\n /*\n * Since binary shifting is a logical (not arithmetic) operation, and since shifting by division only\n * works properly with positive numbers, we call truncate() to produce an unsigned value.\n */\n valNew = this.truncate(valNew, 0, true);\n if (val2 > 0) {\n valNew *= Math.pow(2, val2);\n } else {\n valNew = Math.trunc(valNew / Math.pow(2, -val2));\n }\n }\n break;\n default:\n return false;\n }\n aVals.push(this.truncate(valNew));\n }\n return true;\n }\n\n /**\n * parseArray(asValues, iValue, iLimit, nBase, aUndefined)\n *\n * parseExpression() takes a complete expression and divides it into array elements, where even elements\n * are values (which may be empty if two or more operators appear consecutively) and odd elements are operators.\n *\n * For example, if the original expression was \"2*{3+{4/2}}\", parseExpression() would call parseArray() with:\n *\n * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14\n * - - - - - - - - - - -- -- -- -- --\n * 2 * { 3 + { 4 / 2 } }\n *\n * This function takes care of recursively processing grouped expressions, by processing subsets of the array,\n * as well as handling certain base overrides (eg, temporarily switching to base-10 for binary shift suffixes).\n *\n * @param {Array.<string>} asValues\n * @param {number} iValue\n * @param {number} iLimit\n * @param {number} nBase\n * @param {Array|undefined} [aUndefined]\n * @return {number|undefined}\n */\n parseArray(asValues, iValue, iLimit, nBase, aUndefined)\n {\n var value;\n var sValue, sOp;\n var fError = false;\n var nUnary = 0;\n var aVals = [], aOps = [];\n\n var nBasePrev = this.nBase;\n this.nBase = nBase;\n\n while (iValue < iLimit) {\n var v;\n sValue = asValues[iValue++].trim();\n sOp = (iValue < iLimit? asValues[iValue++] : \"\");\n\n if (sValue) {\n v = this.parseValue(sValue, null, aUndefined, nUnary);\n } else {\n if (sOp == '{') {\n var cOpen = 1;\n var iStart = iValue;\n while (iValue < iLimit) {\n sValue = asValues[iValue++].trim();\n sOp = (iValue < asValues.length? asValues[iValue++] : \"\");\n if (sOp == '{') {\n cOpen++;\n } else if (sOp == '}') {\n if (!--cOpen) break;\n }\n }\n v = this.parseArray(asValues, iStart, iValue-1, this.nBase, aUndefined);\n if (v != null && nUnary) {\n v = this.parseUnary(v, nUnary);\n }\n sValue = (iValue < iLimit? asValues[iValue++].trim() : \"\");\n sOp = (iValue < iLimit? asValues[iValue++] : \"\");\n }\n else {\n /*\n * When parseExpression() calls us, it has collapsed all runs of whitespace into single spaces,\n * and although it allows single spaces to divide the elements of the expression, a space is neither\n * a unary nor binary operator. It's essentially a no-op. If we encounter it here, then it followed\n * another operator and is easily ignored (although perhaps it should still trigger a reset of nBase\n * and nUnary -- TBD).\n */\n if (sOp == ' ') {\n continue;\n }\n if (sOp == '^B') {\n this.nBase = 2;\n continue;\n }\n if (sOp == '^O') {\n this.nBase = 8;\n continue;\n }\n if (sOp == '^D') {\n this.nBase = 10;\n continue;\n }\n if (!(nUnary & (0xC0000000|0))) {\n if (sOp == '+') {\n continue;\n }\n if (sOp == '-') {\n nUnary = (nUnary << 2) | 1;\n continue;\n }\n if (sOp == '~' || sOp == '^-') {\n nUnary = (nUnary << 2) | 2;\n continue;\n }\n if (sOp == '^L') {\n nUnary = (nUnary << 2) | 3;\n continue;\n }\n }\n fError = true;\n break;\n }\n }\n\n if (v === undefined) {\n if (aUndefined) {\n aUndefined.push(sValue);\n v = 0;\n } else {\n fError = true;\n aUndefined = [];\n break;\n }\n }\n\n aVals.push(this.truncate(v));\n\n /*\n * When parseExpression() calls us, it has collapsed all runs of whitespace into single spaces,\n * and although it allows single spaces to divide the elements of the expression, a space is neither\n * a unary nor binary operator. It's essentially a no-op. If we encounter it here, then it followed\n * a value, and since we don't want to misinterpret the next operator as a unary operator, we look\n * ahead and grab the next operator if it's not preceded by a value.\n */\n if (sOp == ' ') {\n if (iValue < asValues.length - 1 && !asValues[iValue]) {\n iValue++;\n sOp = asValues[iValue++]\n } else {\n fError = true;\n break;\n }\n }\n\n if (!sOp) break;\n\n var aBinOp = (this.achGroup[0] == '<'? Debugger.aDECOpPrecedence : Debugger.aBinOpPrecedence);\n if (!aBinOp[sOp]) {\n fError = true;\n break;\n }\n if (aOps.length && aBinOp[sOp] <= aBinOp[aOps[aOps.length - 1]]) {\n this.evalOps(aVals, aOps, 1);\n }\n aOps.push(sOp);\n\n /*\n * The MACRO-10 binary shifting operator assumes a base-10 shift count, regardless of the current\n * base, so we must override the current base to ensure the count is parsed correctly.\n */\n this.nBase = (sOp == '^_')? 10 : nBase;\n nUnary = 0;\n }\n\n if (fError || !this.evalOps(aVals, aOps) || aVals.length != 1) {\n fError = true;\n }\n\n if (!fError) {\n value = aVals.pop();\n\n } else if (!aUndefined) {\n this.println(\"parse error (\" + (sValue || sOp) + \")\");\n }\n\n this.nBase = nBasePrev;\n return value;\n }\n\n /**\n * parseASCII(sExp, chDelim, nBits, cchMax)\n *\n * @this {Debugger}\n * @param {string} sExp\n * @param {string} chDelim\n * @param {number} nBits\n * @param {number} cchMax\n * @return {string|undefined}\n */\n parseASCII(sExp, chDelim, nBits, cchMax)\n {\n var i;\n while ((i = sExp.indexOf(chDelim)) >= 0) {\n var v = 0;\n var j = i + 1;\n var cch = cchMax;\n while (j < sExp.length) {\n var ch = sExp[j++];\n if (ch == chDelim) {\n cch = -1;\n break;\n }\n if (!cch) break;\n cch--;\n var c = ch.charCodeAt(0);\n if (nBits == 7) {\n c &= 0x7F;\n } else {\n c = (c - 0x20) & 0x3F;\n }\n v = this.truncate(v * Math.pow(2, nBits) + c, nBits * cchMax, true);\n }\n if (cch >= 0) {\n this.println(\"parse error (\" + chDelim + sExp + chDelim + \")\");\n return undefined;\n } else {\n sExp = sExp.substr(0, i) + this.toStrBase(v, -1) + sExp.substr(j);\n }\n }\n return sExp;\n }\n\n /**\n * parseExpression(sExp, fQuiet)\n *\n * A quick-and-dirty expression parser. It takes an expression like:\n *\n * EDX+EDX*4+12345678\n *\n * and builds a value stack in aVals and a \"binop\" (binary operator) stack in aOps:\n *\n * aVals aOps\n * ----- ----\n * EDX +\n * EDX *\n * 4 +\n * ...\n *\n * We pop 1 \"binop\" from aOps and 2 values from aVals whenever a \"binop\" of lower priority than its\n * predecessor is encountered, evaluate, and push the result back onto aVals. Only selected unary\n * operators are supported (eg, negate and complement); no ternary operators like '?:' are supported.\n *\n * fQuiet can be used to pass an array that collects any undefined variables that parseExpression()\n * encounters; the value of an undefined variable is zero. This mode was added for components that need\n * to support expressions containing \"fixups\" (ie, values that must be determined later).\n *\n * @this {Debugger}\n * @param {string|undefined} sExp\n * @param {Array|undefined|boolean} [fQuiet]\n * @return {number|undefined} numeric value, or undefined if sExp contains any undefined or invalid values\n */\n parseExpression(sExp, fQuiet)\n {\n var value = undefined;\n var fPrint = (fQuiet === false);\n var aUndefined = Array.isArray(fQuiet)? fQuiet : undefined;\n\n if (sExp) {\n\n /*\n * The default delimiting characters for grouped expressions are braces; they can be changed by altering\n * achGroup, but when that happens, instead of changing our regular expressions and operator tables,\n * we simply replace all achGroup characters with braces in the given expression.\n *\n * Why not use parentheses for grouped expressions? Because some debuggers use parseReference() to perform\n * parenthetical value replacements in message strings, and they don't want parentheses taking on a different\n * meaning. And for some machines, like the PDP-10, the convention is to use parentheses for other things,\n * like indexed addressing, and to use angle brackets for grouped expressions.\n */\n if (this.achGroup[0] != '{') {\n sExp = sExp.split(this.achGroup[0]).join('{').split(this.achGroup[1]).join('}');\n }\n\n /*\n * Quoted ASCII characters can have a numeric value, too, which must be converted now, to avoid any\n * conflicts with the operators below.\n */\n sExp = this.parseASCII(sExp, '\"', 7, 5); // MACRO-10 packs up to 5 7-bit ASCII codes into a value\n if (!sExp) return value;\n sExp = this.parseASCII(sExp, \"'\", 6, 6); // MACRO-10 packs up to 6 6-bit ASCII (SIXBIT) codes into a value\n if (!sExp) return value;\n\n /*\n * All browsers (including, I believe, IE9 and up) support the following idiosyncrasy of a RegExp split():\n * when the RegExp uses a capturing pattern, the resulting array will include entries for all the pattern\n * matches along with the non-matches. This effectively means that, in the set of expressions that we\n * support, all even entries in asValues will contain \"values\" and all odd entries will contain \"operators\".\n *\n * Although I started listing the operators in the RegExp in \"precedential\" order, that's not important;\n * what IS important is listing operators than contain shorter operators first. For example, bitwise\n * shift operators must be listed BEFORE the logical less-than or greater-than operators. The aBinOp tables\n * (aBinOpPrecedence and aDECOpPrecedence) are what determine precedence, not the RegExp.\n *\n * Also, to better accommodate MACRO-10 syntax, I've replaced the single '^' for XOR with '^!', and I've\n * added '!' as an alias for '|' (bitwise inclusive-or), '^-' as an alias for '~' (one's complement operator),\n * and '_' as a shift operator (+/- values specify a left/right shift, and the count is not limited to 32).\n *\n * And to avoid conflicts with MACRO-10 syntax, I've replaced the original mod operator ('%') with '^/'.\n *\n * The MACRO-10 binary shifting suffix ('B') is a bit more problematic, since a capital B can also appear\n * inside symbols, or inside hex values. So if the default base is NOT 16, then I pre-scan for that suffix\n * and replace all non-symbolic occurrences with an internal shift operator ('^_').\n *\n * Note that Str.parseInt(), which parseValue() relies on, supports both the MACRO-10 base prefix overrides\n * and the binary shifting suffix ('B'), but since that suffix can also be a bracketed expression, we have to\n * support it here as well.\n *\n * MACRO-10 supports only a subset of all the PCjs operators; for example, MACRO-10 doesn't support any of\n * the boolean logical/compare operators. But unless we run into conflicts, I prefer sticking with this\n * common set of operators.\n *\n * All whitespace in the expression is collapsed to single spaces, and space has been added to the list\n * of \"operators\", but its sole function is as a separator, not as an operator. parseArray() will ignore\n * single spaces as long as they are preceded and/or followed by a \"real\" operator. It would be dangerous\n * to remove spaces entirely, because if an operator-less expression like \"A B\" was passed in, we would want\n * that to generate an error; if we converted it to \"AB\", evaluation might inadvertently succeed.\n */\n var regExp = /({|}|\\|\\||&&|\\||\\^!|\\^B|\\^O|\\^D|\\^L|\\^-|~|\\^_|_|&|!=|!|==|>=|>>>|>>|>|<=|<<|<|-|\\+|\\^\\/|\\/|\\*|,,| )/;\n if (this.nBase != 16) {\n sExp = sExp.replace(/(^|[^A-Z0-9$%.])([0-9]+)B/, \"$1$2^_\").replace(/\\s+/g, ' ');\n }\n var asValues = sExp.split(regExp);\n value = this.parseArray(asValues, 0, asValues.length, this.nBase, aUndefined);\n if (value !== undefined && fPrint) {\n this.printValue(null, value);\n }\n }\n return value;\n }\n\n /**\n * parseReference(s)\n *\n * Returns the given string with any \"{expression}\" sequences replaced with the value of the expression,\n * and any \"[address]\" references replaced with the contents of the address. Expressions are parsed BEFORE\n * addresses.\n *\n * @this {Debugger}\n * @param {string} s\n * @return {string|undefined}\n */\n parseReference(s)\n {\n var a;\n var chOpen = this.achGroup[0];\n var chClose = this.achGroup[1];\n var chEscape = (chOpen == '(' || chOpen == '{' || chOpen == '[')? '\\\\' : '';\n var chInnerEscape = (chOpen == '['? '\\\\' : '');\n var reSubExp = new RegExp(chEscape + chOpen + \"([^\" + chInnerEscape + chOpen + chInnerEscape + chClose + \"]+)\" + chEscape + chClose);\n while (a = s.match(reSubExp)) {\n var value = this.parseExpression(a[1]);\n if (value === undefined) return undefined;\n var sSearch = chOpen + a[1] + chClose;\n var sReplace = value != null? this.toStrBase(value) : \"undefined\";\n /*\n * Note that by default, the String replace() method only replaces the FIRST occurrence,\n * and there MIGHT be more than one occurrence of the expression we just parsed, so we could\n * do this instead:\n *\n * s = s.split(sSearch).join(sReplace);\n *\n * However, that's knd of an expensive (slow) solution, and it's not strictly necessary, since\n * any additional identical expressions will be picked up on a subsequent iteration through this loop.\n */\n s = s.replace(sSearch, sReplace);\n }\n if (this.achAddress.length) {\n chOpen = this.achAddress[0];\n chClose = this.achAddress[1];\n chEscape = (chOpen == '(' || chOpen == '{' || chOpen == '[')? '\\\\' : '';\n chInnerEscape = (chOpen == '['? '\\\\' : '');\n reSubExp = new RegExp(chEscape + chOpen + \"([^\" + chInnerEscape + chOpen + chInnerEscape + chClose + \"]+)\" + chEscape + chClose);\n while (a = s.match(reSubExp)) {\n s = this.parseAddrReference(s, a[1]);\n }\n }\n return this.parseSysVars(s);\n }\n\n /**\n * parseSysVars(s)\n *\n * Returns the given string with any recognized \"$var\" replaced with its value; eg:\n *\n * $ops: the number of opcodes executed since the last time it was displayed (or reset)\n *\n * @this {Debugger}\n * @param {string} s\n * @return {string}\n */\n parseSysVars(s)\n {\n var a;\n while (a = s.match(/\\$([a-z]+)/i)) {\n var v = null;\n switch(a[1].toLowerCase()) {\n case \"ops\":\n v = this.cOpcodes - this.cOpcodesStart;\n break;\n }\n if (v == null) break;\n s = s.replace(a[0], v.toString());\n }\n return s;\n }\n\n /**\n * parseUnary(value, nUnary)\n *\n * nUnary is actually a small \"stack\" of unary operations encoded in successive pairs of bits.\n * As parseExpression() encounters each unary operator, nUnary is shifted left 2 bits, and the\n * new unary operator is encoded in bits 0 and 1 (0b00 is none, 0b01 is negate, 0b10 is complement,\n * and 0b11 is reserved). Here, we process the bits in reverse order (hence the stack-like nature),\n * ensuring that we process the unary operators associated with this value right-to-left.\n *\n * Since bitwise operators see only 32 bits, more than 16 unary operators cannot be supported\n * using this method. We'll let parseExpression() worry about that; if it ever happens in practice,\n * then we'll have to switch to a more \"expensive\" approach (eg, an actual array of unary operators).\n *\n * @this {Debugger}\n * @param {number} value\n * @param {number} nUnary\n * @return {number}\n */\n parseUnary(value, nUnary)\n {\n while (nUnary) {\n switch(nUnary & 0o3) {\n case 1:\n value = -this.truncate(value);\n break;\n case 2:\n value = this.evalXOR(value, -1); // this is easier than adding an evalNOT()...\n break;\n case 3:\n var bit = 35; // simple left-to-right zero-bit-counting loop...\n while (bit >= 0 && !this.evalAND(value, Math.pow(2, bit))) bit--;\n value = 35 - bit;\n break;\n }\n nUnary >>>= 2;\n }\n return value;\n }\n\n /**\n * parseValue(sValue, sName, fQuiet, nUnary)\n *\n * @this {Debugger}\n * @param {string|undefined} sValue\n * @param {string|null} [sName] is the name of the value, if any\n * @param {Array|undefined|boolean} [fQuiet]\n * @param {number} [nUnary] (0 for none, 1 for negate, 2 for complement, 3 for leading zeros)\n * @return {number|undefined} numeric value, or undefined if sValue is either undefined or invalid\n */\n parseValue(sValue, sName, fQuiet, nUnary = 0)\n {\n var value;\n var aUndefined = Array.isArray(fQuiet)? fQuiet : undefined;\n\n if (sValue != null) {\n var iReg = this.getRegIndex(sValue);\n if (iReg >= 0) {\n value = this.getRegValue(iReg);\n } else {\n value = this.getVariable(sValue);\n if (value != null) {\n var sUndefined = this.getVariableFixup(sValue);\n if (sUndefined) {\n if (aUndefined) {\n aUndefined.push(sUndefined);\n } else {\n var valueUndefined = this.parseExpression(sUndefined, fQuiet);\n if (valueUndefined !== undefined) {\n value += valueUndefined;\n } else {\n if (!fQuiet) {\n this.println(\"undefined \" + (sName || \"value\") + \": \" + sValue + \" (\" + sUndefined + \")\");\n }\n value = undefined;\n }\n }\n }\n } else {\n /*\n * A feature of MACRO-10 is that any single-digit number is automatically interpreted as base-10.\n */\n value = Str.parseInt(sValue, sValue.length > 1 || this.nBase > 10? this.nBase : 10);\n }\n }\n if (value != null) {\n value = this.truncate(this.parseUnary(value, nUnary));\n } else {\n if (!fQuiet) {\n this.println(\"invalid \" + (sName || \"value\") + \": \" + sValue);\n }\n }\n } else {\n if (!fQuiet) {\n this.println(\"missing \" + (sName || \"value\"));\n }\n }\n return value;\n }\n\n /**\n * printValue(sVar, value)\n *\n * @this {Debugger}\n * @param {string|null} sVar\n * @param {number|undefined} value\n * @return {boolean} true if value defined, false if not\n */\n printValue(sVar, value)\n {\n var sValue;\n var fDefined = false;\n if (value !== undefined) {\n fDefined = true;\n if (this.nBase == 8) {\n sValue = this.toStrBase(value, this.nBits, 8, 1) + \" \" + value + '.';\n } else {\n sValue = this.toStrBase(value, this.nBits, 16, 1) + \" \" + this.toStrBase(value, this.nBits, 8, 1) + \" \" + this.toStrBase(value, this.nBits, 2, this.nBits <= 32? 8 : 6) + \" \" + value + '.';\n }\n if (value >= 0x20 && value < 0x7F) {\n sValue += \" '\" + String.fromCharCode(value) + \"'\";\n }\n }\n sVar = (sVar != null? (sVar + \": \") : \"\");\n this.println(sVar + sValue);\n return fDefined;\n }\n\n /**\n * resetVariables()\n *\n * @this {Debugger}\n * @return {Object}\n */\n resetVariables()\n {\n var a = this.aVariables;\n this.aVariables = {};\n return a;\n }\n\n /**\n * restoreVariables(a)\n *\n * @this {Debugger}\n * @param {Object} a (from previous resetVariables() call)\n */\n restoreVariables(a)\n {\n this.aVariables = a;\n }\n\n /**\n * printVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} [sVar]\n * @return {boolean} true if all value(s) defined, false if not\n */\n printVariable(sVar)\n {\n var cVariables = 0;\n if (this.aVariables) {\n if (sVar) {\n return this.printValue(sVar, this.aVariables[sVar] && this.aVariables[sVar].value);\n }\n var aVars = Object.keys(this.aVariables);\n aVars.sort();\n for (var i = 0; i < aVars.length; i++) {\n this.printValue(aVars[i], this.aVariables[aVars[i]].value);\n cVariables++;\n }\n }\n return cVariables > 0;\n }\n\n /**\n * delVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n */\n delVariable(sVar)\n {\n delete this.aVariables[sVar];\n }\n\n /**\n * getVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {number|undefined}\n */\n getVariable(sVar)\n {\n if (this.aVariables[sVar]) {\n return this.aVariables[sVar].value;\n }\n sVar = sVar.substr(0, 6);\n return this.aVariables[sVar] && this.aVariables[sVar].value;\n }\n\n /**\n * getVariableFixup(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {string|undefined}\n */\n getVariableFixup(sVar)\n {\n return this.aVariables[sVar] && this.aVariables[sVar].sUndefined;\n }\n\n /**\n * isVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {boolean}\n */\n isVariable(sVar)\n {\n return this.aVariables[sVar] !== undefined;\n }\n\n /**\n * setVariable(sVar, value, sUndefined)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @param {number} value\n * @param {string|undefined} [sUndefined]\n */\n setVariable(sVar, value, sUndefined)\n {\n this.aVariables[sVar] = {value, sUndefined};\n }\n\n /**\n * toStrBase(n, nBits, nBase, nGrouping)\n *\n * Use this instead of Str's toOct()/toDec()/toHex() to convert numbers to the Debugger's default base.\n *\n * @this {Debugger}\n * @param {number|null|undefined} n\n * @param {number} [nBits] (-1 to strip leading zeros, 0 to allow a variable number of digits)\n * @param {number} [nBase]\n * @param {number} [nGrouping] (if nBase is 2, this is a grouping; otherwise, it's a prefix condition)\n * @return {string}\n */\n toStrBase(n, nBits = 0, nBase = 0, nGrouping = 0)\n {\n var s;\n switch(nBase || this.nBase) {\n case 2:\n s = Str.toBin(n, nBits > 0? nBits : 0, nGrouping);\n break;\n case 8:\n s = Str.toOct(n, nBits > 0? ((nBits + 2)/3)|0 : 0, !!nGrouping);\n break;\n case 10:\n /*\n * The multiplier is actually Math.log(2)/Math.log(10), but an approximation is more than adequate.\n */\n s = Str.toDec(n, nBits > 0? Math.ceil(nBits * 0.3) : 0);\n break;\n case 16:\n default:\n s = Str.toHex(n, nBits > 0? ((nBits + 3) >> 2) : 0, !!nGrouping);\n break;\n }\n return (nBits < 0? Str.stripLeadingZeros(s) : s);\n }\n}\n\nif (DEBUGGER) {\n\n /*\n * These are our operator precedence tables. Operators toward the bottom (with higher values) have\n * higher precedence. aBinOpPrecedence was our original table; we had to add aDECOpPrecedence because\n * the precedence of operators in DEC's MACRO-10 expressions differ. Having separate tables also allows\n * us to remove operators that shouldn't be supported, but unless some operator creates a problem,\n * I prefer to keep as much commonality between the tables as possible.\n *\n * Missing from these tables are the (limited) set of unary operators we support (negate and complement),\n * since this is only a BINARY operator precedence, not a general-purpose precedence table. Assume that\n * all unary operators take precedence over all binary operators.\n */\n Debugger.aBinOpPrecedence = {\n '||': 5, // logical OR\n '&&': 6, // logical AND\n '!': 7, // bitwise OR (conflicts with logical NOT, but we never supported that)\n '|': 7, // bitwise OR\n '^!': 8, // bitwise XOR (added by MACRO-10 sometime between the 1972 and 1978 versions)\n '&': 9, // bitwise AND\n '!=': 10, // inequality\n '==': 10, // equality\n '>=': 11, // greater than or equal to\n '>': 11, // greater than\n '<=': 11, // less than or equal to\n '<': 11, // less than\n '>>>': 12, // unsigned bitwise right shift\n '>>': 12, // bitwise right shift\n '<<': 12, // bitwise left shift\n '-': 13, // subtraction\n '+': 13, // addition\n '^/': 14, // remainder\n '/': 14, // division\n '*': 14, // multiplication\n '_': 19, // MACRO-10 shift operator\n '^_': 19, // MACRO-10 internal shift operator (converted from 'B' suffix form that MACRO-10 uses)\n '{': 20, // open grouped expression (converted from achGroup[0])\n '}': 20 // close grouped expression (converted from achGroup[1])\n };\n Debugger.aDECOpPrecedence = {\n ',,': 1, // high-word,,low-word\n '||': 5, // logical OR\n '&&': 6, // logical AND\n '!=': 10, // inequality\n '==': 10, // equality\n '>=': 11, // greater than or equal to\n '>': 11, // greater than\n '<=': 11, // less than or equal to\n '<': 11, // less than\n '>>>': 12, // unsigned bitwise right shift\n '>>': 12, // bitwise right shift\n '<<': 12, // bitwise left shift\n '-': 13, // subtraction\n '+': 13, // addition\n '^/': 14, // remainder\n '/': 14, // division\n '*': 14, // multiplication\n '!': 15, // bitwise OR (conflicts with logical NOT, but we never supported that)\n '|': 15, // bitwise OR\n '^!': 15, // bitwise XOR (added by MACRO-10 sometime between the 1972 and 1978 versions)\n '&': 15, // bitwise AND\n '_': 19, // MACRO-10 shift operator\n '^_': 19, // MACRO-10 internal shift operator (converted from 'B' suffix form that MACRO-10 uses)\n '{': 20, // open grouped expression (converted from achGroup[0])\n '}': 20 // close grouped expression (converted from achGroup[1])\n };\n\n /*\n * Assorted constants\n */\n Debugger.TWO_POW32 = Math.pow(2, 32);\n\n} // endif DEBUGGER\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/debugger.js (C) Jeff Parsons 2012-2018\n */\n\nif (DEBUGGER) {\n}\n\n/**\n * Debugger Address Object\n *\n * off offset, if any\n * sel selector, if any (if null, addr should be set to a linear address)\n * addr linear address, if any (if null, addr will be recomputed from sel:off)\n * type one of the DebuggerX86.ADDRTYPE values\n * fData32 true if 32-bit operand size in effect\n * fAddr32 true if 32-bit address size in effect\n * fData32Orig original fData32 value, if any\n * fAddr32Orig original fAddr32 value, if any\n * cOverrides non-zero if any overrides were processed with this address\n * fComplete true if a complete instruction was processed with this address\n * fTempBreak true if this is a temporary breakpoint address\n * sCmd set for breakpoint addresses if there's an associated command string\n * aCmds preprocessed commands (from sCmd)\n *\n * @typedef {{\n * off:(number|null|undefined),\n * sel:(number|null|undefined),\n * addr:(number|null|undefined),\n * type:(number|undefined),\n * fData32:(boolean|undefined),\n * fAddr32:(boolean|undefined),\n * fData32Orig:(boolean|undefined),\n * fAddr32Orig:(boolean|undefined),\n * cOverrides:(number|undefined),\n * fComplete:(boolean|undefined),\n * fTempBreak:(boolean|undefined),\n * sCmd:(string|undefined),\n * aCmds:(Array.<string>|undefined)\n * }} DbgAddrX86\n */\nvar DbgAddrX86;\n\n/*\n * Debugger Breakpoint Tips\n *\n * Here's an example of our powerful new breakpoint command capabilities:\n *\n * bp 0397:022B \"?'GlobalAlloc(wFlags:[ss:sp+8],dwBytes:[ss:sp+6][ss:sp+4])';g [ss:sp+2]:[ss:sp] '?ax;if ax'\"\n *\n * The above breakpoint will display a pleasing \"GlobalAlloc()\" string containing the current\n * stack parameters, and will briefly stop execution on the return to print the result in AX,\n * halting the CPU whenever AX is zero (the default behavior of \"if\" whenever the expression is\n * false is to look for an \"else\" and automatically halt when there is no \"else\").\n *\n * How do you figure out where the code for GlobalAlloc is in the first place? You need to have\n * BACKTRACK support enabled (which currently means running the non-COMPILED version), so that as\n * the Disk component loads disk images, it will automatically extract symbolic information from all\n * \"NE\" (New Executable) binaries on those disks, which the Debugger's \"dt\" command can then search\n * for you; eg:\n *\n * ## dt globalalloc\n * GLOBALALLOC: KRNL386.EXE 0001:022B len 0xC570\n *\n * And then you just need to do a bit more sleuthing to find the right CODE segment. And that just\n * got easier, now that the PCx86 Debugger mimics portions of the Windows Debugger INT 0x41 interface;\n * see intWindowsDebugger() for details. So even if you neglect to run WDEB386.EXE /E inside the\n * machine before running Windows, you should still see notifications like:\n *\n * KERNEL!undefined code(0001)=#0397 len 0000C580\n *\n * in the PCx86 Debugger output window, as segments are being loaded by the Windows kernel.\n */\n\n/**\n * class DebuggerX86\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass DebuggerX86 extends Debugger {\n /**\n * DebuggerX86(parmsDbg)\n *\n * The DebuggerX86 component is an optional component that implements a variety of user commands\n * for controlling the CPU, dumping and editing memory, etc.\n *\n * DebuggerX86 extends the shared Debugger component and supports the following optional (parmsDbg)\n * properties:\n *\n * commands: string containing zero or more commands, separated by ';'\n *\n * messages: string containing zero or more message categories to enable;\n * multiple categories must be separated by '|' or ';'. Parsed by messageInit().\n *\n * @this {DebuggerX86}\n * @param {Object} parmsDbg\n */\n constructor(parmsDbg)\n {\n if (DEBUGGER) {\n\n super(parmsDbg);\n\n /*\n * Default number of hex chars in a register and a linear address (ie, for real-mode);\n * updated by initBus().\n */\n this.cchReg = 4;\n this.cchAddr = 5;\n this.maskAddr = 0xfffff;\n\n /*\n * Most commands that require an address call parseAddr(), which defaults to dbgAddrNextCode\n * or dbgAddrNextData when no address has been given. doDump() and doUnassemble(), in turn,\n * update dbgAddrNextData and dbgAddrNextCode, respectively, when they're done.\n *\n * All dbgAddr variables contain properties off, sel, and addr, where sel:off represents the\n * segmented address and addr is the corresponding linear address (if known). For certain\n * segmented addresses (eg, breakpoint addresses), we pre-compute the linear address and save\n * that in addr, so that the breakpoint will still operate as intended even if the mode changes\n * later (eg, from real-mode to protected-mode).\n *\n * Finally, for TEMPORARY breakpoint addresses, we set fTempBreak to true, so that they can be\n * automatically cleared when they're hit.\n */\n this.dbgAddrNextCode = this.newAddr(0, 0);\n this.dbgAddrNextData = this.newAddr(0, 0);\n this.dbgAddrAssemble = this.newAddr(0, 0);\n\n /*\n * aSymbolTable is an array of SymbolTable objects, one per ROM or other chunk of address space,\n * where each object contains the following properties:\n *\n * sModule\n * nSegment\n * sel\n * off\n * addr (physical address, if any; eg, symbols for a ROM)\n * len\n * aSymbols\n * aOffsets\n *\n * See addSymbols() for more details, since that's how callers add sets of symbols to the table.\n */\n this.aSymbolTable = [];\n\n /*\n * clearBreakpoints() initializes the breakpoints lists: aBreakExec is a list of addresses\n * to halt on whenever attempting to execute an instruction at the corresponding address,\n * and aBreakRead and aBreakWrite are lists of addresses to halt on whenever a read or write,\n * respectively, occurs at the corresponding address.\n *\n * NOTE: Curiously, after upgrading the Google Closure Compiler from v20141215 to v20150609,\n * the resulting compiled code would crash in clearBreakpoints(), because the (renamed) aBreakRead\n * property was already defined. To eliminate whatever was confusing the Closure Compiler, I've\n * explicitly initialized all the properties that clearBreakpoints() (re)initializes.\n */\n this.aBreakExec = this.aBreakRead = this.aBreakWrite = [];\n this.clearBreakpoints();\n\n /*\n * The new \"bn\" command allows you to specify a number of instructions to execute and then stop;\n * \"bn 0\" disables any outstanding count.\n */\n this.nBreakIns = 0;\n\n /*\n * Execution history is allocated by historyInit() whenever checksEnabled() conditions change.\n * Execution history is updated whenever the CPU calls checkInstruction(), which will happen\n * only when checksEnabled() returns true (eg, whenever one or more breakpoints have been set).\n * This ensures that, by default, the CPU runs as fast as possible.\n */\n this.historyInit();\n\n /*\n * Initialize Debugger message and command support\n */\n this.afnDumpers = {};\n this.messageInit(parmsDbg['messages']);\n this.sCommandsInit = parmsDbg['commands'];\n\n /*\n * Make it easier to access Debugger commands from an external REPL, like the WebStorm \"live\" console\n * window; eg:\n *\n * pcx86('r')\n * pcx86('dw 0:0')\n * pcx86('h')\n * ...\n */\n var dbg = this;\n if (window) {\n if (window[PCX86.APPCLASS] === undefined) {\n window[PCX86.APPCLASS] = function(s) { return dbg.doCommands(s); };\n }\n } else {\n if (global[PCX86.APPCLASS] === undefined) {\n global[PCX86.APPCLASS] = function(s) { return dbg.doCommands(s); };\n }\n }\n\n } // endif DEBUGGER\n }\n\n /**\n * initBus(bus, cpu, dbg)\n *\n * @this {DebuggerX86}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.cmp = cmp;\n this.fdc = cmp.getMachineComponent(\"FDC\");\n this.hdc = cmp.getMachineComponent(\"HDC\");\n this.fpu = cmp.getMachineComponent(\"FPU\");\n this.mouse = cmp.getMachineComponent(\"Mouse\");\n if (MAXDEBUG) this.chipset = cmp.getMachineComponent(\"ChipSet\");\n\n /*\n * Re-initialize Debugger message and command support as needed\n */\n var sMessages = cmp.getMachineParm('messages');\n if (sMessages) this.messageInit(sMessages);\n this.sCommandsInit = cmp.getMachineParm('commands') || this.sCommandsInit;\n\n this.cchAddr = bus.getWidth() >> 2;\n this.maskAddr = bus.nBusLimit;\n\n /*\n * Allocate a special segment \"register\", for use whenever a requested selector is not currently loaded\n */\n this.segDebugger = new SegX86(this.cpu, SegX86.ID.DBG, \"DBG\");\n\n this.aaOpDescs = DebuggerX86.aaOpDescs;\n if (this.cpu.model >= X86.MODEL_80186) {\n this.aaOpDescs = DebuggerX86.aaOpDescs.slice();\n this.aaOpDescs[0x0F] = DebuggerX86.aOpDescUndefined;\n if (this.cpu.model >= X86.MODEL_80286) {\n /*\n * TODO: Consider whether the aOpDesc0F table should be split in two: one for 80286-only instructions,\n * and one for both 80286 and 80386. For now, the Debugger is not as strict as the CPUX86 is about\n * the instructions it supports for each type of CPU, in part because an 80286 machine could still be\n * presented with 80386-only code that is simply \"skipped over\" when then CPU doesn't support it.\n *\n * Obviously I'm not being entirely consistent, since I don't disassemble *any* 0x0F opcodes for any\n * pre-80286 CPUs. But at least I'm being up front about it.\n */\n this.aaOpDescs[0x0F] = DebuggerX86.aOpDesc0F;\n if (I386 && this.cpu.model >= X86.MODEL_80386) this.cchReg = 8;\n }\n }\n\n this.messageDump(Messages.BUS, function onDumpBus(asArgs) { dbg.dumpBus(asArgs); });\n this.messageDump(Messages.DESC, function onDumpSel(asArgs) { dbg.dumpSel(asArgs); });\n this.messageDump(Messages.DOS, function onDumpDOS(asArgs) { dbg.dumpDOS(asArgs); });\n this.messageDump(Messages.MEM, function onDumpMem(asArgs) { dbg.dumpMem(asArgs); });\n this.messageDump(Messages.TSS, function onDumpTSS(asArgs) { dbg.dumpTSS(asArgs); });\n\n if (Interrupts.WINDBG.ENABLED || Interrupts.WINDBGRM.ENABLED) {\n this.fWinDbg = null;\n this.cTrapFaults = 0;\n this.fIgnoreNextCheckFault = false;\n this.cpu.addIntNotify(Interrupts.WINCB.VECTOR, this.intWindowsCallBack.bind(this));\n this.cpu.addIntNotify(Interrupts.WINDBG.VECTOR, this.intWindowsDebugger.bind(this));\n }\n if (Interrupts.WINDBGRM.ENABLED) {\n this.fWinDbgRM = null;\n this.cpu.addIntNotify(Interrupts.WINDBGRM.VECTOR, this.intWindowsDebuggerRM.bind(this));\n }\n\n this.setReady();\n }\n\n /**\n * addSegmentInfo(dbgAddr, nSegment, sel, fCode, fPrint)\n *\n * CONDITIONAL: if (Interrupts.WINDBG.ENABLED || Interrupts.WINDBGRM.ENABLED)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr (address of module name)\n * @param {number} nSegment (logical segment number)\n * @param {number} sel (current selector)\n * @param {boolean} fCode (true if code segment, false if data segment)\n * @param {boolean} [fPrint] (false means we're merely monitoring, so let WDEB386 print its own notifications)\n */\n addSegmentInfo(dbgAddr, nSegment, sel, fCode, fPrint)\n {\n var sModule = this.getSZ(dbgAddr);\n var seg = this.getSegment(sel);\n var len = seg? seg.limit + 1 : 0;\n var sSection = (fCode? \"_CODE\" : \"_DATA\") + Str.toHex(nSegment, 2);\n if (fPrint && this.messageEnabled(Messages.MEM)) {\n this.message(sModule + ' ' + (fCode? \"code\" : \"data\") + '(' + Str.toHex(nSegment, 4) + \")=#\" + Str.toHex(sel, 4) + \" len \" + Str.toHex(len));\n }\n var off = 0;\n var aSymbols = this.findModuleInfo(sModule, nSegment);\n aSymbols[sModule + sSection] = off;\n this.addSymbols(sModule, nSegment, sel, off, null, len, aSymbols);\n }\n\n /**\n * removeSegmentInfo(sel, fPrint)\n *\n * CONDITIONAL: if (Interrupts.WINDBG.ENABLED || Interrupts.WINDBGRM.ENABLED)\n *\n * @this {DebuggerX86}\n * @param {number} sel\n * @param {boolean} [fPrint] (false means we're merely monitoring OR we don't really care about these notifications)\n */\n removeSegmentInfo(sel, fPrint)\n {\n var sModuleRemoved = this.removeSymbols(null, sel);\n if (fPrint && this.messageEnabled(Messages.MEM)) {\n if (sModuleRemoved) {\n this.message(sModuleRemoved + \" #\" + Str.toHex(sel, 4) + \" removed\");\n } else {\n this.message(\"unable to remove module for segment #\" + Str.toHex(sel, 4));\n }\n }\n }\n\n /**\n * addSectionInfo(dbgAddr, fCode, fPrint)\n *\n * CONDITIONAL: if (Interrupts.WINDBG.ENABLED || Interrupts.WINDBGRM.ENABLED)\n *\n * dbgAddr -> D386_Device_Params structure:\n * DD_logical_seg dw ? ; logical segment # from map\n * DD_actual_sel dw ? ; actual selector value\n * DD_base dd ? ; linear address offset for start of segment\n * DD_length dd ? ; actual length of segment\n * DD_name df ? ; 16:32 ptr to null terminated module name\n * DD_sym_name df ? ; 16:32 ptr to null terminated parent name (eg, \"DOS386\")\n * DD_alias_sel dw ? ; alias selector value (0 = none)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr (address of D386_Device_Params)\n * @param {boolean} fCode (true if code section, false if data section)\n * @param {boolean} [fPrint] (false means we're merely monitoring, so let WDEB386 print its own notifications)\n */\n addSectionInfo(dbgAddr, fCode, fPrint)\n {\n var nSegment = this.getShort(dbgAddr, 2);\n var sel = this.getShort(dbgAddr, 2);\n var off = this.getLong(dbgAddr, 4);\n var len = this.getLong(dbgAddr, 4);\n var dbgAddrModule = this.newAddr(this.getLong(dbgAddr, 4), this.getShort(dbgAddr, 2));\n var dbgAddrParent = this.newAddr(this.getLong(dbgAddr, 4), this.getShort(dbgAddr, 2));\n // sel = this.getShort(dbgAddr, 2) || sel;\n var sParent = this.getSZ(dbgAddrParent).toUpperCase();\n var sModule = this.getSZ(dbgAddrModule).toUpperCase();\n if (sParent == sModule) {\n sParent = \"\";\n } else {\n sParent += '!';\n }\n var sSection = (fCode? \"_CODE\" : \"_DATA\") + Str.toHex(nSegment, 2);\n if (fPrint && this.messageEnabled(Messages.MEM)) {\n /*\n * Mimics WDEB386 output, except that WDEB386 only displays a linear address, omitting the selector.\n */\n this.message(sParent + sModule + ' ' + (fCode? \"code\" : \"data\") + '(' + Str.toHex(nSegment, 4) + \")=\" + Str.toHex(sel, 4) + ':' + Str.toHex(off) + \" len \" + Str.toHex(len));\n }\n /*\n * TODO: Add support for 32-bit symbols; findModuleInfo() relies on Disk.getModuleInfo(), and the Disk\n * component doesn't yet know how to parse 32-bit executables.\n */\n var aSymbols = this.findModuleInfo(sModule, nSegment);\n aSymbols[sModule + sSection] = off;\n this.addSymbols(sModule, nSegment, sel, off, null, len, aSymbols);\n }\n\n /**\n * removeSectionInfo(nSegment, dbgAddr, fPrint)\n *\n * CONDITIONAL: if (Interrupts.WINDBG.ENABLED || Interrupts.WINDBGRM.ENABLED)\n *\n * @this {DebuggerX86}\n * @param {number} nSegment (logical segment number)\n * @param {DbgAddrX86} dbgAddr (address of module)\n * @param {boolean} [fPrint] (false means we're merely monitoring OR we don't really care about these notifications)\n */\n removeSectionInfo(nSegment, dbgAddr, fPrint)\n {\n var sModule = this.getSZ(dbgAddr).toUpperCase();\n var sModuleRemoved = this.removeSymbols(sModule, nSegment);\n if (fPrint && this.messageEnabled(Messages.MEM)) {\n if (sModuleRemoved) {\n this.message(sModule + ' ' + Str.toHex(nSegment, 4) + \" removed\");\n } else {\n this.message(\"unable to remove \" + sModule + \" for section \" + Str.toHex(nSegment, 4));\n }\n }\n }\n\n /**\n * intWindowsCallBack()\n *\n * CONDITIONAL: if (Interrupts.WINDBG.ENABLED || Interrupts.WINDBGRM.ENABLED)\n *\n * This intercepts calls to Windows callback addresses, which use INT 0x30 (aka Transfer Space Faults).\n *\n * We're only interested in one particular callback: the VW32_Int41Dispatch (0x002A002A) that KERNEL32\n * issues as 32-bit executable sections are loaded.\n *\n * At the time that INT 0x30 occurs, a far 32-bit call has been made, preceded by a near 32-bit call,\n * preceded by a 32-bit push of the Windows Debugger function # that would normally be in EAX if this had\n * been an actual INT 0x41.\n *\n * NOTE: Regardless whether we're \"handling\" INT 0x41 or merely \"monitoring\" INT 0x41, as far as THIS\n * interrupt is concerned, we always let the system process it, because execution never continues at the\n * instruction following an INT 0x30; in fact, execution doesn't even continue after the far 32-bit call\n * (even though the kernel places a \"RET 4\" after that call). So, rather than recreate all that automatic\n * address popping, we let the system do it for us, since it's designed to work whether a debugger (eg,\n * WDEB386's DEBUG VxD) is installed or not.\n *\n * TODO: Consider \"consuming\" all VW32_Int41Dispatch callbacks, because the Windows 95 kernel goes to\n * great effort to pass those requests on to the DEBUG VxD, which end up going nowhere when the VxD isn't\n * loaded (to load it, you must either run WDEB386.EXE or install the VxD via SYSTEM.INI). Regrettably,\n * Windows 95 assumes that if WDEB386 support is present, then a DEBUG VxD must be present as well.\n *\n * @this {DebuggerX86}\n * @param {number} addr\n * @return {boolean} true to proceed with the INT 0x30 software interrupt\n */\n intWindowsCallBack(addr)\n {\n var cpu = this.cpu;\n\n if (this.fWinDbg != null && cpu.regEAX == 0x002A002A) {\n\n var DX = cpu.regEDX & 0xffff;\n var SI = cpu.regESI & 0xffff;\n var dbgAddr = this.newAddr(cpu.getSP() + 0x0C, cpu.getSS());\n var EAX = this.getLong(dbgAddr);\n\n switch(EAX) {\n case Interrupts.WINDBG.LOADSEG32:\n /*\n * SI == segment type:\n * 0x0 code selector\n * 0x1 data selector\n * DX:EBX -> D386_Device_Params structure (see addSectionInfo() for details)\n */\n this.addSectionInfo(this.newAddr(cpu.regEBX, DX), !SI, !!this.fWinDbg);\n break;\n }\n }\n return true;\n }\n\n /**\n * intWindowsDebugger()\n *\n * CONDITIONAL: if (Interrupts.WINDBG.ENABLED || Interrupts.WINDBGRM.ENABLED)\n *\n * This intercepts calls to the Windows Debugger protected-mode interface (INT 0x41).\n *\n * It's enabled if Interrupts.WINDBG.ENABLED is true, but it must ALSO be enabled if\n * Interrupts.WINDBGRM.ENABLED is true, because if the latter decides to respond to requests,\n * then we must start responding, too. Windows assumes that if INT 0x68 support is present,\n * then INT 0x41 support must be present as well.\n *\n * That is why intWindowsDebuggerRM() will also set this.fWinDbg to true: we MUST return false\n * for all INT 0x41 requests, so that all requests are consumed, since there's no guarantee\n * that a valid INT 0x41 handler will exist inside the machine.\n *\n * @this {DebuggerX86}\n * @param {number} addr\n * @return {boolean} true to proceed with the INT 0x41 software interrupt, false to skip\n */\n intWindowsDebugger(addr)\n {\n var dbgAddr;\n var cpu = this.cpu;\n var AX = cpu.regEAX & 0xffff;\n var BX = cpu.regEBX & 0xffff;\n var CX = cpu.regECX & 0xffff;\n var DX = cpu.regEDX & 0xffff;\n var SI = cpu.regESI & 0xffff;\n var DI = cpu.regEDI & 0xffff;\n var ES = cpu.segES.sel;\n\n if (this.fWinDbg == null) {\n if (AX == Interrupts.WINDBG.IS_LOADED) {\n /*\n * We're only going to respond to this function if no one else did, in which case,\n * we'll set fWinDbg to true and handle additional notifications.\n */\n cpu.addIntReturn(addr, function(dbg) {\n return function onInt41Return(nLevel) {\n if ((cpu.regEAX & 0xffff) != Interrupts.WINDBG.LOADED) {\n cpu.regEAX = (cpu.regEAX & ~0xffff) | Interrupts.WINDBG.LOADED;\n /*\n * TODO: We need a DEBUGGER message category; using the MEM category for now.\n */\n dbg.printMessage(\"INT 0x41 handling enabled\", Messages.MEM);\n dbg.fWinDbg = true;\n } else {\n dbg.printMessage(\"INT 0x41 monitoring enabled\", Messages.MEM);\n dbg.fWinDbg = false;\n }\n };\n }(this));\n }\n return true;\n }\n\n /*\n * NOTE: If this.fWinDbg is true, then all cases should return false, because we're taking full\n * responsibility for all requests (don't assume there's valid interrupt handler inside the machine).\n */\n switch(AX) {\n case Interrupts.WINDBG.IS_LOADED: // 0x004F\n if (this.fWinDbg) {\n cpu.regEAX = (cpu.regEAX & ~0xffff) | Interrupts.WINDBG.LOADED;\n this.printMessage(\"INT 0x41 handling enabled\", Messages.MEM);\n }\n break;\n\n case Interrupts.WINDBG.LOADSEG: // 0x0050\n this.addSegmentInfo(this.newAddr(DI, ES), BX+1, CX, !(SI & 0x1), !!this.fWinDbg);\n break;\n\n case Interrupts.WINDBG.FREESEG: // 0x0052\n this.removeSegmentInfo(BX);\n break;\n\n case Interrupts.WINDBG.KRNLVARS: // 0x005A\n /*\n * BX = version number of this data (0x3A0)\n * DX:CX points to:\n * WORD hGlobalHeap ****\n * WORD pGlobalHeap ****\n * WORD hExeHead ****\n * WORD hExeSweep\n * WORD topPDB\n * WORD headPDB\n * WORD topsizePDB\n * WORD headTDB ****\n * WORD curTDB ****\n * WORD loadTDB\n * WORD LockTDB\n * WORD SelTableLen ****\n * DWORD SelTableStart ****\n */\n break;\n\n case Interrupts.WINDBG.RELSEG: // 0x005C\n case Interrupts.WINDBG.EXITCALL: // 0x0062\n case Interrupts.WINDBG.LOADDLL: // 0x0064\n case Interrupts.WINDBG.DELMODULE: // 0x0065\n case Interrupts.WINDBG.UNKNOWN66: // 0x0066\n case Interrupts.WINDBG.UNKNOWN67: // 0x0067\n /*\n * TODO: Figure out what to do with these notifications, if anything\n */\n break;\n\n case Interrupts.WINDBG.LOADHIGH: // 0x005D\n case Interrupts.WINDBG.REGDOTCMD: // 0x0070\n case Interrupts.WINDBG.CONDBP: // 0xF001\n break;\n\n case Interrupts.WINDBG.CHECKFAULT: // 0x007F\n if (this.fWinDbg) {\n /*\n * AX == 0 means handle fault normally, 1 means issue TRAPFAULT\n */\n cpu.regEAX = (cpu.regEAX & ~0xffff) | (this.fIgnoreNextCheckFault? 0 : 1);\n if (DEBUG) this.println(\"INT 0x41 CHECKFAULT: fault=\" + Str.toHexWord(BX) + \" type=\" + Str.toHexWord(CX) + \" trap=\" + !this.fIgnoreNextCheckFault);\n }\n break;\n\n case Interrupts.WINDBG.TRAPFAULT: // 0x0083\n /*\n * If we responded with AX == 1 to a preceding CHECKFAULT notification, then we should receive the\n * following TRAPFAULT notification; additionally, a TRAPFAULT notification may be issued without\n * any CHECKFAULT warning if the user was presented with a fault dialog containing a \"Debug\" button,\n * and the user clicked it.\n *\n * Regardless, whenever we receive this notification, we allocate a temporary breakpoint at the\n * reported fault address.\n */\n if (this.fWinDbg) {\n dbgAddr = this.newAddr(cpu.regEDX, CX);\n if (!this.cTrapFaults++) {\n this.println(\"INT 0x41 TRAPFAULT: fault=\" + Str.toHexWord(BX) + \" error=\" + Str.toHexLong(cpu.regESI) + \" addr=\" + this.toHexAddr(dbgAddr));\n this.addBreakpoint(this.aBreakExec, dbgAddr, true);\n this.historyInit(true); // temporary breakpoints don't normally trigger history, but in this case, we want it to\n } else {\n this.println(\"TRAPFAULT failed\");\n this.findBreakpoint(this.aBreakExec, dbgAddr, true, true, true);\n this.cTrapFaults = 0;\n this.stopCPU();\n }\n }\n break;\n\n case Interrupts.WINDBG.GETSYMBOL: // 0x008D\n if (this.fWinDbg) cpu.regEAX = (cpu.regEAX & ~0xffff)|1; // AX == 1 means not found\n break;\n\n case Interrupts.WINDBG.LOADSEG32: // 0x0150\n /*\n * SI == segment type:\n * 0x0 code selector\n * 0x1 data selector\n * DX:EBX -> D386_Device_Params structure (see addSectionInfo() for details)\n */\n this.addSectionInfo(this.newAddr(cpu.regEBX, DX), !SI, !!this.fWinDbg);\n break;\n\n case Interrupts.WINDBG.FREESEG32: // 0x0152\n /*\n * BX == segment number\n * DX:EDI -> module name\n */\n this.removeSectionInfo(BX, this.newAddr(cpu.regEDI, DX));\n break;\n\n default:\n if (DEBUG && this.fWinDbg) {\n this.println(\"INT 0x41: \" + Str.toHexWord(AX));\n }\n break;\n }\n\n /*\n * Let's try to limit the scope of any \"gt\" command by resetting this flag after any INT 0x41\n */\n this.fIgnoreNextCheckFault = false;\n\n return !this.fWinDbg;\n }\n\n /**\n * intWindowsDebuggerRM()\n *\n * CONDITIONAL: if (Interrupts.WINDBGRM.ENABLED)\n *\n * This intercepts calls to the Windows Debugger real-mode interface (INT 0x68).\n *\n * @this {DebuggerX86}\n * @param {number} addr\n * @return {boolean} true to proceed with the INT 0x68 software interrupt, false to skip\n */\n intWindowsDebuggerRM(addr)\n {\n var cpu = this.cpu;\n var AL = cpu.regEAX & 0xff;\n var AH = (cpu.regEAX >> 8) & 0xff;\n var BX = cpu.regEBX & 0xffff;\n var CX = cpu.regECX & 0xffff;\n var DX = cpu.regEDX & 0xffff;\n var DI = cpu.regEDI & 0xffff;\n var ES = cpu.segES.sel;\n\n if (this.fWinDbgRM == null) {\n if (AH == Interrupts.WINDBGRM.IS_LOADED) {\n /*\n * It looks like IFSHLP.SYS issues a preliminary INT 0x68 before Windows 95 gets rolling,\n * and the Windows Debugger will not have had a chance to load yet, so we need to ignore\n * that call. We detect IFSHLP.SYS by looking for \"IFS$\" in the caller's code segment,\n * where the IFSHLP device driver header is located.\n */\n if (cpu.getLong((cpu.segCS.sel << 4) + 0x0A) == 0x24534649) {\n if (DEBUG) this.println(\"Ignoring INT 0x68 from IFSHLP.SYS\");\n return true;\n }\n /*\n * Ditto for WDEB386 itself, which presumably wants to avoid loading on top of itself.\n */\n if (cpu.getLong((cpu.segCS.sel << 4) + 0x5F) == 0x42454457) {\n if (DEBUG) this.println(\"Ignoring INT 0x68 from WDEB386.EXE\");\n return true;\n }\n /*\n * We're only going to respond to this function if no one else did, in which case, we'll set\n * fWinDbgRM to true and handle additional notifications.\n */\n cpu.addIntReturn(addr, function(dbg) {\n return function onInt68Return(nLevel) {\n if ((cpu.regEAX & 0xffff) != Interrupts.WINDBGRM.LOADED) {\n cpu.regEAX = (cpu.regEAX & ~0xffff) | Interrupts.WINDBGRM.LOADED;\n dbg.printMessage(\"INT 0x68 handling enabled\", Messages.MEM);\n /*\n * If we turn on INT 0x68 handling, we must also turn on INT 0x41 handling,\n * because Windows assumes that the latter handler exists whenever the former does.\n */\n dbg.fWinDbg = dbg.fWinDbgRM = true;\n } else {\n dbg.printMessage(\"INT 0x68 monitoring enabled\", Messages.MEM);\n dbg.fWinDbgRM = false;\n }\n };\n }(this));\n }\n return true;\n }\n\n /*\n * NOTE: If this.fWinDbgRM is true, then all cases should return false, because we're taking full\n * responsibility for all requests (don't assume there's valid interrupt handler inside the machine).\n */\n switch(AH) {\n case Interrupts.WINDBGRM.IS_LOADED: // 0x43\n if (this.fWinDbgRM) {\n cpu.regEAX = (cpu.regEAX & ~0xffff) | Interrupts.WINDBGRM.LOADED;\n }\n break;\n\n case Interrupts.WINDBGRM.PREP_PMODE: // 0x44\n if (this.fWinDbgRM) {\n /*\n * Use our fancy new \"call break\" mechanism to obtain a special address that will\n * trap all calls, routing control to the specified function (callWindowsDebuggerPMInit).\n */\n var a = cpu.segCS.addCallBreak(this.callWindowsDebuggerPMInit.bind(this));\n if (a) {\n cpu.regEDI = a[0]; // ES:EDI receives the \"call break\" address\n cpu.setES(a[1]);\n }\n }\n break;\n\n case Interrupts.WINDBGRM.FREESEG: // 0x48\n this.removeSegmentInfo(BX);\n break;\n\n case Interrupts.WINDBGRM.REMOVESEGS: // 0x4F\n /*\n * TODO: This probably just signals the end of module loading; nothing is required, but we should\n * clean up whatever we can....\n */\n break;\n\n case Interrupts.WINDBGRM.LOADSEG: // 0x50\n if (AL == 0x20) {\n /*\n * Real-mode EXE\n * CX == paragraph\n * ES:DI -> module name\n */\n this.addSegmentInfo(this.newAddr(DI, ES), 0, CX, true, !!this.fWinDbgRM);\n }\n else if (AL < 0x80) {\n /*\n * AL == segment type:\n * 0x00 code selector\n * 0x01 data selector\n * 0x10 code segment\n * 0x11 data segment\n * 0x40 code segment & sel\n * 0x41 data segment & sel\n * BX == segment #\n * CX == actual segment/selector\n * DX == actual selector (if 0x40 or 0x41)\n * ES:DI -> module name\n */\n this.addSegmentInfo(this.newAddr(DI, ES), BX+1, (AL & 0x40)? DX : CX, !(AL & 0x1), !!this.fWinDbgRM);\n }\n else {\n /*\n * AL == segment type:\n * 0x80 device driver code seg\n * 0x81 device driver data seg\n * ES:DI -> D386_Device_Params structure (see addSectionInfo() for details)\n */\n this.addSectionInfo(this.newAddr(DI, ES), !(AL & 0x1), !!this.fWinDbgRM);\n }\n if (this.fWinDbgRM) {\n cpu.regEAX = (cpu.regEAX & ~0xff) | 0x01;\n }\n break;\n\n default:\n if (DEBUG && this.fWinDbgRM) {\n this.println(\"INT 0x68: \" + Str.toHexByte(AH));\n }\n break;\n }\n\n return !this.fWinDbgRM;\n }\n\n /**\n * callWindowsDebuggerPMInit()\n *\n * CONDITIONAL: if (Interrupts.WINDBGRM.ENABLED)\n *\n * This intercepts calls to the Windows Debugger \"PMInit\" interface; eg:\n *\n * AL = function code\n *\n * 0 - initialize IDT\n * ES:EDI points to protected mode IDT\n *\n * 1 - initialize page checking\n * BX = physical selector\n * ECX = linear bias\n *\n * 2 - specify that debug queries are supported\n *\n * 3 - initialize spare PTE\n * EBX = linear address of spare PTE\n * EDX = linear address the PTE represents\n *\n * 4 - set Enter/Exit VMM routine address\n * EBX = Enter VMM routine address\n * ECX = Exit VMM routine address\n * EDX = $_Debug_Out_Service address\n * ESI = $_Trace_Out_Service address\n * The VMM enter/exit routines must return with a retfd\n *\n * 5 - get debugger size/physical address\n * returns: AL = 0 (don't call AL = 1)\n * ECX = size in bytes\n * ESI = starting physical code/data address\n *\n * 6 - set debugger base/initialize spare PTE\n * EBX = linear address of spare PTE\n * EDX = linear address the PTE represents\n * ESI = starting linear address of debug code/data\n *\n * 7 - enable memory context functions\n *\n * @this {DebuggerX86}\n * @return {boolean} (must always return false to skip the call, because the call is using a CALLBREAK address)\n */\n callWindowsDebuggerPMInit()\n {\n var cpu = this.cpu;\n var AL = cpu.regEAX & 0xff;\n if (MAXDEBUG) this.println(\"INT 0x68 callback: \" + Str.toHexByte(AL));\n if (AL == 5) {\n cpu.regECX = cpu.regESI = 0; // our in-machine debugger footprint is zero\n cpu.regEAX = (cpu.regEAX & ~0xff) | 0x01; // TODO: Returning a \"don't call\" response sounds good, but what does it REALLY mean?\n }\n return false;\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {DebuggerX86}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"debugInput\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var dbg = this;\n switch (sBinding) {\n\n case \"debugInput\":\n this.bindings[sBinding] = control;\n this.controlDebug = /** @type {HTMLInputElement} */ (control);\n /*\n * For halted machines, this is fine, but for auto-start machines, it can be annoying.\n *\n * controlInput.focus();\n */\n control.onkeydown = function onKeyDownDebugInput(event) {\n var sCmd;\n if (event.keyCode == Keys.KEYCODE.CR) {\n sCmd = dbg.controlDebug.value;\n dbg.controlDebug.value = \"\";\n dbg.doCommands(sCmd, true);\n }\n else if (event.keyCode == Keys.KEYCODE.ESC) {\n dbg.controlDebug.value = sCmd = \"\";\n }\n else {\n if (event.keyCode == Keys.KEYCODE.UP) {\n sCmd = dbg.getPrevCommand();\n }\n else if (event.keyCode == Keys.KEYCODE.DOWN) {\n sCmd = dbg.getNextCommand();\n }\n if (sCmd != null) {\n var cch = sCmd.length;\n dbg.controlDebug.value = sCmd;\n dbg.controlDebug.setSelectionRange(cch, cch);\n }\n }\n if (sCmd != null && event.preventDefault) event.preventDefault();\n };\n return true;\n\n case \"debugEnter\":\n this.bindings[sBinding] = control;\n Web.onClickRepeat(\n control,\n 500, 100,\n function onClickDebugEnter(fRepeat) {\n if (dbg.controlDebug) {\n var sCommands = dbg.controlDebug.value;\n dbg.controlDebug.value = \"\";\n dbg.doCommands(sCommands, true);\n return true;\n }\n if (DEBUG) dbg.log(\"no debugger input buffer\");\n return false;\n }\n );\n return true;\n\n case \"step\":\n this.bindings[sBinding] = control;\n Web.onClickRepeat(\n control,\n 500, 100,\n function onClickStep(fRepeat) {\n var fCompleted = false;\n if (!dbg.isBusy(true)) {\n dbg.setBusy(true);\n fCompleted = dbg.stepCPU(fRepeat? 1 : 0);\n dbg.setBusy(false);\n }\n return fCompleted;\n }\n );\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * updateFocus()\n *\n * @this {DebuggerX86}\n */\n updateFocus()\n {\n if (this.controlDebug) this.controlDebug.focus();\n }\n\n /**\n * getCPUMode()\n *\n * @this {DebuggerX86}\n * @return {boolean} (true if protected mode, false if not)\n */\n getCPUMode()\n {\n return !!(this.cpu && (this.cpu.regCR0 & X86.CR0.MSW.PE) && !(this.cpu.regPS & X86.PS.VM));\n }\n\n /**\n * getAddressType()\n *\n * @this {DebuggerX86}\n * @return {number}\n */\n getAddressType()\n {\n return this.getCPUMode()? DebuggerX86.ADDRTYPE.PROT : DebuggerX86.ADDRTYPE.REAL;\n }\n\n /**\n * getSegment(sel, type)\n *\n * If the selector matches that of any of the CPU segment registers, then return the CPU's segment\n * register, instead of using our own segDebugger segment register. This makes it possible for us to\n * see what the CPU is seeing at certain critical junctures, such as after an LMSW instruction has\n * switched the processor from real to protected mode. Actually loading the selector from the GDT/LDT\n * should be done only as a last resort.\n *\n * @this {DebuggerX86}\n * @param {number|null|undefined} sel\n * @param {number} [type] (defaults to getAddressType())\n * @return {SegX86|null} seg\n */\n getSegment(sel, type)\n {\n var typeDefault = this.getAddressType();\n\n if (!type) type = typeDefault;\n\n if (type == typeDefault) {\n if (sel === this.cpu.getCS()) return this.cpu.segCS;\n if (sel === this.cpu.getDS()) return this.cpu.segDS;\n if (sel === this.cpu.getES()) return this.cpu.segES;\n if (sel === this.cpu.getSS()) return this.cpu.segSS;\n if (I386 && this.cpu.model >= X86.MODEL_80386) {\n if (sel === this.cpu.getFS()) return this.cpu.segFS;\n if (sel === this.cpu.getGS()) return this.cpu.segGS;\n }\n /*\n * Even if nSuppressBreaks is set, we'll allow the call in real-mode,\n * because a loadReal() request using segDebugger should generally be safe.\n */\n if (this.nSuppressBreaks && type == DebuggerX86.ADDRTYPE.PROT || !this.segDebugger) return null;\n }\n var seg = this.segDebugger;\n if (type != DebuggerX86.ADDRTYPE.PROT) {\n seg.loadReal(sel);\n seg.limit = 0xffff; // although an ACTUAL real-mode segment load would not modify the limit,\n seg.offMax = 0x10000; // proper segDebugger operation requires that we update the limit ourselves\n } else {\n seg.probeDesc(sel);\n }\n return seg;\n }\n\n /**\n * getAddr(dbgAddr, fWrite, nb)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86|null|undefined} dbgAddr\n * @param {boolean} [fWrite]\n * @param {number} [nb] number of bytes to check (1, 2 or 4); default is 1\n * @return {number} is the corresponding linear address, or X86.ADDR_INVALID\n */\n getAddr(dbgAddr, fWrite, nb)\n {\n /*\n * Some addresses (eg, breakpoint addresses) save their original linear address in dbgAddr.addr,\n * so we want to use that if it's there, but otherwise, dbgAddr is assumed to be a segmented address\n * whose linear address must always be (re)calculated based on current machine state (mode, active\n * descriptor tables, etc).\n */\n var addr = dbgAddr && dbgAddr.addr;\n if (addr == null) {\n addr = X86.ADDR_INVALID;\n if (dbgAddr) {\n /*\n * TODO: We should try to cache the seg inside dbgAddr, to avoid unnecessary calls to getSegment().\n */\n var seg = this.getSegment(dbgAddr.sel, dbgAddr.type);\n if (seg) {\n if (!fWrite) {\n addr = seg.checkReadDebugger(dbgAddr.off || 0, nb || 1);\n } else {\n addr = seg.checkWriteDebugger(dbgAddr.off || 0, nb || 1);\n }\n dbgAddr.addr = addr;\n }\n }\n }\n return addr;\n }\n\n /**\n * getByte(dbgAddr, inc)\n *\n * We must route all our memory requests through the CPU now, in case paging is enabled.\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {number} [inc]\n * @return {number}\n */\n getByte(dbgAddr, inc)\n {\n var b = 0xff;\n var addr = this.getAddr(dbgAddr, false, 1);\n if (addr !== X86.ADDR_INVALID) {\n /*\n * TODO: Determine what we should do about the fact that we're masking any error from probeAddr()\n */\n b = this.cpu.probeAddr(addr, 1, dbgAddr.type == DebuggerX86.ADDRTYPE.PHYSICAL) | 0;\n if (inc) this.incAddr(dbgAddr, inc);\n }\n return b;\n }\n\n /**\n * getWord(dbgAddr, fAdvance)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {boolean} [fAdvance]\n * @return {number}\n */\n getWord(dbgAddr, fAdvance)\n {\n return dbgAddr.fData32? this.getLong(dbgAddr, fAdvance? 4 : 0) : this.getShort(dbgAddr, fAdvance? 2 : 0);\n }\n\n /**\n * getShort(dbgAddr, inc)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {number} [inc]\n * @return {number}\n */\n getShort(dbgAddr, inc)\n {\n var w = 0xffff;\n var addr = this.getAddr(dbgAddr, false, 2);\n if (addr !== X86.ADDR_INVALID) {\n /*\n * TODO: Determine what we should do about the fact that we're masking any error from probeAddr()\n */\n w = this.cpu.probeAddr(addr, 2, dbgAddr.type == DebuggerX86.ADDRTYPE.PHYSICAL) | 0;\n if (inc) this.incAddr(dbgAddr, inc);\n }\n return w;\n }\n\n /**\n * getLong(dbgAddr, inc)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {number} [inc]\n * @return {number}\n */\n getLong(dbgAddr, inc)\n {\n var l = -1;\n var addr = this.getAddr(dbgAddr, false, 4);\n if (addr !== X86.ADDR_INVALID) {\n /*\n * TODO: Determine what we should do about the fact that we're masking any error from probeAddr()\n */\n l = this.cpu.probeAddr(addr, 4, dbgAddr.type == DebuggerX86.ADDRTYPE.PHYSICAL) | 0;\n if (inc) this.incAddr(dbgAddr, inc);\n }\n return l;\n }\n\n /**\n * setByte(dbgAddr, b, inc, fNoUpdate)\n *\n * NOTE: If you need to patch a ROM, you MUST use the ROM location's physical address.\n *\n * WARNING: Be careful with the editing commands that use function, because we don't have a safe\n * counterpart to cpu.probeAddr().\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {number} b\n * @param {number} [inc]\n * @param {boolean} [fNoUpdate] (when doing a large number of setByte() calls, set this to true and call cpu.updateCPU() when you're done)\n */\n setByte(dbgAddr, b, inc, fNoUpdate)\n {\n var addr = this.getAddr(dbgAddr, true, 1);\n if (addr !== X86.ADDR_INVALID) {\n if (dbgAddr.type != DebuggerX86.ADDRTYPE.PHYSICAL) {\n this.cpu.setByte(addr, b);\n } else {\n this.bus.setByteDirect(addr, b);\n }\n if (inc) this.incAddr(dbgAddr, inc);\n if (!fNoUpdate) this.cpu.updateCPU(true); // we set fForce to true in case video memory was the target\n }\n }\n\n /**\n * setShort(dbgAddr, w, inc)\n *\n * NOTE: If you need to patch a ROM, you MUST use the ROM location's physical address.\n *\n * WARNING: Be careful with the editing commands that use function, because we don't have a safe\n * counterpart to cpu.probeAddr().\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {number} w\n * @param {number} [inc]\n */\n setShort(dbgAddr, w, inc)\n {\n var addr = this.getAddr(dbgAddr, true, 2);\n if (addr !== X86.ADDR_INVALID) {\n if (dbgAddr.type != DebuggerX86.ADDRTYPE.PHYSICAL) {\n this.cpu.setShort(addr, w);\n } else {\n this.bus.setShortDirect(addr, w);\n }\n if (inc) this.incAddr(dbgAddr, inc);\n this.cpu.updateCPU(true); // we set fForce to true in case video memory was the target\n }\n }\n\n /**\n * newAddr(off, sel, addr, type, fData32, fAddr32)\n *\n * Returns a NEW DbgAddrX86 object, initialized with specified values and/or defaults.\n *\n * @this {DebuggerX86}\n * @param {number|null|undefined} [off] (default is zero)\n * @param {number|null|undefined} [sel] (default is undefined)\n * @param {number|null|undefined} [addr] (default is undefined)\n * @param {number} [type] (default is based on current CPU mode)\n * @param {boolean} [fData32] (default is the current CPU operand size)\n * @param {boolean} [fAddr32] (default is the current CPU address size)\n * @return {DbgAddrX86}\n */\n newAddr(off, sel, addr, type, fData32, fAddr32)\n {\n return this.setAddr({}, off, sel, addr, type, fData32, fAddr32);\n }\n\n /**\n * getAddrPrefix(dbgAddr)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @return {string}\n */\n getAddrPrefix(dbgAddr)\n {\n var ch;\n\n switch (dbgAddr.type) {\n case DebuggerX86.ADDRTYPE.REAL:\n case DebuggerX86.ADDRTYPE.V86:\n ch = '&';\n break;\n case DebuggerX86.ADDRTYPE.PROT:\n ch = '#';\n break;\n case DebuggerX86.ADDRTYPE.LINEAR:\n ch = '%';\n break;\n case DebuggerX86.ADDRTYPE.PHYSICAL:\n ch = '%%';\n break;\n default:\n ch = dbgAddr.sel? '' : '%';\n break;\n }\n return ch;\n }\n\n /**\n * setAddr(dbgAddr, off, sel, addr, type, fData32, fAddr32)\n *\n * Updates an EXISTING DbgAddrX86 object, initialized with specified values and/or defaults.\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {number|null|undefined} [off] (default is zero)\n * @param {number|null|undefined} [sel] (default is undefined)\n * @param {number|null|undefined} [addr] (default is undefined)\n * @param {number} [type] (default is based on current CPU mode)\n * @param {boolean} [fData32] (default is the current CPU operand size)\n * @param {boolean} [fAddr32] (default is the current CPU address size)\n * @return {DbgAddrX86}\n */\n setAddr(dbgAddr, off, sel, addr, type, fData32, fAddr32)\n {\n dbgAddr.off = off || 0;\n dbgAddr.sel = sel;\n dbgAddr.addr = addr;\n dbgAddr.type = type || this.getAddressType();\n dbgAddr.fData32 = (fData32 != null)? fData32 : !!(this.cpu && this.cpu.segCS.sizeData == 4);\n dbgAddr.fAddr32 = (fAddr32 != null)? fAddr32 : !!(this.cpu && this.cpu.segCS.sizeAddr == 4);\n dbgAddr.fTempBreak = false;\n return dbgAddr;\n }\n\n /**\n * packAddr(dbgAddr)\n *\n * Packs a DbgAddrX86 object into an Array suitable for saving in a machine state object.\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @return {Array}\n */\n packAddr(dbgAddr)\n {\n return [dbgAddr.off, dbgAddr.sel, dbgAddr.addr, dbgAddr.fTempBreak, dbgAddr.fData32, dbgAddr.fAddr32, dbgAddr.cOverrides, dbgAddr.fComplete];\n }\n\n /**\n * unpackAddr(aAddr)\n *\n * Unpacks a DbgAddrX86 object from an Array created by packAddr() and restored from a saved machine state.\n *\n * @this {DebuggerX86}\n * @param {Array} aAddr\n * @return {DbgAddrX86}\n */\n unpackAddr(aAddr)\n {\n return {off: aAddr[0], sel: aAddr[1], addr: aAddr[2], fTempBreak: aAddr[3], fData32: aAddr[4], fAddr32: aAddr[5], cOverrides: aAddr[6], fComplete: aAddr[7]};\n }\n\n /**\n * checkLimit(dbgAddr, fUpdate)\n *\n * Used by incAddr() and parseAddr() to ensure that the (updated) dbgAddr offset is within segment bounds.\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {boolean} [fUpdate] (true to update segment info)\n * @return {boolean}\n */\n checkLimit(dbgAddr, fUpdate)\n {\n if (dbgAddr.sel != null) {\n var seg = this.getSegment(dbgAddr.sel, dbgAddr.type);\n if (seg) {\n var off = dbgAddr.off & seg.maskAddr;\n if (!seg.fExpDown) {\n if ((off >>> 0) >= seg.offMax) {\n return false;\n }\n }\n else {\n if ((off >>> 0) < seg.offMax) {\n return false;\n }\n }\n if (fUpdate) {\n dbgAddr.off = off;\n dbgAddr.fData32 = (seg.sizeData == 4);\n dbgAddr.fAddr32 = (seg.sizeAddr == 4);\n }\n }\n }\n return true;\n }\n\n /**\n * parseAddr(sAddr, fCode, fNoChecks, fQuiet)\n *\n * As discussed above, dbgAddr variables contain one or more of: off, sel, and addr. They represent\n * a segmented address (sel:off) when sel is defined or a linear address (addr) when sel is undefined\n * (or null).\n *\n * To create a segmented address, specify two values separated by ':'; for a linear address, use\n * a '%' prefix. We check for ':' after '%', so if for some strange reason you specify both, the\n * address will be treated as segmented, not linear.\n *\n * The '%' syntax is similar to that used by the Windows 80386 kernel debugger (wdeb386) for linear\n * addresses. If/when we add support for processors with page tables, we will likely adopt the same\n * convention for linear addresses and provide a different syntax (eg, \"%%\") physical memory references.\n *\n * Address evaluation and validation (eg, range checks) are no longer performed at this stage. That's\n * done later, by getAddr(), which returns X86.ADDR_INVALID for invalid segments, out-of-range offsets,\n * etc. The Debugger's low-level get/set memory functions verify all getAddr() results, but even if an\n * invalid address is passed through to the Bus memory interfaces, the address will simply be masked with\n * Bus.nBusLimit; in the case of X86.ADDR_INVALID, that will generally refer to the top of the physical\n * address space.\n *\n * @this {DebuggerX86}\n * @param {string|undefined} sAddr\n * @param {boolean} [fCode] (true if target is code, false if target is data)\n * @param {boolean} [fNoChecks] (true when setting breakpoints that may not be valid now, but will be later)\n * @param {boolean} [fQuiet]\n * @return {DbgAddrX86|null|undefined}\n */\n parseAddr(sAddr, fCode, fNoChecks, fQuiet)\n {\n var dbgAddr;\n var dbgAddrNext = (fCode? this.dbgAddrNextCode : this.dbgAddrNextData);\n\n var type = fNoChecks? DebuggerX86.ADDRTYPE.NONE : dbgAddrNext.type;\n var off = dbgAddrNext.off, sel = dbgAddrNext.sel, addr = dbgAddrNext.addr;\n\n if (sAddr !== undefined) {\n\n sAddr = this.parseReference(sAddr);\n\n var ch = sAddr.charAt(0);\n var iColon = sAddr.indexOf(':');\n\n switch(ch) {\n case '&':\n type = DebuggerX86.ADDRTYPE.REAL;\n break;\n case '#':\n type = DebuggerX86.ADDRTYPE.PROT;\n break;\n case '%':\n type = DebuggerX86.ADDRTYPE.LINEAR;\n ch = sAddr.charAt(1);\n if (ch == '%') {\n type = DebuggerX86.ADDRTYPE.PHYSICAL;\n ch += ch;\n }\n off = addr = 0;\n sel = null; // we still have code that relies on this crutch, instead of the type field\n break;\n default:\n if (iColon >= 0) type = DebuggerX86.ADDRTYPE.NONE;\n ch = '';\n break;\n }\n\n if (ch) {\n sAddr = sAddr.substr(ch.length);\n iColon -= ch.length;\n }\n\n dbgAddr = this.findSymbolAddr(sAddr);\n if (dbgAddr) return dbgAddr;\n\n if (iColon < 0) {\n if (sel != null) {\n off = this.parseExpression(sAddr, fQuiet);\n addr = null;\n } else {\n addr = this.parseExpression(sAddr, fQuiet);\n if (addr == null) off = null;\n }\n }\n else {\n sel = this.parseExpression(sAddr.substring(0, iColon), fQuiet);\n off = this.parseExpression(sAddr.substring(iColon + 1), fQuiet);\n addr = null;\n }\n }\n\n if (off != null) {\n dbgAddr = this.newAddr(off, sel, addr, type);\n if (!fNoChecks && !this.checkLimit(dbgAddr, true)) {\n this.println(\"invalid offset: \" + this.toHexAddr(dbgAddr));\n dbgAddr = null;\n }\n }\n return dbgAddr;\n }\n\n /**\n * parseAddrOptions(dbgAddr, sOptions)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {string} [sOptions]\n */\n parseAddrOptions(dbgAddr, sOptions)\n {\n if (sOptions) {\n var a = sOptions.match(/(['\"])(.*?)\\1/);\n if (a) {\n dbgAddr.aCmds = this.parseCommand(dbgAddr.sCmd = a[2]);\n }\n }\n }\n\n /**\n * parseAddrReference(s, sAddr)\n *\n * Returns the given string with the given address references replaced with the contents of the address.\n *\n * @this {Debugger}\n * @param {string} s\n * @param {string} sAddr\n * @return {string}\n */\n parseAddrReference(s, sAddr)\n {\n var dbgAddr = this.parseAddr(sAddr);\n return s.replace('[' + sAddr + ']', dbgAddr? Str.toHex(this.getWord(dbgAddr), dbgAddr.fData32? 8 : 4) : \"undefined\");\n }\n\n /**\n * incAddr(dbgAddr, inc)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {number} [inc] contains value to increment dbgAddr by (default is 1)\n */\n incAddr(dbgAddr, inc)\n {\n inc = inc || 1;\n if (dbgAddr.addr != null) {\n dbgAddr.addr += inc;\n }\n if (dbgAddr.sel != null) {\n dbgAddr.off += inc;\n if (!this.checkLimit(dbgAddr)) {\n dbgAddr.off = 0;\n dbgAddr.addr = null;\n }\n }\n }\n\n /**\n * toHexOffset(off, sel, fAddr32)\n *\n * @this {DebuggerX86}\n * @param {number|null|undefined} [off]\n * @param {number|null|undefined} [sel]\n * @param {boolean} [fAddr32] is true for 32-bit ADDRESS size\n * @return {string} the hex representation of off (or sel:off)\n */\n toHexOffset(off, sel, fAddr32)\n {\n if (sel != null) {\n return Str.toHex(sel, 4) + ':' + Str.toHex(off, (off & ~0xffff) || fAddr32? 8 : 4);\n }\n return Str.toHex(off);\n }\n\n /**\n * toHexAddr(dbgAddr)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @return {string} the hex representation of the address\n */\n toHexAddr(dbgAddr)\n {\n var ch = this.getAddrPrefix(dbgAddr);\n /*\n * TODO: Revisit the decision to check sel == null; I would rather see these decisions based on type.\n */\n return (dbgAddr.type >= DebuggerX86.ADDRTYPE.LINEAR || dbgAddr.sel == null)? (ch + Str.toHex(dbgAddr.addr)) : (ch + this.toHexOffset(dbgAddr.off, dbgAddr.sel, dbgAddr.fAddr32));\n }\n\n /**\n * getSZ(dbgAddr, cchMax)\n *\n * Gets zero-terminated (aka \"ASCIIZ\") string from dbgAddr. It also stops at the first '$', in case this is\n * a '$'-terminated string -- mainly because I'm lazy and didn't feel like writing a separate get() function.\n * Yes, a zero-terminated string containing a '$' will be prematurely terminated, and no, I don't care.\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {number} [cchMax] (default is 256)\n * @return {string} (and dbgAddr advanced past the terminating zero)\n */\n getSZ(dbgAddr, cchMax)\n {\n var s = \"\";\n cchMax = cchMax || 256;\n while (s.length < cchMax) {\n var b = this.getByte(dbgAddr, 1);\n if (!b || b == 0x24 || b >= 127) break;\n s += (b >= 32? String.fromCharCode(b) : '.');\n }\n return s;\n }\n\n /**\n * dumpBackTrack(asArgs)\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n */\n dumpBackTrack(asArgs)\n {\n var sInfo = \"no information\";\n if (BACKTRACK) {\n var sAddr = asArgs[0];\n var dbgAddr = this.parseAddr(sAddr, true, true, true);\n if (dbgAddr) {\n var addr = this.getAddr(dbgAddr);\n if (dbgAddr.type != DebuggerX86.ADDRTYPE.PHYSICAL) {\n var pageInfo = this.getPageInfo(addr);\n if (pageInfo) {\n dbgAddr.addr = pageInfo.addrPhys;\n dbgAddr.type = DebuggerX86.ADDRTYPE.PHYSICAL;\n }\n }\n sInfo = this.toHexAddr(dbgAddr) + \": \" + (this.bus.getSymbol(addr, true) || sInfo);\n } else {\n var component, componentPrev = null;\n while (component = this.cmp.getMachineComponent(\"Disk\", componentPrev)) {\n var aInfo = component.getSymbolInfo(sAddr);\n if (aInfo.length) {\n sInfo = \"\";\n for (var i in aInfo) {\n var a = aInfo[i];\n if (sInfo) sInfo += '\\n';\n sInfo += a[0] + \": \" + a[1] + ' ' + Str.toHex(a[2], 4) + ':' + Str.toHex(a[3], 4) + \" len \" + Str.toHexWord(a[4]);\n }\n }\n componentPrev = component;\n }\n }\n }\n return sInfo;\n }\n\n /**\n * dumpBlocks(aBlocks, sAddr, fLinear)\n *\n * @this {DebuggerX86}\n * @param {Array} aBlocks\n * @param {string} [sAddr] (optional block address)\n * @param {boolean} [fLinear] (true if linear, physical otherwise)\n */\n dumpBlocks(aBlocks, sAddr, fLinear)\n {\n var addr = 0, i = 0, n = aBlocks.length;\n\n if (sAddr) {\n addr = this.getAddr(this.parseAddr(sAddr));\n if (addr === X86.ADDR_INVALID) {\n this.println(\"invalid address: \" + sAddr);\n return;\n }\n i = addr >>> this.cpu.nBlockShift;\n n = 1;\n }\n\n this.println(\"blockid \" + (fLinear? \"linear \" : \"physical\") + \" blockaddr used size type\");\n this.println(\"-------- --------- ---------- ------ ------ ----\");\n\n var typePrev = -1, cPrev = 0;\n while (n--) {\n var block = aBlocks[i];\n /*\n * We need to replicate a portion of what probeAddr() does, which is to \"peek\" at the\n * underlying physical block of any UNPAGED block. An UNPAGED block doesn't imply\n * that the page is invalid, but merely that the CPU has not yet been asked to perform\n * the page directory/page table lookup.\n *\n * To do that, we use the same mapPageBlock() interface that the CPU uses, with fSuppress\n * set, so that it doesn't 1) generate a fault or 2) modify the block. Blocks should only\n * \"validated\" when a CPU operation touches the corresponding page, and they should be only\n * be \"invalidated\" when the CPU wants to flush the TLB (ie, whenever CR3 is updated).\n */\n if (block && block.type == Memory.TYPE.UNPAGED) {\n block = this.cpu.mapPageBlock(addr, false, true);\n }\n if (block.type == typePrev) {\n if (!cPrev++) this.println(\"...\");\n } else {\n typePrev = block.type;\n var sType = Memory.TYPE.NAMES[typePrev];\n if (typePrev == Memory.TYPE.PAGED) {\n block = block.blockPhys;\n\n sType += \" -> \" + Memory.TYPE.NAMES[block.type];\n }\n if (block) {\n this.println(Str.toHex(block.id, 8) + \" %\" + Str.toHex(i << this.cpu.nBlockShift, 8) + \" %%\" + Str.toHex(block.addr, 8) + \" \" + Str.toHexWord(block.used) + \" \" + Str.toHexWord(block.size) + \" \" + sType);\n }\n if (typePrev != Memory.TYPE.NONE && typePrev != Memory.TYPE.UNPAGED) typePrev = -1;\n cPrev = 0;\n }\n addr += this.cpu.nBlockSize;\n i++;\n }\n }\n\n /**\n * dumpBus(asArgs)\n *\n * Dumps Bus allocations.\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs (asArgs[0] is an optional block address)\n */\n dumpBus(asArgs)\n {\n this.dumpBlocks(this.cpu.aBusBlocks, asArgs[0]);\n }\n\n /**\n * dumpDOS(asArgs)\n *\n * Dumps DOS MCBs (Memory Control Blocks).\n *\n * TODO: Add some code to detect the current version of DOS (if any) and locate the first MCB automatically.\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n */\n dumpDOS(asArgs)\n {\n var mcb;\n var sMCB = asArgs[0];\n if (sMCB) {\n mcb = this.parseValue(sMCB);\n }\n if (mcb === undefined) {\n this.println(\"invalid MCB\");\n return;\n }\n this.println(\"dumpMCB(\" + Str.toHexWord(mcb) + ')');\n while (mcb) {\n var dbgAddr = this.newAddr(0, mcb);\n var bSig = this.getByte(dbgAddr, 1);\n var wPID = this.getShort(dbgAddr, 2);\n var wParas = this.getShort(dbgAddr, 5);\n if (bSig != 0x4D && bSig != 0x5A) break;\n this.println(this.toHexOffset(0, mcb) + \": '\" + String.fromCharCode(bSig) + \"' PID=\" + Str.toHexWord(wPID) + \" LEN=\" + Str.toHexWord(wParas) + ' \"' + this.getSZ(dbgAddr, 8) + '\"');\n mcb += 1 + wParas;\n }\n }\n\n /**\n * dumpIDT(asArgs)\n *\n * Dumps an IDT vector entry.\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n */\n dumpIDT(asArgs)\n {\n var sIDT = asArgs[0];\n\n if (!sIDT) {\n this.println(\"no IDT vector\");\n return;\n }\n\n var nIDT = this.parseValue(sIDT);\n if (nIDT === undefined || nIDT < 0 || nIDT > 255) {\n this.println(\"invalid vector: \" + sIDT);\n return;\n }\n\n var ch = '&', fProt = this.cpu.isProtMode(), fAddr32 = false;\n var addrIDT = this.cpu.addrIDT + (nIDT << (fProt? 3 : 2));\n var off = this.cpu.getShort(addrIDT + X86.DESC.LIMIT.OFFSET);\n var sel = this.cpu.getShort(addrIDT + X86.DESC.BASE.OFFSET);\n if (fProt) {\n ch = '#';\n var acc = this.cpu.getShort(addrIDT + X86.DESC.ACC.OFFSET);\n if (acc & X86.DESC.ACC.TYPE.NONSEG_386) {\n fAddr32 = true;\n off |= this.cpu.getShort(addrIDT + X86.DESC.EXT.OFFSET) << 16;\n }\n }\n\n this.println(\"dumpIDT(\" + Str.toHexWord(nIDT) + \"): \" + ch + Str.toHex(sel, 4) + ':' + Str.toHex(off, fAddr32? 8 : 4));\n }\n\n /**\n * dumpMem(asArgs)\n *\n * Dumps page allocations.\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs (asArgs[0] is an optional block address)\n */\n dumpMem(asArgs)\n {\n this.dumpBlocks(this.cpu.aMemBlocks, asArgs[0], this.cpu.aMemBlocks !== this.cpu.aBusBlocks);\n }\n\n /**\n * getPageEntry(addrPE, lPE, fPTE)\n *\n * @this {DebuggerX86}\n * @param {number} addrPE\n * @param {number} lPE\n * @param {boolean} [fPTE] (true if the entry is a PTE, false if it's a PDE)\n * @return {string}\n */\n getPageEntry(addrPE, lPE, fPTE)\n {\n var s = Str.toHex(addrPE) + ' ' + Str.toHex(lPE) + ' ';\n s += (fPTE && (lPE & X86.PTE.DIRTY))? 'D' : '-';\n s += (lPE & X86.PTE.ACCESSED)? 'A' : '-';\n s += (lPE & X86.PTE.USER)? 'U' : 'S';\n s += (lPE & X86.PTE.READWRITE)? 'W' : 'R';\n s += (lPE & X86.PTE.PRESENT)? 'P' : 'N';\n return s;\n }\n\n /**\n * getPageInfo(addr)\n *\n * @this {DebuggerX86}\n * @param {number} addr\n * @return {Object|null}\n */\n getPageInfo(addr)\n {\n var pageInfo = null;\n if (I386 && this.cpu.model >= X86.MODEL_80386) {\n var bus = this.bus;\n /*\n * Here begins code remarkably similar to mapPageBlock() (with fSuppress set).\n */\n pageInfo = {};\n pageInfo.offPDE = (addr & X86.LADDR.PDE.MASK) >>> X86.LADDR.PDE.SHIFT;\n pageInfo.addrPDE = this.cpu.regCR3 + pageInfo.offPDE;\n pageInfo.blockPDE = bus.aMemBlocks[(pageInfo.addrPDE & bus.nBusMask) >>> bus.nBlockShift];\n pageInfo.lPDE = pageInfo.blockPDE.readLong(pageInfo.offPDE);\n pageInfo.offPTE = (addr & X86.LADDR.PTE.MASK) >>> X86.LADDR.PTE.SHIFT;\n pageInfo.addrPTE = (pageInfo.lPDE & X86.PTE.FRAME) + pageInfo.offPTE;\n pageInfo.blockPTE = bus.aMemBlocks[(pageInfo.addrPTE & bus.nBusMask) >>> bus.nBlockShift];\n pageInfo.lPTE = pageInfo.blockPTE.readLong(pageInfo.offPTE);\n pageInfo.addrPhys = (pageInfo.lPTE & X86.PTE.FRAME) + (addr & X86.LADDR.OFFSET);\n //var blockPhys = bus.aMemBlocks[(addrPhys & bus.nBusMask) >>> bus.nBlockShift];\n }\n return pageInfo;\n }\n\n /**\n * dumpPage(asArgs)\n *\n * Dumps page table information about the given linear address.\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n */\n dumpPage(asArgs)\n {\n var sAddr = asArgs[0];\n if (!sAddr) {\n this.println(\"missing address\");\n return;\n }\n\n var addr = this.getAddr(this.parseAddr(sAddr));\n if (addr === X86.ADDR_INVALID) {\n this.println(\"invalid address: \" + sAddr);\n return;\n }\n\n var pageInfo = this.getPageInfo(addr);\n if (!pageInfo) {\n this.println(\"unsupported operation\");\n return;\n }\n\n this.println(\"linear PDE addr PDE PTE addr PTE physical\" );\n this.println(\"--------- ---------- -------- ---------- -------- ----------\");\n var s = '%' + Str.toHex(addr);\n s += \" %%\" + this.getPageEntry(pageInfo.addrPDE, pageInfo.lPDE);\n s += \" %%\" + this.getPageEntry(pageInfo.addrPTE, pageInfo.lPTE, true);\n s += \" %%\" + Str.toHex(pageInfo.addrPhys);\n this.println(s);\n }\n\n /**\n * dumpSel(asArgs)\n *\n * Dumps a descriptor for the given selector.\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n */\n dumpSel(asArgs)\n {\n var sSel = asArgs[0];\n\n if (!sSel) {\n this.println(\"no selector\");\n return;\n }\n\n var sel = this.parseValue(sSel);\n if (sel === undefined) {\n this.println(\"invalid selector: \" + sSel);\n return;\n }\n\n var seg = this.getSegment(sel, DebuggerX86.ADDRTYPE.PROT);\n this.println(\"dumpSel(\" + Str.toHexWord(seg? seg.sel : sel) + \"): %\" + Str.toHex(seg? seg.addrDesc : null, this.cchAddr));\n if (!seg) return;\n\n var sType;\n var fGate = false;\n if (seg.type & X86.DESC.ACC.TYPE.SEG) {\n if (seg.type & X86.DESC.ACC.TYPE.CODE) {\n sType = \"code\";\n sType += (seg.type & X86.DESC.ACC.TYPE.READABLE)? \",readable\" : \",execonly\";\n if (seg.type & X86.DESC.ACC.TYPE.CONFORMING) sType += \",conforming\";\n }\n else {\n sType = \"data\";\n sType += (seg.type & X86.DESC.ACC.TYPE.WRITABLE)? \",writable\" : \",readonly\";\n if (seg.type & X86.DESC.ACC.TYPE.EXPDOWN) sType += \",expdown\";\n }\n if (seg.type & X86.DESC.ACC.TYPE.ACCESSED) sType += \",accessed\";\n }\n else {\n var sysDesc = DebuggerX86.SYSDESCS[seg.type];\n if (sysDesc) {\n sType = sysDesc[0];\n fGate = sysDesc[1];\n }\n }\n\n if (sType && !(seg.acc & X86.DESC.ACC.PRESENT)) sType += \",not present\";\n\n var sDump;\n if (fGate) {\n sDump = \"seg=\" + Str.toHexWord(seg.base & 0xffff) + \" off=\" + Str.toHexWord(seg.limit);\n } else {\n sDump = \"base=\" + Str.toHex(seg.base, this.cchAddr) + \" limit=\" + this.getLimitString(seg.limit);\n }\n /*\n * When we dump the EXT word, we mask off the LIMIT1619 and BASE2431 bits, because those have already\n * been incorporated into the limit and base properties of the segment register; all we care about here\n * are whether EXT contains any of the AVAIL (0x10), BIG (0x40) or LIMITPAGES (0x80) bits.\n */\n this.println(sDump + \" type=\" + Str.toHexByte(seg.type >> 8) + \" (\" + sType + ')' + \" ext=\" + Str.toHexWord(seg.ext & ~(X86.DESC.EXT.LIMIT1619 | X86.DESC.EXT.BASE2431)) + \" dpl=\" + Str.toHexByte(seg.dpl));\n }\n\n /**\n * dumpHistory(sPrev, sLines, sComment)\n *\n * If sLines is not a number, it can be a instruction filter. However, for the moment, the only\n * supported filter is \"call\", which filters the history buffer for all CALL and RET instructions\n * from the specified previous point forward.\n *\n * @this {DebuggerX86}\n * @param {string} [sPrev] is a (decimal) number of instructions to rewind to (default is 10)\n * @param {string} [sLines] is a (decimal) number of instructions to print (default is, again, 10)\n * @param {string} [sComment] (should be either \"history\" or \"cycles\"; default is \"history\")\n */\n dumpHistory(sPrev, sLines, sComment = \"history\")\n {\n var sMore = \"\";\n var cHistory = 0;\n var iHistory = this.iOpcodeHistory;\n var aHistory = this.aOpcodeHistory;\n\n if (aHistory.length) {\n var nPrev = +sPrev || this.nextHistory;\n var nLines = +sLines || 10;\n\n if (isNaN(nPrev)) {\n nPrev = nLines;\n } else {\n sMore = \"more \";\n }\n\n if (nPrev > aHistory.length) {\n this.println(\"note: only \" + aHistory.length + \" available\");\n nPrev = aHistory.length;\n }\n\n iHistory -= nPrev;\n if (iHistory < 0) {\n /*\n * If the dbgAddr of the last aHistory element contains a valid selector, wrap around.\n */\n if (aHistory[aHistory.length - 1].sel == null) {\n nPrev = iHistory + nPrev;\n iHistory = 0;\n } else {\n iHistory += aHistory.length;\n }\n }\n\n var aFilters = [];\n if (sLines == \"call\") {\n nLines = 100000;\n aFilters = [\"CALL\"];\n }\n\n if (sPrev !== undefined) {\n this.println(nPrev + \" instructions earlier:\");\n }\n\n /*\n * TODO: The following is necessary to prevent dumpHistory() from causing additional (or worse, recursive)\n * faults due to segmented addresses that are no longer valid, but the only alternative is to dramatically\n * increase the amount of memory used to store instruction history (eg, storing copies of all the instruction\n * bytes alongside the execution addresses).\n *\n * For now, we're living dangerously, so that our history dumps actually work.\n *\n * this.nSuppressBreaks++;\n *\n * If you re-enable this protection, be sure to re-enable the decrement below, too.\n */\n while (nLines > 0 && iHistory != this.iOpcodeHistory) {\n\n var dbgAddr = aHistory[iHistory++];\n if (dbgAddr.sel == null) break;\n\n /*\n * We must create a new dbgAddr from the address in aHistory, because dbgAddr was\n * a reference, not a copy, and we don't want getInstruction() modifying the original.\n */\n var dbgAddrNew = this.newAddr(dbgAddr.off, dbgAddr.sel, dbgAddr.addr, dbgAddr.type, dbgAddr.fData32, dbgAddr.fAddr32);\n\n var nSequence = nPrev--;\n if (dbgAddr.cycleCount != null && sComment == \"cycles\") {\n nSequence = dbgAddr.cycleCount;\n }\n\n var sInstruction = this.getInstruction(dbgAddrNew, sComment, nSequence);\n\n if (!aFilters.length || sInstruction.indexOf(aFilters[0]) >= 0) {\n this.println(sInstruction);\n }\n\n /*\n * If there were OPERAND or ADDRESS overrides on the previous instruction, getInstruction()\n * will have automatically disassembled additional bytes, so skip additional history entries.\n */\n if (dbgAddrNew.cOverrides) {\n iHistory += dbgAddrNew.cOverrides; nLines -= dbgAddrNew.cOverrides; nPrev -= dbgAddrNew.cOverrides;\n }\n\n if (iHistory >= aHistory.length) iHistory = 0;\n this.nextHistory = nPrev;\n cHistory++;\n nLines--;\n }\n /*\n * See comments above.\n *\n * this.nSuppressBreaks--;\n */\n }\n\n if (!cHistory) {\n this.println(\"no \" + sMore + \"history available\");\n this.nextHistory = undefined;\n }\n }\n\n /**\n * dumpTSS(asArgs)\n *\n * This dumps a TSS using the given selector. If none is specified, the current TR is used.\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n */\n dumpTSS(asArgs)\n {\n var seg;\n var sSel = asArgs[0];\n\n if (!sSel) {\n seg = this.cpu.segTSS;\n } else {\n var sel = this.parseValue(sSel);\n if (sel === undefined) {\n this.println(\"invalid task selector: \" + sSel);\n return;\n }\n seg = this.getSegment(sel, DebuggerX86.ADDRTYPE.PROT);\n }\n\n this.println(\"dumpTSS(\" + Str.toHexWord(seg? seg.sel : sel) + \"): %\" + Str.toHex(seg? seg.base : null, this.cchAddr));\n if (!seg) return;\n\n var sDump = \"\";\n var type = seg.type & ~X86.DESC.ACC.TYPE.TSS_BUSY;\n var cch = (type == X86.DESC.ACC.TYPE.TSS286? 4 : 8);\n var aTSSFields = (type == X86.DESC.ACC.TYPE.TSS286? DebuggerX86.TSS286 : DebuggerX86.TSS386);\n var off, addr, v;\n for (var sField in aTSSFields) {\n off = aTSSFields[sField];\n addr = seg.base + off;\n v = this.cpu.probeAddr(addr, 2);\n if (type == X86.DESC.ACC.TYPE.TSS386) {\n v |= this.cpu.probeAddr(addr + 2, 2) << 16;\n }\n if (sDump) sDump += '\\n';\n sDump += Str.toHexWord(off) + ' ' + Str.pad(sField + ':', 11) + Str.toHex(v, cch);\n }\n if (type == X86.DESC.ACC.TYPE.TSS386) {\n var iPort = 0;\n off = (v >>> 16);\n /*\n * We arbitrarily cut the IOPM dump off at port 0x3FF; we're not currently interested in anything above that.\n */\n while (off < seg.offMax && iPort < 0x3ff) {\n addr = seg.base + off;\n v = this.cpu.probeAddr(addr, 2);\n sDump += \"\\n\" + Str.toHexWord(off) + \" ports \" + Str.toHexWord(iPort) + '-' + Str.toHexWord(iPort+15) + \": \" + Str.toBinBytes(v, 2);\n iPort += 16;\n off += 2;\n }\n }\n this.println(sDump);\n }\n\n /**\n * findModuleInfo(sModule, nSegment)\n *\n * Since we're not sure what Disk the module was loaded from, we have to check all of them.\n *\n * @this {DebuggerX86}\n * @param {string} sModule\n * @param {number} nSegment\n * @return {Object}\n */\n findModuleInfo(sModule, nSegment)\n {\n var aSymbols = [];\n if (SYMBOLS) {\n var component, componentPrev = null;\n while (component = this.cmp.getMachineComponent(\"Disk\", componentPrev)) {\n aSymbols = component.getModuleInfo(sModule, nSegment);\n if (aSymbols.length) break;\n componentPrev = component;\n }\n }\n return aSymbols;\n }\n\n /**\n * messageInit(sEnable)\n *\n * @this {DebuggerX86}\n * @param {string|undefined} sEnable contains zero or more message categories to enable, separated by '|'\n */\n messageInit(sEnable)\n {\n this.dbg = this;\n this.bitsMessage = Messages.WARN;\n this.sMessagePrev = null;\n this.aMessageBuffer = [];\n var aEnable = this.parseCommand(sEnable, false, '|');\n if (aEnable.length) {\n this.bitsMessage = Messages.NONE; // when specific messages are being enabled, WARN must be explicitly set\n for (var m in Messages.CATEGORIES) {\n if (Usr.indexOf(aEnable, m) >= 0) {\n this.bitsMessage |= Messages.CATEGORIES[m];\n this.println(m + \" messages enabled\");\n }\n }\n }\n this.historyInit(); // call this just in case Messages.INT was turned on\n }\n\n /**\n * messageDump(bitMessage, fnDumper)\n *\n * @this {DebuggerX86}\n * @param {number} bitMessage is one Messages category flag\n * @param {function(Array.<string>)} fnDumper is a function the Debugger can use to dump data for that category\n * @return {boolean} true if successfully registered, false if not\n */\n messageDump(bitMessage, fnDumper)\n {\n for (var m in Messages.CATEGORIES) {\n if (bitMessage == Messages.CATEGORIES[m]) {\n this.afnDumpers[m] = fnDumper;\n return true;\n }\n }\n return false;\n }\n\n /**\n * getRegIndex(sReg, off)\n *\n * @this {DebuggerX86}\n * @param {string} sReg\n * @param {number} [off] optional offset into sReg\n * @return {number} register index, or -1 if not found\n */\n getRegIndex(sReg, off)\n {\n var i;\n sReg = sReg.toUpperCase();\n if (off == null) {\n i = Usr.indexOf(DebuggerX86.REGS, sReg);\n } else {\n i = Usr.indexOf(DebuggerX86.REGS, sReg.substr(off, 3));\n if (i < 0) i = Usr.indexOf(DebuggerX86.REGS, sReg.substr(off, 2));\n }\n return i;\n }\n\n /**\n * getRegString(iReg)\n *\n * @this {DebuggerX86}\n * @param {number} iReg\n * @return {string}\n */\n getRegString(iReg)\n {\n var cch = 0;\n var n = this.getRegValue(iReg);\n if (n != null) {\n switch(iReg) {\n case DebuggerX86.REG_AL:\n case DebuggerX86.REG_CL:\n case DebuggerX86.REG_DL:\n case DebuggerX86.REG_BL:\n case DebuggerX86.REG_AH:\n case DebuggerX86.REG_CH:\n case DebuggerX86.REG_DH:\n case DebuggerX86.REG_BH:\n cch = 2;\n break;\n case DebuggerX86.REG_AX:\n case DebuggerX86.REG_CX:\n case DebuggerX86.REG_DX:\n case DebuggerX86.REG_BX:\n case DebuggerX86.REG_SP:\n case DebuggerX86.REG_BP:\n case DebuggerX86.REG_SI:\n case DebuggerX86.REG_DI:\n case DebuggerX86.REG_IP:\n case DebuggerX86.REG_SEG + DebuggerX86.REG_ES:\n case DebuggerX86.REG_SEG + DebuggerX86.REG_CS:\n case DebuggerX86.REG_SEG + DebuggerX86.REG_SS:\n case DebuggerX86.REG_SEG + DebuggerX86.REG_DS:\n case DebuggerX86.REG_SEG + DebuggerX86.REG_FS:\n case DebuggerX86.REG_SEG + DebuggerX86.REG_GS:\n cch = 4;\n break;\n case DebuggerX86.REG_EAX:\n case DebuggerX86.REG_ECX:\n case DebuggerX86.REG_EDX:\n case DebuggerX86.REG_EBX:\n case DebuggerX86.REG_ESP:\n case DebuggerX86.REG_EBP:\n case DebuggerX86.REG_ESI:\n case DebuggerX86.REG_EDI:\n case DebuggerX86.REG_CR0:\n case DebuggerX86.REG_CR1:\n case DebuggerX86.REG_CR2:\n case DebuggerX86.REG_CR3:\n case DebuggerX86.REG_EIP:\n cch = 8;\n break;\n case DebuggerX86.REG_PS:\n cch = this.cchReg;\n break;\n }\n }\n return cch? Str.toHex(n, cch) : \"??\";\n }\n\n /**\n * getRegValue(iReg)\n *\n * @this {DebuggerX86}\n * @param {number} iReg\n * @return {number|undefined}\n */\n getRegValue(iReg)\n {\n var n;\n if (iReg >= 0) {\n var cpu = this.cpu;\n switch(iReg) {\n case DebuggerX86.REG_AL:\n n = cpu.regEAX & 0xff;\n break;\n case DebuggerX86.REG_CL:\n n = cpu.regECX & 0xff;\n break;\n case DebuggerX86.REG_DL:\n n = cpu.regEDX & 0xff;\n break;\n case DebuggerX86.REG_BL:\n n = cpu.regEBX & 0xff;\n break;\n case DebuggerX86.REG_AH:\n n = (cpu.regEAX >> 8) & 0xff;\n break;\n case DebuggerX86.REG_CH:\n n = (cpu.regECX >> 8) & 0xff;\n break;\n case DebuggerX86.REG_DH:\n n = (cpu.regEDX >> 8) & 0xff;\n break;\n case DebuggerX86.REG_BH:\n n = (cpu.regEBX >> 8) & 0xff;\n break;\n case DebuggerX86.REG_AX:\n n = cpu.regEAX & 0xffff;\n break;\n case DebuggerX86.REG_CX:\n n = cpu.regECX & 0xffff;\n break;\n case DebuggerX86.REG_DX:\n n = cpu.regEDX & 0xffff;\n break;\n case DebuggerX86.REG_BX:\n n = cpu.regEBX & 0xffff;\n break;\n case DebuggerX86.REG_SP:\n n = cpu.getSP() & 0xffff;\n break;\n case DebuggerX86.REG_BP:\n n = cpu.regEBP & 0xffff;\n break;\n case DebuggerX86.REG_SI:\n n = cpu.regESI & 0xffff;\n break;\n case DebuggerX86.REG_DI:\n n = cpu.regEDI & 0xffff;\n break;\n case DebuggerX86.REG_IP:\n n = cpu.getIP() & 0xffff;\n break;\n case DebuggerX86.REG_PS:\n n = cpu.getPS();\n break;\n case DebuggerX86.REG_SEG + DebuggerX86.REG_ES:\n n = cpu.getES();\n break;\n case DebuggerX86.REG_SEG + DebuggerX86.REG_CS:\n n = cpu.getCS();\n break;\n case DebuggerX86.REG_SEG + DebuggerX86.REG_SS:\n n = cpu.getSS();\n break;\n case DebuggerX86.REG_SEG + DebuggerX86.REG_DS:\n n = cpu.getDS();\n break;\n default:\n if (this.cpu.model == X86.MODEL_80286) {\n if (iReg == DebuggerX86.REG_CR0) {\n n = cpu.regCR0;\n }\n }\n else if (I386 && this.cpu.model >= X86.MODEL_80386) {\n switch(iReg) {\n case DebuggerX86.REG_EAX:\n n = cpu.regEAX;\n break;\n case DebuggerX86.REG_ECX:\n n = cpu.regECX;\n break;\n case DebuggerX86.REG_EDX:\n n = cpu.regEDX;\n break;\n case DebuggerX86.REG_EBX:\n n = cpu.regEBX;\n break;\n case DebuggerX86.REG_ESP:\n n = cpu.getSP();\n break;\n case DebuggerX86.REG_EBP:\n n = cpu.regEBP;\n break;\n case DebuggerX86.REG_ESI:\n n = cpu.regESI;\n break;\n case DebuggerX86.REG_EDI:\n n = cpu.regEDI;\n break;\n case DebuggerX86.REG_CR0:\n n = cpu.regCR0;\n break;\n case DebuggerX86.REG_CR1:\n n = cpu.regCR1;\n break;\n case DebuggerX86.REG_CR2:\n n = cpu.regCR2;\n break;\n case DebuggerX86.REG_CR3:\n n = cpu.regCR3;\n break;\n case DebuggerX86.REG_SEG + DebuggerX86.REG_FS:\n n = cpu.getFS();\n break;\n case DebuggerX86.REG_SEG + DebuggerX86.REG_GS:\n n = cpu.getGS();\n break;\n case DebuggerX86.REG_EIP:\n n = cpu.getIP();\n break;\n }\n }\n break;\n }\n }\n return n;\n }\n\n /**\n * replaceRegs(s)\n *\n * @this {DebuggerX86}\n * @param {string} s\n * @return {string}\n */\n replaceRegs(s)\n {\n /*\n * Replace any references first; this means that register references inside the reference\n * do NOT need to be prefixed with '@'.\n */\n s = this.parseReference(s) || s;\n\n /*\n * Replace every @XX (or @XXX), where XX (or XXX) is a register, with the register's value.\n */\n var i = 0;\n var b, sChar, sAddr, dbgAddr, sReplace;\n while ((i = s.indexOf('@', i)) >= 0) {\n var iReg = this.getRegIndex(s, i + 1);\n if (iReg >= 0) {\n s = s.substr(0, i) + this.getRegString(iReg) + s.substr(i + 1 + DebuggerX86.REGS[iReg].length);\n }\n i++;\n }\n /*\n * Replace every #XX, where XX is a hex byte value, with the corresponding ASCII character (if printable).\n */\n i = 0;\n while ((i = s.indexOf('#', i)) >= 0) {\n sChar = s.substr(i+1, 2);\n b = Str.parseInt(sChar, 16);\n if (b != null && b >= 32 && b < 127) {\n sReplace = sChar + \" '\" + String.fromCharCode(b) + \"'\";\n s = s.replace('#' + sChar, sReplace);\n i += sReplace.length;\n continue;\n }\n i++;\n }\n /*\n * Replace every $XXXX:XXXX, where XXXX:XXXX is a segmented address, with the zero-terminated string at that address.\n */\n i = 0;\n while ((i = s.indexOf('$', i)) >= 0) {\n sAddr = s.substr(i+1, 9);\n dbgAddr = this.parseAddr(sAddr);\n if (dbgAddr) {\n sReplace = sAddr + ' \"' + this.getSZ(dbgAddr) + '\"';\n s = s.replace('$' + sAddr, sReplace);\n i += sReplace.length;\n continue;\n }\n i++;\n }\n /*\n * Replace every ^XXXX:XXXX, where XXXX:XXXX is a segmented address, with the FCB filename stored at that address.\n */\n i = 0;\n while ((i = s.indexOf('^', i)) >= 0) {\n sAddr = s.substr(i+1, 9);\n dbgAddr = this.parseAddr(sAddr);\n if (dbgAddr) {\n this.incAddr(dbgAddr);\n sReplace = sAddr + ' \"' + this.getSZ(dbgAddr, 11) + '\"';\n s = s.replace('^' + sAddr, sReplace);\n i += sReplace.length;\n continue;\n }\n i++;\n }\n return s;\n }\n\n /**\n * message(sMessage, fAddress)\n *\n * @this {DebuggerX86}\n * @param {string} sMessage is any caller-defined message string\n * @param {boolean} [fAddress] is true to display the current CS:IP\n */\n message(sMessage, fAddress)\n {\n if (fAddress) {\n sMessage += \" at \" + this.toHexAddr(this.newAddr(this.cpu.getIP(), this.cpu.getCS())) + \" (%\" + Str.toHex(this.cpu.regLIP) + \")\";\n }\n\n if ((this.bitsMessage & Messages.BUFFER) == Messages.BUFFER) {\n this.aMessageBuffer.push(sMessage);\n return;\n }\n\n if (this.sMessagePrev && sMessage == this.sMessagePrev) return;\n this.sMessagePrev = sMessage;\n\n if ((this.bitsMessage & Messages.HALT) == Messages.HALT) {\n this.stopCPU();\n sMessage += \" (cpu halted)\";\n }\n\n this.println(sMessage); // + \" (\" + this.cpu.getCycles() + \" cycles)\"\n\n /*\n * We have no idea what the frequency of println() calls might be; all we know is that they easily\n * screw up the CPU's careful assumptions about cycles per burst. So we call yieldCPU() after every\n * message, to effectively end the current burst and start fresh.\n *\n * TODO: See CPU.calcStartTime() for a discussion of why we might want to call yieldCPU() *before*\n * we display the message.\n */\n if (this.cpu) this.cpu.yieldCPU();\n }\n\n /**\n * messageInt(nInt, addr, fForce)\n *\n * @this {DebuggerX86}\n * @param {number} nInt\n * @param {number} addr (LIP after the \"INT n\" instruction has been fetched but not dispatched)\n * @param {boolean} [fForce] (true if the message should be forced)\n * @return {boolean} true if message generated (which in turn triggers addIntReturn() inside checkIntNotify()), false if not\n */\n messageInt(nInt, addr, fForce)\n {\n var AH, DL;\n var fMessage = fForce;\n\n /*\n * We currently arrive here only because the CPU has already determined that INT messages are enabled,\n * or because the ChipSet's RTC interrupt handler has already determined that INT messages are enabled.\n *\n * But software interrupts are very common, so we generally require additional categories to be enabled;\n * unless the caller has set fForce, we check those additional categories now.\n */\n if (!fMessage) {\n /*\n * Display all software interrupts if CPU messages are enabled (and it's not an \"annoying\" interrupt);\n * note that in some cases, even \"annoying\" interrupts can be turned with an extra message category.\n */\n fMessage = this.messageEnabled(Messages.CPU) && DebuggerX86.INT_ANNOYING.indexOf(nInt) < 0;\n if (!fMessage) {\n /*\n * Alternatively, display this software interrupt if its corresponding message category is enabled.\n */\n var nCategory = DebuggerX86.INT_MESSAGES[nInt];\n if (nCategory) {\n if (this.messageEnabled(nCategory)) {\n fMessage = true;\n } else {\n /*\n * Alternatively, display this FDC interrupt if HDC messages are enabled (since they share\n * a common software interrupt). Normally, an HDC BIOS will copy the original DISK (0x13)\n * vector to the ALT_DISK (0x40) vector, but it's a nuisance having to check different\n * interrupts in different configurations for the same frickin' functionality, so we don't.\n */\n fMessage = (nCategory == Messages.FDC && this.messageEnabled(nCategory = Messages.HDC));\n }\n }\n }\n }\n if (fMessage) {\n AH = (this.cpu.regEAX >> 8) & 0xff;\n DL = this.cpu.regEDX & 0xff;\n if (nInt == Interrupts.DOS /* 0x21 */ && AH == 0x0b ||\n nCategory == Messages.FDC && DL >= 0x80 || nCategory == Messages.HDC && DL < 0x80) {\n fMessage = false;\n }\n }\n if (fMessage) {\n var aFuncs = Interrupts.FUNCS[nInt];\n var sFunc = (aFuncs && aFuncs[AH]) || \"\";\n if (sFunc) sFunc = ' ' + this.replaceRegs(sFunc);\n /*\n * For display purposes only, rewind addr to the address of the responsible \"INT n\" instruction;\n * we know it's the two-byte \"INT n\" instruction because that's the only opcode handler that calls\n * checkIntNotify() at the moment.\n */\n addr -= 2;\n this.message(\"INT \" + Str.toHexByte(nInt) + \": AH=\" + Str.toHexByte(AH) + \" at \" + this.toHexOffset(addr - this.cpu.segCS.base, this.cpu.getCS()) + sFunc);\n }\n return fMessage;\n }\n\n /**\n * messageIntReturn(nInt, nLevel, nCycles)\n *\n * @this {DebuggerX86}\n * @param {number} nInt\n * @param {number} nLevel\n * @param {number} nCycles\n * @param {string} [sResult]\n */\n messageIntReturn(nInt, nLevel, nCycles, sResult)\n {\n this.message(\"INT \" + Str.toHexByte(nInt) + \": C=\" + (this.cpu.getCF()? 1 : 0) + (sResult || \"\") + \" (cycles=\" + nCycles + (nLevel? \",level=\" + (nLevel+1) : \"\") + ')');\n }\n\n /**\n * messageIO(component, port, bOut, addrFrom, name, bIn, bitsMessage)\n *\n * @this {DebuggerX86}\n * @param {Component} component\n * @param {number} port\n * @param {number|null} bOut if an output operation\n * @param {number|null} [addrFrom]\n * @param {string|null} [name] of the port, if any\n * @param {number|null} [bIn] is the input value, if known, on an input operation\n * @param {number} [bitsMessage] is one or more Messages category flag(s)\n */\n messageIO(component, port, bOut, addrFrom, name, bIn, bitsMessage)\n {\n bitsMessage |= Messages.PORT;\n if (!name) bitsMessage |= Messages.WARN; // we don't want to see \"unknown\" I/O messages unless WARN is enabled\n if (addrFrom == null || (this.bitsMessage & bitsMessage) == bitsMessage) {\n var selFrom = null;\n if (addrFrom != null) {\n selFrom = this.cpu.getCS();\n addrFrom -= this.cpu.segCS.base;\n }\n this.message(component.idComponent + '.' + (bOut != null? \"outPort\" : \"inPort\") + '(' + Str.toHexWord(port) + ',' + (name? name : \"unknown\") + (bOut != null? ',' + Str.toHexByte(bOut) : \"\") + ')' + (bIn != null? (\": \" + Str.toHexByte(bIn)) : \"\") + (addrFrom != null? (\" at \" + this.toHexOffset(addrFrom, selFrom)) : \"\"));\n }\n }\n\n /**\n * init()\n *\n * @this {DebuggerX86}\n */\n init()\n {\n this.println(\"Type ? for help with PCx86 Debugger commands\");\n this.updateStatus();\n if (this.sCommandsInit) {\n var sCommands = this.sCommandsInit;\n this.sCommandsInit = null;\n this.doCommands(sCommands);\n }\n }\n\n /**\n * historyInit(fQuiet)\n *\n * This function is intended to be called by the constructor, reset(), addBreakpoint(), findBreakpoint()\n * and any other function that changes the checksEnabled() criteria used to decide whether checkInstruction()\n * should be called.\n *\n * That is, if the history arrays need to be allocated and haven't already been allocated, then allocate them,\n * and if the arrays are no longer needed, then deallocate them.\n *\n * @this {DebuggerX86}\n * @param {boolean} [fQuiet]\n */\n historyInit(fQuiet)\n {\n var i;\n if (!this.checksEnabled()) {\n if (this.aOpcodeHistory && this.aOpcodeHistory.length && !fQuiet) {\n this.println(\"instruction history buffer freed\");\n }\n this.iOpcodeHistory = 0;\n this.aOpcodeHistory = [];\n this.aaOpcodeCounts = [];\n return;\n }\n if (!this.aOpcodeHistory || !this.aOpcodeHistory.length) {\n this.aOpcodeHistory = new Array(DebuggerX86.HISTORY_LIMIT);\n for (i = 0; i < this.aOpcodeHistory.length; i++) {\n /*\n * Preallocate dummy Addr (Array) objects in every history slot, so that\n * checkInstruction() doesn't need to call newAddr() on every slot update.\n */\n this.aOpcodeHistory[i] = this.newAddr();\n }\n this.iOpcodeHistory = 0;\n if (!fQuiet) {\n this.println(\"instruction history buffer allocated\");\n }\n }\n if (!this.aaOpcodeCounts || !this.aaOpcodeCounts.length) {\n this.aaOpcodeCounts = new Array(256);\n for (i = 0; i < this.aaOpcodeCounts.length; i++) {\n this.aaOpcodeCounts[i] = [i, 0];\n }\n }\n }\n\n /**\n * startCPU(fUpdateFocus, fQuiet)\n *\n * @this {DebuggerX86}\n * @param {boolean} [fUpdateFocus]\n * @param {boolean} [fQuiet]\n * @return {boolean} true if run request successful, false if not\n */\n startCPU(fUpdateFocus, fQuiet)\n {\n if (this.checkCPU(fQuiet)) {\n return this.cpu.startCPU(fUpdateFocus, fQuiet);\n }\n return false;\n }\n\n /**\n * stepCPU(nCycles, fRegs, fUpdateCPU)\n *\n * @this {DebuggerX86}\n * @param {number} nCycles (0 for one instruction without checking breakpoints)\n * @param {boolean} [fRegs] is true to display registers after step (default is false)\n * @param {boolean} [fUpdateCPU] is false to disable calls to updateCPU() (default is true)\n * @return {boolean}\n */\n stepCPU(nCycles, fRegs, fUpdateCPU)\n {\n if (!this.checkCPU()) return false;\n\n this.nCycles = 0;\n do {\n if (!nCycles) {\n /*\n * When single-stepping, the CPU won't call checkInstruction(), which is good for\n * avoiding breakpoints, but bad for instruction data collection if checks are enabled.\n * So we call checkInstruction() ourselves.\n */\n if (this.checksEnabled()) this.checkInstruction(this.cpu.regLIP, 0);\n }\n /*\n * For our typically tiny bursts (usually single instructions), mimic what runCPU() does.\n */\n try {\n var nCyclesStep = this.cpu.stepCPU(nCycles);\n if (nCyclesStep > 0) {\n this.nCycles += nCyclesStep;\n this.cpu.addCycles(nCyclesStep, true);\n this.cpu.updateChecksum(nCyclesStep);\n this.cOpcodes++;\n }\n }\n catch(exception) {\n if (typeof exception != \"number\") {\n var e = exception;\n this.nCycles = 0;\n this.cpu.setError(e.stack || e.message);\n }\n }\n } while (this.cpu.opFlags & X86.OPFLAG_PREFIXES);\n\n /*\n * Because we called cpu.stepCPU() and not cpu.startCPU(), we must nudge the cpu's update code,\n * and then update our own state. Normally, the only time fUpdateCPU will be false is when doTrace()\n * is calling us in a loop, in which case it will perform its own updateCPU() when it's done.\n */\n if (fUpdateCPU !== false) this.cpu.updateCPU();\n\n this.updateStatus(fRegs || false);\n return (this.nCycles > 0);\n }\n\n /**\n * stopCPU()\n *\n * @this {DebuggerX86}\n * @param {boolean} [fComplete]\n * @return {boolean}\n */\n stopCPU(fComplete)\n {\n return this.cpu && this.cpu.stopCPU(fComplete) || false;\n }\n\n /**\n * updateStatus(fRegs)\n *\n * @this {DebuggerX86}\n * @param {boolean} [fRegs] (default is true)\n */\n updateStatus(fRegs)\n {\n if (fRegs === undefined) fRegs = true;\n\n this.dbgAddrNextCode = this.newAddr(this.cpu.getIP(), this.cpu.getCS());\n /*\n * this.nStep used to be a simple boolean, but now it's 0 (or undefined)\n * if inactive, 1 if stepping over an instruction without a register dump, or 2\n * if stepping over an instruction with a register dump.\n */\n if (!fRegs || this.nStep == 1)\n this.doUnassemble();\n else {\n this.doRegisters();\n }\n }\n\n /**\n * checkCPU(fQuiet)\n *\n * Make sure the CPU is ready (finished initializing), not busy (already running), and not in an error state.\n *\n * @this {DebuggerX86}\n * @param {boolean} [fQuiet]\n * @return {boolean}\n */\n checkCPU(fQuiet)\n {\n if (!this.cpu || !this.cpu.isReady() || !this.cpu.isPowered() || this.cpu.isRunning()) {\n if (!fQuiet) this.println(\"cpu busy or unavailable, command ignored\");\n return false;\n }\n return !this.cpu.isError();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {DebuggerX86}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n /*\n * Because Debugger save/restore support is somewhat limited (and didn't always exist),\n * we deviate from the typical save/restore design pattern: instead of reset OR restore,\n * we always reset and then perform a (potentially limited) restore.\n */\n this.reset(true);\n\n // this.println(data? \"resuming\" : \"powering up\");\n\n if (data && this.restore) {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {DebuggerX86}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean}\n */\n powerDown(fSave, fShutdown)\n {\n if (fShutdown) this.println(fSave? \"suspending\" : \"shutting down\");\n return fSave? this.save() : true;\n }\n\n /**\n * reset(fQuiet)\n *\n * This is a notification handler, called by the Computer, to inform us of a reset.\n *\n * @this {DebuggerX86}\n * @param {boolean} fQuiet (true only when called from our own powerUp handler)\n */\n reset(fQuiet)\n {\n this.historyInit();\n this.cOpcodes = this.cOpcodesStart = 0;\n this.sMessagePrev = null;\n this.nCycles = 0;\n this.dbgAddrNextCode = this.newAddr(this.cpu.getIP(), this.cpu.getCS());\n this.clearTempBreakpoint();\n if (!fQuiet && !this.flags.running) this.updateStatus();\n }\n\n /**\n * save()\n *\n * This implements (very rudimentary) save support for the Debugger component.\n *\n * @this {DebuggerX86}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.packAddr(this.dbgAddrNextCode));\n state.set(1, this.packAddr(this.dbgAddrNextData));\n state.set(2, this.packAddr(this.dbgAddrAssemble));\n state.set(3, [this.aPrevCmds, this.fAssemble, this.bitsMessage]);\n state.set(4, this.aSymbolTable);\n state.set(5, [this.aBreakExec, this.aBreakRead, this.aBreakWrite]);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements (very rudimentary) restore support for the Debugger component.\n *\n * @this {DebuggerX86}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var i = 0;\n if (data[i]) this.dbgAddrNextCode = this.unpackAddr(data[i++]);\n /*\n * dbgAddrNextData wasn't saved until there were at least 6 elements, hence the check for data[5] instead of data[i]\n */\n if (data[5]) this.dbgAddrNextData = this.unpackAddr(data[i++]);\n if (data[i]) this.dbgAddrAssemble = this.unpackAddr(data[i++]);\n if (data[i]) {\n this.aPrevCmds = data[i][0];\n if (typeof this.aPrevCmds == \"string\") this.aPrevCmds = [this.aPrevCmds];\n this.fAssemble = data[i][1];\n var bits = data[i][2];\n /*\n * We supplement the message bits only the incoming bits adhere to the new format (ie, if bits exist in both the high\n * nibble and one of the low nibbles).\n */\n if ((bits & 0xf0000000) && (bits & 0x0fffffff)) {\n this.bitsMessage |= bits; // include any saved message bits ONLY if they match our new format (ie, bits in both high and low nibbles)\n }\n i++;\n }\n if (data[i]) {\n this.aSymbolTable = data[i++];\n }\n if (data[i]) {\n this.restoreBreakpoints(this.aBreakExec, data[i][0]);\n this.restoreBreakpoints(this.aBreakRead, data[i][1]);\n this.restoreBreakpoints(this.aBreakWrite, data[i][2]);\n }\n return true;\n }\n\n /**\n * start(ms, nCycles)\n *\n * This is a notification handler, called by the Computer, to inform us the CPU has started.\n *\n * @this {DebuggerX86}\n * @param {number} ms\n * @param {number} nCycles\n */\n start(ms, nCycles)\n {\n if (!this.nStep) this.println(\"running\");\n this.flags.running = true;\n this.msStart = ms;\n this.nCyclesStart = nCycles;\n }\n\n /**\n * stop(ms, nCycles)\n *\n * This is a notification handler, called by the Computer, to inform us the CPU has now stopped.\n *\n * @this {DebuggerX86}\n * @param {number} ms\n * @param {number} nCycles\n */\n stop(ms, nCycles)\n {\n if (this.flags.running) {\n this.flags.running = false;\n this.nCycles = nCycles - this.nCyclesStart;\n if (!this.nStep) {\n var sStopped = \"stopped\";\n if (this.nCycles) {\n var msTotal = ms - this.msStart;\n var nCyclesPerSecond = (msTotal > 0? Math.round(this.nCycles * 1000 / msTotal) : 0);\n sStopped += \" (\";\n if (this.checksEnabled()) {\n sStopped += this.cOpcodes + \" opcodes, \";\n /*\n * $ops displays progress by calculating cOpcodes - cOpcodesStart, so before\n * zeroing cOpcodes, we should subtract cOpcodes from cOpcodesStart (since we're\n * effectively subtracting cOpcodes from cOpcodes as well).\n */\n this.cOpcodesStart -= this.cOpcodes;\n this.cOpcodes = 0;\n }\n sStopped += this.nCycles + \" cycles, \" + msTotal + \" ms, \" + nCyclesPerSecond + \" hz)\";\n if (MAXDEBUG && this.chipset) {\n var i, c, n;\n for (i = 0; i < this.chipset.acInterrupts.length; i++) {\n c = this.chipset.acInterrupts[i];\n if (!c) continue;\n n = c / Math.round(msTotal / 1000);\n this.println(\"IRQ\" + i + \": \" + c + \" interrupts (\" + n + \" per sec)\");\n this.chipset.acInterrupts[i] = 0;\n }\n for (i = 0; i < this.chipset.acTimersFired.length; i++) {\n c = this.chipset.acTimersFired[i];\n if (!c) continue;\n n = c / Math.round(msTotal / 1000);\n this.println(\"TIMER\" + i + \": \" + c + \" fires (\" + n + \" per sec)\");\n this.chipset.acTimersFired[i] = 0;\n }\n n = 0;\n for (i = 0; i < this.chipset.acTimer0Counts.length; i++) {\n var a = this.chipset.acTimer0Counts[i];\n n += a[0];\n this.println(\"TIMER0 update #\" + i + \": [\" + a[0] + ',' + a[1] + ',' + a[2] + ']');\n }\n this.chipset.acTimer0Counts = [];\n }\n } else {\n if (this.messageEnabled(Messages.HALT)) {\n /*\n * It's possible the user is trying to 'g' past a fault that was blocked by helpCheckFault()\n * for the Debugger's benefit; if so, it will continue to be blocked, so try displaying a helpful\n * message (another helpful tip would be to simply turn off the \"halt\" message category).\n */\n sStopped += \" (use the 't' command to execute blocked faults)\";\n }\n }\n this.println(sStopped);\n }\n this.updateStatus(true);\n this.updateFocus();\n this.clearTempBreakpoint(this.cpu.regLIP);\n }\n }\n\n /**\n * checksEnabled(fRelease)\n *\n * This \"check\" function is called by the CPU; we indicate whether or not every instruction needs to be checked.\n *\n * Originally, this returned true even when there were only read and/or write breakpoints, but those breakpoints\n * no longer require the intervention of checkInstruction(); the Bus component automatically swaps in/out appropriate\n * \"checked\" Memory access functions to deal with those breakpoints in the corresponding Memory blocks. So I've\n * simplified the test below.\n *\n * @this {DebuggerX86}\n * @param {boolean} [fRelease] is true for release criteria only; default is false (any criteria)\n * @return {boolean} true if every instruction needs to pass through checkInstruction(), false if not\n */\n checksEnabled(fRelease)\n {\n return ((DEBUG && !fRelease)? true : (this.aBreakExec.length > 1 || !!this.nBreakIns || this.messageEnabled(Messages.INT) /* || this.aBreakRead.length > 1 || this.aBreakWrite.length > 1 */));\n }\n\n /**\n * checkInstruction(addr, nState)\n *\n * This \"check\" function is called by the CPU to inform us about the next instruction to be executed,\n * giving us an opportunity to look for \"exec\" breakpoints and update opcode frequencies and instruction history.\n *\n * @this {DebuggerX86}\n * @param {number} addr\n * @param {number} nState is < 0 if stepping, 0 if starting, or > 0 if running\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkInstruction(addr, nState)\n {\n var cpu = this.cpu;\n\n if (nState > 0) {\n if (this.nBreakIns && !--this.nBreakIns) {\n return true;\n }\n if (this.checkBreakpoint(addr, 1, this.aBreakExec)) {\n return true;\n }\n /*\n * Halt if running with interrupts disabled and IOPL < CPL, because that's likely an error\n */\n if (MAXDEBUG && !(cpu.regPS & X86.PS.IF) && cpu.nIOPL < cpu.nCPL) {\n this.printMessage(\"interrupts disabled at IOPL \" + cpu.nIOPL + \" and CPL \" + cpu.nCPL, true);\n return true;\n }\n }\n\n /*\n * The rest of the instruction tracking logic can only be performed if historyInit() has allocated the\n * necessary data structures. Note that there is no explicit UI for enabling/disabling history, other than\n * adding/removing breakpoints, simply because it's breakpoints that trigger the call to checkInstruction();\n * well, OK, and a few other things now, like enabling Messages.INT messages.\n */\n if (nState >= 0 && this.aaOpcodeCounts.length) {\n this.cOpcodes++;\n var bOpcode = cpu.probeAddr(addr);\n if (bOpcode != null) {\n this.aaOpcodeCounts[bOpcode][1]++;\n var dbgAddr = this.aOpcodeHistory[this.iOpcodeHistory];\n this.setAddr(dbgAddr, cpu.getIP(), cpu.getCS());\n dbgAddr.cycleCount = cpu.getCycles();\n if (++this.iOpcodeHistory == this.aOpcodeHistory.length) this.iOpcodeHistory = 0;\n }\n }\n return false;\n }\n\n /**\n * checkMemoryRead(addr, nb)\n *\n * This \"check\" function is called by a Memory block to inform us that a memory read occurred, giving us an\n * opportunity to track the read if we want, and look for a matching \"read\" breakpoint, if any.\n *\n * In the \"old days\", it would be an error for this call to fail to find a matching Debugger breakpoint, but now\n * Memory blocks have no idea whether the Debugger or the machine's Debug register(s) triggered this \"checked\" read.\n *\n * If we return true, we \"trump\" the machine's Debug register(s); false allows normal Debug register processing.\n *\n * @this {DebuggerX86}\n * @param {number} addr\n * @param {number} [nb] (# of bytes; default is 1)\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkMemoryRead(addr, nb)\n {\n if (this.checkBreakpoint(addr, nb || 1, this.aBreakRead)) {\n this.stopCPU(true);\n return true;\n }\n return false;\n }\n\n /**\n * checkMemoryWrite(addr, nb)\n *\n * This \"check\" function is called by a Memory block to inform us that a memory write occurred, giving us an\n * opportunity to track the write if we want, and look for a matching \"write\" breakpoint, if any.\n *\n * In the \"old days\", it would be an error for this call to fail to find a matching Debugger breakpoint, but now\n * Memory blocks have no idea whether the Debugger or the machine's Debug register(s) triggered this \"checked\" write.\n *\n * If we return true, we \"trump\" the machine's Debug register(s); false allows normal Debug register processing.\n *\n * @this {DebuggerX86}\n * @param {number} addr\n * @param {number} [nb] (# of bytes; default is 1)\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkMemoryWrite(addr, nb)\n {\n if (this.checkBreakpoint(addr, nb || 1, this.aBreakWrite)) {\n this.stopCPU(true);\n return true;\n }\n return false;\n }\n\n /**\n * checkPortInput(port, size, data)\n *\n * This \"check\" function is called by the Bus component to inform us that port input occurred.\n *\n * @this {DebuggerX86}\n * @param {number} port\n * @param {number} size\n * @param {number} data\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkPortInput(port, size, data)\n {\n /*\n * We trust that the Bus component won't call us unless we told it to, so we halt unconditionally\n */\n this.println(\"break on input from port \" + Str.toHexWord(port) + \": \" + Str.toHex(data));\n this.stopCPU(true);\n return true;\n }\n\n /**\n * checkPortOutput(port, size, data)\n *\n * This \"check\" function is called by the Bus component to inform us that port output occurred.\n *\n * @this {DebuggerX86}\n * @param {number} port\n * @param {number} size\n * @param {number} data\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkPortOutput(port, size, data)\n {\n /*\n * We trust that the Bus component won't call us unless we told it to, so we halt unconditionally\n */\n this.println(\"break on output to port \" + Str.toHexWord(port) + \": \" + Str.toHex(data));\n this.stopCPU(true);\n return true;\n }\n\n /**\n * clearBreakpoints()\n *\n * @this {DebuggerX86}\n */\n clearBreakpoints()\n {\n var i, dbgAddr;\n this.aBreakExec = [\"bp\"];\n if (this.aBreakRead !== undefined) {\n for (i = 1; i < this.aBreakRead.length; i++) {\n dbgAddr = this.aBreakRead[i];\n this.cpu.removeMemBreak(this.getAddr(dbgAddr), false, dbgAddr.type == DebuggerX86.ADDRTYPE.PHYSICAL);\n }\n }\n this.aBreakRead = [\"br\"];\n if (this.aBreakWrite !== undefined) {\n for (i = 1; i < this.aBreakWrite.length; i++) {\n dbgAddr = this.aBreakWrite[i];\n this.cpu.removeMemBreak(this.getAddr(dbgAddr), true, dbgAddr.type == DebuggerX86.ADDRTYPE.PHYSICAL);\n }\n }\n this.aBreakWrite = [\"bw\"];\n /*\n * nSuppressBreaks ensures we can't get into an infinite loop where a breakpoint lookup requires\n * reading a segment descriptor via getSegment(), and that triggers more memory reads, which triggers\n * more breakpoint checks.\n */\n this.nSuppressBreaks = 0;\n }\n\n /**\n * addBreakpoint(aBreak, dbgAddr, fTempBreak, fQuiet)\n *\n * In case you haven't already figured this out, all our breakpoint commands use the address\n * to identify a breakpoint, not an incrementally assigned breakpoint index like other debuggers;\n * see doBreak() for details.\n *\n * This has a few implications, one being that you CANNOT set more than one kind of breakpoint\n * on a single address. In practice, that's rarely a problem, because you can almost always set\n * a different breakpoint on a neighboring address.\n *\n * Also, there is one exception to the \"one address, one breakpoint\" rule, and that involves\n * temporary breakpoints (ie, one-time execution breakpoints that either a \"p\" or \"g\" command\n * may create to step over a chunk of code). Those breakpoints automatically clear themselves,\n * so there usually isn't any need to refer to them using breakpoint commands.\n *\n * TODO: Consider supporting the more \"traditional\" breakpoint index syntax; the current\n * address-based syntax was implemented solely for expediency and consistency. At the same time,\n * also consider a more WDEB386-like syntax, where \"br\" is used to set a variety of access-specific\n * breakpoints, using modifiers like \"r1\", \"r2\", \"w1\", \"w2, etc.\n *\n * @this {DebuggerX86}\n * @param {Array} aBreak\n * @param {DbgAddrX86} dbgAddr\n * @param {boolean} [fTempBreak]\n * @param {boolean} [fQuiet]\n * @return {boolean} true if breakpoint added, false if already exists\n */\n addBreakpoint(aBreak, dbgAddr, fTempBreak, fQuiet)\n {\n var fSuccess = true;\n\n // this.nSuppressBreaks++;\n\n /*\n * Instead of complaining that a breakpoint already exists (as we used to do), we now\n * allow breakpoints to be re-set; this makes it easier to update any commands that may\n * be associated with the breakpoint.\n *\n * The only exception: we DO allow a temporary breakpoint at an address where there may\n * already be a breakpoint, so that you can easily step (\"p\" or \"g\") over such addresses.\n */\n if (!fTempBreak) {\n this.findBreakpoint(aBreak, dbgAddr, true, false, true);\n }\n\n if (aBreak != this.aBreakExec) {\n var addr = this.getAddr(dbgAddr);\n if (addr === X86.ADDR_INVALID) {\n this.println(\"invalid address: \" + this.toHexAddr(dbgAddr));\n fSuccess = false;\n } else {\n this.cpu.addMemBreak(addr, aBreak == this.aBreakWrite, dbgAddr.type == DebuggerX86.ADDRTYPE.PHYSICAL);\n }\n }\n\n if (fSuccess) {\n aBreak.push(dbgAddr);\n if (fTempBreak) {\n /*\n * Force temporary breakpoints to use their linear address, if one is available, by zapping\n * the selector; this allows us to step over calls or interrupts that change the processor mode.\n *\n * TODO: Unfortunately, this will fail to \"step\" over a call in segment that moves during the call;\n * consider alternatives.\n */\n if (dbgAddr.addr != null) dbgAddr.sel = null;\n dbgAddr.fTempBreak = true;\n }\n else {\n if (!fQuiet) this.printBreakpoint(aBreak, aBreak.length-1, \"set\");\n this.historyInit();\n }\n }\n\n // this.nSuppressBreaks--;\n\n return fSuccess;\n }\n\n /**\n * findBreakpoint(aBreak, dbgAddr, fRemove, fTempBreak, fQuiet)\n *\n * @this {DebuggerX86}\n * @param {Array} aBreak\n * @param {DbgAddrX86} dbgAddr\n * @param {boolean} [fRemove]\n * @param {boolean} [fTempBreak]\n * @param {boolean} [fQuiet]\n * @return {boolean} true if found, false if not\n */\n findBreakpoint(aBreak, dbgAddr, fRemove, fTempBreak, fQuiet)\n {\n var fFound = false;\n var addr = this.mapBreakpoint(this.getAddr(dbgAddr));\n for (var i = 1; i < aBreak.length; i++) {\n var dbgAddrBreak = aBreak[i];\n if (addr !== X86.ADDR_INVALID && addr == this.mapBreakpoint(this.getAddr(dbgAddrBreak)) ||\n addr === X86.ADDR_INVALID && dbgAddr.sel == dbgAddrBreak.sel && dbgAddr.off == dbgAddrBreak.off) {\n if (!fTempBreak || dbgAddrBreak.fTempBreak) {\n fFound = true;\n if (fRemove) {\n if (!dbgAddrBreak.fTempBreak && !fQuiet) {\n this.printBreakpoint(aBreak, i, \"cleared\");\n }\n aBreak.splice(i, 1);\n if (aBreak != this.aBreakExec) {\n this.cpu.removeMemBreak(addr, aBreak == this.aBreakWrite, dbgAddrBreak.type == DebuggerX86.ADDRTYPE.PHYSICAL);\n }\n /*\n * We'll mirror the logic in addBreakpoint() and leave the history buffer alone if this\n * was a temporary breakpoint.\n */\n if (!dbgAddrBreak.fTempBreak) {\n this.historyInit();\n }\n break;\n }\n if (!fQuiet) this.printBreakpoint(aBreak, i, \"exists\");\n break;\n }\n }\n }\n return fFound;\n }\n\n /**\n * listBreakpoints(aBreak)\n *\n * @this {DebuggerX86}\n * @param {Array} aBreak\n * @return {number} of breakpoints listed, 0 if none\n */\n listBreakpoints(aBreak)\n {\n for (var i = 1; i < aBreak.length; i++) {\n this.printBreakpoint(aBreak, i);\n }\n return aBreak.length - 1;\n }\n\n /**\n * printBreakpoint(aBreak, i, sAction)\n *\n * TODO: We may need to start printing linear addresses also (if any), because segmented address can be ambiguous.\n *\n * @this {DebuggerX86}\n * @param {Array} aBreak\n * @param {number} i\n * @param {string} [sAction]\n */\n printBreakpoint(aBreak, i, sAction)\n {\n var dbgAddr = aBreak[i];\n this.println(aBreak[0] + ' ' + this.toHexAddr(dbgAddr) + (sAction? (' ' + sAction) : (dbgAddr.sCmd? (' \"' + dbgAddr.sCmd + '\"') : '')));\n }\n\n /**\n * restoreBreakpoints(aBreak, aDbgAddr)\n *\n * @this {DebuggerX86}\n * @param {Array} aBreak\n * @param {Array} aDbgAddr\n */\n restoreBreakpoints(aBreak, aDbgAddr)\n {\n if (aDbgAddr[0] != aBreak[0]) return;\n for (var i = 1; i < aDbgAddr.length; i++) {\n var dbgAddr = aDbgAddr[i];\n this.addBreakpoint(aBreak, dbgAddr, dbgAddr.fTempBreak, true);\n }\n }\n\n /**\n * setTempBreakpoint(dbgAddr)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr of new temp breakpoint\n */\n setTempBreakpoint(dbgAddr)\n {\n this.addBreakpoint(this.aBreakExec, dbgAddr, true);\n }\n\n /**\n * clearTempBreakpoint(addr)\n *\n * @this {DebuggerX86}\n * @param {number|undefined} [addr] clear all temp breakpoints if no address specified\n */\n clearTempBreakpoint(addr)\n {\n if (addr !== undefined) {\n this.checkBreakpoint(addr, 1, this.aBreakExec, true);\n this.nStep = 0;\n } else {\n for (var i = 1; i < this.aBreakExec.length; i++) {\n var dbgAddrBreak = this.aBreakExec[i];\n if (dbgAddrBreak.fTempBreak) {\n if (!this.findBreakpoint(this.aBreakExec, dbgAddrBreak, true, true)) break;\n i = 0;\n }\n }\n }\n }\n\n /**\n * mapBreakpoint(addr)\n *\n * @this {DebuggerX86}\n * @param {number} addr\n * @return {number}\n */\n mapBreakpoint(addr)\n {\n /*\n * Map addresses in the top 64Kb at the top of the address space (assuming either a 16Mb or 4Gb\n * address space) to the top of the 1Mb range.\n *\n * The fact that those two 64Kb regions are aliases of each other on an 80286 is a pain in the BUTT,\n * because any CS-based breakpoint you set immediately after a CPU reset will have a physical address\n * in the top 16Mb, yet after the first inter-segment JMP, you will be running in the first 1Mb.\n */\n if (addr !== X86.ADDR_INVALID) {\n var mask = (this.maskAddr & ~0xffff);\n if ((addr & mask) == mask) addr &= 0x000fffff;\n }\n return addr;\n }\n\n /**\n * checkBreakpoint(addr, nb, aBreak, fTempBreak)\n *\n * @this {DebuggerX86}\n * @param {number} addr\n * @param {number} nb (# of bytes)\n * @param {Array} aBreak\n * @param {boolean} [fTempBreak]\n * @return {boolean} true if breakpoint has been hit, false if not\n */\n checkBreakpoint(addr, nb, aBreak, fTempBreak)\n {\n /*\n * Time to check for execution breakpoints; note that this should be done BEFORE updating frequency\n * or history data (see checkInstruction), since we might not actually execute the current instruction.\n */\n var fBreak = false;\n\n if (!this.nSuppressBreaks++) {\n\n addr = this.mapBreakpoint(addr);\n\n /*\n * As discussed in opINT3(), I decided to check for INT3 instructions here: we'll tell the CPU to\n * stop on INT3 whenever both the INT and HALT message bits are set; a simple \"g\" command allows you\n * to continue.\n */\n if (this.messageEnabled(Messages.INT | Messages.HALT)) {\n if (this.cpu.probeAddr(addr) == X86.OPCODE.INT3) {\n fBreak = true;\n }\n }\n\n for (var i = 1; !fBreak && i < aBreak.length; i++) {\n\n var dbgAddrBreak = aBreak[i];\n\n if (fTempBreak && !dbgAddrBreak.fTempBreak) continue;\n\n /*\n * We need to zap the linear address field of the breakpoint address before\n * calling getAddr(), to force it to recalculate the linear address every time,\n * unless this is a breakpoint on a linear address (as indicated by a null sel).\n */\n if (dbgAddrBreak.sel != null) dbgAddrBreak.addr = null;\n\n /*\n * We used to calculate the linear address of the breakpoint at the time the\n * breakpoint was added, so that a breakpoint set in one mode (eg, in real-mode)\n * would still work as intended if the mode changed later (eg, to protected-mode).\n *\n * However, that created difficulties setting protected-mode breakpoints in segments\n * that might not be defined yet, or that could move in physical memory.\n *\n * If you want to create a real-mode breakpoint that will break regardless of mode,\n * use the physical address of the real-mode memory location instead.\n */\n var addrBreak = this.mapBreakpoint(this.getAddr(dbgAddrBreak));\n for (var n = 0; n < nb; n++) {\n if (addr + n == addrBreak) {\n var a;\n fBreak = true;\n if (dbgAddrBreak.fTempBreak) {\n this.findBreakpoint(aBreak, dbgAddrBreak, true, true);\n fTempBreak = true;\n }\n if (a = dbgAddrBreak.aCmds) {\n /*\n * When one or more commands are attached to a breakpoint, we don't halt by default.\n * Instead, we set fBreak to true only if, at the completion of all the commands, the\n * CPU is halted; in other words, you should include \"h\" as one of the breakpoint commands\n * if you want the breakpoint to stop execution.\n *\n * Another useful command is \"if\", which will return false if the expression is false,\n * at which point we'll jump ahead to the next \"else\" command, and if there isn't an \"else\",\n * we abort.\n */\n fBreak = false;\n for (var j = 0; j < a.length; j++) {\n if (!this.doCommand(a[j], true)) {\n if (a[j].indexOf(\"if\")) {\n fBreak = true; // the failed command wasn't \"if\", so abort\n break;\n }\n var k = j + 1;\n for (; k < a.length; k++) {\n if (!a[k].indexOf(\"else\")) break;\n j++;\n }\n if (k == a.length) { // couldn't find an \"else\" after the \"if\", so abort\n fBreak = true;\n break;\n }\n /*\n * If we're still here, we'll execute the \"else\" command (which is just a no-op),\n * followed by any remaining commands.\n */\n }\n }\n if (!this.cpu.isRunning()) fBreak = true;\n }\n if (fBreak) {\n if (!fTempBreak) this.printBreakpoint(aBreak, i, \"hit\");\n break;\n }\n }\n }\n }\n }\n\n this.nSuppressBreaks--;\n\n return fBreak;\n }\n\n /**\n * getInstruction(dbgAddr, sComment, nSequence)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {string} [sComment] is an associated comment\n * @param {number|null} [nSequence] is an associated sequence number, null or undefined if none\n * @return {string} (and dbgAddr is updated to the next instruction)\n */\n getInstruction(dbgAddr, sComment, nSequence)\n {\n var dbgAddrIns = this.newAddr(dbgAddr.off, dbgAddr.sel, dbgAddr.addr, dbgAddr.type);\n\n var bOpcode = this.getByte(dbgAddr, 1);\n\n /*\n * Incorporate OPERAND and ADDRESS size prefixes into the current instruction.\n *\n * And the verdict is in: redundant OPERAND and ADDRESS prefixes must be ignored;\n * see opOS() and opAS() for details. We limit the amount of redundancy to something\n * reasonable (ie, 4).\n */\n var cMaxOverrides = 4, cOverrides = 0;\n var fDataPrefix = false, fAddrPrefix = false;\n\n while ((bOpcode == X86.OPCODE.OS || bOpcode == X86.OPCODE.AS) && cMaxOverrides--) {\n if (bOpcode == X86.OPCODE.OS) {\n if (!fDataPrefix) {\n dbgAddr.fData32 = !dbgAddr.fData32;\n fDataPrefix = true;\n }\n cOverrides++;\n } else {\n if (!fAddrPrefix) {\n dbgAddr.fAddr32 = !dbgAddr.fAddr32;\n fAddrPrefix = true;\n }\n cOverrides++;\n }\n bOpcode = this.getByte(dbgAddr, 1);\n }\n\n var bModRM = -1;\n var asOpcodes = DebuggerX86.INS_NAMES;\n var aOpDesc = this.aaOpDescs[bOpcode];\n var iIns = aOpDesc[0];\n\n if (iIns == DebuggerX86.INS.OP0F) {\n var b = this.getByte(dbgAddr, 1);\n aOpDesc = DebuggerX86.aaOp0FDescs[b] || DebuggerX86.aOpDescUndefined;\n bOpcode |= (b << 8);\n iIns = aOpDesc[0];\n }\n\n if (iIns == DebuggerX86.INS.ESC) {\n bModRM = this.getByte(dbgAddr, 1);\n var aOpFPUDesc = this.getFPUInstruction(bOpcode, bModRM);\n if (aOpFPUDesc) {\n asOpcodes = DebuggerX86.FINS_NAMES;\n aOpDesc = aOpFPUDesc;\n iIns = aOpDesc[0];\n }\n }\n\n if (iIns >= asOpcodes.length) {\n bModRM = this.getByte(dbgAddr, 1);\n aOpDesc = DebuggerX86.aaGrpDescs[iIns - asOpcodes.length][(bModRM >> 3) & 0x7];\n iIns = aOpDesc[0];\n }\n\n var sOpcode = asOpcodes[iIns];\n var cOperands = aOpDesc.length - 1;\n var sOperands = \"\";\n\n if (dbgAddr.fData32) {\n if (iIns == DebuggerX86.INS.CBW) {\n sOpcode = \"CWDE\"; // sign-extend AX into EAX, instead of AL into AX\n }\n else if (iIns == DebuggerX86.INS.CWD) {\n sOpcode = \"CDQ\"; // sign-extend EAX into EDX:EAX, instead of AX into DX:AX\n }\n else if (iIns >= DebuggerX86.INS.POPA && iIns <= DebuggerX86.INS.PUSHA) {\n sOpcode += 'D'; // transform POPA/POPF/PUSHF/PUSHA to POPAD/POPFD/PUSHFD/PUSHAD as appropriate\n }\n }\n if (this.isStringIns(bOpcode)) {\n cOperands = 0; // suppress operands for string instructions, and add 'D' suffix as appropriate\n if (dbgAddr.fData32 && sOpcode.slice(-1) == 'W') sOpcode = sOpcode.slice(0, -1) + 'D';\n }\n\n var typeCPU = -1;\n var fComplete = true;\n\n for (var iOperand = 1; iOperand <= cOperands; iOperand++) {\n\n var disp, off, cch;\n var sOperand = \"\";\n var type = aOpDesc[iOperand];\n if (type === undefined) continue;\n\n if (typeCPU < 0) typeCPU = type >> DebuggerX86.TYPE_CPU_SHIFT;\n\n if (iIns == DebuggerX86.INS.LOADALL) {\n if (typeCPU == DebuggerX86.CPU_80286) {\n sOperands = \"[%800]\";\n } else if (typeCPU == DebuggerX86.CPU_80386) {\n sOperands = \"ES:[\" + (dbgAddr.fAddr32? 'E':'') + \"DI]\";\n }\n }\n\n var typeSize = type & DebuggerX86.TYPE_SIZE;\n if (typeSize == DebuggerX86.TYPE_NONE) {\n continue;\n }\n if (typeSize == DebuggerX86.TYPE_PREFIX) {\n fComplete = false;\n continue;\n }\n var typeMode = type & DebuggerX86.TYPE_MODE;\n if (typeMode >= DebuggerX86.TYPE_MODRM) {\n if (bModRM < 0) {\n bModRM = this.getByte(dbgAddr, 1);\n }\n if (typeMode < DebuggerX86.TYPE_MODREG) {\n /*\n * This test also encompasses TYPE_MODMEM, which is basically the inverse of the case\n * below (ie, only Mod values *other* than 11 are allowed); however, I believe that in\n * some cases that's merely a convention, and that if you try to execute an instruction\n * like \"LEA AX,BX\", it will actually do something (on some if not all processors), so\n * there's probably some diagnostic value in allowing those cases to be disassembled.\n */\n sOperand = this.getModRMOperand(sOpcode, bModRM, type, cOperands, dbgAddr);\n }\n else if (typeMode == DebuggerX86.TYPE_MODREG) {\n /*\n * TYPE_MODREG instructions assume that Mod is 11 (only certain early 80486 steppings\n * actually *required* that Mod contain 11) and always treat RM as a register (which we\n * could also simulate by setting Mod to 11 and letting getModRMOperand() do its thing).\n */\n sOperand = this.getRegOperand(bModRM & 0x7, type, dbgAddr);\n }\n else {\n /*\n * All remaining cases are register-based (eg, TYPE_REG); getRegOperand() will figure out which.\n */\n sOperand = this.getRegOperand((bModRM >> 3) & 0x7, type, dbgAddr);\n }\n }\n else if (typeMode == DebuggerX86.TYPE_ONE) {\n sOperand = '1';\n }\n else if (typeMode == DebuggerX86.TYPE_IMM) {\n sOperand = this.getImmOperand(type, dbgAddr);\n }\n else if (typeMode == DebuggerX86.TYPE_IMMOFF) {\n if (!dbgAddr.fAddr32) {\n cch = 4;\n off = this.getShort(dbgAddr, 2);\n } else {\n cch = 8;\n off = this.getLong(dbgAddr, 4);\n }\n sOperand = '[' + Str.toHex(off, cch) + ']';\n }\n else if (typeMode == DebuggerX86.TYPE_IMMREL) {\n if (typeSize == DebuggerX86.TYPE_BYTE) {\n disp = ((this.getByte(dbgAddr, 1) << 24) >> 24);\n }\n else {\n disp = this.getWord(dbgAddr, true);\n }\n off = (dbgAddr.off + disp) & (dbgAddr.fData32? -1 : 0xffff);\n sOperand = Str.toHex(off, dbgAddr.fData32? 8: 4);\n var aSymbol = this.findSymbol(this.newAddr(off, dbgAddr.sel));\n if (aSymbol[0]) sOperand += \" (\" + aSymbol[0] + \")\";\n }\n else if (typeMode == DebuggerX86.TYPE_IMPREG) {\n if (typeSize == DebuggerX86.TYPE_ST) {\n sOperand = \"ST\";\n } else if (typeSize == DebuggerX86.TYPE_STREG) {\n sOperand = \"ST(\" + (bModRM & 0x7) + \")\";\n } else {\n sOperand = this.getRegOperand((type & DebuggerX86.TYPE_IREG) >> 8, type, dbgAddr);\n }\n }\n else if (typeMode == DebuggerX86.TYPE_IMPSEG) {\n sOperand = this.getRegOperand((type & DebuggerX86.TYPE_IREG) >> 8, DebuggerX86.TYPE_SEGREG, dbgAddr);\n }\n else if (typeMode == DebuggerX86.TYPE_DSSI) {\n sOperand = \"DS:[SI]\";\n }\n else if (typeMode == DebuggerX86.TYPE_ESDI) {\n sOperand = \"ES:[DI]\";\n }\n if (!sOperand || !sOperand.length) {\n sOperands = \"INVALID\";\n break;\n }\n if (sOperands.length > 0) sOperands += ',';\n sOperands += (sOperand || \"???\");\n }\n\n var sBytes = \"\";\n var sLine = this.toHexAddr(dbgAddrIns) + ' ';\n if (dbgAddrIns.addr !== X86.ADDR_INVALID && dbgAddr.addr !== X86.ADDR_INVALID) {\n do {\n sBytes += Str.toHex(this.getByte(dbgAddrIns, 1), 2);\n if (dbgAddrIns.addr == null) break;\n } while (dbgAddrIns.addr != dbgAddr.addr);\n }\n\n sLine += Str.pad(sBytes, dbgAddrIns.fAddr32? 25 : 17);\n sLine += Str.pad(sOpcode, 8);\n if (sOperands) sLine += ' ' + sOperands;\n\n if (this.cpu.model < DebuggerX86.CPUS[typeCPU]) {\n sComment = DebuggerX86.CPUS[typeCPU] + \" CPU only\";\n }\n\n if (sComment && fComplete) {\n sLine = Str.pad(sLine, dbgAddrIns.fAddr32? 74 : 62) + ';' + sComment;\n if (!this.cpu.flags.checksum) {\n sLine += (nSequence != null? '=' + nSequence.toString() : \"\");\n } else {\n var nCycles = this.cpu.getCycles();\n sLine += \"cycles=\" + nCycles.toString() + \" cs=\" + Str.toHex(this.cpu.counts.nChecksum);\n }\n }\n\n this.initAddrSize(dbgAddr, fComplete, cOverrides);\n return sLine;\n }\n\n /**\n * getFPUInstruction(bOpcode, bModRM)\n *\n * @this {DebuggerX86}\n * @param {number} bOpcode\n * @param {number} bModRM\n * @return {Array|null} (FPU instruction group, or null if none)\n */\n getFPUInstruction(bOpcode, bModRM)\n {\n var aOpDesc = null;\n\n var mod = (bModRM >> 6) & 0x3;\n var reg = (bModRM >> 3) & 0x7;\n var r_m = (bModRM & 0x7);\n\n /*\n * Similar to how opFPU() decodes FPU instructions, we combine mod and reg into one\n * decodable value: put mod in the high nibble and reg in the low nibble, after first\n * collapsing all mod values < 3 to zero.\n */\n var modReg = (mod < 3? 0 : 0x30) + reg;\n\n /*\n * All values >= 0x34 imply mod == 3 and reg >= 4, so now we shift reg into the high\n * nibble and r_m into the low, yielding values >= 0x40.\n */\n if ((bOpcode == X86.OPCODE.ESC1 || bOpcode == X86.OPCODE.ESC3) && modReg >= 0x34) {\n modReg = (reg << 4) | r_m;\n }\n\n var aaOpDesc = DebuggerX86.aaaOpFPUDescs[bOpcode];\n if (aaOpDesc) aOpDesc = aaOpDesc[modReg];\n\n return aOpDesc;\n }\n\n /**\n * getImmOperand(type, dbgAddr)\n *\n * @this {DebuggerX86}\n * @param {number} type\n * @param {DbgAddrX86} dbgAddr\n * @return {string} operand\n */\n getImmOperand(type, dbgAddr)\n {\n var sOperand = ' ';\n var typeSize = type & DebuggerX86.TYPE_SIZE;\n\n switch (typeSize) {\n case DebuggerX86.TYPE_BYTE:\n /*\n * There's the occasional immediate byte we don't need to display (eg, the 0x0A\n * following an AAM or AAD instruction), so we suppress the byte if it lacks a TYPE_IN\n * or TYPE_OUT designation (and TYPE_BOTH, as the name implies, includes both).\n */\n if (type & DebuggerX86.TYPE_BOTH) {\n sOperand = Str.toHex(this.getByte(dbgAddr, 1), 2);\n }\n break;\n case DebuggerX86.TYPE_SBYTE:\n sOperand = Str.toHex((this.getByte(dbgAddr, 1) << 24) >> 24, dbgAddr.fData32? 8: 4);\n break;\n case DebuggerX86.TYPE_WORD:\n if (dbgAddr.fData32) {\n sOperand = Str.toHex(this.getLong(dbgAddr, 4));\n break;\n }\n /* falls through */\n case DebuggerX86.TYPE_SHORT:\n sOperand = Str.toHex(this.getShort(dbgAddr, 2), 4);\n break;\n case DebuggerX86.TYPE_FARP:\n dbgAddr = this.newAddr(this.getWord(dbgAddr, true), this.getShort(dbgAddr, 2), null, dbgAddr.type, dbgAddr.fData32, dbgAddr.fAddr32);\n sOperand = this.toHexAddr(dbgAddr);\n var aSymbol = this.findSymbol(dbgAddr);\n if (aSymbol[0]) sOperand += \" (\" + aSymbol[0] + \")\";\n break;\n default:\n sOperand = \"imm(\" + Str.toHexWord(type) + ')';\n break;\n }\n return sOperand;\n }\n\n /**\n * getRegOperand(bReg, type, dbgAddr)\n *\n * @this {DebuggerX86}\n * @param {number} bReg\n * @param {number} type\n * @param {DbgAddrX86} dbgAddr\n * @return {string} operand\n */\n getRegOperand(bReg, type, dbgAddr)\n {\n var typeMode = type & DebuggerX86.TYPE_MODE;\n if (typeMode == DebuggerX86.TYPE_SEGREG) {\n if (bReg > DebuggerX86.REG_GS ||\n bReg >= DebuggerX86.REG_FS && this.cpu.model < X86.MODEL_80386) return \"??\";\n bReg += DebuggerX86.REG_SEG;\n }\n else if (typeMode == DebuggerX86.TYPE_CTLREG) {\n bReg += DebuggerX86.REG_CR0;\n }\n else if (typeMode == DebuggerX86.TYPE_DBGREG) {\n bReg += DebuggerX86.REG_DR0;\n }\n else if (typeMode == DebuggerX86.TYPE_TSTREG) {\n bReg += DebuggerX86.REG_TR0;\n }\n else {\n var typeSize = type & DebuggerX86.TYPE_SIZE;\n if (typeSize >= DebuggerX86.TYPE_SHORT) {\n if (bReg < DebuggerX86.REG_AX) {\n bReg += DebuggerX86.REG_AX - DebuggerX86.REG_AL;\n }\n if (typeSize == DebuggerX86.TYPE_LONG || typeSize == DebuggerX86.TYPE_WORD && dbgAddr.fData32) {\n bReg += DebuggerX86.REG_EAX - DebuggerX86.REG_AX;\n }\n }\n }\n return DebuggerX86.REGS[bReg];\n }\n\n /**\n * getSIBOperand(bMod, dbgAddr)\n *\n * @this {DebuggerX86}\n * @param {number} bMod\n * @param {DbgAddrX86} dbgAddr\n * @return {string} operand\n */\n getSIBOperand(bMod, dbgAddr)\n {\n var bSIB = this.getByte(dbgAddr, 1);\n var bScale = bSIB >> 6;\n var bIndex = (bSIB >> 3) & 0x7;\n var bBase = bSIB & 0x7;\n var sOperand = \"\";\n /*\n * Unless bMod is zero AND bBase is 5, there's always a base register.\n */\n if (bMod || bBase != 5) {\n sOperand = DebuggerX86.RMS[bBase + 8];\n }\n if (bIndex != 4) {\n if (sOperand) sOperand += '+';\n sOperand += DebuggerX86.RMS[bIndex + 8];\n if (bScale) sOperand += '*' + (0x1 << bScale);\n }\n /*\n * If bMod is zero AND bBase is 5, there's a 32-bit displacement instead of a base register.\n */\n if (!bMod && bBase == 5) {\n if (sOperand) sOperand += '+';\n sOperand += Str.toHex(this.getLong(dbgAddr, 4));\n }\n return sOperand;\n }\n\n /**\n * getModRMOperand(sOpcode, bModRM, type, cOperands, dbgAddr)\n *\n * @this {DebuggerX86}\n * @param {string} sOpcode\n * @param {number} bModRM\n * @param {number} type\n * @param {number} cOperands (if 1, memory operands are prefixed with the size; otherwise, size can be inferred)\n * @param {DbgAddrX86} dbgAddr\n * @return {string} operand\n */\n getModRMOperand(sOpcode, bModRM, type, cOperands, dbgAddr)\n {\n var sOperand = \"\";\n var bMod = bModRM >> 6;\n var bRM = bModRM & 0x7;\n if (bMod < 3) {\n var disp;\n var fInteger = (sOpcode.indexOf(\"FI\") == 0);\n if (!bMod && (!dbgAddr.fAddr32 && bRM == 6 || dbgAddr.fAddr32 && bRM == 5)) {\n bMod = 2;\n } else {\n if (dbgAddr.fAddr32) {\n if (bRM != 4) {\n bRM += 8;\n } else {\n sOperand = this.getSIBOperand(bMod, dbgAddr);\n }\n }\n if (!sOperand) sOperand = DebuggerX86.RMS[bRM];\n }\n if (bMod == 1) {\n disp = this.getByte(dbgAddr, 1);\n if (!(disp & 0x80)) {\n sOperand += '+' + Str.toHex(disp, 2);\n }\n else {\n disp = ((disp << 24) >> 24);\n sOperand += '-' + Str.toHex(-disp, 2);\n }\n }\n else if (bMod == 2) {\n if (sOperand) sOperand += '+';\n if (!dbgAddr.fAddr32) {\n disp = this.getShort(dbgAddr, 2);\n sOperand += Str.toHex(disp, 4);\n } else {\n disp = this.getLong(dbgAddr, 4);\n sOperand += Str.toHex(disp);\n }\n }\n sOperand = '[' + sOperand + ']';\n if (cOperands == 1) {\n var sPrefix = \"\";\n type &= DebuggerX86.TYPE_SIZE;\n if (type == DebuggerX86.TYPE_WORD) {\n type = (dbgAddr.fData32? DebuggerX86.TYPE_LONG : DebuggerX86.TYPE_SHORT);\n }\n switch(type) {\n case DebuggerX86.TYPE_FARP:\n sPrefix = \"FAR\";\n break;\n case DebuggerX86.TYPE_BYTE:\n sPrefix = \"BYTE\";\n break;\n case DebuggerX86.TYPE_SHORT:\n if (fInteger) {\n sPrefix = \"INT16\";\n break;\n }\n /* falls through */\n sPrefix = \"WORD\";\n break;\n case DebuggerX86.TYPE_LONG:\n sPrefix = \"DWORD\";\n break;\n case DebuggerX86.TYPE_SINT:\n if (fInteger) {\n sPrefix = \"INT32\";\n break;\n }\n /* falls through */\n case DebuggerX86.TYPE_SREAL:\n sPrefix = \"REAL32\";\n break;\n case DebuggerX86.TYPE_LINT:\n if (fInteger) {\n sPrefix = \"INT64\";\n break;\n }\n /* falls through */\n case DebuggerX86.TYPE_LREAL:\n sPrefix = \"REAL64\";\n break;\n case DebuggerX86.TYPE_TREAL:\n sPrefix = \"REAL80\";\n break;\n case DebuggerX86.TYPE_BCD80:\n sPrefix = \"BCD80\";\n break;\n }\n if (sPrefix) sOperand = sPrefix + ' ' + sOperand;\n }\n }\n else {\n sOperand = this.getRegOperand(bRM, type, dbgAddr);\n }\n return sOperand;\n }\n\n /**\n * parseInstruction(sOp, sOperand, addr)\n *\n * TODO: Unimplemented. See parseInstruction() in modules/c1pjs/lib/debugger.js for a working implementation.\n *\n * @this {DebuggerX86}\n * @param {string} sOp\n * @param {string|undefined} sOperand\n * @param {DbgAddrX86} dbgAddr of memory where this instruction is being assembled\n * @return {Array.<number>} of opcode bytes; if the instruction can't be parsed, the array will be empty\n */\n parseInstruction(sOp, sOperand, dbgAddr)\n {\n var aOpBytes = [];\n this.println(\"not supported yet\");\n return aOpBytes;\n }\n\n /**\n * getFlagOutput(sFlag)\n *\n * @this {DebuggerX86}\n * @param {string} sFlag\n * @return {string} value of flag\n */\n getFlagOutput(sFlag)\n {\n var b;\n switch (sFlag) {\n case 'V':\n b = this.cpu.getOF();\n break;\n case 'D':\n b = this.cpu.getDF();\n break;\n case 'I':\n b = this.cpu.getIF();\n break;\n case 'T':\n b = this.cpu.getTF();\n break;\n case 'S':\n b = this.cpu.getSF();\n break;\n case 'Z':\n b = this.cpu.getZF();\n break;\n case 'A':\n b = this.cpu.getAF();\n break;\n case 'P':\n b = this.cpu.getPF();\n break;\n case 'C':\n b = this.cpu.getCF();\n break;\n default:\n b = 0;\n break;\n }\n return sFlag + (b? '1' : '0') + ' ';\n }\n\n /**\n * getLimitString(l)\n *\n * @this {DebuggerX86}\n * @param {number} l\n * @return {string}\n */\n getLimitString(l)\n {\n return Str.toHex(l, (l & ~0xffff)? 8 : 4);\n }\n\n /**\n * getRegOutput(iReg)\n *\n * @this {DebuggerX86}\n * @param {number} iReg\n * @return {string}\n */\n getRegOutput(iReg)\n {\n if (iReg >= DebuggerX86.REG_AX && iReg <= DebuggerX86.REG_DI && this.cchReg > 4) iReg += DebuggerX86.REG_EAX - DebuggerX86.REG_AX;\n var sReg = DebuggerX86.REGS[iReg];\n if (iReg == DebuggerX86.REG_CR0 && this.cpu.model == X86.MODEL_80286) sReg = \"MS\";\n return sReg + '=' + this.getRegString(iReg) + ' ';\n }\n\n /**\n * getSegOutput(seg, fProt)\n *\n * @this {DebuggerX86}\n * @param {SegX86} seg\n * @param {boolean} [fProt]\n * @return {string}\n */\n getSegOutput(seg, fProt)\n {\n return seg.sName + '=' + Str.toHex(seg.sel, 4) + (fProt? '[' + Str.toHex(seg.base, this.cchAddr) + ',' + this.getLimitString(seg.limit) + ']' : \"\");\n }\n\n /**\n * getDTROutput(sName, sel, addr, addrLimit)\n *\n * @this {DebuggerX86}\n * @param {string} sName\n * @param {number|null} sel\n * @param {number} addr\n * @param {number} addrLimit\n * @return {string}\n */\n getDTROutput(sName, sel, addr, addrLimit)\n {\n return sName + '=' + (sel != null? Str.toHex(sel, 4) : \"\") + '[' + Str.toHex(addr, this.cchAddr) + ',' + Str.toHex(addrLimit - addr, 4) + ']';\n }\n\n /**\n * getRegDump(fProt)\n *\n * Sample 8086 and 80286 real-mode register dump:\n *\n * AX=0000 BX=0000 CX=0000 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000\n * SS=0000 DS=0000 ES=0000 PS=0002 V0 D0 I0 T0 S0 Z0 A0 P0 C0\n * F000:FFF0 EA5BE000F0 JMP F000:E05B\n *\n * Sample 80386 real-mode register dump:\n *\n * EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000000\n * ESP=00000000 EBP=00000000 ESI=00000000 EDI=00000000\n * SS=0000 DS=0000 ES=0000 FS=0000 GS=0000 PS=00000002 V0 D0 I0 T0 S0 Z0 A0 P0 C0\n * F000:FFF0 EA05F900F0 JMP F000:F905\n *\n * Sample 80286 protected-mode register dump:\n *\n * AX=0000 BX=0000 CX=0000 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000\n * SS=0000[000000,FFFF] DS=0000[000000,FFFF] ES=0000[000000,FFFF] A20=ON\n * CS=F000[FF0000,FFFF] LD=0000[000000,FFFF] GD=[000000,FFFF] ID=[000000,03FF]\n * TR=0000 MS=FFF0 PS=0002 V0 D0 I0 T0 S0 Z0 A0 P0 C0\n * F000:FFF0 EA5BE000F0 JMP F000:E05B\n *\n * Sample 80386 protected-mode register dump:\n *\n * EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000000\n * ESP=00000000 EBP=00000000 ESI=00000000 EDI=00000000\n * SS=0000[00000000,FFFF] DS=0000[00000000,FFFF] ES=0000[00000000,FFFF]\n * CS=F000[FFFF0000,FFFF] FS=0000[00000000,FFFF] GS=0000[00000000,FFFF]\n * LD=0000[00000000,FFFF] GD=[00000000,FFFF] ID=[00000000,03FF] TR=0000 A20=ON\n * CR0=00000010 CR2=00000000 CR3=00000000 PS=00000002 V0 D0 I0 T0 S0 Z0 A0 P0 C0\n * F000:0000FFF0 EA05F900F0 JMP F000:0000F905\n *\n * This no longer includes CS in real-mode (or EIP in any mode), because that information can be obtained from the\n * first line of disassembly, which an \"r\" or \"rp\" command will also display.\n *\n * Note that even when the processor is in real mode, you can always use the \"rp\" command to force a protected-mode\n * dump, in case you need to verify any selector base or limit values, since those also affect real-mode operation.\n *\n * @this {DebuggerX86}\n * @param {boolean} [fProt]\n * @return {string}\n */\n getRegDump(fProt)\n {\n var s;\n if (fProt === undefined) fProt = this.getCPUMode();\n\n s = this.getRegOutput(DebuggerX86.REG_AX) +\n this.getRegOutput(DebuggerX86.REG_BX) +\n this.getRegOutput(DebuggerX86.REG_CX) +\n this.getRegOutput(DebuggerX86.REG_DX) + (this.cchReg > 4? '\\n' : '') +\n this.getRegOutput(DebuggerX86.REG_SP) +\n this.getRegOutput(DebuggerX86.REG_BP) +\n this.getRegOutput(DebuggerX86.REG_SI) +\n this.getRegOutput(DebuggerX86.REG_DI) + '\\n' +\n this.getSegOutput(this.cpu.segSS, fProt) + ' ' +\n this.getSegOutput(this.cpu.segDS, fProt) + ' ' +\n this.getSegOutput(this.cpu.segES, fProt) + ' ';\n\n if (fProt) {\n var sTR = \"TR=\" + Str.toHex(this.cpu.segTSS.sel, 4);\n var sA20 = \"A20=\" + (this.bus.getA20()? \"ON \" : \"OFF \");\n if (this.cpu.model < X86.MODEL_80386) {\n sTR = '\\n' + sTR;\n s += sA20; sA20 = '';\n }\n s += '\\n' + this.getSegOutput(this.cpu.segCS, fProt) + ' ';\n if (I386 && this.cpu.model >= X86.MODEL_80386) {\n sA20 += '\\n';\n s += this.getSegOutput(this.cpu.segFS, fProt) + ' ' +\n this.getSegOutput(this.cpu.segGS, fProt) + '\\n';\n }\n s += this.getDTROutput(\"LD\", this.cpu.segLDT.sel, this.cpu.segLDT.base, this.cpu.segLDT.base + this.cpu.segLDT.limit) + ' ' +\n this.getDTROutput(\"GD\", null, this.cpu.addrGDT, this.cpu.addrGDTLimit) + ' ' +\n this.getDTROutput(\"ID\", null, this.cpu.addrIDT, this.cpu.addrIDTLimit) + ' ';\n s += sTR + ' ' + sA20;\n s += this.getRegOutput(DebuggerX86.REG_CR0);\n if (I386 && this.cpu.model >= X86.MODEL_80386) {\n s += this.getRegOutput(DebuggerX86.REG_CR2) + this.getRegOutput(DebuggerX86.REG_CR3);\n }\n } else {\n if (I386 && this.cpu.model >= X86.MODEL_80386) {\n s += this.getSegOutput(this.cpu.segFS, fProt) + ' ' +\n this.getSegOutput(this.cpu.segGS, fProt) + ' ';\n }\n }\n\n s += this.getRegOutput(DebuggerX86.REG_PS) +\n this.getFlagOutput('V') + this.getFlagOutput('D') + this.getFlagOutput('I') + this.getFlagOutput('T') +\n this.getFlagOutput('S') + this.getFlagOutput('Z') + this.getFlagOutput('A') + this.getFlagOutput('P') + this.getFlagOutput('C');\n\n return s;\n }\n\n /**\n * comparePairs(p1, p2)\n *\n * @this {DebuggerX86}\n * @param {number|string|Array|Object} p1\n * @param {number|string|Array|Object} p2\n * @return {number}\n */\n comparePairs(p1, p2)\n {\n return p1[0] > p2[0]? 1 : p1[0] < p2[0]? -1 : 0;\n }\n\n /**\n * addSymbols(sModule, nSegment, sel, off, addr, len, aSymbols)\n *\n * As filedump.js (formerly convrom.php) explains, aSymbols is a JSON-encoded object whose properties consist\n * of all the symbols (in upper-case), and the values of those properties are objects containing any or all of\n * the following properties:\n *\n * 'v': the value of an absolute (unsized) value\n * 'b': either 1, 2, 4 or undefined if an unsized value\n * 's': either a hard-coded segment or undefined\n * 'o': the offset of the symbol within the associated address space\n * 'l': the original-case version of the symbol, present only if it wasn't originally upper-case\n * 'a': annotation for the specified offset; eg, the original assembly language, with optional comment\n *\n * To that list of properties, we also add:\n *\n * 'p': the physical address (calculated whenever both 's' and 'o' properties are defined)\n *\n * Note that values for any 'v', 'b', 's' and 'o' properties are unquoted decimal values, and the values\n * for any 'l' or 'a' properties are quoted strings. Also, if double-quotes were used in any of the original\n * annotation ('a') values, they will have been converted to two single-quotes, so we're responsible for\n * converting them back to individual double-quotes.\n *\n * For example:\n * {\n * 'HF_PORT': {\n * 'v':800\n * },\n * 'HDISK_INT': {\n * 'b':4, 's':0, 'o':52\n * },\n * 'ORG_VECTOR': {\n * 'b':4, 's':0, 'o':76\n * },\n * 'CMD_BLOCK': {\n * 'b':1, 's':64, 'o':66\n * },\n * 'DISK_SETUP': {\n * 'o':3\n * },\n * '.40': {\n * 'o':40, 'a':\"MOV AX,WORD PTR ORG_VECTOR ;GET DISKETTE VECTOR\"\n * }\n * }\n *\n * If a symbol only has an offset, then that offset value can be assigned to the symbol property directly:\n *\n * 'DISK_SETUP': 3\n *\n * The last property is an example of an \"anonymous\" entry, for offsets where there is no associated symbol.\n * Such entries are identified by a period followed by a unique number (usually the offset of the entry), and\n * they usually only contain offset ('o') and annotation ('a') properties. I could eliminate the leading\n * period, but it offers a very convenient way of quickly discriminating among genuine vs. anonymous symbols.\n *\n * We add all these entries to our internal symbol table, which is an array of 4-element arrays, each of which\n * look like:\n *\n * [sel, off, addr, len, aSymbols, aOffsets]\n *\n * There are two basic symbol operations: findSymbol(), which takes an address and finds the symbol, if any,\n * at that address, and findSymbolAddr(), which takes a string and attempts to match it to a non-anonymous\n * symbol with a matching offset ('o') property.\n *\n * To implement findSymbol() efficiently, addSymbols() creates an array of [offset, sSymbol] pairs\n * (aOffsets), one pair for each symbol that corresponds to an offset within the specified address space.\n *\n * We guarantee the elements of aOffsets are in offset order, because we build it using binaryInsert();\n * it's quite likely that the MAP file already ordered all its symbols in offset order, but since they're\n * hand-edited files, we can't assume that, and we need to ensure that findSymbol()'s binarySearch() operates\n * properly.\n *\n * @this {DebuggerX86}\n * @param {string|null} sModule\n * @param {number} nSegment (zero if undefined)\n * @param {number} sel (the default segment/selector for all symbols in this group)\n * @param {number} off (from the base of the given selector)\n * @param {number|null} addr (physical address where the symbols are located, if the memory is physical; eg, ROM)\n * @param {number} len (the size of the region, in bytes)\n * @param {Object} aSymbols (collection of symbols in this group; the format of this collection is described below)\n */\n addSymbols(sModule, nSegment, sel, off, addr, len, aSymbols)\n {\n var dbgAddr = {};\n var aOffsets = [];\n for (var sSymbol in aSymbols) {\n var symbol = aSymbols[sSymbol];\n if (typeof symbol == \"number\") {\n aSymbols[sSymbol] = symbol = {'o': symbol};\n }\n var offSymbol = symbol['o'];\n var selSymbol = symbol['s'];\n var sAnnotation = symbol['a'];\n if (offSymbol !== undefined) {\n if (selSymbol !== undefined) {\n dbgAddr.off = offSymbol;\n dbgAddr.sel = selSymbol;\n dbgAddr.addr = null;\n /*\n * getAddr() computes the corresponding physical address and saves it in dbgAddr.addr.\n */\n this.getAddr(dbgAddr);\n /*\n * The physical address for any symbol located in the top 64Kb of the machine's address space\n * should be relocated to the top 64Kb of the first 1Mb, so that we're immune from any changes\n * to the A20 line.\n */\n if ((dbgAddr.addr & ~0xffff) == (this.bus.nBusLimit & ~0xffff)) {\n dbgAddr.addr &= 0x000fffff;\n }\n symbol['p'] = dbgAddr.addr;\n }\n Usr.binaryInsert(aOffsets, [offSymbol >>> 0, sSymbol], this.comparePairs);\n }\n if (sAnnotation) symbol['a'] = sAnnotation.replace(/''/g, \"\\\"\");\n }\n var symbolTable = {\n sModule: sModule,\n nSegment: nSegment,\n sel: sel,\n off: off,\n addr: addr,\n len: len,\n aSymbols: aSymbols,\n aOffsets: aOffsets\n };\n this.aSymbolTable.push(symbolTable);\n }\n\n /**\n * removeSymbols(sModule, nSegment)\n *\n * @this {DebuggerX86}\n * @param {string|null} sModule\n * @param {number} [nSegment] (segment # if sModule set, selector if sModule clear)\n * @return {string|null} name of the module removed, or null if no module was found\n */\n removeSymbols(sModule, nSegment)\n {\n var sModuleRemoved = null;\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n if (sModule && symbolTable.sModule != sModule) continue;\n if (sModule && nSegment == symbolTable.nSegment || !sModule && nSegment == symbolTable.sel) {\n sModuleRemoved = symbolTable.sModule;\n this.aSymbolTable.splice(iTable, 1);\n break;\n }\n }\n return sModuleRemoved;\n }\n\n /**\n * dumpSymbols()\n *\n * TODO: Add \"numerical\" and \"alphabetical\" dump options. This is simply dumping them in whatever\n * order they appeared in the original MAP file.\n *\n * @this {DebuggerX86}\n */\n dumpSymbols()\n {\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n for (var sSymbol in symbolTable.aSymbols) {\n if (sSymbol.charAt(0) == '.') continue;\n var symbol = symbolTable.aSymbols[sSymbol];\n var offSymbol = symbol['o'];\n if (offSymbol === undefined) continue;\n var selSymbol = symbol['s'];\n if (selSymbol === undefined) selSymbol = symbolTable.sel;\n var sSymbolOrig = symbolTable.aSymbols[sSymbol]['l'];\n if (sSymbolOrig) sSymbol = sSymbolOrig;\n this.println(this.toHexOffset(offSymbol, selSymbol) + ' ' + sSymbol);\n }\n }\n }\n\n /**\n * findSymbol(dbgAddr, fNearest)\n *\n * Search aSymbolTable for dbgAddr, and return an Array for the corresponding symbol (empty if not found).\n *\n * If fNearest is true, and no exact match was found, then the Array returned will contain TWO sets of\n * entries: [0]-[3] will refer to closest preceding symbol, and [4]-[7] will refer to the closest subsequent symbol.\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {boolean} [fNearest]\n * @return {Array} where [0] == symbol name, [1] == symbol value, [2] == any annotation, and [3] == any associated comment\n */\n findSymbol(dbgAddr, fNearest)\n {\n var aSymbol = [];\n var offSymbol = dbgAddr.off >>> 0;\n var addrSymbol = this.getAddr(dbgAddr) >>> 0;\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n var sel = symbolTable.sel;\n var off = symbolTable.off >>> 0;\n var addr = symbolTable.addr;\n if (addr != null) addr >>>= 0;\n var len = symbolTable.len;\n if (sel == 0x30) sel = 0x28; // TODO: Remove this hack once we're able to differentiate Windows 95 ring 0 code and data\n if (sel == dbgAddr.sel && offSymbol >= off && offSymbol < off + len || addr != null && addrSymbol >= addr && addrSymbol < addr + len) {\n var result = Usr.binarySearch(symbolTable.aOffsets, [offSymbol], this.comparePairs);\n if (result >= 0) {\n this.returnSymbol(iTable, result, aSymbol);\n }\n else if (fNearest) {\n result = ~result;\n this.returnSymbol(iTable, result-1, aSymbol);\n this.returnSymbol(iTable, result, aSymbol);\n }\n break;\n }\n }\n if (!aSymbol.length) {\n var sSymbol = this.bus.getSymbol(addrSymbol, true);\n if (sSymbol) {\n aSymbol.push(sSymbol);\n aSymbol.push(addrSymbol);\n }\n }\n return aSymbol;\n }\n\n /**\n * findSymbolAddr(sSymbol)\n *\n * Search aSymbolTable for sSymbol, and if found, return a dbgAddr (same as parseAddr())\n *\n * @this {DebuggerX86}\n * @param {string} sSymbol\n * @return {DbgAddrX86|undefined}\n */\n findSymbolAddr(sSymbol)\n {\n var dbgAddr;\n if (sSymbol.match(/^[a-z_][a-z0-9_]*$/i)) {\n var sUpperCase = sSymbol.toUpperCase();\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n var symbol = symbolTable.aSymbols[sUpperCase];\n if (symbol !== undefined) {\n var offSymbol = symbol['o'];\n if (offSymbol !== undefined) {\n /*\n * We assume that every ROM is ORG'ed at 0x0000, and therefore unless the symbol has an\n * explicitly-defined segment, we return the segment associated with the entire group; for\n * a ROM, that segment is normally \"addrROM >>> 4\". Down the road, we may want/need to\n * support a special symbol entry (eg, \".ORG\") that defines an alternate origin.\n */\n var selSymbol = symbol['s'];\n if (selSymbol === undefined) selSymbol = symbolTable.sel;\n dbgAddr = this.newAddr(offSymbol, selSymbol, symbol['p']);\n }\n /*\n * The symbol matched, but it wasn't for an address (no 'o' offset), and there's no point\n * looking any farther, since each symbol appears only once, so we indicate it's an unknown symbol.\n */\n break;\n }\n }\n }\n return dbgAddr;\n }\n\n /**\n * returnSymbol(iTable, iOffset, aSymbol)\n *\n * Helper function for findSymbol().\n *\n * @param {number} iTable\n * @param {number} iOffset\n * @param {Array} aSymbol is updated with the specified symbol, if it exists\n */\n returnSymbol(iTable, iOffset, aSymbol)\n {\n var symbol = {};\n var aOffsets = this.aSymbolTable[iTable].aOffsets;\n var offset = 0, sSymbol = null;\n if (iOffset >= 0 && iOffset < aOffsets.length) {\n offset = aOffsets[iOffset][0];\n sSymbol = aOffsets[iOffset][1];\n }\n if (sSymbol) {\n symbol = this.aSymbolTable[iTable].aSymbols[sSymbol];\n sSymbol = (sSymbol.charAt(0) == '.'? null : (symbol['l'] || sSymbol));\n }\n aSymbol.push(sSymbol);\n aSymbol.push(offset);\n aSymbol.push(symbol['a']);\n aSymbol.push(symbol['c']);\n }\n\n /**\n * doHelp()\n *\n * @this {DebuggerX86}\n */\n doHelp()\n {\n var s = \"commands:\";\n for (var sCommand in DebuggerX86.COMMANDS) {\n s += '\\n' + Str.pad(sCommand, 7) + DebuggerX86.COMMANDS[sCommand];\n }\n if (!this.checksEnabled()) s += \"\\nnote: frequency/history disabled if no exec breakpoints\";\n this.println(s);\n }\n\n /**\n * doAssemble(asArgs)\n *\n * This always receives the complete argument array, where the order of the arguments is:\n *\n * [0]: the assemble command (assumed to be \"a\")\n * [1]: the target address (eg, \"200\")\n * [2]: the operation code, aka instruction name (eg, \"adc\")\n * [3]: the operation mode operand, if any (eg, \"14\", \"[1234]\", etc)\n *\n * The Debugger enters \"assemble mode\" whenever only the first (or first and second) arguments are present.\n * As long as \"assemble mode is active, the user can omit the first two arguments on all later assemble commands\n * until \"assemble mode\" is cancelled with an empty command line; the command processor automatically prepends \"a\"\n * and the next available target address to the argument array.\n *\n * Entering \"assemble mode\" is optional; one could enter a series of fully-qualified assemble commands; eg:\n *\n * a ff00 cld\n * a ff01 ldx 28\n * ...\n *\n * without ever entering \"assemble mode\", but of course, that requires more typing and doesn't take advantage\n * of automatic target address advancement (see dbgAddrAssemble).\n *\n * NOTE: As the previous example implies, you can even assemble new instructions into ROM address space;\n * as our setByte() function explains, the ROM write-notification handlers only refuse writes from the CPU.\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs is the complete argument array, beginning with the \"a\" command in asArgs[0]\n */\n doAssemble(asArgs)\n {\n var dbgAddr = this.parseAddr(asArgs[1], true);\n if (!dbgAddr) return;\n\n this.dbgAddrAssemble = dbgAddr;\n if (asArgs[2] === undefined) {\n this.println(\"begin assemble at \" + this.toHexAddr(dbgAddr));\n this.fAssemble = true;\n this.cpu.updateCPU();\n return;\n }\n\n var aOpBytes = this.parseInstruction(asArgs[2], asArgs[3], dbgAddr);\n if (aOpBytes.length) {\n for (var i = 0; i < aOpBytes.length; i++) {\n this.setByte(dbgAddr, aOpBytes[i], 1);\n }\n /*\n * Since getInstruction() also updates the specified address, dbgAddrAssemble is automatically advanced.\n */\n this.println(this.getInstruction(this.dbgAddrAssemble));\n }\n }\n\n /**\n * doBreak(sCmd, sAddr, sOptions)\n *\n * As the \"help\" output below indicates, the following breakpoint commands are supported:\n *\n * bp [a] set exec breakpoint on linear addr [a]\n * br [a] set read breakpoint on linear addr [a]\n * bw [a] set write breakpoint on linear addr [a]\n * bc [a] clear breakpoint on linear addr [a] (use \"*\" for all breakpoints)\n * bl list breakpoints\n *\n * to which we have recently added the following I/O breakpoint commands:\n *\n * bi [p] toggle input breakpoint on port [p] (use \"*\" for all input ports)\n * bo [p] toggle output breakpoint on port [p] (use \"*\" for all output ports)\n *\n * These two new commands operate as toggles so that if \"*\" is used to trap all input (or output),\n * you can also use these commands to NOT trap specific ports.\n *\n * bn [n] break after [n] instructions\n *\n * TODO: Update the \"bl\" command to include any/all I/O breakpoints, and the \"bc\" command to\n * clear them. Because \"bi\" and \"bo\" commands are piggy-backing on Bus functions, those breakpoints\n * are currently outside the realm of what the \"bl\" and \"bc\" commands are aware of.\n *\n * @this {DebuggerX86}\n * @param {string} sCmd\n * @param {string|undefined} [sAddr]\n * @param {string} [sOptions] (the rest of the breakpoint command-line)\n */\n doBreak(sCmd, sAddr, sOptions)\n {\n if (sAddr == '?') {\n this.println(\"breakpoint commands:\");\n this.println(\"\\tbi [p]\\ttoggle break on input port [p]\");\n this.println(\"\\tbo [p]\\ttoggle break on output port [p]\");\n this.println(\"\\tbp [a]\\tset exec breakpoint at addr [a]\");\n this.println(\"\\tbr [a]\\tset read breakpoint at addr [a]\");\n this.println(\"\\tbw [a]\\tset write breakpoint at addr [a]\");\n this.println(\"\\tbc [a]\\tclear breakpoint at addr [a]\");\n this.println(\"\\tbl\\tlist all breakpoints\");\n this.println(\"\\tbn [n]\\tbreak after [n] instruction(s)\");\n return;\n }\n var sParm = sCmd.charAt(1);\n if (sParm == 'l') {\n var cBreaks = 0;\n cBreaks += this.listBreakpoints(this.aBreakExec);\n cBreaks += this.listBreakpoints(this.aBreakRead);\n cBreaks += this.listBreakpoints(this.aBreakWrite);\n if (!cBreaks) this.println(\"no breakpoints\");\n return;\n }\n if (sParm == 'n') {\n this.nBreakIns = this.parseValue(sAddr);\n this.println(\"break after \" + this.nBreakIns + \" instruction(s)\");\n return;\n }\n if (sAddr === undefined) {\n this.println(\"missing breakpoint address\");\n return;\n }\n var dbgAddr = {};\n if (sAddr != '*') {\n dbgAddr = this.parseAddr(sAddr, true, true);\n if (!dbgAddr) return;\n }\n\n sAddr = (dbgAddr.off == null? sAddr : Str.toHexWord(dbgAddr.off));\n\n if (sParm == 'c') {\n if (dbgAddr.off == null) {\n this.clearBreakpoints();\n this.println(\"all breakpoints cleared\");\n return;\n }\n if (this.findBreakpoint(this.aBreakExec, dbgAddr, true))\n return;\n if (this.findBreakpoint(this.aBreakRead, dbgAddr, true))\n return;\n if (this.findBreakpoint(this.aBreakWrite, dbgAddr, true))\n return;\n this.println(\"breakpoint missing: \" + this.toHexAddr(dbgAddr));\n return;\n }\n\n if (sParm == 'i') {\n this.println(\"breakpoint \" + (this.bus.addPortInputBreak(dbgAddr.off)? \"enabled\" : \"cleared\") + \": port \" + sAddr + \" (input)\");\n return;\n }\n\n if (sParm == 'o') {\n this.println(\"breakpoint \" + (this.bus.addPortOutputBreak(dbgAddr.off)? \"enabled\" : \"cleared\") + \": port \" + sAddr + \" (output)\");\n return;\n }\n\n if (dbgAddr.off == null) return;\n\n this.parseAddrOptions(dbgAddr, sOptions);\n\n if (sParm == 'p') {\n this.addBreakpoint(this.aBreakExec, dbgAddr);\n return;\n }\n if (sParm == 'r') {\n this.addBreakpoint(this.aBreakRead, dbgAddr);\n return;\n }\n if (sParm == 'w') {\n this.addBreakpoint(this.aBreakWrite, dbgAddr);\n return;\n }\n this.println(\"unknown breakpoint command: \" + sParm);\n }\n\n /**\n * doClear(sCmd)\n *\n * @this {DebuggerX86}\n * @param {string} [sCmd] (eg, \"cls\" or \"clear\")\n */\n doClear(sCmd)\n {\n this.cmp.clearPanel();\n }\n\n /**\n * doDump(asArgs)\n *\n * For memory dumps, the second parameter (sLen) is interpreted as a length (by default, in hex)\n * only if it contains an 'l' prefix; otherwise it's interpreted as an ending address (inclusive).\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs (formerly sCmd, [sAddr], [sLen] and [sBytes])\n */\n doDump(asArgs)\n {\n var m;\n var sCmd = asArgs[0];\n var sAddr = asArgs[1];\n var sLen = asArgs[2];\n var sBytes = asArgs[3];\n\n if (sAddr == '?') {\n var sDumpers = \"\";\n for (m in Messages.CATEGORIES) {\n if (this.afnDumpers[m]) {\n if (sDumpers) sDumpers += ',';\n sDumpers += m;\n }\n }\n sDumpers += \",state,symbols\";\n this.println(\"dump memory commands:\");\n this.println(\"\\tda [a] [#] dump # ASCII chars at address\");\n this.println(\"\\tdb [a] [#] dump # bytes at address\");\n this.println(\"\\tdw [a] [#] dump # words at address\");\n this.println(\"\\tdd [a] [#] dump # dwords at address\");\n this.println(\"\\tdh [#] [#] dump # instructions from history\");\n this.println(\"\\tdi [#] dump descriptor info for IDT #\");\n this.println(\"\\tds [#] dump descriptor info for selector #\");\n if (BACKTRACK) {\n this.println(\"\\tdt [a] dump backtrack info for address\");\n }\n if (sDumpers.length) this.println(\"dump extension commands:\\n\\t\" + sDumpers);\n return;\n }\n\n if (sAddr == \"state\") {\n var sState = this.cmp.powerOff(true);\n if (!sState) {\n this.println(\"powerOff() error\");\n }\n else if (sLen == \"console\") {\n /*\n * Console buffers are notoriously small, and even the following code, which breaks the\n * data into parts (eg, \"d state console 1\", \"d state console 2\", etc) just isn't that helpful.\n *\n * var nPart = +sBytes;\n * if (nPart) sState = sState.substr(1000000 * (nPart-1), 1000000);\n *\n * So, the best way to capture a large machine state is to use the new \"Save Machine\" link\n * that downloads a machine's entire state. Alternatively, run your own local server and use\n * server-side storage. Take a look at the \"Save\" binding in computer.js, which binds an HTML\n * control to the computer.powerOff() and computer.saveServerState() functions.\n */\n console.log(sState);\n } else {\n this.doClear();\n this.println(sState);\n }\n return;\n }\n\n if (sAddr == \"symbols\") {\n this.dumpSymbols();\n return;\n }\n\n /*\n * Transform a \"ds\" command into a \"d desc\" command (simply as shorthand); ditto for \"dg\" and \"dl\",\n * only because that's the syntax that WDEB386 used. I'm uncertain what WDEB386 would do with an LDT\n * selector passed to \"dg\" or a GDT selector passed to \"dl\" (because I'm too lazy to check right now),\n * but that seems nonsensical.\n */\n if (sCmd == \"ds\" || sCmd == \"dg\" || sCmd == \"dl\") {\n sCmd = \"d\";\n asArgs = [sCmd, \"desc\", sAddr];\n }\n\n /*\n * Handle the \"dp\" (aka \"d page\") commands here.\n */\n if (sCmd == \"d\" && sAddr == \"page\") {\n sCmd = \"dp\";\n asArgs.shift();\n }\n if (sCmd == \"dp\") {\n asArgs.shift();\n this.dumpPage(asArgs);\n return;\n }\n\n if (sCmd == \"d\") {\n /*\n * Transform a \"d disk\" command into a \"l json\" command (TODO: Register a dumper for \"disk\" instead?)\n */\n if (sAddr == \"disk\") {\n asArgs[0] = \"l\";\n asArgs[1] = \"json\";\n this.doLoad(asArgs);\n return;\n }\n for (m in Messages.CATEGORIES) {\n if (asArgs[1] == m) {\n var fnDumper = this.afnDumpers[m];\n if (fnDumper) {\n asArgs.shift();\n asArgs.shift();\n fnDumper(asArgs);\n } else {\n this.println(\"no dump registered for \" + sAddr);\n }\n return;\n }\n }\n if (!sAddr) sCmd = this.sCmdDumpPrev || \"db\";\n }\n\n if (sCmd == \"dh\") {\n this.dumpHistory(sAddr, sLen, sBytes);\n return;\n }\n\n if (sCmd == \"di\") {\n asArgs.shift();\n this.dumpIDT(asArgs);\n return;\n }\n\n if (sCmd == \"dt\") {\n asArgs.shift();\n var sInfo = this.dumpBackTrack(asArgs);\n this.println(sInfo);\n return;\n }\n\n if (sCmd[1] && \"abwd\".indexOf(sCmd[1]) < 0) {\n this.println(\"unrecognized dump command\");\n return;\n }\n\n this.sCmdDumpPrev = sCmd;\n\n var dbgAddr = this.parseAddr(sAddr);\n if (!dbgAddr || dbgAddr.sel == null && dbgAddr.addr == null) return;\n\n var len = 0;\n if (sLen) {\n if (sLen.charAt(0) == 'l') {\n sLen = sLen.substr(1) || sBytes;\n len = this.parseValue(sLen);\n } else {\n var dbgAddrEnd = this.parseAddr(sLen);\n if (!dbgAddrEnd) return;\n /*\n * To be more DEBUG-like, when an ending address is used instead of a length, we treat it inclusively, hence the \"+ 1\".\n */\n if (dbgAddr.type != DebuggerX86.ADDRTYPE.LINEAR) {\n len = dbgAddrEnd.off - dbgAddr.off + 1;\n } else {\n len = dbgAddrEnd.addr - dbgAddr.addr + 1;\n }\n }\n if (len < 0 || len > 0x10000) len = 0;\n }\n\n var sDump = \"\";\n var fASCII = false;\n var size = (sCmd == \"dd\"? 4 : (sCmd == \"dw\"? 2 : 1));\n var cb = (size * len) || 128;\n var cLines = ((cb + 15) >> 4) || 1;\n var cbLine = (size == 4? 16 : this.nBase); // the base also happens to be a reasonable number of bytes/line\n \n /*\n * The \"da\" variation uses a line size of 160 bytes, because that's the number of characters\n * per line in a text frame buffer; if no ending address or length is specified, the number of\n * lines defaults to 25 (the typical number of visible lines in a frame buffer).\n * \n * Beyond that, the command doesn't make any other assumptions about the memory format. Video\n * frame buffers usually dump nicely because all the attribute bytes tend to be non-ASCII.\n */\n if (sCmd[1] == 'a') {\n fASCII = true;\n cbLine = 160;\n cLines = (len <= 1? 25 : Math.ceil(len / cbLine));\n cb = cLines * cbLine;\n }\n \n while (cLines-- && cb > 0) {\n var data = 0, iByte = 0, i;\n var sData = \"\", sChars = \"\";\n sAddr = this.toHexAddr(dbgAddr);\n for (i = cbLine; i > 0 && cb > 0; i--) {\n var b = this.getByte(dbgAddr, 1);\n data |= (b << (iByte++ << 3));\n if (iByte == size) {\n sData += (this.nBase == 8? Str.toOct(data, size * 3) : Str.toHex(data, size * 2));\n sData += (size == 1? (i == 9? '-' : ' ') : \" \");\n data = iByte = 0;\n }\n sChars += (b >= 32 && b < 127? String.fromCharCode(b) : (fASCII? '' : '.'));\n cb--;\n }\n if (sDump) sDump += '\\n';\n if (fASCII) {\n sDump += sChars;\n } else {\n sDump += sAddr + \" \" + sData + Str.pad(sChars, sChars.length + i * 3 + 1, true);\n }\n }\n if (sDump) this.println(sDump.replace(/\\s*$/, \"\"));\n this.dbgAddrNextData = dbgAddr;\n }\n\n /**\n * doEdit(asArgs)\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n */\n doEdit(asArgs)\n {\n var size = 1;\n var mask = 0xff;\n var fnGet = this.getByte;\n var fnSet = this.setByte;\n if (asArgs[0] == \"ew\") {\n size = 2;\n mask = 0xffff;\n fnGet = this.getShort;\n fnSet = this.setShort;\n }\n var cch = size << 1;\n\n var sAddr = asArgs[1];\n if (sAddr == null) {\n this.println(\"edit memory commands:\");\n this.println(\"\\teb [a] [...] edit bytes at address a\");\n this.println(\"\\tew [a] [...] edit words at address a\");\n return;\n }\n\n var dbgAddr = this.parseAddr(sAddr);\n if (!dbgAddr) return;\n\n for (var i = 2; i < asArgs.length; i++) {\n var vNew = this.parseExpression(asArgs[i]);\n if (vNew === undefined) {\n this.println(\"unrecognized value: \" + asArgs[i]);\n break;\n }\n if (vNew & ~mask) {\n this.println(\"warning: \" + Str.toHex(vNew) + \" exceeds \" + size + \"-byte value\");\n }\n var vOld = fnGet.call(this, dbgAddr);\n this.println(\"changing \" + this.toHexAddr(dbgAddr) + \" from \" + Str.toHex(vOld, cch, true) + \" to \" + Str.toHex(vNew, cch, true));\n fnSet.call(this, dbgAddr, vNew, size);\n }\n }\n\n /**\n * doFreqs(sParm)\n *\n * @this {DebuggerX86}\n * @param {string|undefined} sParm\n */\n doFreqs(sParm)\n {\n if (sParm == '?') {\n this.println(\"frequency commands:\");\n this.println(\"\\tclear\\tclear all frequency counts\");\n return;\n }\n var i;\n var cData = 0;\n if (this.aaOpcodeCounts) {\n if (sParm == \"clear\") {\n for (i = 0; i < this.aaOpcodeCounts.length; i++)\n this.aaOpcodeCounts[i] = [i, 0];\n this.println(\"frequency data cleared\");\n cData++;\n }\n else if (sParm !== undefined) {\n this.println(\"unknown frequency command: \" + sParm);\n cData++;\n }\n else {\n var aaSortedOpcodeCounts = this.aaOpcodeCounts.slice();\n aaSortedOpcodeCounts.sort(function(p, q) {\n return q[1] - p[1];\n });\n for (i = 0; i < aaSortedOpcodeCounts.length; i++) {\n var bOpcode = aaSortedOpcodeCounts[i][0];\n var cFreq = aaSortedOpcodeCounts[i][1];\n if (cFreq) {\n this.println((DebuggerX86.INS_NAMES[this.aaOpDescs[bOpcode][0]] + \" \").substr(0, 5) + \" (\" + Str.toHexByte(bOpcode) + \"): \" + cFreq + \" times\");\n cData++;\n }\n }\n }\n }\n if (!cData) {\n this.println(\"no frequency data available\");\n }\n }\n\n /**\n * doHalt(fQuiet)\n *\n * @this {DebuggerX86}\n * @param {boolean} [fQuiet]\n */\n doHalt(fQuiet)\n {\n if (!this.stopCPU()) {\n if (this.isBusy(true)) return;\n if (!fQuiet) this.println(\"already halted\");\n }\n }\n\n /**\n * doIf(sCmd, fQuiet)\n *\n * NOTE: Don't forget that the default base for all numeric constants is 16 (hex), so when you evaluate\n * an expression like \"a==10\", it will compare the value of the variable \"a\" to 0x10; use a trailing period\n * (eg, \"10.\") if you really intend decimal.\n *\n * Also, if no variable named \"a\" exists, \"a\" will evaluate to 0x0A, so the expression \"a==10\" becomes\n * \"0x0A==0x10\" (false), whereas the expression \"a==10.\" becomes \"0x0A==0x0A\" (true).\n *\n * @this {DebuggerX86}\n * @param {string} sCmd\n * @param {boolean} [fQuiet]\n * @return {boolean} true if expression is non-zero, false if zero (or undefined due to a parse error)\n */\n doIf(sCmd, fQuiet)\n {\n sCmd = Str.trim(sCmd);\n if (!this.parseExpression(sCmd)) {\n if (!fQuiet) this.println(\"false: \" + sCmd);\n return false;\n }\n if (!fQuiet) this.println(\"true: \" + sCmd);\n return true;\n }\n\n /**\n * doInfo(asArgs)\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n * @return {boolean} true only if the instruction info command (\"n\") is supported\n */\n doInfo(asArgs)\n {\n if (DEBUG) {\n this.println(\"msPerYield: \" + this.cpu.counts.msPerYield);\n this.println(\"nCyclesPerYield: \" + this.cpu.counts.nCyclesPerYield);\n return true;\n }\n return false;\n }\n\n /**\n * doInput(sPort)\n *\n * Simulate a 1-byte port input operation.\n *\n * @this {DebuggerX86}\n * @param {string|undefined} sPort\n */\n doInput(sPort)\n {\n if (!sPort || sPort == '?') {\n this.println(\"input commands:\");\n this.println(\"\\ti [p]\\tread port [p]\");\n /*\n * TODO: Regarding this warning, consider adding an \"unchecked\" version of\n * bus.checkPortInputNotify(), since all Debugger memory accesses are unchecked, too.\n *\n * All port I/O handlers ARE aware when the Debugger is calling (addrFrom is undefined),\n * but changing them all to be non-destructive would take time, and situations where you\n * actually want to affect the hardware state are just as likely as not....\n */\n this.println(\"warning: port accesses can affect hardware state\");\n return;\n }\n var port = this.parseValue(sPort);\n if (port !== undefined) {\n var bIn = this.bus.checkPortInputNotify(port, 1);\n this.println(Str.toHexWord(port) + \": \" + Str.toHexByte(bIn));\n }\n }\n\n /**\n * doInt(sInt)\n *\n * Displays information about the given software interrupt (assuming that said interrupt is in progress).\n *\n * These messages also reset the system variable $ops (by updating cOpcodesStart), to make it easier to see\n * how many opcodes were executed since these interrupts \"started\".\n *\n * @this {DebuggerX86}\n * @param {string|undefined} sInt\n * @return {boolean} true if successful, false if not\n */\n doInt(sInt)\n {\n switch(this.parseValue(sInt)) {\n case 0x13:\n this.messageInt(Interrupts.DISK, this.cpu.regLIP, true);\n this.cOpcodesStart = this.cOpcodes;\n return true;\n case 0x21:\n this.messageInt(Interrupts.DOS, this.cpu.regLIP, true);\n this.cOpcodesStart = this.cOpcodes;\n return true;\n default:\n return false;\n }\n }\n\n /**\n * doVar(sCmd)\n *\n * The command must be of the form \"{variable} = [{expression}]\", where expression may contain constants,\n * operators, registers, symbols, other variables, or nothing at all; in the latter case, the variable, if\n * any, is deleted.\n *\n * Other supported shorthand: \"var\" with no parameters prints the values of all variables, and \"var {variable}\"\n * prints the value of the specified variable.\n *\n * @this {DebuggerX86}\n * @param {string} sCmd\n * @return {boolean} true if valid \"var\" assignment, false if not\n */\n doVar(sCmd)\n {\n var a = sCmd.match(/^\\s*([A-Z_]?[A-Z0-9_]*)\\s*(=?)\\s*(.*)$/i);\n if (a) {\n if (!a[1]) {\n if (!this.printVariable()) this.println(\"no variables\");\n return true; // it's not considered an error to print an empty list of variables\n }\n if (!a[2]) {\n return this.printVariable(a[1]);\n }\n if (!a[3]) {\n this.delVariable(a[1]);\n return true; // it's not considered an error to delete a variable that didn't exist\n }\n var v = this.parseExpression(a[3]);\n if (v !== undefined) {\n this.setVariable(a[1], v);\n return true;\n }\n return false;\n }\n this.println(\"invalid assignment:\" + sCmd);\n return false;\n }\n\n /**\n * doList(sAddr, fPrint)\n *\n * @this {DebuggerX86}\n * @param {string} sAddr\n * @param {boolean} [fPrint]\n * @return {string|null}\n */\n doList(sAddr, fPrint)\n {\n var sSymbol = null;\n\n var dbgAddr = this.parseAddr(sAddr, true);\n if (dbgAddr) {\n\n var addr = this.getAddr(dbgAddr);\n if (MAXDEBUG && fPrint) {\n this.println(this.toHexAddr(dbgAddr) + \" (%\" + Str.toHex(addr, this.cchAddr) + ')');\n }\n\n var aSymbol = this.findSymbol(dbgAddr, true);\n if (aSymbol.length) {\n var nDelta, sDelta, s;\n if (aSymbol[0]) {\n sDelta = \"\";\n nDelta = dbgAddr.off - aSymbol[1];\n if (nDelta) sDelta = \" + \" + Str.toHex(nDelta, 0, true);\n s = aSymbol[0] + \" (\" + this.toHexOffset(aSymbol[1], dbgAddr.sel) + ')' + sDelta;\n if (fPrint) this.println(s);\n sSymbol = s;\n }\n if (aSymbol.length > 4 && aSymbol[4]) {\n sDelta = \"\";\n nDelta = aSymbol[5] - dbgAddr.off;\n if (nDelta) sDelta = \" - \" + Str.toHex(nDelta, 0, true);\n s = aSymbol[4] + \" (\" + this.toHexOffset(aSymbol[5], dbgAddr.sel) + ')' + sDelta;\n if (fPrint) this.println(s);\n if (!sSymbol) sSymbol = s;\n }\n } else {\n if (fPrint) this.println(\"no symbols\");\n }\n }\n return sSymbol;\n }\n\n /**\n * doLoad(asArgs)\n *\n * The format of this command mirrors the DOS DEBUG \"L\" command:\n *\n * l [address] [drive #] [sector #] [# sectors]\n *\n * The only optional parameter is the last, which defaults to 1 sector if not specified.\n *\n * As a quick-and-dirty way of getting the current contents of a disk image as a JSON dump\n * (which you can then save as .json disk image file), I also support this command:\n *\n * l json [drive #]\n *\n * which is aliased to this command:\n *\n * d disk [drive #]\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n */\n doLoad(asArgs)\n {\n if (!asArgs[1] || asArgs[1] == '?') {\n this.println(\"load commands:\");\n this.println(\"\\tl [address] [drive #] [sector #] [# sectors]\");\n return;\n }\n\n var fJSON = (asArgs[1] == \"json\");\n var iDrive, iSector = 0, nSectors = 0;\n\n var dbgAddr = (fJSON? {} : this.parseAddr(asArgs[1]));\n if (!dbgAddr) return;\n\n iDrive = this.parseValue(asArgs[2], \"drive #\");\n if (iDrive === undefined) return;\n if (!fJSON) {\n iSector = this.parseValue(asArgs[3], \"sector #\");\n if (iSector === undefined) return;\n nSectors = this.parseValue(asArgs[4], \"# of sectors\");\n if (nSectors === undefined) nSectors = 1;\n }\n\n /*\n * We choose the disk controller very simplistically: FDC for drives 0 or 1, and HDC for drives 2\n * and up, unless no HDC is present, in which case we assume FDC for all drive numbers.\n *\n * Both controllers must obviously support the same interfaces; ie, copyDrive(), seekDrive(),\n * and readData(). We also rely on the disk property to determine whether the drive is \"loaded\".\n *\n * In the case of the HDC, if the drive is valid, then by definition it is also \"loaded\", since an HDC\n * drive and its disk are inseparable; it's certainly possible that the disk object may be empty at\n * this point (ie, if the disk is uninitialized and unformatted), but that will only affect whether the\n * read succeeds or not.\n */\n var dc = this.fdc;\n if (iDrive >= 2 && this.hdc) {\n iDrive -= 2;\n dc = this.hdc;\n }\n if (dc) {\n var drive = dc.copyDrive(iDrive);\n if (drive) {\n if (drive.disk) {\n if (fJSON) {\n /*\n * This is an interim solution to dumping disk images in JSON. It has many problems, the\n * \"biggest\" being that the large disk images really need to be compressed first, because they\n * get \"inflated\" with use. See the dump() method in the Disk component for more details.\n */\n this.doClear();\n this.println(drive.disk.convertToJSON());\n return;\n }\n if (dc.seekDrive(drive, iSector, nSectors)) {\n var cb = 0;\n var fAbort = false;\n var sAddr = this.toHexAddr(dbgAddr);\n while (!fAbort && drive.nBytes-- > 0) {\n (function(dbg, dbgAddrCur) {\n dc.readData(drive, function(b, fAsync) {\n if (b < 0) {\n dbg.println(\"out of data at address \" + dbg.toHexAddr(dbgAddrCur));\n fAbort = true;\n return;\n }\n dbg.setByte(dbgAddrCur, b, 1, true);\n cb++;\n });\n }(this, dbgAddr));\n }\n /*\n * Call updateCPU() now, since we forced setByte() to defer all updates\n */\n this.cpu.updateCPU(true);\n this.println(cb + \" bytes read at \" + sAddr);\n } else {\n this.println(\"sector \" + iSector + \" request out of range\");\n }\n } else {\n this.println(\"drive \" + iDrive + \" not loaded\");\n }\n } else {\n this.println(\"invalid drive: \" + iDrive);\n }\n } else {\n this.println(\"disk controller not present\");\n }\n }\n\n /**\n * doMessages(asArgs)\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n */\n doMessages(asArgs)\n {\n let m;\n let fCriteria = null;\n let sCategory = asArgs[1];\n if (sCategory == '?') sCategory = undefined;\n\n if (sCategory !== undefined) {\n let bitsMessage = 0;\n if (sCategory == \"all\") {\n bitsMessage = (0xffffffff|0) & ~(Messages.HALT | Messages.BUFFER);\n sCategory = null;\n } else if (sCategory == \"on\") {\n fCriteria = true;\n sCategory = null;\n } else if (sCategory == \"off\") {\n fCriteria = false;\n sCategory = null;\n } else {\n for (m in Messages.CATEGORIES) {\n if (sCategory == m) {\n bitsMessage = Messages.CATEGORIES[m];\n fCriteria = ((this.bitsMessage & bitsMessage) === bitsMessage);\n break;\n }\n }\n if (!bitsMessage) {\n this.println(\"unknown message category: \" + sCategory);\n return;\n }\n }\n if (bitsMessage) {\n if (asArgs[2] == \"on\") {\n this.bitsMessage |= bitsMessage;\n fCriteria = true;\n }\n else if (asArgs[2] == \"off\") {\n this.bitsMessage &= ~bitsMessage;\n if (!(this.bitsMessage & 0xF0000000) && bitsMessage) {\n this.bitsMessage = 0; // if all the high (shared) bits were turned off, ensure all the low bits are off as well.\n }\n fCriteria = false;\n if (bitsMessage == Messages.BUFFER) {\n for (var i = 0; i < this.aMessageBuffer.length; i++) {\n this.println(this.aMessageBuffer[i]);\n }\n this.aMessageBuffer = [];\n }\n }\n }\n }\n\n /*\n * Display those message categories that match the current criteria (on or off)\n */\n let n = 0;\n let sCategories = \"\";\n for (m in Messages.CATEGORIES) {\n if (!sCategory || sCategory == m) {\n let bitsMessage = Messages.CATEGORIES[m];\n let fEnabled = ((this.bitsMessage & bitsMessage) === bitsMessage);\n if (fCriteria !== null && fCriteria != fEnabled) continue;\n if (sCategories) sCategories += ',';\n if (!(++n % 10)) sCategories += \"\\n\\t\"; // jshint ignore:line\n sCategories += m;\n }\n }\n\n if (sCategory === undefined) {\n this.println(\"message commands:\\n\\tm [category] [on|off]\\tturn categories on/off\");\n }\n\n this.println((fCriteria !== null? (fCriteria? \"messages on: \" : \"messages off: \") : \"message categories:\\n\\t\") + (sCategories || \"none\"));\n\n this.historyInit(); // call this just in case Messages.INT was turned on\n }\n\n /**\n * doMouse(sAction, sDelta)\n *\n * When using the \"click\" action, specify 0 for Mouse.BUTTON.LEFT or 2 for Mouse.BUTTON.RIGHT.\n *\n * @this {DebuggerX86}\n * @param {string} sAction\n * @param {string} sDelta\n */\n doMouse(sAction, sDelta)\n {\n if (this.mouse) {\n var sign = 1;\n if (sDelta.charAt(0) == '-') {\n sign = -1;\n sDelta = sDelta.substr(1);\n }\n var n = this.parseValue(sDelta, sAction);\n if (n === undefined) return;\n n = (n * sign)|0;\n switch(sAction) {\n case \"x\":\n this.mouse.moveMouse(n, 0);\n break;\n case \"y\":\n this.mouse.moveMouse(0, n);\n break;\n case \"click\":\n this.mouse.clickMouse(n, true);\n this.mouse.clickMouse(n, false);\n break;\n default:\n this.println(\"unknown action: \" + sAction);\n break;\n }\n return;\n }\n this.println(\"no mouse\");\n }\n\n /**\n * doExecOptions(asArgs)\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n */\n doExecOptions(asArgs)\n {\n if (!asArgs[1] || asArgs[1] == '?') {\n this.println(\"execution options:\");\n this.println(\"\\tcs int #\\tset checksum cycle interval to #\");\n this.println(\"\\tcs start #\\tset checksum cycle start count to #\");\n this.println(\"\\tcs stop #\\tset checksum cycle stop count to #\");\n this.println(\"\\tsp #\\t\\tset speed multiplier to #\");\n return;\n }\n switch (asArgs[1]) {\n case \"cs\":\n var nCycles;\n if (asArgs[3] !== undefined) nCycles = +asArgs[3]; // warning: decimal instead of hex conversion\n switch (asArgs[2]) {\n case \"int\":\n this.cpu.counts.nCyclesChecksumInterval = nCycles;\n break;\n case \"start\":\n this.cpu.counts.nCyclesChecksumStart = nCycles;\n break;\n case \"stop\":\n this.cpu.counts.nCyclesChecksumStop = nCycles;\n break;\n default:\n this.println(\"unknown cs option\");\n return;\n }\n if (nCycles !== undefined) {\n this.cpu.resetChecksum();\n }\n this.println(\"checksums \" + (this.cpu.flags.checksum? \"enabled\" : \"disabled\"));\n break;\n case \"sp\":\n if (asArgs[2] !== undefined) {\n if (!this.cpu.setSpeed(+asArgs[2])) {\n this.println(\"warning: using 1x multiplier, previous target not reached\");\n }\n }\n this.println(\"target speed: \" + this.cpu.getSpeedTarget() + \" (\" + this.cpu.getSpeed() + \"x)\");\n break;\n default:\n this.println(\"unknown option: \" + asArgs[1]);\n break;\n }\n }\n\n /**\n * doOutput(sPort, sByte)\n *\n * Simulate a 1-byte port output operation.\n *\n * @this {DebuggerX86}\n * @param {string|undefined} sPort\n * @param {string|undefined} sByte (string representation of 1 byte)\n */\n doOutput(sPort, sByte)\n {\n if (!sPort || sPort == '?') {\n this.println(\"output commands:\");\n this.println(\"\\to [p] [b]\\twrite byte [b] to port [p]\");\n /*\n * TODO: Regarding this warning, consider adding an \"unchecked\" version of\n * bus.checkPortOutputNotify(), since all Debugger memory accesses are unchecked, too.\n *\n * All port I/O handlers ARE aware when the Debugger is calling (addrFrom is undefined),\n * but changing them all to be non-destructive would take time, and situations where you\n * actually want to affect the hardware state are just as likely as not....\n */\n this.println(\"warning: port accesses can affect hardware state\");\n return;\n }\n var port = this.parseValue(sPort, \"port #\");\n var bOut = this.parseValue(sByte);\n if (port !== undefined && bOut !== undefined) {\n this.bus.checkPortOutputNotify(port, 1, bOut);\n this.println(Str.toHexWord(port) + \": \" + Str.toHexByte(bOut));\n }\n }\n\n /**\n * doRegisters(asArgs, fInstruction)\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} [asArgs]\n * @param {boolean} [fInstruction] (true to include the current instruction; default is true)\n */\n doRegisters(asArgs, fInstruction)\n {\n if (asArgs && asArgs[1] == '?') {\n this.println(\"register commands:\");\n this.println(\"\\tr\\tdump registers\");\n if (this.fpu) this.println(\"\\trfp\\tdump floating-point registers\");\n this.println(\"\\trp\\tdump all registers\");\n this.println(\"\\trx [#]\\tset flag or register x to [#]\");\n return;\n }\n\n var fProt;\n if (fInstruction == null) fInstruction = true;\n\n if (asArgs != null && asArgs.length > 1) {\n var sReg = asArgs[1];\n if (this.fpu && sReg == \"fp\") {\n this.doFPURegisters(asArgs);\n return;\n }\n if (sReg == 'p') {\n fProt = (this.cpu.model >= X86.MODEL_80286);\n }\n else {\n // fInstruction = false;\n var sValue = null;\n var i = sReg.indexOf('=');\n if (i > 0) {\n sValue = sReg.substr(i + 1);\n sReg = sReg.substr(0, i);\n }\n else if (asArgs.length > 2) {\n sValue = asArgs[2];\n }\n else {\n this.println(\"missing value for \" + asArgs[1]);\n return;\n }\n\n var w = this.parseExpression(sValue);\n if (w === undefined) return;\n\n var fValid = true;\n var sRegMatch = sReg.toUpperCase();\n if (sRegMatch.charAt(0) == 'E' && this.cchReg <= 4) {\n sRegMatch = null;\n }\n switch (sRegMatch) {\n case \"AL\":\n this.cpu.regEAX = (this.cpu.regEAX & ~0xff) | (w & 0xff);\n break;\n case \"AH\":\n this.cpu.regEAX = (this.cpu.regEAX & ~0xff00) | ((w << 8) & 0xff);\n break;\n case \"AX\":\n this.cpu.regEAX = (this.cpu.regEAX & ~0xffff) | (w & 0xffff);\n break;\n case \"BL\":\n this.cpu.regEBX = (this.cpu.regEBX & ~0xff) | (w & 0xff);\n break;\n case \"BH\":\n this.cpu.regEBX = (this.cpu.regEBX & ~0xff00) | ((w << 8) & 0xff);\n break;\n case \"BX\":\n this.cpu.regEBX = (this.cpu.regEBX & ~0xffff) | (w & 0xffff);\n break;\n case \"CL\":\n this.cpu.regECX = (this.cpu.regECX & ~0xff) | (w & 0xff);\n break;\n case \"CH\":\n this.cpu.regECX = (this.cpu.regECX & ~0xff00) | ((w << 8) & 0xff);\n break;\n case \"CX\":\n this.cpu.regECX = (this.cpu.regECX & ~0xffff) | (w & 0xffff);\n break;\n case \"DL\":\n this.cpu.regEDX = (this.cpu.regEDX & ~0xff) | (w & 0xff);\n break;\n case \"DH\":\n this.cpu.regEDX = (this.cpu.regEDX & ~0xff00) | ((w << 8) & 0xff);\n break;\n case \"DX\":\n this.cpu.regEDX = (this.cpu.regEDX & ~0xffff) | (w & 0xffff);\n break;\n case \"SP\":\n this.cpu.setSP((this.cpu.getSP() & ~0xffff) | (w & 0xffff));\n break;\n case \"BP\":\n this.cpu.regEBP = (this.cpu.regEBP & ~0xffff) | (w & 0xffff);\n break;\n case \"SI\":\n this.cpu.regESI = (this.cpu.regESI & ~0xffff) | (w & 0xffff);\n break;\n case \"DI\":\n this.cpu.regEDI = (this.cpu.regEDI & ~0xffff) | (w & 0xffff);\n break;\n /*\n * DANGER: For any of the segment loads below, by going through the normal CPU\n * segment load procedure, you run the risk of generating a fault in the machine\n * if you're not careful. So, um, be careful.\n */\n case \"DS\":\n this.cpu.setDS(w);\n break;\n case \"ES\":\n this.cpu.setES(w);\n break;\n case \"SS\":\n this.cpu.setSS(w);\n break;\n case \"CS\":\n // fInstruction = true;\n this.cpu.setCS(w);\n this.dbgAddrNextCode = this.newAddr(this.cpu.getIP(), this.cpu.getCS());\n break;\n case \"IP\":\n case \"EIP\":\n // fInstruction = true;\n this.cpu.setIP(w);\n this.dbgAddrNextCode = this.newAddr(this.cpu.getIP(), this.cpu.getCS());\n break;\n /*\n * I used to alias \"PC\" (Program Counter) to \"IP\" (Instruction Pointer), because in PC-DOS 1.00\n * through 2.10, DEBUG.COM did the same thing. Then I discovered that, starting with PC-DOS 3.00,\n * DEBUG.COM changed \"PC\" to refer to the 16-bit flags register (Program or Processor Control?)\n * I've elected to go for PC-DOS 3.00+ compatibility, since that will be more widely known.\n *\n * PCx86 prefers \"PS\" (Processor Status) for accessing the FLAGS register in its 16-bit (or 32-bit)\n * entirety. Individual flag bits can also be accessed as 1-bit registers, using the names shown\n * below (\"C\", \"P\", \"A\", \"Z\", etc.)\n */\n case \"PC\":\n case \"PS\":\n this.cpu.setPS(w);\n break;\n case 'C':\n if (w) this.cpu.setCF(); else this.cpu.clearCF();\n break;\n case 'P':\n if (w) this.cpu.setPF(); else this.cpu.clearPF();\n break;\n case 'A':\n if (w) this.cpu.setAF(); else this.cpu.clearAF();\n break;\n case 'Z':\n if (w) this.cpu.setZF(); else this.cpu.clearZF();\n break;\n case 'S':\n if (w) this.cpu.setSF(); else this.cpu.clearSF();\n break;\n case 'I':\n if (w) this.cpu.setIF(); else this.cpu.clearIF();\n break;\n case 'D':\n if (w) this.cpu.setDF(); else this.cpu.clearDF();\n break;\n case 'V':\n if (w) this.cpu.setOF(); else this.cpu.clearOF();\n break;\n default:\n var fUnknown = true;\n if (this.cpu.model >= X86.MODEL_80286) {\n fUnknown = false;\n switch(sRegMatch){\n case \"MS\":\n this.cpu.setMSW(w);\n break;\n case \"TR\":\n /*\n * DANGER: Like any of the segment loads above, by going through the normal CPU\n * segment load procedure, you run the risk of generating a fault in the machine\n * if you're not careful. So, um, be careful.\n */\n if (this.cpu.segTSS.load(w) === X86.ADDR_INVALID) {\n fValid = false;\n }\n break;\n /*\n * TODO: Add support for GDTR (addr and limit), IDTR (addr and limit), and perhaps\n * even the ability to edit descriptor information associated with each segment register.\n */\n default:\n fUnknown = true;\n if (I386 && this.cpu.model >= X86.MODEL_80386) {\n fUnknown = false;\n switch(sRegMatch){\n case \"EAX\":\n this.cpu.regEAX = w;\n break;\n case \"EBX\":\n this.cpu.regEBX = w;\n break;\n case \"ECX\":\n this.cpu.regECX = w;\n break;\n case \"EDX\":\n this.cpu.regEDX = w;\n break;\n case \"ESP\":\n this.cpu.setSP(w);\n break;\n case \"EBP\":\n this.cpu.regEBP = w;\n break;\n case \"ESI\":\n this.cpu.regESI = w;\n break;\n case \"EDI\":\n this.cpu.regEDI = w;\n break;\n /*\n * DANGER: For any of the segment loads below, by going through the normal CPU\n * segment load procedure, you run the risk of generating a fault in the machine\n * if you're not careful. So, um, be careful.\n */\n case \"FS\":\n this.cpu.setFS(w);\n break;\n case \"GS\":\n this.cpu.setGS(w);\n break;\n case \"CR0\":\n this.cpu.regCR0 = w;\n X86.helpLoadCR0.call(this.cpu, w);\n break;\n case \"CR2\":\n this.cpu.regCR2 = w;\n break;\n case \"CR3\":\n this.cpu.regCR3 = w;\n X86.helpLoadCR3.call(this.cpu, w);\n break;\n /*\n * TODO: Add support for DR0-DR7 and TR6-TR7.\n */\n default:\n fUnknown = true;\n break;\n }\n }\n break;\n }\n }\n if (fUnknown) {\n this.println(\"unknown register: \" + sReg);\n return;\n }\n }\n if (!fValid) {\n this.println(\"invalid value: \" + sValue);\n return;\n }\n this.cpu.updateCPU();\n this.println(\"updated registers:\");\n }\n }\n\n this.println(this.getRegDump(fProt));\n\n if (fInstruction) {\n this.dbgAddrNextCode = this.newAddr(this.cpu.getIP(), this.cpu.getCS());\n this.doUnassemble(this.toHexAddr(this.dbgAddrNextCode));\n }\n }\n\n /**\n * doFPURegisters(asArgs)\n *\n * NOTE: If we're called, the existence of an FPU has already been verified.\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} [asArgs]\n */\n doFPURegisters(asArgs)\n {\n var fpu = this.fpu;\n\n var wStatus = fpu.getStatus(), wControl = fpu.getControl();\n for (var i = 0; i < 8; i++) {\n var a = fpu.readFPUStack(i);\n if (!a) break;\n var sValue = Str.pad(a[2].toFixed(15), 24, true);\n this.println(\"ST\" + i + \": \" + sValue + \" \" + Str.toHex(a[4]) + \",\" + Str.toHex(a[3]) + \" [\" + a[0] + \":\" + DebuggerX86.FPU_TAGS[a[1]] + \"]\");\n // this.println(\" REG\" + a[0] + \" \" + Str.toBin(a[7], 16) + Str.toBin(a[6]) + Str.toBin(a[5]));\n }\n this.println(\" B3SSS210ESPUOZDI xxxIRRPPIxPUOZDI\");\n this.println(\"SW: \" + Str.toBin(wStatus, 16) + \" (\" + Str.toHexWord(wStatus) + \") CW: \" + Str.toBin(wControl, 16) + \" (\" + Str.toHexWord(wControl) + \")\");\n }\n\n /**\n * doRun(sCmd, sAddr, sOptions, fQuiet)\n *\n * @this {DebuggerX86}\n * @param {string} sCmd\n * @param {string|undefined} [sAddr]\n * @param {string} [sOptions] (the rest of the breakpoint command-line)\n * @param {boolean} [fQuiet]\n */\n doRun(sCmd, sAddr, sOptions, fQuiet)\n {\n if (sCmd == \"gt\") {\n this.fIgnoreNextCheckFault = true;\n }\n if (sAddr !== undefined) {\n var dbgAddr = this.parseAddr(sAddr, true);\n if (!dbgAddr) return;\n this.parseAddrOptions(dbgAddr, sOptions);\n this.setTempBreakpoint(dbgAddr);\n }\n this.startCPU(true, fQuiet);\n }\n\n /**\n * doPrint(sCmd)\n *\n * NOTE: If the string to print is a quoted string, then we run it through replaceRegs(), so that\n * you can take advantage of all the special replacement options used for software interrupt logging.\n *\n * @this {DebuggerX86}\n * @param {string} sCmd\n */\n doPrint(sCmd)\n {\n sCmd = Str.trim(sCmd);\n var a = sCmd.match(/^(['\"])(.*?)\\1$/);\n if (!a) {\n this.parseExpression(sCmd, false);\n } else {\n this.println(this.replaceRegs(a[2]));\n }\n }\n\n /**\n * doStep(sCmd)\n *\n * @this {DebuggerX86}\n * @param {string} [sCmd] \"p\" or \"pr\"\n */\n doStep(sCmd)\n {\n var fCallStep = true;\n var nRegs = (sCmd == \"pr\"? 1 : 0);\n /*\n * Set up the value for this.nStep (ie, 1 or 2) depending on whether the user wants\n * a subsequent register dump (\"pr\") or not (\"p\").\n */\n var nStep = 1 + nRegs;\n if (!this.nStep) {\n var fPrefix;\n var fRepeat = false;\n var dbgAddr = this.newAddr(this.cpu.getIP(), this.cpu.getCS());\n do {\n fPrefix = false;\n var bOpcode = this.getByte(dbgAddr);\n switch (bOpcode) {\n case X86.OPCODE.ES:\n case X86.OPCODE.CS:\n case X86.OPCODE.SS:\n case X86.OPCODE.DS:\n case X86.OPCODE.FS: // I386 only\n case X86.OPCODE.GS: // I386 only\n case X86.OPCODE.OS: // I386 only\n case X86.OPCODE.AS: // I386 only\n case X86.OPCODE.LOCK:\n this.incAddr(dbgAddr, 1);\n fPrefix = true;\n break;\n case X86.OPCODE.INT3:\n case X86.OPCODE.INTO:\n this.nStep = nStep;\n this.incAddr(dbgAddr, 1);\n break;\n case X86.OPCODE.INTN:\n case X86.OPCODE.LOOPNZ:\n case X86.OPCODE.LOOPZ:\n case X86.OPCODE.LOOP:\n this.nStep = nStep;\n this.incAddr(dbgAddr, dbgAddr.fData32? 4 : 2);\n break;\n case X86.OPCODE.CALL:\n if (fCallStep) {\n this.nStep = nStep;\n this.incAddr(dbgAddr, dbgAddr.fData32? 5 : 3);\n }\n break;\n case X86.OPCODE.CALLF:\n if (fCallStep) {\n this.nStep = nStep;\n this.incAddr(dbgAddr, dbgAddr.fData32? 7 : 5);\n }\n break;\n case X86.OPCODE.GRP4W:\n if (fCallStep) {\n var w = this.getWord(dbgAddr) & X86.OPCODE.CALLMASK;\n if (w == X86.OPCODE.CALLW || w == X86.OPCODE.CALLFDW) {\n this.nStep = nStep;\n this.getInstruction(dbgAddr); // advance dbgAddr past this variable-length CALL\n }\n }\n break;\n case X86.OPCODE.REPZ:\n case X86.OPCODE.REPNZ:\n this.incAddr(dbgAddr, 1);\n fRepeat = fPrefix = true;\n break;\n case X86.OPCODE.INSB:\n case X86.OPCODE.INSW:\n case X86.OPCODE.OUTSB:\n case X86.OPCODE.OUTSW:\n case X86.OPCODE.MOVSB:\n case X86.OPCODE.MOVSW:\n case X86.OPCODE.CMPSB:\n case X86.OPCODE.CMPSW:\n case X86.OPCODE.STOSB:\n case X86.OPCODE.STOSW:\n case X86.OPCODE.LODSB:\n case X86.OPCODE.LODSW:\n case X86.OPCODE.SCASB:\n case X86.OPCODE.SCASW:\n if (fRepeat) {\n this.nStep = nStep;\n this.incAddr(dbgAddr, 1);\n }\n break;\n default:\n break;\n }\n } while (fPrefix);\n\n if (this.nStep) {\n this.setTempBreakpoint(dbgAddr);\n if (!this.startCPU()) {\n if (this.cmp) this.cmp.updateFocus();\n this.nStep = 0;\n }\n /*\n * A successful run will ultimately call stop(), which will in turn call clearTempBreakpoint(),\n * which will clear nStep, so there's your assurance that nStep will be reset. Now we may have\n * stopped for reasons unrelated to the temporary breakpoint, but that's OK.\n */\n } else {\n this.doTrace(nRegs? \"tr\" : \"t\");\n }\n } else {\n this.println(\"step in progress\");\n }\n }\n\n /**\n * getCall(dbgAddr, fFar)\n *\n * Given a possible return address (typically from the stack), look for a matching CALL (or INT) that\n * immediately precedes that address.\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {boolean} [fFar]\n * @return {string|null} CALL instruction at or near dbgAddr, or null if none\n */\n getCall(dbgAddr, fFar)\n {\n var sCall = null;\n var off = dbgAddr.off;\n var offOrig = off;\n for (var n = 1; n <= 6 && !!off; n++) {\n if (n > 2) {\n dbgAddr.off = off;\n dbgAddr.addr = null;\n var s = this.getInstruction(dbgAddr);\n if (s.indexOf(\"CALL\") >= 0 || fFar && s.indexOf(\"INT\") >= 0) {\n /*\n * Verify that the length of this CALL (or INT), when added to the address of the CALL (or INT),\n * matches the original return address. We do this by getting the string index of the opcode bytes,\n * subtracting that from the string index of the next space, and dividing that difference by two,\n * to yield the length of the CALL (or INT) instruction, in bytes.\n */\n var i = s.indexOf(' ');\n var j = s.indexOf(' ', i+1);\n if (off + (j - i - 1)/2 == offOrig) {\n sCall = s;\n break;\n }\n }\n }\n off--;\n }\n dbgAddr.off = offOrig;\n return sCall;\n }\n\n /**\n * doStackTrace(sCmd, sAddr)\n *\n * Use \"k\" for a normal stack trace and \"ks\" for a stack trace with symbolic info.\n *\n * @this {DebuggerX86}\n * @param {string} [sCmd]\n * @param {string} [sAddr] (not used yet)\n */\n doStackTrace(sCmd, sAddr)\n {\n if (sAddr == '?') {\n this.println(\"stack trace commands:\");\n this.println(\"\\tk\\tshow frame addresses\");\n this.println(\"\\tks\\tshow symbol information\");\n return;\n }\n\n var nFrames = 10, cFrames = 0;\n var selCode = this.cpu.segCS.sel;\n var dbgAddrCall = this.newAddr();\n var dbgAddrStack = this.newAddr(this.cpu.getSP(), this.cpu.getSS());\n this.println(\"stack trace for \" + this.toHexAddr(dbgAddrStack));\n\n while (cFrames < nFrames) {\n var sCall = null, sCallPrev = null, cTests = 256;\n while ((dbgAddrStack.off >>> 0) < this.cpu.regLSPLimit) {\n dbgAddrCall.off = this.getWord(dbgAddrStack, true);\n /*\n * Because we're using the auto-increment feature of getWord(), and because that will automatically\n * wrap the offset around the end of the segment, we must also check the addr property to detect the wrap.\n */\n if (dbgAddrStack.addr == null || !cTests--) break;\n dbgAddrCall.sel = selCode;\n sCall = this.getCall(dbgAddrCall);\n if (sCall) break;\n dbgAddrCall.sel = this.getWord(dbgAddrStack);\n sCall = this.getCall(dbgAddrCall, true);\n if (sCall) {\n selCode = this.getWord(dbgAddrStack, true);\n /*\n * It's not strictly necessary that we skip over the flags word that's pushed as part of any INT\n * instruction, but it reduces the risk of misinterpreting it as a return address on the next iteration.\n */\n if (sCall.indexOf(\"INT\") > 0) this.getWord(dbgAddrStack, true);\n break;\n }\n }\n /*\n * The sCallPrev check eliminates duplicate sequential calls, which are usually (but not always)\n * indicative of a false positive, in which case the previous call is probably bogus as well, but\n * at least we won't duplicate that mistake. Of course, there are always exceptions, recursion\n * being one of them, but it's rare that we're debugging recursive code.\n */\n if (!sCall || sCall == sCallPrev) break;\n var sSymbol = null;\n if (sCmd == \"ks\") {\n var a = sCall.match(/[0-9A-F]+$/);\n if (a) sSymbol = this.doList(a[0]);\n }\n sCall = Str.pad(sCall, 50) + \" ;\" + (sSymbol || \"stack=\" + this.toHexAddr(dbgAddrStack)); // + \" return=\" + this.toHexAddr(dbgAddrCall));\n this.println(sCall);\n sCallPrev = sCall;\n cFrames++;\n }\n if (!cFrames) this.println(\"no return addresses found\");\n }\n\n /**\n * doTrace(sCmd, sCount)\n *\n * The \"t\" and \"tr\" commands interpret the count as a number of instructions, and since\n * we call the Debugger's stepCPU() for each iteration, a single instruction includes\n * any/all prefixes; the CPU's stepCPU() treats prefixes as discrete operations. The only\n * difference between \"t\" and \"tr\": the former displays only the next instruction, while\n * the latter also displays the (updated) registers.\n *\n * The \"tc\" command interprets the count as a number of cycles rather than instructions,\n * allowing you to quickly execute large chunks of instructions with a single command; it\n * doesn't display anything until the the chunk has finished.\n *\n * However, generally a more useful command is \"bn\", which allows you to break after some\n * number of instructions have been executed (as opposed to some number of cycles).\n *\n * @this {DebuggerX86}\n * @param {string} [sCmd] (\"t\", \"tc\", or \"tr\")\n * @param {string} [sCount] # of instructions to step\n */\n doTrace(sCmd, sCount)\n {\n var dbg = this;\n var fRegs = (sCmd != \"t\");\n var nCount = this.parseValue(sCount, null, true) || 1;\n var nCycles = (nCount == 1? 0 : 1);\n if (sCmd == \"tc\") {\n nCycles = nCount;\n nCount = 1;\n }\n Web.onCountRepeat(\n nCount,\n function onCountStep() {\n return dbg.setBusy(true) && dbg.stepCPU(nCycles, fRegs, false);\n },\n function onCountStepComplete() {\n /*\n * We explicitly called stepCPU() with fUpdateCPU === false, because repeatedly\n * calling updateCPU() can be very slow, especially when fDisplayLiveRegs is true,\n * so once the repeat count has been exhausted, we must perform a final updateCPU().\n */\n dbg.cpu.updateCPU();\n dbg.setBusy(false);\n }\n );\n }\n\n /**\n * initAddrSize(dbgAddr, fComplete, cOverrides)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {boolean} fComplete\n * @param {number} [cOverrides]\n */\n initAddrSize(dbgAddr, fComplete, cOverrides)\n {\n /*\n * We use dbgAddr.fComplete to record whether or not the caller (ie, getInstruction())\n * processed a complete instruction.\n */\n dbgAddr.fComplete = fComplete;\n /*\n * For proper disassembly of instructions preceded by an OPERAND (0x66) size prefix, we set\n * dbgAddr.fData32 to true whenever the operand size is 32-bit; similarly, for an ADDRESS (0x67)\n * size prefix, we set dbgAddr.fAddr32 to true whenever the address size is 32-bit.\n *\n * Initially (and every time we've processed a complete instruction), both fields must be\n * set to their original value.\n */\n if (fComplete) {\n if (dbgAddr.fData32Orig != null) dbgAddr.fData32 = dbgAddr.fData32Orig;\n if (dbgAddr.fAddr32Orig != null) dbgAddr.fAddr32 = dbgAddr.fAddr32Orig;\n dbgAddr.fData32Orig = dbgAddr.fData32;\n dbgAddr.fAddr32Orig = dbgAddr.fAddr32;\n }\n /*\n * Use cOverrides to record whether we previously processed any OPERAND or ADDRESS overrides.\n */\n dbgAddr.cOverrides = cOverrides || 0;\n }\n\n /**\n * isStringIns(bOpcode)\n *\n * @this {DebuggerX86}\n * @param {number} bOpcode\n * @return {boolean} true if string instruction, false if not\n */\n isStringIns(bOpcode)\n {\n return (bOpcode >= X86.OPCODE.MOVSB && bOpcode <= X86.OPCODE.CMPSW || bOpcode >= X86.OPCODE.STOSB && bOpcode <= X86.OPCODE.SCASW);\n }\n\n /**\n * doUnassemble(sAddr, sAddrEnd, n)\n *\n * @this {DebuggerX86}\n * @param {string} [sAddr]\n * @param {string} [sAddrEnd]\n * @param {number} [n]\n */\n doUnassemble(sAddr, sAddrEnd, n)\n {\n var dbgAddr = this.parseAddr(sAddr, true);\n if (!dbgAddr) return;\n\n if (n === undefined) n = 1;\n\n var cb = 0x100;\n if (sAddrEnd !== undefined) {\n\n var dbgAddrEnd = this.parseAddr(sAddrEnd, true);\n if (!dbgAddrEnd || dbgAddrEnd.off < dbgAddr.off) return;\n\n /*\n * We now +1 the count to make the ending address inclusive (just like the dump command).\n */\n cb = dbgAddrEnd.off - dbgAddr.off + 1;\n if (cb < 0) cb = 1;\n /*\n * Limiting the amount of disassembled code to 4K helps prevent the user from wedging the browser.\n */\n if (cb > 0x1000) cb = 0x1000;\n n = -1;\n }\n\n var cLines = 0;\n var sInstruction;\n this.initAddrSize(dbgAddr, true);\n\n while (cb > 0 && n--) {\n\n var nSequence = (this.isBusy(false) || this.nStep)? this.nCycles : null;\n var sComment = (nSequence != null? \"cycles\" : null);\n var aSymbol = this.findSymbol(dbgAddr);\n\n var addr = dbgAddr.addr; // we snap dbgAddr.addr *after* calling findSymbol(), which re-evaluates it\n\n if (aSymbol[0] && n) {\n if (!cLines && n || aSymbol[0].indexOf('+') < 0) {\n var sLabel = aSymbol[0] + ':';\n if (aSymbol[2]) sLabel += ' ' + aSymbol[2];\n this.println(sLabel);\n }\n }\n\n if (aSymbol[3]) {\n sComment = aSymbol[3];\n nSequence = null;\n }\n\n sInstruction = this.getInstruction(dbgAddr, sComment, nSequence);\n\n /*\n * If getInstruction() reported that it did not process a complete instruction (via dbgAddr.fComplete),\n * then bump the instruction count by one, so that we display one more line (and hopefully the complete\n * instruction).\n */\n if (!dbgAddr.fComplete && !n) n++;\n\n this.println(sInstruction);\n this.dbgAddrNextCode = dbgAddr;\n cb -= dbgAddr.addr - addr;\n cLines++;\n }\n }\n\n /**\n * parseCommand(sCmd, fSave, chSep)\n *\n * @this {DebuggerX86}\n * @param {string|undefined} sCmd\n * @param {boolean} [fSave] is true to save the command, false if not\n * @param {string} [chSep] is the command separator character (default is ';')\n * @return {Array.<string>}\n */\n parseCommand(sCmd, fSave, chSep)\n {\n if (fSave) {\n if (!sCmd) {\n sCmd = this.aPrevCmds[this.iPrevCmd+1];\n } else {\n if (this.iPrevCmd < 0 && this.aPrevCmds.length) {\n this.iPrevCmd = 0;\n }\n if (this.iPrevCmd < 0 || sCmd != this.aPrevCmds[this.iPrevCmd]) {\n this.aPrevCmds.splice(0, 0, sCmd);\n this.iPrevCmd = 0;\n }\n this.iPrevCmd--;\n }\n }\n var a = [];\n if (sCmd) {\n /*\n * With the introduction of breakpoint commands (ie, quoted command sequences\n * associated with a breakpoint), we can no longer perform simplistic splitting.\n *\n * a = sCmd.split(chSep || ';');\n * for (var i = 0; i < a.length; i++) a[i] = Str.trim(a[i]);\n *\n * We may now split on semi-colons ONLY if they are outside a quoted sequence.\n *\n * Also, to allow quoted strings *inside* breakpoint commands, we first replace all\n * DOUBLE double-quotes with single quotes.\n */\n sCmd = sCmd.toLowerCase().replace(/\"\"/g, \"'\");\n\n var iPrev = 0;\n var chQuote = null;\n chSep = chSep || ';';\n /*\n * NOTE: Processing charAt() up to and INCLUDING length is not a typo; we're taking\n * advantage of the fact that charAt() with an invalid index returns an empty string,\n * allowing us to use the same substring() call to capture the final portion of sCmd.\n *\n * In a sense, it allows us to pretend that the string ends with a zero terminator.\n */\n for (var i = 0; i <= sCmd.length; i++) {\n var ch = sCmd.charAt(i);\n if (ch == '\"' || ch == \"'\") {\n if (!chQuote) {\n chQuote = ch;\n } else if (ch == chQuote) {\n chQuote = null;\n }\n }\n else if (ch == chSep && !chQuote || !ch) {\n /*\n * Recall that substring() accepts starting (inclusive) and ending (exclusive)\n * indexes, whereas substr() accepts a starting index and a length. We need the former.\n */\n a.push(Str.trim(sCmd.substring(iPrev, i)));\n iPrev = i + 1;\n }\n }\n }\n return a;\n }\n\n /**\n * shiftArgs(asArgs)\n *\n * Used with any command (eg, \"r\") that allows but doesn't require whitespace between command and first argument.\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n * @return {Array.<string>}\n */\n shiftArgs(asArgs)\n {\n if (asArgs && asArgs.length) {\n var s0 = asArgs[0];\n var ch0 = s0.charAt(0);\n for (var i = 1; i < s0.length; i++) {\n var ch = s0.charAt(i);\n if (ch0 == '?' || ch0 == 'r' || ch < 'a' || ch > 'z') {\n asArgs[0] = s0.substr(i);\n asArgs.unshift(s0.substr(0, i));\n break;\n }\n }\n }\n return asArgs;\n }\n\n /**\n * doCommand(sCmd, fQuiet)\n *\n * @this {DebuggerX86}\n * @param {string} sCmd\n * @param {boolean} [fQuiet]\n * @return {boolean} true if command processed, false if unrecognized\n */\n doCommand(sCmd, fQuiet)\n {\n var result = true;\n\n try {\n if (!sCmd.length || sCmd == \"end\") {\n if (this.fAssemble) {\n this.println(\"ended assemble at \" + this.toHexAddr(this.dbgAddrAssemble));\n this.dbgAddrNextCode = this.dbgAddrAssemble;\n this.fAssemble = false;\n }\n sCmd = \"\";\n }\n else if (!fQuiet) {\n var sPrompt = \">> \";\n if (this.cpu.regCR0 & X86.CR0.MSW.PE) {\n sPrompt = (this.cpu.regPS & X86.PS.VM)? \"-- \" : \"## \";\n }\n this.println(sPrompt + sCmd);\n }\n\n var ch = sCmd.charAt(0);\n if (ch == '\"' || ch == \"'\") return true;\n\n /*\n * Zap the previous message buffer to ensure the new command's output is not tossed out as a repeat.\n */\n this.sMessagePrev = null;\n\n /*\n * I've relaxed the !isBusy() requirement, to maximize our ability to issue Debugger commands externally.\n */\n if (this.isReady() /* && !this.isBusy(true) */ && sCmd.length > 0) {\n\n if (this.fAssemble) {\n sCmd = \"a \" + this.toHexAddr(this.dbgAddrAssemble) + ' ' + sCmd;\n }\n\n var asArgs = this.shiftArgs(sCmd.replace(/ +/g, ' ').split(' '));\n\n switch (asArgs[0].charAt(0)) {\n case 'a':\n this.doAssemble(asArgs);\n break;\n case 'b':\n this.doBreak(asArgs[0], asArgs[1], sCmd);\n break;\n case 'c':\n this.doClear(asArgs[0]);\n break;\n case 'd':\n if (!PCX86.COMPILED && sCmd == \"debug\") {\n window.DEBUG = true;\n this.println(\"DEBUG checks on\");\n break;\n }\n this.doDump(asArgs);\n break;\n case 'e':\n if (asArgs[0] == \"else\") break;\n this.doEdit(asArgs);\n break;\n case 'f':\n this.doFreqs(asArgs[1]);\n break;\n case 'g':\n this.doRun(asArgs[0], asArgs[1], sCmd, fQuiet);\n break;\n case 'h':\n this.doHalt(fQuiet);\n break;\n case 'i':\n if (asArgs[0] == \"if\") {\n if (!this.doIf(sCmd.substr(2), fQuiet)) {\n result = false;\n }\n break;\n }\n if (asArgs[0] == \"int\") {\n if (!this.doInt(asArgs[1])) {\n result = false;\n }\n break;\n }\n this.doInput(asArgs[1]);\n break;\n case 'k':\n this.doStackTrace(asArgs[0], asArgs[1]);\n break;\n case 'l':\n if (asArgs[0] == \"ln\") {\n this.doList(asArgs[1], true);\n break;\n }\n this.doLoad(asArgs);\n break;\n case 'm':\n if (asArgs[0] == \"mouse\") {\n this.doMouse(asArgs[1], asArgs[2]);\n break;\n }\n this.doMessages(asArgs);\n break;\n case 'o':\n this.doOutput(asArgs[1], asArgs[2]);\n break;\n case 'p':\n if (asArgs[0] == \"print\") {\n this.doPrint(sCmd.substr(5));\n break;\n }\n this.doStep(asArgs[0]);\n break;\n case 'r':\n if (sCmd == \"reset\") {\n if (this.cmp) this.cmp.reset();\n break;\n }\n this.doRegisters(asArgs);\n break;\n case 't':\n this.doTrace(asArgs[0], asArgs[1]);\n break;\n case 'u':\n this.doUnassemble(asArgs[1], asArgs[2], 8);\n break;\n case 'v':\n if (asArgs[0] == \"var\") {\n if (!this.doVar(sCmd.substr(3))) {\n result = false;\n }\n break;\n }\n this.println((PCX86.APPNAME || \"PCx86\") + \" version \" + (XMLVERSION || PCX86.APPVERSION) + \" (\" + this.cpu.model + (PCX86.COMPILED? \",RELEASE\" : (PCX86.DEBUG? \",DEBUG\" : \",NODEBUG\")) + (PCX86.PREFETCH? \",PREFETCH\" : \",NOPREFETCH\") + (PCX86.TYPEDARRAYS? \",TYPEDARRAYS\" : (PCX86.BYTEARRAYS? \",BYTEARRAYS\" : \",LONGARRAYS\")) + (PCX86.BACKTRACK? \",BACKTRACK\" : \",NOBACKTRACK\") + ')');\n this.println(Web.getUserAgent());\n break;\n case 'x':\n this.doExecOptions(asArgs);\n break;\n case '?':\n if (asArgs[1]) {\n this.doPrint(sCmd.substr(1));\n break;\n }\n this.doHelp();\n break;\n case 'n':\n if (!PCX86.COMPILED && sCmd == \"nodebug\") {\n window.DEBUG = false;\n this.println(\"DEBUG checks off\");\n break;\n }\n if (this.doInfo(asArgs)) break;\n /* falls through */\n default:\n this.println(\"unknown command: \" + sCmd);\n result = false;\n break;\n }\n }\n } catch(e) {\n this.println(\"debugger error: \" + (e.stack || e.message));\n result = false;\n }\n return result;\n }\n\n /**\n * doCommands(sCommands, fSave)\n *\n * @this {DebuggerX86}\n * @param {string} sCommands\n * @param {boolean} [fSave]\n * @return {boolean} true if all commands processed, false if not\n */\n doCommands(sCommands, fSave)\n {\n var a = this.parseCommand(sCommands, fSave);\n for (var s in a) {\n if (!this.doCommand(a[+s])) return false;\n }\n return true;\n }\n\n /**\n * DebuggerX86.init()\n *\n * This function operates on every HTML element of class \"debugger\", extracting the\n * JSON-encoded parameters for the Debugger constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Debugger component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeDbg = Component.getElementsByClass(document, PCX86.APPCLASS, \"debugger\");\n for (var iDbg = 0; iDbg < aeDbg.length; iDbg++) {\n var eDbg = aeDbg[iDbg];\n var parmsDbg = Component.getComponentParms(eDbg);\n var dbg = new DebuggerX86(parmsDbg);\n Component.bindComponentControls(dbg, eDbg, PCX86.APPCLASS);\n }\n }\n}\n\nif (DEBUGGER) {\n\n /*\n * NOTE: The Debugger properties below are considered \"class constants\"; most of them use our \"all-caps\"\n * convention (and all of them SHOULD, but that wouldn't help us catch any bugs).\n *\n * Technically, all of them should ALSO be preceded by a \"@const\" annotation, but that's a lot of work and it\n * really clutters the code. I wish the Closure Compiler had a way to annotate every definition with a given\n * section with a single annotation....\n *\n * Bugs can slip through the cracks without those annotations; for example, I unthinkingly redefined TYPE_SI\n * at one point, and if all the definitions had been preceded by an \"@const\", that mistake would have been\n * caught at compile-time.\n */\n\n /*\n * Information regarding interrupts of interest (used by messageInt() and others)\n */\n DebuggerX86.INT_MESSAGES = {\n 0x10: Messages.VIDEO,\n 0x13: Messages.FDC,\n 0x15: Messages.CHIPSET,\n 0x16: Messages.KBD,\n // 0x1A: Messages.RTC, // ChipSet contains its own custom messageInt() handler for the RTC\n 0x1C: Messages.TIMER,\n 0x21: Messages.DOS,\n 0x33: Messages.MOUSE\n };\n\n /*\n * Information regarding \"annoying\" interrupts (which aren't annoying so much as too frequent);\n * note that some of these can still be enabled if you really want them (eg, RTC can be turned on\n * with RTC messages, ALT_TIMER with TIMER messages, etc).\n */\n DebuggerX86.INT_ANNOYING = [Interrupts.RTC, Interrupts.ALT_TIMER, Interrupts.DOS_IDLE, Interrupts.DOS_NETBIOS, Interrupts.ALT_VIDEO];\n\n DebuggerX86.COMMANDS = {\n '?': \"help/print\",\n 'a [#]': \"assemble\", // TODO: Implement this command someday\n 'b [#]': \"breakpoint\", // multiple variations (use b? to list them)\n 'c': \"clear output\",\n 'd [#]': \"dump memory\", // additional syntax: d [#] [l#], where l# is a number of bytes to dump\n 'e [#]': \"edit memory\",\n 'f': \"frequencies\",\n 'g [#]': \"go [to #]\",\n 'h': \"halt\",\n 'i [#]': \"input port #\",\n 'if': \"eval expression\",\n 'k': \"stack trace\",\n 'l': \"load sector(s)\",\n \"ln\": \"list nearest symbol(s)\",\n 'm': \"messages\",\n 'mouse': \"mouse action\", // syntax: mouse {action} {delta} (eg, mouse x 10, mouse click 0, etc)\n 'o [#]': \"output port #\",\n 'p': \"step over\", // other variations: pr (step and dump registers)\n 'print': \"print expression\",\n 'r': \"dump/set registers\",\n 'reset': \"reset machine\",\n 't [#]': \"trace\", // other variations: tr (trace and dump registers)\n 'u [#]': \"unassemble\",\n 'x': \"execution options\",\n 'v': \"print version\",\n 'var': \"assign variable\"\n };\n\n /*\n * Supported address types; the type field in a DbgAddrX86 object may be one of:\n *\n * NONE, REAL, PROT, V86, LINEAR or PHYSICAL\n *\n * REAL and V86 addresses are specified with a '&' prefix, PROT addresses with a '#' prefix,\n * LINEAR addresses with '%', and PHYSICAL addresses with '%%'.\n */\n DebuggerX86.ADDRTYPE = {\n NONE: 0x00,\n REAL: 0x01,\n PROT: 0x02,\n V86: 0x03,\n LINEAR: 0x04,\n PHYSICAL: 0x05\n };\n\n /*\n * CPU instruction ordinals\n *\n * Note that individual instructions end with ordinal 162 and instruction groups begin with ordinal 163;\n * the disassembler knows it's dealing with a group whenever the ordinal is not a valid index into INS_NAMES.\n *\n * NOTE: While this list started alphabetical, there are a few wrinkles; eg, POPA/POPF/PUSHF/PUSHA are\n * sequential to make it easier to detect instructions that require a D suffix when the operand size is 32 bits.\n */\n DebuggerX86.INS = {\n NONE: 0, AAA: 1, AAD: 2, AAM: 3, AAS: 4, ADC: 5, ADD: 6, AND: 7,\n ARPL: 8, AS: 9, BOUND: 10, BSF: 11, BSR: 12, BT: 13, BTC: 14, BTR: 15,\n BTS: 16, CALL: 17, CBW: 18, CLC: 19, CLD: 20, CLI: 21, CLTS: 22, CMC: 23,\n CMP: 24, CMPSB: 25, CMPSW: 26, CS: 27, CWD: 28, DAA: 29, DAS: 30, DEC: 31,\n DIV: 32, DS: 33, ENTER: 34, ES: 35, ESC: 36, FS: 37, GS: 38, HLT: 39,\n IBTS: 40, IDIV: 41, IMUL: 42, IN: 43, INC: 44, INS: 45, INT: 46, INT3: 47,\n INTO: 48, IRET: 49, JBE: 50, JC: 51, JCXZ: 52, JG: 53, JGE: 54, JL: 55,\n JLE: 56, JMP: 57, JA: 58, JNC: 59, JNO: 60, JNP: 61, JNS: 62, JNZ: 63,\n JO: 64, JP: 65, JS: 66, JZ: 67, LAHF: 68, LAR: 69, LDS: 70, LEA: 71,\n LEAVE: 72, LES: 73, LFS: 74, LGDT: 75, LGS: 76, LIDT: 77, LLDT: 78, LMSW: 79,\n LOADALL:80, LOCK: 81, LODSB: 82, LODSW: 83, LOOP: 84, LOOPNZ: 85, LOOPZ: 86, LSL: 87,\n LSS: 88, LTR: 89, MOV: 90, MOVSB: 91, MOVSW: 92, MOVSX: 93, MOVZX: 94, MUL: 95,\n NEG: 96, NOP: 97, NOT: 98, OR: 99, OS: 100, OUT: 101, OUTS: 102, POP: 103,\n POPA: 104, POPF: 105, PUSHF: 106, PUSHA: 107, PUSH: 108, RCL: 109, RCR: 110, REPNZ: 111,\n REPZ: 112, RET: 113, RETF: 114, ROL: 115, ROR: 116, SAHF: 117, SALC: 118, SAR: 119,\n SBB: 120, SCASB: 121, SCASW: 122, SETBE: 123, SETC: 124, SETG: 125, SETGE: 126, SETL: 127,\n SETLE: 128, SETNBE: 129, SETNC: 130, SETNO: 131, SETNP: 132, SETNS: 133, SETNZ: 134, SETO: 135,\n SETP: 136, SETS: 137, SETZ: 138, SGDT: 139, SHL: 140, SHLD: 141, SHR: 142, SHRD: 143,\n SIDT: 144, SLDT: 145, SMSW: 146, SS: 147, STC: 148, STD: 149, STI: 150, STOSB: 151,\n STOSW: 152, STR: 153, SUB: 154, TEST: 155, VERR: 156, VERW: 157, WAIT: 158, XBTS: 159,\n XCHG: 160, XLAT: 161, XOR: 162, GRP1B: 163, GRP1W: 164, GRP1SW: 165, GRP2B: 166, GRP2W: 167,\n GRP2B1: 168, GRP2W1: 169, GRP2BC: 170, GRP2WC: 171, GRP3B: 172, GRP3W: 173, GRP4B: 174, GRP4W: 175,\n OP0F: 176, GRP6: 177, GRP7: 178, GRP8: 179\n };\n\n /*\n * CPU instruction names (mnemonics), indexed by CPU instruction ordinal (above)\n */\n DebuggerX86.INS_NAMES = [\n \"INVALID\",\"AAA\", \"AAD\", \"AAM\", \"AAS\", \"ADC\", \"ADD\", \"AND\",\n \"ARPL\", \"AS:\", \"BOUND\", \"BSF\", \"BSR\", \"BT\", \"BTC\", \"BTR\",\n \"BTS\", \"CALL\", \"CBW\", \"CLC\", \"CLD\", \"CLI\", \"CLTS\", \"CMC\",\n \"CMP\", \"CMPSB\", \"CMPSW\", \"CS:\", \"CWD\", \"DAA\", \"DAS\", \"DEC\",\n \"DIV\", \"DS:\", \"ENTER\", \"ES:\", \"ESC\", \"FS:\", \"GS:\", \"HLT\",\n \"IBTS\", \"IDIV\", \"IMUL\", \"IN\", \"INC\", \"INS\", \"INT\", \"INT3\",\n \"INTO\", \"IRET\", \"JBE\", \"JC\", \"JCXZ\", \"JG\", \"JGE\", \"JL\",\n \"JLE\", \"JMP\", \"JA\", \"JNC\", \"JNO\", \"JNP\", \"JNS\", \"JNZ\",\n \"JO\", \"JP\", \"JS\", \"JZ\", \"LAHF\", \"LAR\", \"LDS\", \"LEA\",\n \"LEAVE\", \"LES\", \"LFS\", \"LGDT\", \"LGS\", \"LIDT\", \"LLDT\", \"LMSW\",\n \"LOADALL\",\"LOCK\", \"LODSB\", \"LODSW\", \"LOOP\", \"LOOPNZ\", \"LOOPZ\", \"LSL\",\n \"LSS\", \"LTR\", \"MOV\", \"MOVSB\", \"MOVSW\", \"MOVSX\", \"MOVZX\", \"MUL\",\n \"NEG\", \"NOP\", \"NOT\", \"OR\", \"OS:\", \"OUT\", \"OUTS\", \"POP\",\n \"POPA\", \"POPF\", \"PUSHF\", \"PUSHA\", \"PUSH\", \"RCL\", \"RCR\", \"REPNZ\",\n \"REPZ\", \"RET\", \"RETF\", \"ROL\", \"ROR\", \"SAHF\", \"SALC\", \"SAR\",\n \"SBB\", \"SCASB\", \"SCASW\", \"SETBE\", \"SETC\", \"SETG\", \"SETGE\", \"SETL\",\n \"SETLE\", \"SETNBE\", \"SETNC\", \"SETNO\", \"SETNP\", \"SETNS\", \"SETNZ\", \"SETO\",\n \"SETP\", \"SETS\", \"SETZ\", \"SGDT\", \"SHL\", \"SHLD\", \"SHR\", \"SHRD\",\n \"SIDT\", \"SLDT\", \"SMSW\", \"SS:\", \"STC\", \"STD\", \"STI\", \"STOSB\",\n \"STOSW\", \"STR\", \"SUB\", \"TEST\", \"VERR\", \"VERW\", \"WAIT\", \"XBTS\",\n \"XCHG\", \"XLAT\", \"XOR\"\n ];\n\n /*\n * FPU instruction ordinals\n *\n * Unlike CPU instruction ordinals, these are not organized alphabetically (which I did only for the\n * sake of tidiness), but rather by functionality; ie:\n *\n * 0-3: real transfers\n * 4-6: integer transfers\n * 7-8: packed decimal transfers\n * 9-11: addition\n * 12-17: subtraction\n * 18-20: multiplication\n * 21-26: division\n * 27-33: other\n * 34-40: comparisons\n * 41-45: transcendental\n * 46-52: constants\n * 53-77: coprocessor control\n * 78---: new for 80287 or higher\n *\n * Also, unlike the CPU instructions, there is no NONE (\"INVALID\") instruction; if an ESC instruction\n * can't be decoded as a valid FPU instruction, then it should remain an ESC instruction.\n */\n DebuggerX86.FINS = {\n FLD: 0, FST: 1, FSTP: 2, FXCH: 3, FILD: 4, FIST: 5, FISTP: 6, FBLD: 7,\n FBSTP: 8, FADD: 9, FADDP: 10, FIADD: 11, FSUB: 12, FSUBP: 13, FISUB: 14, FSUBR: 15,\n FSUBRP: 16, FISUBR: 17, FMUL: 18, FMULP: 19, FIMUL: 20, FDIV: 21, FDIVP: 22, FIDIV: 23,\n FDIVR: 24, FDIVRP: 25, FIDIVR: 26, FSQRT: 27, FSCALE: 28, FPREM: 29, FRNDINT:30, FXTRACT:31,\n FABS: 32, FCHS: 33, FCOM: 34, FCOMP: 35, FCOMPP: 36, FICOM: 37, FICOMP: 38, FTST: 39,\n FXAM: 40, FPTAN: 41, FPATAN: 42, F2XM1: 43, FYL2X: 44, FYL2XP1:45, FLDZ: 46, FLD1: 47,\n FLDPI: 48, FLDL2T: 49, FLDL2E: 50, FLDLG2: 51, FLDLN2: 52, FINIT: 53, FNINIT: 54, FDISI: 55,\n FNDISI: 56, FENI: 57, FNENI: 58, FLDCW: 59, FSTCW: 60, FNSTCW: 61, FSTSW: 62, FNSTSW: 63,\n FCLEX: 64, FNCLEX: 65, FSTENV: 66, FNSTENV:67, FLDENV: 68, FSAVE: 69, FNSAVE: 70, FRSTOR: 71,\n FINCSTP:72, FDECSTP:73, FFREE: 74, FFREEP: 75, FNOP: 76, FWAIT: 77, FSETPM: 78, FSINCOS:79,\n FSTSWAX:80\n };\n\n /*\n * FPU instruction names (mnemonics), indexed by FPU instruction ordinal (above)\n */\n DebuggerX86.FINS_NAMES = [\n \"FLD\", \"FST\", \"FSTP\", \"FXCH\", \"FILD\", \"FIST\", \"FISTP\", \"FBLD\",\n \"FBSTP\", \"FADD\", \"FADDP\", \"FIADD\", \"FSUB\", \"FSUBP\", \"FISUB\", \"FSUBR\",\n \"FSUBRP\", \"FISUBR\", \"FMUL\", \"FMULP\", \"FIMUL\", \"FDIV\", \"FDIVP\", \"FIDIV\",\n \"FDIVR\", \"FDIVRP\", \"FIDIVR\", \"FSQRT\", \"FSCALE\", \"FPREM\", \"FRNDINT\",\"FXTRACT\",\n \"FABS\", \"FCHS\", \"FCOM\", \"FCOMP\", \"FCOMPP\", \"FICOM\", \"FICOMP\", \"FTST\",\n \"FXAM\", \"FPTAN\", \"FPATAN\", \"F2XM1\", \"FYL2X\", \"FYL2XP1\",\"FLDZ\", \"FLD1\",\n \"FLDPI\", \"FLDL2T\", \"FLDL2E\", \"FLDLG2\", \"FLDLN2\", \"FINIT\", \"FNINIT\", \"FDISI\",\n \"FNDISI\", \"FENI\", \"FNENI\", \"FLDCW\", \"FSTCW\", \"FNSTCW\", \"FSTSW\", \"FNSTSW\",\n \"FCLEX\", \"FNCLEX\", \"FSTENV\", \"FNSTENV\",\"FLDENV\", \"FSAVE\", \"FNSAVE\", \"FRSTOR\",\n \"FINCSTP\",\"FDECSTP\",\"FFREE\", \"FFREEP\", \"FNOP\", \"FWAIT\", \"FSETPM\", \"FSINCOS\",\n \"FSTSWAX\"\n ];\n\n DebuggerX86.FPU_TAGS = [\"VALID\", \"ZERO \", \"SPEC \", \"EMPTY\"];\n\n DebuggerX86.CPU_8086 = 0;\n DebuggerX86.CPU_80186 = 1;\n DebuggerX86.CPU_80286 = 2;\n DebuggerX86.CPU_80386 = 3;\n DebuggerX86.CPUS = [8086, 80186, 80286, 80386];\n\n /*\n * ModRM masks and definitions\n */\n DebuggerX86.REG_AL = 0x00; // bits 0-2 are standard Reg encodings\n DebuggerX86.REG_CL = 0x01;\n DebuggerX86.REG_DL = 0x02;\n DebuggerX86.REG_BL = 0x03;\n DebuggerX86.REG_AH = 0x04;\n DebuggerX86.REG_CH = 0x05;\n DebuggerX86.REG_DH = 0x06;\n DebuggerX86.REG_BH = 0x07;\n DebuggerX86.REG_AX = 0x08;\n DebuggerX86.REG_CX = 0x09;\n DebuggerX86.REG_DX = 0x0A;\n DebuggerX86.REG_BX = 0x0B;\n DebuggerX86.REG_SP = 0x0C;\n DebuggerX86.REG_BP = 0x0D;\n DebuggerX86.REG_SI = 0x0E;\n DebuggerX86.REG_DI = 0x0F;\n DebuggerX86.REG_SEG = 0x10;\n DebuggerX86.REG_IP = 0x16;\n DebuggerX86.REG_PS = 0x17;\n DebuggerX86.REG_EAX = 0x18;\n DebuggerX86.REG_ECX = 0x19;\n DebuggerX86.REG_EDX = 0x1A;\n DebuggerX86.REG_EBX = 0x1B;\n DebuggerX86.REG_ESP = 0x1C;\n DebuggerX86.REG_EBP = 0x1D;\n DebuggerX86.REG_ESI = 0x1E;\n DebuggerX86.REG_EDI = 0x1F;\n DebuggerX86.REG_CR0 = 0x20;\n DebuggerX86.REG_CR1 = 0x21;\n DebuggerX86.REG_CR2 = 0x22;\n DebuggerX86.REG_CR3 = 0x23;\n DebuggerX86.REG_DR0 = 0x28;\n DebuggerX86.REG_DR1 = 0x29;\n DebuggerX86.REG_DR2 = 0x2A;\n DebuggerX86.REG_DR3 = 0x2B;\n DebuggerX86.REG_DR6 = 0x2E;\n DebuggerX86.REG_DR7 = 0x2F;\n DebuggerX86.REG_TR0 = 0x30;\n DebuggerX86.REG_TR6 = 0x36;\n DebuggerX86.REG_TR7 = 0x37;\n DebuggerX86.REG_EIP = 0x38;\n\n DebuggerX86.REGS = [\n \"AL\", \"CL\", \"DL\", \"BL\", \"AH\", \"CH\", \"DH\", \"BH\",\n \"AX\", \"CX\", \"DX\", \"BX\", \"SP\", \"BP\", \"SI\", \"DI\",\n \"ES\", \"CS\", \"SS\", \"DS\", \"FS\", \"GS\", \"IP\", \"PS\",\n \"EAX\", \"ECX\", \"EDX\", \"EBX\", \"ESP\", \"EBP\", \"ESI\", \"EDI\",\n \"CR0\", \"CR1\", \"CR2\", \"CR3\", null, null, null, null, // register names used with TYPE_CTLREG\n \"DR0\", \"DR1\", \"DR2\", \"DR3\", null, null, \"DR6\", \"DR7\", // register names used with TYPE_DBGREG\n null, null, null, null, null, null, \"TR6\", \"TR7\", // register names used with TYPE_TSTREG\n \"EIP\"\n ];\n\n DebuggerX86.REG_ES = 0x00; // bits 0-1 are standard SegReg encodings\n DebuggerX86.REG_CS = 0x01;\n DebuggerX86.REG_SS = 0x02;\n DebuggerX86.REG_DS = 0x03;\n DebuggerX86.REG_FS = 0x04;\n DebuggerX86.REG_GS = 0x05;\n DebuggerX86.REG_UNKNOWN = 0x00;\n\n DebuggerX86.MOD_NODISP = 0x00; // use RM below, no displacement\n DebuggerX86.MOD_DISP8 = 0x01; // use RM below + 8-bit displacement\n DebuggerX86.MOD_DISP16 = 0x02; // use RM below + 16-bit displacement\n DebuggerX86.MOD_REGISTER = 0x03; // use REG above\n\n DebuggerX86.RM_BXSI = 0x00;\n DebuggerX86.RM_BXDI = 0x01;\n DebuggerX86.RM_BPSI = 0x02;\n DebuggerX86.RM_BPDI = 0x03;\n DebuggerX86.RM_SI = 0x04;\n DebuggerX86.RM_DI = 0x05;\n DebuggerX86.RM_BP = 0x06;\n DebuggerX86.RM_IMMOFF = DebuggerX86.RM_BP; // only if MOD_NODISP\n DebuggerX86.RM_BX = 0x07;\n\n DebuggerX86.RMS = [\n \"BX+SI\", \"BX+DI\", \"BP+SI\", \"BP+DI\", \"SI\", \"DI\", \"BP\", \"BX\",\n \"EAX\", \"ECX\", \"EDX\", \"EBX\", \"ESP\", \"EBP\", \"ESI\", \"EDI\"\n ];\n\n /*\n * Operand type descriptor masks and definitions\n *\n * Note that the letters in () in the comments refer to Intel's\n * nomenclature used in Appendix A of the 80386 Programmers Reference Manual.\n */\n DebuggerX86.TYPE_SIZE = 0x000F; // size field\n DebuggerX86.TYPE_MODE = 0x00F0; // mode field\n DebuggerX86.TYPE_IREG = 0x0F00; // implied register field\n DebuggerX86.TYPE_OTHER = 0xF000; // \"other\" field\n\n /*\n * TYPE_SIZE values. Some definitions use duplicate values when the operands are the\n * same size and the Debugger doesn't need to make a distinction.\n */\n DebuggerX86.TYPE_NONE = 0x0000; // (all other TYPE fields ignored)\n DebuggerX86.TYPE_BYTE = 0x0001; // (b) byte, regardless of operand size\n DebuggerX86.TYPE_SBYTE = 0x0002; // byte sign-extended to word\n DebuggerX86.TYPE_SHORT = 0x0003; // (w) 16-bit value\n DebuggerX86.TYPE_WORD = 0x0004; // (v) 16-bit or 32-bit value\n DebuggerX86.TYPE_LONG = 0x0005; // (d) 32-bit value\n DebuggerX86.TYPE_SEGP = 0x0006; // (p) 32-bit or 48-bit pointer\n DebuggerX86.TYPE_FARP = 0x0007; // (p) 32-bit or 48-bit pointer for JMP/CALL\n DebuggerX86.TYPE_PREFIX = 0x0008; // (treat similarly to TYPE_NONE)\n /*\n * The remaining TYPE_SIZE values are for the FPU. Note that there are not enough values\n * within this nibble for every type to have a unique value, so to differentiate between two\n * types of the same size (eg, SINT and SREAL), we can inspect the opcode string, because only\n * FI* instructions use INT operands. Also, some FPU sizes are not in this list (eg, the\n * so-called \"word-integer\"); since a word-integer is always 16 bits, we specify TYPE_SHORT,\n * which the Debugger should display as \"INT16\" for FI* instructions.\n */\n DebuggerX86.TYPE_ST = 0x0009; // FPU ST (implicit stack top)\n DebuggerX86.TYPE_STREG = 0x000A; // FPU ST (explicit stack register, relative to top)\n DebuggerX86.TYPE_SINT = 0x000B; // FPU SI (short-integer; 32-bit); displayed as \"INT32\"\n DebuggerX86.TYPE_SREAL = 0x000B; // FPU SR (short-real; 32-bit); displayed as \"REAL32\"\n DebuggerX86.TYPE_LINT = 0x000C; // FPU LI (long-integer; 64-bit); displayed as \"INT64\"\n DebuggerX86.TYPE_LREAL = 0x000C; // FPU LR (long-real; 64-bit); displayed as \"REAL64\"\n DebuggerX86.TYPE_TREAL = 0x000D; // FPU TR (temp-real; 80-bit); displayed as \"REAL80\"\n DebuggerX86.TYPE_BCD80 = 0x000E; // FPU PD (packed-decimal; 18 BCD digits in 80 bits, bits 72-78 unused, sign in bit 79); displayed as \"BCD80\"\n DebuggerX86.TYPE_ENV = 0x000F; // FPU ENV (environment; 14 bytes in real-mode, 28 bytes in protected-mode)\n DebuggerX86.TYPE_FPU = 0x000F; // FPU SAVE (save/restore; 94 bytes in real-mode, 108 bytes in protected-mode)\n\n /*\n * TYPE_MODE values. Order is somewhat important, as all values implying\n * the presence of a ModRM byte are assumed to be >= TYPE_MODRM.\n */\n DebuggerX86.TYPE_IMM = 0x0000; // (I) immediate data\n DebuggerX86.TYPE_ONE = 0x0010; // implicit 1 (eg, shifts/rotates)\n DebuggerX86.TYPE_IMMOFF = 0x0020; // (A) immediate offset\n DebuggerX86.TYPE_IMMREL = 0x0030; // (J) immediate relative\n DebuggerX86.TYPE_DSSI = 0x0040; // (X) memory addressed by DS:SI\n DebuggerX86.TYPE_ESDI = 0x0050; // (Y) memory addressed by ES:DI\n DebuggerX86.TYPE_IMPREG = 0x0060; // implicit register in TYPE_IREG\n DebuggerX86.TYPE_IMPSEG = 0x0070; // implicit segment reg in TYPE_IREG\n DebuggerX86.TYPE_MODRM = 0x0080; // (E) standard ModRM decoding\n DebuggerX86.TYPE_MODMEM = 0x0090; // (M) ModRM refers to memory only\n DebuggerX86.TYPE_MODREG = 0x00A0; // (R) ModRM refers to register only\n DebuggerX86.TYPE_REG = 0x00B0; // (G) standard Reg decoding\n DebuggerX86.TYPE_SEGREG = 0x00C0; // (S) Reg selects segment register\n DebuggerX86.TYPE_CTLREG = 0x00D0; // (C) Reg selects control register\n DebuggerX86.TYPE_DBGREG = 0x00E0; // (D) Reg selects debug register\n DebuggerX86.TYPE_TSTREG = 0x00F0; // (T) Reg selects test register\n\n /*\n * TYPE_IREG values, based on the REG_* constants.\n * For convenience, they include TYPE_IMPREG or TYPE_IMPSEG as appropriate.\n */\n DebuggerX86.TYPE_AL = (DebuggerX86.REG_AL << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_BYTE);\n DebuggerX86.TYPE_CL = (DebuggerX86.REG_CL << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_BYTE);\n DebuggerX86.TYPE_DL = (DebuggerX86.REG_DL << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_BYTE);\n DebuggerX86.TYPE_BL = (DebuggerX86.REG_BL << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_BYTE);\n DebuggerX86.TYPE_AH = (DebuggerX86.REG_AH << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_BYTE);\n DebuggerX86.TYPE_CH = (DebuggerX86.REG_CH << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_BYTE);\n DebuggerX86.TYPE_DH = (DebuggerX86.REG_DH << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_BYTE);\n DebuggerX86.TYPE_BH = (DebuggerX86.REG_BH << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_BYTE);\n DebuggerX86.TYPE_AX = (DebuggerX86.REG_AX << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_WORD);\n DebuggerX86.TYPE_CX = (DebuggerX86.REG_CX << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_WORD);\n DebuggerX86.TYPE_DX = (DebuggerX86.REG_DX << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_WORD);\n DebuggerX86.TYPE_BX = (DebuggerX86.REG_BX << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_WORD);\n DebuggerX86.TYPE_SP = (DebuggerX86.REG_SP << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_WORD);\n DebuggerX86.TYPE_BP = (DebuggerX86.REG_BP << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_WORD);\n DebuggerX86.TYPE_SI = (DebuggerX86.REG_SI << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_WORD);\n DebuggerX86.TYPE_DI = (DebuggerX86.REG_DI << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_WORD);\n DebuggerX86.TYPE_ES = (DebuggerX86.REG_ES << 8 | DebuggerX86.TYPE_IMPSEG | DebuggerX86.TYPE_SHORT);\n DebuggerX86.TYPE_CS = (DebuggerX86.REG_CS << 8 | DebuggerX86.TYPE_IMPSEG | DebuggerX86.TYPE_SHORT);\n DebuggerX86.TYPE_SS = (DebuggerX86.REG_SS << 8 | DebuggerX86.TYPE_IMPSEG | DebuggerX86.TYPE_SHORT);\n DebuggerX86.TYPE_DS = (DebuggerX86.REG_DS << 8 | DebuggerX86.TYPE_IMPSEG | DebuggerX86.TYPE_SHORT);\n DebuggerX86.TYPE_FS = (DebuggerX86.REG_FS << 8 | DebuggerX86.TYPE_IMPSEG | DebuggerX86.TYPE_SHORT);\n DebuggerX86.TYPE_GS = (DebuggerX86.REG_GS << 8 | DebuggerX86.TYPE_IMPSEG | DebuggerX86.TYPE_SHORT);\n\n /*\n * TYPE_OTHER bit definitions\n */\n DebuggerX86.TYPE_IN = 0x1000; // operand is input\n DebuggerX86.TYPE_OUT = 0x2000; // operand is output\n DebuggerX86.TYPE_BOTH = (DebuggerX86.TYPE_IN | DebuggerX86.TYPE_OUT);\n DebuggerX86.TYPE_8086 = (DebuggerX86.CPU_8086 << 14);\n DebuggerX86.TYPE_8087 = DebuggerX86.TYPE_8086;\n DebuggerX86.TYPE_80186 = (DebuggerX86.CPU_80186 << 14);\n DebuggerX86.TYPE_80286 = (DebuggerX86.CPU_80286 << 14);\n DebuggerX86.TYPE_80287 = DebuggerX86.TYPE_80286;\n DebuggerX86.TYPE_80386 = (DebuggerX86.CPU_80386 << 14);\n DebuggerX86.TYPE_80387 = DebuggerX86.TYPE_80386;\n DebuggerX86.TYPE_CPU_SHIFT = 14;\n\n DebuggerX86.HISTORY_LIMIT = DEBUG? 100000 : 1000;\n\n /*\n * Opcode 0x0F has a distinguished history:\n *\n * On the 8086, it functioned as POP CS\n * On the 80186, it generated an Invalid Opcode (UD_FAULT) exception\n * On the 80286, it introduced a new (and growing) series of two-byte opcodes\n *\n * Based on the active CPU model, we make every effort to execute and disassemble this (and every other)\n * opcode appropriately, by setting the opcode's entry in aaOpDescs accordingly. 0x0F in aaOpDescs points\n * to the 8086 table: aOpDescPopCS.\n *\n * Note that we must NOT modify aaOpDescs directly. this.aaOpDescs will point to DebuggerX86.aaOpDescs\n * if the processor is an 8086, because that's the processor that the hard-coded contents of the table\n * represent; for all other processors, this.aaOpDescs will contain a copy of the table that we can modify.\n */\n DebuggerX86.aOpDescPopCS = [DebuggerX86.INS.POP, DebuggerX86.TYPE_CS | DebuggerX86.TYPE_OUT];\n DebuggerX86.aOpDescUndefined = [DebuggerX86.INS.NONE, DebuggerX86.TYPE_NONE];\n DebuggerX86.aOpDesc0F = [DebuggerX86.INS.OP0F, DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_BOTH];\n\n /*\n * The aaOpDescs array is indexed by opcode, and each element is a sub-array (aOpDesc) that describes\n * the corresponding opcode. The sub-elements are as follows:\n *\n * [0]: {number} of the opcode name (see INS.*)\n * [1]: {number} containing the destination operand descriptor bit(s), if any\n * [2]: {number} containing the source operand descriptor bit(s), if any\n * [3]: {number} containing the occasional third operand descriptor bit(s), if any\n *\n * These sub-elements are all optional. If [0] is not present, the opcode is undefined; if [1] is not\n * present (or contains zero), the opcode has no (or only implied) operands; if [2] is not present, the\n * opcode has only a single operand. And so on.\n */\n DebuggerX86.aaOpDescs = [\n /* 0x00 */ [DebuggerX86.INS.ADD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x01 */ [DebuggerX86.INS.ADD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x02 */ [DebuggerX86.INS.ADD, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x03 */ [DebuggerX86.INS.ADD, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x04 */ [DebuggerX86.INS.ADD, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x05 */ [DebuggerX86.INS.ADD, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x06 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_ES | DebuggerX86.TYPE_IN],\n /* 0x07 */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_ES | DebuggerX86.TYPE_OUT],\n\n /* 0x08 */ [DebuggerX86.INS.OR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x09 */ [DebuggerX86.INS.OR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x0A */ [DebuggerX86.INS.OR, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x0B */ [DebuggerX86.INS.OR, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x0C */ [DebuggerX86.INS.OR, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x0D */ [DebuggerX86.INS.OR, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x0E */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_CS | DebuggerX86.TYPE_IN],\n /* 0x0F */ DebuggerX86.aOpDescPopCS,\n\n /* 0x10 */ [DebuggerX86.INS.ADC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x11 */ [DebuggerX86.INS.ADC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x12 */ [DebuggerX86.INS.ADC, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x13 */ [DebuggerX86.INS.ADC, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x14 */ [DebuggerX86.INS.ADC, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x15 */ [DebuggerX86.INS.ADC, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x16 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_SS | DebuggerX86.TYPE_IN],\n /* 0x17 */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_SS | DebuggerX86.TYPE_OUT],\n\n /* 0x18 */ [DebuggerX86.INS.SBB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x19 */ [DebuggerX86.INS.SBB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x1A */ [DebuggerX86.INS.SBB, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x1B */ [DebuggerX86.INS.SBB, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x1C */ [DebuggerX86.INS.SBB, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x1D */ [DebuggerX86.INS.SBB, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x1E */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_DS | DebuggerX86.TYPE_IN],\n /* 0x1F */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_DS | DebuggerX86.TYPE_OUT],\n\n /* 0x20 */ [DebuggerX86.INS.AND, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x21 */ [DebuggerX86.INS.AND, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x22 */ [DebuggerX86.INS.AND, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x23 */ [DebuggerX86.INS.AND, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x24 */ [DebuggerX86.INS.AND, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x25 */ [DebuggerX86.INS.AND, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x26 */ [DebuggerX86.INS.ES, DebuggerX86.TYPE_PREFIX],\n /* 0x27 */ [DebuggerX86.INS.DAA],\n\n /* 0x28 */ [DebuggerX86.INS.SUB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x29 */ [DebuggerX86.INS.SUB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x2A */ [DebuggerX86.INS.SUB, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x2B */ [DebuggerX86.INS.SUB, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x2C */ [DebuggerX86.INS.SUB, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x2D */ [DebuggerX86.INS.SUB, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x2E */ [DebuggerX86.INS.CS, DebuggerX86.TYPE_PREFIX],\n /* 0x2F */ [DebuggerX86.INS.DAS],\n\n /* 0x30 */ [DebuggerX86.INS.XOR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x31 */ [DebuggerX86.INS.XOR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x32 */ [DebuggerX86.INS.XOR, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x33 */ [DebuggerX86.INS.XOR, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x34 */ [DebuggerX86.INS.XOR, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x35 */ [DebuggerX86.INS.XOR, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x36 */ [DebuggerX86.INS.SS, DebuggerX86.TYPE_PREFIX],\n /* 0x37 */ [DebuggerX86.INS.AAA],\n\n /* 0x38 */ [DebuggerX86.INS.CMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x39 */ [DebuggerX86.INS.CMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x3A */ [DebuggerX86.INS.CMP, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x3B */ [DebuggerX86.INS.CMP, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x3C */ [DebuggerX86.INS.CMP, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x3D */ [DebuggerX86.INS.CMP, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x3E */ [DebuggerX86.INS.DS, DebuggerX86.TYPE_PREFIX],\n /* 0x3F */ [DebuggerX86.INS.AAS],\n\n /* 0x40 */ [DebuggerX86.INS.INC, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH],\n /* 0x41 */ [DebuggerX86.INS.INC, DebuggerX86.TYPE_CX | DebuggerX86.TYPE_BOTH],\n /* 0x42 */ [DebuggerX86.INS.INC, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_BOTH],\n /* 0x43 */ [DebuggerX86.INS.INC, DebuggerX86.TYPE_BX | DebuggerX86.TYPE_BOTH],\n /* 0x44 */ [DebuggerX86.INS.INC, DebuggerX86.TYPE_SP | DebuggerX86.TYPE_BOTH],\n /* 0x45 */ [DebuggerX86.INS.INC, DebuggerX86.TYPE_BP | DebuggerX86.TYPE_BOTH],\n /* 0x46 */ [DebuggerX86.INS.INC, DebuggerX86.TYPE_SI | DebuggerX86.TYPE_BOTH],\n /* 0x47 */ [DebuggerX86.INS.INC, DebuggerX86.TYPE_DI | DebuggerX86.TYPE_BOTH],\n\n /* 0x48 */ [DebuggerX86.INS.DEC, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH],\n /* 0x49 */ [DebuggerX86.INS.DEC, DebuggerX86.TYPE_CX | DebuggerX86.TYPE_BOTH],\n /* 0x4A */ [DebuggerX86.INS.DEC, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_BOTH],\n /* 0x4B */ [DebuggerX86.INS.DEC, DebuggerX86.TYPE_BX | DebuggerX86.TYPE_BOTH],\n /* 0x4C */ [DebuggerX86.INS.DEC, DebuggerX86.TYPE_SP | DebuggerX86.TYPE_BOTH],\n /* 0x4D */ [DebuggerX86.INS.DEC, DebuggerX86.TYPE_BP | DebuggerX86.TYPE_BOTH],\n /* 0x4E */ [DebuggerX86.INS.DEC, DebuggerX86.TYPE_SI | DebuggerX86.TYPE_BOTH],\n /* 0x4F */ [DebuggerX86.INS.DEC, DebuggerX86.TYPE_DI | DebuggerX86.TYPE_BOTH],\n\n /* 0x50 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_IN],\n /* 0x51 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_CX | DebuggerX86.TYPE_IN],\n /* 0x52 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_IN],\n /* 0x53 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_BX | DebuggerX86.TYPE_IN],\n /* 0x54 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_SP | DebuggerX86.TYPE_IN],\n /* 0x55 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_BP | DebuggerX86.TYPE_IN],\n /* 0x56 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_SI | DebuggerX86.TYPE_IN],\n /* 0x57 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_DI | DebuggerX86.TYPE_IN],\n\n /* 0x58 */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_OUT],\n /* 0x59 */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_CX | DebuggerX86.TYPE_OUT],\n /* 0x5A */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_OUT],\n /* 0x5B */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_BX | DebuggerX86.TYPE_OUT],\n /* 0x5C */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_SP | DebuggerX86.TYPE_OUT],\n /* 0x5D */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_BP | DebuggerX86.TYPE_OUT],\n /* 0x5E */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_SI | DebuggerX86.TYPE_OUT],\n /* 0x5F */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_DI | DebuggerX86.TYPE_OUT],\n\n /* 0x60 */ [DebuggerX86.INS.PUSHA, DebuggerX86.TYPE_NONE | DebuggerX86.TYPE_80286],\n /* 0x61 */ [DebuggerX86.INS.POPA, DebuggerX86.TYPE_NONE | DebuggerX86.TYPE_80286],\n /* 0x62 */ [DebuggerX86.INS.BOUND, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x63 */ [DebuggerX86.INS.ARPL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n /* 0x64 */ [DebuggerX86.INS.FS, DebuggerX86.TYPE_PREFIX | DebuggerX86.TYPE_80386],\n /* 0x65 */ [DebuggerX86.INS.GS, DebuggerX86.TYPE_PREFIX | DebuggerX86.TYPE_80386],\n /* 0x66 */ [DebuggerX86.INS.OS, DebuggerX86.TYPE_PREFIX | DebuggerX86.TYPE_80386],\n /* 0x67 */ [DebuggerX86.INS.AS, DebuggerX86.TYPE_PREFIX | DebuggerX86.TYPE_80386],\n\n /* 0x68 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286],\n /* 0x69 */ [DebuggerX86.INS.IMUL, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x6A */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SBYTE | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286],\n /* 0x6B */ [DebuggerX86.INS.IMUL, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x6C */ [DebuggerX86.INS.INS, DebuggerX86.TYPE_ESDI | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_IN],\n /* 0x6D */ [DebuggerX86.INS.INS, DebuggerX86.TYPE_ESDI | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_IN],\n /* 0x6E */ [DebuggerX86.INS.OUTS, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_DSSI | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x6F */ [DebuggerX86.INS.OUTS, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_DSSI | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n\n /* 0x70 */ [DebuggerX86.INS.JO, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x71 */ [DebuggerX86.INS.JNO, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x72 */ [DebuggerX86.INS.JC, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x73 */ [DebuggerX86.INS.JNC, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x74 */ [DebuggerX86.INS.JZ, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x75 */ [DebuggerX86.INS.JNZ, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x76 */ [DebuggerX86.INS.JBE, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x77 */ [DebuggerX86.INS.JA, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n\n /* 0x78 */ [DebuggerX86.INS.JS, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x79 */ [DebuggerX86.INS.JNS, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x7A */ [DebuggerX86.INS.JP, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x7B */ [DebuggerX86.INS.JNP, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x7C */ [DebuggerX86.INS.JL, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x7D */ [DebuggerX86.INS.JGE, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x7E */ [DebuggerX86.INS.JLE, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x7F */ [DebuggerX86.INS.JG, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n\n /* 0x80 */ [DebuggerX86.INS.GRP1B, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x81 */ [DebuggerX86.INS.GRP1W, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x82 */ [DebuggerX86.INS.GRP1B, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x83 */ [DebuggerX86.INS.GRP1SW,DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x84 */ [DebuggerX86.INS.TEST, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x85 */ [DebuggerX86.INS.TEST, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x86 */ [DebuggerX86.INS.XCHG, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH],\n /* 0x87 */ [DebuggerX86.INS.XCHG, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH],\n\n /* 0x88 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x89 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x8A */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x8B */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x8C */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_SEGREG | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n /* 0x8D */ [DebuggerX86.INS.LEA, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_MODMEM | DebuggerX86.TYPE_WORD ],\n /* 0x8E */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_SEGREG | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x8F */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT],\n\n /* 0x90 */ [DebuggerX86.INS.NOP],\n /* 0x91 */ [DebuggerX86.INS.XCHG, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CX | DebuggerX86.TYPE_BOTH],\n /* 0x92 */ [DebuggerX86.INS.XCHG, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_BOTH],\n /* 0x93 */ [DebuggerX86.INS.XCHG, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_BX | DebuggerX86.TYPE_BOTH],\n /* 0x94 */ [DebuggerX86.INS.XCHG, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_SP | DebuggerX86.TYPE_BOTH],\n /* 0x95 */ [DebuggerX86.INS.XCHG, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_BP | DebuggerX86.TYPE_BOTH],\n /* 0x96 */ [DebuggerX86.INS.XCHG, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_SI | DebuggerX86.TYPE_BOTH],\n /* 0x97 */ [DebuggerX86.INS.XCHG, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_DI | DebuggerX86.TYPE_BOTH],\n\n /* 0x98 */ [DebuggerX86.INS.CBW],\n /* 0x99 */ [DebuggerX86.INS.CWD],\n /* 0x9A */ [DebuggerX86.INS.CALL, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_FARP | DebuggerX86.TYPE_IN],\n /* 0x9B */ [DebuggerX86.INS.WAIT],\n /* 0x9C */ [DebuggerX86.INS.PUSHF],\n /* 0x9D */ [DebuggerX86.INS.POPF],\n /* 0x9E */ [DebuggerX86.INS.SAHF],\n /* 0x9F */ [DebuggerX86.INS.LAHF],\n\n /* 0xA0 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMMOFF | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xA1 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMMOFF | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xA2 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_IMMOFF | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_IN],\n /* 0xA3 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_IMMOFF | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_IN],\n /* 0xA4 */ [DebuggerX86.INS.MOVSB, DebuggerX86.TYPE_ESDI | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_DSSI | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xA5 */ [DebuggerX86.INS.MOVSW, DebuggerX86.TYPE_ESDI | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_DSSI | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xA6 */ [DebuggerX86.INS.CMPSB, DebuggerX86.TYPE_ESDI | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_DSSI | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xA7 */ [DebuggerX86.INS.CMPSW, DebuggerX86.TYPE_ESDI | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_DSSI | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n\n /* 0xA8 */ [DebuggerX86.INS.TEST, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xA9 */ [DebuggerX86.INS.TEST, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xAA */ [DebuggerX86.INS.STOSB, DebuggerX86.TYPE_ESDI | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_IN],\n /* 0xAB */ [DebuggerX86.INS.STOSW, DebuggerX86.TYPE_ESDI | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_IN],\n /* 0xAC */ [DebuggerX86.INS.LODSB, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_DSSI | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xAD */ [DebuggerX86.INS.LODSW, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_DSSI | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xAE */ [DebuggerX86.INS.SCASB, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_ESDI | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xAF */ [DebuggerX86.INS.SCASW, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_ESDI | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n\n /* 0xB0 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xB1 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xB2 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_DL | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xB3 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_BL | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xB4 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_AH | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xB5 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_CH | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xB6 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_DH | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xB7 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_BH | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n\n /* 0xB8 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xB9 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_CX | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xBA */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xBB */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_BX | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xBC */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_SP | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xBD */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_BP | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xBE */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_SI | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xBF */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_DI | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n\n /* 0xC0 */ [DebuggerX86.INS.GRP2B, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80186, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xC1 */ [DebuggerX86.INS.GRP2W, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80186, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xC2 */ [DebuggerX86.INS.RET, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n /* 0xC3 */ [DebuggerX86.INS.RET],\n /* 0xC4 */ [DebuggerX86.INS.LES, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_MODMEM | DebuggerX86.TYPE_SEGP | DebuggerX86.TYPE_IN],\n /* 0xC5 */ [DebuggerX86.INS.LDS, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_MODMEM | DebuggerX86.TYPE_SEGP | DebuggerX86.TYPE_IN],\n /* 0xC6 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xC7 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n\n /* 0xC8 */ [DebuggerX86.INS.ENTER, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xC9 */ [DebuggerX86.INS.LEAVE, DebuggerX86.TYPE_NONE | DebuggerX86.TYPE_80286],\n /* 0xCA */ [DebuggerX86.INS.RETF, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n /* 0xCB */ [DebuggerX86.INS.RETF],\n /* 0xCC */ [DebuggerX86.INS.INT3],\n /* 0xCD */ [DebuggerX86.INS.INT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xCE */ [DebuggerX86.INS.INTO],\n /* 0xCF */ [DebuggerX86.INS.IRET],\n\n /* 0xD0 */ [DebuggerX86.INS.GRP2B1,DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xD1 */ [DebuggerX86.INS.GRP2W1,DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xD2 */ [DebuggerX86.INS.GRP2BC,DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n /* 0xD3 */ [DebuggerX86.INS.GRP2WC,DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n /* 0xD4 */ [DebuggerX86.INS.AAM, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE],\n /* 0xD5 */ [DebuggerX86.INS.AAD, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE],\n /* 0xD6 */ [DebuggerX86.INS.SALC],\n /* 0xD7 */ [DebuggerX86.INS.XLAT],\n\n /* 0xD8 */ [DebuggerX86.INS.ESC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xD9 */ [DebuggerX86.INS.ESC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xDA */ [DebuggerX86.INS.ESC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xDB */ [DebuggerX86.INS.ESC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xDC */ [DebuggerX86.INS.ESC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xDD */ [DebuggerX86.INS.ESC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xDE */ [DebuggerX86.INS.ESC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xDF */ [DebuggerX86.INS.ESC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n\n /* 0xE0 */ [DebuggerX86.INS.LOOPNZ,DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xE1 */ [DebuggerX86.INS.LOOPZ, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xE2 */ [DebuggerX86.INS.LOOP, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xE3 */ [DebuggerX86.INS.JCXZ, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xE4 */ [DebuggerX86.INS.IN, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xE5 */ [DebuggerX86.INS.IN, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xE6 */ [DebuggerX86.INS.OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_IN],\n /* 0xE7 */ [DebuggerX86.INS.OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_IN],\n\n /* 0xE8 */ [DebuggerX86.INS.CALL, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xE9 */ [DebuggerX86.INS.JMP, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xEA */ [DebuggerX86.INS.JMP, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_FARP | DebuggerX86.TYPE_IN],\n /* 0xEB */ [DebuggerX86.INS.JMP, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xEC */ [DebuggerX86.INS.IN, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n /* 0xED */ [DebuggerX86.INS.IN, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n /* 0xEE */ [DebuggerX86.INS.OUT, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_IN],\n /* 0xEF */ [DebuggerX86.INS.OUT, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_IN],\n\n /* 0xF0 */ [DebuggerX86.INS.LOCK, DebuggerX86.TYPE_PREFIX],\n /* 0xF1 */ [DebuggerX86.INS.NONE],\n /* 0xF2 */ [DebuggerX86.INS.REPNZ, DebuggerX86.TYPE_PREFIX],\n /* 0xF3 */ [DebuggerX86.INS.REPZ, DebuggerX86.TYPE_PREFIX],\n /* 0xF4 */ [DebuggerX86.INS.HLT],\n /* 0xF5 */ [DebuggerX86.INS.CMC],\n /* 0xF6 */ [DebuggerX86.INS.GRP3B, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH],\n /* 0xF7 */ [DebuggerX86.INS.GRP3W, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH],\n\n /* 0xF8 */ [DebuggerX86.INS.CLC],\n /* 0xF9 */ [DebuggerX86.INS.STC],\n /* 0xFA */ [DebuggerX86.INS.CLI],\n /* 0xFB */ [DebuggerX86.INS.STI],\n /* 0xFC */ [DebuggerX86.INS.CLD],\n /* 0xFD */ [DebuggerX86.INS.STD],\n /* 0xFE */ [DebuggerX86.INS.GRP4B, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH],\n /* 0xFF */ [DebuggerX86.INS.GRP4W, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH]\n ];\n\n DebuggerX86.aaOp0FDescs = {\n 0x00: [DebuggerX86.INS.GRP6, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_BOTH],\n 0x01: [DebuggerX86.INS.GRP7, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_BOTH],\n 0x02: [DebuggerX86.INS.LAR, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_MODMEM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_IN],\n 0x03: [DebuggerX86.INS.LSL, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_MODMEM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_IN],\n 0x05: [DebuggerX86.INS.LOADALL,DebuggerX86.TYPE_80286],\n 0x06: [DebuggerX86.INS.CLTS, DebuggerX86.TYPE_80286],\n 0x07: [DebuggerX86.INS.LOADALL,DebuggerX86.TYPE_80386], // TODO: implied operand is ES:[(E)DI]\n 0x20: [DebuggerX86.INS.MOV, DebuggerX86.TYPE_MODREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_CTLREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_IN],\n 0x21: [DebuggerX86.INS.MOV, DebuggerX86.TYPE_MODREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_DBGREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_IN],\n 0x22: [DebuggerX86.INS.MOV, DebuggerX86.TYPE_CTLREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_MODREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_IN],\n 0x23: [DebuggerX86.INS.MOV, DebuggerX86.TYPE_DBGREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_MODREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_IN],\n 0x24: [DebuggerX86.INS.MOV, DebuggerX86.TYPE_MODREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_TSTREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_IN],\n 0x26: [DebuggerX86.INS.MOV, DebuggerX86.TYPE_TSTREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_MODREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_IN],\n 0x80: [DebuggerX86.INS.JO, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x81: [DebuggerX86.INS.JNO, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x82: [DebuggerX86.INS.JC, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x83: [DebuggerX86.INS.JNC, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x84: [DebuggerX86.INS.JZ, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x85: [DebuggerX86.INS.JNZ, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x86: [DebuggerX86.INS.JBE, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x87: [DebuggerX86.INS.JA, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x88: [DebuggerX86.INS.JS, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x89: [DebuggerX86.INS.JNS, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x8A: [DebuggerX86.INS.JP, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x8B: [DebuggerX86.INS.JNP, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x8C: [DebuggerX86.INS.JL, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x8D: [DebuggerX86.INS.JGE, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x8E: [DebuggerX86.INS.JLE, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x8F: [DebuggerX86.INS.JG, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x90: [DebuggerX86.INS.SETO, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x91: [DebuggerX86.INS.SETNO, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x92: [DebuggerX86.INS.SETC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x93: [DebuggerX86.INS.SETNC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x94: [DebuggerX86.INS.SETZ, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x95: [DebuggerX86.INS.SETNZ, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x96: [DebuggerX86.INS.SETBE, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x97: [DebuggerX86.INS.SETNBE, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x98: [DebuggerX86.INS.SETS, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x99: [DebuggerX86.INS.SETNS, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x9A: [DebuggerX86.INS.SETP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x9B: [DebuggerX86.INS.SETNP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x9C: [DebuggerX86.INS.SETL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x9D: [DebuggerX86.INS.SETGE, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x9E: [DebuggerX86.INS.SETLE, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x9F: [DebuggerX86.INS.SETG, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0xA0: [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_FS | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0xA1: [DebuggerX86.INS.POP, DebuggerX86.TYPE_FS | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0xA3: [DebuggerX86.INS.BT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n 0xA4: [DebuggerX86.INS.SHLD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n 0xA5: [DebuggerX86.INS.SHLD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n 0xA6: [DebuggerX86.INS.XBTS, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n 0xA7: [DebuggerX86.INS.IBTS, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n 0xA8: [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_GS | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0xA9: [DebuggerX86.INS.POP, DebuggerX86.TYPE_GS | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0xAB: [DebuggerX86.INS.BTS, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n 0xAC: [DebuggerX86.INS.SHRD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n 0xAD: [DebuggerX86.INS.SHRD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n 0xAF: [DebuggerX86.INS.IMUL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n 0xB2: [DebuggerX86.INS.LSS, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_MODMEM | DebuggerX86.TYPE_SEGP | DebuggerX86.TYPE_IN],\n 0xB3: [DebuggerX86.INS.BTR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n 0xB4: [DebuggerX86.INS.LFS, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_MODMEM | DebuggerX86.TYPE_SEGP | DebuggerX86.TYPE_IN],\n 0xB5: [DebuggerX86.INS.LGS, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_MODMEM | DebuggerX86.TYPE_SEGP | DebuggerX86.TYPE_IN],\n 0xB6: [DebuggerX86.INS.MOVZX, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n 0xB7: [DebuggerX86.INS.MOVZX, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0xBA: [DebuggerX86.INS.GRP8, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n 0xBB: [DebuggerX86.INS.BTC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n 0xBC: [DebuggerX86.INS.BSF, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n 0xBD: [DebuggerX86.INS.BSR, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n 0xBE: [DebuggerX86.INS.MOVSX, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n 0xBF: [DebuggerX86.INS.MOVSX, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN]\n };\n\n /*\n * Be sure to keep the following table in sync with FPUX86.aaOps\n */\n DebuggerX86.aaaOpFPUDescs = {\n 0xD8: {\n 0x00: [DebuggerX86.FINS.FADD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_IN],\n 0x01: [DebuggerX86.FINS.FMUL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_IN],\n 0x02: [DebuggerX86.FINS.FCOM, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_IN],\n 0x03: [DebuggerX86.FINS.FCOMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_IN],\n 0x04: [DebuggerX86.FINS.FSUB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_IN],\n 0x05: [DebuggerX86.FINS.FSUBR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_IN],\n 0x06: [DebuggerX86.FINS.FDIV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_IN],\n 0x07: [DebuggerX86.FINS.FDIVR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_IN],\n 0x30: [DebuggerX86.FINS.FADD, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN],\n 0x31: [DebuggerX86.FINS.FMUL, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN],\n 0x32: [DebuggerX86.FINS.FCOM, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN],\n 0x33: [DebuggerX86.FINS.FCOMP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN],\n 0x34: [DebuggerX86.FINS.FSUB, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN],\n 0x35: [DebuggerX86.FINS.FSUBR, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN],\n 0x36: [DebuggerX86.FINS.FDIV, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN],\n 0x37: [DebuggerX86.FINS.FDIVR, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN]\n },\n 0xD9: {\n 0x00: [DebuggerX86.FINS.FLD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_IN],\n 0x02: [DebuggerX86.FINS.FST, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_OUT],\n 0x03: [DebuggerX86.FINS.FSTP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_OUT],\n 0x04: [DebuggerX86.FINS.FLDENV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_ENV | DebuggerX86.TYPE_IN],\n 0x05: [DebuggerX86.FINS.FLDCW, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0x06: [DebuggerX86.FINS.FSTENV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_ENV | DebuggerX86.TYPE_OUT],\n 0x07: [DebuggerX86.FINS.FSTCW, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_OUT],\n 0x30: [DebuggerX86.FINS.FLD, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT],\n 0x31: [DebuggerX86.FINS.FXCH, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT],\n 0x32: [DebuggerX86.FINS.FNOP],\n 0x33: [DebuggerX86.FINS.FSTP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT], // Obsolete encoding\n 0x40: [DebuggerX86.FINS.FCHS],\n 0x41: [DebuggerX86.FINS.FABS],\n 0x44: [DebuggerX86.FINS.FTST],\n 0x45: [DebuggerX86.FINS.FXAM],\n 0x50: [DebuggerX86.FINS.FLD1],\n 0x51: [DebuggerX86.FINS.FLDL2T],\n 0x52: [DebuggerX86.FINS.FLDL2E],\n 0x53: [DebuggerX86.FINS.FLDPI],\n 0x54: [DebuggerX86.FINS.FLDLG2],\n 0x55: [DebuggerX86.FINS.FLDLN2],\n 0x56: [DebuggerX86.FINS.FLDZ],\n 0x60: [DebuggerX86.FINS.F2XM1],\n 0x61: [DebuggerX86.FINS.FYL2X],\n 0x62: [DebuggerX86.FINS.FPTAN],\n 0x63: [DebuggerX86.FINS.FPATAN],\n 0x64: [DebuggerX86.FINS.FXTRACT],\n 0x66: [DebuggerX86.FINS.FDECSTP],\n 0x67: [DebuggerX86.FINS.FINCSTP],\n 0x70: [DebuggerX86.FINS.FPREM],\n 0x71: [DebuggerX86.FINS.FYL2XP1],\n 0x72: [DebuggerX86.FINS.FSQRT],\n 0x74: [DebuggerX86.FINS.FRNDINT],\n 0x75: [DebuggerX86.FINS.FSCALE]\n },\n 0xDA: {\n 0x00: [DebuggerX86.FINS.FIADD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_IN],\n 0x01: [DebuggerX86.FINS.FIMUL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_IN],\n 0x02: [DebuggerX86.FINS.FICOM, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_IN],\n 0x03: [DebuggerX86.FINS.FICOMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_IN],\n 0x04: [DebuggerX86.FINS.FISUB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_IN],\n 0x05: [DebuggerX86.FINS.FISUBR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_IN],\n 0x06: [DebuggerX86.FINS.FIDIV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_IN],\n 0x07: [DebuggerX86.FINS.FIDIVR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_IN]\n },\n 0xDB: {\n 0x00: [DebuggerX86.FINS.FILD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_IN],\n 0x02: [DebuggerX86.FINS.FIST, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_OUT],\n 0x03: [DebuggerX86.FINS.FISTP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_OUT],\n 0x05: [DebuggerX86.FINS.FLD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_TREAL | DebuggerX86.TYPE_IN],\n 0x07: [DebuggerX86.FINS.FSTP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_TREAL | DebuggerX86.TYPE_OUT],\n 0x40: [DebuggerX86.FINS.FENI],\n 0x41: [DebuggerX86.FINS.FDISI],\n 0x42: [DebuggerX86.FINS.FCLEX],\n 0x43: [DebuggerX86.FINS.FINIT],\n 0x44: [DebuggerX86.FINS.FSETPM, DebuggerX86.TYPE_80287],\n 0x73: [DebuggerX86.FINS.FSINCOS, DebuggerX86.TYPE_80387]\n },\n 0xDC: {\n 0x00: [DebuggerX86.FINS.FADD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_IN],\n 0x01: [DebuggerX86.FINS.FMUL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_IN],\n 0x02: [DebuggerX86.FINS.FCOM, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_IN],\n 0x03: [DebuggerX86.FINS.FCOMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_IN],\n 0x04: [DebuggerX86.FINS.FSUB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_IN],\n 0x05: [DebuggerX86.FINS.FSUBR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_IN],\n 0x06: [DebuggerX86.FINS.FDIV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_IN],\n 0x07: [DebuggerX86.FINS.FDIVR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_IN],\n 0x30: [DebuggerX86.FINS.FADD, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN],\n 0x31: [DebuggerX86.FINS.FMUL, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN],\n 0x32: [DebuggerX86.FINS.FCOM, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN], // Obsolete encoding\n 0x33: [DebuggerX86.FINS.FCOMP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN], // Obsolete encoding\n 0x34: [DebuggerX86.FINS.FSUBR, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN],\n 0x35: [DebuggerX86.FINS.FSUB, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN],\n 0x36: [DebuggerX86.FINS.FDIVR, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN],\n 0x37: [DebuggerX86.FINS.FDIV, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN]\n },\n 0xDD: {\n 0x00: [DebuggerX86.FINS.FLD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_IN],\n 0x02: [DebuggerX86.FINS.FST, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_OUT],\n 0x03: [DebuggerX86.FINS.FSTP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_OUT],\n 0x04: [DebuggerX86.FINS.FRSTOR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_FPU | DebuggerX86.TYPE_IN],\n 0x06: [DebuggerX86.FINS.FSAVE, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_FPU | DebuggerX86.TYPE_OUT],\n 0x07: [DebuggerX86.FINS.FSTSW, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_OUT],\n 0x30: [DebuggerX86.FINS.FFREE, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN],\n 0x31: [DebuggerX86.FINS.FXCH, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT], // Obsolete encoding\n 0x32: [DebuggerX86.FINS.FST, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN],\n 0x33: [DebuggerX86.FINS.FSTP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN]\n },\n 0xDE: {\n 0x00: [DebuggerX86.FINS.FIADD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0x01: [DebuggerX86.FINS.FIMUL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0x02: [DebuggerX86.FINS.FICOM, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0x03: [DebuggerX86.FINS.FICOMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0x04: [DebuggerX86.FINS.FISUB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0x05: [DebuggerX86.FINS.FISUBR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0x06: [DebuggerX86.FINS.FIDIV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0x07: [DebuggerX86.FINS.FIDIVR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0x30: [DebuggerX86.FINS.FADDP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN],\n 0x31: [DebuggerX86.FINS.FMULP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN],\n 0x32: [DebuggerX86.FINS.FCOMP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN], // Obsolete encoding\n 0x33: [DebuggerX86.FINS.FCOMPP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN],\n 0x34: [DebuggerX86.FINS.FSUBRP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN],\n 0x35: [DebuggerX86.FINS.FSUBP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN],\n 0x36: [DebuggerX86.FINS.FDIVRP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN],\n 0x37: [DebuggerX86.FINS.FDIVP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN]\n },\n 0xDF: {\n 0x00: [DebuggerX86.FINS.FILD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0x02: [DebuggerX86.FINS.FIST, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_OUT],\n 0x03: [DebuggerX86.FINS.FISTP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_OUT],\n 0x04: [DebuggerX86.FINS.FBLD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BCD80 | DebuggerX86.TYPE_IN],\n 0x05: [DebuggerX86.FINS.FILD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LINT | DebuggerX86.TYPE_IN],\n 0x06: [DebuggerX86.FINS.FBSTP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BCD80 | DebuggerX86.TYPE_OUT],\n 0x07: [DebuggerX86.FINS.FISTP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LINT | DebuggerX86.TYPE_OUT],\n 0x30: [DebuggerX86.FINS.FFREEP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN], // Obsolete encoding\n 0x31: [DebuggerX86.FINS.FXCH, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT], // Obsolete encoding\n 0x32: [DebuggerX86.FINS.FSTP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN], // Obsolete encoding\n 0x33: [DebuggerX86.FINS.FSTP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN], // Obsolete encoding\n 0x34: [DebuggerX86.FINS.FSTSWAX, DebuggerX86.TYPE_80287]\n }\n };\n\n DebuggerX86.aaGrpDescs = [\n [\n /* GRP1B */\n [DebuggerX86.INS.ADD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.OR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.ADC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SBB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.AND, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SUB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.XOR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.CMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN]\n ],\n [\n /* GRP1W */\n [DebuggerX86.INS.ADD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.OR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.ADC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SBB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.AND, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SUB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.XOR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.CMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN]\n ],\n [\n /* GRP1SW */\n [DebuggerX86.INS.ADD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SBYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.OR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SBYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.ADC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SBYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SBB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SBYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.AND, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SBYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SUB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SBYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.XOR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SBYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.CMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SBYTE | DebuggerX86.TYPE_IN]\n ],\n [\n /* GRP2B */\n [DebuggerX86.INS.ROL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.ROR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n DebuggerX86.aOpDescUndefined,\n [DebuggerX86.INS.SAR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN]\n ],\n [\n /* GRP2W */\n [DebuggerX86.INS.ROL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.ROR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n DebuggerX86.aOpDescUndefined,\n [DebuggerX86.INS.SAR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN]\n ],\n [\n /* GRP2B1 */\n [DebuggerX86.INS.ROL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.ROR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n DebuggerX86.aOpDescUndefined,\n [DebuggerX86.INS.SAR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN]\n ],\n [\n /* GRP2W1 */\n [DebuggerX86.INS.ROL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.ROR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n DebuggerX86.aOpDescUndefined,\n [DebuggerX86.INS.SAR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN]\n ],\n [\n /* GRP2BC */\n [DebuggerX86.INS.ROL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.ROR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n DebuggerX86.aOpDescUndefined,\n [DebuggerX86.INS.SAR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN]\n ],\n [\n /* GRP2WC */\n [DebuggerX86.INS.ROL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.ROR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n DebuggerX86.aOpDescUndefined,\n [DebuggerX86.INS.SAR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN]\n ],\n [\n /* GRP3B */\n [DebuggerX86.INS.TEST, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n DebuggerX86.aOpDescUndefined,\n [DebuggerX86.INS.NOT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH],\n [DebuggerX86.INS.NEG, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH],\n [DebuggerX86.INS.MUL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.IMUL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH],\n [DebuggerX86.INS.DIV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.IDIV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH]\n ],\n [\n /* GRP3W */\n [DebuggerX86.INS.TEST, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n DebuggerX86.aOpDescUndefined,\n [DebuggerX86.INS.NOT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH],\n [DebuggerX86.INS.NEG, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH],\n [DebuggerX86.INS.MUL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.IMUL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH],\n [DebuggerX86.INS.DIV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.IDIV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH]\n ],\n [\n /* GRP4B */\n [DebuggerX86.INS.INC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH],\n [DebuggerX86.INS.DEC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH],\n DebuggerX86.aOpDescUndefined,\n DebuggerX86.aOpDescUndefined,\n DebuggerX86.aOpDescUndefined,\n DebuggerX86.aOpDescUndefined,\n DebuggerX86.aOpDescUndefined,\n DebuggerX86.aOpDescUndefined\n ],\n [\n /* GRP4W */\n [DebuggerX86.INS.INC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH],\n [DebuggerX86.INS.DEC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH],\n [DebuggerX86.INS.CALL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.CALL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_FARP | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.JMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.JMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_FARP | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n DebuggerX86.aOpDescUndefined\n ],\n [ /* OP0F */ ],\n [\n /* GRP6 */\n [DebuggerX86.INS.SLDT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80286],\n [DebuggerX86.INS.STR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80286],\n [DebuggerX86.INS.LLDT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286],\n [DebuggerX86.INS.LTR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286],\n [DebuggerX86.INS.VERR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286],\n [DebuggerX86.INS.VERW, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286],\n DebuggerX86.aOpDescUndefined,\n DebuggerX86.aOpDescUndefined\n ],\n [\n /* GRP7 */\n [DebuggerX86.INS.SGDT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80286],\n [DebuggerX86.INS.SIDT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80286],\n [DebuggerX86.INS.LGDT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286],\n [DebuggerX86.INS.LIDT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286],\n [DebuggerX86.INS.SMSW, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80286],\n DebuggerX86.aOpDescUndefined,\n [DebuggerX86.INS.LMSW, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286],\n DebuggerX86.aOpDescUndefined\n ],\n [\n /* GRP8 */\n DebuggerX86.aOpDescUndefined,\n DebuggerX86.aOpDescUndefined,\n DebuggerX86.aOpDescUndefined,\n DebuggerX86.aOpDescUndefined,\n [DebuggerX86.INS.BT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.BTS, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.BTR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.BTC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN]\n ]\n ];\n\n /*\n * Table of system (non-segment) descriptors, including indicators of which ones are gates.\n */\n DebuggerX86.SYSDESCS = {\n 0x0100: [\"tss286\", false],\n 0x0200: [\"ldt\", false],\n 0x0300: [\"busy tss286\", false],\n 0x0400: [\"call gate\", true],\n 0x0500: [\"task gate\", true],\n 0x0600: [\"int gate286\", true],\n 0x0700: [\"trap gate286\", true],\n 0x0900: [\"tss386\", false],\n 0x0B00: [\"busy tss386\", false],\n 0x0C00: [\"call gate386\", true],\n 0x0E00: [\"int gate386\", true],\n 0x0F00: [\"trap gate386\", true]\n };\n\n /*\n * TSS field names and offsets used by dumpTSS()\n */\n DebuggerX86.TSS286 = {\n \"PREV_TSS\": 0x00,\n \"CPL0_SP\": 0x02,\n \"CPL0_SS\": 0x04,\n \"CPL1_SP\": 0x06,\n \"CPL1_SS\": 0x08,\n \"CPL2_SP\": 0x0a,\n \"CPL2_SS\": 0x0c,\n \"TASK_IP\": 0x0e,\n \"TASK_PS\": 0x10,\n \"TASK_AX\": 0x12,\n \"TASK_CX\": 0x14,\n \"TASK_DX\": 0x16,\n \"TASK_BX\": 0x18,\n \"TASK_SP\": 0x1a,\n \"TASK_BP\": 0x1c,\n \"TASK_SI\": 0x1e,\n \"TASK_DI\": 0x20,\n \"TASK_ES\": 0x22,\n \"TASK_CS\": 0x24,\n \"TASK_SS\": 0x26,\n \"TASK_DS\": 0x28,\n \"TASK_LDT\": 0x2a\n };\n DebuggerX86.TSS386 = {\n \"PREV_TSS\": 0x00,\n \"CPL0_ESP\": 0x04,\n \"CPL0_SS\": 0x08,\n \"CPL1_ESP\": 0x0c,\n \"CPL1_SS\": 0x10,\n \"CPL2_ESP\": 0x14,\n \"CPL2_SS\": 0x18,\n \"TASK_CR3\": 0x1C,\n \"TASK_EIP\": 0x20,\n \"TASK_PS\": 0x24,\n \"TASK_EAX\": 0x28,\n \"TASK_ECX\": 0x2C,\n \"TASK_EDX\": 0x30,\n \"TASK_EBX\": 0x34,\n \"TASK_ESP\": 0x38,\n \"TASK_EBP\": 0x3C,\n \"TASK_ESI\": 0x40,\n \"TASK_EDI\": 0x44,\n \"TASK_ES\": 0x48,\n \"TASK_CS\": 0x4C,\n \"TASK_SS\": 0x50,\n \"TASK_DS\": 0x54,\n \"TASK_FS\": 0x58,\n \"TASK_GS\": 0x5C,\n \"TASK_LDT\": 0x60,\n \"TASK_IOPM\": 0x64\n };\n\n /*\n * Initialize every Debugger module on the page (as IF there's ever going to be more than one ;-))\n */\n Web.onInit(DebuggerX86.init);\n\n} // endif DEBUGGER\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/computer.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * BUILD INSTRUCTIONS\n *\n * To build PCx86 (pcx86.js), run Google's Closure Compiler, replacing \"*.js\" with the input file sequence defined\n * by the \"PCx86Files\" property in package.json:\n *\n * java -jar compiler.jar\n * --compilation_level ADVANCED_OPTIMIZATIONS\n * --define='DEBUG=false'\n * --warning_level=VERBOSE\n * --js *.js\n * --js_output_file pc.js\n *\n * Google's Closure Compiler (compiler.jar) is documented at https://developers.google.com/closure/compiler/\n * and is available for download here:\n *\n * http://closure-compiler.googlecode.com/files/compiler-latest.zip\n *\n * The PCx86 JavaScript files do have some initialization-order dependencies. If you load the files individually,\n * it's recommended that you load them in the same order that they're compiled.\n *\n * Generally speaking, component.js should be first, computer.js should be last (of the files based on component.js),\n * and panel.js should be listed early so that the Control Panel is ready as soon as possible.\n *\n * Another recent ordering requirement is that rom.js must be loaded before ram.js; this was true before, but now\n * it's required, because I'm starting to add ROM BIOS Data Area definitions to rom.js, and since the data area\n * is in RAM, ram.js may want access to some of those definitions.\n */\n\n\n\n/**\n * class Computer\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass Computer extends Component {\n /**\n * Computer(parmsComputer, parmsMachine, fSuspended)\n *\n * The Computer component has no required (parmsComputer) properties, but it does\n * support the following:\n *\n * autoPower: true to automatically power the computer (default), false to wait;\n * false is honored only if a \"power\" button binding exists.\n *\n * busWidth: number of memory address lines (address bits) on the computer's \"bus\";\n * 20 is the minimum (and the default), which implies 8086/8088 real-mode addressing,\n * while 24 is required for 80286 protected-mode addressing. This value is passed\n * directly through to the Bus component; see that component for more details.\n *\n * resume: one of the Computer.RESUME constants, which are as follows:\n * '0' if resume disabled (default)\n * '1' if enabled without prompting\n * '2' if enabled with prompting\n * '3' if enabled with prompting and auto-delete\n * or a string containing the path of a predefined JSON-encoded state\n *\n * state: the path to JSON-encoded state file (see details regarding 'state' below)\n *\n * The parmsMachine object, if provided, may contain any of:\n *\n * autoMount: if set, this should override any 'autoMount' property in the FDC's\n * parmsFDC object.\n *\n * autoPower: if set, this should override any 'autoPower' property in the Computer's\n * parmsComputer object.\n *\n * messages: if set, this should override any 'messages' property in the Debugger's\n * parmsDbg object.\n *\n * state: if set, this should override any 'state' property in the Computer's\n * parmsComputer object.\n *\n * url: the location of the machine XML file\n *\n * diagnostics: 0 for none, 1 for normal diagnostics, and 2 for diagnostics with prompting\n *\n * If a predefined state is supplied AND it's successfully loaded, then resume behavior\n * defaults to '1' (ie, resume enabled without prompting).\n *\n * This component insures that all components are ready before \"powering\" them.\n *\n * Different components become ready at different times, and initialization order (ie,\n * the order the scripts are combined on the page) only partially determines readiness.\n * This is because components like ROM and Video must finish loading their resource files\n * before they are ready. Other components become ready after we call their initBus()\n * function, because they have a Bus or CPU dependency, such as access to memory management\n * functions. And other components, like CPU and Panel, are ready as soon as their\n * constructor finishes.\n *\n * Once a component has indicated it's ready, we call its powerUp() notification\n * function (if it has one--it's optional). We call the CPU's powerUp() function last,\n * so that the CPU is assured that all other components are ready and \"powered\".\n *\n * @this {Computer}\n * @param {Object} parmsComputer\n * @param {Object} [parmsMachine]\n * @param {boolean} [fSuspended]\n */\n constructor(parmsComputer, parmsMachine, fSuspended)\n {\n super(\"Computer\", parmsComputer, Messages.COMPUTER);\n\n var cmp = this;\n this.setMachineParms(parmsMachine);\n\n this.fAutoPower = this.getMachineParm('autoPower', parmsComputer);\n this.nDiagnostics = +this.getMachineParm('diagnostics', parmsComputer);\n if (!(this.nDiagnostics >= 0 && this.nDiagnostics <= 2)) this.nDiagnostics = 1;\n\n /*\n * nPowerChange is 0 while the power state is stable, 1 while power is transitioning\n * to \"on\", and -1 while power is transitioning to \"off\".\n */\n this.nPowerChange = 0;\n\n /*\n * TODO: Deprecate 'buswidth' (it should have always used camelCase)\n */\n this.nBusWidth = parmsComputer['busWidth'] || parmsComputer['buswidth'];\n\n this.resume = Computer.RESUME_NONE;\n this.sStateData = null;\n this.fStateData = false; // remembers if sStateData was loaded\n this.fServerState = false;\n\n this.url = this.getMachineParm('url') || \"\";\n\n /*\n * Generate a random number x (where 0 <= x < 1), add 0.1 so that it's guaranteed to be\n * non-zero, convert to base 36, and chop off the leading digit and \"decimal\" point.\n */\n this.sMachineID = (Math.random() + 0.1).toString(36).substr(2,12);\n this.sUserID = this.queryUserID();\n\n /*\n * Find the appropriate CPU (and Debugger and Control Panel, if any)\n *\n * CLOSURE COMPILER TIP: To override the type of a right-hand expression (as we need to do here,\n * where we know getComponentByType() will only return an CPUX86 object or null), wrap the expression\n * in parentheses. I never knew this until I stumbled across it in \"Closure: The Definitive Guide\".\n */\n this.cpu = /** @type {CPUX86} */ (Component.getComponentByType(\"CPU\", this.id));\n if (!this.cpu) {\n Component.error(\"Unable to find CPU component\");\n return;\n }\n this.dbg = /** @type {DebuggerX86} */ (Component.getComponentByType(\"Debugger\", this.id));\n\n /*\n * Enumerate all the Video components for diagnostic displays, focus changes, and updateStatus() calls.\n */\n this.aVideo = [];\n for (var video = null; (video = this.getMachineComponent(\"Video\", video));) {\n this.aVideo.push(video);\n }\n\n /*\n * Initialize the Bus component\n */\n this.bus = new Bus({'id': this.idMachine + '.bus', 'busWidth': this.nBusWidth}, this.cpu, this.dbg);\n\n /*\n * Iterate through all the components and override their notice() and println() methods\n * so that their output can be rerouted to a Diagnostic Display or Control Panel, if any.\n */\n var iComponent, component;\n var aComponents = Component.getComponents(this.id);\n\n this.panel = /** @type {Panel} */ (Component.getComponentByType(\"Panel\", this.id));\n this.controlPanel = this.panel && this.panel.bindings['print'];\n\n this.noticeComputer = this.notice;\n this.printComputer = this.print;\n this.printlnComputer = this.println;\n if (this.controlPanel) {\n this.noticeComputer = this.panel.notice;\n this.printComputer = this.panel.print;\n this.printlnComputer = this.panel.println;\n }\n\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n component.notice = function noticeComputer(s, fPrintOnly, id) {\n cmp.outputDiagnostics(s);\n return cmp.noticeComputer.call(this, s, fPrintOnly, id);\n }.bind(component);\n component.print = function printComputer(s) {\n return cmp.printComputer.call(this, s);\n }.bind(component);\n component.println = function printlnComputer(s, type, id) {\n cmp.outputDiagnostics(s, type);\n return cmp.printlnComputer.call(this, s, type, id);\n }.bind(component);\n }\n\n this.cDiagnosticScreens = 0;\n if (!this.controlPanel && this.nDiagnostics) {\n this.enableDiagnostics();\n }\n\n this.println(PCX86.APPNAME + \" v\" + (XMLVERSION || PCX86.APPVERSION) + \"\\n\" + COPYRIGHT + \"\\n\" + LICENSE);\n\n if (DEBUG && this.messageEnabled()) this.printMessage(\"PREFETCH: \" + PREFETCH + \", TYPEDARRAYS: \" + TYPEDARRAYS);\n\n /*\n * Iterate through all the components again and call their initBus() handler, if any\n */\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component.initBus) component.initBus(this, this.bus, this.cpu, this.dbg);\n }\n\n /*\n * This timer replaces the CPU's old dedicated STATUS_UPDATES_PER_SECOND logic; periodic updateStatus()\n * calls are now our own responsibility.\n */\n this.cpu.addTimer(this.id, function updateStatusTimer() {\n cmp.updateStatus(false);\n }, 1000 / Computer.UPDATES_PER_SECOND);\n\n var sStatePath = null;\n var sResume = this.getMachineParm('resume');\n if (sResume !== undefined) {\n /*\n * Decide whether the 'resume' property is a number or the path of a state file to resume.\n */\n if (sResume.length > 1) {\n sStatePath = this.sResumePath = sResume;\n } else {\n this.resume = parseInt(sResume, 10);\n }\n }\n\n /*\n * The Computer 'state' property allows a state file to be specified independent of the 'resume' feature;\n * previously, you could only use 'resume' to load a state file -- which we still support, but loading a state\n * file that way prevents the machine's state from being saved, since we always resume from the 'resume' file.\n *\n * The other wrinkle is on the restore side: we need to IGNORE the 'state' property if a saved state now exists.\n * So we have to peek at localStorage, and unfortunately, the only way to \"peek\" is to actually load the data,\n * but we're not ready to use it yet, so powerUp() has been changed to use any existing stateComputer that we've\n * already loaded.\n *\n * However, there's now a wrinkle to the wrinkle: if a 'state' parameter has been passed via the URL, then that\n * OVERRIDES everything; it overrides any 'state' Computer parameter AND it disables resume of any saved state in\n * localStorage (in other words, it prevents fAllowResume from being true, and forcing resume off).\n */\n var fAllowResume = false;\n var sState = Web.getURLParm('state');\n if (!sState) {\n fAllowResume = true;\n sState = this.getMachineParm('state', parmsComputer);\n }\n if (sState) {\n sStatePath = this.sStatePath = sState;\n if (!fAllowResume) {\n this.fServerState = true;\n this.resume = Computer.RESUME_NONE;\n }\n if (this.resume) {\n this.stateComputer = new State(this, PCX86.APPVERSION);\n if (this.stateComputer.load()) {\n sStatePath = null;\n } else {\n delete this.stateComputer;\n }\n }\n }\n\n /*\n * If sStatePath is set, we must use it. But if there's no sStatePath AND resume is set,\n * then we have the option of resuming from a server-side state, assuming a valid USERID.\n */\n if (!sStatePath && this.resume) {\n sStatePath = this.getServerStatePath();\n if (sStatePath) this.fServerState = true;\n }\n\n this.sStateURL = sStatePath;\n\n if (!this.sStateURL) {\n this.setReady();\n } else {\n var sProgress = \"Loading \" + this.sStateURL + \"...\";\n Web.getResource(this.sStateURL, null, true, function(sURL, sResource, nErrorCode) {\n cmp.doneLoad(sURL, sResource, nErrorCode);\n }, function(nState) {\n cmp.println(sProgress, Component.PRINT.PROGRESS);\n });\n }\n\n if (!this.bindings[\"power\"]) this.fAutoPower = true;\n\n /*\n * Power on the computer, giving every component the opportunity to reset or restore itself.\n */\n if (!fSuspended && this.fAutoPower) this.wait(this.powerOn);\n }\n\n /**\n * clearPanel()\n *\n * @this {Computer}\n */\n clearPanel()\n {\n if (this.controlPanel) {\n this.controlPanel.value = \"\";\n }\n }\n\n /**\n * enableDiagnostics()\n *\n * @this {Computer}\n */\n enableDiagnostics()\n {\n if (!this.cDiagnosticScreens) {\n for (var i = 0; i < this.aVideo.length; i++) {\n var video = this.aVideo[i];\n if (video) {\n var control = video.getTextArea();\n if (control) {\n /*\n * By default, the Video textarea overlay has opacity and lineHeight styles set to \"0\"\n * to make the overall textarea and its blinking caret invisible (respectively), so in order\n * to use it as a diagnostic display, we must temporarily set both those styles to \"1\".\n */\n control.style.opacity = \"1\";\n control.style.lineHeight = \"1\";\n // control.style.fontSize = \"1.5vw\"; // this is a nice idea, but it doesn't work well with side-by-side machines\n this.cDiagnosticScreens++;\n }\n }\n }\n }\n }\n\n /**\n * disableDiagnostics()\n *\n * @this {Computer}\n * @return {boolean} (true if diagnostics were, or already are, disabled; false if they remain enabled)\n */\n disableDiagnostics()\n {\n if (this.cDiagnosticScreens) {\n if (this.nDiagnostics == 2) {\n this.nDiagnostics++;\n this.println(\"Press any key to continue...\");\n return false;\n }\n for (var i = 0; i < this.aVideo.length; i++) {\n var video = this.aVideo[i];\n if (video) {\n var control = video.getTextArea();\n if (control) {\n /*\n * Return the Video textarea overlay's opacity and lineHeight styles to their original values.\n */\n control.style.opacity = \"0\";\n control.style.lineHeight = \"0\";\n /*\n * Setting lineHeight in IE isn't sufficient to hide the caret; we must also set fontSize to \"0\",\n * and we make the change IE-specific because it can have weird side-effects in other browsers (eg,\n * it makes Safari on iOS over-zoom whenever the textarea receives focus).\n */\n if (Web.isUserAgent(\"MSIE\")) control.style.fontSize = \"0\";\n control.value = \"\";\n }\n }\n }\n this.cDiagnosticScreens = 0;\n }\n this.nDiagnostics = 0;\n return true;\n }\n\n /**\n * outputDiagnostics(sMessage, sType)\n *\n * @this {Computer}\n * @param {string} sMessage\n * @param {string} [sType]\n */\n outputDiagnostics(sMessage, sType)\n {\n if (this.cDiagnosticScreens) {\n for (var i = 0; i < this.aVideo.length; i++) {\n var video = this.aVideo[i];\n if (video) {\n var control = video.getTextArea();\n if (control) {\n if (sType != Component.PRINT.PROGRESS || sMessage.slice(-3) != \"...\") {\n Component.appendControl(control, sMessage + '\\n');\n } else {\n Component.replaceControl(control, sMessage, sMessage + '.');\n }\n }\n }\n }\n }\n }\n\n /**\n * notifyKbdEvent(event, fDown)\n *\n * This is called by the Keyboard component for all key presses, and it is effectively a no-op except\n * in the one special case where disableDiagnostics() has delayed powerOn until a key is pressed.\n *\n * @this {Computer}\n * @param {Object} [event]\n * @param {boolean} [fDown] is true for a keyDown event, false for a keyUp event\n * @return {boolean} (true if diagnostics disabled, false if enabled -- at the time of the call)\n */\n notifyKbdEvent(event, fDown)\n {\n var nDiagnostics = this.nDiagnostics;\n if (this.nDiagnostics == 3) {\n this.nDiagnostics++;\n this.setReady(); // this may trigger a call to disableDiagnostics(), which is why we snapshot nDiagnostics\n }\n return !nDiagnostics;\n }\n\n /**\n * getMachineID()\n *\n * @this {Computer}\n * @return {string}\n */\n getMachineID()\n {\n return this.sMachineID;\n }\n\n /**\n * setMachineParms(parmsMachine)\n *\n * If no explicit machine parms were provided, then we check for 'parms' in the bundled resources (if any).\n *\n * @this {Computer}\n * @param {Object} [parmsMachine]\n */\n setMachineParms(parmsMachine)\n {\n if (!parmsMachine) {\n var sParms;\n if (typeof resources == 'object' && (sParms = resources['parms'])) {\n try {\n parmsMachine = /** @type {Object} */ (eval(\"(\" + sParms + \")\")); // jshint ignore:line\n } catch(err) {\n Component.error(err.message + \" (\" + sParms + \")\");\n }\n }\n }\n this.parmsMachine = parmsMachine;\n }\n\n /**\n * getMachineParm(sParm, parmsComponent)\n *\n * If the machine parameter doesn't exist, we check for a matching component parameter (if parmsComponent\n * is provided), and failing that, we check the bundled resources (if any).\n *\n * At the moment, the only bundled resource request we expect to encounter is 'state'; if it exists, then\n * we return 'state' back to the caller (ie, the name of the resource), so that the caller will then attempt\n * to load the 'state' resource to obtain the actual state.\n *\n * TODO: This function could (and perhaps should) be modified to accept an optional type parameter (ie,\n * one of the values in Component.TYPE), so that parms like autoMount could be eval'ed here rather than by\n * the caller (eg, FDC.parseConfig()). The downside is that this function would have to return multiple types,\n * so every call would have to be cast to the expected type.\n *\n * @this {Computer}\n * @param {string} sParm\n * @param {Object} [parmsComponent] (eg, this.parms)\n * @return {string|undefined}\n */\n getMachineParm(sParm, parmsComponent)\n {\n var value = Web.getURLParm(sParm);\n if (value) {\n try {\n /*\n * Ideally, we could simply use strings as-is, but unfortunately, we need to convert all\n * supported escape sequences to their underlying characters, and using eval() is the simplest\n * way to deal with them; eg:\n *\n * \\', \\\", \\r, \\n, \\t, and \\xNN\n *\n * When a string containing the above sequences is passed as a machine or component parameter\n * (ie, as an embedPC() machine parameter or as XML component attribute), that conversion happens\n * automatically, either by virtue of implicit script evaluation, or by explicit eval() in\n * getComponentParms(). But when they're passed as a URL parameter, any backslashes are passed\n * through as-is.\n *\n * The complete list of backslash sequences supported by JavaScript:\n *\n * \\0 \\' \\\" \\\\ \\n \\r \\v \\t \\b \\f \\uXXXX \\xXX\n * ^J ^M ^K ^I ^H ^L\n *\n * and of course, eval() will convert them all, but there's no expectation of any but those I've\n * listed above, in part because of Jekyll limitations in some of our templates; eg:\n *\n * https://github.com/jeffpar/pcjs/blob/jekyll/_includes/machine-engines.html\n *\n * which could be overcome, but there's really no need to support more, since \\xNN can be used to\n * represent anything else.\n *\n * Finally, while the user should escape any quotation characters, just to be safe, we will try to\n * choose the safest quoting character for the overall string.\n */\n var ch = value.indexOf(\"'\") >= 0? '\"' : \"'\";\n value = /** @type {string} */ (eval(ch + value + ch)); // jshint ignore:line\n } catch(err) {\n Component.error(err.message + \" (\" + value + \")\");\n value = undefined;\n }\n }\n if (value === undefined && this.parmsMachine) {\n value = this.parmsMachine[sParm];\n }\n if (value === undefined && parmsComponent) {\n value = parmsComponent[sParm];\n }\n if (value === undefined && typeof resources == 'object' && resources[sParm]) {\n value = sParm;\n }\n return value;\n }\n\n /**\n * saveMachineParms()\n *\n * @this {Computer}\n * @return {string|null}\n */\n saveMachineParms()\n {\n return this.parmsMachine? JSON.stringify(this.parmsMachine) : null;\n }\n\n /**\n * getUserID()\n *\n * @this {Computer}\n * @return {string}\n */\n getUserID()\n {\n return this.sUserID || \"\";\n }\n\n /**\n * doneLoad(sURL, sStateData, nErrorCode)\n *\n * @this {Computer}\n * @param {string} sURL\n * @param {string} sStateData\n * @param {number} nErrorCode\n */\n doneLoad(sURL, sStateData, nErrorCode)\n {\n if (!nErrorCode) {\n this.sStateData = sStateData;\n this.fStateData = true;\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"loaded state file \" + sURL.replace(this.sUserID || \"xxx\", \"xxx\"));\n }\n } else {\n this.sResumePath = null;\n this.fServerState = false;\n this.notice('Unable to load machine state from server (error ' + nErrorCode + (sStateData? ': ' + Str.trim(sStateData) : '') + ')');\n }\n this.setReady();\n }\n\n /**\n * wait(fn, parms)\n *\n * wait() waits until every component is ready (including ourselves, the last component we check), then calls the\n * specified Computer method.\n *\n * TODO: The Closure Compiler makes it difficult for us to define a function type for \"fn\" that works in all cases;\n * sometimes we want to pass a function that takes only a \"number\", and other times we want to pass a function that\n * takes only an \"Array\" (the type will mirror that of the \"parms\" parameter). However, the Closure Compiler insists\n * that both functions must be declared as accepting both types of parameters. So once again, we must use an untyped\n * function declaration, instead of something stricter like:\n *\n * param {function(this:Computer, (number|Array|undefined)): undefined} fn\n *\n * @this {Computer}\n * @param {function(...)} fn\n * @param {number|Array} [parms] optional parameters\n */\n wait(fn, parms)\n {\n var computer = this;\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent <= aComponents.length; iComponent++) {\n var component = (iComponent < aComponents.length? aComponents[iComponent] : this);\n if (!component.isReady()) {\n component.isReady(function onComponentReady() {\n computer.wait(fn, parms);\n });\n return;\n }\n }\n if (DEBUG && this.messageEnabled()) this.printMessage(\"Computer.wait(ready)\");\n fn.call(this, parms);\n }\n\n /**\n * validateState(stateComputer)\n *\n * NOTE: We clear() stateValidate only when there's no stateComputer.\n *\n * @this {Computer}\n * @param {State|null} [stateComputer]\n * @return {boolean} true if state passes validation, false if not\n */\n validateState(stateComputer)\n {\n var fValid = true;\n var stateValidate = new State(this, PCX86.APPVERSION, Computer.STATE_VALIDATE);\n if (stateValidate.load() && stateValidate.parse()) {\n var sTimestampValidate = stateValidate.get(Computer.STATE_TIMESTAMP);\n var sTimestampComputer = stateComputer ? stateComputer.get(Computer.STATE_TIMESTAMP) : \"unknown\";\n if (sTimestampValidate != sTimestampComputer) {\n this.notice(\"Machine state may be out-of-date\\n(\" + sTimestampValidate + \" vs. \" + sTimestampComputer + \")\\nCheck your browser's local storage limits\");\n fValid = false;\n if (!stateComputer) stateValidate.clear();\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"Last state: \" + sTimestampComputer + \" (validate: \" + sTimestampValidate + \")\");\n }\n }\n }\n return fValid;\n }\n\n /**\n * powerOn(resume)\n *\n * Power every component \"up\", applying any previously available state information.\n *\n * @this {Computer}\n * @param {number} [resume] is a valid RESUME value; default is this.resume\n */\n powerOn(resume)\n {\n if (resume === undefined) {\n resume = this.resume || (this.sStateData? Computer.RESUME_AUTO : Computer.RESUME_NONE);\n }\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"Computer.powerOn(\" + (resume == Computer.RESUME_REPOWER ? \"repower\" : (resume ? \"resume\" : \"\")) + \")\");\n }\n\n if (this.nPowerChange) {\n return;\n }\n this.nPowerChange++;\n\n var fRepower = false;\n var fRestore = false;\n this.fRestoreError = false;\n var stateComputer = this.stateComputer || new State(this, PCX86.APPVERSION);\n\n if (resume == Computer.RESUME_REPOWER) {\n fRepower = true;\n }\n else if (resume > Computer.RESUME_NONE) {\n if (stateComputer.load(this.sStateData)) {\n /*\n * Since we're resuming something (either a predefined state or a state from localStorage), let's\n * create a \"failsafe\" checkpoint in localStorage, and destroy it at the end of a successful powerOn().\n * Which means, of course, that if a previous \"failsafe\" checkpoint already exists, something bad\n * may have happened the last time around.\n */\n this.stateFailSafe = new State(this, PCX86.APPVERSION, Computer.STATE_FAILSAFE);\n\n if (this.stateFailSafe.load()) {\n if (resume != Computer.RESUME_AUTO && this.powerReport(stateComputer)) {\n /*\n * Prompt the user; if they decline to restore, the state will be removed.\n */\n resume = Computer.RESUME_PROMPT;\n }\n /*\n * To ensure that the set() below succeeds, we need to call unload(), otherwise it may fail\n * with a \"read only\" error (eg, \"TypeError: Cannot assign to read only property 'timestamp'\").\n */\n this.stateFailSafe.unload();\n }\n\n this.stateFailSafe.set(Computer.STATE_TIMESTAMP, Usr.getTimestamp());\n this.stateFailSafe.store();\n\n var fValidate = this.resume && !this.fServerState;\n if (resume == Computer.RESUME_AUTO || Component.confirmUser(\"Click OK to restore the previous \" + PCX86.APPNAME + \" machine state.\")) {\n fRestore = stateComputer.parse();\n if (fRestore) {\n var sCode = stateComputer.get(UserAPI.RES.CODE);\n var sData = stateComputer.get(UserAPI.RES.DATA);\n if (sCode) {\n if (sCode == UserAPI.CODE.OK) {\n stateComputer.load(/** @type {string} */ (sData));\n } else {\n /*\n * A missing (or not yet created) state file is no cause for alarm, but other errors might be\n */\n if (sCode == UserAPI.CODE.FAIL && sData != UserAPI.FAIL.NOSTATE) {\n this.notice(\"Error: \" + sData);\n if (sData == UserAPI.FAIL.VERIFY) this.resetUserID();\n } else {\n this.println(sCode + \": \" + sData);\n }\n /*\n * Try falling back to the state that we should have saved in localStorage, as a backup to the\n * server-side state.\n */\n stateComputer.unload(); // discard the invalid server-side state first\n if (stateComputer.load()) {\n fRestore = stateComputer.parse();\n fValidate = true;\n } else {\n fRestore = false; // hmmm, there was nothing in localStorage either\n }\n }\n }\n }\n /*\n * If the load/parse was successful, and it was from localStorage (not sStateData),\n * then we should to try verify that localStorage snapshot is current. One reason it may\n * NOT be current is if localStorage was full and we got a quota error during the last\n * powerOff().\n */\n if (fValidate) this.validateState(fRestore? stateComputer : null);\n } else {\n /*\n * RESUME_PROMPT indicates we should delete the state if they clicked Cancel to confirm() above.\n */\n if (resume == Computer.RESUME_PROMPT) stateComputer.clear();\n }\n } else {\n /*\n * If there's no state, then there should also be no validation timestamp; if there is, then once again,\n * we're probably dealing with a quota error.\n */\n this.validateState();\n }\n delete this.sStateData;\n delete this.stateComputer;\n }\n\n /*\n * Start powering all components, including any data they may need to restore their state;\n * we restore power to the CPU last.\n */\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component !== this && component != this.cpu) {\n try {\n fRestore = this.powerRestore(component, stateComputer, fRepower, fRestore);\n } catch(err) {\n Component.error(component.type + \" power failure: \" + err.message);\n }\n }\n }\n\n /*\n * Assuming this is not a repower, we must perform another wait, because some components may\n * have marked themselves as \"not ready\" again (eg, the FDC component, if the restore forced it\n * to mount one or more additional disk images).\n */\n var aParms = [stateComputer, resume, fRestore];\n\n if (resume != Computer.RESUME_REPOWER) {\n this.wait(this.donePowerOn, aParms);\n return;\n }\n this.donePowerOn(aParms);\n }\n\n /**\n * powerRestore(component, stateComputer, fRepower, fRestore)\n *\n * @this {Computer}\n * @param {Component} component\n * @param {State} stateComputer\n * @param {boolean} fRepower\n * @param {boolean} fRestore\n * @return {boolean} true if restore should continue, false if not\n */\n powerRestore(component, stateComputer, fRepower, fRestore)\n {\n if (!component.flags.powered) {\n\n component.flags.powered = true;\n\n if (component.powerUp) {\n\n var data = null;\n if (fRestore) {\n data = stateComputer.get(component.id);\n if (!data) {\n /*\n * This is a hack that makes it possible for a machine whose ID has been\n * supplemented with a hyphenated numeric suffix to find object IDs in states\n * created from a machine without such a suffix.\n *\n * For example, if a state file was created from a machine with ID \"ibm5160\"\n * but the current machine is \"ibm5160-1\", this attempts a second lookup with\n * \"ibm5160\", enabling us to find objects that match the original machine ID\n * (eg, \"ibm5160.romEGA\").\n *\n * See /devices/pcx86/machine/5160/ega/640kb/array for examples of this.\n */\n data = stateComputer.get(component.id.replace(/-[0-9]+\\./i, '.'));\n }\n }\n\n /*\n * State.get() will return whatever was originally passed to State.set() (eg, an\n * Object or a string), but components are supposed to store only Objects, so if a\n * string comes back, something went wrong. By explicitly eliminating \"string\" data,\n * the Closure Compiler stops complaining that we might be passing strings to our\n * powerUp() functions (even though we know we're not). We could also add @type\n * overrides to the data assignments, but this seems like a useful runtime check.\n */\n if (typeof data === \"string\") data = null;\n\n /*\n * If computer is null, this is simply a repower notification, which most components\n * don't do anything with. Exceptions include: CPU (since it may be halted) and Video\n * (since its screen may be \"turned off\").\n */\n if (!component.powerUp(data, fRepower) && data) {\n\n if (component.notice(\"Unable to restore hardware state\")) {\n /*\n * If this is a resume error for a machine that also has a predefined state\n * AND we're not restoring from that state, then throw away the current state,\n * prevent any new state from being created, and then force a reload, which will\n * hopefully restore us to the functioning predefined state.\n *\n * TODO: Considering doing this in ALL cases, not just in situations where a\n * 'state' exists but we're not actually resuming from it.\n */\n if (this.sStatePath && !this.fStateData) {\n stateComputer.clear();\n this.resume = Computer.RESUME_NONE;\n Web.reloadPage();\n } else {\n /*\n * In all other cases, we set fRestoreError, which should trigger a call to\n * powerReport() and then delete the offending state.\n */\n this.fRestoreError = true;\n }\n }\n\n /*\n * Any failure triggers an automatic to call powerUp() again, without any state,\n * in the hopes that the component can recover by performing a reset.\n */\n component.powerUp(null);\n /*\n * We also disable the rest of the restore operation, because it's not clear\n * the remaining state information can be trusted; the machine is already in an\n * inconsistent state, so we're not likely to make things worse, and the only\n * alternative (starting over and performing a state-less reset) isn't likely to make\n * the user any happier. But, we'll see... we need some experience with the code.\n */\n fRestore = false;\n }\n }\n\n component.flags.initDone = true;\n\n if (!fRepower && component.comment) {\n var asComments = component.comment.split(\"|\");\n for (var i = 0; i < asComments.length; i++) {\n component.status(asComments[i]);\n }\n }\n }\n return fRestore;\n }\n\n /**\n * donePowerOn(aParms)\n *\n * This is nothing more than a continuation of powerOn(), giving us the option of calling wait() one more time.\n *\n * @this {Computer}\n * @param {Array} aParms containing [stateComputer, resume, fRestore]\n */\n donePowerOn(aParms)\n {\n if (!this.flags.initDone) {\n if (!this.disableDiagnostics()) {\n this.setReady(false);\n this.wait(this.donePowerOn, aParms);\n return;\n }\n this.flags.initDone = true;\n }\n\n if (DEBUG && this.flags.powered && this.messageEnabled()) {\n this.printMessage(\"Computer.donePowerOn(): redundant\");\n }\n\n var stateComputer = aParms[0];\n var fRepower = (aParms[1] < 0);\n var fRestore = aParms[2];\n\n var controlPower = this.bindings[\"power\"];\n if (controlPower) controlPower.textContent = \"Shutdown\";\n\n this.flags.powered = true;\n\n /*\n * Once we get to this point, we're guaranteed that all components are ready, so it's safe to power the CPU;\n * the CPU should begin executing immediately, unless a debugger is attached.\n */\n if (this.cpu) {\n /*\n * TODO: Do we not care about the return value here? (ie, is checking fRestoreError sufficient)?\n */\n this.powerRestore(this.cpu, stateComputer, fRepower, fRestore);\n this.cpu.autoStart();\n }\n\n /*\n * If the state was bad, offer to report it and then delete it. Deleting may be moot, since invariably a new\n * state will be created on powerOff() before the next powerOn(), but it seems like good paranoia all the same.\n */\n if (this.fRestoreError) {\n this.powerReport(stateComputer);\n stateComputer.clear();\n }\n\n if (!fRepower && this.stateFailSafe) {\n this.stateFailSafe.clear();\n delete this.stateFailSafe;\n }\n\n this.nPowerChange = 0;\n\n Component.processScript(this.idMachine, this.getMachineParm('autoScript'));\n }\n\n /**\n * checkPower()\n *\n * @this {Computer}\n * @return {boolean} true if the computer is fully powered, false otherwise\n */\n checkPower()\n {\n if (this.flags.unloading) {\n /*\n * We happen to know that we're currently only called by the CPU's onClickRun() function, so\n * if the unloading flag is set, then we've somehow gotten into a weird state where the machine\n * thinks it's being (or has been) unloaded by the browser, but in fact, it has not.\n *\n * The only time I've seen this happen is when the user clicks a link on a page that the browser\n * decided to treat as a download operation, instead of loading a new page. The proper way to\n * resolve that confusion is to set the \"download\" attribute on the link (which will prevent the\n * page's \"onbeforeunload\" handler from being called in the first place), but we cannot guarantee\n * that all such links will have their \"download\" attribute properly set.\n *\n * Hence, this code: we do the same thing that the show() function does, which is to attempt a\n * REPOWER operation. If that doesn't result in the powered flag getting turned back on, well,\n * then we're probably screwed.\n */\n this.flags.unloading = false;\n if (this.flags.initDone && !this.flags.powered) {\n this.powerOn(Computer.RESUME_REPOWER);\n }\n }\n\n if (this.flags.powered) return true;\n\n var component = null, iComponent;\n var aComponents = Component.getComponents(this.id);\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component !== this && !component.flags.ready) break;\n }\n if (iComponent == aComponents.length) {\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component !== this && !component.flags.powered) break;\n }\n }\n if (iComponent == aComponents.length) component = this;\n var s = \"The \" + component.type + \" component (\" + component.id + \") is not \" + (!component.flags.ready? \"ready yet\" + (component.fnReady? \" (waiting for notification)\" : \"\") : \"powered yet\") + \".\";\n Component.alertUser(s);\n return false;\n }\n\n /**\n * powerReport(stateComputer)\n *\n * TODO: Ever since I migrated the PCjs website from a Node-based web server on AWS to a GitHub Pages-based site,\n * the sendReport() API has been a bit-bucket. To be honest though, even before that change, I never really had\n * the time (or desire) to look through all the anonymous machine states that were being posted. Most of them were\n * probably due to the user switching away from a page before it finished loading anyway, leaving the machine in\n * an incomplete state. That said, there should be SOME automated way for people to share their machine states\n * when there's a more serious problem -- not this misleading prompt.\n *\n * In the meantime, to help reduce those kind of useless alerts, there's the new 'unloading' flag. However, I'm\n * not sure how reliably that's being set, so additionally, the default 'resume' setting (RESUME_AUTO) tries to be\n * MUCH more automatic now; this function, for example, shouldn't even be called now when RESUME_AUTO is in effect.\n * Another 'resume' setting (eg, RESUME_PROMPT) must be selected instead.\n *\n * @this {Computer}\n * @param {State} stateComputer\n * @return {boolean}\n */\n powerReport(stateComputer)\n {\n if (!this.flags.unloading) {\n if (Component.confirmUser(\"There may be a problem with your \" + PCX86.APPNAME + \" machine.\\n\\nTo help us diagnose it, click OK to send this \" + PCX86.APPNAME + \" machine state to http://\" + SITEHOST + \".\")) {\n Web.sendReport(PCX86.APPNAME, PCX86.APPVERSION, this.url, this.getUserID(), ReportAPI.TYPE.BUG, stateComputer.toString());\n }\n return true;\n }\n return false;\n }\n\n /**\n * powerOff(fSave, fShutdown)\n *\n * Power every component \"down\" and optionally save the machine state.\n *\n * There's one scenario that powerOff() isn't currently able to deal with very effectively: what to do when\n * the user switches away while it's still being restored, causing Disk getResource() calls to fail. The\n * Disk component calls notify() when that happens -- see Disk.mount() -- but the FDC and HDC controllers don't\n * notify *us* of those problems, so Computer assumes that the restore was completely successful, when in fact\n * it was only partially successful.\n *\n * Then we immediately arrive here to perform a save, following that incomplete restore. It would be wrong to\n * deal with that incomplete restore by setting fRestoreError, because we don't want to trigger a powerReport()\n * and the deletion of the previous state, because the state itself was presumably OK. Unfortunately, the new\n * state we now save will no longer include manually mounted disk images whose remounts were interrupted, so future\n * restores won't remount them either.\n *\n * We could perhaps solve this by having the Disk component notify us in those situations, set a new flag\n * (fRestoreIncomplete?), and set fSave to false if that's ever set. Be careful though: when fSave is false,\n * that means MORE than not saving; it also means deleting any previous state, which is NOT what you'd want to\n * do in a \"fRestoreIncomplete\" situation. Also, we have to worry about Disk operations that fail for other reasons,\n * making sure those failures don't interfere with the save process in the same way.\n *\n * As it stands, the worst that happens is any manually mounted disk images might have to be manually remounted,\n * which doesn't seem like a huge problem.\n *\n * @this {Computer}\n * @param {boolean} [fSave] is true to request a saved state\n * @param {boolean} [fShutdown] is true if the machine is being shut down\n * @return {string|null} string representing the saved state (or null if error)\n */\n powerOff(fSave, fShutdown)\n {\n var data;\n var sState = \"none\";\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"Computer.powerOff(\" + (fSave ? \"save\" : \"nosave\") + (fShutdown ? \",shutdown\" : \"\") + \")\");\n }\n\n if (this.nPowerChange) {\n return null;\n }\n this.nPowerChange--;\n\n var stateComputer = new State(this, PCX86.APPVERSION);\n var stateValidate = new State(this, PCX86.APPVERSION, Computer.STATE_VALIDATE);\n\n var sTimestamp = Usr.getTimestamp();\n stateValidate.set(Computer.STATE_TIMESTAMP, sTimestamp);\n stateComputer.set(Computer.STATE_TIMESTAMP, sTimestamp);\n stateComputer.set(Computer.STATE_VERSION, APPVERSION);\n stateComputer.set(Computer.STATE_HOSTURL, Web.getHostURL());\n stateComputer.set(Computer.STATE_BROWSER, Web.getUserAgent());\n\n /*\n * Always power the CPU \"down\" first, just to help insure it doesn't ask other components to do anything\n * after they're no longer ready.\n */\n if (this.cpu && this.cpu.powerDown) {\n data = this.cpu.powerDown(fSave, fShutdown);\n if (typeof data === \"object\") stateComputer.set(this.cpu.id, data);\n if (fShutdown) {\n this.cpu.flags.powered = false;\n if (data === false) sState = null;\n }\n }\n\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.flags.powered) {\n if (component.powerDown) {\n data = component.powerDown(fSave, fShutdown);\n if (typeof data === \"object\") stateComputer.set(component.id, data);\n }\n if (fShutdown) {\n component.flags.powered = false;\n if (data === false) sState = null;\n }\n }\n }\n\n if (sState) {\n if (fShutdown) {\n var fClear = false;\n var fClearAll = false;\n if (fSave) {\n if (this.sUserID) {\n this.saveServerState(this.sUserID, stateComputer.toString());\n }\n if (!stateValidate.store() || !stateComputer.store()) {\n sState = null;\n /*\n * New behavior as of v1.13.2: if it appears that localStorage is full, we blow it ALL away.\n * Dedicated server-side storage is the only way we'll ever be able to reliably preserve a\n * particular machine's state. Historically, attempting to limp along with whatever localStorage\n * is left just generates the same useless and annoying warnings over and over.\n */\n fClear = fClearAll = true;\n }\n }\n else {\n /*\n * I used to ALWAYS clear (ie, delete) any associated computer state, but now I do this only if the\n * current machine is \"resumable\", because there are situations where I have two configurations\n * for the same machine -- one resumable and one not -- and I don't want the latter throwing away the\n * state of the former.\n *\n * So this code is here now strictly for callers to delete the state of a \"resumable\" machine, not as\n * some paranoid clean-up operation.\n *\n * An undocumented feature of this operation is that if your configuration uses the special 'resume=\"3\"'\n * value, and you click the \"Reset\" button, and then you click OK to reset the everything, this will\n * actually reset EVERYTHING (ie, all localStorage for ALL configs will be reclaimed).\n */\n if (this.resume) {\n fClear = true;\n fClearAll = (this.resume == Computer.RESUME_DELETE);\n }\n }\n if (fClear) {\n stateComputer.clear(fClearAll);\n }\n } else {\n sState = stateComputer.toString();\n }\n }\n\n if (fShutdown) {\n this.flags.powered = false;\n var controlPower = this.bindings[\"power\"];\n if (controlPower) controlPower.textContent = \"Power\";\n }\n\n this.nPowerChange = 0;\n\n return sState;\n }\n\n /**\n * reset()\n *\n * Notify all (other) components with a reset() method that the Computer is being reset.\n *\n * NOTE: We'd like to reset the Bus first (due to the importance of the A20 line), but since we\n * allocated the Bus object ourselves, after all the other components were allocated, it ends\n * up near the end of Component's list of components. Hence the special case for this.bus below.\n *\n * @this {Computer}\n */\n reset()\n {\n if (this.bus && this.bus.reset) {\n this.printMessage(\"Resetting \" + this.bus.type);\n this.bus.reset();\n }\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component !== this && component !== this.bus && component.reset) {\n this.printMessage(\"Resetting \" + component.type);\n component.reset();\n }\n }\n }\n\n /**\n * start(ms, nCycles)\n *\n * Notify all (other) components with a start() method that the CPU has started.\n *\n * Note that we're called by startCPU(), which is why we exclude the CPU component,\n * as well as ourselves.\n *\n * @this {Computer}\n * @param {number} ms\n * @param {number} nCycles\n */\n start(ms, nCycles)\n {\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.type == \"CPU\" || component === this) continue;\n if (component.start) {\n component.start(ms, nCycles);\n }\n }\n }\n\n /**\n * stop(ms, nCycles)\n *\n * Notify all (other) components with a stop() method that the CPU has stopped.\n *\n * Note that we're called by stopCPU(), which is why we exclude the CPU component,\n * as well as ourselves.\n *\n * @this {Computer}\n * @param {number} ms\n * @param {number} nCycles\n */\n stop(ms, nCycles)\n {\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.type == \"CPU\" || component === this) continue;\n if (component.stop) {\n component.stop(ms, nCycles);\n }\n }\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {Computer}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var computer = this;\n\n switch (sBinding) {\n case \"power\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickPower() {\n computer.onPower();\n };\n return true;\n\n case \"reset\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickReset() {\n computer.onReset();\n };\n return true;\n\n /*\n * Technically, this binding should now be called \"saveState\", to clearly distinguish it from\n * the \"Save Machine\" control that's normally bound to the savePC() function in save.js. Saving\n * an entire machine includes everything needed to start/restore the machine; eg, the machine\n * XML configuration file(s) *and* the JSON-encoded machine state.\n */\n case \"save\":\n /*\n * Since this feature depends on the server supporting the PCjs User API (see userapi.js),\n * and since pcjs.org is no longer running a Node web server, we disable the feature for that\n * particular host.\n */\n if (Str.endsWith(Web.getHost(), \"pcjs.org\")) {\n if (DEBUG) this.log(\"Remote user API not available\");\n /*\n * We could also simply hide the control; eg:\n *\n * control.style.display = \"none\";\n *\n * but removing the control altogether seems better.\n */\n control.parentNode.removeChild(/** @type {Node} */ (control));\n return false;\n }\n this.bindings[sBinding] = control;\n control.onclick = function onClickSave() {\n var sUserID = computer.queryUserID(true);\n if (sUserID) {\n /*\n * I modified the test to include a check for sStatePath so that I could save new states\n * for machines with existing states; otherwise, I'd have no (easy) way of capturing and\n * updating their state. Making the machine (even temporarily) resumable would have been\n * one work-around, but it's not appropriate for some machines, as their state is simply\n * too large (for localStorage anyway, which is the default storage solution).\n */\n var fSave = !!(computer.resume && !computer.sResumePath || computer.sStatePath);\n var sState = computer.powerOff(fSave);\n if (fSave) {\n computer.saveServerState(sUserID, sState);\n } else {\n computer.notice(\"Resume disabled, machine state not saved\");\n }\n }\n /*\n * This seemed like a handy alternative, but it turned out to be a no-go, at least for large states:\n *\n * var sState = computer.powerOff(true);\n * if (sState) {\n * sState = \"data:text/json;charset=utf-8,\" + encodeURIComponent(sState);\n * window.open(sState);\n * }\n *\n * Perhaps if I embedded the data in a link on the current page instead; eg:\n *\n * $('<a href=\"' + sState + '\" download=\"state.json\">Download</a>').appendTo('#container');\n */\n };\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * resetUserID()\n *\n * @this {Computer}\n */\n resetUserID()\n {\n Web.setLocalStorageItem(Computer.STATE_USERID, \"\");\n this.sUserID = null;\n }\n\n /**\n * queryUserID(fPrompt)\n *\n * @this {Computer}\n * @param {boolean} [fPrompt]\n * @returns {string|null|undefined}\n */\n queryUserID(fPrompt)\n {\n var sUserID = this.sUserID;\n if (!sUserID) {\n sUserID = Web.getLocalStorageItem(Computer.STATE_USERID);\n if (sUserID !== undefined) {\n if (!sUserID && fPrompt) {\n /*\n * NOTE: Warning the user here that \"Save\" operations are not currently supported by pcjs.org is\n * merely a precaution, because ordinarily, setBinding() should have already determined if we are\n * running from pcjs.org and disabled any \"Save\" button.\n */\n sUserID = Component.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.\");\n if (sUserID) {\n sUserID = this.verifyUserID(sUserID);\n if (!sUserID) this.notice(\"The user ID is invalid.\");\n }\n }\n } else if (fPrompt) {\n this.notice(\"Browser local storage is not available\");\n }\n }\n return sUserID;\n }\n\n /**\n * verifyUserID(sUserID)\n *\n * @this {Computer}\n * @param {string} sUserID\n * @return {string} validated user ID, or null if error\n */\n verifyUserID(sUserID)\n {\n this.sUserID = null;\n var fMessages = DEBUG && this.messageEnabled();\n if (fMessages) this.printMessage(\"verifyUserID(\" + sUserID + \")\");\n var sRequest = Web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.VERIFY + '&' + UserAPI.QUERY.USER + '=' + sUserID;\n var response = Web.getResource(sRequest);\n var nErrorCode = response[0];\n var sResponse = response[1];\n if (!nErrorCode && sResponse) {\n try {\n response = eval(\"(\" + sResponse + \")\"); // jshint ignore:line\n if (response.code && response.code == UserAPI.CODE.OK) {\n Web.setLocalStorageItem(Computer.STATE_USERID, response.data);\n if (fMessages) this.printMessage(Computer.STATE_USERID + \" updated: \" + response.data);\n this.sUserID = response.data;\n } else {\n if (fMessages) this.printMessage(response.code + \": \" + response.data);\n }\n } catch(err) {\n Component.error(err.message + \" (\" + sResponse + \")\");\n }\n } else {\n if (fMessages) this.printMessage(\"invalid response (error \" + nErrorCode + \")\");\n }\n return this.sUserID;\n }\n\n /**\n * getServerStatePath()\n *\n * @this {Computer}\n * @return {string|null} sStatePath (null if no localStorage or no USERID stored in localStorage)\n */\n getServerStatePath()\n {\n var sStatePath = null;\n if (this.sUserID) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(Computer.STATE_USERID + \" for load: \" + this.sUserID);\n }\n sStatePath = Web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.LOAD + '&' + UserAPI.QUERY.USER + '=' + this.sUserID + '&' + UserAPI.QUERY.STATE + '=' + State.key(this, PCX86.APPVERSION);\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(Computer.STATE_USERID + \" unavailable\");\n }\n }\n return sStatePath;\n }\n\n /**\n * saveServerState(sUserID, sState)\n *\n * @this {Computer}\n * @param {string} sUserID\n * @param {string|null} sState\n */\n saveServerState(sUserID, sState)\n {\n /*\n * We must pass fSync == true, because (as I understand it) browsers will blow off any async\n * requests when a page is being closed. Since our request is synchronous, storeServerState()\n * should also return a result, but there's not much we can do with it, since browsers ALSO\n * tend to blow off alerts() and the like when closing down.\n */\n if (sState) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"size of server state: \" + sState.length + \" bytes\");\n }\n var response = this.storeServerState(sUserID, sState, true);\n if (response && response[UserAPI.RES.CODE] == UserAPI.CODE.OK) {\n this.notice(\"Machine state saved to server\");\n } else if (sState) {\n var sError = (response && response[UserAPI.RES.DATA]) || UserAPI.FAIL.BADSTORE;\n if (response[UserAPI.RES.CODE] == UserAPI.CODE.FAIL) {\n sError = \"Error: \" + sError;\n } else {\n sError = \"Error \" + response[UserAPI.RES.CODE] + \": \" + sError;\n }\n this.notice(sError);\n this.resetUserID();\n }\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"no state to store\");\n }\n }\n }\n\n /**\n * storeServerState(sUserID, sState, fSync)\n *\n * @this {Computer}\n * @param {string} sUserID\n * @param {string} sState\n * @param {boolean} [fSync] is true if we're powering down and should perform a synchronous request (default is async)\n * @return {*} server response if fSync is true and a response was received; otherwise null\n */\n storeServerState(sUserID, sState, fSync)\n {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(Computer.STATE_USERID + \" for store: \" + sUserID);\n }\n /*\n * TODO: Determine whether or not any browsers cancel our request if we're called during a browser \"shutdown\" event,\n * and whether or not it matters if we do an async request (currently, we're not, to try to ensure the request goes through).\n */\n var dataPost = {};\n dataPost[UserAPI.QUERY.REQ] = UserAPI.REQ.STORE;\n dataPost[UserAPI.QUERY.USER] = sUserID;\n dataPost[UserAPI.QUERY.STATE] = State.key(this, PCX86.APPVERSION);\n dataPost[UserAPI.QUERY.DATA] = sState;\n var sRequest = Web.getHost() + UserAPI.ENDPOINT;\n if (!fSync) {\n Web.getResource(sRequest, dataPost, true);\n } else {\n var response = Web.getResource(sRequest, dataPost);\n var sResponse = response[0];\n if (response[1]) {\n if (sResponse) {\n var i = sResponse.indexOf('\\n');\n if (i > 0) sResponse = sResponse.substr(0, i);\n if (!sResponse.indexOf(\"Error: \")) sResponse = sResponse.substr(7);\n }\n sResponse = '{\"' + UserAPI.RES.CODE + '\":' + response[1] + ',\"' + UserAPI.RES.DATA + '\":\"' + sResponse + '\"}';\n }\n if (DEBUG && this.messageEnabled()) this.printMessage(sResponse);\n return JSON.parse(sResponse);\n }\n return null;\n }\n\n /**\n * onPower()\n *\n * This handles UI requests to toggle the computer's power (eg, see the \"power\" button binding).\n *\n * @this {Computer}\n */\n onPower()\n {\n if (!this.nPowerChange) {\n if (!this.flags.powered) {\n this.wait(this.powerOn);\n } else {\n this.powerOff(false, true);\n }\n }\n }\n\n /**\n * onReset()\n *\n * This handles UI requests to reset the computer's state (eg, see the \"reset\" button binding).\n *\n * @this {Computer}\n */\n onReset()\n {\n /*\n * I'm going to start with the presumption that it makes little sense for an \"unpowered\" computer to be \"reset\";\n * ditto if the power state is currently being changed.\n */\n if (!this.flags.powered || this.nPowerChange) return;\n\n /*\n * Whether or not we autoStart on reset should depend at least in part on whether we were running originally.\n */\n if (this.cpu) {\n this.cpu.flags.autoStart = this.cpu.flags.running;\n }\n /*\n * If this is a \"resumable\" machine (and it's not using a predefined state), then we overload the reset\n * operation to offer an explicit \"save or discard\" option first. This is currently the only UI we offer to\n * discard a machine's state, including any disk changes. The traditional \"reset\" operation is still available\n * for non-resumable machines.\n *\n * TODO: Break this behavior out into a separate \"discard\" operation, in case the designer of the machine really\n * wants to clutter the UI with confusing options. ;-)\n */\n if (this.resume && !this.sResumePath) {\n /*\n * I used to bypass the prompt if this.resume == Computer.RESUME_AUTO, setting fSave to true automatically,\n * but that gives the user no means of resetting a resumable machine that contains errors in its resume state.\n */\n var fSave = (/* this.resume == Computer.RESUME_AUTO || */ this.flags.unloading || !Component.confirmUser(\"Click OK to reset this \" + PCX86.APPNAME + \" machine and discard all disk modifications.\"));\n this.powerOff(fSave, true);\n /*\n * Forcing the page to reload is an expedient option, but ugly. It's preferable to call powerOn()\n * and rely on all the components to reset themselves to their default state. The components with\n * the greatest burden here are FDC and HDC, which must rely on the fReload flag to determine whether\n * or not to unload/reload all their original auto-mounted disk images.\n *\n * However, if we started with a predefined state (ie, sStatePath is set), we take this shortcut, because\n * we don't (yet) have code in place to gracefully reload the initial state (requires calling getResource()\n * again); alternatively, we could avoid throwing that state away, but it seems better to save the memory.\n *\n * TODO: Make this more graceful, so that we can stop using the reloadPage() sledgehammer.\n */\n if (!fSave && this.sStatePath) {\n Web.reloadPage();\n return;\n }\n if (!fSave) this.fReload = true;\n this.powerOn(Computer.RESUME_NONE);\n this.fReload = false;\n } else {\n this.reset();\n if (this.cpu) this.cpu.autoStart();\n }\n this.updateFocus(true);\n }\n\n /**\n * getMachineComponent(sType, componentPrev)\n *\n * @this {Computer}\n * @param {string} sType\n * @param {Component|null} [componentPrev] of previously returned component, if any\n * @return {Component|null}\n */\n getMachineComponent(sType, componentPrev)\n {\n var componentLast = componentPrev;\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (componentPrev) {\n if (componentPrev == component) componentPrev = null;\n continue;\n }\n if (component.type == sType) return component;\n }\n if (!componentLast && sType != \"FPU\") {\n Component.log(\"Machine component type '\" + sType + \"' not found\", \"warning\");\n }\n return null;\n }\n\n /**\n * updateFocus(fScroll)\n *\n * NOTE: When soft keyboard buttons call us to return focus to the machine (and away from the button),\n * the browser's default behavior is to scroll the element into view, which can be annoying, especially on iOS,\n * where the display is more constrained, so we no longer do it by default (fScroll must be true).\n *\n * @this {Computer}\n * @param {boolean} [fScroll] (true if you really want the control scrolled into view)\n */\n updateFocus(fScroll)\n {\n if (this.aVideo.length) {\n /*\n * This seems to be recommended work-around to prevent the browser from scrolling the focused element\n * into view. The CPU is not a visual component, so when the CPU wants to set focus, the primary intent\n * is to ensure that keyboard input is fielded properly.\n */\n var x = 0, y = 0;\n if (!fScroll && window) {\n x = window.scrollX;\n y = window.scrollY;\n }\n\n /*\n * TODO: We need a mechanism to determine the \"active\" display, instead of hard-coding this to aVideo[0].\n */\n this.aVideo[0].setFocus();\n\n if (!fScroll && window) {\n window.scrollTo(x, y);\n }\n }\n }\n\n /**\n * updateStatus(fForce)\n *\n * If any DOM controls were bound to the CPU, then we need to call its updateStatus() handler; if there are no\n * such bindings, then cpu.updateStatus() does nothing.\n *\n * Similarly, if there's a Panel, then we need to call its updateStatus() handler, in case it created its own canvas\n * and implemented its own register display (eg, dumpRegisters()); if not, then panel.updateStatus() also does nothing.\n *\n * In practice, there will *either* be a Panel with a custom canvas *or* a set of DOM controls bound to the CPU *or*\n * neither. In theory, there could be BOTH, but that would be unusual.\n *\n * TODO: Consider alternate approaches to these largely register-oriented display updates. Ordinarily, we like to\n * separate logic from presentation, and currently the CPUX86 contains both, since it's the component that intimately\n * knows the names, number, sizes, etc, of all the active registers. The Panel component is the logical candidate,\n * but Panel is an optional component; generally, only machines that include Debugger also include Panel.\n *\n * @this {Computer}\n * @param {boolean} [fForce] (true will display registers even if the CPU is running and \"live\" registers are not enabled)\n */\n updateStatus(fForce)\n {\n /*\n * fForce is generally set to true whenever the CPU is transitioning to/from a running state, in which case\n * cpu.updateStatus() will definitely want to hide/show register contents; however, at other times, when the\n * CPU is running, constantly updating the DOM controls too frequently can adversely impact overall performance.\n *\n * So fForce serves as a hint to help cpu.updateStatus() make a more informed decision. panel.updateStatus()\n * currently doesn't care, on the theory that canvas updates should be significantly faster than DOM updates,\n * but we still pass fForce on.\n */\n if (this.cpu) this.cpu.updateStatus(fForce);\n if (this.panel) this.panel.updateStatus(fForce);\n /*\n * When called by our own timer for relatively infrequent DOM (see Computer.UPDATES_PER_SECOND), fForce is\n * explicitly set to false, and in those cases, we should avoid performing screen updates, because it may\n * subtly interfere with the Video component's normal refresh rate.\n */\n if (fForce !== false) {\n for (var i = 0; i < this.aVideo.length; i++) {\n this.aVideo[i].updateScreen(fForce);\n }\n }\n }\n\n /**\n * Computer.init()\n *\n * For every machine represented by an HTML element of class \"pcx86-machine\", this function\n * locates the HTML element of class \"computer\", extracting the JSON-encoded parameters for the\n * Computer constructor from the element's \"data-value\" attribute, invoking the constructor to\n * create a Computer component, and then binding any associated HTML controls to the new component.\n */\n static init()\n {\n /*\n * In non-COMPILED builds, embedMachine() may have set XMLVERSION.\n */\n if (!COMPILED && XMLVERSION) PCX86.APPVERSION = XMLVERSION;\n\n var aeMachines = Component.getElementsByClass(document, PCX86.APPCLASS + \"-machine\");\n\n for (var iMachine = 0; iMachine < aeMachines.length; iMachine++) {\n\n var eMachine = aeMachines[iMachine];\n var parmsMachine = Component.getComponentParms(eMachine);\n\n var aeComputers = Component.getElementsByClass(eMachine, PCX86.APPCLASS, \"computer\");\n\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n\n /*\n * We set fSuspended in the Computer constructor because we want to \"power up\" the\n * computer ourselves, after any/all bindings are in place.\n */\n var computer = new Computer(parmsComputer, parmsMachine, true);\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onInit(\" + computer.flags.powered + \")\");\n }\n\n /*\n * Bind any \"power\", \"reset\" and \"save\" buttons. An \"erase\" button was also considered,\n * but \"reset\" now provides a way to force the machine to start from scratch again, so \"erase\"\n * may be redundant now.\n */\n Component.bindComponentControls(computer, eComputer, PCX86.APPCLASS);\n\n /*\n * Power on the computer, giving every component the opportunity to reset or restore itself.\n */\n if (computer.fAutoPower) computer.wait(computer.powerOn);\n }\n }\n }\n\n /**\n * Computer.show()\n *\n * When exit() is using an \"onbeforeunload\" handler, this \"onpageshow\" handler allows us to repower everything,\n * without either resetting or restoring. We call powerOn() with a special resume value (RESUME_REPOWER) if the\n * computer is already marked as \"ready\", meaning the browser didn't change anything. This \"repower\" process\n * should be very quick, essentially just marking all components as powered again (so that, for example, the Video\n * component will start drawing again) and firing the CPU up again.\n */\n static show()\n {\n var aeComputers = Component.getElementsByClass(document, PCX86.APPCLASS, \"computer\");\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n var computer = /** @type {Computer} */ (Component.getComponentByType(\"Computer\", parmsComputer['id']));\n if (computer) {\n\n /*\n * Clear new flag that Component functions (eg, notice()) should check before alerting the user.\n */\n computer.flags.unloading = false;\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onShow(\" + computer.flags.initDone + \",\" + computer.flags.powered + \")\");\n }\n\n if (computer.flags.initDone && !computer.flags.powered) {\n /*\n * Repower the computer, notifying every component to continue running as-is.\n */\n computer.powerOn(Computer.RESUME_REPOWER);\n }\n }\n }\n }\n\n /**\n * Computer.exit()\n *\n * The Computer is currently the only component that uses an \"exit\" handler, which Web.onExit() defines as\n * either an \"unload\" or \"onbeforeunload\" handler. This gives us the opportunity to save the machine state,\n * using our powerOff() function, before the page goes away.\n *\n * It's worth noting that \"onbeforeunload\" offers one nice feature when used instead of \"onload\": the entire\n * page (and therefore this entire application) is retained in its current state by the browser (well, some\n * browsers), so that if you go to a new URL, either by entering a new URL in the same window/tab, or by pressing\n * the FORWARD button, and then you press the BACK button, the page is immediately restored to its previous state.\n *\n * In fact, that's how some browsers operate whether you have an \"onbeforeunload\" handler or not; in other words,\n * an \"onbeforeunload\" handler doesn't change the page retention behavior of the browser. By contrast, the mere\n * presence of an \"onunload\" handler generally causes a browser to throw the page away once the handler returns.\n *\n * However, in order to safely use \"onbeforeunload\", we must add yet another handler (\"onpageshow\") to repower\n * everything, without either resetting or restoring. Hence, the Computer.show() function, which calls powerOn()\n * with a special resume value (RESUME_REPOWER) if the computer is already marked as \"ready\", meaning the browser\n * didn't change anything. This \"repower\" process should be very quick, essentially just marking all components as\n * powered again (so that, for example, the Video component will start drawing again) and firing the CPU up again.\n *\n * Reportedly, some browsers (eg, Opera) don't support \"onbeforeunload\", in which case Component will have to use\n * \"unload\" instead. But even when the page must be rebuilt from scratch, the combination of browser cache and\n * localStorage means the simulation should be restored and become operational almost immediately.\n */\n static exit()\n {\n var aeComputers = Component.getElementsByClass(document, PCX86.APPCLASS, \"computer\");\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n var computer = /** @type {Computer} */ (Component.getComponentByType(\"Computer\", parmsComputer['id']));\n if (computer) {\n\n /*\n * Set new flag that Component functions (eg, notice()) should check before alerting the user.\n */\n computer.flags.unloading = true;\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onExit(\" + computer.flags.powered + \")\");\n }\n\n if (computer.flags.powered) {\n /**\n * Power off the computer, giving every component an opportunity to save its state,\n * but only if 'resume' has been set AND there is no valid resume path (because if a valid resume\n * path exists, we'll always load our state from there, and not from whatever we save here).\n */\n computer.powerOff(!!(computer.resume && !computer.sResumePath), true);\n }\n }\n }\n }\n}\n\nComputer.STATE_FAILSAFE = \"failsafe\";\nComputer.STATE_VALIDATE = \"validate\";\nComputer.STATE_TIMESTAMP = \"timestamp\";\nComputer.STATE_VERSION = \"version\";\nComputer.STATE_HOSTURL = \"url\";\nComputer.STATE_BROWSER = \"browser\";\nComputer.STATE_USERID = \"user\";\n\n/*\n * The following constants define all the resume options. Negative values (eg, RESUME_REPOWER) are for\n * internal use only, and RESUME_DELETE is not documented (it provides a way of deleting ALL saved states\n * whenever a resume is declined). As a result, the only \"end-user\" values are 0, 1 and 2.\n */\nComputer.RESUME_REPOWER = -1; // resume without changing any state (for internal use only)\nComputer.RESUME_NONE = 0; // default (no resume)\nComputer.RESUME_AUTO = 1; // automatically save/restore state\nComputer.RESUME_PROMPT = 2; // automatically save but conditionally restore (WARNING: if restore is declined, any state is discarded)\nComputer.RESUME_DELETE = 3; // same as RESUME_PROMPT but discards ALL machines states whenever ANY machine restore is declined (undocumented)\n\nComputer.UPDATES_PER_SECOND = 2;\n\n/*\n * Initialize every Computer on the page.\n */\nWeb.onInit(Computer.init);\nWeb.onShow(Computer.show);\nWeb.onExit(Computer.exit);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/state.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass State {\n /**\n * State(component, sVersion, sSuffix)\n *\n * State objects are used by components to save/restore their state.\n *\n * During a save operation, components add data to a State object via set(), and then return\n * the resulting data using data().\n *\n * During a restore operation, the Computer component passes the results of each data() call\n * back to the originating component.\n *\n * WARNING: Since State objects are low-level objects that have no UI requirements, they do not\n * inherit from the Component class, so you should only use class methods of Component, such as\n * Component.assert() (or Debugger methods if the Debugger is available).\n *\n * NOTE: 1.01 is the first version to provide limited save/restore support using localStorage.\n * From that point on, care must be taken to insure that any new version that's incompatible with\n * previous localStorage data be released with a version number that is at least 1 greater,\n * since we're tagging the localStorage data with the integer portion of the version string.\n *\n * @param {Component} component\n * @param {string} [sVersion] is used to append a major version number to the key\n * @param {string} [sSuffix] is used to append any additional suffixes to the key\n */\n constructor(component, sVersion, sSuffix)\n {\n this.id = component.id;\n this.dbg = component.dbg;\n this.json = \"\";\n this.state = {};\n this.fLoaded = this.fParsed = false;\n this.key = State.key(component, sVersion, sSuffix);\n this.unload(component.parms);\n }\n\n /**\n * set(id, data)\n *\n * @this {State}\n * @param {number|string} id\n * @param {Object|string} data\n */\n set(id, data)\n {\n try {\n this.state[id] = data;\n } catch(e) {\n Component.log(e.message);\n }\n }\n\n /**\n * get(id)\n *\n * @this {State}\n * @param {number|string} id\n * @return {Object|string|null}\n */\n get(id)\n {\n return this.state[id] || null;\n }\n\n /**\n * data()\n *\n * @this {State}\n * @return {Object}\n */\n data()\n {\n return this.state;\n }\n\n /**\n * load(json)\n *\n * WARNING: Make sure you follow this call with either a call to parse() or unload(),\n * because any stringified data that we've loaded isn't usable until it's been parsed.\n *\n * @this {State}\n * @param {string|null} [json]\n * @return {boolean} true if state exists in localStorage, false if not\n */\n load(json)\n {\n if (json) {\n this.json = json;\n this.fLoaded = true;\n this.fParsed = false;\n return true;\n }\n if (this.fLoaded) {\n /*\n * This is assumed to be a redundant load().\n */\n return true;\n }\n if (Web.hasLocalStorage()) {\n var s = Web.getLocalStorageItem(this.key);\n if (s) {\n this.json = s;\n this.fLoaded = true;\n if (DEBUG) Component.log(\"localStorage(\" + this.key + \"): \" + s.length + \" bytes loaded\");\n return true;\n }\n }\n return false;\n }\n\n /**\n * parse()\n *\n * This completes the load() operation, by parsing what was loaded, on the assumption there\n * might be some benefit to deferring parsing until we've given the user a chance to confirm.\n * Otherwise, load() could have just as easily done this, too.\n *\n * @this {State}\n * @return {boolean} true if successful, false if error\n */\n parse()\n {\n var fSuccess = true;\n if (!this.fParsed) {\n try {\n this.state = JSON.parse(this.json);\n this.fParsed = true;\n } catch (e) {\n Component.error(e.message || e);\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * store()\n *\n * @this {State}\n * @return {boolean} true if successful, false if error\n */\n store()\n {\n var fSuccess = true;\n if (Web.hasLocalStorage()) {\n var s = JSON.stringify(this.state);\n if (Web.setLocalStorageItem(this.key, s)) {\n if (DEBUG) Component.log(\"localStorage(\" + this.key + \"): \" + s.length + \" bytes stored\");\n } else {\n /*\n * WARNING: Because browsers tend to disable all alerts() during an \"unload\" operation,\n * it's unlikely anyone will ever see the \"quota\" errors that occur at this point. Need to\n * think of some way to notify the user that there's a problem, and offer a way of cleaning\n * up old states.\n */\n Component.error(\"Unable to store \" + s.length + \" bytes in browser local storage\");\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * toString()\n *\n * @this {State}\n * @return {string} JSON-encoded state\n */\n toString()\n {\n return this.state? JSON.stringify(this.state) : this.json;\n }\n\n /**\n * unload(parms)\n *\n * This discards any data saved via set() or loaded via load(), creating an empty State object.\n * Note that you have to follow this call with an explicit call to store() if you want to remove\n * the state from localStorage as well.\n *\n * @this {State}\n * @param {Object} [parms]\n */\n unload(parms)\n {\n this.json = \"\";\n this.state = {};\n this.fLoaded = this.fParsed = false;\n if (parms) this.set(\"parms\", parms);\n }\n\n /**\n * clear(fAll)\n *\n * This unloads the current state, and then clears ALL localStorage for the current machine,\n * independent of version, to reduce the chance of orphaned states wasting part of our limited allocation.\n *\n * @this {State}\n * @param {boolean} [fAll] true to unconditionally clear ALL localStorage for the current domain\n */\n clear(fAll)\n {\n this.unload();\n var aKeys = Web.getLocalStorageKeys();\n for (var i = 0; i < aKeys.length; i++) {\n var sKey = aKeys[i];\n if (sKey && (fAll || sKey.substr(0, this.key.length) == this.key)) {\n Web.removeLocalStorageItem(sKey);\n if (DEBUG) Component.log(\"localStorage(\" + sKey + \") removed\");\n aKeys.splice(i, 1);\n i = 0;\n }\n }\n }\n\n /**\n * State.key(component, sVersion, sSuffix)\n *\n * This encapsulates the key generation code.\n *\n * @param {Component} component\n * @param {string} [sVersion] is used to append a major version number to the key\n * @param {string} [sSuffix] is used to append any additional suffixes to the key\n * @return {string} key\n */\n static key(component, sVersion, sSuffix)\n {\n var key = component.id;\n if (sVersion) {\n var i = sVersion.indexOf('.');\n if (i > 0) key += \".v\" + sVersion.substr(0, i);\n }\n if (sSuffix) {\n key += \".\" + sSuffix;\n }\n return key;\n }\n\n /**\n * State.compress(aSrc)\n *\n * @param {Array.<number>|null} aSrc\n * @return {Array.<number>|null} is either the original array (aSrc), or a smaller array of \"count, value\" pairs (aComp)\n */\n static compress(aSrc)\n {\n if (aSrc) {\n var iSrc = 0;\n var iComp = 0;\n var aComp = [];\n while (iSrc < aSrc.length) {\n var n = aSrc[iSrc];\n\n var iCompare = iSrc + 1;\n while (iCompare < aSrc.length && aSrc[iCompare] === n) iCompare++;\n aComp[iComp++] = iCompare - iSrc;\n aComp[iComp++] = n;\n iSrc = iCompare;\n }\n if (aComp.length < aSrc.length) return aComp;\n }\n return aSrc;\n }\n\n /**\n * State.decompress(aComp)\n *\n * @param {Array.<number>} aComp\n * @param {number} nLength is expected length of decompressed data\n * @return {Array.<number>}\n */\n static decompress(aComp, nLength)\n {\n var iDst = 0;\n var aDst = new Array(nLength);\n var iComp = 0;\n while (iComp < aComp.length - 1) {\n var c = aComp[iComp++];\n var n = aComp[iComp++];\n while (c--) {\n aDst[iDst++] = n;\n }\n }\n\n return aDst;\n }\n\n /**\n * State.compressEvenOdd(aSrc)\n *\n * This is a very simple variation on compress() that compresses all the EVEN elements of aSrc first,\n * followed by all the ODD elements. This tends to work better on EGA video memory, because when odd/even\n * addressing is enabled (eg, for text modes), the DWORD values tend to alternate, which is the worst case\n * for compress(), but the best case for compressEvenOdd().\n *\n * One wrinkle we support: if the first element is uninitialized, then we assume the entire array is undefined,\n * and return an empty compressed array. Conversely, decompressEvenOdd() will take an empty compressed array\n * and return an uninitialized array.\n *\n * @param {Array.<number>|null} aSrc\n * @return {Array.<number>|null} is either the original array (aSrc), or a smaller array of \"count, value\" pairs (aComp)\n */\n static compressEvenOdd(aSrc)\n {\n if (aSrc) {\n var iComp = 0, aComp = [];\n if (aSrc[0] !== undefined) {\n for (var off = 0; off < 2; off++) {\n var iSrc = off;\n while (iSrc < aSrc.length) {\n var n = aSrc[iSrc];\n var iCompare = iSrc + 2;\n while (iCompare < aSrc.length && aSrc[iCompare] === n) iCompare += 2;\n aComp[iComp++] = (iCompare - iSrc) >> 1;\n aComp[iComp++] = n;\n iSrc = iCompare;\n }\n }\n }\n if (aComp.length < aSrc.length) return aComp;\n }\n return aSrc;\n }\n\n /**\n * State.decompressEvenOdd(aComp, nLength)\n *\n * This is the counterpart to compressEvenOdd(). Note that because there's nothing in the compressed sequence\n * that differentiates a compress() sequence from a compressEvenOdd() sequence, you simply have to be consistent:\n * if you used even/odd compression, then you must use even/odd decompression.\n *\n * @param {Array.<number>} aComp\n * @param {number} nLength is expected length of decompressed data\n * @return {Array.<number>}\n */\n static decompressEvenOdd(aComp, nLength)\n {\n var iDst = 0;\n var aDst = new Array(nLength);\n var iComp = 0;\n while (iComp < aComp.length - 1) {\n var c = aComp[iComp++];\n var n = aComp[iComp++];\n while (c--) {\n aDst[iDst] = n;\n iDst += 2;\n }\n /*\n * The output of a \"count,value\" pair will never exceed the end of the output array, so as soon as we reach it\n * the first time, we know it's time to switch to ODD elements, and as soon as we reach it again, we should be\n * done.\n */\n\n if (iDst == nLength) iDst = 1;\n }\n\n return aDst;\n }\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/embed.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * We now support asynchronous XML and XSL file loads; simply set fAsync (below) to true.\n *\n * NOTE: For that support to work, we have to keep track of the number of machines on the page\n * (ie, how many embedMachine() calls were issued), reduce the count as each machine XML file\n * is fully transformed into HTML, and when the count finally returns to zero, notify all the\n * machine component init() handlers.\n *\n * Also, to prevent those init() handlers from running prematurely, we must disable all page\n * notification events at the start of the embedding process (Web.enablePageEvents(false)) and\n * re-enable them at the end (Web.enablePageEvents(true)).\n */\nvar fAsync = true;\nvar cAsyncMachines = 0;\n\n/**\n * loadXML(sFile, idMachine, sAppName, sAppClass, sParms, fResolve, display, done)\n *\n * This is the preferred way to load all XML and XSL files. It uses getResource()\n * to load them as strings, which parseXML() can massage before parsing/transforming them.\n *\n * For example, since I've been unable to get the XSLT document() function to work inside any\n * XSL document loaded by JavaScript's XSLT processor, that has prevented me from dynamically\n * loading any XML machine file that uses the \"ref\" attribute to refer to and incorporate\n * another XML document.\n *\n * To solve that, I've added an fResolve parameter that tells parseXML() to fetch any\n * referenced documents ITSELF and insert them into the XML string prior to parsing, instead\n * of relying on the XSLT template to pull them in. That fetching is handled by resolveXML(),\n * which iterates over the XML until all \"refs\" have been resolved (including any nested\n * references).\n *\n * Also, XSL files with a <!DOCTYPE [...]> cause MSIE's Microsoft.XMLDOM.loadXML() function\n * to choke, so I strip that out prior to parsing as well.\n *\n * TODO: Figure out why the XSLT document() function works great when the web browser loads an\n * XML file (and the associated XSL file) itself, but does not work when loading documents via\n * JavaScript XSLT support. Is it broken, is it a security issue, or am I just calling it wrong?\n *\n * @param {string} sXMLFile\n * @param {string|null|undefined} idMachine\n * @param {string|null|undefined} sAppName\n * @param {string|null|undefined} sAppClass\n * @param {string|null|undefined} sParms (machine parameters, if any)\n * @param {string|null|undefined} sClass (an optional machine class name used to style the machine)\n * @param {boolean} fResolve is true to resolve any \"ref\" attributes\n * @param {function(string)} display\n * @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)\n */\nfunction loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n{\n var doneLoadXML = function(sURLName, sXML, nErrorCode) {\n if (nErrorCode) {\n if (!sXML) sXML = \"unable to load \" + sXMLFile + \" (\" + nErrorCode + \")\";\n done(sXML, null);\n return;\n }\n parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done);\n };\n display(\"Loading \" + sXMLFile + \"...\");\n Web.getResource(sXMLFile, null, fAsync, doneLoadXML);\n}\n\n/**\n * parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n *\n * Generates an XML document from an XML string. This function also provides a work-around for XSLT's\n * lack of support for the document() function (at least on some browsers), by replacing every reference\n * tag (ie, a tag with a \"ref\" attribute) with the contents of the referenced file.\n *\n * @param {string} sXML\n * @param {string|null} sXMLFile\n * @param {string|null|undefined} idMachine\n * @param {string|null|undefined} sAppName\n * @param {string|null|undefined} sAppClass\n * @param {string|null|undefined} sParms (machine parameters, if any)\n * @param {string|null|undefined} sClass (an optional machine class name used to style the machine)\n * @param {boolean} fResolve is true to resolve any \"ref\" attributes; default is false\n * @param {function(string)} display\n * @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)\n */\nfunction parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n{\n var buildXML = function(sXML, sError) {\n if (sError) {\n done(sError, null);\n return;\n }\n if (idMachine) {\n\n /*\n * A more sensible place to record the machine XML would be embedMachine(), like we do for the\n * XSL file, but since we're about to modify the original machine XML, it's best to record it now.\n */\n Component.addMachineResource(idMachine, sXMLFile, sXML);\n\n var sURL = sXMLFile;\n if (sURL && sURL.indexOf('/') < 0 && window.location.pathname.slice(-1) == '/') {\n sURL = window.location.pathname + sURL;\n }\n /*\n * We embed the URL of the XML file both as a separate \"xml\" attribute for easy access from the\n * XSL file, and as part of the \"parms\" attribute for easy access from machines (see getMachineParm()).\n */\n if (!sParms) {\n sParms = '{';\n } else if (sParms.slice(-1) == '}') {\n sParms = sParms.slice(0, -1);\n if (sParms.length > 1) sParms += ',';\n } else { // sParms must just be a \"state\" file, so encode it as a \"state\" property\n sParms = '{state:\"' + sParms + '\",';\n }\n sParms += 'url:\"' + sURL + '\"}';\n /*\n * Note that while we no longer generate a machine XML file with a \"state\" attribute (because it's\n * encoded inside the \"parms\" attribute), the XSL file must still cope with \"state\" attributes inside\n * other XML files; for example, manifest XML files like /apps/pcx86/1981/visicalc/manifest.xml contain\n * machine elements with \"state\" attributes that must still be passed down to the computer element\n * \"the old fashioned way\".\n *\n * Until/unless that changes, components.xsl cannot be simplified as much as I might have hoped.\n */\n if (typeof resources == 'object') sURL = null; // turn off URL inclusion if we have embedded resources\n sParms = sParms.replace(/\\$/g, \"$$$$\");\n if (sClass) {\n /*\n * If there's no hard-coded \"class\" attribute in the machine tag, then we can set one in the final\n * replacement below, just like we do for sParms and sURL. However, if a \"class\" attribute already\n * exists, we need alter it and then zap the sClass variable.\n */\n var match = sXML.match(/(<machine[^>]*\\sclass=)(['\"])(.*?)(\\2.*?>)/);\n if (match) {\n sXML = sXML.replace(match[0], match[1] + match[2] + sClass + match[4]);\n sClass = null;\n }\n }\n sXML = sXML.replace(/(<machine[^>]*\\sid=)(['\"]).*?\\2/, \"$1$2\" + idMachine + \"$2\" + (sClass? ' class=\"' + sClass + '\"' : '') + (sParms? \" parms='\" + sParms + \"'\" : \"\") + (sURL? ' url=\"' + sURL + '\"' : ''));\n }\n\n if (!fResolve) {\n /*\n * I'm trying to switch to a shared components.xsl (at least for all PC-class machines),\n * but in the interim, that means hacking the XSL file on the fly to reflect the actual class.\n */\n sXML = sXML.replace(/(<xsl:variable name=\"APPNAME\">).*?(<\\/xsl:variable>)/, \"$1\" + sAppName + \"$2\");\n sXML = sXML.replace(/(<xsl:variable name=\"APPCLASS\">).*?(<\\/xsl:variable>)/, \"$1\" + sAppClass + \"$2\");\n\n /*\n * Non-COMPILED kludge to replace the version number template in the XSL file (which we assume we're reading,\n * since fResolve is false) with whatever XMLVERSION we extracted from the XML file (see corresponding kludge below).\n *\n * ES6 ALERT: Template strings.\n */\n if (!COMPILED && XMLVERSION) {\n sXML = sXML.replace(/<xsl:variable name=\"APPVERSION\"\\/>/, `<xsl:variable name=\"APPVERSION\">${XMLVERSION}</xsl:variable>`);\n }\n }\n\n /*\n * If the resource we requested is not really an XML file (or the file didn't exist and the server simply returned\n * a message like \"Cannot GET /devices/pc/machine/5150/cga/64kb/donkey/machine.xml\"), we'd like to display a more\n * meaningful message, because the XML DOM parsers will blithely return a document that contains nothing useful; eg:\n *\n * This page contains the following errors:error on line 1 at column 1:\n * Document is empty Below is a rendering of the page up to the first error.\n *\n * Supposedly, the IE XML DOM parser will throw an exception, but I haven't tested that, and unless all other\n * browsers do that, that's not helpful.\n *\n * The best I can do at this stage (assuming Web.getResource() didn't drop any error information on the floor)\n * is verify that the requested resource \"looks like\" valid XML (in other words, it begins with a '<').\n */\n var xmlDoc = null;\n if (sXML.charAt(0) == '<') {\n try {\n /*\n * Another hack for MSIE, which fails to load XSL documents containing a <!DOCTYPE [...]> tag.\n *\n * This is also why the XSLTProcessor 'transformToFragment' method in Microsoft Edge silently failed,\n * so I had pull this hack out of the \"ActiveXObject\" code. And rather than add yet-another Microsoft\n * browser check, I'm going to try doing this across the board, and hope that none of the other XSLT\n * processors fail *without* the DOCTYPE tag.\n */\n if (!fResolve) {\n sXML = sXML.replace(/<!DOCTYPE(.|[\\r\\n])*]>\\s*/g, \"\");\n }\n /*\n * Beginning with Microsoft Edge and the corresponding release of Windows 10, all the\n * 'ActiveXObject' crud has gone away; but of course, this code must remain in place if\n * we want to continue supporting older Internet Explorer browsers (ie, back to IE9).\n */\n /** @namespace window.ActiveXObject */\n if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1\n xmlDoc = new window.ActiveXObject(\"Microsoft.XMLDOM\");\n xmlDoc.async = false;\n xmlDoc['loadXML'](sXML);\n } else {\n /** @namespace window.DOMParser */\n xmlDoc = (new window.DOMParser()).parseFromString(sXML, \"text/xml\");\n }\n } catch(e) {\n xmlDoc = null;\n sXML = e.message;\n }\n } else {\n sXML = \"unrecognized XML: \" + (sXML.length > 255? sXML.substr(0, 255) + \"...\" : sXML);\n }\n done(sXML, xmlDoc);\n };\n if (sXML) {\n if (PRIVATE) sXML = sXML.replace(/\\/library.xml/, \"/private/library.xml\");\n if (fResolve) {\n resolveXML(sXML, display, buildXML);\n return;\n }\n buildXML(sXML, null);\n return;\n }\n done(\"no data\" + (sXMLFile? \" for file: \" + sXMLFile : \"\"), null);\n}\n\n/**\n * resolveXML(sXML, display, done)\n *\n * Replaces every tag with a \"ref\" attribute with the contents of the corresponding file.\n *\n * TODO: Fix some of the limitations of this code, such as: 1) requiring the \"ref\" attribute\n * to appear as the tag's first attribute, 2) requiring the \"ref\" attribute to be double-quoted,\n * and 3) requiring the \"ref\" tag to be self-closing.\n *\n * @param {string} sXML\n * @param {function(string)} display\n * @param {function(string,(string|null))} done (the first string contains the resolved XML data, the second is for any error message)\n */\nfunction resolveXML(sXML, display, done)\n{\n var matchRef;\n var reRef = /<([a-z]+)\\s+ref=\"(.*?)\"(.*?)\\/>/g;\n\n if ((matchRef = reRef.exec(sXML))) {\n\n var sRefFile = matchRef[2];\n\n var doneReadXML = function(sURLName, sXMLRef, nErrorCode) {\n if (nErrorCode || !sXMLRef) {\n done(sXML, \"unable to resolve XML reference: \" + matchRef[0] + \" (\" + nErrorCode + \")\");\n return;\n }\n /*\n * If there are additional attributes in the \"referring\" XML tag, we want to insert them\n * into the \"referred\" XML tag; attributes that don't exist in the referred tag should be\n * appended, and attributes that DO exist should be overwritten.\n */\n var sRefAttrs = matchRef[3];\n if (sRefAttrs) {\n var aXMLRefTag = sXMLRef.match(new RegExp(\"<\" + matchRef[1] + \"[^>]*>\"));\n if (aXMLRefTag) {\n var sXMLNewTag = aXMLRefTag[0];\n /*\n * Iterate over all the attributes in the \"referring\" XML tag (sRefAttrs)\n */\n var matchAttr;\n var reAttr = /( [a-z]+=)(['\"])(.*?)\\2/gi;\n while ((matchAttr = reAttr.exec(sRefAttrs))) {\n if (sXMLNewTag.toLowerCase().indexOf(matchAttr[1].toLowerCase()) < 0) {\n /*\n * This is the append case....\n */\n sXMLNewTag = sXMLNewTag.replace(\">\", matchAttr[0] + \">\");\n } else {\n /*\n * This is the overwrite case....\n */\n sXMLNewTag = sXMLNewTag.replace(new RegExp(matchAttr[1] + \"(['\\\"])(.*?)\\\\1\"), matchAttr[0]);\n }\n }\n if (aXMLRefTag[0] != sXMLNewTag) {\n sXMLRef = sXMLRef.replace(aXMLRefTag[0], sXMLNewTag);\n }\n } else {\n done(sXML, \"missing <\" + matchRef[1] + \"> in \" + sRefFile);\n return;\n }\n }\n\n /*\n * Apparently when a Windows Azure server delivers one of my XML files, it may modify the first line:\n *\n * <?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n\n *\n * I didn't determine exactly what it was doing at this point (probably just changing the \\n to \\r\\n),\n * but in any case, relaxing the following replace() solved it.\n */\n sXMLRef = sXMLRef.replace(/<\\?xml[^>]*>[\\r\\n]*/, \"\");\n\n sXML = sXML.replace(matchRef[0], sXMLRef);\n\n resolveXML(sXML, display, done);\n };\n\n display(\"Loading \" + sRefFile + \"...\");\n Web.getResource(sRefFile, null, fAsync, doneReadXML);\n return;\n }\n done(sXML, null);\n}\n\n/**\n * embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * This allows to you embed a machine on a web page, by transforming the machine XML into HTML.\n *\n * @param {string} sAppName is the app name (eg, \"PCx86\")\n * @param {string} sAppClass is the app class (eg, \"pcx86\"); also known as the machine class\n * @param {string} sVersion is the app version (eg, \"1.15.7\")\n * @param {string} idMachine\n * @param {string|undefined} sXMLFile\n * @param {string|undefined} sXSLFile\n * @param {string|undefined} sParms (machine parameters, if any)\n * @param {string|undefined} sClass (an optional machine class name used to style the machine)\n * @return {boolean} true if successful, false if error\n */\nfunction embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n var eMachine, eWarning, fSuccess = true;\n\n if (!sXMLFile) {\n sXMLFile = \"machine.xml\";\n if (!sXSLFile) sXSLFile = \"components.xsl\";\n }\n \n cAsyncMachines++;\n Component.addMachine(idMachine);\n\n var doneMachine = function() {\n\n if (!--cAsyncMachines) {\n if (fAsync) Web.enablePageEvents(true);\n }\n };\n\n var displayError = function(sError) {\n Component.log(sError);\n displayMessage(\"Error: \" + sError);\n if (fSuccess) doneMachine();\n fSuccess = false;\n };\n\n var displayMessage = function(sMessage) {\n if (eWarning === undefined) {\n /*\n * Our MarkOut module (in convertMDMachineLinks()) creates machine containers that look like:\n *\n * <div id=\"' + sMachineID + '\" class=\"machine-placeholder\"><p>Embedded PC</p><p class=\"machine-warning\">...</p></div>\n *\n * with the \"machine-warning\" paragraph pre-populated with a warning message that the user will\n * see if nothing at all happens. But hopefully, in the normal case (and especially the error case),\n * *something* will have happened.\n *\n * Note that it is the HTMLOut module (in processMachines()) that ultimately decides which scripts to\n * include and then generates the embedXXX() call.\n */\n var aeWarning = (eMachine && Component.getElementsByClass(eMachine, \"machine-warning\"));\n eWarning = (aeWarning && aeWarning[0]) || eMachine;\n }\n if (eWarning) eWarning.innerHTML = Str.escapeHTML(sMessage);\n };\n\n try {\n eMachine = document.getElementById(idMachine);\n if (eMachine) {\n\n /*\n * If we have a 'css' resource, add it to the page first.\n */\n var css;\n if (typeof resources == \"object\" && (css = resources['css'])) {\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n // noinspection JSDeprecatedSymbols\n if (style.styleSheet) {\n // noinspection JSDeprecatedSymbols\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n head.appendChild(style);\n }\n\n if (!sXSLFile) {\n /*\n * Now that PCjs is an open-source project, we can make the following test more flexible,\n * and revert to the internal template if DEBUG *or* internal version (instead of *and*).\n *\n * Third-party sites that don't use the PCjs server will ALWAYS want to specify a fully-qualified\n * path to the XSL file, unless they choose to mirror our folder structure.\n */\n var sAppFolder = sAppClass;\n if (DEBUG || !sVersion) {\n if (sAppClass != \"c1pjs\") sAppFolder = \"shared\";\n sXSLFile = \"/modules/\" + sAppFolder + \"/templates/components.xsl\";\n } else {\n if (sAppClass.substr(0, 3) == \"pdp\") sAppFolder = \"pdpjs\";\n sXSLFile = \"/versions/\" + sAppFolder + \"/\" + sVersion + \"/components.xsl\";\n }\n }\n\n var processXML = function(sXML, xml) {\n if (!xml) {\n displayError(sXML);\n return;\n }\n\n /*\n * Non-COMPILED kludge to extract the version number from the stylesheet path in the machine XML file;\n * we don't need this code in COMPILED (non-DEBUG) releases, because APPVERSION is hard-coded into them.\n */\n if (!COMPILED) {\n var aMatch = sXML.match(/<\\?xml-stylesheet[^>]* href=(['\"])[^'\"]*?\\/([0-9.]*)\\/([^'\"]*)\\1/);\n if (aMatch) {\n XMLVERSION = aMatch[2];\n }\n }\n\n var transformXML = function(sXSL, xsl) {\n if (!xsl) {\n displayError(sXSL);\n return;\n }\n\n /*\n * Record the XSL file, in case someone wants to save the entire machine later.\n * \n * NOTE: sXSLFile will never be undefined by this point, but apparently the Closure Compiler doesn't realize that. \n */\n Component.addMachineResource(idMachine, sXSLFile || \"\", sXSL);\n\n /*\n * The <machine> template in components.xsl now generates a \"machine div\" that makes\n * the div we required the caller of embedMachine() to provide redundant, so instead\n * of appending this fragment to the caller's node, we REPLACE the caller's node.\n * This works only because because we ALSO inject the caller's \"machine div\" ID into\n * the fragment's ID during parseXML().\n *\n * eMachine.innerHTML = sFragment;\n *\n * Also, if the transform function fails, make sure you're using the appropriate\n * \"components.xsl\" and not a \"machine.xsl\", because the latter will not produce valid\n * embeddable HTML (and is the most common cause of failure at this final stage).\n */\n displayMessage(\"Processing \" + sXMLFile + \"...\");\n\n /*\n * Beginning with Microsoft Edge and the corresponding release of Windows 10, all the\n * 'ActiveXObject' crud has gone away; but of course, this code must remain in place if\n * we want to continue supporting older Internet Explorer browsers (ie, back to IE9).\n */\n if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1\n var sFragment = xml['transformNode'](xsl);\n if (sFragment) {\n eMachine.outerHTML = sFragment;\n doneMachine();\n } else {\n displayError(\"transformNodeToObject failed\");\n }\n }\n else if (document.implementation && document.implementation.createDocument) {\n var xsltProcessor = new XSLTProcessor();\n xsltProcessor['importStylesheet'](xsl);\n var eFragment = xsltProcessor['transformToFragment'](xml, document);\n if (eFragment) {\n /*\n * This fails in Microsoft Edge...\n *\n var machine = eFragment.getElementById(idMachine);\n if (!machine) {\n displayError(\"machine generation failed: \" + idMachine);\n } else\n */\n if (eMachine.parentNode) {\n eMachine.parentNode.replaceChild(eFragment, eMachine);\n doneMachine();\n } else {\n /*\n * NOTE: This error can occur if our Node web server, when processing a folder with\n * both a manifest.xml with a machine.xml reference AND a README.md containing a\n * machine link, generates duplicate embedXXX() calls for the same machine; if the\n * first embedXXX() call finds its target, subsequent calls for the same target will\n * fail.\n *\n * Technically, such a folder is in a misconfigured state, but it happens, in part\n * because when we switched to the Jekyll web server, we had to add machine links to\n * all README.md files where we had previously relied on manifest.xml or machine.xml\n * processing. This is because the Jekyll web server currently doesn't process XML\n * files, nor is support for that likely to be added any time soon; it was a nice\n * feature of the Node web server, but it's not clear that it's worth doing for Jekyll.\n */\n displayError(\"invalid machine element: \" + idMachine);\n }\n } else {\n displayError(\"transformToFragment failed\");\n }\n } else {\n /*\n * Perhaps I should have performed this test at the outset; on the other hand, I'm\n * not aware of any browsers don't support one or both of the above XSLT transformation\n * methods, so treat this as a bug.\n */\n displayError(\"unable to transform XML: unsupported browser\");\n }\n };\n /*\n * NOTE: sXSLFile will never be undefined by this point, but apparently the Closure Compiler doesn't realize that. \n */\n loadXML(sXSLFile || \"\", null, sAppName, sAppClass, null, null, false, displayMessage, transformXML);\n };\n\n if (sXMLFile.charAt(0) != '<') {\n loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, true, displayMessage, processXML);\n } else {\n parseXML(sXMLFile, null, idMachine, sAppName, sAppClass, sParms, sClass, false, displayMessage, processXML);\n }\n } else {\n displayError(\"missing machine element: \" + idMachine);\n }\n } catch(e) {\n displayError(e.message);\n }\n return fSuccess;\n}\n\n/**\n * embedC1P(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedC1P(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"C1Pjs\", \"c1pjs\", APPVERSION, idMachine, sXMLFile, sXSLFile, undefined, sClass);\n}\n\n/**\n * embedPCx86(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPCx86(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PCx86\", \"pcx86\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPC8080(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPC8080(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PC8080\", \"pc8080\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPDP10(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPDP10(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PDPjs\", \"pdp10\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPDP11(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPDP11(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PDPjs\", \"pdp11\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * findMachineComponent(idMachine, sType)\n *\n * @param {string} idMachine\n * @param {string} sType\n * @return {Component|null}\n */\nfunction findMachineComponent(idMachine, sType)\n{\n return Component.getComponentByType(sType, idMachine + \".machine\");\n}\n\n/**\n * commandMachine(control, fSingle, idMachine, sComponent, sCommand, sValue)\n *\n * Use Component methods to find the requested component for a specific machine, and if the component is found,\n * then check its 'exports' table for an entry matching the specified command string, and if an entry is found, then\n * the corresponding function is called with the specified data.\n *\n * @param {Object} control\n * @param {boolean} fSingle\n * @param {string} idMachine\n * @param {string} sComponent\n * @param {string} sCommand\n * @param {string} [sValue]\n * @return {boolean}\n */\nfunction commandMachine(control, fSingle, idMachine, sComponent, sCommand, sValue)\n{\n if (sCommand == \"script\") {\n if (Component.processScript(idMachine, sValue)) {\n if (fSingle) control.disabled = true;\n return true;\n }\n return false;\n }\n if (sComponent) {\n var component = Component.getComponentByType(sComponent, idMachine + \".machine\");\n if (component) {\n var exports = component['exports'];\n if (exports) {\n var fnCommand = exports[sCommand];\n if (fnCommand) {\n if (fnCommand.call(component, sValue)) {\n if (fSingle) control.disabled = true;\n return true;\n }\n return false;\n }\n }\n }\n }\n console.log(\"unimplemented: commandMachine('\" + idMachine + \"','\" + sComponent + \"','\" + sCommand + \"','\" + sValue + \"')\");\n return false;\n}\n\n/**\n * Prevent the Closure Compiler from renaming functions we want to export, by adding them as global properties.\n *\n * TODO: Consider making all these functions properties on a single global object (eg, 'PCjs'), to minimize global\n * pollution and risk of name collision.\n */\nif (APPNAME == \"C1Pjs\") {\n window['embedC1P'] = embedC1P;\n}\nif (APPNAME == \"PCx86\") {\n window['embedPC'] = embedPCx86; // WARNING: embedPC() deprecated as of v1.23.0\n window['embedPCx86'] = embedPCx86;\n}\nif (APPNAME == \"PC8080\") {\n window['embedPC8080'] = embedPC8080;\n}\nif (APPNAME == \"PDPjs\") {\n window['embedPDP10'] = embedPDP10;\n window['embedPDP11'] = embedPDP11;\n}\n\nwindow['commandMachine'] = commandMachine;\n\nwindow['enableEvents'] = Web.enablePageEvents;\nwindow['sendEvent'] = Web.sendPageEvent;\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/save.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * savePC(idMachine, sPCJSFile, callback)\n *\n * @param {string} idMachine\n * @param {string} sPCJSFile\n * @param {function(Object)} [callback]\n * @return {boolean} true if successful, false if error\n */\nfunction savePC(idMachine, sPCJSFile, callback)\n{\n var cmp = /** @type {Computer} */ (Component.getComponentByType(\"Computer\", idMachine));\n var dbg = false; // /** @type {Debugger} */ (Component.getComponentByType(\"Debugger\", idMachine));\n if (cmp) {\n var sState = cmp.powerOff(true);\n var sParms = cmp.saveMachineParms();\n if (!sPCJSFile) {\n if (DEBUG) {\n sPCJSFile = \"/versions/pcx86/\" + (XMLVERSION || APPVERSION) + \"/pcx86-uncompiled.js\"\n } else {\n sPCJSFile = \"/versions/pcx86/\" + (XMLVERSION || APPVERSION) + \"/pcx86\" + (dbg? \"-dbg\" : \"\") + \".js\";\n }\n }\n if (callback && callback({ state: sState, parms: sParms })) return true;\n Web.getResource(sPCJSFile, null, true, function(sURL, sResponse, nErrorCode) {\n downloadCSS(sURL, sResponse, nErrorCode, [idMachine, Str.getBaseName(sPCJSFile, true), sParms, sState]);\n });\n return true;\n }\n Component.alertUser(\"Unable to identify machine '\" + idMachine + \"'\");\n return false;\n}\n\n/**\n * downloadCSS(sURL, sPCJS, nErrorCode, aMachineInfo)\n *\n * @param {string} sURL\n * @param {string} sPCJS\n * @param {number} nErrorCode\n * @param {Array} aMachineInfo ([0] = idMachine, [1] = sScript, [2] = sParms, [3] = sState)\n */\nfunction downloadCSS(sURL, sPCJS, nErrorCode, aMachineInfo)\n{\n if (!nErrorCode && sPCJS) {\n aMachineInfo.push(sPCJS);\n var res = Component.getMachineResources(aMachineInfo[0]);\n var sCSSFile = null;\n for (var sName in res) {\n if (Str.endsWith(sName, \"components.xsl\")) {\n sCSSFile = sName.replace(\".xsl\", \".css\");\n break;\n }\n }\n if (!sCSSFile) {\n /*\n * This is probably a bad idea (ie, allowing downloadPC() to proceed with our stylesheet)...\n */\n downloadPC(sURL, null, 0, aMachineInfo);\n } else {\n Web.getResource(sCSSFile, null, true, function(sURL, sResponse, nErrorCode) {\n downloadPC(sURL, sResponse, nErrorCode, aMachineInfo);\n });\n }\n return;\n }\n Component.alertUser(\"Error (\" + nErrorCode + \") requesting \" + sURL);\n}\n\n/**\n * downloadPC(sURL, sCSS, nErrorCode, aMachineInfo)\n *\n * @param {string} sURL\n * @param {string|null} sCSS\n * @param {number} nErrorCode\n * @param {Array} aMachineInfo ([0] = idMachine, [1] = sScript, [2] = sParms, [3] = sState, [4] = sPCJS)\n */\nfunction downloadPC(sURL, sCSS, nErrorCode, aMachineInfo)\n{\n var matchScript, sXMLFile, sXSLFile;\n var idMachine = aMachineInfo[0], sScript = aMachineInfo[1], sPCJS = aMachineInfo[4];\n\n /*\n * sPCJS is supposed to contain the entire PCjs script, which has been wrapped with:\n *\n * (function(){...\n *\n * at the top and:\n *\n * ...})();\n *\n * at the bottom, thanks to the following Closure Compiler option:\n *\n * --output_wrapper \"(function(){%output%})();\"\n *\n * NOTE: There may also be a source map comment appended to the script, which we now ignore; eg:\n *\n * //# sourceMappingURL=/versions/pcx86/1.36.1/pcx86.map\n *\n * Immediately inside that wrapping, we want to embed all the specified machine's resources, using:\n *\n * var resources = {\"xml\": \"...\", \"xsl\": \"...\", ...};\n *\n * Note that the \"resources\" variable has been added to our externs.js, to prevent it from being renamed\n * by the Closure Compiler.\n */\n matchScript = sPCJS.match(/^(\\s*\\(function\\(\\){)([\\s\\S]*)(}\\)\\(\\);)/);\n if (!matchScript) {\n /*\n * If the match failed, we assume that a DEBUG (uncompiled) script is being used,\n * so we'll provide a fake match that should work with whatever script was provided.\n */\n if (DEBUG) {\n matchScript = [sPCJS, \"\", sPCJS, \"\"];\n } else {\n Component.alertUser(\"Unsupported script\");\n return;\n }\n }\n\n var resOld = Component.getMachineResources(idMachine), resNew = {};\n for (var sName in resOld) {\n var data = resOld[sName];\n var sExt = Str.getExtension(sName);\n if (sExt == \"xml\") {\n /*\n * Look through this resource for <disk> entries whose paths do not appear as one of the\n * other machine resources, and remove those entries.\n */\n var matchDisk, reDisk = /[ \\t]*<disk [^>]*path=(['\"])(.*?)\\1.*?<\\/disk>\\n?/g;\n while (matchDisk = reDisk.exec(resOld[sName])) {\n var path = matchDisk[2];\n if (path) {\n if (resOld[path]) {\n Component.log(\"recording disk: '\" + path + \"'\");\n } else {\n data = data.replace(matchDisk[0], \"\");\n }\n }\n }\n sXMLFile = sName = Str.getBaseName(sName);\n }\n else if (sExt == \"xsl\") {\n sXSLFile = sName = Str.getBaseName(sName);\n }\n Component.log(\"saving resource: '\" + sName + \"' (\" + data.length + \" bytes)\");\n resNew[sName] = data;\n }\n\n if (sCSS) {\n resNew[sName = 'css'] = sCSS;\n Component.log(\"saving resource: '\" + sName + \"' (\" + sCSS.length + \" bytes)\");\n }\n\n if (aMachineInfo[2]) {\n var sParms = resNew[sName = 'parms'] = aMachineInfo[2];\n Component.log(\"saving resource: '\" + sName + \"' (\" + sParms.length + \" bytes)\");\n }\n\n if (aMachineInfo[3]) {\n var sState = resNew[sName = 'state'] = aMachineInfo[3];\n Component.log(\"saving resource: '\" + sName + \"' (\" + sState.length + \" bytes)\");\n }\n\n if (sXMLFile && sXSLFile) {\n var sResources = JSON.stringify(resNew);\n\n sScript += \".js\";\n sPCJS = matchScript[1] + \"var resources=\" + sResources + \";\" + matchScript[2] + matchScript[3];\n Component.log(\"saving machine: '\" + idMachine + \"' (\" + sPCJS.length + \" bytes)\");\n\n /*\n * I don't recall exactly why I did this, because I just tested FireFox with copyright symbols intact,\n * and it seems to work fine. And unfortunately, if we print any copyright strings containing the HTML\n * entity, the entity doesn't get translated prior to output. So if it turns out we DO need this,\n * it's better to replace with the old-fashioned ASCII version.\n * \n * sPCJS = sPCJS.replace(/\\u00A9/g, \"(C)\"); // \"©\" or \"©\"\n */\n\n var sAlert = Web.downloadFile(sPCJS, \"javascript\", false, sScript);\n\n sAlert += ', copy it to your web server as \"' + sScript + '\", and then add the following to your web page:\\n\\n';\n sAlert += '<div id=\"' + idMachine + '\"></div>\\n';\n sAlert += '...\\n';\n sAlert += '<script type=\"text/javascript\" src=\"' + sScript + '\"></script>\\n';\n \n /*\n * I've updated embedMachine() in embed.js to use these defaults whenever the XML file is omitted, so if our\n * values match those defaults, we can omit both the XML and XSL file parameters and display a simplified call.\n */\n if (sXMLFile == \"machine.xml\" && sXSLFile == \"components.xsl\") {\n sXMLFile = sXSLFile = \"\";\n } else {\n sXMLFile = ',\"' + sXMLFile + '\"';\n sXSLFile = ',\"' + sXSLFile + '\"';\n }\n \n sAlert += '<script type=\"text/javascript\">embedPCx86(\"' + idMachine + '\"' + sXMLFile + sXSLFile + ');</script>\\n\\n';\n sAlert += 'The machine should appear where the <div> is located.';\n Component.alertUser(sAlert);\n return;\n }\n Component.alertUser(\"Missing XML/XSL resources\");\n}\n\n/**\n * Prevent the Closure Compiler from renaming functions we want to export, by adding them\n * as (named) properties of a global object.\n */\nwindow['savePC'] = savePC;\n"]} \ No newline at end of file +{"version":3,"file":"pcx86.js","lineCount":954,"mappings":"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","sources":["versions/pcx86/1.61.0/pcx86-uncompiled.js"," [synthetic:util/objectcreate] "," [synthetic:es6/util/setprototypeof] "," [synthetic:es6/util/inherits] "," [synthetic:util/defineproperty] "," [synthetic:util/global] "," [synthetic:es6/symbol] "," [synthetic:es6/util/arrayfromiterable] "," [synthetic:es6/util/makeiterator] "," [synthetic:es6/util/arrayfromiterator] "," [synthetic:util/polyfill] "," [synthetic:es6/math/trunc] "," [synthetic:es6/number/parseint] "," [synthetic:es6/math/sign] "],"names":["FDC.CMDS","$jscomp.objectCreate","$jscomp.setPrototypeOf","$jscomp.defineProperty","$jscomp.global","$jscomp.initSymbol","$jscomp.Symbol","$jscomp.SYMBOL_PREFIX","$jscomp.arrayIterator","$jscomp.initSymbolIterator","$jscomp.iteratorPrototype","$jscomp.polyfill","DiskAPI.GEOMETRIES","ASCII","BREAK","CTRL_A","CTRL_B","CTRL_C","CTRL_D","CTRL_E","CTRL_F","CTRL_G","CTRL_H","CTRL_I","CTRL_J","CTRL_K","CTRL_L","CTRL_M","CTRL_N","CTRL_O","CTRL_P","CTRL_Q","CTRL_R","CTRL_S","CTRL_T","CTRL_U","CTRL_V","CTRL_W","CTRL_X","CTRL_Y","CTRL_Z","ESC","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","DEL","Keys.NONASCII_KEYCODES","KEYCODE","Keys.ASCII","Keys.SHIFTED_KEYCODES","Str","parseInt","base","chPrefix","fCommas","indexOf","replace","ch","charAt","substr","chSuffix","slice","shift","match","isNaN","Math","pow","trunc","value","toBase","radix","cch","sPrefix","nGrouping","ceil","log","String","fromCharCode","toBin","abs","Str.toBase","toOct","fPrefix","toHex","toHexByte","Str.toHex","toHexWord","getBaseName","sFileName","fStripExt","sBaseName","lastIndexOf","substring","getExtension","sExtension","toLowerCase","endsWith","sSuffix","length","escapeHTML","sHTML","Str.HTMLEscapeMap","pad","fPadLeft","sPadding","sprintf","format","buffer","aParts","split","iArg","iPart","arg","args","flags","minimum","precision","conversion","ach","round","Str.HexUpperCase","Str.HexLowerCase","Number","trim","prototype","toASCIICode","Str.ASCII.CR","Str.ASCII.LF","Str.ASCIICodeMap","LF","CR","binarySearch","fnCompare","left","right","found","undefined","middle","compareResult","formatDate","sFormat","date","sDate","Date","iHour","getHours","iDay","getDate","iMonth","getMonth","Usr.asDays","getDay","Usr.asMonths","getMinutes","getSeconds","getFullYear","Array","Usr.aMonthDays","Usr.getTime","now","getResource","sURL","type","fAsync","done","progress","callback","request","readyState","resource","fArrayBuffer","response","responseText","err","status","window","location","protocol","nErrorCode","resources","XMLHttpRequest","ActiveXObject","fXHR2","responseType","onreadystatechange","sPost","hasOwnProperty","encodeURIComponent","open","setRequestHeader","send","overrideMimeType","getHost","host","SITEHOST","getUserAgent","navigator","userAgent","hasLocalStorage","Web.fLocalStorage","localStorage","setItem","Web.sLocalStorageTest","getItem","removeItem","getLocalStorageItem","sKey","sValue","setLocalStorageItem","isUserAgent","Web.getUserAgent","isMobile","sDevice","sMobile","Web.getURLParm","Web.isUserAgent","fInvert","findProperty","obj","sProp","Web.asBrowserPrefixes.length","sName","Web.asBrowserPrefixes","toUpperCase","getURLParm","sParm","Web.parmsURL","sParms","aParms","search","pl","exec","decodeURIComponent","downloadFile","sData","sType","fBase64","link","sURI","encodeURI","document","createElement","download","href","body","appendChild","click","removeChild","sAlert","onCountRepeat","fnRepeat","fnComplete","fnTimeout","doCountRepeat","setTimeout","onClickRepeat","fn","doClickRepeat","msRepeat","ms","timer","fIgnoreMouseEvents","onmousedown","e.onmousedown","msDelay","ontouchstart","e.ontouchstart","onmouseup","onmouseout","e.onmouseout","clearTimeout","ontouchend","ontouchcancel","e.ontouchcancel","onPageEvent","sFunc","fnPrev","onInit","Web.aPageEventHandlers","push","doPageEvent","afn","Web.fPageEventsEnabled","Component.alertUser","message","enablePageEvents","fEnable","Web.fPageLoaded","Web.sendPageEvent","Web.fPageShowed","sendPageEvent","sEvent","Web.doPageEvent","Web.onPageEvent","onPageLoad","onPageShow","onPageUnload","constructor","Component","parms","bitsMessage","id","name","comment","bindings","idComponent","idMachine","ready","busy","busyCancel","initDone","powered","unloading","error","fnReady","clearError","dbg","cpu","bus","cmp","Component.components.push","component","addMachineResource","data","Component.machines","alertUser","sMessage","alert","confirmUser","sPrompt","fResponse","confirm","appendControl","control","sText","scrollTop","scrollHeight","replaceControl","sSearch","sReplace","bindExternalControl","sBinding","target","Component.getComponentByType","setBinding","bindComponentControls","element","aeControls","Component.getElementsByClass","parentNode","iControl","aeChildNodes","childNodes","iNode","nodeType","sClass","getAttribute","aClasses","iClass","Component.getComponentParms","getComponents","idRelated","aComponents","Component.components.length","Component.components","getComponentByID","getComponentByType","componentPrev","getComponentParms","eval","getElementsByClass","sObjClass","getElementsByClassName","ae","aeAll","getElementsByTagName","re","RegExp","test","className","processScript","sScript","fSuccess","Component.commands","aCommands","aTokens","sToken","chQuote","Component.processCommands","processCommands","splice","sCommand","fnCallReady","Component.asyncCommands.indexOf","processNextCommand","fnCommand","Component.globalCommands","Component.componentCommands","exports","call","Component.prototype","?.prototype","toString","sHTMLType","onclick","clearControl","notice","this.notice","println","print","printControl","Component.appendControl","printlnControl","Component.PRINT.PROGRESS","Component.replaceControl","fPrintOnly","computer","console","setError","isError","isReady","setReady","fReady","isBusy","fCancel","setBusy","fBusy","powerUp","powerDown","fSave","fShutdown","messageEnabled","bitsEnabled","printf","Str.sprintf.apply","$jscomp.arrayFromIterable","printMessage","fAddress","printMessageIO","port","bOut","addrFrom","bIn","messageIO","PROGRESS","Component.asyncCommands","scriptAlert","scriptSleep","fnCallback","sDelay","scriptSelect","aBindings","options","textContent","selectedIndex","Array.prototype.indexOf","start","isArray","Array.isArray","Object","Function","bind","Function.prototype.bind","fnBound","fToBind","apply","fnNOP","concat","arguments","TypeError","TYPEDARRAYS","ArrayBuffer","CYCLES_8088","nWordCyclePenalty","nEACyclesBase","nEACyclesDisp","nEACyclesBaseIndex","nEACyclesBaseIndexExtra","nEACyclesBaseDisp","nEACyclesBaseIndexDisp","nEACyclesBaseIndexDispExtra","nOpCyclesAAA","nOpCyclesAAD","nOpCyclesAAM","nOpCyclesArithRR","nOpCyclesArithRM","nOpCyclesArithMR","nOpCyclesArithMID","nOpCyclesCall","nOpCyclesCallF","nOpCyclesCallWR","nOpCyclesCallWM","nOpCyclesCallDM","nOpCyclesCLI","nOpCyclesCompareRM","nOpCyclesCWD","nOpCyclesBound","nOpCyclesInP","nOpCyclesInDX","nOpCyclesIncR","nOpCyclesIncM","nOpCyclesInt","nOpCyclesInt3D","nOpCyclesIntOD","nOpCyclesIntOFall","nOpCyclesIRet","nOpCyclesJmp","nOpCyclesJmpF","nOpCyclesJmpC","nOpCyclesJmpCFall","nOpCyclesJmpWR","nOpCyclesJmpWM","nOpCyclesJmpDM","nOpCyclesLAHF","nOpCyclesLEA","nOpCyclesLS","nOpCyclesLoop","nOpCyclesLoopZ","nOpCyclesLoopNZ","nOpCyclesLoopFall","nOpCyclesLoopZFall","nOpCyclesMovRR","nOpCyclesMovRM","nOpCyclesMovMR","nOpCyclesMovRI","nOpCyclesMovMI","nOpCyclesMovAM","nOpCyclesMovMA","nOpCyclesDivBR","nOpCyclesDivWR","nOpCyclesDivBM","nOpCyclesDivWM","nOpCyclesIDivBR","nOpCyclesIDivWR","nOpCyclesIDivBM","nOpCyclesIDivWM","nOpCyclesMulBR","nOpCyclesMulWR","nOpCyclesMulBM","nOpCyclesMulWM","nOpCyclesIMulBR","nOpCyclesIMulWR","nOpCyclesIMulBM","nOpCyclesIMulWM","nOpCyclesNegR","nOpCyclesNegM","nOpCyclesOutP","nOpCyclesOutDX","nOpCyclesPopAll","nOpCyclesPopReg","nOpCyclesPopMem","nOpCyclesPushAll","nOpCyclesPushReg","nOpCyclesPushMem","nOpCyclesPushSeg","nOpCyclesPrefix","nOpCyclesCmpS","nOpCyclesCmpSr0","nOpCyclesCmpSrn","nOpCyclesLodS","nOpCyclesLodSr0","nOpCyclesLodSrn","nOpCyclesMovS","nOpCyclesMovSr0","nOpCyclesMovSrn","nOpCyclesScaS","nOpCyclesScaSr0","nOpCyclesScaSrn","nOpCyclesStoS","nOpCyclesStoSr0","nOpCyclesStoSrn","nOpCyclesRet","nOpCyclesRetn","nOpCyclesRetF","nOpCyclesRetFn","nOpCyclesShift1M","nOpCyclesShiftCR","nOpCyclesShiftCM","nOpCyclesShiftCS","nOpCyclesTestRR","nOpCyclesTestRM","nOpCyclesTestRI","nOpCyclesTestMI","nOpCyclesXchgRR","nOpCyclesXchgRM","nOpCyclesXLAT","CYCLES_80286","FUNCS","VIDEO","DISK","CASSETTE","DOS","WINDBG","Messages.CATEGORIES","CPU","SEG","DESC","PORT","TSS","IOPM","INT","NMI","FAULT","TRAP","BUS","IRQ","MEM","DMA","FDC","HDC","PIC","TIMER","CMOS","RTC","C8042","KBD","PARALLEL","SERIAL","MOUSE","SPEAKER","CHIPSET","COMPUTER","DATA","EVENT","KEY","WARN","HALT","BUFFER","Panel","parmsPanel","xMouse","yMouse","lockMouse","$jscomp.inherits","Panel.prototype","initBus","kbd","getMachineComponent","fRepower","Panel.init","clickMouse","event","fDown","button","updateMouse","moveMouse","xScale","Panel.LIVECANVAS.CX","canvas","offsetWidth","yScale","Panel.LIVECANVAS.CY","offsetHeight","rect","getBoundingClientRect","clientX","clientY","top","Panel.LIVEMEM.CX","findAddress","busInfo","aRects","contains","region","aRegions","bf","Bus.BlockInfo.num","num","aBlocks","iBlock","mask","addr","nBlockSize","addrLimit","cBlocks","cx","ratioMemoryToPixels","ADDR_INVALID","addrDumpLast","dumpMemory","context","canvasLiveRegs","contextLiveRegs","Panel.LIVEREGS.CY","Panel.LIVEDUMP.CY","width","fillStyle","Panel.LIVEREGS.COLOR","fillRect","Panel.LIVECANVAS.FONT.CY","sColor","style","color","sFontFace","xLeftMargin","xLeft","xText","yText","yTop","heightText","heightDefault","fontDefault","Panel.LIVECANVAS.FONT.FACE","fontText","canvasText","contextText","colorText","cxColumn","nCols","drawText","iLine","sChars","iCol","aMemBlocks","nBusMask","nBlockShift","readByteDirect","nBlockLimit","drawImage","xDump","yDump","cxDump","cyDump","nValue","nColsSkip","nLinesSkip","font","fillText","nDefaultBase","nDefaultDigits","skipCols","skipLines","init","aePanels","APPCLASS","iPanel","ePanel","panel","Component.getComponentByID","Component.bindComponentControls","CX","CY","FONT","FACE","COLOR","Web.onInit","Controller","getMemoryAccess","getMemoryBuffer","Bus","parmsBus","nBusWidth","addrTotal","nBusLimit","nBlockLen","nBlockTotal","nBlockMask","aPortInputNotify","aPortOutputNotify","fPortInputBreakAll","fPortOutputBreakAll","aPortInputWidth","aPortOutputWidth","block","Memory","copyBreakpoints","initMemory","aBusBlocks","nMemMask","reset","setA20","addMemory","size","controller","addrNext","sizeLeft","addrBlock","sizeBlock","used","sizeAvail","reportError","Bus.ERROR.ADD_MEM_INUSE","blockNew","flushPageBlocks","running","kb","sb","Memory.TYPE.NAMES","Bus.ERROR.ADD_MEM_BADRANGE","cleanMemory","fNoScrub","fClean","fDirty","fDirtyEver","aBlocks2Mb","setMemoryBlocks","getMemoryBlocks","addrMask","setMemoryAccess","fQuiet","Bus.ERROR.SET_MEM_BADRANGE","Bus.ERROR.SET_MEM_NOCTRL","setAccess","removeMemory","blockOld","Bus.ERROR.REM_MEM_BADRANGE","mem","fReadOnly","Memory.TYPE.ROM","dv","ab","aw","adw","littleEndian","Memory.afnArrayLE","Memory.afnArrayBE","Memory.afnMemory","getByte","readByte","getShortDirect","off","readShortDirect","setByte","writeByte","setByteDirect","writeByteDirect","setShortDirect","writeShortDirect","saveMemory","fAll","fA20","getA20","save","iSrc","iComp","aComp","aSrc","iCompare","addPortInputBreak","addPortInputTable","table","offset","addPortInputNotify","end","Str.toHexWord","checkPortInputNotify","addrLIP","aNotify","sizePort","maskPort","dataPort","checkPortInput","addPortOutputBreak","addPortOutputTable","addPortOutputNotify","checkPortOutputNotify","checkPortOutput","op","sError","Bus.BlockInfo","count","btmod","bit","bfs","ADD_MEM_INUSE","ADD_MEM_BADRANGE","SET_MEM_NOCTRL","SET_MEM_BADRANGE","REM_MEM_BADRANGE","setUint16","DataView","Uint16Array","Memory.idBlock","Memory.TYPE.NONE","Uint8Array","Int32Array","Memory.prototype","getInt32","restore","setInt32","fDirect","Memory.TYPE.UNPAGED","Memory.afnUnpaged","Memory.TYPE.PAGED","Memory.afnPaged","Memory.afnNone","setReadAccess","setWriteAccess","cReadBreakpoints","readNone","readShort","readShortDefault","readLong","readLongDefault","readLongDirect","cWriteBreakpoints","writeNone","writeShort","writeShortDefault","writeLong","writeLongDefault","writeLongDirect","addBreakpoint","fWrite","Memory.afnChecked","removeBreakpoint","resetWriteAccess","resetReadAccess","readByteMemory","readShortMemory","idw","nShift","dw","readLongMemory","writeByteMemory","writeShortMemory","writeLongMemory","readByteChecked","checkMemoryRead","checkMemoryException","readShortChecked","readLongChecked","writeByteChecked","checkMemoryWrite","writeShortChecked","writeLongChecked","readBytePaged","blockPDE","iPDE","bitPTEAccessed","blockPTE","iPTE","blockPhys","readShortPaged","readLongPaged","writeBytePaged","bitPTEDirty","writeShortPaged","writeLongPaged","readByteUnpaged","mapPageBlock","getPageBlock","readShortUnpaged","readLongUnpaged","writeByteUnpaged","writeShortUnpaged","writeLongUnpaged","readByteBE","readByteLE","readBytePLE","PTE","readShortBE","getUint16","readShortLE","readShortPLE","readLongBE","readLongLE","readLongPLE","writeByteBE","writeByteLE","writeBytePLE","writeShortBE","writeShortLE","writeShortPLE","writeLongBE","writeLongLE","writeLongPLE","adjustEndian","NONE","ROM","UNPAGED","PAGED","NAMES","Memory.afnPagedLE","parmsCPU","nCyclesDefault","nCycles","nMultiplier","counts","nBaseCyclesPerSecond","msPerYield","CPU.YIELDS_PER_SECOND","nBaseMultiplier","nCurrentMultiplier","nTargetMultiplier","mhzBase","mhzCurrent","mhzTarget","starting","yield","autoStart","displayLiveRegs","checksum","nChecksum","nCyclesChecksumNext","nCyclesChecksumStart","nCyclesChecksumInterval","nCyclesChecksumStop","aTimers","idRunTimeout","onRunTimeout","runCPU","CPU.prototype","CPU.BUTTONS.length","CPU.BUTTONS","fpu","chipset","sAutoStart","getMachineParm","addTimer","yieldTimer","resetCycles","resetChecksum","updateCPU","fRunning","stopCPU","startCPU","getChecksum","nTotalCycles","updateChecksum","fDisplay","getCycles","displayChecksum","fBound","control.onclick","powerOn","Computer.RESUME_REPOWER","iComponent","Component.getComponents","setSpeed","getSpeedTarget","toFixed","setBurstCycles","nDelta","nStepCycles","nBurstCycles","addCycles","fEndStep","calcCycles","nCyclesPerYield","floor","fScaled","nRunCycles","fUpdateFocus","sSpeed","controlSpeed","updateFocus","msStartRun","msEndThisRun","iTimer","resetTimers","setTimer","callBack","fReset","getMSCycles","endBurst","saveTimers","aTimerStates","nCyclesThisRun","calcStartTime","msDiscount","msStartThisRun","msDelta","getCurrentCyclesPerSecond","getBurstCycles","updateAllTimers","fCounting","ticksElapsed","nCyclesUpdate","fScaleTimers","nCyclesStart","nTicksDivisor","getTimerStart","countStart","mode","ChipSet.PIT_CTRL.MODE3","nCyclesRemain","abCMOSData","ChipSet.CMOS.ADDR.STATUSB","ChipSet.CMOS.STATUSB.PIE","nRTCCyclesNextUpdate","stepCPU","exception","updateTimers","stop","stack","calcRemainingTime","msYield","msRemainsThisRun","msElapsed","controlRun","updateStatus","CPU_prototype$stepCPU","fComplete","fStopped","complete","nonCPU","msStart","msStop","fForce","CPUX86","model","MODEL_8088","MODEL_80286","MODEL_80386","stepping","Str.parseInt","initProcessor","PS_SET","X86.PS_SET_8086","PS_DIRECT","X86.PS_DIRECT_8086","PS_CLEAR_RM","OPFLAG_NOINTR_8086","OPFLAG","nShiftCountMask","cycleCounts","X86.CYCLES_80286","X86.CYCLES_8088","aOps","X86.aOps","aOpGrp4b","X86.aOpGrp4b","aOpGrp4w","X86.aOpGrp4w","aOpGrp6","X86.aOpGrp6Real","MODEL_80186","X86.aOps.slice","X86.aOpGrp4b.slice","X86.aOpGrp4w.slice","X86.opInvalid","OPCODE","X86.opPUSHA","X86.opPOPA","X86.opBOUND","X86.opPUSHn","X86.opIMULn","X86.opPUSH8","X86.opIMUL8","X86.opINSb","X86.opINSw","X86.opOUTSb","X86.opOUTSw","X86.opGRP2bn","X86.opGRP2wn","X86.opENTER","X86.opLEAVE","X86.opINT1","X86.fnGRPInvalid","PS","X86.op0F","aOps0F","X86.aOps0F.slice","X86.opUndefined","X86.opPUSHSP","X86.opARPL","bOpcode","X86.opFS","X86.opGS","X86.opOS","X86.opAS","X86.aOps0F386","STEPPING_80386_A0","STEPPING_80386_B0","X86.opXBTS","X86.opIBTS","aIntNotify","aIntReturn","cIntReturn","debugCheck","cLiveRegs","resetRegs","removeMemBreak","fPhysical","enablePageBlocks","blockUnpaged","memEmpty","aCacheBlocks","CPUX86.PAGEBLOCKS_CACHE","iCacheBlocks","aBlocksPaged","releasePageBlock","regCR0","CR0","fSuppress","offPDE","LADDR","regCR3","pde","X86.helpPageFault.call","nCPL","offPTE","pte","acquirePageBlock","blockPage","Memory.adjustEndian","disablePageBlocks","CPUX86.prototype","getReg","reg","regEAX","regECX","regEDX","regEBX","getSP","regEBP","regESI","regEDI","setReg","setSP","regESP","fMDSet","regMDLo","regMDHi","r64Div","r64Rem","regXX","bModRM","addrIDT","addrIDTLimit","regPS","nIOPL","resultDst","resultSrc","resultArith","resultLogic","nFault","opCS","opSS","opLIP","opLSP","segCS","SegX86","SegX86.ID.CODE","segDS","SegX86.ID.DATA","segES","segSS","SegX86.ID.STACK","setSS","STEPPING_80386_B1","STEPPING_80386_C0","STEPPING_80386_D0","STEPPING_80386_D1","STEPPING_80386_D2","regCR1","regCR2","regDR","regTR","segFS","segGS","segNULL","SegX86.ID.NULL","segData","segStack","opFlags","opPrefixes","regEA","regEAWrite","segEA","intFlags","INTFLAG","setCSIP","addrGDT","addrGDTLimit","segLDT","SegX86.ID.LDT","segTSS","SegX86.ID.TSS","segVER","SegX86.ID.VER","regIP","getIP","setCSBase","regLIP","regLIPMax","limit","setPS","setProtMode","updateAddrSize","sizeAddr","getAddr","getShort","decodeModRegByte","X86.modRegByte16","decodeModMemByte","X86.modMemByte16","decodeModGrpByte","X86.modGrpByte16","sizeData","decodeModRegWord","X86.modRegShort16","decodeModMemWord","X86.modMemShort16","decodeModGrpWord","X86.modGrpShort16","X86.modRegLong16","X86.modMemLong16","X86.modGrpLong16","getLong","X86.modRegByte32","X86.modMemByte32","X86.modGrpByte32","X86.modRegShort32","X86.modMemShort32","X86.modGrpShort32","X86.modRegLong32","X86.modMemLong32","X86.modGrpLong32","setDataSize","maskData","updateDataSize","typeData","RESULT","getWord","setWord","setShort","setLong","resetSizes","maskAddr","sum","getCS","sel","getDS","getSS","getES","getPS","addIntNotify","nInt","addIntReturn","checkIntReturn","checkDebugRegisters","regDR7","bitsDR7","addMemCheck","removeMemCheck","nb","DR7","bitsRWRequired","bitsRWMask","len","fProt","fV86","isProtMode","isV86Mode","X86.aOpGrp6Prot","updateMode","state","State","set","saveProtMode","getSpeed","fPaging","isPagingEnabled","restoreProtMode","fRestored","iDst","aDst","getSeg","iTimerState","restoreTimers","setCS","setDS","load","fInterruptable","regLSP","fExpDown","regLSPLimit","regLSPLimitLow","min","setES","setIP","setLIP","cpl","fCall","offIP","fStackSwitch","checkIP","inc","newLIP","X86.helpFault.call","EXCEPTION","resetIP","setArithResult","dst","src","fSubtract","resultType","diff","getCF","getPF","getAF","getZF","getSF","getOF","setLogicResult","carry","overflow","setCF","clearCF","setOF","clearOF","setRotateResult","result","getCarry","clearAF","clearZF","setAF","setZF","setMSW","X86.PS_CACHED","checkIOPM","nPorts","fInput","bitsPorts","addrIOPM","addrIOPMLimit","bits","probeAddr","CPUX86_prototype$getShort","CPUX86_prototype$getLong","cb","cbBlock","CPUX86_prototype$setShort","CPUX86_prototype$setLong","getEAByte","seg","offEA","checkRead","getEAByteData","getEAByteStack","getEAWord","getEAShortData","getEAShortStack","getEALongData","getEALongStack","setEAByte","checkWrite","setEAShort","setEALong","getSOWord","setSOWord","getIPByte","getIPShort","getIPAddr","getIPWord","getIPDisp","popWord","delta","pushWord","pushData","updateReg","sReg","displayValue","sLabel","sVal","nMinCycles","fDebugCheck","checksEnabled","nDebugState","X86.OPFLAG_PREFIXES","checkINTR","iPriority","cPriorities","nIDT","getIRRVector","X86.helpInterrupt.call","DR6","X86.opHLT.call","checkInstruction","aeCPUs","iCPU","eCPU","FPUX86","parmsFPU","FPU","regStack","Float64Array","intStack","regTmpSR","Float32Array","intTmpSR","regTmpLR","intTmpLR","intTmpTR","regCodeSel","regDataSel","regCodeOff","regDataOff","regOpcode","iStack","regIndefinite","intIndefinite","resetFPU","setEAFromSR","setEAFromSI","setEAFromLR","setEAFromLI","FPUX86.prototype","regControl","getStatus","getTags","iReg","setControl","setStatus","regStatus","iST","checkException","setTags","regUsed","ChipSet.MODEL_5170","clearIRR","ChipSet.IRQ.FPU","setIRR","bNMI","ChipSet.NMI.ENABLE","setException","isAtLeastModel","checkResult","isFinite","Infinity","doAdd","operand1","operand2","doSubtract","doMultiply","doDivide","dividend","divisor","quotient","doCompare","cc","roundValue","operand","max","rc","FPUX86.MAX_INT32","getTag","tag","tags","bitUsed","getSR","getLR","getST","setST","checkOperand","getTR","fSafe","iInt","getTRFromLR","getWIFromEA","getSIFromEA","getSRFromEA","getLRFromEA","getTRFromEA","setEAFromTR","getLRFromTR","hiTR","signLR","expLR","loLR","loTR","hiLR","expTR","decodeBCD","encodeBCD","popValue","pushValue","NaN","loadEnv","saveEnv","FPUX86.FCLEX","clearStatus","FPUX86.FCOMst","FPUX86.FCOMPst","FPUX86.FCOMP8087","FPUX86.FCOMPst.call","FPUX86.FDIVsr","FPUX86.FFREEsti","setTag","FPUX86.FINIT","FPUX86.FLDCW","FPUX86.FLDENV","FPUX86.FRSTOR","setTR","FPUX86.FSAVE","FPUX86.FSTENV","FPUX86.FSTPsti","FPUX86.FSTP8087","FPUX86.FSTPsti.call","FPUX86.FSTCW","FPUX86.FSTSW","FPUX86.FSTSWAX287","FPUX86.FXCHsti","tmp","FPUX86.FXCH8087","FPUX86.FXCHsti.call","FPUX86.regL2T","LN2","FPUX86.regL2E","LOG2E","FPUX86.regPI","PI","FPUX86.regLG2","LN10","FPUX86.regLN2","FPUX86.MAX_INT64","FPUX86.aaOps","FPUX86.FADDsr","FPUX86.FMULsr","FPUX86.FCOMsr","FPUX86.FCOMPsr","FPUX86.FSUBsr","FPUX86.FSUBRsr","FPUX86.FADDst","FPUX86.FMULst","FPUX86.FSUBst","FPUX86.FSUBRst","FPUX86.FDIVst","FPUX86.FDIVRst","FPUX86.FLDsr","FPUX86.FSTsr","FPUX86.FSTPsr","FPUX86.FLDsti","FPUX86.FNOP","FPUX86.FCHS","FPUX86.FABS","FPUX86.FTST","FPUX86.FXAM","getSTSign","FPUX86.FLD1","FPUX86.FLDL2T","FPUX86.FLDL2E","FPUX86.FLDPI","FPUX86.FLDLG2","FPUX86.FLDLN2","FPUX86.FLDZ","FPUX86.F2XM1","FPUX86.FYL2X","FPUX86.FPTAN","tan","FPUX86.FPATAN","atan2","FPUX86.FXTRACT","FPUX86.FDECSTP","FPUX86.FINCSTP","FPUX86.FPREM","FPUX86.FYL2XP1","FPUX86.FSQRT","doSquareRoot","sqrt","FPUX86.FRNDINT","FPUX86.FSCALE","FPUX86.FIADD32","FPUX86.FIMUL32","FPUX86.FICOM32","FPUX86.FICOMP32","FPUX86.FISUB32","FPUX86.FISUBR32","FPUX86.FIDIV32","FPUX86.FIDIVR32","FPUX86.FILD32","FPUX86.FIST32","getSI","FPUX86.FISTP32","FPUX86.FLDtr","FPUX86.FSTPtr","FPUX86.FENI8087","isModel","FPUX86.FDISI8087","FPUX86.FSETPM287","FPUX86.FSINCOS387","FPUX86.FADDlr","FPUX86.FMULlr","FPUX86.FCOMlr","FPUX86.FCOMPlr","FPUX86.FSUBlr","FPUX86.FSUBRlr","FPUX86.FDIVlr","FPUX86.FDIVRlr","FPUX86.FADDsti","FPUX86.FMULsti","FPUX86.FCOM8087","FPUX86.FCOMst.call","FPUX86.FSUBRsti","FPUX86.FSUBsti","FPUX86.FDIVRsti","FPUX86.FDIVsti","FPUX86.FLDlr","FPUX86.FSTlr","FPUX86.FSTPlr","FPUX86.FSTsti","FPUX86.FIADD16","FPUX86.FIMUL16","FPUX86.FICOM16","FPUX86.FICOMP16","FPUX86.FISUB16","FPUX86.FISUBR16","FPUX86.FIDIV16","FPUX86.FIDIVR16","FPUX86.FADDPsti","FPUX86.FMULPsti","FPUX86.FCOMPP","FPUX86.FSUBRPsti","FPUX86.FSUBPsti","FPUX86.FDIVRPsti","FPUX86.FDIVPsti","FPUX86.FILD16","FPUX86.FIST16","getWI","FPUX86.MAX_INT16","setEAFromWI","FPUX86.FISTP16","FPUX86.FBLDpd","FPUX86.FILD64","lo","getLIFromEA","hi","FPUX86.FBSTPpd","FPUX86.FISTP64","getLI","FPUX86.FFREEP8087","FPUX86.FFREEsti.call","FPUX86.afnPreserveExceptions","aeFPUs","iFPU","eFPU","offMax","dpl","ext","acc","addrDesc","loadV86","loadReal","checkWriteV86","checkReadV86","checkReadWriteReal","probe","awParms","aCallBreaks","checkReadWriteNone","addCallBreak","SegX86.CALLBREAK_SEL","SegX86.prototype","loadProt","fProbe","SEL","addrDT","addrDTLimit","loadDesc8","ERRCODE","loadIDTReal","loadIDTProt","checkReadProt","checkReadProtDisallowed","checkReadProtDown","checkWriteProt","checkWriteProtDisallowed","checkWriteProtDown","loadDesc","loadDesc6","selMasked","limitOrig","fnCallBreak","rpl","sizeGate","regSP","switchTSS","regPSClear","cplOld","fIDT","selCode","offStack","selStack","cplNew","addrTSS","offSP","TSS386","lenSP","TSS286","nWords","regSSPrev","regSPPrev","typeTSS","selNew","fNest","selOld","addrOld","addrNew","offSS","fLoad","loadIDT","addrType","bType","NULL","CODE","STACK","LDT","VER","X86.fnADCb","X86.fnADCw","X86.fnADDb","X86.fnADDw","X86.fnANDb","X86.fnANDw","X86.fnARPL","X86.fnBOUND","wIndex","wLower","wUpper","X86.fnBSF","X86.fnBSR","X86.fnBT","X86.fnBTC","X86.fnBTR","X86.fnBTS","X86.fnBTMem","X86.fnBT.call","X86.fnBTCMem","X86.fnBTC.call","X86.fnBTRMem","X86.fnBTR.call","X86.fnBTSMem","X86.fnBTS.call","X86.fnCMPb","X86.fnCMPw","X86.fnESC","modReg","fnOp","FPUX86.afnPreserveExceptions.indexOf","X86.fnGRPFault","X86.fnGRPUndefined.call","X86.fnGRPUndefined","X86.opUndefined.call","X86.fnIMUL8","X86.fnIMULrw.call","X86.fnIMULn","X86.fnIMULrd.call","X86.fnIMUL32","fNeg","X86.fnMUL32.call","X86.fnIMULrw","X86.fnIMULrd","X86.fnIMUL32.call","X86.fnLAR","X86.fnLDS","X86.fnLEA","X86.fnLES","X86.fnLFS","setFS","X86.fnLGS","setGS","X86.fnLSL","X86.fnLSS","X86.fnMOV","X86.fnMOVXb","X86.fnMOVXw","X86.fnMOVsrw","X86.fnMOV.call","X86.fnMOVwsr","X86.fnMUL32","srcLo","srcHi","dstLo","dstHi","mul00","mul16","mul32","X86.fnORb","X86.fnORw","X86.fnSBBb","X86.fnSBBw","X86.fnSETO","X86.fnSETC","X86.fnSETNC","X86.fnSETZ","X86.fnSETNZ","X86.fnSETBE","X86.fnSETNBE","X86.fnSETS","X86.fnSETNS","X86.fnSETP","X86.fnSETNP","X86.fnSETL","X86.fnSETNL","X86.fnSETLE","X86.fnSETNLE","X86.fnSHLDwi","X86.helpSHLDw.call","X86.fnSHLDdi","X86.helpSHLDd.call","X86.fnSHLDwCL","X86.fnSHLDdCL","X86.fnSHRDwi","X86.helpSHRDw.call","X86.fnSHRDdi","X86.helpSHRDd.call","X86.fnSHRDwCL","X86.fnSHRDdCL","X86.fnSUBb","X86.fnSUBw","X86.fnTESTb","X86.fnTESTw","X86.fnIBTS","X86.fnXBTS","X86.fnXCHGrb","X86.fnXCHGrw","setEAWord","X86.fnXORb","X86.fnXORw","X86.helpCmp64","r64Dst","r64Src","X86.helpDECreg","X86.helpDIV32","X86.helpINCreg","X86.helpLoadCR0","X86.helpSETcc","fnSet","X86.helpSHLDw","X86.helpSHLDd","X86.helpSHRDw","X86.helpSHRDd","X86.helpSRC1","X86.helpSRCCL","X86.helpSRCByte","X86.helpSRCNone","X86.helpSRCxx","X86.helpCALLF","oldIP","oldSize","X86.helpINT","nError","oldPS","oldCS","X86.helpRETF","newIP","newCS","X86.zeroSeg.call","X86.helpDIVOverflow","MODEL_8086","X86.helpINT.call","X86.helpInterrupt","X86.helpFault","fHalt","fDispatch","Str.toHexByte","X86.helpPageFault","fPresent","X86.zeroSeg","afnGrp","fnSrc","X86.modSIB.call","X86.modSIB","mod","bSIB","scale","index","temp","nReps","setSOByte","getSOByte","X86.opJO","disp","X86.opJNO","X86.opJC","X86.opJNC","X86.opJZ","X86.opJNZ","X86.opJBE","X86.opJNBE","X86.opJS","X86.opJNS","X86.opJP","X86.opJNP","X86.opJL","X86.opJNL","X86.opJLE","X86.opJNLE","X86.opGRP1b","X86.aOpGrp1b","X86.opMOVmb","X86.opMOVmw","X86.opMOVrb","X86.opMOVrw","X86.aOpGrp2b","X86.aOpGrp2w","X86.aOpGrp2d","X86.opRETn","X86.opRET","wLocal","bLevel","wFrame","X86.opRETFn","X86.helpRETF.call","X86.opRETF","X86.opESC","X86.opLOCK","X86.opHLT","getIF","X86.opADDmb","X86.opADDmw","X86.opADDrb","X86.opADDrw","X86.opADDALb","X86.fnADDb.call","X86.opADDAX","X86.fnADDw.call","X86.opPUSHES","X86.opPOPES","X86.opORmb","X86.opORmw","X86.opORrb","X86.opORrw","X86.opORALb","X86.fnORb.call","X86.opORAX","X86.fnORw.call","X86.opPUSHCS","X86.opPOPCS","X86.opADCmb","X86.opADCmw","X86.opADCrb","X86.opADCrw","X86.opADCALb","X86.fnADCb.call","X86.opADCAX","X86.fnADCw.call","X86.opPUSHSS","X86.opPOPSS","X86.opSBBmb","X86.opSBBmw","X86.opSBBrb","X86.opSBBrw","X86.opSBBALb","X86.fnSBBb.call","X86.opSBBAX","X86.fnSBBw.call","X86.opPUSHDS","X86.opPOPDS","X86.opANDmb","X86.opANDmw","X86.opANDrb","X86.opANDrw","X86.opANDAL","X86.fnANDb.call","X86.opANDAX","X86.fnANDw.call","X86.opES","X86.opDAA","AL","AF","CF","X86.opSUBmb","X86.opSUBmw","X86.opSUBrb","X86.opSUBrw","X86.opSUBALb","X86.fnSUBb.call","X86.opSUBAX","X86.fnSUBw.call","X86.opCS","X86.opDAS","X86.opXORmb","X86.opXORmw","X86.opXORrb","X86.opXORrw","X86.opXORALb","X86.fnXORb.call","X86.opXORAX","X86.fnXORw.call","X86.opSS","X86.opAAA","AH","X86.opCMPmb","X86.opCMPmw","X86.opCMPrb","X86.opCMPrw","X86.opCMPALb","X86.fnCMPb.call","X86.opCMPAX","X86.fnCMPw.call","X86.opDS","X86.opAAS","X86.opINCAX","X86.helpINCreg.call","X86.opINCCX","X86.opINCDX","X86.opINCBX","X86.opINCSP","X86.opINCBP","X86.opINCSI","X86.opINCDI","X86.opDECAX","X86.helpDECreg.call","X86.opDECCX","X86.opDECDX","X86.opDECBX","X86.opDECSP","X86.opDECBP","X86.opDECSI","X86.opDECDI","X86.opPUSHAX","X86.opPUSHCX","X86.opPUSHDX","X86.opPUSHBX","X86.opPUSHSP_8086","X86.opPUSHBP","X86.opPUSHSI","X86.opPUSHDI","X86.opPOPAX","X86.opPOPCX","X86.opPOPDX","X86.opPOPBX","X86.opPOPSP","X86.opPOPBP","X86.opPOPSI","X86.opPOPDI","X86.opGRP1w","X86.aOpGrp1w","X86.opGRP1sw","X86.opTESTrb","X86.opTESTrw","X86.opXCHGrb","X86.opXCHGrw","X86.opMOVwsr","X86.opLEA","X86.opMOVsrw","X86.opPOPmw","X86.aOpGrpPOPw","X86.opNOP","X86.opXCHGCX","X86.opXCHGDX","X86.opXCHGBX","X86.opXCHGSP","X86.opXCHGBP","X86.opXCHGSI","X86.opXCHGDI","X86.opCBW","X86.opCWD","X86.opCALLF","X86.helpCALLF.call","X86.opWAIT","X86.opPUSHF","X86.opPOPF","newPS","X86.opSAHF","ah","setPF","clearPF","setSF","clearSF","X86.opLAHF","X86.PS_SAHF","X86.opMOVALm","X86.opMOVAXm","X86.opMOVmAL","X86.opMOVmAX","X86.opMOVSb","nInc","X86.opMOVSw","X86.opCMPSb","bDst","bSrc","X86.opCMPSw","wDst","wSrc","X86.opTESTALb","X86.opTESTAX","X86.opSTOSb","STEPPING_80386_B2","X86.opSTOSw","X86.opLODSb","X86.opLODSw","X86.opSCASb","X86.opSCASw","X86.opMOVALb","X86.opMOVCLb","X86.opMOVDLb","X86.opMOVBLb","X86.opMOVAHb","X86.opMOVCHb","X86.opMOVDHb","X86.opMOVBHb","X86.opMOVAX","X86.opMOVCX","X86.opMOVDX","X86.opMOVBX","X86.opMOVSP","X86.opMOVBP","X86.opMOVSI","X86.opMOVDI","X86.opLES","X86.opLDS","X86.opMOVb","X86.aOpGrpMOVn","X86.opMOVw","X86.opINT3","X86.opINTn","checkIntNotify","messageInt","X86.opINTO","X86.opIRET","newSP","newSS","newES","newDS","newFS","newGS","X86.opGRP2b1","X86.opGRP2w1","X86.opGRP2bCL","X86.opGRP2wCL","X86.opAAM","X86.helpDIVOverflow.call","X86.opAAD","X86.opSALC","X86.opXLAT","X86.opESC0","X86.opESC.call","X86.opESC1","X86.opESC2","X86.opESC3","X86.opESC4","X86.opESC5","X86.opESC6","X86.opESC7","X86.opLOOPNZ","X86.opLOOPZ","X86.opLOOP","X86.opJCXZ","X86.opINb","X86.opINw","X86.opOUTb","X86.opOUTw","X86.opCALL","X86.opJMP","X86.opJMPF","X86.opJMPs","X86.opINDXb","X86.opINDXw","X86.opOUTDXb","X86.opOUTDXw","X86.opREPNZ","X86.opREPZ","X86.opCMC","X86.opGRP3b","X86.aOpGrp3b","X86.opGRP3w","X86.aOpGrp3w","X86.opCLC","X86.opSTC","X86.opCLI","clearIF","X86.opSTI","setIF","X86.opCLD","clearDF","X86.opSTD","setDF","X86.opGRP4b","X86.opGRP4w","X86.fnPOPw","X86.fnMOVn","X86.fnROLb","X86.fnRORb","X86.fnRCLb","X86.fnRCRb","X86.fnSHLb","X86.fnSHRb","X86.fnSARb","X86.fnROLw","X86.fnRORw","X86.fnRCLw","X86.fnRCRw","X86.fnSHLw","X86.fnSHRw","X86.fnSARw","X86.fnROLd","X86.fnRORd","X86.fnRCLd","X86.fnRCRd","X86.fnSHLd","X86.fnSHRd","X86.fnSARd","X86.fnTESTib","X86.fnNOTb","X86.fnNEGb","X86.fnMULb","X86.fnIMULb","X86.fnDIVb","X86.fnIDIVb","div","X86.fnTESTiw","X86.fnNOTw","X86.fnNEGw","X86.fnMULw","X86.fnIMULw","fOverflow","X86.fnDIVw","X86.helpDIV32.call","X86.fnIDIVw","bNegLo","bNegHi","X86.fnINCb","X86.fnDECb","X86.fnINCw","X86.fnDECw","X86.fnCALLw","X86.fnCALLFdw","X86.fnJMPw","X86.fnJMPFdw","X86.fnPUSHw","X86.aOps0F","X86.opGRP6","peekIPByte","X86.opGRP7","X86.aOpGrp7","X86.opLAR","X86.opLSL","X86.opLOADALL286","X86.opCLTS","X86.opLOADALL386","X86.helpLoadCR0.call","accSS","X86.opMOVrc","X86.opMOVrd","X86.opMOVcr","X86.opMOVdr","X86.opMOVrt","X86.opMOVtr","X86.opJOw","X86.opJNOw","X86.opJCw","X86.opJNCw","X86.opJZw","X86.opJNZw","X86.opJBEw","X86.opJNBEw","X86.opJSw","X86.opJNSw","X86.opJPw","X86.opJNPw","X86.opJLw","X86.opJNLw","X86.opJLEw","X86.opJNLEw","X86.opSETO","X86.helpSETcc.call","X86.opSETNO","X86.opSETC","X86.opSETNC","X86.opSETZ","X86.opSETNZ","X86.opSETBE","X86.opSETNBE","X86.opSETS","X86.opSETNS","X86.opSETP","X86.opSETNP","X86.opSETL","X86.opSETNL","X86.opSETLE","X86.opSETNLE","X86.opPUSHFS","X86.opPOPFS","X86.opBT","X86.opSHLDn","X86.opSHLDcl","X86.opPUSHGS","X86.opPOPGS","X86.opBTS","X86.opSHRDn","X86.opSHRDcl","X86.opIMUL","X86.opLSS","X86.opBTR","X86.opLFS","X86.opLGS","X86.opMOVZXb","X86.opMOVZXw","X86.opGRP8","X86.aOpGrp8","X86.opBTC","X86.opBSF","X86.opBSR","X86.opMOVSXb","X86.opMOVSXw","X86.fnSLDT","X86.fnSTR","X86.fnLLDT","X86.fnLTR","X86.fnVERR","X86.fnVERW","X86.fnSGDT","X86.fnSIDT","X86.fnLGDT","X86.fnLIDT","X86.fnSMSW","X86.fnLMSW","ChipSet","parmsChipSet","ChipSet.MODELS","ChipSet.MODEL_5150_OTHER","aDIPSwitches","bSwitches","parseDIPSwitches","ChipSet.CONTROLS.SW1","aFloppyDrives","setDIPSwitches","ChipSet.SWITCH_TYPE.FLOPNUM","ChipSet.SWITCH_TYPE.MONITOR","ChipSet.CONTROLS.SW2","cDMACs","cPICs","sDateRTC","volumeInit","sound","classAudio","contextAudio","fSpeakerEnabled","fSpeakerOn","fUserSound","ChipSet.prototype","ChipSet.SWITCH_TYPE.FPU","volume","ChipSet.TIMER_TICKS_PER_SEC","ChipSet.aPortInput","ChipSet.aPortOutput","ChipSet.MODEL_4860","ChipSet.aPortInput4860","ChipSet.aPortOutput4860","ChipSet.aPortInput5xxx","ChipSet.aPortOutput5xxx","ChipSet.MODEL_ATT_6300","ChipSet.aPortInput6300","ChipSet.aPortOutput6300","ChipSet.aPortInput5150","ChipSet.aPortOutput5150","ChipSet.aPortInput5170","ChipSet.aPortOutput5170","ChipSet.MODEL_COMPAQ_DESKPRO386","ChipSet.aPortInputDeskPro386","ChipSet.aPortOutputDeskPro386","messageDump","onDumpPIC","iPIC","aPICs","pic","sDump","aICW","bIMR","bIRR","bISR","nDelay","onDumpTimer","asArgs","nTimer","updateTimer","countBytes","countCurrent","onDumpCMOS","iCMOS","ChipSet.CMOS.ADDR.TOTAL","ChipSet.CMOS.ADDR.STATUSD","getRTCByte","intBIOSRTC","addDIPSwitches","ChipSet.MODEL_5150","ChipSet.CONTROLS.SWDESC","fHard","updateDIPSwitches","aDMACs","initDMAController","initPIC","ChipSet.PIC0.INDEX","ChipSet.PIC0.PORT_LO","ChipSet.PIC1.INDEX","ChipSet.PIC1.PORT_LO","bPIT1Ctrl","bPIT0Ctrl","initTimer","bPPICtrl","bPPIC","bPPIB","bPPIA","ChipSet.NMI.RESET","bKbdData","b8041Status","b8042Status","ChipSet.C8042.STATUS.NO_INHIBIT","b8042InBuff","b8042CmdData","ChipSet.C8042.DATA.CMD.NO_CLOCK","b8042OutBuff","b8042InPort","ChipSet.C8042.INPORT.MFG_OFF","ChipSet.C8042.INPORT.KBD_UNLOCKED","getDIPMemorySize","ChipSet.C8042.INPORT.ENABLE_256KB","getDIPSwitches","getDIPVideoMonitor","fInit","ChipSet.MONITOR.MONO","ChipSet.C8042.INPORT.MONO","ChipSet.C8042.INPORT.COMPAQ_NO80387","ChipSet.C8042.INPORT.COMPAQ_NOWEITEK","b8042OutPort","ChipSet.C8042.OUTPORT.NO_RESET","ChipSet.C8042.OUTPORT.A20_ON","abDMAPageSpare","bCMOSAddr","initRTCTime","ChipSet.CMOS.ADDR.BASEMEM_LO","ChipSet.CMOS.ADDR.EXTMEM_HI","initCMOSData","ChipSet.CMOS.ADDR.DIAG","ChipSet.CMOS.ADDR.CHKSUM_HI","ChipSet.PPI_SW.MONITOR.SHIFT","SHIFT","ChipSet.PPI_SW.MONITOR.MASK","MASK","ChipSet.PPI_SW.FPU","nDrives","ChipSet.PPI_SW.FDRIVE.SHIFT","ChipSet.PPI_SW.FDRIVE.MASK","ChipSet.PPI_SW.FDRIVE.IPL","IPL","ChipSet.CMOS.ADDR.EQUIP","ChipSet.CMOS.ADDR.FDRIVE","getDIPFloppyDriveType","updateCMOSChecksum","getTime","ChipSet.CMOS.ADDR.RTC_SEC","ChipSet.CMOS.ADDR.RTC_SEC_ALRM","ChipSet.CMOS.ADDR.RTC_MIN","ChipSet.CMOS.ADDR.RTC_MIN_ALRM","ChipSet.CMOS.ADDR.RTC_HOUR","ChipSet.CMOS.ADDR.RTC_HOUR_ALRM","ChipSet.CMOS.ADDR.RTC_WEEK_DAY","ChipSet.CMOS.ADDR.RTC_MONTH_DAY","ChipSet.CMOS.ADDR.RTC_MONTH","nYear","ChipSet.CMOS.ADDR.RTC_YEAR","nCentury","ChipSet.CMOS.ADDR.CENTURY_DATE","ChipSet.CMOS.ADDR.STATUSA","ChipSet.CMOS.STATUSB.HOUR24","ChipSet.CMOS.ADDR.STATUSC","ChipSet.CMOS.STATUSD.VRB","nRTCCyclesLastUpdate","nRTCPeriodsPerSecond","nRTCCyclesPerPeriod","iRTC","f12HourValue","ChipSet.CMOS.STATUSB.BINARY","ChipSet.CMOS.STATUSA.UIP","setRTCCycleLimit","wChecksum","ChipSet.CMOS.ADDR.CHKSUM_LO","iDMAC","saveDMAControllers","iChannel","aChannels","channel","masked","addrInit","countInit","addrCurrent","bPage","sFunction","bStatus","bCmd","bReq","bIndex","bTemp","savePICs","nICW","bIRLow","bOCW3","countLatched","bcd","rw","countIndex","fOUT","fCountLatched","fStatusLatched","setSpeaker","aState","ChipSet.aDMAControllerInit","nChannelBase","initDMAChannel","ChipSet.aDMAChannelInit","initDMAFunction","fnTransfer","ChipSet.aPICInit","nIRQBase","ChipSet.aTimerInit","iDIP","sCellClasses","sCellClass","innerHTML","updateDIPSwitchControls","findDIPSwitch","iSwitch","switchTypes","switchDIPs","ChipSet.DIPSW","iType","switchGroup","VALUES","iDrive","getDIPFloppyDrives","ChipSet.CMOS.FDRIVE.FD360","ChipSet.CMOS.FDRIVE.FD720","ChipSet.CMOS.FDRIVE.FD1200","ChipSet.CMOS.FDRIVE.FD1440","ChipSet.CMOS.FDRIVE.NONE","nKBLowMem","ChipSet.SWITCH_TYPE.LOWMEM","nKBExpMem","ChipSet.SWITCH_TYPE.EXPMEM","sBits","bDefault","setDIPSwitchControl","setAttribute","backgroundColor","updateDIPSwitchDescriptions","aeCells","LABEL","eSwitch","onClickSwitch","asParts","sID","controlDesc","getDIPCoprocessor","asMonitorTypes","inDMAChannelAddr","ChipSet.DMA_REFRESH","outDMAChannelAddr","inDMAChannelCount","outDMAChannelCount","inDMAStatus","ChipSet.DMA_STATUS.CH0_TC","ChipSet.DMA_STATUS.ALL_TC","outDMAReq","outDMAMask","ChipSet.DMA_MASK.CHANNEL","ChipSet.DMA_MASK.CHANNEL_SET","requestDMA","outDMAMode","ChipSet.DMA_MODE.CHANNEL","inDMATemp","outDMAMasterClear","inDMAPageReg","outDMAPageReg","inDMAPageSpare","iSpare","outDMAPageSpare","connectDMA","iDMAChannel","advanceDMA","ChipSet.DMA_MODE.TYPE","fWarning","fError","fAsyncRequest","ChipSet.DMA_MODE.TYPE_WRITE","advanceDMAWrite","addrCur","onTransferDMA","updateDMA","ChipSet.DMA_MODE.TYPE_READ","ChipSet.DMA_MODE.TYPE_VERIFY","ChipSet.DMA_MODE.DECREMENT","ChipSet.DMA_MODE.AUTOINIT","inPICLo","ChipSet.PIC_LO.OCW3_READ_CMD","ChipSet.PIC_LO.OCW3_READ_IRR","ChipSet.PIC_LO.OCW3_READ_ISR","outPICLo","ChipSet.PIC_LO.ICW1","ChipSet.PIC_LO.OCW3","ChipSet.PIC_LO.OCW3_POLL_CMD","ChipSet.PIC_LO.OCW3_SMM_CMD","bOCW2","ChipSet.PIC_LO.OCW2_OP_MASK","ChipSet.PIC_LO.OCW2_EOI","bIREnd","ChipSet.PIC_LO.OCW2_EOI_SPEC","nIRL","ChipSet.PIC_LO.OCW2_IR_LVL","bIR","checkIRR","ChipSet.PIC_LO.OCW2_SET_ROTAUTO","ChipSet.PIC_LO.OCW2_SET_PRI","inPICHi","outPICHi","ChipSet.PIC_LO.ICW1_SNGL","ChipSet.PIC_LO.ICW1_ICW4","nIRQ","messageBitsIRQ","ChipSet.IRQ.SLAVE","bIRNext","inTimer","iPIT","iPITTimer","iBaseTimer","resetTimerIndex","outTimer","ChipSet.PIT_CTRL.MODE0","ChipSet.PIT_CTRL.MODE4","ChipSet.PIT0.INDEX","ChipSet.PIT0.TIMER0","ChipSet.IRQ.TIMER0","getTimerInit","ChipSet.PIT0.TIMER2","inTimerCtrl","outTimerCtrl","ChipSet.PIT_CTRL.SC","ChipSet.PIT_CTRL.SC_BACK","ChipSet.PIT_CTRL.RB_STATUS","ChipSet.PIT_CTRL.RB_CTR0","latchTimerStatus","ChipSet.PIT_CTRL.RB_NULL","ChipSet.PIT_CTRL.RB_OUT","ChipSet.PIT_CTRL.RB_COUNTS","latchTimerCount","ChipSet.PIT_CTRL.SC_SHIFT","ChipSet.PIT_CTRL.BCD","ChipSet.PIT_CTRL.MODE","ChipSet.PIT_CTRL.RW","ChipSet.PIT_CTRL.RW_LATCH","setTimerMode","ChipSet.PPI_B.CLK_TIMER2","ChipSet.PPI_B.ENABLE_SW2","ChipSet.PPI_B.CASS_MOTOR_OFF","ChipSet.PPI_B.CLK_KBD","ChipSet.PIT_CTRL.RW_MSB","ChipSet.PIT_CTRL.RW_BOTH","fCycleReset","ChipSet.PIT_CTRL.MODE2","nCyclesPerSecond","updateRTCTime","ChipSet.CMOS.STATUSC.PF","ChipSet.CMOS.STATUSC.IRQF","ChipSet.IRQ.RTC","ChipSet.CMOS.STATUSC.AF","ChipSet.CMOS.STATUSB.AIE","nCyclesDelta","nSecondsDelta","ChipSet.CMOS.STATUSB.SET","nDays","nMonth","nDayMax","ChipSet.CMOS.STATUSC.UF","ChipSet.CMOS.STATUSB.UIE","outMFGTest","inPPIA","ChipSet.PPI_CTRL.A_IN","ChipSet.PPI_B.CLEAR_KBD","outPPIA","inPPIB","outPPIB","updatePPIB","fNewSpeaker","ChipSet.PPI_B.SPK_TIMER2","fOldSpeaker","setEnabled","inPPIC","ChipSet.NMI.KBD_LATCH","ChipSet.PPI_C.NO_MODEM","ChipSet.PPI_C.NO_DISKETTE","ChipSet.PPI_C.NO_MEMEXP","ChipSet.PPI_C.KBD_DATA","ChipSet.PPI_C.SW","ChipSet.PPI_B.ENABLE_SW_HI","ChipSet.PPI_C.TIMER2_OUT","ChipSet.PPI_C.CASS_DATA_IN","outPPIC","inPPICtrl","outPPICtrl","in8041Kbd","ChipSet.C8042.STATUS.OUTBUFF_FULL","out8041Kbd","in8041Ctrl","out8041Ctrl","in8041Status","in8042OutBuff","ChipSet.C8042.STATUS.OUTBUFF_DELAY","checkBuffer","out8042InBuffData","ChipSet.C8042.STATUS.CMD_FLAG","ChipSet.C8042.CMD.WRITE_CMD","set8042CmdData","ChipSet.C8042.CMD.WRITE_OUTPORT","set8042OutPort","bCmdPending","Keyboard.CMD.RESET","Keyboard.CMDRES.ACK","resetDevice","Keyboard.CMD.SET_RATE","setResponse","Keyboard.CMD.SET_LEDS","set8042OutBuff","in8042RWReg","ChipSet.C8042.RWREG.NMI_ERROR","ChipSet.C8042.RWREG.REFRESH_BIT","out8042RWReg","in8042Status","out8042InBuffCmd","bPulseBits","ChipSet.C8042.CMD.PULSE_OUTPORT","ChipSet.C8042.CMD.READ_CMD","ChipSet.C8042.CMD.DISABLE_KBD","ChipSet.C8042.CMD.ENABLE_KBD","ChipSet.C8042.CMD.SELF_TEST","abBuffer","ChipSet.C8042.DATA.SELF_TEST.OK","ChipSet.C8042.CMD.INTF_TEST","ChipSet.C8042.DATA.INTF_TEST.OK","ChipSet.C8042.CMD.READ_INPORT","ChipSet.C8042.CMD.READ_OUTPORT","ChipSet.C8042.CMD.READ_TEST","ChipSet.C8042.TESTPORT.KBD_CLOCK","ChipSet.C8042.STATUS.SYS_FLAG","ChipSet.C8042.DATA.CMD.SYS_FLAG","ChipSet.C8042.DATA.CMD.NO_INHIBIT","fNoDelay","receiveKbdData","ChipSet.IRQ.KBD","in6300DIPSwitches","inCMOSAddr","outCMOSAddr","ChipSet.CMOS.ADDR.NMI_DISABLE","inCMOSData","bAddr","ChipSet.CMOS.ADDR.MASK","ChipSet.CMOS.STATUSC.RESERVED","outCMOSData","bDelta","fBCD","inNMI","outNMI","outFPUClear","outFPUReset","onBIOSRTCReturn","nLevel","CL","CH","DL","DH","sResult","fOn","freq","startAudio","oscillatorAudio","volumeAudio","ChipSet.IRQ.COM1","ChipSet.IRQ.COM2","ChipSet.IRQ.XTC","ChipSet.IRQ.FDC","ChipSet.IRQ.ATC","ChipSet.MODEL_5160","ChipSet.MODEL_CDP_MPC1600","ChipSet.MODEL_ZENITH_Z150","ChipSet.MODEL_COMPAQ_PORTABLE","SW1","SW2","SWDESC","MONO","CH0_TC","ALL_TC","CHANNEL","CHANNEL_SET","TYPE","TYPE_VERIFY","TYPE_WRITE","TYPE_READ","AUTOINIT","DECREMENT","INDEX","PORT_LO","ICW1","ICW1_ICW4","ICW1_SNGL","OCW2_IR_LVL","OCW2_OP_MASK","OCW2_EOI","OCW2_EOI_SPEC","OCW2_SET_ROTAUTO","OCW2_SET_PRI","OCW3","OCW3_READ_IRR","OCW3_READ_ISR","OCW3_READ_CMD","OCW3_POLL_CMD","OCW3_SMM_CMD","TIMER0","SLAVE","COM2","COM1","XTC","ATC","TIMER2","BCD","MODE","MODE0","MODE2","MODE3","MODE4","RW","RW_LATCH","RW_MSB","RW_BOTH","SC","SC_BACK","SC_SHIFT","RB_CTR0","RB_STATUS","RB_COUNTS","RB_NULL","RB_OUT","CLK_TIMER2","SPK_TIMER2","ENABLE_SW2","CASS_MOTOR_OFF","ENABLE_SW_HI","CLK_KBD","CLEAR_KBD","NO_MODEM","NO_DISKETTE","NO_MEMEXP","SW","CASS_DATA_IN","TIMER2_OUT","KBD_DATA","A_IN","FDRIVE","ONE","TWO","THREE","FOUR","MONITOR","TV","FLOPNUM","LOWMEM","EXPMEM","FLOPTYPE","SYS_FLAG","NO_INHIBIT","NO_CLOCK","OK","COMPAQ_NO80387","INPORT","COMPAQ_NOWEITEK","ENABLE_256KB","MFG_OFF","KBD_UNLOCKED","NO_RESET","OUTPORT","A20_ON","KBD_CLOCK","TESTPORT","REFRESH_BIT","RWREG","NMI_ERROR","READ_CMD","CMD","WRITE_CMD","SELF_TEST","INTF_TEST","DISABLE_KBD","ENABLE_KBD","READ_INPORT","READ_OUTPORT","WRITE_OUTPORT","READ_TEST","PULSE_OUTPORT","OUTBUFF_FULL","STATUS","CMD_FLAG","OUTBUFF_DELAY","RTC_SEC","ADDR","RTC_SEC_ALRM","RTC_MIN","RTC_MIN_ALRM","RTC_HOUR","RTC_HOUR_ALRM","RTC_WEEK_DAY","RTC_MONTH_DAY","RTC_MONTH","RTC_YEAR","STATUSA","STATUSB","STATUSC","STATUSD","DIAG","EQUIP","BASEMEM_LO","EXTMEM_HI","CHKSUM_HI","CHKSUM_LO","CENTURY_DATE","TOTAL","NMI_DISABLE","UIP","SET","PIE","AIE","UIE","BINARY","HOUR24","IRQF","PF","UF","RESERVED","VRB","FD360","FD1200","FD720","FD1440","ENABLE","KBD_LATCH","RESET","32","33","64","65","TIMER1","66","67","0","1","2","3","4","5","6","7","8","13","129","130","131","135","128","132","133","134","136","137","138","139","140","141","142","143","160","161","192","194","196","198","200","202","204","206","208","218","102","103","72","TIMER3","73","TIMER4","74","TIMER5","75","outDMACmd","9","10","11","12","outDMAResetFF","210","212","214","216","aeChipSet","iChip","eChipSet","ROMX86","parmsROM","abROM","addrROM","sizeROM","addrAlias","idNotify","aNotifyParms","sFileURL","sFilePath","sFileExt","Str.getExtension","Str.getBaseName","FORMAT","Web.getHost","rom","sProgress","Web.getResource","doneROMLoad","sResponse","doneLoad","aSymbols","addSymbols","sROMData","Component.addMachineResource","ib","asHexData","sHexData","copyROM","addROM","aliases","cloneROM","nCard","Video.CARD.EGA","setFontData","Video.CARD.VGA","aeROM","iROM","eROM","RAM","parmsRAM","addrRAM","sizeRAM","fTestRAM","fInstalled","fAllocated","RAM.prototype","baseRAM","CompaqController","CompaqController.ADDR","CTRL","RESET_FLAG","wKb","ram","wMappings","CompaqController.MAPPINGS.DEFAULT","wSettings","CompaqController.SETTINGS.DEFAULT","wRAMSetup","CompaqController.RAMSETUP.DEFAULT","aBlocksDst","CompaqController.MAPPINGS.UNMAPPED","CompaqController.MAP_DST","CompaqController.MAP_SIZE","CompaqController.MAP_SRC","CompaqController.MAPPINGS.READWRITE","CompaqController.ACCESS","CompaqController.BUFFER","UNMAPPED","READWRITE","DEFAULT","aeRAM","iRAM","eRAM","Keyboard","parmsKbd","setModel","fMobile","Web.isMobile","fMSWindows","cSoftCodes","fSoftKeyboard","controlTextKeyboard","controlSoftKeyboard","fToggleCapsLock","fEscapeDisabled","aKeysActive","msAutoRelease","msInjectDefault","cKeysPressed","msInjectDelay","softCodeKeys","keys","Keyboard.SOFTCODES","autoType","fDOSReady","fnDOSReady","fnInjectReady","nInjection","Keyboard.INJECTION.ON_INPUT","injectKeys","waitReady","Keyboard.prototype","parentElement","nextElementSibling","enableSoftKeyboard","display","controlSoftKeyboard.ontouchstart","preventDefault","onkeydown","controlText.onkeydown","onKeyChange","onkeypress","controlText.onkeypress","keyCode","which","notifyKbdEvent","sInjectBuffer","fPass","Keyboard.SIMCODES","bitsState","Keyboard.STATE.CMD","Keyboard.STATE.ALTS","Keyboard.SIMCODE.ALT","addActiveKey","onkeyup","controlText.onkeyup","Keyboard.SIMCODE.CAPS_LOCK","Keyboard.SIMCODE.NUM_LOCK","Keyboard.SIMCODE.SCROLL_LOCK","sCode","Keyboard.CLICKCODES","simCode","onKeyboardBindingClick","updateShiftState","msLastEvent","nClickState","fStateKey","Keyboard.KEYSTATES","Keyboard.STATE.ALL_MODIFIERS","fnDown","onKeyboardBindingDown","timeStamp","msDoubleClick","fnUp","onKeyboardBindingUp","removeActiveKey","findBinding","code","Keyboard.SIMCODE.CTRL_PAUSE","Keyboard.SIMCODE.CTRL_BREAK","Keyboard.SIMCODE.CTRL_ALT_DEL","Keyboard.SIMCODE.DEL","Keyboard.SIMCODE.CTRL_ALT_INS","Keyboard.SIMCODE.INS","Keyboard.SIMCODE.CTRL_ALT_ADD","Keyboard.SIMCODE.NUM_ADD","Keyboard.SIMCODE.CTRL_ALT_SUB","Keyboard.SIMCODE.NUM_SUB","Keys.ASCII.a","Keys.ASCII.z","Keys.ASCII.A","timerInject","injectKeysTimer","timerTransmit","transmitDataTimer","transmitData","softKeys","intDOS","injectInit","Keyboard.INJECTION.ON_START","Keyboard.CMDRES.BAT_OK","sModel","iModel","Keyboard.MODELS.indexOf","Keyboard.MODELS","modelKeys","msTransmit","fData","fClock","fResetOnEnable","unshift","initState","saveState","sStatePath","Keyboard.INJECTION.NONE","bitsStateSim","readOnly","nCondition","sKeys","reSpecial","Usr.formatDate","digits","shortName","charCode","charCodeAt","Keys.ASCII.CTRL_Z","Keys.ASCII.CTRL_I","Keys.ASCII.CTRL_J","Keys.ASCII.CTRL_M","fPress","Keyboard.MODIFIERS","clearActiveKeys","sOption","fSim","fRight","bitState","Keyboard.STATE.ALL_RIGHT","Keyboard.STATE.ALL_LOCKS","Keyboard.LEDSTATES","bitLED","updateLEDs","nRepeat","key","updateActiveKey","fModifiers","fFlush","fRemoved","keySimulate","msTimer","msAutoRepeat","msNextRepeat","onUpdateActiveKey","getSimCode","fShifted","Keys.ASCII.Z","Keyboard.STATE.SHIFT","Keyboard.STATE.RSHIFT","Keyboard.STATE.CAPS_LOCK","onFocusChange","fFocus","fIgnore","Component.processScript","nShiftState","LOCATION","Keyboard.STATE.CTRL","Keyboard.STATE.ALT","Keyboard.STATE.RALT","Keyboard.STATE.CTRLS","Keyboard.STATE.CMDS","fSimulated","wCode","abScanCodes","bCode","Keyboard.SCANCODE.BREAK","fAlpha","bShift","bScan","Keyboard.SCANCODE.EXTEND1","Keyboard.SCANCODE.EXTEND2","Keyboard.SCANCODE.SHIFT","Keyboard.SCANCODE.CTRL","Keyboard.STATE.RCTRL","Keyboard.SCANCODE.ALT","addScanCode","Keyboard.LIMIT.MAX_SCANCODES","COMPAQ_KEYCLICK","Keyboard.CMDRES.BUFF_FULL","ALT","CAPS_LOCK","NUM_LOCK","SCROLL_LOCK","NUM_ADD","NUM_SUB","INS","Keys.ASCII.CTRL_A","Keys.ASCII.CTRL_B","Keys.ASCII.CTRL_C","Keys.ASCII.CTRL_D","Keys.ASCII.CTRL_E","Keys.ASCII.CTRL_F","Keys.ASCII.CTRL_G","Keys.ASCII.CTRL_H","Keys.ASCII.CTRL_K","Keys.ASCII.CTRL_L","Keys.ASCII.CTRL_N","Keys.ASCII.CTRL_O","Keys.ASCII.CTRL_P","Keys.ASCII.CTRL_Q","Keys.ASCII.CTRL_R","Keys.ASCII.CTRL_S","Keys.ASCII.CTRL_T","Keys.ASCII.CTRL_U","Keys.ASCII.CTRL_V","Keys.ASCII.CTRL_W","Keys.ASCII.CTRL_X","Keys.ASCII.CTRL_Y","CTRL_PAUSE","CTRL_BREAK","CTRL_ALT_DEL","CTRL_ALT_INS","CTRL_ALT_ADD","CTRL_ALT_SUB","EXTEND1","EXTEND2","RSHIFT","RCTRL","CTRLS","RALT","ALTS","CMDS","ALL_RIGHT","ALL_MODIFIERS","ALL_LOCKS","RCMD","FF_CMD","TAB","F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","LEFT","UP","RIGHT","DOWN","HOME","END","PGUP","PGDN","SYS_REQ","Keyboard.SIMCODE.CTRL_C","CTRL_ALT_ENTER","BS","Keys.ASCII.q","Keys.ASCII.w","Keys.ASCII.e","Keys.ASCII.r","Keys.ASCII.t","Keys.ASCII.y","Keys.ASCII.u","Keys.ASCII.i","Keys.ASCII.o","Keys.ASCII.p","Keys.ASCII.s","Keys.ASCII.d","Keys.ASCII.f","Keys.ASCII.g","Keys.ASCII.h","Keys.ASCII.j","Keys.ASCII.k","Keys.ASCII.l","Keys.ASCII.x","Keys.ASCII.c","Keys.ASCII.v","Keys.ASCII.b","Keys.ASCII.n","Keys.ASCII.m","PRTSC","SPACE","NUM_CENTER","FIVE","SIX","SEVEN","EIGHT","NINE","ZERO","DASH","EQUALS","Keys.ASCII.Q","Keys.ASCII.W","Keys.ASCII.E","Keys.ASCII.R","Keys.ASCII.T","Keys.ASCII.Y","Keys.ASCII.U","Keys.ASCII.I","Keys.ASCII.O","Keys.ASCII.P","LBRACK","RBRACK","ENTER","Keys.ASCII.S","Keys.ASCII.D","Keys.ASCII.F","Keys.ASCII.G","Keys.ASCII.H","Keys.ASCII.J","Keys.ASCII.K","Keys.ASCII.L","SEMI","QUOTE","BQUOTE","BSLASH","Keys.ASCII.X","Keys.ASCII.C","Keys.ASCII.V","Keys.ASCII.B","Keys.ASCII.N","Keys.ASCII.M","COMMA","PERIOD","SLASH","NUM_HOME","NUM_UP","NUM_PGUP","NUM_LEFT","NUM_RIGHT","NUM_END","NUM_DOWN","NUM_PGDN","NUM_INS","NUM_DEL","F11","F12","WIN","MENU","Keyboard.SIMCODE.CTRL_A","Keyboard.SIMCODE.CTRL_B","Keyboard.SIMCODE.CTRL_D","Keyboard.SIMCODE.CTRL_E","Keyboard.SIMCODE.CTRL_F","Keyboard.SIMCODE.CTRL_G","Keyboard.SIMCODE.CTRL_H","Keyboard.SIMCODE.CTRL_I","Keyboard.SIMCODE.CTRL_J","Keyboard.SIMCODE.CTRL_K","Keyboard.SIMCODE.CTRL_L","Keyboard.SIMCODE.CTRL_M","Keyboard.SIMCODE.CTRL_N","Keyboard.SIMCODE.CTRL_O","Keyboard.SIMCODE.CTRL_P","Keyboard.SIMCODE.CTRL_Q","Keyboard.SIMCODE.CTRL_R","Keyboard.SIMCODE.CTRL_S","Keyboard.SIMCODE.CTRL_T","Keyboard.SIMCODE.CTRL_U","Keyboard.SIMCODE.CTRL_V","Keyboard.SIMCODE.CTRL_W","Keyboard.SIMCODE.CTRL_X","Keyboard.SIMCODE.CTRL_Y","Keyboard.SIMCODE.CTRL_Z","SET_RATE","SET_LEDS","BAT_OK","ACK","BUFF_FULL","MAX_SCANCODES","ON_START","ON_INPUT","aeKbd","iKbd","eKbd","Card","video","cbMemory","specs","Video.cardSpecs","nMonitorType","Card.CRTC.TOTAL_REGS","Card.CRTC.EGA.TOTAL_REGS","addrBuffer","sizeBuffer","fActive","regMode","regColor","regCRTIndx","regCRTPrev","regCRTData","nCRTCRegs","asCRTCRegs","Card.CRTC.REGS","offStartAddr","Card.CRTC.STARTLO","Card.CRTC.STARTHI","addrMaskHigh","Card.CRTC.EGA_REGS","Card.ATC.TOTAL_REGS","Card.MISC.IO_SELECT","Card.SEQ.TOTAL_REGS","Card.GRC.TOTAL_REGS","initEGA","Card.ACCESS.READ.MODE0","Card.ACCESS.READ.EVENODD","Card.ACCESS.WRITE.MODE0","Card.ACCESS.WRITE.EVENODD","Card.ACCESS.V2","Card.VGA_ENABLE.ENABLED","Card.DAC.MASK.DEFAULT","Card.DAC.STATE.MODE_WRITE","Card.DAC.TOTAL_REGS","fATCData","regATCIndx","regATCData","asATCRegs","Card.ATC.REGS","regStatus0","regMisc","regFeat","regSEQIndx","regSEQData","asSEQRegs","Card.SEQ.REGS","regGRCPos1","regGRCPos2","regGRCIndx","regGRCData","asGRCRegs","Card.GRC.REGS","latches","cdw","adwMemory","nAccess","Card.ACCESS.V1","nReadMapShift","nSeqMapMask","nDataRotate","nBitMapMask","nSetMapData","nSetMapMask","nSetMapBits","nColorCompare","nColorDontCare","nVertPeriods","nVertPeriodsStartAddr","regVGAEnable","regDACMask","regDACAddr","regDACShift","regDACState","regDACData","monitorSpecs","Video.monitorSpecs","nCyclesHorzPeriod","nHorzPeriodsPerSec","nCyclesHorzActive","percentHorzActive","nCyclesVertPeriod","nHorzPeriodsPerFrame","nCyclesVertActive","percentVertActive","nInitCycles","saveCard","saveEGA","dumpRegs","aRegs","asRegs","getCRTCReg","Str.pad","cchMax","afnAccess","nReadAccess","Card.ACCESS.READ.MASK","fnReadByte","Card.ACCESS.afn","nWriteAccess","Card.ACCESS.WRITE.MASK","fnWriteByte","bOverflowBit8","bOverflowBit9","bMaxScanBit9","Card.CRTC.EGA.VTOTAL","Card.CRTC.EGA.OVERFLOW.VTOTAL_BIT8","Card.CRTC.EGA.OVERFLOW.VTOTAL_BIT9","Card.CRTC.EGA.CURSCAN","Card.CRTC.EGA.OVERFLOW.CURSCAN_BIT8","Card.CRTC.EGA.VRSTART","Card.CRTC.EGA.OVERFLOW.VRSTART_BIT8","Card.CRTC.EGA.OVERFLOW.VRSTART_BIT9","Card.CRTC.EGA.VDEND","Card.CRTC.EGA.OVERFLOW.VDEND_BIT8","Card.CRTC.EGA.OVERFLOW.VDEND_BIT9","Card.CRTC.EGA.VBSTART","Card.CRTC.EGA.OVERFLOW.VBSTART_BIT8","Card.CRTC.EGA.MAXSCAN.VBSTART_BIT9","Card.CRTC.EGA.LINECOMP","Card.CRTC.EGA.OVERFLOW.LINECOMP_BIT8","Card.CRTC.EGA.MAXSCAN.LINECOMP_BIT9","Card.CRTC.EGA.OVERFLOW.INDX","Card.CRTC.EGA.MAXSCAN.INDX","STARTHI","STARTLO","TOTAL_REGS","VTOTAL","EGA","INDX","VTOTAL_BIT8","VDEND_BIT8","VRSTART_BIT8","VBSTART_BIT8","LINECOMP_BIT8","CURSCAN_BIT8","VTOTAL_BIT9","VDEND_BIT9","VRSTART_BIT9","VBSTART_BIT9","LINECOMP_BIT9","CURSCAN","VRSTART","VDEND","VBSTART","LINECOMP","Card.CRTCMASKS","HTOTAL","HDISP","HSPOS","HSWIDTH","VTOTADJ","VDISP","VSPOS","ILMODE","MAXSCAN","CURSCANB","CURSORHI","CURSORLO","PENHI","PENLO","IO_SELECT","ENABLED","MODE_WRITE","STATE","READ","EVENODD","WRITE","V2","Card.ACCESS.readByteMode0","Card.ACCESS.readByteMode0Chain4","Card.ACCESS.readByteMode0EvenOdd","Card.ACCESS.readByteMode1","Card.ACCESS.writeByteMode0","Card.ACCESS.writeByteMode0Rot","Card.ACCESS.writeByteMode0And","Card.ACCESS.writeByteMode0Or","Card.ACCESS.writeByteMode0Xor","Card.ACCESS.writeByteMode0Chain4","Card.ACCESS.writeByteMode0EvenOdd","maskMaps","Card.ACCESS.writeByteMode1","Card.ACCESS.writeByteMode1EvenOdd","Card.ACCESS.writeByteMode2","Video.aEGAByteToDW","Card.ACCESS.writeByteMode2And","Card.ACCESS.writeByteMode2Or","Card.ACCESS.writeByteMode2Xor","Card.ACCESS.writeByteMode3","dwMask","Video","parmsVideo","textarea","container","fGecko","aModelDefaults","Video.MODEL","sSwitches","nRandomize","nModeDefault","Video.aModeParms","nColsDefault","nRowsDefault","cxScreen","cyScreen","canvasScreen","contextScreen","inputScreen","inputTextArea","colorScreen","opacityFlicker","fOpacityReduced","fSmoothing","sSmoothing","Web.findProperty","sTouchScreen","nTouchConfig","Video.TOUCH.NONE","mouse","fAutoLock","aFonts","aRGB","fRGBValid","doFullScreen","sFullScreen","addEventListener","onFullScreenChange","notifyFullScreen","onFullScreenError","onfocus","lockPointer","this.inputScreen.onfocus","onblur","this.inputScreen.onblur","unlockPointer","sPointerLock","onPointerLockChange","notifyPointerLocked","fLocked","Video.prototype","aModel","Video.CARD.CGA","Video.aMDAPortInput","Video.aMDAPortOutput","Video.CARD.MDA","Video.aCGAPortInput","Video.aCGAPortOutput","Video.aEGAPortInput","Video.aEGAPortOutput","Video.aVGAPortInput","Video.aVGAPortOutput","onDumpVideo","cardActive","fColAdjust","prevDump","Str.toBin","nMode","bEGASwitches","captureTouch","Video.TOUCH.MOUSE","Video.TOUCH.KEYGRID","Video.TOUCH.DEFAULT","updateScreenTimer","updateScreen","Video.UPDATES_PER_SECOND","sWidth","screen","height","aspectPhys","aspectVirt","margin","sHeight","focus","sLockMessage","fFullScreen","fLock","setFocus","addPassive","opts","defineProperty","get","removeEventListener","onTouchStart","processTouchEvent","passive","onTouchMove","onTouchEnd","xTouch","yTouch","timeTouch","fTouchDefault","hLongTouch","fLongTouch","onLongTouch","this.onLongTouch","Mouse.BUTTON.LEFT","fStart","xTouchOffset","yTouchOffset","eCurrent","offsetLeft","offsetTop","offsetParent","targetTouches","pageX","pageY","Video.KEYGRID","timeDelta","endLongTouch","xDelta","yDelta","Video.MODE.CGA_80X25","VGACOLOR","aMonitors","Video.aEGAMonitorSwitches","EGACOLOR","Video.MODE.MDA_80X25","cardMono","cardMDA","cardColor","cardCGA","cardEGA","enableEGA","buildFonts","setMode","addrScreenLimit","cbScreen","addrScreen","dataRandom","random","bChar","bAttr","Video.ATTRS.BGND_BLINK","Video.ATTRS.FGND_WHITE","Video.ATTRS.BGND_BLACK","Video.ATTRS.FGND_BLACK","Video.ATTRS.BGND_WHITE","Video.ATTRS.FGND_BRIGHT","checkMode","checkCursor","sFontData","abFontData","getCardColors","nBitsPerPixel","Video.aCGAColors","bBackground","PALETTE","aColorSet","Video.aCGAColorSet2","Video.aCGAColorSet1","iColor","card","aDAC","bRed","bGreen","bBlue","fDAC","Video.aEGAPalDef","COLORSEL","aFontOffsets","cxFontChar","fRebuild","fChanges","nFont","offSplit","cxChar","aRGBColors","buildFont","Video.FONT.CGA","Video.FONT.MDA","Video.aMDAColors","Video.aMDAColorMap","iCellCursor","cBlinks","cBlinkVisible","offData","cyChar","aColorMap","createFont","nColors","cxCell","nDouble","cyCell","aCSSColors","aCanvas","rgbColor","rgbColorOrig","iChar","rgbOff","canvasFont","contextFont","getContext","cyLimit","imageChar","createImageData","fUnderline","offChar","nRowDoubler","xDst","yDst","rgb","setPixel","putImageData","checkBlink","bCursorFlags","bCursorStart","CURSCAN_SLMASK","bCursorEnd","bCursorMax","oCursorStart","oCursorEnd","CURSCAN_BLINKOFF","bCursorWrap","bCursorSize","removeCursor","yCursor","cyCursor","cyCursorWrap","cyCursorCell","aCellCache","drawCursor","Video.ATTRS.DRAW_CURSOR","col","row","contextBuffer","updateChar","getCardAccess","fColor256","regGRCMode","regDataRotate","DATAROT","regSEQMode","MEMMODE","setCardAccess","cbBuffer","cbBufferText","regGRCMisc","MISC","Video.MODE.UNKNOWN","Video.MODE.EGA_640X350_MONO","Video.MODE.EGA_640X350","Video.MODE.CGA_80X25_BW","fTextGraphicsHybrid","nCRTCVertTotal","nCRTCMaxScan","nCRTCModeCtrl","fSEQDotClock","CLOCKING","Video.MODE.VGA_320X200","Video.MODE.VGA_320X240","Video.MODE.VGA_320X400","Video.MODE.EGA_320X200","Video.MODE.EGA_640X200","Video.MODE.VGA_640X480_MONO","Video.MODE.VGA_640X480","Video.MODE.CGA_640X200","Video.MODE.CGA_320X200_BW","Video.MODE.CGA_40X25","opacity","cUpdates","setDimensions","nRows","nColsLogical","nCellsPerWord","cbPadding","modeParms","nCells","nCellCache","cbSplit","cxScreenCell","cyScreenCell","cxBuffer","cyBuffer","imageBuffer","canvasBuffer","xScreenOffset","yScreenOffset","cxScreenOffset","cyScreenOffset","cxBorder","cyBorder","invalidateCache","imageData","initCache","fCellCacheValid","fModified","iFgnd","iBgnd","Video.ATTRS.DRAW_FGND","xSrcFgnd","ySrcFgnd","fEnabled","INDX_PAL_ENABLE","fBlinkUpdate","getRetraceBits","cbScreenWrap","addrScreenWrap","cBlinkOrig","cCells","updateScreenCells","iCell","cBlinkNew","dataBlink","cUpdated","dataDraw","dataMask","fBlinkEnable","updateScreenText","nPixelsPerCell","wPixelMask","nPixelShift","aPixelColors","xDirty","xMaxDirty","yDirty","yMaxDirty","wPixels","wMask","iPixel","bPixel","cbInc","iPixelFirst","HPAN","nRowAdjust","nPixels","Video.aEGADWToByte","nElapsedCycles","inMDAIndx","inCRTCIndx","outMDAIndx","CRTC","outCRTCIndx","inMDAData","inCRTCData","outMDAData","outCRTCData","inMDAMode","inCardMode","outMDAMode","outCardMode","inMDAStatus","inCardStatus","outFeat","BITS","inATCIndx","Video_prototype$inATCData","inATCData","INDX_MASK","outATC","fPalEnabled","PALETTE_REGS","Video.TRAPALL","inStatus0","bSWBit","iBit","CLOCK_SELECT","SWSENSE_SHIFT","dwDAC","SWSENSE","outMisc","PORT_WRITE","inVGAEnable","outVGAEnable","inSEQIndx","outSEQIndx","inSEQData","outSEQData","MAPMASK","inDACMask","outDACMask","inDACState","outDACRead","outDACWrite","inDACData","outDACData","dwNew","inVGAFeat","PORT_READ","outGRCPos2","POS2_PORT","inVGAMisc","outGRCPos1","POS1_PORT","inGRCIndx","outGRCIndx","inGRCData","outGRCData","SRESET","ESRESET","COLORCMP","READMAP","COLORDC","BITMASK","inCGAIndx","outCGAIndx","inCGAData","outCGAData","inCGAMode","outCGAMode","inCGAColor","outCGAColor","inCGAStatus","bCur","bMax","DIAGNOSTIC","CGA_40X25","CGA_80X25_BW","CGA_80X25","CGA_320X200_BW","CGA_640X200","MDA_80X25","EGA_320X200","EGA_640X200","EGA_640X350_MONO","EGA_640X350","VGA_640X480_MONO","VGA_640X480","VGA_320X200","VGA_320X240","VGA_320X400","UNKNOWN","MDA","CGA","VGA","EGAEMULATION","CGA_320X200","CGA_40X25_BW","Video.ATTRS.FGND_GREEN","Video.ATTRS.FGND_RED","Video.ATTRS.FGND_BROWN","Video.ATTRS.FGND_CYAN","Video.ATTRS.FGND_MAGENTA","KEYGRID","aElement","iVideo","onresize","eParent","eChild","cy","onResizeVideo","clientWidth","aspect","aspectRatio","onResizeWindow","fontSize","ParallelPort","parmsParallel","iAdapter","portBase","LPT1","LPT2","controlBuffer","consoleBuffer","Component.bindExternalControl","ParallelPort.prototype","ParallelPort.aPortInput","ParallelPort.aPortOutput","saveRegisters","bData","bControl","ParallelPort.STATUS.NERR","inData","inStatus","ParallelPort.STATUS.NACK","ParallelPort.STATUS.NBUSY","updateIRR","inControl","outData","parallel","fTransmitted","Str.toASCIICode","outControl","ParallelPort.CONTROL.IRQ_ENABLE","NERR","NACK","NBUSY","IRQ_ENABLE","aeParallel","iParallel","eParallel","SerialPort","tabSize","charBOL","iLogicalCol","charPrev","bMSRInit","SerialPort.MSR.CTS","SerialPort.MSR.DSR","fNullModem","connection","sendData","fAutoFlow","bindConnection","initConnection","receiveData","receiveStatus","SerialPort.prototype","bindMouse","fnUpdate","serial","this.controlBuffer.onkeydown","ctrlKey","this.controlBuffer.onkeypress","removeAttribute","timerReceiveNext","receiveDataTimer","timerTransmitNext","bLSR","SerialPort.LSR.THRE","SerialPort.LSR.TSRE","updateIIR","SerialPort.aPortInput","SerialPort.aPortOutput","sConnection","sSourceID","Str.trim","sTargetID","fnConnect","bRBR","bTHR","wDL","bIER","bIIR","bLCR","bMCR","bMSR","abReceive","SerialPort.DL_DEFAULT","SerialPort.IIR.NO_INT","advanceRBR","SerialPort_prototype$receiveStatus","pins","bMSROld","CTS","SerialPort.MSR.DCTS","DSR","SerialPort.MSR.DDSR","SerialPort.LSR.DR","SerialPort.MCR.RTS","getBaudTimeout","inRBR","SerialPort.LCR.DLAB","inIER","inIIR","SerialPort.IIR.INT_THR","inLCR","inMCR","inLSR","inMSR","outTHR","nChars","outIER","outLCR","outMCR","SerialPort.MCR.DTR","RTS","DTR","SerialPort.IER.RBR_AVAIL","SerialPort.IIR.INT_RBR","SerialPort.IER.THR_EMPTY","SerialPort.IER.MSR_DELTA","SerialPort.IIR.INT_MSR","SerialPort.IIR.INT_BITS","RBR_AVAIL","THR_EMPTY","MSR_DELTA","NO_INT","INT_RBR","INT_THR","INT_MSR","INT_BITS","DLAB","DR","THRE","TSRE","DCTS","DDSR","aeSerial","iSerial","eSerial","TestController","tests","fLoading","urlTests","deliverData","deliverInput","deliverTests","serialPort","loadTests","JSON","parse","control.onkeydown","control.onkeypress","bindController","monitor","TestMonitor","sendOutput","aeTest","iTest","eTest","aOperations","idTimeout","fnRemoveOperation","removeOperation","fWaitPending","receiveInput","receiveTests","APPNAME","APPVERSION","TestMonitor.MODE.TERMINAL","addCommand","commandLine","commands","suite","category","commandParts","command","fExists","addForLoop","errorMessage","p1","p2","Str.sprintf","TestMonitor.COMMANDS.indexOf","addOperation","symbol","initial","final","nextOperation","flushOperations","TestMonitor.COMMAND.PRINTF","TestMonitor.COMMAND.WAIT","TestMonitor.MODE.PROMPT","aCategories","aPrompts","cchPromptLongest","prompt","promptBuffer","TestMonitor.MODE.COMMAND","commandBuffer","Keys.ASCII.DEL","TERMINAL","PROMPT","COMMAND","PRINTF","WAIT","TestMonitor.COMMANDS","Mouse","parmsMouse","idDevice","Mouse.TYPE.SERIAL","Mouse.TYPE.BUS","typeDevice","componentDevice","fCaptured","aVideo","aScreens","Mouse.prototype","Mouse.aBusInput","Mouse.BUS.DATA.PORT","Mouse.aBusOutput","getScreen","captureAll","releaseAll","fButton1","fButton2","setActive","captureMouse","onMouseMove","processMouseEvent","onMouseDown","onMouseUp","screenX","screenY","iButton","isActive","sDiag","sendPacket","Mouse.BUTTON.RIGHT","xDiag","yDiag","xScaled","sign","yScaled","b1","b2","b3","Mouse_prototype$receiveStatus","fIdentify","Mouse.SERIAL.ID","inBusData","inBusTPPI","inBusCtrl","inBusCPPI","outBusData","outBusTPPI","outBusCtrl","outBusCPPI","ID","aeMouse","iMouse","eMouse","Disk","drive","Disk.nDisks","sDiskName","fRemovable","fOnDemand","fRemote","create","nCylinders","nHeads","nSectors","cbSector","aDirtySectors","aDirtyTimestamps","timerWrite","msTimerWrite","fWriteInProgress","Disk.prototype","sDiskPath","donePowerUp","Component.confirmUser","findDirtySectors","disconnectRemoteDisk","getMachineID","getUserID","aDiskData","aCylinders","iCylinder","aHeads","iHead","aSectors","iSector","initSector","dwChecksum","file","fnNotify","sDiskURL","sDiskFile","disk","controllerNotify","reader","FileReader","onload","reader.onload","buildDisk","readAsArrayBuffer","ENDPOINT","sDiskExt","connectRemoteDisk","loadDone","cbDiskData","byteLength","diskFormat","cylinder","head","sector","dwPattern","cModify","diskData","fWriteProtected","buildFileTable","iEOL","sConfig","fill","dir","aFileTable","offFile","pbaVolume","lbaTotal","cbDisk","sectorBoot","getSector","getSectorData","SECTOR_BYTES","fValid","lbaFAT","nFATBits","lbaRoot","nClusterSecs","MEDIA_160KB","getClusterEntry","nEntries","MEDIA_320KB","PARTITIONS","TOTAL_SECS","LARGE_SECS","RESERVED_SECS","FAT_SECS","TOTAL_FATS","ROOT_DIRENTS","CLUSTER_SECS","lbaData","LENGTH","nClusters","MAX_CLUSTERS","iClusterMax","CLUSNUM_MAX","apba","lba","getDir","nSectorsPerCylinder","updateSector","nSectorsRemaining","pba","Str.endsWith","loadField","FileInfo.OE.oeSignature","FileInfo.OE.SIG","FileInfo.OE.oeRelocOffset","FileInfo.OE.NE_SIG","offNEHeader","FileInfo.OE.oeNEHeader","FileInfo.NE.neSignature","FileInfo.NE.SIG","FileInfo.NE.neSTEntries","offEntries","FileInfo.NE.neSTOffset","nSegOffShift","FileInfo.NE.neSegOffShift","loadSegmentTable","iSegment","aSegments","aOrdinals","offSegment","loadValue","lenSegment","offStart","offEnd","aEntries","FileInfo.NE.neETOffset","cbEntries","FileInfo.NE.neETSize","loadEntryTable","iOrdinal","offEntriesEnd","bEntries","bSegment","offEntry","FileInfo.NE.neRNTOffset","loadNameTable","FileInfo.NE.neNRNTOffset","FileInfo.NE.neNRNTSize","sDisk","sDir","iStart","nEntriesPerSector","iEntry","getDirEntry","sectorDirCache","pbaDirCache","UNUSED","INVALID","getSectorString","NAME","EXT","ATTR","cbSize","SIZE","iCluster","CLUSTER","CLUSNUM_MIN","FileInfo","iEnd","SUBDIR","iByte","cbitsSector","offBits","sectorFATCache","lbaFATCache","seek","read","iModify","readRemoteSectors","aRequest","abData","writeRemoteSectors","abSectors","dataPost","ACTION","stringify","queueDirtySector","updateWriteTimer","msWrite","Disk.REMOTE_WRITE_DELAY","msNow","sectorNext","toBytes","info","track","bFormatting","bSectorEnd","nBytes","onReadRemoteComplete","bSector","ibSector","write","encodeAsBase64","btoa","deltas","mods","iModifyLimit","nChanges","sReason","aDiskInfo","convertToJSON","deflateSector","cDupes","offSector","aField","cNames","bLength","loadString","sSymbol","tuple","sModule","SIG","oeSignature","oeRelocOffset","oeNEHeader","NE_SIG","neSignature","neETOffset","neETSize","neSTEntries","neNRNTSize","neSTOffset","neRNTOffset","neNRNTOffset","neSegOffShift","parmsFDC","doDMARead","doDMAWrite","doDMAFormat","configMount","parseConfig","sortBy","aDiskHistory","fLocalDisks","loadSelectedDisk","waitDrives","FDC.prototype","fdc","aOptions","sort","text","localeCompare","onchange","controlSelect.onchange","updateSelectedDiskette","displayDiskette","controlDrives","aDrives","Web.downloadFile","controlForm.onchange","fieldset","children","submit","disabled","files","onsubmit","controlForm.onsubmit","currentTarget","sDiskettePath","loadSelectedDrive","sDisketteName","initController","FDC.aPortInput","FDC.aPortOutput","addDiskette","autoMount","config","configMerge","sDrive","fReload","unloadAllDrives","unloadDrive","firstChild","controlOption","saveController","FDC.REG_STATUS.RQM","regDataArray","regDataIndex","regDataTotal","regOutput","dataDrives","nKb","initDrive","fLocal","FDC.REG_DATA.RES.RESET","FDC.DEFAULT_DRIVE_NAME","nDiskCylinders","nDiskHeads","nDiskSectors","resCode","bHead","bCylinderSeek","bCylinder","doneLoadDrive","loadDrive","addDiskHistory","regInput","FDC.REG_CONTROL.RATE500K","saveDrives","saveDeltas","updateDiskHistory","copyDrive","driveOld","driveNew","seekDrive","nSectorsPerTrack","FDC.REG_DATA.RES.NONE","fRemount","cAutoMount","configDrive","controlDisks","findDisketteByPath","removeDiskHistory","fAutoMount","FDC.REG_INPUT.DISK_CHANGE","sPath","fTop","insertBefore","iDriveSelected","sTargetPath","dataValue","sHRef","fAutoUnload","outFDCOutput","FDC.REG_OUTPUT.ENABLE","requestInterrupt","inFDCDiagnostic","inFDCStatus","inFDCData","FDC.REG_OUTPUT.INT_ENABLE","FDC.REG_STATUS.READ_DATA","FDC.REG_STATUS.BUSY","outFDCData","bCmdMasked","FDC.REG_DATA.CMD.MASK","FDC.aCmdInfo","cbReq","fIRQ","doCmd","popCmd","FDC.REG_DATA.CMD.SPECIFY","beginResult","FDC.REG_DATA.CMD.SENSE_DRIVE","bDrive","pushResult","FDC.REG_DATA.RES.ST3","FDC.REG_DATA.CMD.WRITE_DATA","FDC.REG_DATA.CMD.READ_DATA","FDC.REG_DATA.RES.NOT_READY","FDC.REG_DATA.RES.INCOMPLETE","ChipSet.DMA_FDC","FDC.REG_DATA.RES.NOT_WRITABLE","pushResults","FDC.REG_DATA.CMD.RECALIBRATE","FDC.REG_DATA.RES.SEEK_END","FDC.REG_DATA.RES.TRACK0","FDC.REG_DATA.CMD.SENSE_INT","FDC.REG_DATA.RES.ST0","FDC.REG_DATA.CMD.READ_ID","FDC.REG_DATA.CMD.FORMAT_TRACK","bFiller","cbFormat","abFormat","cSectorsFormatted","FDC.REG_DATA.CMD.SEEK","inFDCInput","outFDCControl","pushST0","pushST1","FDC.REG_DATA.RES.ST1","pushST2","FDC.REG_DATA.RES.ST2","FDC.REG_DATA.CMD.MT","fCondition","bResult","FDC_prototype$doDMARead","readData","FDC_prototype$doDMAWrite","writeData","FDC.REG_DATA.RES.NO_DATA","advanceSector","FDC.REG_DATA.RES.CRC_ERROR","bSectorStart","INT_ENABLE","BUSY","READ_DATA","RQM","SPECIFY","SENSE_DRIVE","WRITE_DATA","RECALIBRATE","SENSE_INT","READ_ID","FORMAT_TRACK","SEEK","MT","RES","NOT_READY","SEEK_END","INCOMPLETE","ST0","NOT_WRITABLE","NO_DATA","CRC_ERROR","ST1","ST2","TRACK0","ST3","DISK_CHANGE","RATE500K","cbRes","FDC.CMDS.SPECIFY","FDC.CMDS.SENSE_DRIVE","FDC.CMDS.WRITE_DATA","FDC.CMDS.READ_DATA","FDC.CMDS.RECALIBRATE","FDC.CMDS.SENSE_INT","FDC.CMDS.READ_ID","FDC.CMDS.FORMAT","FDC.CMDS.SEEK","aeFDC","iFDC","eFDC","parmsHDC","doDMAWriteBuffer","doDMAWriteFormat","aDriveConfigs","sDriveConfigs","fATC","HDC.prototype","hdc","onClickSaveDrive","iDriveTable","iDriveTypeDefault","HDC.aATCPortInput","HDC.aXTCPortInput","HDC.aATCPortOutput","HDC.aXTCPortOutput","HDC.ATC.DATA.PORT","intBIOSDisk","ALT_DISK","intBIOSDiskette","sMachineID","sUserID","HDC.ATC.STATUS.READY","regError","regWPreC","regSecCnt","regSecNum","regCylLo","regCylHi","regDrvHd","regCommand","regFDR","HDC.XTC.STATUS.NONE","regConfig","regReset","regPulse","regPattern","iDriveAllowFail","driveConfig","HDC.XTC.DATA.ERR.NONE","errorCode","senseCode","abDriveParms","abSector","wCylinder","bSectorBias","HDC.DEFAULT_DRIVE_NAME","path","HDC.aDriveTypes","driveType","bExt","bOrig","HDRIVE","iExt","setCMOSByte","verifyDrive","loadDisk","doneLoadDisk","HDC.aDriveTables","inXTCData","HDC.XTC.STATUS.INTERRUPT","HDC.XTC.STATUS.IOMODE","HDC.XTC.STATUS.BUS","HDC.XTC.STATUS.BUSY","outXTCData","cbCmd","HDC.XTC.DATA.CMD.INIT_DRIVE","HDC.XTC.STATUS.REQ","doXTC","inXTCStatus","outXTCReset","inXTCConfig","outXTCPulse","outXTCPattern","outXTCNoise","inATCByte","onATCReadData","HDC.ATC.STATUS.BUSY","onATCReadDataNext","setATCIRR","HDC.ATC.STATUS.SEEK_OK","HDC.ATC.STATUS.DATA_REQ","HDC.ATC.STATUS.ERROR","HDC.ATC.ERROR.NO_CHS","HDC_prototype$inATCData","outATCByte","outATCData","inATCError","outATCWPreC","inATCSecCnt","outATCSecCnt","inATCSecNum","outATCSecNum","inATCCylLo","outATCCylLo","inATCCylHi","outATCCylHi","inATCDrvHd","outATCDrvHd","HDC.ATC.DRVHD.DRIVE_MASK","inATCStatus","outATCCommand","doATC","outATCFDR","HDC.ATC.FDR.RESET","HDC.ATC.DIAG.NO_ERROR","fInterrupt","nHead","HDC.ATC.DRVHD.HEAD_MASK","nCylinder","HDC.ATC.CYLHI.MASK","nSector","HDC.ATC.ERROR.NONE","HDC.ATC.COMMAND.DIAGNOSE","HDC.ATC.COMMAND.MASK","HDC.ATC.COMMAND.RESTORE","HDC.ATC.COMMAND.READ_DATA","onATCReadDataFirst","HDC.ATC.COMMAND.WRITE_DATA","HDC.ATC.COMMAND.READ_VERF","HDC.ATC.COMMAND.SEEK","HDC.ATC.COMMAND.SETPARMS","HDC.ATC.FDR.INT_DISABLE","bCount","HDC.XTC.DATA.CMD.REQUEST_SENSE","HDC.XTC.DATA.ERR.NOT_READY","HDC.XTC.DATA.STATUS.OK","bParm","bDataStatus","HDC.XTC.DATA.STATUS.ERROR","HDC.XTC.DATA.CMD.RAM_DIAGNOSTIC","HDC.XTC.DATA.CMD.CTL_DIAGNOSTIC","HDC.XTC.DATA.CMD.TEST_READY","HDC.XTC.DATA.CMD.RECALIBRATE","HDC.XTC.DATA.CMD.READ_VERF","HDC.XTC.DATA.CMD.READ_DATA","doRead","onXTCReadDataCommand","HDC.XTC.DATA.CMD.WRITE_DATA","doWrite","onXTCWriteDataCommand","HDC.XTC.DATA.CMD.WRITE_BUFFER","doWriteBuffer","onXTCWriteBufferCommand","HDC_prototype$doDMARead","HDC_prototype$doDMAWrite","HDC.XTC.DATA.ERR.NO_SECTOR","ChipSet.DMA_HDC","onDMAReadRequest","onDMAWriteRequest","onDMAWriteBufferRequest","fAutoInc","onReadDataSeek","onWriteDataSeek","NO_ERROR","ERROR","NO_CHS","CYLHI","HEAD_MASK","DRVHD","DRIVE_MASK","DATA_REQ","SEEK_OK","READY","RESTORE","READ_VERF","DIAGNOSE","SETPARMS","INT_DISABLE","FDR","TEST_READY","REQUEST_SENSE","INIT_DRIVE","WRITE_BUFFER","RAM_DIAGNOSTIC","CTL_DIAGNOSTIC","NO_SECTOR","REQ","IOMODE","INTERRUPT","aeHDC","iHDC","eHDC","Debugger","parmsDbg","nBase","achGroup","achAddress","cOpcodes","cOpcodesStart","fAssemble","iPrevCmd","aPrevCmds","aVariables","getRegIndex","getRegValue","parseAddrReference","sAddr","parseCommand","sCmd","chSep","iPrev","truncate","nBits","fUnsigned","vNew","evalOps","aVals","cOps","chOp","pop","val2","val1","valNew","parseArray","asValues","iValue","iLimit","aUndefined","nUnary","nBasePrev","sOp","parseValue","cOpen","parseUnary","aBinOp","Debugger.aDECOpPrecedence","Debugger.aBinOpPrecedence","parseASCII","sExp","chDelim","toStrBase","parseExpression","fPrint","join","regExp","printValue","parseReference","chOpen","chClose","chEscape","chInnerEscape","reSubExp","parseSysVars","getVariable","sVar","sUndefined","getVariableFixup","valueUndefined","fDefined","printVariable","cVariables","aVars","Str.toOct","DebuggerX86","cchReg","cchAddr","dbgAddrNextCode","newAddr","dbgAddrNextData","dbgAddrAssemble","aSymbolTable","aBreakExec","aBreakRead","aBreakWrite","clearBreakpoints","nBreakIns","historyInit","afnDumpers","messageInit","sCommandsInit","doCommands","global","DebuggerX86.prototype","sMessages","segDebugger","DBG","aaOpDescs","DebuggerX86.aaOpDescs","DebuggerX86.aaOpDescs.slice","DebuggerX86.aOpDescUndefined","DebuggerX86.aOpDesc0F","onDumpBus","dumpBlocks","onDumpSel","sSel","getSegment","DebuggerX86.ADDRTYPE.PROT","fGate","sysDesc","DebuggerX86.SYSDESCS","getLimitString","onDumpDOS","mcb","sMCB","dbgAddr","bSig","wPID","wParas","toHexOffset","getSZ","onDumpMem","onDumpTSS","aTSSFields","DebuggerX86.TSS286","DebuggerX86.TSS386","sField","iPort","fWinDbg","cTrapFaults","fIgnoreNextCheckFault","WINCB","intWindowsCallBack","intWindowsDebugger","fWinDbgRM","WINDBGRM","intWindowsDebuggerRM","addSegmentInfo","nSegment","fCode","sSection","findModuleInfo","addSectionInfo","dbgAddrModule","dbgAddrParent","sParent","removeSectionInfo","removeSymbols","DX","SI","EAX","AX","BX","DI","ES","onInt41Return","removeSegmentInfo","findBreakpoint","toHexAddr","onInt68Return","callWindowsDebuggerPMInit","controlDebug","setSelectionRange","Web.onClickRepeat","onClickDebugEnter","sCommands","onClickStep","fRepeat","fCompleted","getCPUMode","typeDefault","getAddressType","DebuggerX86.ADDRTYPE.REAL","nSuppressBreaks","DebuggerX86_prototype$getByte","DebuggerX86.ADDRTYPE.PHYSICAL","incAddr","fAdvance","fData32","DebuggerX86_prototype$getShort","DebuggerX86_prototype$setByte","fNoUpdate","DebuggerX86_prototype$setShort","fAddr32","setAddr","fTempBreak","packAddr","cOverrides","unpackAddr","aAddr","checkLimit","fUpdate","parseAddr","fNoChecks","dbgAddrNext","DebuggerX86.ADDRTYPE.NONE","iColon","DebuggerX86.ADDRTYPE.LINEAR","sUpperCase","iTable","findSymbolAddr","symbolTable","offSymbol","selSymbol","parseAddrOptions","sOptions","aCmds","DebuggerX86.ADDRTYPE.V86","fLinear","typePrev","cPrev","getPageEntry","addrPE","lPE","fPTE","iFile","segment","entry","sEnable","sMessagePrev","aMessageBuffer","aEnable","Usr.indexOf","bitMessage","fnDumper","DebuggerX86.REGS","getRegString","DebuggerX86.REG_AL","DebuggerX86.REG_CL","DebuggerX86.REG_DL","DebuggerX86.REG_BL","DebuggerX86.REG_AH","DebuggerX86.REG_CH","DebuggerX86.REG_DH","DebuggerX86.REG_BH","DebuggerX86.REG_AX","DebuggerX86.REG_CX","DebuggerX86.REG_DX","DebuggerX86.REG_BX","DebuggerX86.REG_SP","DebuggerX86.REG_BP","DebuggerX86.REG_SI","DebuggerX86.REG_DI","DebuggerX86.REG_IP","DebuggerX86.REG_SEG","DebuggerX86.REG_ES","DebuggerX86.REG_CS","DebuggerX86.REG_SS","DebuggerX86.REG_DS","DebuggerX86.REG_FS","DebuggerX86.REG_GS","DebuggerX86.REG_EAX","DebuggerX86.REG_ECX","DebuggerX86.REG_EDX","DebuggerX86.REG_EBX","DebuggerX86.REG_ESP","DebuggerX86.REG_EBP","DebuggerX86.REG_ESI","DebuggerX86.REG_EDI","DebuggerX86.REG_CR0","DebuggerX86.REG_CR1","DebuggerX86.REG_CR2","DebuggerX86.REG_CR3","DebuggerX86.REG_EIP","DebuggerX86.REG_PS","replaceRegs","sChar","fMessage","DebuggerX86.INT_ANNOYING.indexOf","nCategory","DebuggerX86.INT_MESSAGES","aFuncs","Interrupts.FUNCS","selFrom","aOpcodeHistory","DebuggerX86.HISTORY_LIMIT","iOpcodeHistory","aaOpcodeCounts","fRegs","fUpdateCPU","checkCPU","nCyclesStep","nStep","doRegisters","doUnassemble","clearTempBreakpoint","restoreBreakpoints","sStopped","msTotal","nState","checkBreakpoint","cycleCount","aBreak","printBreakpoint","fFound","mapBreakpoint","dbgAddrBreak","listBreakpoints","sAction","aDbgAddr","fBreak","addrBreak","doCommand","getInstruction","sComment","nSequence","dbgAddrIns","cMaxOverrides","fDataPrefix","fAddrPrefix","asOpcodes","DebuggerX86.INS_NAMES","aOpDesc","iIns","DebuggerX86.INS.OP0F","DebuggerX86.aaOp0FDescs","DebuggerX86.INS.ESC","aaOpDesc","DebuggerX86.aaaOpFPUDescs","aOpFPUDesc","DebuggerX86.FINS_NAMES","DebuggerX86.aaGrpDescs","sOpcode","cOperands","sOperands","DebuggerX86.INS.CBW","DebuggerX86.INS.CWD","DebuggerX86.INS.POPA","DebuggerX86.INS.PUSHA","typeCPU","iOperand","sOperand","DebuggerX86.TYPE_CPU_SHIFT","DebuggerX86.INS.LOADALL","DebuggerX86.CPU_80286","DebuggerX86.CPU_80386","typeSize","DebuggerX86.TYPE_SIZE","DebuggerX86.TYPE_NONE","DebuggerX86.TYPE_PREFIX","typeMode","DebuggerX86.TYPE_MODE","DebuggerX86.TYPE_MODRM","DebuggerX86.TYPE_MODREG","bMod","bRM","fInteger","getSIBOperand","bScale","bBase","DebuggerX86.RMS","DebuggerX86.TYPE_WORD","DebuggerX86.TYPE_LONG","DebuggerX86.TYPE_SHORT","DebuggerX86.TYPE_FARP","DebuggerX86.TYPE_BYTE","DebuggerX86.TYPE_SINT","DebuggerX86.TYPE_SREAL","DebuggerX86.TYPE_LINT","DebuggerX86.TYPE_LREAL","DebuggerX86.TYPE_TREAL","DebuggerX86.TYPE_BCD80","getRegOperand","DebuggerX86.TYPE_ONE","DebuggerX86.TYPE_IMM","getImmOperand","DebuggerX86.TYPE_BOTH","DebuggerX86.TYPE_SBYTE","aSymbol","findSymbol","DebuggerX86.TYPE_IMMOFF","DebuggerX86.TYPE_IMMREL","DebuggerX86.TYPE_IMPREG","DebuggerX86.TYPE_ST","DebuggerX86.TYPE_STREG","DebuggerX86.TYPE_IREG","DebuggerX86.TYPE_IMPSEG","DebuggerX86.TYPE_SEGREG","DebuggerX86.TYPE_DSSI","DebuggerX86.TYPE_ESDI","sBytes","sLine","DebuggerX86.CPUS","initAddrSize","bReg","DebuggerX86.TYPE_CTLREG","DebuggerX86.TYPE_DBGREG","DebuggerX86.REG_DR0","DebuggerX86.TYPE_TSTREG","DebuggerX86.REG_TR0","getFlagOutput","sFlag","getRegOutput","getSegOutput","getDTROutput","getRegDump","sTR","sA20","comparePairs","aOffsets","sAnnotation","Usr.binarySearch","fNearest","addrSymbol","returnSymbol","iOffset","doFreqs","cData","aaSortedOpcodeCounts","cFreq","doVar","delVariable","setVariable","doList","sDelta","doLoad","fJSON","dc","clearPanel","doClear","fAbort","dbgAddrCur","fInstruction","doFPURegisters","wStatus","wControl","aTR","DebuggerX86.FPU_TAGS","sRegMatch","fUnknown","doPrint","getCall","fFar","sCall","offOrig","doTrace","sCount","nCount","Web.onCountRepeat","onCountStep","onCountStepComplete","fData32Orig","fAddr32Orig","sAddrEnd","dbgAddrEnd","cLines","sInstruction","s0","ch0","doAssemble","aOpBytes","doBreak","cBreaks","sLen","sDumpers","doDump","sState","powerOff","sSymbolOrig","pageInfo","addrPDE","lPDE","addrPTE","lPTE","addrPhys","sCmdDumpPrev","sMore","cHistory","iHistory","aHistory","nPrev","sPrev","nextHistory","nLines","sLines","aFilters","dbgAddrNew","sIDT","sInfo","fASCII","cbLine","fnGet","doEdit","vOld","doRun","doHalt","doIf","doInt","sInt","sPort","doInput","doStackTrace","cFrames","dbgAddrCall","dbgAddrStack","nFrames","cTests","sCallPrev","doMouse","fCriteria","sCategory","doMessages","sCategories","doOutput","sByte","nRegs","doStep","doExecOptions","DebuggerX86.COMMANDS","doHelp","DebuggerX86.INT_ANNOYING","ALT_TIMER","DOS_IDLE","DOS_NETBIOS","ALT_VIDEO","REAL","PROT","V86","LINEAR","PHYSICAL","CBW","CWD","LOADALL","POPA","PUSHA","OP0F","DebuggerX86.TYPE_AL","DebuggerX86.TYPE_CL","DebuggerX86.TYPE_AX","DebuggerX86.TYPE_CX","DebuggerX86.TYPE_DX","DebuggerX86.TYPE_BX","DebuggerX86.TYPE_SP","DebuggerX86.TYPE_BP","DebuggerX86.TYPE_SI","DebuggerX86.TYPE_DI","DebuggerX86.TYPE_ES","DebuggerX86.TYPE_CS","DebuggerX86.TYPE_SS","DebuggerX86.TYPE_DS","DebuggerX86.TYPE_FS","DebuggerX86.TYPE_GS","DebuggerX86.TYPE_80286","DebuggerX86.TYPE_80386","ADD","DebuggerX86.TYPE_IN","DebuggerX86.TYPE_REG","PUSH","POP","DebuggerX86.TYPE_OUT","OR","DebuggerX86.aOpDescPopCS","ADC","SBB","AND","DAA","SUB","CS","DAS","XOR","SS","AAA","CMP","DS","AAS","INC","DEC","BOUND","ARPL","FS","GS","OS","AS","IMUL","OUTS","JO","JNO","JC","JNC","JZ","JNZ","JBE","JA","JS","JNS","JP","JNP","JL","JGE","JLE","JG","GRP1B","GRP1W","GRP1SW","TEST","XCHG","MOV","LEA","DebuggerX86.TYPE_MODMEM","NOP","CALL","PUSHF","POPF","SAHF","LAHF","MOVSB","MOVSW","CMPSB","CMPSW","STOSB","STOSW","LODSB","LODSW","SCASB","SCASW","GRP2B","DebuggerX86.TYPE_80186","GRP2W","RET","LES","LDS","LEAVE","RETF","INT3","INTO","IRET","GRP2B1","GRP2W1","GRP2BC","GRP2WC","AAM","AAD","SALC","XLAT","LOOPNZ","LOOPZ","LOOP","JCXZ","IN","OUT","JMP","LOCK","REPNZ","REPZ","HLT","CMC","GRP3B","GRP3W","CLC","STC","CLI","STI","CLD","STD","GRP4B","GRP4W","GRP6","GRP7","LAR","LSL","CLTS","SETO","SETNO","SETC","SETNC","SETZ","SETNZ","SETBE","SETNBE","SETS","SETNS","SETP","SETNP","SETL","SETGE","SETLE","SETG","BT","SHLD","XBTS","IBTS","BTS","SHRD","LSS","BTR","LFS","LGS","MOVZX","GRP8","BTC","BSF","BSR","MOVSX","FADD","FMUL","FCOM","FCOMP","FSUB","FSUBR","FDIV","FDIVR","FLD","FST","FSTP","FLDENV","FLDCW","FSTENV","FSTCW","FXCH","FNOP","FCHS","FABS","FTST","FXAM","FLD1","FLDL2T","FLDL2E","FLDPI","FLDLG2","FLDLN2","FLDZ","F2XM1","FYL2X","FPTAN","FPATAN","FXTRACT","FDECSTP","FINCSTP","FPREM","FYL2XP1","FSQRT","FRNDINT","FSCALE","FIADD","FIMUL","FICOM","FICOMP","FISUB","FISUBR","FIDIV","FIDIVR","FILD","FIST","FISTP","FENI","FDISI","FCLEX","FINIT","FSETPM","FSINCOS","FRSTOR","FSAVE","FSTSW","FFREE","FADDP","FMULP","FCOMPP","FSUBRP","FSUBP","FDIVRP","FDIVP","FBLD","FBSTP","FFREEP","FSTSWAX","ROL","ROR","RCL","RCR","SHL","SHR","SAR","NOT","NEG","MUL","DIV","IDIV","SLDT","STR","LLDT","LTR","VERR","VERW","SGDT","SIDT","LGDT","LIDT","SMSW","LMSW","aeDbg","iDbg","eDbg","Computer","parmsComputer","parmsMachine","fSuspended","setMachineParms","fAutoPower","nDiagnostics","nPowerChange","resume","Computer.RESUME_NONE","sStateData","fServerState","fStateData","url","queryUserID","controlPanel","noticeComputer","printComputer","printlnComputer","outputDiagnostics","cDiagnosticScreens","enableDiagnostics","updateStatusTimer","Computer.UPDATES_PER_SECOND","sResume","sResumePath","fAllowResume","stateComputer","getServerStatePath","sStateURL","sResource","wait","lineHeight","parmsComponent","Computer.prototype","onComponentReady","validateState","stateValidate","Computer.STATE_VALIDATE","sTimestampValidate","Computer.STATE_TIMESTAMP","sTimestampComputer","clear","Computer.RESUME_AUTO","fRestore","fRestoreError","stateFailSafe","Computer.STATE_FAILSAFE","powerReport","Computer.RESUME_PROMPT","unload","store","fValidate","FAIL","Web.setLocalStorageItem","Computer.STATE_USERID","resetUserID","powerRestore","donePowerOn","reload","asComments","disableDiagnostics","controlPower","QUERY","sUser","sReport","sReportURL","sTimestamp","Computer.STATE_VERSION","Computer.STATE_HOSTURL","Computer.STATE_BROWSER","fClearAll","fClear","saveServerState","Computer.RESUME_DELETE","fPrompt","Web.getLocalStorageItem","verifyUserID","State.key","storeServerState","fScroll","scrollX","scrollY","scrollTo","getFS","getGS","getSpeedCurrent","aeMachines","iMachine","eMachine","aeComputers","iComputer","eComputer","show","exit","sVersion","json","fLoaded","fParsed","State.prototype","Web.hasLocalStorage","cAsyncMachines","loadXML","sXMLFile","fResolve","doneLoadXML","sURLName","sXML","parseXML","buildXML","pathname","xmlDoc","async","parseFromString","DOMParser","resolveXML","matchRef","reRef","sRefFile","doneReadXML","sXMLRef","sRefAttrs","aXMLRefTag","sXMLNewTag","matchAttr","reAttr","embedMachine","sXSLFile","displayMessage","eWarning","aeWarning","Str.escapeHTML","displayError","Web.enablePageEvents","getElementById","css","styleSheet","cssText","createTextNode","processXML","xml","transformXML","sXSL","xsl","sFragment","outerHTML","implementation","createDocument","xsltProcessor","XSLTProcessor","eFragment","replaceChild","embedPCx86","commandMachine","fSingle","sComponent","downloadCSS","sPCJS","aMachineInfo","res","sCSSFile","downloadPC","sCSS","matchScript","resOld","resNew","sExt","reDisk","matchDisk","sResources","savePC","sPCJSFile"],"sourcesContent":["\"use strict\";\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/defines.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @define {string}\n */\nvar APPVERSION = \"\"; // this @define is overridden by the Closure Compiler with the version in machines.json\n\nvar XMLVERSION = null; // this is set in non-COMPILED builds by embedMachine() if a version number was found in the machine XML\n\nvar COPYRIGHT = \"Copyright © 2012-2018 Jeff Parsons <Jeff@pcjs.org>\";\n\nvar LICENSE = \"License: GPL version 3 or later <http://gnu.org/licenses/gpl.html>\";\n\nvar CSSCLASS = \"pcjs\";\n\n/**\n * @define {string}\n */\nvar SITEHOST = \"localhost:8088\";// this @define is overridden by the Closure Compiler with \"www.pcjs.org\"\n\n/**\n * @define {boolean}\n */\nvar COMPILED = false; // this @define is overridden by the Closure Compiler (to true)\n\n/**\n * @define {boolean}\n */\nvar DEBUG = true; // this @define is overridden by the Closure Compiler (to false) to remove DEBUG-only code\n\n/**\n * @define {boolean}\n */\nvar MAXDEBUG = false; // this @define is overridden by the Closure Compiler (to false) to remove MAXDEBUG-only code\n\n/**\n * @define {boolean}\n */\nvar PRIVATE = false; // this @define is overridden by the Closure Compiler (to false) to enable PRIVATE code\n\n/*\n * RS-232 DB-25 Pin Definitions, mapped to bits 1-25 in a 32-bit status value.\n *\n * SerialPorts in PCjs machines are considered DTE (Data Terminal Equipment), which means they should be \"virtually\"\n * connected to each other via a null-modem cable, which assumes the following cross-wiring:\n *\n * G 1 <-> 1 G (Ground)\n * TD 2 <-> 3 RD (Received Data)\n * RD 3 <-> 2 TD (Transmitted Data)\n * RTS 4 <-> 5 CTS (Clear To Send)\n * CTS 5 <-> 4 RTS (Request To Send)\n * DSR 6+8 <-> 20 DTR (Data Terminal Ready)\n * SG 7 <-> 7 SG (Signal Ground)\n * DTR 20 <-> 6+8 DSR (Data Set Ready + Carrier Detect)\n * RI 22 <-> 22 RI (Ring Indicator)\n *\n * TODO: Move these definitions to a more appropriate shared file at some point.\n */\nvar RS232 = {\n RTS: {\n PIN: 4,\n MASK: 0x00000010\n },\n CTS: {\n PIN: 5,\n MASK: 0x00000020\n },\n DSR: {\n PIN: 6,\n MASK: 0x00000040\n },\n CD: {\n PIN: 8,\n MASK: 0x00000100\n },\n DTR: {\n PIN: 20,\n MASK: 0x00100000\n },\n RI: {\n PIN: 22,\n MASK: 0x00400000\n }\n};\n\n/*\n * NODE should be true if we're running under NodeJS (eg, command-line), false if not (eg, web browser)\n */\nvar NODE = false;\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/diskapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Our \"DiskIO API\" looks like:\n *\n * http://www.pcjs.org/api/v1/disk?action=open&volume=*10mb.img&mode=demandrw&chs=c:h:s&machine=xxx&user=yyy\n */\nvar DiskAPI = {\n ENDPOINT: \"/api/v1/disk\",\n QUERY: {\n ACTION: \"action\", // value is one of DiskAPI.ACTION.*\n VOLUME: \"volume\", // value is path of a disk image\n MODE: \"mode\", // value is one of DiskAPI.MODE.*\n CHS: \"chs\", // value is cylinders:heads:sectors:bytes\n ADDR: \"addr\", // value is cylinder:head:sector:count\n MACHINE: \"machine\", // value is machine token\n USER: \"user\", // value is user ID\n DATA: \"data\" // value is data to be written\n },\n ACTION: {\n OPEN: \"open\",\n READ: \"read\",\n WRITE: \"write\",\n CLOSE: \"close\"\n },\n MODE: {\n LOCAL: \"local\", // this mode implies no API (at best, localStorage backing only)\n PRELOAD: \"preload\", // this mode implies use of the DumpAPI\n DEMANDRW: \"demandrw\",\n DEMANDRO: \"demandro\"\n },\n FAIL: {\n BADACTION: \"invalid action\",\n BADUSER: \"invalid user\",\n BADVOL: \"invalid volume\",\n OPENVOL: \"unable to open volume\",\n CREATEVOL: \"unable to create volume\",\n WRITEVOL: \"unable to write volume\",\n REVOKED: \"access revoked\"\n }\n};\n\n/*\n * TODO: Eventually, our tools will need to support looking up disk formats by \"model\" rather than by raw disk size,\n * because obviously multiple disk geometries can yield the same raw disk size. For each conflict that arises, I'll\n * probably create a fake (approximate) disk size entry above, and then create a mapping to that approximate size below.\n */\nDiskAPI.MODELS = {\n \"RL01\": 5242880,\n \"RL02\": 10485760\n};\n\nDiskAPI.MBR = {\n PARTITIONS: {\n OFFSET: 0x1BE,\n ENTRY: {\n STATUS: 0x00, // 1-byte (0x80 if active)\n CHS_FIRST: 0x01, // 3-byte CHS specifier\n TYPE: 0x04, // 1-byte TYPE (see below)\n CHS_LAST: 0x05, // 3-byte CHS specifier\n LBA_FIRST: 0x08, // 4-byte Logical Block Address\n LBA_TOTAL: 0x0C, // 4-byte Logical Block Address\n },\n ENTRY_LENGTH: 0x10,\n STATUS: {\n ACTIVE: 0x80\n },\n TYPE: {\n EMPTY: 0x00,\n FAT12_PRIMARY: 0x01, // DOS 2.0 and up (12-bit FAT)\n FAT16_PRIMARY: 0x04 // DOS 3.0 and up (16-bit FAT)\n }\n },\n SIG_OFFSET: 0x1FE,\n SIGNATURE: 0xAA55 // to be clear, the low byte (at offset 0x1FE) is 0x55 and the high byte (at offset 0x1FF) is 0xAA\n};\n\n/*\n * Boot sector offsets (and assorted constants) in DOS-compatible boot sectors (DOS 2.0 and up)\n *\n * WARNING: I've heard apocryphal stories about SIGNATURE being improperly reversed on some systems\n * (ie, 0x55AA instead 0xAA55) -- perhaps by a dyslexic programmer -- so be careful out there.\n */\nDiskAPI.BOOT = {\n JMP_OPCODE: 0x000, // 1 byte for a JMP opcode, followed by a 1 or 2-byte offset\n OEM_STRING: 0x003, // 8 bytes\n SIG_OFFSET: 0x1FE,\n SIGNATURE: 0xAA55 // to be clear, the low byte (at offset 0x1FE) is 0x55 and the high byte (at offset 0x1FF) is 0xAA\n};\n\n/*\n * BIOS Parameter Block (BPB) offsets in DOS-compatible boot sectors (DOS 2.x and up)\n *\n * NOTE: DOS 2.x OEM documentation says that the words starting at offset 0x018 (TRACK_SECS, TOTAL_HEADS, and HIDDEN_SECS)\n * are optional, but even the DOS 2.0 FORMAT utility initializes all three of those words. There may be some OEM media out\n * there with BPBs that are only valid up to offset 0x018, but I've not run across any media like that.\n *\n * DOS 3.20 added LARGE_SECS, but unfortunately, it was added as a 2-byte value at offset 0x01E. DOS 3.31 decided\n * to make both HIDDEN_SECS and LARGE_SECS 4-byte values, which meant that LARGE_SECS had to move from 0x01E to 0x020.\n */\nDiskAPI.BPB = {\n SECTOR_BYTES: 0x00B, // 2 bytes: bytes per sector (eg, 0x200 or 512)\n CLUSTER_SECS: 0x00D, // 1 byte: sectors per cluster (eg, 1)\n RESERVED_SECS: 0x00E, // 2 bytes: reserved sectors; ie, # sectors preceding the first FAT--usually just the boot sector (eg, 1)\n TOTAL_FATS: 0x010, // 1 byte: FAT copies (eg, 2)\n ROOT_DIRENTS: 0x011, // 2 bytes: root directory entries (eg, 0x40 or 64) 0x40 * 0x20 = 0x800 (1 sector is 0x200 bytes, total of 4 sectors)\n TOTAL_SECS: 0x013, // 2 bytes: number of sectors (eg, 0x140 or 320); if zero, refer to LARGE_SECS\n MEDIA_ID: 0x015, // 1 byte: media ID (see DiskAPI.FAT.MEDIA_*); should also match the first byte of the FAT (aka FAT ID)\n FAT_SECS: 0x016, // 2 bytes: sectors per FAT (eg, 1)\n TRACK_SECS: 0x018, // 2 bytes: sectors per track (eg, 8)\n TOTAL_HEADS: 0x01A, // 2 bytes: number of heads (eg, 1)\n HIDDEN_SECS: 0x01C, // 2 bytes (DOS 2.x) or 4 bytes (DOS 3.31 and up): number of hidden sectors (always 0 for non-partitioned media)\n LARGE_SECS: 0x020 // 4 bytes (DOS 3.31 and up): number of sectors if TOTAL_SECS is zero\n};\n\n/*\n * Common (supported) diskette geometries.\n *\n * Each entry in GEOMETRIES is an array of values in \"CHS\" order:\n *\n * [# cylinders, # heads, # sectors/track, # bytes/sector, media ID]\n *\n * If the 4th value is omitted, the sector size is assumed to be 512. The order of these \"geometric\" values mirrors\n * the structure of our JSON-encoded disk images, which consist of an array of cylinders, each of which is an array of\n * heads, each of which is an array of sector objects.\n */\nDiskAPI.GEOMETRIES = {\n 163840: [40,1,8,,0xFE], // media ID 0xFE: 40 cylinders, 1 head (single-sided), 8 sectors/track, ( 320 total sectors x 512 bytes/sector == 163840)\n 184320: [40,1,9,,0xFC], // media ID 0xFC: 40 cylinders, 1 head (single-sided), 9 sectors/track, ( 360 total sectors x 512 bytes/sector == 184320)\n 327680: [40,2,8,,0xFF], // media ID 0xFF: 40 cylinders, 2 heads (double-sided), 8 sectors/track, ( 640 total sectors x 512 bytes/sector == 327680)\n 368640: [40,2,9,,0xFD], // media ID 0xFD: 40 cylinders, 2 heads (double-sided), 9 sectors/track, ( 720 total sectors x 512 bytes/sector == 368640)\n 737280: [80,2,9,,0xF9], // media ID 0xF9: 80 cylinders, 2 heads (double-sided), 9 sectors/track, (1440 total sectors x 512 bytes/sector == 737280)\n 1228800: [80,2,15,,0xF9], // media ID 0xF9: 80 cylinders, 2 heads (double-sided), 15 sectors/track, (2400 total sectors x 512 bytes/sector == 1228800)\n 1474560: [80,2,18,,0xF0], // media ID 0xF0: 80 cylinders, 2 heads (double-sided), 18 sectors/track, (2880 total sectors x 512 bytes/sector == 1474560)\n 2949120: [80,2,36,,0xF0], // media ID 0xF0: 80 cylinders, 2 heads (double-sided), 36 sectors/track, (5760 total sectors x 512 bytes/sector == 2949120)\n /*\n * The following are some common disk sizes and their CHS values, since missing or bogus MBR and/or BPB values\n * might mislead us when attempting to determine the exact disk geometry.\n */\n 10653696:[306,4,17], // PC XT 10Mb hard drive (type 3)\n 21411840:[615,4,17], // PC AT 20Mb hard drive (type 2)\n /*\n * Assorted DEC disk formats.\n */\n 256256: [77, 1,26,128], // RX01 single-platter diskette: 77 tracks, 1 head, 26 sectors/track, 128 bytes/sector, for a total of 256256 bytes\n 2494464: [203,2,12,512], // RK03 single-platter disk cartridge: 203 tracks, 2 heads, 12 sectors/track, 512 bytes/sector, for a total of 2494464 bytes\n 5242880: [256,2,40,256], // RL01K single-platter disk cartridge: 256 tracks, 2 heads, 40 sectors/track, 256 bytes/sector, for a total of 5242880 bytes\n 10485760:[512,2,40,256] // RL02K single-platter disk cartridge: 512 tracks, 2 heads, 40 sectors/track, 256 bytes/sector, for a total of 10485760 bytes\n};\n\n/*\n * Media ID (descriptor) bytes for DOS-compatible FAT-formatted disks (stored in the first byte of the FAT)\n */\nDiskAPI.FAT = {\n MEDIA_160KB: 0xFE, // 5.25-inch, 1-sided, 8-sector, 40-track\n MEDIA_180KB: 0xFC, // 5.25-inch, 1-sided, 9-sector, 40-track\n MEDIA_320KB: 0xFF, // 5.25-inch, 2-sided, 8-sector, 40-track\n MEDIA_360KB: 0xFD, // 5.25-inch, 2-sided, 9-sector, 40-track\n MEDIA_720KB: 0xF9, // 3.5-inch, 2-sided, 9-sector, 80-track\n MEDIA_1200KB: 0xF9, // 3.5-inch, 2-sided, 15-sector, 80-track\n MEDIA_FIXED: 0xF8, // fixed disk (aka hard drive)\n MEDIA_1440KB: 0xF0, // 3.5-inch, 2-sided, 18-sector, 80-track\n MEDIA_2880KB: 0xF0 // 3.5-inch, 2-sided, 36-sector, 80-track\n};\n\n/*\n * Cluster constants for 12-bit FATs (CLUSNUM_FREE, CLUSNUM_RES and CLUSNUM_MIN are the same for all FATs)\n */\nDiskAPI.FAT12 = {\n MAX_CLUSTERS: 4084,\n CLUSNUM_FREE: 0, // this should NEVER appear in cluster chain (except at the start of an empty chain)\n CLUSNUM_RES: 1, // reserved; this should NEVER appear in cluster chain\n CLUSNUM_MIN: 2, // smallest valid cluster number\n CLUSNUM_MAX: 0xFF6, // largest valid cluster number\n CLUSNUM_BAD: 0xFF7, // bad cluster; this should NEVER appear in cluster chain\n CLUSNUM_EOC: 0xFF8 // end of chain (actually, anything from 0xFF8-0xFFF indicates EOC)\n};\n\n/*\n * Cluster constants for 16-bit FATs (CLUSNUM_FREE, CLUSNUM_RES and CLUSNUM_MIN are the same for all FATs)\n */\nDiskAPI.FAT16 = {\n MAX_CLUSTERS: 65524,\n CLUSNUM_FREE: 0, // this should NEVER appear in cluster chain (except at the start of an empty chain)\n CLUSNUM_RES: 1, // reserved; this should NEVER appear in cluster chain\n CLUSNUM_MIN: 2, // smallest valid cluster number\n CLUSNUM_MAX: 0xFFF6, // largest valid cluster number\n CLUSNUM_BAD: 0xFFF7, // bad cluster; this should NEVER appear in cluster chain\n CLUSNUM_EOC: 0xFFF8 // end of chain (actually, anything from 0xFFF8-0xFFFF indicates EOC)\n};\n\n/*\n * Directory Entry offsets (and assorted constants) in FAT disk images\n *\n * NOTE: Versions of DOS prior to 2.0 used INVALID exclusively to mark available directory entries; any entry marked\n * UNUSED was actually considered USED. In DOS 2.0 and up, UNUSED was added to indicate that all remaining entries were\n * unused, relieving it from having to initialize the rest of the sectors in the directory cluster(s). And in fact,\n * you will likely encounter garbage in subsequent directory sectors if you read beyond the first UNUSED entry.\n */\nDiskAPI.DIRENT = {\n NAME: 0x000, // 8 bytes\n EXT: 0x008, // 3 bytes\n ATTR: 0x00B, // 1 byte\n MODTIME: 0x016, // 2 bytes\n MODDATE: 0x018, // 2 bytes\n CLUSTER: 0x01A, // 2 bytes\n SIZE: 0x01C, // 4 bytes (typically zero for subdirectories)\n LENGTH: 0x20, // 32 bytes total\n UNUSED: 0x00, // indicates this and all subsequent directory entries are unused\n INVALID: 0xE5 // indicates this directory entry is unused\n};\n\n/*\n * Possible values for DIRENT.ATTR\n */\nDiskAPI.ATTR = {\n READONLY: 0x01, // PC-DOS 2.0 and up\n HIDDEN: 0x02,\n SYSTEM: 0x04,\n LABEL: 0x08, // PC-DOS 2.0 and up\n SUBDIR: 0x10, // PC-DOS 2.0 and up\n ARCHIVE: 0x20 // PC-DOS 2.0 and up\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/dumpapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Our \"DiskDump API\", such as it was, used to look like:\n *\n * http://jsmachines.net/bin/convdisk.php?disk=/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json&format=img\n *\n * To make it (a bit) more \"REST-like\", the above request now looks like:\n *\n * http://www.pcjs.org/api/v1/dump?disk=/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json&format=img\n *\n * Similarly, our \"FileDump API\" used to look like:\n *\n * http://jsmachines.net/bin/convrom.php?rom=/devices/pc/rom/5150/1981-04-24/PCBIOS-REV1.rom&format=json\n *\n * and that request now looks like:\n *\n * http://www.pcjs.org/api/v1/dump?file=/devices/pc/rom/5150/1981-04-24/PCBIOS-REV1.rom&format=json\n *\n * I don't think it makes sense to avoid \"query\" parameters, because blending the path of a disk image with the\n * the rest of the URL would be (a) confusing, and (b) more work to parse.\n */\nvar DumpAPI = {\n ENDPOINT: \"/api/v1/dump\",\n QUERY: {\n DIR: \"dir\", // value is path of a directory (DiskDump only)\n DISK: \"disk\", // value is path of a disk image (DiskDump only)\n FILE: \"file\", // value is path of a ROM image file (FileDump only)\n IMG: \"img\", // alias for DISK\n PATH: \"path\", // value is path of a one or more files (DiskDump only)\n FORMAT: \"format\", // value is one of FORMAT values below\n COMMENTS: \"comments\", // value is either \"true\" or \"false\"\n DECIMAL: \"decimal\", // value is either \"true\" to force all numbers to decimal, \"false\" or undefined otherwise\n MBHD: \"mbhd\", // value is hard drive size in Mb (formerly \"mbsize\") (DiskDump only) (DEPRECATED)\n SIZE: \"size\" // value is target disk size in Kb (supersedes \"mbhd\") (DiskDump only)\n },\n FORMAT: {\n JSON: \"json\", // default\n JSON_GZ: \"gz\", // gzip is currently used ONLY for compressed JSON\n DATA: \"data\", // same as \"json\", but built without JSON.stringify() (DiskDump only)\n HEX: \"hex\", // deprecated\n OCTAL: \"octal\", // displays data as octal words\n BYTES: \"bytes\", // displays data as hex bytes; normally used only when comments are enabled\n WORDS: \"words\", // displays data as hex words; normally used only when comments are enabled\n LONGS: \"longs\", // displays data as dwords\n IMG: \"img\", // returns the raw disk data (ie, using a Buffer object) (DiskDump only)\n ROM: \"rom\" // returns the raw file data (ie, using a Buffer object) (FileDump only)\n }\n};\n\n/*\n * Because we use an overloaded API endpoint (ie, one that's shared with the FileDump module), we must\n * also provide a list of commands which, when combined with the endpoint, define a unique request.\n */\nDumpAPI.asDiskCommands = [DumpAPI.QUERY.DIR, DumpAPI.QUERY.DISK, DumpAPI.QUERY.PATH];\nDumpAPI.asFileCommands = [DumpAPI.QUERY.FILE];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/reportapi.js (C) Jeff Parsons 2012-2018\n */\n\nvar ReportAPI = {\n ENDPOINT: \"/api/v1/report\",\n QUERY: {\n APP: \"app\",\n VER: \"ver\",\n URL: \"url\",\n USER: \"user\",\n TYPE: \"type\",\n DATA: \"data\"\n },\n TYPE: {\n BUG: \"bug\"\n },\n RES: {\n OK: \"Thank you\"\n }\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/userapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Examples of User API requests:\n *\n * web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.VERIFY + '&' + UserAPI.QUERY.USER + '=' + sUser;\n */\nvar UserAPI = {\n ENDPOINT: \"/api/v1/user\",\n QUERY: {\n REQ: \"req\", // specifies a request\n USER: \"user\", // specifies a user ID\n STATE: \"state\", // specifies a state ID\n DATA: \"data\" // specifies state data\n },\n REQ: {\n CREATE: \"create\", // creates a user ID\n VERIFY: \"verify\", // requests verification of a user ID\n STORE: \"store\", // stores a machine state on the server\n LOAD: \"load\" // loads a machine state from the server\n },\n RES: {\n CODE: \"code\",\n DATA: \"data\"\n },\n CODE: {\n OK: \"ok\",\n FAIL: \"error\"\n },\n FAIL: {\n DUPLICATE: \"user already exists\",\n VERIFY: \"unable to verify user\",\n BADSTATE: \"invalid state parameter\",\n NOSTATE: \"no machine state\",\n BADLOAD: \"unable to load machine state\",\n BADSTORE: \"unable to save machine state\"\n }\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/keys.js (C) Jeff Parsons 2012-2018\n */\n\nvar Keys = {\n /*\n * Keys and/or key combinations that generate common ASCII codes.\n *\n * NOTE: If you're looking for a general-purpose ASCII code table, see Str.ASCII in strlib.js;\n * if something's missing, that's probably the more appropriate table to add it to.\n *\n * TODO: The Closure Compiler doesn't inline all references to these values, at least those with\n * quoted property names, which is why I've 'unquoted' as many of them as possible. One solution\n * would be to add mnemonics for all of them, not just the non-printable ones (eg, SPACE instead\n * of ' ', AMP instead of '&', etc.)\n */\n ASCII: {\n BREAK: 0, CTRL_A: 1, CTRL_B: 2, CTRL_C: 3, CTRL_D: 4, CTRL_E: 5, CTRL_F: 6, CTRL_G: 7,\n CTRL_H: 8, CTRL_I: 9, CTRL_J: 10, CTRL_K: 11, CTRL_L: 12, CTRL_M: 13, CTRL_N: 14, CTRL_O: 15,\n CTRL_P: 16, CTRL_Q: 17, CTRL_R: 18, CTRL_S: 19, CTRL_T: 20, CTRL_U: 21, CTRL_V: 22, CTRL_W: 23,\n CTRL_X: 24, CTRL_Y: 25, CTRL_Z: 26, ESC: 27,\n ' ': 32, '!': 33, '\"': 34, '#': 35, '$': 36, '%': 37, '&': 38, \"'\": 39,\n '(': 40, ')': 41, '*': 42, '+': 43, ',': 44, '-': 45, '.': 46, '/': 47,\n '0': 48, '1': 49, '2': 50, '3': 51, '4': 52, '5': 53, '6': 54, '7': 55,\n '8': 56, '9': 57, ':': 58, ';': 59, '<': 60, '=': 61, '>': 62, '?': 63,\n '@': 64, A: 65, B: 66, C: 67, D: 68, E: 69, F: 70, G: 71,\n H: 72, I: 73, J: 74, K: 75, L: 76, M: 77, N: 78, O: 79,\n P: 80, Q: 81, R: 82, S: 83, T: 84, U: 85, V: 86, W: 87,\n X: 88, Y: 89, Z: 90, '[': 91, '\\\\':92, ']': 93, '^': 94, '_': 95,\n '`': 96, a: 97, b: 98, c: 99, d: 100, e: 101, f: 102, g: 103,\n h: 104, i: 105, j: 106, k: 107, l: 108, m: 109, n: 110, o: 111,\n p: 112, q: 113, r: 114, s: 115, t: 116, u: 117, v: 118, w: 119,\n x: 120, y: 121, z: 122, '{':123, '|':124, '}':125, '~':126, DEL: 127\n },\n /*\n * Browser keyCodes we must pay particular attention to. For the most part, these are non-alphanumeric\n * or function keys, some which may require special treatment (eg, preventDefault() if returning false on\n * the initial keyDown event is insufficient).\n *\n * keyCodes for most common ASCII keys can simply use the appropriate ASCII code above.\n *\n * Most of these represent non-ASCII keys (eg, the LEFT arrow key), yet for some reason, browsers defined\n * them using ASCII codes (eg, the LEFT arrow key uses the ASCII code for '%' or 37).\n */\n KEYCODE: {\n /* 0x08 */ BS: 8, // BACKSPACE (ASCII.CTRL_H)\n /* 0x09 */ TAB: 9, // TAB (ASCII.CTRL_I)\n /* 0x0A */ LF: 10, // LINE-FEED (ASCII.CTRL_J) (Some Windows-based browsers used to generate this via CTRL-ENTER)\n /* 0x0D */ CR: 13, // CARRIAGE RETURN (ASCII.CTRL_M)\n /* 0x10 */ SHIFT: 16,\n /* 0x11 */ CTRL: 17,\n /* 0x12 */ ALT: 18,\n /* 0x13 */ PAUSE: 19, // PAUSE/BREAK\n /* 0x14 */ CAPS_LOCK: 20,\n /* 0x1B */ ESC: 27,\n /* 0x20 */ SPACE: 32,\n /* 0x21 */ PGUP: 33,\n /* 0x22 */ PGDN: 34,\n /* 0x23 */ END: 35,\n /* 0x24 */ HOME: 36,\n /* 0x25 */ LEFT: 37,\n /* 0x26 */ UP: 38,\n /* 0x27 */ RIGHT: 39,\n /* 0x27 */ FF_QUOTE: 39,\n /* 0x28 */ DOWN: 40,\n /* 0x2C */ FF_COMMA: 44,\n /* 0x2C */ PRTSC: 44,\n /* 0x2D */ INS: 45,\n /* 0x2E */ DEL: 46,\n /* 0x2E */ FF_PERIOD: 46,\n /* 0x2F */ FF_SLASH: 47,\n /* 0x30 */ ZERO: 48,\n /* 0x31 */ ONE: 49,\n /* 0x32 */ TWO: 50,\n /* 0x33 */ THREE: 51,\n /* 0x34 */ FOUR: 52,\n /* 0x35 */ FIVE: 53,\n /* 0x36 */ SIX: 54,\n /* 0x37 */ SEVEN: 55,\n /* 0x38 */ EIGHT: 56,\n /* 0x39 */ NINE: 57,\n /* 0x3B */ FF_SEMI: 59,\n /* 0x3D */ FF_EQUALS: 61,\n /* 0x5B */ CMD: 91, // aka WIN\n /* 0x5B */ FF_LBRACK: 91,\n /* 0x5C */ FF_BSLASH: 92,\n /* 0x5D */ RCMD: 93, // aka MENU\n /* 0x5D */ FF_RBRACK: 93,\n /* 0x60 */ NUM_0: 96,\n /* 0x60 */ NUM_INS: 96,\n /* 0x60 */ FF_BQUOTE: 96,\n /* 0x61 */ NUM_1: 97,\n /* 0x61 */ NUM_END: 97,\n /* 0x62 */ NUM_2: 98,\n /* 0x62 */ NUM_DOWN: 98,\n /* 0x63 */ NUM_3: 99,\n /* 0x63 */ NUM_PGDN: 99,\n /* 0x64 */ NUM_4: 100,\n /* 0x64 */ NUM_LEFT: 100,\n /* 0x65 */ NUM_5: 101,\n /* 0x65 */ NUM_CENTER: 101,\n /* 0x66 */ NUM_6: 102,\n /* 0x66 */ NUM_RIGHT: 102,\n /* 0x67 */ NUM_7: 103,\n /* 0x67 */ NUM_HOME: 103,\n /* 0x68 */ NUM_8: 104,\n /* 0x68 */ NUM_UP: 104,\n /* 0x69 */ NUM_9: 105,\n /* 0x69 */ NUM_PGUP: 105,\n /* 0x6A */ NUM_MUL: 106,\n /* 0x6B */ NUM_ADD: 107,\n /* 0x6D */ NUM_SUB: 109,\n /* 0x6E */ NUM_DEL: 110, // aka PERIOD\n /* 0x6F */ NUM_DIV: 111,\n /* 0x70 */ F1: 112,\n /* 0x71 */ F2: 113,\n /* 0x72 */ F3: 114,\n /* 0x73 */ F4: 115,\n /* 0x74 */ F5: 116,\n /* 0x75 */ F6: 117,\n /* 0x76 */ F7: 118,\n /* 0x77 */ F8: 119,\n /* 0x78 */ F9: 120,\n /* 0x79 */ F10: 121,\n /* 0x7A */ F11: 122,\n /* 0x7B */ F12: 123,\n /* 0x90 */ NUM_LOCK: 144,\n /* 0x91 */ SCROLL_LOCK: 145,\n /* 0xAD */ FF_DASH: 173,\n /* 0xBA */ SEMI: 186, // Firefox: 59 (FF_SEMI)\n /* 0xBB */ EQUALS: 187, // Firefox: 61 (FF_EQUALS)\n /* 0xBC */ COMMA: 188,\n /* 0xBD */ DASH: 189, // Firefox: 173 (FF_DASH)\n /* 0xBE */ PERIOD: 190,\n /* 0xBF */ SLASH: 191,\n /* 0xC0 */ BQUOTE: 192,\n /* 0xDB */ LBRACK: 219,\n /* 0xDC */ BSLASH: 220,\n /* 0xDD */ RBRACK: 221,\n /* 0xDE */ QUOTE: 222,\n /* 0xE0 */ FF_CMD: 224, // Firefox only (used for both CMD and RCMD)\n //\n // The following biases use what I'll call Decimal Coded Binary or DCB (the opposite of BCD),\n // where the thousands digit is used to store the sum of \"binary\" digits 1 and/or 2 and/or 4.\n //\n // Technically, that makes it DCO (Decimal Coded Octal), but then again, BCD should have really\n // been called HCD (Hexadecimal Coded Decimal), so if \"they\" can take liberties, so can I.\n //\n // ONDOWN is a bias we add to browser keyCodes that we want to handle on \"down\" rather than on \"press\".\n //\n ONDOWN: 1000,\n //\n // ONRIGHT is a bias we add to browser keyCodes that need to check for a \"right\" location (default is \"left\")\n //\n ONRIGHT: 2000,\n //\n // FAKE is a bias we add to signal these are fake keyCodes corresponding to internal keystroke combinations.\n // The actual values are for internal use only and merely need to be unique and used consistently.\n //\n FAKE: 4000\n },\n /*\n * The set of values that a browser may store in the 'location' property of a keyboard event object\n * which we also support.\n */\n LOCATION: {\n LEFT: 1,\n RIGHT: 2,\n NUMPAD: 3\n }\n};\n\n/*\n * Check the event object's 'location' property for a non-zero value for the following ONRIGHT keys.\n */\nKeys.KEYCODE.NUM_CR = Keys.KEYCODE.CR + Keys.KEYCODE.ONRIGHT;\n\n\n/*\n * Maps Firefox keyCodes to their more common keyCode counterparts; a number of entries in this table\n * are no longer valid (if indeed they ever were), so they've been commented out. It's likely that I\n * simply extended this table to resolve additional differences in other browsers (ie, Opera), but without\n * browser-specific checks, it's not safe to perform all the mappings shown below.\n */\nKeys.FF_KEYCODES = {};\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_SEMI] = Keys.KEYCODE.SEMI; // 59 -> 186\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_EQUALS] = Keys.KEYCODE.EQUALS; // 61 -> 187\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.KEYCODE.DASH; // 173 -> 189\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_CMD] = Keys.KEYCODE.CMD; // 224 -> 91\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_COMMA] = Keys.KEYCODE.COMMA; // 44 -> 188\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_PERIOD] = Keys.KEYCODE.PERIOD; // 46 -> 190\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_SLASH] = Keys.KEYCODE.SLASH; // 47 -> 191\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_BQUOTE] = Keys.KEYCODE.BQUOTE; // 96 -> 192\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_LBRACK = Keys.KEYCODE.LBRACK; // 91 -> 219\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_BSLASH] = Keys.KEYCODE.BSLASH; // 92 -> 220\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_RBRACK] = Keys.KEYCODE.RBRACK; // 93 -> 221\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_QUOTE] = Keys.KEYCODE.QUOTE; // 39 -> 222\n\n/*\n * Maps non-ASCII keyCodes to their ASCII counterparts\n */\nKeys.NONASCII_KEYCODES = {};\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.ASCII['-']; // 173 -> 45\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.SEMI] = Keys.ASCII[';']; // 186 -> 59\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.EQUALS] = Keys.ASCII['=']; // 187 -> 61\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.DASH] = Keys.ASCII['-']; // 189 -> 45\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.COMMA] = Keys.ASCII[',']; // 188 -> 44\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.PERIOD] = Keys.ASCII['.']; // 190 -> 46\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.SLASH] = Keys.ASCII['/']; // 191 -> 47\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.BQUOTE] = Keys.ASCII['`']; // 192 -> 96\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.LBRACK] = Keys.ASCII['[']; // 219 -> 91\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.BSLASH] = Keys.ASCII['\\\\']; // 220 -> 92\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.RBRACK] = Keys.ASCII[']']; // 221 -> 93\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.QUOTE] = Keys.ASCII[\"'\"]; // 222 -> 39\n\n/*\n * Maps unshifted keyCodes to their shifted counterparts; to be used when a shift-key is down.\n * Alphabetic characters are handled in code, since they must also take CAPS_LOCK into consideration.\n */\nKeys.SHIFTED_KEYCODES = {};\nKeys.SHIFTED_KEYCODES[Keys.ASCII['1']] = Keys.ASCII['!'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['2']] = Keys.ASCII['@'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['3']] = Keys.ASCII['#'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['4']] = Keys.ASCII['$'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['5']] = Keys.ASCII['%'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['6']] = Keys.ASCII['^'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['7']] = Keys.ASCII['&'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['8']] = Keys.ASCII['*'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['9']] = Keys.ASCII['('];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['0']] = Keys.ASCII[')'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.SEMI] = Keys.ASCII[':'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.EQUALS] = Keys.ASCII['+'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.COMMA] = Keys.ASCII['<'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.DASH] = Keys.ASCII['_'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.PERIOD] = Keys.ASCII['>'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.SLASH] = Keys.ASCII['?'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.BQUOTE] = Keys.ASCII['~'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.LBRACK] = Keys.ASCII['{'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.BSLASH] = Keys.ASCII['|'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.RBRACK] = Keys.ASCII['}'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.QUOTE] = Keys.ASCII['\"'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.ASCII['_'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_EQUALS] = Keys.ASCII['+'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_SEMI] = Keys.ASCII[':'];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/strlib.js (C) Jeff Parsons 2012-2018\n */\n\nclass Str {\n /**\n * isValidInt(s, base)\n *\n * The built-in parseInt() function has the annoying feature of returning a partial value (ie,\n * up to the point where it encounters an invalid character); eg, parseInt(\"foo\", 16) returns 0xf.\n *\n * So it's best to use our own Str.parseInt() function, which will in turn use this function to\n * validate the entire string.\n *\n * @param {string} s is the string representation of some number\n * @param {number} [base] is the radix to use (default is 10); only 2, 8, 10 and 16 are supported\n * @return {boolean} true if valid, false if invalid (or the specified base isn't supported)\n */\n static isValidInt(s, base)\n {\n if (!base || base == 10) return s.match(/^-?[0-9]+$/) !== null;\n if (base == 16) return s.match(/^-?[0-9a-f]+$/i) !== null;\n if (base == 8) return s.match(/^-?[0-7]+$/) !== null;\n if (base == 2) return s.match(/^-?[01]+$/) !== null;\n return false;\n }\n\n /**\n * parseInt(s, base)\n *\n * This is a wrapper around the built-in parseInt() function. Our wrapper recognizes certain prefixes\n * ('$' or \"0x\" for hex, '#' or \"0o\" for octal) and suffixes ('.' for decimal, 'h' for hex, 'y' for\n * binary), and then calls isValidInt() to ensure we don't convert strings that contain partial values;\n * see isValidInt() for details.\n *\n * The use of multiple prefix/suffix combinations is undefined (although for the record, we process\n * prefixes first). We do NOT support the \"0b\" prefix to indicate binary UNLESS one or more commas are\n * also present (because \"0b\" is also a valid hex sequence), and we do NOT support a single leading zero\n * to indicate octal (because such a number could also be decimal or hex). Any number of commas are\n * allowed; we remove them all before calling the built-in parseInt().\n *\n * More recently, we've added support for \"^D\", \"^O\", and \"^B\" prefixes to accommodate the base overrides\n * that the PDP-10's MACRO-10 assembly language supports (decimal, octal, and binary, respectively).\n * If this support turns out to adversely affect other debuggers, then it will have to be \"conditionalized\".\n * Similarly, we've added support for \"K\", \"M\", and \"G\" MACRO-10-style suffixes that add 3, 6, or 9 zeros\n * to the value to be parsed, respectively.\n *\n * @param {string} s is the string representation of some number\n * @param {number} [base] is the radix to use (default is 10); can be overridden by prefixes/suffixes\n * @return {number|undefined} corresponding value, or undefined if invalid\n */\n static parseInt(s, base)\n {\n var value;\n\n if (s) {\n if (!base) base = 10;\n\n var ch, chPrefix, chSuffix;\n var fCommas = (s.indexOf(',') > 0);\n if (fCommas) s = s.replace(/,/g, '');\n\n ch = chPrefix = s.charAt(0);\n if (chPrefix == '#') {\n base = 8;\n chPrefix = '';\n }\n else if (chPrefix == '$') {\n base = 16;\n chPrefix = '';\n }\n if (ch != chPrefix) {\n s = s.substr(1);\n }\n else {\n ch = chPrefix = s.substr(0, 2);\n if (chPrefix == '0b' && fCommas || chPrefix == '^B') {\n base = 2;\n chPrefix = '';\n }\n else if (chPrefix == '0o' || chPrefix == '^O') {\n base = 8;\n chPrefix = '';\n }\n else if (chPrefix == '^D') {\n base = 10;\n chPrefix = '';\n }\n else if (chPrefix == '0x') {\n base = 16;\n chPrefix = '';\n }\n if (ch != chPrefix) s = s.substr(2);\n }\n ch = chSuffix = s.slice(-1);\n if (chSuffix == 'Y' || chSuffix == 'y') {\n base = 2;\n chSuffix = '';\n }\n else if (chSuffix == '.') {\n base = 10;\n chSuffix = '';\n }\n else if (chSuffix == 'H' || chSuffix == 'h') {\n base = 16;\n chSuffix = '';\n }\n else if (chSuffix == 'K') {\n chSuffix = '000';\n }\n else if (chSuffix == 'M') {\n chSuffix = '000000';\n }\n else if (chSuffix == 'G') {\n chSuffix = '000000000';\n }\n if (ch != chSuffix) s = s.slice(0, -1) + chSuffix;\n /*\n * This adds support for the MACRO-10 binary shifting (Bn) suffix, which must be stripped from the\n * number before parsing, and then applied to the value after parsing. If n is omitted, 35 is assumed,\n * which is a net shift of zero. If n < 35, then a left shift of (35 - n) is required; if n > 35, then\n * a right shift of -(35 - n) is required.\n */\n var v, shift = 0;\n if (base <= 10) {\n var match = s.match(/(-?[0-9]+)B([0-9]*)/);\n if (match) {\n s = match[1];\n shift = 35 - ((match[2] || 35) & 0xff);\n }\n }\n if (Str.isValidInt(s, base) && !isNaN(v = parseInt(s, base))) {\n /*\n * With the need to support larger (eg, 36-bit) integers, truncating to 32 bits is no longer helpful.\n *\n * value = v|0;\n */\n if (shift) {\n /*\n * Since binary shifting is a logical operation, and since shifting by division only works properly\n * with positive numbers, we must convert a negative value to a positive value, by computing the two's\n * complement.\n */\n if (v < 0) v += Math.pow(2, 36);\n if (shift > 0) {\n v *= Math.pow(2, shift);\n } else {\n v = Math.trunc(v / Math.pow(2, -shift));\n }\n }\n value = v;\n }\n }\n return value;\n }\n\n /**\n * toBase(n, radix, cch, sPrefix, nGrouping)\n *\n * Displays the given number as an unsigned integer using the specified radix and number of digits.\n *\n * @param {number|*} n\n * @param {number} radix (ie, the base)\n * @param {number} cch (the desired number of digits)\n * @param {string} [sPrefix] (default is none)\n * @param {number} [nGrouping]\n * @return {string}\n */\n static toBase(n, radix, cch, sPrefix = \"\", nGrouping = 0)\n {\n /*\n * We can't rely entirely on isNaN(), because isNaN(null) returns false, and we can't rely\n * entirely on typeof either, because typeof Nan returns \"number\". Sigh.\n *\n * Alternatively, we could mask and shift n regardless of whether it's null/undefined/NaN,\n * since JavaScript coerces such operands to zero, but I think there's \"value\" in seeing those\n * values displayed differently.\n */\n var s = \"\";\n if (isNaN(n) || typeof n != \"number\") {\n n = null;\n } else {\n /*\n * Callers that produced an input by dividing by a power of two rather than shifting (in order\n * to access more than 32 bits) may produce a fractional result, which ordinarily we would simply\n * ignore, but if the integer portion is zero and the sign is negative, we should probably treat\n * this value as a sign-extension.\n */\n if (n < 0 && n > -1) n = -1;\n /*\n * Negative values should be two's complemented according to the number of digits; for example,\n * 12 octal digits implies an upper limit 8^12.\n */\n if (n < 0) {\n n += Math.pow(radix, cch);\n }\n if (n >= Math.pow(radix, cch)) {\n cch = Math.ceil(Math.log(n) / Math.log(radix));\n }\n }\n var g = nGrouping || -1;\n while (cch-- > 0) {\n if (!g) {\n s = ',' + s;\n g = nGrouping;\n }\n if (n == null) {\n s = '?' + s;\n } else {\n var d = n % radix;\n d += (d >= 0 && d <= 9? 0x30 : 0x41 - 10);\n s = String.fromCharCode(d) + s;\n n = Math.trunc(n / radix);\n }\n g--;\n }\n return sPrefix + s;\n }\n\n /**\n * toBin(n, cch, nGrouping)\n *\n * Converts an integer to binary, with the specified number of digits (up to a maximum of 36).\n *\n * @param {number|*} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of binary digits (0 or undefined for default of either 8, 18, or 36)\n * @param {number} [nGrouping]\n * @return {string} the binary representation of n\n */\n static toBin(n, cch, nGrouping)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.LN2) || 1;\n var v = Math.abs(n);\n if (v <= 0b11111111) {\n cch = 8;\n } else if (v <= 0b111111111111111111) {\n cch = 18;\n } else {\n cch = 36;\n }\n } else if (cch > 36) cch = 36;\n return Str.toBase(n, 2, cch, \"\", nGrouping);\n }\n\n /**\n * toBinBytes(n, cb, fPrefix)\n *\n * Converts an integer to binary, with the specified number of bytes (up to the default of 4).\n *\n * @param {number|null|undefined} n (interpreted as a 32-bit value)\n * @param {number} [cb] is the desired number of binary bytes (4 is both the default and the maximum)\n * @param {boolean} [fPrefix]\n * @return {string} the binary representation of n\n */\n static toBinBytes(n, cb, fPrefix)\n {\n var s = \"\";\n if (!cb || cb > 4) cb = 4;\n for (var i = 0; i < cb; i++) {\n if (s) s = ',' + s;\n s = Str.toBin(n & 0xff, 8) + s;\n n >>= 8;\n }\n return (fPrefix? \"0b\" : \"\") + s;\n }\n\n /**\n * toOct(n, cch, fPrefix)\n *\n * Converts an integer to octal, with the specified number of digits (default of 6; max of 12)\n *\n * You might be tempted to use the built-in n.toString(8) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw\n * an exception, whereas this function will return '?' characters.\n *\n * @param {number|*} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of octal digits (0 or undefined for default of either 6, 8, or 12)\n * @param {boolean} [fPrefix]\n * @return {string} the octal representation of n\n */\n static toOct(n, cch, fPrefix)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.log(8)) || 1;\n var v = Math.abs(n);\n if (v <= 0o777777) {\n cch = 6;\n } else if (v <= 0o77777777) {\n cch = 8;\n } else {\n cch = 12;\n }\n } else if (cch > 12) cch = 12;\n return Str.toBase(n, 8, cch, fPrefix? \"0o\" : \"\");\n }\n\n /**\n * toDec(n, cch)\n *\n * Converts an integer to decimal, with the specified number of digits (default of 5; max of 11)\n *\n * You might be tempted to use the built-in n.toString(10) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw\n * an exception, whereas this function will return '?' characters.\n *\n * @param {number|*} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of decimal digits (0 or undefined for default of either 5 or 11)\n * @return {string} the decimal representation of n\n */\n static toDec(n, cch)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.LN10) || 1;\n var v = Math.abs(n);\n if (v <= 99999) {\n cch = 5;\n } else {\n cch = 11;\n }\n } else if (cch > 11) cch = 11;\n return Str.toBase(n, 10, cch);\n }\n\n /**\n * toHex(n, cch, fPrefix)\n *\n * Converts an integer to hex, with the specified number of digits (default of 4 or 8, max of 9).\n *\n * You might be tempted to use the built-in n.toString(16) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values; for example, if n is -2147483647, then n.toString(16)\n * will return \"-7fffffff\" instead of \"80000001\". Moreover, if n is undefined, n.toString() will\n * throw an exception, whereas this function will return '?' characters.\n *\n * NOTE: The following work-around (adapted from code found on StackOverflow) would be another solution,\n * taking care of negative values, zero-padding, and upper-casing, but not null/undefined/NaN values:\n *\n * s = (n < 0? n + 0x100000000 : n).toString(16);\n * s = \"00000000\".substr(0, 8 - s.length) + s;\n * s = s.substr(0, cch).toUpperCase();\n *\n * @param {number|*} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of hex digits (0 or undefined for default of either 4, 8, or 9)\n * @param {boolean} [fPrefix]\n * @return {string} the hex representation of n\n */\n static toHex(n, cch, fPrefix)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.log(16)) || 1;\n var v = Math.abs(n);\n if (v <= 0xffff) {\n cch = 4;\n } else if (v <= 0xffffffff) {\n cch = 8;\n } else {\n cch = 9;\n }\n } else if (cch > 9) cch = 9;\n return Str.toBase(n, 16, cch, fPrefix? \"0x\" : \"\");\n }\n\n /**\n * toHexByte(b)\n *\n * Alias for Str.toHex(b, 2, true)\n *\n * @param {number|null|undefined} b is a byte value\n * @return {string} the hex representation of b\n */\n static toHexByte(b)\n {\n return Str.toHex(b, 2, true);\n }\n\n /**\n * toHexWord(w)\n *\n * Alias for Str.toHex(w, 4, true)\n *\n * @param {number|null|undefined} w is a word (16-bit) value\n * @return {string} the hex representation of w\n */\n static toHexWord(w)\n {\n return Str.toHex(w, 4, true);\n }\n\n /**\n * toHexLong(l)\n *\n * Alias for Str.toHex(l, 8, true)\n *\n * @param {number|null|undefined} l is a dword (32-bit) value\n * @return {string} the hex representation of w\n */\n static toHexLong(l)\n {\n return Str.toHex(l, 8, true);\n }\n\n /**\n * getBaseName(sFileName, fStripExt)\n *\n * This is a poor-man's version of Node's path.basename(), which Node-only components should use instead.\n *\n * Note that if fStripExt is true, this strips ANY extension, whereas path.basename() strips the extension only\n * if it matches the second parameter (eg, path.basename(\"/foo/bar/baz/asdf/quux.html\", \".html\") returns \"quux\").\n *\n * @param {string} sFileName\n * @param {boolean} [fStripExt]\n * @return {string}\n */\n static getBaseName(sFileName, fStripExt)\n {\n var sBaseName = sFileName;\n\n var i = sFileName.lastIndexOf('/');\n if (i >= 0) sBaseName = sFileName.substr(i + 1);\n\n /*\n * This next bit is a kludge to clean up names that are part of a URL that includes unsightly query parameters.\n */\n i = sBaseName.indexOf('&');\n if (i > 0) sBaseName = sBaseName.substr(0, i);\n\n if (fStripExt) {\n i = sBaseName.lastIndexOf(\".\");\n if (i > 0) {\n sBaseName = sBaseName.substring(0, i);\n }\n }\n return sBaseName;\n }\n\n /**\n * getExtension(sFileName)\n *\n * This is a poor-man's version of Node's path.extname(), which Node-only components should use instead.\n *\n * Note that we EXCLUDE the period from the returned extension, whereas path.extname() includes it.\n *\n * @param {string} sFileName\n * @return {string} the filename's extension (in lower-case and EXCLUDING the \".\"), or an empty string\n */\n static getExtension(sFileName)\n {\n var sExtension = \"\";\n var i = sFileName.lastIndexOf(\".\");\n if (i >= 0) {\n sExtension = sFileName.substr(i + 1).toLowerCase();\n }\n return sExtension;\n }\n\n /**\n * endsWith(s, sSuffix)\n *\n * @param {string} s\n * @param {string} sSuffix\n * @return {boolean} true if s ends with sSuffix, false if not\n */\n static endsWith(s, sSuffix)\n {\n return s.indexOf(sSuffix, s.length - sSuffix.length) !== -1;\n }\n\n /**\n * escapeHTML(sHTML)\n *\n * @param {string} sHTML\n * @return {string} with HTML entities \"escaped\", similar to PHP's htmlspecialchars()\n */\n static escapeHTML(sHTML)\n {\n return sHTML.replace(/[&<>\"']/g, function(m)\n {\n return Str.HTMLEscapeMap[m];\n });\n }\n\n /**\n * replace(sSearch, sReplace, s)\n *\n * The JavaScript replace() function ALWAYS interprets \"$\" specially in replacement strings, even when\n * the search string is NOT a RegExp; specifically:\n *\n * $$ Inserts a \"$\"\n * $& Inserts the matched substring\n * $` Inserts the portion of the string that precedes the matched substring\n * $' Inserts the portion of the string that follows the matched substring\n * $n Where n is a positive integer less than 100, inserts the nth parenthesized sub-match string,\n * provided the first argument was a RegExp object\n *\n * So, if a replacement string containing dollar signs passes through a series of replace() calls, untold\n * problems could result. Hence, this function, which simply uses the replacement string as-is.\n *\n * Similar to the JavaScript replace() method (when sSearch is a string), this replaces only ONE occurrence\n * (ie, the FIRST occurrence); it might be nice to add options to replace the LAST occurrence and/or ALL\n * occurrences, but we'll revisit that later.\n *\n * @param {string} sSearch\n * @param {string} sReplace\n * @param {string} s\n * @return {string}\n */\n static replace(sSearch, sReplace, s)\n {\n var i = s.indexOf(sSearch);\n if (i >= 0) {\n s = s.substr(0, i) + sReplace + s.substr(i + sSearch.length);\n }\n return s;\n }\n\n /**\n * replaceAll(sSearch, sReplace, s)\n *\n * @param {string} sSearch\n * @param {string} sReplace\n * @param {string} s\n * @return {string}\n */\n static replaceAll(sSearch, sReplace, s)\n {\n var a = {};\n a[sSearch] = sReplace;\n return Str.replaceArray(a, s);\n }\n\n /**\n * replaceArray(a, s)\n *\n * @param {Object} a\n * @param {string} s\n * @return {string}\n */\n static replaceArray(a, s)\n {\n var sMatch = \"\";\n for (var k in a) {\n /*\n * As noted in:\n *\n * http://www.regexguru.com/2008/04/escape-characters-only-when-necessary/\n *\n * inside character classes, only backslash, caret, hyphen and the closing bracket need to be\n * escaped. And in fact, if you ensure that the closing bracket is first, the caret is not first,\n * and the hyphen is last, you can avoid escaping those as well.\n */\n k = k.replace(/([\\\\[\\]*{}().+?|$])/g, \"\\\\$1\");\n sMatch += (sMatch? '|' : '') + k;\n }\n return s.replace(new RegExp('(' + sMatch + ')', \"g\"), function(m)\n {\n return a[m];\n });\n }\n\n /**\n * pad(s, cch, fPadLeft)\n *\n * NOTE: the maximum amount of padding currently supported is 40 spaces.\n *\n * @param {string} s is a string\n * @param {number} cch is desired length\n * @param {boolean} [fPadLeft] (default is padding on the right)\n * @return {string} the original string (s) with spaces padding it to the specified length\n */\n static pad(s, cch, fPadLeft)\n {\n var sPadding = \" \";\n return fPadLeft? (sPadding + s).slice(-cch) : (s + sPadding).slice(0, cch);\n }\n\n /**\n * sprintf(format, ...args)\n *\n * Copied from the CCjs project (https://github.com/jeffpar/ccjs/blob/master/lib/stdio.js) and extended.\n *\n * Far from complete, let alone sprintf-compatible, but it's adequate for the handful of sprintf-style format\n * specifiers that I use.\n *\n * @param {string} format\n * @param {...} args\n * @return {string}\n */\n static sprintf(format, ...args)\n {\n let buffer = \"\";\n let aParts = format.split(/%([-+ 0#]?)([0-9]*)(\\.?)([0-9]*)([hlL]?)([A-Za-z%])/);\n\n let iArg = 0, iPart;\n for (iPart = 0; iPart < aParts.length - 7; iPart += 7) {\n\n buffer += aParts[iPart];\n\n let arg = args[iArg++];\n let flags = aParts[iPart+1];\n let minimum = +aParts[iPart+2] || 0;\n let precision = +aParts[iPart+4] || 0;\n let conversion = aParts[iPart+6];\n let ach = null, s;\n\n switch(conversion) {\n case 'd':\n /*\n * We could use \"arg |= 0\", but there may be some value to supporting integers > 32 bits.\n * \n * Also, unlike the 'X' and 'x' hexadecimal cases, there's no need to explicitly check for a string\n * arguments, because the call to trunc() automatically coerces any string value to a (decimal) number.\n */\n arg = Math.trunc(arg);\n /* falls through */\n\n case 'f':\n s = Math.trunc(arg) + \"\";\n if (precision) {\n minimum -= (precision + 1);\n }\n if (s.length < minimum) {\n if (flags == '0') {\n if (arg < 0) minimum--;\n s = (\"0000000000\" + Math.abs(arg)).slice(-minimum);\n if (arg < 0) s = '-' + s;\n } else {\n s = (\" \" + s).slice(-minimum);\n }\n }\n if (precision) {\n arg = Math.round((arg - Math.trunc(arg)) * Math.pow(10, precision));\n s += '.' + (\"0000000000\" + Math.abs(arg)).slice(-precision);\n }\n buffer += s;\n break;\n\n case 'c':\n arg = String.fromCharCode(arg);\n /* falls through */\n\n case 's':\n if (typeof arg == \"string\") {\n while (arg.length < minimum) {\n if (flags == '-') {\n arg += ' ';\n } else {\n arg = ' ' + arg;\n }\n }\n }\n buffer += arg;\n break;\n\n case 'X':\n ach = Str.HexUpperCase;\n /* falls through */\n\n case 'x':\n if (!ach) ach = Str.HexLowerCase;\n s = \"\";\n if (typeof arg == \"string\") {\n /*\n * Since we're advised to ALWAYS pass a radix to parseInt(), we must detect explicitly\n * hex values ourselves, because using a radix of 10 with any \"0x...\" value always returns 0.\n * \n * And if the value CAN be interpreted as decimal, then we MUST interpret it as decimal, because\n * we have sprintf() calls in /modules/lib/testmon.js that depend on this code to perform decimal\n * to hex conversion. We're allowed to make our own rules here, since passing numbers in string\n * form isn't part of the sprintf \"spec\". \n */\n arg = Number.parseInt(arg, arg.match(/(^0x|[a-f])/i)? 16 : 10);\n } \n do {\n s = ach[arg & 0xf] + s;\n arg >>>= 4;\n } while (--minimum > 0 || arg);\n buffer += s;\n break;\n\n default:\n /*\n * The supported ANSI C set of conversions: \"dioxXucsfeEgGpn%\"\n */\n buffer += \"(unrecognized printf conversion %\" + conversion + \")\";\n break;\n }\n }\n\n buffer += aParts[iPart];\n return buffer;\n }\n\n /**\n * stripLeadingZeros(s, fPad)\n *\n * @param {string} s\n * @param {boolean} [fPad]\n * @return {string}\n */\n static stripLeadingZeros(s, fPad)\n {\n var cch = s.length;\n s = s.replace(/^0+([0-9A-F]+)$/i, \"$1\");\n if (fPad) s = Str.pad(s, cch, true);\n return s;\n }\n\n /**\n * trim(s)\n *\n * @param {string} s\n * @return {string}\n */\n static trim(s)\n {\n if (String.prototype.trim) {\n return s.trim();\n }\n return s.replace(/^\\s+|\\s+$/g, \"\");\n }\n\n /**\n * toASCIICode(b)\n *\n * @param {number} b\n * @return {string}\n */\n static toASCIICode(b)\n {\n var s;\n if (b != Str.ASCII.CR && b != Str.ASCII.LF) {\n s = Str.ASCIICodeMap[b];\n }\n if (s) {\n s = '<' + s + '>';\n } else {\n s = String.fromCharCode(b);\n }\n return s;\n }\n}\n\n/*\n * Map special characters to their HTML escape sequences.\n */\nStr.HTMLEscapeMap = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n};\n\n/*\n * Map \"unprintable\" ASCII codes to mnemonics, to more clearly see what's being printed.\n */\nStr.ASCIICodeMap = {\n 0x00: \"NUL\",\n 0x01: \"SOH\", // (CTRL_A) Start of Heading\n 0x02: \"STX\", // (CTRL_B) Start of Text\n 0x03: \"ETX\", // (CTRL_C) End of Text\n 0x04: \"EOT\", // (CTRL_D) End of Transmission\n 0x05: \"ENQ\", // (CTRL_E) Enquiry\n 0x06: \"ACK\", // (CTRL_F) Acknowledge\n 0x07: \"BEL\", // (CTRL_G) Bell\n 0x08: \"BS\", // (CTRL_H) Backspace\n 0x09: \"TAB\", // (CTRL_I) Horizontal Tab (aka HT)\n 0x0A: \"LF\", // (CTRL_J) Line Feed (New Line)\n 0x0B: \"VT\", // (CTRL_K) Vertical Tab\n 0x0C: \"FF\", // (CTRL_L) Form Feed (New Page)\n 0x0D: \"CR\", // (CTRL_M) Carriage Return\n 0x0E: \"SO\", // (CTRL_N) Shift Out\n 0x0F: \"SI\", // (CTRL_O) Shift In\n 0x10: \"DLE\", // (CTRL_P) Data Link Escape\n 0x11: \"XON\", // (CTRL_Q) Device Control 1 (aka DC1)\n 0x12: \"DC2\", // (CTRL_R) Device Control 2\n 0x13: \"XOFF\", // (CTRL_S) Device Control 3 (aka DC3)\n 0x14: \"DC4\", // (CTRL_T) Device Control 4\n 0x15: \"NAK\", // (CTRL_U) Negative Acknowledge\n 0x16: \"SYN\", // (CTRL_V) Synchronous Idle\n 0x17: \"ETB\", // (CTRL_W) End of Transmission Block\n 0x18: \"CAN\", // (CTRL_X) Cancel\n 0x19: \"EM\", // (CTRL_Y) End of Medium\n 0x1A: \"SUB\", // (CTRL_Z) Substitute\n 0x1B: \"ESC\", // Escape\n 0x1C: \"FS\", // File Separator\n 0x1D: \"GS\", // Group Separator\n 0x1E: \"RS\", // Record Separator\n 0x1F: \"US\", // Unit Separator\n 0x7F: \"DEL\"\n};\n\n/*\n * Refer to: https://en.wikipedia.org/wiki/Code_page_437\n */\nStr.CP437ToUnicode = [\n '\\u0000', '\\u263A', '\\u263B', '\\u2665', '\\u2666', '\\u2663', '\\u2660', '\\u2022',\n '\\u25D8', '\\u25CB', '\\u25D9', '\\u2642', '\\u2640', '\\u266A', '\\u266B', '\\u263C',\n '\\u25BA', '\\u25C4', '\\u2195', '\\u203C', '\\u00B6', '\\u00A7', '\\u25AC', '\\u21A8',\n '\\u2191', '\\u2193', '\\u2192', '\\u2190', '\\u221F', '\\u2194', '\\u25B2', '\\u25BC',\n '\\u0020', '\\u0021', '\\u0022', '\\u0023', '\\u0024', '\\u0025', '\\u0026', '\\u0027',\n '\\u0028', '\\u0029', '\\u002A', '\\u002B', '\\u002C', '\\u002D', '\\u002E', '\\u002F',\n '\\u0030', '\\u0031', '\\u0032', '\\u0033', '\\u0034', '\\u0035', '\\u0036', '\\u0037',\n '\\u0038', '\\u0039', '\\u003A', '\\u003B', '\\u003C', '\\u003D', '\\u003E', '\\u003F',\n '\\u0040', '\\u0041', '\\u0042', '\\u0043', '\\u0044', '\\u0045', '\\u0046', '\\u0047',\n '\\u0048', '\\u0049', '\\u004A', '\\u004B', '\\u004C', '\\u004D', '\\u004E', '\\u004F',\n '\\u0050', '\\u0051', '\\u0052', '\\u0053', '\\u0054', '\\u0055', '\\u0056', '\\u0057',\n '\\u0058', '\\u0059', '\\u005A', '\\u005B', '\\u005C', '\\u005D', '\\u005E', '\\u005F',\n '\\u0060', '\\u0061', '\\u0062', '\\u0063', '\\u0064', '\\u0065', '\\u0066', '\\u0067',\n '\\u0068', '\\u0069', '\\u006A', '\\u006B', '\\u006C', '\\u006D', '\\u006E', '\\u006F',\n '\\u0070', '\\u0071', '\\u0072', '\\u0073', '\\u0074', '\\u0075', '\\u0076', '\\u0077',\n '\\u0078', '\\u0079', '\\u007A', '\\u007B', '\\u007C', '\\u007D', '\\u007E', '\\u2302',\n '\\u00C7', '\\u00FC', '\\u00E9', '\\u00E2', '\\u00E4', '\\u00E0', '\\u00E5', '\\u00E7',\n '\\u00EA', '\\u00EB', '\\u00E8', '\\u00EF', '\\u00EE', '\\u00EC', '\\u00C4', '\\u00C5',\n '\\u00C9', '\\u00E6', '\\u00C6', '\\u00F4', '\\u00F6', '\\u00F2', '\\u00FB', '\\u00F9',\n '\\u00FF', '\\u00D6', '\\u00DC', '\\u00A2', '\\u00A3', '\\u00A5', '\\u20A7', '\\u0192',\n '\\u00E1', '\\u00ED', '\\u00F3', '\\u00FA', '\\u00F1', '\\u00D1', '\\u00AA', '\\u00BA',\n '\\u00BF', '\\u2310', '\\u00AC', '\\u00BD', '\\u00BC', '\\u00A1', '\\u00AB', '\\u00BB',\n '\\u2591', '\\u2592', '\\u2593', '\\u2502', '\\u2524', '\\u2561', '\\u2562', '\\u2556',\n '\\u2555', '\\u2563', '\\u2551', '\\u2557', '\\u255D', '\\u255C', '\\u255B', '\\u2510',\n '\\u2514', '\\u2534', '\\u252C', '\\u251C', '\\u2500', '\\u253C', '\\u255E', '\\u255F',\n '\\u255A', '\\u2554', '\\u2569', '\\u2566', '\\u2560', '\\u2550', '\\u256C', '\\u2567',\n '\\u2568', '\\u2564', '\\u2565', '\\u2559', '\\u2558', '\\u2552', '\\u2553', '\\u256B',\n '\\u256A', '\\u2518', '\\u250C', '\\u2588', '\\u2584', '\\u258C', '\\u2590', '\\u2580',\n '\\u03B1', '\\u00DF', '\\u0393', '\\u03C0', '\\u03A3', '\\u03C3', '\\u00B5', '\\u03C4',\n '\\u03A6', '\\u0398', '\\u03A9', '\\u03B4', '\\u221E', '\\u03C6', '\\u03B5', '\\u2229',\n '\\u2261', '\\u00B1', '\\u2265', '\\u2264', '\\u2320', '\\u2321', '\\u00F7', '\\u2248',\n '\\u00B0', '\\u2219', '\\u00B7', '\\u221A', '\\u207F', '\\u00B2', '\\u25A0', '\\u00A0'\n];\n\n/*\n * TODO: Future home of a complete ASCII table.\n */\nStr.ASCII = {\n LF: 0x0A,\n CR: 0x0D\n};\n\nStr.TYPES = {\n NULL: 0,\n BYTE: 1,\n WORD: 2,\n DWORD: 3,\n NUMBER: 4,\n STRING: 5,\n BOOLEAN: 6,\n OBJECT: 7,\n ARRAY: 8\n};\n\nStr.HexLowerCase = \"0123456789abcdef\";\nStr.HexUpperCase = \"0123456789ABCDEF\";\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/usrlib.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @typedef {{\n * mask: number,\n * shift: number\n * }}\n */\nvar BitField;\n\n/**\n * @typedef {Object.<BitField>}\n */\nvar BitFields;\n\nclass Usr {\n /**\n * binarySearch(a, v, fnCompare)\n *\n * @param {Array} a is an array\n * @param {number|string|Array|Object} v\n * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]\n * @return {number} the index of matching entry if non-negative, otherwise the index of the insertion point\n */\n static binarySearch(a, v, fnCompare)\n {\n var left = 0;\n var right = a.length;\n var found = 0;\n if (fnCompare === undefined) {\n fnCompare = function(a, b)\n {\n return a > b ? 1 : a < b ? -1 : 0;\n };\n }\n while (left < right) {\n var middle = (left + right) >> 1;\n var compareResult;\n compareResult = fnCompare(v, a[middle]);\n if (compareResult > 0) {\n left = middle + 1;\n } else {\n right = middle;\n found = !compareResult;\n }\n }\n return found ? left : ~left;\n }\n\n /**\n * binaryInsert(a, v, fnCompare)\n *\n * If element v already exists in array a, the array is unchanged (we don't allow duplicates); otherwise, the\n * element is inserted into the array at the appropriate index.\n *\n * @param {Array} a is an array\n * @param {number|string|Array|Object} v is the value to insert\n * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]\n */\n static binaryInsert(a, v, fnCompare)\n {\n var index = Usr.binarySearch(a, v, fnCompare);\n if (index < 0) {\n a.splice(-(index + 1), 0, v);\n }\n }\n\n /**\n * getTimestamp()\n *\n * @return {string} timestamp containing the current date and time (\"yyyy-mm-dd hh:mm:ss\")\n */\n static getTimestamp()\n {\n return Usr.formatDate(\"Y-m-d H:i:s\");\n }\n\n /**\n * getMonthDays(nMonth, nYear)\n *\n * Note that if we're being called on behalf of the RTC, its year is always truncated to two digits (mod 100),\n * so we have no idea what century the year 0 might refer to. When using the normal leap-year formula, 0 fails\n * the mod 100 test but passes the mod 400 test, so as far as the RTC is concerned, every century year is a leap\n * year. Since we're most likely dealing with the year 2000, that's fine, since 2000 was also a leap year.\n *\n * TODO: There IS a separate CMOS byte that's supposed to be set to CMOS_ADDR.CENTURY_DATE; it's always BCD,\n * so theoretically it will contain values like 0x19 or 0x20 (for the 20th and 21st centuries, respectively), and\n * we could add that as another parameter to this function, to improve the accuracy, but that would go beyond what\n * a real RTC actually does.\n *\n * @param {number} nMonth (1-12)\n * @param {number} nYear (normally a 4-digit year, but it may also be mod 100)\n * @return {number} the maximum (1-based) day allowed for the specified month and year\n */\n static getMonthDays(nMonth, nYear)\n {\n var nDays = Usr.aMonthDays[nMonth - 1];\n if (nDays == 28) {\n if ((nYear % 4) === 0 && ((nYear % 100) || (nYear % 400) === 0)) {\n nDays++;\n }\n }\n return nDays;\n }\n\n /**\n * formatDate(sFormat, date)\n *\n * @param {string} sFormat (eg, \"F j, Y\", \"Y-m-d H:i:s\")\n * @param {Date} [date] (default is the current time)\n * @return {string}\n *\n * Supported identifiers in sFormat include:\n *\n * a: lowercase ante meridiem and post meridiem (am or pm)\n * d: day of the month, 2 digits with leading zeros (01,02,...,31)\n * D: 3-letter day of the week (\"Sun\",\"Mon\",...,\"Sat\")\n * F: month (\"January\",\"February\",...,\"December\")\n * g: hour in 12-hour format, without leading zeros (1,2,...,12)\n * h: hour in 24-hour format, without leading zeros (0,1,...,23)\n * H: hour in 24-hour format, with leading zeros (00,01,...,23)\n * i: minutes, with leading zeros (00,01,...,59)\n * j: day of the month, without leading zeros (1,2,...,31)\n * l: day of the week (\"Sunday\",\"Monday\",...,\"Saturday\")\n * m: month, with leading zeros (01,02,...,12)\n * M: 3-letter month (\"Jan\",\"Feb\",...,\"Dec\")\n * n: month, without leading zeros (1,2,...,12)\n * s: seconds, with leading zeros (00,01,...,59)\n * y: 2-digit year (eg, 14)\n * Y: 4-digit year (eg, 2014)\n *\n * For more inspiration, see: http://php.net/manual/en/function.date.php (of which we support ONLY a subset).\n */\n static formatDate(sFormat, date)\n {\n var sDate = \"\";\n if (!date) date = new Date();\n var iHour = date.getHours();\n var iDay = date.getDate();\n var iMonth = date.getMonth() + 1;\n for (var i = 0; i < sFormat.length; i++) {\n var ch;\n switch ((ch = sFormat.charAt(i))) {\n case 'a':\n sDate += (iHour < 12 ? \"am\" : \"pm\");\n break;\n case 'd':\n sDate += ('0' + iDay).slice(-2);\n break;\n case 'D':\n sDate += Usr.asDays[date.getDay()].substr(0, 3);\n break;\n case 'F':\n sDate += Usr.asMonths[iMonth - 1];\n break;\n case 'g':\n sDate += (!iHour ? 12 : (iHour > 12 ? iHour - 12 : iHour));\n break;\n case 'h':\n sDate += iHour;\n break;\n case 'H':\n sDate += ('0' + iHour).slice(-2);\n break;\n case 'i':\n sDate += ('0' + date.getMinutes()).slice(-2);\n break;\n case 'j':\n sDate += iDay;\n break;\n case 'l':\n sDate += Usr.asDays[date.getDay()];\n break;\n case 'm':\n sDate += ('0' + iMonth).slice(-2);\n break;\n case 'M':\n sDate += Usr.asMonths[iMonth - 1].substr(0, 3);\n break;\n case 'n':\n sDate += iMonth;\n break;\n case 's':\n sDate += ('0' + date.getSeconds()).slice(-2);\n break;\n case 'y':\n sDate += (\"\" + date.getFullYear()).slice(-2);\n break;\n case 'Y':\n sDate += date.getFullYear();\n break;\n default:\n sDate += ch;\n break;\n }\n }\n return sDate;\n }\n\n /**\n * defineBitFields(bfs)\n *\n * Prepares a bit field definition for use with getBitField() and setBitField(); eg:\n *\n * var bfs = Usr.defineBitFields({num:20, count:8, btmod:1, type:3});\n *\n * The above defines a set of bit fields containing four fields: num (bits 0-19), count (bits 20-27), btmod (bit 28), and type (bits 29-31).\n *\n * Usr.setBitField(bfs.num, n, 1);\n *\n * The above set bit field \"bfs.num\" in numeric variable \"n\" to the value 1.\n *\n * @param {Object} bfs\n * @return {BitFields}\n */\n static defineBitFields(bfs)\n {\n var bit = 0;\n for (var f in bfs) {\n var width = bfs[f];\n var mask = ((1 << width) - 1) << bit;\n bfs[f] = {mask: mask, shift: bit};\n bit += width;\n }\n return bfs;\n }\n\n /**\n * initBitFields(bfs, ...)\n *\n * @param {BitFields} bfs\n * @param {...number} var_args\n * @return {number} a value containing all supplied bit fields\n */\n static initBitFields(bfs, var_args)\n {\n var v = 0, i = 1;\n for (var f in bfs) {\n if (i >= arguments.length) break;\n v = Usr.setBitField(bfs[f], v, arguments[i++]);\n }\n return v;\n }\n\n /**\n * getBitField(bf, v)\n *\n * @param {BitField} bf\n * @param {number} v is a value containing bit fields\n * @return {number} the value of the bit field in v defined by bf\n */\n static getBitField(bf, v)\n {\n return (v & bf.mask) >> bf.shift;\n }\n\n /**\n * setBitField(bf, v, n)\n *\n * @param {BitField} bf\n * @param {number} v is a value containing bit fields\n * @param {number} n is a value to store in v in the bit field defined by bf\n * @return {number} updated v\n */\n static setBitField(bf, v, n)\n {\n return (v & ~bf.mask) | ((n << bf.shift) & bf.mask);\n }\n\n /**\n * indexOf(a, t, i)\n *\n * Use this instead of Array.prototype.indexOf() if you can't be sure the browser supports it.\n *\n * @param {Array} a\n * @param {*} t\n * @param {number} [i]\n * @returns {number}\n */\n static indexOf(a, t, i)\n {\n if (Array.prototype.indexOf) {\n return a.indexOf(t, i);\n }\n i = i || 0;\n if (i < 0) i += a.length;\n if (i < 0) i = 0;\n for (var n = a.length; i < n; i++) {\n if (i in a && a[i] === t) return i;\n }\n return -1;\n }\n}\n\nUsr.asDays = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\nUsr.asMonths = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\nUsr.aMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\n/**\n * getTime()\n *\n * @return {number} the current time, in milliseconds\n */\nUsr.getTime = Date.now || function() { return +new Date(); };\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/weblib.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * According to http://www.w3schools.com/jsref/jsref_obj_global.asp, these are the *global* properties\n * and functions of JavaScript-in-the-Browser:\n *\n * Property Description\n * ---\n * Infinity A numeric value that represents positive/negative infinity\n * NaN \"Not-a-Number\" value\n * undefined Indicates that a variable has not been assigned a value\n *\n * Function Description\n * ---\n * decodeURI() Decodes a URI\n * decodeURIComponent() Decodes a URI component\n * encodeURI() Encodes a URI\n * encodeURIComponent() Encodes a URI component\n * escape() Deprecated in version 1.5. Use encodeURI() or encodeURIComponent() instead\n * eval() Evaluates a string and executes it as if it was script code\n * isFinite() Determines whether a value is a finite, legal number\n * isNaN() Determines whether a value is an illegal number\n * Number() Converts an object's value to a number\n * parseFloat() Parses a string and returns a floating point number\n * parseInt() Parses a string and returns an integer\n * String() Converts an object's value to a string\n * unescape() Deprecated in version 1.5. Use decodeURI() or decodeURIComponent() instead\n *\n * And according to http://www.w3schools.com/jsref/obj_window.asp, these are the properties and functions\n * of the *window* object.\n *\n * Property Description\n * ---\n * closed Returns a Boolean value indicating whether a window has been closed or not\n * defaultStatus Sets or returns the default text in the statusbar of a window\n * document Returns the Document object for the window (See Document object)\n * frames Returns an array of all the frames (including iframes) in the current window\n * history Returns the History object for the window (See History object)\n * innerHeight Returns the inner height of a window's content area\n * innerWidth Returns the inner width of a window's content area\n * length Returns the number of frames (including iframes) in a window\n * location Returns the Location object for the window (See Location object)\n * name Sets or returns the name of a window\n * navigator Returns the Navigator object for the window (See Navigator object)\n * opener Returns a reference to the window that created the window\n * outerHeight Returns the outer height of a window, including toolbars/scrollbars\n * outerWidth Returns the outer width of a window, including toolbars/scrollbars\n * pageXOffset Returns the pixels the current document has been scrolled (horizontally) from the upper left corner of the window\n * pageYOffset Returns the pixels the current document has been scrolled (vertically) from the upper left corner of the window\n * parent Returns the parent window of the current window\n * screen Returns the Screen object for the window (See Screen object)\n * screenLeft Returns the x coordinate of the window relative to the screen\n * screenTop Returns the y coordinate of the window relative to the screen\n * screenX Returns the x coordinate of the window relative to the screen\n * screenY Returns the y coordinate of the window relative to the screen\n * self Returns the current window\n * status Sets or returns the text in the statusbar of a window\n * top Returns the topmost browser window\n *\n * Method Description\n * ---\n * alert() Displays an alert box with a message and an OK button\n * atob() Decodes a base-64 encoded string\n * blur() Removes focus from the current window\n * btoa() Encodes a string in base-64\n * clearInterval() Clears a timer set with setInterval()\n * clearTimeout() Clears a timer set with setTimeout()\n * close() Closes the current window\n * confirm() Displays a dialog box with a message and an OK and a Cancel button\n * createPopup() Creates a pop-up window\n * focus() Sets focus to the current window\n * moveBy() Moves a window relative to its current position\n * moveTo() Moves a window to the specified position\n * open() Opens a new browser window\n * print() Prints the content of the current window\n * prompt() Displays a dialog box that prompts the visitor for input\n * resizeBy() Resizes the window by the specified pixels\n * resizeTo() Resizes the window to the specified width and height\n * scroll() This method has been replaced by the scrollTo() method.\n * scrollBy() Scrolls the content by the specified number of pixels\n * scrollTo() Scrolls the content to the specified coordinates\n * setInterval() Calls a function or evaluates an expression at specified intervals (in milliseconds)\n * setTimeout() Calls a function or evaluates an expression after a specified number of milliseconds\n * stop() Stops the window from loading\n */\n\nclass Web {\n /**\n * log(s, type)\n *\n * For diagnostic output only. DEBUG must be true (or \"--debug\" specified via the command-line)\n * for Component.log() to display anything.\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n static log(s, type)\n {\n Component.log(s, type);\n }\n\n /**\n * notice(s, fPrintOnly, id)\n *\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n */\n static notice(s, fPrintOnly, id)\n {\n Component.notice(s, fPrintOnly, id);\n }\n\n /**\n * alertUser(sMessage)\n * \n * NOTE: Legacy function for older modules (eg, DiskDump); see Component.alertUser().\n *\n * @param {string} sMessage\n */\n static alertUser(sMessage)\n {\n if (window) {\n window.alert(sMessage);\n } else {\n Web.log(sMessage);\n }\n }\n\n /**\n * getResource(sURL, type, fAsync, done, progress)\n *\n * Request the specified resource (sURL), and once the request is complete, notify done().\n *\n * If fAsync is true, a done() callback should ALWAYS be supplied; otherwise, you'll have no\n * idea when the request is complete or what the response was. done() is passed three parameters:\n *\n * done(sURL, resource, nErrorCode)\n *\n * If nErrorCode is zero, resource should contain the requested data; otherwise, an error occurred.\n *\n * If type is set to a string, that string can be used to control the response format;\n * by default, the response format is plain text, but you can specify \"arraybuffer\" to request arbitrary\n * binary data, in which case the returned resource will be a ArrayBuffer rather than a string.\n *\n * @param {string} sURL\n * @param {string|Object|null} [type] (object for POST request, otherwise type of GET request)\n * @param {boolean} [fAsync] is true for an asynchronous request; false otherwise (MUST be set for IE)\n * @param {function(string,string,number)} [done]\n * @param {function(number)} [progress]\n * @return {Array|null} Array containing [resource, nErrorCode], or null if no response available (yet)\n */\n static getResource(sURL, type = \"text\", fAsync = false, done, progress)\n {\n var nErrorCode = 0, resource = null, response = null;\n\n if (typeof resources == 'object' && (resource = resources[sURL])) {\n if (done) done(sURL, resource, nErrorCode);\n return [resource, nErrorCode];\n }\n else if (fAsync && typeof resources == 'function') {\n resources(sURL, function(resource, nErrorCode)\n {\n if (done) done(sURL, resource, nErrorCode);\n });\n return response;\n }\n\n if (!DEBUG && !NODE) {\n /*\n * TODO: Perhaps it's time for our code in netlib.js to finally add support for HTTPS; for now\n * though, it's just as well that the NODE environment assumes all resources are available locally.\n */\n sURL = sURL.replace(/^\\/(pcjs-disks|private-disks)\\//, \"https://jeffpar.github.io/$1/\");\n }\n else {\n /*\n * The larger resources we put on archive.pcjs.org should also be available locally.\n *\n * NOTE: \"http://archive.pcjs.org\" is now \"https://s3-us-west-2.amazonaws.com/archive.pcjs.org\"\n */\n sURL = sURL.replace(/^(http:\\/\\/archive\\.pcjs\\.org|https:\\/\\/s3-us-west-2\\.amazonaws\\.com\\/archive\\.pcjs\\.org)(\\/.*)\\/([^\\/]*)$/, \"$2/archive/$3\");\n sURL = sURL.replace(/^https:\\/\\/jeffpar\\.github\\.io\\/(pcjs-disks|private-disks)\\/(.*)$/, \"/$1/$2\");\n }\n\n\n var request = (window.XMLHttpRequest? new window.XMLHttpRequest() : new window.ActiveXObject(\"Microsoft.XMLHTTP\"));\n var fArrayBuffer = false, fXHR2 = (typeof request.responseType === 'string');\n \n var callback = function() {\n if (request.readyState !== 4) {\n if (progress) progress(1);\n return null;\n }\n /*\n * The following line was recommended for WebKit, as a work-around to prevent the handler firing multiple\n * times when debugging. Unfortunately, that's not the only XMLHttpRequest problem that occurs when\n * debugging, so I think the WebKit problem is deeper than that. When we have multiple XMLHttpRequests\n * pending, any debugging activity means most of them simply get dropped on floor, so what may actually be\n * happening are mis-notifications rather than redundant notifications.\n *\n * request.onreadystatechange = undefined;\n */\n /*\n * If the request failed due to, say, a CORS policy denial; eg:\n * \n * Failed to load http://www.allbootdisks.com/downloads/Disks/Windows_95_Boot_Disk_Download48/Diskette%20Images/Windows95a.img:\n * Redirect from 'http://www.allbootdisks.com/downloads/Disks/Windows_95_Boot_Disk_Download48/Diskette%20Images/Windows95a.img' to\n * 'http://www.allbootdisks.com/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.\n * Origin 'http://pcjs:8088' is therefore not allowed access.\n * \n * and our request type was \"arraybuffer\", attempting to access responseText may trigger an exception; eg:\n * \n * Uncaught DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's\n * 'responseType' is '' or 'text' (was 'arraybuffer').\n * \n * We could tiptoe around these potential landmines, but the safest thing to do is wrap this code with try/catch.\n */\n try {\n resource = fArrayBuffer? request.response : request.responseText;\n } catch(err) {\n if (MAXDEBUG) Web.log(\"xmlHTTPRequest(\" + sURL + \") exception: \" + err.message);\n }\n /*\n * The normal \"success\" case is a non-null resource and an HTTP status code of 200, but when loading files from the\n * local file system (ie, when using the \"file:\" protocol), we have to be a bit more flexible.\n */\n if (resource != null && (request.status == 200 || !request.status && resource.length && Web.getHostProtocol() == \"file:\")) {\n if (MAXDEBUG) Web.log(\"xmlHTTPRequest(\" + sURL + \"): returned \" + resource.length + \" bytes\");\n }\n else {\n nErrorCode = request.status || -1;\n Web.log(\"xmlHTTPRequest(\" + sURL + \"): error code \" + nErrorCode);\n }\n if (progress) progress(2);\n if (done) done(sURL, resource, nErrorCode);\n return [resource, nErrorCode];\n };\n \n if (fAsync) {\n request.onreadystatechange = callback;\n }\n\n if (progress) progress(0);\n\n if (type && typeof type == \"object\") {\n var sPost = \"\";\n for (var p in type) {\n if (!type.hasOwnProperty(p)) continue;\n if (sPost) sPost += \"&\";\n sPost += p + '=' + encodeURIComponent(type[p]);\n }\n sPost = sPost.replace(/%20/g, '+');\n if (MAXDEBUG) Web.log(\"Web.getResource(POST \" + sURL + \"): \" + sPost.length + \" bytes\");\n request.open(\"POST\", sURL, fAsync);\n request.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\n request.send(sPost);\n } else {\n if (MAXDEBUG) Web.log(\"Web.getResource(GET \" + sURL + \")\");\n request.open(\"GET\", sURL, fAsync);\n if (type == \"arraybuffer\") {\n if (fXHR2) {\n fArrayBuffer = true;\n request.responseType = type;\n } else {\n request.overrideMimeType(\"text/plain; charset=x-user-defined\");\n }\n }\n request.send();\n }\n\n if (!fAsync) {\n request.readyState = 4; // this may already be set for synchronous requests, but I don't want to take any chances \n response = callback();\n }\n return response;\n }\n\n /**\n * parseMemoryResource(sURL, sData)\n *\n * This converts a variety of JSON-style data streams into an Object with the following properties:\n *\n * aBytes\n * aSymbols\n * addrLoad\n * addrExec\n *\n * If the source data contains a 'bytes' array, it's passed through to 'aBytes'; alternatively, if\n * it contains a 'words' array, the values are converted from 16-bit to 8-bit and stored in 'aBytes',\n * and if it contains a 'longs' array, the values are converted from 32-bit longs into bytes and\n * stored in 'aBytes'.\n *\n * Alternatively, if the source data contains a 'data' array, we simply pass that through to the output\n * object as:\n *\n * aData\n *\n * @param {string} sURL\n * @param {string} sData\n * @return {Object|null} (resource)\n */\n static parseMemoryResource(sURL, sData)\n {\n var i;\n var resource = {\n aBytes: null,\n aSymbols: null,\n addrLoad: null,\n addrExec: null\n };\n\n if (sData.charAt(0) == \"[\" || sData.charAt(0) == \"{\") {\n try {\n var a, ib, data;\n\n if (sData.substr(0, 1) == \"<\") { // if the \"data\" begins with a \"<\"...\n /*\n * Early server configs reported an error (via the nErrorCode parameter) if a tape URL was invalid,\n * but more recent server configs now display a somewhat friendlier HTML error page. The downside,\n * however, is that the original error has been buried, and we've received \"data\" that isn't actually\n * tape data. So if the data we've received appears to be \"HTML-like\", we treat it as an error message.\n */\n throw new Error(sData);\n }\n\n /*\n * TODO: IE9 is rather unfriendly and restrictive with regard to how much data it's willing to\n * eval(). In particular, the 10Mb disk image we use for the Windows 1.01 demo config fails in\n * IE9 with an \"Out of memory\" exception. One work-around would be to chop the data into chunks\n * (perhaps one track per chunk, using regular expressions) and then manually re-assemble it.\n *\n * However, it turns out that using JSON.parse(sDiskData) instead of eval(\"(\" + sDiskData + \")\")\n * is a much easier fix. The only drawback is that we must first quote any unquoted property names\n * and remove any comments, because while eval() was cool with them, JSON.parse() is more particular;\n * the following RegExp replacements take care of those requirements.\n *\n * The use of hex values is something else that eval() was OK with, but JSON.parse() is not, and\n * while I've stopped using hex values in DumpAPI responses (at least when \"format=json\" is specified),\n * I can't guarantee they won't show up in \"legacy\" images, and there's no simple RegExp replacement\n * for transforming hex values into decimal values, so I cop out and fall back to eval() if I detect\n * any hex prefixes (\"0x\") in the sequence. Ditto for error messages, which appear like so:\n *\n * [\"unrecognized disk path: test.img\"]\n */\n if (sData.indexOf(\"0x\") < 0 && sData.indexOf(\"0o\") < 0 && sData.substr(0, 2) != '[\"') {\n data = JSON.parse(sData.replace(/([a-z]+):/gm, '\"$1\":').replace(/\\/\\/[^\\n]*/gm, \"\"));\n } else {\n data = eval(\"(\" + sData + \")\");\n }\n\n resource.addrLoad = data['load'];\n resource.addrExec = data['exec'];\n\n if (a = data['bytes']) {\n resource.aBytes = a;\n }\n else if (a = data['words']) {\n /*\n * Convert all words into bytes\n */\n resource.aBytes = new Array(a.length * 2);\n for (i = 0, ib = 0; i < a.length; i++) {\n resource.aBytes[ib++] = a[i] & 0xff;\n resource.aBytes[ib++] = (a[i] >> 8) & 0xff;\n\n }\n }\n else if (a = data['longs']) {\n /*\n * Convert all dwords (longs) into bytes\n */\n resource.aBytes = new Array(a.length * 4);\n for (i = 0, ib = 0; i < a.length; i++) {\n resource.aBytes[ib++] = a[i] & 0xff;\n resource.aBytes[ib++] = (a[i] >> 8) & 0xff;\n resource.aBytes[ib++] = (a[i] >> 16) & 0xff;\n resource.aBytes[ib++] = (a[i] >> 24) & 0xff;\n }\n }\n else if (a = data['data']) {\n resource.aData = a;\n }\n else {\n resource.aBytes = data;\n }\n\n if (resource.aBytes) {\n if (!resource.aBytes.length) {\n Component.error(\"Empty resource: \" + sURL);\n resource = null;\n }\n else if (resource.aBytes.length == 1) {\n Component.error(resource.aBytes[0]);\n resource = null;\n }\n }\n resource.aSymbols = data['symbols'];\n\n } catch (e) {\n Component.error(\"Resource data error (\" + sURL + \"): \" + e.message);\n resource = null;\n }\n }\n else {\n /*\n * Parse the data manually; we assume it's a series of hex byte-values separated by whitespace.\n */\n var ab = [];\n var sHexData = sData.replace(/\\n/gm, \" \").replace(/ +$/, \"\");\n var asHexData = sHexData.split(\" \");\n for (i = 0; i < asHexData.length; i++) {\n var n = parseInt(asHexData[i], 16);\n if (isNaN(n)) {\n Component.error(\"Resource data error (\" + sURL + \"): invalid hex byte (\" + asHexData[i] + \")\");\n break;\n }\n ab.push(n & 0xff);\n }\n if (i == asHexData.length) resource.aBytes = ab;\n }\n return resource;\n }\n\n /**\n * sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)\n *\n * Send a report (eg, bug report) to the server.\n *\n * @param {string} sApp (eg, \"PCjs\")\n * @param {string} sVer (eg, \"1.02\")\n * @param {string} sURL (eg, \"/devices/pc/machine/5150/mda/64kb/machine.xml\")\n * @param {string} sUser (ie, the user key, if any)\n * @param {string} sType (eg, \"bug\"); one of ReportAPI.TYPE.*\n * @param {string} sReport (eg, unparsed state data)\n * @param {string} [sHostName] (default is http://SITEHOST)\n */\n static sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)\n {\n var dataPost = {};\n dataPost[ReportAPI.QUERY.APP] = sApp;\n dataPost[ReportAPI.QUERY.VER] = sVer;\n dataPost[ReportAPI.QUERY.URL] = sURL;\n dataPost[ReportAPI.QUERY.USER] = sUser;\n dataPost[ReportAPI.QUERY.TYPE] = sType;\n dataPost[ReportAPI.QUERY.DATA] = sReport;\n var sReportURL = (sHostName? sHostName : \"http://\" + SITEHOST) + ReportAPI.ENDPOINT;\n Web.getResource(sReportURL, dataPost, true);\n }\n\n /**\n * getHost()\n *\n * @return {string}\n */\n static getHost()\n {\n return (\"http://\" + (window? window.location.host : SITEHOST));\n }\n\n /**\n * getHostURL()\n *\n * @return {string|null}\n */\n static getHostURL()\n {\n return (window? window.location.href : null);\n }\n\n /**\n * getHostProtocol()\n *\n * @return {string}\n */\n static getHostProtocol()\n {\n return (window? window.location.protocol : \"file:\");\n }\n\n /**\n * getUserAgent()\n *\n * @return {string}\n */\n static getUserAgent()\n {\n return (window? window.navigator.userAgent : \"\");\n }\n\n /**\n * hasLocalStorage\n *\n * true if localStorage support exists, is enabled, and works; false otherwise\n *\n * @return {boolean}\n */\n static hasLocalStorage()\n {\n if (Web.fLocalStorage == null) {\n var f = false;\n if (window) {\n try {\n window.localStorage.setItem(Web.sLocalStorageTest, Web.sLocalStorageTest);\n f = (window.localStorage.getItem(Web.sLocalStorageTest) == Web.sLocalStorageTest);\n window.localStorage.removeItem(Web.sLocalStorageTest);\n } catch (e) {\n Web.logLocalStorageError(e);\n f = false;\n }\n }\n Web.fLocalStorage = f;\n }\n return Web.fLocalStorage;\n }\n\n /**\n * logLocalStorageError(e)\n *\n * @param {Error} e is an exception\n */\n static logLocalStorageError(e)\n {\n Web.log(e.message, \"localStorage error\");\n }\n\n /**\n * getLocalStorageItem(sKey)\n *\n * Returns the requested key value, or null if the key does not exist, or undefined if localStorage is not available\n *\n * @param {string} sKey\n * @return {string|null|undefined} sValue\n */\n static getLocalStorageItem(sKey)\n {\n var sValue;\n if (window) {\n try {\n sValue = window.localStorage.getItem(sKey);\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n }\n return sValue;\n }\n\n /**\n * setLocalStorageItem(sKey, sValue)\n *\n * @param {string} sKey\n * @param {string} sValue\n * @return {boolean} true if localStorage is available, false if not\n */\n static setLocalStorageItem(sKey, sValue)\n {\n try {\n window.localStorage.setItem(sKey, sValue);\n return true;\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n return false;\n }\n\n /**\n * removeLocalStorageItem(sKey)\n *\n * @param {string} sKey\n */\n static removeLocalStorageItem(sKey)\n {\n try {\n window.localStorage.removeItem(sKey);\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n }\n\n /**\n * getLocalStorageKeys()\n *\n * @return {Array}\n */\n static getLocalStorageKeys()\n {\n var a = [];\n try {\n for (var i = 0, c = window.localStorage.length; i < c; i++) {\n a.push(window.localStorage.key(i));\n }\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n return a;\n }\n\n /**\n * reloadPage()\n */\n static reloadPage()\n {\n if (window) window.location.reload();\n }\n\n /**\n * isUserAgent(s)\n *\n * Check the browser's user-agent string for the given substring; \"iOS\" and \"MSIE\" are special values you can\n * use that will match any iOS or MSIE browser, respectively (even IE11, in the case of \"MSIE\").\n *\n * 2013-11-06: In a questionable move, MSFT changed the user-agent reported by IE11 on Windows 8.1, eliminating\n * the \"MSIE\" string (which MSDN calls a \"version token\"; see http://msdn.microsoft.com/library/ms537503.aspx);\n * they say \"public websites should rely on feature detection, rather than browser detection, in order to design\n * their sites for browsers that don't support the features used by the website.\" So, in IE11, we get a user-agent\n * that tries to fool apps into thinking the browser is more like WebKit or Gecko:\n *\n * Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko\n *\n * That's a nice idea, but in the meantime, they hosed the XSL transform code in embed.js, which contained\n * some very critical browser-specific code; turning on IE's \"Compatibility Mode\" didn't help either, because\n * that's a sledgehammer solution which restores the old user-agent string but also disables other features like\n * HTML5 canvas support. As an interim solution, I'm treating any \"MSIE\" check as a check for either \"MSIE\" or\n * \"Trident\".\n *\n * UPDATE: I've since found ways to make the code in embed.js more browser-agnostic, so for now, there's isn't\n * any code that cares about \"MSIE\", but I've left the change in place, because I wouldn't be surprised if I'll\n * need more IE-specific code in the future, perhaps for things like copy/paste functionality, or mouse capture.\n *\n * @param {string} s is a substring to search for in the user-agent; as noted above, \"iOS\" and \"MSIE\" are special values\n * @return {boolean} is true if the string was found, false if not\n */\n static isUserAgent(s)\n {\n if (window) {\n var userAgent = Web.getUserAgent();\n /*\n * Here's one case where we have to be careful with Component, because when isUserAgent() is called by\n * the init code below, component.js hasn't been loaded yet. The simple solution for now is to remove the call.\n *\n * Web.log(\"agent: \" + userAgent);\n *\n * And yes, it would be pointless to use the conditional (?) operator below, if not for the Google Closure\n * Compiler (v20130823) failing to detect the entire expression as a boolean.\n */\n return s == \"iOS\" && !!userAgent.match(/(iPod|iPhone|iPad)/) && !!userAgent.match(/AppleWebKit/) || s == \"MSIE\" && !!userAgent.match(/(MSIE|Trident)/) || (userAgent.indexOf(s) >= 0);\n }\n return false;\n }\n\n /**\n * isMobile(sDevice)\n *\n * Checks the URL for a \"mobile\" parameter, and failing that, checks the browser's user-agent string for the\n * substring \"Mobi\", as per Mozilla recommendation:\n *\n * https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent\n *\n * @param {string} [sDevice] (eg, \"iPad\" to check for iPad, or \"!iPad\" to specifically exclude it) \n * @return {boolean} is true if the browser appears to be a mobile (ie, non-desktop) web browser, false if not\n */\n static isMobile(sDevice)\n {\n var sMobile = Web.getURLParm(\"mobile\");\n if (sMobile) return sMobile == \"true\";\n if (Web.isUserAgent(\"Mobi\")) {\n if (!sDevice) return true;\n var fInvert = sDevice[0] == '!';\n if (fInvert) sDevice = sDevice.substr(1);\n return Web.isUserAgent(sDevice) != fInvert;\n }\n return false;\n }\n\n /**\n * findProperty(obj, sProp, sSuffix)\n *\n * If both sProp and sSuffix are set, then any browser-specific prefixes are inserted between sProp and sSuffix,\n * and if a match is found, it is returned without sProp.\n *\n * For example, if findProperty(document, 'on', 'fullscreenchange') discovers that 'onwebkitfullscreenchange' exists,\n * it will return 'webkitfullscreenchange', in preparation for an addEventListener() call.\n *\n * More commonly, sSuffix is not used, so whatever property is found is returned as-is.\n *\n * @param {Object|null|undefined} obj\n * @param {string} sProp\n * @param {string} [sSuffix]\n * @return {string|null}\n */\n static findProperty(obj, sProp, sSuffix)\n {\n if (obj) {\n for (var i = 0; i < Web.asBrowserPrefixes.length; i++) {\n var sName = Web.asBrowserPrefixes[i];\n if (sSuffix) {\n sName += sSuffix;\n var sEvent = sProp + sName;\n if (sEvent in obj) return sName;\n } else {\n if (!sName) {\n sName = sProp[0];\n } else {\n sName += sProp[0].toUpperCase();\n }\n sName += sProp.substr(1);\n if (sName in obj) return sName;\n }\n }\n }\n return null;\n }\n\n /**\n * getURLParm(sParm)\n *\n * First looks for sParm exactly as specified, then looks for the lower-case version.\n *\n * @param {string} sParm\n * @return {string|undefined}\n */\n static getURLParm(sParm)\n {\n if (!Web.parmsURL) {\n Web.parmsURL = Web.parseURLParms();\n }\n return Web.parmsURL[sParm] || Web.parmsURL[sParm.toLowerCase()];\n }\n\n /**\n * parseURLParms(sParms)\n *\n * @param {string} [sParms] containing the parameter portion of a URL (ie, after the '?')\n * @return {Object} containing properties for each parameter found\n */\n static parseURLParms(sParms)\n {\n var aParms = {};\n if (window) { // an alternative to \"if (typeof module === 'undefined')\" if require(\"defines\") was used\n if (!sParms) {\n /*\n * Note that window.location.href returns the entire URL, whereas window.location.search\n * returns only the parameters, if any (starting with the '?', which we skip over with a substr() call).\n */\n sParms = window.location.search.substr(1);\n }\n var match;\n var pl = /\\+/g; // RegExp for replacing addition symbol with a space\n var search = /([^&=]+)=?([^&]*)/g;\n var decode = function(s)\n {\n return decodeURIComponent(s.replace(pl, \" \"));\n };\n\n while ((match = search.exec(sParms))) {\n aParms[decode(match[1])] = decode(match[2]);\n }\n }\n return aParms;\n }\n\n /**\n * downloadFile(sData, sType, fBase64, sFileName)\n *\n * @param {string} sData\n * @param {string} sType\n * @param {boolean} [fBase64]\n * @param {string} [sFileName]\n */\n static downloadFile(sData, sType, fBase64, sFileName)\n {\n var link = null, sAlert;\n var sURI = \"data:application/\" + sType + (fBase64? \";base64\" : \"\") + \",\";\n\n if (!Web.isUserAgent(\"Firefox\")) {\n sURI += (fBase64? sData : encodeURI(sData));\n } else {\n sURI += (fBase64? sData : encodeURIComponent(sData));\n }\n if (sFileName) {\n link = document.createElement('a');\n if (typeof link.download != 'string') link = null;\n }\n if (link) {\n link.href = sURI;\n link.download = sFileName;\n document.body.appendChild(link); // Firefox allegedly requires the link to be in the body\n link.click();\n document.body.removeChild(link);\n sAlert = 'Check your Downloads folder for ' + sFileName + '.';\n if (Web.isUserAgent(\"Chrome\")) {\n sAlert += '\\n\\nIn Chrome, after clicking OK, you may ALSO have to select the \"Window\" menu, choose \"Downloads\", and then locate this download and select \"Keep\".';\n sAlert += '\\n\\nThis is part of Chrome\\'s \"Security By Jumping Through Extra Hoops\" technology, which is much easier for Google to implement than actually checking for something malicious.';\n sAlert += '\\n\\nAnd for the record, there is nothing malicious on the PCjs website.';\n }\n } else {\n window.open(sURI);\n sAlert = 'Check your browser for a new window/tab containing the requested data' + (sFileName? (' (' + sFileName + ')') : '') + '.';\n }\n return sAlert;\n }\n\n /**\n * onCountRepeat(n, fnRepeat, fnComplete, msDelay)\n *\n * Call fnRepeat() n times with an msDelay millisecond delay between calls,\n * then call fnComplete() when n has been exhausted OR fnRepeat() returns false.\n *\n * @param {number} n\n * @param {function()} fnRepeat\n * @param {function()} fnComplete\n * @param {number} [msDelay]\n */\n static onCountRepeat(n, fnRepeat, fnComplete, msDelay)\n {\n var fnTimeout = function doCountRepeat()\n {\n n -= 1;\n if (n >= 0) {\n if (!fnRepeat()) n = 0;\n }\n if (n > 0) {\n setTimeout(fnTimeout, msDelay || 0);\n return;\n }\n fnComplete();\n };\n fnTimeout();\n }\n\n /**\n * onClickRepeat(e, msDelay, msRepeat, fn)\n *\n * Repeatedly call fn() with an initial msDelay, and an msRepeat delay thereafter,\n * as long as HTML control Object e has an active \"down\" event and fn() returns true.\n *\n * @param {Object} e\n * @param {number} msDelay\n * @param {number} msRepeat\n * @param {function(boolean)} fn is passed false on the first call, true on all repeated calls\n */\n static onClickRepeat(e, msDelay, msRepeat, fn)\n {\n var ms = 0, timer = null, fIgnoreMouseEvents = false;\n\n var fnRepeat = function doClickRepeat()\n {\n if (fn(ms === msRepeat)) {\n timer = setTimeout(fnRepeat, ms);\n ms = msRepeat;\n }\n };\n e.onmousedown = function()\n {\n // Web.log(\"onMouseDown()\");\n if (!fIgnoreMouseEvents) {\n if (!timer) {\n ms = msDelay;\n fnRepeat();\n }\n }\n };\n e.ontouchstart = function()\n {\n // Web.log(\"onTouchStart()\");\n if (!timer) {\n ms = msDelay;\n fnRepeat();\n }\n };\n e.onmouseup = e.onmouseout = function()\n {\n // Web.log(\"onMouseUp()/onMouseOut()\");\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n };\n e.ontouchend = e.ontouchcancel = function()\n {\n // Web.log(\"onTouchEnd()/onTouchCancel()\");\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n /*\n * Devices that generate ontouch* events ALSO generate onmouse* events,\n * and generally do so immediately after all the touch events are complete,\n * so unless we want double the action, we need to ignore mouse events.\n */\n fIgnoreMouseEvents = true;\n };\n }\n\n /**\n * onPageEvent(sName, fn)\n *\n * For 'onload', 'onunload', and 'onpageshow' events, most callers should NOT use this function, but\n * instead use Web.onInit(), Web.onShow(), and Web.onExit(), respectively.\n *\n * The only components that should still use onPageEvent() are THIS component (see the bottom of this file)\n * and components that need to capture other events (eg, the 'onresize' event in the Video component).\n *\n * This function creates a chain of callbacks, allowing multiple JavaScript modules to define handlers\n * for the same event, which wouldn't be possible if everyone modified window['onload'], window['onunload'],\n * etc, themselves. However, that's less of a concern now, because assuming everyone else is now using\n * onInit(), onExit(), etc, then there really IS only one component setting the window callback: this one.\n *\n * NOTE: It's risky to refer to obscure event handlers with \"dot\" names, because the Closure Compiler may\n * erroneously replace them (eg, window.onpageshow is a good example).\n *\n * @param {string} sFunc\n * @param {function()} fn\n */\n static onPageEvent(sFunc, fn)\n {\n if (window) {\n var fnPrev = window[sFunc];\n if (typeof fnPrev !== 'function') {\n window[sFunc] = fn;\n } else {\n /*\n * TODO: Determine whether there's any value in receiving/sending the Event object that the\n * browser provides when it generates the original event.\n */\n window[sFunc] = function onWindowEvent()\n {\n if (fnPrev) fnPrev();\n fn();\n };\n }\n }\n };\n\n /**\n * onInit(fn)\n *\n * Use this instead of setting window.onload. Allows multiple JavaScript modules to define their own 'onload' event handler.\n *\n * @param {function()} fn\n */\n static onInit(fn)\n {\n Web.aPageEventHandlers['init'].push(fn);\n };\n\n /**\n * onShow(fn)\n *\n * @param {function()} fn\n *\n * Use this instead of setting window.onpageshow. Allows multiple JavaScript modules to define their own 'onpageshow' event handler.\n */\n static onShow(fn)\n {\n Web.aPageEventHandlers['show'].push(fn);\n };\n\n /**\n * onExit(fn)\n *\n * @param {function()} fn\n *\n * Use this instead of setting window.onunload. Allows multiple JavaScript modules to define their own 'onunload' event handler.\n */\n static onExit(fn)\n {\n Web.aPageEventHandlers['exit'].push(fn);\n };\n\n /**\n * doPageEvent(afn)\n *\n * @param {Array.<function()>} afn\n */\n static doPageEvent(afn)\n {\n if (Web.fPageEventsEnabled) {\n try {\n for (var i = 0; i < afn.length; i++) {\n afn[i]();\n }\n } catch (e) {\n Web.notice(\"An unexpected error occurred: \" + e.message + \"\\n\\nIf it happens again, please send this information to support@pcjs.org. Thanks.\");\n }\n }\n };\n\n /**\n * enablePageEvents(fEnable)\n *\n * @param {boolean} fEnable is true to enable page events, false to disable (they're enabled by default)\n */\n static enablePageEvents(fEnable)\n {\n if (!Web.fPageEventsEnabled && fEnable) {\n Web.fPageEventsEnabled = true;\n if (Web.fPageLoaded) Web.sendPageEvent('init');\n if (Web.fPageShowed) Web.sendPageEvent('show');\n return;\n }\n Web.fPageEventsEnabled = fEnable;\n }\n\n /**\n * sendPageEvent(sEvent)\n *\n * This allows us to manually trigger page events.\n *\n * @param {string} sEvent (one of 'init', 'show' or 'exit')\n */\n static sendPageEvent(sEvent)\n {\n if (Web.aPageEventHandlers[sEvent]) {\n Web.doPageEvent(Web.aPageEventHandlers[sEvent]);\n }\n }\n}\n\nWeb.parmsURL = null; // initialized on first call to parseURLParms()\n\nWeb.aPageEventHandlers = {\n 'init': [], // list of window 'onload' handlers\n 'show': [], // list of window 'onpageshow' handlers\n 'exit': [] // list of window 'onunload' handlers (although we prefer to use 'onbeforeunload' if possible)\n};\n\nWeb.asBrowserPrefixes = ['', 'moz', 'ms', 'webkit'];\n\nWeb.fPageLoaded = false; // set once the page's first 'onload' event has occurred\nWeb.fPageShowed = false; // set once the page's first 'onpageshow' event has occurred\nWeb.fPageEventsEnabled = true; // default is true, set to false (or true) by enablePageEvents()\n\n/**\n * fLocalStorage\n *\n * true if localStorage support exists, is enabled, and works; \"falsey\" otherwise\n *\n * @type {boolean|null}\n */\nWeb.fLocalStorage = null;\n\n/**\n * TODO: Is there any way to get the Closure Compiler to stop inlining this string? This isn't cutting it.\n *\n * @const {string}\n */\nWeb.sLocalStorageTest = \"PCjs.localStorage\";\n\nWeb.onPageEvent('onload', function onPageLoad() {\n Web.fPageLoaded = true;\n Web.doPageEvent(Web.aPageEventHandlers['init']);\n});\n\nWeb.onPageEvent('onpageshow', function onPageShow() {\n Web.fPageShowed = true;\n Web.doPageEvent(Web.aPageEventHandlers['show']);\n});\n\nWeb.onPageEvent(Web.isUserAgent(\"iOS\")? 'onpagehide' : (Web.isUserAgent(\"Opera\")? 'onunload' : 'onbeforeunload'), function onPageUnload() {\n Web.doPageEvent(Web.aPageEventHandlers['exit']);\n});\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/component.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * All PCjs components now use JSDoc types, primarily so that Google's Closure Compiler will compile\n * everything with zero warnings when ADVANCED_OPTIMIZATIONS are enabled. For more information about\n * the JSDoc types supported by the Closure Compiler:\n *\n * https://developers.google.com/closure/compiler/docs/js-for-compiler#types\n *\n * I also attempted to validate this code with JSLint, but it complained too much; eg, it didn't like\n * \"while (true)\", a tried and \"true\" programming convention for decades, and it wanted me to replace\n * all \"++\" and \"--\" operators with \"+= 1\" and \"-= 1\", use \"(s || '')\" instead of \"(s? s : '')\", etc.\n *\n * I prefer sticking with traditional C-style idioms, in part because they are more portable. That\n * does NOT mean I'm trying to write \"portable JavaScript,\" but some of this code was ported from C code\n * I'd written long ago, so portability is good, and I'm not going to throw that away if there's no need.\n *\n * UPDATE: I've since switched from JSLint to JSHint, which seems to have more reasonable defaults.\n * And for new code, I have adopted some popular JavaScript idioms, like \"(s || '')\", although the need\n * for those kinds of expressions will be reduced as I also start adopting some ES6 features, like\n * default parameters.\n */\n\n\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * subclass (eg, SerialPort), because otherwise the Compiler won't allow us to *reference*\n * the named property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass Component {\n /**\n * Component(type, parms, bitsMessage)\n *\n * A Component object requires:\n *\n * type: a user-defined type name (eg, \"CPU\")\n *\n * and accepts any or all of the following (parms) properties:\n *\n * id: component ID (default is \"\")\n * name: component name (default is \"\"; if blank, toString() will use the type name only)\n * comment: component comment string (default is undefined)\n *\n * Component subclasses will usually have additional (parms) properties.\n *\n * @param {string} type\n * @param {Object} [parms]\n * @param {number} [bitsMessage] selects message(s) that the component wants to enable (default is 0)\n */\n constructor(type, parms, bitsMessage)\n {\n this.type = type;\n\n if (!parms) parms = {'id': \"\", 'name': \"\"};\n\n this.id = parms['id'] || \"\";\n this.name = parms['name'];\n this.comment = parms['comment'];\n this.parms = parms;\n\n /*\n * The following Component properties need to be accessible by other machines and/or command scripts;\n * well, OK, or we could have exported some new functions to walk the contents of these properties, as we\n * did with findMachineComponent(), but this works just as well.\n *\n * Also, while the double-assignment looks silly (ie, using both dot and bracket property notation), it\n * resolves a complaint from the Closure Compiler, because if we use ONLY bracket notation here, then the\n * Compiler wants us to change all the other references to bracket notation as well.\n */\n this.exports = this['exports'] = {};\n this.bindings = this['bindings'] = {};\n\n var i = this.id.indexOf('.');\n if (i < 0) {\n this.idComponent = this.id;\n } else {\n this.idMachine = this.id.substr(0, i);\n this.idComponent = this.id.substr(i + 1);\n }\n\n /*\n * Gather all the various component flags (booleans) into a single \"flags\" object, and encourage\n * subclasses to do the same, to reduce the property clutter we have to wade through while debugging.\n */\n this.flags = {\n ready: false,\n busy: false,\n busyCancel: false,\n initDone: false,\n powered: false,\n unloading: false,\n error: false\n };\n\n this.fnReady = null;\n this.clearError();\n this.bitsMessage = bitsMessage || 0;\n\n this.cmp = null;\n this.bus = null;\n this.cpu = null;\n this.dbg = null;\n\n /*\n * TODO: Consider adding another parameter to the Component() constructor that allows components to tell\n * us if they support single or multiple instances per machine. For example, there can be multiple SerialPort\n * components per machine, but only one CPU component (some machines also support an FPU, but that component\n * is considered separate from the CPU).\n *\n * It's not critical, but it would help catch machine configuration errors; for example, a machine that mistakenly\n * includes two CPU components may, aside from wasting memory, end up with odd side-effects, like unresponsive\n * CPU controls.\n */\n Component.add(this);\n }\n\n /**\n * Component.add(component)\n *\n * @param {Component} component\n */\n static add(component)\n {\n /*\n * This just generates a lot of useless noise, handy in the early days, not so much these days....\n *\n * if (DEBUG) Component.log(\"Component.add(\" + component.type + \",\" + component.id + \")\");\n */\n Component.components.push(component);\n }\n\n /**\n * Component.addMachine(idMachine)\n *\n * @param {string} idMachine\n */\n static addMachine(idMachine)\n {\n Component.machines[idMachine] = {};\n }\n\n /**\n * Component.addMachineResource(idMachine, sName, data)\n *\n * @param {string} idMachine\n * @param {string|null} sName (name of the resource)\n * @param {*} data\n */\n static addMachineResource(idMachine, sName, data)\n {\n /*\n * I used to assert(Component.machines[idMachine]), but when we're running as a Node app, embed.js is not used,\n * so addMachine() is never called, so resources do not need to be recorded.\n */\n if (Component.machines[idMachine] && sName) {\n Component.machines[idMachine][sName] = data;\n }\n }\n\n /**\n * Component.getMachineResources(idMachine)\n *\n * @param {string} idMachine\n * @return {Object|undefined}\n */\n static getMachineResources(idMachine)\n {\n return Component.machines[idMachine];\n }\n\n /**\n * Component.getTime()\n *\n * @return {number} the current time, in milliseconds\n */\n static getTime()\n {\n return Date.now() || +new Date();\n }\n\n /**\n * Component.log(s, type)\n *\n * For diagnostic output only.\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n static log(s, type)\n {\n if (!COMPILED) {\n if (s) {\n var sElapsed = \"\", sMsg = (type? (type + \": \") : \"\") + s;\n if (typeof Usr != \"undefined\") {\n if (Component.msStart === undefined) {\n Component.msStart = Component.getTime();\n }\n sElapsed = (Component.getTime() - Component.msStart) + \"ms: \";\n }\n sMsg = sMsg.replace(/\\r/g, '\\\\r').replace(/\\n/g, ' ');\n if (window && window.console) console.log(sElapsed + sMsg);\n }\n }\n }\n\n /**\n * Component.assert(f, s)\n *\n * Verifies conditions that must be true (for DEBUG builds only).\n *\n * The Closure Compiler should automatically remove all references to Component.assert() in non-DEBUG builds.\n * TODO: Add a task to the build process that \"asserts\" there are no instances of \"assertion failure\" in RELEASE builds.\n *\n * @param {boolean} f is the expression we are asserting to be true\n * @param {string} [s] is description of the assertion on failure\n */\n static assert(f, s)\n {\n if (DEBUG) {\n if (!f) {\n if (!s) s = \"assertion failure\";\n Component.log(s);\n throw new Error(s);\n }\n }\n }\n\n /**\n * Component.print(s)\n *\n * Components that inherit from this class should use this.print(), rather than Component.print(), because\n * if a Control Panel is loaded, it will override only the instance method, not the class method (overriding the\n * class method would improperly affect any other machines loaded on the same page).\n *\n * @this {Component}\n * @param {string} s\n */\n static print(s)\n {\n if (!COMPILED) {\n var i = s.lastIndexOf('\\n');\n if (i >= 0) {\n Component.println(s.substr(0, i));\n s = s.substr(i + 1);\n }\n Component.printBuffer += s;\n }\n }\n\n /**\n * Component.println(s, type, id)\n *\n * Components that inherit from this class should use this.println(), rather than Component.println(), because\n * if a Control Panel is loaded, it will override only the instance method, not the class method (overriding the\n * class method would improperly affect any other machines loaded on the same page).\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n * @param {string} [id] is the caller's ID, if any\n */\n static println(s, type, id)\n {\n if (!COMPILED) {\n s = Component.printBuffer + (s || \"\");\n Component.log((id? (id + \": \") : \"\") + (s? (\"\\\"\" + s + \"\\\"\") : \"\"), type);\n Component.printBuffer = \"\";\n }\n }\n\n /**\n * Component.notice(s, fPrintOnly, id)\n *\n * notice() is like println() but implies a need for user notification, so we alert() as well.\n *\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n * @return {boolean}\n */\n static notice(s, fPrintOnly, id)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.NOTICE, id);\n }\n if (!fPrintOnly) Component.alertUser((id? (id + \": \") : \"\") + s);\n return true;\n }\n\n /**\n * Component.warning(s)\n *\n * @param {string} s describes the warning\n */\n static warning(s)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.WARNING);\n }\n Component.alertUser(s);\n }\n\n /**\n * Component.error(s)\n *\n * @param {string} s describes the error; an alert() is displayed as well\n */\n static error(s)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.ERROR);\n }\n Component.alertUser(s);\n }\n\n /**\n * Component.alertUser(sMessage)\n *\n * @param {string} sMessage\n */\n static alertUser(sMessage)\n {\n if (window) {\n window.alert(sMessage);\n } else {\n Component.log(sMessage);\n }\n }\n\n /**\n * Component.confirmUser(sPrompt)\n *\n * @param {string} sPrompt\n * @returns {boolean} true if the user clicked OK, false if Cancel/Close\n */\n static confirmUser(sPrompt)\n {\n var fResponse = false;\n if (window) {\n fResponse = window.confirm(sPrompt);\n }\n return fResponse;\n }\n\n /**\n * Component.promptUser()\n *\n * @param {string} sPrompt\n * @param {string} [sDefault]\n * @returns {string|null}\n */\n static promptUser(sPrompt, sDefault)\n {\n var sResponse = null;\n if (window) {\n sResponse = window.prompt(sPrompt, sDefault === undefined? \"\" : sDefault);\n }\n return sResponse;\n }\n\n /**\n * Component.appendControl(control, sText)\n *\n * @param {Object} control\n * @param {string} sText\n */\n static appendControl(control, sText)\n {\n control.value += sText;\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (COMPILED) {\n sText = control.value;\n if (sText.length > 8192) control.value = sText.substr(sText.length - 4096);\n }\n control.scrollTop = control.scrollHeight;\n }\n\n /**\n * Component.replaceControl(control, sSearch, sReplace)\n *\n * @param {Object} control\n * @param {string} sSearch\n * @param {string} sReplace\n */\n static replaceControl(control, sSearch, sReplace)\n {\n var sText = control.value;\n var i = sText.lastIndexOf(sSearch);\n if (i < 0) {\n sText += sSearch + '\\n';\n } else {\n sText = sText.substr(0, i) + sReplace + sText.substr(i + sSearch.length);\n }\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (COMPILED && sText.length > 8192) sText = sText.substr(sText.length - 4096);\n control.value = sText;\n control.scrollTop = control.scrollHeight;\n }\n\n /**\n * Component.bindExternalControl(component, sBinding, sType)\n *\n * @param {Component} component\n * @param {string} sBinding\n * @param {string} [sType] is the external component type (default is \"Panel\")\n */\n static bindExternalControl(component, sBinding, sType = \"Panel\")\n {\n if (sBinding) {\n var target = Component.getComponentByType(sType, component.id);\n if (target) {\n var control = target.bindings[sBinding];\n if (control) {\n component.setBinding(\"\", sBinding, control);\n }\n }\n }\n }\n\n /**\n * Component.bindComponentControls(component, element, sAppClass)\n *\n * @param {Component} component\n * @param {HTMLElement} element from the DOM\n * @param {string} sAppClass\n */\n static bindComponentControls(component, element, sAppClass)\n {\n var aeControls = Component.getElementsByClass(element.parentNode, sAppClass + \"-control\");\n\n for (var iControl = 0; iControl < aeControls.length; iControl++) {\n\n var aeChildNodes = aeControls[iControl].childNodes;\n\n for (var iNode = 0; iNode < aeChildNodes.length; iNode++) {\n var control = aeChildNodes[iNode];\n if (control.nodeType !== 1 /* document.ELEMENT_NODE */) {\n continue;\n }\n var sClass = control.getAttribute(\"class\");\n if (!sClass) continue;\n var aClasses = sClass.split(\" \");\n for (var iClass = 0; iClass < aClasses.length; iClass++) {\n var parms;\n sClass = aClasses[iClass];\n switch (sClass) {\n case sAppClass + \"-binding\":\n parms = Component.getComponentParms(/** @type {HTMLElement} */(control));\n if (parms && parms['binding'] !== undefined) {\n component.setBinding(parms['type'], parms['binding'], /** @type {HTMLElement} */(control), parms['value']);\n } else if (!parms || parms['type'] != \"description\") {\n Component.log(\"Component '\" + component.toString() + \"' missing binding\" + (parms? \" for \" + parms['type'] : \"\"), \"warning\");\n }\n iClass = aClasses.length;\n break;\n default:\n // if (DEBUG) Component.log(\"Component.bindComponentControls(\" + component.toString() + \"): unrecognized control class \\\"\" + sClass + \"\\\"\", \"warning\");\n break;\n }\n }\n }\n }\n }\n\n /**\n * Component.getComponents(idRelated)\n *\n * We could store components as properties, using the component's ID, and change\n * this linear lookup into a property lookup, but some components may have no ID.\n *\n * @param {string} [idRelated] of related component\n * @return {Array} of components\n */\n static getComponents(idRelated)\n {\n var i;\n var aComponents = [];\n /*\n * getComponentByID(id, idRelated)\n *\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated) {\n if ((i = idRelated.indexOf('.')) > 0)\n idRelated = idRelated.substr(0, i + 1);\n else\n idRelated = \"\";\n }\n for (i = 0; i < Component.components.length; i++) {\n var component = Component.components[i];\n if (!idRelated || !component.id.indexOf(idRelated)) {\n aComponents.push(component);\n }\n }\n return aComponents;\n }\n\n /**\n * Component.getComponentByID(id, idRelated)\n *\n * We could store components as properties, using the component's ID, and change\n * this linear lookup into a property lookup, but some components may have no ID.\n *\n * @param {string} id of the desired component\n * @param {string} [idRelated] of related component\n * @return {Component|null}\n */\n static getComponentByID(id, idRelated)\n {\n if (id !== undefined) {\n var i;\n /*\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated && (i = idRelated.indexOf('.')) > 0) {\n id = idRelated.substr(0, i + 1) + id;\n }\n for (i = 0; i < Component.components.length; i++) {\n if (Component.components[i].id === id) {\n return Component.components[i];\n }\n }\n if (Component.components.length) {\n Component.log(\"Component ID '\" + id + \"' not found\", \"warning\");\n }\n }\n return null;\n }\n\n /**\n * Component.getComponentByType(sType, idRelated, componentPrev)\n *\n * @param {string} sType of the desired component\n * @param {string} [idRelated] of related component\n * @param {Component|null} [componentPrev] of previously returned component, if any\n * @return {Component|null}\n */\n static getComponentByType(sType, idRelated, componentPrev)\n {\n if (sType !== undefined) {\n var i;\n /*\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated) {\n if ((i = idRelated.indexOf('.')) > 0) {\n idRelated = idRelated.substr(0, i + 1);\n } else {\n idRelated = \"\";\n }\n }\n for (i = 0; i < Component.components.length; i++) {\n if (componentPrev) {\n if (componentPrev == Component.components[i]) componentPrev = null;\n continue;\n }\n if (sType == Component.components[i].type && (!idRelated || !Component.components[i].id.indexOf(idRelated))) {\n return Component.components[i];\n }\n }\n Component.log(\"Component type '\" + sType + \"' not found\", \"warning\");\n }\n return null;\n }\n\n /**\n * Component.getComponentParms(element)\n *\n * @param {HTMLElement} element from the DOM\n */\n static getComponentParms(element)\n {\n var parms = null;\n var sParms = element.getAttribute(\"data-value\");\n if (sParms) {\n try {\n parms = eval('(' + sParms + ')'); // jshint ignore:line\n /*\n * We can no longer invoke removeAttribute() because some components (eg, Panel) need\n * to run their initXXX() code more than once, to avoid initialization-order dependencies.\n *\n * if (!DEBUG) {\n * element.removeAttribute(\"data-value\");\n * }\n */\n } catch(e) {\n Component.error(e.message + \" (\" + sParms + \")\");\n }\n }\n return parms;\n }\n\n /**\n * Component.getElementsByClass(element, sClass, sObjClass)\n *\n * This is a cross-browser helper function, since not all browser's support getElementsByClassName()\n *\n * TODO: This should probably be moved into weblib.js at some point, along with the control binding functions above,\n * to keep all the browser-related code together.\n *\n * @param {HTMLDocument|HTMLElement|Node} element from the DOM\n * @param {string} sClass\n * @param {string} [sObjClass]\n * @return {Array|NodeList}\n */\n static getElementsByClass(element, sClass, sObjClass)\n {\n if (sObjClass) sClass += '-' + sObjClass + \"-object\";\n /*\n * Use the browser's built-in getElementsByClassName() if it appears to be available\n * (for example, it's not available in IE8, but it should be available in IE9 and up)\n */\n if (element.getElementsByClassName) {\n return element.getElementsByClassName(sClass);\n }\n var i, j, ae = [];\n var aeAll = element.getElementsByTagName(\"*\");\n var re = new RegExp('(^| )' + sClass + '( |$)');\n for (i = 0, j = aeAll.length; i < j; i++) {\n if (re.test(aeAll[i].className)) {\n ae.push(aeAll[i]);\n }\n }\n if (!ae.length) {\n Component.log('No elements of class \"' + sClass + '\" found');\n }\n return ae;\n }\n\n /**\n * Component.getScriptCommands(sScript)\n *\n * This is a simple parser that breaks sScript into an array of commands, where each command\n * is an array of tokens, where tokens are sequences of characters separated by any of: tab, space,\n * carriage-return (CR), line-feed (LF), semicolon, single-quote, or double-quote; if a quote is\n * used, all characters up to the next matching quote become part of the token, allowing any of the\n * other separators to be part of the token. CR, LF and semicolon also serve to terminate a command,\n * with semicolon being preferred, because it's 1) more visible, and 2) essential when the entire\n * script is a multi-line string where all CR/LF were replaced by spaces (which is what Jekyll does,\n * and since we can't change Jekyll, it's what our own MarkDown Front Matter parser does as well;\n * see convertMD() in markout.js, where the aCommandDefs array is built).\n *\n * Backslash sequences like \\n, \\r, and \\\\ have already been converted to LF, CR and backslash\n * characters, since the entire script string is injected into a JavaScript function call, so any\n * backslash sequence that JavaScript supports is automatically converted:\n *\n * \\0 \\' \\\" \\\\ \\n \\r \\v \\t \\b \\f \\uXXXX \\xXX\n * ^J ^M ^K ^I ^H ^L\n *\n * To support any other non-printable 8-bit character, such as ESC, you should use \\xXX, where XX\n * is the ASCII code in hex. For ESC, that would be \\x1B.\n *\n * @param {string} sScript\n * @return {Array}\n */\n static getScriptCommands(sScript)\n {\n var cch = sScript.length;\n var aCommands = [], aTokens = [], sToken = \"\", chQuote = null;\n for (var i = 0; i < cch; i++) {\n var ch = sScript[i];\n if (ch == '\"' || ch == \"'\") {\n if (chQuote && ch != chQuote) {\n sToken += ch;\n continue;\n }\n if (!chQuote) {\n chQuote = ch;\n } else {\n chQuote = null;\n }\n if (sToken) {\n aTokens.push(sToken);\n sToken = \"\";\n }\n continue;\n }\n if (!chQuote) {\n if (ch == '\\r' || ch == '\\n') {\n ch = ';';\n }\n if (ch == ' ' || ch == '\\t' || ch == ';') {\n if (sToken) {\n aTokens.push(sToken);\n sToken = \"\";\n }\n if (ch == ';' && aTokens.length) {\n aCommands.push(aTokens);\n aTokens = [];\n }\n continue;\n }\n }\n sToken += ch;\n }\n if (sToken) {\n aTokens.push(sToken);\n }\n if (aTokens.length) {\n aCommands.push(aTokens);\n }\n return aCommands;\n }\n\n /**\n * Component.processScript(idMachine, sScript)\n *\n * @param {string} idMachine\n * @param {string} [sScript]\n * @return {boolean}\n */\n static processScript(idMachine, sScript)\n {\n var fSuccess = false;\n idMachine += \".machine\";\n if (!sScript) {\n delete Component.commands[idMachine];\n fSuccess = true;\n }\n else if (typeof sScript == \"string\" && !Component.commands[idMachine]) {\n fSuccess = true;\n Component.commands[idMachine] = Component.getScriptCommands(sScript);\n if (!Component.processCommands(idMachine)) {\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * Component.processCommands(idMachine)\n *\n * @param {string} idMachine\n * @return {boolean}\n */\n static processCommands(idMachine)\n {\n var fSuccess = true;\n var aCommands = Component.commands[idMachine];\n\n // var dbg = Component.getComponentByType(\"Debugger\", idMachine);\n\n while (aCommands && aCommands.length) {\n\n var aTokens = aCommands.splice(0, 1)[0];\n var sCommand = aTokens[0];\n\n /*\n * It's possible to route this output to the Debugger window with dbg.println()\n * instead, but it's a bit too confusing mingling script output in a window that\n * already mingles Debugger and machine output.\n */\n Component.println(aTokens.join(' '), Component.PRINT.SCRIPT);\n\n var fnCallReady = null;\n if (Component.asyncCommands.indexOf(sCommand) >= 0) {\n fnCallReady = function processNextCommand() {\n return function() {\n Component.processCommands(idMachine);\n }\n }();\n }\n\n var fnCommand = Component.globalCommands[sCommand];\n if (fnCommand) {\n if (!fnCallReady) {\n fSuccess = fnCommand(aTokens[1], aTokens[2], aTokens[3]);\n } else {\n if (!fnCommand(fnCallReady, aTokens[1], aTokens[2], aTokens[3])) break;\n }\n }\n else {\n fSuccess = false;\n var component = Component.getComponentByType(aTokens[1], idMachine);\n if (component) {\n fnCommand = Component.componentCommands[sCommand];\n if (fnCommand) {\n fSuccess = fnCommand(component, aTokens[2], aTokens[3]);\n }\n else {\n var exports = component['exports'];\n if (exports) {\n fnCommand = exports[sCommand];\n if (fnCommand) {\n fSuccess = true;\n if (!fnCallReady) {\n fSuccess = fnCommand.call(component, aTokens[2], aTokens[3]);\n } else {\n if (!fnCommand.call(component, fnCallReady, aTokens[2], aTokens[3])) break;\n }\n }\n }\n }\n }\n }\n\n if (!fSuccess) {\n Component.alertUser(\"Script error: '\" + sCommand + \"' command \" + (fnCommand? \" failed\" : \" not recognized\"));\n break;\n }\n }\n\n if (aCommands && !aCommands.length) {\n delete Component.commands[idMachine];\n }\n\n return fSuccess;\n }\n\n /**\n * Component.scriptAlert(sMessage)\n *\n * @param {string} sMessage\n * @return {boolean}\n */\n static scriptAlert(sMessage)\n {\n Component.alertUser(sMessage);\n return true;\n }\n\n /**\n * Component.scriptSelect(component, sBinding, sValue)\n *\n * @param {Component} component\n * @param {string} sBinding\n * @param {string} sValue\n * @return {boolean}\n */\n static scriptSelect(component, sBinding, sValue)\n {\n var fSuccess = false;\n var aBindings = component['bindings'];\n var control = aBindings[sBinding];\n if (control) {\n for (var i = 0; i < control.options.length; i++) {\n if (control.options[i].textContent == sValue) {\n if (control.selectedIndex != i) {\n control.selectedIndex = i;\n }\n fSuccess = true;\n break;\n }\n }\n }\n return fSuccess;\n }\n\n /**\n * Component.scriptSleep(fnCallback, sDelay)\n *\n * @param {function()} fnCallback\n * @param {string} sDelay (in milliseconds)\n * @return {boolean}\n */\n static scriptSleep(fnCallback, sDelay)\n {\n setTimeout(fnCallback, +sDelay);\n return false;\n }\n\n /**\n * toString()\n *\n * @this {Component}\n * @return {string}\n */\n toString()\n {\n return (this.name? this.name : (this.id || this.type));\n }\n\n /**\n * getMachineNum()\n *\n * @this {Component}\n * @return {number} unique machine number\n */\n getMachineNum()\n {\n var nMachine = 1;\n if (this.idMachine) {\n var aDigits = this.idMachine.match(/\\d+/);\n if (aDigits !== null)\n nMachine = parseInt(aDigits[0], 10);\n }\n return nMachine;\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * Component's setBinding() method is intended to be overridden by subclasses.\n *\n * @this {Component}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, 'print')\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n switch (sBinding) {\n case 'clear':\n if (!this.bindings[sBinding]) {\n this.bindings[sBinding] = control;\n control.onclick = (function(component) {\n return function clearControl() {\n if (component.bindings['print']) {\n component.bindings['print'].value = \"\";\n }\n };\n }(this));\n }\n return true;\n case 'print':\n if (!this.bindings[sBinding]) {\n var controlTextArea = /** @type {HTMLTextAreaElement} */(control);\n this.bindings[sBinding] = controlTextArea;\n /**\n * Override this.notice() with a replacement function that eliminates the Component.alertUser() call.\n *\n * @this {Component}\n * @param {string} s\n * @return {boolean}\n */\n this.notice = function noticeControl(s /*, fPrintOnly, id*/) {\n this.println(s, this.type);\n return true;\n };\n /*\n * This was added for Firefox (Safari will clear the <textarea> on a page reload, but Firefox does not).\n */\n controlTextArea.value = \"\";\n this.print = function(control) {\n return function printControl(s) {\n Component.appendControl(control, s);\n };\n }(controlTextArea);\n this.println = function(component, control) {\n return function printlnControl(s, type, id) {\n if (!s) s = \"\";\n if (type != Component.PRINT.PROGRESS || s.slice(-3) != \"...\") {\n if (type) s = type + \": \" + s;\n Component.appendControl(control, s + '\\n');\n } else {\n Component.replaceControl(control, s, s + '.');\n }\n if (!COMPILED && window && window.console) Component.println(s, type, id);\n };\n }(this, controlTextArea);\n }\n return true;\n default:\n return false;\n }\n }\n\n /**\n * log(s, type)\n *\n * For diagnostic output only.\n *\n * WARNING: Even though this function's body is completely wrapped in DEBUG, that won't prevent the Closure Compiler\n * from including it, so all calls must still be prefixed with \"if (DEBUG) ....\". For this reason, the class method,\n * Component.log(), is preferred, because the compiler IS smart enough to remove those calls.\n *\n * @this {Component}\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n log(s, type)\n {\n if (!COMPILED) {\n Component.log(s, type || this.id || this.type);\n }\n }\n\n /**\n * assert(f, s)\n *\n * Verifies conditions that must be true (for DEBUG builds only).\n *\n * WARNING: Make sure you preface all calls to this.assert() with \"if (DEBUG)\", because unlike Component.assert(),\n * the Closure Compiler can't be sure that this instance method hasn't been overridden, so it refuses to treat it as\n * dead code in non-DEBUG builds.\n *\n * TODO: Add a task to the build process that \"asserts\" there are no instances of \"assertion failure\" in RELEASE builds.\n *\n * @this {Component}\n * @param {boolean|number} f is the expression asserted to be true\n * @param {string} [s] is a description of the assertion to be displayed or logged on failure\n */\n assert(f, s)\n {\n if (DEBUG) {\n if (!f) {\n s = \"assertion failure in \" + (this.id || this.type) + (s? \": \" + s : \"\");\n if (DEBUGGER && this.dbg) {\n this.dbg.stopCPU();\n /*\n * Why do we throw an Error only to immediately catch and ignore it? Simply to give\n * any IDE the opportunity to inspect the application's state. Even when the IDE has\n * control, you should still be able to invoke Debugger commands from the IDE's REPL,\n * using the global function that the Debugger constructor defines; eg:\n *\n * pcx86('r')\n * pcx86('dw 0:0')\n * pcx86('h')\n * ...\n *\n * If you have no desire to stop on assertions, consider this a no-op. However, another\n * potential benefit of creating an Error object is that, for browsers like Chrome, we get\n * a stack trace, too.\n */\n try {\n throw new Error(s);\n } catch(e) {\n this.println(e.stack || e.message);\n }\n return;\n }\n this.log(s);\n throw new Error(s);\n }\n }\n }\n\n /**\n * print(s)\n *\n * Components using this.print() should wait until after their constructor has run to display any messages, because\n * if a Control Panel has been loaded, its override will not take effect until its own constructor has run.\n *\n * @this {Component}\n * @param {string} s\n */\n print(s)\n {\n Component.print(s);\n }\n\n /**\n * println(s, type, id)\n *\n * Components using this.println() should wait until after their constructor has run to display any messages, because\n * if a Control Panel has been loaded, its override will not take effect until its own constructor has run.\n *\n * @this {Component}\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n * @param {string} [id] is the caller's ID, if any\n */\n println(s, type, id)\n {\n Component.println(s, type, id || this.id);\n }\n\n /**\n * status(s)\n *\n * status() is like println() but it also includes information about the component (ie, the component type),\n * which is why there is no corresponding Component.status() function.\n *\n * @this {Component}\n * @param {string} s is the message text\n */\n status(s)\n {\n this.println(this.type + \": \" + s);\n }\n\n /**\n * notice(s, fPrintOnly, id)\n *\n * notice() is like println() but implies a need for user notification, so we alert() as well; however, if this.println()\n * is overridden, this.notice will be replaced with a similar override, on the assumption that the override is taking care\n * of alerting the user.\n *\n * @this {Component}\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n * @return {boolean}\n */\n notice(s, fPrintOnly, id)\n {\n if (!fPrintOnly) {\n /*\n * See if the associated computer, if any, is \"unloading\"....\n */\n var computer = Component.getComponentByType(\"Computer\", this.id);\n if (computer && computer.flags.unloading) {\n console.log(\"ignoring notice during unload: \" + s);\n return false;\n }\n }\n Component.notice(s, fPrintOnly, id || this.type);\n return true;\n }\n\n /**\n * setError(s)\n *\n * Set a fatal error condition\n *\n * @this {Component}\n * @param {string} s describes a fatal error condition\n */\n setError(s)\n {\n this.flags.error = true;\n this.notice(s); // TODO: Any cases where we should still prefix this string with \"Fatal error: \"?\n }\n\n /**\n * clearError()\n *\n * Clear any fatal error condition\n *\n * @this {Component}\n */\n clearError() {\n this.flags.error = false;\n }\n\n /**\n * isError()\n *\n * Report any fatal error condition\n *\n * @this {Component}\n * @return {boolean} true if a fatal error condition exists, false if not\n */\n isError()\n {\n if (this.flags.error) {\n this.println(this.toString() + \" error\");\n return true;\n }\n return false;\n }\n\n /**\n * isReady(fnReady)\n *\n * Return the \"ready\" state of the component; if the component is not ready, it will queue the optional\n * notification function, otherwise it will immediately call the notification function, if any, without queuing it.\n *\n * NOTE: Since only the Computer component actually cares about the \"readiness\" of other components, the so-called\n * \"queue\" of notification functions supports exactly one function. This keeps things nice and simple.\n *\n * @this {Component}\n * @param {function()} [fnReady]\n * @return {boolean} true if the component is in a \"ready\" state, false if not\n */\n isReady(fnReady)\n {\n if (fnReady) {\n if (this.flags.ready) {\n fnReady();\n } else {\n if (MAXDEBUG) this.log(\"NOT ready\");\n this.fnReady = fnReady;\n }\n }\n return this.flags.ready;\n }\n\n /**\n * setReady(fReady)\n *\n * Set the \"ready\" state of the component to true, and call any queued notification functions.\n *\n * @this {Component}\n * @param {boolean} [fReady] is assumed to indicate \"ready\" unless EXPLICITLY set to false\n */\n setReady(fReady)\n {\n if (!this.flags.error) {\n this.flags.ready = (fReady !== false);\n if (this.flags.ready) {\n if (MAXDEBUG /* || this.name */) this.log(\"ready\");\n var fnReady = this.fnReady;\n this.fnReady = null;\n if (fnReady) fnReady();\n }\n }\n }\n\n /**\n * isBusy(fCancel)\n *\n * Return the \"busy\" state of the component\n *\n * @this {Component}\n * @param {boolean} [fCancel] is set to true to cancel a \"busy\" state\n * @return {boolean} true if \"busy\", false if not\n */\n isBusy(fCancel)\n {\n if (this.flags.busy) {\n if (fCancel) {\n this.flags.busyCancel = true;\n } else if (fCancel === undefined) {\n this.println(this.toString() + \" busy\");\n }\n }\n return this.flags.busy;\n }\n\n /**\n * setBusy(fBusy)\n *\n * Update the current busy state; if a busyCancel request is pending, it will be honored now.\n *\n * @this {Component}\n * @param {boolean} fBusy\n * @return {boolean}\n */\n setBusy(fBusy)\n {\n if (this.flags.busyCancel) {\n this.flags.busy = false;\n this.flags.busyCancel = false;\n return false;\n }\n if (this.flags.error) {\n this.println(this.toString() + \" error\");\n return false;\n }\n this.flags.busy = fBusy;\n return this.flags.busy;\n }\n\n /**\n * powerUp(fSave)\n *\n * @this {Component}\n * @param {Object|null} data\n * @param {boolean} [fRepower] is true if this is \"repower\" notification\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n this.flags.powered = true;\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Component}\n * @param {boolean} fSave\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n if (fShutdown) this.flags.powered = false;\n return true;\n }\n\n /**\n * messageEnabled(bitsMessage)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n *\n * @this {Component}\n * @param {number} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n * @return {boolean} true if all specified message enabled, false if not\n */\n messageEnabled(bitsMessage = 0)\n {\n if (DEBUGGER && this.dbg) {\n if (this !== this.dbg) {\n bitsMessage = bitsMessage || this.bitsMessage;\n }\n var bitsEnabled = this.dbg.bitsMessage & bitsMessage;\n /*\n * This next \"bit\" of logic is for PCx86 and any other machine where we've expanded the set of\n * messages by reusing bits in the low nibbles in combination with different bits in the high nibble.\n * If the input bits adhere to that format, then the mask we just produced must adhere to it as well,\n * and if it doesn't, zero the mask, ensuring that the test will return false.\n */\n if ((bitsMessage & 0xf0000000) && (bitsMessage & 0x0fffffff)) {\n if (!(bitsEnabled & 0xf0000000) || !(bitsEnabled & 0x0fffffff)) bitsEnabled = 0;\n }\n if (bitsMessage && bitsEnabled === bitsMessage) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * printf(format, ...args)\n *\n * @this {Component}\n * @param {string} format\n * @param {...} args\n */\n printf(format, ...args)\n {\n if (DEBUGGER && this.dbg) {\n if (this.messageEnabled()) {\n let s = Str.sprintf(format, ...args);\n /*\n * Since dbg.message() calls println(), we strip any ending linefeed.\n * \n * We could bypass the Debugger and go straight to this.print(), but we would lose\n * the benefits of debugger messages (eg, automatic buffering, halting, yielding, etc).\n */\n if (s.slice(-1) == '\\n') s = s.slice(0, -1);\n this.dbg.message(s);\n }\n }\n }\n\n /**\n * printMessage(sMessage, bitsMessage, fAddress)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n * If bitsMessage is true, the message is displayed regardless.\n *\n * @this {Component}\n * @param {string} sMessage is any caller-defined message string\n * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n * @param {boolean} [fAddress] is true to display the current address\n */\n printMessage(sMessage, bitsMessage, fAddress)\n {\n if (DEBUGGER && this.dbg) {\n if (bitsMessage === true || this.messageEnabled(bitsMessage | 0)) {\n this.dbg.message(sMessage, fAddress);\n }\n }\n }\n\n /**\n * printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n * If bitsMessage is true, the message is displayed as long as MESSAGE.PORT is enabled.\n *\n * @this {Component}\n * @param {number} port\n * @param {number|null|*} bOut if an output operation\n * @param {number|null|*} [addrFrom]\n * @param {string|null|*} [name] of the port, if any\n * @param {number|null|*} [bIn] is the input value, if known, on an input operation\n * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n */\n printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage)\n {\n if (DEBUGGER && this.dbg) {\n if (bitsMessage === true) {\n bitsMessage = 0;\n } else if (bitsMessage == null) {\n bitsMessage = this.bitsMessage;\n }\n this.dbg.messageIO(this, port, bOut, addrFrom, name, bIn, bitsMessage);\n }\n }\n}\n\n/*\n * Types recognized and supported by selected functions (eg, Computer.getMachineParm())\n */\nComponent.TYPE = {\n NUMBER: \"number\",\n OBJECT: \"object\",\n STRING: \"string\"\n};\n\n/*\n * These are the standard PRINT values you can pass as an optional argument to println(); in reality,\n * you can pass anything you want, because they are simply prepended to the message, although PROGRESS\n * messages may also be merged with earlier similar messages to keep the output buffer under control.\n */\nComponent.PRINT = {\n ERROR: \"error\",\n NOTICE: \"notice\",\n PROGRESS: \"progress\",\n SCRIPT: \"script\",\n WARNING: \"warning\"\n};\n\n/*\n * Every component created on the current page is recorded in this array (see Component.add()),\n * enabling any component to locate another component by ID (see Component.getComponentByID())\n * or by type (see Component.getComponentByType()).\n *\n * Every machine on the page are now recorded as well, by their machine ID. We then record the\n * various resources used by that machine.\n *\n * Includes a fallback for non-browser-based environments (ie, Node). TODO: This will need to be\n * tailored to Node, probably using the global object instead of the window object, if we ever want\n * to support multi-machine configs in that environment.\n */\nif (window) {\n if (!window['PCjs']) window['PCjs'] = {};\n if (!window['PCjs']['Machines']) window['PCjs']['Machines'] = {};\n if (!window['PCjs']['Components']) window['PCjs']['Components'] = [];\n if (!window['PCjs']['Commands']) window['PCjs']['Commands'] = {};\n}\nComponent.machines = window? window['PCjs']['Machines'] : {};\nComponent.components = window? window['PCjs']['Components'] : [];\nComponent.commands = window? window['PCjs']['Commands'] : {};\n\nComponent.asyncCommands = [\n 'hold', 'sleep', 'wait'\n];\nComponent.globalCommands = {\n 'alert': Component.scriptAlert,\n 'sleep': Component.scriptSleep\n};\nComponent.componentCommands = {\n 'select': Component.scriptSelect\n};\nComponent.printBuffer = \"\";\n\n/*\n * The following polyfills provide ES5 functionality that's missing in older browsers (eg, IE8),\n * allowing PCjs apps to run without slamming into exceptions; however, due to the lack of HTML5 canvas\n * support in those browsers, all you're likely to see are \"soft\" errors (eg, \"Missing <canvas> support\").\n *\n * Perhaps we can implement a text-only faux video display for a fun retro-browser experience someday.\n *\n * TODO: Come up with a better place to put these polyfills. We will likely have more if we decide to\n * make the leap from ES5 to ES6 features.\n */\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf\n */\nif (!Array.prototype.indexOf) {\n Array.prototype.indexOf = function(obj, start) {\n for (var i = (start || 0), j = this.length; i < j; i++) {\n if (this[i] === obj) { return i; }\n }\n return -1;\n }\n}\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray\n */\nif (!Array.isArray) {\n Array.isArray = function(arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n };\n}\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind\n */\nif (!Function.prototype.bind) {\n Function.prototype.bind = function(obj) {\n if (typeof this != \"function\") {\n // Closest thing possible to the ECMAScript 5 internal IsCallable function\n throw new TypeError(\"Function.prototype.bind: non-callable object\");\n }\n var args = Array.prototype.slice.call(arguments, 1);\n var fToBind = this;\n var fnNOP = /** @constructor */ (function() {});\n var fnBound = function() {\n return fToBind.apply(this instanceof fnNOP && obj? this : obj, args.concat(/** @type {Array} */(Array.prototype.slice.call(arguments))));\n };\n fnNOP.prototype = this.prototype;\n fnBound.prototype = new fnNOP();\n return fnBound;\n };\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/defines.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @define {string}\n */\nvar APPCLASS = \"pcx86\"; // this @define is the default application class (eg, \"pcx86\", \"c1pjs\")\n\n/**\n * @define {string}\n */\nvar APPNAME = \"PCx86\"; // this @define is the default application name (eg, \"PCx86\", \"C1Pjs\")\n\n/**\n * @define {boolean}\n *\n * WARNING: DEBUGGER needs to accurately reflect whether or not the Debugger component is (or will be) loaded.\n * In the compiled case, we rely on the Closure Compiler to override DEBUGGER as appropriate. When it's *false*,\n * nearly all of debugger.js will be conditionally removed by the compiler, reducing it to little more than a\n * \"type skeleton\", which also solves some type-related warnings we would otherwise have if we tried to remove\n * debugger.js from the compilation process altogether.\n *\n * However, when we're in \"development mode\" and running uncompiled code in debugger-less configurations,\n * I would like to skip loading debugger.js altogether. When doing that, we must ALSO arrange for an additional file\n * (nodebugger.js) to be loaded immediately after this file, which *explicitly* overrides DEBUGGER with *false*.\n */\nvar DEBUGGER = true; // this @define is overridden by the Closure Compiler to remove Debugger-related support\n\n/**\n * @define {boolean}\n *\n * PREFETCH enables the use of a prefetch queue. As of v1.20.0, PREFETCH support has been updated and retested,\n * but as currently implemented, it does not yield as much improvement as I'd hoped when paging is enabled, so PREFETCH\n * is still off by default.\n */\nvar PREFETCH = false;\n\n/**\n * @define {boolean}\n *\n * BYTEARRAYS is a Closure Compiler compile-time option that allocates an Array of numbers for every Memory block,\n * where each a number represents ONE byte; very wasteful, but potentially slightly faster.\n *\n * See the Memory component for details.\n */\nvar BYTEARRAYS = false;\n\n/**\n * TYPEDARRAYS enables use of typed arrays for Memory blocks. This used to be a compile-time-only option, but I've\n * added Memory access functions for typed arrays (see Memory.afnTypedArray), so support can be enabled dynamically now.\n *\n * See the Memory component for details.\n */\nvar TYPEDARRAYS = (typeof ArrayBuffer !== 'undefined');\n\n/**\n * @define {boolean}\n *\n * BACKTRACK enables backtracking: a mechanism that allows us to tag every byte of incoming data and follow the\n * flow of that data.\n *\n * This is set to !COMPILED, disabling backtracking in all compiled versions, but we may eventually set it to\n * match the DEBUGGER setting -- unless it slows down machines using the built-in Debugger too much, in which case\n * we'll have to rethink that choice OR provide a Debugger command that dynamically enables/disables as much of\n * the backtracking support as possible.\n *\n * TODO: BACKTRACK support is currently completely disabled until we have a chance to investigate the problem\n * discussed in Bus.addBackTrackObject().\n */\nvar BACKTRACK = !COMPILED && DEBUGGER;\n\n/**\n * @define {boolean}\n *\n * SYMBOLS enables automatic symbol generation from known DLL, EXE and VXD file formats. It's currently\n * enabled whenever DEBUGGER support is enabled.\n */\nvar SYMBOLS = DEBUGGER;\n\n/**\n * @define {boolean}\n *\n * BUGS_8086 enables support for known 8086 bugs. It's turned off by default, because 1) it adds overhead, and\n * 2) it's hard to imagine any software actually being dependent on any of the bugs covered by this (eg, the failure\n * to properly restart string instructions with multiple prefixes, or the failure to inhibit hardware interrupts\n * following SS segment loads).\n */\nvar BUGS_8086 = false;\n\n/**\n * @define {boolean}\n *\n * I386 enables 80386 support. My preference continues to be one \"binary\" that supports all implemented CPUs, but\n * I'm providing this to enable a slimmed-down binary, at least until 80386 support is actually finished; at the\n * moment, there's just a lot of scaffolding that bloats the compiled version without adding any real functionality.\n */\nvar I386 = true;\n\n/**\n * @define {boolean}\n *\n * DESKPRO386 enables COMPAQ DeskPro 386 support. Requires I386 support as well (duh).\n */\nvar DESKPRO386 = I386;\n\n/**\n * @define {boolean}\n *\n * PAGEBLOCKS enables 80386 paging support with assistance from the Bus component. This affects how the Bus component\n * defines physical memory parameters for a 32-bit bus. With the 8086 and 80286 processors, the Bus component was free\n * to choose any block size for physical memory allocations that made sense for the bus width (eg, 4Kb blocks for a\n * 20-bit bus, or 16Kb blocks for a 24-bit bus).\n *\n * However, for the 80386 processor, it makes more sense to choose a block size that matches the page size (ie, 4Kb),\n * because then we have the option of altering the address-to-memory mapping for any block to match whatever page table\n * mapping is in effect for that address, if any, without requiring another layer of address translation.\n */\nvar PAGEBLOCKS = I386;\n\n/*\n * Combine all the shared globals and machine-specific globals into one machine-specific global object,\n * which all machine components should start using; eg: \"if (PCX86.DEBUG) ...\" instead of \"if (DEBUG) ...\".\n */\nvar PCX86 = {\n APPCLASS: APPCLASS,\n APPNAME: APPNAME,\n APPVERSION: APPVERSION, // shared\n BACKTRACK: BACKTRACK,\n BUGS_8086: BUGS_8086,\n BYTEARRAYS: BYTEARRAYS,\n COMPILED: COMPILED, // shared\n CSSCLASS: CSSCLASS, // shared\n DEBUG: DEBUG, // shared\n DEBUGGER: DEBUGGER,\n DESKPRO386: DESKPRO386,\n I386: I386,\n MAXDEBUG: MAXDEBUG, // shared\n PAGEBLOCKS: PAGEBLOCKS,\n PREFETCH: PREFETCH,\n PRIVATE: PRIVATE, // shared\n TYPEDARRAYS: TYPEDARRAYS,\n SITEHOST: SITEHOST, // shared\n SYMBOLS: SYMBOLS,\n XMLVERSION: XMLVERSION // shared\n};\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/x86.js (C) Jeff Parsons 2012-2018\n */\n\nvar X86 = {\n /*\n * CPU model numbers (supported)\n */\n MODEL_8086: 8086,\n MODEL_8088: 8088,\n MODEL_80186: 80186,\n MODEL_80188: 80188,\n MODEL_80286: 80286,\n MODEL_80386: 80386,\n\n /*\n * 80386 CPU stepping identifiers (supported)\n */\n STEPPING_80386_A0: (80386+0xA0), // we have very little information about this stepping...\n STEPPING_80386_A1: (80386+0xA1), // we know much more about the A1 stepping (see /blog/2015/02/23/README.md)\n STEPPING_80386_B0: (80386+0xB0), // for now, the only B0 difference in PCx86 is support for XBTS and IBTS\n STEPPING_80386_B1: (80386+0xB1), // our implementation of the B1 stepping also includes the infamous 32-bit multiplication bug\n STEPPING_80386_B2: (80386+0xB2), // this is an imaginary stepping that simply means \"B1 without the 32-bit multiplication bug\" (ie, a B1 with the \"double sigma\" stamp)\n STEPPING_80386_C0: (80386+0xC0), // this presumably fixed lots of B1 issues, but it seems to have been quickly superseded by the D0\n STEPPING_80386_D0: (80386+0xD0), // we don't have any detailed information (eg, errata) for these later steppings\n STEPPING_80386_D1: (80386+0xD1),\n STEPPING_80386_D2: (80386+0xD2),\n\n /*\n * This constant is used to mark points in the code where the physical address being returned\n * is invalid and should not be used. TODO: There are still functions that will use an invalid\n * address, which is why we've tried to choose a value that causes the least harm, but ultimately,\n * we must add checks to those functions or throw special JavaScript exceptions to bypass them.\n *\n * This value is also used to indicate non-existent EA address calculations, which are usually\n * detected with \"regEA === ADDR_INVALID\" and \"regEAWrite === ADDR_INVALID\" tests. In a 32-bit\n * CPU, -1 (ie, 0xffffffff) could actually be a valid address, so consider changing ADDR_INVALID\n * to NaN or null (which is also why all ADDR_INVALID tests should use strict equality operators).\n *\n * The main reason I'm NOT using NaN or null now is my concern that, by mixing non-numbers\n * (specifically, values outside the range of signed 32-bit integers), performance may suffer.\n *\n * WARNING: Like many of the properties defined here, ADDR_INVALID is a common constant, which the\n * Closure Compiler will happily inline (with or without @const annotations; in fact, I've yet to\n * see a @const annotation EVER improve automatic inlining). However, if you don't make ABSOLUTELY\n * certain that this file is included BEFORE the first reference to any of these properties, that\n * automatic inlining will no longer occur.\n */\n ADDR_INVALID: -1,\n\n /*\n * Processor Exception Interrupts\n *\n * Of the following exceptions, all are designed to be restartable, except for 0x08 and 0x09 (and 0x0D\n * after an attempt to write to a read-only segment).\n *\n * Error codes are pushed onto the stack for 0x08 (always 0) and 0x0A through 0x0E.\n *\n * Priority: Instruction exception, TRAP, NMI, Processor Extension Segment Overrun, and finally INTR.\n *\n * All exceptions can also occur in real-mode, except where noted. A GP_FAULT in real-mode can be triggered\n * by \"any memory reference instruction that attempts to reference [a] 16-bit word at offset 0xFFFF\".\n *\n * Interrupts beyond 0x10 (up through 0x1F) are reserved for future exceptions.\n *\n * Implementation Detail: For any opcode we know must generate a UD_FAULT interrupt, we invoke opInvalid(),\n * NOT opUndefined(). UD_FAULT is for INVALID opcodes, Intel's choice of term \"undefined\" notwithstanding.\n *\n * We reserve the term \"undefined\" for opcodes that require more investigation, and we invoke opUndefined()\n * ONLY until an opcode's behavior has finally been defined, at which point it becomes either valid or invalid.\n * The term \"illegal\" seems completely superfluous; we don't need a third way of describing invalid opcodes.\n *\n * The term \"undocumented\" should be limited to operations that are valid but Intel simply never documented.\n */\n EXCEPTION: {\n DE_EXC: 0x00, // Divide Error Exception (#DE: fault, no error code)\n DB_EXC: 0x01, // Debug (aka Single Step Trap) Exception (#DB: fault or trap)\n NMI: 0x02, // Non-Maskable Interrupt\n BP_TRAP: 0x03, // Breakpoint Exception (#BP: trap)\n OF_TRAP: 0x04, // INTO Overflow Exception (#OF: trap)\n BR_FAULT: 0x05, // BOUND Error Exception (#BR: fault, no error code)\n UD_FAULT: 0x06, // Invalid (aka Undefined/Illegal) Opcode (#UD: fault, no error code)\n NM_FAULT: 0x07, // No Math Unit Available; see ESC or WAIT (#NM: fault, no error code)\n DF_FAULT: 0x08, // Double Fault; see LIDT (#DF: fault, with error code)\n MP_FAULT: 0x09, // Math Unit Protection Fault; see ESC (#MP: fault, no error code)\n TS_FAULT: 0x0A, // Invalid Task State Segment Fault (#TS: fault, with error code; protected-mode only)\n NP_FAULT: 0x0B, // Not Present Fault (#NP: fault, with error code; protected-mode only)\n SS_FAULT: 0x0C, // Stack Fault (#SS: fault, with error code; protected-mode only)\n GP_FAULT: 0x0D, // General Protection Fault (#GP: fault, with error code)\n PF_FAULT: 0x0E, // Page Fault (#PF: fault, with error code)\n MF_FAULT: 0x10 // Math Fault; see ESC or WAIT (#MF: fault, no error code)\n },\n /*\n * Processor Status flag definitions (stored in regPS)\n */\n PS: {\n CF: 0x0001, // bit 0: Carry flag\n BIT1: 0x0002, // bit 1: reserved, always set\n PF: 0x0004, // bit 2: Parity flag\n BIT3: 0x0008, // bit 3: reserved, always clear\n AF: 0x0010, // bit 4: Auxiliary Carry flag (aka Arithmetic flag)\n BIT5: 0x0020, // bit 5: reserved, always clear\n ZF: 0x0040, // bit 6: Zero flag\n SF: 0x0080, // bit 7: Sign flag\n TF: 0x0100, // bit 8: Trap flag\n IF: 0x0200, // bit 9: Interrupt flag\n DF: 0x0400, // bit 10: Direction flag\n OF: 0x0800, // bit 11: Overflow flag\n IOPL: {\n MASK: 0x3000, // bits 12-13: I/O Privilege Level (always set on 8086/80186; clear on 80286 reset)\n SHIFT: 12\n },\n NT: 0x4000, // bit 14: Nested Task flag (always set on 8086/80186; clear on 80286 reset)\n BIT15: 0x8000, // bit 15: reserved (always set on 8086/80186; clear otherwise)\n RF: 0x10000, // bit 16: Resume Flag (temporarily disables debug exceptions; 80386 only)\n VM: 0x20000 // bit 17: Virtual 8086 Mode (80386 only)\n },\n CR0: {\n /*\n * Machine Status Word (MSW) bit definitions\n */\n MSW: {\n PE: 0x0001, // protected-mode enabled\n MP: 0x0002, // monitor processor extension (ie, coprocessor)\n EM: 0x0004, // emulate processor extension\n TS: 0x0008, // task switch indicator\n ON: 0xFFF0, // on the 80286, these bits are always on (TODO: Verify)\n MASK: 0xFFFF // these are the only (MSW) bits that the 80286 can access (within CR0)\n },\n ET: 0x00000010, // coprocessor type (80287 or 80387); always 1 on post-80386 CPUs\n PG: 0x80000000|0 // 0: paging disabled\n },\n DR7: { // Debug Control Register\n L0: 0x00000001,\n G0: 0x00000002,\n L1: 0x00000004,\n G1: 0x00000008,\n L2: 0x00000010,\n G2: 0x00000020,\n L3: 0x00000040,\n G3: 0x00000080,\n ENABLE: 0x000000FF,\n LE: 0x00000100,\n GE: 0x00000200,\n RW0: 0x00030000, // 00: exec-only 01: write-only 10: undefined 11: read/write-only\n LEN0: 0x000C0000, // 00: one-byte, 01: two-byte, 10: undefined 11: four-byte\n RW1: 0x00300000, // 00: exec-only 01: write-only 10: undefined 11: read/write-only\n LEN1: 0x00C00000, // 00: one-byte, 01: two-byte, 10: undefined 11: four-byte\n RW2: 0x03000000, // 00: exec-only 01: write-only 10: undefined 11: read/write-only\n LEN2: 0x0C000000, // 00: one-byte, 01: two-byte, 10: undefined 11: four-byte\n RW3: 0x30000000, // 00: exec-only 01: write-only 10: undefined 11: read/write-only\n LEN3: 0xC0000000|0// 00: one-byte, 01: two-byte, 10: undefined 11: four-byte\n },\n DR6: { // Debug Status Register\n B0: 0x00000001,\n B1: 0x00000002,\n B2: 0x00000004,\n B3: 0x00000008,\n BD: 0x00002000, // set if the next instruction will read or write one of the eight debug registers and ICE-386 is also using them\n BS: 0x00004000, // set if the debug handler is entered due to the TF (trap flag) bit set in the EFLAGS register\n BT: 0x00008000 // set before entering the DEBUG handler if a task switch has occurred and the T-bit of the new TSS is set\n },\n SEL: {\n RPL: 0x0003, // requested privilege level (0-3)\n LDT: 0x0004, // table indicator (0: GDT, 1: LDT)\n MASK: 0xFFF8 // table offset\n },\n DESC: { // Descriptor Table Entry\n LIMIT: { // LIMIT bits 0-15 (or OFFSET if this is an INTERRUPT or TRAP gate)\n OFFSET: 0x0\n },\n BASE: { // BASE bits 0-15 (or SELECTOR if this is a TASK, INTERRUPT or TRAP gate)\n OFFSET: 0x2\n },\n ACC: { // bit definitions for the access word (offset 0x4)\n OFFSET: 0x4,\n BASE1623: 0x00FF, // (not used if this a TASK, INTERRUPT or TRAP gate; bits 0-5 are parm count for CALL gates)\n TYPE: {\n OFFSET: 0x5,\n MASK: 0x1F00,\n SEG: 0x1000,\n NONSEG: 0x0F00,\n /*\n * The following bits apply only when SEG is set\n */\n CODE: 0x0800, // set for CODE, clear for DATA\n ACCESSED: 0x0100, // set if accessed, clear if not accessed\n READABLE: 0x0200, // CODE: set if readable, clear if exec-only\n WRITABLE: 0x0200, // DATA: set if writable, clear if read-only\n CONFORMING: 0x0400, // CODE: set if conforming, clear if not\n EXPDOWN: 0x0400, // DATA: set if expand-down, clear if not\n /*\n * Assorted bits that apply only within NONSEG values\n */\n TSS_BUSY: 0x0200,\n NONSEG_386: 0x0800, // 80386 and up\n /*\n * The following are all the possible (valid) types (well, except for the variations\n * of DATA and CODE where the ACCESSED bit (0x0100) may also be set)\n */\n TSS286: 0x0100,\n LDT: 0x0200,\n TSS286_BUSY: 0x0300,\n GATE_CALL: 0x0400,\n GATE_TASK: 0x0500,\n GATE286_INT: 0x0600,\n GATE286_TRAP: 0x0700,\n TSS386: 0x0900, // 80386 and up\n TSS386_BUSY: 0x0B00, // 80386 and up\n GATE386_CALL: 0x0C00, // 80386 and up\n GATE386_INT: 0x0E00, // 80386 and up\n GATE386_TRAP: 0x0F00, // 80386 and up\n CODE_OR_DATA: 0x1E00,\n DATA_READONLY: 0x1000,\n DATA_WRITABLE: 0x1200,\n DATA_EXPDOWN: 0x1400,\n DATA_EXPDOWN_WRITABLE: 0x1600,\n CODE_EXECONLY: 0x1800,\n CODE_READABLE: 0x1A00,\n CODE_CONFORMING: 0x1C00,\n CODE_CONFORMING_READABLE: 0x1E00\n },\n DPL: {\n MASK: 0x6000,\n SHIFT: 13\n },\n PRESENT: 0x8000,\n INVALID: 0 // use X86.DESC.ACC.INVALID for invalid ACC values\n },\n EXT: { // descriptor extension word (reserved on the 80286; \"must be zero\")\n OFFSET: 0x6,\n LIMIT1619: 0x000F,\n AVAIL: 0x0010, // NOTE: set in various descriptors in OS/2\n /*\n * The BIG bit is known as the D bit for code segments; when set, all addresses and operands\n * in that code segment are assumed to be 32-bit.\n *\n * The BIG bit is known as the B bit for data segments; when set, it indicates: 1) all pushes,\n * pops, calls and returns use ESP instead of SP, and 2) the upper bound of an expand-down segment\n * is 0xffffffff instead of 0xffff.\n */\n BIG: 0x0040, // clear if default operand/address size is 16-bit, set if 32-bit\n LIMITPAGES: 0x0080, // clear if limit granularity is bytes, set if limit granularity is 4Kb pages\n BASE2431: 0xFF00\n },\n INVALID: 0 // use X86.DESC.INVALID for invalid DESC values\n },\n LADDR: { // linear address\n PDE: { // index of page directory entry\n MASK: 0xFFC00000|0,\n SHIFT: 20 // (addr & DIR.MASK) >>> DIR.SHIFT yields a page directory offset (ie, index * 4)\n },\n PTE: { // index of page table entry\n MASK: 0x003FF000,\n SHIFT: 10 // (addr & PAGE.MASK) >>> PAGE.SHIFT yields a page table offset (ie, index * 4)\n },\n OFFSET: 0x00000FFF\n },\n PTE: {\n FRAME: 0xFFFFF000|0,\n DIRTY: 0x00000040, // page has been modified\n ACCESSED: 0x00000020, // page has been accessed\n USER: 0x00000004, // set for user level (CPL 3), clear for supervisor level (CPL 0-2)\n READWRITE: 0x00000002, // set for read/write, clear for read-only (affects CPL 3 only)\n PRESENT: 0x00000001 // set for present page, clear for not-present page\n },\n TSS286: {\n PREV_TSS: 0x00,\n CPL0_SP: 0x02, // start of values altered by task switches\n CPL0_SS: 0x04,\n CPL1_SP: 0x06,\n CPL1_SS: 0x08,\n CPL2_SP: 0x0A,\n CPL2_SS: 0x0C,\n TASK_IP: 0x0E,\n TASK_PS: 0x10,\n TASK_AX: 0x12,\n TASK_CX: 0x14,\n TASK_DX: 0x16,\n TASK_BX: 0x18,\n TASK_SP: 0x1A,\n TASK_BP: 0x1C,\n TASK_SI: 0x1E,\n TASK_DI: 0x20,\n TASK_ES: 0x22,\n TASK_CS: 0x24,\n TASK_SS: 0x26,\n TASK_DS: 0x28, // end of values altered by task switches\n TASK_LDT: 0x2A\n },\n TSS386: {\n PREV_TSS: 0x00,\n CPL0_ESP: 0x04, // start of values altered by task switches\n CPL0_SS: 0x08,\n CPL1_ESP: 0x0c,\n CPL1_SS: 0x10,\n CPL2_ESP: 0x14,\n CPL2_SS: 0x18,\n TASK_CR3: 0x1C, // (not in TSS286)\n TASK_EIP: 0x20,\n TASK_PS: 0x24,\n TASK_EAX: 0x28,\n TASK_ECX: 0x2C,\n TASK_EDX: 0x30,\n TASK_EBX: 0x34,\n TASK_ESP: 0x38,\n TASK_EBP: 0x3C,\n TASK_ESI: 0x40,\n TASK_EDI: 0x44,\n TASK_ES: 0x48,\n TASK_CS: 0x4C,\n TASK_SS: 0x50,\n TASK_DS: 0x54,\n TASK_FS: 0x58, // (not in TSS286)\n TASK_GS: 0x5C, // (not in TSS286) end of values altered by task switches\n TASK_LDT: 0x60,\n TASK_IOPM: 0x64 // (not in TSS286)\n },\n ERRCODE: {\n EXT: 0x0001,\n IDT: 0x0002,\n LDT: 0x0004,\n SELMASK: 0xFFFC\n },\n RESULT: {\n /*\n * Flags were originally computed using 16-bit result registers:\n *\n * CF: resultZeroCarry & resultSize (ie, 0x100 or 0x10000)\n * PF: resultParitySign & 0xff\n * AF: (resultParitySign ^ resultAuxOverflow) & 0x0010\n * ZF: resultZeroCarry & (resultSize - 1)\n * SF: resultParitySign & (resultSize >> 1)\n * OF: (resultParitySign ^ resultAuxOverflow ^ (resultParitySign >> 1)) & (resultSize >> 1)\n *\n * I386 support requires that we now rely on 32-bit result registers:\n *\n * resultDst, resultSrc, resultArith, resultLogic and resultType\n *\n * and flags are now computed as follows:\n *\n * CF: ((resultDst ^ ((resultDst ^ resultSrc) & (resultSrc ^ resultArith))) & resultType)\n * PF: (resultLogic & 0xff)\n * AF: ((resultArith ^ (resultDst ^ resultSrc)) & 0x0010)\n * ZF: (resultLogic & ((resultType - 1) | resultType))\n * SF: (resultLogic & resultType)\n * OF: (((resultDst ^ resultArith) & (resultSrc ^ resultArith)) & resultType)\n *\n * where resultType contains both a size, which must be one of BYTE (0x80), WORD (0x8000),\n * or DWORD (0x80000000), along with bits for each of the arithmetic and/or logical flags that\n * are currently \"cached\" in the result registers (eg, X86.RESULT.CF for carry, X86.RESULT.OF\n * for overflow, etc).\n *\n * WARNING: Do not confuse these RESULT flag definitions with the PS flag definitions. RESULT\n * flags are used only as \"cached\" flag indicators, packed into bits 0-5 of resultType; they do\n * not match the actual flag bit definitions within the Processor Status (PS) register.\n *\n * Arithmetic operations should call:\n *\n * setArithResult(dst, src, value, type)\n * eg:\n * setArithResult(dst, src, dst+src, X86.RESULT.BYTE | X86.RESULT.ALL)\n *\n * and logical operations should call:\n *\n * setLogicResult(value, type [, carry [, overflow]])\n *\n * Since most logical operations clear both CF and OF, most calls to setLogicResult() can omit the\n * last two optional parameters.\n *\n * The type parameter of these methods indicates both the size of the result (BYTE, WORD or DWORD)\n * and which of the flags should now be considered \"cached\" by the result registers. If the previous\n * resultType specifies any flags not present in the new type parameter, then those flags are\n * calculated and written to the appropriate regPS bit(s) *before* the result registers are updated.\n *\n * Arithmetic operations are assumed to represent an \"added\" result; if a \"subtracted\" result is\n * provided instead (eg, from CMP, DEC, SUB, etc), then setArithResult() must include a 5th parameter\n * (fSubtract); eg:\n *\n * setArithResult(dst, src, dst-src, X86.RESULT.BYTE | X86.RESULT.ALL, true)\n *\n * TODO: Consider separating setArithResult() into two functions: setAddResult() and setSubResult().\n */\n BYTE: 0x80, // result is byte value\n WORD: 0x8000, // result is word value\n DWORD: 0x80000000|0,\n TYPE: 0x80008080|0,\n CF: 0x01, // carry flag is cached\n PF: 0x02, // parity flag is cached\n AF: 0x04, // aux carry flag is cached\n ZF: 0x08, // zero flag is cached\n SF: 0x10, // sign flag is cached\n OF: 0x20, // overflow flag is cached\n ALL: 0x3F, // all result flags are cached\n LOGIC: 0x1A, // all logical flags are cached; see setLogicResult()\n NOTCF: 0x3E // all result flags EXCEPT carry are cached\n },\n /*\n * Bit values for opFlags, which are all reset to zero prior to each instruction\n */\n OPFLAG: {\n NOREAD: 0x0001, // disable memory reads for the remainder of the current instruction\n NOWRITE: 0x0002, // disable memory writes for the remainder of the current instruction\n NOINTR: 0x0004, // a segreg has been set, or a prefix, or an STI (delay INTR acknowledgement)\n WRAP: 0x0008, // a segment wrap-around has occurred (relevant to 8086/8088 only)\n SEG: 0x0010, // segment override\n LOCK: 0x0020, // lock prefix\n REPZ: 0x0040, // repeat while Z (NOTE: this value MUST match PS.ZF; see opCMPSb/opCMPSw/opSCASb/opSCASw)\n REPNZ: 0x0080, // repeat while NZ\n REPEAT: 0x0100, // an instruction is being repeated (ie, some iteration AFTER the first)\n PUSHSP: 0x0200, // the SP register is potentially being referenced by a PUSH SP opcode, adjustment may be required\n DATASIZE: 0x0400, // data size override\n ADDRSIZE: 0x0800, // address size override\n FAULT: 0x1000, // a fault occurred during the current instruction\n DBEXC: 0x2000 // a DB_EXC exception occurred during the current instruction\n },\n /*\n * Bit values for intFlags\n */\n INTFLAG: {\n NONE: 0x00,\n INTR: 0x01, // h/w interrupt requested\n TRAP: 0x02, // trap (INT 0x01) requested\n HALT: 0x04, // halt (HLT) requested\n DMA: 0x08 // async DMA operation in progress\n },\n /*\n * Common opcodes (and/or any opcodes we need to refer to explicitly)\n */\n OPCODE: {\n ES: 0x26, // opES()\n CS: 0x2E, // opCS()\n SS: 0x36, // opSS()\n DS: 0x3E, // opDS()\n PUSHSP: 0x54, // opPUSHSP()\n PUSHA: 0x60, // opPUSHA() (80186 and up)\n POPA: 0x61, // opPOPA() (80186 and up)\n BOUND: 0x62, // opBOUND() (80186 and up)\n ARPL: 0x63, // opARPL() (80286 and up)\n FS: 0x64, // opFS() (80386 and up)\n GS: 0x65, // opGS() (80386 and up)\n OS: 0x66, // opOS() (80386 and up)\n AS: 0x67, // opAS() (80386 and up)\n PUSHN: 0x68, // opPUSHn() (80186 and up)\n IMULN: 0x69, // opIMULn() (80186 and up)\n PUSH8: 0x6A, // opPUSH8() (80186 and up)\n IMUL8: 0x6B, // opIMUL8() (80186 and up)\n INSB: 0x6C, // opINSb() (80186 and up)\n INSW: 0x6D, // opINSw() (80186 and up)\n OUTSB: 0x6E, // opOUTSb() (80186 and up)\n OUTSW: 0x6F, // opOUTSw() (80186 and up)\n ENTER: 0xC8, // opENTER() (80186 and up)\n LEAVE: 0xC9, // opLEAVE() (80186 and up)\n CALLF: 0x9A, // opCALLF()\n MOVSB: 0xA4, // opMOVSb()\n MOVSW: 0xA5, // opMOVSw()\n CMPSB: 0xA6, // opCMPSb()\n CMPSW: 0xA7, // opCMPSw()\n STOSB: 0xAA, // opSTOSb()\n STOSW: 0xAB, // opSTOSw()\n LODSB: 0xAC, // opLODSb()\n LODSW: 0xAD, // opLODSw()\n SCASB: 0xAE, // opSCASb()\n SCASW: 0xAF, // opSCASw()\n INT3: 0xCC, // opINT3()\n INTN: 0xCD, // opINTn()\n INTO: 0xCE, // opINTO()\n IRET: 0xCF, // opIRET()\n ESC0: 0xD8, // opESC0()\n ESC1: 0xD9, // opESC1()\n ESC2: 0xDA, // opESC2()\n ESC3: 0xDB, // opESC3()\n ESC4: 0xDC, // opESC4()\n ESC5: 0xDD, // opESC5()\n ESC6: 0xDE, // opESC6()\n ESC7: 0xDF, // opESC7()\n LOOPNZ: 0xE0, // opLOOPNZ()\n LOOPZ: 0xE1, // opLOOPZ()\n LOOP: 0xE2, // opLOOP()\n CALL: 0xE8, // opCALL()\n JMP: 0xE9, // opJMP() (2-byte displacement)\n JMPF: 0xEA, // opJMPF()\n JMPS: 0xEB, // opJMPs() (1-byte displacement)\n LOCK: 0xF0, // opLOCK()\n REPNZ: 0xF2, // opREPNZ()\n REPZ: 0xF3, // opREPZ()\n GRP4W: 0xFF,\n CALLW: 0x10FF, // GRP4W: fnCALLw()\n CALLFDW: 0x18FF, // GRP4W: fnCALLFdw()\n CALLMASK: 0x38FF, // mask 2-byte GRP4W opcodes with this before comparing to CALLW or CALLFDW\n UD2: 0x0B0F // UD2 (invalid opcode \"guaranteed\" to generate UD_FAULT on all post-8086 processors)\n },\n /*\n * Floating Point Unit (FPU), aka Numeric Data Processor (NDP), aka Numeric Processor Extension (NPX), aka Coprocessor definitions\n */\n FPU: {\n MODEL_8087: 8087,\n MODEL_80287: 80287,\n MODEL_80287XL: 80387, // internally, the 80287XL was an 80387SX, so generally, we treat this as MODEL_80387\n MODEL_80387: 80387,\n CONTROL: { // FPU Control Word\n IM: 0x0001, // bit 0: Invalid Operation Mask\n DM: 0x0002, // bit 1: Denormalized Operand Mask\n ZM: 0x0004, // bit 2: Zero Divide Mask\n OM: 0x0008, // bit 3: Overflow Mask\n UM: 0x0010, // bit 4: Underflow Mask\n PM: 0x0020, // bit 5: Precision Mask\n EXC: 0x003F, // all of the above exceptions\n IEM: 0x0080, // bit 7: Interrupt Enable Mask (0 enables interrupts, 1 masks them; 8087 only)\n PC: 0x0300, // bits 8-9: Precision Control\n RC: { // bits 10-11: Rounding Control\n NEAR: 0x0000,\n DOWN: 0x0400,\n UP: 0x0800,\n CHOP: 0x0C00,\n MASK: 0x0C00\n },\n IC: 0x1000, // bit 12: Infinity Control (0 for Projective, 1 for Affine)\n UNUSED: 0xE040, // bits 6,13-15: unused\n INIT: 0x03BF // X86.FPU.CONTROL.IM | X86.FPU.CONTROL.DM | X86.FPU.CONTROL.ZM | X86.FPU.CONTROL.OM | X86.FPU.CONTROL.UM | X86.FPU.CONTROL.PM | X86.FPU.CONTROL.IEM | X86.FPU.CONTROL.PC\n },\n STATUS: { // FPU Status Word\n IE: 0x0001, // bit 0: Invalid Operation\n DE: 0x0002, // bit 1: Denormalized Operand\n ZE: 0x0004, // bit 2: Zero Divide\n OE: 0x0008, // bit 3: Overflow\n UE: 0x0010, // bit 4: Underflow\n PE: 0x0020, // bit 5: Precision\n SF: 0x0040, // bit 6: Stack Fault (80387 and later; triggers an Invalid Operation exception)\n EXC: 0x007F, // all of the above exceptions\n ES: 0x0080, // bit 7: Error/Exception Status/Summary (Interrupt Request on 8087)\n C0: 0x0100, // bit 8: Condition Code 0\n C1: 0x0200, // bit 9: Condition Code 1\n C2: 0x0400, // bit 10: Condition Code 2\n ST: 0x3800, // bits 11-13: Stack Top\n ST_SHIFT: 11,\n C3: 0x4000, // bit 14: Condition Code 3\n CC: 0x4700, // all condition code bits\n BUSY: 0x8000 // bit 15: Busy\n },\n TAGS: {\n VALID: 0x0,\n ZERO: 0x1,\n SPECIAL:0x2,\n EMPTY: 0x3,\n MASK: 0x3\n }\n /*\n C3 C2 C1 C0 Condition Code (CC) values following an Examine\n\n 0 0 0 0 Valid, positive unnormalized (+Unnormal)\n 0 0 0 1 Invalid, positive, exponent=0 (+NaN)\n 0 0 1 0 Valid, negative, unnormalized (-Unnormal)\n 0 0 1 1 Invalid, negative, exponent=0 (-NaN)\n 0 1 0 0 Valid, positive, normalized (+Normal)\n 0 1 0 1 Infinity, positive (+Infinity)\n 0 1 1 0 Valid, negative, normalized (-Normal)\n 0 1 1 1 Infinity, negative (-Infinity)\n 1 0 0 0 Zero, positive (+0)\n 1 0 0 1 Empty\n 1 0 1 0 Zero, negative (-0)\n 1 0 1 1 Empty\n 1 1 0 0 Invalid, positive, exponent=0 (+Denormal)\n 1 1 0 1 Empty\n 1 1 1 0 Invalid, negative, exponent=0 (-Denormal)\n 1 1 1 1 Empty\n\n Condition Code (CC) values following an FCOM or FTST\n\n 0 0 ? 0 ST > source operand (FCOM); ST > 0 (FTST)\n 0 0 ? 1 ST < source operand (FCOM); ST < 0 (FTST)\n 1 0 ? 0 ST = source operand (FCOM); ST = 0 (FTST)\n 1 1 ? 1 ST is not comparable\n\n Condition Code (CC) values following a Remainder\n\n Q1 0 Q0 Q2 Complete reduction (he three low bits of the quotient stored in C0, C3, and C1)\n ? 1 ? ? Incomplete reduction\n */\n },\n CYCLES_8088: {\n nWordCyclePenalty: 4, // NOTE: accurate for the 8088/80188 only (on the 8086/80186, it applies to odd addresses only)\n nEACyclesBase: 5, // base or index only (BX, BP, SI or DI)\n nEACyclesDisp: 6, // displacement only\n nEACyclesBaseIndex: 7, // base + index (BP+DI and BX+SI)\n nEACyclesBaseIndexExtra: 8, // base + index (BP+SI and BX+DI require an extra cycle)\n nEACyclesBaseDisp: 9, // base or index + displacement\n nEACyclesBaseIndexDisp: 11, // base + index + displacement (BP+DI+n and BX+SI+n)\n nEACyclesBaseIndexDispExtra:12, // base + index + displacement (BP+SI+n and BX+DI+n require an extra cycle)\n nOpCyclesAAA: 4, // AAA, AAS, DAA, DAS, TEST acc,imm\n nOpCyclesAAD: 60,\n nOpCyclesAAM: 83,\n nOpCyclesArithRR: 3, // ADC, ADD, AND, OR, SBB, SUB, XOR and CMP reg,reg cycle time\n nOpCyclesArithRM: 9, // ADC, ADD, AND, OR, SBB, SUB, and XOR reg,mem (and CMP mem,reg) cycle time\n nOpCyclesArithMR: 16, // ADC, ADD, AND, OR, SBB, SUB, and XOR mem,reg cycle time\n nOpCyclesArithMID: 1, // ADC, ADD, AND, OR, SBB, SUB, XOR and CMP mem,imm cycle delta\n nOpCyclesCall: 19,\n nOpCyclesCallF: 28,\n nOpCyclesCallWR: 16,\n nOpCyclesCallWM: 21,\n nOpCyclesCallDM: 37,\n nOpCyclesCLI: 2,\n nOpCyclesCompareRM: 9, // CMP reg,mem cycle time (same as nOpCyclesArithRM on an 8086 but not on a 80286)\n nOpCyclesCWD: 5,\n nOpCyclesBound: 33, // N/A if 8086/8088, 33-35 if 80186/80188 (TODO: Determine what the range means for an 80186/80188)\n nOpCyclesInP: 10,\n nOpCyclesInDX: 8,\n nOpCyclesIncR: 3, // INC reg, DEC reg\n nOpCyclesIncM: 15, // INC mem, DEC mem\n nOpCyclesInt: 51,\n nOpCyclesInt3D: 1,\n nOpCyclesIntOD: 2,\n nOpCyclesIntOFall: 4,\n nOpCyclesIRet: 32,\n nOpCyclesJmp: 15,\n nOpCyclesJmpF: 15,\n nOpCyclesJmpC: 16,\n nOpCyclesJmpCFall: 4,\n nOpCyclesJmpWR: 11,\n nOpCyclesJmpWM: 18,\n nOpCyclesJmpDM: 24,\n nOpCyclesLAHF: 4, // LAHF, SAHF, MOV reg,imm\n nOpCyclesLEA: 2,\n nOpCyclesLS: 16, // LDS, LES\n nOpCyclesLoop: 17, // LOOP, LOOPNZ\n nOpCyclesLoopZ: 18, // LOOPZ, JCXZ\n nOpCyclesLoopNZ: 19, // LOOPNZ\n nOpCyclesLoopFall: 5, // LOOP\n nOpCyclesLoopZFall: 6, // LOOPZ, JCXZ\n nOpCyclesMovRR: 2,\n nOpCyclesMovRM: 8,\n nOpCyclesMovMR: 9,\n nOpCyclesMovRI: 10,\n nOpCyclesMovMI: 10,\n nOpCyclesMovAM: 10,\n nOpCyclesMovMA: 10,\n nOpCyclesDivBR: 80, // range of 80-90\n nOpCyclesDivWR: 144, // range of 144-162\n nOpCyclesDivBM: 86, // range of 86-96\n nOpCyclesDivWM: 154, // range of 154-172\n nOpCyclesIDivBR: 101, // range of 101-112\n nOpCyclesIDivWR: 165, // range of 165-184\n nOpCyclesIDivBM: 107, // range of 107-118\n nOpCyclesIDivWM: 171, // range of 171-190\n nOpCyclesMulBR: 70, // range of 70-77\n nOpCyclesMulWR: 113, // range of 113-118\n nOpCyclesMulBM: 76, // range of 76-83\n nOpCyclesMulWM: 124, // range of 124-139\n nOpCyclesIMulBR: 80, // range of 80-98\n nOpCyclesIMulWR: 128, // range of 128-154\n nOpCyclesIMulBM: 86, // range of 86-104\n nOpCyclesIMulWM: 134, // range of 134-160\n nOpCyclesNegR: 3, // NEG reg, NOT reg\n nOpCyclesNegM: 16, // NEG mem, NOT mem\n nOpCyclesOutP: 10,\n nOpCyclesOutDX: 8,\n nOpCyclesPopAll: 51, // N/A if 8086/8088, 51 if 80186, 83 if 80188 (TODO: Verify)\n nOpCyclesPopReg: 8,\n nOpCyclesPopMem: 17,\n nOpCyclesPushAll: 36, // N/A if 8086/8088, 36 if 80186, 68 if 80188 (TODO: Verify)\n nOpCyclesPushReg: 11, // NOTE: \"The 8086 Book\" claims this is 10, but it's an outlier....\n nOpCyclesPushMem: 16,\n nOpCyclesPushSeg: 10,\n nOpCyclesPrefix: 2,\n nOpCyclesCmpS: 18,\n nOpCyclesCmpSr0: 9-2, // reduced by nOpCyclesPrefix\n nOpCyclesCmpSrn: 17-2, // reduced by nOpCyclesPrefix\n nOpCyclesLodS: 12,\n nOpCyclesLodSr0: 9-2, // reduced by nOpCyclesPrefix\n nOpCyclesLodSrn: 13-2, // reduced by nOpCyclesPrefix\n nOpCyclesMovS: 18,\n nOpCyclesMovSr0: 9-2, // reduced by nOpCyclesPrefix\n nOpCyclesMovSrn: 17-2, // reduced by nOpCyclesPrefix\n nOpCyclesScaS: 15,\n nOpCyclesScaSr0: 9-2, // reduced by nOpCyclesPrefix\n nOpCyclesScaSrn: 15-2, // reduced by nOpCyclesPrefix\n nOpCyclesStoS: 11,\n nOpCyclesStoSr0: 9-2, // reduced by nOpCyclesPrefix\n nOpCyclesStoSrn: 10-2, // reduced by nOpCyclesPrefix\n nOpCyclesRet: 8,\n nOpCyclesRetn: 12,\n nOpCyclesRetF: 18,\n nOpCyclesRetFn: 17,\n nOpCyclesShift1M: 15, // ROL/ROR/RCL/RCR/SHL/SHR/SAR reg,1\n nOpCyclesShiftCR: 8, // ROL/ROR/RCL/RCR/SHL/SHR/SAR reg,CL\n nOpCyclesShiftCM: 20, // ROL/ROR/RCL/RCR/SHL/SHR/SAR mem,CL\n nOpCyclesShiftCS: 2, // this is the left-shift value used to convert the count to the cycle cost\n nOpCyclesTestRR: 3,\n nOpCyclesTestRM: 9,\n nOpCyclesTestRI: 5,\n nOpCyclesTestMI: 11,\n nOpCyclesXchgRR: 4,\n nOpCyclesXchgRM: 17,\n nOpCyclesXLAT: 11\n },\n CYCLES_80286: {\n nWordCyclePenalty: 0,\n nEACyclesBase: 0,\n nEACyclesDisp: 0,\n nEACyclesBaseIndex: 0,\n nEACyclesBaseIndexExtra: 0,\n nEACyclesBaseDisp: 0,\n nEACyclesBaseIndexDisp: 1,\n nEACyclesBaseIndexDispExtra:1,\n nOpCyclesAAA: 3,\n nOpCyclesAAD: 14,\n nOpCyclesAAM: 16,\n nOpCyclesArithRR: 2,\n nOpCyclesArithRM: 7,\n nOpCyclesArithMR: 7,\n nOpCyclesArithMID: 0,\n nOpCyclesCall: 7, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesCallF: 13, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesCallWR: 7, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesCallWM: 11, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesCallDM: 16, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesCLI: 3,\n nOpCyclesCompareRM: 6,\n nOpCyclesCWD: 2,\n nOpCyclesBound: 13,\n nOpCyclesInP: 5,\n nOpCyclesInDX: 5,\n nOpCyclesIncR: 2,\n nOpCyclesIncM: 7,\n nOpCyclesInt: 23, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesInt3D: 0,\n nOpCyclesIntOD: 1,\n nOpCyclesIntOFall: 3,\n nOpCyclesIRet: 17, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesJmp: 7, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesJmpF: 11, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesJmpC: 7, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesJmpCFall: 3,\n nOpCyclesJmpWR: 7, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesJmpWM: 11, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesJmpDM: 15, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesLAHF: 2,\n nOpCyclesLEA: 3,\n nOpCyclesLS: 7,\n nOpCyclesLoop: 8, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesLoopZ: 8, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesLoopNZ: 8, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesLoopFall: 4,\n nOpCyclesLoopZFall: 4,\n nOpCyclesMovRR: 2, // this is actually the same as the 8086...\n nOpCyclesMovRM: 3,\n nOpCyclesMovMR: 5,\n nOpCyclesMovRI: 2,\n nOpCyclesMovMI: 3,\n nOpCyclesMovAM: 5, // this is actually slower than the MOD/RM form of MOV AX,mem (see nOpCyclesMovRM)\n nOpCyclesMovMA: 3,\n nOpCyclesDivBR: 14,\n nOpCyclesDivWR: 22,\n nOpCyclesDivBM: 17,\n nOpCyclesDivWM: 25,\n nOpCyclesIDivBR: 17,\n nOpCyclesIDivWR: 25,\n nOpCyclesIDivBM: 20,\n nOpCyclesIDivWM: 28,\n nOpCyclesMulBR: 13,\n nOpCyclesMulWR: 21,\n nOpCyclesMulBM: 16,\n nOpCyclesMulWM: 24,\n nOpCyclesIMulBR: 13,\n nOpCyclesIMulWR: 21,\n nOpCyclesIMulBM: 16,\n nOpCyclesIMulWM: 24,\n nOpCyclesNegR: 2,\n nOpCyclesNegM: 7,\n nOpCyclesOutP: 5,\n nOpCyclesOutDX: 5,\n nOpCyclesPopAll: 19,\n nOpCyclesPopReg: 5,\n nOpCyclesPopMem: 5,\n nOpCyclesPushAll: 17,\n nOpCyclesPushReg: 3,\n nOpCyclesPushMem: 5,\n nOpCyclesPushSeg: 3,\n nOpCyclesPrefix: 0,\n nOpCyclesCmpS: 8,\n nOpCyclesCmpSr0: 5,\n nOpCyclesCmpSrn: 9,\n nOpCyclesLodS: 5,\n nOpCyclesLodSr0: 5,\n nOpCyclesLodSrn: 4,\n nOpCyclesMovS: 5,\n nOpCyclesMovSr0: 5,\n nOpCyclesMovSrn: 4,\n nOpCyclesScaS: 7,\n nOpCyclesScaSr0: 5,\n nOpCyclesScaSrn: 8,\n nOpCyclesStoS: 3,\n nOpCyclesStoSr0: 4,\n nOpCyclesStoSrn: 3,\n nOpCyclesRet: 11, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesRetn: 11, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesRetF: 15, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesRetFn: 15, // on the 80286, this ALSO includes the number of bytes in the target instruction\n nOpCyclesShift1M: 7,\n nOpCyclesShiftCR: 5,\n nOpCyclesShiftCM: 8,\n nOpCyclesShiftCS: 0,\n nOpCyclesTestRR: 2,\n nOpCyclesTestRM: 6,\n nOpCyclesTestRI: 3,\n nOpCyclesTestMI: 6,\n nOpCyclesXchgRR: 3,\n nOpCyclesXchgRM: 5,\n nOpCyclesXLAT: 5\n },\n /*\n * TODO: All 80386 cycle counts are based on 80286 counts until I have time to hand-generate an 80386-specific table;\n * the values below are used by selected 32-bit opcode handlers only.\n */\n CYCLES_80386: {\n nEACyclesBase: 0,\n nEACyclesDisp: 0,\n nEACyclesBaseIndex: 0,\n nEACyclesBaseIndexExtra: 0,\n nEACyclesBaseDisp: 0,\n nEACyclesBaseIndexDisp: 1,\n nEACyclesBaseIndexDispExtra:1\n }\n};\n\n/*\n * BACKTRACK-related definitions (used only if BACKTRACK is defined)\n */\nX86.BTINFO = {\n SP_LO: 0,\n SP_HI: 0\n};\n\n/*\n * These PS flags are always stored directly in regPS for the 8086/8088, hence the\n * \"direct\" designation; other processors must adjust these bits accordingly. The final\n * adjusted value is stored in PS_DIRECT (ie, 80286 and up also include PS.IOPL.MASK and\n * PS.NT in PS_DIRECT).\n */\nX86.PS_DIRECT_8086 = (X86.PS.TF | X86.PS.IF | X86.PS.DF);\n\n/*\n * These are the default \"always set\" PS bits for the 8086/8088; other processors must\n * adjust these bits accordingly. The final adjusted value is stored in PS_SET.\n */\nX86.PS_SET_8086 = (X86.PS.BIT1 | X86.PS.IOPL.MASK | X86.PS.NT | X86.PS.BIT15);\n\n/*\n * These PS arithmetic and logical flags may be \"cached\" across several result registers;\n * whether or not they're currently cached depends on the RESULT bits in resultType.\n */\nX86.PS_CACHED = (X86.PS.CF | X86.PS.PF | X86.PS.AF | X86.PS.ZF | X86.PS.SF | X86.PS.OF);\n\n/*\n * PS_SAHF is a subset of the arithmetic flags, and refers only to those flags that the\n * SAHF and LAHF \"8080 legacy\" opcodes affect.\n */\nX86.PS_SAHF = (X86.PS.CF | X86.PS.PF | X86.PS.AF | X86.PS.ZF | X86.PS.SF);\n\n/*\n * Before we zero opFlags, we first see if any of the following PREFIX bits were set. If any were set,\n * they are OR'ed into opPrefixes; otherwise, opPrefixes is zeroed as well. This gives prefix-conscious\n * instructions like LODS, MOVS, STOS, CMPS, etc, a way of determining which prefixes, if any, immediately\n * preceded them.\n */\nX86.OPFLAG_PREFIXES = (X86.OPFLAG.SEG | X86.OPFLAG.LOCK | X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ | X86.OPFLAG.DATASIZE | X86.OPFLAG.ADDRSIZE);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/interrupts.js (C) Jeff Parsons 2012-2018\n */\n\nvar Interrupts = {\n VIDEO: 0x10,\n DISK: 0x13,\n CASSETTE: 0x15,\n KBD: 0x16,\n RTC: 0x1A,\n ALT_TIMER: 0x1C, // invoked by the BIOS timer interrupt handler (vector 0x08)\n DOS: 0x21,\n DOS_IDLE: 0x28,\n DOS_NETBIOS:0x2A,\n MOUSE: 0x33,\n ALT_DISK: 0x40, // HDC BIOS saves original FDC BIOS vector here\n HD0_PARMS: 0x41, // parameter table for hard drive 0\n HD1_PARMS: 0x46, // parameter table for hard drive 1\n HD_PARMS: {\n MAX_CYL: 0x00, // maximum cylinders (2 bytes)\n MAX_HEADS: 0x02, // maximum heads (1 byte)\n WP_CYL: 0x05, // write precompensation cylinder (2 bytes)\n MAX_ECC: 0x07, // max ECC burst (1 byte)\n DRIVE_CTRL: 0x08, // drive control (1 byte)\n PARK_CYL: 0x0C, // landing zone cylinder (2 bytes)\n SEC_TRACK: 0x0E // sectors per track (1 byte)\n },\n ALT_VIDEO: 0x6D, // IBM VGA BIOS saves original video BIOS vector here\n WINCB: {\n VECTOR: 0x30 // Windows PM call-back interface (aka Transfer Space Fault)\n },\n WINDBG: { // Windows Debugger protected-mode interface\n VECTOR: 0x41, // (AX==command)\n IS_LOADED: 0x004F, // DS_DebLoaded\n LOADED: 0xF386, // DS_DebPresent (returned in AX if Windows Debugger loaded)\n LOADSEG: 0x0050, // DS_LoadSeg (SI==0 if code, 1 if data; BX==segnum-1; CX==selector; ES:[E]DI->module name)\n FREESEG: 0x0052, // DS_FreeSeg (BX==segment)\n KRNLVARS: 0x005A, // DS_Kernel_Vars\n RELSEG: 0x005C, // DS_ReleaseSeg (same as DS_FreeSeg but \"restores any breakpoints first\")\n LOADHIGH: 0x005D, // D386_LoadCodeDataHigh\n EXITCALL: 0x0062, // DS_EXITCALL\n LOADDLL: 0x0064, // DS_LOADDLL\n DELMODULE: 0x0065, // DS_DELMODULE\n UNKNOWN66: 0x0066, // Unknown (but I suspect it isn't good)\n UNKNOWN67: 0x0067, // Unknown (but I suspect it isn't good)\n REGDOTCMD: 0x0070, // DS_RegisterDotCommand\n CHECKFAULT: 0x007F, // DS_CheckFault (BX==fault #, CX==FAULTTYPE bits; return AX=0 to handle fault normally, 1 to issue TRAPFAULT)\n FAULTTYPE: {\n V86: 0x0001,\n PM: 0x0002,\n RING0: 0x0004,\n FIRST: 0x0008,\n LAST: 0x0010\n },\n TRAPFAULT: 0x0083, // DS_TrapFault (BX==fault #, CX==faulting CS, EDX==faulting EIP, ESI==fault error, EDI==fault flags)\n GETSYMBOL: 0x008D, // DS_GetSymbol (DS:ESI->symbol; return AX=0 if success, 1 if not found, 2 if memory not loaded yet)\n LOADSEG32: 0x0150, // DS_LoadSeg_32 (SI==0 if code, 1 if data; DX:EBX->D386_Device_Params)\n FREESEG32: 0x0152, // DS_FreeSeg_32 (BX==segment, DX:EDI->module name)\n CONDBP: 0xF001, // DS_CondBP (break here if WDEB386 was run with /B; ESI -> string to display)\n ENABLED: true // support for WINDBG interrupts can be disabled (but NOT if WINDBGRM is enabled)\n },\n WINDBGRM: { // Windows Debugger real-mode interface\n VECTOR: 0x68, // (AH==command)\n IS_LOADED: 0x43, // D386_Identify\n LOADED: 0xF386, // D386_Id (returned in AX if Windows Debugger loaded)\n PREP_PMODE: 0x44, // D386_Prepare_PMode (must return a 16:32 address in ES:EDI to a \"PMinit\" handler)\n FREESEG: 0x48, // D386_Free_Segment (BX==real-mode segment)\n REMOVESEGS: 0x4F, // D386_Remove_Segs (remove any undefined segments from the named module at ES:DI)\n LOADSEG: 0x50, // D386_Load_Segment (AL=segment type, ES:DI->D386_Device_Params)\n ENABLED: true // support for WINDBGRM interrupts can be disabled\n },\n FUNCS: {} // filled in only if DEBUGGER is true\n};\n\nif (DEBUGGER) {\n Interrupts.BIOS_DATA = {\n 0x400: [\"RS232_BASE\",8], // BASE ADDRESSES OF RS232 ADAPTERS\n 0x408: [\"PRINTER_BASE\",8], // BASE ADDRESSES OF PRINTER ADAPTERS\n 0x410: [\"EQUIP_FLAG\",2], // INSTALLED HARDWARE FLAGS\n 0x412: [\"MFG_TST\",1], // INITIALIZATION FLAGS\n 0x413: [\"MEMORY_SIZE\",2], // BASE MEMORY SIZE IN K BYTES (X 1024)\n 0x415: [\"MFG_ERR_FLAG\",2], // SCRATCHPAD FOR MANUFACTURING ERROR CODES\n 0x417: [\"KB_FLAG\",1], // KEYBOARD SHIFT STATE AND STATUS FLAGS\n 0x418: [\"KB_FLAG_1\",1], // SECOND BYTE OF KEYBOARD STATUS\n 0x419: [\"ALT_INPUT\",1], // STORAGE FOR ALTERNATE KEY PAD ENTRY\n 0x41A: [\"BUFFER_HEAD\",2], // POINTER TO HEAD OF KEYBOARD BUFFER\n 0x41C: [\"BUFFER_TAIL\",2], // POINTER TO TAIL OF KEYBOARD BUFFER\n 0x41E: [\"KB_BUFFER\",32], // ROOM FOR 15 SCAN CODE ENTRIES\n 0x43E: [\"SEEK_STATUS\",1], // DRIVE RECALIBRATION STATUS (BIT 3-0 = DRIVE 3-0 RECALIBRATION BEFORE NEXT SEEK IF BIT IS = 0)\n 0x43F: [\"MOTOR_STATUS\",1], // MOTOR STATUS (BIT 3-0 = DRIVE 3-0 CURRENTLY RUNNING, BIT 7 = CURRENT OPERATION IS A WRITE)\n 0x440: [\"MOTOR_COUNT\",1], // TIME OUT COUNTER FOR MOTOR(S) TURN OFF\n 0x441: [\"DISKETTE_STATUS\",1], // RETURN CODE STATUS BYTE\n 0x442: [\"NEC_STATUS\",7], // STATUS BYTES FROM DISKETTE OPERATION\n 0x449: [\"CRT_MODE\",1], // CURRENT DISPLAY MODE (TYPE)\n 0x44A: [\"CRT_COLS\",2], // NUMBER OF COLUMNS ON SCREEN\n 0x44C: [\"CRT_LEN\",2], // LENGTH OF REGEN BUFFER IN BYTES\n 0x44E: [\"CRT_START\",2], // STARTING ADDRESS IN REGEN BUFFER\n 0x450: [\"CURSOR_POSN\",16], // CURSOR FOR EACH OF UP TO 8 PAGES\n 0x460: [\"CURSOR_MODE\",2], // CURRENT CURSOR MODE SETTING\n 0x462: [\"ACTIVE_PAGE\",1], // CURRENT PAGE BEING DISPLAYED\n 0x463: [\"ADDR_6845\",2], // BASE ADDRESS FOR ACTIVE DISPLAY CARD\n 0x465: [\"CRT_MODE_SET\",1], // CURRENT SETTING OF THE 3X8 REGISTER\n 0x466: [\"CRT_PALETTE\",1], // CURRENT PALETTE SETTING - COLOR CARD\n 0x467: [\"IO_ROM_INIT\",2], // POINTER TO ROM INITIALIZATION ROUTINE\n 0x469: [\"IO_ROM_SEG\",2], // POINTER TO I/O ROM SEGMENT\n 0x46B: [\"INTR_FLAG\",1], // FLAG INDICATING AN INTERRUPT HAPPENED\n 0x46C: [\"TIMER_LOW\",2], // LOW WORD OF TIMER COUNT\n 0x46E: [\"TIMER_HIGH\",2], // HIGH WORD OF TIMER COUNT\n 0x470: [\"TIMER_OFL\",1], // TIMER HAS ROLLED OVER SINCE LAST READ\n 0x471: [\"BIOS_BREAK\",1], // BIT 7=1 IF BREAK KEY HAS BEEN PRESSED\n 0x472: [\"RESET_FLAG\",2], // WORD=1234H IF KEYBOARD RESET UNDERWAY\n 0x474: [\"DISK_STATUS1\",1], // FIXED DISK STATUS\n 0x475: [\"HF_NUM\",1], // COUNT OF FIXED DISK DRIVES\n 0x476: [\"CONTROL_BYTE\",1], // HEAD CONTROL BYTE\n 0x477: [\"PORT_OFF\",1], // RESERVED (PORT OFFSET)\n 0x478: [\"PRINT_TIM_OUT\",4], // TIME OUT COUNTERS FOR PRINTER RESPONSE\n 0x47C: [\"RS232_TIM_OUT\",4], // TIME OUT COUNTERS FOR RS232 RESPONSE\n 0x480: [\"BUFFER_START\",2], // OFFSET OF KEYBOARD BUFFER START\n 0x482: [\"BUFFER_END\",2], // OFFSET OF END OF BUFFER\n 0x484: [\"ROWS\",1], // ROWS ON THE ACTIVE SCREEN (LESS 1)\n 0x485: [\"POINTS\",2], // BYTES PER CHARACTER\n 0x487: [\"INFO\",1], // MODE OPTIONS\n 0x488: [\"INFO_3\",3], // FEATURE BIT SWITCHES\n 0x48B: [\"LASTRATE\",1], // LAST DISKETTE DATA RATE SELECTED\n 0x48C: [\"HF_STATUS\",1], // STATUS REGISTER\n 0x48D: [\"HF_ERROR\",1], // ERROR REGISTER\n 0x48E: [\"HF_INT_FLAG\",1], // FIXED DISK INTERRUPT FLAG\n 0x48F: [\"HF_CNTRL\",1], // COMBO FIXED DISK/DISKETTE CARD BIT 0=1\n 0x490: [\"DSK_STATE\",4], // DRIVE 0 MEDIA STATE, DRIVE 1 MEDIA STATE, DRIVE 0 OPERATION START STATE, DRIVE 1 OPERATION START STATE\n 0x494: [\"DSK_TRK\",2], // DRIVE 0 PRESENT CYLINDER, DRIVE 1 PRESENT CYLINDER\n 0x496: [\"KB_FLAG_3\",1], // KEYBOARD MODE STATE AND TYPE FLAGS\n 0x497: [\"KB_FLAG_2\",1], // KEYBOARD LED FLAGS\n 0x498: [\"USER_FLAG\",2], // OFFSET ADDRESS OF USERS WAIT FLAG\n 0x49A: [\"USER_FLAG_SEG\",2], // SEGMENT ADDRESS OF USER WAIT FLAG\n 0x49C: [\"RTC_LOW\",2], // LOW WORD OF USER WAIT FLAG\n 0x49E: [\"RTC_HIGH\",2], // HIGH WORD OF USER WAIT FLAG\n 0x4A0: [\"RTC_WAIT_FLAG\",1], // WAIT ACTIVE FLAG (01=BUSY, 80=POSTED) (00=POST ACKNOWLEDGED)\n 0x4A1: [\"NET\",7], // RESERVED FOR NETWORK ADAPTERS\n 0x4A8: [\"SAVE_PTR\",4] // POINTER TO EGA PARAMETER CONTROL BLOCK\n };\n \n /*\n * See DebuggerX86.prototype.replaceRegs() for the rules governing how register contents are replaced in the strings below.\n *\n * Replacements occur in the following order:\n *\n * Replace every @XX (or @XXX), where XX (or XXX) is a register, with the register's value.\n * Replace every #XX, where XX is a hex byte value, with the corresponding ASCII character (if printable).\n * Replace every $XXXX:XXXX, where XXXX:XXXX is a segmented address, with the zero-terminated string at that address.\n * Replace every ^XXXX:XXXX, where XXXX:XXXX is a segmented address, with the FCB filename stored at that address.\n *\n * The last replacement is obviously DOS-specific, since FCBs are DOS constructs.\n */\n Interrupts.FUNCS[Interrupts.VIDEO] = {\n 0x00: \"set mode (@AL)\",\n 0x01: \"set cursor type (start=@CH,end=@CL)\",\n 0x02: \"set cursor pos (row=@DH,col=@DL,page=@BH)\",\n 0x03: \"read cursor pos (page=@BH)\",\n 0x04: \"read light pen\",\n 0x05: \"set display page (@AL)\",\n 0x06: \"scroll up (lines=@AL)\",\n 0x07: \"scroll down (lines=@AL)\",\n 0x08: \"read character (page=@BH)\",\n 0x09: \"write char/attr (@AL,attr=@BL,count=@CX)\",\n 0x0A: \"write char (@AL,count=@CX)\",\n 0x0B: \"set palette (id=@BH,color=@BL)\",\n 0x0C: \"write dot (row=@DX,col=@CX)\",\n 0x0D: \"read dot (row=@DX,col=@CX)\",\n 0x0E: \"write tty (@AL)\"\n };\n \n Interrupts.FUNCS[Interrupts.DISK] = {\n 0x00: \"disk reset\",\n 0x01: \"get status\",\n 0x02: \"read drive @DL (@CH:@DH:@CL,@AL) into @ES:@BX\",\n 0x03: \"write drive @DL (@CH:@DH:@CL,@AL) from @ES:@BX\",\n 0x04: \"verify drive @DL (@CH:@DH:@CL,@AL)\",\n 0x05: \"format drive @DL using @ES:@BX\",\n 0x08: \"read drive @DL parameters\",\n 0x15: \"get drive @DL DASD type\",\n 0x16: \"get drive @DL change line status\",\n 0x17: \"set drive @DL DASD type\",\n 0x18: \"set drive @DL media type\"\n /*\n * Here's an additional function reference, previously in the HDC component, but moved here\n * because our components are hardware emulations, not BIOS emulations, so this information is\n * really only of interest to the Debugger (or the casual observer).\n *\n * RESET: 0x00,\n * GET_STATUS: 0x01,\n * READ_SECTORS: 0x02,\n * WRITE_SECTORS: 0x03,\n * VERIFY_SECTORS: 0x04,\n * FORMAT_TRK: 0x05,\n * FORMAT_BAD: 0x06,\n * FORMAT_DRIVE: 0x07,\n * GET_DRIVEPARMS: 0x08,\n * SET_DRIVEPARMS: 0x09,\n * READ_LONG: 0x0A,\n * WRITE_LONG: 0x0B,\n * SEEK: 0x0C,\n * ALT_RESET: 0x0D,\n * READ_BUFFER: 0x0E,\n * WRITE_BUFFER: 0x0F,\n * TEST_READY: 0x10,\n * RECALIBRATE: 0x11,\n * RAM_DIAGNOSTIC: 0x12,\n * DRV_DIAGNOSTIC: 0x13,\n * CTL_DIAGNOSTIC: 0x14\n */\n };\n \n Interrupts.FUNCS[Interrupts.CASSETTE] = {\n 0x80: \"open device\",\n 0x81: \"close device\",\n 0x82: \"program termination\",\n 0x83: \"wait @CX:@DXus for event\",\n 0x84: \"joystick support\",\n 0x85: \"SYSREQ pressed\",\n 0x86: \"wait @CX:@DXus\",\n 0x87: \"move block (@CX words)\",\n 0x88: \"get extended memory size\",\n 0x89: \"processor to virtual mode\",\n 0x90: \"device busy loop\",\n 0x91: \"interrupt complete flag set\"\n };\n \n Interrupts.FUNCS[Interrupts.DOS] = {\n 0x00: \"terminate program\",\n 0x01: \"read character (AL) from stdin with echo\",\n 0x02: \"write character #@DL to stdout\",\n 0x03: \"read character (AL) from stdaux\", // eg, COM1\n 0x04: \"write character #@DL to stdaux\", // eg, COM1\n 0x05: \"write character #@DL to stdprn\", // eg, LPT1\n 0x06: \"direct console output (input if @DL=FF)\",\n 0x07: \"direct console input without echo\",\n 0x08: \"read character (AL) from stdin without echo\",\n 0x09: \"write string $@DS:@DX to stdout\",\n 0x0A: \"buffered input (DS:DX)\", // byte 0 is maximum chars, byte 1 is number of previous characters, byte 2 is number of characters read\n 0x0B: \"get stdin status\",\n 0x0C: \"flush buffer and read stdin\", // AL is a function # (0x01, 0x06, 0x07, 0x08, or 0x0A)\n 0x0D: \"disk reset\",\n 0x0E: \"select default drive @DL\", // returns # of available drives in AL\n 0x0F: \"open file using FCB ^@DS:@DX\", // DS:DX -> unopened File Control Block\n 0x10: \"close file using FCB ^@DS:@DX\",\n 0x11: \"find first matching file using FCB ^@DS:@DX\",\n 0x12: \"find next matching file using FCB ^@DS:@DX\",\n 0x13: \"delete file using FCB ^@DS:@DX\",\n 0x14: \"sequential read from file using FCB ^@DS:@DX\",\n 0x15: \"sequential write to file using FCB ^@DS:@DX\",\n 0x16: \"create or truncate file using FCB ^@DS:@DX\",\n 0x17: \"rename file using FCB ^@DS:@DX\",\n 0x19: \"get current default drive (AL)\",\n 0x1A: \"set disk transfer area (DTA=@DS:@DX)\",\n 0x1B: \"get allocation information for default drive\",\n 0x1C: \"get allocation information for specific drive @DL\",\n 0x1F: \"get drive parameter block for default drive\",\n 0x21: \"read random record from file using FCB ^@DS:@DX\",\n 0x22: \"write random record to file using FCB ^@DS:@DX\",\n 0x23: \"get file size using FCB ^@DS:@DX\",\n 0x24: \"set random record number for FCB ^@DS:@DX\",\n 0x25: \"set address @DS:@DX of interrupt vector @AL\",\n 0x26: \"create new PSP at segment @DX\",\n 0x27: \"random block read from file using FCB ^@DS:@DX\",\n 0x28: \"random block write to file using FCB ^@DS:@DX\",\n 0x29: \"parse filename $@DS:@SI into FCB @ES:@DI using @AL\",\n 0x2A: \"get system date (year=CX, mon=DH, day=DL)\",\n 0x2B: \"set system date (year=@CX, mon=@DH, day=@DL)\",\n 0x2C: \"get system time (hour=CH, min=CL, sec=DH, 100ths=DL)\",\n 0x2D: \"set system time (hour=@CH, min=@CL, sec=@DH, 100ths=@DL)\",\n 0x2E: \"set verify flag @AL\",\n 0x2F: \"get disk transfer area (DTA=ES:BX)\", // DOS 2.00+\n 0x30: \"get DOS version (AL=major, AH=minor)\",\n 0x31: \"terminate and stay resident\",\n 0x32: \"get drive parameter block (DPB=DS:BX) for drive @DL\",\n 0x33: \"extended break check\",\n 0x34: \"get address (ES:BX) of InDOS flag\",\n 0x35: \"get address (ES:BX) of interrupt vector @AL\",\n 0x36: \"get free disk space of drive @DL\",\n 0x37: \"get(0)/set(1) switch character @DL (@AL)\",\n 0x38: \"get country-specific information\",\n 0x39: \"create subdirectory $@DS:@DX\",\n 0x3A: \"remove subdirectory $@DS:@DX\",\n 0x3B: \"set current directory $@DS:@DX\",\n 0x3C: \"create or truncate file $@DS:@DX with attributes @CX\",\n 0x3D: \"open file $@DS:@DX with mode @AL\",\n 0x3E: \"close file @BX\",\n 0x3F: \"read @CX bytes from file @BX into buffer @DS:@DX\",\n 0x40: \"write @CX bytes to file @BX from buffer @DS:@DX\",\n 0x41: \"delete file $@DS:@DX\",\n 0x42: \"set position @CX:@DX of file @BX relative to @AL\",\n 0x43: \"get(0)/set(1) attributes @CX of file $@DS:@DX (@AL)\",\n 0x44: \"get device information (IOCTL)\",\n 0x45: \"duplicate file handle @BX\",\n 0x46: \"force file handle @CX to duplicate file handle @BX\",\n 0x47: \"get current directory (DS:SI) for drive @DL\",\n 0x48: \"allocate memory segment with @BX paragraphs\",\n 0x49: \"free memory segment @ES\",\n 0x4A: \"resize memory segment @ES to @BX paragraphs\",\n 0x4B: \"load program $@DS:@DX using parameter block @ES:@BX\",\n 0x4C: \"terminate with return code @AL\",\n 0x4D: \"get return code (AL)\",\n 0x4E: \"find first matching file $@DS:@DX with attributes @CX\",\n 0x4F: \"find next matching file\",\n 0x50: \"set current PSP @BX\",\n 0x51: \"get current PSP (bx)\",\n 0x52: \"get system variables (ES:BX)\",\n 0x53: \"translate BPB @DS:@SI to DPB (ES:BP)\",\n 0x54: \"get verify flag (AL)\",\n 0x55: \"create child PSP at segment @DX\",\n 0x56: \"rename file $@DS:@DX to $@ES:@DI\",\n 0x57: \"get(0)/set(1) file @BX date @DX and time @CX (@AL)\",\n 0x58: \"get(0)/set(1) memory allocation strategy (@AL)\", // DOS 2.11+\n 0x59: \"get extended error information\", // DOS 3.00+\n 0x5A: \"create temporary file $@DS:@DX with attributes @CX\", // DOS 3.00+\n 0x5B: \"create file $@DS:@DX with attributes @CX\", // DOS 3.00+ (doesn't truncate existing files like 0x3C)\n 0x5C: \"lock(0)/unlock(1) file @BX region @CX:@DX length @SI:@DI (@AL)\", // DOS 3.00+\n 0x5D: \"critical error information (@AL)\", // DOS 3.00+ (undocumented)\n 0x60: \"get fully-qualified filename from $@DS:@SI\", // DOS 3.00+ (undocumented)\n 0x63: \"get lead byte table (@AL)\", // DOS 2.25 and 3.20+\n 0x6C: \"extended open file $@DS:@SI\" // DOS 4.00+\n };\n \n Interrupts.FUNCS[Interrupts.WINDBG.VECTOR] = {\n 0x004F: \"check debugger loaded\" // WINDBG.IS_LOADED returns WINDBG.LOADED (0xF386) if debugger loaded\n };\n}\n\n/*\n * DOS function reference (from https://sites.google.com/site/pcdosretro/dosfuncs)\n *\n * INT 20 Program terminate (1.0+)\n * Entry: CS=PSP\n * Exit: Does not return to caller\n *\n * INT 21 Execute DOS function\n * 00 Program terminate (1.0+)\n * Entry: CS=PSP\n * Exit: Does not return to caller\n * 01 Character input (1.0+)\n * Entry: None\n * Exit: AL=character\n * 02 Character output (1.0+)\n * Entry: DL=character\n * Exit: None\n * 03 Auxiliary input (1.0+)\n * Entry: None\n * Exit: AL=character\n * 04 Auxiliary output (1.0+)\n * Entry: DL=character\n * Exit: None\n * 05 Printer output (1.0+)\n * Entry: DL=character\n * Exit: None\n * 06 Direct console I/O (1.0+)\n * Entry: DL=FF for console input\n * DL=character for console output\n * Exit: ZF=0 if a character is ready, AL=character\n * ZF=1 if no character is ready\n * 07 Direct console input without echo (1.0+)\n * Entry: None\n * Exit: AL=character\n * 08 Console input without echo (1.0+)\n * Entry: None\n * Exit: AL=character\n * 09 Display string (1.0+)\n * Entry: DS:DX->string ending with $\n * Exit: None\n * 0A Buffered keyboard input (1.0+)\n * Entry: DS:DX->input buffer (first byte of buffer=maximum input length)\n * Exit: second byte of buffer=actual input length\n * 0B Get input status (1.0+)\n * Entry: None\n * Exit: AL=00 no character available\n * AL=FF character available\n * 0C Flush input buffer and input (1.0+)\n * Entry: AL=function number (01,06,07,08,or 0A otherwise flush only)\n * DS:DX->input buffer if function 0A\n * Exit: AL=character unless function 0A\n * 0D Disk reset (1.0+)\n * Entry: None\n * Exit: None\n * 0E Set default drive (1.0+)\n * Entry: DL=drive code (0=A)\n * Exit: AL=number of logical drives\n * 0F Open file (1.0+)\n * Entry: DS:DX->unopened FCB\n * Exit: AL=00 file opened\n * AL=FF file not found\n * 10 Close file (1.0+)\n * Entry: DS:DX->opened FCB\n * Exit: AL=00 file closed\n * AL=FF file not found\n * 11 Find first file (1.0+)\n * Entry: DS:DX->unopened FCB\n * Exit: AL=00 matching filename found\n * buffer at DTA receives an unopened FCB and directory entry\n * original FCB contents:\n * FCB search drive code (1=A)\n * FCB+1 specified filespec\n * FCB+12 search attribute byte\n * FCB+13 directory entry offset\n * FCB+15 directory cluster (0=root)\n * FCB+17 unused\n * FCB+21 actual drive code (1=A)\n * AL=FF matching filename not found\n * Note: The file's directory entry is returned after the FCB drive code.\n * If a character device is found then the directory attribute byte\n * is set to 40h.\n * 12 Find next file (1.0+)\n * Entry: DS:DX->unopened FCB from previous 11 or 12 call\n * Exit: AL=00 matching filename found\n * buffer at DTA receives an unopened FCB and directory entry\n * AL=FF matching filename not found\n * Note: The file's directory entry is returned after the FCB drive code.\n * 13 Delete file (1.0+)\n * Entry: DS:DX->unopened FCB\n * Exit: AL=00 file deleted\n * AL=FF matching filename not found or files are read-only\n * 14 Sequential read (1.0+)\n * Entry: DS:DX->opened FCB\n * Exit: AL=00 file was read\n * AL=01 EOF (no data read)\n * AL=02 segment wrap\n * AL=03 EOF (partial read)\n * 15 Sequential write (1.0+)\n * Entry: DS:DX->opened FCB\n * Exit: AL=00 file was written\n * AL=01 disk full\n * AL=02 segment wrap\n * 16 Create or truncate file (1.0+)\n * Entry: DS:DX->unopened FCB\n * Exit: AL=00 file created\n * AL=FF directory full\n * 17 Rename file (1.0+)\n * Entry: DS:DX->rename FCB (FCB+11h->new filename)\n * Exit: AL=00 file renamed\n * AL=FF no matching files found or new filename already exists\n * 18 Reserved\n * 19 Get default drive (1.0+)\n * Entry: None\n * Exit: AL=drive code (0=A)\n * 1A Set disk transfer address (1.0+)\n * Entry: DS:DX=new DTA\n * Exit: None\n * 1B Get allocation info for default drive (1.0+)\n * Entry: None\n * Exit: AL=sectors per cluster\n * CX=bytes per sector\n * DX=clusters per drive\n * DS:BX->media descriptor byte\n * AL=FF invalid drive\n * 1C Get allocation info for specified drive (1.1+)\n * Entry: DL=drive code (0=default)\n * Exit: Same as function 1B\n * 1D Reserved\n * 1E Reserved\n * 1F Get disk parameter block for default drive (1.1+)\n * Entry: None\n * Exit: AL=00 drive valid\n * DS:BX->disk parameter block\n * 0 drive code (0=A) 13 maximum cluster number\n * 1 unit code 15 sectors per FAT\n * 2 bytes per sector 17 first directory sector\n * 4 sectors per cluster-1 19 pointer to device driver\n * 5 cluster shift factor 23 media descriptor byte\n * 6 first FAT sector 24 access flag (0=accessed)\n * 8 number of FATs 25 pointer to next DPB\n * 9 number of directory entries 29 last cluster allocated\n * 11 first data sector 31 free clusters (-1=unknown)\n * AL=FF drive invalid\n * Note: (3.x) The sectors per FAT field is one byte and all following\n * fields are moved back one byte.\n * 20 Reserved\n * 21 Random read (1.0+)\n * Entry: DS:DX->opened FCB\n * Exit: AL=00 file was read\n * AL=01 EOF (no data read)\n * AL=02 segment wrap\n * AL=03 EOF (partial read)\n * 22 Random write (1.0+)\n * Entry: DS:DX->opened FCB\n * Exit: AL=00 file was written\n * AL=01 disk full\n * AL=02 segment wrap\n * 23 Get file size in records (1.0+)\n * Entry: DS:DX->unopened FCB\n * Exit: AL=00 random record field is set by dividing the file size by the\n * specified record size\n * AL=FF file not found\n * 24 Set random record number (1.0+)\n * Entry: DS:DX->opened FCB\n * Exit: random record field is set based on record size, current record,\n * and current block\n * 25 Set interrupt vector (1.0+)\n * Entry: DS:DX=new address\n * AL=interrupt number\n * Exit: None\n * 26 Create PSP (1.0+)\n * Entry: CS=PSP\n * DX=segment for new PSP\n * Exit: None\n * 27 Random block read (1.0+)\n * Entry: DS:DX->opened FCB\n * CX=number of records to read\n * Exit: AL=00 file was read\n * AL=01 EOF (no data read)\n * AL=02 segment wrap\n * AL=03 EOF (partial read)\n * CX=actual number of records read\n * 28 Random block write (1.0+)\n * Entry: DS:DX->opened FCB\n * CX=number of records to write\n * Exit: AL=00 file was written\n * AL=01 disk full\n * AL=02 segment wrap\n * CX=actual number of records written\n * 29 Parse filename (1.0+)\n * Entry: DS:SI->string to parse\n * ES:DI->buffer for unopened FCB\n * AL=flags\n * Bit 0 1=ignore leading separators\n * 1 1=modify FCB drive code byte only if a drive is specified\n * 2 1=modify FCB filename only if a filename is specified\n * 3 1=modify FCB extension only if an extension is specified\n * Exit: DS:SI->first character after parsed filename\n * AL=00 no wildcard characters in string\n * AL=01 wildcard characters in string\n * AL=FF invalid drive\n * 2A Get date (1.0+)\n * Entry: None\n * Exit: AL=weekday (0=Sunday)\n * CX=year\n * DH=month\n * DL=day\n * 2B Set date (1.0+)\n * Entry: CX=year\n * DH=month\n * DL=day\n * Exit: AL=00 date set\n * AL=FF invalid date\n * 2C Get time (1.0+)\n * Entry: None\n * Exit: CH=hours\n * CL=minutes\n * DH=seconds\n * DL=hundredths\n * 2D Set time (1.0+)\n * Entry: CH=hours\n * CL=minutes\n * DH=seconds\n * DL=hundredths\n * Exit: AL=00 time set\n * AL=FF invalid time\n * 2E Set verify flag (1.1+)\n * Entry: AL=verify flag (0=off,1=on)\n * Exit: None\n * 2F Get disk transfer address (2.0+)\n * Entry: None\n * Exit: ES:BX=DTA\n * 30 Get DOS version (2.0+)\n * Entry: AL=0 return OEM number (5.0+)\n * AL=1 return version flag (5.0+)\n * Exit: AL=major version number\n * AH=minor version number\n * BH=OEM number or version flag (00=RAM,08=ROM)\n * BL:CX=24-bit serial number or 0\n * 31 Terminate and stay resident (2.0+)\n * Entry: AL=return code\n * DX=memory size in paragraphs (minimum 6)\n * Exit: Does not return to caller\n * 32 Get disk parameter block for specified drive (2.0+)\n * Entry: DL=drive code (0=default)\n * Exit: Same as function 1F\n * 33 Get or set Ctrl-Break (2.0+)\n * Entry: AL=0 get break\n * AL=1 set break\n * AL=2 swap break (*) (3.1+)\n * AL=5 get boot drive (4.0+)\n * AL=6 get DOS version (5.0+)\n * DL=break flag if set or swap (0=off,1=on)\n * Exit: if function 00 or 02:\n * DL=break flag\n * if function 05:\n * DL=boot drive code (1=A)\n * if function 06:\n * BL=major version\n * BH=minor version\n * DL=revision (0=A)\n * DH=version flag (00=low,08=ROM,10=HMA)\n * 34 Get InDOS flag pointer (2.0+)\n * Entry: None\n * Exit: ES:BX->InDOS flag\n * Note: The DOS critical error flag immediately precedes this byte.\n * 35 Get interrupt vector (2.0+)\n * Entry: AL=interrupt number\n * Exit: ES:BX=interrupt address\n * 36 Get free disk space (2.0+)\n * Entry: DL=drive code (0=default)\n * Exit: AX=sectors per cluster\n * BX=free clusters\n * CX=bytes per sector\n * DX=clusters per drive\n * AX=FFFF if drive invalid\n * 37 Get or set switch character (*) (2.0+)\n * Entry: AL=0 get switch character\n * AL=1 set switch character\n * DL=switch character if set\n * Exit: DL=switch character if get\n * Note: (5.0+) Function 3701 has been disabled.\n * 38 Get or set country info (2.0+)\n * Entry: AL=country code (0=default)\n * BX=country code if AL=FF (3.0+)\n * DX=FFFF if set request (2.11+)\n * DS:DX->buffer if get request\n * Exit: CF=0 BX=country code if get request (3.0+)\n * buffer format:\n * 0 date format (0=USA,1=Europe,2=Japan)\n * 2 currency symbol string\n * 7 thousands separator\n * 9 decimal separator\n * 11 date separator\n * 13 time separator\n * 15 currency format\n * 0 symbol before amount, no space between\n * 1 symbol after amount, no space between\n * 2 symbol before amount, 1 space between\n * 3 symbol after amount, 1 space between\n * 4 symbol replaces decimal separator\n * 16 digits after decimal in currency\n * 17 time format (0=12-hour,1=24-hour)\n * 18 case map call address\n * 22 data list separator\n * 24 reserved (10 bytes)\n * CF=1 AX=error code\n * 39 Create directory (2.0+)\n * Entry: DS:DX->directory name\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 3A Remove directory (2.0+)\n * Entry: DS:DX->directory name\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 3B Change current directory (2.0+)\n * Entry: DS:DX->directory name\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 3C Create or truncate file (2.0+)\n * Entry: DS:DX->filename\n * CX=file attributes\n * Exit: CF=0 AX=file handle\n * CF=1 AX=error code\n * 3D Open file (2.0+)\n * Entry: DS:DX->filename\n * AL=open mode\n * Bit 0-2 access mode\n * 000=read\n * 001=write\n * 010=read/write\n * 4-6 sharing mode (3.0+)\n * 000=compatibility\n * 001=deny read/write access\n * 010=deny write access\n * 011=deny read access\n * 100=deny none access\n * 7 inheritance flag\n * 0=file inherited by EXECed programs\n * 1=file not inherited by EXECed programs\n * Exit: CF=0 AX=file handle\n * CF=1 AX=error code\n * 3E Close file (2.0+)\n * Entry: BX=file handle\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 3F Read file or device (2.0+)\n * Entry: BX=file handle\n * CX=bytes to read\n * DS:DX->input buffer\n * Exit: CF=0 AX=number of bytes read (0=EOF)\n * CF=1 AX=error code\n * 40 Write file or device (2.0+)\n * Entry: BX=file handle\n * CX=bytes to write (0=truncate file)\n * DS:DX->output buffer\n * Exit: CF=0 AX=number of bytes written (0=disk full)\n * CF=1 AX=error code\n * 41 Delete file (2.0+)\n * Entry: DS:DX->filename\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 42 Move file pointer (2.0+)\n * Entry: AL=code (0=absolute,1=relative,2=relative to EOF)\n * BX=file handle\n * CX:DX=offset\n * Exit: CF=0 DX:AX=new pointer\n * CF=1 AX=error code\n * 43 Get or set file attributes (2.0+)\n * Entry: AL=0 get attributes\n * AL=1 set attributes\n * CX=file attributes if set\n * Bit 0 1=read-only\n * 1 1=hidden\n * 2 1=system\n * 4 1=directory (get only)\n * 5 1=archive\n * DS:DX->filename\n * Exit: CF=0 CX=file attributes if get\n * CF=1 AX=error code\n * 44 I/O control for devices (2.0+)\n * Notes: 1) Functions 02-05 work only if bit 14 of the device driver\n * attribute word is set.\n * 2) Function 08 works only if bit 11 of the device driver\n * attribute word is set.\n * 3) Functions 0C-0F work only if bit 6 of the device driver\n * attribute word is set.\n * 4) Functions 10-11 work only if bit 7 of the device driver\n * attribute word is set.\n * 00 Get device attributes (2.0+)\n * Entry: BX=file handle\n * Exit: CF=0 DX=device attributes\n * Character devices:\n * Bit 0 1=console input\n * 1 1=console output\n * 2 1=NUL device\n * 3 1=CLOCK device\n * 4 1=INT 29 output (CON)\n * 5 0=ASCII,1=binary\n * 6 0=EOF on input\n * 7 1=character device\n * 11 1=open/close supported\n * 13 1=output until busy supported\n * 14 1=IOCTL supported\n * Block devices:\n * Bit 0-5 drive code (0=A)\n * 6 0=file has been written\n * 7 0=block device\n * CF=1 AX=error code\n * 01 Set device attributes (2.0+)\n * Entry: BX=file handle (character devices only)\n * DX=device attributes (DH must be 0)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 02 Read from character device (2.0+)\n * 03 Write to character device (2.0+)\n * Entry: BX=file handle\n * CX=number of bytes\n * DS:DX->buffer\n * Exit: CF=0 AX=number of bytes transferred\n * CF=1 AX=error code\n * 04 Read from block device (2.0+)\n * 05 Write to block device (2.0+)\n * Entry: BL=drive code (0=default)\n * CX=number of bytes\n * DS:DX->buffer\n * Exit: CF=0 AX=number of bytes transferred\n * CF=1 AX=error code\n * 06 Get input status (2.0+)\n * 07 Get output status (2.0+)\n * Entry: BX=file handle\n * Exit: CF=0 AL=status (00=not ready,FF=ready)\n * CF=1 AX=error code\n * 08 Removable media check (3.0+)\n * Entry: BL=drive code (0=default)\n * Exit: CF=0 AX=value (0=removable,1=fixed)\n * CF=1 AX=error code\n * 09 Local/remote drive check (3.0+)\n * Entry: BL=drive code (0=default)\n * Exit: CF=0 DX=device attributes\n * Bit 1 1=32-bit sectors supported\n * 6 1=generic IOCTL calls supported\n * 7 1=query IOCTL call supported\n * 9 1=shared drive; direct I/O not allowed\n * 11 1=removable media call supported\n * 12 1=remote drive\n * 13 1=media descriptor in FAT required\n * 14 1=IOCTL calls supported\n * 15 1=SUBSTed\n * CF=1 AX=error code\n * 0A Local/remote handle check (3.0+)\n * Entry: BX=file handle\n * Exit: CF=0 DX=device attributes from SFT\n * Character devices:\n * Bit 0 1=console input\n * 1 1=console output\n * 2 1=NUL device\n * 3 1=CLOCK device\n * 4 1=INT 29 output (CON)\n * 5 0=ASCII,1=binary\n * 6 0=EOF on input\n * 7 1=character device\n * 11 1=network spooler\n * 12 1=no inherit\n * 13 1=named pipe\n * 15 1=remote\n * Block devices:\n * Bit 0-5 drive code (0=A)\n * 6 0=file has been written\n * 7 0=block device\n * 12 1=no inherit\n * 14 1=date/time set\n * 15 1=remote\n * CF=1 AX=error code\n * 0B Change sharing retry count (3.0+)\n * Entry: CX=delay loop count\n * DX=retry count\n * Exit: None\n * 0C Generic IOCTL for handles (3.2+)\n * Entry: BX=file handle\n * CH=category code (01=AUX,03=CON,05=PRN)\n * CL=function code\n * 45 set printer retry count\n * 4A set code page (3.3+)\n * 4C prepare start (3.3+)\n * 4D prepare end (3.3+)\n * 5F set display info (4.0+)\n * 65 get printer retry count\n * 6A get code page (3.3+)\n * 6B get prepare list (3.3+)\n * 7F get display info (4.0+)\n * DS:DX->parameter block or retry count word\n * Exit: CF=0 None\n * CF=1 AX=error code\n * Get/set code page and prepare end parameter block format:\n * 0 length (2)\n * 2 code page\n * Prepare start parameter block format:\n * 0 flags (device specific)\n * 2 data length\n * 4 number of code pages\n * 6 code pages (-1=perform a refresh operation)\n * Get prepare list parameter block format:\n * 0 data length\n * 2 number of hardware code pages\n * 4 hardware code pages\n * n number of prepared code pages\n * n+2 prepared code pages\n * Display info parameter block format:\n * 0 info level (must be 0)\n * 1 reserved\n * 2 data length (14)\n * 4 flags\n * Bit 0 (0=blink,1=intensity)\n * 6 mode (1=text,2=graphics)\n * 7 reserved\n * 8 colors\n * 10 pixel columns\n * 12 pixel rows\n * 14 character columns\n * 16 character rows\n * 0D Generic IOCTL for drives (3.2+)\n * Entry: BL=drive code (0=default)\n * CH=category code (08=disk)\n * CL=function code\n * 40 set device parameters\n * 41 write track\n * 42 format track\n * 46 set media info (4.0+)\n * 47 set access flag (4.0+)\n * 60 get device parameters\n * 61 read track\n * 62 verify track\n * 66 get media info (4.0+)\n * 67 get access flag (4.0+)\n * 68 sense media type (5.0+)\n * DS:DX->parameter block\n * Exit: CF=0 None\n * CF=1 AX=error code\n * Get/set device parameter block format:\n * 0 flags (only bit 0 is used by get)\n * Bit 0 0=return default BPB/build new BPB\n * 1=return build BPB/use device BPB\n * 1 0=read all fields\n * 1=read track layout only\n * 2 0=sector sizes vary\n * 1=sector sizes equal\n * 1 drive type\n * 0=360K 5=fixed\n * 1=1.2M 6=tape\n * 2=720K 7=1.44M\n * 3=8\" single sided 8=read/write optical\n * 4=8\" double sided 9=2.88M\n * 2 attributes\n * Bit 0 1=non-removable\n * 1 1=changeline supported\n * 4 cylinders\n * 6 density (0=high,1=double)\n * 7 BIOS parameter block\n * 32 reserved\n * 38 track layout count\n * 40 track layout words (sector number,sector size)\n * Note: Track layout fields are used by set only.\n * Read/write parameter block format:\n * 0 reserved\n * 1 head\n * 3 cylinder\n * 5 sector\n * 7 number of sectors\n * 9 buffer address\n * Format/verify parameter block format:\n * 0 reserved\n * 1 head\n * 3 cylinder\n * Get/set media info parameter block format:\n * 0 info level (must be 0)\n * 2 volume serial number\n * 6 volume label\n * 17 8-byte file system type\n * Get/set access flag parameter block format:\n * 0 reserved\n * 1 access flag (0=disallow disk access,1=allow disk access)\n * Sense media type parameter block format:\n * 0 media type flag (0=other,1=default)\n * 1 media type (2=720K,7=1.44M,9=2.88M)\n * 0E Get logical drive map (3.2+)\n * 0F Set logical drive map (3.2+)\n * Entry: BL=logical drive code (0=default)\n * Exit: CF=0 AL=physical drive code (0=only 1 logical drive mapped)\n * CF=1 AX=error code\n * 10 Query IOCTL for handles (5.0+)\n * Entry: BX=file handle\n * CH=category code (01=AUX,03=CON,05=PRN)\n * CL=function code\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 11 Query IOCTL for drives (5.0+)\n * Entry: BL=drive code (0=default)\n * CH=category code (08=disk)\n * CL=function code\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 45 Duplicate handle (2.0+)\n * Entry: BX=file handle\n * Exit: CF=0 AX=new file handle\n * CF=1 AX=error code\n * 46 Redirect handle (2.0+)\n * Entry: BX=file handle\n * CX=file handle to redirect\n * Exit: CF=0 None\n * CF=1 AX=error code\n * Note: If the handle to redirect is opened then it is closed before\n * being redirected.\n * 47 Get current directory (2.0+)\n * Entry: DS:SI->64-byte buffer for pathname\n * DL=drive code (0=default)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 48 Allocate memory (2.0+)\n * Entry: BX=number of paragraphs to allocate\n * Exit: CF=0 AX=segment of allocated block\n * CF=1 AX=error code\n * BX=size of largest available block\n * 49 Release memory (2.0+)\n * Entry: ES=segment of block to release\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 4A Reallocate memory (2.0+)\n * Entry: BX=number of paragraphs to allocate\n * ES=segment of block to reallocate\n * Exit: CF=0 None\n * CF=1 AX=error code\n * BX=size of largest available block\n * 4B Execute program (2.0+)\n * Entry: AL=0 execute program\n * AL=1 load program\n * AL=3 load overlay\n * AL=5 enter exec state (5.0+)\n * DS:DX->filename or exec state parameter block\n * ES:BX->parameter block (unused by enter exec state)\n * if function 00 or 01:\n * 0 environment block segment or 0\n * 2 command tail pointer\n * 6 FCB1 pointer\n * 10 FCB2 pointer\n * if function 03:\n * 0 segment where file will be loaded\n * 2 relocation factor\n * if function 05:\n * 0 reserved\n * 2 flags (0=COM,1=EXE,2=overlay)\n * 4 program name pointer\n * 8 PSP\n * 10 program CS:IP\n * 14 doubleword program size\n * Exit: CF=0 BX and DX may be destroyed\n * parameter block if load only:\n * 14 SS:SP of loaded program\n * 18 CS:IP of loaded program\n * CF=1 AX=error code\n * Note: After calling function 4B01 the current PSP is set to that of\n * the loaded program. Before executing the program, DS and ES\n * should be set to the program's PSP and the INT 22 vector in the\n * program's PSP should be set to a valid return address.\n * 4C Terminate with return code (2.0+)\n * Entry: AL=return code\n * Exit: Does not return to caller\n * 4D Get program return code (2.0+)\n * Entry: None\n * Exit: AL=return code\n * AH=exit type (0=normal,1=Ctrl-C,2=critical error,3=TSR)\n * 4E Find first file (2.0+)\n * Entry: DS:DX->filespec\n * CX=file attributes\n * Exit: CF=0 DTA search drive code (1=A)\n * DTA+1 search filespec\n * DTA+12 search attribute byte\n * DTA+13 directory entry offset\n * DTA+15 directory cluster (0=root)\n * DTA+17 unused\n * DTA+21 attribute byte (40h=character device)\n * DTA+22 file time\n * DTA+24 file date\n * DTA+26 file size\n * DTA+30 filename\n * CF=1 AX=error code\n * 4F Find next file (2.0+)\n * Entry: Bytes 0-20 of buffer at DTA must be set from previous 4E or 4F call\n * Exit: Same as function 4E\n * 50 Set current PSP (2.0+)\n * Entry: BX=PSP segment\n * Exit: None\n * 51 Get current PSP (2.0+)\n * Entry: None\n * Exit: BX=PSP segment\n * 52 Get DOS internal pointers (*) (2.0+)\n * Entry: None\n * Exit: ES:BX->DOS internal pointers\n * -02h memory chain anchor\n * +00h pointer to disk parameter blocks\n * +04h pointer to system file tables\n * +08h pointer to CLOCK$ device header\n * +0Ch pointer to CON device header\n * +10h disk buffer size\n * +12h pointer to disk buffer chain (3.x)\n * pointer to disk buffer control block (4.0+)\n * +16h pointer to current directory structures\n * +1Ah pointer to FCB system file tables\n * +1Eh FCB keep count\n * +20h number of actual drives\n * +21h number of logical drives\n * +22h NUL device header\n * 53 Create disk parameter block (*) (2.0+)\n * Entry: DS:SI->BIOS parameter block\n * 0 bytes per sector\n * 2 sectors per cluster\n * 3 number of reserved sectors\n * 5 number of FATs\n * 6 number of root directory entries\n * 8 total number of sectors\n * 10 media descriptor byte\n * 11 sectors per FAT\n * 13 sectors per track\n * 15 number of heads\n * 17 number of hidden sectors\n * 21 32-bit number of sectors if word at 8=0\n * ES:BP->buffer for disk parameter block\n * Exit: None\n * 54 Get verify flag (2.0+)\n * Entry: None\n * Exit: AL=verify flag (0=off,1=on)\n * 55 Create program PSP (*) (2.0+)\n * Entry: DX=segment for new PSP\n * SI=new end of allocation\n * Exit: None\n * Note: After calling function 55 the current PSP is set to the new PSP.\n * 56 Rename file (2.0+)\n * Entry: DS:DX->old filename\n * ES:DI->new filename\n * Exit: CF=0 None\n * CF=1 AX=error code\n * Note: This function can also rename a directory or move a file from\n * one directory to another.\n * 57 Get or set file date and time (2.0+)\n * Entry: AL=0 get date and time\n * AL=1 set date and time\n * BX=file handle\n * CX=time if set\n * Bits 0-4 seconds/2 (0-29)\n * 5-10 minutes (0-59)\n * 11-15 hours (0-23)\n * DX=date if set\n * Bits 0-4 day (1-31)\n * 5-8 month (1-12)\n * 9-15 year-1980\n * Exit: CF=0 CX=time if get\n * DX=date if get\n * CF=1 AX=error code\n * 58 Get or set allocation strategy (2.11+)\n * Entry: AL=0 get strategy\n * AL=1 set strategy\n * AL=2 get UMB link state (5.0+)\n * AL=3 set UMB link state (5.0+)\n * BX=strategy code or UMB link state (0=unlink,1=link)\n * 00=first fit\n * 01=best fit\n * 02=last fit\n * 40=first fit, high only (5.0+)\n * 41=best fit, high only (5.0+)\n * 42=last fit, high only (5.0+)\n * 80=first fit, high first (5.0+)\n * 81=best fit, high first (5.0+)\n * 82=last fit, high first (5.0+)\n * Exit: CF=0 AX=strategy code or UMB link state if get\n * CF=1 AX=error code\n * 59 Get extended error info (3.0+)\n * Entry: None\n * Exit: AX=extended error code\n * BH=error class\n * BL=suggested action\n * CH=locus\n * ES:DI->volume label for invalid disk change error or 0\n * 5A Create unique file (3.0+)\n * Entry: DS:DX->pathname ending with \\\n * CX=file attributes\n * Exit: CF=0 AX=file handle (filename is appended to pathname)\n * CF=1 AX=error code\n * 5B Create new file (3.0+)\n * Entry: DS:DX->filename\n * CX=file attributes\n * Exit: CF=0 AX=file handle\n * CF=1 AX=error code\n * 5C Lock or unlock file (3.0+)\n * Entry: AL=0 lock\n * AL=1 unlock\n * BX=file handle\n * CX:DX=region offset\n * SI:DI=region length\n * Exit: CF=0 None\n * CF=1 AX=error code\n * Note: File sharing (SHARE.EXE) must be loaded to use this function.\n * 5D File sharing functions (*) (3.0+)\n * Notes: 1) Some functions use a parameter block with the following format:\n * AX,BX,CX,DX,SI,DI,DS,ES,reserved,machine #,process (PSP)\n * 2) Functions 02-05 work only if file sharing (SHARE.EXE) is loaded.\n * 3) Functions 07-09 work only if the redirector (REDIR.EXE) is loaded.\n * 00 Server DOS call (*) (3.0+)\n * Entry: DS:DX->parameter block (AX,BX,CX,DX,SI,DI,DS,ES,machine #,process)\n * Exit: Depends on called function\n * 01 Commit all local files (*) (3.0+)\n * Entry: None\n * Exit: None\n * 02 Close all occurrences of file (*) (3.0+)\n * Entry: DS:DX->parameter block (DS:DX->qualified filespec)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 03 Close all files for machine (*) (3.0+)\n * Entry: DS:DX->parameter block (machine #)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 04 Close all files for machine and process (*) (3.0+)\n * Entry: DS:DX->parameter block (machine #,process)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 05 Get shared file info (*) (3.0+)\n * Entry: DS:DX->parameter block (BX=share file table index,CX=SFT index)\n * Exit: CF=0 AX=device info from SFT\n * BX=machine #\n * CX=lock count\n * ES:DI->qualified filename\n * CF=1 AX=error code\n * 06 Get DOS swappable data area (*) (3.0+)\n * Entry: None\n * Exit: DS:SI->DOS swappable data area\n * CX=DOS swappable data area length\n * DX=DOS critical data area length\n * Note: The first byte of the data area is the critical error flag.\n * 07 Get print stream state (*) (3.1+)\n * Entry: None\n * Exit: DL=state (0=truncate off,1=truncate on)\n * 08 Set print stream state (*) (3.1+)\n * Entry DL=state (0=truncate off,1=truncate on)\n * Exit: None\n * 09 Truncate print stream (*) (3.1+)\n * Entry None\n * Exit: None\n * 0A Set extended error info (3.1+)\n * Entry: DS:DX->parameter block (see function 59 for affected registers)\n * Exit: None\n * 5E Network functions (3.0+)\n * Note: Functions 02-05 work only if the redirector (REDIR.EXE) is loaded.\n * 00 Get machine name (3.0+)\n * Entry: DS:DX->buffer for machine name\n * Exit: CH=validity flag (0=invalid,1=valid)\n * CL=netbios number\n * 01 Set machine name (*) (3.0+)\n * Entry: DS:DX->machine name\n * CH=validity flag (0=invalid,1=valid)\n * CL=netbios number\n * Exit: None\n * 02 Set printer string (3.1+)\n * Entry: DS:SI->printer setup string\n * BX=redirection list index\n * CX=printer setup string length\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 03 Get printer string (3.1+)\n * Entry: ES:DI->buffer for printer setup string\n * BX=redirection list index\n * Exit: CF=0 CX=printer setup string length\n * CF=1 AX=error code\n * 04 Set print mode (*) (3.1+)\n * Entry: BX=redirection list index\n * DX=print mode (0=text,1=binary)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 05 Get print mode (*) (3.1+)\n * Entry: BX=redirection list index\n * Exit: CF=0 DX=print mode (0=text,1=binary)\n * CF=1 AX=error code\n * 5F Network redirection functions (3.1+)\n * Notes: 1) Functions 00-05 work only if the redirector (REDIR.EXE) is loaded.\n * 2) Functions 07-08 work only on builtin drives.\n * 00 Get redirection mode (*) (3.1+)\n * Entry: BL=device type (3=printer,4=disk)\n * Exit: CF=0 BH=redirection mode (0=off,1=on)\n * CF=1 AX=error code\n * 01 Set redirection mode (*) (3.1+)\n * Entry: BL=device type (3=printer,4=disk)\n * BH=redirection mode (0=off,1=on)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 02 Get redirection list entry (3.1+)\n * Entry: DS:SI->16-byte buffer for local device name\n * ES:DI->128-byte buffer for remote device name\n * BX=redirection list index\n * Exit: CF=0 BH=status (0=valid,1=invalid)\n * BL=device type (3=printer,4=disk)\n * CX=user word\n * CF=1 AX=error code\n * 03 Set redirection list entry (3.1+)\n * Entry: DS:SI->local device name\n * ES:DI->remote device name\n * BL=device type (3=printer,4=disk)\n * CX=user word\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 04 Cancel redirection list entry (3.1+)\n * Entry: DS:SI->local device name\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 05 Get redirection list entry extended (*) (4.0+)\n * Entry: DS:SI->16-byte buffer for local device name\n * ES:DI->128-byte buffer for remote device name\n * BX=redirection list index\n * Exit: CF=0 BH=status (0=valid,1=invalid)\n * BL=device type (3=printer,4=disk)\n * CX=user word\n * BP=netbios session number\n * CF=1 AX=error code\n * 07 Enable drive (*) (4.0+)\n * Entry: DL=drive code (0=default)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 08 Disable drive (*) (4.0+)\n * Entry: DL=drive code (0=default)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 60 Qualify filename (*) (3.0+)\n * Entry: DS:SI->filespec\n * ES:DI->buffer for qualified filespec\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 61 Reserved\n * 62 Get current PSP (3.0+)\n * Entry: None\n * Exit: BX=PSP segment\n * 63 Get DBCS lead byte table pointer (*) (3.0+)\n * Entry: AL must be 0\n * Exit: DS:SI->DBCS lead byte table\n * 64 Set wait for external event flag (*) (3.2+)\n * Entry: AL=flag (0=enable,>0=disable)\n * Exit: None\n * Note: This function affects the PC Convertible only.\n * If enabled and the default console driver is being used then\n * INT 15 function 41 is issued while waiting for console input\n * during functions 01,08,0A,and 3F.\n * 65 Get extended country info (3.3+)\n * Entry: AL=01 get extended country info\n * 02 get country uppercase table\n * 03 get country lowercase table (reserved until 6.2)\n * 04 get country filename uppercase table\n * 05 get country filename character table\n * 06 get country collating table\n * 07 get DBCS vector table (4.0+)\n * 20 uppercase character (4.0+)\n * 21 uppercase string (4.0+)\n * 22 uppercase ASCIIZ string (4.0+)\n * 23 yes/no check (*) (4.0+)\n * A0 uppercase filename character (*) (4.0+)\n * A1 uppercase filename string (*) (4.0+)\n * A2 uppercase filename ASCIIZ string (*) (4.0+)\n * A3 yes/no check (*) (4.0+)\n * if function 01-07:\n * BX=code page (-1=active code page)\n * CX=length to return (must be at least 5)\n * DX=country code (-1=default)\n * ES:DI->return buffer\n * if function 20,23,A0,A3:\n * DL=character\n * if function 21,A1:\n * DS:DX->string\n * CX=string length\n * if function 22,A2:\n * DS:DX->string\n * Exit: CF=0 CX=data length if function 01-07\n * DL=character if function 20\n * AX=code if function 23,A3 (0=no,1=yes,2=neither)\n * CF=1 AX=error code\n * buffer format if function 01:\n * 0 info ID\n * 1 length\n * 3 country code\n * 5 code page\n * 7 country info (same format as function 38)\n * buffer format if function 02-07:\n * 0 info ID\n * 1 pointer to requested table (word length followed by data)\n * 66 Get or set code page (3.3+)\n * Entry: AL=1 get code page\n * AL=2 set code page\n * BX=active code page if set\n * Exit: CF=0 BX=active code page if get\n * DX=default code page if get\n * CF=1 AX=error code\n * 67 Set handle count (3.3+)\n * Entry: BX=handle count\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 68 Commit file (3.3+)\n * Entry: BX=file handle\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 69 Get or set media info (*) (4.0+)\n * Entry: AL=0 get media info\n * AL=1 set media info\n * BL=drive code (0=default)\n * DS:DX->media info\n * Exit: CF=0 None\n * CF=1 AX=error code\n * Media info format:\n * 0 info level (must be 0)\n * 2 volume serial number\n * 6 volume label\n * 17 8-byte file system type\n * 6A Commit file (*) (4.0+)\n * Entry: Same as function 68\n * Exit: Same as function 68\n * 6B Reserved\n * 6C Extended open/create file (4.0+)\n * Entry: DS:SI->filename\n * BX=open mode\n * Bit 0-2 access mode\n * 000=read\n * 001=write\n * 010=read/write\n * 4-6 sharing mode\n * 000=compatibility\n * 001=deny read/write access\n * 010=deny write access\n * 011=deny read access\n * 100=deny none access\n * 7 inheritance flag\n * 0=file inherited by EXECed programs\n * 1=file not inherited by EXECed programs\n * 13 critical error handling\n * 0=execute INT 24\n * 1=return error code\n * 14 buffering\n * 0=buffer writes\n * 1=don't buffer writes\n * CX=file attributes\n * DX=open flags\n * Bit 0-3 0000=fail if exists\n * 0001=open if exists\n * 0010=truncate if exists\n * 4-7 0000=fail if doesn't exist\n * 0001=create if doesn't exist\n * Exit: CF=0 AX=file handle\n * CX=action code (1=file opened,2=file created,3=file truncated)\n * CF=1 AX=error code\n *\n * INT 22 Terminate address (1.0+)\n * This is the address that DOS returns to after program termination.\n * It is set during execute program (function 4B) processing.\n *\n * INT 23 Ctrl-Break handler address (1.0+)\n * This routine is entered when Ctrl-Break is detected by DOS.\n * On entry the registers are set to the values they had at the start\n * of the interrupted function call. Control may be returned via\n * IRET or FAR RET, if FAR RET is used and the carry flag is set\n * then the program is aborted otherwise the function is restarted.\n * Note: Any DOS function may be issued from an INT 23 handler.\n *\n * INT 24 Critical error handler address (1.0+)\n * Entry: AH=error indicator\n * Bit 0 0=read error\n * 1=write error\n * 1-2 disk area\n * 00=DOS area\n * 01=FAT\n * 10=directory\n * 11=data area\n * 3 1=fail allowed\n * 4 1=retry allowed\n * 5 1=ignore allowed\n * 7 0=block device error\n * 1=character device error\n * AL=drive code (0=A)\n * DI=error code (lower half of DI)\n * 00=write-protect error 07=unknown media type\n * 01=unknown unit 08=sector not found\n * 02=drive not ready 09=printer out of paper\n * 03=unknown command 0A=write fault\n * 04=data error (CRC) 0B=read fault\n * 05=bad request structure length 0C=general failure\n * 06=seek error 0F=invalid disk change\n * BP:SI=pointer to device driver header\n * Exit: Control may be returned to DOS via IRET with an action code in AL\n * 0=ignore error (fail if ignore is unallowed)\n * 1=retry function (fail if retry is unallowed)\n * 2=abort program\n * 3=fail system call (abort if fail is unallowed)\n * Control may be returned directly to the program by removing the\n * INT 24 registers (IP,CS,flags) from the stack, restoring the\n * program's registers (AX,BX,CX,DX,SI,DI,BP,DS,ES) and issuing\n * an IRET. This will leave DOS in an unstable state because the\n * critical error flag is set until a DOS function other than 01-0C,\n * 33,50,51,59,62,or 64 is issued.\n * Note: Only DOS functions 01-0C,33,50,51,59,62,or 64 should be issued from\n * an INT 24 handler.\n *\n * INT 25 Absolute disk read (1.0+)\n * Entry: AL=drive number (0=A)\n * CX=number of sectors or -1 if >32M partition\n * DX=starting sector number\n * DS:BX->data buffer or parameter block\n * parameter block (3.31+)\n * 0 starting sector number\n * 4 number of sectors\n * 6 data buffer\n * Exit: CF=0 None\n * CF=1 AH=error code\n * 01=bad command\n * 02=bad address mark\n * 03=write-protect error\n * 04=sector not found\n * 08=DMA overrun\n * 10=data error (bad CRC)\n * 20=controller error\n * 40=seek error\n * 80=timed-out\n * AL=device error code (same as lower byte of DI for INT 24)\n * Notes: 1) The CPU flags are still on the stack after an INT 25 or INT 26.\n * 2) All registers except the segment registers and SP may be destroyed.\n *\n * INT 26 Absolute disk write (1.0+)\n * Entry: Same as INT 25\n * Exit: Same as INT 25\n *\n * INT 27 Terminate and stay resident (1.0+)\n * Entry: CS=PSP\n * DX=number of bytes to stay resident (minimum 96)\n * Exit: Does not return to caller\n *\n * INT 28 Idle handler (2.0+)\n * This interrupt is issued by DOS during functions 01-0C to indicate\n * that a TSR program may safely issue a non-character I/O DOS\n * function even though the InDOS flag is not zero.\n * DOS functions 01-0C should not be issued from a INT 28 handler\n * unless the critical error flag is set first.\n *\n * INT 29 Character output (2.0+)\n * Entry: AL=character\n * Exit: None\n * Note: This interrupt is called for character output if the console\n * device has bit 4 in the device attribute word set.\n *\n * INT 2A Network/critical section (*) (3.0+)\n * 00 Network installation check (3.0+)\n * Entry: None\n * Exit: AH=00 not installed\n * AH=FF installed\n * 01 Execute NETBIOS request with no error retry (*) (3.0+)\n * Entry: ES:BX->network control block\n * Exit: AH=0 no error\n * AH=1 AL=error code\n * 02 Set network printer parameters (*) (3.0+)\n * Entry: DS:SI->16-byte buffer for local device name\n * BX=characters per line (-1=use current)\n * CX=lines per inch (-1=use current)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 03 Check direct I/O (3.0+)\n * Entry: DS:SI->ASCIIZ disk name (d:)\n * Exit: CF=0 direct I/O allowed\n * CF=1 direct I/O not allowed\n * 04 Execute NETBIOS request (3.0+)\n * Entry: AL=error retry flag (0=retry,1=no retry)\n * ES:BX->network control block\n * Exit: AH=0 no error\n * AH=1 AL=error code\n * 05 Get network resource information (3.0+)\n * Entry: None\n * Exit: BX=available network name count\n * CX=available network control block count\n * DX=available network session count\n * 06 Network print stream control (3.0+)\n * Entry: AL=mode (1=concatenation,2=truncation,3=truncate stream)\n * Exit: CF=0 None\n * CF=1 AX=error code\n * 80 Begin critical section (*) (3.0+)\n * Entry: AL=critical section number\n * Exit: None\n * 81 End critical section (*) (3.0+)\n * Entry: AL=critical section number\n * Exit: None\n * 82 End all critical sections (*) (3.0+)\n * Entry: None\n * Exit: None\n * 84 Keyboard idle loop (*) (3.0+)\n * Entry: None\n * Exit: None\n *\n * INT 2E Execute command (*) (2.0+)\n * Entry: DS:SI->command string-1 followed by a carriage return\n * Exit: All registers except CS and IP are destroyed\n * Note: This function is not re-entrant and should not be issued from a\n * batch file.\n *\n * INT 2F Multiplex (3.0+)\n * Entry: AH=program identifier\n * AL=function code\n * Other registers depend on the function\n * Exit: Depends on the function\n *\n * Program identifier codes:\n * 01 Print queueing (PRINT) (3.0+)\n * 02 Network printer control (REDIR) (3.1+)\n * 05 Network error message lookup (REDIR) (3.0+)\n * 06 ASSIGN (3.1+)\n * 08 IBMBIO drive services (used by DRIVER.SYS) (3.2+)\n * 10 File sharing (SHARE) (3.0+)\n * 11 Redirector services (REDIR and MSCDEX) (3.0+)\n * 12 DOS internal services (used by REDIR and MSCDEX) (3.0+)\n * 13 Swap INT 13 vector (3.2+)\n * 14 NLS support (NLSFUNC) (3.3+)\n * 15 CD-ROM extensions (MSCDEX)\n * 16 Windows services\n * 17 Windows clipboard services\n * 1A ANSI.SYS (4.0+)\n * 43 XMS services (HIMEM.SYS)\n * 46 Windows support\n * 48 DOSKEY (5.0+)\n * 4A DOS services (HMA, RPL), SMARTDRV (5.0+)\n * 53 POWER (APM events broadcast) (5.02+)\n * 54 POWER (main API) (5.02+)\n * 55 COMMAND.COM (5.0+)\n * 56 INTERLNK (5.02+)\n * AC GRAPHICS (5.0+)\n * AD DISPLAY.SYS, KEYB (3.3+)\n * AE Installable command support (APPEND) (3.3+)\n * B0 GRAFTABL (3.3+)\n * B7 APPEND (3.2+)\n *\n * DOS extended error information:\n *\n * Extended error code: Error class:\n * 01 Invalid function number 01 Out of resource\n * 02 File not found 02 Temporary situation\n * 03 Path not found 03 Authorization error\n * 04 Too many open files 04 Internal DOS error\n * 05 Access denied 05 Hardware failure\n * 06 Invalid handle 06 System software failure\n * 07 Memory control blocks destroyed 07 Application program error\n * 08 Insufficient memory 08 Not found\n * 09 Invalid memory block address 09 Invalid format\n * 0A Invalid environment 0A File locked\n * 0B Invalid format 0B Media error\n * 0C Invalid access code 0C Already exists\n * 0D Invalid data 0D Unknown\n * 0E Reserved\n * 0F Invalid drive Suggested action:\n * 10 Attempt to remove current directory 01 Retry\n * 11 Not same device 02 Delay and retry\n * 12 No more files 03 Get corrected user input\n * 13 Write-protect error 04 Exit with cleanup\n * 14 Unknown unit 05 Exit without cleanup\n * 15 Drive not ready 06 Ignore error\n * 16 Unknown command 07 Retry after user intervention\n * 17 Data error (CRC)\n * 18 Bad request structure length Error locus:\n * 19 Seek error 01 Unknown\n * 1A Unknown medium type 02 Block device error\n * 1B Sector not found 03 Network error\n * 1C Printer out of paper 04 Character device error\n * 1D Write fault 05 Memory error\n * 1E Read fault\n * 1F General failure\n * 20 Sharing violation\n * 21 Lock violation\n * 22 Invalid disk change\n * 23 FCB unavailable\n * 24 Sharing buffer overflow\n * 25 Code page mismatch (4.0+)\n * 26 Out of input (4.0+)\n * 27 Insufficient disk space (4.0+)\n * 32 Function not supported\n * 41 Network access denied\n * 50 File exists\n * 51 Reserved\n * 52 Cannot make directory entry\n * 53 Fail on INT 24\n *\n * DOS table and structure reference (from https://sites.google.com/site/pcdosretro/dostables)\n *\n * Program Segment Prefix (100h bytes)\n * 00 INT 20\n * 02 End of allocation segment\n * 04 Reserved\n * 05 Far call to DOS\n * 0A Saved INT 22 vector\n * 0E Saved INT 23 vector\n * 12 Saved INT 24 vector (1.1+)\n * 16 Caller PSP segment (2.0+)\n * 18 File table (2.0+)\n * 2C Environment segment (2.0+)\n * 2E Stack pointer after last DOS call (2.0+)\n * 32 File table size (3.0+)\n * 34 Pointer to file table (3.0+)\n * 38 Pointer to next PSP (SHARE only) (3.0+)\n * 3C Reserved\n * 40 DOS version (4.0+)\n * 42 Reserved\n * 50 INT 21,RETF (2.0+)\n * 53 Reserved\n * 5C FCB 1\n * 6C FCB 2\n * 7C Unused\n * 80 Command tail\n *\n * File Control Block (25h bytes)\n * 00 Drive code (1=A)\n * 01 Filename\n * 09 Extension\n * 0C Current block number\n * 0E Record size\n * 10 File size\n * 14 Date\n * 16 Time\n * 18 Reserved\n * 20 Current record number\n * 21 Random record number\n *\n * Extended FCB (2Ch bytes)\n * 00 FF (Extended FCB indicator)\n * 01 Reserved\n * 06 Attribute byte\n * 07 Standard FCB\n *\n * Disk partition table entry (10h bytes)\n * 00 Status (00=non-bootable,80=bootable)\n * 01 Starting head\n * 02 Starting cylinder and sector (INT 13 format)\n * 04 Type (0=unknown,1=FAT12,4=FAT16,5=extended,6=BIGDOS)\n * 05 Ending head\n * 06 Ending cylinder and sector (INT 13 format)\n * 08 Starting absolute sector\n * 0C Number of sectors\n * Note: There are 4 entries starting at offset 1BE\n *\n * Disk boot sector (200h bytes)\n * 00 Jump to boot code\n * 03 OEM name\n * 0B Bytes per sector\n * 0D Sectors per cluster\n * 0E Number of reserved sectors\n * 10 Number of FATs\n * 11 Number of root directory entries\n * 13 Total number of sectors\n * 15 Media descriptor byte\n * F0 1.44M (2 sides,18 sectors/track,80 tracks)\n * 2.88M (2 sides,36 sectors/track,80 tracks)\n * F8 fixed disk\n * F9 720K (2 sides,9 sectors/track,80 tracks)\n * 1.2M (2 sides,15 sectors/track,80 tracks)\n * FC 180K (1 side,9 sectors/track,40 tracks)\n * FD 360K (2 sides,9 sectors/track,40 tracks)\n * FE 160K (1 side,8 sectors/track,40 tracks)\n * FF 320K (2 sides,8 sectors/track,40 tracks)\n * 16 Sectors per FAT\n * 18 Sectors per track\n * 1A Number of heads\n * 1C Number of hidden sectors\n * 20 32-bit number of sectors if word at 13=0 (3.31+)\n * 24 Drive number (4.0+)\n * 25 Reserved (4.0+)\n * 26 Extended boot record ID (29) (4.0+)\n * 27 Serial number (4.0+)\n * 2B Volume label (4.0+)\n * 36 8-byte file system name (4.0+)\n * Note: Bytes 0B-23 are the BIOS parameter block\n *\n * Directory entry (20h bytes)\n * 00 Filename\n * 08 Extension\n * 0B Attribute byte\n * 01=Read-only\n * 02=Hidden\n * 04=System\n * 08=Volume label (2.0+)\n * 10=Directory (2.0+)\n * 20=Archive (2.0+)\n * 0C Reserved\n * 16 Time\n * Bits 0-4 Seconds/2 (0-29)\n * 5-10 Minutes (0-59)\n * 11-15 Hours (0-23)\n * 18 Date\n * Bits 0-4 Day (1-31)\n * 5-8 Month (1-12)\n * 9-15 Year-1980\n * 1A Starting cluster number\n * 1C File size\n *\n * Disk parameter block (20h bytes in 3.x, 21h bytes in 4.0+)\n * 00 Drive code (0=A)\n * 01 Unit code\n * 02 Bytes per sector\n * 04 Sectors per cluster-1\n * 05 Cluster shift factor (2**n sectors per cluster)\n * 06 First FAT sector\n * 08 Number of FATs\n * 09 Number of directory entries\n * 0B First data sector\n * 0D Maximum cluster number\n * 0F Sectors per FAT\n * 11 First directory sector\n * 13 Pointer to device driver\n * 17 Media descriptor byte\n * 18 Access flag (00=accessed,FF=not accessed)\n * 19 Pointer to next DPB\n * 1D Last cluster allocated\n * 1F Number of free clusters (-1 if unknown)\n * Note: (3.x) The sectors per FAT field is one byte and all following\n * fields are moved back one byte.\n *\n * System file table (35h bytes in 3.x, 3Bh bytes in 4.0+)\n * 00 Open count\n * 02 Open mode\n * Bit 0-2 access mode\n * 000=read\n * 001=write\n * 010=read/write\n * 4-6 sharing mode\n * 000=compatibility\n * 001=deny read/write\n * 010=deny write\n * 011=deny read\n * 100=deny none\n * 13 critical error handling\n * 0=execute INT 24\n * 1=return error code\n * 14 buffering\n * 0=buffer writes\n * 1=don't buffer writes\n * 15 1=FCB SFT\n * 04 Attribute byte\n * 05 Device info\n * Character devices: Block devices:\n * Bit 0 1=console input Bit 0-5 drive code (0=A)\n * 1 1=console output 6 0=file has been written\n * 2 1=NUL device 7 0=block device\n * 3 1=CLOCK device 12 1=no inherit\n * 4 1=INT 29 output (CON) 14 1=date/time set\n * 5 0=ASCII,1=binary 15 1=redirected file\n * 6 0=EOF on input\n * 7 1=character device\n * 11 1=network spooler\n * 12 1=no inherit\n * 13 1=named pipe\n * 15 1=redirected device\n * 07 Pointer to device driver or disk parameter block\n * 0B First cluster number\n * 0D Time\n * 0F Date\n * 11 File size\n * 15 File pointer\n * 19 Current relative cluster number\n * 1B 32-bit directory entry sector (4.0+)\n * 1B Current absolute cluster number (3.x)\n * 1D Directory entry sector (3.x)\n * 1F Directory entry position in sector\n * 20 Filename\n * 28 Extension\n * 2B Pointer to next SFT for the same file (SHARE only)\n * 2F Machine number\n * 31 PSP of owner\n * 33 SHARE file table offset\n * 35 Current absolute cluster number (4.0+)\n * 37 Reserved (4.0+)\n *\n * SHARE file table\n * 00 Entry flag (1=open,0=unused,-1=end of list)\n * 01 Entry length\n * 03 Filespec checksum\n * 04 First lock table offset\n * 06 Pointer to system file table\n * 0A SHARE file number\n * 0C Filespec\n *\n * SHARE lock table (10h bytes)\n * 00 Offset to next lock table for file\n * 02 Start of lock region\n * 06 End of lock region\n * 0A Pointer to system file table\n * 0E PSP of owner\n *\n * Current directory structure (51h bytes in 3.x, 58h bytes in 4.0+)\n * 00 Current directory\n * 43 Drive type\n * 1000=SUBSTed drive\n * 2000=JOINed drive\n * 4000=valid drive\n * 8000=redirected drive\n * 45 Pointer to disk parameter block\n * 49 Cluster number of current directory (0=root)\n * 4B Reserved\n * 4F Length of root directory name starting at offset 0\n * 51 Reserved (4.0+)\n *\n * Disk buffer header (10h bytes) (3.x)\n * 00 Pointer to next buffer\n * 04 Drive code (0=A,FF=unused)\n * 05 Flags\n * Bit 0 reserved\n * 1 1=FAT sector\n * 2 1=directory sector\n * 3 1=data sector\n * 4 reserved\n * 5 1=buffer read\n * 6 1=buffer written\n * 7 reserved\n * 06 Sector number\n * 08 Number of FATs (if FAT) or 1\n * 09 Sectors per FAT (if FAT) or 0\n * 0A Pointer to DPB\n * 0E Reserved\n * 10 Buffered sector\n *\n * Disk buffer header (14h bytes) (4.0+)\n * 00 Pointer to next buffer\n * 02 Pointer to previous buffer\n * 04 Drive code (0=A,FF=unused)\n * 05 Flags\n * Bit 0 reserved\n * 1 1=FAT sector\n * 2 1=directory sector\n * 3 1=data sector\n * 4 reserved\n * 5 1=buffer read (4.0)\n * 6 1=buffer written\n * 7 reserved\n * 06 Sector number\n * 0A Number of FATs (if FAT) or 1\n * 0B Sectors per FAT (if FAT) or 0\n * 0D Pointer to DPB\n * 11 Reserved\n * 14 Buffered sector\n *\n * Disk buffer control block (4.0)\n * 00 Pointer to buffer chain array\n * 04 Number of chains\n * 06 Pointer to sector lookahead buffers\n * 0A Number of sector lookahead buffers\n * 0C Unknown\n *\n * Disk buffer control block (5.0+)\n * 00 Pointer to buffer chain\n * 04 Number of modified buffers\n * 06 Pointer to sector lookahead buffers\n * 0A Number of sector lookahead buffers\n * 0C HMA flag (1=buffers in HMA)\n * 0D Pointer to HMA transfer buffer\n *\n * Disk buffer chain array entry (8 bytes) (4.0)\n * 00 Reserved\n * 02 Pointer to last accessed buffer\n * 06 Number of modified buffers\n * 07 Reserved\n *\n * Stacks block header (12h bytes)\n * 00 Reserved\n * 02 Number of stacks\n * 04 Offset of stacks\n * 06 Stack size\n * 08 Pointer to stacks table (descriptors followed by stacks)\n * 0C Offset of first stacks descriptor\n * 0E Offset of last stacks descriptor\n * 10 Offset of current stacks descriptor\n *\n * Stacks descriptor (8 bytes)\n * 00 Flag (0=free,1=in use)\n * 02 Save area for SS:SP\n * 06 Offset of end of stack\n *\n * Device driver header (12h bytes)\n * 00 Pointer to next device driver or -1\n * 04 Attribute word\n * Bit 0 1=console input\n * 1 1=console output (character devices)\n * 1=32-bit sectors supported (block devices) (3.31+)\n * 2 1=NUL device\n * 3 1=CLOCK device\n * 4 1=INT 29 output (CON)\n * 6 1=extended functions supported (13,17,18) (3.2+)\n * 7 1=query IOCTL function supported (19) (5.0+)\n * 11 1=open/close/removable media supported (3.0+)\n * 13 1=output until busy supported (character devices) (3.0+)\n * 1=media descriptor in FAT required (block devices)\n * 14 1=IOCTL supported\n * 15 0=block device\n * 1=character device\n * 06 Strategy address\n * 08 Interrupt address\n * 0A Device name or number of units\n *\n * Device driver request header (common fields)\n * 00 Request header length\n * 01 Unit number\n * 02 Command code\n * 00=Init 0B=Flush output buffers\n * 01=Media check 0C=I/O control write\n * 02=Build BPB 0D=Open (3.0+)\n * 03=I/O control read 0E=Close (3.0+)\n * 04=Read 0F=Removable media check (3.0+)\n * 05=Non-destructive read 10=Output until busy (3.0+)\n * 06=Input status 13=Generic I/O control (3.2+)\n * 07=Flush input buffers 17=Get drive map (3.2+)\n * 08=Write 18=Set drive map (3.2+)\n * 09=Write with verify 19=Query I/O control (5.0+)\n * 0A=Output status\n * 03 Return status word\n * Bit 0-7 if error\n * 00=write-protect error 07=unknown medium\n * 01=unknown unit 08=sector not found\n * 02=drive not ready 09=printer out of paper\n * 03=unknown command 0A=write fault\n * 04=data error (CRC) 0B=read fault\n * 05=bad request length 0C=general failure\n * 06=seek error 0F=invalid disk change\n * 8 1=done\n * 9 1=busy\n * 15 1=error\n * 05 Reserved (8 bytes)\n *\n * Device driver request headers:\n * Init\n * 00 Common (length=17h in 3.x, 19h in 4.0+)\n * 0D Number of units (set by driver)\n * 0E End of available memory (5.0+)\n * End of resident code (set by driver)\n * 12 Pointer to string after DEVICE=\n * BPB array pointer (set by driver)\n * 16 Drive code of first unit (0=A)\n * 17 Error message flag (1=display message) (4.0+)\n *\n * Media check\n * 00 Common (length=13h)\n * 0D Media descriptor byte\n * 0E Status (set by driver: 1=unchanged,0=unknown,-1=changed)\n * 0F Pointer to previous disk label (set by driver if disk changed)\n *\n * Build BPB\n * 00 Common (length=16h)\n * 0D Media descriptor byte\n * 0E Pointer to sector buffer\n * 12 Pointer to BPB (set by driver)\n * Note: The sector buffer contains the first sector of the FAT if bit 13 in the\n * device attribute word is zero otherwise it may be used as scratch space.\n *\n * IOCTL read, Read, Write, Write with verify, IOCTL write, Output until busy\n * 00 Common (length=14h)\n * 0D Unused\n * 0E Pointer to data buffer\n * 12 Byte count (set by driver to number of bytes transferred)\n * Notes: 1) The IOCTL functions are called only if bit 14 in the device\n * attribute word is set.\n * 2) The output until busy function is called only if bit 13 in the\n * device attribute word is set.\n *\n * Read, Write, Write with verify\n * 00 Common (length=16h-1Eh)\n * 0D Media descriptor byte\n * 0E Pointer to data buffer\n * 12 Sector count (set by driver to number of sectors transferred)\n * 14 Starting sector number (-1=if 32-bit sectors)\n * 16 Pointer to previous disk label (set by driver if error 0F)\n * 1A 32-bit starting sector number\n * Note: The 32-bit starting sector number is used only if bit 1 in the\n * device attribute word is set.\n *\n * Non-destructive read\n * 00 Common (length=0Eh)\n * 0D Character (set by driver)\n * Note: This function sets the busy bit (bit 9) in the request header\n * if no character is ready.\n *\n * Input status, Output status\n * 00 Common (length=0Dh)\n * Note: These functions set the busy bit (bit 9) in the request header\n * to indicate device status.\n *\n * Flush input buffers, Flush output buffers\n * 00 Common (length=0Dh)\n *\n * Open, Close, Removable media check\n * 00 Common (length=0Dh)\n * Notes: 1) These functions are called only if bit 11 in the device\n * attribute word is set.\n * 2) The removable media check function sets bit 9 in the status word\n * if the device is non-removable.\n *\n * Generic IOCTL, Query IOCTL\n * 00 Common (length=17h)\n * 0D Category code\n * 0E Function code\n * 0F Unused\n * 13 Parameter buffer pointer\n * Notes: 1) The Generic IOCTL function is called only if bit 6 in the device\n * attribute word is set.\n * 2) The Query IOCTL function is called only if bit 7 in the device\n * attribute word is set.\n *\n * Get drive map, Set drive map\n * 00 Common (length=0Dh)\n * Notes: 1) These functions are called only if bit 6 in the device\n * attribute word is set.\n * 2) These functions set the unit field (byte 1) in the request\n * header to the physical drive code.\n *\n * Clock device info (6 bytes)\n * 00 Days since 1/1/80\n * 02 Minutes\n * 03 Hours\n * 04 Hundredths\n * 05 Seconds\n *\n * Memory Control Block (10h bytes)\n * 00 Type ('M' or 'Z' if last)\n * 01 PSP segment of owner (0=free,8=DOS)\n * 03 Size (paragraphs)\n * 05 Unused\n * 08 Program name (4.0+)\n *\n * EXE file header\n * 00 'MZ'\n * 02 Size of last page\n * 04 File size in 512-byte pages\n * 06 Relocation table count\n * 08 Header size (paragraphs)\n * 0A Minimum allocation (paragraphs)\n * 0C Maximum allocation (paragraphs)\n * 0E Initial SS\n * 10 Initial SP\n * 12 Checksum\n * 14 Initial IP\n * 16 Initial CS\n * 18 Offset of relocation table\n * Table entry format:\n * 0 offset of relocation\n * 2 segment of relocation\n * 1A Overlay number\n *\n * EXEPACK header\n * 00 Actual IP\n * 02 Actual CS\n * 04 0 (set to PSP+10h by unpack code)\n * 06 Unpack code and data size (including relocation table)\n * 08 Actual SP\n * 0A Actual SS\n * 0C Actual code and data size\n *\n * Note: If an EXE file is packed then CS:IP-2 points to 'RB' and CS:0\n * points to the EXEPACK header, this is followed by the unpack code\n * and a relocation table containing a word count and relocation\n * entries for 16 segments.\n */\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/messages.js (C) Jeff Parsons 2012-2018\n */\n\nvar Messages = {\n NONE: 0x00000000,\n CPU: 0x10000001,\n SEG: 0x10000002,\n DESC: 0x10000003,\n TSS: 0x10000004,\n PORT: 0x10000008,\n IOPM: 0x10000009,\n NMI: 0x10000010,\n TRAP: 0x10000020,\n FAULT: 0x10000030,\n INT: 0x10000040,\n IRQ: 0x20000080,\n BUS: 0x20000100,\n MEM: 0x20000200,\n DMA: 0x20000400,\n FDC: 0x20000800,\n HDC: 0x20001000,\n DISK: 0x20002000,\n PIC: 0x20004000,\n TIMER: 0x20008000,\n CMOS: 0x20010000,\n RTC: 0x20020000,\n C8042: 0x20040000,\n KBD: 0x20080000,\n PARALLEL: 0x20100000,\n SERIAL: 0x20200000,\n MOUSE: 0x20400000,\n SPEAKER: 0x20800000,\n CHIPSET: 0x21000000,\n VIDEO: 0x22000000,\n COMPUTER: 0x24000000,\n DOS: 0x40000001,\n DATA: 0x40000002,\n EVENT: 0x40000004,\n KEY: 0x40000010,\n WARN: 0x40000020,\n HALT: 0x84000000|0,\n BUFFER: 0x88000000|0\n};\n\n/*\n * Message categories supported by the messageEnabled() function and other assorted message\n * functions. Each category has a corresponding bit value that can be combined (ie, OR'ed) as\n * needed. The Debugger's message command (\"m\") is used to turn message categories on and off,\n * like so:\n *\n * m port on\n * m port off\n * ...\n *\n * NOTE: The order of these categories can be rearranged, alphabetized, etc, as desired; just be\n * aware that changing the bit values could break saved Debugger states (not a huge concern, just\n * something to be aware of).\n */\nMessages.CATEGORIES = {\n \"cpu\": Messages.CPU,\n \"seg\": Messages.SEG,\n \"desc\": Messages.DESC,\n \"port\": Messages.PORT,\n \"tss\": Messages.TSS,\n \"iopm\": Messages.IOPM,\n \"int\": Messages.INT,\n \"nmi\": Messages.NMI,\n \"fault\": Messages.FAULT,\n \"trap\": Messages.TRAP,\n \"bus\": Messages.BUS,\n \"irq\": Messages.IRQ,\n \"mem\": Messages.MEM,\n \"dma\": Messages.DMA,\n \"fdc\": Messages.FDC,\n \"hdc\": Messages.HDC,\n \"disk\": Messages.DISK,\n \"pic\": Messages.PIC,\n \"timer\": Messages.TIMER,\n \"cmos\": Messages.CMOS,\n \"rtc\": Messages.RTC,\n \"8042\": Messages.C8042,\n \"kbd\": Messages.KBD,\n \"parallel\": Messages.PARALLEL,\n \"serial\": Messages.SERIAL,\n \"mouse\": Messages.MOUSE,\n \"speaker\": Messages.SPEAKER,\n \"chipset\": Messages.CHIPSET,\n \"video\": Messages.VIDEO,\n \"computer\": Messages.COMPUTER,\n \"dos\": Messages.DOS,\n \"data\": Messages.DATA,\n \"event\": Messages.EVENT,\n \"key\": Messages.KEY,\n \"warn\": Messages.WARN,\n /*\n * Now we turn to message actions rather than message types; for example, setting \"halt\"\n * on or off doesn't enable \"halt\" messages, but rather halts the CPU on any message above.\n *\n * Similarly, \"m buffer on\" turns on message buffering, deferring the display of all messages\n * until \"m buffer off\" is issued.\n */\n \"halt\": Messages.HALT,\n \"buffer\": Messages.BUFFER\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/panel.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Region object definition\n *\n * iBlock: starting block number\n * cBlocks: number of blocks spanned by region\n * type: type of all blocks in the region (see Memory.TYPE.*)\n *\n * @typedef {{\n * iBlock: number,\n * cBlocks: number,\n * type: number\n * }} Region\n */\nvar Region;\n\nclass Color {\n /**\n * Color(r, g, b, a)\n *\n * @this {Color}\n * @param {number} [r]\n * @param {number} [g]\n * @param {number} [b]\n * @param {number} [a]\n */\n constructor(r, g, b, a)\n {\n this.rgb = [r, g, b, a];\n this.sValue = null;\n if (r === undefined) this.randomize();\n }\n\n /**\n * getRandom(nLimit)\n *\n * @this {Color}\n * @param {number} [nLimit]\n */\n getRandom(nLimit)\n {\n return (Math.random() * (nLimit || 0x100)) | 0;\n }\n\n /**\n * randomize()\n *\n * @this {Color}\n */\n randomize()\n {\n this.rgb[0] = this.getRandom(); this.rgb[1] = this.getRandom(); this.rgb[2] = this.getRandom(); this.rgb[3] = 0xff;\n this.sValue = null;\n }\n\n /**\n * toString()\n *\n * @this {Color}\n * @return {string}\n */\n toString()\n {\n if (!this.sValue) this.sValue = '#' + Str.toHex(this.rgb[0], 2) + Str.toHex(this.rgb[1], 2) + Str.toHex(this.rgb[2], 2);\n return this.sValue;\n }\n}\n\nclass Rectangle {\n /**\n * Rectangle(x, y, cx, cy)\n *\n * @this {Rectangle}\n * @param {number} x\n * @param {number} y\n * @param {number} cx\n * @param {number} cy\n */\n constructor(x, y, cx, cy)\n {\n this.x = x;\n this.y = y;\n this.cx = cx;\n this.cy = cy;\n }\n\n /**\n * contains(x, y)\n *\n * @param {number} x\n * @param {number} y\n * @return {boolean} true if (x,y) lies within the rectangle, false if not\n */\n contains(x, y)\n {\n return (x >= this.x && x < this.x + this.cx && y >= this.y && y < this.y + this.cy);\n }\n\n /**\n * subDivide(units, unitsTotal, fHorizontal)\n *\n * Return a new rectangle that is a subset of the current rectangle, based on the ratio of\n * units to unitsTotal, and then update the dimensions of the current rectangle. Whether the\n * original rectangle is divided horizontally or vertically is entirely arbitrary; currently,\n * the criteria is horizontal if the ratio is 1/4 or more, vertical otherwise.\n *\n * @this {Rectangle}\n * @param {number} units\n * @param {number} unitsTotal\n * @param {boolean} [fHorizontal]\n * @return {Rectangle}\n */\n subDivide(units, unitsTotal, fHorizontal)\n {\n var rect;\n if (fHorizontal === undefined) {\n fHorizontal = units >= (unitsTotal >> 2);\n }\n if (fHorizontal) {\n rect = new Rectangle(this.x, this.y, this.cx, ((this.cy * units) / unitsTotal) | 0);\n this.y += rect.cy;\n this.cy -= rect.cy;\n\n } else {\n rect = new Rectangle(this.x, this.y, ((this.cx * units) / unitsTotal) | 0, this.cy);\n this.x += rect.cx;\n this.cx -= rect.cx;\n\n }\n return rect;\n }\n\n /**\n * drawWith(context, color)\n *\n * @param {Object} context\n * @param {Color|string} [color]\n */\n drawWith(context, color)\n {\n if (!color) color = new Color();\n context.strokeStyle = \"black\";\n context.strokeRect(this.x, this.y, this.cx, this.cy);\n context.fillStyle = (typeof color == \"string\"? color : color.toString());\n context.fillRect(this.x, this.y, this.cx, this.cy);\n }\n}\n\n/**\n * class Panel\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass Panel extends Component {\n /**\n * Panel(parmsPanel)\n *\n * The Panel component has no required (parmsPanel) properties.\n *\n * @this {Panel}\n * @param {Object} parmsPanel\n */\n constructor(parmsPanel)\n {\n super(\"Panel\", parmsPanel);\n\n this.canvas = null;\n this.lockMouse = -1;\n this.fMouseDown = false;\n this.xMouse = this.yMouse = -1;\n this.timer = -1;\n if (BACKTRACK) {\n this.busInfo = null;\n this.fBackTrack = false;\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {Panel}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n var panel = this;\n\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.kbd = cmp.getMachineComponent(\"Keyboard\");\n this.startTimer();\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * Most panel layouts don't have bindings of their own, so we pass along all binding requests to the\n * Computer, CPU, Keyboard and Debugger components first. The order shouldn't matter, since any component\n * that doesn't recognize the specified binding should simply ignore it.\n *\n * @this {Panel}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n if (this.cmp && this.cmp.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (this.cpu && this.cpu.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (this.kbd && this.kbd.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (DEBUGGER && this.dbg && this.dbg.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n\n if (!this.canvas && sHTMLType == \"canvas\") {\n\n var panel = this;\n var fPanel = false;\n\n if (BACKTRACK && sBinding == \"btpanel\") {\n this.fBackTrack = fPanel = true;\n }\n\n if (fPanel) {\n this.canvas = /** @type {HTMLCanvasElement} */ (control);\n this.context = /** @type {CanvasRenderingContext2D} */ (this.canvas.getContext(\"2d\"));\n\n /*\n * Employ the same gross onresize() hack for IE9/IE10 that we had to use for the Video canvas\n */\n if (Web.getUserAgent().indexOf(\"MSIE\") >= 0) {\n this.canvas.onresize = function(canvas, cx, cy) {\n return function onResizeVideo() {\n canvas.style.height = (((canvas.clientWidth * cy) / cx) | 0) + \"px\";\n };\n }(this.canvas, this.canvas.width, this.canvas.height);\n this.canvas.onresize(null);\n }\n\n this.xMem = this.yMem = 0;\n this.cxMem = ((this.canvas.width * Panel.LIVEMEM.CX) / Panel.LIVECANVAS.CX) | 0;\n this.cyMem = this.canvas.height;\n\n this.xReg = this.cxMem;\n this.yReg = 0;\n this.cxReg = this.canvas.width - this.cxMem;\n this.cyReg = this.canvas.height;\n\n this.xDump = this.xReg;\n this.yDump = ((this.canvas.height * (Panel.LIVEREGS.CY - Panel.LIVEDUMP.CY)) / Panel.LIVECANVAS.CY) | 0;\n this.cxDump = this.cxReg;\n this.cyDump = ((this.canvas.height * Panel.LIVEDUMP.CY) / Panel.LIVECANVAS.CY) | 0;\n\n this.canvasLiveMem = document.createElement(\"canvas\");\n this.canvasLiveMem.width = Panel.LIVEMEM.CX;\n this.canvasLiveMem.height = Panel.LIVEMEM.CY;\n this.contextLiveMem = this.canvasLiveMem.getContext(\"2d\");\n this.imageLiveMem = this.contextLiveMem.createImageData(this.canvasLiveMem.width, this.canvasLiveMem.height);\n\n this.canvasLiveRegs = document.createElement(\"canvas\");\n this.canvasLiveRegs.width = Panel.LIVEREGS.CX;\n this.canvasLiveRegs.height = Panel.LIVEREGS.CY;\n this.contextLiveRegs = this.canvasLiveRegs.getContext(\"2d\");\n\n this.canvas.addEventListener(\n 'mousemove',\n function onMouseMove(event) {\n panel.moveMouse(event);\n },\n false // we'll specify false for the 'useCapture' parameter for now...\n );\n this.canvas.addEventListener(\n 'mousedown',\n function onMouseDown(event) {\n panel.clickMouse(event, true);\n },\n false // we'll specify false for the 'useCapture' parameter for now...\n );\n this.canvas.addEventListener(\n 'mouseup',\n function onMouseUp(event) {\n panel.clickMouse(event, false);\n },\n false // we'll specify false for the 'useCapture' parameter for now...\n );\n\n this.fRedraw = true;\n this.startTimer();\n return true;\n }\n }\n return super.setBinding(sHTMLType, sBinding, control, sValue);\n }\n\n /**\n * startTimer()\n *\n * This timer replaces the CPU's old dedicated VIDEO_UPDATES_PER_SECOND logic, which periodically called\n * the Computer's updateVideo() function, which in turn called our updateAnimation() function; periodic\n * animation updates are now our own responsibility.\n *\n * @this {Panel}\n */\n startTimer()\n {\n if (this.timer < 0 && this.canvas && this.cpu) {\n var panel = this;\n this.timer = this.cpu.addTimer(this.id, function updateAnimationTimer() {\n panel.updateAnimation();\n }, 1000 / Panel.UPDATES_PER_SECOND);\n }\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {Panel}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) Panel.init();\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Panel}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return true;\n }\n\n /**\n * clickMouse(event, fDown)\n *\n * @this {Panel}\n * @param {Object} event object from a 'mousedown' or 'mouseup' event\n * @param {boolean} fDown\n */\n clickMouse(event, fDown)\n {\n /*\n * event.button is 0 for the LEFT button and 2 for the RIGHT button\n */\n if (!event.button) {\n this.lockMouse = fDown? 0 : -1;\n this.fMouseDown = fDown;\n this.updateMouse(event, fDown);\n }\n }\n\n /**\n * moveMouse(event)\n *\n * @this {Panel}\n * @param {Object} event object from a 'mousemove' event\n */\n moveMouse(event)\n {\n this.updateMouse(event);\n }\n\n /**\n * updateMouse(event, fDown)\n *\n * MouseEvent objects contain, among other things, the following properties:\n *\n * clientX\n * clientY\n *\n * I've selected the above properties because they're widely supported, not because I need\n * client-area coordinates. In fact, layerX and layerY are probably closer to what I really want,\n * but I don't think they're available in all browsers. screenX and screenY would work as well.\n *\n * @this {Panel}\n * @param {Object} event object from a mouse event (specifically, a MouseEvent object)\n * @param {boolean} [fDown] is true or false if this was a click event, otherwise it's just a move event\n */\n updateMouse(event, fDown)\n {\n /*\n * Due to the responsive nature of our pages, the displayed size of the canvas may be smaller than the\n * allocated size, and the coordinates we receive from mouse events are based on the currently displayed size.\n */\n var xScale = Panel.LIVECANVAS.CX / this.canvas.offsetWidth;\n var yScale = Panel.LIVECANVAS.CY / this.canvas.offsetHeight;\n\n var rect = this.canvas.getBoundingClientRect();\n var x = ((event.clientX - rect.left) * xScale) | 0;\n var y = ((event.clientY - rect.top) * yScale) | 0;\n\n if (fDown == null) {\n if (!this.lockMouse) {\n this.lockMouse = Math.abs(this.xMouse - x) > Math.abs(this.yMouse - y)? 1 : 2;\n }\n if (this.lockMouse == 1) {\n y = this.yMouse;\n } else if (this.lockMouse == 2) {\n x = this.xMouse;\n }\n }\n\n this.xMouse = x;\n this.yMouse = y;\n\n if (MAXDEBUG) this.log(\"Panel.moveMouse(\" + x + \",\" + y + \")\");\n\n if (x >= 0 && x < Panel.LIVECANVAS.CX && y >= 0 && y < Panel.LIVECANVAS.CY) {\n /*\n * Convert the mouse position into the corresponding memory address, assuming it's over the live memory area\n */\n var addr = this.findAddress(x, y);\n if (addr !== X86.ADDR_INVALID) {\n addr &= ~0xf;\n if (addr != this.addrDumpLast) {\n this.dumpMemory(addr, true);\n this.addrDumpLast = addr;\n }\n }\n }\n }\n\n /**\n * findAddress(x, y)\n *\n * @this {Panel}\n * @param {number} x\n * @param {number} y\n * @return {number} address corresponding to (x,y) canvas coordinates, or ADDR_INVALID if none\n */\n findAddress(x, y)\n {\n if (x < Panel.LIVEMEM.CX && this.busInfo && this.busInfo.aRects) {\n var i, rect;\n for (i = 0; i < this.busInfo.aRects.length; i++) {\n rect = this.busInfo.aRects[i];\n if (rect.contains(x, y)) {\n x -= rect.x;\n y -= rect.y;\n var region = this.busInfo.aRegions[i];\n var iBlock = Usr.getBitField(/** @type {BitField} */ (Bus.BlockInfo.num), this.busInfo.aBlocks[region.iBlock]);\n var addr = iBlock * this.bus.nBlockSize;\n var addrLimit = (iBlock + region.cBlocks) * this.bus.nBlockSize - 1;\n\n /*\n * If you want memory to be arranged \"vertically\" instead of \"horizontally\", do this:\n *\n * if (x > 0) addr += rect.cy * (x - 1) * this.ratioMemoryToPixels;\n * addr += (y * this.ratioMemoryToPixels);\n */\n if (y > 0) addr += rect.cx * (y - 1) * this.ratioMemoryToPixels;\n addr += (x * this.ratioMemoryToPixels);\n\n addr |= 0;\n if (addr > addrLimit) addr = addrLimit;\n if (MAXDEBUG) this.log(\"Panel.findAddress(\" + x + \",\" + y + \") found type \" + Memory.TYPE.NAMES[region.type] + \", address %\" + Str.toHex(addr));\n return addr;\n }\n }\n }\n return X86.ADDR_INVALID;\n }\n\n /**\n * updateAnimation()\n *\n * If the given Control Panel contains a canvas requiring animation (eg, \"btpanel\"), then this is where that happens.\n *\n * @this {Panel}\n */\n updateAnimation()\n {\n if (this.fRedraw) {\n\n this.initPen(10, Panel.LIVECANVAS.FONT.CY, this.canvasLiveMem, this.contextLiveMem, this.canvas.style.color);\n\n if (this.fBackTrack) {\n if (DEBUG) this.log(\"begin scanMemory()\");\n this.busInfo = this.bus.scanMemory(this.busInfo);\n /*\n * Calculate the pixel-to-memory-address ratio\n */\n this.ratioMemoryToPixels = (this.busInfo.cBlocks * this.bus.nBlockSize) / (Panel.LIVEMEM.CX * Panel.LIVEMEM.CY);\n /*\n * Update the BusInfo object with region information (cRegions and aRegions); return true if region\n * information has changed since the last call.\n */\n if (this.findRegions()) {\n /*\n * For each region, I choose a slice of the LiveMem canvas and record the corresponding rectangle\n * within an aRects array (parallel to the aRegions array) in the BusInfo object.\n *\n * I don't need a sophisticated Treemap algorithm, because at this level, the data is not hierarchical.\n * subDivide() makes a simple horizontal or vertical slicing decision based on the ratio of region blocks\n * to remaining blocks.\n */\n var i, rect;\n var rectAvail = new Rectangle(0, 0, this.canvasLiveMem.width, this.canvasLiveMem.height);\n this.busInfo.aRects = [];\n var cBlocksRemaining = this.busInfo.cBlocks;\n\n for (i = 0; i < this.busInfo.cRegions; i++) {\n var cBlocksRegion = this.busInfo.aRegions[i].cBlocks;\n this.busInfo.aRects.push(rect = rectAvail.subDivide(cBlocksRegion, cBlocksRemaining, !i));\n if (MAXDEBUG) this.log(\"region \" + i + \" rectangle: (\" + rect.x + \",\" + rect.y + \" \" + rect.cx + \",\" + rect.cy + \")\");\n cBlocksRemaining -= cBlocksRegion;\n }\n\n /*\n * Assert that not only did all the specified regions account for all the specified blocks, but also that\n * the series of subDivide() calls exhausted the original rectangle to one of either zero width or zero height.\n */\n\n\n /*\n * Now draw all the rectangles produced by the series of subDivide() calls.\n */\n for (i = 0; i < this.busInfo.aRects.length; i++) {\n var region = this.busInfo.aRegions[i];\n rect = this.busInfo.aRects[i];\n rect.drawWith(this.contextLiveMem, Memory.TYPE.COLORS[region.type]);\n this.centerPen(rect);\n this.centerText(Memory.TYPE.NAMES[region.type] + \" (\" + (((region.cBlocks * this.bus.nBlockSize) / 1024) | 0) + \"Kb)\");\n }\n }\n if (DEBUG) this.log(\"end scanMemory(): total bytes: \" + this.busInfo.cbTotal + \", total blocks: \" + this.busInfo.cBlocks + \", total regions: \" + this.busInfo.cRegions);\n } else {\n this.drawText(\"This space intentionally left blank\");\n }\n this.context.drawImage(this.canvasLiveMem, 0, 0, this.canvasLiveMem.width, this.canvasLiveMem.height, this.xMem, this.yMem, this.cxMem, this.cyMem);\n this.fRedraw = false;\n }\n }\n\n /**\n * updateStatus(fForce)\n *\n * Update function for Panels containing elements with high-frequency display requirements.\n *\n * For older (and slower) DOM-based display elements, those are sill being managed by the CPUX86 component,\n * so it has its own updateStatus() handler.\n *\n * The Computer's updateStatus() handler is currently responsible for calling both our handler and the CPU's handler.\n *\n * @this {Panel}\n * @param {boolean} [fForce] (true will display registers even if the CPU is running and \"live\" registers are not enabled)\n */\n updateStatus(fForce)\n {\n if (this.canvas) this.dumpRegisters();\n }\n\n /**\n * findRegions()\n *\n * This takes the BusInfo object produced by scanMemory() and adds the following:\n *\n * cRegions: number of contiguous memory regions\n * aRegions: array of aBlocks [index, count, type] objects\n *\n * It calls addRegion() for each discrete region (set of contiguous blocks with the same type) that it finds.\n *\n * @this {Panel}\n * @return {boolean} true if current region checksum differed from previous checksum (ie, one or more regions changed)\n */\n findRegions()\n {\n var checksum = 0;\n this.busInfo.cRegions = 0;\n if (!this.busInfo.aRegions) this.busInfo.aRegions = [];\n\n var typeRegion = -1, iBlockRegion = 0, addrRegion = 0, nBlockPrev = -1;\n\n for (var iBlock = 0; iBlock < this.busInfo.cBlocks; iBlock++) {\n var blockInfo = this.busInfo.aBlocks[iBlock];\n var typeBlock = Usr.getBitField(/** @type {BitField} */ (Bus.BlockInfo.type), blockInfo);\n var nBlockCurr = Usr.getBitField(/** @type {BitField} */ (Bus.BlockInfo.num), blockInfo);\n if (typeBlock != typeRegion || nBlockCurr != nBlockPrev + 1) {\n var cBlocks = iBlock - iBlockRegion;\n if (cBlocks) {\n checksum += this.addRegion(addrRegion, iBlockRegion, cBlocks, typeRegion);\n }\n typeRegion = typeBlock;\n iBlockRegion = iBlock;\n addrRegion = nBlockCurr << this.bus.nBlockShift;\n }\n nBlockPrev = nBlockCurr;\n }\n\n checksum += this.addRegion(addrRegion, iBlockRegion, iBlock - iBlockRegion, typeRegion);\n\n var fChanged = (this.busInfo.checksumRegions != checksum);\n this.busInfo.checksumRegions = checksum;\n return fChanged;\n }\n\n /**\n * addRegion(addr, iBlock, cBlocks, type)\n *\n * @this {Panel}\n * @param {number} addr\n * @param {number} iBlock\n * @param {number} cBlocks\n * @param {number} type\n * @return {number} bitfield containing the above values (used for checksum)\n */\n addRegion(addr, iBlock, cBlocks, type)\n {\n if (DEBUG) this.log(\"region \" + this.busInfo.cRegions + \" (addr \" + Str.toHexLong(addr) + \", type \" + Memory.TYPE.NAMES[type] + \") contains \" + cBlocks + \" blocks\");\n this.busInfo.aRegions[this.busInfo.cRegions++] = {iBlock: iBlock, cBlocks: cBlocks, type: type};\n return Usr.initBitFields(Bus.BlockInfo, iBlock, cBlocks, 0, type);\n }\n\n /**\n * dumpRegisters()\n *\n * Updates the live register portion of the panel.\n *\n * @this {Panel}\n */\n dumpRegisters()\n {\n if (this.context && this.canvasLiveRegs && this.contextLiveRegs) {\n\n var cpu = this.cpu;\n var x = 0, y = 0, cx = this.canvasLiveRegs.width, cy = this.canvasLiveRegs.height;\n\n this.contextLiveRegs.fillStyle = Panel.LIVEREGS.COLOR;\n this.contextLiveRegs.fillRect(x, y, cx, cy);\n\n this.initPen(x + 10, y + Panel.LIVECANVAS.FONT.CY, this.canvasLiveRegs, this.contextLiveRegs, this.canvas.style.color);\n this.initCols(3);\n this.drawText(\"CPU\");\n this.drawText(\"Target\");\n this.drawText(\"Current\");\n this.skipLines();\n this.drawText(cpu.model);\n this.drawText(cpu.getSpeedTarget());\n this.drawText(cpu.getSpeedCurrent());\n this.skipLines(2);\n this.initCols(8);\n this.initNumberFormat(16, cpu.model < X86.MODEL_80386? 4 : 8);\n this.drawText(\"AX\", cpu.regEAX, 2);\n this.drawText(\"DS\", cpu.getDS(), 0, 1);\n this.drawText(\"DX\", cpu.regEDX, 2);\n this.drawText(\"SI\", cpu.regESI, 0, 1.5);\n this.drawText(\"BX\", cpu.regEBX, 2);\n this.drawText(\"ES\", cpu.getES(), 0, 1);\n this.drawText(\"CX\", cpu.regECX, 2);\n this.drawText(\"DI\", cpu.regEDI, 0, 1.5);\n this.drawText(\"CS\", cpu.getCS(), 2);\n this.drawText(\"SS\", cpu.getSS(), 0, 1);\n this.drawText(\"IP\", cpu.getIP(), 2);\n this.drawText(\"SP\", cpu.getSP(), 0, 1.5);\n var regPS;\n this.drawText(\"PS\", regPS = cpu.getPS(), 2);\n this.drawText(\"BP\", cpu.regEBP, 0, 1.5);\n if (cpu.model >= X86.MODEL_80386) {\n this.drawText(\"FS\", cpu.getFS(), 2);\n this.drawText(\"CR0\", cpu.regCR0, 0, 1);\n this.drawText(\"GS\", cpu.getGS(), 2);\n this.drawText(\"CR3\", cpu.regCR3, 0, 1.5);\n }\n this.initCols(9);\n this.drawText(\"V\" + ((regPS & X86.PS.OF)? 1 : 0));\n this.drawText(\"D\" + ((regPS & X86.PS.DF)? 1 : 0));\n this.drawText(\"I\" + ((regPS & X86.PS.IF)? 1 : 0));\n this.drawText(\"T\" + ((regPS & X86.PS.TF)? 1 : 0));\n this.drawText(\"S\" + ((regPS & X86.PS.SF)? 1 : 0));\n this.drawText(\"Z\" + ((regPS & X86.PS.ZF)? 1 : 0));\n this.drawText(\"A\" + ((regPS & X86.PS.AF)? 1 : 0));\n this.drawText(\"P\" + ((regPS & X86.PS.PF)? 1 : 0));\n this.drawText(\"C\" + ((regPS & X86.PS.CF)? 1 : 0), 0, 2);\n\n this.dumpMemory(this.addrDumpLast);\n\n this.context.drawImage(this.canvasLiveRegs, x, y, cx, cy, this.xReg, this.yReg, this.cxReg, this.cyReg);\n }\n }\n\n /**\n * dumpMemory(addr, fDraw)\n *\n * @this {Panel}\n * @param {number} addr\n * @param {boolean} [fDraw]\n */\n dumpMemory(addr, fDraw)\n {\n if (this.context && this.canvasLiveRegs && this.contextLiveRegs) {\n\n var x = 0, y = Panel.LIVEREGS.CY - Panel.LIVEDUMP.CY, cx = this.canvasLiveRegs.width, cy = Panel.LIVEDUMP.CY;\n\n this.contextLiveRegs.fillStyle = Panel.LIVEREGS.COLOR;\n this.contextLiveRegs.fillRect(x, y, cx, cy);\n\n this.initPen(x + 10, y + Panel.LIVECANVAS.FONT.CY, this.canvasLiveRegs, this.contextLiveRegs, this.canvas.style.color);\n this.initCols(24);\n if (addr == null) {\n this.drawText(\"Mouse over memory to dump\");\n } else {\n this.drawText(Str.toHexLong(addr), null, 0, 1);\n for (var iLine = 1; iLine <= 16; iLine++) {\n var sChars = \"\";\n for (var iCol = 1; iCol <= 8; iCol++) {\n var b = this.bus.getByteDirect(addr++);\n this.drawText(Str.toHex(b, 2), null, 1);\n sChars += (b >= 32 && b < 128? String.fromCharCode(b) : \".\");\n }\n this.drawText(sChars, null, 0, 1);\n }\n }\n\n if (fDraw) this.context.drawImage(this.canvasLiveRegs, x, y, cx, cy, this.xDump, this.yDump, this.cxDump, this.cyDump);\n }\n }\n\n /**\n * initPen(xLeft, yTop, canvas, context, sColor, cyFont, sFontFace)\n *\n * @this {Panel}\n * @param {number} xLeft\n * @param {number} yTop\n * @param {HTMLCanvasElement} [canvas]\n * @param {Object} [context]\n * @param {string} [sColor]\n * @param {number} [cyFont]\n * @param {string} [sFontFace]\n */\n initPen(xLeft, yTop, canvas, context, sColor, cyFont, sFontFace)\n {\n this.setPen(this.xLeftMargin = xLeft, yTop);\n this.heightText = this.heightDefault = cyFont || Panel.LIVECANVAS.FONT.CY;\n if (!sFontFace) sFontFace = this.fontDefault || (this.heightDefault + \"px \" + Panel.LIVECANVAS.FONT.FACE);\n this.fontText = this.fontDefault = sFontFace;\n if (canvas) {\n this.canvasText = canvas;\n }\n if (context) {\n this.contextText = context;\n this.colorText = sColor || \"white\";\n }\n }\n\n /**\n * setPen(x, y)\n *\n * @this {Panel}\n * @param {number} x\n * @param {number} y\n */\n setPen(x, y)\n {\n this.xText = x;\n this.yText = y;\n }\n\n /**\n * centerPen(rect)\n *\n * @this {Panel}\n * @param {Rectangle} rect\n */\n centerPen(rect)\n {\n this.fontText = this.fontDefault;\n this.heightText = this.heightDefault;\n var x = rect.x + (rect.cx >> 1);\n var y = rect.y + (rect.cy >> 1);\n var maxText = rect.cy;\n if (rect.cx < rect.cy) {\n maxText = rect.cx;\n this.fVerticalText = true;\n this.contextText.save();\n this.contextText.translate(x, y);\n this.contextText.rotate(-Math.PI/2);\n x = y = 0;\n }\n if (maxText < this.heightText) {\n this.heightText = maxText;\n this.fontText = this.heightText + \"px \" + Panel.LIVECANVAS.FONT.FACE;\n }\n this.setPen(x, y);\n }\n\n /**\n * initCols(nCols)\n *\n * @this {Panel}\n * @param {number} nCols\n */\n initCols(nCols)\n {\n this.cxColumn = (this.canvasText.width / nCols) | 0;\n }\n\n /**\n * skipCols(nCols)\n *\n * @this {Panel}\n * @param {number} nCols\n */\n skipCols(nCols)\n {\n this.xText += this.cxColumn * nCols;\n }\n\n /**\n * skipLines(nLines)\n *\n * @this {Panel}\n * @param {number} [nLines]\n */\n skipLines(nLines)\n {\n this.xText = this.xLeftMargin;\n this.yText += (this.heightText + 2) * (nLines || 1);\n }\n\n /**\n * initNumberFormat(nBase, nDigits)\n *\n * @this {Panel}\n * @param {number} nBase\n * @param {number} nDigits\n */\n initNumberFormat(nBase, nDigits)\n {\n this.nDefaultBase = nBase;\n this.nDefaultDigits = nDigits;\n }\n\n /**\n * drawText(sText)\n *\n * @this {Panel}\n * @param {string} sText\n * @param {number|null|*} [nValue]\n * @param {number} [nColsSkip]\n * @param {number} [nLinesSkip]\n */\n drawText(sText, nValue, nColsSkip, nLinesSkip)\n {\n this.contextText.font = this.fontText;\n this.contextText.fillStyle = this.colorText;\n this.contextText.fillText(sText, this.xText, this.yText);\n this.xText += this.cxColumn;\n if (nValue != null) {\n var sValue;\n if (this.nDefaultBase != 16) {\n sValue = nValue.toString();\n } else {\n sValue = this.nDefaultDigits < 8? \"0x\" : \"\";\n sValue += Str.toHex(nValue, this.nDefaultDigits);\n }\n this.contextText.fillText(sValue, this.xText, this.yText);\n this.xText += this.cxColumn;\n }\n if (nColsSkip) this.skipCols(nColsSkip);\n if (nLinesSkip) this.skipLines(nLinesSkip);\n }\n\n /**\n * centerText(sText)\n *\n * To center text within a given Rectangle:\n *\n * centerPen(rect)\n * centerText(sText)\n *\n * centerPen() sets xLeft and yTop to the center of the specified rectangle, and centerText() calculates\n * the width of the text, adjusting the horizontal centering by its width and the vertical centering by the\n * default font height. Then it calls drawText().\n *\n * @this {Panel}\n * @param {string} sText\n */\n centerText(sText)\n {\n this.contextText.font = this.fontText;\n var tm = this.contextText.measureText(sText);\n this.xText -= tm.width >> 1;\n this.yText += (this.heightText >> 1) - 2;\n this.drawText(sText);\n if (this.fVerticalText) {\n this.contextText.restore();\n this.fVerticalText = false;\n }\n }\n\n /**\n * Panel.init()\n *\n * This function operates on every HTML element of class \"panel\", extracting the\n * JSON-encoded parameters for the Panel constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Panel component, and then binding\n * any associated HTML controls to the new component.\n *\n * NOTE: Unlike most other component init() functions, this one is designed to be\n * called multiple times: once at load time, so that we can bind our print()\n * function to the panel's output control ASAP, and again when the Computer component\n * is verifying that all components are ready and invoking their powerUp() functions.\n *\n * Our powerUp() method gives us a second opportunity to notify any components that\n * that might care (eg, CPU, Keyboard, and Debugger) that we have some controls they\n * might want to use.\n */\n static init()\n {\n var fReady = false;\n var aePanels = Component.getElementsByClass(document, PCX86.APPCLASS, \"panel\");\n for (var iPanel=0; iPanel < aePanels.length; iPanel++) {\n var ePanel = aePanels[iPanel];\n var parmsPanel = Component.getComponentParms(ePanel);\n var panel = Component.getComponentByID(parmsPanel['id']);\n if (!panel) {\n fReady = true;\n panel = new Panel(parmsPanel);\n }\n Component.bindComponentControls(panel, ePanel, PCX86.APPCLASS);\n if (fReady) panel.setReady();\n }\n }\n}\n\n/*\n * The \"Live\" canvases that we create internally have the following fixed dimensions, to make drawing\n * simpler. We then render, via drawImage(), these canvases onto the supplied canvas, which will automatically\n * stretch the live images to fit.\n */\nPanel.LIVECANVAS = {\n CX: 1280,\n CY: 720,\n FONT: {\n CY: 18,\n FACE: \"Monaco, Lucida Console, Courier New\"\n }\n};\n\nPanel.LIVEMEM = {\n CX: (Panel.LIVECANVAS.CX * 3) >> 2,\n CY: (Panel.LIVECANVAS.CY)\n};\n\nPanel.LIVEREGS = {\n CX: (Panel.LIVECANVAS.CX - Panel.LIVEMEM.CX),\n CY: (Panel.LIVECANVAS.CY),\n COLOR: \"black\"\n};\n\nPanel.LIVEDUMP = {\n CX: (Panel.LIVECANVAS.CX - Panel.LIVEMEM.CX),\n CY: (Panel.LIVECANVAS.CY >> 1)\n};\n\n/*\n * findRegions() records block numbers in bits 0-14, a BackTrack \"mod\" bit in bit 15, and the block type at bit 16.\n */\nPanel.REGION = {\n MASK: 0x7fff,\n BTMOD_SHIFT: 15,\n TYPE_SHIFT: 16\n};\n\nPanel.UPDATES_PER_SECOND = 10;\n\n/*\n * Initialize every Panel module on the page.\n */\nWeb.onInit(Panel.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/bus.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Think of this Controller class definition as an interface definition, implemented by the Video Card\n * class and the RAM CompaqController class.\n * \n * class Controller\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass Controller {\n /**\n * getMemoryAccess()\n *\n * @this {Controller}\n * @return {Array.<function()>}\n */\n getMemoryAccess()\n {\n return [];\n }\n \n /**\n * getMemoryBuffer(addr)\n *\n * @this {Controller}\n * @param {number} addr\n * @return {Array} containing the buffer (and an offset within that buffer)\n */\n getMemoryBuffer(addr)\n {\n return [];\n }\n}\n\n/**\n * class Bus\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass Bus extends Component {\n /**\n * Bus(cpu, dbg)\n *\n * The Bus component manages physical memory and I/O address spaces.\n *\n * The Bus component has no UI elements, so it does not require an init() handler,\n * but it still inherits from the Component class and must be allocated like any\n * other device component. It's currently allocated by the Computer's init() handler,\n * which then calls the initBus() method of all the other components.\n *\n * When initMemory() initializes the entire address space, it also passes aMemBlocks\n * to the CPU object, so that the CPU can perform its own address-to-block calculations\n * (essential, for example, when the CPU enables paging).\n *\n * For memory beyond the simple needs of the ROM and RAM components (ie, memory-mapped\n * devices), the address space must still be allocated through the Bus component via\n * addMemory(). If the component needs something more than simple read/write storage,\n * it must provide a controller with getMemoryBuffer() and getMemoryAccess() methods.\n *\n * All port (I/O) operations are defined by external handlers; they register with us,\n * and we manage those registrations and provide support for I/O breakpoints, but the\n * only default I/O behavior we provide is ignoring writes to any unregistered output\n * ports and returning 0xff from any unregistered input ports.\n *\n * @this {Bus}\n * @param {Object} parmsBus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n constructor(parmsBus, cpu, dbg)\n {\n super(\"Bus\", parmsBus);\n\n this.cpu = cpu;\n this.dbg = dbg;\n\n this.nBusWidth = parmsBus['busWidth'] || 20;\n\n /*\n * Compute all Bus memory block parameters, based on the width of the bus.\n *\n * Regarding blockTotal, we want to avoid using block overflow expressions like:\n *\n * iBlock < this.nBlockTotal? iBlock : 0\n *\n * As long as we know that blockTotal is a power of two (eg, 256 or 0x100, in the case of\n * nBusWidth == 20 and blockSize == 4096), we can define blockMask as (blockTotal - 1) and\n * rewrite the previous expression as:\n *\n * iBlock & this.nBlockMask\n *\n * Similarly, we mask addresses with busMask to enforce \"A20 wrap\" on 20-bit buses.\n * For larger buses, A20 wrap can be simulated by either clearing bit 20 of busMask or by\n * changing all the block entries for the 2nd megabyte to match those in the 1st megabyte.\n *\n * Bus Property Old hard-coded values (when nBusWidth was always 20)\n * ------------ ----------------------------------------------------\n * this.nBusLimit 0xfffff\n * this.nBusMask [same as busLimit]\n * this.nBlockSize 4096\n * this.nBlockLen (this.nBlockSize >> 2)\n * this.nBlockShift 12\n * this.nBlockLimit 0xfff\n * this.nBlockTotal ((this.nBusLimit + this.nBlockSize) / this.nBlockSize) | 0\n * this.nBlockMask (this.nBlockTotal - 1) [ie, 0xff]\n *\n * Note that we choose a nBlockShift value (and thus a physical memory block size) based on \"buswidth\":\n *\n * Bus Width Block Shift Block Size\n * --------- ----------- ----------\n * 20 bits (1Mb address space): 12 4Kb (256 maximum blocks)\n * 24 bits (16Mb address space): 14 16Kb (1K maximum blocks)\n * 32 bits (4Gb address space); 15 32Kb (128K maximum blocks)\n *\n * The coarser block granularities (ie, 16Kb and 32Kb) may cause problems for certain RAM and/or ROM\n * allocations that are contiguous but are allocated out of order, or that have different controller\n * requirements. Your choices, for the moment, are either to ensure the allocations are performed in\n * order, or to choose smaller nBlockShift values (at the expense of a generating a larger block array).\n *\n * Note that if PAGEBLOCKS is set, then for a bus width of 32 bits, the block size is fixed at 4Kb.\n */\n this.addrTotal = Math.pow(2, this.nBusWidth);\n this.nBusLimit = this.nBusMask = (this.addrTotal - 1) | 0;\n this.nBlockShift = (PAGEBLOCKS && this.nBusWidth == 32 || this.nBusWidth <= 20)? 12 : (this.nBusWidth <= 24? 14 : 15);\n this.nBlockSize = 1 << this.nBlockShift;\n this.nBlockLen = this.nBlockSize >> 2;\n this.nBlockLimit = this.nBlockSize - 1;\n this.nBlockTotal = (this.addrTotal / this.nBlockSize) | 0;\n this.nBlockMask = this.nBlockTotal - 1;\n\n\n /*\n * Lists of I/O notification functions: aPortInputNotify and aPortOutputNotify are arrays, indexed by\n * port, of sub-arrays which contain:\n *\n * [0]: registered function to call for every I/O access\n *\n * The registered function is called with the port address, and if the access was triggered by the CPU,\n * the linear instruction pointer (LIP) at the point of access.\n *\n * WARNING: Unlike the (old) read and write memory notification functions, these support only one\n * pair of input/output functions per port. A more sophisticated architecture could support a list\n * of chained functions across multiple components, but I doubt that will be necessary here.\n *\n * UPDATE: The Debugger now piggy-backs on these arrays to indicate ports for which it wants notification\n * of I/O. In those cases, the registered component/function elements may or may not be set, but the\n * following additional element will be set:\n *\n * [1]: true to break on I/O, false to ignore I/O\n *\n * The false case is important if fPortInputBreakAll and/or fPortOutputBreakAll is set, because it allows the\n * Debugger to selectively ignore specific ports.\n */\n this.aPortInputNotify = [];\n this.aPortOutputNotify = [];\n this.fPortInputBreakAll = this.fPortOutputBreakAll = false;\n\n /*\n * By default, all I/O ports are 1 byte wide; ports that are wider must add themselves to one or both of\n * these lists, using addPortInputWidth() and/or addPortOutputWidth().\n */\n this.aPortInputWidth = [];\n this.aPortOutputWidth = [];\n\n /*\n * Allocate empty Memory blocks to span the entire physical address space.\n */\n this.initMemory();\n\n if (BACKTRACK) {\n this.abtObjects = [];\n this.cbtDeletions = 0;\n this.ibtLastAlloc = -1;\n this.ibtLastDelete = 0;\n }\n\n this.setReady();\n }\n\n /**\n * initMemory()\n *\n * Allocate enough (empty) Memory blocks to span the entire physical address space.\n *\n * @this {Bus}\n */\n initMemory()\n {\n var block = new Memory();\n block.copyBreakpoints(this.dbg);\n this.aMemBlocks = new Array(this.nBlockTotal);\n for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {\n this.aMemBlocks[iBlock] = block;\n }\n this.cpu.initMemory(this.aMemBlocks, this.nBlockShift);\n this.cpu.setAddressMask(this.nBusMask);\n }\n\n /**\n * reset()\n *\n * @this {Bus}\n */\n reset()\n {\n this.setA20(true);\n if (BACKTRACK) this.ibtLastDelete = 0;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * We don't need a powerDown() handler, because for largely historical reasons, our state (including the A20 state)\n * is saved by saveMemory(), which called by the CPU.\n *\n * However, we do need a powerUp() handler, because on resumable machines, the Computer's onReset() function calls\n * everyone's powerUp() handler rather than their reset() handler.\n *\n * TODO: Perhaps Computer should be smarter: if there's no powerUp() handler, then fallback to the reset() handler.\n * In that case, however, we'd either need to remove the powerUp() stub in Component, or detect the existence of the stub.\n *\n * @this {Bus}\n * @param {Object|null} data (always null because we supply no powerDown() handler)\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) this.reset();\n return true;\n }\n\n /**\n * addMemory(addr, size, type, controller)\n *\n * Adds new Memory blocks to the specified address range. Any Memory blocks previously\n * added to that range must first be removed via removeMemory(); otherwise, you'll get\n * an allocation conflict error. This helps prevent address calculation errors, redundant\n * allocations, etc.\n *\n * We've relaxed some of the original requirements (ie, that addresses must start at a\n * block-granular address, or that sizes must be equal to exactly one or more blocks),\n * because machines with large block sizes can make it impossible to load certain ROMs at\n * their required addresses. Every allocation still allocates a whole number of blocks.\n *\n * Even so, Bus memory management does NOT provide a general-purpose heap. Most memory\n * allocations occur during machine initialization and never change. In particular, there\n * is NO support for removing partial-block allocations. Typically, the only region that\n * changes post-initialization is the Video buffer, and only in the EGA/VGA implementation.\n *\n * Each Memory block keeps track of a start address (addr) and length (used), indicating\n * the used space within the block; any free space that precedes or follows that used space\n * can be allocated later, by simply extending the beginning or ending of the previously used\n * space. However, any holes that might have existed between the original allocation and an\n * extension are subsumed by the extension.\n *\n * @this {Bus}\n * @param {number} addr is the starting physical address of the request\n * @param {number} size of the request, in bytes\n * @param {number} type is one of the Memory.TYPE constants\n * @param {Controller} [controller] is an optional memory controller component\n * @return {boolean} true if successful, false if not\n */\n addMemory(addr, size, type, controller)\n {\n var addrNext = addr;\n var sizeLeft = size;\n var iBlock = addrNext >>> this.nBlockShift;\n\n while (sizeLeft > 0 && iBlock < this.aMemBlocks.length) {\n\n var block = this.aMemBlocks[iBlock];\n var addrBlock = iBlock * this.nBlockSize;\n var sizeBlock = this.nBlockSize - (addrNext - addrBlock);\n if (sizeBlock > sizeLeft) sizeBlock = sizeLeft;\n\n if (block && block.size) {\n if (block.type == type && block.controller == controller) {\n /*\n * Where there is already a similar block with a non-zero size, we allow the allocation only if:\n *\n * 1) addrNext + sizeLeft <= block.addr (the request precedes the used portion of the current block), or\n * 2) addrNext >= block.addr + block.used (the request follows the used portion of the current block)\n */\n if (addrNext + sizeLeft <= block.addr) {\n block.used += (block.addr - addrNext);\n block.addr = addrNext;\n return true;\n }\n if (addrNext >= block.addr + block.used) {\n var sizeAvail = block.size - (addrNext - addrBlock);\n if (sizeAvail > sizeLeft) sizeAvail = sizeLeft;\n block.used = addrNext - block.addr + sizeAvail;\n addrNext = addrBlock + this.nBlockSize;\n sizeLeft -= sizeAvail;\n iBlock++;\n continue;\n }\n }\n return this.reportError(Bus.ERROR.ADD_MEM_INUSE, addrNext, sizeLeft);\n }\n\n var blockNew = new Memory(addrNext, sizeBlock, this.nBlockSize, type, controller);\n blockNew.copyBreakpoints(this.dbg, block);\n this.aMemBlocks[iBlock++] = blockNew;\n\n addrNext = addrBlock + this.nBlockSize;\n sizeLeft -= sizeBlock;\n }\n if (sizeLeft <= 0) {\n /*\n * If all addMemory() calls happened ONLY during device initialization, the following code would not\n * be necessary; unfortunately, the Video component can add and remove physical memory blocks during video\n * mode changes, so we have to kick out any PAGED blocks that could have references to those physical memory\n * blocks. If paging isn't enabled (or supported by the current the CPU), this call has no effect.\n *\n * We could handle this case with a little more, um, precision, but Video mode changes aren't frequent enough\n * to warrant it.\n */\n this.cpu.flushPageBlocks();\n if (!this.cpu.isRunning()) { // allocation messages at \"run time\" are bit too much\n var kb = (size / 1024)|0;\n var sb = kb? (kb + \"Kb \") : (size + \" bytes \");\n this.status(sb + Memory.TYPE.NAMES[type] + \" at \" + Str.toHex(addr));\n }\n return true;\n }\n return this.reportError(Bus.ERROR.ADD_MEM_BADRANGE, addr, size);\n }\n\n /**\n * cleanMemory(addr, size, fNoScrub)\n *\n * @this {Bus}\n * @param {number} addr\n * @param {number} size\n * @param {boolean} [fNoScrub] (by default, all blocks are \"scrubbed\" in the process)\n * @return {boolean} (true if all blocks were clean, false if dirty)\n */\n cleanMemory(addr, size, fNoScrub)\n {\n var fClean = true;\n var iBlock = addr >>> this.nBlockShift;\n var sizeBlock = this.nBlockSize - (addr & this.nBlockLimit);\n while (size > 0 && iBlock < this.aMemBlocks.length) {\n if (this.aMemBlocks[iBlock].fDirty) {\n if (!fNoScrub) {\n this.aMemBlocks[iBlock].fDirty = false;\n this.aMemBlocks[iBlock].fDirtyEver = true;\n }\n fClean = false;\n }\n size -= sizeBlock;\n sizeBlock = this.nBlockSize;\n iBlock++;\n }\n return fClean;\n }\n\n /**\n * scanMemory(info, addr, size)\n *\n * Returns a BusInfo object for the specified address range.\n *\n * @this {Bus}\n * @param {Object} [info] previous BusInfo, if any\n * @param {number} [addr] starting address of range (0 if none provided)\n * @param {number} [size] size of range, in bytes (up to end of address space if none provided)\n * @return {Object} updated info (or new info if no previous info provided)\n */\n scanMemory(info, addr, size)\n {\n if (addr == null) addr = 0;\n if (size == null) size = (this.addrTotal - addr) | 0;\n if (info == null) info = {cbTotal: 0, cBlocks: 0, aBlocks: []};\n\n var iBlock = addr >>> this.nBlockShift;\n var iBlockMax = ((addr + size - 1) >>> this.nBlockShift);\n\n info.cbTotal = 0;\n info.cBlocks = 0;\n while (iBlock <= iBlockMax) {\n var block = this.aMemBlocks[iBlock];\n info.cbTotal += block.size;\n if (block.size) {\n var btmod = (BACKTRACK && block.modBackTrack(false)? 1 : 0);\n info.aBlocks.push(Usr.initBitFields(Bus.BlockInfo, iBlock, 0, btmod, block.type));\n info.cBlocks++\n }\n iBlock++;\n }\n return info;\n }\n\n /**\n * getA20()\n *\n * @this {Bus}\n * @return {boolean} true if enabled, false if disabled\n */\n getA20()\n {\n return !this.aBlocks2Mb && this.nBusLimit == this.nBusMask;\n }\n\n /**\n * setA20(fEnable)\n *\n * On 32-bit bus machines, I've adopted the approach that COMPAQ took with DeskPro 386 machines,\n * which is to map the 1st Mb to the 2nd Mb whenever A20 is disabled, rather than blindly masking\n * the A20 address bit from all addresses; in fact, this is what the DeskPro 386 ROM BIOS requires.\n *\n * For 24-bit bus machines, we take the same approach that most if not all 80286 systems took, which\n * is simply masking the A20 address bit. A lot of 32-bit machines probably took the same approach.\n *\n * TODO: On machines with a 32-bit bus, look into whether we can eliminate address masking altogether,\n * which seems feasible, provided all incoming addresses are already pre-truncated to 32 bits. Also,\n * confirm that DeskPro 386 machines mapped the ENTIRE 1st Mb to the 2nd, and not simply the first 64Kb,\n * which is technically all that 8086 address wrap-around compatibility would require.\n *\n * @this {Bus}\n * @param {boolean} fEnable is true to enable A20 (default), false to disable\n */\n setA20(fEnable)\n {\n if (this.nBusWidth == 32) {\n if (fEnable) {\n if (this.aBlocks2Mb) {\n this.setMemoryBlocks(0x100000, 0x100000, this.aBlocks2Mb);\n this.aBlocks2Mb = null;\n }\n } else {\n if (!this.aBlocks2Mb) {\n this.aBlocks2Mb = this.getMemoryBlocks(0x100000, 0x100000);\n this.setMemoryBlocks(0x100000, 0x100000, this.getMemoryBlocks(0x0, 0x100000));\n }\n }\n }\n else if (this.nBusWidth > 20) {\n var addrMask = (this.nBusMask & ~0x100000) | (fEnable? 0x100000 : 0);\n if (addrMask != this.nBusMask) {\n this.nBusMask = addrMask;\n if (this.cpu) this.cpu.setAddressMask(addrMask);\n }\n }\n }\n\n /**\n * getWidth()\n *\n * @this {Bus}\n * @return {number}\n */\n getWidth()\n {\n return this.nBusWidth;\n }\n\n /**\n * setMemoryAccess(addr, size, afn, fQuiet)\n *\n * Updates the access functions in every block of the specified address range. Since the only components\n * that should be dynamically modifying the memory access functions are those that use addMemory() with a custom\n * memory controller, we require that the block(s) being updated do in fact have a controller.\n *\n * @this {Bus}\n * @param {number} addr\n * @param {number} size\n * @param {Array.<function()>} [afn]\n * @param {boolean} [fQuiet] (true if any error should be quietly logged)\n * @return {boolean} true if successful, false if not\n */\n setMemoryAccess(addr, size, afn, fQuiet)\n {\n if (!(addr & this.nBlockLimit) && size && !(size & this.nBlockLimit)) {\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0) {\n var block = this.aMemBlocks[iBlock];\n if (!block.controller) {\n return this.reportError(Bus.ERROR.SET_MEM_NOCTRL, addr, size, fQuiet);\n }\n block.setAccess(afn, true);\n size -= this.nBlockSize;\n iBlock++;\n }\n return true;\n }\n return this.reportError(Bus.ERROR.SET_MEM_BADRANGE, addr, size);\n }\n\n /**\n * removeMemory(addr, size)\n *\n * Replaces every block in the specified address range with empty Memory blocks that ignore all reads/writes.\n *\n * TODO: Update the removeMemory() interface to reflect the relaxed requirements of the addMemory() interface.\n *\n * @this {Bus}\n * @param {number} addr\n * @param {number} size\n * @return {boolean} true if successful, false if not\n */\n removeMemory(addr, size)\n {\n if (!(addr & this.nBlockLimit) && size && !(size & this.nBlockLimit)) {\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0) {\n var blockOld = this.aMemBlocks[iBlock];\n var blockNew = new Memory(addr);\n blockNew.copyBreakpoints(this.dbg, blockOld);\n this.aMemBlocks[iBlock++] = blockNew;\n addr = iBlock * this.nBlockSize;\n size -= this.nBlockSize;\n }\n /*\n * If all removeMemory() calls happened ONLY during device initialization, the following code would not\n * be necessary; unfortunately, the Video component can add and remove physical memory blocks during video\n * mode changes, so we have to kick out any PAGED blocks that could have references to those physical memory\n * blocks. If paging isn't enabled (or supported by the current the CPU), this call has no effect.\n *\n * We could handle this case with a little more, um, precision, but Video mode changes aren't frequent enough\n * to warrant it.\n */\n this.cpu.flushPageBlocks();\n return true;\n }\n return this.reportError(Bus.ERROR.REM_MEM_BADRANGE, addr, size);\n }\n\n /**\n * getMemoryBlocks(addr, size)\n *\n * @this {Bus}\n * @param {number} addr is the starting physical address\n * @param {number} size of the request, in bytes\n * @return {Array} of Memory blocks\n */\n getMemoryBlocks(addr, size)\n {\n var aBlocks = [];\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0 && iBlock < this.aMemBlocks.length) {\n aBlocks.push(this.aMemBlocks[iBlock++]);\n size -= this.nBlockSize;\n }\n return aBlocks;\n }\n\n /**\n * setMemoryBlocks(addr, size, aBlocks, type)\n *\n * If no type is specified, then specified address range uses all the provided blocks as-is;\n * this form of setMemoryBlocks() is used for complete physical aliases.\n *\n * Otherwise, new blocks are allocated with the specified type; the underlying memory from the\n * provided blocks is still used, but the new blocks may have different access to that memory.\n *\n * @this {Bus}\n * @param {number} addr is the starting physical address\n * @param {number} size of the request, in bytes\n * @param {Array} aBlocks as returned by getMemoryBlocks()\n * @param {number} [type] is one of the Memory.TYPE constants\n */\n setMemoryBlocks(addr, size, aBlocks, type)\n {\n var i = 0;\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0 && iBlock < this.aMemBlocks.length) {\n var block = aBlocks[i++];\n\n if (!block) break;\n if (type !== undefined) {\n var blockNew = new Memory(addr);\n blockNew.clone(block, type, this.dbg);\n block = blockNew;\n }\n this.aMemBlocks[iBlock++] = block;\n size -= this.nBlockSize;\n }\n }\n\n /**\n * getByte(addr)\n *\n * For physical addresses only; for linear addresses, use cpu.getByte().\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @return {number} byte (8-bit) value at that address\n */\n getByte(addr)\n {\n return this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].readByte(addr & this.nBlockLimit, addr);\n }\n\n /**\n * getByteDirect(addr)\n *\n * This is useful for the Debugger and other components that want to bypass getByte() breakpoint detection.\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @return {number} byte (8-bit) value at that address\n */\n getByteDirect(addr)\n {\n return this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].readByteDirect(addr & this.nBlockLimit, addr);\n }\n\n /**\n * getShort(addr)\n *\n * For physical addresses only; for linear addresses, use cpu.getShort().\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @return {number} word (16-bit) value at that address\n */\n getShort(addr)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off != this.nBlockLimit) {\n return this.aMemBlocks[iBlock].readShort(off, addr);\n }\n return this.aMemBlocks[iBlock++].readByte(off, addr) | (this.aMemBlocks[iBlock & this.nBlockMask].readByte(0, addr + 1) << 8);\n }\n\n /**\n * getShortDirect(addr)\n *\n * This is useful for the Debugger and other components that want to bypass getShort() breakpoint detection.\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @return {number} word (16-bit) value at that address\n */\n getShortDirect(addr)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off != this.nBlockLimit) {\n return this.aMemBlocks[iBlock].readShortDirect(off, addr);\n }\n return this.aMemBlocks[iBlock++].readByteDirect(off, addr) | (this.aMemBlocks[iBlock & this.nBlockMask].readByteDirect(0, addr + 1) << 8);\n }\n\n /**\n * getLong(addr)\n *\n * For physical addresses only; for linear addresses, use cpu.getLong().\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @return {number} long (32-bit) value at that address\n */\n getLong(addr)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off < this.nBlockLimit - 2) {\n return this.aMemBlocks[iBlock].readLong(off, addr);\n }\n /*\n * I think the previous version of this function tried to be too clever (ie, reading the last\n * long in the current block and the first long in the next block and masking/combining the results),\n * which may have also created some undesirable side-effects for custom memory controllers.\n * This simpler (and probably more reliable) approach is to simply read the long as individual bytes.\n */\n var l = 0;\n var cb = 4, nShift = 0;\n var cbBlock = 4 - (off & 0x3); // (off & 0x3) will be 1, 2 or 3, so cbBlock will be 3, 2, or 1\n while (cb--) {\n l |= (this.aMemBlocks[iBlock].readByte(off++, addr++) << nShift);\n if (!--cbBlock) {\n iBlock = (iBlock + 1) & this.nBlockMask;\n off = 0;\n }\n nShift += 8;\n }\n return l;\n }\n\n /**\n * setByte(addr, b)\n *\n * For physical addresses only; for linear addresses, use cpu.setByte().\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @param {number} b is the byte (8-bit) value to write (we truncate it to 8 bits to be safe)\n */\n setByte(addr, b)\n {\n this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].writeByte(addr & this.nBlockLimit, b & 0xff, addr);\n }\n\n /**\n * setByteDirect(addr, b)\n *\n * This is useful for the Debugger and other components that want to bypass breakpoint detection AND read-only\n * memory protection (for example, this is an interface the ROM component could use to initialize ROM contents).\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @param {number} b is the byte (8-bit) value to write (we truncate it to 8 bits to be safe)\n */\n setByteDirect(addr, b)\n {\n this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].writeByteDirect(addr & this.nBlockLimit, b & 0xff, addr);\n }\n\n /**\n * setShort(addr, w)\n *\n * For physical addresses only; for linear addresses, use cpu.setShort().\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @param {number} w is the word (16-bit) value to write (we truncate it to 16 bits to be safe)\n */\n setShort(addr, w)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off != this.nBlockLimit) {\n this.aMemBlocks[iBlock].writeShort(off, w & 0xffff, addr);\n return;\n }\n this.aMemBlocks[iBlock++].writeByte(off, w & 0xff, addr);\n this.aMemBlocks[iBlock & this.nBlockMask].writeByte(0, (w >> 8) & 0xff, addr + 1);\n }\n\n /**\n * setShortDirect(addr, w)\n *\n * This is useful for the Debugger and other components that want to bypass breakpoint detection AND read-only\n * memory protection (for example, this is an interface the ROM component could use to initialize ROM contents).\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @param {number} w is the word (16-bit) value to write (we truncate it to 16 bits to be safe)\n */\n setShortDirect(addr, w)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off != this.nBlockLimit) {\n this.aMemBlocks[iBlock].writeShortDirect(off, w & 0xffff, addr);\n return;\n }\n this.aMemBlocks[iBlock++].writeByteDirect(off, w & 0xff, addr);\n this.aMemBlocks[iBlock & this.nBlockMask].writeByteDirect(0, (w >> 8) & 0xff, addr + 1);\n }\n\n /**\n * setLong(addr, l)\n *\n * For physical addresses only; for linear addresses, use cpu.setLong().\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @param {number} l is the long (32-bit) value to write\n */\n setLong(addr, l)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off < this.nBlockLimit - 2) {\n this.aMemBlocks[iBlock].writeLong(off, l);\n return;\n }\n /*\n * I think the previous version of this function tried to be too clever (ie, reading and rewriting\n * the last long in the current block, and then reading and rewriting the first long in the next\n * block), which may have also created some undesirable side-effects for custom memory controllers.\n * This simpler (and probably more reliable) approach is to simply write the long as individual bytes.\n */\n var cb = 4;\n var cbBlock = 4 - (off & 0x3); // (off & 0x3) will be 1, 2 or 3, so cbBlock will be 3, 2, or 1\n while (cb--) {\n this.aMemBlocks[iBlock].writeByte(off++, l & 0xff, addr++);\n if (!--cbBlock) {\n iBlock = (iBlock + 1) & this.nBlockMask;\n off = 0;\n }\n l >>>= 8;\n }\n }\n\n /**\n * addBackTrackObject(obj, bto, off)\n *\n * If bto is null, then we create bto (ie, an object that wraps obj and records off).\n *\n * If bto is NOT null, then we verify that off is within the given bto's range; if not,\n * then we must create a new bto and return that instead.\n *\n * @this {Bus}\n * @param {Object} obj\n * @param {BackTrack|null} bto\n * @param {number} off (the offset within obj that this wrapper object is relative to)\n * @return {BackTrack|null}\n */\n addBackTrackObject(obj, bto, off)\n {\n if (BACKTRACK && obj) {\n var cbtObjects = this.abtObjects.length;\n if (!bto) {\n /*\n * Try the most recently created bto, on the off-chance it's what the caller needs\n */\n if (this.ibtLastAlloc >= 0) bto = this.abtObjects[this.ibtLastAlloc];\n }\n if (!bto || bto.obj != obj || off < bto.off || off >= bto.off + Bus.BTINFO.OFF_MAX) {\n\n bto = {obj: obj, off: off, slot: 0, refs: 0};\n\n var slot;\n if (!this.cbtDeletions) {\n slot = cbtObjects;\n } else {\n for (slot = this.ibtLastDelete; slot < cbtObjects; slot++) {\n var btoTest = this.abtObjects[slot];\n if (!btoTest || !btoTest.refs && !this.isBackTrackWeak(slot << Bus.BTINFO.SLOT_SHIFT)) {\n this.ibtLastDelete = slot + 1;\n this.cbtDeletions--;\n break;\n }\n }\n /*\n * There's no longer any guarantee that simply because cbtDeletions was non-zero that there WILL\n * be an available (existing) slot, because cbtDeletions also counts weak references that may still\n * be weak.\n *\n *\n */\n }\n /*\n * I hit the following error after running in a machine with lots of disk activity:\n *\n * Error: assertion failure in deskpro386.bus\n * at Bus.Component.assert (http://pcjs:8088/modules/shared/lib/component.js:732:31)\n * at Bus.addBackTrackObject (http://pcjs:8088/modules/pcx86/lib/bus.js:980:18)\n * at onATCReadData (http://pcjs:8088/modules/pcx86/lib/hdc.js:1410:35)\n * at HDC.readData (http://pcjs:8088/modules/pcx86/lib/hdc.js:2573:23)\n * at HDC.inATCByte (http://pcjs:8088/modules/pcx86/lib/hdc.js:1398:20)\n * at HDC.inATCData (http://pcjs:8088/modules/pcx86/lib/hdc.js:1487:17)\n * at Bus.checkPortInputNotify (http://pcjs:8088/modules/pcx86/lib/bus.js:1457:38)\n * at CPUX86.INSw (http://pcjs:8088/modules/pcx86/lib/x86ops.js:1640:26)\n * at CPUX86.stepCPU (http://pcjs:8088/modules/pcx86/lib/cpux86.js:4637:37)\n * at CPUX86.CPU.runCPU (http://pcjs:8088/modules/pcx86/lib/cpu.js:1014:22)\n *\n * TODO: Investigate. For now, BACKTRACK is completely disabled (in part because it also needs\n * to be revamped for machines with paging enabled).\n */\n\n this.ibtLastAlloc = slot;\n bto.slot = slot + 1;\n if (slot == cbtObjects) {\n this.abtObjects.push(bto);\n } else {\n this.abtObjects[slot] = bto;\n }\n }\n return bto;\n }\n return null;\n }\n\n /**\n * getBackTrackIndex(bto, off)\n *\n * @this {Bus}\n * @param {BackTrack|null} bto\n * @param {number} off\n * @return {number}\n */\n getBackTrackIndex(bto, off)\n {\n var bti = 0;\n if (BACKTRACK && bto) {\n bti = (bto.slot << Bus.BTINFO.SLOT_SHIFT) | Bus.BTINFO.TYPE_DATA | (off - bto.off);\n }\n return bti;\n }\n\n /**\n * writeBackTrackObject(addr, bto, off)\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @param {BackTrack|null} bto\n * @param {number} off\n */\n writeBackTrackObject(addr, bto, off)\n {\n if (BACKTRACK && bto) {\n\n var bti = (bto.slot << Bus.BTINFO.SLOT_SHIFT) | Bus.BTINFO.TYPE_DATA | (off - bto.off);\n this.writeBackTrack(addr, bti);\n }\n }\n\n /**\n * readBackTrack(addr)\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @return {number}\n */\n readBackTrack(addr)\n {\n if (BACKTRACK) {\n return this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].readBackTrack(addr & this.nBlockLimit);\n }\n return 0;\n }\n\n /**\n * writeBackTrack(addr, bti)\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @param {number} bti\n */\n writeBackTrack(addr, bti)\n {\n if (BACKTRACK) {\n var slot = bti >>> Bus.BTINFO.SLOT_SHIFT;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n var btiPrev = this.aMemBlocks[iBlock].writeBackTrack(addr & this.nBlockLimit, bti);\n var slotPrev = btiPrev >>> Bus.BTINFO.SLOT_SHIFT;\n if (slot != slotPrev) {\n this.aMemBlocks[iBlock].modBackTrack(true);\n if (btiPrev && slotPrev) {\n var btoPrev = this.abtObjects[slotPrev-1];\n if (!btoPrev) {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages.WARN)) {\n this.dbg.message(\"writeBackTrack(%\" + Str.toHex(addr) + ',' + Str.toHex(bti) + \"): previous index (\" + Str.toHex(btiPrev) + \") refers to empty slot (\" + slotPrev + \")\");\n }\n }\n else if (btoPrev.refs <= 0) {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages.WARN)) {\n this.dbg.message(\"writeBackTrack(%\" + Str.toHex(addr) + ',' + Str.toHex(bti) + \"): previous index (\" + Str.toHex(btiPrev) + \") refers to object with bad ref count (\" + btoPrev.refs + \")\");\n }\n } else if (!--btoPrev.refs) {\n /*\n * We used to just slam a null into the previous slot and consider it gone, but there may still\n * be \"weak references\" to that slot (ie, it may still be associated with a register bti).\n *\n * The easiest way to handle weak references is to leave the slot allocated, with the object's ref\n * count sitting at zero, and change addBackTrackObject() to look for both empty slots AND non-empty\n * slots with a ref count of zero; in the latter case, it should again check for weak references,\n * after which we can re-use the slot if all its weak references are now gone.\n */\n if (!this.isBackTrackWeak(btiPrev)) this.abtObjects[slotPrev-1] = null;\n /*\n * TODO: Consider what the appropriate trigger should be for resetting ibtLastDelete to zero;\n * if we don't OCCASIONALLY set it to zero, we may never clear out obsolete weak references,\n * whereas if we ALWAYS set it to zero, we may be forcing addBackTrackObject() to scan the entire\n * table too often.\n *\n * I'd prefer to do something like this:\n *\n * if (this.ibtLastDelete > slotPrev-1) this.ibtLastDelete = slotPrev-1;\n *\n * or even this:\n *\n * if (this.ibtLastDelete > slotPrev-1) this.ibtLastDelete = 0;\n *\n * But neither one of those guarantees that we will at least occasionally scan the entire table.\n */\n this.ibtLastDelete = 0;\n this.cbtDeletions++;\n }\n }\n if (bti && slot) {\n var bto = this.abtObjects[slot-1];\n if (bto) {\n\n bto.refs++;\n }\n }\n }\n }\n }\n\n /**\n * isBackTrackWeak(bti)\n *\n * @param {number} bti\n * @returns {boolean} true if the given bti is still referenced by a register, false if not\n */\n isBackTrackWeak(bti)\n {\n var bt = this.cpu.backTrack;\n var slot = bti >> Bus.BTINFO.SLOT_SHIFT;\n return (bt.btiAL >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiAH >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiBL >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiBH >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiCL >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiCH >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiDL >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiDH >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiBPLo >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiBPHi >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiSILo >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiSIHi >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiDILo >> Bus.BTINFO.SLOT_SHIFT == slot ||\n bt.btiDIHi >> Bus.BTINFO.SLOT_SHIFT == slot\n );\n }\n\n /**\n * updateBackTrackCode(addr, bti)\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @param {number} bti\n */\n updateBackTrackCode(addr, bti)\n {\n if (BACKTRACK) {\n if (bti & Bus.BTINFO.TYPE_DATA) {\n bti = (bti & ~Bus.BTINFO.TYPE_MASK) | Bus.BTINFO.TYPE_COUNT_INC;\n } else if ((bti & Bus.BTINFO.TYPE_MASK) < Bus.BTINFO.TYPE_COUNT_MAX) {\n bti += Bus.BTINFO.TYPE_COUNT_INC;\n } else {\n return;\n }\n this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].writeBackTrack(addr & this.nBlockLimit, bti);\n }\n }\n\n /**\n * getBackTrackObject(bti)\n *\n * @this {Bus}\n * @param {number} bti\n * @return {Object|null}\n */\n getBackTrackObject(bti)\n {\n if (BACKTRACK) {\n var slot = bti >>> Bus.BTINFO.SLOT_SHIFT;\n if (slot) return this.abtObjects[slot-1];\n }\n return null;\n }\n\n /**\n * getBackTrackInfo(bti, fSymbol, fNearest)\n *\n * @this {Bus}\n * @param {number} bti\n * @param {boolean} [fSymbol] (true to return only symbol)\n * @param {boolean} [fNearest] (true to return nearest symbol)\n * @return {string|null}\n */\n getBackTrackInfo(bti, fSymbol, fNearest)\n {\n if (BACKTRACK) {\n var bto = this.getBackTrackObject(bti);\n if (bto) {\n var off = bti & Bus.BTINFO.OFF_MASK;\n var file = bto.obj.file;\n if (file) {\n\n return file.getSymbol(bto.obj.offFile + off, fNearest);\n }\n if (!fSymbol || fNearest) {\n if (bto.obj.idComponent) {\n return bto.obj.idComponent + '+' + Str.toHex(bto.off + off, 0, true);\n }\n }\n }\n }\n return null;\n }\n\n /**\n * getSymbol(addr, fNearest)\n *\n * @this {Bus}\n * @param {number} addr\n * @param {boolean} [fNearest] (true to return nearest symbol)\n * @return {string|null}\n */\n getSymbol(addr, fNearest)\n {\n return BACKTRACK? this.getBackTrackInfo(this.readBackTrack(addr), true, fNearest) : null;\n }\n\n /**\n * saveMemory(fAll)\n *\n * The only memory blocks we save are those marked as dirty, but most likely all of RAM will have been marked dirty,\n * and even if our dirty-memory flags were as smart as our dirty-sector flags (ie, were set only when a write changed\n * what was already there), it's unlikely that would reduce the number of RAM blocks we must save/restore. At least\n * all the ROM blocks should be clean (except in the unlikely event that the Debugger was used to modify them).\n *\n * All dirty blocks will be stored in a single array, as pairs of block numbers and data arrays, like so:\n *\n * [iBlock0, [dw0, dw1, ...], iBlock1, [dw0, dw1, ...], ...]\n *\n * In a normal 4Kb block, there will be 1K DWORD values in the data array. Remember that each DWORD is a signed 32-bit\n * integer (because they are formed using bitwise operator rather than floating-point math operators), so don't be\n * surprised to see negative numbers in the data.\n *\n * The above example assumes \"uncompressed\" data arrays. If we choose to use \"compressed\" data arrays, the data arrays\n * will look like:\n *\n * [count0, dw0, count1, dw1, ...]\n *\n * where each count indicates how many times the following DWORD value occurs. A data array length less than 1K indicates\n * that it's compressed, since we'll only store them in compressed form if they actually shrank, and we'll use State\n * helper methods compress() and decompress() to create and expand the compressed data arrays.\n *\n * @this {Bus}\n * @param {boolean} [fAll] (true to save all non-ROM memory blocks, regardless of their dirty flags)\n * @return {Array} a\n */\n saveMemory(fAll)\n {\n var i = 0;\n var a = [];\n\n /*\n * A quick-and-dirty work-around for 32-bit bus machines, to ensure that all blocks in the 2nd Mb are\n * mapped in before we save. We do this by forcing A20 on, and then turning it off again before we leave.\n */\n var fA20 = this.getA20();\n if (!fA20) this.setA20(true);\n\n for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {\n var block = this.aMemBlocks[iBlock];\n /*\n * We have to check both fDirty and fDirtyEver, because we may have called cleanMemory() on some of\n * the memory blocks (eg, video memory), and while cleanMemory() will clear a dirty block's fDirty flag,\n * it also sets the dirty block's fDirtyEver flag, which is left set for the lifetime of the machine.\n */\n if (fAll && block.type != Memory.TYPE.ROM || block.fDirty || block.fDirtyEver) {\n a[i++] = iBlock;\n a[i++] = State.compress(block.save());\n }\n }\n\n if (!fA20) this.setA20(false);\n a[i] = fA20;\n\n return a;\n }\n\n /**\n * restoreMemory(a)\n *\n * This restores the contents of all Memory blocks; called by CPUX86.restore().\n *\n * In theory, we ONLY have to save/restore block contents. Other block attributes,\n * like the type, the memory controller (if any), and the active memory access functions,\n * should already be restored, since every component (re)allocates all the memory blocks\n * it was using when it's restored. And since the CPU is guaranteed to be the last\n * component to be restored, all those blocks (and their attributes) should be in place now.\n *\n * See saveMemory() for more information on how the memory block contents are saved.\n *\n * @this {Bus}\n * @param {Array} a\n * @return {boolean} true if successful, false if not\n */\n restoreMemory(a)\n {\n var i;\n for (i = 0; i < a.length - 1; i += 2) {\n var iBlock = a[i];\n var adw = a[i+1];\n if (adw && adw.length < this.nBlockLen) {\n adw = State.decompress(adw, this.nBlockLen);\n }\n var block = this.aMemBlocks[iBlock];\n if (!block || !block.restore(adw)) {\n /*\n * Either the block to restore hasn't been allocated, indicating a change in the machine\n * configuration since it was last saved (the most likely explanation) or there's some internal\n * inconsistency (eg, the block size is wrong).\n */\n Component.error(\"Unable to restore memory block \" + iBlock);\n return false;\n }\n }\n if (a[i] !== undefined) this.setA20(a[i]);\n return true;\n }\n\n /**\n * addPortInputBreak(port)\n *\n * @this {Bus}\n * @param {number|null} [port]\n * @return {boolean} true if break on port input enabled, false if disabled\n */\n addPortInputBreak(port)\n {\n if (port == null) {\n this.fPortInputBreakAll = !this.fPortInputBreakAll;\n return this.fPortInputBreakAll;\n }\n if (this.aPortInputNotify[port] === undefined) {\n this.aPortInputNotify[port] = [null, false];\n }\n this.aPortInputNotify[port][1] = !this.aPortInputNotify[port][1];\n return this.aPortInputNotify[port][1];\n }\n\n /**\n * addPortInputNotify(start, end, fn)\n *\n * Add a port input-notification handler to the list of such handlers.\n *\n * @this {Bus}\n * @param {number} start port address\n * @param {number} end port address\n * @param {function(number,number)} fn is called with the port and LIP values at the time of the input\n */\n addPortInputNotify(start, end, fn)\n {\n if (fn !== undefined) {\n for (var port = start; port <= end; port++) {\n if (this.aPortInputNotify[port] !== undefined) {\n Component.warning(\"Input port \" + Str.toHexWord(port) + \" already registered\");\n continue;\n }\n this.aPortInputNotify[port] = [fn, false];\n if (MAXDEBUG) this.log(\"addPortInputNotify(\" + Str.toHexWord(port) + \")\");\n }\n }\n }\n\n /**\n * addPortInputTable(component, table, offset)\n *\n * Add port input-notification handlers from the specified table (a batch version of addPortInputNotify)\n *\n * @this {Bus}\n * @param {Component} component\n * @param {Object} table\n * @param {number} [offset] is an optional port offset\n */\n addPortInputTable(component, table, offset)\n {\n if (offset === undefined) offset = 0;\n for (var port in table) {\n this.addPortInputNotify(+port + offset, +port + offset, table[port].bind(component));\n }\n }\n\n /**\n * addPortInputWidth(port, size)\n *\n * By default, all input ports are 1 byte wide; ports that are wider must call this function.\n *\n * @this {Bus}\n * @param {number} port\n * @param {number} size (1, 2 or 4)\n */\n addPortInputWidth(port, size)\n {\n this.aPortInputWidth[port] = size;\n }\n\n /**\n * checkPortInputNotify(port, size, addrLIP)\n *\n * @this {Bus}\n * @param {number} port\n * @param {number} size (1, 2 or 4)\n * @param {number} [addrLIP] is the LIP value at the time of the input\n * @return {number} simulated port data\n *\n * NOTE: It seems that parts of the ROM BIOS (like the RS-232 probes around F000:E5D7 in the 5150 BIOS)\n * assume that ports for non-existent hardware return 0xff rather than 0x00, hence my new default (0xff) below.\n */\n checkPortInputNotify(port, size, addrLIP)\n {\n var data = 0, shift = 0;\n\n while (size > 0) {\n\n var aNotify = this.aPortInputNotify[port];\n var sizePort = this.aPortInputWidth[port] || 1;\n var maskPort = (sizePort == 1? 0xff : (sizePort == 2? 0xffff : -1));\n var dataPort = maskPort;\n\n /*\n * TODO: We need to decide what to do about 8-bit I/O to a 16-bit port (ditto for 16-bit I/O\n * to a 32-bit port). We probably should pass the size through to the aNotify[0] handler,\n * and let it decide what to do, but I don't feel like changing all the I/O handlers right now.\n * The good news, at least, is that the 8-bit handlers would not have to do anything special.\n * This assert will warn us if this is a pressing need.\n */\n\n\n if (BACKTRACK) {\n this.cpu.backTrack.btiIO = 0;\n }\n\n if (aNotify !== undefined) {\n if (aNotify[0]) {\n dataPort = aNotify[0](port, addrLIP);\n if (dataPort == null) {\n dataPort = maskPort;\n } else {\n dataPort &= maskPort;\n }\n }\n if (DEBUGGER && this.dbg && this.fPortInputBreakAll != aNotify[1]) {\n this.dbg.checkPortInput(port, size, dataPort);\n }\n }\n else {\n if (DEBUGGER && this.dbg) {\n this.dbg.messageIO(this, port, null, addrLIP);\n if (this.fPortInputBreakAll) this.dbg.checkPortInput(port, size, dataPort);\n }\n }\n\n data |= dataPort << shift;\n shift += (sizePort << 3);\n port += sizePort;\n size -= sizePort;\n }\n\n\n return data;\n }\n\n /**\n * addPortOutputBreak(port)\n *\n * @this {Bus}\n * @param {number|null} [port]\n * @return {boolean} true if break on port output enabled, false if disabled\n */\n addPortOutputBreak(port)\n {\n if (port == null) {\n this.fPortOutputBreakAll = !this.fPortOutputBreakAll;\n return this.fPortOutputBreakAll;\n }\n if (this.aPortOutputNotify[port] === undefined) {\n this.aPortOutputNotify[port] = [null, false];\n }\n this.aPortOutputNotify[port][1] = !this.aPortOutputNotify[port][1];\n return this.aPortOutputNotify[port][1];\n }\n\n /**\n * addPortOutputNotify(start, end, fn)\n *\n * Add a port output-notification handler to the list of such handlers.\n *\n * @this {Bus}\n * @param {number} start port address\n * @param {number} end port address\n * @param {function(number,number)} fn is called with the port and LIP values at the time of the output\n */\n addPortOutputNotify(start, end, fn)\n {\n if (fn !== undefined) {\n for (var port = start; port <= end; port++) {\n if (this.aPortOutputNotify[port] !== undefined) {\n Component.warning(\"Output port \" + Str.toHexWord(port) + \" already registered\");\n continue;\n }\n this.aPortOutputNotify[port] = [fn, false];\n if (MAXDEBUG) this.log(\"addPortOutputNotify(\" + Str.toHexWord(port) + \")\");\n }\n }\n }\n\n /**\n * addPortOutputTable(component, table, offset)\n *\n * Add port output-notification handlers from the specified table (a batch version of addPortOutputNotify)\n *\n * @this {Bus}\n * @param {Component} component\n * @param {Object} table\n * @param {number} [offset] is an optional port offset\n */\n addPortOutputTable(component, table, offset)\n {\n if (offset === undefined) offset = 0;\n for (var port in table) {\n this.addPortOutputNotify(+port + offset, +port + offset, table[port].bind(component));\n }\n }\n\n /**\n * addPortOutputWidth(port, size)\n *\n * By default, all output ports are 1 byte wide; ports that are wider must call this function.\n *\n * @this {Bus}\n * @param {number} port\n * @param {number} size (1, 2 or 4)\n */\n addPortOutputWidth(port, size)\n {\n this.aPortOutputWidth[port] = size;\n }\n\n /**\n * checkPortOutputNotify(port, size, data, addrLIP)\n *\n * @this {Bus}\n * @param {number} port\n * @param {number} size\n * @param {number} data\n * @param {number} [addrLIP] is the LIP value at the time of the output\n */\n checkPortOutputNotify(port, size, data, addrLIP)\n {\n var shift = 0;\n\n while (size > 0) {\n\n var aNotify = this.aPortOutputNotify[port];\n var sizePort = this.aPortOutputWidth[port] || 1;\n var maskPort = (sizePort == 1? 0xff : (sizePort == 2? 0xffff : -1));\n var dataPort = (data >>>= shift) & maskPort;\n\n /*\n * TODO: We need to decide what to do about 8-bit I/O to a 16-bit port (ditto for 16-bit I/O\n * to a 32-bit port). We probably should pass the size through to the aNotify[0] handler,\n * and let it decide what to do, but I don't feel like changing all the I/O handlers right now.\n * The good news, at least, is that the 8-bit handlers would not have to do anything special.\n * This assert will warn us if this is a pressing need.\n */\n\n\n if (aNotify !== undefined) {\n if (aNotify[0]) {\n aNotify[0](port, dataPort, addrLIP);\n }\n if (DEBUGGER && this.dbg && this.fPortOutputBreakAll != aNotify[1]) {\n this.dbg.checkPortOutput(port, size, dataPort);\n }\n }\n else {\n if (DEBUGGER && this.dbg) {\n this.dbg.messageIO(this, port, dataPort, addrLIP);\n if (this.fPortOutputBreakAll) this.dbg.checkPortOutput(port, size, dataPort);\n }\n }\n\n shift += (sizePort << 3);\n port += sizePort;\n size -= sizePort;\n }\n\n }\n\n /**\n * reportError(op, addr, size, fQuiet)\n *\n * @this {Bus}\n * @param {number} op\n * @param {number} addr\n * @param {number} size\n * @param {boolean} [fQuiet] (true if any error should be quietly logged)\n * @return {boolean} false\n */\n reportError(op, addr, size, fQuiet)\n {\n var sError = \"Memory block error (\" + op + \": \" + Str.toHex(addr) + \",\" + Str.toHex(size) + \")\";\n if (fQuiet) {\n if (this.dbg) {\n this.dbg.message(sError);\n } else {\n this.log(sError);\n }\n } else {\n Component.error(sError);\n }\n return false;\n }\n\n /**\n * getLongDirect(addr)\n *\n * This is useful for the Debugger and other components that want to bypass getLong() breakpoint detection.\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @return {number} long (32-bit) value at that address\n *\n getLongDirect(addr)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off < this.nBlockLimit - 2) {\n return this.aMemBlocks[iBlock].readLongDirect(off, addr);\n }\n //\n // I think the previous version of this function tried to be too clever (ie, reading the last\n // long in the current block and the first long in the next block and masking/combining the results),\n // which may have also created some undesirable side-effects for custom memory controllers.\n // This simpler (and probably more reliable) approach is to simply read the long as individual bytes.\n //\n var l = 0;\n var cb = 4, nShift = 0;\n var cbBlock = 4 - (off & 0x3); // (off & 0x3) will be 1, 2 or 3, so cbBlock will be 3, 2, or 1\n while (cb--) {\n l |= (this.aMemBlocks[iBlock].readByteDirect(off++, addr++) << nShift);\n if (!--cbBlock) {\n iBlock = (iBlock + 1) & this.nBlockMask;\n off = 0;\n }\n nShift += 8;\n }\n return l;\n }\n */\n\n /**\n * setLongDirect(addr, l)\n *\n * This is useful for the Debugger and other components that want to bypass breakpoint detection AND read-only\n * memory protection (for example, this is an interface the ROM component could use to initialize ROM contents).\n *\n * @this {Bus}\n * @param {number} addr is a physical address\n * @param {number} l is the long (32-bit) value to write\n *\n setLongDirect(addr, l)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n if (off < this.nBlockLimit - 2) {\n this.aMemBlocks[iBlock].writeLongDirect(off, l, addr);\n return;\n }\n //\n // I think the previous version of this function tried to be too clever (ie, reading and rewriting\n // the last long in the current block, and then reading and rewriting the first long in the next\n // block), which may have also created some undesirable side-effects for custom memory controllers.\n // This simpler (and probably more reliable) approach is to simply write the long as individual bytes.\n //\n var cb = 4;\n var cbBlock = 4 - (off & 0x3); // (off & 0x3) will be 1, 2 or 3, so cbBlock will be 3, 2, or 1\n while (cb--) {\n this.aMemBlocks[iBlock].writeByteDirect(off++, l & 0xff, addr++);\n if (!--cbBlock) {\n iBlock = (iBlock + 1) & this.nBlockMask;\n off = 0;\n }\n l >>>= 8;\n }\n }\n */\n\n /**\n * getBackTrackObjectFromAddr(addr)\n *\n * @this {Bus}\n * @param {number} addr\n * @return {Object|null}\n *\n getBackTrackObjectFromAddr(addr)\n {\n return BACKTRACK? this.getBackTrackObject(this.readBackTrack(addr)) : null;\n }\n */\n\n /**\n * getBackTrackInfoFromAddr(addr)\n *\n * @this {Bus}\n * @param {number} addr\n * @return {string|null}\n *\n getBackTrackInfoFromAddr(addr)\n {\n return BACKTRACK? this.getBackTrackInfo(this.readBackTrack(addr)) : null;\n }\n */\n\n /**\n * removePortInputNotify(start, end)\n *\n * Remove port input-notification handler(s) (to be ENABLED later if needed)\n *\n * @this {Bus}\n * @param {number} start address\n * @param {number} end address\n *\n removePortInputNotify(start, end)\n {\n for (var port = start; port < end; port++) {\n if (this.aPortInputNotify[port]) {\n delete this.aPortInputNotify[port];\n }\n }\n }\n */\n\n /**\n * removePortOutputNotify(start, end)\n *\n * Remove port output-notification handler(s) (to be ENABLED later if needed)\n *\n * @this {Bus}\n * @param {number} start address\n * @param {number} end address\n *\n removePortOutputNotify(start, end)\n {\n for (var port = start; port < end; port++) {\n if (this.aPortOutputNotify[port]) {\n delete this.aPortOutputNotify[port];\n }\n }\n }\n */\n}\n\n/*\n * Data types used by scanMemory()\n */\n\n/**\n * @typedef {number}\n */\nvar BlockInfo;\n\n/**\n * This defines the BlockInfo bit fields used by scanMemory() when it creates the aBlocks array.\n *\n * @typedef {{\n * num: BitField,\n * count: BitField,\n * btmod: BitField,\n * type: BitField\n * }}\n */\nBus.BlockInfo = Usr.defineBitFields({num:20, count:8, btmod:1, type:3});\n\n/**\n * BusInfo object definition (returned by scanMemory())\n *\n * cbTotal: total bytes allocated\n * cBlocks: total Memory blocks allocated\n * aBlocks: array of allocated Memory block numbers\n *\n * @typedef {{\n * cbTotal: number,\n * cBlocks: number,\n * aBlocks: Array.<BlockInfo>\n * }}\n */\nvar BusInfo;\n\nif (BACKTRACK) {\n /**\n * BackTrack object definition\n *\n * obj: reference to the source object (eg, ROM object, Sector object)\n * off: the offset within the source object that this object refers to\n * slot: the slot (+1) in abtObjects which this object currently occupies\n * refs: the number of memory references, as recorded by writeBackTrack()\n *\n * @typedef {{\n * obj: Object,\n * off: number,\n * slot: number,\n * refs: number\n * }}\n */\n var BackTrack;\n\n /*\n * BackTrack indexes are 31-bit values, where bits 0-8 store an object offset (0-511) and bits 16-30 store\n * an object number (1-32767). Object number 0 is reserved for dynamic data (ie, data created independent\n * of any source); examples include zero values produced by instructions such as \"SUB AX,AX\" or \"XOR AX,AX\".\n * We must special-case instructions like that, because even though AX will almost certainly contain some source\n * data prior to the instruction, the result no longer has any connection to the source. Similarly, \"SBB AX,AX\"\n * may produce 0 or -1, depending on carry, but since we don't track the source of individual bits (including the\n * carry flag), AX is now source-less. TODO: This is an argument for maintaining source info on selected flags,\n * even though it would be rather expensive.\n *\n * The 7 middle bits (9-15) record type and access information, as follows:\n *\n * bit 15: set to indicate a \"data\" byte, clear to indicate a \"code\" byte\n *\n * All bytes start out as \"data\" bytes; only once they've been executed do they become \"code\" bytes. For code\n * bytes, the remaining 6 middle bits (9-14) represent an execution count that starts at 1 (on the byte's initial\n * transition from data to code) and tops out at 63.\n *\n * For data bytes, the remaining middle bits indicate any transformations the data has undergone; eg:\n *\n * bit 14: ADD/SUB/INC/DEC\n * bit 13: MUL/DIV\n * bit 12: OR/AND/XOR/NOT\n *\n * We make no attempt to record the original data or the transformation data, only that the transformation occurred.\n *\n * Other middle bits indicate whether the data was ever read and/or written:\n *\n * bit 11: READ\n * bit 10: WRITE\n *\n * Bit 9 is reserved for now.\n */\n Bus.BTINFO = {\n SLOT_MAX: 32768,\n SLOT_SHIFT: 16,\n TYPE_DATA: 0x8000,\n TYPE_ADDSUB: 0x4000,\n TYPE_MULDIV: 0x2000,\n TYPE_LOGICAL: 0x1000,\n TYPE_READ: 0x0800,\n TYPE_WRITE: 0x0400,\n TYPE_COUNT_INC: 0x0200,\n TYPE_COUNT_MAX: 0x7E00,\n TYPE_MASK: 0xFE00,\n TYPE_SHIFT: 9,\n OFF_MAX: 512,\n OFF_MASK: 0x1FF\n };\n}\n\nBus.ERROR = {\n ADD_MEM_INUSE: 1,\n ADD_MEM_BADRANGE: 2,\n SET_MEM_NOCTRL: 3,\n SET_MEM_BADRANGE: 4,\n REM_MEM_BADRANGE: 5\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/memory.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * @class DataView\n * @property {function(number,boolean):number} getUint8\n * @property {function(number,number,boolean)} setUint8\n * @property {function(number,boolean):number} getUint16\n * @property {function(number,number,boolean)} setUint16\n * @property {function(number,boolean):number} getInt32\n * @property {function(number,number,boolean)} setInt32\n */\n\nvar littleEndian = (TYPEDARRAYS? (function() {\n var buffer = new ArrayBuffer(2);\n new DataView(buffer).setUint16(0, 256, true);\n return new Uint16Array(buffer)[0] === 256;\n})() : false);\n\n/**\n * class Memory\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass Memory {\n /**\n * Memory(addr, used, size, type, controller)\n *\n * The Bus component allocates Memory objects so that each has a memory buffer with a\n * block-granular starting address and an address range equal to bus.nBlockSize; however,\n * the size of any given Memory object's underlying buffer can be either zero or bus.nBlockSize;\n * memory read/write functions for empty (buffer-less) blocks are mapped to readNone/writeNone.\n *\n * The Bus allocates empty blocks for the entire address space during initialization, so that\n * any reads/writes to undefined addresses will have no effect. Later, the ROM and RAM\n * components will ask the Bus to allocate memory for specific ranges, and the Bus will allocate\n * as many new blockSize Memory objects as the ranges require. Partial Memory blocks could\n * also be supported in theory, but in practice, they're not.\n *\n * Because Memory blocks now allow us to have a \"sparse\" address space, we could choose to\n * take the memory hit of allocating 4K arrays per block, where each element stores only one byte,\n * instead of the more frugal but slightly slower approach of allocating arrays of 32-bit dwords\n * (LONGARRAYS) and shifting/masking bytes/words to/from dwords; in theory, byte accesses would\n * be faster and word accesses somewhat less faster.\n *\n * However, preliminary testing of that feature (BYTEARRAYS) did not yield significantly faster\n * performance, so it is OFF by default to minimize our memory consumption. Using TYPEDARRAYS\n * would seem best, but as discussed in defines.js, it's off by default, because it doesn't perform\n * as well as LONGARRAYS; the other advantage of TYPEDARRAYS is that it should theoretically use\n * about 1/2 the memory of LONGARRAYS (32-bit elements vs 64-bit numbers), but I value speed over\n * size at this point. Also, not all JavaScript implementations support TYPEDARRAYS (IE9 is probably\n * the only real outlier: it lacks typed arrays but otherwise has all the necessary HTML5 support).\n *\n * WARNING: Since Memory blocks are low-level objects that have no UI requirements, they\n * do not inherit from the Component class, so if you want to use any Component class methods,\n * such as Component.assert(), use the corresponding Debugger methods instead (assuming a debugger\n * is available).\n *\n * @this {Memory}\n * @param {number|null} [addr] of lowest used address in block\n * @param {number} [used] portion of block in bytes (0 for none); must be a multiple of 4\n * @param {number} [size] of block's buffer in bytes (0 for none); must be a multiple of 4\n * @param {number} [type] is one of the Memory.TYPE constants (default is Memory.TYPE.NONE)\n * @param {Controller} [controller] is an optional memory controller component\n * @param {CPUX86} [cpu] is required for UNPAGED memory blocks, so that the CPU can map it to a PAGED block\n */\n constructor(addr, used, size, type, controller, cpu)\n {\n var i;\n this.id = (Memory.idBlock += 2);\n this.adw = null;\n this.offset = 0;\n this.addr = addr;\n this.used = used;\n this.size = size || 0;\n this.type = type || Memory.TYPE.NONE;\n this.fReadOnly = (type == Memory.TYPE.ROM);\n this.controller = null;\n this.cpu = cpu; // if a CPU reference is provided, then this must be an UNPAGED Memory block allocation\n this.copyBreakpoints(); // initialize the block's Debugger info (eg, breakpoint totals); the caller will reinitialize\n\n /*\n * TODO: Study the impact of dirty block tracking. As noted in the paged block handlers (eg, writeBytePLE),\n * the original purposes were to allow saveMemory() to save only dirty blocks, and to enable the Video component\n * to quickly detect changes to the video buffer. But the benefit to saveMemory() is minimal, and the Video\n * component has other options; for example, it now uses a custom memory controller for all EGA/VGA video modes,\n * which performs its own dirty block tracking, and that could easily be extended to the older MDA/CGA video modes,\n * which still use conventional memory blocks. Alternatively, we could restrict the use of dirty block tracking\n * to certain memory types (eg, VIDEO memory).\n *\n * However, a quick test with dirty block tracking disabled didn't yield a noticeable improvement in performance,\n * so I think the overhead of our block-based architecture is swamping the impact of these micro-updates.\n */\n this.fDirty = this.fDirtyEver = false;\n\n if (BACKTRACK) {\n if (!size || controller) {\n this.fModBackTrack = false;\n this.readBackTrack = this.readBackTrackNone;\n this.writeBackTrack = this.writeBackTrackNone;\n this.modBackTrack = this.modBackTrackNone;\n } else {\n this.fModBackTrack = true;\n this.readBackTrack = this.readBackTrackIndex;\n this.writeBackTrack = this.writeBackTrackIndex;\n this.modBackTrack = this.modBackTrackIndex;\n this.abtIndexes = new Array(size);\n for (i = 0; i < size; i++) this.abtIndexes[i] = 0;\n }\n }\n\n /*\n * For empty memory blocks, all we need to do is ensure all access functions\n * are mapped to \"none\" handlers (or \"unpaged\" handlers if paging is enabled).\n */\n if (!size) {\n this.setAccess();\n return;\n }\n\n /*\n * When a controller is specified, the controller must provide a buffer,\n * via getMemoryBuffer(), and memory access functions, via getMemoryAccess().\n */\n if (controller) {\n this.controller = controller;\n var a = controller.getMemoryBuffer(addr|0);\n this.adw = a[0];\n this.offset = a[1];\n this.setAccess(controller.getMemoryAccess());\n return;\n }\n\n /*\n * This is the normal case: allocate a buffer that provides 8 bits of data per address;\n * no controller is required because our default memory access functions (see afnMemory)\n * know how to deal with this simple 1-1 mapping of addresses to bytes and words.\n *\n * TODO: Consider initializing the memory array to random (or pseudo-random) values in DEBUG\n * mode; pseudo-random might be best, to help make any bugs reproducible.\n */\n if (TYPEDARRAYS) {\n this.buffer = new ArrayBuffer(size);\n this.dv = new DataView(this.buffer, 0, size);\n /*\n * If littleEndian is true, we can use ab[], aw[] and adw[] directly; well, we can use them\n * whenever the offset is a multiple of 1, 2 or 4, respectively. Otherwise, we must fallback to\n * dv.getUint8()/dv.setUint8(), dv.getUint16()/dv.setUint16() and dv.getInt32()/dv.setInt32().\n */\n this.ab = new Uint8Array(this.buffer, 0, size);\n this.aw = new Uint16Array(this.buffer, 0, size >> 1);\n this.adw = new Int32Array(this.buffer, 0, size >> 2);\n this.setAccess(littleEndian? Memory.afnArrayLE : Memory.afnArrayBE);\n } else {\n if (BYTEARRAYS) {\n this.ab = new Array(size);\n } else {\n /*\n * NOTE: This is the default mode of operation (!TYPEDARRAYS && !BYTEARRAYS), because it\n * seems to provide the best performance; and although in theory, that performance might\n * come at twice the overhead of TYPEDARRAYS, it's increasingly likely that the JavaScript\n * runtime will notice that all we ever store are 32-bit values, and optimize accordingly.\n */\n this.adw = new Array(size >> 2);\n for (i = 0; i < this.adw.length; i++) this.adw[i] = 0;\n }\n this.setAccess(Memory.afnMemory);\n }\n }\n\n /**\n * init(addr)\n *\n * Quick reinitializer when reusing a Memory block.\n *\n * @this {Memory}\n * @param {number} addr\n */\n init(addr)\n {\n this.addr = addr;\n }\n\n /**\n * clone(mem, type)\n *\n * Converts the current Memory block (this) into a clone of the given Memory block (mem),\n * and optionally overrides the current block's type with the specified type.\n *\n * @this {Memory}\n * @param {Memory} mem\n * @param {number} [type]\n * @param {DebuggerX86} [dbg]\n */\n clone(mem, type, dbg)\n {\n /*\n * Original memory block IDs are even; cloned memory block IDs are odd;\n * the original ID of the current block is lost, but that's OK, since it was presumably\n * produced merely to become a clone.\n */\n this.id = mem.id | 0x1;\n this.used = mem.used;\n this.size = mem.size;\n if (type) {\n this.type = type;\n this.fReadOnly = (type == Memory.TYPE.ROM);\n }\n if (TYPEDARRAYS) {\n this.buffer = mem.buffer;\n this.dv = mem.dv;\n this.ab = mem.ab;\n this.aw = mem.aw;\n this.adw = mem.adw;\n this.setAccess(littleEndian? Memory.afnArrayLE : Memory.afnArrayBE);\n } else {\n if (BYTEARRAYS) {\n this.ab = mem.ab;\n } else {\n this.adw = mem.adw;\n }\n this.setAccess(Memory.afnMemory);\n }\n this.copyBreakpoints(dbg, mem);\n }\n\n /**\n * save()\n *\n * This gets the contents of a Memory block as an array of 32-bit values; used by Bus.saveMemory(),\n * which in turn is called by CPUX86.save().\n *\n * Memory blocks with custom memory controllers do NOT save their contents; that's the responsibility\n * of the controller component.\n *\n * @this {Memory}\n * @return {Array|Int32Array|null}\n */\n save()\n {\n var adw, i;\n if (this.controller) {\n adw = null;\n }\n else if (BYTEARRAYS) {\n adw = new Array(this.size >> 2);\n var off = 0;\n for (i = 0; i < adw.length; i++) {\n adw[i] = this.ab[off] | (this.ab[off + 1] << 8) | (this.ab[off + 2] << 16) | (this.ab[off + 3] << 24);\n off += 4;\n }\n }\n else if (TYPEDARRAYS) {\n /*\n * It might be tempting to just return a copy of Int32Array(this.buffer, 0, this.size >> 2),\n * but we can't be sure of the \"endianness\" of an Int32Array -- which would be OK if the array\n * was always saved/restored on the same machine, but there's no guarantee of that, either.\n * So we use getInt32() and require little-endian values.\n *\n * Moreover, an Int32Array isn't treated by JSON.stringify() and JSON.parse() exactly like\n * a normal array; it's serialized as an Object rather than an Array, so it lacks a \"length\"\n * property and causes problems for State.store() and State.parse().\n */\n adw = new Array(this.size >> 2);\n for (i = 0; i < adw.length; i++) {\n adw[i] = this.dv.getInt32(i << 2, true);\n }\n }\n else {\n adw = this.adw;\n }\n return adw;\n }\n\n /**\n * restore(adw)\n *\n * This restores the contents of a Memory block from an array of 32-bit values;\n * used by Bus.restoreMemory(), which is called by CPUX86.restore(), after all other\n * components have been restored and thus all Memory blocks have been allocated\n * by their respective components.\n *\n * @this {Memory}\n * @param {Array|null} adw\n * @return {boolean} true if successful, false if block size mismatch\n */\n restore(adw)\n {\n if (this.controller) {\n return (adw == null);\n }\n /*\n * At this point, it's a consistency error for adw to be null; it's happened once already,\n * when there was a restore bug in the Video component that added the frame buffer at the video\n * card's \"spec'ed\" address instead of the programmed address, so there were no controller-owned\n * memory blocks installed at the programmed address, and so we arrived here at a block with\n * no controller AND no data.\n */\n\n\n if (adw && this.size == adw.length << 2) {\n var i;\n if (BYTEARRAYS) {\n var off = 0;\n for (i = 0; i < adw.length; i++) {\n this.ab[off] = adw[i] & 0xff;\n this.ab[off + 1] = (adw[i] >> 8) & 0xff;\n this.ab[off + 2] = (adw[i] >> 16) & 0xff;\n this.ab[off + 3] = (adw[i] >> 24) & 0xff;\n off += 4;\n }\n } else if (TYPEDARRAYS) {\n for (i = 0; i < adw.length; i++) {\n this.dv.setInt32(i << 2, adw[i], true);\n }\n } else {\n this.adw = adw;\n }\n this.fDirty = true;\n return true;\n }\n return false;\n }\n\n /**\n * setAccess(afn, fDirect)\n *\n * The afn parameter should be a 6-entry function table containing two byte handlers, two\n * short handlers, and two long handlers. See the static afnMemory table for an example.\n *\n * If no function table is specified, a default is selected based on the Memory type;\n * similarly, any undefined entries in the table are filled with default handlers that fall\n * back to the byte handlers, and if one or both byte handlers are undefined, they default\n * to handlers that simply ignore the access.\n *\n * fDirect indicates that both the default AND the direct handlers should be updated. Direct\n * handlers normally match the default handlers, except when \"checked\" handlers are installed;\n * this allows \"checked\" handlers to know where to dispatch the call after performing checks.\n * Examples of checks are read/write breakpoints, but it's really up to the Debugger to decide\n * what the check consists of.\n *\n * @this {Memory}\n * @param {Array.<function()>} [afn] function table\n * @param {boolean} [fDirect] (true to update direct access functions as well; default is true)\n */\n setAccess(afn, fDirect)\n {\n if (!afn) {\n if (this.type == Memory.TYPE.UNPAGED) {\n afn = Memory.afnUnpaged;\n }\n else if (this.type == Memory.TYPE.PAGED) {\n afn = Memory.afnPaged;\n } else {\n\n afn = Memory.afnNone;\n }\n }\n this.setReadAccess(afn, fDirect);\n this.setWriteAccess(afn, fDirect);\n }\n\n /**\n * setReadAccess(afn, fDirect)\n *\n * @this {Memory}\n * @param {Array.<function()>} afn\n * @param {boolean} [fDirect]\n */\n setReadAccess(afn, fDirect)\n {\n if (!fDirect || !this.cReadBreakpoints) {\n this.readByte = afn[0] || this.readNone;\n this.readShort = afn[2] || this.readShortDefault;\n this.readLong = afn[4] || this.readLongDefault;\n }\n if (fDirect || fDirect === undefined) {\n this.readByteDirect = afn[0] || this.readNone;\n this.readShortDirect = afn[2] || this.readShortDefault;\n this.readLongDirect = afn[4] || this.readLongDefault;\n }\n }\n\n /**\n * setWriteAccess(afn, fDirect)\n *\n * @this {Memory}\n * @param {Array.<function()>} afn\n * @param {boolean} [fDirect]\n */\n setWriteAccess(afn, fDirect)\n {\n if (!fDirect || !this.cWriteBreakpoints) {\n this.writeByte = !this.fReadOnly && afn[1] || this.writeNone;\n this.writeShort = !this.fReadOnly && afn[3] || this.writeShortDefault;\n this.writeLong = !this.fReadOnly && afn[5] || this.writeLongDefault;\n }\n if (fDirect || fDirect === undefined) {\n this.writeByteDirect = afn[1] || this.writeNone;\n this.writeShortDirect = afn[3] || this.writeShortDefault;\n this.writeLongDirect = afn[5] || this.writeLongDefault;\n }\n }\n\n /**\n * resetReadAccess()\n *\n * @this {Memory}\n */\n resetReadAccess()\n {\n this.readByte = this.readByteDirect;\n this.readShort = this.readShortDirect;\n this.readLong = this.readLongDirect;\n }\n\n /**\n * resetWriteAccess()\n *\n * @this {Memory}\n */\n resetWriteAccess()\n {\n this.writeByte = this.fReadOnly? this.writeNone : this.writeByteDirect;\n this.writeShort = this.fReadOnly? this.writeShortDefault : this.writeShortDirect;\n this.writeLong = this.fReadOnly? this.writeLongDefault : this.writeLongDirect;\n }\n\n /**\n * getPageBlock(addr, fWrite)\n *\n * Called for UNPAGED Memory blocks only.\n *\n * @this {Memory}\n * @param {number} addr\n * @param {boolean} fWrite (true if called for a write, false if for a read)\n * @return {Memory}\n */\n getPageBlock(addr, fWrite)\n {\n /*\n * Even when mapPageBlock() fails (ie, when the page is not present or has insufficient privileges), it\n * will trigger a fault (since we don't set fSuppress), but it will still return a block (ie, an empty block).\n */\n return this.cpu.mapPageBlock(addr, fWrite);\n }\n\n /**\n * setPhysBlock(blockPhys, blockPDE, offPDE, blockPTE, offPTE)\n *\n * @this {Memory}\n * @param {Memory} blockPhys\n * @param {Memory} blockPDE\n * @param {number} offPDE\n * @param {Memory} blockPTE\n * @param {number} offPTE\n */\n setPhysBlock(blockPhys, blockPDE, offPDE, blockPTE, offPTE)\n {\n this.blockPhys = blockPhys;\n this.blockPDE = blockPDE;\n this.iPDE = offPDE >> 2; // convert offPDE into iPDE (an adw index)\n this.blockPTE = blockPTE;\n this.iPTE = offPTE >> 2; // convert offPTE into iPTE (an adw index)\n /*\n * This is an optimization for \"normal\" pages, installing paged memory handlers that mimic\n * normal memory but also know how to update page tables. If any of the criteria are not met\n * for these special handlers, we fall back to the slower default \"paged\" memory handlers.\n */\n if (TYPEDARRAYS && littleEndian && blockPhys.adw && !blockPhys.controller && !blockPhys.cReadBreakpoints && !blockPhys.cWriteBreakpoints) {\n this.ab = blockPhys.ab;\n this.aw = blockPhys.aw;\n this.adw = blockPhys.adw;\n this.setAccess(Memory.afnPagedLE);\n } else {\n this.bitPTEAccessed = blockPhys? Memory.adjustEndian(X86.PTE.ACCESSED) : 0;\n this.bitPTEDirty = blockPhys? Memory.adjustEndian(X86.PTE.ACCESSED | X86.PTE.DIRTY) : 0;\n this.setAccess(Memory.afnPaged);\n }\n }\n\n /**\n * printAddr(sMessage)\n *\n * @this {Memory}\n * @param {string} sMessage\n */\n printAddr(sMessage)\n {\n if (DEBUG && this.dbg && this.dbg.messageEnabled(Messages.MEM)) {\n this.dbg.printMessage(sMessage + ' ' + (this.addr != null? ('%' + Str.toHex(this.addr)) : '#' + this.id), true);\n }\n }\n\n /**\n * addBreakpoint(off, fWrite, cpu)\n *\n * NOTE: Some Memory blocks already require access to the CPU (eg, UNPAGED blocks that need to call cpu.mapPageBlock()),\n * while others require access only if the CPU has set a read or write breakpoint in one of its Debug registers; the latter\n * case is handled here by virtue of the CPU parameter.\n *\n * @this {Memory}\n * @param {number} off\n * @param {boolean} fWrite\n * @param {CPUX86} [cpu] (required for breakpoints set by the CPU, as opposed to the Debugger)\n */\n addBreakpoint(off, fWrite, cpu)\n {\n if (!fWrite) {\n if (this.cReadBreakpoints++ === 0) {\n if (cpu) this.cpu = cpu;\n this.setReadAccess(Memory.afnChecked, false);\n }\n if (DEBUG) this.printAddr(\"read breakpoint added to memory block\");\n }\n else {\n if (this.cWriteBreakpoints++ === 0) {\n if (cpu) this.cpu = cpu;\n this.setWriteAccess(Memory.afnChecked, false);\n }\n if (DEBUG) this.printAddr(\"write breakpoint added to memory block\");\n }\n }\n\n /**\n * removeBreakpoint(off, fWrite)\n *\n * NOTE: If this Memory block is not an UNPAGED block that might need to call cpu.mapPageBlock()), and it no\n * longer has any read or write breakpoints associated with it, then it no longer needs a CPU reference. The\n * existence of a CPU reference only impacts the performance of the \"checked\" memory access functions, so it's\n * not critical to eliminate it.\n *\n * TODO: Another option would be to count CPU references separately from Debugger references, so that when\n * the former goes to zero, we can unconditionally remove the CPU reference; UNPAGED blocks would automatically\n * increment that reference count, so their CPU reference would never go away.\n *\n * @this {Memory}\n * @param {number} off\n * @param {boolean} fWrite\n */\n removeBreakpoint(off, fWrite)\n {\n if (!fWrite) {\n if (--this.cReadBreakpoints === 0) {\n this.resetReadAccess();\n if (DEBUG) this.printAddr(\"all read breakpoints removed from memory block\");\n }\n\n }\n else {\n if (--this.cWriteBreakpoints === 0) {\n this.resetWriteAccess();\n if (DEBUG) this.printAddr(\"all write breakpoints removed from memory block\");\n }\n\n }\n }\n\n /**\n * copyBreakpoints(dbg, mem)\n *\n * @this {Memory}\n * @param {DebuggerX86} [dbg]\n * @param {Memory} [mem] (outgoing Memory block to copy breakpoints from, if any)\n */\n copyBreakpoints(dbg, mem)\n {\n this.dbg = dbg;\n this.cReadBreakpoints = this.cWriteBreakpoints = 0;\n if (mem) {\n if (mem.cpu) this.cpu = mem.cpu;\n if ((this.cReadBreakpoints = mem.cReadBreakpoints)) {\n this.setReadAccess(Memory.afnChecked, false);\n }\n if ((this.cWriteBreakpoints = mem.cWriteBreakpoints)) {\n this.setWriteAccess(Memory.afnChecked, false);\n }\n }\n }\n\n /**\n * readNone(off)\n *\n * Previously, this always returned 0x00, but the initial memory probe by the COMPAQ DeskPro 386 ROM BIOS\n * writes 0x0000 to the first word of every 64Kb block in the nearly 16Mb address space it supports, and\n * if it reads back 0x0000, it will initially think that LOTS of RAM exists, only to be disappointed later\n * when it performs a more exhaustive memory test, generating unwanted error messages in the process.\n *\n * TODO: Determine if we should have separate readByteNone(), readShortNone() and readLongNone() functions\n * to return 0xff, 0xffff and 0xffffffff|0, respectively. This seems sufficient for now, as it seems unlikely\n * that a system would require nonexistent memory locations to return ALL bits set.\n *\n * Also, I'm reluctant to address that potential issue by simply returning -1, because to date, the above\n * Memory interfaces have always returned values that are properly masked to 8, 16 or 32 bits, respectively.\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readNone(off, addr)\n {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages.CPU | Messages.MEM) /* && !off */) {\n this.dbg.message(\"attempt to read invalid block %\" + Str.toHex(addr), true);\n }\n return 0xff;\n }\n\n /**\n * writeNone(off, v, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} v (could be either a byte or word value, since we use the same handler for both kinds of accesses)\n * @param {number} addr\n */\n writeNone(off, v, addr)\n {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages.CPU | Messages.MEM) /* && !off */) {\n this.dbg.message(\"attempt to write \" + Str.toHexWord(v) + \" to invalid block %\" + Str.toHex(addr), true);\n }\n }\n\n /**\n * readShortDefault(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortDefault(off, addr)\n {\n return this.readByte(off++, addr++) | (this.readByte(off, addr) << 8);\n }\n\n /**\n * readLongDefault(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readLongDefault(off, addr)\n {\n return this.readByte(off++, addr++) | (this.readByte(off++, addr++) << 8) | (this.readByte(off++, addr++) << 16) | (this.readByte(off, addr) << 24);\n }\n\n /**\n * writeShortDefault(off, w, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeShortDefault(off, w, addr)\n {\n this.writeByte(off++, w & 0xff, addr++);\n this.writeByte(off, w >> 8, addr);\n }\n\n /**\n * writeLongDefault(off, w, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeLongDefault(off, w, addr)\n {\n this.writeByte(off++, w & 0xff, addr++);\n this.writeByte(off++, (w >> 8) & 0xff, addr++);\n this.writeByte(off++, (w >> 16) & 0xff, addr++);\n this.writeByte(off, (w >>> 24), addr);\n }\n\n /**\n * readByteMemory(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteMemory(off, addr)\n {\n if (BYTEARRAYS) {\n return this.ab[off];\n }\n return ((this.adw[off >> 2] >>> ((off & 0x3) << 3)) & 0xff);\n }\n\n /**\n * readShortMemory(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortMemory(off, addr)\n {\n if (BYTEARRAYS) {\n return this.ab[off] | (this.ab[off + 1] << 8);\n }\n var w;\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n var dw = (this.adw[idw] >> nShift);\n if (nShift < 24) {\n w = dw & 0xffff;\n } else {\n w = (dw & 0xff) | ((this.adw[idw + 1] & 0xff) << 8);\n }\n return w;\n }\n\n /**\n * readLongMemory(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readLongMemory(off, addr)\n {\n if (BYTEARRAYS) {\n return this.ab[off] | (this.ab[off + 1] << 8) | (this.ab[off + 2] << 16) | (this.ab[off + 3] << 24);\n }\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n var l = this.adw[idw];\n if (nShift) {\n l >>>= nShift;\n l |= this.adw[idw + 1] << (32 - nShift);\n }\n return l;\n }\n\n /**\n * writeByteMemory(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b\n * @param {number} addr\n */\n writeByteMemory(off, b, addr)\n {\n if (BYTEARRAYS) {\n this.ab[off] = b;\n } else {\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n this.adw[idw] = (this.adw[idw] & ~(0xff << nShift)) | (b << nShift);\n }\n this.fDirty = true;\n }\n\n /**\n * writeShortMemory(off, w, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeShortMemory(off, w, addr)\n {\n if (BYTEARRAYS) {\n this.ab[off] = (w & 0xff);\n this.ab[off + 1] = (w >> 8);\n } else {\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n if (nShift < 24) {\n this.adw[idw] = (this.adw[idw] & ~(0xffff << nShift)) | (w << nShift);\n } else {\n this.adw[idw] = (this.adw[idw] & 0x00ffffff) | (w << 24);\n idw++;\n this.adw[idw] = (this.adw[idw] & (0xffffff00|0)) | (w >> 8);\n }\n }\n this.fDirty = true;\n }\n\n /**\n * writeLongMemory(off, l, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} l\n * @param {number} addr\n */\n writeLongMemory(off, l, addr)\n {\n if (BYTEARRAYS) {\n this.ab[off] = (l & 0xff);\n this.ab[off + 1] = (l >> 8) & 0xff;\n this.ab[off + 2] = (l >> 16) & 0xff;\n this.ab[off + 3] = (l >> 24) & 0xff;\n } else {\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n if (!nShift) {\n this.adw[idw] = l;\n } else {\n var mask = (0xffffffff|0) << nShift;\n this.adw[idw] = (this.adw[idw] & ~mask) | (l << nShift);\n idw++;\n this.adw[idw] = (this.adw[idw] & mask) | (l >>> (32 - nShift));\n }\n }\n this.fDirty = true;\n }\n\n /**\n * readByteChecked(off, addr)\n *\n * NOTE: When we're called in the context of a PAGED block (eg, with one or more DEBUGGER breakpoints set),\n * the checkMemory functions need \"this.addr + off\" rather than \"addr\", because the former will be the physical\n * address rather than the linear address.\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteChecked(off, addr)\n {\n if (!DEBUGGER || !this.dbg || this.addr == null || !this.dbg.checkMemoryRead(this.addr + off)) {\n if (I386 && this.cpu) this.cpu.checkMemoryException(addr, 1, false);\n }\n return this.readByteDirect(off, addr);\n }\n\n /**\n * readShortChecked(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortChecked(off, addr)\n {\n if (!DEBUGGER || !this.dbg || this.addr == null || !this.dbg.checkMemoryRead(this.addr + off, 2)) {\n if (I386 && this.cpu) this.cpu.checkMemoryException(addr, 2, false);\n }\n return this.readShortDirect(off, addr);\n }\n\n /**\n * readLongChecked(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readLongChecked(off, addr)\n {\n if (!DEBUGGER || !this.dbg || this.addr == null || !this.dbg.checkMemoryRead(this.addr + off, 4)) {\n if (I386 && this.cpu) this.cpu.checkMemoryException(addr, 4, false);\n }\n return this.readLongDirect(off, addr);\n }\n\n /**\n * writeByteChecked(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @param {number} b\n */\n writeByteChecked(off, b, addr)\n {\n if (!DEBUGGER || !this.dbg || this.addr == null || !this.dbg.checkMemoryWrite(this.addr + off)) {\n if (I386 && this.cpu) this.cpu.checkMemoryException(addr, 1, true);\n }\n if (this.fReadOnly) this.writeNone(off, b, addr); else this.writeByteDirect(off, b, addr);\n }\n\n /**\n * writeShortChecked(off, w, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @param {number} w\n */\n writeShortChecked(off, w, addr)\n {\n if (!DEBUGGER || !this.dbg || this.addr == null || !this.dbg.checkMemoryWrite(this.addr + off, 2)) {\n if (I386 && this.cpu) this.cpu.checkMemoryException(addr, 2, true);\n }\n if (this.fReadOnly) this.writeNone(off, w, addr); else this.writeShortDirect(off, w, addr);\n }\n\n /**\n * writeLongChecked(off, l, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} l\n * @param {number} addr\n */\n writeLongChecked(off, l, addr)\n {\n if (!DEBUGGER || !this.dbg || this.addr == null || !this.dbg.checkMemoryWrite(this.addr + off, 4)) {\n if (I386 && this.cpu) this.cpu.checkMemoryException(addr, 4, true);\n }\n if (this.fReadOnly) this.writeNone(off, l, addr); else this.writeLongDirect(off, l, addr);\n }\n\n /**\n * readBytePaged(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readBytePaged(off, addr)\n {\n this.blockPDE.adw[this.iPDE] |= this.bitPTEAccessed;\n this.blockPTE.adw[this.iPTE] |= this.bitPTEAccessed;\n return this.blockPhys.readByte(off, addr);\n }\n\n /**\n * readShortPaged(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortPaged(off, addr)\n {\n this.blockPDE.adw[this.iPDE] |= this.bitPTEAccessed;\n this.blockPTE.adw[this.iPTE] |= this.bitPTEAccessed;\n return this.blockPhys.readShort(off, addr);\n }\n\n /**\n * readLongPaged(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readLongPaged(off, addr)\n {\n this.blockPDE.adw[this.iPDE] |= this.bitPTEAccessed;\n this.blockPTE.adw[this.iPTE] |= this.bitPTEAccessed;\n return this.blockPhys.readLong(off, addr);\n }\n\n /**\n * writeBytePaged(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b\n * @param {number} addr\n */\n writeBytePaged(off, b, addr)\n {\n this.blockPDE.adw[this.iPDE] |= this.bitPTEAccessed;\n this.blockPTE.adw[this.iPTE] |= this.bitPTEDirty;\n this.blockPhys.writeByte(off, b, addr);\n }\n\n /**\n * writeShortPaged(off, w, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeShortPaged(off, w, addr)\n {\n this.blockPDE.adw[this.iPDE] |= this.bitPTEAccessed;\n this.blockPTE.adw[this.iPTE] |= this.bitPTEDirty;\n this.blockPhys.writeShort(off, w, addr);\n }\n\n /**\n * writeLongPaged(off, l, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} l\n * @param {number} addr\n */\n writeLongPaged(off, l, addr)\n {\n this.blockPDE.adw[this.iPDE] |= this.bitPTEAccessed;\n this.blockPTE.adw[this.iPTE] |= this.bitPTEDirty;\n this.blockPhys.writeLong(off, l, addr);\n }\n\n /**\n * readByteUnpaged(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteUnpaged(off, addr)\n {\n return this.getPageBlock(addr, false).readByte(off, addr);\n }\n\n /**\n * readShortUnpaged(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortUnpaged(off, addr)\n {\n return this.getPageBlock(addr, false).readShort(off, addr);\n }\n\n /**\n * readLongUnpaged(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readLongUnpaged(off, addr)\n {\n return this.getPageBlock(addr, false).readLong(off, addr);\n }\n\n /**\n * writeByteUnpaged(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b\n * @param {number} addr\n */\n writeByteUnpaged(off, b, addr)\n {\n this.getPageBlock(addr, true).writeByte(off, b, addr);\n }\n\n /**\n * writeShortUnpaged(off, w, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeShortUnpaged(off, w, addr)\n {\n this.getPageBlock(addr, true).writeShort(off, w, addr);\n }\n\n /**\n * writeLongUnpaged(off, l, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} l\n * @param {number} addr\n */\n writeLongUnpaged(off, l, addr)\n {\n this.getPageBlock(addr, true).writeLong(off, l, addr);\n }\n\n /**\n * readByteBE(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteBE(off, addr)\n {\n return this.ab[off];\n }\n\n /**\n * readByteLE(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteLE(off, addr)\n {\n return this.ab[off];\n }\n\n /**\n * readBytePLE(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readBytePLE(off, addr)\n {\n this.blockPDE.adw[this.iPDE] |= X86.PTE.ACCESSED;\n this.blockPTE.adw[this.iPTE] |= X86.PTE.ACCESSED;\n /*\n * TODO: Review this performance hack. Basically, after the first read of a page,\n * we redirect the default read handler to a faster handler. However, if operating\n * systems clear the PDE/PTE bits without reloading CR3, they won't get set again.\n *\n * We should look into creating special write handlers for pages containing PDE/PTE\n * entries, and whenever those entries are written, reset the read/write handlers\n * for the corresponding pages.\n */\n this.readByte = this.readByteLE;\n return this.ab[off];\n }\n\n /**\n * readShortBE(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortBE(off, addr)\n {\n return this.dv.getUint16(off, true);\n }\n\n /**\n * readShortLE(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortLE(off, addr)\n {\n /*\n * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned read\n * vs. always reading the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.\n */\n return (off & 0x1)? (this.ab[off] | (this.ab[off+1] << 8)) : this.aw[off >> 1];\n }\n\n /**\n * readShortPLE(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readShortPLE(off, addr)\n {\n /*\n * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned read\n * vs. always reading the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.\n */\n this.blockPDE.adw[this.iPDE] |= X86.PTE.ACCESSED;\n this.blockPTE.adw[this.iPTE] |= X86.PTE.ACCESSED;\n /*\n * TODO: Review this performance hack. Basically, after the first read of a page,\n * we redirect the default read handler to a faster handler. However, if operating\n * systems clear the PDE/PTE bits without reloading CR3, they won't get set again.\n *\n * We should look into creating special write handlers for pages containing PDE/PTE\n * entries, and whenever those entries are written, reset the read/write handlers\n * for the corresponding pages.\n */\n this.readShort = this.readShortLE;\n return (off & 0x1)? (this.ab[off] | (this.ab[off+1] << 8)) : this.aw[off >> 1];\n }\n\n /**\n * readLongBE(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readLongBE(off, addr)\n {\n return this.dv.getInt32(off, true);\n }\n\n /**\n * readLongLE(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readLongLE(off, addr)\n {\n /*\n * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned read\n * vs. always reading the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.\n */\n return (off & 0x3)? (this.ab[off] | (this.ab[off+1] << 8) | (this.ab[off+2] << 16) | (this.ab[off+3] << 24)) : this.adw[off >> 2];\n }\n\n /**\n * readLongPLE(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readLongPLE(off, addr)\n {\n /*\n * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned read\n * vs. always reading the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.\n */\n this.blockPDE.adw[this.iPDE] |= X86.PTE.ACCESSED;\n this.blockPTE.adw[this.iPTE] |= X86.PTE.ACCESSED;\n /*\n * TODO: Review this performance hack. Basically, after the first read of a page,\n * we redirect the default read handler to a faster handler. However, if operating\n * systems clear the PDE/PTE bits without reloading CR3, they won't get set again.\n *\n * We should look into creating special write handlers for pages containing PDE/PTE\n * entries, and whenever those entries are written, reset the read/write handlers\n * for the corresponding pages.\n */\n this.readLong = this.readLongLE;\n return (off & 0x3)? (this.ab[off] | (this.ab[off+1] << 8) | (this.ab[off+2] << 16) | (this.ab[off+3] << 24)) : this.adw[off >> 2];\n }\n\n /**\n * writeByteBE(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b\n * @param {number} addr\n */\n writeByteBE(off, b, addr)\n {\n this.ab[off] = b;\n this.fDirty = true;\n }\n\n /**\n * writeByteLE(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @param {number} b\n */\n writeByteLE(off, b, addr)\n {\n this.ab[off] = b;\n this.fDirty = true;\n }\n\n /**\n * writeBytePLE(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @param {number} b\n */\n writeBytePLE(off, b, addr)\n {\n this.ab[off] = b;\n this.blockPDE.adw[this.iPDE] |= X86.PTE.ACCESSED;\n this.blockPTE.adw[this.iPTE] |= X86.PTE.ACCESSED | X86.PTE.DIRTY;\n /*\n * TODO: Review this performance hack. Basically, after the first write of a page,\n * we redirect the default write handler to a faster handler. However, if operating\n * systems clear the PDE/PTE bits without reloading CR3, they won't get set again.\n *\n * We should look into creating special write handlers for pages containing PDE/PTE\n * entries, and whenever those entries are written, reset the read/write handlers\n * for the corresponding pages.\n */\n this.writeByte = this.writeByteLE;\n /*\n * NOTE: Technically, we should be setting the fDirty flag on blockPDE and blockPTE as well, but let's\n * consider the two sole uses of fDirty. First, we have cleanMemory(), which is currently used only by\n * the Video component, and video memory should never contain page directories or page tables, so no\n * worries there. Second, we have saveMemory(), but the CPU now asks that function to save all physical\n * memory blocks whenever paging is enabled, so no worries there either.\n */\n this.blockPhys.fDirty = true;\n }\n\n /**\n * writeShortBE(off, w, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @param {number} w\n */\n writeShortBE(off, w, addr)\n {\n this.dv.setUint16(off, w, true);\n this.fDirty = true;\n }\n\n /**\n * writeShortLE(off, w, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @param {number} w\n */\n writeShortLE(off, w, addr)\n {\n /*\n * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned write\n * vs. always writing the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.\n */\n if (off & 0x1) {\n this.ab[off] = w;\n this.ab[off+1] = w >> 8;\n } else {\n this.aw[off >> 1] = w;\n }\n this.fDirty = true;\n }\n\n /**\n * writeShortPLE(off, w, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} addr\n * @param {number} w\n */\n writeShortPLE(off, w, addr)\n {\n /*\n * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned write\n * vs. always writing the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.\n */\n if (off & 0x1) {\n this.ab[off] = w;\n this.ab[off+1] = w >> 8;\n } else {\n this.aw[off >> 1] = w;\n }\n this.blockPDE.adw[this.iPDE] |= X86.PTE.ACCESSED;\n this.blockPTE.adw[this.iPTE] |= X86.PTE.ACCESSED | X86.PTE.DIRTY;\n /*\n * TODO: Review this performance hack. Basically, after the first write of a page,\n * we redirect the default write handler to a faster handler. However, if operating\n * systems clear the PDE/PTE bits without reloading CR3, they won't get set again.\n *\n * We should look into creating special write handlers for pages containing PDE/PTE\n * entries, and whenever those entries are written, reset the read/write handlers\n * for the corresponding pages.\n */\n this.writeShort = this.writeShortLE;\n /*\n * NOTE: Technically, we should be setting the fDirty flag on blockPDE and blockPTE as well, but let's\n * consider the two sole uses of fDirty. First, we have cleanMemory(), which is currently used only by\n * the Video component, and video memory should never contain page directories or page tables, so no\n * worries there. Second, we have saveMemory(), but the CPU now asks that function to save all physical\n * memory blocks whenever paging is enabled, so no worries there either.\n */\n this.blockPhys.fDirty = true;\n }\n\n /**\n * writeLongBE(off, l, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} l\n * @param {number} addr\n */\n writeLongBE(off, l, addr)\n {\n this.dv.setInt32(off, l, true);\n this.fDirty = true;\n }\n\n /**\n * writeLongLE(off, l, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} l\n * @param {number} addr\n */\n writeLongLE(off, l, addr)\n {\n /*\n * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned write\n * vs. always writing the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.\n */\n if (off & 0x3) {\n this.ab[off] = l;\n this.ab[off+1] = (l >> 8);\n this.ab[off+2] = (l >> 16);\n this.ab[off+3] = (l >> 24);\n } else {\n this.adw[off >> 2] = l;\n }\n this.fDirty = true;\n }\n\n /**\n * writeLongPLE(off, l, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} l\n * @param {number} addr\n */\n writeLongPLE(off, l, addr)\n {\n /*\n * TODO: It remains to be seen if there's any advantage to checking the offset for an aligned write\n * vs. always writing the bytes separately; it seems a safe bet for longs, but it's less clear for shorts.\n */\n if (off & 0x3) {\n this.ab[off] = l;\n this.ab[off+1] = (l >> 8);\n this.ab[off+2] = (l >> 16);\n this.ab[off+3] = (l >> 24);\n } else {\n this.adw[off >> 2] = l;\n }\n this.blockPDE.adw[this.iPDE] |= X86.PTE.ACCESSED;\n this.blockPTE.adw[this.iPTE] |= X86.PTE.ACCESSED | X86.PTE.DIRTY;\n /*\n * TODO: Review this performance hack. Basically, after the first write of a page,\n * we redirect the default write handler to a faster handler. However, if operating\n * systems clear the PDE/PTE bits without reloading CR3, they won't get set again.\n *\n * We should look into creating special write handlers for pages containing PDE/PTE\n * entries, and whenever those entries are written, reset the read/write handlers\n * for the corresponding pages.\n */\n this.writeLong = this.writeLongLE;\n /*\n * NOTE: Technically, we should be setting the fDirty flag on blockPDE and blockPTE as well, but let's\n * consider the two sole uses of fDirty. First, we have cleanMemory(), which is currently used only by\n * the Video component, and video memory should never contain page directories or page tables, so no\n * worries there. Second, we have saveMemory(), but the CPU now asks that function to save all physical\n * memory blocks whenever paging is enabled, so no worries there either.\n */\n this.blockPhys.fDirty = true;\n }\n\n /**\n * readBackTrackNone(off)\n *\n * @this {Memory}\n * @param {number} off\n * @return {number}\n */\n readBackTrackNone(off)\n {\n return 0;\n }\n\n /**\n * writeBackTrackNone(off, bti)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} bti\n */\n writeBackTrackNone(off, bti)\n {\n }\n\n /**\n * modBackTrackNone(fMod)\n *\n * @this {Memory}\n * @param {boolean} fMod\n */\n modBackTrackNone(fMod)\n {\n return false;\n }\n\n /**\n * readBackTrackIndex(off)\n *\n * @this {Memory}\n * @param {number} off\n * @return {number}\n */\n readBackTrackIndex(off)\n {\n return this.abtIndexes[off];\n }\n\n /**\n * writeBackTrackIndex(off, bti)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} bti\n * @return {number} previous bti (0 if none)\n */\n writeBackTrackIndex(off, bti)\n {\n var btiPrev;\n btiPrev = this.abtIndexes[off];\n this.abtIndexes[off] = bti;\n return btiPrev;\n }\n\n /**\n * modBackTrackIndex(fMod)\n *\n * @this {Memory}\n * @param {boolean} fMod\n * @return {boolean} previous value\n */\n modBackTrackIndex(fMod)\n {\n var fModPrev = this.fModBackTrack;\n this.fModBackTrack = fMod;\n return fModPrev;\n }\n\n /**\n * adjustEndian(dw)\n *\n * @param {number} dw\n * @return {number}\n */\n static adjustEndian(dw)\n {\n if (TYPEDARRAYS && !littleEndian) {\n dw = (dw << 24) | ((dw << 8) & 0x00ff0000) | ((dw >> 8) & 0x0000ff00) | (dw >>> 24);\n }\n return dw;\n }\n}\n\n/*\n * Basic memory types\n *\n * RAM is the most conventional memory type, providing full read/write capability to x86-compatible (ie,\n * 'little endian\") storage. ROM is equally conventional, except that the fReadOnly property is set,\n * disabling writes. VIDEO is treated exactly like RAM, unless a controller is provided. Both RAM and\n * VIDEO memory are always considered writable, and even ROM can be written using the Bus setByteDirect()\n * interface (which in turn uses the Memory writeByteDirect() interface), allowing the ROM component to\n * initialize its own memory. The CTRL type is used to identify memory-mapped devices that do not need\n * any default storage and always provide their own controller.\n *\n * UNPAGED and PAGED blocks are created by the CPU when paging is enabled; the role of an UNPAGED block\n * is simply to perform page translation and replace itself with a PAGED block, which redirects read/write\n * requests to the physical page located during translation. UNPAGED and PAGED blocks are considered\n * \"logical\" blocks that don't contain any storage of their own; all other block types represent \"physical\"\n * memory (or a memory-mapped device).\n *\n * Unallocated regions of the address space contain a special memory block of type NONE that contains\n * no storage. Mapping every addressible location to a memory block allows all accesses to be routed in\n * exactly the same manner, without resorting to any range or processor checks.\n *\n * Originally, the Debugger always went through the Bus interfaces, and could therefore modify ROMs as well,\n * but with the introduction of protected mode memory segmentation (and later paging), where logical and\n * physical addresses were no longer the same, that is no longer true. For coherency, all Debugger memory\n * accesses now go through SegX86 and CPUX86 memory interfaces, so that the user sees the same segment\n * and page translation that the CPU sees. However, the Debugger uses a special probeAddr() interface to\n * read memory, along with a special \"fSuppress\" flag to mapPageBlock(), to prevent its memory accesses\n * from triggering segment and/or page faults when invalid or not-present segments or pages are accessed.\n *\n * These types are not mutually exclusive. For example, VIDEO memory could be allocated as RAM, with or\n * without a custom controller (the original Monochrome and CGA video cards used read/write storage that\n * was indistinguishable from RAM), and CTRL memory could be allocated as an empty block of any type, with\n * a custom controller. A few types are required for certain features (eg, ROM is required if you want\n * read-only memory), but the larger purpose of these types is to help document the caller's intent and to\n * provide the Control Panel with the ability to highlight memory regions accordingly.\n */\nMemory.TYPE = {\n NONE: 0,\n RAM: 1,\n ROM: 2,\n VIDEO: 3,\n CTRL: 4,\n UNPAGED: 5,\n PAGED: 6,\n COLORS: [\"black\", \"blue\", \"green\", \"cyan\"],\n NAMES: [\"NONE\", \"RAM\", \"ROM\", \"VIDEO\", \"H/W\", \"UNPAGED\", \"PAGED\"]\n};\n\n/*\n * Last used block ID (used for debugging only)\n */\nMemory.idBlock = 0;\n\n\n/*\n * This is the effective definition of afnNone, but we need not fully define it, because setAccess() uses these\n * defaults when any of the 6 handlers (ie, 2 byte handlers, 2 short handlers, and 2 long handlers) are undefined.\n *\nMemory.afnNone = [\n Memory.prototype.readNone,\n Memory.prototype.writeNone,\n Memory.prototype.readShortDefault,\n Memory.prototype.writeShortDefault,\n Memory.prototype.readLongDefault,\n Memory.prototype.writeLongDefault\n];\n */\nMemory.afnNone = [];\n\nMemory.afnMemory = [\n Memory.prototype.readByteMemory,\n Memory.prototype.writeByteMemory,\n Memory.prototype.readShortMemory,\n Memory.prototype.writeShortMemory,\n Memory.prototype.readLongMemory,\n Memory.prototype.writeLongMemory\n];\n\nMemory.afnChecked = [\n Memory.prototype.readByteChecked,\n Memory.prototype.writeByteChecked,\n Memory.prototype.readShortChecked,\n Memory.prototype.writeShortChecked,\n Memory.prototype.readLongChecked,\n Memory.prototype.writeLongChecked\n];\n\nif (PAGEBLOCKS) {\n Memory.afnPaged = [\n Memory.prototype.readBytePaged,\n Memory.prototype.writeBytePaged,\n Memory.prototype.readShortPaged,\n Memory.prototype.writeShortPaged,\n Memory.prototype.readLongPaged,\n Memory.prototype.writeLongPaged\n ];\n\n Memory.afnUnpaged = [\n Memory.prototype.readByteUnpaged,\n Memory.prototype.writeByteUnpaged,\n Memory.prototype.readShortUnpaged,\n Memory.prototype.writeShortUnpaged,\n Memory.prototype.readLongUnpaged,\n Memory.prototype.writeLongUnpaged\n ];\n}\n\nif (TYPEDARRAYS) {\n Memory.afnArrayBE = [\n Memory.prototype.readByteBE,\n Memory.prototype.writeByteBE,\n Memory.prototype.readShortBE,\n Memory.prototype.writeShortBE,\n Memory.prototype.readLongBE,\n Memory.prototype.writeLongBE\n ];\n\n Memory.afnArrayLE = [\n Memory.prototype.readByteLE,\n Memory.prototype.writeByteLE,\n Memory.prototype.readShortLE,\n Memory.prototype.writeShortLE,\n Memory.prototype.readLongLE,\n Memory.prototype.writeLongLE\n ];\n\n Memory.afnPagedLE = [\n Memory.prototype.readBytePLE,\n Memory.prototype.writeBytePLE,\n Memory.prototype.readShortPLE,\n Memory.prototype.writeShortPLE,\n Memory.prototype.readLongPLE,\n Memory.prototype.writeLongPLE\n ];\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/cpu.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * class CPU\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass CPU extends Component {\n /**\n * CPU(parmsCPU, nCyclesDefault)\n *\n * The CPU class supports the following (parmsCPU) properties:\n *\n * cycles: the machine's base cycles per second; the CPUX86 constructor will provide us with a default\n * (based on the CPU model) to use as a fallback.\n *\n * multiplier: base cycle multiplier; default is 1.\n *\n * autoStart: true to automatically start, false to not, or null if \"it depends\"; null is the default,\n * which means autostart UNLESS there is a Debugger present.\n *\n * csStart: the number of cycles that runCPU() must wait before generating checksum records;\n * -1 if disabled. checksum records are a diagnostic aid used to help compare one CPU run to another.\n *\n * csInterval: the number of cycles that runCPU() must execute before generating a checksum record;\n * -1 if disabled.\n *\n * csStop: the number of cycles to stop generating checksum records.\n *\n * This component is primarily responsible for interfacing the CPU with the outside world (eg, Panel and Debugger\n * components), and managing overall CPU operation.\n *\n * It is extended by the CPUX86 component, where all the x86-specific logic resides.\n *\n * @this {CPU}\n * @param {Object} parmsCPU\n * @param {number} nCyclesDefault\n */\n constructor(parmsCPU, nCyclesDefault)\n {\n super(\"CPU\", parmsCPU, Messages.CPU);\n\n var nCycles = parmsCPU['cycles'] || nCyclesDefault;\n\n var nMultiplier = parmsCPU['multiplier'] || 1;\n\n this.counts = {};\n this.counts.nBaseCyclesPerSecond = nCycles;\n this.counts.msPerYield = Math.round(1000 / CPU.YIELDS_PER_SECOND);\n\n /*\n * nTargetMultiplier replaces the old \"speed\" variable (0, 1, 2) and eliminates the need for\n * the constants (SPEED_SLOW, SPEED_FAST and SPEED_MAX). The UI simply doubles the target multiplier\n * until we've exceeded the host's speed limit (ie, the current value is unable to reach the target),\n * at which point we reset the target back to the default.\n */\n this.counts.nBaseMultiplier = this.counts.nCurrentMultiplier = this.counts.nTargetMultiplier = nMultiplier;\n this.counts.mhzBase = Math.round(this.counts.nBaseCyclesPerSecond / 10000) / 100;\n this.counts.mhzCurrent = this.counts.mhzTarget = this.counts.mhzBase * this.counts.nTargetMultiplier;\n\n /*\n * We add a number of flags to those initialized by Component.\n */\n this.flags.starting = this.flags.running = this.flags.yield = false;\n this.flags.autoStart = parmsCPU['autoStart'];\n\n /*\n * TODO: Add some UI for displayLiveRegs (either an XML property, or a UI checkbox, or both)\n */\n this.flags.displayLiveRegs = false;\n\n /*\n * Get checksum parameters, if any. runCPU() behavior is not affected until fChecksum\n * is true, which won't happen until resetChecksum() is called with nCyclesChecksumInterval\n * (\"csInterval\") set to a positive value.\n *\n * As above, any of these parameters can also be set with the Debugger's execution options\n * command (\"x\"); for example, \"x cs int 5000\" will set nCyclesChecksumInterval to 5000\n * and call resetChecksum().\n */\n this.flags.checksum = false;\n this.counts.nChecksum = this.counts.nCyclesChecksumNext = 0;\n this.counts.nCyclesChecksumStart = parmsCPU[\"csStart\"];\n this.counts.nCyclesChecksumInterval = parmsCPU[\"csInterval\"];\n this.counts.nCyclesChecksumStop = parmsCPU[\"csStop\"];\n\n /*\n * Array of countdown timers managed by addTimer() and setTimer().\n *\n * See also: getMSCycles(), getBurstCycles(), saveTimers(), restoreTimers(), and updateTimers()\n */\n this.aTimers = [];\n\n this.idRunTimeout = 0;\n this.onRunTimeout = this.runCPU.bind(this); // function onRunTimeout() { cpu.runCPU(); };\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {CPU}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPU} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.dbg = dbg;\n\n for (var i = 0; i < CPU.BUTTONS.length; i++) {\n var control = this.bindings[CPU.BUTTONS[i]];\n if (control) this.cmp.setBinding(\"\", CPU.BUTTONS[i], control);\n }\n\n this.fpu = cmp.getMachineComponent(\"FPU\");\n\n /*\n * Attach the ChipSet component to the CPU so that it can obtain the IDT vector number\n * of pending hardware interrupts in response to the ChipSet's updateINTR() notifications.\n *\n * We must also call chipset.updateAllTimers() periodically; stepCPU() takes care of that.\n */\n this.chipset = cmp.getMachineComponent(\"ChipSet\");\n\n /*\n * We've already saved the parmsCPU 'autoStart' setting, but there may be a machine (or URL) override.\n */\n var sAutoStart = cmp.getMachineParm('autoStart');\n if (sAutoStart != null) {\n this.flags.autoStart = (sAutoStart == \"true\"? true : (sAutoStart == \"false\"? false : !!sAutoStart));\n }\n\n this.timerYield = cpu.addTimer(this.id, function yieldTimer() {\n cpu.flags.yield = true;\n }, this.counts.msPerYield);\n\n this.setReady();\n }\n\n /**\n * reset()\n *\n * This is a placeholder for reset (overridden by the CPUX86 component).\n *\n * @this {CPU}\n */\n reset()\n {\n }\n\n /**\n * save(fRunning)\n *\n * This is a placeholder for save support (overridden by the CPUX86 component).\n *\n * @this {CPU}\n * @param {boolean} [fRunning]\n * @return {Object|null}\n */\n save(fRunning)\n {\n return null;\n }\n\n /**\n * restore(data)\n *\n * This is a placeholder for restore support (overridden by the CPUX86 component).\n *\n * @this {CPU}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n return false;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {CPU}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data || !this.restore) {\n this.reset();\n } else {\n this.resetCycles();\n if (!this.restore(data)) return false;\n this.resetChecksum();\n }\n /*\n * Give the Debugger a chance to do/print something once we've powered up\n */\n if (DEBUGGER && this.dbg) {\n this.dbg.init();\n } else {\n this.println(\"No debugger detected\");\n }\n }\n /*\n * The Computer component (which is responsible for all powerDown and powerUp notifications)\n * is now responsible for managing a component's fPowered flag, not us.\n *\n * this.flags.powered = true;\n */\n this.updateCPU();\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {CPU}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n /*\n * The Computer component (which is responsible for all powerDown and powerUp notifications)\n * is now responsible for managing a component's fPowered flag, not us.\n *\n * this.flags.powered = false;\n */\n var fRunning = this.flags.running;\n if (fShutdown) this.stopCPU();\n return fSave? this.save(fRunning) : true;\n }\n\n /**\n * autoStart()\n *\n * @this {CPU}\n * @return {boolean} true if started, false if not\n */\n autoStart()\n {\n if (this.flags.running) {\n return true;\n }\n /*\n * Start running automatically on power-up, assuming there's no Debugger. \n */\n if (this.flags.autoStart || this.flags.autoStart == null && !this.dbg) {\n /*\n * Automatically updating focus when calling startCPU() is a double-edged sword, potentially interfering\n * with the user's attention, which is why we also set fQuiet, to try to prevent the page from \"auto-scrolling\"\n * the newly focused machine into view. \n */\n return this.startCPU(true, true);\n }\n return false;\n }\n\n /**\n * isPowered()\n *\n * @this {CPU}\n * @return {boolean}\n */\n isPowered()\n {\n if (!this.flags.powered) {\n this.println(this.toString() + \" not powered\");\n return false;\n }\n return true;\n }\n\n /**\n * isRunning()\n *\n * @this {CPU}\n * @return {boolean}\n */\n isRunning()\n {\n return this.flags.running;\n }\n\n /**\n * getChecksum()\n *\n * This will be implemented by the CPUX86 component.\n *\n * @this {CPU}\n * @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code)\n */\n getChecksum()\n {\n return 0;\n }\n\n /**\n * resetChecksum()\n *\n * If checksum generation is enabled (fChecksum is true), this resets the running 32-bit checksum and the\n * cycle counter that will trigger the next displayChecksum(); called by resetCycles(), which is called whenever\n * the CPU is reset or restored.\n *\n * @this {CPU}\n * @return {boolean} true if checksum generation enabled, false if not\n */\n resetChecksum()\n {\n if (this.counts.nCyclesChecksumStart === undefined) this.counts.nCyclesChecksumStart = 0;\n if (this.counts.nCyclesChecksumInterval === undefined) this.counts.nCyclesChecksumInterval = -1;\n if (this.counts.nCyclesChecksumStop === undefined) this.counts.nCyclesChecksumStop = -1;\n this.flags.checksum = (this.counts.nCyclesChecksumStart >= 0 && this.counts.nCyclesChecksumInterval > 0);\n if (this.flags.checksum) {\n this.counts.nChecksum = 0;\n this.counts.nCyclesChecksumNext = this.counts.nCyclesChecksumStart - this.nTotalCycles;\n /*\n * this.counts.nCyclesChecksumNext = this.counts.nCyclesChecksumStart + this.counts.nCyclesChecksumInterval -\n * (this.nTotalCycles % this.counts.nCyclesChecksumInterval);\n */\n return true;\n }\n return false;\n }\n\n /**\n * updateChecksum(nCycles)\n *\n * When checksum generation is enabled (fChecksum is true), runCPU() asks stepCPU() to execute a minimum\n * number of cycles (1), effectively limiting execution to a single instruction, and then we're called with\n * the exact number cycles that were actually executed. This should give us instruction-granular checksums\n * at precise intervals that are 100% repeatable.\n *\n * @this {CPU}\n * @param {number} nCycles\n */\n updateChecksum(nCycles)\n {\n if (this.flags.checksum) {\n /*\n * Get a 32-bit summation of the current CPU state and add it to our running 32-bit checksum\n */\n var fDisplay = false;\n this.counts.nChecksum = (this.counts.nChecksum + this.getChecksum())|0;\n this.counts.nCyclesChecksumNext -= nCycles;\n if (this.counts.nCyclesChecksumNext <= 0) {\n this.counts.nCyclesChecksumNext += this.counts.nCyclesChecksumInterval;\n fDisplay = true;\n }\n if (this.counts.nCyclesChecksumStop >= 0) {\n if (this.counts.nCyclesChecksumStop <= this.getCycles()) {\n this.counts.nCyclesChecksumInterval = this.counts.nCyclesChecksumStop = -1;\n this.resetChecksum();\n this.stopCPU();\n fDisplay = true;\n }\n }\n if (fDisplay) this.displayChecksum();\n }\n }\n\n /**\n * displayChecksum()\n *\n * When checksum generation is enabled (fChecksum is true), this is called to provide a crude log of all\n * checksums generated at the specified cycle intervals, as specified by the \"csStart\" and \"csInterval\" parmsCPU\n * properties).\n *\n * @this {CPU}\n */\n displayChecksum()\n {\n this.println(this.getCycles() + \" cycles: \" + \"checksum=\" + Str.toHex(this.counts.nChecksum));\n }\n\n /**\n * displayValue(sLabel, nValue, cch)\n *\n * This is principally for displaying register values, but in reality, it can be used to display any\n * numeric (hex) value bound to the given label.\n *\n * @this {CPU}\n * @param {string} sLabel\n * @param {number} nValue\n * @param {number} cch\n */\n displayValue(sLabel, nValue, cch)\n {\n if (this.bindings[sLabel]) {\n if (nValue === undefined) {\n this.setError(\"Value for \" + sLabel + \" is invalid\");\n this.stopCPU();\n }\n var sVal;\n if (!this.flags.running || this.flags.displayLiveRegs) {\n sVal = Str.toHex(nValue, cch);\n } else {\n sVal = \"--------\".substr(0, cch);\n }\n /*\n * TODO: Determine if this test actually avoids any redrawing when a register hasn't changed, and/or if\n * we should maintain our own (numeric) cache of displayed register values (to avoid creating these temporary\n * string values that will have to garbage-collected), and/or if this is actually slower, and/or if I'm being\n * too obsessive.\n */\n if (this.bindings[sLabel].textContent != sVal) this.bindings[sLabel].textContent = sVal;\n }\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {CPU}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"run\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var cpu = this;\n var fBound = false;\n\n switch (sBinding) {\n case \"power\":\n case \"reset\":\n /*\n * The \"power\" and \"reset\" buttons are functions of the entire computer, not just the CPU,\n * but it's not always convenient to stick a power button in the Computer component definition,\n * so we record those bindings here and pass them on to the Computer component in initBus().\n */\n this.bindings[sBinding] = control;\n fBound = true;\n break;\n\n case \"run\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickRun() {\n var fRunning = cpu.flags.running;\n if (!cpu.cmp || !cpu.cmp.checkPower()) return;\n /*\n * We snapped the CPU's running flag before calling checkPower() because there are rare (REPOWER)\n * situations where checkPower() will have started the CPU as well. So toggle the CPU state ONLY\n * if the running flag remains unchanged.\n */\n if (fRunning == cpu.flags.running) {\n if (!cpu.flags.running) {\n cpu.startCPU(true);\n } else {\n cpu.stopCPU(true);\n }\n }\n };\n fBound = true;\n break;\n\n case \"speed\":\n this.bindings[sBinding] = control;\n fBound = true;\n break;\n\n case \"setSpeed\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickSetSpeed() {\n cpu.setSpeed(cpu.counts.nTargetMultiplier << 1, true);\n };\n control.textContent = this.getSpeedTarget();\n fBound = true;\n break;\n\n default:\n break;\n }\n return fBound;\n }\n\n /**\n * setBurstCycles(nCycles)\n *\n * This function is used by the ChipSet component whenever a very low timer count is set.\n *\n * @this {CPU}\n * @param {number} nCycles is the target number of cycles to drop the current burst to\n * @return {boolean}\n */\n setBurstCycles(nCycles)\n {\n if (this.flags.running) {\n var nDelta = this.nStepCycles - nCycles;\n /*\n * NOTE: If nDelta is negative, we will actually be increasing nStepCycles and nBurstCycles.\n * Which is OK, but if we're also taking snapshots of the cycle counts, to make sure that instruction\n * costs are being properly assessed, then we need to update nSnapCycles as well.\n *\n * TODO: If the delta is negative, we could simply ignore the request, but we must first carefully\n * consider the impact on the ChipSet timers.\n */\n this.nStepCycles -= nDelta;\n this.nBurstCycles -= nDelta;\n return true;\n }\n return false;\n }\n\n /**\n * addCycles(nCycles, fEndStep)\n *\n * @this {CPU}\n * @param {number} nCycles\n * @param {boolean} [fEndStep]\n */\n addCycles(nCycles, fEndStep)\n {\n this.nTotalCycles += nCycles;\n if (fEndStep) {\n this.nBurstCycles = this.nStepCycles = 0;\n }\n }\n\n /**\n * calcCycles()\n *\n * Calculate the maximum number of cycles we should attempt to process before the next yield.\n *\n * @this {CPU}\n */\n calcCycles()\n {\n var nMultiplier = this.counts.mhzCurrent / this.counts.mhzBase;\n if (!nMultiplier || nMultiplier > this.counts.nTargetMultiplier) {\n nMultiplier = this.counts.nTargetMultiplier;\n }\n this.counts.nCyclesPerYield = Math.floor(this.counts.nBaseCyclesPerSecond / CPU.YIELDS_PER_SECOND * nMultiplier);\n this.counts.nCurrentMultiplier = nMultiplier;\n }\n\n /**\n * getCycles(fScaled)\n *\n * getCycles() returns the number of cycles executed so far. Note that we can be called after\n * runCPU() OR during runCPU(), perhaps from a handler triggered during the current run's stepCPU(),\n * so nRunCycles must always be adjusted by number of cycles stepCPU() was asked to run (nBurstCycles),\n * less the number of cycles it has yet to run (nStepCycles).\n *\n * nRunCycles is zeroed whenever the CPU is halted or the CPU speed is changed, which is why we also\n * have nTotalCycles, which accumulates all nRunCycles before we zero it. However, nRunCycles and\n * nTotalCycles eventually get reset by calcSpeed(), to avoid overflow, so components that rely on\n * getCycles() returning steadily increasing values should also be prepared for a reset at any time.\n *\n * @this {CPU}\n * @param {boolean} [fScaled] is true if the caller wants a cycle count relative to a multiplier of 1\n * @return {number}\n */\n getCycles(fScaled)\n {\n var nCycles = this.nTotalCycles + this.nRunCycles + this.nBurstCycles - this.nStepCycles;\n if (fScaled && this.counts.nTargetMultiplier > 1 && this.counts.mhzCurrent > this.counts.mhzBase) {\n /*\n * We could scale the current cycle count by the current speed (this.counts.mhzCurrent); eg:\n *\n * nCycles = Math.round(nCycles / (this.counts.mhzCurrent / this.counts.mhzBase));\n *\n * but that speed will fluctuate somewhat: large fluctuations at first, but increasingly smaller\n * fluctuations after each burst of instructions that runCPU() executes.\n *\n * Alternatively, we can scale the cycle count by the multiplier, which is good in that the\n * multiplier doesn't vary once the user changes it, but a potential downside is that the\n * multiplier might be set too high, resulting in a target speed that's higher than the effective\n * speed is able to reach.\n *\n * Also, if multipliers were always limited to a power-of-two, then this could be calculated\n * with a simple shift. However, only the \"setSpeed\" UI binding limits it that way; the Debugger\n * interface allows any value, as does the CPU \"multiplier\" parmsCPU property (from the machine's\n * XML file).\n */\n nCycles = Math.round(nCycles / this.counts.nTargetMultiplier);\n }\n return nCycles;\n }\n\n /**\n * getBaseCyclesPerSecond()\n *\n * This returns the CPU's base speed (ie, the original cycles per second defined for the machine)\n *\n * @this {CPU}\n * @return {number}\n */\n getBaseCyclesPerSecond()\n {\n return this.counts.nBaseCyclesPerSecond;\n }\n\n /**\n * getCurrentCyclesPerSecond()\n *\n * This returns the CPU's current speed (ie, the actual cycles per second, according the current multiplier)\n *\n * @this {CPU}\n * @return {number}\n */\n getCurrentCyclesPerSecond()\n {\n return (this.counts.nBaseCyclesPerSecond * this.counts.nCurrentMultiplier)|0;\n }\n\n /**\n * resetCycles()\n *\n * Resets speed and cycle information as part of any reset() or restore(); this typically occurs during powerUp().\n * It's important that this be called BEFORE the actual restore() call, because restore() may want to call setSpeed(),\n * which in turn assumes that all the cycle counts have been initialized to sensible values.\n *\n * @this {CPU}\n */\n resetCycles()\n {\n this.nTotalCycles = this.nRunCycles = this.nBurstCycles = this.nStepCycles = 0;\n this.resetChecksum();\n this.setSpeed(this.counts.nBaseMultiplier);\n }\n\n /**\n * getSpeed()\n *\n * @this {CPU}\n * @return {number} the current speed multiplier\n */\n getSpeed()\n {\n return this.counts.nTargetMultiplier;\n }\n\n /**\n * getSpeedCurrent()\n *\n * @this {CPU}\n * @return {string} the current speed, in mhz, as a string formatted to two decimal places\n */\n getSpeedCurrent()\n {\n return ((this.flags.running && this.counts.mhzCurrent)? (this.counts.mhzCurrent.toFixed(2) + \"Mhz\") : \"Stopped\");\n }\n\n /**\n * getSpeedTarget()\n *\n * @this {CPU}\n * @return {string} the target speed, in mhz, as a string formatted to two decimal places\n */\n getSpeedTarget()\n {\n return this.counts.mhzTarget.toFixed(2) + \"Mhz\";\n }\n\n /**\n * setSpeed(nMultiplier, fUpdateFocus)\n *\n * @this {CPU}\n * @param {number} [nMultiplier] is the new proposed multiplier (reverts to default if target was too high)\n * @param {boolean} [fUpdateFocus] is true to update Computer focus\n * @return {boolean} true if successful, false if not\n *\n * @desc Whenever the speed is changed, the running cycle count and corresponding start time must be reset,\n * so that the next effective speed calculation obtains sensible results. In fact, when runCPU() initially calls\n * setSpeed() with no parameters, that's all this function does (it doesn't change the current speed setting).\n */\n setSpeed(nMultiplier, fUpdateFocus)\n {\n var fSuccess = true;\n if (nMultiplier !== undefined) {\n /*\n * If we haven't reached 90% (0.9) of the current target speed, revert to the default multiplier.\n */\n if (this.counts.mhzCurrent > 0 && this.counts.mhzCurrent < this.counts.mhzTarget * 0.9) {\n nMultiplier = this.counts.nBaseMultiplier;\n fSuccess = false;\n }\n this.counts.mhzCurrent = 0;\n this.counts.nTargetMultiplier = nMultiplier;\n var mhzTarget = this.counts.mhzBase * this.counts.nTargetMultiplier;\n if (this.counts.mhzTarget != mhzTarget) {\n this.counts.mhzTarget = mhzTarget;\n var sSpeed = this.getSpeedTarget();\n var controlSpeed = this.bindings[\"setSpeed\"];\n if (controlSpeed) controlSpeed.textContent = sSpeed;\n this.println(\"target speed: \" + sSpeed);\n }\n if (fUpdateFocus && this.cmp) this.cmp.updateFocus();\n }\n this.addCycles(this.nRunCycles);\n this.nRunCycles = 0;\n this.counts.msStartRun = this.counts.msEndThisRun = 0;\n this.calcCycles(); // calculate a new value for the current cycle multiplier\n this.resetTimers(); // and then update all the fixed-period timers using the new cycle multiplier\n return fSuccess;\n }\n\n /**\n * calcSpeed(nCycles, msElapsed)\n *\n * @this {CPU}\n * @param {number} nCycles\n * @param {number} msElapsed\n */\n calcSpeed(nCycles, msElapsed)\n {\n if (msElapsed) {\n this.counts.mhzCurrent = Math.round(nCycles / (msElapsed * 10)) / 100;\n if (msElapsed >= 86400000) {\n this.nTotalCycles = 0;\n if (this.chipset) this.chipset.updateAllTimers(true);\n this.setSpeed(); // reset all counters once per day so that we never have to worry about overflow\n }\n }\n }\n\n /**\n * calcStartTime()\n *\n * @this {CPU}\n */\n calcStartTime()\n {\n this.calcCycles();\n\n this.counts.nCyclesThisRun = 0;\n this.counts.msDiscount = 0;\n this.counts.msStartThisRun = Usr.getTime();\n if (!this.counts.msStartRun) {\n this.counts.msStartRun = this.counts.msStartThisRun;\n }\n\n /*\n * Try to detect situations where the browser may have throttled us, such as when the user switches\n * to a different tab; in those situations, Chrome and Safari may restrict setTimeout() callbacks\n * to roughly one per second.\n *\n * Another scenario: the user resizes the browser window. setTimeout() callbacks are not throttled,\n * but there can still be enough of a lag between the callbacks that CPU speed will be noticeably\n * erratic if we don't compensate for it here.\n *\n * We can detect throttling/lagging by verifying that msEndThisRun (which was set at the end of the\n * previous run and includes any requested sleep time) is comparable to the current msStartThisRun;\n * if the delta is significant, we compensate by bumping msStartRun forward by that delta.\n *\n * This shouldn't be triggered when the Debugger halts the CPU, because setSpeed() -- which is called\n * whenever the CPU starts running again -- zeroes msEndThisRun.\n *\n * This also won't do anything about other internal delays; for example, Debugger message() calls.\n * By the time the message() function has called yieldCPU(), the cost of the message has already been\n * incurred, so it will be end up being charged against the instruction(s) that triggered it.\n *\n * TODO: Consider calling yieldCPU() sooner from message(), so that it can arrange for the msEndThisRun\n * \"snapshot\" to occur sooner; it's unclear, however, whether that will really improve the CPU's ability\n * to hit its target speed, since any instruction that displays a message is unavoidably slooooow.\n */\n var msDelta = 0;\n if (this.counts.msEndThisRun) {\n msDelta = this.counts.msStartThisRun - this.counts.msEndThisRun;\n if (msDelta > this.counts.msPerYield) {\n this.counts.msStartRun += msDelta;\n /*\n * Bumping msStartRun forward should NEVER cause it to exceed msStartThisRun; however, just\n * in case, I make absolutely sure it cannot happen, since doing so could result in negative\n * speed calculations.\n */\n\n if (this.counts.msStartRun > this.counts.msStartThisRun) {\n this.counts.msStartRun = this.counts.msStartThisRun;\n }\n }\n }\n }\n\n /**\n * calcRemainingTime()\n *\n * @this {CPU}\n * @return {number}\n */\n calcRemainingTime()\n {\n this.counts.msEndThisRun = Usr.getTime();\n\n if (this.counts.msDiscount) {\n this.counts.msStartRun += this.counts.msDiscount;\n this.counts.msStartThisRun += this.counts.msDiscount;\n }\n\n var msYield = this.counts.msPerYield;\n if (this.counts.nCyclesThisRun) {\n /*\n * Normally, we would assume we executed a full quota of work over msPerYield, but since the CPU\n * now has the option of calling yieldCPU(), that might not be true. If nCyclesThisRun is correct, then\n * the ratio of nCyclesThisRun/nCyclesPerYield should represent the percentage of work we performed,\n * and so applying that percentage to msPerYield should give us a better estimate of work vs. time.\n */\n msYield = Math.round(msYield * this.counts.nCyclesThisRun / this.counts.nCyclesPerYield);\n }\n\n var msElapsedThisRun = this.counts.msEndThisRun - this.counts.msStartThisRun;\n var msRemainsThisRun = msYield - msElapsedThisRun;\n\n /*\n * We could pass only \"this run\" results to calcSpeed():\n *\n * nCycles = this.counts.nCyclesThisRun;\n * msElapsed = msElapsedThisRun;\n *\n * but it seems preferable to use longer time periods and hopefully get a more accurate speed.\n */\n var nCycles = this.nRunCycles;\n var msElapsed = this.counts.msEndThisRun - this.counts.msStartRun;\n\n if (MAXDEBUG && msRemainsThisRun < 0 && this.counts.nTargetMultiplier > 1) {\n this.println(\"warning: updates @\" + msElapsedThisRun + \"ms (prefer \" + Math.round(msYield) + \"ms)\");\n }\n\n this.calcSpeed(nCycles, msElapsed);\n\n if (msRemainsThisRun < 0) {\n /*\n * Try \"throwing out\" the effects of large anomalies, by moving the overall run start time up;\n * ordinarily, this should only happen when the someone is using an external Debugger or some other\n * tool or feature that is interfering with our overall execution.\n */\n if (msRemainsThisRun < -1000) {\n this.counts.msStartRun -= msRemainsThisRun;\n }\n /*\n * If the last burst took MORE time than we allotted (ie, it's taking more than 1 second to simulate\n * nBaseCyclesPerSecond), all we can do is yield for as little time as possible (ie, 0ms) and hope\n * that the simulation is at least usable.\n */\n msRemainsThisRun = 0;\n }\n else if (this.counts.mhzCurrent < this.counts.mhzTarget) {\n msRemainsThisRun = 0;\n }\n\n if (DEBUG && this.messageEnabled(Messages.CPU)) {\n /*\n * Every time the browser gives us another chance to run, we want to display our targets for that run\n * here, followed by what we accomplished in that run.\n */\n this.printMessage(Str.sprintf(\"%3dms run %3dms wait %6dcy %6.2fmhz %6dms total %8dcy total %6.2fmhz total\",\n msElapsedThisRun,\n msRemainsThisRun,\n this.counts.nCyclesThisRun,\n Math.round(this.counts.nCyclesThisRun / (msElapsedThisRun * 10)) / 100,\n msElapsed,\n nCycles,\n this.counts.mhzCurrent\n ));\n }\n\n this.counts.msEndThisRun += msRemainsThisRun;\n\n return msRemainsThisRun;\n }\n\n /**\n * addTimer(id, callBack, ms)\n *\n * Components that want to have timers that fire after some number of milliseconds call addTimer() to create\n * the timer, and then setTimer() when they want to arm it. Alternatively, they can specify an automatic timeout\n * value (in milliseconds) to have the timer fire automatically at regular intervals. There is currently\n * no removeTimer() because these are generally used for the entire lifetime of a component.\n *\n * Internally, each timer entry is a preallocated Array with the following entries:\n *\n * [0]: timer ID\n * [1]: countdown value, in cycles\n * [2]: automatic setTimer value, if any, in milliseconds\n * [3]: callback function\n *\n * A timer is initially dormant; dormant timers have a countdown value of -1 (although any negative number\n * will suffice) and active timers have a non-negative value.\n *\n * Why not use JavaScript's setTimeout() instead? Good question. For a good answer, see setTimer() below.\n *\n * @this {CPU}\n * @param {string} id\n * @param {function()} callBack\n * @param {number} [ms] (if set, enables automatic setTimer calls)\n * @return {number} timer index\n */\n addTimer(id, callBack, ms = -1)\n {\n var iTimer = this.aTimers.length;\n this.aTimers.push([id, -1, ms, callBack]);\n if (ms >= 0) this.setTimer(iTimer, ms);\n return iTimer;\n }\n\n /**\n * clearTimer(iTimer)\n *\n * Using the timer index from a previous addTimer() call, this clears that timer.\n *\n * @this {CPU}\n * @param {number} iTimer\n * @return {boolean}\n */\n clearTimer(iTimer)\n {\n if (iTimer >= 0 && iTimer < this.aTimers.length) {\n this.aTimers[iTimer][1] = -1;\n return true;\n }\n return false;\n }\n\n /**\n * findTimer(id)\n *\n * @this {CPU}\n * @param {string} id\n * @return {Array|null}\n */\n findTimer(id)\n {\n for (var iTimer = 0; iTimer < this.aTimers.length; iTimer++) {\n var timer = this.aTimers[iTimer];\n if (timer[0] == id) return timer;\n }\n return null;\n }\n\n /**\n * isTimerSet(iTimer)\n *\n * @this {CPU}\n * @param {number} iTimer\n * @return {boolean}\n */\n isTimerSet(iTimer)\n {\n if (iTimer >= 0 && iTimer < this.aTimers.length) {\n return this.aTimers[iTimer][1] >= 0;\n }\n return false;\n }\n\n /**\n * setTimer(iTimer, ms, fReset)\n *\n * Using the timer index from a previous addTimer() call, this sets that timer to fire after the\n * specified number of milliseconds.\n *\n * This is preferred over JavaScript's setTimeout(), because all our timers are effectively paused when\n * the CPU is paused (eg, when the Debugger halts execution). Moreover, setTimeout() handlers only run after\n * runCPU() yields, which is far too granular for some components (eg, when the SerialPort tries to simulate\n * interrupts at 9600 baud).\n *\n * Ideally, the only function that would use setTimeout() is runCPU(), while the rest of the components\n * use setTimer(); however, due to legacy code (ie, code that predates these functions) and/or laziness,\n * that may not be the case.\n *\n * @this {CPU}\n * @param {number} iTimer\n * @param {number} ms (converted into a cycle countdown internally)\n * @param {boolean} [fReset] (true if the timer should be reset even if already armed)\n * @return {number} (number of cycles used to arm timer, or -1 if error)\n */\n setTimer(iTimer, ms, fReset)\n {\n var nCycles = -1;\n if (iTimer >= 0 && iTimer < this.aTimers.length) {\n var timer = this.aTimers[iTimer];\n if (fReset || timer[1] < 0) {\n nCycles = this.getMSCycles(ms);\n /*\n * If the CPU is currently executing a burst of cycles, the number of cycles it has executed in\n * that burst so far must NOT be charged against the cycle timeout we're about to set. The simplest\n * way to resolve that is to immediately call endBurst() and bias the cycle timeout by the number\n * of cycles that the burst executed.\n */\n if (this.flags.running) {\n nCycles += this.endBurst();\n }\n timer[1] = nCycles;\n }\n }\n return nCycles;\n }\n\n /**\n * setTimerCycles(iTimer, nCycles)\n *\n * A cycle-based version of setTimer(), used to help wean components off of functions like setBurstCycles().\n *\n * @this {CPU}\n * @param {number} iTimer\n * @param {number} nCycles\n * @return {boolean}\n */\n setTimerCycles(iTimer, nCycles)\n {\n if (iTimer >= 0 && iTimer < this.aTimers.length) {\n var timer = this.aTimers[iTimer];\n /*\n * If the CPU is currently executing a burst of cycles, the number of cycles it has executed in\n * that burst so far must NOT be charged against the cycle timeout we're about to set. The simplest\n * way to resolve that is to immediately call endBurst() and bias the cycle timeout by the number\n * of cycles that the burst executed.\n */\n if (this.flags.running) {\n nCycles += this.endBurst();\n }\n timer[1] = nCycles;\n return true;\n }\n return false;\n }\n\n /**\n * getMSCycles(ms)\n *\n * @this {CPU}\n * @param {number} ms\n * @return {number} number of corresponding cycles\n */\n getMSCycles(ms)\n {\n return ((this.counts.nBaseCyclesPerSecond * this.counts.nCurrentMultiplier) / 1000 * ms)|0;\n }\n\n /**\n * getBurstCycles(nCycles)\n *\n * @this {CPU}\n * @param {number} nCycles (maximum number of cycles to execute)\n * @return {number}\n */\n getBurstCycles(nCycles)\n {\n for (var iTimer = this.aTimers.length - 1; iTimer >= 0; iTimer--) {\n var timer = this.aTimers[iTimer];\n\n if (timer[1] < 0) continue;\n if (nCycles > timer[1]) {\n nCycles = timer[1];\n }\n }\n return nCycles;\n }\n\n /**\n * saveTimers()\n *\n * @this {CPU}\n * @return {Array}\n */\n saveTimers()\n {\n var aTimerStates = [];\n for (var iTimer = 0; iTimer < this.aTimers.length; iTimer++) {\n var timer = this.aTimers[iTimer];\n aTimerStates.push([timer[0], timer[1], timer[2]]);\n }\n return aTimerStates;\n }\n\n /**\n * restoreTimers(aTimerStates)\n *\n * @this {CPU}\n * @param {Array} aTimerStates\n */\n restoreTimers(aTimerStates)\n {\n for (var iTimerState = 0; iTimerState < aTimerStates.length; iTimerState++) {\n var state = aTimerStates[iTimerState];\n var timer = this.findTimer(state[0]);\n if (timer) {\n timer[1] = state[1];\n timer[2] = state[2];\n }\n }\n }\n\n /**\n * resetTimers()\n *\n * When the target CPU speed multiplier is altered, it's a good idea to run through all the timers that\n * have a fixed millisecond period and re-arm them, because the timers are using cycle counts that were based\n * on a previous multiplier.\n *\n * @this {CPU}\n */\n resetTimers()\n {\n for (var iTimer = this.aTimers.length - 1; iTimer >= 0; iTimer--) {\n var timer = this.aTimers[iTimer];\n if (timer[2] >= 0) this.setTimer(iTimer, timer[2], true);\n }\n }\n\n /**\n * updateTimers(nCycles)\n *\n * Used by runCPU() to reduce all active timer countdown values by the number of cycles just executed;\n * this is the function that actually \"fires\" any timer(s) whose countdown has reached (or dropped below)\n * zero, invoking their callback function.\n *\n * @this {CPU}\n * @param {number} nCycles (number of cycles actually executed)\n */\n updateTimers(nCycles)\n {\n for (var iTimer = this.aTimers.length - 1; iTimer >= 0; iTimer--) {\n var timer = this.aTimers[iTimer];\n\n if (timer[1] < 0) continue;\n timer[1] -= nCycles;\n if (timer[1] <= 0) {\n if (DEBUG && this.messageEnabled(Messages.CPU | Messages.TIMER)) { // CPU TIMER message (as opposed to CHIPSET TIMER message)\n this.printMessage(\"updateTimer(\" + nCycles + \"): firing \" + timer[0] + \" with only \" + (timer[1] + nCycles) + \" cycles left\");\n }\n timer[1] = -1; // zero is technically an \"active\" value, so ensure the timer is dormant now\n timer[3](); // safe to invoke the callback function now\n if (timer[2] >= 0) {\n this.setTimer(iTimer, timer[2]);\n if (DEBUG && this.messageEnabled(Messages.CPU | Messages.TIMER)) { // CPU TIMER message (as opposed to CHIPSET TIMER message)\n this.printMessage(\"updateTimer(\" + nCycles + \"): rearming \" + timer[0] + \" for \" + timer[2] + \"ms (\" + timer[1] + \" cycles)\");\n }\n }\n }\n }\n }\n\n /**\n * endBurst()\n *\n * @this {CPU}\n * @return {number} (number of cycles executed in the most recent burst)\n */\n endBurst()\n {\n var nCycles = this.nBurstCycles - this.nStepCycles;\n this.nBurstCycles = this.nStepCycles = 0;\n this.counts.nCyclesThisRun += nCycles;\n this.nRunCycles += nCycles;\n return nCycles;\n }\n\n /**\n * runCPU()\n *\n * @this {CPU}\n */\n runCPU()\n {\n this.idRunTimeout = 0;\n if (!this.flags.running) return;\n\n /*\n * calcStartTime() initializes the cycle counter and timestamp for this runCPU() invocation.\n */\n this.calcStartTime();\n\n try {\n this.flags.yield = false;\n do {\n /*\n * getBurstCycles() tells us how many cycles to execute as a burst. The answer will always\n * be less than getCurrentCyclesPerSecond(), because at the very least, our own timer fires more than\n * once per second.\n */\n var nCycles = this.getBurstCycles(this.flags.checksum? 1 : this.getCurrentCyclesPerSecond());\n\n if (this.chipset) {\n this.chipset.updateAllTimers();\n nCycles = this.chipset.getTimerCycleLimit(0, nCycles);\n nCycles = this.chipset.getRTCCycleLimit(nCycles);\n }\n\n /*\n * Execute the burst.\n */\n try {\n this.stepCPU(nCycles);\n }\n catch(exception) {\n if (typeof exception != \"number\") throw exception;\n if (MAXDEBUG) this.println(\"CPU exception \" + Str.toHexByte(exception));\n /*\n * TODO: If we ever get into a situation where every single instruction is generating a fault\n * (eg, if an 8088 executes opcode 0xFF 0xFF, which is incorrectly routed to helpFault() instead\n * of fnGRPUndefined()), the browser may hang because we're failing to yield often enough.\n * This is likely because the thrown exceptions are taking MUCH longer than normal instructions,\n * throwing off our burst calculations. We need to either adjust the burst or break out of the\n * DO-WHILE loop on every exception.\n */\n }\n\n /*\n * Terminate the burst, returning the number of cycles that stepCPU() actually ran.\n */\n nCycles = this.endBurst();\n\n /*\n * Update all timers, firing those whose cycle countdowns have reached (or dropped below) zero.\n */\n this.updateTimers(nCycles);\n this.updateChecksum(nCycles);\n\n } while (this.flags.running && !this.flags.yield);\n }\n catch (e) {\n this.stopCPU();\n this.updateCPU();\n if (this.cmp) this.cmp.stop(Usr.getTime(), this.getCycles());\n this.setError(e.stack || e.message);\n return;\n }\n\n if (this.flags.running) {\n\n this.idRunTimeout = setTimeout(this.onRunTimeout, this.calcRemainingTime());\n }\n }\n\n /**\n * startCPU(fUpdateFocus)\n *\n * For use by any component that wants to start the CPU.\n *\n * @param {boolean} [fUpdateFocus]\n * @param {boolean} [fQuiet]\n * @return {boolean}\n */\n startCPU(fUpdateFocus, fQuiet)\n {\n if (this.isError()) {\n return false;\n }\n if (this.flags.running) {\n if (!fQuiet) this.println(this.toString() + \" busy\");\n return false;\n }\n if (this.idRunTimeout) {\n clearTimeout(this.idRunTimeout);\n this.idRunTimeout = 0;\n }\n /*\n * setSpeed() without a speed parameter leaves the selected speed in place, but also resets the\n * cycle counter and timestamp for the current series of runCPU() calls, and calculates the maximum number\n * of cycles for each burst based on the last known effective CPU speed.\n */\n this.setSpeed();\n this.flags.running = true;\n this.flags.starting = true;\n if (this.chipset) this.chipset.start();\n var controlRun = this.bindings[\"run\"];\n if (controlRun) controlRun.textContent = \"Halt\";\n if (this.cmp) {\n this.cmp.updateStatus(true);\n if (fUpdateFocus) this.cmp.updateFocus(!fQuiet);\n this.cmp.start(this.counts.msStartRun, this.getCycles());\n }\n\n this.idRunTimeout = setTimeout(this.onRunTimeout, 0);\n return true;\n }\n\n /**\n * stepCPU(nMinCycles)\n *\n * This will be implemented by the CPUX86 component.\n *\n * @this {CPU}\n * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored)\n * @return {number} of cycles executed; 0 indicates that the last instruction was not executed\n */\n stepCPU(nMinCycles)\n {\n return 0;\n }\n\n /**\n * stopCPU(fComplete)\n *\n * For use by any component that wants to stop the CPU.\n *\n * @this {CPU}\n * @param {boolean} [fComplete]\n * @return {boolean} true if the CPU was stopped, false if it was already stopped\n */\n stopCPU(fComplete)\n {\n var fStopped = false;\n if (this.flags.running) {\n this.endBurst();\n this.addCycles(this.nRunCycles);\n this.nRunCycles = 0;\n this.flags.running = false;\n if (this.chipset) this.chipset.stop();\n var controlRun = this.bindings[\"run\"];\n if (controlRun) controlRun.textContent = \"Run\";\n if (this.cmp) {\n this.cmp.stop(Component.getTime(), this.getCycles());\n this.cmp.updateStatus(true);\n }\n if (!this.dbg) this.status(\"Stopped\");\n fStopped = true;\n }\n this.flags.complete = fComplete;\n return fStopped;\n }\n\n /**\n * nonCPU(fn)\n *\n * Use this function to perform any work outside the scope of the CPU (eg, DOM updates),\n * to prevent that work from disrupting our speed calculations.\n *\n * @this {CPU}\n * @param {function()} fn (should return true only if the function actually performed any work)\n * @return {boolean}\n */\n nonCPU(fn)\n {\n var msStart = Usr.getTime();\n if (fn()) {\n var msStop = Usr.getTime();\n this.counts.msDiscount += msStop - msStart;\n return true;\n }\n return false;\n }\n\n /**\n * updateCPU(fForce)\n *\n * This used to be performed at the end of every stepCPU(), but runCPU() -- which relies upon\n * stepCPU() -- needed to have more control over when these updates are performed. However, for\n * other callers of stepCPU(), such as the Debugger, the combination of stepCPU() + updateCPU()\n * provides the old behavior.\n *\n * @this {CPU}\n * @param {boolean} [fForce] (true to force a Computer update; used by the Debugger)\n */\n updateCPU(fForce)\n {\n if (this.cmp) this.cmp.updateStatus(fForce);\n }\n\n /**\n * yieldCPU()\n *\n * Similar to stopCPU() with regard to how it resets various cycle countdown values, but the CPU\n * remains in a \"running\" state.\n *\n * @this {CPU}\n */\n yieldCPU()\n {\n this.flags.yield = true;\n /*\n * The Debugger calls yieldCPU() after every message() to ensure browser responsiveness, but it looks\n * odd for those messages to show CPU state changes but for the CPU's own status display to not (ditto\n * for the Video display), so I've added this call to try to keep things looking synchronized.\n */\n this.updateCPU();\n }\n}\n\nCPU.YIELDS_PER_SECOND = 30;\n\nCPU.BUTTONS = [\"power\", \"reset\"];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/cpux86.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * class CPUX86\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass CPUX86 extends CPU {\n /**\n * CPUX86(parmsCPU)\n *\n * The CPUX86 class uses the following (parmsCPU) properties:\n *\n * model: a string (eg, \"8088\") that should match one of the X86.MODEL values (default is \"8088\")\n * stepping: a string (eg, \"B1\") that should match one of the X86.STEPPING values (default is \"\")\n *\n * This extends the CPU class and passes any remaining parmsCPU properties to the CPU class\n * constructor, along with a default speed (cycles per second) based on the specified (or default)\n * CPU model number.\n *\n * The CPUX86 class was initially written to simulate a 8086/8088 microprocessor, although over time\n * it has evolved to support later microprocessors (eg, the 80186/80188 and the 80286, including\n * protected-mode support).\n *\n * This is a logical simulation, not a physical simulation, and performance is critical, second only\n * to the accuracy of the simulation when running real-world x86 software. Consequently, it takes a\n * few liberties with the operation of the simulated hardware, especially with regard to timings,\n * little-used features, etc. We do make an effort to maintain approximate instruction cycle counts,\n * but there are many other obstacles (eg, prefetch queue, wait states) to achieving accurate timings.\n *\n * For example, our 8237 DMA controller performs all DMA transfers immediately, since internally\n * they are all memory-to-memory, and attempting to interleave DMA cycles with instruction execution\n * cycles would hurt overall performance. Similarly, 8254 timer counters are updated only on-demand.\n *\n * The 8237 and 8254, along with the 8259 interrupt controller and several other \"chips\", are combined\n * into a single ChipSet component, to keep the number of components we juggle to a minimum.\n *\n * All that being said, this does not change the overall goal: to produce as accurate a simulation as\n * possible, within the limits of what JavaScript allows and how precisely/predictably it behaves.\n *\n * @this {CPUX86}\n * @param {Object} parmsCPU\n */\n constructor(parmsCPU)\n {\n var nCyclesDefault;\n var model = +parmsCPU['model'] || X86.MODEL_8088;\n\n switch(model) {\n case X86.MODEL_8088:\n default:\n nCyclesDefault = 4772727;\n break;\n case X86.MODEL_80286:\n nCyclesDefault = 6000000;\n break;\n case X86.MODEL_80386:\n nCyclesDefault = 16000000;\n break;\n }\n\n super(parmsCPU, nCyclesDefault);\n\n this.model = model;\n\n /*\n * We take the 'stepping' value, convert it to a hex value, and then add that to the model to provide\n * a single value that's unique for any given CPU stepping. If no stepping is provided, then stepping\n * is equal to model.\n */\n var stepping = parmsCPU['stepping'];\n this.stepping = model + (stepping? Str.parseInt(stepping, 16) : 0);\n\n /*\n * Initialize processor operation to match the requested model\n */\n this.initProcessor();\n\n /*\n * List of software interrupt notification functions: aIntNotify is an array, indexed by\n * interrupt number, where each element contains:\n *\n * registered function to call for every software interrupt\n *\n * The registered function is called with the linear address (LIP) following the software interrupt;\n * if any function returns false, the software interrupt will be skipped (presumed to be emulated),\n * and no further notification functions will be called.\n *\n * NOTE: Registered functions are called only for INT N instructions -- *not* INT 0x03 or INTO or the\n * INT 0x00 generated by a divide-by-zero or any other kind of interrupt (nor any interrupt simulated\n * with PUSHF/CALLF).\n *\n * aIntReturn is a hash of return address notifications set up by software interrupt notification\n * functions that want to receive return notifications. A software interrupt function must call\n * cpu.addIntReturn(fn).\n *\n * WARNING: There's no mechanism in place to insure that software interrupt return notifications don't\n * get \"orphaned\" if an interrupt handler bypasses the normal return path (INT 0x24 is one example of an\n * \"evil\" software interrupt).\n */\n this.aIntNotify = [];\n this.aIntReturn = [];\n\n /*\n * Since aReturnNotify is a \"sparse array\", this global count gives the CPU a quick way of knowing whether\n * or not RETF or IRET instructions need to bother calling checkIntReturn().\n */\n this.cIntReturn = 0;\n\n /*\n * A variety of stepCPU() state variables that don't strictly need to be initialized before the first\n * stepCPU() call, but it's good form to do so.\n */\n this.resetCycles();\n this.flags.complete = this.flags.debugCheck = false;\n\n /*\n * If there are no live registers to display, then updateStatus() can skip a bit....\n */\n this.cLiveRegs = 0;\n\n /*\n * We're just declaring aMemBlocks and associated Bus parameters here; they'll be initialized by initMemory()\n * when the Bus is initialized.\n */\n this.aBusBlocks = this.aMemBlocks = [];\n this.nBusMask = this.nMemMask = -1;\n this.nBlockShift = this.nBlockSize = this.nBlockLimit = this.nBlockTotal = this.nBlockMask = 0;\n\n if (PREFETCH) {\n this.cbPrefetch = 0;\n this.adwPrefetch = null;\n }\n\n /*\n * This initial resetRegs() call is important to create all the registers (eg, the SegX86 registers),\n * so that if/when we call restore(), it will have something to fill in.\n */\n this.resetRegs();\n }\n\n /**\n * initMemory(aMemBlocks, nBlockShift)\n *\n * Notification from Bus.initMemory(), giving us direct access to the entire memory space\n * (aMemBlocks). Since the CPU must perform additional layers of address decoding depending\n * on the mode (real-mode, protected-mode, paging), it's best if the CPU can avoid going\n * through the Bus component for every memory access.\n *\n * We also initialize a 32-bit prefetch queue, containing dword-aligned values; the queue is\n * an array of dwords indexed by a masked regLIP; for example, a queue of 4 dwords is indexed\n * by \"regLIP & 0xC\"; we use a sparse array to avoid right-shifting the index, like so:\n *\n * 0: [dword]\n * 4: [dword]\n * 8: [dword]\n * 12: [dword]\n *\n * The actual regLIP mask is CPUX86.PFINFO.IP_MASK; ie, (CPUX86.PFINFO.LENGTH - 1) & ~0x3.\n *\n * On refilling, the queue is always filled to capacity, and cbPrefetch is set to its maximum\n * value (eg, a value from 16 to 13, depending on whether \"regLIP & 0x3\" is 0, 1, 2 or 3).\n *\n * When a byte is requested from the queue, the dword is extracted from index \"regLIP & 0xC\"\n * and then shifted by 0, 8, 16, or 24, depending on whether \"regLIP & 0x3\" is 0, 1, 2 or 3\n * (ie, \"(regLIP & 0x3) << 3\").\n *\n * TODO: Consider how/whether to simulate an effective prefetch queue size of 4 bytes for an 8088,\n * 6 bytes for an 8086, 12 for an 80386, etc.\n *\n * @this {CPUX86}\n * @param {Array} aMemBlocks\n * @param {number} nBlockShift\n */\n initMemory(aMemBlocks, nBlockShift)\n {\n /*\n * aBusBlocks preserves the Bus block array for the life of the machine, whereas aMemBlocks\n * will be altered if/when the CPU enables paging. PAGEBLOCKS must be true when using Memory\n * blocks to simulate paging, ensuring that physical blocks and pages have the same size (4Kb).\n */\n this.aBusBlocks = this.aMemBlocks = aMemBlocks;\n this.nBlockShift = nBlockShift;\n this.nBlockSize = 1 << this.nBlockShift;\n this.nBlockLimit = this.nBlockSize - 1;\n this.nBlockTotal = aMemBlocks.length;\n this.nBlockMask = this.nBlockTotal - 1;\n if (PREFETCH) {\n // this.nBusCycles = 0;\n this.adwPrefetch = new Array(CPUX86.PFINFO.LENGTH);\n }\n }\n\n /**\n * setAddressMask(nBusMask)\n *\n * Notification from Bus.initMemory() and Bus.setA20(); the latter calls us whenever the physical\n * A20 line changes (note that on a 20-bit bus machine, address lines A20 and higher are always zero).\n *\n * For 32-bit bus machines (eg, 80386), nBusMask is never changed after the initial call, because A20\n * wrap-around is simulated by changing the physical memory map rather than altering the A20 bit in nBusMask.\n *\n * We maintain nMemMask separate from nBusMask, because when paging is enabled on the 80386, the CPU memory\n * functions are now dealing with linear addresses rather than physical addresses, so it would be incorrect\n * to apply nBusMask to those addresses; nMemMask must remain 0xffffffff (-1) for the duration. If we change\n * how A20 is simulated on the 80386, then enablePageBlocks() and disablePageBlocks() will need to override\n * nMemMask appropriately.\n *\n * TODO: Ideally, we would eliminate masking altogether of 32-bit addresses, but that would require different\n * sets of memory access functions for different machines (ie, those with 20-bit or 24-bit buses).\n *\n * @this {CPUX86}\n * @param {number} nBusMask\n */\n setAddressMask(nBusMask)\n {\n this.nBusMask = this.nMemMask = nBusMask;\n }\n\n /**\n * addMemBreak(addr, fWrite, fPhysical)\n *\n * NOTE: addMemBreak() could be merged with addMemCheck(), but the new merged interface would\n * have to provide one additional parameter indicating whether the Debugger or the CPU is the client.\n *\n * For now, this is simply a DEBUGGER-only interface.\n *\n * @this {CPUX86}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint\n * @param {boolean} [fPhysical] (true for physical breakpoint, false for linear)\n */\n addMemBreak(addr, fWrite, fPhysical)\n {\n if (DEBUGGER) {\n var iBlock = addr >>> this.nBlockShift;\n var aBlocks = (fPhysical? this.aBusBlocks : this.aMemBlocks);\n aBlocks[iBlock].addBreakpoint(addr & this.nBlockLimit, fWrite);\n /*\n * When a physical memory breakpoint is added, a fresh setPhysBlock() call is REQUIRED for any\n * linear mappings to that address. This is a bit of a sledgehammer solution, but at least it's a solution.\n */\n if (fPhysical) this.flushPageBlocks();\n }\n }\n\n /**\n * removeMemBreak(addr, fWrite, fPhysical)\n *\n * NOTE: removeMemBreak() could be merged with removeMemCheck(), but the new merged interface would\n * have to provide one additional parameter indicating whether the Debugger or the CPU is the client.\n *\n * For now, this is simply a DEBUGGER-only interface.\n *\n * @this {CPUX86}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint\n * @param {boolean} [fPhysical] (true for physical breakpoint, false for linear)\n */\n removeMemBreak(addr, fWrite, fPhysical)\n {\n if (DEBUGGER) {\n var iBlock = addr >>> this.nBlockShift;\n var aBlocks = (fPhysical? this.aBusBlocks : this.aMemBlocks);\n aBlocks[iBlock].removeBreakpoint(addr & this.nBlockLimit, fWrite);\n /*\n * When a physical memory breakpoint is removed, a fresh setPhysBlock() call is RECOMMENDED for any\n * linear mappings to that address. This is a bit of a sledgehammer solution, but at least it's a solution.\n */\n if (fPhysical) this.flushPageBlocks();\n }\n }\n\n /**\n * addMemCheck(addr, fWrite)\n *\n * These functions provide Debug register functionality to the CPU by leveraging the same Memory block-based\n * breakpoint support originally created for our built-in Debugger. Only minimal changes were required to the\n * Memory component, by adding additional checkMemoryException() call-outs from the \"checked\" Memory access\n * functions.\n *\n * Note that those call-outs occur only AFTER our own Debugger (if present) has checked the address and has\n * passed on it, because we want our own Debugger's breakpoints to take precedence over any breakpoints that\n * the emulated machine may have enabled.\n *\n * @this {CPUX86}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write check, false for a memory read check\n */\n addMemCheck(addr, fWrite)\n {\n var iBlock = addr >>> this.nBlockShift;\n this.aMemBlocks[iBlock].addBreakpoint(addr & this.nBlockLimit, fWrite, this);\n }\n\n /**\n * removeMemCheck(addr, fWrite)\n *\n * @this {CPUX86}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write check, false for a memory read check\n */\n removeMemCheck(addr, fWrite)\n {\n var iBlock = addr >>> this.nBlockShift;\n this.aMemBlocks[iBlock].removeBreakpoint(addr & this.nBlockLimit, fWrite);\n }\n\n /**\n * enablePageBlocks()\n *\n * Whenever the CPU turns on paging and/or updates CR3, this function is called to update our copy\n * of the Bus block array, to simulate paging. Whenever the CPU turns paging off, disablePageBlocks()\n * must be called to restore our copy of the Bus block array to its original (physical) mapping.\n *\n * This also requires PAGEBLOCKS be enabled, to ensure the Bus is configured with a 4Kb block size.\n *\n * The first time this function is called, aMemBlocks and aBusBlocks are identical, so aMemBlocks is\n * reinitialized with special UNPAGED Memory blocks that know how to perform page directory/page table\n * lookup and replace themselves with special PAGED Memory blocks that reference memory from the\n * appropriate block in aBusBlocks. A parallel array, aBlocksPaged, keeps track (by block number) of\n * which blocks have been PAGED, so that whenever CR3 is updated, those blocks can be quickly UNPAGED.\n *\n * @this {CPUX86}\n */\n enablePageBlocks()\n {\n if (!PAGEBLOCKS) {\n this.setError(\"PAGEBLOCKS support required\");\n return;\n }\n var iBlock;\n if (this.aMemBlocks === this.aBusBlocks) {\n this.aMemBlocks = new Array(this.nBlockTotal);\n /*\n * TODO: Currently we allocate only one UNPAGED block for the entire linear address space;\n * only when a block is touched and becomes PAGED do we allocate a dedicated Memory block\n * for that slot. One potential downside to using a single UNPAGED block, however, is that\n * it will accumulate all breakpoints for all UNPAGED blocks, requiring copyBreakpoints() to\n * do extra work to figure out which breakpoints should be copied (ie, removed) from the\n * outgoing block -- which it can't currently do, because blocks only keep track of the total\n * number of breakpoints, not the actual breakpoint addresses.\n *\n * So, Memory blocks either need to start maintaining their own breakpoint address lists,\n * or we need to allocate separate (empty) UNPAGED blocks for every slot. I've not tackled\n * this yet, because it's largely just a debugging issue.\n *\n * Notice that when we call copyBreakpoints() here, it's merely to initialize the new block;\n * we make no attempt to copy any breakpoints from physical blocks to linear blocks, although\n * perhaps we should. The plan for our Debugger is to maintain separate physical and linear\n * breakpoint address lists, but what about CPU Debug registers? If the CPU sets the Debug\n * registers, then enables paging, do all the previous Debug register addresses automatically\n * become linear addresses? I'm guessing they do.\n */\n this.blockUnpaged = new Memory(null, 0, 0, Memory.TYPE.UNPAGED, null, this);\n this.blockUnpaged.copyBreakpoints(this.dbg);\n for (iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {\n this.aMemBlocks[iBlock] = this.blockUnpaged;\n }\n /*\n * We also use a special \"empty\" Memory block that mapPageBlock() can pass back to callers\n * whenever a valid block cannot be found for an UNPAGED block. Under normal conditions,\n * an invalid block will trigger a fault, so memEmpty will never actually be returned, but\n * if the Debugger is suppressing faults or calling probeAddr(), returning memEmpty is helpful.\n */\n this.memEmpty = new Memory();\n\n /*\n * Initialize our PAGEBLOCKS cache (see acquirePageBlock() and releasePageBlock()).\n */\n this.aCacheBlocks = new Array(CPUX86.PAGEBLOCKS_CACHE);\n this.iCacheBlocks = 0;\n } else {\n /*\n * Our equivalent of a TLB flush. NOTE: We do not attempt to simulate an actual TLB; our\n * aMemBlocks array will \"cache\" as many pages (ie, allow as many PAGED block) as there are\n * entries in the array. I'm assuming we won't run into any system software that relies on\n * a constrained TLB -- at least not from the 80386 era, which is all we're emulating.\n */\n for (var i = 0; i < this.aBlocksPaged.length; i++) {\n iBlock = this.aBlocksPaged[i];\n this.releasePageBlock(this.aMemBlocks[iBlock]);\n this.aMemBlocks[iBlock] = this.blockUnpaged;\n }\n }\n this.aBlocksPaged = [];\n }\n\n /**\n * flushPageBlocks()\n *\n * @this {CPUX86}\n */\n flushPageBlocks()\n {\n if (this.regCR0 & X86.CR0.PG) this.enablePageBlocks();\n }\n\n /**\n * acquirePageBlock(addr)\n *\n * This implements a simple paged memory block cache. Candidates for caching must be released via\n * releasePageBlock().\n *\n * After acquiring a block from this cache, the caller MUST use setPhysBlock() to properly reinitialize\n * it for the new given linear address.\n *\n * @this {CPUX86}\n * @param {number} addr\n * @return {Memory}\n */\n acquirePageBlock(addr)\n {\n var block;\n if (this.iCacheBlocks > 0) {\n block = this.aCacheBlocks[--this.iCacheBlocks];\n /*\n * Paged memory blocks are all very generic and contain no memory of their own, so the fact\n * that we're not calling the Memory constructor to reinitialize it is OK. setPhysBlock() is\n * what's critical, and the caller will take care of that. However, to avoid any confusion,\n * especially when debugging, there are a few properties we should reinitialize, hence init().\n */\n block.init(addr);\n } else {\n block = new Memory(addr, 0, 0, Memory.TYPE.PAGED);\n }\n return block;\n }\n\n /**\n * releasePageBlock(block)\n *\n * Instead of simply tossing Memory blocks onto the garbage collector's heap, we'll retain a maximum\n * number (CPUX86.PAGEBLOCKS_CACHE) in aCacheBlocks, with iCacheBlocks pointing to the next free element.\n *\n * @this {CPUX86}\n * @param {Memory} block\n */\n releasePageBlock(block)\n {\n\n if (this.iCacheBlocks < CPUX86.PAGEBLOCKS_CACHE) {\n this.aCacheBlocks[this.iCacheBlocks++] = block;\n }\n }\n\n /**\n * mapPageBlock(addr, fWrite, fSuppress)\n *\n * Locate the corresponding physical PDE, PTE and memory blocks for the given linear address, and then\n * upgrade the block from an UNPAGED Memory block to a new PAGED Memory block; all future accesses to\n * the current page will go directly to that block, instead of coming here through the UNPAGED block\n * handlers.\n *\n * Note that since the incoming address (addr) is a linear address, we never need to mask it with nBusMask,\n * but all the intermediate (PDE, PTE) and final physical addresses we calculate should still be masked.\n *\n * Granted, nBusMask on a 32-bit bus is generally going to be 0xffffffff (-1), so masking might seem like\n * a waste of time; however, if we decide to once again rely on nBusMask for emulating A20 wrap-around\n * (instead of changing the physical memory map to alias the 2nd Mb to the 1st Mb), then performing\n * consistent masking will be important.\n *\n * Also, addrPDE, addrPTE and addrPhys do not need any offsets added to them, because we immediately shift\n * the offset portion of those addresses out. But for now, at least for debugging and documentation purposes,\n * my preference is to include the offset in the address calculations.\n *\n * Besides, this should not be a performance-critical function; it's normally called only once per UNPAGED\n * page. Obviously, if CR3 is constantly being updated, that will trigger repeated calls to enablePageBlocks(),\n * which will perform our equivalent of a TLB flush (ie, resetting all PAGED blocks back to UNPAGED blocks).\n * That would hurt our performance, but it would hurt performance on a real machine as well, so presumably\n * CR3 updates will be minimal.\n *\n * @this {CPUX86}\n * @param {number} addr is a linear address\n * @param {boolean} fWrite (true if called for a write, false if for a read)\n * @param {boolean} [fSuppress] (true if any faults, remapping, etc should be suppressed)\n * @return {Memory}\n */\n mapPageBlock(addr, fWrite, fSuppress)\n {\n var offPDE = (addr & X86.LADDR.PDE.MASK) >>> X86.LADDR.PDE.SHIFT;\n var addrPDE = this.regCR3 + offPDE;\n\n /*\n * bus.getLong(addrPDE) would be simpler, but setPhysBlock() needs to know blockPDE and offPDE, too.\n * TODO: Since we're immediately shifting addrPDE by nBlockShift, then we could also skip adding offPDE.\n */\n var blockPDE = this.aBusBlocks[(addrPDE & this.nBusMask) >>> this.nBlockShift];\n var pde = blockPDE.readLong(offPDE);\n\n if (!(pde & X86.PTE.PRESENT)) {\n if (!fSuppress) X86.helpPageFault.call(this, addr, false, fWrite);\n return this.memEmpty;\n }\n\n if (!(pde & X86.PTE.USER) && this.nCPL == 3) {\n if (!fSuppress) X86.helpPageFault.call(this, addr, true, fWrite);\n return this.memEmpty;\n }\n\n var offPTE = (addr & X86.LADDR.PTE.MASK) >>> X86.LADDR.PTE.SHIFT;\n var addrPTE = (pde & X86.PTE.FRAME) + offPTE;\n\n /*\n * bus.getLong(addrPTE) would be simpler, but setPhysBlock() needs to know blockPTE and offPTE, too.\n * TODO: Since we're immediately shifting addrPDE by nBlockShift, then we could also skip adding offPTE.\n */\n var blockPTE = this.aBusBlocks[(addrPTE & this.nBusMask) >>> this.nBlockShift];\n var pte = blockPTE.readLong(offPTE);\n\n if (!(pte & X86.PTE.PRESENT)) {\n if (!fSuppress) X86.helpPageFault.call(this, addr, false, fWrite);\n return this.memEmpty;\n }\n\n if (!(pte & X86.PTE.USER) && this.nCPL == 3) {\n if (!fSuppress) X86.helpPageFault.call(this, addr, true, fWrite);\n return this.memEmpty;\n }\n\n var addrPhys = (pte & X86.PTE.FRAME) + (addr & X86.LADDR.OFFSET);\n /*\n * TODO: Since we're immediately shifting addrPhys by nBlockShift, we could also skip adding the addr's offset.\n */\n var blockPhys = this.aBusBlocks[(addrPhys & this.nBusMask) >>> this.nBlockShift];\n if (fSuppress) return blockPhys;\n\n var iBlock = addr >>> this.nBlockShift;\n var block = this.aMemBlocks[iBlock];\n\n /*\n * So we have the block containing the physical memory corresponding to the given linear address.\n *\n * Now we can create a new PAGED Memory block and record the physical block info using setPhysBlock().\n */\n var blockPage = this.acquirePageBlock(addr & ~X86.LADDR.OFFSET);\n blockPage.setPhysBlock(blockPhys, blockPDE, offPDE, blockPTE, offPTE);\n blockPage.copyBreakpoints(this.dbg, block);\n\n this.aMemBlocks[iBlock] = blockPage;\n this.aBlocksPaged.push(iBlock);\n\n return blockPage;\n }\n\n /**\n * disablePageBlocks()\n *\n * Whenever the CPU turns off paging, this function restores the CPU's original aMemBlocks.\n *\n * @this {CPUX86}\n */\n disablePageBlocks()\n {\n if (this.aMemBlocks !== this.aBusBlocks) {\n this.aMemBlocks = this.aBusBlocks;\n this.blockUnpaged = null;\n this.aBlocksPaged = null;\n this.memEmpty = null;\n }\n }\n\n /**\n * isPagingEnabled()\n *\n * @this {CPUX86}\n * @return {boolean}\n */\n isPagingEnabled()\n {\n var fPaging = !!(this.regCR0 & X86.CR0.PG);\n\n return fPaging;\n }\n\n /**\n * initProcessor()\n *\n * This isolates 80186/80188/80286/80386 support, so that it can be selectively enabled/tested.\n *\n * Here's a summary of 80186/80188 differences according to \"AP-186: Introduction to the 80186\n * Microprocessor, March 1983\" (pp.55-56). \"The iAPX 86,88 and iAPX 186,188 User's Manual Programmer's\n * Reference\", p.3-38, apparently contains the same information, but I've not seen that document.\n *\n * Undefined [Invalid] Opcodes:\n *\n * When the opcodes 63H, 64H, 65H, 66H, 67H, F1H, FEH/xx111xxxB and FFH/xx111xxxB are executed,\n * the 80186 will execute an illegal [invalid] instruction exception, interrupt 0x06.\n * The 8086 will ignore the opcode.\n *\n * 0FH opcode:\n *\n * When the opcode 0FH is encountered, the 8086 will execute a POP CS, while the 80186 will\n * execute an illegal [invalid] instruction exception, interrupt 0x06.\n *\n * Word Write at Offset FFFFH:\n *\n * When a word write is performed at offset FFFFH in a segment, the 8086 will write one byte\n * at offset FFFFH, and the other at offset 0, while the 80186 will write one byte at offset\n * FFFFH, and the other at offset 10000H (one byte beyond the end of the segment). One byte segment\n * underflow will also occur (on the 80186) if a stack PUSH is executed and the Stack Pointer\n * contains the value 1.\n *\n * Shift/Rotate by Value Greater Then [sic] 31:\n *\n * Before the 80186 performs a shift or rotate by a value (either in the CL register, or by an\n * immediate value) it ANDs the value with 1FH, limiting the number of bits rotated to less than 32.\n * The 8086 does not do this.\n *\n * LOCK prefix:\n *\n * The 8086 activates its LOCK signal immediately after executing the LOCK prefix. The 80186 does\n * not activate the LOCK signal until the processor is ready to begin the data cycles associated\n * with the LOCKed instruction.\n *\n * Interrupted String Move Instructions:\n *\n * If an 8086 is interrupted during the execution of a repeated string move instruction, the return\n * value it will push on the stack will point to the last prefix instruction before the string move\n * instruction. If the instruction had more than one prefix (e.g., a segment override prefix in\n * addition to the repeat prefix), it will not be re-executed upon returning from the interrupt.\n * The 80186 will push the value of the first prefix to the repeated instruction, so long as prefixes\n * are not repeated, allowing the string instruction to properly resume.\n *\n * Conditions causing divide error with an integer divide:\n *\n * The 8086 will cause a divide error whenever the absolute value of the quotient is greater then\n * [sic] 7FFFH (for word operations) or if the absolute value of the quotient is greater than 7FH\n * (for byte operations). The 80186 has expanded the range of negative numbers allowed as a quotient\n * by 1 to include 8000H and 80H. These numbers represent the most negative numbers representable\n * using 2's complement arithmetic (equaling -32768 and -128 in decimal, respectively).\n *\n * ESC Opcode:\n *\n * The 80186 may be programmed to cause an interrupt type 7 whenever an ESCape instruction (used for\n * co-processors like the 8087) is executed. The 8086 has no such provision. Before the 80186 performs\n * this trap, it must be programmed to do so. [The details of this \"programming\" are not included.]\n *\n * Here's a summary of 80286 differences according to \"80286 and 80287 Programmer's Reference Manual\",\n * Appendix C, p.C-1 (p.329):\n *\n * 1. Add Six Interrupt Vectors\n *\n * The 80286 adds six interrupts which arise only if the 8086 program has a hidden bug. These interrupts\n * occur only for instructions which were undefined on the 8086/8088 or if a segment wraparound is attempted.\n * It is recommended that you add an interrupt handler to the 8086 software that is to be run on the 80286,\n * which will treat these interrupts as invalid operations.\n *\n * This additional software does not significantly effect [sic] the existing 8086 software because the interrupts\n * do not normally occur and should not already have been used since they are in the interrupt group reserved\n * by Intel. [NOTE: IBM ignored Intel's admonishments.]\n *\n * 2. Do not Rely on 8086/8088 Instruction Clock Counts\n *\n * The 80286 takes fewer clocks for most instructions than the 8086/8088. The areas to look into are delays\n * between I/0 operations, and assumed delays in 8086/8088 operating in parallel with an 8087.\n *\n * 3. Divide Exceptions Point at the DIV Instruction\n *\n * Any interrupt on the 80286 will always leave the saved CS:IP value pointing at the beginning of the\n * instruction that failed (including prefixes). On the 8086, the CS:IP value saved for a divide exception\n * points at the next instruction.\n *\n * 4. Use Interrupt 16 (0x10) for Numeric Exceptions\n *\n * Any 80287 system must use interrupt vector 16 for the numeric error interrupt. If an 8086/8087 or 8088/8087\n * system uses another vector for the 8087 interrupt, both vectors should point at the numeric error interrupt\n * handler.\n *\n * 5. Numeric Exception Handlers Should allow Prefixes\n *\n * The saved CS:IP value in the NPX environment save area will point at any leading prefixes before an ESC\n * instruction. On 8086/8088 systems, this value points only at the ESC instruction.\n *\n * 6. Do Not Attempt Undefined 8086/8088 Operations\n *\n * Instructions like POP CS or MOV CS,op will either cause exception 6 (undefined [invalid] opcode) or perform\n * a protection setup operation like LIDT on the 80286. Undefined bit encodings for bits 5-3 of the second byte\n * of POP MEM or PUSH MEM will cause exception 13 on the 80286.\n *\n * 7. Place a Far JMP Instruction at FFFF0H\n *\n * After reset, CS:IP = F000:FFF0 on the 80286 (versus FFFF:0000 on the 8086/8088). This change was made to allow\n * sufficient code space to enter protected mode without reloading CS. Placing a far JMP instruction at FFFF0H\n * will avoid this difference. Note that the BOOTSTRAP option of LOC86 will automatically generate this jump\n * instruction.\n *\n * 8. Do not Rely on the Value Written by PUSH SP\n *\n * The 80286 will push a different value on the stack for PUSH SP than the 8086/8088. If the value pushed is\n * important [and when would it NOT be?], replace PUSH SP instructions with the following three instructions:\n *\n * PUSH BP\n * MOV BP,SP\n * XCHG BP,[BP]\n *\n * This code functions as the 8086/8088 PUSH SP instruction on the 80286.\n *\n * 9. Do not Shift or Rotate by More than 31 Bits\n *\n * The 80286 masks all shift/rotate counts to the low 5 bits. This MOD 32 operation limits the count to a maximum\n * of 31 bits. With this change, the longest shift/rotate instruction is 39 clocks. Without this change, the longest\n * shift/rotate instruction would be 264 clocks, which delays interrupt response until the instruction completes\n * execution.\n *\n * 10. Do not Duplicate Prefixes\n *\n * The 80286 sets an instruction length limit of 10 bytes. The only way to violate this limit is by duplicating\n * a prefix two or more times before an instruction. Exception 6 occurs if the instruction length limit is violated.\n * The 8086/8088 has no instruction length limit.\n *\n * 11. Do not Rely on Odd 8086/8088 LOCK Characteristics\n *\n * The LOCK prefix and its corresponding output signal should only be used to prevent other bus masters from\n * interrupting a data movement operation. The 80286 will always assert LOCK during an XCHG instruction with memory\n * (even if the LOCK prefix was not used). LOCK should only be used with the XCHG, MOV, MOVS, INS, and OUTS instructions.\n *\n * The 80286 LOCK signal will not go active during an instruction prefetch.\n *\n * 12. Do not Single Step External Interrupt Handlers\n *\n * The priority of the 80286 single step interrupt is different from that of the 8086/8088. This change was made\n * to prevent an external interrupt from being single-stepped if it occurs while single stepping through a program.\n * The 80286 single step interrupt has higher priority than any external interrupt.\n *\n * The 80286 will still single step through an interrupt handler invoked by INT instructions or an instruction\n * exception.\n *\n * 13. Do not Rely on IDIV Exceptions for Quotients of 80H or 8000H\n *\n * The 80286 can generate the largest negative number as a quotient for IDIV instructions. The 8086 will instead\n * cause exception O.\n *\n * 14. Do not Rely on NMI Interrupting NMI Handlers\n *\n * After an NMI is recognized, the NMI input and processor extension limit error interrupt is masked until the\n * first IRET instruction is executed.\n *\n * 15. The NPX error signal does not pass through an interrupt controller (an 8087 INT signal does). Any interrupt\n * controller-oriented instructions for the 8087 may have to be deleted.\n *\n * 16. If any real-mode program relies on address space wrap-around (e.g., FFF0:0400=0000:0300), then external hardware\n * should be used to force the upper 4 addresses to zero during real mode.\n *\n * 17. Do not use I/O ports 00F8-00FFH. These are reserved for controlling 80287 and future processor extensions.\n *\n * @this {CPUX86}\n */\n initProcessor()\n {\n this.PS_SET = X86.PS_SET_8086;\n this.PS_DIRECT = X86.PS_DIRECT_8086;\n this.PS_CLEAR_RM = X86.PS.IOPL.MASK | X86.PS.NT;\n\n this.OPFLAG_NOINTR_8086 = X86.OPFLAG.NOINTR;\n this.nShiftCountMask = 0xff; // on an 8086/8088, all shift counts are used as-is\n\n this.cycleCounts = (this.model >= X86.MODEL_80286? X86.CYCLES_80286 : X86.CYCLES_8088);\n\n this.aOps = X86.aOps;\n this.aOpGrp4b = X86.aOpGrp4b;\n this.aOpGrp4w = X86.aOpGrp4w;\n this.aOpGrp6 = X86.aOpGrp6Real; // setProtMode() will ensure that aOpGrp6 is switched\n\n if (this.model >= X86.MODEL_80186) {\n /*\n * I don't go out of my way to make 80186/80188 cycle times accurate, since I'm not aware of any\n * IBM PC models that used those processors; beyond the 8086, my next priorities are the 80286 and\n * 80386, but I might revisit the 80186 someday.\n *\n * Instruction handlers that contain \"hard-coded\" 80286 cycle times include: opINSb, opINSw, opOUTSb,\n * opOUTSw, opENTER, and opLEAVE.\n */\n this.aOps = X86.aOps.slice(); // make copies of opcode tables before modifying\n this.aOpGrp4b = X86.aOpGrp4b.slice();\n this.aOpGrp4w = X86.aOpGrp4w.slice();\n this.nShiftCountMask = 0x1f; // on newer processors, all shift counts are MOD 32\n this.aOps[0x0F] = X86.opInvalid;\n this.aOps[X86.OPCODE.PUSHA] = X86.opPUSHA; // 0x60\n this.aOps[X86.OPCODE.POPA] = X86.opPOPA; // 0x61\n this.aOps[X86.OPCODE.BOUND] = X86.opBOUND; // 0x62\n this.aOps[X86.OPCODE.ARPL] = X86.opInvalid; // 0x63\n this.aOps[X86.OPCODE.FS] = X86.opInvalid; // 0x64\n this.aOps[X86.OPCODE.GS] = X86.opInvalid; // 0x65\n this.aOps[X86.OPCODE.OS] = X86.opInvalid; // 0x66\n this.aOps[X86.OPCODE.AS] = X86.opInvalid; // 0x67\n this.aOps[X86.OPCODE.PUSHN] = X86.opPUSHn; // 0x68\n this.aOps[X86.OPCODE.IMULN] = X86.opIMULn; // 0x69\n this.aOps[X86.OPCODE.PUSH8] = X86.opPUSH8; // 0x6A\n this.aOps[X86.OPCODE.IMUL8] = X86.opIMUL8; // 0x6B\n this.aOps[X86.OPCODE.INSB] = X86.opINSb; // 0x6C\n this.aOps[X86.OPCODE.INSW] = X86.opINSw; // 0x6D\n this.aOps[X86.OPCODE.OUTSB] = X86.opOUTSb; // 0x6E\n this.aOps[X86.OPCODE.OUTSW] = X86.opOUTSw; // 0x6F\n this.aOps[0xC0] = X86.opGRP2bn; // 0xC0\n this.aOps[0xC1] = X86.opGRP2wn; // 0xC1\n this.aOps[X86.OPCODE.ENTER] = X86.opENTER; // 0xC8\n this.aOps[X86.OPCODE.LEAVE] = X86.opLEAVE; // 0xC9\n this.aOps[0xF1] = X86.opINT1; // 0xF1\n this.aOpGrp4b[0x07] = X86.fnGRPInvalid;\n this.aOpGrp4w[0x07] = X86.fnGRPInvalid;\n\n if (this.model >= X86.MODEL_80286) {\n\n this.PS_SET = X86.PS.BIT1; // on the 80286, only BIT1 of Processor Status (flags) is always set\n this.PS_DIRECT |= X86.PS.IOPL.MASK | X86.PS.NT;\n\n this.OPFLAG_NOINTR_8086 = 0; // for instructions that do *not* set NOINTR on an 80286 (eg, non-SS segment loads)\n\n this.aOps[0x0F] = X86.op0F;\n this.aOps0F = X86.aOps0F.slice();\n for (var i = 0; i < this.aOps0F.length; i++) {\n if (!this.aOps0F[i]) this.aOps0F[i] = X86.opUndefined;\n }\n this.aOps[X86.OPCODE.PUSHSP] = X86.opPUSHSP; // 0x54\n this.aOps[X86.OPCODE.ARPL] = X86.opARPL; // 0x63\n\n if (I386 && this.model >= X86.MODEL_80386) {\n var bOpcode;\n this.PS_CLEAR_RM = 0; // NOTE: This allows the 80386 to modify X86.PS.NT in real-mode (which is presumably OK)\n this.PS_DIRECT |= X86.PS.RF | X86.PS.VM;\n this.aOps[X86.OPCODE.FS] = X86.opFS; // 0x64\n this.aOps[X86.OPCODE.GS] = X86.opGS; // 0x65\n this.aOps[X86.OPCODE.OS] = X86.opOS; // 0x66\n this.aOps[X86.OPCODE.AS] = X86.opAS; // 0x67\n for (bOpcode in X86.aOps0F386) {\n this.aOps0F[+bOpcode] = X86.aOps0F386[+bOpcode];\n }\n if (this.stepping >= X86.STEPPING_80386_A0 && this.stepping <= X86.STEPPING_80386_B0) {\n this.aOps0F[0xA6] = X86.opXBTS;\n this.aOps0F[0xA7] = X86.opIBTS;\n }\n }\n }\n }\n }\n\n /**\n * reset()\n *\n * @this {CPUX86}\n */\n reset()\n {\n this.resetRegs();\n this.resetCycles();\n this.clearError(); // clear any fatal error/exception that setError() may have flagged\n }\n\n /**\n * getReg(i)\n *\n * @this {CPUX86}\n * @param {number} i (0-7)\n * @return {number}\n */\n getReg(i)\n {\n var reg;\n switch(i) {\n case 0x0:\n reg = this.regEAX;\n break;\n case 0x1:\n reg = this.regECX;\n break;\n case 0x2:\n reg = this.regEDX;\n break;\n case 0x3:\n reg = this.regEBX;\n break;\n case 0x4:\n reg = this.getSP();\n break;\n case 0x5:\n reg = this.regEBP;\n break;\n case 0x6:\n reg = this.regESI;\n break;\n case 0x7:\n reg = this.regEDI;\n break;\n }\n return reg;\n }\n\n /**\n * setReg(i, reg)\n *\n * @this {CPUX86}\n * @param {number} i (0-7)\n * @param {number} reg\n */\n setReg(i, reg)\n {\n switch(i) {\n case 0x0:\n this.regEAX = reg;\n break;\n case 0x1:\n this.regECX = reg;\n break;\n case 0x2:\n this.regEDX = reg;\n break;\n case 0x3:\n this.regEBX = reg;\n break;\n case 0x4:\n this.setSP(reg);\n break;\n case 0x5:\n this.regEBP = reg;\n break;\n case 0x6:\n this.regESI = reg;\n break;\n case 0x7:\n this.regEDI = reg;\n break;\n }\n }\n\n /**\n * resetRegs()\n *\n * According to \"The 8086 Book\", p.7-5, a RESET signal initializes the following registers:\n *\n * PS = 0x0000 (which has the important side-effect of disabling interrupts and traps)\n * IP = 0x0000\n * CS = 0xFFFF\n * DS/ES/SS = 0x0000\n *\n * It is silent as to whether the remaining registers are initialized to any particular values.\n *\n * According to the \"80286 and 80287 Programmer's Reference Manual\", these 80286 registers are reset:\n *\n * PS = 0x0002\n * MSW = 0xFFF0\n * IP = 0xFFF0\n * CS Selector = 0xF000 DS/ES/SS Selector = 0x0000\n * CS Base = 0xFF0000 DS/ES/SS Base = 0x000000 IDT Base = 0x000000\n * CS Limit = 0xFFFF DS/ES/SS Limit = 0xFFFF IDT Limit = 0x03FF\n *\n * And from the \"INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986\", section 10.1:\n *\n * The contents of EAX depend upon the results of the power-up self test. The self-test may be requested\n * externally by assertion of BUSY# at the end of RESET. The EAX register holds zero if the 80386 passed\n * the test. A nonzero value in EAX after self-test indicates that the particular 80386 unit is faulty.\n * If the self-test is not requested, the contents of EAX after RESET is undefined.\n *\n * DX holds a component identifier and revision number after RESET as Figure 10-1 illustrates. DH contains\n * 3, which indicates an 80386 component. DL contains a unique identifier of the revision level.\n *\n * EFLAGS = 0x00000002\n * IP = 0x0000FFF0\n * CS selector = 0xF000 (base of 0xFFFF0000 and limit of 0xFFFF)\n * DS selector = 0x0000\n * ES selector = 0x0000\n * SS selector = 0x0000\n * FS selector = 0x0000\n * GS selector = 0x0000\n * IDTR = base of 0 and limit of 0x3FF\n *\n * All other 80386 registers are undefined after a reset (ie, Intel did not document how or if they are set).\n *\n * We've elected to set DX to 0x0308 on a reset, the highest known 80386 revision, since we have no desire to\n * try to emulate all the bugs in older (eg, B1) steppings -- at least not initially. We leave stepping-accurate\n * emulation for another day. It's also known that the B1 (and possibly B0) reported 0x0303 in DX, and that\n * the D0 stepping reported 0x0305; beyond that, it's not known exactly what revision numbers Intel used for all\n * 80386 revisions.\n *\n * We define some additional \"registers\", such as regLIP, which mirrors the linear address corresponding to\n * CS:IP (the address of the next opcode byte). In fact, regLIP functions as our internal IP register, so any\n * code that needs the real IP must call getIP(). This, in turn, means that whenever CS or IP must be modified,\n * regLIP must be recalculated, so you must use either setCSIP(), which takes both an offset and a segment,\n * or setIP(), whichever is appropriate; in unusual cases where only segCS is changing (eg, undocumented 8086\n * opcodes), use setCS().\n *\n * Similarly, regLSP mirrors the linear address corresponding to SS:SP, and therefore you must rely on getSP()\n * to read the current SP, and setSP() and setSS() to update SP and SS.\n *\n * The other segment registers, such as segDS and segES, have similar getters and setters, but we do not mirror\n * any other segment:offset values in the same way that regLIP mirrors CS:IP, or that regLSP mirrors SS:SP.\n *\n * @this {CPUX86}\n */\n resetRegs()\n {\n this.regEAX = 0;\n this.regEBX = 0;\n this.regECX = 0;\n this.regEDX = 0;\n this.regESP = 0; // this isn't needed in a 16-bit environment, but is required for I386\n this.regEBP = 0;\n this.regESI = 0;\n this.regEDI = 0;\n\n /*\n * The following are internal \"registers\" used to capture intermediate values inside selected helper\n * functions and use them if they've been modified (or are known to change); for example, the MUL and DIV\n * instructions perform calculations that must be propagated to specific registers (eg, AX and/or DX), which\n * the ModRM decoder functions don't know about. We initialize them here mainly for documentation purposes.\n */\n this.fMDSet = false; // regMDHi and/or regMDLo are invalid unless fMDSet is true\n this.regMDLo = this.regMDHi = 0;\n this.r64Div = [0, 0];\n this.r64Rem = [0, 0];\n this.regXX = 0; // for internal use only (eg, assists with ModRM helper functions)\n\n /*\n * This internal \"register\" is set in selected opcode handlers to record the original opcode; ordinarily,\n * we dispatch on the opcode but never save it, because it's rarely needed.\n */\n this.bOpcode = 0;\n\n /*\n * Another internal \"register\" we occasionally need is an interim copy of bModRM, set inside selected opcode\n * handlers so that the helper function can have access to the instruction's bModRM without resorting to a\n * closure (which, in the Chrome V8 engine, for example, may cause constant recompilation).\n */\n this.bModRM = 0;\n\n /*\n * NOTE: Even though the 8086 doesn't have CR0 (aka MSW) and IDTR, we initialize them for ALL CPUs, so\n * that functions like X86.helpINT() can use the same code for both. The 8086/8088 have no direct way\n * of accessing or changing them, so this is an implementation detail those processors are unaware of.\n */\n this.regCR0 = X86.CR0.MSW.ON;\n this.addrIDT = 0;\n this.addrIDTLimit = 0x03FF;\n this.regPS = this.nIOPL = 0;// these should be set before the first setPS() call\n\n /*\n * Define all the result registers that can be used to \"cache\" arithmetic and logical flags.\n *\n * In addition, setPS() will initialize resultType, which keeps track of which flags are cached,\n * and resultSize, which maintains the size of the last result; initially, no flags are cached.\n */\n this.resultDst = this.resultSrc = this.resultArith = this.resultLogic = 0;\n\n /*\n * nFault is set by helpFault() and reset (to -1) by resetRegs() and opIRET(). Its initial purpose was to\n * help helpFault() determine when a nested fault should be converted into either a double-fault (DF_FAULT)\n * or a triple-fault (ie, a processor reset).\n *\n * It has since evolved into another important role: helping segCS.loadIDT() know when an exception\n * is occurring, as opposed to a software interrupt (eg, INT3, INT n or INTO). The former must set nFault\n * to the corresponding fault #, whereas the latter must set it to -1, so that if the IDT contains a gate\n * whose DPL < CPL, a GP fault will be generated instead.\n *\n * The former always call helpFault(), and the latter call helpTrap(), so nFault is updated automatically.\n * However, there are also intermediate cases, like hardware interrupts, which call helpINT() after manually\n * setting nFault to the IDT #. TODO: Review all those \"intermediate\" cases.\n */\n this.nFault = -1;\n\n /*\n * These are used to snapshot regLIP and regLSP, to help make instructions restartable;\n * currently opLIP is updated prior to every instruction, but opLSP is updated only for instructions\n * that modify the stack pointer (eg, RETF) and should otherwise remain set to X86.ADDR_INVALID.\n *\n * More recently, opCS was added to selectively snapshot an instruction's original CS in case an\n * exception occurs accessing the stack after a new CS has been loaded, allowing the exception handler\n * to recover the old CS and make instructions like CALLF restartable; otherwise, opCS should remain -1.\n *\n * Ditto for opSS and the SS register.\n */\n this.opCS = this.opSS = -1;\n this.opLIP = this.opLSP = X86.ADDR_INVALID;\n\n /*\n * Segment registers used to be defined as separate selector and base variables (eg, regCS and regCS0),\n * but now they are defined as SegX86 objects.\n */\n this.segCS = new SegX86(this, SegX86.ID.CODE, \"CS\");\n this.segDS = new SegX86(this, SegX86.ID.DATA, \"DS\");\n this.segES = new SegX86(this, SegX86.ID.DATA, \"ES\");\n this.segSS = new SegX86(this, SegX86.ID.STACK, \"SS\");\n this.setSP(0);\n this.setSS(0);\n\n if (I386 && this.model >= X86.MODEL_80386) {\n /*\n * Here lies everything I currently know about 80386 stepping revision numbers...\n */\n switch(this.stepping) {\n case X86.STEPPING_80386_B0:\n case X86.STEPPING_80386_B1:\n this.regEDX = 0x0303;\n break;\n case X86.STEPPING_80386_C0:\n this.regEDX = 0x0304;\n break;\n case X86.STEPPING_80386_D0:\n this.regEDX = 0x0305;\n break;\n case X86.STEPPING_80386_D1:\n case X86.STEPPING_80386_D2:\n this.regEDX = 0x0308;\n break;\n default:\n break; // in the absence of a specific stepping, we leave DX set to zero\n }\n this.regCR0 = X86.CR0.ET; // formerly MSW\n this.regCR1 = 0; // reserved\n this.regCR2 = 0; // page fault linear address (PFLA)\n this.regCR3 = 0; // page directory base register (PDBR)\n this.regDR = [0,0,0,0,null,null,0,0]; // Debug Registers DR0-DR7 (DR4-DR5 are undefined)\n this.regTR = [null,null,null,null,null,null,0,0]; // Test Registers TR0-TR7 (TR0-TR5 are undefined)\n this.segFS = new SegX86(this, SegX86.ID.DATA, \"FS\");\n this.segGS = new SegX86(this, SegX86.ID.DATA, \"GS\");\n /*\n * Synchronize the fact that paging is initially disabled with our PAGEBLOCKS functions\n */\n this.disablePageBlocks();\n }\n\n this.segNULL = new SegX86(this, SegX86.ID.NULL, \"NULL\");\n\n /*\n * The next few initializations mirror what we must do prior to each instruction (ie, inside the stepCPU() function);\n * note that opPrefixes, along with segData and segStack, are reset only after we've executed a non-prefix instruction.\n */\n this.segData = this.segDS;\n this.segStack = this.segSS;\n this.opFlags = this.opPrefixes = 0;\n this.regEA = this.regEAWrite = X86.ADDR_INVALID;\n\n this.segEA = this.segNULL;\n\n /*\n * intFlags contains some internal states we use to indicate whether a hardware interrupt (INTFLAG.INTR) or\n * Trap software interrupt (INTR.TRAP) has been requested, as well as when we're in a \"HLT\" state (INTFLAG.HALT)\n * that requires us to wait for a hardware interrupt (INTFLAG.INTR) before continuing execution.\n *\n * intFlags must be cleared only by checkINTR(), whereas opFlags must be cleared prior to every CPU operation.\n */\n this.intFlags = X86.INTFLAG.NONE;\n\n if (BACKTRACK) {\n /*\n * Initialize the backtrack indexes for all registers to zero. And while, yes, it IS possible\n * for raw data to flow through segment registers as well, it's not common enough in real-mode\n * (and too difficult in protected-mode) to merit the overhead. Ditto for SP, which can't really\n * be considered a general-purpose register.\n *\n * Every time getByte() is called, btiMem0 is filled with the matching backtrack info; similarly,\n * every time getWord() is called, btiMem0 and btiMem1 are filled with the matching backtrack info\n * for the low and high bytes, respectively.\n */\n this.backTrack = {\n btiAL: 0,\n btiAH: 0,\n btiBL: 0,\n btiBH: 0,\n btiCL: 0,\n btiCH: 0,\n btiDL: 0,\n btiDH: 0,\n btiBPLo: 0,\n btiBPHi: 0,\n btiSILo: 0,\n btiSIHi: 0,\n btiDILo: 0,\n btiDIHi: 0,\n btiMem0: 0,\n btiMem1: 0,\n btiMem2: 0,\n btiMem3: 0,\n btiEALo: 0,\n btiEAHi: 0,\n btiIO: 0\n };\n }\n\n /*\n * Set the initial CS:IP appropriate for the processor; this should be done before the first setPS() call,\n * in part so that CPL will be set properly.\n */\n if (this.model < X86.MODEL_80286) {\n this.setCSIP(0, 0xffff);\n } else {\n /*\n * Assorted 80286-specific registers. The GDTR and IDTR registers are stored as the following pieces:\n *\n * GDTR: addrGDT (24 bits) and addrGDTLimit (24 bits)\n * IDTR: addrIDT (24 bits) and addrIDTLimit (24 bits)\n *\n * while the LDTR and TR are stored as special segment registers: segLDT and segTSS.\n *\n * So, yes, our GDTR and IDTR \"registers\" differ from other segment registers in that we do NOT record\n * the 16-bit limit specified by the LGDT or LIDT instructions; instead, we immediately calculate the limiting\n * address, and record that instead.\n *\n * In addition to different CS:IP reset values, the CS base address must be set to the top of the 16Mb\n * address space rather than the top of the first 1Mb (which is why the MODEL_5170 ROM must be addressable\n * at both 0x0F0000 and 0xFF0000; see the ROM component's \"alias\" parameter).\n *\n * TODO: Verify what the 80286 actually sets addrGDT and addrGDTLimit to on reset (or if it leaves them alone).\n */\n this.addrGDT = 0; this.addrGDTLimit = 0xffff; // GDTR\n this.segLDT = new SegX86(this, SegX86.ID.LDT, \"LDT\", true); // LDTR\n this.segTSS = new SegX86(this, SegX86.ID.TSS, \"TSS\", true); // TR\n this.segVER = new SegX86(this, SegX86.ID.VER, \"VER\", true); // a scratch segment register for VERR and VERW instructions\n this.setCSIP(0xfff0, 0xf000); // on an 80286 or 80386, the default CS:IP is 0xF000:0xFFF0 instead of 0xFFFF:0x0000\n this.setCSBase(0xffff0000|0); // on an 80286 or 80386, all CS base address bits above bit 15 must be set\n }\n\n /*\n * This resets the Processor Status flags (regPS), along with all the internal \"result registers\";\n * we've taken care to ensure that both CPL and IOPL are initialized before this first setPS() call.\n */\n this.setPS(0);\n\n /*\n * Now that all the segment registers have been created, it's safe to set the current addressing mode.\n */\n this.setProtMode();\n }\n\n /**\n * updateAddrSize()\n *\n * Select the appropriate ModRM dispatch tables, based on the current ADDRESS size (addrSize), which\n * is based foremost on segCS.sizeAddr, but can also be overridden by an ADDRESS size instruction prefix.\n *\n * There used to be six primary ModRM dispatch table pointers:\n *\n * aOpModRegByte\n * aOpModMemByte\n * aOpModGrpByte\n * aOpModRegWord\n * aOpModMemWord\n * aOpModGrpWord\n *\n * However, when support for the 80386 was added, the number of dispatch tables doubled, and since each entry\n * in the table was a discrete function, decoding was fast, but it also required a LOT of code.\n *\n * So we have now replaced the above table pointers with function pointers:\n *\n * decodeModRegByte (set to one of: modRegByte16, modRegByte32)\n * decodeModMemByte (set to one of: modMemByte16, modMemByte32)\n * decodeModGrpByte (set to one of: modGrpByte16, modGrpByte32)\n * decodeModRegWord (set to one of: modRegShort16, modRegLong16, modRegShort32, modRegLong32)\n * decodeModMemWord (set to one of: modMemShort16, modMemLong16, modMemShort32, modMemLong32)\n * decodeModGrpWord (set to one of: modGrpShort16, modGrpLong16, modGrpShort32, modGrpLong32)\n *\n * So opcode handlers that used to do this:\n *\n * this.aOpModMemByte[b].call(this, X86.fnADDb);\n *\n * now do this:\n *\n * this.decodeModMemByte.call(this, X86.fnADDb);\n *\n * Decoding of ModRM bytes is now slightly slower, but the previous code is still in the repository\n * (look for x86modb.js and x86modw.js for the pre-80386 dispatch tables, and x86modb16.js, x86modb32.js,\n * x86modw16.js, x86modw32.js, and x86modsib.js for the post-80386 dispatch tables).\n *\n * @this {CPUX86}\n */\n updateAddrSize()\n {\n if (!I386) {\n this.getAddr = (PREFETCH? this.getShortPrefetch : this.getShort);\n this.decodeModRegByte = X86.modRegByte16;\n this.decodeModMemByte = X86.modMemByte16;\n this.decodeModGrpByte = X86.modGrpByte16;\n this.decodeModRegWord = X86.modRegShort16;\n this.decodeModMemWord = X86.modMemShort16;\n this.decodeModGrpWord = X86.modGrpShort16;\n } else {\n if (this.sizeAddr == 2) {\n this.getAddr = (PREFETCH? this.getShortPrefetch : this.getShort);\n this.decodeModRegByte = X86.modRegByte16;\n this.decodeModMemByte = X86.modMemByte16;\n this.decodeModGrpByte = X86.modGrpByte16;\n if (this.sizeData == 2) {\n this.decodeModRegWord = X86.modRegShort16;\n this.decodeModMemWord = X86.modMemShort16;\n this.decodeModGrpWord = X86.modGrpShort16;\n } else {\n this.decodeModRegWord = X86.modRegLong16;\n this.decodeModMemWord = X86.modMemLong16;\n this.decodeModGrpWord = X86.modGrpLong16;\n }\n } else {\n this.getAddr = (PREFETCH? this.getLongPrefetch : this.getLong);\n this.decodeModRegByte = X86.modRegByte32;\n this.decodeModMemByte = X86.modMemByte32;\n this.decodeModGrpByte = X86.modGrpByte32;\n if (this.sizeData == 2) {\n this.decodeModRegWord = X86.modRegShort32;\n this.decodeModMemWord = X86.modMemShort32;\n this.decodeModGrpWord = X86.modGrpShort32;\n } else {\n this.decodeModRegWord = X86.modRegLong32;\n this.decodeModMemWord = X86.modMemLong32;\n this.decodeModGrpWord = X86.modGrpLong32;\n }\n }\n }\n }\n\n /**\n * setDataSize(size)\n *\n * This is used by opcodes that require a particular OPERAND size, which we enforce by internally\n * simulating an OPERAND size override, if needed.\n *\n * @this {CPUX86}\n * @param {number} size (2 for 2-byte/16-bit operands, or 4 for 4-byte/32-bit operands)\n */\n setDataSize(size)\n {\n if (this.sizeData != size) {\n this.opPrefixes |= X86.OPFLAG.DATASIZE;\n this.sizeData = size;\n this.maskData = (size == 2? 0xffff : (0xffffffff|0));\n this.updateDataSize();\n }\n }\n\n /**\n * updateDataSize()\n *\n * @this {CPUX86}\n */\n updateDataSize()\n {\n if (this.sizeData == 2) {\n this.typeData = X86.RESULT.WORD;\n this.getWord = this.getShort;\n this.setWord = this.setShort;\n if (this.sizeAddr == 2) {\n this.decodeModRegWord = X86.modRegShort16;\n this.decodeModMemWord = X86.modMemShort16;\n this.decodeModGrpWord = X86.modGrpShort16;\n } else {\n this.decodeModRegWord = X86.modRegShort32;\n this.decodeModMemWord = X86.modMemShort32;\n this.decodeModGrpWord = X86.modGrpShort32;\n }\n } else {\n this.typeData = X86.RESULT.DWORD;\n this.getWord = this.getLong;\n this.setWord = this.setLong;\n if (this.sizeAddr == 2) {\n this.decodeModRegWord = X86.modRegLong16;\n this.decodeModMemWord = X86.modMemLong16;\n this.decodeModGrpWord = X86.modGrpLong16;\n } else {\n this.decodeModRegWord = X86.modRegLong32;\n this.decodeModMemWord = X86.modMemLong32;\n this.decodeModGrpWord = X86.modGrpLong32;\n }\n }\n }\n\n /**\n * resetSizes()\n *\n * @this {CPUX86}\n */\n resetSizes()\n {\n /*\n * The following contain the (default) ADDRESS size (2 for 16 bits, 4 for 32 bits), and the corresponding\n * masks for isolating the (src) bits of an address and clearing the (dst) bits of an address. Like the\n * OPERAND size properties, these are reset to their segCS counterparts at the start of every new instruction.\n */\n this.sizeAddr = this.segCS.sizeAddr;\n this.maskAddr = this.segCS.maskAddr;\n\n /*\n * It's also worth noting that instructions that implicitly use the stack also rely on STACK size,\n * which is based on the BIG bit of the last descriptor loaded into SS; use the following segSS properties:\n *\n * segSS.sizeAddr (2 or 4)\n * segSS.maskAddr (0xffff or 0xffffffff)\n *\n * As there is no STACK size instruction prefix override, there's no need to propagate these segSS properties\n * to separate CPUX86 properties, as we do for the OPERAND size and ADDRESS size properties.\n */\n\n this.updateAddrSize();\n\n /*\n * The following contain the (default) OPERAND size (2 for 16 bits, 4 for 32 bits), and the corresponding masks\n * for isolating the (src) bits of an OPERAND and clearing the (dst) bits of an OPERAND. These are reset to\n * their segCS counterparts at the start of every new instruction, but are also set here for documentation purposes.\n */\n this.sizeData = this.segCS.sizeData;\n this.maskData = this.segCS.maskData;\n\n this.updateDataSize();\n\n this.opPrefixes &= ~(X86.OPFLAG.ADDRSIZE | X86.OPFLAG.DATASIZE);\n }\n\n /**\n * getChecksum()\n *\n * @this {CPUX86}\n * @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code)\n */\n getChecksum()\n {\n var sum = (this.regEAX + this.regEBX + this.regECX + this.regEDX + this.getSP() + this.regEBP + this.regESI + this.regEDI)|0;\n sum = (sum + this.getIP() + this.getCS() + this.getDS() + this.getSS() + this.getES() + this.getPS())|0;\n return sum;\n }\n\n /**\n * addIntNotify(nInt, fn)\n *\n * Add a software interrupt notification handler to the CPU's list of such handlers.\n *\n * TODO: Consider adding removeIntNotify(). Example use case: if the Debugger's intWindowsDebugger() function\n * detects that an INT 0x41 client is loaded, it would be quite happy to uninstall itself.\n *\n * @this {CPUX86}\n * @param {number} nInt\n * @param {function(number)} fn is called with the LIP value following the software interrupt\n */\n addIntNotify(nInt, fn)\n {\n if (this.aIntNotify[nInt] === undefined) {\n this.aIntNotify[nInt] = [];\n }\n this.aIntNotify[nInt].push(fn);\n }\n\n /**\n * checkIntNotify(nInt)\n *\n * NOTE: This is called ONLY for \"INT N\" instructions -- not \"INTO\" or breakpoint or single-step interrupts\n * or divide exception interrupts, or hardware interrupts, or any simulation of an interrupt (eg, \"PUSHF/CALLF\").\n *\n * @this {CPUX86}\n * @param {number} nInt\n * @return {boolean} true if software interrupt may proceed, false if software interrupt should be skipped\n */\n checkIntNotify(nInt)\n {\n var aNotify = this.aIntNotify[nInt];\n if (aNotify !== undefined) {\n for (var i = 0; i < aNotify.length; i++) {\n if (!aNotify[i](this.regLIP)) {\n return false;\n }\n }\n }\n /*\n * The enabling of INT messages is one of the criteria that's also included in the Debugger's checksEnabled()\n * function, and therefore included in fDebugCheck, so for maximum speed, we check fDebugCheck first.\n *\n * NOTE: We've added MAXDEBUG to the test below, because onIntReturn() generates a lot of noise, via\n * dbg.messageIntReturn(), and because there's no way to be sure we'll catch the return (or for some interrupts,\n * *whether* they will return), so it's safer to disable this feature unless you really want it.\n *\n * For most purposes, just having dbg.messageInt(), and the Debugger's ability to selectively turn categories\n * of messages on and off, is good enough.\n */\n if (DEBUGGER && this.flags.debugCheck) {\n if (this.messageEnabled(Messages.INT) && this.dbg.messageInt(nInt, this.regLIP) && MAXDEBUG) {\n this.addIntReturn(this.regLIP, function(cpu, nCycles) {\n return function onIntReturn(nLevel) {\n cpu.dbg.messageIntReturn(nInt, nLevel, cpu.getCycles() - nCycles);\n };\n }(this, this.getCycles()));\n }\n }\n return true;\n }\n\n /**\n * addIntReturn(addr, fn)\n *\n * Add a return notification handler to the CPU's list of such handlers.\n *\n * When fn(n) is called, it's passed a \"software interrupt level\", which will normally be 0,\n * unless it's a return from a nested software interrupt (eg, return from INT 0x10 Video BIOS\n * call issued inside another INT 0x10 Video BIOS call).\n *\n * Note that the nesting could be due to a completely different software interrupt that\n * another interrupt notification function is intercepting, so use it as an advisory value only.\n *\n * @this {CPUX86}\n * @param {number} addr is a linear address\n * @param {function(number)} fn is an interrupt-return notification function\n */\n addIntReturn(addr, fn)\n {\n if (fn !== undefined) {\n if (this.aIntReturn[addr] == null) {\n this.cIntReturn++;\n }\n this.aIntReturn[addr] = fn;\n }\n }\n\n /**\n * checkIntReturn(addr)\n *\n * We check for possible \"INT n\" software interrupt returns in the cases of \"IRET\" (helpIRET), \"RETF 2\"\n * (helpRETF) and \"JMPF [DWORD]\" (fnJMPFdw).\n *\n * \"JMPF [DWORD]\" is an unfortunate choice that newer versions of DOS (as of at least 3.20, and probably\n * earlier) employed in their INT 0x13 hooks; I would have preferred not making this call for that opcode.\n *\n * It is expected (though not required) that callers will check cIntReturn and avoid calling this function\n * if the count is zero, for maximum performance.\n *\n * @this {CPUX86}\n * @param {number} addr is a linear address\n */\n checkIntReturn(addr)\n {\n var fn = this.aIntReturn[addr];\n if (fn != null) {\n fn(--this.cIntReturn);\n delete this.aIntReturn[addr];\n }\n }\n\n /**\n * checkDebugRegisters(fEnable)\n *\n * opMOVdr() simplifies its life by doing work ONLY if the contents of a Debug register is actually changing.\n *\n * Whenever a single register is about to change, it calls this function with fEnable set to false to REMOVE any\n * active checks, then updates the Debug register, then calls us again with fEnable set to true to (re)ADD active\n * checks.\n *\n * @this {CPUX86}\n * @param {boolean} fEnable\n */\n checkDebugRegisters(fEnable)\n {\n /*\n * We use a constant mask for the enable bits (X86.DR7.L0 | X86.DR7.G0) and shift our copy of regDR7\n * right 2 bits after each Debug register check.\n *\n * Similarly, we make a copy of regDR7 in bitsDR7 and shift the latter right 4 bits at a time, so that\n * the RW and LEN bits for the next Debug register are always in positions 1-0 and 3-2, respectively.\n */\n var regDR7 = this.regDR[7];\n var bitsDR7 = regDR7 >> 16;\n\n for (var i = 0; i < 4; i++) {\n if (regDR7 & (X86.DR7.L0 | X86.DR7.G0)) {\n /*\n * We look only to the low bit of the RW field to determine if we should be watching for a write.\n * FYI, if the low bit is clear but the high bit is set, that's \"undefined\"; we treat it as a read.\n */\n var fWrite = !!(bitsDR7 & 0x1);\n /*\n * The address in regDR[i] should already be masked with ~0x1 for 2-byte accesses (LEN == 0x1) or\n * with ~0x3 for 4-byte accesses (LEN == 0x3), but if the client forgets, the hardware supposedly\n * enforces it, so that's what we do here, too.\n *\n * FYI, if LEN is set to the \"undefined\" value of (0x2), we still apply a mask to the address, albeit\n * a nonsensical mask of ~0x2 or 0xfffffffd. That's how we define that particular \"undefined\" LEN.\n */\n var addr = this.regDR[i];\n var len = ((bitsDR7 >> 2) & 0x3);\n addr &= ~len; // NOTE: if LEN == 0x0, we don't need to mask, but ~0x0 is equivalent to no mask\n if (fEnable) {\n this.addMemCheck(addr, fWrite);\n } else {\n this.removeMemCheck(addr, fWrite);\n }\n }\n regDR7 >>= 2; bitsDR7 >>= 4;\n }\n }\n\n /**\n * checkMemoryException(addr, nb, fWrite)\n *\n * This \"check\" function is called by a Memory block to inform us that a memory read or write is occurring,\n * giving us the opportunity look for a matching \"read\" or \"write\" breakpoint enabled in one of the DRn registers.\n *\n * TODO: This currently does not discriminate between data reads and execution reads. When we switch to a true\n * \"prefetch\" model, that would also be a good time to include a signal to this function indicating which \"read\"\n * accesses are are actually \"exec\" accesses.\n *\n * @this {CPUX86}\n * @param {number} addr\n * @param {number} nb (# of bytes)\n * @param {boolean|null} [fWrite] (false if read, true if write, null if exec)\n */\n checkMemoryException(addr, nb, fWrite)\n {\n /*\n * NOTE: We're preventing redundant X86.EXCEPTION.DB_EXC exceptions for a single instruction by checking\n * X86.OPFLAG.DBEXC. I decided not to rely on the generic X86.OPFLAG.FAULT, because if an instruction\n * first triggers a DIFFERENT exception which then triggers a DEBUG exception (eg, because a Debug register\n * was set on the IDT entry of the first exception), then presumably we'd like to see that DEBUG exception,\n * as opposed to, say, a double fault. TODO: Determine whether that SHOULD generate a double-fault.\n */\n if (!(this.opFlags & X86.OPFLAG.DBEXC) && (this.regDR[7] & X86.DR7.ENABLE)) {\n nb--;\n /*\n * We use a constant mask for the enable bits (X86.DR7.L0 | X86.DR7.G0) and shift our copy of regDR7\n * right 2 bits after each Debug register check.\n *\n * Similarly, we make a copy of regDR7 in bitsDR7 and shift the latter right 4 bits at a time, so that\n * the RW and LEN bits for the next Debug register are always in positions 1-0 and 3-2, respectively.\n */\n var regDR7 = this.regDR[7];\n var bitsDR7 = regDR7 >> 16;\n\n var bitsRWMask = X86.DR7.RW0 >> 16;\n var bitsRWRequired = (fWrite? 0x1 : (fWrite == false? 0x3 : 0x0));\n\n for (var i = 0; i < 4; i++) {\n if ((regDR7 & (X86.DR7.L0 | X86.DR7.G0)) && (bitsDR7 & bitsRWMask) == bitsRWRequired) {\n /*\n * NOTE: We reduced nb from 1-4 to 0-3 above, so we don't need to add 1 to len either.\n */\n var len = (bitsDR7 >> 2);\n /*\n * Time to determine if addr through addr + nb overlaps regDR[i] through regDR[i] + len.\n */\n if (addr + nb >= this.regDR[i] && addr <= this.regDR[i] + len) {\n this.regDR[6] |= (1 << i);\n /*\n * Data access breakpoints are not faults; they must generate a trap at the end of the\n * instruction, so we use the X86.INTFLAG.TRAP flag to generate the X86.EXCEPTION.DB_EXC trap.\n *\n * X86.helpFault.call(this, X86.EXCEPTION.DB_EXC);\n */\n this.intFlags |= X86.INTFLAG.TRAP;\n return;\n }\n }\n regDR7 >>= 2; bitsDR7 >>= 4;\n }\n }\n }\n\n /**\n * isProtMode()\n *\n * @this {CPUX86}\n * @return {boolean} true if protected-mode, false if not\n */\n isProtMode()\n {\n return !!(this.regCR0 & X86.CR0.MSW.PE);\n }\n\n /**\n * isV86Mode()\n *\n * @this {CPUX86}\n * @return {boolean} true if V86-mode, false if not\n */\n isV86Mode()\n {\n return !!(this.regPS & X86.PS.VM);\n }\n\n /**\n * setProtMode(fProt, fV86)\n *\n * Update any opcode handlers that operate significantly differently in real-mode vs. protected-mode, and\n * notify all the segment registers about the mode change as well -- but only those that are \"bi-modal\"; internal\n * segment registers like segLDT and segTSS do not need to be notified, because they cannot be accessed in real-mode\n * (ie, LLDT, LTR, SLDT, STR are invalid instructions in real-mode, and are among the opcode handlers that we\n * update here).\n *\n * NOTE: Ideally, this function would do its work ONLY on mode *transitions*, but we assume calls to setProtMode()\n * are sufficiently infrequent that it doesn't really matter.\n *\n * @this {CPUX86}\n * @param {boolean} [fProt] (use the current MSW PE bit if not specified)\n * @param {boolean} [fV86] true if the X86.PS.VM (V86-mode) flag is set (or is about to be)\n */\n setProtMode(fProt, fV86)\n {\n if (fProt === undefined) {\n fProt = this.isProtMode();\n }\n if (fV86 === undefined) {\n fV86 = this.isV86Mode();\n }\n if (DEBUG && (fProt != this.isProtMode() || fV86 != this.isV86Mode()) && this.messageEnabled()) {\n this.printMessage(\"CPU switching to \" + (fProt? (fV86? \"v86\" : \"protected\") : \"real\") + \"-mode\", this.bitsMessage, true);\n }\n this.aOpGrp6 = (fProt && !fV86? X86.aOpGrp6Prot : X86.aOpGrp6Real);\n this.segCS.updateMode(false, fProt, fV86);\n this.segDS.updateMode(false, fProt, fV86);\n this.segSS.updateMode(false, fProt, fV86);\n this.segES.updateMode(false, fProt, fV86);\n if (I386 && this.model >= X86.MODEL_80386) {\n this.segFS.updateMode(false, fProt, fV86);\n this.segGS.updateMode(false, fProt, fV86);\n }\n /*\n * This function used to be called only when I386 is true, but it's probably best if we ALWAYS call it, even\n * for 16-bit-only CPUs like the 8086 and 80286; this allows us to write opcode logic by either checking I386\n * and using appropriate hard-coded sizes, or NOT checking I386 and simply using the \"soft-coded\" sizes in\n * sizeData and sizeAddr.\n */\n this.resetSizes();\n }\n\n /**\n * saveProtMode()\n *\n * Save CPU state related to protected-mode, for save()\n *\n * @this {CPUX86}\n * @return {Array}\n */\n saveProtMode()\n {\n if (this.addrGDT != null) {\n var a = [\n this.regCR0,\n this.addrGDT,\n this.addrGDTLimit,\n this.addrIDT,\n this.addrIDTLimit,\n this.segLDT.save(),\n this.segTSS.save(),\n this.nIOPL\n ];\n if (I386 && this.model >= X86.MODEL_80386) {\n a.push(this.regCR1);\n a.push(this.regCR2);\n a.push(this.regCR3);\n a.push(this.regDR);\n a.push(this.regTR);\n }\n return a;\n }\n return null;\n }\n\n /**\n * restoreProtMode()\n *\n * Restore CPU state related to protected-mode, for restore()\n *\n * @this {CPUX86}\n * @param {Array} a\n */\n restoreProtMode(a)\n {\n if (a && a.length) {\n this.regCR0 = a[0];\n this.addrGDT = a[1];\n this.addrGDTLimit = a[2];\n this.addrIDT = a[3];\n this.addrIDTLimit = a[4];\n this.segLDT.restore(a[5]);\n this.segTSS.restore(a[6]);\n this.nIOPL = a[7];\n if (I386 && this.model >= X86.MODEL_80386) {\n this.regCR1 = a[8];\n this.regCR2 = a[9];\n this.regCR3 = a[10];\n this.regDR = a[11];\n this.regTR = a[12];\n }\n this.setProtMode();\n }\n }\n\n /**\n * save(fRunning)\n *\n * This implements save support for the X86 component.\n *\n * NOTE: When the Computer starts issuing powerDown() calls, it always calls the CPU first, and the CPU's\n * powerDown() handler has the added responsibility of:\n *\n * 1) recording whether or not the CPU is currently running\n * 2) stopping the CPU if the powerDown is part of a shutDown\n * 3) passing the original running state to us\n *\n * UPDATES: The current speed multiplier from getSpeed() is now saved in group #3, so that your speed is preserved.\n *\n * @this {CPUX86}\n * @param {boolean} [fRunning]\n * @return {Object|null}\n */\n save(fRunning)\n {\n var state = new State(this);\n state.set(0, [this.regEAX, this.regEBX, this.regECX, this.regEDX, this.getSP(), this.regEBP, this.regESI, this.regEDI]);\n var a = [this.getIP(), this.segCS.save(), this.segDS.save(), this.segSS.save(), this.segES.save(), this.saveProtMode(), this.getPS()];\n if (I386 && this.model >= X86.MODEL_80386) {\n a.push(this.segFS.save());\n a.push(this.segGS.save());\n }\n state.set(1, a);\n state.set(2, [this.segData.sName, this.segStack.sName, this.opFlags, this.opPrefixes, this.intFlags, this.regEA, this.regEAWrite]);\n state.set(3, [0, this.nTotalCycles, this.getSpeed(), fRunning, this.saveTimers()]);\n state.set(4, this.bus.saveMemory(this.isPagingEnabled()));\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the X86 component.\n *\n * @this {CPUX86}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n var a = data[0];\n this.regEAX = a[0];\n this.regEBX = a[1];\n this.regECX = a[2];\n this.regEDX = a[3];\n var regESP = a[4];\n this.regEBP = a[5];\n this.regESI = a[6];\n this.regEDI = a[7];\n\n a = data[1];\n this.segCS.restore(a[1]);\n this.segDS.restore(a[2]);\n this.segSS.restore(a[3]);\n this.segES.restore(a[4]);\n this.restoreProtMode(a[5]);\n this.setPS(a[6]);\n\n /*\n * The introduction of protected-mode requires us to restore memory contents sooner than we used to\n * (ie, before we load any segment registers).\n */\n var fRestored = false;\n\n if (this.bus.restoreMemory(data[4])) {\n /*\n * It's important to call setCSIP(), both to ensure that the CPU's linear IP register (regLIP) is updated\n * properly AND to ensure the CPU's default ADDRESS and OPERAND sizes are set properly.\n */\n this.setCSIP(a[0], this.segCS.sel);\n\n /*\n * It's also important to call setSP(), so that the linear SP register (regLSP) will be updated properly;\n * we also need to call setSS(), to ensure that the lower and upper stack limits are properly initialized.\n */\n this.setSP(regESP);\n this.setSS(this.segSS.sel);\n\n if (I386 && this.model >= X86.MODEL_80386) {\n this.segFS.restore(a[7]);\n this.segGS.restore(a[8]);\n }\n fRestored = true;\n }\n\n a = data[2];\n this.segData = a[0] != null && this.getSeg(a[0]) || this.segDS;\n this.segStack = a[1] != null && this.getSeg(a[1]) || this.segSS;\n this.opFlags = a[2];\n this.opPrefixes = a[3];\n this.intFlags = a[4];\n this.regEA = a[5]; // save/restore of last EA calculation(s) isn't strictly necessary,\n this.regEAWrite = a[6]; // but they may be of some interest to, say, the Debugger\n\n a = data[3];\n this.nTotalCycles = a[1]; // a[0] was previously nBurstDivisor (no longer used)\n this.setSpeed(a[2]); // old states didn't contain a value from getSpeed(), but setSpeed() checks\n if (a[3] != null) { // less old states didn't preserve the original running state, so we must check it\n this.flags.autoStart = a[3];\n }\n if (a[4] != null) {\n this.restoreTimers(a[4]);\n }\n return fRestored;\n }\n\n /**\n * getSeg(sName)\n *\n * @param {string} sName\n * @return {SegX86|Array}\n */\n getSeg(sName)\n {\n switch(sName) {\n case \"CS\":\n return this.segCS;\n case \"DS\":\n return this.segDS;\n case \"SS\":\n return this.segSS;\n case \"ES\":\n return this.segES;\n case \"NULL\":\n return this.segNULL;\n default:\n /*\n * HACK: We return a fake segment register object in which only the base linear address is valid,\n * because that's all the caller provided (ie, we must be restoring from an older state).\n */\n\n return [0, sName, 0, 0, \"\"];\n }\n }\n\n /**\n * getCS()\n *\n * @this {CPUX86}\n * @return {number}\n */\n getCS()\n {\n return this.segCS.sel;\n }\n\n /**\n * setCS(sel)\n *\n * NOTE: This is used ONLY by those few undocumented 8086/8088/80186/80188 instructions that \"MOV\" or \"POP\" a value\n * into CS, which we assume have the same behavior as any other instruction that moves or pops a segment register\n * (ie, suppresses h/w interrupts for one instruction). Instructions that \"JMP\" or \"CALL\" or \"INT\" or \"IRET\" a new\n * value into CS are always accompanied by a new IP value, so they use setCSIP() instead, which does NOT suppress\n * h/w interrupts.\n *\n * @this {CPUX86}\n * @param {number} sel\n * @return {boolean}\n */\n setCS(sel)\n {\n if (this.setCSIP(this.getIP(), sel) != null) {\n if (!BUGS_8086) this.opFlags |= this.OPFLAG_NOINTR_8086;\n return true;\n }\n return false;\n }\n\n /**\n * getDS()\n *\n * @this {CPUX86}\n * @return {number}\n */\n getDS()\n {\n return this.segDS.sel;\n }\n\n /**\n * setDS(sel)\n *\n * @this {CPUX86}\n * @param {number} sel\n */\n setDS(sel)\n {\n if (this.segDS.load(sel) !== X86.ADDR_INVALID) {\n if (!BUGS_8086) this.opFlags |= this.OPFLAG_NOINTR_8086;\n return true;\n }\n return false;\n }\n\n /**\n * getSS()\n *\n * @this {CPUX86}\n * @return {number}\n */\n getSS()\n {\n return this.segSS.sel;\n }\n\n /**\n * setSS(sel)\n *\n * @this {CPUX86}\n * @param {number} sel\n * @param {boolean} [fInterruptable]\n * @return {boolean}\n */\n setSS(sel, fInterruptable)\n {\n var regESP = this.getSP();\n var regLSP = this.segSS.load(sel);\n if (regLSP !== X86.ADDR_INVALID) {\n /*\n * The safest way to update regLSP after a potential change to segSS.base is to call setSP() with the\n * original stack pointer retrieved above via getSP(). When I tried to be clever and do this instead:\n *\n * this.regLSP = (regLSP + regESP)|0;\n *\n * 16-bit stacks began inadvertently using ESP instead of SP. The moral: don't be needlessly clever.\n */\n this.setSP(regESP);\n \n /*\n * The desire to use a linear stack pointer (regLSP) for internal stack operations has some pitfalls;\n * one involves these upper and lower limit calculations. Example: Xenix 386 creates a (non-expand-down)\n * 32-bit data segment for all of DS, ES, and SS, which uses a limit of \"-1\"; ie:\n * \n * SS=0018[ED800000,FFFFFFFF] DS=0018[ED800000,FFFFFFFF] ES=0018[ED800000,FFFFFFFF]\n *\n * so we end up calculating an upper limit of 0xED7FFFFF, which is lower than the lower limit of 0xED800000.\n * \n * For now, these \"limit wrap-around\" situations are resolved by using unsigned values and then applying\n * a linear address ceiling. TODO: Come up with a simple solution for properly dealing with limit wrap-around.\n */\n if (this.segSS.fExpDown) {\n this.regLSPLimit = (this.segSS.base >>> 0) + (this.segSS.maskAddr >>> 0);\n this.regLSPLimitLow = (this.segSS.base >>> 0) + (this.segSS.limit >>> 0);\n } else {\n this.regLSPLimit = (this.segSS.base >>> 0) + (this.segSS.limit >>> 0);\n this.regLSPLimitLow = (this.segSS.base >>> 0);\n }\n \n this.regLSPLimit = Math.min(this.regLSPLimit, this.nMemMask >>> 0);\n this.regLSPLimitLow = Math.min(this.regLSPLimitLow, this.nMemMask >>> 0);\n \n if (!BUGS_8086 && !fInterruptable) this.opFlags |= X86.OPFLAG.NOINTR;\n return true;\n }\n return false;\n }\n\n /**\n * getES()\n *\n * @this {CPUX86}\n * @return {number}\n */\n getES()\n {\n return this.segES.sel;\n }\n\n /**\n * setES(sel)\n *\n * @this {CPUX86}\n * @param {number} sel\n * @return {boolean}\n */\n setES(sel)\n {\n if (this.segES.load(sel) !== X86.ADDR_INVALID) {\n if (!BUGS_8086) this.opFlags |= this.OPFLAG_NOINTR_8086;\n return true;\n }\n return false;\n }\n\n /**\n * getFS()\n *\n * NOTE: segFS is defined for I386 only.\n *\n * @this {CPUX86}\n * @return {number}\n */\n getFS()\n {\n return this.segFS.sel;\n }\n\n /**\n * setFS(sel)\n *\n * NOTE: segFS is defined for I386 only.\n *\n * @this {CPUX86}\n * @param {number} sel\n * @return {boolean}\n */\n setFS(sel)\n {\n return this.segFS.load(sel) !== X86.ADDR_INVALID;\n }\n\n /**\n * getGS()\n *\n * NOTE: segGS is defined for I386 only.\n *\n * @this {CPUX86}\n * @return {number}\n */\n getGS()\n {\n return this.segGS.sel;\n }\n\n /**\n * setGS(sel)\n *\n * NOTE: segGS is defined for I386 only.\n *\n * @this {CPUX86}\n * @param {number} sel\n * @return {boolean}\n */\n setGS(sel)\n {\n return this.segGS.load(sel) !== X86.ADDR_INVALID;\n }\n\n /**\n * getIP()\n *\n * @this {CPUX86}\n * @return {number}\n */\n getIP()\n {\n return (this.regLIP - this.segCS.base)|0;\n }\n\n /**\n * setIP(off)\n *\n * @this {CPUX86}\n * @param {number} off\n */\n setIP(off)\n {\n this.regLIP = (this.segCS.base + (off & (I386? this.maskData : 0xffff)))|0;\n if (PREFETCH) this.refillPrefetch();\n }\n\n /**\n * setLIP(addr)\n *\n * @this {CPUX86}\n * @param {number} addr\n */\n setLIP(addr)\n {\n this.regLIP = addr;\n this.regLIPMax = (this.segCS.base >>> 0) + (this.segCS.limit >>> 0) + 1;\n\n /*\n * TODO: Verify the proper source for CPL. Should it come from segCS.cpl or segCS.dpl?\n * Also, note that LOADALL386 wants it to come from segSS.dpl.\n */\n this.nCPL = this.segCS.cpl; // cache the current CPL where it's more convenient\n\n if (I386) this.resetSizes();\n /*\n * Here, we need to additionally test whether the prefetch buffer (adwPrefetch) has been allocated yet,\n * because when resetRegs() is first called, the Bus hasn't been initialized yet, so there's nothing to fetch.\n *\n * We'll allocate the prefetch buffer when the Bus calls initMemory().\n */\n if (PREFETCH && this.adwPrefetch) this.refillPrefetch();\n }\n\n /**\n * setCSIP(off, sel, fCall)\n *\n * This function is a little different from the other segment setters, only because it turns out that CS is\n * never set without an accompanying IP (well, except for a few undocumented instructions, like POP CS, which\n * were available ONLY on the 8086/8088/80186/80188; see setCS() for details).\n *\n * And even though this function is called setCSIP(), please note the order of the parameters is [IP,CS],\n * which matches the order that CS:IP values are normally stored in memory, allowing us to make calls like this:\n *\n * this.setCSIP(this.popWord(), this.popWord());\n *\n * @this {CPUX86}\n * @param {number} off\n * @param {number} sel\n * @param {boolean} [fCall] is true if CALLF in progress, false if RETF/IRET in progress, undefined otherwise\n * @return {boolean|null} true if a stack switch occurred; the only operation that needs to pay attention is opRETFn()\n */\n setCSIP(off, sel, fCall)\n {\n /*\n * Setting IP needs to occur AFTER loadCode(), because it may differ from the given IP if sel refers to a gate.\n */\n var base = this.segCS.loadCode(off, sel, fCall);\n if (base !== X86.ADDR_INVALID) {\n this.setLIP(base + (this.segCS.offIP & (I386? this.segCS.maskData : 0xffff)));\n return this.segCS.fStackSwitch;\n }\n return null;\n }\n\n /**\n * setCSBase(addr)\n *\n * Since the CPU must maintain regLIP as the sum of the CS base and the current IP, all calls to setBase()\n * for segCS need to go through here.\n *\n * @param {number} addr\n */\n setCSBase(addr)\n {\n var regIP = this.getIP();\n addr = this.segCS.setBase(addr);\n this.regLIP = (addr + regIP)|0;\n this.regLIPMax = (addr >>> 0) + (this.segCS.limit >>> 0) + 1;\n }\n\n /**\n * checkIP(inc)\n *\n * TODO: If we didn't care about compatibility, we could just return:\n *\n * (this.regLIP + inc)|0\n *\n * and be done with it, because there probably isn't any \"good\" code that triggers the\n * \"newLIP > this.regLIPMax\" condition. This check costs us about 2Mhz performance on an 80386.\n *\n * Turning PREFETCH on tends to offset this performance hit, but PREFETCH *without* this hit would\n * probably perform even better.\n *\n * @this {CPUX86}\n * @param {number} inc (positive)\n * @return {number} new LIP\n */\n checkIP(inc)\n {\n var newLIP = (this.regLIP >>> 0) + inc;\n if (newLIP > this.regLIPMax) {\n /*\n * There's no such thing as a GP fault on the 8086/8088, and I'm now assuming that,\n * on newer processors, all attempts to fetch opcodes beyond the limit trigger a fault.\n */\n if (this.model <= X86.MODEL_8088 /* || this.segCS.limit == this.segCS.maskAddr */) {\n newLIP = this.segCS.base + ((newLIP - this.regLIPMax) & (I386? this.maskData : 0xffff));\n if (inc == 2) this.opFlags |= X86.OPFLAG.WRAP;\n } else {\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n }\n }\n return newLIP|0;\n }\n\n /**\n * resetIP(dec)\n *\n * This \"rewinds\" IP to the beginning of the current instruction (eg, an instruction with a REP prefix)\n *\n * @this {CPUX86}\n * @param {number} dec (negative)\n */\n resetIP(dec)\n {\n if (BUGS_8086) {\n this.regLIP = (this.regLIP + dec)|0;\n /*\n * This assertion is intended to fail if/when we encounter a \"buggy\" instruction (see BUGS_8086)\n */\n\n } else {\n if (PREFETCH) {\n this.cbPrefetch += this.regLIP - this.opLIP;\n this.regLIP = this.opLIP;\n /*\n * If \"rewinding\" produces a prefetch total greater than the allocated amount, then we must have\n * refilled the queue somewhere in the middle of the rewound instruction, so we need to refill the\n * queue all over again; otherwise, the next repetition may fetch future data instead of past data.\n *\n * That's the bad news; the good news is that this extra refill should only hurt performance of the\n * first repetition.\n */\n if (this.cbPrefetch > CPUX86.PFINFO.LENGTH) this.refillPrefetch();\n } else {\n this.regLIP = this.opLIP;\n }\n }\n }\n\n /**\n * getSP()\n *\n * @this {CPUX86}\n * @return {number}\n */\n getSP()\n {\n if (I386) {\n // assert(!((this.regLSP - this.segSS.base) & ~this.segSS.maskAddr));\n return (this.regESP & ~this.segSS.maskAddr) | (this.regLSP - this.segSS.base);\n }\n return (this.regLSP - this.segSS.base)|0;\n }\n\n /**\n * setSP(off)\n *\n * @this {CPUX86}\n * @param {number} off\n */\n setSP(off)\n {\n if (I386) {\n this.regESP = off;\n this.regLSP = (this.segSS.base + (off & this.segSS.maskAddr))|0;\n } else {\n this.regLSP = (this.segSS.base + off)|0;\n }\n }\n\n /**\n * setArithResult(dst, src, value, type, fSubtract)\n *\n * Updates the flags for arithmetic instructions; use setLogicResult() for logical instructions.\n *\n * The type parameter indicates both the size of the result (BYTE, WORD or DWORD) and which of the\n * flags should now be considered \"cached\" by the new result variables. If the previous resultType\n * specifies any flags not contained in the new type parameter, then those flags must be immediately\n * calculated and written to the appropriate bit(s) in regPS.\n *\n * The default assumes an \"addition\" (eg, ADD, ADC, INC), where value = dst + src. The fSubtract\n * parameter is used to indicate a \"subtraction\" (eg, CMP, DEC, SUB, SBB), where value = dst - src;\n * We can transform a subtraction into an addition, since it's also true that dst = value + src,\n * by swapping swap dst and value -- which is exactly what we do below. This allows all downstream\n * flag calculations (eg, getCF(), getOF()) to remain the same.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @param {number} value\n * @param {number} type\n * @param {boolean} [fSubtract]\n */\n setArithResult(dst, src, value, type, fSubtract)\n {\n if ((type & X86.RESULT.ALL) != X86.RESULT.ALL && type != this.resultType) {\n var diff = ((type ^ this.resultType) & this.resultType);\n if (diff) {\n if (diff & X86.RESULT.CF) this.getCF();\n if (diff & X86.RESULT.PF) this.getPF();\n if (diff & X86.RESULT.AF) this.getAF();\n if (diff & X86.RESULT.ZF) this.getZF();\n if (diff & X86.RESULT.SF) this.getSF();\n if (diff & X86.RESULT.OF) this.getOF();\n }\n }\n if (!fSubtract) {\n this.resultDst = dst;\n this.resultArith = value;\n } else {\n this.resultDst = value;\n this.resultArith = dst;\n }\n this.resultSrc = src;\n this.resultLogic = value;\n this.resultType = type;\n }\n\n /**\n * setLogicResult(value, type, carry, overflow)\n *\n * Updates the flags for logical instructions (eg, AND, OR, TEST, XOR); ie, instructions\n * that update PF, ZF, and SF, while clearing CF and OF (although CF and OF can be explicitly\n * set via the carry and overflow parameters as needed). AF is always considered undefined.\n *\n * TODO: We should observe the behavior of AF on real CPUs, and determine if there is a\n * well-defined behavior, even though none is documented. Ditto for OF on shift instructions\n * when the shift count > 1.\n *\n * @this {CPUX86}\n * @param {number} value\n * @param {number} type\n * @param {number} [carry]\n * @param {number} [overflow]\n * @return {number} value\n */\n setLogicResult(value, type, carry, overflow)\n {\n this.resultType = type | X86.RESULT.LOGIC;\n this.resultLogic = value;\n if (carry) this.setCF(); else this.clearCF();\n if (overflow) this.setOF(); else this.clearOF();\n return value;\n }\n\n /**\n * setRotateResult(result, carry, size)\n *\n * Used by all rotate instructions (ie, RCL, RCR, ROL, ROR) to update CF and OF.\n *\n * TODO: We should observe the behavior of OF on real CPUs whenever the rotate count > 1,\n * and determine if there is a well-defined behavior, even though none is documented.\n *\n * @this {CPUX86}\n * @param {number} result\n * @param {number} carry\n * @param {number} size\n */\n setRotateResult(result, carry, size)\n {\n if (carry & size) this.setCF(); else this.clearCF();\n if ((result ^ carry) & size) this.setOF(); else this.clearOF();\n }\n\n /**\n * getCarry()\n *\n * @this {CPUX86}\n * @return {number} 0 or 1, depending on whether CF is clear or set\n */\n getCarry()\n {\n return this.getCF()? 1 : 0;\n }\n\n /**\n * getCF()\n *\n * The following table summarizes bit 31 of the dst (D) and src (S) operands, bit 31 of the\n * addition (A), along with the expected carry bit (C):\n *\n * D S A C\n * - - - -\n * 0 0 0 0 no\n * 0 0 1 0 no (there must have been a carry out of bit 30, but it was \"absorbed\")\n * 0 1 0 1 yes (there must have been a carry out of bit 30, but it was NOT \"absorbed\")\n * 0 1 1 0 no\n * 1 0 0 1 yes (same as the preceding \"yes\" case)\n * 1 0 1 0 no\n * 1 1 0 1 yes (since the addition of two ones must always produce a carry)\n * 1 1 1 1 yes (since the addition of two ones must always produce a carry)\n *\n * So, we use the following calculation:\n *\n * (resultDst ^ ((resultDst ^ resultSrc) & (resultSrc ^ resultArith))) & resultType\n *\n * NOTE: The above table assumes that the resultDst (D) and resultSrc (S) operands were ADDED to\n * produce resultArith (A); if they were SUBTRACTED instead (D - S), then D and A must be swapped\n * after the subtraction, so that the above truth table still applies; see setArithResult().\n *\n * @this {CPUX86}\n * @return {number} 0 or X86.PS.CF\n */\n getCF()\n {\n if (this.resultType & X86.RESULT.CF) {\n this.regPS &= ~X86.PS.CF;\n if ((this.resultDst ^ ((this.resultDst ^ this.resultSrc) & (this.resultSrc ^ this.resultArith))) & (this.resultType & X86.RESULT.TYPE)) {\n this.regPS |= X86.PS.CF;\n }\n this.resultType &= ~X86.RESULT.CF;\n }\n return this.regPS & X86.PS.CF;\n }\n\n /**\n * getPF()\n *\n * From http://graphics.stanford.edu/~seander/bithacks.html#ParityParallel:\n *\n * unsigned int v; // word value to compute the parity of\n * v ^= v >> 16;\n * v ^= v >> 8;\n * v ^= v >> 4;\n * v &= 0xf;\n * return (0x6996 >> v) & 1;\n *\n * The method above takes around 9 operations, and works for 32-bit words. It may be optimized to work just on\n * bytes in 5 operations by removing the two lines immediately following \"unsigned int v;\". The method first shifts\n * and XORs the eight nibbles of the 32-bit value together, leaving the result in the lowest nibble of v. Next,\n * the binary number 0110 1001 1001 0110 (0x6996 in hex) is shifted to the right by the value represented in the\n * lowest nibble of v. This number is like a miniature 16-bit parity-table indexed by the low four bits in v.\n * The result has the parity of v in bit 1, which is masked and returned.\n *\n * The x86 parity flag (PF) is based exclusively on the low 8 bits of resultParitySign, so our calculation is bit\n * simpler. Note that PF must be SET if that byte has EVEN parity, and CLEAR if it has ODD parity.\n *\n * @this {CPUX86}\n * @return {number} 0 or X86.PS.PF\n */\n getPF()\n {\n if (this.resultType & X86.RESULT.PF) {\n this.regPS &= ~X86.PS.PF;\n if ((0x9669 >> ((this.resultLogic ^ (this.resultLogic >> 4)) & 0xf)) & 1) {\n this.regPS |= X86.PS.PF;\n }\n this.resultType &= ~X86.RESULT.PF;\n }\n return this.regPS & X86.PS.PF;\n }\n\n /**\n * getAF()\n *\n * To determine if there's been a carry out of the low 4 bits of an arithmetic operation,\n * we look at all the possible inputs for bit 4, and calculate AF = A^(D^S).\n *\n * D S A D^S AF\n * - - - --- --\n * 0 0 0 0 0\n * 0 0 1 0 1\n * 0 1 0 1 1\n * 0 1 1 1 0\n * 1 0 0 1 1\n * 1 0 1 1 0\n * 1 1 0 0 0\n * 1 1 1 0 1\n *\n * The final calculation looks like:\n *\n * (resultArith ^ (resultDst ^ resultSrc)) & 0x0010\n *\n * @this {CPUX86}\n * @return {number} 0 or X86.PS.AF\n */\n getAF()\n {\n if (this.resultType & X86.RESULT.AF) {\n this.regPS &= ~X86.PS.AF;\n if ((this.resultArith ^ (this.resultDst ^ this.resultSrc)) & 0x0010) {\n this.regPS |= X86.PS.AF;\n }\n this.resultType &= ~X86.RESULT.AF;\n }\n return this.regPS & X86.PS.AF;\n }\n\n /**\n * getZF()\n *\n * @this {CPUX86}\n * @return {number} 0 or X86.PS.ZF\n */\n getZF()\n {\n if (this.resultType & X86.RESULT.ZF) {\n this.regPS &= ~X86.PS.ZF;\n if (!(this.resultLogic & (((this.resultType & X86.RESULT.TYPE) - 1) | (this.resultType & X86.RESULT.TYPE)))) {\n this.regPS |= X86.PS.ZF;\n }\n this.resultType &= ~X86.RESULT.ZF;\n }\n return this.regPS & X86.PS.ZF;\n }\n\n /**\n * getSF()\n *\n * @this {CPUX86}\n * @return {number} 0 or X86.PS.SF\n */\n getSF()\n {\n if (this.resultType & X86.RESULT.SF) {\n this.regPS &= ~X86.PS.SF;\n if (this.resultLogic & (this.resultType & X86.RESULT.TYPE)) {\n this.regPS |= X86.PS.SF;\n }\n this.resultType &= ~X86.RESULT.SF;\n }\n return this.regPS & X86.PS.SF;\n }\n\n /**\n * getOF()\n *\n * Overflow was originally calculated as:\n *\n * (resultParitySign ^ resultAuxOverflow ^ (resultParitySign >> 1)) & (resultSize >> 1)\n *\n * but as you can see, that calculation depends on the carry out of the 8/16/32-bit result in\n * resultParitySign, which we don't have access to for 32-bit results. So we fall-back to the\n * following:\n *\n * ((resultDst ^ resultArith) & (resultSrc ^ resultArith)) & resultType\n *\n * which you can verify from the following table of sign bits, where x1 is resultDst ^ resultArith,\n * and x2 is resultSrc ^ resultArith:\n *\n * D S A x1 x2 OF\n * - - - -- -- --\n * 0 0 0 0 0 0\n * 0 0 1 1 1 1 (adding two positive values yielded a negative value)\n * 0 1 0 0 1 0\n * 0 1 1 1 0 0\n * 1 0 0 1 0 0\n * 1 0 1 0 1 0\n * 1 1 0 1 1 1 (adding two negative values yielded a positive value)\n * 1 1 1 0 0 0\n *\n * NOTE: The above table assumes that the resultDst (D) and resultSrc (S) operands were ADDED to\n * produce resultArith (A); if they were SUBTRACTED instead (D - S), then D and A must be swapped\n * after the subtraction, so that the above truth table still applies; see setArithResult().\n *\n * @this {CPUX86}\n * @return {number} 0 or X86.PS.OF\n */\n getOF()\n {\n if (this.resultType & X86.RESULT.OF) {\n this.regPS &= ~X86.PS.OF;\n if (((this.resultDst ^ this.resultArith) & (this.resultSrc ^ this.resultArith)) & (this.resultType & X86.RESULT.TYPE)) {\n this.regPS |= X86.PS.OF;\n }\n this.resultType &= ~X86.RESULT.OF;\n }\n return this.regPS & X86.PS.OF;\n }\n\n /**\n * getTF()\n *\n * @this {CPUX86}\n * @return {number} 0 or X86.PS.TF\n */\n getTF()\n {\n return (this.regPS & X86.PS.TF);\n }\n\n /**\n * getIF()\n *\n * @this {CPUX86}\n * @return {number} 0 or X86.PS.IF\n */\n getIF()\n {\n return (this.regPS & X86.PS.IF);\n }\n\n /**\n * getDF()\n *\n * @this {CPUX86}\n * @return {number} 0 or X86.PS.DF\n */\n getDF()\n {\n return (this.regPS & X86.PS.DF);\n }\n\n /**\n * clearCF()\n *\n * @this {CPUX86}\n */\n clearCF()\n {\n this.resultType &= ~X86.RESULT.CF;\n this.regPS &= ~X86.PS.CF;\n }\n\n /**\n * clearPF()\n *\n * @this {CPUX86}\n */\n clearPF()\n {\n this.resultType &= ~X86.RESULT.PF;\n this.regPS &= ~X86.PS.PF;\n }\n\n /**\n * clearAF()\n *\n * @this {CPUX86}\n */\n clearAF()\n {\n this.resultType &= ~X86.RESULT.AF;\n this.regPS &= ~X86.PS.AF;\n }\n\n /**\n * clearZF()\n *\n * @this {CPUX86}\n */\n clearZF()\n {\n this.resultType &= ~X86.RESULT.ZF;\n this.regPS &= ~X86.PS.ZF;\n }\n\n /**\n * clearSF()\n *\n * @this {CPUX86}\n */\n clearSF()\n {\n this.resultType &= ~X86.RESULT.SF;\n this.regPS &= ~X86.PS.SF;\n }\n\n /**\n * clearIF()\n *\n * @this {CPUX86}\n */\n clearIF()\n {\n this.regPS &= ~X86.PS.IF;\n }\n\n /**\n * clearDF()\n *\n * @this {CPUX86}\n */\n clearDF()\n {\n this.regPS &= ~X86.PS.DF;\n }\n\n /**\n * clearOF()\n *\n * @this {CPUX86}\n */\n clearOF()\n {\n this.resultType &= ~X86.RESULT.OF;\n this.regPS &= ~X86.PS.OF;\n }\n\n /**\n * setCF()\n *\n * @this {CPUX86}\n */\n setCF()\n {\n this.resultType &= ~X86.RESULT.CF;\n this.regPS |= X86.PS.CF;\n }\n\n /**\n * setPF()\n *\n * @this {CPUX86}\n */\n setPF()\n {\n this.resultType &= ~X86.RESULT.PF;\n this.regPS |= X86.PS.PF;\n }\n\n /**\n * setAF()\n *\n * @this {CPUX86}\n */\n setAF()\n {\n this.resultType &= ~X86.RESULT.AF;\n this.regPS |= X86.PS.AF;\n }\n\n /**\n * setZF()\n *\n * @this {CPUX86}\n */\n setZF()\n {\n this.resultType &= ~X86.RESULT.ZF;\n this.regPS |= X86.PS.ZF;\n }\n\n /**\n * setSF()\n *\n * @this {CPUX86}\n */\n setSF()\n {\n this.resultType &= ~X86.RESULT.SF;\n this.regPS |= X86.PS.SF;\n }\n\n /**\n * setIF()\n *\n * @this {CPUX86}\n */\n setIF()\n {\n this.regPS |= X86.PS.IF;\n }\n\n /**\n * setDF()\n *\n * @this {CPUX86}\n */\n setDF()\n {\n this.regPS |= X86.PS.DF;\n }\n\n /**\n * setOF()\n *\n * @this {CPUX86}\n */\n setOF()\n {\n this.resultType &= ~X86.RESULT.OF;\n this.regPS |= X86.PS.OF;\n }\n\n /**\n * getPS()\n *\n * @this {CPUX86}\n * @return {number}\n */\n getPS()\n {\n return (this.regPS & ~X86.PS_CACHED) | (this.getCF() | this.getPF() | this.getAF() | this.getZF() | this.getSF() | this.getOF());\n }\n\n /**\n * setMSW(w)\n *\n * Factored out of x86op0f.js, since both opLMSW and opLOADALL are capable of setting a new MSW.\n * The caller is responsible for assessing the appropriate cycle cost.\n *\n * @this {CPUX86}\n * @param {number} w\n */\n setMSW(w)\n {\n /*\n * This instruction is always allowed to set MSW.PE, but it cannot clear MSW.PE once set;\n * therefore, we always OR the previous value of MSW.PE into the new value before loading.\n */\n w |= (this.regCR0 & X86.CR0.MSW.PE) | X86.CR0.MSW.ON;\n this.regCR0 = (this.regCR0 & ~X86.CR0.MSW.MASK) | (w & X86.CR0.MSW.MASK);\n /*\n * Since the 80286 cannot return to real-mode via this instruction, the only transition we\n * must worry about is to protected-mode. And there's no harm calling setProtMode() if the\n * CPU is already in protected-mode; we could certainly optimize out the call in that case,\n * but the instruction isn't used frequently enough to warrant it.\n */\n if (this.regCR0 & X86.CR0.MSW.PE) this.setProtMode(true);\n }\n\n /**\n * setPS(regPS)\n *\n * @this {CPUX86}\n * @param {number} regPS\n * @param {number} [cpl]\n */\n setPS(regPS, cpl)\n {\n /*\n * OS/2 1.0 discriminates between an 80286 and an 80386 based on whether an IRET in real-mode that\n * pops 0xF000 into the flags is able to set *any* of flag bits 12-15: if it can, then OS/2 declares\n * the CPU an 80386.\n *\n * So, if the CPU is an 80286, we clear incoming bits 12-14 in real-mode (bit 15 is never allowed to\n * be modified, so there's no need to mask it). And if the CPU is an 80386, no bits are automatically\n * cleared in real-mode (PS_CLEAR_RM is zero); although that allows the IOPL bits to change, it doesn't\n * affect real-mode operation, since CPL is always zero, making IOPL irrelevant.\n */\n if (!(this.regCR0 & X86.CR0.MSW.PE)) regPS &= ~this.PS_CLEAR_RM;\n\n /*\n * There are some cases (eg, an IRET returning to a less privileged code segment) where the CPL\n * we compare against should come from the outgoing code segment, so if the caller provided it, use it.\n */\n if (cpl === undefined) cpl = this.nCPL;\n\n /*\n * Since PS.IOPL and PS.IF are part of PS_DIRECT, we need to take care of any 80286-specific behaviors\n * before setting the PS_DIRECT bits from the incoming regPS bits.\n *\n * Specifically, PS.IOPL is unchanged if CPL > 0, and PS.IF is unchanged if CPL > IOPL.\n */\n if (!cpl) {\n this.nIOPL = (regPS & X86.PS.IOPL.MASK) >> X86.PS.IOPL.SHIFT; // IOPL allowed to change\n } else {\n regPS = (regPS & ~X86.PS.IOPL.MASK) | (this.regPS & X86.PS.IOPL.MASK); // IOPL not allowed to change\n }\n\n if (cpl > this.nIOPL) {\n regPS = (regPS & ~X86.PS.IF) | (this.regPS & X86.PS.IF); // IF not allowed to change\n }\n\n this.resultType = X86.RESULT.BYTE;\n this.regPS = (this.regPS & ~(this.PS_DIRECT|X86.PS_CACHED)) | (regPS & (this.PS_DIRECT|X86.PS_CACHED)) | this.PS_SET;\n\n if (this.regPS & X86.PS.TF) {\n this.intFlags |= X86.INTFLAG.TRAP;\n this.opFlags |= X86.OPFLAG.NOINTR;\n }\n }\n\n /**\n * checkIOPM(port, nPorts, fInput)\n *\n * @this {CPUX86}\n * @param {number} port (0x0000 to 0xffff)\n * @param {number} nPorts (1 to 4)\n * @param {boolean} [fInput] (true if input, false if output; output assumed if not specified)\n * @return {boolean} true if allowed, false if not\n */\n checkIOPM(port, nPorts, fInput)\n {\n var bitsPorts = 0;\n if (I386 && (this.regCR0 & X86.CR0.MSW.PE) && (this.nCPL > this.nIOPL || (this.regPS & X86.PS.VM)) && this.segTSS.addrIOPM) {\n var offIOPM = port >>> 3;\n var addrIOPM = this.segTSS.addrIOPM + offIOPM;\n bitsPorts = ((1 << nPorts) - 1) << (port & 0x7);\n while (bitsPorts && addrIOPM <= this.segTSS.addrIOPMLimit) {\n var bits = this.getByte(addrIOPM);\n if (bits & bitsPorts) break;\n bitsPorts >>>= 8;\n addrIOPM++;\n }\n }\n if (bitsPorts) {\n if (this.messageEnabled(Messages.IOPM)) this.printMessage(\"checkIOPM(\" + Str.toHexWord(port) + \",\" + nPorts + \",\" + (fInput? \"input\" : \"output\") + \"): trapped\", true, true);\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return false;\n }\n return true;\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {CPUX86}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"AX\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var fBound = false;\n switch (sBinding) {\n case \"EAX\":\n case \"EBX\":\n case \"ECX\":\n case \"EDX\":\n case \"ESP\":\n case \"EBP\":\n case \"ESI\":\n case \"EDI\":\n case \"EIP\":\n case \"AX\":\n case \"BX\":\n case \"CX\":\n case \"DX\":\n case \"SP\":\n case \"BP\":\n case \"SI\":\n case \"DI\":\n case \"IP\":\n case \"PC\": // deprecated as an alias for \"IP\" (still used by older XML files, like the one at http://tpoindex.github.io/crobots/)\n case \"CS\":\n case \"DS\":\n case \"SS\":\n case \"ES\":\n case \"FS\":\n case \"GS\":\n case \"CR0\":\n case \"CR2\":\n case \"CR3\":\n case \"PS\": // this refers to \"Processor Status\", aka the 16-bit flags register (although DEBUG.COM refers to this as \"PC\", surprisingly)\n case \"C\":\n case \"P\":\n case \"A\":\n case \"Z\":\n case \"S\":\n case \"T\":\n case \"I\":\n case \"D\":\n case \"V\":\n this.bindings[sBinding] = control;\n this.cLiveRegs++;\n fBound = true;\n break;\n default:\n fBound = super.setBinding(sHTMLType, sBinding, control);\n break;\n }\n return fBound;\n }\n\n /**\n * probeAddr(addr, size, fPhysical)\n *\n * Used by the Debugger to probe addresses without risk of triggering a page fault, and by internal\n * functions, like helpCheckFault(), that must also avoid triggering faults, since they're not part of\n * standard CPU operation.\n *\n * Since originally written, I've also relaxed the requirement that the request be contained entirely\n * within a single block; this was never a problem for any size-aligned request, but unfortunately, it\n * was difficult for the Debugger to guarantee that every 2 or 4-byte request would be always be word or\n * dword-aligned. So now requests that straddle blocks will be broken into smaller probeAddr() requests.\n *\n * @this {CPUX86}\n * @param {number} addr is a linear address\n * @param {number} [size] is a length (default is 1; if specified, must be 1, 2 or 4)\n * @param {boolean} [fPhysical] (true for physical probe, false for linear; linear is the default)\n * @return {number|null} value at the specified address, or null if invalid\n */\n probeAddr(addr, size, fPhysical)\n {\n var aBlocks = (fPhysical? this.aBusBlocks : this.aMemBlocks);\n var block = aBlocks[(addr & this.nMemMask) >>> this.nBlockShift];\n if (block && block.type == Memory.TYPE.UNPAGED) block = this.mapPageBlock(addr, false, true);\n\n if (block) {\n var off = addr & this.nBlockLimit;\n if (!size || size == 1) {\n return block.readByteDirect(off, addr);\n }\n if (size == 2) {\n if (off < this.nBlockLimit) {\n return block.readShortDirect(off, addr);\n }\n return block.readByteDirect(off, addr) | (this.probeAddr(addr + 1, 1, fPhysical) << 8);\n }\n if (size == 4) {\n if (off < this.nBlockLimit - 2) {\n return block.readLongDirect(off, addr);\n }\n if (off == this.nBlockLimit - 1) {\n return block.readShortDirect(off, addr) | (this.probeAddr(addr + 2, 2, fPhysical) << 16);\n }\n return block.readByteDirect(off, addr) | (this.probeAddr(addr + 1, 1, fPhysical) << 8) | (this.probeAddr(addr + 2, 1, fPhysical) << 16) | (this.probeAddr(addr + 3, 1, fPhysical) << 24);\n }\n }\n\n /*\n * Since the Bus component initializes all unused portions of physical address space with an empty\n * block, we have also written mapPageBlock() to return an empty block (memEmpty) whenever there is\n * no valid mapping. So if we ever end up here, this may represent a hole that needs plugging.\n *\n * It's also possible the caller passed a bogus parameter, such as an invalid size (must be 1, 2 or 4).\n */\n\n return null;\n }\n\n /**\n * getByte(addr)\n *\n * Use bus.getByte() for physical addresses, and cpu.getByte() for linear addresses; the latter takes care\n * of paging, cycle counts, and BACKTRACK states, if any.\n *\n * @this {CPUX86}\n * @param {number} addr is a linear address\n * @return {number} byte (8-bit) value at that address\n */\n getByte(addr)\n {\n if (BACKTRACK) this.backTrack.btiMem0 = this.bus.readBackTrack(addr);\n return this.aMemBlocks[(addr & this.nMemMask) >>> this.nBlockShift].readByte(addr & this.nBlockLimit, addr);\n }\n\n /**\n * getShort(addr)\n *\n * Use bus.getShort() for physical addresses, and cpu.getShort() for linear addresses; the latter takes care\n * of paging, cycle counts, and BACKTRACK states, if any.\n *\n * @this {CPUX86}\n * @param {number} addr is a linear address\n * @return {number} word (16-bit) value at that address\n */\n getShort(addr)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nMemMask) >>> this.nBlockShift;\n /*\n * On the 8088, it takes 4 cycles to read the additional byte REGARDLESS whether the address is odd or even.\n * TODO: For the 8086, the penalty is actually \"(addr & 0x1) << 2\" (4 additional cycles only when the address is odd).\n */\n this.nStepCycles -= this.cycleCounts.nWordCyclePenalty;\n\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.bus.readBackTrack(addr);\n this.backTrack.btiMem1 = this.bus.readBackTrack(addr + 1);\n }\n if (off < this.nBlockLimit) {\n return this.aMemBlocks[iBlock].readShort(off, addr);\n }\n var w = this.aMemBlocks[iBlock].readByte(off, addr);\n if (!(this.opFlags & X86.OPFLAG.FAULT)) {\n w |= this.aMemBlocks[(iBlock + 1) & this.nBlockMask].readByte(0, addr + 1) << 8;\n }\n return w;\n }\n\n /**\n * getLong(addr)\n *\n * Use bus.getLong() for physical addresses, and cpu.getLong() for linear addresses; the latter takes care\n * of paging, cycle counts, and BACKTRACK states, if any.\n *\n * @this {CPUX86}\n * @param {number} addr is a linear address\n * @return {number} long (32-bit) value at that address\n */\n getLong(addr)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nMemMask) >>> this.nBlockShift;\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.bus.readBackTrack(addr);\n this.backTrack.btiMem1 = this.bus.readBackTrack(addr + 1);\n this.backTrack.btiMem2 = this.bus.readBackTrack(addr + 2);\n this.backTrack.btiMem3 = this.bus.readBackTrack(addr + 3);\n }\n if (off < this.nBlockLimit - 2) {\n return this.aMemBlocks[iBlock].readLong(off, addr);\n }\n /*\n * I think the previous version of this function tried to be too clever (ie, reading the last\n * long in the current block and the first long in the next block and masking/combining the results),\n * which may have also created some undesirable side-effects for custom memory controllers.\n * This simpler (and probably more reliable) approach is to simply read the long as individual bytes.\n */\n var l = 0;\n var cb = 4, nShift = 0;\n var cbBlock = 4 - (off & 0x3); // (off & 0x3) will be 1, 2 or 3, so cbBlock will be 3, 2, or 1\n while (cb--) {\n l |= (this.aMemBlocks[iBlock].readByte(off++, addr++) << nShift);\n if (this.opFlags & X86.OPFLAG.FAULT) break;\n if (!--cbBlock) {\n iBlock = (iBlock + 1) & this.nBlockMask;\n off = 0;\n }\n nShift += 8;\n }\n return l;\n }\n\n /**\n * setByte(addr, b)\n *\n * Use bus.setByte() for physical addresses, and cpu.setByte() for linear addresses; the latter takes care\n * of paging, cycle counts, and BACKTRACK states, if any.\n *\n * @this {CPUX86}\n * @param {number} addr is a linear address\n * @param {number} b is the byte (8-bit) value to write (which we truncate to 8 bits; required by opSTOSb)\n */\n setByte(addr, b)\n {\n if (BACKTRACK) this.bus.writeBackTrack(addr, this.backTrack.btiMem0);\n this.aMemBlocks[(addr & this.nMemMask) >>> this.nBlockShift].writeByte(addr & this.nBlockLimit, b & 0xff, addr);\n }\n\n /**\n * setShort(addr, w)\n *\n * Use bus.setShort() for physical addresses, and cpu.setShort() for linear addresses; the latter takes care\n * of paging, cycle counts, and BACKTRACK states, if any.\n *\n * @this {CPUX86}\n * @param {number} addr is a linear address\n * @param {number} w is the word (16-bit) value to write (which we truncate to 16 bits to be safe)\n */\n setShort(addr, w)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nMemMask) >>> this.nBlockShift;\n /*\n * On the 8088, it takes 4 cycles to write the additional byte REGARDLESS whether the address is odd or even.\n * TODO: For the 8086, the penalty is actually \"(addr & 0x1) << 2\" (4 additional cycles only when the address is odd).\n */\n this.nStepCycles -= this.cycleCounts.nWordCyclePenalty;\n\n if (BACKTRACK) {\n this.bus.writeBackTrack(addr, this.backTrack.btiMem0);\n this.bus.writeBackTrack(addr + 1, this.backTrack.btiMem1);\n }\n if (off < this.nBlockLimit) {\n this.aMemBlocks[iBlock].writeShort(off, w & 0xffff, addr);\n return;\n }\n this.aMemBlocks[iBlock++].writeByte(off, w & 0xff, addr);\n if (this.opFlags & X86.OPFLAG.FAULT) return;\n this.aMemBlocks[iBlock & this.nBlockMask].writeByte(0, (w >> 8) & 0xff, addr + 1);\n }\n\n /**\n * setLong(addr, l)\n *\n * Use bus.setLong() for physical addresses, and cpu.setLong() for linear addresses; the latter takes care\n * of paging, cycle counts, and BACKTRACK states, if any.\n *\n * @this {CPUX86}\n * @param {number} addr is a linear address\n * @param {number} l is the long (32-bit) value to write\n */\n setLong(addr, l)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nMemMask) >>> this.nBlockShift;\n this.nStepCycles -= this.cycleCounts.nWordCyclePenalty;\n\n if (BACKTRACK) {\n this.bus.writeBackTrack(addr, this.backTrack.btiMem0);\n this.bus.writeBackTrack(addr + 1, this.backTrack.btiMem1);\n this.bus.writeBackTrack(addr + 2, this.backTrack.btiMem2);\n this.bus.writeBackTrack(addr + 3, this.backTrack.btiMem3);\n }\n if (off < this.nBlockLimit - 2) {\n this.aMemBlocks[iBlock].writeLong(off, l, addr);\n return;\n }\n /*\n * I think the previous version of this function tried to be too clever (ie, reading and rewriting\n * the last long in the current block, and then reading and rewriting the first long in the next\n * block), which may have also created some undesirable side-effects for custom memory controllers.\n * This simpler (and probably more reliable) approach is to simply write the long as individual bytes.\n */\n var cb = 4;\n var cbBlock = 4 - (off & 0x3); // (off & 0x3) will be 1, 2 or 3, so cbBlock will be 3, 2, or 1\n while (cb--) {\n this.aMemBlocks[iBlock].writeByte(off++, l & 0xff, addr++);\n if (this.opFlags & X86.OPFLAG.FAULT) return;\n if (!--cbBlock) {\n iBlock = (iBlock + 1) & this.nBlockMask;\n off = 0;\n }\n l >>>= 8;\n }\n }\n\n /**\n * getEAByte(seg, off)\n *\n * @this {CPUX86}\n * @param {SegX86} seg register (eg, segDS)\n * @param {number} off is a segment-relative offset\n * @return {number} byte (8-bit) value at that address\n */\n getEAByte(seg, off)\n {\n this.segEA = seg;\n this.offEA = off & (I386? this.maskAddr : 0xffff);\n this.regEA = seg.checkRead(this.offEA, 1);\n if (this.opFlags & X86.OPFLAG.NOREAD) return 0;\n var b = this.getByte(this.regEA);\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiMem0;\n return b;\n }\n\n /**\n * getEAByteData(off)\n *\n * @this {CPUX86}\n * @param {number} off is a segment-relative offset\n * @return {number} byte (8-bit) value at that address\n */\n getEAByteData(off)\n {\n return this.getEAByte(this.segData, off);\n }\n\n /**\n * getEAByteStack(off)\n *\n * @this {CPUX86}\n * @param {number} off is a segment-relative offset\n * @return {number} byte (8-bit) value at that address\n */\n getEAByteStack(off)\n {\n return this.getEAByte(this.segStack, off);\n }\n\n /**\n * getEAWord(seg, off)\n *\n * @this {CPUX86}\n * @param {SegX86} seg register (eg, segDS)\n * @param {number} off is a segment-relative offset\n * @return {number} word (16-bit or 32-bit) value at that address\n */\n getEAWord(seg, off)\n {\n var w;\n this.segEA = seg;\n this.offEA = off & (I386? this.maskAddr : 0xffff);\n this.regEA = seg.checkRead(this.offEA, (I386? this.sizeData : 2));\n if (this.opFlags & (X86.OPFLAG.NOREAD | X86.OPFLAG.WRAP)) {\n if (this.opFlags & X86.OPFLAG.NOREAD) return 0;\n /*\n * The WRAP flag must have been set by checkReadReal(), so we also know that we're dealing with\n * a 16-bit read, which allows us to make some simplifications here.\n */\n w = this.getByte(this.regEA) | (this.getByte(seg.checkRead(0, 1)) << 8);\n }\n else {\n w = this.getWord(this.regEA);\n }\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiMem0;\n this.backTrack.btiEAHi = this.backTrack.btiMem1;\n }\n return w;\n }\n\n /**\n * getEAShortData(off)\n *\n * @this {CPUX86}\n * @param {number} off is a segment-relative offset\n * @return {number} short (16-bit) value at that address\n */\n getEAShortData(off)\n {\n var w;\n this.segEA = this.segData;\n this.offEA = off & (I386? this.maskAddr : 0xffff);\n this.regEA = this.segEA.checkRead(this.offEA, 2);\n if (this.opFlags & (X86.OPFLAG.NOREAD | X86.OPFLAG.WRAP)) {\n if (this.opFlags & X86.OPFLAG.NOREAD) return 0;\n /*\n * The WRAP flag must have been set by checkReadReal(), so we also know that we're dealing with\n * a 16-bit read, which allows us to make some simplifications here.\n */\n w = this.getByte(this.regEA) | (this.getByte(this.segEA.checkRead(0, 1)) << 8);\n this.opFlags &= ~X86.OPFLAG.WRAP;\n }\n else {\n w = this.getShort(this.regEA);\n }\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiMem0;\n this.backTrack.btiEAHi = this.backTrack.btiMem1;\n }\n return w;\n }\n\n /**\n * getEAShortStack(off)\n *\n * @this {CPUX86}\n * @param {number} off is a segment-relative offset\n * @return {number} short (16-bit) value at that address\n */\n getEAShortStack(off)\n {\n var w;\n this.segEA = this.segStack;\n this.offEA = off & (I386? this.maskAddr : 0xffff);\n this.regEA = this.segEA.checkRead(this.offEA, 2);\n if (this.opFlags & (X86.OPFLAG.NOREAD | X86.OPFLAG.WRAP)) {\n if (this.opFlags & X86.OPFLAG.NOREAD) return 0;\n /*\n * The WRAP flag must have been set by checkReadReal(), so we also know that we're dealing with\n * a 16-bit read, which allows us to make some simplifications here.\n */\n w = this.getByte(this.regEA) | (this.getByte(this.segEA.checkRead(0, 1)) << 8);\n this.opFlags &= ~X86.OPFLAG.WRAP;\n }\n else {\n w = this.getShort(this.regEA);\n }\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiMem0;\n this.backTrack.btiEAHi = this.backTrack.btiMem1;\n }\n return w;\n }\n\n /**\n * getEALongData(off)\n *\n * @this {CPUX86}\n * @param {number} off is a segment-relative offset\n * @return {number} long (32-bit) value at that address\n */\n getEALongData(off)\n {\n this.segEA = this.segData;\n this.offEA = off & (I386? this.maskAddr : 0xffff);\n this.regEA = this.segEA.checkRead(this.offEA, 4);\n if (this.opFlags & X86.OPFLAG.NOREAD) return 0;\n var w = this.getLong(this.regEA);\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiMem0;\n this.backTrack.btiEAHi = this.backTrack.btiMem1;\n }\n return w;\n }\n\n /**\n * getEALongStack(off)\n *\n * @this {CPUX86}\n * @param {number} off is a segment-relative offset\n * @return {number} long (32-bit) value at that address\n */\n getEALongStack(off)\n {\n this.segEA = this.segStack;\n this.offEA = off & (I386? this.maskAddr : 0xffff);\n this.regEA = this.segEA.checkRead(this.offEA, 4);\n if (this.opFlags & X86.OPFLAG.NOREAD) return 0;\n var w = this.getLong(this.regEA);\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiMem0;\n this.backTrack.btiEAHi = this.backTrack.btiMem1;\n }\n return w;\n }\n\n /**\n * setEAByte(b)\n *\n * @this {CPUX86}\n * @param {number} b is the byte (8-bit) value to write\n */\n setEAByte(b)\n {\n if (this.opFlags & X86.OPFLAG.NOWRITE) return;\n if (BACKTRACK) this.backTrack.btiMem0 = this.backTrack.btiEALo;\n this.setByte(this.segEA.checkWrite(this.offEA, 1), b);\n }\n\n /**\n * setEAShort(w)\n *\n * @this {CPUX86}\n * @param {number} w is the short (16-bit) value to write\n */\n setEAShort(w)\n {\n if (this.opFlags & X86.OPFLAG.NOWRITE) return;\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiEALo;\n this.backTrack.btiMem1 = this.backTrack.btiEAHi;\n }\n var addr = this.segEA.checkWrite(this.offEA, 2);\n if (this.opFlags & X86.OPFLAG.WRAP) {\n /*\n * The WRAP flag must have been set by checkWriteReal(), so we also know that we're dealing with\n * a 16-bit write, which allows us to make some simplifications here.\n */\n this.setByte(addr, w);\n this.setByte(this.segEA.checkWrite(0, 1), w >> 8);\n this.opFlags &= ~X86.OPFLAG.WRAP;\n }\n else {\n this.setShort(addr, w);\n }\n }\n\n /**\n * setEALong(l)\n *\n * @this {CPUX86}\n * @param {number} l is the long (32-bit) value to write\n */\n setEALong(l)\n {\n if (this.opFlags & X86.OPFLAG.NOWRITE) return;\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiEALo;\n this.backTrack.btiMem1 = this.backTrack.btiEAHi;\n }\n this.setLong(this.segEA.checkWrite(this.offEA, 4), l);\n }\n\n /**\n * setEAWord(w)\n *\n * @this {CPUX86}\n * @param {number} w is the word (16-bit or 32-bit) value to write\n */\n setEAWord(w)\n {\n if (this.opFlags & X86.OPFLAG.NOWRITE) return;\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiEALo;\n this.backTrack.btiMem1 = this.backTrack.btiEAHi;\n }\n var addr = this.segEA.checkWrite(this.offEA, this.sizeData);\n if (this.opFlags & X86.OPFLAG.WRAP) {\n /*\n * The WRAP flag must have been set by checkWriteReal(), so we also know that we're dealing with\n * a 16-bit write, which allows us to make some simplifications here.\n */\n this.setByte(addr, w);\n this.setByte(this.segEA.checkWrite(0, 1), w >> 8);\n this.opFlags &= ~X86.OPFLAG.WRAP;\n }\n else {\n this.setWord(addr, w);\n }\n }\n\n /**\n * getSOByte(seg, off)\n *\n * This is like getEAByte(), but it does NOT update regEA.\n *\n * @this {CPUX86}\n * @param {SegX86} seg register (eg, segDS)\n * @param {number} off is a segment-relative offset\n * @return {number} byte (8-bit) value at that address\n */\n getSOByte(seg, off)\n {\n return this.getByte(seg.checkRead(off, 1));\n }\n\n /**\n * getSOWord(seg, off)\n *\n * This is like getEAWord(), but it does NOT update regEA.\n *\n * @this {CPUX86}\n * @param {SegX86} seg register (eg, segDS)\n * @param {number} off is a segment-relative offset\n * @return {number} word (16-bit) value at that address\n */\n getSOWord(seg, off)\n {\n var w;\n var addr = seg.checkRead(off, this.sizeData);\n if (this.opFlags & X86.OPFLAG.WRAP) {\n /*\n * The WRAP flag must have been set by checkReadReal(), so we also know that we're dealing with\n * a 16-bit read, which allows us to make some simplifications here.\n */\n w = this.getByte(addr) | (this.getByte(seg.checkRead(0, 1)) << 8);\n this.opFlags &= ~X86.OPFLAG.WRAP;\n }\n else {\n w = this.getWord(addr);\n }\n return w;\n }\n\n /**\n * setSOByte(seg, off, b)\n *\n * This is like setEAByte(), but it does NOT update regEAWrite.\n *\n * @this {CPUX86}\n * @param {SegX86} seg register (eg, segDS)\n * @param {number} off is a segment-relative offset\n * @param {number} b is the byte (8-bit) value to write\n */\n setSOByte(seg, off, b)\n {\n this.setByte(seg.checkWrite(off, 1), b);\n }\n\n /**\n * setSOWord(seg, off, w)\n *\n * This is like setEAWord(), but it does NOT update regEAWrite.\n *\n * @this {CPUX86}\n * @param {SegX86} seg register (eg, segDS)\n * @param {number} off is a segment-relative offset\n * @param {number} w is the word (16-bit) value to write\n */\n setSOWord(seg, off, w)\n {\n var addr = seg.checkWrite(off, this.sizeData);\n if (this.opFlags & X86.OPFLAG.WRAP) {\n /*\n * The WRAP flag must have been set by checkWriteReal(), so we also know that we're dealing with\n * a 16-bit write, which allows us to make some simplifications here.\n */\n this.setByte(addr, w);\n this.setByte(seg.checkWrite(0, 1), w >> 8);\n this.opFlags &= ~X86.OPFLAG.WRAP;\n }\n else {\n this.setWord(addr, w);\n }\n }\n\n /**\n * getBytePrefetch()\n *\n * @this {CPUX86}\n * @return {number} byte (8-bit) value at regLIP\n */\n getBytePrefetch()\n {\n if (!this.cbPrefetch) {\n this.refillPrefetch();\n if (!this.cbPrefetch) return this.getByte(this.regLIP);\n }\n var b = (this.adwPrefetch[this.regLIP & CPUX86.PFINFO.IP_MASK] >> ((this.regLIP & 0x3) << 3)) & 0xff;\n\n this.cbPrefetch--;\n return b;\n }\n\n /**\n * getShortPrefetch()\n *\n * @this {CPUX86}\n * @return {number} short (16-bit) value at regLIP\n */\n getShortPrefetch()\n {\n if (this.cbPrefetch < 2) {\n this.refillPrefetch();\n if (this.cbPrefetch < 2) {\n this.cbPrefetch = 0;\n return this.getShort(this.regLIP);\n }\n }\n var shift = (this.regLIP & 0x3) << 3;\n var w = (this.adwPrefetch[this.regLIP & CPUX86.PFINFO.IP_MASK] >>> shift) & 0xffff;\n if (shift > 16) w |= (this.adwPrefetch[(this.regLIP + 4) & CPUX86.PFINFO.IP_MASK] & 0xff) << 8;\n\n this.cbPrefetch -= 2;\n return w;\n }\n\n /**\n * getLongPrefetch()\n *\n * @this {CPUX86}\n * @return {number} long (32-bit) value at regLIP\n */\n getLongPrefetch()\n {\n if (this.cbPrefetch < 4) {\n this.refillPrefetch();\n if (this.cbPrefetch < 4) {\n this.cbPrefetch = 0;\n return this.getLong(this.regLIP);\n }\n }\n var shift = (this.regLIP & 0x3) << 3;\n var l = (this.adwPrefetch[this.regLIP & CPUX86.PFINFO.IP_MASK] >>> shift)|0;\n if (shift) l |= this.adwPrefetch[(this.regLIP + 4) & CPUX86.PFINFO.IP_MASK] << (32 - shift);\n\n this.cbPrefetch -= 4;\n return l;\n }\n\n /**\n * getWordPrefetch()\n *\n * @this {CPUX86}\n * @return {number} short (16-bit) or long (32-bit) value as appropriate\n */\n getWordPrefetch()\n {\n return (I386 && this.sizeData == 4? this.getLongPrefetch() : this.getShortPrefetch());\n }\n\n /**\n * refillPrefetch()\n *\n * This function is similar to probeAddr() in that must NOT trigger a fault, because prefetching\n * inherently runs the risk of fetching more bytes that may actually be executed. Also, to keep it\n * simple, we limit prefetching to whatever bytes (if any) are available in the current page. If the\n * page is not present, or there are insufficient bytes in the current page to completely fill the\n * queue, then the caller must request byte(s) \"the old-fashioned way\", to ensure proper fault handling.\n *\n * For example, if getShortPrefetch() finds there are only 0 or 1 bytes in the prefetch queue, and\n * if it is unable to obtain any more bytes via refillPrefetch(), then getShortPrefetch() must call\n * getShort(this.regLIP) (which is also what would be called if PREFETCH was disabled completely).\n *\n * @this {CPUX86}\n */\n refillPrefetch()\n {\n var aBlocks = this.aMemBlocks;\n var regLIP = this.regLIP & ~0x3;\n var block = aBlocks[(regLIP & this.nMemMask) >>> this.nBlockShift];\n if (block && block.type == Memory.TYPE.UNPAGED) {\n block = this.mapPageBlock(regLIP, false, true);\n if (block === this.memEmpty) block = null;\n }\n if (block) {\n var off = regLIP & this.nBlockLimit;\n var cbMax = this.nBlockSize - off;\n if (cbMax > CPUX86.PFINFO.LENGTH) cbMax = CPUX86.PFINFO.LENGTH;\n for (var i = 0; i < cbMax; i += 4) {\n this.adwPrefetch[regLIP & CPUX86.PFINFO.IP_MASK] = block.readLongDirect(off, regLIP);\n off += 4; regLIP += 4;\n }\n this.cbPrefetch = i - (this.regLIP & 0x3);\n // this.nBusCycles += 4;\n } else {\n this.cbPrefetch = 0;\n }\n }\n\n /**\n * getIPByte()\n *\n * @this {CPUX86}\n * @return {number} byte at the current IP; IP advanced by 1\n */\n getIPByte()\n {\n var newLIP = this.checkIP(1);\n var b = (PREFETCH? this.getBytePrefetch() : this.getByte(this.regLIP));\n if (BACKTRACK) this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMem0);\n this.regLIP = newLIP;\n return b;\n }\n\n /**\n * getIPShort()\n *\n * @this {CPUX86}\n * @return {number} short at the current IP; IP advanced by 2\n */\n getIPShort()\n {\n var w;\n var newLIP = this.checkIP(2);\n if (PREFETCH) {\n w = this.getShortPrefetch();\n } else if (!(this.opFlags & X86.OPFLAG.WRAP)) {\n w = this.getShort(this.regLIP);\n } else {\n /*\n * The WRAP flag must have been set by checkIP(2), so we also know that we're dealing with\n * a 16-bit read, which allows us to make some simplifications here.\n */\n w = this.getByte(this.regLIP) | (this.getByte(newLIP - 1) << 8);\n this.opFlags &= ~X86.OPFLAG.WRAP;\n }\n if (BACKTRACK) {\n this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMem0);\n this.bus.updateBackTrackCode(this.regLIP + 1, this.backTrack.btiMem1);\n }\n this.regLIP = newLIP;\n return w;\n }\n\n /**\n * getIPAddr()\n *\n * @this {CPUX86}\n * @return {number} word at the current IP; IP advanced by 2 or 4, depending on address size\n */\n getIPAddr()\n {\n var w;\n var newLIP = this.checkIP(this.sizeAddr);\n if (PREFETCH) {\n w = this.getAddr();\n } else if (!(this.opFlags & X86.OPFLAG.WRAP)) {\n w = this.getAddr(this.regLIP);\n } else {\n /*\n * The WRAP flag must have been set by checkIP(), so we also know that we're dealing with\n * a 16-bit read, which allows us to make some simplifications here.\n */\n w = this.getByte(this.regLIP) | (this.getByte(newLIP - 1) << 8);\n this.opFlags &= ~X86.OPFLAG.WRAP;\n }\n if (BACKTRACK) {\n this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMem0);\n this.bus.updateBackTrackCode(this.regLIP + 1, this.backTrack.btiMem1);\n }\n this.regLIP = newLIP;\n return w;\n }\n\n /**\n * getIPWord()\n *\n * @this {CPUX86}\n * @return {number} word at the current IP; IP advanced by 2 or 4, depending on operand size\n */\n getIPWord()\n {\n var w;\n var newLIP = this.checkIP(this.sizeData);\n if (PREFETCH) {\n w = this.getWordPrefetch();\n } else if (!(this.opFlags & X86.OPFLAG.WRAP)) {\n w = this.getWord(this.regLIP);\n } else {\n /*\n * The WRAP flag must have been set by checkIP(), so we also know that we're dealing with\n * a 16-bit read, which allows us to make some simplifications here.\n */\n w = this.getByte(this.regLIP) | (this.getByte(newLIP - 1) << 8);\n this.opFlags &= ~X86.OPFLAG.WRAP;\n }\n if (BACKTRACK) {\n this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMem0);\n this.bus.updateBackTrackCode(this.regLIP + 1, this.backTrack.btiMem1);\n }\n this.regLIP = newLIP;\n return w;\n }\n\n /**\n * getIPDisp()\n *\n * @this {CPUX86}\n * @return {number} sign-extended (32-bit) value from the byte at the current IP; IP advanced by 1\n */\n getIPDisp()\n {\n var newLIP = this.checkIP(1);\n var w = ((PREFETCH? this.getBytePrefetch() : this.getByte(this.regLIP)) << 24) >> 24;\n if (BACKTRACK) this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMem0);\n this.regLIP = newLIP;\n return w;\n }\n\n /**\n * peekIPByte()\n *\n * @this {CPUX86}\n * @return {number} byte at the current IP\n */\n peekIPByte()\n {\n return (PREFETCH? this.getBytePrefetch() : this.getByte(this.regLIP));\n }\n\n /**\n * popWord()\n *\n * @this {CPUX86}\n * @return {number} word popped from the current SP; SP increased by 2 or 4\n */\n popWord()\n {\n var data = this.getWord(this.regLSP);\n var width = I386? this.sizeData : 2;\n this.regLSP = (this.regLSP + width)|0;\n \n var delta = this.regLSPLimit - (this.regLSP >>> 0);\n if (delta < 0) {\n /*\n * There's no such thing as an SS fault on the 8086/8088, and in fact, we have to support the\n * operation even when the address straddles the wrap boundary; other emulators tend to barf on\n * a wrap, usually because they're running in V86 mode instead of real mode.\n */\n if (this.model <= X86.MODEL_8088) {\n this.setSP((this.regLSP - this.segSS.base) & this.segSS.maskAddr);\n if (delta < -1) {\n data = (data & 0xff) | (this.getByte(this.regLSP - 1) << 8);\n }\n }\n else {\n /*\n * I'm assuming that, on newer processors, when the stack segment limit is set to the maximum,\n * it's OK for the stack to wrap, unless the new address is straddling the wrap boundary (ie, when\n * delta is < -1).\n *\n * NOTE: This combines the old 8088 address-wrap check with the new segment-limit check, even though\n * the correct time to do the latter is immediately BEFORE the fetch, not AFTER.\n */\n if (delta < -1) {\n X86.helpFault.call(this, X86.EXCEPTION.SS_FAULT, 0);\n }\n else if (!this.segSS.fExpDown && this.segSS.limit == this.segSS.maskAddr || this.segSS.fExpDown && !this.segSS.limit) {\n this.setSP((this.regLSP - this.segSS.base) & this.segSS.maskAddr);\n }\n }\n }\n return data;\n }\n\n /**\n * pushWord(w)\n *\n * NOTE: pushWord() used to do a simplified version of pushData(), and while that might have made the emulator\n * slightly faster, it was woefully duplicative. Let's trust the combination of the Closure Compiler and the\n * JavaScript engines to automatically inline instead.\n *\n * @this {CPUX86}\n * @param {number} w is the word (16-bit) value to push at current SP; SP decreased by 2 or 4\n */\n pushWord(w)\n {\n this.pushData(w, I386? this.sizeData : 2);\n }\n\n /**\n * pushData(data, width, size)\n *\n * The size parameter serves two very limited purposes: 1) the ability to push data according to a previous\n * operand size, and 2) the ability to write fewer bytes than the width if necessary.\n *\n * The former occurs when a 32-bit code segment performs a 16:32 call to a 16-bit code segment; after the\n * new 16-bit code segment is loaded (and possible stack switch occurs), the return address (both segment\n * and offset) must still be pushed as 32-bit values.\n *\n * The latter occurs with segment register pushes. When a 32-bit operand size is in effect (ie, width is 4),\n * only the low 16 bits should be written (size must be 2).\n *\n * For all other kinds of pushes, width and size are impliedly the same.\n *\n * @this {CPUX86}\n * @param {number} data is the data to push at current SP; SP decreased by size\n * @param {number} width is the width of the data to push, in bytes (must be either 2 or 4)\n * @param {number} [size] is the size of the data to push, in bytes (must be 1, 2, or 4, and <= width)\n */\n pushData(data, width, size = width)\n {\n\n\n var regLSP = (this.regLSP - width)|0;\n \n var delta = (regLSP >>> 0) - this.regLSPLimitLow;\n if (delta < 0) {\n /*\n * There's no such thing as an SS fault on the 8086/8088, and in fact, we have to support the\n * operation even when the address straddles the wrap boundary (ie, when delta is -1); other\n * emulators tend to barf on a wrap, usually because they're running in V86 mode instead of real mode.\n */\n if (this.model <= X86.MODEL_8088) {\n if (delta == -1) {\n this.setByte(regLSP + 1, data >> 8);\n this.setSP((regLSP - this.segSS.base) & this.segSS.maskAddr);\n this.setByte(this.regLSP, data);\n return;\n }\n\n }\n /*\n * I'm assuming that, on newer processors, when the stack segment limit is set to the maximum,\n * it's OK for the stack to wrap, unless the new address is straddling the wrap boundary (ie, when\n * delta is < 0 and > -width).\n */\n if (!this.segSS.fExpDown && this.segSS.limit == this.segSS.maskAddr || this.segSS.fExpDown && !this.segSS.limit) {\n if (delta > -width) {\n X86.helpFault.call(this, X86.EXCEPTION.SS_FAULT, 0);\n return;\n }\n this.setSP((regLSP - this.segSS.base) & this.segSS.maskAddr);\n regLSP = this.regLSP;\n } else {\n X86.helpFault.call(this, X86.EXCEPTION.SS_FAULT, 0);\n return;\n }\n }\n\n switch(size) {\n case 1:\n this.setByte(regLSP, data);\n break;\n case 2:\n this.setShort(regLSP, data);\n break;\n case 4:\n this.setLong(regLSP, data);\n break;\n default:\n\n break;\n }\n\n /*\n * We update this.regLSP at the end to make life simpler for opcode handlers that perform only one\n * pushWord() operation, relieving them from having to snapshot this.regLSP into this.opLSP needlessly.\n */\n this.regLSP = regLSP;\n }\n\n /**\n * checkINTR()\n *\n * This must only be called when intFlags (containing the simulated INTFLAG.INTR signal) is known to be set.\n * Note that it's perfectly possible that between the time updateINTR(true) was called and we request the\n * interrupt vector number below, the interrupt could have been cleared or masked, in which case getIRRVector()\n * will return -1 and we'll simply clear INTFLAG.INTR.\n *\n * intFlags has been overloaded with the INTFLAG.TRAP bit as well, since the acknowledgment of h/w interrupts\n * and the Trap flag are similar; they must both honor the NOINTR suppression flag, and stepCPU() shouldn't\n * have to check multiple variables when deciding whether to simulate an interrupt.\n *\n * This function also includes a check for the new async INTFLAG.DMA flag, which is triggered by a ChipSet call\n * to setDMA(). This DMA flag actually has nothing to do with interrupts; it's simply an expedient way to\n * piggy-back on the CPU's execution logic, to help drive async DMA requests.\n *\n * Originally, DMA requests (eg, FDC or HDC I/O operations) were all handled synchronously, since no actual\n * I/O was required to satisfy the request; from the CPU's perspective, this meant DMA operations were virtually\n * instantaneous. However, with the introduction of remote disk connections, some actual I/O may now be required;\n * in practice, this means that the FIRST byte requested as part of a DMA operation may require a callback to\n * finish, while all remaining bytes will be retrieved during subsequent checkINTR() calls -- unless of course\n * additional remote I/O operations are required to complete the DMA operation.\n *\n * As a result, the CPU will run slightly slower while an async DMA request is in progress, but the slowdown\n * should be negligible. One downside is that this slowdown will be in effect for the entire duration of the\n * I/O (ie, even while we're waiting for the remote I/O to finish), so the ChipSet component should avoid\n * calling setDMA() whenever possible.\n *\n * TODO: While comparing SYMDEB tracing in both PCx86 and VMware, I noticed that after single-stepping ANY\n * segment-load instruction, SYMDEB would get control immediately after that instruction in VMware, whereas\n * I delay acknowledgment of the Trap flag until the *following* instruction, so in PCx86, SYMDEB doesn't get\n * control until the following instruction. I think PCx86 behavior is correct, at least for SS.\n *\n * ERRATA: Early revisions of the 8086/8088 failed to suppress hardware interrupts (and possibly also Trap\n * acknowledgements) after an SS load, but Intel corrected the problem at some point; however, I don't know when\n * that change was made or which IBM PC models may have been affected, if any. TODO: More research required.\n *\n * WARNING: There is also a priority consideration here. On the 8086/8088, hardware interrupts have higher\n * priority than Trap interrupts (which is why the code below is written the way it is). A potentially\n * undesirable side-effect is that a hardware interrupt handler could end up being single-stepped if an\n * external interrupt occurs immediately after the Trap flag is set. This is why some 8086 debuggers temporarily\n * mask all hardware interrupts during a single-step operation (although that doesn't help with NMIs generated\n * by a coprocessor). As of the 80286, those priorities were inverted, giving the Trap interrupt higher priority\n * than external interrupts.\n *\n * TODO: Determine the priorities for the 80186.\n *\n * @this {CPUX86}\n * @return {boolean} true if h/w interrupt (or trap) has just been acknowledged, false if not\n */\n checkINTR()\n {\n // DEBUG:\n\n if (!(this.opFlags & X86.OPFLAG.NOINTR)) {\n /*\n * As discussed above, the 8086/8088 give hardware interrupts higher priority than the TRAP interrupt,\n * whereas the 80286 and up give TRAPs higher priority.\n */\n var iPriority = (this.model < X86.MODEL_80286? 0 : 1);\n for (var cPriorities = 0; cPriorities < 2; cPriorities++) {\n switch(iPriority) {\n case 0:\n if ((this.intFlags & X86.INTFLAG.INTR) && (this.regPS & X86.PS.IF)) {\n var nIDT = this.chipset.getIRRVector();\n if (nIDT >= -1) {\n this.intFlags &= ~X86.INTFLAG.INTR;\n if (nIDT >= 0) {\n this.intFlags &= ~X86.INTFLAG.HALT;\n X86.helpInterrupt.call(this, nIDT);\n return true;\n }\n }\n }\n break;\n case 1:\n if ((this.intFlags & X86.INTFLAG.TRAP)) {\n this.intFlags &= ~X86.INTFLAG.TRAP;\n if (I386 && this.model >= X86.MODEL_80386) this.regDR[6] |= X86.DR6.BS;\n X86.helpInterrupt.call(this, X86.EXCEPTION.DB_EXC);\n return true;\n }\n break;\n }\n iPriority = 1 - iPriority;\n }\n }\n /*\n * As long as the ChipSet component isn't calling setDMA(), we don't need to test INTFLAG.DMA...\n *\n if (this.intFlags & X86.INTFLAG.DMA) {\n if (!this.chipset.checkDMA()) {\n this.intFlags &= ~X86.INTFLAG.DMA;\n }\n }\n */\n return false;\n }\n\n /**\n * updateINTR(fRaise)\n *\n * This is called by the ChipSet component whenever a h/w interrupt needs to be simulated.\n * This is how the PIC component simulates raising the INTFLAG.INTR signal. We will honor the request\n * only if we have a reference back to the ChipSet component. The CPU will then \"respond\" by calling\n * checkINTR() and request the corresponding interrupt vector from the ChipSet.\n *\n * @this {CPUX86}\n * @param {boolean} fRaise is true to raise INTFLAG.INTR, false to lower\n */\n updateINTR(fRaise)\n {\n if (this.chipset) {\n if (fRaise) {\n this.intFlags |= X86.INTFLAG.INTR;\n } else {\n this.intFlags &= ~X86.INTFLAG.INTR;\n }\n }\n }\n\n /**\n * delayINTR()\n *\n * This is called by the ChipSet component whenever the IMR register is being unmasked, to avoid\n * interrupts being simulated too quickly. This works around a problem in the ROM BIOS \"KBD_RESET\"\n * (F000:E688) function, which is called with interrupts enabled by the \"TST8\" (F000:E30D) code.\n *\n * \"KBD_RESET\" appears to be written with the assumption that CLI is in effect, because it issues an\n * STI immediately after unmasking the keyboard IRQ. And normally, the STI would delay INTFLAG.INTR\n * long enough to allow AH to be set to 0. But if interrupts are already enabled, an interrupt could\n * theoretically occur before the STI. And since AH isn't initialized until after the STI, such an\n * interrupt would be missed.\n *\n * I'm assuming this never happens in practice because the PIC isn't that fast. But for us to\n * guarantee that, we need to provide this function to the ChipSet component.\n *\n * @this {CPUX86}\n */\n delayINTR()\n {\n this.opFlags |= X86.OPFLAG.NOINTR;\n }\n\n /**\n * updateReg(sReg, nValue)\n *\n * This function helps updateStatus() by massaging the register names and values according to\n * CPU type before passing the call to displayValue(); in the \"old days\", updateStatus() called\n * displayValue() directly (although then it was called displayReg()).\n *\n * @this {CPUX86}\n * @param {string} sReg\n * @param {number} nValue\n */\n updateReg(sReg, nValue)\n {\n var cch = 4;\n if (sReg.length == 1) {\n cch = 1;\n nValue = nValue? 1 : 0;\n }\n if (this.model < 80386) {\n if (sReg.length > 2) {\n sReg = sReg.substr(1, 2);\n }\n } else {\n if (sReg == \"PS\" || sReg.length > 2) {\n cch = 8;\n }\n }\n this.displayValue(sReg, nValue, cch);\n }\n\n /**\n * updateStatus(fForce)\n *\n * This provides periodic Control Panel updates (eg, a few times per second; see Computer.UPDATES_PER_SECOND).\n * this is where we take care of any DOM updates (eg, register values) while the CPU is running.\n *\n * @this {CPUX86}\n * @param {boolean} [fForce] (true will display registers even if the CPU is running and \"live\" registers are not enabled)\n */\n updateStatus(fForce)\n {\n if (this.cLiveRegs) {\n if (fForce || !this.flags.running || this.flags.displayLiveRegs) {\n this.updateReg(\"EAX\", this.regEAX);\n this.updateReg(\"EBX\", this.regEBX);\n this.updateReg(\"ECX\", this.regECX);\n this.updateReg(\"EDX\", this.regEDX);\n this.updateReg(\"ESP\", this.getSP());\n this.updateReg(\"EBP\", this.regEBP);\n this.updateReg(\"ESI\", this.regESI);\n this.updateReg(\"EDI\", this.regEDI);\n this.updateReg(\"CS\", this.getCS());\n this.updateReg(\"DS\", this.getDS());\n this.updateReg(\"SS\", this.getSS());\n this.updateReg(\"ES\", this.getES());\n this.updateReg(\"EIP\", this.getIP());\n var regPS = this.getPS();\n this.updateReg(\"PS\", regPS);\n this.updateReg(\"V\", (regPS & X86.PS.OF));\n this.updateReg(\"D\", (regPS & X86.PS.DF));\n this.updateReg(\"I\", (regPS & X86.PS.IF));\n this.updateReg(\"T\", (regPS & X86.PS.TF));\n this.updateReg(\"S\", (regPS & X86.PS.SF));\n this.updateReg(\"Z\", (regPS & X86.PS.ZF));\n this.updateReg(\"A\", (regPS & X86.PS.AF));\n this.updateReg(\"P\", (regPS & X86.PS.PF));\n this.updateReg(\"C\", (regPS & X86.PS.CF));\n if (this.model == X86.MODEL_80386) {\n this.updateReg(\"FS\", this.getFS());\n this.updateReg(\"GS\", this.getGS());\n this.updateReg(\"CR0\", this.regCR0);\n this.updateReg(\"CR2\", this.regCR2);\n this.updateReg(\"CR3\", this.regCR3);\n }\n }\n }\n\n var controlSpeed = this.bindings[\"speed\"];\n if (controlSpeed) controlSpeed.textContent = this.getSpeedCurrent();\n }\n\n /**\n * stepCPU(nMinCycles)\n *\n * NOTE: Single-stepping should not be confused with the Trap flag; single-stepping is a Debugger\n * operation that's completely independent of Trap status. The CPU can go in and out of Trap mode,\n * in and out of h/w interrupt service routines (ISRs), etc, but from the Debugger's perspective,\n * they're all one continuous stream of instructions that can be stepped or run at will. Moreover,\n * stepping vs. running should never change the behavior of the simulation.\n *\n * Similarly, the Debugger's execution breakpoints have no involvement with the x86 breakpoint instruction\n * (0xCC); the Debugger monitors changes to the regLIP register to implement its own execution breakpoints.\n *\n * As a result, the Debugger's complete independence means you can run other 8086/8088 debuggers\n * (eg, DEBUG) inside the simulation without interference; you can even \"debug\" them with the Debugger.\n *\n * @this {CPUX86}\n * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored)\n * @return {number} of cycles executed; 0 indicates a pre-execution condition (ie, an execution breakpoint\n * was hit), -1 indicates a post-execution condition (eg, a read or write breakpoint was hit), and a positive\n * number indicates successful completion of that many cycles (which should always be >= nMinCycles).\n */\n stepCPU(nMinCycles)\n {\n /*\n * The Debugger uses fComplete to determine if the instruction completed (true) or was interrupted\n * by a breakpoint or some other exceptional condition (false). NOTE: this does NOT include JavaScript\n * exceptions, which stepCPU() expects the caller to catch using its own exception handler.\n *\n * The CPU relies on the use of stopCPU() rather than fComplete, because the CPU never single-steps\n * (ie, nMinCycles is always some large number), whereas the Debugger does. And conversely, when the\n * Debugger is single-stepping (even when performing multiple single-steps), fRunning is never set,\n * so stopCPU() would have no effect as far as the Debugger is concerned.\n */\n this.flags.complete = true;\n\n /*\n * fDebugCheck is true if we need to \"check\" every instruction with the Debugger.\n */\n var fDebugCheck = this.flags.debugCheck = (DEBUGGER && this.dbg && this.dbg.checksEnabled());\n\n /*\n * nDebugState is checked only when fDebugCheck is true, and its sole purpose is to tell the first call\n * to checkInstruction() that it can skip breakpoint checks, and that will be true ONLY when fStarting is\n * true OR nMinCycles is zero (the latter means the Debugger is single-stepping).\n *\n * Once we snap fStarting, we clear it, because technically, we've moved beyond \"starting\" and have\n * officially \"started\" now.\n */\n var nDebugState = (!nMinCycles)? -1 : (this.flags.starting? 0 : 1);\n this.flags.starting = false;\n\n /*\n * We move the minimum cycle count to nStepCycles (the number of cycles left to step), so that other\n * functions have the ability to force that number to zero (eg, stopCPU()), and thus we don't have to check\n * any other criteria to determine whether we should continue stepping or not.\n */\n this.nBurstCycles = this.nStepCycles = nMinCycles;\n\n /*\n * NOTE: Even though runCPU() calls updateAllTimers(), we need an additional call here if we're being\n * called from the Debugger, so that any single-stepping will update the timers as well.\n */\n if (this.chipset && !nMinCycles) this.chipset.updateAllTimers();\n\n /*\n * Let's also suppress h/w interrupts whenever the Debugger is single-stepping an instruction; I'm loathe\n * to allow Debugger interactions to affect the behavior of the virtual machine in ANY way, but I'm making\n * this small concession to avoid the occasional and sometimes unexpected Debugger command that ends up\n * stepping into a hardware interrupt service routine (ISR).\n *\n * Note that this is similar to the problem discussed in checkINTR() regarding the priority of external h/w\n * interrupts vs. Trap interrupts, but they require different solutions, because our Debugger operates\n * independently of the CPU.\n *\n * One exception I make here is when you've asked the Debugger to display PIC messages, the idea being that\n * if you're watching the PIC that closely, then you want to hardware interrupts to occur regardless.\n */\n if (!nMinCycles && !this.messageEnabled(Messages.PIC)) this.opFlags |= X86.OPFLAG.NOINTR;\n\n do {\n var opPrefixes = this.opFlags & X86.OPFLAG_PREFIXES;\n if (opPrefixes) {\n this.opPrefixes |= opPrefixes;\n } else {\n /*\n * opLIP is used, among other things, to help string instructions rewind to the first prefix\n * byte whenever the instruction needs to be repeated. Repeating string instructions in this\n * manner (essentially restarting them) is a bit heavy-handed, but ultimately it's more compatible,\n * because it allows hardware interrupts (as well as Trap processing and Debugger single-stepping)\n * to occur at any point during the string operation, without any additional effort.\n *\n * NOTE: The way we restart string instructions actually fixes an 8086/8088 flaw, because string\n * instructions with multiple prefixes (eg, a REP and a segment override) would not be restarted\n * properly following a hardware interrupt. The recommended workarounds were to either turn off\n * interrupts or to follow the string instruction with a LOOPNZ back to the first prefix byte.\n * To emulate the flawed behavior, turn on BUGS_8086.\n */\n this.opLIP = this.regLIP;\n this.segData = this.segDS;\n this.segStack = this.segSS;\n this.regEA = this.regEAWrite = X86.ADDR_INVALID;\n\n if (I386 && (this.opPrefixes & (X86.OPFLAG.ADDRSIZE | X86.OPFLAG.DATASIZE))) {\n this.resetSizes();\n }\n\n this.opPrefixes = this.opFlags & X86.OPFLAG.REPEAT;\n\n if (this.intFlags) {\n if (this.checkINTR()) {\n if (!nMinCycles) {\n\n if (DEBUGGER) {\n this.println(\"interrupt dispatched\");\n this.opFlags = 0;\n break;\n }\n }\n }\n if (this.intFlags & X86.INTFLAG.HALT) {\n /*\n * As discussed in opHLT(), the CPU is never REALLY halted by a HLT instruction, because the\n * entire machine relies on the steady advance of the overall cycle count, to ensure that timer\n * updates, video updates, etc, all continue to occur at the expected rates.\n * \n * So opHLT() sets X86.INTFLAG.HALT, signalling that we should not execute any more instructions\n * until checkINTR() detects a hardware interrupt and clears X86.INTFLAG.HALT. \n * \n * Ideally, we would also end the current burst; ie:\n *\n * this.nStepCycles = 0;\n * this.opFlags = 0;\n * break;\n * \n * and save the browser a bunch of work, which would translate into power savings for the host\n * operating system, just as HLT was intended to do for the guest operating system. Unfortunately,\n * that screws up up our dynamic speed recalculations, because it makes it appear that a single\n * instruction (HLT) performed the work of many.\n *\n * We could certainly add more cycle bookkeeping to compensate for HLT's lack of work, but for now,\n * it's simpler to re-execute the HLT as long as X86.INTFLAG.HALT is set. \n */\n X86.opHLT.call(this);\n continue;\n }\n }\n }\n\n if (DEBUGGER && fDebugCheck) {\n if (this.dbg.checkInstruction(this.regLIP, nDebugState)) {\n this.stopCPU();\n break;\n }\n nDebugState = 1;\n }\n\n this.opFlags = 0;\n\n /*\n if (DEBUG || PREFETCH) {\n this.nBusCycles = 0;\n this.nSnapCycles = this.nStepCycles;\n }\n */\n\n this.aOps[this.getIPByte()].call(this);\n\n /*\n if (PREFETCH) {\n var nSpareCycles = (this.nSnapCycles - this.nStepCycles) - this.nBusCycles;\n if (nSpareCycles >= 4) {\n this.fillPrefetch(nSpareCycles >> 2); // for every 4 spare cycles, fetch 1 instruction byte\n }\n }\n */\n\n /*\n if (DEBUG) {\n //\n // Make sure that every instruction is assessing a cycle cost, and that the cost is a net positive.\n //\n if (this.flags.complete && this.nStepCycles >= this.nSnapCycles && !(this.opFlags & X86.OPFLAG_PREFIXES)) {\n this.println(\"cycle miscount: \" + (this.nSnapCycles - this.nStepCycles));\n this.setIP(this.opLIP - this.segCS.base);\n this.stopCPU();\n break;\n }\n }\n */\n\n } while (this.nStepCycles > 0);\n\n return (this.flags.complete? this.nBurstCycles - this.nStepCycles : (this.flags.complete === undefined? 0 : -1));\n }\n\n /**\n * setAddrSize(size)\n *\n * This is used by opcodes that require a particular ADDRESS size, which we enforce by\n * internally simulating an ADDRESS size override, if needed.\n *\n * @this {CPUX86}\n * @param {number} size (2 for 2-byte/16-bit operands, or 4 for 4-byte/32-bit operands)\n *\n setAddrSize(size)\n {\n if (this.sizeAddr != size) {\n this.opPrefixes |= X86.OPFLAG.ADDRSIZE;\n this.sizeAddr = size;\n this.maskAddr = (size == 2? 0xffff : (0xffffffff|0));\n this.updateAddrSize();\n }\n }\n */\n\n /**\n * getIPLong()\n *\n * @this {CPUX86}\n * @return {number} long at the current IP; IP advanced by 4\n *\n getIPLong()\n {\n var newLIP = this.checkIP(4);\n var l = (PREFETCH? this.getLongPrefetch() : this.getLong(this.regLIP));\n if (BACKTRACK) {\n this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMem0);\n this.bus.updateBackTrackCode(this.regLIP + 1, this.backTrack.btiMem1);\n this.bus.updateBackTrackCode(this.regLIP + 2, this.backTrack.btiMem2);\n this.bus.updateBackTrackCode(this.regLIP + 3, this.backTrack.btiMem3);\n }\n this.regLIP = newLIP;\n return l;\n }\n */\n\n /**\n * setDMA(fActive)\n *\n * This is called by the ChipSet component to update DMA status.\n *\n * @this {CPUX86}\n * @param {boolean} fActive is true to set INTFLAG.DMA, false to clear\n *\n setDMA(fActive)\n {\n if (this.chipset) {\n if (fActive) {\n this.intFlags |= X86.INTFLAG.DMA;\n } else {\n this.intFlags &= ~X86.INTFLAG.DMA;\n }\n }\n }\n */\n\n /**\n * CPUX86.init()\n *\n * This function operates on every HTML element of class \"cpu\", extracting the\n * JSON-encoded parameters for the CPUX86 constructor from the element's \"data-value\"\n * attribute, invoking the constructor (which in turn invokes the CPU constructor)\n * to create a CPUX86 component, and then binding any associated HTML controls to the\n * new component.\n */\n static init()\n {\n var aeCPUs = Component.getElementsByClass(document, PCX86.APPCLASS, \"cpu\");\n for (var iCPU = 0; iCPU < aeCPUs.length; iCPU++) {\n var eCPU = aeCPUs[iCPU];\n var parmsCPU = Component.getComponentParms(eCPU);\n var cpu = new CPUX86(parmsCPU);\n Component.bindComponentControls(cpu, eCPU, PCX86.APPCLASS);\n }\n }\n}\n\nif (PREFETCH) {\n /*\n * NOTE: CPUX86.PFINFO.LENGTH must be set to a power of two, so that LENGTH - 1 will form a mask\n * (IP_MASK) we can use to create a sliding prefetch window of LENGTH bytes. We also zero the low\n * 2 bits of IP_MASK so that the sliding window always starts on a 32-bit (long) boundary. Finally,\n * instead breaking breaking all the longs we prefetch into bytes, we simply store the longs as-is\n * into every 4th element of the queue (the queue is sparse array).\n */\n CPUX86.PFINFO = {\n LENGTH: 16 // 16 generates a 16-byte prefetch queue consisting of 4 32-bit entries\n };\n CPUX86.PFINFO.IP_MASK = ((CPUX86.PFINFO.LENGTH - 1) & ~0x3);\n}\n\nCPUX86.PAGEBLOCKS_CACHE = 512; // TODO: This seems adequate for 4Mb of RAM, but it should be dynamically reconfigured\n\n/*\n * Initialize every CPU module on the page\n */\nWeb.onInit(CPUX86.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/fpux86.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * Operand Type Reference\n *\n * ST(0), ST stack top; the register currently at the top of the stack\n * ST(i) register in the stack i (0<=i<=7) stack elements from the top\n * SR (short-real) short real (32 bits) number in memory; exponent bias is 127 (0x7f)\n * LR (long-real) long real (64 bits) number in memory; exponent bias is 1023 (0x3ff)\n * TR (temp-real) temporary real (80 bits) number in memory; exponent bias is 16383 (0x3fff)\n * PD (packed-decimal) packed decimal integer (18 digits, 10 bytes) in memory\n * WI (word-integer) word binary integer (16 bits) in memory\n * SI (short-integer) short binary integer (32 bits) in memory\n * LI (long-integer) long binary integer (64 bits) in memory\n * NN (nn-bytes) memory area nn bytes long\n *\n * FPU Coprocessor Trivia\n *\n * Microsoft C 4.00 libraries executed software interrupts in the range 0x34-0x3B immediately after\n * FPU operations, to assist with floating-point emulation when no coprocessor was present, since\n * processors prior to the 80286 had no mechanism for generating a fault when an unsupported FPU\n * instruction was executed.\n *\n * In short, INT 0x34 through INT 0x3B was used after ESC opcodes 0xD8 through 0xDF, INT 0x3C was\n * used for FPU instructions containing a segment override, and INT 0x3D was used for FWAIT.\n *\n * A sample piece of code is available in x86ops.js, because it also highlights the Microsoft C 4.00\n * library's dependency on the 8086/8088 behavior of \"PUSH SP\" (see the opPUSHSP_8086() function).\n */\n\n/**\n * @class FPUX86\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass FPUX86 extends Component {\n /**\n * FPUX86(parmsFPU)\n *\n * The FPUX86 class uses the following (parmsFPU) properties:\n *\n * model: a number (eg, 8087) that should match one of the X86.FPU.MODEL values (default is 8087)\n * stepping: a string (eg, \"B1\") that should match one of the X86.FPU.STEPPING values (default is \"\")\n *\n * @this {FPUX86}\n * @param {Object} parmsFPU\n */\n constructor(parmsFPU)\n {\n super(\"FPU\", parmsFPU);\n\n this.model = parmsFPU['model'] || X86.FPU.MODEL_8087;\n\n /*\n * We take the 'stepping' value, convert it to a hex value, and then add that to the model to provide\n * a single value that's unique for any given CPU stepping. If no stepping is provided, then stepping\n * is equal to model.\n */\n var stepping = parmsFPU['stepping'];\n this.stepping = this.model + (stepping? Str.parseInt(stepping, 16) : 0);\n\n /*\n * Perform a one-time allocation of all floating-point registers.\n * NOTE: The FPU's internal registers are supposed to be 80-bit, but JavaScript gives us only 64-bit floats.\n */\n this.regStack = new Float64Array(8);\n this.intStack = new Int32Array(this.regStack.buffer);\n\n /*\n * Used for \"short-real\" (SR) 32-bit floating-point operations.\n */\n this.regTmpSR = new Float32Array(1);\n this.intTmpSR = new Int32Array(this.regTmpSR.buffer);\n\n /*\n * Used for \"long-real\" (LR) 64-bit floating-point operations. We also use intTmpLR as temporary storage\n * for all \"word-integer\" (WI or INT16), \"short-integer\" (SI or INT32) and \"long-integer\" (LI or INT64) values,\n * since it's just large enough to accommodate all three integer sizes.\n */\n this.regTmpLR = new Float64Array(1);\n this.intTmpLR = new Int32Array(this.regTmpLR.buffer);\n\n /*\n * Used for conversion to/from the 80-bit \"temp-real\" (TR) format; used as three 32-bit integers,\n * where [0] contains TR bits 0-31, [1] contains TR bits 32-63, and [2] contains TR bits 64-79; the\n * upper 16 bits of [2] are not used and should remain zero.\n */\n this.intTmpTR = new Array(3);\n\n /*\n * Initialize other (non-floating-point) coprocessor registers that resetFPU() doesn't touch,\n * such as the \"exception\" registers: regCodeSel, regCodeOff, regDataSel, regDataOff, and regOpcode.\n *\n * Note that regCodeSel and regDataSel are NEVER set in real-mode and are ALWAYS set in protected-mode,\n * so we set them to -1 in their \"unset\" state; if those values ever show up in an exception block,\n * something may have gone amiss (it's not impossible though, because if an exception occurs before any\n * memory operands have been used, regDataSel may still be \"unset\").\n *\n * NOTE: iStack is the low 3 bits of the bModRM byte, for instructions that have an explicit stack operand.\n */\n this.regCodeSel = this.regDataSel = -1;\n this.regCodeOff = this.regDataOff = this.regOpcode = this.iStack = 0;\n\n /*\n * Initialize special floating-point constants, as if they were internal read-only registers;\n * all other simple (non-special) constants are \"statically\" initialized below, as class constants.\n */\n this.regIndefinite = new Float64Array(1);\n this.intIndefinite = new Int32Array(this.regIndefinite.buffer);\n this.intIndefinite[0] = 0x00000000; this.intIndefinite[1] = 0xFFF8000;\n\n /*\n * Initialize all other coprocessor registers (control word, tag word, status word, etc) by resetting them.\n */\n this.resetFPU();\n /**\n * setEAFromSR()\n *\n * Stores the (32-bit) \"short-real\" value in the internal regTmpSR register to the address in regEA.\n *\n * @this {FPUX86}\n */\n this.setEAFromSR = FPUX86.prototype.setEAFromSI;\n /**\n * setEAFromLR()\n *\n * Stores the (64-bit) \"long-real\" value in the internal regTmpLR register to the address in regEA.\n *\n * @this {FPUX86}\n */\n this.setEAFromLR = FPUX86.prototype.setEAFromLI;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {FPUX86}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cpu = cpu;\n this.chipset = cmp.getMachineComponent(\"ChipSet\");\n this.setReady();\n }\n\n /**\n * clearBusy()\n *\n * The ChipSet calls us whenever an I/O operation that clears the coprocessor's \"busy\" state is performed.\n *\n * @this {FPUX86}\n */\n clearBusy()\n {\n /*\n * We're never \"busy\" as far as other components are concerned, because we perform all FPU operations\n * synchronously, so there's nothing to do here.\n */\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {FPUX86}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data || !this.restore) {\n this.resetFPU();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {FPUX86}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * save()\n *\n * This implements save support for the FPUX86 component.\n *\n * @this {FPUX86}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n var a = [], i = 0;\n a[i++] = this.regControl;\n a[i++] = this.getStatus();\n a[i++] = this.getTags();\n /*\n * Note that, unlike the FSAVE() and FRSTOR() operations, we save the registers in regStack in their physical\n * order (0-7) rather than their logical order (ST0-ST7). Moreover, FSAVE() and FRSTOR() use the \"temp-real\" (TR)\n * format, whereas we use the current native format -- which, sadly, is only a 64-bit \"long-real\" (LR) format.\n */\n for (var iReg = 0; iReg < this.regStack.length; iReg++) {\n a[i++] = this.regStack[iReg];\n }\n state.set(0, a);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the FPUX86 component.\n *\n * @this {FPUX86}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var a = data[0], i = 0;\n this.setControl(a[i++]);\n this.setStatus(a[i++]);\n this.setTags(a[i++]);\n for (var iReg = 0; iReg < this.regStack.length; iReg++) {\n this.regStack[iReg] = a[i++];\n }\n return true;\n }\n\n /**\n * resetFPU()\n *\n * Aside from calling this internally (eg, during initialization and FINIT operations), the ChipSet may also call\n * us whenever an I/O operation that resets the coprocessor is performed. Only 80487 coprocessors and higher will\n * also clear the \"exception\" registers, but the 80487 is currently beyond my planned level of support.\n *\n * TODO: Add support for X86.FPU.CONTROL.PC (Precision Control) and X86.FPU.CONTROL.IC (Infinity Control)\n *\n * @this {FPUX86}\n */\n resetFPU()\n {\n this.regUsed = 0; // bits 0-7 are set as regs 0-7 are used\n this.regControl = X86.FPU.CONTROL.INIT;\n this.regStatus = 0; // contains all status register bits EXCEPT for ST\n this.iST = 0; // the ST bits for regStatus are actually stored here\n if (DEBUG) {\n /*\n * All the registers were tagged \"unused\" above, which is all that would normally happen, but debugging is\n * a little easier if we zero all the registers as well.\n */\n for (var iReg = 0; iReg < this.regStack.length; iReg++) {\n this.regStack[iReg] = 0.0;\n }\n }\n if (this.chipset) this.chipset.clearFPUInterrupt();\n }\n\n /**\n * isModel(model)\n *\n * If the current model is equal to the specified model, then it's assumed the current operation\n * is supported, and we return true.\n *\n * @this {FPUX86}\n * @param {number} model\n * @return {boolean}\n */\n isModel(model)\n {\n return this.model == model;\n }\n\n /**\n * isAtLeastModel(model)\n *\n * If the current model is greater than or equal to the specified model, then it's assumed that the\n * current operation is supported, and we return true.\n *\n * @this {FPUX86}\n * @param {number} model\n * @return {boolean}\n */\n isAtLeastModel(model)\n {\n return this.model >= model;\n }\n\n /**\n * opStop(fError)\n *\n * Place this inside any opcode handler to stop the CPU from running the current instruction; eg:\n *\n * if (this.opStop()) return;\n *\n * You can still use the Debugger to single-step over the instruction; opStop() will return false in that case.\n *\n * @this {FPUX86}\n * @param {boolean} [fError]\n * @return {boolean} (true if there was an error or the CPU was running, false if not)\n */\n opStop(fError)\n {\n if (DEBUG) {\n var cpu = this.cpu;\n if (fError || cpu.isRunning()) {\n cpu.setIP(cpu.opLIP - cpu.segCS.base);\n cpu.stopCPU();\n return true;\n }\n }\n return false;\n }\n\n /**\n * opNone()\n *\n * Used for any coprocessor opcode that has no known operation for the given model.\n *\n * @this {FPUX86}\n */\n opNone()\n {\n if (DEBUG) this.println(this.idComponent + \".opNone(\" + Str.toHexByte(this.cpu.bOpcode) + \",\" + Str.toHexByte(this.cpu.bModRM) + \")\");\n this.opStop(true);\n }\n\n /**\n * opObsolete()\n *\n * Used for any coprocessor opcodes that are redundant and potentially obsolete.\n *\n * @this {FPUX86}\n */\n opObsolete()\n {\n if (DEBUG) this.println(this.idComponent + \".opObsolete(\" + Str.toHexByte(this.cpu.bOpcode) + \",\" + Str.toHexByte(this.cpu.bModRM) + \")\");\n this.opStop(true);\n }\n\n /**\n * opUnimplemented()\n *\n * Used for any coprocessor opcode that DOES have a known operation, we just haven't implemented it yet.\n *\n * @this {FPUX86}\n */\n opUnimplemented()\n {\n if (DEBUG) this.println(this.idComponent + \".opUnimplemented(\" + Str.toHexByte(this.cpu.bOpcode) + \",\" + Str.toHexByte(this.cpu.bModRM) + \")\");\n this.opStop(true);\n }\n\n /**\n * checkException()\n *\n * @this {FPUX86}\n * @return {boolean} (true if unmasked exception exists, false if not)\n */\n checkException()\n {\n this.regStatus &= ~X86.FPU.STATUS.ES;\n /*\n * NOTE: The \"Stack Fault\" (SF) status bit wasn't introduced until the 80387, so it triggers the pre-existing\n * \"Invalid Operation\" (IE) exception; there is no corresponding \"Stack Fault\" (SE) exception, and the matching\n * control bit is still reserved. Consequently, X86.FPU.CONTROL.EXC is a *subset* of X86.FPU.STATUS.EXC (0x3F\n * instead of 0x7F).\n *\n * However, we shouldn't have to do anything special when SF is set, because any setException() call that sets\n * SF should ALSO set IE.\n */\n if (this.regStatus & (~this.regControl & X86.FPU.CONTROL.EXC)) {\n this.regStatus |= X86.FPU.STATUS.ES; // set ES whenever one or more unmasked EXC bits are set\n }\n if ((this.regStatus & X86.FPU.STATUS.ES) && !(this.regControl & X86.FPU.CONTROL.IEM)) {\n this.chipset.setFPUInterrupt();\n return true;\n }\n this.chipset.clearFPUInterrupt();\n return false;\n }\n\n /**\n * setException(n)\n *\n * Sets one or more of the FPU.STATUS.ECX bits; ie:\n *\n * IE (0x0001 bit 0: Invalid Operation)\n * DE (0x0002 bit 1: Denormalized Operand)\n * ZE (0x0004 bit 2: Zero Divide)\n * OE (0x0008 bit 3: Overflow)\n * UE (0x0010 bit 4: Underflow)\n * PE (0x0020 bit 5: Precision)\n * SF (0x0040 bit 6: Stack Fault; 80387 and later)\n *\n * Also, as noted in checkException(), any time you set the SF bit, you should also set the IE bit, because\n * Stack Fault is a subset of Invalid Operation. TODO: We should include a test for that in the assertion below.\n *\n * @this {FPUX86}\n * @param {number} n (one or more of the above error status bits)\n * @return {boolean} (true if unmasked exception exists, false if not)\n */\n setException(n)\n {\n if (DEBUG) this.println(this.idComponent + \".setException(\" + Str.toHexWord(n) + \")\");\n\n if (!this.isAtLeastModel(X86.FPU.MODEL_80387)) {\n n &= ~X86.FPU.STATUS.SF; // the SF bit didn't exist on pre-80387 coprocessors\n }\n\n this.regStatus |= n;\n return this.checkException();\n }\n\n /**\n * getControl()\n *\n * @this {FPUX86}\n * @return {number}\n */\n getControl()\n {\n return this.regControl;\n }\n\n /**\n * setControl(n)\n *\n * NOTE: Be sure to use this function for all \"wholesale\" regControl updates, because it ensures that\n * unused bits cannot be set -- including bit 6, which could otherwise inadvertently mask the SF error\n * condition on 80387 and newer coprocessors.\n *\n * @this {FPUX86}\n * @param {number} n\n */\n setControl(n)\n {\n this.regControl = n & ~X86.FPU.CONTROL.UNUSED;\n }\n\n /**\n * clearStatus(n)\n *\n * @this {FPUX86}\n * @param {number} n\n */\n clearStatus(n)\n {\n this.regStatus &= ~n;\n this.checkException();\n }\n\n /**\n * getStatus()\n *\n * @this {FPUX86}\n * @return {number} regStatus merged with iST\n */\n getStatus()\n {\n /*\n * As long as we never store any ST bits in regStatus, they should always be zero, so in\n * order to return the complete regStatus, all we need to do is shift and \"or\" the bits from iST.\n */\n return this.regStatus | (this.iST << X86.FPU.STATUS.ST_SHIFT);\n }\n\n /**\n * setStatus(n)\n *\n * NOTE: Be sure to use this function for all \"wholesale\" regStatus updates, because it ensures that\n * the ST bits get propagated to the internal iST register. Setting individual EXC bits should be done\n * through the fault() interface, and clearing individual EXC or BUSY bits should be done through\n * clearStatus(). Both functions, including this function, call checkException() after updating regStatus.\n *\n * @this {FPUX86}\n * @param {number} n\n */\n setStatus(n)\n {\n this.regStatus = n & ~X86.FPU.STATUS.ST;\n this.iST = (n & X86.FPU.STATUS.ST) >> X86.FPU.STATUS.ST_SHIFT;\n this.checkException();\n }\n\n /**\n * checkOperand(v)\n *\n * @this {FPUX86}\n * @param {number|null} v\n * @return {boolean} (true if no exception, false otherwise)\n */\n checkOperand(v)\n {\n return isNaN(v)? !this.setException(X86.FPU.STATUS.IE) : true;\n }\n\n /**\n * checkResult(v)\n *\n * @this {FPUX86}\n * @param {number} v\n * @return {boolean} (true if no exception, false otherwise)\n */\n checkResult(v)\n {\n return !isFinite(v)? !this.setException(v === Infinity? X86.FPU.STATUS.OE : X86.FPU.STATUS.UE) : true;\n }\n\n /**\n * doAdd(operand1, operand2)\n *\n * @this {FPUX86}\n * @param {number|null} operand1\n * @param {number|null} operand2\n * @return {number|null}\n */\n doAdd(operand1, operand2)\n {\n var result = null;\n if (operand1 != null && operand2 != null) {\n result = operand1 + operand2;\n if (!this.checkResult(result)) result = null;\n }\n return result;\n }\n\n /**\n * doSubtract(operand1, operand2)\n *\n * @this {FPUX86}\n * @param {number|null} operand1\n * @param {number|null} operand2\n * @return {number|null}\n */\n doSubtract(operand1, operand2)\n {\n var result = null;\n if (operand1 != null && operand2 != null) {\n result = operand1 - operand2;\n if (!this.checkResult(result)) result = null;\n }\n return result;\n }\n\n /**\n * doMultiply(operand1, operand2)\n *\n * @this {FPUX86}\n * @param {number|null} operand1\n * @param {number|null} operand2\n * @return {number|null}\n */\n doMultiply(operand1, operand2)\n {\n var result = null;\n if (operand1 != null && operand2 != null) {\n result = operand1 * operand2;\n if (!this.checkResult(result)) result = null;\n }\n return result;\n }\n\n /**\n * doDivide(dividend, divisor)\n *\n * TODO: IE exceptions: infinity / infinity, 0 / 0, 0 / pseudo-zero, or divisor is denormal or unnormal.\n *\n * @this {FPUX86}\n * @param {number|null} dividend\n * @param {number|null} divisor\n * @return {number|null}\n */\n doDivide(dividend, divisor)\n {\n var quotient = null;\n if (dividend != null && divisor != null) {\n if (divisor || !this.setException(X86.FPU.STATUS.DE)) {\n quotient = dividend / divisor;\n if (!this.checkResult(quotient)) quotient = null;\n }\n }\n return quotient;\n }\n\n /**\n * doCompare(operand1, operand2)\n *\n * @this {FPUX86}\n * @param {number|null} operand1\n * @param {number|null} operand2\n * @return {boolean}\n */\n doCompare(operand1, operand2)\n {\n if (operand1 != null && operand2 != null) {\n var cc = 0; // default value used when result > 0\n if (!isNaN(operand1) && !isNaN(operand2)) {\n var result = operand1 - operand2;\n if (result < 0) {\n cc = X86.FPU.STATUS.C0;\n } else if (result === 0) {\n cc = X86.FPU.STATUS.C3;\n }\n } else {\n cc = X86.FPU.STATUS.C0 | X86.FPU.STATUS.C2 | X86.FPU.STATUS.C3;\n }\n this.regStatus = (this.regStatus & ~X86.FPU.STATUS.CC) | cc;\n return true;\n }\n return false;\n }\n\n /**\n * doSquareRoot(operand)\n *\n * @this {FPUX86}\n * @param {number|null} operand\n * @return {number|null}\n */\n doSquareRoot(operand)\n {\n var result = null;\n /*\n * Happily, -0 is ALSO >= 0. Also happily, Math.sqrt(-0) returns -0.\n */\n if (operand >= 0 || !this.setException(X86.FPU.STATUS.IE)) {\n result = Math.sqrt(operand);\n if (!this.checkResult(result)) result = null;\n }\n return result;\n }\n\n /**\n * roundValue(operand, max)\n *\n * NOTE: The max parameter is EXCLUSIVE, not inclusive (ie, the maximum positive value is < max).\n *\n * Also, callers that expect intTmpLR[] to be loaded with the result *must* also specify a max parameter;\n * callers performing internal rounding and using just the return value may omit max to skip loading intTmpLR[].\n *\n * @this {FPUX86}\n * @param {number|null} operand\n * @param {number} [max] (ie, 0x8000, 0x80000000, or 0x8000000000000000)\n * @return {number|null} (rounded result, or null if there was an unmasked exception)\n */\n roundValue(operand, max)\n {\n if (operand == null) return null;\n\n var rc = (this.regControl & X86.FPU.CONTROL.RC.MASK), result;\n\n if (rc == X86.FPU.CONTROL.RC.NEAR) {\n result = Math.round(operand);\n if (result - operand === 0.5 && (result % 2)) result--;\n }\n else if (rc == X86.FPU.CONTROL.RC.DOWN || rc == X86.FPU.CONTROL.RC.CHOP && operand > 0) {\n result = Math.floor(operand);\n }\n else { // X86.FPU.CONTROL.RC.UP or X86.FPU.CONTROL.RC.CHOP && operand <= 0\n result = Math.ceil(operand);\n }\n\n if (max) {\n if (result >= max) {\n if (this.setException(X86.FPU.STATUS.IE)) return null;\n result = -max; // apparently, the masked response is to return the most negative integer (not max - 1)\n }\n else if (result < -max) {\n if (this.setException(X86.FPU.STATUS.IE)) return null;\n result = -max;\n }\n this.intTmpLR[0] = result|0;\n if (max > FPUX86.MAX_INT32) {\n this.intTmpLR[1] = (result / 0x100000000)|0;\n if (!this.intTmpLR[1] && result < 0) this.intTmpLR[1] = -1;\n }\n }\n return result;\n }\n\n /**\n * truncateValue(v)\n *\n * @this {FPUX86}\n * @param {number} v\n * @return {number}\n */\n truncateValue(v)\n {\n return v > 0? Math.floor(v) : Math.ceil(v);\n }\n\n /**\n * getTag(iReg)\n *\n * @this {FPUX86}\n * @param {number} iReg (register index)\n * @return {number} tag value for register\n */\n getTag(iReg)\n {\n var bitUsed = (1 << iReg);\n var tag = X86.FPU.TAGS.EMPTY;\n if (this.regUsed & bitUsed) {\n var f = this.regStack[iReg];\n tag = X86.FPU.TAGS.VALID;\n if (f === 0.0) {\n tag = X86.FPU.TAGS.ZERO;\n }\n else if (!isFinite(f)) {\n tag = X86.FPU.TAGS.SPECIAL;\n }\n }\n return tag;\n }\n\n /**\n * getTags()\n *\n * @this {FPUX86}\n * @return {number} tag values for all registers\n */\n getTags()\n {\n var tags = 0;\n for (var iReg = this.regStack.length - 1; iReg >= 0; iReg--) {\n tags <<= 2;\n tags |= this.getTag(iReg);\n }\n return tags;\n }\n\n /**\n * setTag(iReg, tag)\n *\n * @this {FPUX86}\n * @param {number} iReg (register index)\n * @param {number} tag value for register (EMPTY is the only supported value)\n */\n setTag(iReg, tag)\n {\n\n this.regUsed &= ~(1 << iReg);\n }\n\n /**\n * setTags(n)\n *\n * All we need to update here are which physical registers are marked \"empty\"; the rest of the tags\n * are generated on the fly based on actual values in the registers.\n *\n * @this {FPUX86}\n * @param {number} n (16-bit tag word, containing 8 2-bit tags)\n */\n setTags(n)\n {\n this.regUsed = 0;\n for (var bitUsed = 0x1; bitUsed <= 0x80; bitUsed <<= 1) {\n var tag = n & X86.FPU.TAGS.MASK;\n if (tag != X86.FPU.TAGS.EMPTY) {\n this.regUsed |= bitUsed;\n }\n n >>= 2;\n }\n }\n\n /**\n * getWI(i)\n *\n * Gets a \"word-integer\" (WI aka INT16) from ST(i)\n *\n * @this {FPUX86}\n * @param {number} i (eg, 0 for top-of-stack)\n * @return {boolean} true if intTmpLR was loaded, false if not\n */\n getWI(i)\n {\n return this.roundValue(this.getST(i), FPUX86.MAX_INT16) != null;\n }\n\n /**\n * getSI(i)\n *\n * Gets a \"short-integer\" (SI aka INT32) from ST(i)\n *\n * @this {FPUX86}\n * @param {number} i (eg, 0 for top-of-stack)\n * @return {boolean} true if intTmpLR was loaded, false if not\n */\n getSI(i)\n {\n return this.roundValue(this.getST(i), FPUX86.MAX_INT32) != null;\n }\n\n /**\n * getLI(i)\n *\n * Gets a \"long-integer\" (LI aka INT64) from ST(i)\n *\n * @this {FPUX86}\n * @param {number} i (eg, 0 for top-of-stack)\n * @return {boolean} true if intTmpLR was loaded, false if not\n */\n getLI(i)\n {\n return this.roundValue(this.getST(i), FPUX86.MAX_INT64) != null;\n }\n\n /**\n * getSR(i)\n *\n * @this {FPUX86}\n * @param {number} i (eg, 0 for top-of-stack)\n * @return {boolean} true if regTmpSR was loaded, false if not\n */\n getSR(i)\n {\n var iReg = (this.iST + i) & 7;\n if (this.regUsed & (1 << iReg)) {\n this.regTmpSR[0] = this.regStack[iReg];\n return true;\n } else if (!this.setException(X86.FPU.STATUS.IE)) {\n this.regTmpSR[0] = this.regIndefinite[0];\n return true;\n }\n return false;\n }\n\n /**\n * getLR(i)\n *\n * @this {FPUX86}\n * @param {number} i (eg, 0 for top-of-stack)\n * @return {boolean} true if regTmpLR was loaded, false if not\n */\n getLR(i)\n {\n var iReg = (this.iST + i) & 7;\n if (this.regUsed & (1 << iReg)) {\n this.regTmpLR[0] = this.regStack[iReg];\n return true;\n } else if (!this.setException(X86.FPU.STATUS.IE)) {\n this.regTmpLR[0] = this.regIndefinite[0];\n return true;\n }\n return false;\n }\n\n /**\n * getST(i)\n *\n * @this {FPUX86}\n * @param {number} i (eg, 0 for top-of-stack)\n * @return {number|null} v\n */\n getST(i)\n {\n var v = null;\n var iReg = (this.iST + i) & 7;\n if (this.regUsed & (1 << iReg)) {\n v = this.regStack[iReg];\n } else if (!this.setException(X86.FPU.STATUS.IE)) {\n v = this.regIndefinite[0];\n }\n return v;\n }\n\n /**\n * getSTSign(i)\n *\n * Returns zero if sign bit clear, and non-zero (negative) if sign bit set. This is safer\n * than comparing getST() to zero, because JavaScript comparisons involving NaNs are meaningless.\n *\n * For internal use only; ignores whether the register is empty, and performs no exception checks.\n *\n * @this {FPUX86}\n * @param {number} i (eg, 0 for top-of-stack)\n * @return {number}\n */\n getSTSign(i)\n {\n var iInt = ((this.iST + i) & 7) << 1;\n return this.intStack[iInt + 1] & (0x80000000|0);\n }\n\n /**\n * setST(i, v)\n *\n * @this {FPUX86}\n * @param {number} i (eg, 0 for top-of-stack)\n * @param {number|null} v\n * @return {boolean}\n */\n setST(i, v)\n {\n if (v != null && this.checkOperand(v)) {\n var iReg = (this.iST + i) & 7;\n this.regStack[iReg] = v;\n this.regUsed |= (1 << iReg);\n return true;\n }\n return false;\n }\n\n /**\n * getTR(i, fSafe)\n *\n * @this {FPUX86}\n * @param {number} i (stack index, 0-7)\n * @param {boolean} [fSafe] (true to ignore all exception criteria; used by FSAVE)\n * @return {Array.<number>|null} (\"temp-real\" aka TR, as an array of three 32-bit integers)\n */\n getTR(i, fSafe)\n {\n var a = null;\n var iReg = (this.iST + i) & 7;\n if (fSafe || this.regUsed & (1 << iReg) || !this.setException(X86.FPU.STATUS.IE)) {\n var iInt = iReg << 1;\n a = this.getTRFromLR(this.intStack[iInt], this.intStack[iInt + 1]);\n }\n return a;\n }\n\n /**\n * setTR(i, a)\n *\n * Sets ST(i) to the TR (\"long-real\") in a[].\n *\n * @this {FPUX86}\n * @param {number} i (stack index, 0-7)\n * @param {Array.<number>|null} a\n */\n setTR(i, a)\n {\n if (a) this.setST(i, this.getLRFromTR(a));\n }\n\n /**\n * getWIFromEA()\n *\n * Returns the (16-bit) \"word-integer\" value located at regEA.\n *\n * @this {FPUX86}\n * @return {number} v\n */\n getWIFromEA()\n {\n\n return (this.cpu.getShort(this.cpu.regEA) << 16) >> 16;\n }\n\n /**\n * getSIFromEA()\n *\n * Returns the (32-bit) \"short-integer\" value located at regEA.\n *\n * @this {FPUX86}\n * @return {number} v\n */\n getSIFromEA()\n {\n\n return this.cpu.getLong(this.cpu.regEA);\n }\n\n /**\n * getLIFromEA()\n *\n * Returns the (64-bit) \"long-integer\" value located at regEA.\n *\n * @this {FPUX86}\n * @return {number} v\n */\n getLIFromEA()\n {\n\n var lo = this.cpu.getLong(this.cpu.regEA);\n var hi = this.cpu.getLong(this.cpu.regEA + 4);\n return (hi * 0x100000000) + (lo >>> 0);\n }\n\n /**\n * getSRFromEA()\n *\n * Sets the internal regTmpSR register to the (32-bit) \"short-real\" value located at regEA.\n *\n * @this {FPUX86}\n * @return {number} v\n */\n getSRFromEA()\n {\n\n this.intTmpSR[0] = this.cpu.getLong(this.cpu.regEA);\n return this.regTmpSR[0];\n }\n\n /**\n * getLRFromEA()\n *\n * Sets the internal regTmpLR register to the (64-bit) \"long-real\" value located at regEA.\n *\n * @this {FPUX86}\n * @return {number} v\n */\n getLRFromEA()\n {\n\n this.intTmpLR[0] = this.cpu.getLong(this.cpu.regEA);\n this.intTmpLR[1] = this.cpu.getLong(this.cpu.regEA + 4);\n return this.regTmpLR[0];\n }\n\n /**\n * getTRFromEA()\n *\n * Sets the internal intTmpTR register to the (80-bit) \"temp-real\" value located at regEA.\n *\n * @this {FPUX86}\n * @return {Array.<number>} intTmpTR\n */\n getTRFromEA()\n {\n\n this.intTmpTR[0] = this.cpu.getLong(this.cpu.regEA);\n this.intTmpTR[1] = this.cpu.getLong(this.cpu.regEA + 4);\n this.intTmpTR[2] = this.cpu.getShort(this.cpu.regEA + 8);\n return this.intTmpTR;\n }\n\n /**\n * setEAFromWI()\n *\n * Stores the (16-bit) \"word-integer\" value in the internal intTmpLR register to the address in regEA.\n *\n * @this {FPUX86}\n */\n setEAFromWI()\n {\n\n this.cpu.setShort(this.cpu.regEA, this.intTmpLR[0]);\n }\n\n /**\n * setEAFromSI()\n *\n * Stores the (32-bit) \"short-integer\" value in the internal intTmpLR register to the address in regEA.\n *\n * @this {FPUX86}\n */\n setEAFromSI()\n {\n\n this.cpu.setLong(this.cpu.regEA, this.intTmpLR[0]);\n }\n\n /**\n * setEAFromLI()\n *\n * Stores the (64-bit) \"long-integer\" value in the internal intTmpLR register to the address in regEA.\n *\n * @this {FPUX86}\n */\n setEAFromLI()\n {\n\n this.cpu.setLong(this.cpu.regEA, this.intTmpLR[0]);\n this.cpu.setLong(this.cpu.regEA + 4, this.intTmpLR[1]);\n }\n\n /**\n * setEAFromTR()\n *\n * Stores the (80-bit) \"temp-real\" value in the internal intTmpTR register to the address in regEA.\n *\n * @this {FPUX86}\n */\n setEAFromTR()\n {\n\n this.cpu.setLong(this.cpu.regEA, this.intTmpTR[0]);\n this.cpu.setLong(this.cpu.regEA + 4, this.intTmpTR[1]);\n this.cpu.setShort(this.cpu.regEA + 8, this.intTmpTR[2]);\n }\n\n /**\n * getLRFromTR(a)\n *\n * Since we must use the \"long-real\" (64-bit) format internally, rather than the \"temp-real\" (80-bit) format,\n * this function converts a 64-bit value to an 80-bit value. The major differences: 1) the former uses a 52-bit\n * fraction and 11-bit exponent, while the latter uses a 64-bit fraction and 15-bit exponent; 2) the former\n * does NOT store a leading 1 with the fraction, whereas the latter does.\n *\n * @this {FPUX86}\n * @param {Array.<number>} a (eg, intTmpTR)\n * @return {number} v\n */\n getLRFromTR(a)\n {\n var loTR = a[0], hiTR = a[1];\n var signLR = (a[2] & 0x8000) >> 4, expLR = a[2] & 0x7fff;\n /*\n * We have no choice but to chop off the bottom 11 TR bits in order to fit in an LR....\n */\n var loLR = (loTR >>> 11) | (hiTR << 21), hiLR = (hiTR >> 11) & 0xfffff;\n\n if (expLR == 0x7fff) {\n /*\n * Convert an TR NaN to a LR NaN.\n */\n expLR = 0x7ff;\n }\n else if (expLR) {\n /*\n * We have a normal (biased) TR exponent which we must now convert to a (biased) LR exponent;\n * subtract the TR bias (0x3fff) and add the LR bias (0x3ff); additionally, we have a problem\n * that getTRFromLR() did not: if the TR exponent is too large to fit in an LR exponent, then we\n * have convert the result to +/- infinity.\n */\n expLR += 0x3ff - 0x3fff;\n if (expLR <= 0) {\n expLR = 0x7ff;\n loLR = hiLR = 0;\n }\n }\n\n this.intTmpLR[0] = loLR;\n this.intTmpLR[1] = hiLR | ((signLR | expLR) << 20);\n return this.regTmpLR[0];\n }\n\n /**\n * getTRFromLR(loLR, hiLR)\n *\n * Since we must use the \"long-real\" (64-bit) format internally, rather than the \"temp-real\" (80-bit) format,\n * this function converts a 64-bit value to an 80-bit value. The major differences: 1) the former uses a 52-bit\n * fraction and 11-bit exponent, while the latter uses a 64-bit fraction and 15-bit exponent; 2) the former\n * does NOT store a leading 1 with the fraction, whereas the latter does.\n *\n * @this {FPUX86}\n * @param {number} loLR\n * @param {number} hiLR\n * @return {Array.<number>} (intTmpTR)\n */\n getTRFromLR(loLR, hiLR)\n {\n var expTR = (hiLR >> 20) & 0x07ff;\n var signTR = (hiLR >> 16) & 0x8000;\n var loTR = loLR << 11, hiTR = 0x80000000 | ((hiLR & 0x000fffff) << 11) | (loLR >>> 21);\n\n if (expTR == 0x07ff) {\n /*\n * Convert an LR NaN to a TR NaN. NaNs encompass +/- infinity, which in the LR\n * world are fractions of all zeros. NaNs also encompass indefinite, which in the LR\n * world are negative numbers with only the high fraction bit set. So, in both cases,\n * our default TR value (ie, with zeros shifted into the bottom 11 bits) should be fine;\n * we simply need to change the exponent to the maximum TR value.\n */\n expTR = 0x7fff;\n }\n else if (!expTR) {\n /*\n * An LR with an exponent of zero could be an actual +/- zero, if the fraction is zero,\n * or it could be a denormal, if the fraction is non-zero. In both cases, the only\n * change we need to make the TR form is clearing the leading 1 bit.\n */\n hiTR &= 0x7fffffff;\n }\n else {\n /*\n * We have a normal (biased) LR exponent which we must now convert to a (biased) TR exponent;\n * subtract the LR bias (0x3ff) and add the TR bias (0x3fff).\n */\n expTR += 0x3fff - 0x3ff;\n }\n\n this.intTmpTR[0] = loTR;\n this.intTmpTR[1] = hiTR;\n this.intTmpTR[2] = signTR | expTR;\n return this.intTmpTR;\n }\n\n /**\n * decodeBCD()\n *\n * @this {FPUX86}\n * @param {number} i (32-bit integer containing n BCD digits)\n * @param {number} n (number of BCD digits to decode)\n * @return {number} (binary value representing the specified number of BCD digits)\n */\n decodeBCD(i, n)\n {\n var v = 0, m = 1;\n\n while (n--) {\n var d = i & 0xf;\n\n v += d * m;\n m *= 10;\n i >>= 4;\n }\n return v;\n }\n\n /**\n * encodeBCD()\n *\n * @this {FPUX86}\n * @param {number} v (binary value from which to extract n BCD digits)\n * @param {number} n (number of BCD digits to extract)\n * @return {number} (integer containing the requested number of BCD digits)\n */\n encodeBCD(v, n)\n {\n var i = 0, s = 0;\n\n while (n--) {\n i |= (v % 10) << s;\n v /= 10;\n s += 4;\n }\n return i;\n }\n\n /**\n * popValue()\n *\n * @this {FPUX86}\n * @return {number|null} v\n */\n popValue()\n {\n var v = null;\n var bitUsed = (1 << this.iST);\n if (!(this.regUsed & bitUsed)) {\n this.regStatus &= ~X86.FPU.STATUS.C1; // clear C1 to indicate stack underflow (80287XL and up)\n if (this.setException(X86.FPU.STATUS.SF | X86.FPU.STATUS.IE)) return v;\n }\n this.regUsed &= ~bitUsed;\n v = this.regStack[this.iST];\n this.iST = (this.iST + 1) & 7;\n return v;\n }\n\n /**\n * pushValue(v)\n *\n * @this {FPUX86}\n * @param {number|null} v\n */\n pushValue(v)\n {\n if (v == null) return;\n var iReg = (this.iST - 1) & 7;\n var bitUsed = (1 << iReg);\n if (this.regUsed & bitUsed) {\n this.regStatus |= X86.FPU.STATUS.C1; // set C1 to indicate stack overflow (80287XL and up)\n if (this.setException(X86.FPU.STATUS.SF | X86.FPU.STATUS.IE)) return;\n }\n if (!this.checkOperand(v)) {\n if (this.setException(X86.FPU.STATUS.IE)) return;\n v = NaN;\n }\n this.regStack[this.iST = iReg] = v;\n this.regUsed |= bitUsed;\n }\n\n /**\n * loadEnv(addr)\n *\n * @this {FPUX86}\n * @param {number} addr\n * @return {number} updated addr\n */\n loadEnv(addr)\n {\n var w;\n var cpu = this.cpu;\n\n this.setControl(cpu.getWord(addr));\n this.setStatus(cpu.getWord(addr += cpu.sizeData));\n this.setTags(cpu.getWord(addr += cpu.sizeData));\n\n if (!(cpu.regCR0 & X86.CR0.MSW.PE) || (cpu.regPS & X86.PS.VM)) {\n this.regCodeOff = cpu.getWord(addr += cpu.sizeData);\n w = cpu.getWord(addr += cpu.sizeData);\n this.regOpcode = w & 0x7ff;\n this.regCodeOff |= (w & ~0xfff) << 4;\n this.regCodeSel = -1;\n this.regDataOff = cpu.getWord(addr += cpu.sizeData);\n this.regDataOff |= (cpu.getWord(addr += cpu.sizeData) & ~0xfff) << 4;\n this.regDataSel = -1;\n } else {\n this.regCodeOff = cpu.getWord(addr += cpu.sizeData);\n w = cpu.getWord(addr += cpu.sizeData);\n this.regCodeSel = w & 0xffff;\n this.regOpcode = (w >> 16) & 0x7ff;\n this.regDataOff = cpu.getWord(addr += cpu.sizeData);\n this.regDataSel = cpu.getWord(addr += cpu.sizeData) & 0xffff;\n }\n return addr + cpu.sizeData;\n }\n\n /**\n * saveEnv(addr)\n *\n * @this {FPUX86}\n * @param {number} addr\n * @return {number} updated addr\n */\n saveEnv(addr)\n {\n var cpu = this.cpu;\n\n cpu.setWord(addr, this.regControl);\n cpu.setWord(addr += cpu.sizeData, this.getStatus());\n cpu.setWord(addr += cpu.sizeData, this.getTags());\n\n if (!(cpu.regCR0 & X86.CR0.MSW.PE) || (cpu.regPS & X86.PS.VM)) {\n var off = (this.regCodeSel << 4) + this.regCodeOff;\n cpu.setWord(addr += cpu.sizeData, off);\n cpu.setWord(addr += cpu.sizeData, ((off >> 4) & ~0xfff) | this.regOpcode);\n off = (this.regDataSel << 4) + this.regDataOff;\n cpu.setWord(addr += cpu.sizeData, off);\n cpu.setWord(addr += cpu.sizeData, ((off >> 4) & ~0xfff));\n } else {\n cpu.setWord(addr += cpu.sizeData, this.regCodeOff);\n cpu.setWord(addr += cpu.sizeData, this.regCodeSel | (this.regOpcode << 16));\n cpu.setWord(addr += cpu.sizeData, this.regDataOff);\n cpu.setWord(addr += cpu.sizeData, this.regDataSel);\n }\n return addr + cpu.sizeData;\n }\n\n /**\n * opFPU(bOpcode, bModRM, dst, src)\n *\n * This is called by the CPU's ESC opcode handlers, after each instruction has been fully decoded.\n *\n * @this {FPUX86}\n * @param {number} bOpcode (0xD8-0xDF)\n * @param {number} bModRM\n * @param {number} dst\n * @param {number} src\n */\n opFPU(bOpcode, bModRM, dst, src)\n {\n var mod = (bModRM >> 6) & 3;\n var reg = (bModRM >> 3) & 7;\n this.iStack = (bModRM & 7);\n\n /*\n * Combine mod and reg into one decodable value: put mod in the high nibble\n * and reg in the low nibble, after first collapsing all mod values < 3 to zero.\n */\n var modReg = (mod < 3? 0 : 0x30) + reg;\n\n /*\n * All values >= 0x34 imply mod == 3 and reg >= 4, so now we shift reg into the high\n * nibble and iStack into the low, yielding values >= 0x40.\n */\n if ((bOpcode == X86.OPCODE.ESC1 || bOpcode == X86.OPCODE.ESC3) && modReg >= 0x34) {\n modReg = (reg << 4) | this.iStack;\n }\n\n var fnOp = FPUX86.aaOps[bOpcode][modReg];\n if (fnOp) {\n /*\n * A handful of FPU instructions must preserve (at least some of) the \"exception\" registers,\n * so if the current function is NOT one of those, then update all the \"exception\" registers.\n */\n if (FPUX86.afnPreserveExceptions.indexOf(fnOp) < 0) {\n var cpu = this.cpu;\n var off = cpu.opLIP;\n /*\n * WARNING: opLIP points to any prefixes preceding the ESC instruction, but the 8087 always\n * points to the ESC instruction. Technically, that's a bug, but it's also a reality, so we\n * check for preceding prefixes and bump the instruction pointer accordingly. This isn't a\n * perfect solution, because it doesn't account for multiple (redundant) prefixes, but it\n * should be adequate.\n */\n if (this.isModel(X86.FPU.MODEL_8087)) {\n if (cpu.opPrefixes & X86.OPFLAG.SEG) off++;\n if (cpu.opPrefixes & X86.OPFLAG.LOCK) off++;\n }\n this.regCodeSel = cpu.segCS.sel;\n this.regCodeOff = off - cpu.segCS.base;\n if (cpu.regEA !== X86.ADDR_INVALID) {\n this.regDataSel = cpu.segEA.sel;\n this.regDataOff = cpu.regEA - cpu.segEA.base;\n }\n this.regOpcode = ((bOpcode & 7) << 8) | bModRM;\n }\n /*\n * Finally, perform the FPU operation.\n */\n fnOp.call(this);\n }\n else {\n /*\n * This is a gray area, at least until aaOps has been filled in for all supported coprocessors;\n * but for now, we'll treat all unrecognized operations as \"no operation\", as opposed to unimplemented.\n */\n this.opNone();\n }\n }\n\n /**\n * opWAIT()\n *\n * This is called by the CPU's WAIT opcode handler, giving us the opportunity to synchronize the FPU with the CPU,\n * charge an appropriate number of cycles, and return true. In this context, it's considered an FWAIT instruction,\n * but technically, it's the same opcode.\n *\n * If we choose to do nothing, then we must return false, so that the CPU can charge a default number of cycles.\n *\n * @this {FPUX86}\n * @return {boolean} true if implemented, false if not\n */\n opWAIT()\n {\n return false;\n }\n\n /**\n * readFPUStack(i)\n *\n * Returns the following information for the requested FPU stack element, relative to ST:\n *\n * a[0]: physical stack position (0-7)\n * a[1]: corresponding tag value\n * a[2]: 64-bit \"long-real\" (LR) value\n * a[3]: bits 0-31 of 64-bit \"long-real\" (LR)\n * a[4]: bits 32-63 of 64-bit \"long-real\" (LR)\n * a[5]: bits 0-31 of 80-bit \"temp-real\" (TR)\n * a[6]: bits 32-63 of 80-bit \"temp-real\" (TR)\n * a[7]: bits 64-79 of 80-bit \"temp-real\" (TR) (in bits 0-15)\n *\n * Used by the Debugger for its floating-point register (\"rfp\") command. For other FPU registers,\n * the Debugger calls getStatus() and getControl() directly.\n *\n * NOTE: The \"temp-real\" values are fake; we manufacture them on demand from 64-bit \"long-real\" values\n * actually stored in the stack; see getTRFromLR().\n *\n * @this {FPUX86}\n * @param {number} i (stack index, relative to ST)\n * @return {Array.<number>|null} (an array of information as described above, or null if invalid element)\n */\n readFPUStack(i)\n {\n var a = null;\n if (i < this.regStack.length) {\n a = [];\n var iReg = (this.iST + i) & 7;\n a[0] = iReg;\n a[1] = this.getTag(iReg);\n a[2] = this.regStack[iReg];\n var iInt = iReg << 1;\n a[3] = this.intStack[iInt];\n a[4] = this.intStack[iInt + 1];\n var aTR = this.getTRFromLR(a[3], a[4]);\n a[5] = aTR[0]; a[6] = aTR[1]; a[7] = aTR[2];\n }\n return a;\n }\n\n /**\n * getRandomInt(min, max)\n *\n * Used with old test code to verify that any randomly-constructed \"long-real\" (REAL64) could be converted\n * to a \"temp-real\" (REAL80) and back again losslessly, otherwise a bug in either getTRFromLR() or getLRFromTR()\n * might exist. That test code can be resurrected from the repo; this code is being retained for future tests.\n *\n * NOTE: If either min or max is a value containing 32 or more significant bits AND bit 31 is set AND it has passed\n * through some bitwise operation(s), then that value may end up being negative, so you may end up with an inverted\n * range, or a range that's smaller or larger than intended.\n *\n * @this {FPUX86}\n * @param {number} min (inclusive)\n * @param {number} max (inclusive)\n * @return {number}\n *\n getRandomInt(min, max)\n {\n max -= min;\n if (max < 0) { // compensate for inverted ranges (ie, where min > max)\n min += max;\n max = -max;\n }\n return Math.floor(Math.random() * (max + 1)) + min;\n }\n */\n\n /**\n * FPUX86.init()\n *\n * This function operates on every HTML element of class \"fpu\", extracting the\n * JSON-encoded parameters for the FPUX86 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create an FPUX86 component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeFPUs = Component.getElementsByClass(document, PCX86.APPCLASS, \"fpu\");\n for (var iFPU = 0; iFPU < aeFPUs.length; iFPU++) {\n var eFPU = aeFPUs[iFPU];\n var parmsFPU = Component.getComponentParms(eFPU);\n var fpu = new FPUX86(parmsFPU);\n Component.bindComponentControls(fpu, eFPU, PCX86.APPCLASS);\n }\n }\n}\n\n/**\n * F2XM1()\n *\n * F2XM1 (2 to the x minus 1) calculates the function 2^x - 1 and returns the result to ST(0).\n *\n * On the 8087 and 80287, the value in ST(0) must satisfy the inequality 0 <= ST(0) <= 0.5. On the 80287XL and\n * later coprocessors, the permissible range is greater, and ST(0) must satisfy the inequality -1 <= ST(0) <= 1.\n * If ST(0) is out of range, the result is undefined, even though no exception is raised.\n *\n * The F2XM1 instruction is designed to provide an accurate result even when x is close to zero. To obtain 2^x,\n * simply add 1.0 to the result returned by F2XM1.\n *\n * This instruction is useful in performing exponentiation of values other than 2 as shown in the following formulas:\n *\n * 10^x = 2^(x * log2(10))\n * e^x = 2^(x * log2(e))\n * y^x = 2^(x * log2(y))\n *\n * Note that the NPX has dedicated instructions for loading the constants log2(10) and log2(e). The FYL2X instruction\n * may be used to calculate x * log2(y).\n *\n * See also: FYL2X, FLDL2T, FLDL2E.\n *\n * @this {FPUX86}\n */\nFPUX86.F2XM1 = function()\n{\n this.setST(0, Math.pow(2, this.getST(0)) - 1);\n};\n\n/**\n * FABS()\n *\n * @this {FPUX86}\n */\nFPUX86.FABS = function()\n{\n /*\n * TODO: This could be implemented more efficiently by simply clearing the sign bit of ST(0).\n */\n this.setST(0, Math.abs(this.getST(0)));\n};\n\n/**\n * FADDlr()\n *\n * @this {FPUX86}\n */\nFPUX86.FADDlr = function()\n{\n this.setST(0, this.doAdd(this.getST(0), this.getLRFromEA()));\n};\n\n/**\n * FADDsr()\n *\n * Encoding 0xD8,reg=0x00 (\"FADD short-real\"): ST(0) <- ST(0) + REAL32\n *\n * @this {FPUX86}\n */\nFPUX86.FADDsr = function()\n{\n this.setST(0, this.doAdd(this.getST(0), this.getSRFromEA()));\n};\n\n/**\n * FADDst()\n *\n * @this {FPUX86}\n */\nFPUX86.FADDst = function()\n{\n this.setST(0, this.doAdd(this.getST(0), this.getST(this.iStack)));\n};\n\n/**\n * FADDsti()\n *\n * @this {FPUX86}\n */\nFPUX86.FADDsti = function()\n{\n this.setST(this.iStack, this.doAdd(this.getST(this.iStack), this.getST(0)));\n};\n\n/**\n * FADDPsti()\n *\n * @this {FPUX86}\n */\nFPUX86.FADDPsti = function()\n{\n if (this.setST(this.iStack, this.doAdd(this.getST(this.iStack), this.getST(0)))) this.popValue();\n};\n\n/**\n * FBLDpd()\n *\n * @this {FPUX86}\n */\nFPUX86.FBLDpd = function()\n{\n var a = this.getTRFromEA();\n /*\n * a[0] contains the 8 least-significant BCD digits, a[1] contains the next 8, and a[2] contains\n * the next 2 (bit 15 of a[2] is the sign bit, and bits 8-14 of a[2] are unused).\n */\n var v = this.decodeBCD(a[0], 8) + this.decodeBCD(a[1], 8) * 100000000 + this.decodeBCD(a[2], 2) * 10000000000000000;\n if (a[2] & 0x8000) v = -v;\n this.pushValue(v);\n};\n\n/**\n * FBSTPpd()\n *\n * @this {FPUX86}\n */\nFPUX86.FBSTPpd = function()\n{\n /*\n * TODO: Verify the operation of FBSTP (eg, does it signal an exception if abs(value) >= 1000000000000000000?)\n */\n var v = this.roundValue(this.popValue());\n if (v != null) {\n /*\n * intTmpTR[0] will contain the 8 least-significant BCD digits, intTmpTR[1] will contain the next 8,\n * and intTmpTR[2] will contain the next 2 (bit 15 of intTmpTR[2] will be the sign bit, and bits 8-14 of\n * intTmpTR[2] will be unused).\n */\n this.intTmpTR[0] = this.encodeBCD(v, 8);\n this.intTmpTR[1] = this.encodeBCD(v / 100000000, 8);\n this.intTmpTR[2] = this.encodeBCD(v / 10000000000000000, 2);\n if (v < 0) this.intTmpTR[2] |= 0x8000;\n this.setEAFromTR();\n }\n};\n\n/**\n * FCHS()\n *\n * @this {FPUX86}\n */\nFPUX86.FCHS = function()\n{\n /*\n * TODO: This could be implemented more efficiently by simply inverting the sign bit of ST(0).\n */\n this.setST(0, -this.getST(0));\n};\n\n/**\n * FCLEX()\n *\n * NOTE: Although we explicitly clear the BUSY bit, there shouldn't be any code setting it, because\n * we're never \"busy\" (all floating-point operations are performed synchronously). Conversely, there's\n * no need to explicitly clear the ES bit, because clearStatus() will call checkException(), which\n * updates ES and clears/sets FPU interrupt status as appropriate.\n *\n * @this {FPUX86}\n */\nFPUX86.FCLEX = function()\n{\n this.clearStatus(X86.FPU.STATUS.EXC | X86.FPU.STATUS.BUSY);\n};\n\n/**\n * FCOMlr()\n *\n * Encoding 0xDC,mod<3,reg=2 (\"FCOM long-real\"): Evaluate ST(0) - REAL64\n *\n * @this {FPUX86}\n */\nFPUX86.FCOMlr = function()\n{\n this.doCompare(this.getST(0), this.getLRFromEA());\n};\n\n/**\n * FCOMsr()\n *\n * Encoding 0xD8,mod<3,reg=2 (\"FCOM short-real\"): Evaluate ST(0) - REAL32\n *\n * @this {FPUX86}\n */\nFPUX86.FCOMsr = function()\n{\n this.doCompare(this.getST(0), this.getSRFromEA());\n};\n\n/**\n * FCOMst()\n *\n * Encoding 0xD8,mod=3,reg=2 (\"FCOM ST(i)\"): Evaluate ST(0) - ST(i)\n *\n * @this {FPUX86}\n */\nFPUX86.FCOMst = function()\n{\n this.doCompare(this.getST(0), this.getST(this.iStack));\n};\n\n/**\n * FCOM8087()\n *\n * NOTE: This is used with encoding(s) (0xDC,0xD0-0xD7) that were valid for the 8087 and 80287\n * but may no longer be valid as of the 80387.\n *\n * TODO: Determine if this form subtracted the operands in the same order, or if it requires an FCOMsti(),\n * which, like the other *sti() functions, uses ST(0) as the second operand rather than the first.\n *\n * @this {FPUX86}\n */\nFPUX86.FCOM8087 = function()\n{\n this.opObsolete();\n FPUX86.FCOMst.call(this);\n};\n\n/**\n * FCOMPlr()\n *\n * Encoding 0xDC,mod<3,reg=3 (\"FCOM long-real\"): Evaluate ST(0) - REAL64, POP\n *\n * @this {FPUX86}\n */\nFPUX86.FCOMPlr = function()\n{\n if (this.doCompare(this.getST(0), this.getLRFromEA())) this.popValue();\n};\n\n/**\n * FCOMPsr()\n *\n * Encoding 0xD8,mod<3,reg=3 (\"FCOM short-real\"): Evaluate ST(0) - REAL32, POP\n *\n * @this {FPUX86}\n */\nFPUX86.FCOMPsr = function()\n{\n if (this.doCompare(this.getST(0), this.getSRFromEA())) this.popValue();\n};\n\n/**\n * FCOMPst()\n *\n * Encoding 0xD8,mod=3,reg=3 (\"FCOMP ST(i)\"): Evaluate ST(0) - ST(i), POP\n *\n * @this {FPUX86}\n */\nFPUX86.FCOMPst = function()\n{\n if (this.doCompare(this.getST(0), this.getST(this.iStack))) this.popValue();\n};\n\n/**\n * FCOMP8087()\n *\n * NOTE: This is used with encodings (0xDC,0xD8-0xDF and 0xDE,0xD0-0xD7) that were valid for the 8087\n * and 80287 but may no longer be valid as of the 80387.\n *\n * TODO: Determine if this form subtracted the operands in the same order, or if it requires an FCOMPsti(),\n * which, like the other *sti() functions, uses ST(0) as the second operand rather than the first.\n *\n * @this {FPUX86}\n */\nFPUX86.FCOMP8087 = function()\n{\n this.opObsolete();\n FPUX86.FCOMPst.call(this);\n};\n\n/**\n * FCOMPP()\n *\n * @this {FPUX86}\n */\nFPUX86.FCOMPP = function()\n{\n if (this.doCompare(this.getST(0), this.getST(1)) && this.popValue() != null) this.popValue();\n};\n\n/**\n * FDECSTP()\n *\n * @this {FPUX86}\n */\nFPUX86.FDECSTP = function()\n{\n this.iST = (this.iST - 1) & 0x7;\n this.regStatus &= ~X86.FPU.STATUS.C1;\n};\n\n/**\n * FDISI8087()\n *\n * @this {FPUX86}\n */\nFPUX86.FDISI8087 = function()\n{\n if (this.isModel(X86.FPU.MODEL_8087)) {\n this.regControl |= X86.FPU.CONTROL.IEM;\n }\n};\n\n/**\n * FDIVlr()\n *\n * @this {FPUX86}\n */\nFPUX86.FDIVlr = function()\n{\n this.setST(0, this.doDivide(this.getST(0), this.getLRFromEA()));\n};\n\n/**\n * FDIVsr()\n *\n * @this {FPUX86}\n */\nFPUX86.FDIVsr = function()\n{\n this.setST(0, this.doDivide(this.getST(0), this.getSRFromEA()));\n};\n\n/**\n * FDIVst()\n *\n * Encoding 0xD8,0xF0-0xF7 (\"FDIV ST,ST(i)\"): ST(0) <- ST(0) / ST(i)\n *\n * @this {FPUX86}\n */\nFPUX86.FDIVst = function()\n{\n this.setST(0, this.doDivide(this.getST(0), this.getST(this.iStack)));\n};\n\n/**\n * FDIVsti()\n *\n * Encoding 0xDC,0xF8-0xFF (\"FDIV ST(i),ST\"): ST(i) <- ST(i) / ST(0)\n *\n * @this {FPUX86}\n */\nFPUX86.FDIVsti = function()\n{\n this.setST(this.iStack, this.doDivide(this.getST(this.iStack), this.getST(0)));\n};\n\n/**\n * FDIVPsti()\n *\n * Encoding 0xDE,0xF8-0xFF (\"FDIVP ST(i),ST\"): ST(i) <- ST(i) / ST(0), POP\n *\n * @this {FPUX86}\n */\nFPUX86.FDIVPsti = function()\n{\n if (this.setST(this.iStack, this.doDivide(this.getST(this.iStack), this.getST(0)))) this.popValue();\n};\n\n/**\n * FDIVRlr()\n *\n * @this {FPUX86}\n */\nFPUX86.FDIVRlr = function()\n{\n this.setST(0, this.doDivide(this.getLRFromEA(), this.getST(0)));\n};\n\n/**\n * FDIVRsr()\n *\n * @this {FPUX86}\n */\nFPUX86.FDIVRsr = function()\n{\n this.setST(0, this.doDivide(this.getSRFromEA(), this.getST(0)));\n};\n\n/**\n * FDIVRst()\n *\n * Encoding 0xD8,0xF8-0xFF (\"FDIVR ST,ST(i)\"): ST(0) <- ST(i) / ST(0)\n *\n * @this {FPUX86}\n */\nFPUX86.FDIVRst = function()\n{\n this.setST(0, this.doDivide(this.getST(this.iStack), this.getST(0)));\n};\n\n/**\n * FDIVRsti()\n *\n * Encoding 0xDC,0xF0-0xF7 (\"FDIVR ST(i),ST\"): ST(i) <- ST(0) / ST(i)\n *\n * @this {FPUX86}\n */\nFPUX86.FDIVRsti = function()\n{\n this.setST(this.iStack, this.doDivide(this.getST(0), this.getST(this.iStack)));\n};\n\n/**\n * FDIVRPsti()\n *\n * Encoding 0xDE,0xF0-0xE7 (\"FDIVRP ST(i),ST\"): ST(i) <- ST(0) / ST(i), POP\n *\n * @this {FPUX86}\n */\nFPUX86.FDIVRPsti = function()\n{\n if (this.setST(this.iStack, this.doDivide(this.getST(0), this.getST(this.iStack)))) this.popValue();\n};\n\n/**\n * FENI8087()\n *\n * @this {FPUX86}\n */\nFPUX86.FENI8087 = function()\n{\n if (this.isModel(X86.FPU.MODEL_8087)) {\n this.regControl &= ~X86.FPU.CONTROL.IEM;\n }\n};\n\n/**\n * FFREEsti()\n *\n * @this {FPUX86}\n */\nFPUX86.FFREEsti = function()\n{\n this.setTag(this.iST, X86.FPU.TAGS.EMPTY);\n};\n\n/**\n * FFREEP8087()\n *\n * NOTE: This is used with an encoding (0xDF,0xC0-0xC7) that was valid for the 8087 and 80287\n * but may no longer be valid as of the 80387. Also, if the older documentation is to be believed,\n * this instruction has no modern counterpart, as FFREE doesn't pop the stack.\n *\n * @this {FPUX86}\n */\nFPUX86.FFREEP8087 = function()\n{\n this.opObsolete();\n FPUX86.FFREEsti.call(this);\n this.popValue();\n};\n\n/**\n * FIADD16()\n *\n * @this {FPUX86}\n */\nFPUX86.FIADD16 = function()\n{\n this.setST(0, this.doAdd(this.getST(0), this.getWIFromEA()));\n};\n\n/**\n * FIADD32()\n *\n * @this {FPUX86}\n */\nFPUX86.FIADD32 = function()\n{\n this.setST(0, this.doAdd(this.getST(0), this.getSIFromEA()));\n};\n\n/**\n * FICOM16()\n *\n * @this {FPUX86}\n */\nFPUX86.FICOM16 = function()\n{\n this.doCompare(this.getST(0), this.getWIFromEA());\n};\n\n/**\n * FICOM32()\n *\n * @this {FPUX86}\n */\nFPUX86.FICOM32 = function()\n{\n this.doCompare(this.getST(0), this.getSIFromEA());\n};\n\n/**\n * FICOMP16()\n *\n * @this {FPUX86}\n */\nFPUX86.FICOMP16 = function()\n{\n if (this.doCompare(this.getST(0), this.getWIFromEA())) this.popValue();\n};\n\n/**\n * FICOMP32()\n *\n * @this {FPUX86}\n */\nFPUX86.FICOMP32 = function()\n{\n if (this.doCompare(this.getST(0), this.getSIFromEA())) this.popValue();\n};\n\n/**\n * FIDIV16()\n *\n * @this {FPUX86}\n */\nFPUX86.FIDIV16 = function()\n{\n this.setST(0, this.doDivide(this.getST(0), this.getWIFromEA()));\n};\n\n/**\n * FIDIV32()\n *\n * @this {FPUX86}\n */\nFPUX86.FIDIV32 = function()\n{\n this.setST(0, this.doDivide(this.getST(0), this.getSIFromEA()));\n};\n\n/**\n * FIDIVR16()\n *\n * @this {FPUX86}\n */\nFPUX86.FIDIVR16 = function()\n{\n this.setST(0, this.doDivide(this.getWIFromEA(), this.getST(0)));\n};\n\n/**\n * FIDIVR32()\n *\n * @this {FPUX86}\n */\nFPUX86.FIDIVR32 = function()\n{\n this.setST(0, this.doDivide(this.getSIFromEA(), this.getST(0)));\n};\n\n/**\n * FILD16()\n *\n * @this {FPUX86}\n */\nFPUX86.FILD16 = function()\n{\n this.pushValue(this.getWIFromEA());\n};\n\n/**\n * FILD32()\n *\n * @this {FPUX86}\n */\nFPUX86.FILD32 = function()\n{\n this.pushValue(this.getSIFromEA());\n};\n\n/**\n * FILD64()\n *\n * @this {FPUX86}\n */\nFPUX86.FILD64 = function()\n{\n this.pushValue(this.getLIFromEA());\n};\n\n/**\n * FIMUL16()\n *\n * @this {FPUX86}\n */\nFPUX86.FIMUL16 = function()\n{\n this.setST(0, this.doMultiply(this.getST(0), this.getWIFromEA()));\n};\n\n/**\n * FIMUL32()\n *\n * @this {FPUX86}\n */\nFPUX86.FIMUL32 = function()\n{\n this.setST(0, this.doMultiply(this.getST(0), this.getSIFromEA()));\n};\n\n/**\n * FINCSTP()\n *\n * @this {FPUX86}\n */\nFPUX86.FINCSTP = function()\n{\n this.iST = (this.iST + 1) & 0x7;\n this.regStatus &= ~X86.FPU.STATUS.C1;\n};\n\n/**\n * FINIT()\n *\n * @this {FPUX86}\n */\nFPUX86.FINIT = function()\n{\n this.resetFPU();\n};\n\n/**\n * FIST16()\n *\n * @this {FPUX86}\n */\nFPUX86.FIST16 = function()\n{\n if (this.getWI(0)) this.setEAFromWI();\n};\n\n/**\n * FIST32()\n *\n * @this {FPUX86}\n */\nFPUX86.FIST32 = function()\n{\n if (this.getSI(0)) this.setEAFromSI();\n};\n\n/**\n * FISTP16()\n *\n * @this {FPUX86}\n */\nFPUX86.FISTP16 = function()\n{\n if (this.getWI(0)) {\n this.setEAFromWI();\n this.popValue();\n }\n};\n\n/**\n * FISTP32()\n *\n * @this {FPUX86}\n */\nFPUX86.FISTP32 = function()\n{\n if (this.getSI(0)) {\n this.setEAFromSI();\n this.popValue();\n }\n};\n\n/**\n * FISTP64()\n *\n * @this {FPUX86}\n */\nFPUX86.FISTP64 = function()\n{\n if (this.getLI(0)) {\n this.setEAFromLI();\n this.popValue();\n }\n};\n\n/**\n * FISUB16()\n *\n * @this {FPUX86}\n */\nFPUX86.FISUB16 = function()\n{\n this.setST(0, this.doSubtract(this.getST(0), this.getWIFromEA()));\n};\n\n/**\n * FISUB32()\n *\n * @this {FPUX86}\n */\nFPUX86.FISUB32 = function()\n{\n this.setST(0, this.doSubtract(this.getST(0), this.getSIFromEA()));\n};\n\n/**\n * FISUBR16()\n *\n * @this {FPUX86}\n */\nFPUX86.FISUBR16 = function()\n{\n this.setST(0, this.doSubtract(this.getWIFromEA(), this.getST(0)));\n};\n\n/**\n * FISUBR32()\n *\n * @this {FPUX86}\n */\nFPUX86.FISUBR32 = function()\n{\n this.setST(0, this.doSubtract(this.getSIFromEA(), this.getST(0)));\n};\n\n/**\n * FLDlr()\n *\n * The FLD instruction loads the source operand, converts it to temporary real format (if required),\n * and pushes the resulting value onto the floating-point stack.\n *\n * The load operation is accomplished by decrementing the top-of-stack pointer (TOP) and copying the\n * source operand to the new stack top. If the source operand is a float ing-point register, the index of\n * the register is taken before TOP is changed. The source operand may also be a short real, long real,\n * or temporary real memory operand. Short real and long real operands are converted automatically.\n *\n * Note that coding the instruction FLD ST(0) duplicates the value at the stack top.\n *\n * On the 8087 and 80287, the FLD real80 instruction will raise the denormal exception if the memory\n * operand is a denormal. The 80287XL and later coprocessors will not, since the operation is not arithmetic.\n *\n * On the 8087 and 80287, a denormal will be converted to an unnormal by FLD; on the 80287XL and later\n * coprocessors, the number will be converted to temporary real. If the next instruction is an FXTRACT or FXAM,\n * the 8087/80827 and 80287XL/80387/ 80486 results will be different.\n *\n * On the 8087 and 80287, the FLD real32 and FLD real64 instructions will not raise an exception when loading\n * a signaling NaN; on the 80287XL and later coprocessors, loading a signaling NaN raises the invalid operation\n * exception.\n *\n * @this {FPUX86}\n */\nFPUX86.FLDlr = function()\n{\n this.pushValue(this.getLRFromEA());\n};\n\n/**\n * FLDsr()\n *\n * @this {FPUX86}\n */\nFPUX86.FLDsr = function()\n{\n this.pushValue(this.getSRFromEA());\n};\n\n/**\n * FLDsti()\n *\n * @this {FPUX86}\n */\nFPUX86.FLDsti = function()\n{\n this.pushValue(this.getST(this.iStack));\n};\n\n/**\n * FLDtr()\n *\n * @this {FPUX86}\n */\nFPUX86.FLDtr = function()\n{\n this.pushValue(this.getLRFromTR(this.getTRFromEA()));\n};\n\n/**\n * FLDCW()\n *\n * @this {FPUX86}\n */\nFPUX86.FLDCW = function()\n{\n\n this.setControl(this.cpu.getShort(this.cpu.regEA));\n};\n\n/**\n * FLDENV()\n *\n * @this {FPUX86}\n */\nFPUX86.FLDENV = function()\n{\n\n this.loadEnv(this.cpu.regEA);\n};\n\n/**\n * FLD1()\n *\n * The FLD1 instruction loads the constant +1.0 from the NPX's constant ROM and pushes the value onto the\n * floating-point stack.\n *\n * The constant is stored internally in temporary real format and is simply moved to the stack.\n *\n * See also: FLDLG2, FLDLN2, FLDL2E, FLDL2T, FLDPI, and FLD1.\n *\n * @this {FPUX86}\n */\nFPUX86.FLD1 = function()\n{\n this.pushValue(1.0);\n};\n\n/**\n * FLDL2T()\n *\n * The FLDL2T instruction loads the constant log2(10) from the NPX's constant ROM and pushes the value onto the\n * floating-point stack.\n *\n * The constant is stored internally in temporary real format and is simply moved to the stack.\n *\n * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and\n * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0), round down (toward\n * -infinity), or round to nearest or even, the result will be the same as on the 8087 and 80287. If RC is set for\n * round up (toward +infinity), the result will differ by one in the least significant bit of the mantissa.\n *\n * See also: FLDLG2, FLDLN2, FLDL2E, FLDPI, FLD1, and FLDZ.\n *\n * @this {FPUX86}\n */\nFPUX86.FLDL2T = function()\n{\n this.pushValue(FPUX86.regL2T);\n};\n\n/**\n * FLDL2E()\n *\n * The FLDL2E instruction loads the constant log2(e) from the NPX's constant ROM and pushes the value onto the\n * floating-point stack.\n *\n * The constant is stored internally in temporary real format and is simply moved to the stack.\n *\n * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and\n * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward\n * -infinity), the result is the same as on the 8087 and 80827. If RC is set for round to nearest or even, or round\n * up (toward +infinity), the result will differ by one in the least significant bit of the mantissa.\n *\n * See also: FLDLG2, FLDLN2, FLDL2T, FLDPI, FLD1, and FLDZ.\n *\n * @this {FPUX86}\n */\nFPUX86.FLDL2E = function()\n{\n this.pushValue(FPUX86.regL2E);\n};\n\n/**\n * FLDPI()\n *\n * The FLDPI instruction loads the constant Pi from the NPX's constant ROM and pushes the value onto the\n * floating-point stack.\n *\n * The constant is stored internally in temporary real format and is simply moved to the stack.\n *\n * On the 8087 and 80287, rounding control is not in effect for the loading of these constants. On the 80287XL and\n * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward\n * -infinity), the result is the same as on the 8087 and 80827. If RC is set for round to nearest or even, or round\n * up (toward +infinity), the result will differ by one in the least significant bit of the mantissa.\n *\n * See also: FLDLG2, FLDLN2, FLDL2E, FLDL2T, FLD1, and FLDZ.\n *\n * @this {FPUX86}\n */\nFPUX86.FLDPI = function()\n{\n this.pushValue(FPUX86.regPI);\n};\n\n/**\n * FLDLG2()\n *\n * The FLDLG2 instruction loads the constant log10(2) from the NPX's constant ROM and pushes the value onto the\n * floating-point stack.\n *\n * The constant is stored internally in temporary real format and is simply moved to the stack.\n *\n * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and\n * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward\n * -infinity), the result is the same as on the 8087 and 80827. If RC is set for round to nearest or even, or round\n * up (toward +infinity), the result will differ by one in the least significant bit of the mantissa.\n *\n * See also: FLDLN2, FLDL2E, FLDL2T, FLDPI, FLD1, and FLDZ.\n *\n * @this {FPUX86}\n */\nFPUX86.FLDLG2 = function()\n{\n this.pushValue(FPUX86.regLG2);\n};\n\n/**\n * FLDLN2()\n *\n * The FLDLN2 instruction loads the constant loge(2) from the NPX's constant ROM and pushes the value onto the\n * floating-point stack.\n *\n * The constant is stored internally in temporary real format and is simply moved to the stack.\n *\n * On the 8087 and 80287, rounding control is not in effect for the loading of this constant. On the 80287XL and\n * later coprocessors, rounding control is in effect. If RC is set for chop (round toward 0) or round down (toward\n * -infinity), the result will be the same as on the 8087 and 80827. If RC is set for round to nearest or even, or\n * round up (toward +infinity), the result will differ by one in the least significant bit of the mantissa.\n *\n * See also: FLDLG2, FLDL2E, FLDL2T, FLDPI, FLD1, and FLDZ.\n *\n * @this {FPUX86}\n */\nFPUX86.FLDLN2 = function()\n{\n this.pushValue(FPUX86.regLN2);\n};\n\n/**\n * FLDZ()\n *\n * The FLDZ instruction loads the constant +0.0 from the NPX's constant ROM and pushes the value onto the\n * floating-point stack.\n *\n * The constant is stored internally in temporary real format and is simply moved to the stack.\n *\n * See also: FLDLG2, FLDLN2, FLDL2E, FLDL2T, FLDPI, and FLD1.\n *\n * @this {FPUX86}\n */\nFPUX86.FLDZ = function()\n{\n this.pushValue(0.0);\n};\n\n/**\n * FMULlr()\n *\n * @this {FPUX86}\n */\nFPUX86.FMULlr = function()\n{\n this.setST(0, this.doMultiply(this.getST(0), this.getLRFromEA()));\n};\n\n/**\n * FMULsr()\n *\n * Encoding 0xD8,reg=0x01 (\"FMUL short-real\"): ST(0) <- ST(0) * REAL32\n *\n * @this {FPUX86}\n */\nFPUX86.FMULsr = function()\n{\n this.setST(0, this.doMultiply(this.getST(0), this.getSRFromEA()));\n};\n\n/**\n * FMULst()\n *\n * @this {FPUX86}\n */\nFPUX86.FMULst = function()\n{\n this.setST(0, this.doMultiply(this.getST(0), this.getST(this.iStack)));\n};\n\n/**\n * FMULsti()\n *\n * @this {FPUX86}\n */\nFPUX86.FMULsti = function()\n{\n this.setST(this.iStack, this.doMultiply(this.getST(this.iStack), this.getST(0)));\n};\n\n/**\n * FMULPsti()\n *\n * @this {FPUX86}\n */\nFPUX86.FMULPsti = function()\n{\n if (this.setST(this.iStack, this.doMultiply(this.getST(this.iStack), this.getST(0)))) this.popValue();\n};\n\n/**\n * FNOP()\n *\n * @this {FPUX86}\n */\nFPUX86.FNOP = function()\n{\n};\n\n/**\n * FPATAN()\n *\n * FPATAN calculates the partial arctangent of ST(0) divided by ST(1):\n *\n * ST(1) = tan^-1( ST(1) / ST(0) )\n *\n * On the 8087 and 80287, the arguments must satisfy the inequality 0 <= ST(1) < ST(0) < +infinity.\n * On the 80287XL and later coprocessors, the range of the operands is unrestricted. The result is\n * returned to ST(1), and the stack is popped, destroying both operands and leaving the result in ST(0).\n *\n * @this {FPUX86}\n */\nFPUX86.FPATAN = function()\n{\n if (this.setST(1, Math.atan2(this.getST(1), this.getST(0)))) this.popValue();\n};\n\n/**\n * FPTAN()\n *\n * FPTAN calculates the partial tangent of ST(0):\n *\n * y / x = tan( ST(0) )\n *\n * The result of the operation is a ratio. y replaces the argument on the stack, and x is pushed onto the stack,\n * where it becomes the new ST(0).\n *\n * On the 8087 and 80287, the FPTAN function assumes that its argument is valid and in-range. No argument checking\n * is performed. The value of ST(0) must satisfy the inequality -pi/4 <= ST(0) <= pi/4. In the case of an invalid\n * argument, the result is undefined and no error is signaled.\n *\n * On the 80287XL and later coprocessors, if value of ST(0) satisfies the condition -2^63 < ST(0) < 2^63, it will\n * automatically be reduced to within range. If the operand is outside this range, however, C2 is set to 1 to indicate\n * that the function is incomplete, and ST(0) is left unchanged.\n *\n * The 80287XL, 80387, and 80486 always push a value of +1.0 for x. The value of x pushed by the 8087 and 80287 may be\n * any real number. In either case, the ratio is the same. The cotangent can be calculated by executing FDIVR immediately\n * after FPTAN. The following code will leave the 8087 and 80287 in the same state as the later coprocessors:\n *\n * FDIV\n * FLD1\n *\n * ST(7) must be empty before this instruction is executed to avoid an invalid operation exception. If the invalid\n * operation exception is masked, the 8087 and 80287 leave the original operand unchanged, but push it to ST(1). On the\n * 80287XL and later coprocessors, both ST(0) and ST(1) will contain quiet NaNs. On the 80287XL and later coprocessors,\n * if condition code bit C2 is 0 and the precision exception is raised, then C1=1 if the last bit was rounded up. C1 is\n * undefined for the 8087 and 80287.\n *\n * @this {FPUX86}\n */\nFPUX86.FPTAN = function()\n{\n if (this.setST(0, Math.tan(this.getST(0)))) this.pushValue(1.0);\n};\n\n/**\n * FPREM()\n *\n * FPREM performs modulo division of ST(0) by ST(1) and returns the result to ST(0).\n *\n * The FPREM instruction is used to reduce the real operand in ST(0) to a value whose magnitude is less than the\n * magnitude of ST(1). FPREM produces an exact result, so the precision exception is never raised and the rounding\n * control has no effect. The sign of the remainder is the same as the sign of the original operand.\n *\n * The remaindering operation is performed by iterative scaled subtractions and can reduce the exponent of ST(0) by\n * no more than 63 in one execution. If the remainder is less than ST(1) (the modulus), the function is complete and\n * C2 in the status word is cleared.\n *\n * If the modulo function is incomplete, C2 is set to 1, and the result in ST(0) is termed the partial remainder.\n * C2 can be inspected by storing the status word and re-executing the instruction until C2 is clear. Alternately,\n * ST(0) can be compared to ST(1). If ST(0) > ST(1), then FPREM must be executed again. If ST(0) = ST(1), then the\n * remainder is 0.\n *\n * FPREM is important for reducing arguments to the periodic transcendental functions such as FPTAN. Because FPREM\n * produces an exact result, no round-off error is introduced into the calculation.\n *\n * When reduction is complete, the three least-significant bits of the quotient are stored in the condition code bits\n * C3, C1, and C0, respectively. When arguments to the tangent function are reduced by pi/4, this result can be used\n * to identify the octant that contained the original angle.\n *\n * The FPREM function operates differently than specified by the IEEE 754 standard when rounding the quotient to form\n * a partial remainder (see the algorithm). The FPREM1 function (80287XL and up) is provided for compatibility with\n * that standard.\n *\n * The FPREM instruction can also be used to normalize ST(0). If ST(0) is unnormal and ST(1) is greater than ST(0),\n * FPREM will normalize ST(0). On the 8087 and 80287, operation on a denormal operand raises the invalid operation\n * exception. Underflow is not possible. On the 80287XL and later coprocessors, operation on a denormal is supported\n * and an underflow exception can occur.\n *\n * ALGORITHM:\n *\n * t = EXPONENT(ST) - EXPONENT(ST(1))\n * IF (t < 64) THEN\n * q = R0UND(ST(0) / ST(1), CHOP)\n * ST(0) = ST(0) - (ST(1) * q)\n * C2 = 0\n * C0 = BIT 2 of q\n * C1 = BIT 1 of q\n * C3 = BIT 0 of q\n * ELSE\n * n = a number between 32 and 63\n * q = ROUND((ST(0) / ST(1)) / 2^(t-n), CHOP)\n * ST(0) = ST(0) - (ST(1) * q * 2^(t-n))\n * C2 = 1\n * ENDIF\n *\n * TODO: Determine the extent to which the JavaScript MOD operator differs from the above algorithm.\n *\n * ERRATA: On the 8087 and 80287, the condition code bits C3, C1, and C0 are incorrect when performing a reduction of\n * 64^n + m, where n >= 1, and m=1 or m=2. A bug fix should be implemented in software.\n *\n * @this {FPUX86}\n */\nFPUX86.FPREM = function()\n{\n this.setST(0, this.getST(0) % this.getST(1));\n};\n\n/**\n * FRSTOR()\n *\n * @this {FPUX86}\n */\nFPUX86.FRSTOR = function()\n{\n var cpu = this.cpu;\n var addr = this.loadEnv(cpu.regEA);\n var a = this.intTmpTR;\n for (var i = 0; i < this.regStack.length; i++) {\n a[0] = cpu.getLong(addr);\n a[1] = cpu.getLong(addr += 4);\n a[2] = cpu.getShort(addr += 4);\n this.setTR(i, a);\n addr += 2;\n }\n};\n\n/**\n * FRNDINT()\n *\n * @this {FPUX86}\n */\nFPUX86.FRNDINT = function()\n{\n this.setST(0, this.roundValue(this.getST(0), FPUX86.MAX_INT64));\n};\n\n/**\n * FSAVE()\n *\n * @this {FPUX86}\n */\nFPUX86.FSAVE = function()\n{\n var cpu = this.cpu;\n var addr = this.saveEnv(cpu.regEA);\n for (var i = 0; i < this.regStack.length; i++) {\n var a = this.getTR(i, true);\n cpu.setLong(addr, a[0]);\n cpu.setLong(addr += 4, a[1]);\n cpu.setShort(addr += 4, a[2]);\n addr += 2;\n }\n this.resetFPU();\n};\n\n/**\n * FSCALE()\n *\n * FSCALE interprets the value in ST(1) as an integer and adds this number to the exponent of the number in ST(0).\n *\n * The FSCALE instruction provides a means of quickly performing multiplication or division by powers of two.\n * This operation is often required when scaling array indexes.\n *\n * On the 8087 and 80287, FSCALE assumes that the scale factor in ST(1) is an integer that satisfies the inequality\n * -2^15 <= ST(1) < +2^15. If ST(1) is not an integer value, the value is chopped to the next smallest integer in\n * magnitude (chopped toward zero). If the value is out of range or 0 < ST(1) < 1, FSCALE produces an undefined\n * result and doesn't signal an exception. Typically, the value in ST(0) is unchanged but should not be depended on.\n *\n * On the 80287XL and later coprocessors, there is no limit on the range of the scale factor in ST(1). The value in\n * ST(1) is still chopped toward zero. If ST(1) is 0, ST(0) is unchanged.\n *\n * @this {FPUX86}\n */\nFPUX86.FSCALE = function()\n{\n var x = this.getST(0);\n var y = this.getST(1);\n if (x != null && y != null) this.setST(0, x * Math.pow(2, this.truncateValue(y)));\n};\n\n/**\n * FSETPM287()\n *\n * @this {FPUX86}\n */\nFPUX86.FSETPM287 = function()\n{\n if (this.isModel(X86.FPU.MODEL_80287)) {\n this.opUnimplemented();\n }\n};\n\n/**\n * FSINCOS387()\n *\n * @this {FPUX86}\n */\nFPUX86.FSINCOS387 = function()\n{\n if (this.isAtLeastModel(X86.FPU.MODEL_80287XL)) {\n this.opUnimplemented();\n }\n};\n\n/**\n * FSQRT()\n *\n * @this {FPUX86}\n */\nFPUX86.FSQRT = function()\n{\n this.setST(0, this.doSquareRoot(this.getST(0)));\n};\n\n/**\n * FSTlr()\n *\n * @this {FPUX86}\n */\nFPUX86.FSTlr = function()\n{\n if (this.getLR(0)) this.setEAFromLR();\n};\n\n/**\n * FSTsr()\n *\n * @this {FPUX86}\n */\nFPUX86.FSTsr = function()\n{\n if (this.getSR(0)) this.setEAFromSR();\n};\n\n/**\n * FSTsti()\n *\n * @this {FPUX86}\n */\nFPUX86.FSTsti = function()\n{\n this.setST(this.iStack, this.getST(0));\n};\n\n/**\n * FSTENV()\n *\n * @this {FPUX86}\n */\nFPUX86.FSTENV = function()\n{\n\n this.saveEnv(this.cpu.regEA);\n this.regControl |= X86.FPU.CONTROL.EXC; // mask all exceptions (but do not set IEM)\n};\n\n/**\n * FSTPlr()\n *\n * @this {FPUX86}\n */\nFPUX86.FSTPlr = function()\n{\n if (this.getLR(0)) {\n this.setEAFromLR();\n this.popValue();\n }\n};\n\n/**\n * FSTPsr()\n *\n * @this {FPUX86}\n */\nFPUX86.FSTPsr = function()\n{\n if (this.getSR(0)) {\n this.setEAFromSR();\n this.popValue();\n }\n};\n\n/**\n * FSTPsti()\n *\n * @this {FPUX86}\n */\nFPUX86.FSTPsti = function()\n{\n if (this.setST(this.iStack, this.getST(0))) this.popValue();\n};\n\n/**\n * FSTP8087()\n *\n * NOTE: This is used with encodings (0xD9,0xD8-0xDF and 0xDF,0xD0-0xDF) that were valid for the 8087 and 80287\n * but may no longer be valid as of the 80387.\n *\n * @this {FPUX86}\n */\nFPUX86.FSTP8087 = function()\n{\n this.opObsolete();\n FPUX86.FSTPsti.call(this);\n};\n\n/**\n * FSTPtr()\n *\n * @this {FPUX86}\n */\nFPUX86.FSTPtr = function()\n{\n if (this.getTR(0)) {\n this.setEAFromTR();\n this.popValue();\n }\n};\n\n/**\n * FSTCW()\n *\n * @this {FPUX86}\n */\nFPUX86.FSTCW = function()\n{\n\n this.cpu.setShort(this.cpu.regEA, this.regControl);\n};\n\n/**\n * FSTSW()\n *\n * @this {FPUX86}\n */\nFPUX86.FSTSW = function()\n{\n\n this.cpu.setShort(this.cpu.regEA, this.getStatus());\n};\n\n/**\n * FSTSWAX287()\n *\n * @this {FPUX86}\n */\nFPUX86.FSTSWAX287 = function()\n{\n if (this.isAtLeastModel(X86.FPU.MODEL_80287)) {\n this.cpu.regEAX = (this.cpu.regEAX & ~0xffff) | this.getStatus();\n }\n};\n\n/**\n * FSUBlr()\n *\n * @this {FPUX86}\n */\nFPUX86.FSUBlr = function()\n{\n this.setST(0, this.doSubtract(this.getST(0), this.getLRFromEA()));\n};\n\n/**\n * FSUBsr()\n *\n * @this {FPUX86}\n */\nFPUX86.FSUBsr = function()\n{\n this.setST(0, this.doSubtract(this.getST(0), this.getSRFromEA()));\n};\n\n/**\n * FSUBst()\n *\n * Encoding 0xD8,0xE0-0xE7 (\"FSUB ST,ST(i)\"): ST(0) <- ST(0) - ST(i)\n *\n * @this {FPUX86}\n */\nFPUX86.FSUBst = function()\n{\n this.setST(0, this.doSubtract(this.getST(0), this.getST(this.iStack)));\n};\n\n/**\n * FSUBsti()\n *\n * Encoding 0xDC,0xE8-0xEF (\"FSUB ST(i),ST\"): ST(i) <- ST(i) - ST(0)\n *\n * @this {FPUX86}\n */\nFPUX86.FSUBsti = function()\n{\n this.setST(this.iStack, this.doSubtract(this.getST(this.iStack), this.getST(0)));\n};\n\n/**\n * FSUBPsti()\n *\n * Encoding 0xDE,0xE8-0xEF (\"FSUBP ST(i),ST\"): ST(i) <- ST(i) - ST(0), POP\n *\n * @this {FPUX86}\n */\nFPUX86.FSUBPsti = function()\n{\n if (this.setST(this.iStack, this.doSubtract(this.getST(this.iStack), this.getST(0)))) this.popValue();\n};\n\n/**\n * FSUBRlr()\n *\n * @this {FPUX86}\n */\nFPUX86.FSUBRlr = function()\n{\n this.setST(0, this.doSubtract(this.getLRFromEA(), this.getST(0)));\n};\n\n/**\n * FSUBRsr()\n *\n * @this {FPUX86}\n */\nFPUX86.FSUBRsr = function()\n{\n this.setST(0, this.doSubtract(this.getSRFromEA(), this.getST(0)));\n};\n\n/**\n * FSUBRst()\n *\n * Encoding 0xD8,0xE8-0xEF (\"FSUBR ST,ST(i)\"): ST(0) <- ST(i) - ST(0)\n *\n * @this {FPUX86}\n */\nFPUX86.FSUBRst = function()\n{\n this.setST(0, this.doSubtract(this.getST(this.iStack), this.getST(0)));\n};\n\n/**\n * FSUBRsti()\n *\n * Encoding 0xDC,0xE0-0xE7 (\"FSUBR ST(i),ST\"): ST(i) <- ST(0) - ST(i)\n *\n * @this {FPUX86}\n */\nFPUX86.FSUBRsti = function()\n{\n this.setST(this.iStack, this.doSubtract(this.getST(0), this.getST(this.iStack)));\n};\n\n/**\n * FSUBRPsti()\n *\n * Encoding 0xDE,0xE0-0xE7 (\"FSUBRP ST(i),ST\"): ST(i) <- ST(0) - ST(i), POP\n *\n * @this {FPUX86}\n */\nFPUX86.FSUBRPsti = function()\n{\n if (this.setST(this.iStack, this.doSubtract(this.getST(0), this.getST(this.iStack)))) this.popValue();\n};\n\n/**\n * FTST()\n *\n * @this {FPUX86}\n */\nFPUX86.FTST = function()\n{\n this.doCompare(this.getST(0), 0);\n};\n\n/**\n * FXAM()\n *\n * @this {FPUX86}\n */\nFPUX86.FXAM = function()\n{\n this.regStatus &= ~X86.FPU.STATUS.CC;\n\n if (this.getSTSign(0)) {\n this.regStatus |= X86.FPU.STATUS.C1;\n }\n if (this.getTag(this.iST) == X86.FPU.TAGS.EMPTY) {\n this.regStatus |= X86.FPU.STATUS.C0 | X86.FPU.STATUS.C3;\n }\n else {\n var v = this.getST(0);\n if (isNaN(v)) {\n this.regStatus |= X86.FPU.STATUS.C0;\n }\n else if (v === 0) { // this equals -0, too (WTF, strict equality?)\n this.regStatus |= X86.FPU.STATUS.C3;\n }\n else if (v === Infinity || v === -Infinity) { // these are so divergent that even non-strict equality doesn't consider them equal\n this.regStatus |= X86.FPU.STATUS.C0 | X86.FPU.STATUS.C2;\n }\n else {\n this.regStatus |= X86.FPU.STATUS.C2;\n }\n }\n};\n\n/**\n * FXCHsti()\n *\n * @this {FPUX86}\n */\nFPUX86.FXCHsti = function()\n{\n var tmp = this.getST(0);\n this.setST(0, this.getST(this.iStack));\n this.setST(this.iStack, tmp);\n};\n\n/**\n * FXCH8087()\n *\n * NOTE: This is used with encodings (0xDD,0xC8-0xCF and 0xDF,0xC8-0xCF) that were valid for the 8087 and 80287\n * but may no longer be valid as of the 80387.\n *\n * @this {FPUX86}\n */\nFPUX86.FXCH8087 = function()\n{\n this.opObsolete();\n FPUX86.FXCHsti.call(this);\n};\n\n/**\n * FXTRACT()\n *\n * FXTRACT splits the value encoded in ST(0) into two separate numbers representing the actual value of the\n * fraction (mantissa) and exponent fields.\n *\n * The FXTRACT instruction is used to decompose the two fields of the temporary real number in ST(0). The exponent\n * replaces the value in ST(0), then the fraction is pushed onto the stack. When execution is complete, ST(0)\n * contains the original fraction, expressed as a real number with a true exponent of 0 (0x3FFF in biased form),\n * and ST(1) contains the value of the original operand's true (unbiased) exponent expressed as a real number.\n *\n * If ST(0) is 0, the 8087 and 80287 will leave zeros in both ST(0) and ST(1); both zeros will have the same sign as\n * the original operand. If ST(0) is +infinity, the invalid operation exception is raised.\n *\n * On the 80287XL and later coprocessors, if ST(0) is 0, the zero-divide exception is reported and ST(1) is set to\n * -infinity. If ST(0) is +infinity, no exception is reported.\n *\n * The FXTRACT instruction may be thought of as the complement to the FSCALE instruction, which combines a separate\n * fraction and exponent into a single value.\n *\n * ALGORITHM:\n *\n * IF (ST(0) = 0) THEN\n * DEC TOP\n * ST(0) = ST(1)\n * ELSE\n * temp = ST(0)\n * ST(0) = EXPONENT(ST(0)) ; stored as true exponent\n * DEC TOP\n * ST(0) = FRACTION(ST(0))\n * ENDIF\n *\n * @this {FPUX86}\n */\nFPUX86.FXTRACT = function()\n{\n var v = this.getST(0);\n if (v != null) {\n this.regTmpLR[0] = v;\n this.setST(0, ((this.intTmpLR[1] >> 20) & 0x7ff) - 0x3ff);\n this.intTmpLR[1] = (this.intTmpLR[1] | 0x3ff00000) & ~0x40000000;\n this.pushValue(this.regTmpLR[0]);\n }\n};\n\n/**\n * FYL2X()\n *\n * FYL2X (y log base 2 of x) calculates:\n *\n * ST(1) = ST(1) * log2(ST(0))\n *\n * The operands must satisfy the inequalities 0 < ST(0) < +infinity and -infinity < ST(1) < +infinity. FYL2X pops\n * the stack and returns the result to the new ST(0). Both original operands are destroyed.\n *\n * The FYL2X function is designed to optimize the calculation of a log to a base, n, other than two. In such a case,\n * the following multiplication is required; ie:\n *\n * logn(x) = logn(2) * log2(x)\n *\n * @this {FPUX86}\n */\nFPUX86.FYL2X = function()\n{\n if (this.setST(1, this.getST(1) * Math.log(this.getST(0)) / Math.LN2)) this.popValue();\n};\n\n/**\n * FYL2XP1()\n *\n * FYL2XP1 (y log base 2 of x plus 1) calculates:\n *\n * ST(1) = ST(1) * log2(ST(0) + 1)\n *\n * The operands must satisfy the inequalities -(1-sqrt(2)/2) < ST(0) < (1-sqrt(2)/2) and -infinity < ST(1) < +infinity.\n * FYL2XP1 pops the stack and returns the result to the new ST(0). Both original operands are destroyed.\n *\n * The FYL2XP1 function provides greater accuracy than FYL2X in computing the log of a number that is very close to 1.\n *\n * FYL2XP1 is typically used when computing compound interest, for example, which requires the calculation of a logarithm\n * of 1.0 + n where 0 < n < 0.29. If 1.0 was added to n, significant digits might be lost. By using FYL2XP1, the result\n * will be as accurate as n to within three units of temporary real precision.\n *\n * @this {FPUX86}\n */\nFPUX86.FYL2XP1 = function()\n{\n if (this.setST(1, this.getST(1) * Math.log(this.getST(0) + 1.0) / Math.LN2)) this.popValue();\n};\n\n/*\n * Class constants\n *\n * TODO: When loading any of the following 5 constants, the 80287XL and newer coprocessors apply rounding control.\n */\n\n/** @const */\nFPUX86.regL2T = Math.log(10) / Math.LN2; // log2(10) (use Math.log2() if we ever switch to ES6)\n\n/** @const */\nFPUX86.regL2E = Math.LOG2E; // log2(e)\n\n/** @const */\nFPUX86.regPI = Math.PI; // pi\n\n/** @const */\nFPUX86.regLG2 = Math.log(2) / Math.LN10; // log10(2) (use Math.log10() if we ever switch to ES6)\n\n/** @const */\nFPUX86.regLN2 = Math.LN2; // log(2)\n\n/** @const */\nFPUX86.MAX_INT16 = 0x8000;\n\n/** @const */\nFPUX86.MAX_INT32 = 0x80000000;\n\n/** @const */\nFPUX86.MAX_INT64 = Math.pow(2, 63);\n\n\n/*\n * FPU operation lookup table (be sure to keep the following table in sync with Debugger.aaaOpFPUDescs).\n *\n * The second lookup value corresponds to bits in the ModRegRM byte that follows the ESC byte (0xD8-0xDF).\n *\n * Here's a little cheat-sheet for how the 2nd lookup values relate to ModRegRM values; see opFPU() for details.\n *\n * Lookup ModRegRM value(s)\n * ------ -------------------------------\n * 0x00: 0x00-0x07, 0x40-0x47, 0x80-0x87\n * 0x01: 0x08-0x0F, 0x48-0x4F, 0x88-0x8F\n * 0x02: 0x10-0x17, 0x50-0x57, 0x90-0x97\n * 0x03: 0x18-0x1F, 0x58-0x5F, 0x98-0x9F\n * 0x04: 0x20-0x27, 0x60-0x67, 0xA0-0xA7\n * 0x05: 0x28-0x2F, 0x68-0x6F, 0xA8-0xAF\n * 0x06: 0x30-0x37, 0x70-0x77, 0xB0-0xB7\n * 0x07: 0x38-0x3F, 0x78-0x7F, 0xB8-0xBF\n * 0x30: 0xC0-0xC7\n * 0x31: 0xC8-0xCF\n * 0x32: 0xD0-0xD7\n * 0x33: 0xD8-0xDF\n * 0x34: 0xE0-0xE7\n * 0x35: 0xE8-0xEF\n * 0x36: 0xF0-0xF7\n * 0x37: 0xF8-0xFF\n *\n * ESC bytes 0xD9 and 0xDB use the RM field to further describe the operation when the ModRegRM value >= 0xE0.\n * In those cases, we shift the Reg value into the high nibble and the RM value into the low nibble, resulting in\n * the following lookup values (which look a lot like hex-encoded octal):\n *\n * 0x40: 0xE0\n * 0x41: 0xE1\n * ... ...\n * 0x46: 0xE6\n * 0x47: 0xE7\n *\n * 0x50: 0xE8\n * 0x51: 0xE9\n * ... ...\n * 0x56: 0xEE\n * 0x57: 0xEF\n *\n * 0x60: 0xF0\n * 0x61: 0xF1\n * ... ...\n * 0x66: 0xF6\n * 0x67: 0xF7\n *\n * 0x70: 0xF8\n * 0x71: 0xF9\n * ... ...\n * 0x76: 0xFE\n * 0x77: 0xFF\n */\nFPUX86.aaOps = {\n 0xD8: {\n 0x00: FPUX86.FADDsr, 0x01: FPUX86.FMULsr, 0x02: FPUX86.FCOMsr, 0x03: FPUX86.FCOMPsr,\n 0x04: FPUX86.FSUBsr, 0x05: FPUX86.FSUBRsr, 0x06: FPUX86.FDIVsr, 0x07: FPUX86.FDIVsr,\n 0x30: FPUX86.FADDst, 0x31: FPUX86.FMULst, 0x32: FPUX86.FCOMst, 0x33: FPUX86.FCOMPst,\n 0x34: FPUX86.FSUBst, 0x35: FPUX86.FSUBRst, 0x36: FPUX86.FDIVst, 0x37: FPUX86.FDIVRst\n },\n 0xD9: {\n 0x00: FPUX86.FLDsr, 0x02: FPUX86.FSTsr, 0x03: FPUX86.FSTPsr,\n 0x04: FPUX86.FLDENV, 0x05: FPUX86.FLDCW, 0x06: FPUX86.FSTENV, 0x07: FPUX86.FSTCW,\n 0x30: FPUX86.FLDsti, 0x31: FPUX86.FXCHsti, 0x32: FPUX86.FNOP, 0x33: FPUX86.FSTP8087,\n 0x40: FPUX86.FCHS, 0x41: FPUX86.FABS,\n 0x44: FPUX86.FTST, 0x45: FPUX86.FXAM,\n 0x50: FPUX86.FLD1, 0x51: FPUX86.FLDL2T, 0x52: FPUX86.FLDL2E, 0x53: FPUX86.FLDPI,\n 0x54: FPUX86.FLDLG2, 0x55: FPUX86.FLDLN2, 0x56: FPUX86.FLDZ,\n 0x60: FPUX86.F2XM1, 0x61: FPUX86.FYL2X, 0x62: FPUX86.FPTAN, 0x63: FPUX86.FPATAN,\n 0x64: FPUX86.FXTRACT, 0x66: FPUX86.FDECSTP, 0x67: FPUX86.FINCSTP,\n 0x70: FPUX86.FPREM, 0x71: FPUX86.FYL2XP1, 0x72: FPUX86.FSQRT,\n 0x74: FPUX86.FRNDINT, 0x75: FPUX86.FSCALE\n },\n 0xDA: {\n 0x00: FPUX86.FIADD32, 0x01: FPUX86.FIMUL32, 0x02: FPUX86.FICOM32, 0x03: FPUX86.FICOMP32,\n 0x04: FPUX86.FISUB32, 0x05: FPUX86.FISUBR32, 0x06: FPUX86.FIDIV32, 0x07: FPUX86.FIDIVR32\n },\n 0xDB: {\n 0x00: FPUX86.FILD32, 0x02: FPUX86.FIST32, 0x03: FPUX86.FISTP32,\n 0x05: FPUX86.FLDtr, 0x07: FPUX86.FSTPtr,\n 0x40: FPUX86.FENI8087, 0x41: FPUX86.FDISI8087, 0x42: FPUX86.FCLEX, 0x43: FPUX86.FINIT,\n 0x44: FPUX86.FSETPM287,\n 0x73: FPUX86.FSINCOS387\n },\n 0xDC: {\n 0x00: FPUX86.FADDlr, 0x01: FPUX86.FMULlr, 0x02: FPUX86.FCOMlr, 0x03: FPUX86.FCOMPlr,\n 0x04: FPUX86.FSUBlr, 0x05: FPUX86.FSUBRlr, 0x06: FPUX86.FDIVlr, 0x07: FPUX86.FDIVRlr,\n 0x30: FPUX86.FADDsti, 0x31: FPUX86.FMULsti, 0x32: FPUX86.FCOM8087, 0x33: FPUX86.FCOMP8087,\n /*\n * Intel's original 8087 datasheet had these forms of SUB and SUBR (and DIV and DIVR) swapped.\n */\n 0x34: FPUX86.FSUBRsti, 0x35: FPUX86.FSUBsti, 0x36: FPUX86.FDIVRsti, 0x37: FPUX86.FDIVsti\n },\n 0xDD: {\n 0x00: FPUX86.FLDlr, 0x02: FPUX86.FSTlr, 0x03: FPUX86.FSTPlr,\n 0x04: FPUX86.FRSTOR, 0x06: FPUX86.FSAVE, 0x07: FPUX86.FSTSW,\n 0x30: FPUX86.FFREEsti, 0x31: FPUX86.FXCH8087, 0x32: FPUX86.FSTsti, 0x33: FPUX86.FSTPsti\n },\n 0xDE: {\n 0x00: FPUX86.FIADD16, 0x01: FPUX86.FIMUL16, 0x02: FPUX86.FICOM16, 0x03: FPUX86.FICOMP16,\n 0x04: FPUX86.FISUB16, 0x05: FPUX86.FISUBR16, 0x06: FPUX86.FIDIV16, 0x07: FPUX86.FIDIVR16,\n 0x30: FPUX86.FADDPsti, 0x31: FPUX86.FMULPsti, 0x32: FPUX86.FCOMP8087, 0x33: FPUX86.FCOMPP,\n /*\n * Intel's original 8087 datasheet had these forms of SUBP and SUBRP (and DIVP and DIVRP) swapped.\n */\n 0x34: FPUX86.FSUBRPsti, 0x35: FPUX86.FSUBPsti, 0x36: FPUX86.FDIVRPsti, 0x37: FPUX86.FDIVPsti\n },\n 0xDF: {\n 0x00: FPUX86.FILD16, 0x02: FPUX86.FIST16, 0x03: FPUX86.FISTP16,\n 0x04: FPUX86.FBLDpd, 0x05: FPUX86.FILD64, 0x06: FPUX86.FBSTPpd, 0x07: FPUX86.FISTP64,\n 0x30: FPUX86.FFREEP8087,0x31: FPUX86.FXCH8087, 0x32: FPUX86.FSTP8087, 0x33: FPUX86.FSTP8087,\n 0x34: FPUX86.FSTSWAX287\n }\n};\n\n/*\n * An array of FPUX86 functions documented as preserving the \"exception\" registers.\n */\nFPUX86.afnPreserveExceptions = [\n FPUX86.FCLEX, FPUX86.FINIT, FPUX86.FLDCW, FPUX86.FLDENV, FPUX86.FRSTOR,\n FPUX86.FSAVE, FPUX86.FSTCW, FPUX86.FSTENV, FPUX86.FSTSW, FPUX86.FSTSWAX287\n];\n\n/*\n * Initialize every FPU module on the page\n */\nWeb.onInit(FPUX86.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/segx86.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * NOTE: The protected-mode support in this module was initially added for 80286 support, and is\n * currently being upgraded for 80386 support. In a perfect world, all 80386-related support would\n * be disabled/skipped whenever the processor is merely an 80286. And in fact, that's the case\n * with some of the early changes (eg, skipping X86.DESC.EXT.BASE2431 and X86.DESC.EXT.LIMIT1619\n * fields unless the processor is an 80386).\n *\n * However, the reality is that I won't always be that strict, either because I'm lazy or I don't\n * want to risk a run-time performance hit or (more pragmatically) because any 80286 code you're likely\n * to run probably won't attempt to use descriptor types or other features unique to the 80386 anyway,\n * so the extra paranoia may not be worth the effort. Ultimately, I would like to see the code tailor\n * itself to the current CPU model, generally with model-specific functions, but that's a lot of work.\n */\n\n/**\n * class SegX86\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass SegX86 {\n /**\n * SegX86(cpu, sName)\n *\n * @this {SegX86}\n * @param {CPUX86} cpu\n * @param {number} id\n * @param {string} [sName] segment register name\n * @param {boolean} [fProt] true if segment register used exclusively in protected-mode (eg, segLDT)\n */\n constructor(cpu, id, sName, fProt)\n {\n this.cpu = cpu;\n /**\n * @type {DebuggerX86}\n */\n this.dbg = cpu.dbg;\n this.id = id;\n this.sName = sName || \"\";\n this.sel = 0;\n this.limit = 0xffff;\n this.offMax = this.limit + 1;\n this.base = 0;\n this.acc = this.type = 0;\n this.ext = 0;\n this.cpl = this.dpl = 0;\n this.addrDesc = X86.ADDR_INVALID;\n this.sizeData = this.sizeAddr = 2;\n this.maskData = this.maskAddr = 0xffff;\n\n this.loadV86 = this.loadReal;\n this.checkReadV86 = this.checkReadWriteReal;\n this.checkWriteV86 = this.checkReadWriteReal;\n\n /*\n * Preallocated object for \"probed\" segment loads\n */\n this.probe = {\n sel: -1, base: 0, limit: 0, acc: 0, type: 0, ext: 0, addrDesc: X86.ADDR_INVALID\n };\n\n /*\n * The following properties are used for CODE segments only (ie, segCS); if the process of loading\n * CS also requires a stack switch, then fStackSwitch will be set to true; additionally, if the stack\n * switch was the result of a CALL (ie, fCall is true) and one or more (up to 32) parameters are on\n * the old stack, they will be copied to awParms, and then once the stack is switched, the parameters\n * will be pushed from awParms onto the new stack.\n *\n * The typical ways of loading a new segment into CS are JMPF, CALLF (or INT), and RETF (or IRET),\n * via CPU functions setCSIP() and helpINT(), which use segCS.loadCode() and segCS.loadIDT(), respectively.\n *\n * loadCode() requires an fCall value: null means NO privilege level transition may occur, true\n * allows a stack switch and a privilege transition to a numerically lower privilege, and false allows\n * a stack restore and a privilege transition to a numerically greater privilege.\n *\n * loadIDT() sets fCall to true unconditionally in protected-mode (fCall has no meaning in real-mode).\n */\n if (this.id == 1 /* SegX86.ID.CODE */) { // don't use SegX86.ID.CODE until it's defined, or the Closure Compiler won't inline it\n this.offIP = 0;\n this.fCall = null;\n this.fStackSwitch = false;\n this.awParms = new Array(32);\n this.aCallBreaks = [];\n }\n\n this.updateMode(true, fProt);\n\n if (this.id == 0 /* SegX86.ID.NULL */) {\n this.checkRead = this.checkReadWriteNone;\n this.checkWrite = this.checkReadWriteNone;\n }\n }\n\n /**\n * addCallBreak(fn)\n *\n * Returns a \"call break\" address in an [off, sel] array. The given function, fn(), is called\n * whenever that address is called, and if fn() returns false, then the call is skipped. Otherwise,\n * the call is performed (ie, the old CS:[E]IP is pushed on the stack, and CS:[E]IP is set to the\n * \"call break\" address. Which is probably a bad idea, so your function should probably always\n * return false. Just sayin'. TODO: Should probably just force all \"call break\" calls to be skipped.\n *\n * @this {SegX86}\n * @param {function()} fn\n * @return {Array.<number>} containing offset and selector of call-break address\n */\n addCallBreak(fn)\n {\n this.aCallBreaks.push(fn);\n return [this.aCallBreaks.length, SegX86.CALLBREAK_SEL];\n }\n\n /**\n * loadCode(off, sel, fCall)\n *\n * A simple wrapper function that encapsulates setting offIP and fCall for segCS loads.\n *\n * @this {SegX86}\n * @param {number} off\n * @param {number} sel\n * @param {boolean|undefined} fCall is true if CALLF in progress, false if RETF/IRET in progress, undefined otherwise\n * @return {number} base address of selected segment, or X86.ADDR_INVALID if error\n */\n loadCode(off, sel, fCall)\n {\n this.offIP = off;\n this.fCall = fCall;\n return this.load(sel);\n }\n\n /**\n * loadReal(sel, fProbe)\n *\n * The default segment load() function for real-mode.\n *\n * @this {SegX86}\n * @param {number} sel\n * @param {boolean} [fProbe] (here only to make the function signatures of loadReal() and loadProt() match)\n * @return {number} base address of selected segment\n */\n loadReal(sel, fProbe)\n {\n this.sel = sel & 0xffff;\n /*\n * Loading a new value into a segment register in real-mode alters ONLY the selector and the base;\n * all other attributes (eg, limit, operand size, address size, etc) are unchanged. If you run any\n * code that switches to protected-mode, loads a 32-bit code segment, and then switches back to\n * real-mode, it is THAT code's responsibility to load a 16-bit segment into CS before returning to\n * real-mode; otherwise, your machine will probably be toast.\n */\n return this.base = this.sel << 4;\n }\n\n /**\n * loadProt(sel, fProbe)\n *\n * This replaces the segment's default load() function whenever the segment is notified via updateMode() by the\n * CPU's setProtMode() that the processor is now in protected-mode.\n *\n * Segments in protected-mode are referenced by selectors, which are indexes into descriptor tables (GDT or LDT)\n * whose descriptors are 4-word (8-byte) entries:\n *\n * word 0: segment limit (0-15)\n * word 1: base address low\n * word 2: base address high (0-7), segment type (8-11), descriptor type (12), DPL (13-14), present bit (15)\n * word 3: used only on 80386 and up (should be set to zero for upward compatibility)\n *\n * See X86.DESC for offset and bit definitions.\n *\n * IDT descriptor entries are handled separately by loadIDT(), which is mapped to loadIDTReal() or loadIDTProt().\n *\n * @this {SegX86}\n * @param {number} sel\n * @param {boolean} [fProbe]\n * @return {number} base address of selected segment, or X86.ADDR_INVALID if error\n */\n loadProt(sel, fProbe)\n {\n var addrDT;\n var addrDTLimit;\n var cpu = this.cpu;\n\n /*\n * Some instructions (eg, CALLF) load a 32-bit value for the selector, while others (eg, LDS) do not;\n * however, in ALL cases, only the low 16 bits are significant.\n */\n sel &= 0xffff;\n\n if (!(sel & X86.SEL.LDT)) {\n addrDT = cpu.addrGDT;\n addrDTLimit = cpu.addrGDTLimit;\n } else {\n addrDT = cpu.segLDT.base;\n addrDTLimit = (addrDT + cpu.segLDT.limit)|0;\n }\n /*\n * The ROM BIOS POST executes some test code in protected-mode without properly initializing the LDT,\n * which has no bearing on the ROM's own code, because it never loads any LDT selectors, but if at the same\n * time our Debugger attempts to validate a selector in one of its breakpoints, that could cause some grief.\n *\n * Fortunately, the Debugger now has its own interface, probeDesc(), so that should no longer be a concern.\n */\n if (addrDT) {\n var addrDesc = (addrDT + (sel & X86.SEL.MASK))|0;\n if ((addrDTLimit - addrDesc)|0 >= 7) {\n /*\n * TODO: This is the first of many steps toward accurately counting cycles in protected mode;\n * I simply noted that \"POP segreg\" takes 5 cycles in real mode and 20 in protected mode, so I'm\n * starting with a 15-cycle difference. Obviously the difference will vary with the instruction,\n * and will be much greater whenever the load fails.\n */\n cpu.nStepCycles -= 15;\n return this.loadDesc8(addrDesc, sel, fProbe);\n }\n if (this.id < SegX86.ID.VER) {\n X86.helpFault.call(cpu, fProbe && this.id == SegX86.ID.STACK? X86.EXCEPTION.TS_FAULT : X86.EXCEPTION.GP_FAULT, sel & X86.ERRCODE.SELMASK);\n }\n }\n return X86.ADDR_INVALID;\n }\n\n /**\n * loadIDTReal(nIDT)\n *\n * @this {SegX86}\n * @param {number} nIDT\n * @return {number} address from selected vector\n */\n loadIDTReal(nIDT)\n {\n var cpu = this.cpu;\n /*\n * NOTE: The COMPAQ DeskPro 386 ROM loads the IDTR for the real-mode IDT with a limit of 0xffff instead\n * of the normal 0x3ff. A limit higher than 0x3ff is OK, since all real-mode IDT entries are 4 bytes, and\n * there's no way to issue an interrupt with a vector > 0xff. Just something to be aware of.\n */\n\n /*\n * Intel documentation for INT/INTO under \"REAL ADDRESS MODE EXCEPTIONS\" says:\n *\n * \"[T]he 80286 will shut down if the SP = 1, 3, or 5 before executing the INT or INTO instruction--due to lack of stack space\"\n *\n * TODO: Verify that 80286 real-mode actually enforces the above. See http://www.pcjs.org/pubs/pc/reference/intel/80286/progref/#page-260\n */\n var addrIDT = cpu.addrIDT + (nIDT << 2);\n var off = cpu.getShort(addrIDT);\n cpu.regPS &= ~(X86.PS.TF | X86.PS.IF);\n return (this.load(cpu.getShort(addrIDT + 2)) + off)|0;\n }\n\n /**\n * loadIDTProt(nIDT)\n *\n * @this {SegX86}\n * @param {number} nIDT\n * @return {number} address from selected vector, or X86.ADDR_INVALID if error\n */\n loadIDTProt(nIDT)\n {\n var cpu = this.cpu;\n\n\n nIDT <<= 3;\n var addrDesc = (cpu.addrIDT + nIDT)|0;\n if (((cpu.addrIDTLimit - addrDesc)|0) >= 7) {\n this.fCall = true;\n var addr = this.loadDesc8(addrDesc, nIDT);\n if (addr !== X86.ADDR_INVALID) addr += this.offIP;\n return addr;\n }\n X86.helpFault.call(cpu, X86.EXCEPTION.GP_FAULT, nIDT | X86.ERRCODE.IDT);\n return X86.ADDR_INVALID;\n }\n\n /**\n * checkReadWriteNone(off, cb)\n *\n * @this {SegX86}\n * @param {number} off is a segment-relative offset\n * @param {number} cb is number of bytes to check (1, 2 or 4)\n * @return {number} corresponding linear address\n */\n checkReadWriteNone(off, cb)\n {\n return (this.base + off)|0;\n }\n\n /**\n * checkReadWriteReal(off, cb)\n *\n * @this {SegX86}\n * @param {number} off is a segment-relative offset\n * @param {number} cb is number of bytes to check (1, 2 or 4)\n * @return {number} corresponding linear address\n */\n checkReadWriteReal(off, cb)\n {\n /*\n * Since off could be a 32-bit value with the sign bit (bit 31) set, we must convert\n * it to an unsigned value using \">>>\"; offMax was already converted at segment load time.\n */\n if ((off >>> 0) + cb > this.offMax) {\n if (this.cpu.model <= X86.MODEL_8088) {\n this.cpu.opFlags |= X86.OPFLAG.WRAP;\n } else {\n X86.helpFault.call(this.cpu, X86.EXCEPTION.GP_FAULT);\n }\n }\n return (this.base + off)|0;\n }\n\n /**\n * checkReadProt(off, cb)\n *\n * @this {SegX86}\n * @param {number} off is a segment-relative offset\n * @param {number} cb is number of bytes to check (1, 2 or 4)\n * @return {number} corresponding linear address if valid, or X86.ADDR_INVALID if not\n */\n checkReadProt(off, cb)\n {\n /*\n * Since off could be a 32-bit value with the sign bit (bit 31) set, we must convert\n * it to an unsigned value using \">>>\"; offMax was already converted at segment load time.\n */\n if ((off >>> 0) + cb <= this.offMax) {\n return (this.base + off)|0;\n }\n return this.checkReadProtDisallowed(off, cb);\n }\n\n /**\n * checkReadProtDown(off, cb)\n *\n * @this {SegX86}\n * @param {number} off is a segment-relative offset\n * @param {number} cb is number of bytes to check (1, 2 or 4)\n * @return {number} corresponding linear address if valid, X86.ADDR_INVALID if not\n */\n checkReadProtDown(off, cb)\n {\n /*\n * Since off could be a 32-bit value with the sign bit (bit 31) set, we must convert\n * it to an unsigned value using \">>>\"; offMax was already converted at segment load time.\n */\n if ((off >>> 0) + cb > this.offMax) {\n return (this.base + off)|0;\n }\n return this.checkReadProtDisallowed(off, cb);\n }\n\n /**\n * checkReadProtDisallowed(off, cb)\n *\n * @this {SegX86}\n * @param {number} off is a segment-relative offset\n * @param {number} cb is number of bytes to check (1, 2 or 4)\n * @return {number} corresponding linear address if valid, X86.ADDR_INVALID if not\n */\n checkReadProtDisallowed(off, cb)\n {\n X86.helpFault.call(this.cpu, X86.EXCEPTION.GP_FAULT, 0);\n return X86.ADDR_INVALID;\n }\n\n /**\n * checkWriteProt(off, cb)\n *\n * @this {SegX86}\n * @param {number} off is a segment-relative offset\n * @param {number} cb is number of bytes to check (1, 2 or 4)\n * @return {number} corresponding linear address if valid, X86.ADDR_INVALID if not\n */\n checkWriteProt(off, cb)\n {\n /*\n * Since off could be a 32-bit value with the sign bit (bit 31) set, we must convert\n * it to an unsigned value using \">>>\"; offMax was already converted at segment load time.\n */\n if ((off >>> 0) + cb <= this.offMax) {\n return (this.base + off)|0;\n }\n return this.checkWriteProtDisallowed(off, cb);\n }\n\n /**\n * checkWriteProtDown(off, cb)\n *\n * @this {SegX86}\n * @param {number} off is a segment-relative offset\n * @param {number} cb is number of bytes to check (1, 2 or 4)\n * @return {number} corresponding linear address if valid, X86.ADDR_INVALID if not\n */\n checkWriteProtDown(off, cb)\n {\n /*\n * Since off could be a 32-bit value with the sign bit (bit 31) set, we must convert\n * it to an unsigned value using \">>>\"; offMax was already converted at segment load time.\n */\n if ((off >>> 0) + cb > this.offMax) {\n return (this.base + off)|0;\n }\n return this.checkWriteProtDisallowed(off, cb);\n }\n\n /**\n * checkWriteProtDisallowed(off, cb)\n *\n * @this {SegX86}\n * @param {number} off is a segment-relative offset\n * @param {number} cb is number of bytes to check (1, 2 or 4)\n * @return {number} corresponding linear address if valid, X86.ADDR_INVALID if not\n */\n checkWriteProtDisallowed(off, cb)\n {\n X86.helpFault.call(this.cpu, X86.EXCEPTION.GP_FAULT, 0);\n return X86.ADDR_INVALID;\n }\n\n /**\n * checkReadDebugger(off, cb)\n *\n * @this {SegX86}\n * @param {number} off is a segment-relative offset\n * @param {number} cb is number of bytes to check (1, 2 or 4)\n * @return {number} corresponding linear address if valid, or X86.ADDR_INVALID if error\n */\n checkReadDebugger(off, cb)\n {\n /*\n * The Debugger doesn't have separate \"check\" interfaces for real and protected mode,\n * since it's not performance-critical. If addrDesc is invalid, then we assume real mode.\n *\n * TODO: This doesn't actually check the segment for readability.\n */\n if (DEBUGGER) {\n if (this.addrDesc === X86.ADDR_INVALID ||\n this.fExpDown && (off >>> 0) + cb > this.offMax ||\n !this.fExpDown && (off >>> 0) + cb <= this.offMax) {\n return (this.base + off)|0;\n }\n }\n return X86.ADDR_INVALID;\n }\n\n /**\n * checkWriteDebugger(off, cb)\n *\n * @this {SegX86}\n * @param {number} off is a segment-relative offset\n * @param {number} cb is number of bytes to check (1, 2 or 4)\n * @return {number} corresponding linear address if valid, or X86.ADDR_INVALID if error\n */\n checkWriteDebugger(off, cb)\n {\n /*\n * The Debugger doesn't have separate \"check\" interfaces for real and protected mode,\n * since it's not performance-critical. If addrDesc is invalid, then we assume real mode.\n *\n * TODO: This doesn't actually check the segment for writability.\n */\n if (DEBUGGER) {\n if (this.addrDesc === X86.ADDR_INVALID ||\n this.fExpDown && (off >>> 0) + cb > this.offMax ||\n !this.fExpDown && (off >>> 0) + cb <= this.offMax) {\n return (this.base + off)|0;\n }\n }\n return X86.ADDR_INVALID;\n }\n\n /**\n * loadDesc(sel, acc, base, limit)\n *\n * Used to manually load a segment register from the data provided (see LOADALL386).\n *\n * @this {SegX86}\n * @param {number} sel\n * @param {number} acc\n * @param {number} base\n * @param {number} limit\n */\n loadDesc(sel, acc, base, limit)\n {\n this.sel = sel;\n this.base = base;\n this.limit = limit;\n this.offMax = (limit >>> 0) + 1;\n this.acc = acc;\n this.type = (acc & X86.DESC.ACC.TYPE.MASK);\n this.ext = (acc >> 16) & (X86.DESC.EXT.BIG | X86.DESC.EXT.LIMITPAGES);\n\n var addrDT = (sel & X86.SEL.LDT)? this.cpu.segLDT.base : this.cpu.addrGDT;\n this.addrDesc = (addrDT + (sel & X86.SEL.MASK))|0;\n\n /*\n * NOTE: This code must take care to leave the mode of the TSS, LDT, and VER segment registers alone;\n * in particular, we must not allow a real-mode LOADALL to modify their mode, because the rest of PCx86\n * assumes that their mode will never change (they were allocated with fProt set to true).\n */\n if (this.id < SegX86.ID.TSS) this.updateMode(true);\n\n if (DEBUG) this.messageSeg(sel, base, limit, this.type);\n }\n\n /**\n * loadDesc6(addrDesc, sel)\n *\n * Used to load a protected-mode selector that refers to a 6-byte \"descriptor cache\" entry (see LOADALL286):\n *\n * word 0: base address low\n * word 1: base address high (0-7), segment type (8-11), descriptor type (12), DPL (13-14), present bit (15)\n * word 2: segment limit (0-15)\n *\n * @this {SegX86}\n * @param {number} addrDesc is the descriptor address\n * @param {number} sel is the associated selector\n * @return {number} base address of selected segment\n */\n loadDesc6(addrDesc, sel)\n {\n var cpu = this.cpu;\n var acc = cpu.getShort(addrDesc + 2);\n var base = cpu.getShort(addrDesc) | ((acc & 0xff) << 16);\n var limit = cpu.getShort(addrDesc + 4);\n\n this.sel = sel;\n this.base = base;\n this.limit = limit;\n this.offMax = (limit >>> 0) + 1;\n this.acc = acc;\n this.type = (acc & X86.DESC.ACC.TYPE.MASK);\n this.ext = 0;\n this.addrDesc = addrDesc;\n\n /*\n * NOTE: This code must take care to leave the mode of the TSS, LDT, and VER segment registers alone;\n * in particular, we must not allow a real-mode LOADALL to modify their mode, because the rest of PCx86\n * assumes that their mode will never change (they were allocated with fProt set to true).\n */\n if (this.id < SegX86.ID.TSS) this.updateMode(true);\n\n if (DEBUG) this.messageSeg(sel, base, limit, this.type);\n\n return base;\n }\n\n /**\n * loadDesc8(addrDesc, sel, fProbe)\n *\n * Used to load a protected-mode selector that refers to an 8-byte \"descriptor table\" (GDT, LDT, IDT) entry:\n *\n * word 0: segment limit (0-15)\n * word 1: base address low\n * word 2: base address high (0-7), segment type (8-11), descriptor type (12), DPL (13-14), present bit (15)\n * word 3: used only on 80386 and up (should be set to zero for upward compatibility)\n *\n * See X86.DESC for offset and bit definitions.\n *\n * When fProbe is set, we do NOT modify the public properties of the SegX86 object (see class SegX86 above).\n * We will generate a fault if any of the usual error conditions are detected (and return X86.ADDR_INVALID), but\n * otherwise, we merely stash all the descriptor values it reads in the SegX86's private \"probe\" object.\n *\n * Probed loads allow us to deal with complex segment load operations (ie, those involving an implied stack-switch\n * or task-switch), by allowing us to probe all the new selectors and generate the necessary faults before modifying\n * any segment registers; if all the probes succeed, then the original load can proceed.\n *\n * The next non-probed load of a probed selector will move those probed descriptor values into the SegX86 object,\n * saving us from having to reload and reparse the descriptor. However, if a different selector is loaded between\n * the probed and non-probed loads, the probed data is tossed.\n *\n * @this {SegX86}\n * @param {number} addrDesc is the descriptor address\n * @param {number} sel is the associated selector, or nIDT*8 if IDT descriptor\n * @param {boolean} [fProbe] (true if this is a probe)\n * @return {number} base address of selected segment, or X86.ADDR_INVALID if error\n */\n loadDesc8(addrDesc, sel, fProbe)\n {\n var cpu = this.cpu;\n\n /*\n * If the previous load was a successful \"probed\" load of the same segment, then we simply load\n * up all the cached descriptor values from the probe and return.\n */\n if (!fProbe && sel === this.probe.sel) {\n this.sel = sel;\n this.base = this.probe.base;\n this.limit = this.probe.limit;\n this.offMax = (this.probe.limit >>> 0) + 1;\n this.acc = this.probe.acc;\n this.type = this.probe.type;\n this.ext = this.probe.ext;\n this.addrDesc = this.probe.addrDesc;\n this.probe.sel = -1;\n this.updateMode(true, true, false);\n return this.base;\n }\n\n /*\n * Any other load, probed or otherwise, should \"flush\" the probe cache, by setting probe.sel to -1.\n */\n this.probe.sel = -1;\n\n /*\n * Load the descriptor from memory.\n */\n var limit = cpu.getShort(addrDesc + X86.DESC.LIMIT.OFFSET);\n var acc = cpu.getShort(addrDesc + X86.DESC.ACC.OFFSET);\n var type = (acc & X86.DESC.ACC.TYPE.MASK);\n var base = cpu.getShort(addrDesc + X86.DESC.BASE.OFFSET) | ((acc & X86.DESC.ACC.BASE1623) << 16);\n var ext = cpu.getShort(addrDesc + X86.DESC.EXT.OFFSET);\n var selMasked = sel & X86.SEL.MASK;\n\n if (I386 && cpu.model >= X86.MODEL_80386) {\n var limitOrig = limit;\n base |= (ext & X86.DESC.EXT.BASE2431) << 16;\n limit |= (ext & X86.DESC.EXT.LIMIT1619) << 16;\n if (ext & X86.DESC.EXT.LIMITPAGES) limit = (limit << 12) | 0xfff;\n }\n\n switch (this.id) {\n\n case SegX86.ID.CODE:\n\n /*\n * NOTE: Since we are SegX86.ID.CODE, we can use this.cpl instead of the more convoluted\n * this.cpu.segCS.cpl.\n */\n var fCall = this.fCall;\n this.fStackSwitch = false;\n\n /*\n * This special bit of code is currently used only by the Debugger, when it needs to inject\n * a 16:32 callback address into the machine that it can intercept calls to. We call these\n * \"call break\" addresses, because they're essentially breakpoints that only operate when\n * a particular address is called; specifically, an address with selector 0x0001 and an offset\n * that forms a (1-based) index into the aCallBreaks function table.\n *\n * In protected-mode, any null selector, including 0x0001 (null with an RPL of 1), is\n * an invalid CS selector, and while it's not inconceivable that an operating system might\n * use such a selector for some strange purpose, I've not seen such an operating system.\n * And in any case, those operating systems are not likely to trigger the Debugger's call to\n * addCallBreak(), so no call breaks will be generated, and this code will never execute.\n *\n * TODO: If we ever need this to be mode-independent, it can be moved somewhere where it will\n * trigger for both real and protected-mode code segment loads, because CALLBREAK_SEL (0x0001)\n * is also a very unlikely real-mode CS value (but again, not inconceivable). I think this is\n * a reasonable solution, and it's likely the best we can do without injecting code into the\n * machine that we could address -- and even then, it would not be a mode-independent address.\n */\n if (fCall && sel == SegX86.CALLBREAK_SEL && this.aCallBreaks.length) {\n var iBreak = this.offIP - 1;\n var fnCallBreak = this.aCallBreaks[iBreak];\n\n if (fnCallBreak && !fnCallBreak()) {\n return X86.ADDR_INVALID;\n }\n }\n\n var rpl = sel & X86.SEL.RPL;\n var dpl = (acc & X86.DESC.ACC.DPL.MASK) >> X86.DESC.ACC.DPL.SHIFT;\n\n var sizeGate = -1, selCode, cplOld, cplNew, fIDT;\n var addrTSS, offSP, lenSP, regSPPrev, regSSPrev, regPSClear, regSP;\n\n if (!selMasked) {\n /*\n * selMasked is really the descriptor table offset, and a zero offset is fine for the IDT,\n * and it's probably fine for the LDT, but it's definitely NOT fine for the GDT, because\n * that's a reference to the null selector. A null selector is allowed in DS, ES, FS, or GS,\n * but never CS or SS. Since there's no parameter that tells us which table we're using,\n * we have to check manually.\n *\n * If we ARE attempting to load a null selector from the GDT, then we zero type, ensuring that\n * sizeGate will remain invalid (-1), triggering a GP_FAULT below.\n */\n if (addrDesc >= cpu.addrGDT && addrDesc < cpu.addrGDTLimit) type = 0;\n }\n\n if (type >= X86.DESC.ACC.TYPE.CODE_EXECONLY) {\n /*\n * There are three basic ways to load a new code segment (ignoring special cases like LOADALL):\n *\n * 1) CALLF (fCall is true)\n * 2) RETF (fCall is false)\n * 3) JMPF (fCall is undefined)\n *\n * Also, note that if fProbe is set, we're being called on behalf of a gate, in which case the\n * gate logic will examine the relative privileges.\n */\n if (fProbe != null) {\n sizeGate = 0;\n }\n else if (fCall !== false) {\n /*\n * We deal with CALLF/JMPF first. We've already ascertained that the selector type is a\n * segment, not a gate, so the next important distinction is CONFORMING vs. non-CONFORMING.\n *\n * For a CONFORMING target, we must verify that its DPL <= CPL. For a non-CONFORMING target,\n * we must verify that RPL <= CPL and DPL == CPL. Assuming both those tests pass, we must also\n * ensure that the current CPL is recorded as the new RPL (that is, the RPL bits of sel must be\n * updated).\n */\n if (type & X86.DESC.ACC.TYPE.CONFORMING) {\n if (dpl <= this.cpl) {\n sizeGate = 0;\n }\n } else {\n if (rpl <= this.cpl && dpl == this.cpl) {\n sizeGate = 0;\n }\n }\n if (!sizeGate) {\n sel = (sel & ~X86.SEL.RPL) | (this.cpl & X86.SEL.RPL);\n }\n }\n else {\n /*\n * We deal with RETF next. For starters, we must verify that RPL >= CPL. Moreover, if\n * RPL > CPL, then we have a privilege level change that requires a stack switch, assuming\n * the stack selector is acceptable.\n */\n if (rpl >= this.cpl) {\n if (rpl > this.cpl) {\n /*\n * TODO: See if we can defer calling setSS() and setSP() until AFTER the final checks\n * below, because if, for example, the new CS is not PRESENT, we must generate a fault,\n * which in turn must restore the original stack, which means helpRETF() must snapshot\n * the stack registers.\n */\n regSP = cpu.popWord();\n cpu.setSS(cpu.popWord(), true);\n cpu.setSP(regSP);\n this.fStackSwitch = true;\n }\n sizeGate = 0;\n }\n }\n }\n else if (type == X86.DESC.ACC.TYPE.TSS286 || type == X86.DESC.ACC.TYPE.TSS386) {\n if (!this.switchTSS(sel, fCall)) {\n return X86.ADDR_INVALID;\n }\n return this.base;\n }\n else if (type == X86.DESC.ACC.TYPE.GATE_CALL) {\n sizeGate = 2;\n regPSClear = 0;\n if (rpl < this.cpl) rpl = this.cpl; // set RPL to max(RPL,CPL) for call gates\n }\n else if (type == X86.DESC.ACC.TYPE.GATE386_CALL) {\n sizeGate = 4;\n regPSClear = 0;\n if (rpl < this.cpl) rpl = this.cpl; // set RPL to max(RPL,CPL) for call gates\n }\n else if (type == X86.DESC.ACC.TYPE.GATE286_INT) {\n sizeGate = 2;\n regPSClear = (X86.PS.VM | X86.PS.NT | X86.PS.TF | X86.PS.IF);\n\n }\n else if (type == X86.DESC.ACC.TYPE.GATE386_INT) {\n sizeGate = 4;\n regPSClear = (X86.PS.VM | X86.PS.NT | X86.PS.TF | X86.PS.IF);\n\n }\n else if (type == X86.DESC.ACC.TYPE.GATE286_TRAP) {\n sizeGate = 2;\n regPSClear = (X86.PS.VM | X86.PS.NT | X86.PS.TF);\n\n }\n else if (type == X86.DESC.ACC.TYPE.GATE386_TRAP) {\n sizeGate = 4;\n regPSClear = (X86.PS.VM | X86.PS.NT | X86.PS.TF);\n\n }\n else if (type == X86.DESC.ACC.TYPE.GATE_TASK) {\n if (!this.switchTSS(base & 0xffff, fCall)) {\n return X86.ADDR_INVALID;\n }\n return this.base;\n }\n\n if (sizeGate > 0 && !(acc & X86.DESC.ACC.PRESENT)) sizeGate = 0;\n\n if (sizeGate > 0) {\n /*\n * Note that since GATE_INT/GATE_TRAP descriptors should appear in the IDT only, that means sel\n * will actually be nIDT * 8, which means the rpl will always be zero; additionally, the nWords\n * portion of ACC should always be zero, but that's really dependent on the descriptor being properly\n * set (which we assert above).\n */\n cplOld = this.cpl;\n fIDT = (addrDesc == cpu.addrIDT + sel);\n\n /*\n * Software interrupts (where fIDT is true and cpu.nFault < 0) require an additional test:\n * if DPL < CPL, then we must fall into the GP_FAULT code at the end of this case.\n */\n if (rpl <= dpl && (!fIDT || cpu.nFault >= 0 || cplOld <= dpl)) {\n\n /*\n * For gates, there is no \"base\" and \"limit\", but rather \"selector\" and \"offset\"; the selector\n * is located where the first 16 bits of base are normally stored, and the offset comes from the\n * original limit and ext fields.\n *\n * TODO: Verify the PRESENT bit of the gate descriptor, and issue NP_FAULT as appropriate.\n */\n selCode = base & 0xffff;\n if (I386 && (type & X86.DESC.ACC.TYPE.NONSEG_386)) {\n limit = limitOrig | (ext << 16);\n }\n\n var selStack = 0, offStack = 0;\n cplNew = (selCode & X86.SEL.RPL);\n\n /*\n * If a stack switch is required, we must perform \"probed\" loads of both the new selCode\n * and selStack segments, so that if either probe fails, a fault will be generated while the\n * old code segment is still loaded.\n */\n if (cplNew < cplOld) {\n /*\n * Intel pseudo-code suggests that selStack should be \"probed\" before selCode, but it also\n * implies that we need to have the DPL of selCode in order to select the correct selStack,\n * so who knows...?\n */\n if (this.loadProt(selCode, true) === X86.ADDR_INVALID) {\n return X86.ADDR_INVALID;\n }\n /*\n * Intel pseudo-code suggests that the TSS stack pointer offset is based on the DPL of selCode\n * rather than the RPL of selCode. TODO: Check for instances where DPL and RPL of selCode differ,\n * and then figure out which should really be used.\n */\n addrTSS = cpu.segTSS.base;\n if (!I386 || !(cpu.segTSS.type & X86.DESC.ACC.TYPE.NONSEG_386)) {\n offSP = (cplNew << 2) + X86.TSS286.CPL0_SP;\n lenSP = 2;\n } else {\n offSP = (cplNew << 3) + X86.TSS386.CPL0_ESP;\n lenSP = 4;\n }\n selStack = cpu.getShort(addrTSS + offSP + lenSP);\n\n /*\n * Intel pseudo-code indicates at least FIVE discrete selStack tests that could trigger\n * a TS_FAULT at this point:\n *\n * 1) Selector must not be null else #TS(O)\n * 2) Selector index must be within its descriptor table limits else #TS (SS selector)\n * 3) Selector's RPL must equal DPL of code segment else #TS (SS selector)\n * 4) Stack segment DPL must equal DPL of code segment else #TS (SS selector)\n * 5) Descriptor must indicate writable data segment else #TS (SS selector)\n */\n if (!selStack) {\n X86.helpFault.call(cpu, X86.EXCEPTION.TS_FAULT, selStack);\n return X86.ADDR_INVALID;\n }\n\n if (cpu.segSS.loadProt(selStack, true) === X86.ADDR_INVALID) {\n return X86.ADDR_INVALID;\n }\n /*\n * Both probes succeeded, so we can proceed with \"normal\" loads for both selCode and\n * selStack (which should automatically use the values cached by the \"probed\" loads above).\n */\n offStack = (lenSP == 2)? cpu.getShort(addrTSS + offSP) : cpu.getLong(addrTSS + offSP);\n }\n\n /*\n * Now that we're past all the probes, it should be safe to clear all flags that need clearing.\n */\n var regPS = cpu.regPS;\n cpu.regPS &= ~regPSClear;\n if (regPS & X86.PS.VM) {\n cpu.setProtMode(true, false);\n }\n\n /*\n * TODO: Consider whether we can skip this loadProt() call if this.sel already contains selCode\n * (and the previous mode matches, which might require we cache the mode in the SegX86 object, too).\n */\n if (this.loadProt(selCode, false) === X86.ADDR_INVALID) {\n return X86.ADDR_INVALID;\n }\n\n cpu.setDataSize(sizeGate);\n\n this.offIP = limit;\n\n //\n\n if (cplNew < cplOld) {\n\n if (fCall !== true) {\n\n return X86.ADDR_INVALID;\n }\n\n regSP = cpu.getSP();\n var i = 0, nWords = (acc & 0x1f);\n while (nWords--) {\n this.awParms[i++] = cpu.getSOWord(cpu.segSS, regSP);\n regSP += 2;\n }\n\n regSSPrev = cpu.getSS();\n regSPPrev = cpu.getSP();\n\n cpu.setSS(selStack, true);\n cpu.setSP(offStack);\n\n if (regPS & X86.PS.VM) {\n /*\n * Frames coming from V86-mode ALWAYS contain 32-bit values, and look like this:\n *\n * low: EIP\n * CS (upper 16 bits undefined)\n * EFLAGS\n * ESP\n * SS (upper 16 bits undefined)\n * ES (upper 16 bits undefined)\n * DS (upper 16 bits undefined)\n * FS (upper 16 bits undefined)\n * high: GS (upper 16 bits undefined)\n *\n * Our caller (eg, helpINT()) will take care of pushing the final bits (EFLAGS, CS, and EIP).\n */\n cpu.setDataSize(4);\n\n cpu.pushData(cpu.segGS.sel, 4, 2);\n cpu.setGS(0);\n cpu.pushData(cpu.segFS.sel, 4, 2);\n cpu.setFS(0);\n cpu.pushData(cpu.segDS.sel, 4, 2);\n cpu.setDS(0);\n cpu.pushData(cpu.segES.sel, 4, 2);\n cpu.setES(0);\n }\n cpu.pushData(regSSPrev, cpu.sizeData, 2);\n cpu.pushWord(regSPPrev);\n while (i) cpu.pushWord(this.awParms[--i]);\n this.fStackSwitch = true;\n }\n return this.base;\n }\n }\n\n if (sizeGate != 0) {\n X86.helpFault.call(cpu, X86.EXCEPTION.GP_FAULT, (sel & X86.ERRCODE.SELMASK) | (fIDT? X86.ERRCODE.IDT : 0));\n return X86.ADDR_INVALID;\n }\n\n if (!(acc & X86.DESC.ACC.PRESENT)) {\n X86.helpFault.call(cpu, X86.EXCEPTION.NP_FAULT, (sel & X86.ERRCODE.SELMASK) | (fIDT? X86.ERRCODE.IDT : 0));\n return X86.ADDR_INVALID;\n }\n break;\n\n case SegX86.ID.DATA:\n if (selMasked) {\n /*\n * OS/2 1.0 faults on segments with \"empty descriptors\" multiple times during boot; for example:\n *\n * Fault 0x0B (0x002C) on opcode 0x8E at 3190:3A05 (%112625)\n * AX=0000 BX=0970 CX=0300 DX=0300 SP=0ABE BP=0ABA SI=0000 DI=001A\n * SS=0038[175CE0,0B5F] DS=19C0[177300,2C5F] ES=001F[1743A0,07FF] A20=ON\n * CS=3190[10EC20,B89F] LD=0028[174BC0,003F] GD=[11A4E0,490F] ID=[11F61A,03FF]\n * TR=0010 MS=0000FFF3 PS=3256 V0 D0 I1 T0 S0 Z1 A1 P1 C0\n * 3190:3A05 8E4604 MOV ES,[BP+04]\n * ## dw ss:bp+4 l1\n * 0038:0ABE 002F 19C0 0000 067C 07FC 0AD2 0010 C420 /.....|....... .\n * ## ds 2f\n * dumpDesc(0x002F): %174BE8\n * base=000000 limit=0000 type=0x00 (undefined) ext=0x0000 dpl=0x00\n *\n * And Windows 95 Setup, during the \"Analyzing Your Computer\" phase, will fault on an attempt to load\n * a GDT selector of type LDT (why it does this is a mystery I've not yet investigated):\n *\n * Fault 0x0D (0x26F0) on opcode 0x8E @039F:039B (%199E9B)\n * EAX=0000149F EBX=00000100 ECX=000026F3 EDX=0020149F\n * ESP=0000AA34 EBP=0000AA3C ESI=000026E7 EDI=00000080\n * SS=155F[002AC9D0,C0BF] DS=149F[0031B470,9B1F] ES=0237[000C0000,FFFF]\n * CS=039F[00199B00,2ABF] FS=0000[00000000,0000] GS=0000[00000000,0000]\n * LD=0038[00FA4C50,FFEF] GD=[00FA0800,011F] ID=[00FA0000,07FF] TR=0088 A20=ON\n * CR0=0000FFF1 CR2=00000000 CR3=00000000 PS=00003246 V0 D0 I1 T0 S0 Z1 A0 P1 C0\n * 039F:039B 8EC1 MOV ES,CX\n * ## ds cx\n * dumpDesc(0x26F3): %00FA2EF0\n * base=0006C726 limit=0000 type=0x02 (ldt,not present) ext=0x0000 dpl=0x00\n *\n * In both cases, the segment type is not valid for the target segment register *and* the PRESENT bit\n * is clear. OS/2 doesn't seem to care whether I report an NP_FAULT or GP_FAULT, but Windows 95 definitely\n * cares: it will resolve the fault only if a GP_FAULT is reported. And Intel's 80386 Programmers Reference\n * implies that, yes, GP_FAULT checks are supposed to be performed *before* NP_FAULT checks.\n */\n if (type < X86.DESC.ACC.TYPE.SEG || (type & (X86.DESC.ACC.TYPE.CODE | X86.DESC.ACC.TYPE.READABLE)) == X86.DESC.ACC.TYPE.CODE) {\n X86.helpFault.call(cpu, X86.EXCEPTION.GP_FAULT, sel & X86.ERRCODE.SELMASK);\n return X86.ADDR_INVALID;\n }\n /*\n * TODO: This would be a good place to perform some additional access rights checks, too.\n */\n if (!(acc & X86.DESC.ACC.PRESENT)) {\n X86.helpFault.call(cpu, X86.EXCEPTION.NP_FAULT, sel & X86.ERRCODE.SELMASK);\n return X86.ADDR_INVALID;\n }\n }\n break;\n\n case SegX86.ID.STACK:\n if (!selMasked || type < X86.DESC.ACC.TYPE.SEG || (type & (X86.DESC.ACC.TYPE.CODE | X86.DESC.ACC.TYPE.WRITABLE)) != X86.DESC.ACC.TYPE.WRITABLE) {\n X86.helpFault.call(cpu, X86.EXCEPTION.GP_FAULT, sel & X86.ERRCODE.SELMASK);\n return X86.ADDR_INVALID;\n }\n if (!(acc & X86.DESC.ACC.PRESENT)) {\n X86.helpFault.call(cpu, X86.EXCEPTION.SS_FAULT, sel & X86.ERRCODE.SELMASK);\n return X86.ADDR_INVALID;\n }\n break;\n\n case SegX86.ID.TSS:\n var typeTSS = type & ~X86.DESC.ACC.TYPE.TSS_BUSY;\n if (!selMasked || typeTSS != X86.DESC.ACC.TYPE.TSS286 && typeTSS != X86.DESC.ACC.TYPE.TSS386) {\n X86.helpFault.call(cpu, X86.EXCEPTION.GP_FAULT, sel & X86.ERRCODE.SELMASK);\n return X86.ADDR_INVALID;\n }\n /*\n * For more efficient IOPM lookups, we cache the starting linear address in segTSS.addrIOPM, and the\n * last valid address in segTSS.addrIOPMLimit.\n */\n if (typeTSS == X86.DESC.ACC.TYPE.TSS386) {\n this.addrIOPM = (base + cpu.getShort(base + X86.TSS386.TASK_IOPM + 2))|0;\n this.addrIOPMLimit = (base + this.limit)|0;\n }\n break;\n\n case SegX86.ID.VER:\n /*\n * For LSL, we must support any descriptor marked X86.DESC.ACC.TYPE.SEG, as well as TSS and LDT descriptors.\n */\n if (!(type & X86.DESC.ACC.TYPE.SEG) && type > X86.DESC.ACC.TYPE.TSS286_BUSY && type != X86.DESC.ACC.TYPE.TSS386 && type != X86.DESC.ACC.TYPE.TSS386_BUSY) {\n return X86.ADDR_INVALID;\n }\n break;\n\n default:\n /*\n * The only other cases are:\n *\n * SegX86.ID.NULL, SegX86.ID.LDT, and SegX86.ID.DBG\n *\n * which correspond to segNULL, segLDT and segDebugger; however, segLDT is the only one that might require further validation (TODO: Investigate).\n */\n break;\n }\n\n if (fProbe) {\n this.probe.sel = sel;\n this.probe.base = base;\n this.probe.limit = limit;\n this.probe.acc = acc;\n this.probe.type = type;\n this.probe.ext = ext;\n this.probe.addrDesc = addrDesc;\n } else {\n this.sel = sel;\n this.base = base;\n this.limit = limit;\n this.offMax = (limit >>> 0) + 1;\n this.acc = acc;\n this.type = type;\n this.ext = ext;\n this.addrDesc = addrDesc;\n /*\n * A quick recap of what updateMode(fLoad=true, fProt=true, fV86=false) actually updates:\n *\n * cpl\n * dpl\n * dataSize\n * dataMask\n * addrSize\n * addrMask\n * fExpDown\n * load()\n * loadIDT()\n * checkRead()\n * checkWrite()\n */\n this.updateMode(true, true, false);\n }\n\n if (DEBUG) this.messageSeg(sel, base, limit, type, ext);\n\n return base;\n }\n\n /**\n * switchTSS(selNew, fNest)\n *\n * Implements TSS (Task State Segment) task switching.\n *\n * NOTES: This typically occurs during double-fault processing, because the IDT entry for DF_FAULT normally\n * contains a task gate. Interestingly, if we force a GP_FAULT to occur at a sufficiently early point in the\n * OS/2 1.0 initialization code, OS/2 does a nice job of displaying the GP fault and then shutting down:\n *\n * 0090:067B FB STI\n * 0090:067C EBFD JMP 067B\n *\n * but it may not have yet reprogrammed the master PIC to re-vector hardware interrupts to IDT entries 0x50-0x57,\n * so when the next timer interrupt (IRQ 0) occurs, it vectors through IDT entry 0x08, which is the DF_FAULT\n * vector. A spurious double-fault is generated, and a clean shutdown turns into a messy crash.\n *\n * Of course, that all could have been avoided if IBM had heeded Intel's advice and not used Intel-reserved IDT\n * entries for PC interrupts.\n *\n * TODO: Add TSS validity checks and appropriate generation of TS_FAULT exceptions; the only rudimentary checks\n * we currently perform are of the GP_FAULT variety.\n *\n * @this {SegX86}\n * @param {number} selNew\n * @param {boolean|null} [fNest] is true if nesting, false if un-nesting, null if neither\n * @return {boolean} true if successful, false if error\n */\n switchTSS(selNew, fNest)\n {\n var cpu = this.cpu;\n\n\n var cplOld = this.cpl;\n var selOld = cpu.segTSS.sel;\n var addrOld = cpu.segTSS.base;\n\n if (!fNest) {\n /*\n * TODO: Verify that it is (always) correct to require that the BUSY bit be currently set.\n */\n if (!(cpu.segTSS.type & X86.DESC.ACC.TYPE.TSS_BUSY)) {\n X86.helpFault.call(cpu, X86.EXCEPTION.GP_FAULT, selNew & X86.ERRCODE.SELMASK);\n return false;\n }\n /*\n * TODO: Should I be more paranoid about writing our cached ACC value back into the descriptor?\n */\n cpu.setShort(cpu.segTSS.addrDesc + X86.DESC.ACC.OFFSET, cpu.segTSS.acc &= ~X86.DESC.ACC.TYPE.TSS_BUSY);\n }\n\n if (cpu.segTSS.load(selNew) === X86.ADDR_INVALID) {\n return false;\n }\n\n var addrNew = cpu.segTSS.base;\n if (DEBUG && DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages.TSS)) {\n this.dbg.message((fNest? \"Task switch\" : \"Task return\") + \": TR \" + Str.toHexWord(selOld) + \" (%\" + Str.toHex(addrOld, 6) + \"), new TR \" + Str.toHexWord(selNew) + \" (%\" + Str.toHex(addrNew, 6) + \")\");\n }\n\n if (fNest !== false) {\n if (cpu.segTSS.type & X86.DESC.ACC.TYPE.TSS_BUSY) {\n X86.helpFault.call(cpu, X86.EXCEPTION.GP_FAULT, selNew & X86.ERRCODE.SELMASK);\n return false;\n }\n cpu.setShort(cpu.segTSS.addrDesc + X86.DESC.ACC.OFFSET, cpu.segTSS.acc |= X86.DESC.ACC.TYPE.TSS_BUSY);\n }\n\n /*\n * Now that we're done checking the TSS_BUSY bit in the TYPE field (which is a subset of the ACC field),\n * sync any changes made above in the ACC field to the TYPE field.\n */\n cpu.segTSS.type = (cpu.segTSS.type & ~X86.DESC.ACC.TYPE.TSS_BUSY) | (cpu.segTSS.acc & X86.DESC.ACC.TYPE.TSS_BUSY);\n\n /*\n * Update the old TSS\n */\n var offSS, offSP;\n if (cpu.segTSS.type == X86.DESC.ACC.TYPE.TSS286 || cpu.segTSS.type == X86.DESC.ACC.TYPE.TSS286_BUSY) {\n cpu.setShort(addrOld + X86.TSS286.TASK_IP, cpu.getIP());\n cpu.setShort(addrOld + X86.TSS286.TASK_PS, cpu.getPS());\n cpu.setShort(addrOld + X86.TSS286.TASK_AX, cpu.regEAX);\n cpu.setShort(addrOld + X86.TSS286.TASK_CX, cpu.regECX);\n cpu.setShort(addrOld + X86.TSS286.TASK_DX, cpu.regEDX);\n cpu.setShort(addrOld + X86.TSS286.TASK_BX, cpu.regEBX);\n cpu.setShort(addrOld + X86.TSS286.TASK_SP, cpu.getSP());\n cpu.setShort(addrOld + X86.TSS286.TASK_BP, cpu.regEBP);\n cpu.setShort(addrOld + X86.TSS286.TASK_SI, cpu.regESI);\n cpu.setShort(addrOld + X86.TSS286.TASK_DI, cpu.regEDI);\n cpu.setShort(addrOld + X86.TSS286.TASK_ES, cpu.segES.sel);\n cpu.setShort(addrOld + X86.TSS286.TASK_CS, cpu.segCS.sel);\n cpu.setShort(addrOld + X86.TSS286.TASK_SS, cpu.segSS.sel);\n cpu.setShort(addrOld + X86.TSS286.TASK_DS, cpu.segDS.sel);\n /*\n * Reload all registers from the new TSS; it's important to reload the LDTR sooner\n * rather than later, so that as segment registers are reloaded, any LDT selectors will\n * will be located in the correct table.\n */\n cpu.segLDT.load(cpu.getShort(addrNew + X86.TSS286.TASK_LDT));\n cpu.setPS(cpu.getShort(addrNew + X86.TSS286.TASK_PS) | (fNest? X86.PS.NT : 0));\n\n cpu.regEAX = cpu.getShort(addrNew + X86.TSS286.TASK_AX);\n cpu.regECX = cpu.getShort(addrNew + X86.TSS286.TASK_CX);\n cpu.regEDX = cpu.getShort(addrNew + X86.TSS286.TASK_DX);\n cpu.regEBX = cpu.getShort(addrNew + X86.TSS286.TASK_BX);\n cpu.regEBP = cpu.getShort(addrNew + X86.TSS286.TASK_BP);\n cpu.regESI = cpu.getShort(addrNew + X86.TSS286.TASK_SI);\n cpu.regEDI = cpu.getShort(addrNew + X86.TSS286.TASK_DI);\n cpu.segES.load(cpu.getShort(addrNew + X86.TSS286.TASK_ES));\n cpu.segDS.load(cpu.getShort(addrNew + X86.TSS286.TASK_DS));\n cpu.setCSIP(cpu.getShort(addrNew + X86.TSS286.TASK_IP), cpu.getShort(addrNew + X86.TSS286.TASK_CS));\n offSS = X86.TSS286.TASK_SS;\n offSP = X86.TSS286.TASK_SP;\n if (this.cpl < cplOld) {\n offSP = (this.cpl << 2) + X86.TSS286.CPL0_SP;\n offSS = offSP + 2;\n }\n cpu.setSS(cpu.getShort(addrNew + offSS), true);\n cpu.setSP(cpu.getShort(addrNew + offSP));\n } else {\n\n cpu.setLong(addrOld + X86.TSS386.TASK_CR3, cpu.regCR3);\n cpu.setLong(addrOld + X86.TSS386.TASK_EIP, cpu.getIP());\n cpu.setLong(addrOld + X86.TSS386.TASK_PS, cpu.getPS());\n cpu.setLong(addrOld + X86.TSS386.TASK_EAX, cpu.regEAX);\n cpu.setLong(addrOld + X86.TSS386.TASK_ECX, cpu.regECX);\n cpu.setLong(addrOld + X86.TSS386.TASK_EDX, cpu.regEDX);\n cpu.setLong(addrOld + X86.TSS386.TASK_EBX, cpu.regEBX);\n cpu.setLong(addrOld + X86.TSS386.TASK_ESP, cpu.getSP());\n cpu.setLong(addrOld + X86.TSS386.TASK_EBP, cpu.regEBP);\n cpu.setLong(addrOld + X86.TSS386.TASK_ESI, cpu.regESI);\n cpu.setLong(addrOld + X86.TSS386.TASK_EDI, cpu.regEDI);\n cpu.setLong(addrOld + X86.TSS386.TASK_ES, cpu.segES.sel);\n cpu.setLong(addrOld + X86.TSS386.TASK_CS, cpu.segCS.sel);\n cpu.setLong(addrOld + X86.TSS386.TASK_SS, cpu.segSS.sel);\n cpu.setLong(addrOld + X86.TSS386.TASK_DS, cpu.segDS.sel);\n\n /*\n * segFS and segGS exist only on 80386 machines\n */\n\n cpu.setLong(addrOld + X86.TSS386.TASK_FS, cpu.segFS.sel);\n cpu.setLong(addrOld + X86.TSS386.TASK_GS, cpu.segGS.sel);\n\n /*\n * Reload all registers from the new TSS; it's important to reload the LDTR sooner\n * rather than later, so that as segment registers are reloaded, any LDT selectors will\n * will be located in the correct table.\n */\n X86.helpLoadCR3.call(cpu, cpu.getLong(addrNew + X86.TSS386.TASK_CR3));\n cpu.segLDT.load(cpu.getShort(addrNew + X86.TSS386.TASK_LDT));\n cpu.setPS(cpu.getLong(addrNew + X86.TSS386.TASK_PS) | (fNest? X86.PS.NT : 0));\n\n cpu.regEAX = cpu.getLong(addrNew + X86.TSS386.TASK_EAX);\n cpu.regECX = cpu.getLong(addrNew + X86.TSS386.TASK_ECX);\n cpu.regEDX = cpu.getLong(addrNew + X86.TSS386.TASK_EDX);\n cpu.regEBX = cpu.getLong(addrNew + X86.TSS386.TASK_EBX);\n cpu.regEBP = cpu.getLong(addrNew + X86.TSS386.TASK_EBP);\n cpu.regESI = cpu.getLong(addrNew + X86.TSS386.TASK_ESI);\n cpu.regEDI = cpu.getLong(addrNew + X86.TSS386.TASK_EDI);\n cpu.segES.load(cpu.getShort(addrNew + X86.TSS386.TASK_ES));\n cpu.segDS.load(cpu.getShort(addrNew + X86.TSS386.TASK_DS));\n\n /*\n * segFS and segGS exist only on 80386 machines\n */\n\n cpu.segFS.load(cpu.getShort(addrNew + X86.TSS386.TASK_FS));\n cpu.segGS.load(cpu.getShort(addrNew + X86.TSS386.TASK_GS));\n\n cpu.setCSIP(cpu.getLong(addrNew + X86.TSS386.TASK_EIP), cpu.getShort(addrNew + X86.TSS386.TASK_CS));\n offSS = X86.TSS386.TASK_SS;\n offSP = X86.TSS386.TASK_ESP;\n if (this.cpl < cplOld) {\n offSP = (this.cpl << 3) + X86.TSS386.CPL0_ESP;\n offSS = offSP + 4;\n }\n cpu.setSS(cpu.getShort(addrNew + offSS), true);\n cpu.setSP(cpu.getLong(addrNew + offSP));\n }\n\n /*\n * Fortunately, X86.TSS286.PREV_TSS and X86.TSS386.PREV_TSS refer to the same TSS offset.\n */\n if (fNest) cpu.setShort(addrNew + X86.TSS286.PREV_TSS, selOld);\n\n cpu.regCR0 |= X86.CR0.MSW.TS;\n return true;\n }\n\n /**\n * setBase(addr)\n *\n * This is used in unusual situations where the base must be set independently; normally, the base is\n * set according to the selector provided to load(), but there are a few cases where setBase() is required.\n *\n * For example, in resetRegs(), the real-mode CS selector must be reset to 0xF000 for an 80286 or 80386,\n * but the CS base must be set to 0x00FF0000 or 0xFFFF0000, respectively. To simplify life for setBase()\n * callers, we allow them to specify 32-bit bases, which we then truncate to 24 bits as needed.\n *\n * WARNING: Since the CPU must maintain regLIP as the sum of the CS base and the current IP, all calls\n * to segCS.setBase() need to go through cpu.setCSBase().\n *\n * @this {SegX86}\n * @param {number} addr\n * @return {number} addr, truncated as needed\n */\n setBase(addr)\n {\n if (this.cpu.model < X86.MODEL_80386) addr &= 0xffffff;\n return this.base = addr;\n }\n\n /**\n * save()\n *\n * Early versions of PCx86 saved only segment selectors, since that's all that mattered in real-mode;\n * newer versions need to save/restore all the \"core\" properties of the SegX86 object (ie, properties other\n * than those that updateMode() will take care of restoring later).\n *\n * @this {SegX86}\n * @return {Array}\n */\n save()\n {\n return [\n this.sel,\n this.base,\n this.limit,\n this.acc,\n this.id,\n this.sName,\n this.cpl,\n this.dpl,\n this.addrDesc,\n this.sizeAddr,\n this.maskAddr,\n this.sizeData,\n this.maskData,\n this.type,\n this.offMax\n ];\n }\n\n /**\n * restore(a)\n *\n * Early versions of PCx86 saved only segment selectors, since that's all that mattered in real-mode;\n * newer versions need to save/restore all the \"core\" properties of the SegX86 object (ie, properties other\n * than those that updateMode() will take care of restoring later).\n *\n * @this {SegX86}\n * @param {Array|number} a\n */\n restore(a)\n {\n if (typeof a == \"number\") {\n this.load(a);\n } else {\n this.sel = a[0];\n this.base = a[1];\n this.limit = a[2];\n this.acc = a[3];\n this.id = a[4];\n this.sName = a[5];\n this.cpl = a[6];\n this.dpl = a[7];\n this.addrDesc = a[8];\n this.sizeAddr = a[9] || 2;\n this.maskAddr = a[10] || 0xffff;\n this.sizeData = a[11] || 2;\n this.maskData = a[12] || 0xffff;\n this.type = a[13] || (this.acc & X86.DESC.ACC.TYPE.MASK);\n this.offMax = a[14] || (this.limit >>> 0) + 1;\n }\n }\n\n /**\n * updateMode(fLoad, fProt, fV86)\n *\n * Ensures that the segment register's access (ie, load and check methods) matches the specified (or current)\n * operating mode (real or protected).\n *\n * @this {SegX86}\n * @param {boolean} [fLoad] true if the segment was just (re)loaded, false if not\n * @param {boolean} [fProt] true for protected-mode access, false for real-mode access, undefined for current mode\n * @param {boolean} [fV86] true for V86-mode access, false for protected-mode access, undefined for current mode\n */\n updateMode(fLoad, fProt, fV86)\n {\n if (fProt === undefined) {\n fProt = !!(this.cpu.regCR0 & X86.CR0.MSW.PE);\n }\n\n /*\n * The fExpDown property is used for STACK segments only (ie, segSS); we want to make it easier for\n * setSS() to set stack lower and upper limits, which requires knowing whether or not the segment is\n * marked as EXPDOWN.\n */\n this.fExpDown = false;\n\n if (fProt) {\n this.load = this.loadProt;\n this.loadIDT = this.loadIDTProt;\n this.checkRead = this.checkReadProt;\n this.checkWrite = this.checkWriteProt;\n\n if (fV86 === undefined) {\n fV86 = !!(this.cpu.regPS & X86.PS.VM);\n }\n\n if (fV86) {\n this.load = this.loadV86;\n this.checkRead = this.checkReadV86;\n this.checkWrite = this.checkWriteV86;\n /*\n * One important feature of V86-mode (as compared to real-mode) are that other segment attributes\n * (eg, limit, operand size, address size, etc) ARE updated, whereas in real-mode, segment attributes\n * remain set to whatever was in effect in protected-mode.\n */\n this.cpl = this.dpl = 3;\n this.sizeData = this.sizeAddr = 2;\n this.maskData = this.maskAddr = 0xffff;\n this.limit = 0xffff;\n this.offMax = this.limit + 1;\n this.sizeAddr = this.sizeData;\n this.addrDesc = X86.ADDR_INVALID;\n this.fStackSwitch = false;\n return;\n }\n\n /*\n * TODO: For null GDT selectors, should we rely on the descriptor being invalid, or should we assume that\n * the null descriptor might contain uninitialized (or other) data? I'm assuming the latter, hence the\n * following null selector test. However, if we're not going to consult the descriptor, is there anything\n * else we should (or should not) be doing for null GDT selectors?\n */\n if (!(this.sel & ~X86.SEL.RPL)) {\n this.checkRead = this.checkReadProtDisallowed;\n this.checkWrite = this.checkWriteProtDisallowed;\n\n }\n else if (this.type & X86.DESC.ACC.TYPE.SEG) {\n /*\n * If the READABLE bit of CODE_READABLE is not set, then disallow reads.\n */\n if ((this.type & X86.DESC.ACC.TYPE.CODE_READABLE) == X86.DESC.ACC.TYPE.CODE_EXECONLY) {\n this.checkRead = this.checkReadProtDisallowed;\n }\n /*\n * If the CODE bit is set, or the the WRITABLE bit is not set, then disallow writes.\n */\n if ((this.type & X86.DESC.ACC.TYPE.CODE) || !(this.type & X86.DESC.ACC.TYPE.WRITABLE)) {\n this.checkWrite = this.checkWriteProtDisallowed;\n }\n /*\n * If the CODE bit is not set *and* the EXPDOWN bit is set, then invert the limit check.\n */\n if ((this.type & (X86.DESC.ACC.TYPE.CODE | X86.DESC.ACC.TYPE.EXPDOWN)) == X86.DESC.ACC.TYPE.EXPDOWN) {\n if (this.checkRead == this.checkReadProt) this.checkRead = this.checkReadProtDown;\n if (this.checkWrite == this.checkWriteProt) this.checkWrite = this.checkWriteProtDown;\n this.fExpDown = true;\n }\n if (fLoad && this.id < SegX86.ID.VER) {\n /*\n * We must update the descriptor's ACCESSED bit whenever the segment is \"accessed\" (ie,\n * loaded); unlike the ACCESSED and DIRTY bits in PTEs, a descriptor ACCESSED bit is only\n * updated on loads, not on every memory access.\n *\n * We compute the address of the descriptor byte containing the ACCESSED bit (offset 0x5);\n * note that it's perfectly normal for addrDesc to occasionally be invalid (eg, when the CPU\n * is creating protected-mode-only segment registers like LDT and TSS, or when the CPU has\n * transitioned from real-mode to protected-mode and new selector(s) have not been loaded yet).\n *\n * NOTE: I do NOT update the ACCESSED bit for null GDT selectors, because I'm assuming the\n * hardware does not update it either. In fact, I've seen code that uses the null GDT descriptor\n * for other purposes, on the assumption that that descriptor is completely unused.\n */\n if ((this.sel & ~X86.SEL.RPL) && this.addrDesc !== X86.ADDR_INVALID) {\n var addrType = this.addrDesc + X86.DESC.ACC.TYPE.OFFSET;\n var bType = this.cpu.getByte(addrType);\n /*\n * This code used to ALWAYS call setByte(), but that's a waste of time if ACCESSED is already\n * set. TODO: It would also be nice if we could simply use the cached type value, and eliminate\n * the getByte() call; that seems a bit risky, but I think we should still try it someday.\n */\n if (!(bType & (X86.DESC.ACC.TYPE.ACCESSED >> 8))) {\n this.cpu.setByte(addrType, bType | (X86.DESC.ACC.TYPE.ACCESSED >> 8));\n }\n }\n }\n }\n\n /*\n * TODO: For non-SEG descriptors, are there other checks or functions we should establish?\n */\n\n /*\n * Any update to the following properties must occur only on segment loads, not simply when\n * we're updating segment registers as part of a mode change.\n */\n if (fLoad) {\n this.cpl = this.sel & X86.SEL.RPL;\n this.dpl = (this.acc & X86.DESC.ACC.DPL.MASK) >> X86.DESC.ACC.DPL.SHIFT;\n if (this.cpu.model < X86.MODEL_80386 || !(this.ext & X86.DESC.EXT.BIG)) {\n this.sizeData = 2;\n this.maskData = 0xffff;\n } else {\n this.sizeData = 4;\n this.maskData = (0xffffffff|0);\n }\n this.sizeAddr = this.sizeData;\n this.maskAddr = this.maskData;\n }\n return;\n }\n /*\n * One important feature of real-mode (as compared to V86-mode) are that other segment attributes\n * (eg, limit, operand size, address size, etc) are NOT updated, enabling features like \"big real-mode\"\n * (aka \"unreal mode\"), which is used by system software like HIMEM.SYS to access extended memory from\n * real-mode.\n */\n this.load = this.loadReal;\n this.loadIDT = this.loadIDTReal;\n this.checkRead = this.checkReadWriteReal;\n this.checkWrite = this.checkReadWriteReal;\n this.cpl = this.dpl = 0;\n this.addrDesc = X86.ADDR_INVALID;\n this.fStackSwitch = false;\n }\n\n /**\n * messageSeg(sel, base, limit, type, ext)\n *\n * @this {SegX86}\n * @param {number} sel\n * @param {number} base\n * @param {number} limit\n * @param {number} type\n * @param {number} [ext]\n */\n messageSeg(sel, base, limit, type, ext)\n {\n if (DEBUG) {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(Messages.SEG)) {\n var ch = (this.sName.length < 3? \" \" : \"\");\n var sDPL = \" dpl=\" + this.dpl;\n if (this.id == SegX86.ID.CODE) sDPL += \" cpl=\" + this.cpl;\n this.dbg.message(\"loadSeg(\" + this.sName + \"):\" + ch + \"sel=\" + Str.toHexWord(sel) + \" base=\" + Str.toHex(base) + \" limit=\" + Str.toHexWord(limit) + \" type=\" + Str.toHexWord(type) + sDPL, true);\n }\n /*\n * Unless I've got a bug that's causing descriptor corruption, it appears that Windows 3.0 may be setting the\n * EXT field of descriptors, even when the processor is an 80286; eg, the EXT field below has been set to 0x000F:\n *\n * ## ds 1bd\n * dumpSel(0x01BD): %1101B8\n * %001101B8 FFFF C090 B317 000F\n *\n * So I've disabled this assert (I had already disabled the \"base !== X86.ADDR_INVALID\" check).\n *\n *\n */\n }\n }\n\n /**\n * probeDesc(sel)\n *\n * This is a neutered version of loadProt() designed for the Debugger.\n *\n * @this {SegX86}\n * @param {number} sel\n * @return {number} base address of selected segment, or X86.ADDR_INVALID if error\n */\n probeDesc(sel)\n {\n if (DEBUGGER) {\n var addrDT;\n var addrDTLimit;\n var cpu = this.cpu;\n\n sel &= 0xffff;\n\n if (!(sel & X86.SEL.LDT)) {\n addrDT = cpu.addrGDT;\n addrDTLimit = cpu.addrGDTLimit;\n } else {\n addrDT = cpu.segLDT.base;\n addrDTLimit = (addrDT + cpu.segLDT.limit)|0;\n }\n\n var addrDesc = (addrDT + (sel & X86.SEL.MASK))|0;\n\n if ((addrDTLimit - addrDesc)|0 >= 7) {\n\n /*\n * Load the descriptor from memory using probeAddr().\n */\n var limit = cpu.probeAddr(addrDesc + X86.DESC.LIMIT.OFFSET, 2);\n var acc = cpu.probeAddr(addrDesc + X86.DESC.ACC.OFFSET, 2);\n var type = (acc & X86.DESC.ACC.TYPE.MASK);\n var base = cpu.probeAddr(addrDesc + X86.DESC.BASE.OFFSET, 2) | ((acc & X86.DESC.ACC.BASE1623) << 16);\n var ext = cpu.probeAddr(addrDesc + X86.DESC.EXT.OFFSET, 2);\n\n if (I386 && cpu.model >= X86.MODEL_80386) {\n base |= (ext & X86.DESC.EXT.BASE2431) << 16;\n limit |= (ext & X86.DESC.EXT.LIMIT1619) << 16;\n if (ext & X86.DESC.EXT.LIMITPAGES) limit = (limit << 12) | 0xfff;\n }\n\n this.sel = sel;\n this.base = base;\n this.limit = limit;\n this.offMax = (limit >>> 0) + 1;\n this.acc = acc;\n this.type = type;\n this.ext = ext;\n this.addrDesc = addrDesc;\n this.updateMode(true, true, false);\n return base;\n }\n }\n return X86.ADDR_INVALID;\n }\n\n /**\n * loadAcc(sel, fGDT)\n *\n * this {SegX86}\n * param {number} sel (protected-mode only)\n * param {boolean} [fGDT] is true if sel must be in the GDT\n * return {number} ACC field from descriptor, or X86.DESC.ACC.INVALID if error\n *\n loadAcc(sel, fGDT)\n {\n var addrDT;\n var addrDTLimit;\n var cpu = this.cpu;\n\n if (!(sel & X86.SEL.LDT)) {\n addrDT = cpu.addrGDT;\n addrDTLimit = cpu.addrGDTLimit;\n } else if (!fGDT) {\n addrDT = cpu.segLDT.base;\n addrDTLimit = (addrDT + cpu.segLDT.limit)|0;\n }\n if (addrDT !== undefined) {\n var addrDesc = (addrDT + (sel & X86.SEL.MASK))|0;\n if (((addrDTLimit - addrDesc)|0) >= 7) {\n return cpu.getShort(addrDesc + X86.DESC.ACC.OFFSET);\n }\n }\n X86.helpFault.call(cpu, X86.EXCEPTION.GP_FAULT, sel & X86.ERRCODE.SELMASK);\n return X86.DESC.ACC.INVALID;\n }\n */\n}\n\nSegX86.ID = {\n NULL: 0, // \"NULL\"\n CODE: 1, // \"CS\"\n DATA: 2, // \"DS\", \"ES\", \"FS\", \"GS\"\n STACK: 3, // \"SS\"\n TSS: 4, // \"TSS\"\n LDT: 5, // \"LDT\"\n VER: 6, // \"VER\"\n DBG: 7 // \"DBG\"\n};\n\nSegX86.CALLBREAK_SEL = 0x0001;\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/x86func.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * fnADCb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnADCb = function(dst, src)\n{\n var b = (dst + src + this.getCarry())|0;\n this.setArithResult(dst, src, b, X86.RESULT.BYTE | X86.RESULT.ALL);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return b & 0xff;\n};\n\n/**\n * fnADCw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnADCw = function(dst, src)\n{\n var w = (dst + src + this.getCarry())|0;\n this.setArithResult(dst, src, w, this.typeData | X86.RESULT.ALL);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return w & this.maskData;\n};\n\n/**\n * fnADDb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnADDb = function(dst, src)\n{\n var b = (dst + src)|0;\n this.setArithResult(dst, src, b, X86.RESULT.BYTE | X86.RESULT.ALL);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return b & 0xff;\n};\n\n/**\n * fnADDw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnADDw = function(dst, src)\n{\n var w = (dst + src)|0;\n this.setArithResult(dst, src, w, this.typeData | X86.RESULT.ALL);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return w & this.maskData;\n};\n\n/**\n * fnANDb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnANDb = function(dst, src)\n{\n var b = dst & src;\n this.setLogicResult(b, X86.RESULT.BYTE);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return b;\n};\n\n/**\n * fnANDw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnANDw = function(dst, src)\n{\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return this.setLogicResult(dst & src, this.typeData) & this.maskData;\n};\n\n/**\n * fnARPL(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnARPL = function(dst, src)\n{\n this.nStepCycles -= (10 + (this.regEA === X86.ADDR_INVALID? 0 : 1));\n if ((dst & X86.SEL.RPL) < (src & X86.SEL.RPL)) {\n dst = (dst & ~X86.SEL.RPL) | (src & X86.SEL.RPL);\n this.setZF();\n return dst;\n }\n this.clearZF();\n return dst;\n};\n\n/**\n * fnBOUND(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBOUND = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n /*\n * Generate UD_FAULT (INT 0x06: Invalid Opcode) if src is not a memory operand.\n */\n X86.opInvalid.call(this);\n return dst;\n }\n /*\n * Note that BOUND performs signed comparisons, so we must transform all arguments into signed values.\n */\n var wIndex = dst;\n var wLower = this.getWord(this.regEA);\n var wUpper = this.getWord(this.regEA + this.sizeData);\n if (this.sizeData == 2) {\n wIndex = (dst << 16) >> 16;\n wLower = (wLower << 16) >> 16;\n wUpper = (wUpper << 16) >> 16;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesBound;\n if (wIndex < wLower || wIndex > wUpper) {\n /*\n * The INT 0x05 handler must be called with CS:IP pointing to the BOUND instruction.\n *\n * TODO: Determine the cycle cost when a BOUND exception is triggered, over and above nCyclesBound,\n * and then call X86.helpFault(X86.EXCEPTION.BR_FAULT, null, nCycles).\n */\n X86.helpFault.call(this, X86.EXCEPTION.BR_FAULT);\n }\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnBSF(dst, src)\n *\n * Scan src starting at bit 0. If a set bit is found, the bit index is stored in dst and ZF is cleared;\n * otherwise, ZF is set and dst is unchanged.\n *\n * NOTES: Early versions of the 80386 manuals misstated how ZF was set/cleared. Also, Intel insists that\n * dst is undefined whenever ZF is set, but in fact, the 80386 leaves dst unchanged when that happens;\n * unfortunately, some early 80486s would always modify dst, so it is unsafe to rely on dst when ZF is set.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBSF = function(dst, src)\n{\n var n = 0;\n if (!src) {\n this.setZF();\n } else {\n this.clearZF();\n var bit = 0x1;\n while (bit & this.maskData) {\n if (src & bit) {\n dst = n;\n break;\n }\n bit <<= 1;\n n++; // TODO: Determine if n should be incremented before the bailout for an accurate cycle count\n }\n }\n this.nStepCycles -= 11 + n * 3;\n return dst;\n};\n\n/**\n * fnBSR(dst, src)\n *\n * Scan src starting from the highest bit. If a set bit is found, the bit index is stored in dst and ZF is\n * cleared; otherwise, ZF is set and dst is unchanged.\n *\n * NOTES: Early versions of the 80386 manuals misstated how ZF was set/cleared. Also, Intel insists that\n * dst is undefined whenever ZF is set, but in fact, the 80386 leaves dst unchanged when that happens;\n * unfortunately, some early 80486s would always modify dst, so it is unsafe to rely on dst when ZF is set.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBSR = function(dst, src)\n{\n var n = 0;\n if (!src) {\n this.setZF();\n } else {\n this.clearZF();\n var i = (this.sizeData == 2? 15 : 31), bit = 1 << i;\n while (bit) {\n if (src & bit) {\n dst = i;\n break;\n }\n bit >>>= 1;\n n++; i--; // TODO: Determine if n should be incremented before the bailout for an accurate cycle count\n }\n\n }\n this.nStepCycles -= 11 + n * 3;\n return dst;\n};\n\n/**\n * fnBT(dst, src)\n *\n * In this form of BT, src is an immediate operand (OR dst is register operand); immediate operands\n * are supposed to be masked with either 0xf or 0x1f for 16-bit or 32-bit operands, respectively.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBT = function(dst, src)\n{\n var bit = 1 << (src & (this.sizeData == 2? 0xf : 0x1f));\n if (dst & bit) this.setCF(); else this.clearCF();\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 6);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnBTC(dst, src)\n *\n * In this form of BTC, src is an immediate operand (OR dst is register operand); immediate operands\n * are supposed to be masked with either 0xf or 0x1f for 16-bit or 32-bit operands, respectively.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBTC = function(dst, src)\n{\n var bit = 1 << (src & (this.sizeData == 2? 0xf : 0x1f));\n if (dst & bit) this.setCF(); else this.clearCF();\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 6 : 8);\n return dst ^ bit;\n};\n\n/**\n * fnBTR(dst, src)\n *\n * In this form of BTR, src is an immediate operand (OR dst is register operand); immediate operands\n * are supposed to be masked with either 0xf or 0x1f for 16-bit or 32-bit operands, respectively.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBTR = function(dst, src)\n{\n var bit = 1 << (src & (this.sizeData == 2? 0xf : 0x1f));\n if (dst & bit) this.setCF(); else this.clearCF();\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 6 : 8);\n return dst & ~bit;\n};\n\n/**\n * fnBTS(dst, src)\n *\n * In this form of BTS, src is an immediate operand (OR dst is register operand); immediate operands\n * are supposed to be masked with either 0xf or 0x1f for 16-bit or 32-bit operands, respectively.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBTS = function(dst, src)\n{\n var bit = 1 << (src & (this.sizeData == 2? 0xf : 0x1f));\n if (dst & bit) this.setCF(); else this.clearCF();\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 6 : 8);\n return dst | bit;\n};\n\n/**\n * fnBTMem(dst, src)\n *\n * In this form of BT, src is a register operand, which is NOT truncated if dst is a memory operand;\n * however, if dst is also a register operand, then we defer to the simpler function, fnBT().\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBTMem = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n return X86.fnBT.call(this, dst, src);\n }\n /*\n * TODO: Consider a worker function that performs the following block of code for: BT, BTC, BTR, and BTS.\n * It's somewhat inconvenient, because it needs to provide two results: an updated src AND an updated dst.\n *\n * src is usually positive BUT can also be negative (as the IA32 spec says: \"The offset operand then selects\n * a bit position within the range −231 to 231 − 1 for a register offset and 0 to 31 for an immediate offset.\")\n */\n var max = this.sizeData << 3;\n if (src >= max || src < -max) {\n /*\n * Now we need to divide src by 16 or 32, according to the OPERAND size, which means shifting it right\n * by either 4 or 5 bits. That gives us a short or long INDEX, which we then multiply by the OPERAND size\n * to obtain to the corresponding short or long OFFSET that we must add to the original EA offset.\n */\n var i = src >> (this.sizeData == 2? 4 : 5);\n dst = this.getEAWord(this.segEA, this.offEA + i * this.sizeData);\n }\n /*\n * Now we convert src from a bit index to a bit mask.\n */\n src = 1 << (src & (this.sizeData == 2? 0xf : 0x1f));\n if (dst & src) this.setCF(); else this.clearCF();\n\n this.nStepCycles -= 6;\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnBTCMem(dst, src)\n *\n * In this form of BTC, src is a register operand, which is NOT truncated if dst is a memory operand;\n * however, if dst is also a register operand, then we defer to the simpler function, fnBTC().\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBTCMem = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n return X86.fnBTC.call(this, dst, src);\n }\n /*\n * src is usually positive BUT can also be negative (as the IA32 spec says: \"The offset operand then selects\n * a bit position within the range −231 to 231 − 1 for a register offset and 0 to 31 for an immediate offset.\")\n */\n var max = this.sizeData << 3;\n if (src >= max || src < -max) {\n /*\n * Now we need to divide src by 16 or 32, according to the OPERAND size, which means shifting it right\n * by either 4 or 5 bits. That gives us a short or long INDEX, which we then multiply by the OPERAND size\n * to obtain to the corresponding short or long OFFSET that we must add to the original EA offset.\n */\n var i = src >> (this.sizeData == 2? 4 : 5);\n dst = this.getEAWord(this.segEA, this.offEA + i * this.sizeData);\n }\n /*\n * Now we convert src from a bit index to a bit mask.\n */\n src = 1 << (src & (this.sizeData == 2? 0xf : 0x1f));\n if (dst & src) this.setCF(); else this.clearCF();\n\n this.nStepCycles -= 8;\n return dst ^ src;\n};\n\n/**\n * fnBTRMem(dst, src)\n *\n * In this form of BTR, src is a register operand, which is NOT truncated if dst is a memory operand;\n * however, if dst is also a register operand, then we defer to the simpler function, fnBTR().\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBTRMem = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n return X86.fnBTR.call(this, dst, src);\n }\n /*\n * src is usually positive BUT can also be negative (as the IA32 spec says: \"The offset operand then selects\n * a bit position within the range −231 to 231 − 1 for a register offset and 0 to 31 for an immediate offset.\")\n */\n var max = this.sizeData << 3;\n if (src >= max || src < -max) {\n /*\n * Now we need to divide src by 16 or 32, according to the OPERAND size, which means shifting it right\n * by either 4 or 5 bits. That gives us a short or long INDEX, which we then multiply by the OPERAND size\n * to obtain to the corresponding short or long OFFSET that we must add to the original EA offset.\n */\n var i = src >> (this.sizeData == 2? 4 : 5);\n dst = this.getEAWord(this.segEA, this.offEA + i * this.sizeData);\n }\n /*\n * Now we convert src from a bit index to a bit mask.\n */\n src = 1 << (src & (this.sizeData == 2? 0xf : 0x1f));\n if (dst & src) this.setCF(); else this.clearCF();\n\n this.nStepCycles -= 8;\n return dst & ~src;\n};\n\n/**\n * fnBTSMem(dst, src)\n *\n * In this form of BTS, src is a register operand, which is NOT truncated if dst is a memory operand;\n * however, if dst is also a register operand, then we defer to the simpler function, fnBTS().\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnBTSMem = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n return X86.fnBTS.call(this, dst, src);\n }\n /*\n * src is usually positive BUT can also be negative (as the IA32 spec says: \"The offset operand then selects\n * a bit position within the range −231 to 231 − 1 for a register offset and 0 to 31 for an immediate offset.\")\n */\n var max = this.sizeData << 3;\n if (src >= max || src < -max) {\n /*\n * Now we need to divide src by 16 or 32, according to the OPERAND size, which means shifting it right\n * by either 4 or 5 bits. That gives us a short or long INDEX, which we then multiply by the OPERAND size\n * to obtain to the corresponding short or long OFFSET that we must add to the original EA offset.\n */\n var i = src >> (this.sizeData == 2? 4 : 5);\n dst = this.getEAWord(this.segEA, this.offEA + i * this.sizeData);\n }\n /*\n * Now we convert src from a bit index to a bit mask.\n */\n src = 1 << (src & (this.sizeData == 2? 0xf : 0x1f));\n if (dst & src) this.setCF(); else this.clearCF();\n\n this.nStepCycles -= 8;\n return dst | src;\n};\n\n/**\n * fnCALLw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnCALLw = function(dst, src)\n{\n this.pushWord(this.getIP());\n this.setIP(dst);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesCallWR : this.cycleCounts.nOpCyclesCallWM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnCALLFdw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnCALLFdw = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n return X86.fnGRPUndefined.call(this, dst, src);\n }\n /*\n * Originally, we would snapshot regLSP into opLSP because helpCALLF() could trigger a segment fault,\n * but additionally, the stack segment could trigger either a segment fault or a page fault; indeed,\n * any operation that performs multiple stack modifications must take this precaution and snapshot regLSP.\n */\n this.opLSP = this.regLSP;\n\n X86.helpCALLF.call(this, dst, this.getShort(this.regEA + this.sizeData));\n this.nStepCycles -= this.cycleCounts.nOpCyclesCallDM;\n this.opFlags |= X86.OPFLAG.NOWRITE;\n\n this.opLSP = X86.ADDR_INVALID;\n return dst;\n};\n\n/**\n * fnCMPb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number} dst unchanged\n */\nX86.fnCMPb = function(dst, src)\n{\n var b = (dst - src)|0;\n this.setArithResult(dst, src, b, X86.RESULT.BYTE | X86.RESULT.ALL, true);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesCompareRM) : this.cycleCounts.nOpCyclesArithRM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnCMPw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number} dst unchanged\n */\nX86.fnCMPw = function(dst, src)\n{\n var w = (dst - src)|0;\n this.setArithResult(dst, src, w, this.typeData | X86.RESULT.ALL, true);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesCompareRM) : this.cycleCounts.nOpCyclesArithRM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnDECb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnDECb = function(dst, src)\n{\n var b = (dst - 1)|0;\n this.setArithResult(dst, 1, b, X86.RESULT.BYTE | X86.RESULT.NOTCF, true);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIncR : this.cycleCounts.nOpCyclesIncM);\n return b & 0xff;\n};\n\n/**\n * fnDECw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnDECw = function(dst, src)\n{\n var w = (dst - 1)|0;\n this.setArithResult(dst, 1, w, this.typeData | X86.RESULT.NOTCF, true);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIncR : this.cycleCounts.nOpCyclesIncM);\n return w & this.maskData;\n};\n\n/**\n * fnDIVb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (the divisor)\n * @param {number} src (null; AX is the implied src)\n * @return {number} (we return dst unchanged, since it's actually AX that's modified)\n */\nX86.fnDIVb = function(dst, src)\n{\n /*\n * Detect zero divisor\n */\n if (!dst) {\n X86.helpDIVOverflow.call(this);\n return dst;\n }\n\n /*\n * Detect too-small divisor (quotient overflow)\n */\n var result = ((src = this.regEAX & 0xffff) / dst);\n if (result > 0xff) {\n X86.helpDIVOverflow.call(this);\n return dst;\n }\n\n this.regMDLo = (result & 0xff) | (((src % dst) & 0xff) << 8);\n this.fMDSet = true;\n\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesDivBR : this.cycleCounts.nOpCyclesDivBM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnDIVw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (the divisor)\n * @param {number} src (null; DX:AX or EDX:EAX is the implied src)\n * @return {number} (we return dst unchanged, since it's actually DX:AX that's modified)\n */\nX86.fnDIVw = function(dst, src)\n{\n if (this.sizeData == 2) {\n /*\n * Detect zero divisor\n */\n if (!dst) {\n X86.helpDIVOverflow.call(this);\n return dst;\n }\n /*\n * Detect too-small divisor (quotient overflow)\n *\n * WARNING: We CANNOT simply do \"src = (this.regEDX << 16) | this.regEAX\", because if bit 15 of DX\n * is set, JavaScript will create a negative 32-bit number. So we instead use non-bitwise operators\n * to force JavaScript to create a floating-point value that won't suffer from 32-bit-math side-effects.\n */\n src = (this.regEDX & 0xffff) * 0x10000 + (this.regEAX & 0xffff);\n var result = (src / dst);\n if (result >= 0x10000) {\n X86.helpDIVOverflow.call(this);\n return dst;\n }\n this.regMDLo = (result & 0xffff);\n this.regMDHi = (src % dst) & 0xffff;\n }\n else {\n if (!X86.helpDIV32.call(this, this.regEAX, this.regEDX, dst)) {\n X86.helpDIVOverflow.call(this);\n return dst;\n }\n this.regMDLo |= 0;\n this.regMDHi |= 0;\n }\n\n this.fMDSet = true;\n\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesDivWR : this.cycleCounts.nOpCyclesDivWM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnESC(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number} dst unchanged\n */\nX86.fnESC = function(dst, src)\n{\n if (this.fpu) {\n this.fpu.opFPU(this.bOpcode, this.bModRM, dst, src);\n }\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 2 : 8);\n return dst;\n};\n\n/**\n * fnGRPFault(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnGRPFault = function(dst, src)\n{\n /*\n * This should NEVER be called on 8086/8088 CPUs, and yet we preset some of the handlers in aOpGrpPOPw,\n * aOpGrp4b, and aOpGrp4w to call it. initProcessor() DOES patch aOpGrp4b[0x07] and aOpGrp4w[0x07] to\n * fnGRPInvalid, but that's it.\n *\n * However, given the infrequency of this call, it's simpler to continue presetting all the handlers in\n * aOpGrpPOPw to their post-8086 default, and deal with the appropriate 8086 behavior here (which for now,\n * is to call fnGRPUndefined instead).\n */\n if (this.model < X86.MODEL_80186) {\n return X86.fnGRPUndefined.call(this, dst, src);\n }\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return dst;\n};\n\n/**\n * fnGRPInvalid(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnGRPInvalid = function(dst, src)\n{\n X86.opInvalid.call(this);\n return dst;\n};\n\n/**\n * fnGRPUndefined(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnGRPUndefined = function(dst, src)\n{\n X86.opUndefined.call(this);\n return dst;\n};\n\n/**\n * fnIDIVb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (the divisor)\n * @param {number} src (null; AX is the implied src)\n * @return {number} (we return dst unchanged, since it's actually AX that's modified)\n */\nX86.fnIDIVb = function(dst, src)\n{\n /*\n * Detect zero divisor\n */\n if (!dst) {\n X86.helpDIVOverflow.call(this);\n return dst;\n }\n\n /*\n * Detect too-small divisor (quotient overflow)\n */\n var div = ((dst << 24) >> 24);\n var result = ((src = (this.regEAX << 16) >> 16) / div)|0;\n\n /*\n * Note the following difference, from \"AP-186: Introduction to the 80186 Microprocessor, March 1983\":\n *\n * \"The 8086 will cause a divide error whenever the absolute value of the quotient is greater then 7FFFH\n * (for word operations) or if the absolute value of the quotient is greater than 7FH (for byte operations).\n * The 80186 has expanded the range of negative numbers allowed as a quotient by 1 to include 8000H and 80H.\n * These numbers represent the most negative numbers representable using 2's complement arithmetic (equaling\n * -32768 and -128 in decimal, respectively).\"\n */\n if (result != ((result << 24) >> 24) || this.model == X86.MODEL_8086 && result == -128) {\n X86.helpDIVOverflow.call(this);\n return dst;\n }\n\n this.regMDLo = (result & 0xff) | (((src % div) & 0xff) << 8);\n this.fMDSet = true;\n\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIDivBR : this.cycleCounts.nOpCyclesIDivBM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnIDIVw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (the divisor)\n * @param {number} src (null; DX:AX or EDX:EAX is the implied src)\n * @return {number} (we return dst unchanged, since it's actually DX:AX that's modified)\n */\nX86.fnIDIVw = function(dst, src)\n{\n if (this.sizeData == 2) {\n /*\n * Detect zero divisor\n */\n if (!dst) {\n X86.helpDIVOverflow.call(this);\n return dst;\n }\n\n /*\n * Detect too-small divisor (quotient overflow)\n */\n var div = ((dst << 16) >> 16);\n var result = ((src = (this.regEDX << 16) | (this.regEAX & 0xffff)) / div)|0;\n\n /*\n * Note the following difference, from \"AP-186: Introduction to the 80186 Microprocessor, March 1983\":\n *\n * \"The 8086 will cause a divide error whenever the absolute value of the quotient is greater then 7FFFH\n * (for word operations) or if the absolute value of the quotient is greater than 7FH (for byte operations).\n * The 80186 has expanded the range of negative numbers allowed as a quotient by 1 to include 8000H and 80H.\n * These numbers represent the most negative numbers representable using 2's complement arithmetic (equaling\n * -32768 and -128 in decimal, respectively).\"\n */\n if (result != ((result << 16) >> 16) || this.model == X86.MODEL_8086 && result == -32768) {\n X86.helpDIVOverflow.call(this);\n return dst;\n }\n\n this.regMDLo = (result & 0xffff);\n this.regMDHi = (src % div) & 0xffff;\n }\n else {\n if (!X86.helpIDIV32.call(this, this.regEAX, this.regEDX, dst)) {\n X86.helpDIVOverflow.call(this);\n return dst;\n }\n this.regMDLo |= 0;\n this.regMDHi |= 0;\n }\n\n this.fMDSet = true;\n\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIDivWR : this.cycleCounts.nOpCyclesIDivWM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnIMUL8(dst, src)\n *\n * 80286_and_80287_Programmers_Reference_Manual_1987.pdf, p.B-44 (p.254) notes that:\n *\n * \"The low 16 bits of the product of a 16-bit signed multiply are the same as those of an\n * unsigned multiply. The three operand IMUL instruction can be used for unsigned operands as well.\"\n *\n * However, we still sign-extend the operands before multiplying, making it easier to range-check the result.\n *\n * (80186/80188 and up)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnIMUL8 = function(dst, src)\n{\n /*\n * NOTE: getIPDisp() already sign-extends the dst parameter, so fnIMULrw() needlessly sign-extends it again;\n * a small price to pay for a common function.\n */\n var result = X86.fnIMULrw.call(this, this.getIPDisp(), src);\n\n /*\n * NOTE: The above function already accounted for the 80386 cycle count, so we are simply accounting for the\n * increased time on an 80286; the 80186/80188 have even larger values, but we'll worry about that another day.\n */\n if (this.model < X86.MODEL_80386) this.nStepCycles -= 12;\n return result;\n};\n\n/**\n * fnIMULn(dst, src)\n *\n * 80286_and_80287_Programmers_Reference_Manual_1987.pdf, p.B-44 (p.254) notes that:\n *\n * \"The low 16 bits of the product of a 16-bit signed multiply are the same as those of an\n * unsigned multiply. The three operand IMUL instruction can be used for unsigned operands as well.\"\n *\n * However, we still sign-extend the operands before multiplying, making it easier to range-check the result.\n *\n * (80186/80188 and up)\n *\n * @this {CPUX86}\n * @param {number} dst (not used)\n * @param {number} src\n * @return {number}\n */\nX86.fnIMULn = function(dst, src)\n{\n var result;\n dst = this.getIPWord();\n\n if (this.sizeData == 2) {\n result = X86.fnIMULrw.call(this, dst, src);\n } else {\n result = X86.fnIMULrd.call(this, dst, src);\n }\n\n /*\n * NOTE: The above functions already accounted for 80386 cycle counts, so we are simply accounting for the\n * increased time on an 80286; the 80186/80188 have even larger values, but we'll worry about that another day.\n */\n if (this.model < X86.MODEL_80386) this.nStepCycles -= 12;\n return result;\n};\n\n/**\n * fnIMUL32(dst, src)\n *\n * This sets regMDHi:regMDLo to the 64-bit result of dst * src, both of which are treated as signed.\n *\n * @this {CPUX86}\n * @param {number} dst (any 32-bit number, treated as signed)\n * @param {number} src (any 32-bit number, treated as signed)\n */\nX86.fnIMUL32 = function(dst, src)\n{\n var fNeg = false;\n if (src < 0) {\n src = -src|0;\n fNeg = !fNeg;\n }\n if (dst < 0) {\n dst = -dst|0;\n fNeg = !fNeg;\n }\n X86.fnMUL32.call(this, dst, src);\n if (fNeg) {\n this.regMDLo = (~this.regMDLo + 1)|0;\n this.regMDHi = (~this.regMDHi + (this.regMDLo? 0 : 1))|0;\n }\n};\n\n/**\n * fnIMULb(dst, src)\n *\n * This 16-bit multiplication must indicate when the upper 8 bits are simply a sign-extension of the\n * lower 8 bits (carry clear) and when the upper 8 bits contain significant bits (carry set). The latter\n * will occur whenever a positive result is > 127 (0x007f) and whenever a negative result is < -128\n * (0xff80).\n *\n * Example 1: 16 * 4 = 64 (0x0040): carry is clear\n * Example 2: 16 * 8 = 128 (0x0080): carry is set (the sign bit no longer fits in the lower 8 bits)\n * Example 3: 16 * -8 (0xf8) = -128 (0xff80): carry is clear (the sign bit *still* fits in the lower 8 bits)\n * Example 4: 16 * -16 (0xf0) = -256 (0xff00): carry is set (the sign bit no longer fits in the lower 8 bits)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null; AL is the implied src)\n * @return {number} (we return dst unchanged, since it's actually AX that's modified)\n */\nX86.fnIMULb = function(dst, src)\n{\n var result = (((this.regEAX << 24) >> 24) * ((dst << 24) >> 24))|0;\n\n this.regMDLo = result & 0xffff;\n\n if (result > 127 || result < -128) {\n this.setCF(); this.setOF();\n } else {\n this.clearCF(); this.clearOF();\n }\n\n this.fMDSet = true;\n\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIMulBR : this.cycleCounts.nOpCyclesIMulBM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnIMULw(dst, src)\n *\n * regMDHi:regMDLo = dst * regEAX\n *\n * This 32-bit multiplication must indicate when the upper 16 bits are simply a sign-extension of the\n * lower 16 bits (carry clear) and when the upper 16 bits contain significant bits (carry set). The latter\n * will occur whenever a positive result is > 32767 (0x00007fff) and whenever a negative result is < -32768\n * (0xffff8000).\n *\n * Example 1: 256 * 64 = 16384 (0x00004000): carry is clear\n * Example 2: 256 * 128 = 32768 (0x00008000): carry is set (the sign bit no longer fits in the lower 16 bits)\n * Example 3: 256 * -128 (0xff80) = -32768 (0xffff8000): carry is clear (the sign bit *still* fits in the lower 16 bits)\n * Example 4: 256 * -256 (0xff00) = -65536 (0xffff0000): carry is set (the sign bit no longer fits in the lower 16 bits)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null; AX or EAX is the implied src)\n * @return {number} (we return dst unchanged, since it's actually DX:AX or EDX:EAX that's modified)\n */\nX86.fnIMULw = function(dst, src)\n{\n var fOverflow;\n if (this.sizeData == 2) {\n src = this.regEAX & 0xffff;\n var result = (((src << 16) >> 16) * ((dst << 16) >> 16))|0;\n this.regMDLo = result & 0xffff;\n this.regMDHi = (result >> 16) & 0xffff;\n fOverflow = (result > 32767 || result < -32768);\n } else {\n X86.fnIMUL32.call(this, dst, this.regEAX);\n fOverflow = (this.regMDHi != (this.regMDLo >> 31));\n }\n\n if (fOverflow) {\n this.setCF(); this.setOF();\n } else {\n this.clearCF(); this.clearOF();\n }\n\n this.fMDSet = true;\n\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIMulWR : this.cycleCounts.nOpCyclesIMulWM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnIMULrw(dst, src)\n *\n * This function exists for 16-bit IMUL instructions that produce a 16-bit result instead of a 32-bit result\n * (and don't implicitly use the accumulator).\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnIMULrw = function(dst, src)\n{\n /*\n * Unlike fnIMULrd() below, we can use normal JavaScript multiplication, because there's no danger of\n * overflowing the floating-point result and losing accuracy in the bottom 16 bits.\n */\n var result = (((dst << 16) >> 16) * ((src << 16) >> 16))|0;\n if (result > 32767 || result < -32768) {\n this.setCF(); this.setOF();\n } else {\n this.clearCF(); this.clearOF();\n }\n result &= 0xffff;\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 9 : 12);\n return result;\n};\n\n/**\n * fnIMULrd(dst, src)\n *\n * This function exists for 32-bit IMUL instructions that produce a 32-bit result instead of a 64-bit result\n * (and don't implicitly use the accumulator).\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnIMULrd = function(dst, src)\n{\n /*\n * The following code works, but I've stopped using it because it produces different results from an actual CPU\n * when overflow occurs; the bottom 32 bits of the result are still supposed to be accurate.\n *\n * And unfortunately, we cannot achieve that level of compatibility using normal JavaScript multiplication,\n * because the result may be too large to fit in a JavaScript floating-point variable, which means we could lose\n * accuracy in the bottom 32 bits, which would defeat what we're trying to achieve here. So we must use the\n * slower fnIMUL32() function.\n *\n * var result = dst * src;\n * if (result > 2147483647 || result < -2147483648) {\n * this.setCF(); this.setOF();\n * } else {\n * this.clearCF(); this.clearOF();\n * }\n * result |= 0;\n */\n X86.fnIMUL32.call(this, dst, src);\n var fOverflow = (this.regMDHi != (this.regMDLo >> 31));\n if (fOverflow) {\n this.setCF(); this.setOF();\n } else {\n this.clearCF(); this.clearOF();\n }\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 9 : 12);\n return this.regMDLo;\n};\n\n/**\n * fnINCb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnINCb = function(dst, src)\n{\n var b = (dst + 1)|0;\n this.setArithResult(dst, 1, b, X86.RESULT.BYTE | X86.RESULT.NOTCF);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIncR : this.cycleCounts.nOpCyclesIncM);\n return b & 0xff;\n};\n\n/**\n * fnINCw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnINCw = function(dst, src)\n{\n var w = (dst + 1)|0;\n this.setArithResult(dst, 1, w, this.typeData | X86.RESULT.NOTCF);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIncR : this.cycleCounts.nOpCyclesIncM);\n return w & this.maskData;\n};\n\n/**\n * fnJMPw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnJMPw = function(dst, src)\n{\n this.setIP(dst);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesJmpWR : this.cycleCounts.nOpCyclesJmpWM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnJMPFdw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnJMPFdw = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n return X86.fnGRPUndefined.call(this, dst, src);\n }\n this.setCSIP(dst, this.getShort(this.regEA + this.sizeData));\n if (MAXDEBUG && this.cIntReturn) this.checkIntReturn(this.regLIP);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpDM;\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnLAR(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnLAR = function(dst, src)\n{\n this.nStepCycles -= (14 + (this.regEA === X86.ADDR_INVALID? 0 : 2));\n /*\n * Currently, segVER.load() will return an error only if the selector is beyond the bounds of the\n * descriptor table or the descriptor is not for a segment.\n *\n * TODO: This instruction's 80286 documentation does not discuss conforming code segments; determine\n * if we need a special check for them.\n */\n this.clearZF();\n if (this.segVER.load(src) !== X86.ADDR_INVALID) {\n if (this.segVER.dpl >= this.nCPL && this.segVER.dpl >= (src & X86.SEL.RPL)) {\n this.setZF();\n dst = this.segVER.acc & ~X86.DESC.ACC.BASE1623;\n if (this.sizeData > 2) {\n dst |= ((this.segVER.ext & ~X86.DESC.EXT.BASE2431) << 16);\n }\n }\n }\n return dst;\n};\n\n/**\n * fnLDS(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnLDS = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n X86.opUndefined.call(this);\n return dst;\n }\n this.setDS(this.getShort(this.regEA + this.sizeData));\n this.nStepCycles -= this.cycleCounts.nOpCyclesLS;\n return src;\n};\n\n/**\n * fnLEA(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnLEA = function(dst, src)\n{\n /*\n * TODO: Until I bite the bullet and choose a truly invalid value for X86.ADDR_INVALID (eg, null),\n * this code must be disabled, because otherwise an instruction like \"LEA ECX,[EAX-1]\" will fail when\n * EAX is zero. And we can't have that.\n *\n if (this.regEA === X86.ADDR_INVALID) {\n //\n // TODO: After reading http://www.os2museum.com/wp/undocumented-8086-opcodes/, it seems that this\n // form of LEA (eg, \"LEA AX,DX\") simply returns the last calculated EA. Since we always reset regEA\n // at the start of a new instruction, we would need to preserve the previous EA if we want to mimic\n // that (undocumented) behavior.\n //\n // And for completeness, we would have to extend EA tracking beyond the usual ModRM instructions\n // (eg, XLAT, instructions that modify the stack pointer, and string instructions). Anything else?\n //\n X86.opUndefined.call(this);\n return dst;\n }\n */\n this.nStepCycles -= this.cycleCounts.nOpCyclesLEA;\n return this.regEA;\n};\n\n/**\n * fnLES(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnLES = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n X86.opUndefined.call(this);\n return dst;\n }\n this.setES(this.getShort(this.regEA + this.sizeData));\n this.nStepCycles -= this.cycleCounts.nOpCyclesLS;\n return src;\n};\n\n/**\n * fnLFS(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnLFS = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n X86.opUndefined.call(this);\n return dst;\n }\n this.setFS(this.getShort(this.regEA + this.sizeData));\n this.nStepCycles -= this.cycleCounts.nOpCyclesLS;\n return src;\n};\n\n/**\n * fnLGDT(dst, src)\n *\n * op=0x0F,0x01,reg=0x2 (GRP7:LGDT)\n *\n * The 80286 LGDT instruction assumes a 40-bit operand: a 16-bit limit followed by a 24-bit base address;\n * the ModRM decoder has already supplied the first word of the operand (in dst), which corresponds to\n * the limit, so we must fetch the remaining bits ourselves.\n *\n * The 80386 LGDT instruction assumes a 48-bit operand: a 16-bit limit followed by a 32-bit base address,\n * but it ignores the last 8 bits of the base address if the OPERAND size is 16 bits; we interpret that to\n * mean that the 24-bit base address should be zero-extended to 32 bits.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnLGDT = function(dst, src)\n{\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to V86-mode.\n */\n if (this.regEA === X86.ADDR_INVALID || I386 && (this.regPS & X86.PS.VM)) {\n X86.opInvalid.call(this);\n } else {\n /*\n * Hopefully it won't hurt to always fetch a 32-bit base address (even on an 80286), which we then\n * mask appropriately.\n */\n this.addrGDT = this.getLong(this.regEA + 2) & (this.maskData | (this.maskData << 8));\n /*\n * An idiosyncrasy of our ModRM decoders is that, if the OPERAND size is 32 bits, then it will have\n * fetched a 32-bit dst operand; we mask off those extra bits now.\n */\n dst &= 0xffff;\n this.addrGDTLimit = this.addrGDT + dst;\n this.opFlags |= X86.OPFLAG.NOWRITE;\n this.nStepCycles -= 11;\n }\n return dst;\n};\n\n/**\n * fnLGS(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnLGS = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n X86.opUndefined.call(this);\n return dst;\n }\n this.setGS(this.getShort(this.regEA + this.sizeData));\n this.nStepCycles -= this.cycleCounts.nOpCyclesLS;\n return src;\n};\n\n/**\n * fnLIDT(dst, src)\n *\n * op=0x0F,0x01,reg=0x3 (GRP7:LIDT)\n *\n * The 80286 LIDT instruction assumes a 40-bit operand: a 16-bit limit followed by a 24-bit base address;\n * the ModRM decoder has already supplied the first word of the operand (in dst), which corresponds to\n * the limit, so we must fetch the remaining bits ourselves.\n *\n * The 80386 LIDT instruction assumes a 48-bit operand: a 16-bit limit followed by a 32-bit base address,\n * but it ignores the last 8 bits of the base address if the OPERAND size is 16 bits; we interpret that to\n * mean that the 24-bit base address should be zero-extended to 32 bits.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnLIDT = function(dst, src)\n{\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to V86-mode.\n */\n if (this.regEA === X86.ADDR_INVALID || I386 && (this.regPS & X86.PS.VM)) {\n X86.opInvalid.call(this);\n } else {\n /*\n * Hopefully it won't hurt to always fetch a 32-bit base address (even on an 80286), which we then\n * mask appropriately.\n */\n this.addrIDT = this.getLong(this.regEA + 2) & (this.maskData | (this.maskData << 8));\n /*\n * An idiosyncrasy of our ModRM decoders is that, if the OPERAND size is 32 bits, then it will have\n * fetched a 32-bit dst operand; we mask off those extra bits now.\n */\n dst &= 0xffff;\n this.addrIDTLimit = this.addrIDT + dst;\n this.opFlags |= X86.OPFLAG.NOWRITE;\n this.nStepCycles -= 12;\n }\n return dst;\n};\n\n/**\n * fnLLDT(dst, src)\n *\n * op=0x0F,0x00,reg=0x2 (GRP6:LLDT)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnLLDT = function(dst, src)\n{\n this.opFlags |= X86.OPFLAG.NOWRITE;\n this.segLDT.load(dst);\n this.nStepCycles -= (17 + (this.regEA === X86.ADDR_INVALID? 0 : 2));\n return dst;\n};\n\n/**\n * fnLMSW(dst, src)\n *\n * op=0x0F,0x01,reg=0x6 (GRP7:LMSW)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnLMSW = function(dst, src)\n{\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to V86-mode.\n */\n if (I386 && (this.regPS & X86.PS.VM)) {\n X86.opInvalid.call(this);\n } else {\n this.setMSW(dst);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 6);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n }\n return dst;\n};\n\n/**\n * fnLSL(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (the selector)\n * @return {number}\n */\nX86.fnLSL = function(dst, src)\n{\n /*\n * TODO: Is this an invalid operation if regEAWrite is set? dst is required to be a register.\n */\n this.nStepCycles -= (14 + (this.regEA === X86.ADDR_INVALID? 0 : 2));\n /*\n * Currently, segVER.load() will return an error only if the selector is beyond the bounds of the\n * descriptor table or the descriptor is not for a segment.\n *\n * TODO: LSL is explicitly documented as ALSO requiring a non-null selector, so we check X86.SEL.MASK;\n * are there any other instructions that were, um, less explicit but also require a non-null selector?\n */\n if ((src & X86.SEL.MASK) && this.segVER.load(src) !== X86.ADDR_INVALID) {\n var fConforming = ((this.segVER.acc & X86.DESC.ACC.TYPE.CODE_CONFORMING) == X86.DESC.ACC.TYPE.CODE_CONFORMING);\n if ((fConforming || this.segVER.dpl >= this.nCPL) && this.segVER.dpl >= (src & X86.SEL.RPL)) {\n this.setZF();\n return this.segVER.limit;\n }\n }\n this.clearZF();\n return dst;\n};\n\n/**\n * fnLSS(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnLSS = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n X86.opUndefined.call(this);\n return dst;\n }\n this.setSS(this.getShort(this.regEA + this.sizeData));\n this.nStepCycles -= this.cycleCounts.nOpCyclesLS;\n return src;\n};\n\n/**\n * fnLTR(dst, src)\n *\n * op=0x0F,0x00,reg=0x3 (GRP6:LTR)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnLTR = function(dst, src)\n{\n this.opFlags |= X86.OPFLAG.NOWRITE;\n if (this.segTSS.load(dst) !== X86.ADDR_INVALID) {\n this.setShort(this.segTSS.addrDesc + X86.DESC.ACC.OFFSET, this.segTSS.acc |= X86.DESC.ACC.TYPE.TSS_BUSY);\n this.segTSS.type |= X86.DESC.ACC.TYPE.TSS_BUSY;\n }\n this.nStepCycles -= (17 + (this.regEA === X86.ADDR_INVALID? 0 : 2));\n return dst;\n};\n\n/**\n * fnMOV(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (current value, ignored)\n * @param {number} src (new value)\n * @return {number} dst (updated value, from src)\n */\nX86.fnMOV = function(dst, src)\n{\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesMovRR : this.cycleCounts.nOpCyclesMovRM) : this.cycleCounts.nOpCyclesMovMR);\n return src;\n};\n\n/**\n * fnMOVXb(dst, src)\n *\n * Helper for opMOVSXb() and opMOVZXb() (which also take care of updating nStepCycles, so we don't have to)\n *\n * @this {CPUX86}\n * @param {number} dst (current value, ignored)\n * @param {number} src (new value)\n * @return {number} dst (updated value, from src)\n */\nX86.fnMOVXb = function(dst, src)\n{\n /*\n * The ModRegByte handlers update the registers in the 1st column, but we need to update those in the 2nd column.\n *\n * 000: AL -> 000: AX\n * 001: CL -> 001: CX\n * 010: DL -> 010: DX\n * 011: BL -> 011: BX\n * 100: AH -> 100: SP\n * 101: CH -> 101: BP\n * 110: DH -> 110: SI\n * 111: BH -> 111: DI\n */\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x4:\n this.regXX = this.regEAX;\n break;\n case 0x5:\n this.regXX = this.regECX;\n break;\n case 0x6:\n this.regXX = this.regEDX;\n break;\n case 0x7:\n this.regXX = this.regEBX;\n break;\n }\n return src;\n};\n\n/**\n * fnMOVXw(dst, src)\n *\n * Helper for opMOVSXw() and opMOVZXw() (which also take care of updating nStepCycles, so we don't have to)\n *\n * @this {CPUX86}\n * @param {number} dst (current value, ignored)\n * @param {number} src (new value)\n * @return {number} dst (updated value, from src)\n */\nX86.fnMOVXw = function(dst, src)\n{\n return src;\n};\n\n/**\n * fnMOVn(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (current value, ignored)\n * @param {number} src (new value)\n * @return {number} dst (updated value, from src)\n */\nX86.fnMOVn = function(dst, src)\n{\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesMovRI : this.cycleCounts.nOpCyclesMovMI);\n return src;\n};\n\n/**\n * fnMOVsrw(dst, src)\n *\n * This helper saves the contents of the general-purpose register that will be overwritten, so that the caller\n * can restore it after moving the updated value to the correct segment register.\n *\n * @this {CPUX86}\n * @param {number} dst (current value, ignored)\n * @param {number} src (new value)\n * @return {number} dst (updated value, from src)\n */\nX86.fnMOVsrw = function(dst, src)\n{\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n this.regXX = this.regEAX;\n break;\n case 0x2:\n this.regXX = this.regEDX;\n break;\n case 0x3:\n this.regXX = this.regEBX;\n break;\n default:\n if (this.model == X86.MODEL_80286 || this.model == X86.MODEL_80386 && reg != 0x4 && reg != 0x5) {\n X86.opInvalid.call(this);\n break;\n }\n switch(reg) {\n case 0x1: // MOV to CS is undocumented on 8086/8088/80186/80188, and invalid on 80286 and up\n this.regXX = this.regECX;\n break;\n case 0x4: // this form of MOV to ES is undocumented on 8086/8088/80186/80188, invalid on 80286, and uses FS starting with 80386\n this.regXX = this.getSP();\n break;\n case 0x5: // this form of MOV to CS is undocumented on 8086/8088/80186/80188, invalid on 80286, and uses GS starting with 80386\n this.regXX = this.regEBP;\n break;\n case 0x6: // this form of MOV to SS is undocumented on 8086/8088/80186/80188, invalid on 80286 and up\n this.regXX = this.regESI;\n break;\n case 0x7: // this form of MOV to DS is undocumented on 8086/8088/80186/80188, invalid on 80286 and up\n this.regXX = this.regEDI;\n break;\n default:\n break;\n }\n break;\n }\n /*\n * We could just return src, but nStepCycles needs to be updated, too.\n */\n return X86.fnMOV.call(this, dst, src);\n};\n\n/**\n * fnMOVwsr(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (current value, ignored)\n * @param {number} src (new value)\n * @return {number} dst\n */\nX86.fnMOVwsr = function(dst, src)\n{\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch (reg) {\n case 0x0:\n src = this.segES.sel;\n break;\n case 0x1:\n src = this.segCS.sel;\n break;\n case 0x2:\n src = this.segSS.sel;\n break;\n case 0x3:\n src = this.segDS.sel;\n break;\n case 0x4:\n if (I386 && this.model >= X86.MODEL_80386) {\n src = this.segFS.sel;\n break;\n }\n X86.opInvalid.call(this);\n src = dst;\n break;\n case 0x5:\n if (I386 && this.model >= X86.MODEL_80386) {\n src = this.segGS.sel;\n break;\n }\n /* falls through */\n default:\n X86.opInvalid.call(this);\n src = dst;\n break;\n }\n\n /*\n * When a 32-bit OPERAND size is in effect, segment register writes via opMOVwsr() must write 32 bits\n * (zero-extended) if the destination is a register, but only 16 bits if the destination is memory,\n * hence the setDataSize(2) below.\n *\n * The only other caller, opMOVrc(), is not affected, because it writes only to register destinations.\n */\n if (this.regEAWrite !== X86.ADDR_INVALID) {\n this.setDataSize(2);\n }\n /*\n * We could just return src, but nStepCycles needs to be updated, too.\n */\n return X86.fnMOV.call(this, dst, src);\n};\n\n/**\n * fnMULb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number} (we return dst unchanged, since it's actually AX that's modified)\n */\nX86.fnMULb = function(dst, src)\n{\n this.regMDLo = ((this.regEAX & 0xff) * dst) & 0xffff;\n\n if (this.regMDLo & 0xff00) {\n this.setCF(); this.setOF();\n } else {\n this.clearCF(); this.clearOF();\n }\n\n this.fMDSet = true;\n\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesMulBR : this.cycleCounts.nOpCyclesMulBM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnMUL32(dst, src)\n *\n * This sets regMDHi:regMDLo to the 64-bit result of dst * src, both of which are treated as unsigned.\n *\n * The algorithm is based on the traditional \"by hand\" multiplication method, by treating the two inputs\n * (dst and src) as two 2-digit numbers, where each digit is a base-65536 digit.\n *\n * @this {CPUX86}\n * @param {number} dst (any 32-bit number, treated as unsigned)\n * @param {number} src (any 32-bit number, treated as unsigned)\n */\nX86.fnMUL32 = function(dst, src)\n{\n if (!(dst & ~0xffff) && !(src & ~0xffff)) {\n this.regMDLo = (dst * src)|0;\n this.regMDHi = 0;\n }\n else {\n var srcLo = src & 0xffff;\n var srcHi = src >>> 16;\n var dstLo = dst & 0xffff;\n var dstHi = dst >>> 16;\n\n var mul00 = srcLo * dstLo;\n var mul16 = ((mul00 >>> 16) + (srcHi * dstLo));\n var mul32 = mul16 >>> 16;\n mul16 = ((mul16 & 0xffff) + (srcLo * dstHi));\n mul32 += ((mul16 >>> 16) + (srcHi * dstHi));\n\n this.regMDLo = (mul16 << 16) | (mul00 & 0xffff);\n this.regMDHi = mul32|0;\n }\n};\n\n/**\n * fnMULw(dst, src)\n *\n * regMDHi:regMDLo = dst * regEAX\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null; AX or EAX is the implied src)\n * @return {number} (we return dst unchanged, since it's actually DX:AX that's modified)\n */\nX86.fnMULw = function(dst, src)\n{\n if (this.sizeData == 2) {\n src = this.regEAX & 0xffff;\n var result = (src * dst)|0;\n this.regMDLo = result & 0xffff;\n this.regMDHi = (result >> 16) & 0xffff;\n } else {\n X86.fnMUL32.call(this, dst, this.regEAX);\n if (this.stepping == X86.STEPPING_80386_B1) {\n if (this.regEAX == 0x0417A000 && dst == 0x00000081) {\n /*\n * Normally, the result should be 0x20FE7A000 (ie, regMDHi should be 0x2).\n * I'm not sure what a typical B1 stepping failure looked like, so I'll set regMDHi to 0.\n *\n * If you want a B1 stepping without this 32-bit multiplication flaw, select the B2 stepping.\n */\n\n this.regMDHi = 0;\n }\n }\n }\n\n if (this.regMDHi) {\n this.setCF(); this.setOF();\n } else {\n this.clearCF(); this.clearOF();\n }\n\n this.fMDSet = true;\n\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesMulWR : this.cycleCounts.nOpCyclesMulWM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnNEGb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnNEGb = function(dst, src)\n{\n var b = (-dst)|0;\n this.setArithResult(0, dst, b, X86.RESULT.BYTE | X86.RESULT.ALL, true);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesNegR : this.cycleCounts.nOpCyclesNegM);\n return b & 0xff;\n};\n\n/**\n * fnNEGw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnNEGw = function(dst, src)\n{\n var w = (-dst)|0;\n this.setArithResult(0, dst, w, this.typeData | X86.RESULT.ALL, true);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesNegR : this.cycleCounts.nOpCyclesNegM);\n return w & this.maskData;\n};\n\n/**\n * fnNOTb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnNOTb = function(dst, src)\n{\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesNegR : this.cycleCounts.nOpCyclesNegM);\n return dst ^ 0xff;\n};\n\n/**\n * fnNOTw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnNOTw = function(dst, src)\n{\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesNegR : this.cycleCounts.nOpCyclesNegM);\n return dst ^ this.maskData;\n};\n\n/**\n * fnORb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnORb = function(dst, src)\n{\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return this.setLogicResult(dst | src, X86.RESULT.BYTE);\n};\n\n/**\n * fnORw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnORw = function(dst, src)\n{\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return this.setLogicResult(dst | src, this.typeData) & this.maskData;\n};\n\n/**\n * fnPOPw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (current value, ignored)\n * @param {number} src (new value)\n * @return {number} dst (updated value, from src)\n */\nX86.fnPOPw = function(dst, src)\n{\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesPopReg : this.cycleCounts.nOpCyclesPopMem);\n return src;\n};\n\n/**\n * fnPUSHw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnPUSHw = function(dst, src)\n{\n var w = dst;\n if (this.opFlags & X86.OPFLAG.PUSHSP) {\n /*\n * This is the one case where must actually modify dst, so that the ModRM function will\n * not put a stale value back into the SP register.\n */\n dst = (dst - 2) & 0xffff;\n /*\n * And on the 8086/8088, the value we just calculated also happens to be the value that must\n * be pushed.\n */\n if (this.model < X86.MODEL_80286) w = dst;\n }\n this.pushWord(w);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesPushReg : this.cycleCounts.nOpCyclesPushMem);\n /*\n * The PUSH is the only write that needs to occur; dst was the source operand and does not need to be rewritten.\n */\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnRCLb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnRCLb = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = this.getCarry();\n count %= 9;\n if (!count) {\n carry <<= 7;\n } else {\n result = ((dst << count) | (carry << (count - 1)) | (dst >> (9 - count))) & 0xff;\n carry = dst << (count - 1);\n }\n this.setRotateResult(result, carry, X86.RESULT.BYTE);\n }\n return result;\n};\n\n/**\n * fnRCLw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnRCLw = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = this.getCarry();\n count %= 17;\n if (!count) {\n carry <<= 15;\n } else {\n result = ((dst << count) | (carry << (count - 1)) | (dst >> (17 - count))) & 0xffff;\n carry = dst << (count - 1);\n }\n this.setRotateResult(result, carry, X86.RESULT.WORD);\n }\n return result;\n};\n\n/**\n * fnRCLd(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnRCLd = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask; // this 32-bit-only function could mask with 0x1f directly\n if (count) {\n var carry = this.getCarry();\n /*\n * JavaScript Alert: much like a post-8086 Intel CPU, JavaScript shift counts are mod 32,\n * so \"dst >>> 32\" is equivalent to \"dst >>> 0\", which doesn't shift any bits at all. To\n * compensate, we shift one bit less than the maximum, and then shift one bit farther.\n */\n result = (dst << count) | (carry << (count - 1)) | ((dst >>> (32 - count)) >>> 1);\n carry = dst << (count - 1);\n this.setRotateResult(result, carry, X86.RESULT.DWORD);\n }\n return result;\n};\n\n/**\n * fnRCRb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnRCRb = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = this.getCarry();\n count %= 9;\n if (!count) {\n carry <<= 7;\n } else {\n result = ((dst >> count) | (carry << (8 - count)) | (dst << (9 - count))) & 0xff;\n carry = dst << (8 - count);\n }\n this.setRotateResult(result, carry, X86.RESULT.BYTE);\n }\n return result;\n};\n\n/**\n * fnRCRw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnRCRw = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = this.getCarry();\n count %= 17;\n if (!count) {\n carry <<= 15;\n } else {\n result = ((dst >> count) | (carry << (16 - count)) | (dst << (17 - count))) & 0xffff;\n carry = dst << (16 - count);\n }\n this.setRotateResult(result, carry, X86.RESULT.WORD);\n }\n return result;\n};\n\n/**\n * fnRCRd(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnRCRd = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask; // this 32-bit-only function could mask with 0x1f directly\n if (count) {\n var carry = this.getCarry();\n /*\n * JavaScript Alert: much like a post-8086 Intel CPU, JavaScript shift counts are mod 32,\n * so \"dst << 32\" is equivalent to \"dst << 0\", which doesn't shift any bits at all. To\n * compensate, we shift one bit less than the maximum, and then shift one bit farther.\n */\n result = (dst >>> count) | (carry << (32 - count)) | ((dst << (32 - count)) << 1);\n carry = dst << (32 - count);\n this.setRotateResult(result, carry, X86.RESULT.DWORD);\n }\n return result;\n};\n\n/**\n * fnROLb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnROLb = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry;\n count &= 0x7;\n if (!count) {\n carry = dst << 7;\n } else {\n carry = dst << (count - 1);\n result = ((dst << count) | (dst >> (8 - count))) & 0xff;\n }\n this.setRotateResult(result, carry, X86.RESULT.BYTE);\n }\n return result;\n};\n\n/**\n * fnROLw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnROLw = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry;\n count &= 0xf;\n if (!count) {\n carry = dst << 15;\n } else {\n carry = dst << (count - 1);\n result = ((dst << count) | (dst >> (16 - count))) & 0xffff;\n }\n this.setRotateResult(result, carry, X86.RESULT.WORD);\n }\n return result;\n};\n\n/**\n * fnROLd(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnROLd = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = dst << (count - 1);\n result = (dst << count) | (dst >>> (32 - count));\n this.setRotateResult(result, carry, X86.RESULT.DWORD);\n }\n return result;\n};\n\n/**\n * fnRORb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnRORb = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry;\n count &= 0x7;\n if (!count) {\n carry = dst;\n } else {\n carry = dst << (8 - count);\n result = ((dst >>> count) | carry) & 0xff;\n }\n this.setRotateResult(result, carry, X86.RESULT.BYTE);\n }\n return result;\n};\n\n/**\n * fnRORw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnRORw = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry;\n count &= 0xf;\n if (!count) {\n carry = dst;\n } else {\n carry = dst << (16 - count);\n result = ((dst >>> count) | carry) & 0xffff;\n }\n this.setRotateResult(result, carry, X86.RESULT.WORD);\n }\n return result;\n};\n\n/**\n * fnRORd(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL)\n * @return {number}\n */\nX86.fnRORd = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = dst << (32 - count);\n result = (dst >>> count) | carry;\n this.setRotateResult(result, carry, X86.RESULT.DWORD);\n }\n return result;\n};\n\n/**\n * fnSARb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)\n * @return {number}\n */\nX86.fnSARb = function(dst, src)\n{\n var count = src & this.nShiftCountMask;\n if (count) {\n if (count > 9) count = 9;\n var carry = ((dst << 24) >> 24) >> (count - 1);\n dst = (carry >> 1) & 0xff;\n this.setLogicResult(dst, X86.RESULT.BYTE, carry & 0x1);\n }\n return dst;\n};\n\n/**\n * fnSARw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)\n * @return {number}\n */\nX86.fnSARw = function(dst, src)\n{\n var count = src & this.nShiftCountMask;\n if (count) {\n if (count > 17) count = 17;\n var carry = ((dst << 16) >> 16) >> (count - 1);\n dst = (carry >> 1) & 0xffff;\n this.setLogicResult(dst, X86.RESULT.WORD, carry & 0x1);\n }\n return dst;\n};\n\n/**\n * fnSARd(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)\n * @return {number}\n */\nX86.fnSARd = function(dst, src)\n{\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = dst >> (count - 1);\n dst = (carry >> 1);\n this.setLogicResult(dst, X86.RESULT.DWORD, carry & 0x1);\n }\n return dst;\n};\n\n/**\n * fnSBBb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSBBb = function(dst, src)\n{\n var b = (dst - src - this.getCarry())|0;\n this.setArithResult(dst, src, b, X86.RESULT.BYTE | X86.RESULT.ALL, true);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return b & 0xff;\n};\n\n/**\n * fnSBBw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSBBw = function(dst, src)\n{\n var w = (dst - src - this.getCarry())|0;\n this.setArithResult(dst, src, w, this.typeData | X86.RESULT.ALL, true);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return w & this.maskData;\n};\n\n/**\n * fnSETO(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETO = function(dst, src)\n{\n return (this.getOF()? 1 : 0);\n};\n\n/**\n * fnSETNO(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETNO = function(dst, src)\n{\n return (this.getOF()? 0 : 1);\n};\n\n/**\n * fnSETC(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETC = function(dst, src)\n{\n return (this.getCF()? 1 : 0);\n};\n\n/**\n * fnSETNC(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETNC = function(dst, src)\n{\n return (this.getCF()? 0 : 1);\n};\n\n/**\n * fnSETZ(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETZ = function(dst, src)\n{\n return (this.getZF()? 1 : 0);\n};\n\n/**\n * fnSETNZ(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETNZ = function(dst, src)\n{\n return (this.getZF()? 0 : 1);\n};\n\n/**\n * fnSETBE(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETBE = function(dst, src)\n{\n return (this.getCF() || this.getZF()? 1 : 0);\n};\n\n/**\n * fnSETNBE(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETNBE = function(dst, src)\n{\n return (this.getCF() || this.getZF()? 0 : 1);\n};\n\n/**\n * fnSETS(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETS = function(dst, src)\n{\n return (this.getSF()? 1 : 0);\n};\n\n/**\n * fnSETNS(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETNS = function(dst, src)\n{\n return (this.getSF()? 0 : 1);\n};\n\n/**\n * fnSETP(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETP = function(dst, src)\n{\n return (this.getPF()? 1 : 0);\n};\n\n/**\n * fnSETNP(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETNP = function(dst, src)\n{\n return (this.getPF()? 0 : 1);\n};\n\n/**\n * fnSETL(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETL = function(dst, src)\n{\n return (!this.getSF() != !this.getOF()? 1 : 0);\n};\n\n/**\n * fnSETNL(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETNL = function(dst, src)\n{\n return (!this.getSF() != !this.getOF()? 0 : 1);\n};\n\n/**\n * fnSETLE(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETLE = function(dst, src)\n{\n return (this.getZF() || !this.getSF() != !this.getOF()? 1 : 0);\n};\n\n/**\n * fnSETNLE(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst (ignored)\n * @param {number} src (ignored)\n * @return {number}\n */\nX86.fnSETNLE = function(dst, src)\n{\n return (this.getZF() || !this.getSF() != !this.getOF()? 0 : 1);\n};\n\n/**\n * fnSGDT(dst, src)\n *\n * op=0x0F,0x01,reg=0x0 (GRP7:SGDT)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnSGDT = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n X86.opInvalid.call(this);\n } else {\n /*\n * We don't need to set the first word of the operand, because the ModRM group decoder that calls us\n * does that automatically with the value we return (dst).\n */\n dst = this.addrGDTLimit - this.addrGDT;\n\n\n var addr = this.addrGDT;\n if (this.model == X86.MODEL_80286) {\n /*\n * We previously left the 6th byte of the target operand \"undefined\". But it turns out we have to set\n * it to *something*, because there's processor detection in PC-DOS 7.0 (at least in the SETUP portion)\n * that looks like this:\n *\n * 145E:4B84 9C PUSHF\n * 145E:4B85 55 PUSH BP\n * 145E:4B86 8BEC MOV BP,SP\n * 145E:4B88 B80000 MOV AX,0000\n * 145E:4B8B 50 PUSH AX\n * 145E:4B8C 9D POPF\n * 145E:4B8D 9C PUSHF\n * 145E:4B8E 58 POP AX\n * 145E:4B8F 2500F0 AND AX,F000\n * 145E:4B92 3D00F0 CMP AX,F000\n * 145E:4B95 7511 JNZ 4BA8\n * 145E:4BA8 C8060000 ENTER 0006,00\n * 145E:4BAC 0F0146FA SGDT [BP-06]\n * 145E:4BB0 807EFFFF CMP [BP-01],FF\n * 145E:4BB4 C9 LEAVE\n * 145E:4BB5 BA8603 MOV DX,0386\n * 145E:4BB8 7503 JNZ 4BBD\n * 145E:4BBA BA8602 MOV DX,0286\n * 145E:4BBD 89163004 MOV [0430],DX\n * 145E:4BC1 5D POP BP\n * 145E:4BC2 9D POPF\n * 145E:4BC3 CB RETF\n *\n * This code is expecting SGDT on an 80286 to set the 6th \"undefined\" byte to 0xFF, so that's what we do.\n */\n addr |= (0xff000000|0);\n }\n else if (this.model >= X86.MODEL_80386) {\n /*\n * The 80386 added another wrinkle: Intel's documentation claimed that the 6th byte is either set to zero\n * or the high byte of the BASE field, depending on the OPERAND size; from the \"INTEL 80386 PROGRAMMER'S\n * REFERENCE MANUAL 1986\":\n *\n * The LIMIT field of the [GDTR or IDTR] register is assigned to the first word at the effective address.\n * If the operand-size attribute is 32 bits, the next three bytes are assigned the BASE field of the\n * register, and the fourth byte is written with zero. The last byte is undefined. Otherwise, if the\n * operand-size attribute is 16 bits, the next 4 bytes are assigned the 32-bit BASE field of the register.\n *\n * However, Intel obviously meant the reverse (ie, that the BASE field is truncated when using a 16-bit\n * OPERAND size, not when using a 32-bit OPERAND size).\n */\n if (this.sizeData == 2) {\n /*\n * Thanks to Michal Necasek, we now know that the: \"386 in reality does not pay attention to the operand\n * size (despite Intel's claims to the contrary). In fact Windows 3.11/Win32s relies on it -- at least in\n * some configurations, it will execute SGDT in 16-bit code and will crash if all 6 bytes aren't stored.\"\n *\n * Based on the above information, we no longer mask the 6th byte on the 80386 when the OPERAND size is 2.\n *\n * addr &= 0x00ffffff;\n */\n } else {\n /*\n * When the OPERAND size is 4, our ModRM group decoder will call setLong(dst) rather than setShort(dst);\n * we could fix that by calling setDataSize(2), but it seems safer/simpler to set the high bits (16-31)\n * of dst to match the low bits (0-15) of addr, so that the caller will harmlessly rewrite what we are\n * already writing with the setLong() below.\n */\n dst |= (addr << 16);\n }\n }\n this.setLong(this.regEA + 2, addr);\n this.nStepCycles -= 11;\n }\n return dst;\n};\n\n/**\n * fnSHLb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)\n * @return {number}\n */\nX86.fnSHLb = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = 0;\n if (count > 8) {\n result = 0;\n } else {\n carry = dst << (count - 1);\n result = (carry << 1) & 0xff;\n }\n this.setLogicResult(result, X86.RESULT.BYTE, carry & X86.RESULT.BYTE, (result ^ carry) & X86.RESULT.BYTE);\n }\n return result;\n};\n\n/**\n * fnSHLw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)\n * @return {number}\n */\nX86.fnSHLw = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = 0;\n if (count > 16) {\n result = 0;\n } else {\n carry = dst << (count - 1);\n result = (carry << 1) & 0xffff;\n }\n this.setLogicResult(result, X86.RESULT.WORD, carry & X86.RESULT.WORD, (result ^ carry) & X86.RESULT.WORD);\n }\n return result;\n};\n\n/**\n * fnSHLd(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)\n * @return {number}\n */\nX86.fnSHLd = function(dst, src)\n{\n var result = dst;\n var count = src & this.nShiftCountMask; // this 32-bit-only function could mask with 0x1f directly\n if (count) {\n var carry = dst << (count - 1);\n result = (carry << 1);\n this.setLogicResult(result, X86.RESULT.DWORD, carry & X86.RESULT.DWORD, (result ^ carry) & X86.RESULT.DWORD);\n }\n return result;\n};\n\n/**\n * fnSHLDwi(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSHLDwi = function(dst, src)\n{\n return X86.helpSHLDw.call(this, dst, src, this.getIPByte());\n};\n\n/**\n * fnSHLDdi(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSHLDdi = function(dst, src)\n{\n return X86.helpSHLDd.call(this, dst, src, this.getIPByte());\n};\n\n/**\n * fnSHLDwCL(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSHLDwCL = function(dst, src)\n{\n return X86.helpSHLDw.call(this, dst, src, this.regECX & 0x1f);\n};\n\n/**\n * fnSHLDdCL(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSHLDdCL = function(dst, src)\n{\n return X86.helpSHLDd.call(this, dst, src, this.regECX & 0x1f);\n};\n\n/**\n * fnSHRb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)\n * @return {number}\n */\nX86.fnSHRb = function(dst, src)\n{\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = (count > 8? 0 : (dst >>> (count - 1)));\n dst = (carry >>> 1) & 0xff;\n this.setLogicResult(dst, X86.RESULT.BYTE, carry & 0x1, dst & X86.RESULT.BYTE);\n }\n return dst;\n};\n\n/**\n * fnSHRw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)\n * @return {number}\n */\nX86.fnSHRw = function(dst, src)\n{\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = (count > 16? 0 : (dst >>> (count - 1)));\n dst = (carry >>> 1) & 0xffff;\n this.setLogicResult(dst, X86.RESULT.WORD, carry & 0x1, dst & X86.RESULT.WORD);\n }\n return dst;\n};\n\n/**\n * fnSHRd(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)\n * @return {number}\n */\nX86.fnSHRd = function(dst, src)\n{\n var count = src & this.nShiftCountMask;\n if (count) {\n var carry = (dst >>> (count - 1));\n dst = (carry >>> 1);\n this.setLogicResult(dst, X86.RESULT.DWORD, carry & 0x1, dst & X86.RESULT.DWORD);\n }\n return dst;\n};\n\n/**\n * fnSHRDwi(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSHRDwi = function(dst, src)\n{\n return X86.helpSHRDw.call(this, dst, src, this.getIPByte());\n};\n\n/**\n * fnSHRDdi(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSHRDdi = function(dst, src)\n{\n return X86.helpSHRDd.call(this, dst, src, this.getIPByte());\n};\n\n/**\n * fnSHRDwCL(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSHRDwCL = function(dst, src)\n{\n return X86.helpSHRDw.call(this, dst, src, this.regECX & 0x1f);\n};\n\n/**\n * fnSHRDdCL(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSHRDdCL = function(dst, src)\n{\n return X86.helpSHRDd.call(this, dst, src, this.regECX & 0x1f);\n};\n\n/**\n * fnSIDT(dst, src)\n *\n * op=0x0F,0x01,reg=0x1 (GRP7:SIDT)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnSIDT = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n X86.opInvalid.call(this);\n } else {\n /*\n * We don't need to set the first word of the operand, because the ModRM group decoder that calls us\n * does that automatically with the value we return (dst).\n */\n dst = this.addrIDTLimit - this.addrIDT;\n\n /*\n * As with SGDT, the 6th byte is technically \"undefined\" on an 80286, but we now set it to 0xFF, for the\n * same reasons discussed in SGDT (above).\n */\n var addr = this.addrIDT;\n if (this.model == X86.MODEL_80286) {\n addr |= (0xff000000|0);\n }\n else if (this.model >= X86.MODEL_80386) {\n if (this.sizeData == 2) {\n /*\n * Based on the SGDT information above, we no longer mask the 6th byte when the OPERAND size is 2.\n *\n * addr &= 0x00ffffff;\n */\n } else {\n dst |= (addr << 16);\n }\n }\n this.setLong(this.regEA + 2, addr);\n this.nStepCycles -= 12;\n }\n return dst;\n};\n\n/**\n * fnSLDT(dst, src)\n *\n * op=0x0F,0x00,reg=0x0 (GRP6:SLDT)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnSLDT = function(dst, src)\n{\n this.nStepCycles -= (2 + (this.regEA === X86.ADDR_INVALID? 0 : 1));\n return this.segLDT.sel;\n};\n\n/**\n * fnSMSW(dst, src)\n *\n * TODO: I've seen a claim that SMSW can be used with an operand size override to obtain the entire CR0.\n * I don't dispute that, and since I don't mask the return value, that should be possible here; however, it\n * should still be confirmed on real hardware at some point. Note that this differs from LMSW, which is\n * REQUIRED to mask the source operand.\n *\n * op=0x0F,0x01,reg=0x4 (GRP7:SMSW)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnSMSW = function(dst, src)\n{\n this.nStepCycles -= (2 + (this.regEA === X86.ADDR_INVALID? 0 : 1));\n return this.regCR0;\n};\n\n/**\n * fnSTR(dst, src)\n *\n * op=0x0F,0x00,reg=0x1 (GRP6:STR)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnSTR = function(dst, src)\n{\n this.nStepCycles -= (2 + (this.regEA === X86.ADDR_INVALID? 0 : 1));\n return this.segTSS.sel;\n};\n\n/**\n * fnSUBb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSUBb = function(dst, src)\n{\n var b = (dst - src)|0;\n this.setArithResult(dst, src, b, X86.RESULT.BYTE | X86.RESULT.ALL, true);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return b & 0xff;\n};\n\n/**\n * fnSUBw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnSUBw = function(dst, src)\n{\n var w = (dst - src)|0;\n this.setArithResult(dst, src, w, this.typeData | X86.RESULT.ALL, true);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return w & this.maskData;\n};\n\n/**\n * fnTESTib(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null; we have to supply the source ourselves)\n * @return {number}\n */\nX86.fnTESTib = function(dst, src)\n{\n src = this.getIPByte();\n this.setLogicResult(dst & src, X86.RESULT.BYTE);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesTestRI : this.cycleCounts.nOpCyclesTestMI);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnTESTiw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null; we have to supply the source ourselves)\n * @return {number}\n */\nX86.fnTESTiw = function(dst, src)\n{\n src = this.getIPWord();\n this.setLogicResult(dst & src, this.typeData);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesTestRI : this.cycleCounts.nOpCyclesTestMI);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnTESTb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnTESTb = function(dst, src)\n{\n this.setLogicResult(dst & src, X86.RESULT.BYTE);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesTestRR : this.cycleCounts.nOpCyclesTestRM) : this.cycleCounts.nOpCyclesTestRM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnTESTw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnTESTw = function(dst, src)\n{\n this.setLogicResult(dst & src, this.typeData);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesTestRR : this.cycleCounts.nOpCyclesTestRM) : this.cycleCounts.nOpCyclesTestRM);\n this.opFlags |= X86.OPFLAG.NOWRITE;\n return dst;\n};\n\n/**\n * fnVERR(dst, src)\n *\n * op=0x0F,0x00,reg=0x4 (GRP6:VERR)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnVERR = function(dst, src)\n{\n this.opFlags |= X86.OPFLAG.NOWRITE;\n /*\n * Currently, segVER.load() will return an error only if the selector is beyond the bounds of the\n * descriptor table or the descriptor is not for a segment.\n */\n this.nStepCycles -= (14 + (this.regEA === X86.ADDR_INVALID? 0 : 2));\n if (this.segVER.load(dst) !== X86.ADDR_INVALID) {\n /*\n * Verify that this is a readable segment; that is, of these four combinations (code+readable,\n * code+nonreadable, data+writable, date+nonwritable), make sure we're not the second combination.\n */\n if ((this.segVER.acc & (X86.DESC.ACC.TYPE.READABLE | X86.DESC.ACC.TYPE.CODE)) != X86.DESC.ACC.TYPE.CODE) {\n /*\n * For VERR, if the code segment is readable and conforming, the descriptor privilege level\n * (DPL) can be any value.\n *\n * Otherwise, DPL must be greater than or equal to (have less or the same privilege as) both the\n * current privilege level and the selector's RPL.\n */\n if (this.segVER.dpl >= this.nCPL && this.segVER.dpl >= (dst & X86.SEL.RPL) ||\n (this.segVER.acc & X86.DESC.ACC.TYPE.CODE_CONFORMING) == X86.DESC.ACC.TYPE.CODE_CONFORMING) {\n this.setZF();\n return dst;\n }\n }\n }\n this.clearZF();\n if (DEBUG && (this.sizeData > 2 || this.sizeAddr > 2)) this.stopCPU();\n return dst;\n};\n\n/**\n * fnVERW(dst, src)\n *\n * op=0x0F,0x00,reg=0x5 (GRP6:VERW)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src (null)\n * @return {number}\n */\nX86.fnVERW = function(dst, src)\n{\n this.opFlags |= X86.OPFLAG.NOWRITE;\n /*\n * Currently, segVER.load() will return an error only if the selector is beyond the bounds of the\n * descriptor table or the descriptor is not for a segment.\n */\n this.nStepCycles -= (14 + (this.regEA === X86.ADDR_INVALID? 0 : 2));\n if (this.segVER.load(dst) !== X86.ADDR_INVALID) {\n /*\n * Verify that this is a writable data segment\n */\n if ((this.segVER.acc & (X86.DESC.ACC.TYPE.WRITABLE | X86.DESC.ACC.TYPE.CODE)) == X86.DESC.ACC.TYPE.WRITABLE) {\n /*\n * DPL must be greater than or equal to (have less or the same privilege as) both the current\n * privilege level and the selector's RPL.\n */\n if (this.segVER.dpl >= this.nCPL && this.segVER.dpl >= (dst & X86.SEL.RPL)) {\n this.setZF();\n return dst;\n }\n }\n }\n this.clearZF();\n if (DEBUG && (this.sizeData > 2 || this.sizeAddr > 2)) this.stopCPU();\n return dst;\n};\n\n/**\n * fnIBTS(dst, src)\n *\n * As best I can determine, this function copies the specified bits from src (starting at bit 0 for CL\n * bits) to dst (starting at bit offset in AX). For register operands, that's simple enough.\n *\n * TODO: If dst refers to a memory location, then the bit index may refer to higher memory locations, just\n * like the BT/BTC/BTR/BTS instructions. For an instruction that no one was really able to use, except\n * as a CPU stepping discriminator, that doesn't seem worth the effort.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnIBTS = function(dst, src)\n{\n var shift = (this.regEAX & this.maskData);\n var mask = ((1 << (this.regECX & 0x1f)) - 1);\n return (dst & ~(mask << shift)) | ((src & mask) << shift);\n};\n\n/**\n * fnXBTS(dst, src)\n *\n * As best I can determine, this function copies the specified bits from src (starting at the bit offset\n * in AX, for the bit length in CL) to dst (starting at bit 0). For register operands, that's simple enough.\n *\n * TODO: If src refers to a memory location, then the bit index may refer to higher memory locations, just\n * like the BT/BTC/BTR/BTS instructions. For an instruction that no one was really able to use, except\n * as a CPU stepping discriminator, that doesn't seem worth the effort.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnXBTS = function(dst, src)\n{\n /*\n * Shift src right by the bit offset in [E]AX, then apply a mask equal to the number of bits in CL,\n * then mask the resulting bit string with the current OPERAND size.\n */\n return ((src >> (this.regEAX & this.maskData)) & ((1 << (this.regECX & 0x1f)) - 1)) & this.maskData;\n};\n\n/**\n * fnXCHGrb(dst, src)\n *\n * If an instruction like \"XCHG AL,AH\" was a traditional \"op dst,src\" instruction, dst would contain AL,\n * src would contain AH, and we would return src, which the caller would then store in AL, and we'd be done.\n *\n * However, that's only half of what XCHG does, so THIS function must perform the other half; in the previous\n * example, that means storing the original AL (dst) into AH (src).\n *\n * BACKTRACK support is incomplete without also passing bti values as parameters, because the caller will\n * store btiAH in btiAL, but the original btiAL will be lost. Similarly, if src is a memory operand, the\n * caller will store btiEALo in btiAL, but again, the original btiAL will be lost.\n *\n * BACKTRACK support for memory operands could be fixed by decoding the dst register in order to determine the\n * corresponding bti and then temporarily storing it in btiEALo around the setEAByte() call below. Register-only\n * XCHGs would require a more extensive hack. For now, I'm going to live with one-way BACKTRACK support here.\n *\n * TODO: Implement full BACKTRACK support for XCHG instructions.\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnXCHGrb = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n /*\n * Decode which register was src\n */\n\n switch (this.bModRM & 0x7) {\n case 0x0: // AL\n this.regEAX = (this.regEAX & ~0xff) | dst;\n break;\n case 0x1: // CL\n this.regECX = (this.regECX & ~0xff) | dst;\n break;\n case 0x2: // DL\n this.regEDX = (this.regEDX & ~0xff) | dst;\n break;\n case 0x3: // BL\n this.regEBX = (this.regEBX & ~0xff) | dst;\n break;\n case 0x4: // AH\n this.regEAX = (this.regEAX & ~0xff00) | (dst << 8);\n break;\n case 0x5: // CH\n this.regECX = (this.regECX & ~0xff00) | (dst << 8);\n break;\n case 0x6: // DH\n this.regEDX = (this.regEDX & ~0xff00) | (dst << 8);\n break;\n case 0x7: // BH\n this.regEBX = (this.regEBX & ~0xff00) | (dst << 8);\n break;\n default:\n break; // there IS no other case, but JavaScript inspections don't know that\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesXchgRR;\n } else {\n /*\n * This is a case where the ModRM decoder that's calling us didn't know it should have set regEAWrite,\n * so we compensate by updating regEAWrite. However, setEAWord() has since been changed to revalidate\n * the write using segEA:offEA, so updating regEAWrite here isn't strictly necessary.\n */\n this.regEAWrite = this.regEA;\n this.setEAByte(dst);\n this.nStepCycles -= this.cycleCounts.nOpCyclesXchgRM;\n }\n return src;\n};\n\n/**\n * fnXCHGrw(dst, src)\n *\n * If an instruction like \"XCHG AX,DX\" was a traditional \"op dst,src\" instruction, dst would contain AX,\n * src would contain DX, and we would return src, which the caller would then store in AX, and we'd be done.\n *\n * However, that's only half of what XCHG does, so THIS function must perform the other half; in the previous\n * example, that means storing the original AX (dst) into DX (src).\n *\n * TODO: Implement full BACKTRACK support for XCHG instructions (see fnXCHGrb comments).\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnXCHGrw = function(dst, src)\n{\n if (this.regEA === X86.ADDR_INVALID) {\n /*\n * Decode which register was src\n */\n\n switch (this.bModRM & 0x7) {\n case 0x0: // [E]AX\n this.regEAX = (this.regEAX & ~this.maskData) | dst;\n break;\n case 0x1: // [E]CX\n this.regECX = (this.regECX & ~this.maskData) | dst;\n break;\n case 0x2: // [E]DX\n this.regEDX = (this.regEDX & ~this.maskData) | dst;\n break;\n case 0x3: // [E]BX\n this.regEBX = (this.regEBX & ~this.maskData) | dst;\n break;\n case 0x4: // [E]SP\n this.setSP((this.getSP() & ~this.maskData) | dst);\n break;\n case 0x5: // [E]BP\n this.regEBP = (this.regEBX & ~this.maskData) | dst;\n break;\n case 0x6: // [E]SI\n this.regESI = (this.regESI & ~this.maskData) | dst;\n break;\n case 0x7: // [E]DI\n this.regEDI = (this.regEDI & ~this.maskData) | dst;\n break;\n default:\n break; // there IS no other case, but JavaScript inspections don't know that\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesXchgRR;\n } else {\n /*\n * This is a case where the ModRM decoder that's calling us didn't know it should have set regEAWrite,\n * so we compensate by updating regEAWrite. However, setEAWord() has since been changed to revalidate\n * the write using segEA:offEA, so updating regEAWrite here isn't strictly necessary.\n */\n this.regEAWrite = this.regEA;\n this.setEAWord(dst);\n this.nStepCycles -= this.cycleCounts.nOpCyclesXchgRM;\n }\n return src;\n};\n\n/**\n * fnXORb(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnXORb = function(dst, src)\n{\n var b = dst ^ src;\n this.setLogicResult(b, X86.RESULT.BYTE);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return b;\n};\n\n/**\n * fnXORw(dst, src)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @return {number}\n */\nX86.fnXORw = function(dst, src)\n{\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesArithRR : this.cycleCounts.nOpCyclesArithRM) : this.cycleCounts.nOpCyclesArithMR);\n return this.setLogicResult(dst ^ src, this.typeData) & this.maskData;\n};\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/x86help.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * helpAdd64(r64Dst, r64Src)\n *\n * Adds r64Src to r64Dst.\n *\n * @param {Array.<number>} r64Dst is a 64-bit value\n * @param {Array.<number>} r64Src is a 64-bit value\n */\nX86.helpAdd64 = function(r64Dst, r64Src)\n{\n r64Dst[0] += r64Src[0];\n r64Dst[1] += r64Src[1];\n if (r64Dst[0] > 0xffffffff) {\n r64Dst[0] >>>= 0; // truncate r64Dst[0] to 32 bits AND keep it unsigned\n r64Dst[1]++;\n }\n};\n\n/**\n * helpCmp64(r64Dst, r64Src)\n *\n * Compares r64Dst to r64Src, by computing r64Dst - r64Src.\n *\n * @param {Array.<number>} r64Dst is a 64-bit value\n * @param {Array.<number>} r64Src is a 64-bit value\n * @return {number} > 0 if r64Dst > r64Src, == 0 if r64Dst == r64Src, < 0 if r64Dst < r64Src\n */\nX86.helpCmp64 = function(r64Dst, r64Src)\n{\n var result = r64Dst[1] - r64Src[1];\n if (!result) result = r64Dst[0] - r64Src[0];\n return result;\n};\n\n/**\n * helpSet64(r64Dst, lo, hi)\n *\n * @param {Array.<number>} r64Dst\n * @param {number} lo\n * @param {number} hi\n * @return {Array.<number>}\n */\nX86.helpSet64 = function(r64Dst, lo, hi)\n{\n r64Dst[0] = lo >>> 0;\n r64Dst[1] = hi >>> 0;\n return r64Dst;\n};\n\n/**\n * helpShr64(r64Dst)\n *\n * Shifts r64Dst right one bit.\n *\n * @param {Array.<number>} r64Dst is a 64-bit value\n */\nX86.helpShr64 = function(r64Dst)\n{\n r64Dst[0] >>>= 1;\n if (r64Dst[1] & 0x1) {\n r64Dst[0] = (r64Dst[0] | 0x80000000) >>> 0;\n }\n r64Dst[1] >>>= 1;\n};\n\n/**\n * helpSub64(r64Dst, r64Src)\n *\n * Subtracts r64Src from r64Dst.\n *\n * @param {Array.<number>} r64Dst is a 64-bit value\n * @param {Array.<number>} r64Src is a 64-bit value\n */\nX86.helpSub64 = function(r64Dst, r64Src)\n{\n r64Dst[0] -= r64Src[0];\n r64Dst[1] -= r64Src[1];\n if (r64Dst[0] < 0) {\n r64Dst[0] >>>= 0; // truncate r64Dst[0] to 32 bits AND keep it unsigned\n r64Dst[1]--;\n }\n};\n\n/**\n * helpDECreg(w)\n *\n * @this {CPUX86}\n * @param {number} w\n * @return {number}\n */\nX86.helpDECreg = function(w)\n{\n var result = (w - 1)|0;\n this.setArithResult(w, 1, result, this.typeData | X86.RESULT.NOTCF, true);\n this.nStepCycles -= 2; // the register form of DEC takes 2 cycles on all CPUs\n return (w & ~this.maskData) | (result & this.maskData);\n};\n\n/**\n * helpDIV32(dstLo, dstHi, src)\n *\n * This sets regMDLo to dstHi:dstLo / src, and regMDHi to dstHi:dstLo % src; all inputs are treated as unsigned.\n *\n * Refer to: http://lxr.linux.no/linux+v2.6.22/lib/div64.c\n *\n * @this {CPUX86}\n * @param {number} dstLo (low 32-bit portion of dividend)\n * @param {number} dstHi (high 32-bit portion of dividend)\n * @param {number} src (32-bit divisor)\n * @return {boolean} true if successful, false if overflow (ie, the divisor was either zero or too small)\n */\nX86.helpDIV32 = function(dstLo, dstHi, src)\n{\n src >>>= 0;\n\n if (!src || src <= (dstHi >>> 0)) {\n return false;\n }\n\n var result = 0, bit = 1;\n\n var r64Div = X86.helpSet64(this.r64Div, src, 0);\n var r64Rem = X86.helpSet64(this.r64Rem, dstLo, dstHi);\n\n while (X86.helpCmp64(r64Rem, r64Div) > 0) {\n X86.helpAdd64(r64Div, r64Div);\n bit += bit;\n }\n do {\n if (X86.helpCmp64(r64Rem, r64Div) >= 0) {\n X86.helpSub64(r64Rem, r64Div);\n result += bit;\n }\n X86.helpShr64(r64Div);\n bit /= 2;\n } while (bit >= 1);\n\n\n\n this.regMDLo = result; // result is the quotient, which callers expect in the low MD register\n this.regMDHi = r64Rem[0]; // r64Rem[0] is the remainder, which callers expect in the high MD register\n return true;\n};\n\n/**\n * helpIDIV32(dstLo, dstHi, src)\n *\n * This sets regMDLo to dstHi:dstLo / src, and regMDHi to dstHi:dstLo % src; all inputs are treated as signed.\n *\n * Refer to: http://lxr.linux.no/linux+v2.6.22/lib/div64.c\n *\n * @this {CPUX86}\n * @param {number} dstLo (low 32-bit portion of dividend)\n * @param {number} dstHi (high 32-bit portion of dividend)\n * @param {number} src (32-bit divisor)\n * @return {boolean} true if successful, false if overflow (ie, the divisor was either zero or too small)\n */\nX86.helpIDIV32 = function(dstLo, dstHi, src)\n{\n var bNegLo = 0, bNegHi = 0;\n /*\n * dividend divisor quotient remainder\n * (dst) (src) (lo) (hi)\n * -------- ------- -------- ---------\n * + + -> + +\n * + - -> - +\n * - + -> - -\n * - - -> + -\n */\n if (src < 0) {\n src = -src|0;\n bNegLo = 1 - bNegLo;\n }\n if (dstHi < 0) {\n dstLo = -dstLo|0;\n dstHi = (~dstHi + (dstLo? 0 : 1))|0;\n bNegHi = 1;\n bNegLo = 1 - bNegLo;\n }\n if (!X86.helpDIV32.call(this, dstLo, dstHi, src) || this.regMDLo > 0x7fffffff+bNegLo || this.regMDHi > 0x7fffffff+bNegHi) {\n return false;\n }\n if (bNegLo) this.regMDLo = -this.regMDLo;\n if (bNegHi) this.regMDHi = -this.regMDHi;\n return true;\n};\n\n/**\n * helpINCreg(w)\n *\n * @this {CPUX86}\n * @param {number} w\n * @return {number}\n */\nX86.helpINCreg = function(w)\n{\n var result = (w + 1)|0;\n this.setArithResult(w, 1, result, this.typeData | X86.RESULT.NOTCF);\n this.nStepCycles -= 2; // the register form of INC takes 2 cycles on all CPUs\n return (w & ~this.maskData) | (result & this.maskData);\n};\n\n/**\n * helpLoadCR0(l)\n *\n * This is called by an 80386 control instruction (ie, MOV CR0,reg).\n *\n * TODO: Determine which CR0 bits, if any, cannot be modified by MOV CR0,reg.\n *\n * @this {CPUX86}\n * @param {number} l\n */\nX86.helpLoadCR0 = function(l)\n{\n this.regCR0 = l;\n this.setProtMode();\n if (this.regCR0 & X86.CR0.PG) {\n /*\n * TODO: Determine if setting X86.CR0.PG when already set should really act as a flush;\n * I'm not currently worried about it, because I'm assuming CR0 is not rewritten that often.\n */\n this.enablePageBlocks();\n } else {\n this.disablePageBlocks();\n }\n};\n\n/**\n * helpLoadCR3(l)\n *\n * This is called by an 80386 control instruction (ie, MOV CR3,reg) or an 80386 task switch.\n *\n * @this {CPUX86}\n * @param {number} l\n */\nX86.helpLoadCR3 = function(l)\n{\n this.regCR3 = l;\n /*\n * Normal use of regCR3 involves adding a 0-4K (12-bit) offset to obtain a page directory entry,\n * so let's ensure that the low 12 bits of regCR3 are always zero.\n */\n\n this.flushPageBlocks();\n};\n\n/**\n * helpSETcc()\n *\n * @this {CPUX86}\n * @param {function(number,number)} fnSet\n */\nX86.helpSETcc = function(fnSet)\n{\n this.opFlags |= X86.OPFLAG.NOREAD;\n this.decodeModMemByte.call(this, fnSet);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 4 : 5);\n};\n\n/**\n * helpSHLDw(dst, src, count)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @param {number} count (0-31)\n * @return {number}\n */\nX86.helpSHLDw = function(dst, src, count)\n{\n if (count) {\n if (count > 16) {\n dst = src;\n count -= 16;\n }\n var carry = dst << (count - 1);\n dst = ((carry << 1) | (src >>> (16 - count))) & 0xffff;\n this.setLogicResult(dst, X86.RESULT.WORD, carry & X86.RESULT.WORD);\n }\n return dst;\n};\n\n/**\n * helpSHLDd(dst, src, count)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @param {number} count\n * @return {number}\n */\nX86.helpSHLDd = function(dst, src, count)\n{\n if (count) {\n var carry = dst << (count - 1);\n dst = (carry << 1) | (src >>> (32 - count));\n this.setLogicResult(dst, X86.RESULT.DWORD, carry & X86.RESULT.DWORD);\n }\n return dst;\n};\n\n/**\n * helpSHRDw(dst, src, count)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @param {number} count (0-31)\n * @return {number}\n */\nX86.helpSHRDw = function(dst, src, count)\n{\n if (count) {\n if (count > 16) {\n dst = src;\n count -= 16;\n }\n var carry = dst >>> (count - 1);\n dst = ((carry >>> 1) | (src << (16 - count))) & 0xffff;\n this.setLogicResult(dst, X86.RESULT.WORD, carry & 0x1);\n }\n return dst;\n};\n\n/**\n * helpSHRDd(dst, src, count)\n *\n * @this {CPUX86}\n * @param {number} dst\n * @param {number} src\n * @param {number} count\n * @return {number}\n */\nX86.helpSHRDd = function(dst, src, count)\n{\n if (count) {\n var carry = dst >>> (count - 1);\n dst = (carry >>> 1) | (src << (32 - count));\n this.setLogicResult(dst, X86.RESULT.DWORD, carry & 0x1);\n }\n return dst;\n};\n\n/**\n * helpSRC1()\n *\n * @this {CPUX86}\n * @return {number}\n */\nX86.helpSRC1 = function()\n{\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 2 : this.cycleCounts.nOpCyclesShift1M);\n return 1;\n};\n\n/**\n * helpSRCCL()\n *\n * @this {CPUX86}\n * @return {number}\n */\nX86.helpSRCCL = function()\n{\n var count = this.regECX & 0xff;\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesShiftCR : this.cycleCounts.nOpCyclesShiftCM) + (count << this.cycleCounts.nOpCyclesShiftCS);\n return count;\n};\n\n/**\n * helpSRCByte()\n *\n * @this {CPUX86}\n * @return {number}\n */\nX86.helpSRCByte = function()\n{\n var count = this.getIPByte();\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesShiftCR : this.cycleCounts.nOpCyclesShiftCM) + (count << this.cycleCounts.nOpCyclesShiftCS);\n return count;\n};\n\n/**\n * helpSRCNone()\n *\n * @this {CPUX86}\n * @return {number|null}\n */\nX86.helpSRCNone = function()\n{\n return null;\n};\n\n/**\n * helpSRCxx()\n *\n * This is used by opPOPmw(), because the actual pop must occur BEFORE the effective address (EA)\n * calculation. So opPOPmw() does the pop, saves the popped value in regXX, and this passes src function\n * to the EA worker.\n *\n * @this {CPUX86}\n * @return {number} regXX\n */\nX86.helpSRCxx = function()\n{\n return this.regXX;\n};\n\n/**\n * helpCALLF(off, sel)\n *\n * For protected-mode, this function must attempt to load the new code segment first, because if the new segment\n * requires a change in privilege level, the return address must be pushed on the NEW stack, not the current stack.\n *\n * Also, we rely on a new function, pushData(), instead of pushWord(), to accommodate the outgoing segment size,\n * which may differ from the incoming segment. For example, when a 32-bit code segment performs a 16:32 call to a\n * 16-bit code segment, we must push 32-bit segment and offset values.\n *\n * TODO: Since setCSIP() already informs the segCS load() function when it's making a call, the load() function\n * could automatically push the old CS and IP values *before* segCS is updated -- which would be a better time to do\n * those pushes AND eliminate the need for pushData(). Unfortunately, load() is also used by loadIDT(), and loadIDT()\n * has different requirements (eg, pushing flags first), so it's not a trivial change.\n *\n * @this {CPUX86}\n * @param {number} off\n * @param {number} sel\n */\nX86.helpCALLF = function(off, sel)\n{\n /*\n * Since we always push the return address AFTER calling setCSIP(), and since either push could trigger\n * a fault (eg, segment fault, page fault, etc), we must not only snapshot regSS and regLSP, but also regCS,\n * so that helpFault() can always make CALLF restartable.\n */\n this.opCS = this.getCS();\n this.opSS = this.getSS();\n this.opLSP = this.regLSP;\n var oldIP = this.getIP();\n var oldSize = (I386? this.sizeData : 2);\n if (this.setCSIP(off, sel, true) != null) {\n /*\n * When the OPERAND size is 32 bits, the 80386 will decrement the stack pointer by 4, write the selector\n * into the 2 lower bytes, and leave the 2 upper bytes untouched; at least, that's the case for all other\n * segment register writes, so we assume this case is no different. Hence, the hard-coded size of 2.\n */\n this.pushData(this.opCS, oldSize, 2);\n this.pushData(oldIP, oldSize, oldSize);\n }\n this.opLSP = X86.ADDR_INVALID;\n this.opCS = this.opSS = -1;\n};\n\n/**\n * helpINT(nIDT, nError, nCycles)\n *\n * NOTE: We no longer use setCSIP(), because it always loads the new CS using segCS.load(), which only knows\n * how to load GDT and LDT descriptors, whereas interrupts must use setCS.loadIDT(), which deals exclusively\n * with IDT descriptors.\n *\n * @this {CPUX86}\n * @param {number} nIDT\n * @param {number|null} [nError]\n * @param {number} [nCycles] (in addition to the default of nOpCyclesInt)\n */\nX86.helpINT = function(nIDT, nError, nCycles)\n{\n /*\n * TODO: We assess the cycle cost up front, because otherwise, if loadIDT() fails, no cost may be assessed.\n */\n this.nStepCycles -= this.cycleCounts.nOpCyclesInt + (nCycles || 0);\n var oldPS = this.getPS();\n var oldCS = this.getCS();\n var oldIP = this.getIP();\n var addr = this.segCS.loadIDT(nIDT);\n if (addr !== X86.ADDR_INVALID) {\n /*\n * TODO: Determine if we should use pushData() instead of pushWord() for oldCS and nError, to deal with\n * the same 32-bit 80386 compatibility issue that helpCALLF(), opPUSHCS(), et al must deal with; namely, that\n * 32-bit segment register writes (and, reportedly, 32-bit error codes) don't modify the upper 16 bits.\n *\n * Also, note that helpCALLF() is using the OPERAND size in effect *before* CS is loaded, whereas here we're\n * using the OPERAND size in effect *after* CS is loaded. Is that correct? And does an explicit OPERAND\n * size override on an \"INT\" instruction have any effect on that behavior? Is that even allowed?\n */\n this.pushWord(oldPS);\n this.pushWord(oldCS);\n this.pushWord(oldIP);\n if (nError != null) this.pushWord(nError);\n this.nFault = -1;\n this.setLIP(addr);\n }\n};\n\n/**\n * helpIRET()\n *\n * @this {CPUX86}\n */\nX86.helpIRET = function()\n{\n this.opSS = this.getSS();\n this.opLSP = this.regLSP;\n\n this.nStepCycles -= this.cycleCounts.nOpCyclesIRet;\n\n if ((this.regCR0 & X86.CR0.MSW.PE) && (this.regPS & X86.PS.NT)) {\n var addrNew = this.segTSS.base;\n /*\n * Fortunately, X86.TSS286.PREV_TSS and X86.TSS386.PREV_TSS refer to the same TSS offset.\n * TODO: Update switchTS() to assess a cycle cost; currently, all we assess is what's shown above.\n */\n var sel = this.getShort(addrNew + X86.TSS286.PREV_TSS);\n this.segCS.switchTSS(sel, false);\n }\n else {\n var cpl = this.nCPL;\n var newIP = this.popWord();\n var newCS = this.popWord();\n var newPS = this.popWord();\n\n if (I386) {\n if (this.regPS & X86.PS.VM) {\n /*\n * On the 80386, in V86-mode, RF is the only defined EFLAGS bit above bit 15 that may be changed by IRETD.\n * This is less restrictive than POPFD, which cannot change ANY bits above bit 15; see opPOPF() for details.\n */\n newPS = (newPS & (0xffff | X86.PS.RF)) | (this.regPS & ~(0xffff | X86.PS.RF));\n }\n else {\n if (newPS & X86.PS.VM) {\n /*\n * As noted in loadDesc8(), where the V86-mode frame we're about to pop was originally pushed,\n * these frames ALWAYS contain 32-bit values, so make sure that sizeData reflects that.\n */\n\n /*\n * We have to assume that a full V86-mode interrupt frame was on the protected-mode stack; namely:\n *\n * low: EIP\n * CS (padded to 32 bits)\n * EFLAGS\n * ESP\n * SS (padded to 32 bits)\n * ES (padded to 32 bits)\n * DS (padded to 32 bits)\n * FS (padded to 32 bits)\n * high: GS (padded to 32 bits)\n *\n * We've already popped EIP, CS, and EFLAGS into newIP, newCS and newPS, respectively, so we must now\n * pop the rest, while we're still in protected-mode, before the switch to V86-mode alters the current\n * operand size (among other things).\n */\n var newSP = this.popWord();\n var newSS = this.popWord();\n var newES = this.popWord();\n var newDS = this.popWord();\n var newFS = this.popWord();\n var newGS = this.popWord();\n this.setProtMode(true, true); // flip the switch to V86-mode now\n this.setSS(newSS);\n this.setSP(newSP);\n this.setES(newES);\n this.setDS(newDS);\n this.setFS(newFS);\n this.setGS(newGS);\n }\n }\n }\n\n if (this.setCSIP(newIP, newCS, false) != null) {\n this.setPS(newPS, cpl);\n if (this.cIntReturn) this.checkIntReturn(this.regLIP);\n }\n }\n\n this.opLSP = X86.ADDR_INVALID;\n this.opSS = -1;\n};\n\n/**\n * helpRETF(n)\n *\n * For protected-mode, this function must pop any arguments off the current stack AND whatever stack\n * we may have switched to; setCSIP() returns true if a stack switch occurred, false if not, and null\n * if an error occurred.\n *\n * @this {CPUX86}\n * @param {number} n\n */\nX86.helpRETF = function(n)\n{\n this.opSS = this.getSS();\n this.opLSP = this.regLSP;\n\n var newIP = this.popWord();\n var newCS = this.popWord();\n\n if (n) this.setSP(this.getSP() + n); // TODO: optimize\n\n if (this.setCSIP(newIP, newCS, false)) { // returns true if a stack switch occurred\n /*\n * Fool me once, shame on... whatever. If setCSIP() indicates a stack switch occurred,\n * make sure we're in protected mode, because automatic stack switches can't occur in real mode.\n */\n\n\n if (n) this.setSP(this.getSP() + n); // TODO: optimize\n\n /*\n * As per Intel documentation: \"If any of [the DS or ES] registers refer to segments whose DPL is\n * less than the new CPL (excluding conforming code segments), the segment register is loaded with\n * the null selector.\"\n *\n * TODO: I'm not clear on whether a conforming code segment must also be marked readable, so I'm playing\n * it safe and using CODE_CONFORMING instead of CODE_CONFORMING_READABLE. Also, for the record, I've not\n * seen this situation occur yet (eg, in OS/2 1.0).\n */\n X86.zeroSeg.call(this, this.segDS);\n X86.zeroSeg.call(this, this.segES);\n if (I386 && this.model >= X86.MODEL_80386) {\n X86.zeroSeg.call(this, this.segFS);\n X86.zeroSeg.call(this, this.segGS);\n }\n }\n if (n == 2 && this.cIntReturn) this.checkIntReturn(this.regLIP);\n\n this.opLSP = X86.ADDR_INVALID;\n this.opSS = -1;\n};\n\n/**\n * helpDIVOverflow()\n *\n * @this {CPUX86}\n */\nX86.helpDIVOverflow = function()\n{\n /*\n * Divide error exceptions are traps on the 8086 and faults on later processors. I question the value of that\n * change, because it implies that someone might actually want to restart a failing divide. The only reasonable\n * explanation I can see for the change is to enable the exception handler to accurately record the address of\n * the failing divide, which seems like a very minor benefit. It doesn't change the fact that, on any processor,\n * the exception handler's only reasonable recourse is to unwind execution to a safe point (or terminate the app).\n *\n * TODO: Determine the proper cycle cost.\n */\n if (this.model == X86.MODEL_8086) {\n X86.helpTrap.call(this, X86.EXCEPTION.DE_EXC, 2);\n } else {\n X86.helpFault.call(this, X86.EXCEPTION.DE_EXC, null, 2);\n }\n};\n\n/**\n * helpInterrupt(nIDT, nCycles)\n *\n * Helper to dispatch external interrupts. nCycles defaults to 11 for the 8086/8088\n * if no alternate value is specified.\n *\n * @this {CPUX86}\n * @param {number} nIDT\n * @param {number} [nCycles] (number of cycles in addition to the default of nOpCyclesInt)\n */\nX86.helpInterrupt = function(nIDT, nCycles)\n{\n this.nFault = nIDT;\n if (nCycles === undefined) nCycles = 11;\n X86.helpINT.call(this, nIDT, null, nCycles);\n};\n\n/**\n * helpTrap(nIDT, nCycles)\n *\n * Helper to dispatch traps (ie, exceptions that occur AFTER the instruction, with NO error code)\n *\n * @this {CPUX86}\n * @param {number} nIDT\n * @param {number} [nCycles] (number of cycles in addition to the default of nOpCyclesInt)\n */\nX86.helpTrap = function(nIDT, nCycles)\n{\n this.nFault = -1;\n X86.helpINT.call(this, nIDT, null, nCycles);\n};\n\n/**\n * helpFault(nFault, nError, nCycles, fHalt)\n *\n * Helper to dispatch faults (ie, exceptions that occur DURING an instruction and MAY generate an error code)\n *\n * @this {CPUX86}\n * @param {number} nFault\n * @param {number|null} [nError] (if omitted, no error code will be pushed)\n * @param {number} [nCycles] cycle count to pass through to helpINT(), if any\n * @param {boolean} [fHalt] (true to halt the CPU, false to not, undefined if \"it depends\")\n */\nX86.helpFault = function(nFault, nError, nCycles, fHalt)\n{\n var fDispatch = false;\n\n if (!this.flags.complete) {\n /*\n * Prior to each new burst of instructions, stepCPU() sets fComplete to true, and the only (normal) way\n * for fComplete to become false is through stopCPU(), which isn't ordinarily called, except by the Debugger.\n */\n this.setLIP(this.opLIP);\n }\n else if (this.model >= X86.MODEL_80186) {\n\n fDispatch = true;\n\n if (this.nFault < 0) {\n /*\n * Single-fault (error code is passed through, and the responsible instruction is restartable.\n *\n * TODO: The following opCS/opLIP/opSS/opLSP checks are primarily required for 80386-based machines\n * with paging enabled, because page faults introduce a new set of complex faults that our current\n * segment load \"probes\" are insufficient to catch. So as a stop-gap measure, we rely on these four\n * \"snapshot\" registers to resolve the general instruction restartability problem (for now).\n *\n * If you want to closely examine the underlying causes of these more complex faults, set breakpoints\n * where indicated below, and examine the stack trace.\n */\n if (this.opCS != -1) {\n if (this.opCS !== this.segCS.sel) {\n /*\n * HACK: We slam the RPL into this.segCS.cpl to ensure that loading the original CS segment doesn't\n * fail. For example, if we faulted in the middle of a ring transition that loaded CS with a higher\n * privilege (lower CPL) code segment, then our attempt here to reload the lower privilege (higher CPL)\n * code segment could be viewed as a privilege violation (which it would be outside this context).\n */\n this.segCS.cpl = this.opCS & 0x3; // set breakpoint here to inspect complex faults\n this.setCS(this.opCS);\n }\n this.opCS = -1;\n }\n if (this.opLIP !== this.regLIP) {\n this.setLIP(this.opLIP); // set breakpoint here to inspect complex faults\n\n }\n if (this.opSS != -1) {\n if (this.opSS !== this.segSS.sel) {\n this.setSS(this.opSS); // set breakpoint here to inspect complex faults\n }\n this.opSS = -1;\n }\n if (this.opLSP !== X86.ADDR_INVALID) {\n if (this.opLSP !== this.regLSP) { // set breakpoint below to inspect complex faults\n this.setSP((this.regESP & ~this.segSS.maskAddr) | (this.opLSP - this.segSS.base));\n\n }\n this.opLSP = X86.ADDR_INVALID;\n }\n }\n else if (this.nFault != X86.EXCEPTION.DF_FAULT) {\n /*\n * Double-fault (error code is always zero, and the responsible instruction is not restartable).\n */\n nError = 0;\n nFault = X86.EXCEPTION.DF_FAULT;\n }\n else {\n /*\n * This is a triple-fault (usually referred to in Intel literature as a \"shutdown\", but it's actually a\n * \"reset\"). There's nothing to \"dispatch\" in this case, but we still want to let helpCheckFault() see\n * the triple-fault. However, regardless what helpCheckFault() returns, we must leave via \"throw -1\",\n * because we need to blow off whatever context triggered the triple-fault; that was less critical when\n * all we dealt with were 80286-based triple-faults (at least the \"normal\" triple-faults that OS/2 would\n * generate), but for any other unexpected triple-faults, \"dispatching\" a throw is critical. \n */\n nError = 0;\n nFault = -1;\n fHalt = false;\n this.resetRegs();\n }\n }\n\n if (X86.helpCheckFault.call(this, nFault, nError, fHalt) || nFault < 0) {\n /*\n * If this is a fault that would normally be dispatched BUT helpCheckFault() wants us to halt,\n * then we throw a bogus fault number (-1), simply to interrupt the current instruction in exactly\n * the same way that a dispatched fault would interrupt it.\n */\n if (fDispatch) throw -1;\n }\n\n if (fDispatch) {\n\n this.nFault = nFault;\n X86.helpINT.call(this, nFault, nError, nCycles);\n\n /*\n * REP'eated instructions that rewind regLIP to opLIP used to screw up this dispatch,\n * so now we slip the new regLIP into opLIP, effectively turning their action into a no-op.\n */\n this.opLIP = this.regLIP;\n\n /*\n * X86.OPFLAG.FAULT flag is used by selected opcodes to provide an early exit, restore register(s),\n * or whatever is needed to help ensure instruction restartability; there is currently no general\n * mechanism for snapping and restoring all registers for any instruction that might fault.\n *\n * X86.EXCEPTION.DB_EXC exceptions set their own special flag, X86.OPFLAG.DBEXC, to prevent redundant\n * DEBUG exceptions, so we don't need to set OPFLAG.FAULT in that case, because a DEBUG exception\n * doesn't actually prevent an instruction from executing (and therefore doesn't need to be restarted).\n */\n if (nFault == X86.EXCEPTION.DB_EXC) {\n this.opFlags |= X86.OPFLAG.DBEXC;\n } else {\n\n this.opFlags |= X86.OPFLAG.FAULT;\n }\n\n /*\n * Since this fault is likely being issued in the context of an instruction that hasn't finished\n * executing, if we don't do anything to interrupt that execution (eg, throw a JavaScript exception),\n * then we would need to shut off all further reads/writes for the current instruction.\n *\n * That's easy for any EA-based memory accesses: simply set both the NOREAD and NOWRITE flags.\n * However, there are also direct, non-EA-based memory accesses to consider. A perfect example is\n * opPUSHA(): if a GP fault occurs on any PUSH other than the last, a subsequent PUSH is likely to\n * cause another fault, which we will misinterpret as a double-fault -- unless the handler for\n * such an opcode checks this.opFlags for X86.OPFLAG.FAULT after each step of the operation.\n *\n * this.opFlags |= (X86.OPFLAG.NOREAD | X86.OPFLAG.NOWRITE);\n *\n * Fortunately, we now throw an exception that terminates the current instruction, so the above hack\n * should no longer be necessary.\n */\n throw nFault;\n }\n};\n\n/**\n * helpPageFault(addr, fPresent, fWrite)\n *\n * Helper to dispatch page faults.\n *\n * @this {CPUX86}\n * @param {number} addr\n * @param {boolean} fPresent\n * @param {boolean} fWrite\n */\nX86.helpPageFault = function(addr, fPresent, fWrite)\n{\n this.regCR2 = addr;\n var nError = 0;\n if (fPresent) nError |= X86.PTE.PRESENT;\n if (fWrite) nError |= X86.PTE.READWRITE;\n if (this.nCPL == 3) nError |= X86.PTE.USER;\n X86.helpFault.call(this, X86.EXCEPTION.PF_FAULT, nError);\n};\n\n/**\n * helpCheckFault(nFault, nError, fHalt)\n *\n * Aside from giving the Debugger an opportunity to report every fault, this also gives us the ability to\n * halt exception processing in tracks: return true to prevent the fault handler from being dispatched.\n *\n * At the moment, the only Debugger control you have over fault interception is setting MESSAGE.FAULT, which\n * will display faults as they occur, and MESSAGE.HALT, which will halt after any Debugger message, including\n * MESSAGE.FAULT. If you want execution to continue after halting, clear MESSAGE.FAULT and/or MESSAGE.HALT,\n * or single-step over the offending instruction, which will allow the fault to be dispatched.\n *\n * @this {CPUX86}\n * @param {number} nFault\n * @param {number|null} [nError] (if omitted, no error code will be reported)\n * @param {boolean} [fHalt] (true to halt the CPU, false to not, undefined if \"it depends\")\n * @return {boolean|undefined} true to block the fault (often desirable when fHalt is true), otherwise dispatch it\n */\nX86.helpCheckFault = function(nFault, nError, fHalt)\n{\n var bitsMessage = Messages.FAULT;\n\n var bOpcode = this.probeAddr(this.regLIP);\n\n /*\n * OS/2 1.0 uses an INT3 (0xCC) opcode in conjunction with an invalid IDT to trigger a triple-fault\n * reset and return to real-mode, and these resets happen quite frequently during boot; for example,\n * OS/2 startup messages are displayed using a series of INT 0x10 BIOS calls for each character, and\n * each series of BIOS calls requires a round-trip mode switch.\n *\n * Since we really only want to halt on \"bad\" faults, not \"good\" (ie, intentional) faults, we take\n * advantage of the fact that all 3 faults comprising the triple-fault point to an INT3 (0xCC) opcode,\n * and so whenever we see that opcode, we ignore the caller's fHalt flag, and suppress FAULT messages\n * unless CPU messages are also enabled.\n *\n * When a triple fault shows up, nFault is -1; it displays as 0xff only because we use toHexByte().\n */\n if (bOpcode == X86.OPCODE.INT3 && !this.addrIDTLimit) {\n fHalt = false;\n }\n\n /*\n * There are a number of V86-mode exceptions we don't need to know about. For starters, Windows 3.00\n * (and other versions of enhanced-mode Windows) use an ARPL to switch out of V86-mode, so we can ignore\n * those UD_FAULTs.\n *\n * Ditto for software interrupts, which will generate a GP_FAULT when the interrupt number (eg, 0x6D)\n * exceeds the protected-mode IDT's limit (eg, a limit of 0x2FF corresponds to a maximum interrupt number\n * of 0x5F). Windows doesn't really care if its IDT is too small, because it has to simulate all software\n * interrupts in V86-mode regardless (they generate a GP_FAULT if IOPL < 3, and even when IOPL == 3, only\n * the protected-mode IDT handler gets to run).\n */\n if (this.regPS & X86.PS.VM) {\n if (nFault == X86.EXCEPTION.UD_FAULT && bOpcode == X86.OPCODE.ARPL ||\n nFault == X86.EXCEPTION.GP_FAULT && bOpcode == X86.OPCODE.INTN) {\n fHalt = false;\n }\n }\n // else if (DEBUG && nFault == X86.EXCEPTION.GP_FAULT && fHalt === undefined) fHalt = true;\n\n /*\n * If fHalt has been explicitly set to false, we also take that as a cue to disable fault messages\n * (which you can override by turning on CPU messages).\n */\n if (fHalt === false) {\n bitsMessage |= Messages.CPU;\n }\n\n /*\n * Similarly, the PC AT ROM BIOS deliberately generates a couple of GP faults as part of the POST\n * (Power-On Self Test); we don't want to ignore those, but we don't want to halt on them either. We\n * detect those faults by virtue of the LIP being in the range 0x0F0000 to 0x0FFFFF.\n *\n * TODO: Be aware that this test can trigger false positives, such as when a V86-mode ARPL is hit; eg:\n *\n * &FD82:22F7 6338 ARPL [BX+SI],DI\n */\n if (this.regLIP >= 0x0F0000 && this.regLIP <= 0x0FFFFF) {\n fHalt = false;\n }\n\n /*\n * However, the foregoing notwithstanding, if MESSAGE.HALT is enabled along with all the other required\n * MESSAGE bits, then we want to halt regardless.\n */\n if (this.messageEnabled(bitsMessage | Messages.HALT)) {\n fHalt = true;\n }\n\n if (this.messageEnabled(bitsMessage) || fHalt) {\n\n var fRunning = this.flags.running;\n var sMessage = \"Fault \" + Str.toHexByte(nFault) + (nError != null? \" (\" + Str.toHexWord(nError) + \")\" : \"\") + \" on opcode \" + Str.toHexByte(bOpcode);\n if (fHalt && fRunning) sMessage += \" (blocked)\";\n\n if (DEBUGGER && this.dbg) {\n this.printMessage(sMessage, fHalt || bitsMessage, true);\n if (fHalt) {\n /*\n * By setting fHalt to fRunning (which is true while running but false while single-stepping),\n * this allows a fault to be dispatched when you single-step over a faulting instruction; you can\n * then continue single-stepping into the fault handler, or start running again.\n *\n * Note that we had to capture fRunning before calling printMessage(), because if MESSAGE.HALT\n * is set, printMessage() will have already halted the CPU.\n */\n fHalt = fRunning;\n this.dbg.stopCPU();\n }\n } else {\n /*\n * If there's no Debugger, then messageEnabled() must have returned false, which means that fHalt must\n * be true. Which means we should shut the machine down.\n */\n\n this.notice(sMessage);\n this.stopCPU();\n }\n }\n return fHalt;\n};\n\n/**\n * zeroSeg(seg)\n *\n * Helper to zero a segment register whenever transitioning to a less privileged (numerically higher) level.\n *\n * @this {CPUX86}\n * @param {SegX86} seg\n */\nX86.zeroSeg = function(seg)\n{\n var acc = seg.acc & X86.DESC.ACC.TYPE.CODE_OR_DATA;\n if (seg.sel & X86.SEL.MASK) {\n if (acc == X86.DESC.ACC.TYPE.CODE_EXECONLY || // non-readable code segment (not allowed)\n acc == X86.DESC.ACC.TYPE.CODE_CONFORMING || // non-readable code segment (not allowed)\n acc < X86.DESC.ACC.TYPE.CODE_CONFORMING && seg.dpl < this.nCPL && seg.dpl < (seg.sel & X86.SEL.RPL)) {\n seg.load(0);\n }\n }\n};\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/x86mods.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * Before 80386 support was added to PCx86, the approach to decoding ModRegRM bytes (which I usually\n * just call ModRM bytes) used one generated function per ModRM value. This was optimal for 16-bit processors,\n * because the functions were small, and it was maximally efficient, turning the entire ModRM decoding operation\n * into one table lookup and function call.\n *\n * However, that approach didn't scale well for 32-bit processors, which had extended ModRM capabilities in both\n * the addressing mode dimension and the operand size dimension. So I've rewritten ModRM decoding as 18 functions.\n * The first 9 are for 16-bit addressing modes, and the second 9 are for 32-bit addressing modes. Within each\n * group of 9, there are 3 for 8-bit operands, 3 for 16-bit operands, and 3 for 32-bit operands. And each group of 3\n * contains functions for register-source, memory-source, and group-source.\n *\n * Each of the 18 functions must do additional work to examine the ModRM bits, which makes decoding slightly slower,\n * but it's not really noticeable, and the speed difference didn't justify the additional generated code. So one much\n * smaller file (x86mods.js) replaces a host of older files (x86modb.js, x86modw.js, x86modb16.js, x86modw16.js,\n * x86modb32.js, x86modw32.js, and x86modsib.js).\n *\n * You can dig up the older files from the repository if you're curious, or you can run /modules/pcx86/bin/x86gen.js to\n * get a sense of what they contained (x86gen.js created most of the code, but it still had to be massaged afterward).\n */\n\n/**\n * modRegByte16(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modRegByte16 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n src = this.getEAByteData(this.regEBX + this.regESI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x01:\n src = this.getEAByteData(this.regEBX + this.regEDI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x02:\n src = this.getEAByteStack(this.regEBP + this.regESI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x03:\n src = this.getEAByteStack(this.regEBP + this.regEDI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x04:\n src = this.getEAByteData(this.regESI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x05:\n src = this.getEAByteData(this.regEDI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x06:\n src = this.getEAByteData(this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesDisp;\n break;\n case 0x07:\n src = this.getEAByteData(this.regEBX);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x40:\n src = this.getEAByteData(this.regEBX + this.regESI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x41:\n src = this.getEAByteData(this.regEBX + this.regEDI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x42:\n src = this.getEAByteStack(this.regEBP + this.regESI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x43:\n src = this.getEAByteStack(this.regEBP + this.regEDI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x44:\n src = this.getEAByteData(this.regESI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x45:\n src = this.getEAByteData(this.regEDI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x46:\n src = this.getEAByteStack(this.regEBP + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x47:\n src = this.getEAByteData(this.regEBX + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x80:\n src = this.getEAByteData(this.regEBX + this.regESI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x81:\n src = this.getEAByteData(this.regEBX + this.regEDI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x82:\n src = this.getEAByteStack(this.regEBP + this.regESI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x83:\n src = this.getEAByteStack(this.regEBP + this.regEDI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x84:\n src = this.getEAByteData(this.regESI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x85:\n src = this.getEAByteData(this.regEDI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x86:\n src = this.getEAByteStack(this.regEBP + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x87:\n src = this.getEAByteData(this.regEBX + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0xC0:\n src = this.regEAX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiAL;\n break;\n case 0xC1:\n src = this.regECX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiCL;\n break;\n case 0xC2:\n src = this.regEDX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiDL;\n break;\n case 0xC3:\n src = this.regEBX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiBL;\n break;\n case 0xC4:\n src = (this.regEAX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiAH;\n break;\n case 0xC5:\n src = (this.regECX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiCH;\n break;\n case 0xC6:\n src = (this.regEDX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiDH;\n break;\n case 0xC7:\n src = (this.regEBX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiBH;\n break;\n default:\n src = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n dst = this.regEAX & 0xff;\n break;\n case 0x1:\n dst = this.regECX & 0xff;\n break;\n case 0x2:\n dst = this.regEDX & 0xff;\n break;\n case 0x3:\n dst = this.regEBX & 0xff;\n break;\n case 0x4:\n dst = (this.regEAX >> 8) & 0xff;\n break;\n case 0x5:\n dst = (this.regECX >> 8) & 0xff;\n break;\n case 0x6:\n dst = (this.regEDX >> 8) & 0xff;\n break;\n case 0x7:\n dst = (this.regEBX >> 8) & 0xff;\n break;\n default:\n dst = 0;\n break;\n }\n\n var b = fn.call(this, dst, src);\n\n switch(reg) {\n case 0x0:\n this.regEAX = (this.regEAX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiEALo;\n break;\n case 0x1:\n this.regECX = (this.regECX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiCL = this.backTrack.btiEALo;\n break;\n case 0x2:\n this.regEDX = (this.regEDX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiDL = this.backTrack.btiEALo;\n break;\n case 0x3:\n this.regEBX = (this.regEBX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiBL = this.backTrack.btiEALo;\n break;\n case 0x4:\n this.regEAX = (this.regEAX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiAH = this.backTrack.btiEALo;\n break;\n case 0x5:\n this.regECX = (this.regECX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiCH = this.backTrack.btiEALo;\n break;\n case 0x6:\n this.regEDX = (this.regEDX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiDH = this.backTrack.btiEALo;\n break;\n case 0x7:\n this.regEBX = (this.regEBX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiBH = this.backTrack.btiEALo;\n break;\n }\n};\n\n/**\n * modMemByte16(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modMemByte16 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEAByteData(this.regEBX + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEAByteData(this.regEBX + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEAByteStack(this.regEBP + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEAByteStack(this.regEBP + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEAByteData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEAByteData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEAByteData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEAByteData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEAByteData(this.regEBX + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEAByteData(this.regEBX + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEAByteStack(this.regEBP + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEAByteStack(this.regEBP + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEAByteData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEAByteData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEAByteStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEAByteData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEAByteData(this.regEBX + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEAByteData(this.regEBX + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEAByteStack(this.regEBP + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEAByteStack(this.regEBP + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEAByteData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEAByteData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEAByteStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEAByteData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX & 0xff;\n break;\n case 0xC1:\n dst = this.regECX & 0xff;\n break;\n case 0xC2:\n dst = this.regEDX & 0xff;\n break;\n case 0xC3:\n dst = this.regEBX & 0xff;\n break;\n case 0xC4:\n dst = (this.regEAX >> 8) & 0xff;\n break;\n case 0xC5:\n dst = (this.regECX >> 8) & 0xff;\n break;\n case 0xC6:\n dst = (this.regEDX >> 8) & 0xff;\n break;\n case 0xC7:\n dst = (this.regEBX >> 8) & 0xff;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n src = this.regEAX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiAL;\n break;\n case 0x1:\n src = this.regECX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiCL;\n break;\n case 0x2:\n src = this.regEDX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiDL;\n break;\n case 0x3:\n src = this.regEBX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiBL;\n break;\n case 0x4:\n src = (this.regEAX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiAH;\n break;\n case 0x5:\n src = (this.regECX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiCH;\n break;\n case 0x6:\n src = (this.regEDX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiDH;\n break;\n case 0x7:\n src = (this.regEBX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiBH;\n break;\n default:\n src = 0;\n break;\n }\n\n var b = fn.call(this, dst, src);\n\n switch(bModRM) {\n case 0x00:\n case 0x03:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x01:\n case 0x02:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x04:\n case 0x05:\n case 0x07:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x06:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesDisp;\n break;\n case 0x40:\n case 0x43:\n case 0x80:\n case 0x83:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x41:\n case 0x42:\n case 0x81:\n case 0x82:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x44:\n case 0x45:\n case 0x46:\n case 0x47:\n case 0x84:\n case 0x85:\n case 0x86:\n case 0x87:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0xC0:\n this.regEAX = (this.regEAX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiEALo;\n break;\n case 0xC1:\n this.regECX = (this.regECX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiCL = this.backTrack.btiEALo;\n break;\n case 0xC2:\n this.regEDX = (this.regEDX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiDL = this.backTrack.btiEALo;\n break;\n case 0xC3:\n this.regEBX = (this.regEBX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiBL = this.backTrack.btiEALo;\n break;\n case 0xC4:\n this.regEAX = (this.regEAX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiAH = this.backTrack.btiEALo;\n break;\n case 0xC5:\n this.regECX = (this.regECX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiCH = this.backTrack.btiEALo;\n break;\n case 0xC6:\n this.regEDX = (this.regEDX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiDH = this.backTrack.btiEALo;\n break;\n case 0xC7:\n this.regEBX = (this.regEBX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiBH = this.backTrack.btiEALo;\n break;\n default:\n\n break;\n }\n};\n\n/**\n * modGrpByte16(afnGrp, fnSrc)\n *\n * @this {CPUX86}\n * @param {Array.<function(number,number)>} afnGrp\n * @param {function()} fnSrc\n */\nX86.modGrpByte16 = function(afnGrp, fnSrc) {\n var dst;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEAByteData(this.regEBX + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEAByteData(this.regEBX + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEAByteStack(this.regEBP + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEAByteStack(this.regEBP + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEAByteData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEAByteData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEAByteData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEAByteData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEAByteData(this.regEBX + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEAByteData(this.regEBX + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEAByteStack(this.regEBP + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEAByteStack(this.regEBP + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEAByteData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEAByteData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEAByteStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEAByteData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEAByteData(this.regEBX + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEAByteData(this.regEBX + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEAByteStack(this.regEBP + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEAByteStack(this.regEBP + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEAByteData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEAByteData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEAByteStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEAByteData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX & 0xff;\n break;\n case 0xC1:\n dst = this.regECX & 0xff;\n break;\n case 0xC2:\n dst = this.regEDX & 0xff;\n break;\n case 0xC3:\n dst = this.regEBX & 0xff;\n break;\n case 0xC4:\n dst = (this.regEAX >> 8) & 0xff;\n break;\n case 0xC5:\n dst = (this.regECX >> 8) & 0xff;\n break;\n case 0xC6:\n dst = (this.regEDX >> 8) & 0xff;\n break;\n case 0xC7:\n dst = (this.regEBX >> 8) & 0xff;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n var b = afnGrp[reg].call(this, dst, fnSrc.call(this));\n\n switch(bModRM) {\n case 0x00:\n case 0x03:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x01:\n case 0x02:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x04:\n case 0x05:\n case 0x07:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x06:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesDisp;\n break;\n case 0x40:\n case 0x43:\n case 0x80:\n case 0x83:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x41:\n case 0x42:\n case 0x81:\n case 0x82:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x44:\n case 0x45:\n case 0x46:\n case 0x47:\n case 0x84:\n case 0x85:\n case 0x86:\n case 0x87:\n this.setEAByte(b);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0xC0:\n this.regEAX = (this.regEAX & ~0xff) | b;\n break;\n case 0xC1:\n this.regECX = (this.regECX & ~0xff) | b;\n break;\n case 0xC2:\n this.regEDX = (this.regEDX & ~0xff) | b;\n break;\n case 0xC3:\n this.regEBX = (this.regEBX & ~0xff) | b;\n break;\n case 0xC4:\n this.regEAX = (this.regEAX & ~0xff00) | (b << 8);\n break;\n case 0xC5:\n this.regECX = (this.regECX & ~0xff00) | (b << 8);\n break;\n case 0xC6:\n this.regEDX = (this.regEDX & ~0xff00) | (b << 8);\n break;\n case 0xC7:\n this.regEBX = (this.regEBX & ~0xff00) | (b << 8);\n break;\n }\n};\n\n/**\n * modRegShort16(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modRegShort16 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n src = this.getEAShortData(this.regEBX + this.regESI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x01:\n src = this.getEAShortData(this.regEBX + this.regEDI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x02:\n src = this.getEAShortStack(this.regEBP + this.regESI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x03:\n src = this.getEAShortStack(this.regEBP + this.regEDI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x04:\n src = this.getEAShortData(this.regESI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x05:\n src = this.getEAShortData(this.regEDI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x06:\n src = this.getEAShortData(this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesDisp;\n break;\n case 0x07:\n src = this.getEAShortData(this.regEBX);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x40:\n src = this.getEAShortData(this.regEBX + this.regESI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x41:\n src = this.getEAShortData(this.regEBX + this.regEDI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x42:\n src = this.getEAShortStack(this.regEBP + this.regESI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x43:\n src = this.getEAShortStack(this.regEBP + this.regEDI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x44:\n src = this.getEAShortData(this.regESI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x45:\n src = this.getEAShortData(this.regEDI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x46:\n src = this.getEAShortStack(this.regEBP + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x47:\n src = this.getEAShortData(this.regEBX + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x80:\n src = this.getEAShortData(this.regEBX + this.regESI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x81:\n src = this.getEAShortData(this.regEBX + this.regEDI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x82:\n src = this.getEAShortStack(this.regEBP + this.regESI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x83:\n src = this.getEAShortStack(this.regEBP + this.regEDI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x84:\n src = this.getEAShortData(this.regESI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x85:\n src = this.getEAShortData(this.regEDI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x86:\n src = this.getEAShortStack(this.regEBP + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x87:\n src = this.getEAShortData(this.regEBX + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0xC0:\n src = this.regEAX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiAL; this.backTrack.btiEAHi = this.backTrack.btiAH;\n }\n break;\n case 0xC1:\n src = this.regECX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiCL; this.backTrack.btiEAHi = this.backTrack.btiCH;\n }\n break;\n case 0xC2:\n src = this.regEDX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDL; this.backTrack.btiEAHi = this.backTrack.btiDH;\n }\n break;\n case 0xC3:\n src = this.regEBX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBL; this.backTrack.btiEAHi = this.backTrack.btiBH;\n }\n break;\n case 0xC4:\n src = this.getSP() & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = X86.BTINFO.SP_LO; this.backTrack.btiEAHi = X86.BTINFO.SP_HI;\n }\n break;\n case 0xC5:\n src = this.regEBP & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBPLo; this.backTrack.btiEAHi = this.backTrack.btiBPHi;\n }\n break;\n case 0xC6:\n src = this.regESI & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiSILo; this.backTrack.btiEAHi = this.backTrack.btiSIHi;\n }\n break;\n case 0xC7:\n src = this.regEDI & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDILo; this.backTrack.btiEAHi = this.backTrack.btiDIHi;\n }\n break;\n default:\n src = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n dst = this.regEAX & 0xffff;\n break;\n case 0x1:\n dst = this.regECX & 0xffff;\n break;\n case 0x2:\n dst = this.regEDX & 0xffff;\n break;\n case 0x3:\n dst = this.regEBX & 0xffff;\n break;\n case 0x4:\n dst = this.getSP() & 0xffff;\n break;\n case 0x5:\n dst = this.regEBP & 0xffff;\n break;\n case 0x6:\n dst = this.regESI & 0xffff;\n break;\n case 0x7:\n dst = this.regEDI & 0xffff;\n break;\n default:\n dst = 0;\n break;\n }\n\n var w = fn.call(this, dst, src);\n\n switch(reg) {\n case 0x0:\n this.regEAX = (this.regEAX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiEALo; this.backTrack.btiAH = this.backTrack.btiEAHi;\n }\n break;\n case 0x1:\n this.regECX = (this.regECX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiEALo; this.backTrack.btiCH = this.backTrack.btiEAHi;\n }\n break;\n case 0x2:\n this.regEDX = (this.regEDX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiEALo; this.backTrack.btiDH = this.backTrack.btiEAHi;\n }\n break;\n case 0x3:\n this.regEBX = (this.regEBX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiEALo; this.backTrack.btiBH = this.backTrack.btiEAHi;\n }\n break;\n case 0x4:\n this.setSP((this.getSP() & ~0xffff) | w);\n break;\n case 0x5:\n this.regEBP = (this.regEBP & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiEALo; this.backTrack.btiBPHi = this.backTrack.btiEAHi;\n }\n break;\n case 0x6:\n this.regESI = (this.regESI & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiEALo; this.backTrack.btiSIHi = this.backTrack.btiEAHi;\n }\n break;\n case 0x7:\n this.regEDI = (this.regEDI & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiEALo; this.backTrack.btiDIHi = this.backTrack.btiEAHi;\n }\n break;\n }\n};\n\n/**\n * modMemShort16(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modMemShort16 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEAShortData(this.regEBX + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEAShortData(this.regEBX + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEAShortStack(this.regEBP + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEAShortStack(this.regEBP + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEAShortData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEAShortData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEAShortData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEAShortData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEAShortData(this.regEBX + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEAShortData(this.regEBX + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEAShortStack(this.regEBP + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEAShortStack(this.regEBP + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEAShortData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEAShortData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEAShortStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEAShortData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEAShortData(this.regEBX + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEAShortData(this.regEBX + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEAShortStack(this.regEBP + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEAShortStack(this.regEBP + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEAShortData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEAShortData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEAShortStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEAShortData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX & 0xffff;\n break;\n case 0xC1:\n dst = this.regECX & 0xffff;\n break;\n case 0xC2:\n dst = this.regEDX & 0xffff;\n break;\n case 0xC3:\n dst = this.regEBX & 0xffff;\n break;\n case 0xC4:\n dst = this.getSP() & 0xffff;\n break;\n case 0xC5:\n dst = this.regEBP & 0xffff;\n break;\n case 0xC6:\n dst = this.regESI & 0xffff;\n break;\n case 0xC7:\n dst = this.regEDI & 0xffff;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n src = this.regEAX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiAL; this.backTrack.btiEAHi = this.backTrack.btiAH;\n }\n break;\n case 0x1:\n src = this.regECX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiCL; this.backTrack.btiEAHi = this.backTrack.btiCH;\n }\n break;\n case 0x2:\n src = this.regEDX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDL; this.backTrack.btiEAHi = this.backTrack.btiDH;\n }\n break;\n case 0x3:\n src = this.regEBX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBL; this.backTrack.btiEAHi = this.backTrack.btiBH;\n }\n break;\n case 0x4:\n src = this.getSP() & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = X86.BTINFO.SP_LO; this.backTrack.btiEAHi = X86.BTINFO.SP_HI;\n }\n break;\n case 0x5:\n src = this.regEBP & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBPLo; this.backTrack.btiEAHi = this.backTrack.btiBPHi;\n }\n break;\n case 0x6:\n src = this.regESI & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiSILo; this.backTrack.btiEAHi = this.backTrack.btiSIHi;\n }\n break;\n case 0x7:\n src = this.regEDI & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDILo; this.backTrack.btiEAHi = this.backTrack.btiDIHi;\n }\n break;\n default:\n src = 0;\n break;\n }\n\n var w = fn.call(this, dst, src);\n\n switch(bModRM) {\n case 0x00:\n case 0x03:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x01:\n case 0x02:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x04:\n case 0x05:\n case 0x07:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x06:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesDisp;\n break;\n case 0x40:\n case 0x43:\n case 0x80:\n case 0x83:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x41:\n case 0x42:\n case 0x81:\n case 0x82:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x44:\n case 0x45:\n case 0x46:\n case 0x47:\n case 0x84:\n case 0x85:\n case 0x86:\n case 0x87:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0xC0:\n this.regEAX = (this.regEAX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiEALo; this.backTrack.btiAH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC1:\n this.regECX = (this.regECX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiEALo; this.backTrack.btiCH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC2:\n this.regEDX = (this.regEDX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiEALo; this.backTrack.btiDH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC3:\n this.regEBX = (this.regEBX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiEALo; this.backTrack.btiBH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC4:\n this.setSP((this.getSP() & ~0xffff) | w);\n break;\n case 0xC5:\n this.regEBP = (this.regEBP & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiEALo; this.backTrack.btiBPHi = this.backTrack.btiEAHi;\n }\n break;\n case 0xC6:\n this.regESI = (this.regESI & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiEALo; this.backTrack.btiSIHi = this.backTrack.btiEAHi;\n }\n break;\n case 0xC7:\n this.regEDI = (this.regEDI & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiEALo; this.backTrack.btiDIHi = this.backTrack.btiEAHi;\n }\n break;\n default:\n\n break;\n }\n};\n\n/**\n * modGrpShort16(afnGrp, fnSrc)\n *\n * @this {CPUX86}\n * @param {Array.<function(number,number)>} afnGrp\n * @param {function()} fnSrc\n */\nX86.modGrpShort16 = function(afnGrp, fnSrc) {\n var dst;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEAShortData(this.regEBX + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEAShortData(this.regEBX + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEAShortStack(this.regEBP + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEAShortStack(this.regEBP + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEAShortData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEAShortData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEAShortData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEAShortData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEAShortData(this.regEBX + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEAShortData(this.regEBX + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEAShortStack(this.regEBP + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEAShortStack(this.regEBP + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEAShortData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEAShortData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEAShortStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEAShortData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEAShortData(this.regEBX + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEAShortData(this.regEBX + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEAShortStack(this.regEBP + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEAShortStack(this.regEBP + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEAShortData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEAShortData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEAShortStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEAShortData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX & 0xffff;\n break;\n case 0xC1:\n dst = this.regECX & 0xffff;\n break;\n case 0xC2:\n dst = this.regEDX & 0xffff;\n break;\n case 0xC3:\n dst = this.regEBX & 0xffff;\n break;\n case 0xC4:\n dst = this.getSP() & 0xffff;\n break;\n case 0xC5:\n dst = this.regEBP & 0xffff;\n break;\n case 0xC6:\n dst = this.regESI & 0xffff;\n break;\n case 0xC7:\n dst = this.regEDI & 0xffff;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n var w = afnGrp[reg].call(this, dst, fnSrc.call(this));\n\n switch(bModRM) {\n case 0x00:\n case 0x03:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x01:\n case 0x02:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x04:\n case 0x05:\n case 0x07:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x06:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesDisp;\n break;\n case 0x40:\n case 0x43:\n case 0x80:\n case 0x83:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x41:\n case 0x42:\n case 0x81:\n case 0x82:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x44:\n case 0x45:\n case 0x46:\n case 0x47:\n case 0x84:\n case 0x85:\n case 0x86:\n case 0x87:\n this.setEAShort(w);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0xC0:\n this.regEAX = (this.regEAX & ~0xffff) | w;\n break;\n case 0xC1:\n this.regECX = (this.regECX & ~0xffff) | w;\n break;\n case 0xC2:\n this.regEDX = (this.regEDX & ~0xffff) | w;\n break;\n case 0xC3:\n this.regEBX = (this.regEBX & ~0xffff) | w;\n break;\n case 0xC4:\n this.setSP((this.getSP() & ~0xffff) | w);\n break;\n case 0xC5:\n this.regEBP = (this.regEBP & ~0xffff) | w;\n break;\n case 0xC6:\n this.regESI = (this.regESI & ~0xffff) | w;\n break;\n case 0xC7:\n this.regEDI = (this.regEDI & ~0xffff) | w;\n break;\n }\n};\n\n/**\n * modRegLong16(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modRegLong16 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n src = this.getEALongData(this.regEBX + this.regESI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x01:\n src = this.getEALongData(this.regEBX + this.regEDI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x02:\n src = this.getEALongStack(this.regEBP + this.regESI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x03:\n src = this.getEALongStack(this.regEBP + this.regEDI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x04:\n src = this.getEALongData(this.regESI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x05:\n src = this.getEALongData(this.regEDI);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x06:\n src = this.getEALongData(this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesDisp;\n break;\n case 0x07:\n src = this.getEALongData(this.regEBX);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x40:\n src = this.getEALongData(this.regEBX + this.regESI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x41:\n src = this.getEALongData(this.regEBX + this.regEDI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x42:\n src = this.getEALongStack(this.regEBP + this.regESI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x43:\n src = this.getEALongStack(this.regEBP + this.regEDI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x44:\n src = this.getEALongData(this.regESI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x45:\n src = this.getEALongData(this.regEDI + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x46:\n src = this.getEALongStack(this.regEBP + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x47:\n src = this.getEALongData(this.regEBX + this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x80:\n src = this.getEALongData(this.regEBX + this.regESI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x81:\n src = this.getEALongData(this.regEBX + this.regEDI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x82:\n src = this.getEALongStack(this.regEBP + this.regESI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x83:\n src = this.getEALongStack(this.regEBP + this.regEDI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x84:\n src = this.getEALongData(this.regESI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x85:\n src = this.getEALongData(this.regEDI + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x86:\n src = this.getEALongStack(this.regEBP + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0x87:\n src = this.getEALongData(this.regEBX + this.getIPAddr());\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0xC0:\n src = this.regEAX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiAL; this.backTrack.btiEAHi = this.backTrack.btiAH;\n }\n break;\n case 0xC1:\n src = this.regECX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiCL; this.backTrack.btiEAHi = this.backTrack.btiCH;\n }\n break;\n case 0xC2:\n src = this.regEDX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDL; this.backTrack.btiEAHi = this.backTrack.btiDH;\n }\n break;\n case 0xC3:\n src = this.regEBX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBL; this.backTrack.btiEAHi = this.backTrack.btiBH;\n }\n break;\n case 0xC4:\n src = this.getSP();\n if (BACKTRACK) {\n this.backTrack.btiEALo = X86.BTINFO.SP_LO; this.backTrack.btiEAHi = X86.BTINFO.SP_HI;\n }\n break;\n case 0xC5:\n src = this.regEBP;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBPLo; this.backTrack.btiEAHi = this.backTrack.btiBPHi;\n }\n break;\n case 0xC6:\n src = this.regESI;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiSILo; this.backTrack.btiEAHi = this.backTrack.btiSIHi;\n }\n break;\n case 0xC7:\n src = this.regEDI;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDILo; this.backTrack.btiEAHi = this.backTrack.btiDIHi;\n }\n break;\n default:\n src = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n dst = this.regEAX;\n break;\n case 0x1:\n dst = this.regECX;\n break;\n case 0x2:\n dst = this.regEDX;\n break;\n case 0x3:\n dst = this.regEBX;\n break;\n case 0x4:\n dst = this.getSP();\n break;\n case 0x5:\n dst = this.regEBP;\n break;\n case 0x6:\n dst = this.regESI;\n break;\n case 0x7:\n dst = this.regEDI;\n break;\n default:\n dst = 0;\n break;\n }\n\n var l = fn.call(this, dst, src);\n\n switch(reg) {\n case 0x0:\n this.regEAX = l;\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiEALo; this.backTrack.btiAH = this.backTrack.btiEAHi;\n }\n break;\n case 0x1:\n this.regECX = l;\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiEALo; this.backTrack.btiCH = this.backTrack.btiEAHi;\n }\n break;\n case 0x2:\n this.regEDX = l;\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiEALo; this.backTrack.btiDH = this.backTrack.btiEAHi;\n }\n break;\n case 0x3:\n this.regEBX = l;\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiEALo; this.backTrack.btiBH = this.backTrack.btiEAHi;\n }\n break;\n case 0x4:\n this.setSP(l);\n break;\n case 0x5:\n this.regEBP = l;\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiEALo; this.backTrack.btiBPHi = this.backTrack.btiEAHi;\n }\n break;\n case 0x6:\n this.regESI = l;\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiEALo; this.backTrack.btiSIHi = this.backTrack.btiEAHi;\n }\n break;\n case 0x7:\n this.regEDI = l;\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiEALo; this.backTrack.btiDIHi = this.backTrack.btiEAHi;\n }\n break;\n }\n};\n\n/**\n * modMemLong16(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modMemLong16 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEALongData(this.regEBX + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEALongData(this.regEBX + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEALongStack(this.regEBP + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEALongStack(this.regEBP + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEALongData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEALongData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEALongData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEALongData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEALongData(this.regEBX + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEALongData(this.regEBX + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEALongStack(this.regEBP + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEALongStack(this.regEBP + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEALongData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEALongData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEALongStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEALongData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEALongData(this.regEBX + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEALongData(this.regEBX + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEALongStack(this.regEBP + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEALongStack(this.regEBP + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEALongData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEALongData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEALongStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEALongData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX;\n break;\n case 0xC1:\n dst = this.regECX;\n break;\n case 0xC2:\n dst = this.regEDX;\n break;\n case 0xC3:\n dst = this.regEBX;\n break;\n case 0xC4:\n dst = this.getSP();\n break;\n case 0xC5:\n dst = this.regEBP;\n break;\n case 0xC6:\n dst = this.regESI;\n break;\n case 0xC7:\n dst = this.regEDI;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n src = this.regEAX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiAL; this.backTrack.btiEAHi = this.backTrack.btiAH;\n }\n break;\n case 0x1:\n src = this.regECX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiCL; this.backTrack.btiEAHi = this.backTrack.btiCH;\n }\n break;\n case 0x2:\n src = this.regEDX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDL; this.backTrack.btiEAHi = this.backTrack.btiDH;\n }\n break;\n case 0x3:\n src = this.regEBX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBL; this.backTrack.btiEAHi = this.backTrack.btiBH;\n }\n break;\n case 0x4:\n src = this.getSP();\n if (BACKTRACK) {\n this.backTrack.btiEALo = X86.BTINFO.SP_LO; this.backTrack.btiEAHi = X86.BTINFO.SP_HI;\n }\n break;\n case 0x5:\n src = this.regEBP;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBPLo; this.backTrack.btiEAHi = this.backTrack.btiBPHi;\n }\n break;\n case 0x6:\n src = this.regESI;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiSILo; this.backTrack.btiEAHi = this.backTrack.btiSIHi;\n }\n break;\n case 0x7:\n src = this.regEDI;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDILo; this.backTrack.btiEAHi = this.backTrack.btiDIHi;\n }\n break;\n default:\n src = 0;\n break;\n }\n\n var l = fn.call(this, dst, src);\n\n switch(bModRM) {\n case 0x00:\n case 0x03:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x01:\n case 0x02:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x04:\n case 0x05:\n case 0x07:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x06:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesDisp;\n break;\n case 0x40:\n case 0x43:\n case 0x80:\n case 0x83:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x41:\n case 0x42:\n case 0x81:\n case 0x82:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x44:\n case 0x45:\n case 0x46:\n case 0x47:\n case 0x84:\n case 0x85:\n case 0x86:\n case 0x87:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0xC0:\n this.regEAX = l;\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiEALo; this.backTrack.btiAH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC1:\n this.regECX = l;\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiEALo; this.backTrack.btiCH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC2:\n this.regEDX = l;\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiEALo; this.backTrack.btiDH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC3:\n this.regEBX = l;\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiEALo; this.backTrack.btiBH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC4:\n this.setSP(l);\n break;\n case 0xC5:\n this.regEBP = l;\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiEALo; this.backTrack.btiBPHi = this.backTrack.btiEAHi;\n }\n break;\n case 0xC6:\n this.regESI = l;\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiEALo; this.backTrack.btiSIHi = this.backTrack.btiEAHi;\n }\n break;\n case 0xC7:\n this.regEDI = l;\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiEALo; this.backTrack.btiDIHi = this.backTrack.btiEAHi;\n }\n break;\n default:\n\n break;\n }\n};\n\n/**\n * modGrpLong16(afnGrp, fnSrc)\n *\n * @this {CPUX86}\n * @param {Array.<function(number,number)>} afnGrp\n * @param {function()} fnSrc\n */\nX86.modGrpLong16 = function(afnGrp, fnSrc) {\n var dst;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEALongData(this.regEBX + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEALongData(this.regEBX + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEALongStack(this.regEBP + this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEALongStack(this.regEBP + this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEALongData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEALongData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEALongData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEALongData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEALongData(this.regEBX + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEALongData(this.regEBX + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEALongStack(this.regEBP + this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEALongStack(this.regEBP + this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEALongData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEALongData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEALongStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEALongData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEALongData(this.regEBX + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEALongData(this.regEBX + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEALongStack(this.regEBP + this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEALongStack(this.regEBP + this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEALongData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEALongData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEALongStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEALongData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX;\n break;\n case 0xC1:\n dst = this.regECX;\n break;\n case 0xC2:\n dst = this.regEDX;\n break;\n case 0xC3:\n dst = this.regEBX;\n break;\n case 0xC4:\n dst = this.getSP();\n break;\n case 0xC5:\n dst = this.regEBP;\n break;\n case 0xC6:\n dst = this.regESI;\n break;\n case 0xC7:\n dst = this.regEDI;\n break;\n default:\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n var l = afnGrp[reg].call(this, dst, fnSrc.call(this));\n\n switch(bModRM) {\n case 0x00:\n case 0x03:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndex;\n break;\n case 0x01:\n case 0x02:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexExtra;\n break;\n case 0x04:\n case 0x05:\n case 0x07:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBase;\n break;\n case 0x06:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesDisp;\n break;\n case 0x40:\n case 0x43:\n case 0x80:\n case 0x83:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDisp;\n break;\n case 0x41:\n case 0x42:\n case 0x81:\n case 0x82:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseIndexDispExtra;\n break;\n case 0x44:\n case 0x45:\n case 0x46:\n case 0x47:\n case 0x84:\n case 0x85:\n case 0x86:\n case 0x87:\n this.setEALong(l);\n this.nStepCycles -= this.cycleCounts.nEACyclesBaseDisp;\n break;\n case 0xC0:\n this.regEAX = l;\n break;\n case 0xC1:\n this.regECX = l;\n break;\n case 0xC2:\n this.regEDX = l;\n break;\n case 0xC3:\n this.regEBX = l;\n break;\n case 0xC4:\n this.setSP(l);\n break;\n case 0xC5:\n this.regEBP = l;\n break;\n case 0xC6:\n this.regESI = l;\n break;\n case 0xC7:\n this.regEDI = l;\n break;\n }\n};\n\n/**\n * modRegByte32(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modRegByte32 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n src = this.getEAByteData(this.regEAX);\n break;\n case 0x01:\n src = this.getEAByteData(this.regECX);\n break;\n case 0x02:\n src = this.getEAByteData(this.regEDX);\n break;\n case 0x03:\n src = this.getEAByteData(this.regEBX);\n break;\n case 0x04:\n src = this.getEAByteData(X86.modSIB.call(this, 0));\n break;\n case 0x05:\n src = this.getEAByteData(this.getIPAddr());\n break;\n case 0x06:\n src = this.getEAByteData(this.regESI);\n break;\n case 0x07:\n src = this.getEAByteData(this.regEDI);\n break;\n case 0x40:\n src = this.getEAByteData(this.regEAX + this.getIPDisp());\n break;\n case 0x41:\n src = this.getEAByteData(this.regECX + this.getIPDisp());\n break;\n case 0x42:\n src = this.getEAByteData(this.regEDX + this.getIPDisp());\n break;\n case 0x43:\n src = this.getEAByteData(this.regEBX + this.getIPDisp());\n break;\n case 0x44:\n src = this.getEAByteData(X86.modSIB.call(this, 1) + this.getIPDisp());\n break;\n case 0x45:\n src = this.getEAByteStack(this.regEBP + this.getIPDisp());\n break;\n case 0x46:\n src = this.getEAByteData(this.regESI + this.getIPDisp());\n break;\n case 0x47:\n src = this.getEAByteData(this.regEDI + this.getIPDisp());\n break;\n case 0x80:\n src = this.getEAByteData(this.regEAX + this.getIPAddr());\n break;\n case 0x81:\n src = this.getEAByteData(this.regECX + this.getIPAddr());\n break;\n case 0x82:\n src = this.getEAByteData(this.regEDX + this.getIPAddr());\n break;\n case 0x83:\n src = this.getEAByteData(this.regEBX + this.getIPAddr());\n break;\n case 0x84:\n src = this.getEAByteData(X86.modSIB.call(this, 2) + this.getIPAddr());\n break;\n case 0x85:\n src = this.getEAByteStack(this.regEBP + this.getIPAddr());\n break;\n case 0x86:\n src = this.getEAByteData(this.regESI + this.getIPAddr());\n break;\n case 0x87:\n src = this.getEAByteData(this.regEDI + this.getIPAddr());\n break;\n case 0xC0:\n src = this.regEAX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiAL;\n break;\n case 0xC1:\n src = this.regECX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiCL;\n break;\n case 0xC2:\n src = this.regEDX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiDL;\n break;\n case 0xC3:\n src = this.regEBX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiBL;\n break;\n case 0xC4:\n src = (this.regEAX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiAH;\n break;\n case 0xC5:\n src = (this.regECX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiCH;\n break;\n case 0xC6:\n src = (this.regEDX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiDH;\n break;\n case 0xC7:\n src = (this.regEBX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiBH;\n break;\n default:\n src = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n dst = this.regEAX & 0xff;\n break;\n case 0x1:\n dst = this.regECX & 0xff;\n break;\n case 0x2:\n dst = this.regEDX & 0xff;\n break;\n case 0x3:\n dst = this.regEBX & 0xff;\n break;\n case 0x4:\n dst = (this.regEAX >> 8) & 0xff;\n break;\n case 0x5:\n dst = (this.regECX >> 8) & 0xff;\n break;\n case 0x6:\n dst = (this.regEDX >> 8) & 0xff;\n break;\n case 0x7:\n dst = (this.regEBX >> 8) & 0xff;\n break;\n default:\n dst = 0;\n break;\n }\n\n var b = fn.call(this, dst, src);\n\n switch(reg) {\n case 0x0:\n this.regEAX = (this.regEAX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiEALo;\n break;\n case 0x1:\n this.regECX = (this.regECX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiCL = this.backTrack.btiEALo;\n break;\n case 0x2:\n this.regEDX = (this.regEDX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiDL = this.backTrack.btiEALo;\n break;\n case 0x3:\n this.regEBX = (this.regEBX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiBL = this.backTrack.btiEALo;\n break;\n case 0x4:\n this.regEAX = (this.regEAX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiAH = this.backTrack.btiEALo;\n break;\n case 0x5:\n this.regECX = (this.regECX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiCH = this.backTrack.btiEALo;\n break;\n case 0x6:\n this.regEDX = (this.regEDX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiDH = this.backTrack.btiEALo;\n break;\n case 0x7:\n this.regEBX = (this.regEBX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiBH = this.backTrack.btiEALo;\n break;\n }\n};\n\n/**\n * modMemByte32(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modMemByte32 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEAByteData(this.regEAX);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEAByteData(this.regECX);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEAByteData(this.regEDX);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEAByteData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEAByteData(X86.modSIB.call(this, 0));\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEAByteData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEAByteData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEAByteData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEAByteData(this.regEAX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEAByteData(this.regECX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEAByteData(this.regEDX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEAByteData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEAByteData(X86.modSIB.call(this, 1) + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEAByteStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEAByteData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEAByteData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEAByteData(this.regEAX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEAByteData(this.regECX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEAByteData(this.regEDX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEAByteData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEAByteData(X86.modSIB.call(this, 2) + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEAByteStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEAByteData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEAByteData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX & 0xff;\n break;\n case 0xC1:\n dst = this.regECX & 0xff;\n break;\n case 0xC2:\n dst = this.regEDX & 0xff;\n break;\n case 0xC3:\n dst = this.regEBX & 0xff;\n break;\n case 0xC4:\n dst = (this.regEAX >> 8) & 0xff;\n break;\n case 0xC5:\n dst = (this.regECX >> 8) & 0xff;\n break;\n case 0xC6:\n dst = (this.regEDX >> 8) & 0xff;\n break;\n case 0xC7:\n dst = (this.regEBX >> 8) & 0xff;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n src = this.regEAX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiAL;\n break;\n case 0x1:\n src = this.regECX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiCL;\n break;\n case 0x2:\n src = this.regEDX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiDL;\n break;\n case 0x3:\n src = this.regEBX & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiBL;\n break;\n case 0x4:\n src = (this.regEAX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiAH;\n break;\n case 0x5:\n src = (this.regECX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiCH;\n break;\n case 0x6:\n src = (this.regEDX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiDH;\n break;\n case 0x7:\n src = (this.regEBX >> 8) & 0xff;\n if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiBH;\n break;\n default:\n src = 0;\n break;\n }\n\n var b = fn.call(this, dst, src);\n\n switch(bModRM) {\n case 0xC0:\n this.regEAX = (this.regEAX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiEALo;\n break;\n case 0xC1:\n this.regECX = (this.regECX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiCL = this.backTrack.btiEALo;\n break;\n case 0xC2:\n this.regEDX = (this.regEDX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiDL = this.backTrack.btiEALo;\n break;\n case 0xC3:\n this.regEBX = (this.regEBX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiBL = this.backTrack.btiEALo;\n break;\n case 0xC4:\n this.regEAX = (this.regEAX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiAH = this.backTrack.btiEALo;\n break;\n case 0xC5:\n this.regECX = (this.regECX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiCH = this.backTrack.btiEALo;\n break;\n case 0xC6:\n this.regEDX = (this.regEDX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiDH = this.backTrack.btiEALo;\n break;\n case 0xC7:\n this.regEBX = (this.regEBX & ~0xff00) | (b << 8);\n if (BACKTRACK) this.backTrack.btiBH = this.backTrack.btiEALo;\n break;\n default:\n this.setEAByte(b);\n break;\n }\n};\n\n/**\n * modGrpByte32(afnGrp, fnSrc)\n *\n * @this {CPUX86}\n * @param {Array.<function(number,number)>} afnGrp\n * @param {function()} fnSrc\n */\nX86.modGrpByte32 = function(afnGrp, fnSrc) {\n var dst;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEAByteData(this.regEAX);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEAByteData(this.regECX);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEAByteData(this.regEDX);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEAByteData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEAByteData(X86.modSIB.call(this, 0));\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEAByteData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEAByteData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEAByteData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEAByteData(this.regEAX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEAByteData(this.regECX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEAByteData(this.regEDX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEAByteData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEAByteData(X86.modSIB.call(this, 1) + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEAByteStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEAByteData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEAByteData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEAByteData(this.regEAX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEAByteData(this.regECX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEAByteData(this.regEDX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEAByteData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEAByteData(X86.modSIB.call(this, 2) + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEAByteStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEAByteData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEAByteData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX & 0xff;\n break;\n case 0xC1:\n dst = this.regECX & 0xff;\n break;\n case 0xC2:\n dst = this.regEDX & 0xff;\n break;\n case 0xC3:\n dst = this.regEBX & 0xff;\n break;\n case 0xC4:\n dst = (this.regEAX >> 8) & 0xff;\n break;\n case 0xC5:\n dst = (this.regECX >> 8) & 0xff;\n break;\n case 0xC6:\n dst = (this.regEDX >> 8) & 0xff;\n break;\n case 0xC7:\n dst = (this.regEBX >> 8) & 0xff;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n var b = afnGrp[reg].call(this, dst, fnSrc.call(this));\n\n switch(bModRM) {\n case 0xC0:\n this.regEAX = (this.regEAX & ~0xff) | b;\n break;\n case 0xC1:\n this.regECX = (this.regECX & ~0xff) | b;\n break;\n case 0xC2:\n this.regEDX = (this.regEDX & ~0xff) | b;\n break;\n case 0xC3:\n this.regEBX = (this.regEBX & ~0xff) | b;\n break;\n case 0xC4:\n this.regEAX = (this.regEAX & ~0xff00) | (b << 8);\n break;\n case 0xC5:\n this.regECX = (this.regECX & ~0xff00) | (b << 8);\n break;\n case 0xC6:\n this.regEDX = (this.regEDX & ~0xff00) | (b << 8);\n break;\n case 0xC7:\n this.regEBX = (this.regEBX & ~0xff00) | (b << 8);\n break;\n default:\n this.setEAByte(b);\n break;\n }\n};\n\n/**\n * modRegShort32(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modRegShort32 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n src = this.getEAShortData(this.regEAX);\n break;\n case 0x01:\n src = this.getEAShortData(this.regECX);\n break;\n case 0x02:\n src = this.getEAShortData(this.regEDX);\n break;\n case 0x03:\n src = this.getEAShortData(this.regEBX);\n break;\n case 0x04:\n src = this.getEAShortData(X86.modSIB.call(this, 0));\n break;\n case 0x05:\n src = this.getEAShortData(this.getIPAddr());\n break;\n case 0x06:\n src = this.getEAShortData(this.regESI);\n break;\n case 0x07:\n src = this.getEAShortData(this.regEDI);\n break;\n case 0x40:\n src = this.getEAShortData(this.regEAX + this.getIPDisp());\n break;\n case 0x41:\n src = this.getEAShortData(this.regECX + this.getIPDisp());\n break;\n case 0x42:\n src = this.getEAShortData(this.regEDX + this.getIPDisp());\n break;\n case 0x43:\n src = this.getEAShortData(this.regEBX + this.getIPDisp());\n break;\n case 0x44:\n src = this.getEAShortData(X86.modSIB.call(this, 1) + this.getIPDisp());\n break;\n case 0x45:\n src = this.getEAShortStack(this.regEBP + this.getIPDisp());\n break;\n case 0x46:\n src = this.getEAShortData(this.regESI + this.getIPDisp());\n break;\n case 0x47:\n src = this.getEAShortData(this.regEDI + this.getIPDisp());\n break;\n case 0x80:\n src = this.getEAShortData(this.regEAX + this.getIPAddr());\n break;\n case 0x81:\n src = this.getEAShortData(this.regECX + this.getIPAddr());\n break;\n case 0x82:\n src = this.getEAShortData(this.regEDX + this.getIPAddr());\n break;\n case 0x83:\n src = this.getEAShortData(this.regEBX + this.getIPAddr());\n break;\n case 0x84:\n src = this.getEAShortData(X86.modSIB.call(this, 2) + this.getIPAddr());\n break;\n case 0x85:\n src = this.getEAShortStack(this.regEBP + this.getIPAddr());\n break;\n case 0x86:\n src = this.getEAShortData(this.regESI + this.getIPAddr());\n break;\n case 0x87:\n src = this.getEAShortData(this.regEDI + this.getIPAddr());\n break;\n case 0xC0:\n src = this.regEAX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiAL; this.backTrack.btiEAHi = this.backTrack.btiAH;\n }\n break;\n case 0xC1:\n src = this.regECX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiCL; this.backTrack.btiEAHi = this.backTrack.btiCH;\n }\n break;\n case 0xC2:\n src = this.regEDX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDL; this.backTrack.btiEAHi = this.backTrack.btiDH;\n }\n break;\n case 0xC3:\n src = this.regEBX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBL; this.backTrack.btiEAHi = this.backTrack.btiBH;\n }\n break;\n case 0xC4:\n src = this.getSP() & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = X86.BTINFO.SP_LO; this.backTrack.btiEAHi = X86.BTINFO.SP_HI;\n }\n break;\n case 0xC5:\n src = this.regEBP & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBPLo; this.backTrack.btiEAHi = this.backTrack.btiBPHi;\n }\n break;\n case 0xC6:\n src = this.regESI & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiSILo; this.backTrack.btiEAHi = this.backTrack.btiSIHi;\n }\n break;\n case 0xC7:\n src = this.regEDI & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDILo; this.backTrack.btiEAHi = this.backTrack.btiDIHi;\n }\n break;\n default:\n src = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n dst = this.regEAX & 0xffff;\n break;\n case 0x1:\n dst = this.regECX & 0xffff;\n break;\n case 0x2:\n dst = this.regEDX & 0xffff;\n break;\n case 0x3:\n dst = this.regEBX & 0xffff;\n break;\n case 0x4:\n dst = this.getSP() & 0xffff;\n break;\n case 0x5:\n dst = this.regEBP & 0xffff;\n break;\n case 0x6:\n dst = this.regESI & 0xffff;\n break;\n case 0x7:\n dst = this.regEDI & 0xffff;\n break;\n default:\n dst = 0;\n break;\n }\n\n var w = fn.call(this, dst, src);\n\n switch(reg) {\n case 0x0:\n this.regEAX = (this.regEAX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiEALo; this.backTrack.btiAH = this.backTrack.btiEAHi;\n }\n break;\n case 0x1:\n this.regECX = (this.regECX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiEALo; this.backTrack.btiCH = this.backTrack.btiEAHi;\n }\n break;\n case 0x2:\n this.regEDX = (this.regEDX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiEALo; this.backTrack.btiDH = this.backTrack.btiEAHi;\n }\n break;\n case 0x3:\n this.regEBX = (this.regEBX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiEALo; this.backTrack.btiBH = this.backTrack.btiEAHi;\n }\n break;\n case 0x4:\n this.setSP((this.getSP() & ~0xffff) | w);\n break;\n case 0x5:\n this.regEBP = (this.regEBP & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiEALo; this.backTrack.btiBPHi = this.backTrack.btiEAHi;\n }\n break;\n case 0x6:\n this.regESI = (this.regESI & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiEALo; this.backTrack.btiSIHi = this.backTrack.btiEAHi;\n }\n break;\n case 0x7:\n this.regEDI = (this.regEDI & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiEALo; this.backTrack.btiDIHi = this.backTrack.btiEAHi;\n }\n break;\n }\n};\n\n/**\n * modMemShort32(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modMemShort32 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEAShortData(this.regEAX);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEAShortData(this.regECX);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEAShortData(this.regEDX);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEAShortData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEAShortData(X86.modSIB.call(this, 0));\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEAShortData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEAShortData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEAShortData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEAShortData(this.regEAX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEAShortData(this.regECX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEAShortData(this.regEDX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEAShortData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEAShortData(X86.modSIB.call(this, 1) + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEAShortStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEAShortData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEAShortData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEAShortData(this.regEAX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEAShortData(this.regECX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEAShortData(this.regEDX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEAShortData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEAShortData(X86.modSIB.call(this, 2) + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEAShortStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEAShortData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEAShortData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX & 0xffff;\n break;\n case 0xC1:\n dst = this.regECX & 0xffff;\n break;\n case 0xC2:\n dst = this.regEDX & 0xffff;\n break;\n case 0xC3:\n dst = this.regEBX & 0xffff;\n break;\n case 0xC4:\n dst = this.getSP() & 0xffff;\n break;\n case 0xC5:\n dst = this.regEBP & 0xffff;\n break;\n case 0xC6:\n dst = this.regESI & 0xffff;\n break;\n case 0xC7:\n dst = this.regEDI & 0xffff;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n src = this.regEAX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiAL; this.backTrack.btiEAHi = this.backTrack.btiAH;\n }\n break;\n case 0x1:\n src = this.regECX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiCL; this.backTrack.btiEAHi = this.backTrack.btiCH;\n }\n break;\n case 0x2:\n src = this.regEDX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDL; this.backTrack.btiEAHi = this.backTrack.btiDH;\n }\n break;\n case 0x3:\n src = this.regEBX & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBL; this.backTrack.btiEAHi = this.backTrack.btiBH;\n }\n break;\n case 0x4:\n src = this.getSP() & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = X86.BTINFO.SP_LO; this.backTrack.btiEAHi = X86.BTINFO.SP_HI;\n }\n break;\n case 0x5:\n src = this.regEBP & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBPLo; this.backTrack.btiEAHi = this.backTrack.btiBPHi;\n }\n break;\n case 0x6:\n src = this.regESI & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiSILo; this.backTrack.btiEAHi = this.backTrack.btiSIHi;\n }\n break;\n case 0x7:\n src = this.regEDI & 0xffff;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDILo; this.backTrack.btiEAHi = this.backTrack.btiDIHi;\n }\n break;\n default:\n src = 0;\n break;\n }\n\n var w = fn.call(this, dst, src);\n\n switch(bModRM) {\n case 0xC0:\n this.regEAX = (this.regEAX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiEALo; this.backTrack.btiAH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC1:\n this.regECX = (this.regECX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiEALo; this.backTrack.btiCH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC2:\n this.regEDX = (this.regEDX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiEALo; this.backTrack.btiDH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC3:\n this.regEBX = (this.regEBX & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiEALo; this.backTrack.btiBH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC4:\n this.setSP((this.getSP() & ~0xffff) | w);\n break;\n case 0xC5:\n this.regEBP = (this.regEBP & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiEALo; this.backTrack.btiBPHi = this.backTrack.btiEAHi;\n }\n break;\n case 0xC6:\n this.regESI = (this.regESI & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiEALo; this.backTrack.btiSIHi = this.backTrack.btiEAHi;\n }\n break;\n case 0xC7:\n this.regEDI = (this.regEDI & ~0xffff) | w;\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiEALo; this.backTrack.btiDIHi = this.backTrack.btiEAHi;\n }\n break;\n default:\n this.setEAShort(w);\n break;\n }\n};\n\n/**\n * modGrpShort32(afnGrp, fnSrc)\n *\n * @this {CPUX86}\n * @param {Array.<function(number,number)>} afnGrp\n * @param {function()} fnSrc\n */\nX86.modGrpShort32 = function(afnGrp, fnSrc) {\n var dst;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEAShortData(this.regEAX);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEAShortData(this.regECX);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEAShortData(this.regEDX);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEAShortData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEAShortData(X86.modSIB.call(this, 0));\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEAShortData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEAShortData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEAShortData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEAShortData(this.regEAX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEAShortData(this.regECX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEAShortData(this.regEDX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEAShortData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEAShortData(X86.modSIB.call(this, 1) + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEAShortStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEAShortData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEAShortData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEAShortData(this.regEAX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEAShortData(this.regECX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEAShortData(this.regEDX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEAShortData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEAShortData(X86.modSIB.call(this, 2) + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEAShortStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEAShortData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEAShortData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX & 0xffff;\n break;\n case 0xC1:\n dst = this.regECX & 0xffff;\n break;\n case 0xC2:\n dst = this.regEDX & 0xffff;\n break;\n case 0xC3:\n dst = this.regEBX & 0xffff;\n break;\n case 0xC4:\n dst = this.getSP() & 0xffff;\n break;\n case 0xC5:\n dst = this.regEBP & 0xffff;\n break;\n case 0xC6:\n dst = this.regESI & 0xffff;\n break;\n case 0xC7:\n dst = this.regEDI & 0xffff;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n var w = afnGrp[reg].call(this, dst, fnSrc.call(this));\n\n switch(bModRM) {\n case 0xC0:\n this.regEAX = (this.regEAX & ~0xffff) | w;\n break;\n case 0xC1:\n this.regECX = (this.regECX & ~0xffff) | w;\n break;\n case 0xC2:\n this.regEDX = (this.regEDX & ~0xffff) | w;\n break;\n case 0xC3:\n this.regEBX = (this.regEBX & ~0xffff) | w;\n break;\n case 0xC4:\n this.setSP((this.getSP() & ~0xffff) | w);\n break;\n case 0xC5:\n this.regEBP = (this.regEBP & ~0xffff) | w;\n break;\n case 0xC6:\n this.regESI = (this.regESI & ~0xffff) | w;\n break;\n case 0xC7:\n this.regEDI = (this.regEDI & ~0xffff) | w;\n break;\n default:\n this.setEAShort(w);\n break;\n }\n};\n\n/**\n * modRegLong32(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modRegLong32 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n src = this.getEALongData(this.regEAX);\n break;\n case 0x01:\n src = this.getEALongData(this.regECX);\n break;\n case 0x02:\n src = this.getEALongData(this.regEDX);\n break;\n case 0x03:\n src = this.getEALongData(this.regEBX);\n break;\n case 0x04:\n src = this.getEALongData(X86.modSIB.call(this, 0));\n break;\n case 0x05:\n src = this.getEALongData(this.getIPAddr());\n break;\n case 0x06:\n src = this.getEALongData(this.regESI);\n break;\n case 0x07:\n src = this.getEALongData(this.regEDI);\n break;\n case 0x40:\n src = this.getEALongData(this.regEAX + this.getIPDisp());\n break;\n case 0x41:\n src = this.getEALongData(this.regECX + this.getIPDisp());\n break;\n case 0x42:\n src = this.getEALongData(this.regEDX + this.getIPDisp());\n break;\n case 0x43:\n src = this.getEALongData(this.regEBX + this.getIPDisp());\n break;\n case 0x44:\n src = this.getEALongData(X86.modSIB.call(this, 1) + this.getIPDisp());\n break;\n case 0x45:\n src = this.getEALongStack(this.regEBP + this.getIPDisp());\n break;\n case 0x46:\n src = this.getEALongData(this.regESI + this.getIPDisp());\n break;\n case 0x47:\n src = this.getEALongData(this.regEDI + this.getIPDisp());\n break;\n case 0x80:\n src = this.getEALongData(this.regEAX + this.getIPAddr());\n break;\n case 0x81:\n src = this.getEALongData(this.regECX + this.getIPAddr());\n break;\n case 0x82:\n src = this.getEALongData(this.regEDX + this.getIPAddr());\n break;\n case 0x83:\n src = this.getEALongData(this.regEBX + this.getIPAddr());\n break;\n case 0x84:\n src = this.getEALongData(X86.modSIB.call(this, 2) + this.getIPAddr());\n break;\n case 0x85:\n src = this.getEALongStack(this.regEBP + this.getIPAddr());\n break;\n case 0x86:\n src = this.getEALongData(this.regESI + this.getIPAddr());\n break;\n case 0x87:\n src = this.getEALongData(this.regEDI + this.getIPAddr());\n break;\n case 0xC0:\n src = this.regEAX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiAL; this.backTrack.btiEAHi = this.backTrack.btiAH;\n }\n break;\n case 0xC1:\n src = this.regECX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiCL; this.backTrack.btiEAHi = this.backTrack.btiCH;\n }\n break;\n case 0xC2:\n src = this.regEDX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDL; this.backTrack.btiEAHi = this.backTrack.btiDH;\n }\n break;\n case 0xC3:\n src = this.regEBX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBL; this.backTrack.btiEAHi = this.backTrack.btiBH;\n }\n break;\n case 0xC4:\n src = this.getSP();\n if (BACKTRACK) {\n this.backTrack.btiEALo = X86.BTINFO.SP_LO; this.backTrack.btiEAHi = X86.BTINFO.SP_HI;\n }\n break;\n case 0xC5:\n src = this.regEBP;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBPLo; this.backTrack.btiEAHi = this.backTrack.btiBPHi;\n }\n break;\n case 0xC6:\n src = this.regESI;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiSILo; this.backTrack.btiEAHi = this.backTrack.btiSIHi;\n }\n break;\n case 0xC7:\n src = this.regEDI;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDILo; this.backTrack.btiEAHi = this.backTrack.btiDIHi;\n }\n break;\n default:\n src = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n dst = this.regEAX;\n break;\n case 0x1:\n dst = this.regECX;\n break;\n case 0x2:\n dst = this.regEDX;\n break;\n case 0x3:\n dst = this.regEBX;\n break;\n case 0x4:\n dst = this.getSP();\n break;\n case 0x5:\n dst = this.regEBP;\n break;\n case 0x6:\n dst = this.regESI;\n break;\n case 0x7:\n dst = this.regEDI;\n break;\n default:\n dst = 0;\n break;\n }\n\n var l = fn.call(this, dst, src);\n\n switch(reg) {\n case 0x0:\n this.regEAX = l;\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiEALo; this.backTrack.btiAH = this.backTrack.btiEAHi;\n }\n break;\n case 0x1:\n this.regECX = l;\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiEALo; this.backTrack.btiCH = this.backTrack.btiEAHi;\n }\n break;\n case 0x2:\n this.regEDX = l;\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiEALo; this.backTrack.btiDH = this.backTrack.btiEAHi;\n }\n break;\n case 0x3:\n this.regEBX = l;\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiEALo; this.backTrack.btiBH = this.backTrack.btiEAHi;\n }\n break;\n case 0x4:\n this.setSP(l);\n break;\n case 0x5:\n this.regEBP = l;\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiEALo; this.backTrack.btiBPHi = this.backTrack.btiEAHi;\n }\n break;\n case 0x6:\n this.regESI = l;\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiEALo; this.backTrack.btiSIHi = this.backTrack.btiEAHi;\n }\n break;\n case 0x7:\n this.regEDI = l;\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiEALo; this.backTrack.btiDIHi = this.backTrack.btiEAHi;\n }\n break;\n }\n};\n\n/**\n * modMemLong32(fn)\n *\n * @this {CPUX86}\n * @param {function(number,number)} fn (dst,src)\n */\nX86.modMemLong32 = function(fn)\n{\n var dst, src;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEALongData(this.regEAX);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEALongData(this.regECX);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEALongData(this.regEDX);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEALongData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEALongData(X86.modSIB.call(this, 0));\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEALongData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEALongData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEALongData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEALongData(this.regEAX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEALongData(this.regECX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEALongData(this.regEDX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEALongData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEALongData(X86.modSIB.call(this, 1) + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEALongStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEALongData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEALongData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEALongData(this.regEAX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEALongData(this.regECX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEALongData(this.regEDX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEALongData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEALongData(X86.modSIB.call(this, 2) + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEALongStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEALongData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEALongData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX;\n break;\n case 0xC1:\n dst = this.regECX;\n break;\n case 0xC2:\n dst = this.regEDX;\n break;\n case 0xC3:\n dst = this.regEBX;\n break;\n case 0xC4:\n dst = this.getSP();\n break;\n case 0xC5:\n dst = this.regEBP;\n break;\n case 0xC6:\n dst = this.regESI;\n break;\n case 0xC7:\n dst = this.regEDI;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n switch(reg) {\n case 0x0:\n src = this.regEAX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiAL; this.backTrack.btiEAHi = this.backTrack.btiAH;\n }\n break;\n case 0x1:\n src = this.regECX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiCL; this.backTrack.btiEAHi = this.backTrack.btiCH;\n }\n break;\n case 0x2:\n src = this.regEDX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDL; this.backTrack.btiEAHi = this.backTrack.btiDH;\n }\n break;\n case 0x3:\n src = this.regEBX;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBL; this.backTrack.btiEAHi = this.backTrack.btiBH;\n }\n break;\n case 0x4:\n src = this.getSP();\n if (BACKTRACK) {\n this.backTrack.btiEALo = X86.BTINFO.SP_LO; this.backTrack.btiEAHi = X86.BTINFO.SP_HI;\n }\n break;\n case 0x5:\n src = this.regEBP;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiBPLo; this.backTrack.btiEAHi = this.backTrack.btiBPHi;\n }\n break;\n case 0x6:\n src = this.regESI;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiSILo; this.backTrack.btiEAHi = this.backTrack.btiSIHi;\n }\n break;\n case 0x7:\n src = this.regEDI;\n if (BACKTRACK) {\n this.backTrack.btiEALo = this.backTrack.btiDILo; this.backTrack.btiEAHi = this.backTrack.btiDIHi;\n }\n break;\n default:\n src = 0;\n break;\n }\n\n var l = fn.call(this, dst, src);\n\n switch(bModRM) {\n case 0xC0:\n this.regEAX = l;\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiEALo; this.backTrack.btiAH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC1:\n this.regECX = l;\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiEALo; this.backTrack.btiCH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC2:\n this.regEDX = l;\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiEALo; this.backTrack.btiDH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC3:\n this.regEBX = l;\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiEALo; this.backTrack.btiBH = this.backTrack.btiEAHi;\n }\n break;\n case 0xC4:\n this.setSP(l);\n break;\n case 0xC5:\n this.regEBP = l;\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiEALo; this.backTrack.btiBPHi = this.backTrack.btiEAHi;\n }\n break;\n case 0xC6:\n this.regESI = l;\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiEALo; this.backTrack.btiSIHi = this.backTrack.btiEAHi;\n }\n break;\n case 0xC7:\n this.regEDI = l;\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiEALo; this.backTrack.btiDIHi = this.backTrack.btiEAHi;\n }\n break;\n default:\n this.setEALong(l);\n break;\n }\n};\n\n/**\n * modGrpLong32(afnGrp, fnSrc)\n *\n * @this {CPUX86}\n * @param {Array.<function(number,number)>} afnGrp\n * @param {function()} fnSrc\n */\nX86.modGrpLong32 = function(afnGrp, fnSrc) {\n var dst;\n var bModRM = (this.bModRM = this.getIPByte()) & 0xC7;\n\n switch(bModRM) {\n case 0x00:\n dst = this.getEALongData(this.regEAX);\n this.regEAWrite = this.regEA;\n break;\n case 0x01:\n dst = this.getEALongData(this.regECX);\n this.regEAWrite = this.regEA;\n break;\n case 0x02:\n dst = this.getEALongData(this.regEDX);\n this.regEAWrite = this.regEA;\n break;\n case 0x03:\n dst = this.getEALongData(this.regEBX);\n this.regEAWrite = this.regEA;\n break;\n case 0x04:\n dst = this.getEALongData(X86.modSIB.call(this, 0));\n this.regEAWrite = this.regEA;\n break;\n case 0x05:\n dst = this.getEALongData(this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x06:\n dst = this.getEALongData(this.regESI);\n this.regEAWrite = this.regEA;\n break;\n case 0x07:\n dst = this.getEALongData(this.regEDI);\n this.regEAWrite = this.regEA;\n break;\n case 0x40:\n dst = this.getEALongData(this.regEAX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x41:\n dst = this.getEALongData(this.regECX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x42:\n dst = this.getEALongData(this.regEDX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x43:\n dst = this.getEALongData(this.regEBX + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x44:\n dst = this.getEALongData(X86.modSIB.call(this, 1) + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x45:\n dst = this.getEALongStack(this.regEBP + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x46:\n dst = this.getEALongData(this.regESI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x47:\n dst = this.getEALongData(this.regEDI + this.getIPDisp());\n this.regEAWrite = this.regEA;\n break;\n case 0x80:\n dst = this.getEALongData(this.regEAX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x81:\n dst = this.getEALongData(this.regECX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x82:\n dst = this.getEALongData(this.regEDX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x83:\n dst = this.getEALongData(this.regEBX + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x84:\n dst = this.getEALongData(X86.modSIB.call(this, 2) + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x85:\n dst = this.getEALongStack(this.regEBP + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x86:\n dst = this.getEALongData(this.regESI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0x87:\n dst = this.getEALongData(this.regEDI + this.getIPAddr());\n this.regEAWrite = this.regEA;\n break;\n case 0xC0:\n dst = this.regEAX;\n break;\n case 0xC1:\n dst = this.regECX;\n break;\n case 0xC2:\n dst = this.regEDX;\n break;\n case 0xC3:\n dst = this.regEBX;\n break;\n case 0xC4:\n dst = this.getSP();\n break;\n case 0xC5:\n dst = this.regEBP;\n break;\n case 0xC6:\n dst = this.regESI;\n break;\n case 0xC7:\n dst = this.regEDI;\n break;\n default:\n dst = 0;\n\n break;\n }\n\n var reg = (this.bModRM >> 3) & 0x7;\n\n var l = afnGrp[reg].call(this, dst, fnSrc.call(this));\n\n switch(bModRM) {\n case 0xC0:\n this.regEAX = l;\n break;\n case 0xC1:\n this.regECX = l;\n break;\n case 0xC2:\n this.regEDX = l;\n break;\n case 0xC3:\n this.regEBX = l;\n break;\n case 0xC4:\n this.setSP(l);\n break;\n case 0xC5:\n this.regEBP = l;\n break;\n case 0xC6:\n this.regESI = l;\n break;\n case 0xC7:\n this.regEDI = l;\n break;\n default:\n this.setEALong(l);\n break;\n }\n};\n\n/**\n * modSIB(mod)\n *\n * @this {CPUX86}\n * @param {number} mod\n * @return {number}\n */\nX86.modSIB = function(mod)\n{\n var bSIB = this.getIPByte();\n var scale = bSIB >> 6, index, base;\n\n switch((bSIB >> 3) & 0x7) {\n case 0:\n index = this.regEAX;\n break;\n case 1:\n index = this.regECX;\n break;\n case 2:\n index = this.regEDX;\n break;\n case 3:\n index = this.regEBX;\n break;\n case 4:\n index = 0;\n break;\n case 5:\n index = this.regEBP;\n break;\n case 6:\n index = this.regESI;\n break;\n case 7:\n index = this.regEDI;\n break;\n }\n\n switch(bSIB & 0x07) {\n case 0:\n base = this.regEAX;\n break;\n case 1:\n base = this.regECX;\n break;\n case 2:\n base = this.regEDX;\n break;\n case 3:\n base = this.regEBX;\n break;\n case 4:\n base = this.getSP();\n this.segData = this.segStack;\n break;\n case 5:\n if (mod) {\n base = this.regEBP;\n this.segData = this.segStack;\n } else {\n base = this.getIPAddr();\n }\n break;\n case 6:\n base = this.regESI;\n break;\n case 7:\n base = this.regEDI;\n break;\n }\n\n return ((index << scale) + base)|0;\n};\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/x86ops.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * op=0x00 (ADD byte,reg)\n *\n * @this {CPUX86}\n */\nX86.opADDmb = function()\n{\n this.decodeModMemByte.call(this, X86.fnADDb);\n /*\n * Opcode bytes 0x00 0x00 are sufficiently uncommon that it's more likely we've started\n * executing in the weeds, so if you're in DEBUG mode, we'll print a warning and stop the\n * CPU if a Debugger is available.\n *\n * Notice that we also test fRunning: this allows the Debugger to step over the instruction,\n * because its trace (\"t\") command doesn't \"run\" the CPU; it merely \"steps\" the CPU.\n */\n if (DEBUG && !this.bModRM && this.flags.running) {\n this.printMessage(\"suspicious opcode: 0x00 0x00\", DEBUGGER || this.bitsMessage);\n if (DEBUGGER && this.dbg) this.dbg.stopCPU();\n }\n};\n\n/**\n * op=0x01 (ADD word,reg)\n *\n * @this {CPUX86}\n */\nX86.opADDmw = function()\n{\n this.decodeModMemWord.call(this, X86.fnADDw);\n};\n\n/**\n * op=0x02 (ADD reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opADDrb = function()\n{\n this.decodeModRegByte.call(this, X86.fnADDb);\n};\n\n/**\n * op=0x03 (ADD reg,word)\n *\n * @this {CPUX86}\n */\nX86.opADDrw = function()\n{\n this.decodeModRegWord.call(this, X86.fnADDw);\n};\n\n/**\n * op=0x04 (ADD AL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opADDALb = function()\n{\n this.regEAX = (this.regEAX & ~0xff) | X86.fnADDb.call(this, this.regEAX & 0xff, this.getIPByte());\n /*\n * NOTE: Whenever the result is \"blended\" value (eg, of btiAL and btiMem0), a new bti should be\n * allocated to reflect that fact; however, I'm leaving \"perfect\" BACKTRACK support for another day.\n */\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiMem0;\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x05 (ADD AX,imm16 or ADD EAX,imm32)\n *\n * @this {CPUX86}\n */\nX86.opADDAX = function()\n{\n this.regEAX = (this.regEAX & ~this.maskData) | X86.fnADDw.call(this, this.regEAX & this.maskData, this.getIPWord());\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x06 (PUSH ES)\n *\n * @this {CPUX86}\n */\nX86.opPUSHES = function()\n{\n /*\n * When the OPERAND size is 32 bits, the 80386 will decrement the stack pointer by 4, write the selector\n * into the 2 lower bytes, and leave the 2 upper bytes untouched; to properly emulate that, we must use the\n * more generic pushData() instead of pushWord().\n */\n if (!I386) {\n this.pushWord(this.segES.sel);\n } else {\n this.pushData(this.segES.sel, this.sizeData, 2);\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushSeg;\n};\n\n/**\n * op=0x07 (POP ES)\n *\n * @this {CPUX86}\n */\nX86.opPOPES = function()\n{\n /*\n * Any operation that modifies the stack before loading a new segment must snapshot regLSP first.\n */\n this.opLSP = this.regLSP;\n this.setES(this.popWord());\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n this.opLSP = X86.ADDR_INVALID;\n};\n\n/**\n * op=0x08 (OR byte,reg)\n *\n * @this {CPUX86}\n */\nX86.opORmb = function()\n{\n this.decodeModMemByte.call(this, X86.fnORb);\n};\n\n/**\n * op=0x09 (OR word,reg)\n *\n * @this {CPUX86}\n */\nX86.opORmw = function()\n{\n this.decodeModMemWord.call(this, X86.fnORw);\n};\n\n/**\n * op=0x0A (OR reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opORrb = function()\n{\n this.decodeModRegByte.call(this, X86.fnORb);\n};\n\n/**\n * op=0x0B (OR reg,word)\n *\n * @this {CPUX86}\n */\nX86.opORrw = function()\n{\n this.decodeModRegWord.call(this, X86.fnORw);\n};\n\n/**\n * op=0x0C (OR AL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opORALb = function()\n{\n this.regEAX = (this.regEAX & ~0xff) | X86.fnORb.call(this, this.regEAX & 0xff, this.getIPByte());\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiMem0;\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x0D (OR AX,imm16 or OR EAX,imm32)\n *\n * @this {CPUX86}\n */\nX86.opORAX = function()\n{\n this.regEAX = (this.regEAX & ~this.maskData) | X86.fnORw.call(this, this.regEAX & this.maskData, this.getIPWord());\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x0E (PUSH CS)\n *\n * @this {CPUX86}\n */\nX86.opPUSHCS = function()\n{\n /*\n * When the OPERAND size is 32 bits, the 80386 will decrement the stack pointer by 4, write the selector\n * into the 2 lower bytes, and leave the 2 upper bytes untouched; to properly emulate that, we must use the\n * more generic pushData() instead of pushWord().\n */\n if (!I386) {\n this.pushWord(this.segCS.sel);\n } else {\n this.pushData(this.segCS.sel, this.sizeData, 2);\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushSeg;\n};\n\n/**\n * op=0x0F (POP CS) (undocumented on 8086/8088; replaced with opInvalid() on 80186/80188, and op0F() on 80286 and up)\n *\n * @this {CPUX86}\n */\nX86.opPOPCS = function()\n{\n /*\n * Because this is an 8088-only operation, we don't have to worry about taking a snapshot of regLSP first.\n */\n this.setCS(this.popWord());\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n};\n\n/**\n * op=0x0F (handler for two-byte opcodes; 80286 and up)\n *\n * @this {CPUX86}\n */\nX86.op0F = function()\n{\n this.aOps0F[this.getIPByte()].call(this);\n};\n\n/**\n * op=0x10 (ADC byte,reg)\n *\n * @this {CPUX86}\n */\nX86.opADCmb = function()\n{\n this.decodeModMemByte.call(this, X86.fnADCb);\n};\n\n/**\n * op=0x11 (ADC word,reg)\n *\n * @this {CPUX86}\n */\nX86.opADCmw = function()\n{\n this.decodeModMemWord.call(this, X86.fnADCw);\n};\n\n/**\n * op=0x12 (ADC reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opADCrb = function()\n{\n this.decodeModRegByte.call(this, X86.fnADCb);\n};\n\n/**\n * op=0x13 (ADC reg,word)\n *\n * @this {CPUX86}\n */\nX86.opADCrw = function()\n{\n this.decodeModRegWord.call(this, X86.fnADCw);\n};\n\n/**\n * op=0x14 (ADC AL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opADCALb = function()\n{\n this.regEAX = (this.regEAX & ~0xff) | X86.fnADCb.call(this, this.regEAX & 0xff, this.getIPByte());\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiMem0;\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x15 (ADC AX,imm16 or ADC EAX,imm32)\n *\n * @this {CPUX86}\n */\nX86.opADCAX = function()\n{\n this.regEAX = (this.regEAX & ~this.maskData) | X86.fnADCw.call(this, this.regEAX & this.maskData, this.getIPWord());\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x16 (PUSH SS)\n *\n * @this {CPUX86}\n */\nX86.opPUSHSS = function()\n{\n /*\n * When the OPERAND size is 32 bits, the 80386 will decrement the stack pointer by 4, write the selector\n * into the 2 lower bytes, and leave the 2 upper bytes untouched; to properly emulate that, we must use the\n * more generic pushData() instead of pushWord().\n */\n if (!I386) {\n this.pushWord(this.segSS.sel);\n } else {\n this.pushData(this.segSS.sel, this.sizeData, 2);\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushSeg;\n};\n\n/**\n * op=0x17 (POP SS)\n *\n * @this {CPUX86}\n */\nX86.opPOPSS = function()\n{\n /*\n * Any operation that modifies the stack before loading a new segment must snapshot regLSP first.\n */\n this.opLSP = this.regLSP;\n this.setSS(this.popWord());\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n this.opLSP = X86.ADDR_INVALID;\n};\n\n/**\n * op=0x18 (SBB byte,reg)\n *\n * @this {CPUX86}\n */\nX86.opSBBmb = function()\n{\n this.decodeModMemByte.call(this, X86.fnSBBb);\n};\n\n/**\n * op=0x19 (SBB word,reg)\n *\n * @this {CPUX86}\n */\nX86.opSBBmw = function()\n{\n this.decodeModMemWord.call(this, X86.fnSBBw);\n};\n\n/**\n * op=0x1A (SBB reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opSBBrb = function()\n{\n this.decodeModRegByte.call(this, X86.fnSBBb);\n};\n\n/**\n * op=0x1B (SBB reg,word)\n *\n * @this {CPUX86}\n */\nX86.opSBBrw = function()\n{\n this.decodeModRegWord.call(this, X86.fnSBBw);\n};\n\n/**\n * op=0x1C (SBB AL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opSBBALb = function()\n{\n this.regEAX = (this.regEAX & ~0xff) | X86.fnSBBb.call(this, this.regEAX & 0xff, this.getIPByte());\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiMem0;\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x1D (SBB AX,imm16 or SBB EAX,imm32)\n *\n * @this {CPUX86}\n */\nX86.opSBBAX = function()\n{\n this.regEAX = (this.regEAX & ~this.maskData) | X86.fnSBBw.call(this, this.regEAX & this.maskData, this.getIPWord());\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x1E (PUSH DS)\n *\n * @this {CPUX86}\n */\nX86.opPUSHDS = function()\n{\n /*\n * When the OPERAND size is 32 bits, the 80386 will decrement the stack pointer by 4, write the selector\n * into the 2 lower bytes, and leave the 2 upper bytes untouched; to properly emulate that, we must use the\n * more generic pushData() instead of pushWord().\n */\n if (!I386) {\n this.pushWord(this.segDS.sel);\n } else {\n this.pushData(this.segDS.sel, this.sizeData, 2);\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushSeg;\n};\n\n/**\n * op=0x1F (POP DS)\n *\n * @this {CPUX86}\n */\nX86.opPOPDS = function()\n{\n /*\n * Any operation that modifies the stack before loading a new segment must snapshot regLSP first.\n */\n this.opLSP = this.regLSP;\n this.setDS(this.popWord());\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n this.opLSP = X86.ADDR_INVALID;\n};\n\n/**\n * op=0x20 (AND byte,reg)\n *\n * @this {CPUX86}\n */\nX86.opANDmb = function()\n{\n this.decodeModMemByte.call(this, X86.fnANDb);\n};\n\n/**\n * op=0x21 (AND word,reg)\n *\n * @this {CPUX86}\n */\nX86.opANDmw = function()\n{\n this.decodeModMemWord.call(this, X86.fnANDw);\n};\n\n/**\n * op=0x22 (AND reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opANDrb = function()\n{\n this.decodeModRegByte.call(this, X86.fnANDb);\n};\n\n/**\n * op=0x23 (AND reg,word)\n *\n * @this {CPUX86}\n */\nX86.opANDrw = function()\n{\n this.decodeModRegWord.call(this, X86.fnANDw);\n};\n\n/**\n * op=0x24 (AND AL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opANDAL = function()\n{\n this.regEAX = (this.regEAX & ~0xff) | X86.fnANDb.call(this, this.regEAX & 0xff, this.getIPByte());\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiMem0;\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x25 (AND AX,imm16 or AND EAX,imm32)\n *\n * @this {CPUX86}\n */\nX86.opANDAX = function()\n{\n this.regEAX = (this.regEAX & ~this.maskData) | X86.fnANDw.call(this, this.regEAX & this.maskData, this.getIPWord());\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x26 (ES:)\n *\n * @this {CPUX86}\n */\nX86.opES = function()\n{\n this.opFlags |= X86.OPFLAG.SEG | X86.OPFLAG.NOINTR;\n this.segData = this.segStack = this.segES;\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n};\n\n/**\n * op=0x27 (DAA)\n *\n * @this {CPUX86}\n */\nX86.opDAA = function()\n{\n var AL = this.regEAX & 0xff;\n var AF = this.getAF();\n var CF = this.getCF();\n if ((AL & 0xf) > 9 || AF) {\n AL += 0x6;\n AF = X86.PS.AF;\n } else {\n AF = 0;\n }\n if (AL > 0x9f || CF) {\n AL += 0x60;\n CF = X86.PS.CF;\n } else {\n CF = 0;\n }\n var b = (AL & 0xff);\n this.regEAX = (this.regEAX & ~0xff) | b;\n this.setLogicResult(b, X86.RESULT.BYTE);\n if (CF) this.setCF(); else this.clearCF();\n if (AF) this.setAF(); else this.clearAF();\n this.nStepCycles -= this.cycleCounts.nOpCyclesAAA; // AAA and DAA have the same cycle times\n};\n\n/**\n * op=0x28 (SUB byte,reg)\n *\n * @this {CPUX86}\n */\nX86.opSUBmb = function()\n{\n this.decodeModMemByte.call(this, X86.fnSUBb);\n};\n\n/**\n * op=0x29 (SUB word,reg)\n *\n * @this {CPUX86}\n */\nX86.opSUBmw = function()\n{\n this.decodeModMemWord.call(this, X86.fnSUBw);\n};\n\n/**\n * op=0x2A (SUB reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opSUBrb = function()\n{\n this.decodeModRegByte.call(this, X86.fnSUBb);\n};\n\n/**\n * op=0x2B (SUB reg,word)\n *\n * @this {CPUX86}\n */\nX86.opSUBrw = function()\n{\n this.decodeModRegWord.call(this, X86.fnSUBw);\n};\n\n/**\n * op=0x2C (SUB AL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opSUBALb = function()\n{\n this.regEAX = (this.regEAX & ~0xff) | X86.fnSUBb.call(this, this.regEAX & 0xff, this.getIPByte());\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiMem0;\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x2D (SUB AX,imm16 or SUB EAX,imm32)\n *\n * @this {CPUX86}\n */\nX86.opSUBAX = function()\n{\n this.regEAX = (this.regEAX & ~this.maskData) | X86.fnSUBw.call(this, this.regEAX & this.maskData, this.getIPWord());\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x2E (CS:)\n *\n * @this {CPUX86}\n */\nX86.opCS = function()\n{\n this.opFlags |= X86.OPFLAG.SEG | X86.OPFLAG.NOINTR;\n this.segData = this.segStack = this.segCS;\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n};\n\n/**\n * op=0x2F (DAS)\n *\n * @this {CPUX86}\n */\nX86.opDAS = function()\n{\n var AL = this.regEAX & 0xff;\n var AF = this.getAF();\n var CF = this.getCF();\n if ((AL & 0xf) > 9 || AF) {\n AL -= 0x6;\n AF = X86.PS.AF;\n } else {\n AF = 0;\n }\n if (AL > 0x9f || CF) {\n AL -= 0x60;\n CF = X86.PS.CF;\n } else {\n CF = 0;\n }\n var b = (AL & 0xff);\n this.regEAX = (this.regEAX & ~0xff) | b;\n this.setLogicResult(b, X86.RESULT.BYTE);\n if (CF) this.setCF(); else this.clearCF();\n if (AF) this.setAF(); else this.clearAF();\n this.nStepCycles -= this.cycleCounts.nOpCyclesAAA; // AAA and DAS have the same cycle times\n};\n\n/**\n * op=0x30 (XOR byte,reg)\n *\n * @this {CPUX86}\n */\nX86.opXORmb = function()\n{\n this.decodeModMemByte.call(this, X86.fnXORb);\n};\n\n/**\n * op=0x31 (XOR word,reg)\n *\n * @this {CPUX86}\n */\nX86.opXORmw = function()\n{\n this.decodeModMemWord.call(this, X86.fnXORw);\n};\n\n/**\n * op=0x32 (XOR reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opXORrb = function()\n{\n this.decodeModRegByte.call(this, X86.fnXORb);\n};\n\n/**\n * op=0x33 (XOR reg,word)\n *\n * @this {CPUX86}\n */\nX86.opXORrw = function()\n{\n this.decodeModRegWord.call(this, X86.fnXORw);\n};\n\n/**\n * op=0x34 (XOR AL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opXORALb = function()\n{\n this.regEAX = (this.regEAX & ~0xff) | X86.fnXORb.call(this, this.regEAX & 0xff, this.getIPByte());\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiMem0;\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x35 (XOR AX,imm16 or XOR EAX,imm32)\n *\n * @this {CPUX86}\n */\nX86.opXORAX = function()\n{\n this.regEAX = (this.regEAX & ~this.maskData) | X86.fnXORw.call(this, this.regEAX & this.maskData, this.getIPWord());\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x36 (SS:)\n *\n * @this {CPUX86}\n */\nX86.opSS = function()\n{\n this.opFlags |= X86.OPFLAG.SEG | X86.OPFLAG.NOINTR;\n this.segData = this.segStack = this.segSS; // QUESTION: Is there a case where segStack would not already be segSS? (eg, multiple segment overrides?)\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n};\n\n/**\n * op=0x37 (AAA)\n *\n * @this {CPUX86}\n */\nX86.opAAA = function()\n{\n var CF, AF;\n var AL = this.regEAX & 0xff;\n var AH = (this.regEAX >> 8) & 0xff;\n if ((AL & 0xf) > 9 || this.getAF()) {\n AL += 6;\n /*\n * Simulate the fact that the 80286 and higher add 6 to AX rather than AL.\n */\n if (this.model >= X86.MODEL_80286 && AL > 0xff) AH++;\n AH++;\n CF = AF = 1;\n } else {\n CF = AF = 0;\n }\n this.regEAX = (this.regEAX & ~0xffff) | (((AH << 8) | AL) & 0xff0f);\n if (CF) this.setCF(); else this.clearCF();\n if (AF) this.setAF(); else this.clearAF();\n this.nStepCycles -= this.cycleCounts.nOpCyclesAAA;\n};\n\n/**\n * op=0x38 (CMP byte,reg)\n *\n * @this {CPUX86}\n */\nX86.opCMPmb = function()\n{\n this.decodeModMemByte.call(this, X86.fnCMPb);\n};\n\n/**\n * op=0x39 (CMP word,reg)\n *\n * @this {CPUX86}\n */\nX86.opCMPmw = function()\n{\n this.decodeModMemWord.call(this, X86.fnCMPw);\n};\n\n/**\n * op=0x3A (CMP reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opCMPrb = function()\n{\n this.decodeModRegByte.call(this, X86.fnCMPb);\n};\n\n/**\n * op=0x3B (CMP reg,word)\n *\n * @this {CPUX86}\n */\nX86.opCMPrw = function()\n{\n this.decodeModRegWord.call(this, X86.fnCMPw);\n};\n\n/**\n * op=0x3C (CMP AL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opCMPALb = function()\n{\n X86.fnCMPb.call(this, this.regEAX & 0xff, this.getIPByte());\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x3D (CMP AX,imm16 or CMP EAX,imm32)\n *\n * @this {CPUX86}\n */\nX86.opCMPAX = function()\n{\n X86.fnCMPw.call(this, this.regEAX & this.maskData, this.getIPWord());\n this.nStepCycles--; // in the absence of any EA calculations, we need deduct only one more cycle\n};\n\n/**\n * op=0x3E (DS:)\n *\n * @this {CPUX86}\n */\nX86.opDS = function()\n{\n this.opFlags |= X86.OPFLAG.SEG | X86.OPFLAG.NOINTR;\n this.segData = this.segStack = this.segDS; // QUESTION: Is there a case where segData would not already be segDS? (eg, multiple segment overrides?)\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n};\n\n/**\n * op=0x3D (AAS)\n *\n * @this {CPUX86}\n */\nX86.opAAS = function()\n{\n var CF, AF;\n var AL = this.regEAX & 0xff;\n var AH = (this.regEAX >> 8) & 0xff;\n if ((AL & 0xf) > 9 || this.getAF()) {\n AL = (AL - 0x6) & 0xf;\n AH = (AH - 1) & 0xff;\n CF = AF = 1;\n } else {\n CF = AF = 0;\n }\n this.regEAX = (this.regEAX & ~0xffff) | ((AH << 8) | AL);\n if (CF) this.setCF(); else this.clearCF();\n if (AF) this.setAF(); else this.clearAF();\n this.nStepCycles -= this.cycleCounts.nOpCyclesAAA; // AAA and AAS have the same cycle times\n};\n\n/**\n * op=0x40 (INC [E]AX)\n *\n * @this {CPUX86}\n */\nX86.opINCAX = function()\n{\n this.regEAX = X86.helpINCreg.call(this, this.regEAX);\n};\n\n/**\n * op=0x41 (INC [E]CX)\n *\n * @this {CPUX86}\n */\nX86.opINCCX = function()\n{\n this.regECX = X86.helpINCreg.call(this, this.regECX);\n};\n\n/**\n * op=0x42 (INC [E]DX)\n *\n * @this {CPUX86}\n */\nX86.opINCDX = function()\n{\n this.regEDX = X86.helpINCreg.call(this, this.regEDX);\n};\n\n/**\n * op=0x43 (INC [E]BX)\n *\n * @this {CPUX86}\n */\nX86.opINCBX = function()\n{\n this.regEBX = X86.helpINCreg.call(this, this.regEBX);\n};\n\n/**\n * op=0x44 (INC [E]SP)\n *\n * @this {CPUX86}\n */\nX86.opINCSP = function()\n{\n this.setSP(X86.helpINCreg.call(this, this.getSP()));\n};\n\n/**\n * op=0x45 (INC [E]BP)\n *\n * @this {CPUX86}\n */\nX86.opINCBP = function()\n{\n this.regEBP = X86.helpINCreg.call(this, this.regEBP);\n};\n\n/**\n * op=0x46 (INC [E]SI)\n *\n * @this {CPUX86}\n */\nX86.opINCSI = function()\n{\n this.regESI = X86.helpINCreg.call(this, this.regESI);\n};\n\n/**\n * op=0x47 (INC [E]DI)\n *\n * @this {CPUX86}\n */\nX86.opINCDI = function()\n{\n this.regEDI = X86.helpINCreg.call(this, this.regEDI);\n};\n\n/**\n * op=0x48 (DEC [E]AX)\n *\n * @this {CPUX86}\n */\nX86.opDECAX = function()\n{\n this.regEAX = X86.helpDECreg.call(this, this.regEAX);\n};\n\n/**\n * op=0x49 (DEC [E]CX)\n *\n * @this {CPUX86}\n */\nX86.opDECCX = function()\n{\n this.regECX = X86.helpDECreg.call(this, this.regECX);\n};\n\n/**\n * op=0x4A (DEC [E]DX)\n *\n * @this {CPUX86}\n */\nX86.opDECDX = function()\n{\n this.regEDX = X86.helpDECreg.call(this, this.regEDX);\n};\n\n/**\n * op=0x4B (DEC [E]BX)\n *\n * @this {CPUX86}\n */\nX86.opDECBX = function()\n{\n this.regEBX = X86.helpDECreg.call(this, this.regEBX);\n};\n\n/**\n * op=0x4C (DEC [E]SP)\n *\n * @this {CPUX86}\n */\nX86.opDECSP = function()\n{\n this.setSP(X86.helpDECreg.call(this, this.getSP()));\n};\n\n/**\n * op=0x4D (DEC [E]BP)\n *\n * @this {CPUX86}\n */\nX86.opDECBP = function()\n{\n this.regEBP = X86.helpDECreg.call(this, this.regEBP);\n};\n\n/**\n * op=0x4E (DEC [E]SI)\n *\n * @this {CPUX86}\n */\nX86.opDECSI = function()\n{\n this.regESI = X86.helpDECreg.call(this, this.regESI);\n};\n\n/**`\n * op=0x4F (DEC [E]DI)\n *\n * @this {CPUX86}\n */\nX86.opDECDI = function()\n{\n this.regEDI = X86.helpDECreg.call(this, this.regEDI);\n};\n\n/**\n * op=0x50 (PUSH [E]AX)\n *\n * @this {CPUX86}\n */\nX86.opPUSHAX = function()\n{\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiAL; this.backTrack.btiMem1 = this.backTrack.btiAH;\n }\n this.pushWord(this.regEAX & this.maskData);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x51 (PUSH [E]CX)\n *\n * @this {CPUX86}\n */\nX86.opPUSHCX = function()\n{\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiCL; this.backTrack.btiMem1 = this.backTrack.btiCH;\n }\n this.pushWord(this.regECX & this.maskData);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x52 (PUSH [E]DX)\n *\n * @this {CPUX86}\n */\nX86.opPUSHDX = function()\n{\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiDL; this.backTrack.btiMem1 = this.backTrack.btiDH;\n }\n this.pushWord(this.regEDX & this.maskData);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x53 (PUSH [E]BX)\n *\n * @this {CPUX86}\n */\nX86.opPUSHBX = function()\n{\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiBL; this.backTrack.btiMem1 = this.backTrack.btiBH;\n }\n this.pushWord(this.regEBX & this.maskData);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x54 (PUSH SP)\n *\n * NOTE: Having an accurate implementation of \"PUSH SP\" for the 8086/8088 isn't just a nice idea, it affects real\n * code. Case in point: early Microsoft C floating-point libraries relied on \"PUSH SP\" behavior to quickly determine\n * whether an 8088 (and therefore presumably an 8087) or an 80286 (and presumably an 80287) was being used; eg:\n *\n * &0910:1E82 D93E1709 FSTCW WORD [0917]\n * &0910:1E86 CD3D INT 3D\n * &0E4E:06D3 50 PUSH AX\n * &0E4E:06D4 B83DA2 MOV AX,A23D\n * &0E4E:06D7 EB04 JMP 06DD\n * &0E4E:06DD 55 PUSH BP\n * &0E4E:06DE 1E PUSH DS\n * &0E4E:06DF 56 PUSH SI\n * &0E4E:06E0 8BEC MOV BP,SP\n * &0E4E:06E2 C57608 LDS SI,[BP+08]\n * &0E4E:06E5 4E DEC SI\n * &0E4E:06E6 4E DEC SI\n * &0E4E:06E7 897608 MOV [BP+08],SI\n * &0E4E:06EA 2904 SUB [SI],AX\n * &0E4E:06EC 53 PUSH BX\n * &0E4E:06ED 33DB XOR BX,BX\n * &0E4E:06EF 54 PUSH SP ; beginning of processor check\n * &0E4E:06F0 58 POP AX\n * &0E4E:06F1 3BC4 CMP AX,SP\n * &0E4E:06F3 7528 JNZ 071D ; jump if 8086/8088/80186/80188, no jump if 80286 or later\n * &0E4E:06F5 8B4001 MOV AX,[BX+SI+01]\n * &0E4E:06F8 25FB30 AND AX,30FB\n * &0E4E:06FB 3DD930 CMP AX,30D9\n * &0E4E:06FE 7507 JNZ 0707\n * &0E4E:0700 8A4002 MOV AL,[BX+SI+02]\n * &0E4E:0703 3CF0 CMP AL,F0\n * &0E4E:0705 7216 JC 071D\n * &0E4E:0707 8B4001 MOV AX,[BX+SI+01]\n * &0E4E:070A 25FFFE AND AX,FEFF\n * &0E4E:070D 3DDBE2 CMP AX,E2DB\n * &0E4E:0710 740B JZ 071D\n * &0E4E:0712 8B4001 MOV AX,[BX+SI+01]\n * &0E4E:0715 3DDFE0 CMP AX,E0DF\n * &0E4E:0718 7403 JZ 071D\n * &0E4E:071A C60490 MOV [SI],90\n * &0E4E:071D 5B POP BX\n * &0E4E:071E 5E POP SI\n * &0E4E:071F 1F POP DS\n * &0E4E:0720 5D POP BP\n * &0E4E:0721 58 POP AX\n * &0E4E:0722 CF IRET\n *\n * @this {CPUX86}\n */\nX86.opPUSHSP_8086 = function()\n{\n var w = (this.getSP() - 2) & 0xffff;\n this.pushWord(w);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x54 (PUSH [E]SP)\n *\n * @this {CPUX86}\n */\nX86.opPUSHSP = function()\n{\n this.pushWord(this.getSP() & this.maskData);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x55 (PUSH [E]BP)\n *\n * @this {CPUX86}\n */\nX86.opPUSHBP = function()\n{\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiBPLo; this.backTrack.btiMem1 = this.backTrack.btiBPHi;\n }\n this.pushWord(this.regEBP & this.maskData);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x56 (PUSH [E]SI)\n *\n * @this {CPUX86}\n */\nX86.opPUSHSI = function()\n{\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiSILo; this.backTrack.btiMem1 = this.backTrack.btiSIHi;\n }\n this.pushWord(this.regESI & this.maskData);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x57 (PUSH [E]DI)\n *\n * @this {CPUX86}\n */\nX86.opPUSHDI = function()\n{\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiDILo; this.backTrack.btiMem1 = this.backTrack.btiDIHi;\n }\n this.pushWord(this.regEDI & this.maskData);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x58 (POP [E]AX)\n *\n * @this {CPUX86}\n */\nX86.opPOPAX = function()\n{\n this.regEAX = (this.regEAX & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n};\n\n/**\n * op=0x59 (POP [E]CX)\n *\n * @this {CPUX86}\n */\nX86.opPOPCX = function()\n{\n this.regECX = (this.regECX & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiMem0; this.backTrack.btiCH = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n};\n\n/**\n * op=0x5A (POP [E]DX)\n *\n * @this {CPUX86}\n */\nX86.opPOPDX = function()\n{\n this.regEDX = (this.regEDX & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiMem0; this.backTrack.btiDH = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n};\n\n/**\n * op=0x5B (POP [E]BX)\n *\n * @this {CPUX86}\n */\nX86.opPOPBX = function()\n{\n this.regEBX = (this.regEBX & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiMem0; this.backTrack.btiBH = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n};\n\n/**\n * op=0x5C (POP [E]SP)\n *\n * @this {CPUX86}\n */\nX86.opPOPSP = function()\n{\n this.setSP((this.getSP() & ~this.maskData) | this.popWord());\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n};\n\n/**\n * op=0x5D (POP [E]BP)\n *\n * @this {CPUX86}\n */\nX86.opPOPBP = function()\n{\n this.regEBP = (this.regEBP & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiMem0; this.backTrack.btiBPHi = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n};\n\n/**\n * op=0x5E (POP [E]SI)\n *\n * @this {CPUX86}\n */\nX86.opPOPSI = function()\n{\n this.regESI = (this.regESI & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiMem0; this.backTrack.btiSIHi = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n};\n\n/**\n * op=0x5F (POP [E]DI)\n *\n * @this {CPUX86}\n */\nX86.opPOPDI = function()\n{\n this.regEDI = (this.regEDI & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiMem0; this.backTrack.btiDIHi = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n};\n\n/**\n * op=0x60 (PUSHA) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opPUSHA = function()\n{\n /*\n * Any operation that performs multiple stack modifications must snapshot regLSP first.\n */\n this.opLSP = this.regLSP;\n\n /*\n * TODO: regLSP needs to be pre-bounds-checked against regLSPLimitLow\n */\n var temp = this.getSP() & this.maskData;\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiAL; this.backTrack.btiMem1 = this.backTrack.btiAH;\n }\n this.pushWord(this.regEAX & this.maskData);\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiCL; this.backTrack.btiMem1 = this.backTrack.btiCH;\n }\n this.pushWord(this.regECX & this.maskData);\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiDL; this.backTrack.btiMem1 = this.backTrack.btiDH;\n }\n this.pushWord(this.regEDX & this.maskData);\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiBL; this.backTrack.btiMem1 = this.backTrack.btiBH;\n }\n this.pushWord(this.regEBX & this.maskData);\n this.pushWord(temp);\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiBPLo; this.backTrack.btiMem1 = this.backTrack.btiBPHi;\n }\n this.pushWord(this.regEBP & this.maskData);\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiSILo; this.backTrack.btiMem1 = this.backTrack.btiSIHi;\n }\n this.pushWord(this.regESI & this.maskData);\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiDILo; this.backTrack.btiMem1 = this.backTrack.btiDIHi;\n }\n this.pushWord(this.regEDI & this.maskData);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushAll;\n\n this.opLSP = X86.ADDR_INVALID;\n};\n\n/**\n * op=0x61 (POPA) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opPOPA = function()\n{\n /*\n * Any operation that performs multiple stack modifications must snapshot regLSP first.\n */\n this.opLSP = this.regLSP;\n\n this.regEDI = (this.regEDI & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiMem0; this.backTrack.btiDIHi = this.backTrack.btiMem1;\n }\n this.regESI = (this.regESI & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiMem0; this.backTrack.btiSIHi = this.backTrack.btiMem1;\n }\n this.regEBP = (this.regEBP & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiMem0; this.backTrack.btiBPHi = this.backTrack.btiMem1;\n }\n /*\n * TODO: regLSP needs to be pre-bounds-checked against regLSPLimit at the start\n */\n this.setSP(this.getSP() + this.sizeData);\n // this.regLSP += (I386? this.sizeData : 2);\n this.regEBX = (this.regEBX & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiMem0; this.backTrack.btiBH = this.backTrack.btiMem1;\n }\n this.regEDX = (this.regEDX & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiMem0; this.backTrack.btiDH = this.backTrack.btiMem1;\n }\n this.regECX = (this.regECX & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiMem0; this.backTrack.btiCH = this.backTrack.btiMem1;\n }\n this.regEAX = (this.regEAX & ~this.maskData) | this.popWord();\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopAll;\n\n this.opLSP = X86.ADDR_INVALID;\n};\n\n/**\n * op=0x62 (BOUND reg,word) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opBOUND = function()\n{\n this.decodeModRegWord.call(this, X86.fnBOUND);\n};\n\n/**\n * op=0x63 (ARPL word,reg) (80286 and up)\n *\n * @this {CPUX86}\n */\nX86.opARPL = function()\n{\n /*\n * ARPL is one of several protected-mode instructions that are meaningless and not allowed in either real-mode\n * or V86-mode; others include LAR, LSL, VERR and VERW. More meaningful but potentially harmful protected-mode\n * instructions that ARE allowed in real-mode but NOT in V86-mode include LIDT, LGDT, LMSW, CLTS, HLT, and\n * control register MOV instructions.\n *\n * ARPL is somewhat more noteworthy because enhanced-mode Windows (going back to at least Windows 3.00, and\n * possibly even the earliest versions of Windows/386) selected the ARPL opcode as a controlled means of exiting\n * V86-mode via the UD_FAULT exception. Windows would use the same ARPL for all controlled exits, using different\n * segment:offset pointers to the ARPL to differentiate them. ARPL was probably chosen because it could trigger\n * a UD_FAULT with a single byte (0x63); any subsequent address bytes would be irrelevant.\n *\n * Which is WHY we must perform the CPU mode tests below rather than in the fnARPL() worker; otherwise we could\n * generate additional (bogus) faults, based on the address of the first operand.\n *\n * TODO: You may have noticed that setProtMode() already swaps out a 0x0F opcode dispatch table for another based\n * on the mode, because none of the \"GRP6\" 0x0F opcodes (eg, SLDT, STR, LLDT, LTR, VERR and VERW) are allowed in\n * real-mode, and it was easy to swap all those handlers in/out with a single update. We've extended that particular\n * swap to include V86-mode as well, but we might want to consider swapping out more opcode handlers in a similar\n * fashion, instead of using these in-line mode tests.\n */\n if (!(this.regCR0 & X86.CR0.MSW.PE) || I386 && (this.regPS & X86.PS.VM)) {\n X86.opInvalid.call(this);\n return;\n }\n this.decodeModMemWord.call(this, X86.fnARPL);\n};\n\n/**\n * op=0x64 (FS:)\n *\n * @this {CPUX86}\n */\nX86.opFS = function()\n{\n this.opFlags |= X86.OPFLAG.SEG | X86.OPFLAG.NOINTR;\n this.segData = this.segStack = this.segFS;\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n};\n\n/**\n * op=0x65 (GS:)\n *\n * @this {CPUX86}\n */\nX86.opGS = function()\n{\n this.opFlags |= X86.OPFLAG.SEG | X86.OPFLAG.NOINTR;\n this.segData = this.segStack = this.segGS;\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n};\n\n/**\n * op=0x66 (OS:) (80386 and up)\n *\n * TODO: Review other effective operand-size criteria, cycle count, etc.\n *\n * @this {CPUX86}\n */\nX86.opOS = function()\n{\n if (I386) {\n /*\n * See opAS() for a discussion of multiple prefixes, which applies equally to both\n * operand-size and address-size prefixes.\n *\n * The simple fix here is to skip the bulk of the operation if the prefix is redundant.\n */\n this.opFlags |= X86.OPFLAG.DATASIZE;\n if (!(this.opPrefixes & X86.OPFLAG.DATASIZE)) {\n this.sizeData ^= 0x6; // that which is 2 shall become 4, and vice versa\n this.maskData ^= (0xffff0000|0); // that which is 0x0000ffff shall become 0xffffffff, and vice versa\n this.updateDataSize();\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n }\n};\n\n/**\n * op=0x67 (AS:) (80386 and up)\n *\n * TODO: Review other effective address-size criteria, cycle count, etc.\n *\n * @this {CPUX86}\n */\nX86.opAS = function()\n{\n if (I386) {\n /*\n * Live and learn: multiple address-size prefixes can and do occur on a single instruction,\n * and contrary to my original assumption that the prefixes act independently, they do not.\n * During Windows 95 SETUP, the following instruction is executed:\n *\n * 06AF:1B4D 67672E CS:\n * 06AF:1B50 FFA25A1B JMP [BP+SI+1B5A]\n *\n * which is in fact:\n *\n * 06AF:1B4D 67672E CS:\n * 06AF:1B50 FFA25A1B0000 JMP [EDX+00001B5A]\n *\n * The other interesting question is: why/how did this instruction get encoded that way?\n * All I can say is, there were no explicit prefixes in the source (BSG.ASM), so we'll chalk\n * it up to a glitch in MASM.\n *\n * The simple fix here is to skip the bulk of the operation if the prefix is redundant.\n */\n this.opFlags |= X86.OPFLAG.ADDRSIZE;\n if (!(this.opPrefixes & X86.OPFLAG.ADDRSIZE)) {\n this.sizeAddr ^= 0x06; // that which is 2 shall become 4, and vice versa\n this.maskAddr ^= (0xffff0000|0); // that which is 0x0000ffff shall become 0xffffffff, and vice versa\n this.updateAddrSize();\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n }\n};\n\n/**\n * op=0x68 (PUSH imm) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opPUSHn = function()\n{\n this.pushWord(this.getIPWord());\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x69 (IMUL reg,word,imm) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opIMULn = function()\n{\n this.decodeModRegWord.call(this, X86.fnIMULn);\n};\n\n/**\n * op=0x6A (PUSH imm8) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opPUSH8 = function()\n{\n if (BACKTRACK) this.backTrack.btiMem1 = 0;\n this.pushWord(this.getIPDisp());\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x6B (IMUL reg,word,imm8) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opIMUL8 = function()\n{\n this.decodeModRegWord.call(this, X86.fnIMUL8);\n};\n\n/**\n * op=0x6C (INSB) (80186/80188 and up)\n *\n * NOTE: Segment overrides are ignored for this instruction, so we must use segES instead of segData.\n *\n * @this {CPUX86}\n */\nX86.opINSb = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n /*\n * NOTE: 5 + 4n is the cycle time for the 80286; the 80186/80188 has different values: 14 cycles for\n * an unrepeated INS, and 8 + 8n for a repeated INS. However, accurate cycle times for the 80186/80188 is\n * low priority.\n */\n var nCycles = 5;\n\n /*\n * The (normal) REP prefix, if used, is REPNZ (0xf2), but either one works....\n */\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n if (this.opPrefixes & X86.OPFLAG.REPEAT) nCycles = 4;\n }\n\n if (nReps--) {\n var port = this.regEDX & 0xffff;\n if (!this.checkIOPM(port, 1, true)) return;\n var b = this.bus.checkPortInputNotify(port, 1, this.regLIP - nDelta - 1);\n this.setSOByte(this.segES, this.regEDI & maskAddr, b);\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n if (BACKTRACK) this.backTrack.btiMem0 = this.backTrack.btiIO;\n this.regEDI = (this.regEDI & ~maskAddr) | ((this.regEDI + ((this.regPS & X86.PS.DF)? -1 : 1)) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n this.nStepCycles -= nCycles;\n if (nReps) {\n this.resetIP(-2);\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0x6D (INSW) (80186/80188 and up)\n *\n * NOTE: Segment overrides are ignored for this instruction, so we must use segDS instead of segData.\n *\n * @this {CPUX86}\n */\nX86.opINSw = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n /*\n * NOTE: 5 + 4n is the cycle time for the 80286; the 80186/80188 has different values: 14 cycles for\n * an unrepeated INS, and 8 + 8n for a repeated INS. However, accurate cycle times for the 80186/80188 is\n * low priority.\n */\n var nCycles = 5;\n\n /*\n * The (normal) REP prefix, if used, is REPNZ (0xf2), but either one works....\n */\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n if (this.opPrefixes & X86.OPFLAG.REPEAT) nCycles = 4;\n }\n if (nReps--) {\n var port = this.regEDX & 0xffff;\n if (!this.checkIOPM(port, this.sizeData, true)) return;\n var w = this.bus.checkPortInputNotify(port, this.sizeData, this.regLIP - nDelta - 1);\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiIO;\n this.backTrack.btiMem1 = this.backTrack.btiIO;\n }\n this.setSOWord(this.segES, this.regEDI & maskAddr, w);\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n this.regEDI = (this.regEDI & ~maskAddr) | ((this.regEDI + ((this.regPS & X86.PS.DF)? -this.sizeData : this.sizeData)) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n this.nStepCycles -= nCycles;\n if (nReps) {\n this.resetIP(-2);\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0x6E (OUTSB) (80186/80188 and up)\n *\n * NOTE: Segment overrides are ignored for this instruction, so we must use segDS instead of segData.\n *\n * @this {CPUX86}\n */\nX86.opOUTSb = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n /*\n * NOTE: 5 + 4n is the cycle time for the 80286; the 80186/80188 has different values: 14 cycles for\n * an unrepeated INS, and 8 + 8n for a repeated INS. TODO: Fix this someday.\n */\n var nCycles = 5;\n\n /*\n * The (normal) REP prefix, if used, is REPNZ (0xf2), but either one works....\n */\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n if (this.opPrefixes & X86.OPFLAG.REPEAT) nCycles = 4;\n }\n if (nReps--) {\n var port = this.regEDX & 0xffff;\n if (!this.checkIOPM(port, 1, false)) return;\n var b = this.getSOByte(this.segDS, this.regESI & maskAddr);\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n if (BACKTRACK) this.backTrack.btiIO = this.backTrack.btiMem0;\n this.bus.checkPortOutputNotify(port, 1, b, this.regLIP - nDelta - 1);\n this.regESI = (this.regESI & ~maskAddr) | ((this.regESI + ((this.regPS & X86.PS.DF)? -1 : 1)) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n this.nStepCycles -= nCycles;\n if (nReps) {\n this.resetIP(-2);\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0x6F (OUTSW) (80186/80188 and up)\n *\n * NOTE: Segment overrides are ignored for this instruction, so we must use segDS instead of segData.\n *\n * @this {CPUX86}\n */\nX86.opOUTSw = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n /*\n * NOTE: 5 + 4n is the cycle time for the 80286; the 80186/80188 has different values: 14 cycles for\n * an unrepeated INS, and 8 + 8n for a repeated INS. TODO: Fix this someday.\n */\n var nCycles = 5;\n\n /*\n * The (normal) REP prefix, if used, is REPNZ (0xf2), but either one works....\n */\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n if (this.opPrefixes & X86.OPFLAG.REPEAT) nCycles = 4;\n }\n if (nReps--) {\n var w = this.getSOWord(this.segDS, this.regESI & maskAddr);\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n var port = this.regEDX & 0xffff;\n if (!this.checkIOPM(port, this.sizeData, false)) return;\n if (BACKTRACK) {\n this.backTrack.btiIO = this.backTrack.btiMem0;\n this.backTrack.btiIO = this.backTrack.btiMem1;\n }\n this.bus.checkPortOutputNotify(port, this.sizeData, w, this.regLIP - nDelta - 1);\n this.regESI = (this.regESI & ~maskAddr) | ((this.regESI + ((this.regPS & X86.PS.DF)? -this.sizeData : this.sizeData)) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n this.nStepCycles -= nCycles;\n if (nReps) {\n this.resetIP(-2);\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0x70 (JO disp)\n *\n * @this {CPUX86}\n */\nX86.opJO = function()\n{\n var disp = this.getIPDisp();\n if (this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x71 (JNO disp)\n *\n * @this {CPUX86}\n */\nX86.opJNO = function()\n{\n var disp = this.getIPDisp();\n if (!this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x72 (JC disp, aka JB disp)\n *\n * @this {CPUX86}\n */\nX86.opJC = function()\n{\n var disp = this.getIPDisp();\n if (this.getCF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x73 (JNC disp, aka JAE disp)\n *\n * @this {CPUX86}\n */\nX86.opJNC = function()\n{\n var disp = this.getIPDisp();\n if (!this.getCF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x74 (JZ disp)\n *\n * @this {CPUX86}\n */\nX86.opJZ = function()\n{\n var disp = this.getIPDisp();\n if (this.getZF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x75 (JNZ disp)\n *\n * @this {CPUX86}\n */\nX86.opJNZ = function()\n{\n var disp = this.getIPDisp();\n if (!this.getZF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x76 (JBE disp)\n *\n * @this {CPUX86}\n */\nX86.opJBE = function()\n{\n var disp = this.getIPDisp();\n if (this.getCF() || this.getZF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x77 (JNBE disp, JA disp)\n *\n * @this {CPUX86}\n */\nX86.opJNBE = function()\n{\n var disp = this.getIPDisp();\n if (!this.getCF() && !this.getZF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x78 (JS disp)\n *\n * @this {CPUX86}\n */\nX86.opJS = function()\n{\n var disp = this.getIPDisp();\n if (this.getSF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x79 (JNS disp)\n *\n * @this {CPUX86}\n */\nX86.opJNS = function()\n{\n var disp = this.getIPDisp();\n if (!this.getSF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x7A (JP disp)\n *\n * @this {CPUX86}\n */\nX86.opJP = function()\n{\n var disp = this.getIPDisp();\n if (this.getPF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x7B (JNP disp)\n *\n * @this {CPUX86}\n */\nX86.opJNP = function()\n{\n var disp = this.getIPDisp();\n if (!this.getPF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x7C (JL disp)\n *\n * @this {CPUX86}\n */\nX86.opJL = function()\n{\n var disp = this.getIPDisp();\n if (!this.getSF() != !this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x7D (JNL disp, aka JGE disp)\n *\n * @this {CPUX86}\n */\nX86.opJNL = function()\n{\n var disp = this.getIPDisp();\n if (!this.getSF() == !this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x7E (JLE disp)\n *\n * @this {CPUX86}\n */\nX86.opJLE = function()\n{\n var disp = this.getIPDisp();\n if (this.getZF() || !this.getSF() != !this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x7F (JNLE disp, aka JG disp)\n *\n * @this {CPUX86}\n */\nX86.opJNLE = function()\n{\n var disp = this.getIPDisp();\n if (!this.getZF() && !this.getSF() == !this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * op=0x80/0x82 (GRP1 byte,imm8)\n *\n * @this {CPUX86}\n */\nX86.opGRP1b = function()\n{\n this.decodeModGrpByte.call(this, X86.aOpGrp1b, this.getIPByte);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? 1 : this.cycleCounts.nOpCyclesArithMID);\n};\n\n/**\n * op=0x81 (GRP1 word,imm)\n *\n * @this {CPUX86}\n */\nX86.opGRP1w = function()\n{\n this.decodeModGrpWord.call(this, X86.aOpGrp1w, this.getIPWord);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? 1 : this.cycleCounts.nOpCyclesArithMID);\n};\n\n/**\n * op=0x83 (GRP1 word,disp)\n *\n * WARNING: This passes getIPDisp() as the fnSrc parameter, which returns a 32-bit signed value,\n * so the worker functions (ie, the functions listed in aOpGrp1w[]) MUST mask their result with maskData,\n * to avoid setting bits beyond the current operand size.\n *\n * @this {CPUX86}\n */\nX86.opGRP1sw = function()\n{\n this.decodeModGrpWord.call(this, X86.aOpGrp1w, this.getIPDisp);\n this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? 1 : this.cycleCounts.nOpCyclesArithMID);\n};\n\n/**\n * op=0x84 (TEST reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opTESTrb = function()\n{\n this.decodeModMemByte.call(this, X86.fnTESTb);\n};\n\n/**\n * op=0x85 (TEST reg,word)\n *\n * @this {CPUX86}\n */\nX86.opTESTrw = function()\n{\n this.decodeModMemWord.call(this, X86.fnTESTw);\n};\n\n/**\n * op=0x86 (XCHG reg,byte)\n *\n * NOTE: The XCHG instruction is unique in that both src and dst are both read and written;\n * see fnXCHGrb() for how we deal with this special case.\n *\n * @this {CPUX86}\n */\nX86.opXCHGrb = function()\n{\n /*\n * If the second operand is a register, then the ModRegByte decoder must use separate \"get\" and\n * \"set\" assignments, otherwise instructions like \"XCHG DH,DL\" will end up using a stale DL instead of\n * the updated DL.\n *\n * To be clear, a single assignment like this will fail:\n *\n * opModRegByteF2: function(fn)\n * {\n * this.regEDX = (this.regEDX & 0xff) | (fn.call(this, this.regEDX >> 8, this.regEDX & 0xff) << 8);\n * }\n *\n * which is why all affected decoders now use separate assignments; eg:\n *\n * opModRegByteF2: function(fn)\n * {\n * var b = fn.call(this, this.regEDX >> 8, this.regEDX & 0xff);\n * this.regEDX = (this.regEDX & 0xff) | (b << 8);\n * }\n */\n this.decodeModRegByte.call(this, X86.fnXCHGrb);\n};\n\n/**\n * op=0x87 (XCHG reg,word)\n *\n * NOTE: The XCHG instruction is unique in that both src and dst are both read and written;\n * see fnXCHGrw() for how we deal with this special case.\n *\n * @this {CPUX86}\n */\nX86.opXCHGrw = function()\n{\n this.decodeModRegWord.call(this, X86.fnXCHGrw);\n};\n\n/**\n * op=0x88 (MOV byte,reg)\n *\n * @this {CPUX86}\n */\nX86.opMOVmb = function()\n{\n /*\n * Like other MOV operations, the destination does not need to be read, just written.\n */\n this.opFlags |= X86.OPFLAG.NOREAD;\n this.decodeModMemByte.call(this, X86.fnMOV);\n};\n\n/**\n * op=0x89 (MOV word,reg)\n *\n * @this {CPUX86}\n */\nX86.opMOVmw = function()\n{\n /*\n * Like other MOV operations, the destination does not need to be read, just written.\n */\n this.opFlags |= X86.OPFLAG.NOREAD;\n this.decodeModMemWord.call(this, X86.fnMOV);\n};\n\n/**\n * op=0x8A (MOV reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opMOVrb = function()\n{\n this.decodeModRegByte.call(this, X86.fnMOV);\n};\n\n/**\n * op=0x8B (MOV reg,word)\n *\n * @this {CPUX86}\n */\nX86.opMOVrw = function()\n{\n this.decodeModRegWord.call(this, X86.fnMOV);\n};\n\n/**\n * op=0x8C (MOV word,sreg)\n *\n * NOTE: Since the ModRM decoders deal only with general-purpose registers, we rely on our helper\n * function (fnMOVwsr) to select the appropriate segment register and replace the decoder's src operand.\n *\n * @this {CPUX86}\n */\nX86.opMOVwsr = function()\n{\n /*\n * Like other MOV operations, the destination does not need to be read, just written.\n */\n this.opFlags |= X86.OPFLAG.NOREAD;\n this.decodeModMemWord.call(this, X86.fnMOVwsr);\n};\n\n/**\n * op=0x8D (LEA reg,word)\n *\n * @this {CPUX86}\n */\nX86.opLEA = function()\n{\n this.opFlags |= X86.OPFLAG.NOREAD;\n this.segData = this.segStack = this.segNULL; // we can't have the EA calculation, if any, \"polluted\" by segment arithmetic\n this.decodeModRegWord.call(this, X86.fnLEA);\n};\n\n/**\n * op=0x8E (MOV sreg,word)\n *\n * NOTE: Since the ModRM decoders deal only with general-purpose registers, we rely on our\n * helper function (fnMOVsrw) to make a note of which general-purpose register will be overwritten,\n * so that we can restore it after moving the updated value to the correct segment register.\n *\n * @this {CPUX86}\n */\nX86.opMOVsrw = function()\n{\n var sel;\n this.decodeModRegWord.call(this, X86.fnMOVsrw);\n switch ((this.bModRM >> 3) & 0x7) {\n case 0x0:\n sel = this.regEAX;\n this.regEAX = this.regXX;\n this.setES(sel);\n break;\n case 0x1:\n sel = this.regECX;\n this.regECX = this.regXX;\n this.setCS(sel);\n break;\n case 0x2:\n sel = this.regEDX;\n this.regEDX = this.regXX;\n this.setSS(sel);\n break;\n case 0x3:\n sel = this.regEBX;\n this.regEBX = this.regXX;\n this.setDS(sel);\n break;\n case 0x4:\n sel = this.getSP();\n this.setSP(this.regXX);\n if (I386 && this.model >= X86.MODEL_80386) {\n this.setFS(sel);\n } else {\n this.setES(sel);\n }\n break;\n case 0x5:\n sel = this.regEBP;\n this.regEBP = this.regXX;\n if (I386 && this.model >= X86.MODEL_80386) {\n this.setGS(sel);\n } else {\n this.setCS(sel);\n }\n break;\n case 0x6:\n sel = this.regESI;\n this.regESI = this.regXX;\n this.setSS(sel);\n break;\n case 0x7:\n sel = this.regEDI;\n this.regEDI = this.regXX;\n this.setDS(sel);\n break;\n }\n};\n\n/**\n * op=0x8F (POP word)\n *\n * @this {CPUX86}\n */\nX86.opPOPmw = function()\n{\n /*\n * Like other MOV operations, the destination does not need to be read, just written.\n */\n this.opFlags |= X86.OPFLAG.NOREAD;\n\n /*\n * If the word we're about to pop FROM the stack gets popped INTO a not-present page, this\n * instruction will not be restartable unless we snapshot regLSP first.\n */\n this.opLSP = this.regLSP;\n\n /*\n * A \"clever\" instruction like this:\n *\n * #0117:651C 67668F442408 POP DWORD [ESP+08]\n *\n * pops the DWORD from the top of the stack and places it at ESP+08, where ESP is the value\n * AFTER the pop, not before. We used to (incorrectly) pass \"popWord\" as the fnSrc parameter\n * below; we now pop the word first, saving it in regXX, and then pass \"helpSRCxx\" as fnSrc,\n * which simply returns the contents of regXX.\n *\n * Also, in case you're wondering, fnPUSHw() (in aOpGrp4w) is the complement to this instruction,\n * but it doesn't require a similar work-around, because a push from memory accesses that memory\n * BEFORE the push, which occurs through our normal ModRM processing.\n */\n this.regXX = this.popWord();\n\n this.decodeModGrpWord.call(this, X86.aOpGrpPOPw, X86.helpSRCxx);\n\n this.opLSP = X86.ADDR_INVALID;\n};\n\n/**\n * op=0x90 (NOP, aka XCHG AX,AX)\n *\n * @this {CPUX86}\n */\nX86.opNOP = function()\n{\n this.nStepCycles -= 3; // this form of XCHG takes 3 cycles on all CPUs\n};\n\n/**\n * op=0x91 (XCHG AX,CX)\n *\n * @this {CPUX86}\n */\nX86.opXCHGCX = function()\n{\n var temp = this.regEAX;\n this.regEAX = (I386? (this.regEAX & ~this.maskData) | (this.regECX & this.maskData) : this.regECX);\n this.regECX = (I386? (this.regECX & ~this.maskData) | (temp & this.maskData) : temp);\n if (BACKTRACK) {\n temp = this.backTrack.btiAL; this.backTrack.btiAL = this.backTrack.btiCL; this.backTrack.btiCL = temp;\n temp = this.backTrack.btiAH; this.backTrack.btiAH = this.backTrack.btiCH; this.backTrack.btiCH = temp;\n }\n this.nStepCycles -= 3; // this form of XCHG takes 3 cycles on all CPUs\n};\n\n/**\n * op=0x92 (XCHG AX,DX)\n *\n * @this {CPUX86}\n */\nX86.opXCHGDX = function()\n{\n var temp = this.regEAX;\n this.regEAX = (I386? (this.regEAX & ~this.maskData) | (this.regEDX & this.maskData) : this.regEDX);\n this.regEDX = (I386? (this.regEDX & ~this.maskData) | (temp & this.maskData) : temp);\n if (BACKTRACK) {\n temp = this.backTrack.btiAL; this.backTrack.btiAL = this.backTrack.btiDL; this.backTrack.btiDL = temp;\n temp = this.backTrack.btiAH; this.backTrack.btiAH = this.backTrack.btiDH; this.backTrack.btiDH = temp;\n }\n this.nStepCycles -= 3; // this form of XCHG takes 3 cycles on all CPUs\n};\n\n/**\n * op=0x93 (XCHG AX,BX)\n *\n * @this {CPUX86}\n */\nX86.opXCHGBX = function()\n{\n var temp = this.regEAX;\n this.regEAX = (I386? (this.regEAX & ~this.maskData) | (this.regEBX & this.maskData) : this.regEBX);\n this.regEBX = (I386? (this.regEBX & ~this.maskData) | (temp & this.maskData) : temp);\n if (BACKTRACK) {\n temp = this.backTrack.btiAL; this.backTrack.btiAL = this.backTrack.btiBL; this.backTrack.btiBL = temp;\n temp = this.backTrack.btiAH; this.backTrack.btiAH = this.backTrack.btiBH; this.backTrack.btiBH = temp;\n }\n this.nStepCycles -= 3; // this form of XCHG takes 3 cycles on all CPUs\n};\n\n/**\n * op=0x94 (XCHG AX,SP)\n *\n * @this {CPUX86}\n */\nX86.opXCHGSP = function()\n{\n var temp = this.regEAX;\n var regESP = this.getSP();\n this.regEAX = (I386? (this.regEAX & ~this.maskData) | (regESP & this.maskData) : regESP);\n this.setSP((I386? (regESP & ~this.maskData) | (temp & this.maskData) : temp));\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiAH = 0;\n this.nStepCycles -= 3; // this form of XCHG takes 3 cycles on all CPUs\n};\n\n/**\n * op=0x95 (XCHG AX,BP)\n *\n * @this {CPUX86}\n */\nX86.opXCHGBP = function()\n{\n var temp = this.regEAX;\n this.regEAX = (I386? (this.regEAX & ~this.maskData) | (this.regEBP & this.maskData) : this.regEBP);\n this.regEBP = (I386? (this.regEBP & ~this.maskData) | (temp & this.maskData) : temp);\n if (BACKTRACK) {\n temp = this.backTrack.btiAL; this.backTrack.btiAL = this.backTrack.btiBPLo; this.backTrack.btiBPLo = temp;\n temp = this.backTrack.btiAH; this.backTrack.btiAH = this.backTrack.btiBPHi; this.backTrack.btiBPHi = temp;\n }\n this.nStepCycles -= 3; // this form of XCHG takes 3 cycles on all CPUs\n};\n\n/**\n * op=0x96 (XCHG AX,SI)\n *\n * @this {CPUX86}\n */\nX86.opXCHGSI = function()\n{\n var temp = this.regEAX;\n this.regEAX = (I386? (this.regEAX & ~this.maskData) | (this.regESI & this.maskData) : this.regESI);\n this.regESI = (I386? (this.regESI & ~this.maskData) | (temp & this.maskData) : temp);\n if (BACKTRACK) {\n temp = this.backTrack.btiAL; this.backTrack.btiAL = this.backTrack.btiSILo; this.backTrack.btiSILo = temp;\n temp = this.backTrack.btiAH; this.backTrack.btiAH = this.backTrack.btiSIHi; this.backTrack.btiSIHi = temp;\n }\n this.nStepCycles -= 3; // this form of XCHG takes 3 cycles on all CPUs\n};\n\n/**\n * op=0x97 (XCHG AX,DI)\n *\n * @this {CPUX86}\n */\nX86.opXCHGDI = function()\n{\n var temp = this.regEAX;\n this.regEAX = (I386? (this.regEAX & ~this.maskData) | (this.regEDI & this.maskData) : this.regEDI);\n this.regEDI = (I386? (this.regEDI & ~this.maskData) | (temp & this.maskData) : temp);\n if (BACKTRACK) {\n temp = this.backTrack.btiAL; this.backTrack.btiAL = this.backTrack.btiDILo; this.backTrack.btiDILo = temp;\n temp = this.backTrack.btiAH; this.backTrack.btiAH = this.backTrack.btiDIHi; this.backTrack.btiDIHi = temp;\n }\n this.nStepCycles -= 3; // this form of XCHG takes 3 cycles on all CPUs\n};\n\n/**\n * op=0x98 (CBW/CWDE)\n *\n * NOTE: The 16-bit form (CBW) sign-extends AL into AX, whereas the 32-bit form (CWDE) sign-extends AX into EAX;\n * CWDE is similar to CWD, except that the destination is EAX rather than DX:AX.\n *\n * @this {CPUX86}\n */\nX86.opCBW = function()\n{\n if (this.sizeData == 2) { // CBW\n this.regEAX = (this.regEAX & ~0xffff) | (((this.regEAX << 24) >> 24) & 0xffff);\n if (BACKTRACK) this.backTrack.btiAH = this.backTrack.btiAL;\n }\n else { // CWDE\n this.regEAX = ((this.regEAX << 16) >> 16);\n }\n this.nStepCycles -= 2; // CBW takes 2 cycles on all CPUs through 80286\n};\n\n/**\n * op=0x99 (CWD/CDQ)\n *\n * NOTE: The 16-bit form (CWD) sign-extends AX, producing a 32-bit result in DX:AX, while the 32-bit form (CDQ)\n * sign-extends EAX, producing a 64-bit result in EDX:EAX.\n *\n * @this {CPUX86}\n */\nX86.opCWD = function()\n{\n if (this.sizeData == 2) { // CWD\n this.regEDX = (this.regEDX & ~0xffff) | ((this.regEAX & 0x8000)? 0xffff : 0);\n if (BACKTRACK) this.backTrack.btiDL = this.backTrack.btiDH = this.backTrack.btiAH;\n }\n else { // CDQ\n this.regEDX = (this.regEAX & (0x80000000|0))? -1 : 0;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesCWD;\n};\n\n/**\n * op=0x9A (CALL seg:off)\n *\n * @this {CPUX86}\n */\nX86.opCALLF = function()\n{\n X86.helpCALLF.call(this, this.getIPWord(), this.getIPShort());\n this.nStepCycles -= this.cycleCounts.nOpCyclesCallF;\n};\n\n/**\n * op=0x9B (WAIT)\n *\n * @this {CPUX86}\n */\nX86.opWAIT = function()\n{\n if (!this.fpu || !this.fpu.opWAIT()) {\n this.nStepCycles -= 3; // FPUX86.opWAIT() is required to charge some number of cycles if it returns true\n }\n};\n\n/**\n * op=0x9C (PUSHF/PUSHFD)\n *\n * @this {CPUX86}\n */\nX86.opPUSHF = function()\n{\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to V86-mode.\n */\n var regPS = this.getPS();\n if (I386) {\n if ((regPS & X86.PS.VM) && this.nIOPL < 3) {\n if (DEBUG) this.printMessage(\"PUSHF in v86-mode (IOPL < 3)\", this.bitsMessage, true);\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n /*\n * It doesn't matter whether this is PUSHF or PUSHFD: the VM and RF flags are never pushed, so\n * we should always clear them. NOTE: This contradicts what the \"INTEL 80386 PROGRAMMER'S REFERENCE\n * MANUAL 1986\" says on page 81 (which we assume is wrong):\n *\n * SYSTEMS FLAGS (INCLUDING THE IOPL FIELD, AND THE VM, RF, AND IF FLAGS) ARE PUSHED AND ARE\n * VISIBLE TO APPLICATIONS PROGRAMS. HOWEVER, WHEN AN APPLICATIONS PROGRAM POPS THE FLAGS,\n * THESE ITEMS ARE NOT CHANGED, REGARDLESS OF THE VALUES POPPED INTO THEM.\n *\n * This does, however, beg the question: how does code running in V86-mode detect that's in V86-mode\n * and not real-mode? By using the SMSW instruction and checking the PE (protected-mode enabled) bit.\n * The SMSW instruction returns a subset of the CR0 bits, and unlike the MOV reg,CR0 instruction, is\n * allowed in V86-mode. See fnSMSW() for more information.\n */\n regPS &= ~(X86.PS.VM | X86.PS.RF);\n }\n this.pushWord(regPS);\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushReg;\n};\n\n/**\n * op=0x9D (POPF/POPFD)\n *\n * @this {CPUX86}\n */\nX86.opPOPF = function()\n{\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to V86-mode.\n */\n if (I386 && (this.regPS & X86.PS.VM) && this.nIOPL < 3) {\n if (DEBUG) this.printMessage(\"POPF in v86-mode (IOPL < 3)\", this.bitsMessage, true);\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n /*\n * Regardless of mode, VM and RF (the only defined EFLAGS bit above bit 15) are never changed by POPFD.\n */\n var newPS = this.popWord();\n if (I386) newPS = (newPS & 0xffff) | (this.regPS & ~0xffff);\n this.setPS(newPS);\n /*\n * NOTE: I'm assuming that neither POPF nor IRET are required to set NOINTR like STI does.\n */\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n};\n\n/**\n * op=0x9E (SAHF)\n *\n * @this {CPUX86}\n */\nX86.opSAHF = function()\n{\n /*\n * NOTE: While it make seem more efficient to do this:\n *\n * this.setPS((this.getPS() & ~X86.PS_SAHF) | ((this.regEAX >> 8) & X86.PS_SAHF));\n *\n * getPS() forces any \"cached\" flags to be resolved first, and setPS() must do extra work above\n * and beyond setting the arithmetic and logical flags, so on balance, the code below may be more\n * efficient, and may also avoid unexpected side-effects of updating the entire PS register.\n */\n var ah = (this.regEAX >> 8) & 0xff;\n if (ah & X86.PS.CF) this.setCF(); else this.clearCF();\n if (ah & X86.PS.PF) this.setPF(); else this.clearPF();\n if (ah & X86.PS.AF) this.setAF(); else this.clearAF();\n if (ah & X86.PS.ZF) this.setZF(); else this.clearZF();\n if (ah & X86.PS.SF) this.setSF(); else this.clearSF();\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n\n};\n\n/**\n * op=0x9F (LAHF)\n *\n * @this {CPUX86}\n */\nX86.opLAHF = function()\n{\n this.regEAX = (this.regEAX & ~0xff00) | (this.getPS() & X86.PS_SAHF) << 8;\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xA0 (MOV AL,mem)\n *\n * @this {CPUX86}\n */\nX86.opMOVALm = function()\n{\n this.regEAX = (this.regEAX & ~0xff) | this.getSOByte(this.segData, this.getIPAddr());\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiMem0;\n this.nStepCycles -= this.cycleCounts.nOpCyclesMovAM;\n};\n\n/**\n * op=0xA1 (MOV [E]AX,mem)\n *\n * @this {CPUX86}\n */\nX86.opMOVAXm = function()\n{\n this.regEAX = (this.regEAX & ~this.maskData) | this.getSOWord(this.segData, this.getIPAddr());\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesMovAM;\n};\n\n/**\n * op=0xA2 (MOV mem,AL)\n *\n * @this {CPUX86}\n */\nX86.opMOVmAL = function()\n{\n if (BACKTRACK) this.backTrack.btiMem0 = this.backTrack.btiAL;\n /*\n * setSOByte() truncates the value as appropriate\n */\n this.setSOByte(this.segData, this.getIPAddr(), this.regEAX);\n this.nStepCycles -= this.cycleCounts.nOpCyclesMovMA;\n};\n\n/**\n * op=0xA3 (MOV mem,AX)\n *\n * @this {CPUX86}\n */\nX86.opMOVmAX = function()\n{\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiAL; this.backTrack.btiMem1 = this.backTrack.btiAH;\n }\n /*\n * setSOWord() truncates the value as appropriate\n */\n this.setSOWord(this.segData, this.getIPAddr(), this.regEAX);\n this.nStepCycles -= this.cycleCounts.nOpCyclesMovMA;\n};\n\n/**\n * op=0xA4 (MOVSB)\n *\n * @this {CPUX86}\n */\nX86.opMOVSb = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n var nCycles = this.cycleCounts.nOpCyclesMovS;\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n nCycles = this.cycleCounts.nOpCyclesMovSrn;\n if (!(this.opPrefixes & X86.OPFLAG.REPEAT)) this.nStepCycles -= this.cycleCounts.nOpCyclesMovSr0;\n }\n if (nReps--) {\n this.setSOByte(this.segES, this.regEDI & maskAddr, this.getSOByte(this.segData, this.regESI & maskAddr));\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n var nInc = ((this.regPS & X86.PS.DF)? -1 : 1);\n this.regESI = (this.regESI & ~maskAddr) | ((this.regESI + nInc) & maskAddr);\n this.regEDI = (this.regEDI & ~maskAddr) | ((this.regEDI + nInc) & maskAddr);\n this.nStepCycles -= nCycles;\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n if (nReps) {\n this.resetIP(((this.opPrefixes & X86.OPFLAG.SEG)? -3 : -2));\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0xA5 (MOVSW)\n *\n * @this {CPUX86}\n */\nX86.opMOVSw = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n var nCycles = this.cycleCounts.nOpCyclesMovS;\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n nCycles = this.cycleCounts.nOpCyclesMovSrn;\n if (!(this.opPrefixes & X86.OPFLAG.REPEAT)) this.nStepCycles -= this.cycleCounts.nOpCyclesMovSr0;\n }\n if (nReps--) {\n this.setSOWord(this.segES, this.regEDI & maskAddr, this.getSOWord(this.segData, this.regESI & maskAddr));\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n var nInc = ((this.regPS & X86.PS.DF)? -this.sizeData : this.sizeData);\n this.regESI = (this.regESI & ~maskAddr) | ((this.regESI + nInc) & maskAddr);\n this.regEDI = (this.regEDI & ~maskAddr) | ((this.regEDI + nInc) & maskAddr);\n this.nStepCycles -= nCycles;\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n if (nReps) {\n this.resetIP(((this.opPrefixes & X86.OPFLAG.SEG)? -3 : -2));\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0xA6 (CMPSB)\n *\n * @this {CPUX86}\n */\nX86.opCMPSb = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n var nCycles = this.cycleCounts.nOpCyclesCmpS;\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n nCycles = this.cycleCounts.nOpCyclesCmpSrn;\n if (!(this.opPrefixes & X86.OPFLAG.REPEAT)) this.nStepCycles -= this.cycleCounts.nOpCyclesCmpSr0;\n }\n if (nReps--) {\n var bDst = this.getEAByte(this.segData, this.regESI);\n var bSrc = this.getEAByte(this.segES, this.regEDI);\n this.regEAWrite = this.regEA; // TODO: Is this necessary?\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n X86.fnCMPb.call(this, bDst, bSrc);\n var nInc = ((this.regPS & X86.PS.DF)? -1 : 1);\n this.regESI = (this.regESI & ~maskAddr) | ((this.regESI + nInc) & maskAddr);\n this.regEDI = (this.regEDI & ~maskAddr) | ((this.regEDI + nInc) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n /*\n * NOTE: As long as we're calling fnCMPb(), all our cycle times must be reduced by nOpCyclesArithRM\n */\n this.nStepCycles -= nCycles - this.cycleCounts.nOpCyclesArithRM;\n /*\n * Repetition continues while ZF matches bit 0 of the REP prefix. getZF() returns 0x40 if ZF is\n * set, and OP_REPZ (which represents the REP prefix whose bit 0 is set) is 0x40 as well, so when those\n * two values are equal, we must continue.\n */\n if (nReps && this.getZF() == (this.opPrefixes & X86.OPFLAG.REPZ)) {\n this.resetIP(((this.opPrefixes & X86.OPFLAG.SEG)? -3 : -2));\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0xA7 (CMPSW)\n *\n * @this {CPUX86}\n */\nX86.opCMPSw = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n var nCycles = this.cycleCounts.nOpCyclesCmpS;\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n nCycles = this.cycleCounts.nOpCyclesCmpSrn;\n if (!(this.opPrefixes & X86.OPFLAG.REPEAT)) this.nStepCycles -= this.cycleCounts.nOpCyclesCmpSr0;\n }\n if (nReps--) {\n var wDst = this.getEAWord(this.segData, this.regESI & maskAddr);\n var wSrc = this.getEAWord(this.segES, this.regEDI & maskAddr);\n this.regEAWrite = this.regEA; // TODO: Is this necessary?\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n X86.fnCMPw.call(this, wDst, wSrc);\n var nInc = ((this.regPS & X86.PS.DF)? -this.sizeData : this.sizeData);\n this.regESI = (this.regESI & ~maskAddr) | ((this.regESI + nInc) & maskAddr);\n this.regEDI = (this.regEDI & ~maskAddr) | ((this.regEDI + nInc) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n /*\n * NOTE: As long as we're calling fnCMPw(), all our cycle times must be reduced by nOpCyclesArithRM\n */\n this.nStepCycles -= nCycles - this.cycleCounts.nOpCyclesArithRM;\n /*\n * Repetition continues while ZF matches bit 0 of the REP prefix. getZF() returns 0x40 if ZF is\n * set, and OP_REPZ (which represents the REP prefix whose bit 0 is set) is 0x40 as well, so when those\n * two values are equal, we must continue.\n */\n if (nReps && this.getZF() == (this.opPrefixes & X86.OPFLAG.REPZ)) {\n this.resetIP(((this.opPrefixes & X86.OPFLAG.SEG)? -3 : -2));\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0xA8 (TEST AL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opTESTALb = function()\n{\n this.setLogicResult(this.regEAX & this.getIPByte(), X86.RESULT.BYTE);\n this.nStepCycles -= this.cycleCounts.nOpCyclesAAA;\n};\n\n/**\n * op=0xA9 (TEST [E]AX,imm)\n *\n * @this {CPUX86}\n */\nX86.opTESTAX = function()\n{\n this.setLogicResult(this.regEAX & this.getIPWord(), this.typeData);\n this.nStepCycles -= this.cycleCounts.nOpCyclesAAA;\n};\n\n/**\n * op=0xAA (STOSB)\n *\n * NOTES: Segment overrides are ignored for this instruction, so we must use segES instead of segData.\n *\n * @this {CPUX86}\n */\nX86.opSTOSb = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n var nCycles = this.cycleCounts.nOpCyclesStoS;\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n nCycles = this.cycleCounts.nOpCyclesStoSrn;\n if (!(this.opPrefixes & X86.OPFLAG.REPEAT)) this.nStepCycles -= this.cycleCounts.nOpCyclesStoSr0;\n }\n if (nReps--) {\n this.setSOByte(this.segES, this.regEDI & maskAddr, this.regEAX);\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n if (BACKTRACK) this.backTrack.btiMem0 = this.backTrack.btiAL;\n\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n \n /*\n * Implement 80386 B1 Errata #7, to the extent that Windows 95 checked for it. This test doesn't\n * detect every possible variation (for example, the ADDRESS override on the next instruction, if\n * it exists, may not be the first prefix byte), but it's adequate for our limited purpose.\n *\n * Note that this code alters maskAddr AFTER it's been used to update ECX, because in the case\n * of STOS, the errata reportedly affects only EDI. The other instructions mentioned in the errata\n * trash different registers, so read the errata carefully.\n *\n * TODO: Extend this errata to STOSW, as well as MOVSB, MOVSW, INSB, and INSW. Also, verify the\n * extent to which this errata existed on earlier 80386 steppings (I'm currently assuming A0-B1).\n */\n if (this.stepping >= X86.STEPPING_80386_A0 && this.stepping <= X86.STEPPING_80386_B2) {\n if (!(this.opPrefixes & X86.OPFLAG.ADDRSIZE) != (this.getByte(this.regLIP) != X86.OPCODE.AS)) {\n maskAddr ^= (0xffff0000|0);\n }\n }\n this.regEDI = (this.regEDI & ~maskAddr) | ((this.regEDI + ((this.regPS & X86.PS.DF)? -1 : 1)) & maskAddr);\n\n this.nStepCycles -= nCycles;\n if (nReps) {\n this.resetIP(-2);\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0xAB (STOSW)\n *\n * NOTES: Segment overrides are ignored for this instruction, so we must use segES instead of segData.\n *\n * @this {CPUX86}\n */\nX86.opSTOSw = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n var nCycles = this.cycleCounts.nOpCyclesStoS;\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n nCycles = this.cycleCounts.nOpCyclesStoSrn;\n if (!(this.opPrefixes & X86.OPFLAG.REPEAT)) this.nStepCycles -= this.cycleCounts.nOpCyclesStoSr0;\n }\n if (nReps--) {\n this.setSOWord(this.segES, this.regEDI & maskAddr, this.regEAX);\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n if (BACKTRACK) {\n this.backTrack.btiMem0 = this.backTrack.btiAL; this.backTrack.btiMem1 = this.backTrack.btiAH;\n }\n this.regEDI = (this.regEDI & ~maskAddr) | ((this.regEDI + ((this.regPS & X86.PS.DF)? -this.sizeData : this.sizeData)) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n this.nStepCycles -= nCycles;\n if (nReps) {\n this.resetIP(-2);\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0xAC (LODSB)\n *\n * @this {CPUX86}\n */\nX86.opLODSb = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n var nCycles = this.cycleCounts.nOpCyclesLodS;\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n nCycles = this.cycleCounts.nOpCyclesLodSrn;\n if (!(this.opPrefixes & X86.OPFLAG.REPEAT)) this.nStepCycles -= this.cycleCounts.nOpCyclesLodSr0;\n }\n if (nReps--) {\n var b = this.getSOByte(this.segData, this.regESI & maskAddr);\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n this.regEAX = (this.regEAX & ~0xff) | b;\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiMem0;\n this.regESI = (this.regESI & ~maskAddr) | ((this.regESI + ((this.regPS & X86.PS.DF)? -1 : 1)) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n this.nStepCycles -= nCycles;\n if (nReps) {\n this.resetIP(((this.opPrefixes & X86.OPFLAG.SEG)? -3 : -2));\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0xAD (LODSW)\n *\n * @this {CPUX86}\n */\nX86.opLODSw = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n var nCycles = this.cycleCounts.nOpCyclesLodS;\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n nCycles = this.cycleCounts.nOpCyclesLodSrn;\n if (!(this.opPrefixes & X86.OPFLAG.REPEAT)) this.nStepCycles -= this.cycleCounts.nOpCyclesLodSr0;\n }\n if (nReps--) {\n var w = this.getSOWord(this.segData, this.regESI & maskAddr);\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n this.regEAX = (this.regEAX & ~this.maskData) | w;\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.regESI = (this.regESI & ~maskAddr) | ((this.regESI + ((this.regPS & X86.PS.DF)? -this.sizeData : this.sizeData)) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n this.nStepCycles -= nCycles;\n if (nReps) {\n this.resetIP(((this.opPrefixes & X86.OPFLAG.SEG)? -3 : -2));\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0xAE (SCASB)\n *\n * @this {CPUX86}\n */\nX86.opSCASb = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n var nCycles = this.cycleCounts.nOpCyclesScaS;\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n nCycles = this.cycleCounts.nOpCyclesScaSrn;\n if (!(this.opPrefixes & X86.OPFLAG.REPEAT)) this.nStepCycles -= this.cycleCounts.nOpCyclesScaSr0;\n }\n if (nReps--) {\n var bDst = this.regEAX & 0xff;\n var bSrc = this.getEAByte(this.segES, this.regEDI);\n this.regEAWrite = this.regEA; // TODO: Is this necessary?\n X86.fnCMPb.call(this, bDst, bSrc);\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n this.regEDI = (this.regEDI & ~maskAddr) | ((this.regEDI + ((this.regPS & X86.PS.DF)? -1 : 1)) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n /*\n * NOTE: As long as we're calling fnCMPb(), all our cycle times must be reduced by nOpCyclesArithRM\n */\n this.nStepCycles -= nCycles - this.cycleCounts.nOpCyclesArithRM;\n /*\n * Repetition continues while ZF matches bit 0 of the REP prefix. getZF() returns 0x40 if ZF is\n * set, and OP_REPZ (which represents the REP prefix whose bit 0 is set) is 0x40 as well, so when those\n * two values are equal, we must continue.\n */\n if (nReps && this.getZF() == (this.opPrefixes & X86.OPFLAG.REPZ)) {\n this.resetIP(-2);\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0xAF (SCASW)\n *\n * @this {CPUX86}\n */\nX86.opSCASw = function()\n{\n var nReps = 1;\n var nDelta = 0;\n var maskAddr = this.maskAddr;\n\n var nCycles = this.cycleCounts.nOpCyclesScaS;\n if (this.opPrefixes & (X86.OPFLAG.REPZ | X86.OPFLAG.REPNZ)) {\n nReps = this.regECX & maskAddr;\n nDelta = 1;\n nCycles = this.cycleCounts.nOpCyclesScaSrn;\n if (!(this.opPrefixes & X86.OPFLAG.REPEAT)) this.nStepCycles -= this.cycleCounts.nOpCyclesScaSr0;\n }\n if (nReps--) {\n var wDst = this.regEAX & this.maskData;\n var wSrc = this.getEAWord(this.segES, this.regEDI & maskAddr);\n this.regEAWrite = this.regEA; // TODO: Is this necessary?\n X86.fnCMPw.call(this, wDst, wSrc);\n /*\n * helpFault() throws exceptions now, so inline checks of X86.OPFLAG.FAULT should no longer be necessary.\n *\n * if (this.opFlags & X86.OPFLAG.FAULT) return;\n */\n this.regEDI = (this.regEDI & ~maskAddr) | ((this.regEDI + ((this.regPS & X86.PS.DF)? -this.sizeData : this.sizeData)) & maskAddr);\n this.regECX = (this.regECX & ~maskAddr) | ((this.regECX - nDelta) & maskAddr);\n /*\n * NOTE: As long as we're calling fnCMPw(), all our cycle times must be reduced by nOpCyclesArithRM\n */\n this.nStepCycles -= nCycles - this.cycleCounts.nOpCyclesArithRM;\n /*\n * Repetition continues while ZF matches bit 0 of the REP prefix. getZF() returns 0x40 if ZF is\n * set, and OP_REPZ (which represents the REP prefix whose bit 0 is set) is 0x40 as well, so when those\n * two values are equal, we must continue.\n */\n if (nReps && this.getZF() == (this.opPrefixes & X86.OPFLAG.REPZ)) {\n this.resetIP(-2);\n this.opFlags |= X86.OPFLAG.REPEAT;\n }\n }\n};\n\n/**\n * op=0xB0 (MOV AL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opMOVALb = function()\n{\n this.regEAX = (this.regEAX & ~0xff) | this.getIPByte();\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiMem0;\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xB1 (MOV CL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opMOVCLb = function()\n{\n this.regECX = (this.regECX & ~0xff) | this.getIPByte();\n if (BACKTRACK) this.backTrack.btiCL = this.backTrack.btiMem0;\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xB2 (MOV DL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opMOVDLb = function()\n{\n this.regEDX = (this.regEDX & ~0xff) | this.getIPByte();\n if (BACKTRACK) this.backTrack.btiDL = this.backTrack.btiMem0;\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xB3 (MOV BL,imm8)\n *\n * @this {CPUX86}\n */\nX86.opMOVBLb = function()\n{\n this.regEBX = (this.regEBX & ~0xff) | this.getIPByte();\n if (BACKTRACK) this.backTrack.btiBL = this.backTrack.btiMem0;\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xB4 (MOV AH,imm8)\n *\n * @this {CPUX86}\n */\nX86.opMOVAHb = function()\n{\n this.regEAX = (this.regEAX & ~0xff00) | (this.getIPByte() << 8);\n if (BACKTRACK) this.backTrack.btiAH = this.backTrack.btiMem0;\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xB5 (MOV CH,imm8)\n *\n * @this {CPUX86}\n */\nX86.opMOVCHb = function()\n{\n this.regECX = (this.regECX & ~0xff00) | (this.getIPByte() << 8);\n if (BACKTRACK) this.backTrack.btiCH = this.backTrack.btiMem0;\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xB6 (MOV DH,imm8)\n *\n * @this {CPUX86}\n */\nX86.opMOVDHb = function()\n{\n this.regEDX = (this.regEDX & ~0xff00) | (this.getIPByte() << 8);\n if (BACKTRACK) this.backTrack.btiDH = this.backTrack.btiMem0;\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xB7 (MOV BH,imm8)\n *\n * @this {CPUX86}\n */\nX86.opMOVBHb = function()\n{\n this.regEBX = (this.regEBX & ~0xff00) | (this.getIPByte() << 8);\n if (BACKTRACK) this.backTrack.btiBH = this.backTrack.btiMem0;\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xB8 (MOV [E]AX,imm)\n *\n * @this {CPUX86}\n */\nX86.opMOVAX = function()\n{\n this.regEAX = (this.regEAX & ~this.maskData) | this.getIPWord();\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiMem0; this.backTrack.btiAH = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xB9 (MOV [E]CX,imm)\n *\n * @this {CPUX86}\n */\nX86.opMOVCX = function()\n{\n this.regECX = (this.regECX & ~this.maskData) | this.getIPWord();\n if (BACKTRACK) {\n this.backTrack.btiCL = this.backTrack.btiMem0; this.backTrack.btiCH = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xBA (MOV [E]DX,imm)\n *\n * @this {CPUX86}\n */\nX86.opMOVDX = function()\n{\n this.regEDX = (this.regEDX & ~this.maskData) | this.getIPWord();\n if (BACKTRACK) {\n this.backTrack.btiDL = this.backTrack.btiMem0; this.backTrack.btiDH = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xBB (MOV [E]BX,imm)\n *\n * @this {CPUX86}\n */\nX86.opMOVBX = function()\n{\n this.regEBX = (this.regEBX & ~this.maskData) | this.getIPWord();\n if (BACKTRACK) {\n this.backTrack.btiBL = this.backTrack.btiMem0; this.backTrack.btiBH = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xBC (MOV [E]SP,imm)\n *\n * @this {CPUX86}\n */\nX86.opMOVSP = function()\n{\n this.setSP((this.getSP() & ~this.maskData) | this.getIPWord());\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xBD (MOV [E]BP,imm)\n *\n * @this {CPUX86}\n */\nX86.opMOVBP = function()\n{\n this.regEBP = (this.regEBP & ~this.maskData) | this.getIPWord();\n if (BACKTRACK) {\n this.backTrack.btiBPLo = this.backTrack.btiMem0; this.backTrack.btiBPHi = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xBE (MOV [E]SI,imm)\n *\n * @this {CPUX86}\n */\nX86.opMOVSI = function()\n{\n this.regESI = (this.regESI & ~this.maskData) | this.getIPWord();\n if (BACKTRACK) {\n this.backTrack.btiSILo = this.backTrack.btiMem0; this.backTrack.btiSIHi = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xBF (MOV [E]DI,imm)\n *\n * @this {CPUX86}\n */\nX86.opMOVDI = function()\n{\n this.regEDI = (this.regEDI & ~this.maskData) | this.getIPWord();\n if (BACKTRACK) {\n this.backTrack.btiDILo = this.backTrack.btiMem0; this.backTrack.btiDIHi = this.backTrack.btiMem1;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLAHF;\n};\n\n/**\n * op=0xC0 (GRP2 byte,imm8) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opGRP2bn = function()\n{\n this.decodeModGrpByte.call(this, X86.aOpGrp2b, X86.helpSRCByte);\n};\n\n/**\n * op=0xC1 (GRP2 word,imm) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opGRP2wn = function()\n{\n this.decodeModGrpWord.call(this, this.sizeData == 2? X86.aOpGrp2w : X86.aOpGrp2d, X86.helpSRCByte);\n};\n\n/**\n * op=0xC2 (RET n)\n *\n * @this {CPUX86}\n */\nX86.opRETn = function()\n{\n var n = this.getIPShort();\n var newIP = this.popWord();\n this.setIP(newIP);\n if (n) this.setSP(this.getSP() + n); // TODO: optimize\n this.nStepCycles -= this.cycleCounts.nOpCyclesRetn;\n};\n\n/**\n * op=0xC3 (RET)\n *\n * @this {CPUX86}\n */\nX86.opRET = function()\n{\n var newIP = this.popWord();\n this.setIP(newIP);\n this.nStepCycles -= this.cycleCounts.nOpCyclesRet;\n};\n\n/**\n * op=0xC4 (LES reg,word)\n *\n * This is like a \"MOV reg,rm\" operation, but it also loads ES from the next word.\n *\n * @this {CPUX86}\n */\nX86.opLES = function()\n{\n this.decodeModRegWord.call(this, X86.fnLES);\n};\n\n/**\n * op=0xC5 (LDS reg,word)\n *\n * This is like a \"MOV reg,rm\" operation, but it also loads DS from the next word.\n *\n * @this {CPUX86}\n */\nX86.opLDS = function()\n{\n this.decodeModRegWord.call(this, X86.fnLDS);\n};\n\n/**\n * op=0xC6 (MOV byte,imm8)\n *\n * @this {CPUX86}\n */\nX86.opMOVb = function()\n{\n /*\n * Like other MOV operations, the destination does not need to be read, just written.\n */\n this.opFlags |= X86.OPFLAG.NOREAD;\n this.decodeModGrpByte.call(this, X86.aOpGrpMOVn, this.getIPByte);\n};\n\n/**\n * op=0xC7 (MOV word,imm)\n *\n * @this {CPUX86}\n */\nX86.opMOVw = function()\n{\n /*\n * Like other MOV operations, the destination does not need to be read, just written.\n */\n this.opFlags |= X86.OPFLAG.NOREAD;\n this.decodeModGrpWord.call(this, X86.aOpGrpMOVn, this.getIPWord);\n};\n\n/**\n * op=0xC8 (ENTER imm16,imm8) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opENTER = function()\n{\n /*\n * Any operation that performs multiple stack modifications must snapshot regLSP first.\n */\n this.opLSP = this.regLSP;\n\n var wLocal = this.getIPShort();\n var bLevel = this.getIPByte() & 0x1f;\n /*\n * NOTE: 11 is the minimum cycle time for the 80286; the 80186/80188 has different cycle times: 15, 25 and\n * 22 + 16 * (bLevel - 1) for bLevel 0, 1 and > 1, respectively. TODO: Fix this someday.\n */\n this.nStepCycles -= 11;\n this.pushWord(this.regEBP);\n var wFrame = this.getSP() & this.maskData;\n if (bLevel > 0) {\n this.nStepCycles -= (bLevel << 2) + (bLevel > 1? 1 : 0);\n while (--bLevel) {\n this.regEBP = (this.regEBP & ~this.maskData) | ((this.regEBP - this.sizeData) & this.maskData);\n this.pushWord(this.getSOWord(this.segSS, this.regEBP & this.maskData));\n }\n this.pushWord(wFrame);\n }\n this.regEBP = (this.regEBP & ~this.maskData) | wFrame;\n this.setSP((this.getSP() & ~this.segSS.maskAddr) | ((this.getSP() - wLocal) & this.segSS.maskAddr));\n\n this.opLSP = X86.ADDR_INVALID;\n};\n\n/**\n * op=0xC9 (LEAVE) (80186/80188 and up)\n *\n * @this {CPUX86}\n */\nX86.opLEAVE = function()\n{\n /*\n * Any operation that performs multiple stack modifications must snapshot regLSP first.\n */\n this.opLSP = this.regLSP;\n\n this.setSP((this.getSP() & ~this.segSS.maskAddr) | (this.regEBP & this.segSS.maskAddr));\n\n this.regEBP = (this.regEBP & ~this.maskData) | (this.popWord() & this.maskData);\n /*\n * NOTE: 5 is the cycle time for the 80286; the 80186/80188 has a cycle time of 8. TODO: Fix this someday.\n */\n this.nStepCycles -= 5;\n\n this.opLSP = X86.ADDR_INVALID;\n};\n\n/**\n * op=0xCA (RETF n)\n *\n * @this {CPUX86}\n */\nX86.opRETFn = function()\n{\n X86.helpRETF.call(this, this.getIPShort());\n this.nStepCycles -= this.cycleCounts.nOpCyclesRetFn;\n};\n\n/**\n * op=0xCB (RETF)\n *\n * @this {CPUX86}\n */\nX86.opRETF = function()\n{\n X86.helpRETF.call(this, 0);\n this.nStepCycles -= this.cycleCounts.nOpCyclesRetF;\n};\n\n/**\n * op=0xCC (INT 3)\n *\n * @this {CPUX86}\n */\nX86.opINT3 = function()\n{\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to V86-mode.\n */\n if (I386 && (this.regPS & X86.PS.VM) && this.nIOPL < 3) {\n if (DEBUG) this.printMessage(\"INT 0x03 in v86-mode (IOPL < 3)\", this.bitsMessage, true);\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n /*\n * Because INT3 is a trap, not a fault, we must use helpTrap() rather than helpFault(). Unfortunately, that\n * means you can't rely on the Debugger logic instead helpFault() to conditionally stop execution on an INT3,\n * so I've changed the Debugger's checkBreakpoint() function to stop execution on INT3 whenever both the\n * INT and HALT message bits are set; a simple \"g\" command allows you to continue.\n */\n X86.helpTrap.call(this, X86.EXCEPTION.BP_TRAP, this.cycleCounts.nOpCyclesInt3D);\n};\n\n/**\n * op=0xCD (INT n)\n *\n * @this {CPUX86}\n */\nX86.opINTn = function()\n{\n var nInt = this.getIPByte();\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to V86-mode.\n */\n if (I386 && (this.regPS & X86.PS.VM) && this.nIOPL < 3) {\n if (DEBUG && this.messageEnabled()) this.printMessage(\"INT \" + Str.toHexByte(nInt) + \" in v86-mode (IOPL < 3)\", true, true);\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n /*\n * checkIntNotify() checks for any notification handlers registered via addIntNotify(), calls them,\n * and returns false ONLY if a notification handler returned false (ie, requesting the interrupt be skipped).\n */\n if (this.checkIntNotify(nInt)) {\n X86.helpTrap.call(this, nInt, 0);\n return;\n }\n this.nStepCycles--; // we don't need to assess the full cost of nOpCyclesInt, but we need to assess something...\n};\n\n/**\n * op=0xCE (INTO: INT 4 if OF set)\n *\n * @this {CPUX86}\n */\nX86.opINTO = function()\n{\n if (this.getOF()) {\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to V86-mode.\n */\n if (I386 && (this.regPS & X86.PS.VM) && this.nIOPL < 3) {\n if (DEBUG) this.printMessage(\"INTO in v86-mode (IOPL < 3)\", this.bitsMessage, true);\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n X86.helpTrap.call(this, X86.EXCEPTION.OF_TRAP, this.cycleCounts.nOpCyclesIntOD);\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesIntOFall;\n};\n\n/**\n * op=0xCF (IRET)\n *\n * @this {CPUX86}\n */\nX86.opIRET = function()\n{\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to V86-mode.\n */\n if (I386 && (this.regPS & X86.PS.VM) && this.nIOPL < 3) {\n if (DEBUG) this.printMessage(\"IRET in v86-mode (IOPL < 3)\", this.bitsMessage, true);\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n X86.helpIRET.call(this);\n};\n\n/**\n * op=0xD0 (GRP2 byte,1)\n *\n * @this {CPUX86}\n */\nX86.opGRP2b1 = function()\n{\n this.decodeModGrpByte.call(this, X86.aOpGrp2b, X86.helpSRC1);\n};\n\n/**\n * op=0xD1 (GRP2 word,1)\n *\n * @this {CPUX86}\n */\nX86.opGRP2w1 = function()\n{\n this.decodeModGrpWord.call(this, this.sizeData == 2? X86.aOpGrp2w : X86.aOpGrp2d, X86.helpSRC1);\n};\n\n/**\n * op=0xD2 (GRP2 byte,CL)\n *\n * @this {CPUX86}\n */\nX86.opGRP2bCL = function()\n{\n this.decodeModGrpByte.call(this, X86.aOpGrp2b, X86.helpSRCCL);\n};\n\n/**\n * op=0xD3 (GRP2 word,CL)\n *\n * @this {CPUX86}\n */\nX86.opGRP2wCL = function()\n{\n this.decodeModGrpWord.call(this, this.sizeData == 2? X86.aOpGrp2w : X86.aOpGrp2d, X86.helpSRCCL);\n};\n\n/**\n * op=0xD4 0x0A (AAM)\n *\n * From \"The 8086 Book\":\n *\n * 1. Divide AL by 0x0A; store the quotient in AH and the remainder in AL\n * 2. Set PF, SF, and ZF based on the AL register (CF, OF, and AF are undefined)\n *\n * From \"Undocumented Opcodes\" (http://www.rcollins.org/secrets/opcodes/AAM.html):\n *\n * AAM is shown as a two byte encoding used to divide AL by 10, putting the quotient in AH, and the remainder in AL.\n * However, AAM is listed in the op code map as a single byte instruction. This leads one to wonder why a two-byte\n * opcode is listed in the single-byte opcode map. In reality, the second byte is an undocumented operand to AAM.\n * The operand is the divisor. In its documented incarnation, AAM is encoded as D4 0A. The operand 0A is the divisor.\n * This divisor can be changed to any value between 0 and FF.\n *\n * Using AAM in this manner is useful -- as it extends the CPU instruction set to include a DIV IMM8 instruction\n * that is not available from any other form of the DIV instruction. The extended form of the AAM instruction is also\n * useful because it sets the flags register according to the results, unlike the DIV or IDIV instruction.\n *\n * According to Intel documentation, SF, ZF, and PF flags are set according to the result, while OF, AF, and CF\n * are undefined. However, if AAM were used strictly as documented, then the Sign Flag (SF) could not be set under\n * any circumstances, since anything divided by 10 will leave a remainder between 0 and 9. Obviously the remainder\n * could never be between 128 and 255 (or -1 and -128 if you prefer) if used only as documented. Since AAM divides\n * an 8 bit number by another 8-bit number, a carry or overflow could never occur. Therefore CF and OF always=0.\n * Intel claims they are undefined, but my observations are consistent with my theory.\n *\n * Contrary to documentation, AAM will generate exceptions in real mode, protected mode, and V86 mode. AAM can only\n * generate Exception 0 -- divide by 0.\n *\n * Finally, in the Pentium User's Manual, this heretofore undocumented form of AMM is described. Intel says:\n *\n * Note: imm8 has the value of the instruction's second byte. The second byte under normally assembly [sic] of\n * this instruction will be 0A, however, explicit modification of this byte will result in the operation described\n * above and may alter results.\n *\n * This instruction exists in this form on all Intel x86 processors. See the file [AAM.ASM](/docs/x86/ops/AAM/AAM.ASM)\n * for diagnostics source code for this instruction.\n *\n * @this {CPUX86}\n */\nX86.opAAM = function()\n{\n var b = this.getIPByte();\n if (!b) {\n X86.helpDIVOverflow.call(this);\n return;\n }\n var AL = this.regEAX & 0xff;\n this.regEAX = (this.regEAX & ~0xffff) | ((AL / b) << 8) | (AL % b);\n /*\n * setLogicResult() is perfect, because it ensures that CF and OF are cleared as well (see above for why).\n */\n this.setLogicResult(this.regEAX, X86.RESULT.BYTE);\n this.nStepCycles -= this.cycleCounts.nOpCyclesAAM;\n};\n\n/**\n * op=0xD5 (AAD)\n *\n * From \"The 8086 Book\":\n *\n * 1. Multiply AH by 0x0A, add AH to AL, and store 0x00 in AH\n * 2. Set PF, SF, and ZF based on the AL register (CF, OF, and AF are undefined)\n *\n * From \"Undocumented Opcodes\" (http://www.rcollins.org/secrets/opcodes/AAD.html):\n *\n * This instruction is the multiplication counterpart to AAM. As is the case with AAM, AAD uses the second\n * byte as an operand. This operand is the multiplicand for AAD. Like AAM, AAD provides a way to execute a MUL\n * IMM8 that is unavailable through any other means in the CPU.\n *\n * Unlike MUL, or IMUL, AAD sets all of the CPU status flags according to the result. Intel states that the\n * Overflow Flag (OF), Auxiliary carry Flag (AF), and Carry Flag (CF) are undefined. This assertion is incorrect.\n * These flags are fully defined, and are set consistently with respect to any other integer operations.\n *\n * And again, like AMM, beginning with the Pentium, Intel has finally acknowledged the existence of the second\n * byte of this instruction as its operand. Intel says:\n *\n * Note: imm8 has the value of the instruction's second byte. The second byte under normally assembly [sic]\n * of this instruction will be 0A, however, explicit modification of this byte will result in the operation\n * described above and may alter results.\n *\n * This instruction exists in this form on all Intel x86 processors. See the file [AAD.ASM](/docs/x86/ops/AAD/AAD.ASM)\n * for diagnostics source code for this instruction.\n *\n * TODO: Confirm on real hardware that flags reflect the result of the final addition (ie, that the result of the\n * intermediate multiplication is irrelevant); it also might be nice to confirm that an operand override has no effect.\n *\n * @this {CPUX86}\n */\nX86.opAAD = function()\n{\n var dst = (this.regEAX & 0xff);\n var src = (((this.regEAX >> 8) & 0xff) * this.getIPByte())|0;\n var result = (dst + src)|0;\n this.regEAX = (this.regEAX & ~0xffff) | (result & 0xff);\n this.setArithResult(dst, src, result, X86.RESULT.BYTE | X86.RESULT.ALL);\n this.nStepCycles -= this.cycleCounts.nOpCyclesAAD;\n};\n\n/**\n * op=0xD6 (SALC aka SETALC) (undocumented until Pentium Pro)\n *\n * Sets AL to 0xFF if CF=1, 0x00 otherwise; no flags are affected (similar to SBB AL,AL, but without side-effects)\n *\n * WARNING: I have no idea how many clocks this instruction originally required, so for now, I'm going with a minimum of 2.\n *\n * @this {CPUX86}\n */\nX86.opSALC = function()\n{\n this.regEAX = (this.regEAX & ~0xff) | (this.getCF()? 0xFF : 0);\n this.nStepCycles -= 2;\n};\n\n/**\n * op=0xD7 (XLAT)\n *\n * @this {CPUX86}\n */\nX86.opXLAT = function()\n{\n /*\n * TODO: Verify whether XLAT wraps its address calculation....\n */\n this.regEAX = (this.regEAX & ~0xff) | this.getEAByte(this.segData, (this.regEBX + (this.regEAX & 0xff)));\n this.nStepCycles -= this.cycleCounts.nOpCyclesXLAT;\n};\n\n/**\n * opESC()\n *\n * @this {CPUX86}\n * @param {number} bOpcode\n */\nX86.opESC = function(bOpcode)\n{\n this.bOpcode = bOpcode;\n this.decodeModRegWord.call(this, X86.fnESC);\n};\n\n/**\n * op=0xD8 (ESC0)\n *\n * @this {CPUX86}\n */\nX86.opESC0 = function()\n{\n X86.opESC.call(this, X86.OPCODE.ESC0);\n};\n\n/**\n * op=0xD9 (ESC1)\n *\n * @this {CPUX86}\n */\nX86.opESC1 = function()\n{\n X86.opESC.call(this, X86.OPCODE.ESC1);\n};\n\n/**\n * op=0xDA (ESC2)\n *\n * @this {CPUX86}\n */\nX86.opESC2 = function()\n{\n X86.opESC.call(this, X86.OPCODE.ESC2);\n};\n\n/**\n * op=0xDB (ESC3)\n *\n * @this {CPUX86}\n */\nX86.opESC3 = function()\n{\n X86.opESC.call(this, X86.OPCODE.ESC3);\n};\n\n/**\n * op=0xDC (ESC4)\n *\n * @this {CPUX86}\n */\nX86.opESC4 = function()\n{\n X86.opESC.call(this, X86.OPCODE.ESC4);\n};\n\n/**\n * op=0xDD (ESC5)\n *\n * @this {CPUX86}\n */\nX86.opESC5 = function()\n{\n X86.opESC.call(this, X86.OPCODE.ESC5);\n};\n\n/**\n * op=0xDE (ESC6)\n *\n * @this {CPUX86}\n */\nX86.opESC6 = function()\n{\n X86.opESC.call(this, X86.OPCODE.ESC6);\n};\n\n/**\n * op=0xDF (ESC7)\n *\n * @this {CPUX86}\n */\nX86.opESC7 = function()\n{\n X86.opESC.call(this, X86.OPCODE.ESC7);\n};\n\n/**\n * op=0xE0 (LOOPNZ disp)\n *\n * NOTE: All the instructions in this group (LOOPNZ, LOOPZ, LOOP, and JCXZ) actually\n * rely on the ADDRESS override setting for determining whether CX or ECX will be used,\n * even though it seems counter-intuitive; ditto for the REP prefix.\n *\n * @this {CPUX86}\n */\nX86.opLOOPNZ = function()\n{\n var disp = this.getIPDisp();\n var n = (this.regECX - 1) & this.maskAddr;\n this.regECX = (this.regECX & ~this.maskAddr) | n;\n if (n && !this.getZF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesLoopNZ;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLoopFall;\n};\n\n/**\n * op=0xE1 (LOOPZ disp)\n *\n * NOTE: All the instructions in this group (LOOPNZ, LOOPZ, LOOP, and JCXZ) actually\n * rely on the ADDRESS override setting for determining whether CX or ECX will be used,\n * even though it seems counter-intuitive; ditto for the REP prefix.\n *\n * @this {CPUX86}\n */\nX86.opLOOPZ = function()\n{\n var disp = this.getIPDisp();\n var n = (this.regECX - 1) & this.maskAddr;\n this.regECX = (this.regECX & ~this.maskAddr) | n;\n if (n && this.getZF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesLoopZ;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLoopZFall;\n};\n\n/**\n * op=0xE2 (LOOP disp)\n *\n * NOTE: All the instructions in this group (LOOPNZ, LOOPZ, LOOP, and JCXZ) actually\n * rely on the ADDRESS override setting for determining whether CX or ECX will be used,\n * even though it seems counter-intuitive; ditto for the REP prefix.\n *\n * @this {CPUX86}\n */\nX86.opLOOP = function()\n{\n var disp = this.getIPDisp();\n var n = (this.regECX - 1) & this.maskAddr;\n this.regECX = (this.regECX & ~this.maskAddr) | n;\n if (n) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesLoop;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLoopFall;\n};\n\n/**\n * op=0xE3 (JCXZ/JECXZ disp)\n *\n * NOTE: All the instructions in this group (LOOPNZ, LOOPZ, LOOP, and JCXZ) actually\n * rely on the ADDRESS override setting for determining whether CX or ECX will be used,\n * even though it seems counter-intuitive; ditto for the REP prefix.\n *\n * @this {CPUX86}\n */\nX86.opJCXZ = function()\n{\n var disp = this.getIPDisp();\n if (!(this.regECX & this.maskAddr)) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesLoopZ;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesLoopZFall;\n};\n\n/**\n * op=0xE4 (IN AL,port)\n *\n * @this {CPUX86}\n */\nX86.opINb = function()\n{\n var port = this.getIPByte();\n if (!this.checkIOPM(port, 1, true)) return;\n this.regEAX = (this.regEAX & ~0xff) | (this.bus.checkPortInputNotify(port, 1, this.regLIP - 2) & 0xff);\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiIO;\n this.nStepCycles -= this.cycleCounts.nOpCyclesInP;\n};\n\n/**\n * op=0xE5 (IN AX,port)\n *\n * @this {CPUX86}\n */\nX86.opINw = function()\n{\n var port = this.getIPByte();\n if (!this.checkIOPM(port, this.sizeData, true)) return;\n this.regEAX = (this.regEAX & ~this.maskData) | (this.bus.checkPortInputNotify(port, this.sizeData, this.regLIP - 2) & this.maskData);\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiIO;\n this.backTrack.btiAH = this.backTrack.btiIO;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesInP;\n};\n\n/**\n * op=0xE6 (OUT port,AL)\n *\n * @this {CPUX86}\n */\nX86.opOUTb = function()\n{\n var port = this.getIPByte();\n if (!this.checkIOPM(port, 1, false)) return;\n this.bus.checkPortOutputNotify(port, 1, this.regEAX & 0xff, this.regLIP - 2);\n this.nStepCycles -= this.cycleCounts.nOpCyclesOutP;\n};\n\n/**\n * op=0xE7 (OUT port,AX)\n *\n * @this {CPUX86}\n */\nX86.opOUTw = function()\n{\n var port = this.getIPByte();\n if (!this.checkIOPM(port, this.sizeData, false)) return;\n this.bus.checkPortOutputNotify(port, this.sizeData, this.regEAX & this.maskData, this.regLIP - 2);\n this.nStepCycles -= this.cycleCounts.nOpCyclesOutP;\n};\n\n/**\n * op=0xE8 (CALL disp16)\n *\n * @this {CPUX86}\n */\nX86.opCALL = function()\n{\n var disp = this.getIPWord();\n var oldIP = this.getIP();\n var newIP = oldIP + disp;\n this.pushWord(oldIP);\n this.setIP(newIP);\n this.nStepCycles -= this.cycleCounts.nOpCyclesCall;\n};\n\n/**\n * op=0xE9 (JMP disp16)\n *\n * @this {CPUX86}\n */\nX86.opJMP = function()\n{\n var disp = this.getIPWord();\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmp;\n};\n\n/**\n * op=0xEA (JMP seg:off)\n *\n * @this {CPUX86}\n */\nX86.opJMPF = function()\n{\n this.setCSIP(this.getIPWord(), this.getIPShort());\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpF;\n};\n\n/**\n * op=0xEB (JMP short disp8)\n *\n * @this {CPUX86}\n */\nX86.opJMPs = function()\n{\n var disp = this.getIPDisp();\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmp;\n};\n\n/**\n * op=0xEC (IN AL,dx)\n *\n * @this {CPUX86}\n */\nX86.opINDXb = function()\n{\n var port = this.regEDX & 0xffff;\n if (!this.checkIOPM(port, 1, true)) return;\n this.regEAX = (this.regEAX & ~0xff) | (this.bus.checkPortInputNotify(port, 1, this.regLIP - 1) & 0xff);\n if (BACKTRACK) this.backTrack.btiAL = this.backTrack.btiIO;\n this.nStepCycles -= this.cycleCounts.nOpCyclesInDX;\n};\n\n/**\n * op=0xED (IN AX,dx)\n *\n * @this {CPUX86}\n */\nX86.opINDXw = function()\n{\n var port = this.regEDX & 0xffff;\n if (!this.checkIOPM(port, this.sizeData, true)) return;\n this.regEAX = (this.regEAX & ~this.maskData) | (this.bus.checkPortInputNotify(port, this.sizeData, this.regLIP - 1) & this.maskData);\n if (BACKTRACK) {\n this.backTrack.btiAL = this.backTrack.btiIO;\n this.backTrack.btiAH = this.backTrack.btiIO;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesInDX;\n};\n\n/**\n * op=0xEE (OUT dx,AL)\n *\n * @this {CPUX86}\n */\nX86.opOUTDXb = function()\n{\n var port = this.regEDX & 0xffff;\n if (!this.checkIOPM(port, 1, false)) return;\n if (BACKTRACK) this.backTrack.btiIO = this.backTrack.btiAL;\n this.bus.checkPortOutputNotify(port, 1, this.regEAX & 0xff, this.regLIP - 1);\n this.nStepCycles -= this.cycleCounts.nOpCyclesOutDX;\n};\n\n/**\n * op=0xEF (OUT dx,AX)\n *\n * @this {CPUX86}\n */\nX86.opOUTDXw = function()\n{\n var port = this.regEDX & 0xffff;\n if (!this.checkIOPM(port, 2, false)) return;\n if (BACKTRACK) {\n this.backTrack.btiIO = this.backTrack.btiAL;\n this.backTrack.btiIO = this.backTrack.btiAH;\n }\n this.bus.checkPortOutputNotify(port, this.sizeData, this.regEAX & this.maskData, this.regLIP - 1);\n this.nStepCycles -= this.cycleCounts.nOpCyclesOutDX;\n};\n\n/**\n * op=0xF0 (LOCK:)\n *\n * @this {CPUX86}\n */\nX86.opLOCK = function()\n{\n this.opFlags |= X86.OPFLAG.LOCK | X86.OPFLAG.NOINTR;\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n};\n\n/**\n * op=0xF1 (INT1; undocumented; 80186/80188 and up; TODO: Verify)\n *\n * Note that this handler is assigned to opcode 0xF1 only on 80186 processors and up, because on 8086/8086\n * processors, we treat that opcode as an alias for LOCK (0xF0).\n *\n * For the 80186 and up, and we treat it as undefined. Starting with the 80386, this opcode is known as INT1\n * or ICEBP, since it effectively performs an INT 0x01 but is normally only performed with an ICE.\n *\n * @this {CPUX86}\n */\nX86.opINT1 = function()\n{\n X86.opUndefined.call(this);\n};\n\n/**\n * op=0xF2 (REPNZ:) (repeat CMPS or SCAS until NZ; repeat MOVS, LODS, or STOS unconditionally)\n *\n * @this {CPUX86}\n */\nX86.opREPNZ = function()\n{\n this.opFlags |= X86.OPFLAG.REPNZ | X86.OPFLAG.NOINTR;\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n};\n\n/**\n * op=0xF3 (REPZ:) (repeat CMPS or SCAS until Z; repeat MOVS, LODS, or STOS unconditionally)\n *\n * @this {CPUX86}\n */\nX86.opREPZ = function()\n{\n this.opFlags |= X86.OPFLAG.REPZ | X86.OPFLAG.NOINTR;\n this.nStepCycles -= this.cycleCounts.nOpCyclesPrefix;\n};\n\n/**\n * op=0xF4 (HLT)\n *\n * @this {CPUX86}\n */\nX86.opHLT = function()\n{\n if (I386 && (this.regPS & X86.PS.VM)) {\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n /*\n * The CPU is never REALLY halted by a HLT instruction; instead, by setting X86.INTFLAG.HALT,\n * we are signalling to stepCPU() that it's free to end the current burst AND that it should not\n * execute any more instructions until checkINTR() indicates a hardware interrupt is requested.\n */\n this.intFlags |= X86.INTFLAG.HALT;\n this.nStepCycles -= 2;\n /*\n * If a Debugger is present and both the CPU and HALT message categories are enabled, then we\n * REALLY halt the CPU, on the theory that whoever's using the Debugger would like to see HLTs.\n */\n if (DEBUGGER && this.dbg && this.messageEnabled(Messages.CPU | Messages.HALT)) {\n this.resetIP(-1); // this is purely for the Debugger's benefit, to show the HLT\n this.dbg.stopCPU();\n return;\n }\n /*\n * We also REALLY halt the machine if interrupts have been disabled, since that means it's dead in\n * the water (yes, we support NMIs, but none of our devices are going to generate an NMI at this point).\n */\n if (!this.getIF()) {\n if (DEBUGGER && this.dbg) this.resetIP(-1);\n this.stopCPU();\n }\n};\n\n/**\n * op=0xF5 (CMC)\n *\n * @this {CPUX86}\n */\nX86.opCMC = function()\n{\n if (this.getCF()) this.clearCF(); else this.setCF();\n this.nStepCycles -= 2; // CMC takes 2 cycles on all CPUs\n};\n\n/**\n * op=0xF6 (GRP3 byte)\n *\n * The MUL byte instruction is problematic in two cases:\n *\n * 0xF6 0xE0: MUL AL\n * 0xF6 0xE4: MUL AH\n *\n * because the OpModGrpByte decoder function will attempt to put the fnMULb() function's\n * return value back into AL or AH, undoing fnMULb's update of AX. And since fnMULb doesn't\n * know what the target is (only the target's value), it cannot easily work around the problem.\n *\n * A simple, albeit kludgy, solution is for fnMULb to always save its result in a special\n * \"register\" (eg, regMDLo), which we will then put back into regEAX if it's been updated.\n * This also relieves us from having to decode any part of the ModRM byte, so maybe it's not\n * such a bad work-around after all.\n *\n * Similar issues with IMUL (and DIV and IDIV) are resolved using the same special variable(s).\n *\n * @this {CPUX86}\n */\nX86.opGRP3b = function()\n{\n this.fMDSet = false;\n this.decodeModGrpByte.call(this, X86.aOpGrp3b, X86.helpSRCNone);\n if (this.fMDSet) this.regEAX = (this.regEAX & ~this.maskData) | (this.regMDLo & this.maskData);\n};\n\n/**\n * op=0xF7 (GRP3 word)\n *\n * The MUL word instruction is problematic in two cases:\n *\n * 0xF7 0xE0: MUL AX\n * 0xF7 0xE2: MUL DX\n *\n * because the OpModGrpWord decoder function will attempt to put the fnMULw() function's\n * return value back into AX or DX, undoing fnMULw's update of DX:AX. And since fnMULw doesn't\n * know what the target is (only the target's value), it cannot easily work around the problem.\n *\n * A simple, albeit kludgy, solution is for fnMULw to always save its result in a special\n * \"register\" (eg, regMDLo/regMDHi), which we will then put back into regEAX/regEDX if it's been\n * updated. This also relieves us from having to decode any part of the ModRM byte, so maybe\n * it's not such a bad work-around after all.\n *\n * @this {CPUX86}\n */\nX86.opGRP3w = function()\n{\n this.fMDSet = false;\n this.decodeModGrpWord.call(this, X86.aOpGrp3w, X86.helpSRCNone);\n if (this.fMDSet) {\n this.regEAX = (this.regEAX & ~this.maskData) | (this.regMDLo & this.maskData);\n this.regEDX = (this.regEDX & ~this.maskData) | (this.regMDHi & this.maskData);\n }\n};\n\n/**\n * op=0xF8 (CLC)\n *\n * @this {CPUX86}\n */\nX86.opCLC = function()\n{\n this.clearCF();\n this.nStepCycles -= 2; // CLC takes 2 cycles on all CPUs\n};\n\n/**\n * op=0xF9 (STC)\n *\n * @this {CPUX86}\n */\nX86.opSTC = function()\n{\n this.setCF();\n this.nStepCycles -= 2; // STC takes 2 cycles on all CPUs\n};\n\n/**\n * op=0xFA (CLI)\n *\n * @this {CPUX86}\n */\nX86.opCLI = function()\n{\n /*\n * The following code should be sufficient for all modes, because in real-mode, CPL is always zero,\n * and in V86-mode, CPL is always 3.\n */\n if (this.nCPL > this.nIOPL) {\n if (DEBUG && (this.regPS & X86.PS.VM)) this.printMessage(\"CLI in v86-mode (IOPL < 3)\", this.bitsMessage, true);\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n this.clearIF();\n this.nStepCycles -= this.cycleCounts.nOpCyclesCLI; // CLI takes LONGER on an 80286\n};\n\n/**\n * op=0xFB (STI)\n *\n * @this {CPUX86}\n */\nX86.opSTI = function()\n{\n /*\n * The following code should be sufficient for all modes, because in real-mode, CPL is always zero,\n * and in V86-mode, CPL is always 3.\n */\n if (this.nCPL > this.nIOPL) {\n if (DEBUG && (this.regPS & X86.PS.VM)) this.printMessage(\"STI in v86-mode (IOPL < 3)\", this.bitsMessage, true);\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n this.setIF();\n this.opFlags |= X86.OPFLAG.NOINTR;\n this.nStepCycles -= 2; // STI takes 2 cycles on all CPUs\n};\n\n/**\n * op=0xFC (CLD)\n *\n * @this {CPUX86}\n */\nX86.opCLD = function()\n{\n this.clearDF();\n this.nStepCycles -= 2; // CLD takes 2 cycles on all CPUs\n};\n\n/**\n * op=0xFD (STD)\n *\n * @this {CPUX86}\n */\nX86.opSTD = function()\n{\n this.setDF();\n this.nStepCycles -= 2; // STD takes 2 cycles on all CPUs\n};\n\n/**\n * op=0xFE (GRP4 byte)\n *\n * @this {CPUX86}\n */\nX86.opGRP4b = function()\n{\n this.decodeModGrpByte.call(this, X86.aOpGrp4b, X86.helpSRCNone);\n};\n\n/**\n * op=0xFF (GRP4 word)\n *\n * @this {CPUX86}\n */\nX86.opGRP4w = function()\n{\n this.decodeModGrpWord.call(this, X86.aOpGrp4w, X86.helpSRCNone);\n};\n\n/**\n * opInvalid()\n *\n * @this {CPUX86}\n */\nX86.opInvalid = function()\n{\n X86.helpFault.call(this, X86.EXCEPTION.UD_FAULT);\n};\n\n/**\n * opUndefined()\n *\n * @this {CPUX86}\n */\nX86.opUndefined = function()\n{\n this.setIP(this.opLIP - this.segCS.base);\n this.setError(\"Undefined opcode \" + Str.toHexByte(this.getByte(this.regLIP)) + \" at \" + Str.toHexLong(this.regLIP));\n this.stopCPU();\n};\n\n/**\n * opTBD()\n *\n * @this {CPUX86}\n */\nX86.opTBD = function()\n{\n this.setIP(this.opLIP - this.segCS.base);\n this.printMessage(\"unimplemented 80386 opcode\", true);\n this.stopCPU();\n};\n\n/*\n * This 256-entry array of opcode functions is at the heart of the CPU engine: stepCPU(n).\n *\n * It might be worth trying a switch() statement instead, to see how the performance compares,\n * but I suspect that would vary quite a bit across JavaScript engines; for now, I'm putting my\n * money on array lookup.\n */\nX86.aOps = [\n X86.opADDmb, X86.opADDmw, X86.opADDrb, X86.opADDrw, // 0x00-0x03\n X86.opADDALb, X86.opADDAX, X86.opPUSHES, X86.opPOPES, // 0x04-0x07\n X86.opORmb, X86.opORmw, X86.opORrb, X86.opORrw, // 0x08-0x0B\n X86.opORALb, X86.opORAX, X86.opPUSHCS, X86.opPOPCS, // 0x0C-0x0F\n X86.opADCmb, X86.opADCmw, X86.opADCrb, X86.opADCrw, // 0x10-0x13\n X86.opADCALb, X86.opADCAX, X86.opPUSHSS, X86.opPOPSS, // 0x14-0x17\n X86.opSBBmb, X86.opSBBmw, X86.opSBBrb, X86.opSBBrw, // 0x18-0x1B\n X86.opSBBALb, X86.opSBBAX, X86.opPUSHDS, X86.opPOPDS, // 0x1C-0x1F\n X86.opANDmb, X86.opANDmw, X86.opANDrb, X86.opANDrw, // 0x20-0x23\n X86.opANDAL, X86.opANDAX, X86.opES, X86.opDAA, // 0x24-0x27\n X86.opSUBmb, X86.opSUBmw, X86.opSUBrb, X86.opSUBrw, // 0x28-0x2B\n X86.opSUBALb, X86.opSUBAX, X86.opCS, X86.opDAS, // 0x2C-0x2F\n X86.opXORmb, X86.opXORmw, X86.opXORrb, X86.opXORrw, // 0x30-0x33\n X86.opXORALb, X86.opXORAX, X86.opSS, X86.opAAA, // 0x34-0x37\n X86.opCMPmb, X86.opCMPmw, X86.opCMPrb, X86.opCMPrw, // 0x38-0x3B\n X86.opCMPALb, X86.opCMPAX, X86.opDS, X86.opAAS, // 0x3C-0x3F\n X86.opINCAX, X86.opINCCX, X86.opINCDX, X86.opINCBX, // 0x40-0x43\n X86.opINCSP, X86.opINCBP, X86.opINCSI, X86.opINCDI, // 0x44-0x47\n X86.opDECAX, X86.opDECCX, X86.opDECDX, X86.opDECBX, // 0x48-0x4B\n X86.opDECSP, X86.opDECBP, X86.opDECSI, X86.opDECDI, // 0x4C-0x4F\n X86.opPUSHAX, X86.opPUSHCX, X86.opPUSHDX, X86.opPUSHBX, // 0x50-0x53\n X86.opPUSHSP_8086, X86.opPUSHBP, X86.opPUSHSI, X86.opPUSHDI, // 0x54-0x57\n X86.opPOPAX, X86.opPOPCX, X86.opPOPDX, X86.opPOPBX, // 0x58-0x5B\n X86.opPOPSP, X86.opPOPBP, X86.opPOPSI, X86.opPOPDI, // 0x5C-0x5F\n /*\n * On an 8086/8088, opcodes 0x60-0x6F are aliases for the conditional jumps 0x70-0x7F. Sometimes you'll see\n * references to these opcodes (like 0x60) being a \"two-byte NOP\" and using them differentiate an 8088 from newer\n * CPUs, but they're only a \"two-byte NOP\" if the second byte is zero, resulting in zero displacement.\n */\n X86.opJO, X86.opJNO, X86.opJC, X86.opJNC, // 0x60-0x63\n X86.opJZ, X86.opJNZ, X86.opJBE, X86.opJNBE, // 0x64-0x67\n X86.opJS, X86.opJNS, X86.opJP, X86.opJNP, // 0x68-0x6B\n X86.opJL, X86.opJNL, X86.opJLE, X86.opJNLE, // 0x6C-0x6F\n X86.opJO, X86.opJNO, X86.opJC, X86.opJNC, // 0x70-0x73\n X86.opJZ, X86.opJNZ, X86.opJBE, X86.opJNBE, // 0x74-0x77\n X86.opJS, X86.opJNS, X86.opJP, X86.opJNP, // 0x78-0x7B\n X86.opJL, X86.opJNL, X86.opJLE, X86.opJNLE, // 0x7C-0x7F\n /*\n * On all processors, opcode groups 0x80 and 0x82 perform identically (0x82 opcodes sign-extend their\n * immediate data, but since both 0x80 and 0x82 are byte operations, the sign extension has no effect).\n *\n * WARNING: Intel's \"Pentium Processor User's Manual (Volume 3: Architecture and Programming Manual)\" refers\n * to opcode 0x82 as a \"reserved\" instruction, but also cryptically refers to it as \"MOVB AL,imm\". This is\n * assumed to be an error in the manual, because as far as I know, 0x82 has always mirrored 0x80.\n */\n X86.opGRP1b, X86.opGRP1w, X86.opGRP1b, X86.opGRP1sw, // 0x80-0x83\n X86.opTESTrb, X86.opTESTrw, X86.opXCHGrb, X86.opXCHGrw, // 0x84-0x87\n X86.opMOVmb, X86.opMOVmw, X86.opMOVrb, X86.opMOVrw, // 0x88-0x8B\n X86.opMOVwsr, X86.opLEA, X86.opMOVsrw, X86.opPOPmw, // 0x8C-0x8F\n X86.opNOP, X86.opXCHGCX, X86.opXCHGDX, X86.opXCHGBX, // 0x90-0x93\n X86.opXCHGSP, X86.opXCHGBP, X86.opXCHGSI, X86.opXCHGDI, // 0x94-0x97\n X86.opCBW, X86.opCWD, X86.opCALLF, X86.opWAIT, // 0x98-0x9B\n X86.opPUSHF, X86.opPOPF, X86.opSAHF, X86.opLAHF, // 0x9C-0x9F\n X86.opMOVALm, X86.opMOVAXm, X86.opMOVmAL, X86.opMOVmAX, // 0xA0-0xA3\n X86.opMOVSb, X86.opMOVSw, X86.opCMPSb, X86.opCMPSw, // 0xA4-0xA7\n X86.opTESTALb, X86.opTESTAX, X86.opSTOSb, X86.opSTOSw, // 0xA8-0xAB\n X86.opLODSb, X86.opLODSw, X86.opSCASb, X86.opSCASw, // 0xAC-0xAF\n X86.opMOVALb, X86.opMOVCLb, X86.opMOVDLb, X86.opMOVBLb, // 0xB0-0xB3\n X86.opMOVAHb, X86.opMOVCHb, X86.opMOVDHb, X86.opMOVBHb, // 0xB4-0xB7\n X86.opMOVAX, X86.opMOVCX, X86.opMOVDX, X86.opMOVBX, // 0xB8-0xBB\n X86.opMOVSP, X86.opMOVBP, X86.opMOVSI, X86.opMOVDI, // 0xBC-0xBF\n /*\n * On an 8086/8088, opcodes 0xC0 -> 0xC2, 0xC1 -> 0xC3, 0xC8 -> 0xCA and 0xC9 -> 0xCB.\n */\n X86.opRETn, X86.opRET, X86.opRETn, X86.opRET, // 0xC0-0xC3\n X86.opLES, X86.opLDS, X86.opMOVb, X86.opMOVw, // 0xC4-0xC7\n X86.opRETFn, X86.opRETF, X86.opRETFn, X86.opRETF, // 0xC8-0xCB\n X86.opINT3, X86.opINTn, X86.opINTO, X86.opIRET, // 0xCC-0xCF\n X86.opGRP2b1, X86.opGRP2w1, X86.opGRP2bCL, X86.opGRP2wCL, // 0xD0-0xD3\n /*\n * Even as of the Pentium, opcode 0xD6 is still marked as \"reserved\", but it's always been SALC (aka SETALC).\n */\n X86.opAAM, X86.opAAD, X86.opSALC, X86.opXLAT, // 0xD4-0xD7\n X86.opESC0, X86.opESC1, X86.opESC2, X86.opESC3, // 0xD8-0xDB\n X86.opESC4, X86.opESC5, X86.opESC6, X86.opESC7, // 0xDC-0xDF\n X86.opLOOPNZ, X86.opLOOPZ, X86.opLOOP, X86.opJCXZ, // 0xE0-0xE3\n X86.opINb, X86.opINw, X86.opOUTb, X86.opOUTw, // 0xE4-0xE7\n X86.opCALL, X86.opJMP, X86.opJMPF, X86.opJMPs, // 0xE8-0xEB\n X86.opINDXb, X86.opINDXw, X86.opOUTDXb, X86.opOUTDXw, // 0xEC-0xEF\n /*\n * On an 8086/8088, opcode 0xF1 is believed to be an alias for 0xF0; in any case, it definitely behaves like\n * a prefix on those processors, so we treat it as such. On the 80186 and up, we treat as opINT1().\n *\n * As of the Pentium, opcode 0xF1 is still marked \"reserved\".\n */\n X86.opLOCK, X86.opLOCK, X86.opREPNZ, X86.opREPZ, // 0xF0-0xF3\n X86.opHLT, X86.opCMC, X86.opGRP3b, X86.opGRP3w, // 0xF4-0xF7\n X86.opCLC, X86.opSTC, X86.opCLI, X86.opSTI, // 0xF8-0xFB\n X86.opCLD, X86.opSTD, X86.opGRP4b, X86.opGRP4w // 0xFC-0xFF\n];\n\n/*\n * A word (or two) on instruction groups (eg, Grp1, Grp2), which are groups of instructions that\n * use a mod/reg/rm byte, where the reg field of that byte selects a function rather than a register.\n *\n * I start with the groupings used by Intel's \"Pentium Processor User's Manual (Volume 3: Architecture\n * and Programming Manual)\", but I deviate slightly, mostly by subdividing their groups with letter suffixes:\n *\n * Opcodes Intel PCx86 PC Mag TechRef\n * ------- ----- ---- --------------\n * 0x80-0x83 Grp1 Grp1b and Grp1w Group A\n * 0xC0-0xC1 Grp2 Grp2b and Grp2w (opGRP2bn/wn) Group B\n * 0xD0-0xD3 Grp2 Grp2b and Grp2w (opGRP2b1/w1 and opGRP2bCL/wCL) Group B\n * 0xF6-0xF7 Grp3 Grp3b and Grp3w Group C\n * 0xFE Grp4 Grp4b Group D\n * 0xFF Grp5 Grp4w Group E\n * 0x0F,0x00 Grp6 Grp6 (SLDT, STR, LLDT, LTR, VERR, VERW) Group F\n * 0x0F,0x01 Grp7 Grp7 (SGDT, SIDT, LGDT, LIDT, SMSW, LMSW, INVLPG) Group G\n * 0x0F,0xBA Grp8 Grp8 (BT, BTS, BTR, BTC) Group H\n * 0x0F,0xC7 Grp9 Grp9 (CMPXCH) (N/A, 80486 and up)\n *\n * My only serious deviation is Grp5, which I refer to as Grp4w, because it contains word forms of\n * the INC and DEC instructions found in Grp4b. Granted, Grp4w also contains versions of the CALL,\n * JMP and PUSH instructions, which are not in Grp4b, but there's nothing in Grp4b that conflicts with\n * Grp4w, so I think my nomenclature makes more sense. To compensate, I don't use Grp5, so that the\n * remaining group numbers remain in sync with Intel's.\n *\n * To the above list, I've added a few \"single-serving\" groups: opcode 0x8F uses GrpPOPw, and opcodes 0xC6/0xC7\n * use GrpMOVn. In both of these groups, the only valid (documented) instruction is where reg=0x0.\n *\n * TODO: Test what happens on real hardware when the reg field is non-zero for opcodes 0x8F and 0xC6/0xC7.\n */\nX86.aOpGrp1b = [\n X86.fnADDb, X86.fnORb, X86.fnADCb, X86.fnSBBb, // 0x80/0x82(reg=0x0-0x3)\n X86.fnANDb, X86.fnSUBb, X86.fnXORb, X86.fnCMPb // 0x80/0x82(reg=0x4-0x7)\n];\n\nX86.aOpGrp1w = [\n X86.fnADDw, X86.fnORw, X86.fnADCw, X86.fnSBBw, // 0x81/0x83(reg=0x0-0x3)\n X86.fnANDw, X86.fnSUBw, X86.fnXORw, X86.fnCMPw // 0x81/0x83(reg=0x4-0x7)\n];\n\nX86.aOpGrpPOPw = [\n X86.fnPOPw, X86.fnGRPFault, X86.fnGRPFault, X86.fnGRPFault, // 0x8F(reg=0x0-0x3)\n X86.fnGRPFault, X86.fnGRPFault, X86.fnGRPFault, X86.fnGRPFault // 0x8F(reg=0x4-0x7)\n];\n\nX86.aOpGrpMOVn = [\n X86.fnMOVn, X86.fnGRPUndefined, X86.fnGRPUndefined, X86.fnGRPUndefined, // 0xC6/0xC7(reg=0x0-0x3)\n X86.fnGRPUndefined, X86.fnGRPUndefined, X86.fnGRPUndefined, X86.fnGRPUndefined // 0xC6/0xC7(reg=0x4-0x7)\n];\n\nX86.aOpGrp2b = [\n X86.fnROLb, X86.fnRORb, X86.fnRCLb, X86.fnRCRb, // 0xC0/0xD0/0xD2(reg=0x0-0x3)\n X86.fnSHLb, X86.fnSHRb, X86.fnGRPUndefined, X86.fnSARb // 0xC0/0xD0/0xD2(reg=0x4-0x7)\n];\n\nX86.aOpGrp2w = [\n X86.fnROLw, X86.fnRORw, X86.fnRCLw, X86.fnRCRw, // 0xC1/0xD1/0xD3(reg=0x0-0x3)\n X86.fnSHLw, X86.fnSHRw, X86.fnGRPUndefined, X86.fnSARw // 0xC1/0xD1/0xD3(reg=0x4-0x7)\n];\n\nX86.aOpGrp2d = [\n X86.fnROLd, X86.fnRORd, X86.fnRCLd, X86.fnRCRd, // 0xC1/0xD1/0xD3(reg=0x0-0x3)\n X86.fnSHLd, X86.fnSHRd, X86.fnGRPUndefined, X86.fnSARd // 0xC1/0xD1/0xD3(reg=0x4-0x7)\n];\n\nX86.aOpGrp3b = [\n X86.fnTESTib, X86.fnGRPUndefined, X86.fnNOTb, X86.fnNEGb, // 0xF6(reg=0x0-0x3)\n X86.fnMULb, X86.fnIMULb, X86.fnDIVb, X86.fnIDIVb // 0xF6(reg=0x4-0x7)\n];\n\nX86.aOpGrp3w = [\n X86.fnTESTiw, X86.fnGRPUndefined, X86.fnNOTw, X86.fnNEGw, // 0xF7(reg=0x0-0x3)\n X86.fnMULw, X86.fnIMULw, X86.fnDIVw, X86.fnIDIVw // 0xF7(reg=0x4-0x7)\n];\n\nX86.aOpGrp4b = [\n X86.fnINCb, X86.fnDECb, X86.fnGRPUndefined, X86.fnGRPUndefined, // 0xFE(reg=0x0-0x3)\n X86.fnGRPUndefined, X86.fnGRPUndefined, X86.fnGRPUndefined, X86.fnGRPUndefined // 0xFE(reg=0x4-0x7)\n];\n\nX86.aOpGrp4w = [\n X86.fnINCw, X86.fnDECw, X86.fnCALLw, X86.fnCALLFdw, // 0xFF(reg=0x0-0x3)\n X86.fnJMPw, X86.fnJMPFdw, X86.fnPUSHw, X86.fnGRPUndefined // 0xFF(reg=0x4-0x7)\n];\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/x86op0f.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * op=0x0F,0x00 (GRP6 mem/reg)\n *\n * @this {CPUX86}\n */\nX86.opGRP6 = function()\n{\n var bModRM = this.peekIPByte();\n if ((bModRM & 0x38) < 0x10) { // possible reg values: 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38\n this.opFlags |= X86.OPFLAG.NOREAD;\n }\n this.decodeModGrpWord.call(this, this.aOpGrp6, X86.helpSRCNone);\n};\n\n/**\n * op=0x0F,0x01 (GRP7 mem/reg)\n *\n * @this {CPUX86}\n */\nX86.opGRP7 = function()\n{\n var bModRM = this.peekIPByte();\n if (!(bModRM & 0x10)) {\n this.opFlags |= X86.OPFLAG.NOREAD;\n }\n this.decodeModGrpWord.call(this, X86.aOpGrp7, X86.helpSRCNone);\n};\n\n/**\n * opLAR()\n *\n * op=0x0F,0x02 (LAR reg,mem/reg)\n *\n * @this {CPUX86}\n */\nX86.opLAR = function()\n{\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to real-mode or V86-mode.\n */\n if (!(this.regCR0 & X86.CR0.MSW.PE) || I386 && (this.regPS & X86.PS.VM)) {\n X86.opInvalid.call(this);\n return;\n }\n this.decodeModRegWord.call(this, X86.fnLAR);\n};\n\n/**\n * opLSL()\n *\n * op=0x0F,0x03 (LSL reg,mem/reg)\n *\n * @this {CPUX86}\n */\nX86.opLSL = function()\n{\n /*\n * TODO: Consider swapping out this function whenever setProtMode() changes the mode to real-mode or V86-mode.\n */\n if (!(this.regCR0 & X86.CR0.MSW.PE) || I386 && (this.regPS & X86.PS.VM)) {\n X86.opInvalid.call(this);\n return;\n }\n this.decodeModRegWord.call(this, X86.fnLSL);\n};\n\n/**\n * opLOADALL286()\n *\n * op=0x0F,0x05 (LOADALL)\n *\n * From the \"Undocumented iAPX 286 Test Instruction\" document at http://www.pcjs.org/pubs/pc/reference/intel/80286/loadall/:\n *\n * Physical Address (Hex) Associated CPU Register\n * 800-805 None\n * 806-807 MSW\n * 808-815 None\n * 816-817 TR\n * 818-819 Flag word\n * 81A-81B IP\n * 81C-81D LDT\n * 81E-81F DS\n * 820-821 SS\n * 822-823 CS\n * 824-825 ES\n * 826-827 DI\n * 828-829 SI\n * 82A-82B BP\n * 82C-82D SP\n * 82E-82F BX\n * 830-831 DX\n * 832-833 CX\n * 834-835 AX\n * 836-83B ES descriptor cache\n * 83C-841 CS descriptor cache\n * 842-847 SS descriptor cache\n * 848-84D DS descriptor cache\n * 84E-853 GDTR\n * 854-859 LDT descriptor cache\n * 85A-85F IDTR\n * 860-865 TSS descriptor cache\n *\n * @this {CPUX86}\n */\nX86.opLOADALL286 = function()\n{\n if (this.nCPL) {\n /*\n * To use LOADALL, CPL must be zero.\n */\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0, 0, true);\n return;\n }\n this.setMSW(this.getShort(0x806));\n this.regEDI = this.getShort(0x826);\n this.regESI = this.getShort(0x828);\n this.regEBP = this.getShort(0x82A);\n this.regEBX = this.getShort(0x82E);\n this.regEDX = this.getShort(0x830);\n this.regECX = this.getShort(0x832);\n this.regEAX = this.getShort(0x834);\n this.segES.loadDesc6(0x836, this.getShort(0x824));\n this.segCS.loadDesc6(0x83C, this.getShort(0x822));\n this.segSS.loadDesc6(0x842, this.getShort(0x820));\n this.segDS.loadDesc6(0x848, this.getShort(0x81E));\n /*\n * Unlike LOADALL386, there's no requirement for calling setPS() before loading segment registers;\n * in fact, since we're not passing a CPL to setPS(), it may be preferable to have CS (and perhaps SS)\n * already loaded, so that setPS() can query the CPL. TODO: Verify that CPL is set correctly.\n */\n this.setPS(this.getShort(0x818));\n /*\n * It's important to call setIP() and setSP() *after* the segCS and segSS loads, so that the CPU's\n * linear IP and SP registers (regLIP and regLSP) will be updated properly. Ordinarily that would be\n * taken care of by simply using the CPU's setCS() and setSS() functions, but those functions call the\n * default descriptor load() functions, and obviously here we must use loadDesc6() instead.\n */\n this.setIP(this.getShort(0x81A));\n this.setSP(this.getShort(0x82C));\n /*\n * The bytes at 0x851 and 0x85D \"should be zeroes\", as per the \"Undocumented iAPX 286 Test Instruction\"\n * document, but the LOADALL issued by RAMDRIVE in PC-DOS 7.0 contains 0xFF in both of those bytes, resulting\n * in very large addrGDT and addrIDT values. Obviously, we can't have that, so we load only the low byte\n * of the second word for both of those registers.\n */\n this.addrGDT = this.getShort(0x84E) | (this.getByte(0x850) << 16);\n this.addrGDTLimit = this.addrGDT + this.getShort(0x852);\n this.addrIDT = this.getShort(0x85A) | (this.getByte(0x85C) << 16);\n this.addrIDTLimit = this.addrIDT + this.getShort(0x85E);\n this.segLDT.loadDesc6(0x854, this.getShort(0x81C));\n this.segTSS.loadDesc6(0x860, this.getShort(0x816));\n\n /*\n * Oddly, the above Intel document gives two contradictory cycle counts for LOADALL: 190 and 195.\n * I'm going with 195, since both the PC Magazine Programmer's Technical Reference and Robert Collins\n * (http://www.rcollins.org/articles/loadall/tspec_a3_doc.html) agree.\n */\n this.nStepCycles -= 195;\n\n /*\n * TODO: LOADALL operation still needs to be verified in protected mode....\n */\n if (DEBUG && DEBUGGER && (this.regCR0 & X86.CR0.MSW.PE)) this.stopCPU();\n};\n\n/**\n * opCLTS()\n *\n * op=0x0F,0x06 (CLTS)\n *\n * @this {CPUX86}\n */\nX86.opCLTS = function()\n{\n /*\n * NOTE: The following code shouldn't need to also test X86.PS.VM, because V86-mode is CPL 3.\n */\n if (this.nCPL) {\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n this.regCR0 &= ~X86.CR0.MSW.TS;\n this.nStepCycles -= 2;\n};\n\n/**\n * opLOADALL386()\n *\n * op=0x0F,0x07 (LOADALL ES:[EDI])\n *\n * Excerpt from Intel Internal Correspondence on \"386 LOADALL Instruction\" (undated), available as part of the\n * PCjs Project at http://www.pcjs.org/pubs/pc/reference/intel/80386/loadall/\n *\n * 1.5. 386 LOADALL Memory Format\n *\n * The following tables define the LOADALL memory format. The LOADALL instruction uses a 512-byte block of\n * memory, where the lowest addressed byte is given in ES:[(E)DI]. The area above offset CC hex is used for\n * processor dependent registers (temporaries, invisible registers). These are loaded into the processor,\n * but will not affect normal program execution. All values in the memory area are read from a four byte field,\n * to keep the memory format DWORD aligned, but it is possible to locate memory area at a non-aligned address.\n * In this case, the execution time of LOADALL will DOUBLE For this reason, the memory dump area should always\n * be DWORD aligned.\n *\n * Offset Register\n * ------ --------\n * 0x00 CR0\n * 0x04 EFLAGS\n * 0x08 EIP\n * 0x0C EDI\n * 0x10 ESI\n * 0x14 EBP\n * 0x18 ESP\n * 0x1C EBX\n * 0x20 EDX\n * 0x24 ECX\n * 0x28 EAX\n * 0x2C DR6\n * 0x30 DR7\n * 0x34 TSSR(TSSSelector-Word)\n * 0x38 LDTR(LDTSelector-Word)\n * 0x3C GS\n * 0x40 FS\n * 0x44 DS\n * 0x48 SS\n * 0x4C CS\n * 0x50 ES\n * 0x54 TSS(AR)\n * 0x58 TSS(BASE)\n * 0x5C TSS(LIMIT)\n * 0x60 IDT(AR)\n * 0x64 IDT(BASE)\n * 0x68 IDT(LIMIT)\n * 0x6C GDT(AR)\n * 0x70 GDT(BASE)\n * 0x74 GDT(LIMIT)\n * 0x78 LDT(AR)\n * 0x7C LDT(BASE)\n * 0x80 LDT(LIMIT)\n * 0x84 GS(AR)\n * 0x88 GS(BASE)\n * 0x8C GS(LIMIT)\n * 0x90 FS(AR)\n * 0x94 FS(BASE)\n * 0x98 FS(LIMIT)\n * 0x9C DS(AR)\n * 0xA0 DS(BASE)\n * 0xA4 DS(LIMIT)\n * 0xA8 SS(AR)\n * 0xAC SS(BASE)\n * 0xB0 SS(LIMIT)\n * 0xB4 CS(AR)\n * 0xB8 CS(BASE)\n * 0xBC CS(LIMIT)\n * 0xC0 ES(AR)\n * 0xC4 ES(BASE)\n * 0xC8 ES(LIMIT)\n *\n * Each descriptor entry consists of 3 pieces:\n *\n * AR\n * BASE\n * LIMIT\n *\n * The AR part has the same format as the second dword of a segment descriptor except that only the AR byte\n * (bits 8-15) and the G and B/D bits (bits 23 and 22) are used. All other bits in the AR field are ignored.\n * The BASE and LIMIT parts contain full 32-bit values, fully expanded and unscrambled from the 386 descriptor.\n * In particular, the LIMIT field loaded for a page granular segment gives a byte granular limit, so should\n * contain the page limit*4096 plus 4095.\n *\n * @this {CPUX86}\n */\nX86.opLOADALL386 = function()\n{\n if (this.nCPL) {\n /*\n * To use LOADALL, CPL must be zero.\n */\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0, 0, true);\n return;\n }\n var addr = this.segES.checkRead(this.regEDI & this.maskAddr, 0xCC);\n if (addr !== X86.ADDR_INVALID) {\n X86.helpLoadCR0.call(this, this.getLong(addr));\n /*\n * We need to call setPS() before loading any segment registers, because if the Virtual 8086 Mode (VM)\n * bit is set in EFLAGS, the segment registers need to know that.\n */\n var accSS = this.getLong(addr + 0xA8);\n var cpl = (accSS & X86.DESC.ACC.DPL.MASK) >> X86.DESC.ACC.DPL.SHIFT;\n this.setPS(this.getLong(addr + 0x04), cpl);\n /*\n * TODO: We have no use for the GDT(AR) at offset 0x6C or the IDT(AR) at offset 0x60, because\n * we don't manage them as segment registers. Should we?\n */\n this.addrGDT = this.getLong(addr + 0x70);\n this.addrGDTLimit = this.addrGDT + this.getLong(addr + 0x74);\n this.addrIDT = this.getLong(addr + 0x64);\n this.addrIDTLimit = this.addrIDT + this.getLong(addr + 0x68);\n this.segLDT.loadDesc(this.getLong(addr + 0x38), this.getLong(addr + 0x78), this.getLong(addr + 0x7C), this.getLong(addr + 0x80));\n this.segTSS.loadDesc(this.getLong(addr + 0x34), this.getLong(addr + 0x54), this.getLong(addr + 0x58), this.getLong(addr + 0x5C));\n this.regEDI = this.getLong(addr + 0x0C);\n this.regESI = this.getLong(addr + 0x10);\n this.regEBP = this.getLong(addr + 0x14);\n this.regEBX = this.getLong(addr + 0x1C);\n this.regEDX = this.getLong(addr + 0x20);\n this.regECX = this.getLong(addr + 0x24);\n this.regEAX = this.getLong(addr + 0x28);\n this.segGS.loadDesc(this.getLong(addr + 0x3C), this.getLong(addr + 0x84), this.getLong(addr + 0x88), this.getLong(addr + 0x8C));\n this.segFS.loadDesc(this.getLong(addr + 0x40), this.getLong(addr + 0x90), this.getLong(addr + 0x94), this.getLong(addr + 0x98));\n this.segDS.loadDesc(this.getLong(addr + 0x44), this.getLong(addr + 0x9C), this.getLong(addr + 0xA0), this.getLong(addr + 0xA4));\n this.segSS.loadDesc(this.getLong(addr + 0x48), accSS, this.getLong(addr + 0xAC), this.getLong(addr + 0xB0));\n this.segCS.loadDesc(this.getLong(addr + 0x4C), this.getLong(addr + 0xB4), this.getLong(addr + 0xB8), this.getLong(addr + 0xBC));\n this.segES.loadDesc(this.getLong(addr + 0x50), this.getLong(addr + 0xC0), this.getLong(addr + 0xC4), this.getLong(addr + 0xC8));\n /*\n * It's important to call setIP() and setSP() *after* the segCS and segSS loads, so that the CPU's\n * linear IP and SP registers (regLIP and regLSP) will be updated properly. Ordinarily that would be\n * taken care of by simply using the CPU's setCS() and setSS() functions, but those functions call the\n * default descriptor load() functions, and obviously here we must use loadDesc() instead.\n */\n this.setIP(this.getLong(addr + 0x08));\n this.setSP(this.getLong(addr + 0x18));\n /*\n * TODO: We need to factor out the code that updates DR6 and DR7 from X86.opMOVdr(), so that we can\n * more easily update DR6 and DR7 (which we're simply ignoring for now).\n */\n }\n\n /*\n * According to Robert Collins (http://www.rcollins.org/articles/loadall/tspec_a3_doc.html), the 80386 LOADALL\n * takes 122 cycles. Also, according the above-mentioned Intel document, if the memory buffer is not DWORD aligned,\n * execution time will DOUBLE.\n */\n this.nStepCycles -= (122 << ((addr & 0x3)? 1 : 0));\n};\n\n/**\n * opMOVrc()\n *\n * op=0x0F,0x20 (MOV reg,ctlreg)\n *\n * NOTE: Since this instruction uses only 32-bit general-purpose registers, our ModRM decoders\n * are going to be more hindrance than help, so we fully decode and execute the instruction ourselves.\n *\n * From PCMag_Prog_TechRef, p.476: \"The 80386 executes the MOV to/from control registers (CRn) regardless\n * of the setting of the MOD field. The MOD field should be set to 11, but an early 80386 documentation\n * error indicated that the MOD field value was a don't care. Early versions of the 80486 detect\n * a MOD != 11 as an illegal opcode. This was changed in later versions to ignore the value of MOD.\n * Assemblers that generate MOD != 11 for these instructions will fail on some 80486s.\"\n *\n * And in fact, the COMPAQ DeskPro 386 ROM BIOS executes this instruction with MOD set to 00, so we have\n * to ignore it.\n *\n * @this {CPUX86}\n */\nX86.opMOVrc = function()\n{\n /*\n * NOTE: The following code shouldn't need to also test X86.PS.VM, because V86-mode is CPL 3.\n */\n if (this.nCPL) {\n /*\n * You're not allowed to read control registers if the current privilege level is not zero.\n */\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n\n var reg;\n var bModRM = this.getIPByte();\n switch((bModRM & 0x38) >> 3) {\n case 0x0:\n reg = this.regCR0;\n break;\n case 0x2:\n reg = this.regCR2;\n break;\n case 0x3:\n reg = this.regCR3;\n break;\n default:\n X86.opUndefined.call(this);\n return;\n }\n\n this.setReg(bModRM & 0x7, reg);\n\n this.nStepCycles -= 6;\n\n /*\n * TODO: Implement BACKTRACK for this instruction (although Control registers are not likely to be a conduit for interesting data).\n */\n};\n\n/**\n * opMOVrd()\n *\n * op=0x0F,0x21 (MOV reg,dbgreg)\n *\n * NOTE: Since this instruction uses only 32-bit general-purpose registers, our ModRM decoders\n * are going to be more hindrance than help, so we fully decode and execute the instruction ourselves.\n *\n * @this {CPUX86}\n */\nX86.opMOVrd = function()\n{\n /*\n * NOTE: The following code shouldn't need to also test X86.PS.VM, because V86-mode is CPL 3.\n */\n if (this.nCPL) {\n /*\n * You're not allowed to read control registers if the current privilege level is not zero.\n */\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n\n var bModRM = this.getIPByte();\n var iSrc = (bModRM & 0x38) >> 3;\n\n if (iSrc == 4 || iSrc == 5) {\n X86.opUndefined.call(this);\n return;\n }\n\n this.setReg(bModRM & 0x7, this.regDR[iSrc]);\n\n this.nStepCycles -= 22;\n\n /*\n * TODO: Implement BACKTRACK for this instruction (although Debug registers are not likely to be a conduit for interesting data).\n */\n};\n\n/**\n * opMOVcr()\n *\n * op=0x0F,0x22 (MOV ctlreg,reg)\n *\n * NOTE: Since this instruction uses only 32-bit general-purpose registers, our ModRM decoders\n * are going to be more hindrance than help, so we fully decode and execute the instruction ourselves.\n *\n * From PCMag_Prog_TechRef, p.476: \"The 80386 executes the MOV to/from control registers (CRn) regardless\n * of the setting of the MOD field. The MOD field should be set to 11, but an early 80386 documentation\n * error indicated that the MOD field value was a don't care. Early versions of the 80486 detect\n * a MOD != 11 as an illegal opcode. This was changed in later versions to ignore the value of MOD.\n * Assemblers that generate MOD != 11 for these instructions will fail on some 80486s.\"\n *\n * And in fact, the COMPAQ DeskPro 386 ROM BIOS executes this instruction with MOD set to 00, so we have\n * to ignore it.\n *\n * @this {CPUX86}\n */\nX86.opMOVcr = function()\n{\n /*\n * NOTE: The following code shouldn't need to also test X86.PS.VM, because V86-mode is CPL 3.\n */\n if (this.nCPL) {\n /*\n * You're not allowed to write control registers if the current privilege level is not zero.\n */\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n\n var bModRM = this.getIPByte();\n var reg = this.getReg(bModRM & 0x7);\n\n switch((bModRM & 0x38) >> 3) {\n case 0x0:\n X86.helpLoadCR0.call(this, reg);\n this.nStepCycles -= 10;\n break;\n case 0x2:\n this.regCR2 = reg;\n this.nStepCycles -= 4;\n break;\n case 0x3:\n X86.helpLoadCR3.call(this, reg);\n this.nStepCycles -= 5;\n break;\n default:\n X86.opUndefined.call(this);\n return;\n }\n\n /*\n * TODO: Implement BACKTRACK for this instruction (although Control registers are not likely to be a conduit for interesting data).\n */\n};\n\n/**\n * opMOVdr()\n *\n * op=0x0F,0x23 (MOV dbgreg,reg)\n *\n * NOTE: Since this instruction uses only 32-bit general-purpose registers, our ModRM decoders\n * are going to be more hindrance than help, so we fully decode and execute the instruction ourselves.\n *\n * @this {CPUX86}\n */\nX86.opMOVdr = function()\n{\n /*\n * NOTE: The following code shouldn't need to also test X86.PS.VM, because V86-mode is CPL 3.\n */\n if (this.nCPL) {\n /*\n * You're not allowed to write control registers if the current privilege level is not zero.\n */\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n\n var bModRM = this.getIPByte();\n var iDst = (bModRM & 0x38) >> 3;\n\n if (iDst == 4 || iDst == 5) {\n X86.opUndefined.call(this);\n return;\n }\n\n var regDR = this.getReg(bModRM & 0x7);\n\n if (regDR != this.regDR[iDst]) {\n this.checkDebugRegisters(false);\n this.regDR[iDst] = regDR;\n this.checkDebugRegisters(true);\n }\n\n this.nStepCycles -= (iDst < 4? 22 : 14);\n\n /*\n * TODO: Implement BACKTRACK for this instruction (although Debug registers are not likely to be a conduit for interesting data).\n */\n};\n\n/**\n * opMOVrt()\n *\n * op=0x0F,0x24 (MOV reg,tstreg)\n *\n * NOTE: Since this instruction uses only 32-bit general-purpose registers, our ModRM decoders\n * are going to be more hindrance than help, so we fully decode and execute the instruction ourselves.\n *\n * @this {CPUX86}\n */\nX86.opMOVrt = function()\n{\n /*\n * NOTE: The following code shouldn't need to also test X86.PS.VM, because V86-mode is CPL 3.\n */\n if (this.nCPL) {\n /*\n * You're not allowed to read control registers if the current privilege level is not zero.\n */\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n\n var bModRM = this.getIPByte();\n var iSrc = (bModRM & 0x38) >> 3;\n\n /*\n * Only TR6 and TR7 are defined, and only for the 80386 and 80486. From the PC Magazine Prog. TechRef, p.64:\n *\n * \"The 80386 provides two 32-bit test registers, TR6 and TR7, as a mechanism for programmers to verify proper\n * operation of the Translation Lookaside Buffer (TLB) when power is applied to the chip. The TLB is a cache used\n * internally by the 80386 to translate linear addresses to physical addresses.\"\n */\n if (iSrc < 6) {\n X86.opUndefined.call(this);\n return;\n }\n\n this.setReg(bModRM & 0x7, this.regTR[iSrc]);\n this.nStepCycles -= 12;\n\n /*\n * TODO: Implement BACKTRACK for this instruction (although Test registers are not likely to be a conduit for interesting data).\n */\n};\n\n/**\n * opMOVtr()\n *\n * op=0x0F,0x26 (MOV tstreg,reg)\n *\n * NOTE: Since this instruction uses only 32-bit general-purpose registers, our ModRM decoders\n * are going to be more hindrance than help, so we fully decode and execute the instruction ourselves.\n *\n * @this {CPUX86}\n */\nX86.opMOVtr = function()\n{\n /*\n * NOTE: The following code shouldn't need to also test X86.PS.VM, because V86-mode is CPL 3.\n */\n if (this.nCPL) {\n /*\n * You're not allowed to write control registers if the current privilege level is not zero.\n */\n X86.helpFault.call(this, X86.EXCEPTION.GP_FAULT, 0);\n return;\n }\n\n var bModRM = this.getIPByte();\n var iDst = (bModRM & 0x38) >> 3;\n\n /*\n * Only TR6 and TR7 are defined, and only for the 80386 and 80486. From the PC Magazine Prog. TechRef, p.64:\n *\n * \"The 80386 provides two 32-bit test registers, TR6 and TR7, as a mechanism for programmers to verify proper\n * operation of the Translation Lookaside Buffer (TLB) when power is applied to the chip. The TLB is a cache used\n * internally by the 80386 to translate linear addresses to physical addresses.\"\n */\n if (iDst < 6) {\n X86.opUndefined.call(this);\n return;\n }\n\n /*\n * TODO: Do something useful with the Test registers.\n */\n this.regTR[iDst] = this.getReg(bModRM & 0x7);\n\n this.nStepCycles -= 12;\n\n /*\n * TODO: Implement BACKTRACK for this instruction (although Test registers are not likely to be a conduit for interesting data).\n */\n};\n\n/*\n * NOTE: The following 16 new conditional jumps actually rely on the OPERAND override setting\n * for determining whether a signed 16-bit or 32-bit displacement will be fetched, even though\n * the ADDRESS override might seem more intuitive. Think of them as instructions that are loading\n * a new operand into IP/EIP.\n *\n * Also, in 16-bit code, even though a signed rel16 value would seem to imply a range of -32768\n * to +32767, any location within a 64Kb code segment outside that range can be reached by choosing\n * a displacement in the opposite direction, causing the 16-bit value in EIP to underflow or overflow;\n * any underflow or overflow doesn't matter, because only the low 16 bits of EIP are updated when a\n * 16-bit OPERAND size is in effect.\n *\n * In fact, for 16-bit jumps, it's simpler to always think of rel16 as an UNSIGNED value added to\n * the current EIP, where the result is then truncated to a 16-bit value. This is why we don't have\n * to sign-extend rel16 before adding it to the current EIP.\n */\n\n/**\n * opJOw()\n *\n * op=0x0F,0x80 (JO rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJOw = function()\n{\n var disp = this.getIPWord();\n if (this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJNOw()\n *\n * op=0x0F,0x81 (JNO rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJNOw = function()\n{\n var disp = this.getIPWord();\n if (!this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJCw()\n *\n * op=0x0F,0x82 (JC rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJCw = function()\n{\n var disp = this.getIPWord();\n if (this.getCF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJNCw()\n *\n * op=0x0F,0x83 (JNC rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJNCw = function()\n{\n var disp = this.getIPWord();\n if (!this.getCF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJZw()\n *\n * op=0x0F,0x84 (JZ rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJZw = function()\n{\n var disp = this.getIPWord();\n if (this.getZF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJNZw()\n *\n * op=0x0F,0x85 (JNZ rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJNZw = function()\n{\n var disp = this.getIPWord();\n if (!this.getZF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJBEw()\n *\n * op=0x0F,0x86 (JBE rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJBEw = function()\n{\n var disp = this.getIPWord();\n if (this.getCF() || this.getZF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJNBEw()\n *\n * op=0x0F,0x87 (JNBE rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJNBEw = function()\n{\n var disp = this.getIPWord();\n if (!this.getCF() && !this.getZF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJSw()\n *\n * op=0x0F,0x88 (JS rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJSw = function()\n{\n var disp = this.getIPWord();\n if (this.getSF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJNSw()\n *\n * op=0x0F,0x89 (JNS rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJNSw = function()\n{\n var disp = this.getIPWord();\n if (!this.getSF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJPw()\n *\n * op=0x0F,0x8A (JP rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJPw = function()\n{\n var disp = this.getIPWord();\n if (this.getPF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJNPw()\n *\n * op=0x0F,0x8B (JNP rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJNPw = function()\n{\n var disp = this.getIPWord();\n if (!this.getPF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJLw()\n *\n * op=0x0F,0x8C (JL rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJLw = function()\n{\n var disp = this.getIPWord();\n if (!this.getSF() != !this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJNLw()\n *\n * op=0x0F,0x8D (JNL rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJNLw = function()\n{\n var disp = this.getIPWord();\n if (!this.getSF() == !this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJLEw()\n *\n * op=0x0F,0x8E (JLE rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJLEw = function()\n{\n var disp = this.getIPWord();\n if (this.getZF() || !this.getSF() != !this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opJNLEw()\n *\n * op=0x0F,0x8F (JNLE rel16/rel32)\n *\n * @this {CPUX86}\n */\nX86.opJNLEw = function()\n{\n var disp = this.getIPWord();\n if (!this.getZF() && !this.getSF() == !this.getOF()) {\n this.setIP(this.getIP() + disp);\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpC;\n return;\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesJmpCFall;\n};\n\n/**\n * opSETO()\n *\n * op=0x0F,0x90 (SETO b)\n *\n * @this {CPUX86}\n */\nX86.opSETO = function()\n{\n X86.helpSETcc.call(this, X86.fnSETO);\n};\n\n/**\n * opSETNO()\n *\n * op=0x0F,0x91 (SETNO b)\n *\n * @this {CPUX86}\n */\nX86.opSETNO = function()\n{\n X86.helpSETcc.call(this, X86.fnSETO);\n};\n\n/**\n * opSETC()\n *\n * op=0x0F,0x92 (SETC b)\n *\n * @this {CPUX86}\n */\nX86.opSETC = function()\n{\n X86.helpSETcc.call(this, X86.fnSETC);\n};\n\n/**\n * opSETNC()\n *\n * op=0x0F,0x93 (SETNC b)\n *\n * @this {CPUX86}\n */\nX86.opSETNC = function()\n{\n X86.helpSETcc.call(this, X86.fnSETNC);\n};\n\n/**\n * opSETZ()\n *\n * op=0x0F,0x94 (SETZ b)\n *\n * @this {CPUX86}\n */\nX86.opSETZ = function()\n{\n X86.helpSETcc.call(this, X86.fnSETZ);\n};\n\n/**\n * opSETNZ()\n *\n * op=0x0F,0x95 (SETNZ b)\n *\n * @this {CPUX86}\n */\nX86.opSETNZ = function()\n{\n X86.helpSETcc.call(this, X86.fnSETNZ);\n};\n\n/**\n * opSETBE()\n *\n * op=0x0F,0x96 (SETBE b)\n *\n * @this {CPUX86}\n */\nX86.opSETBE = function()\n{\n X86.helpSETcc.call(this, X86.fnSETBE);\n};\n\n/**\n * opSETNBE()\n *\n * op=0x0F,0x97 (SETNBE b)\n *\n * @this {CPUX86}\n */\nX86.opSETNBE = function()\n{\n X86.helpSETcc.call(this, X86.fnSETNBE);\n};\n\n/**\n * opSETS()\n *\n * op=0x0F,0x98 (SETS b)\n *\n * @this {CPUX86}\n */\nX86.opSETS = function()\n{\n X86.helpSETcc.call(this, X86.fnSETS);\n};\n\n/**\n * opSETNS()\n *\n * op=0x0F,0x99 (SETNS b)\n *\n * @this {CPUX86}\n */\nX86.opSETNS = function()\n{\n X86.helpSETcc.call(this, X86.fnSETNS);\n};\n\n/**\n * opSETP()\n *\n * op=0x0F,0x9A (SETP b)\n *\n * @this {CPUX86}\n */\nX86.opSETP = function()\n{\n X86.helpSETcc.call(this, X86.fnSETP);\n};\n\n/**\n * opSETNP()\n *\n * op=0x0F,0x9B (SETNP b)\n *\n * @this {CPUX86}\n */\nX86.opSETNP = function()\n{\n X86.helpSETcc.call(this, X86.fnSETNP);\n};\n\n/**\n * opSETL()\n *\n * op=0x0F,0x9C (SETL b)\n *\n * @this {CPUX86}\n */\nX86.opSETL = function()\n{\n X86.helpSETcc.call(this, X86.fnSETL);\n};\n\n/**\n * opSETNL()\n *\n * op=0x0F,0x9D (SETNL b)\n *\n * @this {CPUX86}\n */\nX86.opSETNL = function()\n{\n X86.helpSETcc.call(this, X86.fnSETNL);\n};\n\n/**\n * opSETLE()\n *\n * op=0x0F,0x9E (SETLE b)\n *\n * @this {CPUX86}\n */\nX86.opSETLE = function()\n{\n X86.helpSETcc.call(this, X86.fnSETLE);\n};\n\n/**\n * opSETNLE()\n *\n * op=0x0F,0x9F (SETNLE b)\n *\n * @this {CPUX86}\n */\nX86.opSETNLE = function()\n{\n X86.helpSETcc.call(this, X86.fnSETNLE);\n};\n\n/**\n * opPUSHFS()\n *\n * op=0x0F,0xA0 (PUSH FS)\n *\n * @this {CPUX86}\n */\nX86.opPUSHFS = function()\n{\n /*\n * When the OPERAND size is 32 bits, the 80386 will decrement the stack pointer by 4, write the selector\n * into the 2 lower bytes, and leave the 2 upper bytes untouched; to properly emulate that, we must use the\n * more generic pushData() instead of pushWord().\n */\n if (!I386) {\n this.pushWord(this.segFS.sel);\n } else {\n this.pushData(this.segFS.sel, this.sizeData, 2);\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushSeg;\n};\n\n/**\n * opPOPFS()\n *\n * op=0x0F,0xA1 (POP FS)\n *\n * @this {CPUX86}\n */\nX86.opPOPFS = function()\n{\n /*\n * Any operation that modifies the stack before loading a new segment must snapshot regLSP first.\n */\n this.opLSP = this.regLSP;\n this.setFS(this.popWord());\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n this.opLSP = X86.ADDR_INVALID;\n};\n\n/**\n * opBT()\n *\n * op=0x0F,0xA3 (BT mem/reg,reg)\n *\n * @this {CPUX86}\n */\nX86.opBT = function()\n{\n this.decodeModMemWord.call(this, X86.fnBTMem);\n if (this.regEA !== X86.ADDR_INVALID) this.nStepCycles -= 6;\n};\n\n/**\n * opSHLDn()\n *\n * op=0x0F,0xA4 (SHLD mem/reg,reg,imm8)\n *\n * @this {CPUX86}\n */\nX86.opSHLDn = function()\n{\n this.decodeModMemWord.call(this, this.sizeData == 2? X86.fnSHLDwi : X86.fnSHLDdi);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 7);\n};\n\n/**\n * opSHLDcl()\n *\n * op=0x0F,0xA5 (SHLD mem/reg,reg,CL)\n *\n * @this {CPUX86}\n */\nX86.opSHLDcl = function()\n{\n this.decodeModMemWord.call(this, this.sizeData == 2? X86.fnSHLDwCL : X86.fnSHLDdCL);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 7);\n};\n\n/**\n * opXBTS()\n *\n * op=0x0F,0xA6 (XBTS reg,mem/reg,[E]AX,CL)\n *\n * @this {CPUX86}\n */\nX86.opXBTS = function()\n{\n this.decodeModRegWord.call(this, X86.fnXBTS);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 6 : 13);\n};\n\n/**\n * opIBTS()\n *\n * op=0x0F,0xA7 (IBTS mem/reg,[E]AX,CL,reg)\n *\n * @this {CPUX86}\n */\nX86.opIBTS = function()\n{\n this.decodeModMemWord.call(this, X86.fnIBTS);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 12 : 19);\n};\n\n/**\n * opPUSHGS()\n *\n * op=0x0F,0xA8 (PUSH GS)\n *\n * @this {CPUX86}\n */\nX86.opPUSHGS = function()\n{\n /*\n * When the OPERAND size is 32 bits, the 80386 will decrement the stack pointer by 4, write the selector\n * into the 2 lower bytes, and leave the 2 upper bytes untouched; to properly emulate that, we must use the\n * more generic pushData() instead of pushWord().\n */\n if (!I386) {\n this.pushWord(this.segGS.sel);\n } else {\n this.pushData(this.segGS.sel, this.sizeData, 2);\n }\n this.nStepCycles -= this.cycleCounts.nOpCyclesPushSeg;\n};\n\n/**\n * opPOPGS()\n *\n * op=0x0F,0xA9 (POP GS)\n *\n * @this {CPUX86}\n */\nX86.opPOPGS = function()\n{\n /*\n * Any operation that modifies the stack before loading a new segment must snapshot regLSP first.\n */\n this.opLSP = this.regLSP;\n this.setGS(this.popWord());\n this.nStepCycles -= this.cycleCounts.nOpCyclesPopReg;\n this.opLSP = X86.ADDR_INVALID;\n};\n\n/**\n * opBTS()\n *\n * op=0x0F,0xAB (BTC mem/reg,reg)\n *\n * @this {CPUX86}\n */\nX86.opBTS = function()\n{\n this.decodeModMemWord.call(this, X86.fnBTSMem);\n if (this.regEA !== X86.ADDR_INVALID) this.nStepCycles -= 5;\n};\n\n/**\n * opSHRDn()\n *\n * op=0x0F,0xAC (SHRD mem/reg,reg,imm8)\n *\n * @this {CPUX86}\n */\nX86.opSHRDn = function()\n{\n this.decodeModMemWord.call(this, this.sizeData == 2? X86.fnSHRDwi : X86.fnSHRDdi);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 7);\n};\n\n/**\n * opSHRDcl()\n *\n * op=0x0F,0xAD (SHRD mem/reg,reg,CL)\n *\n * @this {CPUX86}\n */\nX86.opSHRDcl = function()\n{\n this.decodeModMemWord.call(this, this.sizeData == 2? X86.fnSHRDwCL : X86.fnSHRDdCL);\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 7);\n};\n\n/**\n * opIMUL()\n *\n * op=0x0F,0xAF (IMUL reg,mem/reg) (80386 and up)\n *\n * @this {CPUX86}\n */\nX86.opIMUL = function()\n{\n this.decodeModRegWord.call(this, this.sizeData == 2? X86.fnIMULrw : X86.fnIMULrd);\n};\n\n/**\n * opLSS()\n *\n * op=0x0F,0xB2 (LSS reg,word)\n *\n * This is like a \"MOV reg,rm\" operation, but it also loads SS from the next word.\n *\n * @this {CPUX86}\n */\nX86.opLSS = function()\n{\n this.decodeModRegWord.call(this, X86.fnLSS);\n};\n\n/**\n * opBTR()\n *\n * op=0x0F,0xB3 (BTC mem/reg,reg) (80386 and up)\n *\n * @this {CPUX86}\n */\nX86.opBTR = function()\n{\n this.decodeModMemWord.call(this, X86.fnBTRMem);\n if (this.regEA !== X86.ADDR_INVALID) this.nStepCycles -= 5;\n};\n\n/**\n * opLFS()\n *\n * op=0x0F,0xB4 (LFS reg,word)\n *\n * This is like a \"MOV reg,rm\" operation, but it also loads FS from the next word.\n *\n * @this {CPUX86}\n */\nX86.opLFS = function()\n{\n this.decodeModRegWord.call(this, X86.fnLFS);\n};\n\n/**\n * opLGS()\n *\n * op=0x0F,0xB5 (LGS reg,word)\n *\n * This is like a \"MOV reg,rm\" operation, but it also loads GS from the next word.\n *\n * @this {CPUX86}\n */\nX86.opLGS = function()\n{\n this.decodeModRegWord.call(this, X86.fnLGS);\n};\n\n/**\n * opMOVZXb()\n *\n * op=0x0F,0xB6 (MOVZX reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opMOVZXb = function()\n{\n this.decodeModRegByte.call(this, X86.fnMOVXb);\n var reg = (this.bModRM >> 3) & 0x7;\n switch(reg) {\n case 0x0:\n this.regEAX = (this.regEAX & ~this.maskData) | (this.regEAX & 0xff);\n break;\n case 0x1:\n this.regECX = (this.regECX & ~this.maskData) | (this.regECX & 0xff);\n break;\n case 0x2:\n this.regEDX = (this.regEDX & ~this.maskData) | (this.regEDX & 0xff);\n break;\n case 0x3:\n this.regEBX = (this.regEBX & ~this.maskData) | (this.regEBX & 0xff);\n break;\n case 0x4:\n this.regESP = (this.regESP & ~this.maskData) | ((this.regEAX >> 8) & 0xff);\n this.regEAX = this.regXX;\n break;\n case 0x5:\n this.regEBP = (this.regEBP & ~this.maskData) | ((this.regECX >> 8) & 0xff);\n this.regECX = this.regXX;\n break;\n case 0x6:\n this.regESI = (this.regESI & ~this.maskData) | ((this.regEDX >> 8) & 0xff);\n this.regEDX = this.regXX;\n break;\n case 0x7:\n this.regEDI = (this.regEDI & ~this.maskData) | ((this.regEBX >> 8) & 0xff);\n this.regEBX = this.regXX;\n break;\n }\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 6);\n};\n\n/**\n * opMOVZXw()\n *\n * op=0x0F,0xB7 (MOVZX reg,word)\n *\n * @this {CPUX86}\n */\nX86.opMOVZXw = function()\n{\n this.setDataSize(2);\n this.decodeModRegWord.call(this, X86.fnMOVXw);\n switch((this.bModRM >> 3) & 0x7) {\n case 0x0:\n this.regEAX = (this.regEAX & 0xffff);\n break;\n case 0x1:\n this.regECX = (this.regECX & 0xffff);\n break;\n case 0x2:\n this.regEDX = (this.regEDX & 0xffff);\n break;\n case 0x3:\n this.regEBX = (this.regEBX & 0xffff);\n break;\n case 0x4:\n this.regESP = (this.regESP & 0xffff);\n break;\n case 0x5:\n this.regEBP = (this.regEBP & 0xffff);\n break;\n case 0x6:\n this.regESI = (this.regESI & 0xffff);\n break;\n case 0x7:\n this.regEDI = (this.regEDI & 0xffff);\n break;\n }\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 6);\n};\n\n/**\n * op=0x0F,0xBA (GRP8 mem/reg) (80386 and up)\n *\n * @this {CPUX86}\n */\nX86.opGRP8 = function()\n{\n this.decodeModGrpWord.call(this, X86.aOpGrp8, this.getIPByte);\n};\n\n/**\n * opBTC()\n *\n * op=0x0F,0xBB (BTC mem/reg,reg)\n *\n * @this {CPUX86}\n */\nX86.opBTC = function()\n{\n this.decodeModMemWord.call(this, X86.fnBTCMem);\n if (this.regEA !== X86.ADDR_INVALID) this.nStepCycles -= 5;\n};\n\n/**\n * opBSF()\n *\n * op=0x0F,0xBC (BSF reg,mem/reg)\n *\n * @this {CPUX86}\n */\nX86.opBSF = function()\n{\n this.decodeModRegWord.call(this, X86.fnBSF);\n};\n\n/**\n * opBSR()\n *\n * op=0x0F,0xBD (BSR reg,mem/reg)\n *\n * @this {CPUX86}\n */\nX86.opBSR = function()\n{\n this.decodeModRegWord.call(this, X86.fnBSR);\n};\n\n/**\n * opMOVSXb()\n *\n * op=0x0F,0xBE (MOVSX reg,byte)\n *\n * @this {CPUX86}\n */\nX86.opMOVSXb = function()\n{\n this.decodeModRegByte.call(this, X86.fnMOVXb);\n var reg = (this.bModRM >> 3) & 0x7;\n switch(reg) {\n case 0x0:\n this.regEAX = (this.regEAX & ~this.maskData) | ((((this.regEAX & 0xff) << 24) >> 24) & this.maskData);\n break;\n case 0x1:\n this.regECX = (this.regECX & ~this.maskData) | ((((this.regECX & 0xff) << 24) >> 24) & this.maskData);\n break;\n case 0x2:\n this.regEDX = (this.regEDX & ~this.maskData) | ((((this.regEDX & 0xff) << 24) >> 24) & this.maskData);\n break;\n case 0x3:\n this.regEBX = (this.regEBX & ~this.maskData) | ((((this.regEBX & 0xff) << 24) >> 24) & this.maskData);\n break;\n case 0x4:\n this.regESP = (this.regESP & ~this.maskData) | (((this.regEAX << 16) >> 24) & this.maskData);\n this.regEAX = this.regXX;\n break;\n case 0x5:\n this.regEBP = (this.regEBP & ~this.maskData) | (((this.regECX << 16) >> 24) & this.maskData);\n this.regECX = this.regXX;\n break;\n case 0x6:\n this.regESI = (this.regESI & ~this.maskData) | (((this.regEDX << 16) >> 24) & this.maskData);\n this.regEDX = this.regXX;\n break;\n case 0x7:\n this.regEDI = (this.regEDI & ~this.maskData) | (((this.regEBX << 16) >> 24) & this.maskData);\n this.regEBX = this.regXX;\n break;\n }\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 6);\n};\n\n/**\n * opMOVSXw()\n *\n * op=0x0F,0xBF (MOVSX reg,word)\n *\n * @this {CPUX86}\n */\nX86.opMOVSXw = function()\n{\n this.setDataSize(2);\n this.decodeModRegWord.call(this, X86.fnMOVXw);\n switch((this.bModRM >> 3) & 0x7) {\n case 0x0:\n this.regEAX = ((this.regEAX << 16) >> 16);\n break;\n case 0x1:\n this.regECX = ((this.regECX << 16) >> 16);\n break;\n case 0x2:\n this.regEDX = ((this.regEDX << 16) >> 16);\n break;\n case 0x3:\n this.regEBX = ((this.regEBX << 16) >> 16);\n break;\n case 0x4:\n this.regESP = ((this.regESP << 16) >> 16);\n break;\n case 0x5:\n this.regEBP = ((this.regEBP << 16) >> 16);\n break;\n case 0x6:\n this.regESI = ((this.regESI << 16) >> 16);\n break;\n case 0x7:\n this.regEDI = ((this.regEDI << 16) >> 16);\n break;\n }\n this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 6);\n};\n\nX86.aOps0F = new Array(256);\n\nX86.aOps0F[0x00] = X86.opGRP6;\nX86.aOps0F[0x01] = X86.opGRP7;\nX86.aOps0F[0x02] = X86.opLAR;\nX86.aOps0F[0x03] = X86.opLSL;\nX86.aOps0F[0x05] = X86.opLOADALL286;\nX86.aOps0F[0x06] = X86.opCLTS;\n\n/*\n * On all processors (except the 8086/8088, of course), X86.OPCODE.UD2 (0x0F,0x0B), aka \"UD2\", is an\n * instruction guaranteed to raise a #UD (Invalid Opcode) exception (INT 0x06) on all post-8086 processors.\n */\nX86.aOps0F[0x0B] = X86.opInvalid;\n\n/*\n * The following 0x0F opcodes are of no consequence to us, since they were all introduced post-80386;\n * 0x0F,0xA6 and 0x0F,0xA7 were introduced on some 80486 processors (and then deprecated), while 0x0F,0xB0\n * and 0x0F,0xB1 were introduced on 80586 (aka Pentium) processors.\n *\n * CMPXCHG r/m8,reg8 ; 0F B0 /r [PENT]\n * CMPXCHG r/m16,reg16 ; o16 0F B1 /r [PENT]\n * CMPXCHG r/m32,reg32 ; o32 0F B1 /r [PENT]\n * CMPXCHG486 r/m8,reg8 ; 0F A6 /r [486,UNDOC]\n * CMPXCHG486 r/m16,reg16 ; o16 0F A7 /r [486,UNDOC]\n * CMPXCHG486 r/m32,reg32 ; o32 0F A7 /r [486,UNDOC]\n *\n * So why are we even mentioning them here? Only because some software (eg, Windows 3.00) attempts to execute\n * 0x0F,0xA6, so we need to explicitly mark it as invalid. TODO: Purely out of curiosity, I would like to\n * eventually learn *why* Windows 3.00 does this; is it hoping to use the CMPXCHG486 opcode, or is it performing\n * a CPU/stepping check to detect/work-around some errata, or....?\n */\nX86.aOps0F[0xA6] = X86.opInvalid;\n\n/*\n * When Windows 95 Setup initializes in protected-mode, it sets a DPMI exception handler for UD_FAULT and\n * then attempts to generate that exception with undefined opcode 0x0F,0xFF. Apparently, whoever wrote that code\n * didn't get the Intel memo regarding the preferred invalid opcode (0x0F,0x0B, aka UD2), or perhaps Intel hadn't\n * written that memo yet -- although if that's the case, then Intel should have followed Microsoft's lead and\n * selected 0x0F,0xFF instead of 0x0F,0x0B.\n *\n * In any case, this means we need to explicitly set the handler for that opcode to opInvalid(), too.\n */\nX86.aOps0F[0xFF] = X86.opInvalid;\n\n/*\n * NOTE: Any other opcode slots NOT explicitly initialized above with either a dedicated function OR opInvalid()\n * will be set to opUndefined() when initProcessor() finalizes the opcode tables. If the processor is an 80386,\n * initProcessor() will also incorporate all the handlers listed below in aOps0F386.\n *\n * A call to opUndefined() implies something serious has occurred that merits our attention (eg, perhaps someone\n * is using an undocumented opcode that we haven't implemented yet), whereas a call to opInvalid() may or may not.\n */\n\nif (I386) {\n X86.aOps0F386 = [];\n X86.aOps0F386[0x05] = X86.opInvalid; // the 80286 LOADALL opcode (LOADALL286) is invalid on the 80386\n X86.aOps0F386[0x07] = X86.opLOADALL386;\n X86.aOps0F386[0x10] = X86.opMOVmb; // see the undocumented [UMOV](/docs/x86/ops/UMOV/) instruction\n X86.aOps0F386[0x11] = X86.opMOVmw; // see the undocumented [UMOV](/docs/x86/ops/UMOV/) instruction\n X86.aOps0F386[0x12] = X86.opMOVrb; // see the undocumented [UMOV](/docs/x86/ops/UMOV/) instruction\n X86.aOps0F386[0x13] = X86.opMOVrw; // see the undocumented [UMOV](/docs/x86/ops/UMOV/) instruction\n X86.aOps0F386[0x20] = X86.opMOVrc;\n X86.aOps0F386[0x21] = X86.opMOVrd;\n X86.aOps0F386[0x22] = X86.opMOVcr;\n X86.aOps0F386[0x23] = X86.opMOVdr;\n X86.aOps0F386[0x24] = X86.opMOVrt;\n X86.aOps0F386[0x26] = X86.opMOVtr;\n X86.aOps0F386[0x80] = X86.opJOw;\n X86.aOps0F386[0x81] = X86.opJNOw;\n X86.aOps0F386[0x82] = X86.opJCw;\n X86.aOps0F386[0x83] = X86.opJNCw;\n X86.aOps0F386[0x84] = X86.opJZw;\n X86.aOps0F386[0x85] = X86.opJNZw;\n X86.aOps0F386[0x86] = X86.opJBEw;\n X86.aOps0F386[0x87] = X86.opJNBEw;\n X86.aOps0F386[0x88] = X86.opJSw;\n X86.aOps0F386[0x89] = X86.opJNSw;\n X86.aOps0F386[0x8A] = X86.opJPw;\n X86.aOps0F386[0x8B] = X86.opJNPw;\n X86.aOps0F386[0x8C] = X86.opJLw;\n X86.aOps0F386[0x8D] = X86.opJNLw;\n X86.aOps0F386[0x8E] = X86.opJLEw;\n X86.aOps0F386[0x8F] = X86.opJNLEw;\n X86.aOps0F386[0x90] = X86.opSETO;\n X86.aOps0F386[0x91] = X86.opSETNO;\n X86.aOps0F386[0x92] = X86.opSETC;\n X86.aOps0F386[0x93] = X86.opSETNC;\n X86.aOps0F386[0x94] = X86.opSETZ;\n X86.aOps0F386[0x95] = X86.opSETNZ;\n X86.aOps0F386[0x96] = X86.opSETBE;\n X86.aOps0F386[0x97] = X86.opSETNBE;\n X86.aOps0F386[0x98] = X86.opSETS;\n X86.aOps0F386[0x99] = X86.opSETNS;\n X86.aOps0F386[0x9A] = X86.opSETP;\n X86.aOps0F386[0x9B] = X86.opSETNP;\n X86.aOps0F386[0x9C] = X86.opSETL;\n X86.aOps0F386[0x9D] = X86.opSETNL;\n X86.aOps0F386[0x9E] = X86.opSETLE;\n X86.aOps0F386[0x9F] = X86.opSETNLE;\n X86.aOps0F386[0xA0] = X86.opPUSHFS;\n X86.aOps0F386[0xA1] = X86.opPOPFS;\n X86.aOps0F386[0xA3] = X86.opBT;\n X86.aOps0F386[0xA4] = X86.opSHLDn;\n X86.aOps0F386[0xA5] = X86.opSHLDcl;\n X86.aOps0F386[0xA8] = X86.opPUSHGS;\n X86.aOps0F386[0xA9] = X86.opPOPGS;\n X86.aOps0F386[0xAB] = X86.opBTS;\n X86.aOps0F386[0xAC] = X86.opSHRDn;\n X86.aOps0F386[0xAD] = X86.opSHRDcl;\n X86.aOps0F386[0xAF] = X86.opIMUL;\n X86.aOps0F386[0xB2] = X86.opLSS;\n X86.aOps0F386[0xB3] = X86.opBTR;\n X86.aOps0F386[0xB4] = X86.opLFS;\n X86.aOps0F386[0xB5] = X86.opLGS;\n X86.aOps0F386[0xB6] = X86.opMOVZXb;\n X86.aOps0F386[0xB7] = X86.opMOVZXw;\n X86.aOps0F386[0xBA] = X86.opGRP8;\n X86.aOps0F386[0xBB] = X86.opBTC;\n X86.aOps0F386[0xBC] = X86.opBSF;\n X86.aOps0F386[0xBD] = X86.opBSR;\n X86.aOps0F386[0xBE] = X86.opMOVSXb;\n X86.aOps0F386[0xBF] = X86.opMOVSXw;\n}\n\n/*\n * These instruction groups are not as orthogonal as the original 8086/8088 groups (Grp1 through Grp4); some of\n * the instructions in Grp6 and Grp7 only read their dst operand (eg, LLDT), which means the ModRM helper function\n * must insure that setEAWord() is disabled, while others only write their dst operand (eg, SLDT), which means that\n * getEAWord() should be disabled *prior* to calling the ModRM helper function. This latter case requires that\n * we decode the reg field of the ModRM byte before dispatching.\n */\nX86.aOpGrp6Prot = [\n X86.fnSLDT, X86.fnSTR, X86.fnLLDT, X86.fnLTR, // 0x0F,0x00(reg=0x0-0x3)\n X86.fnVERR, X86.fnVERW, X86.fnGRPUndefined, X86.fnGRPUndefined // 0x0F,0x00(reg=0x4-0x7)\n];\n\nX86.aOpGrp6Real = [\n X86.fnGRPInvalid, X86.fnGRPInvalid, X86.fnGRPInvalid, X86.fnGRPInvalid, // 0x0F,0x00(reg=0x0-0x3)\n X86.fnGRPInvalid, X86.fnGRPInvalid, X86.fnGRPUndefined, X86.fnGRPUndefined // 0x0F,0x00(reg=0x4-0x7)\n];\n\n/*\n * Unlike Grp6, Grp7 and Grp8 do not require separate real-mode and protected-mode dispatch tables, because\n * all Grp7 and Grp8 instructions are valid in both modes.\n */\nX86.aOpGrp7 = [\n X86.fnSGDT, X86.fnSIDT, X86.fnLGDT, X86.fnLIDT, // 0x0F,0x01(reg=0x0-0x3)\n X86.fnSMSW, X86.fnGRPUndefined, X86.fnLMSW, X86.fnGRPUndefined // 0x0F,0x01(reg=0x4-0x7)\n];\n\nX86.aOpGrp8 = [\n X86.fnGRPUndefined, X86.fnGRPUndefined, X86.fnGRPUndefined, X86.fnGRPUndefined, // 0x0F,0xBA(reg=0x0-0x3)\n X86.fnBT, X86.fnBTS, X86.fnBTR, X86.fnBTC // 0x0F,0xBA(reg=0x4-0x7)\n];\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/chipset.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * class ChipSet\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass ChipSet extends Component {\n /**\n * ChipSet(parmsChipSet)\n *\n * The ChipSet component has the following component-specific (parmsChipSet) properties:\n *\n * model: eg, \"5150\", \"5160\", \"5170\", \"deskpro386\" (should be a member of ChipSet.MODELS)\n * sw1: 8-character binary string representing the SW1 DIP switches (SW1[1-8]); see Switches Overview\n * sw2: 8-character binary string representing the SW2 DIP switches (SW2[1-8]) (MODEL_5150 only)\n * sound: true (or non-zero) to enable sounds (default), false (or 0) to disable; number used as initial volume\n * scaleTimers: true to divide timer cycle counts by the CPU's cycle multiplier (default is false)\n * floppies: array of floppy drive sizes in Kb (default is \"[360, 360]\" if no sw1 value provided)\n * monitor: none|tv|color|mono|ega|vga (if no sw1 value provided, default is \"ega\" for 5170, \"mono\" otherwise)\n * dateRTC: optional RTC date/time (in GMT) to use on reset; use the ISO 8601 format; eg: \"2014-10-01T08:00:00\"\n *\n * TODO: As support for IBM-compatible machines grows, we should refrain from adding new model strings (eg, \"att6300\")\n * and corresponding model checks, and instead add more ChipSet configuration properties, such as:\n *\n * portPIT1: 0x48 to enable PIT1 at base port 0x48 (as used by COMPAQ_DESKPRO386); default to undefined\n * chipKBD: 8041 to select 8041 emulation (eg, for ATT_6300); default to 8255 for MODEL_5150/MODEL_5160, 8042 for MODEL_5170\n *\n * @this {ChipSet}\n * @param {Object} parmsChipSet\n */\n constructor(parmsChipSet)\n {\n super(\"ChipSet\", parmsChipSet, Messages.CHIPSET);\n\n let model = parmsChipSet['model'];\n\n /*\n * this.model is a numeric version of the 'model' string; when comparing this.model to standard IBM\n * model numbers, you should generally compare (this.model|0) to the target value, which truncates it.\n */\n if (model && !ChipSet.MODELS[model]) {\n Component.notice(\"Unrecognized ChipSet model: \" + model);\n }\n\n this.model = ChipSet.MODELS[model] || ChipSet.MODEL_5150_OTHER;\n\n let bSwitches;\n this.aDIPSwitches = [];\n\n /*\n * SW1 describes the number of floppy drives, the amount of base memory, the primary monitor type,\n * and (on the MODEL_5160) whether or not a coprocessor is installed. If no SW1 settings are provided,\n * we look for individual 'floppies' and 'monitor' settings and build a default SW1 value.\n *\n * The defaults below select max memory, monochrome monitor (EGA monitor for MODEL_5170), and two floppies.\n * Don't get too excited about \"max memory\" either: on a MODEL_5150, the max was 64Kb, and on a MODEL_5160,\n * the max was 256Kb. However, the RAM component is free to install as much base memory as it likes,\n * overriding the SW1 memory setting.\n *\n * Given that the ROM BIOS is hard-coded to load boot sectors @0000:7C00, the minimum amount of system RAM\n * required to boot is therefore 32Kb. Whether that's actually enough to run any or all versions of PC-DOS is\n * a separate question. FYI, with only 16Kb, the ROM BIOS will still try to boot, and fail miserably.\n */\n bSwitches = this.parseDIPSwitches(parmsChipSet[ChipSet.CONTROLS.SW1]);\n this.aDIPSwitches[0] = [bSwitches, bSwitches];\n\n if (bSwitches == null) {\n this.aFloppyDrives = [360, 360];\n let aFloppyDrives = parmsChipSet['floppies'];\n if (aFloppyDrives && aFloppyDrives.length) this.aFloppyDrives = aFloppyDrives;\n this.setDIPSwitches(ChipSet.SWITCH_TYPE.FLOPNUM, this.aFloppyDrives.length);\n\n let sMonitor = parmsChipSet['monitor'] || (this.model < ChipSet.MODEL_5170? \"mono\" : \"ega\");\n this.setDIPSwitches(ChipSet.SWITCH_TYPE.MONITOR, sMonitor);\n }\n\n /*\n * SW2 describes the number of 32Kb blocks of I/O expansion RAM that's present in the system. The MODEL_5150\n * ROM BIOS only checked/supported the first four switches, so the maximum amount of additional RAM specifiable\n * was 15 * 32Kb, or 480Kb. So with a 16Kb-64Kb motherboard, the MODEL_5150 ROM BIOS could support a grand\n * total of 544Kb. With the 64Kb-256Kb motherboard revision, a 5150 could use the first FIVE SW2 switches,\n * allowing for a grand total as high as 640Kb.\n *\n * For MODEL_5160 (PC XT) and up, memory expansion cards had their own switches, and the motherboard\n * SW2 switches for I/O expansion RAM were eliminated. Instead, the ROM BIOS scans the entire address space\n * (up to 0xA0000) looking for additional memory. As a result, the only mechanism we provide for adding RAM\n * (above the maximum of 256Kb supported on the motherboard) is the \"size\" parameter of the RAM component.\n *\n * NOTE: If you use the \"size\" parameter, you will not be able to dynamically alter the memory configuration;\n * the RAM component will ignore any changes to SW1.\n */\n bSwitches = this.parseDIPSwitches(parmsChipSet[ChipSet.CONTROLS.SW2]);\n this.aDIPSwitches[1] = [bSwitches, bSwitches];\n\n this.sCellClass = PCX86.CSSCLASS + \"-bitCell\";\n\n this.cDMACs = this.cPICs = 1;\n if (this.model >= ChipSet.MODEL_5170) {\n this.cDMACs = this.cPICs = 2;\n }\n\n this.fScaleTimers = parmsChipSet['scaleTimers'] || false;\n this.sDateRTC = parmsChipSet['dateRTC'];\n\n /*\n * Here, I'm finally getting around to trying the Web Audio API. Fortunately, based on what little\n * I know about sound generation, using the API to make the same noises as the IBM PC speaker seems\n * straightforward.\n *\n * To start, we create an audio context, unless the 'sound' parameter has been explicitly set to false\n * or 0; the boolean value true (along with any illegal number) now defaults to 0.5 instead of 1.0.\n */\n this.volumeInit = 0;\n let sound = parmsChipSet['sound'];\n if (sound) {\n this.volumeInit = (typeof sound != \"number\" || sound < 0 || sound > 1)? 0.5 : sound;\n this.classAudio = this.contextAudio = null;\n if (window) {\n this.classAudio = window['AudioContext'] || window['webkitAudioContext'];\n }\n if (this.classAudio) {\n this.contextAudio = new this.classAudio();\n } else {\n if (DEBUG) this.log(\"AudioContext not available\");\n }\n }\n /*\n * fSpeakerEnabled indicates whether the speaker is *logically* on, whereas fSpeakerOn indicates\n * whether we have ACTUALLY turned the speaker on. And finally, fUserSound is set to true only after\n * we have have created the audio oscillator in the context of a user event (a requirement for most\n * browsers before they'll actually emit any sound).\n */\n this.fSpeakerEnabled = this.fSpeakerOn = this.fUserSound = false;\n\n /*\n * I used to defer ChipSet's reset() to powerUp(), which then gave us the option of doing either\n * reset() OR restore(), instead of both. However, on MODEL_5170 machines, the initial CMOS data\n * needs to be created earlier, so that when other components are initializing their state (eg, when\n * HDC calls setCMOSDriveType() or RAM calls addCMOSMemory()), the CMOS will be ready to take their calls.\n */\n this.reset(true);\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {ChipSet}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.cmp = cmp;\n\n this.fpu = cmp.getMachineComponent(\"FPU\");\n this.setDIPSwitches(ChipSet.SWITCH_TYPE.FPU, this.fpu? 1 : 0, true);\n\n this.kbd = cmp.getMachineComponent(\"Keyboard\");\n\n let sound = cmp.getMachineParm(\"sound\");\n if (sound != null) {\n let volume = +sound || 0;\n this.volumeInit = (sound == \"true\" || volume < 0 || volume > 1? 0.5 : volume);\n }\n if (!this.volumeInit) this.println(\"note: speaker disabled\");\n\n /*\n * This divisor is invariant, so we calculate it as soon as we're able to query the CPU's base speed.\n */\n this.nTicksDivisor = (cpu.getBaseCyclesPerSecond() / ChipSet.TIMER_TICKS_PER_SEC);\n\n bus.addPortInputTable(this, ChipSet.aPortInput);\n bus.addPortOutputTable(this, ChipSet.aPortOutput);\n if (this.model == ChipSet.MODEL_4860) {\n bus.addPortInputTable(this, ChipSet.aPortInput4860);\n bus.addPortOutputTable(this, ChipSet.aPortOutput4860);\n }\n else {\n bus.addPortInputTable(this, ChipSet.aPortInput5xxx);\n bus.addPortOutputTable(this, ChipSet.aPortOutput5xxx);\n if (this.model < ChipSet.MODEL_5170) {\n if (this.model == ChipSet.MODEL_ATT_6300) {\n bus.addPortInputTable(this, ChipSet.aPortInput6300);\n bus.addPortOutputTable(this, ChipSet.aPortOutput6300);\n } else {\n bus.addPortInputTable(this, ChipSet.aPortInput5150);\n bus.addPortOutputTable(this, ChipSet.aPortOutput5150);\n }\n } else {\n bus.addPortInputTable(this, ChipSet.aPortInput5170);\n bus.addPortOutputTable(this, ChipSet.aPortOutput5170);\n if (DESKPRO386 && (this.model|0) == ChipSet.MODEL_COMPAQ_DESKPRO386) {\n bus.addPortInputTable(this, ChipSet.aPortInputDeskPro386);\n bus.addPortOutputTable(this, ChipSet.aPortOutputDeskPro386);\n }\n }\n }\n if (DEBUGGER) {\n if (dbg) {\n let chipset = this;\n /*\n * TODO: Add more \"dumpers\" (eg, for DMA, RTC, 8042, etc)\n */\n dbg.messageDump(Messages.PIC, function onDumpPIC() {\n chipset.dumpPIC();\n });\n dbg.messageDump(Messages.TIMER, function onDumpTimer(asArgs) {\n chipset.dumpTimer(asArgs);\n });\n if (this.model >= ChipSet.MODEL_5170) {\n dbg.messageDump(Messages.CMOS, function onDumpCMOS() {\n chipset.dumpCMOS();\n });\n }\n }\n cpu.addIntNotify(Interrupts.RTC, this.intBIOSRTC.bind(this));\n }\n this.setReady();\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {ChipSet}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"sw1\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n switch (sBinding) {\n\n case ChipSet.CONTROLS.SW1:\n this.bindings[sBinding] = control;\n this.addDIPSwitches(0, sBinding);\n return true;\n\n case ChipSet.CONTROLS.SW2:\n if ((this.model|0) == ChipSet.MODEL_5150 || this.model == ChipSet.MODEL_ATT_6300) {\n this.bindings[sBinding] = control;\n this.addDIPSwitches(1, sBinding);\n return true;\n }\n break;\n\n case ChipSet.CONTROLS.SWDESC:\n this.bindings[sBinding] = control;\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {ChipSet}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {ChipSet}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset(fHard)\n *\n * @this {ChipSet}\n * @param {boolean} [fHard] true on the initial reset (not a normal \"soft\" reset)\n */\n reset(fHard)\n {\n /*\n * We propagate the initial DIP switch values to the current DIP switch values on reset;\n * the user is only allowed to tweak the initial values, which require a reset to take effect.\n */\n let i;\n this.updateDIPSwitches();\n\n /*\n * DMA (Direct Memory Access) Controller initialization\n */\n this.aDMACs = new Array(this.cDMACs);\n for (i = 0; i < this.cDMACs; i++) {\n this.initDMAController(i);\n }\n\n /*\n * PIC (Programmable Interupt Controller) initialization\n */\n this.aPICs = new Array(this.cPICs);\n this.initPIC(ChipSet.PIC0.INDEX, ChipSet.PIC0.PORT_LO);\n if (this.cPICs > 1) {\n this.initPIC(ChipSet.PIC1.INDEX, ChipSet.PIC1.PORT_LO);\n }\n\n /*\n * PIT (Programmable Interval Timer) initialization\n *\n * Although the DeskPro 386 refers to the timers in the first PIT as \"Timer 1, Counter 0\",\n * \"Timer 1, Counter 1\" and \"Timer 1, Counter 2\", we're sticking with IBM's nomenclature:\n * TIMER0, TIMER1 and TIMER2. Which means that we refer to the \"counters\" in the second PIT\n * as TIMER3, TIMER4 and TIMER5; that numbering also matches their indexes in the aTimers array.\n */\n this.bPIT0Ctrl = null; // tracks writes to port 0x43\n this.bPIT1Ctrl = null; // tracks writes to port 0x4B (MODEL_COMPAQ_DESKPRO386 only)\n this.aTimers = new Array((this.model|0) == ChipSet.MODEL_COMPAQ_DESKPRO386? 6 : 3);\n for (i = 0; i < this.aTimers.length; i++) {\n this.initTimer(i);\n }\n\n /*\n * PPI and other misc ports\n */\n this.bPPIA = null; // tracks writes to port 0x60, in case PPI_CTRL.A_IN is not set\n this.bPPIB = null; // tracks writes to port 0x61, in case PPI_CTRL.B_IN is not set\n this.bPPIC = null; // tracks writes to port 0x62, in case PPI_CTRL.C_IN_LO or PPI_CTRL.C_IN_HI is not set\n this.bPPICtrl = null; // tracks writes to port 0x63 (eg, 0x99); read-only\n this.bNMI = ChipSet.NMI.RESET; // tracks writes to the NMI Mask Register\n this.bKbdData = 0; // records last byte received via receiveKbdData(); for machines without an 8042 (eg, PC/PC XT/PCjr)\n\n if (this.model == ChipSet.MODEL_ATT_6300) {\n this.b8041Status = 0; // similar to b8042Status (but apparently only bits 0 and 1 are used)\n }\n\n /*\n * ChipSet state introduced by the MODEL_5170\n */\n if (this.model >= ChipSet.MODEL_5170) {\n /*\n * The 8042 input buffer is treated as a \"command byte\" when written via port 0x64 and as a \"data byte\"\n * when written via port 0x60. So, whenever the C8042.CMD.WRITE_CMD \"command byte\" is written to the input\n * buffer, the subsequent command data byte is saved in b8042CmdData. Similarly, for C8042.CMD.WRITE_OUTPORT,\n * the subsequent data byte is saved in b8042OutPort.\n *\n * TODO: Consider a UI for the Keyboard INHIBIT switch. By default, our keyboard is never inhibited\n * (ie, locked). Also, note that the hardware changes this bit only when new data is sent to b8042OutBuff.\n */\n this.b8042Status = ChipSet.C8042.STATUS.NO_INHIBIT;\n this.b8042InBuff = 0;\n this.b8042CmdData = ChipSet.C8042.DATA.CMD.NO_CLOCK;\n this.b8042OutBuff = 0;\n\n /*\n * TODO: Provide more control over these 8042 \"Input Port\" bits (eg, the keyboard lock)\n */\n this.b8042InPort = ChipSet.C8042.INPORT.MFG_OFF | ChipSet.C8042.INPORT.KBD_UNLOCKED;\n\n if (this.getDIPMemorySize() >= 512) {\n this.b8042InPort |= ChipSet.C8042.INPORT.ENABLE_256KB;\n }\n\n if (this.getDIPVideoMonitor() == ChipSet.MONITOR.MONO) {\n this.b8042InPort |= ChipSet.C8042.INPORT.MONO;\n }\n\n if (DESKPRO386 && (this.model|0) == ChipSet.MODEL_COMPAQ_DESKPRO386) {\n this.b8042InPort |= ChipSet.C8042.INPORT.COMPAQ_NO80387 | ChipSet.C8042.INPORT.COMPAQ_NOWEITEK;\n }\n\n this.b8042OutPort = ChipSet.C8042.OUTPORT.NO_RESET | ChipSet.C8042.OUTPORT.A20_ON;\n\n this.abDMAPageSpare = new Array(8);\n\n this.bCMOSAddr = 0; // NMI is enabled, since the ChipSet.CMOS.ADDR.NMI_DISABLE bit is not set in bCMOSAddr\n\n /*\n * Now that we call reset() from the ChipSet constructor, enabling other components to update\n * their own CMOS information as needed, we must distinguish between the initial (\"hard\") reset\n * and any later (\"soft\") resets (eg, from powerUp() calls), and make sure the latter preserves\n * existing CMOS information.\n */\n if (fHard) {\n this.abCMOSData = new Array(ChipSet.CMOS.ADDR.TOTAL);\n }\n\n this.initRTCTime(this.sDateRTC);\n\n /*\n * initCMOSData() will initialize a variety of \"legacy\" CMOS bytes, but it will NOT overwrite any memory\n * size or hard drive type information that might have been set, via addCMOSMemory() or setCMOSDriveType().\n */\n this.initCMOSData();\n }\n\n if (DEBUGGER && MAXDEBUG) {\n /*\n * Arrays for interrupt counts (one count per IRQ) and timer data\n */\n this.acInterrupts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n this.acTimersFired = [0, 0, 0];\n this.acTimer0Counts = [];\n }\n }\n\n /**\n * initRTCTime(sDate)\n *\n * Initialize the RTC portion of the CMOS registers to match the specified date/time (or if none is specified,\n * the current date/time). The date/time should be expressed in the ISO 8601 format; eg: \"2011-10-10T14:48:00\".\n *\n * NOTE: There are two approaches we could take here: always store the RTC bytes in binary, and convert them\n * to/from BCD on-demand (ie, as the simulation reads/writes the CMOS RTC registers); or init/update them in the\n * format specified by CMOS.STATUSB.BINARY (1 for binary, 0 for BCD). Both approaches require BCD conversion\n * functions, but the former seems more efficient, in part because the periodic calls to updateRTCTime() won't\n * require any conversions.\n *\n * We take the same approach with the CMOS.STATUSB.HOUR24 setting: internally, we always operate in 24-hour mode,\n * but externally, we convert the RTC hour values to the 12-hour format as needed.\n *\n * Thus, all I/O to the RTC bytes must be routed through the getRTCByte() and setRTCByte() functions, to ensure\n * that all the necessary on-demand conversions occur.\n *\n * @this {ChipSet}\n * @param {string} [sDate]\n */\n initRTCTime(sDate)\n {\n /*\n * NOTE: I've already been burned once by a JavaScript library function that did NOT treat an undefined\n * parameter (ie, a parameter === undefined) the same as an omitted parameter (eg, the async parameter in\n * xmlHTTP.open() in IE), so I'm taking no chances here: if sDate is undefined, then explicitly call Date()\n * with no parameters.\n */\n let date = sDate? new Date(sDate) : new Date();\n\n /*\n * Example of a valid Date string:\n *\n * 2014-10-01T08:00:00 (interpreted as GMT, resulting in \"Wed Oct 01 2014 01:00:00 GMT-0700 (PDT)\")\n *\n * Examples of INVALID Date strings:\n *\n * 2014-10-01T08:00:00PST\n * 2014-10-01T08:00:00-0700 (actually, this DOES work in Chrome, but NOT in Safari)\n *\n * In the case of INVALID Date strings, the Date object is invalid, but there's no obvious test for an \"invalid\"\n * object, so I've adapted the following test from StackOverflow.\n *\n * See http://stackoverflow.com/questions/1353684/detecting-an-invalid-date-date-instance-in-javascript\n */\n if (Object.prototype.toString.call(date) !== \"[object Date]\" || isNaN(date.getTime())) {\n date = new Date();\n this.println(\"CMOS date invalid (\" + sDate + \"), using \" + date);\n } else if (sDate) {\n this.println(\"CMOS date: \" + date);\n }\n\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_SEC] = date.getSeconds();\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_SEC_ALRM] = 0;\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MIN] = date.getMinutes();\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MIN_ALRM] = 0;\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_HOUR] = date.getHours();\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_HOUR_ALRM] = 0;\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_WEEK_DAY] = date.getDay() + 1;\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MONTH_DAY] = date.getDate();\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MONTH] = date.getMonth() + 1;\n let nYear = date.getFullYear();\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_YEAR] = nYear % 100;\n let nCentury = (nYear / 100);\n this.abCMOSData[ChipSet.CMOS.ADDR.CENTURY_DATE] = (nCentury % 10) | ((nCentury / 10) << 4);\n\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSA] = 0x26; // hard-coded default; refer to ChipSet.CMOS.STATUSA.DV and ChipSet.CMOS.STATUSA.RS\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] = ChipSet.CMOS.STATUSB.HOUR24; // default to BCD mode (ChipSet.CMOS.STATUSB.BINARY not set)\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSC] = 0x00;\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSD] = ChipSet.CMOS.STATUSD.VRB;\n\n this.nRTCCyclesLastUpdate = this.nRTCCyclesNextUpdate = 0;\n this.nRTCPeriodsPerSecond = this.nRTCCyclesPerPeriod = null;\n }\n\n /**\n * getRTCByte(iRTC)\n *\n * @param {number} iRTC\n * @return {number} b\n */\n getRTCByte(iRTC)\n {\n\n\n let b = this.abCMOSData[iRTC];\n\n if (iRTC < ChipSet.CMOS.ADDR.STATUSA) {\n let f12HourValue = false;\n if (iRTC == ChipSet.CMOS.ADDR.RTC_HOUR || iRTC == ChipSet.CMOS.ADDR.RTC_HOUR_ALRM) {\n if (!(this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.HOUR24)) {\n if (b < 12) {\n b = (!b? 12 : b);\n } else {\n b -= 12;\n b = (!b? 0x8c : b + 0x80);\n }\n f12HourValue = true;\n }\n }\n if (!(this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.BINARY)) {\n /*\n * We're in BCD mode, so we must convert b from BINARY to BCD. But first:\n *\n * If b is a 12-hour value (ie, we're in 12-hour mode) AND the hour is a PM value\n * (ie, in the range 0x81-0x8C), then it must be adjusted to yield 81-92 in BCD.\n *\n * AM hour values (0x01-0x0C) need no adjustment; they naturally convert to 01-12 in BCD.\n */\n if (f12HourValue && b > 0x80) {\n b -= (0x81 - 81);\n }\n b = (b % 10) | ((b / 10) << 4);\n }\n } else {\n if (iRTC == ChipSet.CMOS.ADDR.STATUSA) {\n /*\n * Make sure that the \"Update-In-Progress\" bit we set in updateRTCTime() doesn't stay set for\n * more than one read.\n */\n this.abCMOSData[iRTC] &= ~ChipSet.CMOS.STATUSA.UIP;\n }\n }\n return b;\n }\n\n /**\n * setRTCByte(iRTC, b)\n *\n * @param {number} iRTC\n * @param {number} b proposed byte to write\n * @return {number} actual byte to write\n */\n setRTCByte(iRTC, b)\n {\n\n\n if (iRTC < ChipSet.CMOS.ADDR.STATUSA) {\n let fBCD = false;\n if (!(this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.BINARY)) {\n /*\n * We're in BCD mode, so we must convert b from BCD to BINARY (we assume it's valid\n * BCD; ie, that both nibbles contain only 0-9, not A-F).\n */\n b = (b >> 4) * 10 + (b & 0xf);\n fBCD = true;\n }\n if (iRTC == ChipSet.CMOS.ADDR.RTC_HOUR || iRTC == ChipSet.CMOS.ADDR.RTC_HOUR_ALRM) {\n if (fBCD) {\n /*\n * If the original BCD hour was 0x81-0x92, then the previous BINARY-to-BCD conversion\n * transformed it to 0x51-0x5C, so we must add 0x30.\n */\n if (b > 23) {\n\n b += 0x30;\n }\n }\n if (!(this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.HOUR24)) {\n if (b <= 12) {\n b = (b == 12? 0 : b);\n } else {\n b -= (0x80 - 12);\n b = (b == 24? 12 : b);\n }\n }\n }\n }\n return b;\n }\n\n /**\n * calcRTCCyclePeriod()\n *\n * This should be called whenever the timings in STATUSA may have changed.\n *\n * TODO: 1024 is a hard-coded number of periods per second based on the default interrupt rate of 976.562us\n * (ie, 1000000 / 976.562). Calculate the actual number based on the values programmed in the STATUSA register.\n *\n * @this {ChipSet}\n */\n calcRTCCyclePeriod()\n {\n this.nRTCCyclesLastUpdate = this.cpu.getCycles(this.fScaleTimers);\n this.nRTCPeriodsPerSecond = 1024;\n this.nRTCCyclesPerPeriod = Math.floor(this.cpu.getBaseCyclesPerSecond() / this.nRTCPeriodsPerSecond);\n this.setRTCCycleLimit();\n }\n\n /**\n * getRTCCycleLimit(nCycles)\n *\n * This is called by the CPU to determine the maximum number of cycles it can process for the current burst.\n *\n * @this {ChipSet}\n * @param {number} nCycles desired\n * @return {number} maximum number of cycles (<= nCycles)\n */\n getRTCCycleLimit(nCycles)\n {\n if (this.abCMOSData && this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.PIE) {\n let nCyclesUpdate = this.nRTCCyclesNextUpdate - this.cpu.getCycles(this.fScaleTimers);\n if (nCyclesUpdate > 0) {\n if (nCycles > nCyclesUpdate) {\n if (DEBUG && this.messageEnabled(Messages.RTC)) {\n this.printMessage(\"getRTCCycleLimit(\" + nCycles + \"): reduced to \" + nCyclesUpdate + \" cycles\", true);\n }\n nCycles = nCyclesUpdate;\n } else {\n if (DEBUG && this.messageEnabled(Messages.RTC)) {\n this.printMessage(\"getRTCCycleLimit(\" + nCycles + \"): already less than \" + nCyclesUpdate + \" cycles\", true);\n }\n }\n } else {\n if (DEBUG && this.messageEnabled(Messages.RTC)) {\n this.printMessage(\"RTC next update has passed by \" + nCyclesUpdate + \" cycles\", true);\n }\n }\n }\n return nCycles;\n }\n\n /**\n * setRTCCycleLimit()\n *\n * This should be called when PIE becomes set in STATUSB (and whenever PF is cleared in STATUSC while PIE is still set).\n *\n * @this {ChipSet}\n */\n setRTCCycleLimit()\n {\n let nCycles = this.nRTCCyclesPerPeriod;\n this.nRTCCyclesNextUpdate = this.cpu.getCycles(this.fScaleTimers) + nCycles;\n if (this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.PIE) {\n this.cpu.setBurstCycles(nCycles);\n }\n }\n\n /**\n * updateRTCTime()\n *\n * @this {ChipSet}\n */\n updateRTCTime()\n {\n let nCyclesPerSecond = this.cpu.getBaseCyclesPerSecond();\n let nCyclesUpdate = this.cpu.getCycles(this.fScaleTimers);\n\n /*\n * We must arrange for the very first calcRTCCyclePeriod() call to occur here, on the very first\n * updateRTCTime() call, because this is the first point we can be guaranteed that CPU cycle counts\n * are initialized (the CPU is the last component to be powered up/restored).\n *\n * TODO: A side-effect of this is that it undermines the save/restore code's preservation of last\n * and next RTC cycle counts, which may affect when the next RTC event is delivered.\n */\n if (this.nRTCCyclesPerPeriod == null) this.calcRTCCyclePeriod();\n\n /*\n * Step 1: Deal with Periodic Interrupts\n */\n if (nCyclesUpdate >= this.nRTCCyclesNextUpdate) {\n let bPrev = this.abCMOSData[ChipSet.CMOS.ADDR.STATUSC];\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSC] |= ChipSet.CMOS.STATUSC.PF;\n if (this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.PIE) {\n /*\n * When PIE is set, setBurstCycles() should be getting called as needed to ensure\n * that updateRTCTime() is called more frequently, so let's assert that we don't have\n * an excess of cycles and thus possibly some missed Periodic Interrupts.\n */\n if (DEBUG) {\n if (nCyclesUpdate - this.nRTCCyclesNextUpdate > this.nRTCCyclesPerPeriod) {\n if (bPrev & ChipSet.CMOS.STATUSC.PF) {\n this.printMessage(\"RTC interrupt handler failed to clear STATUSC\", Messages.RTC);\n } else {\n this.printMessage(\"CPU took too long trigger new RTC periodic interrupt\", Messages.RTC);\n }\n }\n }\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSC] |= ChipSet.CMOS.STATUSC.IRQF;\n this.setIRR(ChipSet.IRQ.RTC);\n /*\n * We could also call setRTCCycleLimit() at this point, but I don't think there's any\n * benefit until the interrupt had been acknowledged and STATUSC has been read, thereby\n * clearing the way for another Periodic Interrupt; it seems to me that when STATUSC\n * is read, that's the more appropriate time to call setRTCCycleLimit().\n */\n }\n this.nRTCCyclesNextUpdate = nCyclesUpdate + this.nRTCCyclesPerPeriod;\n }\n\n /*\n * Step 2: Deal with Alarm Interrupts\n */\n if (this.abCMOSData[ChipSet.CMOS.ADDR.RTC_SEC] == this.abCMOSData[ChipSet.CMOS.ADDR.RTC_SEC_ALRM]) {\n if (this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MIN] == this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MIN_ALRM]) {\n if (this.abCMOSData[ChipSet.CMOS.ADDR.RTC_HOUR] == this.abCMOSData[ChipSet.CMOS.ADDR.RTC_HOUR_ALRM]) {\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSC] |= ChipSet.CMOS.STATUSC.AF;\n if (this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.AIE) {\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSC] |= ChipSet.CMOS.STATUSC.IRQF;\n this.setIRR(ChipSet.IRQ.RTC);\n }\n }\n }\n }\n\n /*\n * Step 3: Update the RTC date/time and deal with Update Interrupts\n */\n let nCyclesDelta = nCyclesUpdate - this.nRTCCyclesLastUpdate;\n // DEBUG:\n let nSecondsDelta = Math.floor(nCyclesDelta / nCyclesPerSecond);\n\n /*\n * We trust that updateRTCTime() is being called as part of updateAllTimers(), and is therefore\n * being called often enough to ensure that nSecondsDelta will never be greater than one. In fact,\n * it would always be LESS than one if it weren't also for the fact that we plow any \"unused\" cycles\n * (nCyclesDelta % nCyclesPerSecond) back into nRTCCyclesLastUpdate, so that we will eventually\n * see a one-second delta.\n */\n // DEBUG:\n\n /*\n * Make sure that CMOS.STATUSB.SET isn't set; if it is, then the once-per-second RTC updates must be\n * disabled so that software can write new RTC date/time values without interference.\n */\n if (nSecondsDelta && !(this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.SET)) {\n while (nSecondsDelta--) {\n if (++this.abCMOSData[ChipSet.CMOS.ADDR.RTC_SEC] >= 60) {\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_SEC] = 0;\n if (++this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MIN] >= 60) {\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MIN] = 0;\n if (++this.abCMOSData[ChipSet.CMOS.ADDR.RTC_HOUR] >= 24) {\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_HOUR] = 0;\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_WEEK_DAY] = (this.abCMOSData[ChipSet.CMOS.ADDR.RTC_WEEK_DAY] % 7) + 1;\n let nDayMax = Usr.getMonthDays(this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MONTH], this.abCMOSData[ChipSet.CMOS.ADDR.RTC_YEAR]);\n if (++this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MONTH_DAY] > nDayMax) {\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MONTH_DAY] = 1;\n if (++this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MONTH] > 12) {\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_MONTH] = 1;\n this.abCMOSData[ChipSet.CMOS.ADDR.RTC_YEAR] = (this.abCMOSData[ChipSet.CMOS.ADDR.RTC_YEAR] + 1) % 100;\n }\n }\n }\n }\n }\n }\n\n /*\n * Obviously, setting the \"Update-In-Progress\" bit now might seem rather pointless, since we just\n * updated the RTC \"atomically\" as far as the machine is concerned; however, the bit must be set at\n * at some point, in order to make the MODEL_5170 BIOS (\"POST2_RTCUP\") happy.\n */\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSA] |= ChipSet.CMOS.STATUSA.UIP;\n\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSC] |= ChipSet.CMOS.STATUSC.UF;\n if (this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.UIE) {\n this.abCMOSData[ChipSet.CMOS.ADDR.STATUSC] |= ChipSet.CMOS.STATUSC.IRQF;\n this.setIRR(ChipSet.IRQ.RTC);\n }\n }\n\n this.nRTCCyclesLastUpdate = nCyclesUpdate - (nCyclesDelta % nCyclesPerSecond);\n }\n\n /**\n * initCMOSData()\n *\n * Initialize all the CMOS configuration bytes in the range 0x0E-0x2F (TODO: Decide what to do about 0x30-0x3F)\n *\n * Note that the MODEL_5170 \"SETUP\" utility is normally what sets all these bytes, including the checksum, and then\n * the BIOS verifies it, but since we want our machines to pass BIOS verification \"out of the box\", we go the extra\n * mile here, even though it's not really our responsibility.\n *\n * @this {ChipSet}\n */\n initCMOSData()\n {\n /*\n * On all reset() calls, the RAM component(s) will (re)add their totals, so we have to make sure that\n * the addition always starts with 0. That also means that ChipSet must always be initialized before RAM.\n */\n let iCMOS;\n for (iCMOS = ChipSet.CMOS.ADDR.BASEMEM_LO; iCMOS <= ChipSet.CMOS.ADDR.EXTMEM_HI; iCMOS++) {\n this.abCMOSData[iCMOS] = 0;\n }\n\n /*\n * Make sure all the \"checksummed\" CMOS bytes are initialized (not just the handful we set below) to ensure\n * that the checksum will be valid.\n */\n for (iCMOS = ChipSet.CMOS.ADDR.DIAG; iCMOS < ChipSet.CMOS.ADDR.CHKSUM_HI; iCMOS++) {\n if (this.abCMOSData[iCMOS] === undefined) this.abCMOSData[iCMOS] = 0;\n }\n\n /*\n * We propagate all compatible \"legacy\" SW1 bits to the CMOS.EQUIP byte using the old SW masks, but any further\n * access to CMOS.ADDR.EQUIP should use the new CMOS_EQUIP flags (eg, CMOS.EQUIP.FPU, CMOS.EQUIP.MONITOR.CGA80, etc).\n */\n this.abCMOSData[ChipSet.CMOS.ADDR.EQUIP] = this.getDIPLegacyBits(0);\n this.abCMOSData[ChipSet.CMOS.ADDR.FDRIVE] = (this.getDIPFloppyDriveType(0) << 4) | this.getDIPFloppyDriveType(1);\n\n /*\n * The final step is calculating the CMOS checksum, which we then store into the CMOS as a courtesy, so that the\n * user doesn't get unnecessary CMOS errors.\n */\n this.updateCMOSChecksum();\n }\n\n /**\n * setCMOSByte(iCMOS, b)\n *\n * This is ONLY for use by components that need to update CMOS configuration bytes to match their internal configuration.\n *\n * @this {ChipSet}\n * @param {number} iCMOS\n * @param {number} b\n * @return {boolean} true if successful, false if not (eg, CMOS not initialized yet, or no CMOS on this machine)\n */\n setCMOSByte(iCMOS, b)\n {\n if (this.abCMOSData) {\n\n this.abCMOSData[iCMOS] = b;\n this.updateCMOSChecksum();\n return true;\n }\n return false;\n }\n\n /**\n * addCMOSMemory(addr, size)\n *\n * For use by the RAM component, to dynamically update the CMOS memory configuration.\n *\n * @this {ChipSet}\n * @param {number} addr (if 0, BASEMEM_LO/BASEMEM_HI is updated; if >= 0x100000, then EXTMEM_LO/EXTMEM_HI is updated)\n * @param {number} size (in bytes; we convert to Kb)\n * @return {boolean} true if successful, false if not (eg, CMOS not initialized yet, or no CMOS on this machine)\n */\n addCMOSMemory(addr, size)\n {\n if (this.abCMOSData) {\n let iCMOS = (addr < 0x100000? ChipSet.CMOS.ADDR.BASEMEM_LO : ChipSet.CMOS.ADDR.EXTMEM_LO);\n let wKb = this.abCMOSData[iCMOS] | (this.abCMOSData[iCMOS+1] << 8);\n wKb += (size >> 10);\n this.abCMOSData[iCMOS] = wKb & 0xff;\n this.abCMOSData[iCMOS+1] = wKb >> 8;\n this.updateCMOSChecksum();\n return true;\n }\n return false;\n }\n\n /**\n * setCMOSDriveType(iDrive, bType)\n *\n * For use by the HDC component, to update the CMOS drive configuration to match HDC's internal configuration.\n *\n * TODO: Consider extending this to support FDC drive updates, so that the FDC can specify diskette drive types\n * (ie, FD360 or FD1200) in the same way that HDC does. However, historically, the ChipSet has been responsible for\n * floppy drive configuration, at least in terms of *number* of drives, through the use of SW1 settings, and we've\n * continued that tradition with the addition of the ChipSet 'floppies' parameter, which allows both the number *and*\n * capacity of drives to be specified with a simple array (eg, [360, 360] for two 360Kb drives).\n *\n * @this {ChipSet}\n * @param {number} iDrive (0 or 1)\n * @param {number} bType (0 for none, 1-14 for original drive type, 16-255 for extended drive type; 15 reserved)\n * @return {boolean} true if successful, false if not (eg, CMOS not initialized yet, or no CMOS on this machine)\n */\n setCMOSDriveType(iDrive, bType)\n {\n if (this.abCMOSData) {\n let bExt = null, iExt;\n let bOrig = this.abCMOSData[ChipSet.CMOS.ADDR.HDRIVE];\n if (bType > 15) {\n bExt = bType; bType = 15;\n }\n if (iDrive) {\n bOrig = (bOrig & ChipSet.CMOS.HDRIVE.D0_MASK) | bType;\n iExt = ChipSet.CMOS.ADDR.EXTHDRIVE1;\n } else {\n bOrig = (bOrig & ChipSet.CMOS.HDRIVE.D1_MASK) | (bType << 4);\n iExt = ChipSet.CMOS.ADDR.EXTHDRIVE0;\n }\n this.setCMOSByte(ChipSet.CMOS.ADDR.HDRIVE, bOrig);\n if (bExt != null) this.setCMOSByte(iExt, bExt);\n return true;\n }\n return false;\n }\n\n /**\n * updateCMOSChecksum()\n *\n * This sums all the CMOS bytes from 0x10-0x2D, creating a 16-bit checksum. That's a total of 30 (unsigned) 8-bit\n * values which could sum to at most 30*255 or 7650 (0x1DE2). Since there's no way that can overflow 16 bits, we don't\n * worry about masking it with 0xffff.\n *\n * WARNING: The IBM PC AT TechRef, p.1-53 (p.75) claims that the checksum is on bytes 0x10-0x20, but that's simply wrong.\n *\n * @this {ChipSet}\n */\n updateCMOSChecksum()\n {\n let wChecksum = 0;\n for (let iCMOS = ChipSet.CMOS.ADDR.FDRIVE; iCMOS < ChipSet.CMOS.ADDR.CHKSUM_HI; iCMOS++) {\n wChecksum += this.abCMOSData[iCMOS];\n }\n this.abCMOSData[ChipSet.CMOS.ADDR.CHKSUM_LO] = wChecksum & 0xff;\n this.abCMOSData[ChipSet.CMOS.ADDR.CHKSUM_HI] = wChecksum >> 8;\n }\n\n /**\n * save()\n *\n * This implements save support for the ChipSet component.\n *\n * @this {ChipSet}\n * @return {Object}\n */\n save()\n {\n let state = new State(this);\n state.set(0, [this.aDIPSwitches]);\n state.set(1, [this.saveDMAControllers()]);\n state.set(2, [this.savePICs()]);\n state.set(3, [this.bPIT0Ctrl, this.saveTimers(), this.bPIT1Ctrl]);\n state.set(4, [this.bPPIA, this.bPPIB, this.bPPIC, this.bPPICtrl, this.bNMI]);\n if (this.model >= ChipSet.MODEL_5170) {\n state.set(5, [this.b8042Status, this.b8042InBuff, this.b8042CmdData,\n this.b8042OutBuff, this.b8042InPort, this.b8042OutPort]);\n state.set(6, [this.abDMAPageSpare[7], this.abDMAPageSpare, this.bCMOSAddr, this.abCMOSData, this.nRTCCyclesLastUpdate, this.nRTCCyclesNextUpdate]);\n }\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the ChipSet component.\n *\n * @this {ChipSet}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n let a, i;\n a = data[0];\n\n if (Array.isArray(a[0])) {\n this.aDIPSwitches = a[0];\n } else {\n this.aDIPSwitches[0][0] = a[0];\n this.aDIPSwitches[1][0] = a[1] & 0x0F; // we do honor SW2[5] now, but it was erroneously set on some machines\n this.aDIPSwitches[0][1] = a[2];\n this.aDIPSwitches[1][1] = a[3] & 0x0F; // we do honor SW2[5] now, but it was erroneously set on some machines\n }\n this.updateDIPSwitches();\n\n a = data[1];\n for (i = 0; i < this.cDMACs; i++) {\n this.initDMAController(i, a.length == 1? a[0][i] : a);\n }\n\n a = data[2];\n for (i = 0; i < this.cPICs; i++) {\n this.initPIC(i, i === 0? ChipSet.PIC0.PORT_LO : ChipSet.PIC1.PORT_LO, a[0][i]);\n }\n\n a = data[3];\n this.bPIT0Ctrl = a[0];\n this.bPIT1Ctrl = a[2];\n for (i = 0; i < this.aTimers.length; i++) {\n this.initTimer(i, a[1][i]);\n }\n\n a = data[4];\n this.bPPIA = a[0];\n this.bPPIB = a[1];\n this.bPPIC = a[2];\n this.bPPICtrl = a[3];\n this.bNMI = a[4];\n\n a = data[5];\n if (a) {\n\n this.b8042Status = a[0];\n this.b8042InBuff = a[1];\n this.b8042CmdData = a[2];\n this.b8042OutBuff = a[3];\n this.b8042InPort = a[4];\n this.b8042OutPort = a[5];\n }\n\n a = data[6];\n if (a) {\n\n this.abDMAPageSpare = a[1];\n this.abDMAPageSpare[7] = a[0]; // formerly bMFGData\n this.bCMOSAddr = a[2];\n this.abCMOSData = a[3];\n this.nRTCCyclesLastUpdate = a[4];\n this.nRTCCyclesNextUpdate = a[5];\n /*\n * TODO: Decide whether restore() should faithfully preserve the RTC date/time that save() saved,\n * or always reinitialize the date/time, or give the user (or the machine configuration) the option.\n *\n * For now, we're always reinitializing the RTC date. Alternatively, we could selectively update\n * the CMOS bytes above, instead of overwriting them all, in which case this extra call to initRTCTime()\n * could be avoided.\n */\n this.initRTCTime();\n }\n return true;\n }\n\n /**\n * start()\n *\n * Notification from the Computer that it's starting.\n *\n * @this {ChipSet}\n */\n start()\n {\n /*\n * Currently, all we do with this notification is allow the speaker to make noise.\n */\n this.setSpeaker();\n }\n\n /**\n * stop()\n *\n * Notification from the Computer that it's stopping.\n *\n * @this {ChipSet}\n */\n stop()\n {\n /*\n * Currently, all we do with this notification is prevent the speaker from making noise.\n */\n this.setSpeaker();\n }\n\n /**\n * initDMAController(iDMAC, aState)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {Array} [aState]\n */\n initDMAController(iDMAC, aState)\n {\n let controller = this.aDMACs[iDMAC];\n if (!controller) {\n\n controller = {\n aChannels: new Array(4)\n };\n }\n let a = aState && aState.length >= 5? aState : ChipSet.aDMAControllerInit;\n controller.bStatus = a[0];\n controller.bCmd = a[1];\n controller.bReq = a[2];\n controller.bIndex = a[3];\n controller.nChannelBase = iDMAC << 2;\n for (let iChannel = 0; iChannel < controller.aChannels.length; iChannel++) {\n this.initDMAChannel(controller, iChannel, a[4][iChannel]);\n }\n controller.bTemp = a[5] || 0; // not present in older states\n this.aDMACs[iDMAC] = controller;\n }\n\n /**\n * initDMAChannel(controller, iChannel, aState)\n *\n * @this {ChipSet}\n * @param {Object} controller\n * @param {number} iChannel\n * @param {Array} [aState]\n */\n initDMAChannel(controller, iChannel, aState)\n {\n let channel = controller.aChannels[iChannel];\n if (!channel) {\n\n channel = {\n addrInit: [0,0],\n countInit: [0,0],\n addrCurrent: [0,0],\n countCurrent: [0,0]\n };\n }\n let a = aState && aState.length == 8? aState : ChipSet.aDMAChannelInit;\n channel.masked = a[0];\n channel.addrInit[0] = a[1][0]; channel.addrInit[1] = a[1][1];\n channel.countInit[0] = a[2][0]; channel.countInit[1] = a[2][1];\n channel.addrCurrent[0] = a[3][0]; channel.addrCurrent[1] = a[3][1];\n channel.countCurrent[0] = a[4][0]; channel.countCurrent[1] = a[4][1];\n channel.mode = a[5];\n channel.bPage = a[6];\n // a[7] is deprecated\n channel.controller = controller;\n channel.iChannel = iChannel;\n this.initDMAFunction(channel, a[8], a[9]);\n controller.aChannels[iChannel] = channel;\n }\n\n /**\n * initDMAFunction(channel)\n *\n * @param {Object} channel\n * @param {Component|string} [component]\n * @param {string} [sFunction]\n * @param {Object} [obj]\n * @return {*}\n */\n initDMAFunction(channel, component, sFunction, obj)\n {\n if (typeof component == \"string\") {\n component = Component.getComponentByID(component);\n }\n if (component) {\n channel.done = null;\n channel.sDevice = component.id;\n channel.sFunction = sFunction;\n channel.component = component;\n channel.fnTransfer = component[sFunction];\n channel.obj = obj;\n }\n return channel.fnTransfer;\n }\n\n /**\n * saveDMAControllers()\n *\n * @this {ChipSet}\n * @return {Array}\n */\n saveDMAControllers()\n {\n let data = [];\n for (let iDMAC = 0; iDMAC < this.aDMACs; iDMAC++) {\n let controller = this.aDMACs[iDMAC];\n data[iDMAC] = [\n controller.bStatus,\n controller.bCmd,\n controller.bReq,\n controller.bIndex,\n this.saveDMAChannels(controller),\n controller.bTemp\n ];\n }\n return data;\n }\n\n /**\n * saveDMAChannels(controller)\n *\n * @this {ChipSet}\n * @param {Object} controller\n * @return {Array}\n */\n saveDMAChannels(controller)\n {\n let data = [];\n for (let iChannel = 0; iChannel < controller.aChannels.length; iChannel++) {\n let channel = controller.aChannels[iChannel];\n data[iChannel] = [\n channel.masked,\n channel.addrInit,\n channel.countInit,\n channel.addrCurrent,\n channel.countCurrent,\n channel.mode,\n channel.bPage,\n channel.sDevice,\n channel.sFunction\n ];\n }\n return data;\n }\n\n /**\n * initPIC(iPIC, port, aState)\n *\n * @this {ChipSet}\n * @param {number} iPIC\n * @param {number} port\n * @param {Array} [aState]\n */\n initPIC(iPIC, port, aState)\n {\n let pic = this.aPICs[iPIC];\n if (!pic) {\n pic = {\n aICW: [null,null,null,null]\n };\n }\n let a = aState && aState.length == 8? aState : ChipSet.aPICInit;\n pic.port = port;\n pic.nIRQBase = iPIC << 3;\n pic.nDelay = a[0];\n pic.aICW[0] = a[1][0]; pic.aICW[1] = a[1][1]; pic.aICW[2] = a[1][2]; pic.aICW[3] = a[1][3];\n pic.nICW = a[2];\n pic.bIMR = a[3];\n pic.bIRR = a[4];\n pic.bISR = a[5];\n pic.bIRLow = a[6];\n pic.bOCW3 = a[7];\n this.aPICs[iPIC] = pic;\n }\n\n /**\n * savePICs()\n *\n * @this {ChipSet}\n * @return {Array}\n */\n savePICs()\n {\n let data = [];\n for (let iPIC = 0; iPIC < this.aPICs.length; iPIC++) {\n let pic = this.aPICs[iPIC];\n data[iPIC] = [\n pic.nDelay,\n pic.aICW,\n pic.nICW,\n pic.bIMR,\n pic.bIRR,\n pic.bISR,\n pic.bIRLow,\n pic.bOCW3\n ];\n }\n return data;\n }\n\n /**\n * initTimer(iTimer, aState)\n *\n * @this {ChipSet}\n * @param {number} iTimer\n * @param {Array} [aState]\n */\n initTimer(iTimer, aState)\n {\n let timer = this.aTimers[iTimer];\n if (!timer) {\n timer = {\n countInit: [0,0],\n countStart: [0,0],\n countCurrent: [0,0],\n countLatched: [0,0]\n };\n }\n let a = aState && aState.length >= 13? aState : ChipSet.aTimerInit;\n timer.countInit[0] = a[0][0]; timer.countInit[1] = a[0][1];\n timer.countStart[0] = a[1][0]; timer.countStart[1] = a[1][1];\n timer.countCurrent[0] = a[2][0]; timer.countCurrent[1] = a[2][1];\n timer.countLatched[0] = a[3][0]; timer.countLatched[1] = a[3][1];\n timer.bcd = a[4];\n timer.mode = a[5];\n timer.rw = a[6];\n timer.countIndex = a[7];\n timer.countBytes = a[8];\n timer.fOUT = a[9];\n timer.fCountLatched = a[10];\n timer.fCounting = a[11];\n timer.nCyclesStart = a[12];\n timer.bStatus = a[13] || 0;\n timer.fStatusLatched = a[14] || false;\n this.aTimers[iTimer] = timer;\n }\n\n /**\n * saveTimers()\n *\n * @this {ChipSet}\n * @return {Array}\n */\n saveTimers()\n {\n let data = [];\n for (let iTimer = 0; iTimer < this.aTimers.length; iTimer++) {\n let timer = this.aTimers[iTimer];\n data[iTimer] = [\n timer.countInit,\n timer.countStart,\n timer.countCurrent,\n timer.countLatched,\n timer.bcd,\n timer.mode,\n timer.rw,\n timer.countIndex,\n timer.countBytes,\n timer.fOUT,\n timer.fCountLatched,\n timer.fCounting,\n timer.nCyclesStart,\n timer.bStatus,\n timer.fStatusLatched\n ];\n }\n return data;\n }\n\n /**\n * addDIPSwitches(iDIP, sBinding)\n *\n * @this {ChipSet}\n * @param {number} iDIP (0 or 1)\n * @param {string} sBinding is the name of the control\n */\n addDIPSwitches(iDIP, sBinding)\n {\n let sHTML = \"\";\n let control = this.bindings[sBinding];\n for (let i = 1; i <= 8; i++) {\n let sCellClasses = this.sCellClass;\n if (!i) sCellClasses += \" \" + this.sCellClass + \"Left\";\n let sCellID = sBinding + \"-\" + i;\n sHTML += \"<div id=\\\"\" + sCellID + \"\\\" class=\\\"\" + sCellClasses + \"\\\" data-value=\\\"0\\\">\" + i + \"</div>\\n\";\n }\n control.innerHTML = sHTML;\n this.updateDIPSwitchControls(iDIP, sBinding, true);\n }\n\n /**\n * findDIPSwitch(iDIP, iSwitch)\n *\n * @this {ChipSet}\n * @param {number} iDIP\n * @param {number} iSwitch\n * @return {Object|null} DIPSW switchGroup containing the DIP switch's MASK, VALUES, and LABEL, or null if none\n */\n findDIPSwitch(iDIP, iSwitch)\n {\n let switchDIPs = ChipSet.DIPSW[this.model|0];\n let switchTypes = switchDIPs && switchDIPs[iDIP];\n if (switchTypes) {\n for (let iType in switchTypes) {\n let switchGroup = switchTypes[iType];\n if (switchGroup.MASK & (1 << iSwitch)) {\n return switchGroup;\n }\n }\n }\n return null;\n }\n\n /**\n * getDIPLegacyBits(iDIP)\n *\n * @this {ChipSet}\n * @param {number} iDIP\n * @return {number|undefined}\n */\n getDIPLegacyBits(iDIP)\n {\n let b;\n if (!iDIP) {\n b = 0;\n b |= (this.getDIPVideoMonitor() << ChipSet.PPI_SW.MONITOR.SHIFT) & ChipSet.PPI_SW.MONITOR.MASK;\n b |= (this.getDIPCoprocessor()? ChipSet.PPI_SW.FPU : 0);\n let nDrives = this.getDIPFloppyDrives();\n b |= (nDrives? ((((nDrives - 1) << ChipSet.PPI_SW.FDRIVE.SHIFT) & ChipSet.PPI_SW.FDRIVE.MASK) | ChipSet.PPI_SW.FDRIVE.IPL) : 0);\n }\n return b;\n }\n\n /**\n * getDIPSwitches(iType, fInit)\n *\n * @this {ChipSet}\n * @param {number} iType\n * @param {boolean} [fInit] is true for initial switch value, current value otherwise\n * @return {*|null}\n */\n getDIPSwitches(iType, fInit)\n {\n let value = null;\n let switchDIPs = ChipSet.DIPSW[this.model] || ChipSet.DIPSW[this.model|0] || ChipSet.DIPSW[ChipSet.MODEL_5150];\n for (let iDIP = 0; iDIP < switchDIPs.length; iDIP++) {\n let switchTypes = switchDIPs[iDIP];\n if (switchTypes) {\n let switchGroup = switchTypes[iType];\n if (switchGroup) {\n let bits = this.aDIPSwitches[iDIP][fInit?0:1] & switchGroup.MASK;\n for (let v in switchGroup.VALUES) {\n if (switchGroup.VALUES[v] == bits) {\n value = v;\n /*\n * We prefer numeric properties, and all switch definitions must provide them\n * if their helper functions (eg, getDIPVideoMonitor()) expect numeric properties.\n */\n if (typeof +value == 'number') break;\n }\n }\n break;\n }\n }\n }\n return value;\n }\n\n /**\n * getDIPCoprocessor(fInit)\n *\n * @this {ChipSet}\n * @param {boolean} [fInit] is true for init switch value(s) only, current value(s) otherwise\n * @return {number} 1 if installed, 0 if not\n */\n getDIPCoprocessor(fInit)\n {\n let n = /** @type {number} */ (this.getDIPSwitches(ChipSet.SWITCH_TYPE.FPU, fInit));\n return +n;\n }\n\n /**\n * getDIPFloppyDrives(fInit)\n *\n * @this {ChipSet}\n * @param {boolean} [fInit] is true for init switch value(s) only, current value(s) otherwise\n * @return {number} number of floppy drives specified by SW1 (range is 0 to 4)\n */\n getDIPFloppyDrives(fInit)\n {\n let n = /** @type {number} */ (this.getDIPSwitches(ChipSet.SWITCH_TYPE.FLOPNUM, fInit));\n return +n;\n }\n\n /**\n * getDIPFloppyDriveType(iDrive)\n *\n * @this {ChipSet}\n * @param {number} iDrive (0-based)\n * @return {number} one of the ChipSet.CMOS.FDRIVE.FD* values (FD360, FD1200, etc)\n */\n getDIPFloppyDriveType(iDrive)\n {\n if (iDrive < this.getDIPFloppyDrives()) {\n if (!this.aFloppyDrives) {\n return ChipSet.CMOS.FDRIVE.FD360;\n }\n if (iDrive < this.aFloppyDrives.length) {\n switch(this.aFloppyDrives[iDrive]) {\n case 160:\n case 180:\n case 320:\n case 360:\n return ChipSet.CMOS.FDRIVE.FD360;\n case 720:\n return ChipSet.CMOS.FDRIVE.FD720;\n case 1200:\n return ChipSet.CMOS.FDRIVE.FD1200;\n case 1440:\n return ChipSet.CMOS.FDRIVE.FD1440;\n }\n }\n\n }\n return ChipSet.CMOS.FDRIVE.NONE;\n }\n\n /**\n * getDIPFloppyDriveSize(iDrive)\n *\n * @this {ChipSet}\n * @param {number} iDrive (0-based)\n * @return {number} capacity of drive in Kb (eg, 360, 1200, 1440, etc), or 0 if none\n */\n getDIPFloppyDriveSize(iDrive)\n {\n if (iDrive < this.getDIPFloppyDrives()) {\n if (!this.aFloppyDrives) {\n return 360;\n }\n if (iDrive < this.aFloppyDrives.length) {\n return this.aFloppyDrives[iDrive];\n }\n\n }\n return 0;\n }\n\n /**\n * getDIPMemorySize(fInit)\n *\n * @this {ChipSet}\n * @param {boolean} [fInit] is true for init switch value(s) only, current value(s) otherwise\n * @return {number} number of Kb of specified memory (NOT necessarily the same as installed memory; see RAM component)\n */\n getDIPMemorySize(fInit)\n {\n let nKBLowMem = /** @type {number} */ (this.getDIPSwitches(ChipSet.SWITCH_TYPE.LOWMEM, fInit));\n let nKBExpMem = /** @type {number} */ (this.getDIPSwitches(ChipSet.SWITCH_TYPE.EXPMEM, fInit));\n return +nKBLowMem + +nKBExpMem;\n }\n\n /**\n * getDIPVideoMonitor(fInit)\n *\n * @this {ChipSet}\n * @param {boolean} [fInit] is true for init switch value(s) only, current value(s) otherwise\n * @return {number} one of ChipSet.MONITOR.*\n */\n getDIPVideoMonitor(fInit)\n {\n let n = /** @type {number} */ (this.getDIPSwitches(ChipSet.SWITCH_TYPE.MONITOR, fInit));\n return +n;\n }\n\n /**\n * parseDIPSwitches(sBits, bDefault)\n *\n * @this {ChipSet}\n * @param {string} sBits describing switch settings\n * @param {number} [bDefault]\n * @return {number|undefined}\n */\n parseDIPSwitches(sBits, bDefault)\n {\n let b = bDefault;\n if (sBits) {\n /*\n * NOTE: We can't use parseInt() with a base of 2, because both bit order and bit sense are reversed.\n */\n b = 0;\n let bit = 0x1;\n for (let i = 0; i < sBits.length; i++) {\n if (sBits.charAt(i) == \"0\") b |= bit;\n bit <<= 1;\n }\n }\n return b;\n }\n\n /**\n * setDIPSwitches(iType, value, fInit)\n *\n * @this {ChipSet}\n * @param {number} iType\n * @param {*} value\n * @param {boolean} [fInit]\n * @return {boolean} true if successful, false if unrecognized type and/or value\n */\n setDIPSwitches(iType, value, fInit)\n {\n let switchDIPs = ChipSet.DIPSW[this.model] || ChipSet.DIPSW[this.model|0] || ChipSet.DIPSW[ChipSet.MODEL_5150];\n for (let iDIP = 0; iDIP < switchDIPs.length; iDIP++) {\n let switchTypes = switchDIPs[iDIP];\n if (switchTypes) {\n let switchGroup = switchTypes[iType];\n if (switchGroup) {\n for (let v in switchGroup.VALUES) {\n if (v == value) {\n this.aDIPSwitches[iDIP][fInit?0:1] &= ~switchGroup.MASK;\n this.aDIPSwitches[iDIP][fInit?0:1] |= switchGroup.VALUES[v];\n return true;\n }\n }\n }\n }\n }\n return false;\n }\n\n /**\n * getDIPSwitchControl(control)\n *\n * @this {ChipSet}\n * @param {HTMLElement} control is an HTML control DOM object\n * @return {boolean} true if the switch represented by e is \"on\", false if \"off\"\n */\n getDIPSwitchControl(control)\n {\n return control.getAttribute(\"data-value\") == \"1\";\n }\n\n /**\n * setDIPSwitchControl(control, f)\n *\n * @this {ChipSet}\n * @param {HTMLElement} control is an HTML control DOM object\n * @param {boolean} f is true if the switch represented by control should be \"on\", false if \"off\"\n */\n setDIPSwitchControl(control, f)\n {\n control.setAttribute(\"data-value\", f? \"1\" : \"0\");\n control.style.color = (f? \"#ffffff\" : \"#000000\");\n control.style.backgroundColor = (f? \"#000000\" : \"#ffffff\");\n }\n\n /**\n * toggleDIPSwitchControl(control)\n *\n * @this {ChipSet}\n * @param {HTMLElement} control is an HTML control DOM object\n */\n toggleDIPSwitchControl(control)\n {\n let f = !this.getDIPSwitchControl(control);\n this.setDIPSwitchControl(control, f);\n let sID = control.getAttribute(\"id\");\n let asParts = sID.split(\"-\");\n let b = (0x1 << (+asParts[1] - 1));\n switch (asParts[0]) {\n case ChipSet.CONTROLS.SW1:\n this.aDIPSwitches[0][0] = (this.aDIPSwitches[0][0] & ~b) | (f? 0 : b);\n break;\n case ChipSet.CONTROLS.SW2:\n this.aDIPSwitches[1][0] = (this.aDIPSwitches[1][0] & ~b) | (f? 0 : b);\n break;\n default:\n break;\n }\n this.updateDIPSwitchDescriptions();\n }\n\n /**\n * updateDIPSwitches()\n *\n * @this {ChipSet}\n */\n updateDIPSwitches()\n {\n this.updateDIPSwitchControls(0, ChipSet.CONTROLS.SW1);\n this.updateDIPSwitchControls(1, ChipSet.CONTROLS.SW2);\n this.updateDIPSwitchDescriptions();\n }\n\n /**\n * updateDIPSwitchControls(iDIP, sBinding, fInit)\n *\n * @this {ChipSet}\n * @param {number} iDIP (0 or 1)\n * @param {string} sBinding is the name of the control\n * @param {boolean} [fInit]\n */\n updateDIPSwitchControls(iDIP, sBinding, fInit)\n {\n let control = this.bindings[sBinding];\n if (control) {\n let v;\n if (fInit) {\n v = this.aDIPSwitches[iDIP][0];\n } else {\n v = this.aDIPSwitches[iDIP][1] = this.aDIPSwitches[iDIP][0];\n }\n let aeCells = Component.getElementsByClass(control, this.sCellClass);\n for (let i = 0; i < aeCells.length; i++) {\n let switchGroup = this.findDIPSwitch(iDIP, i);\n let sLabel = switchGroup && switchGroup.LABEL || \"Reserved\";\n aeCells[i].setAttribute(\"title\", sLabel);\n this.setDIPSwitchControl(aeCells[i], !(v & (0x1 << i)));\n aeCells[i].onclick = function(chipset, eSwitch) {\n /*\n * If we define the onclick handler below as \"function(e)\" instead of simply \"function()\", then we will\n * also receive an Event object; however, IE reportedly requires that we examine a global (window.event)\n * instead. If that's true, and if we ever care to get more details about the click event, then define\n * a local var; eg:\n * \n * let event = window.event || e;\n */\n return function onClickSwitch() {\n chipset.toggleDIPSwitchControl(eSwitch);\n };\n }(this, aeCells[i]);\n }\n }\n }\n\n /**\n * updateDIPSwitchDescriptions()\n *\n * @this {ChipSet}\n */\n updateDIPSwitchDescriptions()\n {\n let controlDesc = this.bindings[ChipSet.CONTROLS.SWDESC];\n if (controlDesc != null) {\n let sText = \"\";\n /*\n * TODO: Monitor type 0 used to be \"None\" (ie, \"No Monitor\"), which was correct in a pre-EGA world,\n * but in the post-EGA world, it depends. We should ask the Video component for a definitive answer.\n */\n let asMonitorTypes = {\n 0: \"Enhanced Color\",\n 1: \"TV\",\n 2: \"Color\",\n 3: \"Monochrome\"\n };\n sText += this.getDIPMemorySize(true) + \"Kb\";\n sText += \", \" + (+this.getDIPCoprocessor(true)? \"\" : \"No \") + \"FPU\";\n sText += \", \" + asMonitorTypes[this.getDIPVideoMonitor(true)] + \" Monitor\";\n sText += \", \" + this.getDIPFloppyDrives(true) + \" Floppy Drives\";\n if (this.aDIPSwitches[0][1] != null && this.aDIPSwitches[0][1] != this.aDIPSwitches[0][0] ||\n this.aDIPSwitches[1][1] != null && this.aDIPSwitches[1][1] != this.aDIPSwitches[1][0]) {\n sText += \" (Reset required)\";\n }\n controlDesc.textContent = sText;\n }\n }\n\n /**\n * dumpPIC()\n *\n * @this {ChipSet}\n */\n dumpPIC()\n {\n if (DEBUGGER) {\n for (let iPIC = 0; iPIC < this.aPICs.length; iPIC++) {\n let pic = this.aPICs[iPIC];\n let sDump = \"PIC\" + iPIC + \":\";\n for (let i = 0; i < pic.aICW.length; i++) {\n let b = pic.aICW[i];\n sDump += \" IC\" + (i + 1) + '=' + Str.toHexByte(b);\n }\n sDump += \" IMR=\" + Str.toHexByte(pic.bIMR) + \" IRR=\" + Str.toHexByte(pic.bIRR) + \" ISR=\" + Str.toHexByte(pic.bISR) + \" DELAY=\" + pic.nDelay;\n this.dbg.println(sDump);\n }\n }\n }\n\n /**\n * dumpTimer(asArgs)\n *\n * Use \"d timer\" to dump all timers, or \"d timer n\" to dump only timer n.\n *\n * @this {ChipSet}\n * @param {Array.<string>} asArgs\n */\n dumpTimer(asArgs)\n {\n if (DEBUGGER) {\n let sParm = asArgs[0];\n let nTimer = (sParm? +sParm : null);\n for (let iTimer = 0; iTimer < this.aTimers.length; iTimer++) {\n if (nTimer != null && iTimer != nTimer) continue;\n this.updateTimer(iTimer);\n let timer = this.aTimers[iTimer];\n let sDump = \"TIMER\" + iTimer + \":\";\n let count = 0;\n if (timer.countBytes != null) {\n for (let i = 0; i <= timer.countBytes; i++) {\n count |= (timer.countCurrent[i] << (i * 8));\n }\n }\n sDump += \" mode=\" + (timer.mode >> 1) + \" bytes=\" + timer.countBytes + \" count=\" + Str.toHexWord(count);\n this.dbg.println(sDump);\n }\n }\n }\n\n /**\n * dumpCMOS()\n *\n * @this {ChipSet}\n */\n dumpCMOS()\n {\n if (DEBUGGER) {\n let sDump = \"\";\n for (let iCMOS = 0; iCMOS < ChipSet.CMOS.ADDR.TOTAL; iCMOS++) {\n let b = (iCMOS <= ChipSet.CMOS.ADDR.STATUSD? this.getRTCByte(iCMOS) : this.abCMOSData[iCMOS]);\n if (sDump) sDump += '\\n';\n sDump += \"CMOS[\" + Str.toHexByte(iCMOS) + \"]: \" + Str.toHexByte(b);\n }\n this.dbg.println(sDump);\n }\n }\n\n /**\n * inDMAChannelAddr(iDMAC, iChannel, port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} iChannel\n * @param {number} port (0x00, 0x02, 0x04, 0x06 for DMAC 0, 0xC0, 0xC4, 0xC8, 0xCC for DMAC 1)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inDMAChannelAddr(iDMAC, iChannel, port, addrFrom)\n {\n let controller = this.aDMACs[iDMAC];\n let channel = controller.aChannels[iChannel];\n let b = channel.addrCurrent[controller.bIndex];\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, null, addrFrom, \"DMA\" + iDMAC + \".CHANNEL\" + iChannel + \".ADDR[\" + controller.bIndex + \"]\", b, true);\n }\n controller.bIndex ^= 0x1;\n /*\n * Technically, aTimers[1].fOut is what drives DMA requests for DMA channel 0 (ChipSet.DMA_REFRESH),\n * every 15us, once the BIOS has initialized the channel's \"mode\" with MODE_SINGLE, INCREMENT, AUTOINIT,\n * and TYPE_READ (0x58) and initialized TIMER1 appropriately.\n *\n * However, we don't need to be that particular. Simply simulate an ever-increasing address after every\n * read of the full DMA channel 0 address.\n */\n if (!iDMAC && iChannel == ChipSet.DMA_REFRESH && !controller.bIndex) {\n channel.addrCurrent[0]++;\n if (channel.addrCurrent[0] > 0xff) {\n channel.addrCurrent[0] = 0;\n channel.addrCurrent[1]++;\n if (channel.addrCurrent[1] > 0xff) {\n channel.addrCurrent[1] = 0;\n }\n }\n }\n return b;\n }\n\n /**\n * outDMAChannelAddr(iDMAC, iChannel, port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} iChannel\n * @param {number} port (0x00, 0x02, 0x04, 0x06 for DMAC 0, 0xC0, 0xC4, 0xC8, 0xCC for DMAC 1)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outDMAChannelAddr(iDMAC, iChannel, port, bOut, addrFrom)\n {\n let controller = this.aDMACs[iDMAC];\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"DMA\" + iDMAC + \".CHANNEL\" + iChannel + \".ADDR[\" + controller.bIndex + \"]\", null, true);\n }\n let channel = controller.aChannels[iChannel];\n channel.addrCurrent[controller.bIndex] = channel.addrInit[controller.bIndex] = bOut;\n controller.bIndex ^= 0x1;\n }\n\n /**\n * inDMAChannelCount(iDMAC, iChannel, port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} iChannel\n * @param {number} port (0x01, 0x03, 0x05, 0x07 for DMAC 0, 0xC2, 0xC6, 0xCA, 0xCE for DMAC 1)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inDMAChannelCount(iDMAC, iChannel, port, addrFrom)\n {\n let controller = this.aDMACs[iDMAC];\n let channel = controller.aChannels[iChannel];\n let b = channel.countCurrent[controller.bIndex];\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, null, addrFrom, \"DMA\" + iDMAC + \".CHANNEL\" + iChannel + \".COUNT[\" + controller.bIndex + \"]\", b, true);\n }\n controller.bIndex ^= 0x1;\n /*\n * Technically, aTimers[1].fOut is what drives DMA requests for DMA channel 0 (ChipSet.DMA_REFRESH),\n * every 15us, once the BIOS has initialized the channel's \"mode\" with MODE_SINGLE, INCREMENT, AUTOINIT,\n * and TYPE_READ (0x58) and initialized TIMER1 appropriately.\n *\n * However, we don't need to be that particular. Simply simulate an ever-decreasing count after every\n * read of the full DMA channel 0 count.\n */\n if (!iDMAC && iChannel == ChipSet.DMA_REFRESH && !controller.bIndex) {\n channel.countCurrent[0]--;\n if (channel.countCurrent[0] < 0) {\n channel.countCurrent[0] = 0xff;\n channel.countCurrent[1]--;\n if (channel.countCurrent[1] < 0) {\n channel.countCurrent[1] = 0xff;\n /*\n * This is the logical point to indicate Terminal Count (TC), but again, there's no need to be\n * so particular; inDMAStatus() has its own logic for periodically signalling TC.\n */\n }\n }\n }\n return b;\n }\n\n /**\n * outDMAChannelCount(iDMAC, iChannel, port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} iChannel (ports 0x01, 0x03, 0x05, 0x07)\n * @param {number} port (0x01, 0x03, 0x05, 0x07 for DMAC 0, 0xC2, 0xC6, 0xCA, 0xCE for DMAC 1)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outDMAChannelCount(iDMAC, iChannel, port, bOut, addrFrom)\n {\n let controller = this.aDMACs[iDMAC];\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"DMA\" + iDMAC + \".CHANNEL\" + iChannel + \".COUNT[\" + controller.bIndex + \"]\", null, true);\n }\n let channel = controller.aChannels[iChannel];\n channel.countCurrent[controller.bIndex] = channel.countInit[controller.bIndex] = bOut;\n controller.bIndex ^= 0x1;\n }\n\n /**\n * inDMAStatus(iDMAC, port, addrFrom)\n *\n * From the 8237A spec:\n *\n * \"The Status register is available to be read out of the 8237A by the microprocessor.\n * It contains information about the status of the devices at this point. This information includes\n * which channels have reached Terminal Count (TC) and which channels have pending DMA requests.\n *\n * Bits 0–3 are set every time a TC is reached by that channel or an external EOP is applied.\n * These bits are cleared upon Reset and on each Status Read.\n *\n * Bits 4–7 are set whenever their corresponding channel is requesting service.\"\n *\n * TRIVIA: This hook wasn't installed when I was testing with the MODEL_5150 ROM BIOS, and it\n * didn't matter, but the MODEL_5160 ROM BIOS checks it several times, including @F000:E156, where\n * it verifies that TIMER1 didn't request service on channel 0.\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} port (0x08 for DMAC 0, 0xD0 for DMAC 1)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inDMAStatus(iDMAC, port, addrFrom)\n {\n /*\n * HACK: Unlike the MODEL_5150, the MODEL_5160 ROM BIOS checks DMA channel 0 for TC (@F000:E4DF)\n * after running a number of unrelated tests, since enough time would have passed for channel 0 to\n * have reached TC at least once. So I simply OR in a hard-coded TC bit for channel 0 every time\n * status is read.\n */\n let controller = this.aDMACs[iDMAC];\n let b = controller.bStatus | ChipSet.DMA_STATUS.CH0_TC;\n controller.bStatus &= ~ChipSet.DMA_STATUS.ALL_TC;\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, null, addrFrom, \"DMA\" + iDMAC + \".STATUS\", b, true);\n }\n return b;\n }\n\n /**\n * outDMACmd(iDMAC, port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} port (0x08 for DMAC 0, 0xD0 for DMAC 1)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outDMACmd(iDMAC, port, bOut, addrFrom)\n {\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"DMA\" + iDMAC + \".CMD\", null, true);\n }\n this.aDMACs[iDMAC].bCmd = bOut;\n }\n\n /**\n * outDMAReq(iDMAC, port, bOut, addrFrom)\n *\n * From the 8237A spec:\n *\n * \"The 8237A can respond to requests for DMA service which are initiated by software as well as by a DREQ.\n * Each channel has a request bit associated with it in the 4-bit Request register. These are non-maskable and subject\n * to prioritization by the Priority Encoder network. Each register bit is set or reset separately under software\n * control or is cleared upon generation of a TC or external EOP. The entire register is cleared by a Reset.\n *\n * To set or reset a bit the software loads the proper form of the data word.... In order to make a software request,\n * the channel must be in Block Mode.\"\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} port (0x09 for DMAC 0, 0xD2 for DMAC 1)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outDMAReq(iDMAC, port, bOut, addrFrom)\n {\n let controller = this.aDMACs[iDMAC];\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"DMA\" + iDMAC + \".REQ\", null, true);\n }\n /*\n * Bits 0-1 contain the channel number\n */\n let iChannel = (bOut & 0x3);\n /*\n * Bit 2 is the request bit (0 to reset, 1 to set), which must be propagated to the corresponding bit (4-7) in the status register\n */\n let iChannelBit = ((bOut & 0x4) << (iChannel + 2));\n controller.bStatus = (controller.bStatus & ~(0x10 << iChannel)) | iChannelBit;\n controller.bReq = bOut;\n }\n\n /**\n * outDMAMask(iDMAC, port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} port (0x0A for DMAC 0, 0xD4 for DMAC 1)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outDMAMask(iDMAC, port, bOut, addrFrom)\n {\n let controller = this.aDMACs[iDMAC];\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"DMA\" + iDMAC + \".MASK\", null, true);\n }\n let iChannel = bOut & ChipSet.DMA_MASK.CHANNEL;\n let channel = controller.aChannels[iChannel];\n channel.masked = !!(bOut & ChipSet.DMA_MASK.CHANNEL_SET);\n if (!channel.masked) this.requestDMA(controller.nChannelBase + iChannel);\n }\n\n /**\n * outDMAMode(iDMAC, port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} port (0x0B for DMAC 0, 0xD6 for DMAC 1)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outDMAMode(iDMAC, port, bOut, addrFrom)\n {\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"DMA\" + iDMAC + \".MODE\", null, true);\n }\n let iChannel = bOut & ChipSet.DMA_MODE.CHANNEL;\n this.aDMACs[iDMAC].aChannels[iChannel].mode = bOut;\n }\n\n /**\n * outDMAResetFF(iDMAC, port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} port (0x0C for DMAC 0, 0xD8 for DMAC 1)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n *\n * Any write to this port simply resets the controller's \"first/last flip-flop\", which determines whether\n * the even or odd byte of a DMA address or count register will be accessed next.\n */\n outDMAResetFF(iDMAC, port, bOut, addrFrom)\n {\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"DMA\" + iDMAC + \".RESET_FF\", null, true);\n }\n this.aDMACs[iDMAC].bIndex = 0;\n }\n\n /**\n * inDMATemp(iDMAC, port, addrFrom)\n *\n * From the 8237A spec:\n *\n * \"The Temporary register is used to hold data during memory-to-memory transfers Following the\n * completion of the transfers, the last word moved can be read by the microprocessor in the Program Condition.\n * The Temporary register always contains the last byte transferred in the previous memory-to-memory operation,\n * unless cleared by a Reset.\"\n *\n * TRIVIA: This hook wasn't installed when I was testing with ANY of the IBM ROMs, but it's required\n * by the AT&T 6300 (aka Olivetti M24) ROM.\n *\n * TODO: When support is added for memory-to-memory transfers, bTemp needs to be updated according to spec.\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} port (0x0D for DMAC 0, 0xDA for DMAC 1)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inDMATemp(iDMAC, port, addrFrom)\n {\n let controller = this.aDMACs[iDMAC];\n let b = controller.bTemp;\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, null, addrFrom, \"DMA\" + iDMAC + \".TEMP\", b, true);\n }\n return b;\n }\n\n /**\n * outDMAMasterClear(iDMAC, port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} port (0x0D for DMAC 0, 0xDA for DMAC 1)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outDMAMasterClear(iDMAC, port, bOut, addrFrom)\n {\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"DMA\" + iDMAC + \".MASTER_CLEAR\", null, true);\n }\n /*\n * The value written to this port doesn't matter; any write triggers a \"master clear\" operation\n *\n * TODO: Can't we just call initDMAController(), which would also take care of clearing controller.bStatus?\n */\n let controller = this.aDMACs[iDMAC];\n for (let i = 0; i < controller.aChannels.length; i++) {\n this.initDMAChannel(controller, i);\n }\n }\n\n /**\n * inDMAPageReg(iDMAC, iChannel, port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} iChannel\n * @param {number} port\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inDMAPageReg(iDMAC, iChannel, port, addrFrom)\n {\n let bIn = this.aDMACs[iDMAC].aChannels[iChannel].bPage;\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, null, addrFrom, \"DMA\" + iDMAC + \".CHANNEL\" + iChannel + \".PAGE\", bIn, true);\n }\n return bIn;\n }\n\n /**\n * outDMAPageReg(iDMAC, iChannel, port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDMAC\n * @param {number} iChannel\n * @param {number} port\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outDMAPageReg(iDMAC, iChannel, port, bOut, addrFrom)\n {\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"DMA\" + iDMAC + \".CHANNEL\" + iChannel + \".PAGE\", null, true);\n }\n this.aDMACs[iDMAC].aChannels[iChannel].bPage = bOut;\n }\n\n /**\n * inDMAPageSpare(iSpare, port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iSpare\n * @param {number} port\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inDMAPageSpare(iSpare, port, addrFrom)\n {\n let bIn = this.abDMAPageSpare[iSpare];\n if (this.messageEnabled(Messages.DMA | Messages.PORT)) {\n this.printMessageIO(port, null, addrFrom, \"DMA.SPARE\" + iSpare + \".PAGE\", bIn, true);\n }\n return bIn;\n }\n\n /**\n * outDMAPageSpare(iSpare, port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iSpare\n * @param {number} port\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outDMAPageSpare(iSpare, port, bOut, addrFrom)\n {\n /*\n * TODO: Remove this DEBUG-only DESKPRO386 code once we're done debugging DeskPro 386 ROMs;\n * it enables logging of all DeskPro 386 ROM checkpoint I/O to port 0x84.\n */\n if (this.messageEnabled(Messages.DMA | Messages.PORT) || DEBUG && (this.model|0) == ChipSet.MODEL_COMPAQ_DESKPRO386 && port == 0x84) {\n this.printMessageIO(port, bOut, addrFrom, \"DMA.SPARE\" + iSpare + \".PAGE\", null, true);\n }\n this.abDMAPageSpare[iSpare] = bOut;\n }\n\n /**\n * connectDMA(iDMAChannel, component, sFunction, obj)\n *\n * @param {number} iDMAChannel\n * @param {Component|string} component\n * @param {string} sFunction\n * @param {Object} obj (eg, when the HDC connects, it passes a drive object)\n */\n connectDMA(iDMAChannel, component, sFunction, obj)\n {\n let iDMAC = iDMAChannel >> 2;\n let controller = this.aDMACs[iDMAC];\n\n let iChannel = iDMAChannel & 0x3;\n let channel = controller.aChannels[iChannel];\n\n this.initDMAFunction(channel, component, sFunction, obj);\n }\n\n /**\n * requestDMA(iDMAChannel, done)\n *\n * @this {ChipSet}\n * @param {number} iDMAChannel\n * @param {function(boolean)} [done]\n *\n * For DMA_MODE.TYPE_WRITE transfers, fnTransfer(-1) must return bytes as long as we request them (although it may\n * return -1 if it runs out of bytes prematurely).\n *\n * Similarly, for DMA_MODE.TYPE_READ transfers, fnTransfer(b) must accept bytes as long as we deliver them (although\n * it is certainly free to ignore bytes it no longer wants).\n */\n requestDMA(iDMAChannel, done)\n {\n let iDMAC = iDMAChannel >> 2;\n let controller = this.aDMACs[iDMAC];\n\n let iChannel = iDMAChannel & 0x3;\n let channel = controller.aChannels[iChannel];\n\n if (!channel.component || !channel.fnTransfer || !channel.obj) {\n if (DEBUG && this.messageEnabled(Messages.DMA | Messages.DATA)) {\n this.printMessage(\"requestDMA(\" + iDMAChannel + \"): not connected to a component\", true);\n }\n if (done) done(true);\n return;\n }\n\n /*\n * We can't simply slam done into channel.done; that would be fine if requestDMA() was called only by functions\n * like HDC.doRead() and HDC.doWrite(), but we're also called whenever a DMA channel is unmasked, and in those cases,\n * we need to preserve whatever handler may have been previously set.\n *\n * However, in an effort to ensure we don't end up with stale done handlers, connectDMA() will reset channel.done.\n */\n if (done) channel.done = done;\n\n if (channel.masked) {\n if (DEBUG && this.messageEnabled(Messages.DMA | Messages.DATA)) {\n this.printMessage(\"requestDMA(\" + iDMAChannel + \"): channel masked, request queued\", true);\n }\n return;\n }\n\n /*\n * Let's try to do async DMA without asking the CPU for help...\n *\n * this.cpu.setDMA(true);\n */\n this.advanceDMA(channel, true);\n }\n\n /**\n * advanceDMA(channel, fInit)\n *\n * @this {ChipSet}\n * @param {Object} channel\n * @param {boolean} [fInit]\n */\n advanceDMA(channel, fInit)\n {\n if (fInit) {\n channel.count = (channel.countCurrent[1] << 8) | channel.countCurrent[0];\n channel.type = (channel.mode & ChipSet.DMA_MODE.TYPE);\n channel.fWarning = channel.fError = false;\n if (DEBUG && DEBUGGER) {\n channel.cbDebug = channel.count + 1;\n channel.sAddrDebug = (DEBUG && DEBUGGER? null : undefined);\n }\n }\n /*\n * To support async DMA without requiring help from the CPU (ie, without relying upon cpu.setDMA()), we require that\n * the data transfer functions provide an fAsync parameter to their callbacks; fAsync must be true if the callback was\n * truly asynchronous (ie, it had to wait for a remote I/O request to finish), or false if the data was already available\n * and the callback was performed synchronously.\n *\n * Whenever a callback is issued asynchronously, we will immediately daisy-chain another pair of updateDMA()/advanceDMA()\n * calls, which will either finish the DMA operation if no more remote I/O requests are required, or will queue up another\n * I/O request, which will in turn trigger another async callback. Thus, the DMA request keeps itself going without\n * requiring any special assistance from the CPU via setDMA().\n */\n let bto = null;\n let chipset = this;\n let fAsyncRequest = false;\n let controller = channel.controller;\n let iDMAChannel = controller.nChannelBase + channel.iChannel;\n\n while (true) {\n if (channel.count >= 0) {\n let b;\n let addr = (channel.bPage << 16) | (channel.addrCurrent[1] << 8) | channel.addrCurrent[0];\n if (DEBUG && DEBUGGER && channel.sAddrDebug === null) {\n channel.sAddrDebug = Str.toHex(addr >> 4, 4) + \":\" + Str.toHex(addr & 0xf, 4);\n if (this.messageEnabled(this.messageBitsDMA(iDMAChannel)) && channel.type != ChipSet.DMA_MODE.TYPE_WRITE) {\n this.printMessage(\"advanceDMA(\" + iDMAChannel + \") transferring \" + channel.cbDebug + \" bytes from \" + channel.sAddrDebug, true);\n this.dbg.doDump([\"db\", channel.sAddrDebug, 'l', channel.cbDebug]);\n }\n }\n if (channel.type == ChipSet.DMA_MODE.TYPE_WRITE) {\n fAsyncRequest = true;\n (function advanceDMAWrite(addrCur) {\n channel.fnTransfer.call(channel.component, channel.obj, -1, function onTransferDMA(b, fAsync, obj, off) {\n if (b < 0) {\n if (!channel.fWarning) {\n if (DEBUG && chipset.messageEnabled(Messages.DMA)) {\n chipset.printMessage(\"advanceDMA(\" + iDMAChannel + \") ran out of data, assuming 0xff\", true);\n }\n channel.fWarning = true;\n }\n /*\n * TODO: Determine whether to abort, as we do for DMA_MODE.TYPE_READ.\n */\n b = 0xff;\n }\n if (!channel.masked) {\n chipset.bus.setByte(addrCur, b);\n /*\n * WARNING: Do NOT assume that obj is valid; if the sector data was not found, there will be no obj.\n */\n if (BACKTRACK && obj) {\n if (!off && obj.file) {\n if (chipset.messageEnabled(Messages.DISK)) {\n chipset.printMessage(\"loading \" + obj.file.sPath + '[' + obj.offFile + \"] at %\" + Str.toHex(addrCur), true);\n }\n /*\n if (obj.file.sPath == \"\\\\SYSBAS.EXE\" && obj.offFile == 512) {\n chipset.cpu.stopCPU();\n }\n */\n }\n bto = chipset.bus.addBackTrackObject(obj, bto, off);\n chipset.bus.writeBackTrackObject(addrCur, bto, off);\n }\n }\n fAsyncRequest = fAsync;\n if (fAsync) {\n setTimeout(function() {\n if (!chipset.updateDMA(channel)) chipset.advanceDMA(channel);\n }, 0);\n }\n });\n }(addr));\n }\n else if (channel.type == ChipSet.DMA_MODE.TYPE_READ) {\n /*\n * TODO: Determine whether we should support async dmaWrite() functions (currently not required)\n */\n b = chipset.bus.getByte(addr);\n if (channel.fnTransfer.call(channel.component, channel.obj, b) < 0) {\n /*\n * In this case, I think I have no choice but to terminate the DMA operation in response to a failure,\n * because the ROM BIOS FDC.REG_DATA.CMD.FORMAT_TRACK command specifies a count that is MUCH too large\n * (a side-effect of the ROM BIOS using the same \"DMA_SETUP\" code for reads, writes AND formats).\n */\n channel.fError = true;\n }\n }\n else if (channel.type == ChipSet.DMA_MODE.TYPE_VERIFY) {\n /*\n * Nothing to read or write; just call updateDMA()\n */\n }\n else {\n if (DEBUG && this.messageEnabled(Messages.DMA | Messages.WARN)) {\n this.printMessage(\"advanceDMA(\" + iDMAChannel + \") unsupported transfer type: \" + Str.toHexWord(channel.type), true);\n }\n channel.fError = true;\n }\n }\n if (fAsyncRequest || this.updateDMA(channel)) break;\n }\n }\n\n /**\n * updateDMA(channel)\n *\n * @this {ChipSet}\n * @param {Object} channel\n * @return {boolean} true if DMA operation complete, false if not\n */\n updateDMA(channel)\n {\n if (!channel.fError && --channel.count >= 0) {\n if (channel.mode & ChipSet.DMA_MODE.DECREMENT) {\n channel.addrCurrent[0]--;\n if (channel.addrCurrent[0] < 0) {\n channel.addrCurrent[0] = 0xff;\n channel.addrCurrent[1]--;\n if (channel.addrCurrent[1] < 0) channel.addrCurrent[1] = 0xff;\n }\n } else {\n channel.addrCurrent[0]++;\n if (channel.addrCurrent[0] > 0xff) {\n channel.addrCurrent[0] = 0x00;\n channel.addrCurrent[1]++;\n if (channel.addrCurrent[1] > 0xff) channel.addrCurrent[1] = 0x00;\n }\n }\n /*\n * In situations where an HDC DMA operation took too long, the Fixed Disk BIOS would give up, but the DMA operation would continue.\n *\n * TODO: Verify that the Fixed Disk BIOS shuts down (ie, re-masks) a DMA channel for failed requests, and that this handles those failures.\n */\n if (!channel.masked) return false;\n }\n\n let controller = channel.controller;\n let iDMAChannel = controller.nChannelBase + channel.iChannel;\n controller.bStatus = (controller.bStatus & ~(0x10 << channel.iChannel)) | (0x1 << channel.iChannel);\n\n /*\n * EOP is supposed to automatically (re)mask the channel, unless it's set for auto-initialize.\n */\n if (!(channel.mode & ChipSet.DMA_MODE.AUTOINIT)) {\n channel.masked = true;\n channel.component = channel.obj = null;\n }\n\n if (DEBUG && this.messageEnabled(this.messageBitsDMA(iDMAChannel)) && channel.type == ChipSet.DMA_MODE.TYPE_WRITE && channel.sAddrDebug) {\n this.printMessage(\"updateDMA(\" + iDMAChannel + \") transferred \" + channel.cbDebug + \" bytes to \" + channel.sAddrDebug, true);\n this.dbg.doDump([\"db\", channel.sAddrDebug, 'l', channel.cbDebug]);\n }\n\n if (channel.done) {\n channel.done(!channel.fError);\n channel.done = null;\n }\n\n /*\n * While it might make sense to call cpu.setDMA() here, it's simpler to let the CPU issue one more call\n * to chipset.checkDMA() and let the CPU update INTR.DMA on its own, based on the return value from checkDMA().\n */\n return true;\n }\n\n /**\n * inPICLo(iPIC, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iPIC\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inPICLo(iPIC, addrFrom)\n {\n let b = 0;\n let pic = this.aPICs[iPIC];\n if (pic.bOCW3 != null) {\n let bReadReg = pic.bOCW3 & ChipSet.PIC_LO.OCW3_READ_CMD;\n switch (bReadReg) {\n case ChipSet.PIC_LO.OCW3_READ_IRR:\n b = pic.bIRR;\n break;\n case ChipSet.PIC_LO.OCW3_READ_ISR:\n b = pic.bISR;\n break;\n default:\n break;\n }\n }\n if (this.messageEnabled(Messages.PIC | Messages.PORT)) {\n this.printMessageIO(pic.port, null, addrFrom, \"PIC\" + iPIC, b, true);\n }\n return b;\n }\n\n /**\n * outPICLo(iPIC, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iPIC\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outPICLo(iPIC, bOut, addrFrom)\n {\n let pic = this.aPICs[iPIC];\n if (this.messageEnabled(Messages.PIC | Messages.PORT)) {\n this.printMessageIO(pic.port, bOut, addrFrom, \"PIC\" + iPIC, null, true);\n }\n if (bOut & ChipSet.PIC_LO.ICW1) {\n /*\n * This must be an ICW1...\n */\n pic.nICW = 0;\n pic.aICW[pic.nICW++] = bOut;\n /*\n * I used to do the rest of this initialization in outPICHi(), once all the ICW commands had been received,\n * but a closer reading of the 8259A spec indicates that that should happen now, on receipt on ICW1.\n *\n * Also, on p.10 of that spec, it says \"The Interrupt Mask Register is cleared\". I originally took that to\n * mean that all interrupts were masked, but based on what MS-DOS 4.0M expects to happen after this code runs:\n *\n * 0070:44C6 B013 MOV AL,13\n * 0070:44C8 E620 OUT 20,AL\n * 0070:44CA B050 MOV AL,50\n * 0070:44CC E621 OUT 21,AL\n * 0070:44CE B009 MOV AL,09\n * 0070:44D0 E621 OUT 21,AL\n *\n * (ie, it expects its next call to INT 0x13 will still generate an interrupt), I've decided the spec\n * must be read literally, meaning that all IMR bits must be zeroed. Unmasking all possible interrupts by\n * default seems unwise to me, but who am I to judge....\n */\n pic.bIMR = 0x00;\n pic.bIRLow = 7;\n /*\n * TODO: I'm also zeroing both IRR and ISR, even though that's not actually mentioned as part of the ICW\n * sequence, because they need to be (re)initialized at some point. However, if some component is currently\n * requesting an interrupt, what should I do about that? Originally, I had decided to clear them ONLY if they\n * were still undefined, but that change appeared to break the ROM BIOS handling of CTRL-ALT-DEL, so I'm back\n * to unconditionally zeroing them.\n */\n pic.bIRR = pic.bISR = 0;\n /*\n * The spec also says that \"Special Mask Mode is cleared and Status Read is set to IRR\". I attempt to insure\n * the latter, but as for special mask mode... well, that mode isn't supported yet.\n */\n pic.bOCW3 = ChipSet.PIC_LO.OCW3 | ChipSet.PIC_LO.OCW3_READ_IRR;\n }\n else if (!(bOut & ChipSet.PIC_LO.OCW3)) {\n /*\n * This must be an OCW2...\n */\n let bOCW2 = bOut & ChipSet.PIC_LO.OCW2_OP_MASK;\n if (bOCW2 & ChipSet.PIC_LO.OCW2_EOI) {\n /*\n * This OCW2 must be an EOI command...\n */\n let nIRL, bIREnd = 0;\n if ((bOCW2 & ChipSet.PIC_LO.OCW2_EOI_SPEC) == ChipSet.PIC_LO.OCW2_EOI_SPEC) {\n /*\n * More \"specifically\", a specific EOI command...\n */\n nIRL = bOut & ChipSet.PIC_LO.OCW2_IR_LVL;\n bIREnd = 1 << nIRL;\n } else {\n /*\n * Less \"specifically\", a non-specific EOI command. The search for the highest priority in-service\n * interrupt must start with whichever interrupt is opposite the lowest priority interrupt (normally 7,\n * but technically whatever bIRLow is currently set to). For example:\n *\n * If bIRLow is 7, then the priority order is: 0, 1, 2, 3, 4, 5, 6, 7.\n * If bIRLow is 6, then the priority order is: 7, 0, 1, 2, 3, 4, 5, 6.\n * If bIRLow is 5, then the priority order is: 6, 7, 0, 1, 2, 3, 4, 5.\n * etc.\n */\n nIRL = pic.bIRLow + 1;\n while (true) {\n nIRL &= 0x7;\n let bIR = 1 << nIRL;\n if (pic.bISR & bIR) {\n bIREnd = bIR;\n break;\n }\n if (nIRL++ == pic.bIRLow) break;\n }\n if (DEBUG && !bIREnd) nIRL = null; // for unexpected non-specific EOI commands, there's no IRQ to report\n }\n let nIRQ = (nIRL == null? undefined : pic.nIRQBase + nIRL);\n if (pic.bISR & bIREnd) {\n if (DEBUG && this.messageEnabled(this.messageBitsIRQ(nIRQ))) {\n this.printMessage(\"outPIC\" + iPIC + '(' + Str.toHexByte(pic.port) + \"): IRQ \" + nIRQ + \" ending @\" + this.dbg.toHexOffset(this.cpu.getIP(), this.cpu.getCS()) + \" stack=\" + this.dbg.toHexOffset(this.cpu.getSP(), this.cpu.getSS()), true);\n }\n pic.bISR &= ~bIREnd;\n this.checkIRR();\n } else {\n if (DEBUG && this.messageEnabled(Messages.PIC | Messages.WARN)) {\n this.printMessage(\"outPIC\" + iPIC + '(' + Str.toHexByte(pic.port) + \"): unexpected EOI for IRQ \" + nIRQ, true, true);\n if (MAXDEBUG) this.dbg.stopCPU();\n }\n }\n /*\n * TODO: Support EOI commands with automatic rotation (eg, ChipSet.PIC_LO.OCW2_EOI_ROT and ChipSet.PIC_LO.OCW2_EOI_ROTSPEC)\n */\n if (bOCW2 & ChipSet.PIC_LO.OCW2_SET_ROTAUTO) {\n if (this.messageEnabled(Messages.PIC | Messages.WARN)) {\n this.printMessage(\"PIC\" + iPIC + '(' + Str.toHexByte(pic.port) + \"): unsupported OCW2 rotate \" + Str.toHexByte(bOut), true, true);\n }\n }\n }\n else if (bOCW2 == ChipSet.PIC_LO.OCW2_SET_PRI) {\n /*\n * This OCW2 changes the lowest priority interrupt to the specified level (the default is 7)\n */\n pic.bIRLow = bOut & ChipSet.PIC_LO.OCW2_IR_LVL;\n }\n else {\n /*\n * TODO: Remaining commands to support: ChipSet.PIC_LO.OCW2_SET_ROTAUTO and ChipSet.PIC_LO.OCW2_CLR_ROTAUTO\n */\n if (this.messageEnabled(Messages.PIC | Messages.WARN)) {\n this.printMessage(\"PIC\" + iPIC + '(' + Str.toHexByte(pic.port) + \"): unsupported OCW2 automatic EOI \" + Str.toHexByte(bOut), true, true);\n }\n }\n } else {\n /*\n * This must be an OCW3 request. If it's a \"Read Register\" command (PIC_LO.OCW3_READ_CMD), inPICLo() will take care it.\n *\n * TODO: If OCW3 specified a \"Poll\" command (PIC_LO.OCW3_POLL_CMD) or a \"Special Mask Mode\" command (PIC_LO.OCW3_SMM_CMD),\n * that's unfortunate, because I don't support them yet.\n */\n if (bOut & (ChipSet.PIC_LO.OCW3_POLL_CMD | ChipSet.PIC_LO.OCW3_SMM_CMD)) {\n if (this.messageEnabled(Messages.PIC | Messages.WARN)) {\n this.printMessage(\"PIC\" + iPIC + '(' + Str.toHexByte(pic.port) + \"): unsupported OCW3 \" + Str.toHexByte(bOut), true, true);\n }\n }\n pic.bOCW3 = bOut;\n }\n }\n\n /**\n * inPICHi(iPIC, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iPIC\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inPICHi(iPIC, addrFrom)\n {\n let pic = this.aPICs[iPIC];\n let b = pic.bIMR;\n if (this.messageEnabled(Messages.PIC | Messages.PORT)) {\n this.printMessageIO(pic.port+1, null, addrFrom, \"PIC\" + iPIC, b, true);\n }\n return b;\n }\n\n /**\n * outPICHi(iPIC, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iPIC\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outPICHi(iPIC, bOut, addrFrom)\n {\n let pic = this.aPICs[iPIC];\n if (this.messageEnabled(Messages.PIC | Messages.PORT)) {\n this.printMessageIO(pic.port+1, bOut, addrFrom, \"PIC\" + iPIC, null, true);\n }\n if (pic.nICW < pic.aICW.length) {\n pic.aICW[pic.nICW++] = bOut;\n if (pic.nICW == 2 && (pic.aICW[0] & ChipSet.PIC_LO.ICW1_SNGL))\n pic.nICW++;\n if (pic.nICW == 3 && !(pic.aICW[0] & ChipSet.PIC_LO.ICW1_ICW4))\n pic.nICW++;\n }\n else {\n /*\n * We have all our ICW \"words\" (ie, bytes), so this must be an OCW1 write (which is simply an IMR write)\n */\n pic.bIMR = bOut;\n /*\n * See the CPU's delayINTR() function for an explanation of why this explicit delay is necessary.\n */\n this.cpu.delayINTR();\n /*\n * Alas, we need a longer delay for the MODEL_5170's \"KBD_RESET\" function (F000:17D2), which must drop\n * into a loop and decrement CX at least once after unmasking the KBD IRQ. The \"KBD_RESET\" function on\n * previous models could be handled with a 4-instruction delay provided by the Keyboard.resetDevice() call\n * to setIRR(), but the MODEL_5170 needs a roughly 6-instruction delay after it unmasks the KBD IRQ.\n */\n this.checkIRR(!iPIC && bOut == 0xFD? 6 : 0);\n }\n }\n\n /**\n * checkIMR(nIRQ)\n *\n * @this {ChipSet}\n * @param {number} nIRQ\n * @return {boolean} true if the specified IRQ is masked, false if not\n */\n checkIMR(nIRQ)\n {\n let iPIC = nIRQ >> 3;\n let nIRL = nIRQ & 0x7;\n let pic = this.aPICs[iPIC];\n return !!(pic.bIMR & (0x1 << nIRL));\n }\n\n /**\n * setIRR(nIRQ, nDelay)\n *\n * @this {ChipSet}\n * @param {number} nIRQ (IRQ 0-7 implies iPIC 0, and IRQ 8-15 implies iPIC 1)\n * @param {number} [nDelay] is an optional number of instructions to delay acknowledgment of the IRQ (see getIRRVector)\n */\n setIRR(nIRQ, nDelay)\n {\n let iPIC = nIRQ >> 3;\n let nIRL = nIRQ & 0x7;\n let pic = this.aPICs[iPIC];\n let bIRR = (1 << nIRL);\n if (!(pic.bIRR & bIRR)) {\n pic.bIRR |= bIRR;\n if (this.messageEnabled(this.messageBitsIRQ(nIRQ))) this.printMessage(\"set IRQ \" + nIRQ, true);\n pic.nDelay = nDelay || 0;\n this.checkIRR();\n }\n }\n\n /**\n * clearIRR(nIRQ)\n *\n * @this {ChipSet}\n * @param {number} nIRQ (IRQ 0-7 implies iPIC 0, and IRQ 8-15 implies iPIC 1)\n */\n clearIRR(nIRQ)\n {\n let iPIC = nIRQ >> 3;\n let nIRL = nIRQ & 0x7;\n let pic = this.aPICs[iPIC];\n let bIRR = (1 << nIRL);\n if (pic.bIRR & bIRR) {\n pic.bIRR &= ~bIRR;\n if (this.messageEnabled(this.messageBitsIRQ(nIRQ))) this.printMessage(\"clear IRQ \" + nIRQ, true);\n this.checkIRR();\n }\n }\n\n /**\n * checkIRR(nDelay)\n *\n * @this {ChipSet}\n * @param {number} [nDelay] is an optional number of instructions to delay acknowledgment of a pending interrupt\n */\n checkIRR(nDelay)\n {\n /*\n * Look for any IRR bits that aren't masked and aren't already in service; in theory, all we'd have to\n * check is the master PIC (which is the *only* PIC on pre-5170 models), because when any IRQs are set or\n * cleared on the slave, that would automatically be reflected in IRQ.SLAVE on the master; that's what\n * setIRR() and clearIRR() used to do.\n *\n * Unfortunately, despite setIRR() and clearIRR()'s efforts, whenever a slave interrupt is acknowledged,\n * getIRRVector() ends up clearing the IRR bits for BOTH the slave's IRQ and the master's IRQ.SLAVE.\n * So if another lower-priority slave IRQ is waiting to be dispatched, that fact is no longer reflected\n * in IRQ.SLAVE.\n *\n * Since checkIRR() is called on every EOI, we can resolve that problem here, by first checking the slave\n * PIC for any unmasked, unserviced interrupts and updating the master's IRQ.SLAVE.\n *\n * And since this is ALSO called by both setIRR() and clearIRR(), those functions no longer need to perform\n * their own IRQ.SLAVE updates. This function consolidates the propagation of slave interrupts to the master.\n */\n let pic;\n let bIR = -1;\n\n if (this.cPICs > 1) {\n pic = this.aPICs[1];\n bIR = ~(pic.bISR | pic.bIMR) & pic.bIRR;\n }\n\n pic = this.aPICs[0];\n\n if (bIR >= 0) {\n if (bIR) {\n pic.bIRR |= (1 << ChipSet.IRQ.SLAVE);\n } else {\n pic.bIRR &= ~(1 << ChipSet.IRQ.SLAVE);\n }\n }\n\n bIR = ~(pic.bISR | pic.bIMR) & pic.bIRR;\n\n this.cpu.updateINTR(!!bIR);\n\n if (bIR && nDelay) pic.nDelay = nDelay;\n }\n\n /**\n * getIRRVector()\n *\n * getIRRVector() is called by the CPU whenever PS_IF is set and OP_NOINTR is clear. Ordinarily, an immediate\n * response would seem perfectly reasonable, but unfortunately, there are places in the original ROM BIOS like\n * \"KBD_RESET\" (F000:E688) that enable interrupts but still expect nothing to happen for several more instructions.\n *\n * So, in addition to the two normal responses (an IDT vector #, or -1 indicating no pending interrupts), we must\n * support a third response (-2) that basically means: don't change the CPU interrupt state, just keep calling until\n * we return one of the first two responses. The number of times we delay our normal response is determined by the\n * component that originally called setIRR with an optional delay parameter.\n *\n * @this {ChipSet}\n * @param {number} [iPIC]\n * @return {number} IDT vector # of the next highest-priority interrupt, -1 if none, or -2 for \"please try your call again later\"\n */\n getIRRVector(iPIC)\n {\n if (iPIC === undefined) iPIC = 0;\n\n /*\n * Look for any IRR bits that aren't masked and aren't already in service...\n */\n let nIDT = -1;\n let pic = this.aPICs[iPIC];\n if (!pic.nDelay) {\n let bIR = pic.bIRR & ((pic.bISR | pic.bIMR) ^ 0xff);\n /*\n * The search for the next highest priority requested interrupt (that's also not in-service and not masked)\n * must start with whichever interrupt is opposite the lowest priority interrupt (normally 7, but technically\n * whatever bIRLow is currently set to). For example:\n *\n * If bIRLow is 7, then the priority order is: 0, 1, 2, 3, 4, 5, 6, 7.\n * If bIRLow is 6, then the priority order is: 7, 0, 1, 2, 3, 4, 5, 6.\n * If bIRLow is 5, then the priority order is: 6, 7, 0, 1, 2, 3, 4, 5.\n * etc.\n *\n * This process is similar to the search performed by non-specific EOIs, except those apply only to a single\n * PIC (which is why a slave interrupt must be EOI'ed twice: once for the slave PIC and again for the master),\n * whereas here we must search across all PICs.\n */\n let nIRL = pic.bIRLow + 1;\n while (true) {\n\n nIRL &= 0x7;\n let bIRNext = 1 << nIRL;\n\n /*\n * If we encounter an interrupt that's still in-service BEFORE we encounter a requested interrupt,\n * then we're done; we must allow a higher priority in-service interrupt to finish before acknowledging\n * any lower priority interrupts.\n */\n if (pic.bISR & bIRNext) break;\n\n if (bIR & bIRNext) {\n\n if (!iPIC && nIRL == ChipSet.IRQ.SLAVE) {\n /*\n * Slave interrupts are tied to the master PIC on IRQ2; query the slave PIC for the vector #\n */\n nIDT = this.getIRRVector(1);\n } else {\n /*\n * Get the starting IDT vector # from ICW2 and add the IR level to obtain the target IDT vector #\n */\n nIDT = pic.aICW[1] + nIRL;\n }\n\n if (nIDT >= 0) {\n pic.bISR |= bIRNext;\n\n /*\n * Setting the ISR implies clearing the IRR, but clearIRR() has side-effects we don't want\n * (eg, clearing the slave IRQ, notifying the CPU, etc), so we clear the IRR ourselves.\n */\n pic.bIRR &= ~bIRNext;\n\n let nIRQ = pic.nIRQBase + nIRL;\n if (DEBUG && this.messageEnabled(this.messageBitsIRQ(nIRQ))) {\n this.printMessage(\"getIRRVector(): IRQ \" + nIRQ + \" interrupting stack \" + this.dbg.toHexOffset(this.cpu.getSP(), this.cpu.getSS()), true, true);\n }\n if (MAXDEBUG && DEBUGGER) {\n this.acInterrupts[nIRQ]++;\n }\n }\n break;\n }\n\n if (nIRL++ == pic.bIRLow) break;\n }\n } else {\n nIDT = -2;\n pic.nDelay--;\n }\n return nIDT;\n }\n\n /**\n * setFPUInterrupt()\n *\n * @this {ChipSet}\n */\n setFPUInterrupt()\n {\n if (this.model >= ChipSet.MODEL_5170) {\n this.setIRR(ChipSet.IRQ.FPU);\n } else {\n /*\n * TODO: Determine whether we need to maintain an \"Active NMI\" state; ie, if NMI.DISABLE is cleared\n * later, and the FPU coprocessor is still indicating an error condition, should we then generate an NMI?\n */\n if (this.bNMI & ChipSet.NMI.ENABLE) {\n X86.helpInterrupt.call(this.cpu, X86.EXCEPTION.NMI);\n }\n }\n }\n\n /**\n * clearFPUInterrupt(fSet)\n *\n * @this {ChipSet}\n */\n clearFPUInterrupt()\n {\n if (this.model >= ChipSet.MODEL_5170) {\n this.clearIRR(ChipSet.IRQ.FPU);\n } else {\n /*\n * TODO: If we maintain an \"Active NMI\" state, then we will need code here to clear that state, as well\n * as code in outNMI() to clear that state and generate an NMI as needed.\n */\n }\n }\n\n /**\n * inTimer(iPIT, iPITTimer, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iPIT (0 or 1)\n * @param {number} iPITTimer (0, 1, or 2)\n * @param {number} port (0x40, 0x41, 0x42, etc)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inTimer(iPIT, iPITTimer, port, addrFrom)\n {\n let b;\n let iBaseTimer = (iPIT? 3 : 0);\n let timer = this.aTimers[iBaseTimer + iPITTimer];\n\n if (timer.fStatusLatched) {\n b = timer.bStatus;\n timer.fStatusLatched = false;\n }\n else {\n if (timer.countIndex == timer.countBytes) {\n this.resetTimerIndex(iBaseTimer + iPITTimer);\n }\n if (timer.fCountLatched) {\n b = timer.countLatched[timer.countIndex++];\n if (timer.countIndex == timer.countBytes) {\n timer.fCountLatched = false\n }\n }\n else {\n this.updateTimer(iBaseTimer + iPITTimer);\n b = timer.countCurrent[timer.countIndex++];\n }\n }\n if (this.messageEnabled(Messages.TIMER | Messages.PORT)) {\n this.printMessageIO(port, null, addrFrom, \"PIT\" + iPIT + \".TIMER\" + iPITTimer, b, true);\n }\n return b;\n }\n\n /**\n * outTimer(iPIT, iPITTimer, port, bOut, addrFrom)\n *\n * We now rely EXCLUSIVELY on setBurstCycles() to address situations where quick timer interrupt turn-around\n * is expected; eg, by the ROM BIOS POST when it sets TIMER0 to a low test count (0x16); since we typically\n * don't update any of the timers until after we've finished a burst of CPU cycles, we must reduce the current\n * burst cycle count, so that the current instruction burst will end at the same time a timer interrupt is expected.\n *\n * Note that in some cases, if the number of cycles remaining in the current burst is less than the target,\n * this may have the effect of *lengthening* the current burst instead of shortening it, but stepCPU() should be\n * OK with that.\n *\n * @this {ChipSet}\n * @param {number} iPIT (0 or 1)\n * @param {number} iPITTimer (0, 1, or 2)\n * @param {number} port (0x40, 0x41, 0x42, etc)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outTimer(iPIT, iPITTimer, port, bOut, addrFrom)\n {\n if (this.messageEnabled(Messages.TIMER | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"PIT\" + iPIT + \".TIMER\" + iPITTimer, null, true);\n }\n\n let iBaseTimer = (iPIT? 3 : 0);\n let timer = this.aTimers[iBaseTimer + iPITTimer];\n\n if (timer.countIndex == timer.countBytes) {\n this.resetTimerIndex(iBaseTimer + iPITTimer);\n }\n\n timer.countInit[timer.countIndex++] = bOut;\n\n if (timer.countIndex == timer.countBytes) {\n /*\n * In general, writing a new count to a timer that's already counting isn't supposed to affect the current\n * count, with the notable exceptions of MODE0 and MODE4.\n */\n if (!timer.fCounting || timer.mode == ChipSet.PIT_CTRL.MODE0 || timer.mode == ChipSet.PIT_CTRL.MODE4) {\n timer.fCountLatched = false;\n timer.countCurrent[0] = timer.countStart[0] = timer.countInit[0];\n timer.countCurrent[1] = timer.countStart[1] = timer.countInit[1];\n timer.nCyclesStart = this.cpu.getCycles(this.fScaleTimers);\n timer.fCounting = true;\n\n /*\n * I believe MODE0 is the only mode where OUT (fOUT) starts out low (false); for the rest of the modes,\n * OUT (fOUT) starts high (true). It's also my understanding that the way edge-triggered interrupts work\n * on the original PC is that an interrupt is requested only when the corresponding OUT transitions from\n * low to high.\n */\n timer.fOUT = (timer.mode != ChipSet.PIT_CTRL.MODE0);\n\n if (iPIT == ChipSet.PIT0.INDEX && iPITTimer == ChipSet.PIT0.TIMER0) {\n /*\n * TODO: Determine if there are situations/modes where I should NOT automatically clear IRQ0 on behalf of TIMER0.\n */\n this.clearIRR(ChipSet.IRQ.TIMER0);\n let countInit = this.getTimerInit(ChipSet.PIT0.TIMER0);\n let nCyclesRemain = (countInit * this.nTicksDivisor) | 0;\n if (timer.mode == ChipSet.PIT_CTRL.MODE3) nCyclesRemain >>= 1;\n this.cpu.setBurstCycles(nCyclesRemain);\n }\n }\n\n if (iPIT == ChipSet.PIT0.INDEX && iPITTimer == ChipSet.PIT0.TIMER2) this.setSpeaker();\n }\n }\n\n /**\n * inTimerCtrl(iPIT, port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iPIT (0 or 1)\n * @param {number} port (0x43 or 0x4B)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number|null} simulated port value\n */\n inTimerCtrl(iPIT, port, addrFrom)\n {\n this.printMessageIO(port, null, addrFrom, \"PIT\" + iPIT + \".CTRL\", null, Messages.TIMER);\n /*\n * NOTE: Even though reads to port 0x43 are undefined (I think), I'm going to \"define\" it\n * as returning the last value written, purely for the Debugger's benefit.\n */\n return iPIT? this.bPIT1Ctrl : this.bPIT0Ctrl;\n }\n\n /**\n * outTimerCtrl(iPIT, port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iPIT (0 or 1)\n * @param {number} port (0x43)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outTimerCtrl(iPIT, port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"PIT\" + iPIT + \".CTRL\", null, Messages.TIMER);\n\n /*\n * Extract the SC (Select Counter) bits.\n */\n let iBaseTimer = 0;\n let iPITTimer = (bOut & ChipSet.PIT_CTRL.SC);\n if (!iPIT) {\n this.bPIT0Ctrl = bOut;\n } else {\n iBaseTimer = 3;\n this.bPIT1Ctrl = bOut;\n }\n\n /*\n * Check for the Read-Back command and process as needed.\n */\n if (iPITTimer == ChipSet.PIT_CTRL.SC_BACK) {\n if (!(bOut & ChipSet.PIT_CTRL.RB_STATUS)) {\n for (iPITTimer = 0; iPITTimer <= 2; iPITTimer++) {\n if (bOut & (ChipSet.PIT_CTRL.RB_CTR0 << iPITTimer)) {\n this.latchTimerStatus(iBaseTimer + iPITTimer);\n }\n }\n }\n if (!(bOut & ChipSet.PIT_CTRL.RB_COUNTS)) {\n for (iPITTimer = 0; iPITTimer <= 2; iPITTimer++) {\n if (bOut & (ChipSet.PIT_CTRL.RB_CTR0 << iPITTimer)) {\n this.latchTimerCount(iBaseTimer + iPITTimer);\n }\n }\n }\n return;\n }\n\n /*\n * Convert the SC (Select Counter) bits into an iPITTimer index (0-2).\n */\n iPITTimer >>= ChipSet.PIT_CTRL.SC_SHIFT;\n\n /*\n * Extract BCD (bit 0), MODE (bits 1-3), and RW (bits 4-5), which we simply store as-is (see setTimerMode).\n */\n let bcd = (bOut & ChipSet.PIT_CTRL.BCD);\n let mode = (bOut & ChipSet.PIT_CTRL.MODE);\n let rw = (bOut & ChipSet.PIT_CTRL.RW);\n\n if (rw == ChipSet.PIT_CTRL.RW_LATCH) {\n /*\n * Of all the RW bit combinations, this is the only one that \"countermands\" normal control register\n * processing (the BCD and MODE bits are \"don't care\").\n */\n this.latchTimerCount(iBaseTimer + iPITTimer);\n }\n else {\n this.setTimerMode(iBaseTimer + iPITTimer, bcd, mode, rw);\n\n /*\n * The 5150 ROM BIOS code @F000:E285 (\"TEST.7\") would fail after a warm boot (eg, after a CTRL-ALT-DEL) because\n * it assumed that no TIMER0 interrupt would occur between the point it unmasked the TIMER0 interrupt and the\n * point it started reprogramming TIMER0.\n *\n * Similarly, the 5160 ROM BIOS @F000:E35D (\"8253 TIMER CHECKOUT\") would fail after initializing the EGA BIOS,\n * because the EGA BIOS uses TIMER0 during its diagnostics; as in the previous example, by the time the 8253\n * test code runs later, there's now a pending TIMER0 interrupt, which triggers an interrupt as soon as IRQ0 is\n * unmasked @F000:E364.\n *\n * After looking at this problem at bit more closely the second time around (while debugging the EGA BIOS),\n * it turns out I missed an important 8253 feature: whenever a new MODE0 control word OR a new MODE0 count\n * is written, fOUT (which is what drives IRQ0) goes low. So, by simply adding an appropriate clearIRR() call\n * both here and in outTimer(), this annoying problem seems to be gone.\n *\n * TODO: Determine if there are situations/modes where I should NOT automatically clear IRQ0 on behalf of TIMER0.\n */\n if (iPIT == ChipSet.PIT0.INDEX && iPITTimer == ChipSet.PIT0.TIMER0) this.clearIRR(ChipSet.IRQ.TIMER0);\n\n /*\n * Another TIMER0 HACK: The \"CASSETTE DATA WRAP TEST\" @F000:E51E occasionally reports an error when the second of\n * two TIMER0 counts it latches is greater than the first. You would think the ROM BIOS would expect this, since\n * TIMER0 can reload its count at any time. Is the ROM BIOS assuming that TIMER0 was initialized sufficiently\n * recently that this should never happen? I'm not sure, but for now, let's try resetting TIMER0's count immediately\n * after TIMER2 has been reprogrammed for the test in question (ie, when interrupts are masked and PPIB is set as\n * shown below).\n *\n * FWIW, I believe the cassette hardware was discontinued after MODEL_5150, and even if the test fails, it's non-fatal;\n * the ROM BIOS displays an error (131) and moves on.\n */\n if (iPIT == ChipSet.PIT0.INDEX && iPITTimer == ChipSet.PIT0.TIMER2) {\n let pic = this.aPICs[0];\n if (pic.bIMR == 0xff && this.bPPIB == (ChipSet.PPI_B.CLK_TIMER2 | ChipSet.PPI_B.ENABLE_SW2 | ChipSet.PPI_B.CASS_MOTOR_OFF | ChipSet.PPI_B.CLK_KBD)) {\n let timer = this.aTimers[0];\n timer.countStart[0] = timer.countInit[0];\n timer.countStart[1] = timer.countInit[1];\n timer.nCyclesStart = this.cpu.getCycles(this.fScaleTimers);\n if (DEBUG && this.messageEnabled(Messages.TIMER)) {\n this.printMessage(\"PIT0.TIMER0 count reset @\" + timer.nCyclesStart + \" cycles\", true);\n }\n }\n }\n }\n }\n\n /**\n * getTimerInit(iTimer)\n *\n * @this {ChipSet}\n * @param {number} iTimer\n * @return {number} initial timer count\n */\n getTimerInit(iTimer)\n {\n let timer = this.aTimers[iTimer];\n let countInit = (timer.countInit[1] << 8) | timer.countInit[0];\n if (!countInit) countInit = (timer.countBytes == 1? 0x100 : 0x10000);\n return countInit;\n }\n\n /**\n * getTimerStart(iTimer)\n *\n * @this {ChipSet}\n * @param {number} iTimer\n * @return {number} starting timer count (from the initial timer count for the current countdown)\n */\n getTimerStart(iTimer)\n {\n let timer = this.aTimers[iTimer];\n let countStart = (timer.countStart[1] << 8) | timer.countStart[0];\n if (!countStart) countStart = (timer.countBytes == 1? 0x100 : 0x10000);\n return countStart;\n }\n\n /**\n * getTimerCycleLimit(iTimer, nCycles)\n *\n * This is called by the CPU to determine the maximum number of cycles it can process for the current burst.\n * It's presumed that no instructions have been executed since the last updateTimer(iTimer) call.\n *\n * @this {ChipSet}\n * @param {number} iTimer\n * @param {number} nCycles desired\n * @return {number} maximum number of cycles remaining for the specified timer (<= nCycles)\n */\n getTimerCycleLimit(iTimer, nCycles)\n {\n let timer = this.aTimers[iTimer];\n if (timer.fCounting) {\n let nCyclesUpdate = this.cpu.getCycles(this.fScaleTimers);\n let ticksElapsed = ((nCyclesUpdate - timer.nCyclesStart) / this.nTicksDivisor) | 0;\n // DEBUG:\n let countStart = this.getTimerStart(iTimer);\n let count = countStart - ticksElapsed;\n if (timer.mode == ChipSet.PIT_CTRL.MODE3) count -= ticksElapsed;\n // DEBUG:\n let nCyclesRemain = (count * this.nTicksDivisor) | 0;\n if (timer.mode == ChipSet.PIT_CTRL.MODE3) nCyclesRemain >>= 1;\n if (nCycles > nCyclesRemain) nCycles = nCyclesRemain;\n }\n return nCycles;\n }\n\n /**\n * latchTimerCount(iTimer)\n *\n * @this {ChipSet}\n * @param {number} iTimer\n */\n latchTimerCount(iTimer)\n {\n /*\n * Update the timer's current count.\n */\n this.updateTimer(iTimer);\n\n /*\n * Now we can latch it.\n */\n let timer = this.aTimers[iTimer];\n timer.countLatched[0] = timer.countCurrent[0];\n timer.countLatched[1] = timer.countCurrent[1];\n timer.fCountLatched = true;\n\n /*\n * VERIFY: That a latch request resets the timer index.\n */\n this.resetTimerIndex(iTimer);\n }\n\n /**\n * latchTimerStatus(iTimer)\n *\n * @this {ChipSet}\n * @param {number} iTimer\n */\n latchTimerStatus(iTimer)\n {\n let timer = this.aTimers[iTimer];\n if (!timer.fStatusLatched) {\n this.updateTimer(iTimer);\n timer.bStatus = timer.bcd | timer.mode | timer.rw | (timer.countIndex < timer.countBytes? ChipSet.PIT_CTRL.RB_NULL : 0) | (timer.fOUT? ChipSet.PIT_CTRL.RB_OUT : 0);\n timer.fStatusLatched = true;\n }\n }\n\n /**\n * setTimerMode(iTimer, bcd, mode, rw)\n *\n * FYI: After setting a timer's mode, the CPU must set the timer's count before it becomes operational;\n * ie, before fCounting becomes true.\n *\n * @this {ChipSet}\n * @param {number} iTimer\n * @param {number} bcd\n * @param {number} mode\n * @param {number} rw\n */\n setTimerMode(iTimer, bcd, mode, rw)\n {\n let timer = this.aTimers[iTimer];\n timer.rw = rw;\n timer.mode = mode;\n timer.bcd = bcd;\n timer.countInit = [0, 0];\n timer.countCurrent = [0, 0];\n timer.countLatched = [0, 0];\n timer.fOUT = false;\n timer.fCountLatched = false;\n timer.fCounting = false;\n timer.fStatusLatched = false;\n this.resetTimerIndex(iTimer);\n }\n\n /**\n * resetTimerIndex(iTimer)\n *\n * @this {ChipSet}\n * @param {number} iTimer\n */\n resetTimerIndex(iTimer)\n {\n let timer = this.aTimers[iTimer];\n timer.countIndex = (timer.rw == ChipSet.PIT_CTRL.RW_MSB? 1 : 0);\n timer.countBytes = (timer.rw == ChipSet.PIT_CTRL.RW_BOTH? 2 : 1);\n }\n\n /**\n * updateTimer(iTimer, fCycleReset)\n *\n * updateTimer() calculates and updates a timer's current count purely on an \"on-demand\" basis; we don't\n * actually adjust timer counters every 4 CPU cycles on a 4.77Mhz PC, since updating timers that frequently\n * would be prohibitively slow. If you're single-stepping the CPU, then yes, updateTimer() will be called\n * after every stepCPU(), via updateAllTimers(), but if we're doing our job correctly here, the frequency\n * of calls to updateTimer() should not affect timer counts across otherwise identical runs.\n *\n * TODO: Implement support for all TIMER modes, and verify that all the modes currently implemented are\n * \"up to spec\"; they're close enough to make the ROM BIOS happy, but beyond that, I've done very little.\n *\n * @this {ChipSet}\n * @param {number} iTimer\n * 0: Time-of-Day interrupt (~18.2 interrupts/second)\n * 1: DMA refresh\n * 2: Sound/Cassette\n * @param {boolean} [fCycleReset] is true if a cycle-count reset is about to occur\n * @return {Object} timer\n */\n updateTimer(iTimer, fCycleReset)\n {\n let timer = this.aTimers[iTimer];\n\n /*\n * Every timer's counting state is gated by its own fCounting flag; TIMER2 is further gated by PPI_B's\n * CLK_TIMER2 bit.\n */\n if (timer.fCounting && (iTimer != ChipSet.PIT0.TIMER2 || (this.bPPIB & ChipSet.PPI_B.CLK_TIMER2))) {\n /*\n * We determine the current timer count based on how many instruction cycles have elapsed since we started\n * the timer. Timers are supposed to be \"ticking\" at a rate of 1193181.8181 times per second, which is\n * the system clock of 14.31818Mhz, divided by 12.\n *\n * Similarly, for an 8088, there are supposed to be 4.77Mhz instruction cycles per second, which comes from\n * the system clock of 14.31818Mhz, divided by 3.\n *\n * If we divide 4,772,727 CPU cycles per second by 1,193,181 ticks per second, we get 4 cycles per tick,\n * which agrees with the ratio of the clock divisors: 12 / 3 == 4.\n *\n * However, if getCycles() is being called with fScaleTimers == true AND the CPU is running faster than its\n * base cycles-per-second setting, then getCycles() will divide the cycle count by the CPU's cycle multiplier,\n * so that the timers fire with the same real-world frequency that the user expects. However, that will\n * break any code (eg, the ROM BIOS diagnostics) that assumes that the timers are ticking once every 4 cycles\n * (or more like every 5 cycles on a 6Mhz 80286).\n *\n * So, when using a machine with the ChipSet \"scaleTimers\" property set, make sure you reset the machine's\n * speed prior to rebooting, otherwise you're likely to see ROM BIOS errors. Ditto for any application code\n * that makes similar assumptions about the relationship between CPU and timer speeds.\n *\n * In general, you're probably better off NOT using the \"scaleTimers\" property, and simply allowing the timers\n * to tick faster as you increase CPU speed (which is why fScaleTimers defaults to false).\n */\n let nCycles = this.cpu.getCycles(this.fScaleTimers);\n\n /*\n * Instead of maintaining partial tick counts, we calculate a fresh countCurrent from countStart every\n * time we're called, using the cycle count recorded when the timer was initialized. countStart is set\n * to countInit when fCounting is first set, and then it is refreshed from countInit at the expiration of\n * every count, so that if someone loaded a new countInit in the meantime (eg, BASICA), we'll pick it up.\n *\n * For the original MODEL_5170, the number of cycles per tick is approximately 6,000,000 / 1,193,181,\n * or 5.028575, so we can no longer always divide cycles by 4 with a simple right-shift by 2. The proper\n * divisor (eg, 4 for MODEL_5150 and MODEL_5160, 5 for MODEL_5170, etc) is nTicksDivisor, which initBus()\n * calculates using the base CPU speed returned by cpu.getBaseCyclesPerSecond().\n */\n let ticksElapsed = ((nCycles - timer.nCyclesStart) / this.nTicksDivisor) | 0;\n\n if (ticksElapsed < 0) {\n if (DEBUG && this.messageEnabled(Messages.TIMER)) {\n this.printMessage(\"updateTimer(\" + iTimer + \"): negative tick count (\" + ticksElapsed + \")\", true);\n }\n timer.nCyclesStart = nCycles;\n ticksElapsed = 0;\n }\n\n let countInit = this.getTimerInit(iTimer);\n let countStart = this.getTimerStart(iTimer);\n\n let fFired = false;\n let count = countStart - ticksElapsed;\n\n /*\n * NOTE: This mode is used by ROM BIOS test code that wants to verify timer interrupts are arriving\n * neither too slowly nor too quickly. As a result, I've had to add some corresponding trickery\n * in outTimer() to force interrupt simulation immediately after a low initial count (0x16) has been set.\n */\n if (timer.mode == ChipSet.PIT_CTRL.MODE0) {\n if (count <= 0) count = 0;\n if (DEBUG && this.messageEnabled(Messages.TIMER)) {\n this.printMessage(\"updateTimer(\" + iTimer + \"): MODE0 timer count=\" + count, true);\n }\n if (!count) {\n timer.fOUT = true;\n timer.fCounting = false;\n if (!iTimer) {\n fFired = true;\n this.setIRR(ChipSet.IRQ.TIMER0);\n if (MAXDEBUG && DEBUGGER) this.acTimersFired[iTimer]++;\n }\n }\n }\n /*\n * Early implementation of this mode was minimal because when using this mode, the ROM BIOS simply wanted\n * to see the count changing; it wasn't looking for interrupts. See ROM BIOS \"TEST.03\" code @F000:E0DE,\n * where TIMER1 is programmed for MODE2, LSB (the same settings, incidentally, used immediately afterward\n * for TIMER1 in conjunction with DMA channel 0 memory refreshes).\n *\n * Now this mode generates interrupts. Note that OUT goes low when the count reaches 1, then high\n * one tick later, at which point the count is reloaded and counting continues.\n *\n * Chances are, we will often miss the exact point at which the count becomes 1 (or more importantly,\n * one tick later, when the count *would* become 0, since that's when OUT transitions from low to high),\n * but as with MODE3, hopefully no one will mind.\n *\n * FYI, technically, it appears that the count is never supposed to reach 0, and that an initial count of 1\n * is \"illegal\", whatever that means.\n */\n else if (timer.mode == ChipSet.PIT_CTRL.MODE2) {\n timer.fOUT = (count != 1); // yes, this line does seem rather pointless....\n if (count <= 0) {\n count = countInit + count;\n if (count <= 0) {\n /*\n * TODO: Consider whether we ever care about TIMER1 or TIMER2 underflow\n */\n if (DEBUG && this.messageEnabled(Messages.TIMER) && !iTimer) {\n this.printMessage(\"updateTimer(\" + iTimer + \"): mode=2, underflow=\" + count, true);\n }\n count = countInit;\n }\n timer.countStart[0] = count & 0xff;\n timer.countStart[1] = (count >> 8) & 0xff;\n timer.nCyclesStart = nCycles;\n if (!iTimer && timer.fOUT) {\n fFired = true;\n this.setIRR(ChipSet.IRQ.TIMER0);\n if (MAXDEBUG && DEBUGGER) this.acTimersFired[iTimer]++;\n }\n }\n }\n /*\n * NOTE: This is the normal mode for TIMER0, which the ROM BIOS uses to generate h/w interrupts roughly\n * 18.2 times per second. In this mode, the count must be decremented twice as fast (hence the extra ticks\n * subtraction below, in addition to the subtraction above), but IRQ_TIMER0 is raised only on alternate\n * iterations; ie, only when fOUT transitions to true (\"high\"). The equal alternating fOUT states is why\n * this mode is referred to as \"square wave\" mode.\n *\n * TODO: Implement the correct behavior for this mode when the count is ODD. In that case, fOUT is supposed\n * to be \"high\" for (N + 1) / 2 ticks and \"low\" for (N - 1) / 2 ticks.\n */\n else if (timer.mode == ChipSet.PIT_CTRL.MODE3) {\n count -= ticksElapsed;\n if (count <= 0) {\n timer.fOUT = !timer.fOUT;\n count = countInit + count;\n if (count <= 0) {\n /*\n * TODO: Consider whether we ever care about TIMER1 or TIMER2 underflow\n */\n if (DEBUG && this.messageEnabled(Messages.TIMER) && !iTimer) {\n this.printMessage(\"updateTimer(\" + iTimer + \"): mode=3, underflow=\" + count, true);\n }\n count = countInit;\n }\n if (MAXDEBUG && DEBUGGER && !iTimer) {\n let nCycleDelta = 0;\n if (this.acTimer0Counts.length > 0) nCycleDelta = nCycles - this.acTimer0Counts[0][1];\n this.acTimer0Counts.push([count, nCycles, nCycleDelta]);\n }\n timer.countStart[0] = count & 0xff;\n timer.countStart[1] = (count >> 8) & 0xff;\n timer.nCyclesStart = nCycles;\n if (!iTimer && timer.fOUT) {\n fFired = true;\n this.setIRR(ChipSet.IRQ.TIMER0);\n if (MAXDEBUG && DEBUGGER) this.acTimersFired[iTimer]++;\n }\n }\n }\n\n if (MAXDEBUG && this.messageEnabled(Messages.TIMER | Messages.WARN)) {\n this.log(\"TIMER\" + iTimer + \" count: \" + count + \", ticks: \" + ticksElapsed + \", fired: \" + (fFired? \"true\" : \"false\"));\n }\n\n timer.countCurrent[0] = count & 0xff;\n timer.countCurrent[1] = (count >> 8) & 0xff;\n if (fCycleReset) this.nCyclesStart = 0;\n }\n return timer;\n }\n\n /**\n * updateAllTimers(fCycleReset)\n *\n * @this {ChipSet}\n * @param {boolean} [fCycleReset] is true if a cycle-count reset is about to occur\n */\n updateAllTimers(fCycleReset)\n {\n for (let iTimer = 0; iTimer < this.aTimers.length; iTimer++) {\n this.updateTimer(iTimer, fCycleReset);\n }\n if (this.model >= ChipSet.MODEL_5170) this.updateRTCTime();\n }\n\n /**\n * outMFGTest(port, bOut, addrFrom)\n * \n * This is test port on the PCjr (MODEL_4860) only.\n *\n * @this {ChipSet}\n * @param {number} port (0x10)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outMFGTest(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"MFG_TEST\");\n }\n\n /**\n * inPPIA(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x60)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inPPIA(port, addrFrom)\n {\n let b = this.bPPIA;\n if (this.bPPICtrl & ChipSet.PPI_CTRL.A_IN) {\n if (this.bPPIB & ChipSet.PPI_B.CLEAR_KBD) {\n b = this.aDIPSwitches[0][1];\n } else {\n b = this.bKbdData;\n this.printMessageIO(port, null, addrFrom, \"PPI_A\", b, Messages.KBD);\n return b;\n }\n }\n this.printMessageIO(port, null, addrFrom, \"PPI_A\", b);\n return b;\n }\n\n /**\n * outPPIA(port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x60)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outPPIA(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"PPI_A\");\n this.bPPIA = bOut;\n }\n\n /**\n * inPPIB(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x61)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inPPIB(port, addrFrom)\n {\n let b = this.bPPIB;\n this.printMessageIO(port, null, addrFrom, \"PPI_B\", b);\n return b;\n }\n\n /**\n * outPPIB(port, bOut, addrFrom)\n *\n * This is the original (MODEL_5150 and MODEL_5160) handler for port 0x61. Functionality common\n * to all models must be placed in updatePPIB().\n *\n * @this {ChipSet}\n * @param {number} port (0x61)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outPPIB(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"PPI_B\");\n this.updatePPIB(bOut);\n }\n\n /**\n * updatePPIB(bOut)\n *\n * On MODEL_5170 and up, this updates the \"simulated\" PPI_B. The only common (and well-documented) PPI_B bits\n * across all models are PPI_B.CLK_TIMER2 and PPI_B.SPK_TIMER2, so its possible that this function may need to\n * limit its updates to just those bits, and move any model-specific requirements back into the appropriate I/O\n * handlers (PPIB or 8042RWReg). We'll see.\n *\n * UPDATE: The WOLF3D keyboard interrupt handler toggles the CLEAR_KBD bit of port 0x61 (ie, it sets and then\n * clears the bit) after reading the scan code from port 0x60; assuming that they use the same interrupt handler\n * for all machine models (which I haven't verified), the clear implication is that updatePPIB() also needs to\n * support CLEAR_KBD and CLK_KBD, so I've moved that code from outPPIB() to updatePPIB().\n *\n * @this {ChipSet}\n * @param {number} bOut\n */\n updatePPIB(bOut)\n {\n let fNewSpeaker = !!(bOut & ChipSet.PPI_B.SPK_TIMER2);\n let fOldSpeaker = !!(this.bPPIB & ChipSet.PPI_B.SPK_TIMER2);\n this.bPPIB = bOut;\n if (this.kbd) this.kbd.setEnabled(!(bOut & ChipSet.PPI_B.CLEAR_KBD), !!(bOut & ChipSet.PPI_B.CLK_KBD));\n if (fNewSpeaker != fOldSpeaker) {\n /*\n * Originally, this code didn't catch the \"ERROR_BEEP\" case @F000:EC34, which first turns both PPI_B.CLK_TIMER2 (0x01)\n * and PPI_B.SPK_TIMER2 (0x02) off, then turns on only PPI_B.SPK_TIMER2 (0x02), then restores the original port value.\n *\n * So, when the ROM BIOS keyboard buffer got full, we didn't issue a BEEP alert. I've fixed that by limiting the test\n * to PPI_B.SPK_TIMER2 and ignoring PPI_B.CLK_TIMER2.\n */\n this.setSpeaker(fNewSpeaker);\n }\n }\n\n /**\n * inPPIC(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x62)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inPPIC(port, addrFrom)\n {\n let b = 0;\n\n /*\n * If you ever wanted to simulate I/O channel errors or R/W memory parity errors, you could\n * add either PPI_C.IO_CHANNEL_CHK (0x40) or PPI_C.RW_PARITY_CHK (0x80) to the return value (b).\n */\n if ((this.model|0) == ChipSet.MODEL_4860) {\n b |= this.bNMI & ChipSet.NMI.KBD_LATCH;\n /*\n * We're going to hard-code the rest of the PCjr settings for now, including NOT setting the NO_KBD_CABLE\n * bit, on the theory that if we don't have to deal with IR hardware emulation, so much the better.\n */\n b |= ChipSet.PPI_C.NO_MODEM | ChipSet.PPI_C.NO_DISKETTE | ChipSet.PPI_C.NO_MEMEXP;\n /*\n * I'm just guessing at how keyboard data is \"clocked\" into the the KBD_DATA bit; this will be revisited.\n */\n b |= (this.bKbdData & 0x1)? ChipSet.PPI_C.KBD_DATA : 0;\n this.bKbdData >>>= 1;\n }\n else if ((this.model|0) == ChipSet.MODEL_5150) {\n if (this.bPPIB & ChipSet.PPI_B.ENABLE_SW2) {\n b |= this.aDIPSwitches[1][1] & ChipSet.PPI_C.SW;\n } else {\n b |= (this.aDIPSwitches[1][1] >> 4) & 0x1;\n }\n } else {\n if (this.bPPIB & ChipSet.PPI_B.ENABLE_SW_HI) {\n b |= this.aDIPSwitches[0][1] >> 4;\n } else {\n b |= this.aDIPSwitches[0][1] & 0xf;\n }\n }\n\n if (this.bPPIB & ChipSet.PPI_B.CLK_TIMER2) {\n let timer = this.updateTimer(ChipSet.PIT0.TIMER2);\n if (timer.fOUT) {\n if (this.bPPIB & ChipSet.PPI_B.SPK_TIMER2)\n b |= ChipSet.PPI_C.TIMER2_OUT;\n else\n b |= ChipSet.PPI_C.CASS_DATA_IN;\n }\n }\n\n /*\n * The ROM BIOS polls this port incessantly during its memory tests, checking for memory parity errors\n * (which of course we never report), so you must use both Messages.PORT and Messages.CHIPSET.\n */\n this.printMessageIO(port, null, addrFrom, \"PPI_C\", b, Messages.CHIPSET);\n return b;\n }\n\n /**\n * outPPIC(port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x62)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n outPPIC(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"PPI_C\");\n this.bPPIC = bOut;\n }\n\n /**\n * inPPICtrl(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x63)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inPPICtrl(port, addrFrom)\n {\n let b = this.bPPICtrl;\n this.printMessageIO(port, null, addrFrom, \"PPI_CTRL\", b);\n return b;\n }\n\n /**\n * outPPICtrl(port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x63)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outPPICtrl(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"PPI_CTRL\");\n this.bPPICtrl = bOut;\n }\n\n /**\n * in8041Kbd(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x60)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n in8041Kbd(port, addrFrom)\n {\n let b = this.bKbdData;\n this.printMessageIO(port, null, addrFrom, \"8041_KBD\", b, Messages.KBD);\n this.b8041Status &= ~ChipSet.C8042.STATUS.OUTBUFF_FULL;\n return b;\n }\n\n /**\n * out8041Kbd(port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x60)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n out8041Kbd(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"8041_KBD\");\n // if (this.kbd) this.kbd.receiveCmd(bOut);\n }\n\n /**\n * in8041Ctrl(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x61)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n in8041Ctrl(port, addrFrom)\n {\n let b = this.bPPIB;\n this.printMessageIO(port, null, addrFrom, \"8041_CTRL\", b);\n return b;\n }\n\n /**\n * out8041Ctrl(port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x61)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n out8041Ctrl(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"8041_CTRL\");\n this.updatePPIB(bOut);\n }\n\n /**\n * in8041Status(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x64)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n in8041Status(port, addrFrom)\n {\n let b = this.b8041Status;\n this.printMessageIO(port, null, addrFrom, \"8041_STATUS\", b);\n return b;\n }\n\n /**\n * in8042OutBuff(port, addrFrom)\n *\n * Return the contents of the OUTBUFF register and clear the OUTBUFF_FULL status bit.\n *\n * Moreover, we also call kbd.checkBuffer() to let the Keyboard know that we just pulled\n * data, so that it can reset its internal timer controlling the delivery of additional data.\n * \n * Note that there are applications like BASICA that install a keyboard interrupt handler\n * that reads OUTBUFF, does some scan code preprocessing, and then passes control on to the\n * ROM's interrupt handler. As a result, OUTBUFF is read multiple times during a single\n * interrupt, so we need to avoid filling it with new data after every read; otherwise,\n * scan codes will get dropped.\n *\n * The safest thing to do is to wait until kbd.setEnabled() is called, and let that call supply\n * more data to receiveKbdData(). That will happen as soon as the ROM re-enables the controller,\n * and is why C8042.CMD.ENABLE_KBD processing ends with a call to kbd.checkBuffer(). However,\n * not all software (eg, Xenix 286, and the Windows 95 VMM) does that, so we have to rely on\n * the Keyboard's internal timer.\n *\n * Also note that, the foregoing notwithstanding, I still clear the OUTBUFF_FULL bit here\n * (as I believe I should); fortunately, none of the interrupt handlers I've seen rely on\n * OUTBUFF_FULL as a prerequisite for reading OUTBUFF (certainly not BASICA or the ROM).\n * The assumption seems to be that if an interrupt occurred, OUTBUFF must contain data,\n * regardless of the state of OUTBUFF_FULL.\n *\n * @this {ChipSet}\n * @param {number} port (0x60)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n in8042OutBuff(port, addrFrom)\n {\n let b = this.b8042OutBuff;\n this.printMessageIO(port, null, addrFrom, \"8042_OUTBUFF\", b, Messages.C8042);\n this.b8042Status &= ~(ChipSet.C8042.STATUS.OUTBUFF_FULL | ChipSet.C8042.STATUS.OUTBUFF_DELAY);\n if (this.kbd) this.kbd.checkBuffer(b);\n return b;\n }\n\n /**\n * out8042InBuffData(port, bOut, addrFrom)\n *\n * This writes to the 8042's input buffer; using this port (ie, 0x60 instead of 0x64) designates the\n * the byte as a C8042.DATA.CMD \"data byte\". Before clearing C8042.STATUS.CMD_FLAG, however, we see if it's set,\n * and then based on the previous C8042.CMD \"command byte\", we do whatever needs to be done with this \"data byte\".\n *\n * @this {ChipSet}\n * @param {number} port (0x60)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n out8042InBuffData(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"8042_INBUF.DATA\", null, Messages.C8042);\n\n if (this.b8042Status & ChipSet.C8042.STATUS.CMD_FLAG) {\n\n switch (this.b8042InBuff) {\n\n case ChipSet.C8042.CMD.WRITE_CMD:\n this.set8042CmdData(bOut);\n break;\n\n case ChipSet.C8042.CMD.WRITE_OUTPORT:\n this.set8042OutPort(bOut);\n break;\n\n /*\n * This case is reserved for command bytes that the 8042 is not expecting, which should therefore be passed\n * on to the Keyboard itself.\n *\n * Here's some relevant MODEL_5170 ROM BIOS code, \"XMIT_8042\" (missing from the original MODEL_5170 ROM BIOS\n * listing), which sends a command code in AL to the Keyboard and waits for a response, returning it in AL.\n * Note that the only \"success\" exit path from this function involves LOOPing 64K times before finally reading\n * the Keyboard's response; either the hardware and/or this code seems a bit brain-damaged if that's REALLY\n * what you had to do to ensure a valid response....\n *\n * F000:1B25 86E0 XCHG AH,AL\n * F000:1B27 2BC9 SUB CX,CX\n * F000:1B29 E464 IN AL,64\n * F000:1B2B A802 TEST AL,02 ; WAIT FOR INBUFF_FULL TO BE CLEAR\n * F000:1B2D E0FA LOOPNZ 1B29\n * F000:1B2F E334 JCXZ 1B65 ; EXIT WITH ERROR (CX == 0)\n * F000:1B31 86E0 XCHG AH,AL\n * F000:1B33 E660 OUT 60,AL ; SAFE TO WRITE KEYBOARD CMD TO INBUFF NOW\n * F000:1B35 2BC9 SUB CX,CX\n * F000:1B37 E464 IN AL,64\n * F000:1B39 8AE0 MOV AH,AL\n * F000:1B3B A801 TEST AL,01\n * F000:1B3D 7402 JZ 1B41\n * F000:1B3F E460 IN AL,60 ; READ PORT 0x60 IF OUTBUFF_FULL SET (\"FLUSH\"?)\n * F000:1B41 F6C402 TEST AH,02\n * F000:1B44 E0F1 LOOPNZ 1B37\n * F000:1B46 751D JNZ 1B65 ; EXIT WITH ERROR (CX == 0)\n * F000:1B48 B306 MOV BL,06\n * F000:1B4A 2BC9 SUB CX,CX\n * F000:1B4C E464 IN AL,64\n * F000:1B4E A801 TEST AL,01\n * F000:1B50 E1FA LOOPZ 1B4C\n * F000:1B52 7508 JNZ 1B5C ; PROCEED TO EXIT NOW THAT OUTBUFF_FULL IS SET\n * F000:1B54 FECB DEC BL\n * F000:1B56 75F4 JNZ 1B4C\n * F000:1B58 FEC3 INC BL\n * F000:1B5A EB09 JMP 1B65 ; EXIT WITH ERROR (CX == 0)\n * F000:1B5C 2BC9 SUB CX,CX\n * F000:1B5E E2FE LOOP 1B5E ; LOOOOOOPING....\n * F000:1B60 E460 IN AL,60\n * F000:1B62 83E901 SUB CX,0001 ; EXIT WITH SUCCESS (CX != 0)\n * F000:1B65 C3 RET\n *\n * But WAIT, the FUN doesn't end there. After this function returns, \"KBD_RESET\" waits for a Keyboard\n * interrupt to occur, hoping for scan code 0xAA as the Keyboard's final response. \"KBD_RESET\" also returns\n * CX to the caller, and the caller (\"TEST.21\") assumes there was no interrupt if CX is zero.\n *\n * MOV AL,0FDH\n * OUT INTA01,AL\n * MOV INTR_FLAG,0\n * STI\n * MOV BL,10\n * SUB CX,CX\n * G11: TEST [1NTR_FLAG],02H\n * JNZ G12\n * LOOP G11\n * DEC BL\n * JNZ G11\n * ...\n *\n * However, if [INTR_FLAG] is set immediately, the above code will exit immediately, without ever decrementing\n * CX. CX can be zero not only if the loop exhausted it, but also if no looping was required; the latter is not\n * an error, but \"TEST.21\" assumes that it is.\n */\n default:\n this.set8042CmdData(this.b8042CmdData & ~ChipSet.C8042.DATA.CMD.NO_CLOCK);\n if (this.kbd) this.set8042OutBuff(this.kbd.receiveCmd(bOut));\n break;\n }\n }\n this.b8042InBuff = bOut;\n this.b8042Status &= ~ChipSet.C8042.STATUS.CMD_FLAG;\n }\n\n /**\n * in8042RWReg(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x61)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n in8042RWReg(port, addrFrom)\n {\n /*\n * Normally, we return whatever was last written to this port, but we do need to mask the\n * two upper-most bits (C8042.RWREG.NMI_ERROR), as those are output-only bits used to signal\n * parity errors.\n *\n * Also, \"TEST.09\" of the MODEL_5170 BIOS expects the REFRESH_BIT to alternate, so we used to\n * do this:\n *\n * this.bPPIB ^= ChipSet.C8042.RWREG.REFRESH_BIT;\n *\n * However, the MODEL_5170_REV3 BIOS not only checks REFRESH_BIT in \"TEST.09\", but includes\n * an additional test right before \"TEST.11A\", which requires the bit change \"a bit less\"\n * frequently. This new test sets CX to zero, and at the end of the test (@F000:05B8), CX\n * must be in the narrow range of 0xF600 through 0xF9FD.\n *\n * In fact, the new \"WAITF\" function @F000:1A3A tells us exactly how frequently REFRESH_BIT\n * is expected to change now. That function performs a \"FIXED TIME WAIT\", where CX is a\n * \"COUNT OF 15.085737us INTERVALS TO WAIT\".\n *\n * So we now tie the state of the REFRESH_BIT to bit 6 of the current CPU cycle count,\n * effectively toggling the bit after every 64 cycles. On an 8Mhz CPU that can do 8 cycles\n * in 1us, 64 cycles represents 8us, so that might be a bit fast for \"WAITF\", but bit 6\n * is the only choice that also satisfies the pre-\"TEST.11A\" test as well.\n */\n let b = this.bPPIB & ~(ChipSet.C8042.RWREG.NMI_ERROR | ChipSet.C8042.RWREG.REFRESH_BIT) | ((this.cpu.getCycles() & 0x40)? ChipSet.C8042.RWREG.REFRESH_BIT : 0);\n /*\n * Thanks to the WAITF function, this has become a very \"busy\" port, so if this generates too\n * many messages, try adding Messages.WARN to the criteria.\n */\n this.printMessageIO(port, null, addrFrom, \"8042_RWREG\", b, Messages.C8042 | Messages.WARN);\n return b;\n }\n\n /**\n * out8042RWReg(port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x61)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n */\n out8042RWReg(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"8042_RWREG\", null, Messages.C8042);\n this.updatePPIB(bOut);\n }\n\n /**\n * in8042Status(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x64)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n in8042Status(port, addrFrom)\n {\n this.printMessageIO(port, null, addrFrom, \"8042_STATUS\", this.b8042Status, Messages.C8042);\n let b = this.b8042Status & 0xff;\n /*\n * There's code in the 5170 BIOS (F000:03BF) that writes an 8042 command (0xAA), waits for\n * C8042.STATUS.INBUFF_FULL to go clear (which it always is, because we always accept commands\n * immediately), then checks C8042.STATUS.OUTBUFF_FULL and performs a \"flush\" on port 0x60 if\n * it's set, then waits for C8042.STATUS.OUTBUFF_FULL *again*. Unfortunately, the \"flush\" throws\n * away our response if we respond immediately.\n *\n * So now when out8042InBuffCmd() has a response, it sets C8042.STATUS.OUTBUFF_DELAY instead\n * (which is outside the 0xff range of bits we return); when we see C8042.STATUS.OUTBUFF_DELAY,\n * we clear it and set C8042.STATUS.OUTBUFF_FULL, which will be returned on the next read.\n *\n * This provides a single poll delay, so that the aforementioned \"flush\" won't toss our response.\n * If longer delays are needed down the road, we may need to set a delay count in the upper (unused)\n * bits of b8042Status, instead of using a single delay bit.\n */\n if (this.b8042Status & ChipSet.C8042.STATUS.OUTBUFF_DELAY) {\n this.b8042Status |= ChipSet.C8042.STATUS.OUTBUFF_FULL;\n this.b8042Status &= ~ChipSet.C8042.STATUS.OUTBUFF_DELAY;\n }\n /*\n * I added this for Windows 95's VMM keyboard driver for DOS sessions, which differs from the keyboard\n * driver for protected-mode applications (see the keyboard's setEnabled() function for more details).\n * \n * The Windows 95 VMM driver doesn't do what EITHER the ROM or the protected-mode driver typically does\n * after receiving a scan code (ie, toggle the keyboard's enable state). Instead, the VMM simply checks\n * this status port one more time, perhaps to confirm that the OUTBUFF_FULL bit is clear. It then\n * expects another keyboard interrupt to arrive when the next scan code is available. Very minimalistic.\n */\n if (!(this.b8042Status & ChipSet.C8042.STATUS.OUTBUFF_FULL) && this.kbd) {\n this.kbd.checkBuffer();\n }\n return b;\n }\n\n /**\n * out8042InBuffCmd(port, bOut, addrFrom)\n *\n * This writes to the 8042's input buffer; using this port (ie, 0x64 instead of 0x60) designates the\n * the byte as a \"command byte\". We immediately set C8042.STATUS.CMD_FLAG, and then see if we can act upon\n * the command immediately (some commands requires us to wait for a \"data byte\").\n *\n * @this {ChipSet}\n * @param {number} port (0x64)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n out8042InBuffCmd(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"8042_INBUFF.CMD\", null, Messages.C8042);\n\n this.b8042InBuff = bOut;\n\n this.b8042Status |= ChipSet.C8042.STATUS.CMD_FLAG;\n\n let bPulseBits = 0;\n if (this.b8042InBuff >= ChipSet.C8042.CMD.PULSE_OUTPORT) {\n bPulseBits = (this.b8042InBuff ^ 0xf);\n /*\n * Now that we have isolated the bit(s) to pulse, map all pulse commands to C8042.CMD.PULSE_OUTPORT\n */\n this.b8042InBuff = ChipSet.C8042.CMD.PULSE_OUTPORT;\n }\n\n switch (this.b8042InBuff) {\n case ChipSet.C8042.CMD.READ_CMD: // 0x20\n this.set8042OutBuff(this.b8042CmdData);\n break;\n\n case ChipSet.C8042.CMD.WRITE_CMD: // 0x60\n /*\n * No further action required for this command; more data is expected via out8042InBuffData()\n */\n break;\n\n case ChipSet.C8042.CMD.DISABLE_KBD: // 0xAD\n this.set8042CmdData(this.b8042CmdData | ChipSet.C8042.DATA.CMD.NO_CLOCK);\n if (!COMPILED) this.printMessage(\"keyboard disabled\", Messages.KBD | Messages.PORT);\n /*\n * NOTE: The MODEL_5170 BIOS calls \"KBD_RESET\" (F000:17D2) while the keyboard interface is disabled,\n * yet we must still deliver the Keyboard's CMDRES.BAT_OK response code? Seems like an odd thing for\n * a \"disabled interface\" to do.\n */\n break;\n\n case ChipSet.C8042.CMD.ENABLE_KBD: // 0xAE\n this.set8042CmdData(this.b8042CmdData & ~ChipSet.C8042.DATA.CMD.NO_CLOCK);\n if (!COMPILED) this.printMessage(\"keyboard re-enabled\", Messages.KBD | Messages.PORT);\n if (this.kbd) this.kbd.checkBuffer();\n break;\n\n case ChipSet.C8042.CMD.SELF_TEST: // 0xAA\n if (this.kbd) this.kbd.flushBuffer();\n this.set8042CmdData(this.b8042CmdData | ChipSet.C8042.DATA.CMD.NO_CLOCK);\n if (!COMPILED) this.printMessage(\"keyboard disabled on reset\", Messages.KBD | Messages.PORT);\n this.set8042OutBuff(ChipSet.C8042.DATA.SELF_TEST.OK);\n this.set8042OutPort(ChipSet.C8042.OUTPORT.NO_RESET | ChipSet.C8042.OUTPORT.A20_ON);\n break;\n\n case ChipSet.C8042.CMD.INTF_TEST: // 0xAB\n /*\n * TODO: Determine all the side-effects of the Interface Test, if any.\n */\n this.set8042OutBuff(ChipSet.C8042.DATA.INTF_TEST.OK);\n break;\n\n case ChipSet.C8042.CMD.READ_INPORT: // 0xC0\n this.set8042OutBuff(this.b8042InPort);\n break;\n\n case ChipSet.C8042.CMD.READ_OUTPORT: // 0xD0\n this.set8042OutBuff(this.b8042OutPort);\n break;\n\n case ChipSet.C8042.CMD.WRITE_OUTPORT: // 0xD1\n /*\n * No further action required for this command; more data is expected via out8042InBuffData()\n */\n break;\n\n case ChipSet.C8042.CMD.READ_TEST: // 0xE0\n this.set8042OutBuff((this.b8042CmdData & ChipSet.C8042.DATA.CMD.NO_CLOCK)? 0 : ChipSet.C8042.TESTPORT.KBD_CLOCK);\n break;\n\n case ChipSet.C8042.CMD.PULSE_OUTPORT: // 0xF0-0xFF\n if (bPulseBits & 0x1) {\n /*\n * Bit 0 of the 8042's output port is connected to RESET. If it's pulsed, the processor resets.\n * We don't want to clear *all* CPU state (eg, cycle counts), so we call cpu.resetRegs() instead\n * of cpu.reset().\n */\n this.cpu.resetRegs();\n }\n break;\n\n default:\n if (!COMPILED && this.messageEnabled(Messages.C8042)) {\n this.printMessage(\"unrecognized 8042 command: \" + Str.toHexByte(this.b8042InBuff), true);\n this.dbg.stopCPU();\n }\n break;\n }\n }\n\n /**\n * set8042CmdData(b)\n *\n * @this {ChipSet}\n * @param {number} b\n */\n set8042CmdData(b)\n {\n this.b8042CmdData = b;\n\n this.b8042Status = (this.b8042Status & ~ChipSet.C8042.STATUS.SYS_FLAG) | (b & ChipSet.C8042.DATA.CMD.SYS_FLAG);\n if (this.kbd) {\n /*\n * This seems to be what the doctor ordered for the MODEL_5170_REV3 BIOS @F000:0A6D, where it\n * sends ChipSet.C8042.CMD.WRITE_CMD to port 0x64, followed by 0x4D to port 0x60, which clears NO_CLOCK\n * and enables the keyboard. The BIOS then waits for OUTBUFF_FULL to be set, at which point it seems\n * to be anticipating an 0xAA response in the output buffer.\n *\n * And indeed, if we call the original MODEL_5150/MODEL_5160 setEnabled() Keyboard interface here,\n * and both the data and clock lines have transitioned high (ie, both parameters are true), then it\n * will call resetDevice(), generating a Keyboard.CMDRES.BAT_OK response.\n *\n * This agrees with my understanding of what happens when the 8042 toggles the clock line high\n * (ie, clears NO_CLOCK): the TechRef's \"Basic Assurance Test\" section says that when the Keyboard is\n * powered on, it performs the BAT, and then when the clock and data lines go high, the keyboard sends\n * a completion code (eg, 0xAA for success, or 0xFC or something else for failure).\n */\n this.kbd.setEnabled(!!(b & ChipSet.C8042.DATA.CMD.NO_INHIBIT), !(b & ChipSet.C8042.DATA.CMD.NO_CLOCK));\n }\n }\n\n /**\n * set8042OutBuff(b, fNoDelay)\n *\n * The 5170 ROM BIOS assumed there would be a slight delay after certain 8042 commands, like SELF_TEST\n * (0xAA), before there was an OUTBUFF response; in fact, there is BIOS code that will fail without such\n * a delay. This is discussed in greater detail in in8042Status().\n *\n * So we default to a \"single poll\" delay, setting OUTBUFF_DELAY instead of OUTBUFF_FULL, unless the caller\n * explicitly asks for no delay. The fNoDelay parameter was added later, so that receiveKbdData() could\n * request immediate delivery of keyboard scan codes, because some operating systems (eg, Microport's 1986\n * version of Unix for PC AT machines) poll the status port only once, immediately giving up if no data is\n * available.\n *\n * TODO: Determine if we should invert the fNoDelay default (from false to true) and delay only in specific\n * cases; ie, perhaps only the SELF_TEST command required a delay.\n *\n * @this {ChipSet}\n * @param {number} b\n * @param {boolean} [fNoDelay]\n */\n set8042OutBuff(b, fNoDelay)\n {\n if (b >= 0) {\n this.b8042OutBuff = b;\n if (fNoDelay) {\n this.b8042Status |= ChipSet.C8042.STATUS.OUTBUFF_FULL;\n } else {\n this.b8042Status &= ~ChipSet.C8042.STATUS.OUTBUFF_FULL;\n this.b8042Status |= ChipSet.C8042.STATUS.OUTBUFF_DELAY;\n }\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.PORT)) {\n this.printMessage(\"chipset.set8042OutBuff(\" + Str.toHexByte(b) + ',' + (fNoDelay? \"no\" : \"\") + \"delay)\", true);\n }\n }\n }\n\n /**\n * set8042OutPort(b)\n *\n * When ChipSet.C8042.CMD.WRITE_OUTPORT (0xD1) is written to port 0x64, the next byte written to port 0x60 comes here,\n * to the KBC's OUTPORT. One of the most important bits in the OUTPORT is the A20_ON bit (0x02): set it to turn A20 on,\n * clear it to turn A20 off.\n *\n * @this {ChipSet}\n * @param {number} b\n */\n set8042OutPort(b)\n {\n this.b8042OutPort = b;\n\n this.bus.setA20(!!(b & ChipSet.C8042.OUTPORT.A20_ON));\n\n if (!(b & ChipSet.C8042.OUTPORT.NO_RESET)) {\n /*\n * Bit 0 of the 8042's output port is connected to RESET. Normally, it's \"pulsed\" with the\n * C8042.CMD.PULSE_OUTPORT command, so if a RESET is detected via this command, we should try to\n * determine if that's what the caller intended.\n */\n if (!COMPILED && this.messageEnabled(Messages.C8042)) {\n this.printMessage(\"unexpected 8042 output port reset: \" + Str.toHexByte(b), true);\n this.dbg.stopCPU();\n }\n this.cpu.resetRegs();\n }\n }\n\n /**\n * receiveKbdData(b)\n *\n * In the old days of PCx86, the Keyboard component would simply call setIRR() when it had some data for the\n * keyboard controller. However, the Keyboard's sole responsibility is to emulate an actual keyboard and call\n * receiveKbdData() whenever it has some data; it's not allowed to mess with IRQ lines.\n *\n * If there's an 8042, we check (this.b8042CmdData & ChipSet.C8042.DATA.CMD.NO_CLOCK); if NO_CLOCK is clear,\n * we can raise the IRQ immediately. Well, not quite immediately....\n *\n * Notes regarding the MODEL_5170 (eg, /devices/pc/machine/5170/ega/1152kb/rev3/machine.xml):\n *\n * The \"Rev3\" BIOS, dated 11-Nov-1985, contains the following code in the keyboard interrupt handler at K26A:\n *\n * F000:3704 FA CLI\n * F000:3705 B020 MOV AL,20\n * F000:3707 E620 OUT 20,AL\n * F000:3709 B0AE MOV AL,AE\n * F000:370B E88D02 CALL SHIP_IT\n * F000:370E FA CLI <-- window of opportunity\n * F000:370F 07 POP ES\n * F000:3710 1F POP DS\n * F000:3711 5F POP DI\n * F000:3712 5E POP SI\n * F000:3713 5A POP DX\n * F000:3714 59 POP CX\n * F000:3715 5B POP BX\n * F000:3716 58 POP AX\n * F000:3717 5D POP BP\n * F000:3718 CF IRET\n *\n * and SHIP_IT looks like this:\n *\n * F000:399B 50 PUSH AX\n * F000:399C FA CLI\n * F000:399D 2BC9 SUB CX,CX\n * F000:399F E464 IN AL,64\n * F000:39A1 A802 TEST AL,02\n * F000:39A3 E0FA LOOPNZ 399F\n * F000:39A5 58 POP AX\n * F000:39A6 E664 OUT 64,AL\n * F000:39A8 FB STI\n * F000:39A9 C3 RET\n *\n * This code *appears* to be trying to ensure that another keyboard interrupt won't occur until after the IRET,\n * but sadly, it looks to me like the CLI following the call to SHIP_IT is too late. SHIP_IT should have been\n * written with PUSHF/CLI and POPF intro/outro sequences, thereby honoring the first CLI at the top of K26A and\n * eliminating the need for the second CLI (@F000:370E).\n *\n * Of course, in \"real life\", this was probably never a problem, because the 8042 probably wasn't fast enough to\n * generate another interrupt so soon after receiving the ChipSet.C8042.CMD.ENABLE_KBD command. In my case, I ran\n * into this problem by 1) turning on \"kbd\" Debugger messages and 2) rapidly typing lots of keys. The Debugger\n * messages bogged the machine down enough for me to hit the \"window of opportunity\", generating this message in\n * PC-DOS 3.20:\n *\n * \"FATAL: Internal Stack Failure, System Halted.\"\n *\n * and halting the system @0070:0923 (JMP 0923).\n *\n * That wasn't the only spot in the BIOS where I hit this problem; here's another \"window of opportunity\":\n *\n * F000:3975 FA CLI\n * F000:3976 B020 MOV AL,20\n * F000:3978 E620 OUT 20,AL\n * F000:397A B0AE MOV AL,AE\n * F000:397C E81C00 CALL SHIP_IT\n * F000:397F B80291 MOV AX,9102 <-- window of opportunity\n * F000:3982 CD15 INT 15\n * F000:3984 80269600FC AND [0096],FC\n * F000:3989 E982FD JMP 370E\n *\n * In this second, lengthier, example, I counted about 60 instructions being executed from the EOI @F000:3978 to\n * the final IRET @F000:3718, most of them in the INT 0x15 handler. So, I'm going to double that count to 120\n * instructions, just to be safe, and pass that along to every setIRR() call we make here.\n *\n * @this {ChipSet}\n * @param {number} b\n * @return {boolean} (true if data accepted, false if declined)\n */\n receiveKbdData(b)\n {\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.PORT)) {\n this.printMessage(\"chipset.receiveKbdData(\" + Str.toHexByte(b) + ')', true);\n }\n if (this.model == ChipSet.MODEL_4860) {\n if (!(this.bNMI & ChipSet.NMI.KBD_LATCH)) {\n this.bNMI |= ChipSet.NMI.KBD_LATCH;\n this.bKbdData = b;\n if (b && (this.bNMI & ChipSet.NMI.ENABLE)) {\n X86.helpInterrupt.call(this.cpu, X86.EXCEPTION.NMI);\n }\n return true;\n }\n return false;\n }\n if (this.model < ChipSet.MODEL_5170) {\n if (this.bPPIB & ChipSet.PPI_B.CLK_KBD) {\n this.bKbdData = b;\n if (b) {\n this.setIRR(ChipSet.IRQ.KBD, 120);\n this.b8041Status |= ChipSet.C8042.STATUS.OUTBUFF_FULL;\n }\n return true;\n }\n return false;\n }\n if (b) {\n if (!(this.b8042CmdData & ChipSet.C8042.DATA.CMD.NO_CLOCK)) {\n /*\n * The next in8042OutBuff() will clear both of these bits and call kbd.checkBuffer(),\n * which will call receiveKbdData() again if there's still keyboard data to process.\n */\n if (!(this.b8042Status & (ChipSet.C8042.STATUS.OUTBUFF_FULL | ChipSet.C8042.STATUS.OUTBUFF_DELAY))) {\n this.set8042OutBuff(b, true);\n /*\n * A delay of 4 instructions was originally requested as part of the the Keyboard's resetDevice()\n * response, but a larger delay (120) is now needed for MODEL_5170 machines, per the discussion above.\n */\n this.setIRR(ChipSet.IRQ.KBD, 120);\n return true;\n }\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.PORT)) {\n this.printMessage(\"chipset.receiveKbdData(\" + Str.toHexByte(b) + \"): output buffer full\", true);\n }\n return false;\n }\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.PORT)) {\n this.printMessage(\"chipset.receiveKbdData(\" + Str.toHexByte(b) + \"): disabled\", true);\n }\n }\n return false;\n }\n\n /**\n * in6300DIPSwitches(iDIP, port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} iDIP (0 or 1)\n * @param {number} port (0x66 or 0x67)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n in6300DIPSwitches(iDIP, port, addrFrom)\n {\n let b = this.aDIPSwitches[iDIP][1];\n this.printMessageIO(port, null, addrFrom, \"DIPSW-\" + iDIP, b, Messages.CHIPSET);\n return b;\n }\n\n /**\n * inCMOSAddr(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x70)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inCMOSAddr(port, addrFrom)\n {\n this.printMessageIO(port, null, addrFrom, \"CMOS.ADDR\", this.bCMOSAddr, Messages.CMOS);\n return this.bCMOSAddr;\n }\n\n /**\n * outCMOSAddr(port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x70)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outCMOSAddr(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"CMOS.ADDR\", null, Messages.CMOS);\n this.bCMOSAddr = bOut;\n this.bNMI = (this.bNMI & ~ChipSet.NMI.ENABLE) | ((bOut & ChipSet.CMOS.ADDR.NMI_DISABLE)? 0 : ChipSet.NMI.ENABLE);\n }\n\n /**\n * inCMOSData(port, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x71)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inCMOSData(port, addrFrom)\n {\n let bAddr = this.bCMOSAddr & ChipSet.CMOS.ADDR.MASK;\n let bIn = (bAddr <= ChipSet.CMOS.ADDR.STATUSD? this.getRTCByte(bAddr) : this.abCMOSData[bAddr]);\n if (this.messageEnabled(Messages.CMOS | Messages.PORT)) {\n this.printMessageIO(port, null, addrFrom, \"CMOS.DATA[\" + Str.toHexByte(bAddr) + \"]\", bIn, true);\n }\n if (addrFrom != null) {\n if (bAddr == ChipSet.CMOS.ADDR.STATUSC) {\n /*\n * When software reads the STATUSC port, all interrupt bits (PF, AF, and UF) are automatically\n * cleared, which in turn clears the IRQF bit, which in turn clears the IRQ.\n */\n this.abCMOSData[bAddr] &= ChipSet.CMOS.STATUSC.RESERVED;\n if (bIn & ChipSet.CMOS.STATUSC.IRQF) this.clearIRR(ChipSet.IRQ.RTC);\n /*\n * If we just cleared PF, and PIE is still set, then we need to make sure the next Periodic Interrupt\n * occurs in a timely manner, too.\n */\n if ((bIn & ChipSet.CMOS.STATUSC.PF) && (this.abCMOSData[ChipSet.CMOS.ADDR.STATUSB] & ChipSet.CMOS.STATUSB.PIE)) {\n if (!COMPILED) this.printMessage(\"RTC periodic interrupt cleared\", Messages.RTC);\n this.setRTCCycleLimit();\n }\n }\n }\n return bIn;\n }\n\n /**\n * outCMOSData(port, bOut, addrFrom)\n *\n * @this {ChipSet}\n * @param {number} port (0x71)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outCMOSData(port, bOut, addrFrom)\n {\n let bAddr = this.bCMOSAddr & ChipSet.CMOS.ADDR.MASK;\n if (this.messageEnabled(Messages.CMOS | Messages.PORT)) {\n this.printMessageIO(port, bOut, addrFrom, \"CMOS.DATA[\" + Str.toHexByte(bAddr) + \"]\", null, true);\n }\n let bDelta = bOut ^ this.abCMOSData[bAddr];\n this.abCMOSData[bAddr] = (bAddr <= ChipSet.CMOS.ADDR.STATUSD? this.setRTCByte(bAddr, bOut) : bOut);\n if (bAddr == ChipSet.CMOS.ADDR.STATUSB && (bDelta & ChipSet.CMOS.STATUSB.PIE)) {\n if (bOut & ChipSet.CMOS.STATUSB.PIE) {\n if (!COMPILED) this.printMessage(\"RTC periodic interrupts enabled\", Messages.RTC);\n this.setRTCCycleLimit();\n } else {\n if (!COMPILED) this.printMessage(\"RTC periodic interrupts disabled\", Messages.RTC);\n }\n }\n }\n\n /**\n * inNMI(port, addrFrom)\n *\n * This handler is installed only for models before MODEL_5170; technically, this port is not readable,\n * except on the MODEL_4860, and even there, all a read is required to do is clear KBD_LATCH, but we go ahead\n * and return all the bits.\n *\n * @this {ChipSet}\n * @param {number} port (0xA0)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)\n * @return {number} simulated port value\n */\n inNMI(port, addrFrom)\n {\n let bIn = this.bNMI;\n this.printMessageIO(port, null, addrFrom, \"NMI\", bIn);\n this.bNMI &= ~ChipSet.NMI.KBD_LATCH;\n return bIn;\n }\n\n /**\n * outNMI(port, bOut, addrFrom)\n *\n * This handler is installed only for models before MODEL_5170.\n *\n * @this {ChipSet}\n * @param {number} port (0xA0)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outNMI(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"NMI\");\n this.bNMI = bOut;\n }\n\n /**\n * outFPUClear(port, bOut, addrFrom)\n *\n * This handler is installed only for MODEL_5170.\n *\n * @this {ChipSet}\n * @param {number} port (0xF0)\n * @param {number} bOut (0x00 is the only expected output)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outFPUClear(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"FPU.CLEAR\");\n\n if (this.fpu) this.fpu.clearBusy();\n }\n\n /**\n * outFPUReset(port, bOut, addrFrom)\n *\n * This handler is installed only for MODEL_5170.\n *\n * @this {ChipSet}\n * @param {number} port (0xF1)\n * @param {number} bOut (0x00 is the only expected output)\n * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)\n */\n outFPUReset(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"FPU.RESET\");\n\n if (this.fpu) this.fpu.resetFPU();\n }\n\n /**\n * intBIOSRTC(addr)\n *\n * INT 0x1A Quick Reference:\n *\n * AH\n * ----\n * 0x00 Get current clock count in CX:DX\n * 0x01 Set current clock count from CX:DX\n * 0x02 Get real-time clock using BCD (CH=hours, CL=minutes, DH=seconds)\n * 0x03 Set real-time clock using BCD (CH=hours, CL=minutes, DH=seconds, DL=1 if Daylight Savings Time option)\n * 0x04 Get real-time date using BCD (CH=century, CL=year, DH=month, DL=day)\n * 0x05 Set real-time date using BCD (CH=century, CL=year, DH=month, DL=day)\n * 0x06 Set alarm using BCD (CH=hours, CL=minutes, DH=seconds)\n * 0x07 Reset alarm\n *\n * @this {ChipSet}\n * @param {number} addr\n * @return {boolean} true to proceed with the INT 0x1A software interrupt, false to skip\n */\n intBIOSRTC(addr)\n {\n if (DEBUGGER) {\n if (this.messageEnabled(Messages.INT) && this.dbg.messageInt(Interrupts.RTC, addr)) {\n /*\n * By computing AH now, we get the incoming AH value; if we computed it below, along with\n * the rest of the register values, we'd get the outgoing AH value, which is not what we want.\n */\n let chipset = this;\n let AH = this.cpu.regEAX >> 8;\n let nCycles = this.cpu.getCycles();\n this.cpu.addIntReturn(addr, function onBIOSRTCReturn(nLevel) {\n let sResult;\n let CL = chipset.cpu.regEDX & 0xff;\n let CH = chipset.cpu.regEDX >> 8;\n let DL = chipset.cpu.regEDX & 0xff;\n let DH = chipset.cpu.regEDX >> 8;\n if (AH == 0x02 || AH == 0x03) {\n sResult = \" CH(hour)=\" + Str.toHexWord(CH) + \" CL(min)=\" + Str.toHexByte(CL) + \" DH(sec)=\" + Str.toHexByte(DH);\n } else if (AH == 0x04 || AH == 0x05) {\n sResult = \" CX(year)=\" + Str.toHexWord(chipset.cpu.regECX) + \" DH(month)=\" + Str.toHexByte(DH) + \" DL(day)=\" + Str.toHexByte(DL);\n }\n let nCyclesDelta = -nCycles + (nCycles = chipset.cpu.getCycles());\n chipset.dbg.messageIntReturn(Interrupts.RTC, nLevel, nCyclesDelta, sResult);\n });\n }\n }\n return true;\n }\n\n /**\n * setSpeaker(fEnable)\n *\n * @this {ChipSet}\n * @param {boolean} [fEnable] true to enable speaker, false to disable it, otherwise update it as appropriate\n */\n setSpeaker(fEnable)\n {\n let fOn;\n if (fEnable !== undefined) {\n fOn = fEnable;\n if (fOn != this.fSpeakerEnabled) {\n // \n // Yielding doesn't seem to help the simulation of sound via rapid speaker toggling.\n //\n // if (this.cpu) {\n // this.cpu.yieldCPU();\n // }\n this.fSpeakerEnabled = fOn;\n }\n } else {\n fOn = !!(this.fSpeakerEnabled && this.cpu && this.cpu.isRunning());\n }\n let freq = Math.round(ChipSet.TIMER_TICKS_PER_SEC / this.getTimerInit(ChipSet.PIT0.TIMER2));\n if (freq < 20 || freq > 20000) {\n /*\n * Treat frequencies outside the normal hearing range (below 20hz or above 20Khz) as a clever\n * attempt to turn sound off.\n */\n fOn = false;\n }\n if (this.contextAudio) {\n if (fOn && this.startAudio()) {\n /*\n * Instead of setting the frequency's 'value' property directly, as we used to do, we use the\n * setValueAtTime() method, with a time of zero, as a work-around to avoid the \"easing\" (aka\n * \"de-zippering\") of the frequency that browsers like to do. Supposedly de-zippering is an\n * attempt to avoid \"pops\" if the frequency is altered while the wave is still rising or falling.\n * \n * Ditto for the gain's 'value'.\n */\n // this.oscillatorAudio['frequency']['value'] = freq;\n this.oscillatorAudio['frequency']['setValueAtTime'](freq, 0);\n // this.volumeAudio['gain']['value'] = this.volumeInit;\n this.volumeAudio['gain']['setValueAtTime'](this.volumeInit, 0);\n if (this.messageEnabled(Messages.SPEAKER)) this.printMessage(\"speaker on at \" + freq + \"hz\", true);\n } else if (this.volumeAudio) {\n this.volumeAudio['gain']['setValueAtTime'](0, 0);\n if (this.messageEnabled(Messages.SPEAKER)) this.printMessage(\"speaker off at \" + freq + \"hz\", true);\n }\n } else if (fOn && this.fSpeakerOn != fOn) {\n this.printMessage(\"BEEP\", Messages.SPEAKER);\n }\n this.fSpeakerOn = fOn;\n }\n\n /**\n * startAudio(event)\n *\n * NOTE: We currently use named properties rather than \"dot\" properties to access all the AudioContext\n * properties and methods, because we don't have any built-in declarations or externs for them, so neither\n * WebStorm nor the Closure Compiler recognize them. We could live with the WebStorm inspection warnings,\n * but we definitely can't have the Closure Compiler renaming any of the properties -- and since it\n * automatically converts them all to \"dot\" properties, there's no incentive for us to do anything more.\n *\n * @this {ChipSet}\n * @param {Event} [event] object from a 'touch' event, if any\n * @return {boolean}\n */\n startAudio(event)\n {\n if (this.contextAudio) {\n /*\n * NOTE: If the machine happened to enable its speaker *before* the user generated an event\n * (eg, touchstart) that resulted in a call here, then we're too late -- at least as far as iOS\n * devices are concerned, because those devices require the oscillator's start() method to be\n * called in the context of a user-initiated event.\n *\n * So, for the benefit of iOS devices, when we finally receive a user-generated call, we will\n * simply recreate the oscillator. This is a one-time work-around for the life of the machine.\n *\n * TODO: Consider adding a \"Sound On/Off\" button to all machines (probably in the top right corner,\n * where \"Full Screen\" and \"Lock Pointer\" buttons typically appear), at least on iOS devices.\n */\n if (event) {\n if (this.fUserSound) return true;\n this.oscillatorAudio = null;\n this.fUserSound = true;\n }\n if (this.oscillatorAudio) return true;\n try {\n this.oscillatorAudio = this.contextAudio['createOscillator']();\n if ('start' in this.oscillatorAudio) { // early versions of Web Audio used noteOn() instead of start()\n this.volumeAudio = this.contextAudio['createGain']();\n this.oscillatorAudio['connect'](this.volumeAudio);\n this.volumeAudio['connect'](this.contextAudio['destination']);\n this.volumeAudio['gain']['setValueAtTime'](0, 0);\n this.oscillatorAudio['type'] = \"square\";\n this.oscillatorAudio['start'](0);\n return true;\n }\n } catch(e) {\n this.notice(\"AudioContext exception: \" + e.message);\n this.contextAudio = null;\n }\n }\n return false;\n }\n\n /**\n * messageBitsDMA(iChannel)\n *\n * @this {ChipSet}\n * @param {number} [iChannel] if the message is associated with a particular IRQ #\n * @return {number}\n */\n messageBitsDMA(iChannel)\n {\n let bitsMessage = 0;\n if (DEBUG) {\n bitsMessage = Messages.DATA;\n if (iChannel == ChipSet.DMA_FDC) {\n bitsMessage |= Messages.FDC;\n } else if (iChannel == ChipSet.DMA_HDC) {\n bitsMessage |= Messages.HDC;\n }\n }\n return bitsMessage;\n }\n\n /**\n * messageBitsIRQ(nIRQ)\n *\n * @this {ChipSet}\n * @param {number|undefined} [nIRQ] if the message is associated with a particular IRQ #\n * @return {number}\n */\n messageBitsIRQ(nIRQ)\n {\n let bitsMessage = Messages.IRQ;\n if (nIRQ == ChipSet.IRQ.TIMER0) { // IRQ 0\n bitsMessage |= Messages.TIMER;\n } else if (nIRQ == ChipSet.IRQ.KBD) { // IRQ 1\n bitsMessage |= Messages.KBD;\n } else if (nIRQ == ChipSet.IRQ.SLAVE) { // IRQ 2\n bitsMessage = Messages.NONE; // (we're not really interested in IRQ 2 itself, just the slaves)\n } else if (nIRQ == ChipSet.IRQ.COM1 || nIRQ == ChipSet.IRQ.COM2) {\n bitsMessage |= Messages.SERIAL;\n } else if (nIRQ == ChipSet.IRQ.XTC) { // IRQ 5 (MODEL_5160)\n bitsMessage |= Messages.HDC;\n } else if (nIRQ == ChipSet.IRQ.FDC) { // IRQ 6\n bitsMessage |= Messages.FDC;\n } else if (nIRQ == ChipSet.IRQ.RTC) { // IRQ 8 (MODEL_5170 and up)\n bitsMessage |= Messages.RTC;\n } else if (nIRQ == ChipSet.IRQ.ATC) { // IRQ 14 (MODEL_5170 and up)\n bitsMessage |= Messages.HDC;\n }\n return bitsMessage;\n }\n\n /**\n * checkDMA()\n *\n * Called by the CPU whenever INTR.DMA is set.\n *\n * @return {boolean} true if one or more async DMA channels are still active (unmasked), false to reset INTR.DMA\n *\n checkDMA()\n {\n let fActive = false;\n for (let iDMAC = 0; iDMAC < this.aDMACs; iDMAC++) {\n let controller = this.aDMACs[iDMAC];\n for (let iChannel = 0; iChannel < controller.aChannels.length; iChannel++) {\n let channel = controller.aChannels[iChannel];\n if (!channel.masked) {\n this.advanceDMA(channel);\n if (!channel.masked) fActive = true;\n }\n }\n }\n return fActive;\n }\n */\n\n /**\n * ChipSet.init()\n *\n * This function operates on every HTML element of class \"chipset\", extracting the\n * JSON-encoded parameters for the ChipSet constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a ChipSet component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n let aeChipSet = Component.getElementsByClass(document, PCX86.APPCLASS, \"chipset\");\n for (let iChip = 0; iChip < aeChipSet.length; iChip++) {\n let eChipSet = aeChipSet[iChip];\n let parmsChipSet = Component.getComponentParms(eChipSet);\n let chipset = new ChipSet(parmsChipSet);\n Component.bindComponentControls(chipset, eChipSet, PCX86.APPCLASS);\n chipset.updateDIPSwitchDescriptions();\n }\n }\n}\n\n/*\n * Ports Overview\n * --------------\n *\n * This module provides support for many of the following components (except where a separate component is noted).\n * This list is taken from p.1-8 (\"System Unit\") of the IBM 5160 (PC XT) Technical Reference Manual (as revised\n * April 1983), only because I didn't see a similar listing in the original 5150 Technical Reference.\n *\n * Port(s) Description\n * ------- -----------\n * 000-00F DMA Chip 8237A-5 [see below]\n * 020-021 Interrupt 8259A [see below]\n * 040-043 Timer 8253-5 [see below]\n * 060-063 PPI 8255A-5 [see below]\n * 080-083 DMA Page Registers [see below]\n * 0Ax [1] NMI Mask Register [see below]\n * 0Cx Reserved\n * 0Ex Reserved\n * 200-20F Game Control\n * 210-217 Expansion Unit\n * 220-24F Reserved\n * 278-27F Reserved\n * 2F0-2F7 Reserved\n * 2F8-2FF Asynchronous Communications (Secondary) [see the SerialPort component]\n * 300-31F Prototype Card\n * 320-32F Hard Drive Controller (XTC) [see the HDC component]\n * 378-37F Printer\n * 380-38C [2] SDLC Communications\n * 380-389 [2] Binary Synchronous Communications (Secondary)\n * 3A0-3A9 Binary Synchronous Communications (Primary)\n * 3B0-3BF IBM Monochrome Display/Printer [see the Video component]\n * 3C0-3CF Reserved\n * 3D0-3DF Color/Graphics (Motorola 6845) [see the Video component]\n * 3EO-3E7 Reserved\n * 3FO-3F7 Floppy Drive Controller [see the FDC component]\n * 3F8-3FF Asynchronous Communications (Primary) [see the SerialPort component]\n *\n * [1] At power-on time, NMI is masked off, perhaps because models 5150 and 5160 also tie coprocessor\n * (FPU) interrupts to NMI. Suppressing NMI by default seems odd, because that would also suppress memory\n * parity errors. TODO: Determine whether \"power-on time\" refers to the initial power-on state of the\n * NMI Mask Register or the state that the BIOS \"POST\" (Power-On Self-Test) sets.\n *\n * [2] These devices cannot be used together since their port addresses overlap.\n *\n * MODEL_5170 Description\n * ---------- -----------\n * 070 [3] CMOS Address ChipSet.CMOS.ADDR.PORT\n * 071 CMOS Data ChipSet.CMOS.DATA.PORT\n * 0F0 FPU Coprocessor Clear Busy (output 0x00)\n * 0F1 FPU Coprocessor Reset (output 0x00)\n * 1F0-1F7 Hard Drive Controller (ATC) [see the HDC component]\n *\n * [3] Port 0x70 doubles as the NMI Mask Register: output a CMOS address with bit 7 clear to enable NMI\n * or with bit 7 set to disable NMI (apparently the inverse of the older NMI Mask Register at port 0xA0).\n * Also, apparently unlike previous models, the MODEL_5170 POST leaves NMI enabled. And fortunately, the\n * FPU coprocessor interrupt line is no longer tied to NMI (it uses IRQ 13).\n */\n\n/*\n * Supported model numbers\n *\n * In general, when comparing this.model to \"base\" model numbers (ie, non-REV numbers), you should use\n * (this.model|0), which truncates the current model number.\n *\n * Note that there were two 5150 motherboard revisions: the \"REV A\" 16Kb-64Kb motherboard and the\n * \"REV B\" 64Kb-256Kb motherboard. There may have been a manufacturing correlation between motherboard\n * revisions (\"REV A\" and \"REV B\") and the ROM BIOS revisions shown below, but in general, we can't assume\n * any correlation, because newer ROMs could be installed with either motherboard.\n *\n * I do know that, for \"REV A\" motherboards, the Apr 1984 5150 TechRef says that \"To expand the memory\n * of your system beyond 544K requires your IBM Personal Computer System Unit to have a BIOS ROM module\n * dated 10/27/82 or later.\" Which suggests that SW2[5] was not used until the REV3 5150 ROM BIOS.\n *\n * For now, we treat all our MODEL_5150 systems as 16Kb-64Kb motherboards; if you want a 64Kb-256Kb motherboard,\n * then step up to a MODEL_5160 system. We use a multiplier of 16 for 5150 LOWMEM values, and a multiplier\n * of 64 for 5160 LOWMEM values.\n */\nChipSet.MODEL_4860 = 4860; // PCjr\n\nChipSet.MODEL_5150 = 5150; // used in reference to the 1st 5150 ROM BIOS, dated Apr 24, 1981\nChipSet.MODEL_5150_REV2 = 5150.2; // used in reference to the 2nd 5150 ROM BIOS, dated Oct 19, 1981\nChipSet.MODEL_5150_REV3 = 5150.3; // used in reference to the 3rd 5150 ROM BIOS, dated Oct 27, 1982\nChipSet.MODEL_5150_OTHER = 5150.9;\n\nChipSet.MODEL_5160 = 5160; // used in reference to the 1st 5160 ROM BIOS, dated Nov 08, 1982\nChipSet.MODEL_5160_REV2 = 5160.2; // used in reference to the 1st 5160 ROM BIOS, dated Jan 10, 1986\nChipSet.MODEL_5160_REV3 = 5160.3; // used in reference to the 1st 5160 ROM BIOS, dated May 09, 1986\nChipSet.MODEL_5160_OTHER = 5160.9;\n\nChipSet.MODEL_5170 = 5170; // used in reference to the 1st 5170 ROM BIOS, dated Jan 10, 1984\nChipSet.MODEL_5170_REV2 = 5170.2; // used in reference to the 2nd 5170 ROM BIOS, dated Jun 10, 1985\nChipSet.MODEL_5170_REV3 = 5170.3; // used in reference to the 3rd 5170 ROM BIOS, dated Nov 15, 1985\nChipSet.MODEL_5170_OTHER = 5170.9;\n\n/*\n * Assorted non-IBM models (we don't put \"IBM\" in the IBM models, but non-IBM models should include the company name).\n */\nChipSet.MODEL_CDP_MPC1600 = 5150.101; // Columbia Data Products MPC 1600 (\"Copyright Columbia Data Products 1983, ROM/BIOS Ver 4.34\")\nChipSet.MODEL_COMPAQ_PORTABLE = 5150.102; // COMPAQ Portable (COMPAQ's first PC)\n\nChipSet.MODEL_ATT_6300 = 5160.101; // AT&T Personal Computer 6300/Olivetti M24 (\"COPYRIGHT (C) OLIVETTI 1984\",\"04/03/86\",v1.43)\nChipSet.MODEL_ZENITH_Z150 = 5160.150; // Zenith Data Systems Z-150 (\"08/11/88 (C)ZDS CORP\")\n\nChipSet.MODEL_COMPAQ_DESKPRO386 = 5180; // COMPAQ DeskPro 386 (COMPAQ's first 80386-based PC); should be > MODEL_5170\n\n/*\n * Last but not least, a complete list of supported model strings, and corresponding internal model numbers.\n */\nChipSet.MODELS = {\n \"4860\": ChipSet.MODEL_4860, // IBM PCjr\n \"5150\": ChipSet.MODEL_5150, // IBM PC\n \"5160\": ChipSet.MODEL_5160, // IBM PC XT\n \"5170\": ChipSet.MODEL_5170, // IBM PC AT\n \"att6300\": ChipSet.MODEL_ATT_6300,\n \"mpc1600\": ChipSet.MODEL_CDP_MPC1600,\n \"z150\": ChipSet.MODEL_ZENITH_Z150,\n \"compaq\": ChipSet.MODEL_COMPAQ_PORTABLE,\n \"other\": ChipSet.MODEL_5150_OTHER\n};\n\nif (DESKPRO386) {\n ChipSet.MODELS[\"deskpro386\"] = ChipSet.MODEL_COMPAQ_DESKPRO386;\n}\n\nChipSet.CONTROLS = {\n SW1: \"sw1\",\n SW2: \"sw2\",\n SWDESC: \"swdesc\"\n};\n\n/*\n * Values returned by ChipSet.getDIPVideoMonitor()\n */\nChipSet.MONITOR = {\n NONE: 0,\n TV: 1, // Composite monitor (lower resolution; no support)\n COLOR: 2, // Color Display (5153)\n MONO: 3, // Monochrome Display (5151)\n EGACOLOR: 4, // Enhanced Color Display (5154) in High-Res Mode\n EGAEMULATION: 6, // Enhanced Color Display (5154) in Emulation Mode\n VGACOLOR: 7 // VGA Color Display\n};\n\n/*\n * 8237A DMA Controller (DMAC) I/O ports\n *\n * MODEL_5150 and up uses DMA channel 0 for memory refresh cycles and channel 2 for the FDC.\n *\n * MODEL_5160 and up uses DMA channel 3 for HDC transfers (XTC only).\n *\n * DMA0 refers to the original DMA controller found on all models, and DMA1 refers to the additional\n * controller found on MODEL_5170 and up; channel 4 on DMA1 is used to \"cascade\" channels 0-3 from DMA0,\n * so only channels 5-7 are available on DMA1.\n *\n * For FDC DMA notes, refer to http://wiki.osdev.org/ISA_DMA\n * For general DMA notes, refer to http://www.freebsd.org/doc/en/books/developers-handbook/dma.html\n *\n * TODO: Determine why the MODEL_5150 ROM BIOS sets the DMA channel 1 page register (port 0x83) to zero.\n */\nChipSet.DMA0 = {\n INDEX: 0,\n PORT: {\n CH0_ADDR: 0x00, // OUT: starting address IN: current address\n CH0_COUNT: 0x01, // OUT: starting word count IN: remaining word count\n CH1_ADDR: 0x02, // OUT: starting address IN: current address\n CH1_COUNT: 0x03, // OUT: starting word count IN: remaining word count\n CH2_ADDR: 0x04, // OUT: starting address IN: current address\n CH2_COUNT: 0x05, // OUT: starting word count IN: remaining word count\n CH3_ADDR: 0x06, // OUT: starting address IN: current address\n CH3_COUNT: 0x07, // OUT: starting word count IN: remaining word count\n CMD_STATUS: 0x08, // OUT: command register IN: status register\n REQUEST: 0x09,\n MASK: 0x0A,\n MODE: 0x0B,\n RESET_FF: 0x0C, // reset flip-flop\n MASTER_CLEAR: 0x0D, // OUT: master clear IN: temporary register\n MASK_CLEAR: 0x0E, // TODO: Provide handlers\n MASK_ALL: 0x0F, // TODO: Provide handlers\n CH2_PAGE: 0x81, // OUT: DMA channel 2 page register\n CH3_PAGE: 0x82, // OUT: DMA channel 3 page register\n CH1_PAGE: 0x83, // OUT: DMA channel 1 page register\n CH0_PAGE: 0x87 // OUT: DMA channel 0 page register (unusable; See \"The Inside Out\" book, p.246)\n }\n};\nChipSet.DMA1 = {\n INDEX: 1,\n PORT: {\n CH6_PAGE: 0x89, // OUT: DMA channel 6 page register (MODEL_5170)\n CH7_PAGE: 0x8A, // OUT: DMA channel 7 page register (MODEL_5170)\n CH5_PAGE: 0x8B, // OUT: DMA channel 5 page register (MODEL_5170)\n CH4_PAGE: 0x8F, // OUT: DMA channel 4 page register (MODEL_5170; unusable; aka \"Refresh\" page register?)\n CH4_ADDR: 0xC0, // OUT: starting address IN: current address\n CH4_COUNT: 0xC2, // OUT: starting word count IN: remaining word count\n CH5_ADDR: 0xC4, // OUT: starting address IN: current address\n CH5_COUNT: 0xC6, // OUT: starting word count IN: remaining word count\n CH6_ADDR: 0xC8, // OUT: starting address IN: current address\n CH6_COUNT: 0xCA, // OUT: starting word count IN: remaining word count\n CH7_ADDR: 0xCC, // OUT: starting address IN: current address\n CH7_COUNT: 0xCE, // OUT: starting word count IN: remaining word count\n CMD_STATUS: 0xD0, // OUT: command register IN: status register\n REQUEST: 0xD2,\n MASK: 0xD4,\n MODE: 0xD6,\n RESET_FF: 0xD8, // reset flip-flop\n MASTER_CLEAR: 0xDA, // master clear\n MASK_CLEAR: 0xDC, // TODO: Provide handlers\n MASK_ALL: 0xDE // TODO: Provide handlers\n }\n};\n\nChipSet.DMA_CMD = {\n M2M_ENABLE: 0x01,\n CH0HOLD_ENABLE: 0x02,\n CTRL_DISABLE: 0x04,\n COMP_TIMING: 0x08,\n ROT_PRIORITY: 0x10,\n EXT_WRITE_SEL: 0x20,\n DREQ_ACTIVE_LO: 0x40,\n DACK_ACTIVE_HI: 0x80\n};\n\nChipSet.DMA_STATUS = {\n CH0_TC: 0x01, // Channel 0 has reached Terminal Count (TC)\n CH1_TC: 0x02, // Channel 1 has reached Terminal Count (TC)\n CH2_TC: 0x04, // Channel 2 has reached Terminal Count (TC)\n CH3_TC: 0x08, // Channel 3 has reached Terminal Count (TC)\n ALL_TC: 0x0f, // all TC bits are cleared whenever DMA_STATUS is read\n CH0_REQ: 0x10, // Channel 0 DMA requested\n CH1_REQ: 0x20, // Channel 1 DMA requested\n CH2_REQ: 0x40, // Channel 2 DMA requested\n CH3_REQ: 0x80 // Channel 3 DMA requested\n};\n\nChipSet.DMA_MASK = {\n CHANNEL: 0x03,\n CHANNEL_SET: 0x04\n};\n\nChipSet.DMA_MODE = {\n CHANNEL: 0x03, // bits 0-1 select 1 of 4 possible channels\n TYPE: 0x0C, // bits 2-3 select 1 of 3 valid (4 possible) transfer types\n TYPE_VERIFY: 0x00, // pseudo transfer (generates addresses, responds to EOP, but nothing is moved)\n TYPE_WRITE: 0x04, // write to memory (move data FROM an I/O device; eg, reading a sector from a disk)\n TYPE_READ: 0x08, // read from memory (move data TO an I/O device; eg, writing a sector to a disk)\n AUTOINIT: 0x10,\n DECREMENT: 0x20, // clear for INCREMENT\n MODE: 0xC0, // bits 6-7 select 1 of 4 possible transfer modes\n MODE_DEMAND: 0x00,\n MODE_SINGLE: 0x40,\n MODE_BLOCK: 0x80,\n MODE_CASCADE: 0xC0\n};\n\nChipSet.DMA_REFRESH = 0x00; // DMA channel assigned to memory refresh\nChipSet.DMA_FDC = 0x02; // DMA channel assigned to the Floppy Drive Controller (FDC)\nChipSet.DMA_HDC = 0x03; // DMA channel assigned to the Hard Drive Controller (HDC; XTC only)\n\n/*\n * 8259A Programmable Interrupt Controller (PIC) I/O ports\n *\n * Internal registers:\n *\n * ICW1 Initialization Command Word 1 (sent to port ChipSet.PIC_LO)\n * ICW2 Initialization Command Word 2 (sent to port ChipSet.PIC_HI)\n * ICW3 Initialization Command Word 3 (sent to port ChipSet.PIC_HI)\n * ICW4 Initialization Command Word 4 (sent to port ChipSet.PIC_HI)\n * IMR Interrupt Mask Register\n * IRR Interrupt Request Register\n * ISR Interrupt Service Register\n * IRLow (IR having lowest priority; IR+1 will have highest priority; default is 7)\n *\n * Note that ICW2 effectively contains the starting IDT vector number (ie, for IRQ 0),\n * which must be multiplied by 4 to calculate the vector offset, since every vector is 4 bytes long.\n *\n * Also, since the low 3 bits of ICW2 are ignored in 8086/8088 mode (ie, they are effectively\n * treated as zeros), this means that the starting IDT vector can only be a multiple of 8.\n *\n * So, if ICW2 is set to 0x08, the starting vector number (ie, for IRQ 0) will be 0x08, and the\n * 4-byte address for the corresponding ISR will be located at offset 0x20 in the real-mode IDT.\n *\n * ICW4 is typically set to 0x09, indicating 8086 mode, non-automatic EOI, buffered/slave mode.\n *\n * TODO: Determine why the original ROM BIOS chose buffered/slave over buffered/master.\n * Did it simply not matter in pre-AT systems with only one PIC, or am I misreading something?\n *\n * TODO: Consider support for level-triggered PIC interrupts, even though the original IBM PCs\n * (up through MODEL_5170) used only edge-triggered interrupts.\n */\nChipSet.PIC0 = { // all models: the \"master\" PIC\n INDEX: 0,\n PORT_LO: 0x20,\n PORT_HI: 0x21\n};\n\nChipSet.PIC1 = { // MODEL_5170 and up: the \"slave\" PIC\n INDEX: 1,\n PORT_LO: 0xA0,\n PORT_HI: 0xA1\n};\n\nChipSet.PIC_LO = { // ChipSet.PIC1.PORT_LO or ChipSet.PIC2.PORT_LO\n ICW1: 0x10, // set means ICW1\n ICW1_ICW4: 0x01, // ICW4 needed (otherwise ICW4 must be sent)\n ICW1_SNGL: 0x02, // single PIC (and therefore no ICW3; otherwise there is another \"cascaded\" PIC)\n ICW1_ADI: 0x04, // call address interval is 4 (otherwise 8; presumably ignored in 8086/8088 mode)\n ICW1_LTIM: 0x08, // level-triggered interrupt mode (otherwise edge-triggered mode, which is what PCs use)\n OCW2: 0x00, // bit 3 (PIC_LO.OCW3) and bit 4 (ChipSet.PIC_LO.ICW1) are clear in an OCW2 command byte\n OCW2_IR_LVL: 0x07,\n OCW2_OP_MASK: 0xE0, // of the following valid OCW2 operations, the first 4 are EOI commands (all have ChipSet.PIC_LO.OCW2_EOI set)\n OCW2_EOI: 0x20, // non-specific EOI (end-of-interrupt)\n OCW2_EOI_SPEC: 0x60, // specific EOI\n OCW2_EOI_ROT: 0xA0, // rotate on non-specific EOI\n OCW2_EOI_ROTSPEC: 0xE0, // rotate on specific EOI\n OCW2_SET_ROTAUTO: 0x80, // set rotate in automatic EOI mode\n OCW2_CLR_ROTAUTO: 0x00, // clear rotate in automatic EOI mode\n OCW2_SET_PRI: 0xC0, // bits 0-2 specify the lowest priority interrupt\n OCW3: 0x08, // bit 3 (PIC_LO.OCW3) is set and bit 4 (PIC_LO.ICW1) clear in an OCW3 command byte (bit 7 should be clear, too)\n OCW3_READ_IRR: 0x02, // read IRR register\n OCW3_READ_ISR: 0x03, // read ISR register\n OCW3_READ_CMD: 0x03,\n OCW3_POLL_CMD: 0x04, // poll\n OCW3_SMM_RESET: 0x40, // special mask mode: reset\n OCW3_SMM_SET: 0x60, // special mask mode: set\n OCW3_SMM_CMD: 0x60\n};\n\nChipSet.PIC_HI = { // ChipSet.PIC1.PORT_HI or ChipSet.PIC2.PORT_HI\n ICW2_VECTOR: 0xF8, // starting vector number (bits 0-2 are effectively treated as zeros in 8086/8088 mode)\n ICW4_8086: 0x01,\n ICW4_AUTO_EOI: 0x02,\n ICW4_MASTER: 0x04,\n ICW4_BUFFERED: 0x08,\n ICW4_FULLY_NESTED: 0x10,\n OCW1_IMR: 0xFF\n};\n\n/*\n * The priorities of IRQs 0-7 are normally high to low, unless the master PIC has been reprogrammed.\n * Also, if a slave PIC is present, the priorities of IRQs 8-15 fall between the priorities of IRQs 1 and 3.\n *\n * As the MODEL_5170 TechRef states:\n *\n * \"Interrupt requests are prioritized, with IRQ9 through IRQ12 and IRQ14 through IRQ15 having the\n * highest priority (IRQ9 is the highest) and IRQ3 through IRQ7 having the lowest priority (IRQ7 is\n * the lowest).\n *\n * Interrupt 13 (IRQ.FPU) is used on the system board and is not available on the I/O channel.\n * Interrupt 8 (IRQ.RTC) is used for the real-time clock.\"\n *\n * This priority scheme is a byproduct of IRQ8 through IRQ15 (slave PIC interrupts) being tied to IRQ2 of\n * the master PIC. As a result, the two other system board interrupts, IRQ0 and IRQ1, continue to have the\n * highest priority, by default.\n */\nChipSet.IRQ = {\n TIMER0: 0x00,\n KBD: 0x01,\n SLAVE: 0x02, // MODEL_5170\n COM2: 0x03,\n COM1: 0x04,\n XTC: 0x05, // MODEL_5160 uses IRQ 5 for HDC (XTC version)\n LPT2: 0x05, // MODEL_5170 uses IRQ 5 for LPT2\n FDC: 0x06,\n LPT1: 0x07,\n RTC: 0x08, // MODEL_5170\n IRQ2: 0x09, // MODEL_5170\n FPU: 0x0D, // MODEL_5170\n ATC: 0x0E // MODEL_5170 uses IRQ 14 for HDC (ATC version)\n};\n\n/*\n * 8253 Programmable Interval Timer (PIT) I/O ports\n *\n * Although technically, a PIT provides 3 \"counters\" rather than 3 \"timers\", we have\n * adopted IBM's TechRef nomenclature, which refers to the PIT's counters as TIMER0,\n * TIMER1, and TIMER2. For machines with a second PIT (eg, the DeskPro 386), we refer\n * to those additional counters as TIMER3, TIMER4, and TIMER5.\n *\n * In addition, if there's a need to refer to a specific PIT, use PIT0 for the first PIT\n * and PIT1 for the second. This mirrors how we refer to multiple DMA controllers\n * (eg, DMA0 and DMA1) and multiple PICs (eg, PIC0 and PIC1).\n *\n * This differs from COMPAQ's nomenclature, which used \"Timer 1\" to refer to the first\n * PIT, and \"Timer 2\" for the second PIT, and then referred to \"Counter 0\", \"Counter 1\",\n * and \"Counter 2\" within each PIT.\n */\nChipSet.PIT0 = {\n PORT: 0x40,\n INDEX: 0,\n TIMER0: 0, // used for time-of-day (prior to MODEL_5170)\n TIMER1: 1, // used for memory refresh\n TIMER2: 2 // used for speaker tone generation\n};\n\nChipSet.PIT1 = {\n PORT: 0x48, // MODEL_COMPAQ_DESKPRO386 only\n INDEX: 1,\n TIMER3: 0, // used for fail-safe clock\n TIMER4: 1, // N/A\n TIMER5: 2 // used for refresher request extend/speed control\n};\n\nChipSet.PIT_CTRL = {\n PORT1: 0x43, // write-only control register (use the Read-Back command to get status)\n PORT2: 0x4B, // write-only control register (use the Read-Back command to get status)\n BCD: 0x01,\n MODE: 0x0E,\n MODE0: 0x00, // interrupt on Terminal Count (TC)\n MODE1: 0x02, // programmable one-shot\n MODE2: 0x04, // rate generator\n MODE3: 0x06, // square wave generator\n MODE4: 0x08, // software-triggered strobe\n MODE5: 0x0A, // hardware-triggered strobe\n RW: 0x30,\n RW_LATCH: 0x00,\n RW_LSB: 0x10,\n RW_MSB: 0x20,\n RW_BOTH: 0x30,\n SC: 0xC0,\n SC_CTR0: 0x00,\n SC_CTR1: 0x40,\n SC_CTR2: 0x80,\n SC_BACK: 0xC0,\n SC_SHIFT: 6,\n RB_CTR0: 0x02,\n RB_CTR1: 0x04,\n RB_CTR2: 0x08,\n RB_STATUS: 0x10, // if this bit is CLEAR, then latch the current status of the selected counter(s)\n RB_COUNTS: 0x20, // if this bit is CLEAR, then latch the current count(s) of the selected counter(s)\n RB_NULL: 0x40, // bit set in Read-Back status byte if the counter has not been \"fully loaded\" yet\n RB_OUT: 0x80 // bit set in Read-Back status byte if fOUT is true\n};\n\nChipSet.TIMER_TICKS_PER_SEC = 1193181;\n\n/*\n * 8255A Programmable Peripheral Interface (PPI) I/O ports, for Cassette/Speaker/Keyboard/SW1/etc\n *\n * Normally, 0x99 is written to PPI_CTRL.PORT, indicating that PPI_A.PORT and PPI_C.PORT are INPUT ports\n * and PPI_B.PORT is an OUTPUT port.\n *\n * However, the MODEL_5160 ROM BIOS initially writes 0x89 instead, making PPI_A.PORT an OUTPUT port.\n * I'm guessing that's just part of some \"diagnostic mode\", because all it writes to PPI_A.PORT are a series\n * of \"checkpoint\" values (ie, 0x01, 0x02, and 0x03) before updating PPI_CTRL.PORT with the usual 0x99.\n */\nChipSet.PPI_A = { // this.bPPIA (port 0x60)\n PORT: 0x60 // INPUT: keyboard scan code (PPI_B.CLEAR_KBD must be clear)\n};\n\nChipSet.PPI_B = { // this.bPPIB (port 0x61)\n PORT: 0x61, // OUTPUT (although it has to be treated as INPUT, too; the keyboard interrupt handler reads it, OR's PPI_B.CLEAR_KBD, writes it, and then rewrites the original read value)\n CLK_TIMER2: 0x01, // ALL: set to enable clock to TIMER2\n SPK_TIMER2: 0x02, // ALL: set to connect output of TIMER2 to speaker (MODEL_5150: clear for cassette)\n ENABLE_SW2: 0x04, // MODEL_5150: set to enable SW2[1-4] through PPI_C.PORT, clear to enable SW2[5]; MODEL_5160: unused (there is no SW2 switch block on the MODEL_5160 motherboard)\n CASS_MOTOR_OFF: 0x08, // MODEL_5150: cassette motor off\n ENABLE_SW_HI: 0x08, // MODEL_5160: clear to read SW1[1-4], set to read SW1[5-8]\n DISABLE_RW_MEM: 0x10, // ALL: clear to enable RAM parity check, set to disable\n DISABLE_IO_CHK: 0x20, // ALL: clear to enable I/O channel check, set to disable\n CLK_KBD: 0x40, // ALL: clear to force keyboard clock low\n CLEAR_KBD: 0x80 // ALL: clear to enable keyboard scan codes (MODEL_5150: set to enable SW1 through PPI_A.PORT)\n};\n\nChipSet.PPI_C = { // this.bPPIC (port 0x62)\n PORT: 0x62, // INPUT (see below)\n KBD_LATCH: 0x01, // MODEL_4860 only (set if keyboard data latched)\n NO_MODEM: 0x02, // MODEL_4860 only (set if no Internal Model Card installed)\n NO_DISKETTE: 0x04, // MODEL_4860 only (set if no Diskette Drive Adapter installed)\n NO_MEMEXP: 0x08, // MODEL_4860 only (set if no 64Kb Memory Expansion installed)\n SW: 0x0F, // MODEL_5150: SW2[1-4] or SW2[5], depending on whether PPI_B.ENABLE_SW2 is set or clear; MODEL_5160: SW1[1-4] or SW1[5-8], depending on whether PPI_B.ENABLE_SW_HI is clear or set\n CASS_DATA_IN: 0x10, // MODEL_4860 and MODEL_5150 \n TIMER2_OUT: 0x20, // MODEL_4860 and up (timer 2 output)\n KBD_DATA: 0x40, // MODEL_4860 only: data from either the keyboard cable or the IR receiver\n NO_KBD_CABLE: 0x80, // MODEL_4860 only: (set if keyboard cable not connected)\n IO_CHANNEL_CHK: 0x40, // used by NMI handler to detect I/O channel errors\n RW_PARITY_CHK: 0x80 // used by NMI handler to detect R/W memory parity errors\n};\n\nChipSet.PPI_CTRL = { // this.bPPICtrl (port 0x63)\n PORT: 0x63, // OUTPUT: initialized to 0x99, defining PPI_A and PPI_C as INPUT and PPI_B as OUTPUT\n A_IN: 0x10,\n B_IN: 0x02,\n C_IN_LO: 0x01,\n C_IN_HI: 0x08,\n B_MODE: 0x04,\n A_MODE: 0x60\n};\n\n/*\n * Switches Overview\n * -----------------\n *\n * The conventions used for the sw1 and sw2 strings are that the left-most character represents DIP switch [1],\n * the right-most character represents DIP switch [8], and \"1\" means the DIP switch is ON and \"0\" means it is OFF.\n *\n * Internally, we convert the above strings into binary values that the 8255A PPI returns, where DIP switch [1]\n * is bit 0 and DIP switch [8] is bit 7, and 0 indicates the switch is ON and 1 indicates it is OFF.\n *\n * For reference, here's how the SW1 and SW2 switches correspond to the internal 8255A PPI bit values:\n *\n * SW1[1] (bit 0) \"0xxxxxxx\" (1): IPL, \"1xxxxxxx\" (0): No IPL\n * SW1[2] (bit 1) reserved on the 5150; OFF (1) if FPU installed in a 5160\n * SW1[3,4] (bits 3-2) \"xx11xxxx\" (00): 16Kb, \"xx01xxxx\" (10): 32Kb, \"xx10xxxx\" (01): 48Kb, \"xx00xxxx\" (11): 64Kb\n * SW1[5,6] (bits 5-4) \"xxxx11xx\" (00): none, \"xxxx01xx\" (10): tv, \"xxxx10xx\" (01): color, \"xxxx00xx\" (11): mono\n * SW1[7,8] (bits 7-6) \"xxxxxx11\" (00): 1 FD, \"xxxxxx01\" (10): 2 FD, \"xxxxxx10\" (01): 3 FD, \"xxxxxx00\" (11): 4 FD\n *\n * Note: FD refers to floppy drive, and IPL refers to an \"Initial Program Load\" floppy drive.\n *\n * SW2[1-5] (bits 4-0) \"NNNxxxxx\": number of 32Kb blocks of I/O expansion RAM present\n *\n * For example, sw1=\"01110011\" indicates that all SW1 DIP switches are ON, except for SW1[1], SW1[5] and SW1[6],\n * which are OFF. Internally, the order of these bits must reversed (to 11001110) and then inverted (to 00110001)\n * to yield the value that the 8255A PPI returns. Reading the final value right-to-left, 00110001 indicates an\n * IPL floppy drive, 1X of RAM (where X is 16Kb on a MODEL_5150 and 64Kb on a MODEL_5160), MDA, and 1 floppy drive.\n *\n * WARNING: It is possible to set SW1 to indicate more memory than the RAM component has been configured to provide.\n * This is a configuration error which will cause the machine to crash after reporting a \"201\" error code (memory\n * test failure), which is presumably what a real machine would do if it was similarly misconfigured. Surprisingly,\n * the BIOS forges ahead, setting SP to the top of the memory range indicated by SW1 (via INT 0x12), but the lack of\n * a valid stack causes the system to crash after the next IRET. The BIOS should have either halted or modified\n * the actual memory size to match the results of the memory test.\n *\n * MODEL 5150 Switches\n * -------------------\n *\n * PPI_SW bits are exposed via port PPI_A.\n *\n * MODEL 5160 Switches\n * ------------------------\n *\n * PPI_SW bits 0-3 are exposed via PPI_C.SW if PPI_B.ENABLE_SW_HI is clear; bits 4-7 if PPI_B.ENABLE_SW_HI is set.\n *\n * AT&T 6300 Switches\n * ------------------\n *\n * Based on ATT_PC_6300_Service_Manual.pdf, there are two 8-switch blocks, DIPSW-0 and DIPSW-1, where:\n *\n * DIPSW-0[1-4] Total RAM\n * DIPSW-0[5] - ON if 8087 not installed, OFF if installed\n * DIPSW-0[6] - ON if 8250 ACE serial interface present, OFF if Z-8530 SCC interface present\n * DIPSW-0[7] - Not used\n * DIPSW-0[8] - Type of EPROM chip for ROM 1.21 or lower, or presence of RAM in bank 1 for ROM 1.43 or higher\n *\n * and:\n *\n * DIPSW-1[1] - Floppy Type (ON for 48TPI, OFF for 96TPI)\n * DIPSW-1[2] - Floppy Speed (ON for slow startup, OFF for fast startup)\n * DIPSW-1[3] - HDU ROM (ON for indigenous, OFF for external)\n * DIPSW-1[4] - Not used (ROM 1.21 or lower) or Scroll Speed (ROM 1.43 or higher: ON for fast, OFF for slow)\n * DIPSW-1[5-6] - Display Type (11=EGA or none, 01=color 40x25, 10=color 80x25, 00=monochrome 80x25)\n * DIPSW-1[7-8] - Number of Floppy Drives (11=one, 01=two, 10=three, 00=four)\n *\n * For AT&T 6300 ROM 1.43 and up, DIPSW-0 supports the following RAM combinations:\n *\n * 0111xxx1: 128Kb on motherboard\n * 1011xxx0: 256Kb on motherboard\n * 1101xxx0: 256Kb on motherboard, 256Kb on expansion board (512Kb total)\n * 1110xxx1: 512Kb on motherboard\n * 0101xxx0: 256Kb on motherboard, 384Kb on expansion board (640Kb total)\n * 0100xxx0: 640Kb on motherboard (128Kb bank 0, 512Kb bank 1)\n * 0110xxx0: 640Kb on motherboard (512Kb bank 0, 128Kb bank 1)\n *\n * Inspection of the AT&T 6300 Plus ROM BIOS reveals that DIPSW-0[1-8] are obtained from bits 0-7\n * of port 0x66 (\"sys_conf_a\") and DIPSW-1[1-8] are obtained from bits 0-7 of port 0x67 (\"sys_conf_b\").\n */\n\nChipSet.PPI_SW = {\n FDRIVE: {\n IPL: 0x01, // MODEL_5150: IPL (\"Initial Program Load\") floppy drive attached; MODEL_5160: \"Loop on POST\"\n ONE: 0x00, // 1 floppy drive attached (or 0 drives if PPI_SW.FDRIVE_IPL is not set -- MODEL_5150 only)\n TWO: 0x40, // 2 floppy drives attached\n THREE: 0x80, // 3 floppy drives attached\n FOUR: 0xC0, // 4 floppy drives attached\n MASK: 0xC0,\n SHIFT: 6\n },\n FPU: 0x02, // MODEL_5150: reserved; MODEL_5160: FPU coprocessor installed\n MEMORY: { // MODEL_5150: \"X\" is 16Kb; MODEL_5160: \"X\" is 64Kb\n X1: 0x00, // 16Kb or 64Kb\n X2: 0x04, // 32Kb or 128Kb\n X3: 0x08, // 48Kb or 192Kb\n X4: 0x0C, // 64Kb or 256Kb\n MASK: 0x0C,\n SHIFT: 2\n },\n MONITOR: {\n TV: 0x10,\n COLOR: 0x20,\n MONO: 0x30,\n MASK: 0x30,\n SHIFT: 4\n }\n};\n\n/*\n * Some models have completely different DIP switch implementations from the MODEL_5150, which, being\n * the first IBM PC, was the model that we, um, modeled our DIP switch support on. So, to support other\n * implementations, we now get and set DIP switch values according to SWITCH_TYPE, and rely on the\n * tables that follow to define which DIP switch(es) correspond to each SWITCH_TYPE.\n *\n * Not every model needs its own tables. The getDIPSwitches() and setDIPSwitches() functions look first\n * for an *exact* model match, then a \"truncated\" model match, and failing that, they fall back to the\n * MODEL_5150 switch definitions.\n */\nChipSet.SWITCH_TYPE = {\n FLOPNUM: 1,\n FLOPTYPE: 2,\n FPU: 3,\n MONITOR: 4,\n LOWMEM: 5,\n EXPMEM: 6\n};\n\nChipSet.DIPSW = {};\nChipSet.DIPSW[ChipSet.MODEL_5150] = [{},{}];\nChipSet.DIPSW[ChipSet.MODEL_5150][0][ChipSet.SWITCH_TYPE.FLOPNUM] = {\n MASK: 0xC0,\n VALUES: {\n 1: 0x00,\n 2: 0x40,\n 3: 0x80,\n 4: 0xC0\n },\n LABEL: \"Number of Floppy Drives\"\n};\n/*\n * NOTE: Both the Aug 1981 and the Apr 1984 IBM 5150 Technical Reference Manuals list SW1[2] as \"RESERVED\",\n * but the Aug 1981 edition (p. 2-28) also says SW1[2] \"MUST BE ON (RESERVED FOR CO-PROCESSOR)\". Contemporary\n * articles discussing 8087 support in early PCs all indicate that switch SW1[2] must OFF if a coprocessor\n * is installed, and the 1984 5150 Guide to Operations (p. 5-34) confirms it.\n *\n * The Aug 1981 5150 TechRef makes no further mention of coprocessor support, whereas the Apr 1984 5150 TechRef\n * discusses it in a fair bit of detail, including the fact that 8087 exceptions generate an NMI, despite Intel's\n * warning in their iAPX 86,88 User's Manual, p. S-27, that \"[t]he 8087 should not be tied to the CPU's NMI\n * (non-maskable interrupt) line.\")\n */\nChipSet.DIPSW[ChipSet.MODEL_5150][0][ChipSet.SWITCH_TYPE.FPU] = {\n MASK: 0x02,\n VALUES: {\n 0: 0x00, // 0 means an FPU is NOT installed\n 1: 0x02 // 1 means an FPU is installed\n },\n LABEL: \"FPU\"\n};\nChipSet.DIPSW[ChipSet.MODEL_5150][0][ChipSet.SWITCH_TYPE.MONITOR] = {\n MASK: 0x30,\n VALUES: {\n 0: 0x00,\n 1: 0x10,\n 2: 0x20,\n 3: 0x30,\n \"none\": 0x00,\n \"tv\": 0x10, // aka composite\n \"color\":0x20,\n \"cga\": 0x20, // alias for color\n \"mda\": 0x30, // alias for mono\n \"mono\": 0x30,\n \"ega\": 0x00,\n \"vga\": 0x00\n },\n LABEL: \"Monitor Type\"\n};\nChipSet.DIPSW[ChipSet.MODEL_5150][0][ChipSet.SWITCH_TYPE.LOWMEM] = {\n MASK: 0x0C,\n VALUES: {\n 16: 0x00,\n 32: 0x04,\n 48: 0x08,\n 64: 0x0C\n },\n LABEL: \"Base Memory (16Kb Increments)\"\n};\nChipSet.DIPSW[ChipSet.MODEL_5150][1][ChipSet.SWITCH_TYPE.EXPMEM] = {\n MASK: 0x1F, // technically, this mask should be 0x0F for ROM revisions prior to 5150_REV3, and 0x1F on 5150_REV3\n VALUES: {\n 0: 0x00,\n 32: 0x01,\n 64: 0x02,\n 96: 0x03,\n 128: 0x04,\n 160: 0x05,\n 192: 0x06,\n 224: 0x07,\n 256: 0x08,\n 288: 0x09,\n 320: 0x0A,\n 352: 0x0B,\n 384: 0x0C,\n 416: 0x0D,\n 448: 0x0E,\n 480: 0x0F,\n 512: 0x10,\n 544: 0x11,\n 576: 0x12\n /*\n * Obviously, more bit combinations are possible here (up to 0x1F), but assuming a minimum of 64Kb already on\n * the motherboard, any amount of expansion memory above 576Kb would break the 640Kb barrier. Yes, if you used\n * only MDA or CGA video cards, you could go as high as 704Kb in a real system. But in our happy little world,\n * this is where we stop.\n *\n * TODO: A value larger than 0x12 usually comes from a misconfigured machine (ie, it forgot to leave SW2[5] ON).\n * To compensate, when getDIPMemorySize() gets null back from its EXPMEM request, perhaps it should try truncating\n * the DIP switch value. However, that would introduce a machine-specific hack into a function that's supposed\n * be machine-independent now.\n */\n },\n LABEL: \"Expansion Memory (32Kb Increments)\"\n};\n\nChipSet.DIPSW[ChipSet.MODEL_5160] = [{},{}];\nChipSet.DIPSW[ChipSet.MODEL_5160][0][ChipSet.SWITCH_TYPE.FLOPNUM] = ChipSet.DIPSW[ChipSet.MODEL_5150][0][ChipSet.SWITCH_TYPE.FLOPNUM];\nChipSet.DIPSW[ChipSet.MODEL_5160][0][ChipSet.SWITCH_TYPE.FPU] = ChipSet.DIPSW[ChipSet.MODEL_5150][0][ChipSet.SWITCH_TYPE.FPU];\nChipSet.DIPSW[ChipSet.MODEL_5160][0][ChipSet.SWITCH_TYPE.MONITOR] = ChipSet.DIPSW[ChipSet.MODEL_5150][0][ChipSet.SWITCH_TYPE.MONITOR];\nChipSet.DIPSW[ChipSet.MODEL_5160][0][ChipSet.SWITCH_TYPE.LOWMEM] = {\n MASK: 0x0C,\n VALUES: {\n 64: 0x00,\n 128: 0x04,\n 192: 0x08,\n 256: 0x0C\n },\n LABEL: \"Base Memory (64Kb Increments)\"\n};\nChipSet.DIPSW[ChipSet.MODEL_5160][1][ChipSet.SWITCH_TYPE.EXPMEM] = ChipSet.DIPSW[ChipSet.MODEL_5150][1][ChipSet.SWITCH_TYPE.EXPMEM];\n\nChipSet.DIPSW[ChipSet.MODEL_ATT_6300] = [{},{}];\nChipSet.DIPSW[ChipSet.MODEL_ATT_6300][0][ChipSet.SWITCH_TYPE.LOWMEM] = {\n MASK: 0x8F,\n VALUES: {\n 128: 0x01, // \"0111xxx1\"\n 256: 0x82, // \"1011xxx0\"\n 512: 0x08, // \"1110xxx1\"\n 640: 0x8D // \"0100xxx0\"\n },\n LABEL: \"Base Memory (128Kb Increments)\"\n};\nChipSet.DIPSW[ChipSet.MODEL_ATT_6300][0][ChipSet.SWITCH_TYPE.FPU] = {\n MASK: 0x10,\n VALUES: {\n 0: 0x00,\n 1: 0x10\n },\n LABEL: \"FPU\"\n};\nChipSet.DIPSW[ChipSet.MODEL_ATT_6300][1][ChipSet.SWITCH_TYPE.FLOPTYPE] = {\n MASK: 0x01,\n VALUES: {\n 0: 0x00,\n 1: 0x01\n },\n LABEL: \"Floppy Type\"\n};\nChipSet.DIPSW[ChipSet.MODEL_ATT_6300][1][ChipSet.SWITCH_TYPE.FLOPNUM] = ChipSet.DIPSW[ChipSet.MODEL_5150][0][ChipSet.SWITCH_TYPE.FLOPNUM];\nChipSet.DIPSW[ChipSet.MODEL_ATT_6300][1][ChipSet.SWITCH_TYPE.MONITOR] = ChipSet.DIPSW[ChipSet.MODEL_5150][0][ChipSet.SWITCH_TYPE.MONITOR];\n\n/*\n * 8041 Keyboard Controller I/O ports (MODEL_ATT_6300)\n *\n * The AT&T 6300 uses an 8041 for its Keyboard Controller, which has the following ports:\n *\n * Port Description\n * ---- -----------\n * 0x60 Keyboard Scan Code (input)\n * 0x61 Keyboard Control Port (output)\n * 0x64 Keyboard Status Port (input)\n *\n * And the Keyboard Control Port (0x61) has the following bit definitions:\n *\n * 0x01 Speaker gate to 8253 (counter 2)\n * 0x02 Speaker data\n * 0x0C Not used\n * 0x10 RAM Parity (NMI) Enable\n * 0x20 I/O Channel (NMI) Enable\n * 0x40 Keyboard Clock Reset\n * 0x80 Reset Interrupt Pending\n */\n\n/*\n * 8042 Keyboard Controller I/O ports (MODEL_5170)\n *\n * On the MODEL_5170, port 0x60 is designated C8042.DATA rather than PPI_A, although the BIOS also refers to it\n * as \"PORT_A: 8042 KEYBOARD SCAN/DIAG OUTPUTS\"). This is the 8042's output buffer and should be read only when\n * C8042.STATUS.OUTBUFF_FULL is set.\n *\n * Similarly, port 0x61 is designated C8042.RWREG rather than PPI_B; the BIOS also refers to it as \"PORT_B: 8042\n * READ WRITE REGISTER\", but it is not otherwise discussed in the MODEL_5170 TechRef's 8042 documentation.\n *\n * There are brief references to bits 0 and 1 (C8042.RWREG.CLK_TIMER2 and C8042.RWREG.SPK_TIMER2), and the BIOS sets\n * bits 2-7 to \"DISABLE PARITY CHECKERS\" (principally C8042.RWREG.DISABLE_NMI, which are bits 2 and 3); why the BIOS\n * also sets bits 4-7 (or if those bits are even settable) is unclear, since it uses 11111100b rather than defined\n * constants.\n *\n * The bottom line: on a MODEL_5170, port 0x61 is still used for speaker control and parity checking, so we use\n * the same register (bPPIB) but install different I/O handlers. It's also bi-directional: at one point, the BIOS\n * reads C8042.RWREG.REFRESH_BIT (bit 4) to verify that it's alternating.\n *\n * PPI_C and PPI_CTRL don't seem to be documented or used by the MODEL_5170 BIOS, so I'm assuming they're obsolete.\n *\n * NOTE: For more information on the 8042 Controller, including information on undocumented commands, refer to the\n * documents in /devices/pc/keyboard, as well as the following websites:\n *\n * http://halicery.com/8042/8042_INTERN_TXT.htm\n * http://www.os2museum.com/wp/ibm-pcat-8042-keyboard-controller-commands/\n */\nChipSet.C8042 = {\n DATA: { // this.b8042OutBuff (PPI_A on previous models, still referred to as \"PORT A\" by the MODEL_5170 BIOS)\n PORT: 0x60,\n CMD: { // this.b8042CmdData (C8042.DATA.CMD \"data bytes\" written to port 0x60, after writing a C8042.CMD byte to port 0x64)\n INT_ENABLE: 0x01, // generate an interrupt when the controller places data in the output buffer\n SYS_FLAG: 0x04, // this value is propagated to ChipSet.C8042.STATUS.SYS_FLAG\n NO_INHIBIT: 0x08, // disable inhibit function\n NO_CLOCK: 0x10, // disable keyboard by driving \"clock\" line low\n PC_MODE: 0x20,\n PC_COMPAT: 0x40 // generate IBM PC-compatible scan codes\n },\n SELF_TEST: { // result of ChipSet.C8042.CMD.SELF_TEST command (0xAA)\n OK: 0x55\n },\n INTF_TEST: { // result of ChipSet.C8042.CMD.INTF_TEST command (0xAB)\n OK: 0x00, // no error\n CLOCK_LO: 0x01, // keyboard clock line stuck low\n CLOCK_HI: 0x02, // keyboard clock line stuck high\n DATA_LO: 0x03, // keyboard data line stuck low\n DATA_HI: 0x04 // keyboard data line stuck high\n }\n },\n INPORT: { // this.b8042InPort\n COMPAQ_50MHZ: 0x01, // 50Mhz system clock enabled (0=48Mhz); see COMPAQ 386/25 TechRef p2-106\n UNDEFINED: 0x02, // undefined\n COMPAQ_NO80387: 0x04, // 80387 coprocessor NOT installed; see COMPAQ 386/25 TechRef p2-106\n COMPAQ_NOWEITEK:0x08, // Weitek coprocessor NOT installed; see COMPAQ 386/25 TechRef p2-106\n ENABLE_256KB: 0x10, // enable 2nd 256Kb of system board RAM\n COMPAQ_HISPEED: 0x10, // high-speed enabled (0=auto); see COMPAQ 386/25 TechRef p2-106\n MFG_OFF: 0x20, // manufacturing jumper not installed\n COMPAQ_DIP5OFF: 0x20, // system board DIP switch #5 OFF (0=ON); see COMPAQ 386/25 TechRef p2-106\n MONO: 0x40, // monochrome monitor is primary display\n COMPAQ_NONDUAL: 0x40, // COMPAQ Dual-Mode monitor NOT installed; see COMPAQ 386/25 TechRef p2-106\n KBD_UNLOCKED: 0x80 // keyboard not inhibited (in COMPAQ parlance: security lock is unlocked)\n },\n OUTPORT: { // this.b8042OutPort\n NO_RESET: 0x01, // set by default\n A20_ON: 0x02, // set by default\n COMPAQ_SLOWD: 0x08, // SL0WD* NOT asserted (refer to timer 2, counter 2); see COMPAQ 386/25 TechRef p2-105\n OUTBUFF_FULL: 0x10, // output buffer full\n INBUFF_EMPTY: 0x20, // input buffer empty\n KBD_CLOCK: 0x40, // keyboard clock (output)\n KBD_DATA: 0x80 // keyboard data (output)\n },\n TESTPORT: { // generated \"on the fly\"\n KBD_CLOCK: 0x01, // keyboard clock (input)\n KBD_DATA: 0x02 // keyboard data (input)\n },\n RWREG: { // this.bPPIB (since CLK_TIMER2 and SPK_TIMER2 are in both PPI_B and RWREG)\n PORT: 0x61,\n CLK_TIMER2: 0x01, // set to enable clock to TIMER2 (R/W)\n SPK_TIMER2: 0x02, // set to connect output of TIMER2 to speaker (R/W)\n COMPAQ_FSNMI: 0x04, // set to disable RAM/FS NMI (R/W, DESKPRO386)\n COMPAQ_IONMI: 0x08, // set to disable IOCHK NMI (R/W, DESKPRO386)\n DISABLE_NMI: 0x0C, // set to disable IOCHK and RAM/FS NMI, clear to enable (R/W)\n REFRESH_BIT: 0x10, // 0 if RAM refresh occurring, 1 if RAM not in refresh cycle (R/O)\n OUT_TIMER2: 0x20, // state of TIMER2 output signal (R/O, DESKPRO386)\n IOCHK_NMI: 0x40, // IOCHK NMI (R/O); to reset, pulse bit 3 (0x08)\n RAMFS_NMI: 0x80, // RAM/FS (parity or fail-safe) NMI (R/O); to reset, pulse bit 2 (0x04)\n NMI_ERROR: 0xC0\n },\n CMD: { // this.b8042InBuff (on write to port 0x64, interpret this as a CMD)\n PORT: 0x64,\n READ_CMD: 0x20, // sends the current CMD byte (this.b8042CmdData) to C8042.DATA.PORT\n WRITE_CMD: 0x60, // followed by a command byte written to C8042.DATA.PORT (see C8042.DATA.CMD)\n COMPAQ_SLOWD: 0xA3, // enable system slow down; see COMPAQ 386/25 TechRef p2-111\n COMPAQ_TOGGLE: 0xA4, // toggle speed-control bit; see COMPAQ 386/25 TechRef p2-111\n COMPAQ_SPCREAD: 0xA5, // special read of \"port 2\"; see COMPAQ 386/25 TechRef p2-111\n SELF_TEST: 0xAA, // self-test (C8042.DATA.SELF_TEST.OK is placed in the output buffer if no errors)\n INTF_TEST: 0xAB, // interface test\n DIAG_DUMP: 0xAC, // diagnostic dump\n DISABLE_KBD: 0xAD, // disable keyboard\n ENABLE_KBD: 0xAE, // enable keyboard\n READ_INPORT: 0xC0, // read input port and place data in output buffer (use only if output buffer empty)\n READ_OUTPORT: 0xD0, // read output port and place data in output buffer (use only if output buffer empty)\n WRITE_OUTPORT: 0xD1, // next byte written to C8042.DATA.PORT (port 0x60) is placed in the output port (see C8042.OUTPORT)\n READ_TEST: 0xE0,\n PULSE_OUTPORT: 0xF0 // this is the 1st of 16 commands (0xF0-0xFF) that pulse bits 0-3 of the output port\n },\n STATUS: { // this.b8042Status (on read from port 0x64)\n PORT: 0x64,\n OUTBUFF_FULL: 0x01,\n INBUFF_FULL: 0x02, // set if the controller has received but not yet read data from the input buffer (not normally set)\n SYS_FLAG: 0x04,\n CMD_FLAG: 0x08, // set on write to C8042.CMD (port 0x64), clear on write to C8042.DATA (port 0x60)\n NO_INHIBIT: 0x10, // (in COMPAQ parlance: security lock not engaged)\n XMT_TIMEOUT: 0x20,\n RCV_TIMEOUT: 0x40,\n PARITY_ERR: 0x80, // last byte of data received had EVEN parity (ODD parity is normally expected)\n OUTBUFF_DELAY: 0x100\n }\n};\n\n/*\n * MC146818A RTC/CMOS Ports (MODEL_5170)\n *\n * Write a CMOS address to ChipSet.CMOS.ADDR.PORT, then read/write data from/to ChipSet.CMOS.DATA.PORT.\n *\n * The ADDR port also controls NMI: write an address with bit 7 clear to enable NMI or set to disable NMI.\n */\nChipSet.CMOS = {\n ADDR: { // this.bCMOSAddr\n PORT: 0x70,\n RTC_SEC: 0x00,\n RTC_SEC_ALRM: 0x01,\n RTC_MIN: 0x02,\n RTC_MIN_ALRM: 0x03,\n RTC_HOUR: 0x04,\n RTC_HOUR_ALRM: 0x05,\n RTC_WEEK_DAY: 0x06,\n RTC_MONTH_DAY: 0x07,\n RTC_MONTH: 0x08,\n RTC_YEAR: 0x09, // 2-digit year (eg, 0x82 for 1982 if BCD mode)\n STATUSA: 0x0A,\n STATUSB: 0x0B,\n STATUSC: 0x0C,\n STATUSD: 0x0D,\n DIAG: 0x0E,\n SHUTDOWN: 0x0F,\n FDRIVE: 0x10,\n HDRIVE: 0x12, // bits 4-7 contain type of drive 0, bits 0-3 contain type of drive 1 (type 0 means none)\n EQUIP: 0x14,\n BASEMEM_LO: 0x15,\n BASEMEM_HI: 0x16, // the BASEMEM values indicate the total Kb of base memory, up to 0x280 (640Kb)\n EXTMEM_LO: 0x17,\n EXTMEM_HI: 0x18, // the EXTMEM values indicate the total Kb of extended memory, up to 0x3C00 (15Mb)\n EXTHDRIVE0: 0x19, // if bits 4-7 of HDRIVE contains 15, then the type of drive 0 is stored here (16-255)\n EXTHDRIVE1: 0x1A, // if bits 0-3 of HDRIVE contains 15, then the type of drive 1 is stored here (16-255)\n CHKSUM_HI: 0x2E,\n CHKSUM_LO: 0x2F, // CMOS bytes included in the checksum calculation: 0x10-0x2D\n EXTMEM2_LO: 0x30,\n EXTMEM2_HI: 0x31,\n CENTURY_DATE: 0x32, // 2-digit century value in BCD (eg, 0x19 for 20th century, 0x20 for 21st century)\n BOOT_INFO: 0x33, // 0x80 if 128Kb expansion memory installed, 0x40 if Setup Utility wants an initial setup message\n MASK: 0x3F,\n TOTAL: 0x40,\n NMI_DISABLE: 0x80\n },\n DATA: { // this.abCMOSData\n PORT: 0x71\n },\n STATUSA: { // abCMOSData[ChipSet.CMOS.ADDR.STATUSA]\n UIP: 0x80, // bit 7: 1 indicates Update-In-Progress, 0 indicates date/time ready to read\n DV: 0x70, // bits 6-4 (DV2-DV0) are programmed to 010 to select a 32.768Khz time base\n RS: 0x0F // bits 3-0 (RS3-RS0) are programmed to 0110 to select a 976.562us interrupt rate\n },\n STATUSB: { // abCMOSData[ChipSet.CMOS.ADDR.STATUSB]\n SET: 0x80, // bit 7: 1 to set any/all of the 14 time-bytes\n PIE: 0x40, // bit 6: 1 for Periodic Interrupt Enable\n AIE: 0x20, // bit 5: 1 for Alarm Interrupt Enable\n UIE: 0x10, // bit 4: 1 for Update Interrupt Enable\n SQWE: 0x08, // bit 3: 1 for Square Wave Enabled (as set by the STATUSA rate selection bits)\n BINARY: 0x04, // bit 2: 1 for binary Date Mode, 0 for BCD Date Mode\n HOUR24: 0x02, // bit 1: 1 for 24-hour mode, 0 for 12-hour mode\n DST: 0x01 // bit 0: 1 for Daylight Savings Time enabled\n },\n STATUSC: { // abCMOSData[ChipSet.CMOS.ADDR.STATUSC]\n IRQF: 0x80, // bit 7: 1 indicates one or more of the following bits (PF, AF, UF) are set\n PF: 0x40, // bit 6: 1 indicates Periodic Interrupt\n AF: 0x20, // bit 5: 1 indicates Alarm Interrupt\n UF: 0x10, // bit 4: 1 indicates Update Interrupt\n RESERVED: 0x0F\n },\n STATUSD: { // abCMOSData[ChipSet.CMOS.ADDR.STATUSD]\n VRB: 0x80, // bit 7: 1 indicates Valid RAM Bit (0 implies power was and/or is lost)\n RESERVED: 0x7F\n },\n DIAG: { // abCMOSData[ChipSet.CMOS.ADDR.DIAG]\n RTCFAIL: 0x80, // bit 7: 1 indicates RTC lost power\n CHKSUMFAIL: 0x40, // bit 6: 1 indicates bad CMOS checksum\n CONFIGFAIL: 0x20, // bit 5: 1 indicates bad CMOS configuration info\n MEMSIZEFAIL: 0x10, // bit 4: 1 indicates memory size miscompare\n HDRIVEFAIL: 0x08, // bit 3: 1 indicates hard drive controller or drive init failure\n TIMEFAIL: 0x04, // bit 2: 1 indicates time failure\n RESERVED: 0x03\n },\n FDRIVE: { // abCMOSData[ChipSet.CMOS.ADDR.FDRIVE]\n D0_MASK: 0xF0, // Drive 0 type in high nibble\n D1_MASK: 0x0F, // Drive 1 type in lower nibble\n NONE: 0, // no drive\n /*\n * There's at least one floppy drive type that IBM didn't bother defining a CMOS drive type for:\n * single-sided drives that were only capable of storing 160Kb (or 180Kb when using 9 sectors/track).\n * So, as you can see in getDIPFloppyDriveType(), we lump all standard diskette capacities <= 360Kb\n * into the FD360 bucket.\n */\n FD360: 1, // 5.25-inch double-sided double-density (DSDD 48TPI) drive: 40 tracks, 9 sectors/track, 360Kb max\n FD1200: 2, // 5.25-inch double-sided high-density (DSHD 96TPI) drive: 80 tracks, 15 sectors/track, 1200Kb max\n FD720: 3, // 3.5-inch drive capable of storing 80 tracks and up to 9 sectors/track, 720Kb max\n FD1440: 4 // 3.5-inch drive capable of storing 80 tracks and up to 18 sectors/track, 1440Kb max\n },\n /*\n * HDRIVE types are defined by table in the HDC component, which uses setCMOSDriveType() to update the CMOS\n */\n HDRIVE: { // abCMOSData[ChipSet.CMOS.ADDR.HDRIVE]\n D0_MASK: 0xF0, // Drive 0 type in high nibble\n D1_MASK: 0x0F // Drive 1 type in lower nibble\n },\n /*\n * The CMOS equipment flags use the same format as the older PPI equipment flags\n */\n EQUIP: { // abCMOSData[ChipSet.CMOS.ADDR.EQUIP]\n MONITOR: ChipSet.PPI_SW.MONITOR, // PPI_SW.MONITOR.MASK == 0x30\n FPU: ChipSet.PPI_SW.FPU, // PPI_SW.FPU == 0x02\n FDRIVE: ChipSet.PPI_SW.FDRIVE // PPI_SW.FDRIVE.IPL == 0x01 and PPI_SW.FDRIVE.MASK = 0xC0\n }\n};\n\n/*\n * DMA Page Registers\n *\n * The MODEL_5170 TechRef lists 0x80-0x9F as the range for DMA page registers, but that may be a bit\n * overbroad. There are a total of 8 (7 usable) DMA channels on the MODEL_5170, each of which has the\n * following assigned DMA page registers:\n *\n * Channel # Page Reg\n * --------- --------\n * 0 0x87\n * 1 0x83\n * 2 0x81\n * 3 0x82\n * 4 0x8F (not usable; the 5170 TechRef refers to this as the \"Refresh\" page register)\n * 5 0x8B\n * 6 0x89\n * 7 0x8A\n *\n * That leaves 0x80, 0x84, 0x85, 0x86, 0x88, 0x8C, 0x8D and 0x8E unaccounted for in the range 0x80-0x8F.\n * (I'm saving the question of what, if anything, is available in the range 0x90-0x9F for another day.)\n *\n * As for port 0x80, the TechRef says:\n *\n * \"I/O address hex 080 is used as a diagnostic-checkpoint port or register.\n * This port corresponds to a read/write register in the DMA page register (74LS612).\"\n *\n * so I used to have dedicated handlers and storage (bMFGData) for the register at port 0x80, but I've since\n * appended it to abDMAPageSpare, an 8-element array that captures all I/O to the 8 unassigned (aka \"spare\")\n * DMA page registers. The 5170 BIOS uses 0x80 as a \"checkpoint\" register, and the DESKPRO386 uses 0x84 in a\n * similar fashion. The 5170 also contains \"MFG_TST\" code that uses other unassigned DMA page registers as\n * scratch registers, which come in handy when RAM hasn't been tested/initialized yet.\n *\n * Here's our mapping of entries in the abDMAPageSpare array to the unassigned (\"spare\") DMA page registers:\n *\n * Index # Page Reg\n * -------- --------\n * 0 0x84\n * 1 0x85\n * 2 0x86\n * 3 0x88\n * 4 0x8C\n * 5 0x8D\n * 6 0x8E\n * 7 0x80\n *\n * The only reason port 0x80 is out of sequence (ie, at the end of the array, at index 7 instead of index 0) is\n * because it was added the array later, and the entire array gets written to our save/restore data structures, so\n * reordering the elements would be a bad idea.\n */\n\n/*\n * NMI Mask Register (port 0xA0)\n * \n * On the MODEL_5150 and MODEL_5160, this is a write-only register, and the only valid bit is ENABLE.\n * \n * On the MODEL_4860, this is a read-write register; the following bit definitions apply to writes, whereas\n * reads are defined as merely clearing the PCjr's keyboard NMI latch (which we maintain here in bit 0). \n */\nChipSet.NMI = { // this.bNMI\n PORT: 0xA0, //\n ENABLE: 0x80, // enables NMI\n IRTEST: 0x40, // enables 8253 timer 2 output into an IR diode on the IR receiver board\n SELCLK1: 0x20, // selects timer 0 output to be used as CLK input to timer 1\n DISHRQ: 0x10, // not implemented on the system board; for use with external bus-master devices\n KBD_LATCH: 0x01, // keyboard latch (we maintain it here for convenience; it gets propagated to PPI_C bit 0)\n RESET: 0x00 // default value on reset (TODO: Is NMI really disabled by default on reset?)\n};\n\n/*\n * FPU Coprocessor Control Registers (MODEL_5170)\n */\nChipSet.FPU = { // TODO: Define a variable for this?\n PORT_CLEAR: 0xF0, // clear the FPU's \"busy\" state\n PORT_RESET: 0xF1 // reset the FPU\n};\n\nChipSet.aDMAControllerInit = [0, null, null, 0, new Array(4), 0];\n\nChipSet.aDMAChannelInit = [true, [0,0], [0,0], [0,0], [0,0]];\n\nChipSet.aPICInit = [0, new Array(4)];\n\nChipSet.aTimerInit = [[0,0], [0,0], [0,0], [0,0]];\n\n/*\n * Port input notification tables, starting with the one that's common to all models (aPortInput)\n */\nChipSet.aPortInput = {\n 0x20: /** @this {ChipSet} */ function(port, addrFrom) { return this.inPICLo(ChipSet.PIC0.INDEX, addrFrom); },\n 0x21: /** @this {ChipSet} */ function(port, addrFrom) { return this.inPICHi(ChipSet.PIC0.INDEX, addrFrom); },\n 0x40: /** @this {ChipSet} */ function(port, addrFrom) { return this.inTimer(ChipSet.PIT0.INDEX, ChipSet.PIT0.TIMER0, port, addrFrom); },\n 0x41: /** @this {ChipSet} */ function(port, addrFrom) { return this.inTimer(ChipSet.PIT0.INDEX, ChipSet.PIT0.TIMER1, port, addrFrom); },\n 0x42: /** @this {ChipSet} */ function(port, addrFrom) { return this.inTimer(ChipSet.PIT0.INDEX, ChipSet.PIT0.TIMER2, port, addrFrom); },\n 0x43: /** @this {ChipSet} */ function(port, addrFrom) { return this.inTimerCtrl(ChipSet.PIT0.INDEX, port, addrFrom); },\n};\n\nChipSet.aPortInput4860 = {\n 0x60: ChipSet.prototype.inPPIA,\n 0x61: ChipSet.prototype.inPPIB,\n 0x62: ChipSet.prototype.inPPIC,\n 0x63: ChipSet.prototype.inPPICtrl, // technically, not actually readable, but I want the Debugger to be able to read it\n 0xA0: ChipSet.prototype.inNMI\n};\n\nChipSet.aPortInput5150 = {\n 0x60: ChipSet.prototype.inPPIA,\n 0x61: ChipSet.prototype.inPPIB,\n 0x62: ChipSet.prototype.inPPIC,\n 0x63: ChipSet.prototype.inPPICtrl, // technically, not actually readable, but I want the Debugger to be able to read it\n};\n\nChipSet.aPortInput5xxx = {\n 0x00: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelAddr(ChipSet.DMA0.INDEX, 0, port, addrFrom); },\n 0x01: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelCount(ChipSet.DMA0.INDEX, 0, port, addrFrom); },\n 0x02: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelAddr(ChipSet.DMA0.INDEX, 1, port, addrFrom); },\n 0x03: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelCount(ChipSet.DMA0.INDEX, 1, port, addrFrom); },\n 0x04: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelAddr(ChipSet.DMA0.INDEX, 2, port, addrFrom); },\n 0x05: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelCount(ChipSet.DMA0.INDEX, 2, port, addrFrom); },\n 0x06: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelAddr(ChipSet.DMA0.INDEX, 3, port, addrFrom); },\n 0x07: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelCount(ChipSet.DMA0.INDEX, 3, port, addrFrom); },\n 0x08: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAStatus(ChipSet.DMA0.INDEX, port, addrFrom); },\n 0x0D: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMATemp(ChipSet.DMA0.INDEX, port, addrFrom); },\n 0x81: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageReg(ChipSet.DMA0.INDEX, 2, port, addrFrom); },\n 0x82: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageReg(ChipSet.DMA0.INDEX, 3, port, addrFrom); },\n 0x83: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageReg(ChipSet.DMA0.INDEX, 1, port, addrFrom); },\n 0x87: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageReg(ChipSet.DMA0.INDEX, 0, port, addrFrom); }\n};\n\nChipSet.aPortInput5170 = {\n 0x60: ChipSet.prototype.in8042OutBuff,\n 0x61: ChipSet.prototype.in8042RWReg,\n 0x64: ChipSet.prototype.in8042Status,\n 0x70: ChipSet.prototype.inCMOSAddr,\n 0x71: ChipSet.prototype.inCMOSData,\n 0x80: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageSpare(7, port, addrFrom); },\n 0x84: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageSpare(0, port, addrFrom); },\n 0x85: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageSpare(1, port, addrFrom); },\n 0x86: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageSpare(2, port, addrFrom); },\n 0x88: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageSpare(3, port, addrFrom); },\n 0x89: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageReg(ChipSet.DMA1.INDEX, 2, port, addrFrom); },\n 0x8A: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageReg(ChipSet.DMA1.INDEX, 3, port, addrFrom); },\n 0x8B: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageReg(ChipSet.DMA1.INDEX, 1, port, addrFrom); },\n 0x8C: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageSpare(4, port, addrFrom); },\n 0x8D: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageSpare(5, port, addrFrom); },\n 0x8E: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageSpare(6, port, addrFrom); },\n 0x8F: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageReg(ChipSet.DMA1.INDEX, 0, port, addrFrom); },\n 0xA0: /** @this {ChipSet} */ function(port, addrFrom) { return this.inPICLo(ChipSet.PIC1.INDEX, addrFrom); },\n 0xA1: /** @this {ChipSet} */ function(port, addrFrom) { return this.inPICHi(ChipSet.PIC1.INDEX, addrFrom); },\n 0xC0: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelAddr(ChipSet.DMA1.INDEX, 0, port, addrFrom); },\n 0xC2: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelCount(ChipSet.DMA1.INDEX, 0, port, addrFrom); },\n 0xC4: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelAddr(ChipSet.DMA1.INDEX, 1, port, addrFrom); },\n 0xC6: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelCount(ChipSet.DMA1.INDEX, 1, port, addrFrom); },\n 0xC8: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelAddr(ChipSet.DMA1.INDEX, 2, port, addrFrom); },\n 0xCA: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelCount(ChipSet.DMA1.INDEX, 2, port, addrFrom); },\n 0xCC: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelAddr(ChipSet.DMA1.INDEX, 3, port, addrFrom); },\n 0xCE: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAChannelCount(ChipSet.DMA1.INDEX, 3, port, addrFrom); },\n 0xD0: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAStatus(ChipSet.DMA1.INDEX, port, addrFrom); },\n 0xDA: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMATemp(ChipSet.DMA1.INDEX, port, addrFrom); }\n};\n\nChipSet.aPortInput6300 = {\n 0x60: ChipSet.prototype.in8041Kbd,\n 0x61: ChipSet.prototype.in8041Ctrl,\n 0x64: ChipSet.prototype.in8041Status,\n 0x66: /** @this {ChipSet} */ function(port, addrFrom) { return this.in6300DIPSwitches(0, port, addrFrom); },\n 0x67: /** @this {ChipSet} */ function(port, addrFrom) { return this.in6300DIPSwitches(1, port, addrFrom); }\n};\n\nif (DESKPRO386) {\n ChipSet.aPortInputDeskPro386 = {\n 0x48: /** @this {ChipSet} */ function(port, addrFrom) { return this.inTimer(ChipSet.PIT1.INDEX, ChipSet.PIT1.TIMER3, port, addrFrom); },\n 0x49: /** @this {ChipSet} */ function(port, addrFrom) { return this.inTimer(ChipSet.PIT1.INDEX, ChipSet.PIT1.TIMER4, port, addrFrom); },\n 0x4A: /** @this {ChipSet} */ function(port, addrFrom) { return this.inTimer(ChipSet.PIT1.INDEX, ChipSet.PIT1.TIMER5, port, addrFrom); },\n 0x4B: /** @this {ChipSet} */ function(port, addrFrom) { return this.inTimerCtrl(ChipSet.PIT1.INDEX, port, addrFrom); }\n };\n}\n\n/*\n * Port output notification tables, starting with the one that's common to all models (aPortOutput)\n */\nChipSet.aPortOutput = {\n 0x20: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outPICLo(ChipSet.PIC0.INDEX, bOut, addrFrom); },\n 0x21: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outPICHi(ChipSet.PIC0.INDEX, bOut, addrFrom); },\n 0x40: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outTimer(ChipSet.PIT0.INDEX, ChipSet.PIT0.TIMER0, port, bOut, addrFrom); },\n 0x41: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outTimer(ChipSet.PIT0.INDEX, ChipSet.PIT0.TIMER1, port, bOut, addrFrom); },\n 0x42: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outTimer(ChipSet.PIT0.INDEX, ChipSet.PIT0.TIMER2, port, bOut, addrFrom); },\n 0x43: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outTimerCtrl(ChipSet.PIT0.INDEX, port, bOut, addrFrom); },\n};\n\nChipSet.aPortOutput4860 = {\n 0x10: ChipSet.prototype.outMFGTest, // a manufacturing test port that we don't really care about \n 0x60: ChipSet.prototype.outPPIA,\n 0x61: ChipSet.prototype.outPPIB,\n 0x62: ChipSet.prototype.outPPIC,\n 0x63: ChipSet.prototype.outPPICtrl,\n 0xA0: ChipSet.prototype.outNMI\n};\n\nChipSet.aPortOutput5150 = {\n 0x60: ChipSet.prototype.outPPIA,\n 0x61: ChipSet.prototype.outPPIB,\n 0x62: ChipSet.prototype.outPPIC,\n 0x63: ChipSet.prototype.outPPICtrl,\n 0xA0: ChipSet.prototype.outNMI\n};\n\nChipSet.aPortOutput5xxx = {\n 0x00: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelAddr(ChipSet.DMA0.INDEX, 0, port, bOut, addrFrom); },\n 0x01: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelCount(ChipSet.DMA0.INDEX, 0, port, bOut, addrFrom); },\n 0x02: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelAddr(ChipSet.DMA0.INDEX, 1, port, bOut, addrFrom); },\n 0x03: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelCount(ChipSet.DMA0.INDEX, 1, port, bOut, addrFrom); },\n 0x04: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelAddr(ChipSet.DMA0.INDEX, 2, port, bOut, addrFrom); },\n 0x05: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelCount(ChipSet.DMA0.INDEX, 2, port, bOut, addrFrom); },\n 0x06: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelAddr(ChipSet.DMA0.INDEX, 3, port, bOut, addrFrom); },\n 0x07: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelCount(ChipSet.DMA0.INDEX, 3, port, bOut, addrFrom); },\n 0x08: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMACmd(ChipSet.DMA0.INDEX, port, bOut, addrFrom); },\n 0x09: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAReq(ChipSet.DMA0.INDEX, port, bOut, addrFrom); },\n 0x0A: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAMask(ChipSet.DMA0.INDEX, port, bOut, addrFrom); },\n 0x0B: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAMode(ChipSet.DMA0.INDEX, port, bOut, addrFrom); },\n 0x0C: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAResetFF(ChipSet.DMA0.INDEX, port, bOut, addrFrom); },\n 0x0D: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAMasterClear(ChipSet.DMA0.INDEX, port, bOut, addrFrom); },\n 0x81: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageReg(ChipSet.DMA0.INDEX, 2, port, bOut, addrFrom); },\n 0x82: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageReg(ChipSet.DMA0.INDEX, 3, port, bOut, addrFrom); },\n 0x83: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageReg(ChipSet.DMA0.INDEX, 1, port, bOut, addrFrom); },\n 0x87: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageReg(ChipSet.DMA0.INDEX, 0, port, bOut, addrFrom); }\n};\n\nChipSet.aPortOutput5170 = {\n 0x60: ChipSet.prototype.out8042InBuffData,\n 0x61: ChipSet.prototype.out8042RWReg,\n 0x64: ChipSet.prototype.out8042InBuffCmd,\n 0x70: ChipSet.prototype.outCMOSAddr,\n 0x71: ChipSet.prototype.outCMOSData,\n 0x80: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageSpare(7, port, bOut, addrFrom); },\n 0x84: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageSpare(0, port, bOut, addrFrom); },\n 0x85: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageSpare(1, port, bOut, addrFrom); },\n 0x86: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageSpare(2, port, bOut, addrFrom); },\n 0x88: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageSpare(3, port, bOut, addrFrom); },\n 0x89: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageReg(ChipSet.DMA1.INDEX, 2, port, bOut, addrFrom); },\n 0x8A: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageReg(ChipSet.DMA1.INDEX, 3, port, bOut, addrFrom); },\n 0x8B: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageReg(ChipSet.DMA1.INDEX, 1, port, bOut, addrFrom); },\n 0x8C: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageSpare(4, port, bOut, addrFrom); },\n 0x8D: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageSpare(5, port, bOut, addrFrom); },\n 0x8E: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageSpare(6, port, bOut, addrFrom); },\n 0x8F: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageReg(ChipSet.DMA1.INDEX, 0, port, bOut, addrFrom); },\n 0xA0: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outPICLo(ChipSet.PIC1.INDEX, bOut, addrFrom); },\n 0xA1: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outPICHi(ChipSet.PIC1.INDEX, bOut, addrFrom); },\n 0xC0: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelAddr(ChipSet.DMA1.INDEX, 0, port, bOut, addrFrom); },\n 0xC2: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelCount(ChipSet.DMA1.INDEX, 0, port, bOut, addrFrom); },\n 0xC4: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelAddr(ChipSet.DMA1.INDEX, 1, port, bOut, addrFrom); },\n 0xC6: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelCount(ChipSet.DMA1.INDEX, 1, port, bOut, addrFrom); },\n 0xC8: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelAddr(ChipSet.DMA1.INDEX, 2, port, bOut, addrFrom); },\n 0xCA: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelCount(ChipSet.DMA1.INDEX, 2, port, bOut, addrFrom); },\n 0xCC: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelAddr(ChipSet.DMA1.INDEX, 3, port, bOut, addrFrom); },\n 0xCE: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAChannelCount(ChipSet.DMA1.INDEX, 3, port, bOut, addrFrom); },\n 0xD0: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMACmd(ChipSet.DMA1.INDEX, port, bOut, addrFrom); },\n 0xD2: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAReq(ChipSet.DMA1.INDEX, port, bOut, addrFrom); },\n 0xD4: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAMask(ChipSet.DMA1.INDEX, port, bOut, addrFrom); },\n 0xD6: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAMode(ChipSet.DMA1.INDEX, port, bOut, addrFrom); },\n 0xD8: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAResetFF(ChipSet.DMA1.INDEX, port, bOut, addrFrom); },\n 0xDA: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAMasterClear(ChipSet.DMA1.INDEX, port, bOut, addrFrom); },\n 0xF0: ChipSet.prototype.outFPUClear,\n 0xF1: ChipSet.prototype.outFPUReset\n};\n\nChipSet.aPortOutput6300 = {\n 0x60: ChipSet.prototype.out8041Kbd,\n 0x61: ChipSet.prototype.out8041Ctrl,\n 0xA0: ChipSet.prototype.outNMI\n};\n\nif (DESKPRO386) {\n ChipSet.aPortOutputDeskPro386 = {\n 0x48: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outTimer(ChipSet.PIT1.INDEX, ChipSet.PIT1.TIMER3, port, bOut, addrFrom); },\n 0x49: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outTimer(ChipSet.PIT1.INDEX, ChipSet.PIT1.TIMER4, port, bOut, addrFrom); },\n 0x4A: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outTimer(ChipSet.PIT1.INDEX, ChipSet.PIT1.TIMER5, port, bOut, addrFrom); },\n 0x4B: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outTimerCtrl(ChipSet.PIT1.INDEX, port, bOut, addrFrom); }\n };\n}\n\n/*\n * Initialize every ChipSet module on the page.\n */\nWeb.onInit(ChipSet.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/rom.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * class ROMX86\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass ROMX86 extends Component {\n /**\n * ROMX86(parmsROM)\n *\n * The ROMX86 component expects the following (parmsROM) properties:\n *\n * addr: physical address of ROM\n * size: amount of ROM, in bytes\n * alias: physical alias address (null if none)\n * file: name of ROM data file\n * notify: ID of a component to notify once the ROM is in place (optional)\n *\n * NOTE: The ROM data will not be copied into place until the Bus is ready (see initBus()) AND the\n * ROM data file has finished loading (see doneLoad()).\n *\n * Also, while the size parameter may seem redundant, I consider it useful to confirm that the ROM you received\n * is the ROM you expected.\n *\n * @this {ROMX86}\n * @param {Object} parmsROM\n */\n constructor(parmsROM)\n {\n super(\"ROMX86\", parmsROM);\n\n this.abROM = null;\n this.addrROM = parmsROM['addr'];\n this.sizeROM = parmsROM['size'];\n\n /*\n * The new 'alias' property can now be EITHER a single physical address (like 'addr') OR an array of\n * physical addresses; eg:\n *\n * [0xf0000,0xffff0000,0xffff8000]\n *\n * We could have overloaded 'addr' to accomplish the same thing, but I think it's better to have any\n * aliased locations listed under a separate property.\n *\n * Most ROMs are not aliased, in which case the 'alias' property should have the default value of null.\n */\n this.addrAlias = parmsROM['alias'];\n\n /*\n * The 'notify' property can now (as of v1.18.2) contain an array of parameters that the notified\n * component (typically Video) may use as it sees fit. For example, the Video component is generally\n * interested in knowing the offsets of specific font tables within the ROM, which used to be hard-coded\n * when all we supported were a few specific IBM video cards, but that's no longer feasible as we move\n * beyond the original handful of IBM cards.\n *\n * It's up to the notified component to decide how to interpret the parameters it receives, if any.\n */\n this.idNotify = parmsROM['notify'];\n this.aNotifyParms = null;\n if (this.idNotify) {\n var i = this.idNotify.indexOf('[');\n if (i > 0) {\n try {\n this.aNotifyParms = eval(this.idNotify.substr(i));\n } catch (e) {}\n this.idNotify = this.idNotify.substr(0, i);\n }\n }\n\n this.sFileURL = this.sFilePath = parmsROM['file'];\n\n if (this.sFileURL) {\n var sFileName = Str.getBaseName(this.sFileURL);\n if (DEBUG) this.log('load(\"' + this.sFileURL + '\")');\n /*\n * If the selected ROM file has a \".json\" extension, then we assume it's pre-converted\n * JSON-encoded ROM data, so we load it as-is; ditto for ROM files with a \".hex\" extension.\n * Otherwise, we ask our server-side ROM converter to return the file in a JSON-compatible format.\n */\n var sFileExt = Str.getExtension(sFileName);\n if (sFileExt != DumpAPI.FORMAT.JSON && sFileExt != DumpAPI.FORMAT.HEX) {\n this.sFileURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFilePath + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES + '&' + DumpAPI.QUERY.DECIMAL + '=true';\n }\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {ROMX86}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n if (this.sFileURL) {\n var rom = this;\n var sProgress = \"Loading \" + this.sFileURL + \"...\";\n Web.getResource(this.sFileURL, null, true, function doneROMLoad(sURL, sResponse, nErrorCode) {\n rom.doneLoad(sURL, sResponse, nErrorCode);\n }, function(nState) {\n rom.println(sProgress, Component.PRINT.PROGRESS);\n });\n }\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {ROMX86}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (this.aSymbols) {\n if (this.dbg) {\n this.dbg.addSymbols(this.id, 0, this.addrROM >>> 4, 0, this.addrROM, this.sizeROM, this.aSymbols);\n }\n /*\n * Our only role in the handling of symbols is to hand them off to the Debugger at our\n * first opportunity. Now that we've done that, our copy of the symbols, if any, are toast.\n */\n delete this.aSymbols;\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * Since we have nothing to do on powerDown(), and no state to return, we could simply omit\n * this function. But it doesn't hurt anything, and maybe we'll use our state to save something\n * useful down the road, like user-defined symbols (ie, symbols that the Debugger may have\n * created, above and beyond those symbols we automatically loaded, if any, along with the ROM).\n *\n * @this {ROMX86}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return true;\n }\n\n /**\n * doneLoad(sURL, sROMData, nErrorCode)\n *\n * @this {ROMX86}\n * @param {string} sURL\n * @param {string} sROMData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n doneLoad(sURL, sROMData, nErrorCode)\n {\n if (nErrorCode) {\n this.notice(\"Unable to load system ROM (error \" + nErrorCode + \": \" + sURL + \")\", nErrorCode < 0);\n return;\n }\n\n Component.addMachineResource(this.idMachine, sURL, sROMData);\n\n if (sROMData.charAt(0) == \"[\" || sROMData.charAt(0) == \"{\") {\n try {\n /*\n * The most likely source of any exception will be here: parsing the JSON-encoded ROM data.\n */\n var rom = eval(\"(\" + sROMData + \")\");\n var ab = rom['bytes'];\n /*\n * Resource 'longs' should always be 32-bit DWORD values, whereas 'data' bit lengths\n * will vary according to the machine architecture for which the resource was designed.\n */\n var adw = rom['longs'] || rom['data'];\n\n if (ab) {\n this.abROM = ab;\n }\n else if (adw) {\n /*\n * Convert all the DWORDs into BYTEs, so that subsequent code only has to deal with abROM.\n */\n this.abROM = new Array(adw.length * 4);\n for (var idw = 0, ib = 0; idw < adw.length; idw++) {\n this.abROM[ib++] = adw[idw] & 0xff;\n this.abROM[ib++] = (adw[idw] >> 8) & 0xff;\n this.abROM[ib++] = (adw[idw] >> 16) & 0xff;\n this.abROM[ib++] = (adw[idw] >> 24) & 0xff;\n }\n }\n else {\n this.abROM = rom;\n }\n\n this.aSymbols = rom['symbols'];\n\n if (!this.abROM.length) {\n Component.error(\"Empty ROM: \" + sURL);\n return;\n }\n else if (this.abROM.length == 1) {\n Component.error(this.abROM[0]);\n return;\n }\n } catch (e) {\n this.notice(\"ROM data error: \" + e.message);\n return;\n }\n }\n else {\n /*\n * Parse the ROM data manually; we assume it's in \"simplified\" hex form (a series of hex byte-values\n * separated by whitespace).\n */\n var sHexData = sROMData.replace(/\\n/gm, \" \").replace(/ +$/, \"\");\n var asHexData = sHexData.split(\" \");\n this.abROM = new Array(asHexData.length);\n for (var i = 0; i < asHexData.length; i++) {\n this.abROM[i] = Str.parseInt(asHexData[i], 16);\n }\n }\n this.copyROM();\n }\n\n /**\n * copyROM()\n *\n * This function is called by both initBus() and doneLoad(), but it cannot copy the the ROM data into place\n * until after initBus() has received the Bus component AND doneLoad() has received the abROM data. When both\n * those criteria are satisfied, the component becomes \"ready\".\n *\n * @this {ROMX86}\n */\n copyROM()\n {\n if (!this.isReady()) {\n if (!this.sFilePath) {\n this.setReady();\n }\n else if (this.abROM && this.bus) {\n /*\n * If no explicit size was specified, then use whatever the actual size is.\n */\n if (!this.sizeROM) {\n this.sizeROM = this.abROM.length;\n }\n if (this.abROM.length != this.sizeROM) {\n /*\n * Note that setError() sets the component's fError flag, which in turn prevents setReady() from\n * marking the component ready. TODO: Revisit this decision. On the one hand, it sounds like a\n * good idea to stop the machine in its tracks whenever a setError() occurs, but there may also be\n * times when we'd like to forge ahead anyway.\n */\n this.setError(\"ROM size (\" + Str.toHexLong(this.abROM.length) + \") does not match specified size (\" + Str.toHexLong(this.sizeROM) + \")\");\n }\n else if (this.addROM(this.addrROM)) {\n\n var aliases = [];\n if (typeof this.addrAlias == \"number\") {\n aliases.push(this.addrAlias);\n } else if (this.addrAlias != null && this.addrAlias.length) {\n aliases = this.addrAlias;\n }\n for (var i = 0; i < aliases.length; i++) {\n this.cloneROM(aliases[i]);\n }\n /*\n * If there's a component we should notify, notify it now, and give it the internal byte array, so that\n * it doesn't have to ask the CPU for the data. Currently, the only component that uses this notification\n * option is the Video component, and only when the associated ROM contains font data that it needs.\n */\n if (this.idNotify) {\n var component = Component.getComponentByID(this.idNotify, this.id);\n if (component) {\n component.onROMLoad(this.abROM, this.aNotifyParms);\n } else {\n this.notice(\"Unable to find component: \" + this.idNotify);\n }\n }\n /*\n * We used to hang onto the original ROM data so that we could restore any bytes the CPU overwrote,\n * using memory write-notification handlers, but with the introduction of read-only memory blocks, that's\n * no longer necessary.\n *\n * TODO: Consider an option to retain the ROM data, and give the user some way of restoring ROMs.\n * That may be useful for \"resumable\" machines that save/restore all dirty block of memory, regardless\n * whether they're ROM or RAM. However, the only way to modify a machine's ROM is with the Debugger,\n * and Debugger users should know better.\n */\n delete this.abROM;\n }\n this.setReady();\n }\n }\n }\n\n /**\n * addROM(addr)\n *\n * @this {ROMX86}\n * @param {number} addr\n * @return {boolean}\n */\n addROM(addr)\n {\n if (this.bus.addMemory(addr, this.sizeROM, Memory.TYPE.ROM)) {\n if (DEBUG) this.log(\"addROM(): copying ROM to \" + Str.toHexLong(addr) + \" (\" + Str.toHexLong(this.abROM.length) + \" bytes)\");\n var bto = null;\n for (var off = 0; off < this.abROM.length; off++) {\n this.bus.setByteDirect(addr + off, this.abROM[off]);\n if (BACKTRACK) {\n bto = this.bus.addBackTrackObject(this, bto, off);\n this.bus.writeBackTrackObject(addr + off, bto, off);\n }\n }\n return true;\n }\n /*\n * We don't need to report an error here, because addMemory() already takes care of that.\n */\n return false;\n }\n\n /**\n * cloneROM(addr)\n *\n * For ROMs with one or more alias addresses, we used to call addROM() for each address. However,\n * that obviously wasted memory, since each alias was an independent copy, and if you used the\n * Debugger to edit the ROM in one location, the changes would not appear in the other location(s).\n *\n * Now that the Bus component provides low-level getMemoryBlocks() and setMemoryBlocks() methods\n * to manually get and set the blocks of any memory range, it is now possible to create true aliases.\n *\n * @this {ROMX86}\n * @param {number} addr\n */\n cloneROM(addr)\n {\n var aBlocks = this.bus.getMemoryBlocks(this.addrROM, this.sizeROM);\n this.bus.setMemoryBlocks(addr, this.sizeROM, aBlocks);\n }\n\n /**\n * ROMX86.init()\n *\n * This function operates on every HTML element of class \"rom\", extracting the\n * JSON-encoded parameters for the ROM constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a ROM component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeROM = Component.getElementsByClass(document, PCX86.APPCLASS, \"rom\");\n for (var iROM = 0; iROM < aeROM.length; iROM++) {\n var eROM = aeROM[iROM];\n var parmsROM = Component.getComponentParms(eROM);\n var rom = new ROMX86(parmsROM);\n Component.bindComponentControls(rom, eROM, PCX86.APPCLASS);\n }\n }\n}\n\n/*\n * ROM BIOS Data Area (RBDA) definitions, in physical address form, using the same CAPITALIZED names\n * found in the original IBM PC ROM BIOS listing.\n */\nROMX86.BIOS = {\n RS232_BASE: 0x400, // ADDRESSES OF RS232 ADAPTERS (4 words)\n PRINTER_BASE: 0x408, // ADDRESSES OF PRINTERS (4 words)\n EQUIP_FLAG: { // INSTALLED HARDWARE (word)\n ADDR: 0x410,\n NUM_PRINT: 0xC000, // NUMBER OF PRINTERS ATTACHED\n GAME_CTRL: 0x1000, // GAME I/O ATTACHED\n NUM_RS232: 0x0E00, // NUMBER OF RS232 CARDS ATTACHED\n NUM_DRIVES: 0x00C0, // NUMBER OF DISKETTE DRIVES (00=1, 01=2, 10=3, 11=4) ONLY IF IPL_DRIVE SET\n VIDEO_MODE: 0x0030, // INITIAL VIDEO MODE (00=UNUSED, 01=40X25 COLOR, 10=80X25 COLOR, 11=80X25 MONO)\n RAM_SIZE: 0x000C, // PLANAR RAM SIZE (00=16K,01=32K,10=48K,11=64K)\n IPL_DRIVE: 0x0001 // IPL (Initial Program Load) FROM DISKETTE (ie, diskette drives exist)\n },\n MFG_TEST: 0x412, // INITIALIZATION FLAG (byte)\n MEMORY_SIZE: 0x413, // MEMORY SIZE IN K BYTES (word)\n IO_RAM_SIZE: 0x415, // PC: MEMORY IN I/O CHANNEL (word)\n MFG_ERR_FLAG: 0x415, // PC AT: SCRATCHPAD FOR MANUFACTURING ERROR CODES (2 bytes)\n COMPAQ_PREV_SC: 0x415, // COMPAQ DESKPRO 386: PREVIOUS SCAN CODE (byte)\n COMPAQ_KEYCLICK:0x416, // COMPAQ DESKPRO 386: KEYCLICK LOUDNESS (byte)\n /*\n * KEYBOARD DATA AREAS\n */\n KB_FLAG: { // FIRST BYTE OF KEYBOARD STATUS (byte)\n ADDR: 0x417, //\n INS_STATE: 0x80, // INSERT STATE IS ACTIVE\n CAPS_STATE: 0x40, // CAPS LOCK STATE HAS BEEN TOGGLED\n NUM_STATE: 0x20, // NUM LOCK STATE HAS BEEN TOGGLED\n SCROLL_STATE: 0x10, // SCROLL LOCK STATE HAS BEEN TOGGLED\n ALT_SHIFT: 0x08, // ALTERNATE SHIFT KEY DEPRESSED\n CTL_SHIFT: 0x04, // CONTROL SHIFT KEY DEPRESSED\n LEFT_SHIFT: 0x02, // LEFT SHIFT KEY DEPRESSED\n RIGHT_SHIFT: 0x01 // RIGHT SHIFT KEY DEPRESSED\n },\n KB_FLAG_1: { // SECOND BYTE OF KEYBOARD STATUS (byte)\n ADDR: 0x418, //\n INS_SHIFT: 0x80, // INSERT KEY IS DEPRESSED\n CAPS_SHIFT: 0x40, // CAPS LOCK KEY IS DEPRESSED\n NUM_SHIFT: 0x20, // NUM LOCK KEY IS DEPRESSED\n SCROLL_SHIFT: 0x10, // SCROLL LOCK KEY IS DEPRESSED\n HOLD_STATE: 0x08 // SUSPEND KEY HAS BEEN TOGGLED\n },\n ALT_INPUT: 0x419, // STORAGE FOR ALTERNATE KEYPAD ENTRY (byte)\n BUFFER_HEAD: 0x41A, // POINTER TO HEAD OF KEYBOARD BUFFER (word)\n BUFFER_TAIL: 0x41C, // POINTER TO TAIL OF KEYBOARD BUFFER (word)\n KB_BUFFER: 0x41E, // ROOM FOR 15 ENTRIES (16 words)\n KB_BUFFER_END: 0x43E, // HEAD = TAIL INDICATES THAT THE BUFFER IS EMPTY\n /*\n * DISKETTE DATA AREAS\n */\n SEEK_STATUS: { // DRIVE RECALIBRATION STATUS (byte)\n ADDR: 0x43E, //\n // BIT 3-0 = DRIVE 3-0 NEEDS RECAL BEFORE\n // NEXT SEEK IF BIT IS = 0\n INT_FLAG: 0x80, // INTERRUPT OCCURRENCE FLAG\n },\n MOTOR_STATUS: 0x43F, // MOTOR STATUS (byte)\n // BIT 3-0 = DRIVE 3-0 IS CURRENTLY RUNNING\n // BIT 7 = CURRENT OPERATION IS A WRITE, REQUIRES DELAY\n MOTOR_COUNT: 0x440, // TIME OUT COUNTER FOR DRIVE TURN OFF\n // 37 == TWO SECONDS OF COUNTS FOR MOTOR TURN OFF\n DISKETTE_STATUS: { // SINGLE BYTE OF RETURN CODE INFO FOR STATUS\n ADDR: 0x441,\n TIME_OUT: 0x80, // ATTACHMENT FAILED TO RESPOND\n BAD_SEEK: 0x40, // SEEK OPERATION FAILED\n BAD_NEC: 0x20, // NEC CONTROLLER HAS FAILED\n BAD_CRC: 0x10, // BAD CRC ON DISKETTE READ\n DMA_BOUNDARY: 0x09, // ATTEMPT TO DMA ACROSS 64K BOUNDARY\n BAD_DMA: 0x08, // DMA OVERRUN ON OPERATION\n RECORD_NOT_FND: 0x04, // REQUESTED SECTOR NOT FOUND\n WRITE_PROTECT: 0x03, // WRITE ATTEMPTED ON WRITE PROT DISK\n BAD_ADDR_MARK: 0x02, // ADDRESS MARK NOT FOUND\n BAD_CMD: 0x01 // BAD COMMAND PASSED TO DISKETTE I/O\n },\n NEC_STATUS: 0x442, // STATUS BYTES FROM NEC (7 bytes)\n /*\n * VIDEO DISPLAY DATA AREA\n */\n CRT_MODE: 0x449, // CURRENT CRT MODE (byte)\n CRT_COLS: 0x44A, // NUMBER OF COLUMNS ON SCREEN (word)\n CRT_LEN: 0x44C, // LENGTH OF REGEN IN BYTES (word)\n CRT_START: 0x44E, // STARTING ADDRESS IN REGEN BUFFER (word)\n CURSOR_POSN: 0x450, // CURSOR FOR EACH OF UP TO 8 PAGES (8 words)\n CURSOR_MODE: 0x460, // CURRENT CURSOR MODE SETTING (word)\n ACTIVE_PAGE: 0x462, // CURRENT PAGE BEING DISPLAYED (byte)\n ADDR_6845: 0x463, // BASE ADDRESS FOR ACTIVE DISPLAY CARD (word)\n CRT_MODE_SET: 0x465, // CURRENT SETTING OF THE 3X8 REGISTER (byte)\n CRT_PALLETTE: 0x466, // CURRENT PALLETTE SETTING COLOR CARD (byte)\n /*\n * CASSETTE DATA AREA\n */\n EDGE_CNT: 0x467, // PC: TIME COUNT AT DATA EDGE (word)\n CRC_REG: 0x469, // PC: CRC REGISTER (word)\n LAST_VAL: 0x46B, // PC: LAST INPUT VALUE (byte)\n IO_ROM_INIT: 0x467, // PC AT: POINTER TO ROM INITIALIZATION ROUTINE\n IO_ROM_SEG: 0x469, // PC AT: POINTER TO I/O ROM SEGMENT\n INTR_FLAG: 0x46B, // PC AT: FLAG INDICATING AN INTERRUPT HAPPENED\n /*\n * TIMER DATA AREA\n */\n TIMER_LOW: 0x46C, // LOW WORD OF TIMER COUNT (word)\n TIMER_HIGH: 0x46E, // HIGH WORD OF TIMER COUNT (word)\n TIMER_OFL: 0x470, // TIMER HAS ROLLED OVER SINCE LAST READ (byte)\n /*\n * SYSTEM DATA AREA\n */\n BIOS_BREAK: 0x471, // BIT 7 = 1 IF BREAK KEY HAS BEEN DEPRESSED (byte)\n /*\n * RESET_FLAG is the traditional end of the RBDA, as originally defined by the IBM PC\n */\n RESET_FLAG: {\n ADDR: 0x472, // SET TO 0x1234 IF KEYBOARD RESET UNDERWAY (word)\n WARMBOOT: 0x1234 // this value indicates a \"warm boot\", bypassing memory tests\n },\n /*\n * FIXED DISK DATA AREAS\n */\n DISK_STATUS1: 0x474, // PC AT: FIXED DISK STATUS (byte)\n HF_NUM: 0x475, // PC AT: COUNT OF FIXED DISK DRIVES (byte)\n CONTROL_BYTE: 0x476, // PC AT: HEAD CONTROL BYTE (byte)\n PORT_OFF: 0x477, // PC AT: RESERVED (PORT OFFSET) (byte)\n /*\n * TIME-OUT VARIABLES\n */\n PRINT_TIM_OUT: 0x478, // PC AT: TIME OUT COUNTERS FOR PRINTER RESPONSE (4 bytes)\n RS232_TIM_OUT: 0x47C, // PC AT: TIME OUT COUNTERS FOR RS232 RESPONSE (4 bytes)\n /*\n * ADDITIONAL KEYBOARD DATA AREA\n */\n BUFFER_START: 0x480, // PC AT: OFFSET OF KEYBOARD BUFFER START WITHIN SEGMENT 40H\n BUFFER_END: 0x482, // PC AT: OFFSET OF END OF BUFFER\n /*\n * EGA/PGA DISPLAY WORK AREA\n */\n ROWS: 0x484, // PC AT: ROWS ON THE ACTIVE SCREEN (LESS 1) (byte)\n POINTS: 0x485, // PC AT: BYTES PER CHARACTER (word)\n INFO: 0x487, // PC AT: MODE OPTIONS (byte)\n /*\n * INFO BITS:\n * \n * 0x80: HIGH BIT OF MODE SET, CLEAR/NOT CLEAR REGEN\n * 0x60: 256K OF VRAM\n * 0x40: 192K OF VRAM\n * 0x20: 128K OF VRAM\n * 0x10: RESERVED\n * 0x08: EGA ACTIVE MONITOR (0), EGA NOT ACTIVE (1)\n * 0x04: WAIT FOR DISPLAY ENABLE (1)\n * 0x02: EGA HAS A MONOCHROME ATTACHED\n * 0x01: SET C_TYPE EMULATE ACTIVE (0)\n */\n INFO_3: 0x488, // PC AT: FEATURE BIT SWITCHES (1 byte, plus 2 reserved bytes)\n /*\n * ADDITIONAL MEDIA DATA\n */\n LASTRATE: 0x48B, // PC AT: LAST DISKETTE DATA RATE SELECTED (byte)\n HF_STATUS: 0x48C, // PC AT: STATUS REGISTER (byte)\n HF_ERROR: 0x48D, // PC AT: ERROR REGISTER (byte)\n HF_INT_FLAG: 0x48E, // PC AT: FIXED DISK INTERRUPT FLAG (byte)\n HF_CNTRL: 0x48F, // PC AT: COMBO FIXED DISK/DISKETTE CARD BIT 0=1 (byte)\n DSK_STATE: 0x490, // PC AT: DRIVE 0/1 MEDIA/OPERATION STATES (4 bytes)\n DSK_TRK: 0x494, // PC AT: DRIVE 0/1 PRESENT CYLINDER (2 bytes)\n /*\n * ADDITIONAL KEYBOARD FLAGS\n */\n KB_FLAG_3: {\n ADDR: 0x496, // PC AT: KEYBOARD MODE STATE AND TYPE FLAGS (byte)\n LC_E1: 0b00000001, // LAST CODE WAS THE E1 HIDDEN CODE\n LC_E0: 0b00000010, // LAST CODE WAS THE E0 HIDDEN CODE\n R_CTL_SHIFT: 0b00000100, // RIGHT CTL KEY DOWN\n R_ALT_SHIFT: 0b00001000, // RIGHT ALT KEY DOWN\n GRAPH_ON: 0b00001000, // ALT GRAPHICS KEY DOWN (WT ONLY)\n KBX: 0b00010000, // ENHANCED KEYBOARD INSTALLED\n SET_NUM_LK: 0b00100000, // FORCE NUM LOCK IF READ ID AND KBX\n LC_AB: 0b01000000, // LAST CHARACTER WAS FIRST ID CHARACTER\n RD_ID: 0b10000000 // DOING A READ ID (MUST BE BIT0)\n },\n KB_FLAG_2: {\n ADDR: 0x497, // PC AT: KEYBOARD LED FLAGS (byte)\n KB_LEDS: 0b00000111, // KEYBOARD LED STATE BITS\n SCROLL_LOCK: 0b00000001, // SCROLL LOCK INDICATOR\n NUM_LOCK: 0b00000010, // NUM LOCK INDICATOR\n CAPS_LOCK: 0b00000100, // CAPS LOCK INDICATOR\n KB_FA: 0b00010000, // ACKNOWLEDGMENT RECEIVED\n KB_FE: 0b00100000, // RESEND RECEIVED FLAG\n KB_PR_LED: 0b01000000, // MODE INDICATOR UPDATE\n KB_ERR: 0b10000000 // KEYBOARD TRANSMIT ERROR FLAG\n },\n /*\n * REAL TIME CLOCK DATA AREA\n */\n USER_FLAG: 0x498, // PC AT: OFFSET ADDRESS OF USERS WAIT FLAG (word)\n USER_FLAG_SEG: 0x49A, // PC AT: SEGMENT ADDRESS OF USER WAIT FLAG (word)\n RTC_LOW: 0x49C, // PC AT: LOW WORD OF USER WAIT FLAG (word)\n RTC_HIGH: 0x49E, // PC AT: HIGH WORD OF USER WAIT FLAG (word)\n RTC_WAIT_FLAG: 0x4A0, // PC AT: WAIT ACTIVE FLAG (01=BUSY, 80=POSTED, 00=POST ACKNOWLEDGED) (byte)\n /*\n * AREA FOR NETWORK ADAPTER\n */\n NET: 0x4A1, // PC AT: RESERVED FOR NETWORK ADAPTERS (7 bytes)\n /*\n * EGA/PGA PALETTE POINTER\n */\n SAVE_PTR: 0x4A8, // PC AT: POINTER TO EGA PARAMETER CONTROL BLOCK (2 words)\n /*\n * DATA AREA - PRINT SCREEN\n */\n STATUS_BYTE: 0x500 // PRINT SCREEN STATUS BYTE (00=READY/OK, 01=BUSY, FF=ERROR) (byte)\n};\n\n/*\n * NOTE: There's currently no need for this component to have a reset() function, since\n * once the ROM data is loaded, it can't be changed, so there's nothing to reinitialize.\n *\n * OK, well, I take that back, because the Debugger, if installed, has the ability to modify\n * ROM contents, so in that case, having a reset() function that restores the original ROM data\n * might be useful; then again, it might not, depending on what you're trying to debug.\n *\n * If we do add reset(), then we'll want to change copyROM() to hang onto the original\n * ROM data; currently, we release it after copying it into the read-only memory allocated\n * via bus.addMemory().\n */\n\n/*\n * Initialize all the ROM modules on the page.\n */\nWeb.onInit(ROMX86.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/ram.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * class RAM\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass RAM extends Component {\n /**\n * RAM(parmsRAM)\n *\n * The RAM component expects the following (parmsRAM) properties:\n *\n * addr: starting physical address of RAM (default is 0)\n * size: amount of RAM, in bytes (default is 0, which means defer to motherboard switch settings)\n * test: true (default) means don't interfere with any BIOS memory tests, false means \"fake a warm boot\"\n *\n * NOTE: We make a note of the specified size, but no memory is initially allocated for the RAM until the\n * Computer component calls powerUp().\n *\n * @this {RAM}\n * @param {Object} parmsRAM\n */\n constructor(parmsRAM)\n {\n super(\"RAM\", parmsRAM);\n\n this.addrRAM = parmsRAM['addr'];\n this.sizeRAM = parmsRAM['size'];\n this.fTestRAM = parmsRAM['test'];\n this.fInstalled = (!!this.sizeRAM); // 0 is the default value for 'size' when none is specified\n this.fAllocated = false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {RAM}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.chipset = cmp.getMachineComponent(\"ChipSet\");\n this.setReady();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {RAM}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n /*\n * The Computer powers up the CPU last, at which point CPUX86 state is restored,\n * which includes the Bus state, and since we use the Bus to allocate all our memory,\n * memory contents are already restored for us, so we don't need the usual restore\n * logic. We just need to call reset(), to allocate memory for the RAM.\n *\n * The only exception is when there's a custom Memory controller (eg, CompaqController).\n */\n this.reset();\n if (data && this.controller) {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {RAM}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n /*\n * The Computer powers down the CPU first, at which point CPUX86 state is saved,\n * which includes the Bus state, and since we use the Bus component to allocate all\n * our memory, memory contents are already saved for us, so we don't need the usual\n * save logic.\n *\n * The only exception is when there's a custom Memory controller (eg, CompaqController).\n */\n return (fSave && this.controller)? this.save() : true;\n }\n\n /**\n * reset()\n *\n * NOTE: When we were initialized, we were given an amount of INSTALLED memory (see sizeRAM above).\n * The ChipSet component, on the other hand, tells us how much SPECIFIED memory there is -- which,\n * like a real PC, may not match the amount of installed memory (due to either user error or perhaps\n * an attempt to prevent some portion of the installed memory from being used).\n *\n * However, since we're a virtual machine, we can defer allocation of RAM until we're able to query the\n * ChipSet component, and then allocate an amount of memory that matches the SPECIFIED memory, making\n * it easy to reconfigure the machine on the fly and prevent mismatches.\n *\n * But, we do that ONLY for the RAM instance configured with an addrRAM of 0x0000, and ONLY if that RAM\n * object was not given a specific size (see fInstalled). If there are other RAM objects in the system,\n * they must necessarily specify a non-conflicting, non-zero start address, in which case their sizeRAM\n * value will never be affected by the ChipSet settings.\n *\n * @this {RAM}\n */\n reset()\n {\n if (!this.addrRAM && !this.fInstalled && this.chipset) {\n var baseRAM = this.chipset.getDIPMemorySize() * 1024;\n if (this.sizeRAM && baseRAM != this.sizeRAM) {\n this.bus.removeMemory(this.addrRAM, this.sizeRAM);\n this.fAllocated = false;\n }\n this.sizeRAM = baseRAM;\n }\n if (!this.fAllocated && this.sizeRAM) {\n if (this.bus.addMemory(this.addrRAM, this.sizeRAM, Memory.TYPE.RAM)) {\n this.fAllocated = true;\n\n /*\n * NOTE: I'm specifying MAXDEBUG for status() messages because I'm not yet sure I want these\n * messages buried in the app, since they're seen only when a Control Panel is active. Another\n * and perhaps better alternative is to add \"comment\" attributes to the XML configuration file\n * for these components, which the Computer component will display as it \"powers up\" components.\n */\n if (MAXDEBUG && !this.addrRAM && this.fInstalled) this.status(\"specified size overrides SW1\");\n\n /*\n * Memory with an ID of \"ramCPQ\" is reserved for built-in memory located just below the 16Mb\n * boundary on COMPAQ DeskPro 386 machines.\n *\n * Technically, that memory is part of the first 1Mb of memory that also provides up to 640Kb\n * of conventional memory (ie, memory below 1Mb).\n *\n * However, PCx86 doesn't support individual memory allocations that (a) are discontiguous\n * or (b) dynamically change location. Components must simulate those features by performing\n * a separate allocation for each starting address, and removing/adding memory allocations\n * whenever their starting address changes.\n *\n * Therefore, a DeskPro 386's first 1Mb of physical memory is allocated by PCx86 in two pieces,\n * and the second piece must have an ID of \"ramCPQ\", triggering the additional allocation of\n * COMPAQ-specific memory-mapped registers.\n *\n * See CompaqController for more details.\n */\n if (DESKPRO386) {\n if (this.idComponent == \"ramCPQ\") {\n this.controller = new CompaqController(this);\n this.bus.addMemory(CompaqController.ADDR, 4, Memory.TYPE.CTRL, this.controller);\n }\n }\n }\n }\n if (this.fAllocated) {\n if (!this.addrRAM && !this.fTestRAM) {\n /*\n * HACK: Set the word at 40:72 in the ROM BIOS Data Area (RBDA) to 0x1234 to bypass the ROM BIOS\n * memory storage tests. See rom.js for all RBDA definitions.\n */\n if (MAXDEBUG) this.status(\"ROM BIOS memory test has been disabled\");\n this.bus.setShortDirect(ROMX86.BIOS.RESET_FLAG.ADDR, ROMX86.BIOS.RESET_FLAG.WARMBOOT);\n }\n /*\n * Don't add the \"ramCPQ\" memory to the CMOS total, because addCMOSMemory() will add it to the extended\n * memory total, which will just confuse the COMPAQ BIOS.\n */\n if (!DESKPRO386 || this.idComponent != \"ramCPQ\") {\n if (this.chipset) this.chipset.addCMOSMemory(this.addrRAM, this.sizeRAM);\n }\n } else {\n Component.error(\"No RAM allocated\");\n }\n }\n \n /**\n * save()\n *\n * This implements save support for the RAM component.\n *\n * @this {RAM}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n if (this.controller) state.set(0, this.controller.save());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the RAM component.\n *\n * @this {RAM}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n if (this.controller) return this.controller.restore(data[0]);\n return true;\n }\n\n /**\n * RAM.init()\n *\n * This function operates on every HTML element of class \"ram\", extracting the\n * JSON-encoded parameters for the RAM constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a RAM component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeRAM = Component.getElementsByClass(document, PCX86.APPCLASS, \"ram\");\n for (var iRAM = 0; iRAM < aeRAM.length; iRAM++) {\n var eRAM = aeRAM[iRAM];\n var parmsRAM = Component.getComponentParms(eRAM);\n var ram = new RAM(parmsRAM);\n Component.bindComponentControls(ram, eRAM, PCX86.APPCLASS);\n }\n }\n}\n\n/**\n * class CompaqController\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass CompaqController extends Controller {\n /**\n * CompaqController(ram)\n *\n * DeskPro 386 machines came with a minimum of 1Mb of RAM, which could be configured (via jumpers)\n * for 256Kb, 512Kb or 640Kb of conventional memory, starting at address 0x00000000, with the\n * remainder (768Kb, 512Kb, or 384Kb) accessible only at an address just below 0x01000000. In PCx86,\n * this second chunk of RAM must be separately allocated, with an ID of \"ramCPQ\".\n *\n * The typical configuration was 640Kb of conventional memory, leaving 384Kb accessible at 0x00FA0000.\n * Presumably, the other configurations (256Kb and 512Kb) would leave 768Kb and 512Kb accessible at\n * 0x00F40000 and 0x00F80000, respectively.\n *\n * The DeskPro 386 also contained two memory-mapped registers at 0x80C00000. The first is a write-only\n * mapping register that provides the ability to map the 128Kb at 0x00FE0000 to 0x000E0000, replacing\n * any ROMs in the range 0x000E0000-0x000FFFFF, and optionally write-protecting that 128Kb; internally,\n * this register corresponds to wMappings.\n *\n * The second register is a read-only diagnostics register that indicates jumper configuration and\n * parity errors; internally, this register corresponds to wSettings.\n *\n * To emulate the memory-mapped registers at 0x80C00000, the RAM component allocates a block at that\n * address using this custom controller once it sees an allocation for \"ramCPQ\".\n *\n * Later, when the addressability of \"ramCPQ\" memory is altered, we record the blocks in all the\n * memory slots spanning 0x000E0000-0x000FFFFF, and then update those slots with the blocks from\n * 0x00FE0000-0x00FFFFFF. Note that only the top 128Kb of \"ramCPQ\" addressability is affected; the\n * rest of that memory, ranging anywhere from 256Kb to 640Kb, remains addressable at its original\n * location. COMPAQ's CEMM and VDISK utilities were generally the only software able to access that\n * remaining memory (what COMPAQ refers to as \"Compaq Built-in Memory\").\n *\n * @this {CompaqController}\n * @param {RAM} ram\n */\n constructor(ram)\n {\n super();\n \n this.ram = ram;\n this.wMappings = CompaqController.MAPPINGS.DEFAULT;\n /*\n * TODO: wSettings needs to reflect the actual amount of configured memory....\n */\n this.wSettings = CompaqController.SETTINGS.DEFAULT;\n this.wRAMSetup = CompaqController.RAMSETUP.DEFAULT;\n this.aBlocksDst = null;\n }\n\n /**\n * save()\n *\n * This implements save support for the CompaqController component.\n *\n * @this {CompaqController}\n * @return {Array}\n */\n save()\n {\n return [this.wMappings, this.wRAMSetup];\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the CompaqController component.\n *\n * @this {CompaqController}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n this.setByte(0, data[0] & 0xff);\n this.setByte(2, data[1] & 0xff);\n return true;\n }\n\n /**\n * getByte(off)\n *\n * @this {CompaqController}\n * @param {number} off\n * @return {number}\n */\n getByte(off)\n {\n /*\n * Offsets 0-3 correspond to reads from 0x80C00000-0x80C00003; anything outside that range\n * returns our standard non-responsive value of 0xff.\n */\n var b = 0xff;\n if (off < 0x02) {\n b = (off & 0x1)? (this.wSettings >> 8) : (this.wSettings & 0xff);\n }\n else if (off < 0x4) {\n b = (off & 0x1)? (this.wRAMSetup >> 8) : (this.wRAMSetup & 0xff);\n }\n return b;\n }\n\n /**\n * setByte(off, b)\n *\n * @this {CompaqController}\n * @param {number} off (relative to 0x80C00000)\n * @param {number} b\n */\n setByte(off, b)\n {\n if (!off) {\n /*\n * This is a write to 0x80C00000\n */\n if (b != (this.wMappings & 0xff)) {\n var bus = this.ram.bus;\n if (!(b & CompaqController.MAPPINGS.UNMAPPED)) {\n if (!this.aBlocksDst) {\n this.aBlocksDst = bus.getMemoryBlocks(CompaqController.MAP_DST, CompaqController.MAP_SIZE);\n }\n /*\n * You might think that the next three lines could ALSO be moved to the preceding IF,\n * but it's possible for the write-protection feature to be enabled/disabled separately\n * from the mapping feature. We could avoid executing this code as well by checking the\n * current read-write state, but this is an infrequent operation, so there's no point.\n */\n var aBlocks = bus.getMemoryBlocks(CompaqController.MAP_SRC, CompaqController.MAP_SIZE);\n var type = (b & CompaqController.MAPPINGS.READWRITE)? Memory.TYPE.RAM : Memory.TYPE.ROM;\n bus.setMemoryBlocks(CompaqController.MAP_DST, CompaqController.MAP_SIZE, aBlocks, type);\n }\n else {\n if (this.aBlocksDst) {\n bus.setMemoryBlocks(CompaqController.MAP_DST, CompaqController.MAP_SIZE, this.aBlocksDst);\n this.aBlocksDst = null;\n }\n }\n this.wMappings = (this.wMappings & ~0xff) | b;\n }\n }\n else if (off == 0x2) {\n /*\n * This is a write to 0x80C00002\n */\n this.wRAMSetup = (this.wRAMSetup & ~0xff) | b;\n }\n }\n\n /**\n * getMemoryAccess()\n *\n * @this {CompaqController}\n * @return {Array.<function()>}\n */\n getMemoryAccess()\n {\n return CompaqController.ACCESS;\n }\n\n /**\n * getMemoryBuffer(addr)\n *\n * @this {CompaqController}\n * @param {number} addr\n * @return {Array} containing the buffer (and an offset within that buffer)\n */\n getMemoryBuffer(addr)\n {\n return CompaqController.BUFFER;\n }\n\n /**\n * readByte(off, addr)\n *\n * NOTE: Even though we asked bus.addMemory() for only 4 bytes, corresponding to the 4 memory-mapped register\n * locations we must manage, we're at the mercy of the Bus component's physical block allocation granularity,\n * which, on 80386-based machines, is fixed at 4K (the same as the 80386 page size, to simplify emulation of paging).\n *\n * So we must allow for requests outside that 4-byte range.\n *\n * @this {Memory}\n * @param {number} off (relative to 0x80C00000)\n * @param {number} [addr]\n * @return {number}\n */\n static readByte(off, addr)\n {\n var b = this.controller.getByte(off);\n if (DEBUG) {\n this.controller.ram.printMessage(\"CompaqController.readByte(\" + Str.toHexWord(off) + \") returned \" + Str.toHexByte(b), 0, true);\n }\n return b;\n }\n\n /**\n * writeByte(off, b, addr)\n *\n * NOTE: Even though we asked bus.addMemory() for only 4 bytes, corresponding to the 4 memory-mapped register\n * locations we must manage, we're at the mercy of the Bus component's physical memory allocation granularity,\n * which, on 80386-based machines, is fixed at 4K (the same as the 80386 page size, to simplify emulation of paging).\n *\n * So we must allow for requests outside that 4-byte range.\n *\n * @this {Memory}\n * @param {number} off (relative to 0x80C00000)\n * @param {number} b\n * @param {number} [addr]\n */\n static writeByte(off, b, addr)\n {\n this.controller.setByte(off, b);\n /*\n * All bits in 0x80C00001 and 0x80C00003 are reserved, so we can simply ignore those writes.\n */\n if (DEBUG) {\n this.controller.ram.printMessage(\"CompaqController.writeByte(\" + Str.toHexWord(off) + \",\" + Str.toHexByte(b) + \")\", 0, true);\n }\n }\n}\n\nCompaqController.ADDR = 0x80C00000|0;\nCompaqController.MAP_SRC = 0x00FE0000;\nCompaqController.MAP_DST = 0x000E0000;\nCompaqController.MAP_SIZE = 0x00020000;\n\n/*\n * Bit definitions for the 16-bit write-only memory-mapping register (wMappings)\n *\n * NOTE: Although COMPAQ says the memory at %FE0000 is \"relocated\", it actually remains addressable\n * at %FE0000; it simply becomes addressable at %0E0000 as well, displacing any ROMs that used to be\n * addressable at %0E0000 through %0FFFFF.\n */\nCompaqController.MAPPINGS = {\n UNMAPPED: 0x0001, // is this bit is CLEAR, the last 128Kb (at 0x00FE0000) is mapped to 0x000E0000\n READWRITE: 0x0002, // if this bit is CLEAR, the last 128Kb (at 0x00FE0000) is read-only (ie, write-protected)\n RESERVED: 0xFFFC, // the remaining 6 bits are reserved and should always be SET\n DEFAULT: 0xFFFF // our default settings (no mapping, no write-protection)\n};\n\n/*\n * Bit definitions for the 16-bit read-only settings/diagnostics register (wSettings)\n *\n * SW1-7 and SW1-8 are mapped to bits 5 and 4 of wSettings, respectively, as follows:\n *\n * SW1-7 SW1-8 Bit5 Bit4 Amount (of base memory provided by the COMPAQ 32-bit memory board)\n * ----- ----- ---- ---- ------\n * ON ON 0 0 640Kb\n * ON OFF 0 1 Invalid\n * OFF ON 1 0 512Kb\n * OFF OFF 1 1 256Kb\n *\n * Other SW1 switches include:\n *\n * SW1-1: ON enables fail-safe timer\n * SW1-2: ON indicates 80387 coprocessor installed\n * SW1-3: ON sets memory from 0xC00000 to 0xFFFFFF (between 12 and 16 megabytes) non-cacheable\n * SW1-4: ON selects AUTO system speed (OFF selects HIGH system speed)\n * SW1-5: RESERVED (however, the system can read its state; see below)\n * SW1-6: COMPAQ Dual-Mode Monitor or Color Monitor (OFF selects Monochrome monitor other than COMPAQ)\n *\n * While SW1-7 and SW1-8 are connected to this memory-mapped register, other SW1 DIP switches are accessible\n * through the 8042 Keyboard Controller's KBC.INPORT register, as follows:\n *\n * SW1-1: TODO: Determine\n * SW1-2: ChipSet.KC8042.INPORT.COMPAQ_NO80387 clear if ON, set (0x04) if OFF\n * SW1-3: TODO: Determine\n * SW1-4: ChipSet.KC8042.INPORT.COMPAQ_HISPEED clear if ON, set (0x10) if OFF\n * SW1-5: ChipSet.KC8042.INPORT.COMPAQ_DIP5OFF clear if ON, set (0x20) if OFF\n * SW1-6: ChipSet.KC8042.INPORT.COMPAQ_NONDUAL clear if ON, set (0x40) if OFF\n */\nCompaqController.SETTINGS = {\n B0_PARITY: 0x0001, // parity OK in byte 0\n B1_PARITY: 0x0002, // parity OK in byte 1\n B2_PARITY: 0x0004, // parity OK in byte 2\n B3_PARITY: 0x0008, // parity OK in byte 3\n BASE_640KB: 0x0000, // SW1-7,8: ON ON Bits 5,4: 00\n BASE_ERROR: 0x0010, // SW1-7,8: ON OFF Bits 5,4: 01\n BASE_512KB: 0x0020, // SW1-7,8: OFF ON Bits 5,4: 10\n BASE_256KB: 0x0030, // SW1-7,8: OFF OFF Bits 5,4: 11\n /*\n * TODO: The DeskPro 386/25 TechRef says bit 6 (0x40) is always set,\n * but setting it results in memory configuration errors; review.\n */\n ADDED_1MB: 0x0040,\n /*\n * TODO: The DeskPro 386/25 TechRef says bit 7 (0x80) is always clear; review.\n */\n PIGGYBACK: 0x0080,\n SYS_4MB: 0x0100, // 4Mb on system board\n SYS_1MB: 0x0200, // 1Mb on system board\n SYS_NONE: 0x0300, // no memory on system board\n MODA_4MB: 0x0400, // 4Mb on module A board\n MODA_1MB: 0x0800, // 1Mb on module A board\n MODA_NONE: 0x0C00, // no memory on module A board\n MODB_4MB: 0x1000, // 4Mb on module B board\n MODB_1MB: 0x2000, // 1Mb on module B board\n MODB_NONE: 0x3000, // no memory on module B board\n MODC_4MB: 0x4000, // 4Mb on module C board\n MODC_1MB: 0x8000, // 1Mb on module C board\n MODC_NONE: 0xC000, // no memory on module C board\n /*\n * NOTE: It doesn't seem to matter to the ROM whether I set any of bits 8-15 or not....\n */\n DEFAULT: 0x0A0F // our default settings (ie, parity OK, 640Kb base memory, 1Mb system memory, 1Mb module A memory)\n};\n\nCompaqController.RAMSETUP = {\n SETUP: 0x000F,\n CACHE: 0x0040,\n RESERVED: 0xFFB0,\n DEFAULT: 0x0002 // our default settings (ie, 2Mb, cache disabled)\n};\n\nCompaqController.BUFFER = [null, 0];\nCompaqController.ACCESS = [CompaqController.readByte, null, null, CompaqController.writeByte, null, null];\n\n/*\n * Initialize all the RAM modules on the page.\n */\nWeb.onInit(RAM.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/keyboard.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * class Keyboard\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass Keyboard extends Component {\n /**\n * Keyboard(parmsKbd)\n *\n * The Keyboard component can be configured with the following (parmsKbd) properties:\n *\n * model: keyboard model string, which must match one of the values listed in Keyboard.MODELS:\n *\n * \"US83\" (default)\n * \"US84\"\n * \"US101\" (not fully supported yet) \n *\n * autoType: string of keys to automatically inject when the machine is ready (undefined if none)\n * \n * softKeys: boolean set to true to enable the machine's soft keyboard, if any (default is false)\n *\n * Its main purpose is to receive binding requests for various keyboard events, and to use those events\n * to simulate the PC's keyboard hardware.\n * \n * TODO: Consider finishing 101-key keyboard support, even though that's sort of a \"PS/2\" thing, and I'm not\n * really interested in taking PCjs into the PS/2 line (that's also why we still support only serial mice, not\n * \"PS/2\" mice). In addition, all keyboards *after* the original PC 83-key keyboard supported their own unique\n * scan code sets, which the 8042 controller would then convert to PC-compatible scan codes. That's probably\n * more important to implement, because that feature was introduced with the 84-key keyboard on the PC AT.\n *\n * @this {Keyboard}\n * @param {Object} parmsKbd\n */\n constructor(parmsKbd)\n {\n super(\"Keyboard\", parmsKbd, Messages.KBD);\n\n this.setModel(parmsKbd['model']);\n\n this.fMobile = Web.isMobile(\"!iPad\");\n this.printMessage(\"mobile keyboard support: \" + (this.fMobile? \"true\" : \"false\"));\n \n /*\n * This flag (formerly fMSIE, for all versions of Microsoft Internet Explorer, up to and including v11)\n * has been updated to reflect the Microsoft Windows *platform* rather than the *browser*, because it appears\n * that all Windows-based browsers (at least now, as of 2018) have the same behavior with respect to \"lock\"\n * keys: keys like CAPS-LOCK generate both UP and DOWN events on every press. On other platforms (eg, macOS),\n * those keys generate only a DOWN event when \"locking\" and only an UP event when \"unlocking\".\n */\n this.fMSWindows = Web.isUserAgent(\"Windows\");\n\n /*\n * This is count of the number of \"soft keyboard\" keys present. At the moment, its only\n * purpose is to signal findBinding() whether to waste any time looking for SOFTCODE matches.\n */\n this.cSoftCodes = 0;\n this.fSoftKeyboard = parmsKbd['softKeys'];\n this.controlSoftKeyboard = null;\n this.controlTextKeyboard = null;\n\n /*\n * Updated by onFocusChange()\n */\n this.fHasFocus = true;\n\n /*\n * This is true whenever the physical Escape key is disabled (eg, by pointer locking code),\n * giving us the opportunity to map a different physical key to machine's virtual Escape key.\n */\n this.fEscapeDisabled = false;\n\n /*\n * This is set whenever we notice a discrepancy between our internal CAPS_LOCK state and its\n * apparent state; we check whenever aKeysActive has been emptied.\n */\n this.fToggleCapsLock = false;\n\n /*\n * New unified approach to key event processing: When we process a key on the \"down\" event,\n * we check the aKeysActive array: if the key is already active, do nothing; otherwise, insert\n * it into the table, generate the \"make\" scan code(s), and set a timeout for \"repeat\" if it's\n * a repeatable key (most are).\n *\n * Similarly, when a key goes \"up\", if it's already not active, do nothing; otherwise, generate\n * the \"break\" scan code(s), cancel any pending timeout, and remove it from the active key table.\n *\n * If a \"press\" event is received, then if the key is already active, remove it and (re)insert\n * it at the head of the table, generate the \"make\" scan code(s), set nRepeat to -1, and set a\n * timeout for \"break\".\n *\n * This requires an aKeysActive array that keeps track of the status of every active key; only the\n * first entry in the array is allowed to repeat. Each entry is a key object with the following\n * properties:\n *\n * simCode: our simulated keyCode from onKeyChange or onKeyPress\n * bitsState: snapshot of the current bitsState when the key is added (currently not used)\n * fDown: next state to simulate (true for down, false for up)\n * nRepeat: > 0 if timer should generate more \"make\" scan code(s), -1 for \"break\" scan code(s)\n * timer: timer for next key operation, if any\n *\n * Keys are inserted at the head of aKeysActive, using splice(0, 0, key), but not before zeroing\n * nRepeat of any repeating key that already occupies the head (index 0), so that at most only one\n * key (ie, the most recent) will ever be in a repeating state.\n *\n * IBM PC keyboard repeat behavior: when pressing CTRL, then C, and then releasing CTRL while still\n * holding C, the repeated CTRL_C characters turn into 'c' characters. We emulate that behavior.\n * However, when pressing C, then CTRL, all repeating stops: not a single CTRL_C is generated, and\n * even if the CTRL is released before the C, no more more 'c' characters are generated either.\n * We do NOT fully emulate that behavior -- we DO stop the repeating, but we also generate one CTRL_C.\n * More investigation is required, because I need to confirm whether the IBM keyboard automatically\n * \"breaks\" all non-shift keys before it \"makes\" the CTRL.\n */\n this.aKeysActive = [];\n\n this.msTransmit = 10; // minimum number of milliseconds between data transmissions\n this.msAutoRepeat = 500;\n this.msNextRepeat = 100;\n this.msAutoRelease = 50;\n this.msInjectDefault = 100; // number of milliseconds between injected keystrokes\n this.msInjectDelay = 0; // set by the initial injectKeys() call\n this.msDoubleClick = 250; // used by mousedown/mouseup handlers to soft-lock modifier keys\n this.cKeysPressed = 0; // count of keys pressed since the last time it was reset\n this.softCodeKeys = Object.keys(Keyboard.SOFTCODES);\n \n /*\n * Remove all single-character SOFTCODE keys from the softCodeKeys array, because those SOFTCODES\n * are not supported by injectKeys(); they can be specified normally using their single-character identity.\n */\n for (var i = 0; i < this.softCodeKeys.length; i++) {\n if (this.softCodeKeys[i].length < 2) {\n this.softCodeKeys.splice(i, 1);\n i--;\n }\n }\n \n /*\n * autoType records the machine's specified autoType sequence, if any, and when injectInit() is called\n * with the appropriate INJECTION signal, injectInit() pass autoType to injectKeys().\n */\n this.autoType = parmsKbd['autoType'];\n this.fDOSReady = false;\n this.fnDOSReady = this.fnInjectReady = null;\n this.nInjection = Keyboard.INJECTION.ON_INPUT;\n\n /*\n * HACK: We set fAllDown to false to ignore all down/up events for keys not explicitly marked as ONDOWN;\n * even though that prevents those keys from being repeated properly (ie, at the simulation's repeat rate\n * rather than the browser's repeat rate), it's the safest thing to do when dealing with international keyboards,\n * because our mapping tables are designed for US keyboards, and testing all the permutations of international\n * keyboards and web browsers is more work than I can take on right now. TODO: Dig into this some day.\n */\n this.fAllDown = false;\n\n this['exports'] = {\n 'type': this.injectKeys,\n 'wait': this.waitReady\n };\n\n this.setReady();\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {Keyboard}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"esc\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var kbd = this;\n var className;\n var id = sHTMLType + '-' + sBinding;\n var controlText = /** @type {HTMLTextAreaElement} */ (control);\n\n if (this.bindings[id] === undefined) {\n switch (sBinding) {\n case \"keyboard\":\n try {\n /*\n * TODO: Fix this rather fragile code, which depends on the current structure of the given xxxx-softkeys.xml\n */\n var controlSoftKeyboard = control.parentElement.parentElement.nextElementSibling;\n className = controlSoftKeyboard.className;\n if (this.fMobile != (className.indexOf('mobile') >= 0)) {\n controlSoftKeyboard = controlSoftKeyboard.nextElementSibling;\n }\n if (controlSoftKeyboard) {\n this.controlSoftKeyboard = controlSoftKeyboard;\n if (this.fSoftKeyboard != null) {\n this.enableSoftKeyboard(this.fSoftKeyboard);\n } else {\n this.fSoftKeyboard = (controlSoftKeyboard.style.display != \"none\");\n }\n control.onclick = function onToggleKeyboard(event) {\n kbd.enableSoftKeyboard(!kbd.fSoftKeyboard);\n };\n /*\n * This is added simply to prevent the page from \"zooming\" around if you accidentally touch between the keys.\n */\n if ('ontouchstart' in window) {\n controlSoftKeyboard.ontouchstart = function onTouchKeyboard(event) {\n event.preventDefault();\n };\n }\n }\n } catch(err) {}\n return true;\n \n case \"screen\":\n /*\n * This is a special binding that the Video component uses to effectively bind its screen to the\n * entire keyboard; eg:\n * \n * this.kbd.setBinding(this.inputTextArea? \"textarea\" : \"canvas\", \"screen\", this.inputScreen);\n *\n * Recording the binding ID prevents multiple controls (or components) from attempting to erroneously\n * bind a control to the same ID, but in the case of a \"dual display\" configuration, we actually want\n * to allow BOTH video components to call setBinding() for \"screen\", so that it doesn't matter which\n * display the user gives focus to.\n *\n * this.bindings[id] = control;\n */\n if (sHTMLType == \"textarea\") {\n this.controlTextKeyboard = controlText;\n }\n controlText.onkeydown = function onKeyDown(event) {\n return kbd.onKeyChange(event, true);\n };\n controlText.onkeypress = function onKeyPressKbd(event) {\n return kbd.onKeyPress(event);\n };\n controlText.onkeyup = function onKeyUp(event) {\n return kbd.onKeyChange(event, false);\n };\n return true;\n\n case \"caps-lock\":\n if (sHTMLType == 'led') {\n this.bindings[id] = control;\n control.onclick = function onClickCapsLock(event) {\n event.preventDefault();\n if (kbd.cmp) kbd.cmp.updateFocus();\n return kbd.toggleCapsLock();\n };\n return true;\n }\n /* falls through */\n\n case \"num-lock\":\n if (sHTMLType == 'led') {\n this.bindings[id] = control;\n control.onclick = function onClickNumLock(event) {\n event.preventDefault();\n if (kbd.cmp) kbd.cmp.updateFocus();\n return kbd.toggleNumLock();\n };\n return true;\n }\n /* falls through */\n\n case \"scroll-lock\":\n if (sHTMLType == 'led') {\n this.bindings[id] = control;\n control.onclick = function onClickScrollLock(event) {\n event.preventDefault();\n if (kbd.cmp) kbd.cmp.updateFocus();\n return kbd.toggleScrollLock();\n };\n return true;\n }\n /* falls through */\n\n default:\n /*\n * Maintain support for older button codes; eg, map button code \"ctrl-c\" to CLICKCODE \"CTRL_C\"\n */\n var sCode = sBinding.toUpperCase().replace(/-/g, '_');\n if (Keyboard.CLICKCODES[sCode] !== undefined && sHTMLType == \"button\") {\n this.bindings[id] = controlText;\n if (MAXDEBUG) console.log(\"binding click-code '\" + sCode + \"'\");\n controlText.onclick = function(kbd, sKey, simCode) {\n return function onKeyboardBindingClick(event) {\n if (kbd.messageEnabled()) kbd.printMessage(sKey + \" clicked\", Messages.EVENT | Messages.KEY);\n event.preventDefault(); // preventDefault() is necessary...\n if (kbd.cmp) kbd.cmp.updateFocus(); // ...for the updateFocus() call to actually work\n kbd.sInjectBuffer = \"\"; // key events should stop any injection currently in progress\n kbd.updateShiftState(simCode, true); // future-proofing if/when any LOCK keys are added to CLICKCODES\n kbd.addActiveKey(simCode, true);\n };\n }(this, sCode, Keyboard.CLICKCODES[sCode]);\n return true;\n }\n else if (Keyboard.SOFTCODES[sBinding] !== undefined) {\n /*\n * TODO: Fix this rather fragile code, which depends on the current structure of the given xxxx-softkeys.xml\n */\n className = control.parentElement.parentElement.className;\n if (className && this.fMobile != (className.indexOf('mobile') >= 0)) {\n break;\n }\n this.cSoftCodes++;\n this.bindings[id] = controlText;\n if (MAXDEBUG) console.log(\"binding soft-code '\" + sBinding + \"'\");\n var msLastEvent = 0, nClickState = 0;\n var fStateKey = (Keyboard.KEYSTATES[Keyboard.SOFTCODES[sBinding]] <= Keyboard.STATE.ALL_MODIFIERS);\n var fnDown = function(kbd, sKey, simCode) {\n return function onKeyboardBindingDown(event) {\n var msDelta = event.timeStamp - msLastEvent;\n nClickState = (nClickState && msDelta < kbd.msDoubleClick? (nClickState << 1) : 1);\n msLastEvent = event.timeStamp;\n event.preventDefault(); // preventDefault() is necessary to avoid \"zooming\" when you type rapidly\n kbd.sInjectBuffer = \"\"; // key events should stop any injection currently in progress\n kbd.addActiveKey(simCode);\n };\n }(this, sBinding, Keyboard.SOFTCODES[sBinding]);\n var fnUp = function(kbd, sKey, simCode) {\n return function onKeyboardBindingUp(event) {\n if (nClickState) {\n var msDelta = event.timeStamp - msLastEvent;\n nClickState = (fStateKey && msDelta < kbd.msDoubleClick? (nClickState << 1) : 0);\n msLastEvent = event.timeStamp;\n if (nClickState < 8) {\n kbd.removeActiveKey(simCode);\n } else {\n if (MAXDEBUG) console.log(\"soft-locking '\" + sBinding + \"'\");\n nClickState = 0;\n }\n }\n };\n }(this, sBinding, Keyboard.SOFTCODES[sBinding]);\n if ('ontouchstart' in window) {\n controlText.ontouchstart = fnDown;\n controlText.ontouchend = fnUp;\n } else {\n controlText.onmousedown = fnDown;\n controlText.onmouseup = controlText.onmouseout = fnUp;\n }\n return true;\n }\n else if (sValue) {\n /*\n * Instead of just having a dedicated \"test\" control, we now treat any unrecognized control with\n * a \"value\" attribute as a test control. The only caveat is that such controls must have binding IDs\n * that do not conflict with predefined controls (which, of course, is the only way you can get here).\n */\n this.bindings[id] = control;\n control.onclick = function onClickTest(event) {\n event.preventDefault(); // preventDefault() is necessary...\n if (kbd.cmp) kbd.cmp.updateFocus(); // ...for the updateFocus() call to actually work\n return kbd.injectKeys(sValue);\n };\n return true;\n }\n break;\n }\n }\n return false;\n }\n\n /**\n * findBinding(simCode, sType, fDown)\n *\n * TODO: This function is woefully inefficient, because the SOFTCODES table is designed for converting\n * soft key presses into SIMCODES, whereas this function is doing the reverse: looking for the soft key,\n * if any, that corresponds to a SIMCODE, simply so we can provide visual feedback of keys activated\n * by other means (eg, real keyboard events, button clicks that generate key sequences like CTRL-ALT-DEL,\n * etc).\n *\n * To minimize this function's cost, we would want to dynamically create a reverse-lookup table after\n * all the setBinding() calls for the soft keys have been established; note that the reverse-lookup table\n * would contain MORE entries than the SOFTCODES table, because there are multiple simCodes that correspond\n * to a given soft key (eg, '1' and '!' both map to the same soft key).\n *\n * @this {Keyboard}\n * @param {number} simCode\n * @param {string} sType is the type of control (eg, \"button\" or \"key\")\n * @param {boolean} [fDown] is true if the key is going down, false if up, or undefined if unchanged\n * @return {Object} is the HTML control DOM object (eg, HTMLButtonElement), or undefined if no such control exists\n */\n findBinding(simCode, sType, fDown)\n {\n var control;\n if (this.cSoftCodes && this.fSoftKeyboard) {\n for (var code in Keys.SHIFTED_KEYCODES) {\n if (simCode == Keys.SHIFTED_KEYCODES[code]) {\n simCode = +code;\n code = Keys.NONASCII_KEYCODES[code];\n if (code) simCode = +code;\n break;\n }\n }\n /*\n * TODO: Create a table that maps these SIMCODEs to the corresponding entries in the SOFTCODES table;\n * these SIMCODEs can be generated by CLICKCODEs or by the special key remapping HACKs in onKeyChange().\n */\n if (simCode == Keyboard.SIMCODE.CTRL_PAUSE) {\n simCode = Keyboard.SIMCODE.NUM_LOCK;\n }\n else if (simCode == Keyboard.SIMCODE.CTRL_BREAK) {\n simCode = Keyboard.SIMCODE.SCROLL_LOCK;\n }\n else if (simCode == Keyboard.SIMCODE.CTRL_ALT_DEL) {\n simCode = Keyboard.SIMCODE.DEL;\n }\n else if (simCode == Keyboard.SIMCODE.CTRL_ALT_INS) {\n simCode = Keyboard.SIMCODE.INS;\n }\n else if (simCode == Keyboard.SIMCODE.CTRL_ALT_ADD) {\n simCode = Keyboard.SIMCODE.NUM_ADD;\n }\n else if (simCode == Keyboard.SIMCODE.CTRL_ALT_SUB) {\n simCode = Keyboard.SIMCODE.NUM_SUB;\n }\n for (var sBinding in Keyboard.SOFTCODES) {\n if (Keyboard.SOFTCODES[sBinding] == simCode || Keyboard.SOFTCODES[sBinding] == this.toUpperKey(simCode)) {\n var id = sType + '-' + sBinding;\n control = this.bindings[id];\n if (control && fDown !== undefined) {\n this.setSoftKeyState(control, fDown);\n }\n break;\n }\n }\n }\n return control;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {Keyboard}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n var kbd = this;\n this.timerInject = this.cpu.addTimer(this.id + \".inject\", function injectKeysTimer() {\n kbd.injectKeys();\n });\n \n this.timerTransmit = this.cpu.addTimer(this.id + \".transmit\", function transmitDataTimer() {\n kbd.transmitData();\n });\n\n this.chipset = cmp.getMachineComponent(\"ChipSet\");\n this.autoType = cmp.getMachineParm('autoType') || this.autoType;\n\n var softKeys = cmp.getMachineParm('softKeys');\n if (softKeys) this.enableSoftKeyboard(softKeys != \"false\");\n\n cpu.addIntNotify(Interrupts.DOS, this.intDOS.bind(this));\n }\n\n /**\n * start()\n *\n * Notification from the Computer that it's starting.\n *\n * @this {Keyboard}\n */\n start()\n {\n this.injectInit(Keyboard.INJECTION.ON_START);\n }\n\n /**\n * intDOS()\n *\n * Monitors selected DOS interrupts for signals to initialize 'autoType' injection.\n *\n * @this {Keyboard}\n * @param {number} addr\n * @return {boolean} true to proceed with the INT 0x21 software interrupt, false to skip\n */\n intDOS(addr)\n {\n var AH = (this.cpu.regEAX >> 8) & 0xff;\n if (AH == 0x0A) {\n this.fDOSReady = true;\n if (this.fnDOSReady) {\n this.fnDOSReady();\n this.fnDOSReady = null;\n this.fDOSReady = false;\n } else {\n this.injectInit(Keyboard.INJECTION.ON_INPUT);\n }\n }\n return true;\n }\n\n /**\n * notifyEscape(fDisabled, fAllDown)\n *\n * When ESC is used by the browser to disable pointer lock, this gives us the option of mapping a different key to ESC.\n *\n * @this {Keyboard}\n * @param {boolean} fDisabled\n * @param {boolean} [fAllDown] (an experimental option to re-enable processing of all onkeydown/onkeyup events)\n */\n notifyEscape(fDisabled, fAllDown)\n {\n this.fEscapeDisabled = fDisabled;\n if (fAllDown !== undefined) this.fAllDown = fAllDown;\n }\n\n /**\n * resetDevice()\n *\n * @this {Keyboard}\n */\n resetDevice()\n {\n /*\n * TODO: There's more to reset, like LED indicators, default type rate, and emptying the scan code buffer.\n */\n this.printMessage(\"keyboard reset\", Messages.KBD | Messages.PORT);\n this.abBuffer = [];\n this.setResponse(Keyboard.CMDRES.BAT_OK);\n }\n\n /**\n * setModel(sModel)\n *\n * This breaks a model string (eg, \"US83\") into two parts: modelCountry (eg, \"US\") and modelKeys (eg, 83).\n * If the model string isn't recognized, we use Keyboard.MODELS[0] (ie, the first entry in the model array).\n *\n * @this {Keyboard}\n * @param {string|undefined} sModel\n */\n setModel(sModel)\n {\n var iModel = 0;\n this.model = null;\n if (typeof sModel == \"string\") {\n this.model = sModel.toUpperCase();\n iModel = Keyboard.MODELS.indexOf(this.model);\n if (iModel < 0) iModel = 0;\n }\n sModel = Keyboard.MODELS[iModel];\n if (sModel) {\n this.modelCountry = sModel.substr(0, 2);\n this.modelKeys = parseInt(sModel.substr(2), 10);\n }\n }\n\n /**\n * checkBuffer(b)\n *\n * This is the ChipSet's interface to let us know it's ready.\n *\n * @this {Keyboard}\n * @param {number} [b] (set to the data, if any, that the ChipSet just delivered)\n */\n checkBuffer(b)\n {\n var fReady = false;\n if (b) {\n /*\n * The following hack is for the 5170 ROM BIOS keyboard diagnostic, which expects the keyboard\n * to report BAT_OK immediately after the ACK from a RESET command. The BAT_OK response should already\n * be in the keyboard's buffer; we just need to give it a little nudge.\n */\n if (b == Keyboard.CMDRES.ACK) {\n fReady = true;\n }\n if (this.cpu) {\n this.cpu.setTimer(this.timerTransmit, this.msTransmit, true);\n }\n }\n this.transmitData(fReady);\n }\n\n /**\n * flushBuffer()\n *\n * This is the ChipSet's interface to flush any buffered keyboard data.\n *\n * @this {Keyboard}\n */\n flushBuffer()\n {\n this.abBuffer = [];\n if (!COMPILED && this.messageEnabled()) this.printMessage(\"keyboard data flushed\");\n }\n\n /**\n * receiveCmd(bCmd)\n *\n * This is the ChipSet's interface for controlling \"Model M\" keyboards (ie, those used with MODEL_5170\n * machines). Commands are delivered through the ChipSet's 8042 Keyboard Controller.\n *\n * @this {Keyboard}\n * @param {number} bCmd should be one of the Keyboard.CMD.* command codes (Model M keyboards only)\n * @return {number} response should be one of the Keyboard.CMDRES.* response codes, or -1 if unrecognized\n */\n receiveCmd(bCmd)\n {\n var b = -1;\n\n if (!COMPILED && this.messageEnabled()) this.printMessage(\"receiveCmd(\" + Str.toHexByte(bCmd) + \")\");\n\n switch(this.bCmdPending || bCmd) {\n\n case Keyboard.CMD.RESET: // 0xFF\n b = Keyboard.CMDRES.ACK;\n this.resetDevice();\n break;\n\n case Keyboard.CMD.SET_RATE: // 0xF3\n if (this.bCmdPending) {\n this.setRate(bCmd);\n bCmd = 0;\n }\n this.setResponse(Keyboard.CMDRES.ACK);\n this.bCmdPending = bCmd;\n break;\n\n case Keyboard.CMD.SET_LEDS: // 0xED\n if (this.bCmdPending) {\n this.setLEDs(bCmd);\n bCmd = 0;\n }\n this.setResponse(Keyboard.CMDRES.ACK);\n this.bCmdPending = bCmd;\n break;\n\n default:\n if (!COMPILED) this.printMessage(\"receiveCmd(): unrecognized command\");\n break;\n }\n\n return b;\n }\n\n /**\n * setEnabled(fData, fClock)\n *\n * This is the ChipSet's interface for toggling keyboard \"data\" and \"clock\" lines.\n * \n * For MODEL_5150 and MODEL_5160 machines, this function is called from the ChipSet's PPI_B\n * output handler. For MODEL_5170 machines, this function is called when selected CMD\n * \"data bytes\" have been written.\n *\n * @this {Keyboard}\n * @param {boolean} fData is true if the keyboard simulated data line should be enabled\n * @param {boolean} fClock is true if the keyboard's simulated clock line should be enabled\n * @return {boolean} true if keyboard was re-enabled, false if not (or no change)\n */\n setEnabled(fData, fClock)\n {\n var fReset = false;\n if (this.fClock !== fClock) {\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.PORT)) {\n this.printMessage(\"keyboard clock line changing to \" + fClock, true);\n }\n /*\n * Toggling the clock line low and then high signals a \"reset\", which we acknowledge once the\n * data line is high as well.\n */\n this.fClock = this.fResetOnEnable = fClock;\n }\n if (this.fData !== fData) {\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.PORT)) {\n this.printMessage(\"keyboard data line changing to \" + fData, true);\n }\n this.fData = fData;\n if (fData && !this.fResetOnEnable) {\n this.transmitData(true);\n }\n }\n if (this.fData && this.fResetOnEnable) {\n this.resetDevice();\n this.fResetOnEnable = false;\n fReset = true;\n }\n return fReset;\n }\n\n /**\n * setLEDs(b)\n *\n * This processes the option byte received after a SET_LEDS command byte.\n *\n * @this {Keyboard}\n * @param {number} b\n */\n setLEDs(b)\n {\n this.bLEDs = b; // TODO: Implement\n }\n\n /**\n * setRate(b)\n *\n * This processes the rate parameter byte received after a SET_RATE command byte.\n *\n * @this {Keyboard}\n * @param {number} b\n */\n setRate(b)\n {\n this.bRate = b; // TODO: Implement\n }\n\n /**\n * setResponse(b)\n *\n * @this {Keyboard}\n * @param {number} b\n */\n setResponse(b)\n {\n if (this.chipset) {\n this.abBuffer.unshift(b);\n if (!COMPILED && this.messageEnabled()) this.printMessage(\"keyboard response \" + Str.toHexByte(b) + \" buffered\");\n this.transmitData();\n }\n }\n\n /**\n * transmitData(fReady)\n *\n * This manages communication with the ChipSet's receiveKbdData() interface.\n *\n * @this {Keyboard}\n * @param {boolean} [fReady]\n */\n transmitData(fReady)\n {\n if (this.chipset) {\n if (fReady || !this.cpu.isTimerSet(this.timerTransmit)) {\n /*\n * The original IBM PC BIOS performs a \"stuck key\" test by resetting the keyboard\n * (by toggling the CLOCK line), then checking for a BAT_OK response (0xAA), and then\n * clocking in the next byte (by toggling the DATA line); if that next byte isn't 0x00,\n * then the BIOS reports a \"301\" error, along with \"AA\" if we failed to properly flush\n * the BAT_OK response. \n */\n var b = this.abBuffer.length? this.abBuffer[0] : 0; \n if (this.chipset.receiveKbdData(b)) {\n if (!COMPILED && this.messageEnabled()) this.printMessage(\"keyboard data \" + Str.toHexByte(b) + \" delivered\");\n this.abBuffer.shift();\n }\n if (b) this.cpu.setTimer(this.timerTransmit, this.msTransmit);\n }\n }\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {Keyboard}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n /*\n * TODO: Save/restore support for Keyboard is the barest minimum. In fact, originally, I wasn't\n * saving/restoring anything, and that was OK, but if we don't at least re-initialize fClock/fData,\n * we can get a spurious reset following a restore. In an ideal world, we might choose to save/restore\n * abBuffer as well, but realistically, I think it's going to be safer to always start with an\n * empty buffer--and who's going to notice anyway?\n *\n * So, like Debugger, we deviate from the typical save/restore pattern: instead of reset OR restore,\n * we always reset and then perform a (very limited) restore.\n */\n this.reset();\n if (data && this.restore) {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Keyboard}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {Keyboard}\n */\n reset()\n {\n /*\n * If no keyboard model was specified, our initial setModel() call will select the \"US83\" keyboard as the\n * default, but now that the ChipSet is initialized, we can pick a better default, based on the ChipSet model.\n */\n if (!this.model && this.chipset) {\n switch(this.chipset.model) {\n case ChipSet.MODEL_5150:\n case ChipSet.MODEL_5160:\n this.setModel(Keyboard.MODELS[0]);\n break;\n case ChipSet.MODEL_5170:\n default:\n this.setModel(Keyboard.MODELS[1]);\n break;\n }\n }\n this.initState();\n }\n\n /**\n * save()\n *\n * This implements save support for the Keyboard component.\n *\n * @this {Keyboard}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveState());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the Keyboard component.\n *\n * @this {Keyboard}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return this.initState(data[0]);\n }\n\n /**\n * initState(data)\n *\n * @this {Keyboard}\n * @param {Array} [data]\n * @return {boolean} true if successful, false if failure\n */\n initState(data)\n {\n /*\n * Empty the injection buffer (an injection could have been in progress on any reset after the first).\n */\n this.sInjectBuffer = \"\";\n this.nInjection = Keyboard.INJECTION.ON_INPUT;\n\n if (!data) {\n data = [];\n } else {\n /*\n * If there is a predefined state for this machine, then the assumption is that any injection\n * sequence can be injected as soon as the machine starts. Any other kind of state must disable\n * injection, because injection depends on the machine being in a known state.\n */\n this.nInjection = this.cmp.sStatePath? Keyboard.INJECTION.ON_START : Keyboard.INJECTION.NONE;\n }\n\n var i = 0;\n this.fClock = data[i++];\n this.fData = data[i];\n this.bCmdPending = 0; // when non-zero, a command is pending (eg, SET_LED or SET_RATE)\n\n /*\n * The current (assumed) physical (and simulated) states of the various shift/lock keys.\n *\n * TODO: Determine how (or whether) we can query the browser's initial shift/lock key states.\n */\n this.bitsState = this.bitsStateSim = 0;\n\n /*\n * New scan codes are \"pushed\" onto abBuffer and then \"shifted\" off.\n */\n this.abBuffer = [];\n\n return true;\n }\n\n /**\n * saveState()\n *\n * @this {Keyboard}\n * @return {Array}\n */\n saveState()\n {\n var data = [];\n data[0] = this.fClock;\n data[1] = this.fData;\n return data;\n }\n\n /**\n * enableSoftKeyboard(fEnable)\n *\n * In addition to enabling or disabling our own soft keyboard (if any), this also attempts to disable or enable\n * (as appropriate) the textarea control (if any) that machines use to trigger a touch device's built-in keyboard.\n * \n * @this {Keyboard}\n * @param {boolean} fEnable\n */\n enableSoftKeyboard(fEnable)\n {\n if (this.controlSoftKeyboard) {\n if (!fEnable) {\n this.controlSoftKeyboard.style.display = \"none\";\n if (this.controlTextKeyboard) {\n this.controlTextKeyboard.readOnly = false;\n }\n } else {\n this.controlSoftKeyboard.style.display = \"block\";\n if (this.controlTextKeyboard) {\n this.controlTextKeyboard.readOnly = true;\n }\n }\n }\n this.fSoftKeyboard = fEnable;\n }\n \n /**\n * setSoftKeyState(control, f)\n *\n * @this {Keyboard}\n * @param {HTMLElement} control is an HTML control DOM object\n * @param {boolean} f is true if the key represented by e should be \"on\", false if \"off\"\n */\n setSoftKeyState(control, f)\n {\n control.style.color = (f? \"#ffffff\" : \"#000000\");\n control.style.backgroundColor = (f? \"#000000\" : \"#ffffff\");\n }\n\n /**\n * addScanCode(bScan)\n *\n * @this {Keyboard}\n * @param {number} bScan\n */\n addScanCode(bScan)\n {\n /*\n * Prepare for the possibility that our reset() function may not have been called yet.\n *\n * TODO: Determine whether we need to reset() the Keyboard sooner (ie, in the constructor),\n * or if we need to protect other methods from prematurely accessing certain Keyboard structures,\n * as a result of calls from any of the key event handlers established by setBinding().\n */\n if (this.abBuffer) {\n if (this.abBuffer.length < Keyboard.LIMIT.MAX_SCANCODES) {\n if (DESKPRO386) {\n if (this.chipset && this.chipset.model == ChipSet.MODEL_COMPAQ_DESKPRO386) {\n /*\n * COMPAQ keyclick support is being disabled because we are currently unable to properly\n * simulate the keyclick sound, due to the way the COMPAQ DeskPro 386 ROM rapidly toggles\n * the speaker bit. And there isn't really a better time to disable it, because the\n * COMPAQ_KEYCLICK byte is set by IBMBIO.COM initialization code in COMPAQ MS-DOS, if the\n * machine model byte is FC (indicating PC AT):\n * \n * &0070:2EF7 2E CS:\n * &0070:2EF8 803E442DFC CMP [2D44],FC\n * &0070:2EFD 750C JNZ 2F0B (IBMBIO.COM+0x3174)\n * &0070:2EFF 26 ES:\n * &0070:2F00 C606160401 MOV [0416],01\n */\n if (!this.cpu.isProtMode()) {\n this.bus.setByteDirect(ROMX86.BIOS.COMPAQ_KEYCLICK, 0);\n }\n }\n }\n this.abBuffer.push(bScan);\n if (!COMPILED && this.messageEnabled()) this.printMessage(\"keyboard data \" + Str.toHexByte(bScan) + \" buffered\");\n this.transmitData();\n return;\n }\n if (this.abBuffer.length == Keyboard.LIMIT.MAX_SCANCODES) {\n this.abBuffer.push(Keyboard.CMDRES.BUFF_FULL);\n }\n this.printMessage(\"keyboard buffer overflow\");\n }\n }\n\n /**\n * injectInit(nCondition)\n *\n * @this {Keyboard}\n * @param {number} nCondition\n */\n injectInit(nCondition)\n {\n if (this.nInjection == nCondition) {\n this.nInjection = Keyboard.INJECTION.NONE;\n if (this.autoType) this.injectKeys(this.autoType);\n }\n }\n\n /**\n * injectKeys(sKeys, msDelay)\n *\n * @this {Keyboard}\n * @param {string} [sKeys]\n * @param {number} [msDelay] is an optional injection delay (default is msInjectDefault)\n * @return {boolean}\n */\n injectKeys(sKeys, msDelay)\n {\n if (sKeys) {\n var sInjectBuffer = this.parseKeys(sKeys);\n if (sInjectBuffer) {\n this.nInjection = Keyboard.INJECTION.NONE;\n this.sInjectBuffer = sInjectBuffer;\n if (!COMPILED) this.log(\"injectKeys(\\\"\" + this.sInjectBuffer.split(\"\\n\").join(\"\\\\n\") + \"\\\")\");\n this.msInjectDelay = msDelay || this.msInjectDefault;\n this.injectKeys();\n return true;\n }\n return false;\n }\n /*\n * Any delay of one second or more ($10 and up) is automatically reverted to the default.\n */\n if (this.msInjectDelay >= 1000) {\n this.msInjectDelay = this.msInjectDefault;\n }\n var simCode = 0;\n while (this.sInjectBuffer.length > 0 && !simCode) {\n var ch = this.sInjectBuffer.charAt(0);\n if (ch == '$') {\n /*\n * $<number> pauses injection by the specified number of tenths of a second; eg,\n * $5 pauses for 1/2 second. $0 reverts the default injection delay (eg, 100ms).\n * Also, you may end the number with a period if you need to avoid an injected digit\n * being misinterpreted as part of the delay (eg, $5.1) pauses for 1/2 second and\n * then injects \"1\").\n */\n var digits = this.sInjectBuffer.match(/^\\$([0-9]+)\\.?/);\n if (digits) {\n this.msInjectDelay = (+digits[1] * 100) || this.msInjectDefault;\n this.sInjectBuffer = this.sInjectBuffer.substr(digits[0].length);\n break;\n }\n /*\n * Yes, this code is slow and gross, but it's simple, and key injection doesn't have\n * to be that fast anyway. The added check for SOFTCODES that have omitted the 'num-'\n * prefix adds to the slowness, but it's a nice convenience, allowing you to specify\n * non-ASCII keys like 'num-right' or 'num-up' more succinctly as \"$right\" or \"$up\". \n */\n for (var i = 0; i < this.softCodeKeys.length; i++) {\n var name = this.softCodeKeys[i];\n if (this.sInjectBuffer.indexOf(name) == 1) {\n simCode = Keyboard.SOFTCODES[name];\n this.sInjectBuffer = this.sInjectBuffer.substr(name.length + 1);\n break;\n }\n var shortName = (name.indexOf('num-') == 0? name.substr(4) : \"\");\n if (shortName && this.sInjectBuffer.indexOf(shortName) == 1) {\n simCode = Keyboard.SOFTCODES[name];\n this.sInjectBuffer = this.sInjectBuffer.substr(shortName.length + 1);\n break;\n }\n }\n }\n if (simCode) break;\n this.sInjectBuffer = this.sInjectBuffer.substr(1);\n var charCode = ch.charCodeAt(0);\n /*\n * charCodes 0x01-0x1A correspond to key combinations CTRL-A through CTRL-Z, unless they\n * are \\t, \\n, or \\r, which are reserved for TAB, LINE-FEED, and RETURN, respectively, so if\n * you need to simulate CTRL-I, CTRL-J, or CTRL-M, those must be specified using \\x1C, \\x1D,\n * or \\x1E, respectively. Also, since PCs have no dedicated LINE-FEED key, and since \\n is\n * often used instead of \\r, we map LINE-FEED (LF) to RETURN (CR) below.\n */\n if (charCode <= Keys.ASCII.CTRL_Z) {\n simCode = charCode;\n /*\n * I could require all callers to supply CRs instead of LFs, but this is friendlier; besides,\n * PCs don't have a dedicated LINE-FEED key, so the LF charCode is somewhat meaningless.\n */\n if (charCode == 0x0A) simCode = 0x0D;\n if (charCode != Keys.ASCII.CTRL_I && charCode != Keys.ASCII.CTRL_J && charCode != Keys.ASCII.CTRL_M) {\n simCode += Keys.KEYCODE.FAKE;\n }\n }\n else if (charCode == 0x1C) {\n simCode = Keys.ASCII.CTRL_I + Keys.KEYCODE.FAKE;\n }\n else if (charCode == 0x1D) {\n simCode = Keys.ASCII.CTRL_J + Keys.KEYCODE.FAKE;\n }\n else if (charCode == 0x1E) {\n simCode = Keys.ASCII.CTRL_M + Keys.KEYCODE.FAKE;\n }\n else if (charCode == 0x1F) {\n simCode = Keys.ASCII['$'];\n }\n else if (charCode <= 0x7F) {\n simCode = charCode;\n }\n }\n \n if (simCode) {\n var fPress = (Keyboard.MODIFIERS[simCode] === undefined); \n this.addActiveKey(simCode, fPress);\n if (fPress) this.clearActiveKeys(true);\n }\n \n if (!this.sInjectBuffer.length) {\n if (this.fnInjectReady) {\n this.fnInjectReady();\n this.fnInjectReady = null;\n }\n } else {\n this.cpu.setTimer(this.timerInject, this.msInjectDelay);\n }\n return true;\n }\n\n /**\n * parseKeys(sKeys)\n *\n * The following special \"macro\" sequences are recognized:\n *\n * $date: converted to MM-DD-YYYY\n * $time: converted to HH:MM\n *\n * In addition, property keys in the SOFTCODES tables can be prefixed with \"$\" if you want to specify\n * a key by its SOFTCODE; eg:\n *\n * $f1: the F1 function key\n * $alt: the ALT key\n *\n * Not all SOFTCODES are allowed; for example, SOFTCODES that begin with a digit or other non-alpha symbol,\n * or that contain only one letter, because those SOFTCODES can already be specified as-is, WITHOUT a leading\n * \"$\". Also, all we replace here are the \"macro\" sequences, leaving any prefixed SOFTCODES in place so that\n * injectKeys() can convert them on the fly.\n *\n * If you want any of those sequences to be typed as-is, then you must specify two \"$\" (eg, \"$$date\").\n * Pairs of dollar signs will be automatically converted to single dollar signs, and single dollar signs\n * will be used as-is, provided they don't precede any of the above \"macro\" or SOFTCODE sequences.\n *\n * WARNING: the JavaScript replace() function ALWAYS interprets \"$\" specially in replacement strings,\n * even when the search string is NOT a RegExp; specifically:\n *\n * $$ Inserts a \"$\"\n * $& Inserts the matched substring\n * $` Inserts the portion of the string that precedes the matched substring\n * $' Inserts the portion of the string that follows the matched substring\n * $n Where n is a positive integer less than 100, inserts the nth parenthesized sub-match string,\n * provided the first argument was a RegExp object\n *\n * Since we build machine definitions on a page from a potentially indeterminate number of string replace()\n * operations, multiple dollar signs could eventually get reduced to a single dollar sign BEFORE we get here.\n *\n * To compensate, I've changed a few replace() methods, like MarkOut's convertMDMachineLinks() and HTMLOut's\n * addFilesToHTML(), from the conventional string replace() to my own Str.replace(), and for situations like the\n * embed.js parseXML() function, which needs to use a RegExp-style replace(), I've added a preliminary\n * replace(/\\$/g, \"$$$$\") to the replacement string.\n *\n * Unfortunately, this is something that will be extremely difficult to prevent from breaking down the road.\n * So, heads up to future me....\n *\n * @this {Keyboard}\n * @param {string|undefined} sKeys\n * @return {string|undefined}\n */\n parseKeys(sKeys)\n {\n if (sKeys) {\n var match, reSpecial = /(?:^|[^$])\\$([a-z0-9][a-z0-9-]+)/g;\n while (match = reSpecial.exec(sKeys)) {\n var sReplace = \"\";\n switch (match[1]) {\n case 'date':\n sReplace = Usr.formatDate(\"n-j-Y\");\n break;\n case 'time':\n sReplace = Usr.formatDate(\"h:i:s\");\n break;\n default:\n continue;\n }\n sKeys = sKeys.replace('$' + match[1], sReplace);\n /*\n * Even though we did just modify the string that reSpecial is iterating over, we aren't\n * going to muck with lastIndex, because 1) the replacement strings are always longer than\n * original strings, and 2) any unrecognized sequences that we now leave in place would cause\n * us to loop indefinitely. So, if you really want to do this, you will have to carefully\n * set lastIndex to the next unexamined character, not back to the beginning.\n *\n * reSpecial.lastIndex = 0;\n */\n }\n /*\n * Any lingering \"$$\" sequences are now converted to a special code (\\x1F) that injectKeys() knows about.\n */\n sKeys = sKeys.replace(/\\$\\$/g, '\\x1F');\n }\n return sKeys;\n }\n\n /**\n * waitReady(fnCallReady, sOption)\n *\n * @this {Keyboard}\n * @param {function()|null} fnCallReady\n * @param {string} [sOption]\n * @return {boolean} false if wait required, true otherwise\n */\n waitReady(fnCallReady, sOption)\n {\n var fReady = false;\n\n switch(sOption) {\n case \"DOS\":\n if (this.fDOSReady) {\n fReady = true;\n } else {\n this.fnDOSReady = fnCallReady;\n }\n break;\n\n default:\n if (!this.sInjectBuffer.length) {\n fReady = true;\n } else {\n this.fnInjectReady = fnCallReady;\n }\n break;\n }\n return fReady;\n }\n\n /**\n * setLED(control, f)\n *\n * @this {Keyboard}\n * @param {HTMLElement} control is an HTML control DOM object\n * @param {boolean} f is true if the LED represented by control should be \"on\", false if \"off\"\n */\n setLED(control, f)\n {\n /*\n * TODO: Add support for user-definable LED colors\n */\n control.style.backgroundColor = (f? \"#00ff00\" : \"#000000\");\n }\n\n /**\n * updateLEDs(bitState)\n *\n * Updates any and all shift-related LEDs with the corresponding state in bitsStateSim.\n *\n * @this {Keyboard}\n * @param {number} [bitState] is the bit in bitsStateSim that may have changed, if known; undefined if not\n */\n updateLEDs(bitState)\n {\n var control;\n for (var sBinding in Keyboard.LEDSTATES) {\n var id = \"led-\" + sBinding;\n var bitLED = Keyboard.LEDSTATES[sBinding];\n if ((!bitState || bitState == bitLED) && (control = this.bindings[id])) {\n this.setLED(control, !!(this.bitsStateSim & bitLED));\n }\n }\n }\n\n /**\n * toggleCapsLock()\n *\n * @this {Keyboard}\n */\n toggleCapsLock()\n {\n this.addActiveKey(Keyboard.SIMCODE.CAPS_LOCK, true);\n }\n\n /**\n * toggleNumLock()\n *\n * @this {Keyboard}\n */\n toggleNumLock()\n {\n this.addActiveKey(Keyboard.SIMCODE.NUM_LOCK, true);\n }\n\n /**\n * toggleScrollLock()\n *\n * @this {Keyboard}\n */\n toggleScrollLock()\n {\n this.addActiveKey(Keyboard.SIMCODE.SCROLL_LOCK, true);\n }\n\n /**\n * updateShiftState(simCode, fSim, fDown)\n *\n * For non-locking shift keys, this function is straightforward: when fDown is true, the corresponding bitState\n * is set, and when fDown is false, it's cleared. However, for LOCK keys, fDown true means toggle, and fDown false\n * means no change.\n *\n * @this {Keyboard}\n * @param {number} simCode (includes any ONDOWN and/or ONRIGHT modifiers)\n * @param {boolean} [fSim] is true to update simulated state only\n * @param {boolean|null} [fDown] is true for down, false for up, undefined for toggle\n * @return {number} 0 if not a shift key, 1 if shift key down, -1 if shift key up\n */\n updateShiftState(simCode, fSim, fDown)\n {\n var result = 0;\n if (Keyboard.SIMCODES[simCode]) {\n var fRight = (Math.floor(simCode / 1000) & 2);\n var bitState = Keyboard.KEYSTATES[simCode] || 0;\n if (bitState) {\n if (fRight && !(bitState & Keyboard.STATE.ALL_RIGHT)) {\n bitState >>= 1;\n }\n if (bitState & Keyboard.STATE.ALL_LOCKS) {\n if (fDown === false) return -1;\n fDown = null;\n }\n if (fDown == null) { // ie, null or undefined\n fDown = !((fSim? this.bitsStateSim : this.bitsState) & bitState);\n }\n else if (!fDown && !fSim) {\n /*\n * In current webkit browsers, pressing and then releasing both left and right shift keys together\n * (or both ALT keys, or both CMD/Windows keys, or presumably both CTRL keys) results in 4 events,\n * as you would expect, but 3 of the 4 are \"down\" events; only the last of the 4 is an \"up\" event.\n *\n * Perhaps this is a browser accessibility feature (ie, deliberately suppressing the \"up\" event\n * of one of the shift keys to implement a \"sticky shift mode\"?), but in any case, to maintain our\n * internal consistency, if this is an \"up\" event and the shift state bit is any of ALL_MODIFIERS,\n * then we set it to ALL_MODIFIERS, so that we'll automatically clear ALL shift states.\n *\n * TODO: The only downside to this work-around is that the simulation will still think a shift key is\n * down. So in effect, we have enabled a \"sticky shift mode\" inside the simulation, whether or not that\n * was the browser's intent. To fix that, we would have to identify the shift key that never went up\n * and simulate the \"up\". That's more work than I think the problem merits. The user just needs to tap\n * a single shift key to get out that mode.\n */\n if (bitState & Keyboard.STATE.ALL_MODIFIERS) bitState = Keyboard.STATE.ALL_MODIFIERS;\n }\n if (!fSim) {\n this.bitsState &= ~bitState;\n if (fDown) this.bitsState |= bitState;\n } else {\n /*\n * This next line reflects the fact that we don't want to modify any simulated LOCK states if a simulated\n * shift state (ie, CTRL, ALT, SHIFT, etc) is also active. For example, CTRL-NUM-LOCK is a special sequence\n * (Pause) that isn't supposed to alter the NUM-LOCK state; similarly, CTRL-SCROLL-LOCK (aka Ctrl-Break)\n * isn't supposed to alter the SCROLL-LOCK state.\n */\n if (!(this.bitsStateSim & Keyboard.STATE.ALL_MODIFIERS) || !(bitState & Keyboard.STATE.ALL_LOCKS)) {\n this.bitsStateSim &= ~bitState;\n if (fDown) this.bitsStateSim |= bitState;\n this.updateLEDs(bitState);\n }\n }\n result = fDown? 1 : -1;\n }\n }\n return result;\n }\n\n /**\n * addActiveKey(simCode, fPress)\n *\n * @this {Keyboard}\n * @param {number} simCode\n * @param {boolean} [fPress]\n * @return {boolean} true if added, false if not (eg, not recognized, already added, etc)\n */\n addActiveKey(simCode, fPress)\n {\n var wCode = Keyboard.SIMCODES[simCode] || Keyboard.SIMCODES[simCode += Keys.KEYCODE.ONDOWN];\n\n if (!wCode) {\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.KEY)) {\n this.printMessage(\"addActiveKey(\" + simCode + \",\" + (fPress? \"press\" : \"down\") + \"): unrecognized\", true);\n }\n return false;\n }\n\n /*\n * Ignore all active keys if the CPU is not running.\n */\n if (!this.cpu || !this.cpu.isRunning()) return false;\n\n /*\n * If this simCode is in the KEYSTATE table, then stop all repeating.\n */\n if (Keyboard.KEYSTATES[simCode] && this.aKeysActive.length) {\n if (this.aKeysActive[0].nRepeat > 0) this.aKeysActive[0].nRepeat = 0;\n }\n\n var key;\n for (var i = 0; i < this.aKeysActive.length; i++) {\n key = this.aKeysActive[i];\n if (key.simCode == simCode) {\n /*\n * This key is already active, so if this a \"down\" request (or a \"press\" for a key we already\n * processed as a \"down\"), ignore it.\n */\n if (!fPress || key.nRepeat >= 0) {\n i = -1;\n break;\n }\n if (i > 0) {\n if (this.aKeysActive[0].nRepeat > 0) this.aKeysActive[0].nRepeat = 0;\n this.aKeysActive.splice(i, 1);\n }\n break;\n }\n }\n\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.KEY)) {\n this.printMessage(\"addActiveKey(\" + simCode + \",\" + (fPress? \"press\" : \"down\") + \"): \" + (i < 0? \"already active\" : (i == this.aKeysActive.length? \"adding\" : \"updating\")), true);\n }\n\n if (i < 0) return false;\n\n if (i == this.aKeysActive.length) {\n key = {simCode}; // create a new Key object\n // key.bitsState = this.bitsState; // not needed unless we revive checkActiveKeyShift()\n this.findBinding(simCode, \"key\", true);\n i++;\n }\n \n if (i > 0) {\n this.aKeysActive.splice(0, 0, key); // aka aKeysActive.unshift(key)\n }\n\n key.fDown = true;\n key.nRepeat = (fPress? -1: (Keyboard.KEYSTATES[simCode]? 0 : 1));\n\n this.updateActiveKey(key);\n return true;\n }\n\n /**\n * checkActiveKey()\n *\n * @this {Keyboard}\n * @return {number} simCode of active key, 0 if none\n */\n checkActiveKey()\n {\n return this.aKeysActive.length? this.aKeysActive[0].simCode : 0;\n }\n\n /**\n * isAlphaKey(code)\n *\n * @this {Keyboard}\n * @param {number} code\n * @returns {boolean} true if alpha key, false if not\n */\n isAlphaKey(code)\n {\n return (code >= Keys.ASCII.A && code <= Keys.ASCII.Z || code >= Keys.ASCII.a && code <= Keys.ASCII.z);\n }\n\n /**\n * toUpperKey(code)\n *\n * @this {Keyboard}\n * @param {number} code\n * @returns {number}\n */\n toUpperKey(code)\n {\n if (code >= Keys.ASCII.a && code <= Keys.ASCII.z) {\n code -= (Keys.ASCII.a - Keys.ASCII.A);\n }\n return code;\n }\n\n /**\n * clearActiveKeys(fModifiers)\n *\n * Force all active keys to \"deactivate\" (or, optionally, just any modifiers)\n *\n * @this {Keyboard}\n * @param {boolean} [fModifiers] (true to clear modifier keys only; default is ALL keys)\n */\n clearActiveKeys(fModifiers)\n {\n for (var i = 0; i < this.aKeysActive.length; i++) {\n var key = this.aKeysActive[i];\n if (fModifiers && !Keyboard.MODIFIERS[key.simCode]) continue;\n if (this.removeActiveKey(key.simCode)) i--;\n }\n }\n\n /**\n * removeActiveKey(simCode, fFlush)\n *\n * @param {number} simCode\n * @param {boolean} [fFlush] is true whenever the key must be removed, independent of other factors\n * @return {boolean} true if successfully removed, false if not\n */\n removeActiveKey(simCode, fFlush)\n {\n if (!Keyboard.SIMCODES[simCode]) {\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.KEY)) {\n this.printMessage(\"removeActiveKey(\" + simCode + \"): unrecognized\", true);\n }\n return false;\n }\n\n /*\n * Ignore all active keys if the CPU is not running.\n */\n if (!fFlush && (!this.cpu || !this.cpu.isRunning())) return false;\n\n var fRemoved = false;\n for (var i = 0; i < this.aKeysActive.length; i++) {\n var key = this.aKeysActive[i];\n if (key.simCode == simCode || key.simCode == Keys.SHIFTED_KEYCODES[simCode]) {\n this.aKeysActive.splice(i, 1);\n if (key.timer) clearTimeout(key.timer);\n if (key.fDown && !fFlush) this.keySimulate(key.simCode, false);\n this.findBinding(simCode, \"key\", false);\n fRemoved = true;\n break;\n }\n }\n if (!COMPILED && !fFlush && this.messageEnabled(Messages.KBD | Messages.KEY)) {\n this.printMessage(\"removeActiveKey(\" + simCode + \"): \" + (fRemoved? \"removed\" : \"not active\"), true);\n }\n if (!this.aKeysActive.length && this.fToggleCapsLock) {\n if (!COMPILED) this.printMessage(\"removeActiveKey(): inverting caps-lock now\", Messages.KBD | Messages.KEY);\n this.updateShiftState(Keyboard.SIMCODE.CAPS_LOCK);\n this.fToggleCapsLock = false;\n }\n return fRemoved;\n }\n\n /**\n * updateActiveKey(key, msTimer)\n *\n * When called by addActiveKey(), msTimer is undefined; that's used only when we're called by our own timeout handler.\n *\n * @param {Object} key\n * @param {number} [msTimer]\n */\n updateActiveKey(key, msTimer)\n {\n /*\n * All active keys are automatically removed once the CPU stops running.\n */\n if (!this.cpu || !this.cpu.isRunning()) {\n this.removeActiveKey(key.simCode, true);\n return;\n }\n\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.KEY)) {\n this.printMessage(\"updateActiveKey(\" + key.simCode + (msTimer? \",\" + msTimer + \"ms\" : \"\") + \"): \" + (key.fDown? \"down\" : \"up\"), true);\n }\n\n if (msTimer && key.nRepeat < 0) {\n key.fDown = false;\n }\n \n if (!this.keySimulate(key.simCode, key.fDown) || !key.nRepeat) {\n /*\n * Why isn't there a simple return here? In order to set breakpoints on two different return conditions, of course!\n */\n if (!msTimer) {\n return;\n }\n return;\n }\n\n var ms;\n if (key.nRepeat < 0) {\n if (!key.fDown) {\n this.removeActiveKey(key.simCode);\n return;\n }\n ms = this.msAutoRelease;\n }\n else {\n ms = (key.nRepeat++ == 1? this.msAutoRepeat : this.msNextRepeat);\n }\n \n if (key.timer) {\n clearTimeout(key.timer);\n }\n \n key.timer = setTimeout(function(kbd) {\n return function onUpdateActiveKey() {\n kbd.updateActiveKey(key, ms);\n };\n }(this), ms);\n }\n\n /**\n * getSimCode(keyCode)\n *\n * @this {Keyboard}\n * @param {number} keyCode\n * @param {boolean} fShifted\n * @return {number} simCode\n */\n getSimCode(keyCode, fShifted)\n {\n var code;\n var simCode = keyCode;\n\n if (keyCode >= Keys.ASCII.A && keyCode <= Keys.ASCII.Z) {\n if (!(this.bitsState & (Keyboard.STATE.SHIFT | Keyboard.STATE.RSHIFT | Keyboard.STATE.CAPS_LOCK)) == fShifted) {\n simCode = keyCode + (Keys.ASCII.a - Keys.ASCII.A);\n }\n }\n else if (keyCode >= Keys.ASCII.a && keyCode <= Keys.ASCII.z) {\n if (!!(this.bitsState & (Keyboard.STATE.SHIFT | Keyboard.STATE.RSHIFT | Keyboard.STATE.CAPS_LOCK)) == fShifted) {\n simCode = keyCode - (Keys.ASCII.a - Keys.ASCII.A);\n }\n }\n else if (!!(this.bitsState & (Keyboard.STATE.SHIFT | Keyboard.STATE.RSHIFT)) == fShifted) {\n if (code = Keys.SHIFTED_KEYCODES[keyCode]) {\n simCode = code;\n }\n }\n else {\n if (code = Keys.NONASCII_KEYCODES[keyCode]) {\n simCode = code;\n }\n }\n return simCode;\n }\n\n /**\n * onFocusChange(fFocus)\n *\n * @this {Keyboard}\n * @param {boolean} fFocus is true if gaining focus, false if losing it\n */\n onFocusChange(fFocus)\n {\n if (!COMPILED && this.fHasFocus != fFocus && this.messageEnabled(Messages.EVENT)) {\n this.printMessage(\"onFocusChange(\" + (fFocus? \"true\" : \"false\") + \")\", true);\n }\n this.fHasFocus = fFocus;\n /*\n * Since we can't be sure of any shift states after losing focus, we clear them all.\n */\n if (!fFocus) {\n this.bitsState &= ~Keyboard.STATE.ALL_MODIFIERS;\n this.clearActiveKeys(true);\n }\n }\n\n /**\n * onKeyChange(event, fDown)\n *\n * @this {Keyboard}\n * @param {Object} event\n * @param {boolean} fDown is true for a keyDown event, false for a keyUp event\n * @return {boolean} true to pass the event along, false to consume it\n */\n onKeyChange(event, fDown)\n {\n var fPass = true;\n var fPress = false;\n var fIgnore = false;\n var keyCode = event.keyCode;\n\n if (!this.cmp.notifyKbdEvent(event, fDown)) {\n return false;\n }\n \n if (fDown) this.cKeysPressed++;\n this.sInjectBuffer = \"\"; // actual key events should stop any injection in progress\n Component.processScript(this.idMachine); // and any script, too\n\n /*\n * Although it would be nice to pay attention ONLY to these \"up\" and \"down\" events, and ignore \"press\"\n * events, iOS devices force us to process \"press\" events, because they don't give us shift-key events,\n * so we have to infer the shift state from the character code in the \"press\" event.\n *\n * So, to seamlessly blend \"up\" and \"down\" events with \"press\" events, we must convert any keyCodes we\n * receive here to a compatibly shifted simCode.\n */\n var simCode = this.getSimCode(keyCode, true);\n\n if (this.fEscapeDisabled && simCode == Keys.ASCII['`']) {\n keyCode = simCode = Keys.KEYCODE.ESC;\n }\n\n if (Keyboard.SIMCODES[keyCode + Keys.KEYCODE.ONDOWN]) {\n\n simCode += Keys.KEYCODE.ONDOWN;\n if (event.location == Keys.LOCATION.RIGHT) {\n simCode += Keys.KEYCODE.ONRIGHT;\n }\n\n var nShiftState = this.updateShiftState(simCode, false, fDown);\n if (nShiftState) {\n\n if (keyCode == Keys.KEYCODE.CAPS_LOCK || keyCode == Keys.KEYCODE.NUM_LOCK || keyCode == Keys.KEYCODE.SCROLL_LOCK) {\n /*\n * FYI, \"lock\" keys generate a DOWN event ONLY when getting locked and an UP event ONLY\n * when getting unlocked--which is a little odd, since the key did go UP and DOWN each time.\n *\n * We must treat each event like a \"down\", and also as a \"press\", so that addActiveKey() will\n * automatically generate both the \"make\" and \"break\".\n *\n * Of course, there have to be exceptions, most notably both Microsoft Internet Explorer and Edge\n * (and, apparently, pretty much any other browser running on the Windows platform), which send both\n * UP and DOWN events on every press, so there's no need for this trickery.\n */\n if (!this.fMSWindows) {\n fDown = fPress = true;\n }\n }\n \n /*\n * HACK for Windows (as the host operating system): the ALT key is often used with key combinations\n * not meant for our machine (eg, Alt-Tab to switch to a different window, or simply tapping the ALT\n * key by itself to switch focus to the browser's menubar). And sadly, browsers are quite happy to\n * give us the DOWN event for the ALT key, but not an UP event, leaving our machine with the impression\n * that the ALT key is still down, which the user user has no easy way to detect OR correct.\n * \n * So we still record the ALT state in bitsState as best we can, and clear it whenever we lose focus\n * in onFocusChange(), but we no longer pass through DOWN events to our machine. Instead, we now\n * check bitsState prior to simulating any other key, and if the ALT bit is set, we simulate an\n * active ALT key first; you'll find that check at the end of both onKeyChange() and onKeyPress().\n * \n * NOTE: Even though this is a hack intended largely for browsers running on Windows, I'm implementing\n * it for all platforms, for consistency.\n */\n if (keyCode == Keys.KEYCODE.ALT) {\n if (fDown) {\n /*\n * One exception to this hack is the \"Sidekick\" exception: if the CTRL key is also down,\n * we'll still simulate ALT immediately, for those users who press CTRL and then ALT to pop up\n * Sidekick (as opposed to pressing ALT and then CTRL, which should also work, regardless).\n */\n if (!(this.bitsState & Keyboard.STATE.CTRL)) fIgnore = true;\n /*\n * Reset cKeysPressed so that we can detect the mere \"tapping\" of the ALT key, which some PCjs\n * demos depend on (eg, Multi-tasking MS-DOS 4.0).\n */\n this.cKeysPressed = 0;\n }\n else {\n if (!this.cKeysPressed) {\n /*\n * Since cKeysPressed is zero, the assumption here is that the ALT key (and the Alt key ALONE)\n * was just tapped, so as long the ALT key was not already \"soft-locked\" (based on bitsStateSim),\n * we will transform this \"up\" event into a \"fake press\" event. \n */\n if (!(this.bitsStateSim & (Keyboard.STATE.ALT | Keyboard.STATE.RALT))) {\n fDown = fPress = true;\n }\n }\n }\n }\n \n /*\n * As a safeguard, whenever the CMD key goes up, clear all active keys, because there appear to be\n * cases where we don't always get notification of a CMD key's companion key going up (this probably\n * overlaps with most if not all situations where we also lose focus).\n */\n if (!fDown && (keyCode == Keys.KEYCODE.CMD || keyCode == Keys.KEYCODE.RCMD)) {\n this.clearActiveKeys();\n }\n }\n else {\n /*\n * Here we have all the non-shift keys in the ONDOWN category; eg, BS, TAB, ESC, UP, DOWN, LEFT, RIGHT,\n * and many more.\n *\n * For various reasons (some of which are discussed below), we don't want to pass these on (ie, we want\n * to suppress their \"press\" event), which means we must perform all key simulation on the \"up\" and \"down\"\n * events.\n *\n * Regarding BS: I never want the browser to act on BS, since it does double-duty as the BACK button,\n * leaving the current page.\n *\n * Regarding TAB: If I don't consume TAB on the \"down\" event, then that's all I'll see, because the browser\n * acts on it by giving focus to the next control.\n *\n * Regarding ESC: This key generates \"down\" and \"up\" events (LOTS of \"down\" events for that matter), but no\n * \"press\" event.\n */\n\n /*\n * HACKs for mapping CTRL-BACKSPACE and CTRL-ALT-BACKSPACE to CTRL-BREAK and CTRL-ALT-DEL, respectively.\n */\n if (keyCode == Keys.KEYCODE.BS && (this.bitsState & (Keyboard.STATE.CTRL|Keyboard.STATE.ALT)) == Keyboard.STATE.CTRL) {\n simCode = Keyboard.SIMCODE.CTRL_BREAK;\n }\n if (keyCode == Keys.KEYCODE.BS && (this.bitsState & (Keyboard.STATE.CTRL|Keyboard.STATE.ALT)) == (Keyboard.STATE.CTRL|Keyboard.STATE.ALT)) {\n simCode = Keyboard.SIMCODE.CTRL_ALT_DEL;\n }\n\n /*\n * There are a number of other common key sequences that interfere with our machines; for example,\n * the up/down arrows have a \"default\" behavior of scrolling the web page up and down, which is\n * definitely NOT a behavior we want. Since we mark those keys as ONDOWN, we'll catch them all here.\n */\n fPass = false;\n }\n }\n else {\n /*\n * HACKs for mapping assorted CTRL-ALT sequences involving \"normal\" keys (eg, PERIOD, EQUALS, and DASH).\n */\n if ((this.bitsState & (Keyboard.STATE.CTRL|Keyboard.STATE.ALT)) == (Keyboard.STATE.CTRL|Keyboard.STATE.ALT)) {\n if (keyCode == Keys.KEYCODE.PERIOD) {\n simCode = Keyboard.SIMCODE.CTRL_ALT_DEL; // in case your operating system won't let you type CTRL-ALT-BACKSPACE either\n }\n if (keyCode == Keys.KEYCODE.EQUALS) {\n simCode = Keyboard.SIMCODE.CTRL_ALT_ADD; // in case your keyboard doesn't have a numeric keypad '+'\n }\n else if (keyCode == Keys.KEYCODE.DASH) {\n simCode = Keyboard.SIMCODE.CTRL_ALT_SUB; // in case your keyboard doesn't have a numeric keypad '-'\n }\n }\n \n /*\n * When I have defined system-wide CTRL-key sequences to perform common editing operations (eg, CTRL_W\n * and CTRL_Z to scroll pages of text), the browser likes to act on those operations, so let's set fPass\n * to false to prevent that.\n *\n * Also, we don't want to set fIgnore in such cases, because the browser may not give us a press event for\n * these CTRL-key sequences, so we can't risk ignoring them.\n */\n if (Keyboard.SIMCODES[simCode] && (this.bitsState & (Keyboard.STATE.CTRLS | Keyboard.STATE.ALTS))) {\n fPass = false;\n }\n\n /*\n * Don't simulate any key not explicitly marked ONDOWN, as well as any key sequence with the CMD key held.\n */\n if (!this.fAllDown && fPass && fDown || (this.bitsState & Keyboard.STATE.CMDS)) {\n fIgnore = true;\n }\n }\n\n if (!fPass) {\n event.preventDefault();\n }\n\n if (this.messageEnabled(Messages.EVENT | Messages.KEY)) {\n this.printMessage(\"onKeyChange(\" + keyCode + \"): \" + (fDown? \"down\" : \"up\") + (fIgnore? \",ignore\" : (fPass? \"\" : \",consume\")), true);\n }\n\n /*\n * Mobile (eg, iOS) keyboards don't fully support onkeydown/onkeyup events; for example, they usually\n * don't generate ANY events when a shift key is pressed, and even for normal keys, they seem to generate\n * rapid (ie, fake) \"up\" and \"down\" events around \"press\" events, probably more to satisfy compatibility\n * issues rather than making a serious effort to indicate when a key ACTUALLY went down or up.\n */\n if (!fIgnore && (!this.fMobile || !fPass)) {\n if (fDown) {\n /*\n * This is the companion code to the onKeyChange() hack for Windows that suppresses DOWN events\n * for ALT keys: if we're about to activate another key and we believe that an ALT key is still down,\n * we fake an ALT activation first. \n */\n if (this.bitsState & Keyboard.STATE.ALTS) {\n var simCodeAlt = Keyboard.SIMCODE.ALT;\n this.printMessage(\"onKeyChange(\" + simCodeAlt + \"): simulating ALT down\", Messages.EVENT);\n this.addActiveKey(simCodeAlt);\n }\n this.addActiveKey(simCode, fPress);\n } else {\n if (!this.removeActiveKey(simCode)) {\n var code = this.getSimCode(keyCode, false);\n if (code != simCode) this.removeActiveKey(code);\n }\n }\n }\n\n return fPass;\n }\n\n /**\n * onKeyPress(event)\n *\n * @this {Keyboard}\n * @param {Object} event\n * @return {boolean} true to pass the event along, false to consume it\n */\n onKeyPress(event)\n {\n event = event || window.event;\n var keyCode = event.which || event.keyCode;\n\n if (!this.cmp.notifyKbdEvent(event)) {\n return false;\n }\n\n this.cKeysPressed++;\n this.sInjectBuffer = \"\"; // actual key events should stop any injection currently in progress\n\n if (this.fAllDown) {\n var simCode = this.checkActiveKey();\n if (simCode && this.isAlphaKey(simCode) && this.isAlphaKey(keyCode) && simCode != keyCode) {\n if (!COMPILED && this.messageEnabled(Messages.EVENT | Messages.KEY)) {\n this.printMessage(\"onKeyPress(\" + keyCode + \") out of sync with \" + simCode + \", invert caps-lock\", true);\n }\n this.fToggleCapsLock = true;\n keyCode = simCode;\n }\n }\n\n var fPass = !Keyboard.SIMCODES[keyCode] || !!(this.bitsState & Keyboard.STATE.CMD);\n\n if (this.messageEnabled(Messages.EVENT | Messages.KEY)) {\n this.printMessage(\"onKeyPress(\" + keyCode + \"): \" + (fPass? \"true\" : \"false\"), true);\n }\n\n if (!fPass) {\n /*\n * This is the companion code to the onKeyChange() hack for Windows that suppresses DOWN events\n * for ALT keys: if we're about to activate another key and we believe that an ALT key is still down,\n * we fake an ALT activation first.\n */\n if (this.bitsState & Keyboard.STATE.ALTS) {\n var simCodeAlt = Keyboard.SIMCODE.ALT;\n this.printMessage(\"onKeyPress(\" + simCodeAlt + \"): simulating ALT down\", Messages.EVENT);\n this.addActiveKey(simCodeAlt);\n }\n this.addActiveKey(keyCode, true);\n }\n\n return fPass;\n }\n\n /**\n * keySimulate(simCode, fDown)\n *\n * @this {Keyboard}\n * @param {number} simCode\n * @param {boolean} fDown\n * @return {boolean} true if successfully simulated, false if unrecognized/unsupported key\n */\n keySimulate(simCode, fDown)\n {\n var fSimulated = false;\n\n this.updateShiftState(simCode, true, fDown);\n\n var wCode = Keyboard.SIMCODES[simCode] || Keyboard.SIMCODES[simCode + Keys.KEYCODE.ONDOWN];\n\n if (wCode !== undefined) {\n\n var abScanCodes = [];\n var bCode = wCode & 0xff;\n\n /*\n * TODO: Update the following restrictions to address 84-key and 101-key keyboard limitations.\n */\n if (bCode > 83 && this.modelKeys == 83) {\n return false;\n }\n\n abScanCodes.push(bCode | (fDown? 0 : Keyboard.SCANCODE.BREAK));\n\n var fAlpha = (simCode >= Keys.ASCII.A && simCode <= Keys.ASCII.Z || simCode >= Keys.ASCII.a && simCode <= Keys.ASCII.z);\n\n while (wCode >>>= 8) {\n var bShift = 0;\n var bScan = wCode & 0xff;\n /*\n * TODO: The handling of SIMCODE entries with \"extended\" codes still needs to be tested, and\n * moreover, if any of them need to perform any shift-state modifications, those modifications\n * may need to be encoded differently.\n */\n if (bCode == Keyboard.SCANCODE.EXTEND1 || bCode == Keyboard.SCANCODE.EXTEND2) {\n abScanCodes.push(bCode | (fDown? 0 : Keyboard.SCANCODE.BREAK));\n continue;\n }\n if (bScan == Keyboard.SCANCODE.SHIFT) {\n if (!(this.bitsStateSim & (Keyboard.STATE.SHIFT | Keyboard.STATE.RSHIFT))) {\n if (!(this.bitsStateSim & Keyboard.STATE.CAPS_LOCK) || !fAlpha) {\n bShift = bScan;\n }\n }\n } else if (bScan == Keyboard.SCANCODE.CTRL) {\n if (!(this.bitsStateSim & (Keyboard.STATE.CTRL | Keyboard.STATE.RCTRL))) {\n bShift = bScan;\n }\n } else if (bScan == Keyboard.SCANCODE.ALT) {\n if (!(this.bitsStateSim & (Keyboard.STATE.ALT | Keyboard.STATE.RALT))) {\n bShift = bScan;\n }\n } else {\n abScanCodes.push(bCode | (fDown? 0 : Keyboard.SCANCODE.BREAK));\n\n }\n if (bShift) {\n if (fDown)\n abScanCodes.unshift(bShift);\n else\n abScanCodes.push(bShift | Keyboard.SCANCODE.BREAK);\n }\n }\n\n for (var i = 0; i < abScanCodes.length; i++) {\n this.addScanCode(abScanCodes[i]);\n }\n\n fSimulated = true;\n }\n\n if (!COMPILED && this.messageEnabled(Messages.KBD | Messages.KEY)) {\n this.printMessage(\"keySimulate(\" + simCode + \",\" + (fDown? \"down\" : \"up\") + \"): \" + (fSimulated? \"true\" : \"false\"), true);\n }\n\n return fSimulated;\n }\n\n /**\n * checkActiveKeyShift()\n *\n * @this {Keyboard}\n * @return {number|null} bitsState for active key, null if none\n *\n checkActiveKeyShift()\n {\n return this.aKeysActive.length? this.aKeysActive[0].bitsState : null;\n }\n */\n\n /**\n * Keyboard.init()\n *\n * This function operates on every HTML element of class \"keyboard\", extracting the\n * JSON-encoded parameters for the Keyboard constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Keyboard component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeKbd = Component.getElementsByClass(document, PCX86.APPCLASS, \"keyboard\");\n for (var iKbd = 0; iKbd < aeKbd.length; iKbd++) {\n var eKbd = aeKbd[iKbd];\n var parmsKbd = Component.getComponentParms(eKbd);\n var kbd = new Keyboard(parmsKbd);\n Component.bindComponentControls(kbd, eKbd, PCX86.APPCLASS);\n }\n }\n}\n\n/*\n * Supported keyboard models (the first entry is the default if the specified model isn't recognized)\n */\nKeyboard.MODELS = [\"US83\", \"US84\", \"US101\"];\n\nKeyboard.SIMCODE = {\n BS: Keys.KEYCODE.BS + Keys.KEYCODE.ONDOWN,\n TAB: Keys.KEYCODE.TAB + Keys.KEYCODE.ONDOWN,\n SHIFT: Keys.KEYCODE.SHIFT + Keys.KEYCODE.ONDOWN,\n RSHIFT: Keys.KEYCODE.SHIFT + Keys.KEYCODE.ONDOWN + Keys.KEYCODE.ONRIGHT,\n CTRL: Keys.KEYCODE.CTRL + Keys.KEYCODE.ONDOWN,\n ALT: Keys.KEYCODE.ALT + Keys.KEYCODE.ONDOWN,\n RALT: Keys.KEYCODE.ALT + Keys.KEYCODE.ONDOWN + Keys.KEYCODE.ONRIGHT,\n CAPS_LOCK: Keys.KEYCODE.CAPS_LOCK + Keys.KEYCODE.ONDOWN,\n ESC: Keys.KEYCODE.ESC + Keys.KEYCODE.ONDOWN,\n /*\n * It seems that a recent change to Safari on iOS (first noticed in iOS 9.1) treats SPACE\n * differently now, at least with regard to <textarea> controls, and possibly only readonly\n * or hidden controls, like the hidden <textarea> we overlay on the Video <canvas> element.\n *\n * Whatever the exact criteria are, Safari on iOS now performs SPACE's default behavior\n * after the onkeydown event but before the onkeypress event. So we must now process SPACE\n * as an ONDOWN key, so that we can call preventDefault() and properly simulate the key at\n * the time the key goes down.\n */\n SPACE: Keys.KEYCODE.SPACE + Keys.KEYCODE.ONDOWN,\n F1: Keys.KEYCODE.F1 + Keys.KEYCODE.ONDOWN,\n F2: Keys.KEYCODE.F2 + Keys.KEYCODE.ONDOWN,\n F3: Keys.KEYCODE.F3 + Keys.KEYCODE.ONDOWN,\n F4: Keys.KEYCODE.F4 + Keys.KEYCODE.ONDOWN,\n F5: Keys.KEYCODE.F5 + Keys.KEYCODE.ONDOWN,\n F6: Keys.KEYCODE.F6 + Keys.KEYCODE.ONDOWN,\n F7: Keys.KEYCODE.F7 + Keys.KEYCODE.ONDOWN,\n F8: Keys.KEYCODE.F8 + Keys.KEYCODE.ONDOWN,\n F9: Keys.KEYCODE.F9 + Keys.KEYCODE.ONDOWN,\n F10: Keys.KEYCODE.F10 + Keys.KEYCODE.ONDOWN,\n F11: Keys.KEYCODE.F11 + Keys.KEYCODE.ONDOWN,\n F12: Keys.KEYCODE.F12 + Keys.KEYCODE.ONDOWN,\n NUM_LOCK: Keys.KEYCODE.NUM_LOCK + Keys.KEYCODE.ONDOWN,\n SCROLL_LOCK: Keys.KEYCODE.SCROLL_LOCK + Keys.KEYCODE.ONDOWN,\n PRTSC: Keys.KEYCODE.PRTSC + Keys.KEYCODE.ONDOWN,\n HOME: Keys.KEYCODE.HOME + Keys.KEYCODE.ONDOWN,\n UP: Keys.KEYCODE.UP + Keys.KEYCODE.ONDOWN,\n PGUP: Keys.KEYCODE.PGUP + Keys.KEYCODE.ONDOWN,\n LEFT: Keys.KEYCODE.LEFT + Keys.KEYCODE.ONDOWN,\n NUM_INS: Keys.KEYCODE.NUM_INS + Keys.KEYCODE.ONDOWN,\n NUM_END: Keys.KEYCODE.NUM_END + Keys.KEYCODE.ONDOWN,\n NUM_DOWN: Keys.KEYCODE.NUM_DOWN + Keys.KEYCODE.ONDOWN,\n NUM_PGDN: Keys.KEYCODE.NUM_PGDN + Keys.KEYCODE.ONDOWN,\n NUM_LEFT: Keys.KEYCODE.NUM_LEFT + Keys.KEYCODE.ONDOWN,\n NUM_CENTER: Keys.KEYCODE.NUM_CENTER + Keys.KEYCODE.ONDOWN,\n NUM_RIGHT: Keys.KEYCODE.NUM_RIGHT + Keys.KEYCODE.ONDOWN,\n NUM_HOME: Keys.KEYCODE.NUM_HOME + Keys.KEYCODE.ONDOWN,\n NUM_UP: Keys.KEYCODE.NUM_UP + Keys.KEYCODE.ONDOWN,\n NUM_PGUP: Keys.KEYCODE.NUM_PGUP + Keys.KEYCODE.ONDOWN,\n NUM_ADD: Keys.KEYCODE.NUM_ADD + Keys.KEYCODE.ONDOWN,\n NUM_SUB: Keys.KEYCODE.NUM_SUB + Keys.KEYCODE.ONDOWN,\n NUM_DEL: Keys.KEYCODE.NUM_DEL + Keys.KEYCODE.ONDOWN,\n RIGHT: Keys.KEYCODE.RIGHT + Keys.KEYCODE.ONDOWN,\n END: Keys.KEYCODE.END + Keys.KEYCODE.ONDOWN,\n DOWN: Keys.KEYCODE.DOWN + Keys.KEYCODE.ONDOWN,\n PGDN: Keys.KEYCODE.PGDN + Keys.KEYCODE.ONDOWN,\n INS: Keys.KEYCODE.INS + Keys.KEYCODE.ONDOWN,\n DEL: Keys.KEYCODE.DEL + Keys.KEYCODE.ONDOWN,\n CMD: Keys.KEYCODE.CMD + Keys.KEYCODE.ONDOWN,\n RCMD: Keys.KEYCODE.RCMD + Keys.KEYCODE.ONDOWN,\n FF_CMD: Keys.KEYCODE.FF_CMD + Keys.KEYCODE.ONDOWN,\n CTRL_A: Keys.ASCII.CTRL_A + Keys.KEYCODE.FAKE,\n CTRL_B: Keys.ASCII.CTRL_B + Keys.KEYCODE.FAKE,\n CTRL_C: Keys.ASCII.CTRL_C + Keys.KEYCODE.FAKE,\n CTRL_D: Keys.ASCII.CTRL_D + Keys.KEYCODE.FAKE,\n CTRL_E: Keys.ASCII.CTRL_E + Keys.KEYCODE.FAKE,\n CTRL_F: Keys.ASCII.CTRL_F + Keys.KEYCODE.FAKE,\n CTRL_G: Keys.ASCII.CTRL_G + Keys.KEYCODE.FAKE,\n CTRL_H: Keys.ASCII.CTRL_H + Keys.KEYCODE.FAKE,\n CTRL_I: Keys.ASCII.CTRL_I + Keys.KEYCODE.FAKE,\n CTRL_J: Keys.ASCII.CTRL_J + Keys.KEYCODE.FAKE,\n CTRL_K: Keys.ASCII.CTRL_K + Keys.KEYCODE.FAKE,\n CTRL_L: Keys.ASCII.CTRL_L + Keys.KEYCODE.FAKE,\n CTRL_M: Keys.ASCII.CTRL_M + Keys.KEYCODE.FAKE,\n CTRL_N: Keys.ASCII.CTRL_N + Keys.KEYCODE.FAKE,\n CTRL_O: Keys.ASCII.CTRL_O + Keys.KEYCODE.FAKE,\n CTRL_P: Keys.ASCII.CTRL_P + Keys.KEYCODE.FAKE,\n CTRL_Q: Keys.ASCII.CTRL_Q + Keys.KEYCODE.FAKE,\n CTRL_R: Keys.ASCII.CTRL_R + Keys.KEYCODE.FAKE,\n CTRL_S: Keys.ASCII.CTRL_S + Keys.KEYCODE.FAKE,\n CTRL_T: Keys.ASCII.CTRL_T + Keys.KEYCODE.FAKE,\n CTRL_U: Keys.ASCII.CTRL_U + Keys.KEYCODE.FAKE,\n CTRL_V: Keys.ASCII.CTRL_V + Keys.KEYCODE.FAKE,\n CTRL_W: Keys.ASCII.CTRL_W + Keys.KEYCODE.FAKE,\n CTRL_X: Keys.ASCII.CTRL_X + Keys.KEYCODE.FAKE,\n CTRL_Y: Keys.ASCII.CTRL_Y + Keys.KEYCODE.FAKE,\n CTRL_Z: Keys.ASCII.CTRL_Z + Keys.KEYCODE.FAKE,\n SYS_REQ: Keys.KEYCODE.ESC + Keys.KEYCODE.FAKE,\n CTRL_PAUSE: Keys.KEYCODE.NUM_LOCK + Keys.KEYCODE.FAKE,\n CTRL_BREAK: Keys.KEYCODE.SCROLL_LOCK + Keys.KEYCODE.FAKE,\n CTRL_ALT_DEL: Keys.KEYCODE.DEL + Keys.KEYCODE.FAKE,\n CTRL_ALT_INS: Keys.KEYCODE.INS + Keys.KEYCODE.FAKE,\n CTRL_ALT_ADD: Keys.KEYCODE.NUM_ADD + Keys.KEYCODE.FAKE,\n CTRL_ALT_SUB: Keys.KEYCODE.NUM_SUB + Keys.KEYCODE.FAKE,\n CTRL_ALT_ENTER: Keys.KEYCODE.NUM_CR + Keys.KEYCODE.FAKE\n};\n\n/*\n * Scan code constants\n */\nKeyboard.SCANCODE = {\n /* 0x01 */ ESC: 1,\n /* 0x02 */ ONE: 2,\n /* 0x03 */ TWO: 3,\n /* 0x04 */ THREE: 4,\n /* 0x05 */ FOUR: 5,\n /* 0x06 */ FIVE: 6,\n /* 0x07 */ SIX: 7,\n /* 0x08 */ SEVEN: 8,\n /* 0x09 */ EIGHT: 9,\n /* 0x0A */ NINE: 10,\n /* 0x0B */ ZERO: 11,\n /* 0x0C */ DASH: 12,\n /* 0x0D */ EQUALS: 13,\n /* 0x0E */ BS: 14,\n /* 0x0F */ TAB: 15,\n /* 0x10 */ Q: 16,\n /* 0x11 */ W: 17,\n /* 0x12 */ E: 18,\n /* 0x13 */ R: 19,\n /* 0x14 */ T: 20,\n /* 0x15 */ Y: 21,\n /* 0x16 */ U: 22,\n /* 0x17 */ I: 23,\n /* 0x18 */ O: 24,\n /* 0x19 */ P: 25,\n /* 0x1A */ LBRACK: 26,\n /* 0x1B */ RBRACK: 27,\n /* 0x1C */ ENTER: 28,\n /* 0x1D */ CTRL: 29,\n /* 0x1E */ A: 30,\n /* 0x1F */ S: 31,\n /* 0x20 */ D: 32,\n /* 0x21 */ F: 33,\n /* 0x22 */ G: 34,\n /* 0x23 */ H: 35,\n /* 0x24 */ J: 36,\n /* 0x25 */ K: 37,\n /* 0x26 */ L: 38,\n /* 0x27 */ SEMI: 39,\n /* 0x28 */ QUOTE: 40,\n /* 0x29 */ BQUOTE: 41,\n /* 0x2A */ SHIFT: 42,\n /* 0x2B */ BSLASH: 43,\n /* 0x2C */ Z: 44,\n /* 0x2D */ X: 45,\n /* 0x2E */ C: 46,\n /* 0x2F */ V: 47,\n /* 0x30 */ B: 48,\n /* 0x31 */ N: 49,\n /* 0x32 */ M: 50,\n /* 0x33 */ COMMA: 51,\n /* 0x34 */ PERIOD: 52,\n /* 0x35 */ SLASH: 53,\n /* 0x36 */ RSHIFT: 54,\n /* 0x37 */ PRTSC: 55, // unshifted '*'; becomes dedicated 'Print Screen' key on 101-key keyboards\n /* 0x38 */ ALT: 56,\n /* 0x39 */ SPACE: 57,\n /* 0x3A */ CAPS_LOCK: 58,\n /* 0x3B */ F1: 59,\n /* 0x3C */ F2: 60,\n /* 0x3D */ F3: 61,\n /* 0x3E */ F4: 62,\n /* 0x3F */ F5: 63,\n /* 0x40 */ F6: 64,\n /* 0x41 */ F7: 65,\n /* 0x42 */ F8: 66,\n /* 0x43 */ F9: 67,\n /* 0x44 */ F10: 68,\n /* 0x45 */ NUM_LOCK: 69,\n /* 0x46 */ SCROLL_LOCK: 70,\n /* 0x47 */ NUM_HOME: 71,\n /* 0x48 */ NUM_UP: 72,\n /* 0x49 */ NUM_PGUP: 73,\n /* 0x4A */ NUM_SUB: 74,\n /* 0x4B */ NUM_LEFT: 75,\n /* 0x4C */ NUM_CENTER: 76,\n /* 0x4D */ NUM_RIGHT: 77,\n /* 0x4E */ NUM_ADD: 78,\n /* 0x4F */ NUM_END: 79,\n /* 0x50 */ NUM_DOWN: 80,\n /* 0x51 */ NUM_PGDN: 81,\n /* 0x52 */ NUM_INS: 82,\n /* 0x53 */ NUM_DEL: 83,\n /* 0x54 */ SYS_REQ: 84, // 84-key keyboard only (simulated with 'alt'+'prtsc' on 101-key keyboards)\n /* 0x54 */ PAUSE: 84, // 101-key keyboard only\n /* 0x57 */ F11: 87,\n /* 0x58 */ F12: 88,\n /* 0x5B */ WIN: 91, // aka CMD\n /* 0x5C */ RWIN: 92,\n /* 0x5D */ MENU: 93, // aka CMD + ONRIGHT\n /* 0x7F */ MAKE: 127,\n /* 0x80 */ BREAK: 128,\n /* 0xE0 */ EXTEND1: 224,\n /* 0xE1 */ EXTEND2: 225\n};\n\n/**\n * These internal \"shift key\" states are used to indicate BOTH the physical shift-key states (in bitsState)\n * and the simulated shift-key states (in bitsStateSim). The LOCK keys are problematic in both cases: the\n * browsers give us no way to query the LOCK key states, so we can only infer them, and because they are \"soft\"\n * locks, the machine's notion of their state is subject to change at any time as well. Granted, the IBM PC\n * ROM BIOS will store its LOCK states in the ROM BIOS Data Area (@0040:0017), but that's just a BIOS convention.\n *\n * Also, because this is purely for internal use, don't make the mistake of thinking that these bits have any\n * connection to the ROM BIOS bits @0040:0017 (they don't). We emulate hardware, not ROMs.\n *\n * TODO: Consider taking notice of the ROM BIOS Data Area state anyway, even though I'd rather remain ROM-agnostic;\n * at the very least, it would help us keep our LOCK LEDs in sync with the machine's LOCK states. However, the LED\n * issue will be largely moot (at least for MODEL_5170 machines) once we add support for PC AT keyboard LED commands.\n *\n * Note that right-hand state bits are equal to the left-hand bits shifted right 1 bit; makes sense, \"right\"? ;-)\n *\n * @enum {number}\n */\nKeyboard.STATE = {\n RSHIFT: 0x0001,\n SHIFT: 0x0002,\n SHIFTS: 0x0003,\n RCTRL: 0x0004, // 101-key keyboard only\n CTRL: 0x0008,\n CTRLS: 0x000C,\n RALT: 0x0010, // 101-key keyboard only\n ALT: 0x0020,\n ALTS: 0x0030,\n RCMD: 0x0040, // 101-key keyboard only\n CMD: 0x0080, // 101-key keyboard only\n CMDS: 0x00C0,\n ALL_RIGHT: 0x0055, // RSHIFT | RCTRL | RALT | RCMD\n ALL_MODIFIERS: 0x00FF, // SHIFT | RSHIFT | CTRL | RCTRL | ALT | RALT | CMD | RCMD\n INSERT: 0x0100, // TODO: Placeholder (we currently have no notion of any \"insert\" states)\n CAPS_LOCK: 0x0200,\n NUM_LOCK: 0x0400,\n SCROLL_LOCK: 0x0800,\n ALL_LOCKS: 0x0E00 // CAPS_LOCK | NUM_LOCK | SCROLL_LOCK\n};\n\n/*\n * Maps KEYCODES of modifier keys to their corresponding (default) STATES bit above.\n */\nKeyboard.MODIFIERS = {\n [Keyboard.SIMCODE.RSHIFT]: Keyboard.STATE.RSHIFT,\n [Keyboard.SIMCODE.SHIFT]: Keyboard.STATE.SHIFT,\n [Keyboard.SIMCODE.CTRL]: Keyboard.STATE.CTRL,\n [Keyboard.SIMCODE.ALT]: Keyboard.STATE.ALT,\n [Keyboard.SIMCODE.RALT]: Keyboard.STATE.ALT,\n [Keyboard.SIMCODE.CMD]: Keyboard.STATE.CMD,\n [Keyboard.SIMCODE.RCMD]: Keyboard.STATE.RCMD,\n [Keyboard.SIMCODE.FF_CMD]: Keyboard.STATE.CMD\n};\n\n/*\n * Maps KEYCODES of all modifier and lock keys to their corresponding (default) STATES bit above.\n */\nKeyboard.KEYSTATES = {\n [Keyboard.SIMCODE.RSHIFT]: Keyboard.STATE.RSHIFT,\n [Keyboard.SIMCODE.SHIFT]: Keyboard.STATE.SHIFT,\n [Keyboard.SIMCODE.CTRL]: Keyboard.STATE.CTRL,\n [Keyboard.SIMCODE.ALT]: Keyboard.STATE.ALT,\n [Keyboard.SIMCODE.RALT]: Keyboard.STATE.ALT,\n [Keyboard.SIMCODE.CMD]: Keyboard.STATE.CMD,\n [Keyboard.SIMCODE.RCMD]: Keyboard.STATE.RCMD,\n [Keyboard.SIMCODE.FF_CMD]: Keyboard.STATE.CMD,\n [Keyboard.SIMCODE.CAPS_LOCK]: Keyboard.STATE.CAPS_LOCK,\n [Keyboard.SIMCODE.NUM_LOCK]: Keyboard.STATE.NUM_LOCK,\n [Keyboard.SIMCODE.SCROLL_LOCK]: Keyboard.STATE.SCROLL_LOCK\n};\n\n/*\n * Maps CLICKCODE (string) to SIMCODE (number).\n *\n * NOTE: Unlike SOFTCODES, CLICKCODES are upper-case and use underscores instead of dashes, so that this\n * and other components can reference them using \"dot\" property syntax; using upper-case merely adheres to\n * our convention for constants. setBinding() will automatically convert any incoming CLICKCODE bindings\n * that use lower-case and dashes to upper-case and underscores before performing property lookup.\n */\nKeyboard.CLICKCODES = {\n 'TAB': Keyboard.SIMCODE.TAB,\n 'ESC': Keyboard.SIMCODE.ESC,\n 'F1': Keyboard.SIMCODE.F1,\n 'F2': Keyboard.SIMCODE.F2,\n 'F3': Keyboard.SIMCODE.F3,\n 'F4': Keyboard.SIMCODE.F4,\n 'F5': Keyboard.SIMCODE.F5,\n 'F6': Keyboard.SIMCODE.F6,\n 'F7': Keyboard.SIMCODE.F7,\n 'F8': Keyboard.SIMCODE.F8,\n 'F9': Keyboard.SIMCODE.F9,\n 'F10': Keyboard.SIMCODE.F10,\n 'LEFT': Keyboard.SIMCODE.LEFT,\n 'UP': Keyboard.SIMCODE.UP,\n 'RIGHT': Keyboard.SIMCODE.RIGHT,\n 'DOWN': Keyboard.SIMCODE.DOWN,\n 'NUM_HOME': Keyboard.SIMCODE.HOME,\n 'NUM_END': Keyboard.SIMCODE.END,\n 'NUM_PGUP': Keyboard.SIMCODE.PGUP,\n 'NUM_PGDN': Keyboard.SIMCODE.PGDN,\n 'ALT': Keyboard.SIMCODE.ALT,\n 'SYS_REQ': Keyboard.SIMCODE.SYS_REQ,\n /*\n * These bindings are for convenience (common key combinations that can be bound to a single control)\n */\n 'CTRL_C': Keyboard.SIMCODE.CTRL_C,\n 'CTRL_PAUSE': Keyboard.SIMCODE.CTRL_PAUSE,\n 'CTRL_BREAK': Keyboard.SIMCODE.CTRL_BREAK,\n 'CTRL_ALT_DEL': Keyboard.SIMCODE.CTRL_ALT_DEL,\n 'CTRL_ALT_INS': Keyboard.SIMCODE.CTRL_ALT_INS,\n 'CTRL_ALT_ADD': Keyboard.SIMCODE.CTRL_ALT_ADD,\n 'CTRL_ALT_SUB': Keyboard.SIMCODE.CTRL_ALT_SUB,\n 'CTRL_ALT_ENTER': Keyboard.SIMCODE.CTRL_ALT_ENTER\n};\n\n/*\n * Maps SOFTCODE (string) to SIMCODE (number) -- which may be the same as KEYCODE for ASCII keys.\n *\n * We define identifiers for all possible keys, based on their primary (unshifted) character or function.\n * This also serves as a definition of all supported keys, making it possible to create full-featured\n * \"soft keyboards\".\n *\n * One exception to the (unshifted) rule above is 'prtsc': on the original IBM 83-key and 84-key keyboards,\n * its primary (unshifted) character was '*', but on 101-key keyboards, it became a separate key ('prtsc',\n * now labeled \"Print Screen\"), as did the num-pad '*' ('num-mul'), so 'prtsc' seems worthy of an exception\n * to the rule.\n *\n * On 83-key and 84-key keyboards, 'ctrl'+'num-lock' triggered a \"pause\" operation and 'ctrl'+'scroll-lock'\n * triggered a \"break\" operation.\n *\n * On 101-key keyboards, IBM decided to move both those special operations to a new 'pause' (\"Pause/Break\")\n * key, near the new dedicated 'prtsc' (\"Print Screen/SysRq\") key -- and to drop the \"e\" from \"Sys Req\".\n * Those keys behave as follows:\n *\n * When 'pause' is pressed alone, it generates 0xe1 0x1d 0x45 0xe1 0x9d 0xc5 on make (nothing on break),\n * which essentially simulates the make-and-break of the 'ctrl' and 'num-lock' keys (ignoring the 0xe1),\n * triggering a \"pause\" operation.\n *\n * When 'pause' is pressed with 'ctrl', it generates 0xe0 0x46 0xe0 0xc6 on make (nothing on break) and\n * does not repeat, which essentially simulates the make-and-break of 'scroll-lock', which, in conjunction\n * with the separate make-and-break of 'ctrl', triggers a \"break\" operation.\n *\n * When 'prtsc' is pressed alone, it generates 0xe0 0x2a 0xe0 0x37, simulating the make of both 'shift'\n * and 'prtsc'; when pressed with 'shift' or 'ctrl', it generates only 0xe0 0x37; and when pressed with\n * 'alt', it generates only 0x54 (to simulate 'sys-req').\n *\n * TODO: Implement the above behaviors, whenever we get around to actually supporting 101-key keyboards.\n *\n * All key identifiers must be quotable using single-quotes, because that's how components.xsl will encode them\n * *inside* the \"data-value\" attribute of the corresponding HTML control. Which, in turn, is why the single-quote\n * key is defined as 'quote' rather than \"'\". Similarly, if there was unshifted \"double-quote\" key, it could\n * not be called '\"', because components.xsl quotes the *entire* \"data-value\" attribute using double-quotes.\n *\n * The (commented) numbering of keys below is purely for my own reference. Two keys are deliberately numbered 84,\n * reflecting the fact that the 'sys-req' key was added to the 84-key keyboard but later dropped from the 101-key\n * keyboard (as a stand-alone key, that is).\n * \n * With the introduction of the PC AT and the 84-key keyboard, IBM developed a new key numbering scheme and\n * key code generation; the 8042 keyboard controller would then convert those key codes into the PC scan codes\n * defined by the older 83-key keyboard. That's a layer of complexity we currently bypass; instead, we continue\n * to convert browser key codes directly into PC scan codes, which is what our 8042 controller implementation\n * assumes we're doing.\n */\nKeyboard.SOFTCODES = {\n /* 1 */ 'esc': Keyboard.SIMCODE.ESC,\n /* 2 */ '1': Keys.ASCII['1'],\n /* 3 */ '2': Keys.ASCII['2'],\n /* 4 */ '3': Keys.ASCII['3'],\n /* 5 */ '4': Keys.ASCII['4'],\n /* 6 */ '5': Keys.ASCII['5'],\n /* 7 */ '6': Keys.ASCII['6'],\n /* 8 */ '7': Keys.ASCII['7'],\n /* 9 */ '8': Keys.ASCII['8'],\n /* 10 */ '9': Keys.ASCII['9'],\n /* 11 */ '0': Keys.ASCII['0'],\n /* 12 */ '-': Keys.ASCII['-'],\n /* 13 */ '=': Keys.ASCII['='],\n /* 14 */ 'bs': Keyboard.SIMCODE.BS,\n /* 15 */ 'tab': Keyboard.SIMCODE.TAB,\n /* 16 */ 'q': Keys.ASCII.q,\n /* 17 */ 'w': Keys.ASCII.w,\n /* 18 */ 'e': Keys.ASCII.e,\n /* 19 */ 'r': Keys.ASCII.r,\n /* 20 */ 't': Keys.ASCII.t,\n /* 21 */ 'y': Keys.ASCII.y,\n /* 22 */ 'u': Keys.ASCII.u,\n /* 23 */ 'i': Keys.ASCII.i,\n /* 24 */ 'o': Keys.ASCII.o,\n /* 25 */ 'p': Keys.ASCII.p,\n /* 26 */ '[': Keys.ASCII['['],\n /* 27 */ ']': Keys.ASCII[']'],\n /* 28 */ 'enter': Keys.KEYCODE.CR,\n /* 29 */ 'ctrl': Keyboard.SIMCODE.CTRL,\n /* 30 */ 'a': Keys.ASCII.a,\n /* 31 */ 's': Keys.ASCII.s,\n /* 32 */ 'd': Keys.ASCII.d,\n /* 33 */ 'f': Keys.ASCII.f,\n /* 34 */ 'g': Keys.ASCII.g,\n /* 35 */ 'h': Keys.ASCII.h,\n /* 36 */ 'j': Keys.ASCII.j,\n /* 37 */ 'k': Keys.ASCII.k,\n /* 38 */ 'l': Keys.ASCII.l,\n /* 39 */ ';': Keys.ASCII[';'],\n /* 40 */ 'quote': Keys.ASCII[\"'\"], // formerly \"squote\"\n /* 41 */ '`': Keys.ASCII['`'], // formerly \"bquote\"\n /* 42 */ 'shift': Keyboard.SIMCODE.SHIFT, // formerly \"lshift\"\n /* 43 */ '\\\\': Keys.ASCII['\\\\'], // formerly \"bslash\"\n /* 44 */ 'z': Keys.ASCII.z,\n /* 45 */ 'x': Keys.ASCII.x,\n /* 46 */ 'c': Keys.ASCII.c,\n /* 47 */ 'v': Keys.ASCII.v,\n /* 48 */ 'b': Keys.ASCII.b,\n /* 49 */ 'n': Keys.ASCII.n,\n /* 50 */ 'm': Keys.ASCII.m,\n /* 51 */ ',': Keys.ASCII[','],\n /* 52 */ '.': Keys.ASCII['.'],\n /* 53 */ '/': Keys.ASCII['/'],\n /* 54 */ 'right-shift': Keyboard.SIMCODE.RSHIFT, // formerly \"rshift\"\n /* 55 */ 'prtsc': Keyboard.SIMCODE.PRTSC, // unshifted '*'; becomes dedicated 'Print Screen' key on 101-key keyboards\n /* 56 */ 'alt': Keyboard.SIMCODE.ALT,\n /* 57 */ 'space': Keyboard.SIMCODE.SPACE,\n /* 58 */ 'caps-lock': Keyboard.SIMCODE.CAPS_LOCK,\n /* 59 */ 'f1': Keyboard.SIMCODE.F1,\n /* 60 */ 'f2': Keyboard.SIMCODE.F2,\n /* 61 */ 'f3': Keyboard.SIMCODE.F3,\n /* 62 */ 'f4': Keyboard.SIMCODE.F4,\n /* 63 */ 'f5': Keyboard.SIMCODE.F5,\n /* 64 */ 'f6': Keyboard.SIMCODE.F6,\n /* 65 */ 'f7': Keyboard.SIMCODE.F7,\n /* 66 */ 'f8': Keyboard.SIMCODE.F8,\n /* 67 */ 'f9': Keyboard.SIMCODE.F9,\n /* 68 */ 'f10': Keyboard.SIMCODE.F10,\n /* 69 */ 'num-lock': Keyboard.SIMCODE.NUM_LOCK,\n /* 70 */ 'scroll-lock': Keyboard.SIMCODE.SCROLL_LOCK, // TODO: 0xe046 on 101-key keyboards?\n \n /*\n * Yes, distinguishing keys 71 through 83 with the 'num-' prefix seems like overkill, but it was\n * intended to be future-proofing, for the day when we might eventually add support for 101-key keyboards,\n * because they have their own dedicated non-numeric-keypad versions of these keys (in other words, they\n * account for most of the bloat on the 101-key keyboard, a trend that more modern keyboards have gradually\n * been reversing).\n * \n * To offset 'num-' prefix overkill, injectKeys() allows SOFTCODES to be used with or without the prefix,\n * on the theory that key injection users won't really care precisely which version of the key is used.\n */\n \n /* 71 */ 'num-home': Keyboard.SIMCODE.HOME, // formerly \"home\"\n /* 72 */ 'num-up': Keyboard.SIMCODE.UP, // formerly \"up-arrow\"\n /* 73 */ 'num-pgup': Keyboard.SIMCODE.PGUP, // formerly \"page-up\"\n /* 74 */ 'num-sub': Keyboard.SIMCODE.NUM_SUB, // formerly \"num-minus\"\n /* 75 */ 'num-left': Keyboard.SIMCODE.LEFT, // formerly \"left-arrow\"\n /* 76 */ 'num-center': Keyboard.SIMCODE.NUM_CENTER, // formerly \"center\"\n /* 77 */ 'num-right': Keyboard.SIMCODE.RIGHT, // formerly \"right-arrow\"\n /* 78 */ 'num-add': Keyboard.SIMCODE.NUM_ADD, // formerly \"num-plus\"\n /* 79 */ 'num-end': Keyboard.SIMCODE.END, // formerly \"end\"\n /* 80 */ 'num-down': Keyboard.SIMCODE.DOWN, // formerly \"down-arrow\"\n /* 81 */ 'num-pgdn': Keyboard.SIMCODE.PGDN, // formerly \"page-down\"\n /* 82 */ 'num-ins': Keyboard.SIMCODE.INS, // formerly \"ins\"\n /* 83 */ 'num-del': Keyboard.SIMCODE.DEL, // formerly \"del\"\n /* 84 */ 'sys-req': Keyboard.SIMCODE.SYS_REQ // 84-key keyboard only (simulated with 'alt'+'prtsc' on 101-key keyboards)\n \n /*\n * If I ever add 101-key keyboard support (and it's not clear that I will), then the following entries\n * will have to be converted to SIMCODE indexes, and each SIMCODE index will need an entry in the SIMCODES\n * table that defines the appropriate SCANCODE(S); as this component has evolved, SOFTCODES are no longer\n * mapped directly to SCANCODES.\n */\n \n// /* 84 */ 'pause': Keyboard.SCANCODE.PAUSE, // 101-key keyboard only\n// /* 85 */ 'f11': Keyboard.SCANCODE.F11,\n// /* 86 */ 'f12': Keyboard.SCANCODE.F12,\n// /* 87 */ 'num-enter': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.ENTER << 8),\n// /* 88 */ 'right-ctrl': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.CTRL << 8),\n// /* 89 */ 'num-div': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.SLASH << 8),\n// /* 90 */ 'num-mul': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.PRTSC << 8),\n// /* 91 */ 'right-alt': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.ALT << 8),\n// /* 92 */ 'home': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.NUM_HOME << 8),\n// /* 93 */ 'up': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.NUM_UP << 8),\n// /* 94 */ 'pgup': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.NUM_PGUP << 8),\n// /* 95 */ 'left': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.NUM_LEFT << 8),\n// /* 96 */ 'right': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.NUM_RIGHT << 8),\n// /* 97 */ 'end': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.NUM_END << 8),\n// /* 98 */ 'down': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.NUM_DOWN << 8),\n// /* 99 */ 'pgdn': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.NUM_PGDN << 8),\n// /*100 */ 'ins': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.NUM_INS << 8),\n// /*101 */ 'del': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.NUM_DEL << 8),\n \n// /*102 */ 'win': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.WIN << 8),\n// /*103 */ 'right-win': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.RWIN << 8),\n// /*104 */ 'menu': Keyboard.SCANCODE.EXTEND1 | (Keyboard.SCANCODE.MENU << 8)\n};\n\n/*\n * Maps \"soft-key\" definitions (above) of shift/modifier keys to their corresponding (default) STATES bit.\n */\nKeyboard.LEDSTATES = {\n 'caps-lock': Keyboard.STATE.CAPS_LOCK,\n 'num-lock': Keyboard.STATE.NUM_LOCK,\n 'scroll-lock': Keyboard.STATE.SCROLL_LOCK\n};\n\n/*\n * Maps SIMCODE (number) to SCANCODE (number(s)).\n *\n * This array is used by keySimulate() to lookup a given SIMCODE and convert it to a SCANCODE\n * (lower byte), plus any required shift key SCANCODES (upper bytes).\n *\n * Using keyCodes from keyPress events proved to be more robust than using keyCodes from keyDown and\n * keyUp events, in part because of differences in the way browsers generate the keyDown and keyUp events.\n * For example, Safari on iOS devices will not generate up/down events for shift keys, and for other keys,\n * the up/down events are usually generated after the actual press is complete, and in rapid succession.\n *\n * The other problem (which is more of a problem with keyboards like the C1P than any IBM keyboards) is\n * that the shift/modifier state for a character on the \"source\" keyboard may not match the shift/modifier\n * state for the same character on the \"target\" keyboard. And since this code is inherited from C1Pjs,\n * we've inherited the same solution: keySimulate() has the ability to \"undo\" any states in bitsState\n * that conflict with the state(s) required for the character in question.\n */\nKeyboard.SIMCODES = {\n [Keyboard.SIMCODE.ESC]: Keyboard.SCANCODE.ESC,\n [Keys.ASCII['1']]: Keyboard.SCANCODE.ONE,\n [Keys.ASCII['!']]: Keyboard.SCANCODE.ONE | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['2']]: Keyboard.SCANCODE.TWO,\n [Keys.ASCII['@']]: Keyboard.SCANCODE.TWO | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['3']]: Keyboard.SCANCODE.THREE,\n [Keys.ASCII['#']]: Keyboard.SCANCODE.THREE | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['4']]: Keyboard.SCANCODE.FOUR,\n [Keys.ASCII['$']]: Keyboard.SCANCODE.FOUR | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['5']]: Keyboard.SCANCODE.FIVE,\n [Keys.ASCII['%']]: Keyboard.SCANCODE.FIVE | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['6']]: Keyboard.SCANCODE.SIX,\n [Keys.ASCII['^']]: Keyboard.SCANCODE.SIX | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['7']]: Keyboard.SCANCODE.SEVEN,\n [Keys.ASCII['&']]: Keyboard.SCANCODE.SEVEN | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['8']]: Keyboard.SCANCODE.EIGHT,\n [Keys.ASCII['*']]: Keyboard.SCANCODE.EIGHT | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['9']]: Keyboard.SCANCODE.NINE,\n [Keys.ASCII['(']]: Keyboard.SCANCODE.NINE | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['0']]: Keyboard.SCANCODE.ZERO,\n [Keys.ASCII[')']]: Keyboard.SCANCODE.ZERO | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['-']]: Keyboard.SCANCODE.DASH,\n [Keys.ASCII['_']]: Keyboard.SCANCODE.DASH | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['=']]: Keyboard.SCANCODE.EQUALS,\n [Keys.ASCII['+']]: Keyboard.SCANCODE.EQUALS | (Keyboard.SCANCODE.SHIFT << 8),\n [Keyboard.SIMCODE.BS]: Keyboard.SCANCODE.BS,\n [Keyboard.SIMCODE.TAB]: Keyboard.SCANCODE.TAB,\n [Keys.ASCII.q]: Keyboard.SCANCODE.Q,\n [Keys.ASCII.Q]: Keyboard.SCANCODE.Q | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.w]: Keyboard.SCANCODE.W,\n [Keys.ASCII.W]: Keyboard.SCANCODE.W | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.e]: Keyboard.SCANCODE.E,\n [Keys.ASCII.E]: Keyboard.SCANCODE.E | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.r]: Keyboard.SCANCODE.R,\n [Keys.ASCII.R]: Keyboard.SCANCODE.R | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.t]: Keyboard.SCANCODE.T,\n [Keys.ASCII.T]: Keyboard.SCANCODE.T | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.y]: Keyboard.SCANCODE.Y,\n [Keys.ASCII.Y]: Keyboard.SCANCODE.Y | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.u]: Keyboard.SCANCODE.U,\n [Keys.ASCII.U]: Keyboard.SCANCODE.U | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.i]: Keyboard.SCANCODE.I,\n [Keys.ASCII.I]: Keyboard.SCANCODE.I | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.o]: Keyboard.SCANCODE.O,\n [Keys.ASCII.O]: Keyboard.SCANCODE.O | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.p]: Keyboard.SCANCODE.P,\n [Keys.ASCII.P]: Keyboard.SCANCODE.P | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['[']]: Keyboard.SCANCODE.LBRACK,\n [Keys.ASCII['{']]: Keyboard.SCANCODE.LBRACK | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII[']']]: Keyboard.SCANCODE.RBRACK,\n [Keys.ASCII['}']]: Keyboard.SCANCODE.RBRACK | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.KEYCODE.CR]: Keyboard.SCANCODE.ENTER,\n [Keyboard.SIMCODE.CTRL]: Keyboard.SCANCODE.CTRL,\n [Keys.ASCII.a]: Keyboard.SCANCODE.A,\n [Keys.ASCII.A]: Keyboard.SCANCODE.A | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.s]: Keyboard.SCANCODE.S,\n [Keys.ASCII.S]: Keyboard.SCANCODE.S | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.d]: Keyboard.SCANCODE.D,\n [Keys.ASCII.D]: Keyboard.SCANCODE.D | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.f]: Keyboard.SCANCODE.F,\n [Keys.ASCII.F]: Keyboard.SCANCODE.F | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.g]: Keyboard.SCANCODE.G,\n [Keys.ASCII.G]: Keyboard.SCANCODE.G | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.h]: Keyboard.SCANCODE.H,\n [Keys.ASCII.H]: Keyboard.SCANCODE.H | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.j]: Keyboard.SCANCODE.J,\n [Keys.ASCII.J]: Keyboard.SCANCODE.J | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.k]: Keyboard.SCANCODE.K,\n [Keys.ASCII.K]: Keyboard.SCANCODE.K | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.l]: Keyboard.SCANCODE.L,\n [Keys.ASCII.L]: Keyboard.SCANCODE.L | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII[';']]: Keyboard.SCANCODE.SEMI,\n [Keys.ASCII[':']]: Keyboard.SCANCODE.SEMI | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII[\"'\"]]: Keyboard.SCANCODE.QUOTE,\n [Keys.ASCII['\"']]: Keyboard.SCANCODE.QUOTE | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['`']]: Keyboard.SCANCODE.BQUOTE,\n [Keys.ASCII['~']]: Keyboard.SCANCODE.BQUOTE | (Keyboard.SCANCODE.SHIFT << 8),\n [Keyboard.SIMCODE.SHIFT]: Keyboard.SCANCODE.SHIFT,\n [Keys.ASCII['\\\\']]: Keyboard.SCANCODE.BSLASH,\n [Keys.ASCII['|']]: Keyboard.SCANCODE.BSLASH | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.z]: Keyboard.SCANCODE.Z,\n [Keys.ASCII.Z]: Keyboard.SCANCODE.Z | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.x]: Keyboard.SCANCODE.X,\n [Keys.ASCII.X]: Keyboard.SCANCODE.X | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.c]: Keyboard.SCANCODE.C,\n [Keys.ASCII.C]: Keyboard.SCANCODE.C | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.v]: Keyboard.SCANCODE.V,\n [Keys.ASCII.V]: Keyboard.SCANCODE.V | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.b]: Keyboard.SCANCODE.B,\n [Keys.ASCII.B]: Keyboard.SCANCODE.B | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.n]: Keyboard.SCANCODE.N,\n [Keys.ASCII.N]: Keyboard.SCANCODE.N | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII.m]: Keyboard.SCANCODE.M,\n [Keys.ASCII.M]: Keyboard.SCANCODE.M | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII[',']]: Keyboard.SCANCODE.COMMA,\n [Keys.ASCII['<']]: Keyboard.SCANCODE.COMMA | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['.']]: Keyboard.SCANCODE.PERIOD,\n [Keys.ASCII['>']]: Keyboard.SCANCODE.PERIOD | (Keyboard.SCANCODE.SHIFT << 8),\n [Keys.ASCII['/']]: Keyboard.SCANCODE.SLASH,\n [Keys.ASCII['?']]: Keyboard.SCANCODE.SLASH | (Keyboard.SCANCODE.SHIFT << 8),\n [Keyboard.SIMCODE.RSHIFT]: Keyboard.SCANCODE.RSHIFT,\n [Keyboard.SIMCODE.PRTSC]: Keyboard.SCANCODE.PRTSC,\n [Keyboard.SIMCODE.ALT]: Keyboard.SCANCODE.ALT,\n [Keyboard.SIMCODE.RALT]: Keyboard.SCANCODE.ALT,\n [Keyboard.SIMCODE.SPACE]: Keyboard.SCANCODE.SPACE,\n [Keyboard.SIMCODE.CAPS_LOCK]: Keyboard.SCANCODE.CAPS_LOCK,\n [Keyboard.SIMCODE.F1]: Keyboard.SCANCODE.F1,\n [Keyboard.SIMCODE.F2]: Keyboard.SCANCODE.F2,\n [Keyboard.SIMCODE.F3]: Keyboard.SCANCODE.F3,\n [Keyboard.SIMCODE.F4]: Keyboard.SCANCODE.F4,\n [Keyboard.SIMCODE.F5]: Keyboard.SCANCODE.F5,\n [Keyboard.SIMCODE.F6]: Keyboard.SCANCODE.F6,\n [Keyboard.SIMCODE.F7]: Keyboard.SCANCODE.F7,\n [Keyboard.SIMCODE.F8]: Keyboard.SCANCODE.F8,\n [Keyboard.SIMCODE.F9]: Keyboard.SCANCODE.F9,\n [Keyboard.SIMCODE.F10]: Keyboard.SCANCODE.F10,\n [Keyboard.SIMCODE.NUM_LOCK]: Keyboard.SCANCODE.NUM_LOCK,\n [Keyboard.SIMCODE.SCROLL_LOCK]: Keyboard.SCANCODE.SCROLL_LOCK,\n [Keyboard.SIMCODE.HOME]: Keyboard.SCANCODE.NUM_HOME,\n [Keyboard.SIMCODE.NUM_HOME]: Keyboard.SCANCODE.NUM_HOME,\n [Keyboard.SIMCODE.UP]: Keyboard.SCANCODE.NUM_UP,\n [Keyboard.SIMCODE.NUM_UP]: Keyboard.SCANCODE.NUM_UP,\n [Keyboard.SIMCODE.PGUP]: Keyboard.SCANCODE.NUM_PGUP,\n [Keyboard.SIMCODE.NUM_PGUP]: Keyboard.SCANCODE.NUM_PGUP,\n [Keyboard.SIMCODE.LEFT]: Keyboard.SCANCODE.NUM_LEFT,\n [Keyboard.SIMCODE.NUM_LEFT]: Keyboard.SCANCODE.NUM_LEFT,\n [Keyboard.SIMCODE.NUM_CENTER]: Keyboard.SCANCODE.NUM_CENTER,\n [Keyboard.SIMCODE.RIGHT]: Keyboard.SCANCODE.NUM_RIGHT,\n [Keyboard.SIMCODE.NUM_RIGHT]: Keyboard.SCANCODE.NUM_RIGHT,\n [Keyboard.SIMCODE.END]: Keyboard.SCANCODE.NUM_END,\n [Keyboard.SIMCODE.NUM_END]: Keyboard.SCANCODE.NUM_END,\n [Keyboard.SIMCODE.DOWN]: Keyboard.SCANCODE.NUM_DOWN,\n [Keyboard.SIMCODE.NUM_DOWN]: Keyboard.SCANCODE.NUM_DOWN,\n [Keyboard.SIMCODE.PGDN]: Keyboard.SCANCODE.NUM_PGDN,\n [Keyboard.SIMCODE.NUM_PGDN]: Keyboard.SCANCODE.NUM_PGDN,\n [Keyboard.SIMCODE.INS]: Keyboard.SCANCODE.NUM_INS,\n [Keyboard.SIMCODE.NUM_INS]: Keyboard.SCANCODE.NUM_INS,\n [Keyboard.SIMCODE.NUM_ADD]: Keyboard.SCANCODE.NUM_ADD,\n [Keyboard.SIMCODE.NUM_SUB]: Keyboard.SCANCODE.NUM_SUB,\n [Keyboard.SIMCODE.DEL]: Keyboard.SCANCODE.NUM_DEL,\n [Keyboard.SIMCODE.NUM_DEL]: Keyboard.SCANCODE.NUM_DEL,\n [Keyboard.SIMCODE.SYS_REQ]: Keyboard.SCANCODE.SYS_REQ,\n /*\n * Entries beyond this point are for keys that existed only on 101-key keyboards (well, except for 'sys-req',\n * which also existed on the 84-key keyboard), which ALSO means that these keys essentially did not exist\n * for a MODEL_5150 or MODEL_5160 machine, because those machines could use only 83-key keyboards. Remember\n * that IBM machines and IBM keyboards are our reference point here, so while there were undoubtedly 5150/5160\n * clones that could use newer keyboards, as well as 3rd-party keyboards that could work with older machines,\n * support for non-IBM configurations is left for another day.\n *\n * TODO: The only relevance of newer keyboards to older machines is the fact that you're probably using a newer\n * keyboard with your browser, which raises the question of what to do with newer keys that older machines\n * wouldn't understand. I don't attempt to filter out any of the entries below based on machine model, but that\n * would seem like a wise thing to do.\n *\n * TODO: Add entries for 'num-mul', 'num-div', 'num-enter', the stand-alone arrow keys, etc, AND at the same time,\n * make sure that keys with multi-byte sequences (eg, 0xe0 0x1c) work properly.\n */\n [Keyboard.SIMCODE.F11]: Keyboard.SCANCODE.F11,\n [Keyboard.SIMCODE.F12]: Keyboard.SCANCODE.F12,\n [Keyboard.SIMCODE.CMD]: Keyboard.SCANCODE.WIN,\n [Keyboard.SIMCODE.RCMD]: Keyboard.SCANCODE.MENU,\n [Keyboard.SIMCODE.FF_CMD]: Keyboard.SCANCODE.WIN,\n \n [Keyboard.SIMCODE.CTRL_A]: Keyboard.SCANCODE.A | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_B]: Keyboard.SCANCODE.B | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_C]: Keyboard.SCANCODE.C | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_D]: Keyboard.SCANCODE.D | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_E]: Keyboard.SCANCODE.E | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_F]: Keyboard.SCANCODE.F | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_G]: Keyboard.SCANCODE.G | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_H]: Keyboard.SCANCODE.H | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_I]: Keyboard.SCANCODE.I | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_J]: Keyboard.SCANCODE.J | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_K]: Keyboard.SCANCODE.K | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_L]: Keyboard.SCANCODE.L | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_M]: Keyboard.SCANCODE.M | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_N]: Keyboard.SCANCODE.N | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_O]: Keyboard.SCANCODE.O | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_P]: Keyboard.SCANCODE.P | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_Q]: Keyboard.SCANCODE.Q | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_R]: Keyboard.SCANCODE.R | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_S]: Keyboard.SCANCODE.S | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_T]: Keyboard.SCANCODE.T | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_U]: Keyboard.SCANCODE.U | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_V]: Keyboard.SCANCODE.V | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_W]: Keyboard.SCANCODE.W | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_X]: Keyboard.SCANCODE.X | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_Y]: Keyboard.SCANCODE.Y | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_Z]: Keyboard.SCANCODE.Z | (Keyboard.SCANCODE.CTRL << 8),\n [Keyboard.SIMCODE.CTRL_BREAK]: Keyboard.SCANCODE.SCROLL_LOCK | (Keyboard.SCANCODE.CTRL << 8),\n \n [Keyboard.SIMCODE.CTRL_ALT_DEL]: Keyboard.SCANCODE.NUM_DEL | (Keyboard.SCANCODE.CTRL << 8) | (Keyboard.SCANCODE.ALT << 16),\n [Keyboard.SIMCODE.CTRL_ALT_INS]: Keyboard.SCANCODE.NUM_INS | (Keyboard.SCANCODE.CTRL << 8) | (Keyboard.SCANCODE.ALT << 16),\n [Keyboard.SIMCODE.CTRL_ALT_ADD]: Keyboard.SCANCODE.NUM_ADD | (Keyboard.SCANCODE.CTRL << 8) | (Keyboard.SCANCODE.ALT << 16),\n [Keyboard.SIMCODE.CTRL_ALT_SUB]: Keyboard.SCANCODE.NUM_SUB | (Keyboard.SCANCODE.CTRL << 8) | (Keyboard.SCANCODE.ALT << 16),\n [Keyboard.SIMCODE.CTRL_ALT_ENTER]: Keyboard.SCANCODE.ENTER | (Keyboard.SCANCODE.CTRL << 8) | (Keyboard.SCANCODE.ALT << 16)\n};\n\n/**\n * Commands that can be sent to the Keyboard via the 8042; see receiveCmd()\n *\n * Aside from the commands listed below, 0xEF-0xF2 and 0xF7-0xFD are expressly documented as NOPs; ie:\n *\n * These commands are reserved and are effectively no-operation or NOP. The system does not use these codes.\n * If sent, the keyboard will acknowledge the command and continue in its prior scanning state. No other\n * operation will occur.\n *\n * However, IBM's documentation is silent with regard to 0x00-0xEC. It's likely that most if not all of those\n * commands are NOPs as well.\n *\n * @enum {number}\n */\nKeyboard.CMD = {\n /*\n * RESET (0xFF)\n *\n * The system issues a RESET command to start a program reset and a keyboard internal self-test. The keyboard\n * acknowledges the command with an 'acknowledge' signal (ACK) and ensures the system accepts the ACK before\n * executing the command. The system signals acceptance of the ACK by raising the clock and data for a minimum\n * of 500 microseconds. The keyboard is disabled from the time it receives the RESET command until the ACK is\n * accepted or until another command overrides the previous one. Following acceptance of the ACK, the keyboard\n * begins the reset operation, which is similar to a power-on reset. The keyboard clears the output buffer and\n * sets up default values for typematic and delay rates.\n */\n RESET: 0xFF,\n\n /*\n * RESEND (0xFE)\n *\n * The system can send this command when it detects an error in any transmission from the keyboard. It can be\n * sent only after a keyboard transmission and before the system enables the interface to allow the next keyboard\n * output. Upon receipt of RESEND, the keyboard sends the previous output again unless the previous output was\n * RESEND. In this case, the keyboard will resend the last byte before the RESEND command.\n */\n RESEND: 0xFE,\n\n /*\n * SET DEFAULT (0xF6)\n *\n * The SET DEFAULT command resets all conditions to the power-on default state. The keyboard responds with ACK,\n * clears its output buffer, sets default conditions, and continues scanning (only if the keyboard was previously\n * enabled).\n */\n DEF_ON: 0xF6,\n\n /*\n * DEFAULT DISABLE (0xF5)\n *\n * This command is similar to SET DEFAULT, except the keyboard stops scanning and awaits further instructions.\n */\n DEF_OFF: 0xF5,\n\n /*\n * ENABLE (0xF4)\n *\n * Upon receipt of this command, the keyboard responds with ACK, clears its output buffer, and starts scanning.\n */\n ENABLE: 0xF4,\n\n /*\n * SET TYPEMATIC RATE/DELAY (0xF3)\n *\n * The system issues this command, followed by a parameter, to change the typematic rate and delay. The typematic\n * rate and delay parameters are determined by the value of the byte following the command. Bits 6 and 5 serve as\n * the delay parameter and bits 4,3,2, 1, and 0 (the least-significant bit) are the rate parameter. Bit 7, the\n * most-significant bit, is always 0. The delay is equal to 1 plus the binary value of bits 6 and 5 multiplied by\n * 250 milliseconds ±20%.\n */\n SET_RATE: 0xF3,\n\n /*\n * ECHO (0xEE)\n *\n * ECHO is a diagnostic aid. When the keyboard receives this command, it issues a 0xEE response and continues\n * scanning if the keyboard was previously enabled.\n */\n ECHO: 0xEE,\n\n /*\n * SET/RESET MODE INDICATORS (0xED)\n *\n * Three mode indicators on the keyboard are accessible to the system. The keyboard activates or deactivates\n * these indicators when it receives a valid command from the system. They can be activated or deactivated in\n * any combination.\n *\n * The system remembers the previous state of an indicator so that its setting does not change when a command\n * sequence is issued to change the state of another indicator.\n *\n * A SET/RESET MODE INDICATORS command consists of 2 bytes. The first is the command byte and has the following\n * bit setup:\n *\n * 11101101 - 0xED\n *\n * The second byte is an option byte. It has a list of the indicators to be acted upon. The bit assignments for\n * this option byte are as follows:\n *\n * Bit Indicator\n * --- ---------\n * 0 Scroll Lock Indicator\n * 1 Num Lock Indicator\n * 2 Caps Lock Indicator\n * 3-7 Reserved (must be 0's)\n *\n * NOTE: Bit 7 is the most-significant bit; bit 0 is the least-significant.\n *\n * The keyboard will respond to the set/reset mode indicators command with an ACK, discontinue scanning, and wait\n * for the option byte. The keyboard will respond to the option byte with an ACK, set the indicators, and continue\n * scanning if the keyboard was previously enabled. If another command is received in place of the option byte,\n * execution of the function of the SET/RESET MODE INDICATORS command is stopped with no change to the indicator\n * states, and the new command is processed. Then scanning is resumed.\n */\n SET_LEDS: 0xED\n};\n\n/**\n * Command responses returned to the Keyboard via the 8042; see receiveCmd()\n *\n * @enum {number}\n */\nKeyboard.CMDRES = {\n /*\n * OVERRUN (0x00)\n *\n * An overrun character is placed in position 17 of the keyboard buffer, overlaying the last code if the\n * buffer becomes full. The code is sent to the system as an overrun when it reaches the top of the buffer.\n */\n OVERRUN: 0x00,\n\n LOAD_TEST: 0x65, // undocumented \"LOAD MANUFACTURING TEST REQUEST\" response code\n\n /*\n * BAT Completion Code (0xAA)\n *\n * Following satisfactory completion of the BAT, the keyboard sends 0xAA. 0xFC (or any other code)\n * means the keyboard microprocessor check failed.\n */\n BAT_OK: 0xAA,\n\n /*\n * ECHO Response (0xEE)\n *\n * This is sent in response to an ECHO command (also 0xEE) from the system.\n */\n ECHO: 0xEE,\n\n /*\n * BREAK CODE PREFIX (0xF0)\n *\n * This code is sent as the first byte of a 2-byte sequence to indicate the release of a key.\n */\n BREAK_PREF: 0xF0,\n\n /*\n * ACK (0xFA)\n *\n * The keyboard issues an ACK response to any valid input other than an ECHO or RESEND command.\n * If the keyboard is interrupted while sending ACK, it will discard ACK and accept and respond\n * to the new command.\n */\n ACK: 0xFA,\n\n /*\n * BASIC ASSURANCE TEST FAILURE (0xFC)\n */\n BAT_FAIL: 0xFC, // TODO: Verify this response code (is this just for older 83-key keyboards?)\n\n /*\n * DIAGNOSTIC FAILURE (0xFD)\n *\n * The keyboard periodically tests the sense amplifier and sends a diagnostic failure code if it detects\n * any problems. If a failure occurs during BAT, the keyboard stops scanning and waits for a system command\n * or power-down to restart. If a failure is reported after scanning is enabled, scanning continues.\n */\n DIAG_FAIL: 0xFD,\n\n /*\n * RESEND (0xFE)\n *\n * The keyboard issues a RESEND command following receipt of an invalid input, or any input with incorrect parity.\n * If the system sends nothing to the keyboard, no response is required.\n */\n RESEND: 0xFE,\n\n BUFF_FULL: 0xFF // TODO: Verify this response code (is this just for older 83-key keyboards?)\n};\n\nKeyboard.LIMIT = {\n MAX_SCANCODES: 20 // TODO: Verify this limit for newer keyboards (84-key and up)\n};\n\nKeyboard.INJECTION = {\n NONE: 0,\n ON_START: 1,\n ON_INPUT: 2\n};\n\n/*\n * Initialize every Keyboard module on the page.\n */\nWeb.onInit(Keyboard.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/video.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * MDA/CGA Support\n * ---------------\n *\n * Since there's a lot of similarity between the MDA and CGA (eg, their text-mode video buffer\n * format, and their use of the 6845 CRT controller), since the MDA ROM contains the fonts used\n * by both devices, and since the same ROM BIOS supports both (in fact, the BIOS indiscriminately\n * initializes both, regardless which is actually installed), this same component emulates both\n * devices.\n *\n * When no model is specified, this component supports the ability to dynamically switch between\n * MDA and CGA emulation, by simply toggling the SW1 motherboard \"monitor type\" switch settings\n * and resetting the machine. In that model-less configuration, we install I/O port handlers for\n * both MDA and CGA cards, regardless which monitor type is initially selected.\n *\n * To simulate an IBM PC containing both an MDA and CGA (ie, a \"dual display\" system), the machine\n * configuration simply defines two video components, one with model \"mda\" and the other with model\n * \"cga\", resulting in two displays; setting a specific model forces each instance of this component\n * to register only those I/O ports belonging to that model.\n *\n * In a single-display system, dynamically switching cards (ie, between MDA and CGA) creates some\n * visual challenges. For one, the MDA prefers a native screen size of 720x350, as it supports only\n * one video mode, 80x25, with a 9x14 cell size. The CGA, on the other hand, has an 8x8 cell size,\n * so when using an MDA-size screen, an 80x25 CGA screen will end up with 40-pixel borders on the\n * left and right, and 75-pixel borders on the top and bottom. The result is a rather tiny CGA font\n * surrounded by lots of wasted space, so it's best to turn on font scaling (see the \"scale\" property)\n * and go with a larger screen size of, say, 960x400 (50% larger in width, 100% larger in height).\n *\n * I've also added support for font-doubling in createFont(). We use the 8x8 font for 80-column\n * modes and the \"doubled\" 16x16 font for 40-column modes OR whenever the screen is large enough\n * to use the 16x16 font, since font rendering without scaling provides the sharpest results.\n * In fact, there's special logic in setDimensions() to ignore fScaleFont in certain cases (eg,\n * 40-column modes, to improve sharpness and avoid stretching the font beyond readability).\n *\n * Graphics modes, on the other hand, are always scaled to the screen size. Pixels are captured\n * in an off-screen buffer, which is then drawn to match the size of the virtual screen.\n *\n * TODO: Whenever there are borders, they should be filled with the CGA's overscan colors. However,\n * in the case of graphics modes (and text modes whenever font scaling is enabled), we don't reserve\n * any space for borders, so if borders are important, explicit border support will be required.\n *\n * EGA Support\n * -----------\n *\n * EGA support piggy-backs on the existing MDA/CGA support. All the existing MDA/CGA port handlers\n * now refer to either cardMono or cardColor (instead of directly to cardMDA or cardCGA), enabling\n * the handlers to be redirected to cardMDA, cardCGA or cardEGA as appropriate.\n *\n * Note that an MDA card supported only a Monochrome Display and a CGA card supported only a Color\n * Display (well, OK, *or* a TV monitor, which we don't currently support), but the EGA is much\n * more flexible: the Enhanced Color Display was the preferred display, but the EGA also supported\n * older displays; a Color Display on EGA wasn't ideal (same low resolutions but with more colors),\n * but the EGA also brought high-resolution graphics to Monochrome displays, which was nice. Anyway,\n * while all those EGA/monitor combinations will be nice to support, our virtual display support\n * will focus initially on the Enhanced Color Display.\n *\n * TODO: Add support for jumpers P1 and P3 (see EGA TechRef p.85). P1 selects either 5-color-output\n * for a CGA monitor or 6-color-output for an EGA monitor; we would presumably use this only to\n * control certain assumptions about the virtual display's capabilities (ie, Color Display vs. Enhanced\n * Color Display). P3 can switch all the I/O ports from 0x3nn to 0x2nn; the default is 0x3nn, and\n * that's the only port range the EGA ROM supports as well.\n *\n * VGA Support\n * -----------\n *\n * VGA support further piggy-backs on the existing EGA support, by adding the extra registers, I/O port\n * handlers, etc, that the VGA requires; any differences in registers common to both EGA and VGA are handled on\n * a case-by-case basis, usually according to the Video.CARD value stored in nCard.\n * \n * More will be said here about PCjs VGA support later. But first, a word from IBM: \"Video Graphics Array [VGA]\n * Programming Considerations\":\n *\n * Certain internal timings must be guaranteed by the user, in order to have the CRTC perform properly.\n * This is due to the physical design of the chip. These timings can be guaranteed by ensuring that the\n * rules listed below are followed when programming the CRTC.\n *\n * 1. The Horizontal Total [HTOTAL] register (R0) must be greater than or equal to a value of\n * 25 decimal.\n *\n * 2. The minimum positive pulse width of the HSYNC output must be four character clock units.\n *\n * 3. Register R5, Horizontal Sync End [HREND], must be programmed such that the HSYNC\n * output goes to a logic 0 a minimum of one character clock time before the 'horizontal display enable'\n * signal goes to a logical 1.\n *\n * 4. Register R16, Vsync Start [VRSTART], must be a minimum of one horizontal scan line greater\n * than register R18 [VDEND]. Register R18 defines where the 'vertical display enable' signal ends.\n *\n * When bit 5 of the Attribute Mode Control register equals 1, a successful line compare (see Line Compare\n * [LINECOMP] register) in the CRT Controller forces the output of the PEL Panning register to 0's until Vsync\n * occurs. When Vsync occurs, the output returns to the programmed value. This allows the portion of the screen\n * indicated by the Line Compare register to be operated on by the PEL Panning register.\n *\n * A write to the Character Map Select register becomes valid on the next whole character line. No deformed\n * characters are displayed by changing character generators in the middle of a character scan line.\n *\n * For 256-color 320 x 200 graphics mode hex 13, the attribute controller is configured so that the 8-bit attribute\n * stored in video memory for each PEL becomes the 8-bit address (P0 - P7) into the integrated DAC. The user should\n * not modify the contents of the internal Palette registers when using this mode.\n *\n * The following sequence should be followed when accessing any of the Attribute Data registers pointed to by the\n * Attribute Index register:\n *\n * 1. Disable interrupts\n * 2. Reset read/write flip/flop\n * 3. Write to Index register\n * 4. Read from or write to a data register\n * 5. Enable interrupts\n *\n * The Color Select register in the Attribute Controller section may be used to rapidly switch between sets of colors\n * in the video DAC. When bit 7 of the Attribute Mode Control register equals 0, the 8-bit color value presented to the\n * video DAC is composed of 6 bits from the internal Palette registers and bits 2 and 3 from the Color Select register.\n * When bit 7 of the Attribute Mode Control register equals 1, the 8-bit color value presented to the video DAC is\n * composed of the lower four bits from the internal Palette registers and the four bits in the Color Select register.\n * By changing the value in the Color Select register, software rapidly switches between sets of colors in the video DAC.\n * Note that BIOS does not support multiple sets of colors in the video DAC. The user must load these colors if this\n * function is to be used. Also see the Attribute Controller block diagram on page 4-26. Note that the above discussion\n * applies to all modes except 256 Color Graphics mode. In this mode the Color Select register is not used to switch\n * between sets of colors.\n *\n * An application that saves the \"Video State\" must store the 4 bytes of information contained in the system microprocessor\n * latches in the graphics controller subsection. These latches are loaded with 32 bits from video memory (8 bits per map)\n * each time the system microprocessor does a read from video memory. The application needs to:\n *\n * 1. Use write mode 1 to write the values in the latches to a location in video memory that is not part of\n * the display buffer. The last location in the address range is a good choice.\n *\n * 2. Save the values of the latches by reading them back from video memory.\n *\n * Note: If in a chain 4 or odd/even mode, it will be necessary to reconfigure the memory organization as four\n * sequential maps prior to performing the sequence above. BIOS provides support for completely saving and\n * restoring video state. See the IBM Personal System/2 and Personal Computer BIOS Interface Technical Reference\n * for more information.\n *\n * The description of the Horizontal PEL Panning register includes a figure showing the number of PELs shifted left\n * for each valid value of the PEL Panning register and each valid video mode. Further panning beyond that shown in\n * the figure may be accomplished by changing the start address in the CRT Controller registers, Start Address High\n * and Start Address Low. The sequence involved in further panning would be as follows:\n *\n * 1. Use the PEL Panning register to shift the maximum number of bits to the left. See Figure 4-103 on page\n * 4-106 for the appropriate values.\n *\n * 2. Increment the start address.\n *\n * 3. If you are not using Modes 0 + , 1 + , 2 + , 3 + ,7, or7 + , set the PEL Panning register to 0. If you\n * are using these modes, set the PEL Panning register to 8. The screen will now be shifted one PEL left\n * of the position it was in at the end of step 1. Step 1 through Step 3 may be repeated as desired.\n *\n * The Line Compare register (CRTC register hex 18) should be programmed with even values in 200 line modes when\n * used in split screen applications that scroll a second screen on top of a first screen. This is a requirement\n * imposed by the scan doubling logic in the CRTC.\n *\n * If the Cursor Start register (CRTC register hex 0A) is programmed with a value greater than that in the Cursor End\n * register (CRTC register hex 0B), then no cursor is displayed. A split cursor is not possible.\n *\n * In 8-dot character modes, the underline attribute produces a solid line across adjacent characters, as in the IBM\n * Color/Graphics Monitor Adapter, Monochrome Display Adapter and the Enhanced Graphics Adapter. In 9-dot modes, the\n * underline across adjacent characters is dashed, as in the IBM 327X display terminals. In 9-dot modes, the line\n * graphics characters (C0 - DF character codes) have solid underlines.\n *\n * For compatibility with the IBM Enhanced Graphics Adapter (EGA), the internal VGA palette is programmed the same\n * as the EGA. The video DAC is programmed by BIOS so that the compatible values in the internal VGA palette produce\n * a color compatible with what was produced by EGA. Mode hex 13 (256 colors) is programmed so that the first 16\n * locations in the DAC produce compatible colors.\n *\n * Summing: When BIOS is used to load the video DAC palette for a color mode and a monochrome display is connected\n * to the system unit, the color palette is changed. The colors are summed to produce shades of gray that allow\n * color applications to produce a readable screen.\n *\n * There are 4 bits that should not be modified unless the sequencer is reset by setting bit 1 of the Reset register\n * to 0. These bits are:\n *\n * • Bit 3, or bit 0 of the Clocking Mode register\n * • Bit 3, or bit 2 of the Miscellaneous Output register\n *\n * Also, for quick reference, IBM VGA register values for the standard VGA modes (from http://www.pcjs.org/blog/2015/06/01/):\n *\n * INT 0x10 Mode Requested: 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x0D 0x0E 0x10 0x12 0x13\n *\n * BIOSMODE: 0x01 0x01 0x03 0x03 0x04 0x04 0x06 0x0D 0x0E 0x10 0x12 0x13\n * CRTC[0x00]: HTOTAL 0x2D 0x2D 0x5F 0x5F 0x2D 0x2D 0x5F 0x2D 0x5F 0x5F 0x5F 0x5F\n * CRTC[0x01]: HDEND 0x27 0x27 0x4F 0x4F 0x27 0x27 0x4F 0x27 0x4F 0x4F 0x4F 0x4F\n * CRTC[0x02]: HBSTART 0x28 0x28 0x50 0x50 0x28 0x28 0x50 0x28 0x50 0x50 0x50 0x50\n * CRTC[0x03]: HBEND 0x90 0x90 0x82 0x82 0x90 0x90 0x82 0x90 0x82 0x82 0x82 0x82\n * CRTC[0x04]: HRSTART 0x2B 0x2B 0x55 0x55 0x2B 0x2B 0x54 0x2B 0x54 0x54 0x54 0x54\n * CRTC[0x05]: HREND 0xA0 0xA0 0x81 0x81 0x80 0x80 0x80 0x80 0x80 0x80 0x80 0x80\n * CRTC[0x06]: VTOTAL 0xBF 0xBF 0xBF 0xBF 0xBF 0xBF 0xBF 0xBF 0xBF 0xBF 0x0B 0xBF\n * CRTC[0x07]: OVERFLOW 0x1F 0x1F 0x1F 0x1F 0x1F 0x1F 0x1F 0x1F 0x1F 0x1F 0x3E 0x1F\n * CRTC[0x08]: PRESCAN 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * CRTC[0x09]: MAXSCAN 0x4F 0x4F 0x4F 0x4F 0xC1 0xC1 0xC1 0xC0 0xC0 0x40 0x40 0x41\n * CRTC[0x0A]: CURSCAN 0x0D 0x0D 0x0D 0x0D 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * CRTC[0x0B]: CURSCANB 0x0E 0x0E 0x0E 0x0E 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * CRTC[0x0C]: STARTHI 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * CRTC[0x0D]: STARTLO 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * CRTC[0x0E]: CURSORHI 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x00\n * CRTC[0x0F]: CURSORLO 0x19 0x19 0x41 0x41 0x19 0x19 0x41 0x19 0x41 0x41 0xE1 0xA2\n * CRTC[0x10]: VRSTART 0x9C 0x9C 0x9C 0x9C 0x9C 0x9C 0x9C 0x9C 0x9C 0x83 0xEA 0x9C\n * CRTC[0x11]: VREND 0x8E 0x8E 0x8E 0x8E 0x8E 0x8E 0x8E 0x8E 0x8E 0x85 0x8C 0x8E\n * CRTC[0x12]: VDEND 0x8F 0x8F 0x8F 0x8F 0x8F 0x8F 0x8F 0x8F 0x8F 0x5D 0xDF 0x8F\n * CRTC[0x13]: OFFSET 0x14 0x14 0x28 0x28 0x14 0x14 0x28 0x14 0x28 0x28 0x28 0x28\n * CRTC[0x14]: UNDERLINE 0x1F 0x1F 0x1F 0x1F 0x00 0x00 0x00 0x00 0x00 0x0F 0x00 0x40\n * CRTC[0x15]: VBSTART 0x96 0x96 0x96 0x96 0x96 0x96 0x96 0x96 0x96 0x63 0xE7 0x96\n * CRTC[0x16]: VBEND 0xB9 0xB9 0xB9 0xB9 0xB9 0xB9 0xB9 0xB9 0xB9 0xBA 0x04 0xB9\n * CRTC[0x17]: MODECTRL 0xA3 0xA3 0xA3 0xA3 0xA2 0xA2 0xC2 0xE3 0xE3 0xE3 0xE3 0xA3\n * CRTC[0x18]: LINECOMP 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF\n * GRC[0x00]: SRESET 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * GRC[0x01]: ESRESET 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * GRC[0x02]: COLORCMP 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * GRC[0x03]: DATAROT 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * GRC[0x04]: READMAP 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * GRC[0x05]: MODE 0x10 0x10 0x10 0x10 0x30 0x30 0x00 0x00 0x00 0x00 0x00 0x40\n * GRC[0x06]: MISC 0x0E 0x0E 0x0E 0x0E 0x0F 0x0F 0x0D 0x05 0x05 0x05 0x05 0x05\n * GRC[0x07]: COLORDC 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0F 0x0F 0x0F 0x0F 0x0F\n * GRC[0x08]: BITMASK 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF\n * SEQ[0x00]: RESET 0x03 0x03 0x03 0x03 0x03 0x03 0x03 0x03 0x03 0x03 0x03 0x03\n * SEQ[0x01]: CLOCKING 0x08 0x08 0x00 0x00 0x09 0x09 0x01 0x09 0x01 0x01 0x01 0x01\n * SEQ[0x02]: MAPMASK 0x03 0x03 0x03 0x03 0x03 0x03 0x01 0x0F 0x0F 0x0F 0x0F 0x0F\n * SEQ[0x03]: CHARMAP 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * SEQ[0x04]: MEMMODE 0x03 0x03 0x03 0x03 0x02 0x02 0x06 0x06 0x06 0x06 0x06 0x0E\n * ATC[0x00]: PAL00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * ATC[0x01]: PAL01 0x01 0x01 0x01 0x01 0x13 0x13 0x17 0x01 0x01 0x01 0x01 0x01\n * ATC[0x02]: PAL02 0x02 0x02 0x02 0x02 0x15 0x15 0x17 0x02 0x02 0x02 0x02 0x02\n * ATC[0x03]: PAL03 0x03 0x03 0x03 0x03 0x17 0x17 0x17 0x03 0x03 0x03 0x03 0x03\n * ATC[0x04]: PAL04 0x04 0x04 0x04 0x04 0x02 0x02 0x17 0x04 0x04 0x04 0x04 0x04\n * ATC[0x05]: PAL05 0x05 0x05 0x05 0x05 0x04 0x04 0x17 0x05 0x05 0x05 0x05 0x05\n * ATC[0x06]: PAL06 0x14 0x14 0x14 0x14 0x06 0x06 0x17 0x06 0x06 0x14 0x14 0x06\n * ATC[0x07]: PAL07 0x07 0x07 0x07 0x07 0x07 0x07 0x17 0x07 0x07 0x07 0x07 0x07\n * ATC[0x08]: PAL08 0x38 0x38 0x38 0x38 0x10 0x10 0x17 0x10 0x10 0x38 0x38 0x08\n * ATC[0x09]: PAL09 0x39 0x39 0x39 0x39 0x11 0x11 0x17 0x11 0x11 0x39 0x39 0x09\n * ATC[0x0A]: PAL0A 0x3A 0x3A 0x3A 0x3A 0x12 0x12 0x17 0x12 0x12 0x3A 0x3A 0x0A\n * ATC[0x0B]: PAL0B 0x3B 0x3B 0x3B 0x3B 0x13 0x13 0x17 0x13 0x13 0x3B 0x3B 0x0B\n * ATC[0x0C]: PAL0C 0x3C 0x3C 0x3C 0x3C 0x14 0x14 0x17 0x14 0x14 0x3C 0x3C 0x0C\n * ATC[0x0D]: PAL0D 0x3D 0x3D 0x3D 0x3D 0x15 0x15 0x17 0x15 0x15 0x3D 0x3D 0x0D\n * ATC[0x0E]: PAL0E 0x3E 0x3E 0x3E 0x3E 0x16 0x16 0x17 0x16 0x16 0x3E 0x3E 0x0E\n * ATC[0x0F]: PAL0F 0x3F 0x3F 0x3F 0x3F 0x17 0x17 0x17 0x17 0x17 0x3F 0x3F 0x0F\n * ATC[0x10]: MODE 0x0C 0x0C 0x0C 0x0C 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x41\n * ATC[0x11]: OVERSCAN 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n * ATC[0x12]: PLANES 0x0F 0x0F 0x0F 0x0F 0x03 0x03 0x01 0x0F 0x0F 0x0F 0x0F 0x0F\n * ATC[0x13]: HPAN 0x08 0x08 0x08 0x08 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n *\n * TODO: Build a similar table for the IBM EGA, and then work on rationalizing the mode detection logic in checkMode().\n */\n\n/**\n * @class Card\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass Card extends Controller {\n /**\n * Card(video, nCard, data, cbMemory)\n *\n * Creates an object representing an initial video card state;\n * can also restore a video card from state data created by saveCard().\n *\n * WARNING: Since Card objects are low-level objects that have no UI requirements,\n * they do not inherit from the Component class, so you should only use class methods\n * of Component, such as Component.assert(), or methods of the parent (video) object.\n *\n * @this {Card}\n * @param {Video} [video]\n * @param {number} [nCard] (see Video.CARD.*)\n * @param {Array|null} [data]\n * @param {number} [cbMemory] is specified if the card must allocate its own memory buffer\n */\n constructor(video, nCard, data, cbMemory)\n {\n super();\n \n /*\n * If a card was originally not present (eg, EGA), then the state will be empty,\n * so we need to detect that case and continue indicating that the card is not present.\n */\n if (nCard !== undefined && (!data || data.length)) {\n\n this.video = video;\n\n var specs = Video.cardSpecs[nCard];\n var nMonitorType = video.nMonitorType || specs[5];\n\n if (!data || data.length < 6) {\n data = [false, 0, null, null, 0, new Array(nCard < Video.CARD.EGA? Card.CRTC.TOTAL_REGS : Card.CRTC.EGA.TOTAL_REGS)];\n }\n\n /*\n * If a Debugger is present, we want to stash a bit more info in each Card.\n */\n if (DEBUGGER) {\n this.dbg = /** @type {DebuggerX86} */ (video.dbg);\n this.type = specs[0];\n this.port = specs[1];\n }\n\n this.nCard = nCard;\n this.addrBuffer = specs[2]; // default (physical) video buffer address\n this.sizeBuffer = specs[3]; // default video buffer length (this is the total size, not the current visible size; this.cbScreen is calculated on the fly to reflect the latter)\n\n /*\n * If no memory size is specified, then setMode() will use addMemory() to automatically add enough\n * memory blocks to cover the video buffer specified above; otherwise, it instructs addMemory() to call\n * getMemoryBuffer(), which will return a portion of the buffer (adwMemory) allocated below. This allows\n * a card like the EGA to move/resize its video buffer as needed, as well as giving it total control over\n * the underlying memory.\n */\n this.cbMemory = cbMemory || specs[4];\n\n /*\n * All of our cardSpec video buffer sizes are based on the default text mode (eg, 4Kb for an MDA, 16Kb for\n * a CGA), but for a card with 64Kb or more of memory (ie, any EGA card), the default text mode video buffer\n * size should be dynamically recalculated as the smaller of: cbMemory divided by 4, or 32Kb.\n */\n if (this.cbMemory >= 0x10000 && this.addrBuffer >= 0xB0000) {\n this.sizeBuffer = Math.min(this.cbMemory >> 2, 0x8000);\n }\n\n this.fActive = data[0];\n this.regMode = data[1]; // see MDA.MODE* or CGA.MODE_* (use (MDA.MODE.HIRES | MDA.MODE.VIDEO_ENABLE | MDA.MODE.BLINK_ENABLE) if you want to test blinking immediately after the initial power-on reset)\n this.regColor = data[2]; // see CGA.COLOR.* (undefined on MDA)\n this.regStatus = data[3]; // see MDA.STATUS.* or CGA.STATUS.*\n this.regCRTIndx = data[4] & 0xff;\n this.regCRTPrev = (data[4] >> 8) & 0xff;\n this.regCRTData = data[5];\n this.nCRTCRegs = Card.CRTC.TOTAL_REGS;\n this.asCRTCRegs = DEBUGGER? Card.CRTC.REGS : [];\n this.offStartAddr = this.regCRTData[Card.CRTC.STARTLO] | (this.regCRTData[Card.CRTC.STARTHI] << 8);\n this.addrMaskHigh = 0x3F; // card-specific mask for the high (bits 8 and up) of CRTC address registers\n\n if (nCard >= Video.CARD.EGA) {\n this.addrMaskHigh = 0xFF;\n this.nCRTCRegs = Card.CRTC.EGA.TOTAL_REGS;\n this.asCRTCRegs = DEBUGGER? Card.CRTC.EGA_REGS : [];\n this.initEGA(data[6], nMonitorType);\n }\n\n var monitorSpecs = Video.monitorSpecs[nMonitorType] || Video.monitorSpecs[ChipSet.MONITOR.MONO];\n\n var nCyclesDefault = video.cpu.getBaseCyclesPerSecond(); // eg, 4772727\n this.nCyclesHorzPeriod = (nCyclesDefault / monitorSpecs.nHorzPeriodsPerSec)|0;\n this.nCyclesHorzActive = (this.nCyclesHorzPeriod * monitorSpecs.percentHorzActive / 100)|0;\n this.nCyclesVertPeriod = (this.nCyclesHorzPeriod * monitorSpecs.nHorzPeriodsPerFrame)|0;\n this.nCyclesVertActive = (this.nCyclesVertPeriod * monitorSpecs.percentVertActive / 100)|0;\n this.nInitCycles = (data[7] || 0);\n }\n }\n\n /**\n * initEGA(data)\n *\n * Another one of my frustrations with JSON is that it encodes empty arrays with non-zero lengths as\n * arrays of nulls, which means that any uninitialized register arrays whose elements were all originally\n * undefined come back via the JSON round-trip as *initialized* arrays whose elements are now all null.\n *\n * I'm a bit surprised, because JavaScript purists tell us to always use the '===' operator (eg, use\n * 'aReg[i] === undefined' to determine if an element is initialized), but because of this JSON stupidity,\n * that would require all such tests to become 'aReg[i] === undefined || aReg[i] === null'. I'm puzzled\n * why the coercion of '==' is considered evil but JSON's coercion of undefined to null is perfectly fine.\n *\n * The simple solution is to change such comparisons to 'aReg[i] == null', because undefined is coerced\n * to null, whereas numeric values are not.\n *\n * [What do I mean by \"another\" frustration? Let me talk to you some day about disallowing hex constants,\n * or insisting that property names be quoted, or refusing to allow comments. I think it's fine for\n * JSON.stringify() to produce output that adheres to rules like that -- although some parameters to control\n * the output would be nice -- but it's completely unnecessary for JSON.parse() to refuse to parse objects\n * that are perfectly valid.]\n *\n * @this {Card}\n * @param {Array|undefined} data\n * @param {number} nMonitorType\n */\n initEGA(data, nMonitorType)\n {\n if (data === undefined) {\n data = [\n /* 0*/ false,\n /* 1*/ 0,\n /* 2*/ new Array(Card.ATC.TOTAL_REGS),\n /* 3*/ 0,\n /* 4*/ (nMonitorType == ChipSet.MONITOR.MONO? 0: Card.MISC.IO_SELECT),\n /* 5*/ 0,\n /* 6*/ 0,\n /* 7*/ new Array(Card.SEQ.TOTAL_REGS),\n /* 8*/ 0,\n /* 9*/ 0,\n /*10*/ 0,\n /*11*/ new Array(Card.GRC.TOTAL_REGS),\n /*12*/ 0,\n /*13*/ [this.addrBuffer, this.sizeBuffer, this.cbMemory],\n /*14*/ new Array(this.cbMemory >> 2), // divide cbMemory by 4 since this is an array of DWORDs (8 bits for each of 4 planes)\n /*\n * Card.ACCESS.WRITE.MODE0 by itself is a pretty good default, but if we choose to \"randomize\" the screen with\n * text characters prior to starting the machine, defaulting to Card.ACCESS.WRITE.EVENODD is more faithful to how\n * characters and attributes are typically stored (ie, in planes 0 and 1, respectively). As soon as the machine\n * starts up and initializes the hardware itself, these defaults won't matter.\n */\n /*15*/ Card.ACCESS.READ.MODE0 | Card.ACCESS.READ.EVENODD | Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.EVENODD | Card.ACCESS.V2,\n /*16*/ 0,\n /*17*/ 0xffffffff|0,\n /*18*/ 0,\n /*19*/ 0xffffffff|0,\n /*20*/ 0,\n /*21*/ 0xffffffff|0,\n /*22*/ 0,\n /*23*/ 0,\n /*24*/ 0,\n /*25*/ 0,\n /*26*/ Card.VGA_ENABLE.ENABLED,\n /*27*/ Card.DAC.MASK.DEFAULT,\n /*28*/ 0,\n /*29*/ 0,\n /*30*/ Card.DAC.STATE.MODE_WRITE,\n /*31*/ new Array(Card.DAC.TOTAL_REGS)\n ];\n }\n\n this.fATCData = data[0];\n this.regATCIndx = data[1];\n this.regATCData = data[2];\n this.asATCRegs = DEBUGGER? Card.ATC.REGS : [];\n this.regStatus0 = data[3]; // aka STATUS0 (not to be confused with this.regStatus, which the EGA refers to as STATUS1)\n this.regMisc = data[4];\n this.regFeat = data[5]; // for feature control bits, see Card.FEAT_CTRL.BITS; for feature status bits, see Card.STATUS0.FEAT\n this.regSEQIndx = data[6];\n this.regSEQData = data[7];\n this.asSEQRegs = DEBUGGER? Card.SEQ.REGS : [];\n this.regGRCPos1 = data[8];\n this.regGRCPos2 = data[9];\n this.regGRCIndx = data[10];\n this.regGRCData = data[11];\n this.asGRCRegs = DEBUGGER? Card.GRC.REGS : [];\n this.latches = data[12];\n\n /*\n * Since we originally neglected to save/restore the card's active video buffer address and length,\n * we're now stashing all that information in data[13]. So if we're presented with an old data entry\n * that contains only the card's memory size, fix it up.\n *\n * TODO: This code just creates the required array; the correct video buffer address and length would\n * still need to be calculated from the current GRC registers; checkMode() knows how to do that, but I'm\n * not prepared to shoehorn in a call to checkMode() here, and potentially create more issues, for an\n * old problem that will eventually disappear anyway.\n */\n var a = data[13];\n if (typeof a == \"number\") {\n a = [this.addrBuffer, this.sizeBuffer, a];\n }\n this.addrBuffer = a[0];\n this.sizeBuffer = a[1];\n\n\n var cdw = this.cbMemory >> 2;\n this.adwMemory = data[14];\n if (this.adwMemory && this.adwMemory.length < cdw) {\n this.adwMemory = State.decompressEvenOdd(this.adwMemory, cdw);\n }\n\n var nAccess = data[15];\n if (nAccess) {\n if (nAccess & Card.ACCESS.V2) {\n nAccess &= ~Card.ACCESS.V2;\n } else {\n\n nAccess = Card.ACCESS.V1[nAccess & 0xff00] | Card.ACCESS.V1[nAccess & 0xff];\n }\n }\n this.setMemoryAccess(nAccess);\n\n /*\n * nReadMapShift must perfectly track how the GRC.READMAP register is programmed, so that Card.ACCESS.READ.MODE0\n * memory read functions read the appropriate plane. This default is not terribly critical, unless Card.ACCESS.WRITE.MODE0\n * is chosen as our default AND you want the screen randomizer to work.\n */\n this.nReadMapShift = data[16];\n\n /*\n * Similarly, nSeqMapMask must perfectly track how the SEQ.MAPMASK register is programmed, so that memory write\n * functions write the appropriate plane(s). Again, this default is not terribly critical, unless Card.ACCESS.WRITE.MODE0\n * is chosen as our default AND you want the screen randomizer to work.\n */\n this.nSeqMapMask = data[17];\n this.nDataRotate = data[18];\n this.nBitMapMask = data[19];\n this.nSetMapData = data[20];\n this.nSetMapMask = data[21];\n this.nSetMapBits = data[22];\n this.nColorCompare = data[23];\n this.nColorDontCare = data[24];\n this.offStartAddr = data[25]; // this is the last CRTC start address latched from CRTC.STARTHI,CRTC.STARTLO\n\n this.nVertPeriods = this.nVertPeriodsStartAddr = 0;\n\n if (this.nCard == Video.CARD.VGA) {\n this.regVGAEnable = data[26];\n this.regDACMask = data[27];\n this.regDACAddr = data[28];\n this.regDACShift = data[29];\n this.regDACState = data[30];\n this.regDACData = data[31];\n }\n }\n\n /**\n * saveCard()\n *\n * @this {Card}\n * @return {Array}\n */\n saveCard()\n {\n var data = [];\n if (this.nCard !== undefined) {\n data[0] = this.fActive;\n data[1] = this.regMode;\n data[2] = this.regColor;\n data[3] = this.regStatus;\n data[4] = this.regCRTIndx | (this.regCRTPrev << 8);\n data[5] = this.regCRTData;\n if (this.nCard >= Video.CARD.EGA) {\n data[6] = this.saveEGA();\n }\n data[7] = this.nInitCycles;\n }\n return data;\n }\n\n /**\n * saveEGA()\n *\n * @this {Card}\n * @return {Array}\n */\n saveEGA()\n {\n var data = [];\n data[0] = this.fATCData;\n data[1] = this.regATCIndx;\n data[2] = this.regATCData;\n data[3] = this.regStatus0;\n data[4] = this.regMisc;\n data[5] = this.regFeat;\n data[6] = this.regSEQIndx;\n data[7] = this.regSEQData;\n data[8] = this.regGRCPos1;\n data[9] = this.regGRCPos2;\n data[10] = this.regGRCIndx;\n data[11] = this.regGRCData;\n data[12] = this.latches;\n data[13] = [this.addrBuffer, this.sizeBuffer, this.cbMemory];\n data[14] = State.compressEvenOdd(this.adwMemory);\n data[15] = this.nAccess | Card.ACCESS.V2;\n data[16] = this.nReadMapShift;\n data[17] = this.nSeqMapMask;\n data[18] = this.nDataRotate;\n data[19] = this.nBitMapMask;\n data[20] = this.nSetMapData;\n data[21] = this.nSetMapMask;\n data[22] = this.nSetMapBits;\n data[23] = this.nColorCompare;\n data[24] = this.nColorDontCare;\n data[25] = this.offStartAddr;\n\n if (this.nCard == Video.CARD.VGA) {\n data[26] = this.regVGAEnable;\n data[27] = this.regDACMask;\n data[28] = this.regDACAddr;\n data[29] = this.regDACShift;\n data[30] = this.regDACState;\n data[31] = this.regDACData;\n }\n return data;\n }\n\n /**\n * dumpRegs()\n *\n * Since we don't pre-allocate the register arrays (eg, ATC, CRTC, GRC, etc) on a Card, we can't\n * rely on their array length, so we instead rely on the number of register names supplied in asRegs.\n *\n * @this {Card}\n * @param {string} sName\n * @param {number} iReg\n * @param {Array} [aRegs]\n * @param {Array} [asRegs]\n */\n dumpRegs(sName, iReg, aRegs, asRegs)\n {\n if (DEBUGGER) {\n if (!aRegs) {\n this.dbg.println(sName + \": \" + Str.toHex(iReg, 2));\n return;\n }\n var i, cchMax = 18, s = \"\";\n for (i = 0; i < asRegs.length; i++) {\n var reg = (aRegs === this.regCRTData)? this.getCRTCReg(i) : aRegs[i];\n if (s) s += '\\n';\n s += sName + \"[\" + Str.toHex(i, 2) + \"]: \" + Str.pad(asRegs[i], cchMax) + (i === iReg? '*' : ' ') + Str.toHex(reg, reg > 0xff? 4 : 2);\n if (reg != null) s += \" (\" + reg + \".)\";\n }\n this.dbg.println(s);\n }\n }\n\n /**\n * dumpVideoCard()\n *\n * @this {Card}\n */\n dumpVideoCard()\n {\n if (DEBUGGER) {\n /*\n * Start with registers that are common to all cards....\n */\n this.dumpRegs(\"CRTC\", this.regCRTIndx, this.regCRTData, this.asCRTCRegs);\n\n if (this.nCard >= Video.CARD.EGA) {\n this.dumpRegs(\" GRC\", this.regGRCIndx, this.regGRCData, this.asGRCRegs);\n this.dumpRegs(\" SEQ\", this.regSEQIndx, this.regSEQData, this.asSEQRegs);\n this.dumpRegs(\" ATC\", this.regATCIndx, this.regATCData, this.asATCRegs);\n this.dumpRegs(\" ATCINDX\", this.regATCIndx);\n this.dbg.println(\" ATCDATA: \" + this.fATCData);\n this.dumpRegs(\" FEAT\", this.regFeat);\n this.dumpRegs(\" MISC\", this.regMisc);\n this.dumpRegs(\" STATUS0\", this.regStatus0);\n /*\n * There are few more EGA regs we could dump, like GRCPos1, GRCPos2, but does anyone care?\n */\n }\n\n /*\n * TODO: This simply dumps the last value read from the STATUS1 register, not necessarily\n * its current state; consider dumping getRetraceBits() instead of (or in addition to) this.\n */\n this.dumpRegs(\" STATUS1\", this.regStatus);\n\n if (this.nCard == Video.CARD.MDA || this.nCard == Video.CARD.CGA) {\n this.dumpRegs(\" MODEREG\", this.regMode);\n }\n\n if (this.nCard == Video.CARD.CGA) {\n this.dumpRegs(\" COLOR\", this.regColor);\n }\n\n if (this.nCard >= Video.CARD.EGA) {\n this.dbg.println(\" LATCHES: \" + Str.toHex(this.latches));\n this.dbg.println(\" ACCESS: \" + Str.toHex(this.nAccess, 4));\n this.dbg.println(\"Use 'd video [addr]' to dump video memory\");\n /*\n * There are few more EGA regs we could dump, like GRCPos1, GRCPos2, but does anyone care?\n */\n }\n }\n }\n\n /**\n * dumpVideoBuffer(asArgs)\n *\n * Rather than requiring the first parameter to ALWAYS be a frame buffer address OR a frame buffer\n * offset, we'll just make a guess as to what the user intended and support BOTH; basically, if the\n * value is less than the frame buffer address, we'll assume it's an offset.\n *\n * Also, we allow some special options to be encoded in asArgs: 'l' followed by a number means\n * print that many rows of data. 'n' followed by a number (1-8) means print only that number of\n * memory locations per row, and then adjust the starting address of the next row by the number\n * of bytes per row (or whatever is specified by the 'w' option) so that the dump reflects a\n * rectangular chunk of video data. Finally, if asArgs contains 'p' followed by a number (0-3),\n * we display only the bits from that plane for each memory location, in binary instead of hex.\n *\n * For example, assuming a standard VGA frame buffer with 640x480 pixels across 38400 (0x9600) memory\n * locations, the following command will dump a vertical swath of bits from plane 0 that is 32 (0x20)\n * rows tall and 8 columns wide, from roughly the center of the screen (0x4B00 + 0x28 - 2 = 0x4B26).\n *\n * d video 4b26 l20 n8 p0\n *\n * Subsequent commands that omit a starting address or offset will continue where the last dump\n * left off; eg:\n *\n * d video n8 p0\n *\n * To dump a chunk of off-screen memory starting at 0x9600, where the Windows VGA driver typically\n * stores a copy of the video memory containing the current mouse pointer:\n *\n * d video 9600 l20 n5 w5 p0\n *\n * Alternatively, you could use decimal values:\n *\n * d video 9600 l32. n5. w5. p0.\n *\n * NOTE: If these commands look suspiciously like weird Hayes modem command strings, trust me,\n * that is ENTIRELY coincidental (but mildly amusing).\n *\n * TODO: Make these options more general-purpose (it currently assumes a conventional VGA planar layout).\n *\n * @this {Card}\n * @param {Array.<string>} asArgs (all numeric arguments default to base 16 unless otherwise specified)\n */\n dumpVideoBuffer(asArgs)\n {\n if (DEBUGGER) {\n if (!this.adwMemory) {\n this.dbg.println(\"no buffer\");\n return;\n }\n\n var i, j, idw, fColAdjust = false;\n var l = 8, n = 8, p = -1, w = this.video.nCols >> 3;\n\n for (i = 0; i < asArgs.length; i++) {\n\n var s = asArgs[i];\n if (!i) {\n idw = Str.parseInt(s, 16);\n continue;\n }\n\n var ch = s.charAt(0);\n j = Str.parseInt(s.substr(1), 16);\n\n switch(ch) {\n case 'l':\n l = j;\n break;\n case 'n':\n if (j >= 1 && j <= 8) {\n n = j;\n fColAdjust = true;\n }\n break;\n case 'p':\n if (j >= 0 && j <= 3) p = j;\n break;\n case 'w':\n if (j < w) w = j;\n break;\n default:\n this.dbg.println(\"unrecognized argument: \" + s);\n break;\n }\n }\n\n if (idw === undefined) {\n idw = this.prevDump || 0;\n } else if (idw >= this.addrBuffer) {\n idw -= this.addrBuffer;\n }\n\n var sDump = \"\";\n for (i = 0; i < l; i++) {\n var sData = Str.toHex(this.addrBuffer + idw) + \":\";\n for (j = 0; j < n && idw < this.adwMemory.length; j++) {\n var dw = this.adwMemory[idw++];\n sData += ' ' + ((p < 0)? Str.toHex(dw, 8) : Str.toBin((dw >> (p << 3)), 8));\n }\n if (fColAdjust) idw += w - n;\n if (sDump) sDump += \"\\n\";\n sDump += sData;\n }\n\n if (sDump) this.dbg.println(sDump);\n this.prevDump = idw;\n }\n }\n\n /**\n * getMemoryBuffer(addr)\n *\n * If we passed a controller object (ie, this card) to addMemory(), then each allocated Memory block\n * will call this function to obtain a buffer.\n *\n * @this {Card}\n * @param {number} addr\n * @return {Array} containing the buffer (and the offset within that buffer that corresponds to the requested block)\n */\n getMemoryBuffer(addr)\n {\n return [this.adwMemory, addr - this.addrBuffer];\n }\n\n /**\n * getMemoryAccess()\n *\n * WARNING: This is a public method, whereas most Card methods are private to the Video component;\n * because a Card also acts as a Memory controller, it must provide getMemoryAccess() to the Memory component.\n *\n * Return the last set of memory access functions recorded by setMemoryAccess().\n *\n * @this {Card}\n * @return {Array.<function()>}\n */\n getMemoryAccess()\n {\n return this.afnAccess;\n }\n\n /**\n * setMemoryAccess(nAccess)\n *\n * This transforms the memory access value that getCardAccess() returns into the best available set of\n * memory access functions, which are then returned via getMemoryAccess() to any memory blocks we allocate\n * or modify.\n *\n * @this {Card}\n * @param {number|undefined} nAccess\n */\n setMemoryAccess(nAccess)\n {\n if (nAccess != null && nAccess != this.nAccess) {\n\n var nReadAccess = nAccess & Card.ACCESS.READ.MASK;\n var fnReadByte = Card.ACCESS.afn[nReadAccess];\n if (!fnReadByte) {\n if (DEBUG && this.dbg && this.dbg.messageEnabled(Messages.VIDEO)) {\n this.dbg.message(\"Card.setMemoryAccess(\" + Str.toHexWord(nAccess) + \"): missing readByte handler\");\n /*\n * I've taken a look, and the cases I've seen so far stem from the order in which the IBM VGA BIOS\n * reprograms registers during a mode change: it reprograms the Sequencer registers BEFORE the Graphics\n * Controller registers, so if GRC.MODE was set to READ.MODE1 prior to the mode change and the new mode\n * clears SEQ.MEMMODE.SEQUENTIAL, we will briefly be in an \"odd\" (unsupported) state.\n *\n * This didn't used to occur when we relied on the GRC.MODE register instead of the SEQ.MEMMODE for\n * determining the EVENODD state. But, as explained in getCardAccess(), we've run into inconsistencies in\n * how GRC.MODE.EVENODD is programmed, so we must live with this warning.\n *\n * The ultimate solution is to provide a EVENODD handler for READ.MODE1, since there is the remote\n * possibility of third-party software that relies on that \"odd\" combination.\n *\n * this.dbg.stopCPU(); // let's take a look\n */\n }\n if (nReadAccess & Card.ACCESS.READ.EVENODD) {\n fnReadByte = Card.ACCESS.afn[Card.ACCESS.READ.EVENODD];\n }\n }\n var nWriteAccess = nAccess & Card.ACCESS.WRITE.MASK;\n var fnWriteByte = Card.ACCESS.afn[nWriteAccess];\n if (!fnWriteByte) {\n if (DEBUG && this.dbg && this.dbg.messageEnabled(Messages.VIDEO)) {\n this.dbg.message(\"Card.setMemoryAccess(\" + Str.toHexWord(nAccess) + \"): missing writeByte handler\");\n /*\n * I've taken a look, and the cases I've seen so far stem from the order in which the IBM VGA BIOS\n * reprograms registers during a mode change: it reprograms the Sequencer registers BEFORE the Graphics\n * Controller registers, so if GRC.MODE was set to WRITE.MODE2 prior to the mode change and the new mode\n * clears SEQ.MEMMODE.SEQUENTIAL, we will briefly be in an \"odd\" (unsupported) state.\n *\n * This didn't used to occur when we relied on the GRC.MODE register instead of the SEQ.MEMMODE for\n * determining the EVENODD state. But, as explained in getCardAccess(), we've run into inconsistencies in\n * how GRC.MODE.EVENODD is programmed, so we must live with this warning.\n *\n * The ultimate solution is to provide EVENODD handlers for all modes other than WRITE.MODE0, since there\n * is the remote possibility of third-party software that relies on one of those \"odd\" combinations.\n *\n * this.dbg.stopCPU(); // let's take a look\n */\n }\n if (nWriteAccess & Card.ACCESS.WRITE.EVENODD) {\n fnWriteByte = Card.ACCESS.afn[Card.ACCESS.WRITE.EVENODD];\n }\n }\n if (!this.afnAccess) this.afnAccess = new Array(6);\n this.afnAccess[0] = fnReadByte;\n this.afnAccess[1] = fnWriteByte;\n this.nAccess = nAccess;\n }\n }\n\n /**\n * getCRTCReg()\n *\n * @this {Card}\n * @param {number} iReg\n * @return {number}\n */\n getCRTCReg(iReg)\n {\n var reg = this.regCRTData[iReg];\n if (reg != null && this.nCard >= Video.CARD.EGA) {\n var bOverflowBit8 = 0, bOverflowBit9 = 0, bMaxScanBit9 = 0;\n switch(iReg) {\n case Card.CRTC.EGA.VTOTAL: // 0x06\n bOverflowBit8 = Card.CRTC.EGA.OVERFLOW.VTOTAL_BIT8; // 0x01\n if (this.nCard == Video.CARD.VGA) bOverflowBit9 = Card.CRTC.EGA.OVERFLOW.VTOTAL_BIT9;\n break;\n case Card.CRTC.EGA.CURSCAN: // 0x0A\n if (this.nCard == Video.CARD.EGA) bOverflowBit8 = Card.CRTC.EGA.OVERFLOW.CURSCAN_BIT8;\n break;\n case Card.CRTC.EGA.VRSTART: // 0x10\n bOverflowBit8 = Card.CRTC.EGA.OVERFLOW.VRSTART_BIT8; // 0x04\n if (this.nCard == Video.CARD.VGA) bOverflowBit9 = Card.CRTC.EGA.OVERFLOW.VRSTART_BIT9;\n break;\n case Card.CRTC.EGA.VDEND: // 0x12\n bOverflowBit8 = Card.CRTC.EGA.OVERFLOW.VDEND_BIT8; // 0x02\n if (this.nCard == Video.CARD.VGA) bOverflowBit9 = Card.CRTC.EGA.OVERFLOW.VDEND_BIT9;\n break;\n case Card.CRTC.EGA.VBSTART: // 0x15\n bOverflowBit8 = Card.CRTC.EGA.OVERFLOW.VBSTART_BIT8; // 0x08\n if (this.nCard == Video.CARD.VGA) bMaxScanBit9 = Card.CRTC.EGA.MAXSCAN.VBSTART_BIT9;\n break;\n case Card.CRTC.EGA.LINECOMP: // 0x18\n bOverflowBit8 = Card.CRTC.EGA.OVERFLOW.LINECOMP_BIT8; // 0x10\n if (this.nCard == Video.CARD.VGA) bMaxScanBit9 = Card.CRTC.EGA.MAXSCAN.LINECOMP_BIT9;\n break;\n }\n if (bOverflowBit8) {\n reg |= ((this.regCRTData[Card.CRTC.EGA.OVERFLOW.INDX] & bOverflowBit8)? 0x100 : 0);\n reg |= ((this.regCRTData[Card.CRTC.EGA.OVERFLOW.INDX] & bOverflowBit9)? 0x200 : 0);\n reg |= ((this.regCRTData[Card.CRTC.EGA.MAXSCAN.INDX] & bMaxScanBit9)? 0x200 : 0);\n }\n }\n return reg;\n }\n}\n\n/*\n * MDA Registers (ports 0x3B4, 0x3B5, 0x3B8, and 0x3BA)\n */\nCard.MDA = {\n CRTC: {\n INDX: {\n PORT: 0x3B4, // NOTE: the low byte of this port address (0xB4) is mirrored at 40:0063 (0x0463)\n MASK: 0x1F\n },\n DATA: {\n PORT: 0x3B5\n }\n },\n MODE: {\n PORT: 0x3B8, // Mode Select Register, aka CRT Control Port 1 (write-only); the BIOS mirrors this register at 40:0065 (0x0465)\n HIRES: 0x01,\n VIDEO_ENABLE: 0x08,\n BLINK_ENABLE: 0x20\n },\n STATUS: {\n PORT: 0x3BA,\n HDRIVE: 0x01,\n BWVIDEO: 0x08\n },\n /*\n * TODO: Add support for parallel port(s) someday....\n */\n PRT_DATA: {\n PORT: 0x3BC\n },\n PRT_STATUS: {\n PORT: 0x3BD\n },\n PRT_CTRL: {\n PORT: 0x3BE\n }\n};\n\n/*\n * CGA Registers (ports 0x3D4, 0x3D5, 0x3D8, 0x3D9, and 0x3DA)\n */\nCard.CGA = {\n CRTC: {\n INDX: {\n PORT: 0x3D4, // NOTE: the low byte of this port address (0xB4) is mirrored at 40:0063 (0x0463)\n MASK: 0x1F\n },\n DATA: {\n PORT: 0x3D5\n }\n },\n MODE: {\n PORT: 0x3D8, // Mode Select Register (write-only); the BIOS mirrors this register at 40:0065 (0x0465)\n _80X25: 0x01,\n GRAPHIC_SEL: 0x02,\n BW_SEL: 0x04,\n VIDEO_ENABLE: 0x08, // same as MDA.MODE.VIDEO_ENABLE\n HIRES_BW: 0x10,\n BLINK_ENABLE: 0x20 // same as MDA.MODE.BLINK_ENABLE\n },\n COLOR: {\n PORT: 0x3D9, // write-only\n BORDER: 0x07,\n BRIGHT: 0x08,\n BGND_ALT: 0x10, // alternate, intensified background colors in text mode\n COLORSET2: 0x20 // selects aCGAColorSet2 colors for 320x200 graphics mode; aCGAColorSet1 otherwise\n },\n STATUS: {\n PORT: 0x3DA, // read-only; same for EGA (although the EGA calls this STATUS1, to distinguish it from STATUS0)\n RETRACE: 0x01,\n PEN_TRIGGER: 0x02,\n PEN_ON: 0x04,\n VRETRACE: 0x08 // when set, this indicates the CGA is performing a vertical retrace\n },\n /*\n * TODO: Add support for light pen port(s) someday....\n */\n CLEAR_PEN: {\n PORT: 0x3DB\n },\n PRESET_PEN: {\n PORT: 0x3DC\n }\n};\n\n/*\n * Common CRT hardware registers (ports 0x3B4/0x3B5 or 0x3D4/0x3D5)\n *\n * NOTE: In this implementation, because we have to make at least two of the registers readable (CURSORHI and CURSORLO),\n * we end up making ALL the registers readable, otherwise we would have to explicitly block any register marked write-only.\n * I don't think making the CRT registers fully readable presents any serious compatibility issues, and it actually offers\n * some benefits (eg, improved debugging).\n *\n * However, some things are broken: the (readable) light pen registers on the EGA are overloaded as (writable) vertical retrace\n * registers, so the vertical retrace registers cannot actually be read that way. I'm sure the VGA solved that problem, but I haven't\n * looked into it yet.\n */\nCard.CRTC = {\n HTOTAL: 0x00, // Horizontal Total\n HDISP: 0x01, // Horizontal Displayed\n HSPOS: 0x02, // Horizontal Sync Position\n HSWIDTH: 0x03, // Horizontal Sync Width\n VTOTAL: 0x04, // Vertical Total\n VTOTADJ: 0x05, // Vertical Total Adjust\n VDISP: 0x06, // Vertical Displayed\n VSPOS: 0x07, // Vertical Sync Position\n ILMODE: 0x08, // Interlace Mode\n MAXSCAN: 0x09, // Max Scan Line Address\n CURSCAN: 0x0A, // Cursor Scan Line Top\n CURSCAN_SLMASK: 0x1F, // Scan Line Mask\n /*\n * I don't entirely understand the cursor blink control bits. Here's what the MC6845 datasheet says:\n *\n * Bit 5 is the blink timing control. When bit 5 is low, the blink frequency is 1/16 of the vertical field rate,\n * and when bit 5 is high, the blink frequency is 1/32 of the vertical field rate. Bit 6 is used to enable a blink.\n */\n CURSCAN_BLINKON: 0x00, // (supposedly, 0x40 has the same effect as 0x00?)\n CURSCAN_BLINKOFF: 0x20, // if blinking is disabled, the cursor is effectively hidden (TODO: CGA and VGA only?)\n CURSCAN_BLINKFAST: 0x60, // default is 1/16 of the frame rate; this switches to 1/32 of the frame rate (TODO: CGA only?)\n CURSCANB: 0x0B, // Cursor Scan Line Bottom\n STARTHI: 0x0C, // Start Address High\n STARTLO: 0x0D, // Start Address Low\n CURSORHI: 0x0E, // Cursor Address High\n CURSORLO: 0x0F, // Cursor Address Low\n PENHI: 0x10, // Light Pen High\n PENLO: 0x11, // Light Pen Low\n TOTAL_REGS: 0x12, // total CRT registers on MDA/CGA\n EGA: {\n HDEND: 0x01,\n HBSTART: 0x02,\n HBEND: 0x03,\n HRSTART: 0x04,\n HREND: 0x05,\n VTOTAL: 0x06,\n OVERFLOW: {\n INDX: 0x07,\n VTOTAL_BIT8: 0x01, // bit 8 of register 0x06\n VDEND_BIT8: 0x02, // bit 8 of register 0x12\n VRSTART_BIT8: 0x04, // bit 8 of register 0x10\n VBSTART_BIT8: 0x08, // bit 8 of register 0x15\n LINECOMP_BIT8: 0x10, // bit 8 of register 0x18\n CURSCAN_BIT8: 0x20, // bit 8 of register 0x0A (EGA only; TODO: What is this for? The CURSCAN register doesn't even use bit 7, so why would it need a bit 8?)\n VTOTAL_BIT9: 0x20, // bit 9 of register 0x06 (VGA only)\n VDEND_BIT9: 0x40, // bit 9 of register 0x12 (VGA only, unused on EGA)\n VRSTART_BIT9: 0x80 // bit 9 of register 0x10 (VGA only, unused on EGA)\n },\n PRESCAN: 0x08,\n /*\n * NOTE: EGA/VGA CRTC registers 0x09-0x0F are the same as the MDA/CGA CRTC registers defined above\n */\n MAXSCAN: {\n INDX: 0x09, // (same as MDA/CGA)\n SLMASK: 0x1F, // Scan Line Mask\n VBSTART_BIT9: 0x20, // (VGA only)\n LINECOMP_BIT9: 0x40, // (VGA only)\n CONVERT400: 0x80 // 200-to-400 scan-line conversion is in effect (VGA only)\n },\n CURSCAN: 0x0A, // (same as MDA/CGA)\n CURSCANB: 0x0B, // (same as MDA/CGA)\n STARTHI: 0x0C, // (same as MDA/CGA)\n STARTLO: 0x0D, // (same as MDA/CGA)\n CURSORHI: 0x0E, // (same as MDA/CGA)\n CURSORLO: 0x0F, // (same as MDA/CGA)\n VRSTART: 0x10, // (formerly PENHI on MDA/CGA)\n VREND: 0x11, // (formerly PENLO on MDA/CGA; last register on the original 6845 controller)\n VDEND: 0x12,\n /*\n * The OFFSET register (bits 0-7) specifies the logical line width of the screen. The starting memory address\n * for the next character row is larger than the current character row by two or four times this amount.\n * The OFFSET register is programmed with a word address. Depending on the method of clocking the CRT Controller,\n * this word address is [effectively] either a word or double-word address. #IBMVGATechRef\n */\n OFFSET: 0x13,\n UNDERLINE: {\n INDX: 0x14,\n ROWSCAN: 0x1F,\n COUNT_BY_4: 0x20, // (VGA only)\n DWORD: 0x40 // (VGA only)\n },\n VBSTART: 0x15,\n VBEND: 0x16,\n MODECTRL: {\n INDX: 0x17,\n COMPAT_MODE: 0x01, // Compatibility Mode Support (CGA A13 control)\n SEL_ROW_SCAN: 0x02, // Select Row Scan Counter\n SEL_HRETRACE: 0x04, // Horizontal Retrace Select\n COUNT_BY_2: 0x08, // Count By Two\n OUTPUT_CTRL: 0x10, // Output Control\n ADDR_WRAP: 0x20, // Address Wrap (in Word mode, 1 maps A15 to A0 and 0 maps A13; use the latter when only 64Kb is installed)\n BYTE_MODE: 0x40, // Byte Mode (1 selects Byte Mode; 0 selects Word Mode)\n HARD_RESET: 0x80 // Hardware Reset\n },\n LINECOMP: 0x18,\n TOTAL_REGS: 0x19 // total CRT registers on EGA/VGA\n }\n};\n\n/*\n * TODO: These mask tables need to be card-specific. For example, the STARTHI and CURSORHI registers used to be\n * limited to 0x3F, because the MC6845 controller used with the original MDA and CGA cards was limited to 16Kb of RAM,\n * whereas later cards like the EGA and VGA had anywhere from 64Kb to 256Kb, so all the bits of those registers were\n * significant. Currently, I'm doing very little masking, which means most CRTC registers are treated as full 8-bit\n * registers (and fully readable as well), which might cause some compatibility problems for any MDA/CGA apps that\n * were sloppy about how they programmed registers.\n *\n * I do make an exception, however, in the case of STARTHI and CURSORHI, due to the way the MC6845 controller wraps\n * addresses around to the beginning of the buffer, because that seems like a high-risk case. See the card-specific\n * variable addrMaskHigh.\n */\nCard.CRTCMASKS = {\n [Card.CRTC.HTOTAL]: 0xFF, // R0\n [Card.CRTC.HDISP]: 0xFF, // R1\n [Card.CRTC.HSPOS]: 0xFF, // R2\n [Card.CRTC.HSWIDTH]: 0x0F, // R3\n [Card.CRTC.VTOTAL]: 0x7F, // R4\n [Card.CRTC.VTOTADJ]: 0x1F, // R5\n [Card.CRTC.VDISP]: 0x7F, // R6\n [Card.CRTC.VSPOS]: 0x7F, // R7\n [Card.CRTC.ILMODE]: 0x03, // R8\n [Card.CRTC.MAXSCAN]: 0x1F, // R9\n [Card.CRTC.CURSCAN]: 0x7F, // R10\n [Card.CRTC.CURSCANB]: 0x1F, // R11\n [Card.CRTC.STARTHI]: 0x3F, // R12\n [Card.CRTC.STARTLO]: 0xFF, // R13\n [Card.CRTC.CURSORHI]: 0x3F, // R14\n [Card.CRTC.CURSORLO]: 0xFF, // R15\n [Card.CRTC.PENHI]: 0x3F, // R16\n [Card.CRTC.PENLO]: 0xFF // R17\n};\n\nif (DEBUGGER) {\n Card.CRTC.REGS = [\n \"HTOTAL\",\"HDISP\",\"HSPOS\",\"HSWIDTH\",\"VTOTAL\",\"VTOTADJ\",\n \"VDISP\",\"VSPOS\",\"ILMODE\",\"MAXSCAN\",\"CURSCAN\",\"CURSCANB\",\n \"STARTHI\",\"STARTLO\",\"CURSORHI\",\"CURSORLO\",\"PENHI\",\"PENLO\"];\n\n Card.CRTC.EGA_REGS = [\n \"HTOTAL\",\"HDEND\",\"HBSTART\",\"HBEND\",\"HRSTART\",\"HREND\",\n \"VTOTAL\",\"OVERFLOW\",\"PRESCAN\",\"MAXSCAN\",\"CURSCAN\",\"CURSCANB\",\n \"STARTHI\",\"STARTLO\",\"CURSORHI\",\"CURSORLO\",\"VRSTART\",\"VREND\",\n \"VDEND\",\"OFFSET\",\"UNDERLINE\",\"VBSTART\",\"VBEND\",\"MODECTRL\",\"LINECOMP\"];\n}\n\n/*\n * EGA/VGA Input Status 1 Register (port 0x3DA)\n *\n * STATUS1 bit 0 has confusing documentation: the EGA Tech Ref says \"Logical 0 indicates the CRT raster is in a\n * horizontal or vertical retrace interval\", whereas the VGA Tech Ref says \"Logical 1 indicates a horizontal or\n * vertical retrace interval,\" but then clarifies: \"This bit is the real-time status of the INVERTED display enable\n * signal\". So, instead of calling bit 0 DISP_ENABLE (or more precisely, DISP_ENABLE_INVERTED), it's simply RETRACE.\n *\n * STATUS1 diagnostic bits 5 and 4 are set according to the Card.ATC.PLANES.MUX bits:\n *\n * MUX Bit 5 Bit 4\n * --- ---- ----\n * 00: Red Blue\n * 01: SecBlue Green\n * 10: SecRed SecGreen\n * 11: unused unused\n */\nCard.STATUS1 = {\n PORT: 0x3DA,\n RETRACE: 0x01, // bit 0: logical OR of horizontal and vertical retrace\n VRETRACE: 0x08, // bit 3: set during vertical retrace interval\n DIAGNOSTIC: 0x30, // bits 5,4 are controlled by the Card.ATC.PLANES.MUX bits\n RESERVED: 0xC6\n};\n\n/*\n * EGA/VGA Attribute Controller Registers (port 0x3C0: regATCIndx and regATCData)\n *\n * The current ATC INDX value is stored in cardEGA.regATCIndx (including the Card.ATC.INDX_ENABLE bit), and the\n * ATC DATA values are stored in cardEGA.regATCData. The state of the ATC INDX/DATA flip-flop is stored in fATCData.\n *\n * Note that the ATC palette registers (0x0-0xf) all use the following 6 bit assignments, with bits 6 and 7 unused:\n *\n * 0: Blue\n * 1: Green\n * 2: Red\n * 3: SecBlue (or mono video)\n * 4: SecGreen (or intensity)\n * 5: SecRed\n */\nCard.ATC = {\n PORT: 0x3C0, // ATC Index/Data Port\n INDX_MASK: 0x1F,\n INDX_PAL_ENABLE: 0x20, // must be clear when loading palette registers\n PALETTE: {\n INDX: 0x00, // 16 registers: 0x00 - 0x0F\n MASK: 0x3f,\n BLUE: 0x01,\n GREEN: 0x02,\n RED: 0x04,\n SECBLUE: 0x08,\n BRIGHT: 0x10, // NOTE: The IBM EGA manual (p.56) also calls this the \"intensity\" bit\n SECGREEN: 0x10,\n SECRED: 0x20\n },\n PALETTE_REGS: 0x10, // 16 total palette registers\n MODE: {\n INDX: 0x10, // ATC Mode Control Register\n GRAPHICS: 0x01, // bit 0: set for graphics mode, clear for alphanumeric mode\n MONOEM: 0x02, // bit 1: set for monochrome emulation mode, clear for color emulation\n TEXT_9DOT: 0x04, // bit 2: set for 9-dot replication in character codes 0xC0-0xDF\n BLINK_ENABLE: 0x08, // bit 3: set for text/graphics blink, clear for background intensity\n RESERVED: 0x10, // bit 4: reserved\n PANCOMPAT: 0x20, // bit 5: set for pixel-panning compatibility\n PELWIDTH: 0x40, // bit 6: set for 256-color modes, clear for all other modes\n COLORSEL_ALL: 0x80 // bit 7: set to enable all COLORSEL bits (ie, COLORSEL.DAC_BIT5 and COLORSEL.DAC_BIT4)\n },\n OVERSCAN: {\n INDX: 0x11 // ATC Overscan Color Register\n },\n PLANES: {\n INDX: 0x12, // ATC Color Plane Enable Register\n MASK: 0x0F,\n MUX: 0x30,\n RESERVED: 0xC0\n },\n HPAN: {\n INDX: 0x13, // ATC Horizontal PEL Panning Register\n SHIFT_LEFT: 0x0F // bits 0-3 indicate # of pixels to shift left\n },\n COLORSEL: {\n INDX: 0x14, // ATC Color Select Register (VGA only)\n DAC_BIT7: 0x08, // specifies bit 7 of DAC values (ignored in 256-color modes)\n DAC_BIT6: 0x04, // specifies bit 6 of DAC values (ignored in 256-color modes)\n DAC_BIT5: 0x02, // specifies bit 5 of DAC values (if ATC.MODE.COLORSEL_ALL is set; ignored in 256-color modes)\n DAC_BIT4: 0x01 // specifies bit 4 of DAC values (if ATC.MODE.COLORSEL_ALL is set; ignored in 256-color modes)\n },\n TOTAL_REGS: 0x14\n};\n\nif (DEBUGGER) {\n Card.ATC.REGS = [\n \"ATC00\",\"ATC01\",\"ATC02\",\"ATC03\",\"ATC04\",\"ATC05\",\"ATC06\",\"ATC07\",\n \"ATC08\",\"ATC09\",\"ATC0A\",\"ATC0B\",\"ATC0C\",\"ATC0D\",\"ATC0E\",\"ATC0F\", \"ATCMODE\",\"OVERSCAN\",\"PLANES\",\"HPAN\"];\n}\n\n/*\n * EGA/VGA Feature Control Register (port 0x3BA or 0x3DA: regFeat)\n *\n * The EGA BIOS writes 0x1 to Card.FEAT_CTRL.BITS and reads Card.STATUS0.FEAT, then writes 0x2 to\n * Card.FEAT_CTRL.BITS and reads Card.STATUS0.FEAT. The bits from the first and second reads are shifted\n * into the high nibble of the byte at 40:88h.\n */\nCard.FEAT_CTRL = {\n PORT_MONO: 0x3BA, // write port address (other than the two bits below, the rest are reserved and/or unused)\n PORT_COLOR: 0x3DA, // write port address (other than the two bits below, the rest are reserved and/or unused)\n PORT_READ: 0x3CA, // read port address (VGA only)\n BITS: 0x03 // feature control bits\n};\n\n/*\n * EGA/VGA Miscellaneous Output Register (port 0x3C2: regMisc)\n */\nCard.MISC = {\n PORT_WRITE: 0x3C2, // write port address (EGA and VGA)\n PORT_READ: 0x3CC, // read port address (VGA only)\n IO_SELECT: 0x01, // 0 sets CRT ports to 0x3Bn, 1 sets CRT ports to 0x3Dn\n ENABLE_RAM: 0x02, // 0 disables video RAM, 1 enables\n CLOCK_SELECT: 0x0C, // 0x0: 14Mhz I/O clock, 0x4: 16Mhz on-board clock, 0x8: external clock, 0xC: unused\n DISABLE_DRV: 0x10, // 0 activates internal video drivers, 1 activates feature connector direct drive outputs\n PAGE_ODD_EVEN: 0x20, // 0 selects the low 64Kb page of video RAM for text modes, 1 selects the high page\n HPOLARITY: 0x40, // 0 selects positive horizontal retrace\n VPOLARITY: 0x80 // 0 selects positive vertical retrace\n};\n\n/*\n * EGA/VGA Input Status 0 Register (port 0x3C2: regStatus0)\n */\nCard.STATUS0 = {\n PORT: 0x3C2, // read-only (aka STATUS0, to distinguish it from PORT_CGA_STATUS)\n RESERVED: 0x0F,\n SWSENSE: 0x10,\n SWSENSE_SHIFT: 4,\n FEAT: 0x60, // VGA: reserved\n INTERRUPT: 0x80 // 1: video is being displayed; 0: vertical retrace is occurring\n};\n\n/*\n * VGA Subsystem Enable Register (port 0x3C3: regVGAEnable)\n */\nCard.VGA_ENABLE = {\n PORT: 0x3C3,\n ENABLED: 0x01, // when set, all VGA I/O and memory decoding is enabled; otherwise disabled (TODO: Implement)\n RESERVED: 0xFE\n};\n\n/*\n * EGA/VGA Sequencer Registers (ports 0x3C4/0x3C5: regSEQIndx and regSEQData)\n */\nCard.SEQ = {\n INDX: {\n PORT: 0x3C4, // Sequencer Index Port\n MASK: 0x07\n },\n DATA: {\n PORT: 0x3C5 // Sequencer Data Port\n },\n RESET: {\n INDX: 0x00, // Sequencer Reset Register\n ASYNC: 0x01,\n SYNC: 0x02\n },\n CLOCKING: {\n INDX: 0x01, // Sequencer Clocking Mode Register\n DOTS8: 0x01, // 1: 8 dots; 0: 9 dots\n BANDWIDTH: 0x02, // 0: CRTC has access 4 out of every 5 cycles (for high-res modes); 1: CRTC has access 2 out of 5 (VGA: reserved)\n SHIFTLOAD: 0x04,\n DOTCLOCK: 0x08, // 0: normal dot clock; 1: master clock divided by two (used for 320x200 modes: 0, 1, 4, 5, and D)\n SHIFT4: 0x10, // VGA only\n SCREEN_OFF: 0x20, // VGA only\n RESERVED: 0xC0\n },\n MAPMASK: {\n INDX: 0x02, // Sequencer Map Mask Register\n PL0: 0x01,\n PL1: 0x02,\n PL2: 0x04,\n PL3: 0x08,\n MAPS: 0x0F,\n RESERVED: 0xF0\n },\n CHARMAP: {\n INDX: 0x03, // Sequencer Character Map Select Register\n SELB: 0x03, // 0x0: 1st 8Kb of plane 2; 0x1: 2nd 8Kb; 0x2: 3rd 8Kb; 0x3: 4th 8Kb\n SELA: 0x0C, // 0x0: 1st 8Kb of plane 2; 0x4: 2nd 8Kb; 0x8: 3rd 8Kb; 0xC: 4th 8Kb\n SELB_HI: 0x10, // VGA only\n SELA_HI: 0x20 // VGA only\n },\n MEMMODE: {\n INDX: 0x04, // Sequencer Memory Mode Register\n ALPHA: 0x01, // set for alphanumeric (A/N) mode, clear for graphics (APA or \"All Points Addressable\") mode (EGA only)\n EXT: 0x02, // set if memory expansion installed, clear if not installed\n SEQUENTIAL: 0x04, // set for sequential memory access, clear for mapping even addresses to planes 0/2, odd addresses to planes 1/3\n CHAIN4: 0x08 // VGA only: set to select memory map (plane) based on low 2 bits of address\n },\n TOTAL_REGS: 0x05\n};\n\nif (DEBUGGER) Card.SEQ.REGS = [\"RESET\",\"CLOCKING\",\"MAPMASK\",\"CHARMAP\",\"MEMMODE\"];\n\n/*\n * VGA Digital-to-Analog Converter (DAC) Registers (regDACMask, regDACState, regDACAddr, and regDACData)\n *\n * To write DAC data, write an address to DAC.ADDR.PORT_WRITE, then write 3 bytes to DAC.DATA.PORT; the low 6 bits\n * of each byte will be concatenated to form an 18-bit DAC value (red is least significant, followed by green, then blue).\n * When the final byte is received, the 18-bit DAC value is updated and regDACAddr is auto-incremented.\n *\n * To read DAC data, the process is similar, but the initial address is written to DAC.ADDR.PORT_READ instead.\n *\n * DAC.STATE.PORT and DAC.ADDR.PORT_WRITE can be read at any time and will not interfere with a read or write operation\n * in progress. To prevent \"snow\", reading or writing DAC values should be limited to retrace intervals (see regStatus1),\n * or by using the SCREEN_OFF bit in the SEQ.CLOCKING register.\n */\nCard.DAC = {\n MASK: {\n PORT: 0x3C6, // initialized to 0xFF and should not be changed\n DEFAULT: 0xFF\n },\n STATE: {\n PORT: 0x3C7,\n MODE_WRITE: 0x00, // the DAC is in write mode if bits 0 and 1 are clear\n MODE_READ: 0x03 // the DAC is in read mode if bits 0 and 1 are set\n },\n ADDR: {\n PORT_READ: 0x3C7, // write to initiate a read\n PORT_WRITE: 0x3C8 // write to initiate a write; read to determine the current ADDR\n },\n DATA: {\n PORT: 0x3C9\n },\n TOTAL_REGS: 0x100\n};\n\n/*\n * EGA/VGA Graphics Controller Registers (ports 0x3CE/0x3CF: regGRCIndx and regGRCData)\n *\n * The VGA added Write Mode 3, which is described as follows:\n *\n * \"Each map is written with 8 bits of the value contained in the Set/Reset register for that map\n * (the Enable Set/Reset register has no effect). Rotated system microprocessor data is ANDed with the\n * Bit Mask register data to form an 8-bit value that performs the same function as the Bit Mask register\n * does in write modes 0 and 2.\"\n */\nCard.GRC = {\n POS1_PORT: 0x3CC, // EGA only, write-only\n POS2_PORT: 0x3CA, // EGA only, write-only\n INDX: {\n PORT: 0x3CE, // GRC Index Port\n MASK: 0x0F\n },\n DATA: {\n PORT: 0x3CF // GRC Data Port\n },\n SRESET: {\n INDX: 0x00 // GRC Set/Reset Register (write-only; each bit used only if WRITE.MODE0 and corresponding ESR bit set)\n },\n ESRESET: {\n INDX: 0x01 // GRC Enable Set/Reset Register\n },\n COLORCMP: {\n INDX: 0x02 // GRC Color Compare Register\n },\n DATAROT: {\n INDX: 0x03, // GRC Data Rotate Register\n COUNT: 0x07,\n AND: 0x08,\n OR: 0x10,\n XOR: 0x18,\n FUNC: 0x18,\n MASK: 0x1F\n },\n READMAP: {\n INDX: 0x04, // GRC Read Map Select Register\n NUM: 0x03\n },\n MODE: {\n INDX: 0x05, // GRC Mode Register\n WRITE: {\n MODE0: 0x00, // write mode 0: each plane written with CPU data, rotated as needed, unless SR enabled\n MODE1: 0x01, // write mode 1: each plane written with contents of the processor latches (loaded by a read)\n MODE2: 0x02, // write mode 2: memory plane N is written with 8 bits matching data bit N\n MODE3: 0x03, // write mode 3: VGA only\n MASK: 0x03\n },\n TEST: 0x04,\n READ: {\n MODE0: 0x00, // read mode 0: read map mode\n MODE1: 0x08, // read mode 1: color compare mode\n MASK: 0x08\n },\n EVENODD: 0x10,\n SHIFT: 0x20,\n COLOR256: 0x40 // VGA only\n },\n MISC: {\n INDX: 0x06, // GRC Miscellaneous Register\n GRAPHICS: 0x01, // set for graphics mode addressing, clear for text mode addressing\n CHAIN: 0x02, // set for odd/even planes selected with odd/even values of the processor AO bit\n MAPMEM: 0x0C, //\n MAPA0128: 0x00, //\n MAPA064: 0x04, //\n MAPB032: 0x08, //\n MAPB832: 0x0C //\n },\n COLORDC: {\n INDX: 0x07 // GRC Color \"Don't Care\" Register\n },\n BITMASK: {\n INDX: 0x08 // GRC Bit Mask Register\n },\n TOTAL_REGS: 0x09\n};\n\nif (DEBUGGER) Card.GRC.REGS = [\"SRESET\",\"ESRESET\",\"COLORCMP\",\"DATAROT\",\"READMAP\",\"GRCMODE\",\"GRCMISC\",\"COLORDC\",\"BITMASK\"];\n\n/*\n * EGA Memory Access Functions\n *\n * Here's where we define all the getMemoryAccess() functions that know how to deal with \"planar\" EGA memory,\n * which consists of 32-bit values for every byte of address space, allowing us to internally store plane 0\n * bytes in bits 0-7, plane 1 bytes in bits 8-15, plane 2 bytes in bits 16-23, and plane 3 bytes in bits 24-31.\n *\n * All our functions have slightly more overhead than the standard Bus memory access functions, because the\n * offset (off) parameter is block-relative, which we must transform into a buffer-relative offset. Fortunately,\n * all our Memory objects know this and have already recorded their buffer-relative offset in \"this.offset\".\n *\n * Also, the EGA includes a set of latches, one for each plane, which must be updated on most reads/writes;\n * we rely on the Memory object's \"this.controller\" property to give us access to the Card's state.\n *\n * And we take a little extra time to conditionally set fDirty on writes, meaning if a write did not actually\n * change the value of the memory, we will not set fDirty. The default write functions in memory.js don't take\n * that performance hit, but here, it may be worthwhile, because if it results in fewer dirty blocks, display\n * updates may be faster.\n *\n * Note that we don't have to worry about dealing with word accesses that straddle block boundaries, because\n * the Bus component automatically breaks those accesses into separate byte requests. Similarly, byte and word\n * values for the write functions have already been pre-masked by the Bus component to 8 and 16 bits, respectively.\n *\n * My motto: Be paranoid, but also be careful not to do any more work than you absolutely have to.\n *\n *\n * CGA Emulation on the EGA\n *\n * Modes 4/5 (320x200 low-res graphics) emulate the same buffer format that the CGA uses. To recap: 1 byte contains\n * 4 pixels (pixel 0 in bits 7-6, pixel 1 in bits 5-4, etc), and thus one row of pixels is 80 (0x50) bytes long.\n * Moreover, all even rows are stored in the first 8K of the video buffer (at 0xB8000), and all odd rows are stored\n * in the second 8K (at 0xBA000). Of each 8K, only 8000 (0x1F40) bytes are used (80 bytes X 100 rows); the remaining\n * 192 bytes of each 8K are unused.\n *\n * For these modes, the EGA's GRC.MODE is programmed with 0x30: Card.GRC.MODE.EVENODD and Card.GRC.MODE.SHIFT.\n * The latter claims to work by forming each 2-bit pixel with even bits from plane 0 and odd bits from plane 1;\n * however, I'm unclear how that works if even bytes are only written to plane 0 and odd bytes are only written to\n * plane 1, as Card.GRC.MODE.EVENODD implies, because plane 0 would never have any bits for the odd bytes, and\n * plane 1 would never have any bits for the even bytes. TODO: Figure this out.\n *\n *\n * Even/Odd Memory Access Functions\n *\n * The \"EVENODD\" functions deal with the EGA's default text-mode addressing, where EVEN addresses are mapped to\n * plane 0 (and 2) and ODD addresses are mapped to plane 1 (and 3). This occurs when SEQ.MEMMODE.SEQUENTIAL is\n * clear (and GRC.MODE.EVENODD is set), turning address bit 0 (A0) into a \"plane select\" bit. Whether A0 is also\n * used as a memory address bit depends on CRTC.MODECTRL.BYTE_MODE: if it's set, then we're in \"Byte Mode\" and A0 is\n * used as-is; if it's clear, then we're in \"Word Mode\", and either A15 (when CRTC.MODECTRL.ADDR_WRAP is set) or A13\n * (when CRTC.MODECTRL.ADDR_WRAP is clear, typically when only 64Kb of EGA memory is installed) is substituted for A0.\n *\n * Note that A13 remains clear until addresses reach 8K, at which point we've spanned 32Kb of EGA memory, so it makes\n * sense to propagate A13 to A0 at that point, so that the next 8K of addresses start using ODD instead of EVEN bytes,\n * and no memory is wasted on a 64Kb EGA card.\n *\n * These functions, however, don't yet deal with all those subtleties: A0 is currently used only as a \"plane select\"\n * bit and set to zero for addressing purposes, meaning that only the EVEN bytes in EGA memory will ever be used.\n * TODO: Implement the subtleties.\n */\n\n/*\n * Values returned by getCardAccess(); the high byte describes the read mode, and the low byte describes the write mode.\n *\n * V2 should never appear in any values used by getCardAccess() or setCardAccess(); the sole purpose of V2 is to\n * distinguish newer (V2) access values from older (V1) access values in saved contexts. It's set when the context\n * is saved, and cleared when the context is restored. Thus, if V2 is not set on restore, we assume we're dealing with\n * a V1 value, so we run it through the V1 table (below) to produce a V2 value. Hopefully at some point V1 contexts\n * can be deprecated, and the V2 bit can be eliminated/repurposed.\n */\nCard.ACCESS = {\n READ: { // READ values are designed to be OR'ed with WRITE values\n MODE0: 0x0400,\n MODE1: 0x0500,\n EVENODD: 0x1000,\n CHAIN4: 0x4000,\n MASK: 0xFF00\n },\n WRITE: { // and WRITE values are designed to be OR'ed with READ values\n MODE0: 0x0000,\n MODE1: 0x0001,\n MODE2: 0x0002,\n MODE3: 0x0003, // VGA only\n CHAIN4: 0x0004,\n EVENODD: 0x0010,\n ROT: 0x0020,\n AND: 0x0060,\n OR: 0x00A0,\n XOR: 0x00E0,\n MASK: 0x00FF\n },\n V2: (0x80000000|0) // this is a signature bit used ONLY to differentiate V2 access values from V1\n};\n\n/*\n * Table of older (V1) access values and their corresponding new values; the new values are similar but more orthogonal\n */\nCard.ACCESS.V1 = [];\nCard.ACCESS.V1[0x0002] = Card.ACCESS.READ.MODE0;\nCard.ACCESS.V1[0x0003] = Card.ACCESS.READ.MODE0 | Card.ACCESS.READ.EVENODD;\nCard.ACCESS.V1[0x0010] = Card.ACCESS.READ.MODE1;\nCard.ACCESS.V1[0x0200] = Card.ACCESS.WRITE.MODE0;\nCard.ACCESS.V1[0x0400] = Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.ROT;\nCard.ACCESS.V1[0x0600] = Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.AND;\nCard.ACCESS.V1[0x0A00] = Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.OR;\nCard.ACCESS.V1[0x0E00] = Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.XOR;\nCard.ACCESS.V1[0x0300] = Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.EVENODD;\nCard.ACCESS.V1[0x1000] = Card.ACCESS.WRITE.MODE1;\nCard.ACCESS.V1[0x2000] = Card.ACCESS.WRITE.MODE2;\nCard.ACCESS.V1[0x6000] = Card.ACCESS.WRITE.MODE2 | Card.ACCESS.WRITE.AND;\nCard.ACCESS.V1[0xA000] = Card.ACCESS.WRITE.MODE2 | Card.ACCESS.WRITE.OR;\nCard.ACCESS.V1[0xE000] = Card.ACCESS.WRITE.MODE2 | Card.ACCESS.WRITE.XOR;\n\n/**\n * readByteMode0(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} [addr]\n * @return {number}\n */\nCard.ACCESS.readByteMode0 = function readByteMode0(off, addr)\n{\n off += this.offset;\n var dw = this.controller.latches = this.adw[off];\n return (dw >> this.controller.nReadMapShift) & 0xff;\n};\n\n/**\n * readByteMode0Chain4(off, addr)\n *\n * See writeByteMode0Chain4 for a description of how writes are distributed across planes.\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} [addr]\n * @return {number}\n */\nCard.ACCESS.readByteMode0Chain4 = function readByteMode0Chain4(off, addr)\n{\n var idw = (off & ~0x3) + this.offset;\n var shift = (off & 0x3) << 3;\n return ((this.controller.latches = this.adw[idw]) >> shift) & 0xff;\n};\n\n/**\n * readByteMode0EvenOdd(off, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} [addr]\n * @return {number}\n */\nCard.ACCESS.readByteMode0EvenOdd = function readByteMode0EvenOdd(off, addr)\n{\n /*\n * TODO: As discussed in getCardAccess(), we need to run some tests on real EGA/VGA hardware to determine\n * exactly what gets latched (ie, from which address) when EVENODD is in effect. Whatever we learn may\n * also dictate a special EVENODD function for READ.MODE1 as well.\n */\n off += this.offset;\n var idw = off & ~0x1;\n var dw = this.controller.latches = this.adw[idw];\n return (!(off & 1)? dw : (dw >> 8)) & 0xff;\n};\n\n/**\n * readByteMode1(off, addr)\n *\n * This mode requires us to step through each of the 8 sets of 4 bits in the specified DWORD of video memory,\n * returning a 1 wherever all 4 match the Color Compare (COLORCMP) Register and a 0 otherwise. An added wrinkle\n * is that the Color Don't Care (COLORDC) Register can specify that any/all/none of the 4 bits must be ignored.\n *\n * We perform the comparison from most to least significant bit, because that matches how the nColorCompare and\n * nColorDontCare masks are initialized; we could have gone either way, but this is more consistent with the rest\n * of the component (eg, pixels are drawn across the screen from left to right, starting with the most significant\n * bit of each byte).\n *\n * Also note that, while not well-documented, this mode also affects the internal latches, so we make sure those\n * are updated as well.\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} [addr]\n * @return {number}\n */\nCard.ACCESS.readByteMode1 = function readByteMode1(off, addr)\n{\n off += this.offset;\n var dw = this.controller.latches = this.adw[off];\n /*\n * Minor optimization: we could pre-mask nColorCompare with nColorDontCare, whenever either register\n * is updated, but that's a drop in the bucket compared to all the other work this function must do.\n */\n var mask = this.controller.nColorDontCare;\n var color = this.controller.nColorCompare & mask;\n var b = 0, bit = 0x80;\n while (bit) {\n if ((dw & mask) == color) b |= bit;\n color >>>= 1; mask >>>= 1; bit >>= 1;\n }\n return b;\n};\n\n/**\n * writeByteMode0(off, b, addr)\n *\n * Supporting Set/Reset means that for every plane for which Set/Reset is enabled, we must\n * replace the corresponding byte in dw with a byte of zeros or ones. This is accomplished with\n * nSetMapMask, nSetMapData, and nSetMapBits. nSetMapMask is the inverse of the ESRESET bits,\n * because we use it to mask the processor data, nSetMapData records the desired SRESET bits,\n * and nSetMapBits contains the bits to replace those that we masked in the processor data.\n *\n * We could have done this:\n *\n * dw = (dw & this.controller.nSetMapMask) | (this.controller.nSetMapData & ~this.controller.nSetMapMask)\n *\n * but by maintaining nSetMapBits equal to (nSetMapData & ~nSetMapMask), we are able to make\n * the writes slightly more efficient.\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode0 = function writeByteMode0(off, b, addr)\n{\n var idw = off + this.offset;\n var dw = b | (b << 8) | (b << 16) | (b << 24);\n dw = (dw & this.controller.nSetMapMask) | this.controller.nSetMapBits;\n dw = (dw & this.controller.nBitMapMask) | (this.controller.latches & ~this.controller.nBitMapMask);\n dw = (dw & this.controller.nSeqMapMask) | (this.adw[idw] & ~this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode0(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode0Chain4(off, b, addr)\n *\n * This is how we distribute writes of 0xff across the address space to the planes (assuming that all\n * planes are enabled by the Sequencer's MAPMASK register):\n *\n * off idw adw[idw]\n * ------ ------ ----------\n * 0x0000: 0x0000 0x000000ff\n * 0x0001: 0x0000 0x0000ff00\n * 0x0002: 0x0000 0x00ff0000\n * 0x0003: 0x0000 0xff000000\n * 0x0004: 0x0004 0x000000ff\n * 0x0005: 0x0004 0x0000ff00\n * 0x0006: 0x0004 0x00ff0000\n * 0x0007: 0x0004 0xff000000\n * ...\n *\n * Some VGA emulations calculate the video buffer index (idw) by shifting the offset (off) right 2 bits,\n * instead of simply masking off the low 2 bits, as we do here. That would be a more \"pleasing\" arrangement,\n * because we would be using sequential video buffer locations, instead of multiples of 4, and would match how\n * pixels are stored in \"Mode X\". However, I don't think that's how CHAIN4 modes operate (although that still\n * needs to be confirmed, because multiple sources conflict on this point). TODO: Confirm CHAIN4 operation on\n * actual VGA hardware, including the extent to which ALU and other writeByteMode0() functionality needs to\n * be folded into this.\n *\n * Address decoding may not matter that much, as long as both the read and write CHAIN4 functions decode their\n * addresses in exactly the same manner; we'd only get into trouble with software that \"unchained\" or otherwise\n * reconfigured the planes and then made assumptions about existing data in the video buffer.\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode0Chain4 = function writeByteMode0Chain4(off, b, addr)\n{\n var idw = (off & ~0x3) + this.offset;\n var shift = (off & 0x3) << 3;\n /*\n * TODO: Consider adding a separate \"unmasked\" version of this CHAIN4 write function when nSeqMapMask is -1\n * (or removing nSeqMapMask from the equation altogether, if CHAIN4 is never used with any planes disabled).\n */\n var dw = ((b << shift) & this.controller.nSeqMapMask) | (this.adw[idw] & ~((0xff << shift) & this.controller.nSeqMapMask));\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode0Chain4(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode0EvenOdd(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode0EvenOdd = function writeByteMode0EvenOdd(off, b, addr)\n{\n off += this.offset;\n var dw = b | (b << 8) | (b << 16) | (b << 24);\n /*\n * When even/odd addressing is enabled, nSeqMapMask must be cleared for planes 1\n * and 3 if the address is even, and cleared for planes 0 and 2 if the address is odd.\n */\n var idw = off & ~0x1;\n dw = (dw & this.controller.nBitMapMask) | (this.controller.latches & ~this.controller.nBitMapMask);\n var maskMaps = this.controller.nSeqMapMask & (idw == off? 0x00ff00ff : (0xff00ff00|0));\n dw = (dw & maskMaps) | (this.adw[idw] & ~maskMaps);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode0EvenOdd(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode0Rot(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode0Rot = function writeByteMode0Rot(off, b, addr)\n{\n var idw = off + this.offset;\n b = ((b >> this.controller.nDataRotate) | (b << (8 - this.controller.nDataRotate)) & 0xff);\n var dw = b | (b << 8) | (b << 16) | (b << 24);\n dw = (dw & this.controller.nSetMapMask) | this.controller.nSetMapBits;\n dw = (dw & this.controller.nBitMapMask) | (this.controller.latches & ~this.controller.nBitMapMask);\n dw = (dw & this.controller.nSeqMapMask) | (this.adw[idw] & ~this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode0Rot(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode0And(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode0And = function writeByteMode0And(off, b, addr)\n{\n var idw = off + this.offset;\n b = ((b >> this.controller.nDataRotate) | (b << (8 - this.controller.nDataRotate)) & 0xff);\n var dw = b | (b << 8) | (b << 16) | (b << 24);\n dw = (dw & this.controller.nSetMapMask) | this.controller.nSetMapBits;\n dw &= this.controller.latches;\n dw = (dw & this.controller.nBitMapMask) | (this.controller.latches & ~this.controller.nBitMapMask);\n dw = (dw & this.controller.nSeqMapMask) | (this.adw[idw] & ~this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode0And(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode0Or(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode0Or = function writeByteMode0Or(off, b, addr)\n{\n var idw = off + this.offset;\n b = ((b >> this.controller.nDataRotate) | (b << (8 - this.controller.nDataRotate)) & 0xff);\n var dw = b | (b << 8) | (b << 16) | (b << 24);\n dw = (dw & this.controller.nSetMapMask) | this.controller.nSetMapBits;\n dw |= this.controller.latches;\n dw = (dw & this.controller.nBitMapMask) | (this.controller.latches & ~this.controller.nBitMapMask);\n dw = (dw & this.controller.nSeqMapMask) | (this.adw[idw] & ~this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode0Or(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode0Xor(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode0Xor = function writeByteMode0Xor(off, b, addr)\n{\n var idw = off + this.offset;\n b = ((b >> this.controller.nDataRotate) | (b << (8 - this.controller.nDataRotate)) & 0xff);\n var dw = b | (b << 8) | (b << 16) | (b << 24);\n dw = (dw & this.controller.nSetMapMask) | this.controller.nSetMapBits;\n dw ^= this.controller.latches;\n dw = (dw & this.controller.nBitMapMask) | (this.controller.latches & ~this.controller.nBitMapMask);\n dw = (dw & this.controller.nSeqMapMask) | (this.adw[idw] & ~this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode0Xor(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode1(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (ignored; the EGA latches provide the source data)\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode1 = function writeByteMode1(off, b, addr)\n{\n var idw = off + this.offset;\n var dw = (this.adw[idw] & ~this.controller.nSeqMapMask) | (this.controller.latches & this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode1(\" + Str.toHexLong(addr) + \"): \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode1EvenOdd(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (ignored; the EGA latches provide the source data)\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode1EvenOdd = function writeByteMode1EvenOdd(off, b, addr)\n{\n /*\n * TODO: As discussed in getCardAccess(), we need to run some tests on real EGA/VGA hardware to\n * determine exactly where latches are written (ie, to which address) when EVENODD is in effect.\n */\n off += this.offset;\n //\n // When even/odd addressing is enabled, nSeqMapMask must be cleared for planes 1 and 3 if\n // the address is even, and cleared for planes 0 and 2 if the address is odd.\n //\n var idw = off & ~0x1;\n var maskMaps = this.controller.nSeqMapMask & (idw == off? 0x00ff00ff : (0xff00ff00|0));\n var dw = (this.adw[idw] & ~maskMaps) | (this.controller.latches & maskMaps);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode1EvenOdd(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(dw));\n }\n};\n\n/**\n * writeByteMode2(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode2 = function writeByteMode2(off, b, addr)\n{\n var idw = off + this.offset;\n var dw = Video.aEGAByteToDW[b & 0xf];\n dw = (dw & this.controller.nBitMapMask) | (this.controller.latches & ~this.controller.nBitMapMask);\n dw = (dw & this.controller.nSeqMapMask) | (this.adw[idw] & ~this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode2(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode2And(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode2And = function writeByteMode2And(off, b, addr)\n{\n var idw = off + this.offset;\n var dw = Video.aEGAByteToDW[b & 0xf];\n dw &= this.controller.latches;\n dw = (dw & this.controller.nBitMapMask) | (this.controller.latches & ~this.controller.nBitMapMask);\n dw = (dw & this.controller.nSeqMapMask) | (this.adw[idw] & ~this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode2And(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode2Or(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode2Or = function writeByteMode2Or(off, b, addr)\n{\n var idw = off + this.offset;\n var dw = Video.aEGAByteToDW[b & 0xf];\n dw |= this.controller.latches;\n dw = (dw & this.controller.nBitMapMask) | (this.controller.latches & ~this.controller.nBitMapMask);\n dw = (dw & this.controller.nSeqMapMask) | (this.adw[idw] & ~this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode2Or(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode2Xor(off, b, addr)\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode2Xor = function writeByteMode2Xor(off, b, addr)\n{\n var idw = off + this.offset;\n var dw = Video.aEGAByteToDW[b & 0xf];\n dw ^= this.controller.latches;\n dw = (dw & this.controller.nBitMapMask) | (this.controller.latches & ~this.controller.nBitMapMask);\n dw = (dw & this.controller.nSeqMapMask) | (this.adw[idw] & ~this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode2Xor(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/**\n * writeByteMode3(off, b, addr)\n *\n * In MODE3, Set/Reset is always enabled, so the ESRESET bits (and therefore nSetMapMask and nSetMapBits)\n * are ignored; we look only at the SRESET bits, which are stored in nSetMapData.\n *\n * Unlike MODE0, we currently have no non-rotate function for MODE3. If performance dictates, we can add one;\n * ditto for other features like the Sequencer's MAPMASK register (nSeqMapMask).\n *\n * @this {Memory}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits; see cpu.setByte())\n * @param {number} [addr]\n */\nCard.ACCESS.writeByteMode3 = function writeByteMode3(off, b, addr)\n{\n var idw = off + this.offset;\n b = ((b >> this.controller.nDataRotate) | (b << (8 - this.controller.nDataRotate)) & 0xff);\n var dw = b | (b << 8) | (b << 16) | (b << 24);\n var dwMask = (dw & this.controller.nBitMapMask);\n dw = (this.controller.nSetMapData & dwMask) | (this.controller.latches & ~dwMask);\n dw = (dw & this.controller.nSeqMapMask) | (this.adw[idw] & ~this.controller.nSeqMapMask);\n if (this.adw[idw] != dw) {\n this.adw[idw] = dw;\n this.fDirty = true;\n }\n if (DEBUG && this.controller.video.messageEnabled(Messages.MEM | Messages.VIDEO)) {\n this.controller.video.printMessage(\"writeByteMode3(\" + Str.toHexLong(addr) + \"): \" + Str.toHexByte(b) + \" -> \" + Str.toHexLong(dw));\n }\n};\n\n/*\n * Mappings from getCardAccess() values to access functions above\n */\nCard.ACCESS.afn = [];\n\nCard.ACCESS.afn[Card.ACCESS.READ.MODE0] = Card.ACCESS.readByteMode0;\nCard.ACCESS.afn[Card.ACCESS.READ.MODE0 | Card.ACCESS.READ.CHAIN4] = Card.ACCESS.readByteMode0Chain4;\nCard.ACCESS.afn[Card.ACCESS.READ.MODE0 | Card.ACCESS.READ.EVENODD] = Card.ACCESS.readByteMode0EvenOdd;\nCard.ACCESS.afn[Card.ACCESS.READ.MODE1] = Card.ACCESS.readByteMode1;\n\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE0] = Card.ACCESS.writeByteMode0;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.ROT] = Card.ACCESS.writeByteMode0Rot;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.AND] = Card.ACCESS.writeByteMode0And;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.OR] = Card.ACCESS.writeByteMode0Or;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.XOR] = Card.ACCESS.writeByteMode0Xor;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.CHAIN4] = Card.ACCESS.writeByteMode0Chain4;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.EVENODD] = Card.ACCESS.writeByteMode0EvenOdd;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE1] = Card.ACCESS.writeByteMode1;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE1 | Card.ACCESS.WRITE.EVENODD] = Card.ACCESS.writeByteMode1EvenOdd;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE2] = Card.ACCESS.writeByteMode2;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE2 | Card.ACCESS.WRITE.AND] = Card.ACCESS.writeByteMode2And;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE2 | Card.ACCESS.WRITE.OR] = Card.ACCESS.writeByteMode2Or;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE2 | Card.ACCESS.WRITE.XOR] = Card.ACCESS.writeByteMode2Xor;\nCard.ACCESS.afn[Card.ACCESS.WRITE.MODE3] = Card.ACCESS.writeByteMode3;\n\n/**\n * @class Video\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass Video extends Component {\n /**\n * Video(parmsVideo, canvas, context, textarea, container)\n *\n * The Video component can be configured with the following (parmsVideo) properties:\n *\n * model: model (eg, \"mda\" for Monochrome Display Adapter)\n * mode: initial video mode (default is null, which selects a mode based on model)\n * screenWidth: width of the screen canvas, in pixels\n * screenHeight: height of the screen canvas, in pixels\n * screenColor: background color of the screen canvas (default is black)\n * flicker: 1 enables screen flicker, 0 disables (default is 0)\n * scale: true for font scaling, false (default) to center the display on the screen\n * charCols: number of character columns\n * charRows: number of character rows\n * fontROM: path to .rom file (or a JSON representation) containing the character set\n * touchScreen: string specifying desired touch-screen support (default is none)\n * autoLock: true to (attempt to) auto-lock the mouse to the canvas (default is false)\n * randomize: 1 enables screen randomization, 0 disables (default is 1)\n *\n * An EGA/VGA may specify the following additional properties:\n *\n * switches: string representing EGA switches (see \"SW1-SW4\" documentation below)\n * memory: the size of the EGA's on-board memory (overrides EGA's Video.cardSpecs)\n *\n * This calls the Bus to allocate a video buffer at the appropriate memory location whenever\n * a reset() or setMode() occurs; setMode() is called whenever a mode change is detected at\n * the port level, and whenever reset() is called. setMode() also invokes updateScreen(true),\n * which forces reallocation of our internal buffer (aCellCache) that mirrors the video buffer.\n *\n * Our initBus() handler defines a timer that periodically calls updateScreen() for each Video\n * instance. These updates should occur at a rate of 60 times/second, to update any blinking\n * elements (the cursor and any cells with the blink attribute), to compare/update the contents\n * of our internal buffer with the video buffer, and to render any differences between the two\n * buffers into the associated screen canvas, via either updateChar() or setPixel().\n *\n * Thanks to the Bus' new block-based memory manager that allows us to sparse-allocate memory\n * (in 4Kb increments on 20-bit buses, 16Kb increments on 24-bit buses), updateScreen()\n * can also ask the CPU for the \"dirty\" state of all the blocks underlying the video buffer,\n * bypassing the update completely if the buffer is still clean.\n *\n * Sadly, that optimization is defeated if the count of active blink elements is non-zero,\n * because we must rescan the entire buffer to locate and redraw them all; I'm assuming for now\n * that, more often than not, very few (if any) blink attributes will be present, and therefore\n * they're not worth a separate caching mechanism. If the only blinking element is the cursor,\n * that's no problem, as we redraw only the one cell containing the cursor (assuming the buffer\n * is otherwise clean).\n *\n * @this {Video}\n * @param {Object} parmsVideo\n * @param {HTMLCanvasElement} [canvas]\n * @param {CanvasRenderingContext2D} [context]\n * @param {HTMLTextAreaElement} [textarea]\n * @param {HTMLElement} [container]\n */\n constructor(parmsVideo, canvas, context, textarea, container)\n {\n super(\"Video\", parmsVideo, Messages.VIDEO);\n\n var video = this, sProp, sEvent;\n this.fGecko = Web.isUserAgent(\"Gecko/\");\n\n /*\n * This records the model specified (eg, \"mda\", \"cga\", \"ega\", \"vga\" or \"\" if none specified);\n * when a model is specified, it overrides whatever model we infer from the ChipSet's switches\n * (since those motherboard switches tell us only the type of monitor, not the type of card).\n */\n this.model = parmsVideo['model'];\n var aModelDefaults = Video.MODEL[this.model] || Video.MODEL['mda'];\n\n this.nCard = aModelDefaults[0];\n this.cbMemory = parmsVideo['memory'] || 0; // zero means fallback to the cardSpec's default size\n this.sSwitches = parmsVideo['switches'];\n this.nRandomize = parmsVideo['randomize'];\n if (this.nRandomize == null) this.nRandomize = 1;\n\n /*\n * powerUp() uses the default mode ONLY if ChipSet doesn't give us a default.\n */\n this.nModeDefault = parmsVideo['mode'];\n if (this.nModeDefault == null || Video.aModeParms[this.nModeDefault] == null) {\n this.nModeDefault = aModelDefaults[1];\n }\n\n /*\n * setDimensions() uses these values ONLY if it doesn't recognize the video mode.\n */\n this.nColsDefault = parmsVideo['charCols'];\n this.nRowsDefault = parmsVideo['charRows'];\n if (this.nColsDefault === undefined || this.nRowsDefault === undefined) {\n this.nColsDefault = Video.aModeParms[this.nModeDefault][0];\n this.nRowsDefault = Video.aModeParms[this.nModeDefault][1];\n }\n\n /*\n * setDimensions() uses these values unconditionally, as the machine has no idea what the\n * physical screen size should be.\n */\n this.cxScreen = parmsVideo['screenWidth'];\n this.cyScreen = parmsVideo['screenHeight'];\n\n /*\n * The font 'scale' parameter is deprecated (we ALWAYS scale now), and the internal fDoubleFont\n * setting is now always true, but it is retained in case we want to revisit the benefits (or lack\n * thereof) of font-doubling.\n * \n * When fScaleFont was false, one key difference was these additional lines in setDimensions():\n * \n * if (!this.fScaleFont) {\n * this.cxScreenCell = font.cxCell;\n * this.cyScreenCell = font.cyCell;\n * }\n * \n * which meant that if the font was only 8 pixels wide (instead of 16), then 40-column mode would\n * simply display normal size characters with large black borders on either of the screen.\n *\n * this.fScaleFont = parmsVideo['scale'];\n */\n this.fDoubleFont = true;\n\n this.canvasScreen = canvas;\n this.contextScreen = context;\n this.inputTextArea = textarea;\n this.inputScreen = textarea || canvas || null;\n\n /*\n * We now ensure that a colorScreen property is always set (to \"black\" if nothing else), and\n * set BOTH the canvas element's AND the container element's backgroundColor to match that color.\n *\n * This gives us option of doing \"cute\" things like flipping the canvas element's opacity from\n * 1 to 0 briefly, alternately revealing and hiding the underlying container element, to simulate\n * screen \"flicker\".\n */\n this.colorScreen = parmsVideo['screenColor'] || \"black\";\n this.opacityFlicker = (1 - (Web.getURLParm('flicker') || parmsVideo['flicker'] || 0)).toString();\n this.fOpacityReduced = false;\n if (canvas) canvas.style.backgroundColor = this.colorScreen;\n if (container) container.style.backgroundColor = this.colorScreen;\n\n /*\n * Support for disabling (or, less commonly, enabling) image smoothing, which all browsers\n * seem to support now (well, OK, I still have to test the latest MS Edge browser), despite\n * it still being labelled \"experimental technology\". Let's hope the browsers standardize\n * on this. I see other options emerging, like the CSS property \"image-rendering: pixelated\"\n * that's apparently been added to Chrome. Sigh.\n */\n var fSmoothing = parmsVideo['smoothing'];\n var sSmoothing = Web.getURLParm('smoothing');\n if (sSmoothing) fSmoothing = (sSmoothing == \"true\");\n if (fSmoothing != null) {\n sProp = Web.findProperty(this.contextScreen, 'imageSmoothingEnabled');\n if (sProp) this.contextScreen[sProp] = fSmoothing;\n }\n\n /*\n * initBus() will determine touch-screen support; for now, just record values and set defaults.\n */\n this.sTouchScreen = parmsVideo['touchScreen'];\n this.nTouchConfig = Video.TOUCH.NONE;\n\n /*\n * If a Mouse exists, we'll be notified when it requests our canvas, and we make a note of it\n * so that if lockPointer() is ever invoked, we can notify the Mouse.\n */\n this.mouse = null;\n this.fAutoLock = parmsVideo['autoLock'];\n\n /*\n * Originally, setMode() would map/unmap the video buffer ONLY when the active card changed,\n * because as long as an MDA or CGA remained active, its video buffer never changed. However,\n * since the EGA can change its video buffer on the fly, setMode() must also compare the card's\n * hard-coded and/or programmed buffer address/size to the \"active\" address/size; the latter\n * is recorded here.\n */\n this.addrBuffer = this.sizeBuffer = 0;\n\n /*\n * aFonts is an array of font objects indexed by FONT ID. Font characters are arranged\n * in 16x16 grids, with one grid per canvas object in the aCanvas array of each font object.\n *\n * Each element is a Font object that describes the font size and provides bitmaps for all the font\n * color permutations. aFonts.length will be non-zero if ANY fonts are loaded, but do NOT assume\n * that EVERY font has been loaded; check for the existence of a font by checking for its unique ID\n * within this sparse array.\n */\n this.aFonts = [];\n\n /*\n * Instead of (re)allocating a new color array every time getCardColors() is called, we preallocate\n * an array and simply update the entries as needed. Note that for an EGA (or a VGA operating in an\n * EGA-compatible mode), only the first 16 entries get used (derived from the ATC); only when a VGA\n * is operating in an 8bpp mode are 256 entries used (derived from the DAC rather than the ATC).\n */\n this.aRGB = new Array(this.nCard == Video.CARD.VGA? 256 : 16);\n this.fRGBValid = false; // whenever this is false, it signals getCardColors() to rebuild aRGB\n\n /*\n * Since I've not found clear documentation on a reliable way to check whether a particular DOM element\n * (other than the BODY element) has focus at any given time, I've added onfocus() and onblur() handlers\n * to the screen to maintain my own focus state.\n */\n this.fHasFocus = false;\n\n /*\n * Here's the gross code to handle full-screen support across all supported browsers. The lack of standards\n * is exasperating; browsers can't agree on 'Fullscreen' (most common) or 'FullScreen' (least common), and while\n * some browsers honor other browser prefixes, most don't. Event handlers tend to be more consistent (ie, all\n * lower-case).\n */\n this.container = container;\n if (this.container) {\n sProp = Web.findProperty(container, 'requestFullscreen') || Web.findProperty(container, 'requestFullScreen');\n if (sProp) {\n this.container.doFullScreen = container[sProp];\n sEvent = Web.findProperty(document, 'on', 'fullscreenchange');\n if (sEvent) {\n var sFullScreen = Web.findProperty(document, 'fullscreenElement') || Web.findProperty(document, 'fullScreenElement');\n document.addEventListener(sEvent, function onFullScreenChange() {\n video.notifyFullScreen(document[sFullScreen] != null);\n }, false);\n }\n sEvent = Web.findProperty(document, 'on', 'fullscreenerror');\n if (sEvent) {\n document.addEventListener(sEvent, function onFullScreenError() {\n video.notifyFullScreen();\n }, false);\n }\n }\n }\n\n /*\n * More gross code to handle pointer-locking support across all supported browsers.\n */\n if (this.inputScreen) {\n this.inputScreen.onfocus = function onFocusScreen() {\n return video.onFocusChange(true);\n };\n this.inputScreen.onblur = function onBlurScreen() {\n return video.onFocusChange(false);\n };\n this.inputScreen.lockPointer = (sProp = Web.findProperty(this.inputScreen, 'requestPointerLock')) && this.inputScreen[sProp];\n this.inputScreen.unlockPointer = (sProp = Web.findProperty(this.inputScreen, 'exitPointerLock')) && this.inputScreen[sProp];\n if (this.inputScreen.lockPointer) {\n sEvent = Web.findProperty(document, 'on', 'pointerlockchange');\n if (sEvent) {\n var sPointerLock = Web.findProperty(document, 'pointerLockElement');\n document.addEventListener(sEvent, function onPointerLockChange() {\n var fLocked = !!(sPointerLock && document[sPointerLock] === video.inputScreen);\n video.notifyPointerLocked(fLocked);\n }, false);\n }\n }\n }\n\n this.sFileURL = parmsVideo['fontROM'];\n\n if (this.sFileURL) {\n var sFileExt = Str.getExtension(this.sFileURL);\n if (sFileExt != \"json\") {\n this.sFileURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFileURL + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES;\n }\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * This is a notification issued by the Computer component, after all the other components (notably the CPU)\n * have had a chance to initialize.\n *\n * @this {Video}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n var video = this;\n\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n var nRandomize = +cmp.getMachineParm('randomize');\n if (nRandomize >= 0 && nRandomize <= 1) this.nRandomize = nRandomize;\n\n /*\n * nCard will be undefined if no model was explicitly set (whereas this.nCard is ALWAYS defined).\n */\n var aModel = Video.MODEL[this.model], nCard = aModel && aModel[0];\n\n /*\n * The only time we do NOT want to trap MDA ports is when the model has been explicitly set to CGA.\n */\n if (nCard !== Video.CARD.CGA) {\n bus.addPortInputTable(this, Video.aMDAPortInput);\n bus.addPortOutputTable(this, Video.aMDAPortOutput);\n }\n\n /*\n * Similarly, the only time we do NOT want to trap CGA ports is when the model is explicitly set to MDA.\n */\n if (nCard !== Video.CARD.MDA) {\n bus.addPortInputTable(this, Video.aCGAPortInput);\n bus.addPortOutputTable(this, Video.aCGAPortOutput);\n }\n\n /*\n * Note that in the case of EGA and VGA models, the above code ensures that we will trap both MDA and CGA\n * port ranges -- which is good, because both the EGA and VGA can be reprogrammed to respond to those ports,\n * but also potentially bad if you want to simulate a \"dual display\" system, where one of the displays is\n * driven by either an MDA or CGA.\n *\n * However, you should still be able to make that work by loading the MDA or CGA video component first, because\n * components should be initialized in the order they appear in the machine configuration file. Any attempt\n * by another component to trap the same ports should be ignored.\n */\n if (this.nCard >= Video.CARD.EGA) {\n bus.addPortInputTable(this, Video.aEGAPortInput);\n bus.addPortOutputTable(this, Video.aEGAPortOutput);\n }\n\n if (this.nCard == Video.CARD.VGA) {\n bus.addPortInputTable(this, Video.aVGAPortInput);\n bus.addPortOutputTable(this, Video.aVGAPortOutput);\n }\n\n if (DEBUGGER && dbg) {\n dbg.messageDump(Messages.VIDEO, function onDumpVideo(asArgs) {\n video.dumpVideo(asArgs);\n });\n }\n\n /*\n * If we have an associated keyboard, then ensure that the keyboard will be notified whenever the canvas\n * gets focus and receives input.\n */\n this.kbd = cmp.getMachineComponent(\"Keyboard\");\n if (this.kbd && this.canvasScreen) {\n for (var s in this.bindings) {\n if (s.indexOf(\"lock\") > 0) this.kbd.setBinding(\"led\", s, this.bindings[s]);\n }\n this.kbd.setBinding(this.inputTextArea? \"textarea\" : \"canvas\", \"screen\", this.inputScreen);\n }\n\n this.bEGASwitches = 0x09; // our default \"switches\" setting (see aEGAMonitorSwitches)\n this.chipset = cmp.getMachineComponent(\"ChipSet\");\n if (this.chipset && this.sSwitches) {\n if (this.nCard == Video.CARD.EGA) {\n this.bEGASwitches = this.chipset.parseDIPSwitches(this.sSwitches, this.bEGASwitches);\n }\n }\n\n /*\n * The default value for the 'touchScreen' parameter is an empty string; machine configs must explicitly\n * select one of the following values, via the 'touchscreen' attribute in the <video> element, to enable any\n * touch-screen support.\n */\n if (this.sTouchScreen == \"mouse\") {\n this.mouse = cmp.getMachineComponent(\"Mouse\");\n if (this.mouse) this.captureTouch(Video.TOUCH.MOUSE);\n }\n else if (this.sTouchScreen == \"keygrid\") {\n if (this.kbd) this.captureTouch(Video.TOUCH.KEYGRID);\n }\n\n /*\n * If no touch support was required or requested, we still want to do some minimal touch event processing;\n * eg, notifying the ChipSet component whenever a touchstart occurs, so that it can enable audio in response\n * to a user action on iOS devices.\n */\n if (!this.nTouchConfig) {\n this.captureTouch(Video.TOUCH.DEFAULT);\n }\n\n if (this.sFileURL) {\n var sProgress = \"Loading \" + this.sFileURL + \"...\";\n Web.getResource(this.sFileURL, null, true, function(sURL, sResponse, nErrorCode) {\n video.doneLoad(sURL, sResponse, nErrorCode);\n }, function(nState) {\n video.println(sProgress, Component.PRINT.PROGRESS);\n });\n }\n\n this.cpu.addTimer(this.id, function updateScreenTimer() {\n video.updateScreen();\n }, 1000 / Video.UPDATES_PER_SECOND);\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {Video}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"refresh\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var video = this;\n\n if (!this.bindings[sBinding]) {\n\n /*\n * We now save every binding that comes in, so that if there are bindings for \"caps-lock' and the like,\n * we can forward them to the Keyboard. TODO: Perhaps we should limit this to sHTMLType == \"led\", and collect\n * them in a separate object (eg, ledBindings), so that initBus() can safely enumerate JUST the LEDs. This\n * is what we do in PC8080. Be aware that's there's also sHTMLType == \"rled\" now, too.\n */\n this.bindings[sBinding] = control;\n\n switch (sBinding) {\n\n case \"fullScreen\":\n if (this.container && this.container.doFullScreen) {\n control.onclick = function onClickFullScreen() {\n if (DEBUG) video.printMessage(\"fullScreen()\");\n video.goFullScreen();\n };\n } else {\n if (DEBUG) this.log(\"FullScreen API not available\");\n control.parentNode.removeChild(/** @type {Node} */ (control));\n }\n return true;\n\n case \"lockPointer\":\n this.sLockMessage = control.textContent;\n if (this.inputScreen && this.inputScreen.lockPointer) {\n control.onclick = function onClickLockPointer() {\n if (DEBUG) video.printMessage(\"lockPointer()\");\n video.lockPointer(true);\n };\n } else {\n if (DEBUG) this.log(\"Pointer Lock API not available\");\n control.parentNode.removeChild(/** @type {Node} */ (control));\n }\n return true;\n\n case \"refresh\":\n control.onclick = function onClickRefresh() {\n if (DEBUG) video.printMessage(\"refreshScreen()\");\n video.updateScreen(true);\n };\n return true;\n\n default:\n break;\n }\n }\n return false;\n }\n\n /**\n * setFocus()\n *\n * @this {Video}\n */\n setFocus()\n {\n if (this.inputScreen) this.inputScreen.focus();\n }\n\n /**\n * getScreen()\n *\n * This is an interface used by the Mouse component, so that it can capture mouse events from the screen.\n *\n * @this {Video}\n * @param {Mouse} [mouse]\n * @return {Object|undefined}\n */\n getScreen(mouse)\n {\n this.mouse = mouse;\n return this.inputScreen;\n }\n\n /**\n * getTextArea()\n *\n * This is an interface used by the Computer component, so that it can display resource status messages.\n *\n * @this {Video}\n * @return {HTMLTextAreaElement|undefined}\n */\n getTextArea()\n {\n return this.inputTextArea;\n }\n\n /**\n * goFullScreen()\n *\n * @this {Video}\n * @return {boolean} true if request successful, false if not (eg, failed OR not supported)\n */\n goFullScreen()\n {\n var fSuccess = false;\n if (this.container) {\n if (this.container.doFullScreen) {\n /*\n * Styling the container with a width of \"100%\" and a height of \"auto\" works great when the aspect ratio\n * of our virtual screen is at least roughly equivalent to the physical screen's aspect ratio, but now that\n * we support virtual VGA screens with an aspect ratio of 1.33, that's very much out of step with modern\n * wide-screen monitors, which usually have an aspect ratio of 1.6 or greater.\n *\n * And unfortunately, none of the browsers I've tested appear to make any attempt to scale our container to\n * the physical screen's dimensions, so the bottom of our screen gets clipped. To prevent that, I reduce\n * the width from 100% to whatever percentage will accommodate the entire height of the virtual screen.\n *\n * NOTE: Mozilla recommends both a width and a height of \"100%\", but all my tests suggest that using \"auto\"\n * for height works equally well, so I'm sticking with it, because \"auto\" is also consistent with how I've\n * implemented a responsive canvas when the browser window is being resized.\n */\n var sWidth = \"100%\";\n var sHeight = \"auto\";\n if (screen && screen.width && screen.height) {\n var aspectPhys = screen.width / screen.height;\n var aspectVirt = this.cxScreen / this.cyScreen;\n if (aspectPhys > aspectVirt) {\n sWidth = Math.round(aspectVirt / aspectPhys * 100) + '%';\n }\n // TODO: We may need to someday consider the case of a physical screen with an aspect ratio < 1.0....\n }\n if (!this.fGecko) {\n this.container.style.width = sWidth;\n this.container.style.height = sHeight;\n } else {\n /*\n * Sadly, the above code doesn't work for Firefox, because as:\n *\n * http://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode\n *\n * explains:\n *\n * 'It's worth noting a key difference here between the Gecko and WebKit implementations at this time:\n * Gecko automatically adds CSS rules to the element to stretch it to fill the screen: \"width: 100%; height: 100%\".\n *\n * Which would be OK if Gecko did that BEFORE we're called, but apparently it does that AFTER, effectively\n * overwriting our careful calculations. So we style the inner element (canvasScreen) instead, which\n * requires even more work to ensure that the canvas is properly centered. FYI, this solution is consistent\n * with Mozilla's recommendation for working around their automatic CSS rules:\n *\n * '[I]f you're trying to emulate WebKit's behavior on Gecko, you need to place the element you want\n * to present inside another element, which you'll make fullscreen instead, and use CSS rules to adjust\n * the inner element to match the appearance you want.'\n */\n this.canvasScreen.style.width = sWidth;\n this.canvasScreen.style.width = sWidth;\n this.canvasScreen.style.display = \"block\";\n this.canvasScreen.style.margin = \"auto\";\n }\n this.container.style.backgroundColor = this.colorScreen;\n this.container.doFullScreen();\n fSuccess = true;\n }\n this.setFocus();\n }\n return fSuccess;\n }\n\n /**\n * notifyFullScreen(fFullScreen)\n *\n * @this {Video}\n * @param {boolean|undefined} [fFullScreen] (undefined if there was a full-screen error)\n */\n notifyFullScreen(fFullScreen)\n {\n if (!fFullScreen && this.container) {\n if (!this.fGecko) {\n this.container.style.width = this.container.style.height = \"\";\n } else {\n this.canvasScreen.style.width = this.canvasScreen.style.height = \"\";\n }\n }\n if (DEBUG) this.printMessage(\"notifyFullScreen(\" + fFullScreen + \")\", true);\n if (this.kbd) this.kbd.notifyEscape(fFullScreen == true);\n }\n\n /**\n * lockPointer()\n *\n * @this {Video}\n * @param {boolean} fLock\n * @return {boolean} true if request successful, false if not (eg, failed OR not supported)\n */\n lockPointer(fLock)\n {\n var fSuccess = false;\n if (this.inputScreen && this.mouse) {\n if (fLock) {\n if (this.inputScreen.lockPointer) {\n this.inputScreen.lockPointer();\n this.mouse.notifyPointerLocked(true);\n fSuccess = true;\n }\n } else {\n if (this.inputScreen.unlockPointer) {\n this.inputScreen.unlockPointer();\n this.mouse.notifyPointerLocked(false);\n fSuccess = true;\n }\n }\n this.setFocus();\n }\n return fSuccess;\n }\n\n /**\n * notifyPointerActive(fActive)\n *\n * @this {Video}\n * @param {boolean} fActive\n * @return {boolean} true if autolock enabled AND pointer lock supported, false if not\n */\n notifyPointerActive(fActive)\n {\n if (this.fAutoLock) {\n return this.lockPointer(fActive);\n }\n return false;\n }\n\n /**\n * notifyPointerLocked(fLocked)\n *\n * @this {Video}\n * @param {boolean} fLocked\n */\n notifyPointerLocked(fLocked)\n {\n if (this.mouse) {\n this.mouse.notifyPointerLocked(fLocked);\n if (this.kbd) this.kbd.notifyEscape(fLocked);\n }\n var control = this.bindings[\"lockPointer\"];\n if (control) control.textContent = (fLocked? \"Press Esc to Unlock Pointer\" : this.sLockMessage);\n }\n\n /**\n * captureTouch(nTouchConfig)\n *\n * @this {Video}\n * @param {number} nTouchConfig (must be one of the supported Video.TOUCH values)\n */\n captureTouch(nTouchConfig)\n {\n var control = this.inputScreen;\n if (control) {\n var video = this;\n if (!this.nTouchConfig) {\n\n this.nTouchConfig = nTouchConfig;\n \n var addPassive = false;\n if (nTouchConfig != Video.TOUCH.MOUSE) {\n /*\n * If we're not capturing touch events for mouse event simulation, then we won't be calling\n * preventDefault(), which means we should tell Chrome and any other browser that supports\n * passive event listeners that we're installing a \"passive\" event listener, so that the browser\n * won't suspend us during `touchstart` and `touchmove` events. But in order to know whether\n * the browser supports that feature, we have to probe for it first.\n */\n try {\n var opts = Object.defineProperty({}, 'passive', {\n get: function() {\n addPassive = true;\n }\n });\n window.addEventListener(\"testPassive\", null, opts);\n window.removeEventListener(\"testPassive\", null, opts);\n } catch (e) {}\n }\n\n control.addEventListener(\n 'touchstart',\n function onTouchStart(event) { video.onTouchStart(event); },\n addPassive? {passive: true} : false\n );\n\n if (nTouchConfig == Video.TOUCH.DEFAULT) {\n return;\n }\n\n control.addEventListener(\n 'touchmove',\n function onTouchMove(event) { video.onTouchMove(event); },\n addPassive? {passive: true} : true\n );\n\n control.addEventListener(\n 'touchend',\n function onTouchEnd(event) { video.onTouchEnd(event); },\n false // we'll specify false for the 'useCapture' parameter for now...\n );\n\n /*\n * Using desktop mouse events to simulate touch events should only be enabled as needed.\n */\n if (MAXDEBUG) {\n control.addEventListener(\n 'mousedown',\n function onMouseDown(event) { video.onTouchStart(event); },\n false // we'll specify false for the 'useCapture' parameter for now...\n );\n control.addEventListener(\n 'mousemove',\n function onMouseMove(event) { video.onTouchMove(event); },\n true\n );\n control.addEventListener(\n 'mouseup',\n function onMouseUp(event) { video.onTouchEnd(event); },\n false // we'll specify false for the 'useCapture' parameter for now...\n );\n }\n\n // this.log(\"touch events captured\");\n\n this.xTouch = this.yTouch = this.timeTouch = -1;\n\n /*\n * As long as fTouchDefault is false, we call preventDefault() on every touch event, to prevent\n * the page from moving/scrolling while the canvas is processing touch events. However, there must\n * also be exceptions to permit the soft keyboard to activate; see processTouchEvent() for details.\n */\n this.fTouchDefault = false;\n\n /*\n * I also need to come up with some rules for when the simulated mouse's primary button stays down.\n * Let's try setting a timeout handler whenever a touchstart is received, which we'll immediately cancel\n * as soon as a touchmove or touchend event is received, and if the timeout handler fires, we'll set\n * fLongTouch to true.\n */\n this.hLongTouch = null;\n this.fLongTouch = false;\n this.onLongTouch = function onLongTouch() { video.startLongTouch(); };\n }\n }\n }\n\n /**\n * onFocusChange(fFocus)\n *\n * @this {Video}\n * @param {boolean} fFocus is true if gaining focus, false if losing it\n */\n onFocusChange(fFocus)\n {\n /*\n * As per http://stackoverflow.com/questions/6740253/disable-scrolling-when-changing-focus-form-elements-ipad-web-app,\n * I decided to try this work-around to prevent the webpage from scrolling around whenever the canvas is given\n * focus. That sort of scrolling-into-view sounds great in principle, but in practice, if you were reading some other\n * portion of the page, it can be irritating to be scrolled away from that portion when refreshing/returning to the page.\n *\n * However, this work-around doesn't seem to work with the latest version of Safari (or else I misunderstood something).\n *\n * if (fFocus) {\n * window.scrollTo(0, 0);\n * document.body.scrollTop = 0;\n * }\n */\n this.fHasFocus = fFocus;\n if (this.kbd) this.kbd.onFocusChange(fFocus);\n }\n\n /**\n * onTouchStart(event)\n *\n * @this {Video}\n * @param {Event} event object from a 'touch' event\n */\n onTouchStart(event)\n {\n if (DEBUG) this.printMessage(\"onTouchStart()\");\n this.chipset.startAudio(event);\n if (this.nTouchConfig == Video.TOUCH.DEFAULT) return;\n this.processTouchEvent(event, true);\n }\n\n /**\n * onTouchMove(event)\n *\n * @this {Video}\n * @param {Event} event object from a 'touch' event\n */\n onTouchMove(event)\n {\n if (DEBUG) this.printMessage(\"onTouchMove()\");\n this.processTouchEvent(event);\n }\n\n /**\n * onTouchEnd(event)\n *\n * @this {Video}\n * @param {Event} event object from a 'touch' event\n */\n onTouchEnd(event)\n {\n if (DEBUG) this.printMessage(\"onTouchEnd()\");\n this.processTouchEvent(event, false);\n }\n\n /**\n * processTouchEvent(event, fStart)\n *\n * If nTouchConfig is non-zero, touch event handlers are installed, which pass their events to this function.\n *\n * What we do with those events here depends on the value of nTouchConfig. Originally, the only supported\n * configuration was the experimental conversion of touch events into arrow keys, based on an invisible grid\n * that divided the screen into thirds; that configuration is now identified as Video.TOUCH.KEYGRID.\n *\n * The new preferred configuration is Video.TOUCH.MOUSE, which does little more than allow you to \"push\" the\n * simulated mouse around. If Video.TOUCH.MOUSE is enabled, it's already been confirmed the machine has a mouse.\n *\n * @this {Video}\n * @param {Event|MouseEvent|TouchEvent} event object from a 'touch' event\n * @param {boolean} [fStart] (true if 'touchstart', false if 'touchend', undefined if 'touchmove')\n */\n processTouchEvent(event, fStart)\n {\n var xTouch, yTouch;\n\n // if (!event) event = window.event;\n\n /*\n * Touch coordinates (that is, the pageX and pageY properties) are relative to the page, so to make\n * them relative to the canvas, we must subtract the canvas's left and top positions. This Apple web page:\n *\n * https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/AddingMouseandTouchControlstoCanvas/AddingMouseandTouchControlstoCanvas.html\n *\n * makes it sound simple, but it turns out we have to walk the canvas' entire \"parentage\" of DOM elements\n * to get the exact offsets.\n *\n * TODO: Determine whether the getBoundingClientRect() code used in panel.js for mouse events can also\n * be used here to simplify this annoyingly complicated code for touch events.\n */\n var xTouchOffset = 0;\n var yTouchOffset = 0;\n var eCurrent = this.canvasScreen;\n\n do {\n if (!isNaN(eCurrent.offsetLeft)) {\n xTouchOffset += eCurrent.offsetLeft;\n yTouchOffset += eCurrent.offsetTop;\n }\n } while ((eCurrent = eCurrent.offsetParent));\n\n /*\n * Due to the responsive nature of our pages, the displayed size of the canvas may be smaller than the\n * allocated size, and the coordinates we receive from touch events are based on the currently displayed size.\n */\n var xScale = this.cxScreen / this.canvasScreen.offsetWidth;\n var yScale = this.cyScreen / this.canvasScreen.offsetHeight;\n\n /**\n * @name Event\n * @property {Array} targetTouches\n */\n if (!event.targetTouches || !event.targetTouches.length) {\n xTouch = event.pageX;\n yTouch = event.pageY;\n } else {\n xTouch = event.targetTouches[0].pageX;\n yTouch = event.targetTouches[0].pageY;\n }\n\n xTouch = ((xTouch - xTouchOffset) * xScale);\n yTouch = ((yTouch - yTouchOffset) * yScale);\n\n if (this.nTouchConfig == Video.TOUCH.KEYGRID) {\n\n /*\n * We don't want to simulate a key on EVERY touch event; preferably, only touchstart or touchend. And\n * I probably would have preferred triggering key presses on touchend, so that if you decided to move\n * your finger off-screen before releasing, you could avoid a key press, but sadly (as I've documented in\n * the Mandelbot project; see https://github.com/jeffpar/mandelbot/blob/master/src/mandelbot.js),\n * touchend doesn't reliably provide coordinates on all platforms, so we're going to go with touchstart.\n */\n if (fStart) {\n\n var xThird = (xTouch / (this.cxScreen / 3)) | 0;\n var yThird = (yTouch / (this.cyScreen / 3)) | 0;\n\n /*\n * At this point, xThird and yThird should both be one of 0, 1 or 2, indicating which horizontal and\n * vertical third of the virtual screen the touch event occurred.\n */\n this.kbd.addActiveKey(Video.KEYGRID[yThird][xThird], true);\n }\n } else {\n\n if (this.mouse) {\n /*\n * As long as fTouchDefault is false, we call preventDefault() on every touch event, to keep\n * the page stable. However, we must allow some touch event(s) to perform their default action,\n * otherwise the soft keyboard can never be activated. So if a touchstart occurs at least 1/2\n * second (500ms) after the last touchstart, with no intervening touchmove events, fTouchDefault\n * is allowed to become true.\n */\n var fTouchDefault = this.fTouchDefault;\n var timeDelta = event.timeStamp - this.timeTouch;\n\n if (fStart === true) {\n this.fTouchDefault = (timeDelta > 500);\n this.timeTouch = event.timeStamp;\n this.hLongTouch = setTimeout(this.onLongTouch, 500);\n } else {\n if (this.hLongTouch != null) {\n clearTimeout(this.hLongTouch);\n this.hLongTouch = null;\n }\n }\n if (fStart === undefined) {\n this.fTouchDefault = false;\n }\n\n if (DEBUG) {\n this.log(\"processTouchEvent(\" + (fStart? \"touchStart\" : (fStart === false? \"touchEnd\" : \"touchMove\")) + \",\" + timeDelta + \"ms,\" + fTouchDefault + \")\");\n }\n\n if (!fTouchDefault) {\n event.preventDefault();\n }\n\n if (fStart === false) {\n /*\n * NOTE: 200ms is merely my initial stab at a reasonable number of milliseconds to interpret a\n * start/end touch sequence as a \"tap\"; I also make no note of any intervening move events (ie,\n * events where fStart is undefined), and perhaps I should....\n */\n if (this.endLongTouch()) {\n return;\n }\n if (timeDelta < 200) {\n this.mouse.clickMouse(Mouse.BUTTON.LEFT, true);\n this.mouse.clickMouse(Mouse.BUTTON.LEFT, false);\n return;\n }\n }\n /*\n * This 'touchmove\" code mimics the 'mousemove' event processing in processMouseEvent() in mouse.js, with\n * one important difference: every time touching \"restarts\", we need to reset the variables used to calculate\n * the deltas, so that the mere act of lifting and replacing your finger doesn't generate a delta by itself.\n */\n if (fStart || this.xTouch < 0 || this.yTouch < 0) {\n this.xTouch = xTouch;\n this.yTouch = yTouch;\n }\n var xDelta = Math.round(xTouch - this.xTouch);\n var yDelta = Math.round(yTouch - this.yTouch);\n this.xTouch = xTouch;\n this.yTouch = yTouch;\n // this.println(\"moveMouse(\" + xDelta + \",\" + yDelta + \")\");\n this.mouse.moveMouse(xDelta, yDelta, this.xTouch, this.yTouch);\n }\n }\n }\n\n /**\n * startLongTouch()\n *\n * @this {Video}\n */\n startLongTouch()\n {\n this.fLongTouch = true;\n this.mouse.clickMouse(Mouse.BUTTON.LEFT, true);\n }\n\n /**\n * endLongTouch()\n *\n * @this {Video}\n * @return {boolean} true if long touch was active, false if not\n */\n endLongTouch()\n {\n if (this.fLongTouch) {\n this.mouse.clickMouse(Mouse.BUTTON.LEFT, false);\n this.fLongTouch = false;\n return true;\n }\n return false;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {Video}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data || !this.restore) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * This is where we might add some method of blanking the display, without the disturbing the video\n * buffer contents, and blocking all further updates to the display.\n *\n * @this {Video}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {Video}\n */\n reset()\n {\n var nMonitorType = ChipSet.MONITOR.NONE;\n\n /*\n * We'll ask the ChipSet what SW1 indicates for monitor type, but we may override it if a specific\n * video card model is set. For EGA, SW1 is supposed to be set to indicate NO monitor, and we rely\n * on the EGA's own switch settings instead.\n */\n if (this.chipset) {\n nMonitorType = this.chipset.getDIPVideoMonitor();\n }\n\n /*\n * As we noted in the constructor, when a model is specified, that takes precedence over any monitor\n * switch settings. Conversely, when no model is specified, the nCard setting is considered provisional,\n * so the monitor switch settings, if any, are allowed to determine the card type.\n */\n if (!this.model) {\n this.nCard = (nMonitorType == ChipSet.MONITOR.MONO? Video.CARD.MDA : Video.CARD.CGA);\n }\n\n this.nModeDefault = Video.MODE.CGA_80X25;\n\n switch (this.nCard) {\n case Video.CARD.VGA:\n nMonitorType = ChipSet.MONITOR.VGACOLOR;\n break;\n case Video.CARD.EGA:\n var aMonitors = Video.aEGAMonitorSwitches[this.bEGASwitches];\n /*\n * TODO: Figure out how to deal with aMonitors[2], the boolean which indicates\n * whether the EGA is driving the primary monitor (true) or the secondary monitor (false).\n */\n if (aMonitors) nMonitorType = aMonitors[0];\n if (!nMonitorType) nMonitorType = ChipSet.MONITOR.EGACOLOR;\n break;\n case Video.CARD.MDA:\n nMonitorType = ChipSet.MONITOR.MONO;\n this.nModeDefault = Video.MODE.MDA_80X25;\n break;\n case Video.CARD.CGA:\n /* falls through */\n default:\n nMonitorType = ChipSet.MONITOR.COLOR;\n break;\n }\n\n if (this.nMonitorType !== nMonitorType) {\n this.nMonitorType = nMonitorType;\n }\n\n this.cardActive = null;\n this.cardMono = this.cardMDA = new Card(this, Video.CARD.MDA);\n this.cardColor = this.cardCGA = new Card(this, Video.CARD.CGA);\n\n if (this.nCard < Video.CARD.EGA) {\n this.cardEGA = new Card(); // define a dummy (uninitialized) EGA card for now\n }\n else {\n this.cardEGA = new Card(this, this.nCard, null, this.cbMemory);\n this.enableEGA();\n }\n\n /*\n * We need to call buildFonts() *after* the card(s) are initialized but *before* setMode() is called.\n */\n this.buildFonts();\n\n this.nMode = null;\n this.setMode(this.nModeDefault);\n\n if (this.cardActive.addrBuffer && this.nRandomize) {\n /*\n * On the initial power-on, we initialize the video buffer to random characters, as a way of testing\n * whether our font(s) were successfully loaded. It's assumed that our default display mode is a text mode,\n * and that since this is a reset, the CRTC.START_ADDR registers are zero as well.\n *\n * If this is an MDA device, then the buffer should reside at 0xB0000 through 0xB0FFF, for a total length\n * of 4Kb (0x1000), where every even byte contains a character code, and every odd byte contains an attribute\n * code. See the ATTR bit definitions above for applicable color, intensity, and blink values. On a CGA\n * device, the buffer resides at 0xB8000 through 0xBBFFF, for a total length of 16Kb.\n *\n * Note that the only valid MDA display mode (7) is the 80x25 text mode, which uses 4000 bytes (2000 character\n * bytes + 2000 attribute bytes), not all 4096 bytes; addrScreenLimit reflects the visible limit, not the\n * physical limit. Also, as noted in updateScreen(), this simplistic calculation of the extent of visible\n * screen memory is valid only for text modes; in general, it's safer to use cardActive.sizeBuffer as the extent.\n */\n var addrScreenLimit = this.cardActive.addrBuffer + this.cbScreen;\n for (var addrScreen = this.cardActive.addrBuffer; addrScreen < addrScreenLimit; addrScreen += 2) {\n var dataRandom = (Math.random() * 0x10000)|0;\n var bChar, bAttr;\n if (this.nMonitorType == ChipSet.MONITOR.EGACOLOR || this.nMonitorType == ChipSet.MONITOR.VGACOLOR) {\n /*\n * For the EGA, we choose sequential characters; for random characters, copy the MDA/CGA code below.\n */\n bChar = (addrScreen >> 1) & 0xff;\n bAttr = (dataRandom >> 8) & ~Video.ATTRS.BGND_BLINK; // TODO: turn blink attributes off unless we can ensure blinking is initially disabled\n if ((bAttr >> 4) == (bAttr & 0xf)) {\n bAttr ^= 0x0f; // if background matches foreground, invert foreground to ensure character visibility\n }\n } else {\n bChar = dataRandom & 0xff;\n bAttr = ((dataRandom & 0x100)? (Video.ATTRS.FGND_WHITE | Video.ATTRS.BGND_BLACK) : (Video.ATTRS.FGND_BLACK | Video.ATTRS.BGND_WHITE)) | ((Video.ATTRS.FGND_BRIGHT /* | Video.ATTRS.BGND_BLINK */) & (dataRandom >> 8));\n }\n this.bus.setShortDirect(addrScreen, bChar | (bAttr << 8));\n }\n this.updateScreen(true);\n }\n }\n\n /**\n * enableEGA()\n *\n * Redirect cardMono or cardColor to cardEGA as appropriate.\n *\n * @this {Video}\n */\n enableEGA()\n {\n if (!(this.cardEGA.regMisc & Card.MISC.IO_SELECT)) {\n this.cardMono = this.cardEGA;\n this.cardColor = this.cardCGA; // this is done mainly to siphon away any CGA I/O\n } else {\n this.cardMono = this.cardMDA; // similarly, this is done to siphon away any MDA I/O\n this.cardColor = this.cardEGA;\n }\n }\n\n /**\n * save()\n *\n * This implements save support for the Video component.\n *\n * @this {Video}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.cardMDA.saveCard());\n state.set(1, this.cardCGA.saveCard());\n state.set(2, [this.nMonitorType, this.nModeDefault, this.nMode]);\n state.set(3, this.cardEGA.saveCard());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the Video component.\n *\n * @this {Video}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var a = data[2];\n this.nMonitorType = a[0];\n this.nModeDefault = a[1];\n this.nMode = a[2];\n\n this.cardActive = null;\n this.cardMono = this.cardMDA = new Card(this, Video.CARD.MDA, data[0]);\n this.cardColor = this.cardCGA = new Card(this, Video.CARD.CGA, data[1]);\n\n /*\n * If no EGA was originally initialized, then cardEGA will remain uninitialized.\n */\n this.cardEGA = new Card(this, this.nCard, data[3], this.cbMemory);\n if (this.cardEGA.fActive) this.enableEGA();\n\n /*\n * We need to call buildFonts() *after* the card(s) are initialized but *before* setMode() is called.\n */\n this.buildFonts();\n\n /*\n * While I could restore the active card here, it's better for setMode() to do it, because\n * setMode() will also take care of mapping the appropriate video buffer. So, after restore() has\n * finished, we call checkMode(), because the current video mode (nMode) is determined by the\n * active card state.\n *\n * Unfortunately, that creates a chicken-and-egg problem, since I just said I didn't want to select\n * the active card here.\n *\n * So, we'll add some \"cop-out\" code to checkMode(): if there's no active card, then fall-back\n * to the last known video mode (nMode) and force a call to setMode().\n *\n * this.cardActive = (this.cardMDA.fActive? this.cardMDA : (this.cardCGA.fActive? this.cardCGA : undefined));\n */\n if (!this.checkMode()) return false;\n\n this.checkCursor();\n return true;\n }\n\n /**\n * doneLoad(sURL, sFontData, nErrorCode)\n *\n * @this {Video}\n * @param {string} sURL\n * @param {string} sFontData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n doneLoad(sURL, sFontData, nErrorCode)\n {\n if (nErrorCode) {\n this.notice(\"Unable to load font ROM (error \" + nErrorCode + \": \" + sURL + \")\", nErrorCode < 0);\n return;\n }\n\n Component.addMachineResource(this.idMachine, sURL, sFontData);\n\n try {\n /*\n * The most likely source of any exception will be right here, where we're parsing the JSON-encoded data.\n */\n var abFontData = eval(\"(\" + sFontData + \")\");\n\n var ab = abFontData['bytes'] || abFontData;\n\n if (!ab.length) {\n Component.error(\"Empty font ROM: \" + sURL);\n return;\n }\n else if (ab.length == 1) {\n Component.error(ab[0]);\n return;\n }\n /*\n * Translate the character data into separate \"fonts\", each of which will be a separate canvas object, with all\n * 256 characters arranged in a 16x16 grid.\n */\n if (ab.length == 8192) {\n /*\n * The assumption here is that we're dealing with the original (IBM) MDA/CGA font data, which apparently\n * was identical on both MDA and CGA cards (even though the former had no use for the latter, and vice versa).\n *\n * First, let's take a look at the MDA portion of the data. Here are the first few rows of MDA font data,\n * at the 0K and 2K boundaries:\n *\n * 00000000 00 00 00 00 00 00 00 00 00 00 7e 81 a5 81 81 bd |..........~.....|\n * 00000010 00 00 7e ff db ff ff c3 00 00 00 36 7f 7f 7f 7f |..~........6....|\n * ...\n * 00000800 00 00 00 00 00 00 00 00 99 81 7e 00 00 00 00 00 |..........~.....|\n * 00000810 e7 ff 7e 00 00 00 00 00 3e 1c 08 00 00 00 00 00 |..~.....>.......|\n *\n * 8 bytes of data from a row in each of the 2K chunks are combined to form a 8-bit wide character with\n * a maximum height of 16 bits. Assembling the bits for character 0x01 (a happy face), we observe the following:\n *\n * 0 0 0 0 0 0 0 0 <== 00 from offset 0x0008\n * 0 0 0 0 0 0 0 0 <== 00 from offset 0x0009\n * 0 1 1 1 1 1 1 0 <== 7e from offset 0x000A\n * 1 0 0 0 0 0 0 1 <== 81 from offset 0x000B\n * 1 0 1 0 0 1 0 1 <== a5 from offset 0x000C\n * 1 0 0 0 0 0 0 1 <== 81 from offset 0x000D\n * 1 0 0 0 0 0 0 1 <== 81 from offset 0x000E\n * 1 0 1 1 1 1 0 1 <== bd from offset 0x000F\n * 1 0 0 1 1 0 0 1 <== 99 from offset 0x0808\n * 1 0 0 0 0 0 0 1 <== 81 from offset 0x0809\n * 0 1 1 1 1 1 1 0 <== 7e from offset 0x080A\n * 0 0 0 0 0 0 0 0 <== 00 from offset 0x080B\n * 0 0 0 0 0 0 0 0 <== 00 from offset 0x080C\n * 0 0 0 0 0 0 0 0 <== 00 from offset 0x080D\n * 0 0 0 0 0 0 0 0 <== 00 from offset 0x080E\n * 0 0 0 0 0 0 0 0 <== 00 from offset 0x080F\n *\n * In the second 2K chunk, we observe that the last two bytes of every font cell definition are zero;\n * this confirms our understanding that MDA font cell size is 8x14.\n *\n * Finally, there's the issue of screen cell size, which is actually 9x14 on the MDA. We compensate for that\n * by building a 9x14 font, even though there's only 8x14 bits of data. As http://www.seasip.info/VintagePC/mda.html\n * explains:\n *\n * \"For characters C0h-DFh, the ninth pixel column is a duplicate of the eighth; for others, it's blank.\"\n *\n * This last point is confirmed by \"The IBM Personal Computer From The Inside Out\", p.295:\n *\n * \"Another unique feature of the monochrome adapter is a set of line-drawing and area-fill characters\n * that give continuous lines and filled areas. This is unusual for a display with a 9x14 character box\n * because the character generator provides a row only eight dots wide. On most displays, a blank 9th\n * dot is then inserted between characters. On the monochrome display, there is circuitry that duplicates\n * the 8th dot into the 9th dot position for characters whose ASCII codes are 0xB0 [sic] through 0xDF.\"\n *\n * However, the above text is mistaken about the start of the range. While there ARE line-drawing characters\n * in the range 0xB0-0xBF, none of them extend all the way to the right edge; IBM carefully segregated them.\n * And in fact, characters 0xB0-0xB2 contain hash patterns that you would NOT want extended into the 9th column.\n *\n * The CGA font is part of the same ROM. In fact, there are TWO CGA fonts in the ROM: a thin 5x7 \"single dot\"\n * font located at offset 0x1000, and a thick 7x7 \"double dot\" font at offset 0x1800. The latter is the default\n * font, unless overridden by a jumper setting on the CGA card, so it is our default CGA font as well (although\n * someday we may provide a virtual jumper setting that allows you to select the thinner font).\n *\n * The first offset we must pass to setFontData() is the offset of the CGA font; we choose the thicker \"double dot\"\n * CGA font at 0x1800 (which was the PC's default font as well), instead of the thinner \"single dot\" font at 0x1000.\n * The second offset is for the MDA font.\n */\n this.setFontData(ab, [0x1800, 0x0000]);\n }\n else if (ab.length == 2048) {\n /*\n * The assumption here is that we're dealing strictly with CGA (8x8) font data, like the font data found\n * in the Columbia Data Products (CDP) Font ROM.\n */\n this.setFontData(ab, [0x0000]);\n }\n else {\n this.notice(\"Unrecognized font data length (\" + ab.length + \")\");\n return;\n }\n\n } catch (e) {\n this.notice(\"Font ROM data error: \" + e.message);\n return;\n }\n /*\n * If we're still here, then we're ready!\n *\n * UPDATE: Per issue #21, I'm issuing setReady() *only* if a valid contextScreen exists *or* a Debugger is attached.\n *\n * TODO: Consider a more general-purpose solution for deciding whether or not the user wants to run in a \"headless\" mode.\n */\n if (this.contextScreen || this.dbg) this.setReady();\n }\n\n /**\n * onROMLoad(abRom, aParms)\n *\n * Called by the ROM's copyROM() function whenever a ROM component with a 'notify' attribute containing\n * our component ID has been loaded.\n *\n * @this {Video}\n * @param {Array.<number>} abROM\n * @param {Array.<number>} [aParms]\n */\n onROMLoad(abROM, aParms)\n {\n if (this.nCard == Video.CARD.EGA) {\n /*\n * TODO: Unlike the MDA/CGA font data, we may want to hang onto this data, so that we can\n * regenerate the color font(s) whenever the foreground and/or background colors have changed.\n */\n if (DEBUG) this.printMessage(\"onROMLoad(): EGA fonts loaded\");\n /*\n * For EGA cards, in the absence of any parameters, we assume that we're receiving the original\n * IBM EGA ROM, which stores its 8x14 font data at 0x2230 as one continuous sequence; the total size\n * of the 8x14 font is 0xE00 bytes.\n *\n * At 0x3030, there is an \"ALPHA SUPPLEMENT\" table, which contains 15 bytes per row instead of 14,\n * because each row is preceded by one byte containing the corresponding ASCII code; there are 20\n * entries in the supplemental table, for a total size of 0x12C bytes.\n *\n * Finally, at 0x3160, we have the 8x8 font data (also known as the thicker \"double dot\" CGA font);\n * the total size of the 8x8 font is 0x800 bytes. No other font data is present in the EGA ROM;\n * the thin 5x7 \"single dot\" CGA font is notably absent, which is fine, because we never loaded it for\n * the MDA/CGA either.\n *\n * TODO: Determine how the supplemental table is used and whether we need to add some \"run-time\"\n * font generation to support it (as opposed to \"init-time\" generation, which is all we do now).\n * There's probably a similar need for user-defined fonts; for now, they're simply not supported.\n */\n this.setFontData(abROM, aParms || [0x3160, 0x2230], 8);\n }\n else if (this.nCard == Video.CARD.VGA) {\n if (DEBUG) this.printMessage(\"onROMLoad(): VGA fonts loaded\");\n /*\n * For VGA cards, in the absence of any parameters, we assume that we're receiving the original\n * IBM VGA ROM, which contains an 8x14 font at 0x3F8D (and corresponding supplemental table at 0x4D8D)\n * and an 8x8 font at 0x378D; however, it also contains an 8x16 font at 0x4EBA (and corresponding\n * supplemental table at 0x5EBA). See our reconstructed source code in ibm-vga.nasm.\n */\n this.setFontData(abROM, aParms || [0x378d, 0x3f8d], 8);\n }\n this.setReady();\n }\n\n /**\n * getCardColors(nBitsPerPixel)\n *\n * @this {Video}\n * @param {number} [nBitsPerPixel]\n * @returns {Array}\n */\n getCardColors(nBitsPerPixel)\n {\n if (nBitsPerPixel == 1) {\n /*\n * Only 2 total colors.\n */\n this.aRGB[0] = Video.aCGAColors[Video.ATTRS.FGND_BLACK];\n this.aRGB[1] = Video.aCGAColors[Video.ATTRS.FGND_WHITE];\n return this.aRGB;\n }\n\n if (nBitsPerPixel == 2) {\n /*\n * Of the 4 colors returned, the first color comes from regColor and the other 3 come from one of\n * the two hard-coded CGA color sets:\n *\n * Color Set 1 Color Set 2\n * ----------- -----------\n * Background (0x00) Background (0x00)\n * Green (0x12) Cyan (0x13)\n * Red (0x14) Magenta (0x15)\n * Brown (0x16) White (0x17)\n *\n * The numbers in parentheses are the EGA ATC palette register values that the EGA BIOS uses for each\n * color set; on an EGA, I synthesize a fake CGA regColor value, until I (TODO:) figure out exactly how\n * the EGA simulates the CGA color palette.\n */\n var regColor = this.cardActive.regColor;\n if (this.cardActive === this.cardEGA) {\n var bBackground = this.cardEGA.regATCData[0];\n regColor = bBackground & Card.CGA.COLOR.BORDER;\n if (bBackground & Card.ATC.PALETTE.BRIGHT) regColor |= Card.CGA.COLOR.BRIGHT;\n if (this.cardEGA.regATCData[1] != 0x12) regColor |= Card.CGA.COLOR.COLORSET2;\n }\n this.aRGB[0] = Video.aCGAColors[regColor & (Card.CGA.COLOR.BORDER | Card.CGA.COLOR.BRIGHT)];\n var aColorSet = (regColor & Card.CGA.COLOR.COLORSET2)? Video.aCGAColorSet2 : Video.aCGAColorSet1;\n for (var iColor = 0; iColor < aColorSet.length; iColor++) {\n this.aRGB[iColor+1] = Video.aCGAColors[aColorSet[iColor]];\n }\n return this.aRGB;\n }\n\n if (this.cardColor === this.cardCGA) {\n /*\n * There's no need to update this.aRGB if we simply want to return a hard-coded set of 16 colors.\n */\n return Video.aCGAColors;\n }\n\n\n\n if (this.fRGBValid && nBitsPerPixel && !this.aRGB[16]) {\n this.fRGBValid = false;\n }\n\n if (!this.fRGBValid) {\n\n var card = this.cardEGA;\n var aDAC = card.regDACData;\n var aRegs, i, dw, b, bRed, bGreen, bBlue;\n\n if (nBitsPerPixel == 8) {\n /*\n * The card must be a VGA, and it's using an (8bpp) mode that bypasses the ATC, so we need to pull\n * RGB data exclusively from the 256-entry DAC; each entry contains 6-bit red, green, and blue values\n * packed into bits 0-5, 6-11, and 12-17, respectively, each of which we effectively shift left 2 bits:\n * a crude 6-to-8-bit color conversion.\n */\n for (i = 0; i < 256; i++) {\n dw = aDAC[i] || 0;\n\n bRed = (dw << 2) & 0xfc;\n bGreen = (dw >> 4) & 0xfc;\n bBlue = (dw >> 10) & 0xfc;\n this.aRGB[i] = [bRed, bGreen, bBlue, 0xff];\n }\n } else {\n /*\n * We need to pull RGB data from the ATC; moreover, if the ATC hasn't been initialized yet,\n * we go with a default EGA-compatible 16-color palette. We'll also use the DAC if there is one\n * (ie, this is actually a VGA) and it appears to be initialized (ie, the VGA BIOS has been run).\n */\n var fDAC = (aDAC && aDAC[255]);\n aRegs = (card.regATCData[15] != null? card.regATCData : Video.aEGAPalDef);\n for (i = 0; i < 16; i++) {\n b = aRegs[i] & Card.ATC.PALETTE.MASK;\n /*\n * If the DAC is valid, we need to supplement the 6 bits of each ATC palette entry with the values\n * for bits 6 and 7 from the ATC COLORSEL register (and overwrite bits 4 and 5 if ATC.MODE.COLORSEL_ALL\n * is set as well).\n *\n * The only reasons the DAC wouldn't be valid are if 1) we're trying to display an image before the machine\n * and its BIOS have had a chance to initialize the DAC (because we don't preset it to anything, although\n * perhaps we should), or 2) this is an EGA, which doesn't have a DAC.\n */\n if (fDAC) {\n b |= (card.regATCData[Card.ATC.COLORSEL.INDX] & (Card.ATC.COLORSEL.DAC_BIT7 | Card.ATC.COLORSEL.DAC_BIT6)) << 4;\n if (card.regATCData[Card.ATC.MODE.INDX] & Card.ATC.MODE.COLORSEL_ALL) {\n b &= ~0x30;\n b |= (card.regATCData[Card.ATC.COLORSEL.INDX] & (Card.ATC.COLORSEL.DAC_BIT5 | Card.ATC.COLORSEL.DAC_BIT4)) << 4;\n }\n\n dw = aDAC[b];\n\n bRed = (dw << 2) & 0xfc;\n bGreen = (dw >> 4) & 0xfc;\n bBlue = (dw >> 10) & 0xfc;\n } else {\n bRed = (((b & 0x04)? 0xaa : 0) | ((b & 0x20)? 0x55 : 0));\n bGreen = (((b & 0x02)? 0xaa : 0) | ((b & 0x10)? 0x55 : 0));\n bBlue = (((b & 0x01)? 0xaa : 0) | ((b & 0x08)? 0x55 : 0));\n }\n this.aRGB[i] = [bRed, bGreen, bBlue, 0xff];\n }\n }\n this.fRGBValid = true;\n }\n\n return this.aRGB;\n }\n\n /**\n * setFontData(abFontData, aFontOffsets, cxFontChar)\n *\n * To support partial font rebuilds (required for the EGA), we now preserve the original font data (abFontData),\n * font offsets (aFontOffsets), and font character width (8 for the EGA, undefined for the MDA/CGA).\n *\n * TODO: Ultimately, we want to have exactly one dedicated font for the EGA, the data for which we'll read directly\n * from plane 2 of video memory, instead of relying on the original font data in ROM. Relying on the ROM data was\n * originally just a crutch to help get EGA support bootstrapped.\n *\n * Also, for the MDA/CGA, we should be discarding the font data after the first buildFonts() call, because we\n * should not need to ever rebuild the fonts for those cards (both their font patterns and colors were hard-coded).\n *\n * @this {Video}\n * @param {*} abFontData is the raw font data, from the ROM font file\n * @param {Array.<number>} aFontOffsets contains offsets into abFontData: [0] for CGA, [1] for MDA\n * @param {number} [cxFontChar] is a fixed character width to use for all fonts; undefined to use MDA/CGA defaults\n */\n setFontData(abFontData, aFontOffsets, cxFontChar)\n {\n this.abFontData = abFontData;\n this.aFontOffsets = aFontOffsets;\n this.cxFontChar = cxFontChar;\n }\n\n /**\n * buildFonts()\n *\n * buildFonts() is called whenever the Video component is reset or restored; we used to build the fonts as soon\n * as the ROM containing them was loaded, and then throw away the underlying font data, but with the EGA's ability\n * to change the color of any font, font building must now be deferred until the reset or restore notifications,\n * ensuring we have access to all the colors the card is currently programmed to use.\n *\n * We're also called whenever EGA palette registers are modified, since one or more fonts will likely need\n * to be rebuilt (this is because our fonts contain pre-rendered images of all glyphs for all 16 active colors).\n * Calls to buildFonts() should not be expensive though: the underlying createFont() function rebuilds a font only\n * if its color has actually changed.\n *\n * TODO: Our font code is still written with the assumption that, like the MDA/CGA, the underlying font data never\n * changes. The EGA, however, stores its fonts in plane 2, which means fonts are dynamic; this needs to be fixed.\n *\n * Supporting dynamic EGA fonts should not be hard though. We can get rid of abFontData and simply build a\n * temporary snapshot of all the font bytes in plane 2 of the EGA's video buffer (adwMemory), and pass that on to\n * buildFont() instead. We'll also need to either invalidate the existing font's color (to trigger a rebuild) or\n * pass a new \"force rebuild\" flag.\n *\n * Once that's done, an added benefit will be that we can build just the font(s) that have been loaded into plane 2,\n * instead of the multitude of fonts that we now build on a just-in-case basis (eg, the MDA font, the 8x8 CGA font\n * for 43-line mode, and so on).\n *\n * @this {Video}\n * @param {boolean} [fRebuild] (true if this is a rebuild, not an initial build)\n * @return {boolean} true if any or all fonts were (re)built, false if nothing changed\n */\n buildFonts(fRebuild)\n {\n var fChanges = false;\n\n /*\n * There's no point building fonts if this is a non-windowed (command-line) environment\n * OR no font data is available (OR this is a rebuild AND we're currently in a graphics mode).\n *\n * In other words, build fonts if this IS a windowed environment AND font data is available\n * AND this is not a rebuild, OR it IS a rebuild but we're in a graphics mode (ie, nFont is zero).\n */\n if (window && this.abFontData && (!fRebuild || this.nFont)) {\n\n var offSplit = 0x0000;\n var cxChar = this.cxFontChar? this.cxFontChar : 8;\n var aRGBColors = this.getCardColors();\n\n if (this.aFontOffsets[0] != null) {\n if (this.buildFont(Video.FONT.CGA, this.aFontOffsets[0], offSplit, cxChar, 8, this.abFontData, aRGBColors)) {\n fChanges = true;\n }\n }\n\n offSplit = this.cxFontChar? 0 : 0x0800;\n cxChar = this.cxFontChar? this.cxFontChar : 9;\n\n if (this.aFontOffsets[1] != null) {\n if (this.buildFont(Video.FONT.MDA, this.aFontOffsets[1], offSplit, cxChar, 14, this.abFontData, Video.aMDAColors, Video.aMDAColorMap)) {\n fChanges = true;\n }\n if (this.cxFontChar) {\n if (this.buildFont(this.nCard, this.aFontOffsets[1], 0, this.cxFontChar, 14, this.abFontData, aRGBColors)) {\n fChanges = true;\n }\n }\n }\n }\n if (!fRebuild) {\n /*\n * Perform some additional initialization common to both reset() and restore() sequences.\n */\n this.iCellCursor = -1; // initially, there is no visible cursor cell\n this.cBlinks = -1; // initially, blinking is not active\n this.cBlinkVisible = 0; // no visible blinking characters (yet)\n }\n return fChanges;\n }\n\n /**\n * buildFont(nFont, offData, offSplit, cxChar, cyChar, abFontData, aRGBColors, aColorMap)\n *\n * This is a wrapper for createFont() which also takes care loading double-size fonts when fDoubleFont is set.\n *\n * @this {Video}\n * @param {number} nFont\n * @param {number|null} offData is the offset of the font data, null if none\n * @param {number} offSplit is the offset of any split font data, or zero if not split\n * @param {number} cxChar is the width of the font characters\n * @param {number} cyChar is the height of the font characters\n * @param {*} abFontData is the raw font data, from the ROM font file\n * @param {Array} aRGBColors is an array of color RGB variations, corresponding to supported FGND attribute values\n * @param {Array} [aColorMap] contains color indexes corresponding to attribute values (if not supplied, the mapping is assumed to be 1-1)\n * @return {boolean} true if any or all fonts were (re)built, false if nothing changed\n */\n buildFont(nFont, offData, offSplit, cxChar, cyChar, abFontData, aRGBColors, aColorMap)\n {\n var fChanges = false;\n\n if (offData != null) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"buildFont(\" + nFont + \"): building \" + Video.cardSpecs[nFont][0] + \" font\");\n }\n if (this.createFont(nFont, offData, offSplit, cxChar, cyChar, abFontData, aRGBColors, aColorMap)) {\n fChanges = true;\n }\n }\n return fChanges;\n }\n\n /**\n * createFont(nFont, offData, offSplit, cxChar, cyChar, abFontData, aRGBColors, aColorMap)\n *\n * All color variations are stored on the same font canvas, arranged vertically as a series of grids, where each\n * grid is a 16x16 character glyph array.\n *\n * Since every character must be drawn first with its background color and then with the foreground shape on top,\n * I used to include a series of empty cells at the top every font canvas containing all supported background colors\n * (ie, before the character grids). But now createFont() also creates an aCSSColors array that is saved alongside\n * the font canvas, and updateChar() uses that array in conjunction with fillRect() to draw character backgrounds.\n *\n * @this {Video}\n * @param {number} nFont\n * @param {number} offData is the offset of the font data\n * @param {number} offSplit is the offset of any split font data, or zero if not split\n * @param {number} cxChar is the width of the font characters\n * @param {number} cyChar is the height of the font characters\n * @param {*} abFontData is the raw font data, from the ROM font file\n * @param {Array} aRGBColors is an array of color RGB variations, corresponding to supported FGND attribute values\n * @param {Array|undefined} aColorMap contains color indexes corresponding to attribute values (if not supplied, the mapping is assumed to be 1-1)\n * @return {boolean} true if any or all fonts were (re)created, false if nothing changed\n */\n createFont(nFont, offData, offSplit, cxChar, cyChar, abFontData, aRGBColors, aColorMap)\n {\n var fChanges = false;\n var nDouble = (this.fDoubleFont? 1 : 0);\n var font = this.aFonts[nFont];\n var nColors = (aRGBColors.length < 16? aRGBColors.length : 16);\n if (!font) {\n font = {\n cxCell: cxChar << nDouble,\n cyCell: cyChar << nDouble,\n aCSSColors: new Array(nColors),\n aRGBColors: aRGBColors.slice(0, nColors), // using the Array slice() method to simply make a copy\n aColorMap: aColorMap,\n aCanvas: new Array(nColors)\n };\n }\n for (var iColor = 0; iColor < nColors; iColor++) {\n var rgbColor = aRGBColors[iColor];\n var rgbColorOrig = font.aCSSColors[iColor]? font.aRGBColors[iColor] : [];\n if (rgbColor[0] !== rgbColorOrig[0] || rgbColor[1] !== rgbColorOrig[1] || rgbColor[2] !== rgbColorOrig[2]) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"creating font color \" + iColor + \" for font \" + nFont);\n }\n this.createFontColor(font, iColor, rgbColor, nDouble, offData, offSplit, cxChar, cyChar, abFontData);\n fChanges = true;\n }\n }\n this.aFonts[nFont] = font;\n return fChanges;\n }\n\n /**\n * createFontColor(font, iColor, rgbColor, nDouble, offData, offSplit, cxChar, cyChar, abFontData)\n *\n * Now we're ready to create a 16x16 character grid for the specified color. Note that all\n * the character bits are opaque (alpha=0xff) while all the surrounding bits are transparent\n * (alpha=0x00, as specified in the 4th byte of rgbOff).\n *\n * Originally, I created 256 ImageData objects, using context.createImageData(cxChar,cyChar),\n * then setting its pixels to match those of an individual character, and then drawing characters\n * with contextFont.putImageData(). But putImageData() is relatively slow....\n *\n * Now I create a new canvas, with dimensions that allow me to arrange all 256 characters in an\n * 16x16 grid -- much like the \"chargen.png\" bitmap used in the C1Pjs version of the Video component.\n * Then drawing becomes much the same as before, because it turns out that drawImage() accepts either\n * an image object OR a canvas object.\n *\n * This also yields better performance, since drawImage() is much faster than putImageData().\n * We still have to use putImageData() to build the font canvas, but that's a one-time operation.\n * \n * @this {Video}\n * @param {Font} font\n * @param {number} iColor\n * @param {Array} rgbColor contains the RGB values for iColor\n * @param {number} nDouble is 1 to double output font dimensions, 0 to match input dimensions\n * @param {number} offData is the offset of the font data\n * @param {number} offSplit is the offset of any split font data, or zero if not split\n * @param {number} cxChar is the width of the font characters\n * @param {number} cyChar is the height of the font characters\n * @param {*} abFontData is the raw font data, from the ROM font file\n */\n createFontColor(font, iColor, rgbColor, nDouble, offData, offSplit, cxChar, cyChar, abFontData)\n {\n var rgbOff = [0x00, 0x00, 0x00, 0x00];\n var canvasFont = document.createElement(\"canvas\");\n canvasFont.width = font.cxCell << 4;\n canvasFont.height = (font.cyCell << 4);\n var contextFont = canvasFont.getContext(\"2d\");\n\n var iChar, x, y;\n var cyLimit = (cyChar < 8 || !offSplit)? cyChar : 8;\n var imageChar = contextFont.createImageData(font.cxCell, font.cyCell);\n\n for (iChar = 0; iChar < 256; iChar++) {\n for (y = 0; y < cyChar; y++) {\n /*\n * fUnderline should be true only in the FONT_MDA case, and only for the odd color variations\n * (1 and 3, out of variations 0 to 4), and only for the two bottom-most rows of the character cell\n * (which I still need to confirm).\n */\n var fUnderline = (font.aColorMap && (iColor & 0x1) && y >= cyChar - 2);\n var offChar = (y < cyLimit? offData + iChar * cyLimit + y : offSplit + iChar * cyLimit + y - cyLimit);\n var b = abFontData[offChar];\n for (var nRowDoubler = 0; nRowDoubler <= nDouble; nRowDoubler++) {\n for (x = 0; x < cxChar; x++) {\n /*\n * This \"bit\" of logic takes care of those characters (0xC0-0xDF) whose 9th bit must mirror the 8th bit;\n * in all other cases, any bit past the 8th bit is automatically zero. It also takes care of embedding a\n * solid row of bits whenever fUnderline is true.\n *\n * TODO: For EGA/VGA, replication of the 9th dot needs to be based on the TEXT_9DOT bit of the ATC.MODE\n * register, which is particularly important for user-defined fonts that do not want that bit replicated.\n */\n var bit = (fUnderline? 1 : (b & (0x80 >> (x >= 8 && iChar >= 0xC0 && iChar <= 0xDF? 7 : x))));\n var xDst = (x << nDouble);\n var yDst = (y << nDouble) + nRowDoubler;\n var rgb = (bit? rgbColor : rgbOff);\n this.setPixel(imageChar, xDst, yDst, rgb);\n if (nDouble) this.setPixel(imageChar, xDst + 1, yDst, rgb);\n }\n }\n }\n /*\n * (iChar >> 4) performs the integer equivalent of Math.floor(iChar / 16), and (iChar & 0xf) is the equivalent of (iChar % 16).\n */\n contextFont.putImageData(imageChar, x = (iChar & 0xf) * font.cxCell, y = (iChar >> 4) * font.cyCell);\n }\n\n /*\n * The colors for cell backgrounds and cursor elements must be converted to CSS color strings.\n */\n font.aCSSColors[iColor] = \"#\" + Str.toHex(rgbColor[0], 2) + Str.toHex(rgbColor[1], 2) + Str.toHex(rgbColor[2], 2);\n font.aRGBColors[iColor] = rgbColor;\n\n /*\n * Enable this code if you want to see what the generated font looks like....\n *\n if (MAXDEBUG) {\n var iSrcColor = (iColor == 15? 0 : iColor + 1);\n this.contextScreen.fillStyle = aCSSColors[iSrcColor];\n this.contextScreen.fillRect(iColor*(font.cxCell<<2), 0, canvasFont.width>>2, font.cyCell<<4);\n this.contextScreen.drawImage(canvasFont, 0, iColor*(font.cyCell<<4), canvasFont.width>>2, font.cyCell<<4, iColor*(font.cxCell<<2), 0, canvasFont.width>>2, font.cyCell<<4);\n }\n */\n\n font.aCanvas[iColor] = canvasFont;\n }\n\n /**\n * checkBlink()\n *\n * Called at the end of every updateScreenText(), which may have updated cBlinkVisible to a non-zero value.\n *\n * Also called at the end of every checkCursor(); ie, whenever the CRT register(s) affecting the position or shape\n * of the hardware cursor have been modified, and any of iCellCursor, yCursor or cyCursor have been modified as a result.\n *\n * Note that the cursor always blinks when it's ON; it can only be turned OFF, moved off-screen, or its rate set to half\n * the normal blink rate (by default, it blinks at the normal blink rate). Bits 5-6 of the CRTC.CURSCAN register can\n * be set as follows:\n *\n * 00: Cursor blinks at normal blink rate\n * 01: Cursor is off\n * 10: (Same as 00)\n * 11: Cursor blinks at half the normal blink rate\n *\n * According to documentation, the normal blink rate is 1/16 of the frame rate (8 frames on, 8 off).\n *\n * TODO: As an aside, I've observed in the \"real world\" that the MDA cursor cycles about 3 times per second, and by \"cycle\"\n * I mean one full off-and-on-again cycle. I'm assuming that's the normal rate (00), not the slower \"half rate\" (11).\n * Since that's faster than our current cursor blink rate, we should look into an option to boost our rate, without adversely\n * affecting the attribute blink rate (which is currently hard-coded at half the cursor blink rate), and we should look into\n * supporting \"half rate\" blinking, too.\n *\n * @this {Video}\n * @return {boolean} true if there are things to blink, false if not\n */\n checkBlink()\n {\n if (this.cBlinkVisible > 0 || this.iCellCursor >= 0) {\n if (this.cBlinks < 0) {\n this.cBlinks = 0;\n /*\n * At this point, we can either fire up our own timer (doBlink), or rely on updateScreen() being\n * called by the CPU at regular bursts (eg, Video.UPDATES_PER_SECOND = 60) and advance cBlinks at\n * the start of updateScreen() accordingly.\n *\n * doBlink() wants to increment cBlinks every 266ms. On the other hand, if updateScreen() is being\n * called 60 times per second, that's about once every 16ms, so if every 16th updateScreen() increments\n * cBlinks, cBlinks should advance at the same rate.\n *\n * One side-effect of relying on the CPU driving our blink count is that whenever the CPU is halted\n * (eg, by our Debugger) all blinking stops -- all characters with the blink attribute AND the cursor.\n *\n * But that's more consistent with how we halt everything else (eg, the PITs, RTC, etc); our Debugger\n * halts the entire machine, not just the CPU.\n *\n * this.doBlink(true);\n */\n }\n return true;\n }\n this.cBlinks = -1;\n return false;\n }\n\n /**\n * checkCursor()\n *\n * Called whenever a CRT data register is updated, since there are multiple registers that can affect the\n * visibility of the cursor (more than these, actually, but I'm going to limit my initial support to standard\n * ROM BIOS controller settings):\n *\n * CRTC.MAXSCAN\n * CRTC.CURSCAN\n * CRTC.CURSCANB\n * CRTC.STARTHI\n * CRTC.STARTLO\n * CRTC.CURSORHI\n * CRTC.CURSORLO\n * \n * The top of the cursor starts at CURSCAN, and the bottom is CURSCANB - 1, except that if CURSCAN == CURSCANB\n * (or more precisely, if CURSCAN == CURSCANB mod 16), then a single scan line is still drawn. Also, on the EGA,\n * if CURSCANB < CURSCAN, a split cursor is drawn.\n * \n * Also, at least on the EGA, if CURSCANB is set to a value > MAXSCAN (typically 13 on an EGA), cursor scan line\n * drawing wraps around to zero and does not stop until we reach CURSCAN again. However, this happens only when\n * CURSCAN is <= MAXSCAN; if CURSCAN > MAXSCAN, then nothing is drawn, regardless of CURSCANB.\n *\n * @this {Video}\n * @return {boolean} true if the cursor is visible, false if not\n */\n checkCursor()\n {\n /*\n * The \"hardware cursor\" is never visible in graphics modes.\n */\n if (!this.nFont) return false;\n \n var card = this.cardActive;\n for (var i = Card.CRTC.CURSCAN; i <= Card.CRTC.CURSORLO; i++) {\n if (card.regCRTData[i] == null)\n return false;\n }\n\n var bCursorFlags = card.regCRTData[Card.CRTC.CURSCAN];\n var bCursorStart = bCursorFlags & Card.CRTC.CURSCAN_SLMASK;\n var bCursorEnd = card.regCRTData[Card.CRTC.CURSCANB] & Card.CRTCMASKS[Card.CRTC.CURSCANB];\n var bCursorMax = card.regCRTData[Card.CRTC.MAXSCAN] & Card.CRTCMASKS[Card.CRTC.MAXSCAN];\n var oCursorStart = bCursorStart, oCursorEnd = bCursorEnd;\n \n /*\n * Before range-checking CURSCAN and CURSCANB, let's see if the cursor is disabled by a starting value\n * outside the visible range; if so, simulate the condition by pretending the CURSCAN_BLINKOFF bit is set.\n * \n * For example, on a CGA, ThinkTank sets both CURSCAN and CURSCANB to 15, WordStar for PCjr sets CURSCAN and\n * CURSCANB to 12 and 13, respectively, and Rogue sets CURSCAN and CURSCANB to 15 and 0, respectively.\n */\n if (bCursorStart > bCursorMax) {\n bCursorFlags |= Card.CRTC.CURSCAN_BLINKOFF;\n }\n\n var bCursorWrap = 0;\n \n if (this.nCard != Video.CARD.EGA) {\n /*\n * Live and learn: I originally thought that the EGA introduced funky split cursors, but it turns\n * out that older cards did it, too (well, I've confirmed it on an actual MDA anyway; haven't tried\n * the CGA). I've also confirmed that the MDA did NOT have the \"mod 16\" EGA anomaly described below. \n */\n if (bCursorEnd < bCursorStart) {\n bCursorWrap = bCursorEnd + 1;\n bCursorEnd = bCursorMax;\n /*\n * The VGA didn't support funky split (aka wrap-around) cursors, so as above, we pretend that the\n * cursor has simply been disabled.\n */\n if (this.nCard == Video.CARD.VGA) {\n bCursorFlags |= Card.CRTC.CURSCAN_BLINKOFF;\n bCursorWrap = 0;\n }\n }\n else if (bCursorEnd > bCursorMax) {\n bCursorStart = 0;\n bCursorEnd = bCursorMax;\n }\n bCursorEnd++;\n }\n else {\n /*\n * HACK: The original EGA BIOS has a cursor emulation bug when 43-line mode is enabled; we used to\n * detect that particular combination of bad values and automatically fix them (we're so thoughtful),\n * but in retrospect, that doesn't seem very faithful. Better to fix things like this 1) only if\n * the user asks, and 2) preferably with a BIOS patch rather than monkeying with the hardware registers.\n *\n * if (this.nCard == Video.CARD.EGA) {\n * if (bCursorMax == 7 && bCursorStart == 4 && !bCursorEnd) bCursorEnd = 7;\n * }\n */\n /*\n * Here's another strange EGA anomaly: if CURSCAN == CURSCANB mod 16, then it's treated the same as if\n * CURSCAN == CURSCANB. For example, if you set (CURSCAN,CURSCANB) to either the decimal values\n * (4,19) or (4,21), you'll get a full block cursor, but if you set it to (4,20), you get a single line\n * cursor at row 4. Go figure!\n */\n if (bCursorStart == bCursorEnd % 16) {\n bCursorEnd = bCursorStart + 1;\n }\n else if (bCursorEnd < bCursorStart) {\n bCursorWrap = bCursorEnd;\n bCursorEnd = bCursorMax + 1;\n }\n else if (bCursorEnd > bCursorMax) {\n bCursorStart = 0;\n bCursorEnd = bCursorMax + 1;\n }\n }\n \n var bCursorSize = bCursorEnd - bCursorStart;\n\n /*\n * One way of disabling the cursor is to set bit 5 (Card.CRTC.CURSCAN_BLINKOFF) of the CRTC.CURSCAN flags;\n * another way is setting bCursorStart > bCursorEnd, which implies that bCursorSize <= 0.\n */\n if ((bCursorFlags & Card.CRTC.CURSCAN_BLINKOFF) || bCursorSize <= 0) {\n this.removeCursor();\n return false;\n }\n\n /*\n * The least tricky way of disabling (ie, hiding) the cursor is to simply move it to an off-screen position.\n */\n var iCellCursor = card.regCRTData[Card.CRTC.CURSORLO];\n iCellCursor |= (card.regCRTData[Card.CRTC.CURSORHI] & card.addrMaskHigh) << 8;\n\n var offStartAddr = card.regCRTData[Card.CRTC.STARTLO];\n offStartAddr |= (card.regCRTData[Card.CRTC.STARTHI] & card.addrMaskHigh) << 8;\n \n iCellCursor -= offStartAddr;\n \n if (this.iCellCursor != iCellCursor) {\n //\n // let rowFrom = (this.iCellCursor / this.nCols)|0;\n // let colFrom = (this.iCellCursor % this.nCols);\n // let rowTo = (iCellCursor / this.nCols)|0;\n // let colTo = (iCellCursor % this.nCols);\n // this.printf(\"checkCursor(): cursor moved from %d,%d to %d,%d\\n\", rowFrom, colFrom, rowTo, colTo);\n // this.removeCursor();\n //\n this.iCellCursor = iCellCursor;\n /*\n * We invalidate cBlinkVisible on a cursor position change to ensure the cursor will be redrawn on the\n * next call to updateScreenCells(). It has the downside of requiring ALL cells to be re-examined, not\n * just the old and new cursor cells, but the cell cache should prevent any unnecessary redrawing.\n */\n this.cBlinkVisible = -1;\n }\n\n /*\n * yCursor and cyCursor are no longer scaled at this point, because the necessary scaling will depend on\n * whether we're drawing the cursor to the on-screen or off-screen buffer, and updateChar() is in the best\n * position to determine that.\n *\n * We also record cyCursorCell, the hardware cell height, since we'll need to know what the yCursor and\n * cyCursor values are relative to when it's time to scale them.\n */\n if (this.yCursor !== bCursorStart || this.cyCursor !== bCursorSize || this.cyCursorWrap !== bCursorWrap) {\n this.printf(\"checkCursor(): cursor shape changed from %d,%d to %d,%d (0x%02x-0x%02x)\\n\", this.yCursor, this.cyCursor, bCursorStart, bCursorSize, oCursorStart, oCursorEnd);\n this.yCursor = bCursorStart;\n this.cyCursor = bCursorSize;\n this.cyCursorWrap = bCursorWrap;\n /*\n * TODO: Consider our redraw options for cursor shape changes, because invalidating cBlinkVisible won't\n * have the desired effect if the cursor is still in the same location. The only existing mechanism for\n * making this happen would be to invalidate the cell cache (reset fCellCacheValid), which is rather drastic.\n * Note that we don't have to worry about this if the cursor has ALSO just moved (ie, this.cBlinkVisible < 0).\n */\n // if (this.cBlinkVisible >= 0) this.fCellCacheValid = false;\n }\n \n this.cyCursorCell = bCursorMax + 1;\n\n /*\n * This next condition is critical; WordStar for PCjr (designed for the CGA) would program CURSCANB to 31,\n * whereas MAXSCAN was 7. This resulted in cyCursorCell of 8 and cyCursor of 32, producing elongated cursors\n * in updateChar(). By range-checking CURSCAN and CURSCANB against MAXSCAN above, that should no longer happen.\n * \n * This condition can also happen while the CRT controller is in an inconsistent state (ie, in the middle of\n * being completely reprogrammed), so we mustn't freak out.\n */\n if (this.cyCursor > this.cyCursorCell) {\n this.cyCursor = this.cyCursorCell;\n }\n \n this.checkBlink();\n return true;\n }\n\n /**\n * removeCursor()\n *\n * @this {Video}\n */\n removeCursor()\n {\n if (this.iCellCursor >= 0) {\n if (this.aCellCache !== undefined && this.iCellCursor < this.aCellCache.length) {\n var drawCursor = (Video.ATTRS.DRAW_CURSOR << 8);\n var data = this.aCellCache[this.iCellCursor];\n if (data & drawCursor) {\n data &= ~drawCursor;\n var col = this.iCellCursor % this.nCols;\n var row = (this.iCellCursor / this.nCols)|0;\n if (this.nFont && this.aFonts[this.nFont]) {\n /*\n * If we're using an off-screen buffer in text mode, then we need to keep it in sync with \"reality\".\n */\n if (this.contextBuffer) {\n this.updateChar(col, row, data, this.contextBuffer);\n }\n /*\n * While updating the on-screen canvas directly could open us up to potential subpixel artifacts again,\n * I'm hopeful that won't be the case, since removeCursor() is called only during certain well-defined\n * events. The alternative to this simple updateChar() call is unappealing: redrawing the ENTIRE off-screen\n * buffer to the on-screen canvas, just as updateScreen() does.\n */\n this.updateChar(col, row, data);\n }\n this.printf(\"removeCursor(): removed from %d,%d\\n\", row, col);\n this.aCellCache[this.iCellCursor] = data;\n }\n }\n this.iCellCursor = -1;\n }\n }\n\n /**\n * getCardAccess()\n *\n * @this {Video}\n * @return {number|undefined} current memory access setting, or undefined if unknown\n */\n getCardAccess()\n {\n var nAccess;\n var card = this.cardActive;\n\n this.fColor256 = false;\n var regGRCMode = card.regGRCData[Card.GRC.MODE.INDX];\n if (regGRCMode != null) {\n var nReadAccess = Card.ACCESS.READ.MODE0;\n var nWriteAccess = Card.ACCESS.WRITE.MODE0;\n var nWriteMode = regGRCMode & Card.GRC.MODE.WRITE.MASK;\n var regDataRotate = card.regGRCData[Card.GRC.DATAROT.INDX] & Card.GRC.DATAROT.MASK;\n switch (nWriteMode) {\n case Card.GRC.MODE.WRITE.MODE0:\n if (regDataRotate) {\n nWriteAccess = Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.ROT;\n switch (regDataRotate & Card.GRC.DATAROT.FUNC) {\n case Card.GRC.DATAROT.AND:\n nWriteAccess = Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.AND;\n break;\n case Card.GRC.DATAROT.OR:\n nWriteAccess = Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.OR;\n break;\n case Card.GRC.DATAROT.XOR:\n nWriteAccess = Card.ACCESS.WRITE.MODE0 | Card.ACCESS.WRITE.XOR;\n break;\n default:\n break;\n }\n card.nDataRotate = regDataRotate & Card.GRC.DATAROT.COUNT;\n }\n break;\n case Card.GRC.MODE.WRITE.MODE1:\n nWriteAccess = Card.ACCESS.WRITE.MODE1;\n break;\n case Card.GRC.MODE.WRITE.MODE2:\n switch (regDataRotate & Card.GRC.DATAROT.FUNC) {\n default:\n nWriteAccess = Card.ACCESS.WRITE.MODE2;\n break;\n case Card.GRC.DATAROT.AND:\n nWriteAccess = Card.ACCESS.WRITE.MODE2 | Card.ACCESS.WRITE.AND;\n break;\n case Card.GRC.DATAROT.OR:\n nWriteAccess = Card.ACCESS.WRITE.MODE2 | Card.ACCESS.WRITE.OR;\n break;\n case Card.GRC.DATAROT.XOR:\n nWriteAccess = Card.ACCESS.WRITE.MODE2 | Card.ACCESS.WRITE.XOR;\n break;\n }\n break;\n case Card.GRC.MODE.WRITE.MODE3:\n if (this.nCard == Video.CARD.VGA) {\n nWriteAccess = Card.ACCESS.WRITE.MODE3;\n card.nDataRotate = regDataRotate & Card.GRC.DATAROT.COUNT;\n }\n break;\n default:\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"getCardAccess(): invalid GRC mode (\" + Str.toHexByte(regGRCMode) + \")\");\n }\n break;\n }\n if (regGRCMode & Card.GRC.MODE.READ.MODE1) {\n nReadAccess = Card.ACCESS.READ.MODE1;\n }\n /*\n * I discovered that when the IBM EGA ROM scrolls the screen in graphics modes 0x0D and 0x0E, it\n * reprograms this register for WRITE.MODE1 (which is fine) *and* EVENODD (which is, um, very odd).\n * Moreover, it does NOT make the complementary change to the SEQ.MEMMODE.SEQUENTIAL bit; under\n * normal circumstances, those two bits are always supposed to programmed oppositely.\n *\n * Until I can perform some tests on real hardware, I have to assume that the EGA scroll operation\n * is supposed to actually WORK in modes 0x0D and 0x0E, so I've decided to tie the trigger for my own\n * EVENODD functions to SEQ.MEMMODE.SEQUENTIAL being clear, instead of GRC.MODE.EVENODD being set.\n *\n * It's also possible that my EVENODD read/write functions are not implemented properly; when EVENODD\n * is in effect, which addresses get latched by a read, and to which addresses are latches written?\n * If EVENODD has no effect on the effective address used with the latches, then I should change the\n * EVENODD read/write functions accordingly.\n *\n * However, I've also done some limited testing with an emulated VGA running in text mode, and I've\n * discovered that toggling the GRC.MODE.EVENODD bit *alone* doesn't seem to affect the delivery of\n * text mode attributes from plane 1. So maybe this is the wiser change after all.\n *\n * TODO: Perform some tests on actual EGA/VGA hardware, to determine the proper course of action.\n *\n * if (regGRCMode & Card.GRC.MODE.EVENODD) {\n * nReadAccess |= Card.ACCESS.READ.EVENODD;\n * nWriteAccess |= Card.ACCESS.WRITE.EVENODD;\n * }\n */\n var regSEQMode = card.regSEQData[Card.SEQ.MEMMODE.INDX];\n if (regSEQMode != null) {\n if (!(regSEQMode & Card.SEQ.MEMMODE.SEQUENTIAL)) {\n nReadAccess |= Card.ACCESS.READ.EVENODD;\n nWriteAccess |= Card.ACCESS.WRITE.EVENODD;\n }\n if (regGRCMode & Card.GRC.MODE.COLOR256) {\n if (regSEQMode & Card.SEQ.MEMMODE.CHAIN4) {\n nReadAccess |= Card.ACCESS.READ.CHAIN4;\n nWriteAccess |= Card.ACCESS.WRITE.CHAIN4;\n }\n this.fColor256 = true;\n }\n }\n nAccess = nReadAccess | nWriteAccess;\n }\n return nAccess;\n }\n\n /**\n * setCardAccess(nAccess)\n *\n * @this {Video}\n * @param {number|undefined} nAccess (one of the Card.ACCESS.* constants)\n * @return {boolean} true if access may have changed, false if not\n */\n setCardAccess(nAccess)\n {\n var card = this.cardActive;\n if (card && nAccess != null && nAccess != card.nAccess) {\n\n this.printf(\"setCardAccess(0x%04x)\\n\", nAccess);\n\n card.setMemoryAccess(nAccess);\n\n /*\n * Note that setMemoryAccess() can fail, in which case it will an report error, indicating either a\n * misconfiguration or some sort of internal inconsistency; in any case, there's not much we can do about\n * it at this point, other than possibly reverting the current access setting. There's probably not much\n * point, however, because there's no guarantee that setMemoryAccess() didn't modify one or more blocks\n * before choking.\n */\n this.bus.setMemoryAccess(card.addrBuffer, card.sizeBuffer, card.getMemoryAccess(), true);\n return true;\n }\n return false;\n }\n\n /**\n * setDimensions()\n *\n * This is the workhorse of setMode()\n *\n * @this {Video}\n */\n setDimensions()\n {\n this.nFont = 0;\n this.nCols = this.nColsDefault;\n this.nRows = this.nRowsDefault;\n this.nColsLogical = this.nCols;\n this.nCellsPerWord = Video.aModeParms[Video.MODE.MDA_80X25][2];\n\n var cbPadding = 0;\n var modeParms = Video.aModeParms[this.nMode];\n if (modeParms) {\n\n this.nCols = modeParms[0];\n this.nRows = modeParms[1];\n this.nCellsPerWord = modeParms[2];\n cbPadding = modeParms[3]; // undefined for EGA/VGA graphics modes only\n this.nFont = modeParms[4]; // this will be undefined for all graphics modes\n\n if (this.nMonitorType == ChipSet.MONITOR.EGACOLOR || this.nMonitorType == ChipSet.MONITOR.VGACOLOR) {\n /*\n * When an EGA is connected to a CGA monitor, the old aModeParms table is correct: we must\n * use the hard-coded 8x8 \"CGA_80\" font. But when it's connected to an EGA monitor, we want\n * to use the 9x14 \"EGA\" color font instead.\n *\n * TODO: Can an EGA with a monochrome monitor be programmed for 43-line mode as well? If so,\n * then we'll need to load another MDA font variation, because we only load the 9x14 font for MDA.\n */\n if (this.cardActive === this.cardEGA && this.nFont == Video.FONT.CGA) {\n if ((this.cardEGA.regCRTData[Card.CRTC.EGA.MAXSCAN.INDX] & Card.CRTC.EGA.MAXSCAN.SLMASK) == 7) {\n /*\n * Vertical resolution of 350 divided by 8 (ie, scan lines 0-7) yields 43 whole rows.\n */\n this.nRows = this.cardEGA.getCRTCReg(Card.CRTC.EGA.VDEND) < 350? 43 : 50;\n }\n /*\n * Since we can also be called before any hardware registers have been initialized,\n * it may be best to not perform the following test (which is why it's commented out).\n */\n else /* if (this.cardEGA.regCRTData[Card.CRTC.EGA.MAXSCAN.INDX] == 13) */ {\n /*\n * Vertical resolution of 350 divided by 14 (ie, scan lines 0-13) yields exactly 25 rows.\n *\n * Note that a card's default font matches its card ID (eg, Video.CARD.EGA == Video.FONT.EGA,\n * and Video.CARD.VGA == Video.FONT.VGA)\n */\n this.nFont = this.nCard;\n }\n }\n }\n }\n\n this.nCells = (this.nCols * this.nRows)|0;\n this.nCellCache = (this.nCells / this.nCellsPerWord)|0;\n this.cbScreen = this.nCellCache;\n this.cbSplit = 0;\n\n if (cbPadding !== undefined) {\n this.cbScreen = ((this.cbScreen << 1) + cbPadding)|0;\n this.cbSplit = (this.cbScreen + cbPadding) >> 1;\n }\n\n /*\n * If no fonts were successfully loaded, there's no point in initializing the remaining drawing parameters.\n */\n if (!this.aFonts.length) return;\n\n this.cxScreenCell = (this.cxScreen / this.nCols)|0;\n this.cyScreenCell = (this.cyScreen / this.nRows)|0;\n\n if (this.nFont) {\n var font = this.aFonts[this.nFont];\n if (!font) {\n\n return;\n }\n /*\n * In text modes, we have the option of setting all the *Buffer variables to null instead of\n * allocating them, because updateChar(), as currently written, is capable of writing characters to\n * either an off-screen or on-screen context.\n *\n * this.imageBuffer = this.canvasBuffer = this.contextBuffer = null;\n */\n this.cxBuffer = this.cyBuffer = 0;\n if (font) {\n this.cxBuffer = this.nCols * font.cxCell;\n this.cyBuffer = this.nRows * font.cyCell;\n }\n } else {\n /*\n * CGA graphics modes have their \"cells\" (pixels) split evenly across two halves of the video buffer, with\n * EVEN scan lines in the first half and ODD scan lines in the second half, so unlike text modes, we can't set a\n * limit of what's visible on-screen to \"columns * rows\", so the screen limit is set to match the buffer limit.\n *\n * In addition, updateScreen() requires an off-screen imageData buffer that matches the size of the entire screen,\n * so that updateScreen() can set all pixels that have changed and then update the screen with a single drawImage().\n *\n * An alternative approach, with a smaller footprint, would be to allocate an off-screen buffer large enough for a\n * single scan line, and redraw one scan line at a time, but given how EVEN and ODD scan lines are spread across the\n * entire buffer, it's not clear there would be enough unchanged scan lines on average to make that approach faster.\n */\n this.cxScreenCell = this.cyScreenCell = 1; // in graphics mode, a cell is exactly one pixel\n this.cxBuffer = this.nCols;\n this.cyBuffer = this.nRows;\n }\n\n /*\n * Allocate the off-screen buffers\n */\n this.imageBuffer = this.contextScreen.createImageData(this.cxBuffer, this.cyBuffer);\n this.canvasBuffer = document.createElement(\"canvas\");\n this.canvasBuffer.width = this.cxBuffer;\n this.canvasBuffer.height = this.cyBuffer;\n this.contextBuffer = this.canvasBuffer.getContext(\"2d\");\n\n /*\n * Since cxCell and cyCell were originally defined in terms of cxScreen/nCols and cyScreen/nRows, you might think\n * these border calculations would always be zero, but that would mean you overlooked the code above which tries to\n * avoid stretching 40-column modes into an unpleasantly wide shape.\n */\n this.xScreenOffset = this.yScreenOffset = 0;\n this.cxScreenOffset = this.cxScreen;\n this.cyScreenOffset = this.cyScreen;\n\n var cxBorder = this.cxScreen - (this.nCols * this.cxScreenCell);\n var cyBorder = this.cyScreen - (this.nRows * this.cyScreenCell);\n if (cxBorder > 0) {\n this.xScreenOffset = (cxBorder >> 1);\n this.cxScreenOffset -= cxBorder;\n }\n if (cyBorder > 0) {\n this.yScreenOffset = (cyBorder >> 1);\n this.cyScreenOffset -= cyBorder;\n }\n if (cxBorder || cyBorder) {\n this.contextScreen.fillStyle = this.canvasScreen.style.backgroundColor;\n this.contextScreen.fillRect(0, 0, this.cxScreen, this.cyScreen);\n }\n }\n\n /**\n * checkMode(fForce)\n *\n * Called whenever the MDA/CGA's mode register (eg, Card.MDA.MODE.PORT, Card.CGA.MODE.PORT) is updated,\n * or whenever the EGA/VGA's GRC.MISC register is updated, or when we've just finished a restore().\n *\n * @this {Video}\n * @param {boolean} [fForce] is used to force a mode update, if we recognize the current mode\n * @return {boolean} true if successful, false if not\n */\n checkMode(fForce)\n {\n var nAccess;\n var nMode = this.nMode;\n var card = this.cardActive;\n\n if (!card) {\n /*\n * We are likely being called after a restore(), which needs us to call setMode() to insure the proper video\n * buffer is mapped in. So we unset this.nMode to guarantee that setMode() will be called, and if it wasn't set\n * to anything before, then we fall-back to the default mode.\n */\n this.nMode = null;\n if (nMode == null) nMode = this.nModeDefault;\n }\n else {\n if (card.nCard == Video.CARD.MDA) {\n nMode = Video.MODE.MDA_80X25;\n }\n else if (card.nCard >= Video.CARD.EGA) {\n /*\n * The sizeBuffer we choose reflects the amount of physical address space that all 4 planes\n * of EGA memory normally span, NOT the total amount of EGA memory. So for a 64Kb EGA card,\n * we would set card.sizeBuffer to 16Kb (0x4000).\n *\n * TODO: Need to take into account modes that \"chain\" planes together (eg, mode 0x0F, and\n * presumably mode 0x10, on an EGA card with only 64Kb).\n */\n nMode = null;\n var cbBuffer = card.cbMemory >> 2;\n var cbBufferText = (cbBuffer > 0x8000? 0x8000 : cbBuffer);\n\n var regGRCMisc = card.regGRCData[Card.GRC.MISC.INDX];\n if (regGRCMisc != null) {\n\n switch(regGRCMisc & Card.GRC.MISC.MAPMEM) {\n case Card.GRC.MISC.MAPA0128:\n card.addrBuffer = 0xA0000;\n card.sizeBuffer = cbBuffer; // 0x20000\n nMode = Video.MODE.UNKNOWN; // no BIOS mode uses this mapping, but we don't want to leave nMode null if we've come this far\n break;\n case Card.GRC.MISC.MAPA064:\n card.addrBuffer = 0xA0000;\n card.sizeBuffer = cbBuffer; // 0x10000\n nMode = (this.nMonitorType == ChipSet.MONITOR.MONO? Video.MODE.EGA_640X350_MONO : Video.MODE.EGA_640X350);\n break;\n case Card.GRC.MISC.MAPB032:\n card.addrBuffer = 0xB0000;\n card.sizeBuffer = cbBufferText;\n nMode = Video.MODE.MDA_80X25;\n break;\n case Card.GRC.MISC.MAPB832:\n card.addrBuffer = 0xB8000;\n card.sizeBuffer = cbBufferText;\n nMode = (this.nMonitorType == ChipSet.MONITOR.MONO? Video.MODE.CGA_80X25_BW : Video.MODE.CGA_80X25);\n break;\n default:\n break;\n }\n /*\n * TODO: The following mode discrimination code is all a bit haphazard, a byproduct of its slow evolution\n * from increasingly greater EGA support to increasingly greater VGA support. Make it more rational someday,\n * so that as support is added for even more modes (eg, \"Mode X\" variations, monochrome modes, etc), it\n * doesn't get totally out of control.\n *\n * One of the problems with the current approach is that it depends on the card's registers being programmed\n * in at least roughly the same order that the IBM EGA and VGA ROMs program them.\n */\n var regGRCMode = card.regGRCData[Card.GRC.MODE.INDX];\n\n /*\n * This text/graphics hybrid test detects the way Windows 95 reprograms the VGA on boot; ie, switching\n * to graphics mode 0x13 (320x200) without disturbing the text buffer contents, then reprogramming it\n * to enable graphics mode 0x15 (320x400), then drawing a logo in the 2nd half of the video memory, and\n * finally reprogramming regGRCMode and regGRCMisc to move the frame buffer back to its original text mode\n * location.\n */\n var fTextGraphicsHybrid = (regGRCMode & (Card.GRC.MODE.COLOR256 | Card.GRC.MODE.EVENODD)) == (Card.GRC.MODE.COLOR256 | Card.GRC.MODE.EVENODD);\n if (fTextGraphicsHybrid) {\n /*\n * When fTextGraphicsHybrid is true, we should be at the end of the above process, so addrBuffer\n * will have changed. Since we don't (yet) assign a special mode to that configuration, we must at\n * least set fForce to true, so that setMode() will notice the buffer address change and remap it.\n */\n if (card.addrBuffer != this.addrBuffer || card.sizeBuffer != this.sizeBuffer) {\n fForce = true;\n }\n }\n\n var nCRTCVertTotal = card.getCRTCReg(Card.CRTC.EGA.VTOTAL);\n var nCRTCMaxScan = card.regCRTData[Card.CRTC.EGA.MAXSCAN.INDX];\n var nCRTCModeCtrl = card.regCRTData[Card.CRTC.EGA.MODECTRL.INDX];\n\n var fSEQDotClock = (card.regSEQData[Card.SEQ.CLOCKING.INDX] & Card.SEQ.CLOCKING.DOTCLOCK);\n\n if (nMode != Video.MODE.UNKNOWN) {\n if (!(regGRCMisc & Card.GRC.MISC.GRAPHICS)) {\n /*\n * Here's where we handle text modes; since nMode will have been assigned a default\n * of either 0x02 or 0x03, convert that to either 0x05 or 0x04 if we're in a low-res\n * graphics mode, 0x06 otherwise.\n */\n nMode -= (fSEQDotClock? 2 : 0);\n }\n else if (card.addrBuffer != 0xA0000 && !fTextGraphicsHybrid && !(nCRTCModeCtrl & Card.CRTC.EGA.MODECTRL.COMPAT_MODE)) {\n /*\n * Here's where we handle CGA graphics modes; since nMode will have been assigned a\n * default of either 0x02 or 0x03, convert that to either 0x05 or 0x04 if we're in a\n * low-res graphics mode, 0x06 otherwise.\n *\n * For Windows 95, I've had to add BOTH the fTextGraphicsHybrid test, to avoid misdetecting\n * the logo display mode, AND the COMPAT_MODE test, to avoid misinterpreting the VDD's physical\n * (NOT logical) card reprogramming during windowed VM creation; the latter seems like a VDD bug,\n * because only the Windows display driver should be *physically* reprogramming the card then.\n */\n nMode = fSEQDotClock? (7 - nMode) : Video.MODE.CGA_640X200;\n } else {\n /*\n * Here's where we handle EGA/VGA graphics modes, discriminating among modes 0x0D and up;\n * we've already defaulted to either 0x0F or 0x10. If COLOR256 is set, then select mode\n * 0x13 (or greater), else if 200-to-400 scan-line conversion is in effect, select either\n * mode 0x0D or 0x0E, else if VGA resolution is set, select either mode 0x11 or 0x12.\n */\n if (card.regGRCData[Card.GRC.MODE.INDX] & Card.GRC.MODE.COLOR256) {\n if (nCRTCMaxScan & Card.CRTC.EGA.MAXSCAN.SLMASK) {\n /*\n * NOTE: Technically, VDEND is one of those CRTC registers that should be read using\n * card.getCRTCReg(), because there are overflow bits (8 and 9). However, all known modes\n * always SET bit 8 and CLEAR bit 9, so examining only bits 0-7 is sorta OK.\n */\n if (card.regCRTData[Card.CRTC.EGA.VDEND] <= 0x8F) {\n nMode = Video.MODE.VGA_320X200;\n }\n else { /* (card.regCRTData[Card.CRTC.EGA.VDEND] == 0xDF) */\n nMode = Video.MODE.VGA_320X240;\n }\n } else {\n nMode = Video.MODE.VGA_320X400;\n }\n }\n else if ((nCRTCMaxScan & Card.CRTC.EGA.MAXSCAN.CONVERT400) || nCRTCVertTotal < 350) {\n nMode = (fSEQDotClock? Video.MODE.EGA_320X200 : Video.MODE.EGA_640X200);\n } else if (nCRTCVertTotal >= 480) {\n nMode = (this.nMonitorType == ChipSet.MONITOR.MONO? Video.MODE.VGA_640X480_MONO : Video.MODE.VGA_640X480);\n }\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"checkMode(): nCRTCVertTotal=\" + nCRTCVertTotal + \", mode=\" + Str.toHexByte(nMode));\n }\n }\n }\n nAccess = this.getCardAccess();\n }\n }\n else if (card.regMode & Card.CGA.MODE.VIDEO_ENABLE) {\n /*\n * NOTE: For the CGA, we precondition any mode change on CGA.MODE.VIDEO_ENABLE being set, otherwise\n * we'll get spoofed by the ROM BIOS scroll code, which waits for vertical retrace and then turns CGA.MODE.VIDEO_ENABLE\n * off, using a hard-coded mode value (0x25) that does NOT necessarily match the the CGA video mode currently in effect.\n */\n if (!(card.regMode & Card.CGA.MODE.GRAPHIC_SEL)) {\n nMode = ((card.regMode & Card.CGA.MODE._80X25)? Video.MODE.CGA_80X25 : Video.MODE.CGA_40X25);\n if (card.regMode & Card.CGA.MODE.BW_SEL) {\n nMode -= 1;\n }\n } else {\n nMode = ((card.regMode & Card.CGA.MODE.HIRES_BW)? Video.MODE.CGA_640X200 : Video.MODE.CGA_320X200_BW);\n if (!(card.regMode & Card.CGA.MODE.BW_SEL)) {\n nMode -= 1;\n }\n }\n if (this.fOpacityReduced) {\n this.canvasScreen.style.opacity = \"1\";\n this.fOpacityReduced = false;\n }\n }\n else {\n /*\n * This code is responsible for simulating flicker on a CGA screen. Note that we have to also\n * call yieldCPU() to ensure that the browser \"comes up for air\" and honors the new opacity, otherwise\n * you'll see very intermittent flicker (which is actually more annoying than regular flicker, believe\n * it or not).\n *\n * You also have the option of setting opacityFlicker to something greater than zero (eg, \"0.5\") to\n * make the flicker less obtrusive; in fact, that might be more faithful to the persistence of a CGA\n * screen's phosphor. The downside is that if the VIDEO_ENABLE bit is ever turned for off a \"long time\",\n * then you'll be treated to a very unnatural persistence effect.\n */\n if (!this.fOpacityReduced && +this.opacityFlicker < 1) {\n this.fOpacityReduced = true;\n this.canvasScreen.style.opacity = this.opacityFlicker;\n this.cpu.yieldCPU();\n }\n }\n }\n\n /*\n * NOTE: If setMode() remaps the video memory, that will trigger calls to setCardAccess() to also update the\n * memory's access functions. However, if the memory access setting (nAccess) is about to change as well, those\n * changes will be moot until the setCardAccess() call that follows. Basically, whenever both memory mapping AND\n * access functions are changing, the memory will be in an inconsistent state until both setMode() and setCardAccess()\n * are finished.\n *\n * The setMode() call takes precedence; if we called setCardAccess() first, it might attempt to modify memory access\n * functions based on the card's addrBuffer setting, and if that doesn't match what's currently mapped, assertions\n * will be triggered (probably not fatal, but it would defeat the point of the assertions).\n */\n if (!this.setMode(nMode, fForce)) return false;\n\n this.setCardAccess(nAccess);\n\n return true;\n }\n\n /**\n * setMode(nMode, fForce)\n *\n * Set fForce to true to update the mode regardless of previous mode, or false to perform a normal update\n * that bypasses updateScreen() but still calls initCache().\n *\n * @this {Video}\n * @param {number|null} nMode\n * @param {boolean|undefined} [fForce] is set when checkMode() wants to force a mode update\n * @return {boolean} true if successful, false if failure\n */\n setMode(nMode, fForce)\n {\n if (nMode != null && (nMode != this.nMode || fForce)) {\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"setMode(\" + Str.toHexByte(nMode) + (fForce? \",force\" : \"\") + \")\", true, true);\n }\n\n this.cUpdates = 0; // count updateScreen() calls as a means of driving blink updates\n this.nMode = nMode;\n this.fRGBValid = false;\n\n /*\n * On an EGA, it's CRITICAL that a reset() invalidate cardActive, to ensure that the code below\n * releases the previous video buffer and installs a new one, even if there was no change in the\n * video buffer address or size, because otherwise the Memory blocks installed at the video buffer\n * address may still be using blocks of the EGA's previous memory buffer.\n *\n * When the EGA is reinitialized, a new memory buffer (adwMemory) is allocated (see initEGA()), and\n * this is where the mapping of that EGA memory buffer to the video buffer occurs. Other cards\n * (MDA or CGA) don't allocate/manage their own memory buffer, but even then, it's still a good idea\n * to always force this operation (eg, in case a switch setting changed the active video card).\n */\n var card = this.cardActive || (nMode == Video.MODE.MDA_80X25? this.cardMono : this.cardColor);\n\n if (card != this.cardActive || card.addrBuffer != this.addrBuffer || card.sizeBuffer != this.sizeBuffer) {\n\n this.removeCursor();\n\n if (this.addrBuffer) {\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"setMode(\" + Str.toHexByte(nMode) + \"): removing \" + Str.toHexLong(this.sizeBuffer) + \" bytes from \" + Str.toHexLong(this.addrBuffer));\n }\n\n if (!this.bus.removeMemory(this.addrBuffer, this.sizeBuffer)) {\n /*\n * TODO: Force this failure case and see how well the Video component deals with it.\n */\n return false;\n }\n if (this.cardActive) this.cardActive.fActive = false;\n }\n\n this.cardActive = card;\n card.fActive = true;\n\n this.addrBuffer = card.addrBuffer;\n this.sizeBuffer = card.sizeBuffer;\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"setMode(\" + Str.toHexByte(nMode) + \"): adding \" + Str.toHexLong(this.sizeBuffer) + \" bytes to \" + Str.toHexLong(this.addrBuffer));\n }\n\n var controller = (card === this.cardEGA? card : null);\n\n if (!this.bus.addMemory(card.addrBuffer, card.sizeBuffer, Memory.TYPE.VIDEO, controller)) {\n /*\n * TODO: Force this failure case and see how well the Video component deals with it.\n */\n return false;\n }\n }\n this.setDimensions();\n this.invalidateCache(true);\n this.updateScreen();\n }\n return true;\n }\n\n /**\n * setPixel(imageData, x, y, rgb)\n *\n * Worker function used by createFontColor() and updateScreen() (graphics modes only).\n *\n * @this {Video}\n * @param {Object} imageData\n * @param {number} x\n * @param {number} y\n * @param {Array.<number>} rgb is a 4-element array containing the red, green, blue and alpha values\n */\n setPixel(imageData, x, y, rgb)\n {\n var index = (x + y * imageData.width) * rgb.length;\n imageData.data[index] = rgb[0];\n imageData.data[index+1] = rgb[1];\n imageData.data[index+2] = rgb[2];\n imageData.data[index+3] = rgb[3];\n }\n\n /**\n * initCache()\n *\n * Initializes the contents of our internal cell cache.\n *\n * TODO: Consider changing this to a cache of RGB values, so that when the buffer is merely being color-cycled,\n * we don't have to update the entire screen. This will also allow invalidateCache() to honor the fModified flag,\n * bypassing initCache() when it is false.\n *\n * @this {Video}\n */\n initCache()\n {\n this.cBlinkVisible = -1; // force updateScreen() to recount visible blinking characters \n this.fCellCacheValid = false;\n var nCells = this.nCellCache;\n if (this.aCellCache === undefined || this.aCellCache.length != nCells) {\n this.aCellCache = new Array(nCells);\n }\n }\n\n /**\n * invalidateCache(fModified)\n *\n * Ensure that the next updateScreen() will update every cell; intended for situations where the entire screen needs\n * to be redrawn, even though the underlying data in the video buffer has not changed (and therefore cleanMemory() will\n * report that the buffer is still clean, and/or all the video data still matches everything in our cell cache).\n *\n * For example, when the palette is being cycled, the screen is being panned, the page is being flipped, etc.\n *\n * @this {Video}\n * @param {boolean} [fModified] (true if the buffer may have been modified, false if only color(s) may have changed)\n */\n invalidateCache(fModified)\n {\n if (!fModified) this.fRGBValid = false;\n this.initCache();\n }\n\n /**\n * updateChar(col, row, data, context)\n *\n * Updates a particular character cell (row,col) in the associated window.\n *\n * The data parameter is the attribute byte from the display buffer (fgnd attribute in the low nibble,\n * bgnd attribute in the high nibble), but updateScreen() supplements data with a couple internal attribute bits:\n *\n * ATTRS.DRAW_FGND: set for every cell whose fgnd element is currently on (ie, non-blinking, or whenever blink is on)\n * ATTRS.DRAW_CURSOR: set only for the cell containing the cursor, if any\n *\n * To make a character blink, we alternately draw its cell with ATTRS.DRAW_FGND set, and then again with\n * ATTRS.DRAW_FGND clear (meaning only the cell background is drawn).\n *\n * To make the cursor blink, we must alternately draw its entire cell with ATTRS.DRAW_CURSOR set, and then\n * draw it again with ATTRS.DRAW_CURSOR clear.\n *\n * @this {Video}\n * @param {number} col\n * @param {number} row\n * @param {number} data (if text mode, character code in low byte, attribute code in high byte)\n * @param {CanvasRenderingContext2D} [context]\n */\n updateChar(col, row, data, context)\n {\n /*\n * The caller MUST promise this.nFont is defined, and that the font in this.aFonts[this.nFont] has been loaded.\n */\n var bChar = data & 0xff;\n var bAttr = data >> 8;\n var iFgnd = bAttr & 0xf;\n var font = this.aFonts[this.nFont];\n if (font.aColorMap) iFgnd = font.aColorMap[iFgnd];\n\n /*\n * Just as aColorMap maps the foreground attribute to the appropriate foreground character grid,\n * it also maps the background attribute to the appropriate background color.\n */\n var xDst, yDst;\n var iBgnd = (bAttr >> 4) & 0xf;\n if (font.aColorMap) iBgnd = font.aColorMap[iBgnd];\n\n if (context) {\n xDst = col * font.cxCell;\n yDst = row * font.cyCell;\n context.fillStyle = font.aCSSColors[iBgnd];\n context.fillRect(xDst, yDst, font.cxCell, font.cyCell);\n } else {\n xDst = col * this.cxScreenCell + this.xScreenOffset;\n yDst = row * this.cyScreenCell + this.yScreenOffset;\n this.contextScreen.fillStyle = font.aCSSColors[iBgnd];\n this.contextScreen.fillRect(xDst, yDst, this.cxScreenCell, this.cyScreenCell);\n }\n\n if (MAXDEBUG && this.messageEnabled(Messages.VIDEO | Messages.BUFFER)) {\n this.log(\"updateCharBgnd(\" + col + \",\" + row + \",\" + bChar + \"): filled \" + xDst + \",\" + yDst);\n }\n\n if (bAttr & Video.ATTRS.DRAW_FGND) {\n /*\n * (bChar & 0xf) is the equivalent of (bChar % 16), and (bChar >> 4) is the equivalent of Math.floor(bChar / 16)\n */\n var xSrcFgnd = (bChar & 0xf) * font.cxCell;\n var ySrcFgnd = (bChar >> 4) * font.cyCell;\n\n if (MAXDEBUG && this.messageEnabled(Messages.VIDEO | Messages.BUFFER)) {\n this.log(\"updateCharFgnd(\" + col + \",\" + row + \",\" + bChar + \"): draw from \" + xSrcFgnd + \",\" + ySrcFgnd + \" (\" + font.cxCell + \",\" + font.cyCell + \") to \" + xDst + \",\" + yDst);\n }\n\n if (context) {\n context.drawImage(font.aCanvas[iFgnd], xSrcFgnd, ySrcFgnd, font.cxCell, font.cyCell, xDst, yDst, font.cxCell, font.cyCell);\n } else {\n this.contextScreen.drawImage(font.aCanvas[iFgnd], xSrcFgnd, ySrcFgnd, font.cxCell, font.cyCell, xDst, yDst, this.cxScreenCell, this.cyScreenCell);\n }\n }\n\n if (bAttr & Video.ATTRS.DRAW_CURSOR) {\n if (this.cyCursorWrap) {\n this.drawCursor(0, this.cyCursorWrap, xDst, yDst, iFgnd, font, context);\n }\n this.drawCursor(this.yCursor, this.cyCursor, xDst, yDst, iFgnd, font, context);\n }\n }\n\n /**\n * drawCursor(yCursor, cyCursor, xDst, yDst, iFgnd, font, context)\n *\n * We have factored the cursor-drawing code out of updateChar() so that we can call this function multiple times,\n * in case we have to draw a \"split cursor\" (something that only happens on the EGA).\n *\n * @this {Video}\n * @param {number} yCursor\n * @param {number} cyCursor\n * @param {number} xDst\n * @param {number} yDst\n * @param {number} iFgnd\n * @param {Font} font\n * @param {CanvasRenderingContext2D} [context]\n */\n drawCursor(yCursor, cyCursor, xDst, yDst, iFgnd, font, context)\n {\n /*\n * Drawing the cursor with lineTo() seemed logical, but it was complicated by the fact that the\n * TOP of the line must appear at \"yDst + this.yCursor\", whereas lineTo() wants to know the CENTER\n * of the line. So it's simpler to draw the cursor with another fillRect(). Here's the old code:\n *\n * this.contextScreen.strokeStyle = font.aCSSColors[iFgnd];\n * this.contextScreen.lineWidth = this.cyCursor;\n * this.contextScreen.beginPath();\n * this.contextScreen.moveTo(xDst, yDst + this.yCursor);\n * this.contextScreen.lineTo(xDst + this.cxScreenCell, yDst + this.yCursor);\n * this.contextScreen.stroke();\n *\n * Also, note that we're scaling the yCursor and cyCursor values here, instead of in checkCursor(), because\n * this is where we have all the required information: in the first case (off-screen buffer), the scaling must\n * be based on the font cell size (cxCell, cyCell), whereas in the second case (on-screen buffer), the scaling\n * must be based on the screen cell size (cxScreenCell,cyScreenCell).\n *\n * yCursor and cyCursor are actual hardware values, both relative to another hardware value: cyCursorCell.\n */\n if (context) {\n if (this.cyCursorCell && this.cyCursorCell !== font.cyCell) {\n yCursor = Math.round((yCursor * font.cyCell) / this.cyCursorCell);\n cyCursor = Math.round((cyCursor * font.cyCell) / this.cyCursorCell);\n }\n context.fillStyle = font.aCSSColors[iFgnd];\n context.fillRect(xDst, yDst + yCursor, font.cxCell, cyCursor);\n } else {\n if (this.cyCursorCell && this.cyCursorCell !== this.cyScreenCell) {\n yCursor = Math.round((yCursor * this.cyScreenCell) / this.cyCursorCell);\n cyCursor = Math.round((cyCursor * this.cyScreenCell) / this.cyCursorCell);\n }\n this.contextScreen.fillStyle = font.aCSSColors[iFgnd];\n this.contextScreen.fillRect(xDst, yDst + yCursor, this.cxScreenCell, cyCursor);\n }\n }\n\n /**\n * updateScreen(fForce)\n *\n * Propagates the video buffer to the cell cache and updates the screen with any changes. Forced updates\n * are generally internal updates triggered by an I/O operation or other state change, while non-forced updates\n * are the periodic updates coming from the CPU.\n *\n * @this {Video}\n * @param {boolean} [fForce] is used by setMode() to reset the cell cache and force a redraw\n */\n updateScreen(fForce = false)\n {\n /*\n * The Computer component maintains the fPowered setting on our behalf, so we use it.\n */\n if (!this.flags.powered) return;\n\n /*\n * If the card's video signal is disabled (eg, during a mode change), then skip the update,\n * unless fForce is set.\n */\n var fEnabled = false;\n var card = this.cardActive;\n\n if (card) {\n if (card !== this.cardEGA) {\n if (card.regMode & Card.CGA.MODE.VIDEO_ENABLE) fEnabled = true;\n }\n else {\n if (card.regATCIndx & Card.ATC.INDX_PAL_ENABLE) fEnabled = true;\n }\n }\n\n if (!fEnabled && !fForce) return;\n\n if (fForce) {\n this.initCache();\n }\n else {\n /*\n * This should never happen, but since updateScreen() is also called by Computer.updateStatus(),\n * better safe than sorry.\n */\n if (this.aCellCache === undefined) return;\n }\n\n /*\n * If cBlinks is \"enabled\" (ie, >= 0), then advance it once every 16 updateScreen() calls\n * (assuming an updateScreen() frequency of 60 per second; see Video.UPDATES_PER_SECOND).\n *\n * We assume that the CPU is calling us whenever fForce is undefined.\n */\n var fBlinkUpdate = false;\n if (!fForce && !(++this.cUpdates & 0xf) && this.cBlinks >= 0) {\n this.cBlinks++;\n fBlinkUpdate = true;\n }\n\n var iCell = 0;\n var nCells = this.nCells;\n\n /*\n * Calculate the VISIBLE start of screen memory (addrScreen), not merely the PHYSICAL start,\n * as well as the extent of it (cbScreen) and use those values for all addressing operations to follow.\n * FYI, in these calculations, offScreen does not refer to \"off-screen\" memory, but rather the \"offset\"\n * of the start of visible screen memory.\n */\n var addrBuffer = this.addrBuffer;\n var addrScreen = addrBuffer;\n var addrScreenLimit = addrScreen + this.sizeBuffer;\n\n /*\n * HACK: To deal with the fTextGraphicsHybrid 320x400 mode that Windows 95 uses (ie, when the buffer\n * is mapped to B800:0000 instead of A000:0000 and is configured for text mode access, but graphics are\n * still being displayed from the second half of video memory), we must ignore the programmed address.\n *\n * In that case, the hard-coded address range below isn't actually active either, but it doesn't matter;\n * we just have to get through the rest of this function and make it to the updateScreenGraphicsVGA() call,\n * which will draw from our video buffer (adwMemory) directly; these addresses are only used for bounds\n * checking.\n */\n if (this.nMode >= Video.MODE.VGA_320X200) {\n addrBuffer = addrScreen = 0xA0000;\n addrScreenLimit = addrScreen + 0x10000;\n }\n\n /*\n * HACK: The CRTC's STARTHI and STARTLO registers are supposed to be \"latched\" into offStartAddr\n * ONLY at the start of every VRETRACE interval; this is an attempt to honor that behavior,\n * but unfortunately, updateScreen() is currently called at the CPU's discretion, not necessarily in\n * sync with nCyclesVertPeriod. As a result, we must rely on other criteria, like the number of vertical\n * periods that have elapsed since the last CRTC write, writes to the ATC (see outATC()), etc.\n *\n * TODO: Consider matching the CPU's nCyclesNextVideoUpdate to the card's nCyclesVertPeriod, ensuring\n * that CPU bursts are in sync with VRETRACE. Note, however, that that will be complicated by other\n * factors, such as the horizontal retrace interval, and the timing requirements of other cards in a\n * multi-display configuration.\n */\n if ((this.getRetraceBits(card) & Card.CGA.STATUS.VRETRACE) || card.nVertPeriodsStartAddr && card.nVertPeriodsStartAddr < card.nVertPeriods) {\n /*\n * PARANOIA: Don't call invalidateCache() unless the address we're about to \"latch\" actually changed.\n */\n var offStartAddr = card.regCRTData[Card.CRTC.STARTLO];\n offStartAddr |= (card.regCRTData[Card.CRTC.STARTHI] & card.addrMaskHigh) << 8;\n if (card.offStartAddr !== offStartAddr) {\n card.offStartAddr = offStartAddr;\n this.invalidateCache();\n }\n card.nVertPeriodsStartAddr = 0;\n }\n\n /*\n * Any screen (aka \"page\") offset must be doubled for text modes, due to the attribute bytes.\n * TODO: Come up with a more robust method of deciding when any screen offset should be doubled.\n */\n addrScreen += card.offStartAddr << (this.nFont? 1 : 0);\n var cbScreen = this.cbScreen;\n\n if (this.nCard >= Video.CARD.EGA && card.regCRTData[Card.CRTC.EGA.OFFSET] && (card.regCRTData[Card.CRTC.EGA.OFFSET] << 1) != card.regCRTData[Card.CRTC.EGA.HDEND] + 1) {\n /*\n * Pre-EGA, the extent of visible screen memory (cbScreen) was derived from nCols * nRows, but since\n * then, the logical width of screen memory (nColsLogical) can differ from the visible width (nCols).\n * We now calculate the logical width, and the compute a new cbScreen in much the same way the original\n * cbScreen was computed (but without any CGA-related padding considerations).\n *\n * TODO: I'm taking a lot of shortcuts in this calculation (eg, relying on nFont to detect text modes,\n * ignoring MODECTRL.BYTE_MODE, etc); generalize this someday. In addition, dividing the total number of\n * cells by nCellsPerWord yields total WORDS, not BYTES, so we need to double cbScreen -- EXCEPT that the\n * notion of cell has a slightly different meaning for EGA and VGA-specific modes. nCellsPerWord should\n * not be overloaded like that.\n */\n this.nColsLogical = card.regCRTData[Card.CRTC.EGA.OFFSET] << (this.nFont? 1 : (card.regCRTData[Card.CRTC.EGA.UNDERLINE.INDX] & Card.CRTC.EGA.UNDERLINE.DWORD)? 3 : 4);\n cbScreen = ((this.nColsLogical * (this.nRows-1) + this.nCols) / this.nCellsPerWord)|0;\n if (this.nMode <= Video.MODE.MDA_80X25) cbScreen <<= 1;\n }\n\n /*\n * If the amount of data (cbScreen) we need to display goes beyond the end of the screen buffer\n * (addrScreenLimit), then the assumption is that we will have to do a second update operation that\n * wraps around to addrBuffer.\n */\n var addrScreenWrap = 0, cbScreenWrap = 0;\n if (addrScreen + cbScreen > addrScreenLimit) {\n /*\n * There are two possibilities here: addrScreen itself is at or beyond addrScreenLimit, or just a\n * portion of cbScreen goes beyond the limit. We'll deal with the first case first.\n */\n cbScreenWrap = cbScreen;\n if (addrScreen >= addrScreenLimit) {\n addrScreenWrap = addrBuffer + (addrScreen - addrScreenLimit);\n cbScreen = 0;\n } else {\n addrScreenWrap = addrBuffer;\n cbScreen = addrScreenLimit - addrScreen;\n cbScreenWrap -= cbScreen;\n }\n }\n /*\n * updateScreenCells() no longer \"scrubs\" the screen buffer itself; we call cleanMemory() afterward\n * to take care of that. This has two benefits: 1) if this was a \"forced\" updated (or an update to make\n * the cell cache valid), cleaning the screen buffer ourselves reflects the fact that both it and our\n * display are now \"in sync\"; 2) if screen wrap-around is in effect, we don't want to scrub either subset\n * of the screen until both subsets have been updated, otherwise the second update may erroneously think\n * that nothing changed if it happens to share any blocks with the first.\n */\n var cBlinkOrig = this.cBlinkVisible;\n var cCells = this.updateScreenCells(addrBuffer, addrScreen, cbScreen, iCell, nCells, fForce, fBlinkUpdate);\n if (cbScreenWrap) {\n iCell += cCells;\n var cBlinkNew = this.cBlinkVisible;\n if (cBlinkOrig < 0) this.cBlinkVisible = -1;\n cCells += this.updateScreenCells(addrBuffer, addrScreenWrap, cbScreenWrap, iCell, nCells, fForce, fBlinkUpdate);\n this.cBlinkVisible += cBlinkNew;\n this.bus.cleanMemory(addrScreenWrap, cbScreenWrap);\n }\n this.bus.cleanMemory(addrScreen, cbScreen);\n if (cCells) this.fCellCacheValid = true;\n }\n\n /**\n * updateScreenCells(addrBuffer, addrScreen, cbScreen, iCell, nCells, fForce, fBlinkUpdate)\n *\n * @this {Video}\n * @param {number} addrBuffer\n * @param {number} addrScreen\n * @param {number} cbScreen\n * @param {number} iCell\n * @param {number} nCells\n * @param {boolean} fForce\n * @param {boolean} fBlinkUpdate\n * @return {number} (number of cells processed)\n */\n updateScreenCells(addrBuffer, addrScreen, cbScreen, iCell, nCells, fForce, fBlinkUpdate)\n {\n var cCells = cbScreen >> 1;\n if (cCells > nCells) cCells = nCells;\n var addrScreenLimit = addrScreen + cbScreen;\n\n /*\n * This next bit of code can be completely disabled if we discover problems with the dirty\n * memory block tracking feature, or if we need to remove or disable that feature in the future.\n *\n * We use cleanMemory() to check the video buffer's dirty state. If the buffer is clean\n * AND there are no visible blinking characters (as of the last updateScreen) AND there is\n * no visible cursor, then we're done; simply return. Otherwise, if there's only a blinking\n * cursor, then update JUST that one cell.\n */\n if (!fForce && this.fCellCacheValid && this.bus.cleanMemory(addrScreen, cbScreen, true)) {\n if (!fBlinkUpdate && this.cBlinkVisible >= 0) {\n return cCells;\n }\n if (!this.cBlinkVisible) {\n /*\n * iCellCursor may be negative if the cursor is hidden or if it's not on the visible screen.\n */\n var iCellCursor = this.iCellCursor - iCell;\n if (iCellCursor < 0) {\n return cCells;\n }\n addrScreen += (iCellCursor << 1);\n iCell += iCellCursor;\n nCells = iCell + 1;\n }\n // else if (this.cBlinks & 0x1) return;\n }\n\n if (this.nFont) {\n /*\n * This is the text-mode update case. We're required to FIRST verify that the current font\n * has been successfully loaded, because we're not allowed to call updateChar() if there's no font.\n */\n if (this.aFonts[this.nFont]) {\n this.updateScreenText(addrScreen, addrScreenLimit, iCell, nCells);\n }\n }\n else if (this.cbSplit) {\n /*\n * All CGA graphics modes have the goofy split-buffer layout, hence the simple test above.\n */\n cCells = this.updateScreenGraphicsCGA(addrScreen, addrScreenLimit);\n }\n else if (!this.fColor256) {\n /*\n * All EGA graphics modes are taken care of here, including all 16-color VGA graphics modes.\n */\n cCells = this.updateScreenGraphicsEGA(addrBuffer, addrScreen, addrScreenLimit);\n }\n else {\n /*\n * Finally, all 256-color VGA modes are processed here.\n */\n cCells = this.updateScreenGraphicsVGA(addrBuffer, addrScreen, addrScreenLimit);\n }\n return cCells;\n }\n\n /**\n * updateScreenText(addrScreen, addrScreenLimit, iCell, nCells)\n *\n * @this {Video}\n * @param {number} addrScreen\n * @param {number} addrScreenLimit\n * @param {number} iCell\n * @param {number} nCells\n * @return {number} (number of cells processed)\n */\n updateScreenText(addrScreen, addrScreenLimit, iCell, nCells)\n {\n /*\n * If MDA.MODE.BLINK_ENABLE is set and a cell's blink bit is set, then if (cBlinks & 0x2) != 0,\n * we want the foreground element of the cell to be drawn; otherwise we don't. So every 16-bit\n * data word we pull from the video buffer will be supplemented with our own special attribute bit\n * (ATTRS.DRAW_FGND = 0x100) accordingly; and to simplify the drawing code, we will also mask the\n * blink bit from the cell's attribute bits.\n *\n * If MDA.MODE.BLINK_ENABLE is clear, then we always set ATTRS.DRAW_FGND and never mask the blink\n * bit in a cell's attributes bits, since it's actually an intensity bit in that case.\n */\n var cCells = 0, cUpdated = 0;\n var dataBlink = 0;\n var dataDraw = (Video.ATTRS.DRAW_FGND << 8);\n var dataMask = 0xfffff;\n var fBlinkEnable = (this.cardActive.regMode & Card.MDA.MODE.BLINK_ENABLE);\n if (this.nCard >= Video.CARD.EGA) {\n fBlinkEnable = (this.cardActive.regATCData[Card.ATC.MODE.INDX] & Card.ATC.MODE.BLINK_ENABLE);\n }\n\n if (fBlinkEnable) {\n dataBlink = (Video.ATTRS.BGND_BLINK << 8);\n dataMask &= ~dataBlink;\n if (!(this.cBlinks & 0x2)) dataMask &= ~dataDraw;\n }\n\n this.cBlinkVisible = 0;\n while (addrScreen < addrScreenLimit && iCell < nCells) {\n var data = this.bus.getShortDirect(addrScreen);\n data |= dataDraw;\n if (data & dataBlink) {\n this.cBlinkVisible++;\n data &= dataMask;\n }\n if (iCell == this.iCellCursor) {\n data |= ((this.cBlinks & 0x1)? (Video.ATTRS.DRAW_CURSOR << 8) : 0);\n }\n\n if (!this.fCellCacheValid || data !== this.aCellCache[iCell]) {\n var col = iCell % this.nCols;\n var row = (iCell / this.nCols)|0;\n /*\n * The following code is useful for setting a breakpoint (on the non-destructive \"cUpdated |= 0\" line)\n * when debugging the \"FlickerFree\" utility while doing a series of \"DIR\" listings on the screen. When\n * unusual data gets rendered past column 40, we've caught the utility clearing memory revealed by a\n * scroll.\n *\n * if (col > 40 && data != 106272) {\n * cUpdated |= 0;\n * }\n *\n * TODO: How do we prevent that data from being displayed until the code has finished clearing it?\n * One trick would be to extend the current CPU burst slightly every time the STATUS register is read\n * with the RETRACE bit set, since it's only at the end of those bursts that we do other things like\n * update timers, update the screen, etc.\n *\n * FYI, to see what that \"FlickerFree\" code looks like, see the inCardStatus() function.\n */\n this.updateChar(col, row, data, this.contextBuffer);\n this.aCellCache[iCell] = data;\n cUpdated++;\n }\n addrScreen += 2;\n cCells++;\n iCell++;\n }\n\n if (cUpdated && this.contextBuffer) {\n this.contextScreen.drawImage(this.canvasBuffer, 0, 0, this.cxBuffer, this.cyBuffer, this.xScreenOffset, this.yScreenOffset, this.cxScreenOffset, this.cyScreenOffset);\n }\n \n this.checkBlink();\n return cCells;\n }\n\n /**\n * updateScreenGraphicsCGA(addrScreen, addrScreenLimit)\n *\n * @this {Video}\n * @param {number} addrScreen\n * @param {number} addrScreenLimit\n * @return {number} (number of cells processed)\n */\n updateScreenGraphicsCGA(addrScreen, addrScreenLimit)\n {\n /*\n * This is the CGA graphics-mode update case, where cells are pixels spread across two halves of the buffer.\n */\n var cCells = (addrScreenLimit - addrScreen) >> 1;\n var iCell = 0, nPixelsPerCell = this.nCellsPerWord;\n var addr = addrScreen;\n var wPixelMask = (nPixelsPerCell == 16? 0x10000 : 0x30000);\n var nPixelShift = (nPixelsPerCell == 16? 1 : 2);\n var aPixelColors = this.getCardColors(nPixelShift);\n\n var x = 0, y = 0;\n var xDirty = this.nCols, xMaxDirty = 0, yDirty = this.nRows, yMaxDirty = 0;\n\n this.cBlinkVisible = 0;\n while (addr < addrScreenLimit) {\n var data = this.bus.getShortDirect(addr);\n\n if (this.fCellCacheValid && data === this.aCellCache[iCell]) {\n x += nPixelsPerCell;\n } else {\n this.aCellCache[iCell] = data;\n var wPixels = (data >> 8) | ((data & 0xff) << 8);\n var wMask = wPixelMask, nShift = 16;\n if (x < xDirty) xDirty = x;\n for (var iPixel = 0; iPixel < nPixelsPerCell; iPixel++) {\n var bPixel = (wPixels & (wMask >>= nPixelShift)) >> (nShift -= nPixelShift);\n this.setPixel(this.imageBuffer, x++, y, aPixelColors[bPixel]);\n }\n if (x > xMaxDirty) xMaxDirty = x;\n if (y < yDirty) yDirty = y;\n if (y >= yMaxDirty) yMaxDirty = y + 1;\n }\n addr += 2;\n iCell++;\n if (x >= this.nCols) {\n x = 0;\n y += 2;\n if (y > this.nRows)\n break;\n if (y == this.nRows) {\n y = 1;\n addr = addrScreen + this.cbSplit;\n }\n }\n }\n\n /*\n * Instead of blasting the ENTIRE imageBuffer into contextBuffer, and then blasting the ENTIRE\n * canvasBuffer onto contextScreen, even for the smallest change, let's try to be a bit smarter about\n * the update (well, to the extent that the canvas APIs permit).\n */\n if (xDirty < this.nCols) {\n var cxDirty = xMaxDirty - xDirty;\n var cyDirty = yMaxDirty - yDirty;\n // this.contextBuffer.putImageData(this.imageBuffer, 0, 0);\n this.contextBuffer.putImageData(this.imageBuffer, 0, 0, xDirty, yDirty, cxDirty, cyDirty);\n /*\n * While ideally I would draw only the dirty portion of canvasBuffer, there usually isn't a 1-1 pixel mapping\n * between canvasBuffer and contextScreen. In fact, the WHOLE POINT of the canvasBuffer is to leverage\n * drawImage()'s scaling ability; for example, a CGA graphics mode might be 640x200, whereas the canvas representing\n * the screen might be 960x400. In those situations, if we draw interior rectangles, we often end up with subpixel\n * artifacts along the edges of those rectangles. So it appears I must continue to redraw the entire canvasBuffer\n * on every change.\n *\n var xScreen = (((xDirty * this.cxScreen) / this.nCols) | 0);\n var yScreen = (((yDirty * this.cyScreen) / this.nRows) | 0);\n var cxScreen = (((cxDirty * this.cxScreen) / this.nCols) | 0);\n var cyScreen = (((cyDirty * this.cyScreen) / this.nRows) | 0);\n this.contextScreen.drawImage(this.canvasBuffer, xDirty, yDirty, cxDirty, cyDirty, xScreen, yScreen, cxScreen, cyScreen);\n */\n this.contextScreen.drawImage(this.canvasBuffer, 0, 0, this.nCols, this.nRows, 0, 0, this.cxScreen, this.cyScreen);\n }\n return cCells;\n }\n\n /**\n * updateScreenGraphicsEGA(addrBuffer, addrScreen, addrScreenLimit)\n *\n * TODO: Add support for blinking graphics (ATC.MODE.BLINK_ENABLE)\n *\n * @this {Video}\n * @param {number} addrBuffer\n * @param {number} addrScreen\n * @param {number} addrScreenLimit\n * @return {number} (number of cells processed)\n */\n updateScreenGraphicsEGA(addrBuffer, addrScreen, addrScreenLimit)\n {\n var iCell = 0;\n var cCells = addrScreenLimit - addrScreen;\n var addr = addrScreen;\n var aPixelColors = this.getCardColors();\n var adwMemory = this.cardActive.adwMemory;\n\n var x = 0, y = 0;\n var xDirty = this.nCols, xMaxDirty = 0, yDirty = this.nRows, yMaxDirty = 0;\n var iPixelFirst = this.cardActive.regATCData[Card.ATC.HPAN.INDX] & Card.ATC.HPAN.SHIFT_LEFT;\n\n /*\n * TODO: What should happen if the card is programmed such that nColsLogical is LESS THAN nCols?\n */\n var nRowAdjust = (this.nColsLogical > this.nCols? ((this.nColsLogical - this.nCols - iPixelFirst) >> 3) : 0);\n\n this.cBlinkVisible = 0;\n while (addr < addrScreenLimit) {\n var idw = addr++ - addrBuffer;\n\n var data = adwMemory[idw];\n\n /*\n * Figure out how many visible pixels this data represents; usually 8, unless panning is being used.\n */\n var iPixel, nPixels = 8;\n\n if (iPixelFirst) {\n /*\n * Notice that we're not using the cell cache when panning is active, because the cached cell data no\n * longer aligns with the data we're pulling out of the video buffer, and it's not clear that the effort\n * to realign the data and make a valid cache comparison would save enough work to make it worthwhile.\n */\n if (!x) {\n data <<= iPixelFirst;\n nPixels -= iPixelFirst;\n /*\n * This is as good a place as any to invalidate the cell cache when panning is active; this ensures\n * we don't rely on stale cache contents once panning stops.\n */\n this.fCellCacheValid = false;\n } else {\n iPixel = this.nCols - x;\n if (nPixels > iPixel) nPixels = iPixel;\n }\n } else {\n\n if (this.fCellCacheValid && data === this.aCellCache[iCell]) {\n x += nPixels;\n nPixels = 0;\n } else {\n this.aCellCache[iCell] = data;\n }\n iCell++;\n }\n\n if (nPixels) {\n if (x < xDirty) xDirty = x;\n for (iPixel = 0; iPixel < nPixels; iPixel++) {\n /*\n * 0x80808080 may LOOK like a 32-bit value, but it is not, because JavaScript treats it as a POSITIVE\n * number, and therefore outside the normal 32-bit integer range; however, the AND operator guarantees\n * that the result will be a 32-bit value, so it doesn't matter.\n */\n var dwPixel = data & 0x80808080;\n\n /*\n * Since assertions don't fix problems (only catch them, and only in DEBUG builds), I'm also ensuring\n * that bPixel will default to 0 if an undefined value ever slips through again.\n *\n * How did an undefined value slip through? We had (incorrectly) initialized entries in aEGADWToByte;\n * for example, we used to set aEGADWToByte[0x80808080] instead of aEGADWToByte[0x80808080|0]. The\n * former is a POSITIVE index that is outside the 32-bit integer range, whereas the latter is a NEGATIVE\n * index, which is what this code requires.\n */\n var bPixel = Video.aEGADWToByte[dwPixel] || 0;\n this.setPixel(this.imageBuffer, x++, y, aPixelColors[bPixel]);\n data <<= 1;\n }\n if (x > xMaxDirty) xMaxDirty = x;\n if (y < yDirty) yDirty = y;\n if (y >= yMaxDirty) yMaxDirty = y + 1;\n }\n\n\n\n if (x >= this.nCols) {\n x = 0;\n if (++y > this.nRows) break;\n addr += nRowAdjust;\n }\n }\n\n if (iPixelFirst) cCells = 0; // zero the cell count to inhibit setting fCellCacheValid\n\n /*\n * For a fascinating discussion of the best way to update the screen canvas at this point, see updateScreenGraphicsCGA().\n */\n if (xDirty < this.nCols) {\n var cxDirty = xMaxDirty - xDirty;\n var cyDirty = yMaxDirty - yDirty;\n this.contextBuffer.putImageData(this.imageBuffer, 0, 0, xDirty, yDirty, cxDirty, cyDirty);\n this.contextScreen.drawImage(this.canvasBuffer, 0, 0, this.nCols, this.nRows, 0, 0, this.cxScreen, this.cyScreen);\n }\n return cCells;\n }\n\n /**\n * updateScreenGraphicsVGA(addrBuffer, addrScreen, addrScreenLimit)\n *\n * This function name is a slight misnomer: updateScreenGraphicsEGA() takes care of all the 4bpp video modes\n * (first introduced by the EGA and later expanded by the VGA), where each pixel's bits are spread across the 4\n * planes, whereas this function takes care of just the 8bpp video modes introduced by the VGA, such as mode 0x13\n * (320x200x256), where each pixel's bits are contained within a single plane. This is essentially all 256-color\n * modes (CHAIN4, \"Mode X\", etc), hence the hard-coded call to getCardColors(8).\n *\n * TODO: Add support for blinking graphics (ATC.MODE.BLINK_ENABLE)\n *\n * @this {Video}\n * @param {number} addrBuffer\n * @param {number} addrScreen\n * @param {number} addrScreenLimit\n * @return {number} (number of cells processed)\n */\n updateScreenGraphicsVGA(addrBuffer, addrScreen, addrScreenLimit)\n {\n var iCell = 0;\n var cCells = addrScreenLimit - addrScreen;\n var addr = addrScreen;\n var aPixelColors = this.getCardColors(8);\n var adwMemory = this.cardActive.adwMemory;\n\n var x = 0, y = 0;\n var xDirty = this.nCols, xMaxDirty = 0, yDirty = this.nRows, yMaxDirty = 0;\n var cbInc = (this.cardActive.regSEQData[Card.SEQ.MEMMODE.INDX] & Card.SEQ.MEMMODE.CHAIN4)? 4 : 1;\n var iPixelFirst = this.cardActive.regATCData[Card.ATC.HPAN.INDX] & Card.ATC.HPAN.SHIFT_LEFT;\n\n /*\n * TODO: What should happen if the card is programmed such that nColsLogical is LESS THAN nCols?\n */\n var nRowAdjust = (this.nColsLogical > this.nCols? ((this.nColsLogical - this.nCols - iPixelFirst) >> 3) : 0);\n\n this.cBlinkVisible = 0;\n while (addr < addrScreenLimit) {\n var idw = addr - addrBuffer;\n\n var data = adwMemory[idw];\n\n /*\n * Figure out how many visible pixels this data represents; usually 4, unless panning is being used.\n */\n var iPixel, nPixels = 4;\n\n if (iPixelFirst) {\n /*\n * TODO: Implement support for 8bpp panning\n */\n } else {\n\n if (this.fCellCacheValid && data === this.aCellCache[iCell]) {\n x += nPixels;\n nPixels = 0;\n } else {\n this.aCellCache[iCell] = data;\n }\n iCell++;\n }\n\n if (nPixels) {\n if (x < xDirty) xDirty = x;\n for (iPixel = 0; iPixel < nPixels; iPixel++) {\n this.setPixel(this.imageBuffer, x++, y, aPixelColors[data & 0xff]);\n data >>= 8;\n }\n if (x > xMaxDirty) xMaxDirty = x;\n if (y < yDirty) yDirty = y;\n if (y >= yMaxDirty) yMaxDirty = y + 1;\n }\n\n\n\n addr += cbInc;\n\n if (x >= this.nCols) {\n x = 0;\n if (++y > this.nRows) break;\n addr += nRowAdjust;\n }\n }\n\n if (iPixelFirst) cCells = 0; // zero the cell count to inhibit setting fCellCacheValid\n\n /*\n * For a fascinating discussion of the best way to update the screen canvas at this point, see updateScreenGraphicsCGA().\n */\n if (xDirty < this.nCols) {\n var cxDirty = xMaxDirty - xDirty;\n var cyDirty = yMaxDirty - yDirty;\n this.contextBuffer.putImageData(this.imageBuffer, 0, 0, xDirty, yDirty, cxDirty, cyDirty);\n this.contextScreen.drawImage(this.canvasBuffer, 0, 0, this.nCols, this.nRows, 0, 0, this.cxScreen, this.cyScreen);\n }\n return cCells;\n }\n\n /**\n * getRetraceBits(card)\n *\n * This returns a byte value with two bits set or clear as appropriate: RETRACE and VRETRACE.\n *\n * @this {Video}\n * @param {Object} card\n * @return {number}\n */\n getRetraceBits(card)\n {\n /*\n * NOTE: The CGA bits CGA.STATUS.RETRACE (0x01) and CGA.STATUS.VRETRACE (0x08) match the EGA definitions,\n * and they also correspond to the MDA bits MDA.STATUS.HDRIVE (0x01) and MDA.STATUS.BWVIDEO (0x08); I'm not sure\n * why the MDA uses different designations, but the bits appear to serve the same purpose.\n *\n * TODO: Verify that when a saved machine state is restored, both the CPU's cycle count AND the card's nInitCycles\n * are properly restored. It's probably not a big deal, but details like that bother me.\n */\n var b = 0;\n var nCycles = this.cpu.getCycles();\n var nElapsedCycles = nCycles - card.nInitCycles;\n if (nElapsedCycles < 0) { // perhaps the CPU decided to reset its cycle count?\n card.nInitCycles = nElapsedCycles;\n nElapsedCycles = -nElapsedCycles|0;\n }\n var nCyclesHorzRemain = nElapsedCycles % card.nCyclesHorzPeriod;\n if (nCyclesHorzRemain > card.nCyclesHorzActive) b |= Card.CGA.STATUS.RETRACE;\n var nCyclesVertRemain = nElapsedCycles % card.nCyclesVertPeriod;\n if (nCyclesVertRemain > card.nCyclesVertActive) b |= Card.CGA.STATUS.VRETRACE | Card.CGA.STATUS.RETRACE;\n /*\n * Some callers also want to know how many vertical retrace periods have occurred since the last time they checked,\n * so we compute that now.\n */\n card.nVertPeriods = (nElapsedCycles / card.nCyclesVertPeriod)|0;\n return b;\n }\n\n /**\n * inMDAIndx(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3B4)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number|undefined}\n */\n inMDAIndx(port, addrFrom)\n {\n return this.inCRTCIndx(this.cardMono, port, addrFrom);\n }\n\n /**\n * outMDAIndx(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3B4)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outMDAIndx(port, bOut, addrFrom)\n {\n this.outCRTCIndx(this.cardMono, port, bOut, addrFrom);\n }\n\n /**\n * inMDAData(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3B5)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number|undefined}\n */\n inMDAData(port, addrFrom)\n {\n return this.inCRTCData(this.cardMono, port, addrFrom);\n }\n\n /**\n * outMDAData(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3B5)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outMDAData(port, bOut, addrFrom)\n {\n this.outCRTCData(this.cardMono, port, bOut, addrFrom);\n }\n\n /**\n * inMDAMode(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3B8)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inMDAMode(port, addrFrom)\n {\n return this.inCardMode(this.cardMono, addrFrom);\n }\n\n /**\n * outMDAMode(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3B8)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outMDAMode(port, bOut, addrFrom)\n {\n this.outCardMode(this.cardMono, bOut, addrFrom);\n }\n\n /**\n * inMDAStatus(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3BA)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inMDAStatus(port, addrFrom)\n {\n return this.inCardStatus(this.cardMono, addrFrom);\n }\n\n /**\n * outFeat(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3BA or 0x3DA)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n *\n * NOTE: While this port also existed on the MDA and CGA, it existed only as an INPUT port, not an OUTPUT port.\n */\n outFeat(port, bOut, addrFrom)\n {\n this.cardEGA.regFeat = (this.cardEGA.regFeat & ~Card.FEAT_CTRL.BITS) | (bOut & Card.FEAT_CTRL.BITS);\n this.printMessageIO(port, bOut, addrFrom, \"FEAT\");\n }\n\n /**\n * inATCIndx(port, addrFrom)\n *\n * Technically, port 0x3C0 is readable only on a VGA, but we allow reads on an EGA as well,\n * primarily for debugging purposes. Moreover, ATC port reads do NOT toggle the ATC address/data\n * flip-flop; only writes have that effect.\n *\n * @this {Video}\n * @param {number} port (0x3C0)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inATCIndx(port, addrFrom)\n {\n var b = this.cardEGA.regATCIndx;\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.ATC.PORT, null, addrFrom, \"ATC.INDX\", b);\n }\n return b;\n }\n\n /**\n * inATCData(port, addrFrom)\n *\n * Technically, port 0x3C0 is readable only on a VGA, but we allow reads on an EGA as well,\n * primarily for debugging purposes. Moreover, ATC port reads do NOT toggle the ATC address/data\n * flip-flop; only writes have that effect.\n *\n * @this {Video}\n * @param {number} port (0x3C1)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inATCData(port, addrFrom)\n {\n var b = this.cardEGA.regATCData[this.cardEGA.regATCIndx & Card.ATC.INDX_MASK];\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.ATC.PORT, null, addrFrom, \"ATC.\" + this.cardEGA.asATCRegs[this.cardEGA.regATCIndx & Card.ATC.INDX_MASK], b);\n }\n return b;\n }\n\n /**\n * outATC(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C0)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outATC(port, bOut, addrFrom)\n {\n var card = this.cardEGA;\n var fPalEnabled = (card.regATCIndx & Card.ATC.INDX_PAL_ENABLE);\n if (!card.fATCData) {\n card.regATCIndx = bOut;\n this.printMessageIO(port, bOut, addrFrom, \"ATC.INDX\");\n card.fATCData = true;\n if ((bOut & Card.ATC.INDX_PAL_ENABLE) && !fPalEnabled) {\n if (!this.buildFonts(true)) {\n if (DEBUG && (!addrFrom || this.messageEnabled())) {\n this.printMessage(\"outATC(\" + Str.toHexByte(bOut) + \"): no font changes required\");\n }\n } else {\n if (DEBUG && (!addrFrom || this.messageEnabled())) {\n this.printMessage(\"outATC(\" + Str.toHexByte(bOut) + \"): redraw screen for font changes\");\n }\n this.updateScreen(true);\n }\n }\n else {\n /*\n * TODO: We might want a screen blanking function, suitable for any mode, when INDX_PAL_ENABLE is cleared.\n * powerDown() might like to use such a function, too. updateScreen() already disables any further screen\n * updates while INDX_PAL_ENABLE is clear (except when fForce is true), but that's all we currently do.\n *\n * if (!(bOut & Card.ATC.INDX_PAL_ENABLE) && fPalEnabled) this.blankScreen();\n *\n * However, there also needs to be a delay, because when the IBM VGA BIOS changes the mode, it updates\n * the ATC palette registers in such a way that INDX_PAL_ENABLE is constantly toggled; here's one iteration:\n *\n * C000:2B39 EC IN AL,DX\n * C000:2B3A B2C0 MOV DL,C0\n * C000:2B3C 8BC3 MOV AX,BX\n * C000:2B3E 86C4 XCHG AL,AH\n * C000:2B40 EE OUT DX,AL <-- this ATC index value does NOT contain 0x20\n * C000:2B41 86C4 XCHG AL,AH\n * C000:2B43 EE OUT DX,AL\n * C000:2B44 B020 MOV AL,20\n * C000:2B46 EE OUT DX,AL <-- this ATC index value obviously DOES contain 0x20\n *\n * I'm not sure there are any situations where deliberately flickering the screen is a good thing -- unless\n * someone REALLY wants to recreate the ugly flickering scroll of a CGA...?\n */\n }\n /*\n * HACK: offStartAddr is supposed to be \"latched\" ONLY at the start of every VRETRACE interval, but\n * other \"triggers\" are helpful; see updateScreen() for details.\n *\n * PARANOIA: Don't call invalidateCache() unless the start address we just \"latched\" actually changed.\n */\n var offStartAddr = card.regCRTData[Card.CRTC.STARTLO];\n offStartAddr |= (card.regCRTData[Card.CRTC.STARTHI] & card.addrMaskHigh) << 8;\n if (card.offStartAddr != offStartAddr) {\n card.offStartAddr = offStartAddr;\n this.invalidateCache();\n }\n card.nVertPeriodsStartAddr = 0;\n } else {\n card.fATCData = false;\n var iReg = card.regATCIndx & Card.ATC.INDX_MASK;\n if (iReg >= Card.ATC.PALETTE_REGS || !fPalEnabled) {\n if (Video.TRAPALL || card.regATCData[iReg] !== bOut) {\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(port, bOut, addrFrom, \"ATC.\" + card.asATCRegs[iReg]);\n }\n card.regATCData[iReg] = bOut;\n this.invalidateCache(false);\n }\n }\n }\n }\n\n /**\n * inStatus0(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C2)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inStatus0(port, addrFrom)\n {\n var bSWBit = 0;\n if (this.nCard == Video.CARD.EGA) {\n var iBit = 3 - ((this.cardEGA.regMisc & Card.MISC.CLOCK_SELECT) >> 2); // this is the desired SW # (0-3)\n bSWBit = (this.bEGASwitches & (1 << iBit)) << (Card.STATUS0.SWSENSE_SHIFT - iBit);\n } else {\n /*\n * The IBM VGA ROM expects the SWSENSE bit to change according to how the DAC is programmed.\n *\n * At C000:0391, the ROM selects the following array at 0x0454:\n *\n * db 0x12,0x12,0x12,0x10\n *\n * and writes the first 3 bytes to DAC register #0, and then compares SWSENSE to the 4th byte (0x10).\n *\n * If the 4th byte matches, then the ROM clears the BIOS \"monochrome monitor\" bit, and does the same\n * thing again with 5 more arrays, expecting the 4th byte in all 5 arrays to match SWSENSE, and being\n * very unhappy if they don't:\n *\n * db 0x14,0x14,0x14,0x10\n * db 0x2D,0x14,0x14,0x00\n * db 0x14,0x2D,0x14,0x00\n * db 0x14,0x14,0x2D,0x00\n * db 0x2D,0x2D,0x2D,0x00\n *\n * I ensure much happiness by setting SWSENSE unless any of the three 6-bit DAC values contain 0x2D.\n *\n * This hard-coded behavior assumes a color monitor. If you really want to simulate a monochrome monitor,\n * then the 1st array (above) must mismatch, and a different set of arrays must all match:\n *\n * db 0x04,0x12,0x04,0x10\n * db 0x1E,0x12,0x04,0x00\n * db 0x04,0x2D,0x04,0x00\n * db 0x04,0x16,0x15,0x00\n * db 0x00,0x00,0x00,0x10\n *\n * In other words, for a monochrome monitor, set SWSENSE only when DAC register #0 matches the first and last\n * sets of values.\n */\n var dwDAC = this.cardEGA.regDACData[0];\n if ((dwDAC & 0x3f) != 0x2d && (dwDAC & (0x3f << 6)) != (0x2d << 6) && (dwDAC & (0x3f << 12)) != (0x2d << 12)) {\n bSWBit |= Card.STATUS0.SWSENSE;\n }\n }\n var b = ((this.cardEGA.regStatus0 & ~Card.STATUS0.SWSENSE) | bSWBit);\n /*\n * TODO: Figure out where Card.STATUS0.FEAT bits should come from....\n */\n this.cardEGA.regStatus0 = b;\n this.printMessageIO(Card.STATUS0.PORT, null, addrFrom, \"STATUS0\", b);\n return b;\n }\n\n /**\n * @this {Video}\n * @param {number} port (0x3C2)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outMisc(port, bOut, addrFrom)\n {\n this.cardEGA.regMisc = bOut;\n this.enableEGA();\n this.printMessageIO(Card.MISC.PORT_WRITE, bOut, addrFrom, \"MISC\");\n }\n\n /**\n * inVGAEnable(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C3)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inVGAEnable(port, addrFrom)\n {\n var b = this.cardEGA.regVGAEnable;\n this.printMessageIO(Card.VGA_ENABLE.PORT, null, addrFrom, \"VGA_ENABLE\", b);\n return b;\n }\n\n /**\n * outVGAEnable(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C3)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outVGAEnable(port, bOut, addrFrom)\n {\n this.cardEGA.regVGAEnable = bOut;\n this.printMessageIO(Card.VGA_ENABLE.PORT, bOut, addrFrom, \"VGA_ENABLE\");\n }\n\n /**\n * inSEQIndx(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C4)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inSEQIndx(port, addrFrom)\n {\n var b = this.cardEGA.regSEQIndx;\n this.printMessageIO(Card.SEQ.INDX.PORT, null, addrFrom, \"SEQ.INDX\", b);\n return b;\n }\n\n /**\n * outSEQIndx(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C4)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outSEQIndx(port, bOut, addrFrom)\n {\n this.cardEGA.regSEQIndx = bOut;\n this.printMessageIO(Card.SEQ.INDX.PORT, bOut, addrFrom, \"SEQ.INDX\");\n }\n\n /**\n * inSEQData(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C5)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inSEQData(port, addrFrom)\n {\n var b = this.cardEGA.regSEQData[this.cardEGA.regSEQIndx];\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.SEQ.DATA.PORT, null, addrFrom, \"SEQ.\" + this.cardEGA.asSEQRegs[this.cardEGA.regSEQIndx], b);\n }\n return b;\n }\n\n /**\n * outSEQData(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C5)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outSEQData(port, bOut, addrFrom)\n {\n if (Video.TRAPALL || this.cardEGA.regSEQData[this.cardEGA.regSEQIndx] !== bOut) {\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.SEQ.DATA.PORT, bOut, addrFrom, \"SEQ.\" + this.cardEGA.asSEQRegs[this.cardEGA.regSEQIndx]);\n }\n this.cardEGA.regSEQData[this.cardEGA.regSEQIndx] = bOut;\n }\n switch(this.cardEGA.regSEQIndx) {\n case Card.SEQ.MAPMASK.INDX:\n this.cardEGA.nSeqMapMask = Video.aEGAByteToDW[bOut & Card.SEQ.MAPMASK.MAPS];\n break;\n case Card.SEQ.MEMMODE.INDX:\n if (this.setCardAccess(this.getCardAccess())) {\n /*\n * When switching screens (via SysReq) on early revisions of OS/2 (eg, FOOTBALL), the screen would go\n * blank; this appeared to be because when the card is reprogrammed, we first think the card is going into\n * graphics mode, then we reverse course when it becomes clear that the card is going back into text mode,\n * but unfortunately, at that precise moment, the Sequencer hasn't been fully reprogrammed, so when we're\n * reading screen memory, we're getting back ZEROS for every odd byte (which are the text attribute bytes),\n * so the screen is redrawn as black-on-black.\n *\n * My solution was to change setCardAccess() to indicate whether it actually altered the video buffer\n * address and/or format, and if so, then force another screen update.\n *\n * TODO: This scenario does not seem unique; it suggests that we should generally force a screen update\n * whenever the video buffer has undergone a significant change.\n *\n * UPDATE: This change was NOT sufficient to resolve the OS/2 screen-switching bug described above; in fact,\n * it's apparently not even necessary, because the REAL problem was caused by PAGED blocks with stale\n * physical video memory blocks; the solution was for the Bus addMemory() and removeMemory() functions to\n * call the the CPU flushPageBlocks() function. With that change in place, the window now stays in sync\n * with the buffer.\n *\n * However, calling updateScreen() here still seems like a good idea, and it shouldn't hurt performance,\n * since we're doing it only when setCardAccess() indicates a change, so I'm leaving this addition in place.\n */\n this.updateScreen(true);\n }\n break;\n default:\n break;\n }\n }\n\n /**\n * inDACMask(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C6)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inDACMask(port, addrFrom)\n {\n var b = this.cardEGA.regDACMask;\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.DAC.MASK.PORT, null, addrFrom, \"DAC.MASK\", b);\n }\n return b;\n }\n\n /**\n * outDACMask(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C6)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outDACMask(port, bOut, addrFrom)\n {\n if (Video.TRAPALL || this.cardEGA.regDACMask !== bOut) {\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.DAC.MASK.PORT, bOut, addrFrom, \"DAC.MASK\");\n }\n this.cardEGA.regDACMask = bOut;\n }\n }\n\n /**\n * inDACState(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C7)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inDACState(port, addrFrom)\n {\n var b = this.cardEGA.regDACState;\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.DAC.STATE.PORT, null, addrFrom, \"DAC.STATE\", b);\n }\n return b;\n }\n\n /**\n * outDACRead(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C7)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outDACRead(port, bOut, addrFrom)\n {\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.DAC.ADDR.PORT_READ, bOut, addrFrom, \"DAC.READ\");\n }\n this.cardEGA.regDACAddr = bOut;\n this.cardEGA.regDACState = Card.DAC.STATE.MODE_READ;\n this.cardEGA.regDACShift = 0;\n }\n\n /**\n * outDACWrite(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C8)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outDACWrite(port, bOut, addrFrom)\n {\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.DAC.ADDR.PORT_WRITE, bOut, addrFrom, \"DAC.WRITE\");\n }\n this.cardEGA.regDACAddr = bOut;\n this.cardEGA.regDACState = Card.DAC.STATE.MODE_WRITE;\n this.cardEGA.regDACShift = 0;\n }\n\n /**\n * inDACData(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C9)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inDACData(port, addrFrom)\n {\n var b = (this.cardEGA.regDACData[this.cardEGA.regDACAddr] >> this.cardEGA.regDACShift) & 0x3f;\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.DAC.DATA.PORT, null, addrFrom, \"DAC.DATA[\" + Str.toHexByte(this.cardEGA.regDACAddr) + \"][\" + Str.toHexByte(this.cardEGA.regDACShift) + \"]\", b);\n }\n this.cardEGA.regDACShift += 6;\n if (this.cardEGA.regDACShift > 12) {\n this.cardEGA.regDACShift = 0;\n this.cardEGA.regDACAddr = (this.cardEGA.regDACAddr + 1) & (Card.DAC.TOTAL_REGS-1);\n }\n return b;\n }\n\n /**\n * outDACData(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3C9)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outDACData(port, bOut, addrFrom)\n {\n var dw = this.cardEGA.regDACData[this.cardEGA.regDACAddr];\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.DAC.DATA.PORT, bOut, addrFrom, \"DAC.DATA[\" + Str.toHexByte(this.cardEGA.regDACAddr) + \"][\" + Str.toHexByte(this.cardEGA.regDACShift) + \"]\");\n }\n var dwNew = (dw & ~(0x3f << this.cardEGA.regDACShift)) | ((bOut & 0x3f) << this.cardEGA.regDACShift);\n if (dw !== dwNew) {\n this.cardEGA.regDACData[this.cardEGA.regDACAddr] = dwNew;\n this.invalidateCache(false);\n }\n this.cardEGA.regDACShift += 6;\n if (this.cardEGA.regDACShift > 12) {\n this.cardEGA.regDACShift = 0;\n this.cardEGA.regDACAddr = (this.cardEGA.regDACAddr + 1) & (Card.DAC.TOTAL_REGS-1);\n }\n }\n\n /**\n * inVGAFeat(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3CA)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inVGAFeat(port, addrFrom)\n {\n var b = this.cardEGA.regFeat;\n this.printMessageIO(Card.FEAT_CTRL.PORT_READ, null, addrFrom, \"FEAT\", b);\n return b;\n }\n\n /**\n * outGRCPos2(port, bOut, addrFrom)\n *\n * \"The EGA was originally implemented by IBM using two Graphics Controller Chips. This register is used to program\n * the Graphics #2 chip. See the Graphics #1 Position Register for details.\"\n *\n * \"A one should be loaded into this location to map host data bus bits 2 and 3 to display planes 2 and 3, respectively.\"\n *\n * @this {Video}\n * @param {number} port (0x3CA)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outGRCPos2(port, bOut, addrFrom)\n {\n this.cardEGA.regGRCPos2 = bOut;\n this.printMessageIO(Card.GRC.POS2_PORT, bOut, addrFrom, \"GRC2\");\n }\n\n /**\n * inVGAMisc(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3CC)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inVGAMisc(port, addrFrom)\n {\n var b = this.cardEGA.regMisc;\n this.printMessageIO(Card.MISC.PORT_READ, null, addrFrom, \"MISC\", b);\n return b;\n }\n\n /**\n * outGRCPos1(port, bOut, addrFrom)\n *\n * \"The EGA was originally implemented by IBM using two Graphics Controller Chips. It was necessary to program\n * each to respond to a different set of two consecutive bits of the 8-bit host data bus. In the IBM EGA implementation,\n * a 0 must be loaded into this register. In the VGA, there is no analogous register.\"\n *\n * \"A zero should be loaded into this location to map host data bus bits 0 and 1 to display planes 0 and 1 respectively.\"\n *\n * Note that this register was not readable on the EGA, and when the VGA came along, reads of this port read the Misc reg.\n *\n * @this {Video}\n * @param {number} port (0x3CC)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outGRCPos1(port, bOut, addrFrom)\n {\n this.cardEGA.regGRCPos1 = bOut;\n this.printMessageIO(Card.GRC.POS1_PORT, bOut, addrFrom, \"GRC1\");\n }\n\n /**\n * inGRCIndx(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3CE)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inGRCIndx(port, addrFrom)\n {\n var b = this.cardEGA.regGRCIndx;\n this.printMessageIO(Card.GRC.INDX.PORT, null, addrFrom, \"GRC.INDX\", b);\n return b;\n }\n\n /**\n * outGRCIndx(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3CE)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outGRCIndx(port, bOut, addrFrom)\n {\n this.cardEGA.regGRCIndx = bOut;\n this.printMessageIO(Card.GRC.INDX.PORT, bOut, addrFrom, \"GRC.INDX\");\n }\n\n /**\n * inGRCData(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3CF)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inGRCData(port, addrFrom)\n {\n var b = this.cardEGA.regGRCData[this.cardEGA.regGRCIndx];\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.GRC.DATA.PORT, null, addrFrom, \"GRC.\" + this.cardEGA.asGRCRegs[this.cardEGA.regGRCIndx], b);\n }\n return b;\n }\n\n /**\n * outGRCData(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3CF)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outGRCData(port, bOut, addrFrom)\n {\n if (Video.TRAPALL || this.cardEGA.regGRCData[this.cardEGA.regGRCIndx] !== bOut) {\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(Card.GRC.DATA.PORT, bOut, addrFrom, \"GRC.\" + this.cardEGA.asGRCRegs[this.cardEGA.regGRCIndx]);\n }\n this.cardEGA.regGRCData[this.cardEGA.regGRCIndx] = bOut;\n }\n switch(this.cardEGA.regGRCIndx) {\n case Card.GRC.SRESET.INDX:\n this.cardEGA.nSetMapData = Video.aEGAByteToDW[bOut & 0xf];\n this.cardEGA.nSetMapBits = this.cardEGA.nSetMapData & ~this.cardEGA.nSetMapMask;\n break;\n case Card.GRC.ESRESET.INDX:\n this.cardEGA.nSetMapMask = ~Video.aEGAByteToDW[bOut & 0xf];\n this.cardEGA.nSetMapBits = this.cardEGA.nSetMapData & ~this.cardEGA.nSetMapMask;\n break;\n case Card.GRC.COLORCMP.INDX:\n this.cardEGA.nColorCompare = Video.aEGAByteToDW[bOut & 0xf] & (0x80808080|0);\n break;\n case Card.GRC.DATAROT.INDX:\n case Card.GRC.MODE.INDX:\n this.setCardAccess(this.getCardAccess());\n break;\n case Card.GRC.READMAP.INDX:\n this.cardEGA.nReadMapShift = (bOut & Card.GRC.READMAP.NUM) << 3;\n break;\n case Card.GRC.MISC.INDX:\n this.checkMode(false);\n break;\n case Card.GRC.COLORDC.INDX:\n this.cardEGA.nColorDontCare = Video.aEGAByteToDW[bOut & 0xf] & (0x80808080|0);\n break;\n case Card.GRC.BITMASK.INDX:\n this.cardEGA.nBitMapMask = bOut | (bOut << 8) | (bOut << 16) | (bOut << 24);\n break;\n default:\n break;\n }\n }\n\n /**\n * inCGAIndx(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3D4)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number|undefined}\n */\n inCGAIndx(port, addrFrom)\n {\n return this.inCRTCIndx(this.cardColor, port, addrFrom);\n }\n\n /**\n * outCGAIndx(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3D4)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outCGAIndx(port, bOut, addrFrom)\n {\n this.outCRTCIndx(this.cardColor, port, bOut, addrFrom);\n }\n\n /**\n * inCGAData(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3D5)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number|undefined}\n */\n inCGAData(port, addrFrom)\n {\n return this.inCRTCData(this.cardColor, port, addrFrom);\n }\n\n /**\n * outCGAData(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3D5)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outCGAData(port, bOut, addrFrom)\n {\n this.outCRTCData(this.cardColor, port, bOut, addrFrom);\n }\n\n /**\n * inCGAMode(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3D8)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inCGAMode(port, addrFrom)\n {\n return this.inCardMode(this.cardColor, addrFrom);\n }\n\n /**\n * outCGAMode(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3D8)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outCGAMode(port, bOut, addrFrom)\n {\n this.outCardMode(this.cardColor, bOut, addrFrom);\n }\n\n /**\n * inCGAColor(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3D9)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inCGAColor(port, addrFrom)\n {\n var b = this.cardColor.regColor;\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(port /* this.cardColor.port + 5 */, null, addrFrom, this.cardColor.type + \".COLOR\", b);\n }\n return b;\n }\n\n /**\n * outCGAColor(port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3D9)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outCGAColor(port, bOut, addrFrom)\n {\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(port /* this.cardColor.port + 5 */, bOut, addrFrom, this.cardColor.type + \".COLOR\");\n }\n if (this.cardColor.regColor !== bOut) {\n this.cardColor.regColor = bOut;\n this.invalidateCache(false);\n }\n }\n\n /**\n * inCGAStatus(port, addrFrom)\n *\n * @this {Video}\n * @param {number} port (0x3DA)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inCGAStatus(port, addrFrom)\n {\n return this.inCardStatus(this.cardColor, addrFrom);\n }\n\n /**\n * inCRTCIndx(card, port, addrFrom)\n *\n * @this {Video}\n * @param {Object} card\n * @param {number} port\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number|undefined}\n */\n inCRTCIndx(card, port, addrFrom)\n {\n var b;\n /*\n * The IBM VGA ROM makes some hardware determinations based on how the CRTC controller responds when\n * the IO_SELECT bit in the Miscellaneous Output Register is cleared; normally, that would mean ports\n * 0x3B? are decoded and ports 0x3D? are ignored. We didn't used to bother ignoring them, but the\n * VGA ROM's logic requires it, so now we also check fActive. However, we ignore only CRTC reads;\n * we retain any writes in case that information proves useful later.\n *\n * Note that returning an undefined value now signals the Bus component to return whatever default value\n * it prefers (normally 0xff).\n */\n if (card.fActive) b = card.regCRTIndx;\n this.printMessageIO(port, null, addrFrom, \"CRTC.INDX\", b);\n return b;\n }\n\n /**\n * outCRTCIndx(card, port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {Object} card\n * @param {number} port\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outCRTCIndx(card, port, bOut, addrFrom)\n {\n card.regCRTPrev = card.regCRTIndx;\n card.regCRTIndx = bOut & Card.CGA.CRTC.INDX.MASK;\n this.printMessageIO(port /* card.port */, bOut, addrFrom, \"CRTC.INDX\");\n }\n\n /**\n * inCRTCData(card, port, addrFrom)\n *\n * @this {Video}\n * @param {Object} card\n * @param {number} port\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number|undefined}\n */\n inCRTCData(card, port, addrFrom)\n {\n var b;\n /*\n * The IBM VGA ROM makes some hardware determinations based on how the CRTC controller responds when\n * the IO_SELECT bit in the Miscellaneous Output Register is cleared; normally, that would mean ports\n * 0x3B? are decoded and ports 0x3D? are ignored. We didn't used to bother ignoring them, but the\n * VGA ROM's logic requires it, so now we also check fActive. However, we ignore only CTRC reads;\n * we retain any writes in case that information proves useful later.\n *\n * Note that returning an undefined value now signals the Bus component to return whatever default value\n * it prefers (normally 0xff).\n */\n if (card.fActive && card.regCRTIndx < card.nCRTCRegs) b = card.regCRTData[card.regCRTIndx];\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(port /* card.port + 1 */, null, addrFrom, \"CRTC.\" + card.asCRTCRegs[card.regCRTIndx], b);\n }\n return b;\n }\n\n /**\n * outCRTCData(card, port, bOut, addrFrom)\n *\n * @this {Video}\n * @param {Object} card\n * @param {number} port\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outCRTCData(card, port, bOut, addrFrom)\n {\n if (card.regCRTIndx < card.nCRTCRegs) {\n /*\n * To simulate how the 6845 effectively ignores changes to CURSCAN or CURSCANB whenever one is written\n * while the other is currently > MAXSCAN, we check for those writes now, and ignore the write as appropriate.\n * \n * Since CURSCAN == 0xA and CURSCANB == 0xB, we can get the complementary register by XOR'ing the index with 0x1.\n */\n if (card.regCRTIndx == Card.CRTC.CURSCAN || card.regCRTIndx == Card.CRTC.CURSCANB) {\n var bCur = bOut & Card.CRTCMASKS[Card.CRTC.MAXSCAN];\n var bMax = card.regCRTData[Card.CRTC.MAXSCAN] & Card.CRTCMASKS[Card.CRTC.MAXSCAN];\n if (bCur > bMax) {\n bCur = card.regCRTData[card.regCRTIndx ^ 0x1] & Card.CRTCMASKS[Card.CRTC.MAXSCAN];\n if (bCur > bMax) {\n if (DEBUG) {\n this.printf(\"outCRTCData(0x%02x): ignoring write to CRTC[0x%02x] since 0x%02x > 0x%02x\\n\", bOut, card.regCRTIndx, bCur, bMax);\n }\n return;\n }\n }\n }\n if (Video.TRAPALL || card.regCRTData[card.regCRTIndx] !== bOut) {\n if (!addrFrom || this.messageEnabled()) {\n this.printMessageIO(port /* card.port + 1 */, bOut, addrFrom, \"CRTC.\" + card.asCRTCRegs[card.regCRTIndx]);\n }\n card.regCRTData[card.regCRTIndx] = bOut;\n }\n if (card.regCRTIndx == Card.CRTC.STARTHI || card.regCRTIndx == Card.CRTC.STARTLO) {\n /*\n * Both STARTHI and STARTLO are supposed to be latched at the start of every VRETRACE interval.\n * However, since we don't have an interrupt that tells us exactly when that occurs, we used to latch\n * them now, whenever either one was written during any RETRACE interval. Unfortunately, one problem\n * with that approach is that we might latch only *one* of the registers, depending on timing.\n *\n * So now, we still call getRetraceBits(card), but only to recalculate the card's nVertPeriods value,\n * which we then snapshot in card.nVertPeriodsStartAddr.\n */\n this.getRetraceBits(card);\n card.nVertPeriodsStartAddr = card.nVertPeriods;\n }\n /*\n * During mode changes on the EGA, all the CRTC regs are typically programmed in sequence,\n * and if that's all that's happening with Card.CRTC.MAXSCAN, then we don't want to treat\n * it special; let the mode change be detected normally (eg, when the GRC regs are written later).\n *\n * On the other hand, if this was an out-of-sequence write to Card.CRTC.MAXSCAN, then\n * yes, we want to force setMode() to call setDimensions(), which is key to setting the proper\n * number of screen rows.\n *\n * The second part of the check is required to promptly detect a switch to \"Mode X\"; if we assume\n * that anyone switching to \"Mode X\" will first switch to mode 0x13, then it's a given that they\n * must reprogram the VDEND register, and that they will probably change it from 0x8F to 0xDF.\n *\n * Originally, I wasn't going to check specifically for 0xDF, to help catch other \"Mode X\" variations,\n * but if I don't, then some spurious mode changes are triggered (eg, when Windows 1.0 switches from\n * CGA graphics mode 0x06 to an EGA graphics mode).\n */\n if (card.regCRTIndx == Card.CRTC.MAXSCAN && card.regCRTPrev != Card.CRTC.MAXSCAN-1 || card.regCRTIndx == Card.CRTC.EGA.VDEND && bOut == 0xDF) {\n this.checkMode(true);\n }\n this.checkCursor();\n }\n else if (DEBUG) {\n this.printf(\"outCRTCData(0x%02x): ignoring unexpected write to CRTC[0x%02x]\\n\", bOut, card.regCRTIndx);\n }\n }\n\n /**\n * inCardMode(card, addrFrom)\n *\n * @this {Video}\n * @param {Object} card\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inCardMode(card, addrFrom)\n {\n var b = card.regMode;\n this.printMessageIO(card.port + 4, null, addrFrom, \"MODE\", b);\n return b;\n }\n\n /**\n * outCardMode(card, bOut, addrFrom)\n *\n * @this {Video}\n * @param {Object} card\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outCardMode(card, bOut, addrFrom)\n {\n this.printMessageIO(card.port + 4, bOut, addrFrom, \"MODE\");\n card.regMode = bOut;\n this.checkMode(false);\n }\n\n /**\n * inCardStatus(card, addrFrom)\n *\n * On an EGA, this register is called \"Status Register One\" (0x3BA/0x3DA aka STATUS1), to distinguish it from\n * \"Status Register Zero\" (0x3C2 aka STATUS0). One of the side-effects of reading STATUS1 is that it resets the\n * ATC address/data flip-flop to \"address\" mode, which we emulate by setting cardEGA.fATCData to false, indicating\n * that the ATC is not in \"data\" mode.\n *\n * @this {Video}\n * @param {Object} card\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number}\n */\n inCardStatus(card, addrFrom)\n {\n var b = this.getRetraceBits(card);\n\n if (card === this.cardEGA) {\n /*\n * STATUS1 diagnostic bits 5 and 4 are set according to the Card.ATC.PLANES.MUX bits:\n *\n * MUX Bit 5 Bit 4\n * --- ---- ----\n * 00: Red Blue\n * 01: SecBlue Green\n * 10: SecRed SecGreen\n * 11: unused unused\n *\n * Depending on where we are in the horizontal and vertical periods (which can be inferred from the\n * same elapsed cycle count that we used to simulate the retrace bits above), we could extract 4 bits\n * from a corresponding region of the video buffer, \"and\" them with Card.ATC.PLANES.MASK, use\n * that to index into the palette registers (cardEGA.regATCData), and use the resulting palette register\n * bits to set these diagnostics bits. However, that's all rather tedious, and the process of extracting\n * 4 appropriate bits from the video buffer varies depending on the video mode.\n *\n * Why are we even considering this? Because the EGA BIOS diagnostic code draws a bright reverse-video\n * line of text blocks across the top of the screen, writes 0x3F to palette register 0x0f, and then\n * monitors the STATUS1 diagnostic bits, waiting for those palette bits to show up. It turns out, however,\n * that we can easily fool the EGA BIOS by simply toggling the diagnostic bits. So we take the easy way out.\n *\n * TODO: Faithful emulation of these bits is certainly doable, so consider doing that at some point.\n */\n b |= ((card.regStatus & Card.STATUS1.DIAGNOSTIC) ^ Card.STATUS1.DIAGNOSTIC);\n\n /*\n * Last but not least, we must reset the EGA's ATC flip-flop whenever this register is read.\n */\n card.fATCData = false;\n }\n else {\n /*\n * On the MDA/CGA, to satisfy ROM BIOS testing (\"TEST.10\"), it's sufficient to do a simple toggle of\n * bits 0 and 3 on every read.\n *\n * Also, according to http://www.seasip.info/VintagePC/mda.html, on an MDA, bits 7-4 are always ON and\n * bits 2-1 are always OFF, hence the \"OR\" of 0xF0.\n *\n * Alternatively, I *could* use the retrace bits from getRetraceBits() as-is:\n *\n * b |= 0xF0;\n *\n * but doing so hurts the performance of code like this in the \"FlickerFree\" utility:\n *\n * &0600:079A EC IN AL,DX\n * &0600:079B D0E8 SHR AL,1\n * &0600:079D 72FB JC 079A\n * &0600:079F FA CLI\n * &0600:07A0 EC IN AL,DX\n * &0600:07A1 D0E8 SHR AL,1\n * &0600:07A3 73FB JNC 07A0\n * &0600:07A5 8BC3 MOV AX,BX\n * &0600:07A7 AB STOSW\n * &0600:07A8 FB STI\n * &0600:07A9 E2EF LOOP 079A\n *\n * which, oddly, appears to want to write only ONE word to video memory per retrace interval. Sticking\n * with our older, cruder, toggling code, makes that code run faster and reduce the odds that you'll see\n * old data on appear on the screen before the above code has the chance to store new data over it.\n */\n b = (card.regStatus ^= (Card.CGA.STATUS.RETRACE | Card.CGA.STATUS.VRETRACE)) | 0xF0;\n }\n\n card.regStatus = b;\n this.printMessageIO(card.port + 6, null, addrFrom, (card === this.cardEGA? \"STATUS1\" : \"STATUS\"), b);\n return b;\n }\n\n /**\n * dumpVideo(asArgs)\n *\n * @this {Video}\n * @param {Array.<string>} asArgs\n */\n dumpVideo(asArgs)\n {\n if (DEBUGGER) {\n var component = /** @type {Component} */ (this.dbg);\n if (!this.cardActive) {\n component.println(\"no active video card\");\n return;\n }\n if (asArgs[0]) {\n this.cardActive.dumpVideoBuffer(asArgs);\n return;\n }\n component.println(\"BIOSMODE: \" + Str.toHexByte(this.nMode));\n this.cardActive.dumpVideoCard();\n }\n }\n\n /**\n * doBlink()\n *\n * This function is obsolete, now that the checkBlink() function is called on every updateScreen()\n * and checkCursor() call. updateScreen() is driven by CPU bursts, so piggy-backing on that to drive\n * blink updates seems preferable to having another active timer in the system.\n *\n * @this {Video}\n * @param {boolean} [fStart]\n *\n doBlink(fStart)\n {\n if (this.cBlinks >= 0) {\n this.cBlinks++;\n if (this.cBlinkVisible || this.iCellCursor >= 0) {\n if (!fStart && !this.cpu.isRunning()) {\n this.updateScreen();\n }\n setTimeout(function(video) { return function onBlinkTimeout() {video.doBlink();}; }(this), 266);\n return;\n }\n this.cBlinks = -1;\n }\n },\n */\n\n /**\n * Video.init()\n *\n * This function operates on every HTML element of class \"video\", extracting the\n * JSON-encoded parameters for the Video constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Video component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aElement = Component.getElementsByClass(document, PCX86.APPCLASS, \"video\");\n for (var iVideo = 0; iVideo < aElement.length; iVideo++) {\n var element = aElement[iVideo];\n var parmsVideo = Component.getComponentParms(element);\n\n var canvas = /** @type {HTMLCanvasElement} */ (document.createElement(\"canvas\"));\n if (canvas === undefined || !canvas.getContext) {\n element.innerHTML = \"<br/>Missing <canvas> support. Please try a newer web browser.\";\n return;\n }\n\n canvas.setAttribute(\"class\", \"pcjs-canvas\");\n canvas.setAttribute(\"width\", parmsVideo['screenWidth']);\n canvas.setAttribute(\"height\", parmsVideo['screenHeight']);\n\n /*\n * The \"contenteditable\" attribute on a canvas element NOTICEABLY slows down canvas drawing on\n * Safari as soon as you give the canvas focus (ie, click away from the canvas, and drawing speeds\n * up; click on the canvas, and drawing slows down). So the \"transparent textarea hack\" that we\n * once employed as only a work-around for Android devices is now our default.\n *\n * canvas.setAttribute(\"contenteditable\", \"true\");\n *\n * HACK: A canvas style of \"auto\" provides for excellent responsive canvas scaling in EVERY browser\n * except IE9/IE10, so I recalculate the appropriate CSS height every time the parent DIV is resized;\n * IE11 works without this hack, so we take advantage of the fact that IE11 doesn't identify as \"MSIE\".\n *\n * The other reason it's good to keep this particular hack limited to IE9/IE10 is that most other\n * browsers don't actually support an 'onresize' handler on anything but the window object.\n */\n canvas.style.height = \"auto\";\n if (Web.getUserAgent().indexOf(\"MSIE\") >= 0) {\n element.onresize = function(eParent, eChild, cx, cy) {\n return function onResizeVideo() {\n eChild.style.height = (((eParent.clientWidth * cy) / cx) | 0) + \"px\";\n };\n }(element, canvas, parmsVideo['screenWidth'], parmsVideo['screenHeight']);\n element.onresize(null);\n }\n /*\n * The following is a related hack that allows the user to force the screen to use a particular aspect\n * ratio if an 'aspect' attribute or URL parameter is set. Initially, it's just for testing purposes\n * until we figure out a better UI. And note that we use our Web.onPageEvent() helper function to make\n * sure we don't trample any other 'onresize' handler(s) attached to the window object.\n */\n var aspect = +(Web.getURLParm('aspect') || parmsVideo['aspect']);\n /*\n * No 'aspect' parameter yields NaN, which is falsey, and anything else must satisfy my arbitrary\n * constraints of 0.3 <= aspect <= 3.33, to prevent any useless (or worse, browser-blowing) results.\n */\n if (aspect && aspect >= 0.3 && aspect <= 3.33) {\n Web.onPageEvent('onresize', function(eParent, eChild, aspectRatio) {\n return function onResizeWindow() {\n /*\n * Since aspectRatio is the target width/height, we have:\n *\n * eParent.clientWidth / eChild.style.height = aspectRatio\n *\n * which means that:\n *\n * eChild.style.height = eParent.clientWidth / aspectRatio\n *\n * so for example, if aspectRatio is 16:9, or 1.78, and clientWidth = 640,\n * then the calculated height should approximately 360.\n */\n eChild.style.height = ((eParent.clientWidth / aspectRatio)|0) + \"px\";\n };\n }(element, canvas, aspect));\n window['onresize']();\n }\n element.appendChild(canvas);\n\n /*\n * HACK: Android-based browsers, like the Silk (Amazon) browser and Chrome for Android, don't honor the\n * \"contenteditable\" attribute; that is, when the canvas receives focus, they don't activate the on-screen\n * keyboard. So my fallback is to create a transparent textarea on top of the canvas.\n *\n * The parent DIV must have a style of \"position:relative\" (alternatively, a class of \"pcjs-container\"),\n * so that we can position the textarea using absolute coordinates. Also, we don't want the textarea to be\n * visible, but we must use \"opacity:0\" instead of \"visibility:hidden\", because the latter seems to prevent\n * the element from receiving events. These styling requirements are taken care of in components.css\n * (see references to the \"pcjs-video-object\" class).\n *\n * UPDATE: Unfortunately, Android keyboards like to compose whole words before transmitting any of the\n * intervening characters; our textarea's keyDown/keyUp event handlers DO receive intervening key events,\n * but their keyCode property is ZERO. Virtually the only usable key event we receive is the Enter key.\n * Android users will have to use machines that include their own on-screen \"soft keyboard\", or use an\n * external keyboard.\n *\n * The following attempt to use a password-enabled input field didn't work any better on Android. You could\n * clearly see the overlaid semi-transparent input field, but none of the input characters were passed along,\n * with the exception of the \"Go\" (Enter) key.\n *\n * var input = document.createElement(\"input\");\n * input.setAttribute(\"type\", \"password\");\n * input.setAttribute(\"style\", \"position:absolute; left:0; top:0; width:100%; height:100%; opacity:0.5\");\n * element.appendChild(input);\n *\n * See this Chromium issue for more information: https://code.google.com/p/chromium/issues/detail?id=118639\n */\n var textarea = /** @type {HTMLTextAreaElement} */ (document.createElement(\"textarea\"));\n\n /*\n * As noted in keyboard.js, the keyboard on an iOS device tends to pop up with the SHIFT key depressed,\n * which is not the initial keyboard state that the Keyboard component expects, so hopefully turning off\n * these \"auto\" attributes will help.\n */\n if (Web.isUserAgent(\"iOS\")) {\n textarea.setAttribute(\"autocapitalize\", \"off\");\n textarea.setAttribute(\"autocorrect\", \"off\");\n /*\n * One of the problems on iOS devices is that after a soft-key control is clicked, we need to give\n * focus back to the above textarea, usually by calling cmp.updateFocus(), but in doing so, iOS may\n * also \"zoom\" the page rather jarringly. While it's a simple matter to completely disable zooming,\n * by fiddling with the page's viewport, that prevents the user from intentionally zooming. A bit of\n * Googling reveals that another way to prevent those jarring unintentional zooms is to simply set the\n * font-size of the text control to 16px. So that's what we do.\n */\n textarea.style.fontSize = \"16px\";\n }\n element.appendChild(textarea);\n\n /*\n * Now we can create the Video object, record it, and wire it up to the associated document elements.\n */\n var context = /** @type {CanvasRenderingContext2D} */ (canvas.getContext(\"2d\"));\n var video = new Video(parmsVideo, canvas, context, textarea /* || input */, element);\n\n /*\n * Bind any video-specific controls (eg, the Refresh button). There are no essential controls, however;\n * even the \"Refresh\" button is just a diagnostic tool, to ensure that the screen contents are up-to-date.\n */\n Component.bindComponentControls(video, element, PCX86.APPCLASS);\n }\n }\n}\n\nVideo.TRAPALL = true; // monitor all I/O by default (not just deltas)\n\n/*\n * Supported Modes\n *\n * Although this component is designed to be a video hardware emulation, not a BIOS simulation, we DO\n * look for changes to the hardware state that correspond to standard BIOS mode settings, so our internal\n * mode setting will normally match the current BIOS mode setting; however, this a debugging convenience,\n * not an attempt to monitor or emulate the BIOS.\n *\n * We do have some BIOS awareness (eg, when loading ROM-based fonts, and some special code to ensure all\n * the BIOS diagnostics pass), but for the most part, we treat the BIOS like any other application code.\n *\n * As we expand support to include more programmable cards like the EGA, it becomes quite easy for the card\n * to enter a \"mode\" that has no BIOS counterpart (eg, non-standard combinations of video buffer address,\n * memory access modes, fonts, display regions, etc). Our hardware emulation routines will cope with those\n * situations as best they can (and when they don't, it should be considered a bug if some application is\n * broken as a result), but realistically, our hardware emulation is never likely to be 100% accurate.\n */\nVideo.MODE = {\n CGA_40X25_BW: 0,\n CGA_40X25: 1,\n CGA_80X25_BW: 2,\n CGA_80X25: 3,\n CGA_320X200: 4,\n CGA_320X200_BW: 5,\n CGA_640X200: 6,\n MDA_80X25: 7,\n EGA_320X200: 0x0D, // mapped at A000:0000, color, 4bpp, planar\n EGA_640X200: 0x0E, // mapped at A000:0000, color, 4bpp, planar\n EGA_640X350_MONO: 0x0F, // mapped at A000:0000, mono, 2bpp, planar\n EGA_640X350: 0x10, // mapped at A000:0000, color, 4bpp, planar\n VGA_640X480_MONO: 0x11, // mapped at A000:0000, mono, 2bpp, planar\n VGA_640X480: 0x12, // mapped at A000:0000, color, 4bpp, planar\n VGA_320X200: 0x13, // mapped at A000:0000, color, 8bpp, linear\n /*\n * The remaining mode identifiers are for internal use only; there is no correlation with any\n * publicly defined BIOS modes, and overlap with any third-party mode numbers is purely coincidental.\n */\n VGA_320X240: 0x14, // mapped at A000:0000, color, 8bpp, planar (\"Mode X\")\n VGA_320X400: 0x15, // mapped at A000:0000, color, 8bpp, planar\n /*\n * Here's where we might assign additional identifiers to certain unique combinations, like the\n * fTextGraphicsHybrid 320x400 mode that Windows 95 uses (ie, when the buffer is mapped to B800:0000\n * instead of A000:0000 and is configured for text mode access, but graphics are still being displayed\n * from the second half of video memory).\n */\n UNKNOWN: 0xFF\n};\n\nVideo.UPDATES_PER_SECOND = 60;\n\n/*\n * Supported Fonts\n *\n * Once we've finished loading the standard 8K font file, aFonts[] should contain one or more of the\n * entries listed below. For the standard MDA/CGA font ROM, the first (MDA) font resides in the first 4Kb,\n * and the second and third (CGA) fonts reside in the two 2K halves of the second 4Kb.\n *\n * It may seem odd that the cell size for FONT_CGAD is *larger* than the cell size for FONT_CGA,\n * since 40-column mode is actually lower resolution, but since we don't shrink the screen canvas when we\n * shrink the mode, the characters must be drawn larger, and they look better if we don't have to scale them.\n *\n * From the IBM EGA Manual (p.5):\n *\n * \"In alphanumeric modes, characters are formed from one of two ROM (Read Only Memory) character\n * generators on the adapter. One character generator defines 7x9 characters in a 9x14 character box.\n * For Enhanced Color Display support, the 9x14 character set is modified to provide an 8x14 character set.\n * The second character generator defines 7x7 characters in an 8x8 character box. These generators contain\n * dot patterns for 256 different characters. The character sets are identical to those provided by the\n * IBM Monochrome Display Adapter and the IBM Color/Graphics Monitor Adapter.\"\n */\nVideo.FONT = {\n MDA: 1, // 9x14 monochrome font\n CGA: 2, // 8x8 color font\n EGA: 3, // 8x14 color font\n VGA: 4 // 8x16 color font\n};\n\n/*\n * Supported Cards\n *\n * Note that we choose card IDs that match the default font ID for each card as well, for convenience.\n */\nVideo.CARD = {\n MDA: Video.FONT.MDA,\n CGA: Video.FONT.CGA,\n EGA: Video.FONT.EGA,\n VGA: Video.FONT.VGA\n};\n\n/*\n * Supported Models\n *\n * Each model refers to an array where [0] is the card ID, and [1] is the default mode.\n */\nVideo.MODEL = {\n \"mda\": [Video.CARD.MDA, Video.MODE.MDA_80X25],\n \"cga\": [Video.CARD.CGA, Video.MODE.CGA_80X25],\n \"ega\": [Video.CARD.EGA, Video.MODE.CGA_80X25],\n \"vga\": [Video.CARD.VGA, Video.MODE.CGA_80X25]\n};\n\n/*\n * Supported Monitors\n *\n * The MDA monitor displays 350 lines of vertical resolution, 720 lines of horizontal resolution, and refreshes\n * at ~50Hz. The CGA monitor displays 200 lines vertically, 640 horizontally, and refreshes at ~60Hz.\n *\n * Based on actual MDA timings (see http://diylab.atwebpages.com/pressureDev.htm), the total horizontal\n * period (drawing a line and retracing) is ~54.25uSec (1000000uSec / 18432) and the horizontal retrace interval\n * is about 15% of that, or ~8.14uSec. Vertical sync occurs once every 370 horizontal periods. Of those 370,\n * only 354 represent actively drawn lines (and of those, only 350 are visible); the remaining 16 horizontal\n * periods, or 4% of the 370 total, represent the vertical retrace interval.\n *\n * I don't have similar numbers for the CGA or EGA, so for now, I assume similar percentages; ie, 15% of\n * the horizontal period will represent horizontal retrace, and 4% of the vertical pixel maximum (262) will\n * represent vertical retrace. However, 24% of the CGA's 262 vertical maximum represents non-visible lines,\n * whereas only 5% of the MDA's 370 maximum represents non-visible lines; is there really that much \"overscan\"\n * on the CGA?\n *\n * For each monitor type, there's a Video.monitorSpecs object that describes the horizontal and vertical\n * timings, along with my assumptions about the percentage of time that drawing is \"active\" within those periods,\n * and then based on the selected monitor type, I compute the number of CPU cycles that each period lasts,\n * as well as the number of CPU cycles that drawing lasts within each period, so that the horizontal and vertical\n * retrace status flags can be quickly calculated.\n *\n * For reference, here are some important numbers to know (from https://github.com/reenigne/reenigne/blob/master/8088/cga/register_values.txt):\n *\n * CGA MDA\n * Pixel clock 14.318 MHz 16.257 MHz (aka \"maximum video bandwidth\", as IBM Tech Refs sometimes call it)\n * Horizontal 15.700 KHz 18.432 KHz (aka \"horizontal drive\", as IBM Tech Refs sometimes call it)\n * Vertical 59.923 Hz 49.816 Hz\n * Usage 53.69% 77.22%\n * H pix 912 = 114*8 882 = 98*9\n * V pix 262 370\n * Dots 238944 326340\n */\n\n/** @typedef {{ nHorzPeriodsPerSec: number, nHorzPeriodsPerFrame: number, percentHorzActive: number, percentVertActive: number }} */\nvar MonitorSpecs;\n\n/**\n * @type {Object}\n */\nVideo.monitorSpecs = {};\n\n/**\n * NOTE: Based on trial-and-error, 208 is the magic number of horizontal syncs per vertical sync that\n * yielded the necessary number of \"horizontal enables\" (200 or 0xC8) in the EGA ROM BIOS at C000:03D0.\n *\n * @type {{MonitorSpecs}}\n */\nVideo.monitorSpecs[ChipSet.MONITOR.COLOR] = {\n nHorzPeriodsPerSec: 15700,\n nHorzPeriodsPerFrame: 208,\n percentHorzActive: 85,\n percentVertActive: 96\n};\n\n/**\n * NOTE: Based on trial-and-error, 364 is the magic number of horizontal syncs per vertical sync that\n * yielded the necessary number of \"horizontal enables\" (350 or 0x15E) in the EGA ROM BIOS at C000:03D0.\n *\n * @type {{MonitorSpecs}}\n */\nVideo.monitorSpecs[ChipSet.MONITOR.MONO] = {\n nHorzPeriodsPerSec: 18432,\n nHorzPeriodsPerFrame: 364,\n percentHorzActive: 85,\n percentVertActive: 96\n};\n\n/**\n * @type {{MonitorSpecs}}\n */\nVideo.monitorSpecs[ChipSet.MONITOR.EGACOLOR] = {\n nHorzPeriodsPerSec: 21850,\n nHorzPeriodsPerFrame: 364,\n percentHorzActive: 85,\n percentVertActive: 96\n};\n\n/**\n * NOTE: As above, the following values are based purely on trial-and-error, to yield results that fall\n * squarely within the bounds of the IBM VGA ROM timing requirements; see the IBM VGA ROM code at C000:024A.\n *\n * @type {{MonitorSpecs}}\n */\nVideo.monitorSpecs[ChipSet.MONITOR.VGACOLOR] = {\n nHorzPeriodsPerSec: 16700,\n nHorzPeriodsPerFrame: 480,\n percentHorzActive: 85,\n percentVertActive: 83\n};\n\n/*\n * EGA Miscellaneous ports and SW1-Sw4\n *\n * The Card.MISC.CLOCK_SELECT bits determine which of the EGA board's 4 configuration switches are\n * returned via Card.STATUS0.SWSENSE (when SWSENSE is zero, the switch is closed):\n *\n * 0xC: return SW1\n * 0x8: return SW2\n * 0x4: return SW3\n * 0x0: return SW4\n *\n * These 4 bits are also copied to the byte at 40:88h by the EGA BIOS, where bit 0 is SW1, bit 1 is SW2,\n * bit 2 is SW3 and bit 3 is SW4. Our switch settings come from bEGASwitches, which in turn comes from\n * sSwitches, which in turn comes from the \"switches\" property passed to the Video component, if any.\n *\n * As usual, the switch settings are reversed in both direction and sense from the switch settings; the\n * good news, however, is that we can use the parseSwitches() method in the ChipSet component to parse them.\n *\n * The set of valid EGA switch values, after conversion, is stored in the table below. For each value,\n * there is an array that defines the corresponding monitor type(s) for the EGA adapter and any secondary\n * adapter. The third value is a boolean indicating whether the EGA is the primary adapter.\n */\nVideo.aEGAMonitorSwitches = {\n 0x06: [ChipSet.MONITOR.TV, ChipSet.MONITOR.MONO, true], // \"1001\"\n 0x07: [ChipSet.MONITOR.COLOR, ChipSet.MONITOR.MONO, true], // \"0001\"\n 0x08: [ChipSet.MONITOR.EGAEMULATION, ChipSet.MONITOR.MONO, true], // \"1110\"\n 0x09: [ChipSet.MONITOR.EGACOLOR, ChipSet.MONITOR.MONO, true], // \"0110\" [our default; see bEGASwitches below]\n 0x0a: [ChipSet.MONITOR.MONO, ChipSet.MONITOR.TV, true], // \"1010\"\n 0x0b: [ChipSet.MONITOR.MONO, ChipSet.MONITOR.COLOR, true], // \"0010\"\n 0x00: [ChipSet.MONITOR.TV, ChipSet.MONITOR.MONO, false], // \"1111\"\n 0x01: [ChipSet.MONITOR.COLOR, ChipSet.MONITOR.MONO, false], // \"0111\"\n 0x02: [ChipSet.MONITOR.EGAEMULATION, ChipSet.MONITOR.MONO, false], // \"1011\"\n 0x03: [ChipSet.MONITOR.EGACOLOR, ChipSet.MONITOR.MONO, false], // \"0011\"\n 0x04: [ChipSet.MONITOR.MONO, ChipSet.MONITOR.TV, false], // \"1101\"\n 0x05: [ChipSet.MONITOR.MONO, ChipSet.MONITOR.COLOR, false] // \"0101\"\n};\n\n/** @typedef {{ cxCell: number, cyCell: number, aCSSColors: Array, aRGBColors: Array, aColorMap: Array, aCanvas: Array }} */\nvar Font;\n\n/*\n * For each video mode, we need to know the following pieces of information:\n *\n * 0: # of columns (nCols)\n * 1: # of rows (nRows)\n * 2: # cells per word (nCellsPerWord: # of characters or pixels per word)\n * 3: # bytes of visible screen padding, if any (used for CGA graphics modes only)\n * 4: font ID (nFont: undefined if graphics mode)\n *\n * For MDA and CGA modes, a \"word\" of memory is 16 bits of CPU-addressable data, so by calculating\n * ([0] * [1]) / [2], we obtain the number of words that mode actively displays; for example, the\n * amount of visible memory used by mode 0x04 is (320 * 200) / 4, or 16000.\n *\n * However, for EGA and VGA graphics modes, a \"word\" of memory is a single element in the video buffer\n * containing 32 bits of pixel data.\n */\nVideo.aModeParms = []; // Mode\nVideo.aModeParms[Video.MODE.CGA_40X25] = [ 40, 25, 1, 0, Video.FONT.CGA]; // 0x01\nVideo.aModeParms[Video.MODE.CGA_80X25] = [ 80, 25, 1, 0, Video.FONT.CGA]; // 0x03\nVideo.aModeParms[Video.MODE.CGA_320X200] = [320, 200, 8, 192]; // 0x04\nVideo.aModeParms[Video.MODE.CGA_640X200] = [640, 200, 16, 192]; // 0x06\nVideo.aModeParms[Video.MODE.MDA_80X25] = [ 80, 25, 1, 0, Video.FONT.MDA]; // 0x07\nVideo.aModeParms[Video.MODE.EGA_320X200] = [320, 200, 8]; // 0x0D\nVideo.aModeParms[Video.MODE.EGA_640X200] = [640, 200, 8]; // 0x0E\nVideo.aModeParms[Video.MODE.EGA_640X350_MONO] = [640, 350, 8]; // 0x0F\nVideo.aModeParms[Video.MODE.EGA_640X350] = [640, 350, 8]; // 0x10\nVideo.aModeParms[Video.MODE.VGA_640X480_MONO] = [640, 480, 8]; // 0x11\nVideo.aModeParms[Video.MODE.VGA_640X480] = [640, 480, 8]; // 0x12\nVideo.aModeParms[Video.MODE.VGA_320X200] = [320, 200, 1]; // 0x13\nVideo.aModeParms[Video.MODE.VGA_320X240] = [320, 240, 4]; // 0x14\nVideo.aModeParms[Video.MODE.VGA_320X400] = [320, 400, 4]; // 0x15\nVideo.aModeParms[Video.MODE.CGA_40X25_BW] = Video.aModeParms[Video.MODE.CGA_40X25]; // 0x00\nVideo.aModeParms[Video.MODE.CGA_80X25_BW] = Video.aModeParms[Video.MODE.CGA_80X25]; // 0x02\nVideo.aModeParms[Video.MODE.CGA_320X200_BW] = Video.aModeParms[Video.MODE.CGA_320X200]; // 0x05\n\n/*\n * MDA attribute byte definitions\n *\n * For MDA, only the following group of ATTR definitions are supported; any FGND/BGND value combinations\n * outside this group will be treated as \"normal\" (ATTR_FGND_WHITE | ATTR_BGND_BLACK).\n *\n * NOTE: Assuming MDA.MODE.BLINK_ENABLE is set (which the ROM BIOS sets by default), ATTR_BGND_BLINK will\n * cause the *foreground* element of the cell to blink, even though it is part of the *background* attribute bits.\n *\n * Regarding blink rate, characters are supposed to blink every 16 vertical frames, which amounts to .26667 blinks\n * per second, assuming a 60Hz vertical refresh rate. So roughly every 267ms, we need to take care of any blinking\n * characters. updateScreen() maintains a global count (cBlinkVisible) of blinking characters, to simplify the\n * decision of when to redraw the screen.\n */\nVideo.ATTRS = {};\nVideo.ATTRS.FGND_BLACK = 0x00;\nVideo.ATTRS.FGND_ULINE = 0x01;\nVideo.ATTRS.FGND_WHITE = 0x07;\nVideo.ATTRS.FGND_BRIGHT = 0x08;\nVideo.ATTRS.BGND_BLACK = 0x00;\nVideo.ATTRS.BGND_WHITE = 0x70;\nVideo.ATTRS.BGND_BLINK = 0x80;\nVideo.ATTRS.BGND_BRIGHT = 0x80;\nVideo.ATTRS.DRAW_FGND = 0x100; // this is an internal attribute bit, indicating the foreground should be drawn\nVideo.ATTRS.DRAW_CURSOR = 0x200; // this is an internal attribute bit, indicating when the cursor should be drawn\n\n/*\n * Here's a \"cheat sheet\" for attribute byte combinations that the IBM MDA could have supported. The original (Aug 1981)\n * IBM Tech Ref is very terse and implies that only those marked with * are actually supported.\n *\n * *0x00: non-display ATTR_FGND_BLACK | ATTR_BGND_BLACK\n * *0x01: underline ATTR_FGND_ULINE | ATTR_BGND_BLACK\n * *0x07: normal (white on black) ATTR_FGND_WHITE | ATTR_BGND_BLACK\n * **0x09: bright underline ATTR_FGND_ULINE | ATTR_FGND_BRIGHT | ATTR_BGND_BLACK\n * **0x0F: bold (bright white on black) ATTR_FGND_WHITE | ATTR_FGND_BRIGHT | ATTR_BGND_BLACK\n * *0x70: reverse (black on white) ATTR_FGND_BLACK | | ATTR_BGND_WHITE\n * 0x81: blinking underline ATTR_FGND_ULINE | | ATTR_BGND_BLINK (or dim background if blink disabled)\n * **0x87: blinking normal ATTR_FGND_WHITE | | ATTR_BGND_BLINK (or dim background if blink disabled)\n * 0x89: blinking bright underline ATTR_FGND_ULINE | ATTR_FGND_BRIGHT | ATTR_BGND_BLINK (or dim background if blink disabled)\n * **0x8F: blinking bold ATTR_FGND_WHITE | ATTR_FGND_BRIGHT | ATTR_BGND_BLINK (or dim background if blink disabled)\n * **0xF0: blinking reverse ATTR_FGND_WHITE | ATTR_FGND_BRIGHT | ATTR_BGND_BLINK (or bright background if blink disabled)\n *\n * Unsupported attributes reportedly display as \"normal\" (ATTR_FGND_WHITE | ATTR_BGND_BLACK). However, precisely which\n * attributes are unsupported on the MDA varies depending on the source. Some sources (eg, the IBM Tech Ref) imply that\n * only those marked by * are supported, while others (eg, some--but not all--Peter Norton guides) include those marked\n * by **, and still others include ALL the combinations listed above.\n *\n * Furthermore, according to http://www.seasip.info/VintagePC/mda.html:\n *\n * Attributes 0x00, 0x08, 0x80 and 0x88 display as black space;\n * Attribute 0x78 displays as dark green on green; depending on the monitor, there may be a green \"halo\" where the dark and bright bits meet;\n * Attribute 0xF0 displays as a blinking version of 0x70 if blink enabled, and black on bright green otherwise;\n * Attribute 0xF8 displays as a blinking version of 0x78 if blink enabled, and as dark green on bright green otherwise.\n *\n * However, I'm rather skeptical about supporting 0x78 and 0xF8, until I see some evidence that \"bright black\" actually\n * produced dark green on IBM equipment; it also doesn't sound like a combination many people would have used. I'll probably\n * treat all of 0x08, 0x80 and 0x88 the same as 0x00, only because it seems logical (they're all \"black on black\" combinations\n * with only BRIGHT and/or BLINK bits set). Beyond that, I'll likely treat any other combination not listed in the above cheat\n * sheet as \"normal\".\n *\n * All the discrepancies/disagreements I've found are probably due in part to the proliferation of IBM and non-IBM MDA\n * cards, combined with IBM and non-IBM monochrome monitors, and people assuming that their non-IBM card and/or monitor\n * behaved exactly like the original IBM equipment, which probably wasn't true in all cases.\n *\n * I would like to limit my MDA display support to EXACTLY everything that the IBM MDA supported and nothing more, but\n * since there will be combinations that will logically \"fall out\" unless I specifically exclude them, it's very likely\n * this implementation will end up being a superset.\n */\n\n/*\n * CGA attribute byte definitions; these simply extend the set of MDA attributes, with the exception of ATTR_FNGD_ULINE,\n * which the CGA can treat only as ATTR_FGND_BLUE.\n */\nVideo.ATTRS.FGND_BLUE = 0x01;\nVideo.ATTRS.FGND_GREEN = 0x02;\nVideo.ATTRS.FGND_CYAN = 0x03;\nVideo.ATTRS.FGND_RED = 0x04;\nVideo.ATTRS.FGND_MAGENTA = 0x05;\nVideo.ATTRS.FGND_BROWN = 0x06;\n\nVideo.ATTRS.BGND_BLUE = 0x10;\nVideo.ATTRS.BGND_GREEN = 0x20;\nVideo.ATTRS.BGND_CYAN = 0x30;\nVideo.ATTRS.BGND_RED = 0x40;\nVideo.ATTRS.BGND_MAGENTA = 0x50;\nVideo.ATTRS.BGND_BROWN = 0x60;\n\n/*\n * For the MDA, the number of unique \"colors\" is 5, based on the following supported FGND attribute values:\n *\n * 0x0: black font (attribute value 0x8 is mapped to 0x0)\n * 0x1: green font with underline\n * 0x7: green font without underline (attribute values 0x2-0x6 are mapped to 0x7)\n * 0x9: bright green font with underline\n * 0xf: bright green font without underline (attribute values 0xa-0xe are mapped to 0xf)\n *\n * I'm still not sure about 0x8 (dark green?); for now, I'm mapping it to 0x0, but it may become a 6th supported color.\n *\n * MDA attributes form an index into aMDAColorMap, which in turn provides an index (0-4) into aMDAColors.\n */\nVideo.aMDAColors = [\n [0x00, 0x00, 0x00, 0xff],\n [0x7f, 0xc0, 0x7f, 0xff],\n [0x7f, 0xc0, 0x7f, 0xff],\n [0x7f, 0xff, 0x7f, 0xff],\n [0x7f, 0xff, 0x7f, 0xff]\n];\nVideo.aMDAColorMap = [0x0, 0x1, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x0, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4];\n\nVideo.aCGAColors = [\n [0x00, 0x00, 0x00, 0xff], // 0x00: ATTR_FGND_BLACK\n [0x00, 0x00, 0xaa, 0xff], // 0x01: ATTR_FGND_BLUE\n [0x00, 0xaa, 0x00, 0xff], // 0x02: ATTR_FGND_GREEN\n [0x00, 0xaa, 0xaa, 0xff], // 0x03: ATTR_FGND_CYAN\n [0xaa, 0x00, 0x00, 0xff], // 0x04: ATTR_FGND_RED\n [0xaa, 0x00, 0xaa, 0xff], // 0x05: ATTR_FGND_MAGENTA\n [0xaa, 0x55, 0x00, 0xff], // 0x06: ATTR_FGND_BROWN\n [0xaa, 0xaa, 0xaa, 0xff], // 0x07: ATTR_FGND_WHITE (aka light gray)\n [0x55, 0x55, 0x55, 0xff], // 0x08: ATTR_FGND_BLACK | ATTR_FGND_BRIGHT (aka gray)\n [0x55, 0x55, 0xff, 0xff], // 0x09: ATTR_FGND_BLUE | ATTR_FGND_BRIGHT\n [0x55, 0xff, 0x55, 0xff], // 0x0A: ATTR_FGND_GREEN | ATTR_FGND_BRIGHT\n [0x55, 0xff, 0xff, 0xff], // 0x0B: ATTR_FGND_CYAN | ATTR_FGND_BRIGHT\n [0xff, 0x55, 0x55, 0xff], // 0x0C: ATTR_FGND_RED | ATTR_FGND_BRIGHT\n [0xff, 0x55, 0xff, 0xff], // 0x0D: ATTR_FGND_MAGENTA | ATTR_FGND_BRIGHT\n [0xff, 0xff, 0x55, 0xff], // 0x0E: ATTR_FGND_BROWN | ATTR_FGND_BRIGHT (aka yellow)\n [0xff, 0xff, 0xff, 0xff] // 0x0F: ATTR_FGND_WHITE | ATTR_FGND_BRIGHT (aka white)\n];\n\nVideo.aCGAColorSet1 = [Video.ATTRS.FGND_GREEN, Video.ATTRS.FGND_RED, Video.ATTRS.FGND_BROWN];\nVideo.aCGAColorSet2 = [Video.ATTRS.FGND_CYAN, Video.ATTRS.FGND_MAGENTA, Video.ATTRS.FGND_WHITE];\n\n/*\n * Here is the EGA BIOS default ATC palette register set for color text modes, from which getCardColors()\n * builds a default RGB array, similar to aCGAColors above.\n */\nVideo.aEGAPalDef = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F];\n\nVideo.aEGAByteToDW = [\n 0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,\n 0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,\n 0xff000000|0, 0xff0000ff|0, 0xff00ff00|0, 0xff00ffff|0,\n 0xffff0000|0, 0xffff00ff|0, 0xffffff00|0, 0xffffffff|0\n];\n\nVideo.aEGADWToByte = [];\nVideo.aEGADWToByte[0x00000000] = 0x0;\nVideo.aEGADWToByte[0x00000080] = 0x1;\nVideo.aEGADWToByte[0x00008000] = 0x2;\nVideo.aEGADWToByte[0x00008080] = 0x3;\nVideo.aEGADWToByte[0x00800000] = 0x4;\nVideo.aEGADWToByte[0x00800080] = 0x5;\nVideo.aEGADWToByte[0x00808000] = 0x6;\nVideo.aEGADWToByte[0x00808080] = 0x7;\nVideo.aEGADWToByte[0x80000000|0] = 0x8;\nVideo.aEGADWToByte[0x80000080|0] = 0x9;\nVideo.aEGADWToByte[0x80008000|0] = 0xa;\nVideo.aEGADWToByte[0x80008080|0] = 0xb;\nVideo.aEGADWToByte[0x80800000|0] = 0xc;\nVideo.aEGADWToByte[0x80800080|0] = 0xd;\nVideo.aEGADWToByte[0x80808000|0] = 0xe;\nVideo.aEGADWToByte[0x80808080|0] = 0xf;\n\n/*\n * Card Specifications\n *\n * We support dynamically switching between MDA and CGA cards by simply flipping switches on\n * the virtual SW1 switch block and resetting the machine. However, I'm not sure I'll support\n * dynamically switching the EGA card the same way; there's certainly no UI for it at this point.\n *\n * For each supported card, there is a cardSpec array that the Card class uses to initialize the\n * card's defaults:\n *\n * [0]: card descriptor\n * [1]: default CRTC port address\n * [2]: default video buffer address\n * [3]: default video buffer size\n * [4]: total on-board memory (if no \"memory\" parm was specified)\n * [5]: default monitor type\n *\n * If total on-board memory is zero, then addMemory() will simply add the specified video buffer\n * to the address space; otherwise, we will allocate an internal buffer (adwMemory) and tell addMemory()\n * to map it to the video buffer address. The latter approach gives us total control over the buffer;\n * refer to getMemoryAccess().\n *\n * TODO: Consider allocating our own buffer for all video cards, not just EGA/VGA. For MDA/CGA, I'm not\n * sure it would offer any benefits, other than allowing our internal update functions, like updateScreen(),\n * to access the buffer directly, instead of going through the Bus memory interface.\n */\nVideo.cardSpecs = [];\nVideo.cardSpecs[Video.CARD.MDA] = [\"MDA\", Card.MDA.CRTC.INDX.PORT, 0xB0000, 0x01000, 0, ChipSet.MONITOR.MONO];\nVideo.cardSpecs[Video.CARD.CGA] = [\"CGA\", Card.CGA.CRTC.INDX.PORT, 0xB8000, 0x04000, 0, ChipSet.MONITOR.COLOR];\nVideo.cardSpecs[Video.CARD.EGA] = [\"EGA\", Card.CGA.CRTC.INDX.PORT, 0xB8000, 0x04000, 0x10000, ChipSet.MONITOR.EGACOLOR];\nVideo.cardSpecs[Video.CARD.VGA] = [\"VGA\", Card.CGA.CRTC.INDX.PORT, 0xB8000, 0x04000, 0x40000, ChipSet.MONITOR.VGACOLOR];\n\n/*\n * Values for nTouchConfig; a value will be selected based on the sTouchScreen configuration parameter.\n */\nVideo.TOUCH = {\n NONE: 0,\n DEFAULT: 1,\n KEYGRID: 2,\n MOUSE: 3\n};\n\n/*\n * Why simulate a SPACE if the tap is in the middle third (center) of the screen? Well, apparently\n * I didn't explain earlier that the WHOLE reason I originally added KEYGRID support (before it was\n * even called KEYGRID support) was to make the 1985 game \"Rogue\" (pcjs.org/apps/pcx86/1985/rogue)\n * more fun to play on an iPad (the space-bar is a commonly required key).\n */\nVideo.KEYGRID = [\n [Keyboard.SIMCODE.HOME, Keyboard.SIMCODE.UP, Keyboard.SIMCODE.PGUP],\n [Keyboard.SIMCODE.LEFT, Keyboard.SIMCODE.SPACE, Keyboard.SIMCODE.RIGHT],\n [Keyboard.SIMCODE.END, Keyboard.SIMCODE.DOWN, Keyboard.SIMCODE.PGDN],\n];\n\n/*\n * Port input/output notification tables\n *\n * TODO: At one point, I'd added some \"duplicate\" entries for the MDA because, according to docs I'd read,\n * MDA ports are decoded at multiple addresses. However, if this is important, then it should be verified\n * and implemented consistently (eg, for CGA as well). For now, I'm decoding only the standard port addresses.\n *\n * For example, 0x3B5 is apparently also decoded at 0x3B1, 0x3B3, and 0x3B7, while 0x3B4 is also decoded at\n * 0x3B0, 0x3B2, and 0x3B6.\n */\nVideo.aMDAPortInput = {\n 0x3B4: Video.prototype.inMDAIndx, // technically, not actually readable, but I want the Debugger to be able to read this\n 0x3B5: Video.prototype.inMDAData, // technically, the only CRTC Data registers that are readable are R14-R17\n 0x3B8: Video.prototype.inMDAMode, // technically, not actually readable, but I want the Debugger to be able to read this\n 0x3BA: Video.prototype.inMDAStatus\n};\n\nVideo.aMDAPortOutput = {\n 0x3B4: Video.prototype.outMDAIndx,\n 0x3B5: Video.prototype.outMDAData,\n 0x3B8: Video.prototype.outMDAMode\n};\n\nVideo.aCGAPortInput = {\n 0x3D4: Video.prototype.inCGAIndx, // technically, not actually readable, but I want the Debugger to be able to read this\n 0x3D5: Video.prototype.inCGAData, // technically, the only CRTC Data registers that are readable are R14-R17\n 0x3D8: Video.prototype.inCGAMode, // technically, not actually readable, but I want the Debugger to be able to read this\n 0x3D9: Video.prototype.inCGAColor, // technically, not actually readable, but I want the Debugger to be able to read this\n 0x3DA: Video.prototype.inCGAStatus\n};\n\nVideo.aCGAPortOutput = {\n 0x3D4: Video.prototype.outCGAIndx,\n 0x3D5: Video.prototype.outCGAData,\n 0x3D8: Video.prototype.outCGAMode,\n 0x3D9: Video.prototype.outCGAColor\n};\n\nVideo.aEGAPortInput = {\n 0x3C0: Video.prototype.inATCIndx, // technically, only readable on a VGA, but I want the Debugger to be able to read this, too\n 0x3C1: Video.prototype.inATCData, // technically, only readable on a VGA, but I want the Debugger to be able to read this, too\n 0x3C2: Video.prototype.inStatus0,\n 0x3C4: Video.prototype.inSEQIndx, // technically, only readable on a VGA, but I want the Debugger to be able to read this, too\n 0x3C5: Video.prototype.inSEQData, // technically, only readable on a VGA, but I want the Debugger to be able to read this, too\n 0x3CE: Video.prototype.inGRCIndx, // technically, only readable on a VGA, but I want the Debugger to be able to read this, too\n 0x3CF: Video.prototype.inGRCData // technically, only readable on a VGA, but I want the Debugger to be able to read this, too\n};\n\n/*\n * WARNING: Unlike the EGA, a standard VGA does not support writes to 0x3C1, but it's easier for me to leave that\n * ability in place, treating the VGA as a superset of the EGA as much as possible; will any code break because word\n * OUTs to port 0x3C0 (and/or byte OUTs to port 0x3C1) actually work? Possibly, but highly unlikely.\n */\nVideo.aEGAPortOutput = {\n 0x3BA: Video.prototype.outFeat,\n 0x3C0: Video.prototype.outATC,\n 0x3C1: Video.prototype.outATC, // the EGA BIOS writes to this port (see C000:0416), implying that 0x3C0 and 0x3C1 both decode the same register\n 0x3C2: Video.prototype.outMisc, // FYI, since this overlaps with STATUS0.PORT, there's currently no way for the Debugger to read the Misc register\n 0x3C4: Video.prototype.outSEQIndx,\n 0x3C5: Video.prototype.outSEQData,\n 0x3CA: Video.prototype.outGRCPos2,\n 0x3CC: Video.prototype.outGRCPos1,\n 0x3CE: Video.prototype.outGRCIndx,\n 0x3CF: Video.prototype.outGRCData,\n 0x3DA: Video.prototype.outFeat\n};\n\nVideo.aVGAPortInput = {\n 0x3C3: Video.prototype.inVGAEnable,\n 0x3C6: Video.prototype.inDACMask,\n 0x3C7: Video.prototype.inDACState,\n 0x3C9: Video.prototype.inDACData,\n 0x3CA: Video.prototype.inVGAFeat,\n 0x3CC: Video.prototype.inVGAMisc\n};\n\nVideo.aVGAPortOutput = {\n 0x3C3: Video.prototype.outVGAEnable,\n 0x3C6: Video.prototype.outDACMask,\n 0x3C7: Video.prototype.outDACRead,\n 0x3C8: Video.prototype.outDACWrite,\n 0x3C9: Video.prototype.outDACData\n};\n\n/*\n * Initialize every Video module on the page.\n */\nWeb.onInit(Video.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/parallel.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * class ParallelPort\n * property {number} iAdapter\n * property {number} portBase\n * property {number} nIRQ\n * property {Object} controlBuffer is a DOM element bound to the port (for rudimentary output; see transmitByte())\n *\n * NOTE: This class declaration started as a way of informing the code inspector of the controlBuffer property,\n * which remained undefined until a setBinding() call set it later, but I've since decided that explicitly\n * initializing such properties in the constructor is a better way to go -- even though it's more code -- because\n * JavaScript compilers are supposed to be happier when the underlying object structures aren't constantly changing.\n *\n * Besides, I'm not sure I want to get into documenting every property this way, for this or any/every other class,\n * let alone getting into which ones should be considered private or protected, because PCjs isn't really a library\n * for third-party apps.\n */\n\n/**\n * class ParallelPort\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass ParallelPort extends Component {\n /**\n * ParallelPort(parmsParallel)\n *\n * The ParallelPort component has the following component-specific (parmsParallel) properties:\n *\n * adapter: 1 (port 0x3BC), 2 (port 0x378), or 3 (port 0x278); 0 if not defined\n *\n * binding: name of a control (based on its \"binding\" attribute) to bind to this port's I/O\n *\n * In the future, we may support 'port' and 'irq' properties that allow the machine to define a\n * non-standard parallel port configuration, instead of only our pre-defined 'adapter' configurations.\n *\n * NOTE: Since the XSL file defines 'adapter' as a number, not a string, there's no need to use\n * parseInt(), and as an added benefit, we don't need to worry about whether a hex or decimal format\n * was used.\n *\n * DOS typically names the Primary adapter \"LPT1\" and the Secondary adapter \"LPT2\", but I prefer\n * to stick to adapter numbers, since not all operating systems follow those naming conventions.\n *\n * @this {ParallelPort}\n * @param {Object} parmsParallel\n */\n constructor(parmsParallel)\n {\n super(\"ParallelPort\", parmsParallel, Messages.PARALLEL);\n\n this.iAdapter = parmsParallel['adapter'];\n\n switch (this.iAdapter) {\n case 1:\n this.portBase = 0x3BC;\n this.nIRQ = ChipSet.IRQ.LPT1;\n break;\n case 2:\n this.portBase = 0x378;\n this.nIRQ = ChipSet.IRQ.LPT1;\n break;\n case 3:\n this.portBase = 0x278;\n this.nIRQ = ChipSet.IRQ.LPT2;\n break;\n default:\n Component.warning(\"Unrecognized parallel adapter #\" + this.iAdapter);\n return;\n }\n /**\n * consoleBuffer becomes a string that records parallel port output if the 'binding' property is set to the\n * reserved name \"console\". Nothing is written to the console, however, until a linefeed (0x0A) is output\n * or the string length reaches a threshold (currently, 1024 characters).\n *\n * @type {string|null}\n */\n this.consoleBuffer = null;\n\n /**\n * controlBuffer is a DOM element bound to the port (currently used for output only; see transmitByte()).\n *\n * @type {Object}\n */\n this.controlBuffer = null;\n\n var sBinding = parmsParallel['binding'];\n if (sBinding == \"console\") {\n this.consoleBuffer = \"\";\n } else {\n /*\n * If the ParallelPort wants to bind to a control (eg, \"print\") in a DIFFERENT component (eg, \"Panel\"),\n * then it specifies the name of that control with the 'binding' property. The ParallelPort constructor\n * will then call bindExternalControl(), which looks up the control, and then passes it to our own\n * setBinding() handler.\n * \n * For bindExternalControl() to succeed, it also need to know the target component; for now, that's\n * been hard-coded to \"Panel\", in part because that's one of the few components we can rely upon\n * initializing before we do, but it would be a simple matter to include a component type or ID as part\n * of the 'binding' property as well, if we need more flexibility later.\n * \n * NOTE: If sBinding is not the name of a valid Control Panel DOM element, this call does nothing.\n */\n Component.bindExternalControl(this, sBinding);\n }\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {ParallelPort}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"buffer\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n if (!sHTMLType || sHTMLType == \"textarea\") {\n this.bindings[sBinding] = this.controlBuffer = control;\n return true;\n }\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {ParallelPort}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.chipset = cmp.getMachineComponent(\"ChipSet\");\n bus.addPortInputTable(this, ParallelPort.aPortInput, this.portBase);\n bus.addPortOutputTable(this, ParallelPort.aPortOutput, this.portBase);\n this.setReady();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {ParallelPort}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data || !this.restore) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {ParallelPort}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {ParallelPort}\n */\n reset()\n {\n this.initState();\n }\n\n /**\n * save()\n *\n * This implements save support for the ParallelPort component.\n *\n * @this {ParallelPort}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveRegisters());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the ParallelPort component.\n *\n * @this {ParallelPort}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return this.initState(data[0]);\n }\n\n /**\n * initState(data)\n *\n * @this {ParallelPort}\n * @param {Array} [data]\n * @return {boolean} true if successful, false if failure\n */\n initState(data)\n {\n var i = 0;\n if (data === undefined) {\n data = [0, ParallelPort.STATUS.NERR, 0];\n }\n this.bData = data[i++];\n this.bStatus = data[i++];\n this.bControl = data[i];\n return true;\n }\n\n /**\n * saveRegisters()\n *\n * @this {ParallelPort}\n * @return {Array}\n */\n saveRegisters()\n {\n var i = 0;\n var data = [];\n data[i++] = this.bData;\n data[i++] = this.bStatus;\n data[i] = this.bControl;\n return data;\n }\n\n /**\n * inData(port, addrFrom)\n *\n * @this {ParallelPort}\n * @param {number} port (0x3BC, 0x378, or 0x278)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inData(port, addrFrom)\n {\n var b = this.bData;\n this.printMessageIO(port, null, addrFrom, \"DATA\", b);\n return b;\n }\n\n /**\n * inStatus(port, addrFrom)\n *\n * @this {ParallelPort}\n * @param {number} port (0x3BD, 0x379, or 0x279)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inStatus(port, addrFrom)\n {\n var b = this.bStatus;\n this.bStatus |= (ParallelPort.STATUS.NACK | ParallelPort.STATUS.NBUSY);\n this.printMessageIO(port, null, addrFrom, \"STAT\", b);\n this.updateIRR();\n return b;\n }\n\n /**\n * inControl(port, addrFrom)\n *\n * @this {ParallelPort}\n * @param {number} port (0x3BE, 0x37A, or 0x27A)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inControl(port, addrFrom)\n {\n var b = this.bControl;\n this.printMessageIO(port, null, addrFrom, \"CTRL\", b);\n return b;\n }\n\n /**\n * outData(port, bOut, addrFrom)\n *\n * @this {ParallelPort}\n * @param {number} port (0x3BC, 0x378, or 0x278)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outData(port, bOut, addrFrom)\n {\n var parallel = this;\n this.printMessageIO(port, bOut, addrFrom, \"DATA\");\n this.bData = bOut;\n this.cpu.nonCPU(function() {\n if (parallel.transmitByte(bOut)) {\n parallel.bStatus |= ParallelPort.STATUS.NERR;\n parallel.bStatus &= ~(ParallelPort.STATUS.NACK | ParallelPort.STATUS.NBUSY);\n return true;\n }\n return false;\n });\n this.updateIRR();\n }\n\n /**\n * outControl(port, bOut, addrFrom)\n *\n * @this {ParallelPort}\n * @param {number} port (0x3BE, 0x37A, or 0x27A)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outControl(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"CTRL\");\n this.bControl = bOut;\n this.updateIRR();\n }\n\n /**\n * updateIRR()\n *\n * @this {ParallelPort}\n */\n updateIRR()\n {\n if (this.chipset && this.nIRQ) {\n if ((this.bControl & ParallelPort.CONTROL.IRQ_ENABLE) && !(this.bStatus & ParallelPort.STATUS.NACK)) {\n this.chipset.setIRR(this.nIRQ);\n } else {\n this.chipset.clearIRR(this.nIRQ);\n }\n }\n }\n\n /**\n * transmitByte(b)\n *\n * @this {ParallelPort}\n * @param {number} b\n * @return {boolean} true if transmitted, false if not\n */\n transmitByte(b)\n {\n var fTransmitted = false;\n\n this.printMessage(\"transmitByte(\" + Str.toHexByte(b) + \")\");\n\n if (this.controlBuffer) {\n if (b == 0x0D) {\n // this.iLogicalCol = 0;\n }\n else if (b == 0x08) {\n this.controlBuffer.value = this.controlBuffer.value.slice(0, -1);\n }\n else {\n /*\n * If we assume that the printer being used was the original IBM 80 CPS Matrix Printer,\n * characters 0x80-0x9F mirror control codes 0x00-0x1F, and characters 0xA0-0xDF are various\n * block shapes, sort of in the spirit of the line-drawing characters 0xC0-0xDF defined by\n * IBM Code Page 437, but, no, completely different. And apparently, characters 0xE0-0xFF\n * printed nothing at all (see Table 11 on page 2-78 of the original IBM PC 5150 TechRef).\n *\n * The only control character we care about is LINE-FEED; for all other control characters,\n * we'll display the ASCII mnemonic, to make it clear what the software intended. And as for\n * any block characters, we'll print an asterisk and call it good, for now. Beyond that,\n * we'll just print spaces.\n */\n if (b >= 0x80) {\n if (b < 0xA0) {\n b -= 0x80;\n } else if (b < 0xE0) {\n b = 0x2A; // ASCII code for an asterisk\n } else {\n b = 0x20; // ASCII code for a space\n }\n }\n this.controlBuffer.value += Str.toASCIICode(b);\n this.controlBuffer.scrollTop = this.controlBuffer.scrollHeight;\n }\n fTransmitted = true;\n }\n else if (this.consoleBuffer != null) {\n if (b == 0x0A || this.consoleBuffer.length >= 1024) {\n this.println(this.consoleBuffer);\n this.consoleBuffer = \"\";\n }\n if (b != 0x0A) {\n this.consoleBuffer += String.fromCharCode(b);\n }\n fTransmitted = true;\n }\n\n return fTransmitted;\n }\n\n /**\n * ParallelPort.init()\n *\n * This function operates on every HTML element of class \"parallel\", extracting the\n * JSON-encoded parameters for the ParallelPort constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a ParallelPort component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeParallel = Component.getElementsByClass(document, PCX86.APPCLASS, \"parallel\");\n for (var iParallel = 0; iParallel < aeParallel.length; iParallel++) {\n var eParallel = aeParallel[iParallel];\n var parmsParallel = Component.getComponentParms(eParallel);\n var parallel = new ParallelPort(parmsParallel);\n Component.bindComponentControls(parallel, eParallel, PCX86.APPCLASS);\n }\n }\n}\n\n/*\n * The \"Data Register\" is an input/output register at offset 0 from portBase. The bit-to-pin mappings are:\n *\n * Bit Pin\n * --- ---\n * 0 2 // 0x01 (DATA 1)\n * 1 3 // 0x02 (DATA 2)\n * 2 4 // 0x04 (DATA 3)\n * 3 5 // 0x08 (DATA 4)\n * 4 6 // 0x10 (DATA 5)\n * 5 7 // 0x20 (DATA 6)\n * 6 8 // 0x40 (DATA 7)\n * 7 9 // 0x80 (DATA 8)\n */\nParallelPort.DATA = { // (read/write)\n REG: 0\n};\n\n/*\n * The \"Status Register\" is an input register at offset 1 from portBase. The bit-to-pin mappings are:\n *\n * Bit Pin\n * --- ---\n * 0 - // 0x01\n * 1 - // 0x02\n * 2 - // 0x04\n * 3 !15 // 0x08 (Error)\n * 4 13 // 0x10 (Select)\n * 5 12 // 0x20 (Out of Paper)\n * 6 !10 // 0x40 (Acknowledged)\n * 7 11 // 0x80 (Busy; eg, printer off-line or operation in progress)\n */\nParallelPort.STATUS = { // (read)\n REG: 1,\n NERR: 0x08, // when this bit is clear, I/O error (inverted by the ROM BIOS INT 17h Status function)\n SELECT: 0x10, // when this bit is set, printer selected\n PAPER: 0x20, // when this bit is set, out of paper\n NACK: 0x40, // when this bit is clear, data acknowledged (and optionally, interrupt requested; inverted by the ROM BIOS INT 17h Status function)\n NBUSY: 0x80 // when this bit is clear, printer busy\n};\n\n/*\n * The \"Control Register\" is an input/output register at offset 2 from portBase. The bit-to-pin mappings are:\n *\n * Bit Pin\n * --- ---\n * 0 !1 // 0x01 (read input data)\n * 1 !14 // 0x02 (automatically feed paper one line)\n * 2 16 // 0x04\n * 3 !17 // 0x08\n *\n * Additionally, bit 4 is the IRQ ENABLE bit, which allows interrupts when pin 10 transitions high to low.\n */\nParallelPort.CONTROL = { // (read/write)\n REG: 2,\n IRQ_ENABLE: 0x10 // set to enable interrupts\n};\n\n/*\n * Port input notification table\n */\nParallelPort.aPortInput = {\n 0x0: ParallelPort.prototype.inData,\n 0x1: ParallelPort.prototype.inStatus,\n 0x2: ParallelPort.prototype.inControl\n};\n\n/*\n * Port output notification table\n */\nParallelPort.aPortOutput = {\n 0x0: ParallelPort.prototype.outData,\n 0x2: ParallelPort.prototype.outControl\n};\n\n/*\n * Initialize every ParallelPort module on the page.\n */\nWeb.onInit(ParallelPort.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/serial.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * SerialPort class\n *\n * The class property declarations below started as a way of informing the code inspector of the controlBuffer\n * property, which remained undefined until a setBinding() call set it later, but I've since decided that explicitly\n * initializing such properties in the constructor is a better way to go -- even though it's more code -- because\n * JavaScript compilers are supposed to be happier when the underlying object structures aren't constantly changing.\n *\n * Besides, I'm not sure I want to get into documenting every property this way, for this or any/every other class,\n * let alone getting into which ones should be considered private or protected, because PCjs isn't really a library\n * for third-party apps.\n *\n * @class SerialPort\n * @property {number} iAdapter\n * @property {number} portBase\n * @property {number} nIRQ\n * @property {string|null} consoleBuffer\n * @property {HTMLTextAreaElement} controlBuffer (DOM element bound to the port for rudimentary output; see transmitByte())\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass SerialPort extends Component {\n /**\n * SerialPort(parms)\n *\n * The SerialPort component has the following component-specific (parms) properties:\n *\n * adapter: 1 (port 0x3F8) or 2 (port 0x2F8); 0 if not defined\n *\n * binding: name of a control (based on its \"binding\" attribute) to bind to this port's I/O;\n * as a special case, it can be set to \"console\" to direct all output to the component's default\n * println() handler (eg, the Control Panel's \"print\" control, if any, or console.log() if using\n * a DEBUG or non-COMPILED machine)\n *\n * tabSize: a non-zero number specifies the tab-stop multiple to use for automatic tab-to-space\n * conversion; it applies only to the above binding, and the default is 0 (no tab conversion)\n *\n * charBOL: a non-zero number specifies the ASCII code of a character to display at the beginning\n * of every line; it applies only to the above binding, and the default is 0 (no BOL character)\n *\n * In the future, we may support 'port' and 'irq' properties that allow the machine to define a non-standard\n * serial port configuration, instead of only our pre-defined 'adapter' configurations.\n *\n * NOTE: Since the XSL file defines 'adapter' as a number, not a string, there's no need to use parseInt(),\n * and as an added benefit, we don't need to worry about whether a hex or decimal format was used.\n *\n * This hard-coded approach mimics the original IBM PC Asynchronous Adapter configuration, which contained\n * a pair of \"shunt modules\" that allowed the user to select a port address/IRQ combo of either 0x3F8/IRQ4\n * (\"Primary\") or 0x2F8/IRQ3 (\"Secondary\").\n *\n * DOS names the first adapter listed by the ROM BIOS as \"COM1\", even if that adapter is a secondary adapter,\n * so don't assume that COM1 always maps to port 0x3F8/IRQ4. Internally, I try avoid confusion by always\n * starting with a primary adapter and giving that adapter an ID of \"com1\". But different operating systems\n * may follow different device enumeration and naming conventions, so don't make too much of my internally\n * assigned IDs.\n *\n * @this {SerialPort}\n * @param {Object} parms\n */\n constructor(parms)\n {\n super(\"SerialPort\", parms, Messages.SERIAL);\n\n this.iAdapter = parms['adapter'];\n\n switch (this.iAdapter) {\n case 1:\n this.portBase = 0x3F8;\n this.nIRQ = ChipSet.IRQ.COM1;\n break;\n case 2:\n this.portBase = 0x2F8;\n this.nIRQ = ChipSet.IRQ.COM2;\n break;\n default:\n if (this.idComponent != \"test\") {\n Component.warning(\"Unrecognized serial adapter #\" + this.iAdapter);\n return;\n }\n break;\n }\n \n /*\n * consoleBuffer becomes a string that records serial port output if the 'binding' property is set to the\n * reserved name \"console\". Nothing is written to the console, however, until a linefeed (0x0A) is output\n * or the string length reaches a threshold (currently, 1024 characters).\n */\n this.consoleBuffer = null;\n\n /*\n * controlBuffer is a DOM element bound to the port (currently used for output only; see transmitByte()).\n *\n * Example: CTTY COM2\n *\n * The CTTY DOS command redirects all CON I/O to the specified serial port (eg, COM2), which it assumes is\n * connected to a serial terminal, and therefore anything it *transmits* via COM2 will be displayed by the\n * terminal. It further assumes that anything typed on such a terminal is NOT displayed, so as DOS *receives*\n * serial input, DOS *transmits* the appropriate characters back to the terminal via COM2.\n *\n * As a result, controlBuffer only needs to be updated by the transmitByte() function.\n */\n this.controlBuffer = null;\n\n /*\n * If controlBuffer is being used AND 'tabSize' is set, then we make an attempt to monitor the characters\n * being echoed via transmitByte(), maintain a logical column position, and convert any tabs into the appropriate\n * number of spaces.\n *\n * Another controlBuffer feature is charBOL, which, if nonzero, specifies a character to automatically output\n * at the beginning of every line. This probably isn't generally useful; I use it internally to preformat serial\n * output.\n */\n this.tabSize = parms['tabSize'] || 0;\n this.charBOL = parms['charBOL'] || 0;\n this.charPrev = 0;\n this.iLogicalCol = 0;\n\n this.bMSRInit = SerialPort.MSR.CTS | SerialPort.MSR.DSR;\n this.fNullModem = true;\n\n /*\n * Normally, any HTML controls defined within the scope of the component's XML element are *implicitly*\n * bound to us. For example, in the XML below, the textarea control will automatically trigger a call to\n * setBinding() with sBinding set to \"serialWindow\" and control set to an HTMLTextAreaElement.\n * \n\t * <serial id=\"com1\">\n\t * <control type=\"container\" class=\"pcjs-textarea\">\n\t * \t <control type=\"textarea\" binding=\"serialWindow\"/>\n\t * </control>\n\t * </serial>\n\t * \n\t * However, this component also supports an *explicit* binding attribute, which can either be the hard-coded\n\t * name \"console\" (for routing all output to the system console) or the name of a control binding that has\n\t * been defined in another component (eg, an HTMLTextAreaElement defined as part of the Control Panel layout).\n */\n var sBinding = parms['binding'];\n if (sBinding == \"console\") {\n this.consoleBuffer = \"\";\n } else {\n /*\n * If the SerialPort wants to bind to a control (eg, \"print\") in a DIFFERENT component (eg, \"Panel\"),\n * then it specifies the name of that control with the 'binding' property. The SerialPort constructor\n * will then call bindExternalControl(), which looks up the control, and then passes it to our own\n * setBinding() handler.\n * \n * For bindExternalControl() to succeed, it also need to know the target component; for now, that's\n * been hard-coded to \"Panel\", in part because that's one of the few components we can rely upon\n * initializing before we do, but it would be a simple matter to include a component type or ID as part\n * of the 'binding' property as well, if we need more flexibility later.\n * \n * NOTE: If sBinding is not the name of a valid Control Panel DOM element, this call does nothing.\n */\n Component.bindExternalControl(this, sBinding);\n }\n\n /*\n * No connection until initConnection() is called.\n */\n this.sDataReceived = \"\";\n this.connection = this.sendData = this.updateStatus = null;\n this.fAutoFlow = false;\n\n /*\n * Export all functions required by bindConnection() or initConnection(), whichever is required.\n */\n this['exports'] = {\n 'bind': this.bindConnection,\n 'connect': this.initConnection,\n 'receiveData': this.receiveData,\n 'receiveStatus': this.receiveStatus\n };\n }\n\n /**\n * bindConnection(connection, receiveData, fAutoFlow)\n * \n * This is basically a lighter-weight version of initConnection(), used by built-in components\n * like TestController, as opposed to components in external machines, which require more work to connect.\n *\n * @this {SerialPort}\n * @param {Component} connection\n * @param {function()} receiveData\n * @param {boolean} [fAutoFlow] (true to enable automatic flow control; default is false)\n * @return {boolean}\n */\n bindConnection(connection, receiveData, fAutoFlow = false)\n {\n if (!this.connection) {\n this.connection = connection;\n this.sendData = receiveData;\n this.fAutoFlow = fAutoFlow;\n return true;\n }\n return false;\n }\n\n /**\n * bindMouse(id, mouse, fnUpdate)\n *\n * @this {SerialPort}\n * @param {string} id\n * @param {Mouse} mouse\n * @param {function(number)} fnUpdate\n * @return {Component|null}\n */\n bindMouse(id, mouse, fnUpdate)\n {\n var component = null;\n if (id == this.idComponent && !this.connection) {\n this.connection = mouse;\n this.updateStatus = fnUpdate;\n this.fNullModem = false;\n component = this;\n }\n return component;\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {SerialPort}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"buffer\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n if (!sHTMLType || sHTMLType == \"textarea\") {\n\n var serial = this;\n this.bindings[sBinding] = this.controlBuffer = /** @type {HTMLTextAreaElement} */ (control);\n\n /*\n * By establishing an onkeypress handler here, we make it possible for DOS commands like\n * \"CTTY COM1\" to more or less work (use \"CTTY CON\" to restore control to the DOS console).\n */\n this.controlBuffer.onkeydown = function onKeyDown(event) {\n /*\n * This is required in addition to onkeypress, because it's the only way to prevent\n * BACKSPACE (keyCode 8) from being interpreted by the browser as a \"Back\" operation;\n * moreover, not all browsers generate an onkeypress notification for BACKSPACE.\n *\n * A related problem exists for Ctrl-key combinations in most Windows-based browsers\n * (eg, IE, Edge, Chrome for Windows, etc), because keys like Ctrl-C and Ctrl-S have\n * special meanings (eg, Copy, Save). To the extent the browser will allow it, we\n * attempt to disable that default behavior when this control receives an onkeydown\n * event for one of those keys (probably the only event the browser generates for them).\n */\n event = event || window.event;\n var keyCode = event.keyCode;\n if (keyCode === 0x08 || event.ctrlKey && keyCode >= 0x41 && keyCode <= 0x5A) {\n if (event.preventDefault) event.preventDefault();\n if (keyCode > 0x40) keyCode -= 0x40;\n serial.receiveData(keyCode);\n }\n return true;\n };\n\n this.controlBuffer.onkeypress = function onKeyPress(event) {\n /*\n * Browser-independent keyCode extraction; refer to onKeyPress() and the other key event\n * handlers in keyboard.js.\n */\n event = event || window.event;\n var keyCode = event.which || event.keyCode;\n serial.receiveData(keyCode);\n /*\n * Since we're going to remove the \"readonly\" attribute from the <textarea> control\n * (so that the soft keyboard activates on iOS), instead of calling preventDefault() for\n * selected keys (eg, the SPACE key, whose default behavior is to scroll the page), we must\n * now call it for *all* keys, so that the keyCode isn't added to the control immediately,\n * on top of whatever the machine is echoing back, resulting in double characters.\n */\n if (event.preventDefault) event.preventDefault();\n return true;\n };\n\n /*\n * Now that we've added an onkeypress handler that calls preventDefault() for ALL keys, the control\n * itself no longer needs the \"readonly\" attribute; we primarily need to remove it for iOS browsers,\n * so that the soft keyboard will activate, but it shouldn't hurt to remove the attribute for all browsers.\n */\n this.controlBuffer.removeAttribute(\"readonly\");\n return true;\n }\n\n // default:\n // if (!this.iAdapter) {\n // control.removeAttribute(\"readonly\");\n // }\n // break;\n // }\n \n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {SerialPort}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n \n if (this.iAdapter) {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n var serial = this;\n this.timerReceiveNext = this.cpu.addTimer(this.id + \".receive\", function receiveDataTimer() {\n serial.receiveData();\n });\n this.timerTransmitNext = this.cpu.addTimer(this.id + \".transmit\", function transmitDataTimer() {\n serial.transmitData();\n });\n\n this.chipset = cmp.getMachineComponent(\"ChipSet\");\n\n bus.addPortInputTable(this, SerialPort.aPortInput, this.portBase);\n bus.addPortOutputTable(this, SerialPort.aPortOutput, this.portBase);\n }\n this.setReady();\n }\n\n /**\n * initConnection(fNullModem)\n *\n * If a machine 'connection' parameter exists of the form \"{sourcePort}->{targetMachine}.{targetPort}\",\n * and \"{sourcePort}\" matches our idComponent, then look for a component with id \"{targetMachine}.{targetPort}\".\n *\n * If the target component is found, then verify that it has exported functions with the following names:\n *\n * receiveData(data): called when we have data to transmit; aliased internally to sendData(data)\n * receiveStatus(pins): called when our control signals have changed; aliased internally to updateStatus(pins)\n *\n * For now, we're not going to worry about communication in the other direction, because when the target component\n * performs its own initConnection(), it will find our receiveData() and receiveStatus() functions, at which point\n * communication in both directions should be established, and the circle of life is complete.\n *\n * For added robustness, if the target machine initializes much more slowly than we do, and our connection attempt\n * fails, that's OK, because when it finally initializes, its initConnection() will call our initConnection();\n * if we've already initialized, no harm done.\n *\n * @this {SerialPort}\n * @param {boolean} [fNullModem] (caller's null-modem setting, to ensure our settings are in agreement)\n */\n initConnection(fNullModem)\n {\n if (!this.connection) {\n var sConnection = this.cmp.getMachineParm(\"connection\");\n if (sConnection) {\n var asParts = sConnection.split('->');\n if (asParts.length == 2) {\n var sSourceID = Str.trim(asParts[0]);\n if (sSourceID != this.idComponent) return; // this connection string is intended for another instance\n var sTargetID = Str.trim(asParts[1]);\n this.connection = Component.getComponentByID(sTargetID);\n if (this.connection) {\n var exports = this.connection['exports'];\n if (exports) {\n var fnConnect = /** @function */ (exports['connect']);\n if (fnConnect) fnConnect.call(this.connection, this.fNullModem);\n this.sendData = exports['receiveData'];\n if (this.sendData) {\n this.fNullModem = fNullModem;\n this.updateStatus = exports['receiveStatus'];\n this.status(\"Connected \" + this.idMachine + '.' + sSourceID + \" to \" + sTargetID);\n return;\n }\n }\n }\n }\n /*\n * Changed from notice() to status() because sometimes a connection fails simply because one of us is a laggard.\n */\n this.status(\"Unable to establish connection: \" + sConnection);\n }\n }\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {SerialPort}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n /*\n * This is as late as we can currently wait to make our first inter-machine connection attempt;\n * even so, the target machine's initialization process may still be ongoing, so any connection\n * may be not fully resolved until the target machine performs its own initConnection(), which will\n * in turn invoke our initConnection() again.\n */\n this.initConnection(this.fNullModem);\n\n if (!data || !this.restore) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {SerialPort}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {SerialPort}\n */\n reset()\n {\n this.initState();\n }\n\n /**\n * save()\n *\n * This implements save support for the SerialPort component.\n *\n * @this {SerialPort}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveRegisters());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the SerialPort component.\n *\n * @this {SerialPort}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return this.initState(data[0]);\n }\n\n /**\n * initState(data)\n *\n * @this {SerialPort}\n * @param {Array} [data]\n * @return {boolean} true if successful, false if failure\n */\n initState(data)\n {\n /*\n * The NS8250A spec doesn't explicitly say what the RBR and THR are initialized to on a reset,\n * but I think we can safely assume zeros. Similarly, we reset the baud rate Divisor Latch (wDL)\n * to an arbitrary but consistent default (DL_DEFAULT).\n */\n var i = 0;\n if (data === undefined) {\n data = [\n 0, // RBR\n 0, // THR\n SerialPort.DL_DEFAULT, // DL\n 0, // IER\n SerialPort.IIR.NO_INT, // IIR\n 0, // LCR\n 0, // MCR\n SerialPort.LSR.THRE | SerialPort.LSR.TSRE, // LSR\n this.bMSRInit, // MSR\n []\n ];\n }\n this.bRBR = data[i++];\n this.bTHR = data[i++];\n this.wDL = data[i++];\n this.bIER = data[i++];\n this.bIIR = data[i++];\n this.bLCR = data[i++];\n this.bMCR = data[i++];\n this.bLSR = data[i++];\n this.bMSR = data[i++];\n this.abReceive = data[i];\n return true;\n }\n\n /**\n * saveRegisters()\n *\n * @this {SerialPort}\n * @return {Array}\n */\n saveRegisters()\n {\n var i = 0;\n var data = [];\n data[i++] = this.bRBR;\n data[i++] = this.bTHR;\n data[i++] = this.wDL;\n data[i++] = this.bIER;\n data[i++] = this.bIIR;\n data[i++] = this.bLCR;\n data[i++] = this.bMCR;\n data[i++] = this.bLSR;\n data[i++] = this.bMSR;\n data[i] = this.abReceive;\n return data;\n }\n\n /**\n * getBaudTimeout()\n *\n * The 16-bit Divisor Latch is stored in wDL. If we take the frequency value 1843200 and divide it by wDL*128,\n * we get the maximum number of bytes per second that the SerialPort interface should generate. For example,\n * if a baud rate of 1200 is being used, the divisor will be 0x60 (96), so we calculate 1843200/(96*128) = 150,\n * which means there should be a 1000ms/150 or 6.667ms delay between bytes delivered.\n *\n * @this {SerialPort}\n * @return {number} (number of milliseconds per byte)\n */\n getBaudTimeout()\n {\n var nBytesPerSecond = 1843200 / ((this.wDL || 1) << 7);\n return (1000 / nBytesPerSecond)|0;\n }\n\n /**\n * receiveData(data)\n *\n * This replaces the old sendRBR() function, which expected an Array of bytes. We still support that,\n * but in order to support connections with other SerialPort components (ie, the PC8080 SerialPort), we\n * have added support for numbers and strings as well. If no data is specified at all, then all we do\n * is \"clock\" any remaining data into the receiver.\n *\n * @this {SerialPort}\n * @param {number|string|Array} [data]\n * @return {boolean} true if received, false if not\n */\n receiveData(data)\n {\n if (data != null) {\n if (typeof data == \"number\") {\n this.abReceive.push(data);\n }\n else if (typeof data == \"string\") {\n for (var i = 0; i < data.length; i++) {\n this.abReceive.push(data.charCodeAt(i));\n }\n }\n else {\n this.abReceive = this.abReceive.concat(data);\n }\n }\n this.advanceRBR();\n return true; // for now, return true regardless, since we're buffering everything anyway\n }\n\n /**\n * receiveStatus(pins)\n *\n * NOTE: Prior to the addition of this interface, the CTS and DSR bits were initialized set and remained set\n * for the life of the machine. It is entirely appropriate that this is the only way those bits can be changed,\n * because they represent external control signals.\n *\n * @this {SerialPort}\n * @param {number} pins\n */\n receiveStatus(pins)\n {\n var bMSROld = this.bMSR;\n this.bMSR &= ~(SerialPort.MSR.CTS | SerialPort.MSR.DSR);\n if (pins & RS232.CTS.MASK) {\n this.bMSR |= SerialPort.MSR.CTS | SerialPort.MSR.DCTS;\n }\n if (pins & RS232.DSR.MASK) {\n this.bMSR |= SerialPort.MSR.DSR | SerialPort.MSR.DDSR;\n }\n if (bMSROld != this.bMSR) this.updateIIR();\n }\n\n /**\n * advanceRBR()\n *\n * @this {SerialPort}\n */\n advanceRBR()\n {\n if (this.abReceive.length > 0 && !(this.bLSR & SerialPort.LSR.DR)) {\n if (!this.fAutoFlow || (this.bMCR & SerialPort.MCR.RTS)) {\n this.bRBR = this.abReceive.shift();\n this.bLSR |= SerialPort.LSR.DR;\n if (this.abReceive.length && this.cpu) {\n this.cpu.setTimer(this.timerReceiveNext, this.getBaudTimeout());\n }\n }\n }\n this.updateIIR();\n }\n\n /**\n * inRBR(port, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3F8 or 0x2F8)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inRBR(port, addrFrom)\n {\n var b = ((this.bLCR & SerialPort.LCR.DLAB) ? (this.wDL & 0xff) : this.bRBR);\n this.printMessageIO(port, null, addrFrom, (this.bLCR & SerialPort.LCR.DLAB) ? \"DLL\" : \"RBR\", b);\n this.bLSR &= ~SerialPort.LSR.DR;\n this.advanceRBR();\n return b;\n }\n\n /**\n * inIER(port, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3F9 or 0x2F9)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inIER(port, addrFrom)\n {\n var b = ((this.bLCR & SerialPort.LCR.DLAB) ? (this.wDL >> 8) : this.bIER);\n this.printMessageIO(port, null, addrFrom, (this.bLCR & SerialPort.LCR.DLAB) ? \"DLM\" : \"IER\", b);\n return b;\n }\n\n /**\n * inIIR(port, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3FA or 0x2FA)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inIIR(port, addrFrom)\n {\n var b = this.bIIR;\n /*\n * Reading the IIR is supposed to clear the INT_THR condition (as is another write to the THR).\n */\n if (b == SerialPort.IIR.INT_THR) {\n this.bIIR = SerialPort.IIR.NO_INT;\n }\n this.printMessageIO(port, null, addrFrom, \"IIR\", b);\n return b;\n }\n\n /**\n * inLCR(port, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3FB or 0x2FB)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inLCR(port, addrFrom)\n {\n var b = this.bLCR;\n this.printMessageIO(port, null, addrFrom, \"LCR\", b);\n return b;\n }\n\n /**\n * inMCR(port, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3FC or 0x2FC)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inMCR(port, addrFrom)\n {\n var b = this.bMCR;\n this.printMessageIO(port, null, addrFrom, \"MCR\", b);\n return b;\n }\n\n /**\n * inLSR(port, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3FD or 0x2FD)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inLSR(port, addrFrom)\n {\n var b = this.bLSR;\n this.printMessageIO(port, null, addrFrom, \"LSR\", b);\n return b;\n }\n\n /**\n * inMSR(port, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3FE or 0x2FE)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inMSR(port, addrFrom)\n {\n var b = this.bMSR;\n this.bMSR &= ~(SerialPort.MSR.DCTS | SerialPort.MSR.DDSR);\n this.printMessageIO(port, null, addrFrom, \"MSR\", b);\n return b;\n }\n\n /**\n * outTHR(port, bOut, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3F8 or 0x2F8)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outTHR(port, bOut, addrFrom)\n {\n var serial = this;\n this.printMessageIO(port, bOut, addrFrom, (this.bLCR & SerialPort.LCR.DLAB) ? \"DLL\" : \"THR\");\n if (this.bLCR & SerialPort.LCR.DLAB) {\n this.wDL = (this.wDL & ~0xff) | bOut;\n } else {\n this.bTHR = bOut;\n this.bLSR &= ~(SerialPort.LSR.THRE | SerialPort.LSR.TSRE);\n /*\n * If transmitByte() returned success, we used to immediately re-set the transmitter empty bits:\n *\n * this.bLSR |= (SerialPort.LSR.THRE | SerialPort.LSR.TSRE);\n *\n * But when we're connected to a virtual device that has no measurable delay, that sets the bits\n * too quickly. We now arm a timer based on the programmed baud rate, and set the above bits only\n * when that timer fires.\n *\n * Additionally, we no longer care if transmitByte() succeeds, because whether or not a connected\n * device or component received the data is irrelevant to the internal mechanics of the serial port.\n *\n * TODO: Determine if we should also flush/zero bTHR after transmission.\n */\n this.cpu.nonCPU(function() {\n return serial.transmitByte(bOut);\n });\n this.cpu.setTimer(this.timerTransmitNext, this.getBaudTimeout());\n this.updateIIR();\n }\n }\n\n /**\n * outIER(port, bOut, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3F9 or 0x2F9)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outIER(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, (this.bLCR & SerialPort.LCR.DLAB) ? \"DLM\" : \"IER\");\n if (this.bLCR & SerialPort.LCR.DLAB) {\n this.wDL = (this.wDL & 0xff) | (bOut << 8);\n } else {\n this.bIER = bOut;\n }\n }\n\n /**\n * outLCR(port, bOut, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3FB or 0x2FB)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outLCR(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"LCR\");\n this.bLCR = bOut;\n }\n\n /**\n * outMCR(port, bOut, addrFrom)\n *\n * @this {SerialPort}\n * @param {number} port (eg, 0x3FC or 0x2FC)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outMCR(port, bOut, addrFrom)\n {\n var delta = (bOut ^ this.bMCR);\n this.printMessageIO(port, bOut, addrFrom, \"MCR\");\n this.bMCR = bOut;\n /*\n * Whenever DTR or RTS changes, we also need to notify any connected machine or mouse, via updateStatus().\n */\n if (delta & (SerialPort.MCR.DTR | SerialPort.MCR.RTS)) {\n if (this.updateStatus) {\n var pins = 0;\n if (this.fNullModem) {\n pins |= (bOut & SerialPort.MCR.RTS)? RS232.CTS.MASK : 0;\n pins |= (bOut & SerialPort.MCR.DTR)? (RS232.DSR.MASK | RS232.CD.MASK): 0;\n } else {\n pins |= (bOut & SerialPort.MCR.RTS)? RS232.RTS.MASK : 0;\n pins |= (bOut & SerialPort.MCR.DTR)? RS232.DTR.MASK : 0;\n }\n this.updateStatus.call(this.connection, pins);\n }\n /*\n * Throw in a call to advanceRBR() for good measure, in case fAutoFlow is set and RTS was just enabled.\n */\n this.advanceRBR();\n }\n }\n\n /**\n * updateIIR()\n *\n * @this {SerialPort}\n */\n updateIIR()\n {\n var bIIR = -1;\n /*\n * We check all the interrupt conditions in priority order. TODO: Add INT_LSR.\n */\n if ((this.bLSR & SerialPort.LSR.DR) && (this.bIER & SerialPort.IER.RBR_AVAIL)) {\n bIIR = SerialPort.IIR.INT_RBR;\n }\n else if ((this.bLSR & SerialPort.LSR.THRE) && (this.bIER & SerialPort.IER.THR_EMPTY)) {\n bIIR = SerialPort.IIR.INT_THR;\n }\n else if ((this.bMSR & (SerialPort.MSR.DCTS | SerialPort.MSR.DDSR)) && (this.bIER & SerialPort.IER.MSR_DELTA)) {\n bIIR = SerialPort.IIR.INT_MSR;\n }\n if (bIIR >= 0) {\n this.bIIR &= ~(SerialPort.IIR.NO_INT | SerialPort.IIR.INT_BITS);\n this.bIIR |= bIIR;\n /*\n * I still throttle SerialPort interrupts by passing a hard-coded delay of 100 instructions to setIRR(),\n * even though we are now (theoretically) honoring the programmed baud rate. The setIRR() delay does not\n * ensure any particular baud rate, it simply gives the underlying Interrupt Service Routine (ISR) some\n * breathing room.\n *\n * The Microsoft Windows 1.01 serial mouse driver ISR issues an EOI before it has safely exited, presumably\n * relying on the fact that a 1200 baud serial device would not normally interrupt frequently enough to\n * blow the stack. However, in PCx86, all you have to do is remove the delay below and enable Debugger\n * messages on every serial interrupt and mouse event, eg:\n *\n * m serial on;m pic on;m mouse on\n *\n * to slow the machine down to the point where serial mouse interrupts overwhelm the ISR. The Debugger\n * messages display the current stack pointer, which you can watch drop to zero and then wrap around, no\n * doubt trampling lots of code and data along the way.\n *\n * This problem could also occur without being forced by the Debugger; eg, if your physical machine's mouse\n * was configured for a high interrupt rate, and your browser generated mouse events at a comparable rate.\n */\n if (this.chipset && this.nIRQ) this.chipset.setIRR(this.nIRQ, 100);\n } else {\n this.bIIR = SerialPort.IIR.NO_INT;\n if (this.chipset && this.nIRQ) this.chipset.clearIRR(this.nIRQ);\n }\n }\n\n /**\n * transmitByte(b)\n *\n * @this {SerialPort}\n * @param {number} b\n * @return {boolean} true if transmitted, false if not\n */\n transmitByte(b)\n {\n var fTransmitted = false;\n\n this.printMessage(\"transmitByte(\" + Str.toHexByte(b) + \")\");\n\n if (this.sendData) {\n if (this.sendData.call(this.connection, b)) {\n fTransmitted = true;\n }\n }\n\n if (this.controlBuffer) {\n if (b == 0x0D) {\n this.iLogicalCol = 0;\n }\n else if (b == 0x08) {\n this.controlBuffer.value = this.controlBuffer.value.slice(0, -1);\n /*\n * TODO: Back up the correct number of columns if the character erased was a tab.\n */\n if (this.iLogicalCol > 0) this.iLogicalCol--;\n }\n else {\n var s = Str.toASCIICode(b); // formerly: String.fromCharCode(b);\n var nChars = s.length; // formerly: (b >= 0x20? 1 : 0);\n if (b < 0x20 && nChars == 1) nChars = 0;\n if (b == 0x09) {\n var tabSize = this.tabSize || 8;\n nChars = tabSize - (this.iLogicalCol % tabSize);\n if (this.tabSize) s = Str.pad(\"\", nChars);\n }\n if (!this.iLogicalCol && nChars) {\n /*\n * When BASIC.COM outputs a listing to a serial port, it ends every line with a CR (0x0D)\n * but no LF (0x0A), which seems a bit odd. We fix that here.\n */\n if (this.charPrev != 0x0A) s = \"\\n\" + s;\n if (this.charBOL) s = String.fromCharCode(this.charBOL) + s;\n }\n this.controlBuffer.value += s;\n this.controlBuffer.scrollTop = this.controlBuffer.scrollHeight;\n this.iLogicalCol += nChars;\n }\n this.charPrev = b;\n fTransmitted = true;\n }\n else if (this.consoleBuffer != null) {\n if (b == 0x0A || this.consoleBuffer.length >= 1024) {\n this.println(this.consoleBuffer);\n this.consoleBuffer = \"\";\n }\n if (b != 0x0A) {\n this.consoleBuffer += String.fromCharCode(b);\n }\n fTransmitted = true;\n }\n\n return fTransmitted;\n }\n\n /**\n * transmitData()\n *\n * Helper for clocking transmitted data at the expected baud rate.\n *\n * @this {SerialPort}\n */\n transmitData()\n {\n this.bLSR |= (SerialPort.LSR.THRE | SerialPort.LSR.TSRE);\n this.updateIIR();\n }\n\n /**\n * SerialPort.init()\n *\n * This function operates on every HTML element of class \"serial\", extracting the\n * JSON-encoded parameters for the SerialPort constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a SerialPort component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeSerial = Component.getElementsByClass(document, PCX86.APPCLASS, \"serial\");\n for (var iSerial = 0; iSerial < aeSerial.length; iSerial++) {\n var eSerial = aeSerial[iSerial];\n var parms = Component.getComponentParms(eSerial);\n var serial = new SerialPort(parms);\n Component.bindComponentControls(serial, eSerial, PCX86.APPCLASS);\n }\n }\n}\n\n/*\n * 8250 I/O register offsets (add these to a I/O base address to obtain an I/O port address)\n *\n * NOTE: DLL.REG and DLM.REG form a 16-bit divisor into a clock input frequency of 1.8432Mhz. The following\n * values should be used for the corresponding baud rates. Rates above 9600 are discouraged by the IBM Tech Ref,\n * but rates as high as 128000 are listed on the NS8250A data sheet.\n *\n * Divisor Rate Percent Error\n * 0x0900 50\n * 0x0600 75\n * 0x0417 110 0.026%\n * 0x0359 134.5 0.058%\n * 0x0300 150\n * 0x0180 300\n * 0x00C0 600\n * 0x0060 1200\n * 0x0040 1800\n * 0x003A 2000 0.69%\n * 0x0030 2400\n * 0x0020 3600\n * 0x0018 4800\n * 0x0010 7200\n * 0x000C 9600\n * 0x0006 19200\n * 0x0003 38400\n * 0x0002 56000 2.86%\n * 0x0001 128000\n */\nSerialPort.DLL = {REG: 0}; // Divisor Latch LSB (only when SerialPort.LCR.DLAB is set)\nSerialPort.THR = {REG: 0}; // Transmitter Holding Register (write)\nSerialPort.DL_DEFAULT = 0x180; // we select an arbitrary default Divisor Latch equivalent to 300 baud\n\n/*\n * Receiver Buffer Register (RBR.REG, offset 0; eg, 0x3F8 or 0x2F8) on read, Transmitter Holding Register on write\n */\nSerialPort.RBR = {REG: 0}; // (read)\n\n/*\n * Interrupt Enable Register (IER.REG, offset 1; eg, 0x3F9 or 0x2F9)\n */\nSerialPort.IER = {\n REG: 1, // Interrupt Enable Register\n RBR_AVAIL: 0x01,\n THR_EMPTY: 0x02,\n LSR_DELTA: 0x04,\n MSR_DELTA: 0x08,\n UNUSED: 0xF0 // always zero\n};\n\nSerialPort.DLM = {REG: 1}; // Divisor Latch MSB (only when SerialPort.LCR.DLAB is set)\n\n/*\n * Interrupt ID Register (IIR.REG, offset 2; eg, 0x3FA or 0x2FA)\n *\n * All interrupt conditions cleared by reading the corresponding register (or, in the case of IIR.INT_THR, writing a new value to THR.REG)\n */\nSerialPort.IIR = {\n REG: 2, // Interrupt ID Register (read-only)\n NO_INT: 0x01,\n INT_LSR: 0x06, // Line Status (highest priority: Overrun error, Parity error, Framing error, or Break Interrupt)\n INT_RBR: 0x04, // Receiver Data Available\n INT_THR: 0x02, // Transmitter Holding Register Empty\n INT_MSR: 0x00, // Modem Status Register (lowest priority: Clear To Send, Data Set Ready, Ring Indicator, or Data Carrier Detect)\n INT_BITS: 0x06,\n UNUSED: 0xF8 // always zero (the ROM BIOS relies on these bits \"floating to 1\" when no SerialPort is present)\n};\n\n/*\n * Line Control Register (LCR.REG, offset 3; eg, 0x3FB or 0x2FB)\n */\nSerialPort.LCR = {\n REG: 3, // Line Control Register\n DATA_5BITS: 0x00,\n DATA_6BITS: 0x01,\n DATA_7BITS: 0x02,\n DATA_8BITS: 0x03,\n STOP_BITS: 0x04, // clear: 1 stop bit; set: 1.5 stop bits for LCR_DATA_5BITS, 2 stop bits for all other data lengths\n PARITY_BIT: 0x08, // if set, a parity bit is inserted/expected between the last data bit and the first stop bit; no parity bit if clear\n PARITY_EVEN: 0x10, // if set, even parity is selected (ie, the parity bit insures an even number of set bits); if clear, odd parity\n PARITY_STICK: 0x20, // if set, parity bit is transmitted inverted; if clear, parity bit is transmitted normally\n BREAK: 0x40, // if set, serial output (SOUT) signal is forced to logical 0 for the duration\n DLAB: 0x80 // Divisor Latch Access Bit; if set, DLL.REG and DLM.REG can be read or written\n};\n\n/*\n * Modem Control Register (MCR.REG, offset 4; eg, 0x3FC or 0x2FC)\n */\nSerialPort.MCR = {\n REG: 4, // Modem Control Register\n DTR: 0x01, // when set, DTR goes high, indicating ready to establish link (looped back to DSR in loop-back mode)\n RTS: 0x02, // when set, RTS goes high, indicating ready to exchange data (looped back to CTS in loop-back mode)\n OUT1: 0x04, // when set, OUT1 goes high (looped back to RI in loop-back mode)\n OUT2: 0x08, // when set, OUT2 goes high (looped back to RLSD in loop-back mode); must also be set for most UARTs to enable interrupts (but not ours)\n LOOPBACK: 0x10, // when set, enables loop-back mode\n UNUSED: 0xE0 // always zero\n};\n\n/*\n * Line Status Register (LSR.REG, offset 5; eg, 0x3FD or 0x2FD)\n *\n * NOTE: I've seen different specs for the LSR_TSRE. I'm following the IBM Tech Ref's lead here, but the data sheet\n * I have calls it TEMT instead of TSRE, and claims that it is set whenever BOTH the THR and TSR are empty, and clear\n * whenever EITHER the THR or TSR contain data.\n */\nSerialPort.LSR = {\n REG: 5, // Line Status Register\n DR: 0x01, // Data Ready (set when new data in RBR.REG; cleared when RBR.REG read)\n OE: 0x02, // Overrun Error (set when new data arrives in RBR.REG before previous data read; cleared when LSR.REG read)\n PE: 0x04, // Parity Error (set when new data has incorrect parity; cleared when LSR.REG read)\n FE: 0x08, // Framing Error (set when new data has invalid stop bit; cleared when LSR.REG read)\n BI: 0x10, // Break Interrupt (set when new data exceeded normal transmission time; cleared LSR.REG when read)\n THRE: 0x20, // Transmitter Holding Register Empty (set when UART ready to accept new data; cleared when THR.REG written)\n TSRE: 0x40, // Transmitter Shift Register Empty (set when the TSR is empty; cleared when the THR is transferred to the TSR)\n UNUSED: 0x80 // always zero\n};\n\n/*\n * Modem Status Register (MSR.REG, offset 6; eg, 0x3FE or 0x2FE)\n */\nSerialPort.MSR = {\n REG: 6, // Modem Status Register\n DCTS: 0x01, // when set, CTS (Clear To Send) has changed since last read\n DDSR: 0x02, // when set, DSR (Data Set Ready) has changed since last read\n TERI: 0x04, // when set, TERI (Trailing Edge Ring Indicator) indicates RI has changed from 1 to 0\n DRLSD: 0x08, // when set, RLSD (Received Line Signal Detector) has changed\n CTS: 0x10, // when set, the modem or data set is ready to exchange data (complement of the Clear To Send input signal)\n DSR: 0x20, // when set, the modem or data set is ready to establish link (complement of the Data Set Ready input signal)\n RI: 0x40, // complement of the RI (Ring Indicator) input\n RLSD: 0x80 // complement of the RLSD (Received Line Signal Detect) input\n};\n\n/*\n * Scratch Register (SCR.REG, offset 7; eg, 0x3FF or 0x2FF)\n */\nSerialPort.SCR = {REG: 7};\n\n/*\n * Port input notification table\n */\nSerialPort.aPortInput = {\n 0x0: SerialPort.prototype.inRBR, // or DLL if DLAB set\n 0x1: SerialPort.prototype.inIER, // or DLM if DLAB set\n 0x2: SerialPort.prototype.inIIR,\n 0x3: SerialPort.prototype.inLCR,\n 0x4: SerialPort.prototype.inMCR,\n 0x5: SerialPort.prototype.inLSR,\n 0x6: SerialPort.prototype.inMSR\n};\n\n/*\n * Port output notification table\n */\nSerialPort.aPortOutput = {\n 0x0: SerialPort.prototype.outTHR, // or DLL if DLAB set\n 0x1: SerialPort.prototype.outIER, // or DLM if DLAB set\n 0x3: SerialPort.prototype.outLCR,\n 0x4: SerialPort.prototype.outMCR\n};\n\n/*\n * Initialize every SerialPort module on the page.\n */\nWeb.onInit(SerialPort.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/testctl.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * This module provides connectivity between the TestMonitor component and whichever PCx86 SerialPort\n * our 'binding' property indicates, if any.\n */\n\n\n/**\n * TestController class\n *\n * @class TestController\n * @property {string|undefined urlTests\n * @property {Object|null} tests\n * @property {string|null} consoleBuffer\n * @property {HTMLTextAreaElement|null} controlBuffer\n * @property {function(...)|null} sendData\n * @property {function(number)|null} deliverData\n * @property {function(number)|null} deliverInput\n * @property {function(Object)|null} deliverTests\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass TestController extends Component {\n /**\n * TestController(parms)\n *\n * @this {TestController}\n * @param {Object} parms\n */\n constructor(parms)\n {\n super(\"TestController\", parms);\n\n this.tests = null;\n let fLoading = false;\n this.urlTests = parms['tests'];\n \n this.consoleBuffer = \"\";\n this.controlBuffer = null;\n this.sendData = null;\n this.deliverData = this.deliverInput = this.deliverTests = null;\n \n this.sBinding = parms['binding'];\n if (this.sBinding) {\n this.serialPort = Component.getComponentByID(this.sBinding, this.id);\n if (this.serialPort) {\n let exports = this.serialPort['exports'];\n if (exports) {\n let bind = /** @function */ (exports['bind']);\n if (bind && bind.call(this.serialPort, this, this.receiveData, true)) {\n this.sendData = exports['receiveData'].bind(this.serialPort);\n if (this.urlTests) {\n this.loadTests(this.urlTests);\n fLoading = true;\n }\n }\n }\n }\n if (!this.sendData) {\n Component.warning(this.id + \": binding '\" + this.sBinding + \"' unavailable\");\n }\n }\n if (!fLoading) this.setReady();\n }\n\n /**\n * loadTests(sURL)\n *\n * @this {TestController}\n * @param {string} sURL\n */\n loadTests(sURL)\n {\n let controller = this;\n let sProgress = \"Loading \" + sURL + \"...\";\n Web.getResource(sURL, null, true, function(sURL, sResponse, nErrorCode) {\n controller.doneLoad(sURL, sResponse, nErrorCode);\n }, function(nState) {\n controller.println(sProgress, Component.PRINT.PROGRESS);\n });\n \n }\n \n /**\n * doneLoad(sURL, sTestData, nErrorCode)\n *\n * @this {TestController}\n * @param {string} sURL\n * @param {string} sTestData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n doneLoad(sURL, sTestData, nErrorCode)\n {\n if (nErrorCode) {\n this.notice(\"Unable to load tests (error \" + nErrorCode + \": \" + sURL + \")\", nErrorCode < 0);\n }\n else {\n try {\n this.tests = /** @type {Object} */ (JSON.parse(sTestData));\n if (this.deliverTests) {\n this.deliverTests(this.tests);\n this.tests = null;\n }\n Component.addMachineResource(this.idMachine, sURL, sTestData);\n } catch (err) {\n this.notice(\"Test parsing error: \" + err.message);\n }\n }\n this.setReady();\n }\n\n /**\n * bindMonitor(monitor, deliverData, deliverInput, deliverTests)\n *\n * @this {TestController}\n * @param {TestMonitor} monitor\n * @param {function(number)} deliverData\n * @param {function(number)} deliverInput\n * @param {function(Object)} deliverTests\n */\n bindMonitor(monitor, deliverData, deliverInput, deliverTests)\n {\n this.deliverData = deliverData.bind(monitor);\n this.deliverInput = deliverInput.bind(monitor);\n this.deliverTests = deliverTests.bind(monitor);\n if (this.tests && this.deliverTests) {\n this.deliverTests(this.tests);\n this.tests = null;\n }\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {TestController}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"buffer\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n let controller = this;\n\n if (sHTMLType == \"textarea\" && !this.controlBuffer) {\n\n this.bindings[sBinding] = control;\n this.controlBuffer = /** @type {HTMLTextAreaElement} */ (control);\n this.consoleBuffer = null; // we currently use one or the other: control or console\n\n /*\n * By establishing an onkeypress handler here, we make it possible for DOS commands like\n * \"CTTY COM1\" to more or less work (use \"CTTY CON\" to restore control to the DOS console).\n */\n control.onkeydown = function onKeyDown(event) {\n /*\n * This is required in addition to onkeypress, because it's the only way to prevent\n * BACKSPACE (keyCode 8) from being interpreted by the browser as a \"Back\" operation;\n * moreover, not all browsers generate an onkeypress notification for BACKSPACE.\n *\n * A related problem exists for Ctrl-key combinations in most Windows-based browsers\n * (eg, IE, Edge, Chrome for Windows, etc), because keys like Ctrl-C and Ctrl-S have\n * special meanings (eg, Copy, Save). To the extent the browser will allow it, we\n * attempt to disable that default behavior when this control receives an onkeydown\n * event for one of those keys (probably the only event the browser generates for them).\n */\n event = event || window.event;\n let keyCode = event.keyCode;\n if (keyCode === 0x08 || event.ctrlKey && keyCode >= 0x41 && keyCode <= 0x5A) {\n if (event.preventDefault) event.preventDefault();\n if (keyCode > 0x40) keyCode -= 0x40;\n if (controller.deliverInput) controller.deliverInput(keyCode);\n }\n return true;\n };\n\n control.onkeypress = function onKeyPress(event) {\n /*\n * Browser-independent keyCode extraction; refer to onKeyPress() and the other key event\n * handlers in keyboard.js.\n */\n event = event || window.event;\n let keyCode = event.which || event.keyCode;\n if (controller.deliverInput) controller.deliverInput(keyCode);\n /*\n * Since we're going to remove the \"readonly\" attribute from the <textarea> control\n * (so that the soft keyboard activates on iOS), instead of calling preventDefault() for\n * selected keys (eg, the SPACE key, whose default behavior is to scroll the page), we must\n * now call it for *all* keys, so that the keyCode isn't added to the control immediately,\n * on top of whatever the machine is echoing back, resulting in double characters.\n */\n if (event.preventDefault) event.preventDefault();\n return true;\n };\n\n /*\n * Now that we've added an onkeypress handler that calls preventDefault() for ALL keys, the control\n * itself no longer needs the \"readonly\" attribute; we primarily need to remove it for iOS browsers,\n * so that the soft keyboard will activate, but it shouldn't hurt to remove the attribute for all browsers.\n */\n control.removeAttribute(\"readonly\");\n\n if (this.sendData) {\n let monitor = new TestMonitor();\n monitor.bindController(this, this.sendData, this.sendOutput, this.printf, this.sBinding);\n }\n return true;\n }\n return false;\n }\n\n /**\n * sendOutput(data)\n *\n * @this {TestController}\n * @param {number|string|Array} data\n */\n sendOutput(data)\n {\n if (typeof data == \"number\") {\n this.printf(\"%c\", data);\n }\n else if (typeof data == \"string\") {\n this.printf(\"%s\", data);\n }\n else {\n for (let i = 0; i < data.length; i++) this.printf(\"[0x%02x]\", data[i]);\n }\n }\n\n /**\n * printf(format, ...args)\n *\n * @this {TestController}\n * @param {string} format\n * @param {...} args\n */\n printf(format, ...args)\n {\n let s = Str.sprintf(format, ...args);\n \n if (this.controlBuffer != null) {\n if (s != '\\r') {\n if (s == '\\b' || s == \"\\b \\b\") {\n this.controlBuffer.value = this.controlBuffer.value.slice(0, -1);\n } else {\n this.controlBuffer.value += s;\n }\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (!DEBUG && this.controlBuffer.value.length > 8192) {\n this.controlBuffer.value = this.controlBuffer.value.substr(this.controlBuffer.value.length - 4096);\n }\n this.controlBuffer.scrollTop = this.controlBuffer.scrollHeight;\n }\n }\n \n if (this.consoleBuffer != null) {\n let i = s.lastIndexOf('\\n');\n if (i >= 0) {\n console.log(this.consoleBuffer + s.substr(0, i));\n this.consoleBuffer = \"\";\n s = s.substr(i + 1);\n }\n this.consoleBuffer += s;\n }\n }\n\n /**\n * receiveData(data)\n *\n * @this {TestController}\n * @param {number|string|Array} data\n */\n receiveData(data)\n {\n if (typeof data == \"number\") {\n this.deliverData(data);\n }\n else if (typeof data == \"string\") {\n for (let i = 0; i < data.length; i++) this.deliverData(data.charCodeAt(i));\n }\n else {\n for (let i = 0; i < data.length; i++) this.deliverData(data[i]);\n }\n }\n \n /**\n * TestController.init()\n *\n * This function operates on every HTML element of class \"TestController\", extracting the\n * JSON-encoded parameters for the TestController constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a TestController component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n let aeTest = Component.getElementsByClass(document, PCX86.APPCLASS, \"testctl\");\n for (let iTest = 0; iTest < aeTest.length; iTest++) {\n let eTest = aeTest[iTest];\n let parms = Component.getComponentParms(eTest);\n let test = new TestController(parms);\n Component.bindComponentControls(test, eTest, PCX86.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize every TestController module on the page.\n */\nWeb.onInit(TestController.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/testmon.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Overview\n * --------\n * \n * TestMonitor monitors activity on the bound SerialPort and a user I/O device (eg, a terminal,\n * a console window, etc). It operates in several modes:\n * \n * 1) TERMINAL mode: all data received from the SerialPort is routed the user output device,\n * and all data received from the user input device is routed to the SerialPort. No special actions\n * are taken, until/unless the ATTENTION key is detected from the user input device (ie, Ctrl-T).\n * \n * 2) PROMPT mode: data from the SerialPort is monitored for specific prompts (eg, \"A>\"), and\n * when one of those prompts is detected, we enter COMMAND mode, with category set to the appropriate\n * collection of tests.\n * \n * 3) COMMAND mode: CR-terminated lines of user input are checked against the current set of test\n * commands, and if a match is found, the corresponding request is sent to the SerialPort.\n */\n\n\n/**\n * TestMonitor class\n *\n * @class TestMonitor\n * @property {string} mode\n * @property {string} promptActive\n * @property {string} promptBuffer\n * @property {Object|undefined} tests\n * @property {Object|undefined} category (eg, \"DOS\")\n * @property {string} commandBuffer\n * @property {function(...)} sendData\n * @property {function(...)} sendOutput\n * @property {function(string,...)} printf\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass TestMonitor {\n /**\n * TestMonitor()\n *\n * @this {TestMonitor}\n */\n constructor()\n {\n if (DEBUG) console.log(\"TestMonitor()\");\n /*\n * Operations are added to the following queue by addOperation(), which ensures that as soon as it\n * transitions from empty to non-empty, a timeout handler is established to begin draining the queue.\n * \n * While this approach is more complicated than simply sending operations (via sendData()) as they\n * arrive, it has at least one important advantage: special operations, such as \"wait\" (eg, wait for a\n * key to be pressed), are easier to implement, because control of the draining process can be switched\n * from a timeout handler to an appropriate event handler.\n */\n this.aOperations = [];\n this.idTimeout = 0;\n this.fnRemoveOperation = this.removeOperation.bind(this);\n this.fWaitPending = false;\n }\n\n /**\n * bindController(controller, sendData, sendOutput, printf, sBinding)\n *\n * @this {TestMonitor}\n * @param {Object} controller\n * @param {function(...)} sendData\n * @param {function(...)} sendOutput\n * @param {function(string,...)} printf\n * @param {string} [sBinding]\n */\n bindController(controller, sendData, sendOutput, printf, sBinding)\n {\n this.sendData = sendData.bind(controller);\n this.sendOutput = sendOutput.bind(controller);\n this.printf = printf.bind(controller);\n controller.bindMonitor(this, this.receiveData, this.receiveInput, this.receiveTests);\n this.printf(\"%s TestMonitor v%s\\n\", APPNAME, APPVERSION || XMLVERSION);\n this.printf(\"Use Ctrl-T to toggle terminal mode%s\\n\", (sBinding? \" (\" + sBinding.toUpperCase() + \")\" : \"\"));\n this.setMode(TestMonitor.MODE.TERMINAL);\n }\n\n /**\n * addCommand(commandLine)\n *\n * @this {TestMonitor}\n * @param {string} commandLine\n * @return {boolean} (true if successful, false if error)\n */\n addCommand(commandLine)\n {\n if (!commandLine) return true;\n \n let suite = this.tests[this.category];\n let commands = suite['commands'];\n let commandParts = commandLine.split(' ');\n let command = commandParts[0];\n \n /*\n * Check for a matching command in the current \"test suite\" category.\n */\n let fExists = false;\n if (commands[command]) {\n fExists = true;\n command = commands[command];\n }\n \n let op, mode;\n if (typeof command == \"string\") {\n op = command;\n /*\n * If you don't want any special op processing (eg, for-loop), then use an explicit 'op' property.\n */\n if (this.addForLoop(op)) return true;\n } else {\n op = command['op'];\n mode = command['mode'];\n }\n \n if (op) {\n let errorMessage = \"\";\n op = op.replace(/([$%])([0-9]+)/g, function(match, p1, p2, offset, s) {\n let i = +p2;\n let result = \"\";\n if (i >= commandParts.length) {\n result = p1 + p2;\n errorMessage = \"missing value for \" + result;\n } else if (!i) {\n result = commandLine;\n } else if (p1 == '$') {\n result = commandParts[i];\n } else { // p1 must be '%', which means convert the value to hex\n result = Str.sprintf(\"%x\", commandParts[i]);\n }\n return result;\n });\n if (errorMessage) {\n this.printf(\"%s\\n\", errorMessage);\n } else {\n let i = op.indexOf('(');\n command = (i > 0? op.substr(0, i) : \"\");\n if (TestMonitor.COMMANDS.indexOf(command) >= 0) {\n if (!fExists) op = commandLine;\n fExists = true;\n let j = op.lastIndexOf(')');\n if (j > 0) {\n mode = op.substr(i+1, j-i-1);\n op = command;\n }\n }\n else if (TestMonitor.COMMANDS.indexOf(op) >= 0) {\n fExists = true;\n mode = commandParts[1];\n }\n if (fExists) {\n if (DEBUG) console.log(\"TestMonitor.addCommand(\" + commandLine + \"): op '\" + op + \"'\");\n this.addOperation(op, mode);\n return true;\n }\n this.printf(\"unrecognized command: %s\\n\", commandLine);\n }\n } else {\n this.printf(\"missing operation for command: %s\\n\", commandParts[0]);\n }\n return false;\n }\n\n /**\n * addForLoop(commandLine)\n * \n * @this {TestMonitor}\n * @param {string} commandLine\n * @return {boolean}\n */\n addForLoop(commandLine)\n {\n let fSuccess = false;\n let match = commandLine.match(/^\\s*for\\s+([a-z]+)\\s*=\\s*([0-9]+)\\s+to\\s+([0-9]+)\\s*{\\s*([\\s\\S]*?)\\s*}\\s*$/i);\n if (match) {\n fSuccess = true;\n let symbol = match[1];\n let initial = +match[2];\n let final = +match[3];\n let commands = match[4].split(';');\n for (let value = initial; value <= final && fSuccess; value++) {\n for (let i = 0; i < commands.length; i++) {\n let commandLine = commands[i].trim();\n if (!commandLine) continue;\n commandLine = commandLine.replace(new RegExp(\"\\\\$\" + symbol, 'g'), value.toString());\n if (!this.addCommand(commandLine)) {\n fSuccess = false;\n break;\n }\n }\n }\n }\n return fSuccess;\n }\n\n /**\n * addOperation(op, mode)\n * \n * @this {TestMonitor}\n * @param {string} op\n * @param {string} [mode]\n */\n addOperation(op, mode)\n {\n this.aOperations.push(mode? [op, mode] : op);\n this.nextOperation();\n }\n\n /**\n * flushOperations()\n *\n * @this {TestMonitor}\n */\n flushOperations()\n {\n if (this.idTimeout) {\n clearTimeout(this.idTimeout);\n this.idTimeout = 0;\n }\n this.aOperations = [];\n this.fWaitPending = false;\n }\n\n /**\n * nextOperation(msDelay)\n *\n * @this {TestMonitor}\n * @param {number} [msDelay]\n * @return {boolean}\n */\n nextOperation(msDelay)\n {\n this.fWaitPending = false;\n if (this.aOperations.length) {\n if (!this.idTimeout) {\n this.idTimeout = setTimeout(this.fnRemoveOperation, msDelay || 0);\n }\n return true;\n }\n this.printf(\"done\\n\");\n return false;\n }\n \n /**\n * removeOperation()\n *\n * @this {TestMonitor}\n */\n removeOperation()\n {\n this.idTimeout = 0;\n let op = this.aOperations.shift();\n if (op) {\n let mode;\n if (typeof op != \"string\") {\n mode = op[1]; op = op[0];\n }\n if (op == TestMonitor.COMMAND.PRINTF) {\n let format = \"nothing to print\", args = [];\n if (mode) {\n let parms = mode.match(/^\\s*([\"'])([\\s\\S]*?)\\1\\s*,?\\s*([\\s\\S]*)$/);\n if (parms) {\n format = parms[2];\n args = parms[3].split(',');\n }\n }\n this.printf(format, ...args);\n }\n else if (op == TestMonitor.COMMAND.WAIT) {\n if (mode) {\n this.nextOperation(+mode);\n return;\n }\n this.printf(\"press a key to continue...\");\n this.fWaitPending = true;\n return;\n }\n else {\n this.sendData(op);\n if (mode) {\n this.flushOperations();\n this.setMode(mode);\n return;\n }\n }\n this.nextOperation();\n }\n }\n \n /**\n * setMode(mode, category)\n * \n * @this {TestMonitor}\n * @param {string} mode\n * @param {string} [category]\n */\n setMode(mode, category)\n {\n if (mode != this.mode) {\n switch (mode) {\n case TestMonitor.MODE.TERMINAL:\n this.category = null;\n break;\n\n case TestMonitor.MODE.PROMPT:\n this.aCategories = [];\n this.aPrompts = [];\n this.cchPromptLongest = 0;\n for (let category in this.tests) {\n let suite = this.tests[category];\n let prompt = suite[TestMonitor.MODE.PROMPT];\n if (prompt) {\n /*\n * The 'prompt' property is allowed to contain a string or array of strings.\n */\n if (typeof prompt == \"string\") {\n prompt = [prompt];\n }\n for (let i = 0; i < prompt.length; i++) {\n this.aCategories.push(category);\n this.aPrompts.push(prompt[i]);\n if (this.cchPromptLongest < prompt[i].length) {\n this.cchPromptLongest = prompt[i].length;\n }\n }\n }\n }\n this.promptActive = this.promptBuffer = \"\";\n this.category = null;\n break;\n\n case TestMonitor.MODE.COMMAND:\n if (category) this.category = category;\n this.commandBuffer = \"\";\n break;\n\n default:\n this.printf(\"unrecognized mode: %s\\n\", mode);\n return;\n }\n\n this.mode = mode;\n this.printf(\"mode: %s\\n\", this.category || this.mode);\n }\n }\n \n /**\n * receiveTests(tests)\n *\n * @this {TestMonitor}\n * @param {Object} tests\n */\n receiveTests(tests)\n {\n if (DEBUG) console.log(\"TestMonitor.receiveTests(\" + JSON.stringify(tests) + \")\");\n this.tests = tests;\n this.setMode(TestMonitor.MODE.PROMPT);\n }\n\n /**\n * receiveData(data)\n *\n * @this {TestMonitor}\n * @param {number} data\n */\n receiveData(data)\n {\n if (this.mode == TestMonitor.MODE.PROMPT) {\n if (this.promptBuffer.length >= this.cchPromptLongest) {\n this.promptBuffer = this.promptBuffer.slice(-(this.cchPromptLongest - 1));\n }\n if (data == 10) this.promptBuffer = \"\";\n this.promptBuffer += String.fromCharCode(data);\n if (DEBUG) console.log(\"TestMonitor.receiveData(\" + data + \"): checking prompts for '\" + this.promptBuffer + \"'\");\n let i = this.aPrompts.indexOf(this.promptBuffer);\n if (i >= 0) {\n this.setMode(TestMonitor.MODE.COMMAND, this.aCategories[i]);\n }\n } else if (this.mode == TestMonitor.MODE.TERMINAL) {\n this.sendOutput(data);\n } else {\n /*\n * TODO: This is where we need to collect the response to any commands we have issued.\n */\n // this.sendOutput(data);\n if (DEBUG) console.log(\"TestMonitor.receiveData(\" + data + \"): ignored while mode is '\" + this.mode + \"'\");\n }\n }\n\n /**\n * receiveInput(charCode)\n *\n * @this {TestMonitor}\n * @param {number} charCode\n */\n receiveInput(charCode)\n {\n if (DEBUG) console.log(\"TestMonitor.receiveInput(\" + charCode + \")\");\n if (charCode == Keys.ASCII.CTRL_T) {\n this.setMode(this.mode == TestMonitor.MODE.TERMINAL? (this.category? TestMonitor.MODE.COMMAND : TestMonitor.MODE.PROMPT) : TestMonitor.MODE.TERMINAL);\n return;\n }\n if (this.mode == TestMonitor.MODE.TERMINAL || this.mode == TestMonitor.MODE.PROMPT) {\n this.sendData(charCode);\n } else if (this.mode == TestMonitor.MODE.COMMAND) {\n if (this.fWaitPending) {\n this.sendOutput(Keys.KEYCODE.LF);\n this.nextOperation();\n return;\n }\n if (charCode == Keys.KEYCODE.CR) {\n this.sendOutput(Keys.KEYCODE.LF);\n this.flushOperations();\n this.addCommand(this.commandBuffer.replace(/\\\\n/g, \"\\n\"));\n this.commandBuffer = \"\";\n } else {\n if (charCode == Keys.ASCII.CTRL_H || charCode == Keys.ASCII.DEL) {\n if (this.commandBuffer.length) {\n this.commandBuffer = this.commandBuffer.slice(0, -1);\n this.sendOutput(\"\\b \\b\");\n }\n } else if (charCode >= 32 && charCode < 127) {\n this.commandBuffer += String.fromCharCode(charCode);\n this.sendOutput(charCode);\n }\n }\n }\n }\n}\n\nTestMonitor.MODE = {\n TERMINAL: \"terminal\",\n PROMPT: \"prompt\",\n COMMAND: \"command\"\n};\n\nTestMonitor.COMMAND = {\n PRINTF: \"printf\",\n WAIT: \"wait\"\n};\n\nTestMonitor.COMMANDS = [\n TestMonitor.COMMAND.PRINTF,\n TestMonitor.COMMAND.WAIT\n];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/mouse.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * class Mouse\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass Mouse extends Component {\n /**\n * Mouse(parmsMouse)\n *\n * The Mouse component has the following component-specific (parmsMouse) properties:\n *\n * adapter: 1 (primary) or 2 (secondary); 0 if not defined\n *\n * binding: name of a corresponding device component (implies type=\"serial\")\n *\n * scaleMouse: a floating-point number used to scale incoming mouse coordinates; the default is 0.5\n *\n * serial: the ID of a corresponding serial component (used in lieu of type=\"serial\" and binding=\"ID\")\n *\n * type: one of \"bus\", \"inport\", or \"serial\"; the default is \"serial\" if serial or binding properties are set\n *\n * The first version of this component supported ONLY emulation of the original Microsoft serial mouse,\n * so a valid SerialPort component ID using the 'serial' property was required. Now, using the 'type' property,\n * it's possible to enable support for other types of mouse hardware (eg, 'bus' for the original Microsoft\n * Bus Mouse interface or 'inport' for the Microsoft InPort Mouse interface). The 'adapter' property is used\n * only when the selected type supports different configurations (eg, primary vs. secondary InPort adapters).\n *\n * If the 'type' property is set to \"serial\" (or 'type' is not set and either the original 'serial' property\n * or the new 'binding' property is set), then serial communication will be established with the specified\n * SerialPort component, requesting access to the corresponding serial component ID. If the SerialPort component\n * is not installed and/or the specified serial component ID is not present, a configuration error will be reported.\n *\n * To recap, the following machine XML syntax is still supported:\n *\n * <mouse serial=\"com2\"/>\n *\n * but going forward, you should stop using the serial attribute and use syntax like this instead:\n *\n * <mouse type=\"serial\" binding=\"com2\"/>\n *\n * @this {Mouse}\n * @param {Object} parmsMouse\n */\n constructor(parmsMouse)\n {\n super(\"Mouse\", parmsMouse, Messages.MOUSE);\n\n this.iAdapter = parmsMouse['adapter'] || 0;\n this.idDevice = parmsMouse['serial'] || parmsMouse['binding'];\n this.sType = parmsMouse['type'] || (this.idDevice? Mouse.TYPE.SERIAL : Mouse.TYPE.BUS);\n this.typeDevice = (this.sType == Mouse.TYPE.SERIAL? \"SerialPort\" : null);\n this.componentDevice = null;\n\n this.scale = parmsMouse['scaleMouse'];\n this.setActive(false);\n this.fActive = this.fCaptured = this.fLocked = false;\n\n /*\n * Initially, no video devices, and therefore no screens, are attached. initBus() will update aVideo,\n * and powerUp() will update aScreens.\n */\n this.aVideo = [];\n this.aScreens = [];\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {Mouse}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.scale = cmp.getMachineParm('scaleMouse') || this.scale;\n /*\n * Enumerate all the Video components that we may need to interact with.\n */\n for (var video = null; (video = cmp.getMachineComponent(\"Video\", video));) {\n this.aVideo.push(video);\n }\n if (this.sType == Mouse.TYPE.BUS) {\n bus.addPortInputTable(this, Mouse.aBusInput, Mouse.BUS.DATA.PORT);\n bus.addPortOutputTable(this, Mouse.aBusOutput, Mouse.BUS.DATA.PORT);\n }\n this.setReady();\n }\n\n /**\n * isActive()\n *\n * @this {Mouse}\n * @return {boolean} true if active, false if not\n */\n isActive()\n {\n return this.fActive && (this.cpu? this.cpu.isRunning() : false);\n }\n\n /**\n * setActive(fActive)\n *\n * @this {Mouse}\n * @param {boolean} fActive is true if active, false if not\n */\n setActive(fActive)\n {\n this.fActive = fActive;\n /*\n * It's currently not possible to automatically lock the pointer outside the context of a user action\n * (eg, a button or screen click), so this code is for naught.\n *\n * if (this.aVideo.length) this.aVideo[0].notifyPointerActive(fActive);\n *\n * We now rely on similar code in clickMouse().\n */\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {Mouse}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data || !this.restore) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n if (this.typeDevice && !this.componentDevice) {\n var componentDevice = null;\n while ((componentDevice = this.cmp.getMachineComponent(this.typeDevice, componentDevice))) {\n if (componentDevice.bindMouse) {\n this.componentDevice = componentDevice.bindMouse(this.idDevice, this, this.receiveStatus);\n if (this.componentDevice) {\n /*\n * It's possible that the SerialPort we've just attached to might want to bring us \"up to speed\"\n * on the device's state, which is why I envisioned a subsequent syncMouse() call. And you would\n * want to do that as a separate call, not as part of bindMouse(), because componentDevice\n * isn't set until bindMouse() returns.\n *\n * However, syncMouse() seems unnecessary, given that SerialPort initializes its MCR to an \"inactive\"\n * state, and even when restoring a previous state, if we've done our job properly, both SerialPort\n * and Mouse should be restored in sync, making any explicit attempt at sync'ing unnecessary (or so I hope).\n *\n * this.componentDevice.syncMouse();\n */\n break;\n }\n }\n }\n if (this.componentDevice) {\n this.aScreens = []; // ensure the screen array is empty before (re)filling it\n for (var i = 0; i < this.aVideo.length; i++) {\n var screen = this.aVideo[i].getScreen(this);\n if (screen) this.aScreens.push(screen);\n }\n } else {\n Component.warning(this.id + \": \" + this.typeDevice + \" \" + this.idDevice + \" unavailable\");\n }\n }\n if (this.fActive) {\n this.captureAll();\n } else {\n this.releaseAll();\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Mouse}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {Mouse}\n */\n reset()\n {\n this.initState();\n }\n\n /**\n * save()\n *\n * This implements save support for the Mouse component.\n *\n * @this {Mouse}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveState());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the Mouse component.\n *\n * @this {Mouse}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return this.initState(data[0]);\n }\n\n /**\n * initState(data)\n *\n * @this {Mouse}\n * @param {Array} [data]\n * @return {boolean} true if successful, false if failure\n */\n initState(data)\n {\n var i = 0;\n if (data === undefined) data = [false, -1, -1, 0, 0, false, false, 0];\n this.setActive(data[i++]);\n this.xMouse = data[i++];\n this.yMouse = data[i++];\n this.xDelta = data[i++];\n this.yDelta = data[i++];\n this.fButton1 = data[i++]; // FYI, we consider button1 to be the LEFT button\n this.fButton2 = data[i++]; // FYI, we consider button2 to be the RIGHT button\n this.pins = data[i];\n /*\n * Convert old UART \"MCR\" data to new RS-232 \"pins\" data, in case we're loading an old state;\n * detection and conversion relies on the fact that the MCR bits don't overlap with any RS-232 bits.\n */\n if (this.pins & (SerialPort.MCR.DTR | SerialPort.MCR.RTS)) {\n this.pins = ((this.pins & SerialPort.MCR.DTR)? RS232.DTR.MASK : 0) | ((this.pins & SerialPort.MCR.RTS)? RS232.RTS.MASK : 0);\n }\n return true;\n }\n\n /**\n * saveState()\n *\n * @this {Mouse}\n * @return {Array}\n */\n saveState()\n {\n var i = 0;\n var data = [];\n data[i++] = this.fActive;\n data[i++] = this.xMouse;\n data[i++] = this.yMouse;\n data[i++] = this.xDelta;\n data[i++] = this.yDelta;\n data[i++] = this.fButton1;\n data[i++] = this.fButton2;\n data[i] = this.pins;\n return data;\n }\n\n /**\n * notifyPointerLocked()\n *\n * @this {Mouse}\n * @param {boolean} fLocked\n */\n notifyPointerLocked(fLocked)\n {\n this.fLocked = fLocked;\n }\n\n /**\n * captureAll()\n *\n * @this {Mouse}\n */\n captureAll()\n {\n if (!this.fCaptured) {\n for (var i = 0; i < this.aScreens.length; i++) {\n if (this.captureMouse(this.aScreens[i])) this.fCaptured = true;\n }\n }\n }\n\n /**\n * releaseAll()\n *\n * @this {Mouse}\n */\n releaseAll()\n {\n if (this.fCaptured) {\n for (var i = 0; i < this.aScreens.length; i++) {\n if (this.releaseMouse(this.aScreens[i])) this.fCaptured = false;\n }\n }\n }\n\n /**\n * captureMouse(control)\n *\n * NOTE: addEventListener() wasn't supported in Internet Explorer until IE9, but that's OK, because\n * IE9 is the oldest IE we support anyway (since versions prior to IE9 lack the necessary HTML5 support).\n *\n * @this {Mouse}\n * @param {HTMLElement} control from the HTML DOM (eg, the control for the simulated screen)\n * @return {boolean} true if event handlers were actually added, false if not\n */\n captureMouse(control)\n {\n if (control) {\n var mouse = this;\n control.addEventListener(\n 'mousemove',\n function onMouseMove(event) {\n mouse.processMouseEvent(event);\n },\n false // we'll specify false for the 'useCapture' parameter for now...\n );\n control.addEventListener(\n 'mousedown',\n function onMouseDown(event) {\n mouse.processMouseEvent(event, true);\n },\n false // we'll specify false for the 'useCapture' parameter for now...\n );\n control.addEventListener(\n 'mouseup',\n function onMouseUp(event) {\n mouse.processMouseEvent(event, false);\n },\n false // we'll specify false for the 'useCapture' parameter for now...\n );\n /*\n * None of these tricks seemed to work for IE10, so I'm giving up hiding the browser's mouse pointer in IE for now.\n *\n * control['style']['cursor'] = \"url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjbQg61aAAAADUlEQVQYV2P4//8/IwAI/QL/+TZZdwAAAABJRU5ErkJggg=='), url('/versions/images/current/blank.cur'), none\";\n *\n * Setting the cursor style to \"none\" may not be a standard, but it works in Safari, Firefox and Chrome, so that's pretty\n * good for a non-standard!\n *\n * TODO: The reference to '/versions/images/current/blank.cur' is also problematic for anyone who might want\n * to run this app from a different server, so think about that as well.\n */\n control['style']['cursor'] = \"none\";\n return true;\n }\n return false;\n }\n\n /**\n * releaseMouse(control)\n *\n * TODO: Use removeEventListener() to clean up our handlers; since I'm currently using anonymous functions,\n * and since I'm not seeing any compelling reason to remove the handlers once they've been established, it's\n * less code to leave them in place.\n *\n * @this {Mouse}\n * @param {HTMLElement} control from the HTML DOM\n * @return {boolean} true if event handlers were actually released, false if not\n */\n releaseMouse(control)\n {\n if (control) {\n control['style']['cursor'] = \"auto\";\n }\n return false;\n }\n\n /**\n * processMouseEvent(event, fDown)\n *\n * @this {Mouse}\n * @param {Object} event object from a 'mousemove', 'mousedown' or 'mouseup' event (ie, a MouseEvent object)\n * @param {boolean} [fDown] (undefined if neither a down nor up event)\n */\n processMouseEvent(event, fDown)\n {\n if (fDown !== undefined) {\n if (this.fLocked === false) {\n /*\n * If there's no support for automatic pointer locking in the Video component, notifyPointerActive()\n * will return false, and we will set fLocked to null, ensuring that we never attempt this again.\n */\n if (!this.aVideo.length || !this.aVideo[0].notifyPointerActive(true)) {\n this.fLocked = null;\n }\n }\n this.clickMouse(event.button, fDown);\n } else {\n /*\n * All we really care about are deltas. We record screenX and screenY (as xMouse and yMouse)\n * merely to calculate xDelta and yDelta.\n */\n var xDelta, yDelta;\n if (this.xMouse < 0 || this.yMouse < 0) {\n this.xMouse = event.screenX;\n this.yMouse = event.screenY;\n }\n if (this.fLocked) {\n xDelta = event['movementX'] || event['mozMovementX'] || event['webkitMovementX'] || 0;\n yDelta = event['movementY'] || event['mozMovementY'] || event['webkitMovementY'] || 0;\n } else {\n xDelta = event.screenX - this.xMouse;\n yDelta = event.screenY - this.yMouse;\n }\n this.xMouse = event.screenX;\n this.yMouse = event.screenY;\n this.moveMouse(xDelta, yDelta, this.xMouse, this.yMouse);\n }\n }\n\n /**\n * clickMouse(iButton, fDown)\n *\n * @this {Mouse}\n * @param {number} iButton is Mouse.BUTTON.LEFT (0) for fButton1, Mouse.BUTTON.RIGHT (2) for fButton2\n * @param {boolean} fDown\n */\n clickMouse(iButton, fDown)\n {\n if (this.isActive()) {\n var sDiag = DEBUGGER? (\"mouse button\" + iButton + ' ' + (fDown? \"dn\" : \"up\")) : null;\n switch (iButton) {\n case Mouse.BUTTON.LEFT:\n if (this.fButton1 != fDown) {\n this.fButton1 = fDown;\n this.sendPacket(sDiag);\n return;\n }\n break;\n case Mouse.BUTTON.RIGHT:\n if (this.fButton2 != fDown) {\n this.fButton2 = fDown;\n this.sendPacket(sDiag);\n return;\n }\n break;\n default:\n break;\n }\n this.printMessage(sDiag + \": ignored\");\n }\n }\n\n /**\n * moveMouse(xDelta, yDelta, xDiag, yDiag)\n *\n * @this {Mouse}\n * @param {number} xDelta\n * @param {number} yDelta\n * @param {number} [xDiag]\n * @param {number} [yDiag]\n */\n moveMouse(xDelta, yDelta, xDiag, yDiag)\n {\n if (this.isActive()) {\n /*\n * I would prefer to simply say \"Math.round(xDelta * this.scale)\", but JavaScript's round() function\n * rounds negative numbers toward +infinity if the fraction is exactly 0.5. All positive numbers are\n * rounded correctly, so we convert the value to positive and restore its sign afterward. Additionally,\n * if the scaling factor turns a non-zero value into zero, we restore the value to its smallest legal\n * non-zero value (thanks to Math.sign() again). This ensures that tiniest movement of the physical\n * mouse always results in at least the tiniest movement of the virtual mouse.\n */\n var xScaled = (Math.round(Math.abs(xDelta) * this.scale) * Math.sign(xDelta)) || Math.sign(xDelta);\n var yScaled = (Math.round(Math.abs(yDelta) * this.scale) * Math.sign(yDelta)) || Math.sign(yDelta);\n if (xScaled || yScaled) {\n if (this.messageEnabled(Messages.MOUSE)) {\n this.printMessage(\"moveMouse(\" + xScaled + \",\" + yScaled + \")\");\n }\n /*\n * As sendPacket() indicates, any x and y coordinates we supply are for diagnostic purposes only.\n * sendPacket() only cares about the xDelta and yDelta properties we provide above, which it then zeroes\n * on completion.\n */\n this.xDelta = xScaled;\n this.yDelta = yScaled;\n this.sendPacket(null, xDiag, yDiag);\n }\n }\n }\n\n /**\n * sendPacket(sDiag, xDiag, yDiag)\n *\n * If we're called, something changed.\n *\n * Let's review the 3-byte packet format:\n *\n * D7 D6 D5 D4 D3 D2 D1 D0\n * Byte 1 X 1 LB RB Y7 Y6 X7 X6\n * Byte 2 X 0 X5 X4 X3 X2 X1 X0\n * Byte 3 X 0 Y5 Y4 Y3 Y2 Y1 Y0\n *\n * @this {Mouse}\n * @param {string|null|*} [sDiag] diagnostic message\n * @param {number} [xDiag] original x-coordinate (optional; for diagnostic use only)\n * @param {number} [yDiag] original y-coordinate (optional; for diagnostic use only)\n */\n sendPacket(sDiag, xDiag, yDiag)\n {\n var b1 = 0x40 | (this.fButton1? 0x20 : 0) | (this.fButton2? 0x10 : 0) | ((this.yDelta & 0xC0) >> 4) | ((this.xDelta & 0xC0) >> 6);\n var b2 = this.xDelta & 0x3F;\n var b3 = this.yDelta & 0x3F;\n if (this.messageEnabled(Messages.SERIAL)) {\n this.printMessage((sDiag? (sDiag + \": \") : \"\") + (yDiag !== undefined? (\"mouse (\" + xDiag + \",\" + yDiag + \"): \") : \"\") + \"serial packet [\" + Str.toHexByte(b1) + \",\" + Str.toHexByte(b2) + \",\" + Str.toHexByte(b3) + \"]\", 0, true);\n }\n this.componentDevice.receiveData([b1, b2, b3]);\n this.xDelta = this.yDelta = 0;\n }\n\n /**\n * receiveStatus(pins)\n *\n * The SerialPort notifies us whenever SerialPort.MCR.DTR or SerialPort.MCR.RTS changes.\n *\n * During normal serial mouse operation, both RTS and DTR must be \"positive\".\n *\n * Setting RTS \"negative\" for 100ms resets the mouse. Toggling DTR requests an identification byte (SERIAL.ID).\n *\n * NOTES: The above 3rd-party information notwithstanding, I've observed that Windows v1.01 initially writes 0x01\n * to the MCR (DTR on, RTS off), spins in a loop that reads the RBR (probably to avoid a bogus identification byte\n * sitting in the RBR), and then writes 0x0B to the MCR (DTR on, RTS on). This last step is consistent with making\n * the mouse \"active\", but it is NOT consistent with \"toggling DTR\", so I conclude that a reset is ALSO sufficient\n * for sending the identification byte. Right or wrong, this gets the ball rolling for Windows v1.01.\n *\n * @this {Mouse}\n * @param {number} pins\n */\n receiveStatus(pins)\n {\n var fActive = ((pins & (RS232.DTR.MASK | RS232.RTS.MASK)) == (RS232.DTR.MASK | RS232.RTS.MASK));\n if (fActive) {\n if (!this.fActive) {\n var fIdentify = false;\n if (!(this.pins & RS232.RTS.MASK)) {\n this.reset();\n this.printMessage(\"serial mouse reset\");\n fIdentify = true;\n }\n if (!(this.pins & RS232.DTR.MASK)) {\n this.printMessage(\"serial mouse ID requested\");\n fIdentify = true;\n }\n if (fIdentify) {\n /*\n * HEADS UP: Everything I'd read about the (original) Microsoft Serial Mouse \"reset\" protocol says\n * that the device sends a single byte (0x4D aka 'M'). It's not surprising to think that newer mice\n * might send additional bytes, but you would think that newer mouse drivers (eg, MOUSE.COM v8.20)\n * would always be able to deal with mice that sent only one byte.\n *\n * You would be wrong. On an INT 0x33 reset, the v8.20 driver looks for an 'M', then it waits for\n * another byte (0x42 aka 'B'). If it doesn't receive a 'B', it will accept another 'M'. But if it\n * receives something else (or nothing at all), it will spend a long time waiting for it, and then\n * return an error.\n *\n * It's entirely possible that I've done something wrong and inadvertently \"tricked\" MOUSE.COM into\n * using the wrong detection logic. But given the other problems I've seen in MOUSE.COM v8.20, including\n * its failure to properly terminate-and-stay-resident when its initial INT 0x33 reset returns an error,\n * I'm not in the mood to give it the benefit of the doubt.\n *\n * So, anyway, I solve the terminate-and-stay-resident bug in MOUSE.COM v8.20 by feeding it *two* SERIAL.ID\n * bytes on a reset. This doesn't seem to adversely affect serial mouse emulation for Windows 1.01, so\n * I'm calling this good enough for now.\n */\n this.componentDevice.receiveData([Mouse.SERIAL.ID, Mouse.SERIAL.ID]);\n this.printMessage(\"serial mouse ID sent\");\n }\n this.captureAll();\n this.setActive(fActive);\n }\n } else {\n if (this.fActive) {\n /*\n * Although this would seem nice (ie, for the Windows v1.01 mouse driver to turn RTS off when its mouse\n * driver shuts down and Windows exits, since it DID turn RTS on), that doesn't appear to actually happen.\n * At the very least, Windows will have (re)masked the serial port's IRQ, so what does it matter? Not much,\n * I just would have preferred that fActive properly reflect whether we should continue dispatching mouse\n * events, displaying MOUSE messages, etc.\n *\n * We could ask the ChipSet component to notify the SerialPort component whenever its IRQ is masked/unmasked,\n * and then have the SerialPort pass that notification on to us, but I'm assuming that in the real world,\n * a mouse device that's still powered may still send event data to the serial port, and if there was software\n * polling the serial port, it might expect to see that data. Unlikely, but not impossible.\n */\n this.printMessage(\"serial mouse inactive\");\n this.releaseAll();\n this.setActive(fActive);\n }\n }\n this.pins = pins;\n }\n\n /**\n * inBusData(port, addrFrom)\n *\n * @this {Mouse}\n * @param {number} port (eg, 0x23C)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inBusData(port, addrFrom)\n {\n var b = 0;\n this.printMessageIO(port, null, addrFrom, \"DATA\", b);\n return b;\n }\n\n /**\n * inBusTPPI(port, addrFrom)\n *\n * @this {Mouse}\n * @param {number} port (eg, 0x23D)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inBusTPPI(port, addrFrom)\n {\n var b = 0;\n this.printMessageIO(port, null, addrFrom, \"TPPI\", b);\n return b;\n }\n\n /**\n * inBusCtrl(port, addrFrom)\n *\n * @this {Mouse}\n * @param {number} port (eg, 0x23E)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inBusCtrl(port, addrFrom)\n {\n var b = 0;\n this.printMessageIO(port, null, addrFrom, \"CTRL\", b);\n return b;\n }\n\n /**\n * inBusCPPI(port, addrFrom)\n *\n * @this {Mouse}\n * @param {number} port (eg, 0x23F)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inBusCPPI(port, addrFrom)\n {\n var b = 0;\n this.printMessageIO(port, null, addrFrom, \"CPPI\", b);\n return b;\n }\n\n /**\n * outBusData(port, bOut, addrFrom)\n *\n * @this {Mouse}\n * @param {number} port (eg, 0x23C)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outBusData(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"DATA\");\n }\n\n /**\n * outBusTPPI(port, bOut, addrFrom)\n *\n * @this {Mouse}\n * @param {number} port (eg, 0x23D)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outBusTPPI(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"TPPI\");\n }\n\n /**\n * outBusCtrl(port, bOut, addrFrom)\n *\n * @this {Mouse}\n * @param {number} port (eg, 0x23E)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outBusCtrl(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"CTRL\");\n }\n\n /**\n * outBusCPPI(port, bOut, addrFrom)\n *\n * @this {Mouse}\n * @param {number} port (eg, 0x23F)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outBusCPPI(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"CPPI\");\n }\n\n /**\n * Mouse.init()\n *\n * This function operates on every HTML element of class \"mouse\", extracting the\n * JSON-encoded parameters for the Mouse constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Mouse component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeMouse = Component.getElementsByClass(document, PCX86.APPCLASS, \"mouse\");\n for (var iMouse = 0; iMouse < aeMouse.length; iMouse++) {\n var eMouse = aeMouse[iMouse];\n var parmsMouse = Component.getComponentParms(eMouse);\n var mouse = new Mouse(parmsMouse);\n Component.bindComponentControls(mouse, eMouse, PCX86.APPCLASS);\n }\n }\n}\n\nMouse.TYPE = {\n BUS: \"bus\",\n INPORT: \"inport\",\n SERIAL: \"serial\"\n};\n\nMouse.BUTTON = {\n LEFT: 0,\n RIGHT: 2\n};\n\n/*\n * The Microsoft Bus Mouse supported only one base address: 0x23C.\n *\n * NOTE: Windows v1.01 probes ports 0x23D and 0x23F immediately prior to probing COM2 (and then COM1)\n * for a serial mouse.\n */\nMouse.BUS = {\n DATA: { // Mouse Data Register\n PORT: 0x23C\n },\n TPPI: { // 8255 (PPI) Test Register\n PORT: 0x23D\n },\n CTRL: { // Mouse Control Register\n PORT: 0x23E\n },\n CPPI: { // 8255 (PPI) Control Register\n PORT: 0x23F\n }\n};\n\nMouse.aBusInput = {\n 0x0: Mouse.prototype.inBusData,\n 0x1: Mouse.prototype.inBusTPPI,\n 0x2: Mouse.prototype.inBusCtrl,\n 0x3: Mouse.prototype.inBusCPPI\n};\n\nMouse.aBusOutput = {\n 0x0: Mouse.prototype.outBusData,\n 0x1: Mouse.prototype.outBusTPPI,\n 0x2: Mouse.prototype.outBusCtrl,\n 0x3: Mouse.prototype.outBusCPPI\n};\n\n/*\n * The retail Microsoft InPort card supported two base addresses, 0x23C and 0x238, through the primary and\n * secondary jumpers, respectively. However, OEMs may have had InPorts on other base addresses.\n *\n * Here's a typical InPort Mouse detection sequence:\n *\n * S = IN(Mouse.INPORT.ID.PORT)\n * ...\n * VERIFY THAT S EQUALS Mouse.INPORT.ID.CHIP\n * T = IN(Mouse.INPORT.ID.PORT)\n * ...\n * VERIFY ADDITIONAL PAIRS OF READS RETURN MATCHING S AND T VALUES\n *\n * Here's a typical InPort Mouse interrupt sequence:\n *\n * OUT(Mouse.INPORT.ADDR.PORT, Mouse.INPORT.ADDR.MODE)\n * OUT(Mouse.INPORT.DATA.PORT, IN(Mouse.INPORT.DATA.PORT) | Mouse.INPORT.DATA.MODE.HOLD)\n * ...\n * OUT(Mouse.INPORT.ADDR.PORT, Mouse.INPORT.ADDR.X)\n * X = IN(Mouse.INPORT.DATA.PORT)\n * OUT(Mouse.INPORT.ADDR.PORT, Mouse.INPORT.ADDR.Y)\n * Y = IN(Mouse.INPORT.DATA.PORT)\n * OUT(Mouse.INPORT.ADDR.PORT, Mouse.INPORT.ADDR.STATUS)\n * B = IN(Mouse.INPORT.DATA.PORT) & (Mouse.INPORT.DATA.STATUS.B1 | Mouse.INPORT.DATA.STATUS.B2 | Mouse.INPORT.DATA.STATUS.B3)\n * ...\n * OUT(Mouse.INPORT.ADDR.PORT, Mouse.INPORT.ADDR.MODE)\n * OUT(Mouse.INPORT.DATA.PORT, IN(Mouse.INPORT.DATA.PORT) & ~Mouse.INPORT.DATA.MODE.HOLD)\n */\nMouse.INPORT = {\n ADDR: {\n PORT: 0x23C,\n STATUS: 0x00, // InPort Status Register\n X: 0x01, // InPort X Movement Register\n Y: 0x02, // InPort Y Movement Register\n ISTAT: 0x05, // InPort Interface Status Register\n ICTRL: 0x06, // InPort Interface Control Register\n MODE: 0x07 // InPort Mode Register\n },\n DATA: {\n /*\n * The internal register read or written via this port is determined by the value written to ADDR.PORT\n */\n PORT: 0x23D,\n STATUS: { // InPort Status Register (0)\n B3: 0x01, // Status button 3\n B2: 0x02, // Status button 2\n B1: 0x04, // Status button 1\n DB3: 0x08, // Delta button 3\n DB2: 0x10, // Delta button 2\n DB1: 0x20, // Delta button 1\n MOVE: 0x40, // Movement\n PACKET: 0x80 // Packet complete\n },\n MODE: { // InPort Mode Register (7)\n HOLD: 0x20 // hold the status for reading\n }\n },\n ID: {\n /*\n * The initial read returns the Chip ID; alternate reads return a byte containing the InPort revision number\n * in the low nibble and the InPort version number in the high nibble.\n */\n PORT: 0x23E,\n CHIP: 0xDE // InPort Chip ID\n },\n TEST: {\n PORT: 0x23F\n }\n};\n\n/*\n * From http://paulbourke.net/dataformats/serialmouse:\n *\n * The old MicroSoft serial mouse, while no longer in general use, can be employed to provide a low cost input device,\n * for example, coupling the internal mechanism to other moving objects. The serial protocol for the mouse is:\n *\n * 1200 baud, 7 bit, 1 stop bit, no parity.\n *\n * The pinout of the connector follows the standard serial interface, as shown below:\n *\n * Pin Abbr Description\n * 1 DCD Data Carrier Detect\n * 2 RD Receive Data [serial data from mouse to host]\n * 3 TD Transmit Data\n * 4 DTR Data Terminal Ready [used to provide positive voltage to mouse, plus reset/detection]\n * 5 SG Signal Ground\n * 6 DSR Data Set Ready\n * 7 RTS Request To Send [used to provide positive voltage to mouse]\n * 8 CTS Clear To Send\n * 9 RI Ring\n *\n * Every time the mouse changes state (moved or button pressed) a three byte \"packet\" is sent to the serial interface.\n * For reasons known only to the engineers, the data is arranged as follows, most notably the two high order bits for the\n * x and y coordinates share the first byte with the button status.\n *\n * D6 D5 D4 D3 D2 D1 D0\n * 1st byte 1 LB RB Y7 Y6 X7 X6\n * 2nd byte 0 X5 X4 X3 X2 X1 X0\n * 3rd byte 0 Y5 Y4 Y3 Y2 Y1 Y0\n *\n * where:\n *\n * LB is the state of the left button, 1 = pressed, 0 = released.\n * RB is the state of the right button, 1 = pressed, 0 = released\n * X0-7 is movement of the mouse in the X direction since the last packet. Positive movement is toward the right.\n * Y0-7 is movement of the mouse in the Y direction since the last packet. Positive movement is back, toward the user.\n *\n * From http://www.kryslix.com/nsfaq/Q.12.html:\n *\n * The Microsoft serial mouse is the most popular 2-button mouse. It is supported by all major operating systems.\n * The maximum tracking rate for a Microsoft mouse is 40 reports/second * 127 counts per report, in other words, 5080 counts\n * per second. The most common range for mice is is 100 to 400 CPI (counts per inch) but can be up to 1000 CPI. A 100 CPI mouse\n * can discriminate motion up to 50.8 inches/second while a 400 CPI mouse can only discriminate motion up to 12.7 inches/second.\n *\n * 9-pin 25-pin Line Comments\n * shell 1 GND\n * 3 2 TD Serial data from host to mouse (only for power)\n * 2 3 RD Serial data from mouse to host\n * 7 4 RTS Positive voltage to mouse\n * 8 5 CTS\n * 6 6 DSR\n * 5 7 SGND\n * 4 20 DTR Positive voltage to mouse and reset/detection\n *\n * To function correctly, both the RTS and DTR lines must be positive. DTR/DSR and RTS/CTS must NOT be shorted.\n * RTS may be toggled negative for at least 100ms to reset the mouse. (After a cold boot, the RTS line is usually negative.\n * This provides an automatic toggle when RTS is brought positive). When DTR is toggled the mouse should send a single byte\n * (0x4D, ASCII 'M').\n *\n * Serial data parameters: 1200bps, 7 data bits, 1 stop bit\n *\n * Data is sent in 3 byte packets for each event (a button is pressed or released, or the mouse moves):\n *\n * D7 D6 D5 D4 D3 D2 D1 D0\n * Byte 1 X 1 LB RB Y7 Y6 X7 X6\n * Byte 2 X 0 X5 X4 X3 X2 X1 X0\n * Byte 3 X 0 Y5 Y4 Y3 Y2 Y1 Y0\n *\n * LB is the state of the left button (1 means down).\n * RB is the state of the right button (1 means down).\n * X7-X0 movement in X direction since last packet (signed byte).\n * Y7-Y0 movement in Y direction since last packet (signed byte).\n * The high order bit of each byte (D7) is ignored. Bit D6 indicates the start of an event, which allows the software to\n * synchronize with the mouse.\n */\nMouse.SERIAL = {\n ID: 0x4D\n};\n\n/*\n * Initialize every Mouse module on the page.\n */\nWeb.onInit(Mouse.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/disk.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * The Disk component provides methods for:\n *\n * 1) creating an empty disk: create()\n * 2) loading a disk image: load()\n * 3) getting disk information: info()\n * 4) seeking a disk sector: seek()\n * 5) reading data from a sector: read()\n * 6) writing data to a sector: write()\n * 7) save disk deltas: save()\n * 8) restore disk deltas: restore()\n * 9) converting disk contents: convertToJSON()\n *\n * More functionality may be factored out of the FDC and HDC components later and moved here, to\n * further reduce some of the duplication between them, but the above functionality is a good start.\n */\n\n/*\n * Client/Server Disk I/O\n *\n * To support large disks without consuming large amounts of client-side memory, and to push\n * client-side disk changes back the server, we need a DiskIO API that can be used in place of\n * the DiskDump API.\n *\n * Use of the DiskIO API and any associated disk images must be tightly coupled to per-user\n * storage and specific machine configurations, to prevent the disk images from being corrupted\n * by inconsistent I/O operations. Our basic User API (userapi.js) already provides some\n * per-user storage that we can use to get the design rolling.\n *\n * The DiskIO API must also provide the ability to create new (empty) hard disk images in per-user\n * storage and automatically associate them with the machine configurations that requested them.\n */\n\n/*\n * Principles\n *\n * Originally, when the Disk class was given a disk image to load and mount, it would request the\n * ENTIRE disk image from the DiskDump module. That works well for small (floppy) disk images, but\n * for larger disks -- let's just say anything stored on the server as an \"img\" file -- we'd prefer\n * to interact with that disk using \"On-Demand I/O\". Any \"img\" file on the same server as the PCjs\n * application should be a candidate for on-demand access.\n *\n * On-Demand I/O means that nothing is initially transferred from the server. As sectors are\n * requested by the PCx86 machine, PCx86 requests them from the server, and maintains an MRU cache\n * of sectors, periodically discarding the least-used clean sectors above a certain memory limit.\n * Dirty sectors (ie, those that the PCx86 machine has written to) must be periodically sent\n * back to the server and then marked as clean, so that they can be discarded like any other\n * sector.\n *\n * We also support \"local\" init-only disk images, which means that dirty sectors are never sent\n * back to the server and are instead retained by the client for the lifetime of the app; such\n * images are \"read-only\" as far as the server is concerned, but \"read-write\" as far as the client\n * is concerned. Reloading/restarting an app with an \"local\" disk will return the disk to its\n * initial state.\n *\n * Practice\n * ---\n * Let's first look at what we *already* do for the HDC component:\n *\n * 1) Creating new (empty) disk images\n * 2) Pre-loading pre-built JSON-encoded disk images (converting them to JSON on the fly as needed)\n *\n * An example of #1 is in /devices/pc/machine/5160/cga/256kb/demo/machine.xml:\n *\n * <hdc id=\"hdcXT\" drives='[{name:\"10Mb Hard Drive\",type:3}]'/>\n *\n * and an example of #2 is in /disks/pc/fixed/win101.xml:\n *\n * <hdc id=\"hdcXT\" drives='[{name:\"10Mb Hard Drive\",path:\"/disks/pc/fixed/win101/10mb.json\",type:3}]'/>\n *\n * The HDC component expects an array of drive entries. Array position determines drive numbering\n * (the first entry is drive 0, the second is drive 1, etc), and each entry contains the following\n * properties:\n *\n * 'name': user-friendly name for the disk, if any\n * 'path': URL of the disk image, if any\n * 'type': a drive type\n *\n * Of those properties, only 'type' is required, which provides an index into an HDC \"Drive Type\"\n * table that determines disk geometry and therefore disk size. As we add support for larger disks and\n * newer disk controllers, the 'type' parameter will be superseded by either a user-defined 'geometry'\n * parameter that will define number of heads, cylinders, tracks, sectors per track, and (max) bytes per\n * sector, or perhaps a generic 'size' parameter that leaves geometry choices to the HDC component,\n * which will then pass those decisions on to the Disk component.\n *\n * We will enable on-demand I/O for a disk image with a new 'mode' parameter that looks like:\n *\n * 'mode': one of \"local\", \"preload\", \"demandrw\", \"demandro\"\n *\n * \"preload\" means the disk image will be completely preloaded, exactly as before; \"demandrw\" enables\n * full on-demand I/O support; and \"demandro\" enables on-demand I/O for reads only (all writes are retained\n * and never written back to the server).\n *\n * \"ro\" will be the fallback for \"rw\" unless TWO other important criteria are met: 1) the user has a\n * private user key, and therefore per-user storage; and 2) the disk image 'path' contains an asterisk (*)\n * that the server can internally remap to a directory in the user's storage; eg:\n *\n * 'path': <asterisk>/10mb.img (path components following the asterisk are optional)\n *\n * If the disk image does not already exist, it will be created (but not formatted).\n *\n * This preserves the promise that EVERYTHING a user does within a PCx86 machine is private (ie, not\n * visible to any other PCjs users). I don't want to be in the business of saving any user machine\n * states or disk changes, but at least those operations are limited to users who have asked for (and\n * received) a private user key.\n *\n * Another important consideration at this stage is dealing with multiple machines writing to the same\n * disk image; even though we're limiting the \"demandrw\" mode to per-user images, a single user may still\n * inadvertently start up multiple machines that refer to the same disk image.\n *\n * So, every PCx86 machine needs to generate a unique token and include that token with every Disk I/O API\n * operation, so that the server can revoke a previous machine's \"rw\" access to a disk image when a new\n * machine requests \"rw\" access to the same disk image.\n *\n * From the client's perspective, revocation can be quietly dealt with by reverting to \"demandro\" mode;\n * that client becomes stuck with all their dirty sectors until they can reclaim \"rw\" access, which should\n * only happen if no intervening writes to the disk image on the server have occurred (if I bother allowing\n * reclamation at all).\n *\n * The real challenge here is avoiding revocation of a machine that still has critical changes to commit,\n * but since we can't even solve the problem of a user closing their browser at an inopportune time\n * and potentially leaving a disk image in an inconsistent state, premature revocation is the least of\n * our problems. Since a real hard drive could suffer the same fate if the machine's power was turned off\n * at the wrong time, you could say that we're simply providing a faithful simulation of reality.\n */\n\n/**\n * class Disk\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass Disk extends Component {\n /**\n * Disk(controller, drive, mode)\n *\n * Disk contents are stored as an array (aDiskData) of cylinders, each of which is an array of\n * heads, each of which is an array of sector objects; the latter contain sector numbers and\n * sector data, where sector data is an array of dwords. The format does not impose any\n * limitations on number of cylinders, number of heads, sectors per track, or bytes per sector.\n *\n * WARNING: All accesses to disk sector properties must be via their string names, not their\n * \"dot\" names, otherwise code will break after it's been processed by the Closure Compiler,\n * and any dumped disks may be unmountable. This is a side-effect of how we mount and dump\n * disk images (ie, as JSON-encoded streams).\n *\n * This means, for example, that all references to \"track[iSector].data\" must actually appear as\n * \"track[iSector]['data']\".\n *\n * @this {Disk}\n * @param {HDC|FDC} controller\n * @param {Object} drive\n * @param {string} mode\n */\n constructor(controller, drive, mode)\n {\n super(\"Disk\", {'id': controller.idMachine + \".disk\" + Str.toHex(++Disk.nDisks, 4)}, Messages.DISK);\n\n this.controller = controller;\n\n /*\n * Route all non-Debugger messages (eg, notice() and println() calls) through\n * this.controller (eg, controller.notice() and controller.println()), because\n * the Computer component is unaware of any Disk objects and therefore will not\n * set up the usual overrides when a Control Panel is installed.\n */\n this.notice = controller.notice;\n this.println = controller.println;\n\n this.cmp = controller.cmp;\n this.dbg = controller.dbg;\n this.drive = drive;\n\n /*\n * We pull out a number of drive properties that we may or may not need as defaults\n */\n this.sDiskName = drive.name;\n this.fRemovable = drive.fRemovable;\n this.fOnDemand = this.fRemote = false;\n\n /*\n * Initialize the disk contents\n */\n this.create(mode, drive.nCylinders, drive.nHeads, drive.nSectors, drive.cbSector);\n\n /*\n * The following dirty sector and timer properties are used only with fOnDemand disks,\n * assuming fRemote was successfully set.\n */\n this.aDirtySectors = [];\n this.aDirtyTimestamps = []; // this array is parallel to aDirtySectors\n this.timerWrite = null; // REMOTE_WRITE_DELAY timer in effect, if any\n this.msTimerWrite = 0; // the time that the write timer, if any, is set to fire\n this.fWriteInProgress = false;\n\n this.setReady();\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * We have no real interest in this notification, other than to obtain a reference to the Debugger\n * for every disk loaded BEFORE the initBus() phase; any disk loaded AFTER that point will get its Debugger\n * reference, if any, from the disk controller passed to the Disk() constructor.\n *\n * @this {Disk}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.dbg = dbg;\n }\n\n /**\n * isRemote()\n *\n * @this {Disk}\n * @return {boolean} true if remote disk, false if not\n */\n isRemote()\n {\n /*\n * Ironically, we can't rely on fRemote, because that is cleared and set across disconnect and\n * reconnect operations. fOnDemand is the next best thing.\n */\n return this.fOnDemand;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * As with powerDown(), our sole concern here is for REMOTE disks: if a powerDown() call disconnected an\n * \"on-demand\" disk, we need to get reconnected. Calling our own load() function should get the job done.\n *\n * The HDC component could have triggered this as well, but its powerUp() function only calls autoMount()\n * in case of page (ie, application) reload, which is fine for local disks but insufficient for remote disks,\n * which have a server connection that must be re-established.\n *\n * @this {Disk}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (this.fOnDemand && !this.fRemote) {\n this.setReady(false);\n this.load(this.sDiskName, this.sDiskPath, null, this.donePowerUp, this);\n }\n }\n return true;\n }\n\n /**\n * donePowerUp(drive, disk, sDiskName, sDiskPath)\n *\n * This is a callback issued by the Disk component once the load() from powerUp() has finished.\n *\n * @this {Disk}\n * @param {Object} drive\n * @param {Disk} disk is set if the disk was successfully mounted, null if not\n * @param {string} sDiskName\n * @param {string} sDiskPath\n */\n donePowerUp(drive, disk, sDiskName, sDiskPath)\n {\n this.setReady(true);\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * Our sole concern here is for REMOTE disks, making sure any unwritten changes get flushed to\n * the server during a shutdown. No local state is ever returned, so fSave is ignored.\n *\n * Local disks are managed by the controller (ie, FDC or HDC) that mounted them; the controller's\n * powerDown() handler will take care of calling save() as needed.\n *\n * TODO: Consider taking responsibility for saving the state of local disks as well; the only reason\n * the controllers still take care of them is historical, because this component originally didn't\n * exist, and even after it was created, it didn't originally receive powerDown() notifications.\n *\n * @this {Disk}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean}\n */\n powerDown(fSave, fShutdown)\n {\n /*\n * If we're connected to a remote disk, take this opportunity to flush any remaining unwritten\n * changes and then close the connection.\n */\n if (this.fRemote) {\n var response;\n var nErrorCode = 0;\n if (this.fWriteInProgress) {\n /*\n * TODO: Verify that the Computer's powerOff() handler will actually honor a false return value.\n */\n if (!Component.confirmUser(\"Disk writes are still in progress, shut down anyway?\")) {\n return false;\n }\n }\n while ((response = this.findDirtySectors(false))) {\n if ((nErrorCode = response[0])) {\n this.notice('Unable to save \"' + this.sDiskName + '\" (error ' + nErrorCode + ')');\n break;\n }\n }\n if (fShutdown) {\n this.disconnectRemoteDisk();\n }\n /*\n * I only report that changes to the disk have been \"saved\" if fSave is true, to avoid confusing\n * users who might not understand the difference between discarding local changes (which should restore\n * all diskettes to their original state) and discarding remote changes (which could leave the remote disk\n * in a bad state).\n */\n if (!nErrorCode && fSave) this.notice(this.sDiskName + \" saved\");\n }\n return true;\n }\n\n /**\n * create()\n *\n * @this {Disk}\n * @param {string} mode\n * @param {number} nCylinders\n * @param {number} nHeads\n * @param {number} nSectors (per track)\n * @param {number} cbSector\n *\n * Initializes the disk contents according to the current drive mode and parameters.\n */\n create(mode, nCylinders, nHeads, nSectors, cbSector)\n {\n this.mode = mode;\n this.nCylinders = nCylinders;\n this.nHeads = nHeads;\n this.nSectors = nSectors;\n this.cbSector = cbSector;\n this.aDiskData = [];\n /*\n * If the drive is using PRELOAD mode, then it will use the load()/mount() process to initialize the disk contents;\n * it wouldn't hurt to let create() do its thing, too, but it's a waste of time.\n */\n if (this.mode != DiskAPI.MODE.PRELOAD) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"blank disk for \\\"\" + this.sDiskName + \"\\\": \" + this.nCylinders + \" cylinders, \" + this.nHeads + \" head(s)\");\n }\n var aCylinders = new Array(this.nCylinders);\n for (var iCylinder = 0; iCylinder < aCylinders.length; iCylinder++) {\n var aHeads = new Array(this.nHeads);\n for (var iHead = 0; iHead < aHeads.length; iHead++) {\n var aSectors = new Array(this.nSectors);\n for (var iSector = 1; iSector <= aSectors.length; iSector++) {\n /*\n * Now that our read() and write() functions can deal with unallocated data\n * arrays, and can read/write the specified pattern on-the-fly, we no longer need\n * to pre-allocate and pre-initialize the 'data' array.\n *\n * For \"local\" disks, we can assume a 'pattern' of 0, but for \"demandrw\" and \"demandro\"\n * disks, 'pattern' is set to null, as yet another indication that I/O is required to load\n * the sector from the server (or to write it back to the server).\n */\n aSectors[iSector - 1] = this.initSector(null, iCylinder, iHead, iSector, this.cbSector, (this.mode == DiskAPI.MODE.LOCAL? 0 : null));\n }\n aHeads[iHead] = aSectors;\n }\n aCylinders[iCylinder] = aHeads;\n }\n this.aDiskData = aCylinders;\n }\n this.dwChecksum = null;\n }\n\n /**\n * load(sDiskName, sDiskPath, file, fnNotify)\n *\n * TODO: Figure out how we can strongly type fnNotify, because the Closure Compiler has issues with:\n *\n * param {function(Component,Object,Disk,string,string)} fnNotify\n *\n * for:\n *\n * this.fnNotify.call(this.controller, this.drive, disk, this.sDiskName, this.sDiskPath);\n *\n * Also, while we're at it, learn if there are ways to:\n *\n * 1) declare a function taking NO parameters (ie, generate a warning if any parameters are specified)\n * 2) declare a type for a function's return value\n *\n * @this {Disk}\n * @param {string} sDiskName\n * @param {string} sDiskPath\n * @param {File} [file] is set if there's an associated File object\n * @param {function(...)} [fnNotify]\n * @param {Component} [controller]\n * @return {boolean} true if load completed (successfully or not), false if queued\n */\n load(sDiskName, sDiskPath, file, fnNotify, controller)\n {\n var sDiskURL = sDiskPath;\n\n /*\n * We could use this.log() as well, but it wouldn't display which component initiated the load.\n */\n if (DEBUG) {\n var sMessage = 'load(\"' + sDiskName + '\",\"' + sDiskPath + '\")';\n this.controller.log(sMessage);\n this.printMessage(sMessage);\n }\n\n if (this.fnNotify) {\n if (DEBUG) this.controller.log('too many load requests for \"' + sDiskName + '\" (' + sDiskPath + ')');\n return true;\n }\n\n this.sDiskName = sDiskName;\n this.sDiskPath = sDiskPath;\n this.sDiskFile = Str.getBaseName(sDiskPath);\n this.sFormat = \"json\";\n\n var disk = this;\n this.fnNotify = fnNotify;\n this.controllerNotify = controller || this.controller;\n\n if (file) {\n var reader = new FileReader();\n reader.onload = function() {\n disk.buildDisk(reader.result, true);\n };\n reader.readAsArrayBuffer(file);\n return true;\n }\n\n /*\n * If there's an occurrence of API_ENDPOINT anywhere in the path, we assume we can use it as-is;\n * ie, that the user has already formed a URL of the type we use ourselves for unconverted disk images.\n */\n if (sDiskPath.indexOf(DumpAPI.ENDPOINT) < 0) {\n /*\n * If the selected disk image has a \"json\" extension, then we assume it's a pre-converted\n * JSON-encoded disk image, so we load it as-is; otherwise, we ask our server-side disk image\n * converter to return the corresponding JSON-encoded data.\n */\n var sDiskExt = Str.getExtension(sDiskPath);\n if (sDiskExt == DumpAPI.FORMAT.JSON || sDiskExt == DumpAPI.FORMAT.JSON_GZ) {\n sDiskURL = encodeURI(sDiskPath);\n } else {\n if (this.mode == DiskAPI.MODE.DEMANDRW || this.mode == DiskAPI.MODE.DEMANDRO) {\n sDiskURL = this.connectRemoteDisk(sDiskPath);\n this.fOnDemand = true;\n } else {\n this.sFormat = \"arraybuffer\";\n }\n // else {\n // var sDiskParm = DumpAPI.QUERY.PATH;\n // var sSizeParm = '&' + DumpAPI.QUERY.MBHD + \"=10\";\n // /*\n // * 'mbhd' is a new parm added for hard drive support. In the case of 'file' or 'dir' requests,\n // * 'mbhd' informs DumpAPI.ENDPOINT that it should create a hard disk image, and one not larger than\n // * the specified size (eg, 10mb). In fact, until DumpAPI.ENDPOINT is changed to create custom hard\n // * disk BPBs, you'll always get a standard PC XT 10mb disk image, so if the 'file' or 'dir' contains\n // * more than 10mb of data, the request will fail. Ultimately, I want to honor the controller's\n // * driveConfig 'size' parm, or to match the capacity required by the driveConfig 'type' parameter.\n // *\n // * If a 'disk' is specified, we pass mbhd=0, because the actual size will depend on the image.\n // * However, I don't currently have any \"dsk\" or \"img\" files containing hard disk images; those formats\n // * were really intended for floppy disk images. If I never create any hard disk image files, then\n // * we can simply eliminate sSizeParm in the 'disk' case.\n // *\n // * Added more extensions to the list of paths-treated-as-disk-images, so that URLs to files located here:\n // *\n // * ftp://ftp.oldskool.org/pub/TOPBENCH/dskimage/\n // *\n // * can be used as-is. TODO: There's a TODO in netlib.getFile() regarding remote support that needs\n // * to be resolved first; DiskDump relies on that function for its remote requests, and it currently\n // * supports only HTTP.\n // */\n // if (!sDiskPath.indexOf(\"http:\") || !sDiskPath.indexOf(\"ftp:\") || [\"dsk\", \"ima\", \"img\", \"360\", \"720\", \"12\", \"144\"].indexOf(sDiskExt) >= 0) {\n // sDiskParm = DumpAPI.QUERY.DISK;\n // sSizeParm = '&' + DumpAPI.QUERY.MBHD + \"=0\";\n // } else if (Str.endsWith(sDiskPath, '/')) {\n // sDiskParm = DumpAPI.QUERY.DIR;\n // }\n // sDiskURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + sDiskParm + '=' + encodeURIComponent(sDiskPath) + (this.fRemovable ? \"\" : sSizeParm) + \"&\" + DumpAPI.QUERY.FORMAT + \"=\" + DumpAPI.FORMAT.JSON;\n // }\n }\n }\n var sProgress = \"Loading \" + sDiskURL + \"...\";\n return !!Web.getResource(sDiskURL, this.sFormat, true, function loadDone(sURL, sResponse, nErrorCode) {\n disk.doneLoad(sURL, sResponse, nErrorCode);\n }, function(nState) {\n disk.println(sProgress, Component.PRINT.PROGRESS);\n });\n }\n\n /**\n * buildDisk(buffer, fModified)\n *\n * Builds a disk image from an ArrayBuffer (eg, from a FileReader object), rather than from JSON-encoded data.\n *\n * @this {Disk}\n * @param {?} buffer (technically, this is always an ArrayBuffer, because we tell FileReader to use readAsArrayBuffer, but the Closure Compiler doesn't realize that) \n * @param {boolean} [fModified] is true if we should mark the entire disk modified (to ensure that we save/restore it)\n */\n buildDisk(buffer, fModified)\n {\n var disk;\n var cbDiskData = buffer? buffer.byteLength : 0;\n var diskFormat = DiskAPI.GEOMETRIES[cbDiskData];\n\n if (diskFormat) {\n this.nCylinders = diskFormat[0];\n this.nHeads = diskFormat[1];\n this.nSectors = diskFormat[2];\n this.cbSector = (diskFormat[3] || 512);\n\n var cdw = this.cbSector >> 2, dwPattern = 0, dwChecksum = 0;\n var ib = 0;\n var dv = new DataView(buffer, 0, cbDiskData);\n\n this.aDiskData = new Array(this.nCylinders);\n for (var iCylinder = 0; iCylinder < this.aDiskData.length; iCylinder++) {\n var cylinder = this.aDiskData[iCylinder] = new Array(this.nHeads);\n for (var iHead = 0; iHead < cylinder.length; iHead++) {\n var head = cylinder[iHead] = new Array(this.nSectors);\n for (var iSector = 0; iSector < head.length; iSector++) {\n var sector = this.initSector(null, iCylinder, iHead, iSector + 1, this.cbSector, dwPattern);\n var adw = sector['data'];\n for (var idw = 0; idw < cdw; idw++, ib += 4) {\n var dw = adw[idw] = dv.getInt32(ib, true);\n dwChecksum = (dwChecksum + dw) & (0xffffffff|0);\n }\n if (fModified) sector.cModify = cdw;\n head[iSector] = sector;\n }\n }\n }\n this.dwChecksum = dwChecksum;\n disk = this;\n } else {\n this.notice(\"Unrecognized disk format (\" + cbDiskData + \" bytes)\");\n }\n\n if (this.fnNotify) {\n this.fnNotify.call(this.controller, this.drive, disk, this.sDiskName, this.sDiskPath);\n this.fnNotify = null;\n }\n }\n\n /**\n * doneLoad(sURL, diskData, nErrorCode)\n *\n * This function was originally called mount(). If the mount is successful, we pass the Disk object to the\n * caller's fnNotify handler; otherwise, we pass null.\n *\n * @this {Disk}\n * @param {string} sURL\n * @param {string|ArrayBuffer} diskData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n doneLoad(sURL, diskData, nErrorCode)\n {\n var disk = null;\n this.fWriteProtected = false;\n var fPrintOnly = !!(nErrorCode < 0 && this.cmp && !this.cmp.flags.powered);\n\n if (this.fOnDemand) {\n if (!nErrorCode) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage('doneLoad(\"' + this.sDiskPath + '\")');\n }\n this.fRemote = true;\n if (BACKTRACK || SYMBOLS) this.buildFileTable();\n disk = this;\n } else {\n this.notice('Unable to connect to disk \"' + this.sDiskPath + '\" (error ' + nErrorCode + ': ' + diskData + ')', fPrintOnly);\n }\n }\n else if (nErrorCode) {\n /*\n * This can happen for innocuous reasons, such as the user switching away too quickly, forcing\n * the request to be cancelled. And unfortunately, the browser cancels XMLHttpRequest requests\n * BEFORE it notifies any page event handlers, so if the Computer's being powered down, we won't know\n * that yet. For now, we rely on the lack of a specific error (nErrorCode < 0), and suppress the\n * notify() alert if there's no specific error AND the computer is not powered up yet.\n */\n this.notice(\"Unable to load disk \\\"\" + this.sDiskName + \"\\\" (error \" + nErrorCode + \": \" + sURL + \")\", fPrintOnly);\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage('doneLoad(\"' + this.sDiskPath + '\")');\n }\n\n /*\n * If we received binary data instead of JSON, we can use the same buildDisk() function that our FileReader\n * code uses.\n */\n if (typeof diskData != \"string\") {\n this.buildDisk(diskData);\n return;\n }\n \n try {\n /*\n * The following code was a hack to turn on write-protection for a disk image if there was\n * an initial comment line containing the string \"write-protected\". However, since comments\n * are technically not allowed in JSON, I needed an alternative solution. So, if the basename\n * contains the suffix \"-readonly\", then I'll turn on write-protection for that disk as well.\n *\n * TODO: Provide some UI for turning write-protection on/off for disks at will, and provide\n * an XML-based solution (ie, a per-disk XML configuration option) for controlling it as well.\n */\n var sBaseName = Str.getBaseName(this.sDiskFile, true).toLowerCase();\n if (sBaseName.indexOf(\"-readonly\") > 0) {\n this.fWriteProtected = true;\n } else {\n var iEOL = diskData.indexOf(\"\\n\");\n if (iEOL > 0 && iEOL < 1024) {\n var sConfig = diskData.substring(0, iEOL);\n if (sConfig.indexOf(\"write-protected\") > 0) {\n this.fWriteProtected = true;\n }\n }\n }\n /*\n * The most likely source of any exception will be here, where we're parsing the disk data.\n */\n var aDiskData;\n if (diskData.substr(0, 1) == \"<\") { // if the \"data\" begins with a \"<\"...\n /*\n * Early server configs reported an error (via the nErrorCode parameter) if a disk URL was invalid,\n * but more recent server configs now display a somewhat friendlier HTML error page. The downside,\n * however, is that the original error has been buried, and we've received \"data\" that isn't actually\n * disk data.\n *\n * So, if the data we've received appears to be \"HTML-like\", all we can really do is assume that the\n * disk image is missing. And so we pretend we received an error message to that effect.\n */\n aDiskData = [\"Missing disk image: \" + this.sDiskName];\n } else {\n /*\n * TODO: IE9 is rather unfriendly and restrictive with regard to how much data it's willing to\n * eval(). In particular, the 10Mb disk image we use for the Windows 1.01 demo config fails in\n * IE9 with an \"Out of memory\" exception. One work-around would be to chop the data into chunks\n * (perhaps one track per chunk, using regular expressions) and then manually re-assemble it.\n *\n * However, it turns out that using JSON.parse(diskData) instead of eval(\"(\" + diskData + \")\")\n * is a much easier fix. The only drawback is that we must first quote any unquoted property names\n * and remove any comments, because while eval() was cool with them, JSON.parse() is more particular;\n * the following RegExp replacements take care of those requirements.\n *\n * The use of hex values is something else that eval() was OK with, but JSON.parse() is not, and\n * while I've stopped using hex values in DumpAPI responses (at least when \"format=json\" is specified),\n * I can't guarantee they won't show up in \"legacy\" images, and there's no simple RegExp replacement\n * for transforming hex values into decimal values, so I cop out and fall back to eval() if I detect\n * any hex prefixes (\"0x\") in the sequence. Ditto for error messages, which appear like so:\n *\n * [\"unrecognized disk path: test.img\"]\n */\n if (diskData.indexOf(\"0x\") < 0 && diskData.substr(0, 2) != \"[\\\"\") {\n aDiskData = JSON.parse(diskData.replace(/([a-z]+):/gm, \"\\\"$1\\\":\").replace(/\\/\\/[^\\n]*/gm, \"\"));\n } else {\n aDiskData = eval(\"(\" + diskData + \")\");\n }\n }\n\n if (!aDiskData.length) {\n Component.error(\"Empty disk image: \" + this.sDiskName);\n }\n else if (aDiskData.length == 1) {\n Component.error(aDiskData[0]);\n }\n /*\n * aDiskData is an array of cylinders, each of which is an array of heads, each of which\n * is an array of sector objects. The format does not impose any limitations on number of\n * cylinders, number of heads, or number of bytes in any of the sector object byte-arrays.\n *\n * WARNING: All accesses to sector object properties must be via their string names, not their\n * \"dot\" names, otherwise code will break after it's been processed by the Closure Compiler.\n *\n * Sector object properties include:\n *\n * 'sector' the sector number (1-based, not required to be sequential)\n * 'length' the byte-length (ie, formatted length) of the sector\n * 'data' the dword-array containing the sector data\n * 'pattern' if the dword-array length is less than 'length'/4, this value must be used\n * to pad out the sector; if no 'pattern' is specified, it's assumed to be zero\n *\n * We still support the older JSON encoding, where sector data was encoded as an array of 'bytes'\n * rather than a dword 'data' array. However, our support is strictly limited to an on-the-fly\n * conversion to a forward-compatible 'data' array.\n */\n else {\n if (DEBUG && this.messageEnabled(Messages.DISK | Messages.DATA)) {\n var sCylinders = aDiskData.length + \" track\" + (aDiskData.length > 1 ? \"s\" : \"\");\n var nHeads = aDiskData[0].length;\n var sHeads = nHeads + \" head\" + (nHeads > 1 ? \"s\" : \"\");\n var nSectorsPerTrack = aDiskData[0][0].length;\n var sSectorsPerTrack = nSectorsPerTrack + \" sector\" + (nSectorsPerTrack > 1 ? \"s\" : \"\") + \"/track\";\n this.printMessage(sCylinders + \", \" + sHeads + \", \" + sSectorsPerTrack);\n }\n /*\n * Before the image is usable, we must \"normalize\" all the sectors. In the past, this meant\n * \"inflating\" them all. However, that's no longer strictly necessary. Mainly, it just means\n * setting 'length', 'data', and 'pattern' properties, so that all the sectors are well-defined.\n * This includes detecting sector data in older formats (eg, the old array of 'bytes' instead\n * of the new 'data' array of dwords) and converting them on-the-fly to the current format.\n */\n this.nCylinders = aDiskData.length;\n this.nHeads = aDiskData[0].length;\n this.nSectors = aDiskData[0][0].length;\n var sector = aDiskData[0][0][0];\n this.cbSector = (sector && sector['length']) || 512;\n\n var dwChecksum = 0;\n for (var iCylinder = 0; iCylinder < this.nCylinders; iCylinder++) {\n for (var iHead = 0; iHead < this.nHeads; iHead++) {\n for (var iSector = 0; iSector < this.nSectors; iSector++) {\n sector = aDiskData[iCylinder][iHead][iSector];\n if (!sector) continue; // non-standard (eg, XDF) disk images may have \"unused\" (null) sectors\n var length = sector['length'];\n if (length === undefined) { // provide backward-compatibility with older JSON...\n length = sector['length'] = 512;\n }\n length >>= 2; // convert length from a byte-length to a dword-length\n var dwPattern = sector['pattern'];\n if (dwPattern === undefined) {\n dwPattern = sector['pattern'] = 0;\n }\n var adw = sector['data'];\n if (adw === undefined) {\n var ab = sector['bytes'];\n if (ab === undefined || !ab.length) {\n /*\n * If there is neither a 'bytes' nor 'data' array, then our job is simple:\n * create an empty 'data' array; it will be filled in with the dword pattern\n * as needed later.\n *\n * The only wrinkle is if there *is* a 'bytes' array but it's empty, in which\n * case we must assume that the pattern was a byte pattern, so convert it to a\n * dword pattern.\n */\n sector['data'] = adw = [];\n if (ab) {\n\n sector['pattern'] = (dwPattern | (dwPattern << 8) | (dwPattern << 16) | (dwPattern << 24));\n }\n }\n else {\n /*\n * To keep the conversion code simple, we'll do any necessary pattern-filling first,\n * to fully \"inflate\" the sector, eliminating the possibility of partial dwords and\n * saving any code downstream from dealing with byte-size patterns.\n */\n var cb = length << 2;\n\n for (var ib = ab.length; ib < cb; ib++) {\n ab[ib] = dwPattern; // the pattern for byte-arrays was only a byte\n }\n this.fill(sector, ab, 0);\n }\n delete sector['bytes'];\n }\n this.initSector(sector, iCylinder, iHead);\n /*\n * For the disk as a whole, we maintain a checksum of the original unmodified data:\n *\n * dwChecksum: summation of all dwords in all non-empty sectors\n *\n * Pattern-filling of sectors is deferred until absolutely necessary (eg, when a sector is\n * being written). So all we need to do at this point is checksum all the initial sector data.\n */\n for (var idw = 0; idw < adw.length; idw++) {\n dwChecksum = (dwChecksum + adw[idw]) & (0xffffffff|0);\n }\n }\n }\n }\n this.aDiskData = aDiskData;\n this.dwChecksum = dwChecksum;\n if (BACKTRACK || SYMBOLS) this.buildFileTable();\n disk = this;\n }\n } catch (e) {\n Component.error(\"Disk image error (\" + sURL + \"): \" + e.message);\n diskData = null;\n }\n \n if (diskData) {\n Component.addMachineResource(this.controller.idMachine, sURL, diskData);\n }\n }\n\n if (this.fnNotify) {\n this.fnNotify.call(this.controllerNotify, this.drive, disk, this.sDiskName, this.sDiskPath);\n this.fnNotify = null;\n }\n }\n\n /**\n * buildFileTable()\n *\n * This function builds (or rebuilds) a complete file table from the (first) FAT volume found on the current\n * disk, and then updates all the sector objects to point back to the corresponding file. Used for BACKTRACK\n * and SYMBOLS support. Because this is an expensive operation, in terms of both time and memory, it should\n * only be called when a disk is mounted or has been modified (eg, by applying deltas from a saved machine state).\n *\n * More recently, the FileInfo objects in the table have been enhanced to include debugging information if\n * the file is an EXE or DLL, which we determine merely by checking the file extension.\n *\n * Note that while most of the methods in this module use CHS-style parameters, because our primary clients\n * are old disk controllers that deal exclusively with cylinder/head/sector values, here we use 0-based\n * \"logical\" sector numbers for volume-relative block addresses (aka LBAs or Logical Block Addresses), and\n * 0-based \"physical\" sector numbers for disk-relative block addresses (aka PBAs or Physical Block Addresses).\n *\n * Also, our use of the term LBA differs from that of more modern disk controllers; in the pre-modern world\n * of PCx86, what we call PBA numbers are what those controllers would later call LBA numbers.\n *\n * @this {Disk}\n * @return {Array.<FileInfo>|undefined}\n */\n buildFileTable()\n {\n if (BACKTRACK || SYMBOLS) {\n\n var i, off, dir = {}, iSector;\n\n if (this.aFileTable && this.aFileTable.length) {\n /*\n * In order for buildFileTable() to rebuild an existing table (eg, after deltas have been\n * applied), we need to zap any and all existing file table references in the sector data.\n */\n var aDiskData = this.aDiskData;\n for (var iCylinder = 0; iCylinder < aDiskData.length; iCylinder++) {\n for (var iHead = 0; iHead < aDiskData[iCylinder].length; iHead++) {\n for (iSector = 0; iSector < aDiskData[iCylinder][iHead].length; iSector++) {\n var sector = aDiskData[iCylinder][iHead][iSector];\n if (sector) {\n delete sector['file'];\n delete sector.offFile;\n }\n }\n }\n }\n }\n\n this.aFileTable = [];\n\n dir.pbaVolume = dir.lbaTotal = 0;\n\n var cbDisk = this.nCylinders * this.nHeads * this.nSectors * this.cbSector;\n\n /*\n * At this point, if this is a remote disk, you may see some warning messages in your browser's console,\n * like this message from Chrome:\n *\n * \"Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects\n * to the end user's experience. For more help, check http://xhr.spec.whatwg.org/.\"\n *\n * This is because I was lazy and made the buildFileTable() worker function getSector() use the synchronous\n * form of seek(). For development purposes, that was fine, but... TODO: Eventually change buildFileTable()\n * to use async I/O.\n */\n if (this.fRemote) this.log(\"ignore any synchronous XMLHttpRequest warnings here (for now)\");\n\n var sectorBoot = this.getSector(0);\n if (!sectorBoot) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"buildFileTable(): unable to read boot sector\");\n }\n return;\n }\n\n dir.cbSector = this.getSectorData(sectorBoot, DiskAPI.BPB.SECTOR_BYTES, 2);\n\n var fValid = true;\n if (dir.cbSector != this.cbSector) {\n /*\n * When the first sector doesn't appear to contain a valid BPB, the most likely explanations are:\n *\n * 1. The image is from a diskette formatted by DOS 1.xx, which didn't use BPBs\n * 2. The image is a fixed (partitioned) disk and the first sector is actually an MBR\n * 3. The image is from a diskette that used a non-standard sector size (ie, not 512)\n *\n * To start, if this is an 160Kb disk (circa DOS 1.00) or a 320Kb disk (circa DOS 1.10), then we'll\n * assume it's a 12-bit FAT, set assorted BPB values accordingly, and see if our assumption holds up.\n */\n fValid = false;\n dir.lbaFAT = 1;\n dir.nFATBits = 12;\n dir.lbaRoot = dir.lbaFAT + 2; // both 160Kb and 320Kb disks contained 2 FATs, each containing 1 sector\n dir.nClusterSecs = 1;\n dir.cbSector = this.cbSector;\n\n if (cbDisk == 160 * 1024 && this.getClusterEntry(dir, 0, 0) == DiskAPI.FAT.MEDIA_160KB) {\n dir.lbaTotal = 320;\n dir.nEntries = 64;\n fValid = true;\n }\n else if (cbDisk == 320 * 1024 && this.getClusterEntry(dir, 0, 0) == DiskAPI.FAT.MEDIA_320KB) {\n dir.lbaTotal = 640;\n dir.nEntries = 112;\n\n dir.nClusterSecs++; // 320Kb disks use 2 sectors/cluster\n fValid = true;\n }\n else {\n /*\n * So, this is either a fixed (partitioned) disk, or a disk using a non-standard sector size; let's assume\n * the former and check for an MBR. For now, we're only going to process the first active partition we find.\n */\n off = DiskAPI.MBR.PARTITIONS.OFFSET;\n for (i = 0; i < 4; i++) {\n var bStatus = this.getSectorData(sectorBoot, off + DiskAPI.MBR.PARTITIONS.ENTRY.STATUS, 1);\n if (bStatus == DiskAPI.MBR.PARTITIONS.STATUS.ACTIVE) {\n dir.pbaVolume = this.getSectorData(sectorBoot, off + DiskAPI.MBR.PARTITIONS.ENTRY.LBA_FIRST, 4);\n sectorBoot = this.getSector(dir.pbaVolume);\n if (sectorBoot && this.getSectorData(sectorBoot, DiskAPI.BPB.SECTOR_BYTES, 2) == this.cbSector) {\n fValid = true;\n }\n break;\n }\n off += DiskAPI.MBR.PARTITIONS.ENTRY_LENGTH;\n }\n }\n if (!fValid) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"buildFileTable(): unrecognized \" + cbDisk + \"-byte disk image with \" + this.cbSector + \"-byte sectors\");\n }\n return;\n }\n }\n\n if (!dir.lbaTotal) {\n dir.lbaTotal = this.getSectorData(sectorBoot, DiskAPI.BPB.TOTAL_SECS, 2) || this.getSectorData(sectorBoot, DiskAPI.BPB.LARGE_SECS, 4);\n dir.lbaFAT = this.getSectorData(sectorBoot, DiskAPI.BPB.RESERVED_SECS, 2);\n dir.lbaRoot = dir.lbaFAT + this.getSectorData(sectorBoot, DiskAPI.BPB.FAT_SECS, 2) * this.getSectorData(sectorBoot, DiskAPI.BPB.TOTAL_FATS, 1);\n dir.nEntries = this.getSectorData(sectorBoot, DiskAPI.BPB.ROOT_DIRENTS, 2);\n dir.nClusterSecs = this.getSectorData(sectorBoot, DiskAPI.BPB.CLUSTER_SECS, 1);\n }\n\n dir.lbaData = dir.lbaRoot + (((dir.nEntries * DiskAPI.DIRENT.LENGTH + (dir.cbSector - 1)) / dir.cbSector) | 0);\n dir.nClusters = (((dir.lbaTotal - dir.lbaData) / dir.nClusterSecs) | 0);\n\n /*\n * In all FATs, the first valid cluster number is 2, as 0 is used to indicate a free cluster and 1 is reserved.\n *\n * In a 12-bit FAT chain, the largest valid cluster number (iClusterMax) is 0xFF6; 0xFF7 is reserved for marking\n * bad clusters and should NEVER appear in a cluster chain, and 0xFF8-0xFFF are used to indicate the end of a chain.\n * Reports that cluster numbers 0xFF0-0xFF6 are \"reserved\" (eg, http://support.microsoft.com/KB/65541) should be\n * ignored; those numbers may have been considered \"reserved\" at some early point in FAT's history, but no longer.\n *\n * Since 12 bits yield 4096 possible values, and since 11 of the values (0, 1, and 0xFF7-0xFFF) cannot be used to\n * refer to an actual cluster, that leaves a theoretical maximum of 4085 clusters for a 12-bit FAT. However, for\n * reasons that only a small (and shrinking -- RIP AAR) number of people know, the actual cut-off is 4084.\n *\n * So, a FAT volume with 4084 or fewer clusters uses a 12-bit FAT, a FAT volume with 4085 to 65524 clusters uses\n * a 16-bit FAT, and a FAT volume with more than 65524 clusters uses a 32-bit FAT.\n *\n * TODO: Eventually add support for FAT32.\n */\n dir.nFATBits = (dir.nClusters <= DiskAPI.FAT12.MAX_CLUSTERS? 12 : 16);\n dir.iClusterMax = (dir.nFATBits == 12? DiskAPI.FAT12.CLUSNUM_MAX : DiskAPI.FAT16.CLUSNUM_MAX);\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"buildFileTable()\\n\\tlbaFAT: \" + dir.lbaFAT + \"\\n\\tlbaRoot: \" + dir.lbaRoot + \"\\n\\tlbaData: \" + dir.lbaData + \"\\n\\tlbaTotal: \" + dir.lbaTotal + \"\\n\\tnClusterSecs: \" + dir.nClusterSecs + \"\\n\\tnClusters: \" + dir.nClusters);\n }\n\n /*\n * The following assertion is here only to catch anomalies; it is NOT a requirement that the number of data sectors\n * be a perfect multiple of nClusterSecs, but if it ever happens, it's worth verifying we didn't miscalculate something.\n */\n i = (dir.lbaTotal - dir.lbaData) % dir.nClusterSecs;\n if (i) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"buildFileTable(): \" + cbDisk + \"-byte disk image wasting \" + i + \" sectors\");\n }\n }\n\n /*\n * Similarly, it is NOT a requirement that the size of all root directory entries be a perfect multiple of the sector\n * size (cbSector), but it may indicate a problem if it's not. Note that when it comes time to read the root directory,\n * we treat it exactly like any other directory; that is, we ignore the nEntries value and scan the entire contents of\n * every sector allocated to the directory. TODO: Determine whether DOS reads all root sector contents or only nEntries\n * (ie, create a test volume where nEntries * 32 is NOT a multiple of cbSector and watch what happens).\n */\n\n\n var apba = [];\n for (var lba = dir.lbaRoot; lba < dir.lbaData; lba++) apba.push(dir.pbaVolume + lba);\n this.getDir(dir, this.sDiskFile, \"\", apba);\n\n /*\n * Create the sector-to-file mappings now.\n */\n for (i = 0; i < this.aFileTable.length; i++) {\n var file = this.aFileTable[i];\n off = 0;\n for (iSector = 0; iSector < file.apba.length; iSector++) {\n this.updateSector(file, file.apba[iSector], off);\n off += this.cbSector;\n }\n file.loadSymbols();\n }\n }\n return this.aFileTable;\n }\n\n /**\n * getModuleInfo(sModule, nSegment)\n *\n * If the given module and segment number is found, we return an Array of symbol offsets, indexed by symbol name.\n *\n * @this {Disk}\n * @param {string} sModule\n * @param {number} nSegment\n * @return {Object}\n */\n getModuleInfo(sModule, nSegment)\n {\n var aSymbols = {};\n if (SYMBOLS && this.aFileTable) {\n for (var iFile = 0; iFile < this.aFileTable.length; iFile++) {\n var file = this.aFileTable[iFile];\n if (file.sModule != sModule) continue;\n var segment = file.aSegments[nSegment];\n if (!segment) continue;\n for (var iOrdinal in segment.aEntries) {\n var entry = segment.aEntries[iOrdinal];\n /*\n * entry[1] is the symbol name, which becomes the index, and entry[0] is the offset.\n */\n aSymbols[entry[1]] = entry[0];\n }\n break;\n }\n }\n return aSymbols;\n }\n\n /**\n * getSymbolInfo(sSymbol)\n *\n * For all whole or partial symbol matches, return them in an Array of entries:\n *\n * [symbol, file name, segment number, segment offset, segment size].\n *\n * TODO: This function has many limitations (ie, slow, case-sensitive), but it gets the job done for now.\n *\n * @this {Disk}\n * @param {string} sSymbol\n * @return {Array}\n */\n getSymbolInfo(sSymbol)\n {\n var aInfo = [];\n if (SYMBOLS && this.aFileTable) {\n var sSymbolUpper = sSymbol.toUpperCase();\n for (var iFile = 0; iFile < this.aFileTable.length; iFile++) {\n var file = this.aFileTable[iFile];\n for (var iSegment in file.aSegments) {\n var segment = file.aSegments[iSegment];\n for (var iOrdinal in segment.aEntries) {\n var entry = segment.aEntries[iOrdinal];\n if (entry[1] && entry[1].indexOf(sSymbolUpper) >= 0) {\n aInfo.push([entry[1], file.sName, iSegment, entry[0], segment.offEnd - segment.offStart]);\n }\n }\n }\n }\n }\n return aInfo;\n }\n\n /**\n * getDir(dir, sDisk, sDir, apba)\n *\n * @this {Disk}\n * @param {Object} dir\n * @param {string} sDisk\n * @param {string} sDir\n * @param {Array.<number>} apba\n */\n getDir(dir, sDisk, sDir, apba)\n {\n var file;\n var iStart = this.aFileTable.length;\n var nEntriesPerSector = (dir.cbSector / DiskAPI.DIRENT.LENGTH) | 0;\n\n dir.sDir = sDir + \"\\\\\";\n\n if (DEBUG && this.messageEnabled()) this.printMessage('getDir(\"' + sDisk + '\",\"' + dir.sDir + '\")');\n\n for (var iSector = 0; iSector < apba.length; iSector++) {\n var pba = apba[iSector];\n for (var iEntry = 0; iEntry < nEntriesPerSector; iEntry++) {\n if (!this.getDirEntry(dir, pba, iEntry)) {\n iSector = apba.length;\n break;\n }\n if (dir.sName == null || dir.sName == \".\" || dir.sName == \"..\") continue;\n var sPath = dir.sDir + dir.sName;\n if (DEBUG && this.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.printMessage('\"' + sPath + '\" size=' + dir.cbSize + ' cluster=' + dir.iCluster + ' sectors=' + JSON.stringify(dir.apba));\n if (dir.apba.length) this.printMessage(this.dumpSector(this.getSector(dir.apba[0]), dir.apba[0], sPath));\n }\n file = new FileInfo(this, sPath, dir.sName, dir.bAttr, dir.cbSize, dir.apba);\n this.aFileTable.push(file);\n }\n }\n\n var iEnd = this.aFileTable.length;\n\n for (var i = iStart; i < iEnd; i++) {\n file = this.aFileTable[i];\n if (file.bAttr & DiskAPI.ATTR.SUBDIR && file.apba.length) this.getDir(dir, sDisk, sDir + \"\\\\\" + file.sName, file.apba);\n }\n }\n\n /**\n * getDirEntry(dir, pba, i)\n *\n * This sets the following properties on the 'dir' object:\n *\n * sName (null if invalid/deleted entry)\n * bAttr\n * cbSize\n * iCluster\n * apba (ie, array of physical block addresses)\n *\n * On return, it's the caller's responsibility to copy out any data into a new object\n * if it wants to preserve any of the above information.\n *\n * This function also caches the following properties in the 'dir' object:\n *\n * pbaDirCache (of the last directory sector read, if any)\n * sectorDirCache (of the last directory sector read, if any)\n *\n * Also, the caller must also set the following 'dir' helper properties, so that clusters\n * can be located and converted to sectors (see convertClusterToSectors):\n *\n * lbaFAT\n * lbaData\n * cbSector\n * iClusterMax\n * nClusterSecs\n * nFATBits\n *\n * @this {Disk}\n * @param {Object} dir (to be filled in)\n * @param {number} pba (a sector of the directory)\n * @param {number} i (an entry in the directory sector, 0-based)\n * @returns {boolean} true if entry was returned (even if invalid/deleted), false if no more entries\n */\n getDirEntry(dir, pba, i)\n {\n if (!dir.sectorDirCache || !dir.pbaDirCache || dir.pbaDirCache != pba) {\n dir.pbaDirCache = pba;\n dir.sectorDirCache = this.getSector(dir.pbaDirCache);\n if (DEBUG && this.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.printMessage(this.dumpSector(dir.sectorDirCache, dir.pbaDirCache, dir.sDir));\n }\n }\n if (dir.sectorDirCache) {\n var off = i * DiskAPI.DIRENT.LENGTH;\n var b = this.getSectorData(dir.sectorDirCache, off, 1);\n if (b == DiskAPI.DIRENT.UNUSED) {\n return false;\n }\n if (b == DiskAPI.DIRENT.INVALID) {\n dir.sName = null;\n return true;\n }\n dir.sName = Str.trim(this.getSectorString(dir.sectorDirCache, off + DiskAPI.DIRENT.NAME, 8));\n var s = Str.trim(this.getSectorString(dir.sectorDirCache, off + DiskAPI.DIRENT.EXT, 3));\n if (s.length) dir.sName += '.' + s;\n dir.bAttr = this.getSectorData(dir.sectorDirCache, off + DiskAPI.DIRENT.ATTR, 1);\n dir.cbSize = this.getSectorData(dir.sectorDirCache, off + DiskAPI.DIRENT.SIZE, 2);\n dir.iCluster = this.getSectorData(dir.sectorDirCache, off + DiskAPI.DIRENT.CLUSTER, 2);\n dir.apba = this.convertClusterToSectors(dir);\n return true;\n }\n return false;\n }\n\n /**\n * convertClusterToSectors(dir)\n *\n * @this {Disk}\n * @param {Object} dir\n * @return {Array.<number>} of PBAs (physical block addresses)\n */\n convertClusterToSectors(dir)\n {\n var apba = [];\n var iCluster = dir.iCluster;\n if (iCluster) {\n do {\n if (iCluster < DiskAPI.FAT12.CLUSNUM_MIN) {\n\n break;\n }\n var lba = dir.lbaData + ((iCluster - DiskAPI.FAT12.CLUSNUM_MIN) * dir.nClusterSecs);\n for (var i = 0; i < dir.nClusterSecs; i++) {\n apba.push(dir.pbaVolume + lba++);\n }\n iCluster = this.getClusterEntry(dir, iCluster, 0) | this.getClusterEntry(dir, iCluster, 1);\n } while (iCluster <= dir.iClusterMax);\n\n }\n return apba;\n }\n\n /**\n * getClusterEntry(dir, iCluster, iByte)\n *\n * @this {Disk}\n * @param {Object} dir\n * @param {number} iCluster\n * @param {number} iByte (0 for low byte of cluster entry, 1 for high byte)\n * @return {number}\n */\n getClusterEntry(dir, iCluster, iByte)\n {\n var w = 0;\n var cbitsSector = dir.cbSector * 8;\n var offBits = dir.nFATBits * iCluster + (iByte? 8 : 0);\n var iSector = (offBits / cbitsSector) | 0;\n if (!dir.sectorFATCache || !dir.lbaFATCache || dir.lbaFATCache != dir.lbaFAT + iSector) {\n dir.lbaFATCache = dir.lbaFAT + iSector;\n dir.sectorFATCache = this.getSector(dir.pbaVolume + dir.lbaFATCache);\n }\n if (dir.sectorFATCache) {\n offBits = (offBits % cbitsSector) | 0;\n var off = (offBits >> 3);\n w = this.getSectorData(dir.sectorFATCache, off, 1);\n if (!iByte) {\n if (offBits & 0x7) w >>= 4;\n } else {\n if (dir.nFATBits == 16) {\n w <<= 8;\n } else {\n\n if (offBits & 0x7) {\n w <<= 4;\n } else {\n w = (w & 0xf) << 8;\n }\n }\n }\n }\n return w;\n }\n\n /**\n * getSector(pba)\n *\n * @this {Disk}\n * @param {number} pba (physical block address)\n * @return {Object|null} sector\n */\n getSector(pba)\n {\n var nSectorsPerCylinder = this.nHeads * this.nSectors;\n var iCylinder = (pba / nSectorsPerCylinder) | 0;\n if (iCylinder < this.nCylinders) {\n var nSectorsRemaining = (pba % nSectorsPerCylinder);\n var iHead = (nSectorsRemaining / this.nSectors) | 0;\n /*\n * PBA numbers are 0-based, but the sector numbers in CHS addressing are 1-based, so add one to iSector\n */\n var iSector = (nSectorsRemaining % this.nSectors) + 1;\n return this.seek(iCylinder, iHead, iSector);\n }\n return null;\n }\n\n /**\n * getSectorData(sector, off, len)\n *\n * WARNING: This function is restricted to reading data contained ENTIRELY within the specified sector.\n *\n * NOTE: Yes, this function is not the most efficient way to read a byte/word/dword value from within a sector,\n * but given the different states a sector may be in, it's certainly the simplest and safest, and since this is\n * only used by buildFileTable() and its progeny, it's not clear that we need to be superfast anyway.\n *\n * @this {Disk}\n * @param {Object} sector\n * @param {number} off (byte offset)\n * @param {number} len (1 to 4 bytes)\n * @return {number}\n */\n getSectorData(sector, off, len)\n {\n var dw = 0;\n var nShift = 0;\n\n while (len--) {\n\n var b = this.read(sector, off++);\n\n if (b < 0) break;\n dw |= (b << nShift);\n nShift += 8;\n }\n return dw;\n }\n\n /**\n * getSectorString(sector, off, len)\n *\n * WARNING: This function is restricted to reading a string contained ENTIRELY within the specified sector.\n *\n * @this {Disk}\n * @param {Object} sector\n * @param {number} off (byte offset)\n * @param {number} len (use -1 to read a null-terminated string)\n * @return {string}\n */\n getSectorString(sector, off, len)\n {\n var s = \"\";\n while (len--) {\n var b = this.read(sector, off++);\n if (b <= 0) break;\n s += String.fromCharCode(b);\n }\n return s;\n }\n\n /**\n * updateSector(file, pba, off)\n *\n * Like getSector(), this must convert a PBA into CHS values; consider factoring that conversion code out.\n *\n * @this {Disk}\n * @param {FileInfo} file\n * @param {number} pba (physical block address from the file's apba)\n * @param {number} off (file offset corresponding to the given pba of the given file)\n * @return {boolean} true if successfully updated, false if not\n */\n updateSector(file, pba, off)\n {\n var nSectorsPerCylinder = this.nHeads * this.nSectors;\n var iCylinder = (pba / nSectorsPerCylinder) | 0;\n var nSectorsRemaining = (pba % nSectorsPerCylinder);\n var iHead = (nSectorsRemaining / this.nSectors) | 0;\n var iSector = (nSectorsRemaining % this.nSectors);\n var cylinder, head, sector;\n if ((cylinder = this.aDiskData[iCylinder]) && (head = cylinder[iHead]) && (sector = head[iSector])) {\n\n if (sector['file']) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage('\"' + sector['file'].sPath + '\" cross-linked at offset ' + sector['file'].offFile + ' with \"' + file.sPath + '\" at offset ' + off);\n }\n return false;\n }\n sector['file'] = file;\n sector.offFile = off;\n return true;\n }\n if (DEBUG && this.messageEnabled()) this.printMessage(\"unable to map PBA \" + pba + \" to CHS\");\n return false;\n }\n\n /**\n * initSector(sector, iCylinder, iHead, iSector, cbSector, dwPattern)\n *\n * Ensures every sector has ALL the properties of a proper Sector object; ie:\n *\n * 'sector': sector number\n * 'length': size of the sector, in bytes\n * 'data': array of dwords\n * 'pattern': dword pattern to use for empty or partial sectors (null for unread remote sectors)\n *\n * In addition, we will maintain the following information on a per-sector basis,\n * as sectors are modified:\n *\n * iModify: index of first modified dword in sector\n * cModify: number of modified dwords in sector\n * fDirty: true if sector is dirty, false if clean (or cleaning in progress)\n *\n * @this {Disk}\n * @param {Object} sector\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} [iSector]\n * @param {number} [cbSector]\n * @param {number|null} [dwPattern]\n * @return {Object}\n */\n initSector(sector, iCylinder, iHead, iSector, cbSector, dwPattern)\n {\n if (!sector) {\n sector = {'sector': iSector, 'length': cbSector, 'data': [], 'pattern': dwPattern};\n }\n sector.iCylinder = iCylinder;\n sector.iHead = iHead;\n sector.iModify = sector.cModify = 0;\n sector.fDirty = false;\n return sector;\n }\n\n /**\n * connectRemoteDisk(sDiskPath)\n *\n * Unlike disconnect(), we don't issue the connect request ourselves; instead, we piggyback on the existing\n * preload code in load() to establish the connection. That, in turn, will trigger a call to mount(), which\n * will check fOnDemand and set fRemote if the connection was successful.\n *\n * @this {Disk}\n * @param {string} sDiskPath\n * @return {string} is the URL connection string required to connect to sDiskPath\n */\n connectRemoteDisk(sDiskPath)\n {\n var sParms = DiskAPI.QUERY.ACTION + '=' + DiskAPI.ACTION.OPEN;\n sParms += '&' + DiskAPI.QUERY.VOLUME + '=' + sDiskPath;\n sParms += '&' + DiskAPI.QUERY.MODE + '=' + this.mode;\n sParms += '&' + DiskAPI.QUERY.CHS + '=' + this.nCylinders + ':' + this.nHeads + ':' + this.nSectors + ':' + this.cbSector;\n sParms += '&' + DiskAPI.QUERY.MACHINE + '=' + this.controller.getMachineID();\n sParms += '&' + DiskAPI.QUERY.USER + '=' + this.controller.getUserID();\n return Web.getHost() + DiskAPI.ENDPOINT + '?' + sParms;\n }\n\n /**\n * readRemoteSectors(iCylinder, iHead, iSector, nSectors, fAsync, done)\n *\n * @this {Disk}\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nSectors (to read)\n * @param {boolean} fAsync\n * @param {function(number,boolean)} [done]\n */\n readRemoteSectors(iCylinder, iHead, iSector, nSectors, fAsync, done)\n {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"readRemoteSectors(CHS=\" + iCylinder + ':' + iHead + ':' + iSector + \",N=\" + nSectors + \")\");\n }\n\n if (this.fRemote) {\n var sParms = DiskAPI.QUERY.ACTION + '=' + DiskAPI.ACTION.READ;\n sParms += '&' + DiskAPI.QUERY.VOLUME + '=' + this.sDiskPath;\n sParms += '&' + DiskAPI.QUERY.CHS + '=' + this.nCylinders + ':' + this.nHeads + ':' + this.nSectors + ':' + this.cbSector;\n sParms += '&' + DiskAPI.QUERY.ADDR + '=' + iCylinder + ':' + iHead + ':' + iSector + ':' + nSectors;\n sParms += '&' + DiskAPI.QUERY.MACHINE + '=' + this.controller.getMachineID();\n sParms += '&' + DiskAPI.QUERY.USER + '=' + this.controller.getUserID();\n var disk = this;\n var sDiskURL = Web.getHost() + DiskAPI.ENDPOINT + '?' + sParms;\n Web.getResource(sDiskURL, null, fAsync, function(sURL, sResponse, nErrorCode) {\n disk.doneReadRemoteSectors(sURL, sResponse, nErrorCode, [iCylinder, iHead, iSector, nSectors, fAsync, done]);\n });\n return;\n }\n if (done) done(-1, false);\n }\n\n /**\n * doneReadRemoteSectors(sURLName, sURLData, nErrorCode, aRequest)\n *\n * @this {Disk}\n * @param {string} sURLName\n * @param {string} sURLData\n * @param {number} nErrorCode\n * @param {Array} aRequest ([iCylinder, iHead, iSector, nSectors, fAsync, done])\n */\n doneReadRemoteSectors(sURLName, sURLData, nErrorCode, aRequest)\n {\n var fAsync = false;\n\n var iCylinder = aRequest[0];\n var iHead = aRequest[1];\n var iSector = aRequest[2];\n var nSectors = aRequest[3];\n\n if (!nErrorCode) {\n var abData = JSON.parse(sURLData);\n var offData = 0;\n while (nSectors--) {\n /*\n * We call seek with fWrite == true to prevent seek() from triggering another call\n * to readRemoteSectors() and endlessly recursing. That also forces seek() to:\n *\n * 1) zero the sector's 'pattern'\n * 2) disable warning about reading an uninitialized sector\n *\n * We KNOW this is an uninitialized sector, because we're about to initialize it.\n */\n var sector = this.seek(iCylinder, iHead, iSector, true);\n if (!sector) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"doneReadRemoteSectors(): seek(CHS=\" + iCylinder + ':' + iHead + ':' + iSector + \") failed\");\n }\n break;\n }\n this.fill(sector, abData, offData);\n offData += sector['length'];\n /*\n * We happen to know that when seek() calls readRemoteSectors(), it limits the number of sectors\n * to the current track, so the only variable we need to advance is iSector.\n */\n iSector++;\n }\n fAsync = aRequest[4];\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"doneReadRemoteSectors(CHS=\" + iCylinder + ':' + iHead + ':' + iSector + \",N=\" + nSectors + \") returned error \" + nErrorCode);\n }\n }\n var done = aRequest[5];\n if (done) done(nErrorCode, fAsync);\n }\n\n /**\n * writeRemoteSectors(iCylinder, iHead, iSector, nSectors, abSectors, fAsync)\n *\n * Writes to a remote disk are performed on a timer-driven basis. When a sector is modified for the first time,\n * a reference to that sector is \"pushed\" onto (ie, appended to the end of) aDirtySectors, and if aDirtySectors was\n * originally empty, then a REMOTE_WRITE_DELAY timer is set.\n *\n * When the timer fires, the first batch of contiguous sectors is sent off the server, and when the server responds\n * (ie, when cleanDirtySectors() is called), if the response indicates success, every sector that was sent is marked\n * clean -- unless one or more writes to the sector occurred in the meantime, which we track through a per-sector\n * fDirty flag.\n *\n * @this {Disk}\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nSectors (to write)\n * @param {Array.<number>} abSectors\n * @param {boolean} fAsync\n * @return {boolean|Array}\n */\n writeRemoteSectors(iCylinder, iHead, iSector, nSectors, abSectors, fAsync)\n {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"writeRemoteSectors(CHS=\" + iCylinder + ':' + iHead + ':' + iSector + \",N=\" + nSectors + \")\");\n }\n\n if (this.fRemote) {\n var dataPost = {};\n this.fWriteInProgress = true;\n dataPost[DiskAPI.QUERY.ACTION] = DiskAPI.ACTION.WRITE;\n dataPost[DiskAPI.QUERY.VOLUME] = this.sDiskPath;\n dataPost[DiskAPI.QUERY.CHS] = this.nCylinders + ':' + this.nHeads + ':' + this.nSectors + ':' + this.cbSector;\n dataPost[DiskAPI.QUERY.ADDR] = iCylinder + ':' + iHead + ':' + iSector + ':' + nSectors;\n dataPost[DiskAPI.QUERY.MACHINE] = this.controller.getMachineID();\n dataPost[DiskAPI.QUERY.USER] = this.controller.getUserID();\n dataPost[DiskAPI.QUERY.DATA] = JSON.stringify(abSectors);\n var disk = this;\n var sDiskURL = Web.getHost() + DiskAPI.ENDPOINT;\n Web.getResource(sDiskURL, dataPost, fAsync, function(sURL, sResponse, nErrorCode) {\n disk.doneWriteRemoteSectors(sURL, sResponse, nErrorCode, [iCylinder, iHead, iSector, nSectors, fAsync]);\n });\n }\n return false;\n }\n\n /**\n * doneWriteRemoteSectors(sURLName, sURLData, nErrorCode, aRequest)\n *\n * @this {Disk}\n * @param {string} sURLName\n * @param {string} sURLData\n * @param {number} nErrorCode\n * @param {Array} aRequest ([iCylinder, iHead, iSector, nSectors, fAsync])\n */\n doneWriteRemoteSectors(sURLName, sURLData, nErrorCode, aRequest)\n {\n var iCylinder = aRequest[0];\n var iHead = aRequest[1];\n var iSector = aRequest[2];\n var nSectors = aRequest[3];\n var fAsync = aRequest[4];\n this.fWriteInProgress = false;\n\n if (iCylinder >= 0 && iCylinder < this.aDiskData.length && iHead >= 0 && iHead < this.aDiskData[iCylinder].length) {\n for (var i = iSector - 1; nSectors-- > 0 && i >= 0 && i < this.aDiskData[iCylinder][iHead].length; i++) {\n var sector = this.aDiskData[iCylinder][iHead][i];\n\n if (!nErrorCode) {\n if (!sector.fDirty) {\n sector.iModify = sector.cModify = 0;\n }\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"doneWriteRemoteSectors(CHS=\" + iCylinder + ':' + iHead + ':' + sector['sector'] + \") returned error \" + nErrorCode);\n }\n this.queueDirtySector(sector, false);\n }\n }\n }\n if (fAsync) this.updateWriteTimer();\n }\n\n /**\n * disconnectRemoteDisk()\n *\n * This is called by our powerDown() notification handler. If fRemote is true, we issue the disconnect\n * request and then immediately set fRemote to false; we don't wait for (or test) the response.\n *\n * @this {Disk}\n */\n disconnectRemoteDisk()\n {\n if (this.fRemote) {\n var sParms = DiskAPI.QUERY.ACTION + '=' + DiskAPI.ACTION.CLOSE;\n sParms += '&' + DiskAPI.QUERY.VOLUME + '=' + this.sDiskPath;\n sParms += '&' + DiskAPI.QUERY.MACHINE + '=' + this.controller.getMachineID();\n sParms += '&' + DiskAPI.QUERY.USER + '=' + this.controller.getUserID();\n var sDiskURL = Web.getHost() + DiskAPI.ENDPOINT + '?' + sParms;\n Web.getResource(sDiskURL, null, true);\n this.fRemote = false;\n }\n }\n\n /**\n * queueDirtySector(sector, fAsync)\n *\n * Mark the specified sector as dirty, add it to the queue (aDirtySectors) if not already added,\n * and establish a timeout handler (findDirtySectors) if not already established.\n *\n * A freshly dirtied sector should sit in the queue for a short period of time (eg, 2 seconds)\n * before we attempt to write it; that is, a REMOTE_WRITE_DELAY timer should start ticking again\n * for any sector that is rewritten. However, there will be exceptions; for example, when a sector\n * is finally written, we want to take advantage of the write request to write any additional dirty\n * sectors that follow it, even if those additional sectors were written less than 2 seconds ago.\n *\n * @this {Disk}\n * @param {Object} sector\n * @param {boolean} fAsync (true to update write timer, false to not)\n * @return {boolean} true if write timer set, false if not\n */\n queueDirtySector(sector, fAsync)\n {\n sector.fDirty = true;\n\n var j = this.aDirtySectors.indexOf(sector);\n if (j >= 0) {\n this.aDirtySectors.splice(j, 1);\n this.aDirtyTimestamps.splice(j, 1);\n }\n this.aDirtySectors.push(sector);\n this.aDirtyTimestamps.push(Usr.getTime());\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"queueDirtySector(CHS=\" + sector.iCylinder + ':' + sector.iHead + ':' + sector['sector'] + \"): \" + this.aDirtySectors.length + \" dirty\");\n }\n\n return fAsync && this.updateWriteTimer();\n }\n\n /**\n * updateWriteTimer()\n *\n * If a timer is already active, make sure it's still valid (ie, the time the timer is scheduled to fire is\n * >= the timestamp of the next dirty sector + REMOTE_WRITE_DELAY); if not, cancel the timer and start a new one.\n *\n * @this {Disk}\n * @return {boolean} true if write timer set, false if not\n */\n updateWriteTimer()\n {\n if (this.aDirtySectors.length) {\n var msWrite = this.aDirtyTimestamps[0] + Disk.REMOTE_WRITE_DELAY;\n if (this.timerWrite) {\n if (this.msTimerWrite < msWrite) {\n clearTimeout(this.timerWrite);\n this.timerWrite = null;\n }\n }\n if (!this.timerWrite) {\n var obj = this;\n var msNow = Usr.getTime();\n var msDelay = msWrite - msNow;\n if (msDelay < 0) msDelay = 0;\n if (msDelay > Disk.REMOTE_WRITE_DELAY) msDelay = Disk.REMOTE_WRITE_DELAY;\n this.timerWrite = setTimeout(function() {\n obj.findDirtySectors(true);\n }, msDelay);\n this.msTimerWrite = msNow + msDelay;\n }\n } else {\n if (this.timerWrite) {\n clearTimeout(this.timerWrite);\n this.timerWrite = null;\n }\n }\n return this.timerWrite !== null;\n }\n\n /**\n * findDirtySectors(fAsync)\n *\n * Starting with the oldest dirty sector in the queue (aDirtySectors), determine the longest contiguous stretch of\n * dirty sectors (currently limited to the same track), mark them all as not dirty, and then call writeRemoteSectors().\n *\n * @this {Disk}\n * @param {boolean} fAsync is true if this function is being called asynchronously, false otherwise\n * @return {boolean|Array} false if no dirty sectors, otherwise true (or a response array if not fAsync)\n */\n findDirtySectors(fAsync)\n {\n if (fAsync) {\n this.timerWrite = null;\n }\n var sector = this.aDirtySectors[0];\n if (sector) {\n var iCylinder = sector.iCylinder;\n var iHead = sector.iHead;\n var iSector = sector['sector'];\n var nSectors = 0;\n var abSectors = [];\n for (var i = iSector - 1; i < this.aDiskData[iCylinder][iHead].length; i++) {\n var sectorNext = this.aDiskData[iCylinder][iHead][i];\n if (!sectorNext.fDirty) break;\n var j = this.aDirtySectors.indexOf(sectorNext);\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"findDirtySectors(CHS=\" + iCylinder + ':' + iHead + ':' + sectorNext['sector'] + \")\");\n }\n this.aDirtySectors.splice(j, 1);\n this.aDirtyTimestamps.splice(j, 1);\n abSectors = abSectors.concat(this.toBytes(sectorNext));\n sectorNext.fDirty = false;\n nSectors++;\n }\n\n var response = this.writeRemoteSectors(iCylinder, iHead, iSector, nSectors, abSectors, fAsync);\n return fAsync || response;\n }\n return false;\n }\n\n /**\n * info()\n *\n * @this {Disk}\n * @return {Array} containing: [nCylinders, nHeads, nSectorsPerTrack, nBytesPerSector]\n */\n info()\n {\n if (!this.aDiskData.length) {\n return [0, 0, 0, 0];\n }\n return [this.aDiskData.length, this.aDiskData[0].length, this.aDiskData[0][0].length, this.aDiskData[0][0][0]['length']];\n }\n\n /**\n * seek(iCylinder, iHead, iSector, fWrite, done)\n *\n * TODO: There's some dodgy code in seek() that allows floppy images to be dynamically\n * reconfigured with more heads and/or sectors/track, and it does so by peeking at more drive\n * properties. That code used to be in the FDC component, where it was perfectly reasonable\n * to access those properties. We need a cleaner interface back to the drive, similar to the\n * info() interface we provide to the controller.\n *\n * Whether or not the \"dynamic reconfiguration\" feature itself is perfectly reasonable is,\n * of course, a separate question.\n *\n * @this {Disk}\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {boolean} [fWrite]\n * @param {function(Object,boolean)} [done]\n * @return {Object|null} is the requested sector, or null if not found (or not available yet)\n */\n seek(iCylinder, iHead, iSector, fWrite, done)\n {\n var sector = null;\n var drive = this.drive;\n var cylinder = this.aDiskData[iCylinder];\n if (cylinder) {\n var i;\n var track = cylinder[iHead];\n /*\n * The following code allows a single-sided diskette image to be reformatted (ie, \"expanded\")\n * as a double-sided image, provided the drive has more than one head (see drive.nHeads).\n */\n if (!track && drive.bFormatting && iHead < drive.nHeads) {\n track = cylinder[iHead] = new Array(drive.bSectorEnd);\n for (i = 0; i < track.length; i++) {\n track[i] = this.initSector(null, iCylinder, iHead, i + 1, drive.nBytes, 0);\n }\n /*\n * TODO: This is more dodginess, because we can't be certain that every cylinder on the disk\n * will receive the same \"expanded\" treatment, but functions like getSector() rely on instance\n * properties (eg, this.nHeads), on the assumption that the disk's geometry is homogeneous.\n */\n if (this.nHeads <= iHead) this.nHeads = iHead + 1;\n }\n if (track) {\n for (i = 0; i < track.length; i++) {\n if (track[i] && track[i]['sector'] == iSector) {\n /*\n * If the sector's pattern is null, then this sector's true contents have not yet\n * been fetched from the server.\n */\n sector = track[i];\n if (sector['pattern'] === null) {\n if (fWrite) {\n /*\n * Optimization: if the caller has explicitly told us that they're about to WRITE to the\n * sector, then we shouldn't need to read it from the server; assume a zero pattern and return.\n */\n sector['pattern'] = 0;\n } else {\n var nSectors = 1;\n /*\n * We know we need to read at least 1 sector, but let's count the number of trailing sectors\n * on the same track that may also be required.\n */\n while (++i < track.length) {\n if (track[i]['pattern'] === null) nSectors++;\n }\n this.readRemoteSectors(iCylinder, iHead, iSector, nSectors, done != null, function onReadRemoteComplete(err, fAsync) {\n if (err) sector = null;\n if (done) { //noinspection JSReferencingMutableVariableFromClosure\n done(sector, fAsync);\n }\n });\n return done? null : sector;\n }\n }\n break;\n }\n }\n /*\n * The following code allows an 8-sector track to be reformatted (ie, \"expanded\") as a 9-sector track.\n */\n if (!sector && drive.bFormatting && drive.bSector == 9) {\n sector = track[i] = this.initSector(null, iCylinder, iHead, drive.bSector, drive.nBytes, 0);\n /*\n * TODO: This is more dodginess, because we can't be certain that every track on the disk\n * will receive the same \"expanded\" treatment, but functions like getSector() rely on instance\n * properties (eg, this.nSectors), on the assumption that the disk's geometry is homogeneous.\n */\n if (this.nSectors < drive.bSector) this.nSectors = drive.bSector;\n }\n }\n }\n if (done) done(sector, false);\n return sector;\n }\n\n /**\n * fill(sector, ab, off)\n *\n * @this {Disk}\n * @param {Object} sector\n * @param {*} ab (technically, this should be typed as Array.<number> but I'm having trouble coercing JSON.parse() to that)\n * @param {number} off\n */\n fill(sector, ab, off)\n {\n var cdw = sector['length'] >> 2;\n var adw = new Array(cdw);\n for (var idw = 0; idw < cdw; idw++) {\n adw[idw] = ab[off] | (ab[off + 1] << 8) | (ab[off + 2] << 16) | (ab[off + 3] << 24);\n off += 4;\n }\n sector['data'] = adw;\n /*\n * TODO: Consider taking this opportunity to shrink 'data' down by the number of dwords at the end of the buffer that\n * contain the same pattern, and setting 'pattern' accordingly.\n */\n }\n\n /**\n * toBytes(sector)\n *\n * @this {Disk}\n * @param {Object} sector\n * @return {Array.<number>} is an array of bytes\n */\n toBytes(sector)\n {\n var cb = sector['length'];\n var ab = new Array(cb);\n var ib = 0;\n var cdw = cb >> 2;\n var adw = sector['data'];\n var dwPattern = sector['pattern'];\n for (var idw = 0; idw < cdw; idw++) {\n var dw = (idw < adw.length? adw[idw] : dwPattern);\n ab[ib++] = dw & 0xff;\n ab[ib++] = (dw >> 8) & 0xff;\n ab[ib++] = (dw >> 16) & 0xff;\n ab[ib++] = (dw >> 24) & 0xff;\n }\n return ab;\n }\n\n /**\n * read(sector, ibSector, fCompare)\n *\n * @this {Disk}\n * @param {Object} sector (returned from a previous seek)\n * @param {number} ibSector a byte index within the given sector\n * @param {boolean} [fCompare] is true if this write-compare read\n * @return {number} the specified (unsigned) byte, or -1 if no more data in the sector\n */\n read(sector, ibSector, fCompare)\n {\n var b = -1;\n if (sector) {\n if (DEBUG && !ibSector && !fCompare && this.messageEnabled()) {\n this.printMessage('read(\"' + this.sDiskFile + '\",CHS=' + sector.iCylinder + ':' + sector.iHead + ':' + sector['sector'] + ')');\n }\n if (ibSector < sector['length']) {\n var adw = sector['data'];\n var idw = ibSector >> 2;\n var dw = (idw < adw.length ? adw[idw] : sector['pattern']);\n b = ((dw >> ((ibSector & 0x3) << 3)) & 0xff);\n }\n }\n return b;\n }\n\n /**\n * write(sector, ibSector, b)\n *\n * @this {Disk}\n * @param {Object} sector (returned from a previous seek)\n * @param {number} ibSector a byte index within the given sector\n * @param {number} b the byte value to write\n * @return {boolean|null} true if write successful, false if write-protected, null if out of bounds\n */\n write(sector, ibSector, b)\n {\n if (this.fWriteProtected)\n return false;\n\n if (DEBUG && !ibSector && this.messageEnabled()) {\n this.printMessage('write(\"' + this.sDiskFile + '\",CHS=' + sector.iCylinder + ':' + sector.iHead + ':' + sector['sector'] + ')');\n }\n\n if (ibSector < sector['length']) {\n if (b != this.read(sector, ibSector, true)) {\n var adw = sector['data'];\n var dwPattern = sector['pattern'];\n var idw = ibSector >> 2;\n var nShift = (ibSector & 0x3) << 3;\n\n /*\n * Ensure every byte up to the specified byte is properly initialized.\n */\n for (var i = adw.length; i <= idw; i++) adw[i] = dwPattern;\n\n if (!sector.cModify) {\n sector.iModify = idw;\n sector.cModify = 1;\n } else if (idw < sector.iModify) {\n sector.cModify += sector.iModify - idw;\n sector.iModify = idw;\n } else if (idw >= sector.iModify + sector.cModify) {\n sector.cModify += idw - (sector.iModify + sector.cModify) + 1;\n }\n adw[idw] = (adw[idw] & ~(0xff << nShift)) | (b << nShift);\n\n if (this.fRemote) this.queueDirtySector(sector, true);\n }\n return true;\n }\n return null;\n }\n\n /**\n * encodeAsBase64()\n *\n * @this {Disk}\n * @return {string}\n */\n encodeAsBase64()\n {\n /*\n * Gross, but simple; more importantly, it works -- at least for disks of typical floppy magnitude.\n */\n var s = \"\", pba = 0, sector;\n while ((sector = this.getSector(pba++))) {\n for (var off = 0, len = sector['length']; off < len; off++) {\n s += String.fromCharCode(this.getSectorData(sector, off, 1));\n }\n }\n return btoa(s);\n }\n\n /**\n * save()\n *\n * The first array entry contains some disk information:\n *\n * [sDiskPath, dwChecksum, nCylinders, nHeads, nSectors, cbSector]\n *\n * Each subsequent entry in the returned array contains the following:\n *\n * [iCylinder, iHead, iSector, iModify, [...]]\n *\n * where [...] is an array of modified dword(s) in the corresponding sector.\n *\n * @this {Disk}\n * @return {Array} of modified sectors\n */\n save()\n {\n var i = 0;\n var deltas = [];\n deltas[i++] = [this.sDiskPath, this.dwChecksum, this.nCylinders, this.nHeads, this.nSectors, this.cbSector];\n if (!this.fRemote && !this.fWriteProtected) {\n var aDiskData = this.aDiskData;\n for (var iCylinder = 0; iCylinder < aDiskData.length; iCylinder++) {\n for (var iHead = 0; iHead < aDiskData[iCylinder].length; iHead++) {\n for (var iSector = 0; iSector < aDiskData[iCylinder][iHead].length; iSector++) {\n var sector = aDiskData[iCylinder][iHead][iSector];\n if (sector && sector.cModify) {\n var mods = [], n = 0;\n var iModify = sector.iModify, iModifyLimit = sector.iModify + sector.cModify;\n while (iModify < iModifyLimit) {\n mods[n++] = sector['data'][iModify++];\n }\n deltas[i++] = [iCylinder, iHead, iSector, sector.iModify, mods];\n }\n }\n }\n }\n }\n if (DEBUG && this.messageEnabled()) {\n this.printMessage('save(\"' + this.sDiskName + '\"): saved ' + (deltas.length - 1) + ' change(s)');\n }\n return deltas;\n }\n\n /**\n * restore(deltas)\n *\n * The first array entry contains some disk information:\n *\n * [sDiskPath, dwChecksum, nCylinders, nHeads, nSectors, cbSector]\n *\n * Each subsequent entry in the supplied array contains the following:\n *\n * [iCylinder, iHead, iSector, iModify, [...]]\n *\n * where [...] is an array of modified dword(s) in the corresponding sector.\n *\n * @this {Disk}\n * @param {Array} deltas\n * @return {number} 0 if no changes applied, -1 if an error occurred, otherwise the number of sectors modified\n */\n restore(deltas)\n {\n /*\n * If deltas is undefined, that's not necessarily an error; the controller may simply be (re)initializing\n * itself (although neither controller should be calling restore() under those conditions anymore).\n */\n var nChanges = 0;\n var sReason = \"unsupported restore format\";\n /*\n * I originally added a check for aDiskData here on the assumption that if there was an error loading\n * a disk image, we will have already notified the user, so any additional errors about differing checksums,\n * failure to restore the disk state, etc, would just be annoying. HOWEVER, HDC will create an empty disk\n * image if its initialization code discovers that no disk was loaded earlier (see verifyDrive). So while\n * checking aDiskData is still a good idea, be aware that it won't necessarily avoid redundant error messages\n * (at least in the case of HDC).\n */\n if (deltas && deltas.length > 0) {\n\n var i = 0;\n var aDiskInfo = deltas[i++];\n\n if (aDiskInfo && aDiskInfo.length >= 2) {\n /*\n * Before getting to the checksum, we have to deal with a new situation: restoring an uninitialized\n * disk image from a complete set of deltas. And that is only possible if the disk was saved with the\n * original disk geometry.\n */\n if (!this.aDiskData.length && aDiskInfo.length >= 6) {\n this.create(DiskAPI.MODE.LOCAL, aDiskInfo[2], aDiskInfo[3], aDiskInfo[4], aDiskInfo[5]);\n /*\n * TODO: Consider setting a flag here that we can check at the end of the restore() function\n * that indicates we should recalculate dwChecksum, because we currently have an inconsistency\n * between local disks that are mounted via buildDisk() and the same disks that are \"remounted\"\n * later by this code; the former has the correct checksum, while the latter has a null checksum.\n *\n * As you can see below, we currently deal with this by simply ignoring null checksums....\n */\n }\n /*\n * v1.01 failed to indicate an error if either one of these failure conditions occurred. Although maybe\n * that's just as well, since v1.01 also failed to properly deal with situations where the user mounted\n * different diskette(s) prior to exiting (hopefully fixed in v1.02).\n *\n * UPDATE: We also check aDiskInfo[0] first, because if it's null, then presumably there was no previous\n * disk, and I'd like the addition of a disk to a machine to not be fatal to the restoration process.\n */\n else if (aDiskInfo[0] != null) {\n if (aDiskInfo[1] != null && this.dwChecksum != null && aDiskInfo[1] != this.dwChecksum) {\n sReason = \"original checksum (\" + aDiskInfo[1] + \") differs from current checksum (\" + this.dwChecksum + \")\";\n nChanges = -2;\n }\n /*\n * Checksum is more important than disk path, and for now, I want the flexibility to move disk images.\n *\n * else if (aDiskInfo[0] != this.sDiskPath) {\n * sReason = \"original path '\" + aDiskInfo[0] + \"' differs from current path '\" + this.sDiskPath + \"'\";\n * nChanges = -1;\n * }\n */\n }\n }\n\n if (!this.aDiskData.length) nChanges = -1;\n\n while (i < deltas.length && nChanges >= 0) {\n var m = 0;\n var mod = deltas[i++];\n var iCylinder = mod[m++];\n var iHead = mod[m++];\n var iSector = mod[m++];\n /*\n * Note the buried test for write-protection. Yes, an invariant condition should be tested\n * outside the loop, not inside, but (a) it's a trivial test, (b) the test should never fail\n * because save() should never generate any mods for a write-protected disk, and (c) it\n * centralizes all the failure conditions we're currently checking (which, admittedly, ain't much).\n */\n if (iCylinder >= this.aDiskData.length || iHead >= this.aDiskData[iCylinder].length || iSector >= this.aDiskData[iCylinder][iHead].length) {\n sReason = \"sector (CHS=\" + iCylinder + ':' + iHead + ':' + iSector + \") out of range (\" + nChanges + \" changes applied)\";\n nChanges = -1;\n break;\n }\n if (this.fWriteProtected) {\n sReason = \"unable to modify write-protected disk\";\n nChanges = -1;\n break;\n }\n var iModify = mod[m++];\n var mods = mod[m++];\n var iModifyLimit = iModify + mods.length;\n var sector = this.aDiskData[iCylinder][iHead][iSector];\n if (!sector) continue;\n /*\n * Since write() now deals with empty/partial sectors, we no longer need to completely \"inflate\"\n * the sector prior to applying modifications. So let's just make sure that the sector is \"inflated\"\n * up to iModify.\n */\n var idw = sector['data'].length;\n while (idw < iModify) {\n sector['data'][idw++] = sector['pattern'];\n }\n var n = 0;\n sector.iModify = iModify;\n sector.cModify = mods.length;\n while (iModify < iModifyLimit) {\n sector['data'][iModify++] = mods[n++];\n }\n nChanges++;\n }\n }\n\n if (nChanges < 0) {\n /*\n * We're suppressing checksum messages for the general public for now....\n */\n if (DEBUG || nChanges != -2) {\n this.notice(\"Unable to restore disk '\" + this.sDiskName + \": \" + sReason);\n }\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage('restore(\"' + this.sDiskName + '\"): restored ' + nChanges + ' change(s)');\n }\n /*\n * Last but not least, rebuild the disk's file table if BACKTRACK or SYMBOLS support is enabled.\n */\n if (BACKTRACK || SYMBOLS) this.buildFileTable();\n }\n return nChanges;\n }\n\n /**\n * convertToJSON(fFormatted)\n *\n * We perform some RegExp massaging on the JSON data to eliminate unnecessary properties\n * (eg, 'length' values of 512, 'pattern' values of 0, and empty 'data' arrays, since those\n * are defaults).\n *\n * In addition, we first check every sector to see if it can be \"deflated\". Sectors that were\n * initially \"deflated\" should remain that way unless/until they were modified, so technically,\n * we could call deflateSector() just for modified sectors, but this isn't a common operation,\n * so it doesn't hurt to check every sector.\n *\n * @this {Disk}\n * @param {boolean} [fFormatted]\n * @return {string} containing the entire disk image as JSON-encoded data\n */\n convertToJSON(fFormatted)\n {\n var s, pba = 0, sector, sectorLast;\n\n while ((sector = this.getSector(pba++))) {\n this.deflateSector(sector);\n }\n\n s = JSON.stringify(this.aDiskData, function(key, value) {\n /*\n * If BACKTRACK support is enabled, we have to filter out any 'file' properties that may\n * be attached to the sector objects, lest we risk blowing the stack due to circular references.\n */\n if (key == 'file') {\n return undefined;\n }\n return value;\n });\n\n /*\n * Eliminate unnecessary default properties (eg, 'length' values of 512, 'pattern' values of 0, etc).\n */\n s = s.replace(/,\"length\":512/g, \"\").replace(/,\"pattern\":0/g, \"\").replace(/,\"data\":\\[]/g, \"\");\n\n /*\n * I don't really want to strip quotes from disk image property names, since I would have to put them\n * back again during mount() -- or whenever JSON.parse() is used instead of eval(). But I still remove\n * them temporarily, so that any remaining property names (eg, \"iModify\", \"cModify\", \"fDirty\") can\n * easily be stripped out, by virtue of their being the only quoted properties left. We then \"requote\"\n * all the property names that remain.\n */\n s = s.replace(/\"(sector|length|data|pattern)\":/g, \"$1:\");\n\n /*\n * The next line will remove any other numeric or boolean properties that were added at runtime, although\n * they may have completely different (\"minified\") names if the code has been compiled.\n */\n s = s.replace(/,\"[^\"]*\":([0-9]+|true|false)/g, \"\");\n s = s.replace(/(sector|length|data|pattern):/g, \"\\\"$1\\\":\");\n\n /*\n * Last but not least, insert line breaks after every object definition, to improve human readability\n * (but only if the caller asks for it).\n */\n if (fFormatted) s = s.replace(/([\\]}]),/g, \"$1,\\n\");\n return s;\n }\n\n /**\n * deflateSector(sector)\n *\n * This is just the first revision: it currently looks only at fully inflated sectors.\n *\n * @this {Disk}\n * @param {Object} sector\n */\n deflateSector(sector)\n {\n var adw = sector['data'];\n var cdw = adw.length;\n if ((cdw << 2) == sector['length']) {\n var idw = cdw - 1;\n var dwPattern = adw[idw], cDupes = 0;\n while (idw--) {\n if (adw[idw] !== dwPattern) break;\n cDupes++;\n }\n if (cDupes++) {\n adw.length = cdw - cDupes;\n sector['pattern'] = dwPattern;\n }\n }\n }\n\n /**\n * dumpSector(sector, pba, sDesc)\n *\n * @this {Disk}\n * @param {Object} sector (returned from a previous seek)\n * @param {number} [pba]\n * @param {string} [sDesc]\n * @return {string}\n */\n dumpSector(sector, pba, sDesc)\n {\n var sDump = \"\";\n if (DEBUG && sector) {\n if (pba != null) sDump += \"sector \" + pba + (sDesc? (\" for \" + sDesc) : \"\") + ':';\n var sBytes = \"\", sChars = \"\";\n var cbSector = sector['length'];\n var cdwData = sector['data'].length;\n var dw = 0;\n for (var i = 0; i < cbSector; i++) {\n if ((i % 16) === 0) {\n if (sDump) sDump += sBytes + ' ' + sChars + '\\n';\n sDump += Str.toHex(i, 4) + \": \";\n sBytes = sChars = \"\";\n }\n if ((i % 4) === 0) {\n var idw = i >> 2;\n dw = (idw < cdwData? sector['data'][idw] : sector['pattern']);\n }\n var b = dw & 0xff;\n dw >>>= 8;\n sBytes += Str.toHex(b, 2) + (i % 16 == 7? \"-\" : \" \");\n sChars += (b >= 32 && b < 128? String.fromCharCode(b) : \".\");\n }\n if (sBytes) sDump += sBytes + ' ' + sChars;\n }\n return sDump;\n }\n}\n\n/**\n * The default number of milliseconds to wait before writing a dirty sector back to a remote disk image\n *\n * @const {number}\n */\nDisk.REMOTE_WRITE_DELAY = 2000; // 2-second delay\n\n/*\n * A global disk count, used to form unique Disk component IDs (totally optional; for debugging purposes only)\n */\nDisk.nDisks = 0;\n\n/**\n * class FileInfo\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass FileInfo {\n /**\n * FileInfo(disk, sPath, sName, bAttr, cbSize, apba)\n *\n * To the basic file information below, loadSymbols() may also add:\n *\n * sModule\n * sDescription\n * aSegments[]\n *\n * which is indexed by 1-based segment numbers, where each aSegments[] element is an object\n * containing:\n *\n * offStart (file-relative offset of start of segment data)\n * offEnd (file-relative offset of end of segment data)\n * aEntries[]\n *\n * where aEntries is an array indexed by 1-based ordinals, where each aEntries[] element contains:\n *\n * [offset, symbol]\n *\n * where offset is relative to the segment's offStart value, and symbol is a string describing the\n * entry.\n *\n * NOTE: Although aEntries arrays are similar to the Debugger's aOffsets arrays, they are not\n * interchangeable data structures, because ours is ordered by ordinal, whereas aOffsets is\n * ordered by offset. We provide an interface, getModuleInfo(), to the Debugger that converts\n * our data into an intermediate array, aSymbols, which the Debugger then uses to build aOffsets.\n * It would be nice to avoid building that intermediate representation, but it's a side-effect of\n * the Debugger's earlier support for JSON-encoded MAP files.\n *\n * There will always be an offset at index 0 of an aEntries[] element, but some error or incomplete\n * symbolic information could result in a missing symbol at index 1, because symbol name processing is\n * separate from entry table processing.\n *\n * @param {Disk} disk\n * @param {string} sPath\n * @param {string} sName\n * @param {number} bAttr\n * @param {number} cbSize\n * @param {Array.<number>} apba\n */\n constructor(disk, sPath, sName, bAttr, cbSize, apba)\n {\n this.disk = disk;\n this.sPath = sPath;\n this.sName = sName;\n this.bAttr = bAttr;\n this.cbSize = cbSize;\n this.apba = apba;\n }\n\n /**\n * loadValue(offset, length)\n *\n * @this {FileInfo}\n * @param {number} offset\n * @param {number} [length] (1, 2 or 4 bytes; default is 2)\n * @return {number|undefined}\n */\n loadValue(offset, length)\n {\n var l;\n length = length || 2;\n var iSector = offset >> 9;\n var offSector = offset & 0x1ff;\n var sector = this.disk.getSector(this.apba[iSector]);\n if (sector) {\n /*\n * If the read is wholly contained within a sector, read it with one call.\n */\n if (offSector + length <= sector['length']) {\n return this.disk.getSectorData(sector, offSector, length);\n }\n /*\n * The spans a sector boundary, so we just call ourselves one byte at a time.\n */\n l = 0;\n var shift = 0;\n while (length--) {\n l |= this.loadValue(offset++, 1) << shift;\n shift += 8;\n }\n }\n return l;\n }\n\n /**\n * loadString(offset, length)\n *\n * @this {FileInfo}\n * @param {number} offset\n * @param {number} [length] (if omitted, then string must be zero-terminated)\n * @return {string}\n */\n loadString(offset, length)\n {\n var s = \"\";\n if (!length) length = -1;\n while (length--) {\n var b = this.loadValue(offset++, 1);\n if (!b) break;\n s += String.fromCharCode(b);\n }\n return s;\n }\n\n /**\n * loadField(aField, offset)\n *\n * @this {FileInfo}\n * @param {Array.<number>} aField\n * @param {number} [offset] (0 if not specified)\n * @return {number|undefined}\n */\n loadField(aField, offset)\n {\n return this.loadValue(aField[0] + (offset || 0), aField[1]);\n }\n\n /**\n * loadSegmentTable(offEntries, nEntries, nSegOffShift)\n *\n * @this {FileInfo}\n * @param {number} offEntries\n * @param {number} nEntries\n * @param {number} nSegOffShift\n */\n loadSegmentTable(offEntries, nEntries, nSegOffShift)\n {\n /*\n * Read the Segment Table entries now.\n */\n var iSegment = 1;\n this.aSegments = [];\n this.aOrdinals = []; // this is an optional array for quick ordinal-to-segment lookup\n\n if (DEBUG && this.disk.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.disk.printMessage(\"loadSegmentTable(\" + this.sPath + \",\" + Str.toHexLong(offEntries) + \",\" + Str.toHexWord(nEntries) + \")\");\n }\n\n while (nEntries--) {\n var offSegment = this.loadValue(offEntries) << nSegOffShift;\n if (offSegment) {\n var lenSegment = this.loadValue(offEntries + 2) || 0x10000; // 0 means 64K\n\n if (DEBUG && this.disk.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.disk.printMessage(\"segment \" + iSegment + \": offStart=\" + Str.toHexLong(offSegment) + \" offEnd=\" + Str.toHexLong(offSegment + lenSegment));\n }\n\n this.aSegments[iSegment++] = {offStart: offSegment, offEnd: offSegment + lenSegment - 1, aEntries: []};\n }\n offEntries += 8;\n }\n /*\n * Although not documented (at least not in any of the early Windows \"New Executable\" documents I've seen),\n * the Entry Table may also contain entries whose bSegment field is 0xFE, which doesn't correspond to a valid\n * segment number. That pseudo-segment number appears to be reserved for constants. Here are some examples\n * from a 3.1-vintage KRNL386.EXE:\n *\n * cannot find segment 254 (offset 0xF000) for symbol __ROMBIOS with ordinal 173\n * cannot find segment 254 (offset 0x0000) for symbol __0000H with ordinal 183\n * cannot find segment 254 (offset 0x0040) for symbol __0040H with ordinal 193\n * cannot find segment 254 (offset 0x0008) for symbol __AHINCR with ordinal 114\n * cannot find segment 254 (offset 0x0003) for symbol __AHSHIFT with ordinal 113\n * cannot find segment 254 (offset 0xA000) for symbol __A000H with ordinal 174\n * cannot find segment 254 (offset 0xB000) for symbol __B000H with ordinal 181\n * cannot find segment 254 (offset 0xC000) for symbol __C000H with ordinal 195\n * cannot find segment 254 (offset 0xB800) for symbol __B800H with ordinal 182\n * cannot find segment 254 (offset 0xD000) for symbol __D000H with ordinal 179\n * cannot find segment 254 (offset 0xE000) for symbol __E000H with ordinal 190\n * cannot find segment 254 (offset 0xF000) for symbol __F000H with ordinal 194\n * cannot find segment 254 (offset 0x0001) for symbol __WINFLAGS with ordinal 178\n *\n * The simplest way to handle those Entry Table entries is creating an additional (fake) aSegments table entry.\n */\n this.aSegments[0xFE] = {offStart: 0, offEnd: 0, aEntries: []};\n }\n\n /**\n * loadEntryTable(offEntries, offEntriesEnd)\n *\n * @this {FileInfo}\n * @param {number} offEntries\n * @param {number} offEntriesEnd\n */\n loadEntryTable(offEntries, offEntriesEnd)\n {\n var iOrdinal = 1;\n\n if (DEBUG && this.disk.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.disk.printMessage(\"loadEntryTable(\" + Str.toHexLong(offEntries) + \",\" + Str.toHexLong(offEntriesEnd) + \")\");\n }\n\n while (offEntries < offEntriesEnd) {\n\n var w = this.loadValue(offEntries);\n var bEntries = w & 0xff;\n if (!bEntries) break;\n var bSegment = w >> 8, iSegment;\n\n if (DEBUG && this.disk.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.disk.printMessage(\"bundle for segment \" + bSegment + \": \" + bEntries + \" entries @\" + Str.toHex(offEntries));\n }\n\n offEntries += 2;\n\n /*\n * bSegment 0x00 means all the entries spanned by bEntries are unused, so move on.\n */\n if (!bSegment) {\n iOrdinal += bEntries;\n continue;\n }\n while (bEntries--) {\n /*\n * bSegment 0x01-0xFE means the next 3 bytes describe a fixed segment entry; the next\n * byte contains flags indicating exported (0x1) and/or global/shared (0x2) data, and the\n * next word is the offset within the segment.\n */\n var offEntry;\n var offDebug = offEntries;\n var bFlags = this.loadValue(offEntries, 1);\n\n if (bSegment <= 0xFE) {\n iSegment = bSegment;\n offEntry = this.loadValue(offEntries + 1);\n offEntries += 3;\n } else {\n /*\n * bSegment 0xFF means a movable segment entry, which is 6 bytes long: flags byte (which\n * we've already read), an INT 0x3F (0xCD,0x3F), a 1-byte segment number, and a 2-byte offset.\n */\n iSegment = this.loadValue(offEntries + 3, 1);\n offEntry = this.loadValue(offEntries + 4);\n offEntries += 6;\n }\n if (!this.aSegments[iSegment]) {\n if (DEBUG && this.disk.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.disk.printMessage(\"invalid segment: \" + iSegment);\n }\n } else {\n this.aSegments[iSegment].aEntries[iOrdinal] = [offEntry];\n if (DEBUG && this.disk.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.disk.printMessage(\"ordinal \" + iOrdinal + \": segment=\" + iSegment + \" offset=\" + Str.toHexLong(offEntry) + \" @\" + Str.toHex(offDebug));\n }\n }\n this.aOrdinals[iOrdinal] = [iSegment, offEntry];\n iOrdinal++;\n }\n }\n }\n\n /**\n * loadNameTable(aField, offset)\n *\n * NOTE: If offset is omitted, we assume we're reading the Resident Name Table, and therefore\n * the first name is the module name; otherwise, we assume it is the Non-Resident Name Table, and\n * that the first name is the module description.\n *\n * @this {FileInfo}\n * @param {number} offEntries\n * @param {number} [offEntriesEnd] (if omitted, then the table must be null-terminated)\n */\n loadNameTable(offEntries, offEntriesEnd)\n {\n var cNames = 0;\n\n if (DEBUG && this.disk.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.disk.printMessage(\"loadNameTable(\" + Str.toHexLong(offEntries) + (offEntriesEnd? (\",\" + Str.toHexLong(offEntriesEnd)) : \"\") + \")\");\n }\n\n while (!offEntriesEnd || offEntries < offEntriesEnd) {\n\n var offDebug = offEntries;\n var bLength = this.loadValue(offEntries, 1);\n if (!bLength) break;\n\n var sSymbol = this.loadString(offEntries + 1, bLength);\n if (!sSymbol) break; // an error must have occurred (this is not a natural way to end)\n offEntries += 1 + bLength;\n\n if (!cNames) {\n if (!offEntriesEnd) {\n this.sModule = sSymbol;\n } else {\n this.sDescription = sSymbol;\n }\n }\n else {\n var iOrdinal = this.loadValue(offEntries);\n var tuple = this.aOrdinals[iOrdinal];\n if (tuple) {\n var iSegment = tuple[0]; // tuple[0] is the segment number and tuple[1] is the corresponding offEntry\n if (this.aSegments[iSegment]) {\n var aEntries = this.aSegments[iSegment].aEntries[iOrdinal];\n\n aEntries.push(sSymbol);\n if (DEBUG && this.disk.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.disk.printMessage(\"segment \" + iSegment + \" offset \" + Str.toHexWord(aEntries[0]) + \" ordinal \" + iOrdinal + \": \" + sSymbol + \" @\" + Str.toHex(offDebug));\n }\n } else {\n if (DEBUG && this.disk.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.disk.printMessage(this.sPath + \": cannot find segment \" + iSegment + \" (offset \" + Str.toHexWord(tuple[1]) + \") for symbol \" + sSymbol + \" with ordinal \" + iOrdinal + \" @\" + Str.toHex(offDebug));\n }\n }\n } else {\n if (DEBUG && this.disk.messageEnabled(Messages.DISK | Messages.DATA)) {\n this.disk.printMessage(this.sPath + \": cannot find ordinal \" + iOrdinal + \" for symbol \" + sSymbol + \" @\" + Str.toHex(offDebug));\n }\n }\n }\n offEntries += 2;\n cNames++;\n }\n }\n\n /**\n * loadSymbols()\n *\n * For files with NE headers, extract all available symbolic information from the file.\n *\n * @this {FileInfo}\n */\n loadSymbols()\n {\n if (!Str.endsWith(this.sName, \".EXE\") && !Str.endsWith(this.sName, \".DLL\") && !Str.endsWith(this.sName, \".DRV\")) {\n return;\n }\n\n if (this.loadField(FileInfo.OE.oeSignature) != FileInfo.OE.SIG) {\n return;\n }\n\n if (this.loadField(FileInfo.OE.oeRelocOffset) != FileInfo.OE.NE_SIG) {\n return;\n }\n\n var offNEHeader = this.loadField(FileInfo.OE.oeNEHeader);\n if (this.loadField(FileInfo.NE.neSignature, offNEHeader) != FileInfo.NE.SIG) {\n return;\n }\n\n var nEntries = this.loadField(FileInfo.NE.neSTEntries, offNEHeader);\n var offEntries = this.loadField(FileInfo.NE.neSTOffset, offNEHeader);\n var nSegOffShift = this.loadField(FileInfo.NE.neSegOffShift, offNEHeader);\n\n if (offEntries && nEntries) {\n this.loadSegmentTable(offEntries + offNEHeader, nEntries, nSegOffShift || 0);\n }\n\n offEntries = this.loadField(FileInfo.NE.neETOffset, offNEHeader);\n var cbEntries = this.loadField(FileInfo.NE.neETSize, offNEHeader);\n if (offEntries && cbEntries) {\n this.loadEntryTable(offEntries += offNEHeader, offEntries + cbEntries);\n }\n\n /*\n * Time to walk the Resident Name Table and update the corresponding ordinals.\n */\n offEntries = this.loadField(FileInfo.NE.neRNTOffset, offNEHeader);\n if (offEntries) {\n this.loadNameTable(offEntries + offNEHeader);\n }\n\n /*\n * Ditto for the Non-Resident Name Table, which for some reason, uses a file-relative offset rather than\n * an NE header-relative offset, and which is both sized AND null-terminated; we check both terminating\n * conditions to be safe.\n */\n offEntries = this.loadField(FileInfo.NE.neNRNTOffset, offNEHeader);\n cbEntries = this.loadField(FileInfo.NE.neNRNTSize, offNEHeader);\n if (offEntries && cbEntries) {\n this.loadNameTable(offEntries, offEntries + cbEntries);\n }\n }\n\n /**\n * getSymbol(off, fNearest)\n *\n * @this {FileInfo}\n * @param {number} off (offset relative to start of file)\n * @param {boolean} [fNearest] (true to return nearest symbol if a segment with symbols is found)\n * @return {string} symbol corresponding to file offset (of the file name + offset if no symbol found)\n */\n getSymbol(off, fNearest)\n {\n var sSymbol = null;\n if (this.aSegments) {\n for (var iSegment in this.aSegments) {\n var segment = this.aSegments[iSegment];\n if (off >= segment.offStart && off <= segment.offEnd) {\n /*\n * This is the one and only segment we need to check, so we can make off segment-relative now.\n */\n off -= segment.offStart;\n /*\n * To support fNearest, save the entry where (off - entry[0]) yields the smallest positive result.\n */\n var cbNearest = off, entryNearest;\n for (var iOrdinal in segment.aEntries) {\n var entry = segment.aEntries[iOrdinal];\n var cb = off - entry[0];\n if (!cb) {\n sSymbol = this.sModule + '!' + entry[1];\n break;\n }\n if (fNearest && cb > 0 && cb < cbNearest) {\n entryNearest = entry;\n cbNearest = cb;\n }\n }\n if (!sSymbol && entryNearest) {\n sSymbol = this.sModule + '!' + entryNearest[1] + \"+\" + Str.toHex(cbNearest, 0, true);\n }\n break;\n }\n }\n }\n return sSymbol || this.sName + '+' + Str.toHex(off, 0, true);\n }\n}\n\n/*\n * Original (aka \"Old\") Executable MS-DOS File Format\n *\n * Relocation entries are pairs of 16-bit words:\n *\n * wOffset\n * wSegment\n *\n * I've noticed that a \"PKLITE\" EXE may have a oeRelocOffset of 0x52, where the word at 0x001C is 0x210F and the\n * bytes from 0x001E through 0x0051 are:\n *\n * \"PKLITE Copr. 1990-92 PKWARE Inc. All Rights Reserved\"\n *\n * Other EXEs have a oeRelocOffset of 0x1E, which begs the question: what is the word at 0x001C typically used for?\n *\n * It was not uncommon for there to be wasted space in the header; even an EXE with, say, 20 (0x14) entries would\n * likely have a wHeaderParas value of 0x20, which is 512 (0x200) bytes. The desire, no doubt, was to align the\n * start of the EXE segment(s) to a traditional sector boundary.\n */\nFileInfo.OE = {\n SIG: 0x5A4D,\n oeSignature: [0x0000, 2], // \"MZ\" (0x4D,0x5A)\n oeLastBytes: [0x0002, 2], // 0-511 (0 means the entire last block is used)\n oeBlocks: [0x0004, 2], // number of blocks in the file\n oeRelocEntries: [0x0006, 2], // number of relocation entries in the header\n oeHeaderParas: [0x0008, 2], // number of (16-byte) paragraphs in the header\n oeExtraParas: [0x000A, 2], // minimum number of additional paragraphs required at load-time\n oeMaxParas: [0x000C, 2], // maximum number of additional paragraphs required at load-time\n oeSSRel: [0x000E, 2], // relative value of SS\n oeSPInit: [0x0010, 2], // initial value of SP\n oeChecksum: [0x0012, 2], // checksum if non-zero (sum of all words, including this, should be zero)\n oeIPInit: [0x0014, 2], // initial value of IP\n oeCSRel: [0x0016, 2], // relative value of CS\n oeRelocOffset: [0x0018, 2], // offset of first relocation item\n oeOverlay: [0x001A, 2], // overlay number (normally zero, implying main program)\n /*\n * The following fields are accommodated by the NE format, but they were actually defined by \"the DOS 4.0 group\"\n * as extensions to the OE format.\n */\n oeDOS40Bits: [0x0020, 2], // DOS 4.0 behavior bits\n oeUnusedBits: [0x0022, 2], // unused behavior bits\n /*\n * If oeRelocOffset (0x0018) is 0x40, then the file is considered an NE (New Executable) MS-DOS file, and\n * the offset of the NE header (from the start of the file) is a 32-bit value stored at 0x003C. Note that early\n * versions of Windows (aka \"DOS 2.0 Windows\") originally defined the NE header offset as a 16-bit value stored\n * at 0x003E. And before that, it may have been a 16-bit value stored at 0x0024, which would have been immediately\n * after the \"behavior bits\" fields shown above).\n */\n oeNEHeader: [0x003C, 4], // offset from start of file to NE header\n NE_SIG: 0x40\n};\n\n/*\n * New Executable MS-DOS File Format\n *\n * Unless otherwise specified, all *Offset fields are relative to the start of the NE header, and all *Size fields\n * are in bytes.\n */\nFileInfo.NE = {\n SIG: 0x454E,\n neSignature: [0x0000, 2], // \"NE\" (0x4E,0x45)\n neLinkerVer: [0x0002, 2], // (low byte is version, high byte is revision)\n neETOffset: [0x0004, 2], // Entry Table offset\n neETSize: [0x0006, 2], // Entry Table size\n neChecksum: [0x0008, 4], // checksum (sum of all DWORDs in the file, excluding this one)\n neFlags: [0x000C, 2],\n neDataSeg: [0x000E, 2],\n neHeapSize: [0x0010, 2],\n neStackSize: [0x0012, 2],\n neCSIP: [0x0014, 4],\n neSSSP: [0x0018, 4],\n neSTEntries: [0x001C, 2], // Segment Table entries\n neMRTEntries: [0x001E, 2], // Module Reference Table entries\n neNRNTSize: [0x0020, 2], // Non-Resident Name Table size\n neSTOffset: [0x0022, 2], // Segment Table offset\n neRTOffset: [0x0024, 2], // Resource Table offset\n neRNTOffset: [0x0026, 2], // Resident Name Table offset\n neMRTOffset: [0x0028, 2], // Module Reference Table offset\n neINTOffset: [0x002A, 2], // Imported Names Table offset\n neNRNTOffset: [0x002C, 4], // Non-Resident Name Table offset (relative to start of file)\n neETMovable: [0x0030, 2], // number of movable entries in the Entry Table\n neSegOffShift: [0x0032, 2], // logical sector alignment shift count, log(base 2) of the segment sector size (default 9)\n /*\n * Fields after this point are post \"DOS 2.0 Windows\"...\n */\n neRTEntries: [0x0034, 2], // Resource Table entries\n neEXEType: [0x0036, 1] // executable type (0x02 for Windows)\n /*\n * 0x37 through 0x3F is reserved.\n */\n};\n\n/**\n * Every Sector object (once loaded, parsed, and \"normalized\") should have ALL of the following named properties:\n *\n * 'sector': sector number\n * 'length': size of the sector, in bytes\n * 'data': array of dwords\n * 'pattern': dword pattern to use for empty or partial sectors (or null if sector still needs to be loaded)\n *\n * initSector() also sets the following properties, to help us quickly identify its location within aDiskData:\n *\n * iCylinder\n * iHead\n *\n * In addition, we will maintain the following information on a per-sector basis, as sectors are modified:\n *\n * iModify: index of first modified dword in sector\n * cModify: number of modified dwords in sector\n * fDirty: true if sector is dirty, false if clean (or cleaning in progress)\n *\n * fDirty is used in conjunction with \"demandrw\" disks; it is set to true whenever the sector is modified, and is\n * set to false whenever the sector has been sent to the server. If the server write succeeds and fDirty is still\n * false, then the sector modifications are removed (cModify is set to zero). If the write succeeds but fDirty was\n * set to true again in the meantime, then all the sector modifications (even those that were just written) remain\n * in place (since we don't keep track of more than one modification range within a sector). And if the write failed,\n * then fDirty is set back to true and again all modifications remain in place; the best we can do is schedule another\n * write attempt.\n *\n * TODO: Perhaps we should also maintain a failure count and stop trying to write sectors that reach a certain\n * threshold. Error-handling, as usual, is the thorniest problem.\n *\n * @typedef {{\n * sector: number,\n * length: number,\n * data: Array.<number>,\n * pattern: (number|null),\n * iCylinder: number,\n * iHead: number,\n * iModify: number,\n * cModify: number,\n * file: FileInfo,\n * offFile: number\n * }}\n */\nvar SectorInfo;\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/fdc.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * FDC Terms (see FDC.TERMS)\n *\n * C Cylinder Number the current or selected cylinder number\n *\n * D Data the data pattern to be written to a sector\n *\n * DS Drive Select the selected driver number encoded the same as bits 0 and 1 of the Digital Output\n * Register (DOR); eg, DS0, DS1, DS2, or DS3\n *\n * DTL Data Length when N is 00, DTL is the data length to be read from or written to a sector\n *\n * EOT End Of Track the final sector number on a cylinder\n *\n * GPL Gap Length the length of gap 3 (spacing between sectors excluding the VCO synchronous field)\n *\n * H Head Address the head number, either 0 or 1, as specified in the ID field\n *\n * HD Head the selected head number, 0 or 1 (H = HD in all command words)\n *\n * HLT Head Load Time the head load time in the selected drive (2 to 256 milliseconds in 2-millisecond\n * increments for the 1.2M-byte drive and 4 to 512 milliseconds in 4 millisecond increments\n * for the 320K-byte drive)\n *\n * HUT Head Unload Time the head unload time after a read or write operation (0 to 240 milliseconds in\n * 16-millisecond increments for the 1.2M-byte drive and 0 to 480 milliseconds in\n * 32-millisecond increments for the 320K-byte drive)\n *\n * MF FM or MFM Mode 0 selects FM mode and 1 selects MFM (MFM is selected only if it is implemented)\n *\n * MT Multitrack 1 selects multitrack operation (both HD0 and HD1 will be read or written)\n *\n * N Number the number of data bytes written in a sector\n *\n * NCN New Cylinder Number the new cylinder number for a SEEK operation\n *\n * ND Non-Data Mode indicates an operation in the non-data mode\n *\n * PCN Present Cylinder Number the cylinder number at the completion of a SENSE INTERRUPT STATUS command\n * (present position of the head)\n *\n * R Record the sector number to be read or written\n *\n * SC Sectors Per Cylinder the number of sectors per cylinder\n *\n * SK Skip this stands for skip deleted-data address mark\n *\n * SRT Stepping Rate this 4 bit byte indicates the stepping rate for the diskette drive as follows:\n * 1.2M-Byte Diskette Drive: 1111=1ms, 1110=2ms, 1101=3ms\n * 320K-Byte Diskette Drive: 1111=2ms, 1110=4ms, 1101=6ms\n *\n * STP STP Scan Test if STP is 1, the data in contiguous sectors is compared with the data sent\n * by the processor during a scan operation; if STP is 2, then alternate sections\n * are read and compared\n */\n\n/**\n * class FDC\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass FDC extends Component {\n /**\n * FDC(parmsFDC)\n *\n * The FDC component simulates a NEC µPD765A or Intel 8272A compatible floppy disk controller, and has one\n * component-specific property:\n *\n * autoMount: one or more JSON-encoded objects, each containing 'name' and 'path' properties\n *\n * sortBy: \"name\" to sort disks by name, \"path\" to sort by path, or \"none\" to leave as-is (default is \"name\")\n *\n * Regarding early diskette drives: the IBM PC Model 5150 originally shipped with single-sided drives,\n * and therefore supported only 160Kb diskettes. That's the only diskette format PC-DOS 1.00 supported, too.\n *\n * At some point, 5150's started shipping with double-sided drives, but I'm not sure whether the ROMs changed;\n * they probably did NOT change, because the original ROM BIOS already supported drives with multiple heads.\n * However, what the ROM BIOS did NOT do was provide any indication of drive type, which as far as I can tell,\n * meant you had to simply read/write/format tracks with the second head and check for errors.\n *\n * Presumably at the same time double-sided drives started shipping, PC-DOS 1.10 shipped, which added\n * support for 320Kb diskettes. And the FORMAT command changed as well, defaulting to a double-sided format\n * operation UNLESS you specified \"FORMAT /1\". If I run PC-DOS 1.10 and try to simulate a single-sided drive\n * (by setting drive.nHeads = 1 in initDrive), FORMAT will balk with \"Track 0 bad - disk unusable\". I have to\n * wonder if everyone with single-sided drives who upgraded to PC-DOS 1.10 also got that error, forcing them\n * to always specify \"FORMAT /1\", or if I'm doing something wrong wrt single-sided drive simulation.\n *\n * I've noticed that if I turn FDC messages on (\"m fdc on\"), and then run \"FORMAT B:/1\", the command still\n * tries to format head 1/track 0, followed by head 0/track 0, and then the FDC is reset, and the format operation\n * proceeds with only head 0 for all tracks 0 through 39. FORMAT successfully creates a 160Kb single-sided diskette,\n * but why it also tries to initially format track 0 using the second head remains a bit of a mystery.\n *\n * @this {FDC}\n * @param {Object} parmsFDC\n */\n constructor(parmsFDC)\n {\n /*\n * TODO: Indicate the type of diskette image being loaded (this might help folks understand what's going\n * on when they try to load a diskette image that's larger than what the selected operating system supports).\n */\n super(\"FDC\", parmsFDC, Messages.FDC);\n\n this['dmaRead'] = FDC.prototype.doDMARead;\n this['dmaWrite'] = FDC.prototype.doDMAWrite;\n this['dmaFormat'] = FDC.prototype.doDMAFormat;\n\n /*\n * We record any 'autoMount' object now, but we no longer parse it until initBus(), because the Computer's\n * getMachineParm() service may have an override for us.\n */\n this.configMount = this.parseConfig(parmsFDC['autoMount']);\n\n /*\n * This establishes \"name\" as the default; if we decide we'd prefer \"none\" to be the default (ie, the order\n * to use when no sortBy value is specified), we can just drop the '|| \"name\"', because an undefined value is\n * just as falsey as null.\n *\n * The code that actually performs the sorting (in setBinding()) first checks that sortBy is not falsey, and\n * then assumes that the non-falsey value must be either \"path\" or \"name\", and since it explicitly checks for\n * \"path\" first, any non-sensical value will be treated as \"name\" (which is fine, since that's our current default).\n */\n this.sortBy = parmsFDC['sortBy'] || \"name\";\n if (this.sortBy == \"none\") this.sortBy = null;\n\n /*\n * The following array keeps track of every disk image we've ever mounted. Each entry in the\n * array is another array whose elements are:\n *\n * [0]: name of disk\n * [1]: path of disk\n * [2]: array of deltas, uninitialized until the disk is unmounted and/or all state is saved\n *\n * See functions addDiskHistory() and updateDiskHistory().\n */\n this.aDiskHistory = [];\n\n /*\n * Support for local disk images is currently limited to desktop browsers with FileReader support;\n * when this flag is set, setBinding() allows local disk bindings and informs initBus() to update the\n * \"listDisks\" binding accordingly.\n */\n this.fLocalDisks = (!Web.isMobile() && window && 'FileReader' in window);\n\n /*\n * The remainder of FDC initialization now takes place in our initBus() handler, largely because we\n * want initController() to have access to the ChipSet component, so that it can query switches and/or CMOS\n * settings that determine the number of drives and their characteristics (eg, 40-track vs. 80-track),\n * which it can then pass on to initDrive().\n */\n\n this['exports'] = {\n 'loadDisk': this.loadSelectedDisk,\n 'wait': this.waitDrives\n };\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {FDC}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"listDisks\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var fdc = this;\n /*\n * TODO: Making copies of control that are simply cast to different types seems silly, but it doesn't\n * really cost anything and it's cleaner than doing a lot MORE type overrides inline. However, it still\n * doesn't solve all my problems: controlForm should really be cast as HTMLFormElement, but JavaScript\n * inspections refuse to believe there's an 'onsubmit' property on an HTMLFormElement that I can override.\n */\n var controlForm = /** @type {Object} */ (control);\n var controlSelect = /** @type {HTMLSelectElement} */ (control);\n\n switch (sBinding) {\n\n case \"listDisks\":\n this.bindings[sBinding] = controlSelect;\n /*\n * Since binding is a one-time initialization operation, it's also the perfect time to\n * perform whatever sorting (if any) is indicated by the FDC component's \"sortBy\" property.\n *\n * And since setBinding() is called before initBus(), that means any \"special\" disk entries\n * will be added after the sorting, so we won't be \"burying\" those entries somewhere in the\n * middle.\n */\n if (this.sortBy) {\n var i, aOptions = [];\n /*\n * NOTE: All this monkeying around with copying the elements from control.options to aOptions\n * and then back again is necessary because control.options isn't a *real* Array (at least not\n * in all browsers); consequently, it may have no sort() method. It has a length property,\n * along with numeric properties 0 to length-1, but it's still probably just an Object, not\n * an Array.\n *\n * Also note that changing the order of the control's options would ordinarily mean that the\n * control's selectedIndex may now be incorrect, but in our case, it doesn't matter, because\n * we have a special function, displayDiskette(), that will be called at LEAST once during\n * initialization, ensuring that selectedIndex is set correctly.\n */\n for (i = 0; i < controlSelect.options.length; i++) {\n aOptions.push(controlSelect.options[i]);\n }\n aOptions.sort(function(a, b) {\n /*\n * I've switched to localeCompare() because it offers case-insensitivity by default;\n * I'm still a little concerned that we could somehow end up with list elements whose text\n * and/or value properties are undefined (because calling a method on an undefined variable\n * will throw an exception), but maybe I'm being overly paranoid....\n */\n if (fdc.sortBy != \"path\") {\n return a.text.localeCompare(b.text);\n } else {\n return a.value.localeCompare(b.value);\n }\n });\n for (i = 0; i < aOptions.length; i++) {\n try {\n /*\n * TODO: Determine why this line blows up in IE8; are the properties of an options object not settable in IE8?\n */\n controlSelect.options[i] = aOptions[i];\n } catch(e) {\n break;\n }\n }\n }\n controlSelect.onchange = function onChangeListDisks(event) {\n fdc.updateSelectedDiskette();\n };\n return true;\n\n case \"descDisk\":\n case \"listDrives\":\n this.bindings[sBinding] = controlSelect;\n /*\n * I tried going with onclick instead of onchange, so that if you wanted to confirm what's\n * loaded in a particular drive, you could click the drive control without having to change it.\n * However, that doesn't seem to work for all browsers, so I've reverted to onchange.\n */\n controlSelect.onchange = function onChangeListDrives(event) {\n var iDrive = Str.parseInt(controlSelect.value, 10);\n if (iDrive != null) fdc.displayDiskette(iDrive);\n };\n return true;\n\n case \"loadDisk\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickLoadDisk(event) {\n fdc.loadSelectedDisk();\n };\n return true;\n\n case \"saveDisk\":\n /*\n * Yes, technically, this feature does not require \"Local disk support\" (which is really a reference\n * to FileReader support), but since fLocalDisks is also false for all mobile devices, and since there\n * is an \"orthogonality\" to disabling both features in tandem, let's just let it slide, OK?\n */\n if (!this.fLocalDisks) {\n if (DEBUG) this.log(\"Local disk support not available\");\n /*\n * We could also simply hide the control; eg:\n *\n * control.style.display = \"none\";\n *\n * but removing the control altogether seems better.\n */\n control.parentNode.removeChild(/** @type {Node} */ (control));\n return false;\n }\n this.bindings[sBinding] = control;\n control.onclick = function onClickSaveDisk(event) {\n var controlDrives = fdc.bindings[\"listDrives\"];\n if (controlDrives && controlDrives.options && fdc.aDrives) {\n var iDriveSelected = Str.parseInt(controlDrives.value, 10) || 0;\n var drive = fdc.aDrives[iDriveSelected];\n if (drive) {\n /*\n * Note the similarity (and hence factoring opportunity) between this code and the HDC's\n * \"saveHD*\" binding.\n */\n var disk = drive.disk;\n if (disk) {\n if (DEBUG) fdc.println(\"saving diskette \" + disk.sDiskPath + \"...\");\n var sAlert = Web.downloadFile(disk.encodeAsBase64(), \"octet-stream\", true, disk.sDiskFile.replace(\".json\", \".img\"));\n Component.alertUser(sAlert);\n } else {\n fdc.notice(\"No diskette loaded in drive.\");\n }\n } else {\n fdc.notice(\"No diskette drive selected.\");\n }\n }\n };\n return true;\n\n case \"mountDisk\":\n if (!this.fLocalDisks) {\n if (DEBUG) this.log(\"Local disk support not available\");\n /*\n * We could also simply hide the control; eg:\n *\n * controlForm.style.display = \"none\";\n *\n * but removing the control altogether seems better.\n */\n controlForm.parentNode.removeChild(/** @type {Node} */ (controlForm));\n return false;\n }\n this.bindings[sBinding] = controlForm;\n /*\n * Enable \"Mount\" button only if a file is actually selected\n */\n controlForm.onchange = function onChangeMountDisk() {\n var fieldset = controlForm.children[0];\n var files = fieldset.children[0].files;\n var submit = fieldset.children[1];\n submit.disabled = !files.length;\n };\n controlForm.onsubmit = function onSubmitMountDisk(event) {\n var file = event.currentTarget[1].files[0];\n if (file) {\n var sDiskettePath = file.name;\n var sDisketteName = Str.getBaseName(sDiskettePath, true);\n fdc.loadSelectedDrive(sDisketteName, sDiskettePath, file);\n }\n /*\n * Prevent reloading of web page after form submission\n */\n return false;\n };\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {FDC}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.cmp = cmp;\n\n this.chipset = cmp.getMachineComponent(\"ChipSet\");\n this.parseConfig(this.cmp.getMachineParm('autoMount'), this.configMount);\n\n /*\n * If we didn't need auto-mount support, we could defer controller initialization until we received a powerUp() notification,\n * at which point reset() would call initController(), or restore() would restore the controller; in that case, all we'd need\n * to do here is call setReady().\n */\n this.initController();\n\n bus.addPortInputTable(this, FDC.aPortInput);\n bus.addPortOutputTable(this, FDC.aPortOutput);\n\n this.addDiskette(\"None\", \"\", true);\n if (this.fLocalDisks) this.addDiskette(\"Local Disk\", \"?\");\n this.addDiskette(\"Remote Disk\", \"??\");\n\n if (!this.autoMount()) this.setReady();\n }\n\n /**\n * parseConfig(config, configMerge)\n *\n * @this {FDC}\n * @param {Object|string|undefined} config\n * @param {Object} [configMerge]\n * @return {Object}\n */\n parseConfig(config, configMerge)\n {\n if (config) {\n if (typeof config == \"string\") {\n try {\n /*\n * We must take care when parsing user-supplied JSON-encoded diskette data.\n */\n config = /** @type {Object} */ (eval(\"(\" + config + \")\"));\n } catch (e) {\n Component.error(\"FDC auto-mount error: \" + e.message + \" (\" + config + \")\");\n config = {};\n }\n }\n } else {\n config = {};\n }\n for (var sDrive in config) {\n if (configMerge) configMerge[sDrive] = config[sDrive];\n }\n return config;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {FDC}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.reset();\n if (this.cmp.fReload) {\n /*\n * If the computer's fReload flag is set, we're required to toss all currently\n * loaded disks and remount all disks specified in the auto-mount configuration.\n */\n this.unloadAllDrives(true);\n this.autoMount(true);\n }\n } else {\n if (!this.restore(data)) return false;\n }\n /*\n * Populate the HTML controls to match the actual (well, um, specified) number of floppy drives.\n */\n var controlDrives;\n if ((controlDrives = this.bindings['listDrives'])) {\n while (controlDrives.firstChild) {\n controlDrives.removeChild(controlDrives.firstChild);\n }\n controlDrives.value = \"\";\n for (var iDrive = 0; iDrive < this.nDrives; iDrive++) {\n var controlOption = document.createElement(\"option\");\n controlOption.value = iDrive.toString();\n /*\n * TODO: This conversion of drive number to drive letter, starting with A:, is very simplistic\n * and will NOT match the drive mappings that DOS ultimately uses. We'll need to spiff this up at\n * some point.\n */\n controlOption.text = String.fromCharCode(0x41 + iDrive) + \":\";\n controlDrives.appendChild(controlOption);\n }\n if (this.nDrives > 0) {\n controlDrives.value = \"0\";\n this.displayDiskette(0);\n }\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {FDC}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * NOTE: initController() establishes the maximum possible number of drives, but it's not until\n * we interrogate the current SW1 settings that we will have an ACTUAL number of drives (nDrives),\n * at which point we can also update the contents of the \"listDrives\" HTML control, if any.\n *\n * @this {FDC}\n */\n reset()\n {\n /*\n * NOTE: The controller is also initialized by the constructor, to assist with auto-mount support,\n * so think about whether we can skip powerUp initialization.\n */\n this.initController();\n }\n\n /**\n * save()\n *\n * This implements save support for the FDC component.\n *\n * @this {FDC}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveController());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the FDC component.\n *\n * @this {FDC}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return this.initController(data[0]);\n }\n\n /**\n * initController(data)\n *\n * @this {FDC}\n * @param {Array} [data]\n * @return {boolean} true if successful, false if failure\n */\n initController(data)\n {\n var i = 0, iDrive;\n var fSuccess = true;\n\n if (!data) {\n data = [0, 0, FDC.REG_STATUS.RQM, new Array(9), 0, 0, 0, []];\n }\n\n /*\n * Selected drive (from regOutput), which can only be selected if its motor is on (see regOutput).\n */\n this.iDrive = data[i++];\n i++; // unused slot (if reused, bias by +4, since it was formerly a unit #)\n\n /*\n * Defaults to FDC.REG_STATUS.RQM set (ready for command) and FDC.REG_STATUS.READ_DATA clear (data direction\n * is from processor to the FDC Data Register).\n */\n this.regStatus = data[i++];\n\n /*\n * There can be up to 9 command bytes, and 7 result bytes, so 9 data registers are sufficient for communicating\n * in both directions (hence, the new Array(9) default above).\n */\n this.regDataArray = data[i++];\n\n /*\n * Determines the next data byte to be received.\n */\n this.regDataIndex = data[i++];\n\n /*\n * Determines the next data byte to be sent (internally, we use regDataIndex to read data bytes, up to this total).\n */\n this.regDataTotal = data[i++];\n this.regOutput = data[i++];\n var dataDrives = data[i++];\n\n /*\n * Initialize the disk history (if available) before initializing the drives, so that any disk deltas can be\n * applied to disk images that are already loaded.\n */\n var aDiskHistory = data[i++];\n if (aDiskHistory != null) this.aDiskHistory = aDiskHistory;\n\n if (this.aDrives === undefined) {\n this.nDrives = 4; // default to the maximum number of drives\n if (this.chipset) this.nDrives = this.chipset.getDIPFloppyDrives();\n /*\n * I would prefer to allocate only nDrives, but as discussed in the handling of the FDC.REG_DATA.CMD.SENSE_INT\n * command, we're faced with situations where the controller must respond to any drive in the range 0-3, regardless\n * how many drives are actually installed. We still rely upon nDrives to determine the number of drives displayed\n * to the user, however.\n */\n this.aDrives = new Array(4);\n }\n\n for (iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n var drive = this.aDrives[iDrive];\n if (drive === undefined) {\n /*\n * The first time each drive is initialized, we query its capacity (based on switches or CMOS) and set\n * the drive's physical limits accordingly (ie, max tracks, max heads, and max sectors/track).\n */\n drive = this.aDrives[iDrive] = {};\n var nKb = (this.chipset? this.chipset.getDIPFloppyDriveSize(iDrive) : 0);\n switch(nKb) {\n case 160:\n case 180:\n drive.nHeads = 1; // required for single-sided drives only (all others default to double-sided)\n /* falls through */\n case 320:\n case 360:\n /* falls through */\n default: // drives that don't have a recognized capacity default to 360\n drive.nCylinders = 40;\n drive.nSectors = 9; // drives capable of writing 8 sectors/track can also write 9 sectors/track\n break;\n case 720:\n drive.nCylinders = 80;\n drive.nSectors = 9;\n break;\n case 1200:\n drive.nCylinders = 80;\n drive.nSectors = 15;\n break;\n case 1440:\n drive.nCylinders = 80;\n drive.nSectors = 18;\n break;\n }\n }\n if (!this.initDrive(drive, iDrive, dataDrives[iDrive])) {\n fSuccess = false;\n }\n }\n\n /*\n * regInput and regControl (port 0x3F7) were not present on controllers prior to MODEL_5170, which is why\n * we don't include initializers for them in the default data array; we could eliminate them on older models,\n * but we don't have access to the model info right now, and there's no real cost to always including them\n * in the FDC state.\n *\n * The bigger compatibility question is whether to always include hooks for them (see aPortInput and aPortOutput).\n */\n this.regInput = data[i++] || 0; // TODO: Determine if we should default to FDC.REG_INPUT.DISK_CHANGE instead of 0\n this.regControl = data[i] || FDC.REG_CONTROL.RATE500K; // default to maximum data rate\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"FDC initialized for \" + this.aDrives.length + \" drive(s)\");\n }\n return fSuccess;\n }\n\n /**\n * saveController()\n *\n * @this {FDC}\n * @return {Array}\n */\n saveController()\n {\n var i = 0;\n var data = [];\n data[i++] = this.iDrive;\n data[i++] = 0;\n data[i++] = this.regStatus;\n data[i++] = this.regDataArray;\n data[i++] = this.regDataIndex;\n data[i++] = this.regDataTotal;\n data[i++] = this.regOutput;\n data[i++] = this.saveDrives();\n data[i++] = this.saveDeltas();\n data[i++] = this.regInput;\n data[i] = this.regControl;\n return data;\n }\n\n /**\n * initDrive(drive, iDrive, data)\n *\n * TODO: Consider a separate Drive class that both FDC and HDC can use, since there's a lot of commonality\n * between the drive objects created by both controllers. This will clean up overall drive management and allow\n * us to factor out some common Drive methods (eg, advanceSector()).\n *\n * @this {FDC}\n * @param {Object} drive\n * @param {number} iDrive\n * @param {Array|undefined} data\n * @return {boolean} true if successful, false if failure\n */\n initDrive(drive, iDrive, data)\n {\n var i = 0;\n var fSuccess = true;\n\n drive.iDrive = iDrive;\n drive.fBusy = drive.fLocal = false;\n drive.fnCallReady = null;\n\n if (data === undefined) {\n /*\n * We set a default of two heads (MODEL_5150 PCs originally shipped with single-sided drives,\n * but the ROM BIOS appears to have always supported both drive types).\n */\n data = [FDC.REG_DATA.RES.RESET, true, 0, 2, 0];\n }\n\n if (typeof data[1] == \"boolean\") {\n /*\n * Note that when no data is provided (eg, when the controller is being reinitialized), we now take\n * care to preserve any drive defaults that initController() already obtained for us, falling back to\n * bare minimums only when all else fails.\n */\n data[1] = [\n FDC.DEFAULT_DRIVE_NAME, // a[0]\n drive.nCylinders || 40, // a[1]\n drive.nHeads || data[3],// a[2]\n drive.nSectors || 9, // a[3]\n drive.cbSector || 512, // a[4]\n data[1], // a[5]\n drive.nDiskCylinders, // a[6]\n drive.nDiskHeads, // a[7]\n drive.nDiskSectors // a[8]\n ];\n }\n\n /*\n * resCode used to be an FDC global, but in order to insulate FDC state from the operation of various functions\n * that operate on drive objects (eg, readData and writeData), I've made it a per-drive variable. This choice,\n * similar to my choice for handling PCN, may be contrary to how the actual hardware works, but I prefer this\n * approach, as long as it doesn't expose any incompatibilities that any software actually cares about.\n */\n drive.resCode = data[i++];\n\n /*\n * Some additional drive properties/defaults that are largely for the Disk component's benefit.\n */\n var a = data[i++];\n drive.name = a[0];\n drive.nCylinders = a[1]; // cylinders\n drive.nHeads = a[2]; // heads/cylinders\n drive.nSectors = a[3]; // sectors/track\n drive.cbSector = a[4]; // bytes/sector\n drive.fRemovable = a[5];\n /*\n * If we have current media parameters, restore them; otherwise, default to the drive's physical parameters.\n */\n if (drive.nDiskCylinders = a[6]) {\n drive.nDiskHeads = a[7];\n drive.nDiskSectors = a[8];\n } else {\n drive.nDiskCylinders = drive.nCylinders;\n drive.nDiskHeads = drive.nHeads;\n drive.nDiskSectors = drive.nSectors;\n }\n\n /*\n * The next group of properties are set by various FDC command sequences.\n *\n * We initialize this.iDrive (above) and drive.bHead and drive.bCylinder (below) to zero, but leave the rest undefined,\n * awaiting their first FDC command. We do this because the initial SENSE_INT command returns a PCN, which will also\n * be undefined unless we have at least zeroed both the current drive and the \"present\" cylinder on that drive.\n *\n * Alternatively, I could make PCN a global FDC variable. That may be closer to how the actual hardware operates,\n * but I'm using per-drive variables so that the FDC component can be a good client to both the CPU and other components.\n *\n * COMPATIBILITY ALERT: The MODEL_5170 BIOS (\"DSKETTE_SETUP\") attempts to discern the drive type (double-density vs.\n * high-capacity) by \"slapping\" the heads around -- \"litrally\" (it uses a constant named \"TRK_SLAP\" equal to 48).\n * After seeking to \"TRK_SLAP\", the BIOS performs a series of seeks, looking for the precise point where the heads\n * return to track 0.\n *\n * Here's how it works: the BIOS seeks to track 48 (which is fine on an 80-track 1.2Mb high-capacity drive, but 9 tracks\n * too far on a 40-track 360Kb double-density drive), then seeks to track 10, and then seeks in single-track increments\n * up to 10 more times until the SENSE_DRIVE command returns ST3 with the TRACK0 bit set.\n *\n * This implies that SEEK isn't really seeking to a specified cylinder, but rather it is calculating a delta from\n * the previous cylinder to the specified cylinder, and stepping over that number of tracks. Which means that SEEK\n * is updating a \"logical\" cylinder number, not the \"physical\" (actual) cylinder number. Presumably a RECALIBRATE\n * command will bring the logical and physical values into sync, but once an out-of-bounds cylinder is requested, they\n * will be out of sync.\n *\n * To simulate this, bCylinder is now treated as the \"physical\" cylinder (since that's how it's ALWAYS been used here),\n * and bCylinderSeek will now track (pun intended) the \"logical\" cylinder that's programmed via SEEK commands.\n */\n drive.bHead = data[i++];\n drive.bCylinderSeek = data[i++]; // the data[] slot where we used to store drive.nHeads (or -1)\n drive.bCylinder = data[i++];\n if (drive.bCylinderSeek >= 100) { // verify that the saved bCylinderSeek is valid, otherwise sync it with bCylinder\n drive.bCylinderSeek -= 100;\n } else {\n drive.bCylinderSeek -= drive.bCylinder;\n }\n drive.bSector = data[i++];\n drive.bSectorEnd = data[i++]; // aka EOT\n drive.nBytes = data[i++];\n\n /*\n * We no longer reinitialize drive.disk, in order to retain previously mounted diskette across resets.\n */\n\n /*\n * The next group of properties are managed by worker functions (eg, doRead()) to maintain state across DMA requests.\n */\n drive.ibSector = data[i++]; // location of the next byte to be accessed in the current sector\n drive.sector = null;\n\n if (!drive.disk) {\n drive.sDiskettePath = \"\"; // ensure this is initialized to a default that displayDiskette() can deal with\n }\n\n var deltas = data[i++];\n if (deltas == 102) deltas = false; // v1.02 backward-compatibility\n\n if (typeof deltas == \"boolean\") {\n var fLocal = deltas;\n var sDisketteName = data[i++];\n var sDiskettePath = data[i];\n /*\n * If we're restoring a local disk image, then the entire disk contents should be captured in aDiskHistory,\n * so all we have to do is mount a blank diskette and let disk.restore() do the rest; ie, there's nothing to\n * \"load\" (it's a purely synchronous operation).\n *\n * Otherwise, we must call loadDrive(); in the common case, loadDrive() will have already \"auto-mounted\"\n * the diskette, so it will return true, and then we restore any deltas to the current image.\n *\n * However, if loadDrive() returns false, then it has initiated the load for a *different* disk image,\n * so we must mark ourselves as \"not ready\" again, and add another \"wait for ready\" test in Computer before\n * finally powering the CPU.\n */\n if (fLocal) {\n this.mountDrive(iDrive, sDisketteName, sDiskettePath);\n }\n else if (this.loadDrive(iDrive, sDisketteName, sDiskettePath, true)) {\n if (drive.disk) {\n if (sDiskettePath) {\n this.addDiskHistory(sDisketteName, sDiskettePath, drive.disk);\n } else {\n if (MAXDEBUG) Component.warning(\"Disk '\" + (drive.disk.sDiskName || sDisketteName) + \"' not recorded properly in drive \" + iDrive);\n }\n }\n } else {\n this.setReady(false);\n }\n } else if (deltas !== undefined) {\n /*\n * If there's any data at all (ie, if this is a restore and not a reset), then it must be in the\n * pre-v1.02 save/restore format, so we'll restore as best we can, but be aware that if disk.restore()\n * notices that the currently mounted disk image differs from the disk image that these deltas belong to,\n * it will return false, and the restore operation will be aborted.\n */\n if (drive.disk && drive.disk.restore(deltas) < 0) {\n fSuccess = false;\n }\n }\n\n /*\n * TODO: If loadDrive() returned true, then this can happen immediately. Otherwise, loadDrive()\n * will have merely \"queued up\" the load request and drive.disk won't be ready yet, so figure out how/when\n * we can properly restore drive.sector in that case.\n */\n if (fSuccess && drive.disk && drive.ibSector !== undefined) {\n drive.sector = drive.disk.seek(drive.bCylinder, drive.bHead, drive.bSector);\n }\n return fSuccess;\n }\n\n /**\n * saveDrives()\n *\n * @this {FDC}\n * @return {Array}\n */\n saveDrives()\n {\n var i = 0;\n var data = [];\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n data[i++] = this.saveDrive(this.aDrives[iDrive]);\n }\n return data;\n }\n\n /**\n * saveDrive(drive)\n *\n * @this {FDC}\n * @param {Object} drive\n * @return {Array}\n */\n saveDrive(drive)\n {\n var i = 0;\n var data = [];\n data[i++] = drive.resCode;\n data[i++] = [drive.name, drive.nCylinders, drive.nHeads, drive.nSectors, drive.cbSector, drive.fRemovable, drive.nDiskCylinders, drive.nDiskHeads, drive.nDiskSectors];\n data[i++] = drive.bHead;\n /*\n * We used to store drive.nHeads in the next slot, but now we store bCylinderSeek,\n * and we bias it by +100 so that initDrive() can distinguish it from older values.\n */\n data[i++] = drive.bCylinderSeek + 100;\n data[i++] = drive.bCylinder;\n data[i++] = drive.bSector;\n data[i++] = drive.bSectorEnd;\n data[i++] = drive.nBytes;\n data[i++] = drive.ibSector;\n /*\n * Now we deviate from the 1.01a save format: instead of next storing all the deltas for the\n * currently mounted disk (if any), we store only the name and path of the currently mounted disk\n * (if any). Deltas for ALL disks, both currently mounted and previously mounted, are stored later.\n *\n * data[i++] = drive.disk? drive.disk.save() : null;\n *\n * To indicate this deviation, we store neither a null nor a delta array, but a boolean (fLocal);\n * if that boolean is not present, then the restore code will know it's dealing with a pre-v1.02 state.\n */\n data[i++] = drive.fLocal;\n data[i++] = drive.sDisketteName;\n data[i] = drive.sDiskettePath;\n if (DEBUG && !drive.sDiskettePath && drive.disk && drive.disk.sDiskPath) {\n Component.warning(\"Disk '\" + drive.disk.sDiskName + \"' not saved properly in drive \" + drive.iDrive);\n }\n return data;\n }\n\n /**\n * saveDeltas()\n *\n * This returns an array of entries, one for each disk image we've ever mounted, including any deltas; ie:\n *\n * [name, path, deltas]\n *\n * aDiskHistory contains exactly that, except that deltas may not be up-to-date for any currently mounted\n * disk image(s), so we call updateHistory() for all those disks, and then aDiskHistory is ready to be saved.\n *\n * @this {FDC}\n * @return {Array}\n */\n saveDeltas()\n {\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n var drive = this.aDrives[iDrive];\n if (drive.disk) {\n this.updateDiskHistory(drive.sDisketteName, drive.sDiskettePath, drive.disk);\n }\n }\n return this.aDiskHistory;\n }\n\n /**\n * copyDrive(iDrive)\n *\n * @this {FDC}\n * @param {number} iDrive\n * @return {Object|undefined} drive (which may be undefined if the requested drive does not exist)\n */\n copyDrive(iDrive)\n {\n var driveNew;\n var driveOld = this.aDrives[iDrive];\n if (driveOld !== undefined) {\n driveNew = {};\n for (var p in driveOld) {\n driveNew[p] = driveOld[p];\n }\n }\n return driveNew;\n }\n\n /**\n * seekDrive(drive, iSector, nSectors)\n *\n * The FDC doesn't need this function, since all FDC requests from the CPU are handled by doCmd(). This function\n * is used by other components (eg, Debugger) to mimic an FDC request, using a drive object obtained from copyDrive(),\n * to avoid disturbing the internal state of the FDC's drive objects.\n *\n * Also note that in an actual FDC request, drive.nBytes is initialized to the size of a single sector; the extent\n * of the entire transfer is actually determined by a count that has been pre-loaded into the DMA controller. The FDC\n * isn't even aware of the extent of the transfer, so in the case of a read request, all readData() can do is return\n * bytes until the current track (or, in the case of a multi-track request, the current cylinder) has been exhausted.\n *\n * Since seekDrive() is for use with non-DMA requests, we use nBytes to specify the length of the entire transfer.\n *\n * @this {FDC}\n * @param {Object} drive\n * @param {number} iSector (a \"logical\" sector number, relative to the entire disk, NOT a physical sector number)\n * @param {number} nSectors\n * @return {boolean} true if successful, false if invalid position request\n */\n seekDrive(drive, iSector, nSectors)\n {\n if (drive.disk) {\n var aDiskInfo = drive.disk.info();\n var nCylinders = aDiskInfo[0];\n var nHeads = aDiskInfo[1];\n var nSectorsPerTrack = aDiskInfo[2];\n var nSectorsPerCylinder = nHeads * nSectorsPerTrack;\n var nSectorsPerDisk = nCylinders * nSectorsPerCylinder;\n if (iSector + nSectors <= nSectorsPerDisk) {\n drive.bCylinder = Math.floor(iSector / nSectorsPerCylinder);\n iSector %= nSectorsPerCylinder;\n drive.bHead = Math.floor(iSector / nSectorsPerTrack);\n drive.bSector = (iSector % nSectorsPerTrack) + 1;\n drive.nBytes = nSectors * aDiskInfo[3];\n /*\n * NOTE: We don't set bSectorEnd, as an FDC command would, but it's irrelevant, because we don't actually\n * do anything with bSectorEnd at this point. Perhaps someday, when we faithfully honor/restrict requests\n * to a single track (or a single cylinder, in the case of multi-track requests).\n */\n drive.resCode = FDC.REG_DATA.RES.NONE;\n /*\n * At this point, we've finished simulating what an FDC.REG_DATA.CMD.READ_DATA command would have performed,\n * up through doRead(). Now it's the caller responsibility to call readData(), just like the DMA Controller would.\n */\n return true;\n }\n }\n return false;\n }\n\n /**\n * autoMount(fRemount)\n *\n * @this {FDC}\n * @param {boolean} [fRemount] is true if we're remounting all auto-mounted diskettes\n * @return {boolean} true if one or more diskette images are being auto-mounted, false if none\n */\n autoMount(fRemount)\n {\n if (!fRemount) this.cAutoMount = 0;\n for (var sDrive in this.configMount) {\n var configDrive = this.configMount[sDrive];\n var sDiskettePath = configDrive['path'] || this.findDisketteByName(configDrive['name']);\n if (sDiskettePath) {\n /*\n * WARNING: This conversion of drive letter to drive number, starting with A:, is very simplistic\n * and is not guaranteed to match the drive mapping that DOS ultimately uses.\n */\n var iDrive = sDrive.charCodeAt(0) - 0x41;\n if (iDrive >= 0 && iDrive < this.aDrives.length) {\n var sDisketteName = configDrive['name'] || this.findDisketteByPath(sDiskettePath) || Str.getBaseName(sDiskettePath, true);\n if (!this.loadDrive(iDrive, sDisketteName, sDiskettePath, true) && fRemount) {\n this.setReady(false);\n }\n continue;\n }\n this.notice(\"Incorrect auto-mount settings for drive \" + sDrive + \" (\" + JSON.stringify(configDrive) + \")\");\n }\n }\n return !!this.cAutoMount;\n }\n\n /**\n * loadSelectedDisk()\n *\n * NOTE: Since this can be called via script command (eg, 'loadDisk FDC'), additional parameters can be\n * passed; use the arguments array to access them if necessary.\n *\n * @this {FDC}\n * @return {boolean}\n */\n loadSelectedDisk()\n {\n var controlDisks = this.bindings[\"listDisks\"];\n if (controlDisks) {\n var sDisketteName = controlDisks.options[controlDisks.selectedIndex].text;\n var sDiskettePath = controlDisks.value;\n return this.loadSelectedDrive(sDisketteName, sDiskettePath);\n }\n return false;\n }\n\n /**\n * loadSelectedDrive(sDisketteName, sDiskettePath, file)\n *\n * @this {FDC}\n * @param {string} sDisketteName\n * @param {string} sDiskettePath\n * @param {File} [file] is set if there's an associated File object\n * @return {boolean}\n */\n loadSelectedDrive(sDisketteName, sDiskettePath, file)\n {\n var iDrive;\n var controlDrives = this.bindings[\"listDrives\"];\n if (controlDrives && !isNaN(iDrive = Str.parseInt(controlDrives.value, 10)) && iDrive >= 0 && iDrive < this.aDrives.length) {\n\n if (!sDiskettePath) {\n this.unloadDrive(iDrive);\n return true;\n }\n\n if (sDiskettePath == \"?\") {\n this.notice('Use \"Choose File\" and \"Mount\" to select and load a local disk.');\n return false;\n }\n\n /*\n * If the special path of \"??\" is selected, then we want to prompt the user for a URL. Oh, and\n * make sure we pass an empty string as the 2nd parameter to prompt(), so that IE won't display\n * \"undefined\" -- because after all, undefined and \"undefined\" are EXACTLY the same thing, right?\n *\n * TODO: This is literally all I've done to support remote disk images. There's probably more\n * I should do, like dynamically updating \"listDisks\" to include new entries, and adding new entries\n * to the save/restore data.\n */\n if (sDiskettePath == \"??\") {\n sDiskettePath = window.prompt(\"Enter the URL of a remote disk image.\", \"\") || \"\";\n if (!sDiskettePath) return false;\n sDisketteName = Str.getBaseName(sDiskettePath);\n if (DEBUG) this.println(\"Attempting to load \" + sDiskettePath + \" as \\\"\" + sDisketteName + \"\\\"\");\n }\n\n while (this.loadDrive(iDrive, sDisketteName, sDiskettePath, false, file) < 0) {\n if (!window.confirm(\"Click OK to reload the original disk and discard any changes.\")) {\n if (DEBUG) this.println(\"load cancelled\");\n return false;\n }\n /*\n * So here's the story: loadDrive() returned true, which it does ONLY if the specified disk is already\n * mounted, AND the user clicked OK to reload the original disk image. So we must toss any history we have\n * for the disk, unload it, and then loop back around to loadDrive().\n *\n * loadDrive() should NEVER return true the second time, since no disk is loaded. In other words,\n * this isn't really a loop so much as a one-time retry operation.\n */\n this.removeDiskHistory(sDisketteName, sDiskettePath);\n this.unloadDrive(iDrive, false, true);\n }\n return true;\n }\n this.notice(\"Unable to load the selected drive\");\n return false;\n }\n\n /**\n * mountDrive(iDrive, sDisketteName, sDiskettePath)\n *\n * @this {FDC}\n * @param {number} iDrive\n * @param {string} sDisketteName\n * @param {string} sDiskettePath\n */\n mountDrive(iDrive, sDisketteName, sDiskettePath)\n {\n var drive = this.aDrives[iDrive];\n this.unloadDrive(iDrive, true, true);\n drive.fLocal = true;\n var disk = new Disk(this, drive, DiskAPI.MODE.PRELOAD);\n this.doneLoadDrive(drive, disk, sDisketteName, sDiskettePath, true);\n }\n\n /**\n * loadDrive(iDrive, sDisketteName, sDiskettePath, fAutoMount, file)\n *\n * NOTE: If sDiskettePath is already loaded in the drive, nothing needs to be done.\n *\n * @this {FDC}\n * @param {number} iDrive\n * @param {string} sDisketteName\n * @param {string} sDiskettePath\n * @param {boolean} [fAutoMount]\n * @param {File} [file] is set if there's an associated File object\n * @return {number} 1 if diskette loaded, 0 if queued up (or busy), -1 if already loaded\n */\n loadDrive(iDrive, sDisketteName, sDiskettePath, fAutoMount, file)\n {\n var drive = this.aDrives[iDrive];\n if (sDiskettePath) {\n /*\n * The following hacks should only be necessary for (old) saved states, since all our disk manifests\n * should no longer be using any of these old paths.\n */\n sDiskettePath = sDiskettePath.replace(\"/disks/pc/\", \"/disks/pcx86/\");\n sDiskettePath = sDiskettePath.replace(\"/disks/pcx86/private/\", \"/private-disks/pcx86/\");\n sDiskettePath = sDiskettePath.replace(\"/disks/pcx86/\", \"/pcjs-disks/pcx86/\");\n /*\n * TODO: Machines with saved states may be using lower-case disk image names, whereas we now use\n * UPPER-CASE names for disk images, so we lower-case both before comparing. The only problem with\n * removing these hacks is that we can never be sure when all saved states in the wild have been updated.\n */\n if (drive.sDiskettePath.toLowerCase() != sDiskettePath.toLowerCase()) {\n this.unloadDrive(iDrive, fAutoMount, true);\n if (drive.fBusy) {\n this.notice(\"Drive \" + iDrive + \" busy\");\n return 0;\n }\n drive.fBusy = true;\n if (fAutoMount) {\n drive.fAutoMount = true;\n this.cAutoMount++;\n if (this.messageEnabled()) this.printMessage(\"loading diskette '\" + sDisketteName + \"'\");\n }\n drive.fLocal = !!file;\n var disk = new Disk(this, drive, DiskAPI.MODE.PRELOAD);\n if (!disk.load(sDisketteName, sDiskettePath, file, this.doneLoadDrive)) {\n return 0;\n }\n return 1;\n }\n }\n return -1;\n }\n\n /**\n * doneLoadDrive(drive, disk, sDisketteName, sDiskettePath, fAutoMount)\n *\n * @this {FDC}\n * @param {Object} drive\n * @param {Disk} disk is set if the disk was successfully loaded, null if not\n * @param {string} sDisketteName\n * @param {string} sDiskettePath\n * @param {boolean} [fAutoMount]\n */\n doneLoadDrive(drive, disk, sDisketteName, sDiskettePath, fAutoMount)\n {\n var aDiskInfo;\n\n drive.fBusy = false;\n\n if (disk) {\n /*\n * We shouldn't mount the diskette unless the drive is able to handle it; for example, FD360 (40-track)\n * drives cannot read FD1200 (80-track) diskettes. However, I no longer require that the diskette's\n * sectors/track fall within the drive's standard maximum, because XDF diskettes use 19 physical sectors/track\n * on the first cylinder (1 more than the typical 18 sectors/track found on 1.44Mb diskettes) but declare\n * a larger logical size (23 512-byte sectors/track) to reflect the actual capacity of XDF tracks beyond the\n * first cylinder (ie, one 8Kb sector, one 2Kb sector, one 1Kb sector, and one 512-byte sector).\n */\n aDiskInfo = disk.info();\n if (disk && aDiskInfo[0] > drive.nCylinders || aDiskInfo[1] > drive.nHeads /* || aDiskInfo[2] > drive.nSectors */) {\n this.notice(\"Diskette \\\"\" + sDisketteName + \"\\\" too large for drive \" + String.fromCharCode(0x41 + drive.iDrive));\n disk = null;\n }\n }\n\n if (disk) {\n drive.disk = disk;\n drive.sDisketteName = sDisketteName;\n drive.sDiskettePath = sDiskettePath;\n\n /*\n * Since we allow a diskette image to be auto-mounted even if it isn't in the machine's list of disks,\n * let's add it to the list now, since the disk apparently exists.\n */\n if (!this.findDisketteByPath(sDiskettePath)) {\n this.addDiskette(sDisketteName, sDiskettePath);\n }\n\n /*\n * Adding local disk image names to the disk list seems like a nice idea, but it's too confusing,\n * because then it looks like the \"Mount\" button should be able to (re)load them, and that can NEVER\n * happen, for security reasons; local disk images can ONLY be loaded via the \"Mount\" button after\n * the user has selected them via the \"Choose File\" button.\n *\n * this.addDiskette(sDisketteName, sDiskettePath);\n *\n * So we're going to take a different approach: when displayDiskette() is asked to display the name\n * of a local disk image, it will map all such disks to \"Local Disk\", and any attempt to \"Mount\" such\n * a disk, will essentially result in a \"Disk not found\" error.\n */\n this.addDiskHistory(sDisketteName, sDiskettePath, disk);\n\n /*\n * For a local disk (ie, one loaded via mountDrive()), the disk.restore() performed by addDiskHistory()\n * may have altered the disk geometry, so refresh the disk info.\n */\n aDiskInfo = disk.info();\n\n /*\n * Clearly, a successful mount implies a disk change, and I suppose that, technically, an *unsuccessful*\n * mount should imply the same, but what would the real-world analog be? Inserting a piece of cardboard\n * instead of an actual diskette? In any case, if we can do the user a favor by pretending (as far as the\n * disk change line is concerned) that an unsuccessful mount never happened, let's do it.\n *\n * Successful unmounts are a different story, however; those *do* trigger a change. See unloadDrive().\n */\n this.regInput |= FDC.REG_INPUT.DISK_CHANGE;\n\n /*\n * With the addition of notify(), users are now \"alerted\" whenever a diskette has finished loading;\n * notify() is selective about its output, using print() if a print window is open, alert() otherwise.\n *\n * WARNING: This conversion of drive number to drive letter, starting with A:, is very simplistic\n * and will not match the drive mappings that DOS ultimately uses (ie, for drives beyond B:).\n */\n if (!drive.fnCallReady) this.notice(\"Mounted diskette \\\"\" + sDisketteName + \"\\\" in drive \" + String.fromCharCode(0x41 + drive.iDrive), drive.fAutoMount || fAutoMount);\n\n /*\n * Update the drive's current media parameters to match the disk's.\n */\n drive.nDiskCylinders = aDiskInfo[0];\n drive.nDiskHeads = aDiskInfo[1];\n drive.nDiskSectors = aDiskInfo[2];\n\n /*\n * Since you usually want the Computer to have focus again after loading a new diskette, let's try automatically\n * updating the focus after a successful load.\n */\n if (this.cmp) this.cmp.updateFocus();\n }\n else {\n drive.fLocal = false;\n }\n\n if (drive.fAutoMount) {\n drive.fAutoMount = false;\n if (!--this.cAutoMount) this.setReady();\n }\n\n this.displayDiskette(drive.iDrive);\n\n if (drive.fnCallReady) {\n drive.fnCallReady();\n drive.fnCallReady = null;\n }\n }\n\n /**\n * addDiskette(sName, sPath, fTop)\n *\n * @this {FDC}\n * @param {string} sName\n * @param {string} sPath\n * @param {boolean} [fTop] (default is bottom)\n */\n addDiskette(sName, sPath, fTop)\n {\n var controlDisks = this.bindings[\"listDisks\"];\n if (controlDisks && controlDisks.options) {\n for (var i = 0; i < controlDisks.options.length; i++) {\n if (controlDisks.options[i].value == sPath) return;\n }\n var controlOption = document.createElement(\"option\");\n controlOption.text = sName;\n controlOption.value = sPath;\n if (fTop && controlDisks.childNodes[0]) {\n controlDisks.insertBefore(controlOption, controlDisks.childNodes[0]);\n } else {\n controlDisks.appendChild(controlOption);\n }\n }\n }\n\n /**\n * findDisketteByPath(sPath)\n *\n * This is used to deal with mount requests (eg, autoMount) that supply a path without a name;\n * if we can find the path in the \"listDisks\" control, then we return the associated disk name.\n *\n * @this {FDC}\n * @param {string} sPath\n * @return {string|null}\n */\n findDisketteByPath(sPath)\n {\n var controlDisks = this.bindings[\"listDisks\"];\n if (controlDisks && controlDisks.options) {\n for (var i = 0; i < controlDisks.options.length; i++) {\n var control = controlDisks.options[i];\n if (control.value == sPath) return control.text;\n }\n }\n return null;\n }\n\n /**\n * findDisketteByName(sName)\n *\n * This is used to deal with mount requests (eg, autoMount) that supply a name without a path;\n * if we can find the name in the \"listDisks\" control, then we return the associated disk path.\n *\n * @this {FDC}\n * @param {string|undefined} sName\n * @return {string}\n */\n findDisketteByName(sName)\n {\n if (sName) {\n var controlDisks = this.bindings[\"listDisks\"];\n if (controlDisks && controlDisks.options) {\n for (var i = 0; i < controlDisks.options.length; i++) {\n var control = controlDisks.options[i];\n if (control.text == sName) return control.value;\n }\n }\n }\n return \"\";\n }\n\n /**\n * displayDiskette(iDrive, fUpdateDrive)\n *\n * @this {FDC}\n * @param {number} iDrive (unvalidated)\n * @param {boolean} [fUpdateDrive] is true to update the drive list to match the specified drive (eg, the auto-mount case)\n */\n displayDiskette(iDrive, fUpdateDrive)\n {\n /*\n * First things first: validate iDrive.\n */\n if (iDrive >= 0 && iDrive < this.aDrives.length) {\n var drive = this.aDrives[iDrive];\n var controlDisks = this.bindings[\"listDisks\"];\n var controlDrives = this.bindings[\"listDrives\"];\n /*\n * Next, make sure controls for both drives and disks exist.\n */\n if (controlDisks && controlDrives && controlDisks.options && controlDrives.options) {\n /*\n * Next, make sure the drive whose disk we're updating is the currently selected drive.\n */\n var i;\n var iDriveSelected = Str.parseInt(controlDrives.value, 10);\n var sTargetPath = (drive.fLocal? \"?\" : drive.sDiskettePath);\n if (!isNaN(iDriveSelected) && iDriveSelected == iDrive) {\n for (i = 0; i < controlDisks.options.length; i++) {\n if (controlDisks.options[i].value == sTargetPath) {\n if (controlDisks.selectedIndex != i) {\n controlDisks.selectedIndex = i;\n }\n break;\n }\n }\n if (i == controlDisks.options.length) controlDisks.selectedIndex = 0;\n }\n if (fUpdateDrive) {\n for (i = 0; i < controlDrives.options.length; i++) {\n if (Str.parseInt(controlDrives.options[i].value, 10) == drive.iDrive) {\n if (controlDrives.selectedIndex != i) {\n controlDrives.selectedIndex = i;\n }\n break;\n }\n }\n }\n }\n }\n }\n\n /**\n * updateSelectedDiskette()\n *\n * @this {FDC}\n */\n updateSelectedDiskette()\n {\n var control = this.bindings[\"listDisks\"];\n var controlDesc = this.bindings[\"descDisk\"];\n var controlOption = control.options[control.selectedIndex];\n if (controlDesc && controlOption) {\n var dataValue = {};\n var sValue = controlOption.getAttribute(\"data-value\");\n if (sValue) {\n try {\n dataValue = eval(\"(\" + sValue + \")\");\n } catch (e) {\n Component.error(this.type + \" option error: \" + e.message);\n }\n }\n var sHTML = dataValue['desc'];\n if (sHTML === undefined) sHTML = \"\";\n var sHRef = dataValue['href'];\n if (sHRef !== undefined) sHTML = \"<a href=\\\"\" + sHRef + \"\\\" target=\\\"_blank\\\">\" + sHTML + \"</a>\";\n controlDesc.innerHTML = sHTML;\n }\n }\n\n /**\n * waitDrives(fnCallReady)\n *\n * @this {FDC}\n * @param {function()|null} fnCallReady\n * @return {boolean} false if wait required, true otherwise\n */\n waitDrives(fnCallReady)\n {\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n var drive = this.aDrives[iDrive];\n if (drive && drive.fBusy) {\n if (!drive.fnCallReady) drive.fnCallReady = fnCallReady;\n return false;\n }\n }\n return true;\n }\n\n /**\n * unloadDrive(iDrive, fAutoUnload, fQuiet)\n *\n * @this {FDC}\n * @param {number} iDrive (pre-validated)\n * @param {boolean} [fAutoUnload] is true if this unload is being forced as part of an automount and/or restored mount\n * @param {boolean} [fQuiet]\n */\n unloadDrive(iDrive, fAutoUnload, fQuiet)\n {\n var drive = this.aDrives[iDrive];\n if (drive.disk) {\n /*\n * Before we toss the disk's information, capture any deltas that may have occurred.\n */\n this.updateDiskHistory(drive.sDisketteName, drive.sDiskettePath, drive.disk);\n drive.sDisketteName = \"\";\n drive.sDiskettePath = \"\";\n drive.disk = null;\n drive.fLocal = false;\n\n this.regInput |= FDC.REG_INPUT.DISK_CHANGE;\n\n /*\n * WARNING: This conversion of drive number to drive letter, starting with A:, is very simplistic\n * and is not guaranteed to match the drive mapping that DOS ultimately uses.\n */\n if (!fQuiet) {\n this.notice(\"Drive \" + String.fromCharCode(0x41 + iDrive) + \" unloaded\", fAutoUnload);\n }\n /*\n * Try to avoid any unnecessary hysteresis regarding the diskette display if this unload is merely\n * a prelude to another load.\n */\n if (!fAutoUnload && !fQuiet) {\n this.displayDiskette(iDrive);\n }\n }\n }\n\n /**\n * unloadAllDrives(fDiscard)\n *\n * @this {FDC}\n * @param {boolean} fDiscard to discard all disk history before unloading\n */\n unloadAllDrives(fDiscard)\n {\n if (fDiscard) {\n this.aDiskHistory = [];\n }\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n this.unloadDrive(iDrive, true);\n }\n }\n\n /**\n * addDiskHistory(sDisketteName, sDiskettePath, disk)\n *\n * @this {FDC}\n * @param {string} sDisketteName\n * @param {string} sDiskettePath\n * @param {Disk} disk containing corresponding disk image\n */\n addDiskHistory(sDisketteName, sDiskettePath, disk)\n {\n var i;\n //\n for (i = 0; i < this.aDiskHistory.length; i++) {\n if (this.aDiskHistory[i][1] == sDiskettePath) {\n var nChanges = disk.restore(this.aDiskHistory[i][2]);\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"disk '\" + sDisketteName + \"' restored from history (\" + nChanges + \" changes)\");\n }\n return;\n }\n }\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"disk '\" + sDisketteName + \"' added to history (nothing to restore)\");\n }\n this.aDiskHistory[i] = [sDisketteName, sDiskettePath, []];\n }\n\n /**\n * removeDiskHistory(sDisketteName, sDiskettePath)\n *\n * @this {FDC}\n * @param {string} sDisketteName\n * @param {string} sDiskettePath\n */\n removeDiskHistory(sDisketteName, sDiskettePath)\n {\n var i;\n for (i = 0; i < this.aDiskHistory.length; i++) {\n if (this.aDiskHistory[i][1] == sDiskettePath) {\n this.aDiskHistory.splice(i, 1);\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"disk '\" + sDisketteName + \"' removed from history\");\n }\n return;\n }\n }\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"unable to remove disk '\" + sDisketteName + \"' from history (\" + sDiskettePath + \")\");\n }\n }\n\n /**\n * updateDiskHistory(sDisketteName, sDiskettePath, disk)\n *\n * @this {FDC}\n * @param {string} sDisketteName\n * @param {string} sDiskettePath\n * @param {Disk} disk containing corresponding disk image, with possible deltas\n */\n updateDiskHistory(sDisketteName, sDiskettePath, disk)\n {\n var i;\n for (i = 0; i < this.aDiskHistory.length; i++) {\n if (this.aDiskHistory[i][1] == sDiskettePath) {\n this.aDiskHistory[i][2] = disk.save();\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"disk '\" + sDisketteName + \"' updated in history\");\n }\n return;\n }\n }\n /*\n * I used to report this as an error (at least in the DEBUG release), but it's no longer really\n * an error, because if we're trying to re-mount a clean copy of a disk, we toss its history, then\n * unload, and then reload/remount. And since unloadDrive's normal behavior is to call updateDiskHistory()\n * before unloading, the fact that the disk is no longer listed here can't be treated as an error.\n */\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"unable to update disk '\" + sDisketteName + \"' in history (\" + sDiskettePath + \")\");\n }\n }\n\n /**\n * outFDCOutput(port, bOut, addrFrom)\n *\n * @this {FDC}\n * @param {number} port (0x3F2, output only)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outFDCOutput(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"OUTPUT\");\n if (!(bOut & FDC.REG_OUTPUT.ENABLE)) {\n this.initController();\n /*\n * initController() resets, among other things, the selected drive (this.iDrive), so if we were\n * still updating this.iDrive below based on the \"drive select\" bits in regOutput, we would want\n * to make sure those bits now match what initController() set. But since we no longer do that\n * (see below), this is no longer needed either.\n *\n * bOut = (bOut & ~FDC.REG_OUTPUT.DS) | this.iDrive;\n */\n }\n else if (!(this.regOutput & FDC.REG_OUTPUT.ENABLE)) {\n /*\n * When FDC.REG_OUTPUT.ENABLE transitions from 0 to 1, generate an interrupt (assuming INT_ENABLE is set).\n */\n this.requestInterrupt();\n }\n /*\n * This no longer updates the internally selected drive (this.iDrive) based on regOutput, because (a) there seems\n * to be no point, as all drive-related commands include their own \"drive select\" bits, and (b) it breaks the\n * MODEL_5170 boot code. Here's why:\n *\n * Unlike previous models, the MODEL_5170 BIOS probes all installed diskette drives to determine drive type;\n * ie, FD360 (40-track) or FD1200 (80-track). So if there are two drives, the last selected drive will be drive 1.\n * Immediately before booting, the BIOS issues an INT 0x13/AH=0 reset, which writes regOutput two times: first\n * with FDC.REG_OUTPUT.ENABLE clear, and then with it set. However, both times, it ALSO loads the last selected\n * drive number into regOutput's \"drive select\" bits.\n *\n * If we switched our selected drive to match regOutput, then the ST0 value we returned on an SENSE_INT command\n * following the regOutput reset operation would indicate drive 1 instead of drive 0. But the BIOS requires\n * the ST0 result from the SENSE_INT command ALWAYS be 0xC0 (not 0xC1), so the controller must not be propagating\n * regOutput's \"drive select\" bits in the way I originally assumed.\n *\n * var iDrive = bOut & FDC.REG_OUTPUT.DS;\n * if (bOut & (FDC.REG_OUTPUT.MOTOR_D0 << iDrive)) this.iDrive = iDrive;\n */\n this.regOutput = bOut;\n }\n\n /**\n * inFDCDiagnostic(port, addrFrom)\n *\n * It turns out that any 5170 configuration without an HDC component that attempts to use either the REV2 or REV3\n * PC AT ROM BIOS will fail with error \"601-Diskette Error\", unless we also provide this \"D/S/P DIAGNOSTIC REGISTER\".\n * The original 5170 REV1 BIOS didn't have this requirement.\n *\n * I'm unable to find any documentation on this so-called \"D/S/P DIAGNOSTIC REGISTER\" (port 0x3F1) or the \"D/S/P CARD\"\n * to which the ROM BIOS refers. But it seems clear that if we don't provide the expected response from the DIAGNOSTIC\n * REGISTER, and there's no HDC to respond to the MULTIPLE DATA RATE CAPABLE test that follows, then an error is\n * inevitable. Clearly, there is a very intimate relationship between the FDC and HDC portions of this card.\n *\n * Here's the relevant code from the REV3 PC AT ROM BIOS (TEST2.ASM):\n *\n * ;----- CHECK FOR MULTIPLE DATA RATE CAPABILITY\n *\n * J_OK:\n * MOV DX,03F1H ; D/S/P DIAGNOSTIC REGISTER\n * IN AL,DX ; READ D/S/P TYPE CODE\n * AND AL,11111000B ; KEEP ONLY UNIQUE CODE FOR D/S/P\n * CMP AL,01010000B ; D/S/P CARD - MULTIPLE DATA RATE?\n * JZ J_OK3 ; IF SO JUMP\n *\n * MOV DX,05F7H ; FIXED DISK DIAGNOSTIC REGISTER\n * IN AL,DX ; READ FIXED DISK TYPE CODE\n * AND AL,11110000B ; KEEP ONLY UNIQUE CODE FOR F/D\n * CMP AL,10100000B ; FIXED DISK ADAPTER ?\n * JZ J_FAIL ; MUST BE COMBO ELSE ERROR\n *\n * MOV BL,0FH ; OUTER LOOP COUNT WAIT FOR BUSY OFF\n * SUB CX,CX\n * MOV DX,01F7H ; HARD FILE STATUS PORT\n * J_OK1:\n * IN AL,DX ; GET THE STATUS\n * TEST AL,080H ; IS THE CONTROLLER BUSY?\n * JZ J_OK2 ; CONTINUE IF NOT\n * LOOP J_OK1 ; TRY AGAIN\n * DEC BL ; DECREMENT OUTER LOOP\n * JNZ J_OK1 ; TRY AGAIN IF NOT ZERO\n * AND AL,0CH ; BITS 2 & 3 = 0 IF MULTI DATA CAPABLE\n * JZ J_OK3 ; GO IF YES\n * JMP SHORT J_FAIL ; NO MULTIPLE DATA RATE CAPABILITY\n * J_OK2:\n * MOV DX,1F4H ; VERIFY MULTIPLE DATA RATE CAPABLE\n * MOV AL,055H ; WRITE TO THE CYLINDER BYTE\n * OUT DX,AL\n * JMP $+2 ; I/O DELAY\n * IN AL,DX ; CHECK DATA WRITTEN = DATA READ\n * CMP AL,055H\n * JNZ J_FAIL ; GO IF NOT\n * MOV AL,0AAH ; WRITE ANOTHER PATTERN\n * OUT DX,AL\n * JMP $+2 ; I/O DELAY\n * IN AL,DX\n * CMP AL,0AAH ; IS DATA PATTERN THE SAME?\n * JZ J_OK3 ; GO IF SO\n *\n * J_FAIL:\n * OR @MFG_ERR_FLAG+1,DSK_FAIL; <><><><><><><><><><><><><>\n * ; <><> DISKETTE FAILED <><>\n * MOV SI,OFFSET E601 ; GET ADDRESS OF MESSAGE\n * CALL E_MSG ; GO PRINT ERROR MESSAGE\n * JMP SHORT F15C ; SKIP SETUP IF ERROR\n *\n * J_OK3:\n * OR @LASTRATE,DUAL ; TURN ON DSP/COMBO FLAG\n *\n * @this {FDC}\n * @param {number} port (0x3F1, input only)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inFDCDiagnostic(port, addrFrom)\n {\n var b = 0x50; // we simply return the expected pattern (01010000B); see code excerpt above\n this.printMessageIO(port, null, addrFrom, \"DIAG\", b);\n return b;\n }\n\n /**\n * inFDCStatus(port, addrFrom)\n *\n * @this {FDC}\n * @param {number} port (0x3F4, input only)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inFDCStatus(port, addrFrom)\n {\n this.printMessageIO(port, null, addrFrom, \"STATUS\", this.regStatus);\n return this.regStatus;\n }\n\n /**\n * inFDCData(port, addrFrom)\n *\n * @this {FDC}\n * @param {number} port (0x3F5, input/output)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inFDCData(port, addrFrom)\n {\n var bIn = 0;\n if (this.regDataIndex < this.regDataTotal) {\n bIn = this.regDataArray[this.regDataIndex];\n }\n /*\n * As per the discussion in doCmd(), once the first byte of the Result Phase has been read, the interrupt must be cleared.\n */\n if (this.regOutput & FDC.REG_OUTPUT.INT_ENABLE) {\n if (this.chipset) this.chipset.clearIRR(ChipSet.IRQ.FDC);\n }\n if (this.messageEnabled()) {\n this.printMessageIO(port, null, addrFrom, \"DATA[\" + this.regDataIndex + \"]\", bIn);\n }\n if (++this.regDataIndex >= this.regDataTotal) {\n this.regStatus &= ~(FDC.REG_STATUS.READ_DATA | FDC.REG_STATUS.BUSY);\n this.regDataIndex = this.regDataTotal = 0;\n }\n return bIn;\n }\n\n /**\n * outFDCData(port, bOut, addrFrom)\n *\n * @this {FDC}\n * @param {number} port (0x3F5, input/output)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outFDCData(port, bOut, addrFrom)\n {\n if (this.messageEnabled()) {\n this.printMessageIO(port, bOut, addrFrom, \"DATA[\" + this.regDataTotal + \"]\");\n }\n\n if (this.regDataTotal < this.regDataArray.length) {\n this.regDataArray[this.regDataTotal++] = bOut;\n }\n var bCmd = this.regDataArray[0];\n var bCmdMasked = bCmd & FDC.REG_DATA.CMD.MASK;\n if (FDC.aCmdInfo[bCmdMasked] !== undefined) {\n if (this.regDataTotal >= FDC.aCmdInfo[bCmdMasked].cbReq) {\n this.doCmd();\n }\n return;\n }\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"unsupported FDC command: \" + Str.toHexByte(bCmd));\n if (MAXDEBUG) this.dbg.stopCPU();\n }\n }\n\n /**\n * inFDCInput(port, addrFrom)\n *\n * @this {FDC}\n * @param {number} port (0x3F7, input only, MODEL_5170 only)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inFDCInput(port, addrFrom)\n {\n var bIn = this.regInput;\n /*\n * TODO: Determine when the DISK_CHANGE bit is *really* cleared (this is just a guess)\n */\n this.regInput &= ~FDC.REG_INPUT.DISK_CHANGE;\n this.printMessageIO(port, null, addrFrom, \"INPUT\", bIn);\n return bIn;\n }\n\n /**\n * outFDCControl(port, bOut, addrFrom)\n *\n * @this {FDC}\n * @param {number} port (0x3F7, output only, MODEL_5170 only)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n */\n outFDCControl(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"CONTROL\");\n this.regControl = bOut;\n }\n\n /**\n * doCmd()\n *\n * @this {FDC}\n */\n doCmd()\n {\n var fIRQ = false;\n this.regDataIndex = 0;\n var bCmd = this.popCmd();\n var drive, bDrive, bHead, c, h, r, n;\n\n /*\n * NOTE: We currently ignore the FDC.REG_DATA.CMD.SK, FDC.REG_DATA.CMD.MF and FDC.REG_DATA.CMD.MT bits of every command.\n * The only command bit of possible interest down the road might be the FDC.REG_DATA.CMD.MT (Multi-Track); the rest relate\n * to storage format details that we cannot emulate as long as our diskette images contain nothing more than sector\n * data without any formatting data.\n *\n * Similarly, we ignore parameters like SRT, HUT, HLT and the like, since our \"motors\" don't require physical delays;\n * however, if timing issues become compatibility issues, we'll have to revisit those delays. In any case, the maximum\n * speed of the simulation will still be limited by various spin-loops in the ROM BIOS that wait prescribed times, so even\n * with infinitely fast hardware, the simulation will never run as fast as it theoretically could, unless we opt to identify\n * those spin-loops and either patch them or skip over them.\n */\n var bCmdMasked = bCmd & FDC.REG_DATA.CMD.MASK;\n\n switch (bCmdMasked) {\n case FDC.REG_DATA.CMD.SPECIFY: // 0x03\n this.popSRT(); // SRT and HUT (encodings?)\n this.popHLT(); // HLT and ND (encodings?)\n this.beginResult();\n /*\n * No results are provided by this command, and fIRQ should remain false\n */\n break;\n\n case FDC.REG_DATA.CMD.SENSE_DRIVE: // 0x04\n bDrive = this.popCmd(FDC.TERMS.DS);\n bHead = (bDrive >> 2) & 0x1;\n this.iDrive = (bDrive & 0x3);\n drive = this.aDrives[this.iDrive];\n this.beginResult();\n this.pushST3(drive);\n break;\n\n case FDC.REG_DATA.CMD.WRITE_DATA: // 0x05\n case FDC.REG_DATA.CMD.READ_DATA: // 0x06\n bDrive = this.popCmd(FDC.TERMS.DS); // Drive Select\n bHead = (bDrive >> 2) & 0x1; // isolate HD (Head Select) bits\n this.iDrive = (bDrive & 0x3); // isolate DS (Drive Select, aka Unit Select) bits\n drive = this.aDrives[this.iDrive];\n drive.bHead = bHead;\n c = drive.bCylinder = this.popCmd(FDC.TERMS.C); // C\n h = this.popCmd(FDC.TERMS.H); // H\n /*\n * Controller docs say that H should always match HD, so I assert that, but what if someone\n * made a mistake and didn't program them identically -- what would happen? Which should we honor?\n */\n\n r = drive.bSector = this.popCmd(FDC.TERMS.R); // R\n n = this.popCmd(FDC.TERMS.N); // N\n drive.nBytes = 128 << n; // 0 => 128, 1 => 256, 2 => 512, 3 => 1024\n drive.bSectorEnd = this.popCmd(FDC.TERMS.EOT); // EOT (final sector number on a cylinder)\n this.popCmd(FDC.TERMS.GPL); // GPL (spacing between sectors, excluding VCO Sync Field; 3)\n this.popCmd(FDC.TERMS.DTL); // DTL (when N is 0, DTL stands for the data length to read out or write into the sector)\n if (bCmdMasked == FDC.REG_DATA.CMD.READ_DATA)\n this.doRead(drive);\n else\n this.doWrite(drive);\n this.pushResults(drive, bCmd, bHead, c, h, r, n);\n fIRQ = true;\n break;\n\n case FDC.REG_DATA.CMD.RECALIBRATE: // 0x07\n bDrive = this.popCmd(FDC.TERMS.DS);\n this.iDrive = (bDrive & 0x3);\n drive = this.aDrives[this.iDrive];\n drive.bCylinder = drive.bCylinderSeek = 0;\n drive.resCode = FDC.REG_DATA.RES.SEEK_END | FDC.REG_DATA.RES.TRACK0;\n this.beginResult(); // no results provided; this command is typically followed by FDC.REG_DATA.CMD.SENSE_INT\n fIRQ = true;\n break;\n\n case FDC.REG_DATA.CMD.SENSE_INT: // 0x08\n drive = this.aDrives[this.iDrive];\n drive.bHead = 0; // this command is documented as ALWAYS returning a head address of 0 in ST0; see pushST0()\n this.beginResult();\n this.pushST0(drive);\n this.pushResult(drive.bCylinder, FDC.TERMS.PCN);\n /*\n * For some strange reason, the \"DISK_RESET\" function in the MODEL_5170_REV3 BIOS resets the\n * adapter and then issues FOUR -- that's right, not ONE but FOUR -- SENSE INTERRUPT STATUS commands\n * in a row, and expects ST0 to contain a different drive number after each command (first 0, then 1,\n * then 2, and finally 3). What makes this doubly weird is SENSE INTERRUPT STATUS (unlike SENSE\n * DRIVE STATUS) is a drive-agnostic command.\n *\n * Didn't the original PC AT \"HFCOMBO\" controller limit support to TWO diskette drives max?\n * And even if the PC AT supported other FDC controllers that DID support up to FOUR diskette drives,\n * why should \"DISK_RESET\" hard-code a 4-drive loop?\n *\n * Well, whatever. All this head-scratching doesn't change the fact that I apparently have to\n * \"auto-increment\" the internal drive number (this.iDrive) after each SENSE INTERRUPT STATUS command.\n */\n this.iDrive = (this.iDrive + 1) & 0x3;\n /*\n * No interrupt is generated by this command, so fIRQ should remain false.\n */\n break;\n\n case FDC.REG_DATA.CMD.READ_ID: // 0x0A\n /*\n * This command is used by \"SETUP_DBL\" in the MODEL_5170_REV3 BIOS to determine if a double-density\n * (40-track) diskette has been inserted in a high-density (80-track) drive; ie, whether \"double stepping\"\n * is required, since only 40 of the 80 possible \"steps\" are valid for a double-density diskette.\n *\n * To start, we'll focus on making this work in the normal case (80-track diskette in 80-track drive).\n */\n bDrive = this.popCmd(FDC.TERMS.DS);\n bHead = (bDrive >> 2) & 0x1;\n this.iDrive = (bDrive & 0x3);\n drive = this.aDrives[this.iDrive];\n c = drive.bCylinder;\n h = drive.bHead = bHead;\n r = drive.bSector = 1;\n n = 0;\n drive.resCode = FDC.REG_DATA.RES.NONE;\n if (drive.disk && (drive.sector = drive.disk.seek(drive.bCylinder, drive.bHead, drive.bSector))) {\n n = (drive.sector['length'] >> 8);\n } else {\n /*\n * TODO: Determine the appropriate response code(s) for the possible errors that can occur here.\n */\n drive.resCode = FDC.REG_DATA.RES.NOT_READY | FDC.REG_DATA.RES.INCOMPLETE;\n }\n this.pushResults(drive, bCmd, bHead, c, h, r, n);\n fIRQ = true;\n break;\n\n case FDC.REG_DATA.CMD.FORMAT_TRACK: // 0x0D\n bDrive = this.popCmd(FDC.TERMS.DS);\n bHead = (bDrive >> 2) & 0x1;\n this.iDrive = (bDrive & 0x3);\n drive = this.aDrives[this.iDrive];\n c = drive.bCylinder;\n h = drive.bHead = bHead;\n r = 1;\n n = this.popCmd(FDC.TERMS.N); // N\n drive.nBytes = 128 << n; // 0 => 128, 1 => 256, 2 => 512, 3 => 1024 (bytes/sector)\n drive.bSectorEnd = this.popCmd(FDC.TERMS.SC); // SC (sectors/track)\n this.popCmd(FDC.TERMS.GPL); // GPL (spacing between sectors, excluding VCO Sync Field; 3)\n drive.bFiller = this.popCmd(FDC.TERMS.D); // D (filler byte)\n this.doFormat(drive);\n this.pushResults(drive, bCmd, bHead, c, h, r, n);\n fIRQ = true;\n break;\n\n case FDC.REG_DATA.CMD.SEEK: // 0x0F\n bDrive = this.popCmd(FDC.TERMS.DS);\n bHead = (bDrive >> 2) & 0x1;\n this.iDrive = (bDrive & 0x3);\n drive = this.aDrives[this.iDrive];\n drive.bHead = bHead;\n /*\n * As discussed in initDrive(), we can no longer simply set bCylinder to the specified NCN;\n * instead, we must calculate the delta between bCylinderSeek and the NCN, and adjust bCylinder\n * by that amount. Then we simply move the NCN into bCylinderSeek without any range checking.\n *\n * Since bCylinder is now expressly defined as the \"physical\" cylinder number, it must never\n * be allowed to exceed the physical boundaries of the drive (ie, never lower than 0, and never\n * greater than or equal to nCylinders).\n */\n c = this.popCmd(FDC.TERMS.NCN);\n drive.bCylinder += c - drive.bCylinderSeek;\n if (drive.bCylinder < 0) drive.bCylinder = 0;\n if (drive.bCylinder >= drive.nCylinders) drive.bCylinder = drive.nCylinders - 1;\n drive.bCylinderSeek = c;\n drive.resCode = FDC.REG_DATA.RES.SEEK_END;\n /*\n * TODO: To properly support ALL the ST3 result bits (not just TRACK0), we need a resCode\n * update() function that all FDC commands can use. This code is merely sufficient to get us\n * through the \"DSKETTE_SETUP\" gauntlet in the MODEL_5170 BIOS.\n */\n if (!drive.bCylinder) {\n drive.resCode |= FDC.REG_DATA.RES.TRACK0;\n }\n this.beginResult(); // like FDC.REG_DATA.CMD.RECALIBRATE, no results are provided\n fIRQ = true;\n break;\n\n default:\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"unsupported FDC operation: \" + Str.toHexByte(bCmd));\n if (MAXDEBUG) this.dbg.stopCPU();\n }\n break;\n }\n\n if (this.regDataTotal > 0) {\n this.regStatus |= (FDC.REG_STATUS.READ_DATA | FDC.REG_STATUS.BUSY);\n }\n\n /*\n * After the Execution Phase (eg, DMA Terminal Count has occurred, or the EOT sector has been read/written),\n * an interrupt is supposed to occur, signaling the beginning of the Result Phase. Once the first byte of the\n * result has been read, the interrupt is cleared (see inFDCData).\n *\n * TODO: Technically, interrupt request status should be cleared by the FDC.REG_DATA.CMD.SENSE_INT command; in fact,\n * if that command is issued and no interrupt was pending, then FDC.REG_DATA.RES.INVALID should be returned (via ST0).\n */\n \n /*\n * When the Windows 95 HSFLOP (\"High-Speed Floppy\") VxD performs its diskette change-line detection logic\n * (\"determine_changeline\"), it sets a special callback (\"dcl_callback_int_entry\") for its interrupt handler\n * to invoke, then issues a READ_ID command, and then sets a bit telling its interrupt handler to expect an\n * interrupt (\"FLP_NEC_INT_EXPECTED\").\n * \n * Technically, it should have set *both* \"dcl_callback_int_entry\" *and* \"FLP_NEC_INT_EXPECTED\" *before*\n * issuing the READ_ID command, but I imagine the author assumed all was fine, since interrupts had been\n * disabled with a \"cli\" beforehand and had not been re-enabled with an \"sti\" yet. But alas, the function\n * used to the issue the READ_ID command (\"NecOut\") immediately re-enabled interrupts.\n * \n * So, if we request an interrupt immediately after the READ_ID command, the interrupt handler will think\n * our interrupt is spurious (ie, not EXPECTED). In this particular case, there are only about 10 instructions\n * executed from the time READ_ID is issued until the \"FLP_NEC_INT_EXPECTED\" bit is set, but I'm going to\n * add a little padding to that, in part because I wouldn't be surprised if there are other places where a\n * similar assumption exists (ie, either that \"NecOut\" leaves interrupts disabled, or simply that the floppy\n * controller is an inherently slow device).\n * \n * TODO: Determine why the Football prototype disk fails to boot if we specify a larger delay (eg, 32) and\n * why TopView 1.10 hangs when the delay is set to 16. I've worked around those questions for now, by simply\n * limiting the delay\n */\n this.requestInterrupt(drive && fIRQ && !(drive.resCode & FDC.REG_DATA.RES.NOT_READY), bCmdMasked == FDC.REG_DATA.CMD.READ_ID? 16 : 0);\n }\n\n /**\n * pushResults(drive, bCmd, bHead, c, h, r, n)\n *\n * @param {Object} drive\n * @param {number} bCmd\n * @param {number} bHead\n * @param {number} c\n * @param {number} h\n * @param {number} r\n * @param {number} n\n */\n pushResults(drive, bCmd, bHead, c, h, r, n)\n {\n this.beginResult();\n this.pushST0(drive);\n this.pushST1(drive);\n this.pushST2(drive);\n /*\n * NOTE: I used to set the following C/H/R/N results using the values that advanceSector() had \"advanced\"\n * them to, which seemed logical but was technically incorrect. For non-multi-track reads, they should match\n * the programmed C/H/R/N values, except when EOT has been reached, in which case C = C + 1 and R = 1.\n *\n * For multi-track, the LSB of H should be complemented whenever EOT has been reached, which I \"informally\"\n * detect by testing if the drive's current bCylinder and/or bHead positions advanced to a new cylinder or head,\n * and apparently, C should never be advanced if H was initially 0.\n *\n * I don't do strict EOT comparisons here or elsewhere, because it allows the controller to work with a wider\n * range of disks (eg, \"fake\" XDF disk images that contain 23 512-byte sectors/track).\n */\n var i = 0;\n if (c != drive.bCylinder || h != drive.bHead) {\n i = r = 1;\n }\n if (bCmd & FDC.REG_DATA.CMD.MT) {\n h ^= i;\n if (!bHead) i = 0;\n }\n c += i;\n this.pushResult(c, FDC.TERMS.C); // formerly drive.bCylinder\n this.pushResult(h, FDC.TERMS.H); // formerly drive.bHead\n this.pushResult(r, FDC.TERMS.R); // formerly drive.bSector\n this.pushResult(n, FDC.TERMS.N);\n }\n\n /**\n * popCmd(name)\n *\n * @this {FDC}\n * @param {string|undefined} [name]\n * @return {number}\n */\n popCmd(name)\n {\n\n var bCmd = this.regDataArray[this.regDataIndex];\n if (DEBUG && this.messageEnabled(Messages.PORT | Messages.FDC)) {\n var bCmdMasked = bCmd & FDC.REG_DATA.CMD.MASK;\n if (!name && !this.regDataIndex && FDC.aCmdInfo[bCmdMasked]) name = FDC.aCmdInfo[bCmdMasked].name;\n this.printMessage(this.idComponent + \".popCmd(\" + (name || this.regDataIndex) + \"): \" + Str.toHexByte(bCmd), true);\n }\n this.regDataIndex++;\n return bCmd;\n }\n\n /**\n * popHLT()\n *\n * NOTE: This byte is actually a combination of HLT (Head Load Time) and ND (Non-DMA Mode)\n *\n * @this {FDC}\n */\n popHLT()\n {\n this.popCmd(FDC.TERMS.HLT);\n // this.nHLT = this.popCmd(FDC.TERMS.HLT);\n }\n\n /**\n * popSRT()\n *\n * NOTE: This byte is actually a combination of SRT (Step Rate Time) and HUT (Head Unload Time)\n *\n * @this {FDC}\n */\n popSRT()\n {\n this.popCmd(FDC.TERMS.SRT);\n // this.nSRT = this.popCmd(FDC.TERMS.SRT);\n }\n\n /**\n * requestInterrupt(fCondition, nDelay)\n * \n * Request an FDC interrupt, as long as INT_ENABLE is set (and the optional supplied condition, if any, is true).\n * \n * @this {FDC}\n * @param {boolean} [fCondition]\n * @param {number} [nDelay]\n */\n requestInterrupt(fCondition = true, nDelay = 0)\n {\n if (fCondition && (this.regOutput & FDC.REG_OUTPUT.INT_ENABLE)) {\n if (this.chipset) this.chipset.setIRR(ChipSet.IRQ.FDC, nDelay);\n }\n }\n \n /**\n * beginResult()\n *\n * @this {FDC}\n */\n beginResult()\n {\n this.regDataIndex = this.regDataTotal = 0;\n }\n\n /**\n * pushResult(bResult, name)\n *\n * @this {FDC}\n * @param {number} bResult\n * @param {string|undefined} [name]\n */\n pushResult(bResult, name)\n {\n if (DEBUG && this.messageEnabled(Messages.PORT | Messages.FDC)) {\n this.printMessage(this.idComponent + \".pushResult(\" + (name || this.regDataTotal) + \"): \" + Str.toHexByte(bResult), true);\n }\n\n this.regDataArray[this.regDataTotal++] = bResult;\n }\n\n /**\n * pushST0(drive)\n *\n * @this {FDC}\n * @param {Object} drive\n */\n pushST0(drive)\n {\n this.pushResult(drive.iDrive | (drive.bHead << 2) | (drive.resCode & FDC.REG_DATA.RES.ST0), FDC.TERMS.ST0);\n }\n\n /**\n * pushST1(drive)\n *\n * @this {FDC}\n * @param {Object} drive\n */\n pushST1(drive)\n {\n this.pushResult((drive.resCode & FDC.REG_DATA.RES.ST1) >>> 8, FDC.TERMS.ST1);\n }\n\n /**\n * pushST2(drive)\n *\n * @this {FDC}\n * @param {Object} drive\n */\n pushST2(drive)\n {\n this.pushResult((drive.resCode & FDC.REG_DATA.RES.ST2) >>> 16, FDC.TERMS.ST2);\n }\n\n /**\n * pushST3(drive)\n *\n * @this {FDC}\n * @param {Object} drive\n */\n pushST3(drive)\n {\n this.pushResult((drive.resCode & FDC.REG_DATA.RES.ST3) >>> 24, FDC.TERMS.ST3);\n }\n\n /**\n * doDMARead(drive, b, done)\n *\n * @this {FDC}\n * @param {Object} drive\n * @param {number} b\n * @param {function(number,boolean)} done\n */\n doDMARead(drive, b, done)\n {\n if (b === undefined || b < 0) {\n this.readData(drive, done);\n return;\n }\n /*\n * The DMA controller should be ASKING for data, not GIVING us data; this suggests an internal DMA miscommunication\n */\n if (DEBUG) this.printMessage(this.idComponent + \".doDMARead(): invalid DMA acknowledgement\");\n done(-1, false);\n }\n\n /**\n * doDMAWrite(drive, b)\n *\n * @this {FDC}\n * @param {Object} drive\n * @param {number} b\n * @return {number}\n */\n doDMAWrite(drive, b)\n {\n if (b !== undefined && b >= 0)\n return this.writeData(drive, b);\n /*\n * The DMA controller should be GIVING us data, not ASKING for data; this suggests an internal DMA miscommunication\n */\n if (DEBUG) this.printMessage(this.idComponent + \".doDMAWrite(): invalid DMA acknowledgement\");\n return -1;\n }\n\n /**\n * doDMAFormat(drive, b)\n *\n * @this {FDC}\n * @param {Object} drive\n * @param {number} b\n * @returns {number}\n */\n doDMAFormat(drive, b)\n {\n if (b !== undefined && b >= 0)\n return this.writeFormat(drive, b);\n /*\n * The DMA controller should be GIVING us data, not ASKING for data; this suggests an internal DMA miscommunication\n */\n if (DEBUG) this.printMessage(this.idComponent + \".doDMAFormat(): invalid DMA acknowledgement\");\n return -1;\n }\n\n /**\n * doRead(drive)\n *\n * @this {FDC}\n * @param {Object} drive\n */\n doRead(drive)\n {\n /*\n * With only NOT_READY and INCOMPLETE set, an empty drive causes DOS to report \"General Failure\";\n * with the addition of NO_DATA, DOS reports \"Sector not found\". The traditional \"Drive not ready\"\n * error message is not triggered by anything we return here, but simply by BIOS commands timing out.\n */\n drive.resCode = FDC.REG_DATA.RES.NOT_READY | FDC.REG_DATA.RES.INCOMPLETE;\n\n if (drive.disk) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".doRead(CHS=\" + drive.bCylinder + ':' + drive.bHead + ':' + drive.bSector + \",PBA=\" + (drive.bCylinder * (drive.disk.nHeads * drive.disk.nSectors) + drive.bHead * drive.disk.nSectors + drive.bSector-1) + ')');\n }\n drive.sector = null;\n drive.resCode = FDC.REG_DATA.RES.NONE;\n if (this.chipset) {\n this.chipset.connectDMA(ChipSet.DMA_FDC, this, 'dmaRead', drive);\n this.chipset.requestDMA(ChipSet.DMA_FDC);\n }\n }\n }\n\n /**\n * doWrite(drive)\n *\n * @this {FDC}\n * @param {Object} drive\n */\n doWrite(drive)\n {\n drive.resCode = FDC.REG_DATA.RES.NOT_READY | FDC.REG_DATA.RES.INCOMPLETE;\n\n if (drive.disk) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".doWrite(CHS=\" + drive.bCylinder + ':' + drive.bHead + ':' + drive.bSector + \",PBA=\" + (drive.bCylinder * (drive.disk.nHeads * drive.disk.nSectors) + drive.bHead * drive.disk.nSectors + drive.bSector-1) + ')');\n }\n if (drive.disk.fWriteProtected) {\n drive.resCode = FDC.REG_DATA.RES.NOT_WRITABLE | FDC.REG_DATA.RES.INCOMPLETE;\n return;\n }\n drive.sector = null;\n drive.resCode = FDC.REG_DATA.RES.NONE;\n if (this.chipset) {\n this.chipset.connectDMA(ChipSet.DMA_FDC, this, 'dmaWrite', drive);\n this.chipset.requestDMA(ChipSet.DMA_FDC);\n }\n }\n }\n\n /**\n * doFormat(drive)\n *\n * drive is initialized by doCmd() to the following extent:\n *\n * drive.bHead (ignored)\n * drive.nBytes (bytes/sector)\n * drive.bSectorEnd (sectors/track)\n * drive.bFiller (fill byte)\n *\n * and we expect the DMA controller to provide C, H, R and N (ie, 4 bytes) for each sector to be formatted.\n *\n * @this {FDC}\n * @param {Object} drive\n */\n doFormat(drive)\n {\n drive.resCode = FDC.REG_DATA.RES.NOT_READY | FDC.REG_DATA.RES.INCOMPLETE;\n\n if (drive.disk) {\n drive.sector = null;\n drive.resCode = FDC.REG_DATA.RES.NONE;\n if (this.chipset) {\n drive.cbFormat = 0;\n drive.abFormat = new Array(4);\n drive.bFormatting = true;\n drive.cSectorsFormatted = 0;\n this.chipset.connectDMA(ChipSet.DMA_FDC, this, 'dmaFormat', drive);\n this.chipset.requestDMA(ChipSet.DMA_FDC);\n drive.bFormatting = false;\n }\n }\n }\n\n /**\n * readData(drive, done)\n *\n * The following drive properties must have been setup prior to our first call:\n *\n * drive.bHead\n * drive.bCylinder\n * drive.bSector\n * drive.sector (initialized to null)\n *\n * On the first readData() request, since drive.sector will be null, we ask the Disk object to look\n * up the first sector of the request. We then ask the Disk for bytes from that sector until the sector\n * is exhausted, and then we look up the next sector and continue the process.\n *\n * NOTE: Since the FDC isn't aware of the extent of the transfer, all readData() can do is return bytes\n * until the current track (or, in the case of a multi-track request, the current cylinder) has been exhausted.\n *\n * TODO: Research the requirements, if any, for multi-track I/O and determine what else needs to be done.\n *\n * @this {FDC}\n * @param {Object} drive\n * @param {function(number,boolean,Object,number)} done (number is next available byte from drive, or -1 if no more bytes available)\n */\n readData(drive, done)\n {\n var b = -1;\n var obj = null, off = 0; // these variables are purely for BACKTRACK purposes\n\n if (!drive.resCode && drive.disk) {\n do {\n if (drive.sector) {\n off = drive.ibSector;\n if ((b = drive.disk.read(drive.sector, drive.ibSector++)) >= 0) {\n obj = drive.sector;\n break;\n }\n }\n /*\n * Locate the next sector, and then try reading again.\n */\n drive.sector = drive.disk.seek(drive.bCylinder, drive.bHead, drive.bSector);\n if (!drive.sector) {\n drive.resCode = FDC.REG_DATA.RES.NO_DATA | FDC.REG_DATA.RES.INCOMPLETE;\n break;\n }\n drive.ibSector = 0;\n /*\n * We \"pre-advance\" bSector et al now, instead of waiting to advance it right before the seek().\n * This allows the initial call to readData() to perform a seek without triggering an unwanted advance.\n */\n this.advanceSector(drive);\n } while (true);\n }\n done(b, false, obj, off);\n }\n\n /**\n * writeData(drive, b)\n *\n * The following drive properties must have been setup prior to our first call:\n *\n * drive.bHead\n * drive.bCylinder\n * drive.bSector\n * drive.sector (initialized to null)\n *\n * On the first writeData() request, since drive.sector will be null, we ask the Disk object to look\n * up the first sector of the request. We then send the Disk bytes for that sector until the sector\n * is full, and then we look up the next sector and continue the process.\n *\n * NOTE: Since the FDC isn't aware of the extent of the transfer, all writeData() can do is accept bytes\n * until the current track (or, in the case of a multi-track request, the current cylinder) has been exhausted.\n *\n * TODO: Research the requirements, if any, for multi-track I/O and determine what else needs to be done.\n *\n * @this {FDC}\n * @param {Object} drive\n * @param {number} b containing next byte to write\n * @return {number} (b unchanged; return -1 if command should be terminated)\n */\n writeData(drive, b)\n {\n if (drive.resCode || !drive.disk) return -1;\n do {\n if (drive.sector) {\n if (drive.disk.write(drive.sector, drive.ibSector++, b))\n break;\n }\n /*\n * Locate the next sector, and then try writing again.\n */\n drive.sector = drive.disk.seek(drive.bCylinder, drive.bHead, drive.bSector);\n if (!drive.sector) {\n /*\n * TODO: Determine whether this should be FDC.REG_DATA.RES.CRC_ERROR or FDC.REG_DATA.RES.DATA_FIELD\n */\n drive.resCode = FDC.REG_DATA.RES.CRC_ERROR | FDC.REG_DATA.RES.INCOMPLETE;\n b = -1;\n break;\n }\n drive.ibSector = 0;\n /*\n * We \"pre-advance\" bSector et al now, instead of waiting to advance it right before the seek().\n * This allows the initial call to writeData() to perform a seek without triggering an unwanted advance.\n */\n this.advanceSector(drive);\n } while (true);\n return b;\n }\n\n /**\n * advanceSector(drive)\n *\n * This increments the sector number; when the sector number reaches drive.nDiskSectors on the current track, we\n * increment drive.bHead and reset drive.bSector, and when drive.bHead reaches drive.nDiskHeads, we reset drive.bHead\n * and increment drive.bCylinder.\n *\n * @this {FDC}\n * @param {Object} drive\n */\n advanceSector(drive)\n {\n\n drive.bSector++;\n var bSectorStart = 1;\n if (drive.bSector >= drive.nDiskSectors + bSectorStart) {\n drive.bSector = bSectorStart;\n drive.bHead++;\n if (drive.bHead >= drive.nDiskHeads) {\n drive.bHead = 0;\n drive.bCylinder++;\n }\n }\n }\n\n /**\n * writeFormat(drive, b)\n *\n * @this {FDC}\n * @param {Object} drive\n * @param {number} b containing a format command byte\n * @return {number} (b if successful, -1 if command should be terminated)\n */\n writeFormat(drive, b)\n {\n if (drive.resCode) return -1;\n drive.abFormat[drive.cbFormat++] = b;\n if (drive.cbFormat == drive.abFormat.length) {\n drive.bCylinder = drive.abFormat[0]; // C\n drive.bHead = drive.abFormat[1]; // H\n drive.bSector = drive.abFormat[2]; // R\n drive.nBytes = 128 << drive.abFormat[3];// N (0 => 128, 1 => 256, 2 => 512, 3 => 1024)\n drive.cbFormat = 0;\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".writeFormat(head=\" + Str.toHexByte(drive.bHead) + \",cyl=\" + Str.toHexByte(drive.bCylinder) + \",sec=\" + Str.toHexByte(drive.bSector) + \",len=\" + Str.toHexWord(drive.nBytes) + \")\");\n }\n for (var i = 0; i < drive.nBytes; i++) {\n if (this.writeData(drive, drive.bFiller) < 0) {\n return -1;\n }\n }\n drive.cSectorsFormatted++;\n }\n if (drive.cSectorsFormatted >= drive.bSectorEnd) b = -1;\n return b;\n }\n\n /**\n * FDC.init()\n *\n * This function operates on every HTML element of class \"fdc\", extracting the\n * JSON-encoded parameters for the FDC constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a FDC component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeFDC = Component.getElementsByClass(document, PCX86.APPCLASS, \"fdc\");\n for (var iFDC = 0; iFDC < aeFDC.length; iFDC++) {\n var eFDC = aeFDC[iFDC];\n var parmsFDC = Component.getComponentParms(eFDC);\n var fdc = new FDC(parmsFDC);\n Component.bindComponentControls(fdc, eFDC, PCX86.APPCLASS);\n }\n }\n}\n\nFDC.DEFAULT_DRIVE_NAME = \"Floppy Drive\";\n\nif (DEBUG) {\n FDC.TERMS = {\n C: \"C\", // Cylinder Number\n D: \"D\", // Data (eg, pattern to be written to a sector)\n H: \"H\", // Head Address\n R: \"R\", // Record (ie, sector number to be read or written)\n N: \"N\", // Number (ie, number of data bytes to write)\n DS: \"DS\", // Drive Select\n SC: \"SC\", // Sectors per Cylinder\n DTL: \"DTL\", // Data Length\n EOT: \"EOT\", // End of Track\n GPL: \"GPL\", // Gap Length\n HLT: \"HLT\", // Head Load Time\n NCN: \"NCN\", // New Cylinder Number\n PCN: \"PCN\", // Present Cylinder Number\n SRT: \"SRT\", // Stepping Rate\n ST0: \"ST0\", // Status Register 0\n ST1: \"ST1\", // Status Register 1\n ST2: \"ST2\", // Status Register 2\n ST3: \"ST3\" // Status Register 3\n };\n} else {\n FDC.TERMS = {};\n}\n\n/*\n * FDC Digital Output Register (DOR) (0x3F2, write-only)\n *\n * NOTE: Reportedly, a drive's MOTOR had to be ON before the drive could be selected; however, outFDCOutput() no\n * longer verifies that. Also, motor start time for original drives was 500ms, but we make no attempt to simulate that.\n *\n * On the MODEL_5170 \"PC AT Fixed Disk and Diskette Drive Adapter\", this port is called the Digital Output Register\n * or DOR. It uses the same bit definitions as the original FDC Output Register, except that only two diskette drives\n * are supported, hence bit 1 is always 0 (ie, FDC.REG_OUTPUT.DS2 and FDC.REG_OUTPUT.DS3 are not supported) and bits\n * 6 and 7 are unused (FDC.REG_OUTPUT.MOTOR_D2 and FDC.REG_OUTPUT.MOTOR_D3 are not supported).\n */\nFDC.REG_OUTPUT = {\n PORT: 0x3F2,\n DS: 0x03, // drive select bits\n DS0: 0x00,\n DS1: 0x01,\n DS2: 0x02, // reserved on the MODEL_5170\n DS3: 0x03, // reserved on the MODEL_5170\n ENABLE: 0x04, // clearing this bit resets the FDC\n INT_ENABLE: 0x08, // enables both FDC and DMA (Channel 2) interrupt requests (IRQ 6)\n MOTOR_D0: 0x10,\n MOTOR_D1: 0x20,\n MOTOR_D2: 0x40, // reserved on the MODEL_5170\n MOTOR_D3: 0x80 // reserved on the MODEL_5170\n};\n\n/*\n * FDC Main Status Register (0x3F4, read-only)\n *\n * On the MODEL_5170 \"PC AT Fixed Disk and Diskette Drive Adapter\", bits 2 and 3 are reserved, since that adapter\n * supported a maximum of two diskette drives.\n */\nFDC.REG_STATUS = {\n PORT: 0x3F4,\n BUSY_A: 0x01,\n BUSY_B: 0x02,\n BUSY_C: 0x04, // reserved on the MODEL_5170\n BUSY_D: 0x08, // reserved on the MODEL_5170\n BUSY: 0x10, // a read or write command is in progress\n NON_DMA: 0x20, // FDC is in non-DMA mode\n READ_DATA: 0x40, // transfer is from FDC Data Register to processor (if clear, then transfer is from processor to the FDC Data Register)\n RQM: 0x80 // indicates FDC Data Register is ready to send or receive data to or from the processor (Request for Master)\n};\n\n/*\n * FDC Data Register (0x3F5, read-write)\n */\nFDC.REG_DATA = {\n PORT: 0x3F5,\n /*\n * FDC Commands\n *\n * NOTE: FDC command bytes need to be masked with FDC.REG_DATA.CMD.MASK before comparing to the values below, since a\n * number of commands use the following additional bits as follows:\n *\n * SK (0x20): Skip Deleted Data Address Mark\n * MF (0x40): Modified Frequency Modulation (as opposed to FM or Frequency Modulation)\n * MT (0x80): multi-track operation (ie, data processed under both head 0 and head 1)\n *\n * We don't support MT (Multi-Track) operations at this time, and the MF and SK designations cannot be supported as long\n * as our diskette images contain only the original data bytes without any formatting information.\n */\n CMD: {\n READ_TRACK: 0x02,\n SPECIFY: 0x03,\n SENSE_DRIVE: 0x04,\n WRITE_DATA: 0x05,\n READ_DATA: 0x06,\n RECALIBRATE: 0x07,\n SENSE_INT: 0x08, // this command is used to clear the FDC interrupt following the clearing/setting of FDC.REG_OUTPUT.ENABLE\n WRITE_DEL_DATA: 0x09,\n READ_ID: 0x0A,\n READ_DEL_DATA: 0x0C,\n FORMAT_TRACK: 0x0D,\n SEEK: 0x0F,\n SCAN_EQUAL: 0x11,\n SCAN_LO_EQUAL: 0x19,\n SCAN_HI_EQUAL: 0x1D,\n MASK: 0x1F,\n SK: 0x20, // SK (Skip Deleted Data Address Mark)\n MF: 0x40, // MF (Modified Frequency Modulation)\n MT: 0x80 // MT (Multi-Track; ie, data under both heads will be processed)\n },\n /*\n * FDC status/error results, generally assigned according to the corresponding ST0, ST1, ST2 or ST3 status bit.\n *\n * TODO: Determine when EQUIP_CHECK is *really* set; also, \"77 step pulses\" sounds suspiciously like a typo (it's not 79?)\n */\n RES: {\n NONE: 0x00000000, // ST0 (IC): Normal termination of command (NT)\n NOT_READY: 0x00000008, // ST0 (NR): When the FDD is in the not-ready state and a read or write command is issued, this flag is set; if a read or write command is issued to side 1 of a single sided drive, then this flag is set\n EQUIP_CHECK: 0x00000010, // ST0 (EC): If a fault signal is received from the FDD, or if the track 0 signal fails to occur after 77 step pulses (recalibrate command), then this flag is set\n SEEK_END: 0x00000020, // ST0 (SE): When the FDC completes the Seek command, this flag is set to 1 (high)\n INCOMPLETE: 0x00000040, // ST0 (IC): Abnormal termination of command (AT); execution of command was started, but was not successfully completed\n RESET: 0x000000C0, // ST0 (IC): Abnormal termination because during command execution the ready signal from the drive changed state\n INVALID: 0x00000080, // ST0 (IC): Invalid command issue (IC); command which was issued was never started\n ST0: 0x000000FF,\n NO_ID_MARK: 0x00000100, // ST1 (MA): If the FDC cannot detect the ID Address Mark, this flag is set; at the same time, the MD (Missing Address Mark in Data Field) of Status Register 2 is set\n NOT_WRITABLE: 0x00000200, // ST1 (NW): During Execution of a Write Data, Write Deleted Data, or Format a Cylinder command, if the FDC detects a write protect signal from the FDD, then this flag is set\n NO_DATA: 0x00000400, // ST1 (ND): FDC cannot find specified sector (or specified ID if READ_ID command)\n DMA_OVERRUN: 0x00001000, // ST1 (OR): If the FDC is not serviced by the main systems during data transfers within a certain time interval, this flag is set\n CRC_ERROR: 0x00002000, // ST1 (DE): When the FDC detects a CRC error in either the ID field or the data field, this flag is set\n END_OF_CYL: 0x00008000, // ST1 (EN): When the FDC tries to access a sector beyond the final sector of a cylinder, this flag is set\n ST1: 0x0000FF00,\n NO_DATA_MARK: 0x00010000, // ST2 (MD): When data is read from the medium, if the FDC cannot find a Data Address Mark or Deleted Data Address Mark, then this flag is set\n BAD_CYL: 0x00020000, // ST2 (BC): This bit is related to the ND bit, and when the contents of C on the medium are different from that stored in the ID Register, and the content of C is FF, then this flag is set\n SCAN_FAILED: 0x00040000, // ST2 (SN): During execution of the Scan command, if the FDC cannot find a sector on the cylinder which meets the condition, then this flag is set\n SCAN_EQUAL: 0x00080000, // ST2 (SH): During execution of the Scan command, if the condition of \"equal\" is satisfied, this flag is set\n WRONG_CYL: 0x00100000, // ST2 (WC): This bit is related to the ND bit, and when the contents of C on the medium are different from that stored in the ID Register, this flag is set\n DATA_FIELD: 0x00200000, // ST2 (DD): If the FDC detects a CRC error in the data, then this flag is set\n STRL_MARK: 0x00400000, // ST2 (CM): During execution of the Read Data or Scan command, if the FDC encounters a sector which contains a Deleted Data Address Mark, this flag is set\n ST2: 0x00FF0000,\n DRIVE: 0x03000000, // ST3 (Ux): Status of the \"Drive Select\" signals from the diskette drive\n HEAD: 0x04000000, // ST3 (HD): Status of the \"Side Select\" signal from the diskette drive\n TWOSIDE: 0x08000000, // ST3 (TS): Status of the \"Two Side\" signal from the diskette drive\n TRACK0: 0x10000000, // ST3 (T0): Status of the \"Track 0\" signal from the diskette drive\n READY: 0x20000000, // ST3 (RY): Status of the \"Ready\" signal from the diskette drive\n WRITEPROT: 0x40000000, // ST3 (WP): Status of the \"Write Protect\" signal from the diskette drive\n FAULT: 0x80000000|0, // ST3 (FT): Status of the \"Fault\" signal from the diskette drive\n ST3: 0xFF000000|0\n }\n};\n\n/*\n * FDC \"Fixed Disk\" Register (0x3F6, write-only)\n *\n * Since this register's functions are all specific to the Hard Drive Controller, see the HDC component for details.\n * The fact that this HDC register is in the middle of the FDC I/O port range is an oddity of the \"HFCOMBO\" controller.\n */\n\n/*\n * FDC Digital Input Register (0x3F7, read-only, MODEL_5170 only)\n *\n * Bit 7 indicates a diskette change (the MODEL_5170 introduced change-line support). Bits 0-6 are for the selected\n * hard drive, so this port must be shared with the HDC; bits 0-6 are valid for 50 microseconds after a write to the\n * Drive Head Register.\n */\nFDC.REG_INPUT = {\n PORT: 0x3F7,\n DS0: 0x01, // Drive Select 0\n DS1: 0x02, // Drive Select 1\n HS0: 0x04, // Head Select 0\n HS1: 0x08, // Head Select 1\n HS2: 0x10, // Head Select 2\n HS3: 0x20, // Head Select 3\n WRITE_GATE: 0x40, // Write Gate\n DISK_CHANGE:0x80 // Diskette Change\n};\n\n/*\n * FDC Diskette Control Register (0x3F7, write-only, MODEL_5170 only)\n *\n * Only bits 0-1 are used; bits 2-7 are reserved.\n */\nFDC.REG_CONTROL = {\n PORT: 0x3F7,\n RATE500K: 0x00, // 500,000 bps\n RATE300K: 0x02, // 300,000 bps\n RATE250K: 0x01, // 250,000 bps\n RATEUNUSED: 0x03\n};\n\n/*\n * FDC Command Sequences\n *\n * For each command, cbReq indicates the total number of bytes in the command request sequence,\n * including the first (command) byte; cbRes indicates total number of bytes in the response sequence.\n */\nif (DEBUG) {\n FDC.CMDS = {\n SPECIFY: \"SPECIFY\",\n SENSE_DRIVE: \"SENSE DRIVE\",\n WRITE_DATA: \"WRITE DATA\",\n READ_DATA: \"READ DATA\",\n RECALIBRATE: \"RECALIBRATE\",\n SENSE_INT: \"SENSE INTERRUPT\",\n READ_ID: \"READ ID\",\n FORMAT: \"FORMAT\",\n SEEK: \"SEEK\"\n };\n} else {\n FDC.CMDS = {};\n}\n\nFDC.aCmdInfo = {\n 0x03: {cbReq: 3, cbRes: 0, name: FDC.CMDS.SPECIFY},\n 0x04: {cbReq: 2, cbRes: 1, name: FDC.CMDS.SENSE_DRIVE},\n 0x05: {cbReq: 9, cbRes: 7, name: FDC.CMDS.WRITE_DATA},\n 0x06: {cbReq: 9, cbRes: 7, name: FDC.CMDS.READ_DATA},\n 0x07: {cbReq: 2, cbRes: 0, name: FDC.CMDS.RECALIBRATE},\n 0x08: {cbReq: 1, cbRes: 2, name: FDC.CMDS.SENSE_INT},\n 0x0A: {cbReq: 2, cbRes: 7, name: FDC.CMDS.READ_ID},\n 0x0D: {cbReq: 6, cbRes: 7, name: FDC.CMDS.FORMAT},\n 0x0F: {cbReq: 3, cbRes: 0, name: FDC.CMDS.SEEK}\n};\n\n/*\n * Port input notification table\n *\n * TODO: Even though port 0x3F7 was not present on controllers prior to MODEL_5170, I'm taking the easy\n * way out and always emulating it. So, consider an FDC parameter to disable that feature for stricter compatibility.\n */\nFDC.aPortInput = {\n 0x3F1: FDC.prototype.inFDCDiagnostic,\n 0x3F4: FDC.prototype.inFDCStatus,\n 0x3F5: FDC.prototype.inFDCData,\n 0x3F7: FDC.prototype.inFDCInput\n};\n\n/*\n * Port output notification table\n *\n * TODO: Even though port 0x3F7 was not present on controllers prior to MODEL_5170, I'm taking the easy\n * way out and always emulating it. So, consider an FDC parameter to disable that feature for stricter compatibility.\n */\nFDC.aPortOutput = {\n 0x3F2: FDC.prototype.outFDCOutput,\n 0x3F5: FDC.prototype.outFDCData,\n 0x3F7: FDC.prototype.outFDCControl\n};\n\n/*\n * Initialize every Floppy Drive Controller (FDC) module on the page.\n */\nWeb.onInit(FDC.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/hdc.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * class HDC\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass HDC extends Component {\n /**\n * HDC(parmsHDC)\n *\n * The HDC component simulates an STC-506/412 interface to an IBM-compatible fixed disk drive. The first\n * such drive was a 10Mb 5.25-inch drive containing two platters and 4 heads. Data spanned 306 cylinders\n * for a total of 1224 tracks, with 17 sectors/track and 512 bytes/sector. Support has since been expanded\n * to include the original PC AT Western Digital controller.\n *\n * HDC supports the following component-specific properties:\n *\n * drives: an array of driveConfig objects, each containing 'name', 'path', 'size' and 'type' properties\n * type: either 'XT' (for the PC XT Xebec controller) or 'AT' (for the PC AT Western Digital controller)\n *\n * The 'type' parameter defaults to 'XT'. All ports for the PC XT controller are referred to as XTC ports,\n * and similarly, all PC AT controller ports are referred to as ATC ports.\n *\n * If 'path' is empty, a scratch disk image is created; otherwise, we make a note of the path, but we will NOT\n * pre-load it like we do for floppy disk images.\n *\n * My current plan is to read all disk data on-demand, keeping a cache of what we've read, and possibly adding\n * some read-ahead as well. Any portions of the disk image that are written before being read will never be read.\n *\n * TRIVIA: On p.1-179 of the PC XT Technical Reference Manual (revised APR83), it reads:\n *\n * \"WARNING: The last cylinder on the fixed disk drive is reserved for diagnostic use.\n * Diagnostic write tests will destroy any data on this cylinder.\"\n *\n * Does FDISK insure that the last cylinder is reserved? I'm sure we'll eventually find out.\n *\n * @this {HDC}\n * @param {Object} parmsHDC\n */\n constructor(parmsHDC)\n {\n super(\"HDC\", parmsHDC, Messages.HDC);\n\n this['dmaRead'] = HDC.prototype.doDMARead;\n this['dmaWrite'] = HDC.prototype.doDMAWrite;\n this['dmaWriteBuffer'] = HDC.prototype.doDMAWriteBuffer;\n this['dmaWriteFormat'] = HDC.prototype.doDMAWriteFormat;\n\n this.aDriveConfigs = [];\n\n /*\n * We used to eval() sDriveConfigs immediately, but now we wait until initBus() is called, so that\n * we can check for any machine overrides.\n */\n this.sDriveConfigs = parmsHDC['drives'];\n\n /*\n * Set fATC (AT Controller flag) according to the 'type' parameter. This in turn determines other\n * defaults. For example, the default XT drive type is 3 (for a 10Mb disk drive), whereas the default\n * AT drive type is 2 (for a 20Mb disk drive).\n */\n var sType = parmsHDC['type'];\n this.fATC = sType && sType.toUpperCase() == \"AT\" || false;\n\n /*\n * Support for local disk images is currently limited to desktop browsers with FileReader support;\n * when this flag is set, setBinding() allows local disk bindings and informs initBus() to update the\n * \"listDisks\" binding accordingly.\n */\n this.fLocalDisks = (!Web.isMobile() && window && 'FileReader' in window);\n\n /*\n * The remainder of HDC initialization now takes place in our initBus() handler.\n */\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {HDC}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"listDisks\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var hdc = this;\n\n switch (sBinding) {\n\n case \"saveHD0\":\n case \"saveHD1\":\n /*\n * Yes, technically, this feature does not require \"Local disk support\" (which is really a reference\n * to FileReader support), but since fLocalDisks is also false for all mobile devices, and since there\n * is an \"orthogonality\" to disabling both features in tandem, let's just let it slide, OK?\n */\n if (!this.fLocalDisks) {\n if (DEBUG) this.log(\"Local disk support not available\");\n /*\n * We could also simply hide the control; eg:\n *\n * control.style.display = \"none\";\n *\n * but removing the control altogether seems better.\n */\n control.parentNode.removeChild(/** @type {Node} */ (control));\n return false;\n }\n this.bindings[sBinding] = control;\n control.onclick = function(iDrive) {\n return function onClickSaveDrive(event) {\n var drive = hdc.aDrives && hdc.aDrives[iDrive];\n if (drive && drive.disk) {\n /*\n * Note the similarity (and hence factoring opportunity) between this code and the FDC's\n * \"saveDisk\" binding.\n *\n * One important difference between the FDC and the HDC is that an FDC may or may not contain\n * a disk, whereas an HDC always contains a disk. However, the contents of an HDC's disk may\n * never have been initialized with the contents of an external disk image, and therefore the\n * disk's sDiskFile/sDiskPath properties may be undefined. sDiskName should always be defined\n * though, defaulting to the name of the drive (eg, \"10Mb Hard Disk\").\n */\n var disk = drive.disk;\n var sDiskName = disk.sDiskFile || disk.sDiskName;\n var i = sDiskName.lastIndexOf('.');\n if (i >= 0) sDiskName = sDiskName.substr(0, i);\n sDiskName += \".img\";\n if (DEBUG) hdc.println(\"saving disk \" + sDiskName + \"...\");\n var sAlert = Web.downloadFile(disk.encodeAsBase64(), \"octet-stream\", true, sDiskName);\n Component.alertUser(sAlert);\n } else {\n hdc.notice(\"Hard drive \" + iDrive + \" is not available.\");\n }\n };\n }(+sBinding.slice(-1));\n return true;\n }\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {HDC}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.cmp = cmp;\n\n var aDriveConfigs = cmp.getMachineParm('drives');\n if (aDriveConfigs) {\n if (typeof aDriveConfigs == \"string\") {\n this.sDriveConfigs = aDriveConfigs;\n } else {\n this.aDriveConfigs = aDriveConfigs;\n this.sDriveConfigs = \"\";\n }\n }\n \n if (this.sDriveConfigs) {\n try {\n /*\n * We must take care when parsing user-supplied JSON-encoded drive data.\n */\n this.aDriveConfigs = eval(\"(\" + this.sDriveConfigs + \")\");\n /*\n * Nothing more to do with aDriveConfigs now. initController() and autoMount() (if there are\n * any disk image \"path\" properties to process) will take care of the rest.\n */\n this.sDriveConfigs = \"\";\n } catch (e) {\n Component.error(\"HDC drive configuration error: \" + e.message + \" (\" + this.sDriveConfigs + \")\");\n }\n }\n\n /*\n * We need access to the ChipSet component, because we need to communicate with\n * the PIC and DMA controller.\n */\n this.chipset = cmp.getMachineComponent(\"ChipSet\");\n\n this.iDriveTable = 0;\n this.iDriveTypeDefault = 3;\n\n bus.addPortInputTable(this, this.fATC? HDC.aATCPortInput : HDC.aXTCPortInput);\n bus.addPortOutputTable(this, this.fATC? HDC.aATCPortOutput : HDC.aXTCPortOutput);\n\n if (this.fATC) {\n this.iDriveTable++;\n if (this.chipset && this.chipset.model == ChipSet.MODEL_COMPAQ_DESKPRO386) this.iDriveTable++;\n this.iDriveTypeDefault = 2;\n bus.addPortInputWidth(HDC.ATC.DATA.PORT, 2);\n bus.addPortOutputWidth(HDC.ATC.DATA.PORT, 2);\n }\n\n cpu.addIntNotify(Interrupts.DISK, this.intBIOSDisk.bind(this));\n cpu.addIntNotify(Interrupts.ALT_DISK, this.intBIOSDiskette.bind(this));\n\n /*\n * The following code used to be performed in the HDC constructor, but now we need to wait for information\n * about the Computer to be available (eg, getMachineID() and getUserID()) before we start loading and/or\n * connecting to disk images.\n *\n * If we didn't need auto-mount support, we could defer controller initialization until we received a powerUp()\n * notification, at which point reset() would call initController(), or restore() would restore the controller;\n * in that case, all we'd need to do here is call setReady().\n */\n this.reset();\n\n if (!this.autoMount()) this.setReady();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {HDC}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.initController();\n if (this.cmp.fReload) {\n /*\n * If the computer's fReload flag is set, we're required to toss all currently\n * loaded disks and remount all disks specified in the auto-mount configuration.\n */\n this.autoMount(true);\n }\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {HDC}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean}\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * getMachineID()\n *\n * @return {string}\n */\n getMachineID()\n {\n return this.cmp? this.cmp.getMachineID() : \"\";\n }\n\n /**\n * getUserID()\n *\n * @return {string}\n */\n getUserID()\n {\n return this.cmp? this.cmp.getUserID() : \"\";\n }\n\n /**\n * reset()\n *\n * @this {HDC}\n */\n reset()\n {\n /*\n * TODO: The controller is also initialized by the constructor, to assist with auto-mount support,\n * so think about whether we can skip powerUp initialization.\n */\n this.initController(null, true);\n }\n\n /**\n * save()\n *\n * This implements save support for the HDC component.\n *\n * @this {HDC}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveController());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the HDC component.\n *\n * @this {HDC}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return this.initController(data[0]);\n }\n\n /**\n * initController(data, fHard)\n *\n * @this {HDC}\n * @param {Array} [data]\n * @param {boolean} [fHard] true if a machine reset (not just a controller reset)\n * @return {boolean} true if successful, false if failure\n */\n initController(data, fHard)\n {\n var i = 0;\n var fSuccess = true;\n\n /*\n * TODO: This is used to re-select the controller's active drive whenever the machine is restored, but alas,\n * we currently only update it and save it for the ATC, not the XTC.\n */\n this.iDrive = -1;\n\n /*\n * At this point, it's worth calling into question my decision to NOT split the HDC component into separate XTC\n * and ATC components, given all the differences, and given that I'm about to write some \"if (ATC) else (XTC) ...\"\n * code. And all I can say in my defense is, yes, it's definitely worth calling that into question.\n *\n * However, there's also some common code, mostly in the area of disk management rather than controller management,\n * and if the components were split, then I'd have to create a third component for that common code (although again,\n * disk management probably belongs in its own component anyway).\n *\n * However, let's not forget that since my overall plan is to have only one PCx86 \"binary\", everything's going to end\n * up in the same bucket anyway, so let's not be too obsessive about organizational details. As long as the number\n * of these conditionals is small and they're not performance-critical, this seems much ado about nothing.\n */\n if (this.fATC) {\n /*\n * Since there's no way (and never will be a way) for an HDC to change its \"personality\" (from 'xt' to 'at'\n * or vice versa), we're under no obligation to use the same number of registers, or save/restore format, etc,\n * as the original XT controller.\n */\n if (data == null) data = [0, 0, 0, 0, 0, 0, 0, HDC.ATC.STATUS.READY, 0, [0, -1]];\n this.regError = data[i++];\n this.regWPreC = data[i++];\n this.regSecCnt = data[i++];\n this.regSecNum = data[i++];\n this.regCylLo = data[i++];\n this.regCylHi = data[i++];\n this.regDrvHd = data[i++];\n this.regStatus = data[i++];\n this.regCommand = data[i++];\n this.regFDR = data[i++];\n if (typeof this.regFDR == \"object\") {\n var a = this.regFDR;\n this.regFDR = a[0];\n this.iDrive = a[1];\n }\n /*\n * Additional state is maintained by the Drive object (eg, abSector, ibSector)\n */\n } else {\n if (data == null) data = [0, HDC.XTC.STATUS.NONE, new Array(14), 0, 0];\n this.regConfig = data[i++];\n this.regStatus = data[i++];\n this.regDataArray = data[i++]; // there can be up to 14 command bytes (6 for normal commands, plus 8 more for HDC.XTC.DATA.CMD.INIT_DRIVE)\n this.regDataIndex = data[i++]; // used to control the next data byte to be received\n this.regDataTotal = data[i++]; // used to control the next data byte to be sent (internally, we use regDataIndex to read data bytes, up to this total)\n this.regReset = data[i++];\n this.regPulse = data[i++];\n this.regPattern = data[i++];\n /*\n * Initialize iDriveAllowFail only if it's never been initialized, otherwise its entire purpose will be defeated.\n * See the related HACK in intBIOSDisk() for more details.\n */\n var iDriveAllowFail = data[i++];\n if (iDriveAllowFail !== undefined) {\n this.iDriveAllowFail = iDriveAllowFail;\n } else {\n if (this.iDriveAllowFail === undefined) this.iDriveAllowFail = -1;\n }\n }\n\n if (this.aDrives === undefined) {\n this.aDrives = new Array(this.aDriveConfigs.length);\n }\n\n var dataDrives = data[i];\n if (dataDrives === undefined) dataDrives = [];\n\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n if (this.aDrives[iDrive] === undefined) {\n this.aDrives[iDrive] = {};\n }\n var drive = this.aDrives[iDrive];\n var driveConfig = this.aDriveConfigs[iDrive];\n if (!this.initDrive(iDrive, drive, driveConfig, dataDrives[iDrive], fHard)) {\n fSuccess = false;\n }\n /*\n * XTC only: the original STC-506/412 controller had two pairs of DIP switches to indicate a drive\n * type (0, 1, 2 or 3) for drives 0 and 1. Those switch settings are recorded in regConfig, now that\n * drive.type has been validated by initDrive().\n */\n if (this.regConfig != null && iDrive <= 1) {\n this.regConfig |= (drive.type & 0x3) << ((1 - iDrive) << 1);\n }\n }\n\n if (this.iDrive >= 0) {\n this.drive = this.aDrives[this.iDrive];\n }\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"HDC initialized for \" + this.aDrives.length + \" drive(s)\");\n }\n return fSuccess;\n }\n\n /**\n * saveController()\n *\n * @this {HDC}\n * @return {Array}\n */\n saveController()\n {\n var i = 0;\n var data = [];\n if (this.fATC) {\n data[i++] = this.regError;\n data[i++] = this.regWPreC;\n data[i++] = this.regSecCnt;\n data[i++] = this.regSecNum;\n data[i++] = this.regCylLo;\n data[i++] = this.regCylHi;\n data[i++] = this.regDrvHd;\n data[i++] = this.regStatus;\n data[i++] = this.regCommand;\n data[i++] = [this.regFDR, this.iDrive];\n } else {\n data[i++] = this.regConfig;\n data[i++] = this.regStatus;\n data[i++] = this.regDataArray;\n data[i++] = this.regDataIndex;\n data[i++] = this.regDataTotal;\n data[i++] = this.regReset;\n data[i++] = this.regPulse;\n data[i++] = this.regPattern;\n data[i++] = this.iDriveAllowFail;\n }\n data[i] = this.saveDrives();\n return data;\n }\n\n /**\n * initDrive(iDrive, drive, driveConfig, data, fHard)\n *\n * TODO: Consider a separate Drive class that both FDC and HDC can use, since there's a lot of commonality\n * between the drive objects created by both controllers. This will clean up overall drive management and allow\n * us to factor out some common Drive methods (eg, advanceSector()).\n *\n * @this {HDC}\n * @param {number} iDrive\n * @param {Object} drive\n * @param {Object} driveConfig (contains one or more of the following properties: 'name', 'path', 'size', 'type')\n * @param {Array} [data]\n * @param {boolean} [fHard] true if a machine reset (not just a controller reset)\n * @return {boolean} true if successful, false if failure\n */\n initDrive(iDrive, drive, driveConfig, data, fHard)\n {\n var i = 0;\n var fSuccess = true;\n if (data === undefined) data = [HDC.XTC.DATA.ERR.NONE, 0, false, new Array(8)];\n\n drive.iDrive = iDrive;\n\n /*\n * errorCode could be an HDC global, but in order to insulate HDC state from the operation of various functions\n * that operate on drive objects (eg, readData and writeData), I've made it a per-drive variable. This choice may\n * be contrary to how the actual hardware works, but I prefer this approach, as long as it doesn't expose any\n * incompatibilities that any software actually cares about.\n */\n drive.errorCode = data[i++];\n drive.senseCode = data[i++];\n drive.fRemovable = data[i++];\n drive.abDriveParms = data[i++]; // captures drive parameters programmed via HDC.XTC.DATA.CMD.INIT_DRIVE\n\n /*\n * TODO: Make abSector a DWORD array rather than a BYTE array (we could even allocate a Memory block for it);\n * alternatively, eliminate the buffer entirely and re-establish a reference to the appropriate Disk sector object.\n */\n drive.abSector = data[i++];\n\n /*\n * The next group of properties are set by various HDC command sequences.\n */\n drive.bHead = data[i++];\n drive.nHeads = data[i++];\n drive.wCylinder = data[i++];\n drive.bSector = data[i++];\n drive.bSectorEnd = data[i++]; // aka EOT\n drive.nBytes = data[i++];\n drive.bSectorBias = (this.fATC? 0: 1);\n\n drive.name = driveConfig['name'];\n if (drive.name === undefined) drive.name = HDC.DEFAULT_DRIVE_NAME;\n drive.path = driveConfig['path'];\n\n /*\n * If no 'mode' is specified, we fall back to the original behavior, which is to completely preload\n * any specific disk image, or create an empty (purely local) disk image.\n */\n drive.mode = driveConfig['mode'] || (drive.path? DiskAPI.MODE.PRELOAD : DiskAPI.MODE.LOCAL);\n\n /*\n * On-demand I/O of raw disk images is supported only if there's a valid user ID; fall back to an empty\n * local disk image if there's not.\n */\n if (drive.mode == DiskAPI.MODE.DEMANDRO || drive.mode == DiskAPI.MODE.DEMANDRW) {\n if (!this.getUserID()) drive.mode = DiskAPI.MODE.LOCAL;\n }\n\n drive.type = driveConfig['type'];\n if (drive.type === undefined || HDC.aDriveTypes[this.iDriveTable][drive.type] === undefined) drive.type = this.iDriveTypeDefault;\n\n var driveType = HDC.aDriveTypes[this.iDriveTable][drive.type];\n drive.nSectors = driveType[2] || 17; // sectors/track\n drive.cbSector = driveType[3] || 512; // bytes/sector (default is 512 if unspecified in the table)\n\n /*\n * On a full machine reset, pass the current drive type to setCMOSDriveType() (a no-op on pre-CMOS machines)\n */\n if (fHard && this.chipset) {\n this.chipset.setCMOSDriveType(iDrive, drive.type);\n }\n\n /*\n * The next group of properties are set by user requests to load/unload disk images.\n *\n * We no longer reinitialize drive.disk, in order to retain previously mounted disk across resets.\n */\n if (drive.disk === undefined) {\n drive.disk = null;\n this.notice(\"Type \" + drive.type + \" \\\"\" + drive.name + \"\\\" is fixed disk \" + iDrive, true);\n }\n\n /*\n * With the advent of save/restore, we need to verify every drive at initialization, not just whenever\n * drive characteristics are initialized. Thus, if we've restored a sensible set of drive characteristics,\n * then verifyDrive will create an empty disk if none has been provided, insuring we are ready for\n * disk.restore().\n */\n this.verifyDrive(drive);\n\n /*\n * The next group of properties are managed by worker functions (eg, doRead()) to maintain state across DMA requests.\n */\n drive.ibSector = data[i++]; // location of the next byte to be accessed in the above sector\n drive.sector = null; // initialized to null by worker, and then set to the next sector satisfying the request\n\n if (drive.disk) {\n var deltas = data[i];\n if (deltas !== undefined && drive.disk.restore(deltas) < 0) {\n fSuccess = false;\n }\n if (fSuccess && drive.ibSector !== undefined) {\n drive.sector = drive.disk.seek(drive.wCylinder, drive.bHead, drive.bSector + drive.bSectorBias);\n }\n }\n return fSuccess;\n }\n\n /**\n * saveDrives()\n *\n * @this {HDC}\n * @return {Array}\n */\n saveDrives()\n {\n var i = 0;\n var data = [];\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n data[i++] = this.saveDrive(this.aDrives[iDrive]);\n }\n return data;\n }\n\n /**\n * saveDrive(drive)\n *\n * @this {HDC}\n * @return {Array}\n */\n saveDrive(drive)\n {\n var i = 0;\n var data = [];\n data[i++] = drive.errorCode;\n data[i++] = drive.senseCode;\n data[i++] = drive.fRemovable;\n data[i++] = drive.abDriveParms;\n data[i++] = drive.abSector;\n data[i++] = drive.bHead;\n data[i++] = drive.nHeads;\n data[i++] = drive.wCylinder;\n data[i++] = drive.bSector;\n data[i++] = drive.bSectorEnd;\n data[i++] = drive.nBytes;\n data[i++] = drive.ibSector;\n data[i] = drive.disk? drive.disk.save() : null;\n return data;\n }\n\n /**\n * copyDrive(iDrive)\n *\n * @this {HDC}\n * @param {number} iDrive\n * @return {Object|undefined} (undefined if the requested drive does not exist)\n */\n copyDrive(iDrive)\n {\n var driveNew;\n var driveOld = this.aDrives[iDrive];\n if (driveOld !== undefined) {\n driveNew = {};\n for (var p in driveOld) {\n driveNew[p] = driveOld[p];\n }\n }\n return driveNew;\n }\n\n /**\n * verifyDrive(drive, type)\n *\n * If no disk image is attached, create an empty disk with the specified drive characteristics.\n * Normally, we'd rely on the drive characteristics programmed via the HDC.XTC.DATA.CMD.INIT_DRIVE\n * command, but if an explicit drive type is specified, then we use the characteristics (geometry)\n * associated with that type.\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {number} [type] to create a disk of the specified type, if no disk exists yet\n */\n verifyDrive(drive, type)\n {\n if (drive) {\n var nHeads = 0, nCylinders = 0;\n if (type == null) {\n /*\n * If the caller wants us to use the programmed drive parameters, we use those,\n * but if there aren't any drive parameters (yet), then use default parameters based\n * on drive.type.\n *\n * We used to do the last step ONLY if there was no drive.path -- otherwise, we'd waste\n * time creating an empty disk if autoMount() was going to load an image from drive.path;\n * but hopefully the Disk component is smarter now.\n */\n nHeads = drive.abDriveParms[2];\n if (nHeads) {\n nCylinders = (drive.abDriveParms[0] << 8) | drive.abDriveParms[1];\n } else {\n type = drive.type;\n }\n }\n if (type != null && !nHeads) {\n nHeads = HDC.aDriveTypes[this.iDriveTable][type][1];\n nCylinders = HDC.aDriveTypes[this.iDriveTable][type][0];\n }\n if (nHeads) {\n /*\n * The assumption here is that if the 3rd drive parameter byte (abDriveParms[2]) has been set\n * (ie, if nHeads is valid) then the first two bytes (ie, the low and high cylinder byte values)\n * must have been set as well.\n *\n * Do these values agree with those for the given drive type? Even if they don't, all we do is warn.\n */\n var driveType = HDC.aDriveTypes[this.iDriveTable][drive.type];\n if (driveType) {\n if (nCylinders != driveType[0] && nHeads != driveType[1]) {\n this.notice(\"Warning: drive parameters (\" + nCylinders + \",\" + nHeads + \") do not match drive type \" + drive.type + \" (\" + driveType[0] + \",\" + driveType[1] + \")\");\n }\n }\n drive.nCylinders = nCylinders;\n drive.nHeads = nHeads;\n if (drive.disk == null) {\n drive.disk = new Disk(this, drive, drive.mode);\n }\n }\n }\n }\n\n /**\n * seekDrive(drive, iSector, nSectors)\n *\n * The HDC doesn't need this function, since all HDC requests from the CPU are handled by doXTCmd(). This function\n * is used by other components (eg, Debugger) to mimic an HDC request, using a drive object obtained from copyDrive(),\n * to avoid disturbing the internal state of the HDC's drive objects.\n *\n * Also note that in an actual HDC request, drive.nBytes is initialized to the size of a single sector; the extent\n * of the entire transfer is actually determined by a count that has been pre-loaded into the DMA controller. The HDC\n * isn't aware of the extent of the transfer, so in the case of a read request, all readData() can do is return bytes\n * until the current track (or, in the case of a multi-track request, the current cylinder) has been exhausted.\n *\n * Since seekDrive() is for use with non-DMA requests, we use nBytes to specify the length of the entire transfer.\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {number} iSector (a \"logical\" sector number, relative to the entire disk, NOT a physical sector number)\n * @param {number} nSectors\n * @return {boolean} true if successful, false if invalid position request\n */\n seekDrive(drive, iSector, nSectors)\n {\n if (drive.disk) {\n var aDiskInfo = drive.disk.info();\n var nCylinders = aDiskInfo[0];\n /*\n * If nCylinders is zero, we probably have an empty disk image, awaiting initialization (see verifyDrive())\n */\n if (nCylinders) {\n var nHeads = aDiskInfo[1];\n var nSectorsPerTrack = aDiskInfo[2];\n var nSectorsPerCylinder = nHeads * nSectorsPerTrack;\n var nSectorsPerDisk = nCylinders * nSectorsPerCylinder;\n if (iSector + nSectors <= nSectorsPerDisk) {\n drive.wCylinder = Math.floor(iSector / nSectorsPerCylinder);\n iSector %= nSectorsPerCylinder;\n drive.bHead = Math.floor(iSector / nSectorsPerTrack);\n /*\n * Important difference between the FDC and the XTC: the XTC uses 0-based sector numbers, so unlike\n * FDC.seekDrive(), we must NOT add 1 to bSector below. I could change how sector numbers are stored in\n * hard drive images, but it seems preferable to keep the image format consistent and controller-independent.\n */\n drive.bSector = (iSector % nSectorsPerTrack);\n drive.nBytes = nSectors * aDiskInfo[3];\n /*\n * NOTE: We don't set nSectorEnd, as an HDC command would, but it's irrelevant, because we don't actually\n * do anything with nSectorEnd at this point. Perhaps someday, when we faithfully honor/restrict requests\n * to a single track (or a single cylinder, in the case of multi-track requests).\n */\n drive.errorCode = HDC.XTC.DATA.ERR.NONE;\n /*\n * At this point, we've finished simulating what an HDC.XTC.DATA.CMD.READ_DATA command would have performed,\n * up through doRead(). Now it's the caller responsibility to call readData(), like the DMA Controller would.\n */\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * autoMount(fRemount)\n *\n * @this {HDC}\n * @param {boolean} [fRemount] is true if we're remounting all auto-mounted disks\n * @return {boolean} true if one or more disk images are being auto-mounted, false if none\n */\n autoMount(fRemount)\n {\n if (!fRemount) this.cAutoMount = 0;\n\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n var drive = this.aDrives[iDrive];\n if (drive.name && drive.path) {\n\n if (fRemount && drive.disk && drive.disk.isRemote()) {\n /*\n * The Disk component has its own logic for remounting remote disks, so skip this disk.\n *\n * TODO: Consider rewriting how ALL disks are automounted/remounted, now that the Disk component\n * is receiving its own powerDown() and powerUp() notifications (originally, it didn't receive them).\n */\n continue;\n }\n\n if (!this.loadDisk(iDrive, drive.name, drive.path, true) && fRemount)\n this.setReady(false);\n continue;\n }\n if (fRemount && drive.type !== undefined) {\n drive.disk = null;\n this.verifyDrive(drive, drive.type);\n }\n }\n return !!this.cAutoMount;\n }\n\n /**\n * loadDisk(iDrive, sDiskName, sDiskPath, fAutoMount)\n *\n * @this {HDC}\n * @param {number} iDrive\n * @param {string} sDiskName\n * @param {string} sDiskPath\n * @param {boolean} fAutoMount\n * @return {boolean} true if disk (already) loaded, false if queued up (or busy)\n */\n loadDisk(iDrive, sDiskName, sDiskPath, fAutoMount)\n {\n var drive = this.aDrives[iDrive];\n if (drive.fBusy) {\n this.notice(\"Drive \" + iDrive + \" busy\");\n return true;\n }\n drive.fBusy = true;\n if (fAutoMount) {\n drive.fAutoMount = true;\n this.cAutoMount++;\n if (this.messageEnabled()) this.printMessage(\"loading \" + sDiskName);\n }\n var disk = drive.disk || new Disk(this, drive, drive.mode);\n /*\n * The following hacks should only be necessary for (old) saved states, since all our disk manifests\n * should no longer be using any of these old paths.\n */\n sDiskPath = sDiskPath.replace(\"/disks/pc/\", \"/disks/pcx86/\");\n sDiskPath = sDiskPath.replace(\"/disks/pcx86/private/\", \"/private-disks/pcx86/\");\n sDiskPath = sDiskPath.replace(\"/disks/pcx86/\", \"/pcjs-disks/pcx86/\");\n sDiskPath = sDiskPath.replace(\"/fixed/\", \"/drives/\");\n disk.load(sDiskName, sDiskPath, null, this.doneLoadDisk);\n return false;\n }\n\n /**\n * doneLoadDisk(drive, disk, sDiskName, sDiskPath)\n *\n * This is a callback issued by the Disk component once the load() operation has finished.\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {Disk} disk is set if the disk was successfully mounted, null if not\n * @param {string} sDiskName\n * @param {string} sDiskPath\n */\n doneLoadDisk(drive, disk, sDiskName, sDiskPath)\n {\n drive.fBusy = false;\n if ((drive.disk = disk)) {\n /*\n * With the addition of notice(), users are now \"alerted\" whenever a diskette has finished loading;\n * notice() is selective about its output, using print() if a print window is open, otherwise alert().\n *\n * WARNING: This conversion of drive number to drive letter, starting with \"C:\" (0x43), is very simplistic\n * and is not guaranteed to match the drive mapping that DOS ultimately uses.\n */\n this.notice(\"Mounted disk \\\"\" + sDiskName + \"\\\" in drive \" + String.fromCharCode(0x43 + drive.iDrive), drive.fAutoMount);\n\n var aDiskInfo = disk.info();\n if (aDiskInfo[0] != drive.nCylinders || aDiskInfo[1] != drive.nHeads || aDiskInfo[2] != drive.nSectors || aDiskInfo[3] != drive.cbSector) {\n /*\n * TODO: Decide how to deal with this problem; ie, either disallow disk access altogether, or automatically\n * map the controller's I/O requests to the disk's geometry. Also, we should provide a way to reformat such a\n * disk so that its geometry matches the controller requirements.\n */\n this.notice(\"Warning: disk geometry (\" + aDiskInfo[0] + ':' + aDiskInfo[1] + ':' + aDiskInfo[2] + \") does not match \" + HDC.aDriveTables[this.iDriveTable] + \" drive type \" + drive.type + \" (\" + drive.nCylinders + ':' + drive.nHeads + ':' + drive.nSectors + \")\");\n }\n }\n if (drive.fAutoMount) {\n drive.fAutoMount = false;\n if (!--this.cAutoMount) this.setReady();\n }\n }\n\n /**\n * intXTCData(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x320)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inXTCData(port, addrFrom)\n {\n var bIn = 0;\n if (this.regDataIndex < this.regDataTotal) {\n bIn = this.regDataArray[this.regDataIndex];\n }\n if (this.chipset) this.chipset.clearIRR(ChipSet.IRQ.XTC);\n this.regStatus &= ~HDC.XTC.STATUS.INTERRUPT;\n\n this.printMessageIO(port, null, addrFrom, \"DATA[\" + this.regDataIndex + \"]\", bIn);\n if (++this.regDataIndex >= this.regDataTotal) {\n this.regDataIndex = this.regDataTotal = 0;\n this.regStatus &= ~(HDC.XTC.STATUS.IOMODE | HDC.XTC.STATUS.BUS | HDC.XTC.STATUS.BUSY);\n }\n return bIn;\n }\n\n /**\n * outXTCData(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x320)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outXTCData(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"DATA[\" + this.regDataTotal + \"]\");\n if (this.regDataTotal < this.regDataArray.length) {\n this.regDataArray[this.regDataTotal++] = bOut;\n }\n var bCmd = this.regDataArray[0];\n var cbCmd = (bCmd != HDC.XTC.DATA.CMD.INIT_DRIVE? 6 : this.regDataArray.length);\n if (this.regDataTotal == 6) {\n /*\n * XTC.STATUS.REQ must be CLEAR following any 6-byte command sequence that the HDC BIOS \"COMMAND\" function outputs,\n * yet it must also be SET before the HDC BIOS will proceed with the remaining the 8-byte sequence that's part of\n * HDC.XTC.DATA.CMD.INIT_DRIVE command. See inXTCStatus() for HACK details.\n */\n this.regStatus &= ~HDC.XTC.STATUS.REQ;\n }\n if (this.regDataTotal >= cbCmd) {\n /*\n * It's essential that XTC.STATUS.IOMODE be set here, at least after the final 8-byte HDC.XTC.DATA.CMD.INIT_DRIVE sequence.\n */\n this.regStatus |= HDC.XTC.STATUS.IOMODE;\n this.regStatus &= ~HDC.XTC.STATUS.REQ;\n this.doXTC();\n }\n }\n\n /**\n * inXTCStatus(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x321)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inXTCStatus(port, addrFrom)\n {\n var b = this.regStatus;\n this.printMessageIO(port, null, addrFrom, \"STATUS\", b);\n /*\n * HACK: The HDC BIOS will not finish the HDC.XTC.DATA.CMD.INIT_DRIVE sequence unless it sees XTC.STATUS.REQ set again, nor will\n * it read any of the XTC.DATA bytes returned from a HDC.XTC.DATA.CMD.REQUEST_SENSE command unless XTC.STATUS.REQ is set again, so\n * we turn it back on if there are unprocessed data bytes.\n */\n if (this.regDataIndex < this.regDataTotal) {\n this.regStatus |= HDC.XTC.STATUS.REQ;\n }\n return b;\n }\n\n /**\n * outXTCReset(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x321)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outXTCReset(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"RESET\");\n /*\n * Not sure what to do with this value, and the value itself may be \"don't care\", but we'll save it anyway.\n */\n this.regReset = bOut;\n if (this.chipset) this.chipset.clearIRR(ChipSet.IRQ.XTC);\n this.initController();\n }\n\n /**\n * inXTCConfig(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x322)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inXTCConfig(port, addrFrom)\n {\n this.printMessageIO(port, null, addrFrom, \"CONFIG\", this.regConfig);\n return this.regConfig;\n }\n\n /**\n * outXTCPulse(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x322)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outXTCPulse(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"PULSE\");\n /*\n * Not sure what to do with this value, and the value itself may be \"don't care\", but we'll save it anyway.\n */\n this.regPulse = bOut;\n /*\n * The HDC BIOS \"COMMAND\" function (@C800:0562) waits for these ALL status bits after writing to both regPulse\n * and regPattern, so we must oblige it.\n *\n * TODO: Figure out exactly when either XTC.STATUS.BUS or XTC.STATUS.BUSY are supposed to be cleared.\n * The HDC BIOS doesn't care much about them, except for the one location mentioned above. However, MS-DOS 4.0\n * (aka the unreleased \"multitasking\" version of MS-DOS) cares, so I'm going to start by clearing them at the\n * same point I clear XTC.STATUS.IOMODE.\n */\n this.regStatus = HDC.XTC.STATUS.REQ | HDC.XTC.STATUS.BUS | HDC.XTC.STATUS.BUSY;\n }\n\n /**\n * outXTCPattern(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x323)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outXTCPattern(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"PATTERN\");\n this.regPattern = bOut;\n }\n\n /**\n * outXTCNoise(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x327, 0x32B or 0x32F)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outXTCNoise(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"NOISE\");\n }\n\n /**\n * inATCByte(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F0)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inATCByte(port, addrFrom)\n {\n var bIn = -1;\n\n if (this.drive) {\n /*\n * We use the synchronous form of readData() at this point because we have no choice; an I/O instruction\n * has just occurred and cannot be delayed. The good news is that doATCommand() should have already primed\n * the pump; all we can do is assert that the pump has something in it. If bIn is inexplicably negative,\n * well, then the caller will get 0xff.\n */\n var hdc = this;\n bIn = this.readData(this.drive, function onATCReadData(b, fAsync, obj, off) {\n\n if (BACKTRACK) {\n if (!off && obj.file && hdc.messageEnabled(Messages.DISK)) {\n hdc.printMessage(\"loading \" + obj.file.sPath + '[' + obj.offFile + \"] via port \" + Str.toHexWord(port), true);\n }\n /*\n * TODO: We could define a cached BTO that's reset prior to a new ATC command, and then pass that\n * to addBackTrackObject() here instead of null; but for now, we're going to rely on that function's\n * simplistic MRU logic. If that fails, the worst that will (or should) happen is we'll burn through\n * more BackTrack wrapper objects than necessary, and risk running out.\n */\n var bto = hdc.bus.addBackTrackObject(obj, /** @type BackTrack */ (null), off);\n hdc.cpu.backTrack.btiIO = hdc.bus.getBackTrackIndex(bto, off);\n }\n });\n\n\n if (this.drive.ibSector == 1 || this.drive.ibSector == this.drive.cbSector) {\n /*\n * printMessageIO() calls, if enabled, can be overwhelming for this port, so limit them to the first\n * and last bytes of each sector.\n */\n if (this.messageEnabled(Messages.PORT | Messages.HDC)) {\n this.printMessageIO(port, null, addrFrom, \"DATA[\" + this.drive.ibSector + \"]\", bIn);\n }\n if (this.drive.ibSector > 1) { // in other words, if this.drive.ibSector == this.drive.cbSector...\n if (this.messageEnabled(Messages.DATA | Messages.HDC)) {\n var sDump = this.drive.disk.dumpSector(this.drive.sector);\n if (sDump) this.dbg.message(sDump);\n }\n /*\n * Now that we've supplied a full sector of data, see if the caller's expecting additional sectors;\n * if so, prime the pump again. The caller should not poll us again until another interrupt's delivered.\n */\n this.drive.nBytes -= this.drive.cbSector;\n this.regSecCnt = (this.regSecCnt - 1) & 0xff;\n /*\n * TODO: If the WITH_ECC bit is set in the READ_DATA command, then we need to support \"stuffing\" 4\n * additional bytes into the inATCByte() stream. And we must first set DATA_REQ in the STATUS register.\n */\n if (this.drive.nBytes >= this.drive.cbSector) {\n /*\n * FYI, with regard to regStatus, I'm simply aping what the ATC.COMMAND.READ_DATA setup code does\n * for the first sector, which may not strictly be necessary for subsequent sectors....\n */\n hdc.regStatus = HDC.ATC.STATUS.BUSY;\n this.readData(this.drive, function onATCReadDataNext(b, fAsync) {\n if (b >= 0) {\n hdc.setATCIRR();\n /*\n * Due to the way I'm immediately triggering an interrupt whenever more data is available,\n * I must take a \"shotgun approach' to regStatus bits in order to make the MODEL_5170_REV1,\n * MODEL_5170_REV3, and MODEL_COMPAQ_DESKPRO386 all happy.\n *\n * In general, it's fine for all of STATUS.READY, STATUS.SEEK_OK and STATUS.DATA_REQ to be\n * set now; the MODEL_5170_REV3 requires at least the first two, and the MODEL_COMPAQ_DESKPRO386\n * requires the third. Unfortunately, the outlier is the MODEL_5170_REV1, which also needs\n * the STATUS.BUSY to be set on the first regStatus read after it finishes reading a sector;\n * otherwise, the MODEL_5170_REV1 BIOS will never read any remaining sectors.\n *\n * Technically, it doesn't make sense for both BUSY and READY to be set at the same time,\n * so we fix that in inATCStatus() by clearing BUSY whenever READY is detected *after* that\n * first read. In addition, since this hack is really only needed for the MODEL_5170_REV1,\n * we clear BUSY immediately on the MODEL_COMPAQ_DESKPRO386 (which makes the Windows 95\n * protected-mode disk driver much happier).\n */\n if (hdc.chipset && hdc.chipset.model == ChipSet.MODEL_COMPAQ_DESKPRO386) hdc.regStatus = 0;\n hdc.regStatus |= HDC.ATC.STATUS.READY | HDC.ATC.STATUS.SEEK_OK | HDC.ATC.STATUS.DATA_REQ;\n } else {\n /*\n * TODO: It would be nice to be a bit more specific about the error (if any) that just occurred.\n * Consult drive.errorCode (it uses older XTC error codes, but mapping those codes should be trivial).\n */\n hdc.regStatus = HDC.ATC.STATUS.ERROR;\n hdc.regError = HDC.ATC.ERROR.NO_CHS;\n if (DEBUG) hdc.printMessage(this.idComponent + \".inATCByte(): read failed\");\n }\n }, false);\n } else {\n\n this.regStatus = HDC.ATC.STATUS.READY | HDC.ATC.STATUS.SEEK_OK;\n }\n }\n }\n }\n return bIn;\n }\n\n /**\n * inATCData(port, addrFrom)\n *\n * Wrapper around inATCByte() to treat this as a 16-bit port; see addPortInputWidth(HDC.ATC.DATA.PORT, 2).\n *\n * @this {HDC}\n * @param {number} port (0x1F0)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port data\n */\n inATCData(port, addrFrom)\n {\n return this.inATCByte(port, addrFrom) | (this.inATCByte(port, addrFrom) << 8);\n }\n\n /**\n * outATCByte(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F0)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outATCByte(port, bOut, addrFrom)\n {\n if (this.drive) {\n if (this.drive.nBytes >= this.drive.cbSector) {\n if (this.writeData(this.drive, bOut) < 0) {\n /*\n * TODO: It would be nice to be a bit more specific about the error (if any) that just occurred.\n * Consult drive.errorCode (it uses older XTC error codes, but mapping those codes should be trivial).\n */\n this.regStatus = HDC.ATC.STATUS.ERROR;\n this.regError = HDC.ATC.ERROR.NO_CHS;\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".outATCByte(\" + Str.toHexByte(bOut) + \"): write failed\");\n }\n }\n else if (this.drive.ibSector == 1 || this.drive.ibSector == this.drive.cbSector) {\n /*\n * printMessageIO() calls, if enabled, can be overwhelming for this port, so limit them to the first\n * and last bytes of each sector.\n */\n if (this.messageEnabled(Messages.PORT | Messages.HDC)) {\n this.printMessageIO(port, bOut, addrFrom, \"DATA[\" + this.drive.ibSector + \"]\");\n }\n if (this.drive.ibSector > 1) { // in other words, if this.drive.ibSector == this.drive.cbSector...\n if (this.messageEnabled(Messages.DATA | Messages.HDC)) {\n var sDump = this.drive.disk.dumpSector(this.drive.sector);\n if (sDump) this.dbg.message(sDump);\n }\n this.drive.nBytes -= this.drive.cbSector;\n this.regSecCnt = (this.regSecCnt - 1) & 0xff;\n this.setATCIRR(true);\n this.regStatus = HDC.ATC.STATUS.READY | HDC.ATC.STATUS.SEEK_OK;\n if (this.drive.nBytes >= this.drive.cbSector) {\n this.regStatus |= HDC.ATC.STATUS.DATA_REQ;\n } else {\n\n }\n }\n }\n } else {\n /*\n * TODO: What to do about unexpected writes? The number of bytes has exceeded what the command specified.\n */\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".outATCByte(\" + Str.toHexByte(bOut) + \"): write exceeds count (\" + this.drive.nBytes + \")\");\n }\n }\n } else {\n /*\n * TODO: What to do about unexpected writes? No command was specified.\n */\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".outATCByte(\" + Str.toHexByte(bOut) + \"): write without command\");\n }\n }\n }\n\n /**\n * outATCData(port, data, addrFrom)\n *\n * Wrapper around outATCByte() to treat this as a 16-bit port; see addPortOutputWidth(HDC.ATC.DATA.PORT, 2)\n *\n * @this {HDC}\n * @param {number} port (0x1F0)\n * @param {number} data\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outATCData(port, data, addrFrom)\n {\n this.outATCByte(port, data & 0xff, addrFrom);\n this.outATCByte(port, (data >> 8) & 0xff, addrFrom);\n }\n\n /**\n * inATCError(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F1)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inATCError(port, addrFrom)\n {\n var bIn = this.regError;\n this.printMessageIO(port, null, addrFrom, \"ERROR\", bIn);\n return bIn;\n }\n\n /**\n * outATCWPreC(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F1)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outATCWPreC(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"WPREC\");\n this.regWPreC = bOut;\n }\n\n /**\n * inATCSecCnt(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F2)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inATCSecCnt(port, addrFrom)\n {\n var bIn = this.regSecCnt;\n this.printMessageIO(port, null, addrFrom, \"SECCNT\", bIn);\n return bIn;\n }\n\n /**\n * outATCSecCnt(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F2)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outATCSecCnt(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"SECCNT\");\n this.regSecCnt = bOut;\n }\n\n /**\n * inATCSecNum(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F3)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inATCSecNum(port, addrFrom)\n {\n var bIn = this.regSecNum;\n this.printMessageIO(port, null, addrFrom, \"SECNUM\", bIn);\n return bIn;\n }\n\n /**\n * outATCSecNum(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F3)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outATCSecNum(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"SECNUM\");\n this.regSecNum = bOut;\n }\n\n /**\n * inATCCylLo(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F4)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inATCCylLo(port, addrFrom)\n {\n var bIn = this.regCylLo;\n this.printMessageIO(port, null, addrFrom, \"CYLLO\", bIn);\n return bIn;\n }\n\n /**\n * outATCCylLo(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F4)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outATCCylLo(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"CYLLO\");\n this.regCylLo = bOut;\n }\n\n /**\n * inATCCylHi(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F5)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inATCCylHi(port, addrFrom)\n {\n var bIn = this.regCylHi;\n this.printMessageIO(port, null, addrFrom, \"CYLHI\", bIn);\n return bIn;\n }\n\n /**\n * outATCCylHi(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F5)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outATCCylHi(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"CYLHI\");\n this.regCylHi = bOut;\n }\n\n /**\n * inATCDrvHd(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F6)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inATCDrvHd(port, addrFrom)\n {\n var bIn = this.regDrvHd;\n this.printMessageIO(port, null, addrFrom, \"DRVHD\", bIn);\n return bIn;\n }\n\n /**\n * outATCDrvHd(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F6)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outATCDrvHd(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"DRVHD\");\n this.regDrvHd = bOut;\n /*\n * The MODEL_5170_REV3 BIOS (see \"POST2_CHK_HF2\" @F000:14FC) probes for a 2nd hard drive when the number\n * of configured hard drives is something other than 2, using INT 0x13/AH=0x10. This in turn calls the\n * BIOS \"TST_RDY\" function, which selects the drive in this register (see DRIVE_MASK), and then immediately\n * expects regStatus to reflect success or failure.\n *\n * We were always returning success, because no ATC command was actually issued, and so the user would\n * always get a spurious CMOS configuration error: \"System Options Not Set-(Run SETUP)\".\n *\n * So now we update regStatus here. I'm not sure which status bits are normally set to indicate failure,\n * but it should be sufficient to set or clear the READY bit according to whether the drive exists or not.\n *\n * TODO: Dig into the ATC documentation some more, and determine what other situations, if any, regStatus\n * needs to be updated.\n *\n * UPDATE: The COMPAQ DeskPro 386 ROM BIOS requires setting STATUS.SEEK_OK in addition to STATUS.READY;\n * a quick retest of the MODEL_5170_REV3 BIOS suggests that it's happy with that change, so it's quite likely\n * that was the appropriate change all along.\n */\n var iDrive = (this.regDrvHd & HDC.ATC.DRVHD.DRIVE_MASK? 1 : 0);\n if (this.aDrives[iDrive]) {\n this.regStatus |= HDC.ATC.STATUS.READY | HDC.ATC.STATUS.SEEK_OK;\n } else {\n this.regStatus &= ~HDC.ATC.STATUS.READY;\n }\n }\n\n /**\n * inATCStatus(port, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F7)\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to read the specified port)\n * @return {number} simulated port value\n */\n inATCStatus(port, addrFrom)\n {\n var bIn = this.regStatus;\n this.printMessageIO(port, null, addrFrom, \"STATUS\", bIn);\n /*\n * Despite what IBM's documentation for the \"Personal Computer AT Fixed Disk and Diskette Drive Adapter\"\n * (August 31, 1984) says (ie, \"A read of the status register clears interrupt request 14\"), we cannot\n * unilaterally clear the IRQ on any read of STATUS. For starters, that would completely break the PC AT\n * ROM BIOS; here's what it does for multi-sector reads:\n *\n * (1) read sector (REP INSW)\n * (2) check STATUS\n * (3) check sector count, exit if done\n * (4) wait for interrupt\n * (5) repeat\n *\n * Since we set the IRR immediately after (1), we cannot immediately clear the IRR at (2), otherwise the\n * interrupt at (4) never happens. So, maybe there are SOME situations where IRR should be cleared on\n * a read, but I don't know what they are.\n *\n * if (this.chipset) this.chipset.clearIRR(ChipSet.IRQ.ATC);\n */\n if (this.regStatus & HDC.ATC.STATUS.READY) this.regStatus &= ~HDC.ATC.STATUS.BUSY;\n return bIn;\n }\n\n /**\n * outATCCommand(port, bOut, addrFrom)\n *\n * @this {HDC}\n * @param {number} port (0x1F7)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outATCCommand(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"COMMAND\");\n this.regCommand = bOut;\n if (this.chipset) this.chipset.clearIRR(ChipSet.IRQ.ATC);\n this.doATC();\n }\n\n /**\n * outATCFDR(port, bOut, addrFrom)\n *\n * This is referred to in IBM's docs as the \"Fixed Disk Register\" (write-only)\n *\n * @this {HDC}\n * @param {number} port (0x3F6)\n * @param {number} bOut\n * @param {number} [addrFrom] (not defined whenever the Debugger tries to write the specified port)\n */\n outATCFDR(port, bOut, addrFrom)\n {\n this.printMessageIO(port, bOut, addrFrom, \"FDR\");\n /*\n * I'm not really sure if I should set HDC.ATC.DIAG.NO_ERROR in regError after *every* write where\n * HDC.ATC.FDR.RESET is clear, or only after it has transitioned from set to clear; since the BIOS only\n * requires the latter, I'm going to be conservative and restrict regError updates to the latter.\n */\n if ((this.regFDR & HDC.ATC.FDR.RESET) && !(bOut & HDC.ATC.FDR.RESET)) this.regError = HDC.ATC.DIAG.NO_ERROR;\n this.regFDR = bOut;\n }\n\n /**\n * doATC()\n *\n * Handles ATC (AT Controller) commands\n *\n * @this {HDC}\n */\n doATC()\n {\n var hdc = this;\n var fInterrupt = false;\n var bCmd = this.regCommand;\n var iDrive = (this.regDrvHd & HDC.ATC.DRVHD.DRIVE_MASK? 1 : 0);\n var nHead = this.regDrvHd & HDC.ATC.DRVHD.HEAD_MASK;\n var nCylinder = this.regCylLo | ((this.regCylHi & HDC.ATC.CYLHI.MASK) << 8);\n var nSector = this.regSecNum;\n var nSectors = this.regSecCnt || 256;\n\n this.iDrive = -1;\n this.drive = null;\n this.regError = HDC.ATC.ERROR.NONE;\n this.regStatus = HDC.ATC.STATUS.READY | HDC.ATC.STATUS.SEEK_OK;\n\n var drive = this.aDrives[iDrive];\n if (!drive) {\n bCmd = -1;\n } else {\n /*\n * Update the Drive object with the new positional information associated with this command.\n */\n drive.wCylinder = nCylinder;\n drive.bHead = nHead;\n drive.bSector = nSector;\n drive.nBytes = nSectors * drive.cbSector;\n bCmd = (bCmd >= HDC.ATC.COMMAND.DIAGNOSE? bCmd : (bCmd & HDC.ATC.COMMAND.MASK));\n /*\n * Since the ATC doesn't use DMA, we must now set some additional Drive state for the benefit of any\n * follow-up I/O instructions. For example, any subsequent inATCByte() and outATCByte() calls need to\n * know which drive to talk to (\"this.drive\"), to issue their own readData() and writeData() calls.\n *\n * The XTC didn't need this, because it used doRead(), doWrite(), doFormat() helper functions,\n * which reset the current drive's \"sector\" and \"errorCode\" properties themselves and then used DMA\n * functions that delivered drive data with direct calls to readData() and writeData().\n */\n drive.sector = null;\n drive.ibSector = 0;\n drive.errorCode = 0;\n this.iDrive = iDrive;\n this.drive = drive;\n }\n\n if (DEBUG && this.messageEnabled(Messages.HDC)) {\n this.printMessage(this.idComponent + \".doATC(\" + Str.toHexByte(bCmd) + \"): \" + HDC.aATCCommands[bCmd], true);\n }\n\n switch (bCmd & HDC.ATC.COMMAND.MASK) {\n\n case HDC.ATC.COMMAND.RESTORE: // 0x10\n /*\n * Physically, this retracts the heads to cylinder 0, but logically, there isn't anything to do.\n */\n fInterrupt = true;\n break;\n\n case HDC.ATC.COMMAND.READ_DATA: // 0x20\n if (DEBUG && this.messageEnabled(Messages.HDC)) {\n this.printMessage(this.idComponent + \".doATCRead(\" + iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + nSectors + \")\", true);\n }\n /*\n * We're using a call to readData() that disables auto-increment, so that once we've got the first\n * byte of the next sector, we can signal an interrupt without also consuming the first byte, allowing\n * inATCByte() to begin with that byte.\n */\n hdc.regStatus = HDC.ATC.STATUS.BUSY;\n this.readData(drive, function onATCReadDataFirst(b, fAsync) {\n if (b >= 0 && hdc.chipset) {\n hdc.setATCIRR();\n /*\n * Bytes from the requested sector(s) will now be delivered via inATCByte().\n *\n * FYI, I'm taking a shotgun approach to these status bits: I need to clear STATUS.BUSY and\n * set STATUS.DATA_REQ, because otherwise COMPAQ DeskPro 386 reads will fail, and I need to set\n * the STATUS.READY and STATUS.SEEK_OK bits, because otherwise MODEL_5170_REV3 reads will fail.\n */\n hdc.regStatus = HDC.ATC.STATUS.READY | HDC.ATC.STATUS.SEEK_OK | HDC.ATC.STATUS.DATA_REQ;\n } else {\n /*\n * TODO: It would be nice to be a bit more specific about the error (if any) that just occurred.\n * Consult drive.errorCode (it uses older XTC error codes, but mapping those codes should be trivial).\n */\n hdc.regStatus = HDC.ATC.STATUS.ERROR;\n hdc.regError = HDC.ATC.ERROR.NO_CHS;\n }\n }, false);\n break;\n\n case HDC.ATC.COMMAND.WRITE_DATA: // 0x30\n if (DEBUG && this.messageEnabled(Messages.HDC)) {\n this.printMessage(this.idComponent + \".doATCWrite(\" + iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + nSectors + \")\", true);\n }\n this.regStatus = HDC.ATC.STATUS.DATA_REQ;\n break;\n\n case HDC.ATC.COMMAND.READ_VERF: // 0x40\n /*\n * Since the READ VERIFY command returns no data, once again, logically, there isn't much we HAVE to\n * to do, but... TODO: Verify that all the disk parameters are valid, and return an error if they're not.\n */\n fInterrupt = true;\n break;\n\n case HDC.ATC.COMMAND.SEEK: // 0x70\n /*\n * Physically, this moves the head(s) to the requested cylinder, but logically, there isn't anything to do;\n * in fact, we didn't even need this command for the MODEL_5170 ROM BIOS (the COMPAQ DeskPro 386 ROM BIOS was\n * another story).\n */\n fInterrupt = true;\n break;\n\n case HDC.ATC.COMMAND.DIAGNOSE: // 0x90\n this.regError = HDC.ATC.DIAG.NO_ERROR;\n fInterrupt = true;\n break;\n\n case HDC.ATC.COMMAND.SETPARMS: // 0x91\n /*\n * The documentation implies that the only parameters this command really affects are the number\n * of heads (from regDrvHd) and sectors/track (from regSecCnt) -- this despite the fact that the BIOS\n * programs all the other registers. For a type 2 drive, that includes:\n *\n * WPREC: 0x4B\n * SECCNT: 0x11 (for 17 sectors per track)\n * CYL: 0x100 (256 -- huh?)\n * SECNUM: 0x0C (12 -- huh?)\n * DRVHD: 0xA3 (max head of 0x03, for 4 total heads)\n *\n * The importance of SECCNT (nSectors) and DRVHD (nHeads) is controlling how multi-sector operations\n * advance to the next sector; see advanceSector().\n */\n\n\n drive.nHeads = nHead + 1;\n drive.nSectors = nSectors;\n fInterrupt = true;\n break;\n\n default:\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".doATC(\" + Str.toHexByte(this.regCommand) + \"): \" + (bCmd < 0? (\"invalid drive (\" + iDrive + \")\") : \"unsupported operation\"));\n if (MAXDEBUG && bCmd >= 0) this.dbg.stopCPU();\n }\n break;\n }\n\n if (fInterrupt) this.setATCIRR();\n }\n\n /**\n * setATCIRR(fWrite)\n *\n * Raise the ATC's IRQ, provided ATC interrupts are enabled.\n *\n * @this {HDC}\n * @param {boolean} [fWrite] is true on completion of a write to the sector buffer\n */\n setATCIRR(fWrite)\n {\n if (this.chipset) {\n if (!(this.regFDR & HDC.ATC.FDR.INT_DISABLE)) {\n /*\n * TODO: Determine what the \"correct\" instruction delay should be here. When the OS/2 1.0 Install Disk\n * begins copying files to the hard drive, at one point it performs the following 125-sector write (use the\n * Debugger's \"m hdc on\" and \"m pic on\" commands to enable HDC and PIC messages, along with \"m data on\"\n * if you also want to see the actual sector data being written):\n *\n * HDC.doATC(0x30): Write\n * HDC.doATCWrite(0,2:0:5,125)\n *\n * As the write progresses, you'll notice that the HDC interrupt after each sector occurs at decreasingly\n * lower points in the stack, until we eventually start overwriting non-stack data:\n *\n * getIRRVector(): IRQ 14 interrupting @0090:52A6 stack=0050:1906\n * getIRRVector(): IRQ 14 interrupting @0318:196B stack=0050:18D6\n * getIRRVector(): IRQ 14 interrupting @0318:196B stack=0050:18A6\n * ...\n * getIRRVector(): IRQ 14 interrupting @0318:196B stack=0050:1156\n *\n * At roughly this point, very bad things start happening. I decided to try an arbitrarily large delay\n * on the setIRR() call here (120), and the problem vanished, so it seems likely that the OS/2 disk driver\n * has a low tolerance for fast controller interrupts during multi-sector operations.\n */\n this.chipset.setIRR(ChipSet.IRQ.ATC, 120);\n if (DEBUG) this.printMessage(this.idComponent + \".setATCIRR(): enabled\", Messages.PIC | Messages.HDC);\n } else {\n if (DEBUG) this.printMessage(this.idComponent + \".setATCIRR(): disabled\", Messages.PIC | Messages.HDC);\n }\n }\n }\n\n /**\n * doXTC()\n *\n * Handles XTC (XT Controller) commands\n *\n * @this {HDC}\n */\n doXTC()\n {\n var hdc = this;\n this.regDataIndex = 0;\n\n var bCmd = this.popCmd();\n var bCmdOrig = bCmd;\n var b1 = this.popCmd();\n var bDrive = b1 & 0x20;\n var iDrive = (bDrive >> 5);\n\n var bHead = b1 & 0x1f;\n var b2 = this.popCmd();\n var b3 = this.popCmd();\n var wCylinder = ((b2 << 2) & 0x300) | b3;\n var bSector = b2 & 0x3f;\n var bCount = this.popCmd(); // block count or interleave count, depending on the command\n var bControl = this.popCmd();\n var bParm, bDataStatus;\n\n var drive = this.aDrives[iDrive];\n if (drive) {\n drive.wCylinder = wCylinder;\n drive.bHead = bHead;\n drive.bSector = bSector;\n drive.nBytes = bCount * drive.cbSector;\n }\n\n /*\n * I tried to save normal command processing from having to deal with invalid drives,\n * but the HDC BIOS initializes both drive 0 AND drive 1 on a HDC.XTC.DATA.CMD.INIT_DRIVE command,\n * and apparently that particular command has no problem with non-existent drives.\n *\n * So I've separated the commands into two groups: drive-ambivalent commands should be\n * processed in the first group, and all the rest should be processed in the second group.\n */\n switch (bCmd) {\n\n case HDC.XTC.DATA.CMD.REQUEST_SENSE: // 0x03\n this.beginResult(drive? drive.errorCode : HDC.XTC.DATA.ERR.NOT_READY);\n this.pushResult(b1);\n this.pushResult(b2);\n this.pushResult(b3);\n /*\n * Although not terribly clear from IBM's \"Fixed Disk Adapter\" documentation, a data \"status byte\"\n * also follows the 4 \"sense bytes\". Interestingly, The HDC BIOS checks that data status byte for\n * XTC.DATA.STATUS.ERROR, but I have to wonder if it would have ever been set for this command....\n *\n * The whole point of the HDC.XTC.DATA.CMD.REQUEST_SENSE command is to obtain details about a\n * previous error, so if HDC.XTC.DATA.CMD.REQUEST_SENSE itself reports an error, what would that mean?\n */\n this.pushResult(HDC.XTC.DATA.STATUS.OK | bDrive);\n bCmd = -1; // mark the command as complete\n break;\n\n case HDC.XTC.DATA.CMD.INIT_DRIVE: // 0x0C\n /*\n * Pop off all the extra \"Initialize Drive Characteristics\" bytes and store them, for the benefit of\n * other functions, like verifyDrive().\n */\n var i = 0;\n while ((bParm = this.popCmd()) >= 0) {\n if (drive && i < drive.abDriveParms.length) {\n drive.abDriveParms[i++] = bParm;\n }\n }\n if (drive) this.verifyDrive(drive);\n bDataStatus = HDC.XTC.DATA.STATUS.OK;\n if (!drive && this.iDriveAllowFail == iDrive) {\n this.iDriveAllowFail = -1;\n if (DEBUG) this.printMessage(this.idComponent + \".doXTC(): fake failure triggered\");\n bDataStatus = HDC.XTC.DATA.STATUS.ERROR;\n }\n this.beginResult(bDataStatus | bDrive);\n bCmd = -1; // mark the command as complete\n break;\n\n case HDC.XTC.DATA.CMD.RAM_DIAGNOSTIC: // 0xE0\n case HDC.XTC.DATA.CMD.CTL_DIAGNOSTIC: // 0xE4\n this.beginResult(HDC.XTC.DATA.STATUS.OK | bDrive);\n bCmd = -1; // mark the command as complete\n break;\n\n default:\n break;\n }\n\n if (bCmd >= 0) {\n if (drive === undefined) {\n bCmd = -1;\n } else {\n /*\n * In preparation for this command, zero out the drive's errorCode and senseCode.\n * Commands that require a disk address should update senseCode with HDC.XTC.DATA.SENSE_ADDR_VALID.\n * And of course, any command that encounters an error should set the appropriate error code.\n */\n drive.errorCode = HDC.XTC.DATA.ERR.NONE;\n drive.senseCode = 0;\n }\n switch (bCmd) {\n case HDC.XTC.DATA.CMD.TEST_READY: // 0x00\n this.beginResult(HDC.XTC.DATA.STATUS.OK | bDrive);\n break;\n\n case HDC.XTC.DATA.CMD.RECALIBRATE: // 0x01\n drive.bControl = bControl;\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".doXTC(): drive \" + iDrive + \" control byte: \" + Str.toHexByte(bControl));\n }\n this.beginResult(HDC.XTC.DATA.STATUS.OK | bDrive);\n break;\n\n case HDC.XTC.DATA.CMD.READ_VERF: // 0x05\n /*\n * This is a non-DMA operation, so we simply pretend everything is OK for now. TODO: Revisit.\n */\n this.beginResult(HDC.XTC.DATA.STATUS.OK | bDrive);\n break;\n\n case HDC.XTC.DATA.CMD.READ_DATA: // 0x08\n this.doRead(drive, function onXTCReadDataCommand(bStatus) {\n hdc.beginResult(bStatus | bDrive);\n });\n break;\n\n case HDC.XTC.DATA.CMD.WRITE_DATA: // 0x0A\n /*\n * QUESTION: The IBM TechRef (p.1-188) implies that bCount is used as part of HDC.XTC.DATA.CMD.WRITE_DATA command,\n * but it is omitted from the HDC.XTC.DATA.CMD.READ_DATA command. Is that correct? Note that, as far as the length\n * of the transfer is concerned, we rely exclusively on the DMA controller being programmed with the appropriate byte count.\n */\n this.doWrite(drive, function onXTCWriteDataCommand(bStatus) {\n hdc.beginResult(bStatus | bDrive);\n });\n break;\n\n case HDC.XTC.DATA.CMD.WRITE_BUFFER: // 0x0F\n this.doWriteBuffer(drive, function onXTCWriteBufferCommand(bStatus) {\n hdc.beginResult(bStatus | bDrive);\n });\n break;\n\n default:\n this.beginResult(HDC.XTC.DATA.STATUS.ERROR | bDrive);\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".doXTC(\" + Str.toHexByte(bCmdOrig) + \"): \" + (bCmd < 0? (\"invalid drive (\" + iDrive + \")\") : \"unsupported operation\"));\n if (MAXDEBUG && bCmd >= 0) this.dbg.stopCPU();\n }\n break;\n }\n }\n }\n\n /**\n * popCmd()\n *\n * @this {HDC}\n * @return {number}\n */\n popCmd()\n {\n var bCmd = -1;\n var bCmdIndex = this.regDataIndex;\n if (bCmdIndex < this.regDataTotal) {\n bCmd = this.regDataArray[this.regDataIndex++];\n if (DEBUG && this.messageEnabled((bCmdIndex > 0? Messages.PORT : 0) | Messages.HDC)) {\n this.printMessage(this.idComponent + \".popCmd(\" + bCmdIndex + \"): \" + Str.toHexByte(bCmd) + (!bCmdIndex && HDC.aXTCCommands[bCmd]? (\" (\" + HDC.aXTCCommands[bCmd] + \")\") : \"\"), true);\n }\n }\n return bCmd;\n }\n\n /**\n * beginResult(bResult)\n *\n * @this {HDC}\n * @param {number} [bResult]\n */\n beginResult(bResult)\n {\n this.regDataIndex = this.regDataTotal = 0;\n if (bResult !== undefined) this.pushResult(bResult);\n /*\n * After the Execution phase (eg, DMA Terminal Count has occurred, or the EOT sector has been read/written),\n * an interrupt is supposed to occur, signaling the beginning of the Result Phase. Once the data \"status byte\"\n * has been read from XTC.DATA, the interrupt is cleared (see inXTCData).\n */\n if (this.chipset) this.chipset.setIRR(ChipSet.IRQ.XTC);\n this.regStatus |= HDC.XTC.STATUS.INTERRUPT;\n }\n\n /**\n * pushResult(bResult)\n *\n * @this {HDC}\n * @param {number} bResult\n */\n pushResult(bResult)\n {\n if (DEBUG && this.messageEnabled((this.regDataTotal > 0? Messages.PORT : 0) | Messages.HDC)) {\n this.printMessage(this.idComponent + \".pushResult(\" + this.regDataTotal + \"): \" + Str.toHexByte(bResult), true);\n }\n this.regDataArray[this.regDataTotal++] = bResult;\n }\n\n /**\n * doDMARead(drive, b, done)\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {number} b\n * @param {function(number,boolean)} done\n */\n doDMARead(drive, b, done)\n {\n if (b === undefined || b < 0) {\n this.readData(drive, done);\n return;\n }\n /*\n * The DMA controller should be ASKING for data, not GIVING us data; this suggests an internal DMA miscommunication\n */\n if (DEBUG) this.printMessage(this.idComponent + \".doDMARead(): invalid DMA acknowledgement\");\n done(-1, false);\n }\n\n /**\n * doDMAWrite(drive, b)\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {number} b\n * @return {number}\n */\n doDMAWrite(drive, b)\n {\n if (b !== undefined && b >= 0)\n return this.writeData(drive, b);\n /*\n * The DMA controller should be GIVING us data, not ASKING for data; this suggests an internal DMA miscommunication\n */\n if (DEBUG) this.printMessage(this.idComponent + \".doDMAWrite(): invalid DMA acknowledgement\");\n return -1;\n }\n\n /**\n * doDMAWriteBuffer(drive, b)\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {number} b\n * @return {number}\n */\n doDMAWriteBuffer(drive, b)\n {\n if (b !== undefined && b >= 0)\n return this.writeBuffer(drive, b);\n /*\n * The DMA controller should be GIVING us data, not ASKING for data; this suggests an internal DMA miscommunication\n */\n if (DEBUG) this.printMessage(this.idComponent + \".doDMAWriteBuffer(): invalid DMA acknowledgement\");\n return -1;\n }\n\n /**\n * doDMAWriteFormat(drive, b)\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {number} b\n * @returns {number}\n */\n doDMAWriteFormat(drive, b)\n {\n if (b !== undefined && b >= 0)\n return this.writeFormat(drive, b);\n /*\n * The DMA controller should be GIVING us data, not ASKING for data; this suggests an internal DMA miscommunication\n */\n if (DEBUG) this.printMessage(this.idComponent + \".doDMAWriteFormat(): invalid DMA acknowledgement\");\n return -1;\n }\n\n /**\n * doRead(drive, done)\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {function(number)} done (dataStatus is XTC.DATA.STATUS.OK or XTC.DATA.STATUS.ERROR; if error, then drive.errorCode should be set as well)\n */\n doRead(drive, done)\n {\n drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".doRead(\" + drive.iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + ((drive.nBytes / drive.cbSector)|0) + \")\");\n }\n\n if (drive.disk) {\n drive.sector = null;\n if (this.chipset) {\n /*\n * We need to reverse the original logic, and default to success unless/until an actual error occurs;\n * otherwise doDMARead()/readData() will bail on us. The original approach used to work because requestDMA()\n * would immediately call us back with fComplete set to true EVEN if the DMA channel was not yet unmasked;\n * now the callback is deferred until the DMA channel has been unmasked and the DMA request has finished.\n */\n drive.errorCode = HDC.XTC.DATA.ERR.NONE;\n this.chipset.connectDMA(ChipSet.DMA_HDC, this, 'dmaRead', drive);\n this.chipset.requestDMA(ChipSet.DMA_HDC, function onDMAReadRequest(fComplete) {\n if (!fComplete) {\n /*\n * If an incomplete request wasn't triggered by an explicit error, then let's make explicit\n * (ie, revert to the default failure code that we originally set above).\n */\n if (drive.errorCode == HDC.XTC.DATA.ERR.NONE) {\n drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;\n }\n }\n done(drive.errorCode? HDC.XTC.DATA.STATUS.ERROR : HDC.XTC.DATA.STATUS.OK);\n });\n return;\n }\n }\n done(drive.errorCode? HDC.XTC.DATA.STATUS.ERROR : HDC.XTC.DATA.STATUS.OK);\n }\n\n /**\n * doWrite(drive, done)\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {function(number)} done (dataStatus is XTC.DATA.STATUS.OK or XTC.DATA.STATUS.ERROR; if error, then drive.errorCode should be set as well)\n */\n doWrite(drive, done)\n {\n drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".doWrite(\" + drive.iDrive + ',' + drive.wCylinder + ':' + drive.bHead + ':' + drive.bSector + ',' + ((drive.nBytes / drive.cbSector)|0) + \")\");\n }\n\n if (drive.disk) {\n drive.sector = null;\n if (this.chipset) {\n /*\n * We need to reverse the original logic, and default to success unless/until an actual error occurs;\n * otherwise doDMAWrite()/writeData() will bail on us. The original approach would work because requestDMA()\n * would immediately call us back with fComplete set to true EVEN if the DMA channel was not yet unmasked;\n * now the callback is deferred until the DMA channel has been unmasked and the DMA request has finished.\n */\n drive.errorCode = HDC.XTC.DATA.ERR.NONE;\n this.chipset.connectDMA(ChipSet.DMA_HDC, this, 'dmaWrite', drive);\n this.chipset.requestDMA(ChipSet.DMA_HDC, function onDMAWriteRequest(fComplete) {\n if (!fComplete) {\n /*\n * If an incomplete request wasn't triggered by an explicit error, then let's make explicit\n * (ie, revert to the default failure code that we originally set above).\n */\n if (drive.errorCode == HDC.XTC.DATA.ERR.NONE) {\n drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;\n }\n /*\n * Mask any error that's the result of an attempt to write beyond the end of the track (which is\n * something the MS-DOS 4.0M's FORMAT utility seems to like to do).\n */\n if (drive.errorCode == HDC.XTC.DATA.ERR.NO_SECTOR) {\n drive.errorCode = HDC.XTC.DATA.ERR.NONE;\n }\n }\n done(drive.errorCode? HDC.XTC.DATA.STATUS.ERROR : HDC.XTC.DATA.STATUS.OK);\n });\n return;\n }\n }\n done(drive.errorCode? HDC.XTC.DATA.STATUS.ERROR : HDC.XTC.DATA.STATUS.OK);\n }\n\n /**\n * doWriteBuffer(drive, done)\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {function(number)} done (dataStatus is XTC.DATA.STATUS.OK or XTC.DATA.STATUS.ERROR; if error, then drive.errorCode should be set as well)\n */\n doWriteBuffer(drive, done)\n {\n drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;\n\n if (DEBUG) this.printMessage(this.idComponent + \".doWriteBuffer()\");\n\n if (!drive.abSector || drive.abSector.length != drive.nBytes) {\n drive.abSector = new Array(drive.nBytes);\n }\n drive.ibSector = 0;\n if (this.chipset) {\n /*\n * We need to reverse the original logic, and default to success unless/until an actual error occurs;\n * otherwise doDMAWriteBuffer() will bail on us. The original approach would work because requestDMA()\n * would immediately call us back with fComplete set to true EVEN if the DMA channel was not yet unmasked;\n * now the callback is deferred until the DMA channel has been unmasked and the DMA request has finished.\n */\n drive.errorCode = HDC.XTC.DATA.ERR.NONE;\n this.chipset.connectDMA(ChipSet.DMA_HDC, this, 'dmaWriteBuffer', drive);\n this.chipset.requestDMA(ChipSet.DMA_HDC, function onDMAWriteBufferRequest(fComplete) {\n if (!fComplete) {\n /*\n * If an incomplete request wasn't triggered by an explicit error, then let's make explicit\n * (ie, revert to the default failure code that we originally set above).\n */\n if (drive.errorCode == HDC.XTC.DATA.ERR.NONE) {\n drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;\n }\n }\n done(drive.errorCode? HDC.XTC.DATA.STATUS.ERROR : HDC.XTC.DATA.STATUS.OK);\n });\n return;\n }\n done(drive.errorCode? HDC.XTC.DATA.STATUS.ERROR : HDC.XTC.DATA.STATUS.OK);\n }\n\n /**\n * readData(drive, done)\n *\n * The following drive variable properties must have been setup prior to our first call:\n *\n * drive.wCylinder\n * drive.bHead\n * drive.bSector\n * drive.sector (initialized to null)\n *\n * On the first readData() request, since drive.sector will be null, we ask the Disk object to look\n * up the first sector of the request. We then ask the Disk for bytes from that sector until the sector\n * is exhausted, and then we look up the next sector and continue the process.\n *\n * NOTE: Since the HDC isn't aware of the extent of the transfer, all readData() can do is return bytes\n * until the current track (or, in the case of a multi-track request, the current cylinder) has been exhausted.\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {function(number,boolean,Object,number)} [done] (number is next available byte from drive, or -1 if no more bytes available)\n * @param {boolean} [fAutoInc] (default is true to auto-increment)\n * @return {number} the requested byte, or -1 if unavailable\n */\n readData(drive, done, fAutoInc)\n {\n var b = -1;\n var obj = null, off = 0; // these variables are purely for BACKTRACK purposes\n\n if (drive.errorCode) {\n if (done) done(b, false, obj, off);\n return b;\n }\n\n var inc = (fAutoInc !== false? 1 : 0);\n\n if (drive.sector) {\n off = drive.ibSector;\n b = drive.disk.read(drive.sector, drive.ibSector);\n drive.ibSector += inc;\n if (b >= 0) {\n obj = drive.sector;\n if (done) done(b, false, obj, off);\n return b;\n }\n }\n\n /*\n * Locate the next sector, and then try reading again.\n *\n * Important difference between the FDC and the XTC: the XTC uses 0-based sector numbers,\n * hence the bSectorBias below. I could change how sector numbers are stored in the image,\n * but it seems preferable to keep the image format consistent and controller-independent.\n */\n if (done) {\n var hdc = this;\n if (drive.disk) {\n drive.disk.seek(drive.wCylinder, drive.bHead, drive.bSector + drive.bSectorBias, false, function onReadDataSeek(sector, fAsync) {\n if ((drive.sector = sector)) {\n obj = sector;\n off = drive.ibSector = 0;\n /*\n * We \"pre-advance\" bSector et al now, instead of waiting to advance it right before the seek().\n * This allows the initial call to readData() to perform a seek without triggering an unwanted advance.\n */\n hdc.advanceSector(drive);\n b = drive.disk.read(drive.sector, drive.ibSector);\n drive.ibSector += inc;\n } else {\n drive.errorCode = HDC.XTC.DATA.ERR.NO_SECTOR;\n }\n done(b, fAsync, obj, off);\n });\n return b;\n }\n drive.errorCode = HDC.XTC.DATA.ERR.NO_SECTOR;\n done(b, false, obj, off);\n }\n return b;\n }\n\n /**\n * writeData(drive, b)\n *\n * The following drive variable properties must have been setup prior to our first call:\n *\n * drive.wCylinder\n * drive.bHead\n * drive.bSector\n * drive.sector (initialized to null)\n *\n * On the first writeData() request, since drive.sector will be null, we ask the Disk object to look\n * up the first sector of the request. We then send the Disk bytes for that sector until the sector\n * is full, and then we look up the next sector and continue the process.\n *\n * NOTE: Since the HDC isn't aware of the extent of the transfer, all writeData() can do is accept bytes\n * until the current track (or, in the case of a multi-track request, the current cylinder) has been exhausted.\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {number} b containing next byte to write\n * @return {number} (b unchanged; return -1 if command should be terminated)\n */\n writeData(drive, b)\n {\n if (drive.errorCode) return -1;\n do {\n if (drive.sector) {\n if (drive.disk.write(drive.sector, drive.ibSector++, b))\n break;\n }\n /*\n * Locate the next sector, and then try writing again.\n *\n * Important difference between the FDC and the XTC: the XTC uses 0-based sector numbers,\n * hence the bSectorBias below. I could change how sector numbers are stored in the image,\n * but it seems preferable to keep the image format consistent and controller-independent.\n */\n if (drive.disk) {\n drive.disk.seek(drive.wCylinder, drive.bHead, drive.bSector + drive.bSectorBias, true, function onWriteDataSeek(sector, fAsync) {\n drive.sector = sector;\n });\n }\n if (!drive.sector) {\n drive.errorCode = HDC.XTC.DATA.ERR.NO_SECTOR;\n b = -1;\n break;\n }\n drive.ibSector = 0;\n /*\n * We \"pre-advance\" bSector et al now, instead of waiting to advance it right before the seek().\n * This allows the initial call to writeData() to perform a seek without triggering an unwanted advance.\n */\n this.advanceSector(drive);\n } while (true);\n return b;\n }\n\n /**\n * advanceSector(drive)\n *\n * This increments the sector number; when the sector number reaches drive.nSectors on the current track, we\n * increment drive.bHead and reset drive.bSector, and when drive.bHead reaches drive.nHeads, we reset drive.bHead\n * and increment drive.wCylinder.\n *\n * One wrinkle is that the ATC uses 1-based sector numbers (bSectorBias is 0), whereas the XTC uses 0-based sector\n * numbers (bSectorBias is 1). Thus, the correct \"reset\" value for bSector is (1 - bSectorBias), and the correct\n * limit for bSector is (nSectors + bSectorStart).\n *\n * @this {HDC}\n * @param {Object} drive\n */\n advanceSector(drive)\n {\n\n drive.bSector++;\n var bSectorStart = (1 - drive.bSectorBias);\n if (drive.bSector >= drive.nSectors + bSectorStart) {\n drive.bSector = bSectorStart;\n drive.bHead++;\n if (drive.bHead >= drive.nHeads) {\n drive.bHead = 0;\n drive.wCylinder++;\n }\n }\n }\n\n /**\n * writeBuffer(drive, b)\n *\n * NOTE: Since the HDC isn't aware of the extent of the transfer, all writeBuffer() can do is accept bytes\n * until the buffer is full.\n *\n * TODO: Support for HDC.XTC.DATA.CMD.READ_BUFFER is missing, and support for HDC.XTC.DATA.CMD.WRITE_BUFFER may not be complete;\n * tests required.\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {number} b containing next byte to write\n * @return {number} (b unchanged; return -1 if command should be terminated)\n */\n writeBuffer(drive, b)\n {\n if (drive.ibSector < drive.abSector.length) {\n drive.abSector[drive.ibSector++] = b;\n } else {\n /*\n * TODO: Determine the proper error code to return here.\n */\n drive.errorCode = HDC.XTC.DATA.ERR.NO_SECTOR;\n b = -1;\n }\n return b;\n }\n\n /**\n * writeFormat(drive, b)\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {number} b containing a format command byte\n * @return {number} (b if successful, -1 if command should be terminated)\n */\n writeFormat(drive, b)\n {\n if (drive.errorCode) return -1;\n drive.abFormat[drive.cbFormat++] = b;\n if (drive.cbFormat == drive.abFormat.length) {\n drive.wCylinder = drive.abFormat[0]; // C\n drive.bHead = drive.abFormat[1]; // H\n drive.bSector = drive.abFormat[2]; // R\n drive.nBytes = 128 << drive.abFormat[3];// N (0 => 128, 1 => 256, 2 => 512, 3 => 1024)\n drive.cbFormat = 0;\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(this.idComponent + \".writeFormat(\" + drive.wCylinder + \":\" + drive.bHead + \":\" + drive.bSector + \":\" + drive.nBytes + \")\");\n }\n\n for (var i = 0; i < drive.nBytes; i++) {\n if (this.writeData(drive, drive.bFiller) < 0) {\n return -1;\n }\n }\n drive.cSectorsFormatted++;\n }\n if (drive.cSectorsFormatted >= drive.bSectorEnd) b = -1;\n return b;\n }\n\n /**\n * intBIOSDisk(addr)\n *\n * NOTE: This function differentiates HDC requests from FDC requests, based on whether the INT 0x13 drive number\n * in DL is >= 0x80.\n *\n * HACK: The HDC BIOS code for both INT 0x13/AH=0x00 and INT 0x13/AH=0x09 calls \"INIT_DRV\" @C800:0427, which is\n * hard-coded to issue the HDC.XTC.DATA.CMD.INIT_DRIVE command for BOTH drives 0 and 1 (aka drive numbers 0x80 and\n * 0x81), regardless of the drive number specified in DL; this means that the HDC.XTC.DATA.CMD.INIT_DRIVE command\n * must always succeed for drive 1 if it also succeeds for drive 0 -- even if there is no drive 1. Bizarre, but OK,\n * whatever.\n *\n * So assuming we a have drive 0, when the power-on diagnostics in \"DISK_SETUP\" @C800:0003 call INT 0x13/AH=0x09\n * (@C800:00DB) for drive 0, it must succeed. No problem. But when \"DISK_SETUP\" starts probing for additional drives,\n * it first issues INT 0x13/AH=0x00, followed by INT 0x13/AH=0x11, and finally INT 0x13/AH=0x09. If the first\n * (AH=0x00) or third (AH=0x09) INT 0x13 fails, it quickly moves on (ie, it jumps to \"POD_DONE\"). But as we just\n * discussed, both those operations call \"INIT_DRV\", which can't return an error. This means the only function that\n * can return an error in this context is the recalibrate function (AH=0x11). That sucks, because the way the HDC\n * BIOS is written, it will loop for anywhere from 1.5 seconds to 25 seconds (depending on whether the controller\n * is part of the \"System Unit\" or not; see port 0x213), attempting to recalibrate drive 1 until it finally times out.\n *\n * Normally, you'll only experience the 1.5 second delay, but even so, it's a ridiculous waste of time and a lot of\n * useless INT 0x13 calls. So I monitor INT 0x13/AH=0x00 for DL >= 0x80 and set a special HDC.XTC.DATA.CMD.INIT_DRIVE\n * override flag (iDriveAllowFail) that will allow that command to fail, and in theory, make the the HDC BIOS\n * \"DISK_SETUP\" code much more efficient.\n *\n * @this {HDC}\n * @param {number} addr\n * @return {boolean} true to proceed with the INT 0x13 software interrupt, false to skip\n */\n intBIOSDisk(addr)\n {\n var AH = this.cpu.regEAX >> 8;\n var DL = this.cpu.regEDX & 0xff;\n if (!AH && DL > 0x80) this.iDriveAllowFail = DL - 0x80;\n return true;\n }\n\n /**\n * intBIOSDiskette(addr)\n *\n * When the HDC BIOS overwrites the ROM BIOS INT 0x13 address, it saves the original INT 0x13 address\n * in the INT 0x40 vector. This function intercepts calls to that vector to work around a minor nuisance.\n *\n * The HDC BIOS's plan was simple, albeit slightly flawed: assign fixed disks drive numbers >= 0x80,\n * and whenever someone calls INT 0x13 with a drive number < 0x80, invoke the original INT 0x13 diskette\n * code via INT 0x40 and return via RET 2.\n *\n * Unfortunately, not all original INT 0x13 functions required a drive number in DL (eg, the \"reset\"\n * function, where AH=0). And the HDC BIOS knew this, which is why, in the case of the \"reset\" function,\n * the HDC BIOS performs BOTH an INT 0x40 diskette reset AND an HDC reset -- it can't be sure which\n * controller the caller really wants to reset.\n *\n * An unfortunate side-effect of this behavior: when the HDC BIOS is initialized for the first time, it may\n * issue several resets internally, depending on whether there are 0, 1 or 2 hard drives installed, and each\n * of those resets also triggers completely useless diskette resets, each wasting up to two seconds waiting\n * for the FDC to interrupt. The FDC tries to interrupt, but it can't, because at this early stage of\n * ROM BIOS initialization, IRQ.FDC hasn't been unmasked yet.\n *\n * My work-around: have the HDC component hook INT 0x40, and every time an INT 0x40 is issued with AH=0 and\n * IRQ.FDC masked, bypass the INT 0x40 interrupt. This is as close as PCx86 has come to patching any BIOS code\n * (something I've refused to do), and even here, I'm not doing it out of necessity, just annoyance.\n *\n * @this {HDC}\n * @param {number} addr\n * @return {boolean} true to proceed with the INT 0x40 software interrupt, false to skip\n */\n intBIOSDiskette(addr)\n {\n var AH = this.cpu.regEAX >> 8;\n if ((!AH && this.chipset && this.chipset.checkIMR(ChipSet.IRQ.FDC))) {\n if (DEBUG) this.printMessage(this.idComponent + \".intBIOSDiskette(): skipping useless INT 0x40 diskette reset\");\n return false;\n }\n return true;\n }\n\n /**\n * unloadDrive(iDrive)\n *\n * NOTE: At the moment, we support only auto-mounts; there is no user interface for selecting hard drive\n * images, let alone unloading them, so there is currently no need for the following function.\n *\n * @this {HDC}\n * @param {number} iDrive\n *\n unloadDrive(iDrive)\n {\n this.aDrives[iDrive].disk = null;\n //\n // WARNING: This conversion of drive number to drive letter, starting with \"C:\" (0x43), is very simplistic\n // and is not guaranteed to match the drive mapping that DOS ultimately uses.\n //\n this.notice(\"Drive \" + String.fromCharCode(0x43 + iDrive) + \" unloaded\");\n }\n */\n\n /**\n * doFormat(drive, done)\n *\n * The drive variable is initialized by doXTC() to the following extent:\n *\n * drive.bHead (ignored)\n * drive.nBytes (bytes/sector)\n * drive.bSectorEnd (sectors/track)\n * drive.bFiller (fill byte)\n *\n * and we expect the DMA controller to provide C, H, R and N (ie, 4 bytes) for each sector to be formatted.\n *\n * NOTE: This function is not currently used.\n *\n * @this {HDC}\n * @param {Object} drive\n * @param {function(number)} done (dataStatus is XTC.DATA.STATUS.OK or XTC.DATA.STATUS.ERROR; if error, then drive.errorCode should be set as well)\n *\n doFormat(drive, done)\n {\n drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;\n\n if (drive.disk) {\n drive.sector = null;\n if (this.chipset) {\n drive.cbFormat = 0;\n drive.abFormat = new Array(4);\n drive.bFormatting = true;\n drive.cSectorsFormatted = 0;\n //\n // We need to reverse the original logic, and default to success unless/until an actual error occurs;\n // otherwise doDMAWriteFormat() will bail on us. The original approach would work because requestDMA()\n // would immediately call us back with fComplete set to true EVEN if the DMA channel was not yet unmasked;\n // now the callback is deferred until the DMA channel has been unmasked and the DMA request has finished.\n //\n drive.errorCode = HDC.XTC.DATA.ERR.NONE;\n this.chipset.connectDMA(ChipSet.DMA_HDC, this, 'dmaWriteFormat', drive);\n this.chipset.requestDMA(ChipSet.DMA_HDC, function onDMAFormat(fComplete) {\n if (!fComplete) {\n //\n // If an incomplete request wasn't triggered by an explicit error, then let's make explicit\n // (ie, revert to the default failure code that we originally set above).\n //\n if (drive.errorCode == HDC.XTC.DATA.ERR.NONE) {\n drive.errorCode = HDC.XTC.DATA.ERR.NOT_READY;\n }\n }\n drive.bFormatting = false;\n done(drive.errorCode? HDC.XTC.DATA.STATUS.ERROR : HDC.XTC.DATA.STATUS.OK);\n });\n return;\n }\n }\n done(drive.errorCode? HDC.XTC.DATA.STATUS.ERROR : HDC.XTC.DATA.STATUS.OK);\n }\n */\n\n /**\n * HDC.init()\n *\n * This function operates on every HTML element of class \"hdc\", extracting the\n * JSON-encoded parameters for the HDC constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a HDC component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeHDC = Component.getElementsByClass(document, PCX86.APPCLASS, \"hdc\");\n for (var iHDC = 0; iHDC < aeHDC.length; iHDC++) {\n var eHDC = aeHDC[iHDC];\n var parmsHDC = Component.getComponentParms(eHDC);\n var hdc = new HDC(parmsHDC);\n Component.bindComponentControls(hdc, eHDC, PCX86.APPCLASS);\n }\n }\n}\n\n/*\n * HDC defaults, in case drive parameters weren't specified\n */\nHDC.DEFAULT_DRIVE_NAME = \"Hard Drive\";\n\n/*\n * Starting with the IBM PC XT, the ROM defined a \"Fixed Disk Parameter Table\" (FD_TBL) that contained 16 bytes\n * at the following offsets for each of 4 drive types (see IBM 5160 Tech Ref, April 1983, p. A-94):\n * \n * 0: maximum number of cylinders (word)\n * 2: maximum number of heads\n * 3: starting reduced write current cylinder (word)\n * 5: starting write precompensation cylinder (word)\n * 7: maximum ECC data burst length\n * 8: control byte (drive step option)\n * bit 7: disable disk-access retries\n * bit 6: disable ECC retries\n * bits 5-3: zero\n * bits 2-0: drive option\n * 9: standard time-out value\n * A: time-out value for format drive\n * B: time-out value for check drive\n * C: reserved\n * D: reserved\n * E: reserved\n * F: reserved\n * \n * Starting with the IBM PC AT, the ROM defined a \"Fixed Disk Parameter Table\" (FD_TBL) that contained 16 bytes\n * at the following offsets for each of 47 drive types (see IBM 5170 Tech Ref, March 1986, p. 5-185):\n * \n * 0: maximum number of cylinders (word)\n * 2: maximum number of heads\n * 3: not used\n * 5: starting write precompensation cylinder (word)\n * 7: not used\n * 8: control byte (drive step option)\n * bit 7: disable retries -OR-\n * bit 6: disable retries\n * bit 3: more than 8 heads\n * 9: not used\n * A: not used\n * B: not used\n * C: landing zone (word)\n * E: number of sectors/track (NOTE: all PC AT drive types specified 17 sectors/track)\n * F: reserved\n * \n * NOTE: While drive type 0 was a valid type in the PC XT, it was NOT a valid drive type in the PC AT; zero was used\n * to indicate that no hard drive was installed.\n * \n * Of the 47 PC AT drive types, the first 14 (1-E) could be selected by 4 bits in CMOS byte 0x12. Drive type 15 was not\n * a valid type but rather an indicator that CMOS byte 0x19 (or 0x1A) contained the actual drive type, which technically\n * could contain any value from 0-255, but was documented as being limited to values 16-255. And in fact, the ROM only\n * contained entries for drive types 1-47, and of those, only drive types 1-14 and 16-23 were valid; the rest (15 and 24-47)\n * were marked \"RESERVED\" and contained zeros.\n * \n * If a system needed a drive type that wasn't defined by the ROM, it could be placed in RAM, as the ROM explained:\n * \n * To dynamically define a set of parameters, build a table for up to 15 types and place\n * the corresponding vector into interrupt 0x41 for drive 0 and interrupt 0x46 for drive 1.\n * \n * To make PCjs easier to configure, we have three drive tables (for XT, AT, and COMPAQ machines), each of which\n * contains DriveArrays for the various DriveTypes supported by each machine. Each DriveArray contains the following\n * subset of \"Fixed Disk Parameter Table\" information:\n *\n * [0]: total cylinders\n * [1]: total heads\n * [2]: total sectors/tracks (optional; default is 17)\n * [3]: total bytes/sector (optional; default is 512)\n *\n * verifyDrive() attempts to confirm that these values agree with the programmed drive characteristics.\n *\n * NOTE: For the record, PCjs considers 1Kb to be 1 kilobyte (1,024 bytes, not 1,000 bytes) and 1Mb to be 1 megabyte\n * (1024*1024 or 1,048,576 bytes, not 1,000,000 bytes).\n *\n * Apparently, in 1998, it was decided that a kilobyte should be 1,000 bytes and a megabyte should be 1,000,000 bytes,\n * and that if you really meant 2^10 (1,024) or 2^20 (1,048,576), you should use \"kibibyte\" (KiB) or \"mebibyte\" (MiB)\n * instead. But since PCjs simulates machines that pre-date 1998, I have chosen to retain the more \"traditional\"\n * understanding of Kb and Mb; I never use KiB or MiB. \n */\n\n/*\n * Drive type tables differed across IBM controller models (XTC drive types don't match ATC drive types) and across OEMs\n * (eg, COMPAQ drive types only match a few IBM drive types), so you must use iDriveTable to index the correct table type\n * inside both aDriveTables and aDriveTypes.\n */\nHDC.aDriveTables = [\"XTC\", \"ATC\", \"COMPAQ\"];\n\nHDC.aDriveTypes = [\n /*\n * aDriveTypes[0] is for the IBM PC XT (XTC) controller.\n */\n {\n 0: [306, 2],\n 1: [375, 8],\n 2: [306, 6],\n 3: [306, 4] // 10Mb (10.16Mb: 306*4*17*512 or 10,653,696 bytes) (default XTC drive type: 3)\n },\n /*\n * aDriveTypes[1] is for the IBM PC AT (ATC) controller.\n *\n * The following is a more complete description of the drive types supported by the MODEL_5170, where C is\n * Cylinders, H is Heads, WP is Write Pre-Comp, and LZ is Landing Zone (in practice, we don't need WP or LZ).\n *\n * Type C H WP LZ\n * ---- --- -- --- ---\n * 1 306 4 128 305\n * 2 615 4 300 615\n * 3 615 6 300 615\n * 4 940 8 512 940\n * 5 940 6 512 940\n * 6 615 4 no 615\n * 7 462 8 256 511\n * 8 733 5 no 733\n * 9 900 15 no 901\n * 10 820 3 no 820\n * 11 855 5 no 855\n * 12 855 7 no 855\n * 13 306 8 128 319\n * 14 733 7 no 733\n * 15 (reserved--all zeros)\n * 16 612 4 all 663\n * 17 977 5 300 977\n * 18 977 7 no 977\n * 19 1024 7 512 1023\n * 20 733 5 300 732\n * 21 733 7 300 732\n * 22 733 5 300 733\n * 23 306 4 no 336\n */\n {\n 1: [306, 4], // 10Mb (10.16Mb: 306*4*17*512 or 10,653,696 bytes)\n 2: [615, 4], // 20Mb (20.42Mb: 615*4*17*512 or 21,411,840 bytes) (default ATC drive type)\n 3: [615, 6], // 31Mb (30.63Mb: 615*6*17*512 or 32,117,760 bytes)\n 4: [940, 8], // 62Mb (62.42Mb: 940*8*17*512 or 65,454,080 bytes)\n 5: [940, 6], // 47Mb (46.82Mb: 940*6*17*512 or 49,090,560 bytes)\n 6: [615, 4],\n 7: [462, 8],\n 8: [733, 5],\n 9: [900, 15],\n 10: [820, 3],\n 11: [855, 5],\n 12: [855, 7],\n 13: [306, 8],\n 14: [733, 7],\n /*\n * Since the remaining drive types are > 14, they must be stored in either EXTHDRIVE0 or EXTHDRIVE1 CMOS bytes (0x19 or 0x1A)\n */\n 16: [612, 4],\n 17: [977, 5],\n 18: [977, 7],\n 19: [1024, 7],\n 20: [733, 5],\n 21: [733, 7],\n 22: [733, 5],\n 23: [306, 4]\n },\n /*\n * aDriveTypes[2] is for the COMPAQ DeskPro (ATC) controller.\n *\n * NOTE: According to COMPAQ, drive type 25 (0x19) must be used with their 130Mb drive when using MS-DOS 3.1\n * or earlier, or when using any [unspecified] application software that supports only 17 sectors per track;\n * otherwise, use drive type 35 (0x23), which uses the drive's full capacity of 34 sectors per track.\n */\n {\n 1: [306, 4], // 10Mb (10.16Mb: 306*4*17*512 or 10,653,696 bytes) (same as IBM)\n 2: [615, 4], // 20Mb (20.42Mb: 615*4*17*512 or 21,411,840 bytes) (same as IBM)\n 3: [615, 6], // 31Mb (30.63Mb: 615*6*17*512 or 32,117,760 bytes) (same as IBM)\n 4: [1023, 8], // 68Mb (67.93Mb: 1023*8*17*512 or 71,233,536 bytes) (TODO: Cylinders is listed as 1024 in the COMPAQ TechRef; confirm)\n 5: [940, 6], // 47Mb (46.82Mb: 940*6*17*512 or 49,090,560 bytes) (same as IBM)\n 6: [697, 5],\n 7: [462, 8], // same as IBM\n 8: [925, 5],\n 9: [900, 15], // same as IBM\n 10: [980, 5],\n 11: [925, 7],\n 12: [925, 9], // 70Mb (69.10Mb: 925*9*17*512 or 72,460,800 bytes)\n 13: [612, 8],\n 14: [980, 4],\n /*\n * Since the remaining drive types are > 14, they must be stored in either EXTHDRIVE0 or EXTHDRIVE1 CMOS bytes (0x19 or 0x1A)\n */\n 16: [612, 4], // same as IBM\n 17: [980, 5], // 40Mb (40.67Mb: 980*5*17*512 or 42,649,600 bytes)\n 18: [966, 6],\n 19: [1023, 8],\n 20: [733, 5], // same as IBM\n 21: [733, 7], // same as IBM\n 22: [524, 4, 40],\n 23: [924, 8],\n 24: [966, 14],\n 25: [966, 16], // 130Mb (128.30Mb: 966*16*17*512 or 134,529,024 bytes)\n 26: [1023,14],\n 27: [832, 6, 33],\n 28: [1222,15, 34],\n 29: [1240, 7, 34],\n 30: [615, 4, 25],\n 31: [615, 8, 25],\n 32: [905, 9, 25],\n 33: [832, 8, 33], // 110Mb (107.25Mb: 832*8*33*512 or 112,459,776 bytes)\n 34: [966, 7, 34],\n 35: [966, 8, 34], // 130Mb (128.30Mb: 966*8*34*512 or 134,529,024 bytes)\n 36: [966, 9, 34],\n 37: [966, 5, 34],\n 38: [612, 16, 63], // 300Mb (301.22Mb: 612*16*63*512 or 315,850,752 bytes) (TODO: Cylinders is listed as 611 in the COMPAQ TechRef; confirm)\n 39: [1023,11, 33],\n 40: [1023,15, 34],\n 41: [1630,15, 52],\n 42: [1023,16, 63],\n 43: [805, 4, 26],\n 44: [805, 2, 26],\n 45: [748, 8, 33],\n 46: [748, 6, 33],\n 47: [966, 5, 25]\n }\n];\n\n/*\n * ATC (AT Controller) Registers\n *\n * The \"IBM Personal Computer AT Fixed Disk and Diskette Drive Adapter\", aka the HFCOMBO card, contains what we refer\n * to here as the ATC (AT Controller). Even though that card contains both Fixed Disk and Diskette Drive controllers,\n * this component (HDC) still deals only with the \"Fixed Disk\" portion. Fortunately, the \"Diskette Drive Adapter\"\n * portion of the card is compatible with the existing FDC component, so that component continues to be responsible\n * for all diskette operations.\n *\n * ATC ports default to their primary addresses; secondary port addresses are 0x80 lower (eg, 0x170 instead of 0x1F0).\n *\n * It's important to know that the MODEL_5170 BIOS has a special relationship with the \"Combo Hard File/Diskette\n * (HFCOMBO) Card\" (see @F000:144C). Initially, the ChipSet component intercepted reads for HFCOMBO's STATUS port\n * and returned the BUSY bit clear to reduce boot time; however, it turned out that was also a prerequisite for the\n * BIOS to write test patterns to the CYLLO port (0x1F4) and set the \"DUAL\" bit (bit 0) of the \"HFCNTRL\" byte at 40:8Fh\n * if those CYLLO operations succeeded (now that the HDC is \"ATC-aware\", the ChipSet port intercepts have been removed).\n *\n * Without the \"DUAL\" bit set, when it came time later to report the diskette drive type, the \"DISK_TYPE\" function\n * (@F000:273D) would branch to one of two almost-identical blocks of code -- specifically, a block that disallowed\n * diskette drive types >= 2 (ChipSet.CMOS.FDRIVE.FD360) instead of >= 3 (ChipSet.CMOS.FDRIVE.FD1200).\n *\n * In other words, the \"Fixed Disk\" portion of the HFCOMBO controller has to be present and operational if the user\n * wants to use high-capacity (80-track) diskettes with \"Diskette Drive\" portion of the controller. This may not be\n * immediately obvious to anyone creating a 5170 machine configuration with the FDC component but no HDC component.\n *\n * TODO: Investigate what a MODEL_5170 can do, if anything, with diskettes if an \"HFCOMBO card\" was NOT installed;\n * eg, was there Diskette-only Controller that could be installed, and if so, did it support high-capacity diskette\n * drives? Also, consider making the FDC component able to detect when the HDC is missing and provide the same minimal\n * HFCOMBO port intercepts that ChipSet once provided (this is not a requirement, just a usability improvement).\n *\n * UPDATE: I later discovered that newer (ie, REV2 and REV3) 5170 ROMs are even less happy when no HDC is installed,\n * *unless* an undocumented FDC \"DIAGNOSTIC\" register (port 0x3F1) provides a \"MULTIPLE DATA RATE\" response, bypassing\n * the HDC port tests described above. This may also imply that those newer 5170 revisions are incompatible with FD360\n * diskette drives, because if none of the \"MULTIPLE DATA RATE\" tests succeed, a \"601-Diskette Error\" always occurs.\n */\nHDC.ATC = {\n DATA: { PORT: 0x1F0}, // no register (read-write)\n DIAG: { // this.regError (read-only)\n PORT: 0x1F1,\n NO_ERROR: 0x01,\n CTRL_ERROR: 0x02,\n SEC_ERROR: 0x03,\n ECC_ERROR: 0x04,\n PROC_ERROR: 0x05\n },\n ERROR: { // this.regError (read-only)\n PORT: 0x1F1,\n NONE: 0x00,\n NO_DAM: 0x01, // Data Address Mark (DAM) not found\n NO_TRK0: 0x02, // Track 0 not detected\n CMD_ABORT: 0x04, // Aborted Command\n NO_CHS: 0x10, // ID field with the specified C:H:S not found\n ECC_ERR: 0x40, // Data ECC Error\n BAD_BLOCK: 0x80 // Bad Block Detect\n },\n WPREC: { PORT: 0x1F1}, // this.regWPreC (write-only)\n SECCNT: { PORT: 0x1F2}, // this.regSecCnt (read-write; 0 implies a 256-sector request)\n SECNUM: { PORT: 0x1F3}, // this.regSecNum (read-write)\n CYLLO: { PORT: 0x1F4}, // this.regCylLo (read-write; all 8 bits are used)\n CYLHI: { // this.regCylHi (read-write; only bits 0-1 are used, for a total of 10 bits, or 1024 max cylinders)\n PORT: 0x1F5,\n MASK: 0x03\n },\n DRVHD: { // this.regDrvHd (read-write)\n PORT: 0x1F6,\n HEAD_MASK: 0x0F, // set this to the max number of heads before issuing a SET PARAMETERS command\n DRIVE_MASK: 0x10,\n SET_MASK: 0xE0,\n SET_BITS: 0xA0 // for whatever reason, these bits must always be set\n },\n STATUS: { // this.regStatus (read-only; reading clears IRQ.ATC)\n PORT: 0x1F7,\n ERROR: 0x01, // set when the previous command ended in an error; one or more bits are set in the ERROR register (the next command to the controller resets the ERROR bit)\n INDEX: 0x02, // set once for every revolution of the disk\n CORRECTED: 0x04,\n DATA_REQ: 0x08, // indicates that \"the sector buffer requires servicing during a Read or Write command. If either bit 7 (BUSY) or this bit is active, a command is being executed. Upon receipt of any command, this bit is reset.\"\n SEEK_OK: 0x10, // seek operation complete\n WFAULT: 0x20, // write fault\n READY: 0x40, // if this is set (along with the SEEK_OK bit), the drive is ready to read/write/seek again\n BUSY: 0x80 // if this is set, no other STATUS bits are valid\n },\n COMMAND: { // this.regCommand (write-only)\n PORT: 0x1F7,\n RESTORE: 0x10, // low nibble x 500us equal stepping rate (except for 0, which corresponds to 35us) (aka RECALIBRATE)\n READ_DATA: 0x20, // also supports NO_RETRIES and WITH_ECC\n WRITE_DATA: 0x30, // also supports NO_RETRIES and WITH_ECC\n READ_VERF: 0x40, // also supports NO_RETRIES\n FORMAT_TRK: 0x50, // TODO\n SEEK: 0x70, // low nibble x 500us equal stepping rate (except for 0, which corresponds to 35us)\n DIAGNOSE: 0x90,\n SETPARMS: 0x91,\n NO_RETRIES: 0x01,\n WITH_ECC: 0x02,\n MASK: 0xF0\n },\n FDR: { // this.regFDR\n PORT: 0x3F6,\n INT_DISABLE: 0x02, // a logical 0 enables fixed disk interrupts\n RESET: 0x04, // a logical 1 enables reset fixed disk function\n HS3: 0x08, // a logical 1 enables head select 3 (a logical 0 enables reduced write current)\n RESERVED: 0xF1\n }\n};\n\n/*\n * XTC (XT Controller) Registers\n */\nHDC.XTC = {\n /*\n * XTC Data Register (0x320, read-write)\n *\n * Writes to this register are discussed below; see HDC Commands.\n *\n * Reads from this register after a command has been executed retrieve a \"status byte\",\n * which must NOT be confused with the Status Register (see below). This data \"status byte\"\n * contains only two bits of interest: XTC.DATA.STATUS.ERROR and XTC.DATA.STATUS.UNIT.\n */\n DATA: {\n PORT: 0x320, // port address\n STATUS: {\n OK: 0x00, // no error\n ERROR: 0x02, // error occurred during command execution\n UNIT: 0x20 // logical unit number of the drive\n },\n /*\n * XTC Commands, as issued to XTC_DATA\n *\n * Commands are multi-byte sequences sent to XTC_DATA, starting with a XTC_DATA.CMD byte,\n * and followed by 5 more bytes, for a total of 6 bytes, which collectively are called a\n * Device Control Block (DCB). Not all commands use all 6 bytes, but all 6 bytes must be present;\n * unused bytes are simply ignored.\n *\n * XTC_DATA.CMD (3-bit class code, 5-bit operation code)\n * XTC_DATA.HEAD (1-bit drive number, 5-bit head number)\n * XTC_DATA.CLSEC (upper bits of 10-bit cylinder number, 6-bit sector number)\n * XTC_DATA.CH (lower bits of 10-bit cylinder number)\n * XTC_DATA.COUNT (8-bit interleave or block count)\n * XTC_DATA.CTRL (8-bit control field)\n *\n * One command, HDC.XTC.DATA.CMD.INIT_DRIVE, must include 8 additional bytes following the DCB:\n *\n * maximum number of cylinders (high)\n * maximum number of cylinders (low)\n * maximum number of heads\n * start reduced write current cylinder (high)\n * start reduced write current cylinder (low)\n * start write precompensation cylinder (high)\n * start write precompensation cylinder (low)\n * maximum ECC data burst length\n *\n * Note that the 3 word values above are stored in \"big-endian\" format (high byte followed by low byte),\n * rather than the more typical \"little-endian\" format (low byte followed by high byte).\n */\n CMD: {\n TEST_READY: 0x00, // Test Drive Ready\n RECALIBRATE: 0x01, // Recalibrate\n REQUEST_SENSE: 0x03, // Request Sense Status\n FORMAT_DRIVE: 0x04, // Format Drive\n READ_VERF: 0x05, // Read Verify\n FORMAT_TRK: 0x06, // Format Track\n FORMAT_BAD: 0x07, // Format Bad Track\n READ_DATA: 0x08, // Read\n WRITE_DATA: 0x0A, // Write\n SEEK: 0x0B, // Seek\n INIT_DRIVE: 0x0C, // Initialize Drive Characteristics\n READ_ECC_BURST: 0x0D, // Read ECC Burst Error Length\n READ_BUFFER: 0x0E, // Read Data from Sector Buffer\n WRITE_BUFFER: 0x0F, // Write Data to Sector Buffer\n RAM_DIAGNOSTIC: 0xE0, // RAM Diagnostic\n DRV_DIAGNOSTIC: 0xE3, // HDC BIOS: CHK_DRV_CMD\n CTL_DIAGNOSTIC: 0xE4, // HDC BIOS: CNTLR_DIAG_CMD\n READ_LONG: 0xE5, // HDC BIOS: RD_LONG_CMD\n WRITE_LONG: 0xE6 // HDC BIOS: WR_LONG_CMD\n },\n ERR: {\n /*\n * HDC error conditions, as returned in byte 0 of the (4) bytes returned by the Request Sense Status command\n */\n NONE: 0x00,\n NO_INDEX: 0x01, // no index signal detected\n SEEK_INCOMPLETE:0x02, // no seek-complete signal\n WRITE_FAULT: 0x03,\n NOT_READY: 0x04, // after the controller selected the drive, the drive did not respond with a ready signal\n NO_TRACK: 0x06, // after stepping the max number of cylinders, the controller did not receive the track 00 signal from the drive\n STILL_SEEKING: 0x08,\n ECC_ID_ERROR: 0x10,\n ECC_DATA_ERROR: 0x11,\n NO_ADDR_MARK: 0x12,\n NO_SECTOR: 0x14,\n BAD_SEEK: 0x15, // seek error: the cylinder and/or head address did not compare with the expected target address\n ECC_CORRECTABLE:0x18, // correctable data error\n BAD_TRACK: 0x19,\n BAD_CMD: 0x20,\n BAD_DISK_ADDR: 0x21,\n RAM: 0x30,\n CHECKSUM: 0x31,\n POLYNOMIAL: 0x32,\n MASK: 0x3F\n },\n SENSE: {\n ADDR_VALID: 0x80\n }\n },\n /*\n * XTC Status Register (0x321, read-only)\n *\n * WARNING: The IBM Technical Reference Manual *badly* confuses the XTC_DATA \"status byte\" (above)\n * that the controller sends following an HDC.XTC.DATA.CMD operation with the Status Register (below).\n * In fact, it's so badly confused that it completely fails to document any of the Status Register\n * bits below; I'm forced to guess at their meanings from the HDC BIOS listing.\n */\n STATUS: {\n PORT: 0x321, // port address\n NONE: 0x00,\n REQ: 0x01, // HDC BIOS: request bit\n IOMODE: 0x02, // HDC BIOS: mode bit (GUESS: set whenever XTC_DATA contains a response?)\n BUS: 0x04, // HDC BIOS: command/data bit (GUESS: set whenever XTC_DATA ready for request?)\n BUSY: 0x08, // HDC BIOS: busy bit\n INTERRUPT: 0x20 // HDC BIOS: interrupt bit\n }\n};\n\n/*\n * XTC Config Register (0x322, read-only)\n *\n * This register is used to read HDC card switch settings that defined the \"Drive Type\" for\n * drives 0 and 1. SW[1],SW[2] (for drive 0) and SW[3],SW[4] (for drive 1) are set as follows:\n *\n * ON, ON Drive Type 0 (306 cylinders, 2 heads)\n * ON, OFF Drive Type 1 (375 cylinders, 8 heads)\n * OFF, ON Drive Type 2 (306 cylinders, 6 heads)\n * OFF, OFF Drive Type 3 (306 cylinders, 4 heads)\n */\n\n/*\n * HDC Command Sequences\n *\n * Unlike the FDC, all the HDC commands have fixed-length command request sequences (well, OK, except for\n * HDC.XTC.DATA.CMD.INIT_DRIVE) and fixed-length response sequences (well, OK, except for HDC.XTC.DATA.CMD.REQUEST_SENSE),\n * so a table of byte-lengths isn't much use, but having names for all the commands is still handy for debugging.\n */\nif (DEBUG) {\n HDC.aATCCommands = {\n 0x10: \"Restore (Recalibrate)\",\n 0x20: \"Read\",\n 0x30: \"Write\",\n 0x40: \"Read Verify\",\n 0x50: \"Format Track\",\n 0x70: \"Seek\",\n 0x90: \"Diagnose\",\n 0x91: \"Set Parameters\"\n };\n HDC.aXTCCommands = {\n 0x00: \"Test Drive Ready\",\n 0x01: \"Recalibrate\",\n 0x03: \"Request Sense Status\",\n 0x04: \"Format Drive\",\n 0x05: \"Read Verify\",\n 0x06: \"Format Track\",\n 0x07: \"Format Bad Track\",\n 0x08: \"Read\",\n 0x0A: \"Write\",\n 0x0B: \"Seek\",\n 0x0C: \"Initialize Drive Characteristics\",\n 0x0D: \"Read ECC Burst Error Length\",\n 0x0E: \"Read Data from Sector Buffer\",\n 0x0F: \"Write Data to Sector Buffer\",\n 0xE0: \"RAM Diagnostic\",\n 0xE3: \"Drive Diagnostic\",\n 0xE4: \"Controller Diagnostic\",\n 0xE5: \"Read Long\",\n 0xE6: \"Write Long\"\n };\n}\n\n/*\n * Port input notification tables\n */\nHDC.aXTCPortInput = {\n 0x320: HDC.prototype.inXTCData,\n 0x321: HDC.prototype.inXTCStatus,\n 0x322: HDC.prototype.inXTCConfig\n};\n\n/*\n * For future reference, the REV2 and REV3 PC AT ROM BIOS also refer to a \"FIXED DISK DIAGNOSTIC REGISTER\" at\n * port 0x5F7, but I have no documentation on it, and failure to respond is non-fatal. See the discussion of the\n * FDC diagnostic register in inFDCDiagnostic() for more details.\n */\nHDC.aATCPortInput = {\n 0x1F0: HDC.prototype.inATCData,\n 0x1F1: HDC.prototype.inATCError,\n 0x1F2: HDC.prototype.inATCSecCnt,\n 0x1F3: HDC.prototype.inATCSecNum,\n 0x1F4: HDC.prototype.inATCCylLo,\n 0x1F5: HDC.prototype.inATCCylHi,\n 0x1F6: HDC.prototype.inATCDrvHd,\n 0x1F7: HDC.prototype.inATCStatus\n};\n\n/*\n * Port output notification tables\n */\nHDC.aXTCPortOutput = {\n 0x320: HDC.prototype.outXTCData,\n 0x321: HDC.prototype.outXTCReset,\n 0x322: HDC.prototype.outXTCPulse,\n 0x323: HDC.prototype.outXTCPattern,\n /*\n * The PC XT Fixed Disk BIOS includes some additional \"housekeeping\" that it performs\n * not only on port 0x323 but also on three additional ports, at increments of 4 (see all\n * references to \"RESET INT/DMA MASK\" in the Fixed Disk BIOS). It's not clear to me if\n * those ports refer to additional HDC controllers, and I haven't seen other references to\n * them, but in any case, they represent a lot of \"I/O noise\" that we simply squelch here.\n */\n 0x327: HDC.prototype.outXTCNoise,\n 0x32B: HDC.prototype.outXTCNoise,\n 0x32F: HDC.prototype.outXTCNoise\n};\n\nHDC.aATCPortOutput = {\n 0x1F0: HDC.prototype.outATCData,\n 0x1F1: HDC.prototype.outATCWPreC,\n 0x1F2: HDC.prototype.outATCSecCnt,\n 0x1F3: HDC.prototype.outATCSecNum,\n 0x1F4: HDC.prototype.outATCCylLo,\n 0x1F5: HDC.prototype.outATCCylHi,\n 0x1F6: HDC.prototype.outATCDrvHd,\n 0x1F7: HDC.prototype.outATCCommand,\n 0x3F6: HDC.prototype.outATCFDR\n};\n\n/*\n * Initialize every Hard Drive Controller (HDC) module on the page.\n */\nWeb.onInit(HDC.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/debugger.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Debugger Address Object\n *\n * This is the basic structure; other debuggers may extend it.\n *\n * addr address\n * fTemporary true if this is a temporary breakpoint address\n * sCmd set for breakpoint addresses if there's an associated command string\n * aCmds preprocessed commands (from sCmd)\n *\n * @typedef {{\n * addr:(number|undefined),\n * fTemporary:(boolean|undefined),\n * sCmd:(string|undefined),\n * aCmds:(Array.<string>|undefined)\n * }}\n */\nvar DbgAddr;\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * subclass (eg, SerialPort), because otherwise the Compiler won't allow us to *reference*\n * the named property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass Debugger extends Component\n{\n /**\n * Debugger(parmsDbg)\n *\n * The Debugger component supports the following optional (parmsDbg) properties:\n *\n * base: the base to use for most numeric input/output (default is 16)\n *\n * The Debugger component is a shared component containing a subset of functionality used by\n * the other CPU-specific Debuggers (eg, DebuggerX86). Over time, the goal is to factor out as\n * much common debugging support as possible from those components into this one.\n *\n * @param {Object} parmsDbg\n */\n constructor(parmsDbg)\n {\n if (DEBUGGER) {\n\n super(\"Debugger\", parmsDbg);\n\n /*\n * Default base used to display all values; modified with the \"s base\" command.\n */\n this.nBase = +parmsDbg['base'] || 16;\n\n /*\n * Default number of bits of integer precision; it can be overridden by the Debugger\n * but there is no command to adjust it.\n */\n this.nBits = 32;\n\n this.achGroup = ['{','}'];\n this.achAddress = ['[',']'];\n\n /*\n * These keep track of instruction activity, but only when tracing or when Debugger checks\n * have been enabled (eg, one or more breakpoints have been set).\n *\n * They are zeroed by the reset() notification handler. cInstructions is advanced by\n * stepCPU() and checkInstruction() calls. nCycles is updated by every stepCPU() or stop()\n * call and simply represents the number of cycles performed by the last run of instructions.\n */\n this.nCycles = 0;\n this.cOpcodes = this.cOpcodesStart = 0;\n\n /*\n * fAssemble is true when \"assemble mode\" is active, false when not.\n */\n this.fAssemble = false;\n\n /*\n * This maintains command history. New commands are inserted at index 0 of the array.\n * When Enter is pressed on an empty input buffer, we default to the command at aPrevCmds[0].\n */\n this.iPrevCmd = -1;\n this.aPrevCmds = [];\n\n /*\n * aVariables is an object with properties that grow as setVariable() assigns more variables;\n * each property corresponds to one variable, where the property name is the variable name (ie,\n * a string beginning with a non-digit, followed by zero or more symbol characters and/or digits)\n * and the property value is the variable's numeric value. See doVar() and setVariable() for\n * details.\n *\n * Note that parseValue() parses variables before numbers, so any variable that looks like a\n * unprefixed hex value (eg, \"a5\" as opposed to \"0xa5\") will trump the numeric value. Unprefixed\n * hex values are a convenience of parseValue(), which always calls Str.parseInt() with a default\n * base of 16; however, that default be overridden with a variety of explicit prefixes or suffixes\n * (eg, a leading \"0o\" to indicate octal, a trailing period to indicate decimal, etc.)\n *\n * See Str.parseInt() for more details about supported numbers.\n */\n this.aVariables = {};\n\n } // endif DEBUGGER\n }\n\n /**\n * getRegIndex(sReg, off)\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {string} sReg\n * @param {number} [off] optional offset into sReg\n * @return {number} register index, or -1 if not found\n */\n getRegIndex(sReg, off)\n {\n return -1;\n }\n\n /**\n * getRegValue(iReg)\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {number} iReg\n * @return {number|undefined}\n */\n getRegValue(iReg)\n {\n return undefined;\n }\n\n /**\n * parseAddrReference(s, sAddr)\n *\n * Returns the given string with the given address reference replaced with the contents of that address.\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {string} s\n * @param {string} sAddr\n * @return {string}\n */\n parseAddrReference(s, sAddr)\n {\n return s.replace('[' + sAddr + ']', \"unimplemented\");\n }\n\n /**\n * getNextCommand()\n *\n * @this {Debugger}\n * @return {string}\n */\n getNextCommand()\n {\n var sCmd;\n if (this.iPrevCmd > 0) {\n sCmd = this.aPrevCmds[--this.iPrevCmd];\n } else {\n sCmd = \"\";\n this.iPrevCmd = -1;\n }\n return sCmd;\n }\n\n /**\n * getPrevCommand()\n *\n * @this {Debugger}\n * @return {string|null}\n */\n getPrevCommand()\n {\n var sCmd = null;\n if (this.iPrevCmd < this.aPrevCmds.length - 1) {\n sCmd = this.aPrevCmds[++this.iPrevCmd];\n }\n return sCmd;\n }\n\n /**\n * parseCommand(sCmd, fSave, chSep)\n *\n * @this {Debugger}\n * @param {string|undefined} sCmd\n * @param {boolean} [fSave] is true to save the command, false if not\n * @param {string} [chSep] is the command separator character (default is ';')\n * @return {Array.<string>}\n */\n parseCommand(sCmd, fSave, chSep)\n {\n if (fSave) {\n if (!sCmd) {\n if (this.fAssemble) {\n sCmd = \"end\";\n } else {\n sCmd = this.aPrevCmds[this.iPrevCmd+1];\n }\n } else {\n if (this.iPrevCmd < 0 && this.aPrevCmds.length) {\n this.iPrevCmd = 0;\n }\n if (this.iPrevCmd < 0 || sCmd != this.aPrevCmds[this.iPrevCmd]) {\n this.aPrevCmds.splice(0, 0, sCmd);\n this.iPrevCmd = 0;\n }\n this.iPrevCmd--;\n }\n }\n var a = [];\n if (sCmd) {\n /*\n * With the introduction of breakpoint commands (ie, quoted command sequences\n * associated with a breakpoint), we can no longer perform simplistic splitting.\n *\n * a = sCmd.split(chSep || ';');\n * for (var i = 0; i < a.length; i++) a[i] = Str.trim(a[i]);\n *\n * We may now split on semi-colons ONLY if they are outside a quoted sequence.\n *\n * Also, to allow quoted strings *inside* breakpoint commands, we first replace all\n * DOUBLE double-quotes with single quotes.\n */\n sCmd = sCmd.replace(/\"\"/g, \"'\");\n\n var iPrev = 0;\n var chQuote = null;\n chSep = chSep || ';';\n /*\n * NOTE: Processing charAt() up to and INCLUDING length is not a typo; we're taking\n * advantage of the fact that charAt() with an invalid index returns an empty string,\n * allowing us to use the same substring() call to capture the final portion of sCmd.\n *\n * In a sense, it allows us to pretend that the string ends with a zero terminator.\n */\n for (var i = 0; i <= sCmd.length; i++) {\n var ch = sCmd.charAt(i);\n if (ch == '\"' || ch == \"'\") {\n if (!chQuote) {\n chQuote = ch;\n } else if (ch == chQuote) {\n chQuote = null;\n }\n }\n else if (ch == chSep && !chQuote || !ch) {\n /*\n * Recall that substring() accepts starting (inclusive) and ending (exclusive)\n * indexes, whereas substr() accepts a starting index and a length. We need the former.\n */\n a.push(Str.trim(sCmd.substring(iPrev, i)));\n iPrev = i + 1;\n }\n }\n }\n return a;\n }\n\n /**\n * evalAND(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.AND().\n *\n * Performs the bitwise \"and\" (AND) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst & src)\n */\n evalAND(dst, src)\n {\n /*\n * We AND the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 AND 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst & src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) & ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst & src) >>> 0);\n }\n\n /**\n * evalIOR(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.IOR().\n *\n * Performs the logical \"inclusive-or\" (OR) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst | src)\n */\n evalIOR(dst, src)\n {\n /*\n * We OR the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 OR 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst | src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) | ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst | src) >>> 0);\n }\n\n /**\n * evalXOR(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.XOR().\n *\n * Performs the logical \"exclusive-or\" (XOR) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst ^ src)\n */\n evalXOR(dst, src)\n {\n /*\n * We XOR the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 XOR 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst | src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) ^ ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst ^ src) >>> 0);\n }\n\n /**\n * evalMUL(dst, src)\n *\n * I could have adapted the code from /modules/pdp10/lib/cpuops.js:PDP10.doMUL(), but it was simpler to\n * write this base method and let the PDP-10 Debugger override it with a call to the *actual* doMUL() method.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst * src)\n */\n evalMUL(dst, src)\n {\n return dst * src;\n }\n\n /**\n * truncate(v, nBits, fUnsigned)\n *\n * @this {Debugger}\n * @param {number} v\n * @param {number} [nBits]\n * @param {boolean} [fUnsigned]\n * @return {number}\n */\n truncate(v, nBits, fUnsigned)\n {\n var limit, vNew = v;\n nBits = nBits || this.nBits;\n\n if (fUnsigned) {\n if (nBits == 32) {\n vNew = v >>> 0;\n }\n else if (nBits < 32) {\n vNew = v & ((1 << nBits) - 1);\n }\n else {\n limit = Math.pow(2, nBits);\n if (v < 0 || v >= limit) {\n vNew = v % limit;\n if (vNew < 0) vNew += limit;\n }\n }\n }\n else {\n if (nBits <= 32) {\n vNew = (v << (32 - nBits)) >> (32 - nBits);\n }\n else {\n limit = Math.pow(2, nBits - 1);\n if (v >= limit) {\n vNew = (v % limit);\n if (((v / limit)|0) & 1) vNew -= limit;\n } else if (v < -limit) {\n vNew = (v % limit);\n if ((((-v - 1) / limit) | 0) & 1) {\n if (vNew) vNew += limit;\n }\n else {\n if (!vNew) vNew -= limit;\n }\n }\n }\n }\n if (v != vNew) {\n if (MAXDEBUG) this.println(\"warning: value \" + v + \" truncated to \" + vNew);\n v = vNew;\n }\n return v;\n }\n\n /**\n * evalOps(aVals, aOps, cOps)\n *\n * Some of our clients want a specific number of bits of integer precision. If that precision is\n * greater than 32, some of the operations below will fail; for example, JavaScript bitwise operators\n * always truncate the result to 32 bits, so beware when using shift operations. Similarly, it would\n * be wrong to always \"|0\" the final result, which is why we rely on truncate() now.\n *\n * Note that JavaScript integer precision is limited to 52 bits. For example, in Node, if you set a\n * variable to 0x80000001:\n *\n * foo=0x80000001|0\n *\n * then calculate foo*foo and display the result in binary using \"(foo*foo).toString(2)\":\n *\n * '11111111111111111111111111111100000000000000000000000000000000'\n *\n * which is slightly incorrect because it has overflowed JavaScript's floating-point precision.\n *\n * 0x80000001 in decimal is -2147483647, so the product is 4611686014132420609, which is 0x3FFFFFFF00000001.\n *\n * @this {Debugger}\n * @param {Array.<number>} aVals\n * @param {Array.<string>} aOps\n * @param {number} [cOps] (default is -1 for all)\n * @return {boolean} true if successful, false if error\n */\n evalOps(aVals, aOps, cOps = -1)\n {\n while (cOps-- && aOps.length) {\n var chOp = aOps.pop();\n if (aVals.length < 2) return false;\n var valNew;\n var val2 = aVals.pop();\n var val1 = aVals.pop();\n switch(chOp) {\n case '*':\n valNew = this.evalMUL(val1, val2);\n break;\n case '/':\n if (!val2) return false;\n valNew = Math.trunc(val1 / val2);\n break;\n case '^/':\n if (!val2) return false;\n valNew = val1 % val2;\n break;\n case '+':\n valNew = val1 + val2;\n break;\n case '-':\n valNew = val1 - val2;\n break;\n case '<<':\n valNew = val1 << val2;\n break;\n case '>>':\n valNew = val1 >> val2;\n break;\n case '>>>':\n valNew = val1 >>> val2;\n break;\n case '<':\n valNew = (val1 < val2? 1 : 0);\n break;\n case '<=':\n valNew = (val1 <= val2? 1 : 0);\n break;\n case '>':\n valNew = (val1 > val2? 1 : 0);\n break;\n case '>=':\n valNew = (val1 >= val2? 1 : 0);\n break;\n case '==':\n valNew = (val1 == val2? 1 : 0);\n break;\n case '!=':\n valNew = (val1 != val2? 1 : 0);\n break;\n case '&':\n valNew = this.evalAND(val1, val2);\n break;\n case '!': // alias for MACRO-10 to perform a bitwise inclusive-or (OR)\n case '|':\n valNew = this.evalIOR(val1, val2);\n break;\n case '^!': // since MACRO-10 uses '^' for base overrides, '^!' is used for bitwise exclusive-or (XOR)\n valNew = this.evalXOR(val1, val2);\n break;\n case '&&':\n valNew = (val1 && val2? 1 : 0);\n break;\n case '||':\n valNew = (val1 || val2? 1 : 0);\n break;\n case ',,':\n valNew = this.truncate(val1, 18, true) * Math.pow(2, 18) + this.truncate(val2, 18, true);\n break;\n case '_':\n case '^_':\n valNew = val1;\n /*\n * While we always try to avoid assuming any particular number of bits of precision, the 'B' shift\n * operator (which we've converted to '^_') is unique to the MACRO-10 environment, which imposes the\n * following restrictions on the shift count.\n */\n if (chOp == '^_') val2 = 35 - (val2 & 0xff);\n if (val2) {\n /*\n * Since binary shifting is a logical (not arithmetic) operation, and since shifting by division only\n * works properly with positive numbers, we call truncate() to produce an unsigned value.\n */\n valNew = this.truncate(valNew, 0, true);\n if (val2 > 0) {\n valNew *= Math.pow(2, val2);\n } else {\n valNew = Math.trunc(valNew / Math.pow(2, -val2));\n }\n }\n break;\n default:\n return false;\n }\n aVals.push(this.truncate(valNew));\n }\n return true;\n }\n\n /**\n * parseArray(asValues, iValue, iLimit, nBase, aUndefined)\n *\n * parseExpression() takes a complete expression and divides it into array elements, where even elements\n * are values (which may be empty if two or more operators appear consecutively) and odd elements are operators.\n *\n * For example, if the original expression was \"2*{3+{4/2}}\", parseExpression() would call parseArray() with:\n *\n * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14\n * - - - - - - - - - - -- -- -- -- --\n * 2 * { 3 + { 4 / 2 } }\n *\n * This function takes care of recursively processing grouped expressions, by processing subsets of the array,\n * as well as handling certain base overrides (eg, temporarily switching to base-10 for binary shift suffixes).\n *\n * @param {Array.<string>} asValues\n * @param {number} iValue\n * @param {number} iLimit\n * @param {number} nBase\n * @param {Array|undefined} [aUndefined]\n * @return {number|undefined}\n */\n parseArray(asValues, iValue, iLimit, nBase, aUndefined)\n {\n var value;\n var sValue, sOp;\n var fError = false;\n var nUnary = 0;\n var aVals = [], aOps = [];\n\n var nBasePrev = this.nBase;\n this.nBase = nBase;\n\n while (iValue < iLimit) {\n var v;\n sValue = asValues[iValue++].trim();\n sOp = (iValue < iLimit? asValues[iValue++] : \"\");\n\n if (sValue) {\n v = this.parseValue(sValue, null, aUndefined, nUnary);\n } else {\n if (sOp == '{') {\n var cOpen = 1;\n var iStart = iValue;\n while (iValue < iLimit) {\n sValue = asValues[iValue++].trim();\n sOp = (iValue < asValues.length? asValues[iValue++] : \"\");\n if (sOp == '{') {\n cOpen++;\n } else if (sOp == '}') {\n if (!--cOpen) break;\n }\n }\n v = this.parseArray(asValues, iStart, iValue-1, this.nBase, aUndefined);\n if (v != null && nUnary) {\n v = this.parseUnary(v, nUnary);\n }\n sValue = (iValue < iLimit? asValues[iValue++].trim() : \"\");\n sOp = (iValue < iLimit? asValues[iValue++] : \"\");\n }\n else {\n /*\n * When parseExpression() calls us, it has collapsed all runs of whitespace into single spaces,\n * and although it allows single spaces to divide the elements of the expression, a space is neither\n * a unary nor binary operator. It's essentially a no-op. If we encounter it here, then it followed\n * another operator and is easily ignored (although perhaps it should still trigger a reset of nBase\n * and nUnary -- TBD).\n */\n if (sOp == ' ') {\n continue;\n }\n if (sOp == '^B') {\n this.nBase = 2;\n continue;\n }\n if (sOp == '^O') {\n this.nBase = 8;\n continue;\n }\n if (sOp == '^D') {\n this.nBase = 10;\n continue;\n }\n if (!(nUnary & (0xC0000000|0))) {\n if (sOp == '+') {\n continue;\n }\n if (sOp == '-') {\n nUnary = (nUnary << 2) | 1;\n continue;\n }\n if (sOp == '~' || sOp == '^-') {\n nUnary = (nUnary << 2) | 2;\n continue;\n }\n if (sOp == '^L') {\n nUnary = (nUnary << 2) | 3;\n continue;\n }\n }\n fError = true;\n break;\n }\n }\n\n if (v === undefined) {\n if (aUndefined) {\n aUndefined.push(sValue);\n v = 0;\n } else {\n fError = true;\n aUndefined = [];\n break;\n }\n }\n\n aVals.push(this.truncate(v));\n\n /*\n * When parseExpression() calls us, it has collapsed all runs of whitespace into single spaces,\n * and although it allows single spaces to divide the elements of the expression, a space is neither\n * a unary nor binary operator. It's essentially a no-op. If we encounter it here, then it followed\n * a value, and since we don't want to misinterpret the next operator as a unary operator, we look\n * ahead and grab the next operator if it's not preceded by a value.\n */\n if (sOp == ' ') {\n if (iValue < asValues.length - 1 && !asValues[iValue]) {\n iValue++;\n sOp = asValues[iValue++]\n } else {\n fError = true;\n break;\n }\n }\n\n if (!sOp) break;\n\n var aBinOp = (this.achGroup[0] == '<'? Debugger.aDECOpPrecedence : Debugger.aBinOpPrecedence);\n if (!aBinOp[sOp]) {\n fError = true;\n break;\n }\n if (aOps.length && aBinOp[sOp] <= aBinOp[aOps[aOps.length - 1]]) {\n this.evalOps(aVals, aOps, 1);\n }\n aOps.push(sOp);\n\n /*\n * The MACRO-10 binary shifting operator assumes a base-10 shift count, regardless of the current\n * base, so we must override the current base to ensure the count is parsed correctly.\n */\n this.nBase = (sOp == '^_')? 10 : nBase;\n nUnary = 0;\n }\n\n if (fError || !this.evalOps(aVals, aOps) || aVals.length != 1) {\n fError = true;\n }\n\n if (!fError) {\n value = aVals.pop();\n\n } else if (!aUndefined) {\n this.println(\"parse error (\" + (sValue || sOp) + \")\");\n }\n\n this.nBase = nBasePrev;\n return value;\n }\n\n /**\n * parseASCII(sExp, chDelim, nBits, cchMax)\n *\n * @this {Debugger}\n * @param {string} sExp\n * @param {string} chDelim\n * @param {number} nBits\n * @param {number} cchMax\n * @return {string|undefined}\n */\n parseASCII(sExp, chDelim, nBits, cchMax)\n {\n var i;\n while ((i = sExp.indexOf(chDelim)) >= 0) {\n var v = 0;\n var j = i + 1;\n var cch = cchMax;\n while (j < sExp.length) {\n var ch = sExp[j++];\n if (ch == chDelim) {\n cch = -1;\n break;\n }\n if (!cch) break;\n cch--;\n var c = ch.charCodeAt(0);\n if (nBits == 7) {\n c &= 0x7F;\n } else {\n c = (c - 0x20) & 0x3F;\n }\n v = this.truncate(v * Math.pow(2, nBits) + c, nBits * cchMax, true);\n }\n if (cch >= 0) {\n this.println(\"parse error (\" + chDelim + sExp + chDelim + \")\");\n return undefined;\n } else {\n sExp = sExp.substr(0, i) + this.toStrBase(v, -1) + sExp.substr(j);\n }\n }\n return sExp;\n }\n\n /**\n * parseExpression(sExp, fQuiet)\n *\n * A quick-and-dirty expression parser. It takes an expression like:\n *\n * EDX+EDX*4+12345678\n *\n * and builds a value stack in aVals and a \"binop\" (binary operator) stack in aOps:\n *\n * aVals aOps\n * ----- ----\n * EDX +\n * EDX *\n * 4 +\n * ...\n *\n * We pop 1 \"binop\" from aOps and 2 values from aVals whenever a \"binop\" of lower priority than its\n * predecessor is encountered, evaluate, and push the result back onto aVals. Only selected unary\n * operators are supported (eg, negate and complement); no ternary operators like '?:' are supported.\n *\n * fQuiet can be used to pass an array that collects any undefined variables that parseExpression()\n * encounters; the value of an undefined variable is zero. This mode was added for components that need\n * to support expressions containing \"fixups\" (ie, values that must be determined later).\n *\n * @this {Debugger}\n * @param {string|undefined} sExp\n * @param {Array|undefined|boolean} [fQuiet]\n * @return {number|undefined} numeric value, or undefined if sExp contains any undefined or invalid values\n */\n parseExpression(sExp, fQuiet)\n {\n var value = undefined;\n var fPrint = (fQuiet === false);\n var aUndefined = Array.isArray(fQuiet)? fQuiet : undefined;\n\n if (sExp) {\n\n /*\n * The default delimiting characters for grouped expressions are braces; they can be changed by altering\n * achGroup, but when that happens, instead of changing our regular expressions and operator tables,\n * we simply replace all achGroup characters with braces in the given expression.\n *\n * Why not use parentheses for grouped expressions? Because some debuggers use parseReference() to perform\n * parenthetical value replacements in message strings, and they don't want parentheses taking on a different\n * meaning. And for some machines, like the PDP-10, the convention is to use parentheses for other things,\n * like indexed addressing, and to use angle brackets for grouped expressions.\n */\n if (this.achGroup[0] != '{') {\n sExp = sExp.split(this.achGroup[0]).join('{').split(this.achGroup[1]).join('}');\n }\n\n /*\n * Quoted ASCII characters can have a numeric value, too, which must be converted now, to avoid any\n * conflicts with the operators below.\n */\n sExp = this.parseASCII(sExp, '\"', 7, 5); // MACRO-10 packs up to 5 7-bit ASCII codes into a value\n if (!sExp) return value;\n sExp = this.parseASCII(sExp, \"'\", 6, 6); // MACRO-10 packs up to 6 6-bit ASCII (SIXBIT) codes into a value\n if (!sExp) return value;\n\n /*\n * All browsers (including, I believe, IE9 and up) support the following idiosyncrasy of a RegExp split():\n * when the RegExp uses a capturing pattern, the resulting array will include entries for all the pattern\n * matches along with the non-matches. This effectively means that, in the set of expressions that we\n * support, all even entries in asValues will contain \"values\" and all odd entries will contain \"operators\".\n *\n * Although I started listing the operators in the RegExp in \"precedential\" order, that's not important;\n * what IS important is listing operators than contain shorter operators first. For example, bitwise\n * shift operators must be listed BEFORE the logical less-than or greater-than operators. The aBinOp tables\n * (aBinOpPrecedence and aDECOpPrecedence) are what determine precedence, not the RegExp.\n *\n * Also, to better accommodate MACRO-10 syntax, I've replaced the single '^' for XOR with '^!', and I've\n * added '!' as an alias for '|' (bitwise inclusive-or), '^-' as an alias for '~' (one's complement operator),\n * and '_' as a shift operator (+/- values specify a left/right shift, and the count is not limited to 32).\n *\n * And to avoid conflicts with MACRO-10 syntax, I've replaced the original mod operator ('%') with '^/'.\n *\n * The MACRO-10 binary shifting suffix ('B') is a bit more problematic, since a capital B can also appear\n * inside symbols, or inside hex values. So if the default base is NOT 16, then I pre-scan for that suffix\n * and replace all non-symbolic occurrences with an internal shift operator ('^_').\n *\n * Note that Str.parseInt(), which parseValue() relies on, supports both the MACRO-10 base prefix overrides\n * and the binary shifting suffix ('B'), but since that suffix can also be a bracketed expression, we have to\n * support it here as well.\n *\n * MACRO-10 supports only a subset of all the PCjs operators; for example, MACRO-10 doesn't support any of\n * the boolean logical/compare operators. But unless we run into conflicts, I prefer sticking with this\n * common set of operators.\n *\n * All whitespace in the expression is collapsed to single spaces, and space has been added to the list\n * of \"operators\", but its sole function is as a separator, not as an operator. parseArray() will ignore\n * single spaces as long as they are preceded and/or followed by a \"real\" operator. It would be dangerous\n * to remove spaces entirely, because if an operator-less expression like \"A B\" was passed in, we would want\n * that to generate an error; if we converted it to \"AB\", evaluation might inadvertently succeed.\n */\n var regExp = /({|}|\\|\\||&&|\\||\\^!|\\^B|\\^O|\\^D|\\^L|\\^-|~|\\^_|_|&|!=|!|==|>=|>>>|>>|>|<=|<<|<|-|\\+|\\^\\/|\\/|\\*|,,| )/;\n if (this.nBase != 16) {\n sExp = sExp.replace(/(^|[^A-Z0-9$%.])([0-9]+)B/, \"$1$2^_\").replace(/\\s+/g, ' ');\n }\n var asValues = sExp.split(regExp);\n value = this.parseArray(asValues, 0, asValues.length, this.nBase, aUndefined);\n if (value !== undefined && fPrint) {\n this.printValue(null, value);\n }\n }\n return value;\n }\n\n /**\n * parseReference(s)\n *\n * Returns the given string with any \"{expression}\" sequences replaced with the value of the expression,\n * and any \"[address]\" references replaced with the contents of the address. Expressions are parsed BEFORE\n * addresses.\n *\n * @this {Debugger}\n * @param {string} s\n * @return {string|undefined}\n */\n parseReference(s)\n {\n var a;\n var chOpen = this.achGroup[0];\n var chClose = this.achGroup[1];\n var chEscape = (chOpen == '(' || chOpen == '{' || chOpen == '[')? '\\\\' : '';\n var chInnerEscape = (chOpen == '['? '\\\\' : '');\n var reSubExp = new RegExp(chEscape + chOpen + \"([^\" + chInnerEscape + chOpen + chInnerEscape + chClose + \"]+)\" + chEscape + chClose);\n while (a = s.match(reSubExp)) {\n var value = this.parseExpression(a[1]);\n if (value === undefined) return undefined;\n var sSearch = chOpen + a[1] + chClose;\n var sReplace = value != null? this.toStrBase(value) : \"undefined\";\n /*\n * Note that by default, the String replace() method only replaces the FIRST occurrence,\n * and there MIGHT be more than one occurrence of the expression we just parsed, so we could\n * do this instead:\n *\n * s = s.split(sSearch).join(sReplace);\n *\n * However, that's knd of an expensive (slow) solution, and it's not strictly necessary, since\n * any additional identical expressions will be picked up on a subsequent iteration through this loop.\n */\n s = s.replace(sSearch, sReplace);\n }\n if (this.achAddress.length) {\n chOpen = this.achAddress[0];\n chClose = this.achAddress[1];\n chEscape = (chOpen == '(' || chOpen == '{' || chOpen == '[')? '\\\\' : '';\n chInnerEscape = (chOpen == '['? '\\\\' : '');\n reSubExp = new RegExp(chEscape + chOpen + \"([^\" + chInnerEscape + chOpen + chInnerEscape + chClose + \"]+)\" + chEscape + chClose);\n while (a = s.match(reSubExp)) {\n s = this.parseAddrReference(s, a[1]);\n }\n }\n return this.parseSysVars(s);\n }\n\n /**\n * parseSysVars(s)\n *\n * Returns the given string with any recognized \"$var\" replaced with its value; eg:\n *\n * $ops: the number of opcodes executed since the last time it was displayed (or reset)\n *\n * @this {Debugger}\n * @param {string} s\n * @return {string}\n */\n parseSysVars(s)\n {\n var a;\n while (a = s.match(/\\$([a-z]+)/i)) {\n var v = null;\n switch(a[1].toLowerCase()) {\n case \"ops\":\n v = this.cOpcodes - this.cOpcodesStart;\n break;\n }\n if (v == null) break;\n s = s.replace(a[0], v.toString());\n }\n return s;\n }\n\n /**\n * parseUnary(value, nUnary)\n *\n * nUnary is actually a small \"stack\" of unary operations encoded in successive pairs of bits.\n * As parseExpression() encounters each unary operator, nUnary is shifted left 2 bits, and the\n * new unary operator is encoded in bits 0 and 1 (0b00 is none, 0b01 is negate, 0b10 is complement,\n * and 0b11 is reserved). Here, we process the bits in reverse order (hence the stack-like nature),\n * ensuring that we process the unary operators associated with this value right-to-left.\n *\n * Since bitwise operators see only 32 bits, more than 16 unary operators cannot be supported\n * using this method. We'll let parseExpression() worry about that; if it ever happens in practice,\n * then we'll have to switch to a more \"expensive\" approach (eg, an actual array of unary operators).\n *\n * @this {Debugger}\n * @param {number} value\n * @param {number} nUnary\n * @return {number}\n */\n parseUnary(value, nUnary)\n {\n while (nUnary) {\n switch(nUnary & 0o3) {\n case 1:\n value = -this.truncate(value);\n break;\n case 2:\n value = this.evalXOR(value, -1); // this is easier than adding an evalNOT()...\n break;\n case 3:\n var bit = 35; // simple left-to-right zero-bit-counting loop...\n while (bit >= 0 && !this.evalAND(value, Math.pow(2, bit))) bit--;\n value = 35 - bit;\n break;\n }\n nUnary >>>= 2;\n }\n return value;\n }\n\n /**\n * parseValue(sValue, sName, fQuiet, nUnary)\n *\n * @this {Debugger}\n * @param {string|undefined} sValue\n * @param {string|null|*} [sName] is the name of the value, if any\n * @param {Array|undefined|boolean} [fQuiet]\n * @param {number} [nUnary] (0 for none, 1 for negate, 2 for complement, 3 for leading zeros)\n * @return {number|undefined} numeric value, or undefined if sValue is either undefined or invalid\n */\n parseValue(sValue, sName, fQuiet, nUnary = 0)\n {\n var value;\n var aUndefined = Array.isArray(fQuiet)? fQuiet : undefined;\n\n if (sValue != null) {\n var iReg = this.getRegIndex(sValue);\n if (iReg >= 0) {\n value = this.getRegValue(iReg);\n } else {\n value = this.getVariable(sValue);\n if (value != null) {\n var sUndefined = this.getVariableFixup(sValue);\n if (sUndefined) {\n if (aUndefined) {\n aUndefined.push(sUndefined);\n } else {\n var valueUndefined = this.parseExpression(sUndefined, fQuiet);\n if (valueUndefined !== undefined) {\n value += valueUndefined;\n } else {\n if (!fQuiet) {\n this.println(\"undefined \" + (sName || \"value\") + \": \" + sValue + \" (\" + sUndefined + \")\");\n }\n value = undefined;\n }\n }\n }\n } else {\n /*\n * A feature of MACRO-10 is that any single-digit number is automatically interpreted as base-10.\n */\n value = Str.parseInt(sValue, sValue.length > 1 || this.nBase > 10? this.nBase : 10);\n }\n }\n if (value != null) {\n value = this.truncate(this.parseUnary(value, nUnary));\n } else {\n if (!fQuiet) {\n this.println(\"invalid \" + (sName || \"value\") + \": \" + sValue);\n }\n }\n } else {\n if (!fQuiet) {\n this.println(\"missing \" + (sName || \"value\"));\n }\n }\n return value;\n }\n\n /**\n * printValue(sVar, value)\n *\n * @this {Debugger}\n * @param {string|null} sVar\n * @param {number|undefined} value\n * @return {boolean} true if value defined, false if not\n */\n printValue(sVar, value)\n {\n var sValue;\n var fDefined = false;\n if (value !== undefined) {\n fDefined = true;\n if (this.nBase == 8) {\n sValue = this.toStrBase(value, this.nBits, 8, 1) + \" \" + value + '.';\n } else {\n sValue = this.toStrBase(value, this.nBits, 16, 1) + \" \" + this.toStrBase(value, this.nBits, 8, 1) + \" \" + this.toStrBase(value, this.nBits, 2, this.nBits <= 32? 8 : 6) + \" \" + value + '.';\n }\n if (value >= 0x20 && value < 0x7F) {\n sValue += \" '\" + String.fromCharCode(value) + \"'\";\n }\n }\n sVar = (sVar != null? (sVar + \": \") : \"\");\n this.println(sVar + sValue);\n return fDefined;\n }\n\n /**\n * resetVariables()\n *\n * @this {Debugger}\n * @return {Object}\n */\n resetVariables()\n {\n var a = this.aVariables;\n this.aVariables = {};\n return a;\n }\n\n /**\n * restoreVariables(a)\n *\n * @this {Debugger}\n * @param {Object} a (from previous resetVariables() call)\n */\n restoreVariables(a)\n {\n this.aVariables = a;\n }\n\n /**\n * printVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} [sVar]\n * @return {boolean} true if all value(s) defined, false if not\n */\n printVariable(sVar)\n {\n var cVariables = 0;\n if (this.aVariables) {\n if (sVar) {\n return this.printValue(sVar, this.aVariables[sVar] && this.aVariables[sVar].value);\n }\n var aVars = Object.keys(this.aVariables);\n aVars.sort();\n for (var i = 0; i < aVars.length; i++) {\n this.printValue(aVars[i], this.aVariables[aVars[i]].value);\n cVariables++;\n }\n }\n return cVariables > 0;\n }\n\n /**\n * delVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n */\n delVariable(sVar)\n {\n delete this.aVariables[sVar];\n }\n\n /**\n * getVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {number|undefined}\n */\n getVariable(sVar)\n {\n if (this.aVariables[sVar]) {\n return this.aVariables[sVar].value;\n }\n sVar = sVar.substr(0, 6);\n return this.aVariables[sVar] && this.aVariables[sVar].value;\n }\n\n /**\n * getVariableFixup(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {string|undefined}\n */\n getVariableFixup(sVar)\n {\n return this.aVariables[sVar] && this.aVariables[sVar].sUndefined;\n }\n\n /**\n * isVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {boolean}\n */\n isVariable(sVar)\n {\n return this.aVariables[sVar] !== undefined;\n }\n\n /**\n * setVariable(sVar, value, sUndefined)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @param {number} value\n * @param {string|undefined} [sUndefined]\n */\n setVariable(sVar, value, sUndefined)\n {\n this.aVariables[sVar] = {value, sUndefined};\n }\n\n /**\n * toStrBase(n, nBits, nBase, nGrouping)\n *\n * Use this instead of Str's toOct()/toDec()/toHex() to convert numbers to the Debugger's default base.\n *\n * @this {Debugger}\n * @param {number|null|undefined} n\n * @param {number} [nBits] (-1 to strip leading zeros, 0 to allow a variable number of digits)\n * @param {number} [nBase]\n * @param {number} [nGrouping] (if nBase is 2, this is a grouping; otherwise, it's a prefix condition)\n * @return {string}\n */\n toStrBase(n, nBits = 0, nBase = 0, nGrouping = 0)\n {\n var s;\n switch(nBase || this.nBase) {\n case 2:\n s = Str.toBin(n, nBits > 0? nBits : 0, nGrouping);\n break;\n case 8:\n s = Str.toOct(n, nBits > 0? ((nBits + 2)/3)|0 : 0, !!nGrouping);\n break;\n case 10:\n /*\n * The multiplier is actually Math.log(2)/Math.log(10), but an approximation is more than adequate.\n */\n s = Str.toDec(n, nBits > 0? Math.ceil(nBits * 0.3) : 0);\n break;\n case 16:\n default:\n s = Str.toHex(n, nBits > 0? ((nBits + 3) >> 2) : 0, !!nGrouping);\n break;\n }\n return (nBits < 0? Str.stripLeadingZeros(s) : s);\n }\n}\n\nif (DEBUGGER) {\n\n /*\n * These are our operator precedence tables. Operators toward the bottom (with higher values) have\n * higher precedence. aBinOpPrecedence was our original table; we had to add aDECOpPrecedence because\n * the precedence of operators in DEC's MACRO-10 expressions differ. Having separate tables also allows\n * us to remove operators that shouldn't be supported, but unless some operator creates a problem,\n * I prefer to keep as much commonality between the tables as possible.\n *\n * Missing from these tables are the (limited) set of unary operators we support (negate and complement),\n * since this is only a BINARY operator precedence, not a general-purpose precedence table. Assume that\n * all unary operators take precedence over all binary operators.\n */\n Debugger.aBinOpPrecedence = {\n '||': 5, // logical OR\n '&&': 6, // logical AND\n '!': 7, // bitwise OR (conflicts with logical NOT, but we never supported that)\n '|': 7, // bitwise OR\n '^!': 8, // bitwise XOR (added by MACRO-10 sometime between the 1972 and 1978 versions)\n '&': 9, // bitwise AND\n '!=': 10, // inequality\n '==': 10, // equality\n '>=': 11, // greater than or equal to\n '>': 11, // greater than\n '<=': 11, // less than or equal to\n '<': 11, // less than\n '>>>': 12, // unsigned bitwise right shift\n '>>': 12, // bitwise right shift\n '<<': 12, // bitwise left shift\n '-': 13, // subtraction\n '+': 13, // addition\n '^/': 14, // remainder\n '/': 14, // division\n '*': 14, // multiplication\n '_': 19, // MACRO-10 shift operator\n '^_': 19, // MACRO-10 internal shift operator (converted from 'B' suffix form that MACRO-10 uses)\n '{': 20, // open grouped expression (converted from achGroup[0])\n '}': 20 // close grouped expression (converted from achGroup[1])\n };\n Debugger.aDECOpPrecedence = {\n ',,': 1, // high-word,,low-word\n '||': 5, // logical OR\n '&&': 6, // logical AND\n '!=': 10, // inequality\n '==': 10, // equality\n '>=': 11, // greater than or equal to\n '>': 11, // greater than\n '<=': 11, // less than or equal to\n '<': 11, // less than\n '>>>': 12, // unsigned bitwise right shift\n '>>': 12, // bitwise right shift\n '<<': 12, // bitwise left shift\n '-': 13, // subtraction\n '+': 13, // addition\n '^/': 14, // remainder\n '/': 14, // division\n '*': 14, // multiplication\n '!': 15, // bitwise OR (conflicts with logical NOT, but we never supported that)\n '|': 15, // bitwise OR\n '^!': 15, // bitwise XOR (added by MACRO-10 sometime between the 1972 and 1978 versions)\n '&': 15, // bitwise AND\n '_': 19, // MACRO-10 shift operator\n '^_': 19, // MACRO-10 internal shift operator (converted from 'B' suffix form that MACRO-10 uses)\n '{': 20, // open grouped expression (converted from achGroup[0])\n '}': 20 // close grouped expression (converted from achGroup[1])\n };\n\n /*\n * Assorted constants\n */\n Debugger.TWO_POW32 = Math.pow(2, 32);\n\n} // endif DEBUGGER\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/debugger.js (C) Jeff Parsons 2012-2018\n */\n\nif (DEBUGGER) {\n}\n\n/**\n * Debugger Address Object\n *\n * off offset, if any\n * sel selector, if any (if null, addr should be set to a linear address)\n * addr linear address, if any (if null, addr will be recomputed from sel:off)\n * type one of the DebuggerX86.ADDRTYPE values\n * fData32 true if 32-bit operand size in effect\n * fAddr32 true if 32-bit address size in effect\n * fData32Orig original fData32 value, if any\n * fAddr32Orig original fAddr32 value, if any\n * cOverrides non-zero if any overrides were processed with this address\n * fComplete true if a complete instruction was processed with this address\n * fTempBreak true if this is a temporary breakpoint address\n * sCmd set for breakpoint addresses if there's an associated command string\n * aCmds preprocessed commands (from sCmd)\n *\n * @typedef {{\n * off:(number|null|undefined),\n * sel:(number|null|undefined),\n * addr:(number|null|undefined),\n * type:(number|undefined),\n * fData32:(boolean|undefined),\n * fAddr32:(boolean|undefined),\n * fData32Orig:(boolean|undefined),\n * fAddr32Orig:(boolean|undefined),\n * cOverrides:(number|undefined),\n * fComplete:(boolean|undefined),\n * fTempBreak:(boolean|undefined),\n * sCmd:(string|undefined),\n * aCmds:(Array.<string>|undefined)\n * }} DbgAddrX86\n */\nvar DbgAddrX86;\n\n/*\n * Debugger Breakpoint Tips\n *\n * Here's an example of our powerful new breakpoint command capabilities:\n *\n * bp 0397:022B \"?'GlobalAlloc(wFlags:[ss:sp+8],dwBytes:[ss:sp+6][ss:sp+4])';g [ss:sp+2]:[ss:sp] '?ax;if ax'\"\n *\n * The above breakpoint will display a pleasing \"GlobalAlloc()\" string containing the current\n * stack parameters, and will briefly stop execution on the return to print the result in AX,\n * halting the CPU whenever AX is zero (the default behavior of \"if\" whenever the expression is\n * false is to look for an \"else\" and automatically halt when there is no \"else\").\n *\n * How do you figure out where the code for GlobalAlloc is in the first place? You need to have\n * BACKTRACK support enabled (which currently means running the non-COMPILED version), so that as\n * the Disk component loads disk images, it will automatically extract symbolic information from all\n * \"NE\" (New Executable) binaries on those disks, which the Debugger's \"dt\" command can then search\n * for you; eg:\n *\n * ## dt globalalloc\n * GLOBALALLOC: KRNL386.EXE 0001:022B len 0xC570\n *\n * And then you just need to do a bit more sleuthing to find the right CODE segment. And that just\n * got easier, now that the PCx86 Debugger mimics portions of the Windows Debugger INT 0x41 interface;\n * see intWindowsDebugger() for details. So even if you neglect to run WDEB386.EXE /E inside the\n * machine before running Windows, you should still see notifications like:\n *\n * KERNEL!undefined code(0001)=#0397 len 0000C580\n *\n * in the PCx86 Debugger output window, as segments are being loaded by the Windows kernel.\n */\n\n/**\n * class DebuggerX86\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass DebuggerX86 extends Debugger {\n /**\n * DebuggerX86(parmsDbg)\n *\n * The DebuggerX86 component is an optional component that implements a variety of user commands\n * for controlling the CPU, dumping and editing memory, etc.\n *\n * DebuggerX86 extends the shared Debugger component and supports the following optional (parmsDbg)\n * properties:\n *\n * commands: string containing zero or more commands, separated by ';'\n *\n * messages: string containing zero or more message categories to enable;\n * multiple categories must be separated by '|' or ';'. Parsed by messageInit().\n *\n * @this {DebuggerX86}\n * @param {Object} parmsDbg\n */\n constructor(parmsDbg)\n {\n if (DEBUGGER) {\n\n super(parmsDbg);\n\n /*\n * Default number of hex chars in a register and a linear address (ie, for real-mode);\n * updated by initBus().\n */\n this.cchReg = 4;\n this.cchAddr = 5;\n this.maskAddr = 0xfffff;\n\n /*\n * Most commands that require an address call parseAddr(), which defaults to dbgAddrNextCode\n * or dbgAddrNextData when no address has been given. doDump() and doUnassemble(), in turn,\n * update dbgAddrNextData and dbgAddrNextCode, respectively, when they're done.\n *\n * All dbgAddr variables contain properties off, sel, and addr, where sel:off represents the\n * segmented address and addr is the corresponding linear address (if known). For certain\n * segmented addresses (eg, breakpoint addresses), we pre-compute the linear address and save\n * that in addr, so that the breakpoint will still operate as intended even if the mode changes\n * later (eg, from real-mode to protected-mode).\n *\n * Finally, for TEMPORARY breakpoint addresses, we set fTempBreak to true, so that they can be\n * automatically cleared when they're hit.\n */\n this.dbgAddrNextCode = this.newAddr(0, 0);\n this.dbgAddrNextData = this.newAddr(0, 0);\n this.dbgAddrAssemble = this.newAddr(0, 0);\n\n /*\n * aSymbolTable is an array of SymbolTable objects, one per ROM or other chunk of address space,\n * where each object contains the following properties:\n *\n * sModule\n * nSegment\n * sel\n * off\n * addr (physical address, if any; eg, symbols for a ROM)\n * len\n * aSymbols\n * aOffsets\n *\n * See addSymbols() for more details, since that's how callers add sets of symbols to the table.\n */\n this.aSymbolTable = [];\n\n /*\n * clearBreakpoints() initializes the breakpoints lists: aBreakExec is a list of addresses\n * to halt on whenever attempting to execute an instruction at the corresponding address,\n * and aBreakRead and aBreakWrite are lists of addresses to halt on whenever a read or write,\n * respectively, occurs at the corresponding address.\n *\n * NOTE: Curiously, after upgrading the Google Closure Compiler from v20141215 to v20150609,\n * the resulting compiled code would crash in clearBreakpoints(), because the (renamed) aBreakRead\n * property was already defined. To eliminate whatever was confusing the Closure Compiler, I've\n * explicitly initialized all the properties that clearBreakpoints() (re)initializes.\n */\n this.aBreakExec = this.aBreakRead = this.aBreakWrite = [];\n this.clearBreakpoints();\n\n /*\n * The new \"bn\" command allows you to specify a number of instructions to execute and then stop;\n * \"bn 0\" disables any outstanding count.\n */\n this.nBreakIns = 0;\n\n /*\n * Execution history is allocated by historyInit() whenever checksEnabled() conditions change.\n * Execution history is updated whenever the CPU calls checkInstruction(), which will happen\n * only when checksEnabled() returns true (eg, whenever one or more breakpoints have been set).\n * This ensures that, by default, the CPU runs as fast as possible.\n */\n this.historyInit();\n\n /*\n * Initialize Debugger message and command support\n */\n this.afnDumpers = {};\n this.messageInit(parmsDbg['messages']);\n this.sCommandsInit = parmsDbg['commands'];\n\n /*\n * Make it easier to access Debugger commands from an external REPL, like the WebStorm \"live\" console\n * window; eg:\n *\n * pcx86('r')\n * pcx86('dw 0:0')\n * pcx86('h')\n * ...\n */\n var dbg = this;\n if (window) {\n if (window[PCX86.APPCLASS] === undefined) {\n window[PCX86.APPCLASS] = function(s) { return dbg.doCommands(s); };\n }\n } else {\n if (global[PCX86.APPCLASS] === undefined) {\n global[PCX86.APPCLASS] = function(s) { return dbg.doCommands(s); };\n }\n }\n\n } // endif DEBUGGER\n }\n\n /**\n * initBus(bus, cpu, dbg)\n *\n * @this {DebuggerX86}\n * @param {Computer} cmp\n * @param {Bus} bus\n * @param {CPUX86} cpu\n * @param {DebuggerX86} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.cmp = cmp;\n this.fdc = cmp.getMachineComponent(\"FDC\");\n this.hdc = cmp.getMachineComponent(\"HDC\");\n this.fpu = cmp.getMachineComponent(\"FPU\");\n this.mouse = cmp.getMachineComponent(\"Mouse\");\n if (MAXDEBUG) this.chipset = cmp.getMachineComponent(\"ChipSet\");\n\n /*\n * Re-initialize Debugger message and command support as needed\n */\n var sMessages = cmp.getMachineParm('messages');\n if (sMessages) this.messageInit(sMessages);\n this.sCommandsInit = cmp.getMachineParm('commands') || this.sCommandsInit;\n\n this.cchAddr = bus.getWidth() >> 2;\n this.maskAddr = bus.nBusLimit;\n\n /*\n * Allocate a special segment \"register\", for use whenever a requested selector is not currently loaded\n */\n this.segDebugger = new SegX86(this.cpu, SegX86.ID.DBG, \"DBG\");\n\n this.aaOpDescs = DebuggerX86.aaOpDescs;\n if (this.cpu.model >= X86.MODEL_80186) {\n this.aaOpDescs = DebuggerX86.aaOpDescs.slice();\n this.aaOpDescs[0x0F] = DebuggerX86.aOpDescUndefined;\n if (this.cpu.model >= X86.MODEL_80286) {\n /*\n * TODO: Consider whether the aOpDesc0F table should be split in two: one for 80286-only instructions,\n * and one for both 80286 and 80386. For now, the Debugger is not as strict as the CPUX86 is about\n * the instructions it supports for each type of CPU, in part because an 80286 machine could still be\n * presented with 80386-only code that is simply \"skipped over\" when then CPU doesn't support it.\n *\n * Obviously I'm not being entirely consistent, since I don't disassemble *any* 0x0F opcodes for any\n * pre-80286 CPUs. But at least I'm being up front about it.\n */\n this.aaOpDescs[0x0F] = DebuggerX86.aOpDesc0F;\n if (I386 && this.cpu.model >= X86.MODEL_80386) this.cchReg = 8;\n }\n }\n\n this.messageDump(Messages.BUS, function onDumpBus(asArgs) { dbg.dumpBus(asArgs); });\n this.messageDump(Messages.DESC, function onDumpSel(asArgs) { dbg.dumpSel(asArgs); });\n this.messageDump(Messages.DOS, function onDumpDOS(asArgs) { dbg.dumpDOS(asArgs); });\n this.messageDump(Messages.MEM, function onDumpMem(asArgs) { dbg.dumpMem(asArgs); });\n this.messageDump(Messages.TSS, function onDumpTSS(asArgs) { dbg.dumpTSS(asArgs); });\n\n if (Interrupts.WINDBG.ENABLED || Interrupts.WINDBGRM.ENABLED) {\n this.fWinDbg = null;\n this.cTrapFaults = 0;\n this.fIgnoreNextCheckFault = false;\n this.cpu.addIntNotify(Interrupts.WINCB.VECTOR, this.intWindowsCallBack.bind(this));\n this.cpu.addIntNotify(Interrupts.WINDBG.VECTOR, this.intWindowsDebugger.bind(this));\n }\n if (Interrupts.WINDBGRM.ENABLED) {\n this.fWinDbgRM = null;\n this.cpu.addIntNotify(Interrupts.WINDBGRM.VECTOR, this.intWindowsDebuggerRM.bind(this));\n }\n\n this.setReady();\n }\n\n /**\n * addSegmentInfo(dbgAddr, nSegment, sel, fCode, fPrint)\n *\n * CONDITIONAL: if (Interrupts.WINDBG.ENABLED || Interrupts.WINDBGRM.ENABLED)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr (address of module name)\n * @param {number} nSegment (logical segment number)\n * @param {number} sel (current selector)\n * @param {boolean} fCode (true if code segment, false if data segment)\n * @param {boolean} [fPrint] (false means we're merely monitoring, so let WDEB386 print its own notifications)\n */\n addSegmentInfo(dbgAddr, nSegment, sel, fCode, fPrint)\n {\n var sModule = this.getSZ(dbgAddr);\n var seg = this.getSegment(sel);\n var len = seg? seg.limit + 1 : 0;\n var sSection = (fCode? \"_CODE\" : \"_DATA\") + Str.toHex(nSegment, 2);\n if (fPrint && this.messageEnabled(Messages.MEM)) {\n this.message(sModule + ' ' + (fCode? \"code\" : \"data\") + '(' + Str.toHex(nSegment, 4) + \")=#\" + Str.toHex(sel, 4) + \" len \" + Str.toHex(len));\n }\n var off = 0;\n var aSymbols = this.findModuleInfo(sModule, nSegment);\n aSymbols[sModule + sSection] = off;\n this.addSymbols(sModule, nSegment, sel, off, null, len, aSymbols);\n }\n\n /**\n * removeSegmentInfo(sel, fPrint)\n *\n * CONDITIONAL: if (Interrupts.WINDBG.ENABLED || Interrupts.WINDBGRM.ENABLED)\n *\n * @this {DebuggerX86}\n * @param {number} sel\n * @param {boolean} [fPrint] (false means we're merely monitoring OR we don't really care about these notifications)\n */\n removeSegmentInfo(sel, fPrint)\n {\n var sModuleRemoved = this.removeSymbols(null, sel);\n if (fPrint && this.messageEnabled(Messages.MEM)) {\n if (sModuleRemoved) {\n this.message(sModuleRemoved + \" #\" + Str.toHex(sel, 4) + \" removed\");\n } else {\n this.message(\"unable to remove module for segment #\" + Str.toHex(sel, 4));\n }\n }\n }\n\n /**\n * addSectionInfo(dbgAddr, fCode, fPrint)\n *\n * CONDITIONAL: if (Interrupts.WINDBG.ENABLED || Interrupts.WINDBGRM.ENABLED)\n *\n * dbgAddr -> D386_Device_Params structure:\n * DD_logical_seg dw ? ; logical segment # from map\n * DD_actual_sel dw ? ; actual selector value\n * DD_base dd ? ; linear address offset for start of segment\n * DD_length dd ? ; actual length of segment\n * DD_name df ? ; 16:32 ptr to null terminated module name\n * DD_sym_name df ? ; 16:32 ptr to null terminated parent name (eg, \"DOS386\")\n * DD_alias_sel dw ? ; alias selector value (0 = none)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr (address of D386_Device_Params)\n * @param {boolean} fCode (true if code section, false if data section)\n * @param {boolean} [fPrint] (false means we're merely monitoring, so let WDEB386 print its own notifications)\n */\n addSectionInfo(dbgAddr, fCode, fPrint)\n {\n var nSegment = this.getShort(dbgAddr, 2);\n var sel = this.getShort(dbgAddr, 2);\n var off = this.getLong(dbgAddr, 4);\n var len = this.getLong(dbgAddr, 4);\n var dbgAddrModule = this.newAddr(this.getLong(dbgAddr, 4), this.getShort(dbgAddr, 2));\n var dbgAddrParent = this.newAddr(this.getLong(dbgAddr, 4), this.getShort(dbgAddr, 2));\n // sel = this.getShort(dbgAddr, 2) || sel;\n var sParent = this.getSZ(dbgAddrParent).toUpperCase();\n var sModule = this.getSZ(dbgAddrModule).toUpperCase();\n if (sParent == sModule) {\n sParent = \"\";\n } else {\n sParent += '!';\n }\n var sSection = (fCode? \"_CODE\" : \"_DATA\") + Str.toHex(nSegment, 2);\n if (fPrint && this.messageEnabled(Messages.MEM)) {\n /*\n * Mimics WDEB386 output, except that WDEB386 only displays a linear address, omitting the selector.\n */\n this.message(sParent + sModule + ' ' + (fCode? \"code\" : \"data\") + '(' + Str.toHex(nSegment, 4) + \")=\" + Str.toHex(sel, 4) + ':' + Str.toHex(off) + \" len \" + Str.toHex(len));\n }\n /*\n * TODO: Add support for 32-bit symbols; findModuleInfo() relies on Disk.getModuleInfo(), and the Disk\n * component doesn't yet know how to parse 32-bit executables.\n */\n var aSymbols = this.findModuleInfo(sModule, nSegment);\n aSymbols[sModule + sSection] = off;\n this.addSymbols(sModule, nSegment, sel, off, null, len, aSymbols);\n }\n\n /**\n * removeSectionInfo(nSegment, dbgAddr, fPrint)\n *\n * CONDITIONAL: if (Interrupts.WINDBG.ENABLED || Interrupts.WINDBGRM.ENABLED)\n *\n * @this {DebuggerX86}\n * @param {number} nSegment (logical segment number)\n * @param {DbgAddrX86} dbgAddr (address of module)\n * @param {boolean} [fPrint] (false means we're merely monitoring OR we don't really care about these notifications)\n */\n removeSectionInfo(nSegment, dbgAddr, fPrint)\n {\n var sModule = this.getSZ(dbgAddr).toUpperCase();\n var sModuleRemoved = this.removeSymbols(sModule, nSegment);\n if (fPrint && this.messageEnabled(Messages.MEM)) {\n if (sModuleRemoved) {\n this.message(sModule + ' ' + Str.toHex(nSegment, 4) + \" removed\");\n } else {\n this.message(\"unable to remove \" + sModule + \" for section \" + Str.toHex(nSegment, 4));\n }\n }\n }\n\n /**\n * intWindowsCallBack()\n *\n * CONDITIONAL: if (Interrupts.WINDBG.ENABLED || Interrupts.WINDBGRM.ENABLED)\n *\n * This intercepts calls to Windows callback addresses, which use INT 0x30 (aka Transfer Space Faults).\n *\n * We're only interested in one particular callback: the VW32_Int41Dispatch (0x002A002A) that KERNEL32\n * issues as 32-bit executable sections are loaded.\n *\n * At the time that INT 0x30 occurs, a far 32-bit call has been made, preceded by a near 32-bit call,\n * preceded by a 32-bit push of the Windows Debugger function # that would normally be in EAX if this had\n * been an actual INT 0x41.\n *\n * NOTE: Regardless whether we're \"handling\" INT 0x41 or merely \"monitoring\" INT 0x41, as far as THIS\n * interrupt is concerned, we always let the system process it, because execution never continues at the\n * instruction following an INT 0x30; in fact, execution doesn't even continue after the far 32-bit call\n * (even though the kernel places a \"RET 4\" after that call). So, rather than recreate all that automatic\n * address popping, we let the system do it for us, since it's designed to work whether a debugger (eg,\n * WDEB386's DEBUG VxD) is installed or not.\n *\n * TODO: Consider \"consuming\" all VW32_Int41Dispatch callbacks, because the Windows 95 kernel goes to\n * great effort to pass those requests on to the DEBUG VxD, which end up going nowhere when the VxD isn't\n * loaded (to load it, you must either run WDEB386.EXE or install the VxD via SYSTEM.INI). Regrettably,\n * Windows 95 assumes that if WDEB386 support is present, then a DEBUG VxD must be present as well.\n *\n * @this {DebuggerX86}\n * @param {number} addr\n * @return {boolean} true to proceed with the INT 0x30 software interrupt\n */\n intWindowsCallBack(addr)\n {\n var cpu = this.cpu;\n\n if (this.fWinDbg != null && cpu.regEAX == 0x002A002A) {\n\n var DX = cpu.regEDX & 0xffff;\n var SI = cpu.regESI & 0xffff;\n var dbgAddr = this.newAddr(cpu.getSP() + 0x0C, cpu.getSS());\n var EAX = this.getLong(dbgAddr);\n\n switch(EAX) {\n case Interrupts.WINDBG.LOADSEG32:\n /*\n * SI == segment type:\n * 0x0 code selector\n * 0x1 data selector\n * DX:EBX -> D386_Device_Params structure (see addSectionInfo() for details)\n */\n this.addSectionInfo(this.newAddr(cpu.regEBX, DX), !SI, !!this.fWinDbg);\n break;\n }\n }\n return true;\n }\n\n /**\n * intWindowsDebugger()\n *\n * CONDITIONAL: if (Interrupts.WINDBG.ENABLED || Interrupts.WINDBGRM.ENABLED)\n *\n * This intercepts calls to the Windows Debugger protected-mode interface (INT 0x41).\n *\n * It's enabled if Interrupts.WINDBG.ENABLED is true, but it must ALSO be enabled if\n * Interrupts.WINDBGRM.ENABLED is true, because if the latter decides to respond to requests,\n * then we must start responding, too. Windows assumes that if INT 0x68 support is present,\n * then INT 0x41 support must be present as well.\n *\n * That is why intWindowsDebuggerRM() will also set this.fWinDbg to true: we MUST return false\n * for all INT 0x41 requests, so that all requests are consumed, since there's no guarantee\n * that a valid INT 0x41 handler will exist inside the machine.\n *\n * @this {DebuggerX86}\n * @param {number} addr\n * @return {boolean} true to proceed with the INT 0x41 software interrupt, false to skip\n */\n intWindowsDebugger(addr)\n {\n var dbgAddr;\n var cpu = this.cpu;\n var AX = cpu.regEAX & 0xffff;\n var BX = cpu.regEBX & 0xffff;\n var CX = cpu.regECX & 0xffff;\n var DX = cpu.regEDX & 0xffff;\n var SI = cpu.regESI & 0xffff;\n var DI = cpu.regEDI & 0xffff;\n var ES = cpu.segES.sel;\n\n if (this.fWinDbg == null) {\n if (AX == Interrupts.WINDBG.IS_LOADED) {\n /*\n * We're only going to respond to this function if no one else did, in which case,\n * we'll set fWinDbg to true and handle additional notifications.\n */\n cpu.addIntReturn(addr, function(dbg) {\n return function onInt41Return(nLevel) {\n if ((cpu.regEAX & 0xffff) != Interrupts.WINDBG.LOADED) {\n cpu.regEAX = (cpu.regEAX & ~0xffff) | Interrupts.WINDBG.LOADED;\n /*\n * TODO: We need a DEBUGGER message category; using the MEM category for now.\n */\n dbg.printMessage(\"INT 0x41 handling enabled\", Messages.MEM);\n dbg.fWinDbg = true;\n } else {\n dbg.printMessage(\"INT 0x41 monitoring enabled\", Messages.MEM);\n dbg.fWinDbg = false;\n }\n };\n }(this));\n }\n return true;\n }\n\n /*\n * NOTE: If this.fWinDbg is true, then all cases should return false, because we're taking full\n * responsibility for all requests (don't assume there's valid interrupt handler inside the machine).\n */\n switch(AX) {\n case Interrupts.WINDBG.IS_LOADED: // 0x004F\n if (this.fWinDbg) {\n cpu.regEAX = (cpu.regEAX & ~0xffff) | Interrupts.WINDBG.LOADED;\n this.printMessage(\"INT 0x41 handling enabled\", Messages.MEM);\n }\n break;\n\n case Interrupts.WINDBG.LOADSEG: // 0x0050\n this.addSegmentInfo(this.newAddr(DI, ES), BX+1, CX, !(SI & 0x1), !!this.fWinDbg);\n break;\n\n case Interrupts.WINDBG.FREESEG: // 0x0052\n this.removeSegmentInfo(BX);\n break;\n\n case Interrupts.WINDBG.KRNLVARS: // 0x005A\n /*\n * BX = version number of this data (0x3A0)\n * DX:CX points to:\n * WORD hGlobalHeap ****\n * WORD pGlobalHeap ****\n * WORD hExeHead ****\n * WORD hExeSweep\n * WORD topPDB\n * WORD headPDB\n * WORD topsizePDB\n * WORD headTDB ****\n * WORD curTDB ****\n * WORD loadTDB\n * WORD LockTDB\n * WORD SelTableLen ****\n * DWORD SelTableStart ****\n */\n break;\n\n case Interrupts.WINDBG.RELSEG: // 0x005C\n case Interrupts.WINDBG.EXITCALL: // 0x0062\n case Interrupts.WINDBG.LOADDLL: // 0x0064\n case Interrupts.WINDBG.DELMODULE: // 0x0065\n case Interrupts.WINDBG.UNKNOWN66: // 0x0066\n case Interrupts.WINDBG.UNKNOWN67: // 0x0067\n /*\n * TODO: Figure out what to do with these notifications, if anything\n */\n break;\n\n case Interrupts.WINDBG.LOADHIGH: // 0x005D\n case Interrupts.WINDBG.REGDOTCMD: // 0x0070\n case Interrupts.WINDBG.CONDBP: // 0xF001\n break;\n\n case Interrupts.WINDBG.CHECKFAULT: // 0x007F\n if (this.fWinDbg) {\n /*\n * AX == 0 means handle fault normally, 1 means issue TRAPFAULT\n */\n cpu.regEAX = (cpu.regEAX & ~0xffff) | (this.fIgnoreNextCheckFault? 0 : 1);\n if (DEBUG) this.println(\"INT 0x41 CHECKFAULT: fault=\" + Str.toHexWord(BX) + \" type=\" + Str.toHexWord(CX) + \" trap=\" + !this.fIgnoreNextCheckFault);\n }\n break;\n\n case Interrupts.WINDBG.TRAPFAULT: // 0x0083\n /*\n * If we responded with AX == 1 to a preceding CHECKFAULT notification, then we should receive the\n * following TRAPFAULT notification; additionally, a TRAPFAULT notification may be issued without\n * any CHECKFAULT warning if the user was presented with a fault dialog containing a \"Debug\" button,\n * and the user clicked it.\n *\n * Regardless, whenever we receive this notification, we allocate a temporary breakpoint at the\n * reported fault address.\n */\n if (this.fWinDbg) {\n dbgAddr = this.newAddr(cpu.regEDX, CX);\n if (!this.cTrapFaults++) {\n this.println(\"INT 0x41 TRAPFAULT: fault=\" + Str.toHexWord(BX) + \" error=\" + Str.toHexLong(cpu.regESI) + \" addr=\" + this.toHexAddr(dbgAddr));\n this.addBreakpoint(this.aBreakExec, dbgAddr, true);\n this.historyInit(true); // temporary breakpoints don't normally trigger history, but in this case, we want it to\n } else {\n this.println(\"TRAPFAULT failed\");\n this.findBreakpoint(this.aBreakExec, dbgAddr, true, true, true);\n this.cTrapFaults = 0;\n this.stopCPU();\n }\n }\n break;\n\n case Interrupts.WINDBG.GETSYMBOL: // 0x008D\n if (this.fWinDbg) cpu.regEAX = (cpu.regEAX & ~0xffff)|1; // AX == 1 means not found\n break;\n\n case Interrupts.WINDBG.LOADSEG32: // 0x0150\n /*\n * SI == segment type:\n * 0x0 code selector\n * 0x1 data selector\n * DX:EBX -> D386_Device_Params structure (see addSectionInfo() for details)\n */\n this.addSectionInfo(this.newAddr(cpu.regEBX, DX), !SI, !!this.fWinDbg);\n break;\n\n case Interrupts.WINDBG.FREESEG32: // 0x0152\n /*\n * BX == segment number\n * DX:EDI -> module name\n */\n this.removeSectionInfo(BX, this.newAddr(cpu.regEDI, DX));\n break;\n\n default:\n if (DEBUG && this.fWinDbg) {\n this.println(\"INT 0x41: \" + Str.toHexWord(AX));\n }\n break;\n }\n\n /*\n * Let's try to limit the scope of any \"gt\" command by resetting this flag after any INT 0x41\n */\n this.fIgnoreNextCheckFault = false;\n\n return !this.fWinDbg;\n }\n\n /**\n * intWindowsDebuggerRM()\n *\n * CONDITIONAL: if (Interrupts.WINDBGRM.ENABLED)\n *\n * This intercepts calls to the Windows Debugger real-mode interface (INT 0x68).\n *\n * @this {DebuggerX86}\n * @param {number} addr\n * @return {boolean} true to proceed with the INT 0x68 software interrupt, false to skip\n */\n intWindowsDebuggerRM(addr)\n {\n var cpu = this.cpu;\n var AL = cpu.regEAX & 0xff;\n var AH = (cpu.regEAX >> 8) & 0xff;\n var BX = cpu.regEBX & 0xffff;\n var CX = cpu.regECX & 0xffff;\n var DX = cpu.regEDX & 0xffff;\n var DI = cpu.regEDI & 0xffff;\n var ES = cpu.segES.sel;\n\n if (this.fWinDbgRM == null) {\n if (AH == Interrupts.WINDBGRM.IS_LOADED) {\n /*\n * It looks like IFSHLP.SYS issues a preliminary INT 0x68 before Windows 95 gets rolling,\n * and the Windows Debugger will not have had a chance to load yet, so we need to ignore\n * that call. We detect IFSHLP.SYS by looking for \"IFS$\" in the caller's code segment,\n * where the IFSHLP device driver header is located.\n */\n if (cpu.getLong((cpu.segCS.sel << 4) + 0x0A) == 0x24534649) {\n if (DEBUG) this.println(\"Ignoring INT 0x68 from IFSHLP.SYS\");\n return true;\n }\n /*\n * Ditto for WDEB386 itself, which presumably wants to avoid loading on top of itself.\n */\n if (cpu.getLong((cpu.segCS.sel << 4) + 0x5F) == 0x42454457) {\n if (DEBUG) this.println(\"Ignoring INT 0x68 from WDEB386.EXE\");\n return true;\n }\n /*\n * We're only going to respond to this function if no one else did, in which case, we'll set\n * fWinDbgRM to true and handle additional notifications.\n */\n cpu.addIntReturn(addr, function(dbg) {\n return function onInt68Return(nLevel) {\n if ((cpu.regEAX & 0xffff) != Interrupts.WINDBGRM.LOADED) {\n cpu.regEAX = (cpu.regEAX & ~0xffff) | Interrupts.WINDBGRM.LOADED;\n dbg.printMessage(\"INT 0x68 handling enabled\", Messages.MEM);\n /*\n * If we turn on INT 0x68 handling, we must also turn on INT 0x41 handling,\n * because Windows assumes that the latter handler exists whenever the former does.\n */\n dbg.fWinDbg = dbg.fWinDbgRM = true;\n } else {\n dbg.printMessage(\"INT 0x68 monitoring enabled\", Messages.MEM);\n dbg.fWinDbgRM = false;\n }\n };\n }(this));\n }\n return true;\n }\n\n /*\n * NOTE: If this.fWinDbgRM is true, then all cases should return false, because we're taking full\n * responsibility for all requests (don't assume there's valid interrupt handler inside the machine).\n */\n switch(AH) {\n case Interrupts.WINDBGRM.IS_LOADED: // 0x43\n if (this.fWinDbgRM) {\n cpu.regEAX = (cpu.regEAX & ~0xffff) | Interrupts.WINDBGRM.LOADED;\n }\n break;\n\n case Interrupts.WINDBGRM.PREP_PMODE: // 0x44\n if (this.fWinDbgRM) {\n /*\n * Use our fancy new \"call break\" mechanism to obtain a special address that will\n * trap all calls, routing control to the specified function (callWindowsDebuggerPMInit).\n */\n var a = cpu.segCS.addCallBreak(this.callWindowsDebuggerPMInit.bind(this));\n if (a) {\n cpu.regEDI = a[0]; // ES:EDI receives the \"call break\" address\n cpu.setES(a[1]);\n }\n }\n break;\n\n case Interrupts.WINDBGRM.FREESEG: // 0x48\n this.removeSegmentInfo(BX);\n break;\n\n case Interrupts.WINDBGRM.REMOVESEGS: // 0x4F\n /*\n * TODO: This probably just signals the end of module loading; nothing is required, but we should\n * clean up whatever we can....\n */\n break;\n\n case Interrupts.WINDBGRM.LOADSEG: // 0x50\n if (AL == 0x20) {\n /*\n * Real-mode EXE\n * CX == paragraph\n * ES:DI -> module name\n */\n this.addSegmentInfo(this.newAddr(DI, ES), 0, CX, true, !!this.fWinDbgRM);\n }\n else if (AL < 0x80) {\n /*\n * AL == segment type:\n * 0x00 code selector\n * 0x01 data selector\n * 0x10 code segment\n * 0x11 data segment\n * 0x40 code segment & sel\n * 0x41 data segment & sel\n * BX == segment #\n * CX == actual segment/selector\n * DX == actual selector (if 0x40 or 0x41)\n * ES:DI -> module name\n */\n this.addSegmentInfo(this.newAddr(DI, ES), BX+1, (AL & 0x40)? DX : CX, !(AL & 0x1), !!this.fWinDbgRM);\n }\n else {\n /*\n * AL == segment type:\n * 0x80 device driver code seg\n * 0x81 device driver data seg\n * ES:DI -> D386_Device_Params structure (see addSectionInfo() for details)\n */\n this.addSectionInfo(this.newAddr(DI, ES), !(AL & 0x1), !!this.fWinDbgRM);\n }\n if (this.fWinDbgRM) {\n cpu.regEAX = (cpu.regEAX & ~0xff) | 0x01;\n }\n break;\n\n default:\n if (DEBUG && this.fWinDbgRM) {\n this.println(\"INT 0x68: \" + Str.toHexByte(AH));\n }\n break;\n }\n\n return !this.fWinDbgRM;\n }\n\n /**\n * callWindowsDebuggerPMInit()\n *\n * CONDITIONAL: if (Interrupts.WINDBGRM.ENABLED)\n *\n * This intercepts calls to the Windows Debugger \"PMInit\" interface; eg:\n *\n * AL = function code\n *\n * 0 - initialize IDT\n * ES:EDI points to protected mode IDT\n *\n * 1 - initialize page checking\n * BX = physical selector\n * ECX = linear bias\n *\n * 2 - specify that debug queries are supported\n *\n * 3 - initialize spare PTE\n * EBX = linear address of spare PTE\n * EDX = linear address the PTE represents\n *\n * 4 - set Enter/Exit VMM routine address\n * EBX = Enter VMM routine address\n * ECX = Exit VMM routine address\n * EDX = $_Debug_Out_Service address\n * ESI = $_Trace_Out_Service address\n * The VMM enter/exit routines must return with a retfd\n *\n * 5 - get debugger size/physical address\n * returns: AL = 0 (don't call AL = 1)\n * ECX = size in bytes\n * ESI = starting physical code/data address\n *\n * 6 - set debugger base/initialize spare PTE\n * EBX = linear address of spare PTE\n * EDX = linear address the PTE represents\n * ESI = starting linear address of debug code/data\n *\n * 7 - enable memory context functions\n *\n * @this {DebuggerX86}\n * @return {boolean} (must always return false to skip the call, because the call is using a CALLBREAK address)\n */\n callWindowsDebuggerPMInit()\n {\n var cpu = this.cpu;\n var AL = cpu.regEAX & 0xff;\n if (MAXDEBUG) this.println(\"INT 0x68 callback: \" + Str.toHexByte(AL));\n if (AL == 5) {\n cpu.regECX = cpu.regESI = 0; // our in-machine debugger footprint is zero\n cpu.regEAX = (cpu.regEAX & ~0xff) | 0x01; // TODO: Returning a \"don't call\" response sounds good, but what does it REALLY mean?\n }\n return false;\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {DebuggerX86}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"debugInput\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var dbg = this;\n switch (sBinding) {\n\n case \"debugInput\":\n this.bindings[sBinding] = control;\n this.controlDebug = /** @type {HTMLInputElement} */ (control);\n /*\n * For halted machines, this is fine, but for auto-start machines, it can be annoying.\n *\n * controlInput.focus();\n */\n control.onkeydown = function onKeyDownDebugInput(event) {\n var sCmd;\n if (event.keyCode == Keys.KEYCODE.CR) {\n sCmd = dbg.controlDebug.value;\n dbg.controlDebug.value = \"\";\n dbg.doCommands(sCmd, true);\n }\n else if (event.keyCode == Keys.KEYCODE.ESC) {\n dbg.controlDebug.value = sCmd = \"\";\n }\n else {\n if (event.keyCode == Keys.KEYCODE.UP) {\n sCmd = dbg.getPrevCommand();\n }\n else if (event.keyCode == Keys.KEYCODE.DOWN) {\n sCmd = dbg.getNextCommand();\n }\n if (sCmd != null) {\n var cch = sCmd.length;\n dbg.controlDebug.value = sCmd;\n dbg.controlDebug.setSelectionRange(cch, cch);\n }\n }\n if (sCmd != null && event.preventDefault) event.preventDefault();\n };\n return true;\n\n case \"debugEnter\":\n this.bindings[sBinding] = control;\n Web.onClickRepeat(\n control,\n 500, 100,\n function onClickDebugEnter(fRepeat) {\n if (dbg.controlDebug) {\n var sCommands = dbg.controlDebug.value;\n dbg.controlDebug.value = \"\";\n dbg.doCommands(sCommands, true);\n return true;\n }\n if (DEBUG) dbg.log(\"no debugger input buffer\");\n return false;\n }\n );\n return true;\n\n case \"step\":\n this.bindings[sBinding] = control;\n Web.onClickRepeat(\n control,\n 500, 100,\n function onClickStep(fRepeat) {\n var fCompleted = false;\n if (!dbg.isBusy(true)) {\n dbg.setBusy(true);\n fCompleted = dbg.stepCPU(fRepeat? 1 : 0);\n dbg.setBusy(false);\n }\n return fCompleted;\n }\n );\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * updateFocus()\n *\n * @this {DebuggerX86}\n */\n updateFocus()\n {\n if (this.controlDebug) this.controlDebug.focus();\n }\n\n /**\n * getCPUMode()\n *\n * @this {DebuggerX86}\n * @return {boolean} (true if protected mode, false if not)\n */\n getCPUMode()\n {\n return !!(this.cpu && (this.cpu.regCR0 & X86.CR0.MSW.PE) && !(this.cpu.regPS & X86.PS.VM));\n }\n\n /**\n * getAddressType()\n *\n * @this {DebuggerX86}\n * @return {number}\n */\n getAddressType()\n {\n return this.getCPUMode()? DebuggerX86.ADDRTYPE.PROT : DebuggerX86.ADDRTYPE.REAL;\n }\n\n /**\n * getSegment(sel, type)\n *\n * If the selector matches that of any of the CPU segment registers, then return the CPU's segment\n * register, instead of using our own segDebugger segment register. This makes it possible for us to\n * see what the CPU is seeing at certain critical junctures, such as after an LMSW instruction has\n * switched the processor from real to protected mode. Actually loading the selector from the GDT/LDT\n * should be done only as a last resort.\n *\n * @this {DebuggerX86}\n * @param {number|null|undefined} sel\n * @param {number} [type] (defaults to getAddressType())\n * @return {SegX86|null} seg\n */\n getSegment(sel, type)\n {\n var typeDefault = this.getAddressType();\n\n if (!type) type = typeDefault;\n\n if (type == typeDefault) {\n if (sel === this.cpu.getCS()) return this.cpu.segCS;\n if (sel === this.cpu.getDS()) return this.cpu.segDS;\n if (sel === this.cpu.getES()) return this.cpu.segES;\n if (sel === this.cpu.getSS()) return this.cpu.segSS;\n if (I386 && this.cpu.model >= X86.MODEL_80386) {\n if (sel === this.cpu.getFS()) return this.cpu.segFS;\n if (sel === this.cpu.getGS()) return this.cpu.segGS;\n }\n /*\n * Even if nSuppressBreaks is set, we'll allow the call in real-mode,\n * because a loadReal() request using segDebugger should generally be safe.\n */\n if (this.nSuppressBreaks && type == DebuggerX86.ADDRTYPE.PROT || !this.segDebugger) return null;\n }\n var seg = this.segDebugger;\n if (type != DebuggerX86.ADDRTYPE.PROT) {\n seg.loadReal(sel);\n seg.limit = 0xffff; // although an ACTUAL real-mode segment load would not modify the limit,\n seg.offMax = 0x10000; // proper segDebugger operation requires that we update the limit ourselves\n } else {\n seg.probeDesc(sel);\n }\n return seg;\n }\n\n /**\n * getAddr(dbgAddr, fWrite, nb)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86|null|undefined} dbgAddr\n * @param {boolean} [fWrite]\n * @param {number} [nb] number of bytes to check (1, 2 or 4); default is 1\n * @return {number} is the corresponding linear address, or X86.ADDR_INVALID\n */\n getAddr(dbgAddr, fWrite, nb)\n {\n /*\n * Some addresses (eg, breakpoint addresses) save their original linear address in dbgAddr.addr,\n * so we want to use that if it's there, but otherwise, dbgAddr is assumed to be a segmented address\n * whose linear address must always be (re)calculated based on current machine state (mode, active\n * descriptor tables, etc).\n */\n var addr = dbgAddr && dbgAddr.addr;\n if (addr == null) {\n addr = X86.ADDR_INVALID;\n if (dbgAddr) {\n /*\n * TODO: We should try to cache the seg inside dbgAddr, to avoid unnecessary calls to getSegment().\n */\n var seg = this.getSegment(dbgAddr.sel, dbgAddr.type);\n if (seg) {\n if (!fWrite) {\n addr = seg.checkReadDebugger(dbgAddr.off || 0, nb || 1);\n } else {\n addr = seg.checkWriteDebugger(dbgAddr.off || 0, nb || 1);\n }\n dbgAddr.addr = addr;\n }\n }\n }\n return addr;\n }\n\n /**\n * getByte(dbgAddr, inc)\n *\n * We must route all our memory requests through the CPU now, in case paging is enabled.\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {number} [inc]\n * @return {number}\n */\n getByte(dbgAddr, inc)\n {\n var b = 0xff;\n var addr = this.getAddr(dbgAddr, false, 1);\n if (addr !== X86.ADDR_INVALID) {\n /*\n * TODO: Determine what we should do about the fact that we're masking any error from probeAddr()\n */\n b = this.cpu.probeAddr(addr, 1, dbgAddr.type == DebuggerX86.ADDRTYPE.PHYSICAL) | 0;\n if (inc) this.incAddr(dbgAddr, inc);\n }\n return b;\n }\n\n /**\n * getWord(dbgAddr, fAdvance)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {boolean} [fAdvance]\n * @return {number}\n */\n getWord(dbgAddr, fAdvance)\n {\n return dbgAddr.fData32? this.getLong(dbgAddr, fAdvance? 4 : 0) : this.getShort(dbgAddr, fAdvance? 2 : 0);\n }\n\n /**\n * getShort(dbgAddr, inc)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {number} [inc]\n * @return {number}\n */\n getShort(dbgAddr, inc)\n {\n var w = 0xffff;\n var addr = this.getAddr(dbgAddr, false, 2);\n if (addr !== X86.ADDR_INVALID) {\n /*\n * TODO: Determine what we should do about the fact that we're masking any error from probeAddr()\n */\n w = this.cpu.probeAddr(addr, 2, dbgAddr.type == DebuggerX86.ADDRTYPE.PHYSICAL) | 0;\n if (inc) this.incAddr(dbgAddr, inc);\n }\n return w;\n }\n\n /**\n * getLong(dbgAddr, inc)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {number} [inc]\n * @return {number}\n */\n getLong(dbgAddr, inc)\n {\n var l = -1;\n var addr = this.getAddr(dbgAddr, false, 4);\n if (addr !== X86.ADDR_INVALID) {\n /*\n * TODO: Determine what we should do about the fact that we're masking any error from probeAddr()\n */\n l = this.cpu.probeAddr(addr, 4, dbgAddr.type == DebuggerX86.ADDRTYPE.PHYSICAL) | 0;\n if (inc) this.incAddr(dbgAddr, inc);\n }\n return l;\n }\n\n /**\n * setByte(dbgAddr, b, inc, fNoUpdate)\n *\n * NOTE: If you need to patch a ROM, you MUST use the ROM location's physical address.\n *\n * WARNING: Be careful with the editing commands that use function, because we don't have a safe\n * counterpart to cpu.probeAddr().\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {number} b\n * @param {number} [inc]\n * @param {boolean} [fNoUpdate] (when doing a large number of setByte() calls, set this to true and call cpu.updateCPU() when you're done)\n */\n setByte(dbgAddr, b, inc, fNoUpdate)\n {\n var addr = this.getAddr(dbgAddr, true, 1);\n if (addr !== X86.ADDR_INVALID) {\n if (dbgAddr.type != DebuggerX86.ADDRTYPE.PHYSICAL) {\n this.cpu.setByte(addr, b);\n } else {\n this.bus.setByteDirect(addr, b);\n }\n if (inc) this.incAddr(dbgAddr, inc);\n if (!fNoUpdate) this.cpu.updateCPU(true); // we set fForce to true in case video memory was the target\n }\n }\n\n /**\n * setShort(dbgAddr, w, inc)\n *\n * NOTE: If you need to patch a ROM, you MUST use the ROM location's physical address.\n *\n * WARNING: Be careful with the editing commands that use function, because we don't have a safe\n * counterpart to cpu.probeAddr().\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {number} w\n * @param {number} [inc]\n */\n setShort(dbgAddr, w, inc)\n {\n var addr = this.getAddr(dbgAddr, true, 2);\n if (addr !== X86.ADDR_INVALID) {\n if (dbgAddr.type != DebuggerX86.ADDRTYPE.PHYSICAL) {\n this.cpu.setShort(addr, w);\n } else {\n this.bus.setShortDirect(addr, w);\n }\n if (inc) this.incAddr(dbgAddr, inc);\n this.cpu.updateCPU(true); // we set fForce to true in case video memory was the target\n }\n }\n\n /**\n * newAddr(off, sel, addr, type, fData32, fAddr32)\n *\n * Returns a NEW DbgAddrX86 object, initialized with specified values and/or defaults.\n *\n * @this {DebuggerX86}\n * @param {number|null|undefined} [off] (default is zero)\n * @param {number|null|undefined} [sel] (default is undefined)\n * @param {number|null|undefined} [addr] (default is undefined)\n * @param {number} [type] (default is based on current CPU mode)\n * @param {boolean} [fData32] (default is the current CPU operand size)\n * @param {boolean} [fAddr32] (default is the current CPU address size)\n * @return {DbgAddrX86}\n */\n newAddr(off, sel, addr, type, fData32, fAddr32)\n {\n return this.setAddr({}, off, sel, addr, type, fData32, fAddr32);\n }\n\n /**\n * getAddrPrefix(dbgAddr)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @return {string}\n */\n getAddrPrefix(dbgAddr)\n {\n var ch;\n\n switch (dbgAddr.type) {\n case DebuggerX86.ADDRTYPE.REAL:\n case DebuggerX86.ADDRTYPE.V86:\n ch = '&';\n break;\n case DebuggerX86.ADDRTYPE.PROT:\n ch = '#';\n break;\n case DebuggerX86.ADDRTYPE.LINEAR:\n ch = '%';\n break;\n case DebuggerX86.ADDRTYPE.PHYSICAL:\n ch = '%%';\n break;\n default:\n ch = dbgAddr.sel? '' : '%';\n break;\n }\n return ch;\n }\n\n /**\n * setAddr(dbgAddr, off, sel, addr, type, fData32, fAddr32)\n *\n * Updates an EXISTING DbgAddrX86 object, initialized with specified values and/or defaults.\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {number|null|undefined} [off] (default is zero)\n * @param {number|null|undefined} [sel] (default is undefined)\n * @param {number|null|undefined} [addr] (default is undefined)\n * @param {number} [type] (default is based on current CPU mode)\n * @param {boolean} [fData32] (default is the current CPU operand size)\n * @param {boolean} [fAddr32] (default is the current CPU address size)\n * @return {DbgAddrX86}\n */\n setAddr(dbgAddr, off, sel, addr, type, fData32, fAddr32)\n {\n dbgAddr.off = off || 0;\n dbgAddr.sel = sel;\n dbgAddr.addr = addr;\n dbgAddr.type = type || this.getAddressType();\n dbgAddr.fData32 = (fData32 != null)? fData32 : !!(this.cpu && this.cpu.segCS.sizeData == 4);\n dbgAddr.fAddr32 = (fAddr32 != null)? fAddr32 : !!(this.cpu && this.cpu.segCS.sizeAddr == 4);\n dbgAddr.fTempBreak = false;\n return dbgAddr;\n }\n\n /**\n * packAddr(dbgAddr)\n *\n * Packs a DbgAddrX86 object into an Array suitable for saving in a machine state object.\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @return {Array}\n */\n packAddr(dbgAddr)\n {\n return [dbgAddr.off, dbgAddr.sel, dbgAddr.addr, dbgAddr.fTempBreak, dbgAddr.fData32, dbgAddr.fAddr32, dbgAddr.cOverrides, dbgAddr.fComplete];\n }\n\n /**\n * unpackAddr(aAddr)\n *\n * Unpacks a DbgAddrX86 object from an Array created by packAddr() and restored from a saved machine state.\n *\n * @this {DebuggerX86}\n * @param {Array} aAddr\n * @return {DbgAddrX86}\n */\n unpackAddr(aAddr)\n {\n return {off: aAddr[0], sel: aAddr[1], addr: aAddr[2], fTempBreak: aAddr[3], fData32: aAddr[4], fAddr32: aAddr[5], cOverrides: aAddr[6], fComplete: aAddr[7]};\n }\n\n /**\n * checkLimit(dbgAddr, fUpdate)\n *\n * Used by incAddr() and parseAddr() to ensure that the (updated) dbgAddr offset is within segment bounds.\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {boolean} [fUpdate] (true to update segment info)\n * @return {boolean}\n */\n checkLimit(dbgAddr, fUpdate)\n {\n if (dbgAddr.sel != null) {\n var seg = this.getSegment(dbgAddr.sel, dbgAddr.type);\n if (seg) {\n var off = dbgAddr.off & seg.maskAddr;\n if (!seg.fExpDown) {\n if ((off >>> 0) >= seg.offMax) {\n return false;\n }\n }\n else {\n if ((off >>> 0) < seg.offMax) {\n return false;\n }\n }\n if (fUpdate) {\n dbgAddr.off = off;\n dbgAddr.fData32 = (seg.sizeData == 4);\n dbgAddr.fAddr32 = (seg.sizeAddr == 4);\n }\n }\n }\n return true;\n }\n\n /**\n * parseAddr(sAddr, fCode, fNoChecks, fQuiet)\n *\n * As discussed above, dbgAddr variables contain one or more of: off, sel, and addr. They represent\n * a segmented address (sel:off) when sel is defined or a linear address (addr) when sel is undefined\n * (or null).\n *\n * To create a segmented address, specify two values separated by ':'; for a linear address, use\n * a '%' prefix. We check for ':' after '%', so if for some strange reason you specify both, the\n * address will be treated as segmented, not linear.\n *\n * The '%' syntax is similar to that used by the Windows 80386 kernel debugger (wdeb386) for linear\n * addresses. If/when we add support for processors with page tables, we will likely adopt the same\n * convention for linear addresses and provide a different syntax (eg, \"%%\") physical memory references.\n *\n * Address evaluation and validation (eg, range checks) are no longer performed at this stage. That's\n * done later, by getAddr(), which returns X86.ADDR_INVALID for invalid segments, out-of-range offsets,\n * etc. The Debugger's low-level get/set memory functions verify all getAddr() results, but even if an\n * invalid address is passed through to the Bus memory interfaces, the address will simply be masked with\n * Bus.nBusLimit; in the case of X86.ADDR_INVALID, that will generally refer to the top of the physical\n * address space.\n *\n * @this {DebuggerX86}\n * @param {string|undefined} sAddr\n * @param {boolean} [fCode] (true if target is code, false if target is data)\n * @param {boolean} [fNoChecks] (true when setting breakpoints that may not be valid now, but will be later)\n * @param {boolean} [fQuiet]\n * @return {DbgAddrX86|null|undefined}\n */\n parseAddr(sAddr, fCode, fNoChecks, fQuiet)\n {\n var dbgAddr;\n var dbgAddrNext = (fCode? this.dbgAddrNextCode : this.dbgAddrNextData);\n\n var type = fNoChecks? DebuggerX86.ADDRTYPE.NONE : dbgAddrNext.type;\n var off = dbgAddrNext.off, sel = dbgAddrNext.sel, addr = dbgAddrNext.addr;\n\n if (sAddr !== undefined) {\n\n sAddr = this.parseReference(sAddr);\n\n var ch = sAddr.charAt(0);\n var iColon = sAddr.indexOf(':');\n\n switch(ch) {\n case '&':\n type = DebuggerX86.ADDRTYPE.REAL;\n break;\n case '#':\n type = DebuggerX86.ADDRTYPE.PROT;\n break;\n case '%':\n type = DebuggerX86.ADDRTYPE.LINEAR;\n ch = sAddr.charAt(1);\n if (ch == '%') {\n type = DebuggerX86.ADDRTYPE.PHYSICAL;\n ch += ch;\n }\n off = addr = 0;\n sel = null; // we still have code that relies on this crutch, instead of the type field\n break;\n default:\n if (iColon >= 0) type = DebuggerX86.ADDRTYPE.NONE;\n ch = '';\n break;\n }\n\n if (ch) {\n sAddr = sAddr.substr(ch.length);\n iColon -= ch.length;\n }\n\n dbgAddr = this.findSymbolAddr(sAddr);\n if (dbgAddr) return dbgAddr;\n\n if (iColon < 0) {\n if (sel != null) {\n off = this.parseExpression(sAddr, fQuiet);\n addr = null;\n } else {\n addr = this.parseExpression(sAddr, fQuiet);\n if (addr == null) off = null;\n }\n }\n else {\n sel = this.parseExpression(sAddr.substring(0, iColon), fQuiet);\n off = this.parseExpression(sAddr.substring(iColon + 1), fQuiet);\n addr = null;\n }\n }\n\n if (off != null) {\n dbgAddr = this.newAddr(off, sel, addr, type);\n if (!fNoChecks && !this.checkLimit(dbgAddr, true)) {\n this.println(\"invalid offset: \" + this.toHexAddr(dbgAddr));\n dbgAddr = null;\n }\n }\n return dbgAddr;\n }\n\n /**\n * parseAddrOptions(dbgAddr, sOptions)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {string} [sOptions]\n */\n parseAddrOptions(dbgAddr, sOptions)\n {\n if (sOptions) {\n var a = sOptions.match(/(['\"])(.*?)\\1/);\n if (a) {\n dbgAddr.aCmds = this.parseCommand(dbgAddr.sCmd = a[2]);\n }\n }\n }\n\n /**\n * parseAddrReference(s, sAddr)\n *\n * Returns the given string with the given address references replaced with the contents of the address.\n *\n * @this {Debugger}\n * @param {string} s\n * @param {string} sAddr\n * @return {string}\n */\n parseAddrReference(s, sAddr)\n {\n var dbgAddr = this.parseAddr(sAddr);\n return s.replace('[' + sAddr + ']', dbgAddr? Str.toHex(this.getWord(dbgAddr), dbgAddr.fData32? 8 : 4) : \"undefined\");\n }\n\n /**\n * incAddr(dbgAddr, inc)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {number} [inc] contains value to increment dbgAddr by (default is 1)\n */\n incAddr(dbgAddr, inc)\n {\n inc = inc || 1;\n if (dbgAddr.addr != null) {\n dbgAddr.addr += inc;\n }\n if (dbgAddr.sel != null) {\n dbgAddr.off += inc;\n if (!this.checkLimit(dbgAddr)) {\n dbgAddr.off = 0;\n dbgAddr.addr = null;\n }\n }\n }\n\n /**\n * toHexOffset(off, sel, fAddr32)\n *\n * @this {DebuggerX86}\n * @param {number|null|undefined} [off]\n * @param {number|null|undefined} [sel]\n * @param {boolean} [fAddr32] is true for 32-bit ADDRESS size\n * @return {string} the hex representation of off (or sel:off)\n */\n toHexOffset(off, sel, fAddr32)\n {\n if (sel != null) {\n return Str.toHex(sel, 4) + ':' + Str.toHex(off, (off & ~0xffff) || fAddr32? 8 : 4);\n }\n return Str.toHex(off);\n }\n\n /**\n * toHexAddr(dbgAddr)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @return {string} the hex representation of the address\n */\n toHexAddr(dbgAddr)\n {\n var ch = this.getAddrPrefix(dbgAddr);\n /*\n * TODO: Revisit the decision to check sel == null; I would rather see these decisions based on type.\n */\n return (dbgAddr.type >= DebuggerX86.ADDRTYPE.LINEAR || dbgAddr.sel == null)? (ch + Str.toHex(dbgAddr.addr)) : (ch + this.toHexOffset(dbgAddr.off, dbgAddr.sel, dbgAddr.fAddr32));\n }\n\n /**\n * getSZ(dbgAddr, cchMax)\n *\n * Gets zero-terminated (aka \"ASCIIZ\") string from dbgAddr. It also stops at the first '$', in case this is\n * a '$'-terminated string -- mainly because I'm lazy and didn't feel like writing a separate get() function.\n * Yes, a zero-terminated string containing a '$' will be prematurely terminated, and no, I don't care.\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {number} [cchMax] (default is 256)\n * @return {string} (and dbgAddr advanced past the terminating zero)\n */\n getSZ(dbgAddr, cchMax)\n {\n var s = \"\";\n cchMax = cchMax || 256;\n while (s.length < cchMax) {\n var b = this.getByte(dbgAddr, 1);\n if (!b || b == 0x24 || b >= 127) break;\n s += (b >= 32? String.fromCharCode(b) : '.');\n }\n return s;\n }\n\n /**\n * dumpBackTrack(asArgs)\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n */\n dumpBackTrack(asArgs)\n {\n var sInfo = \"no information\";\n if (BACKTRACK) {\n var sAddr = asArgs[0];\n var dbgAddr = this.parseAddr(sAddr, true, true, true);\n if (dbgAddr) {\n var addr = this.getAddr(dbgAddr);\n if (dbgAddr.type != DebuggerX86.ADDRTYPE.PHYSICAL) {\n var pageInfo = this.getPageInfo(addr);\n if (pageInfo) {\n dbgAddr.addr = pageInfo.addrPhys;\n dbgAddr.type = DebuggerX86.ADDRTYPE.PHYSICAL;\n }\n }\n sInfo = this.toHexAddr(dbgAddr) + \": \" + (this.bus.getSymbol(addr, true) || sInfo);\n } else {\n var component, componentPrev = null;\n while (component = this.cmp.getMachineComponent(\"Disk\", componentPrev)) {\n var aInfo = component.getSymbolInfo(sAddr);\n if (aInfo.length) {\n sInfo = \"\";\n for (var i in aInfo) {\n var a = aInfo[i];\n if (sInfo) sInfo += '\\n';\n sInfo += a[0] + \": \" + a[1] + ' ' + Str.toHex(a[2], 4) + ':' + Str.toHex(a[3], 4) + \" len \" + Str.toHexWord(a[4]);\n }\n }\n componentPrev = component;\n }\n }\n }\n return sInfo;\n }\n\n /**\n * dumpBlocks(aBlocks, sAddr, fLinear)\n *\n * @this {DebuggerX86}\n * @param {Array} aBlocks\n * @param {string} [sAddr] (optional block address)\n * @param {boolean} [fLinear] (true if linear, physical otherwise)\n */\n dumpBlocks(aBlocks, sAddr, fLinear)\n {\n var addr = 0, i = 0, n = aBlocks.length;\n\n if (sAddr) {\n addr = this.getAddr(this.parseAddr(sAddr));\n if (addr === X86.ADDR_INVALID) {\n this.println(\"invalid address: \" + sAddr);\n return;\n }\n i = addr >>> this.cpu.nBlockShift;\n n = 1;\n }\n\n this.println(\"blockid \" + (fLinear? \"linear \" : \"physical\") + \" blockaddr used size type\");\n this.println(\"-------- --------- ---------- ------ ------ ----\");\n\n var typePrev = -1, cPrev = 0;\n while (n--) {\n var block = aBlocks[i];\n /*\n * We need to replicate a portion of what probeAddr() does, which is to \"peek\" at the\n * underlying physical block of any UNPAGED block. An UNPAGED block doesn't imply\n * that the page is invalid, but merely that the CPU has not yet been asked to perform\n * the page directory/page table lookup.\n *\n * To do that, we use the same mapPageBlock() interface that the CPU uses, with fSuppress\n * set, so that it doesn't 1) generate a fault or 2) modify the block. Blocks should only\n * \"validated\" when a CPU operation touches the corresponding page, and they should be only\n * be \"invalidated\" when the CPU wants to flush the TLB (ie, whenever CR3 is updated).\n */\n if (block && block.type == Memory.TYPE.UNPAGED) {\n block = this.cpu.mapPageBlock(addr, false, true);\n }\n if (block.type == typePrev) {\n if (!cPrev++) this.println(\"...\");\n } else {\n typePrev = block.type;\n var sType = Memory.TYPE.NAMES[typePrev];\n if (typePrev == Memory.TYPE.PAGED) {\n block = block.blockPhys;\n\n sType += \" -> \" + Memory.TYPE.NAMES[block.type];\n }\n if (block) {\n this.println(Str.toHex(block.id, 8) + \" %\" + Str.toHex(i << this.cpu.nBlockShift, 8) + \" %%\" + Str.toHex(block.addr, 8) + \" \" + Str.toHexWord(block.used) + \" \" + Str.toHexWord(block.size) + \" \" + sType);\n }\n if (typePrev != Memory.TYPE.NONE && typePrev != Memory.TYPE.UNPAGED) typePrev = -1;\n cPrev = 0;\n }\n addr += this.cpu.nBlockSize;\n i++;\n }\n }\n\n /**\n * dumpBus(asArgs)\n *\n * Dumps Bus allocations.\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs (asArgs[0] is an optional block address)\n */\n dumpBus(asArgs)\n {\n this.dumpBlocks(this.cpu.aBusBlocks, asArgs[0]);\n }\n\n /**\n * dumpDOS(asArgs)\n *\n * Dumps DOS MCBs (Memory Control Blocks).\n *\n * TODO: Add some code to detect the current version of DOS (if any) and locate the first MCB automatically.\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n */\n dumpDOS(asArgs)\n {\n var mcb;\n var sMCB = asArgs[0];\n if (sMCB) {\n mcb = this.parseValue(sMCB);\n }\n if (mcb === undefined) {\n this.println(\"invalid MCB\");\n return;\n }\n this.println(\"dumpMCB(\" + Str.toHexWord(mcb) + ')');\n while (mcb) {\n var dbgAddr = this.newAddr(0, mcb);\n var bSig = this.getByte(dbgAddr, 1);\n var wPID = this.getShort(dbgAddr, 2);\n var wParas = this.getShort(dbgAddr, 5);\n if (bSig != 0x4D && bSig != 0x5A) break;\n this.println(this.toHexOffset(0, mcb) + \": '\" + String.fromCharCode(bSig) + \"' PID=\" + Str.toHexWord(wPID) + \" LEN=\" + Str.toHexWord(wParas) + ' \"' + this.getSZ(dbgAddr, 8) + '\"');\n mcb += 1 + wParas;\n }\n }\n\n /**\n * dumpIDT(asArgs)\n *\n * Dumps an IDT vector entry.\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n */\n dumpIDT(asArgs)\n {\n var sIDT = asArgs[0];\n\n if (!sIDT) {\n this.println(\"no IDT vector\");\n return;\n }\n\n var nIDT = this.parseValue(sIDT);\n if (nIDT === undefined || nIDT < 0 || nIDT > 255) {\n this.println(\"invalid vector: \" + sIDT);\n return;\n }\n\n var ch = '&', fProt = this.cpu.isProtMode(), fAddr32 = false;\n var addrIDT = this.cpu.addrIDT + (nIDT << (fProt? 3 : 2));\n var off = this.cpu.getShort(addrIDT + X86.DESC.LIMIT.OFFSET);\n var sel = this.cpu.getShort(addrIDT + X86.DESC.BASE.OFFSET);\n if (fProt) {\n ch = '#';\n var acc = this.cpu.getShort(addrIDT + X86.DESC.ACC.OFFSET);\n if (acc & X86.DESC.ACC.TYPE.NONSEG_386) {\n fAddr32 = true;\n off |= this.cpu.getShort(addrIDT + X86.DESC.EXT.OFFSET) << 16;\n }\n }\n\n this.println(\"dumpIDT(\" + Str.toHexWord(nIDT) + \"): \" + ch + Str.toHex(sel, 4) + ':' + Str.toHex(off, fAddr32? 8 : 4));\n }\n\n /**\n * dumpMem(asArgs)\n *\n * Dumps page allocations.\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs (asArgs[0] is an optional block address)\n */\n dumpMem(asArgs)\n {\n this.dumpBlocks(this.cpu.aMemBlocks, asArgs[0], this.cpu.aMemBlocks !== this.cpu.aBusBlocks);\n }\n\n /**\n * getPageEntry(addrPE, lPE, fPTE)\n *\n * @this {DebuggerX86}\n * @param {number} addrPE\n * @param {number} lPE\n * @param {boolean} [fPTE] (true if the entry is a PTE, false if it's a PDE)\n * @return {string}\n */\n getPageEntry(addrPE, lPE, fPTE)\n {\n var s = Str.toHex(addrPE) + ' ' + Str.toHex(lPE) + ' ';\n s += (fPTE && (lPE & X86.PTE.DIRTY))? 'D' : '-';\n s += (lPE & X86.PTE.ACCESSED)? 'A' : '-';\n s += (lPE & X86.PTE.USER)? 'U' : 'S';\n s += (lPE & X86.PTE.READWRITE)? 'W' : 'R';\n s += (lPE & X86.PTE.PRESENT)? 'P' : 'N';\n return s;\n }\n\n /**\n * getPageInfo(addr)\n *\n * @this {DebuggerX86}\n * @param {number} addr\n * @return {Object|null}\n */\n getPageInfo(addr)\n {\n var pageInfo = null;\n if (I386 && this.cpu.model >= X86.MODEL_80386) {\n var bus = this.bus;\n /*\n * Here begins code remarkably similar to mapPageBlock() (with fSuppress set).\n */\n pageInfo = {};\n pageInfo.offPDE = (addr & X86.LADDR.PDE.MASK) >>> X86.LADDR.PDE.SHIFT;\n pageInfo.addrPDE = this.cpu.regCR3 + pageInfo.offPDE;\n pageInfo.blockPDE = bus.aMemBlocks[(pageInfo.addrPDE & bus.nBusMask) >>> bus.nBlockShift];\n pageInfo.lPDE = pageInfo.blockPDE.readLong(pageInfo.offPDE);\n pageInfo.offPTE = (addr & X86.LADDR.PTE.MASK) >>> X86.LADDR.PTE.SHIFT;\n pageInfo.addrPTE = (pageInfo.lPDE & X86.PTE.FRAME) + pageInfo.offPTE;\n pageInfo.blockPTE = bus.aMemBlocks[(pageInfo.addrPTE & bus.nBusMask) >>> bus.nBlockShift];\n pageInfo.lPTE = pageInfo.blockPTE.readLong(pageInfo.offPTE);\n pageInfo.addrPhys = (pageInfo.lPTE & X86.PTE.FRAME) + (addr & X86.LADDR.OFFSET);\n //var blockPhys = bus.aMemBlocks[(addrPhys & bus.nBusMask) >>> bus.nBlockShift];\n }\n return pageInfo;\n }\n\n /**\n * dumpPage(asArgs)\n *\n * Dumps page table information about the given linear address.\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n */\n dumpPage(asArgs)\n {\n var sAddr = asArgs[0];\n if (!sAddr) {\n this.println(\"missing address\");\n return;\n }\n\n var addr = this.getAddr(this.parseAddr(sAddr));\n if (addr === X86.ADDR_INVALID) {\n this.println(\"invalid address: \" + sAddr);\n return;\n }\n\n var pageInfo = this.getPageInfo(addr);\n if (!pageInfo) {\n this.println(\"unsupported operation\");\n return;\n }\n\n this.println(\"linear PDE addr PDE PTE addr PTE physical\" );\n this.println(\"--------- ---------- -------- ---------- -------- ----------\");\n var s = '%' + Str.toHex(addr);\n s += \" %%\" + this.getPageEntry(pageInfo.addrPDE, pageInfo.lPDE);\n s += \" %%\" + this.getPageEntry(pageInfo.addrPTE, pageInfo.lPTE, true);\n s += \" %%\" + Str.toHex(pageInfo.addrPhys);\n this.println(s);\n }\n\n /**\n * dumpSel(asArgs)\n *\n * Dumps a descriptor for the given selector.\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n */\n dumpSel(asArgs)\n {\n var sSel = asArgs[0];\n\n if (!sSel) {\n this.println(\"no selector\");\n return;\n }\n\n var sel = this.parseValue(sSel);\n if (sel === undefined) {\n this.println(\"invalid selector: \" + sSel);\n return;\n }\n\n var seg = this.getSegment(sel, DebuggerX86.ADDRTYPE.PROT);\n this.println(\"dumpSel(\" + Str.toHexWord(seg? seg.sel : sel) + \"): %\" + Str.toHex(seg? seg.addrDesc : null, this.cchAddr));\n if (!seg) return;\n\n var sType;\n var fGate = false;\n if (seg.type & X86.DESC.ACC.TYPE.SEG) {\n if (seg.type & X86.DESC.ACC.TYPE.CODE) {\n sType = \"code\";\n sType += (seg.type & X86.DESC.ACC.TYPE.READABLE)? \",readable\" : \",execonly\";\n if (seg.type & X86.DESC.ACC.TYPE.CONFORMING) sType += \",conforming\";\n }\n else {\n sType = \"data\";\n sType += (seg.type & X86.DESC.ACC.TYPE.WRITABLE)? \",writable\" : \",readonly\";\n if (seg.type & X86.DESC.ACC.TYPE.EXPDOWN) sType += \",expdown\";\n }\n if (seg.type & X86.DESC.ACC.TYPE.ACCESSED) sType += \",accessed\";\n }\n else {\n var sysDesc = DebuggerX86.SYSDESCS[seg.type];\n if (sysDesc) {\n sType = sysDesc[0];\n fGate = sysDesc[1];\n }\n }\n\n if (sType && !(seg.acc & X86.DESC.ACC.PRESENT)) sType += \",not present\";\n\n var sDump;\n if (fGate) {\n sDump = \"seg=\" + Str.toHexWord(seg.base & 0xffff) + \" off=\" + Str.toHexWord(seg.limit);\n } else {\n sDump = \"base=\" + Str.toHex(seg.base, this.cchAddr) + \" limit=\" + this.getLimitString(seg.limit);\n }\n /*\n * When we dump the EXT word, we mask off the LIMIT1619 and BASE2431 bits, because those have already\n * been incorporated into the limit and base properties of the segment register; all we care about here\n * are whether EXT contains any of the AVAIL (0x10), BIG (0x40) or LIMITPAGES (0x80) bits.\n */\n this.println(sDump + \" type=\" + Str.toHexByte(seg.type >> 8) + \" (\" + sType + ')' + \" ext=\" + Str.toHexWord(seg.ext & ~(X86.DESC.EXT.LIMIT1619 | X86.DESC.EXT.BASE2431)) + \" dpl=\" + Str.toHexByte(seg.dpl));\n }\n\n /**\n * dumpHistory(sPrev, sLines, sComment)\n *\n * If sLines is not a number, it can be a instruction filter. However, for the moment, the only\n * supported filter is \"call\", which filters the history buffer for all CALL and RET instructions\n * from the specified previous point forward.\n *\n * @this {DebuggerX86}\n * @param {string} [sPrev] is a (decimal) number of instructions to rewind to (default is 10)\n * @param {string} [sLines] is a (decimal) number of instructions to print (default is, again, 10)\n * @param {string} [sComment] (should be either \"history\" or \"cycles\"; default is \"history\")\n */\n dumpHistory(sPrev, sLines, sComment = \"history\")\n {\n var sMore = \"\";\n var cHistory = 0;\n var iHistory = this.iOpcodeHistory;\n var aHistory = this.aOpcodeHistory;\n\n if (aHistory.length) {\n var nPrev = +sPrev || this.nextHistory;\n var nLines = +sLines || 10;\n\n if (isNaN(nPrev)) {\n nPrev = nLines;\n } else {\n sMore = \"more \";\n }\n\n if (nPrev > aHistory.length) {\n this.println(\"note: only \" + aHistory.length + \" available\");\n nPrev = aHistory.length;\n }\n\n iHistory -= nPrev;\n if (iHistory < 0) {\n /*\n * If the dbgAddr of the last aHistory element contains a valid selector, wrap around.\n */\n if (aHistory[aHistory.length - 1].sel == null) {\n nPrev = iHistory + nPrev;\n iHistory = 0;\n } else {\n iHistory += aHistory.length;\n }\n }\n\n var aFilters = [];\n if (sLines == \"call\") {\n nLines = 100000;\n aFilters = [\"CALL\"];\n }\n\n if (sPrev !== undefined) {\n this.println(nPrev + \" instructions earlier:\");\n }\n\n /*\n * TODO: The following is necessary to prevent dumpHistory() from causing additional (or worse, recursive)\n * faults due to segmented addresses that are no longer valid, but the only alternative is to dramatically\n * increase the amount of memory used to store instruction history (eg, storing copies of all the instruction\n * bytes alongside the execution addresses).\n *\n * For now, we're living dangerously, so that our history dumps actually work.\n *\n * this.nSuppressBreaks++;\n *\n * If you re-enable this protection, be sure to re-enable the decrement below, too.\n */\n while (nLines > 0 && iHistory != this.iOpcodeHistory) {\n\n var dbgAddr = aHistory[iHistory++];\n if (dbgAddr.sel == null) break;\n\n /*\n * We must create a new dbgAddr from the address in aHistory, because dbgAddr was\n * a reference, not a copy, and we don't want getInstruction() modifying the original.\n */\n var dbgAddrNew = this.newAddr(dbgAddr.off, dbgAddr.sel, dbgAddr.addr, dbgAddr.type, dbgAddr.fData32, dbgAddr.fAddr32);\n\n var nSequence = nPrev--;\n if (dbgAddr.cycleCount != null && sComment == \"cycles\") {\n nSequence = dbgAddr.cycleCount;\n }\n\n var sInstruction = this.getInstruction(dbgAddrNew, sComment, nSequence);\n\n if (!aFilters.length || sInstruction.indexOf(aFilters[0]) >= 0) {\n this.println(sInstruction);\n }\n\n /*\n * If there were OPERAND or ADDRESS overrides on the previous instruction, getInstruction()\n * will have automatically disassembled additional bytes, so skip additional history entries.\n */\n if (dbgAddrNew.cOverrides) {\n iHistory += dbgAddrNew.cOverrides; nLines -= dbgAddrNew.cOverrides; nPrev -= dbgAddrNew.cOverrides;\n }\n\n if (iHistory >= aHistory.length) iHistory = 0;\n this.nextHistory = nPrev;\n cHistory++;\n nLines--;\n }\n /*\n * See comments above.\n *\n * this.nSuppressBreaks--;\n */\n }\n\n if (!cHistory) {\n this.println(\"no \" + sMore + \"history available\");\n this.nextHistory = undefined;\n }\n }\n\n /**\n * dumpTSS(asArgs)\n *\n * This dumps a TSS using the given selector. If none is specified, the current TR is used.\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n */\n dumpTSS(asArgs)\n {\n var seg;\n var sSel = asArgs[0];\n\n if (!sSel) {\n seg = this.cpu.segTSS;\n } else {\n var sel = this.parseValue(sSel);\n if (sel === undefined) {\n this.println(\"invalid task selector: \" + sSel);\n return;\n }\n seg = this.getSegment(sel, DebuggerX86.ADDRTYPE.PROT);\n }\n\n this.println(\"dumpTSS(\" + Str.toHexWord(seg? seg.sel : sel) + \"): %\" + Str.toHex(seg? seg.base : null, this.cchAddr));\n if (!seg) return;\n\n var sDump = \"\";\n var type = seg.type & ~X86.DESC.ACC.TYPE.TSS_BUSY;\n var cch = (type == X86.DESC.ACC.TYPE.TSS286? 4 : 8);\n var aTSSFields = (type == X86.DESC.ACC.TYPE.TSS286? DebuggerX86.TSS286 : DebuggerX86.TSS386);\n var off, addr, v;\n for (var sField in aTSSFields) {\n off = aTSSFields[sField];\n addr = seg.base + off;\n v = this.cpu.probeAddr(addr, 2);\n if (type == X86.DESC.ACC.TYPE.TSS386) {\n v |= this.cpu.probeAddr(addr + 2, 2) << 16;\n }\n if (sDump) sDump += '\\n';\n sDump += Str.toHexWord(off) + ' ' + Str.pad(sField + ':', 11) + Str.toHex(v, cch);\n }\n if (type == X86.DESC.ACC.TYPE.TSS386) {\n var iPort = 0;\n off = (v >>> 16);\n /*\n * We arbitrarily cut the IOPM dump off at port 0x3FF; we're not currently interested in anything above that.\n */\n while (off < seg.offMax && iPort < 0x3ff) {\n addr = seg.base + off;\n v = this.cpu.probeAddr(addr, 2);\n sDump += \"\\n\" + Str.toHexWord(off) + \" ports \" + Str.toHexWord(iPort) + '-' + Str.toHexWord(iPort+15) + \": \" + Str.toBinBytes(v, 2);\n iPort += 16;\n off += 2;\n }\n }\n this.println(sDump);\n }\n\n /**\n * findModuleInfo(sModule, nSegment)\n *\n * Since we're not sure what Disk the module was loaded from, we have to check all of them.\n *\n * @this {DebuggerX86}\n * @param {string} sModule\n * @param {number} nSegment\n * @return {Object}\n */\n findModuleInfo(sModule, nSegment)\n {\n var aSymbols = [];\n if (SYMBOLS) {\n var component, componentPrev = null;\n while (component = this.cmp.getMachineComponent(\"Disk\", componentPrev)) {\n aSymbols = component.getModuleInfo(sModule, nSegment);\n if (aSymbols.length) break;\n componentPrev = component;\n }\n }\n return aSymbols;\n }\n\n /**\n * messageInit(sEnable)\n *\n * @this {DebuggerX86}\n * @param {string|undefined} sEnable contains zero or more message categories to enable, separated by '|'\n */\n messageInit(sEnable)\n {\n this.dbg = this;\n this.bitsMessage = Messages.WARN;\n this.sMessagePrev = null;\n this.aMessageBuffer = [];\n var aEnable = this.parseCommand(sEnable, false, '|');\n if (aEnable.length) {\n this.bitsMessage = Messages.NONE; // when specific messages are being enabled, WARN must be explicitly set\n for (var m in Messages.CATEGORIES) {\n if (Usr.indexOf(aEnable, m) >= 0) {\n this.bitsMessage |= Messages.CATEGORIES[m];\n this.println(m + \" messages enabled\");\n }\n }\n }\n this.historyInit(); // call this just in case Messages.INT was turned on\n }\n\n /**\n * messageDump(bitMessage, fnDumper)\n *\n * @this {DebuggerX86}\n * @param {number} bitMessage is one Messages category flag\n * @param {function(Array.<string>)} fnDumper is a function the Debugger can use to dump data for that category\n * @return {boolean} true if successfully registered, false if not\n */\n messageDump(bitMessage, fnDumper)\n {\n for (var m in Messages.CATEGORIES) {\n if (bitMessage == Messages.CATEGORIES[m]) {\n this.afnDumpers[m] = fnDumper;\n return true;\n }\n }\n return false;\n }\n\n /**\n * getRegIndex(sReg, off)\n *\n * @this {DebuggerX86}\n * @param {string} sReg\n * @param {number} [off] optional offset into sReg\n * @return {number} register index, or -1 if not found\n */\n getRegIndex(sReg, off)\n {\n var i;\n sReg = sReg.toUpperCase();\n if (off == null) {\n i = Usr.indexOf(DebuggerX86.REGS, sReg);\n } else {\n i = Usr.indexOf(DebuggerX86.REGS, sReg.substr(off, 3));\n if (i < 0) i = Usr.indexOf(DebuggerX86.REGS, sReg.substr(off, 2));\n }\n return i;\n }\n\n /**\n * getRegString(iReg)\n *\n * @this {DebuggerX86}\n * @param {number} iReg\n * @return {string}\n */\n getRegString(iReg)\n {\n var cch = 0;\n var n = this.getRegValue(iReg);\n if (n != null) {\n switch(iReg) {\n case DebuggerX86.REG_AL:\n case DebuggerX86.REG_CL:\n case DebuggerX86.REG_DL:\n case DebuggerX86.REG_BL:\n case DebuggerX86.REG_AH:\n case DebuggerX86.REG_CH:\n case DebuggerX86.REG_DH:\n case DebuggerX86.REG_BH:\n cch = 2;\n break;\n case DebuggerX86.REG_AX:\n case DebuggerX86.REG_CX:\n case DebuggerX86.REG_DX:\n case DebuggerX86.REG_BX:\n case DebuggerX86.REG_SP:\n case DebuggerX86.REG_BP:\n case DebuggerX86.REG_SI:\n case DebuggerX86.REG_DI:\n case DebuggerX86.REG_IP:\n case DebuggerX86.REG_SEG + DebuggerX86.REG_ES:\n case DebuggerX86.REG_SEG + DebuggerX86.REG_CS:\n case DebuggerX86.REG_SEG + DebuggerX86.REG_SS:\n case DebuggerX86.REG_SEG + DebuggerX86.REG_DS:\n case DebuggerX86.REG_SEG + DebuggerX86.REG_FS:\n case DebuggerX86.REG_SEG + DebuggerX86.REG_GS:\n cch = 4;\n break;\n case DebuggerX86.REG_EAX:\n case DebuggerX86.REG_ECX:\n case DebuggerX86.REG_EDX:\n case DebuggerX86.REG_EBX:\n case DebuggerX86.REG_ESP:\n case DebuggerX86.REG_EBP:\n case DebuggerX86.REG_ESI:\n case DebuggerX86.REG_EDI:\n case DebuggerX86.REG_CR0:\n case DebuggerX86.REG_CR1:\n case DebuggerX86.REG_CR2:\n case DebuggerX86.REG_CR3:\n case DebuggerX86.REG_EIP:\n cch = 8;\n break;\n case DebuggerX86.REG_PS:\n cch = this.cchReg;\n break;\n }\n }\n return cch? Str.toHex(n, cch) : \"??\";\n }\n\n /**\n * getRegValue(iReg)\n *\n * @this {DebuggerX86}\n * @param {number} iReg\n * @return {number|undefined}\n */\n getRegValue(iReg)\n {\n var n;\n if (iReg >= 0) {\n var cpu = this.cpu;\n switch(iReg) {\n case DebuggerX86.REG_AL:\n n = cpu.regEAX & 0xff;\n break;\n case DebuggerX86.REG_CL:\n n = cpu.regECX & 0xff;\n break;\n case DebuggerX86.REG_DL:\n n = cpu.regEDX & 0xff;\n break;\n case DebuggerX86.REG_BL:\n n = cpu.regEBX & 0xff;\n break;\n case DebuggerX86.REG_AH:\n n = (cpu.regEAX >> 8) & 0xff;\n break;\n case DebuggerX86.REG_CH:\n n = (cpu.regECX >> 8) & 0xff;\n break;\n case DebuggerX86.REG_DH:\n n = (cpu.regEDX >> 8) & 0xff;\n break;\n case DebuggerX86.REG_BH:\n n = (cpu.regEBX >> 8) & 0xff;\n break;\n case DebuggerX86.REG_AX:\n n = cpu.regEAX & 0xffff;\n break;\n case DebuggerX86.REG_CX:\n n = cpu.regECX & 0xffff;\n break;\n case DebuggerX86.REG_DX:\n n = cpu.regEDX & 0xffff;\n break;\n case DebuggerX86.REG_BX:\n n = cpu.regEBX & 0xffff;\n break;\n case DebuggerX86.REG_SP:\n n = cpu.getSP() & 0xffff;\n break;\n case DebuggerX86.REG_BP:\n n = cpu.regEBP & 0xffff;\n break;\n case DebuggerX86.REG_SI:\n n = cpu.regESI & 0xffff;\n break;\n case DebuggerX86.REG_DI:\n n = cpu.regEDI & 0xffff;\n break;\n case DebuggerX86.REG_IP:\n n = cpu.getIP() & 0xffff;\n break;\n case DebuggerX86.REG_PS:\n n = cpu.getPS();\n break;\n case DebuggerX86.REG_SEG + DebuggerX86.REG_ES:\n n = cpu.getES();\n break;\n case DebuggerX86.REG_SEG + DebuggerX86.REG_CS:\n n = cpu.getCS();\n break;\n case DebuggerX86.REG_SEG + DebuggerX86.REG_SS:\n n = cpu.getSS();\n break;\n case DebuggerX86.REG_SEG + DebuggerX86.REG_DS:\n n = cpu.getDS();\n break;\n default:\n if (this.cpu.model == X86.MODEL_80286) {\n if (iReg == DebuggerX86.REG_CR0) {\n n = cpu.regCR0;\n }\n }\n else if (I386 && this.cpu.model >= X86.MODEL_80386) {\n switch(iReg) {\n case DebuggerX86.REG_EAX:\n n = cpu.regEAX;\n break;\n case DebuggerX86.REG_ECX:\n n = cpu.regECX;\n break;\n case DebuggerX86.REG_EDX:\n n = cpu.regEDX;\n break;\n case DebuggerX86.REG_EBX:\n n = cpu.regEBX;\n break;\n case DebuggerX86.REG_ESP:\n n = cpu.getSP();\n break;\n case DebuggerX86.REG_EBP:\n n = cpu.regEBP;\n break;\n case DebuggerX86.REG_ESI:\n n = cpu.regESI;\n break;\n case DebuggerX86.REG_EDI:\n n = cpu.regEDI;\n break;\n case DebuggerX86.REG_CR0:\n n = cpu.regCR0;\n break;\n case DebuggerX86.REG_CR1:\n n = cpu.regCR1;\n break;\n case DebuggerX86.REG_CR2:\n n = cpu.regCR2;\n break;\n case DebuggerX86.REG_CR3:\n n = cpu.regCR3;\n break;\n case DebuggerX86.REG_SEG + DebuggerX86.REG_FS:\n n = cpu.getFS();\n break;\n case DebuggerX86.REG_SEG + DebuggerX86.REG_GS:\n n = cpu.getGS();\n break;\n case DebuggerX86.REG_EIP:\n n = cpu.getIP();\n break;\n }\n }\n break;\n }\n }\n return n;\n }\n\n /**\n * replaceRegs(s)\n *\n * @this {DebuggerX86}\n * @param {string} s\n * @return {string}\n */\n replaceRegs(s)\n {\n /*\n * Replace any references first; this means that register references inside the reference\n * do NOT need to be prefixed with '@'.\n */\n s = this.parseReference(s) || s;\n\n /*\n * Replace every @XX (or @XXX), where XX (or XXX) is a register, with the register's value.\n */\n var i = 0;\n var b, sChar, sAddr, dbgAddr, sReplace;\n while ((i = s.indexOf('@', i)) >= 0) {\n var iReg = this.getRegIndex(s, i + 1);\n if (iReg >= 0) {\n s = s.substr(0, i) + this.getRegString(iReg) + s.substr(i + 1 + DebuggerX86.REGS[iReg].length);\n }\n i++;\n }\n /*\n * Replace every #XX, where XX is a hex byte value, with the corresponding ASCII character (if printable).\n */\n i = 0;\n while ((i = s.indexOf('#', i)) >= 0) {\n sChar = s.substr(i+1, 2);\n b = Str.parseInt(sChar, 16);\n if (b != null && b >= 32 && b < 127) {\n sReplace = sChar + \" '\" + String.fromCharCode(b) + \"'\";\n s = s.replace('#' + sChar, sReplace);\n i += sReplace.length;\n continue;\n }\n i++;\n }\n /*\n * Replace every $XXXX:XXXX, where XXXX:XXXX is a segmented address, with the zero-terminated string at that address.\n */\n i = 0;\n while ((i = s.indexOf('$', i)) >= 0) {\n sAddr = s.substr(i+1, 9);\n dbgAddr = this.parseAddr(sAddr);\n if (dbgAddr) {\n sReplace = sAddr + ' \"' + this.getSZ(dbgAddr) + '\"';\n s = s.replace('$' + sAddr, sReplace);\n i += sReplace.length;\n continue;\n }\n i++;\n }\n /*\n * Replace every ^XXXX:XXXX, where XXXX:XXXX is a segmented address, with the FCB filename stored at that address.\n */\n i = 0;\n while ((i = s.indexOf('^', i)) >= 0) {\n sAddr = s.substr(i+1, 9);\n dbgAddr = this.parseAddr(sAddr);\n if (dbgAddr) {\n this.incAddr(dbgAddr);\n sReplace = sAddr + ' \"' + this.getSZ(dbgAddr, 11) + '\"';\n s = s.replace('^' + sAddr, sReplace);\n i += sReplace.length;\n continue;\n }\n i++;\n }\n return s;\n }\n\n /**\n * message(sMessage, fAddress)\n *\n * @this {DebuggerX86}\n * @param {string} sMessage is any caller-defined message string\n * @param {boolean} [fAddress] is true to display the current CS:IP\n */\n message(sMessage, fAddress)\n {\n if (fAddress) {\n sMessage += \" at \" + this.toHexAddr(this.newAddr(this.cpu.getIP(), this.cpu.getCS())) + \" (%\" + Str.toHex(this.cpu.regLIP) + \")\";\n }\n\n if ((this.bitsMessage & Messages.BUFFER) == Messages.BUFFER) {\n this.aMessageBuffer.push(sMessage);\n return;\n }\n\n if (this.sMessagePrev && sMessage == this.sMessagePrev) return;\n this.sMessagePrev = sMessage;\n\n if ((this.bitsMessage & Messages.HALT) == Messages.HALT) {\n this.stopCPU();\n sMessage += \" (cpu halted)\";\n }\n\n this.println(sMessage); // + \" (\" + this.cpu.getCycles() + \" cycles)\"\n\n /*\n * We have no idea what the frequency of println() calls might be; all we know is that they easily\n * screw up the CPU's careful assumptions about cycles per burst. So we call yieldCPU() after every\n * message, to effectively end the current burst and start fresh.\n *\n * TODO: See CPU.calcStartTime() for a discussion of why we might want to call yieldCPU() *before*\n * we display the message.\n */\n if (this.cpu) this.cpu.yieldCPU();\n }\n\n /**\n * messageInt(nInt, addr, fForce)\n *\n * @this {DebuggerX86}\n * @param {number} nInt\n * @param {number} addr (LIP after the \"INT n\" instruction has been fetched but not dispatched)\n * @param {boolean} [fForce] (true if the message should be forced)\n * @return {boolean} true if message generated (which in turn triggers addIntReturn() inside checkIntNotify()), false if not\n */\n messageInt(nInt, addr, fForce)\n {\n var AH, DL;\n var fMessage = fForce;\n\n /*\n * We currently arrive here only because the CPU has already determined that INT messages are enabled,\n * or because the ChipSet's RTC interrupt handler has already determined that INT messages are enabled.\n *\n * But software interrupts are very common, so we generally require additional categories to be enabled;\n * unless the caller has set fForce, we check those additional categories now.\n */\n if (!fMessage) {\n /*\n * Display all software interrupts if CPU messages are enabled (and it's not an \"annoying\" interrupt);\n * note that in some cases, even \"annoying\" interrupts can be turned with an extra message category.\n */\n fMessage = this.messageEnabled(Messages.CPU) && DebuggerX86.INT_ANNOYING.indexOf(nInt) < 0;\n if (!fMessage) {\n /*\n * Alternatively, display this software interrupt if its corresponding message category is enabled.\n */\n var nCategory = DebuggerX86.INT_MESSAGES[nInt];\n if (nCategory) {\n if (this.messageEnabled(nCategory)) {\n fMessage = true;\n } else {\n /*\n * Alternatively, display this FDC interrupt if HDC messages are enabled (since they share\n * a common software interrupt). Normally, an HDC BIOS will copy the original DISK (0x13)\n * vector to the ALT_DISK (0x40) vector, but it's a nuisance having to check different\n * interrupts in different configurations for the same frickin' functionality, so we don't.\n */\n fMessage = (nCategory == Messages.FDC && this.messageEnabled(nCategory = Messages.HDC));\n }\n }\n }\n }\n if (fMessage) {\n AH = (this.cpu.regEAX >> 8) & 0xff;\n DL = this.cpu.regEDX & 0xff;\n if (nInt == Interrupts.DOS /* 0x21 */ && AH == 0x0b ||\n nCategory == Messages.FDC && DL >= 0x80 || nCategory == Messages.HDC && DL < 0x80) {\n fMessage = false;\n }\n }\n if (fMessage) {\n var aFuncs = Interrupts.FUNCS[nInt];\n var sFunc = (aFuncs && aFuncs[AH]) || \"\";\n if (sFunc) sFunc = ' ' + this.replaceRegs(sFunc);\n /*\n * For display purposes only, rewind addr to the address of the responsible \"INT n\" instruction;\n * we know it's the two-byte \"INT n\" instruction because that's the only opcode handler that calls\n * checkIntNotify() at the moment.\n */\n addr -= 2;\n this.message(\"INT \" + Str.toHexByte(nInt) + \": AH=\" + Str.toHexByte(AH) + \" at \" + this.toHexOffset(addr - this.cpu.segCS.base, this.cpu.getCS()) + sFunc);\n }\n return fMessage;\n }\n\n /**\n * messageIntReturn(nInt, nLevel, nCycles)\n *\n * @this {DebuggerX86}\n * @param {number} nInt\n * @param {number} nLevel\n * @param {number} nCycles\n * @param {string} [sResult]\n */\n messageIntReturn(nInt, nLevel, nCycles, sResult)\n {\n this.message(\"INT \" + Str.toHexByte(nInt) + \": C=\" + (this.cpu.getCF()? 1 : 0) + (sResult || \"\") + \" (cycles=\" + nCycles + (nLevel? \",level=\" + (nLevel+1) : \"\") + ')');\n }\n\n /**\n * messageIO(component, port, bOut, addrFrom, name, bIn, bitsMessage)\n *\n * @this {DebuggerX86}\n * @param {Component} component\n * @param {number} port\n * @param {number|null} bOut if an output operation\n * @param {number|null} [addrFrom]\n * @param {string|null} [name] of the port, if any\n * @param {number|null} [bIn] is the input value, if known, on an input operation\n * @param {number} [bitsMessage] is one or more Messages category flag(s)\n */\n messageIO(component, port, bOut, addrFrom, name, bIn, bitsMessage)\n {\n bitsMessage |= Messages.PORT;\n if (!name) bitsMessage |= Messages.WARN; // we don't want to see \"unknown\" I/O messages unless WARN is enabled\n if (addrFrom == null || (this.bitsMessage & bitsMessage) == bitsMessage) {\n var selFrom = null;\n if (addrFrom != null) {\n selFrom = this.cpu.getCS();\n addrFrom -= this.cpu.segCS.base;\n }\n this.message(component.idComponent + '.' + (bOut != null? \"outPort\" : \"inPort\") + '(' + Str.toHexWord(port) + ',' + (name? name : \"unknown\") + (bOut != null? ',' + Str.toHexByte(bOut) : \"\") + ')' + (bIn != null? (\": \" + Str.toHexByte(bIn)) : \"\") + (addrFrom != null? (\" at \" + this.toHexOffset(addrFrom, selFrom)) : \"\"));\n }\n }\n\n /**\n * init()\n *\n * @this {DebuggerX86}\n */\n init()\n {\n this.println(\"Type ? for help with PCx86 Debugger commands\");\n this.updateStatus();\n if (this.sCommandsInit) {\n var sCommands = this.sCommandsInit;\n this.sCommandsInit = null;\n this.doCommands(sCommands);\n }\n }\n\n /**\n * historyInit(fQuiet)\n *\n * This function is intended to be called by the constructor, reset(), addBreakpoint(), findBreakpoint()\n * and any other function that changes the checksEnabled() criteria used to decide whether checkInstruction()\n * should be called.\n *\n * That is, if the history arrays need to be allocated and haven't already been allocated, then allocate them,\n * and if the arrays are no longer needed, then deallocate them.\n *\n * @this {DebuggerX86}\n * @param {boolean} [fQuiet]\n */\n historyInit(fQuiet)\n {\n var i;\n if (!this.checksEnabled()) {\n if (this.aOpcodeHistory && this.aOpcodeHistory.length && !fQuiet) {\n this.println(\"instruction history buffer freed\");\n }\n this.iOpcodeHistory = 0;\n this.aOpcodeHistory = [];\n this.aaOpcodeCounts = [];\n return;\n }\n if (!this.aOpcodeHistory || !this.aOpcodeHistory.length) {\n this.aOpcodeHistory = new Array(DebuggerX86.HISTORY_LIMIT);\n for (i = 0; i < this.aOpcodeHistory.length; i++) {\n /*\n * Preallocate dummy Addr (Array) objects in every history slot, so that\n * checkInstruction() doesn't need to call newAddr() on every slot update.\n */\n this.aOpcodeHistory[i] = this.newAddr();\n }\n this.iOpcodeHistory = 0;\n if (!fQuiet) {\n this.println(\"instruction history buffer allocated\");\n }\n }\n if (!this.aaOpcodeCounts || !this.aaOpcodeCounts.length) {\n this.aaOpcodeCounts = new Array(256);\n for (i = 0; i < this.aaOpcodeCounts.length; i++) {\n this.aaOpcodeCounts[i] = [i, 0];\n }\n }\n }\n\n /**\n * startCPU(fUpdateFocus, fQuiet)\n *\n * @this {DebuggerX86}\n * @param {boolean} [fUpdateFocus]\n * @param {boolean} [fQuiet]\n * @return {boolean} true if run request successful, false if not\n */\n startCPU(fUpdateFocus, fQuiet)\n {\n if (this.checkCPU(fQuiet)) {\n return this.cpu.startCPU(fUpdateFocus, fQuiet);\n }\n return false;\n }\n\n /**\n * stepCPU(nCycles, fRegs, fUpdateCPU)\n *\n * @this {DebuggerX86}\n * @param {number} nCycles (0 for one instruction without checking breakpoints)\n * @param {boolean} [fRegs] is true to display registers after step (default is false)\n * @param {boolean} [fUpdateCPU] is false to disable calls to updateCPU() (default is true)\n * @return {boolean}\n */\n stepCPU(nCycles, fRegs, fUpdateCPU)\n {\n if (!this.checkCPU()) return false;\n\n this.nCycles = 0;\n do {\n if (!nCycles) {\n /*\n * When single-stepping, the CPU won't call checkInstruction(), which is good for\n * avoiding breakpoints, but bad for instruction data collection if checks are enabled.\n * So we call checkInstruction() ourselves.\n */\n if (this.checksEnabled()) this.checkInstruction(this.cpu.regLIP, 0);\n }\n /*\n * For our typically tiny bursts (usually single instructions), mimic what runCPU() does.\n */\n try {\n var nCyclesStep = this.cpu.stepCPU(nCycles);\n if (nCyclesStep > 0) {\n this.nCycles += nCyclesStep;\n this.cpu.addCycles(nCyclesStep, true);\n this.cpu.updateChecksum(nCyclesStep);\n this.cOpcodes++;\n }\n }\n catch(exception) {\n if (typeof exception != \"number\") {\n var e = exception;\n this.nCycles = 0;\n this.cpu.setError(e.stack || e.message);\n }\n }\n } while (this.cpu.opFlags & X86.OPFLAG_PREFIXES);\n\n /*\n * Because we called cpu.stepCPU() and not cpu.startCPU(), we must nudge the cpu's update code,\n * and then update our own state. Normally, the only time fUpdateCPU will be false is when doTrace()\n * is calling us in a loop, in which case it will perform its own updateCPU() when it's done.\n */\n if (fUpdateCPU !== false) this.cpu.updateCPU();\n\n this.updateStatus(fRegs || false);\n return (this.nCycles > 0);\n }\n\n /**\n * stopCPU()\n *\n * @this {DebuggerX86}\n * @param {boolean} [fComplete]\n * @return {boolean}\n */\n stopCPU(fComplete)\n {\n return this.cpu && this.cpu.stopCPU(fComplete) || false;\n }\n\n /**\n * updateStatus(fRegs)\n *\n * @this {DebuggerX86}\n * @param {boolean} [fRegs] (default is true)\n */\n updateStatus(fRegs)\n {\n if (fRegs === undefined) fRegs = true;\n\n this.dbgAddrNextCode = this.newAddr(this.cpu.getIP(), this.cpu.getCS());\n /*\n * this.nStep used to be a simple boolean, but now it's 0 (or undefined)\n * if inactive, 1 if stepping over an instruction without a register dump, or 2\n * if stepping over an instruction with a register dump.\n */\n if (!fRegs || this.nStep == 1)\n this.doUnassemble();\n else {\n this.doRegisters();\n }\n }\n\n /**\n * checkCPU(fQuiet)\n *\n * Make sure the CPU is ready (finished initializing), not busy (already running), and not in an error state.\n *\n * @this {DebuggerX86}\n * @param {boolean} [fQuiet]\n * @return {boolean}\n */\n checkCPU(fQuiet)\n {\n if (!this.cpu || !this.cpu.isReady() || !this.cpu.isPowered() || this.cpu.isRunning()) {\n if (!fQuiet) this.println(\"cpu busy or unavailable, command ignored\");\n return false;\n }\n return !this.cpu.isError();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {DebuggerX86}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n /*\n * Because Debugger save/restore support is somewhat limited (and didn't always exist),\n * we deviate from the typical save/restore design pattern: instead of reset OR restore,\n * we always reset and then perform a (potentially limited) restore.\n */\n this.reset(true);\n\n // this.println(data? \"resuming\" : \"powering up\");\n\n if (data && this.restore) {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {DebuggerX86}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean}\n */\n powerDown(fSave, fShutdown)\n {\n if (fShutdown) this.println(fSave? \"suspending\" : \"shutting down\");\n return fSave? this.save() : true;\n }\n\n /**\n * reset(fQuiet)\n *\n * This is a notification handler, called by the Computer, to inform us of a reset.\n *\n * @this {DebuggerX86}\n * @param {boolean} fQuiet (true only when called from our own powerUp handler)\n */\n reset(fQuiet)\n {\n this.historyInit();\n this.cOpcodes = this.cOpcodesStart = 0;\n this.sMessagePrev = null;\n this.nCycles = 0;\n this.dbgAddrNextCode = this.newAddr(this.cpu.getIP(), this.cpu.getCS());\n this.clearTempBreakpoint();\n if (!fQuiet && !this.flags.running) this.updateStatus();\n }\n\n /**\n * save()\n *\n * This implements (very rudimentary) save support for the Debugger component.\n *\n * @this {DebuggerX86}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.packAddr(this.dbgAddrNextCode));\n state.set(1, this.packAddr(this.dbgAddrNextData));\n state.set(2, this.packAddr(this.dbgAddrAssemble));\n state.set(3, [this.aPrevCmds, this.fAssemble, this.bitsMessage]);\n state.set(4, this.aSymbolTable);\n state.set(5, [this.aBreakExec, this.aBreakRead, this.aBreakWrite]);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements (very rudimentary) restore support for the Debugger component.\n *\n * @this {DebuggerX86}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var i = 0;\n if (data[i]) this.dbgAddrNextCode = this.unpackAddr(data[i++]);\n /*\n * dbgAddrNextData wasn't saved until there were at least 6 elements, hence the check for data[5] instead of data[i]\n */\n if (data[5]) this.dbgAddrNextData = this.unpackAddr(data[i++]);\n if (data[i]) this.dbgAddrAssemble = this.unpackAddr(data[i++]);\n if (data[i]) {\n this.aPrevCmds = data[i][0];\n if (typeof this.aPrevCmds == \"string\") this.aPrevCmds = [this.aPrevCmds];\n this.fAssemble = data[i][1];\n var bits = data[i][2];\n /*\n * We supplement the message bits only the incoming bits adhere to the new format (ie, if bits exist in both the high\n * nibble and one of the low nibbles).\n */\n if ((bits & 0xf0000000) && (bits & 0x0fffffff)) {\n this.bitsMessage |= bits; // include any saved message bits ONLY if they match our new format (ie, bits in both high and low nibbles)\n }\n i++;\n }\n if (data[i]) {\n this.aSymbolTable = data[i++];\n }\n if (data[i]) {\n this.restoreBreakpoints(this.aBreakExec, data[i][0]);\n this.restoreBreakpoints(this.aBreakRead, data[i][1]);\n this.restoreBreakpoints(this.aBreakWrite, data[i][2]);\n }\n return true;\n }\n\n /**\n * start(ms, nCycles)\n *\n * This is a notification handler, called by the Computer, to inform us the CPU has started.\n *\n * @this {DebuggerX86}\n * @param {number} ms\n * @param {number} nCycles\n */\n start(ms, nCycles)\n {\n if (!this.nStep) this.println(\"running\");\n this.flags.running = true;\n this.msStart = ms;\n this.nCyclesStart = nCycles;\n }\n\n /**\n * stop(ms, nCycles)\n *\n * This is a notification handler, called by the Computer, to inform us the CPU has now stopped.\n *\n * @this {DebuggerX86}\n * @param {number} ms\n * @param {number} nCycles\n */\n stop(ms, nCycles)\n {\n if (this.flags.running) {\n this.flags.running = false;\n this.nCycles = nCycles - this.nCyclesStart;\n if (!this.nStep) {\n var sStopped = \"stopped\";\n if (this.nCycles) {\n var msTotal = ms - this.msStart;\n var nCyclesPerSecond = (msTotal > 0? Math.round(this.nCycles * 1000 / msTotal) : 0);\n sStopped += \" (\";\n if (this.checksEnabled()) {\n sStopped += this.cOpcodes + \" opcodes, \";\n /*\n * $ops displays progress by calculating cOpcodes - cOpcodesStart, so before\n * zeroing cOpcodes, we should subtract cOpcodes from cOpcodesStart (since we're\n * effectively subtracting cOpcodes from cOpcodes as well).\n */\n this.cOpcodesStart -= this.cOpcodes;\n this.cOpcodes = 0;\n }\n sStopped += this.nCycles + \" cycles, \" + msTotal + \" ms, \" + nCyclesPerSecond + \" hz)\";\n if (MAXDEBUG && this.chipset) {\n var i, c, n;\n for (i = 0; i < this.chipset.acInterrupts.length; i++) {\n c = this.chipset.acInterrupts[i];\n if (!c) continue;\n n = c / Math.round(msTotal / 1000);\n this.println(\"IRQ\" + i + \": \" + c + \" interrupts (\" + n + \" per sec)\");\n this.chipset.acInterrupts[i] = 0;\n }\n for (i = 0; i < this.chipset.acTimersFired.length; i++) {\n c = this.chipset.acTimersFired[i];\n if (!c) continue;\n n = c / Math.round(msTotal / 1000);\n this.println(\"TIMER\" + i + \": \" + c + \" fires (\" + n + \" per sec)\");\n this.chipset.acTimersFired[i] = 0;\n }\n n = 0;\n for (i = 0; i < this.chipset.acTimer0Counts.length; i++) {\n var a = this.chipset.acTimer0Counts[i];\n n += a[0];\n this.println(\"TIMER0 update #\" + i + \": [\" + a[0] + ',' + a[1] + ',' + a[2] + ']');\n }\n this.chipset.acTimer0Counts = [];\n }\n } else {\n if (this.messageEnabled(Messages.HALT)) {\n /*\n * It's possible the user is trying to 'g' past a fault that was blocked by helpCheckFault()\n * for the Debugger's benefit; if so, it will continue to be blocked, so try displaying a helpful\n * message (another helpful tip would be to simply turn off the \"halt\" message category).\n */\n sStopped += \" (use the 't' command to execute blocked faults)\";\n }\n }\n this.println(sStopped);\n }\n this.updateStatus(true);\n this.updateFocus();\n this.clearTempBreakpoint(this.cpu.regLIP);\n }\n }\n\n /**\n * checksEnabled(fRelease)\n *\n * This \"check\" function is called by the CPU; we indicate whether or not every instruction needs to be checked.\n *\n * Originally, this returned true even when there were only read and/or write breakpoints, but those breakpoints\n * no longer require the intervention of checkInstruction(); the Bus component automatically swaps in/out appropriate\n * \"checked\" Memory access functions to deal with those breakpoints in the corresponding Memory blocks. So I've\n * simplified the test below.\n *\n * @this {DebuggerX86}\n * @param {boolean} [fRelease] is true for release criteria only; default is false (any criteria)\n * @return {boolean} true if every instruction needs to pass through checkInstruction(), false if not\n */\n checksEnabled(fRelease)\n {\n return ((DEBUG && !fRelease)? true : (this.aBreakExec.length > 1 || !!this.nBreakIns || this.messageEnabled(Messages.INT) /* || this.aBreakRead.length > 1 || this.aBreakWrite.length > 1 */));\n }\n\n /**\n * checkInstruction(addr, nState)\n *\n * This \"check\" function is called by the CPU to inform us about the next instruction to be executed,\n * giving us an opportunity to look for \"exec\" breakpoints and update opcode frequencies and instruction history.\n *\n * @this {DebuggerX86}\n * @param {number} addr\n * @param {number} nState is < 0 if stepping, 0 if starting, or > 0 if running\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkInstruction(addr, nState)\n {\n var cpu = this.cpu;\n\n if (nState > 0) {\n if (this.nBreakIns && !--this.nBreakIns) {\n return true;\n }\n if (this.checkBreakpoint(addr, 1, this.aBreakExec)) {\n return true;\n }\n /*\n * Halt if running with interrupts disabled and IOPL < CPL, because that's likely an error\n */\n if (MAXDEBUG && !(cpu.regPS & X86.PS.IF) && cpu.nIOPL < cpu.nCPL) {\n this.printMessage(\"interrupts disabled at IOPL \" + cpu.nIOPL + \" and CPL \" + cpu.nCPL, true);\n return true;\n }\n }\n\n /*\n * The rest of the instruction tracking logic can only be performed if historyInit() has allocated the\n * necessary data structures. Note that there is no explicit UI for enabling/disabling history, other than\n * adding/removing breakpoints, simply because it's breakpoints that trigger the call to checkInstruction();\n * well, OK, and a few other things now, like enabling Messages.INT messages.\n */\n if (nState >= 0 && this.aaOpcodeCounts.length) {\n this.cOpcodes++;\n var bOpcode = cpu.probeAddr(addr);\n if (bOpcode != null) {\n this.aaOpcodeCounts[bOpcode][1]++;\n var dbgAddr = this.aOpcodeHistory[this.iOpcodeHistory];\n this.setAddr(dbgAddr, cpu.getIP(), cpu.getCS());\n dbgAddr.cycleCount = cpu.getCycles();\n if (++this.iOpcodeHistory == this.aOpcodeHistory.length) this.iOpcodeHistory = 0;\n }\n }\n return false;\n }\n\n /**\n * checkMemoryRead(addr, nb)\n *\n * This \"check\" function is called by a Memory block to inform us that a memory read occurred, giving us an\n * opportunity to track the read if we want, and look for a matching \"read\" breakpoint, if any.\n *\n * In the \"old days\", it would be an error for this call to fail to find a matching Debugger breakpoint, but now\n * Memory blocks have no idea whether the Debugger or the machine's Debug register(s) triggered this \"checked\" read.\n *\n * If we return true, we \"trump\" the machine's Debug register(s); false allows normal Debug register processing.\n *\n * @this {DebuggerX86}\n * @param {number} addr\n * @param {number} [nb] (# of bytes; default is 1)\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkMemoryRead(addr, nb)\n {\n if (this.checkBreakpoint(addr, nb || 1, this.aBreakRead)) {\n this.stopCPU(true);\n return true;\n }\n return false;\n }\n\n /**\n * checkMemoryWrite(addr, nb)\n *\n * This \"check\" function is called by a Memory block to inform us that a memory write occurred, giving us an\n * opportunity to track the write if we want, and look for a matching \"write\" breakpoint, if any.\n *\n * In the \"old days\", it would be an error for this call to fail to find a matching Debugger breakpoint, but now\n * Memory blocks have no idea whether the Debugger or the machine's Debug register(s) triggered this \"checked\" write.\n *\n * If we return true, we \"trump\" the machine's Debug register(s); false allows normal Debug register processing.\n *\n * @this {DebuggerX86}\n * @param {number} addr\n * @param {number} [nb] (# of bytes; default is 1)\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkMemoryWrite(addr, nb)\n {\n if (this.checkBreakpoint(addr, nb || 1, this.aBreakWrite)) {\n this.stopCPU(true);\n return true;\n }\n return false;\n }\n\n /**\n * checkPortInput(port, size, data)\n *\n * This \"check\" function is called by the Bus component to inform us that port input occurred.\n *\n * @this {DebuggerX86}\n * @param {number} port\n * @param {number} size\n * @param {number} data\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkPortInput(port, size, data)\n {\n /*\n * We trust that the Bus component won't call us unless we told it to, so we halt unconditionally\n */\n this.println(\"break on input from port \" + Str.toHexWord(port) + \": \" + Str.toHex(data));\n this.stopCPU(true);\n return true;\n }\n\n /**\n * checkPortOutput(port, size, data)\n *\n * This \"check\" function is called by the Bus component to inform us that port output occurred.\n *\n * @this {DebuggerX86}\n * @param {number} port\n * @param {number} size\n * @param {number} data\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkPortOutput(port, size, data)\n {\n /*\n * We trust that the Bus component won't call us unless we told it to, so we halt unconditionally\n */\n this.println(\"break on output to port \" + Str.toHexWord(port) + \": \" + Str.toHex(data));\n this.stopCPU(true);\n return true;\n }\n\n /**\n * clearBreakpoints()\n *\n * @this {DebuggerX86}\n */\n clearBreakpoints()\n {\n var i, dbgAddr;\n this.aBreakExec = [\"bp\"];\n if (this.aBreakRead !== undefined) {\n for (i = 1; i < this.aBreakRead.length; i++) {\n dbgAddr = this.aBreakRead[i];\n this.cpu.removeMemBreak(this.getAddr(dbgAddr), false, dbgAddr.type == DebuggerX86.ADDRTYPE.PHYSICAL);\n }\n }\n this.aBreakRead = [\"br\"];\n if (this.aBreakWrite !== undefined) {\n for (i = 1; i < this.aBreakWrite.length; i++) {\n dbgAddr = this.aBreakWrite[i];\n this.cpu.removeMemBreak(this.getAddr(dbgAddr), true, dbgAddr.type == DebuggerX86.ADDRTYPE.PHYSICAL);\n }\n }\n this.aBreakWrite = [\"bw\"];\n /*\n * nSuppressBreaks ensures we can't get into an infinite loop where a breakpoint lookup requires\n * reading a segment descriptor via getSegment(), and that triggers more memory reads, which triggers\n * more breakpoint checks.\n */\n this.nSuppressBreaks = 0;\n }\n\n /**\n * addBreakpoint(aBreak, dbgAddr, fTempBreak, fQuiet)\n *\n * In case you haven't already figured this out, all our breakpoint commands use the address\n * to identify a breakpoint, not an incrementally assigned breakpoint index like other debuggers;\n * see doBreak() for details.\n *\n * This has a few implications, one being that you CANNOT set more than one kind of breakpoint\n * on a single address. In practice, that's rarely a problem, because you can almost always set\n * a different breakpoint on a neighboring address.\n *\n * Also, there is one exception to the \"one address, one breakpoint\" rule, and that involves\n * temporary breakpoints (ie, one-time execution breakpoints that either a \"p\" or \"g\" command\n * may create to step over a chunk of code). Those breakpoints automatically clear themselves,\n * so there usually isn't any need to refer to them using breakpoint commands.\n *\n * TODO: Consider supporting the more \"traditional\" breakpoint index syntax; the current\n * address-based syntax was implemented solely for expediency and consistency. At the same time,\n * also consider a more WDEB386-like syntax, where \"br\" is used to set a variety of access-specific\n * breakpoints, using modifiers like \"r1\", \"r2\", \"w1\", \"w2, etc.\n *\n * @this {DebuggerX86}\n * @param {Array} aBreak\n * @param {DbgAddrX86} dbgAddr\n * @param {boolean} [fTempBreak]\n * @param {boolean} [fQuiet]\n * @return {boolean} true if breakpoint added, false if already exists\n */\n addBreakpoint(aBreak, dbgAddr, fTempBreak, fQuiet)\n {\n var fSuccess = true;\n\n // this.nSuppressBreaks++;\n\n /*\n * Instead of complaining that a breakpoint already exists (as we used to do), we now\n * allow breakpoints to be re-set; this makes it easier to update any commands that may\n * be associated with the breakpoint.\n *\n * The only exception: we DO allow a temporary breakpoint at an address where there may\n * already be a breakpoint, so that you can easily step (\"p\" or \"g\") over such addresses.\n */\n if (!fTempBreak) {\n this.findBreakpoint(aBreak, dbgAddr, true, false, true);\n }\n\n if (aBreak != this.aBreakExec) {\n var addr = this.getAddr(dbgAddr);\n if (addr === X86.ADDR_INVALID) {\n this.println(\"invalid address: \" + this.toHexAddr(dbgAddr));\n fSuccess = false;\n } else {\n this.cpu.addMemBreak(addr, aBreak == this.aBreakWrite, dbgAddr.type == DebuggerX86.ADDRTYPE.PHYSICAL);\n }\n }\n\n if (fSuccess) {\n aBreak.push(dbgAddr);\n if (fTempBreak) {\n /*\n * Force temporary breakpoints to use their linear address, if one is available, by zapping\n * the selector; this allows us to step over calls or interrupts that change the processor mode.\n *\n * TODO: Unfortunately, this will fail to \"step\" over a call in segment that moves during the call;\n * consider alternatives.\n */\n if (dbgAddr.addr != null) dbgAddr.sel = null;\n dbgAddr.fTempBreak = true;\n }\n else {\n if (!fQuiet) this.printBreakpoint(aBreak, aBreak.length-1, \"set\");\n this.historyInit();\n }\n }\n\n // this.nSuppressBreaks--;\n\n return fSuccess;\n }\n\n /**\n * findBreakpoint(aBreak, dbgAddr, fRemove, fTempBreak, fQuiet)\n *\n * @this {DebuggerX86}\n * @param {Array} aBreak\n * @param {DbgAddrX86} dbgAddr\n * @param {boolean} [fRemove]\n * @param {boolean} [fTempBreak]\n * @param {boolean} [fQuiet]\n * @return {boolean} true if found, false if not\n */\n findBreakpoint(aBreak, dbgAddr, fRemove, fTempBreak, fQuiet)\n {\n var fFound = false;\n var addr = this.mapBreakpoint(this.getAddr(dbgAddr));\n for (var i = 1; i < aBreak.length; i++) {\n var dbgAddrBreak = aBreak[i];\n if (addr !== X86.ADDR_INVALID && addr == this.mapBreakpoint(this.getAddr(dbgAddrBreak)) ||\n addr === X86.ADDR_INVALID && dbgAddr.sel == dbgAddrBreak.sel && dbgAddr.off == dbgAddrBreak.off) {\n if (!fTempBreak || dbgAddrBreak.fTempBreak) {\n fFound = true;\n if (fRemove) {\n if (!dbgAddrBreak.fTempBreak && !fQuiet) {\n this.printBreakpoint(aBreak, i, \"cleared\");\n }\n aBreak.splice(i, 1);\n if (aBreak != this.aBreakExec) {\n this.cpu.removeMemBreak(addr, aBreak == this.aBreakWrite, dbgAddrBreak.type == DebuggerX86.ADDRTYPE.PHYSICAL);\n }\n /*\n * We'll mirror the logic in addBreakpoint() and leave the history buffer alone if this\n * was a temporary breakpoint.\n */\n if (!dbgAddrBreak.fTempBreak) {\n this.historyInit();\n }\n break;\n }\n if (!fQuiet) this.printBreakpoint(aBreak, i, \"exists\");\n break;\n }\n }\n }\n return fFound;\n }\n\n /**\n * listBreakpoints(aBreak)\n *\n * @this {DebuggerX86}\n * @param {Array} aBreak\n * @return {number} of breakpoints listed, 0 if none\n */\n listBreakpoints(aBreak)\n {\n for (var i = 1; i < aBreak.length; i++) {\n this.printBreakpoint(aBreak, i);\n }\n return aBreak.length - 1;\n }\n\n /**\n * printBreakpoint(aBreak, i, sAction)\n *\n * TODO: We may need to start printing linear addresses also (if any), because segmented address can be ambiguous.\n *\n * @this {DebuggerX86}\n * @param {Array} aBreak\n * @param {number} i\n * @param {string} [sAction]\n */\n printBreakpoint(aBreak, i, sAction)\n {\n var dbgAddr = aBreak[i];\n this.println(aBreak[0] + ' ' + this.toHexAddr(dbgAddr) + (sAction? (' ' + sAction) : (dbgAddr.sCmd? (' \"' + dbgAddr.sCmd + '\"') : '')));\n }\n\n /**\n * restoreBreakpoints(aBreak, aDbgAddr)\n *\n * @this {DebuggerX86}\n * @param {Array} aBreak\n * @param {Array} aDbgAddr\n */\n restoreBreakpoints(aBreak, aDbgAddr)\n {\n if (aDbgAddr[0] != aBreak[0]) return;\n for (var i = 1; i < aDbgAddr.length; i++) {\n var dbgAddr = aDbgAddr[i];\n this.addBreakpoint(aBreak, dbgAddr, dbgAddr.fTempBreak, true);\n }\n }\n\n /**\n * setTempBreakpoint(dbgAddr)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr of new temp breakpoint\n */\n setTempBreakpoint(dbgAddr)\n {\n this.addBreakpoint(this.aBreakExec, dbgAddr, true);\n }\n\n /**\n * clearTempBreakpoint(addr)\n *\n * @this {DebuggerX86}\n * @param {number|undefined} [addr] clear all temp breakpoints if no address specified\n */\n clearTempBreakpoint(addr)\n {\n if (addr !== undefined) {\n this.checkBreakpoint(addr, 1, this.aBreakExec, true);\n this.nStep = 0;\n } else {\n for (var i = 1; i < this.aBreakExec.length; i++) {\n var dbgAddrBreak = this.aBreakExec[i];\n if (dbgAddrBreak.fTempBreak) {\n if (!this.findBreakpoint(this.aBreakExec, dbgAddrBreak, true, true)) break;\n i = 0;\n }\n }\n }\n }\n\n /**\n * mapBreakpoint(addr)\n *\n * @this {DebuggerX86}\n * @param {number} addr\n * @return {number}\n */\n mapBreakpoint(addr)\n {\n /*\n * Map addresses in the top 64Kb at the top of the address space (assuming either a 16Mb or 4Gb\n * address space) to the top of the 1Mb range.\n *\n * The fact that those two 64Kb regions are aliases of each other on an 80286 is a pain in the BUTT,\n * because any CS-based breakpoint you set immediately after a CPU reset will have a physical address\n * in the top 16Mb, yet after the first inter-segment JMP, you will be running in the first 1Mb.\n */\n if (addr !== X86.ADDR_INVALID) {\n var mask = (this.maskAddr & ~0xffff);\n if ((addr & mask) == mask) addr &= 0x000fffff;\n }\n return addr;\n }\n\n /**\n * checkBreakpoint(addr, nb, aBreak, fTempBreak)\n *\n * @this {DebuggerX86}\n * @param {number} addr\n * @param {number} nb (# of bytes)\n * @param {Array} aBreak\n * @param {boolean} [fTempBreak]\n * @return {boolean} true if breakpoint has been hit, false if not\n */\n checkBreakpoint(addr, nb, aBreak, fTempBreak)\n {\n /*\n * Time to check for execution breakpoints; note that this should be done BEFORE updating frequency\n * or history data (see checkInstruction), since we might not actually execute the current instruction.\n */\n var fBreak = false;\n\n if (!this.nSuppressBreaks++) {\n\n addr = this.mapBreakpoint(addr);\n\n /*\n * As discussed in opINT3(), I decided to check for INT3 instructions here: we'll tell the CPU to\n * stop on INT3 whenever both the INT and HALT message bits are set; a simple \"g\" command allows you\n * to continue.\n */\n if (this.messageEnabled(Messages.INT | Messages.HALT)) {\n if (this.cpu.probeAddr(addr) == X86.OPCODE.INT3) {\n fBreak = true;\n }\n }\n\n for (var i = 1; !fBreak && i < aBreak.length; i++) {\n\n var dbgAddrBreak = aBreak[i];\n\n if (fTempBreak && !dbgAddrBreak.fTempBreak) continue;\n\n /*\n * We need to zap the linear address field of the breakpoint address before\n * calling getAddr(), to force it to recalculate the linear address every time,\n * unless this is a breakpoint on a linear address (as indicated by a null sel).\n */\n if (dbgAddrBreak.sel != null) dbgAddrBreak.addr = null;\n\n /*\n * We used to calculate the linear address of the breakpoint at the time the\n * breakpoint was added, so that a breakpoint set in one mode (eg, in real-mode)\n * would still work as intended if the mode changed later (eg, to protected-mode).\n *\n * However, that created difficulties setting protected-mode breakpoints in segments\n * that might not be defined yet, or that could move in physical memory.\n *\n * If you want to create a real-mode breakpoint that will break regardless of mode,\n * use the physical address of the real-mode memory location instead.\n */\n var addrBreak = this.mapBreakpoint(this.getAddr(dbgAddrBreak));\n for (var n = 0; n < nb; n++) {\n if (addr + n == addrBreak) {\n var a;\n fBreak = true;\n if (dbgAddrBreak.fTempBreak) {\n this.findBreakpoint(aBreak, dbgAddrBreak, true, true);\n fTempBreak = true;\n }\n if (a = dbgAddrBreak.aCmds) {\n /*\n * When one or more commands are attached to a breakpoint, we don't halt by default.\n * Instead, we set fBreak to true only if, at the completion of all the commands, the\n * CPU is halted; in other words, you should include \"h\" as one of the breakpoint commands\n * if you want the breakpoint to stop execution.\n *\n * Another useful command is \"if\", which will return false if the expression is false,\n * at which point we'll jump ahead to the next \"else\" command, and if there isn't an \"else\",\n * we abort.\n */\n fBreak = false;\n for (var j = 0; j < a.length; j++) {\n if (!this.doCommand(a[j], true)) {\n if (a[j].indexOf(\"if\")) {\n fBreak = true; // the failed command wasn't \"if\", so abort\n break;\n }\n var k = j + 1;\n for (; k < a.length; k++) {\n if (!a[k].indexOf(\"else\")) break;\n j++;\n }\n if (k == a.length) { // couldn't find an \"else\" after the \"if\", so abort\n fBreak = true;\n break;\n }\n /*\n * If we're still here, we'll execute the \"else\" command (which is just a no-op),\n * followed by any remaining commands.\n */\n }\n }\n if (!this.cpu.isRunning()) fBreak = true;\n }\n if (fBreak) {\n if (!fTempBreak) this.printBreakpoint(aBreak, i, \"hit\");\n break;\n }\n }\n }\n }\n }\n\n this.nSuppressBreaks--;\n\n return fBreak;\n }\n\n /**\n * getInstruction(dbgAddr, sComment, nSequence)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {string} [sComment] is an associated comment\n * @param {number|null} [nSequence] is an associated sequence number, null or undefined if none\n * @return {string} (and dbgAddr is updated to the next instruction)\n */\n getInstruction(dbgAddr, sComment, nSequence)\n {\n var dbgAddrIns = this.newAddr(dbgAddr.off, dbgAddr.sel, dbgAddr.addr, dbgAddr.type);\n\n var bOpcode = this.getByte(dbgAddr, 1);\n\n /*\n * Incorporate OPERAND and ADDRESS size prefixes into the current instruction.\n *\n * And the verdict is in: redundant OPERAND and ADDRESS prefixes must be ignored;\n * see opOS() and opAS() for details. We limit the amount of redundancy to something\n * reasonable (ie, 4).\n */\n var cMaxOverrides = 4, cOverrides = 0;\n var fDataPrefix = false, fAddrPrefix = false;\n\n while ((bOpcode == X86.OPCODE.OS || bOpcode == X86.OPCODE.AS) && cMaxOverrides--) {\n if (bOpcode == X86.OPCODE.OS) {\n if (!fDataPrefix) {\n dbgAddr.fData32 = !dbgAddr.fData32;\n fDataPrefix = true;\n }\n cOverrides++;\n } else {\n if (!fAddrPrefix) {\n dbgAddr.fAddr32 = !dbgAddr.fAddr32;\n fAddrPrefix = true;\n }\n cOverrides++;\n }\n bOpcode = this.getByte(dbgAddr, 1);\n }\n\n var bModRM = -1;\n var asOpcodes = DebuggerX86.INS_NAMES;\n var aOpDesc = this.aaOpDescs[bOpcode];\n var iIns = aOpDesc[0];\n\n if (iIns == DebuggerX86.INS.OP0F) {\n var b = this.getByte(dbgAddr, 1);\n aOpDesc = DebuggerX86.aaOp0FDescs[b] || DebuggerX86.aOpDescUndefined;\n bOpcode |= (b << 8);\n iIns = aOpDesc[0];\n }\n\n if (iIns == DebuggerX86.INS.ESC) {\n bModRM = this.getByte(dbgAddr, 1);\n var aOpFPUDesc = this.getFPUInstruction(bOpcode, bModRM);\n if (aOpFPUDesc) {\n asOpcodes = DebuggerX86.FINS_NAMES;\n aOpDesc = aOpFPUDesc;\n iIns = aOpDesc[0];\n }\n }\n\n if (iIns >= asOpcodes.length) {\n bModRM = this.getByte(dbgAddr, 1);\n aOpDesc = DebuggerX86.aaGrpDescs[iIns - asOpcodes.length][(bModRM >> 3) & 0x7];\n iIns = aOpDesc[0];\n }\n\n var sOpcode = asOpcodes[iIns];\n var cOperands = aOpDesc.length - 1;\n var sOperands = \"\";\n\n if (dbgAddr.fData32) {\n if (iIns == DebuggerX86.INS.CBW) {\n sOpcode = \"CWDE\"; // sign-extend AX into EAX, instead of AL into AX\n }\n else if (iIns == DebuggerX86.INS.CWD) {\n sOpcode = \"CDQ\"; // sign-extend EAX into EDX:EAX, instead of AX into DX:AX\n }\n else if (iIns >= DebuggerX86.INS.POPA && iIns <= DebuggerX86.INS.PUSHA) {\n sOpcode += 'D'; // transform POPA/POPF/PUSHF/PUSHA to POPAD/POPFD/PUSHFD/PUSHAD as appropriate\n }\n }\n if (this.isStringIns(bOpcode)) {\n cOperands = 0; // suppress operands for string instructions, and add 'D' suffix as appropriate\n if (dbgAddr.fData32 && sOpcode.slice(-1) == 'W') sOpcode = sOpcode.slice(0, -1) + 'D';\n }\n\n var typeCPU = -1;\n var fComplete = true;\n\n for (var iOperand = 1; iOperand <= cOperands; iOperand++) {\n\n var disp, off, cch;\n var sOperand = \"\";\n var type = aOpDesc[iOperand];\n if (type === undefined) continue;\n\n if (typeCPU < 0) typeCPU = type >> DebuggerX86.TYPE_CPU_SHIFT;\n\n if (iIns == DebuggerX86.INS.LOADALL) {\n if (typeCPU == DebuggerX86.CPU_80286) {\n sOperands = \"[%800]\";\n } else if (typeCPU == DebuggerX86.CPU_80386) {\n sOperands = \"ES:[\" + (dbgAddr.fAddr32? 'E':'') + \"DI]\";\n }\n }\n\n var typeSize = type & DebuggerX86.TYPE_SIZE;\n if (typeSize == DebuggerX86.TYPE_NONE) {\n continue;\n }\n if (typeSize == DebuggerX86.TYPE_PREFIX) {\n fComplete = false;\n continue;\n }\n var typeMode = type & DebuggerX86.TYPE_MODE;\n if (typeMode >= DebuggerX86.TYPE_MODRM) {\n if (bModRM < 0) {\n bModRM = this.getByte(dbgAddr, 1);\n }\n if (typeMode < DebuggerX86.TYPE_MODREG) {\n /*\n * This test also encompasses TYPE_MODMEM, which is basically the inverse of the case\n * below (ie, only Mod values *other* than 11 are allowed); however, I believe that in\n * some cases that's merely a convention, and that if you try to execute an instruction\n * like \"LEA AX,BX\", it will actually do something (on some if not all processors), so\n * there's probably some diagnostic value in allowing those cases to be disassembled.\n */\n sOperand = this.getModRMOperand(sOpcode, bModRM, type, cOperands, dbgAddr);\n }\n else if (typeMode == DebuggerX86.TYPE_MODREG) {\n /*\n * TYPE_MODREG instructions assume that Mod is 11 (only certain early 80486 steppings\n * actually *required* that Mod contain 11) and always treat RM as a register (which we\n * could also simulate by setting Mod to 11 and letting getModRMOperand() do its thing).\n */\n sOperand = this.getRegOperand(bModRM & 0x7, type, dbgAddr);\n }\n else {\n /*\n * All remaining cases are register-based (eg, TYPE_REG); getRegOperand() will figure out which.\n */\n sOperand = this.getRegOperand((bModRM >> 3) & 0x7, type, dbgAddr);\n }\n }\n else if (typeMode == DebuggerX86.TYPE_ONE) {\n sOperand = '1';\n }\n else if (typeMode == DebuggerX86.TYPE_IMM) {\n sOperand = this.getImmOperand(type, dbgAddr);\n }\n else if (typeMode == DebuggerX86.TYPE_IMMOFF) {\n if (!dbgAddr.fAddr32) {\n cch = 4;\n off = this.getShort(dbgAddr, 2);\n } else {\n cch = 8;\n off = this.getLong(dbgAddr, 4);\n }\n sOperand = '[' + Str.toHex(off, cch) + ']';\n }\n else if (typeMode == DebuggerX86.TYPE_IMMREL) {\n if (typeSize == DebuggerX86.TYPE_BYTE) {\n disp = ((this.getByte(dbgAddr, 1) << 24) >> 24);\n }\n else {\n disp = this.getWord(dbgAddr, true);\n }\n off = (dbgAddr.off + disp) & (dbgAddr.fData32? -1 : 0xffff);\n sOperand = Str.toHex(off, dbgAddr.fData32? 8: 4);\n var aSymbol = this.findSymbol(this.newAddr(off, dbgAddr.sel));\n if (aSymbol[0]) sOperand += \" (\" + aSymbol[0] + \")\";\n }\n else if (typeMode == DebuggerX86.TYPE_IMPREG) {\n if (typeSize == DebuggerX86.TYPE_ST) {\n sOperand = \"ST\";\n } else if (typeSize == DebuggerX86.TYPE_STREG) {\n sOperand = \"ST(\" + (bModRM & 0x7) + \")\";\n } else {\n sOperand = this.getRegOperand((type & DebuggerX86.TYPE_IREG) >> 8, type, dbgAddr);\n }\n }\n else if (typeMode == DebuggerX86.TYPE_IMPSEG) {\n sOperand = this.getRegOperand((type & DebuggerX86.TYPE_IREG) >> 8, DebuggerX86.TYPE_SEGREG, dbgAddr);\n }\n else if (typeMode == DebuggerX86.TYPE_DSSI) {\n sOperand = \"DS:[SI]\";\n }\n else if (typeMode == DebuggerX86.TYPE_ESDI) {\n sOperand = \"ES:[DI]\";\n }\n if (!sOperand || !sOperand.length) {\n sOperands = \"INVALID\";\n break;\n }\n if (sOperands.length > 0) sOperands += ',';\n sOperands += (sOperand || \"???\");\n }\n\n var sBytes = \"\";\n var sLine = this.toHexAddr(dbgAddrIns) + ' ';\n if (dbgAddrIns.addr !== X86.ADDR_INVALID && dbgAddr.addr !== X86.ADDR_INVALID) {\n do {\n sBytes += Str.toHex(this.getByte(dbgAddrIns, 1), 2);\n if (dbgAddrIns.addr == null) break;\n } while (dbgAddrIns.addr != dbgAddr.addr);\n }\n\n sLine += Str.pad(sBytes, dbgAddrIns.fAddr32? 25 : 17);\n sLine += Str.pad(sOpcode, 8);\n if (sOperands) sLine += ' ' + sOperands;\n\n if (this.cpu.model < DebuggerX86.CPUS[typeCPU]) {\n sComment = DebuggerX86.CPUS[typeCPU] + \" CPU only\";\n }\n\n if (sComment && fComplete) {\n sLine = Str.pad(sLine, dbgAddrIns.fAddr32? 74 : 62) + ';' + sComment;\n if (!this.cpu.flags.checksum) {\n sLine += (nSequence != null? '=' + nSequence.toString() : \"\");\n } else {\n var nCycles = this.cpu.getCycles();\n sLine += \"cycles=\" + nCycles.toString() + \" cs=\" + Str.toHex(this.cpu.counts.nChecksum);\n }\n }\n\n this.initAddrSize(dbgAddr, fComplete, cOverrides);\n return sLine;\n }\n\n /**\n * getFPUInstruction(bOpcode, bModRM)\n *\n * @this {DebuggerX86}\n * @param {number} bOpcode\n * @param {number} bModRM\n * @return {Array|null} (FPU instruction group, or null if none)\n */\n getFPUInstruction(bOpcode, bModRM)\n {\n var aOpDesc = null;\n\n var mod = (bModRM >> 6) & 0x3;\n var reg = (bModRM >> 3) & 0x7;\n var r_m = (bModRM & 0x7);\n\n /*\n * Similar to how opFPU() decodes FPU instructions, we combine mod and reg into one\n * decodable value: put mod in the high nibble and reg in the low nibble, after first\n * collapsing all mod values < 3 to zero.\n */\n var modReg = (mod < 3? 0 : 0x30) + reg;\n\n /*\n * All values >= 0x34 imply mod == 3 and reg >= 4, so now we shift reg into the high\n * nibble and r_m into the low, yielding values >= 0x40.\n */\n if ((bOpcode == X86.OPCODE.ESC1 || bOpcode == X86.OPCODE.ESC3) && modReg >= 0x34) {\n modReg = (reg << 4) | r_m;\n }\n\n var aaOpDesc = DebuggerX86.aaaOpFPUDescs[bOpcode];\n if (aaOpDesc) aOpDesc = aaOpDesc[modReg];\n\n return aOpDesc;\n }\n\n /**\n * getImmOperand(type, dbgAddr)\n *\n * @this {DebuggerX86}\n * @param {number} type\n * @param {DbgAddrX86} dbgAddr\n * @return {string} operand\n */\n getImmOperand(type, dbgAddr)\n {\n var sOperand = ' ';\n var typeSize = type & DebuggerX86.TYPE_SIZE;\n\n switch (typeSize) {\n case DebuggerX86.TYPE_BYTE:\n /*\n * There's the occasional immediate byte we don't need to display (eg, the 0x0A\n * following an AAM or AAD instruction), so we suppress the byte if it lacks a TYPE_IN\n * or TYPE_OUT designation (and TYPE_BOTH, as the name implies, includes both).\n */\n if (type & DebuggerX86.TYPE_BOTH) {\n sOperand = Str.toHex(this.getByte(dbgAddr, 1), 2);\n }\n break;\n case DebuggerX86.TYPE_SBYTE:\n sOperand = Str.toHex((this.getByte(dbgAddr, 1) << 24) >> 24, dbgAddr.fData32? 8: 4);\n break;\n case DebuggerX86.TYPE_WORD:\n if (dbgAddr.fData32) {\n sOperand = Str.toHex(this.getLong(dbgAddr, 4));\n break;\n }\n /* falls through */\n case DebuggerX86.TYPE_SHORT:\n sOperand = Str.toHex(this.getShort(dbgAddr, 2), 4);\n break;\n case DebuggerX86.TYPE_FARP:\n dbgAddr = this.newAddr(this.getWord(dbgAddr, true), this.getShort(dbgAddr, 2), null, dbgAddr.type, dbgAddr.fData32, dbgAddr.fAddr32);\n sOperand = this.toHexAddr(dbgAddr);\n var aSymbol = this.findSymbol(dbgAddr);\n if (aSymbol[0]) sOperand += \" (\" + aSymbol[0] + \")\";\n break;\n default:\n sOperand = \"imm(\" + Str.toHexWord(type) + ')';\n break;\n }\n return sOperand;\n }\n\n /**\n * getRegOperand(bReg, type, dbgAddr)\n *\n * @this {DebuggerX86}\n * @param {number} bReg\n * @param {number} type\n * @param {DbgAddrX86} dbgAddr\n * @return {string} operand\n */\n getRegOperand(bReg, type, dbgAddr)\n {\n var typeMode = type & DebuggerX86.TYPE_MODE;\n if (typeMode == DebuggerX86.TYPE_SEGREG) {\n if (bReg > DebuggerX86.REG_GS ||\n bReg >= DebuggerX86.REG_FS && this.cpu.model < X86.MODEL_80386) return \"??\";\n bReg += DebuggerX86.REG_SEG;\n }\n else if (typeMode == DebuggerX86.TYPE_CTLREG) {\n bReg += DebuggerX86.REG_CR0;\n }\n else if (typeMode == DebuggerX86.TYPE_DBGREG) {\n bReg += DebuggerX86.REG_DR0;\n }\n else if (typeMode == DebuggerX86.TYPE_TSTREG) {\n bReg += DebuggerX86.REG_TR0;\n }\n else {\n var typeSize = type & DebuggerX86.TYPE_SIZE;\n if (typeSize >= DebuggerX86.TYPE_SHORT) {\n if (bReg < DebuggerX86.REG_AX) {\n bReg += DebuggerX86.REG_AX - DebuggerX86.REG_AL;\n }\n if (typeSize == DebuggerX86.TYPE_LONG || typeSize == DebuggerX86.TYPE_WORD && dbgAddr.fData32) {\n bReg += DebuggerX86.REG_EAX - DebuggerX86.REG_AX;\n }\n }\n }\n return DebuggerX86.REGS[bReg];\n }\n\n /**\n * getSIBOperand(bMod, dbgAddr)\n *\n * @this {DebuggerX86}\n * @param {number} bMod\n * @param {DbgAddrX86} dbgAddr\n * @return {string} operand\n */\n getSIBOperand(bMod, dbgAddr)\n {\n var bSIB = this.getByte(dbgAddr, 1);\n var bScale = bSIB >> 6;\n var bIndex = (bSIB >> 3) & 0x7;\n var bBase = bSIB & 0x7;\n var sOperand = \"\";\n /*\n * Unless bMod is zero AND bBase is 5, there's always a base register.\n */\n if (bMod || bBase != 5) {\n sOperand = DebuggerX86.RMS[bBase + 8];\n }\n if (bIndex != 4) {\n if (sOperand) sOperand += '+';\n sOperand += DebuggerX86.RMS[bIndex + 8];\n if (bScale) sOperand += '*' + (0x1 << bScale);\n }\n /*\n * If bMod is zero AND bBase is 5, there's a 32-bit displacement instead of a base register.\n */\n if (!bMod && bBase == 5) {\n if (sOperand) sOperand += '+';\n sOperand += Str.toHex(this.getLong(dbgAddr, 4));\n }\n return sOperand;\n }\n\n /**\n * getModRMOperand(sOpcode, bModRM, type, cOperands, dbgAddr)\n *\n * @this {DebuggerX86}\n * @param {string} sOpcode\n * @param {number} bModRM\n * @param {number} type\n * @param {number} cOperands (if 1, memory operands are prefixed with the size; otherwise, size can be inferred)\n * @param {DbgAddrX86} dbgAddr\n * @return {string} operand\n */\n getModRMOperand(sOpcode, bModRM, type, cOperands, dbgAddr)\n {\n var sOperand = \"\";\n var bMod = bModRM >> 6;\n var bRM = bModRM & 0x7;\n if (bMod < 3) {\n var disp;\n var fInteger = (sOpcode.indexOf(\"FI\") == 0);\n if (!bMod && (!dbgAddr.fAddr32 && bRM == 6 || dbgAddr.fAddr32 && bRM == 5)) {\n bMod = 2;\n } else {\n if (dbgAddr.fAddr32) {\n if (bRM != 4) {\n bRM += 8;\n } else {\n sOperand = this.getSIBOperand(bMod, dbgAddr);\n }\n }\n if (!sOperand) sOperand = DebuggerX86.RMS[bRM];\n }\n if (bMod == 1) {\n disp = this.getByte(dbgAddr, 1);\n if (!(disp & 0x80)) {\n sOperand += '+' + Str.toHex(disp, 2);\n }\n else {\n disp = ((disp << 24) >> 24);\n sOperand += '-' + Str.toHex(-disp, 2);\n }\n }\n else if (bMod == 2) {\n if (sOperand) sOperand += '+';\n if (!dbgAddr.fAddr32) {\n disp = this.getShort(dbgAddr, 2);\n sOperand += Str.toHex(disp, 4);\n } else {\n disp = this.getLong(dbgAddr, 4);\n sOperand += Str.toHex(disp);\n }\n }\n sOperand = '[' + sOperand + ']';\n if (cOperands == 1) {\n var sPrefix = \"\";\n type &= DebuggerX86.TYPE_SIZE;\n if (type == DebuggerX86.TYPE_WORD) {\n type = (dbgAddr.fData32? DebuggerX86.TYPE_LONG : DebuggerX86.TYPE_SHORT);\n }\n switch(type) {\n case DebuggerX86.TYPE_FARP:\n sPrefix = \"FAR\";\n break;\n case DebuggerX86.TYPE_BYTE:\n sPrefix = \"BYTE\";\n break;\n case DebuggerX86.TYPE_SHORT:\n if (fInteger) {\n sPrefix = \"INT16\";\n break;\n }\n /* falls through */\n sPrefix = \"WORD\";\n break;\n case DebuggerX86.TYPE_LONG:\n sPrefix = \"DWORD\";\n break;\n case DebuggerX86.TYPE_SINT:\n if (fInteger) {\n sPrefix = \"INT32\";\n break;\n }\n /* falls through */\n case DebuggerX86.TYPE_SREAL:\n sPrefix = \"REAL32\";\n break;\n case DebuggerX86.TYPE_LINT:\n if (fInteger) {\n sPrefix = \"INT64\";\n break;\n }\n /* falls through */\n case DebuggerX86.TYPE_LREAL:\n sPrefix = \"REAL64\";\n break;\n case DebuggerX86.TYPE_TREAL:\n sPrefix = \"REAL80\";\n break;\n case DebuggerX86.TYPE_BCD80:\n sPrefix = \"BCD80\";\n break;\n }\n if (sPrefix) sOperand = sPrefix + ' ' + sOperand;\n }\n }\n else {\n sOperand = this.getRegOperand(bRM, type, dbgAddr);\n }\n return sOperand;\n }\n\n /**\n * parseInstruction(sOp, sOperand, addr)\n *\n * TODO: Unimplemented. See parseInstruction() in modules/c1pjs/lib/debugger.js for a working implementation.\n *\n * @this {DebuggerX86}\n * @param {string} sOp\n * @param {string|undefined} sOperand\n * @param {DbgAddrX86} dbgAddr of memory where this instruction is being assembled\n * @return {Array.<number>} of opcode bytes; if the instruction can't be parsed, the array will be empty\n */\n parseInstruction(sOp, sOperand, dbgAddr)\n {\n var aOpBytes = [];\n this.println(\"not supported yet\");\n return aOpBytes;\n }\n\n /**\n * getFlagOutput(sFlag)\n *\n * @this {DebuggerX86}\n * @param {string} sFlag\n * @return {string} value of flag\n */\n getFlagOutput(sFlag)\n {\n var b;\n switch (sFlag) {\n case 'V':\n b = this.cpu.getOF();\n break;\n case 'D':\n b = this.cpu.getDF();\n break;\n case 'I':\n b = this.cpu.getIF();\n break;\n case 'T':\n b = this.cpu.getTF();\n break;\n case 'S':\n b = this.cpu.getSF();\n break;\n case 'Z':\n b = this.cpu.getZF();\n break;\n case 'A':\n b = this.cpu.getAF();\n break;\n case 'P':\n b = this.cpu.getPF();\n break;\n case 'C':\n b = this.cpu.getCF();\n break;\n default:\n b = 0;\n break;\n }\n return sFlag + (b? '1' : '0') + ' ';\n }\n\n /**\n * getLimitString(l)\n *\n * @this {DebuggerX86}\n * @param {number} l\n * @return {string}\n */\n getLimitString(l)\n {\n return Str.toHex(l, (l & ~0xffff)? 8 : 4);\n }\n\n /**\n * getRegOutput(iReg)\n *\n * @this {DebuggerX86}\n * @param {number} iReg\n * @return {string}\n */\n getRegOutput(iReg)\n {\n if (iReg >= DebuggerX86.REG_AX && iReg <= DebuggerX86.REG_DI && this.cchReg > 4) iReg += DebuggerX86.REG_EAX - DebuggerX86.REG_AX;\n var sReg = DebuggerX86.REGS[iReg];\n if (iReg == DebuggerX86.REG_CR0 && this.cpu.model == X86.MODEL_80286) sReg = \"MS\";\n return sReg + '=' + this.getRegString(iReg) + ' ';\n }\n\n /**\n * getSegOutput(seg, fProt)\n *\n * @this {DebuggerX86}\n * @param {SegX86} seg\n * @param {boolean} [fProt]\n * @return {string}\n */\n getSegOutput(seg, fProt)\n {\n return seg.sName + '=' + Str.toHex(seg.sel, 4) + (fProt? '[' + Str.toHex(seg.base, this.cchAddr) + ',' + this.getLimitString(seg.limit) + ']' : \"\");\n }\n\n /**\n * getDTROutput(sName, sel, addr, addrLimit)\n *\n * @this {DebuggerX86}\n * @param {string} sName\n * @param {number|null|*} sel\n * @param {number} addr\n * @param {number} addrLimit\n * @return {string}\n */\n getDTROutput(sName, sel, addr, addrLimit)\n {\n return sName + '=' + (sel != null? Str.toHex(sel, 4) : \"\") + '[' + Str.toHex(addr, this.cchAddr) + ',' + Str.toHex(addrLimit - addr, 4) + ']';\n }\n\n /**\n * getRegDump(fProt)\n *\n * Sample 8086 and 80286 real-mode register dump:\n *\n * AX=0000 BX=0000 CX=0000 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000\n * SS=0000 DS=0000 ES=0000 PS=0002 V0 D0 I0 T0 S0 Z0 A0 P0 C0\n * F000:FFF0 EA5BE000F0 JMP F000:E05B\n *\n * Sample 80386 real-mode register dump:\n *\n * EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000000\n * ESP=00000000 EBP=00000000 ESI=00000000 EDI=00000000\n * SS=0000 DS=0000 ES=0000 FS=0000 GS=0000 PS=00000002 V0 D0 I0 T0 S0 Z0 A0 P0 C0\n * F000:FFF0 EA05F900F0 JMP F000:F905\n *\n * Sample 80286 protected-mode register dump:\n *\n * AX=0000 BX=0000 CX=0000 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000\n * SS=0000[000000,FFFF] DS=0000[000000,FFFF] ES=0000[000000,FFFF] A20=ON\n * CS=F000[FF0000,FFFF] LD=0000[000000,FFFF] GD=[000000,FFFF] ID=[000000,03FF]\n * TR=0000 MS=FFF0 PS=0002 V0 D0 I0 T0 S0 Z0 A0 P0 C0\n * F000:FFF0 EA5BE000F0 JMP F000:E05B\n *\n * Sample 80386 protected-mode register dump:\n *\n * EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000000\n * ESP=00000000 EBP=00000000 ESI=00000000 EDI=00000000\n * SS=0000[00000000,FFFF] DS=0000[00000000,FFFF] ES=0000[00000000,FFFF]\n * CS=F000[FFFF0000,FFFF] FS=0000[00000000,FFFF] GS=0000[00000000,FFFF]\n * LD=0000[00000000,FFFF] GD=[00000000,FFFF] ID=[00000000,03FF] TR=0000 A20=ON\n * CR0=00000010 CR2=00000000 CR3=00000000 PS=00000002 V0 D0 I0 T0 S0 Z0 A0 P0 C0\n * F000:0000FFF0 EA05F900F0 JMP F000:0000F905\n *\n * This no longer includes CS in real-mode (or EIP in any mode), because that information can be obtained from the\n * first line of disassembly, which an \"r\" or \"rp\" command will also display.\n *\n * Note that even when the processor is in real mode, you can always use the \"rp\" command to force a protected-mode\n * dump, in case you need to verify any selector base or limit values, since those also affect real-mode operation.\n *\n * @this {DebuggerX86}\n * @param {boolean} [fProt]\n * @return {string}\n */\n getRegDump(fProt)\n {\n var s;\n if (fProt === undefined) fProt = this.getCPUMode();\n\n s = this.getRegOutput(DebuggerX86.REG_AX) +\n this.getRegOutput(DebuggerX86.REG_BX) +\n this.getRegOutput(DebuggerX86.REG_CX) +\n this.getRegOutput(DebuggerX86.REG_DX) + (this.cchReg > 4? '\\n' : '') +\n this.getRegOutput(DebuggerX86.REG_SP) +\n this.getRegOutput(DebuggerX86.REG_BP) +\n this.getRegOutput(DebuggerX86.REG_SI) +\n this.getRegOutput(DebuggerX86.REG_DI) + '\\n' +\n this.getSegOutput(this.cpu.segSS, fProt) + ' ' +\n this.getSegOutput(this.cpu.segDS, fProt) + ' ' +\n this.getSegOutput(this.cpu.segES, fProt) + ' ';\n\n if (fProt) {\n var sTR = \"TR=\" + Str.toHex(this.cpu.segTSS.sel, 4);\n var sA20 = \"A20=\" + (this.bus.getA20()? \"ON \" : \"OFF \");\n if (this.cpu.model < X86.MODEL_80386) {\n sTR = '\\n' + sTR;\n s += sA20; sA20 = '';\n }\n s += '\\n' + this.getSegOutput(this.cpu.segCS, fProt) + ' ';\n if (I386 && this.cpu.model >= X86.MODEL_80386) {\n sA20 += '\\n';\n s += this.getSegOutput(this.cpu.segFS, fProt) + ' ' +\n this.getSegOutput(this.cpu.segGS, fProt) + '\\n';\n }\n s += this.getDTROutput(\"LD\", this.cpu.segLDT.sel, this.cpu.segLDT.base, this.cpu.segLDT.base + this.cpu.segLDT.limit) + ' ' +\n this.getDTROutput(\"GD\", null, this.cpu.addrGDT, this.cpu.addrGDTLimit) + ' ' +\n this.getDTROutput(\"ID\", null, this.cpu.addrIDT, this.cpu.addrIDTLimit) + ' ';\n s += sTR + ' ' + sA20;\n s += this.getRegOutput(DebuggerX86.REG_CR0);\n if (I386 && this.cpu.model >= X86.MODEL_80386) {\n s += this.getRegOutput(DebuggerX86.REG_CR2) + this.getRegOutput(DebuggerX86.REG_CR3);\n }\n } else {\n if (I386 && this.cpu.model >= X86.MODEL_80386) {\n s += this.getSegOutput(this.cpu.segFS, fProt) + ' ' +\n this.getSegOutput(this.cpu.segGS, fProt) + ' ';\n }\n }\n\n s += this.getRegOutput(DebuggerX86.REG_PS) +\n this.getFlagOutput('V') + this.getFlagOutput('D') + this.getFlagOutput('I') + this.getFlagOutput('T') +\n this.getFlagOutput('S') + this.getFlagOutput('Z') + this.getFlagOutput('A') + this.getFlagOutput('P') + this.getFlagOutput('C');\n\n return s;\n }\n\n /**\n * comparePairs(p1, p2)\n *\n * @this {DebuggerX86}\n * @param {number|string|Array|Object} p1\n * @param {number|string|Array|Object} p2\n * @return {number}\n */\n comparePairs(p1, p2)\n {\n return p1[0] > p2[0]? 1 : p1[0] < p2[0]? -1 : 0;\n }\n\n /**\n * addSymbols(sModule, nSegment, sel, off, addr, len, aSymbols)\n *\n * As filedump.js (formerly convrom.php) explains, aSymbols is a JSON-encoded object whose properties consist\n * of all the symbols (in upper-case), and the values of those properties are objects containing any or all of\n * the following properties:\n *\n * 'v': the value of an absolute (unsized) value\n * 'b': either 1, 2, 4 or undefined if an unsized value\n * 's': either a hard-coded segment or undefined\n * 'o': the offset of the symbol within the associated address space\n * 'l': the original-case version of the symbol, present only if it wasn't originally upper-case\n * 'a': annotation for the specified offset; eg, the original assembly language, with optional comment\n *\n * To that list of properties, we also add:\n *\n * 'p': the physical address (calculated whenever both 's' and 'o' properties are defined)\n *\n * Note that values for any 'v', 'b', 's' and 'o' properties are unquoted decimal values, and the values\n * for any 'l' or 'a' properties are quoted strings. Also, if double-quotes were used in any of the original\n * annotation ('a') values, they will have been converted to two single-quotes, so we're responsible for\n * converting them back to individual double-quotes.\n *\n * For example:\n * {\n * 'HF_PORT': {\n * 'v':800\n * },\n * 'HDISK_INT': {\n * 'b':4, 's':0, 'o':52\n * },\n * 'ORG_VECTOR': {\n * 'b':4, 's':0, 'o':76\n * },\n * 'CMD_BLOCK': {\n * 'b':1, 's':64, 'o':66\n * },\n * 'DISK_SETUP': {\n * 'o':3\n * },\n * '.40': {\n * 'o':40, 'a':\"MOV AX,WORD PTR ORG_VECTOR ;GET DISKETTE VECTOR\"\n * }\n * }\n *\n * If a symbol only has an offset, then that offset value can be assigned to the symbol property directly:\n *\n * 'DISK_SETUP': 3\n *\n * The last property is an example of an \"anonymous\" entry, for offsets where there is no associated symbol.\n * Such entries are identified by a period followed by a unique number (usually the offset of the entry), and\n * they usually only contain offset ('o') and annotation ('a') properties. I could eliminate the leading\n * period, but it offers a very convenient way of quickly discriminating among genuine vs. anonymous symbols.\n *\n * We add all these entries to our internal symbol table, which is an array of 4-element arrays, each of which\n * look like:\n *\n * [sel, off, addr, len, aSymbols, aOffsets]\n *\n * There are two basic symbol operations: findSymbol(), which takes an address and finds the symbol, if any,\n * at that address, and findSymbolAddr(), which takes a string and attempts to match it to a non-anonymous\n * symbol with a matching offset ('o') property.\n *\n * To implement findSymbol() efficiently, addSymbols() creates an array of [offset, sSymbol] pairs\n * (aOffsets), one pair for each symbol that corresponds to an offset within the specified address space.\n *\n * We guarantee the elements of aOffsets are in offset order, because we build it using binaryInsert();\n * it's quite likely that the MAP file already ordered all its symbols in offset order, but since they're\n * hand-edited files, we can't assume that, and we need to ensure that findSymbol()'s binarySearch() operates\n * properly.\n *\n * @this {DebuggerX86}\n * @param {string|null} sModule\n * @param {number} nSegment (zero if undefined)\n * @param {number} sel (the default segment/selector for all symbols in this group)\n * @param {number} off (from the base of the given selector)\n * @param {number|null|*} addr (physical address where the symbols are located, if the memory is physical; eg, ROM)\n * @param {number} len (the size of the region, in bytes)\n * @param {Object} aSymbols (collection of symbols in this group; the format of this collection is described below)\n */\n addSymbols(sModule, nSegment, sel, off, addr, len, aSymbols)\n {\n var dbgAddr = {};\n var aOffsets = [];\n for (var sSymbol in aSymbols) {\n var symbol = aSymbols[sSymbol];\n if (typeof symbol == \"number\") {\n aSymbols[sSymbol] = symbol = {'o': symbol};\n }\n var offSymbol = symbol['o'];\n var selSymbol = symbol['s'];\n var sAnnotation = symbol['a'];\n if (offSymbol !== undefined) {\n if (selSymbol !== undefined) {\n dbgAddr.off = offSymbol;\n dbgAddr.sel = selSymbol;\n dbgAddr.addr = null;\n /*\n * getAddr() computes the corresponding physical address and saves it in dbgAddr.addr.\n */\n this.getAddr(dbgAddr);\n /*\n * The physical address for any symbol located in the top 64Kb of the machine's address space\n * should be relocated to the top 64Kb of the first 1Mb, so that we're immune from any changes\n * to the A20 line.\n */\n if ((dbgAddr.addr & ~0xffff) == (this.bus.nBusLimit & ~0xffff)) {\n dbgAddr.addr &= 0x000fffff;\n }\n symbol['p'] = dbgAddr.addr;\n }\n Usr.binaryInsert(aOffsets, [offSymbol >>> 0, sSymbol], this.comparePairs);\n }\n if (sAnnotation) symbol['a'] = sAnnotation.replace(/''/g, \"\\\"\");\n }\n var symbolTable = {\n sModule: sModule,\n nSegment: nSegment,\n sel: sel,\n off: off,\n addr: addr,\n len: len,\n aSymbols: aSymbols,\n aOffsets: aOffsets\n };\n this.aSymbolTable.push(symbolTable);\n }\n\n /**\n * removeSymbols(sModule, nSegment)\n *\n * @this {DebuggerX86}\n * @param {string|null|*} sModule\n * @param {number} [nSegment] (segment # if sModule set, selector if sModule clear)\n * @return {string|null} name of the module removed, or null if no module was found\n */\n removeSymbols(sModule, nSegment)\n {\n var sModuleRemoved = null;\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n if (sModule && symbolTable.sModule != sModule) continue;\n if (sModule && nSegment == symbolTable.nSegment || !sModule && nSegment == symbolTable.sel) {\n sModuleRemoved = symbolTable.sModule;\n this.aSymbolTable.splice(iTable, 1);\n break;\n }\n }\n return sModuleRemoved;\n }\n\n /**\n * dumpSymbols()\n *\n * TODO: Add \"numerical\" and \"alphabetical\" dump options. This is simply dumping them in whatever\n * order they appeared in the original MAP file.\n *\n * @this {DebuggerX86}\n */\n dumpSymbols()\n {\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n for (var sSymbol in symbolTable.aSymbols) {\n if (sSymbol.charAt(0) == '.') continue;\n var symbol = symbolTable.aSymbols[sSymbol];\n var offSymbol = symbol['o'];\n if (offSymbol === undefined) continue;\n var selSymbol = symbol['s'];\n if (selSymbol === undefined) selSymbol = symbolTable.sel;\n var sSymbolOrig = symbolTable.aSymbols[sSymbol]['l'];\n if (sSymbolOrig) sSymbol = sSymbolOrig;\n this.println(this.toHexOffset(offSymbol, selSymbol) + ' ' + sSymbol);\n }\n }\n }\n\n /**\n * findSymbol(dbgAddr, fNearest)\n *\n * Search aSymbolTable for dbgAddr, and return an Array for the corresponding symbol (empty if not found).\n *\n * If fNearest is true, and no exact match was found, then the Array returned will contain TWO sets of\n * entries: [0]-[3] will refer to closest preceding symbol, and [4]-[7] will refer to the closest subsequent symbol.\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {boolean} [fNearest]\n * @return {Array} where [0] == symbol name, [1] == symbol value, [2] == any annotation, and [3] == any associated comment\n */\n findSymbol(dbgAddr, fNearest)\n {\n var aSymbol = [];\n var offSymbol = dbgAddr.off >>> 0;\n var addrSymbol = this.getAddr(dbgAddr) >>> 0;\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n var sel = symbolTable.sel;\n var off = symbolTable.off >>> 0;\n var addr = symbolTable.addr;\n if (addr != null) addr >>>= 0;\n var len = symbolTable.len;\n if (sel == 0x30) sel = 0x28; // TODO: Remove this hack once we're able to differentiate Windows 95 ring 0 code and data\n if (sel == dbgAddr.sel && offSymbol >= off && offSymbol < off + len || addr != null && addrSymbol >= addr && addrSymbol < addr + len) {\n var result = Usr.binarySearch(symbolTable.aOffsets, [offSymbol], this.comparePairs);\n if (result >= 0) {\n this.returnSymbol(iTable, result, aSymbol);\n }\n else if (fNearest) {\n result = ~result;\n this.returnSymbol(iTable, result-1, aSymbol);\n this.returnSymbol(iTable, result, aSymbol);\n }\n break;\n }\n }\n if (!aSymbol.length) {\n var sSymbol = this.bus.getSymbol(addrSymbol, true);\n if (sSymbol) {\n aSymbol.push(sSymbol);\n aSymbol.push(addrSymbol);\n }\n }\n return aSymbol;\n }\n\n /**\n * findSymbolAddr(sSymbol)\n *\n * Search aSymbolTable for sSymbol, and if found, return a dbgAddr (same as parseAddr())\n *\n * @this {DebuggerX86}\n * @param {string} sSymbol\n * @return {DbgAddrX86|undefined}\n */\n findSymbolAddr(sSymbol)\n {\n var dbgAddr;\n if (sSymbol.match(/^[a-z_][a-z0-9_]*$/i)) {\n var sUpperCase = sSymbol.toUpperCase();\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n var symbol = symbolTable.aSymbols[sUpperCase];\n if (symbol !== undefined) {\n var offSymbol = symbol['o'];\n if (offSymbol !== undefined) {\n /*\n * We assume that every ROM is ORG'ed at 0x0000, and therefore unless the symbol has an\n * explicitly-defined segment, we return the segment associated with the entire group; for\n * a ROM, that segment is normally \"addrROM >>> 4\". Down the road, we may want/need to\n * support a special symbol entry (eg, \".ORG\") that defines an alternate origin.\n */\n var selSymbol = symbol['s'];\n if (selSymbol === undefined) selSymbol = symbolTable.sel;\n dbgAddr = this.newAddr(offSymbol, selSymbol, symbol['p']);\n }\n /*\n * The symbol matched, but it wasn't for an address (no 'o' offset), and there's no point\n * looking any farther, since each symbol appears only once, so we indicate it's an unknown symbol.\n */\n break;\n }\n }\n }\n return dbgAddr;\n }\n\n /**\n * returnSymbol(iTable, iOffset, aSymbol)\n *\n * Helper function for findSymbol().\n *\n * @param {number} iTable\n * @param {number} iOffset\n * @param {Array} aSymbol is updated with the specified symbol, if it exists\n */\n returnSymbol(iTable, iOffset, aSymbol)\n {\n var symbol = {};\n var aOffsets = this.aSymbolTable[iTable].aOffsets;\n var offset = 0, sSymbol = null;\n if (iOffset >= 0 && iOffset < aOffsets.length) {\n offset = aOffsets[iOffset][0];\n sSymbol = aOffsets[iOffset][1];\n }\n if (sSymbol) {\n symbol = this.aSymbolTable[iTable].aSymbols[sSymbol];\n sSymbol = (sSymbol.charAt(0) == '.'? null : (symbol['l'] || sSymbol));\n }\n aSymbol.push(sSymbol);\n aSymbol.push(offset);\n aSymbol.push(symbol['a']);\n aSymbol.push(symbol['c']);\n }\n\n /**\n * doHelp()\n *\n * @this {DebuggerX86}\n */\n doHelp()\n {\n var s = \"commands:\";\n for (var sCommand in DebuggerX86.COMMANDS) {\n s += '\\n' + Str.pad(sCommand, 7) + DebuggerX86.COMMANDS[sCommand];\n }\n if (!this.checksEnabled()) s += \"\\nnote: frequency/history disabled if no exec breakpoints\";\n this.println(s);\n }\n\n /**\n * doAssemble(asArgs)\n *\n * This always receives the complete argument array, where the order of the arguments is:\n *\n * [0]: the assemble command (assumed to be \"a\")\n * [1]: the target address (eg, \"200\")\n * [2]: the operation code, aka instruction name (eg, \"adc\")\n * [3]: the operation mode operand, if any (eg, \"14\", \"[1234]\", etc)\n *\n * The Debugger enters \"assemble mode\" whenever only the first (or first and second) arguments are present.\n * As long as \"assemble mode is active, the user can omit the first two arguments on all later assemble commands\n * until \"assemble mode\" is cancelled with an empty command line; the command processor automatically prepends \"a\"\n * and the next available target address to the argument array.\n *\n * Entering \"assemble mode\" is optional; one could enter a series of fully-qualified assemble commands; eg:\n *\n * a ff00 cld\n * a ff01 ldx 28\n * ...\n *\n * without ever entering \"assemble mode\", but of course, that requires more typing and doesn't take advantage\n * of automatic target address advancement (see dbgAddrAssemble).\n *\n * NOTE: As the previous example implies, you can even assemble new instructions into ROM address space;\n * as our setByte() function explains, the ROM write-notification handlers only refuse writes from the CPU.\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs is the complete argument array, beginning with the \"a\" command in asArgs[0]\n */\n doAssemble(asArgs)\n {\n var dbgAddr = this.parseAddr(asArgs[1], true);\n if (!dbgAddr) return;\n\n this.dbgAddrAssemble = dbgAddr;\n if (asArgs[2] === undefined) {\n this.println(\"begin assemble at \" + this.toHexAddr(dbgAddr));\n this.fAssemble = true;\n this.cpu.updateCPU();\n return;\n }\n\n var aOpBytes = this.parseInstruction(asArgs[2], asArgs[3], dbgAddr);\n if (aOpBytes.length) {\n for (var i = 0; i < aOpBytes.length; i++) {\n this.setByte(dbgAddr, aOpBytes[i], 1);\n }\n /*\n * Since getInstruction() also updates the specified address, dbgAddrAssemble is automatically advanced.\n */\n this.println(this.getInstruction(this.dbgAddrAssemble));\n }\n }\n\n /**\n * doBreak(sCmd, sAddr, sOptions)\n *\n * As the \"help\" output below indicates, the following breakpoint commands are supported:\n *\n * bp [a] set exec breakpoint on linear addr [a]\n * br [a] set read breakpoint on linear addr [a]\n * bw [a] set write breakpoint on linear addr [a]\n * bc [a] clear breakpoint on linear addr [a] (use \"*\" for all breakpoints)\n * bl list breakpoints\n *\n * to which we have recently added the following I/O breakpoint commands:\n *\n * bi [p] toggle input breakpoint on port [p] (use \"*\" for all input ports)\n * bo [p] toggle output breakpoint on port [p] (use \"*\" for all output ports)\n *\n * These two new commands operate as toggles so that if \"*\" is used to trap all input (or output),\n * you can also use these commands to NOT trap specific ports.\n *\n * bn [n] break after [n] instructions\n *\n * TODO: Update the \"bl\" command to include any/all I/O breakpoints, and the \"bc\" command to\n * clear them. Because \"bi\" and \"bo\" commands are piggy-backing on Bus functions, those breakpoints\n * are currently outside the realm of what the \"bl\" and \"bc\" commands are aware of.\n *\n * @this {DebuggerX86}\n * @param {string} sCmd\n * @param {string|undefined} [sAddr]\n * @param {string} [sOptions] (the rest of the breakpoint command-line)\n */\n doBreak(sCmd, sAddr, sOptions)\n {\n if (sAddr == '?') {\n this.println(\"breakpoint commands:\");\n this.println(\"\\tbi [p]\\ttoggle break on input port [p]\");\n this.println(\"\\tbo [p]\\ttoggle break on output port [p]\");\n this.println(\"\\tbp [a]\\tset exec breakpoint at addr [a]\");\n this.println(\"\\tbr [a]\\tset read breakpoint at addr [a]\");\n this.println(\"\\tbw [a]\\tset write breakpoint at addr [a]\");\n this.println(\"\\tbc [a]\\tclear breakpoint at addr [a]\");\n this.println(\"\\tbl\\tlist all breakpoints\");\n this.println(\"\\tbn [n]\\tbreak after [n] instruction(s)\");\n return;\n }\n var sParm = sCmd.charAt(1);\n if (sParm == 'l') {\n var cBreaks = 0;\n cBreaks += this.listBreakpoints(this.aBreakExec);\n cBreaks += this.listBreakpoints(this.aBreakRead);\n cBreaks += this.listBreakpoints(this.aBreakWrite);\n if (!cBreaks) this.println(\"no breakpoints\");\n return;\n }\n if (sParm == 'n') {\n this.nBreakIns = this.parseValue(sAddr);\n this.println(\"break after \" + this.nBreakIns + \" instruction(s)\");\n return;\n }\n if (sAddr === undefined) {\n this.println(\"missing breakpoint address\");\n return;\n }\n var dbgAddr = {};\n if (sAddr != '*') {\n dbgAddr = this.parseAddr(sAddr, true, true);\n if (!dbgAddr) return;\n }\n\n sAddr = (dbgAddr.off == null? sAddr : Str.toHexWord(dbgAddr.off));\n\n if (sParm == 'c') {\n if (dbgAddr.off == null) {\n this.clearBreakpoints();\n this.println(\"all breakpoints cleared\");\n return;\n }\n if (this.findBreakpoint(this.aBreakExec, dbgAddr, true))\n return;\n if (this.findBreakpoint(this.aBreakRead, dbgAddr, true))\n return;\n if (this.findBreakpoint(this.aBreakWrite, dbgAddr, true))\n return;\n this.println(\"breakpoint missing: \" + this.toHexAddr(dbgAddr));\n return;\n }\n\n if (sParm == 'i') {\n this.println(\"breakpoint \" + (this.bus.addPortInputBreak(dbgAddr.off)? \"enabled\" : \"cleared\") + \": port \" + sAddr + \" (input)\");\n return;\n }\n\n if (sParm == 'o') {\n this.println(\"breakpoint \" + (this.bus.addPortOutputBreak(dbgAddr.off)? \"enabled\" : \"cleared\") + \": port \" + sAddr + \" (output)\");\n return;\n }\n\n if (dbgAddr.off == null) return;\n\n this.parseAddrOptions(dbgAddr, sOptions);\n\n if (sParm == 'p') {\n this.addBreakpoint(this.aBreakExec, dbgAddr);\n return;\n }\n if (sParm == 'r') {\n this.addBreakpoint(this.aBreakRead, dbgAddr);\n return;\n }\n if (sParm == 'w') {\n this.addBreakpoint(this.aBreakWrite, dbgAddr);\n return;\n }\n this.println(\"unknown breakpoint command: \" + sParm);\n }\n\n /**\n * doClear(sCmd)\n *\n * @this {DebuggerX86}\n * @param {string} [sCmd] (eg, \"cls\" or \"clear\")\n */\n doClear(sCmd)\n {\n this.cmp.clearPanel();\n }\n\n /**\n * doDump(asArgs)\n *\n * For memory dumps, the second parameter (sLen) is interpreted as a length (by default, in hex)\n * only if it contains an 'l' prefix; otherwise it's interpreted as an ending address (inclusive).\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs (formerly sCmd, [sAddr], [sLen] and [sBytes])\n */\n doDump(asArgs)\n {\n var m;\n var sCmd = asArgs[0];\n var sAddr = asArgs[1];\n var sLen = asArgs[2];\n var sBytes = asArgs[3];\n\n if (sAddr == '?') {\n var sDumpers = \"\";\n for (m in Messages.CATEGORIES) {\n if (this.afnDumpers[m]) {\n if (sDumpers) sDumpers += ',';\n sDumpers += m;\n }\n }\n sDumpers += \",state,symbols\";\n this.println(\"dump memory commands:\");\n this.println(\"\\tda [a] [#] dump # ASCII chars at address\");\n this.println(\"\\tdb [a] [#] dump # bytes at address\");\n this.println(\"\\tdw [a] [#] dump # words at address\");\n this.println(\"\\tdd [a] [#] dump # dwords at address\");\n this.println(\"\\tdh [#] [#] dump # instructions from history\");\n this.println(\"\\tdi [#] dump descriptor info for IDT #\");\n this.println(\"\\tds [#] dump descriptor info for selector #\");\n if (BACKTRACK) {\n this.println(\"\\tdt [a] dump backtrack info for address\");\n }\n if (sDumpers.length) this.println(\"dump extension commands:\\n\\t\" + sDumpers);\n return;\n }\n\n if (sAddr == \"state\") {\n var sState = this.cmp.powerOff(true);\n if (!sState) {\n this.println(\"powerOff() error\");\n }\n else if (sLen == \"console\") {\n /*\n * Console buffers are notoriously small, and even the following code, which breaks the\n * data into parts (eg, \"d state console 1\", \"d state console 2\", etc) just isn't that helpful.\n *\n * var nPart = +sBytes;\n * if (nPart) sState = sState.substr(1000000 * (nPart-1), 1000000);\n *\n * So, the best way to capture a large machine state is to use the new \"Save Machine\" link\n * that downloads a machine's entire state. Alternatively, run your own local server and use\n * server-side storage. Take a look at the \"Save\" binding in computer.js, which binds an HTML\n * control to the computer.powerOff() and computer.saveServerState() functions.\n */\n console.log(sState);\n } else {\n this.doClear();\n this.println(sState);\n }\n return;\n }\n\n if (sAddr == \"symbols\") {\n this.dumpSymbols();\n return;\n }\n\n /*\n * Transform a \"ds\" command into a \"d desc\" command (simply as shorthand); ditto for \"dg\" and \"dl\",\n * only because that's the syntax that WDEB386 used. I'm uncertain what WDEB386 would do with an LDT\n * selector passed to \"dg\" or a GDT selector passed to \"dl\" (because I'm too lazy to check right now),\n * but that seems nonsensical.\n */\n if (sCmd == \"ds\" || sCmd == \"dg\" || sCmd == \"dl\") {\n sCmd = \"d\";\n asArgs = [sCmd, \"desc\", sAddr];\n }\n\n /*\n * Handle the \"dp\" (aka \"d page\") commands here.\n */\n if (sCmd == \"d\" && sAddr == \"page\") {\n sCmd = \"dp\";\n asArgs.shift();\n }\n if (sCmd == \"dp\") {\n asArgs.shift();\n this.dumpPage(asArgs);\n return;\n }\n\n if (sCmd == \"d\") {\n /*\n * Transform a \"d disk\" command into a \"l json\" command (TODO: Register a dumper for \"disk\" instead?)\n */\n if (sAddr == \"disk\") {\n asArgs[0] = \"l\";\n asArgs[1] = \"json\";\n this.doLoad(asArgs);\n return;\n }\n for (m in Messages.CATEGORIES) {\n if (asArgs[1] == m) {\n var fnDumper = this.afnDumpers[m];\n if (fnDumper) {\n asArgs.shift();\n asArgs.shift();\n fnDumper(asArgs);\n } else {\n this.println(\"no dump registered for \" + sAddr);\n }\n return;\n }\n }\n if (!sAddr) sCmd = this.sCmdDumpPrev || \"db\";\n }\n\n if (sCmd == \"dh\") {\n this.dumpHistory(sAddr, sLen, sBytes);\n return;\n }\n\n if (sCmd == \"di\") {\n asArgs.shift();\n this.dumpIDT(asArgs);\n return;\n }\n\n if (sCmd == \"dt\") {\n asArgs.shift();\n var sInfo = this.dumpBackTrack(asArgs);\n this.println(sInfo);\n return;\n }\n\n if (sCmd[1] && \"abwd\".indexOf(sCmd[1]) < 0) {\n this.println(\"unrecognized dump command\");\n return;\n }\n\n this.sCmdDumpPrev = sCmd;\n\n var dbgAddr = this.parseAddr(sAddr);\n if (!dbgAddr || dbgAddr.sel == null && dbgAddr.addr == null) return;\n\n var len = 0;\n if (sLen) {\n if (sLen.charAt(0) == 'l') {\n sLen = sLen.substr(1) || sBytes;\n len = this.parseValue(sLen);\n } else {\n var dbgAddrEnd = this.parseAddr(sLen);\n if (!dbgAddrEnd) return;\n /*\n * To be more DEBUG-like, when an ending address is used instead of a length, we treat it inclusively, hence the \"+ 1\".\n */\n if (dbgAddr.type != DebuggerX86.ADDRTYPE.LINEAR) {\n len = dbgAddrEnd.off - dbgAddr.off + 1;\n } else {\n len = dbgAddrEnd.addr - dbgAddr.addr + 1;\n }\n }\n if (len < 0 || len > 0x10000) len = 0;\n }\n\n var sDump = \"\";\n var fASCII = false;\n var size = (sCmd == \"dd\"? 4 : (sCmd == \"dw\"? 2 : 1));\n var cb = (size * len) || 128;\n var cLines = ((cb + 15) >> 4) || 1;\n var cbLine = (size == 4? 16 : this.nBase); // the base also happens to be a reasonable number of bytes/line\n \n /*\n * The \"da\" variation uses a line size of 160 bytes, because that's the number of characters\n * per line in a text frame buffer; if no ending address or length is specified, the number of\n * lines defaults to 25 (the typical number of visible lines in a frame buffer).\n * \n * Beyond that, the command doesn't make any other assumptions about the memory format. Video\n * frame buffers usually dump nicely because all the attribute bytes tend to be non-ASCII.\n */\n if (sCmd[1] == 'a') {\n fASCII = true;\n cbLine = 160;\n cLines = (len <= 1? 25 : Math.ceil(len / cbLine));\n cb = cLines * cbLine;\n }\n \n while (cLines-- && cb > 0) {\n var data = 0, iByte = 0, i;\n var sData = \"\", sChars = \"\";\n sAddr = this.toHexAddr(dbgAddr);\n for (i = cbLine; i > 0 && cb > 0; i--) {\n var b = this.getByte(dbgAddr, 1);\n data |= (b << (iByte++ << 3));\n if (iByte == size) {\n sData += (this.nBase == 8? Str.toOct(data, size * 3) : Str.toHex(data, size * 2));\n sData += (size == 1? (i == 9? '-' : ' ') : \" \");\n data = iByte = 0;\n }\n sChars += (b >= 32 && b < 127? String.fromCharCode(b) : (fASCII? '' : '.'));\n cb--;\n }\n if (sDump) sDump += '\\n';\n if (fASCII) {\n sDump += sChars;\n } else {\n sDump += sAddr + \" \" + sData + Str.pad(sChars, sChars.length + i * 3 + 1, true);\n }\n }\n if (sDump) this.println(sDump.replace(/\\s*$/, \"\"));\n this.dbgAddrNextData = dbgAddr;\n }\n\n /**\n * doEdit(asArgs)\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n */\n doEdit(asArgs)\n {\n var size = 1;\n var mask = 0xff;\n var fnGet = this.getByte;\n var fnSet = this.setByte;\n if (asArgs[0] == \"ew\") {\n size = 2;\n mask = 0xffff;\n fnGet = this.getShort;\n fnSet = this.setShort;\n }\n var cch = size << 1;\n\n var sAddr = asArgs[1];\n if (sAddr == null) {\n this.println(\"edit memory commands:\");\n this.println(\"\\teb [a] [...] edit bytes at address a\");\n this.println(\"\\tew [a] [...] edit words at address a\");\n return;\n }\n\n var dbgAddr = this.parseAddr(sAddr);\n if (!dbgAddr) return;\n\n for (var i = 2; i < asArgs.length; i++) {\n var vNew = this.parseExpression(asArgs[i]);\n if (vNew === undefined) {\n this.println(\"unrecognized value: \" + asArgs[i]);\n break;\n }\n if (vNew & ~mask) {\n this.println(\"warning: \" + Str.toHex(vNew) + \" exceeds \" + size + \"-byte value\");\n }\n var vOld = fnGet.call(this, dbgAddr);\n this.println(\"changing \" + this.toHexAddr(dbgAddr) + \" from \" + Str.toHex(vOld, cch, true) + \" to \" + Str.toHex(vNew, cch, true));\n fnSet.call(this, dbgAddr, vNew, size);\n }\n }\n\n /**\n * doFreqs(sParm)\n *\n * @this {DebuggerX86}\n * @param {string|undefined} sParm\n */\n doFreqs(sParm)\n {\n if (sParm == '?') {\n this.println(\"frequency commands:\");\n this.println(\"\\tclear\\tclear all frequency counts\");\n return;\n }\n var i;\n var cData = 0;\n if (this.aaOpcodeCounts) {\n if (sParm == \"clear\") {\n for (i = 0; i < this.aaOpcodeCounts.length; i++)\n this.aaOpcodeCounts[i] = [i, 0];\n this.println(\"frequency data cleared\");\n cData++;\n }\n else if (sParm !== undefined) {\n this.println(\"unknown frequency command: \" + sParm);\n cData++;\n }\n else {\n var aaSortedOpcodeCounts = this.aaOpcodeCounts.slice();\n aaSortedOpcodeCounts.sort(function(p, q) {\n return q[1] - p[1];\n });\n for (i = 0; i < aaSortedOpcodeCounts.length; i++) {\n var bOpcode = aaSortedOpcodeCounts[i][0];\n var cFreq = aaSortedOpcodeCounts[i][1];\n if (cFreq) {\n this.println((DebuggerX86.INS_NAMES[this.aaOpDescs[bOpcode][0]] + \" \").substr(0, 5) + \" (\" + Str.toHexByte(bOpcode) + \"): \" + cFreq + \" times\");\n cData++;\n }\n }\n }\n }\n if (!cData) {\n this.println(\"no frequency data available\");\n }\n }\n\n /**\n * doHalt(fQuiet)\n *\n * @this {DebuggerX86}\n * @param {boolean} [fQuiet]\n */\n doHalt(fQuiet)\n {\n if (!this.stopCPU()) {\n if (this.isBusy(true)) return;\n if (!fQuiet) this.println(\"already halted\");\n }\n }\n\n /**\n * doIf(sCmd, fQuiet)\n *\n * NOTE: Don't forget that the default base for all numeric constants is 16 (hex), so when you evaluate\n * an expression like \"a==10\", it will compare the value of the variable \"a\" to 0x10; use a trailing period\n * (eg, \"10.\") if you really intend decimal.\n *\n * Also, if no variable named \"a\" exists, \"a\" will evaluate to 0x0A, so the expression \"a==10\" becomes\n * \"0x0A==0x10\" (false), whereas the expression \"a==10.\" becomes \"0x0A==0x0A\" (true).\n *\n * @this {DebuggerX86}\n * @param {string} sCmd\n * @param {boolean} [fQuiet]\n * @return {boolean} true if expression is non-zero, false if zero (or undefined due to a parse error)\n */\n doIf(sCmd, fQuiet)\n {\n sCmd = Str.trim(sCmd);\n if (!this.parseExpression(sCmd)) {\n if (!fQuiet) this.println(\"false: \" + sCmd);\n return false;\n }\n if (!fQuiet) this.println(\"true: \" + sCmd);\n return true;\n }\n\n /**\n * doInfo(asArgs)\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n * @return {boolean} true only if the instruction info command (\"n\") is supported\n */\n doInfo(asArgs)\n {\n if (DEBUG) {\n this.println(\"msPerYield: \" + this.cpu.counts.msPerYield);\n this.println(\"nCyclesPerYield: \" + this.cpu.counts.nCyclesPerYield);\n return true;\n }\n return false;\n }\n\n /**\n * doInput(sPort)\n *\n * Simulate a 1-byte port input operation.\n *\n * @this {DebuggerX86}\n * @param {string|undefined} sPort\n */\n doInput(sPort)\n {\n if (!sPort || sPort == '?') {\n this.println(\"input commands:\");\n this.println(\"\\ti [p]\\tread port [p]\");\n /*\n * TODO: Regarding this warning, consider adding an \"unchecked\" version of\n * bus.checkPortInputNotify(), since all Debugger memory accesses are unchecked, too.\n *\n * All port I/O handlers ARE aware when the Debugger is calling (addrFrom is undefined),\n * but changing them all to be non-destructive would take time, and situations where you\n * actually want to affect the hardware state are just as likely as not....\n */\n this.println(\"warning: port accesses can affect hardware state\");\n return;\n }\n var port = this.parseValue(sPort);\n if (port !== undefined) {\n var bIn = this.bus.checkPortInputNotify(port, 1);\n this.println(Str.toHexWord(port) + \": \" + Str.toHexByte(bIn));\n }\n }\n\n /**\n * doInt(sInt)\n *\n * Displays information about the given software interrupt (assuming that said interrupt is in progress).\n *\n * These messages also reset the system variable $ops (by updating cOpcodesStart), to make it easier to see\n * how many opcodes were executed since these interrupts \"started\".\n *\n * @this {DebuggerX86}\n * @param {string|undefined} sInt\n * @return {boolean} true if successful, false if not\n */\n doInt(sInt)\n {\n switch(this.parseValue(sInt)) {\n case 0x13:\n this.messageInt(Interrupts.DISK, this.cpu.regLIP, true);\n this.cOpcodesStart = this.cOpcodes;\n return true;\n case 0x21:\n this.messageInt(Interrupts.DOS, this.cpu.regLIP, true);\n this.cOpcodesStart = this.cOpcodes;\n return true;\n default:\n return false;\n }\n }\n\n /**\n * doVar(sCmd)\n *\n * The command must be of the form \"{variable} = [{expression}]\", where expression may contain constants,\n * operators, registers, symbols, other variables, or nothing at all; in the latter case, the variable, if\n * any, is deleted.\n *\n * Other supported shorthand: \"var\" with no parameters prints the values of all variables, and \"var {variable}\"\n * prints the value of the specified variable.\n *\n * @this {DebuggerX86}\n * @param {string} sCmd\n * @return {boolean} true if valid \"var\" assignment, false if not\n */\n doVar(sCmd)\n {\n var a = sCmd.match(/^\\s*([A-Z_]?[A-Z0-9_]*)\\s*(=?)\\s*(.*)$/i);\n if (a) {\n if (!a[1]) {\n if (!this.printVariable()) this.println(\"no variables\");\n return true; // it's not considered an error to print an empty list of variables\n }\n if (!a[2]) {\n return this.printVariable(a[1]);\n }\n if (!a[3]) {\n this.delVariable(a[1]);\n return true; // it's not considered an error to delete a variable that didn't exist\n }\n var v = this.parseExpression(a[3]);\n if (v !== undefined) {\n this.setVariable(a[1], v);\n return true;\n }\n return false;\n }\n this.println(\"invalid assignment:\" + sCmd);\n return false;\n }\n\n /**\n * doList(sAddr, fPrint)\n *\n * @this {DebuggerX86}\n * @param {string} sAddr\n * @param {boolean} [fPrint]\n * @return {string|null}\n */\n doList(sAddr, fPrint)\n {\n var sSymbol = null;\n\n var dbgAddr = this.parseAddr(sAddr, true);\n if (dbgAddr) {\n\n var addr = this.getAddr(dbgAddr);\n if (MAXDEBUG && fPrint) {\n this.println(this.toHexAddr(dbgAddr) + \" (%\" + Str.toHex(addr, this.cchAddr) + ')');\n }\n\n var aSymbol = this.findSymbol(dbgAddr, true);\n if (aSymbol.length) {\n var nDelta, sDelta, s;\n if (aSymbol[0]) {\n sDelta = \"\";\n nDelta = dbgAddr.off - aSymbol[1];\n if (nDelta) sDelta = \" + \" + Str.toHex(nDelta, 0, true);\n s = aSymbol[0] + \" (\" + this.toHexOffset(aSymbol[1], dbgAddr.sel) + ')' + sDelta;\n if (fPrint) this.println(s);\n sSymbol = s;\n }\n if (aSymbol.length > 4 && aSymbol[4]) {\n sDelta = \"\";\n nDelta = aSymbol[5] - dbgAddr.off;\n if (nDelta) sDelta = \" - \" + Str.toHex(nDelta, 0, true);\n s = aSymbol[4] + \" (\" + this.toHexOffset(aSymbol[5], dbgAddr.sel) + ')' + sDelta;\n if (fPrint) this.println(s);\n if (!sSymbol) sSymbol = s;\n }\n } else {\n if (fPrint) this.println(\"no symbols\");\n }\n }\n return sSymbol;\n }\n\n /**\n * doLoad(asArgs)\n *\n * The format of this command mirrors the DOS DEBUG \"L\" command:\n *\n * l [address] [drive #] [sector #] [# sectors]\n *\n * The only optional parameter is the last, which defaults to 1 sector if not specified.\n *\n * As a quick-and-dirty way of getting the current contents of a disk image as a JSON dump\n * (which you can then save as .json disk image file), I also support this command:\n *\n * l json [drive #]\n *\n * which is aliased to this command:\n *\n * d disk [drive #]\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n */\n doLoad(asArgs)\n {\n if (!asArgs[1] || asArgs[1] == '?') {\n this.println(\"load commands:\");\n this.println(\"\\tl [address] [drive #] [sector #] [# sectors]\");\n return;\n }\n\n var fJSON = (asArgs[1] == \"json\");\n var iDrive, iSector = 0, nSectors = 0;\n\n var dbgAddr = (fJSON? {} : this.parseAddr(asArgs[1]));\n if (!dbgAddr) return;\n\n iDrive = this.parseValue(asArgs[2], \"drive #\");\n if (iDrive === undefined) return;\n if (!fJSON) {\n iSector = this.parseValue(asArgs[3], \"sector #\");\n if (iSector === undefined) return;\n nSectors = this.parseValue(asArgs[4], \"# of sectors\");\n if (nSectors === undefined) nSectors = 1;\n }\n\n /*\n * We choose the disk controller very simplistically: FDC for drives 0 or 1, and HDC for drives 2\n * and up, unless no HDC is present, in which case we assume FDC for all drive numbers.\n *\n * Both controllers must obviously support the same interfaces; ie, copyDrive(), seekDrive(),\n * and readData(). We also rely on the disk property to determine whether the drive is \"loaded\".\n *\n * In the case of the HDC, if the drive is valid, then by definition it is also \"loaded\", since an HDC\n * drive and its disk are inseparable; it's certainly possible that the disk object may be empty at\n * this point (ie, if the disk is uninitialized and unformatted), but that will only affect whether the\n * read succeeds or not.\n */\n var dc = this.fdc;\n if (iDrive >= 2 && this.hdc) {\n iDrive -= 2;\n dc = this.hdc;\n }\n if (dc) {\n var drive = dc.copyDrive(iDrive);\n if (drive) {\n if (drive.disk) {\n if (fJSON) {\n /*\n * This is an interim solution to dumping disk images in JSON. It has many problems, the\n * \"biggest\" being that the large disk images really need to be compressed first, because they\n * get \"inflated\" with use. See the dump() method in the Disk component for more details.\n */\n this.doClear();\n this.println(drive.disk.convertToJSON());\n return;\n }\n if (dc.seekDrive(drive, iSector, nSectors)) {\n var cb = 0;\n var fAbort = false;\n var sAddr = this.toHexAddr(dbgAddr);\n while (!fAbort && drive.nBytes-- > 0) {\n (function(dbg, dbgAddrCur) {\n dc.readData(drive, function(b, fAsync) {\n if (b < 0) {\n dbg.println(\"out of data at address \" + dbg.toHexAddr(dbgAddrCur));\n fAbort = true;\n return;\n }\n dbg.setByte(dbgAddrCur, b, 1, true);\n cb++;\n });\n }(this, dbgAddr));\n }\n /*\n * Call updateCPU() now, since we forced setByte() to defer all updates\n */\n this.cpu.updateCPU(true);\n this.println(cb + \" bytes read at \" + sAddr);\n } else {\n this.println(\"sector \" + iSector + \" request out of range\");\n }\n } else {\n this.println(\"drive \" + iDrive + \" not loaded\");\n }\n } else {\n this.println(\"invalid drive: \" + iDrive);\n }\n } else {\n this.println(\"disk controller not present\");\n }\n }\n\n /**\n * doMessages(asArgs)\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n */\n doMessages(asArgs)\n {\n let m;\n let fCriteria = null;\n let sCategory = asArgs[1];\n if (sCategory == '?') sCategory = undefined;\n\n if (sCategory !== undefined) {\n let bitsMessage = 0;\n if (sCategory == \"all\") {\n bitsMessage = (0xffffffff|0) & ~(Messages.HALT | Messages.BUFFER);\n sCategory = null;\n } else if (sCategory == \"on\") {\n fCriteria = true;\n sCategory = null;\n } else if (sCategory == \"off\") {\n fCriteria = false;\n sCategory = null;\n } else {\n for (m in Messages.CATEGORIES) {\n if (sCategory == m) {\n bitsMessage = Messages.CATEGORIES[m];\n fCriteria = ((this.bitsMessage & bitsMessage) === bitsMessage);\n break;\n }\n }\n if (!bitsMessage) {\n this.println(\"unknown message category: \" + sCategory);\n return;\n }\n }\n if (bitsMessage) {\n if (asArgs[2] == \"on\") {\n this.bitsMessage |= bitsMessage;\n fCriteria = true;\n }\n else if (asArgs[2] == \"off\") {\n this.bitsMessage &= ~bitsMessage;\n if (!(this.bitsMessage & 0xF0000000) && bitsMessage) {\n this.bitsMessage = 0; // if all the high (shared) bits were turned off, ensure all the low bits are off as well.\n }\n fCriteria = false;\n if (bitsMessage == Messages.BUFFER) {\n for (var i = 0; i < this.aMessageBuffer.length; i++) {\n this.println(this.aMessageBuffer[i]);\n }\n this.aMessageBuffer = [];\n }\n }\n }\n }\n\n /*\n * Display those message categories that match the current criteria (on or off)\n */\n let n = 0;\n let sCategories = \"\";\n for (m in Messages.CATEGORIES) {\n if (!sCategory || sCategory == m) {\n let bitsMessage = Messages.CATEGORIES[m];\n let fEnabled = ((this.bitsMessage & bitsMessage) === bitsMessage);\n if (fCriteria !== null && fCriteria != fEnabled) continue;\n if (sCategories) sCategories += ',';\n if (!(++n % 10)) sCategories += \"\\n\\t\"; // jshint ignore:line\n sCategories += m;\n }\n }\n\n if (sCategory === undefined) {\n this.println(\"message commands:\\n\\tm [category] [on|off]\\tturn categories on/off\");\n }\n\n this.println((fCriteria !== null? (fCriteria? \"messages on: \" : \"messages off: \") : \"message categories:\\n\\t\") + (sCategories || \"none\"));\n\n this.historyInit(); // call this just in case Messages.INT was turned on\n }\n\n /**\n * doMouse(sAction, sDelta)\n *\n * When using the \"click\" action, specify 0 for Mouse.BUTTON.LEFT or 2 for Mouse.BUTTON.RIGHT.\n *\n * @this {DebuggerX86}\n * @param {string} sAction\n * @param {string} sDelta\n */\n doMouse(sAction, sDelta)\n {\n if (this.mouse) {\n var sign = 1;\n if (sDelta.charAt(0) == '-') {\n sign = -1;\n sDelta = sDelta.substr(1);\n }\n var n = this.parseValue(sDelta, sAction);\n if (n === undefined) return;\n n = (n * sign)|0;\n switch(sAction) {\n case \"x\":\n this.mouse.moveMouse(n, 0);\n break;\n case \"y\":\n this.mouse.moveMouse(0, n);\n break;\n case \"click\":\n this.mouse.clickMouse(n, true);\n this.mouse.clickMouse(n, false);\n break;\n default:\n this.println(\"unknown action: \" + sAction);\n break;\n }\n return;\n }\n this.println(\"no mouse\");\n }\n\n /**\n * doExecOptions(asArgs)\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n */\n doExecOptions(asArgs)\n {\n if (!asArgs[1] || asArgs[1] == '?') {\n this.println(\"execution options:\");\n this.println(\"\\tcs int #\\tset checksum cycle interval to #\");\n this.println(\"\\tcs start #\\tset checksum cycle start count to #\");\n this.println(\"\\tcs stop #\\tset checksum cycle stop count to #\");\n this.println(\"\\tsp #\\t\\tset speed multiplier to #\");\n return;\n }\n switch (asArgs[1]) {\n case \"cs\":\n var nCycles;\n if (asArgs[3] !== undefined) nCycles = +asArgs[3]; // warning: decimal instead of hex conversion\n switch (asArgs[2]) {\n case \"int\":\n this.cpu.counts.nCyclesChecksumInterval = nCycles;\n break;\n case \"start\":\n this.cpu.counts.nCyclesChecksumStart = nCycles;\n break;\n case \"stop\":\n this.cpu.counts.nCyclesChecksumStop = nCycles;\n break;\n default:\n this.println(\"unknown cs option\");\n return;\n }\n if (nCycles !== undefined) {\n this.cpu.resetChecksum();\n }\n this.println(\"checksums \" + (this.cpu.flags.checksum? \"enabled\" : \"disabled\"));\n break;\n case \"sp\":\n if (asArgs[2] !== undefined) {\n if (!this.cpu.setSpeed(+asArgs[2])) {\n this.println(\"warning: using 1x multiplier, previous target not reached\");\n }\n }\n this.println(\"target speed: \" + this.cpu.getSpeedTarget() + \" (\" + this.cpu.getSpeed() + \"x)\");\n break;\n default:\n this.println(\"unknown option: \" + asArgs[1]);\n break;\n }\n }\n\n /**\n * doOutput(sPort, sByte)\n *\n * Simulate a 1-byte port output operation.\n *\n * @this {DebuggerX86}\n * @param {string|undefined} sPort\n * @param {string|undefined} sByte (string representation of 1 byte)\n */\n doOutput(sPort, sByte)\n {\n if (!sPort || sPort == '?') {\n this.println(\"output commands:\");\n this.println(\"\\to [p] [b]\\twrite byte [b] to port [p]\");\n /*\n * TODO: Regarding this warning, consider adding an \"unchecked\" version of\n * bus.checkPortOutputNotify(), since all Debugger memory accesses are unchecked, too.\n *\n * All port I/O handlers ARE aware when the Debugger is calling (addrFrom is undefined),\n * but changing them all to be non-destructive would take time, and situations where you\n * actually want to affect the hardware state are just as likely as not....\n */\n this.println(\"warning: port accesses can affect hardware state\");\n return;\n }\n var port = this.parseValue(sPort, \"port #\");\n var bOut = this.parseValue(sByte);\n if (port !== undefined && bOut !== undefined) {\n this.bus.checkPortOutputNotify(port, 1, bOut);\n this.println(Str.toHexWord(port) + \": \" + Str.toHexByte(bOut));\n }\n }\n\n /**\n * doRegisters(asArgs, fInstruction)\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} [asArgs]\n * @param {boolean} [fInstruction] (true to include the current instruction; default is true)\n */\n doRegisters(asArgs, fInstruction)\n {\n if (asArgs && asArgs[1] == '?') {\n this.println(\"register commands:\");\n this.println(\"\\tr\\tdump registers\");\n if (this.fpu) this.println(\"\\trfp\\tdump floating-point registers\");\n this.println(\"\\trp\\tdump all registers\");\n this.println(\"\\trx [#]\\tset flag or register x to [#]\");\n return;\n }\n\n var fProt;\n if (fInstruction == null) fInstruction = true;\n\n if (asArgs != null && asArgs.length > 1) {\n var sReg = asArgs[1];\n if (this.fpu && sReg == \"fp\") {\n this.doFPURegisters(asArgs);\n return;\n }\n if (sReg == 'p') {\n fProt = (this.cpu.model >= X86.MODEL_80286);\n }\n else {\n // fInstruction = false;\n var sValue = null;\n var i = sReg.indexOf('=');\n if (i > 0) {\n sValue = sReg.substr(i + 1);\n sReg = sReg.substr(0, i);\n }\n else if (asArgs.length > 2) {\n sValue = asArgs[2];\n }\n else {\n this.println(\"missing value for \" + asArgs[1]);\n return;\n }\n\n var w = this.parseExpression(sValue);\n if (w === undefined) return;\n\n var fValid = true;\n var sRegMatch = sReg.toUpperCase();\n if (sRegMatch.charAt(0) == 'E' && this.cchReg <= 4) {\n sRegMatch = null;\n }\n switch (sRegMatch) {\n case \"AL\":\n this.cpu.regEAX = (this.cpu.regEAX & ~0xff) | (w & 0xff);\n break;\n case \"AH\":\n this.cpu.regEAX = (this.cpu.regEAX & ~0xff00) | ((w << 8) & 0xff);\n break;\n case \"AX\":\n this.cpu.regEAX = (this.cpu.regEAX & ~0xffff) | (w & 0xffff);\n break;\n case \"BL\":\n this.cpu.regEBX = (this.cpu.regEBX & ~0xff) | (w & 0xff);\n break;\n case \"BH\":\n this.cpu.regEBX = (this.cpu.regEBX & ~0xff00) | ((w << 8) & 0xff);\n break;\n case \"BX\":\n this.cpu.regEBX = (this.cpu.regEBX & ~0xffff) | (w & 0xffff);\n break;\n case \"CL\":\n this.cpu.regECX = (this.cpu.regECX & ~0xff) | (w & 0xff);\n break;\n case \"CH\":\n this.cpu.regECX = (this.cpu.regECX & ~0xff00) | ((w << 8) & 0xff);\n break;\n case \"CX\":\n this.cpu.regECX = (this.cpu.regECX & ~0xffff) | (w & 0xffff);\n break;\n case \"DL\":\n this.cpu.regEDX = (this.cpu.regEDX & ~0xff) | (w & 0xff);\n break;\n case \"DH\":\n this.cpu.regEDX = (this.cpu.regEDX & ~0xff00) | ((w << 8) & 0xff);\n break;\n case \"DX\":\n this.cpu.regEDX = (this.cpu.regEDX & ~0xffff) | (w & 0xffff);\n break;\n case \"SP\":\n this.cpu.setSP((this.cpu.getSP() & ~0xffff) | (w & 0xffff));\n break;\n case \"BP\":\n this.cpu.regEBP = (this.cpu.regEBP & ~0xffff) | (w & 0xffff);\n break;\n case \"SI\":\n this.cpu.regESI = (this.cpu.regESI & ~0xffff) | (w & 0xffff);\n break;\n case \"DI\":\n this.cpu.regEDI = (this.cpu.regEDI & ~0xffff) | (w & 0xffff);\n break;\n /*\n * DANGER: For any of the segment loads below, by going through the normal CPU\n * segment load procedure, you run the risk of generating a fault in the machine\n * if you're not careful. So, um, be careful.\n */\n case \"DS\":\n this.cpu.setDS(w);\n break;\n case \"ES\":\n this.cpu.setES(w);\n break;\n case \"SS\":\n this.cpu.setSS(w);\n break;\n case \"CS\":\n // fInstruction = true;\n this.cpu.setCS(w);\n this.dbgAddrNextCode = this.newAddr(this.cpu.getIP(), this.cpu.getCS());\n break;\n case \"IP\":\n case \"EIP\":\n // fInstruction = true;\n this.cpu.setIP(w);\n this.dbgAddrNextCode = this.newAddr(this.cpu.getIP(), this.cpu.getCS());\n break;\n /*\n * I used to alias \"PC\" (Program Counter) to \"IP\" (Instruction Pointer), because in PC-DOS 1.00\n * through 2.10, DEBUG.COM did the same thing. Then I discovered that, starting with PC-DOS 3.00,\n * DEBUG.COM changed \"PC\" to refer to the 16-bit flags register (Program or Processor Control?)\n * I've elected to go for PC-DOS 3.00+ compatibility, since that will be more widely known.\n *\n * PCx86 prefers \"PS\" (Processor Status) for accessing the FLAGS register in its 16-bit (or 32-bit)\n * entirety. Individual flag bits can also be accessed as 1-bit registers, using the names shown\n * below (\"C\", \"P\", \"A\", \"Z\", etc.)\n */\n case \"PC\":\n case \"PS\":\n this.cpu.setPS(w);\n break;\n case 'C':\n if (w) this.cpu.setCF(); else this.cpu.clearCF();\n break;\n case 'P':\n if (w) this.cpu.setPF(); else this.cpu.clearPF();\n break;\n case 'A':\n if (w) this.cpu.setAF(); else this.cpu.clearAF();\n break;\n case 'Z':\n if (w) this.cpu.setZF(); else this.cpu.clearZF();\n break;\n case 'S':\n if (w) this.cpu.setSF(); else this.cpu.clearSF();\n break;\n case 'I':\n if (w) this.cpu.setIF(); else this.cpu.clearIF();\n break;\n case 'D':\n if (w) this.cpu.setDF(); else this.cpu.clearDF();\n break;\n case 'V':\n if (w) this.cpu.setOF(); else this.cpu.clearOF();\n break;\n default:\n var fUnknown = true;\n if (this.cpu.model >= X86.MODEL_80286) {\n fUnknown = false;\n switch(sRegMatch){\n case \"MS\":\n this.cpu.setMSW(w);\n break;\n case \"TR\":\n /*\n * DANGER: Like any of the segment loads above, by going through the normal CPU\n * segment load procedure, you run the risk of generating a fault in the machine\n * if you're not careful. So, um, be careful.\n */\n if (this.cpu.segTSS.load(w) === X86.ADDR_INVALID) {\n fValid = false;\n }\n break;\n /*\n * TODO: Add support for GDTR (addr and limit), IDTR (addr and limit), and perhaps\n * even the ability to edit descriptor information associated with each segment register.\n */\n default:\n fUnknown = true;\n if (I386 && this.cpu.model >= X86.MODEL_80386) {\n fUnknown = false;\n switch(sRegMatch){\n case \"EAX\":\n this.cpu.regEAX = w;\n break;\n case \"EBX\":\n this.cpu.regEBX = w;\n break;\n case \"ECX\":\n this.cpu.regECX = w;\n break;\n case \"EDX\":\n this.cpu.regEDX = w;\n break;\n case \"ESP\":\n this.cpu.setSP(w);\n break;\n case \"EBP\":\n this.cpu.regEBP = w;\n break;\n case \"ESI\":\n this.cpu.regESI = w;\n break;\n case \"EDI\":\n this.cpu.regEDI = w;\n break;\n /*\n * DANGER: For any of the segment loads below, by going through the normal CPU\n * segment load procedure, you run the risk of generating a fault in the machine\n * if you're not careful. So, um, be careful.\n */\n case \"FS\":\n this.cpu.setFS(w);\n break;\n case \"GS\":\n this.cpu.setGS(w);\n break;\n case \"CR0\":\n this.cpu.regCR0 = w;\n X86.helpLoadCR0.call(this.cpu, w);\n break;\n case \"CR2\":\n this.cpu.regCR2 = w;\n break;\n case \"CR3\":\n this.cpu.regCR3 = w;\n X86.helpLoadCR3.call(this.cpu, w);\n break;\n /*\n * TODO: Add support for DR0-DR7 and TR6-TR7.\n */\n default:\n fUnknown = true;\n break;\n }\n }\n break;\n }\n }\n if (fUnknown) {\n this.println(\"unknown register: \" + sReg);\n return;\n }\n }\n if (!fValid) {\n this.println(\"invalid value: \" + sValue);\n return;\n }\n this.cpu.updateCPU();\n this.println(\"updated registers:\");\n }\n }\n\n this.println(this.getRegDump(fProt));\n\n if (fInstruction) {\n this.dbgAddrNextCode = this.newAddr(this.cpu.getIP(), this.cpu.getCS());\n this.doUnassemble(this.toHexAddr(this.dbgAddrNextCode));\n }\n }\n\n /**\n * doFPURegisters(asArgs)\n *\n * NOTE: If we're called, the existence of an FPU has already been verified.\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} [asArgs]\n */\n doFPURegisters(asArgs)\n {\n var fpu = this.fpu;\n\n var wStatus = fpu.getStatus(), wControl = fpu.getControl();\n for (var i = 0; i < 8; i++) {\n var a = fpu.readFPUStack(i);\n if (!a) break;\n var sValue = Str.pad(a[2].toFixed(15), 24, true);\n this.println(\"ST\" + i + \": \" + sValue + \" \" + Str.toHex(a[4]) + \",\" + Str.toHex(a[3]) + \" [\" + a[0] + \":\" + DebuggerX86.FPU_TAGS[a[1]] + \"]\");\n // this.println(\" REG\" + a[0] + \" \" + Str.toBin(a[7], 16) + Str.toBin(a[6]) + Str.toBin(a[5]));\n }\n this.println(\" B3SSS210ESPUOZDI xxxIRRPPIxPUOZDI\");\n this.println(\"SW: \" + Str.toBin(wStatus, 16) + \" (\" + Str.toHexWord(wStatus) + \") CW: \" + Str.toBin(wControl, 16) + \" (\" + Str.toHexWord(wControl) + \")\");\n }\n\n /**\n * doRun(sCmd, sAddr, sOptions, fQuiet)\n *\n * @this {DebuggerX86}\n * @param {string} sCmd\n * @param {string|undefined} [sAddr]\n * @param {string} [sOptions] (the rest of the breakpoint command-line)\n * @param {boolean} [fQuiet]\n */\n doRun(sCmd, sAddr, sOptions, fQuiet)\n {\n if (sCmd == \"gt\") {\n this.fIgnoreNextCheckFault = true;\n }\n if (sAddr !== undefined) {\n var dbgAddr = this.parseAddr(sAddr, true);\n if (!dbgAddr) return;\n this.parseAddrOptions(dbgAddr, sOptions);\n this.setTempBreakpoint(dbgAddr);\n }\n this.startCPU(true, fQuiet);\n }\n\n /**\n * doPrint(sCmd)\n *\n * NOTE: If the string to print is a quoted string, then we run it through replaceRegs(), so that\n * you can take advantage of all the special replacement options used for software interrupt logging.\n *\n * @this {DebuggerX86}\n * @param {string} sCmd\n */\n doPrint(sCmd)\n {\n sCmd = Str.trim(sCmd);\n var a = sCmd.match(/^(['\"])(.*?)\\1$/);\n if (!a) {\n this.parseExpression(sCmd, false);\n } else {\n this.println(this.replaceRegs(a[2]));\n }\n }\n\n /**\n * doStep(sCmd)\n *\n * @this {DebuggerX86}\n * @param {string} [sCmd] \"p\" or \"pr\"\n */\n doStep(sCmd)\n {\n var fCallStep = true;\n var nRegs = (sCmd == \"pr\"? 1 : 0);\n /*\n * Set up the value for this.nStep (ie, 1 or 2) depending on whether the user wants\n * a subsequent register dump (\"pr\") or not (\"p\").\n */\n var nStep = 1 + nRegs;\n if (!this.nStep) {\n var fPrefix;\n var fRepeat = false;\n var dbgAddr = this.newAddr(this.cpu.getIP(), this.cpu.getCS());\n do {\n fPrefix = false;\n var bOpcode = this.getByte(dbgAddr);\n switch (bOpcode) {\n case X86.OPCODE.ES:\n case X86.OPCODE.CS:\n case X86.OPCODE.SS:\n case X86.OPCODE.DS:\n case X86.OPCODE.FS: // I386 only\n case X86.OPCODE.GS: // I386 only\n case X86.OPCODE.OS: // I386 only\n case X86.OPCODE.AS: // I386 only\n case X86.OPCODE.LOCK:\n this.incAddr(dbgAddr, 1);\n fPrefix = true;\n break;\n case X86.OPCODE.INT3:\n case X86.OPCODE.INTO:\n this.nStep = nStep;\n this.incAddr(dbgAddr, 1);\n break;\n case X86.OPCODE.INTN:\n case X86.OPCODE.LOOPNZ:\n case X86.OPCODE.LOOPZ:\n case X86.OPCODE.LOOP:\n this.nStep = nStep;\n this.incAddr(dbgAddr, dbgAddr.fData32? 4 : 2);\n break;\n case X86.OPCODE.CALL:\n if (fCallStep) {\n this.nStep = nStep;\n this.incAddr(dbgAddr, dbgAddr.fData32? 5 : 3);\n }\n break;\n case X86.OPCODE.CALLF:\n if (fCallStep) {\n this.nStep = nStep;\n this.incAddr(dbgAddr, dbgAddr.fData32? 7 : 5);\n }\n break;\n case X86.OPCODE.GRP4W:\n if (fCallStep) {\n var w = this.getWord(dbgAddr) & X86.OPCODE.CALLMASK;\n if (w == X86.OPCODE.CALLW || w == X86.OPCODE.CALLFDW) {\n this.nStep = nStep;\n this.getInstruction(dbgAddr); // advance dbgAddr past this variable-length CALL\n }\n }\n break;\n case X86.OPCODE.REPZ:\n case X86.OPCODE.REPNZ:\n this.incAddr(dbgAddr, 1);\n fRepeat = fPrefix = true;\n break;\n case X86.OPCODE.INSB:\n case X86.OPCODE.INSW:\n case X86.OPCODE.OUTSB:\n case X86.OPCODE.OUTSW:\n case X86.OPCODE.MOVSB:\n case X86.OPCODE.MOVSW:\n case X86.OPCODE.CMPSB:\n case X86.OPCODE.CMPSW:\n case X86.OPCODE.STOSB:\n case X86.OPCODE.STOSW:\n case X86.OPCODE.LODSB:\n case X86.OPCODE.LODSW:\n case X86.OPCODE.SCASB:\n case X86.OPCODE.SCASW:\n if (fRepeat) {\n this.nStep = nStep;\n this.incAddr(dbgAddr, 1);\n }\n break;\n default:\n break;\n }\n } while (fPrefix);\n\n if (this.nStep) {\n this.setTempBreakpoint(dbgAddr);\n if (!this.startCPU()) {\n if (this.cmp) this.cmp.updateFocus();\n this.nStep = 0;\n }\n /*\n * A successful run will ultimately call stop(), which will in turn call clearTempBreakpoint(),\n * which will clear nStep, so there's your assurance that nStep will be reset. Now we may have\n * stopped for reasons unrelated to the temporary breakpoint, but that's OK.\n */\n } else {\n this.doTrace(nRegs? \"tr\" : \"t\");\n }\n } else {\n this.println(\"step in progress\");\n }\n }\n\n /**\n * getCall(dbgAddr, fFar)\n *\n * Given a possible return address (typically from the stack), look for a matching CALL (or INT) that\n * immediately precedes that address.\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {boolean} [fFar]\n * @return {string|null} CALL instruction at or near dbgAddr, or null if none\n */\n getCall(dbgAddr, fFar)\n {\n var sCall = null;\n var off = dbgAddr.off;\n var offOrig = off;\n for (var n = 1; n <= 6 && !!off; n++) {\n if (n > 2) {\n dbgAddr.off = off;\n dbgAddr.addr = null;\n var s = this.getInstruction(dbgAddr);\n if (s.indexOf(\"CALL\") >= 0 || fFar && s.indexOf(\"INT\") >= 0) {\n /*\n * Verify that the length of this CALL (or INT), when added to the address of the CALL (or INT),\n * matches the original return address. We do this by getting the string index of the opcode bytes,\n * subtracting that from the string index of the next space, and dividing that difference by two,\n * to yield the length of the CALL (or INT) instruction, in bytes.\n */\n var i = s.indexOf(' ');\n var j = s.indexOf(' ', i+1);\n if (off + (j - i - 1)/2 == offOrig) {\n sCall = s;\n break;\n }\n }\n }\n off--;\n }\n dbgAddr.off = offOrig;\n return sCall;\n }\n\n /**\n * doStackTrace(sCmd, sAddr)\n *\n * Use \"k\" for a normal stack trace and \"ks\" for a stack trace with symbolic info.\n *\n * @this {DebuggerX86}\n * @param {string} [sCmd]\n * @param {string} [sAddr] (not used yet)\n */\n doStackTrace(sCmd, sAddr)\n {\n if (sAddr == '?') {\n this.println(\"stack trace commands:\");\n this.println(\"\\tk\\tshow frame addresses\");\n this.println(\"\\tks\\tshow symbol information\");\n return;\n }\n\n var nFrames = 10, cFrames = 0;\n var selCode = this.cpu.segCS.sel;\n var dbgAddrCall = this.newAddr();\n var dbgAddrStack = this.newAddr(this.cpu.getSP(), this.cpu.getSS());\n this.println(\"stack trace for \" + this.toHexAddr(dbgAddrStack));\n\n while (cFrames < nFrames) {\n var sCall = null, sCallPrev = null, cTests = 256;\n while ((dbgAddrStack.off >>> 0) < this.cpu.regLSPLimit) {\n dbgAddrCall.off = this.getWord(dbgAddrStack, true);\n /*\n * Because we're using the auto-increment feature of getWord(), and because that will automatically\n * wrap the offset around the end of the segment, we must also check the addr property to detect the wrap.\n */\n if (dbgAddrStack.addr == null || !cTests--) break;\n dbgAddrCall.sel = selCode;\n sCall = this.getCall(dbgAddrCall);\n if (sCall) break;\n dbgAddrCall.sel = this.getWord(dbgAddrStack);\n sCall = this.getCall(dbgAddrCall, true);\n if (sCall) {\n selCode = this.getWord(dbgAddrStack, true);\n /*\n * It's not strictly necessary that we skip over the flags word that's pushed as part of any INT\n * instruction, but it reduces the risk of misinterpreting it as a return address on the next iteration.\n */\n if (sCall.indexOf(\"INT\") > 0) this.getWord(dbgAddrStack, true);\n break;\n }\n }\n /*\n * The sCallPrev check eliminates duplicate sequential calls, which are usually (but not always)\n * indicative of a false positive, in which case the previous call is probably bogus as well, but\n * at least we won't duplicate that mistake. Of course, there are always exceptions, recursion\n * being one of them, but it's rare that we're debugging recursive code.\n */\n if (!sCall || sCall == sCallPrev) break;\n var sSymbol = null;\n if (sCmd == \"ks\") {\n var a = sCall.match(/[0-9A-F]+$/);\n if (a) sSymbol = this.doList(a[0]);\n }\n sCall = Str.pad(sCall, 50) + \" ;\" + (sSymbol || \"stack=\" + this.toHexAddr(dbgAddrStack)); // + \" return=\" + this.toHexAddr(dbgAddrCall));\n this.println(sCall);\n sCallPrev = sCall;\n cFrames++;\n }\n if (!cFrames) this.println(\"no return addresses found\");\n }\n\n /**\n * doTrace(sCmd, sCount)\n *\n * The \"t\" and \"tr\" commands interpret the count as a number of instructions, and since\n * we call the Debugger's stepCPU() for each iteration, a single instruction includes\n * any/all prefixes; the CPU's stepCPU() treats prefixes as discrete operations. The only\n * difference between \"t\" and \"tr\": the former displays only the next instruction, while\n * the latter also displays the (updated) registers.\n *\n * The \"tc\" command interprets the count as a number of cycles rather than instructions,\n * allowing you to quickly execute large chunks of instructions with a single command; it\n * doesn't display anything until the the chunk has finished.\n *\n * However, generally a more useful command is \"bn\", which allows you to break after some\n * number of instructions have been executed (as opposed to some number of cycles).\n *\n * @this {DebuggerX86}\n * @param {string} [sCmd] (\"t\", \"tc\", or \"tr\")\n * @param {string} [sCount] # of instructions to step\n */\n doTrace(sCmd, sCount)\n {\n var dbg = this;\n var fRegs = (sCmd != \"t\");\n var nCount = this.parseValue(sCount, null, true) || 1;\n var nCycles = (nCount == 1? 0 : 1);\n if (sCmd == \"tc\") {\n nCycles = nCount;\n nCount = 1;\n }\n Web.onCountRepeat(\n nCount,\n function onCountStep() {\n return dbg.setBusy(true) && dbg.stepCPU(nCycles, fRegs, false);\n },\n function onCountStepComplete() {\n /*\n * We explicitly called stepCPU() with fUpdateCPU === false, because repeatedly\n * calling updateCPU() can be very slow, especially when fDisplayLiveRegs is true,\n * so once the repeat count has been exhausted, we must perform a final updateCPU().\n */\n dbg.cpu.updateCPU();\n dbg.setBusy(false);\n }\n );\n }\n\n /**\n * initAddrSize(dbgAddr, fComplete, cOverrides)\n *\n * @this {DebuggerX86}\n * @param {DbgAddrX86} dbgAddr\n * @param {boolean} fComplete\n * @param {number} [cOverrides]\n */\n initAddrSize(dbgAddr, fComplete, cOverrides)\n {\n /*\n * We use dbgAddr.fComplete to record whether or not the caller (ie, getInstruction())\n * processed a complete instruction.\n */\n dbgAddr.fComplete = fComplete;\n /*\n * For proper disassembly of instructions preceded by an OPERAND (0x66) size prefix, we set\n * dbgAddr.fData32 to true whenever the operand size is 32-bit; similarly, for an ADDRESS (0x67)\n * size prefix, we set dbgAddr.fAddr32 to true whenever the address size is 32-bit.\n *\n * Initially (and every time we've processed a complete instruction), both fields must be\n * set to their original value.\n */\n if (fComplete) {\n if (dbgAddr.fData32Orig != null) dbgAddr.fData32 = dbgAddr.fData32Orig;\n if (dbgAddr.fAddr32Orig != null) dbgAddr.fAddr32 = dbgAddr.fAddr32Orig;\n dbgAddr.fData32Orig = dbgAddr.fData32;\n dbgAddr.fAddr32Orig = dbgAddr.fAddr32;\n }\n /*\n * Use cOverrides to record whether we previously processed any OPERAND or ADDRESS overrides.\n */\n dbgAddr.cOverrides = cOverrides || 0;\n }\n\n /**\n * isStringIns(bOpcode)\n *\n * @this {DebuggerX86}\n * @param {number} bOpcode\n * @return {boolean} true if string instruction, false if not\n */\n isStringIns(bOpcode)\n {\n return (bOpcode >= X86.OPCODE.MOVSB && bOpcode <= X86.OPCODE.CMPSW || bOpcode >= X86.OPCODE.STOSB && bOpcode <= X86.OPCODE.SCASW);\n }\n\n /**\n * doUnassemble(sAddr, sAddrEnd, n)\n *\n * @this {DebuggerX86}\n * @param {string} [sAddr]\n * @param {string} [sAddrEnd]\n * @param {number} [n]\n */\n doUnassemble(sAddr, sAddrEnd, n)\n {\n var dbgAddr = this.parseAddr(sAddr, true);\n if (!dbgAddr) return;\n\n if (n === undefined) n = 1;\n\n var cb = 0x100;\n if (sAddrEnd !== undefined) {\n\n var dbgAddrEnd = this.parseAddr(sAddrEnd, true);\n if (!dbgAddrEnd || dbgAddrEnd.off < dbgAddr.off) return;\n\n /*\n * We now +1 the count to make the ending address inclusive (just like the dump command).\n */\n cb = dbgAddrEnd.off - dbgAddr.off + 1;\n if (cb < 0) cb = 1;\n /*\n * Limiting the amount of disassembled code to 4K helps prevent the user from wedging the browser.\n */\n if (cb > 0x1000) cb = 0x1000;\n n = -1;\n }\n\n var cLines = 0;\n var sInstruction;\n this.initAddrSize(dbgAddr, true);\n\n while (cb > 0 && n--) {\n\n var nSequence = (this.isBusy(false) || this.nStep)? this.nCycles : null;\n var sComment = (nSequence != null? \"cycles\" : null);\n var aSymbol = this.findSymbol(dbgAddr);\n\n var addr = dbgAddr.addr; // we snap dbgAddr.addr *after* calling findSymbol(), which re-evaluates it\n\n if (aSymbol[0] && n) {\n if (!cLines && n || aSymbol[0].indexOf('+') < 0) {\n var sLabel = aSymbol[0] + ':';\n if (aSymbol[2]) sLabel += ' ' + aSymbol[2];\n this.println(sLabel);\n }\n }\n\n if (aSymbol[3]) {\n sComment = aSymbol[3];\n nSequence = null;\n }\n\n sInstruction = this.getInstruction(dbgAddr, sComment, nSequence);\n\n /*\n * If getInstruction() reported that it did not process a complete instruction (via dbgAddr.fComplete),\n * then bump the instruction count by one, so that we display one more line (and hopefully the complete\n * instruction).\n */\n if (!dbgAddr.fComplete && !n) n++;\n\n this.println(sInstruction);\n this.dbgAddrNextCode = dbgAddr;\n cb -= dbgAddr.addr - addr;\n cLines++;\n }\n }\n\n /**\n * parseCommand(sCmd, fSave, chSep)\n *\n * @this {DebuggerX86}\n * @param {string|undefined} sCmd\n * @param {boolean} [fSave] is true to save the command, false if not\n * @param {string} [chSep] is the command separator character (default is ';')\n * @return {Array.<string>}\n */\n parseCommand(sCmd, fSave, chSep)\n {\n if (fSave) {\n if (!sCmd) {\n sCmd = this.aPrevCmds[this.iPrevCmd+1];\n } else {\n if (this.iPrevCmd < 0 && this.aPrevCmds.length) {\n this.iPrevCmd = 0;\n }\n if (this.iPrevCmd < 0 || sCmd != this.aPrevCmds[this.iPrevCmd]) {\n this.aPrevCmds.splice(0, 0, sCmd);\n this.iPrevCmd = 0;\n }\n this.iPrevCmd--;\n }\n }\n var a = [];\n if (sCmd) {\n /*\n * With the introduction of breakpoint commands (ie, quoted command sequences\n * associated with a breakpoint), we can no longer perform simplistic splitting.\n *\n * a = sCmd.split(chSep || ';');\n * for (var i = 0; i < a.length; i++) a[i] = Str.trim(a[i]);\n *\n * We may now split on semi-colons ONLY if they are outside a quoted sequence.\n *\n * Also, to allow quoted strings *inside* breakpoint commands, we first replace all\n * DOUBLE double-quotes with single quotes.\n */\n sCmd = sCmd.toLowerCase().replace(/\"\"/g, \"'\");\n\n var iPrev = 0;\n var chQuote = null;\n chSep = chSep || ';';\n /*\n * NOTE: Processing charAt() up to and INCLUDING length is not a typo; we're taking\n * advantage of the fact that charAt() with an invalid index returns an empty string,\n * allowing us to use the same substring() call to capture the final portion of sCmd.\n *\n * In a sense, it allows us to pretend that the string ends with a zero terminator.\n */\n for (var i = 0; i <= sCmd.length; i++) {\n var ch = sCmd.charAt(i);\n if (ch == '\"' || ch == \"'\") {\n if (!chQuote) {\n chQuote = ch;\n } else if (ch == chQuote) {\n chQuote = null;\n }\n }\n else if (ch == chSep && !chQuote || !ch) {\n /*\n * Recall that substring() accepts starting (inclusive) and ending (exclusive)\n * indexes, whereas substr() accepts a starting index and a length. We need the former.\n */\n a.push(Str.trim(sCmd.substring(iPrev, i)));\n iPrev = i + 1;\n }\n }\n }\n return a;\n }\n\n /**\n * shiftArgs(asArgs)\n *\n * Used with any command (eg, \"r\") that allows but doesn't require whitespace between command and first argument.\n *\n * @this {DebuggerX86}\n * @param {Array.<string>} asArgs\n * @return {Array.<string>}\n */\n shiftArgs(asArgs)\n {\n if (asArgs && asArgs.length) {\n var s0 = asArgs[0];\n var ch0 = s0.charAt(0);\n for (var i = 1; i < s0.length; i++) {\n var ch = s0.charAt(i);\n if (ch0 == '?' || ch0 == 'r' || ch < 'a' || ch > 'z') {\n asArgs[0] = s0.substr(i);\n asArgs.unshift(s0.substr(0, i));\n break;\n }\n }\n }\n return asArgs;\n }\n\n /**\n * doCommand(sCmd, fQuiet)\n *\n * @this {DebuggerX86}\n * @param {string} sCmd\n * @param {boolean} [fQuiet]\n * @return {boolean} true if command processed, false if unrecognized\n */\n doCommand(sCmd, fQuiet)\n {\n var result = true;\n\n try {\n if (!sCmd.length || sCmd == \"end\") {\n if (this.fAssemble) {\n this.println(\"ended assemble at \" + this.toHexAddr(this.dbgAddrAssemble));\n this.dbgAddrNextCode = this.dbgAddrAssemble;\n this.fAssemble = false;\n }\n sCmd = \"\";\n }\n else if (!fQuiet) {\n var sPrompt = \">> \";\n if (this.cpu.regCR0 & X86.CR0.MSW.PE) {\n sPrompt = (this.cpu.regPS & X86.PS.VM)? \"-- \" : \"## \";\n }\n this.println(sPrompt + sCmd);\n }\n\n var ch = sCmd.charAt(0);\n if (ch == '\"' || ch == \"'\") return true;\n\n /*\n * Zap the previous message buffer to ensure the new command's output is not tossed out as a repeat.\n */\n this.sMessagePrev = null;\n\n /*\n * I've relaxed the !isBusy() requirement, to maximize our ability to issue Debugger commands externally.\n */\n if (this.isReady() /* && !this.isBusy(true) */ && sCmd.length > 0) {\n\n if (this.fAssemble) {\n sCmd = \"a \" + this.toHexAddr(this.dbgAddrAssemble) + ' ' + sCmd;\n }\n\n var asArgs = this.shiftArgs(sCmd.replace(/ +/g, ' ').split(' '));\n\n switch (asArgs[0].charAt(0)) {\n case 'a':\n this.doAssemble(asArgs);\n break;\n case 'b':\n this.doBreak(asArgs[0], asArgs[1], sCmd);\n break;\n case 'c':\n this.doClear(asArgs[0]);\n break;\n case 'd':\n if (!PCX86.COMPILED && sCmd == \"debug\") {\n window.DEBUG = true;\n this.println(\"DEBUG checks on\");\n break;\n }\n this.doDump(asArgs);\n break;\n case 'e':\n if (asArgs[0] == \"else\") break;\n this.doEdit(asArgs);\n break;\n case 'f':\n this.doFreqs(asArgs[1]);\n break;\n case 'g':\n this.doRun(asArgs[0], asArgs[1], sCmd, fQuiet);\n break;\n case 'h':\n this.doHalt(fQuiet);\n break;\n case 'i':\n if (asArgs[0] == \"if\") {\n if (!this.doIf(sCmd.substr(2), fQuiet)) {\n result = false;\n }\n break;\n }\n if (asArgs[0] == \"int\") {\n if (!this.doInt(asArgs[1])) {\n result = false;\n }\n break;\n }\n this.doInput(asArgs[1]);\n break;\n case 'k':\n this.doStackTrace(asArgs[0], asArgs[1]);\n break;\n case 'l':\n if (asArgs[0] == \"ln\") {\n this.doList(asArgs[1], true);\n break;\n }\n this.doLoad(asArgs);\n break;\n case 'm':\n if (asArgs[0] == \"mouse\") {\n this.doMouse(asArgs[1], asArgs[2]);\n break;\n }\n this.doMessages(asArgs);\n break;\n case 'o':\n this.doOutput(asArgs[1], asArgs[2]);\n break;\n case 'p':\n if (asArgs[0] == \"print\") {\n this.doPrint(sCmd.substr(5));\n break;\n }\n this.doStep(asArgs[0]);\n break;\n case 'r':\n if (sCmd == \"reset\") {\n if (this.cmp) this.cmp.reset();\n break;\n }\n this.doRegisters(asArgs);\n break;\n case 't':\n this.doTrace(asArgs[0], asArgs[1]);\n break;\n case 'u':\n this.doUnassemble(asArgs[1], asArgs[2], 8);\n break;\n case 'v':\n if (asArgs[0] == \"var\") {\n if (!this.doVar(sCmd.substr(3))) {\n result = false;\n }\n break;\n }\n this.println((PCX86.APPNAME || \"PCx86\") + \" version \" + (XMLVERSION || PCX86.APPVERSION) + \" (\" + this.cpu.model + (PCX86.COMPILED? \",RELEASE\" : (PCX86.DEBUG? \",DEBUG\" : \",NODEBUG\")) + (PCX86.PREFETCH? \",PREFETCH\" : \",NOPREFETCH\") + (PCX86.TYPEDARRAYS? \",TYPEDARRAYS\" : (PCX86.BYTEARRAYS? \",BYTEARRAYS\" : \",LONGARRAYS\")) + (PCX86.BACKTRACK? \",BACKTRACK\" : \",NOBACKTRACK\") + ')');\n this.println(Web.getUserAgent());\n break;\n case 'x':\n this.doExecOptions(asArgs);\n break;\n case '?':\n if (asArgs[1]) {\n this.doPrint(sCmd.substr(1));\n break;\n }\n this.doHelp();\n break;\n case 'n':\n if (!PCX86.COMPILED && sCmd == \"nodebug\") {\n window.DEBUG = false;\n this.println(\"DEBUG checks off\");\n break;\n }\n if (this.doInfo(asArgs)) break;\n /* falls through */\n default:\n this.println(\"unknown command: \" + sCmd);\n result = false;\n break;\n }\n }\n } catch(e) {\n this.println(\"debugger error: \" + (e.stack || e.message));\n result = false;\n }\n return result;\n }\n\n /**\n * doCommands(sCommands, fSave)\n *\n * @this {DebuggerX86}\n * @param {string} sCommands\n * @param {boolean} [fSave]\n * @return {boolean} true if all commands processed, false if not\n */\n doCommands(sCommands, fSave)\n {\n var a = this.parseCommand(sCommands, fSave);\n for (var s in a) {\n if (!this.doCommand(a[+s])) return false;\n }\n return true;\n }\n\n /**\n * DebuggerX86.init()\n *\n * This function operates on every HTML element of class \"debugger\", extracting the\n * JSON-encoded parameters for the Debugger constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Debugger component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeDbg = Component.getElementsByClass(document, PCX86.APPCLASS, \"debugger\");\n for (var iDbg = 0; iDbg < aeDbg.length; iDbg++) {\n var eDbg = aeDbg[iDbg];\n var parmsDbg = Component.getComponentParms(eDbg);\n var dbg = new DebuggerX86(parmsDbg);\n Component.bindComponentControls(dbg, eDbg, PCX86.APPCLASS);\n }\n }\n}\n\nif (DEBUGGER) {\n\n /*\n * NOTE: The Debugger properties below are considered \"class constants\"; most of them use our \"all-caps\"\n * convention (and all of them SHOULD, but that wouldn't help us catch any bugs).\n *\n * Technically, all of them should ALSO be preceded by a \"@const\" annotation, but that's a lot of work and it\n * really clutters the code. I wish the Closure Compiler had a way to annotate every definition with a given\n * section with a single annotation....\n *\n * Bugs can slip through the cracks without those annotations; for example, I unthinkingly redefined TYPE_SI\n * at one point, and if all the definitions had been preceded by an \"@const\", that mistake would have been\n * caught at compile-time.\n */\n\n /*\n * Information regarding interrupts of interest (used by messageInt() and others)\n */\n DebuggerX86.INT_MESSAGES = {\n 0x10: Messages.VIDEO,\n 0x13: Messages.FDC,\n 0x15: Messages.CHIPSET,\n 0x16: Messages.KBD,\n // 0x1A: Messages.RTC, // ChipSet contains its own custom messageInt() handler for the RTC\n 0x1C: Messages.TIMER,\n 0x21: Messages.DOS,\n 0x33: Messages.MOUSE\n };\n\n /*\n * Information regarding \"annoying\" interrupts (which aren't annoying so much as too frequent);\n * note that some of these can still be enabled if you really want them (eg, RTC can be turned on\n * with RTC messages, ALT_TIMER with TIMER messages, etc).\n */\n DebuggerX86.INT_ANNOYING = [Interrupts.RTC, Interrupts.ALT_TIMER, Interrupts.DOS_IDLE, Interrupts.DOS_NETBIOS, Interrupts.ALT_VIDEO];\n\n DebuggerX86.COMMANDS = {\n '?': \"help/print\",\n 'a [#]': \"assemble\", // TODO: Implement this command someday\n 'b [#]': \"breakpoint\", // multiple variations (use b? to list them)\n 'c': \"clear output\",\n 'd [#]': \"dump memory\", // additional syntax: d [#] [l#], where l# is a number of bytes to dump\n 'e [#]': \"edit memory\",\n 'f': \"frequencies\",\n 'g [#]': \"go [to #]\",\n 'h': \"halt\",\n 'i [#]': \"input port #\",\n 'if': \"eval expression\",\n 'k': \"stack trace\",\n 'l': \"load sector(s)\",\n \"ln\": \"list nearest symbol(s)\",\n 'm': \"messages\",\n 'mouse': \"mouse action\", // syntax: mouse {action} {delta} (eg, mouse x 10, mouse click 0, etc)\n 'o [#]': \"output port #\",\n 'p': \"step over\", // other variations: pr (step and dump registers)\n 'print': \"print expression\",\n 'r': \"dump/set registers\",\n 'reset': \"reset machine\",\n 't [#]': \"trace\", // other variations: tr (trace and dump registers)\n 'u [#]': \"unassemble\",\n 'x': \"execution options\",\n 'v': \"print version\",\n 'var': \"assign variable\"\n };\n\n /*\n * Supported address types; the type field in a DbgAddrX86 object may be one of:\n *\n * NONE, REAL, PROT, V86, LINEAR or PHYSICAL\n *\n * REAL and V86 addresses are specified with a '&' prefix, PROT addresses with a '#' prefix,\n * LINEAR addresses with '%', and PHYSICAL addresses with '%%'.\n */\n DebuggerX86.ADDRTYPE = {\n NONE: 0x00,\n REAL: 0x01,\n PROT: 0x02,\n V86: 0x03,\n LINEAR: 0x04,\n PHYSICAL: 0x05\n };\n\n /*\n * CPU instruction ordinals\n *\n * Note that individual instructions end with ordinal 162 and instruction groups begin with ordinal 163;\n * the disassembler knows it's dealing with a group whenever the ordinal is not a valid index into INS_NAMES.\n *\n * NOTE: While this list started alphabetical, there are a few wrinkles; eg, POPA/POPF/PUSHF/PUSHA are\n * sequential to make it easier to detect instructions that require a D suffix when the operand size is 32 bits.\n */\n DebuggerX86.INS = {\n NONE: 0, AAA: 1, AAD: 2, AAM: 3, AAS: 4, ADC: 5, ADD: 6, AND: 7,\n ARPL: 8, AS: 9, BOUND: 10, BSF: 11, BSR: 12, BT: 13, BTC: 14, BTR: 15,\n BTS: 16, CALL: 17, CBW: 18, CLC: 19, CLD: 20, CLI: 21, CLTS: 22, CMC: 23,\n CMP: 24, CMPSB: 25, CMPSW: 26, CS: 27, CWD: 28, DAA: 29, DAS: 30, DEC: 31,\n DIV: 32, DS: 33, ENTER: 34, ES: 35, ESC: 36, FS: 37, GS: 38, HLT: 39,\n IBTS: 40, IDIV: 41, IMUL: 42, IN: 43, INC: 44, INS: 45, INT: 46, INT3: 47,\n INTO: 48, IRET: 49, JBE: 50, JC: 51, JCXZ: 52, JG: 53, JGE: 54, JL: 55,\n JLE: 56, JMP: 57, JA: 58, JNC: 59, JNO: 60, JNP: 61, JNS: 62, JNZ: 63,\n JO: 64, JP: 65, JS: 66, JZ: 67, LAHF: 68, LAR: 69, LDS: 70, LEA: 71,\n LEAVE: 72, LES: 73, LFS: 74, LGDT: 75, LGS: 76, LIDT: 77, LLDT: 78, LMSW: 79,\n LOADALL:80, LOCK: 81, LODSB: 82, LODSW: 83, LOOP: 84, LOOPNZ: 85, LOOPZ: 86, LSL: 87,\n LSS: 88, LTR: 89, MOV: 90, MOVSB: 91, MOVSW: 92, MOVSX: 93, MOVZX: 94, MUL: 95,\n NEG: 96, NOP: 97, NOT: 98, OR: 99, OS: 100, OUT: 101, OUTS: 102, POP: 103,\n POPA: 104, POPF: 105, PUSHF: 106, PUSHA: 107, PUSH: 108, RCL: 109, RCR: 110, REPNZ: 111,\n REPZ: 112, RET: 113, RETF: 114, ROL: 115, ROR: 116, SAHF: 117, SALC: 118, SAR: 119,\n SBB: 120, SCASB: 121, SCASW: 122, SETBE: 123, SETC: 124, SETG: 125, SETGE: 126, SETL: 127,\n SETLE: 128, SETNBE: 129, SETNC: 130, SETNO: 131, SETNP: 132, SETNS: 133, SETNZ: 134, SETO: 135,\n SETP: 136, SETS: 137, SETZ: 138, SGDT: 139, SHL: 140, SHLD: 141, SHR: 142, SHRD: 143,\n SIDT: 144, SLDT: 145, SMSW: 146, SS: 147, STC: 148, STD: 149, STI: 150, STOSB: 151,\n STOSW: 152, STR: 153, SUB: 154, TEST: 155, VERR: 156, VERW: 157, WAIT: 158, XBTS: 159,\n XCHG: 160, XLAT: 161, XOR: 162, GRP1B: 163, GRP1W: 164, GRP1SW: 165, GRP2B: 166, GRP2W: 167,\n GRP2B1: 168, GRP2W1: 169, GRP2BC: 170, GRP2WC: 171, GRP3B: 172, GRP3W: 173, GRP4B: 174, GRP4W: 175,\n OP0F: 176, GRP6: 177, GRP7: 178, GRP8: 179\n };\n\n /*\n * CPU instruction names (mnemonics), indexed by CPU instruction ordinal (above)\n */\n DebuggerX86.INS_NAMES = [\n \"INVALID\",\"AAA\", \"AAD\", \"AAM\", \"AAS\", \"ADC\", \"ADD\", \"AND\",\n \"ARPL\", \"AS:\", \"BOUND\", \"BSF\", \"BSR\", \"BT\", \"BTC\", \"BTR\",\n \"BTS\", \"CALL\", \"CBW\", \"CLC\", \"CLD\", \"CLI\", \"CLTS\", \"CMC\",\n \"CMP\", \"CMPSB\", \"CMPSW\", \"CS:\", \"CWD\", \"DAA\", \"DAS\", \"DEC\",\n \"DIV\", \"DS:\", \"ENTER\", \"ES:\", \"ESC\", \"FS:\", \"GS:\", \"HLT\",\n \"IBTS\", \"IDIV\", \"IMUL\", \"IN\", \"INC\", \"INS\", \"INT\", \"INT3\",\n \"INTO\", \"IRET\", \"JBE\", \"JC\", \"JCXZ\", \"JG\", \"JGE\", \"JL\",\n \"JLE\", \"JMP\", \"JA\", \"JNC\", \"JNO\", \"JNP\", \"JNS\", \"JNZ\",\n \"JO\", \"JP\", \"JS\", \"JZ\", \"LAHF\", \"LAR\", \"LDS\", \"LEA\",\n \"LEAVE\", \"LES\", \"LFS\", \"LGDT\", \"LGS\", \"LIDT\", \"LLDT\", \"LMSW\",\n \"LOADALL\",\"LOCK\", \"LODSB\", \"LODSW\", \"LOOP\", \"LOOPNZ\", \"LOOPZ\", \"LSL\",\n \"LSS\", \"LTR\", \"MOV\", \"MOVSB\", \"MOVSW\", \"MOVSX\", \"MOVZX\", \"MUL\",\n \"NEG\", \"NOP\", \"NOT\", \"OR\", \"OS:\", \"OUT\", \"OUTS\", \"POP\",\n \"POPA\", \"POPF\", \"PUSHF\", \"PUSHA\", \"PUSH\", \"RCL\", \"RCR\", \"REPNZ\",\n \"REPZ\", \"RET\", \"RETF\", \"ROL\", \"ROR\", \"SAHF\", \"SALC\", \"SAR\",\n \"SBB\", \"SCASB\", \"SCASW\", \"SETBE\", \"SETC\", \"SETG\", \"SETGE\", \"SETL\",\n \"SETLE\", \"SETNBE\", \"SETNC\", \"SETNO\", \"SETNP\", \"SETNS\", \"SETNZ\", \"SETO\",\n \"SETP\", \"SETS\", \"SETZ\", \"SGDT\", \"SHL\", \"SHLD\", \"SHR\", \"SHRD\",\n \"SIDT\", \"SLDT\", \"SMSW\", \"SS:\", \"STC\", \"STD\", \"STI\", \"STOSB\",\n \"STOSW\", \"STR\", \"SUB\", \"TEST\", \"VERR\", \"VERW\", \"WAIT\", \"XBTS\",\n \"XCHG\", \"XLAT\", \"XOR\"\n ];\n\n /*\n * FPU instruction ordinals\n *\n * Unlike CPU instruction ordinals, these are not organized alphabetically (which I did only for the\n * sake of tidiness), but rather by functionality; ie:\n *\n * 0-3: real transfers\n * 4-6: integer transfers\n * 7-8: packed decimal transfers\n * 9-11: addition\n * 12-17: subtraction\n * 18-20: multiplication\n * 21-26: division\n * 27-33: other\n * 34-40: comparisons\n * 41-45: transcendental\n * 46-52: constants\n * 53-77: coprocessor control\n * 78---: new for 80287 or higher\n *\n * Also, unlike the CPU instructions, there is no NONE (\"INVALID\") instruction; if an ESC instruction\n * can't be decoded as a valid FPU instruction, then it should remain an ESC instruction.\n */\n DebuggerX86.FINS = {\n FLD: 0, FST: 1, FSTP: 2, FXCH: 3, FILD: 4, FIST: 5, FISTP: 6, FBLD: 7,\n FBSTP: 8, FADD: 9, FADDP: 10, FIADD: 11, FSUB: 12, FSUBP: 13, FISUB: 14, FSUBR: 15,\n FSUBRP: 16, FISUBR: 17, FMUL: 18, FMULP: 19, FIMUL: 20, FDIV: 21, FDIVP: 22, FIDIV: 23,\n FDIVR: 24, FDIVRP: 25, FIDIVR: 26, FSQRT: 27, FSCALE: 28, FPREM: 29, FRNDINT:30, FXTRACT:31,\n FABS: 32, FCHS: 33, FCOM: 34, FCOMP: 35, FCOMPP: 36, FICOM: 37, FICOMP: 38, FTST: 39,\n FXAM: 40, FPTAN: 41, FPATAN: 42, F2XM1: 43, FYL2X: 44, FYL2XP1:45, FLDZ: 46, FLD1: 47,\n FLDPI: 48, FLDL2T: 49, FLDL2E: 50, FLDLG2: 51, FLDLN2: 52, FINIT: 53, FNINIT: 54, FDISI: 55,\n FNDISI: 56, FENI: 57, FNENI: 58, FLDCW: 59, FSTCW: 60, FNSTCW: 61, FSTSW: 62, FNSTSW: 63,\n FCLEX: 64, FNCLEX: 65, FSTENV: 66, FNSTENV:67, FLDENV: 68, FSAVE: 69, FNSAVE: 70, FRSTOR: 71,\n FINCSTP:72, FDECSTP:73, FFREE: 74, FFREEP: 75, FNOP: 76, FWAIT: 77, FSETPM: 78, FSINCOS:79,\n FSTSWAX:80\n };\n\n /*\n * FPU instruction names (mnemonics), indexed by FPU instruction ordinal (above)\n */\n DebuggerX86.FINS_NAMES = [\n \"FLD\", \"FST\", \"FSTP\", \"FXCH\", \"FILD\", \"FIST\", \"FISTP\", \"FBLD\",\n \"FBSTP\", \"FADD\", \"FADDP\", \"FIADD\", \"FSUB\", \"FSUBP\", \"FISUB\", \"FSUBR\",\n \"FSUBRP\", \"FISUBR\", \"FMUL\", \"FMULP\", \"FIMUL\", \"FDIV\", \"FDIVP\", \"FIDIV\",\n \"FDIVR\", \"FDIVRP\", \"FIDIVR\", \"FSQRT\", \"FSCALE\", \"FPREM\", \"FRNDINT\",\"FXTRACT\",\n \"FABS\", \"FCHS\", \"FCOM\", \"FCOMP\", \"FCOMPP\", \"FICOM\", \"FICOMP\", \"FTST\",\n \"FXAM\", \"FPTAN\", \"FPATAN\", \"F2XM1\", \"FYL2X\", \"FYL2XP1\",\"FLDZ\", \"FLD1\",\n \"FLDPI\", \"FLDL2T\", \"FLDL2E\", \"FLDLG2\", \"FLDLN2\", \"FINIT\", \"FNINIT\", \"FDISI\",\n \"FNDISI\", \"FENI\", \"FNENI\", \"FLDCW\", \"FSTCW\", \"FNSTCW\", \"FSTSW\", \"FNSTSW\",\n \"FCLEX\", \"FNCLEX\", \"FSTENV\", \"FNSTENV\",\"FLDENV\", \"FSAVE\", \"FNSAVE\", \"FRSTOR\",\n \"FINCSTP\",\"FDECSTP\",\"FFREE\", \"FFREEP\", \"FNOP\", \"FWAIT\", \"FSETPM\", \"FSINCOS\",\n \"FSTSWAX\"\n ];\n\n DebuggerX86.FPU_TAGS = [\"VALID\", \"ZERO \", \"SPEC \", \"EMPTY\"];\n\n DebuggerX86.CPU_8086 = 0;\n DebuggerX86.CPU_80186 = 1;\n DebuggerX86.CPU_80286 = 2;\n DebuggerX86.CPU_80386 = 3;\n DebuggerX86.CPUS = [8086, 80186, 80286, 80386];\n\n /*\n * ModRM masks and definitions\n */\n DebuggerX86.REG_AL = 0x00; // bits 0-2 are standard Reg encodings\n DebuggerX86.REG_CL = 0x01;\n DebuggerX86.REG_DL = 0x02;\n DebuggerX86.REG_BL = 0x03;\n DebuggerX86.REG_AH = 0x04;\n DebuggerX86.REG_CH = 0x05;\n DebuggerX86.REG_DH = 0x06;\n DebuggerX86.REG_BH = 0x07;\n DebuggerX86.REG_AX = 0x08;\n DebuggerX86.REG_CX = 0x09;\n DebuggerX86.REG_DX = 0x0A;\n DebuggerX86.REG_BX = 0x0B;\n DebuggerX86.REG_SP = 0x0C;\n DebuggerX86.REG_BP = 0x0D;\n DebuggerX86.REG_SI = 0x0E;\n DebuggerX86.REG_DI = 0x0F;\n DebuggerX86.REG_SEG = 0x10;\n DebuggerX86.REG_IP = 0x16;\n DebuggerX86.REG_PS = 0x17;\n DebuggerX86.REG_EAX = 0x18;\n DebuggerX86.REG_ECX = 0x19;\n DebuggerX86.REG_EDX = 0x1A;\n DebuggerX86.REG_EBX = 0x1B;\n DebuggerX86.REG_ESP = 0x1C;\n DebuggerX86.REG_EBP = 0x1D;\n DebuggerX86.REG_ESI = 0x1E;\n DebuggerX86.REG_EDI = 0x1F;\n DebuggerX86.REG_CR0 = 0x20;\n DebuggerX86.REG_CR1 = 0x21;\n DebuggerX86.REG_CR2 = 0x22;\n DebuggerX86.REG_CR3 = 0x23;\n DebuggerX86.REG_DR0 = 0x28;\n DebuggerX86.REG_DR1 = 0x29;\n DebuggerX86.REG_DR2 = 0x2A;\n DebuggerX86.REG_DR3 = 0x2B;\n DebuggerX86.REG_DR6 = 0x2E;\n DebuggerX86.REG_DR7 = 0x2F;\n DebuggerX86.REG_TR0 = 0x30;\n DebuggerX86.REG_TR6 = 0x36;\n DebuggerX86.REG_TR7 = 0x37;\n DebuggerX86.REG_EIP = 0x38;\n\n DebuggerX86.REGS = [\n \"AL\", \"CL\", \"DL\", \"BL\", \"AH\", \"CH\", \"DH\", \"BH\",\n \"AX\", \"CX\", \"DX\", \"BX\", \"SP\", \"BP\", \"SI\", \"DI\",\n \"ES\", \"CS\", \"SS\", \"DS\", \"FS\", \"GS\", \"IP\", \"PS\",\n \"EAX\", \"ECX\", \"EDX\", \"EBX\", \"ESP\", \"EBP\", \"ESI\", \"EDI\",\n \"CR0\", \"CR1\", \"CR2\", \"CR3\", null, null, null, null, // register names used with TYPE_CTLREG\n \"DR0\", \"DR1\", \"DR2\", \"DR3\", null, null, \"DR6\", \"DR7\", // register names used with TYPE_DBGREG\n null, null, null, null, null, null, \"TR6\", \"TR7\", // register names used with TYPE_TSTREG\n \"EIP\"\n ];\n\n DebuggerX86.REG_ES = 0x00; // bits 0-1 are standard SegReg encodings\n DebuggerX86.REG_CS = 0x01;\n DebuggerX86.REG_SS = 0x02;\n DebuggerX86.REG_DS = 0x03;\n DebuggerX86.REG_FS = 0x04;\n DebuggerX86.REG_GS = 0x05;\n DebuggerX86.REG_UNKNOWN = 0x00;\n\n DebuggerX86.MOD_NODISP = 0x00; // use RM below, no displacement\n DebuggerX86.MOD_DISP8 = 0x01; // use RM below + 8-bit displacement\n DebuggerX86.MOD_DISP16 = 0x02; // use RM below + 16-bit displacement\n DebuggerX86.MOD_REGISTER = 0x03; // use REG above\n\n DebuggerX86.RM_BXSI = 0x00;\n DebuggerX86.RM_BXDI = 0x01;\n DebuggerX86.RM_BPSI = 0x02;\n DebuggerX86.RM_BPDI = 0x03;\n DebuggerX86.RM_SI = 0x04;\n DebuggerX86.RM_DI = 0x05;\n DebuggerX86.RM_BP = 0x06;\n DebuggerX86.RM_IMMOFF = DebuggerX86.RM_BP; // only if MOD_NODISP\n DebuggerX86.RM_BX = 0x07;\n\n DebuggerX86.RMS = [\n \"BX+SI\", \"BX+DI\", \"BP+SI\", \"BP+DI\", \"SI\", \"DI\", \"BP\", \"BX\",\n \"EAX\", \"ECX\", \"EDX\", \"EBX\", \"ESP\", \"EBP\", \"ESI\", \"EDI\"\n ];\n\n /*\n * Operand type descriptor masks and definitions\n *\n * Note that the letters in () in the comments refer to Intel's\n * nomenclature used in Appendix A of the 80386 Programmers Reference Manual.\n */\n DebuggerX86.TYPE_SIZE = 0x000F; // size field\n DebuggerX86.TYPE_MODE = 0x00F0; // mode field\n DebuggerX86.TYPE_IREG = 0x0F00; // implied register field\n DebuggerX86.TYPE_OTHER = 0xF000; // \"other\" field\n\n /*\n * TYPE_SIZE values. Some definitions use duplicate values when the operands are the\n * same size and the Debugger doesn't need to make a distinction.\n */\n DebuggerX86.TYPE_NONE = 0x0000; // (all other TYPE fields ignored)\n DebuggerX86.TYPE_BYTE = 0x0001; // (b) byte, regardless of operand size\n DebuggerX86.TYPE_SBYTE = 0x0002; // byte sign-extended to word\n DebuggerX86.TYPE_SHORT = 0x0003; // (w) 16-bit value\n DebuggerX86.TYPE_WORD = 0x0004; // (v) 16-bit or 32-bit value\n DebuggerX86.TYPE_LONG = 0x0005; // (d) 32-bit value\n DebuggerX86.TYPE_SEGP = 0x0006; // (p) 32-bit or 48-bit pointer\n DebuggerX86.TYPE_FARP = 0x0007; // (p) 32-bit or 48-bit pointer for JMP/CALL\n DebuggerX86.TYPE_PREFIX = 0x0008; // (treat similarly to TYPE_NONE)\n /*\n * The remaining TYPE_SIZE values are for the FPU. Note that there are not enough values\n * within this nibble for every type to have a unique value, so to differentiate between two\n * types of the same size (eg, SINT and SREAL), we can inspect the opcode string, because only\n * FI* instructions use INT operands. Also, some FPU sizes are not in this list (eg, the\n * so-called \"word-integer\"); since a word-integer is always 16 bits, we specify TYPE_SHORT,\n * which the Debugger should display as \"INT16\" for FI* instructions.\n */\n DebuggerX86.TYPE_ST = 0x0009; // FPU ST (implicit stack top)\n DebuggerX86.TYPE_STREG = 0x000A; // FPU ST (explicit stack register, relative to top)\n DebuggerX86.TYPE_SINT = 0x000B; // FPU SI (short-integer; 32-bit); displayed as \"INT32\"\n DebuggerX86.TYPE_SREAL = 0x000B; // FPU SR (short-real; 32-bit); displayed as \"REAL32\"\n DebuggerX86.TYPE_LINT = 0x000C; // FPU LI (long-integer; 64-bit); displayed as \"INT64\"\n DebuggerX86.TYPE_LREAL = 0x000C; // FPU LR (long-real; 64-bit); displayed as \"REAL64\"\n DebuggerX86.TYPE_TREAL = 0x000D; // FPU TR (temp-real; 80-bit); displayed as \"REAL80\"\n DebuggerX86.TYPE_BCD80 = 0x000E; // FPU PD (packed-decimal; 18 BCD digits in 80 bits, bits 72-78 unused, sign in bit 79); displayed as \"BCD80\"\n DebuggerX86.TYPE_ENV = 0x000F; // FPU ENV (environment; 14 bytes in real-mode, 28 bytes in protected-mode)\n DebuggerX86.TYPE_FPU = 0x000F; // FPU SAVE (save/restore; 94 bytes in real-mode, 108 bytes in protected-mode)\n\n /*\n * TYPE_MODE values. Order is somewhat important, as all values implying\n * the presence of a ModRM byte are assumed to be >= TYPE_MODRM.\n */\n DebuggerX86.TYPE_IMM = 0x0000; // (I) immediate data\n DebuggerX86.TYPE_ONE = 0x0010; // implicit 1 (eg, shifts/rotates)\n DebuggerX86.TYPE_IMMOFF = 0x0020; // (A) immediate offset\n DebuggerX86.TYPE_IMMREL = 0x0030; // (J) immediate relative\n DebuggerX86.TYPE_DSSI = 0x0040; // (X) memory addressed by DS:SI\n DebuggerX86.TYPE_ESDI = 0x0050; // (Y) memory addressed by ES:DI\n DebuggerX86.TYPE_IMPREG = 0x0060; // implicit register in TYPE_IREG\n DebuggerX86.TYPE_IMPSEG = 0x0070; // implicit segment reg in TYPE_IREG\n DebuggerX86.TYPE_MODRM = 0x0080; // (E) standard ModRM decoding\n DebuggerX86.TYPE_MODMEM = 0x0090; // (M) ModRM refers to memory only\n DebuggerX86.TYPE_MODREG = 0x00A0; // (R) ModRM refers to register only\n DebuggerX86.TYPE_REG = 0x00B0; // (G) standard Reg decoding\n DebuggerX86.TYPE_SEGREG = 0x00C0; // (S) Reg selects segment register\n DebuggerX86.TYPE_CTLREG = 0x00D0; // (C) Reg selects control register\n DebuggerX86.TYPE_DBGREG = 0x00E0; // (D) Reg selects debug register\n DebuggerX86.TYPE_TSTREG = 0x00F0; // (T) Reg selects test register\n\n /*\n * TYPE_IREG values, based on the REG_* constants.\n * For convenience, they include TYPE_IMPREG or TYPE_IMPSEG as appropriate.\n */\n DebuggerX86.TYPE_AL = (DebuggerX86.REG_AL << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_BYTE);\n DebuggerX86.TYPE_CL = (DebuggerX86.REG_CL << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_BYTE);\n DebuggerX86.TYPE_DL = (DebuggerX86.REG_DL << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_BYTE);\n DebuggerX86.TYPE_BL = (DebuggerX86.REG_BL << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_BYTE);\n DebuggerX86.TYPE_AH = (DebuggerX86.REG_AH << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_BYTE);\n DebuggerX86.TYPE_CH = (DebuggerX86.REG_CH << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_BYTE);\n DebuggerX86.TYPE_DH = (DebuggerX86.REG_DH << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_BYTE);\n DebuggerX86.TYPE_BH = (DebuggerX86.REG_BH << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_BYTE);\n DebuggerX86.TYPE_AX = (DebuggerX86.REG_AX << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_WORD);\n DebuggerX86.TYPE_CX = (DebuggerX86.REG_CX << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_WORD);\n DebuggerX86.TYPE_DX = (DebuggerX86.REG_DX << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_WORD);\n DebuggerX86.TYPE_BX = (DebuggerX86.REG_BX << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_WORD);\n DebuggerX86.TYPE_SP = (DebuggerX86.REG_SP << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_WORD);\n DebuggerX86.TYPE_BP = (DebuggerX86.REG_BP << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_WORD);\n DebuggerX86.TYPE_SI = (DebuggerX86.REG_SI << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_WORD);\n DebuggerX86.TYPE_DI = (DebuggerX86.REG_DI << 8 | DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_WORD);\n DebuggerX86.TYPE_ES = (DebuggerX86.REG_ES << 8 | DebuggerX86.TYPE_IMPSEG | DebuggerX86.TYPE_SHORT);\n DebuggerX86.TYPE_CS = (DebuggerX86.REG_CS << 8 | DebuggerX86.TYPE_IMPSEG | DebuggerX86.TYPE_SHORT);\n DebuggerX86.TYPE_SS = (DebuggerX86.REG_SS << 8 | DebuggerX86.TYPE_IMPSEG | DebuggerX86.TYPE_SHORT);\n DebuggerX86.TYPE_DS = (DebuggerX86.REG_DS << 8 | DebuggerX86.TYPE_IMPSEG | DebuggerX86.TYPE_SHORT);\n DebuggerX86.TYPE_FS = (DebuggerX86.REG_FS << 8 | DebuggerX86.TYPE_IMPSEG | DebuggerX86.TYPE_SHORT);\n DebuggerX86.TYPE_GS = (DebuggerX86.REG_GS << 8 | DebuggerX86.TYPE_IMPSEG | DebuggerX86.TYPE_SHORT);\n\n /*\n * TYPE_OTHER bit definitions\n */\n DebuggerX86.TYPE_IN = 0x1000; // operand is input\n DebuggerX86.TYPE_OUT = 0x2000; // operand is output\n DebuggerX86.TYPE_BOTH = (DebuggerX86.TYPE_IN | DebuggerX86.TYPE_OUT);\n DebuggerX86.TYPE_8086 = (DebuggerX86.CPU_8086 << 14);\n DebuggerX86.TYPE_8087 = DebuggerX86.TYPE_8086;\n DebuggerX86.TYPE_80186 = (DebuggerX86.CPU_80186 << 14);\n DebuggerX86.TYPE_80286 = (DebuggerX86.CPU_80286 << 14);\n DebuggerX86.TYPE_80287 = DebuggerX86.TYPE_80286;\n DebuggerX86.TYPE_80386 = (DebuggerX86.CPU_80386 << 14);\n DebuggerX86.TYPE_80387 = DebuggerX86.TYPE_80386;\n DebuggerX86.TYPE_CPU_SHIFT = 14;\n\n DebuggerX86.HISTORY_LIMIT = DEBUG? 100000 : 1000;\n\n /*\n * Opcode 0x0F has a distinguished history:\n *\n * On the 8086, it functioned as POP CS\n * On the 80186, it generated an Invalid Opcode (UD_FAULT) exception\n * On the 80286, it introduced a new (and growing) series of two-byte opcodes\n *\n * Based on the active CPU model, we make every effort to execute and disassemble this (and every other)\n * opcode appropriately, by setting the opcode's entry in aaOpDescs accordingly. 0x0F in aaOpDescs points\n * to the 8086 table: aOpDescPopCS.\n *\n * Note that we must NOT modify aaOpDescs directly. this.aaOpDescs will point to DebuggerX86.aaOpDescs\n * if the processor is an 8086, because that's the processor that the hard-coded contents of the table\n * represent; for all other processors, this.aaOpDescs will contain a copy of the table that we can modify.\n */\n DebuggerX86.aOpDescPopCS = [DebuggerX86.INS.POP, DebuggerX86.TYPE_CS | DebuggerX86.TYPE_OUT];\n DebuggerX86.aOpDescUndefined = [DebuggerX86.INS.NONE, DebuggerX86.TYPE_NONE];\n DebuggerX86.aOpDesc0F = [DebuggerX86.INS.OP0F, DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_BOTH];\n\n /*\n * The aaOpDescs array is indexed by opcode, and each element is a sub-array (aOpDesc) that describes\n * the corresponding opcode. The sub-elements are as follows:\n *\n * [0]: {number} of the opcode name (see INS.*)\n * [1]: {number} containing the destination operand descriptor bit(s), if any\n * [2]: {number} containing the source operand descriptor bit(s), if any\n * [3]: {number} containing the occasional third operand descriptor bit(s), if any\n *\n * These sub-elements are all optional. If [0] is not present, the opcode is undefined; if [1] is not\n * present (or contains zero), the opcode has no (or only implied) operands; if [2] is not present, the\n * opcode has only a single operand. And so on.\n */\n DebuggerX86.aaOpDescs = [\n /* 0x00 */ [DebuggerX86.INS.ADD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x01 */ [DebuggerX86.INS.ADD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x02 */ [DebuggerX86.INS.ADD, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x03 */ [DebuggerX86.INS.ADD, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x04 */ [DebuggerX86.INS.ADD, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x05 */ [DebuggerX86.INS.ADD, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x06 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_ES | DebuggerX86.TYPE_IN],\n /* 0x07 */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_ES | DebuggerX86.TYPE_OUT],\n\n /* 0x08 */ [DebuggerX86.INS.OR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x09 */ [DebuggerX86.INS.OR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x0A */ [DebuggerX86.INS.OR, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x0B */ [DebuggerX86.INS.OR, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x0C */ [DebuggerX86.INS.OR, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x0D */ [DebuggerX86.INS.OR, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x0E */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_CS | DebuggerX86.TYPE_IN],\n /* 0x0F */ DebuggerX86.aOpDescPopCS,\n\n /* 0x10 */ [DebuggerX86.INS.ADC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x11 */ [DebuggerX86.INS.ADC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x12 */ [DebuggerX86.INS.ADC, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x13 */ [DebuggerX86.INS.ADC, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x14 */ [DebuggerX86.INS.ADC, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x15 */ [DebuggerX86.INS.ADC, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x16 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_SS | DebuggerX86.TYPE_IN],\n /* 0x17 */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_SS | DebuggerX86.TYPE_OUT],\n\n /* 0x18 */ [DebuggerX86.INS.SBB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x19 */ [DebuggerX86.INS.SBB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x1A */ [DebuggerX86.INS.SBB, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x1B */ [DebuggerX86.INS.SBB, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x1C */ [DebuggerX86.INS.SBB, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x1D */ [DebuggerX86.INS.SBB, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x1E */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_DS | DebuggerX86.TYPE_IN],\n /* 0x1F */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_DS | DebuggerX86.TYPE_OUT],\n\n /* 0x20 */ [DebuggerX86.INS.AND, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x21 */ [DebuggerX86.INS.AND, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x22 */ [DebuggerX86.INS.AND, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x23 */ [DebuggerX86.INS.AND, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x24 */ [DebuggerX86.INS.AND, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x25 */ [DebuggerX86.INS.AND, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x26 */ [DebuggerX86.INS.ES, DebuggerX86.TYPE_PREFIX],\n /* 0x27 */ [DebuggerX86.INS.DAA],\n\n /* 0x28 */ [DebuggerX86.INS.SUB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x29 */ [DebuggerX86.INS.SUB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x2A */ [DebuggerX86.INS.SUB, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x2B */ [DebuggerX86.INS.SUB, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x2C */ [DebuggerX86.INS.SUB, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x2D */ [DebuggerX86.INS.SUB, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x2E */ [DebuggerX86.INS.CS, DebuggerX86.TYPE_PREFIX],\n /* 0x2F */ [DebuggerX86.INS.DAS],\n\n /* 0x30 */ [DebuggerX86.INS.XOR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x31 */ [DebuggerX86.INS.XOR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x32 */ [DebuggerX86.INS.XOR, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x33 */ [DebuggerX86.INS.XOR, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x34 */ [DebuggerX86.INS.XOR, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x35 */ [DebuggerX86.INS.XOR, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x36 */ [DebuggerX86.INS.SS, DebuggerX86.TYPE_PREFIX],\n /* 0x37 */ [DebuggerX86.INS.AAA],\n\n /* 0x38 */ [DebuggerX86.INS.CMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x39 */ [DebuggerX86.INS.CMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x3A */ [DebuggerX86.INS.CMP, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x3B */ [DebuggerX86.INS.CMP, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x3C */ [DebuggerX86.INS.CMP, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x3D */ [DebuggerX86.INS.CMP, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x3E */ [DebuggerX86.INS.DS, DebuggerX86.TYPE_PREFIX],\n /* 0x3F */ [DebuggerX86.INS.AAS],\n\n /* 0x40 */ [DebuggerX86.INS.INC, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH],\n /* 0x41 */ [DebuggerX86.INS.INC, DebuggerX86.TYPE_CX | DebuggerX86.TYPE_BOTH],\n /* 0x42 */ [DebuggerX86.INS.INC, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_BOTH],\n /* 0x43 */ [DebuggerX86.INS.INC, DebuggerX86.TYPE_BX | DebuggerX86.TYPE_BOTH],\n /* 0x44 */ [DebuggerX86.INS.INC, DebuggerX86.TYPE_SP | DebuggerX86.TYPE_BOTH],\n /* 0x45 */ [DebuggerX86.INS.INC, DebuggerX86.TYPE_BP | DebuggerX86.TYPE_BOTH],\n /* 0x46 */ [DebuggerX86.INS.INC, DebuggerX86.TYPE_SI | DebuggerX86.TYPE_BOTH],\n /* 0x47 */ [DebuggerX86.INS.INC, DebuggerX86.TYPE_DI | DebuggerX86.TYPE_BOTH],\n\n /* 0x48 */ [DebuggerX86.INS.DEC, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH],\n /* 0x49 */ [DebuggerX86.INS.DEC, DebuggerX86.TYPE_CX | DebuggerX86.TYPE_BOTH],\n /* 0x4A */ [DebuggerX86.INS.DEC, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_BOTH],\n /* 0x4B */ [DebuggerX86.INS.DEC, DebuggerX86.TYPE_BX | DebuggerX86.TYPE_BOTH],\n /* 0x4C */ [DebuggerX86.INS.DEC, DebuggerX86.TYPE_SP | DebuggerX86.TYPE_BOTH],\n /* 0x4D */ [DebuggerX86.INS.DEC, DebuggerX86.TYPE_BP | DebuggerX86.TYPE_BOTH],\n /* 0x4E */ [DebuggerX86.INS.DEC, DebuggerX86.TYPE_SI | DebuggerX86.TYPE_BOTH],\n /* 0x4F */ [DebuggerX86.INS.DEC, DebuggerX86.TYPE_DI | DebuggerX86.TYPE_BOTH],\n\n /* 0x50 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_IN],\n /* 0x51 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_CX | DebuggerX86.TYPE_IN],\n /* 0x52 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_IN],\n /* 0x53 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_BX | DebuggerX86.TYPE_IN],\n /* 0x54 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_SP | DebuggerX86.TYPE_IN],\n /* 0x55 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_BP | DebuggerX86.TYPE_IN],\n /* 0x56 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_SI | DebuggerX86.TYPE_IN],\n /* 0x57 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_DI | DebuggerX86.TYPE_IN],\n\n /* 0x58 */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_OUT],\n /* 0x59 */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_CX | DebuggerX86.TYPE_OUT],\n /* 0x5A */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_OUT],\n /* 0x5B */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_BX | DebuggerX86.TYPE_OUT],\n /* 0x5C */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_SP | DebuggerX86.TYPE_OUT],\n /* 0x5D */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_BP | DebuggerX86.TYPE_OUT],\n /* 0x5E */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_SI | DebuggerX86.TYPE_OUT],\n /* 0x5F */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_DI | DebuggerX86.TYPE_OUT],\n\n /* 0x60 */ [DebuggerX86.INS.PUSHA, DebuggerX86.TYPE_NONE | DebuggerX86.TYPE_80286],\n /* 0x61 */ [DebuggerX86.INS.POPA, DebuggerX86.TYPE_NONE | DebuggerX86.TYPE_80286],\n /* 0x62 */ [DebuggerX86.INS.BOUND, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x63 */ [DebuggerX86.INS.ARPL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n /* 0x64 */ [DebuggerX86.INS.FS, DebuggerX86.TYPE_PREFIX | DebuggerX86.TYPE_80386],\n /* 0x65 */ [DebuggerX86.INS.GS, DebuggerX86.TYPE_PREFIX | DebuggerX86.TYPE_80386],\n /* 0x66 */ [DebuggerX86.INS.OS, DebuggerX86.TYPE_PREFIX | DebuggerX86.TYPE_80386],\n /* 0x67 */ [DebuggerX86.INS.AS, DebuggerX86.TYPE_PREFIX | DebuggerX86.TYPE_80386],\n\n /* 0x68 */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286],\n /* 0x69 */ [DebuggerX86.INS.IMUL, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x6A */ [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SBYTE | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286],\n /* 0x6B */ [DebuggerX86.INS.IMUL, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x6C */ [DebuggerX86.INS.INS, DebuggerX86.TYPE_ESDI | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_IN],\n /* 0x6D */ [DebuggerX86.INS.INS, DebuggerX86.TYPE_ESDI | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_IN],\n /* 0x6E */ [DebuggerX86.INS.OUTS, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_DSSI | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x6F */ [DebuggerX86.INS.OUTS, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_DSSI | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n\n /* 0x70 */ [DebuggerX86.INS.JO, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x71 */ [DebuggerX86.INS.JNO, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x72 */ [DebuggerX86.INS.JC, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x73 */ [DebuggerX86.INS.JNC, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x74 */ [DebuggerX86.INS.JZ, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x75 */ [DebuggerX86.INS.JNZ, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x76 */ [DebuggerX86.INS.JBE, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x77 */ [DebuggerX86.INS.JA, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n\n /* 0x78 */ [DebuggerX86.INS.JS, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x79 */ [DebuggerX86.INS.JNS, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x7A */ [DebuggerX86.INS.JP, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x7B */ [DebuggerX86.INS.JNP, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x7C */ [DebuggerX86.INS.JL, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x7D */ [DebuggerX86.INS.JGE, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x7E */ [DebuggerX86.INS.JLE, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x7F */ [DebuggerX86.INS.JG, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n\n /* 0x80 */ [DebuggerX86.INS.GRP1B, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x81 */ [DebuggerX86.INS.GRP1W, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x82 */ [DebuggerX86.INS.GRP1B, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x83 */ [DebuggerX86.INS.GRP1SW,DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x84 */ [DebuggerX86.INS.TEST, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x85 */ [DebuggerX86.INS.TEST, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x86 */ [DebuggerX86.INS.XCHG, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH],\n /* 0x87 */ [DebuggerX86.INS.XCHG, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH],\n\n /* 0x88 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x89 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x8A */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0x8B */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x8C */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_SEGREG | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n /* 0x8D */ [DebuggerX86.INS.LEA, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_MODMEM | DebuggerX86.TYPE_WORD ],\n /* 0x8E */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_SEGREG | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0x8F */ [DebuggerX86.INS.POP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT],\n\n /* 0x90 */ [DebuggerX86.INS.NOP],\n /* 0x91 */ [DebuggerX86.INS.XCHG, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CX | DebuggerX86.TYPE_BOTH],\n /* 0x92 */ [DebuggerX86.INS.XCHG, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_BOTH],\n /* 0x93 */ [DebuggerX86.INS.XCHG, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_BX | DebuggerX86.TYPE_BOTH],\n /* 0x94 */ [DebuggerX86.INS.XCHG, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_SP | DebuggerX86.TYPE_BOTH],\n /* 0x95 */ [DebuggerX86.INS.XCHG, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_BP | DebuggerX86.TYPE_BOTH],\n /* 0x96 */ [DebuggerX86.INS.XCHG, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_SI | DebuggerX86.TYPE_BOTH],\n /* 0x97 */ [DebuggerX86.INS.XCHG, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_DI | DebuggerX86.TYPE_BOTH],\n\n /* 0x98 */ [DebuggerX86.INS.CBW],\n /* 0x99 */ [DebuggerX86.INS.CWD],\n /* 0x9A */ [DebuggerX86.INS.CALL, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_FARP | DebuggerX86.TYPE_IN],\n /* 0x9B */ [DebuggerX86.INS.WAIT],\n /* 0x9C */ [DebuggerX86.INS.PUSHF],\n /* 0x9D */ [DebuggerX86.INS.POPF],\n /* 0x9E */ [DebuggerX86.INS.SAHF],\n /* 0x9F */ [DebuggerX86.INS.LAHF],\n\n /* 0xA0 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMMOFF | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xA1 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMMOFF | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xA2 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_IMMOFF | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_IN],\n /* 0xA3 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_IMMOFF | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_IN],\n /* 0xA4 */ [DebuggerX86.INS.MOVSB, DebuggerX86.TYPE_ESDI | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_DSSI | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xA5 */ [DebuggerX86.INS.MOVSW, DebuggerX86.TYPE_ESDI | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_DSSI | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xA6 */ [DebuggerX86.INS.CMPSB, DebuggerX86.TYPE_ESDI | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_DSSI | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xA7 */ [DebuggerX86.INS.CMPSW, DebuggerX86.TYPE_ESDI | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_DSSI | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n\n /* 0xA8 */ [DebuggerX86.INS.TEST, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xA9 */ [DebuggerX86.INS.TEST, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xAA */ [DebuggerX86.INS.STOSB, DebuggerX86.TYPE_ESDI | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_IN],\n /* 0xAB */ [DebuggerX86.INS.STOSW, DebuggerX86.TYPE_ESDI | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_IN],\n /* 0xAC */ [DebuggerX86.INS.LODSB, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_DSSI | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xAD */ [DebuggerX86.INS.LODSW, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_DSSI | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xAE */ [DebuggerX86.INS.SCASB, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_ESDI | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xAF */ [DebuggerX86.INS.SCASW, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_ESDI | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n\n /* 0xB0 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xB1 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xB2 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_DL | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xB3 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_BL | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xB4 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_AH | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xB5 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_CH | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xB6 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_DH | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xB7 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_BH | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n\n /* 0xB8 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xB9 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_CX | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xBA */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xBB */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_BX | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xBC */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_SP | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xBD */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_BP | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xBE */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_SI | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xBF */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_DI | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n\n /* 0xC0 */ [DebuggerX86.INS.GRP2B, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80186, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xC1 */ [DebuggerX86.INS.GRP2W, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80186, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xC2 */ [DebuggerX86.INS.RET, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n /* 0xC3 */ [DebuggerX86.INS.RET],\n /* 0xC4 */ [DebuggerX86.INS.LES, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_MODMEM | DebuggerX86.TYPE_SEGP | DebuggerX86.TYPE_IN],\n /* 0xC5 */ [DebuggerX86.INS.LDS, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_MODMEM | DebuggerX86.TYPE_SEGP | DebuggerX86.TYPE_IN],\n /* 0xC6 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xC7 */ [DebuggerX86.INS.MOV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n\n /* 0xC8 */ [DebuggerX86.INS.ENTER, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xC9 */ [DebuggerX86.INS.LEAVE, DebuggerX86.TYPE_NONE | DebuggerX86.TYPE_80286],\n /* 0xCA */ [DebuggerX86.INS.RETF, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n /* 0xCB */ [DebuggerX86.INS.RETF],\n /* 0xCC */ [DebuggerX86.INS.INT3],\n /* 0xCD */ [DebuggerX86.INS.INT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xCE */ [DebuggerX86.INS.INTO],\n /* 0xCF */ [DebuggerX86.INS.IRET],\n\n /* 0xD0 */ [DebuggerX86.INS.GRP2B1,DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xD1 */ [DebuggerX86.INS.GRP2W1,DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xD2 */ [DebuggerX86.INS.GRP2BC,DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n /* 0xD3 */ [DebuggerX86.INS.GRP2WC,DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n /* 0xD4 */ [DebuggerX86.INS.AAM, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE],\n /* 0xD5 */ [DebuggerX86.INS.AAD, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE],\n /* 0xD6 */ [DebuggerX86.INS.SALC],\n /* 0xD7 */ [DebuggerX86.INS.XLAT],\n\n /* 0xD8 */ [DebuggerX86.INS.ESC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xD9 */ [DebuggerX86.INS.ESC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xDA */ [DebuggerX86.INS.ESC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xDB */ [DebuggerX86.INS.ESC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xDC */ [DebuggerX86.INS.ESC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xDD */ [DebuggerX86.INS.ESC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xDE */ [DebuggerX86.INS.ESC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xDF */ [DebuggerX86.INS.ESC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n\n /* 0xE0 */ [DebuggerX86.INS.LOOPNZ,DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xE1 */ [DebuggerX86.INS.LOOPZ, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xE2 */ [DebuggerX86.INS.LOOP, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xE3 */ [DebuggerX86.INS.JCXZ, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xE4 */ [DebuggerX86.INS.IN, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xE5 */ [DebuggerX86.INS.IN, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xE6 */ [DebuggerX86.INS.OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_IN],\n /* 0xE7 */ [DebuggerX86.INS.OUT, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_IN],\n\n /* 0xE8 */ [DebuggerX86.INS.CALL, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xE9 */ [DebuggerX86.INS.JMP, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n /* 0xEA */ [DebuggerX86.INS.JMP, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_FARP | DebuggerX86.TYPE_IN],\n /* 0xEB */ [DebuggerX86.INS.JMP, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n /* 0xEC */ [DebuggerX86.INS.IN, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n /* 0xED */ [DebuggerX86.INS.IN, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n /* 0xEE */ [DebuggerX86.INS.OUT, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_AL | DebuggerX86.TYPE_IN],\n /* 0xEF */ [DebuggerX86.INS.OUT, DebuggerX86.TYPE_DX | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_IN],\n\n /* 0xF0 */ [DebuggerX86.INS.LOCK, DebuggerX86.TYPE_PREFIX],\n /* 0xF1 */ [DebuggerX86.INS.NONE],\n /* 0xF2 */ [DebuggerX86.INS.REPNZ, DebuggerX86.TYPE_PREFIX],\n /* 0xF3 */ [DebuggerX86.INS.REPZ, DebuggerX86.TYPE_PREFIX],\n /* 0xF4 */ [DebuggerX86.INS.HLT],\n /* 0xF5 */ [DebuggerX86.INS.CMC],\n /* 0xF6 */ [DebuggerX86.INS.GRP3B, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH],\n /* 0xF7 */ [DebuggerX86.INS.GRP3W, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH],\n\n /* 0xF8 */ [DebuggerX86.INS.CLC],\n /* 0xF9 */ [DebuggerX86.INS.STC],\n /* 0xFA */ [DebuggerX86.INS.CLI],\n /* 0xFB */ [DebuggerX86.INS.STI],\n /* 0xFC */ [DebuggerX86.INS.CLD],\n /* 0xFD */ [DebuggerX86.INS.STD],\n /* 0xFE */ [DebuggerX86.INS.GRP4B, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH],\n /* 0xFF */ [DebuggerX86.INS.GRP4W, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH]\n ];\n\n DebuggerX86.aaOp0FDescs = {\n 0x00: [DebuggerX86.INS.GRP6, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_BOTH],\n 0x01: [DebuggerX86.INS.GRP7, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_BOTH],\n 0x02: [DebuggerX86.INS.LAR, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_MODMEM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_IN],\n 0x03: [DebuggerX86.INS.LSL, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_MODMEM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_IN],\n 0x05: [DebuggerX86.INS.LOADALL,DebuggerX86.TYPE_80286],\n 0x06: [DebuggerX86.INS.CLTS, DebuggerX86.TYPE_80286],\n 0x07: [DebuggerX86.INS.LOADALL,DebuggerX86.TYPE_80386], // TODO: implied operand is ES:[(E)DI]\n 0x20: [DebuggerX86.INS.MOV, DebuggerX86.TYPE_MODREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_CTLREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_IN],\n 0x21: [DebuggerX86.INS.MOV, DebuggerX86.TYPE_MODREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_DBGREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_IN],\n 0x22: [DebuggerX86.INS.MOV, DebuggerX86.TYPE_CTLREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_MODREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_IN],\n 0x23: [DebuggerX86.INS.MOV, DebuggerX86.TYPE_DBGREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_MODREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_IN],\n 0x24: [DebuggerX86.INS.MOV, DebuggerX86.TYPE_MODREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_TSTREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_IN],\n 0x26: [DebuggerX86.INS.MOV, DebuggerX86.TYPE_TSTREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_MODREG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_IN],\n 0x80: [DebuggerX86.INS.JO, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x81: [DebuggerX86.INS.JNO, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x82: [DebuggerX86.INS.JC, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x83: [DebuggerX86.INS.JNC, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x84: [DebuggerX86.INS.JZ, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x85: [DebuggerX86.INS.JNZ, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x86: [DebuggerX86.INS.JBE, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x87: [DebuggerX86.INS.JA, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x88: [DebuggerX86.INS.JS, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x89: [DebuggerX86.INS.JNS, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x8A: [DebuggerX86.INS.JP, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x8B: [DebuggerX86.INS.JNP, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x8C: [DebuggerX86.INS.JL, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x8D: [DebuggerX86.INS.JGE, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x8E: [DebuggerX86.INS.JLE, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x8F: [DebuggerX86.INS.JG, DebuggerX86.TYPE_IMMREL | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0x90: [DebuggerX86.INS.SETO, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x91: [DebuggerX86.INS.SETNO, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x92: [DebuggerX86.INS.SETC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x93: [DebuggerX86.INS.SETNC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x94: [DebuggerX86.INS.SETZ, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x95: [DebuggerX86.INS.SETNZ, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x96: [DebuggerX86.INS.SETBE, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x97: [DebuggerX86.INS.SETNBE, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x98: [DebuggerX86.INS.SETS, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x99: [DebuggerX86.INS.SETNS, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x9A: [DebuggerX86.INS.SETP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x9B: [DebuggerX86.INS.SETNP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x9C: [DebuggerX86.INS.SETL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x9D: [DebuggerX86.INS.SETGE, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x9E: [DebuggerX86.INS.SETLE, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0x9F: [DebuggerX86.INS.SETG, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0xA0: [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_FS | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0xA1: [DebuggerX86.INS.POP, DebuggerX86.TYPE_FS | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0xA3: [DebuggerX86.INS.BT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n 0xA4: [DebuggerX86.INS.SHLD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n 0xA5: [DebuggerX86.INS.SHLD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n 0xA6: [DebuggerX86.INS.XBTS, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n 0xA7: [DebuggerX86.INS.IBTS, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_AX | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n 0xA8: [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_GS | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386],\n 0xA9: [DebuggerX86.INS.POP, DebuggerX86.TYPE_GS | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386],\n 0xAB: [DebuggerX86.INS.BTS, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n 0xAC: [DebuggerX86.INS.SHRD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n 0xAD: [DebuggerX86.INS.SHRD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n 0xAF: [DebuggerX86.INS.IMUL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n 0xB2: [DebuggerX86.INS.LSS, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_MODMEM | DebuggerX86.TYPE_SEGP | DebuggerX86.TYPE_IN],\n 0xB3: [DebuggerX86.INS.BTR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n 0xB4: [DebuggerX86.INS.LFS, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_MODMEM | DebuggerX86.TYPE_SEGP | DebuggerX86.TYPE_IN],\n 0xB5: [DebuggerX86.INS.LGS, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_MODMEM | DebuggerX86.TYPE_SEGP | DebuggerX86.TYPE_IN],\n 0xB6: [DebuggerX86.INS.MOVZX, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n 0xB7: [DebuggerX86.INS.MOVZX, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0xBA: [DebuggerX86.INS.GRP8, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n 0xBB: [DebuggerX86.INS.BTC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n 0xBC: [DebuggerX86.INS.BSF, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n 0xBD: [DebuggerX86.INS.BSR, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n 0xBE: [DebuggerX86.INS.MOVSX, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n 0xBF: [DebuggerX86.INS.MOVSX, DebuggerX86.TYPE_REG | DebuggerX86.TYPE_LONG | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN]\n };\n\n /*\n * Be sure to keep the following table in sync with FPUX86.aaOps\n */\n DebuggerX86.aaaOpFPUDescs = {\n 0xD8: {\n 0x00: [DebuggerX86.FINS.FADD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_IN],\n 0x01: [DebuggerX86.FINS.FMUL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_IN],\n 0x02: [DebuggerX86.FINS.FCOM, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_IN],\n 0x03: [DebuggerX86.FINS.FCOMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_IN],\n 0x04: [DebuggerX86.FINS.FSUB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_IN],\n 0x05: [DebuggerX86.FINS.FSUBR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_IN],\n 0x06: [DebuggerX86.FINS.FDIV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_IN],\n 0x07: [DebuggerX86.FINS.FDIVR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_IN],\n 0x30: [DebuggerX86.FINS.FADD, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN],\n 0x31: [DebuggerX86.FINS.FMUL, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN],\n 0x32: [DebuggerX86.FINS.FCOM, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN],\n 0x33: [DebuggerX86.FINS.FCOMP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN],\n 0x34: [DebuggerX86.FINS.FSUB, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN],\n 0x35: [DebuggerX86.FINS.FSUBR, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN],\n 0x36: [DebuggerX86.FINS.FDIV, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN],\n 0x37: [DebuggerX86.FINS.FDIVR, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN]\n },\n 0xD9: {\n 0x00: [DebuggerX86.FINS.FLD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_IN],\n 0x02: [DebuggerX86.FINS.FST, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_OUT],\n 0x03: [DebuggerX86.FINS.FSTP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SREAL | DebuggerX86.TYPE_OUT],\n 0x04: [DebuggerX86.FINS.FLDENV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_ENV | DebuggerX86.TYPE_IN],\n 0x05: [DebuggerX86.FINS.FLDCW, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0x06: [DebuggerX86.FINS.FSTENV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_ENV | DebuggerX86.TYPE_OUT],\n 0x07: [DebuggerX86.FINS.FSTCW, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_OUT],\n 0x30: [DebuggerX86.FINS.FLD, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT],\n 0x31: [DebuggerX86.FINS.FXCH, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT],\n 0x32: [DebuggerX86.FINS.FNOP],\n 0x33: [DebuggerX86.FINS.FSTP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT], // Obsolete encoding\n 0x40: [DebuggerX86.FINS.FCHS],\n 0x41: [DebuggerX86.FINS.FABS],\n 0x44: [DebuggerX86.FINS.FTST],\n 0x45: [DebuggerX86.FINS.FXAM],\n 0x50: [DebuggerX86.FINS.FLD1],\n 0x51: [DebuggerX86.FINS.FLDL2T],\n 0x52: [DebuggerX86.FINS.FLDL2E],\n 0x53: [DebuggerX86.FINS.FLDPI],\n 0x54: [DebuggerX86.FINS.FLDLG2],\n 0x55: [DebuggerX86.FINS.FLDLN2],\n 0x56: [DebuggerX86.FINS.FLDZ],\n 0x60: [DebuggerX86.FINS.F2XM1],\n 0x61: [DebuggerX86.FINS.FYL2X],\n 0x62: [DebuggerX86.FINS.FPTAN],\n 0x63: [DebuggerX86.FINS.FPATAN],\n 0x64: [DebuggerX86.FINS.FXTRACT],\n 0x66: [DebuggerX86.FINS.FDECSTP],\n 0x67: [DebuggerX86.FINS.FINCSTP],\n 0x70: [DebuggerX86.FINS.FPREM],\n 0x71: [DebuggerX86.FINS.FYL2XP1],\n 0x72: [DebuggerX86.FINS.FSQRT],\n 0x74: [DebuggerX86.FINS.FRNDINT],\n 0x75: [DebuggerX86.FINS.FSCALE]\n },\n 0xDA: {\n 0x00: [DebuggerX86.FINS.FIADD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_IN],\n 0x01: [DebuggerX86.FINS.FIMUL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_IN],\n 0x02: [DebuggerX86.FINS.FICOM, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_IN],\n 0x03: [DebuggerX86.FINS.FICOMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_IN],\n 0x04: [DebuggerX86.FINS.FISUB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_IN],\n 0x05: [DebuggerX86.FINS.FISUBR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_IN],\n 0x06: [DebuggerX86.FINS.FIDIV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_IN],\n 0x07: [DebuggerX86.FINS.FIDIVR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_IN]\n },\n 0xDB: {\n 0x00: [DebuggerX86.FINS.FILD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_IN],\n 0x02: [DebuggerX86.FINS.FIST, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_OUT],\n 0x03: [DebuggerX86.FINS.FISTP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SINT | DebuggerX86.TYPE_OUT],\n 0x05: [DebuggerX86.FINS.FLD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_TREAL | DebuggerX86.TYPE_IN],\n 0x07: [DebuggerX86.FINS.FSTP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_TREAL | DebuggerX86.TYPE_OUT],\n 0x40: [DebuggerX86.FINS.FENI],\n 0x41: [DebuggerX86.FINS.FDISI],\n 0x42: [DebuggerX86.FINS.FCLEX],\n 0x43: [DebuggerX86.FINS.FINIT],\n 0x44: [DebuggerX86.FINS.FSETPM, DebuggerX86.TYPE_80287],\n 0x73: [DebuggerX86.FINS.FSINCOS, DebuggerX86.TYPE_80387]\n },\n 0xDC: {\n 0x00: [DebuggerX86.FINS.FADD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_IN],\n 0x01: [DebuggerX86.FINS.FMUL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_IN],\n 0x02: [DebuggerX86.FINS.FCOM, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_IN],\n 0x03: [DebuggerX86.FINS.FCOMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_IN],\n 0x04: [DebuggerX86.FINS.FSUB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_IN],\n 0x05: [DebuggerX86.FINS.FSUBR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_IN],\n 0x06: [DebuggerX86.FINS.FDIV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_IN],\n 0x07: [DebuggerX86.FINS.FDIVR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_IN],\n 0x30: [DebuggerX86.FINS.FADD, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN],\n 0x31: [DebuggerX86.FINS.FMUL, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN],\n 0x32: [DebuggerX86.FINS.FCOM, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN], // Obsolete encoding\n 0x33: [DebuggerX86.FINS.FCOMP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN], // Obsolete encoding\n 0x34: [DebuggerX86.FINS.FSUBR, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN],\n 0x35: [DebuggerX86.FINS.FSUB, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN],\n 0x36: [DebuggerX86.FINS.FDIVR, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN],\n 0x37: [DebuggerX86.FINS.FDIV, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN]\n },\n 0xDD: {\n 0x00: [DebuggerX86.FINS.FLD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_IN],\n 0x02: [DebuggerX86.FINS.FST, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_OUT],\n 0x03: [DebuggerX86.FINS.FSTP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LREAL | DebuggerX86.TYPE_OUT],\n 0x04: [DebuggerX86.FINS.FRSTOR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_FPU | DebuggerX86.TYPE_IN],\n 0x06: [DebuggerX86.FINS.FSAVE, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_FPU | DebuggerX86.TYPE_OUT],\n 0x07: [DebuggerX86.FINS.FSTSW, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_OUT],\n 0x30: [DebuggerX86.FINS.FFREE, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN],\n 0x31: [DebuggerX86.FINS.FXCH, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT], // Obsolete encoding\n 0x32: [DebuggerX86.FINS.FST, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN],\n 0x33: [DebuggerX86.FINS.FSTP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN]\n },\n 0xDE: {\n 0x00: [DebuggerX86.FINS.FIADD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0x01: [DebuggerX86.FINS.FIMUL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0x02: [DebuggerX86.FINS.FICOM, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0x03: [DebuggerX86.FINS.FICOMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0x04: [DebuggerX86.FINS.FISUB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0x05: [DebuggerX86.FINS.FISUBR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0x06: [DebuggerX86.FINS.FIDIV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0x07: [DebuggerX86.FINS.FIDIVR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0x30: [DebuggerX86.FINS.FADDP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN],\n 0x31: [DebuggerX86.FINS.FMULP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN],\n 0x32: [DebuggerX86.FINS.FCOMP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN], // Obsolete encoding\n 0x33: [DebuggerX86.FINS.FCOMPP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN],\n 0x34: [DebuggerX86.FINS.FSUBRP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN],\n 0x35: [DebuggerX86.FINS.FSUBP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN],\n 0x36: [DebuggerX86.FINS.FDIVRP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN],\n 0x37: [DebuggerX86.FINS.FDIVP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_ST | DebuggerX86.TYPE_IN]\n },\n 0xDF: {\n 0x00: [DebuggerX86.FINS.FILD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_IN],\n 0x02: [DebuggerX86.FINS.FIST, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_OUT],\n 0x03: [DebuggerX86.FINS.FISTP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT | DebuggerX86.TYPE_OUT],\n 0x04: [DebuggerX86.FINS.FBLD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BCD80 | DebuggerX86.TYPE_IN],\n 0x05: [DebuggerX86.FINS.FILD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LINT | DebuggerX86.TYPE_IN],\n 0x06: [DebuggerX86.FINS.FBSTP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BCD80 | DebuggerX86.TYPE_OUT],\n 0x07: [DebuggerX86.FINS.FISTP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_LINT | DebuggerX86.TYPE_OUT],\n 0x30: [DebuggerX86.FINS.FFREEP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN], // Obsolete encoding\n 0x31: [DebuggerX86.FINS.FXCH, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_OUT], // Obsolete encoding\n 0x32: [DebuggerX86.FINS.FSTP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN], // Obsolete encoding\n 0x33: [DebuggerX86.FINS.FSTP, DebuggerX86.TYPE_IMPREG | DebuggerX86.TYPE_STREG | DebuggerX86.TYPE_IN], // Obsolete encoding\n 0x34: [DebuggerX86.FINS.FSTSWAX, DebuggerX86.TYPE_80287]\n }\n };\n\n DebuggerX86.aaGrpDescs = [\n [\n /* GRP1B */\n [DebuggerX86.INS.ADD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.OR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.ADC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SBB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.AND, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SUB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.XOR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.CMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN]\n ],\n [\n /* GRP1W */\n [DebuggerX86.INS.ADD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.OR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.ADC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SBB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.AND, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SUB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.XOR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.CMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN]\n ],\n [\n /* GRP1SW */\n [DebuggerX86.INS.ADD, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SBYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.OR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SBYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.ADC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SBYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SBB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SBYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.AND, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SBYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SUB, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SBYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.XOR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SBYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.CMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_SBYTE | DebuggerX86.TYPE_IN]\n ],\n [\n /* GRP2B */\n [DebuggerX86.INS.ROL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.ROR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n DebuggerX86.aOpDescUndefined,\n [DebuggerX86.INS.SAR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN]\n ],\n [\n /* GRP2W */\n [DebuggerX86.INS.ROL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.ROR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n DebuggerX86.aOpDescUndefined,\n [DebuggerX86.INS.SAR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH | DebuggerX86.TYPE_80286, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN]\n ],\n [\n /* GRP2B1 */\n [DebuggerX86.INS.ROL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.ROR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n DebuggerX86.aOpDescUndefined,\n [DebuggerX86.INS.SAR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN]\n ],\n [\n /* GRP2W1 */\n [DebuggerX86.INS.ROL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.ROR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n DebuggerX86.aOpDescUndefined,\n [DebuggerX86.INS.SAR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_ONE | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN]\n ],\n [\n /* GRP2BC */\n [DebuggerX86.INS.ROL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.ROR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n DebuggerX86.aOpDescUndefined,\n [DebuggerX86.INS.SAR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN]\n ],\n [\n /* GRP2WC */\n [DebuggerX86.INS.ROL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.ROR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.RCR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.SHR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN],\n DebuggerX86.aOpDescUndefined,\n [DebuggerX86.INS.SAR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH, DebuggerX86.TYPE_CL | DebuggerX86.TYPE_IN]\n ],\n [\n /* GRP3B */\n [DebuggerX86.INS.TEST, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n DebuggerX86.aOpDescUndefined,\n [DebuggerX86.INS.NOT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH],\n [DebuggerX86.INS.NEG, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH],\n [DebuggerX86.INS.MUL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.IMUL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH],\n [DebuggerX86.INS.DIV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.IDIV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH]\n ],\n [\n /* GRP3W */\n [DebuggerX86.INS.TEST, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n DebuggerX86.aOpDescUndefined,\n [DebuggerX86.INS.NOT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH],\n [DebuggerX86.INS.NEG, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH],\n [DebuggerX86.INS.MUL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.IMUL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH],\n [DebuggerX86.INS.DIV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.IDIV, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH]\n ],\n [\n /* GRP4B */\n [DebuggerX86.INS.INC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH],\n [DebuggerX86.INS.DEC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_BOTH],\n DebuggerX86.aOpDescUndefined,\n DebuggerX86.aOpDescUndefined,\n DebuggerX86.aOpDescUndefined,\n DebuggerX86.aOpDescUndefined,\n DebuggerX86.aOpDescUndefined,\n DebuggerX86.aOpDescUndefined\n ],\n [\n /* GRP4W */\n [DebuggerX86.INS.INC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH],\n [DebuggerX86.INS.DEC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_BOTH],\n [DebuggerX86.INS.CALL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.CALL, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_FARP | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.JMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.JMP, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_FARP | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.PUSH, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN],\n DebuggerX86.aOpDescUndefined\n ],\n [ /* OP0F */ ],\n [\n /* GRP6 */\n [DebuggerX86.INS.SLDT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80286],\n [DebuggerX86.INS.STR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80286],\n [DebuggerX86.INS.LLDT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286],\n [DebuggerX86.INS.LTR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286],\n [DebuggerX86.INS.VERR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286],\n [DebuggerX86.INS.VERW, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286],\n DebuggerX86.aOpDescUndefined,\n DebuggerX86.aOpDescUndefined\n ],\n [\n /* GRP7 */\n [DebuggerX86.INS.SGDT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80286],\n [DebuggerX86.INS.SIDT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80286],\n [DebuggerX86.INS.LGDT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286],\n [DebuggerX86.INS.LIDT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286],\n [DebuggerX86.INS.SMSW, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80286],\n DebuggerX86.aOpDescUndefined,\n [DebuggerX86.INS.LMSW, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_SHORT| DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80286],\n DebuggerX86.aOpDescUndefined\n ],\n [\n /* GRP8 */\n DebuggerX86.aOpDescUndefined,\n DebuggerX86.aOpDescUndefined,\n DebuggerX86.aOpDescUndefined,\n DebuggerX86.aOpDescUndefined,\n [DebuggerX86.INS.BT, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_IN | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.BTS, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.BTR, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN],\n [DebuggerX86.INS.BTC, DebuggerX86.TYPE_MODRM | DebuggerX86.TYPE_WORD | DebuggerX86.TYPE_OUT | DebuggerX86.TYPE_80386, DebuggerX86.TYPE_IMM | DebuggerX86.TYPE_BYTE | DebuggerX86.TYPE_IN]\n ]\n ];\n\n /*\n * Table of system (non-segment) descriptors, including indicators of which ones are gates.\n */\n DebuggerX86.SYSDESCS = {\n 0x0100: [\"tss286\", false],\n 0x0200: [\"ldt\", false],\n 0x0300: [\"busy tss286\", false],\n 0x0400: [\"call gate\", true],\n 0x0500: [\"task gate\", true],\n 0x0600: [\"int gate286\", true],\n 0x0700: [\"trap gate286\", true],\n 0x0900: [\"tss386\", false],\n 0x0B00: [\"busy tss386\", false],\n 0x0C00: [\"call gate386\", true],\n 0x0E00: [\"int gate386\", true],\n 0x0F00: [\"trap gate386\", true]\n };\n\n /*\n * TSS field names and offsets used by dumpTSS()\n */\n DebuggerX86.TSS286 = {\n \"PREV_TSS\": 0x00,\n \"CPL0_SP\": 0x02,\n \"CPL0_SS\": 0x04,\n \"CPL1_SP\": 0x06,\n \"CPL1_SS\": 0x08,\n \"CPL2_SP\": 0x0a,\n \"CPL2_SS\": 0x0c,\n \"TASK_IP\": 0x0e,\n \"TASK_PS\": 0x10,\n \"TASK_AX\": 0x12,\n \"TASK_CX\": 0x14,\n \"TASK_DX\": 0x16,\n \"TASK_BX\": 0x18,\n \"TASK_SP\": 0x1a,\n \"TASK_BP\": 0x1c,\n \"TASK_SI\": 0x1e,\n \"TASK_DI\": 0x20,\n \"TASK_ES\": 0x22,\n \"TASK_CS\": 0x24,\n \"TASK_SS\": 0x26,\n \"TASK_DS\": 0x28,\n \"TASK_LDT\": 0x2a\n };\n DebuggerX86.TSS386 = {\n \"PREV_TSS\": 0x00,\n \"CPL0_ESP\": 0x04,\n \"CPL0_SS\": 0x08,\n \"CPL1_ESP\": 0x0c,\n \"CPL1_SS\": 0x10,\n \"CPL2_ESP\": 0x14,\n \"CPL2_SS\": 0x18,\n \"TASK_CR3\": 0x1C,\n \"TASK_EIP\": 0x20,\n \"TASK_PS\": 0x24,\n \"TASK_EAX\": 0x28,\n \"TASK_ECX\": 0x2C,\n \"TASK_EDX\": 0x30,\n \"TASK_EBX\": 0x34,\n \"TASK_ESP\": 0x38,\n \"TASK_EBP\": 0x3C,\n \"TASK_ESI\": 0x40,\n \"TASK_EDI\": 0x44,\n \"TASK_ES\": 0x48,\n \"TASK_CS\": 0x4C,\n \"TASK_SS\": 0x50,\n \"TASK_DS\": 0x54,\n \"TASK_FS\": 0x58,\n \"TASK_GS\": 0x5C,\n \"TASK_LDT\": 0x60,\n \"TASK_IOPM\": 0x64\n };\n\n /*\n * Initialize every Debugger module on the page (as IF there's ever going to be more than one ;-))\n */\n Web.onInit(DebuggerX86.init);\n\n} // endif DEBUGGER\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pcx86/lib/computer.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * BUILD INSTRUCTIONS\n *\n * To build PCx86 (pcx86.js), run Google's Closure Compiler, replacing \"*.js\" with the input file sequence defined\n * by the \"PCx86Files\" property in package.json:\n *\n * java -jar compiler.jar\n * --compilation_level ADVANCED_OPTIMIZATIONS\n * --define='DEBUG=false'\n * --warning_level=VERBOSE\n * --js *.js\n * --js_output_file pc.js\n *\n * Google's Closure Compiler (compiler.jar) is documented at https://developers.google.com/closure/compiler/\n * and is available for download here:\n *\n * http://closure-compiler.googlecode.com/files/compiler-latest.zip\n *\n * The PCx86 JavaScript files do have some initialization-order dependencies. If you load the files individually,\n * it's recommended that you load them in the same order that they're compiled.\n *\n * Generally speaking, component.js should be first, computer.js should be last (of the files based on component.js),\n * and panel.js should be listed early so that the Control Panel is ready as soon as possible.\n *\n * Another recent ordering requirement is that rom.js must be loaded before ram.js; this was true before, but now\n * it's required, because I'm starting to add ROM BIOS Data Area definitions to rom.js, and since the data area\n * is in RAM, ram.js may want access to some of those definitions.\n */\n\n\n\n/**\n * class Computer\n * @unrestricted (allows the class to define properties, both dot and named, outside of the constructor)\n */\nclass Computer extends Component {\n /**\n * Computer(parmsComputer, parmsMachine, fSuspended)\n *\n * The Computer component has no required (parmsComputer) properties, but it does\n * support the following:\n *\n * autoPower: true to automatically power the computer (default), false to wait;\n * false is honored only if a \"power\" button binding exists.\n *\n * busWidth: number of memory address lines (address bits) on the computer's \"bus\";\n * 20 is the minimum (and the default), which implies 8086/8088 real-mode addressing,\n * while 24 is required for 80286 protected-mode addressing. This value is passed\n * directly through to the Bus component; see that component for more details.\n *\n * resume: one of the Computer.RESUME constants, which are as follows:\n * '0' if resume disabled (default)\n * '1' if enabled without prompting\n * '2' if enabled with prompting\n * '3' if enabled with prompting and auto-delete\n * or a string containing the path of a predefined JSON-encoded state\n *\n * state: the path to JSON-encoded state file (see details regarding 'state' below)\n *\n * The parmsMachine object, if provided, may contain any of:\n *\n * autoMount: if set, this should override any 'autoMount' property in the FDC's\n * parmsFDC object.\n *\n * autoPower: if set, this should override any 'autoPower' property in the Computer's\n * parmsComputer object.\n *\n * messages: if set, this should override any 'messages' property in the Debugger's\n * parmsDbg object.\n *\n * state: if set, this should override any 'state' property in the Computer's\n * parmsComputer object.\n *\n * url: the location of the machine XML file\n *\n * diagnostics: 0 for none, 1 for normal diagnostics, and 2 for diagnostics with prompting\n *\n * If a predefined state is supplied AND it's successfully loaded, then resume behavior\n * defaults to '1' (ie, resume enabled without prompting).\n *\n * This component insures that all components are ready before \"powering\" them.\n *\n * Different components become ready at different times, and initialization order (ie,\n * the order the scripts are combined on the page) only partially determines readiness.\n * This is because components like ROM and Video must finish loading their resource files\n * before they are ready. Other components become ready after we call their initBus()\n * function, because they have a Bus or CPU dependency, such as access to memory management\n * functions. And other components, like CPU and Panel, are ready as soon as their\n * constructor finishes.\n *\n * Once a component has indicated it's ready, we call its powerUp() notification\n * function (if it has one--it's optional). We call the CPU's powerUp() function last,\n * so that the CPU is assured that all other components are ready and \"powered\".\n *\n * @this {Computer}\n * @param {Object} parmsComputer\n * @param {Object} [parmsMachine]\n * @param {boolean} [fSuspended]\n */\n constructor(parmsComputer, parmsMachine, fSuspended)\n {\n super(\"Computer\", parmsComputer, Messages.COMPUTER);\n\n var cmp = this;\n this.setMachineParms(parmsMachine);\n\n this.fAutoPower = this.getMachineParm('autoPower', parmsComputer);\n this.nDiagnostics = +this.getMachineParm('diagnostics', parmsComputer);\n if (!(this.nDiagnostics >= 0 && this.nDiagnostics <= 2)) this.nDiagnostics = 1;\n\n /*\n * nPowerChange is 0 while the power state is stable, 1 while power is transitioning\n * to \"on\", and -1 while power is transitioning to \"off\".\n */\n this.nPowerChange = 0;\n\n /*\n * TODO: Deprecate 'buswidth' (it should have always used camelCase)\n */\n this.nBusWidth = parmsComputer['busWidth'] || parmsComputer['buswidth'];\n\n this.resume = Computer.RESUME_NONE;\n this.sStateData = null;\n this.fStateData = false; // remembers if sStateData was loaded\n this.fServerState = false;\n\n this.url = this.getMachineParm('url') || \"\";\n\n /*\n * Generate a random number x (where 0 <= x < 1), add 0.1 so that it's guaranteed to be\n * non-zero, convert to base 36, and chop off the leading digit and \"decimal\" point.\n */\n this.sMachineID = (Math.random() + 0.1).toString(36).substr(2,12);\n this.sUserID = this.queryUserID();\n\n /*\n * Find the appropriate CPU (and Debugger and Control Panel, if any)\n *\n * CLOSURE COMPILER TIP: To override the type of a right-hand expression (as we need to do here,\n * where we know getComponentByType() will only return an CPUX86 object or null), wrap the expression\n * in parentheses. I never knew this until I stumbled across it in \"Closure: The Definitive Guide\".\n */\n this.cpu = /** @type {CPUX86} */ (Component.getComponentByType(\"CPU\", this.id));\n if (!this.cpu) {\n Component.error(\"Unable to find CPU component\");\n return;\n }\n this.dbg = /** @type {DebuggerX86} */ (Component.getComponentByType(\"Debugger\", this.id));\n\n /*\n * Enumerate all the Video components for diagnostic displays, focus changes, and updateStatus() calls.\n */\n this.aVideo = [];\n for (var video = null; (video = this.getMachineComponent(\"Video\", video));) {\n this.aVideo.push(video);\n }\n\n /*\n * Initialize the Bus component\n */\n this.bus = new Bus({'id': this.idMachine + '.bus', 'busWidth': this.nBusWidth}, this.cpu, this.dbg);\n\n /*\n * Iterate through all the components and override their notice() and println() methods\n * so that their output can be rerouted to a Diagnostic Display or Control Panel, if any.\n */\n var iComponent, component;\n var aComponents = Component.getComponents(this.id);\n\n this.panel = /** @type {Panel} */ (Component.getComponentByType(\"Panel\", this.id));\n this.controlPanel = this.panel && this.panel.bindings['print'];\n\n this.noticeComputer = this.notice;\n this.printComputer = this.print;\n this.printlnComputer = this.println;\n if (this.controlPanel) {\n this.noticeComputer = this.panel.notice;\n this.printComputer = this.panel.print;\n this.printlnComputer = this.panel.println;\n }\n\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n component.notice = function noticeComputer(s, fPrintOnly, id) {\n cmp.outputDiagnostics(s);\n return cmp.noticeComputer.call(this, s, fPrintOnly, id);\n }.bind(component);\n component.print = function printComputer(s) {\n return cmp.printComputer.call(this, s);\n }.bind(component);\n component.println = function printlnComputer(s, type, id) {\n cmp.outputDiagnostics(s, type);\n return cmp.printlnComputer.call(this, s, type, id);\n }.bind(component);\n }\n\n this.cDiagnosticScreens = 0;\n if (!this.controlPanel && this.nDiagnostics) {\n this.enableDiagnostics();\n }\n\n this.println(PCX86.APPNAME + \" v\" + (XMLVERSION || PCX86.APPVERSION) + \"\\n\" + COPYRIGHT + \"\\n\" + LICENSE);\n\n if (DEBUG && this.messageEnabled()) this.printMessage(\"PREFETCH: \" + PREFETCH + \", TYPEDARRAYS: \" + TYPEDARRAYS);\n\n /*\n * Iterate through all the components again and call their initBus() handler, if any\n */\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component.initBus) component.initBus(this, this.bus, this.cpu, this.dbg);\n }\n\n /*\n * This timer replaces the CPU's old dedicated STATUS_UPDATES_PER_SECOND logic; periodic updateStatus()\n * calls are now our own responsibility.\n */\n this.cpu.addTimer(this.id, function updateStatusTimer() {\n cmp.updateStatus(false);\n }, 1000 / Computer.UPDATES_PER_SECOND);\n\n var sStatePath = null;\n var sResume = this.getMachineParm('resume');\n if (sResume !== undefined) {\n /*\n * Decide whether the 'resume' property is a number or the path of a state file to resume.\n */\n if (sResume.length > 1) {\n sStatePath = this.sResumePath = sResume;\n } else {\n this.resume = parseInt(sResume, 10);\n }\n }\n\n /*\n * The Computer 'state' property allows a state file to be specified independent of the 'resume' feature;\n * previously, you could only use 'resume' to load a state file -- which we still support, but loading a state\n * file that way prevents the machine's state from being saved, since we always resume from the 'resume' file.\n *\n * The other wrinkle is on the restore side: we need to IGNORE the 'state' property if a saved state now exists.\n * So we have to peek at localStorage, and unfortunately, the only way to \"peek\" is to actually load the data,\n * but we're not ready to use it yet, so powerUp() has been changed to use any existing stateComputer that we've\n * already loaded.\n *\n * However, there's now a wrinkle to the wrinkle: if a 'state' parameter has been passed via the URL, then that\n * OVERRIDES everything; it overrides any 'state' Computer parameter AND it disables resume of any saved state in\n * localStorage (in other words, it prevents fAllowResume from being true, and forcing resume off).\n */\n var fAllowResume = false;\n var sState = Web.getURLParm('state');\n if (!sState) {\n fAllowResume = true;\n sState = this.getMachineParm('state', parmsComputer);\n }\n if (sState) {\n sStatePath = this.sStatePath = sState;\n if (!fAllowResume) {\n this.fServerState = true;\n this.resume = Computer.RESUME_NONE;\n }\n if (this.resume) {\n this.stateComputer = new State(this, PCX86.APPVERSION);\n if (this.stateComputer.load()) {\n sStatePath = null;\n } else {\n delete this.stateComputer;\n }\n }\n }\n\n /*\n * If sStatePath is set, we must use it. But if there's no sStatePath AND resume is set,\n * then we have the option of resuming from a server-side state, assuming a valid USERID.\n */\n if (!sStatePath && this.resume) {\n sStatePath = this.getServerStatePath();\n if (sStatePath) this.fServerState = true;\n }\n\n this.sStateURL = sStatePath;\n\n if (!this.sStateURL) {\n this.setReady();\n } else {\n var sProgress = \"Loading \" + this.sStateURL + \"...\";\n Web.getResource(this.sStateURL, null, true, function(sURL, sResource, nErrorCode) {\n cmp.doneLoad(sURL, sResource, nErrorCode);\n }, function(nState) {\n cmp.println(sProgress, Component.PRINT.PROGRESS);\n });\n }\n\n if (!this.bindings[\"power\"]) this.fAutoPower = true;\n\n /*\n * Power on the computer, giving every component the opportunity to reset or restore itself.\n */\n if (!fSuspended && this.fAutoPower) this.wait(this.powerOn);\n }\n\n /**\n * clearPanel()\n *\n * @this {Computer}\n */\n clearPanel()\n {\n if (this.controlPanel) {\n this.controlPanel.value = \"\";\n }\n }\n\n /**\n * enableDiagnostics()\n *\n * @this {Computer}\n */\n enableDiagnostics()\n {\n if (!this.cDiagnosticScreens) {\n for (var i = 0; i < this.aVideo.length; i++) {\n var video = this.aVideo[i];\n if (video) {\n var control = video.getTextArea();\n if (control) {\n /*\n * By default, the Video textarea overlay has opacity and lineHeight styles set to \"0\"\n * to make the overall textarea and its blinking caret invisible (respectively), so in order\n * to use it as a diagnostic display, we must temporarily set both those styles to \"1\".\n */\n control.style.opacity = \"1\";\n control.style.lineHeight = \"1\";\n // control.style.fontSize = \"1.5vw\"; // this is a nice idea, but it doesn't work well with side-by-side machines\n this.cDiagnosticScreens++;\n }\n }\n }\n }\n }\n\n /**\n * disableDiagnostics()\n *\n * @this {Computer}\n * @return {boolean} (true if diagnostics were, or already are, disabled; false if they remain enabled)\n */\n disableDiagnostics()\n {\n if (this.cDiagnosticScreens) {\n if (this.nDiagnostics == 2) {\n this.nDiagnostics++;\n this.println(\"Press any key to continue...\");\n return false;\n }\n for (var i = 0; i < this.aVideo.length; i++) {\n var video = this.aVideo[i];\n if (video) {\n var control = video.getTextArea();\n if (control) {\n /*\n * Return the Video textarea overlay's opacity and lineHeight styles to their original values.\n */\n control.style.opacity = \"0\";\n control.style.lineHeight = \"0\";\n /*\n * Setting lineHeight in IE isn't sufficient to hide the caret; we must also set fontSize to \"0\",\n * and we make the change IE-specific because it can have weird side-effects in other browsers (eg,\n * it makes Safari on iOS over-zoom whenever the textarea receives focus).\n */\n if (Web.isUserAgent(\"MSIE\")) control.style.fontSize = \"0\";\n control.value = \"\";\n }\n }\n }\n this.cDiagnosticScreens = 0;\n }\n this.nDiagnostics = 0;\n return true;\n }\n\n /**\n * outputDiagnostics(sMessage, sType)\n *\n * @this {Computer}\n * @param {string} sMessage\n * @param {string} [sType]\n */\n outputDiagnostics(sMessage, sType)\n {\n if (this.cDiagnosticScreens) {\n for (var i = 0; i < this.aVideo.length; i++) {\n var video = this.aVideo[i];\n if (video) {\n var control = video.getTextArea();\n if (control) {\n if (sType != Component.PRINT.PROGRESS || sMessage.slice(-3) != \"...\") {\n Component.appendControl(control, sMessage + '\\n');\n } else {\n Component.replaceControl(control, sMessage, sMessage + '.');\n }\n }\n }\n }\n }\n }\n\n /**\n * notifyKbdEvent(event, fDown)\n *\n * This is called by the Keyboard component for all key presses, and it is effectively a no-op except\n * in the one special case where disableDiagnostics() has delayed powerOn until a key is pressed.\n *\n * @this {Computer}\n * @param {Object} [event]\n * @param {boolean} [fDown] is true for a keyDown event, false for a keyUp event\n * @return {boolean} (true if diagnostics disabled, false if enabled -- at the time of the call)\n */\n notifyKbdEvent(event, fDown)\n {\n var nDiagnostics = this.nDiagnostics;\n if (this.nDiagnostics == 3) {\n this.nDiagnostics++;\n this.setReady(); // this may trigger a call to disableDiagnostics(), which is why we snapshot nDiagnostics\n }\n return !nDiagnostics;\n }\n\n /**\n * getMachineID()\n *\n * @this {Computer}\n * @return {string}\n */\n getMachineID()\n {\n return this.sMachineID;\n }\n\n /**\n * setMachineParms(parmsMachine)\n *\n * If no explicit machine parms were provided, then we check for 'parms' in the bundled resources (if any).\n *\n * @this {Computer}\n * @param {Object} [parmsMachine]\n */\n setMachineParms(parmsMachine)\n {\n if (!parmsMachine) {\n var sParms;\n if (typeof resources == 'object' && (sParms = resources['parms'])) {\n try {\n parmsMachine = /** @type {Object} */ (eval(\"(\" + sParms + \")\")); // jshint ignore:line\n } catch(err) {\n Component.error(err.message + \" (\" + sParms + \")\");\n }\n }\n }\n this.parmsMachine = parmsMachine;\n }\n\n /**\n * getMachineParm(sParm, parmsComponent)\n *\n * If the machine parameter doesn't exist, we check for a matching component parameter (if parmsComponent\n * is provided), and failing that, we check the bundled resources (if any).\n *\n * At the moment, the only bundled resource request we expect to encounter is 'state'; if it exists, then\n * we return 'state' back to the caller (ie, the name of the resource), so that the caller will then attempt\n * to load the 'state' resource to obtain the actual state.\n *\n * TODO: This function could (and perhaps should) be modified to accept an optional type parameter (ie,\n * one of the values in Component.TYPE), so that parms like autoMount could be eval'ed here rather than by\n * the caller (eg, FDC.parseConfig()). The downside is that this function would have to return multiple types,\n * so every call would have to be cast to the expected type.\n *\n * @this {Computer}\n * @param {string} sParm\n * @param {Object} [parmsComponent] (eg, this.parms)\n * @return {string|undefined}\n */\n getMachineParm(sParm, parmsComponent)\n {\n var value = Web.getURLParm(sParm);\n if (value) {\n try {\n /*\n * Ideally, we could simply use strings as-is, but unfortunately, we need to convert all\n * supported escape sequences to their underlying characters, and using eval() is the simplest\n * way to deal with them; eg:\n *\n * \\', \\\", \\r, \\n, \\t, and \\xNN\n *\n * When a string containing the above sequences is passed as a machine or component parameter\n * (ie, as an embedPC() machine parameter or as XML component attribute), that conversion happens\n * automatically, either by virtue of implicit script evaluation, or by explicit eval() in\n * getComponentParms(). But when they're passed as a URL parameter, any backslashes are passed\n * through as-is.\n *\n * The complete list of backslash sequences supported by JavaScript:\n *\n * \\0 \\' \\\" \\\\ \\n \\r \\v \\t \\b \\f \\uXXXX \\xXX\n * ^J ^M ^K ^I ^H ^L\n *\n * and of course, eval() will convert them all, but there's no expectation of any but those I've\n * listed above, in part because of Jekyll limitations in some of our templates; eg:\n *\n * https://github.com/jeffpar/pcjs/blob/jekyll/_includes/machine-engines.html\n *\n * which could be overcome, but there's really no need to support more, since \\xNN can be used to\n * represent anything else.\n *\n * Finally, while the user should escape any quotation characters, just to be safe, we will try to\n * choose the safest quoting character for the overall string.\n */\n var ch = value.indexOf(\"'\") >= 0? '\"' : \"'\";\n value = /** @type {string} */ (eval(ch + value + ch)); // jshint ignore:line\n } catch(err) {\n Component.error(err.message + \" (\" + value + \")\");\n value = undefined;\n }\n }\n if (value === undefined && this.parmsMachine) {\n value = this.parmsMachine[sParm];\n }\n if (value === undefined && parmsComponent) {\n value = parmsComponent[sParm];\n }\n if (value === undefined && typeof resources == 'object' && resources[sParm]) {\n value = sParm;\n }\n return value;\n }\n\n /**\n * saveMachineParms()\n *\n * @this {Computer}\n * @return {string|null}\n */\n saveMachineParms()\n {\n return this.parmsMachine? JSON.stringify(this.parmsMachine) : null;\n }\n\n /**\n * getUserID()\n *\n * @this {Computer}\n * @return {string}\n */\n getUserID()\n {\n return this.sUserID || \"\";\n }\n\n /**\n * doneLoad(sURL, sStateData, nErrorCode)\n *\n * @this {Computer}\n * @param {string} sURL\n * @param {string} sStateData\n * @param {number} nErrorCode\n */\n doneLoad(sURL, sStateData, nErrorCode)\n {\n if (!nErrorCode) {\n this.sStateData = sStateData;\n this.fStateData = true;\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"loaded state file \" + sURL.replace(this.sUserID || \"xxx\", \"xxx\"));\n }\n } else {\n this.sResumePath = null;\n this.fServerState = false;\n this.notice('Unable to load machine state from server (error ' + nErrorCode + (sStateData? ': ' + Str.trim(sStateData) : '') + ')');\n }\n this.setReady();\n }\n\n /**\n * wait(fn, parms)\n *\n * wait() waits until every component is ready (including ourselves, the last component we check), then calls the\n * specified Computer method.\n *\n * TODO: The Closure Compiler makes it difficult for us to define a function type for \"fn\" that works in all cases;\n * sometimes we want to pass a function that takes only a \"number\", and other times we want to pass a function that\n * takes only an \"Array\" (the type will mirror that of the \"parms\" parameter). However, the Closure Compiler insists\n * that both functions must be declared as accepting both types of parameters. So once again, we must use an untyped\n * function declaration, instead of something stricter like:\n *\n * param {function(this:Computer, (number|Array|undefined)): undefined} fn\n *\n * @this {Computer}\n * @param {function(...)} fn\n * @param {number|Array} [parms] optional parameters\n */\n wait(fn, parms)\n {\n var computer = this;\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent <= aComponents.length; iComponent++) {\n var component = (iComponent < aComponents.length? aComponents[iComponent] : this);\n if (!component.isReady()) {\n component.isReady(function onComponentReady() {\n computer.wait(fn, parms);\n });\n return;\n }\n }\n if (DEBUG && this.messageEnabled()) this.printMessage(\"Computer.wait(ready)\");\n fn.call(this, parms);\n }\n\n /**\n * validateState(stateComputer)\n *\n * NOTE: We clear() stateValidate only when there's no stateComputer.\n *\n * @this {Computer}\n * @param {State|null} [stateComputer]\n * @return {boolean} true if state passes validation, false if not\n */\n validateState(stateComputer)\n {\n var fValid = true;\n var stateValidate = new State(this, PCX86.APPVERSION, Computer.STATE_VALIDATE);\n if (stateValidate.load() && stateValidate.parse()) {\n var sTimestampValidate = stateValidate.get(Computer.STATE_TIMESTAMP);\n var sTimestampComputer = stateComputer ? stateComputer.get(Computer.STATE_TIMESTAMP) : \"unknown\";\n if (sTimestampValidate != sTimestampComputer) {\n this.notice(\"Machine state may be out-of-date\\n(\" + sTimestampValidate + \" vs. \" + sTimestampComputer + \")\\nCheck your browser's local storage limits\");\n fValid = false;\n if (!stateComputer) stateValidate.clear();\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"Last state: \" + sTimestampComputer + \" (validate: \" + sTimestampValidate + \")\");\n }\n }\n }\n return fValid;\n }\n\n /**\n * powerOn(resume)\n *\n * Power every component \"up\", applying any previously available state information.\n *\n * @this {Computer}\n * @param {number} [resume] is a valid RESUME value; default is this.resume\n */\n powerOn(resume)\n {\n if (resume === undefined) {\n resume = this.resume || (this.sStateData? Computer.RESUME_AUTO : Computer.RESUME_NONE);\n }\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"Computer.powerOn(\" + (resume == Computer.RESUME_REPOWER ? \"repower\" : (resume ? \"resume\" : \"\")) + \")\");\n }\n\n if (this.nPowerChange) {\n return;\n }\n this.nPowerChange++;\n\n var fRepower = false;\n var fRestore = false;\n this.fRestoreError = false;\n var stateComputer = this.stateComputer || new State(this, PCX86.APPVERSION);\n\n if (resume == Computer.RESUME_REPOWER) {\n fRepower = true;\n }\n else if (resume > Computer.RESUME_NONE) {\n if (stateComputer.load(this.sStateData)) {\n /*\n * Since we're resuming something (either a predefined state or a state from localStorage), let's\n * create a \"failsafe\" checkpoint in localStorage, and destroy it at the end of a successful powerOn().\n * Which means, of course, that if a previous \"failsafe\" checkpoint already exists, something bad\n * may have happened the last time around.\n */\n this.stateFailSafe = new State(this, PCX86.APPVERSION, Computer.STATE_FAILSAFE);\n\n if (this.stateFailSafe.load()) {\n if (resume != Computer.RESUME_AUTO && this.powerReport(stateComputer)) {\n /*\n * Prompt the user; if they decline to restore, the state will be removed.\n */\n resume = Computer.RESUME_PROMPT;\n }\n /*\n * To ensure that the set() below succeeds, we need to call unload(), otherwise it may fail\n * with a \"read only\" error (eg, \"TypeError: Cannot assign to read only property 'timestamp'\").\n */\n this.stateFailSafe.unload();\n }\n\n this.stateFailSafe.set(Computer.STATE_TIMESTAMP, Usr.getTimestamp());\n this.stateFailSafe.store();\n\n var fValidate = this.resume && !this.fServerState;\n if (resume == Computer.RESUME_AUTO || Component.confirmUser(\"Click OK to restore the previous \" + PCX86.APPNAME + \" machine state.\")) {\n fRestore = stateComputer.parse();\n if (fRestore) {\n var sCode = stateComputer.get(UserAPI.RES.CODE);\n var sData = stateComputer.get(UserAPI.RES.DATA);\n if (sCode) {\n if (sCode == UserAPI.CODE.OK) {\n stateComputer.load(/** @type {string} */ (sData));\n } else {\n /*\n * A missing (or not yet created) state file is no cause for alarm, but other errors might be\n */\n if (sCode == UserAPI.CODE.FAIL && sData != UserAPI.FAIL.NOSTATE) {\n this.notice(\"Error: \" + sData);\n if (sData == UserAPI.FAIL.VERIFY) this.resetUserID();\n } else {\n this.println(sCode + \": \" + sData);\n }\n /*\n * Try falling back to the state that we should have saved in localStorage, as a backup to the\n * server-side state.\n */\n stateComputer.unload(); // discard the invalid server-side state first\n if (stateComputer.load()) {\n fRestore = stateComputer.parse();\n fValidate = true;\n } else {\n fRestore = false; // hmmm, there was nothing in localStorage either\n }\n }\n }\n }\n /*\n * If the load/parse was successful, and it was from localStorage (not sStateData),\n * then we should to try verify that localStorage snapshot is current. One reason it may\n * NOT be current is if localStorage was full and we got a quota error during the last\n * powerOff().\n */\n if (fValidate) this.validateState(fRestore? stateComputer : null);\n } else {\n /*\n * RESUME_PROMPT indicates we should delete the state if they clicked Cancel to confirm() above.\n */\n if (resume == Computer.RESUME_PROMPT) stateComputer.clear();\n }\n } else {\n /*\n * If there's no state, then there should also be no validation timestamp; if there is, then once again,\n * we're probably dealing with a quota error.\n */\n this.validateState();\n }\n delete this.sStateData;\n delete this.stateComputer;\n }\n\n /*\n * Start powering all components, including any data they may need to restore their state;\n * we restore power to the CPU last.\n */\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component !== this && component != this.cpu) {\n try {\n fRestore = this.powerRestore(component, stateComputer, fRepower, fRestore);\n } catch(err) {\n Component.error(component.type + \" power failure: \" + err.message);\n }\n }\n }\n\n /*\n * Assuming this is not a repower, we must perform another wait, because some components may\n * have marked themselves as \"not ready\" again (eg, the FDC component, if the restore forced it\n * to mount one or more additional disk images).\n */\n var aParms = [stateComputer, resume, fRestore];\n\n if (resume != Computer.RESUME_REPOWER) {\n this.wait(this.donePowerOn, aParms);\n return;\n }\n this.donePowerOn(aParms);\n }\n\n /**\n * powerRestore(component, stateComputer, fRepower, fRestore)\n *\n * @this {Computer}\n * @param {Component} component\n * @param {State} stateComputer\n * @param {boolean} fRepower\n * @param {boolean} fRestore\n * @return {boolean} true if restore should continue, false if not\n */\n powerRestore(component, stateComputer, fRepower, fRestore)\n {\n if (!component.flags.powered) {\n\n component.flags.powered = true;\n\n if (component.powerUp) {\n\n var data = null;\n if (fRestore) {\n data = stateComputer.get(component.id);\n if (!data) {\n /*\n * This is a hack that makes it possible for a machine whose ID has been\n * supplemented with a hyphenated numeric suffix to find object IDs in states\n * created from a machine without such a suffix.\n *\n * For example, if a state file was created from a machine with ID \"ibm5160\"\n * but the current machine is \"ibm5160-1\", this attempts a second lookup with\n * \"ibm5160\", enabling us to find objects that match the original machine ID\n * (eg, \"ibm5160.romEGA\").\n *\n * See /devices/pcx86/machine/5160/ega/640kb/array for examples of this.\n */\n data = stateComputer.get(component.id.replace(/-[0-9]+\\./i, '.'));\n }\n }\n\n /*\n * State.get() will return whatever was originally passed to State.set() (eg, an\n * Object or a string), but components are supposed to store only Objects, so if a\n * string comes back, something went wrong. By explicitly eliminating \"string\" data,\n * the Closure Compiler stops complaining that we might be passing strings to our\n * powerUp() functions (even though we know we're not). We could also add @type\n * overrides to the data assignments, but this seems like a useful runtime check.\n */\n if (typeof data === \"string\") data = null;\n\n /*\n * If computer is null, this is simply a repower notification, which most components\n * don't do anything with. Exceptions include: CPU (since it may be halted) and Video\n * (since its screen may be \"turned off\").\n */\n if (!component.powerUp(data, fRepower) && data) {\n\n if (component.notice(\"Unable to restore hardware state\")) {\n /*\n * If this is a resume error for a machine that also has a predefined state\n * AND we're not restoring from that state, then throw away the current state,\n * prevent any new state from being created, and then force a reload, which will\n * hopefully restore us to the functioning predefined state.\n *\n * TODO: Considering doing this in ALL cases, not just in situations where a\n * 'state' exists but we're not actually resuming from it.\n */\n if (this.sStatePath && !this.fStateData) {\n stateComputer.clear();\n this.resume = Computer.RESUME_NONE;\n Web.reloadPage();\n } else {\n /*\n * In all other cases, we set fRestoreError, which should trigger a call to\n * powerReport() and then delete the offending state.\n */\n this.fRestoreError = true;\n }\n }\n\n /*\n * Any failure triggers an automatic to call powerUp() again, without any state,\n * in the hopes that the component can recover by performing a reset.\n */\n component.powerUp(null);\n /*\n * We also disable the rest of the restore operation, because it's not clear\n * the remaining state information can be trusted; the machine is already in an\n * inconsistent state, so we're not likely to make things worse, and the only\n * alternative (starting over and performing a state-less reset) isn't likely to make\n * the user any happier. But, we'll see... we need some experience with the code.\n */\n fRestore = false;\n }\n }\n\n component.flags.initDone = true;\n\n if (!fRepower && component.comment) {\n var asComments = component.comment.split(\"|\");\n for (var i = 0; i < asComments.length; i++) {\n component.status(asComments[i]);\n }\n }\n }\n return fRestore;\n }\n\n /**\n * donePowerOn(aParms)\n *\n * This is nothing more than a continuation of powerOn(), giving us the option of calling wait() one more time.\n *\n * @this {Computer}\n * @param {Array} aParms containing [stateComputer, resume, fRestore]\n */\n donePowerOn(aParms)\n {\n if (!this.flags.initDone) {\n if (!this.disableDiagnostics()) {\n this.setReady(false);\n this.wait(this.donePowerOn, aParms);\n return;\n }\n this.flags.initDone = true;\n }\n\n if (DEBUG && this.flags.powered && this.messageEnabled()) {\n this.printMessage(\"Computer.donePowerOn(): redundant\");\n }\n\n var stateComputer = aParms[0];\n var fRepower = (aParms[1] < 0);\n var fRestore = aParms[2];\n\n var controlPower = this.bindings[\"power\"];\n if (controlPower) controlPower.textContent = \"Shutdown\";\n\n this.flags.powered = true;\n\n /*\n * Once we get to this point, we're guaranteed that all components are ready, so it's safe to power the CPU;\n * the CPU should begin executing immediately, unless a debugger is attached.\n */\n if (this.cpu) {\n /*\n * TODO: Do we not care about the return value here? (ie, is checking fRestoreError sufficient)?\n */\n this.powerRestore(this.cpu, stateComputer, fRepower, fRestore);\n this.cpu.autoStart();\n }\n\n /*\n * If the state was bad, offer to report it and then delete it. Deleting may be moot, since invariably a new\n * state will be created on powerOff() before the next powerOn(), but it seems like good paranoia all the same.\n */\n if (this.fRestoreError) {\n this.powerReport(stateComputer);\n stateComputer.clear();\n }\n\n if (!fRepower && this.stateFailSafe) {\n this.stateFailSafe.clear();\n delete this.stateFailSafe;\n }\n\n this.nPowerChange = 0;\n\n Component.processScript(this.idMachine, this.getMachineParm('autoScript'));\n }\n\n /**\n * checkPower()\n *\n * @this {Computer}\n * @return {boolean} true if the computer is fully powered, false otherwise\n */\n checkPower()\n {\n if (this.flags.unloading) {\n /*\n * We happen to know that we're currently only called by the CPU's onClickRun() function, so\n * if the unloading flag is set, then we've somehow gotten into a weird state where the machine\n * thinks it's being (or has been) unloaded by the browser, but in fact, it has not.\n *\n * The only time I've seen this happen is when the user clicks a link on a page that the browser\n * decided to treat as a download operation, instead of loading a new page. The proper way to\n * resolve that confusion is to set the \"download\" attribute on the link (which will prevent the\n * page's \"onbeforeunload\" handler from being called in the first place), but we cannot guarantee\n * that all such links will have their \"download\" attribute properly set.\n *\n * Hence, this code: we do the same thing that the show() function does, which is to attempt a\n * REPOWER operation. If that doesn't result in the powered flag getting turned back on, well,\n * then we're probably screwed.\n */\n this.flags.unloading = false;\n if (this.flags.initDone && !this.flags.powered) {\n this.powerOn(Computer.RESUME_REPOWER);\n }\n }\n\n if (this.flags.powered) return true;\n\n var component = null, iComponent;\n var aComponents = Component.getComponents(this.id);\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component !== this && !component.flags.ready) break;\n }\n if (iComponent == aComponents.length) {\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component !== this && !component.flags.powered) break;\n }\n }\n if (iComponent == aComponents.length) component = this;\n var s = \"The \" + component.type + \" component (\" + component.id + \") is not \" + (!component.flags.ready? \"ready yet\" + (component.fnReady? \" (waiting for notification)\" : \"\") : \"powered yet\") + \".\";\n Component.alertUser(s);\n return false;\n }\n\n /**\n * powerReport(stateComputer)\n *\n * TODO: Ever since I migrated the PCjs website from a Node-based web server on AWS to a GitHub Pages-based site,\n * the sendReport() API has been a bit-bucket. To be honest though, even before that change, I never really had\n * the time (or desire) to look through all the anonymous machine states that were being posted. Most of them were\n * probably due to the user switching away from a page before it finished loading anyway, leaving the machine in\n * an incomplete state. That said, there should be SOME automated way for people to share their machine states\n * when there's a more serious problem -- not this misleading prompt.\n *\n * In the meantime, to help reduce those kind of useless alerts, there's the new 'unloading' flag. However, I'm\n * not sure how reliably that's being set, so additionally, the default 'resume' setting (RESUME_AUTO) tries to be\n * MUCH more automatic now; this function, for example, shouldn't even be called now when RESUME_AUTO is in effect.\n * Another 'resume' setting (eg, RESUME_PROMPT) must be selected instead.\n *\n * @this {Computer}\n * @param {State} stateComputer\n * @return {boolean}\n */\n powerReport(stateComputer)\n {\n if (!this.flags.unloading) {\n if (Component.confirmUser(\"There may be a problem with your \" + PCX86.APPNAME + \" machine.\\n\\nTo help us diagnose it, click OK to send this \" + PCX86.APPNAME + \" machine state to http://\" + SITEHOST + \".\")) {\n Web.sendReport(PCX86.APPNAME, PCX86.APPVERSION, this.url, this.getUserID(), ReportAPI.TYPE.BUG, stateComputer.toString());\n }\n return true;\n }\n return false;\n }\n\n /**\n * powerOff(fSave, fShutdown)\n *\n * Power every component \"down\" and optionally save the machine state.\n *\n * There's one scenario that powerOff() isn't currently able to deal with very effectively: what to do when\n * the user switches away while it's still being restored, causing Disk getResource() calls to fail. The\n * Disk component calls notify() when that happens -- see Disk.mount() -- but the FDC and HDC controllers don't\n * notify *us* of those problems, so Computer assumes that the restore was completely successful, when in fact\n * it was only partially successful.\n *\n * Then we immediately arrive here to perform a save, following that incomplete restore. It would be wrong to\n * deal with that incomplete restore by setting fRestoreError, because we don't want to trigger a powerReport()\n * and the deletion of the previous state, because the state itself was presumably OK. Unfortunately, the new\n * state we now save will no longer include manually mounted disk images whose remounts were interrupted, so future\n * restores won't remount them either.\n *\n * We could perhaps solve this by having the Disk component notify us in those situations, set a new flag\n * (fRestoreIncomplete?), and set fSave to false if that's ever set. Be careful though: when fSave is false,\n * that means MORE than not saving; it also means deleting any previous state, which is NOT what you'd want to\n * do in a \"fRestoreIncomplete\" situation. Also, we have to worry about Disk operations that fail for other reasons,\n * making sure those failures don't interfere with the save process in the same way.\n *\n * As it stands, the worst that happens is any manually mounted disk images might have to be manually remounted,\n * which doesn't seem like a huge problem.\n *\n * @this {Computer}\n * @param {boolean} [fSave] is true to request a saved state\n * @param {boolean} [fShutdown] is true if the machine is being shut down\n * @return {string|null} string representing the saved state (or null if error)\n */\n powerOff(fSave, fShutdown)\n {\n var data;\n var sState = \"none\";\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"Computer.powerOff(\" + (fSave ? \"save\" : \"nosave\") + (fShutdown ? \",shutdown\" : \"\") + \")\");\n }\n\n if (this.nPowerChange) {\n return null;\n }\n this.nPowerChange--;\n\n var stateComputer = new State(this, PCX86.APPVERSION);\n var stateValidate = new State(this, PCX86.APPVERSION, Computer.STATE_VALIDATE);\n\n var sTimestamp = Usr.getTimestamp();\n stateValidate.set(Computer.STATE_TIMESTAMP, sTimestamp);\n stateComputer.set(Computer.STATE_TIMESTAMP, sTimestamp);\n stateComputer.set(Computer.STATE_VERSION, APPVERSION);\n stateComputer.set(Computer.STATE_HOSTURL, Web.getHostURL());\n stateComputer.set(Computer.STATE_BROWSER, Web.getUserAgent());\n\n /*\n * Always power the CPU \"down\" first, just to help insure it doesn't ask other components to do anything\n * after they're no longer ready.\n */\n if (this.cpu && this.cpu.powerDown) {\n data = this.cpu.powerDown(fSave, fShutdown);\n if (typeof data === \"object\") stateComputer.set(this.cpu.id, data);\n if (fShutdown) {\n this.cpu.flags.powered = false;\n if (data === false) sState = null;\n }\n }\n\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.flags.powered) {\n if (component.powerDown) {\n data = component.powerDown(fSave, fShutdown);\n if (typeof data === \"object\") stateComputer.set(component.id, data);\n }\n if (fShutdown) {\n component.flags.powered = false;\n if (data === false) sState = null;\n }\n }\n }\n\n if (sState) {\n if (fShutdown) {\n var fClear = false;\n var fClearAll = false;\n if (fSave) {\n if (this.sUserID) {\n this.saveServerState(this.sUserID, stateComputer.toString());\n }\n if (!stateValidate.store() || !stateComputer.store()) {\n sState = null;\n /*\n * New behavior as of v1.13.2: if it appears that localStorage is full, we blow it ALL away.\n * Dedicated server-side storage is the only way we'll ever be able to reliably preserve a\n * particular machine's state. Historically, attempting to limp along with whatever localStorage\n * is left just generates the same useless and annoying warnings over and over.\n */\n fClear = fClearAll = true;\n }\n }\n else {\n /*\n * I used to ALWAYS clear (ie, delete) any associated computer state, but now I do this only if the\n * current machine is \"resumable\", because there are situations where I have two configurations\n * for the same machine -- one resumable and one not -- and I don't want the latter throwing away the\n * state of the former.\n *\n * So this code is here now strictly for callers to delete the state of a \"resumable\" machine, not as\n * some paranoid clean-up operation.\n *\n * An undocumented feature of this operation is that if your configuration uses the special 'resume=\"3\"'\n * value, and you click the \"Reset\" button, and then you click OK to reset the everything, this will\n * actually reset EVERYTHING (ie, all localStorage for ALL configs will be reclaimed).\n */\n if (this.resume) {\n fClear = true;\n fClearAll = (this.resume == Computer.RESUME_DELETE);\n }\n }\n if (fClear) {\n stateComputer.clear(fClearAll);\n }\n } else {\n sState = stateComputer.toString();\n }\n }\n\n if (fShutdown) {\n this.flags.powered = false;\n var controlPower = this.bindings[\"power\"];\n if (controlPower) controlPower.textContent = \"Power\";\n }\n\n this.nPowerChange = 0;\n\n return sState;\n }\n\n /**\n * reset()\n *\n * Notify all (other) components with a reset() method that the Computer is being reset.\n *\n * NOTE: We'd like to reset the Bus first (due to the importance of the A20 line), but since we\n * allocated the Bus object ourselves, after all the other components were allocated, it ends\n * up near the end of Component's list of components. Hence the special case for this.bus below.\n *\n * @this {Computer}\n */\n reset()\n {\n if (this.bus && this.bus.reset) {\n this.printMessage(\"Resetting \" + this.bus.type);\n this.bus.reset();\n }\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component !== this && component !== this.bus && component.reset) {\n this.printMessage(\"Resetting \" + component.type);\n component.reset();\n }\n }\n }\n\n /**\n * start(ms, nCycles)\n *\n * Notify all (other) components with a start() method that the CPU has started.\n *\n * Note that we're called by startCPU(), which is why we exclude the CPU component,\n * as well as ourselves.\n *\n * @this {Computer}\n * @param {number} ms\n * @param {number} nCycles\n */\n start(ms, nCycles)\n {\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.type == \"CPU\" || component === this) continue;\n if (component.start) {\n component.start(ms, nCycles);\n }\n }\n }\n\n /**\n * stop(ms, nCycles)\n *\n * Notify all (other) components with a stop() method that the CPU has stopped.\n *\n * Note that we're called by stopCPU(), which is why we exclude the CPU component,\n * as well as ourselves.\n *\n * @this {Computer}\n * @param {number} ms\n * @param {number} nCycles\n */\n stop(ms, nCycles)\n {\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.type == \"CPU\" || component === this) continue;\n if (component.stop) {\n component.stop(ms, nCycles);\n }\n }\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {Computer}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var computer = this;\n\n switch (sBinding) {\n case \"power\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickPower() {\n computer.onPower();\n };\n return true;\n\n case \"reset\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickReset() {\n computer.onReset();\n };\n return true;\n\n /*\n * Technically, this binding should now be called \"saveState\", to clearly distinguish it from\n * the \"Save Machine\" control that's normally bound to the savePC() function in save.js. Saving\n * an entire machine includes everything needed to start/restore the machine; eg, the machine\n * XML configuration file(s) *and* the JSON-encoded machine state.\n */\n case \"save\":\n /*\n * Since this feature depends on the server supporting the PCjs User API (see userapi.js),\n * and since pcjs.org is no longer running a Node web server, we disable the feature for that\n * particular host.\n */\n if (Str.endsWith(Web.getHost(), \"pcjs.org\")) {\n if (DEBUG) this.log(\"Remote user API not available\");\n /*\n * We could also simply hide the control; eg:\n *\n * control.style.display = \"none\";\n *\n * but removing the control altogether seems better.\n */\n control.parentNode.removeChild(/** @type {Node} */ (control));\n return false;\n }\n this.bindings[sBinding] = control;\n control.onclick = function onClickSave() {\n var sUserID = computer.queryUserID(true);\n if (sUserID) {\n /*\n * I modified the test to include a check for sStatePath so that I could save new states\n * for machines with existing states; otherwise, I'd have no (easy) way of capturing and\n * updating their state. Making the machine (even temporarily) resumable would have been\n * one work-around, but it's not appropriate for some machines, as their state is simply\n * too large (for localStorage anyway, which is the default storage solution).\n */\n var fSave = !!(computer.resume && !computer.sResumePath || computer.sStatePath);\n var sState = computer.powerOff(fSave);\n if (fSave) {\n computer.saveServerState(sUserID, sState);\n } else {\n computer.notice(\"Resume disabled, machine state not saved\");\n }\n }\n /*\n * This seemed like a handy alternative, but it turned out to be a no-go, at least for large states:\n *\n * var sState = computer.powerOff(true);\n * if (sState) {\n * sState = \"data:text/json;charset=utf-8,\" + encodeURIComponent(sState);\n * window.open(sState);\n * }\n *\n * Perhaps if I embedded the data in a link on the current page instead; eg:\n *\n * $('<a href=\"' + sState + '\" download=\"state.json\">Download</a>').appendTo('#container');\n */\n };\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * resetUserID()\n *\n * @this {Computer}\n */\n resetUserID()\n {\n Web.setLocalStorageItem(Computer.STATE_USERID, \"\");\n this.sUserID = null;\n }\n\n /**\n * queryUserID(fPrompt)\n *\n * @this {Computer}\n * @param {boolean} [fPrompt]\n * @returns {string|null|undefined}\n */\n queryUserID(fPrompt)\n {\n var sUserID = this.sUserID;\n if (!sUserID) {\n sUserID = Web.getLocalStorageItem(Computer.STATE_USERID);\n if (sUserID !== undefined) {\n if (!sUserID && fPrompt) {\n /*\n * NOTE: Warning the user here that \"Save\" operations are not currently supported by pcjs.org is\n * merely a precaution, because ordinarily, setBinding() should have already determined if we are\n * running from pcjs.org and disabled any \"Save\" button.\n */\n sUserID = Component.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.\");\n if (sUserID) {\n sUserID = this.verifyUserID(sUserID);\n if (!sUserID) this.notice(\"The user ID is invalid.\");\n }\n }\n } else if (fPrompt) {\n this.notice(\"Browser local storage is not available\");\n }\n }\n return sUserID;\n }\n\n /**\n * verifyUserID(sUserID)\n *\n * @this {Computer}\n * @param {string} sUserID\n * @return {string} validated user ID, or null if error\n */\n verifyUserID(sUserID)\n {\n this.sUserID = null;\n var fMessages = DEBUG && this.messageEnabled();\n if (fMessages) this.printMessage(\"verifyUserID(\" + sUserID + \")\");\n var sRequest = Web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.VERIFY + '&' + UserAPI.QUERY.USER + '=' + sUserID;\n var response = Web.getResource(sRequest);\n var nErrorCode = response[0];\n var sResponse = response[1];\n if (!nErrorCode && sResponse) {\n try {\n response = eval(\"(\" + sResponse + \")\"); // jshint ignore:line\n if (response.code && response.code == UserAPI.CODE.OK) {\n Web.setLocalStorageItem(Computer.STATE_USERID, response.data);\n if (fMessages) this.printMessage(Computer.STATE_USERID + \" updated: \" + response.data);\n this.sUserID = response.data;\n } else {\n if (fMessages) this.printMessage(response.code + \": \" + response.data);\n }\n } catch(err) {\n Component.error(err.message + \" (\" + sResponse + \")\");\n }\n } else {\n if (fMessages) this.printMessage(\"invalid response (error \" + nErrorCode + \")\");\n }\n return this.sUserID;\n }\n\n /**\n * getServerStatePath()\n *\n * @this {Computer}\n * @return {string|null} sStatePath (null if no localStorage or no USERID stored in localStorage)\n */\n getServerStatePath()\n {\n var sStatePath = null;\n if (this.sUserID) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(Computer.STATE_USERID + \" for load: \" + this.sUserID);\n }\n sStatePath = Web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.LOAD + '&' + UserAPI.QUERY.USER + '=' + this.sUserID + '&' + UserAPI.QUERY.STATE + '=' + State.key(this, PCX86.APPVERSION);\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(Computer.STATE_USERID + \" unavailable\");\n }\n }\n return sStatePath;\n }\n\n /**\n * saveServerState(sUserID, sState)\n *\n * @this {Computer}\n * @param {string} sUserID\n * @param {string|null} sState\n */\n saveServerState(sUserID, sState)\n {\n /*\n * We must pass fSync == true, because (as I understand it) browsers will blow off any async\n * requests when a page is being closed. Since our request is synchronous, storeServerState()\n * should also return a result, but there's not much we can do with it, since browsers ALSO\n * tend to blow off alerts() and the like when closing down.\n */\n if (sState) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"size of server state: \" + sState.length + \" bytes\");\n }\n var response = this.storeServerState(sUserID, sState, true);\n if (response && response[UserAPI.RES.CODE] == UserAPI.CODE.OK) {\n this.notice(\"Machine state saved to server\");\n } else if (sState) {\n var sError = (response && response[UserAPI.RES.DATA]) || UserAPI.FAIL.BADSTORE;\n if (response[UserAPI.RES.CODE] == UserAPI.CODE.FAIL) {\n sError = \"Error: \" + sError;\n } else {\n sError = \"Error \" + response[UserAPI.RES.CODE] + \": \" + sError;\n }\n this.notice(sError);\n this.resetUserID();\n }\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"no state to store\");\n }\n }\n }\n\n /**\n * storeServerState(sUserID, sState, fSync)\n *\n * @this {Computer}\n * @param {string} sUserID\n * @param {string} sState\n * @param {boolean} [fSync] is true if we're powering down and should perform a synchronous request (default is async)\n * @return {*} server response if fSync is true and a response was received; otherwise null\n */\n storeServerState(sUserID, sState, fSync)\n {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(Computer.STATE_USERID + \" for store: \" + sUserID);\n }\n /*\n * TODO: Determine whether or not any browsers cancel our request if we're called during a browser \"shutdown\" event,\n * and whether or not it matters if we do an async request (currently, we're not, to try to ensure the request goes through).\n */\n var dataPost = {};\n dataPost[UserAPI.QUERY.REQ] = UserAPI.REQ.STORE;\n dataPost[UserAPI.QUERY.USER] = sUserID;\n dataPost[UserAPI.QUERY.STATE] = State.key(this, PCX86.APPVERSION);\n dataPost[UserAPI.QUERY.DATA] = sState;\n var sRequest = Web.getHost() + UserAPI.ENDPOINT;\n if (!fSync) {\n Web.getResource(sRequest, dataPost, true);\n } else {\n var response = Web.getResource(sRequest, dataPost);\n var sResponse = response[0];\n if (response[1]) {\n if (sResponse) {\n var i = sResponse.indexOf('\\n');\n if (i > 0) sResponse = sResponse.substr(0, i);\n if (!sResponse.indexOf(\"Error: \")) sResponse = sResponse.substr(7);\n }\n sResponse = '{\"' + UserAPI.RES.CODE + '\":' + response[1] + ',\"' + UserAPI.RES.DATA + '\":\"' + sResponse + '\"}';\n }\n if (DEBUG && this.messageEnabled()) this.printMessage(sResponse);\n return JSON.parse(sResponse);\n }\n return null;\n }\n\n /**\n * onPower()\n *\n * This handles UI requests to toggle the computer's power (eg, see the \"power\" button binding).\n *\n * @this {Computer}\n */\n onPower()\n {\n if (!this.nPowerChange) {\n if (!this.flags.powered) {\n this.wait(this.powerOn);\n } else {\n this.powerOff(false, true);\n }\n }\n }\n\n /**\n * onReset()\n *\n * This handles UI requests to reset the computer's state (eg, see the \"reset\" button binding).\n *\n * @this {Computer}\n */\n onReset()\n {\n /*\n * I'm going to start with the presumption that it makes little sense for an \"unpowered\" computer to be \"reset\";\n * ditto if the power state is currently being changed.\n */\n if (!this.flags.powered || this.nPowerChange) return;\n\n /*\n * Whether or not we autoStart on reset should depend at least in part on whether we were running originally.\n */\n if (this.cpu) {\n this.cpu.flags.autoStart = this.cpu.flags.running;\n }\n /*\n * If this is a \"resumable\" machine (and it's not using a predefined state), then we overload the reset\n * operation to offer an explicit \"save or discard\" option first. This is currently the only UI we offer to\n * discard a machine's state, including any disk changes. The traditional \"reset\" operation is still available\n * for non-resumable machines.\n *\n * TODO: Break this behavior out into a separate \"discard\" operation, in case the designer of the machine really\n * wants to clutter the UI with confusing options. ;-)\n */\n if (this.resume && !this.sResumePath) {\n /*\n * I used to bypass the prompt if this.resume == Computer.RESUME_AUTO, setting fSave to true automatically,\n * but that gives the user no means of resetting a resumable machine that contains errors in its resume state.\n */\n var fSave = (/* this.resume == Computer.RESUME_AUTO || */ this.flags.unloading || !Component.confirmUser(\"Click OK to reset this \" + PCX86.APPNAME + \" machine and discard all disk modifications.\"));\n this.powerOff(fSave, true);\n /*\n * Forcing the page to reload is an expedient option, but ugly. It's preferable to call powerOn()\n * and rely on all the components to reset themselves to their default state. The components with\n * the greatest burden here are FDC and HDC, which must rely on the fReload flag to determine whether\n * or not to unload/reload all their original auto-mounted disk images.\n *\n * However, if we started with a predefined state (ie, sStatePath is set), we take this shortcut, because\n * we don't (yet) have code in place to gracefully reload the initial state (requires calling getResource()\n * again); alternatively, we could avoid throwing that state away, but it seems better to save the memory.\n *\n * TODO: Make this more graceful, so that we can stop using the reloadPage() sledgehammer.\n */\n if (!fSave && this.sStatePath) {\n Web.reloadPage();\n return;\n }\n if (!fSave) this.fReload = true;\n this.powerOn(Computer.RESUME_NONE);\n this.fReload = false;\n } else {\n this.reset();\n if (this.cpu) this.cpu.autoStart();\n }\n this.updateFocus(true);\n }\n\n /**\n * getMachineComponent(sType, componentPrev)\n *\n * @this {Computer}\n * @param {string} sType\n * @param {Component|null} [componentPrev] of previously returned component, if any\n * @return {Component|null}\n */\n getMachineComponent(sType, componentPrev)\n {\n var componentLast = componentPrev;\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (componentPrev) {\n if (componentPrev == component) componentPrev = null;\n continue;\n }\n if (component.type == sType) return component;\n }\n if (!componentLast && sType != \"FPU\") {\n Component.log(\"Machine component type '\" + sType + \"' not found\", \"warning\");\n }\n return null;\n }\n\n /**\n * updateFocus(fScroll)\n *\n * NOTE: When soft keyboard buttons call us to return focus to the machine (and away from the button),\n * the browser's default behavior is to scroll the element into view, which can be annoying, especially on iOS,\n * where the display is more constrained, so we no longer do it by default (fScroll must be true).\n *\n * @this {Computer}\n * @param {boolean} [fScroll] (true if you really want the control scrolled into view)\n */\n updateFocus(fScroll)\n {\n if (this.aVideo.length) {\n /*\n * This seems to be recommended work-around to prevent the browser from scrolling the focused element\n * into view. The CPU is not a visual component, so when the CPU wants to set focus, the primary intent\n * is to ensure that keyboard input is fielded properly.\n */\n var x = 0, y = 0;\n if (!fScroll && window) {\n x = window.scrollX;\n y = window.scrollY;\n }\n\n /*\n * TODO: We need a mechanism to determine the \"active\" display, instead of hard-coding this to aVideo[0].\n */\n this.aVideo[0].setFocus();\n\n if (!fScroll && window) {\n window.scrollTo(x, y);\n }\n }\n }\n\n /**\n * updateStatus(fForce)\n *\n * If any DOM controls were bound to the CPU, then we need to call its updateStatus() handler; if there are no\n * such bindings, then cpu.updateStatus() does nothing.\n *\n * Similarly, if there's a Panel, then we need to call its updateStatus() handler, in case it created its own canvas\n * and implemented its own register display (eg, dumpRegisters()); if not, then panel.updateStatus() also does nothing.\n *\n * In practice, there will *either* be a Panel with a custom canvas *or* a set of DOM controls bound to the CPU *or*\n * neither. In theory, there could be BOTH, but that would be unusual.\n *\n * TODO: Consider alternate approaches to these largely register-oriented display updates. Ordinarily, we like to\n * separate logic from presentation, and currently the CPUX86 contains both, since it's the component that intimately\n * knows the names, number, sizes, etc, of all the active registers. The Panel component is the logical candidate,\n * but Panel is an optional component; generally, only machines that include Debugger also include Panel.\n *\n * @this {Computer}\n * @param {boolean} [fForce] (true will display registers even if the CPU is running and \"live\" registers are not enabled)\n */\n updateStatus(fForce)\n {\n /*\n * fForce is generally set to true whenever the CPU is transitioning to/from a running state, in which case\n * cpu.updateStatus() will definitely want to hide/show register contents; however, at other times, when the\n * CPU is running, constantly updating the DOM controls too frequently can adversely impact overall performance.\n *\n * So fForce serves as a hint to help cpu.updateStatus() make a more informed decision. panel.updateStatus()\n * currently doesn't care, on the theory that canvas updates should be significantly faster than DOM updates,\n * but we still pass fForce on.\n */\n if (this.cpu) this.cpu.updateStatus(fForce);\n if (this.panel) this.panel.updateStatus(fForce);\n /*\n * When called by our own timer for relatively infrequent DOM (see Computer.UPDATES_PER_SECOND), fForce is\n * explicitly set to false, and in those cases, we should avoid performing screen updates, because it may\n * subtly interfere with the Video component's normal refresh rate.\n */\n if (fForce !== false) {\n for (var i = 0; i < this.aVideo.length; i++) {\n this.aVideo[i].updateScreen(fForce);\n }\n }\n }\n\n /**\n * Computer.init()\n *\n * For every machine represented by an HTML element of class \"pcx86-machine\", this function\n * locates the HTML element of class \"computer\", extracting the JSON-encoded parameters for the\n * Computer constructor from the element's \"data-value\" attribute, invoking the constructor to\n * create a Computer component, and then binding any associated HTML controls to the new component.\n */\n static init()\n {\n /*\n * In non-COMPILED builds, embedMachine() may have set XMLVERSION.\n */\n if (!COMPILED && XMLVERSION) PCX86.APPVERSION = XMLVERSION;\n\n var aeMachines = Component.getElementsByClass(document, PCX86.APPCLASS + \"-machine\");\n\n for (var iMachine = 0; iMachine < aeMachines.length; iMachine++) {\n\n var eMachine = aeMachines[iMachine];\n var parmsMachine = Component.getComponentParms(eMachine);\n\n var aeComputers = Component.getElementsByClass(eMachine, PCX86.APPCLASS, \"computer\");\n\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n\n /*\n * We set fSuspended in the Computer constructor because we want to \"power up\" the\n * computer ourselves, after any/all bindings are in place.\n */\n var computer = new Computer(parmsComputer, parmsMachine, true);\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onInit(\" + computer.flags.powered + \")\");\n }\n\n /*\n * Bind any \"power\", \"reset\" and \"save\" buttons. An \"erase\" button was also considered,\n * but \"reset\" now provides a way to force the machine to start from scratch again, so \"erase\"\n * may be redundant now.\n */\n Component.bindComponentControls(computer, eComputer, PCX86.APPCLASS);\n\n /*\n * Power on the computer, giving every component the opportunity to reset or restore itself.\n */\n if (computer.fAutoPower) computer.wait(computer.powerOn);\n }\n }\n }\n\n /**\n * Computer.show()\n *\n * When exit() is using an \"onbeforeunload\" handler, this \"onpageshow\" handler allows us to repower everything,\n * without either resetting or restoring. We call powerOn() with a special resume value (RESUME_REPOWER) if the\n * computer is already marked as \"ready\", meaning the browser didn't change anything. This \"repower\" process\n * should be very quick, essentially just marking all components as powered again (so that, for example, the Video\n * component will start drawing again) and firing the CPU up again.\n */\n static show()\n {\n var aeComputers = Component.getElementsByClass(document, PCX86.APPCLASS, \"computer\");\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n var computer = /** @type {Computer} */ (Component.getComponentByType(\"Computer\", parmsComputer['id']));\n if (computer) {\n\n /*\n * Clear new flag that Component functions (eg, notice()) should check before alerting the user.\n */\n computer.flags.unloading = false;\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onShow(\" + computer.flags.initDone + \",\" + computer.flags.powered + \")\");\n }\n\n if (computer.flags.initDone && !computer.flags.powered) {\n /*\n * Repower the computer, notifying every component to continue running as-is.\n */\n computer.powerOn(Computer.RESUME_REPOWER);\n }\n }\n }\n }\n\n /**\n * Computer.exit()\n *\n * The Computer is currently the only component that uses an \"exit\" handler, which Web.onExit() defines as\n * either an \"unload\" or \"onbeforeunload\" handler. This gives us the opportunity to save the machine state,\n * using our powerOff() function, before the page goes away.\n *\n * It's worth noting that \"onbeforeunload\" offers one nice feature when used instead of \"onload\": the entire\n * page (and therefore this entire application) is retained in its current state by the browser (well, some\n * browsers), so that if you go to a new URL, either by entering a new URL in the same window/tab, or by pressing\n * the FORWARD button, and then you press the BACK button, the page is immediately restored to its previous state.\n *\n * In fact, that's how some browsers operate whether you have an \"onbeforeunload\" handler or not; in other words,\n * an \"onbeforeunload\" handler doesn't change the page retention behavior of the browser. By contrast, the mere\n * presence of an \"onunload\" handler generally causes a browser to throw the page away once the handler returns.\n *\n * However, in order to safely use \"onbeforeunload\", we must add yet another handler (\"onpageshow\") to repower\n * everything, without either resetting or restoring. Hence, the Computer.show() function, which calls powerOn()\n * with a special resume value (RESUME_REPOWER) if the computer is already marked as \"ready\", meaning the browser\n * didn't change anything. This \"repower\" process should be very quick, essentially just marking all components as\n * powered again (so that, for example, the Video component will start drawing again) and firing the CPU up again.\n *\n * Reportedly, some browsers (eg, Opera) don't support \"onbeforeunload\", in which case Component will have to use\n * \"unload\" instead. But even when the page must be rebuilt from scratch, the combination of browser cache and\n * localStorage means the simulation should be restored and become operational almost immediately.\n */\n static exit()\n {\n var aeComputers = Component.getElementsByClass(document, PCX86.APPCLASS, \"computer\");\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n var computer = /** @type {Computer} */ (Component.getComponentByType(\"Computer\", parmsComputer['id']));\n if (computer) {\n\n /*\n * Set new flag that Component functions (eg, notice()) should check before alerting the user.\n */\n computer.flags.unloading = true;\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onExit(\" + computer.flags.powered + \")\");\n }\n\n if (computer.flags.powered) {\n /**\n * Power off the computer, giving every component an opportunity to save its state,\n * but only if 'resume' has been set AND there is no valid resume path (because if a valid resume\n * path exists, we'll always load our state from there, and not from whatever we save here).\n */\n computer.powerOff(!!(computer.resume && !computer.sResumePath), true);\n }\n }\n }\n }\n}\n\nComputer.STATE_FAILSAFE = \"failsafe\";\nComputer.STATE_VALIDATE = \"validate\";\nComputer.STATE_TIMESTAMP = \"timestamp\";\nComputer.STATE_VERSION = \"version\";\nComputer.STATE_HOSTURL = \"url\";\nComputer.STATE_BROWSER = \"browser\";\nComputer.STATE_USERID = \"user\";\n\n/*\n * The following constants define all the resume options. Negative values (eg, RESUME_REPOWER) are for\n * internal use only, and RESUME_DELETE is not documented (it provides a way of deleting ALL saved states\n * whenever a resume is declined). As a result, the only \"end-user\" values are 0, 1 and 2.\n */\nComputer.RESUME_REPOWER = -1; // resume without changing any state (for internal use only)\nComputer.RESUME_NONE = 0; // default (no resume)\nComputer.RESUME_AUTO = 1; // automatically save/restore state\nComputer.RESUME_PROMPT = 2; // automatically save but conditionally restore (WARNING: if restore is declined, any state is discarded)\nComputer.RESUME_DELETE = 3; // same as RESUME_PROMPT but discards ALL machines states whenever ANY machine restore is declined (undocumented)\n\nComputer.UPDATES_PER_SECOND = 2;\n\n/*\n * Initialize every Computer on the page.\n */\nWeb.onInit(Computer.init);\nWeb.onShow(Computer.show);\nWeb.onExit(Computer.exit);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/state.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass State {\n /**\n * State(component, sVersion, sSuffix)\n *\n * State objects are used by components to save/restore their state.\n *\n * During a save operation, components add data to a State object via set(), and then return\n * the resulting data using data().\n *\n * During a restore operation, the Computer component passes the results of each data() call\n * back to the originating component.\n *\n * WARNING: Since State objects are low-level objects that have no UI requirements, they do not\n * inherit from the Component class, so you should only use class methods of Component, such as\n * Component.assert() (or Debugger methods if the Debugger is available).\n *\n * NOTE: 1.01 is the first version to provide limited save/restore support using localStorage.\n * From that point on, care must be taken to insure that any new version that's incompatible with\n * previous localStorage data be released with a version number that is at least 1 greater,\n * since we're tagging the localStorage data with the integer portion of the version string.\n *\n * @param {Component} component\n * @param {string} [sVersion] is used to append a major version number to the key\n * @param {string} [sSuffix] is used to append any additional suffixes to the key\n */\n constructor(component, sVersion, sSuffix)\n {\n this.id = component.id;\n this.dbg = component.dbg;\n this.json = \"\";\n this.state = {};\n this.fLoaded = this.fParsed = false;\n this.key = State.key(component, sVersion, sSuffix);\n this.unload(component.parms);\n }\n\n /**\n * set(id, data)\n *\n * @this {State}\n * @param {number|string} id\n * @param {Object|string} data\n */\n set(id, data)\n {\n try {\n this.state[id] = data;\n } catch(e) {\n Component.log(e.message);\n }\n }\n\n /**\n * get(id)\n *\n * @this {State}\n * @param {number|string} id\n * @return {Object|string|null}\n */\n get(id)\n {\n return this.state[id] || null;\n }\n\n /**\n * data()\n *\n * @this {State}\n * @return {Object}\n */\n data()\n {\n return this.state;\n }\n\n /**\n * load(json)\n *\n * WARNING: Make sure you follow this call with either a call to parse() or unload(),\n * because any stringified data that we've loaded isn't usable until it's been parsed.\n *\n * @this {State}\n * @param {string|null} [json]\n * @return {boolean} true if state exists in localStorage, false if not\n */\n load(json)\n {\n if (json) {\n this.json = json;\n this.fLoaded = true;\n this.fParsed = false;\n return true;\n }\n if (this.fLoaded) {\n /*\n * This is assumed to be a redundant load().\n */\n return true;\n }\n if (Web.hasLocalStorage()) {\n var s = Web.getLocalStorageItem(this.key);\n if (s) {\n this.json = s;\n this.fLoaded = true;\n if (DEBUG) Component.log(\"localStorage(\" + this.key + \"): \" + s.length + \" bytes loaded\");\n return true;\n }\n }\n return false;\n }\n\n /**\n * parse()\n *\n * This completes the load() operation, by parsing what was loaded, on the assumption there\n * might be some benefit to deferring parsing until we've given the user a chance to confirm.\n * Otherwise, load() could have just as easily done this, too.\n *\n * @this {State}\n * @return {boolean} true if successful, false if error\n */\n parse()\n {\n var fSuccess = true;\n if (!this.fParsed) {\n try {\n this.state = JSON.parse(this.json);\n this.fParsed = true;\n } catch (e) {\n Component.error(e.message || e);\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * store()\n *\n * @this {State}\n * @return {boolean} true if successful, false if error\n */\n store()\n {\n var fSuccess = true;\n if (Web.hasLocalStorage()) {\n var s = JSON.stringify(this.state);\n if (Web.setLocalStorageItem(this.key, s)) {\n if (DEBUG) Component.log(\"localStorage(\" + this.key + \"): \" + s.length + \" bytes stored\");\n } else {\n /*\n * WARNING: Because browsers tend to disable all alerts() during an \"unload\" operation,\n * it's unlikely anyone will ever see the \"quota\" errors that occur at this point. Need to\n * think of some way to notify the user that there's a problem, and offer a way of cleaning\n * up old states.\n */\n Component.error(\"Unable to store \" + s.length + \" bytes in browser local storage\");\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * toString()\n *\n * @this {State}\n * @return {string} JSON-encoded state\n */\n toString()\n {\n return this.state? JSON.stringify(this.state) : this.json;\n }\n\n /**\n * unload(parms)\n *\n * This discards any data saved via set() or loaded via load(), creating an empty State object.\n * Note that you have to follow this call with an explicit call to store() if you want to remove\n * the state from localStorage as well.\n *\n * @this {State}\n * @param {Object} [parms]\n */\n unload(parms)\n {\n this.json = \"\";\n this.state = {};\n this.fLoaded = this.fParsed = false;\n if (parms) this.set(\"parms\", parms);\n }\n\n /**\n * clear(fAll)\n *\n * This unloads the current state, and then clears ALL localStorage for the current machine,\n * independent of version, to reduce the chance of orphaned states wasting part of our limited allocation.\n *\n * @this {State}\n * @param {boolean} [fAll] true to unconditionally clear ALL localStorage for the current domain\n */\n clear(fAll)\n {\n this.unload();\n var aKeys = Web.getLocalStorageKeys();\n for (var i = 0; i < aKeys.length; i++) {\n var sKey = aKeys[i];\n if (sKey && (fAll || sKey.substr(0, this.key.length) == this.key)) {\n Web.removeLocalStorageItem(sKey);\n if (DEBUG) Component.log(\"localStorage(\" + sKey + \") removed\");\n aKeys.splice(i, 1);\n i = 0;\n }\n }\n }\n\n /**\n * State.key(component, sVersion, sSuffix)\n *\n * This encapsulates the key generation code.\n *\n * @param {Component} component\n * @param {string} [sVersion] is used to append a major version number to the key\n * @param {string} [sSuffix] is used to append any additional suffixes to the key\n * @return {string} key\n */\n static key(component, sVersion, sSuffix)\n {\n var key = component.id;\n if (sVersion) {\n var i = sVersion.indexOf('.');\n if (i > 0) key += \".v\" + sVersion.substr(0, i);\n }\n if (sSuffix) {\n key += \".\" + sSuffix;\n }\n return key;\n }\n\n /**\n * State.compress(aSrc)\n *\n * @param {Array.<number>|null} aSrc\n * @return {Array.<number>|null} is either the original array (aSrc), or a smaller array of \"count, value\" pairs (aComp)\n */\n static compress(aSrc)\n {\n if (aSrc) {\n var iSrc = 0;\n var iComp = 0;\n var aComp = [];\n while (iSrc < aSrc.length) {\n var n = aSrc[iSrc];\n\n var iCompare = iSrc + 1;\n while (iCompare < aSrc.length && aSrc[iCompare] === n) iCompare++;\n aComp[iComp++] = iCompare - iSrc;\n aComp[iComp++] = n;\n iSrc = iCompare;\n }\n if (aComp.length < aSrc.length) return aComp;\n }\n return aSrc;\n }\n\n /**\n * State.decompress(aComp)\n *\n * @param {Array.<number>} aComp\n * @param {number} nLength is expected length of decompressed data\n * @return {Array.<number>}\n */\n static decompress(aComp, nLength)\n {\n var iDst = 0;\n var aDst = new Array(nLength);\n var iComp = 0;\n while (iComp < aComp.length - 1) {\n var c = aComp[iComp++];\n var n = aComp[iComp++];\n while (c--) {\n aDst[iDst++] = n;\n }\n }\n\n return aDst;\n }\n\n /**\n * State.compressEvenOdd(aSrc)\n *\n * This is a very simple variation on compress() that compresses all the EVEN elements of aSrc first,\n * followed by all the ODD elements. This tends to work better on EGA video memory, because when odd/even\n * addressing is enabled (eg, for text modes), the DWORD values tend to alternate, which is the worst case\n * for compress(), but the best case for compressEvenOdd().\n *\n * One wrinkle we support: if the first element is uninitialized, then we assume the entire array is undefined,\n * and return an empty compressed array. Conversely, decompressEvenOdd() will take an empty compressed array\n * and return an uninitialized array.\n *\n * @param {Array.<number>|null} aSrc\n * @return {Array.<number>|null} is either the original array (aSrc), or a smaller array of \"count, value\" pairs (aComp)\n */\n static compressEvenOdd(aSrc)\n {\n if (aSrc) {\n var iComp = 0, aComp = [];\n if (aSrc[0] !== undefined) {\n for (var off = 0; off < 2; off++) {\n var iSrc = off;\n while (iSrc < aSrc.length) {\n var n = aSrc[iSrc];\n var iCompare = iSrc + 2;\n while (iCompare < aSrc.length && aSrc[iCompare] === n) iCompare += 2;\n aComp[iComp++] = (iCompare - iSrc) >> 1;\n aComp[iComp++] = n;\n iSrc = iCompare;\n }\n }\n }\n if (aComp.length < aSrc.length) return aComp;\n }\n return aSrc;\n }\n\n /**\n * State.decompressEvenOdd(aComp, nLength)\n *\n * This is the counterpart to compressEvenOdd(). Note that because there's nothing in the compressed sequence\n * that differentiates a compress() sequence from a compressEvenOdd() sequence, you simply have to be consistent:\n * if you used even/odd compression, then you must use even/odd decompression.\n *\n * @param {Array.<number>} aComp\n * @param {number} nLength is expected length of decompressed data\n * @return {Array.<number>}\n */\n static decompressEvenOdd(aComp, nLength)\n {\n var iDst = 0;\n var aDst = new Array(nLength);\n var iComp = 0;\n while (iComp < aComp.length - 1) {\n var c = aComp[iComp++];\n var n = aComp[iComp++];\n while (c--) {\n aDst[iDst] = n;\n iDst += 2;\n }\n /*\n * The output of a \"count,value\" pair will never exceed the end of the output array, so as soon as we reach it\n * the first time, we know it's time to switch to ODD elements, and as soon as we reach it again, we should be\n * done.\n */\n\n if (iDst == nLength) iDst = 1;\n }\n\n return aDst;\n }\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/embed.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * We now support asynchronous XML and XSL file loads; simply set fAsync (below) to true.\n *\n * NOTE: For that support to work, we have to keep track of the number of machines on the page\n * (ie, how many embedMachine() calls were issued), reduce the count as each machine XML file\n * is fully transformed into HTML, and when the count finally returns to zero, notify all the\n * machine component init() handlers.\n *\n * Also, to prevent those init() handlers from running prematurely, we must disable all page\n * notification events at the start of the embedding process (Web.enablePageEvents(false)) and\n * re-enable them at the end (Web.enablePageEvents(true)).\n */\nvar fAsync = true;\nvar cAsyncMachines = 0;\n\n/**\n * loadXML(sFile, idMachine, sAppName, sAppClass, sParms, fResolve, display, done)\n *\n * This is the preferred way to load all XML and XSL files. It uses getResource()\n * to load them as strings, which parseXML() can massage before parsing/transforming them.\n *\n * For example, since I've been unable to get the XSLT document() function to work inside any\n * XSL document loaded by JavaScript's XSLT processor, that has prevented me from dynamically\n * loading any XML machine file that uses the \"ref\" attribute to refer to and incorporate\n * another XML document.\n *\n * To solve that, I've added an fResolve parameter that tells parseXML() to fetch any\n * referenced documents ITSELF and insert them into the XML string prior to parsing, instead\n * of relying on the XSLT template to pull them in. That fetching is handled by resolveXML(),\n * which iterates over the XML until all \"refs\" have been resolved (including any nested\n * references).\n *\n * Also, XSL files with a <!DOCTYPE [...]> cause MSIE's Microsoft.XMLDOM.loadXML() function\n * to choke, so I strip that out prior to parsing as well.\n *\n * TODO: Figure out why the XSLT document() function works great when the web browser loads an\n * XML file (and the associated XSL file) itself, but does not work when loading documents via\n * JavaScript XSLT support. Is it broken, is it a security issue, or am I just calling it wrong?\n *\n * @param {string} sXMLFile\n * @param {string|null|undefined} idMachine\n * @param {string|null|undefined} sAppName\n * @param {string|null|undefined} sAppClass\n * @param {string|null|undefined} sParms (machine parameters, if any)\n * @param {string|null|undefined} sClass (an optional machine class name used to style the machine)\n * @param {boolean} fResolve is true to resolve any \"ref\" attributes\n * @param {function(string)} display\n * @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)\n */\nfunction loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n{\n var doneLoadXML = function(sURLName, sXML, nErrorCode) {\n if (nErrorCode) {\n if (!sXML) sXML = \"unable to load \" + sXMLFile + \" (\" + nErrorCode + \")\";\n done(sXML, null);\n return;\n }\n parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done);\n };\n display(\"Loading \" + sXMLFile + \"...\");\n Web.getResource(sXMLFile, null, fAsync, doneLoadXML);\n}\n\n/**\n * parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n *\n * Generates an XML document from an XML string. This function also provides a work-around for XSLT's\n * lack of support for the document() function (at least on some browsers), by replacing every reference\n * tag (ie, a tag with a \"ref\" attribute) with the contents of the referenced file.\n *\n * @param {string} sXML\n * @param {string|null} sXMLFile\n * @param {string|null|undefined} idMachine\n * @param {string|null|undefined} sAppName\n * @param {string|null|undefined} sAppClass\n * @param {string|null|undefined} sParms (machine parameters, if any)\n * @param {string|null|undefined} sClass (an optional machine class name used to style the machine)\n * @param {boolean} fResolve is true to resolve any \"ref\" attributes; default is false\n * @param {function(string)} display\n * @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)\n */\nfunction parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n{\n var buildXML = function(sXML, sError) {\n if (sError) {\n done(sError, null);\n return;\n }\n if (idMachine) {\n\n /*\n * A more sensible place to record the machine XML would be embedMachine(), like we do for the\n * XSL file, but since we're about to modify the original machine XML, it's best to record it now.\n */\n Component.addMachineResource(idMachine, sXMLFile, sXML);\n\n var sURL = sXMLFile;\n if (sURL && sURL.indexOf('/') < 0 && window.location.pathname.slice(-1) == '/') {\n sURL = window.location.pathname + sURL;\n }\n /*\n * We embed the URL of the XML file both as a separate \"xml\" attribute for easy access from the\n * XSL file, and as part of the \"parms\" attribute for easy access from machines (see getMachineParm()).\n */\n if (!sParms) {\n sParms = '{';\n } else if (sParms.slice(-1) == '}') {\n sParms = sParms.slice(0, -1);\n if (sParms.length > 1) sParms += ',';\n } else { // sParms must just be a \"state\" file, so encode it as a \"state\" property\n sParms = '{state:\"' + sParms + '\",';\n }\n sParms += 'url:\"' + sURL + '\"}';\n /*\n * Note that while we no longer generate a machine XML file with a \"state\" attribute (because it's\n * encoded inside the \"parms\" attribute), the XSL file must still cope with \"state\" attributes inside\n * other XML files; for example, manifest XML files like /apps/pcx86/1981/visicalc/manifest.xml contain\n * machine elements with \"state\" attributes that must still be passed down to the computer element\n * \"the old fashioned way\".\n *\n * Until/unless that changes, components.xsl cannot be simplified as much as I might have hoped.\n */\n if (typeof resources == 'object') sURL = null; // turn off URL inclusion if we have embedded resources\n sParms = sParms.replace(/\\$/g, \"$$$$\");\n if (sClass) {\n /*\n * If there's no hard-coded \"class\" attribute in the machine tag, then we can set one in the final\n * replacement below, just like we do for sParms and sURL. However, if a \"class\" attribute already\n * exists, we need alter it and then zap the sClass variable.\n */\n var match = sXML.match(/(<machine[^>]*\\sclass=)(['\"])(.*?)(\\2.*?>)/);\n if (match) {\n sXML = sXML.replace(match[0], match[1] + match[2] + sClass + match[4]);\n sClass = null;\n }\n }\n sXML = sXML.replace(/(<machine[^>]*\\sid=)(['\"]).*?\\2/, \"$1$2\" + idMachine + \"$2\" + (sClass? ' class=\"' + sClass + '\"' : '') + (sParms? \" parms='\" + sParms + \"'\" : \"\") + (sURL? ' url=\"' + sURL + '\"' : ''));\n }\n\n if (!fResolve) {\n /*\n * I'm trying to switch to a shared components.xsl (at least for all PC-class machines),\n * but in the interim, that means hacking the XSL file on the fly to reflect the actual class.\n */\n sXML = sXML.replace(/(<xsl:variable name=\"APPNAME\">).*?(<\\/xsl:variable>)/, \"$1\" + sAppName + \"$2\");\n sXML = sXML.replace(/(<xsl:variable name=\"APPCLASS\">).*?(<\\/xsl:variable>)/, \"$1\" + sAppClass + \"$2\");\n\n /*\n * Non-COMPILED kludge to replace the version number template in the XSL file (which we assume we're reading,\n * since fResolve is false) with whatever XMLVERSION we extracted from the XML file (see corresponding kludge below).\n *\n * ES6 ALERT: Template strings.\n */\n if (!COMPILED && XMLVERSION) {\n sXML = sXML.replace(/<xsl:variable name=\"APPVERSION\"\\/>/, `<xsl:variable name=\"APPVERSION\">${XMLVERSION}</xsl:variable>`);\n }\n }\n\n /*\n * If the resource we requested is not really an XML file (or the file didn't exist and the server simply returned\n * a message like \"Cannot GET /devices/pc/machine/5150/cga/64kb/donkey/machine.xml\"), we'd like to display a more\n * meaningful message, because the XML DOM parsers will blithely return a document that contains nothing useful; eg:\n *\n * This page contains the following errors:error on line 1 at column 1:\n * Document is empty Below is a rendering of the page up to the first error.\n *\n * Supposedly, the IE XML DOM parser will throw an exception, but I haven't tested that, and unless all other\n * browsers do that, that's not helpful.\n *\n * The best I can do at this stage (assuming Web.getResource() didn't drop any error information on the floor)\n * is verify that the requested resource \"looks like\" valid XML (in other words, it begins with a '<').\n */\n var xmlDoc = null;\n if (sXML.charAt(0) == '<') {\n try {\n /*\n * Another hack for MSIE, which fails to load XSL documents containing a <!DOCTYPE [...]> tag.\n *\n * This is also why the XSLTProcessor 'transformToFragment' method in Microsoft Edge silently failed,\n * so I had pull this hack out of the \"ActiveXObject\" code. And rather than add yet-another Microsoft\n * browser check, I'm going to try doing this across the board, and hope that none of the other XSLT\n * processors fail *without* the DOCTYPE tag.\n */\n if (!fResolve) {\n sXML = sXML.replace(/<!DOCTYPE(.|[\\r\\n])*]>\\s*/g, \"\");\n }\n /*\n * Beginning with Microsoft Edge and the corresponding release of Windows 10, all the\n * 'ActiveXObject' crud has gone away; but of course, this code must remain in place if\n * we want to continue supporting older Internet Explorer browsers (ie, back to IE9).\n */\n /** @namespace window.ActiveXObject */\n if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1\n xmlDoc = new window.ActiveXObject(\"Microsoft.XMLDOM\");\n xmlDoc.async = false;\n xmlDoc['loadXML'](sXML);\n } else {\n /** @namespace window.DOMParser */\n xmlDoc = (new window.DOMParser()).parseFromString(sXML, \"text/xml\");\n }\n } catch(e) {\n xmlDoc = null;\n sXML = e.message;\n }\n } else {\n sXML = \"unrecognized XML: \" + (sXML.length > 255? sXML.substr(0, 255) + \"...\" : sXML);\n }\n done(sXML, xmlDoc);\n };\n if (sXML) {\n if (PRIVATE) sXML = sXML.replace(/\\/library.xml/, \"/private/library.xml\");\n if (fResolve) {\n resolveXML(sXML, display, buildXML);\n return;\n }\n buildXML(sXML, null);\n return;\n }\n done(\"no data\" + (sXMLFile? \" for file: \" + sXMLFile : \"\"), null);\n}\n\n/**\n * resolveXML(sXML, display, done)\n *\n * Replaces every tag with a \"ref\" attribute with the contents of the corresponding file.\n *\n * TODO: Fix some of the limitations of this code, such as: 1) requiring the \"ref\" attribute\n * to appear as the tag's first attribute, 2) requiring the \"ref\" attribute to be double-quoted,\n * and 3) requiring the \"ref\" tag to be self-closing.\n *\n * @param {string} sXML\n * @param {function(string)} display\n * @param {function(string,(string|null))} done (the first string contains the resolved XML data, the second is for any error message)\n */\nfunction resolveXML(sXML, display, done)\n{\n var matchRef;\n var reRef = /<([a-z]+)\\s+ref=\"(.*?)\"(.*?)\\/>/g;\n\n if ((matchRef = reRef.exec(sXML))) {\n\n var sRefFile = matchRef[2];\n\n var doneReadXML = function(sURLName, sXMLRef, nErrorCode) {\n if (nErrorCode || !sXMLRef) {\n done(sXML, \"unable to resolve XML reference: \" + matchRef[0] + \" (\" + nErrorCode + \")\");\n return;\n }\n /*\n * If there are additional attributes in the \"referring\" XML tag, we want to insert them\n * into the \"referred\" XML tag; attributes that don't exist in the referred tag should be\n * appended, and attributes that DO exist should be overwritten.\n */\n var sRefAttrs = matchRef[3];\n if (sRefAttrs) {\n var aXMLRefTag = sXMLRef.match(new RegExp(\"<\" + matchRef[1] + \"[^>]*>\"));\n if (aXMLRefTag) {\n var sXMLNewTag = aXMLRefTag[0];\n /*\n * Iterate over all the attributes in the \"referring\" XML tag (sRefAttrs)\n */\n var matchAttr;\n var reAttr = /( [a-z]+=)(['\"])(.*?)\\2/gi;\n while ((matchAttr = reAttr.exec(sRefAttrs))) {\n if (sXMLNewTag.toLowerCase().indexOf(matchAttr[1].toLowerCase()) < 0) {\n /*\n * This is the append case....\n */\n sXMLNewTag = sXMLNewTag.replace(\">\", matchAttr[0] + \">\");\n } else {\n /*\n * This is the overwrite case....\n */\n sXMLNewTag = sXMLNewTag.replace(new RegExp(matchAttr[1] + \"(['\\\"])(.*?)\\\\1\"), matchAttr[0]);\n }\n }\n if (aXMLRefTag[0] != sXMLNewTag) {\n sXMLRef = sXMLRef.replace(aXMLRefTag[0], sXMLNewTag);\n }\n } else {\n done(sXML, \"missing <\" + matchRef[1] + \"> in \" + sRefFile);\n return;\n }\n }\n\n /*\n * Apparently when a Windows Azure server delivers one of my XML files, it may modify the first line:\n *\n * <?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n\n *\n * I didn't determine exactly what it was doing at this point (probably just changing the \\n to \\r\\n),\n * but in any case, relaxing the following replace() solved it.\n */\n sXMLRef = sXMLRef.replace(/<\\?xml[^>]*>[\\r\\n]*/, \"\");\n\n sXML = sXML.replace(matchRef[0], sXMLRef);\n\n resolveXML(sXML, display, done);\n };\n\n display(\"Loading \" + sRefFile + \"...\");\n Web.getResource(sRefFile, null, fAsync, doneReadXML);\n return;\n }\n done(sXML, null);\n}\n\n/**\n * embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * This allows to you embed a machine on a web page, by transforming the machine XML into HTML.\n *\n * @param {string} sAppName is the app name (eg, \"PCx86\")\n * @param {string} sAppClass is the app class (eg, \"pcx86\"); also known as the machine class\n * @param {string} sVersion is the app version (eg, \"1.15.7\")\n * @param {string} idMachine\n * @param {string|undefined} sXMLFile\n * @param {string|undefined} sXSLFile\n * @param {string|undefined} sParms (machine parameters, if any)\n * @param {string|undefined} sClass (an optional machine class name used to style the machine)\n * @return {boolean} true if successful, false if error\n */\nfunction embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n var eMachine, eWarning, fSuccess = true;\n\n if (!sXMLFile) {\n sXMLFile = \"machine.xml\";\n if (!sXSLFile) sXSLFile = \"components.xsl\";\n }\n \n cAsyncMachines++;\n Component.addMachine(idMachine);\n\n var doneMachine = function() {\n\n if (!--cAsyncMachines) {\n if (fAsync) Web.enablePageEvents(true);\n }\n };\n\n var displayError = function(sError) {\n Component.log(sError);\n displayMessage(\"Error: \" + sError);\n if (fSuccess) doneMachine();\n fSuccess = false;\n };\n\n var displayMessage = function(sMessage) {\n if (eWarning === undefined) {\n /*\n * Our MarkOut module (in convertMDMachineLinks()) creates machine containers that look like:\n *\n * <div id=\"' + sMachineID + '\" class=\"machine-placeholder\"><p>Embedded PC</p><p class=\"machine-warning\">...</p></div>\n *\n * with the \"machine-warning\" paragraph pre-populated with a warning message that the user will\n * see if nothing at all happens. But hopefully, in the normal case (and especially the error case),\n * *something* will have happened.\n *\n * Note that it is the HTMLOut module (in processMachines()) that ultimately decides which scripts to\n * include and then generates the embedXXX() call.\n */\n var aeWarning = (eMachine && Component.getElementsByClass(eMachine, \"machine-warning\"));\n eWarning = (aeWarning && aeWarning[0]) || eMachine;\n }\n if (eWarning) eWarning.innerHTML = Str.escapeHTML(sMessage);\n };\n\n try {\n eMachine = document.getElementById(idMachine);\n if (eMachine) {\n\n /*\n * If we have a 'css' resource, add it to the page first.\n */\n var css;\n if (typeof resources == \"object\" && (css = resources['css'])) {\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n // noinspection JSDeprecatedSymbols\n if (style.styleSheet) {\n // noinspection JSDeprecatedSymbols\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n head.appendChild(style);\n }\n\n if (!sXSLFile) {\n /*\n * Now that PCjs is an open-source project, we can make the following test more flexible,\n * and revert to the internal template if DEBUG *or* internal version (instead of *and*).\n *\n * Third-party sites that don't use the PCjs server will ALWAYS want to specify a fully-qualified\n * path to the XSL file, unless they choose to mirror our folder structure.\n */\n var sAppFolder = sAppClass;\n if (DEBUG || !sVersion) {\n if (sAppClass != \"c1pjs\") sAppFolder = \"shared\";\n sXSLFile = \"/modules/\" + sAppFolder + \"/templates/components.xsl\";\n } else {\n if (sAppClass.substr(0, 3) == \"pdp\") sAppFolder = \"pdpjs\";\n sXSLFile = \"/versions/\" + sAppFolder + \"/\" + sVersion + \"/components.xsl\";\n }\n }\n\n var processXML = function(sXML, xml) {\n if (!xml) {\n displayError(sXML);\n return;\n }\n\n /*\n * Non-COMPILED kludge to extract the version number from the stylesheet path in the machine XML file;\n * we don't need this code in COMPILED (non-DEBUG) releases, because APPVERSION is hard-coded into them.\n */\n if (!COMPILED) {\n var aMatch = sXML.match(/<\\?xml-stylesheet[^>]* href=(['\"])[^'\"]*?\\/([0-9.]*)\\/([^'\"]*)\\1/);\n if (aMatch) {\n XMLVERSION = aMatch[2];\n }\n }\n\n var transformXML = function(sXSL, xsl) {\n if (!xsl) {\n displayError(sXSL);\n return;\n }\n\n /*\n * Record the XSL file, in case someone wants to save the entire machine later.\n * \n * NOTE: sXSLFile will never be undefined by this point, but apparently the Closure Compiler doesn't realize that. \n */\n Component.addMachineResource(idMachine, sXSLFile || \"\", sXSL);\n\n /*\n * The <machine> template in components.xsl now generates a \"machine div\" that makes\n * the div we required the caller of embedMachine() to provide redundant, so instead\n * of appending this fragment to the caller's node, we REPLACE the caller's node.\n * This works only because because we ALSO inject the caller's \"machine div\" ID into\n * the fragment's ID during parseXML().\n *\n * eMachine.innerHTML = sFragment;\n *\n * Also, if the transform function fails, make sure you're using the appropriate\n * \"components.xsl\" and not a \"machine.xsl\", because the latter will not produce valid\n * embeddable HTML (and is the most common cause of failure at this final stage).\n */\n displayMessage(\"Processing \" + sXMLFile + \"...\");\n\n /*\n * Beginning with Microsoft Edge and the corresponding release of Windows 10, all the\n * 'ActiveXObject' crud has gone away; but of course, this code must remain in place if\n * we want to continue supporting older Internet Explorer browsers (ie, back to IE9).\n */\n if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1\n var sFragment = xml['transformNode'](xsl);\n if (sFragment) {\n eMachine.outerHTML = sFragment;\n doneMachine();\n } else {\n displayError(\"transformNodeToObject failed\");\n }\n }\n else if (document.implementation && document.implementation.createDocument) {\n var xsltProcessor = new XSLTProcessor();\n xsltProcessor['importStylesheet'](xsl);\n var eFragment = xsltProcessor['transformToFragment'](xml, document);\n if (eFragment) {\n /*\n * This fails in Microsoft Edge...\n *\n var machine = eFragment.getElementById(idMachine);\n if (!machine) {\n displayError(\"machine generation failed: \" + idMachine);\n } else\n */\n if (eMachine.parentNode) {\n eMachine.parentNode.replaceChild(eFragment, eMachine);\n doneMachine();\n } else {\n /*\n * NOTE: This error can occur if our Node web server, when processing a folder with\n * both a manifest.xml with a machine.xml reference AND a README.md containing a\n * machine link, generates duplicate embedXXX() calls for the same machine; if the\n * first embedXXX() call finds its target, subsequent calls for the same target will\n * fail.\n *\n * Technically, such a folder is in a misconfigured state, but it happens, in part\n * because when we switched to the Jekyll web server, we had to add machine links to\n * all README.md files where we had previously relied on manifest.xml or machine.xml\n * processing. This is because the Jekyll web server currently doesn't process XML\n * files, nor is support for that likely to be added any time soon; it was a nice\n * feature of the Node web server, but it's not clear that it's worth doing for Jekyll.\n */\n displayError(\"invalid machine element: \" + idMachine);\n }\n } else {\n displayError(\"transformToFragment failed\");\n }\n } else {\n /*\n * Perhaps I should have performed this test at the outset; on the other hand, I'm\n * not aware of any browsers don't support one or both of the above XSLT transformation\n * methods, so treat this as a bug.\n */\n displayError(\"unable to transform XML: unsupported browser\");\n }\n };\n /*\n * NOTE: sXSLFile will never be undefined by this point, but apparently the Closure Compiler doesn't realize that. \n */\n loadXML(sXSLFile || \"\", null, sAppName, sAppClass, null, null, false, displayMessage, transformXML);\n };\n\n if (sXMLFile.charAt(0) != '<') {\n loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, true, displayMessage, processXML);\n } else {\n parseXML(sXMLFile, null, idMachine, sAppName, sAppClass, sParms, sClass, false, displayMessage, processXML);\n }\n } else {\n displayError(\"missing machine element: \" + idMachine);\n }\n } catch(e) {\n displayError(e.message);\n }\n return fSuccess;\n}\n\n/**\n * embedC1P(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedC1P(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"C1Pjs\", \"c1pjs\", APPVERSION, idMachine, sXMLFile, sXSLFile, undefined, sClass);\n}\n\n/**\n * embedPCx86(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPCx86(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PCx86\", \"pcx86\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPC8080(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPC8080(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PC8080\", \"pc8080\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPDP10(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPDP10(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PDPjs\", \"pdp10\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPDP11(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPDP11(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PDPjs\", \"pdp11\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * findMachineComponent(idMachine, sType)\n *\n * @param {string} idMachine\n * @param {string} sType\n * @return {Component|null}\n */\nfunction findMachineComponent(idMachine, sType)\n{\n return Component.getComponentByType(sType, idMachine + \".machine\");\n}\n\n/**\n * commandMachine(control, fSingle, idMachine, sComponent, sCommand, sValue)\n *\n * Use Component methods to find the requested component for a specific machine, and if the component is found,\n * then check its 'exports' table for an entry matching the specified command string, and if an entry is found, then\n * the corresponding function is called with the specified data.\n *\n * @param {Object} control\n * @param {boolean} fSingle\n * @param {string} idMachine\n * @param {string} sComponent\n * @param {string} sCommand\n * @param {string} [sValue]\n * @return {boolean}\n */\nfunction commandMachine(control, fSingle, idMachine, sComponent, sCommand, sValue)\n{\n if (sCommand == \"script\") {\n if (Component.processScript(idMachine, sValue)) {\n if (fSingle) control.disabled = true;\n return true;\n }\n return false;\n }\n if (sComponent) {\n var component = Component.getComponentByType(sComponent, idMachine + \".machine\");\n if (component) {\n var exports = component['exports'];\n if (exports) {\n var fnCommand = exports[sCommand];\n if (fnCommand) {\n if (fnCommand.call(component, sValue)) {\n if (fSingle) control.disabled = true;\n return true;\n }\n return false;\n }\n }\n }\n }\n console.log(\"unimplemented: commandMachine('\" + idMachine + \"','\" + sComponent + \"','\" + sCommand + \"','\" + sValue + \"')\");\n return false;\n}\n\n/**\n * Prevent the Closure Compiler from renaming functions we want to export, by adding them as global properties.\n *\n * TODO: Consider making all these functions properties on a single global object (eg, 'PCjs'), to minimize global\n * pollution and risk of name collision.\n */\nif (APPNAME == \"C1Pjs\") {\n window['embedC1P'] = embedC1P;\n}\nif (APPNAME == \"PCx86\") {\n window['embedPC'] = embedPCx86; // WARNING: embedPC() deprecated as of v1.23.0\n window['embedPCx86'] = embedPCx86;\n}\nif (APPNAME == \"PC8080\") {\n window['embedPC8080'] = embedPC8080;\n}\nif (APPNAME == \"PDPjs\") {\n window['embedPDP10'] = embedPDP10;\n window['embedPDP11'] = embedPDP11;\n}\n\nwindow['commandMachine'] = commandMachine;\n\nwindow['enableEvents'] = Web.enablePageEvents;\nwindow['sendEvent'] = Web.sendPageEvent;\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/save.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * savePC(idMachine, sPCJSFile, callback)\n *\n * @param {string} idMachine\n * @param {string} sPCJSFile\n * @param {function(Object)} [callback]\n * @return {boolean} true if successful, false if error\n */\nfunction savePC(idMachine, sPCJSFile, callback)\n{\n var cmp = /** @type {Computer} */ (Component.getComponentByType(\"Computer\", idMachine));\n var dbg = false; // /** @type {Debugger} */ (Component.getComponentByType(\"Debugger\", idMachine));\n if (cmp) {\n var sState = cmp.powerOff(true);\n var sParms = cmp.saveMachineParms();\n if (!sPCJSFile) {\n if (DEBUG) {\n sPCJSFile = \"/versions/pcx86/\" + (XMLVERSION || APPVERSION) + \"/pcx86-uncompiled.js\"\n } else {\n sPCJSFile = \"/versions/pcx86/\" + (XMLVERSION || APPVERSION) + \"/pcx86\" + (dbg? \"-dbg\" : \"\") + \".js\";\n }\n }\n if (callback && callback({ state: sState, parms: sParms })) return true;\n Web.getResource(sPCJSFile, null, true, function(sURL, sResponse, nErrorCode) {\n downloadCSS(sURL, sResponse, nErrorCode, [idMachine, Str.getBaseName(sPCJSFile, true), sParms, sState]);\n });\n return true;\n }\n Component.alertUser(\"Unable to identify machine '\" + idMachine + \"'\");\n return false;\n}\n\n/**\n * downloadCSS(sURL, sPCJS, nErrorCode, aMachineInfo)\n *\n * @param {string} sURL\n * @param {string} sPCJS\n * @param {number} nErrorCode\n * @param {Array} aMachineInfo ([0] = idMachine, [1] = sScript, [2] = sParms, [3] = sState)\n */\nfunction downloadCSS(sURL, sPCJS, nErrorCode, aMachineInfo)\n{\n if (!nErrorCode && sPCJS) {\n aMachineInfo.push(sPCJS);\n var res = Component.getMachineResources(aMachineInfo[0]);\n var sCSSFile = null;\n for (var sName in res) {\n if (Str.endsWith(sName, \"components.xsl\")) {\n sCSSFile = sName.replace(\".xsl\", \".css\");\n break;\n }\n }\n if (!sCSSFile) {\n /*\n * This is probably a bad idea (ie, allowing downloadPC() to proceed with our stylesheet)...\n */\n downloadPC(sURL, null, 0, aMachineInfo);\n } else {\n Web.getResource(sCSSFile, null, true, function(sURL, sResponse, nErrorCode) {\n downloadPC(sURL, sResponse, nErrorCode, aMachineInfo);\n });\n }\n return;\n }\n Component.alertUser(\"Error (\" + nErrorCode + \") requesting \" + sURL);\n}\n\n/**\n * downloadPC(sURL, sCSS, nErrorCode, aMachineInfo)\n *\n * @param {string} sURL\n * @param {string|null} sCSS\n * @param {number} nErrorCode\n * @param {Array} aMachineInfo ([0] = idMachine, [1] = sScript, [2] = sParms, [3] = sState, [4] = sPCJS)\n */\nfunction downloadPC(sURL, sCSS, nErrorCode, aMachineInfo)\n{\n var matchScript, sXMLFile, sXSLFile;\n var idMachine = aMachineInfo[0], sScript = aMachineInfo[1], sPCJS = aMachineInfo[4];\n\n /*\n * sPCJS is supposed to contain the entire PCjs script, which has been wrapped with:\n *\n * (function(){...\n *\n * at the top and:\n *\n * ...})();\n *\n * at the bottom, thanks to the following Closure Compiler option:\n *\n * --output_wrapper \"(function(){%output%})();\"\n *\n * NOTE: There may also be a source map comment appended to the script, which we now ignore; eg:\n *\n * //# sourceMappingURL=/versions/pcx86/1.36.1/pcx86.map\n *\n * Immediately inside that wrapping, we want to embed all the specified machine's resources, using:\n *\n * var resources = {\"xml\": \"...\", \"xsl\": \"...\", ...};\n *\n * Note that the \"resources\" variable has been added to our externs.js, to prevent it from being renamed\n * by the Closure Compiler.\n */\n matchScript = sPCJS.match(/^(\\s*\\(function\\(\\){)([\\s\\S]*)(}\\)\\(\\);)/);\n if (!matchScript) {\n /*\n * If the match failed, we assume that a DEBUG (uncompiled) script is being used,\n * so we'll provide a fake match that should work with whatever script was provided.\n */\n if (DEBUG) {\n matchScript = [sPCJS, \"\", sPCJS, \"\"];\n } else {\n Component.alertUser(\"Unsupported script\");\n return;\n }\n }\n\n var resOld = Component.getMachineResources(idMachine), resNew = {};\n for (var sName in resOld) {\n var data = resOld[sName];\n var sExt = Str.getExtension(sName);\n if (sExt == \"xml\") {\n /*\n * Look through this resource for <disk> entries whose paths do not appear as one of the\n * other machine resources, and remove those entries.\n */\n var matchDisk, reDisk = /[ \\t]*<disk [^>]*path=(['\"])(.*?)\\1.*?<\\/disk>\\n?/g;\n while (matchDisk = reDisk.exec(resOld[sName])) {\n var path = matchDisk[2];\n if (path) {\n if (resOld[path]) {\n Component.log(\"recording disk: '\" + path + \"'\");\n } else {\n data = data.replace(matchDisk[0], \"\");\n }\n }\n }\n sXMLFile = sName = Str.getBaseName(sName);\n }\n else if (sExt == \"xsl\") {\n sXSLFile = sName = Str.getBaseName(sName);\n }\n Component.log(\"saving resource: '\" + sName + \"' (\" + data.length + \" bytes)\");\n resNew[sName] = data;\n }\n\n if (sCSS) {\n resNew[sName = 'css'] = sCSS;\n Component.log(\"saving resource: '\" + sName + \"' (\" + sCSS.length + \" bytes)\");\n }\n\n if (aMachineInfo[2]) {\n var sParms = resNew[sName = 'parms'] = aMachineInfo[2];\n Component.log(\"saving resource: '\" + sName + \"' (\" + sParms.length + \" bytes)\");\n }\n\n if (aMachineInfo[3]) {\n var sState = resNew[sName = 'state'] = aMachineInfo[3];\n Component.log(\"saving resource: '\" + sName + \"' (\" + sState.length + \" bytes)\");\n }\n\n if (sXMLFile && sXSLFile) {\n var sResources = JSON.stringify(resNew);\n\n sScript += \".js\";\n sPCJS = matchScript[1] + \"var resources=\" + sResources + \";\" + matchScript[2] + matchScript[3];\n Component.log(\"saving machine: '\" + idMachine + \"' (\" + sPCJS.length + \" bytes)\");\n\n /*\n * I don't recall exactly why I did this, because I just tested FireFox with copyright symbols intact,\n * and it seems to work fine. And unfortunately, if we print any copyright strings containing the HTML\n * entity, the entity doesn't get translated prior to output. So if it turns out we DO need this,\n * it's better to replace with the old-fashioned ASCII version.\n * \n * sPCJS = sPCJS.replace(/\\u00A9/g, \"(C)\"); // \"©\" or \"©\"\n */\n\n var sAlert = Web.downloadFile(sPCJS, \"javascript\", false, sScript);\n\n sAlert += ', copy it to your web server as \"' + sScript + '\", and then add the following to your web page:\\n\\n';\n sAlert += '<div id=\"' + idMachine + '\"></div>\\n';\n sAlert += '...\\n';\n sAlert += '<script type=\"text/javascript\" src=\"' + sScript + '\"></script>\\n';\n \n /*\n * I've updated embedMachine() in embed.js to use these defaults whenever the XML file is omitted, so if our\n * values match those defaults, we can omit both the XML and XSL file parameters and display a simplified call.\n */\n if (sXMLFile == \"machine.xml\" && sXSLFile == \"components.xsl\") {\n sXMLFile = sXSLFile = \"\";\n } else {\n sXMLFile = ',\"' + sXMLFile + '\"';\n sXSLFile = ',\"' + sXSLFile + '\"';\n }\n \n sAlert += '<script type=\"text/javascript\">embedPCx86(\"' + idMachine + '\"' + sXMLFile + sXSLFile + ');</script>\\n\\n';\n sAlert += 'The machine should appear where the <div> is located.';\n Component.alertUser(sAlert);\n return;\n }\n Component.alertUser(\"Missing XML/XSL resources\");\n}\n\n/**\n * Prevent the Closure Compiler from renaming functions we want to export, by adding them\n * as (named) properties of a global object.\n */\nwindow['savePC'] = savePC;\n"]} \ No newline at end of file diff --git a/versions/pdpjs/1.61.0/pdp10-uncompiled.js b/versions/pdpjs/1.61.0/pdp10-uncompiled.js index e61a431495..41ae2b4a31 100644 --- a/versions/pdpjs/1.61.0/pdp10-uncompiled.js +++ b/versions/pdpjs/1.61.0/pdp10-uncompiled.js @@ -629,7 +629,7 @@ class Str { * * Displays the given number as an unsigned integer using the specified radix and number of digits. * - * @param {number|null|undefined} n + * @param {number|*} n * @param {number} radix (ie, the base) * @param {number} cch (the desired number of digits) * @param {string} [sPrefix] (default is none) @@ -639,17 +639,17 @@ class Str { static toBase(n, radix, cch, sPrefix = "", nGrouping = 0) { /* - * An initial "falsey" check for null takes care of both null and undefined; - * we can't rely entirely on isNaN(), because isNaN(null) returns false, oddly enough. + * We can't rely entirely on isNaN(), because isNaN(null) returns false, and we can't rely + * entirely on typeof either, because typeof Nan returns "number". Sigh. * * Alternatively, we could mask and shift n regardless of whether it's null/undefined/NaN, * since JavaScript coerces such operands to zero, but I think there's "value" in seeing those * values displayed differently. */ var s = ""; - if (isNaN(n)) { + if (isNaN(n) || typeof n != "number") { n = null; - } else if (n != null) { + } else { /* * Callers that produced an input by dividing by a power of two rather than shifting (in order * to access more than 32 bits) may produce a fractional result, which ordinarily we would simply @@ -692,7 +692,7 @@ class Str { * * Converts an integer to binary, with the specified number of digits (up to a maximum of 36). * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of binary digits (0 or undefined for default of either 8, 18, or 36) * @param {number} [nGrouping] * @return {string} the binary representation of n @@ -744,7 +744,7 @@ class Str { * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw * an exception, whereas this function will return '?' characters. * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of octal digits (0 or undefined for default of either 6, 8, or 12) * @param {boolean} [fPrefix] * @return {string} the octal representation of n @@ -774,7 +774,7 @@ class Str { * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw * an exception, whereas this function will return '?' characters. * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of decimal digits (0 or undefined for default of either 5 or 11) * @return {string} the decimal representation of n */ @@ -809,7 +809,7 @@ class Str { * s = "00000000".substr(0, 8 - s.length) + s; * s = s.substr(0, cch).toUpperCase(); * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of hex digits (0 or undefined for default of either 4, 8, or 9) * @param {boolean} [fPrefix] * @return {string} the hex representation of n @@ -3139,7 +3139,7 @@ class Component { if (target) { var control = target.bindings[sBinding]; if (control) { - component.setBinding(null, sBinding, control); + component.setBinding("", sBinding, control); } } } @@ -3627,7 +3627,7 @@ class Component { * Component's setBinding() method is intended to be overridden by subclasses. * * @this {Component} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, 'print') * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -4080,10 +4080,10 @@ class Component { * * @this {Component} * @param {number} port - * @param {number|null} bOut if an output operation - * @param {number|null} [addrFrom] - * @param {string|null} [name] of the port, if any - * @param {number|null} [bIn] is the input value, if known, on an input operation + * @param {number|null|*} bOut if an output operation + * @param {number|null|*} [addrFrom] + * @param {string|null|*} [name] of the port, if any + * @param {number|null|*} [bIn] is the input value, if known, on an input operation * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s) */ printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage) @@ -4812,7 +4812,7 @@ class PanelPDP10 extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * Some panel layouts don't have bindings of their own, and even when they do, there may still be some * components (eg, the CPU) that prefer to update their own bindings, so we pass along all binding requests @@ -4820,23 +4820,17 @@ class PanelPDP10 extends Component { * component that doesn't recognize the specified binding should simply ignore it. * * @this {PanelPDP10} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "reset") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { - if (this.cmp && this.cmp.setBinding(sType, sBinding, control, sValue)) { - return true; - } - if (this.cpu && this.cpu.setBinding(sType, sBinding, control, sValue)) { - return true; - } - if (DEBUGGER && this.dbg && this.dbg.setBinding(sType, sBinding, control, sValue)) { - return true; - } + 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; switch (sBinding) { case 'PC': @@ -4852,7 +4846,7 @@ class PanelPDP10 extends Component { * * Only *type* and *binding* attributes are required; if *value* is omitted, the default value is 0 ("off"). */ - if (sType == "led" || sType == "rled") { + if (sHTMLType == "led" || sHTMLType == "rled") { this.bindings[sBinding] = control; this.leds[sBinding] = sValue? 1 : 0; this.cLiveRegs++; @@ -4868,7 +4862,7 @@ class PanelPDP10 extends Component { * Currently, there is no XML attribute to indicate whether a switch is "momentary"; only recognized switches * in our internal table can have that attribute. */ - if (sType == "switch") { + if (sHTMLType == "switch") { /* * Like LEDs, we allow unrecognized switches to be defined as well, but they won't do anything useful, * since only recognized switches will have handlers that perform the appropriate operations. @@ -4902,7 +4896,7 @@ class PanelPDP10 extends Component { }(this, sBinding); return true; } - return super.setBinding(sType, sBinding, control, sValue); + return super.setBinding(sHTMLType, sBinding, control, sValue); } } @@ -7266,7 +7260,7 @@ class CPUPDP10 extends Component { this.panel = cmp.panel; for (var i = 0; i < CPUPDP10.BUTTONS.length; i++) { var control = this.bindings[CPUPDP10.BUTTONS[i]]; - if (control) this.cmp.setBinding(null, CPUPDP10.BUTTONS[i], control); + if (control) this.cmp.setBinding("", CPUPDP10.BUTTONS[i], control); } this.setReady(); } @@ -7517,16 +7511,16 @@ class CPUPDP10 extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {CPUPDP10} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "run") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { var cpu = this; @@ -17684,18 +17678,18 @@ class SerialPortPDP10 extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {SerialPortPDP10} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "buffer") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { - if (sType == null || sType == "textarea") { + if (!sHTMLType || sHTMLType == "textarea") { var serial = this; this.bindings[sBinding] = this.controlBuffer = control; @@ -19203,7 +19197,7 @@ class Debugger extends Component * * @this {Debugger} * @param {string|undefined} sValue - * @param {string|null} [sName] is the name of the value, if any + * @param {string|null|*} [sName] is the name of the value, if any * @param {Array|undefined|boolean} [fQuiet] * @param {number} [nUnary] (0 for none, 1 for negate, 2 for complement, 3 for leading zeros) * @return {number|undefined} numeric value, or undefined if sValue is either undefined or invalid @@ -19825,16 +19819,16 @@ class DebuggerPDP10 extends Debugger { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {DebuggerPDP10} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "debugInput") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { var dbg = this; switch (sBinding) { @@ -26922,16 +26916,16 @@ class ComputerPDP10 extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {ComputerPDP10} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "reset") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { var computer = this; diff --git a/versions/pdpjs/1.61.0/pdp10.js b/versions/pdpjs/1.61.0/pdp10.js index 24c20f2ab6..eafb92ec02 100644 --- a/versions/pdpjs/1.61.0/pdp10.js +++ b/versions/pdpjs/1.61.0/pdp10.js @@ -36,7 +36,7 @@ var ya={sc:0,Lb:1,uc:2,vc:3,wc:4,xc:5,yc:6,zc:7,vb:8,Ac:9,Mb:10,Bc:11,Cc:12,Nb:1 fd:85,gd:86,hd:87,jd:88,kd:89,Pb:90,"[":91,"\\":92,"]":93,"^":94,_:95,"`":96,xb:97,ld:98,md:99,d:100,e:101,nd:102,od:103,pd:104,qd:105,sd:106,k:107,td:108,ud:109,n:110,vd:111,p:112,q:113,r:114,wd:115,t:116,zd:117,Ad:118,Bd:119,x:120,y:121,z:122,"{":123,"|":124,"}":125,"~":126,Ob:127}; function za(a,b){if(a){b||(b=10);var c,d=0<a.indexOf(",");d&&(a=a.replace(/,/g,""));var e=c=a.charAt(0);"#"==c?(b=8,c=""):"$"==c&&(b=16,c="");e!=c?a=a.substr(1):(e=c=a.substr(0,2),"0b"==c&&d||"^B"==c?(b=2,c=""):"0o"==c||"^O"==c?(b=8,c=""):"^D"==c?(b=10,c=""):"0x"==c&&(b=16,c=""),e!=c&&(a=a.substr(2)));e=c=a.slice(-1);"Y"==c||"y"==c?(b=2,c=""):"."==c?(b=10,c=""):"H"==c||"h"==c?(b=16,c=""):"K"==c?c="000":"M"==c?c="000000":"G"==c&&(c="000000000");e!=c&&(a=a.slice(0,-1)+c);var f;e=0;10>=b&&(c=a.match(/(-?[0-9]+)B([0-9]*)/))&& (a=c[1],e=35-((c[2]||35)&255));c=a;if(((d=b)&&10!=d?16==d?null!==c.match(/^-?[0-9a-f]+$/i):8==d?null!==c.match(/^-?[0-7]+$/):2==d&&null!==c.match(/^-?[01]+$/):null!==c.match(/^-?[0-9]+$/))&&!isNaN(f=parseInt(a,b))){e&&(0>f&&(f+=Math.pow(2,36)),f=0<e?f*Math.pow(2,e):Math.trunc(f/Math.pow(2,-e)));var g=f}}return g} -function Aa(a,b,c,d,e){e=void 0===e?0:e;var f="";isNaN(a)?a=null:null!=a&&(0>a&&-1<a&&(a=-1),0>a&&(a+=Math.pow(b,c)),a>=Math.pow(b,c)&&(c=Math.ceil(Math.log(a)/Math.log(b))));for(var g=e||-1;0<c--;){g||(f=","+f,g=e);if(null==a)f="?"+f;else{var h=a%b;h+=0<=h&&9>=h?48:55;f=String.fromCharCode(h)+f;a=Math.trunc(a/b)}g--}return(void 0===d?"":d)+f}function Ba(a,b,c){b?12<b&&(b=12):(b=Math.abs(a),b=262143>=b?6:16777215>=b?8:12);return Aa(a,8,b,c?"0o":"")} +function Aa(a,b,c,d,e){e=void 0===e?0:e;var f="";isNaN(a)||"number"!=typeof a?a=null:(0>a&&-1<a&&(a=-1),0>a&&(a+=Math.pow(b,c)),a>=Math.pow(b,c)&&(c=Math.ceil(Math.log(a)/Math.log(b))));for(var g=e||-1;0<c--;){g||(f=","+f,g=e);if(null==a)f="?"+f;else{var h=a%b;h+=0<=h&&9>=h?48:55;f=String.fromCharCode(h)+f;a=Math.trunc(a/b)}g--}return(void 0===d?"":d)+f}function Ba(a,b,c){b?12<b&&(b=12):(b=Math.abs(a),b=262143>=b?6:16777215>=b?8:12);return Aa(a,8,b,c?"0o":"")} function Ca(a,b){b?11<b&&(b=11):b=99999>=Math.abs(a)?5:11;return Aa(a,10,b)}function n(a,b,c){b?9<b&&(b=9):(b=Math.abs(a),b=65535>=b?4:4294967295>=b?8:9);return Aa(a,16,b,c?"0x":"")}function Da(a){var b=a,c=a.lastIndexOf("/");0<=c&&(b=a.substr(c+1));c=b.indexOf("\x26");0<c&&(b=b.substr(0,c));return b}function Ea(a){var b="",c=a.lastIndexOf(".");0<=c&&(b=a.substr(c+1).toLowerCase());return b}function Fa(a,b){return-1!==a.indexOf(b,a.length-b.length)} function Ga(a){return a.replace(/[&<>"']/g,function(a){return Ka[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 Ka={"\x26":"\x26amp;","\x3c":"\x26lt;","\x3e":"\x26gt;",'"':"\x26quot;","'":"\x26#039;"};function Na(a,b,c){var d=0,e=a.length,f=0;for(void 0===c&&(c=function(a,b){return a>b?1:a<b?-1:0});d<e;){var g=d+e>>1;var h=c(b,a[g]);0<h?d=g+1:(e=g,f=!h)}return f?d:~d} function Oa(){var a,b="";a||(a=new Date);for(var c=a.getHours(),d=a.getDate(),e=a.getMonth()+1,f=0;11>f;f++){var g;switch(g="Y-m-d H:i:s".charAt(f)){case "a":b+=12>c?"am":"pm";break;case "d":b+=("0"+d).slice(-2);break;case "D":b+=Pa[a.getDay()].substr(0,3);break;case "F":b+=Qa[e-1];break;case "g":b+=c?12<c?c-12:c:12;break;case "h":b+=c;break;case "H":b+=("0"+c).slice(-2);break;case "i":b+=("0"+a.getMinutes()).slice(-2);break;case "j":b+=d;break;case "l":b+=Pa[a.getDay()];break;case "m":b+=("0"+e).slice(-2); @@ -89,7 +89,7 @@ function fd(a,b,c){c&&a.i||(a.f=b[0]||a.rb);if(c||void 0===c)a.w=b[0]||a.rb}func m.Va=function(a,b,c){this.b&&$b(this.b,32)&&ac(this.b,"attempt to write "+L(this.b,a)+" to invalid addresses "+L(this.b,c),!0);this.G.Hb(c)};m.gc=function(a){return this.j[a]};m.pc=function(a,b){this.j[b]!=a&&(this.j[b]=a,this.ob=!0)};m.ec=function(a,b){if(this.b&&null!=this.A){var c=this.b;id(c,this.A+a,2,c.N)&&jd(c,!1)}return this.w(a,b)};m.oc=function(a,b,c){if(this.b&&null!=this.A){var d=this.b;id(d,this.A+b,2,d.K)&&jd(d,!1)}this.F?this.Va(a,b,c):this.C(a,b,c)}; var ad=0,bd=2,Wc=["NONE","RAM","ROM"],$c=0,ed=[],dd=[Qc.prototype.gc,Qc.prototype.pc],hd=[Qc.prototype.ec,Qc.prototype.oc]; function kd(a,b){u.call(this,"CPU",a,1);b=+a.cycles||b;var c=+a.multiplier||1;this.fb=0;this.jb=b;this.fa=c;this.gb=Math.round(this.jb/1E4)/100;this.aa=this.gb*this.fa;this.ib=this.Ga=this.ka=this.Za=0;this.flags.P=this.flags.eb=!1;this.flags.ea=a.autoStart;"string"==typeof this.flags.ea&&(this.flags.ea="true"==this.flags.ea);this.flags.Ra=!1;this.Ea=this.ra=0;this.Fa=+a.csStart;this.na=+a.csInterval;this.sa=+a.csStop;this.O=[];this.Db=this.jc.bind(this);this.V=this.L=this.U=this.M=this.K=this.Da= -this.R=this.ta=this.kb=this.X=0;this.La=null;Xb(this)}ra(kd,u);m=kd.prototype;m.Ja=function(a,b,c,d){this.F=a;this.G=b;this.C=d;this.La=a.j;for(a=0;a<ld.length;a++)(b=this.I[ld[a]])&&this.F.qa(null,ld[a],b);Xb(this)};m.reset=function(){};m.save=function(){return null};m.restore=function(){return!1}; +this.R=this.ta=this.kb=this.X=0;this.La=null;Xb(this)}ra(kd,u);m=kd.prototype;m.Ja=function(a,b,c,d){this.F=a;this.G=b;this.C=d;this.La=a.j;for(a=0;a<ld.length;a++)(b=this.I[ld[a]])&&this.F.qa("",ld[a],b);Xb(this)};m.reset=function(){};m.save=function(){return null};m.restore=function(){return!1}; m.ya=function(a,b){var c=md(this.F,"autoStart");null!=c?this.flags.ea="true"==c?!0:"false"==c?!1:!!c:null==this.flags.ea&&(this.flags.ea=!this.C&&void 0===this.I.run);if(!b){if(a){nd(this);if(!this.restore(a))return!1;od(this)}else this.reset();this.C?(a=this.C,b=this.flags.ea,a.Ga=!0,a.u("Type ? for help with PDPjs Debugger commands"),pd(a),b||qd(a),a.sa&&(b=a.sa,a.sa=null,rd(a,b,!0))):this.status("No debugger detected");this.flags.ea||this.u("CPU will not be auto-started "+(this.La?"(click Run to start)": "(type 'go' to start)"))}return!0};m.pa=function(a){return a?this.save():!0};m.ea=function(){return this.flags.P?!0:this.flags.ea?(Dc(this),!0):!1};m.Ib=function(){return 0};function od(a){void 0===a.Fa&&(a.Fa=0);void 0===a.na&&(a.na=-1);void 0===a.sa&&(a.sa=-1);a.flags.Ra=0<=a.Fa&&0<a.na;a.flags.Ra&&(a.Ea=0,a.ra=a.Fa-a.V)} function Hc(a,b){if(a.flags.Ra){var c=!1;a.Ea=a.Ea+a.Ib()|0;a.ra-=b;0>=a.ra&&(a.ra+=a.na,c=!0);0<=a.sa&&a.sa<=sd(a)&&(a.na=a.sa=-1,od(a),H(a),c=!0);c&&a.u(sd(a)+" cycles: checksum\x3d"+n(a.Ea))}} @@ -168,8 +168,8 @@ b))?(c.Ma=a.Ma,c.Y=a.Y,null==c.ja&&(c.ja=a.ja),null==c.wa&&(c.wa=a.wa)):c.b=null function Te(a){if(a.G&&(!a.w&&a.j&&(Tc(a.G,a.i,a.j,1)?a.w=!0:a.j=0),!Wb(a))){if(!a.w)t("No RAM allocated");else if(a.b){if(!a.Ma)return;Ue(a,a.Ma,a.ja,a.wa,a.i)?a.status('Loaded image "'+a.B+'"'):a.ha('Error loading image "'+a.B+'"')}a.D=!0;Xb(a)}} Se.prototype.reset=function(){if(this.w&&!this.D){var a=this.G,b=this.i,c=this.j,d=b&16383;for(b>>>=a.i;0<c&&b<a.b.length;){var e=a.b[b],f=c,g=0;g=void 0===g?0:g;d=d||0;void 0===f&&(f=e.size);0>g&&g>=-A&&(g+=D);g=Math.trunc(Math.abs(g))%D;for(var h=d;f--&&h<e.size;h++)e.C(g,d,e.A+d);c-=16384;b++;d=0}this.Ma&&Ue(this,this.Ma,this.ja,this.wa,this.i,!this.C)}this.D=!1}; function Ue(a,b,c,d,e,f){var g=!1;null==c&&(c=e);if(null!=c){for(g=0;g<b.length;g++)Jc(a.G,c+g,b[g]);g=!0}g&&(null==d&&(H(a.v),f=!1),null!=d&&(a=a.v,a.Xa=d,G(a,d),f?a.flags.Z?a.flags.P||Dc(a):a.flags.ea=!0:a.C&&a.flags.Z?H(a)||a.F.flags.reset||(pd(a.C),K(a.F,-1)):!1===f&&H(a),!a.flags.P&&a.La&&a.La.stop()));return g}hb(function(){for(var a=w(document,v,"ram"),b=0;b<a.length;b++){var c=a[b],d=Bb(c);d=new Se(d);Ab(d,c)}}); -function Ve(a){u.call(this,"SerialPort",a,1048576);this.w=a.upperCase;"string"==typeof this.w&&(this.w="true"==this.w);this.j=!0;this.i=[];a=a.binding;if("console"!=a&&a){var b=Eb("Panel",this.id);b&&(b=b.I[a])&&this.qa(null,a,b)}this.b=this.B=null;this.exports={connect:this.Jb,receiveData:this.bb,receiveStatus:this.hc,setConnection:this.kc}}ra(Ve,u);m=Ve.prototype; -m.qa=function(a,b,c){if(null==a||"textarea"==a){var d=this;this.I[b]=c;c.onkeydown=function(a){a=a||window.event;var b=0,c=a.keyCode;8==c?b=a.altKey?ya.vb:ya.Ob:46==c?b=ya.vb:a.ctrlKey&&c>=ya.ub&&c<=ya.Pb&&(b=c-(ya.ub-ya.Lb));b&&(a.preventDefault&&a.preventDefault(),d.bb(b));return!0};c.onkeypress=function(a){a=a||window.event;if(!a.metaKey){var b=a.which||a.keyCode;a.altKey&&b==ya.Nb&&(b=ya.Mb);d.bb(b);a.preventDefault&&a.preventDefault()}return!0};c.onpaste=function(a){a.stopPropagation&&a.stopPropagation(); +function Ve(a){u.call(this,"SerialPort",a,1048576);this.w=a.upperCase;"string"==typeof this.w&&(this.w="true"==this.w);this.j=!0;this.i=[];a=a.binding;if("console"!=a&&a){var b=Eb("Panel",this.id);b&&(b=b.I[a])&&this.qa("",a,b)}this.b=this.B=null;this.exports={connect:this.Jb,receiveData:this.bb,receiveStatus:this.hc,setConnection:this.kc}}ra(Ve,u);m=Ve.prototype; +m.qa=function(a,b,c){if(!a||"textarea"==a){var d=this;this.I[b]=c;c.onkeydown=function(a){a=a||window.event;var b=0,c=a.keyCode;8==c?b=a.altKey?ya.vb:ya.Ob:46==c?b=ya.vb:a.ctrlKey&&c>=ya.ub&&c<=ya.Pb&&(b=c-(ya.ub-ya.Lb));b&&(a.preventDefault&&a.preventDefault(),d.bb(b));return!0};c.onkeypress=function(a){a=a||window.event;if(!a.metaKey){var b=a.which||a.keyCode;a.altKey&&b==ya.Nb&&(b=ya.Mb);d.bb(b);a.preventDefault&&a.preventDefault()}return!0};c.onpaste=function(a){a.stopPropagation&&a.stopPropagation(); a.preventDefault&&a.preventDefault();(a=a.clipboardData||window.clipboardData)&&d.bb(a.getData("Text"))};c.removeAttribute("readonly");return!0}return!1};m.Ja=function(a,b,c,d){this.F=a;this.G=b;this.v=c;this.C=d;Xb(this)}; m.Jb=function(a){if(!this.b){var b=md(this.F,"connection");if(b){var c=b.split("-\x3e");if(2==c.length){var d=Ma(c[0]);if(d!=this.Cb)return;c=Ma(c[1]);if(this.b=Db(c)){var e=this.b.exports;if(e){var f=e.connect;f&&f.call(this.b,this.j);if(this.B=e.receiveData){this.j=a;this.status("Connected "+this.Ya+"."+d+" to "+c);return}}}}this.status("Unable to establish connection: "+b)}}};m.ya=function(a,b){if(!b)if(this.Jb(this.j),!a)this.reset();else if(!this.restore(a))return!1;return!0}; m.pa=function(a){return a?this.save():!0};m.reset=function(){};m.save=function(){var a=new F(this);a.set(0,[]);return a.data()};m.restore=function(){return!0};m.bb=function(a){if("number"==typeof a)this.i.push(a);else if("string"==typeof a)for(var b=0,c,d=0;d<a.length;d++){c=b;b=a.charCodeAt(d);if(10==b){if(13==c)continue;b=13}this.i.push(b)}else this.i=this.i.concat(a);return!0};m.hc=function(){};m.kc=function(a,b){return this.b?!1:(this.b=a,this.B=b,!0)}; diff --git a/versions/pdpjs/1.61.0/pdp10.js.map b/versions/pdpjs/1.61.0/pdp10.js.map index 3fa7e6bae5..ddb52e0f7d 100644 --- a/versions/pdpjs/1.61.0/pdp10.js.map +++ b/versions/pdpjs/1.61.0/pdp10.js.map @@ -1 +1 @@ -{"version":3,"file":"pdp10.js","lineCount":311,"mappings":"A;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAA,CAAA,CCoCAA,GAC4D,UAAxD,EAAsB,MAAO,OAAA,iBAA7B,CACA,MAAA,eADA,CAEA,QAAQ,CAAC,CAAD,CAAS,CAAT,CAAmB,CAAnB,CAA+B,CAOjC,CAAJ,EAAc,KAAA,UAAd,EAAiC,CAAjC,EAA2C,MAAA,UAA3C,GACA,CAAA,CAAO,CAAP,CADA,CACmB,CAAA,MADnB,CAPqC,CDvC3C,CE2CAC,GAb2B,WAAlB,EAAC,MAAO,OAAR,EAAiC,MAAjC,GAa0B,IAb1B,CAa0B,IAb1B,CAEe,WAAlB,EAAC,MAAO,OAAR,EAA2C,IAA3C,EAAiC,MAAjC,CAAmD,MAAnD,CAW6B,IChBd,SAAA,GAAQ,EAAG,CAE9BC,EAAA,CAAqB,QAAQ,EAAG,EAE3BD,GAAA,OAAL,GACEA,EAAA,OADF,CAC6BE,EAD7B,CAJ8B,CAehC,IAAAA,GAAuD,QAAQ,EAAG,CAChE,IAAI,EAAU,CAUd,OAJA,SAAe,CAAC,CAAD,CAAkB,CAC/B,MA9BoBC,gBA8BpB,EAC6B,CAD7B,EACgD,EADhD,EACuD,CAAA,EAFxB,CAP+B,CAAZ,EAoBzB;QAAA,GAAQ,EAAG,CACtCF,EAAA,EACA,KAAI,EAAiBD,EAAA,OAAA,SAChB,EAAL,GACE,CADF,CACmBA,EAAA,OAAA,SADnB,CAEMA,EAAA,OAAA,CAAyB,UAAzB,CAFN,CAK8C,WAA9C,EAAI,MAAO,MAAA,UAAA,CAAgB,CAAhB,CAAX,EACED,EAAA,CACI,KAAA,UADJ,CACqB,CADrB,CACqC,CAC/B,aAAc,CAAA,CADiB,CAE/B,SAAU,CAAA,CAFqB,CAO/B,MAAO,QAAQ,EAAG,CAChB,MAAOK,GAAA,CAAsB,IAAtB,CADS,CAPa,CADrC,CAeFC,GAAA,CAA6B,QAAQ,EAAG,EAxBF,CAkChB,QAAA,GAAQ,CAAC,CAAD,CAAQ,CACtC,IAAI,EAAQ,CACZ,OAAOC,GAAA,CAA0B,QAAQ,EAAG,CAC1C,MAAI,EAAJ,CAAY,CAAA,OAAZ,CACS,CACL,KAAM,CAAA,CADD,CAEL,MAAO,CAAA,CAAM,CAAA,EAAN,CAFF,CADT,CAMS,CAAC,KAAM,CAAA,CAAP,CAPiC,CAArC,CAF+B,CA0BZ,QAAA,GAAQ,CAAC,CAAD,CAAO,CACzCD,EAAA,EAEI,EAAA,CAAW,CAAC,KAAM,CAAP,CAKf,EAAA,CAASL,EAAA,OAAA,SAAT,CAAA,CAA8C,QAAQ,EAAG,CAAE,MAAO,KAAT,CACzD,OAAyC,EATA;AC5F3C,IAAAO,GACmD,UAA/C,EAAuB,MAAO,OAAA,OAA9B,CACA,MAAA,OADA,CAEA,QAAQ,CAAC,CAAD,CAAY,CAEP,QAAA,EAAQ,EAAG,EACtB,CAAA,UAAA,CAAiB,CACjB,OAAO,KAAI,CAJO,CAHxB,CCgByB,EAAA,IAAiC,UAAjC,EAAC,MAAO,OAAA,eAAR,CACrB,EAAA,CAAA,MAAA,eADqB,KAAA,CAErB,IAAA,EAvByC,EAAA,CAAA,CAC3C,IAAI,GAAI,CAAC,GAAG,CAAA,CAAJ,CAAR,CACI,GAAI,EACR,IAAI,CACF,EAAA,UAAA,CAAc,EACd,GAAA,CAAO,EAAA,GAAP,OAAA,CAFE,CAGF,MAAO,CAAP,CAAU,EAGZ,EAAA,CAAO,CAAA,CAToC,CAuBzC,EAAA,CAAA,EAAA,CAAA,QAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,UAAA,CAAA,CAAA,IAAA,CAAA,UAAA,GAAA,CAAA,CAAA,KAAA,KAAA,SAAA,CAAA,CAAA,CAAA,oBAAA,CAAA,CAAA,MAAA,EAAA,CAAA,CAAA,IAFqB,CAAzB,IAAAC,GAAyB,ECSN;QAAA,GAAQ,CAAC,CAAD,CAAY,CAAZ,CAAwB,CACjD,CAAA,UAAA,CAAsBD,EAAA,CAAqB,CAAA,UAArB,CACL,EAAA,UAAA,YAAA,CAAkC,CACnD,IAAIC,EAAJ,CAGuBA,EACrB,CAAe,CAAf,CAA0B,CAA1B,CAJF,KAQE,KAAK,IAAI,CAAT,GAAc,EAAd,CACE,GAAS,WAAT,EAAI,CAAJ,CAIA,GAAI,MAAA,iBAAJ,CAA6B,CAC3B,IAAI,EAAa,MAAA,yBAAA,CAAgC,CAAhC,CAA4C,CAA5C,CACb,EAAJ,EACE,MAAA,eAAA,CAAsB,CAAtB,CAAiC,CAAjC,CAAoC,CAApC,CAHyB,CAA7B,IAOE,EAAA,CAAU,CAAV,CAAA,CAAe,CAAA,CAAW,CAAX,CAKrB,EAAA,GAAA,CAAwB,CAAA,UA5ByB,CCXhC,QAAA,GAAQ,CAAC,CAAD,CAAS,CAAT,CAAqC,CAC9D,GAAK,CAAL,CAAA,CACA,IAAI,EAAMR,EACN,EAAA,CAAQ,CAAA,MAAA,CAAa,GAAb,CACZ,KAAK,IAAI,EAAI,CAAb,CAAgB,CAAhB,CAAoB,CAAA,OAApB,CAAmC,CAAnC,CAAsC,CAAA,EAAtC,CAA2C,CACzC,IAAI,EAAM,CAAA,CAAM,CAAN,CACJ,EAAN,GAAa,EAAb,GAAmB,CAAA,CAAI,CAAJ,CAAnB,CAA8B,EAA9B,CACA,EAAA,CAAM,CAAA,CAAI,CAAJ,CAHmC,CAKvC,CAAA,CAAW,CAAA,CAAM,CAAA,OAAN,CAAqB,CAArB,CACX,EAAA,CAAO,CAAA,CAAI,CAAJ,CACP,EAAA,CAAO,CAAA,CAAS,CAAT,CACP,EAAJ,EAAY,CAAZ,EAA4B,IAA5B,EAAoB,CAApB,EACAD,EAAA,CACI,CADJ,CACS,CADT,CACmB,CAAC,aAAc,CAAA,CAAf,CAAqB,SAAU,CAAA,CAA/B,CAAqC,MAAO,CAA5C,CADnB,CAZA,CAD8D;AC1BhEU,EAAA,CAAiB,YAAjB,CAA+B,QAAQ,CAAC,CAAD,CAAO,CAC5C,MAAI,EAAJ,CAAiB,CAAjB,CAUe,QAAQ,CAAC,CAAD,CAAI,CACzB,CAAA,CAAI,MAAA,CAAO,CAAP,CACJ,IAAI,KAAA,CAAM,CAAN,CAAJ,EAAsB,QAAtB,GAAgB,CAAhB,EAAwC,CAAC,QAAzC,GAAkC,CAAlC,EAA2D,CAA3D,GAAqD,CAArD,CAA8D,MAAO,EACrE,KAAI,EAAI,IAAA,MAAA,CAAW,IAAA,IAAA,CAAS,CAAT,CAAX,CACR,OAAW,EAAJ,CAAA,CAAA,CAAQ,CAAC,CAAT,CAAa,CAJK,CAXiB,CAA9C,CCAAA,GAAA,CAAiB,iBAAjB,CAAoC,QAAQ,CAAC,CAAD,CAAO,CACjD,MAAO,EAAP,EAAe,QADkC,CAAnD,CCAAA,GAAA,CAAiB,WAAjB,CAA8B,QAAQ,CAAC,CAAD,CAAO,CAC3C,MAAI,EAAJ,CAAiB,CAAjB,CAUe,QAAQ,CAAC,CAAD,CAAI,CACzB,MAAO,KAAA,IAAA,CAAS,CAAT,CAAP,CAAqB,IAAA,IADI,CAXgB,CAA7C,CV6NIC;IAAAA,GAAOA,CACDC,GAAQD,CADPA,CACUE,GAASF,CADnBA,CACsBG,GAASH,CAD/BA,CACkCI,GAASJ,CAD3CA,CAC8CK,GAASL,CADvDA,CAC0DM,GAASN,CADnEA,CACsEO,GAASP,CAD/EA,CACkFQ,GAASR,CAD3FA,CAEFS,GAAST,CAFPA,CAEUU,GAASV,CAFnBA,CAEsBW,GAAQX,EAF9BA,CAEkCY,GAAQZ,EAF1CA,CAE8Ca,GAAQb,EAFtDA,CAE0Dc,GAAQd,EAFlEA,CAEsEe,GAAQf,EAF9EA,CAEkFgB,GAAQhB,EAF1FA,CAGFiB,GAAQjB,EAHNA,CAGUkB,GAAQlB,EAHlBA,CAGsBmB,GAAQnB,EAH9BA,CAGkCoB,GAAQpB,EAH1CA,CAG8CqB,GAAQrB,EAHtDA,CAG0DsB,GAAQtB,EAHlEA,CAGsEuB,GAAQvB,EAH9EA,CAGkFwB,GAAQxB,EAH1FA,CAIFyB,GAAQzB,EAJNA,CAIU0B,GAAQ1B,EAJlBA,CAIsB2B,GAAQ3B,EAJ9BA,CAIkC4B,GAAQ5B,EAJ1CA,CAKCA,IAAKA,EALNA,CAKaA,IAAKA,EALlBA,CAKyBA,IAAKA,EAL9BA,CAKqCA,IAAKA,EAL1CA,CAKiDA,EAAKA,EALtDA,CAK6DA,IAAKA,EALlEA,CAKyEA,OAAKA,EAL9EA,CAKqFA,IAAKA,EAL1FA,CAMCA,IAAKA,EANNA,CAMaA,IAAKA,EANlBA,CAMyBA,IAAKA,EAN9BA,CAMqCA,IAAKA,EAN1CA,CAMiDA,IAAKA,EANtDA,CAM6DA,IAAKA,EANlEA,CAMyEA,IAAKA,EAN9EA,CAMqFA,IAAKA,EAN1FA,CAOCA,EAAKA,EAPNA,CAOaA,EAAKA,EAPlBA,CAOyBA,EAAKA,EAP9BA,CAOqCA,EAAKA,EAP1CA,CAOiDA,EAAKA,EAPtDA,CAO6DA,EAAKA,EAPlEA,CAOyEA,EAAKA,EAP9EA,CAOqFA,EAAKA,EAP1FA,CAQCA,EAAKA,EARNA,CAQaA,EAAKA,EARlBA,CAQyBA,IAAKA,EAR9BA,CAQqCA,IAAKA,EAR1CA,CAQiDA,OAAKA,EARtDA,CAQ6DA,OAAKA,EARlEA,CAQyEA,OAAKA,EAR9EA,CAQqFA,IAAKA,EAR1FA,CASCA,IAAKA,EATNA,CASc6B,GAAI7B,EATlBA,CAS0B8B,GAAI9B,EAT9BA,CASsC+B,GAAI/B,EAT1CA,CASkDgC,GAAIhC,EATtDA,CAS8DiC,EAAIjC,EATlEA,CAS0EkC,GAAIlC,EAT9EA,CASsFmC,GAAInC,EAT1FA,CAUEoC,GAAIpC,EAVNA,CAUcqC,GAAIrC,EAVlBA,CAU0BsC,GAAItC,EAV9BA,CAUsCuC,GAAIvC,EAV1CA,CAUkDwC,GAAIxC,EAVtDA,CAU8DyC,GAAIzC,EAVlEA,CAU0E0C,GAAI1C,EAV9EA,CAUsF2C,GAAI3C,EAV1FA,CAWE4C,GAAI5C,EAXNA,CAWc6C,EAAI7C,EAXlBA,CAW0B8C,GAAI9C,EAX9BA,CAWsC+C,GAAI/C,EAX1CA,CAWkDgD,GAAIhD,EAXtDA;AAW8DiD,GAAIjD,EAXlEA,CAW0EkD,GAAIlD,EAX9EA,CAWsFmD,GAAInD,EAX1FA,CAYEoD,GAAIpD,EAZNA,CAYcqD,GAAIrD,EAZlBA,CAY0BsD,GAAItD,EAZ9BA,CAYqCA,IAAKA,EAZ1CA,CAYiDA,KAAKA,EAZtDA,CAY6DA,IAAKA,EAZlEA,CAYyEA,IAAKA,EAZ9EA,CAYqFA,EAAKA,EAZ1FA,CAaCA,IAAKA,EAbNA,CAacuD,GAAIvD,EAblBA,CAa0BwD,GAAIxD,EAb9BA,CAasCyD,GAAIzD,EAb1CA,CAakD0D,EAAG1D,GAbrDA,CAa8D2D,EAAG3D,GAbjEA,CAa0E4D,GAAG5D,GAb7EA,CAasF6D,GAAG7D,GAbzFA,CAcE8D,GAAI9D,GAdNA,CAcc+D,GAAG/D,GAdjBA,CAc0BgE,GAAGhE,GAd7BA,CAcsCiE,EAAGjE,GAdzCA,CAckDkE,GAAGlE,GAdrDA,CAc8DmE,GAAGnE,GAdjEA,CAc0EoE,EAAGpE,GAd7EA,CAcsFqE,GAAGrE,GAdzFA,CAeEsE,EAAItE,GAfNA,CAecuE,EAAGvE,GAfjBA,CAe0BwE,EAAGxE,GAf7BA,CAesCyE,GAAGzE,GAfzCA,CAekD0E,EAAG1E,GAfrDA,CAe8D2E,GAAG3E,GAfjEA,CAe0E4E,GAAG5E,GAf7EA,CAesF6E,GAAG7E,GAfzFA,CAgBE8E,EAAI9E,GAhBNA,CAgBc+E,EAAG/E,GAhBjBA,CAgB0BgF,EAAGhF,GAhB7BA,CAgBqCA,IAAIA,GAhBzCA,CAgBiDA,IAAIA,GAhBrDA,CAgB6DA,IAAIA,GAhBjEA,CAgByEA,IAAIA,GAhB7EA,CAgBoFiF,GAAKjF,GAhBzFA,CA0RPkF;QAAO,GAAQ,CAACT,CAAD,CAAIU,CAAJ,CACf,CAGI,GAAIV,CAAJ,CAAO,CACEU,CAAL,GAAWA,CAAX,CAAkB,EAAlB,CADG,KAGKC,CAHL,CAICC,EAA4B,CAA5BA,CAAWZ,CAAAa,QAAA,CAAU,GAAV,CACXD,EAAJ,GAAaZ,CAAb,CAAiBA,CAAAc,QAAA,CAAU,IAAV,CAAgB,EAAhB,CAAjB,CAEA,KAAAC,EAAKJ,CAALI,CAAgBf,CAAAgB,OAAA,CAAS,CAAT,CACA,IAAhB,EAAIL,CAAJ,EACID,CACA,CADO,CACP,CAAAC,CAAA,CAAW,EAFf,EAIqB,GAJrB,EAISA,CAJT,GAKID,CACA,CADO,EACP,CAAAC,CAAA,CAAW,EANf,CAQII,EAAJ,EAAUJ,CAAV,CACIX,CADJ,CACQA,CAAAiB,OAAA,CAAS,CAAT,CADR,EAIIF,CAiBA,CAjBKJ,CAiBL,CAjBgBX,CAAAiB,OAAA,CAAS,CAAT,CAAY,CAAZ,CAiBhB,CAhBgB,IAAhB,EAAIN,CAAJ,EAAwBC,CAAxB,EAA+C,IAA/C,EAAmCD,CAAnC,EACID,CACA,CADO,CACP,CAAAC,CAAA,CAAW,EAFf,EAIqB,IAAhB,EAAIA,CAAJ,EAAoC,IAApC,EAAwBA,CAAxB,EACDD,CACA,CADO,CACP,CAAAC,CAAA,CAAW,EAFV,EAIgB,IAAhB,EAAIA,CAAJ,EACDD,CACA,CADO,EACP,CAAAC,CAAA,CAAW,EAFV,EAIgB,IAJhB,EAIIA,CAJJ,GAKDD,CACA,CADO,EACP,CAAAC,CAAA,CAAW,EANV,CAQL,CAAII,CAAJ,EAAUJ,CAAV,GAAoBX,CAApB,CAAwBA,CAAAiB,OAAA,CAAS,CAAT,CAAxB,CArBJ,CAuBAF,EAAA,CAAKG,CAAL,CAAgBlB,CAAAmB,MAAA,CAAS,EAAT,CACA,IAAhB,EAAID,CAAJ,EAAmC,GAAnC,EAAuBA,CAAvB,EACIR,CACA,CADO,CACP,CAAAQ,CAAA,CAAW,EAFf,EAIqB,GAAhB,EAAIA,CAAJ,EACDR,CACA,CADO,EACP,CAAAQ,CAAA,CAAW,EAFV,EAIgB,GAAhB,EAAIA,CAAJ,EAAmC,GAAnC,EAAuBA,CAAvB,EACDR,CACA,CADO,EACP,CAAAQ,CAAA,CAAW,EAFV,EAIgB,GAAhB,EAAIA,CAAJ,CACDA,CADC,CACU,KADV,CAGgB,GAAhB,EAAIA,CAAJ,CACDA,CADC,CACU,QADV,CAGgB,GAHhB,EAGIA,CAHJ,GAIDA,CAJC,CAIU,WAJV,CAMDH,EAAJ,EAAUG,CAAV,GAAoBlB,CAApB,CAAwBA,CAAAmB,MAAA,CAAQ,CAAR,CAAY,EAAZ,CAAxB,CAAyCD,CAAzC,CA7DG,KAoECf,CAAGiB,EAAAA,CAAQ,CACH,GAAZ,EAAIV,CAAJ,GACQW,CADR,CACgBrB,CAAAqB,MAAA,CAAQ,qBAAR,CADhB;CAGQrB,CACA,CADIqB,CAAA,CAAM,CAAN,CACJ,CAAAD,CAAA,CAAQ,EAAR,GAAeC,CAAA,CAAM,CAAN,CAAf,EAA2B,EAA3B,EAAiC,GAAjC,CAJR,CAOmBrB,EAAAA,CAAAA,CAAnB,KA/GJ,CA+G0BU,CA/G1B,CA+G0BA,CA/G1B,GAAqB,EAArB,EAAaA,CAAb,CACY,EAAZ,EAAIA,CAAJ,CAAqD,IAArD,GAAuBV,CAAAqB,MAAA,CAAQ,gBAAR,CAAvB,CACY,CAAZ,EAAIX,CAAJ,CAAgD,IAAhD,GAAsBV,CAAAqB,MAAA,CAAQ,YAAR,CAAtB,CACY,CADZ,EACIX,CADJ,EAC+C,IAD/C,GACsBV,CAAAqB,MAAA,CAAQ,WAAR,CAHtB,CAA0D,IAA1D,GAAgCrB,CAAAqB,MAAA,CAAQ,YAAR,CA+G5B,GAA+B,CAACC,KAAA,CAAMnB,CAAN,CAAUM,QAAA,CAAST,CAAT,CAAYU,CAAZ,CAAV,CAAhC,CAA8D,CAMtDU,CAAJ,GAMY,CAEJ,CAFAjB,CAEA,GAFOA,CAEP,EAFYoB,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAEZ,EAAArB,CAAA,CADQ,CAAZ,CAAIiB,CAAJ,CACIjB,CADJ,CACSoB,IAAAC,IAAA,CAAS,CAAT,CAAYJ,CAAZ,CADT,CAGQG,IAAAE,MAAA,CAAWtB,CAAX,CAAeoB,IAAAC,IAAA,CAAS,CAAT,CAAY,CAACJ,CAAb,CAAf,CAVZ,CAaA,KAAAM,EAAQvB,CAnBkD,CA5E3D,CAkGP,MAAOuB,EArGX;AAoHAC,QAAO,GAAM,CAAChC,CAAD,CAAIiC,CAAJ,CAAWC,CAAX,CAAgBC,CAAhB,CAA8BC,CAA9B,CACb,CAD2CA,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAY,CAAZ,CAAAA,CAUvC,KAAI/B,EAAI,EACJsB,MAAA,CAAM3B,CAAN,CAAJ,CACIA,CADJ,CACQ,IADR,CAEgB,IAFhB,EAEWA,CAFX,GASY,CAQR,CARIA,CAQJ,EARkB,EAQlB,CARaA,CAQb,GARqBA,CAQrB,CAR0B,EAQ1B,EAHQ,CAGR,CAHIA,CAGJ,GAFIA,CAEJ,EAFS4B,IAAAC,IAAA,CAASI,CAAT,CAAgBC,CAAhB,CAET,EAAIlC,CAAJ,EAAS4B,IAAAC,IAAA,CAASI,CAAT,CAAgBC,CAAhB,CAAT,GACIA,CADJ,CACUN,IAAAS,KAAA,CAAUT,IAAAU,IAAA,CAAStC,CAAT,CAAV,CAAwB4B,IAAAU,IAAA,CAASL,CAAT,CAAxB,CADV,CAjBJ,CAsBA,KADA,IAAIxC,EAAI2C,CAAJ3C,EAAkB,EACtB,CAAe,CAAf,CAAOyC,CAAA,EAAP,CAAA,CAAkB,CACTzC,CAAL,GACIY,CACA,CADI,GACJ,CADUA,CACV,CAAAZ,CAAA,CAAI2C,CAFR,CAIA,IAAS,IAAT,EAAIpC,CAAJ,CACIK,CAAA,CAAI,GAAJ,CAAUA,CADd,KAEO,CACH,IAAIf,EAAIU,CAAJV,CAAQ2C,CACZ3C,EAAA,EAAW,CAAL,EAAAA,CAAA,EAAe,CAAf,EAAUA,CAAV,CAAkB,EAAlB,CAAyB,EAC/Be,EAAA,CAAIkC,MAAAC,aAAA,CAAoBlD,CAApB,CAAJ,CAA6Be,CAC7BL,EAAA,CAAI4B,IAAAE,MAAA,CAAW9B,CAAX,CAAeiC,CAAf,CAJD,CAMPxC,CAAA,EAbc,CAelB,OAhDyB,IAAA,EAAA0C,GAAAA,CAAAA,CAAU,EAAVA,CAAAA,CAgDzB,EAAiB9B,CA/CrB,CAgHAoC,QAAO,GAAK,CAACzC,CAAD,CAAIkC,CAAJ,CAASQ,CAAT,CACZ,CACSR,CAAL,CAUiB,EAVjB,CAUWA,CAVX,GAUqBA,CAVrB,CAU2B,EAV3B,GAEQ1B,CAEA,CAFIoB,IAAAe,IAAA,CAAS3C,CAAT,CAEJ,CAAAkC,CAAA,CADK,MAAT,EAAI1B,CAAJ,CACU,CADV,CAEgB,QAAT,EAAIA,CAAJ,CACG,CADH,CAGG,EARd,CAWA,OAAOoC,GAAA,CAAW5C,CAAX,CAAc,CAAd,CAAiBkC,CAAjB,CAAsBQ,CAAA,CAAS,IAAT,CAAgB,EAAtC,CAZX;AA4BAG,QAAO,GAAK,CAAC7C,CAAD,CAAIkC,CAAJ,CACZ,CACSA,CAAL,CAQiB,EARjB,CAQWA,CARX,GAQqBA,CARrB,CAQ2B,EAR3B,EAIQA,CAJR,CAGa,KAAT,EADQN,IAAAe,IAAAnC,CAASR,CAATQ,CACR,CACU,CADV,CAGU,EAGd,OAAOoC,GAAA,CAAW5C,CAAX,CAAc,EAAd,CAAkBkC,CAAlB,CAVX,CAmCAY,QAAO,EAAK,CAAC9C,CAAD,CAAIkC,CAAJ,CAASQ,CAAT,CACZ,CACSR,CAAL,CAUiB,CAVjB,CAUWA,CAVX,GAUoBA,CAVpB,CAU0B,CAV1B,GAEQ1B,CAEA,CAFIoB,IAAAe,IAAA,CAAS3C,CAAT,CAEJ,CAAAkC,CAAA,CADK,KAAT,EAAI1B,CAAJ,CACU,CADV,CAEgB,UAAT,EAAIA,CAAJ,CACG,CADH,CAGG,CARd,CAWA,OAAOoC,GAAA,CAAW5C,CAAX,CAAc,EAAd,CAAkBkC,CAAlB,CAAuBQ,CAAA,CAAS,IAAT,CAAgB,EAAvC,CAZX,CAkEAK,QAAO,GAAW,CAACC,CAAD,CAClB,CACI,IAAIC,EAAYD,CAAhB,CAEIrD,EAAIqD,CAAAE,YAAA,CAAsB,GAAtB,CACC,EAAT,EAAIvD,CAAJ,GAAYsD,CAAZ,CAAwBD,CAAA1B,OAAA,CAAiB3B,CAAjB,CAAqB,CAArB,CAAxB,CAKAA,EAAA,CAAIsD,CAAA/B,QAAA,CAAkB,MAAlB,CACI,EAAR,CAAIvB,CAAJ,GAAWsD,CAAX,CAAuBA,CAAA3B,OAAA,CAAiB,CAAjB,CAAoB3B,CAApB,CAAvB,CAQA,OAAOsD,EAlBX,CA+BAE,QAAO,GAAY,CAACH,CAAD,CACnB,CACI,IAAII,EAAa,EAAjB,CACIzD,EAAIqD,CAAAE,YAAA,CAAsB,GAAtB,CACC,EAAT,EAAIvD,CAAJ,GACIyD,CADJ,CACiBJ,CAAA1B,OAAA,CAAiB3B,CAAjB,CAAqB,CAArB,CAAA0D,YAAA,EADjB,CAGA,OAAOD,EANX,CAgBAE,QAAO,GAAQ,CAACjD,CAAD,CAAIkD,CAAJ,CACf,CACI,MAA0D,EAA1D,GAAOlD,CAAAa,QAAA,CAAUqC,CAAV,CAAmBlD,CAAAmD,OAAnB,CAA8BD,CAAAC,OAA9B,CADX;AAUAC,QAAO,GAAU,CAACC,CAAD,CACjB,CACI,MAAOA,EAAAvC,QAAA,CAAc,UAAd,CAA0B,QAAQ,CAACpB,CAAD,CACzC,CACI,MAAO4D,GAAA,CAAkB5D,CAAlB,CADX,CADO,CADX,CA+FA6D,QAAO,GAAG,CAACvD,CAAD,CAAI6B,CAAJ,CACV,CAEI,MAA8CV,CAACnB,CAADmB,CAD/BqC,0CAC+BrC,OAAA,CAAqB,CAArB,CAAwBU,CAAxB,CAFlD,CA+IA4B,QAAO,GAAI,CAACzD,CAAD,CACX,CACI,MAAIkC,OAAAwB,UAAAD,KAAJ,CACWzD,CAAAyD,KAAA,EADX,CAGOzD,CAAAc,QAAA,CAAU,YAAV,CAAwB,EAAxB,CAJX,CA+BJ,IAAAwC,GAAoB,CAChB,OAAK,UADW,CAEhB,OAAK,SAFW,CAGhB,OAAK,SAHW,CAIhB,IAAK,WAJW,CAKhB,IAAK,WALW,CAwIhBK,SAAO,GAAY,CAAC7E,CAAD,CAAIqB,CAAJ,CAAOyD,CAAP,CACnB,CACI,IAAIC,EAAO,CAAX,CACIC,EAAQhF,CAAAqE,OADZ,CAEIY,EAAQ,CAOZ,KANkBC,IAAAA,EAMlB,GANIJ,CAMJ,GALIA,CAKJ,CALgBA,QAAQ,CAAC9E,CAAD,CAAIC,CAAJ,CACpB,CACI,MAAOD,EAAA,CAAIC,CAAJ,CAAQ,CAAR,CAAYD,CAAA,CAAIC,CAAJ,CAAS,EAAT,CAAa,CADpC,CAIJ,EAAO8E,CAAP,CAAcC,CAAd,CAAA,CAAqB,CACjB,IAAIG,EAAUJ,CAAVI,CAAiBH,CAAjBG,EAA2B,CAE/B,KAAAC,EAAgBN,CAAA,CAAUzD,CAAV,CAAarB,CAAA,CAAEmF,CAAF,CAAb,CACI,EAApB,CAAIC,CAAJ,CACIL,CADJ,CACWI,CADX,CACoB,CADpB,EAGIH,CACA,CADQG,CACR,CAAAF,CAAA,CAAQ,CAACG,CAJb,CAJiB,CAWrB,MAAOH,EAAA,CAAQF,CAAR,CAAe,CAACA,CArB3B;AA4GAM,QAAO,GAAU,EACjB,CAD2BC,IAAAA,CAAAA,CAEnBC,EAAQ,EACPD,EAAL,GAAWA,CAAX,CAAkB,IAAIE,IAAtB,CAIA,KAHA,IAAIC,EAAQH,CAAAI,SAAA,EAAZ,CACIC,EAAOL,CAAAM,QAAA,EADX,CAEIC,EAASP,CAAAQ,SAAA,EAATD,CAA2B,CAF/B,CAGSrF,EAAI,CAAb,CAAoB6D,EAApB,CAAgB7D,CAAhB,CAAoCA,CAAA,EAApC,CAAyC,CACrC,IAAIyB,CACJ,QAASA,CAAT,CApEkB8D,aAoEJ7D,OAAA,CAAe1B,CAAf,CAAd,EACA,KAAK,GAAL,CACI+E,CAAA,EAAkB,EAAR,CAAAE,CAAA,CAAa,IAAb,CAAoB,IAC9B,MACJ,MAAK,GAAL,CACIF,CAAA,EAASlD,CAAC,GAADA,CAAOsD,CAAPtD,OAAA,CAAoB,EAApB,CACT,MACJ,MAAK,GAAL,CACIkD,CAAA,EAASS,EAAA,CAAWV,CAAAW,OAAA,EAAX,CAAA9D,OAAA,CAAiC,CAAjC,CAAoC,CAApC,CACT,MACJ,MAAK,GAAL,CACIoD,CAAA,EAASW,EAAA,CAAaL,CAAb,CAAsB,CAAtB,CACT,MACJ,MAAK,GAAL,CACIN,CAAA,EAAWE,CAAD,CAAuB,EAAR,CAAAA,CAAA,CAAaA,CAAb,CAAqB,EAArB,CAA0BA,CAAzC,CAAS,EACnB,MACJ,MAAK,GAAL,CACIF,CAAA,EAASE,CACT,MACJ,MAAK,GAAL,CACIF,CAAA,EAASlD,CAAC,GAADA,CAAOoD,CAAPpD,OAAA,CAAqB,EAArB,CACT,MACJ,MAAK,GAAL,CACIkD,CAAA,EAASlD,CAAC,GAADA,CAAOiD,CAAAa,WAAA,EAAP9D,OAAA,CAAiC,EAAjC,CACT,MACJ,MAAK,GAAL,CACIkD,CAAA,EAASI,CACT,MACJ,MAAK,GAAL,CACIJ,CAAA,EAASS,EAAA,CAAWV,CAAAW,OAAA,EAAX,CACT,MACJ,MAAK,GAAL,CACIV,CAAA,EAASlD,CAAC,GAADA,CAAOwD,CAAPxD,OAAA,CAAsB,EAAtB,CACT;KACJ,MAAK,GAAL,CACIkD,CAAA,EAASW,EAAA,CAAaL,CAAb,CAAsB,CAAtB,CAAA1D,OAAA,CAAgC,CAAhC,CAAmC,CAAnC,CACT,MACJ,MAAK,GAAL,CACIoD,CAAA,EAASM,CACT,MACJ,MAAK,GAAL,CACIN,CAAA,EAASlD,CAAC,GAADA,CAAOiD,CAAAc,WAAA,EAAP/D,OAAA,CAAiC,EAAjC,CACT,MACJ,MAAK,GAAL,CACIkD,CAAA,EAASlD,CAAC,EAADA,CAAMiD,CAAAe,YAAA,EAANhE,OAAA,CAAiC,EAAjC,CACT,MACJ,MAAK,GAAL,CACIkD,CAAA,EAASD,CAAAe,YAAA,EACT,MACJ,SACId,CAAA,EAAStD,CAlDb,CAFqC,CAwDzC,MAAOsD,EA9DX,CAgKJ,IAAAS,GAAa,0DAAA,MAAA,CAAA,GAAA,CAAb,CACAE,GAAe,uFAAA,MAAA,CAAA,GAAA,CAuKXI;QAAO,GAAW,CAACC,CAAD,CAAOC,CAAP,CAAsBC,CAAtB,CAAsCC,CAAtC,CAClB,CAoCmBC,QAAA,EAAQ,EAAG,CACtB,GAA2B,CAA3B,GAAIC,CAAAC,WAAJ,CAEI,MAAO,KA0BX,IAAI,CACAC,CAAA,CAAWC,CAAA,CAAcH,CAAAI,SAAd,CAAiCJ,CAAAK,aAD5C,CAEF,MAAMC,CAAN,CAAW,EAOb,GAAgB,IAAhB,EAAIJ,CAAJ,EAA2C,GAA3C,EAAyBF,CAAAO,OAAzB,GAAmDP,CAAAO,OAAnD,EAAqE9C,CAAAyC,CAAAzC,OAArE,EAAiH,OAAjH,GA0PI+C,MAAA,CAAQA,MAAAC,SAAAC,SAAR,CAAmC,OA1PvC,GAIIC,CAAA,CAAaX,CAAAO,OAAb,EAAgC,EAIhCT,EAAJ,EAAUA,CAAA,CAAKH,CAAL,CAAWO,CAAX,CAAqBS,CAArB,CACV,OAAO,CAACT,CAAD,CAAWS,CAAX,CA/Ce,CArCLf,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAO,MAAP,CAAAA,CAAeC,EAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAS,CAAA,CAAT,CAAAA,CACxC,KACQc,EAAa,CADrB,CACwBT,EAAW,IADnC,CACyCE,EAAW,IAEhD,IAAwB,QAAxB,EAAI,MAAOQ,UAAX,GAAqCV,CAArC,CAAgDU,SAAA,CAAUjB,CAAV,CAAhD,EAEI,MADIG,EACG,EADGA,CAAA,CAAKH,CAAL,CAAWO,CAAX,CAAqBS,CAArB,CACH,CAAA,CAACT,CAAD,CAAWS,CAAX,CAEN,IAAId,CAAJ,EAAkC,UAAlC,EAAc,MAAOe,UAArB,CAKD,MAJAA,UAAA,CAAUjB,CAAV,CAAgB,QAAQ,CAACO,CAAD,CAAWS,CAAX,CACxB,CACQb,CAAJ,EAAUA,CAAA,CAAKH,CAAL,CAAWO,CAAX,CAAqBS,CAArB,CADd,CADA,CAIOP,CAAAA,CAQPT,EAAA,CAAOA,CAAAvE,QAAA,CAAa,iCAAb;AAAgD,+BAAhD,CAaX,KAAI4E,EAAWQ,MAAAK,eAAA,CAAuB,IAAIL,MAAAK,eAA3B,CAAqD,IAAIL,MAAAM,cAAJ,CAAyB,mBAAzB,CAApE,CACIX,EAAe,CAAA,CADnB,CAC0BY,EAAyC,QAAzCA,GAAS,MAAOf,EAAAgB,aAoDtCnB,EAAJ,GACIG,CAAAiB,mBADJ,CACiClB,CADjC,CAMA,IAAIH,CAAJ,EAA2B,QAA3B,EAAY,MAAOA,EAAnB,CAAqC,CAC7BsB,CAAAA,CAAQ,EACZ,KAAK/G,IAAIA,CAAT,GAAcyF,EAAd,CACSA,CAAAuB,eAAA,CAAoBhH,CAApB,CAAL,GACI+G,CACJ,GADWA,CACX,EADoB,MACpB,EAAAA,CAAA,EAAS/G,CAAT,CAAa,MAAb,CAAmBiH,kBAAA,CAAmBxB,CAAA,CAAKzF,CAAL,CAAnB,CAFnB,CAIJ+G,EAAA,CAAQA,CAAA9F,QAAA,CAAc,MAAd,CAAsB,GAAtB,CAER4E,EAAAqB,KAAA,CAAa,MAAb,CAAqB1B,CAArB,CAA2BE,CAA3B,CACAG,EAAAsB,iBAAA,CAAyB,cAAzB,CAAyC,mCAAzC,CACAtB,EAAAuB,KAAA,CAAaL,CAAb,CAXiC,CAArC,IAcIlB,EAAAqB,KAAA,CAAa,KAAb,CAAoB1B,CAApB,CAA0BE,CAA1B,CASA,CARY,aAQZ,EARID,CAQJ,GAPQmB,CAAJ,EACIZ,CACA,CADe,CAAA,CACf,CAAAH,CAAAgB,aAAA;AAAuBpB,CAF3B,EAIII,CAAAwB,iBAAA,CAAyB,uCAAzB,CAGR,EAAAxB,CAAAuB,KAAA,EAGC1B,EAAL,GACIG,CAAAC,WACA,CADqB,CACrB,CAAAG,CAAA,CAAWL,CAAA,EAFf,CAIA,OAAOK,EA1HX;AAqJAqB,QAAO,GAAmB,CAAC9B,CAAD,CAAO+B,CAAP,CAC1B,CACI,IAAI9H,CAAJ,CACIsG,EAAW,CACXyB,GAAQ,IADG,CAEXC,EAAU,IAFC,CAGXC,GAAU,IAHC,CAIXC,GAAU,IAJC,CAOf,IAAuB,GAAvB,EAAIJ,CAAApG,OAAA,CAAa,CAAb,CAAJ,EAAiD,GAAjD,EAA8BoG,CAAApG,OAAA,CAAa,CAAb,CAA9B,CACI,GAAI,CAAA,IACIlC,CADJ,CACO2I,CAEP,IAA0B,MAA1B,EAAIL,CAAAnG,OAAA,CAAa,CAAb,CAAJ,CAOI,KAAUyG,MAAJ,CAAUN,CAAV,CAAN,CAuBA,IAAAO,EADsB,CAA1B,CAAIP,CAAAvG,QAAA,CAAc,IAAd,CAAJ,EAAqD,CAArD,CAA+BuG,CAAAvG,QAAA,CAAc,IAAd,CAA/B,EAAgF,IAAhF,EAA0DuG,CAAAnG,OAAA,CAAa,CAAb,CAAgB,CAAhB,CAA1D,CACW2G,IAAAC,MAAA,CAAWT,CAAAtG,QAAA,CAAc,aAAd,CAA6B,OAA7B,CAAAA,QAAA,CAA8C,cAA9C,CAA8D,EAA9D,CAAX,CADX,CAGWgH,IAAA,CAAK,GAAL,CAAWV,CAAX,CAAmB,GAAnB,CAGXxB,EAAA2B,GAAA,CAAoBI,CAAA,KACpB/B,EAAA4B,GAAA,CAAoBG,CAAA,KAEpB,IAAI7I,CAAJ,CAAQ6I,CAAA,MAAR,CACI/B,CAAAyB,GAAA,CAAkBvI,CADtB,KAGK,IAAIA,CAAJ,CAAQ6I,CAAA,MAAR,CAKD,IADA/B,CAAAyB,GACY,CADUU,KAAJ,CAAqB,CAArB,CAAUjJ,CAAAqE,OAAV,CACN,CAAAsE,CAAA,CAAPnI,CAAO,CAAH,CAAT,CAAoBA,CAApB,CAAwBR,CAAAqE,OAAxB,CAAkC7D,CAAA,EAAlC,CACIsG,CAAAyB,GAAA,CAAgBI,CAAA,EAAhB,CACA,CADwB3I,CAAA,CAAEQ,CAAF,CACxB,CAD+B,GAC/B,CAAAsG,CAAAyB,GAAA,CAAgBI,CAAA,EAAhB,CAAA,CAAyB3I,CAAA,CAAEQ,CAAF,CAAzB,EAAiC,CAAjC,CAAsC,GAPzC,KAWA,IAAIR,CAAJ,CAAQ6I,CAAA,MAAR,CAKD,IADA/B,CAAAyB,GACY,CADUU,KAAJ,CAAqB,CAArB,CAAUjJ,CAAAqE,OAAV,CACN,CAAAsE,CAAA,CAAPnI,CAAO,CAAH,CAAT,CAAoBA,CAApB;AAAwBR,CAAAqE,OAAxB,CAAkC7D,CAAA,EAAlC,CACIsG,CAAAyB,GAAA,CAAgBI,CAAA,EAAhB,CAGA,CAHwB3I,CAAA,CAAEQ,CAAF,CAGxB,CAH+B,GAG/B,CAFAsG,CAAAyB,GAAA,CAAgBI,CAAA,EAAhB,CAEA,CAFyB3I,CAAA,CAAEQ,CAAF,CAEzB,EAFiC,CAEjC,CAFsC,GAEtC,CADAsG,CAAAyB,GAAA,CAAgBI,CAAA,EAAhB,CACA,CADyB3I,CAAA,CAAEQ,CAAF,CACzB,EADiC,EACjC,CADuC,GACvC,CAAAsG,CAAAyB,GAAA,CAAgBI,CAAA,EAAhB,CAAA,CAAyB3I,CAAA,CAAEQ,CAAF,CAAzB,EAAiC,EAAjC,CAAuC,GAT1C,KAYA,CAAIR,CAAJ,CAAQ6I,CAAA,KAAR,EACD/B,CAAAoC,GADC,CACgBlJ,CADhB,CAID8G,CAAAyB,GAJC,CAIiBM,CAGlB/B,EAAAyB,GAAJ,GACSzB,CAAAyB,GAAAlE,OAAL,CAImC,CAJnC,EAISyC,CAAAyB,GAAAlE,OAJT,GAm/BZ8E,CAAA,CA9+BgCrC,CAAAyB,GAAArH,CAAgB,CAAhBA,CA8+BhC,CA7+BgB,CAAA4F,CAAA,CAAW,IANf,GAm/BZqC,CAAA,CAl/BgC,kBAk/BhC,CAl/BqD5C,CAk/BrD,CAj/BgB,CAAAO,CAAA,CAAW,IAFf,CADJ,CAUAA,EAAA0B,EAAA,CAAoBK,CAAA,QApFpB,CAsFF,MAAOzI,CAAP,CAAU,CAw+BhB+I,CAAA,CAv+BwB,uBAu+BxB,CAv+BkD5C,CAu+BlD,CAv+ByD,KAu+BzD,CAv+BiEnG,CAAAgJ,QAu+BjE,CAt+BQ,CAAAtC,CAAA,CAAW,IAFH,CAvFhB,IA4FK,CAIGuC,CAAAA,CAAK,EAELC,EAAAA,CADWhB,CAAAtG,QAAA,CAAc,MAAd,CAAsB,GAAtB,CAAAA,QAAAuH,CAAmC,KAAnCA,CAA0C,EAA1CA,CACCC,MAAA,CAAe,GAAf,CAChB,KAAKhJ,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB8I,CAAAjF,OAAhB,CAAkC7D,CAAA,EAAlC,CAAuC,CAC/BK,CAAAA,CAAIc,QAAA,CAAS2H,CAAA,CAAU9I,CAAV,CAAT,CAAuB,EAAvB,CACR,IAAIgC,KAAA,CAAM3B,CAAN,CAAJ,CAAc,CA09BtBsI,CAAA,CAz9B4B,uBAy9B5B,CAz9BsD5C,CAy9BtD,CAz9B6D,uBAy9B7D,CAz9BuF+C,CAAA,CAAU9I,CAAV,CAy9BvF,CAz9BsG,GAy9BtG,CAx9BY,MAFU,CAId6I,CAAAI,KAAA,CAAQ5I,CAAR,CAAY,GAAZ,CANmC,CAQnCL,CAAJ,EAAS8I,CAAAjF,OAAT;CAA2ByC,CAAAyB,GAA3B,CAA6Cc,CAA7C,CAfC,CAiBL,MAAOvC,EAtHX,CAwJA4C,QAAO,GAAO,EACd,CACI,MAAQ,SAAR,EAAqBtC,MAAA,CAAQA,MAAAC,SAAAsC,KAAR,CAxhEdC,cAwhEP,CADJ,CAyCAC,QAAO,GAAe,EACtB,CACI,GAAyB,IAAzB,EAAIC,EAAJ,CAA+B,CAC3B,IAAIzJ,EAAI,CAAA,CACR,IAAI+G,MAAJ,CACI,GAAI,CACAA,MAAA2C,aAAAC,QAAA,CAgiBIC,mBAhiBJ,CAgiBIA,mBAhiBJ,CAEA,CADA5J,CACA,CA8hBI4J,mBA9hBJ,EADK7C,MAAA2C,aAAAG,QAAA,CA+hBDD,mBA/hBC,CACL,CAAA7C,MAAA2C,aAAAI,WAAA,CA8hBIF,mBA9hBJ,CAHA,CAIF,MAAO7J,CAAP,CAAU,CAERC,CAAA,CAAI,CAAA,CAFI,CAKhByJ,EAAA,CAAoBzJ,CAZO,CAc/B,MAAOyJ,GAfX,CAoCAM,QAAO,GAAmB,CAACC,CAAD,CAC1B,CAEI,GAAIjD,MAAJ,CACI,GAAI,CACA,IAAAkD,EAASlD,MAAA2C,aAAAG,QAAA,CAA4BG,CAA5B,CADT,CAEF,MAAOjK,CAAP,CAAU,EAIhB,MAAOkK,EATX;AAmBAC,QAAO,GAAmB,CAACF,CAAD,CAAOC,CAAP,CAC1B,CACI,GAAI,CAEA,MADAlD,OAAA2C,aAAAC,QAAA,CAA4BK,CAA5B,CAAkCC,CAAlC,CACO,CAAA,CAAA,CAFP,CAGF,MAAOlK,CAAP,CAAU,EAGZ,MAAO,CAAA,CAPX,CA6EAoK,QAAO,GAAW,CAACtJ,CAAD,CAClB,CACI,GAAIkG,MAAJ,CAAY,CACR,IAAIqD,EApJArD,MAAA,CAAQA,MAAAsD,UAAAD,UAAR,CAAqC,EA8JzC,OAAY,KAAZ,EAAOvJ,CAAP,EAAqB,CAAC,CAACuJ,CAAAlI,MAAA,CAAgB,oBAAhB,CAAvB,EAAgE,CAAC,CAACkI,CAAAlI,MAAA,CAAgB,aAAhB,CAAlE,EAAyG,MAAzG,EAAoGrB,CAApG,EAAmH,CAAC,CAACuJ,CAAAlI,MAAA,CAAgB,gBAAhB,CAArH,EAAmL,CAAnL,EAA2JkI,CAAA1I,QAAA,CAAkBb,CAAlB,CAXnJ,CAaZ,MAAO,CAAA,CAdX;AAwFAyJ,QAAO,GAAU,CAACC,CAAD,CACjB,CACI,GAAKC,CAAAA,EAAL,CAAA,CAYiBC,IAAAA,CAAAA,CAEbC,EAAS,EACb,IAAI3D,MAAJ,CAAY,CACH0D,CAAL,GAKIA,CALJ,CAKa1D,MAAAC,SAAA2D,OAAA7I,OAAA,CAA8B,CAA9B,CALb,CAeA,KARA,IAAII,CAAJ,CACI0I,EAAK,KADT,CAEID,EAAS,oBAMb,CAAQzI,CAAR,CAAgByI,CAAAE,KAAA,CAAYJ,CAAZ,CAAhB,CAAA,CACIC,CAAA,CAJOI,kBAAA,CAIO5I,CAAArB,CAAM,CAANA,CAJYc,QAAA,CAAUiJ,CAAV,CAAc,GAAd,CAAnB,CAIP,CAAA,CAJOE,kBAAA,CAI2B5I,CAAArB,CAAM,CAANA,CAJRc,QAAA,CAAUiJ,CAAV,CAAc,GAAd,CAAnB,CAbH,CAoBZ,EAAA,CAAOF,CAnCP,CAGA,MAAOF,GAAA,CAAaD,CAAb,CAAP,EAA8BC,EAAA,CAAaD,CAAA1G,YAAA,EAAb,CAJlC,CA2FAkH,QAAO,GAAa,CAACvK,CAAD,CAAIwK,CAAJ,CAAcC,CAAd,CACpB,CACoBC,QAASC,EAAa,EACtC,CACI,EAAA3K,CACS,EAAT,EAAIA,CAAJ,GACSwK,CAAA,EADT,GACqBxK,CADrB,CACyB,CADzB,EAGQ,EAAR,CAAIA,CAAJ,CACI4K,UAAA,CAAWF,CAAX,CAAiC,CAAjC,CADJ,CAIAD,CAAA,EATJ,CAWAC,CAAA,EAbJ;AA2BAG,QAAO,GAAa,CAACtL,CAAD,CAAuBuL,CAAvB,CACpB,CAGmBN,QAASO,EAAa,EACrC,CACQD,CAAA,CAo/hBKE,GAp/hBL,GAAGC,CAAH,CAAJ,GACIC,CACA,CADQN,UAAA,CAAWJ,CAAX,CAAqBS,CAArB,CACR,CAAAA,CAAA,CAk/hBKD,GAp/hBT,CADJ,CAJJ,IACQC,EAAK,CADb,CACgBC,EAAQ,IADxB,CAC8BC,EAAqB,CAAA,CAS/C5L,EAAA6L,YAAA,CAAgBC,QAAQ,EACxB,CAESF,CAAL,EACSD,CADT,GAEQD,CACA,CAy+hBJK,GAz+hBI,CAAAd,CAAA,EAHR,CAFJ,CASAjL,EAAAgM,aAAA,CAAiBC,QAAQ,EACzB,CAESN,CAAL,GACID,CACA,CAg+hBAK,GAh+hBA,CAAAd,CAAA,EAFJ,CAFJ,CAOAjL,EAAAkM,UAAA,CAAclM,CAAAmM,WAAd,CAA6BC,QAAQ,EACrC,CAEQT,CAAJ,GACIU,YAAA,CAAaV,CAAb,CACA,CAAAA,CAAA,CAAQ,IAFZ,CAFJ,CAOA3L,EAAAsM,WAAA,CAAetM,CAAAuM,cAAf,CAAiCC,QAAQ,EACzC,CAEQb,CAAJ,GACIU,YAAA,CAAaV,CAAb,CACA,CAAAA,CAAA,CAAQ,IAFZ,CASAC,EAAA,CAAqB,CAAA,CAXzB,CArCJ,CAwEAa,QAAO,GAAW,CAACC,CAAD,CAAQnB,CAAR,CAClB,CACI,GAAIvE,MAAJ,CAAY,CACR,IAAI2F,EAAS3F,MAAA,CAAO0F,CAAP,CAET1F,OAAA,CAAO0F,CAAP,CAAA,CADkB,UAAtB,GAAI,MAAOC,EAAX,CACoBpB,CADpB,CAOoB,QAAsB,EACtC,CACQoB,CAAJ,EAAYA,CAAA,EACZpB,EAAA,EAFJ,CAVI,CADhB,CA0BAqB,QAAO,GAAM,CAACrB,CAAD,CACb,CACIsB,EAAA,KAAAxD,KAAA,CAAoCkC,CAApC,CADJ;AAiCAuB,QAAO,GAAW,CAACC,CAAD,CAClB,CACI,GAAIC,EAAJ,CACI,GAAI,CACA,IAAK,IAAI5M,EAAI,CAAb,CAAgBA,CAAhB,CAAoB2M,CAAA9I,OAApB,CAAgC7D,CAAA,EAAhC,CACI2M,CAAA,CAAI3M,CAAJ,CAAA,EAFJ,CAIF,MAAOJ,CAAP,CAAU,CAsYC+I,CAAA,CAAuC,EAAvC,EArYE,gCAqYF,CArYqC/I,CAAAgJ,QAqYrC,CArYiD,oFAqYjD,EAtYD,CANpB,CAiBAiE,QAAO,GAAgB,CAACC,CAAD,CACvB,CACQ,CAACF,EAAL,EAA+BE,CAA/B,EACIF,EAEA,CAFyB,CAAA,CAEzB,CADIG,EACJ,EADqBC,EAAA,CAAkB,MAAlB,CACrB,CAAIC,EAAJ,EAAqBD,EAAA,CAAkB,MAAlB,CAHzB,EAMAJ,EANA,CAMyBE,CAP7B,CAiBAI,QAAO,GAAa,CAACC,CAAD,CACpB,CACQV,EAAA,CAAuBU,CAAvB,CAAJ,EACIC,EAAA,CAAgBX,EAAA,CAAuBU,CAAvB,CAAhB,CAFR,CAOJ,IAAA9C,GAAe,IAAf,CAEAoC,GAAyB,CACrB,KAAQ,EADa,CAErB,KAAQ,EAFa,CAGrB,KAAQ,EAHa,CAFzB,CAUAM,GAAkB,CAAA,CAVlB,CAWAE,GAAkB,CAAA,CAXlB,CAYAL,GAAyB,CAAA,CAZzB,CAqBAtD,GAAoB,IASpB+D,GAAA,CAAgB,QAAhB,CAA0BC,QAAmB,EAAG,CAC5CP,EAAA,CAAkB,CAAA,CAClBK,GAAA,CAAgBX,EAAA,KAAhB,CAF4C,CAAhD,CAKAY,GAAA,CAAgB,YAAhB,CAA8BE,QAAmB,EAAG,CAChDN,EAAA,CAAkB,CAAA,CAClBG,GAAA,CAAgBX,EAAA,KAAhB,CAFgD,CAApD,CAKAY;EAAA,CAAgBG,EAAA,CAAgB,KAAhB,CAAA,CAAwB,YAAxB,CAAwCA,EAAA,CAAgB,OAAhB,CAAA,CAA0B,UAA1B,CAAuC,gBAA/F,CAAkHC,QAAqB,EAAG,CACtIL,EAAA,CAAgBX,EAAA,KAAhB,CADsI,CAA1I,CA8EIiB,SApBEC,EAoBS,CAAC3H,CAAD,CAAO4H,CAAP,CAAcC,CAAd,CACX,CACI,IAAA7H,KAAA,CAAYA,CAEP4H,EAAL,GAAYA,CAAZ,CAAoB,CAAC,GAAM,EAAP,CAAW,KAAQ,EAAnB,CAApB,CAEA,KAAAE,GAAA,CAAUF,CAAA,GAAV,EAAyB,EACzB,KAAAG,KAAA,CAAYH,CAAA,KACZ,KAAAI,GAAA,CAAeJ,CAAA,QACf,KAAAA,GAAA,CAAaA,CAWE,KAAA,QAAf,CAAiC,EACjC,KAAAK,EAAA,CAAgB,IAAA,SAAhB,CAAmC,EAE/BjO,EAAAA,CAAI,IAAA8N,GAAAvM,QAAA,CAAgB,GAAhB,CACA,EAAR,CAAIvB,CAAJ,CACI,IAAAkO,GADJ,CACuB,IAAAJ,GADvB,EAGI,IAAAK,GACA,CADiB,IAAAL,GAAAnM,OAAA,CAAe,CAAf,CAAkB3B,CAAlB,CACjB,CAAA,IAAAkO,GAAA,CAAmB,IAAAJ,GAAAnM,OAAA,CAAe3B,CAAf,CAAmB,CAAnB,CAJvB,CAWA,KAAAoO,MAAA,CAAa,CACTC,MAAY,CAAA,CADH,CAETC,GAAY,CAAA,CAFH,CAGTC,GAAY,CAAA,CAHH,CAITC,GAAY,CAAA,CAJH,CAKTC,EAAY,CAAA,CALH,CAMTC,GAAY,CAAA,CANH,CAOTC,MAAY,CAAA,CAPH,CAUb,KAAAC,GAAA,CAAe,IACfC,KA8gCAT,MAAAO,MAAA,CAAmB,CAAA,CA7gCnB,KAAAd,GAAA,CAAmBA,CAAnB,EAAkC,CAKlC,KAAAiB,EAAA,CADA,IAAAC,EACA,CAFA,IAAAC,EAEA,CAHA,IAAAC,EAGA,CAHW,IA8BXC,GAAAjG,KAAA,CAfckG,IAed,CA9EJ;AAkGAC,QAAO,GAAkB,CAACjB,CAAD,CAAYkB,CAAZ,CAAmBhH,CAAnB,CACzB,CAKQiH,EAAA,CAAmBnB,CAAnB,CAAJ,EAAqCkB,CAArC,GACIC,EAAA,CAAmBnB,CAAnB,CAAA,CAA8BkB,CAA9B,CADJ,CAC2ChH,CAD3C,CALJ,CA0BAkH,QAAO,GAAO,EACd,CACI,MAAOvK,KAAAwK,IAAA,EAAP,EAAqB,CAAC,IAAIxK,IAD9B,CA+IAyK,QAAO,EAAS,CAACC,CAAD,CAChB,CACQ9I,MAAJ,EACIA,MAAA+I,MAAA,CAAaD,CAAb,CAFR,CAcAE,QAAO,GAAW,CAACC,CAAD,CAClB,CACI,IAAIC,EAAY,CAAA,CACZlJ,OAAJ,GACIkJ,CADJ,CACgBlJ,MAAAmJ,QAAA,CAAeF,CAAf,CADhB,CAGA,OAAOC,EALX,CA8BAE,QAAO,GAAa,CAACC,CAAD,CAAUC,CAAV,CACpB,CACID,CAAA7N,MAAA,EAAiB8N,CAKbA,EAAA,CAAQD,CAAA7N,MACW,KAAnB,CAAI8N,CAAArM,OAAJ,GAAyBoM,CAAA7N,MAAzB,CAAyC8N,CAAAvO,OAAA,CAAauO,CAAArM,OAAb,CAA4B,IAA5B,CAAzC,CAEJoM,EAAAE,UAAA,CAAoBF,CAAAG,aATxB;AA+DAC,QAAO,GAAqB,CAAClB,CAAD,CAAYmB,CAAZ,CAC5B,CADiDC,IAAAA,EAyhFMC,CAvhF/CC,EAAAA,CAAaC,CAAA,CAA6BJ,CAAAK,WAA7B,CAAiDJ,CAAjD,CAA6D,UAA7D,CAEjB,KAAK,IAAIK,EAAW,CAApB,CAAuBA,CAAvB,CAAkCH,CAAA5M,OAAlC,CAAqD+M,CAAA,EAArD,CAII,IAFA,IAAIC,EAAeJ,CAAA,CAAWG,CAAX,CAAAE,WAAnB,CAESC,EAAQ,CAAjB,CAAoBA,CAApB,CAA4BF,CAAAhN,OAA5B,CAAiDkN,CAAA,EAAjD,CAA0D,CACtD,IAAId,EAAUY,CAAA,CAAaE,CAAb,CACd,IAAyB,CAAzB,GAAId,CAAAe,SAAJ,CAAA,CAGA,IAAIC,EAAShB,CAAAiB,aAAA,CAAqB,OAArB,CACb,IAAKD,CAAL,CAEA,IADA,IAAIE,EAAWF,CAAAjI,MAAA,CAAa,GAAb,CAAf,CACSoI,EAAS,CAAlB,CAAqBA,CAArB,CAA8BD,CAAAtN,OAA9B,CAA+CuN,CAAA,EAA/C,CAGI,OADAH,CACQA,CADCE,CAAA,CAASC,CAAT,CACDH,CAAAA,CAAR,EACI,KAAKV,CAAL,CAAiB,UAAjB,CAOI,CANA3C,CAMA,CANQyD,EAAA,CAAuDpB,CAAvD,CAMR,GALkCvL,IAAAA,EAKlC,GALakJ,CAAA,QAKb,EAJIuB,CAAAmC,GAAA,CAAqB1D,CAAA,KAArB,CAAoCA,CAAA,QAApC,CAAiFqC,CAAjF,CAA2FrC,CAAA,MAA3F,CAIJ,CAAAwD,CAAA,CAASD,CAAAtN,OARjB,CATJ,CAFsD,CAPlE,CA8CA0N,QAAO,GAAa,CAACC,CAAD,CACpB,CACI,IAAIxR,CAAJ,CACIyR,EAAc,EAQdD,EAAJ,GAEQA,CAFR,CACuC,CAAnC,EAAKxR,CAAL,CAASwR,CAAAjQ,QAAA,CAAkB,GAAlB,CAAT,EACgBiQ,CAAA7P,OAAA,CAAiB,CAAjB,CAAoB3B,CAApB,CAAwB,CAAxB,CADhB,CAGgB,EAJpB,CAMA,KAAKA,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB0R,EAAA7N,OAAhB,CAA6C7D,CAAA,EAA7C,CAAkD,CAC9C,IAAImP,EAAYwC,EAAA,CAAqB3R,CAArB,CACXwR,EAAL,EAAmBrC,CAAArB,GAAAvM,QAAA,CAAqBiQ,CAArB,CAAnB,EACIC,CAAAxI,KAAA,CAAiBkG,CAAjB,CAH0C,CAMlD,MAAOsC,EAtBX;AAmCAG,QAAO,GAAgB,CAAC9D,CAAD,CACvB,CACI,GAAWpJ,IAAAA,EAAX,GAAIoJ,CAAJ,CAAsB,CAClB,IAAI9N,CASJ,KAAKA,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB0R,EAAA7N,OAAhB,CAA6C7D,CAAA,EAA7C,CACI,GAAI2R,EAAA,CAAqB3R,CAArB,CAAA8N,GAAJ,GAAmCA,CAAnC,CACI,MAAO6D,GAAA,CAAqB3R,CAArB,CAZG,CAmBtB,MAAO,KApBX,CA+BA6R,QAAO,GAAkB,CAACC,CAAD,CAAQN,CAAR,CACzB,CAD4CO,IAAAA,CAExC,IAAcrN,IAAAA,EAAd,GAAIoN,CAAJ,CAAyB,CACrB,IAAI9R,CAMAwR,EAAJ,GAEQA,CAFR,CACuC,CAAnC,EAAKxR,CAAL,CAASwR,CAAAjQ,QAAA,CAAkB,GAAlB,CAAT,EACgBiQ,CAAA7P,OAAA,CAAiB,CAAjB,CAAoB3B,CAApB,CAAwB,CAAxB,CADhB,CAGgB,EAJpB,CAOA,KAAKA,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB0R,EAAA7N,OAAhB,CAA6C7D,CAAA,EAA7C,CACI,GAAI+R,CAAJ,CACQA,CAAJ,EAAqBJ,EAAA,CAAqB3R,CAArB,CAArB,GAA8C+R,CAA9C,CAA8D,IAA9D,CADJ,KAIA,IAAI,EAAAD,CAAA,EAASH,EAAA,CAAqB3R,CAArB,CAAAgG,KAAT,EAA2CwL,CAA3C,EAAyDG,EAAA,CAAqB3R,CAArB,CAAA8N,GAAAvM,QAAA,CAAmCiQ,CAAnC,CAAzD,CAAJ,CACI,MAAOG,GAAA,CAAqB3R,CAArB,CApBM,CAyBzB,MAAO,KA1BX,CAkCAgS,QAAO,GAAiB,CAAC1B,CAAD,CACxB,CACI,IAAI1C,EAAQ,IAEZ,IADItD,CACJ,CADagG,CAAAY,aAAA,CAAqB,YAArB,CACb,CACI,GAAI,CACAtD,CAAA,CAAQpF,IAAA,CAAK,GAAL,CAAW8B,CAAX,CAAoB,GAApB,CADR,CAUF,MAAM1K,CAAN,CAAS,CA3Rf+I,CAAA,CA4RwB/I,CAAAgJ,QA5RxB,CA4RoC,IA5RpC,CA4R2C0B,CA5R3C,CA4RoD,GA5RpD,CA2Re,CAIf,MAAOsD,EAlBX;AAkCAqE,QAAO,EAAkB,CAAC3B,CAAD,CAAUW,CAAV,CAAkBiB,CAAlB,CACzB,CACQA,CAAJ,GAAejB,CAAf,EAAyB,GAAzB,CAA+BiB,CAA/B,CAA2C,SAA3C,CAKA,IAAI5B,CAAA6B,uBAAJ,CACI,MAAO7B,EAAA6B,uBAAA,CAA+BlB,CAA/B,CAPf,KASWhR,CAAGmS,EAAAA,CAAK,EACXC,EAAAA,CAAQ/B,CAAAgC,qBAAA,CAA6B,GAA7B,CACZ,KAAIC,EAAK,IAAIC,MAAJ,CAAW,OAAX,CAAqBvB,CAArB,CAA8B,OAA9B,CACJjR,EAAA,CAAI,CAAT,KAAYC,CAAZ,CAAgBoS,CAAAxO,OAAhB,CAA8B7D,CAA9B,CAAkCC,CAAlC,CAAqCD,CAAA,EAArC,CACQuS,CAAAE,KAAA,CAAQJ,CAAA,CAAMrS,CAAN,CAAA0S,UAAR,CAAJ,EACIN,CAAAnJ,KAAA,CAAQoJ,CAAA,CAAMrS,CAAN,CAAR,CAMR,OAAOoS,EApBX;AAiIAO,QAAO,GAAe,CAACxE,CAAD,CACtB,CAMI,IALA,IAAIyE,EAAW,CAAA,CAAf,CACIC,EAAYC,EAAA,CAAmB3E,CAAnB,CAIhB,CAAO0E,CAAP,EAAoBA,CAAAhP,OAApB,CAAA,CAAsC,CAElC,IAAIkP,EAAUF,CAAAG,OAAA,CAAiB,CAAjB,CAAoB,CAApB,CAAA,CAAuB,CAAvB,CAAd,CACIC,EAAWF,CAAA,CAAQ,CAAR,CADf,CAUIG,EAAc,IAC+B,EAAjD,EAAIC,EAAA5R,QAAA,CAAgC0R,CAAhC,CAAJ,GACIC,CADJ,CACkBE,QAA2B,EAAG,CACxC,MAAO,SAAQ,EAAG,CACdC,EAAA,CAA0BlF,CAA1B,CADc,CADsB,CAA9B,EADlB,CAQA,KAAImF,EAAYC,EAAA,CAAyBN,CAAzB,CAChB,IAAIK,CAAJ,CACI,GAAI,CAACJ,CAAL,CACIN,CAAA,CAAWU,CAAA,CAAUP,CAAA,CAAQ,CAAR,CAAV,CAAsBA,CAAA,CAAQ,CAAR,CAAtB,CAAkCA,CAAA,CAAQ,CAAR,CAAlC,CADf,KAGI,IAAI,CAACO,CAAA,CAAUJ,CAAV,CAAuBH,CAAA,CAAQ,CAAR,CAAvB,CAAmCA,CAAA,CAAQ,CAAR,CAAnC,CAA+CA,CAAA,CAAQ,CAAR,CAA/C,CAAL,CAAiE,KAAjE,CAJR,IAOK,CACDH,CAAA,CAAW,CAAA,CACX,KAAIzD,EAAYqE,EAAA,CAA6BT,CAAA,CAAQ,CAAR,CAA7B,CAAyC5E,CAAzC,CAChB,IAAIgB,CAAJ,CAEI,GADAmE,CACA,CADYG,EAAA,CAA4BR,CAA5B,CACZ,CACIL,CAAA,CAAWU,CAAA,CAAUnE,CAAV,CAAqB4D,CAAA,CAAQ,CAAR,CAArB,CAAiCA,CAAA,CAAQ,CAAR,CAAjC,CADf,KAGK,CACD,IAAIW,EAAUvE,CAAA,QACd,IAAIuE,CAAJ,GACIJ,CADJ,CACgBI,CAAA,CAAQT,CAAR,CADhB,EAIQ,GADAL,CACI,CADO,CAAA,CACP,CAAA,CAACM,CAAL,CACIN,CAAA,CAAWU,CAAAK,KAAA,CAAexE,CAAf,CAA0B4D,CAAA,CAAQ,CAAR,CAA1B,CAAsCA,CAAA,CAAQ,CAAR,CAAtC,CADf,KAGI,IAAI,CAACO,CAAAK,KAAA,CAAexE,CAAf,CAA0B+D,CAA1B,CAAuCH,CAAA,CAAQ,CAAR,CAAvC,CAAmDA,CAAA,CAAQ,CAAR,CAAnD,CAAL,CAAqE,KAThF,CARR,CAyBL,GAAI,CAACH,CAAL,CAAe,CACXjK,CAAA,CAAoB,iBAApB,CAAwCsK,CAAxC,CAAmD,YAAnD,EAAmEK,CAAA,CAAW,SAAX,CAAuB,iBAA1F,EACA,MAFW,CAtDmB,CA4DlCT,CAAJ,EAAiB,CAACA,CAAAhP,OAAlB,EACI,OAAOiP,EAAA,CAAmB3E,CAAnB,CAGX;MAAOyE,EAtEX,CAmIA,CAAA,CAjhHJ,CAAAgB,UAihHIC,EAAAC,SAAA,CAAAA,QAAQ,EACR,CACI,MAAQ,KAAA/F,KAAA,CAAW,IAAAA,KAAX,CAAwB,IAAAD,GAAxB,EAAmC,IAAA9H,KAD/C,CAiCA6N;CAAAvC,GAAA,CAAAA,QAAU,CAACyC,CAAD,CAAYC,CAAZ,CAAsB/D,CAAtB,CACV,CACI,OAAQ+D,CAAR,EACA,KAAK,OAAL,CAWI,MAVK,KAAA/F,EAAA,CAAc+F,CAAd,CAUE,GATH,IAAA/F,EAAA,CAAc+F,CAAd,CACA,CAD0B/D,CAC1B,CAAAA,CAAAgE,QAAA,CAAmB,QAAQ,CAAC9E,CAAD,CAAY,CACnC,MAAO+E,SAAqB,EAAG,CACvB/E,CAAAlB,EAAA,MAAJ,GACIkB,CAAAlB,EAAA,MAAA7L,MADJ,CACwC,EADxC,CAD2B,CADI,CAApB,CAMjB,IANiB,CAQhB,EAAA,CAAA,CACX,MAAK,OAAL,CAqCI,MApCK,KAAA6L,EAAA,CAAc+F,CAAd,CAoCE,GAlCH,IAAA/F,EAAA,CAAc+F,CAAd,CAqBA,CAtByD/D,CAsBzD,CAbA,IAAAkE,GAaA,CAbcC,QAAsB,CAAC1T,CAAD,CAAyB,CACzD,IAAA2T,EAAA,CAAa3T,CAAb,CAAgB,IAAAsF,KAAhB,CACA,OAAO,CAAA,CAFkD,CAa7D,CAtByDiK,CAgBzD7N,MAMA,CANwB,EAMxB,CALA,IAAAkS,MAKA,CALa,QAAQ,CAACrE,CAAD,CAAU,CAC3B,MAAOsE,SAAqB,CAAC7T,CAAD,CAAI,CAC5B8T,EAAA,CAAwBvE,CAAxB,CAAiCvP,CAAjC,CAD4B,CADL,CAAlB,CAjB4CuP,CAiB5C,CAKb,CAAA,IAAAoE,EAAA,CAAe,QAAQ,CAAClF,CAAD,CAAYc,CAAZ,CAAqB,CACxC,MAAOwE,SAAuB,CAAC/T,CAAD,CAAIsF,CAAJ,CAAc,CACnCtF,CAAL,GAAQA,CAAR,CAAY,EAAZ,CACA,IAAIsF,CAAJ,EAAY0O,EAAZ,EAAuD,KAAvD,EAAwChU,CAAAmB,MAAA,CAAS,EAAT,CAAxC,CACQmE,CACJ,GADUtF,CACV,CADcsF,CACd,CADqB,IACrB,CAD4BtF,CAC5B,EAAA8T,EAAA,CAAwBvE,CAAxB,CAAiCvP,CAAjC,CAAqC,IAArC,CAFJ,KAGO,CAxjBnBwP,CAAAA,CAyjByCD,CAzjBjC7N,MACZ,KAAIpC,EAAIkQ,CAAA3M,YAAA,CAwjB8C7C,CAxjB9C,CACA,EAAR,CAAIV,CAAJ,CACIkQ,CADJ,EAujBsDxP,CAvjBtD,CACuB,IADvB,CAGIwP,CAHJ,CAGYA,CAAAvO,OAAA,CAAa,CAAb,CAAgB3B,CAAhB,CAHZ,EAujByDU,CAvjBzD,CAujB6D,GAvjB7D;AAG4CwP,CAAAvO,OAAA,CAAa3B,CAAb,CAojBUU,CApjBOmD,OAAjB,CAKb,KAA/B,CAAgBqM,CAAArM,OAAhB,GAAqCqM,CAArC,CAA6CA,CAAAvO,OAAA,CAAauO,CAAArM,OAAb,CAA4B,IAA5B,CAA7C,CA+iB6CoM,EA9iB7C7N,MAAA,CAAgB8N,CA8iB6BD,EA7iB7CE,UAAA,CA6iB6CF,CA7iBzBG,aA4iBG,CALiC,CADJ,CAA7B,CAWb,IAXa,CAtB0CH,CAsB1C,CAaZ,EAAA,CAAA,CACX,SACI,MAAO,CAAA,CApDX,CADJ,CAsEA4D,EAAAlR,IAAA,CAAAA,QAAG,EACH,EAiEAkR,EAAAS,MAAA,CAAAA,QAAK,EACL,EAeAT,EAAAQ,EAAA,CAAAA,QAAO,EACP,EAaAR,EAAAlN,OAAA,CAAAA,QAAM,CAACjG,CAAD,CACN,CACI,IAAA2T,EAAA,CAAa,IAAArO,KAAb,CAAyB,IAAzB,CAAgCtF,CAAhC,CADJ,CAiBAmT,EAAAM,GAAA,CAAAA,QAAM,CAACzT,CAAD,CAAIiU,CAAJ,CAAgB7G,CAAhB,CACN,CACI,GAAI,CAAC6G,CAAL,CAAiB,CAIb,IAAIC,EAAWpB,EAAA,CAA6B,UAA7B,CAAyC,IAAA1F,GAAzC,CACf,IAAI8G,CAAJ,EAAgBA,CAAAxG,MAAAM,GAAhB,CAEI,MADAmG,QAAAlS,IAAA,CAAY,iCAAZ,CAAgDjC,CAAhD,CACO,CAAA,CAAA,CAPE,CAUe,CAAA,CAAAoN,CAAA,EAAM,IAAA9H,KAAlB2O,EAvzBpB,EAAiBhM,CAAA,EAAqBmF,CAAA,CAAKA,CAAL,CAAU,IAAV,CAAkB,EAAvC,EAuzBApN,CAvzBA,CAwzBjB,OAAO,CAAA,CAZX,CAuBAoU,SAAA,GAAQ,CAARA,CAAQ,CAACpU,CAAD,CACR,CACI,CAAA0N,MAAAO,MAAA,CAAmB,CAAA,CACnB,EAAAwF,GAAA,CAAYzT,CAAZ,CAFJ;AAwBAqU,QAAA,GAAO,CAAPA,CAAO,CACP,CACI,MAAI,EAAA3G,MAAAO,MAAJ,EACI,CAAA0F,EAAA,CAAa,CAAAP,SAAA,EAAb,CAA+B,QAA/B,CACO,CAAA,CAAA,CAFX,EAIO,CAAA,CALX,CAqBAkB,QAAA,GAAO,CAAPA,CAAO,CAACpG,CAAD,CACP,CACQA,CAAJ,GACQ,CAAAR,MAAAC,MAAJ,CACIO,CAAA,EADJ,CAII,CAAAA,GAJJ,CAImBA,CALvB,CAQA,OAAO,EAAAR,MAAAC,MATX,CAoBA4G,QAAA,GAAQ,CAARA,CAAQ,CACR,CACI,GAAI,CAAC,CAAA7G,MAAAO,MAAL,GACI,CAAAP,MAAAC,MACIA,CADgB,CAAA,CAChBA,CAAA,CAAAD,MAAAC,MAFR,EAE0B,CAElB,IAAIO,EAAU,CAAAA,GACd,EAAAA,GAAA,CAAe,IACXA,EAAJ,EAAaA,CAAA,EAJK,CAH9B,CAqBAsG,QAAA,GAAM,CAANA,CAAM,CAACC,CAAD,CACN,CACQ,CAAA/G,MAAAE,GAAJ,GACQ6G,CAAJ,CACI,CAAA/G,MAAAG,GADJ,CAC4B,CAAA,CAD5B,CAEuB7J,IAAAA,EAFvB,GAEWyQ,CAFX,EAGI,CAAAd,EAAA,CAAa,CAAAP,SAAA,EAAb,CAA+B,OAA/B,CAJR,CAOA,OAAO,EAAA1F,MAAAE,GARX,CAoBA8G,QAAA,GAAO,CAAPA,CAAO,CAACC,CAAD,CACP,CACI,GAAI,CAAAjH,MAAAG,GAAJ,CAGI,MAFA,EAAAH,MAAAE,GACA,CADkB,CAAA,CAClB,CAAA,CAAAF,MAAAG,GAAA,CAAwB,CAAA,CAG5B,IAAI,CAAAH,MAAAO,MAAJ,CAEI,MADA,EAAA0F,EAAA,CAAa,CAAAP,SAAA,EAAb,CAA+B,QAA/B,CACO,CAAA,CAAA,CAEX,EAAA1F,MAAAE,GAAA,CAAkB+G,CAClB,OAAO,EAAAjH,MAAAE,GAXX;AAsBAuF,CAAAyB,GAAA,CAAAA,QAAO,EACP,CAEI,MADA,KAAAlH,MAAAK,EACA,CADqB,CAAA,CADzB,CAaAoF,EAAA0B,GAAA,CAAAA,QAAS,CAACC,CAAD,CAAQC,CAAR,CACT,CACQA,CAAJ,GAAe,IAAArH,MAAAK,EAAf,CAAoC,CAAA,CAApC,CACA,OAAO,CAAA,CAFX,CAcAiH,SAAA,GAAc,CAAdA,CAAc,CAAC7H,CAAD,CACd,CADeA,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAc,CAAd,CAAAA,CAEX,OAAgB,EAAAiB,EAAhB,GACQ,CAaA,GAbS,CAAAA,EAaT,GAZAjB,CAYA,CAZcA,CAYd,EAZ6B,CAAAA,GAY7B,EAVA8H,CAUA,CAVc,CAAA7G,EAAAjB,GAUd,CAVqCA,CAUrC,CAHCA,CAGD,CAHe,UAGf,EAH+BA,CAG/B,CAH6C,SAG7C,GAFM8H,CAEN,CAFoB,UAEpB,EAFqCA,CAErC,CAFmD,SAEnD,GAFgEA,CAEhE,CAF8E,CAE9E,GAAA9H,CAAA,EAAe8H,CAAf,GAA+B9H,CAdvC,EAee,CAAA,CAff,CAkBO,CAAA,CAnBX,CAyDA+H,QAAA,GAAY,CAAZA,CAAY,CAAClG,CAAD,CAAW7B,CAAX,CAAwBgI,CAAxB,CACZ,CACoB,CAAA/G,EAAhB,GACwB,CAAA,CADxB,GACQjB,CADR,EACgC6H,EAAA,CAAAA,CAAA,CAAoB7H,CAApB,CAAkC,CAAlC,CADhC,GAEQ,CAAAiB,EAAAlG,QAAA,CAAiB8G,CAAjB,CAA2BmG,CAA3B,CAHZ,CAoDAC,IAAAA,GAAYA,UAiBZlP;MAAJ,GACSA,MAAA,KAGL,GAHqBA,MAAA,KAGrB,CAHsC,EAGtC,EAFKA,MAAA,KAAA,SAEL,GAFiCA,MAAA,KAAA,SAEjC,CAF8D,EAE9D,EADKA,MAAA,KAAA,WACL,GADmCA,MAAA,KAAA,WACnC,CADkE,EAClE,EAAKA,MAAA,KAAA,SAAL,GAAiCA,MAAA,KAAA,SAAjC,CAA8D,EAA9D,CAJJ,CAMA;IAAA0I,GAAqB1I,MAAA,CAAQA,MAAA,KAAA,SAAR,CAAqC,EAA1D,CACA+K,GAAuB/K,MAAA,CAAQA,MAAA,KAAA,WAAR,CAAuC,EAD9D,CAEAkM,GAAqBlM,MAAA,CAAQA,MAAA,KAAA,SAAR,CAAqC,EAF1D,CAIAmP,GAA0B,CACtB,MADsB,CACd,OADc,CACL,MADK,CAJ1B,CAOAxC,GAA2B,CACvB,MAxlBAyC,QAAkB,CAACtG,CAAD,CAClB,CACI/G,CAAA,CAAoB+G,CAApB,CACA,OAAO,CAAA,CAFX,CAslBuB,CAEvB,MAjjBAuG,QAAkB,CAACC,CAAD,CAAaC,CAAb,CAClB,CACIlL,UAAA,CAAWiL,CAAX,CAAuB,CAACC,CAAxB,CACA,OAAO,CAAA,CAFX,CA8iBuB,CAP3B,CAWA1C,GAA8B,CAC1B,OA9kBA2C,QAAmB,CAACjH,CAAD,CAAY6E,CAAZ,CAAsBlK,CAAtB,CACnB,CACI,IAAI8I,EAAW,CAAA,CAGf,IADI3C,CACJ,CAFgBd,CAAAkH,SACF,CAAUrC,CAAV,CACd,CACI,IAAShU,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoBiQ,CAAAqG,QAAAzS,OAApB,CAA4C7D,CAAA,EAA5C,CACI,GAAIiQ,CAAAqG,QAAA,CAAgBtW,CAAhB,CAAAuW,YAAJ,EAAsCzM,CAAtC,CAA8C,CACtCmG,CAAAuG,cAAJ,EAA6BxW,CAA7B,GACIiQ,CAAAuG,cADJ,CAC4BxW,CAD5B,CAGA4S,EAAA,CAAW,CAAA,CACX,MAL0C,CAStD,MAAOA,EAfX,CA4kB0B,CAmBzBnK;KAAArE,UAAA7C,QAAL,GACIkH,KAAArE,UAAA7C,QADJ,CAC8BkV,QAAQ,CAACC,CAAD,CAAMC,CAAN,CAAa,CAClC3W,CAAAA,CAAK2W,CAAL3W,EAAc,CAAvB,KAAK,IAAsBC,EAAI,IAAA4D,OAA/B,CAA4C7D,CAA5C,CAAgDC,CAAhD,CAAmDD,CAAA,EAAnD,CACI,GAAI,IAAA,CAAKA,CAAL,CAAJ,GAAgB0W,CAAhB,CAAuB,MAAO1W,EAElC,OAAQ,EAJmC,CADnD,CAYKyI,MAAAmO,QAAL,GACInO,KAAAmO,QADJ,CACoBC,QAAQ,CAACC,CAAD,CAAM,CAC1B,MAA+C,gBAA/C,GAAOC,MAAA3S,UAAA0P,SAAAH,KAAA,CAA+BmD,CAA/B,CADmB,CADlC,CASKE;QAAA5S,UAAA6S,KAAL,GACID,QAAA5S,UAAA6S,KADJ,CAC8BC,QAAQ,CAACR,CAAD,CAAM,CAQtBS,QAAA,EAAQ,EAAG,CACrB,MAAOC,EAAAC,MAAA,CAAc,IAAA,WAAgBC,EAAhB,EAAyBZ,CAAzB,CAA8B,IAA9B,CAAqCA,CAAnD,CAAwDa,CAAAC,OAAA,CAAiC/O,KAAArE,UAAAvC,MAAA8R,KAAA,CAA2B8D,SAA3B,CAAjC,CAAxD,CADc,CADQH,QAAA,EAAQ,EAAG,EAN5C,GAAmB,UAAnB,EAAI,MAAO,KAAX,CAEI,KAAM,KAAII,SAAJ,CAAc,8CAAd,CAAN,CAEJ,IAAIH,EAAO9O,KAAArE,UAAAvC,MAAA8R,KAAA,CAA2B8D,SAA3B,CAAsC,CAAtC,CAAX,CACIL,EAAU,IAKdE,EAAAlT,UAAA,CAAkB,IAAAA,UAClB+S,EAAA/S,UAAA,CAAoB,IAAIkT,CACxB,OAAOH,EAb6B,CAD5C,CA8DIQ;IAAAA,EAnCWA,OAmCXA,CACAC,GA5BUA,OA2BVD,CAmCAE,GAAgB5V,IAAAC,IAAA2V,CAASA,CAATA,CAAYA,EAAZA,CAAhBA,CAAkCA,CAnClCF,CAoCAG,GAAgB7V,IAAAC,IAAA4V,CAASA,CAATA,CAAYA,EAAZA,CApChBH,CA2CAI,GAAgB9V,IAAAC,IAAA6V,CAASA,CAATA,CAAYA,EAAZA,CAAhBA,CAAkCA,CA3ClCJ,CA4CAK,GAAgB/V,IAAAC,IAAA8V,CAASA,CAATA,CAAYA,EAAZA,CA5ChBL,CA6CAM,EAAgBhW,IAAAC,IAAA+V,CAASA,CAATA,CAAYA,EAAZA,CAAhBA,CAAkCA,CA7ClCN,CA8CAO,EAAgBjW,IAAAC,IAAAgW,CAASA,CAATA,CAAYA,EAAZA,CA9ChBP,CA+CAQ,EAAgBlW,IAAAC,IAAAiW,CAASA,CAATA,CAAYA,EAAZA,CAAhBA,CAAkCA,CA/ClCR,CAgDAS,EAAgBnW,IAAAC,IAAAkW,CAASA,CAATA,CAAYA,EAAZA,CAhDhBT,CAiDAU,EAAgBpW,IAAAC,IAAAmW,CAASA,CAATA,CAAYA,EAAZA,CAAhBA,CAAkCA,CAjDlCV,CAkDAW,EAAgBrW,IAAAC,IAAAoW,CAASA,CAATA,CAAYA,EAAZA,CAlDhBX,CAoDAY,EAAgBtW,IAAAC,IAAAqW,CAASA,CAATA,CAAYA,EAAZA,CApDhBZ,CAqDAa,GAAgBvW,IAAAC,IAAAsW,CAASA,CAATA,CAAYA,EAAZA,CArDhBb,CAsDAc,GAAgBxW,IAAAC,IAAAuW,CAASA,CAATA,CAAYA,EAAZA,CAtDhBd,CAgGIe,GAAYzW,IAAAC,IAAAyW,CAASA,CAATA,CAAYA,EAAZA,CAhGhBhB,CAiGIiB,GAAY3W,IAAAC,IAAAyW,CAASA,CAATA,CAAYA,EAAZA,CAjGhBhB,CAmGIkB,GAAY5W,IAAAC,IAAAyW,CAASA,CAATA,CAAYA,EAAZA,CAnGhBhB,CAoGImB,GAAY7W,IAAAC,IAAAyW,CAASA,CAATA,CAAYA,EAAZA,CAgHpBnI,EAAA,CAvPemH,OAwPfoB,GAAA,CAhPcnB,OAiSd;IAAAoB,GAA2B,CACvB,IAxCYC,CAuCW,CAEvB,KAxCYC,CAsCW,CAGvB,MAxCYC,CAqCW,CAIvB,MAxCYC,CAoCW,CAKvB,IAxCYC,EAmCW,CAMvB,OAxCYC,EAkCW,CAOvB,IAxCYC,EAiCW,CAQvB,IAxCYC,GAgCW,CASvB,OAxCYC,GA+BW,CAUvB,MAxCYC,GA8BW,CAWvB,SAxCYC,IA6BW,CAYvB,IAxCYC,IA4BW,CAavB,MAxCYC,IA2BW,CAcvB,KAxCYC,KA0BW,CAevB,MAxCYC,KAyBW,CAgBvB,OAxCYC,OAwBW,CAiBvB,MAxCYC,OAuBW,CAkBvB,QAxCYC,QAsBW,CAmBvB,SAxCYC,QAqBW,CAoBvB,IAxCYC,SAoBW,CAqBvB,KAxCYC,SAmBW,CA6BvB,OA/CYC,UAkBW,CA8BvB,KA/CYC,WAiBW,CA0EvB7M;QATE8M,GASS,CAACC,CAAD,CAAaC,CAAb,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,OAAN,CAAeD,CAAf,CA1GQf,GA0GR,CAOA,KAAAiB,EAAA,CADA,IAAAC,EACA,CADiB,CAIjB,KAAAF,EAAA,CAAiBA,CAiBjB,KAAAG,EAAA,CAAe,IAAAC,EAAf,CADA,IAAAC,EACA,CAFA,IAAAC,EAEA,CAFkB,CAGlB,KAAAC,EAAA,CAAe,IAAAC,EAAf,CAA+B,EAa/B,KAAAC,EAAA,CADA,IAAAC,EACA,CAFA,IAAAC,EAEA,CAFgB,CAAA,CAGhB,KAAAC,EAAA,CAAgBC,EAShB,KAAAC,EAAA,CAAY,EAsBZ,KAAAC,EAAA,CAAgB,CACZ,MAAY,CAAC,CAAD,CAAI,CAAJ,CAAO,CAAA,CAAP,CAAc,CAAA,CAAd,CAAqB,IAAAC,GAArB,CADA,CAEZ,KAAY,CAAC,CAAD,CAAI,CAAJ,CAAO,CAAA,CAAP,CAAc,CAAA,CAAd,CAAqB,IAAAC,GAArB,CAFA,CAGZ,OAAY,CAAC,CAAD,CAAI,CAAJ,CAAO,CAAA,CAAP,CAAc,CAAA,CAAd,CAAqB,IAAAC,GAArB,CAHA,CAIZ,KAAY,CAAC,CAAD,CAAI,CAAJ,CAAO,CAAA,CAAP,CAAc,CAAA,CAAd,CAAqB,IAAAC,GAArB,CAJA,CAKZ,IAAY,CAAC,CAAD,CAAI,CAAJ,CAAO,CAAA,CAAP,CAAc,CAAA,CAAd,CAAqB,IAAAC,GAArB,CALA,CAMZ,KAAY,CAAC,CAAD,CAAI,CAAJ,CAAO,CAAA,CAAP,CAAc,CAAA,CAAd,CAAqB,IAAAC,GAArB,CANA,CAOZ,KAAY,CAAC,CAAD,CAAI,CAAJ,CAAO,CAAA,CAAP,CAAc,CAAA,CAAd,CAAqB,IAAAC,GAArB,CAPA,CAQZ,KAAY,CAAC,CAAD,CAAI,CAAJ,CAAO,CAAA,CAAP,CAAc,CAAA,CAAd,CAAqB,IAAAC,GAArB,CARA,CAUhB,KAASjc,CAAT,CAAa,CAAb,CAAoB,EAApB,CAAgBA,CAAhB,CAAwBA,CAAA,EAAxB,CACI,IAAAyb,EAAA,CAAc,GAAd,CAAkBzb,CAAlB,CAAA,CAAuB,CAAC,CAAD,CAAI,CAAJ,CAAO,CAAA,CAAP,CAAc,CAAA,CAAd,CAAqB,IAAAkc,GAArB,CAA2Clc,CAA3C,CAa3B,KAAA8O,EAAA,CAHA,IAAAC,EAGA,CANA,IAAAC,EAMA,CATA,IAAAC,EASA,CATW,IAyBX,KAAA,QAAA,CAAkB,CACd,KAAQ,IAAAkN,GADM,CAEd,OAAU,IAAAC,GAFI,CAGd,MAAS,IAAAC,GAHK;AAId,IAAO,IAAAC,GAJO,CAOlBrH,GAAA,CAAAA,IAAA,CAzHJ,CAVqBsH,EAAA5O,CAAnB6M,EAAmB7M,CAAAA,CAAAA,CA+NrB,EAAA,CApsJJ,EAAA6O,UAosJI3I,EAAA4I,MAAA,CAAAA,QAAK,CAACC,CAAD,CACL,CAII,IAAAC,KAAA,EACID,EAAJ,EArDOE,EAAA,CAqDOC,IArDP,CAqDOA,IArDS7B,EAAhB,CAqDkB5Y,CArDlB,CAgDX,CAuBAyR;CAAAvC,GAAA,CAAAA,QAAU,CAACQ,CAAD,CAAQkC,CAAR,CAAkB/D,CAAlB,CAA2BnG,CAA3B,CACV,CAOI,GANI,IAAAmF,EAMJ,EANgB,IAAAA,EAAAqC,GAAA,CAAoBQ,CAApB,CAA2BkC,CAA3B,CAAqC/D,CAArC,CAA8CnG,CAA9C,CAMhB,EAHI,IAAAiF,EAGJ,EAHgB,IAAAA,EAAAuC,GAAA,CAAoBQ,CAApB,CAA2BkC,CAA3B,CAAqC/D,CAArC,CAA8CnG,CAA9C,CAGhB,EAAgB,IAAAgF,EAAhB,EAA4B,IAAAA,EAAAwC,GAAA,CAAoBQ,CAApB,CAA2BkC,CAA3B,CAAqC/D,CAArC,CAA8CnG,CAA9C,CAA5B,CACI,MAAO,CAAA,CAGX,QAAQkK,CAAR,EACA,KAAK,IAAL,CAGI,MAFA,KAAA/F,EAAA,CAAc+F,CAAd,CAEO,CAFmB/D,CAEnB,CADP,IAAA2K,EAAA,EACO,CAAA,CAAA,CAEX,SAQI,MAAa,KAAb,EAAI9I,CAAJ,EAA+B,MAA/B,EAAsBA,CAAtB,EACI,IAAA7D,EAAA,CAAc+F,CAAd,CAGO,CAHmB/D,CAGnB,CAFP,IAAAuL,EAAA,CAAUxH,CAAV,CAEO,CAFelK,CAAA,CAAQ,CAAR,CAAY,CAE3B,CADP,IAAA8Q,EAAA,EACO,CAAA,CAAA,CAJX,EAgBa,QAAb,EAAI9I,CAAJ,EAKoCpN,IAAAA,EA2BzB,GA3BH,IAAA+W,EAAA,CAAczH,CAAd,CA2BG,GA1BH,IAAAyH,EAAA,CAAczH,CAAd,CA0BG,CA1BuB,CAAClK,CAAA,CAAQ,CAAR,CAAY,CAAb,CAAgBA,CAAA,CAAQ,CAAR,CAAY,CAA5B,CA0BvB,EAxBP,IAAAmE,EAAA,CAAc+F,CAAd,CAwBO,CAxBmB/D,CAwBnB,CAvBH6M,CAuBG,CAvBM7M,CAAA8M,cAuBN,EAvB+B9M,CAuB/B,CAtBP6M,CAsBO,CAtBEA,CAAAC,cAsBF,EAtB0BD,CAsB1B,CArBPA,CAAArR,YAqBO,CArBc,QAAQ,CAACuR,CAAD,CAAQhJ,CAAR,CAAkB,CAC3C,MAAOiJ,SAAsB,EAAG,CAC5BC,EAAA,CAAAF,CAAA,CAAkBhJ,CAAlB,CAD4B,CADW,CAA1B,CAInB,IAJmB,CAIbA,CAJa,CAqBd,CAhBP8I,CAAAhR,UAgBO,CAhBYgR,CAAA/Q,WAgBZ,CAhBgC,QAAQ,CAACiR,CAAD,CAAQhJ,CAAR,CAAkB,CAC7D,MAAOmJ,SAAwB,EAAG,CAC9BC,EAAA,CAAAJ,CAAA,CAAoBhJ,CAApB,CAD8B,CAD2B,CAA1B,CAIrC,IAJqC,CAI/BA,CAJ+B,CAgBhC,CAXP8I,CAAAlR,aAWO;AAXe,QAAQ,CAACoR,CAAD,CAAQhJ,CAAR,CAAkB,CAC5C,MAAOiJ,SAAsB,CAACI,CAAD,CAAQ,CACjCH,EAAA,CAAAF,CAAA,CAAkBhJ,CAAlB,CACAqJ,EAAAC,eAAA,EAFiC,CADO,CAA1B,CAKpB,IALoB,CAKdtJ,CALc,CAWf,CALP8I,CAAA5Q,WAKO,CALa,QAAQ,CAAC8Q,CAAD,CAAQhJ,CAAR,CAAkB,CAC1C,MAAOmJ,SAAwB,EAAG,CAC9BC,EAAA,CAAAJ,CAAA,CAAoBhJ,CAApB,CAD8B,CADQ,CAA1B,CAIlB,IAJkB,CAIZA,CAJY,CAKb,CAAA,CAAA,CAhCX,EAkCO1C,CAAAA,UAAAA,GAAAA,KAAAA,CAAAA,IAAAA,CAAiBQ,CAAjBR,CAAwB0C,CAAxB1C,CAAkCrB,CAAlCqB,CAA2CxH,CAA3CwH,CAhEX,CAXJ,CAwFAuC,EAAA0J,GAAA,CAAAA,QAAO,CAACtO,CAAD,CAAMD,CAAN,CAAWD,CAAX,CAAgBD,CAAhB,CACP,CACI,IAAAG,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CAEX0O,GAAA,CAAAA,IAAA,CACAC,GAAA,CAAAA,IAAA,CAPJ,CAkBA5J,EAAAyB,GAAA,CAAAA,QAAO,CAACjN,CAAD,CAAOqV,CAAP,CACP,CACI,GAAI,CAACA,CAAL,CAQI,GAFI,IAAAhD,EAEA,EAFgBiD,EAAA,EAEhB,CAAA,CAACtV,CAAL,CACI,IAAAoU,MAAA,CAAW,CAAA,CAAX,CADJ,KAGI,IAAI,CAAC,IAAAmB,QAAA,CAAavV,CAAb,CAAL,CAAyB,MAAO,CAAA,CAGxC,OAAO,CAAA,CAfX,CA0BAwL,EAAA0B,GAAA,CAAAA,QAAS,CAACC,CAAD,CACT,CACI,MAAOA,EAAA,CAAO,IAAAqI,KAAA,EAAP,CAAqB,CAAA,CADhC,CAYAhK,EAAAgK,KAAA,CAAAA,QAAI,EACJ,CACI,IAAIC,EAAQ,IAAIC,CAAJ,CAAU,IAAV,CACZD,EAAAE,IAAA,CAAU,CAAV,CAAa,CACTC,IAjQGpD,EAgQM,CAETqD,IA5OGlD,EA0OM,CAGTmD,IAtNGpD,EAmNM,CAAb,CAKA,OAAO+C,EAAAzV,KAAA,EAPX,CAmBAwL;CAAA+J,QAAA,CAAAA,QAAO,CAACvV,CAAD,CACP,CAEI,GADI7I,CACJ,CADQ6I,CAAA,CAAK,CAAL,CACR,CAzQA+V,EAAA,CA0QIC,IA1QJ,CA0QIA,IA1QYxD,EAAhB,CA0Qerb,CAAA4C,CAAE,CAAFA,CA1Qf,CA6CA,CAtBOwa,EAAA,CAoPHC,IApPG,CAoPHA,IApPmB7B,EAAhB,CAoPQxb,CAAA4C,CAAE,CAAFA,CApPR,CAsBP,CAAAkc,EAAA,CA+NIC,IA/NJ,CA+Ne/e,CAAA4C,CAAE,CAAFA,CA/Nf,CAiOA,OAAO,CAAA,CAPX,CAgBAyR,EAAAwI,GAAA,CAAAA,QAAa,EACb,CACI,IAAKrI,IAAIA,CAAT,GAAqB,KAAAyH,EAArB,CAAoC,CAChC,IAAI+C,EAAK,IAAA/C,EAAA,CAAczH,CAAd,CACTwK,EAAA,CAAG,CAAH,CAAA,CAAQA,CAAA,CAAG,CAAH,CAFwB,CAIpCf,EAAA,CAAAA,IAAA,CACA,OAAO,CAAA,CANX,CAgBAgB,SAAA,GAAU,CAAVA,CAAU,CAACzK,CAAD,CAAW5R,CAAX,CACV,CAEI,GADI6N,CACJ,CADc,CAAAhC,EAAA,CAAc+F,CAAd,CACd,CAII/D,CAAAyO,MAAAC,gBAAA,CAAiCvc,CAAA,CAAO,SAAP,CAAmB,SAN5D,CAgBAob,QAAA,GAAW,CAAXA,CAAW,CAACoB,CAAD,CACX,CACI,IAAK5K,IAAIA,CAAT,GAAqB,EAAAwH,EAArB,CACIiD,EAAA,CAAAA,CAAA,CAAgBzK,CAAhB,CAAsC,IAAZ,EAAA4K,CAAA,CAAkBA,CAAlB,CAA6B,CAAApD,EAAA,CAAUxH,CAAV,CAAvD,CAFR,CAaA6K,QAAA,GAAa,CAAbA,CAAa,CAAC7K,CAAD,CAAW5R,CAAX,CACb,CAEI,GADI6N,CACJ,CADc,CAAAhC,EAAA,CAAc+F,CAAd,CACd,CACI/D,CAAAyO,MAAAI,UACA,CAD2B1c,CAAA,CAAO,KAAP,CAAe,MAC1C,CAAA6N,CAAAyO,MAAAC,gBAAA,CAAiCvc,CAAA,CAAO,SAAP,CAAmB,SAJ5D,CAaAqb,QAAA,GAAe,CAAfA,CAAe,CACf,CACI,IAAKzJ,IAAIA,CAAT,GAAqB,EAAAyH,EAArB,CACIoD,EAAA,CAAAA,CAAA,CAAmB7K,CAAnB,CAA6B,CAAAyH,EAAA,CAAczH,CAAd,CAAA,CAAwB,CAAxB,CAA7B,CAFR;AA+CAH,CAAAsI,GAAA,CAAAA,QAAU,CAACjG,CAAD,CAAalC,CAAb,CAAuBmC,CAAvB,CACV,CACI,GAAI+G,EAAA,CAAAA,IAAA,CAAiBlJ,CAAjB,CAAJ,CAAgC,CAC5B,GAAImC,CAAJ,CAAY,CACR,IAAI6G,EAAQ,IACZ/R,WAAA,CAAW,QAAQ,EAAG,CAClBmS,EAAA,CAAAJ,CAAA,CAAoBhJ,CAApB,CACIkC,EAAJ,EAAgBA,CAAA,EAFE,CAAtB,CAGG,CAACC,CAHJ,CAIA,OAAO,CAAA,CANC,CAQRiH,EAAA,CAAAA,IAAA,CAAmBpJ,CAAnB,CATwB,CAYhC,MAAO,CAAA,CAbX,CAwBAH,EAAAyI,GAAA,CAAAA,QAAS,CAACtI,CAAD,CAAWlK,CAAX,CACT,CACI,GAAgB,IAAhB,EAAIkK,CAAJ,CACI,MAAOsK,GAAA,CAAAA,IAAA,CAAmBS,EAAA,CAAajV,CAAb,CAAqB,CAArB,CAAnB,CAEX,KAAI0U,EAAK,IAAA/C,EAAA,CAAczH,CAAd,CACT,OAAIwK,EAAJ,EACIA,CAAA,CAAG,CAAH,CAEO,CAFC,CAAC1U,CAAD,CAAS,CAAT,CAAa,CAEd,CADP+U,EAAA,CAAAA,IAAA,CAAmB7K,CAAnB,CAA6BwK,CAAA,CAAG,CAAH,CAA7B,CACO,CAAA,CAAA,CAHX,EAKO,CAAA,CAVX,CAoBA3K,EAAAuI,GAAA,CAAAA,QAAY,CAACpI,CAAD,CACZ,CACI,MAAIkJ,GAAA,CAAAA,IAAA,CAAiBlJ,CAAjB,CAAJ,EACIoJ,EAAA,CAAAA,IAAA,CAAmBpJ,CAAnB,CACO,CAAA,CAAA,CAFX,EAIO,CAAA,CALX,CAeAkJ,SAAA,GAAW,CAAXA,CAAW,CAAClJ,CAAD,CACX,CACI,IAAIwK,EAAK,CAAA/C,EAAA,CAAczH,CAAd,CACT,OAAIwK,EAAJ,EAIIK,EAAA,CAAAA,CAAA,CAAmB7K,CAAnB,CAA8BwK,CAAA,CAAG,CAAH,CAA9B,CAAsC,CAAtC,CAA0CA,CAAA,CAAG,CAAH,CAA1C,CAoBO,CAfPA,CAAA,CAAG,CAAH,CAeO,CAfC,CAAA,CAeD,CAVHA,CAAA,CAAG,CAAH,CAUG,EAVIA,CAAA,CAAG,CAAH,CAAA7K,KAAA,CAAW,CAAX,CAAiB6K,CAAA,CAAG,CAAH,CAAjB,CAAwBA,CAAA,CAAG,CAAH,CAAxB,CAUJ,CAJHxK,CAIG,EAJSgL,EAIT,GAHH,CAAA7D,EACA,CADiBnH,CACjB,EAD6BiL,EAC7B,CAAA,CAAA7D,EAAA,CAAiBpH,CAAjB,EAA6BkL,EAE1B,EAAA,CAAA,CAxBX,EA0BO,CAAA,CA5BX;AAsCA9B,QAAA,GAAa,CAAbA,CAAa,CAACpJ,CAAD,CACb,CAUI,IAAIwK,EAAK,CAAA/C,EAAA,CAAczH,CAAd,CACLwK,EAAJ,GACQA,CAAA,CAAG,CAAH,CAcJ,EAdaA,CAAA,CAAG,CAAH,CAcb,GAVIK,EAAA,CAAAA,CAAA,CAAmB7K,CAAnB,CAA8BwK,CAAA,CAAG,CAAH,CAA9B,CAAsCA,CAAA,CAAG,CAAH,CAAtC,CAKA,CAAIA,CAAA,CAAG,CAAH,CAAJ,EAAWA,CAAA,CAAG,CAAH,CAAA7K,KAAA,CAAW,CAAX,CAAiB6K,CAAA,CAAG,CAAH,CAAjB,CAAwBA,CAAA,CAAG,CAAH,CAAxB,CAKf,EAAAA,CAAA,CAAG,CAAH,CAAA,CAAQ,CAAA,CAfZ,CAXJ,CAuCA3K,CAAA6H,GAAA,CAAAA,QAAY,CAACtZ,CAAD,CACZ,CACSA,CAAL,EAAe,IAAA2M,EA8mERX,MAAA+Q,EA9mEP,GAEIC,CAAA,CAAA,IAAArQ,EAAA,CAAe,IAAA8L,EAAf,CAOA,CAAIwE,IApeD5D,EAAA,CAoegB6D,EApehB,CAoeH,EAAID,IApesB5D,EAAA,CAoeP6D,EApeO,CAAA,CAAoB,CAApB,CAoe1B,EACIC,EAAA,CAAA,IAAAxQ,EAAA,CAVR,CADJ,CAiCA8E,EAAA8H,GAAA,CAAAA,QAAW,EACX,EAgBA9H,EAAA+H,GAAA,CAAAA,QAAa,CAACxZ,CAAD,CACb,CAMSA,CAAL,EACIod,CAAA,CAAA,IAAAzQ,EAAA,CAPR,CAkBA8E;CAAAgI,GAAA,CAAAA,QAAe,CAACzZ,CAAD,CACf,CACI,GAAI,CAACA,CAAL,EAAc,CAAC,IAAA2M,EAwiERX,MAAA+Q,EAxiEP,CAKI,GAAKE,IAtiBF5D,EAAA,CAsiBiB6D,EAtiBjB,CAsiBH,EAAKD,IAtiBqB5D,EAAA,CAsiBN6D,EAtiBM,CAAA,CAAoB,CAApB,CAsiB1B,CAoDIC,EAAA,CAAA,IAAAxQ,EAAA,CApDJ,KAA+C,CAO3C,IADID,CACJ,CADU,IAAAA,EACV,GAAW,CAACoG,EAAA,CAAApG,CAAA,CAAW,CAAA,CAAX,CAAZ,CACIsG,EAAA,CAAAtG,CAAA,CAAY,CAAA,CAAZ,CAEA,CADA2Q,EAAA,CAAA3Q,CAAA,CAAY,CAAZ,CAAe,IAAf,CACA,CAAAsG,EAAA,CAAAtG,CAAA,CAAY,CAAA,CAAZ,CAHJ,KASI,IAAI,CACA,IAAI4Q,EAAc,IAAA3Q,EAAA0Q,GAAA,CAAiB,CAAjB,CACA,EAAlB,CAAIC,CAAJ,GACIC,EAAA,CAAA,IAAA5Q,EAAA,CAAsB2Q,CAAtB,CAEA,CADAE,EAAA,CAAA,IAAA7Q,EAAA,CAAmB2Q,CAAnB,CAAgC,CAAA,CAAhC,CACA,CAAAG,EAAA,CAAA,IAAA9Q,EAAA,CAAwB2Q,CAAxB,CAHJ,CAFA,CAQJ,MAAMI,CAAN,CAAiB,CAKW,QAAxB,EAAI,MAAOA,EAAX,GACQlgB,CACJ,CADQkgB,CACR,CAAAhL,EAAA,CAAA,IAAA/F,EAAA,CAAkBnP,CAAAmgB,MAAlB,EAA6BngB,CAAAgJ,QAA7B,CAFJ,CALa,CAerB,IAAA+T,KAAA,EAUI,KAAA1N,EAAJ,EAAc+Q,CAAA,CAAA,IAAA/Q,EAAA,CAjD6B,CANvD,CAsEA4E,EAAAiI,GAAA,CAAAA,QAAc,CAAC1Z,CAAD,CACd,CACQA,CAAJ,EAAa,CAAC,IAAA2M,EAi+DPX,MAAA+Q,EAj+DP,GACQ,IAAAhE,EAOJ,EAPmB8E,EAAA,CAAAA,IAAA,CAOnB,CAFInf,CAEJ,CAlpBG8b,EAAA,CAgpBKC,IAhpBL,CAgpBKA,IAhpBW7B,EAAhB,CAgpBgB,IAAAD,EAhpBhB,CAkpBH,CAAI,IAAAO,EAAJ,EAAqBC,EAArB,CAII2E,EAAA,CAAA,IAAAlR,EAAA,CAAuB,IAAA6L,EAAvB,CAAqC/Z,CAArC,CAJJ,CASI,IAAAiO,EAAAoR,EAAA,CAAmB,IAAAtF,EAAnB,CAAiC/Z,CAAjC,CAjBR,CADJ,CA8BA+S;CAAAkI,GAAA,CAAAA,QAAc,CAAC3Z,CAAD,CACd,CACI,GAAI,CAACA,CAAL,EAAc,CAAC,IAAA2M,EAk8DRX,MAAA+Q,EAl8DP,CAAqC,CACjC,IAAIre,CACA,KAAAsa,EAAJ,EAAmB6E,EAAA,CAAAA,IAAA,CACf,KAAA3E,EAAJ,EAAqBC,EAArB,CAIIza,CAJJ,CAIQsf,EAAA,CAAA,IAAApR,EAAA,CAAuB,IAAA6L,EAAvB,CAJR,CASI/Z,CATJ,CASQ,IAAAiO,EAAAsR,EAAA,CAAkB,IAAAxF,EAAlB,CArrBL+B,GAAA,CA2rBHC,IA3rBG,CA2rBHA,IA3rBmB7B,EAAhB,CA2rBQla,CA3rBR,CAyqB8B,CADzC,CA8BA+S,EAAAmI,GAAA,CAAAA,QAAe,CAAC5Z,CAAD,CACf,CACSA,CAAL,EAAe,IAAA2M,EAm6DRX,MAAA+Q,EAn6DP,EACIf,EAAA,CAAAA,IAAA,CAAgB,IAAArD,EAAhB,CAFR,CAaAlH,EAAAoI,GAAA,CAAAA,QAAc,CAAC7Z,CAAD,CACd,CACQA,CAAJ,EACI,IAAAiZ,EACA,CADgB,CAAA,CAChB,CAAAmC,EAAA,CAAAA,IAAA,CAAiB,CAAA,CAAjB,CAFJ,GAII,IAAAnC,EAKA,CALgB,CAAA,CAKhB,CAJAmC,EAAA,CAAAA,IAAA,CAIA,CAAAc,EAAA,CAAAA,IAAA,CAAmB,CAAnB,CATJ,CADJ,CAqBAzK,EAAAqI,GAAA,CAAAA,QAAe,CAAC9Z,CAAD,CAAQke,CAAR,CACf,CAEQ,IAAAvF,EAAA,CADA3Y,CAAJ,CACI,IAAA2Y,EADJ,CACwB,CADxB,EAC6BuF,CAD7B,CAGI,IAAAvF,EAHJ,CAGwB,EAAE,CAAF,EAAOuF,CAAP,CAJ5B,CAuBAL,SAAA,GAAW,CAAXA,CAAW,CACX,CACI,IAAIM,EAAM,CAAV,CACIC,EAAO,CAAAxR,EAAAyR,EACNpB,EApuBE5D,EAAA,CAouBauD,EApuBb,CAouBP,EAAKK,CApuByB5D,EAAA,CAouBVuD,EApuBU,CAAA,CAAoB,CAApB,CAouB9B,GAA6CuB,CAA7C,CAAmD,CAACA,CAApD,CACOnC,GAAA,CAAAA,CAAA,CAAiB,CAAAvD,EAAjB,CAAgC,CAAC2F,CAAjC,CAA2C,CAAA3F,EAA3C,CAA0D0F,CAA1D,CAAiEC,CAAjE,CAJX;AAcApC,QAAA,GAAU,CAAVA,CAAU,CAAChc,CAAD,CACV,CACI,CAAAyY,EAAA,CAAezY,CAAf,CAAuB,CAAA4M,EAAAyR,EACvB,IAAI,CAAAxF,EAAJ,GAAqB,CAAAJ,EAArB,CAAmC,CAC/B,CAAAI,EAAA,CAAe,CAAAJ,EACUI,EAAAA,CAAAA,CAAAA,EA+C7B,KAAK,IAAIjb,EAAI,CAAb,CA/C2C0gB,EA+C3C,CAAgB1gB,CAAhB,CAA2BA,CAAA,EAA3B,CAAgC,CA/C5B2gB,IAAAA,EAAAA,CAAAA,CAgDe3M,EAhDKxR,GAgDLwR,CAAUhU,CAhDzB2gB,CAiDyB,EAAAve,CAAA,CAAS,CAAT,EAAcpC,CAjB3C,EAAAwb,EAAA,CAAUxH,CAAV,CAAA,CAAsB5R,CACjB,EAAAiZ,EAAL,EAAoBoD,EAAA,CAAAA,CAAA,CAAgBzK,CAAhB,CAA0B5R,CAA1B,CAcY,CAjDG,CAFvC,CAgBAwa,QAAA,GAAU,CAAVA,CAAU,CAACxa,CAAD,CACV,CACI,CAAA0Y,EAAA,CAAe1Y,CAAf,CAAuBwe,CACvB,IAAI,CAAA1F,EAAJ,GAAqB,CAAAJ,EAArB,CAAmC,CAC/B,CAAAI,EAAA,CAAe,CAAAJ,EACUI,EAAAA,CAAAA,CAAAA,EA8B7B,KAAK,IAAIlb,EAAI,CAAb,CA9B2C0gB,EA8B3C,CAAgB1gB,CAAhB,CAA2BA,CAAA,EAA3B,CAAgC,CA9B5B2gB,IAAAA,EAAAA,CAAAA,CA+Be3M,EA/BKxR,GA+BLwR,CAAUhU,CA/BzB2gB,CAgCyB,EAAAve,CAAA,CAAS,CAAT,EAAcpC,CAjB3C,EAAAwb,EAAA,CAAUxH,CAAV,CAAA,CAAsB5R,CACjB,EAAAiZ,EAAL,EAAoBoD,EAAA,CAAAA,CAAA,CAAgBzK,CAAhB,CAA0B5R,CAA1B,CAcY,CAhCG,CAInC,MAAO,EAAA0Y,EANX,CA+CAwD,QAAA,GAAa,CAAbA,CAAa,CAAClc,CAAD,CACb,CACI,CAAA2Y,EAAA,CAAmB3Y,CAAnB,CAA2B,CAC3B,KAASpC,CAAT,CAAa,CAAb,CAAoB,EAApB,CAAgBA,CAAhB,CAAwBA,CAAA,EAAxB,CACI,CAAAyb,EAAA,CAAc,GAAd,CAAkBzb,CAAlB,CAAA,CAAqB,CAArB,CAAA,CAA2B,CAAA+a,EAAD,CAAqB,CAArB,EAA0B/a,CAA1B,CAA+B,CAA/B,CAAmC,CAKjEyd,GAAA,CAAAA,CAAA,CACA,OAAO,CAAA,CATX,CAqBA5J,CAAA8I,KAAA,CAAAA,QAAI,EACJ,CACIyB,EAAA,CAAAA,IAAA,CAAgB,IAAArP,EAonGT8R,EApnGP,CADJ,CAqGAC;QAAO,GAAI,EACX,CAEI,IADA,IAAIC,EAAWrQ,CAAA,CAA6BsQ,QAA7B,CAAuCxQ,CAAvC,CAAuD,OAAvD,CAAf,CACSyQ,EAAO,CAAhB,CAAmBA,CAAnB,CAA4BF,CAAAld,OAA5B,CAA6Cod,CAAA,EAA7C,CAAuD,CACnD,IAAIC,EAASH,CAAA,CAASE,CAAT,CAAb,CACIxG,EAAapJ,EAAA,CAA4B6P,CAA5B,CADjB,CAEIlE,EAAQmE,EAAA,CAA2B1G,CAAA,GAA3B,CACPuC,EAAL,GAAYA,CAAZ,CAAoB,IAAIxC,EAAJ,CAAeC,CAAf,CAA2B,CAAA,CAA3B,CAApB,CACA2G,GAAA,CAAgCpE,CAAhC,CAAuCkE,CAAvC,CALmD,CAF3D,CAaAG,IAAAA,GAAYA,CAAZA,CAaAC,GAAQA,KAbRD,CAcAE,GAAQA,QAdRF,CAeAG,GAAQA,MAfRH,CAgBAI,GAAQA,MAMZC,GAAA,CAAW/D,EAAX,CA4DIjQ,SApBEiU,GAoBS,CAACC,CAAD,CAAW7S,CAAX,CAAgBD,CAAhB,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,KAAN,CAAa8S,CAAb,CAp0CQvI,EAo0CR,CAEA,KAAAtK,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CAMX,KAAA+S,EAAA,CAAiB,CAACD,CAAA,SAAlB,EAA0C,EAS1C,KAAAE,EAAA,CAAiB,CAAjB,EAAsB,IAAAD,EACtB,KAAApB,EAAA,CAAiB,IAAAqB,EAAjB,CAAkC,CAElC,KAAAC,EAAA,CAAmB9f,IAAA+f,KAAA,CADDC,KACC,CAGnB,KAAAC,EAAA,CAAoB,IAAAJ,EAApB,CAJkBG,KAIlB,CAAwD,CAIxD,KAAAE,EAAA,CAAsB,CAMtB,KAAAC,EAAA,CAAkB,EAmBdC,EAAAA,CAAQ,IAAIC,EAAJ,CAdZC,IAcY,CACZC,GAAA,CAAAH,CAAA,CAfAE,IAesBzT,EAAtB,CAfAyT,KAiBAH,EAAA,CAAsB3Z,KAAJ,CAjBlB8Z,IAiB4BL,EAAV,CAClB,KAASO,CAAT,CAAkB,CAAlB,CAAqBA,CAArB,CAlBAF,IAkB8BL,EAA9B,CAAgDO,CAAA,EAAhD,CAlBAF,IAmBIH,EAAA,CAAgBK,CAAhB,CAAA,CAA0BJ,CAjB9BpN,GAAA,CAAAA,IAAA,CA1CJ,CArBmBsH,EAAA5O,CAAjBgU,EAAiBhU,CAAAA,CAAAA,CAyFnB,EAAA,CAxwLJ,EAAA+U,UAwwLI7O,EAAA4I,MAAA,CAAAA,QAAK,EACL,EAsBA5I;CAAAyB,GAAA,CAAAA,QAAO,CAACjN,CAAD,CAAOqV,CAAP,CACP,CACI,GAAI,CAACA,CAAL,CACI,GAAI,CAACrV,CAAL,CACI,IAAAoU,MAAA,EADJ,KAGI,IAAI,CAAC,IAAAmB,QAAA,CAAavV,CAAb,CAAL,CAAyB,MAAO,CAAA,CAGxC,OAAO,CAAA,CARX,CAmBAwL,EAAA0B,GAAA,CAAAA,QAAS,CAACC,CAAD,CACT,CACI,MAAOA,EAAA,CAAO,IAAAqI,KAAA,EAAP,CAAqB,CAAA,CADhC,CAUAhK,EAAAgK,KAAA,CAAAA,QAAI,EACJ,CACI,IAAIC,EAAQ,IAAIC,CAAJ,CAAU,IAAV,CACZD,EAAAE,IAAA,CAAU,CAAV,CAAa2E,EAAA,CAAAA,IAAA,CAAb,CACA,OAAO7E,EAAAzV,KAAA,EAHX,CAaAwL,EAAA+J,QAAA,CAAAA,QAAO,CAACvV,CAAD,CACP,CAwaA,CAAA,CAAA,CAva8B,CAAA,CAAAA,CAAA,CAAK,CAAL,CAwa1B,KAAIrI,CACJ,KAAKA,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgBR,CAAAqE,OAAhB,CAA2B,CAA3B,CAA8B7D,CAA9B,EAAmC,CAAnC,CAAsC,CAClC,IAAIyiB,EAASjjB,CAAA,CAAEQ,CAAF,CAAb,CACI4iB,EAAMpjB,CAAA,CAAEQ,CAAF,CAAI,CAAJ,CACV,IAAI4iB,CAAJ,EA/hBaC,IA+hBb,CAAWD,CAAA/e,OAAX,CAAA,CAm5pBJ,IAHA,IAAIif,EAAO,CAAX,CACIC,EAAWta,KAAJ,CAh7qBMoa,IAg7qBN,CADX,CAEIG,EAAQ,CACZ,CAAOA,CAAP,CAAeC,CAAApf,OAAf,CAA8B,CAA9B,CAAA,CAGI,IAFA,IAAInE,EAAIujB,CAAA,CAAMD,CAAA,EAAN,CAAR,CACI3iB,EAAI4iB,CAAA,CAAMD,CAAA,EAAN,CACR,CAAOtjB,CAAA,EAAP,CAAA,CACIqjB,CAAA,CAAKD,CAAA,EAAL,CAAA,CAAeziB,CAIvB,EAAA,CAAO0iB,CA35pBH,CAGIV,CAAAA,CA/aDa,IA+aSd,EAAA,CAAgBK,CAAhB,CACZ,IAAI,CAACJ,CAAL,EAAc,CAACA,CAAAzE,QAAA,CAAcgF,CAAd,CAAf,CAAmC,CAlyGvCja,CAAA,CAwyGwB,iCAxyGxB,CAwyG4D8Z,CAxyG5D,CAyyGQ,EAAA,CAAO,CAAA,CAAP,OAAA,CAP+B,CAPD,CAiBtC,CAAA,CAAO,CAAA,CAnBX,CAvaI,MAAO,EADX,CAiCAU;QAAA,GAAS,CAATA,CAAS,CAACC,CAAD,CAAOC,CAAP,CAAard,CAAb,CACT,CAKI,IAJA,IAAIsd,EAAWF,CAAf,CACIG,EAAWF,CADf,CAEIZ,EAASa,CAATb,GAAsB,CAAAV,EAE1B,CAAkB,CAAlB,CAAOwB,CAAP,EAAuBd,CAAvB,CAAgC,CAAAL,EAAAve,OAAhC,CAAA,CAAwD,CAEpD,IAAIwe,EAAQ,CAAAD,EAAA,CAAgBK,CAAhB,CAAZ,CACIe,EA9JUvB,KA8JVuB,CAAYf,CADhB,CAEIgB,EA/JUxB,KA+JVwB,EAA+BH,CAA/BG,CAA0CD,CAA1CC,CACAA,EAAJ,CAAgBF,CAAhB,GAA0BE,CAA1B,CAAsCF,CAAtC,CAEA,IAAIlB,CAAJ,EAAaA,CAAAgB,KAAb,CAAyB,CACrB,GAAIhB,CAAArc,KAAJ,EAAkBA,CAAlB,CAAwB,CAOpB,GAAIsd,CAAJ,CAAeC,CAAf,EAA2BlB,CAAAe,EAA3B,CAGI,MAFAf,EAAAqB,GAEO,EAFQrB,CAAAe,EAER,CAFqBE,CAErB,CADPjB,CAAAe,EACO,CADME,CACN,CAAA,CAAA,CAEX,IAAIA,CAAJ,EAAgBjB,CAAAe,EAAhB,CAA6Bf,CAAAqB,GAA7B,CAAyC,CACjCC,CAAAA,CAAYtB,CAAAgB,KAAZM,EAA0BL,CAA1BK,CAAqCH,CAArCG,CACAA,EAAJ,CAAgBJ,CAAhB,GAA0BI,CAA1B,CAAsCJ,CAAtC,CACAlB,EAAAqB,GAAA,CAAaJ,CAAb,CAAwBjB,CAAAe,EAAxB,CAAqCO,CACrCL,EAAA,CAAWE,CAAX,CAnLEvB,KAoLFsB,EAAA,EAAYI,CACZlB,EAAA,EACA,SAPqC,CAZrB,CAsBxB,MAAOmB,GAAA,CAAiBC,EAAjB,CAA6CP,CAA7C,CAAuDC,CAAvD,CAvBc,CA0BrBO,CAAAA,CAAW,IAAIxB,EAAJ,CAAgB,CAAhB,CAAsBgB,CAAtB,CAAgCG,CAAhC,CA5LDxB,KA4LC,CAA4Djc,CAA5D,CACfwc,GAAA,CAAAsB,CAAA,CAAyB,CAAAhV,EAAzB,CAAmCuT,CAAnC,CACA,EAAAD,EAAA,CAAgBK,CAAA,EAAhB,CAAA,CAA4BqB,CAE5BR,EAAA,CAAWE,CAAX,CAhMcvB,KAiMdsB,EAAA,EAAYE,CAtCwC,CAyCxD,MAAgB,EAAhB,EAAIF,CAAJ,EACI,CAAA5c,OAAA,CAAY,QAAZ,EAAwB0c,CAAxB,EAAgC,EAAhC,EAAsC,KAAtC,CAA8CU,EAAA,CAAuB/d,CAAvB,CAA9C,CAA6E,MAA7E,CAAsFge,EAAA,CAAUZ,CAAV,CAAtF,CACO,CAAA,CAAA,CAFX,EAKOQ,EAAA,CAAiBK,EAAjB,CAA+Cb,CAA/C,CAAqDC,CAArD,CAnDX;AAuQAjD,QAAA,GAAa,CAAbA,CAAa,CAACgD,CAAD,CACb,CAGI,IAAIf,EAAQ6B,CAhBL9B,EAAA,EAgByBgB,CAhBzB,CAgBKc,CAhBmBzD,EAAxB,IAgBKyD,CAhBsCnC,EAA3C,CAiBP,EAAAI,EAAA,EACArhB,EAAA,CAAIuhB,CAAA8B,EAAA,CAHMf,CAGN,CAhaegB,KAgaf,CAA0BhB,CAA1B,CACJ,EAAAjB,EAAA,EACA,OAAOrhB,EAPX,CAmBAof,QAAA,GAAa,CAAbA,CAAa,CAACkD,CAAD,CAAOtiB,CAAP,CACb,CAEI,IAAIuhB,EAAQ6B,CAnCL9B,EAAA,EAmCyBgB,CAnCzB,CAmCKc,CAnCmBzD,EAAxB,IAmCKyD,CAnCsCnC,EAA3C,CAoCP,EAAAI,EAAA,EACAE,EAAAgC,EAAA,CAAsBvjB,CAAtB,CAHUsiB,CAGV,CAnbmBgB,KAmbnB,CAA8BhB,CAA9B,CACA,EAAAjB,EAAA,EALJ,CA8BAmC,QAAA,GAAc,CAAdA,CAAc,CAAClB,CAAD,CAAOmB,CAAP,CACd,CAGQC,CAAAA,CAAAA,CAAApC,EAAAoC,CADapB,CACboB,GADsBA,CAAAzC,EACtByC,CAAkED,EA2oBtE,CAQqC,CARrC,GAQQ,EAAE,CAAAE,EARV,GASQC,CAzDRvE,EAgDA,CASQuE,CAzDSC,EAAA,CAyDTD,CAzDyBE,GAAhB,CAyDTF,CAzD0CL,EAgDlD,EACoC,CADpC,GACQ,EAAE,CAAAQ,EADV,GAEQC,CA5DRzE,EA0DA,CAEQyE,CA5DQX,EA0DhB,CA9oBJ,CAoCAxB,QAAA,GAAU,CAAVA,CAAU,CACV,CAII,IAHA,IAAI3iB,EAAI,CAAR,CACIR,EAAI,EADR,CAGSijB,EAAS,CAAlB,CAAqBA,CAArB,CAA8B,CAAAP,EAA9B,CAAgDO,CAAA,EAAhD,CAA0D,CACtD,IAAIJ,EAAQ,CAAAD,EAAA,CAAgBK,CAAhB,CAMZ,IAAkDJ,CAAA0C,GAAlD,EAAkE1C,CAAA2C,GAAlE,CAAoF,CAChFxlB,CAAA,CAAEQ,CAAA,EAAF,CAAA,CAASyiB,CACP,KAAA,EAAAziB,CAAA,EAm5pBV,IAn5pBgC,CAm5pBhC,CAn5pBgCqiB,CAAAxE,KAAA,EAm5pBhC,CAAU,CAIN,IAHA,IAAIoH,EAAO,CAAX,CACIjC,EAAQ,CADZ,CAEIC,EAAQ,EACZ,CAAOgC,CAAP,CAAcC,CAAArhB,OAAd,CAAA,CAA2B,CAIvB,IAHA,IAAIxD,EAAI6kB,CAAA,CAAKD,CAAL,CAAR,CAEIE,EAAWF,CAAXE,CAAkB,CACtB,CAAOA,CAAP,CAAkBD,CAAArhB,OAAlB,EAAiCqhB,CAAA,CAAKC,CAAL,CAAjC,GAAoD9kB,CAApD,CAAA,CAAuD8kB,CAAA,EACvDlC,EAAA,CAAMD,CAAA,EAAN,CAAA,CAAiBmC,CAAjB,CAA4BF,CAC5BhC,EAAA,CAAMD,CAAA,EAAN,CAAA,CAAiB3iB,CACjB4kB,EAAA,CAAOE,CAPgB,CASvBlC,CAAApf,OAAJ,CAAmBqhB,CAAArhB,OAAnB,GAAgC,CAAhC,CAAuCof,CAAvC,CAbM,CAn5pBFzjB,CAAA,CAAE,CAAF,CAAA,CAAS,CAFuE,CAP9B,CAa1D,MAAOA,EAjBX;AAyFAqU,CAAAuR,GAAA,CAAAA,QAAK,CAAChC,CAAD,CACL,CAEI,GAAI,CAAC,IAAAjB,EAAL,CAmqFA,KAlqFoB,KAAArT,EAkqFb,EAlqFyB4G,EAAA,CAAA,IAAA5G,EAAA,CA76DxBqK,CA66DwB,CAkqFzB,EAjqFCvD,EAAA,CAAA,IAAA9G,EAAA,CAAsB,kBAAtB,CAA2CuW,CAAA,CAAA,IAAAvW,EAAA,CAAmBsU,CAAnB,CAA3C,CAAqE,CAAA,CAArE,CAA2E,CAAA,CAA3E,CAiqFD,CADP5D,CAAA,CA9pFI,IAAAzQ,EA8pFJ,CACO,CAAA,EAAP,CArqFJ,CAmCA6U,SAAA,GAAW,CAAC0B,CAAD,CAASlC,CAAT,CAAeC,CAAf,CACX,CAj3GI1a,CAAA,CAk3Ga,sBAl3Gb,CAk3GsC2c,CAl3GtC,CAk3G+C,IAl3G/C,CAk3GsDC,CAAA,CAAUnC,CAAV,CAl3GtD,CAk3GwE,GAl3GxE,CAk3G8EmC,CAAA,CAAUlC,CAAV,CAl3G9E,CAk3GgG,GAl3GhG,CA43GA,OAAO,CAAA,CAXX,CAgBAmC,IAAAA,GAAoBA,CAApBA,CACAC,GAAoBA,CAgBpB/X,SANEgY,GAMS,CAACC,CAAD,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,QAAN,CAAgBA,CAAhB,CA3+DQlM,GA2+DR,CADJ,CAPsB8C,EAAA5O,CAApB+X,EAAoB/X,CAAAA,CAAAA,CAoBtB,EAAA,CA53MJ,EAAAiY,UA43MI/R,EAAA0J,GAAA,CAAAA,QAAO,CAACtO,CAAD,CAAMD,CAAN,CAAWD,CAAX,CAAgBD,CAAhB,CACP,CACI,IAAAE,EAAA,CAAWA,CACX,KAAAC,EAAA,CAAWA,CACX,KAAAF,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CAEXmG,GAAA,CAAAA,IAAA,CANJ,CAiBApB,EAAAyB,GAAA,CAAAA,QAAO,CAACjN,CAAD,CAAOqV,CAAP,CACP,CACI,GAAI,CAACA,CAAL,CACI,GAAI,CAACrV,CAAL,CACI,IAAAoU,MAAA,EADJ,KAGI,IAAI,CAAC,IAAAmB,QAAA,CAAavV,CAAb,CAAL,CAAyB,MAAO,CAAA,CAGxC,OAAO,CAAA,CARX,CAmBAwL,EAAA0B,GAAA,CAAAA,QAAS,CAACC,CAAD,CACT,CACI,MAAOA,EAAA,CAAO,IAAAqI,KAAA,EAAP,CAAqB,CAAA,CADhC,CASAhK,EAAA4I,MAAA,CAAAA,QAAK,EACL,EAWA5I;CAAAgK,KAAA,CAAAA,QAAI,EACJ,CAEI,MAAOxV,CADKyV,IAAIC,CAAJD,CAAU,IAAVA,CACLzV,MAAA,EAFX,CAcAwL,EAAA+J,QAAA,CAAAA,QAAO,EACP,CACI,MAAO,CAAA,CADX,CAgCJ8D,GAAA,CApBIZ,QAAW,EACX,CAEI,IADA,IAAI+E,EAAWnV,CAAA,CAA6BsQ,QAA7B,CAAuCxQ,CAAvC,CAAuD,QAAvD,CAAf,CACSsV,EAAU,CAAnB,CAAsBA,CAAtB,CAAgCD,CAAAhiB,OAAhC,CAAiDiiB,CAAA,EAAjD,CAA4D,CACxD,IACIC,EAAUF,CAAA,CAASC,CAAT,CACVH,KAAAA,EAActU,EAAA,CAA4B0U,CAA5B,CAClB,QAAOJ,CAAA,KAAP,EACA,KAAK,SAAL,CACIK,CACA,CADS,IAAIN,EAAJ,CAAgBC,CAAhB,CACT,CAAAvE,EAAA,CAAgC4E,CAAhC,CAAwCD,CAAxC,CAHJ,CAJwD,CAFhE,CAmBJ,CAoDIrY;QA1BE4U,GA0BS,CAACtT,CAAD,CAAMoU,CAAN,CAAYM,CAAZ,CAAkBL,CAAlB,CAAwBrd,CAAxB,CACX,CAEI,IAAAgJ,EAAA,CAAWA,CACX,KAAAlB,GAAA,CAAWmY,EAAX,EAAkC,CAGlC,KAAA7C,EAAA,CAAYA,CACZ,KAAAM,GAAA,CAAYA,CACZ,KAAAL,KAAA,CAAYA,CAAZ,EAAoB,CACpB,KAAArd,KAAA,CAAYA,CAAZ,EAAoBkgB,EACpB,KAAAvB,EAAA,CAAkB3e,CAAlB,EAA0BmgB,EAC1B,KAAArX,EAAA,CAAW,IACX,KAAAuR,EAAA,CAAgB,IAAA8D,EAAhB,CAAsC,IAAAiC,GACtC,KAAAjG,EAAA,CAAiB,IAAAkE,EAAjB,CAAwC,IAAAO,GACxC,KAAAC,EAAA,CAAwB,IAAAJ,EAAxB,CAAiD,CACjDjC,GAAA,CAAAA,IAAA,CASA,KAAAuC,GAAA,CAAc,IAAAC,GAAd,CAAgC,CAAA,CAKhC,IAAK,IAAA3B,KAAL,CAAA,CAaA7jB,CAAA,CAAI,IAAA6mB,EAAJ,CAAkB5d,KAAJ,CAAU,IAAA4a,KAAV,CACd,KAAKrjB,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgBR,CAAAqE,OAAhB,CAA0B7D,CAAA,EAA1B,CAA+BR,CAAA,CAAEQ,CAAF,CAAA,CAAO,CACtCsmB,GAAA,CAAAA,IAAA,CAAeC,EAAf,CAfA,CAAA,IACID,GAAA,CAAAA,IAAA,CA9BR,CAmGA,CAAA,CAhoNJ,EAAAE,UAgoNI3S,EAAAgK,KAAA,CAAAA,QAAI,EACJ,CACI,MAAO,KAAAwI,EADX,CAeAxS,EAAA+J,QAAA,CAAAA,QAAO,CAACyI,CAAD,CACP,CACI,MAAIA,EAAJ,EAAU,IAAAhD,KAAV,EAAuBgD,CAAAxiB,OAAvB,EACI,IAAAwiB,EACA,CADUA,CACV,CAAA,IAAAtB,GAAA,CAAc,CAAA,CAFlB,EAKO,CAAA,CANX,CA0DAuB,SAAA,GAAS,CAATA,CAAS,CAAC3Z,CAAD,CACT,CACSA,CAAL,GAEIA,CAFJ,CAEU8Z,EAFV,CAIAC,GAAA,CAAAA,CAAA,CAAmB/Z,CAAnB,CANWga,IAAAA,EAMX,CACAC,GAAA,CAAAA,CAAA,CAAoBja,CAApB,CAPWga,IAAAA,EAOX,CANJ;AAgBAD,QAAA,GAAa,CAAbA,CAAa,CAAC/Z,CAAD,CAAMga,CAAN,CACb,CACSA,CAAL,EAAiB,CAAA9B,EAAjB,GACI,CAAAxE,EADJ,CACoB1T,CAAA,CAAI,CAAJ,CADpB,EAC8B,CAAAyZ,GAD9B,CAGA,IAAIO,CAAJ,EAA2BjiB,IAAAA,EAA3B,GAAeiiB,CAAf,CACI,CAAAxC,EAAA,CAAsBxX,CAAA,CAAI,CAAJ,CAAtB,EAAgC,CAAAyZ,GALxC,CAgBAQ,QAAA,GAAc,CAAdA,CAAc,CAACja,CAAD,CAAMga,CAAN,CACd,CACSA,CAAL,EAAiB,CAAAlC,EAAjB,GACI,CAAAtE,EADJ,CACqB,CAAC,CAAAwE,EADtB,EACwChY,CAAA,CAAI,CAAJ,CADxC,EACkD,CAAAiY,GADlD,CAGA,IAAI+B,CAAJ,EAA2BjiB,IAAAA,EAA3B,GAAeiiB,CAAf,CACI,CAAAtC,EAAA,CAAuB1X,CAAA,CAAI,CAAJ,CAAvB,EAAiC,CAAAiY,GALzC,CAiDA/Q,CAAAgT,GAAA,CAAAA,QAAa,CAACC,CAAD,CAAMvC,CAAN,CACb,CACSA,CAAL,CAOqC,CAPrC,GAOQ,IAAAE,EAAA,EAPR,EAQQmC,EAAA,CAAAA,IAAA,CAAoBG,EAApB,CAA4C,CAAA,CAA5C,CARR,CACoC,CADpC,GACQ,IAAAlC,EAAA,EADR,EAEQ6B,EAAA,CAAAA,IAAA,CAAmBK,EAAnB,CAA2C,CAAA,CAA3C,CAHZ,CA+CAvE,SAAA,GAAe,CAAfA,CAAe,CAAC1T,CAAD,CAAMkY,CAAN,CACf,CACI,CAAAlY,EAAA,CAAWA,CACX,EAAA+V,EAAA,CAAwB,CAAAJ,EAAxB,CAAiD,CAC7CuC,EAAJ,GAII,CAHK,CAAAnC,EAGL,CAH6BmC,CAAAnC,EAG7B,GAFI6B,EAAA,CAAAA,CAAA,CAAmBK,EAAnB,CAA2C,CAAA,CAA3C,CAEJ,EAAK,CAAAtC,EAAL,CAA8BuC,CAAAvC,EAA9B,GACImC,EAAA,CAAAA,CAAA,CAAoBG,EAApB,CAA4C,CAAA,CAA5C,CALR,CAHJ,CAqBAlT,CAAAuS,GAAA,CAAAA,QAAQ,CAACU,CAAD,CAAM1D,CAAN,CACR,CACoB,IAAAtU,EAAhB,EAA4B4G,EAAA,CAAA,IAAA5G,EAAA,CAr+EpBwK,EAq+EoB,CAA5B,EACI1D,EAAA,CAAA,IAAA9G,EAAA,CAAsB,kCAAtB,CAA2DuW,CAAA,CAAA,IAAAvW,EAAA,CAAmBsU,CAAnB,CAA3D,CAAqF,CAAA,CAArF,CAEJ,KAAApU,EAAAoW,GAAA,CAAehC,CAAf,CACA,OAnqFa6D,EA8pFjB,CAgBApT;CAAA+Q,GAAA,CAAAA,QAAS,CAAC/jB,CAAD,CAAIimB,CAAJ,CAAS1D,CAAT,CACT,CACoB,IAAAtU,EAAhB,EAA4B4G,EAAA,CAAA,IAAA5G,EAAA,CAt/EpBwK,EAs/EoB,CAA5B,EACI1D,EAAA,CAAA,IAAA9G,EAAA,CAAsB,mBAAtB,CAA4CuW,CAAA,CAAA,IAAAvW,EAAA,CAAmBjO,CAAnB,CAA5C,CAAoE,wBAApE,CAA+FwkB,CAAA,CAAA,IAAAvW,EAAA,CAAmBsU,CAAnB,CAA/F,CAAyH,CAAA,CAAzH,CAEJ,KAAApU,EAAAoW,GAAA,CAAehC,CAAf,CAJJ,CAeAvP,EAAAqT,GAAA,CAAAA,QAAc,CAACJ,CAAD,CACd,CAGI,MAFQ,KAAAT,EAAAvlB,CAAQgmB,CAARhmB,CADZ,CAcA+S,EAAAsT,GAAA,CAAAA,QAAe,CAACrmB,CAAD,CAAIgmB,CAAJ,CACf,CAEQ,IAAAT,EAAA,CAAQS,CAAR,CAAJ,EAAoBhmB,CAApB,GACI,IAAAulB,EAAA,CAAQS,CAAR,CACA,CADehmB,CACf,CAAA,IAAAikB,GAAA,CAAc,CAAA,CAFlB,CAFJ,CAgBAlR,EAAAuT,GAAA,CAAAA,QAAe,CAACN,CAAD,CAAM1D,CAAN,CACf,CACI,GAAgB,IAAAtU,EAAhB,EAAyC,IAAzC,EAA4B,IAAAsU,EAA5B,CAAA,CACItU,IAAAA,EAAAA,IAAAA,EAggcAuY,GAAA,CAAAA,CAAA,CAhgcyB,IAAAjE,EAggczB,CAhgcqC0D,CAggcrC,CAhgc0CQ,CAggc1C,CAAoC,CAAAC,EAApC,CAAJ,EACI/H,EAAA,CAAAA,CAAA,CAAa,CAAA,CAAb,CAlgcJ,CAGA,MAAO,KAAA2E,EAAA,CAAoB2C,CAApB,CAAyB1D,CAAzB,CAJX,CAeAvP,EAAA2T,GAAA,CAAAA,QAAgB,CAAC1mB,CAAD,CAAIgmB,CAAJ,CAAS1D,CAAT,CAChB,CACI,GAAgB,IAAAtU,EAAhB,EAAyC,IAAzC,EAA4B,IAAAsU,EAA5B,CAAA,CACItU,IAAAA,EAAAA,IAAAA,EAygcAuY,GAAA,CAAAA,CAAA,CAzgc0B,IAAAjE,EAygc1B,CAzgcsC0D,CAygctC,CAzgc2CQ,CAygc3C,CAAoC,CAAAG,EAApC,CAAJ,EACIjI,EAAA,CAAAA,CAAA,CAAa,CAAA,CAAb,CA3gcJ,CAGI,IAAAmF,EAAJ,CAAoB,IAAAC,GAAA,CAAe9jB,CAAf,CAAkBgmB,CAAlB,CAAuB1D,CAAvB,CAApB,CAAuD,IAAAiB,EAAA,CAAqBvjB,CAArB,CAAwBgmB,CAAxB,CAA6B1D,CAA7B,CAJ3D,CAiBAsE;IAAAA,GAAYA,CAAZA,CAEAlO,GAAYA,CAFZkO,CAKJ3D,GAA0B,CAAC,MAAD,CAAU,KAAV,CAAkB,KAAlB,CALtB2D,CAUJzB,GAAsB,CAVlByB,CAqBJjB,GAAsB,EArBlBiB,CAuBJnB,GAAwB,CACpBjE,EAAAle,UAAA8iB,GADoB,CAEpB5E,EAAAle,UAAA+iB,GAFoB,CAvBpBO,CA4BJX,GAAyB,CACrBzE,EAAAle,UAAAgjB,GADqB,CAErB9E,EAAAle,UAAAojB,GAFqB,CAgDrB9Z;QAhCEia,GAgCS,CAACC,CAAD,CAAWC,CAAX,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,KAAN,CAAaD,CAAb,CAzpFQ3O,CAypFR,CAEI6O,EAAAA,CAAU,CAACF,CAAA,OAAXE,EAAiCD,CAErC,KAAIE,EAAc,CAACH,CAAA,WAAfG,EAAyC,CAE7C,KAAApN,GAAA,CAAqB,CAErB,KAAAqN,GAAA,CAAwBF,CAOxB,KAAAG,GAAA,CAAyBF,CACzB,KAAAG,GAAA,CAAkBjmB,IAAAkmB,MAAA,CAAW,IAAAH,GAAX,CAAmC,GAAnC,CAAlB,CAA8D,GAC9D,KAAAI,GAAA,CAAiB,IAAAF,GAAjB,CAAmC,IAAAD,GACnC,KAAAI,GAAA,CAAkB,IAAAC,GAAlB,CAAyC,IAAAC,GAAzC,CAAiE,IAAAC,GAAjE,CAAsF,CAKtF,KAAApa,MAAA+Q,EAAA,CAAqB,IAAA/Q,MAAAqa,GAArB,CAA2C,CAAA,CAC3C,KAAAra,MAAAsa,GAAA,CAAuBd,CAAA,UACY,SAAnC,EAAI,MAAO,KAAAxZ,MAAAsa,GAAX,GAA6C,IAAAta,MAAAsa,GAA7C,CAA6F,MAA7F,EAAqE,IAAAta,MAAAsa,GAArE,CAWA,KAAAta,MAAAua,GAAA,CAAsB,CAAA,CACtB,KAAAC,GAAA,CAAiB,IAAAC,GAAjB,CAA4C,CAC5C,KAAAC,GAAA,CAA4B,CAAClB,CAAA,QAC7B,KAAAmB,GAAA,CAA+B,CAACnB,CAAA,WAChC,KAAAoB,GAAA,CAA2B,CAACpB,CAAA,OAK5B,KAAAqB,EAAA,CAAe,EAEf,KAAAC,GAAA,CAAoB,IAAAC,GAAAlS,KAAA,CAAiB,IAAjB,CAQpB,KAAAmS,EAAA,CAAoB,IAAAC,EAApB,CAAsC,IAAAC,EAAtC,CAA0D,IAAAC,EAA1D,CADA,IAAAC,EACA,CADkB,IAAAC,GAClB;AADwC,IAAAC,EACxC,CAD4D,IAAAC,GAC5D,CAFA,IAAAC,GAEA,CAHA,IAAAC,EAGA,CAHW,CAIX,KAAA7M,GAAA,CAAa,IAEb/H,GAAA,CAAAA,IAAA,CA3DJ,CAjCmBsH,EAAA5O,CAAjBga,EAAiBha,CAAAA,CAAAA,CAwGnB,EAAA,CA5lOJ,EAAAmc,UA4lOIjW,EAAA0J,GAAA,CAAAA,QAAO,CAACtO,CAAD,CAAMD,CAAN,CAAWD,CAAX,CAAgBD,CAAhB,CACP,CACI,IAAAG,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CACX,KAAAF,EAAA,CAAWA,CACX,KAAAkO,GAAA,CAAa/N,CAAA+N,EACb,KAAShd,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoB+pB,EAAAlmB,OAApB,CAA6C7D,CAAA,EAA7C,CAEI,CADIiQ,CACJ,CADc,IAAAhC,EAAA,CAAc+b,EAAA,CAAiBhqB,CAAjB,CAAd,CACd,GAAa,IAAAiP,EAAAqC,GAAA,CAAoB,IAApB,CAA0B0Y,EAAA,CAAiBhqB,CAAjB,CAA1B,CAA+CiQ,CAA/C,CAEjBgF,GAAA,CAAAA,IAAA,CATJ,CAmBApB,EAAA4I,MAAA,CAAAA,QAAK,EACL,EAWA5I,EAAAgK,KAAA,CAAAA,QAAI,EACJ,CACI,MAAO,KADX,CAaAhK,EAAA+J,QAAA,CAAAA,QAAO,EACP,CACI,MAAO,CAAA,CADX,CAYA/J;CAAAyB,GAAA,CAAAA,QAAO,CAACjN,CAAD,CAAOqV,CAAP,CACP,CAII,IAAIuM,EAAaC,EAAA,CAAA,IAAAjb,EAAA,CAAwB,WAAxB,CACC,KAAlB,EAAIgb,CAAJ,CACI,IAAA7b,MAAAsa,GADJ,CAC0C,MAAd,EAAAuB,CAAA,CAAsB,CAAA,CAAtB,CAA6C,OAAf,EAAAA,CAAA,CAAwB,CAAA,CAAxB,CAAgC,CAAC,CAACA,CAD5F,CAGiC,IAHjC,EAGS,IAAA7b,MAAAsa,GAHT,GAQI,IAAAta,MAAAsa,GARJ,CAQ0C,CAAC,IAAA5Z,EAR3C,EAQiFpK,IAAAA,EARjF,GAQwD,IAAAuJ,EAAA,IARxD,CAWA,IAAI,CAACyP,CAAL,CAAe,CACX,GAAKrV,CAAL,CAEO,CACH8hB,EAAA,CAAAA,IAAA,CACA,IAAI,CAAC,IAAAvM,QAAA,CAAavV,CAAb,CAAL,CAAyB,MAAO,CAAA,CAChC+hB,GAAA,CAAAA,IAAA,CAHG,CAFP,IACI,KAAA3N,MAAA,EASY,KAAA3N,EAAhB,EACIA,CAi6ZR,CAj6ZQA,IAAAA,EAi6ZR,CAj6ZsB4Z,CAi6ZtB,CAj6ZsBA,IAAAta,MAAAsa,GAi6ZtB,CAJA,CAAA2B,GAIA,CAJa,CAAA,CAIb,CAHA,CAAAhW,EAAA,CAAa,8CAAb,CAGA,CAFAiW,EAAA,CAAAA,CAAA,CAEA,CADKC,CACL,EADiBC,EAAA,CAAAA,CAAA,CACjB,CAAI,CAAAC,GAAJ,GACQC,CAEJ,CAFY,CAAAD,GAEZ,CADA,CAAAA,GACA,CADqB,IACrB,CAAAE,EAAA,CAAAA,CAAA,CAAgBD,CAAhB,CAAuB,CAAA,CAAvB,CAHJ,CAl6ZI,EAGI,IAAA/jB,OAAA,CAAY,sBAAZ,CAEC,KAAAyH,MAAAsa,GAAL,EACI,IAAArU,EAAA,CAAa,+BAAb,EAAgD,IAAA2I,GAAA,CAAY,sBAAZ;AAAqC,sBAArF,EAjBO,CA0Bf,MAAO,CAAA,CA1CX,CAqDAnJ,EAAA0B,GAAA,CAAAA,QAAS,CAACC,CAAD,CACT,CACI,MAAOA,EAAA,CAAO,IAAAqI,KAAA,EAAP,CAAqB,CAAA,CADhC,CAUAhK,EAAA6U,GAAA,CAAAA,QAAS,EACT,CACI,MAAI,KAAAta,MAAA+Q,EAAJ,CACW,CAAA,CADX,CAGI,IAAA/Q,MAAAsa,GAAJ,EAMInJ,EAAA,CAAAA,IAAA,CACO,CAAA,CAAA,CAPX,EASO,CAAA,CAbX,CAkDA1L,EAAA+W,GAAA,CAAAA,QAAW,EACX,CACI,MAAO,EADX,CAcAR,SAAA,GAAa,CAAbA,CAAa,CACb,CACsC1lB,IAAAA,EAAlC,GAAI,CAAAokB,GAAJ,GAA6C,CAAAA,GAA7C,CAAyE,CAAzE,CACqCpkB,KAAAA,EAArC,GAAI,CAAAqkB,GAAJ,GAAgD,CAAAA,GAAhD,CAAgF,EAAhF,CACiCrkB,KAAAA,EAAjC,GAAI,CAAAskB,GAAJ,GAA4C,CAAAA,GAA5C,CAAwE,EAAxE,CACA,EAAA5a,MAAAua,GAAA,CAAoD,CAApD,EAAuB,CAAAG,GAAvB,EAAwF,CAAxF,CAAyD,CAAAC,GACrD,EAAA3a,MAAAua,GAAJ,GACI,CAAAC,GACA,CADiB,CACjB,CAAA,CAAAC,GAAA,CAA2B,CAAAC,GAA3B,CAAuD,CAAAM,EAF3D,CALJ;AA4BAvJ,QAAA,GAAc,CAAdA,CAAc,CAACiI,CAAD,CACd,CACI,GAAI,CAAA1Z,MAAAua,GAAJ,CAAyB,CAIrB,IAAIkC,EAAW,CAAA,CACf,EAAAjC,GAAA,CAAkB,CAAAA,GAAlB,CAAmC,CAAAgC,GAAA,EAAnC,CAAuD,CACvD,EAAA/B,GAAA,EAA4Bf,CACI,EAAhC,EAAI,CAAAe,GAAJ,GACI,CAAAA,GACA,EAD4B,CAAAE,GAC5B,CAAA8B,CAAA,CAAW,CAAA,CAFf,CAIgC,EAAhC,EAAI,CAAA7B,GAAJ,EACQ,CAAAA,GADR,EACoC8B,EAAA,CAAAA,CAAA,CADpC,GAEQ,CAAA/B,GAGA,CAH+B,CAAAC,GAG/B,CAH2D,EAG3D,CAFAoB,EAAA,CAAAA,CAAA,CAEA,CADA5K,CAAA,CAAAA,CAAA,CACA,CAAAqL,CAAA,CAAW,CAAA,CALnB,CAQIA,EAAJ,EAAcE,CAelB1W,EAAA,CAAayW,EAAA,CAfKC,CAeL,CAAb,CAA8C,uBAA9C,CAA4DxF,CAAA,CAf1CwF,CAeoDnC,GAAV,CAA5D,CAlCyB,CAD7B;AAgDA/U,CAAAvC,GAAA,CAAAA,QAAU,CAACQ,CAAD,CAAQkC,CAAR,CAAkB/D,CAAlB,CACV,CACI,IAAIlB,EAAM,IAEV,QAAQiF,CAAR,EACA,KAAK,OAAL,CACA,KAAK,OAAL,CAOI,MADA,KAAA/F,EAAA,CAAc+F,CAAd,CACO,CADmB/D,CACnB,CAAA,CAAA,CAEX,MAAK,KAAL,CAcI,MAbA,KAAAhC,EAAA,CAAc+F,CAAd,CAaO,CAbmB/D,CAanB,CAZPA,CAAAgE,QAYO,CAZW+W,QAAmB,EAAG,CAChC,IAAA,CAAA,IAAC/b,CAAD,CAACA,CAAAA,EAAD,CAkolBZ,GAlolByB,CAkolBrBR,CAlolBqB,CAAA,EAkolBrBA,CAAA,CAAAL,MAAAK,EAAJ,CAAwB,CAAA,CAAO,CAAA,CAA/B,KAAA,CADJ,IAGQU,EAAY,IAHpB,CAG0B8b,CAH1B,CAIQxZ,EAAcyZ,EAAA,CAAwB,CAAApd,GAAxB,CAClB,KAAKmd,CAAL,CAAkB,CAAlB,CAAqBA,CAArB,CAAkCxZ,CAAA5N,OAAlC,GACIsL,CACI,CADQsC,CAAA,CAAYwZ,CAAZ,CACR,CAAA9b,CAAA,GAAc,CAAd,EAAuBA,CAAAf,MAAAC,MAF/B,EAAsD4c,CAAA,EAAtD,EAIA,GAAIA,CAAJ,EAAkBxZ,CAAA5N,OAAlB,CACI,IAAKonB,CAAL,CAAkB,CAAlB,CAAqBA,CAArB,CAAkCxZ,CAAA5N,OAAlC,GACIsL,CACI,CADQsC,CAAA,CAAYwZ,CAAZ,CACR,CAAA9b,CAAA,GAAc,CAAd,EAAuBA,CAAAf,MAAAK,EAF/B,EAAsDwc,CAAA,EAAtD,EAKAA,CAAJ,EAAkBxZ,CAAA5N,OAAlB,GAAsCsL,CAAtC,CAAkD,CAAlD,CAEAxG,EAAA,CADQ,MACR,CADiBwG,CAAAnJ,KACjB,CADkC,cAClC,CADmDmJ,CAAArB,GACnD,CADkE,WAClE,EADkFqB,CAAAf,MAAAC,MAAD,CAAgG,aAAhG,CAAwB,WAAxB,EAAuCc,CAAAP,GAAA,CAAmB,6BAAnB,CAAmD,EAA1F,CACjF,EADkM,GAClM,CACA,EAAA,CAAO,CAAA,CAjBP,CAlolBY,CAAJ,GAMKG,CAAAX,MAAA+Q,EAAL;AAGIK,CAAA,CAAAzQ,CAAA,CAHJ,CACIwQ,EAAA,CAAAxQ,CAAA,CAPJ,CADoC,CAYjC,CAAA,CAAA,CAEX,MAAK,OAAL,CAEI,MADA,KAAAd,EAAA,CAAc+F,CAAd,CACO,CADmB/D,CACnB,CAAA,CAAA,CAEX,MAAK,UAAL,CAMI,MALA,KAAAhC,EAAA,CAAc+F,CAAd,CAKO,CALmB/D,CAKnB,CAJPA,CAAAgE,QAIO,CAJW+W,QAAwB,EAAG,CACzCG,EAAA,CAAApc,CAAA,CAAaA,CAAAkZ,GAAb,EAAsC,CAAtC,CAAyC,CAAA,CAAzC,CADyC,CAItC,CADPhY,CAAAsG,YACO,CADe6U,IA6MnBhD,GAAAiD,QAAA,CAAuB,CAAvB,CA5MI,CA4MwB,KA5MxB,CAAA,CAAA,CArCX,CA0CA,MAAO,CAAA,CA7CX,CAwFAzL,SAAA,GAAS,CAATA,CAAS,CAACkI,CAAD,CAAUwD,CAAV,CACT,CACI,CAAAlC,EAAA,EAAqBtB,CACjBwD,EAAJ,GACI,CAAAhC,EADJ,CACwB,CAAAC,EADxB,CAC8D,CAD9D,CAFJ,CAsBAgC,QAAA,GAAU,CAAVA,CAAU,CAACC,CAAD,CACV,CAII,IAAIC,EAAc,CACdD,EAAJ,EACiC,CADjC,CACQ,CAAAvD,GADR,EACsC,CAAA4B,EADtC,GAEQ4B,CAFR,CAEuB,CAAA5B,EAFvB,CAEkC,CAAA3B,GAFlC,CAMA,EAAAG,GAAA,CAAkBpmB,IAAAkmB,MAAA,CAAW,GAAX,CAAkBuD,EAAlB,CAClB,EAAApD,GAAA,CAAuBrmB,IAAA0pB,MAAA,CAAW,CAAA3D,GAAX,CAAmC0D,EAAnC,CAAgED,CAAhE,CAKlBD,EAAL,GAAc,CAAAjD,GAAd,CAAsC,CAAAD,GAAtC,CACA,EAAAE,GAAA,CAAqB,CAlBzB,CAsCAsC,QAAA,GAAS,CAATA,CAAS,CACT,CAuBI,MAtBc,EAAA1B,EAsBd,CAtBkC,CAAAC,EAsBlC,CAtBoD,CAAAC,EAsBpD,CAtBwE,CAAAC,EAD5E,CAgDAY,QAAA,GAAW,CAAXA,CAAW,CACX,CACI,CAAAN,EAAA,CAAW,CACX,EAAAD,GAAA,CAAgC,CAChC,EAAAR,EAAA,CAAoB,CAAAC,EAApB,CAAsC,CAAAC,EAAtC,CAA0D,CAAAC,EAA1D,CAAgG,CAChGa,GAAA,CAAAA,CAAA,CACAe,GAAA,CAAAA,CAAA,CAAc,CAAd,CALJ;AA6DAA,QAAA,GAAQ,CAARA,CAAQ,CAACpD,CAAD,CAAc6D,CAAd,CACR,CACI,IAAIhZ,EAAW,CAAA,CACf,IAAoBlO,IAAAA,EAApB,GAAIqjB,CAAJ,CAA+B,CAIK,EAAhC,CAAI,CAAA8B,EAAJ,CAAe,CAAAzB,GAAf,CACIL,CADJ,CACkB,CADlB,CAGInV,CAHJ,CAGe,CAAA,CAEf,EAAAqV,GAAA,CAAyBF,CACrB8B,EAAAA,CAAM,CAAA3B,GAAN2B,CAAwB,CAAA5B,GAC5B,IAAI,CAAAG,GAAJ,EAAsByB,CAAtB,CAA2B,CACvB,CAAAzB,GAAA,CAAiByB,CACbgC,EAAAA,CAAST,CAjCdhD,GAAAiD,QAAA,CAAuB,CAAvB,CAiCKQ,CAjCuB,KAkC3B,KAAIC,EAAe,CAAA7d,EAAA,SACf6d,EAAJ,GAAkBA,CAAAvV,YAAlB,CAA6CsV,CAA7C,CACA,EAAAxX,EAAA,CAAa,gBAAb,CAAgCwX,CAAhC,CALuB,CAOvBD,CAAJ,EAAoB,CAAA3c,EAApB,EAA8Bub,EAAA,CAAA,CAAAvb,EAAA,CAlBH,CAoB/B2Q,EAAA,CAAAA,CAAA,CAAe,CAAAyJ,EAAf,CACA,EAAAA,EAAA,CAAkB,CAClB,EAAAG,EAAA,CAAkBuC,EAAA,EAClB,EAAArC,EAAA,CAAoB,CACpB6B,GAAA,CAAAA,CAAA,CACA,OAAO3Y,EA3BX,CAmRAoZ,QAAA,GAAc,CAAdA,CAAc,CAAClE,CAAD,CACd,CACI,IAAK,IAAI9nB,EAAI,CAAAipB,EAAAplB,OAAJ7D,CAA0B,CAAnC,CAA2C,CAA3C,EAAsCA,CAAtC,CAA8CA,CAAA,EAA9C,CAAmD,CAC/C,IAAIuL,EAAQ,CAAA0d,EAAA,CAAajpB,CAAb,CAEG,EAAf,CAAIuL,CAAA,CAAM,CAAN,CAAJ,EACIuc,CADJ,CACcvc,CAAA,CAAM,CAAN,CADd,GAEIuc,CAFJ,CAEcvc,CAAA,CAAM,CAAN,CAFd,CAH+C,CAQnD,MAAOuc,EATX,CAkBAmE,QAAA,GAAU,CAAVA,CAAU,CACV,CAEI,IADA,IAAIC,EAAe,EAAnB,CACSlsB,EAAI,CAAb,CAAgBA,CAAhB,CAAoB,CAAAipB,EAAAplB,OAApB,CAAyC7D,CAAA,EAAzC,CAEIksB,CAAAjjB,KAAA,CADY,CAAAggB,EAAA1d,CAAavL,CAAbuL,CACM,CAAM,CAAN,CAAlB,CAEJ,OAAO2gB,EANX;AAkCAvM,QAAA,GAAY,CAAZA,CAAY,CAACmI,CAAD,CACZ,CACI,IAAK,IAAI9nB,EAAI,CAAAipB,EAAAplB,OAAJ7D,CAA0B,CAAnC,CAA2C,CAA3C,EAAsCA,CAAtC,CAA8CA,CAAA,EAA9C,CAAmD,CAC/C,IAAIuL,EAAQ,CAAA0d,EAAA,CAAajpB,CAAb,CAEG,EAAf,CAAIuL,CAAA,CAAM,CAAN,CAAJ,GACAA,CAAA,CAAM,CAAN,CACA,EADYuc,CACZ,CAAgB,CAAhB,EAAIvc,CAAA,CAAM,CAAN,CAAJ,GACIA,CAAA,CAAM,CAAN,CACA,CADY,EACZ,CAAAA,CAAA,CAAM,CAAN,CAAA,EAFJ,CAFA,CAH+C,CADvD,CAoBA4gB,QAAA,GAAQ,CAARA,CAAQ,CAACC,CAAD,CACR,CACI,IAAItE,EAAU,CAAAwB,EAAVxB,EAA+B,CAAAyB,EAOnC,EAAAA,EAAA,CAAsC,CAClC6C,EAAJ,GAAY,CAAA9C,EAAZ,CAAgC,CAAhC,CACA,OAAOxB,EAVX;AAkBAjU,CAAAsV,GAAA,CAAAA,QAAM,EACN,CACI,GAAK,IAAA/a,MAAA+Q,EAAL,CAAA,CAMAkN,IAlUI7D,GAAJ,EAkUA6D,IAlU0BrE,GAA1B,EACIuD,EAAA,CAiUJc,IAjUI,CAAgB,CAAA,CAAhB,CAiUJA,KA/TA1C,GAAA,CAAsB,CA+TtB0C,KA9TA5C,GAAA,CAAsBsC,EAAA,EA2BtB,IAmSAM,IAnSI3C,EAAJ,CAAuB,CACnB,IAAI4C,EAkSRD,IAlSkB5C,GAAV6C,CAkSRD,IAlSwC3C,EAChC4C,EAAJ,CAiSJD,IAjSkBhE,GAAd,GAiSJgE,IA/RQ7C,EAOA,EAPmB8C,CAOnB,CAwRRD,IAxRY7C,EAAJ,CAwRR6C,IAxR8B5C,GAAtB,GAwRR4C,IAvRY7C,EADJ,CAwRR6C,IAvR8B5C,GADtB,CATJ,CAFmB,CAqSvB,GAAI,CACA,EAAG,CAMC,IAAI3B,EAAUkE,EAAA,CAAAA,IAAA,CAAoB,IAAA5d,MAAAua,GAAA,CAAqB,CAArB,CAAyB,IAAAL,GAA7C,CAKd,IAAI,CACA,IAAA7I,GAAA,CAAaqI,CAAb,CADA,CAGJ,MAAMhI,CAAN,CAAiB,CAMb,GAAwB,QAAxB,EAAI,MAAOA,EAAX,CAAkC,KAAMA,EAAN,CANrB,CAYjBgI,CAAA,CAAUqE,EAAA,CAAAA,IAAA,CAAc,CAAA,CAAd,CAKV,KAAAxC,GAAA,EAAuB7B,CACvB,KAAAuB,EAAA,EAAmBvB,CACnBjI,GAAA,CAAAA,IAAA,CAAoBiI,CAApB,CAKAnI,GAAA,CAAAA,IAAA,CAAkBmI,CAAlB,CAEA,KAAAS,GAAA,EAAyBT,CACzB,IAA6B,CAA7B,EAAI,IAAAS,GAAJ,CAAgC,CAC5B,IAAAA,GAAA,EAAyB,IAAAD,GACrB,GAAE,IAAAsB,GAAN,EAAuC2C,EAAvC,GACIvM,IApnBZ/Q,EAqnBY,EArnBF+Q,CAAA,CAonBEA,IApnBF/Q,EAAA,CAFHud,IAAAA,EAEG,CAqnBE,CAAA,IAAA5C,GAAA,CAAgC,CAFpC,CAIA,MAN4B,CAzCjC,CAAH,MAiDS,IAAAxb,MAAA+Q,EAjDT,CADA,CAoDJ,MAAOvf,CAAP,CAAU,CACN4f,CAAA,CAAAA,IAAA,CACI,KAAAvQ,EAAJ,EAAc,IAAAA,EAAA0N,KAAA,CAAcoP,EAAA,EAAd,CAAmCjB,EAAA,CAAAA,IAAA,CAAnC,CACdhW;EAAA,CAAAA,IAAA,CAAclV,CAAAmgB,MAAd,EAAyBngB,CAAAgJ,QAAzB,CACA,OAJM,CAOV,GAAI,IAAAwF,MAAA+Q,EAAJ,CAAA,CAAwBlU,CAAAA,CAAAA,UAAWie,EAAAA,CAAA,IAAAA,GAAmBuD,KAtUtD/C,EAAA,CAAoBqC,EAAA,EAEpB,KAAIW,EAoUkDD,IApUxCpE,GAoUwCoE,KAnUlD9C,GAAJ,GAOI+C,CAPJ,CAOczqB,IAAAkmB,MAAA,CAAWuE,CAAX,CA4TwCD,IA5TnB9C,GAArB,CA4TwC8C,IA5TGnE,GAA3C,CAPd,CAWuBoE,EAAnBC,EAwTkDF,IAzT/B/C,EACnBiD,CAwTkDF,IAzTXhD,GAmB3BmD,KAAAA,EAsSsCH,IAtStC/C,EAAAkD,CAsSsCH,IAtSlBjD,EAzGhCoD,EAAJ,GA+YsDH,IA9YlD5C,EACA,CADW5nB,IAAAkmB,MAAA,CA8YuCsE,IAvSxCpD,EAvGC,EAAkC,EAAlC,CAAsBuD,CAAtB,EACX,CADoD,GACpD,CAAiB,KAAjB,EAAIA,CAAJ,GA6YkDH,IA5Y9CrD,EACA,CADoB,CACpB,CAAA+B,EAAA,CA2Y8CsB,IA3Y9C,CAFJ,CAFJ,CAiHA,IAAuB,CAAvB,CAAIE,CAAJ,EA8RsDF,IA9R1B5C,EAA5B,CA8RsD4C,IA9RfrE,GAAvC,CAM4B,IAQxB,CARIuE,CAQJ,GAgRkDF,IAvR9CjD,EAOJ,EAPuBmD,CAOvB,EAAAA,CAAA,CAAmB,CAgR+BF,KAzQtDjE,GAAA,EAyQsDiE,IAzQhC9C,GAyQgC8C,KAnQtD/C,EAAA,EAAqBiD,CAmQG1hB,EAAA,CAAWie,CAAX,CAlQjByD,CAkQiB,CAAxB,CAnEA,CADJ,CA+EApN;QAAA,GAAQ,CAARA,CAAQ,CAACqM,CAAD,CACR,CACI,GAAI,CAAA7W,EAAA,CAAAA,CAAA,CAAJ,CAGA,GAAI,CAAA3G,MAAA+Q,EAAJ,CACI,CAAA9K,EAAA,CAAa,CAAAP,SAAA,EAAb,CAA+B,OAA/B,CADJ,KAAA,CAUAqX,EAAA,CAAAA,CAAA,CACA,EAAA/c,MAAA+Q,EAAA,CAAqB,CAAA,CACrB,EAAA/Q,MAAAqa,GAAA,CAAsB,CAAA,CACtB,KAAIoE,EAAa,CAAA5e,EAAA,IACb4e,EAAJ,GAAgBA,CAAAtW,YAAhB,CAAyC,MAAzC,CACI,EAAAtH,EAAJ,GACQ2c,CACJ,EADkBpB,EAAA,CAAA,CAAAvb,EAAA,CAAkB,CAAA,CAAlB,CAClB,CAAA,CAAAA,EAAA0H,MAAA,CAAe,CAAA6S,EAAf,CAAgCsB,EAAA,CAAAA,CAAA,CAAhC,CAFJ,CAIK,EAAAhc,EAAL,EAAe,CAAAnI,OAAA,CAAY,SAAZ,CACfsE,WAAA,CAAW,CAAAie,GAAX,CAA8B,CAA9B,CApBA,CAJJ,CAqCArV,CAAAiZ,GAAA,CAAArN,QAAO,EACP,CACI,MAAO,EADX,CAgBAD,SAAA,EAAO,CAAPA,CAAO,CAACuN,CAAD,CACP,CACI,IAAIC,EAAW,CAAA,CACf,IAAI,CAAA5e,MAAA+Q,EAAJ,CAAwB,CACpBgN,EAAA,CAAAA,CAAA,CACAvM,GAAA,CAAAA,CAAA,CAAe,CAAAyJ,EAAf,CACA,EAAAA,EAAA,CAAkB,CAClB,EAAAjb,MAAA+Q,EAAA,CAAqB,CAAA,CAErB,IADI0N,CACJ,CADiB,CAAA5e,EAAA,IACjB,CAAgB4e,CAAAtW,YAAA,CAAyB,KACrC,EAAAtH,EAAJ,EACI,CAAAA,EAAA0N,KAAA,CAAcoP,EAAA,EAAd,CAAmCjB,EAAA,CAAAA,CAAA,CAAnC,CAEJkC,EAAA,CAAW,CAAA,CACN,EAAAle,EAAL,EAAe,CAAAnI,OAAA,CAAY,SAAZ,CAXK,CAaxB,CAAAyH,MAAA6e,SAAA,CAAsBF,CACtB,OAAOC,EAhBX,CAsDJ,IAAAtB,GAAkC,EAAlC,CACAa,GAAkC,EADlC,CAGAvC,GAAmB,CAAC,OAAD,CAAU,OAAV,CAyEftc;QAzBEwf,GAyBS,CAACtF,CAAD,CACX,CAEI,IAAIuF,EAAQ,CAACvF,CAAA,MAATuF,EAhkIIC,IA4kIR,GAAA,KAAA,CAAA,IAAA,CAAMxF,CAAN,CAPqBC,GAOrB,CAEA,KAAAsF,GAAA,CAAaA,CACb,KAAAE,GAAA,CAAiB,CAACzF,CAAA,UAAlB,EAA2C,CAE3C,KAAA0F,GAAA,CAAgBC,EAAAtW,KAAA,CAAkB,IAAlB,CAChB,KAAAuW,EAAA,CAAmBC,CAAAxW,KAAA,CAAuB,IAAvB,CAGnB,KAAAyW,GAAA,CAAe,IAGf,KAAAC,GAAA,CAAa,EAEb,KAAAvf,MAAA6e,SAAA,CAAsB,CAAA,CA5B1B,CA1BwB1Q,EAAAoL,CAAtBuF,EAAsBvF,CAAAA,EAAAA,CA8ExB,EAAA,CA/xQJ,EAAAiG,UA+xQI/Z;CAAA4I,MAAA,CAAAA,QAAK,EACL,CACI,IAAA9V,OAAA,CAAY,QAAZ,CAAuB,IAAAwmB,GAAvB,CACI,KAAA/e,MAAA+Q,EAAJ,EAAwBK,CAAA,CAAAA,IAAA,CACxBqO,KAkBAC,GAAA,CAlBAD,IAkBcE,GAAd,CAlBAF,IAiBAG,EACA,CAlBAH,IAiBcI,EACd,CAD2B,CAjB3BJ,KAmBAhN,EAAA,CAnBAgN,IAmBcK,GAAd,CAnBAL,IAmB4BR,GAnB5BQ,KAqBAM,EAAA,CArBAN,IAoBAO,EACA,CADe,EApBfP,KAuBAQ,EAAA,CAvBAR,IAsBAS,EACA,CADe,CAtBfT,KAyBAU,GAAA,CAAc,CAAC,CAAD,CAAI,CAAJ,CAzBdV,KA0BAW,GAAA,CAAc,CAAC,CAAD,CAAI,CAAJ,CA1BdX,KA2BAY,GAAA,CAAc,CAAC,CAAD,CAAI,CAAJ,CA3BdZ,KA4BAa,GAAA,CAAc,CAAC,CAAD,CAAI,CAAJ,CA5Bdb,KAqCAc,GAAA,CArCAd,IAqCgBhN,EArChBgN,KA0CAe,EAAA,CAAe,CA1Cff,KAwDAxN,EAAA,CAxDAwN,IAwDgBgB,GAxDhBhB,KAyDA1N,EAAA,CAzDA0N,IAyDiBiB,GAzDjBjB,KAyhBAH,GAAA,CAAe,IAxhBfvD,GAAA,CAAAA,IAAA,CACAtb,KAnhJAT,MAAAO,MAAA,CAAmB,CAAA,CAohJnB8N,GAAAA,UAAAA,MAAAA,KAAAA,CAAAA,IAAAA,CANJ,CAqHA5I,EAAA+W,GAAA,CAAAA,QAAW,EACX,CACI,MAAO,EADX,CAUA/W;CAAAgK,KAAA,CAAAA,QAAI,EACJ,CACI,IAAIC,EAAQ,IAAIC,CAAJ,CAAU,IAAV,CACZD,EAAAE,IAAA,CAAU,CAAV,CAAa,CACT,IAAAgQ,EADS,CAET,IAAAC,EAFS,CAGT,IAAAH,GAHS,CAIT,IAAAC,GAJS,CAKT,IAAAlN,EALS,CAMT,IAAAuN,EANS,CAOT,IAAAD,EAPS,CAQT,IAAAG,EARS,CAST,IAAAM,EATS,CAUT,IAAAV,GAVS,CAWT,IAAAS,GAXS,CAYT,IAAAtB,GAZS,CAAb,CAcAvP,EAAAE,IAAA,CAAU,CAAV,CAAa,EAAb,CACAF,EAAAE,IAAA,CAAU,CAAV,CAAa,CAAC,IAAAoL,EAAD,CAAoB2F,IAj3B1B9G,GAi3BM,CAAqC,IAAA7Z,MAAAsa,GAArC,CAAb,CACA5K,EAAAE,IAAA,CAAU,CAAV,CAAagR,EAAA,CAAAA,IAAA,CAAb,CACAlR,EAAAE,IAAA,CAAU,CAAV,CAAaiO,EAAA,CAAAA,IAAA,CAAb,CACA,OAAOnO,EAAAzV,KAAA,EApBX,CA8BAwL;CAAA+J,QAAA,CAAAA,QAAO,CAACvV,CAAD,CACP,CAkBQ,IAAA,EAAAA,CAAA,CAAK,CAAL,CWn7QVzM,GAAA,EAGAJ,GAAA,EAAAI,GAAA,EAAA,KAAI,EAAqC,CAAD,CAAW,MAAA,SAAX,CACxC,EAAA,CAAO,CAAA,CAAmB,CAAA,KAAA,CAAsB,CAAtB,CAAnB,CACHD,EAAA,CAA6C,CAA7C,CXk6QM,KAAAqyB,EADJ,CAAA,CAAA,KAAA,EAAA,MAEI,KAAAC,EAFJ,CAAA,CAAA,KAAA,EAAA,MAGI,KAAAH,GAHJ,CAAA,CAAA,KAAA,EAAA,MAII,KAAAC,GAJJ,CAAA,CAAA,KAAA,EAAA,MAKI,KAAAlN,EALJ,CAAA,CAAA,KAAA,EAAA,MAMI,KAAAuN,EANJ,CAAA,CAAA,KAAA,EAAA,MAOI,KAAAD,EAPJ,CAAA,CAAA,KAAA,EAAA,MAQI,KAAAG,EARJ,CAAA,CAAA,KAAA,EAAA,MASI,KAAAM,EATJ,CAAA,CAAA,KAAA,EAAA,MAUI,KAAAV,GAVJ,CAAA,CAAA,KAAA,EAAA,MAWI,KAAAS,GAXJ,CAAA,CAAA,KAAA,EAAA,MAYI,KAAAtB,GAZJ,CAAA,CAAA,KAAA,EAAA,MAeI7tB,EAAAA,CAAI6I,CAAA,CAAK,CAAL,CACR,KAAA+gB,EAAA,CAAoB5pB,CAAA,CAAE,CAAF,CACpB2rB,GAAA,CAAAA,IAAA,CAAc3rB,CAAA,CAAE,CAAF,CAAd,CACA,KAAA4O,MAAAsa,GAAA,CAAuBlpB,CAAA,CAAE,CAAF,CAEN,EAAA,CAAA6I,CAAA,CAAK,CAAL,CA+XjB,KAASrI,CAAT,CAAaivB,CAAAprB,OAAb,CAAkC,CAAlC,CAA0C,CAA1C,EAAqC7D,CAArC,CAA6CA,CAAA,EAA7C,CAAkD,CAC9C,IAAIkvB,CAxDZ,EAAA,CAAA,CACI,IAASlvB,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAzUAmvB,IAyUoBxB,GAAA9pB,OAApB,CAAuC7D,CAAA,EAAvC,CAA4C,CACxC,IAAIkvB,EA1URC,IA0UcxB,GAAA,CAAW3tB,CAAX,CACV;GAAIkvB,CAAAE,GAAJ,GAqDuBH,CAAAG,CAAYpvB,CAAZovB,CArDvB,CAA2B,CAAA,CAAA,CAAOF,CAAP,OAAA,CAAA,CAFa,CAI5C,CAAA,CAAO,IALX,CA0DYA,CAAJ,GACIA,CAAAG,KACA,CApYRF,IAmYmBzB,GACX,CApYRyB,IAoYQzB,GAAA,CAAewB,CAFnB,CAH8C,CA9X/B,CAAA,CAAA7mB,CAAA,CAAK,CAAL,CAljBnB,KAASrI,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAkjBAsvB,IAljBoBrG,EAAAplB,OAApB,EAA2C7D,CAA3C,CAA+CksB,CAAAroB,OAA/C,CAAoE7D,CAAA,EAApE,CAkjBAsvB,IAjjBgBrG,EAAA1d,CAAavL,CAAbuL,CACZ,CAAM,CAAN,CAAA,CAAW2gB,CAAA,CAAalsB,CAAb,CAijBf,OAAO,CAAA,CA3BX,CAmDAuvB,SAAA,GAAK,CAALA,CAAK,CAACzuB,CAAD,CACL,CACI,CAAAwtB,EAAA,CAAc,CAAAA,EAAd,CAA2B,OAA3B,CAAsDxtB,CAAtD,CA7rIW0uB,MA8rIX,EAAAlB,EAAA,EAAextB,CAAf,CAvsIY0uB,IAwsIN1uB,EAAN,CAvsIY0uB,IAusIZ,CAGU,CAAAlB,EAHV,CAxsIYkB,IAwsIZ,GAG4C,CAAAlB,EAH5C,EAvsIYkB,IAusIZ,EACI,CAAAlB,EADJ,EACkB,KAJtB,CA8GAmB,QAAA,GAAS,CAATA,CAAS,CAAC3I,CAAD,CACT,CACI,IAAI4I,EAAK,CAAA7O,EACT,EAAAA,EAAA,EAAc6O,CAAd,CAAmB5I,CAAnB,EAA0B6I,EAC1B,OAAOD,EAHX,CA2BAE,QAAA,GAAK,CAALA,CAAK,CACL,CACI,MAAqB,EAAd,EAAA,CAAAxB,EAAA,CAAiB,CAAAA,EAAjB,CAAgC,CAAAH,EAAD,CAv3I1BtV,OAu3I0B,CAAqC,CAAAuV,GAArC,CAAmD,CAAArN,EAD7F,CAmCAzB,QAAA,EAAK,CAALA,CAAK,CAACgE,CAAD,CACL,CACI,CAAA6K,EAAA,CAAa,CACb,EAAAG,EAAA,CAAc,EACd,EAAAvN,EAAA,CAAauC,CAAb,CAAoBuM,EAHxB,CAkKAX,QAAA,GAAQ,CAARA,CAAQ,CACR,CACI,IAAIC,EAAc,EAElB,KADIC,CACJ,CADU,CAAAxB,GACV,CAAOwB,CAAP,CAAA,CACID,CAAAhmB,KAAA,CAAiBimB,CAAAE,GAAjB,CACA,CAAAF,CAAA,CAAMA,CAAAG,KAEV,OAAOJ,EAPX;AAwGApb,CAAAgb,GAAA,CAAAA,QAAoB,CAACzL,CAAD,CACpB,CACWpU,IAAAA,EAAAA,IAAAA,EAAiB,EAAA,CAAA,IAAA2f,GAAA,CAAgBvL,CAAxC,OAh2FO,EAAAhB,EAAA,EADOgB,CACP,CADc,CAAA3C,EACd,IADiC,CAAAsB,EACjC,CAAA1B,EAAA,CAFG+C,CAEH,CApXYgB,KAoXZ,CAAsChB,CAAtC,CA+1FX,CAcAvP,EAAAib,GAAA,CAAAA,QAAmB,CAAC1L,CAAD,CAAO/a,CAAP,CACnB,CACI2G,IAAAA,EAAAA,IAAAA,EAAiB,EAAA,CAAA,IAAA2f,GAAA,CAAgBvL,CAj2FjC,EAAAhB,EAAA,EADcgB,CACd,CADqB,CAAA3C,EACrB,IADwC,CAAAsB,EACxC,CAAA5B,EAAA,CAi2FuC9X,CAj2FvC,CAFU+a,CAEV,CAlYmBgB,KAkYnB,CAA0ChB,CAA1C,CAk2FA,OAAO/a,EAFX,CAkCAwL;CAAAiZ,GAAA,CAAArN,QAAO,CAACoQ,CAAD,CACP,CAWI,IAAAzhB,MAAA6e,SAAA,CAAsB,CAAA,CAMtB,KAAI6C,EAA2B,IAAAhhB,EAAb,CAAyBihB,EAAA,CAAA,IAAAjhB,EAAA,CAAA,CAA0B,CAA1B,CAA+B,IAAAV,MAAAqa,GAAA,CAAsB,EAAtB,CAA0B,CAAlF,CAAwF,CAA1G,CAQIuH,EAAgBH,CAAF,CAAqB,IAAAzhB,MAAAqa,GAAA,CAAqB,CAArB,CAAyB,CAA9C,CAAgB,EAClC,KAAAra,MAAAqa,GAAA,CAAsB,CAAA,CAOtB,KAAAa,EAAA,CAAoB,IAAAC,EAApB,CAAuCsG,CAKvC,KAAAjB,EAAA,CAAgB,IAAAA,EAAhB,CAA+B,EAA/B,EAA0DkB,CAAA,CA3uJ9CG,CA2uJ8C,CAAqC,CAA/F,CAEA,GAAG,CACC,GAAI,IAAArB,EAAJ,CAAkB,CAKd,GAAiB,IAAAA,EAAjB,CAnvJIqB,CAmvJJ,CAAwD,CACpD,GAAIC,EAAA,CAAA,IAAAphB,EAAA,CAA0B8gB,EAAA,CAAAA,IAAA,CAA1B,CAAwCI,CAAxC,CAAJ,CAA0D,CACtDxQ,CAAA,CAAAA,IAAA,CACA,MAFsD,CAIrD,EAAEsQ,CAAP,GAAoB,IAAAlB,EAApB,EAAoC,EAApC,CACKoB,EAAL,EAAkBA,CAAA,EANkC,CAgBnD,GAAA,CAAA,CAAA,IAAA,EAAA,CAAA,EAAA,CACG,IApLZpB,EAAJ,CAllJYqB,CAklJZ,CAoLgB,IApKPvC,GAhBT,GAoLgB,IAnKRkB,EAjBR,EAiBwB,EAjBxB,EAoLgB,IAhKPA,EApBT,CAnlJYqB,CAmlJZ,EAoLgB,IA3JZrB,EAAA,EAEJ,CAAA,CAAA,CA7BiBuB,CAAAA,CAqLT,IAAK,CAAL,CACgC,CACxB,GAAK,IAAAvB,EAAL,CArwJJqB,CAqwJI,EAA8CC,EAAA,CAAA,IAAAphB,EAAA,CAA0B8gB,EAAA,CAAAA,IAAA,CAA1B,CAAwCI,CAAxC,CAA9C,CAAoG,CAChGxQ,CAAA,CAAAA,IAAA,CACA,MAFgG,CAWpG,GAAkB,CAAlB,CAAIwQ,CAAJ,CAAqB,KAZG,CAtBlB,CAuClB,IAAApB,EAAA,EAnxJQqB,EAqxJCG,KA5fRnC,EAAL,CA9yIYtV,OA8yIZ,CA4fayX,IA3fTnC,EADJ,CA4famC,IA3fItC,GADjB,CA4fasC,IA3fiB/P,EAAA,CA2fjB+P,IA3f+BpC,EAAd,CAD9B,CAEyB,CAAlB,EA0fMoC,IA1fFhC,EAAJ,EA0fMgC,IAzfTnC,EACA,CAwfSmC,IAzfIrC,GACb,CAwfSqC,IAzfiB/P,EAAA,CAyfjB+P,IAzf+BhC,EAAd,CAC1B,CAwfSgC,IAxfThC,EAAA;AAAc,EAFX,GA0fMgC,IAtfTnC,EACA,CAqfSmC,IAtfIrC,GACb,CAqfSqC,IAtfiB/P,EAAA,CAsfjB+P,IAtf+BlC,GAAd,CAsfjBkC,IAtf6CvP,EAA5B,CAC1B,CAqfSuP,IArfTvP,EAAA,EAqfSuP,IArfKvP,EAAd,CAA2B,CAA3B,EAAgC8O,EAL7B,CA0fMS,KA9ebnC,EAAA,EArzIYtV,OAmyJCyX,KAjebpC,EAAA,CAieaoC,IAjeAnC,EAAb,CAp0IYtV,MAs0IZ,IADI5X,CACJ,CA+daqvB,IAheJnC,EACT,EA10IYtV,EA00IZ,CAz0IYA,EAy0IZ,CA+dayX,IA/dNpC,EAAA,CA+dMoC,IA/dQpC,EAAd,EA+dMoC,IA/dsBtC,GAA5B,CA+dMsC,IA/dmC/P,EAAA,CAActf,CAAd,CAAzC,EAA8DsvB,EAErE,EAAA,CA6daD,IA7dLnC,EAAD,CA70IKtV,OA60IL,CAAsC,EAAtC,CA6dMyX,IA7dsCrC,GAA5C,CAAyDuC,EAAzD,CAA+E,CA8dxE,EAAV,EAAIC,CAAJ,EACI,IAAAjD,GAAA,CAAciD,CAAd,CAMJ,KAAAhH,EAAA,EAlDD,CAAH,MAoD4B,CApD5B,CAoDS,IAAAA,EApDT,CAsDA,OAAQ,KAAAnb,MAAA6e,SAAA,CAAqB,IAAA3D,EAArB,CAAyC,IAAAC,EAAzC,CAAqF,CAAA,CAAxB,GAAA,IAAAnb,MAAA6e,SAAA,CAAgC,EAAhC,CAAoC,CA9F7G,CAyHJvL,GAAA,CAfIZ,QAAW,EACX,CAEI,IADA,IAAI0P,EAAS9f,CAAA,CAA6BsQ,QAA7B,CAAuCxQ,CAAvC,CAAuD,KAAvD,CAAb,CACSigB,EAAO,CAAhB,CAAmBA,CAAnB,CAA0BD,CAAA3sB,OAA1B,CAAyC4sB,CAAA,EAAzC,CAAiD,CAC7C,IAAIC,EAAOF,CAAA,CAAOC,CAAP,CAAX,CACI7I,EAAWvW,EAAA,CAA4Bqf,CAA5B,CACX3hB,EAAAA,CAAM,IAAIme,EAAJ,CAAkBtF,CAAlB,CACVxG,GAAA,CAAgCrS,CAAhC,CAAqC2hB,CAArC,CAJ6C,CAFrD,CAcJ,CA0GeC,SAAA,GAAQ,CAACJ,CAAD,CACvB,CAMIK,EAAA,CAAkBL,CAAlB,EAAwB,CAAxB,CAAA5c,KAAA,CAAgC,IAAhC,CAAsC4c,CAAtC,CAA0CA,CAA1C,CAp8JgB5X,EAo8JhB,CANJ,CAmCckY,QAAA,EAAQ,CAACN,CAAD,CACtB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ;AA0HcO,QAAA,GAAQ,EACtB,CACI,IAAIvQ,EAAM,CAAV,CACIzf,EAAI,IAAAuf,EAAA,CAAc,IAAA2N,EAAd,CADR,CAEIztB,EAAKO,CAALP,CAASwwB,EAATxwB,CApmKYoY,EAkmKhB,CAGIjY,EAAKI,CAALJ,EApmKYiY,EAomKZjY,CAnmKYiY,EAomKhBpY,EAAA,EAAKG,CACG,EAAR,CAAIH,CAAJ,GACIggB,CAAA,EAEA,CADAhgB,CACA,CADI,EACJ,CADSG,CACT,CAAQ,CAAR,CAAIH,CAAJ,GAAWA,CAAX,CAAe,GAAf,CAAqBG,CAArB,CAHJ,CAaAI,EAAA,CAAKP,CAAL,CAASwwB,EAAT,EAAkCrwB,CAAlC,EAnnKgBiY,EAmnKhB,GAAgE7X,CAAhE,CAtmKgB6X,QAsmKhB,CACI4H,EAAJ,GAASzf,CAAT,EAAcA,CAAd,CAAkByf,CAAlB,EAAyBK,CAAzB,CACA,KAAAT,EAAA,CAAe,IAAA6N,EAAf,CAA2BltB,CAA3B,CArBJ,CA+EckwB,QAAA,GAAQ,CAACT,CAAD,CAAKU,CAAL,CACtB,CAKQnwB,CAAAA,CAAI,IAAAuf,EAAA,CAAc,IAAA2N,EAAd,CACR,IAAiB,CAAjB,CAAI,IAAAG,EAAJ,CACI,IAAAA,EACA,CADartB,CACb,CAAA,IAAAmtB,EAAA,CAAa,IAAAD,EAAb,CAnrKYrV,OAirKhB,KAAA,CAKA,IAAIpY,EAAK,IAAA4tB,EAAL5tB,CAAkBwwB,EAAlBxwB,CA5rKYoY,EA4rKhB,CACIjY,EAAK,IAAAytB,EAALztB,EA5rKYiY,EA4rKZjY,CA3rKYiY,EAksKZ7X,EAAA,CANQ,EAAZ,CAAIP,CAAJ,CAAQG,CAAR,EAMUI,CANV,EAMeP,CANf,EAMsB,CANtB,EAM2BG,CAN3B,EAMgC,CANhC,IAMwC,CANxC,CAaQuB,IAAAE,MAAA,CAAWrB,CAAX,CAAemB,IAAAC,IAAA,CAAS,CAAT,CAAY3B,CAAZ,CAAf,CAbR,CAayC0B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAEzC,KAAAyf,EAAA,CAAe8Q,CAAf,CAAmBnwB,CAAnB,CACA,KAAAwtB,EAAA,EAAc,KACd,KAAAH,EAAA,CAAc,EAxBd,CANJ;AAuFc+C,QAAA,GAAQ,CAACX,CAAD,CAAKU,CAAL,CACtB,CAKQnwB,CAAAA,CAAI,IAAAuf,EAAA,CAAc,IAAA2N,EAAd,CACR,IAAiB,CAAjB,CAAI,IAAAG,EAAJ,CACI,IAAAA,EACA,CADartB,CACb,CAAA,IAAAmtB,EAAA,CAAa,IAAAD,EAAb,CA3wKYrV,OAywKhB,KAAA,CAKA,IAAIpY,EAAK,IAAA4tB,EAAL5tB,CAAkBwwB,EAAlBxwB,CApxKYoY,EAoxKhB,CACIjY,EAAK,IAAAytB,EAALztB,EApxKYiY,EAoxKZjY,CAnxKYiY,EAyxKZlZ,EAAAA,CAAM,IAAA4gB,EAAA,CAAc4Q,CAAd,CAANxxB,CAA0BwC,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAA1BjB,CAA4CwC,IAAAC,IAAA,CAAS,CAAT,CAAY3B,CAAZ,CAA5Cd,CAA8DmhB,CAClE9f,EAAA,CAAKA,CAAL,CAAUA,CAAV,CAAcmB,IAAAC,IAAA,CAAS,CAAT,CAAY3B,CAAZ,CAAgBG,CAAhB,CAAd,CAAqCjB,CAArC,CAA0CqB,CAA1C,CAA8CmB,IAAAC,IAAA,CAAS,CAAT,CAAY3B,CAAZ,CAC9C,KAAA4f,EAAA,CAAe,IAAA6N,EAAf,CAA2BltB,CAA3B,CACA,KAAAwtB,EAAA,EAAc,KACd,KAAAH,EAAA,CAAc,EAhBd,CANJ,CAyaegD,QAAA,GAAQ,CAACZ,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAAnB,CADJ,CAsBgBoD,QAAA,GAAQ,CAACb,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB,IAAAjD,EAAnB,CADJ,CAoBgBqD,QAAA,GAAQ,CAACd,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA3N,EAAA,CAAc4Q,CAAd,CAA3B,CADJ,CAq/FeK,QAAA,GAAQ,CAACf,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB,CAAnB,CADJ,CAygBgBM,QAAA,GAAQ,CAAChB,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBO,CAAnB,CAAqC,IAAAnR,EAAA,CAAc4Q,CAAd,CAArC,CADJ,CAgUeQ,QAAA,GAAQ,CAAClB,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBO,CAAnB,CADJ;AAkDcE,QAAA,GAAQ,CAACnB,CAAD,CAAKU,CAAL,CACtB,CACI,IAAIU,EAAM,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CAAV,CACI4D,EAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBY,EAAA,CAAYtB,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAAnB,EAAgDA,CAAhD,EAAuDA,CAAvD,CAA6DG,CAA7D,GAHJ,CAuBeC,QAAA,GAAQ,CAACxB,CAAD,CAAKU,CAAL,CACvB,CACI,IAAIW,EAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBY,EAAA,CAAYtB,CAAZ,CAAgBqB,CAAhB,CAAqB,CAArB,CAAnB,CAFJ,CAmBeI,QAAA,GAAQ,CAACzB,CAAD,CAAKU,CAAL,CACvB,CACQU,CAAAA,CAAM,IAAAtR,EAAA,CAAc4Q,CAAd,CACV,KAAIW,EAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CACV,KAAA7N,EAAA,CAAe,IAAA6N,EAAf,CAA2B6D,EAAA,CAAYtB,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAA3B,EAAwDA,CAAxD,EAA+DA,CAA/D,CAAqEG,CAArE,GAHJ,CAsBeG,QAAA,GAAQ,CAAC1B,CAAD,CAAKU,CAAL,CACvB,CACI,IAAIW,EAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CAAV,CACsB4D,EAAAA,CA68DtB,IA78DkBrB,CA68DlB,EAAU,GAAV,CAEI,OADAqB,CACOrB,EADCqB,CACDrB,CADOuB,CACPvB,CAAAA,CAAP,EACA,KAAK,GAAL,CACIqB,CAAA,EAAOE,CACP,MACJ,MAAK,GAAL,CACIF,CAAA,EAp9DmBA,CAo9DX,CAAMM,CAAN,CAAsBJ,CAAtB,CAAwC,CALpD,CASJ,CAAA,CAAOF,CAv9DP,KAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B4D,CAA3B,CACIX,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAJZ,CAsBcO,QAAA,GAAQ,CAAC5B,CAAD,CAAKU,CAAL,CACtB,CACI,IAAIU,GAAO,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CAAP2D,CAAmCG,CAAnCH,EAAsDS,CAA1D,CACIR,EAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBY,EAAA,CAAYtB,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAAnB,CAA+CA,CAA/C,CAHJ;AAqBeU,QAAA,GAAQ,CAAC9B,CAAD,CAAKU,CAAL,CACvB,CACI,IAAIU,EAAM,IAAA3D,EAAN2D,CAAmBS,CAAvB,CACIR,EAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBY,EAAA,CAAYtB,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAAnB,CAA+CA,CAA/C,CAHJ,CAqBeW,QAAA,GAAQ,CAAC/B,CAAD,CAAKU,CAAL,CACvB,CACQU,CAAAA,EAAO,IAAAtR,EAAA,CAAc4Q,CAAd,CAAPU,CAA2BG,CAA3BH,EAA8CS,CAClD,KAAIR,EAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CACV,KAAA7N,EAAA,CAAe,IAAA6N,EAAf,CAA2B6D,EAAA,CAAYtB,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAA3B,CAAuDA,CAAvD,CAHJ,CAqBeY,QAAA,GAAQ,CAAChC,CAAD,CAAKU,CAAL,CACvB,CACI,IAAIW,EAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CAAV,CACI2D,GAAOC,CAAPD,CAAaG,CAAbH,EAAgCS,CACpCR,EAAA,CAAMC,EAAA,CAAYtB,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAAN,CAAkCA,CAClC,KAAAxR,EAAA,CAAe,IAAA6N,EAAf,CAA2B4D,CAA3B,CACIX,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CALZ,CAuBcY,QAAA,GAAQ,CAACjC,CAAD,CAAKU,CAAL,CACtB,CACI,IAAIU,EAAM,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CAAN2D,CAAkCG,CAAtC,CACIF,EAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBwB,EAAA,CAAYlC,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAAnB,CAA+CA,CAA/C,CAHJ,CAqBee,QAAA,GAAQ,CAACnC,CAAD,CAAKU,CAAL,CACvB,CACI,IAAIW,EAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBwB,EAAA,CAAYlC,CAAZ,CAAgBqB,CAAhB,CAAqB,IAAA5D,EAArB,CAAnB,CAAsD,IAAAA,EAAtD,CAFJ,CAoBe2E,QAAA,GAAQ,CAACpC,CAAD,CAAKU,CAAL,CACvB,CACQU,CAAAA,CAAM,IAAAtR,EAAA,CAAc4Q,CAAd,CAANU,CAA0BG,CAC9B,KAAIF,EAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CACV,KAAA7N,EAAA,CAAe,IAAA6N,EAAf,CAA2ByE,EAAA,CAAYlC,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAA3B,CAAuDA,CAAvD,CAHJ;AAuBeiB,QAAA,GAAQ,CAACrC,CAAD,CAAKU,CAAL,CACvB,CACI,IAAIW,EAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CAAV,CACsB4D,EAAAA,CAkuDtB,IAluDkBrB,CAkuDlB,EAAU,GAAV,CAEI,OADAqB,CACOrB,EADAuB,CACAvB,CAAAA,CAAP,EACA,KAAK,GAAL,CACIqB,CAAA,EAAQE,CAAR,CAA0BM,CAC1B,MACJ,MAAK,GAAL,CACIR,CAAA,EAzuDmBA,CAyuDX,CAAMiB,EAAN,CAAwBf,CAAxB,CAA0CM,CAA1C,CAA8D,CAL1E,CASJ,CAAA,CAAOR,CA5uDP,KAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B4D,CAA3B,CACIX,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAJZ,CAqBckB,QAAA,GAAQ,CAACvC,CAAD,CAAKU,CAAL,CACtB,CACI,IAAIU,EAAO,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CAAP2D,CAAmCS,CAAnCT,CAAqD,CAAzD,CACIC,EAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBwB,EAAA,CAAYlC,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAAnB,CAA+CA,CAA/C,CAHJ,CAsBeoB,QAAA,GAAQ,CAACxC,CAAD,CAAKU,CAAL,CACvB,CACI,IAAIW,EAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBwB,EAAA,CAAYlC,CAAZ,CAAgBqB,CAAhB,CAAqB,CAArB,CAAnB,CAFJ,CAmBeoB,QAAA,GAAQ,CAACzC,CAAD,CAAKU,CAAL,CACvB,CACQU,CAAAA,CAAO,IAAAtR,EAAA,CAAc4Q,CAAd,CAAPU,CAA2BS,CAA3BT,CAA6C,CACjD,KAAIC,EAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CACV,KAAA7N,EAAA,CAAe,IAAA6N,EAAf,CAA2ByE,EAAA,CAAYlC,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAA3B,CAAuDA,CAAvD,CAHJ,CAoBesB,QAAA,GAAQ,CAAC1C,CAAD,CAAKU,CAAL,CACvB,CACI,IAAIW,EAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CAAV,CACI2D,EAAOC,CAAPD,CAAaS,CAAbT,CAA+B,CACnCC,EAAA,CAAMa,EAAA,CAAYlC,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAAN,CAAkCA,CAClC,KAAAxR,EAAA,CAAe,IAAA6N,EAAf,CAA2B4D,CAA3B,CACIX,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CALZ,CAs6BasB,QAAA,EAAQ,CAAC3C,CAAD,CACrB,CACI4C,EAAA,CAAiB5C,CAAjB,CAAsB,CAAtB,CAAA5c,KAAA,CAA8B,IAA9B,CAAoC4c,CAApC,CAAyCA,CAAzC,EAA+C,CAA/C,CAAoD,GAApD,CADJ;AAac6C,QAAA,GAAQ,EACtB,EAYeC,QAAA,GAAQ,EACvB,EAUoBC,QAAA,EAAQ,CAAC/C,CAAD,CAC5B,CACI,IAAAlc,EAAA,CAAa,oBAAb,CAAoC2P,EAAA,CAAUuM,CAAV,CAApC,CACAd,GAAA,CAAAA,IAAA,CAAgB,EAAhB,CACAjQ,EAAA,CAAAA,IAAA,CAHJ,CAec+T,QAAA,GAAQ,CAAC5B,CAAD,CACtB,CACQA,CAAJ,CAAUO,CAAV,GACQP,CAAJ,EAAW6B,CAAX,CACI7B,CADJ,CACU8B,EADV,CAC4B9B,CAD5B,CAGI,IAAArD,EAHJ,EAGmB,MAJvB,CAOA,OAAOqD,EARX,CAqBc+B,QAAA,EAAQ,CAAC9B,CAAD,CAAMD,CAAN,CACtB,CAKI,IAAIgC,GAAO/B,CAAP+B,CAAahC,CAAbgC,EAAoB/S,CACxBgT,GAAAjgB,KAAA,CAAuB,IAAvB,CAA6Bie,CAA7B,CAAkCD,CAAlC,CAAuCgC,CAAvC,CACA,OAAOA,EAPX;AAqBcE,QAAA,GAAQ,CAAClC,CAAD,CAAMC,CAAN,CAAWkC,CAAX,CACtB,CAAA,IACQC,EAAQ,CAAA,CADhB,CACuBC,EAAQ,CAAA,CAM3B,IAAYtvB,IAAAA,EAAZ,GAAIovB,CAAJ,CAAuB,CACnB,GAAI,CAACnC,CAAL,CAEI,MADA,KAAArD,EACQ,EADM,MACN,CAAA,EAEZwF,EAAA,CAAOlC,CAAD,CAAOM,CAAP,CAAwBV,CAAxB,CAA0C,CAL7B,CAAvB,IASI,KADcsC,CAAAG,CAAMT,CAANS,CAAuBH,CAAvBG,CAA6BR,EAA7BQ,CAA+CH,CAA/CG,EAAsDrC,CAAA,CAAK,CAAL,CAAS,CAA/DqC,CACd,IAFctC,CAAAuC,CAAMV,CAANU,CAAuBvC,CAAvBuC,CAA6BT,EAA7BS,CAA+CvC,CAE7D,EAEI,MADA,KAAArD,EACQ,EADM,MACN,CAAA,EAoRhB,KAAI6F,EA7QgCL,CA6QhCK,CA7QgCL,CA6QhCK,CAAqBX,CAUzB5B,EAAA,CAvR+BA,CAuR/B,CAAa4B,CAAb,EAvRoCM,CAuRpC,CAAwC,CAAxC,EAA6CN,CAtR7CM,EAAA,CAuRA,IAAAzF,EAvRA,CAuRa8F,CAvRb,CAuRoBlyB,IAAAE,MAAA,CAxRgB2xB,CAwRhB,CAAiB,CAAjB,CAlRhBnC,EAAJ,CAAUO,CAAV,GACIP,CACA,CADM/Q,CACN,CADyB+Q,CACzB,CAAAoC,CAAA,CAAQ,CAACA,CAFb,CAIID,EAAJ,CAAU5B,CAAV,GACQN,CAAJ,EACIkC,CACA,CADMtC,CACN,CADwBsC,CACxB,CAAAlC,CAAA,CAAMhR,CAAN,CAAyBgR,CAF7B,EAKQkC,CALR,GAKaA,CALb,CAKmBlT,CALnB,CAKsCkT,CALtC,CAOc,CAAdE,CAAc,CAAN,CAAA,CAAM,CAAAD,CAAA,CAAQ,CAACA,CAR3B,CAwBYxF,EAAAA,CAAAA,IAAAA,GA4rBZ6F,EAAA,CAAK,CAAL,CAAA,CA5rByBC,CA6rBzBD,EAAA,CAAK,CAAL,CAAA,CA7rB4BE,CAChB9F,EAAAA,CAAAA,IAAAA,GA2rBZ4F,EAAA,CAAK,CAAL,CAAA,CA3rByBC,CA4rBzBD,EAAA,CAAK,CAAL,CAAA,CA5rB4BE,CAChB7F,EAAAA,CAAAA,IAAAA,GA0rBZ2F,EAAA,CAAK,CAAL,CAAA,CA1rByBzC,CA2rBzByC,EAAA,CAAK,CAAL,CAAA,CA3rB8BE,CAClB5F,EAAAA,CAAAA,IAAAA,GAyrBZ0F,EAAA,CAAK,CAAL,CAAA,CAzrByBxC,CAEzB,KAwrBAwC,CAAA,CAAK,CAAL,CAxrBA,CAF8BN,CAE9B,CAA8C,CAA9C,CAAOS,EAAA,CAAW,IAAA7F,GAAX,CAAwB,IAAAD,GAAxB,CAAP,CAAA,CACI+F,EAAA,CAAW,IAAA/F,GAAX,CAAwB,IAAAA,GAAxB,CACA,CAAA+F,EAAA,CAAW,IAAAhG,GAAX,CAAwB,IAAAA,GAAxB,CAEJ,GAAG,CACC,GAA4C,CAA5C,EAAI+F,EAAA,CAAW,IAAA7F,GAAX,CAAwB,IAAAD,GAAxB,CAAJ,GACeC,CAEP,CAFOA,IAAAA,GAEP,CAFoBD,CAEpB,CAFoBA,IAAAA,GAEpB,CA6sBZ2F,CAAA,CAAK,CAAL,CA7sBY,EA6sBDK,CAAA,CAAK,CAAL,CA7sBC,CA8sBZL,CAAA,CAAK,CAAL,CA9sBY;AA8sBDK,CAAA,CAAK,CAAL,CA9sBC,CA+sBE,CA/sBF,CA+sBRL,CAAA,CAAK,CAAL,CA/sBQ,GAgtBRA,CAAA,CAAK,CAAL,CACA,EADWxT,CACX,CAAAwT,CAAA,CAAK,CAAL,CAAA,EAjtBQ,EADJI,EAAA,CAAW,IAAAjG,GAAX,CAAwB,IAAAC,GAAxB,CACI,CAAAkG,EAAA,CAAY,IAAAhG,GAAZ,CAHR,EAGkC,KAElCiG,GAAA,CAAW,IAAAlG,GAAX,CACAkG,GAAA,CAAW,IAAAnG,GAAX,CAPD,CAAH,MAQS,CAACkG,EAAA,CAAY,IAAAlG,GAAZ,CARV,CAaAoD,EAAA,CAAM,IAAArD,GAAA,CAAY,CAAZ,CACN,KAAAF,EAAA,CAAa,IAAAK,GAAA,CAAY,CAAZ,CAETqF,EAAJ,EAAanC,CAAb,GACIA,CADJ,CACUhR,CADV,CAC6BgR,CAD7B,CAIIoC,EAAJ,EAAa,IAAA3F,EAAb,GACI,IAAAA,EADJ,CACiBzN,CADjB,CACoC,IAAAyN,EADpC,CAIA,OAAOuD,EA5FX;AA6IcgD,QAAA,GAAQ,CAAChD,CAAD,CAAMD,CAAN,CAAWkD,CAAX,CAAsBC,CAAtB,CACtB,CAAA,IACQC,EAAKnD,CADb,CACkBoD,EAAKrD,CACfsD,EAAAA,CAAO,CAAA,CAMPF,EAAJ,CAAS7C,CAAT,GACQ4C,CADR,EArpWY1H,IAqpWZ,EACqB,IAAAD,GADrB,EACuD4H,CADvD,EAC6DvB,CAD7D,IAEQuB,CACA,CADKnU,CACL,CADwBmU,CACxB,CAAAE,CAAA,CAAO,CAACA,CAHhB,CAOID,EAAJ,CAAS9C,CAAT,GACI8C,CACA,CADKpU,CACL,CADwBoU,CACxB,CAAAC,CAAA,CAAO,CAACA,CAFZ,CAKA,IAAIF,CAAJ,CAAS3C,CAAT,EAA6B4C,CAA7B,CAAkC5C,CAAlC,CAAoD,CAChDuB,CAAA,CAAMoB,CAAN,CAAWC,CACX,KAAAlB,EAAM,CAF0C,CAApD,IAIK,CACGoB,CAAAA,CAAQH,CAARG,CAAapD,CACbqD,EAAAA,CAAOlzB,IAAAE,MAAA,CAAW4yB,CAAX,CAAgB3C,CAAhB,CACPgD,EAAAA,CAAQJ,CAARI,CAAatD,CACbuD,EAAAA,CAAOpzB,IAAAE,MAAA,CAAW6yB,CAAX,CAAgB5C,CAAhB,CACX,KAAIkD,EAAOJ,CAAPI,CAAcF,CAAlB,CACIG,EAAQJ,CAARI,CAAeH,CAAfG,CAAuBtzB,IAAAE,MAAA,CAAWmzB,CAAX,CAAkBlD,CAAlB,CAC3B0B,EAAA,CAAM7xB,IAAAE,MAAA,CAAWozB,CAAX,CAAkBnD,CAAlB,CACNmD,EAAA,EAAQA,CAAR,CAAezD,CAAf,EAAmCoD,CAAnC,CAA0CG,CAC1C1B,EAAA,EAAQ4B,CAAR,CAAenD,CAAf,EAAoCkD,CAApC,CAA2CxD,CAA3C,GAA+DlR,CAC/DkT,EAAA,EAAO7xB,IAAAE,MAAA,CAAWozB,CAAX,CAAkBnD,CAAlB,CAAP,CAA8C+C,CAA9C,CAAqDE,CAVpD,CAaDJ,CAAJ,GACQtB,CAAJ,EACIG,CACA,CADMtC,CACN,CADwBsC,CACxB,CAAAH,CAAA,CAAM/S,CAAN,CAAyB+S,CAF7B,EAKQG,CALR,GAKaA,CALb,CAKmBlT,CALnB,CAKsCkT,CALtC,CADJ,CAU+BH,EAAAA,CAAAA,CAAKG,EAAAA,CAAAA,CA6IhCK,EAAAA,CAAOL,CAAPK,CAAcL,CAAdK,CAAoBX,CACxBM,EAAA,CAAc,CAAd,CAAQA,CAAR,CAAmBlT,CAAnB,CAAuC3e,IAAAE,MAAA,CAAWwxB,CAAX,CAAiBH,CAAjB,CACvCG,EAAA,CAAMQ,CAAN,CAAcR,CAAd,CAAoBH,CAENM,EACd,CADqBA,CACrB,CAD2BN,CAC3B,EAAeW,CAAf,GAUIR,CAVJ,CAUUG,CAVV,CAlJyCgB,EA+JzC,CAAe,CAAf,CAAsBnB,CAAtB,EAEIA,CAIJ,EAJWH,CAIX,EAJ8BM,CAI9B,EAJqCN,CAIrC,GAHI,IAAAlF,EAGJ,EApuWgBkB,MAouWhB,EADA,IAAAnB,EACA,CADasF,CACb,CAAA,CAAA,CAAOG,CANP,CA7JIe,EAAJ,GAMIlB,CA0BA,CA1BM,IAAAtF,EA0BN,CAzBI,CAACyG,CAyBL,GAJShB,CAIT,EAJgBH,CAIhB,CAJsBzB,CAItB,IAJ0C4B,CAI1C,EAJiDtC,CAIjD,EAJoEmC,CAIpE,EAJ2EzB,CAI3E,IAHQ,IAAA5D,EAGR,EAjmWYkB,MAimWZ,EAAAsE,CAAA,CAAMH,CAhCV,CAkCA,OAAOG,EAnFX;AA+Fc0B,QAAA,GAAQ,CAAC7D,CAAD,CACtB,CACSA,CAAL,CAQQA,CAAJ,EAAW6B,CAAX,CACI,IAAAlF,EADJ,EACmB,MADnB,CAGIqD,CAHJ,CAGU8B,EAHV,CAG4B9B,CAXhC,CACI,IAAArD,EADJ,EACmB,KAanB,OAAOqD,EAfX,CA4Bc8D,QAAA,GAAQ,CAAC7D,CAAD,CAAMD,CAAN,CACtB,CAKI,IAAIgC,EAAO/B,CAAP+B,CAAahC,CACP,EAAV,CAAIgC,CAAJ,GAAaA,CAAb,EAAoB/S,CAApB,CAKAgT,GAAAjgB,KAAA,CAAuB,IAAvB,CAA6BggB,CAA7B,CAAkChC,CAAlC,CAAuCC,CAAvC,CACA,OAAO+B,EAZX,CAkGoB+B,QAAA,GAAQ,CAAC9D,CAAD,CAAMD,CAAN,CAAWgC,CAAX,CAC5B,CAOQgC,CAAAA,CAAQ1zB,IAAAE,MAAA,CAAWyvB,CAAX,CAAiBgE,EAAjB,CACRC,EAAAA,CAAQ5zB,IAAAE,MAAA,CAAWwvB,CAAX,CAAiBiE,EAAjB,CACRE,EAAAA,CAAQ7zB,IAAAE,MAAA,CAAWwxB,CAAX,CAAiBiC,EAAjB,CAgBZ,KAAIG,EAAaJ,CAAbI,EAAuBJ,CAAvBI,CAA+BF,CAA/BE,GAAyCF,CAAzCE,CAAiDD,CAAjDC,CAoBJ,KAAAzH,EAAA,CAAA,IAAAA,EAAA,EAnBcyH,CAmBC,CAnBW,CAmBX,CA5xWCvG,KA4xWD,CAA6B,CAA5C,GAlBcuG,CAkBoC,CAlBxB,CAkBwB,CA3xWlCvG,KA2xWkC,CAA6B,CAA/E,GAAqF,CADnEmG,CACmE,CAD3DG,CAC2D,GADjDD,CACiD,CADzCC,CACyC,EAD/B,CAC+B,CA7xWrEtG,MA6xWqE,CAA+B,CAApH,CA7CJ,CAyDYwG,QAAA,EAAQ,CAACpE,CAAD,CAAMD,CAAN,CACpB,CAcI,QAAWC,CAAX,CAAiBqE,CAAjB,CAAkC,CAAlC,GAAyCtE,CAAzC,CAA+CsE,CAA/C,CAAgE,CAAhE,GAAsEA,CAAtE,GAA2FrE,CAA3F,CAAiGD,CAAjG,IAA0G,CAA1G,CAdJ,CA0BYuE,QAAA,EAAQ,CAACtE,CAAD,CAAMD,CAAN,CACpB,CACI,MAAOqE,EAAA,CAAUpE,CAAV,EA8FE,EA9FuBD,CA8FvB,CAASsE,CAAT,CAA0B,CAA1B,CA9FF,CA8FiC,EA9FjC,EA8FyCA,CA9FzC,EA8F6D,CA9FpCtE,CAAzB,GA8FsE,CA9FtE,EADX,CAaYwE,QAAA,GAAQ,CAACvE,CAAD,CAAMD,CAAN,CACpB,CACI,OAAQC,CAAA,CAAM4B,CAAN,CAAuB5B,CAAvB,CAA6BA,CAA7B,CAAmChR,CAA3C,GAAgE+Q,CAAA,CAAM6B,CAAN,CAAuB7B,CAAvB,CAA6BA,CAA7B,CAAmC/Q,CAAnG,CADJ;AAaYwV,QAAA,GAAQ,CAACxE,CAAD,CAAMD,CAAN,CACpB,CAcI,OAAS,GAAIC,CAAJ,CAAUqE,CAAV,CAA2B,CAA3B,GAAkCtE,CAAlC,CAAwCsE,CAAxC,CAAyD,CAAzD,EAAT,CAAwE,EAAxE,EAAgFA,CAAhF,EAAoG,EAAErE,CAAF,CAAQD,CAAR,CAApG,GAAqH,CAArH,CAdJ,CA0BY0E,QAAA,EAAQ,CAACzE,CAAD,CAAMD,CAAN,CACpB,CAcI,OAAWC,CAAX,CAAiBqE,CAAjB,CAAkC,CAAlC,CAAyCtE,CAAzC,CAA+CsE,CAA/C,CAAgE,CAAhE,EAAsEA,CAAtE,GAA2FrE,CAA3F,CAAiGD,CAAjG,IAA0G,CAA1G,CAdJ,CAmDa2E,QAAA,EAAQ,CAAC1E,CAAD,CACrB,CACI,MAAQA,EAAA,CAAM4B,CAAN,CAAuB5B,CAAvB,CAA6BA,CAA7B,CAAmChR,CAD/C,CAaY2V,QAAA,EAAQ,CAAC3E,CAAD,CAAMD,CAAN,CACpB,CAcI,QAAWC,CAAX,CAAiBqE,CAAjB,CAAkC,CAAlC,GAAyCtE,CAAzC,CAA+CsE,CAA/C,CAAgE,CAAhE,GAAsEA,CAAtE,GAA2FrE,CAA3F,CAAiGD,CAAjG,IAA0G,CAA1G,CAdJ,CA2Ba6E,QAAA,EAAQ,CAAC7E,CAAD,CACrB,CACI,OAASA,CAAT,CAAeS,CAAf,CAAiC,CAAjC,GAAwCT,CAAxC,CAA8CG,CAA9C,EAAiEM,CADrE,CAccK,QAAA,GAAQ,CAAClC,CAAD,CAAKqB,CAAL,CAAUD,CAAV,CACtB,CACI,OAAOpB,CAAP,CAAY,GAAZ,EACA,KAAK,CAAL,CACIqB,CAAA,EAAQA,CAAR,CAAcE,CACd,MACJ,MAAK,GAAL,CACIF,CAAA,CAAM,CACN,MACJ,MAAK,GAAL,CACIA,CAAA,CAAOE,CAAP,CAAyBM,CACzB,MACJ,MAAK,GAAL,CACIR,CAAA,CAAOD,CAAA,CAAMkB,EAAN,CAAwBf,CAAxB,CAA0CM,CAA1C,CAA8D,CAXzE,CAcA,MAAOR,EAfX,CAsDcC,QAAA,GAAQ,CAACtB,CAAD,CAAKqB,CAAL,CAAUD,CAAV,CACtB,CACI,OAAOpB,CAAP,CAAY,GAAZ,EACA,KAAK,CAAL,CACWqB,CAAP,EAAaE,CACb,MACJ,MAAK,GAAL,CACIF,CAAA,CAAM,CACN,MACJ,MAAK,GAAL,CACIA,CAAA,CAAME,CACN,MACJ,MAAK,GAAL,CACIF,CAAA,CAAOD,CAAA,CAAMO,CAAN,CAAsBJ,CAAtB,CAAwC,CAXnD,CAcA,MAAOF,EAfX;AAoDa4C,QAAA,GAAQ,CAACJ,CAAD,CAAOK,CAAP,CACrB,CACIL,CAAA,CAAK,CAAL,CAAA,EAAWK,CAAA,CAAK,CAAL,CACXL,EAAA,CAAK,CAAL,CAAA,EAAWK,CAAA,CAAK,CAAL,CACPL,EAAA,CAAK,CAAL,CAAJ,EAAexT,CAAf,GACIwT,CAAA,CAAK,CAAL,CACA,EADWxT,CACX,CAAAwT,CAAA,CAAK,CAAL,CAAA,EAFJ,CAHJ,CAkBaG,QAAA,GAAQ,CAACH,CAAD,CAAOK,CAAP,CACrB,CACI,IAAIgC,EAASrC,CAAA,CAAK,CAAL,CAATqC,CAAmBhC,CAAA,CAAK,CAAL,CAClBgC,EAAL,GAAaA,CAAb,CAAsBrC,CAAA,CAAK,CAAL,CAAtB,CAAgCK,CAAA,CAAK,CAAL,CAAhC,CACA,OAAOgC,EAHX,CA4Ba9B,QAAA,GAAQ,CAACP,CAAD,CACrB,CACQA,CAAA,CAAK,CAAL,CAAJ,CAAc,CAAd,GACIA,CAAA,CAAK,CAAL,CADJ,EACexT,CADf,CAGAwT,EAAA,CAAK,CAAL,CAAA,CAAUnyB,IAAAE,MAAA,CAAWiyB,CAAA,CAAK,CAAL,CAAX,CAAqB,CAArB,CACVA,EAAA,CAAK,CAAL,CAAA,CAAUnyB,IAAAE,MAAA,CAAWiyB,CAAA,CAAK,CAAL,CAAX,CAAqB,CAArB,CALd,CAkCcM,QAAA,GAAQ,CAAC/0B,CAAD,CACtB,CACI,MAAO,CAACA,CAAA,CAAE,CAAF,CAAR,EAAgB,CAACA,CAAA,CAAE,CAAF,CADrB;AAkFA,IAAAixB,GAAoB,CAChBC,CADgB,CAEhBA,CAFgB,CAGhBA,CAHgB,CAIhBA,CAJgB,CAKhBA,CALgB,CAMhBA,CANgB,CAOhBA,CAPgB,CAQhBA,CARgB,CAShBA,CATgB,CAUhBA,CAVgB,CAWhBA,CAXgB,CAYhBA,CAZgB,CAahBA,CAbgB,CAchBA,CAdgB,CAehBA,CAfgB,CAgBhBA,CAhBgB,CAiBhBA,CAjBgB,CAkBhBA,CAlBgB,CAmBhBA,CAnBgB,CAoBhBA,CApBgB,CAqBhBA,CArBgB,CAsBhBA,CAtBgB,CAuBhBA,CAvBgB,CAwBhBA,CAxBgB,CAyBhBA,CAzBgB,CA0BhBA,CA1BgB,CA2BhBA,CA3BgB,CA4BhBA,CA5BgB,CA6BhBA,CA7BgB,CA8BhBA,CA9BgB,CA+BhBA,CA/BgB,CAgChBA,CAhCgB,CAiChBA,CAjCgB,CAkChBA,CAlCgB,CAmChBA,CAnCgB,CAoChBA,CApCgB,CAqChBA,CArCgB,CAsChBA,CAtCgB,CAuChBA,CAvCgB,CAwChBA,CAxCgB,CAyChBA,CAzCgB,CA0ChBA,CA1CgB,CA2ChBA,CA3CgB,CA4ChBA,CA5CgB,CA6ChBA,CA7CgB,CA8ChBA,CA9CgB,CA+ChBA,CA/CgB,CAgDhBA,CAhDgB,CAiDhBA,CAjDgB,CAkDhBA,CAlDgB,CAmDhBA,CAnDgB,CAoDhBA,CApDgB,CAqDhBA,CArDgB,CAsDhBA,CAtDgB,CAuDhBA,CAvDgB,CAwDhBA,CAxDgB,CAyDhBA,CAzDgB,CA0DhBA,CA1DgB,CA2DhBA,CA3DgB,CA4DhBA,CA5DgB,CA6DhBA,CA7DgB,CA8DhBA,CA9DgB,CA+DhBA,CA/DgB,CAgEhBA,CAhEgB,CAiEhByC,CAjEgB,CAkEhBA,CAlEgB,CAmEhBA,CAnEgB,CAoEhBA,CApEgB,CAqEhBA,CArEgB,CAsEhBA,CAtEgB,CAuEhBA,CAvEgB,CAwEhBA,CAxEgB,CAyEhBA,CAzEgB,CA0EhBA,CA1EgB,CA2EhBA,CA3EgB,CA4EhBA,CA5EgB,CA6EhBA,CA7EgB,CA8EhBA,CA9EgB,CA+EhBA,CA/EgB,CAgFhBA,CAhFgB,CAiFhBA,CAjFgB,CAkFhBA,CAlFgB,CAmFhBA,CAnFgB,CAoFhBA,CApFgB,CAqFhBA,CArFgB,CAsFhBA,CAtFgB,CAuFhBA,CAvFgB,CAwFhBA,CAxFgB,CAjyNNoD,QAAQ,CAACnG,CAAD,CACtB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAgyNoB,CA7wNNoG,QAAQ,CAACpG,CAAD,CACtB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA4wNoB,CA5uNNqG,QAAQ,CAACrG,CAAD,CACtB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA2uNoB,CA4FhBO,EA5FgB,CAppNL+F,QAAQ,CAACtG,CAAD,CAAKU,CAAL,CACvB,CAQU,IAAA3C,EAAN,CA3mKgBkB,IA2mKhB,GACIsH,EAAAnjB,KAAA,CAAiB,IAAjB,CAAuB4c,CAAvB,CAA2BU,CAA3B,CACA,CAAA,IAAA3C,EAAA,EA7mKYkB,IA2mKhB,CAIAuH,GAAApjB,KAAA,CAAiB,IAAjB,CAAuB4c,CAAvB,CAA2BU,CAA3B,CAZJ,CAmpNoB,CA8FhBD,EA9FgB,CA5jNLgG,QAAQ,CAACzG,CAAD,CAAKU,CAAL,CACvB,CAQU,IAAA3C,EAAN,CAnsKgBkB,IAmsKhB,GACIsH,EAAAnjB,KAAA,CAAiB,IAAjB,CAAuB4c,CAAvB,CAA2BU,CAA3B,CACA,CAAA,IAAA3C,EAAA,EArsKYkB,IAmsKhB,CAIAyH,GAAAtjB,KAAA,CAAiB,IAAjB,CAAuB4c,CAAvB,CAA2BU,CAA3B,CAZJ,CA2jNoB,CAgGhBC,EAhGgB,CAx/MNgG,QAAQ,CAAC3G,CAAD,CACtB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAu/MoB,CA5+ML4G,QAAQ,CAAC5G,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA2+MoB,CAh+ML6G,QAAQ,CAAC7G,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA+9MoB,CAp9ML8G,QAAQ,CAAC9G,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAm9MoB;AAx8ML+G,QAAQ,CAAC/G,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAu8MoB,CA57MJgH,QAAQ,CAAChH,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA27MoB,CAh7MJiH,QAAQ,CAACjH,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA+6MoB,CAp6MJkH,QAAQ,CAAClH,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAm6MoB,CAx5MNmH,QAAQ,CAACnH,CAAD,CACtB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAu5MoB,CA54MLoH,QAAQ,CAACpH,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA24MoB,CAh4MLqH,QAAQ,CAACrH,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA+3MoB,CAp3MLsH,QAAQ,CAACtH,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAm3MoB,CAx2MLuH,QAAQ,CAACvH,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAu2MoB,CA51MJwH,QAAQ,CAACxH,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA21MoB,CAh1MJyH,QAAQ,CAACzH,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA+0MoB,CAp0MJ0H,QAAQ,CAAC1H,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAm0MoB,CAxzMN2H,QAAQ,CAAC3H,CAAD,CACtB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAuzMoB,CA5yML4H,QAAQ,CAAC5H,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA2yMoB,CAhyML6H,QAAQ,CAAC7H,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA+xMoB,CApxML8H,QAAQ,CAAC9H,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAmxMoB,CAxwML+H,QAAQ,CAAC/H,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAuwMoB,CA5vMJgI,QAAQ,CAAChI,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA2vMoB,CAhvMJiI,QAAQ,CAACjI,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA+uMoB,CApuMJkI,QAAQ,CAAClI,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAmuMoB,CAxtMNmI,QAAQ,CAACnI,CAAD,CACtB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAutMoB,CA5sMLoI,QAAQ,CAACpI,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA2sMoB;AAhsMLqI,QAAQ,CAACrI,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA+rMoB,CAprMLsI,QAAQ,CAACtI,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAmrMoB,CAxqMLuI,QAAQ,CAACvI,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAuqMoB,CA5pMJwI,QAAQ,CAACxI,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA2pMoB,CAhpMJyI,QAAQ,CAACzI,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA+oMoB,CApoMJ0I,QAAQ,CAAC1I,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAmoMoB,CAiIhBY,EAjIgB,CAkIhBC,EAlIgB,CAmIhBC,EAnIgB,CA9iMJ6H,QAAQ,CAAC3I,CAAD,CAAKU,CAAL,CACxB,CACQA,CAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAAnB,CADZ,CA6iMoB,CA3hMLmL,QAAQ,CAAC5I,CAAD,CAAKU,CAAL,CACvB,CACQU,CAAAA,CAAM,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CACV2D,EAAA,EAAQA,CAAR,CAAcS,CAAd,CAAgC,CAAhC,GAAuCT,CAAvC,CAA6CG,CAA7C,EAAgEM,CAChE,KAAAjS,EAAA,CAAe8Q,CAAf,CAAmBU,CAAnB,CAHJ,CA0hMoB,CApgMJyH,QAAQ,CAAC7I,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB,IAAAjD,EAAnB,CAAgCoE,CAAhC,CADJ,CAmgMoB,CAj/LJiH,QAAQ,CAAC9I,CAAD,CAAKU,CAAL,CACxB,CACQU,CAAAA,CAAM,IAAAtR,EAAA,CAAc4Q,CAAd,CACVU,EAAA,EAAQA,CAAR,CAAcS,CAAd,CAAgC,CAAhC,GAAuCT,CAAvC,CAA6CG,CAA7C,EAAgEM,CAChE,KAAAjS,EAAA,CAAe,IAAA6N,EAAf,CAA2B2D,CAA3B,CAHJ,CAg/LoB,CA59LJ2H,QAAQ,CAAC/I,CAAD,CAAKU,CAAL,CACxB,CACQU,CAAAA,CAAM,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CACV2D,EAAA,EAAQA,CAAR,CAAcS,CAAd,CAAgC,CAAhC,GAAuCT,CAAvC,CAA6CG,CAA7C,EAAgEM,CAChE,KAAAjS,EAAA,CAAe,IAAA6N,EAAf,CAA2B2D,CAA3B,CACIV,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBU,CAAnB,CAJZ,CA29LoB,CAh8LL4H,QAAQ,CAAChJ,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBuI,EAAA7lB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAnB,CADJ,CA+7LoB,CAr6LJyL,QAAQ,CAAClJ,CAAD,CAAKU,CAAL,CACxB,CASI,IAAA9Q,EAAA,CAAe8Q,CAAf;AAAmBuI,EAAA7lB,KAAA,CAAiB,IAAjB,CAAuB,IAAAqa,EAAvB,CAAnB,CATJ,CAo6LoB,CAp4LJ0L,QAAQ,CAACnJ,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BwL,EAAA7lB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA3B,CADJ,CAm4LoB,CA32LJ0I,QAAQ,CAACpJ,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM4H,EAAA7lB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CACV,KAAA7N,EAAA,CAAe,IAAA6N,EAAf,CAA2B4D,CAA3B,CACIX,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA02LoB,CAh1LLgI,QAAQ,CAACrJ,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB4I,EAAAlmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAnB,CADJ,CA+0LoB,CArzLJ8L,QAAQ,CAACvJ,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB,IAAAjD,EAAnB,CADJ,CAozLoB,CA5xLJ+L,QAAQ,CAACxJ,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B6L,EAAAlmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA3B,CADJ,CA2xLoB,CAnwLJ+I,QAAQ,CAACzJ,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAMiI,EAAAlmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CACV,KAAA7N,EAAA,CAAe,IAAA6N,EAAf,CAA2B4D,CAA3B,CACIX,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAkwLoB,CA7uLLqI,QAAQ,CAAC1J,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBiJ,EAAAvmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAAqE,CAAA,CAArE,CAAnB,CADJ,CA4uLoB,CAztLJmM,QAAQ,CAAC5J,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBiJ,EAAAvmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAAjD,EAA1C,CAAsD,CAAA,CAAtD,CAAnB,CADJ,CAwtLoB,CArsLJoM,QAAQ,CAAC7J,CAAD;AAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BkM,EAAAvmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAAqE,CAAA,CAArE,CAA3B,CADJ,CAosLoB,CAjrLJqM,QAAQ,CAAC9J,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBiJ,EAAAvmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAAqE,CAAA,CAArE,CAAnB,CAA3B,CADJ,CAgrLoB,CA7pLNsM,QAAQ,CAAC/J,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBiJ,EAAAvmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAAnB,CACA,KAAA7N,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC,IAAA5C,EAAhC,CAFJ,CA4pLoB,CAxoLLkM,QAAQ,CAAChK,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBiJ,EAAAvmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAAjD,EAA1C,CAAnB,CACA,KAAA7N,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC,IAAA5C,EAAhC,CAFJ,CAuoLoB,CAnnLLmM,QAAQ,CAACjK,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BkM,EAAAvmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAA3B,CADJ,CAknLoB,CA/lLLyM,QAAQ,CAAClK,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBiJ,EAAAvmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAAnB,CAA3B,CACA,KAAA7N,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC,IAAA5C,EAAhC,CAFJ,CA8lLoB,CAxkLLqM,QAAQ,CAACnK,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM+I,EAAAhnB,KAAA,CAAiB,IAAjB;AAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,IAAA3N,EAAA,CAAc4Q,CAAd,CAAlD,CACA,EAAV,CAAIW,CAAJ,GACA,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CACA,CAAA,IAAAzR,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC,IAAA5C,EAAhC,CAFA,CAFJ,CAukLoB,CA/iLJuM,QAAQ,CAACrK,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM+I,EAAAhnB,KAAA,CAAiB,IAAjB,CAAuB,IAAAqa,EAAvB,CAAmC,IAAA3N,EAAA,CAAc4Q,CAAd,CAAnC,CACA,EAAV,CAAIW,CAAJ,GACA,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CACA,CAAA,IAAAzR,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC,IAAA5C,EAAhC,CAFA,CAFJ,CA8iLoB,CAthLJwM,QAAQ,CAACtK,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM+I,EAAAhnB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,IAAA3N,EAAA,CAAc4Q,CAAd,CAAlD,CACA,EAAV,CAAIW,CAAJ,EACA,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B4D,CAA3B,CAHJ,CAqhLoB,CA9/KJkJ,QAAQ,CAACvK,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM+I,EAAAhnB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,IAAA3N,EAAA,CAAc4Q,CAAd,CAAlD,CACA,EAAV,CAAIW,CAAJ,GACA,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAA3B,CACA,CAAA,IAAAzR,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC,IAAA5C,EAAhC,CAFA,CAFJ,CA6/KoB,CAp+KN0M,QAAQ,CAACxK,CAAD,CAAKU,CAAL,CACtB,CACQ6C,CAAAA,CAAM,IAAAzT,EAAA,CAAc4Q,CAAd,CACV,KAAIW,EAAM,IAAAvR,EAAA,CAAe4Q,CAAf,CAAoB,CAApB,CAAyB,EAAzB,CACVW,EAAA,CAAM+I,EAAAhnB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD4D,CAAlD,CAAuDkC,CAAvD,CACI,EAAV,CAAIlC,CAAJ,GACA,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CACA,CAAA,IAAAzR,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC,IAAA5C,EAAhC,CAFA,CAJJ,CAm+KoB,CAx8KL2M,QAAQ,CAACzK,CAAD,CAAKU,CAAL,CACvB,CACQ6C,CAAAA,CAAM,IAAAzT,EAAA,CAAc4Q,CAAd,CACV,KAAIW;AAAM,IAAAvR,EAAA,CAAe4Q,CAAf,CAAoB,CAApB,CAAyB,EAAzB,CACVW,EAAA,CAAM+I,EAAAhnB,KAAA,CAAiB,IAAjB,CAAuB,IAAAqa,EAAvB,CAAmC4D,CAAnC,CAAwCkC,CAAxC,CACI,EAAV,CAAIlC,CAAJ,GACA,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CACA,CAAA,IAAAzR,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC,IAAA5C,EAAhC,CAFA,CAJJ,CAu8KoB,CA56KL4M,QAAQ,CAAC1K,CAAD,CAAKU,CAAL,CACvB,CACQ6C,CAAAA,CAAM,IAAAzT,EAAA,CAAc4Q,CAAd,CACNW,EAAAA,CAAM,IAAAvR,EAAA,CAAe4Q,CAAf,CAAoB,CAApB,CAAyB,EAAzB,CACVW,EAAA,CAAM+I,EAAAhnB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD4D,CAAlD,CAAuDkC,CAAvD,CACI,EAAV,CAAIlC,CAAJ,EACA,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B4D,CAA3B,CALJ,CA26KoB,CAj5KLsJ,QAAQ,CAAC3K,CAAD,CAAKU,CAAL,CACvB,CACQ6C,CAAAA,CAAM,IAAAzT,EAAA,CAAc4Q,CAAd,CACV,KAAIW,EAAM,IAAAvR,EAAA,CAAe4Q,CAAf,CAAoB,CAApB,CAAyB,EAAzB,CACVW,EAAA,CAAM+I,EAAAhnB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD4D,CAAlD,CAAuDkC,CAAvD,CACI,EAAV,CAAIlC,CAAJ,GACA,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmB,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B4D,CAA3B,CAAnB,CACA,CAAA,IAAAzR,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC,IAAA5C,EAAhC,CAFA,CAJJ,CAg5KoB,CA/1KN8M,QAAQ,CAAC5K,CAAD,CAAKU,CAAL,CACtB,CAKI,GADIvwB,CACJ,EADW,IAAAstB,EACX,CADwBoN,EACxB,GAD6C,EAC7C,EADoD,EACpD,CAD2D,IAAApN,EAC3D,CADwE,GACxE,CAAO,CAAA,IAECltB,EAAI,IAAAuf,EAAA,CAAc4Q,CAAd,CACR,IAAQ,CAAR,CAAIvwB,CAAJ,CAAW,CACP,IAAA26B,EAAOnJ,CACP,KAAArxB,EAAKC,CAAD,CAAK0yB,CAAL,CAAuB,CAAvB,CAA2BA,CACvB,GAAR,CAAI9yB,CAAJ,GACIG,CAcA,EAdMC,CAcN,CAdUmB,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAcV,CAd4B8yB,CAc5B,CAAA6H,CAAA,CAAO7H,CAAP,CAAyBvxB,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAf7B,CAiBII,EAAJ,CAAQ0yB,CAAR,CAMQ1yB,CANR,CAMYu6B,CANZ,CAMmBnJ,CANnB,GAOQ,IAAA5D,EAPR,EAx7MQkB,MAw7MR,EAeQ1uB,CAfR;AAeYu6B,CAfZ,CAemB7H,CAfnB,GAgBQ,IAAAlF,EAhBR,EAx7MQkB,MAw7MR,CApBO,CAAX,IAwCc,GAAV,EAAI9uB,CAAJ,CACIG,CADJ,CACSC,CAAD,CAAK0yB,CAAL,CAAuB,CAAvB,CAA2BtB,CADnC,EAGIrxB,CACA,CADIoB,IAAAE,MAAA,CAAWrB,CAAX,CAAemB,IAAAC,IAAA,CAAS,CAAT,CAAY,CAACxB,CAAb,CAAf,CACJ,CAAII,CAAJ,CAAQoxB,CAAR,GACImJ,CACA,CADOza,CACP,CAD0B3e,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAC1B,CAAAG,CAAA,EAAKw6B,CAFT,CAJJ,CAWJ,KAAAlb,EAAA,CAAe8Q,CAAf,CAAmBpwB,CAAnB,CAtDG,CALX,CA81KoB,CA5wKNy6B,QAAQ,CAAC/K,CAAD,CAAKU,CAAL,CACtB,CAKI,GADIvwB,CACJ,GADY,IAAAstB,EACZ,CADyBoN,EACzB,GAD8C,EAC9C,EADqD,EACrD,CAD4D,IAAApN,EAC5D,CADyE,GACzE,EADkF,EAClF,CAAO,CACH,IAAIltB,EAAI,IAAAuf,EAAA,CAAc4Q,CAAd,CAIA,EAAR,CAAIvwB,CAAJ,GAAWA,CAAX,CAAe,EAAf,CAAoBA,CAApB,CACAI,EAAA,CAAMA,CAAN,CAAUmB,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAAV,CAA4BkgB,CAA5B,CAAgD3e,IAAAE,MAAA,CAAWrB,CAAX,CAAemB,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAAf,CAChD,KAAAyf,EAAA,CAAe8Q,CAAf,CAAmBnwB,CAAnB,CAPG,CALX,CA2wKoB,CA3tKNy6B,QAAQ,CAAChL,CAAD,CAAKU,CAAL,CACtB,CAKI,GADIvwB,CACJ,EADW,IAAAstB,EACX,CADwBoN,EACxB,GAD6C,EAC7C,EADoD,EACpD,CAD2D,IAAApN,EAC3D,CADwE,GACxE,CAAO,CACH,IAAIltB,EAAI,IAAAuf,EAAA,CAAc4Q,CAAd,CAGAnwB,EAAA,CAFA,CAAR,CAAIJ,CAAJ,CACa,EAAT,EAAIA,CAAJ,CACQ,CADR,CAGSI,CAHT,CAGamB,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAHb,CAG+BkgB,CAJnC,CAOc,GAAV,EAAIlgB,CAAJ,CACQ,CADR,CAGQuB,IAAAE,MAAA,CAAWrB,CAAX,CAAemB,IAAAC,IAAA,CAAS,CAAT,CAAY,CAACxB,CAAb,CAAf,CAGZ,KAAAyf,EAAA,CAAe8Q,CAAf,CAAmBnwB,CAAnB,CAfG,CALX,CA0tKoB,CAnrKL06B,QAAQ,CAACjL,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,CACV,KAAID,EAAM,IAAAtR,EAAA,CAAc4Q,CAAd,CACV,IAAIU,CAAJ,CAAS,CACL,IAAA,CAAOA,CAAP,CAAa6B,CAAb,CAAA,CACI5B,CAAA,EACA,CAAAD,CAAA,EAAO,CAEXvS,EAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CALK,CAOT,IAAA7N,EAAA,CAAgB8Q,CAAhB;AAAqB,CAArB,CAA0B,EAA1B,CAAgCW,CAAhC,CAVJ,CAkrKoB,CAlpKL6J,QAAQ,CAAClL,CAAD,CAAKU,CAAL,CACvB,CAKI,GADIvwB,CACJ,EADW,IAAAstB,EACX,CADwBoN,EACxB,GAD6C,EAC7C,EADoD,EACpD,CAD2D,IAAApN,EAC3D,CADwE,GACxE,CAAO,CACH,IACI0N,EAAQ,IAAArb,EAAA,CAAc4Q,CAAd,CADZ,CAEI0K,EAAS,IAAAtb,EAAA,CAAe4Q,CAAf,CAAoB,CAApB,CAAyB,EAAzB,CACb,IAAQ,CAAR,CAAIvwB,CAAJ,CAAW,CAKP,IAAIk7B,EAAYF,CAChB,IAAS,EAAT,EAAIh7B,CAAJ,CAAa,CAKT,GAAY,CAAZ,CAAIg7B,CAAJ,EAAiBA,CAAjB,CAAyBlI,CAAzB,EAA4CkI,CAA5C,CAAoDxJ,CAApD,EAAsEwJ,CAAtE,CAA8ElK,CAA9E,CACI,IAAAlD,EAAA,EA9nNAkB,MAgoNJ,IAAS,EAAT,EAAI9uB,CAAJ,CAAa,CAKT,GAAa,CAAb,CAAIi7B,CAAJ,EAAkBA,CAAlB,CAA2BnI,CAA3B,EAA8CmI,CAA9C,CAAuDzJ,CAAvD,EAAyEyJ,CAAzE,CAAkFnK,CAAlF,CACI,IAAAlD,EAAA,EAtoNJkB,MAwoNAkM,EAAA,CAAQ,CARC,CAAb,IASO,CAIHA,CAAA,CAASC,CAAT,CAAkB15B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAAgB,EAAhB,CAAlB,CAAyC8yB,CACzC,KAAA6H,EAAO7H,CAAP6H,CAAyBp5B,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CACrBk7B,EAAJ,EAAiB1J,CAAjB,CAMQyJ,CANR,CAMiBN,CANjB,CAMwBnJ,CANxB,GAOQ,IAAA5D,EAPR,EA/oNAkB,MA+oNA,EAeQmM,CAfR,CAeiBN,CAfjB,EAeyBnJ,CAfzB,GAgBQ,IAAA5D,EAhBR,EA/oNAkB,MA+oNA,CANG,CA0BPmM,CAAA,CAAS,CACLC,EAAJ,CAAgB1J,CAAhB,GACIwJ,CACA,EADSlI,CACT,CAAAmI,CAAA,EAAUnI,CAFd,CA5CS,CAAb,IAoDIkI,EAMA,CANUA,CAMV,CANkBz5B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAMlB,CANoC8yB,CAMpC,CANuDvxB,IAAAE,MAAA,CAAYw5B,CAAZ,CAAqBnI,CAArB,CAAwCvxB,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAAxC,CAMvD,CALAi7B,CAKA,CALUA,CAKV,CALmB15B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAKnB,CALqC8yB,CAKrC,CADA6H,CACA,CADO7H,CACP,CADyBvxB,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CACzB,CAAIk7B,CAAJ,EAAiB1J,CAAjB,CAMQ0J,CANR,CAMoBP,CANpB,CAM2BnJ,CAN3B,GAOQ,IAAA5D,EAPR,EAlrNIkB,MAkrNJ,GAeQoM,CAOJ,CAPgBP,CAOhB,EAPwBnJ,CAOxB,GANI,IAAA5D,EAMJ,EAxsNAkB,MAwsNA,EADAkM,CACA,EADSlI,CACT,CAAAmI,CAAA,EAAUnI,CAtBd,CAhEG,CAAX,IA8Fc,GAAV;AAAI9yB,CAAJ,EAEQi7B,CAIJ,CALU,GAAV,EAAIj7B,CAAJ,CACcg7B,CAAA,CAAQxJ,CAAR,CAAwBV,CAAxB,CAA0C,CADxD,CAGavvB,IAAAE,MAAA,CAAYu5B,CAAZ,CAAoBlI,CAApB,CAAuCvxB,IAAAC,IAAA,CAAS,CAAT,CAAY,CAACxB,CAAb,CAAiB,EAAjB,CAAvC,CAEb,CAAIg7B,CAAJ,EAAaxJ,CAAb,CACIwJ,CADJ,CACY,CADZ,EAGIA,CACA,CADQlK,CACR,CAAAmK,CAAA,EAAUnI,CAJd,CANJ,GAgBI6H,CAWA,CAXQK,CAAA,CAAQxJ,CAAR,CAAwBtR,CAAxB,CAA2C3e,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAA3C,CAAiE,CAWzE,CALAi7B,CAKA,CALS15B,IAAAE,MAAA,CAAYw5B,CAAZ,CAAqBnI,CAArB,CAAwCvxB,IAAAC,IAAA,CAAS,CAAT,CAAY,CAACxB,CAAb,CAAxC,CAKT,CALuEg7B,CAKvE,CAL+ElI,CAK/E,CALkGvxB,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAKlG,CALyH8yB,CAKzH,CAJAkI,CAIA,CAJQz5B,IAAAE,MAAA,CAAWu5B,CAAX,CAAmBz5B,IAAAC,IAAA,CAAS,CAAT,CAAY,CAACxB,CAAb,CAAnB,CAIR,CAJ8C26B,CAI9C,CAAIK,CAAJ,CAAYxJ,CAAZ,GAA4ByJ,CAA5B,EAAsCnI,CAAtC,CA3BJ,CA8BJ,KAAArT,EAAA,CAAe8Q,CAAf,CAAmByK,CAAnB,CACA,KAAAvb,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC0K,CAAhC,CAjIG,CALX,CAipKoB,CAl/JLE,QAAQ,CAACtL,CAAD,CAAKU,CAAL,CACvB,CAKI,GADIvwB,CACJ,GADY,IAAAstB,EACZ,CADyBoN,EACzB,GAD8C,EAC9C,EADqD,EACrD,CAD4D,IAAApN,EAC5D,CADyE,GACzE,EADkF,EAClF,CAAO,CACH,IAAI0N,EAAQ,IAAArb,EAAA,CAAc4Q,CAAd,CAAZ,CACI0K,EAAS,IAAAtb,EAAA,CAAe4Q,CAAf,CAAoB,CAApB,CAAyB,EAAzB,CADb,CAEI2K,EAAYF,CAIR,EAAR,CAAIh7B,CAAJ,GAAWA,CAAX,CAAe,EAAf,CAAoBA,CAApB,CACQ,GAAR,CAAIA,CAAJ,EACIg7B,CACA,CADUA,CACV,CADkBz5B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAClB,CADoCkgB,CACpC,CADwD3e,IAAAE,MAAA,CAAWw5B,CAAX,CAAoB15B,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAApB,CACxD,CAAAi7B,CAAA,CAAWA,CAAX,CAAoB15B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAApB,CAAsCkgB,CAAtC,CAA0D3e,IAAAE,MAAA,CAAWy5B,CAAX,CAAuB35B,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAAvB,CAF9D,GAIIg7B,CACA,CADUC,CACV,CADmB15B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAAgB,EAAhB,CACnB,CAD0CkgB,CAC1C,CAD8D3e,IAAAE,MAAA,CAAWu5B,CAAX,CAAmBz5B,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ;AAAiBxB,CAAjB,CAAnB,CAC9D,CAAAi7B,CAAA,CAAWC,CAAX,CAAuB35B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAAgB,EAAhB,CAAvB,CAA8CkgB,CAA9C,CAAkE3e,IAAAE,MAAA,CAAWw5B,CAAX,CAAoB15B,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAApB,CALtE,CAOA,KAAAyf,EAAA,CAAe8Q,CAAf,CAAmByK,CAAnB,CACA,KAAAvb,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC0K,CAAhC,CAhBG,CALX,CAi/JoB,CAn8JLG,QAAQ,CAACvL,CAAD,CAAKU,CAAL,CACvB,CAKI,GADIvwB,CACJ,EADW,IAAAstB,EACX,CADwBoN,EACxB,GAD6C,EAC7C,EADoD,EACpD,CAD2D,IAAApN,EAC3D,CADwE,GACxE,CAAO,CACH,IAAI0N,EAAQ,IAAArb,EAAA,CAAc4Q,CAAd,CAAZ,CACI0K,EAAS,IAAAtb,EAAA,CAAe4Q,CAAf,CAAoB,CAApB,CAAyB,EAAzB,CACL,EAAR,CAAIvwB,CAAJ,CACa,EAAT,EAAIA,CAAJ,EAEQg7B,CAIJ,CALS,EAAT,EAAIh7B,CAAJ,CACY,CADZ,CAGai7B,CAHb,CAGsB15B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAAgB,EAAhB,CAHtB,CAG6CkgB,CAE7C,CAAA+a,CAAA,CAAS,CANb,GAQID,CACA,CADUA,CACV,CADkBz5B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAClB,CADoCkgB,CACpC,CADwD3e,IAAAE,MAAA,CAAWw5B,CAAX,CAAoB15B,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAApB,CACxD,CAAAi7B,CAAA,CAAUA,CAAV,CAAmB15B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAAnB,CAAqCkgB,CATzC,CADJ,CAac,GAAV,EAAIlgB,CAAJ,EAEQi7B,CAIJ,CALU,GAAV,EAAIj7B,CAAJ,CACa,CADb,CAGauB,IAAAE,MAAA,CAAWu5B,CAAX,CAAmBz5B,IAAAC,IAAA,CAAS,CAAT,CAAY,CAACxB,CAAb,CAAiB,EAAjB,CAAnB,CAEb,CAAAg7B,CAAA,CAAQ,CANZ,GAQIC,CACA,CADS15B,IAAAE,MAAA,CAAWw5B,CAAX,CAAoB15B,IAAAC,IAAA,CAAS,CAAT,CAAY,CAACxB,CAAb,CAApB,CACT,CADkDg7B,CAClD,CAD0Dz5B,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAC1D,CADiFkgB,CACjF,CAAA8a,CAAA,CAAQz5B,IAAAE,MAAA,CAAWu5B,CAAX,CAAmBz5B,IAAAC,IAAA,CAAS,CAAT,CAAY,CAACxB,CAAb,CAAnB,CATZ,CAYJ,KAAAyf,EAAA,CAAe8Q,CAAf,CAAmByK,CAAnB,CACA,KAAAvb,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC0K,CAAhC,CA7BG,CALX,CAk8JoB,CAwKhBrI,CAxKgB,CAj5JLyI,QAAQ,CAACxL,CAAD,CAAKU,CAAL,CACvB,CACQ+K,CAAAA,CAAM,IAAA3b,EAAA,CAAc4Q,CAAd,CACV,KAAA9Q,EAAA,CAAe8Q,CAAf;AAAmB,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAAnB,CACA,KAAA7N,EAAA,CAAe,IAAA6N,EAAf,CAA2BgO,CAA3B,CAHJ,CAg5JoB,CAl3JNC,QAAQ,CAAC1L,CAAD,CAAKU,CAAL,CACtB,CACI,IAAmBiL,EAAfC,CAAeD,CAAP,CAAA,CAAZ,CACIE,EAAU,IAAA/b,EAAA,CAAc4Q,CAAd,CADd,CAEIoL,EAAWD,CAAXC,CAAqBjK,CAArBiK,CAAuC,CAE3C,KADAD,CACA,EADWtK,CACX,CAAO,CAACqK,CAAR,CAAA,CAaI,GAZA,IAAAhc,EAAA,CAAeic,CAAf,CAAwB,IAAA/b,EAAA,CAAcgc,CAAd,CAAxB,CAYI,EALEF,CAKF,CALWC,CAKX,EALsB,IAAApO,EAKtB,IAJAqO,CAEA,CAFWA,CAEX,CAFqB,CAErB,CAF0BvK,CAE1B,CADAsK,CACA,CADWA,CACX,CADqB,CACrB,CAD0BtK,CAC1B,CAAAoK,CAAA,CAAU,CAAA,CAEV,EAAAC,CAAA,EAAS,CAACG,IAr8HPluB,MAAA+Q,EAq8HP,CAAgC,CAKxB+c,CAAJ,EAAa,IAAA/b,EAAA,CAAe8Q,CAAf,CAAmBoL,CAAnB,CAA6BjK,CAA7B,CAAgDgK,CAAhD,CACRD,EAAL,EAAY1M,EAAA,CAAAA,IAAA,CAAgB,EAAhB,CACZ,MAP4B,CAlBxC,CAi3JoB,CAl0JJ8M,QAAQ,CAAChM,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,EAAO,IAAAvR,EAAA,CAAc4Q,CAAd,CAAPW,CAA2B,MAA3BA,EAA6ChR,CACjD,KAAAT,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CACIA,EAAJ,CAAU4B,CAAV,EAA2BpU,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAH/B,CAi0JoB,CA1yJJwO,QAAQ,CAACjM,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,EAAO,IAAAvR,EAAA,CAAc4Q,CAAd,CAAPW,CAA2B,MAA3BA,EAA6ChR,CACjD,KAAAT,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CACIA,EAAJ,EAAW4B,CAAX,EAA4BpU,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAHhC,CAyyJoB,CA1vJLyO,QAAQ,CAAClM,CAAD,CAAKU,CAAL,CACvB,CACQA,CAAJ,CAAS,CAAT,GAIIyL,IAzyFApO,EAqyFJ,EA7/NgBkB,IA6/NhB,CAMIyB,EAAJ,CAAS,CAAT,EAII1B,EAAA,CAAAA,IAAA,CAAY,IAAAzB,GAAZ,CAAyBsE,CAAzB,CAA2C,CAA3C,CAEAnB,EAAJ,CAAS,CAAT,EAIIzR,CAAA,CAAAA,IAAA,CAEAyR,EAAJ,CAAS,CAAT,EAII,IAAAzD,EAAA,CAAiB+C,CAAjB,CAEJnR,EAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAzBJ,CAyvJoB,CA9rJL2O,QAAQ,CAACpM,CAAD,CAAKU,CAAL,CACvB,CAIQ2L,CAAAA,CAAS3L,CAAT2L,EAAe,EACf,KAAAtO,EAAJ,CAAiBsO,CAAjB,GACI,IAAAtO,EACA,EADc,CAACsO,CACf;AAAAxd,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAFJ,CALJ,CA6rJoB,CAnqJN6O,QAAQ,EACtB,CACI,IAAAzO,EAAA,CAAa,IAAAJ,EADjB,CAkqJoB,CAgLhBsF,CAhLgB,CA3oJJwJ,QAAQ,CAACvM,CAAD,CAAKU,CAAL,CACxB,CACQ1wB,CAAAA,EAAK,IAAA8f,EAAA,CAAc4Q,CAAd,CAAL1wB,CAAyB,MAAzBA,EAA2CqgB,CAC/C,KAAAT,EAAA,CAAe8Q,CAAf,CAAmB1wB,CAAnB,CACOA,EAAP,CAAW6xB,CAAX,CAA6B,CAA7B,GACI,IAAA9D,EADJ,EAtmOekB,MAsmOf,CAGA,KAAArP,EAAA,CAAe5f,CAAf,CAAmB8vB,EAAnB,EAAoC0M,IAx7FxBzO,EAw7FZ,CAx7FyBwD,CAw7FzB,EAAmDM,CAAnD,CAAsE4K,IA7yF3Dnc,EA6yFX,CACA,KAAAyN,EAAA,EAAc,KACdlP,EAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CARJ,CA0oJoB,CAnmJLiP,QAAQ,CAAC1M,CAAD,CAAKU,CAAL,CACvB,CACQ1wB,CAAAA,CAAI,IAAA8f,EAAA,CAAc4Q,CAAd,CAKJ1wB,EAAA,EAAK,MACL,KAAA4f,EAAA,CAAe5f,CAAf,CAAmB8vB,EAAnB,CAAoC,IAAAhQ,EAAA,CAAc,IAAA2N,EAAd,CAApC,CACIztB,EAAJ,EAASqgB,CAAT,GAA2BrgB,CAA3B,EAAgCqgB,CAAhC,CACOrgB,EAAP,CAAW6xB,CAAX,CAA6B,CAA7B,GACI,IAAA9D,EADJ,EAppOWkB,MAopOX,CAeJ,KAAArP,EAAA,CAAe8Q,CAAf,CAAmB1wB,CAAnB,CAxBJ,CAkmJoB,CAvjJN28B,QAAQ,CAAC3M,CAAD,CAAKU,CAAL,CACtB,CACQ1wB,CAAAA,CAAI,IAAA8f,EAAA,CAAc4Q,CAAd,CACR,KAAIU,EAAM,IAAAtR,EAAA,CAAc9f,CAAd,CAAkB8vB,EAAlB,CACV,KAAAlQ,EAAA,CAAe,IAAA6N,EAAf,CAA2B2D,CAA3B,CACI,KAAA3D,EAAJ,EAAkBiD,CAAlB,GAAsB1wB,CAAtB,CAA0BoxB,CAA1B,CACApxB,EAAA,EAAK,MACG,EAAR,CAAIA,CAAJ,GAAWA,CAAX,EAAgBqgB,CAAhB,CACA,EAAMrgB,CAAN,CAAU6xB,CAAV,CAA4B,CAA5B,GAAkCN,CAAlC,GACI,IAAAxD,EADJ,EA9rOekB,MA8rOf,CAGA,KAAArP,EAAA,CAAe8Q,CAAf,CAAmB1wB,CAAnB,CAVJ,CAsjJoB,CAzhJL48B,QAAQ,CAAC5M,CAAD,CAAKU,CAAL,CACvB,CACQ1wB,CAAAA,CAAI,IAAA8f,EAAA,CAAc4Q,CAAd,CACR,KAAIvB,EAAK,IAAArP,EAAA,CAAc9f,CAAd,CAAkB8vB,EAAlB,CACT9vB,EAAA,EAAK,MACG,EAAR,CAAIA,CAAJ,GAAWA,CAAX;AAAgBqgB,CAAhB,CACA,EAAMrgB,CAAN,CAAU6xB,CAAV,CAA4B,CAA5B,GAAkCN,CAAlC,GACI,IAAAxD,EADJ,EA1tOekB,MA0tOf,CAGA,KAAArP,EAAA,CAAe8Q,CAAf,CAAmB1wB,CAAnB,CACA6e,EAAA,CAAAA,IAAA,CAAWsQ,CAAX,CAAgBW,EAAhB,CATJ,CAwhJoB,CA3/IN+M,QAAQ,EACtB,CACI,IAAAjd,EAAA,CAAe,IAAA6N,EAAf,EAA2B+O,IAnkGfzO,EAmkGZ,CAnkGyBwD,CAmkGzB,EAA0CM,CAA1C,CAA6D4K,IAx7FlDnc,EAw7FX,CACA,KAAAyN,EAAA,EAAc,KACdlP,EAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAAwB,CAAxB,CAHJ,CA0/IoB,CAn+INqP,QAAQ,CAAC9M,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,EAAmB8L,IA3lGPzO,EA2lGZ,CA3lGyBwD,CA2lGzB,EAAkCM,CAAlC,CAAqD4K,IAh9F1Cnc,EAg9FX,CACA,KAAAyN,EAAA,EAAc,KACdlP,EAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAHJ,CAk+IoB,CAp8INsP,QAAQ,CAAC/M,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA3N,EAAA,CAAc4Q,CAAd,CAA3B,CACA,KAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB,IAAAjD,EAAnB,CAAgCoE,CAAhC,CAAmD4K,IAh/FxCnc,EAg/FX,CACAzB,EAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAAwB,CAAxB,CAHJ,CAm8IoB,CAv6INuP,QAAQ,CAAChN,CAAD,CAAKU,CAAL,CACtB,CACQuM,CAAAA,CAAM,IAAAnd,EAAA,CAAc4Q,CAAd,CACV,KAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB,IAAA5Q,EAAA,CAAemd,CAAf,CAAqBpL,CAArB,CAAuC,CAAvC,CAAnB,CACAhT,EAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAHJ,CAs6IoB,CA/4INyP,QAAQ,CAAClN,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAAnB,CADJ,CA84IoB,CAz3IL2P,QAAQ,CAACpN,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAAjD,EAA1C,CAAnB,CADJ,CAw3IoB,CAn2IL4P,QAAQ,CAACrN,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf;AAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAA3B,CADJ,CAk2IoB,CA70IL6P,QAAQ,CAACtN,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAAnB,CAA3B,CADJ,CA40IoB,CAvzIN8P,QAAQ,CAACvN,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB8M,EAAApqB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAAnB,CADJ,CAszIoB,CAjyILgQ,QAAQ,CAACzN,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB8M,EAAApqB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAAjD,EAA1C,CAAnB,CADJ,CAgyIoB,CA3wILiQ,QAAQ,CAAC1N,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B+P,EAAApqB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAA3B,CADJ,CA0wIoB,CArvILkQ,QAAQ,CAAC3N,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmB8M,EAAApqB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAAnB,CAA3B,CADJ,CAovIoB,CARFoF,EAQE,CApuIL+K,QAAQ,CAAC5N,CAAD,CAAKU,CAAL,CACvB,CACmD,CAA/C,CAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAJ,EAAkD5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADtD,CAmuIoB,CAntILud,QAAQ,CAAC7N,CAAD,CAAKU,CAAL,CACvB,CACoD,CAAhD,EAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAJ,EAAmD5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADvD,CAktIoB;AAlsIJwd,QAAQ,CAAC9N,CAAD,CAAKU,CAAL,CACxB,CACoD,CAAhD,EAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAJ,EAAmD5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADvD,CAisIoB,CAjrILyd,QAAQ,EACvB,CAEIlf,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAFJ,CAgrIoB,CA/pIJ0d,QAAQ,CAAChO,CAAD,CAAKU,CAAL,CACxB,CACoD,CAAhD,EAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAJ,EAAmD5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADvD,CA8pIoB,CA9oIL2d,QAAQ,CAACjO,CAAD,CAAKU,CAAL,CACvB,CACoD,CAAhD,EAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAJ,EAAmD5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADvD,CA6oIoB,CA7nIL4d,QAAQ,CAAClO,CAAD,CAAKU,CAAL,CACvB,CACmD,CAA/C,CAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAJ,EAAkD5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADtD,CA4nIoB,CAPFwS,EAOE,CA3mILqL,QAAQ,CAACnO,CAAD,CAAKU,CAAL,CACvB,CACkE,CAA9D,CAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAJ,EAAiE5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADrE,CA0mIoB,CAzlIL8d,QAAQ,CAACpO,CAAD,CAAKU,CAAL,CACvB,CACmE,CAA/D,EAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAJ,EAAkE5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADtE,CAwlIoB,CAvkIJ+d,QAAQ,CAACrO,CAAD,CAAKU,CAAL,CACxB,CACmE,CAA/D,EAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAJ,EAAkE5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADtE,CAskIoB,CArjILge,QAAQ,EACvB,CAEIzf,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAFJ,CAojIoB,CAliIJie,QAAQ,CAACvO,CAAD,CAAKU,CAAL,CACxB,CACmE,CAA/D,EAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV;AAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAJ,EAAkE5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADtE,CAiiIoB,CAhhILke,QAAQ,CAACxO,CAAD,CAAKU,CAAL,CACvB,CACmE,CAA/D,EAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAJ,EAAkE5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADtE,CA+gIoB,CA9/HLme,QAAQ,CAACzO,CAAD,CAAKU,CAAL,CACvB,CACkE,CAA9D,CAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAJ,EAAiE5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADrE,CA6/HoB,CANFuS,EAME,CA7+HJ6L,QAAQ,CAAC1O,CAAD,CAAKU,CAAL,CACxB,CACwC,CAApC,CAAIqF,CAAA,CAAW,IAAAjW,EAAA,CAAc4Q,CAAd,CAAX,CAAJ,EAAuC7R,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAD3C,CA4+HoB,CA59HJkR,QAAQ,CAAC3O,CAAD,CAAKU,CAAL,CACxB,CACyC,CAArC,EAAIqF,CAAA,CAAW,IAAAjW,EAAA,CAAc4Q,CAAd,CAAX,CAAJ,EAAwC7R,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAD5C,CA29HoB,CA38HHmR,QAAQ,CAAC5O,CAAD,CAAKU,CAAL,CACzB,CACyC,CAArC,EAAIqF,CAAA,CAAW,IAAAjW,EAAA,CAAc4Q,CAAd,CAAX,CAAJ,EAAwC7R,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAD5C,CA08HoB,CA17HJoR,QAAQ,EACxB,CACIhgB,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CADJ,CAy7HoB,CAz6HHqR,QAAQ,CAAC9O,CAAD,CAAKU,CAAL,CACzB,CACyC,CAArC,EAAIqF,CAAA,CAAW,IAAAjW,EAAA,CAAc4Q,CAAd,CAAX,CAAJ,EAAwC7R,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAD5C,CAw6HoB,CAx5HJsR,QAAQ,CAAC/O,CAAD,CAAKU,CAAL,CACxB,CACyC,CAArC,EAAIqF,CAAA,CAAW,IAAAjW,EAAA,CAAc4Q,CAAd,CAAX,CAAJ,EAAwC7R,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAD5C,CAu5HoB,CAv4HJuR,QAAQ,CAAChP,CAAD,CAAKU,CAAL,CACxB,CACwC,CAApC,CAAIqF,CAAA,CAAW,IAAAjW,EAAA,CAAc4Q,CAAd,CAAX,CAAJ,EAAuC7R,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAD3C,CAs4HoB,CAr3HLwR,QAAQ,CAACjP,CAAD,CAAKU,CAAL,CACvB,CACQA,CAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAAnB,CADZ,CAo3HoB;AAn2HJyR,QAAQ,CAAClP,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CACY,EAAtB,CAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAAyBxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAk2HoB,CA/0HJ8N,QAAQ,CAACnP,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CACa,EAAvB,EAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA80HoB,CA3zHH+N,QAAQ,CAACpP,CAAD,CAAKU,CAAL,CACzB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CACa,EAAvB,EAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA0zHoB,CAvyHJgO,QAAQ,CAACrP,CAAD,CAAKU,CAAL,CACxB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACIoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAAnB,CAFZ,CAsyHoB,CApxHH6R,QAAQ,CAACtP,CAAD,CAAKU,CAAL,CACzB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CACa,EAAvB,EAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAmxHoB,CAhwHJkO,QAAQ,CAACvP,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CACa,EAAvB,EAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA+vHoB,CA5uHJmO,QAAQ,CAACxP,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CACY,EAAtB,CAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAAyBxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA2uHoB,CAvtHNoO,QAAQ,CAACzP,CAAD;AAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,CAA1C,CAAnB,CADJ,CAstHoB,CApsHLgP,QAAQ,CAAC1P,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,CAA1C,CAAnB,CACY,EAAtB,CAAIqF,CAAA,CAAW1E,CAAX,CAAJ,EAAyBxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF7B,CAmsHoB,CAhrHLkS,QAAQ,CAAC3P,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,CAA1C,CAAnB,CACa,EAAvB,EAAIqF,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF9B,CA+qHoB,CA5pHJmS,QAAQ,CAAC5P,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,CAA1C,CAAnB,CACa,EAAvB,EAAIqF,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF9B,CA2pHoB,CAxoHLoS,QAAQ,CAAC7P,CAAD,CAAKU,CAAL,CACvB,CACc,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,CAA1C,CAAnB,CACV7R,EAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAFJ,CAuoHoB,CApnHJqS,QAAQ,CAAC9P,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,CAA1C,CAAnB,CACa,EAAvB,EAAIqF,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF9B,CAmnHoB,CAhmHLsS,QAAQ,CAAC/P,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,CAA1C,CAAnB,CACa,EAAvB,EAAIqF,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF9B,CA+lHoB,CA5kHLuS,QAAQ,CAAChQ,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf;AAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,CAA1C,CAAnB,CACY,EAAtB,CAAIqF,CAAA,CAAW1E,CAAX,CAAJ,EAAyBxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF7B,CA2kHoB,CAxjHNwS,QAAQ,CAACjQ,CAAD,CAAKU,CAAL,CACtB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,CAAlD,CAA3B,CACNiD,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAFZ,CAujHoB,CApiHL6O,QAAQ,CAAClQ,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,CAAlD,CAA3B,CACY,EAAtB,CAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAAyBxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAmiHoB,CA/gHL8O,QAAQ,CAACnQ,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,CAAlD,CAA3B,CACa,EAAvB,EAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA8gHoB,CA1/GJ+O,QAAQ,CAACpQ,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,CAAlD,CAA3B,CACa,EAAvB,EAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAy/GoB,CAr+GLgP,QAAQ,CAACrQ,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,CAAlD,CAA3B,CACV5O,EAAA,CAAAA,IAAA;AAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACIoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAo+GoB,CAh9GJiP,QAAQ,CAACtQ,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,CAAlD,CAA3B,CACa,EAAvB,EAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA+8GoB,CA37GLkP,QAAQ,CAACvQ,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,CAAlD,CAA3B,CACa,EAAvB,EAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA07GoB,CAt6GLmP,QAAQ,CAACxQ,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,CAAlD,CAA3B,CACY,EAAtB,CAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAAyBxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAq6GoB,CAj5GNoP,QAAQ,CAACzQ,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0CO,CAA1C,CAAnB,CADJ,CAg5GoB,CA93GLyP,QAAQ,CAAC1Q,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0CO,CAA1C,CAAnB,CACY,EAAtB,CAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAAyBxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF7B,CA63GoB,CA12GLkT,QAAQ,CAAC3Q,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB;AAA0CO,CAA1C,CAAnB,CACa,EAAvB,EAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF9B,CAy2GoB,CAt1GJmT,QAAQ,CAAC5Q,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0CO,CAA1C,CAAnB,CACa,EAAvB,EAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF9B,CAq1GoB,CAl0GLoT,QAAQ,CAAC7Q,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0CO,CAA1C,CAAnB,CACApS,EAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAFJ,CAi0GoB,CA9yGJqT,QAAQ,CAAC9Q,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0CO,CAA1C,CAAnB,CACa,EAAvB,EAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF9B,CA6yGoB,CA1xGLsT,QAAQ,CAAC/Q,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0CO,CAA1C,CAAnB,CACa,EAAvB,EAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF9B,CAyxGoB,CAtwGLuT,QAAQ,CAAChR,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0CO,CAA1C,CAAnB,CACY,EAAtB,CAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAAyBxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF7B,CAqwGoB,CAlvGNwT,QAAQ,CAACjR,CAAD,CAAKU,CAAL,CACtB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkDwD,CAAlD,CAA3B,CACNP,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAFZ,CAivGoB,CA9tGL6P,QAAQ,CAAClR,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf;AAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkDwD,CAAlD,CAA3B,CACY,EAAtB,CAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAAyBxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA6tGoB,CAzsGL8P,QAAQ,CAACnR,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkDwD,CAAlD,CAA3B,CACa,EAAvB,EAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAwsGoB,CAprGJ+P,QAAQ,CAACpR,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkDwD,CAAlD,CAA3B,CACa,EAAvB,EAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAmrGoB,CA/pGLgQ,QAAQ,CAACrR,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkDwD,CAAlD,CAA3B,CACVpS,EAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACIoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA8pGoB,CA1oGJiQ,QAAQ,CAACtR,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkDwD,CAAlD,CAA3B,CACa,EAAvB,EAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAyoGoB,CArnGLkQ,QAAQ,CAACvR,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf;AAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkDwD,CAAlD,CAA3B,CACa,EAAvB,EAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAonGoB,CAhmGLmQ,QAAQ,CAACxR,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkDwD,CAAlD,CAA3B,CACY,EAAtB,CAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAAyBxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA+lGoB,CAiQhBN,EAjQgB,CAnBFA,EAmBE,CA7jGJ0Q,QAAQ,EACxB,CACI,IAAA7hB,EAAA,CAAe,IAAA6N,EAAf,CAA2B,CAA3B,CADJ,CA4jGoB,CA7iGJiU,QAAQ,CAAC1R,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmB,CAAnB,CAA3B,CADJ,CA4iGoB,CA7hGNiR,QAAQ,CAAC3R,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CADJ,CA4hGoB,CA7gGLmU,QAAQ,CAAC5R,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAnB,CADJ,CA4gGoB,CA7/FLoU,QAAQ,CAAC7R,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BgI,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAA3B,CADJ,CA4/FoB,CA5+FLqU,QAAQ,CAAC9R,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CAA3B,CADJ,CA2+FoB,CA39FJsU,QAAQ,CAAC/R,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAUxE,CAAV;AAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAAnB,CADJ,CA09FoB,CA18FHuU,QAAQ,CAAChS,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAUxE,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+C,IAAAjD,EAA/C,CAAnB,CADJ,CAy8FoB,CAz7FHwU,QAAQ,CAACjS,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BgI,CAAA,CAAUxE,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAA3B,CADJ,CAw7FoB,CAx6FHyU,QAAQ,CAAClS,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAUxE,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAAnB,CAA3B,CADJ,CAu6FoB,CAZFmD,EAYE,CAXFC,EAWE,CAVFiC,EAUE,CATFlC,EASE,CAv5FJuR,QAAQ,CAACnS,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6BO,CAA7B,CAA+C,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAAnB,CADJ,CAs5FoB,CAt4FH2U,QAAQ,CAACpS,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6BO,CAA7B,CAA+C,IAAAxD,EAA/C,CAAnB,CADJ,CAq4FoB,CAr3FH4U,QAAQ,CAACrS,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BgI,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6BO,CAA7B,CAA+C,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAA3B,CADJ,CAo3FoB,CAp2FH6U,QAAQ,CAACtS,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6BO,CAA7B,CAA+C,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAAnB,CAA3B,CADJ,CAm2FoB,CAhBFoF,EAgBE,CAfFA,EAeE,CAdF/B,EAcE,CAbFA,EAaE,CAn1FNyR,QAAQ,CAACvS,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CADJ,CAk1FoB;AAl0FL+U,QAAQ,CAACxS,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAnB,CADJ,CAi0FoB,CAjzFLgV,QAAQ,CAACzS,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BuI,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAA3B,CADJ,CAgzFoB,CAhyFLiV,QAAQ,CAAC1S,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CAA3B,CADJ,CA+xFoB,CA/wFNkV,QAAQ,CAAC3S,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CADJ,CA8wFoB,CA9vFLmV,QAAQ,CAAC5S,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAnB,CADJ,CA6vFoB,CA7uFLoV,QAAQ,CAAC7S,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BqI,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAA3B,CADJ,CA4uFoB,CA5tFLqV,QAAQ,CAAC9S,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CAA3B,CADJ,CA2tFoB,CA3sFJsV,QAAQ,CAAC/S,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAUxE,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+CO,CAA/C,CAAiE,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAAjE,CAAnB,CADJ,CA0sFoB,CA1rFHuV,QAAQ,CAAChT,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAUxE,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+CO,CAA/C,CAAiE,IAAAxD,EAAjE,CAAnB,CADJ,CAyrFoB;AAzqFHwV,QAAQ,CAACjT,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BgI,CAAA,CAAUxE,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+CO,CAA/C,CAAiE,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAAjE,CAA3B,CADJ,CAwqFoB,CAxpFHyV,QAAQ,CAAClT,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAUxE,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+CO,CAA/C,CAAiE,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAAjE,CAAnB,CAA3B,CADJ,CAupFoB,CAvoFN0V,QAAQ,CAACnT,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBmF,EAAA,CAAU,IAAA/V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CADJ,CAsoFoB,CAtnFL2V,QAAQ,CAACpT,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBmF,EAAA,CAAU,IAAA/V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAnB,CADJ,CAqnFoB,CArmFL4V,QAAQ,CAACrT,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BoI,EAAA,CAAU,IAAA/V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAA3B,CADJ,CAomFoB,CAplFL6V,QAAQ,CAACtT,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBmF,EAAA,CAAU,IAAA/V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CAA3B,CADJ,CAmlFoB,CAyShBuD,EAzSgB,CAjBFA,EAiBE,CAnjFHuS,QAAQ,CAACvT,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BwD,CAA3B,CAA6C,IAAAnR,EAAA,CAAc4Q,CAAd,CAA7C,CADJ,CAkjFoB,CAniFH8S,QAAQ,CAACxT,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBO,CAAnB,CAAqC,IAAAnR,EAAA,CAAc4Q,CAAd,CAArC,CAA3B,CADJ,CAkiFoB,CAlhFL+S,QAAQ,CAACzT,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU7E,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAAnB,CADJ,CAihFoB;AAjgFJiW,QAAQ,CAAC1T,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU7E,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+C,IAAAjD,EAA/C,CAAnB,CADJ,CAggFoB,CAh/EJkW,QAAQ,CAAC3T,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BqI,CAAA,CAAU7E,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAA3B,CADJ,CA++EoB,CA/9EJmW,QAAQ,CAAC5T,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU7E,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAAnB,CAA3B,CADJ,CA89EoB,CA98EJoW,QAAQ,CAAC7T,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBO,CAAnB,CAAqC,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAArC,CADJ,CA68EoB,CA77EHqW,QAAQ,CAAC9T,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBO,CAAnB,CAAqC,IAAAxD,EAArC,CADJ,CA47EoB,CA56EHsW,QAAQ,EACzB,CACI,IAAAnkB,EAAA,CAAe,IAAA6N,EAAf,CAA2BwD,CAA3B,CAA6C,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAA7C,CADJ,CA26EoB,CA35EHuW,QAAQ,CAAChU,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBO,CAAnB,CAAqC,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAArC,CAA3B,CADJ,CA05EoB,CA14ELwW,QAAQ,CAACjU,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6BO,CAA7B,CAA+C,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAAnB,CADJ,CAy4EoB,CAz3EJyW,QAAQ,CAAClU,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6BO,CAA7B,CAA+C,IAAAxD,EAA/C,CAAnB,CADJ,CAw3EoB,CAx2EJ0W,QAAQ,CAACnU,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BqI,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6BO,CAA7B,CAA+C,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAA3B,CADJ,CAu2EoB;AAv1EJ2W,QAAQ,CAACpU,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6BO,CAA7B,CAA+C,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAAnB,CAA3B,CADJ,CAs1EoB,CAt0EL4W,QAAQ,CAACrU,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU7E,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+CO,CAA/C,CAAiE,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAAjE,CAAnB,CADJ,CAq0EoB,CArzEJ6W,QAAQ,CAACtU,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU7E,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+CO,CAA/C,CAAiE,IAAAxD,EAAjE,CAAnB,CADJ,CAozEoB,CApyEJ8W,QAAQ,CAACvU,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BqI,CAAA,CAAU7E,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+CO,CAA/C,CAAiE,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAAjE,CAA3B,CADJ,CAmyEoB,CAnxEJ+W,QAAQ,CAACxU,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU7E,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+CO,CAA/C,CAAiE,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAAjE,CAAnB,CAA3B,CADJ,CAkxEoB,CA6ThByD,EA7TgB,CAlBFA,EAkBE,CAlvEJuT,QAAQ,EACxB,CACI,IAAA7kB,EAAA,CAAe,IAAA6N,EAAf,CAA2BwD,CAA3B,CADJ,CAivEoB,CAluEJyT,QAAQ,CAAC1U,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBO,CAAnB,CAA3B,CADJ,CAiuEoB,CAiUhBE,EAjUgB,CAkUhBK,EAlUgB,CAmUhBC,EAnUgB,CAoUhBC,EApUgB,CAqUhBE,EArUgB,CAsUhBE,EAtUgB,CAuUhBC,EAvUgB,CAwUhBC,EAxUgB,CApEFb,EAoEE,CAnEFK,EAmEE,CAlEFC,EAkEE,CAjEFC,EAiEE,CAxDFE,EAwDE,CAvDFE,EAuDE,CAtDFC,EAsDE,CArDFC,EAqDE,CAhEFb,EAgEE,CA/DFK,EA+DE,CA9DFC,EA8DE,CA7DFC,EA6DE,CApDFE,EAoDE,CAnDFE,EAmDE,CAlDFC,EAkDE,CAjDFC,EAiDE,CA5DFb,EA4DE,CA3DFK,EA2DE,CA1DFC,EA0DE,CAzDFC,EAyDE,CAhDFE,EAgDE,CA/CFE,EA+CE,CA9CFC,EA8CE,CA7CFC,EA6CE,CAiWhBC,EAjWgB,CAkWhBE,EAlWgB,CAmWhBC,EAnWgB,CAoWhBC,EApWgB,CAqWhBE,EArWgB,CAsWhBC,EAtWgB;AAuWhBC,EAvWgB,CAwWhBC,EAxWgB,CA5CFT,EA4CE,CA3CFE,EA2CE,CA1CFC,EA0CE,CAzCFC,EAyCE,CAhCFE,EAgCE,CA/BFC,EA+BE,CA9BFC,EA8BE,CA7BFC,EA6BE,CAxCFT,EAwCE,CAvCFE,EAuCE,CAtCFC,EAsCE,CArCFC,EAqCE,CA5BFE,EA4BE,CA3BFC,EA2BE,CA1BFC,EA0BE,CAzBFC,EAyBE,CApCFT,EAoCE,CAnCFE,EAmCE,CAlCFC,EAkCE,CAjCFC,EAiCE,CAxBFE,EAwBE,CAvBFC,EAuBE,CAtBFC,EAsBE,CArBFC,EAqBE,CALFG,EAKE,CAJFA,EAIE,CAl3DL8R,QAAQ,CAAC3U,CAAD,CAAKU,CAAL,CACvB,CACoD,CAAhD,EAAI+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAJ,EAAmD5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADvD,CAi3DoB,CAt2DLskB,QAAQ,CAAC5U,CAAD,CAAKU,CAAL,CACvB,CACuE,CAAnE,EAAI+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAA0CoE,CAA1C,CAAJ,EAAsEhT,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAD1E,CAq2DoB,CA11DLukB,QAAQ,EACvB,CACIhmB,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADJ,CAy1DoB,CA90DLwkB,QAAQ,EACvB,CACIjmB,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADJ,CA60DoB,CAl0DLykB,QAAQ,CAAC/U,CAAD,CAAKU,CAAL,CACvB,CACoD,CAAhD,EAAI+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAJ,EAAmD5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADvD,CAi0DoB,CAtzDL0kB,QAAQ,CAAChV,CAAD,CAAKU,CAAL,CACvB,CACuE,CAAnE,EAAI+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAA0CoE,CAA1C,CAAJ,EAAsEhT,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAD1E,CAqzDoB,CAHFwS,EAGE,CAFFA,EAEE,CA1yDLmS,QAAQ,CAACjV,CAAD,CAAKU,CAAL,CACvB,CACmE,CAA/D,EAAI+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAJ,EAAkE5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADtE,CAyyDoB,CA9xDL4kB,QAAQ,CAAClV,CAAD,CAAKU,CAAL,CACvB,CAC+E,CAA3E,EAAI+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6BuF,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CAA7B,CAAJ,EAA8E5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX;AAAwB,CAAxB,CADlF,CA6xDoB,CAlxDL6kB,QAAQ,EACvB,CACItmB,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADJ,CAixDoB,CAtwDL8kB,QAAQ,EACvB,CACIvmB,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADJ,CAqwDoB,CA1vDL+kB,QAAQ,CAACrV,CAAD,CAAKU,CAAL,CACvB,CACmE,CAA/D,EAAI+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAJ,EAAkE5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADtE,CAyvDoB,CA9uDLglB,QAAQ,CAACtV,CAAD,CAAKU,CAAL,CACvB,CAC+E,CAA3E,EAAI+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6BuF,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CAA7B,CAAJ,EAA8E5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADlF,CA6uDoB,CAluDNilB,QAAQ,CAACvV,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAU,IAAA7V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAnB,CADJ,CAiuDoB,CAttDN+X,QAAQ,CAACxV,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAU,IAAA7V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAA0CoE,CAA1C,CAAnB,CADJ,CAqtDoB,CA1sDL4T,QAAQ,CAACzV,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACwB,EAAlC,EAAI+E,CAAA,CAAUpE,CAAV,CAAe,IAAA5D,EAAf,CAAJ,EAAqC5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrC,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAUtE,CAAV,CAAe,IAAA5D,EAAf,CAAnB,CAHJ,CAysDoB,CA5rDLiY,QAAQ,CAAC1V,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAA3D,EAAN2D,CAAmBS,CACI,EAA3B,EAAI4D,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAUtE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CA2rDoB,CA7qDLuU,QAAQ,CAAC3V,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAU,IAAA7V,EAAA,CAAc4Q,CAAd,CAAV;AAA6B,IAAAjD,EAA7B,CAAnB,CAFJ,CA4qDoB,CAhqDLmY,QAAQ,CAAC5V,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAU,IAAA7V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAA0CoE,CAA1C,CAAnB,CAFJ,CA+pDoB,CAnpDLgU,QAAQ,CAAC7V,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACwB,EAAlC,EAAI+E,CAAA,CAAUpE,CAAV,CAAe,IAAA5D,EAAf,CAAJ,EAAqC5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrC,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAUtE,CAAV,CAAe,IAAA5D,EAAf,CAAnB,CAHJ,CAkpDoB,CAroDLqY,QAAQ,CAAC9V,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAA3D,EAAN2D,CAAmBS,CACI,EAA3B,EAAI4D,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAUtE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CAooDoB,CAtnDN2U,QAAQ,CAAC/V,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAU,IAAA7V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CADJ,CAqnDoB,CA1mDNuY,QAAQ,CAAChW,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAU,IAAA7V,EAAA,CAAc4Q,CAAd,CAAV,CAA6BuF,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CAA7B,CAAnB,CADJ,CAymDoB,CA9lDLwY,QAAQ,CAACjW,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAUtE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CA6lDoB,CA/kDL8U,QAAQ,CAAClW,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM6E,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV;AAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAUtE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CA8kDoB,CAhkDL+U,QAAQ,CAACnW,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAU,IAAA7V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CAFJ,CA+jDoB,CAnjDL2Y,QAAQ,CAACpW,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAU,IAAA7V,EAAA,CAAc4Q,CAAd,CAAV,CAA6BuF,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CAA7B,CAAnB,CAFJ,CAkjDoB,CAtiDL4Y,QAAQ,CAACrW,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAUtE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CAqiDoB,CAvhDLkV,QAAQ,CAACtW,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM6E,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAUtE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CAshDoB,CAxgDNmV,QAAQ,CAACvW,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAnB,CADJ,CAugDoB,CA5/CN+Y,QAAQ,CAACxW,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAA0CoE,CAA1C,CAAnB,CADJ,CA2/CoB,CAh/CL4U,QAAQ,CAACzW,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACwB,EAAlC,EAAI+E,CAAA,CAAUpE,CAAV,CAAe,IAAA5D,EAAf,CAAJ;AAAqC5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrC,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU3E,CAAV,CAAe,IAAA5D,EAAf,CAAnB,CAHJ,CA++CoB,CAl+CLiZ,QAAQ,CAAC1W,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAA3D,EAAN2D,CAAmBS,CACI,EAA3B,EAAI4D,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU3E,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CAi+CoB,CAn9CLuV,QAAQ,CAAC3W,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAnB,CAFJ,CAk9CoB,CAt8CLmZ,QAAQ,CAAC5W,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAA0CoE,CAA1C,CAAnB,CAFJ,CAq8CoB,CAz7CLgV,QAAQ,CAAC7W,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACwB,EAAlC,EAAI+E,CAAA,CAAUpE,CAAV,CAAe,IAAA5D,EAAf,CAAJ,EAAqC5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrC,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU3E,CAAV,CAAe,IAAA5D,EAAf,CAAnB,CAHJ,CAw7CoB,CA36CLqZ,QAAQ,CAAC9W,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAA3D,EAAN2D,CAAmBS,CACI,EAA3B,EAAI4D,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU3E,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CA06CoB,CA55CN2V,QAAQ,CAAC/W,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CADJ,CA25CoB,CAh5CNuZ,QAAQ,CAAChX,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV;AAA6BuF,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CAA7B,CAAnB,CADJ,CA+4CoB,CAp4CLwZ,QAAQ,CAACjX,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU3E,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CAm4CoB,CAr3CL8V,QAAQ,CAAClX,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM6E,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU3E,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CAo3CoB,CAt2CL+V,QAAQ,CAACnX,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CAFJ,CAq2CoB,CAz1CL2Z,QAAQ,CAACpX,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6BuF,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CAA7B,CAAnB,CAFJ,CAw1CoB,CA50CL4Z,QAAQ,CAACrX,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU3E,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CA20CoB,CA7zCLkW,QAAQ,CAACtX,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM6E,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV;AAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU3E,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CA4zCoB,CA9yCNmW,QAAQ,CAACvX,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAnB,CADJ,CA6yCoB,CAlyCN+Z,QAAQ,CAACxX,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAA0CoE,CAA1C,CAAnB,CADJ,CAiyCoB,CAtxCL4V,QAAQ,CAACzX,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACwB,EAAlC,EAAI+E,CAAA,CAAUpE,CAAV,CAAe,IAAA5D,EAAf,CAAJ,EAAqC5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrC,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAUzE,CAAV,CAAe,IAAA5D,EAAf,CAAnB,CAHJ,CAqxCoB,CAxwCLia,QAAQ,CAAC1X,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CAC2C,EAArD,EAAI+E,CAAA,CAAUpE,CAAV,CAAe,IAAA5D,EAAf,CAA4BoE,CAA5B,CAAJ,EAAwDhT,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACxD,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAUzE,CAAV,CAAe,IAAA5D,EAAf,CAA4BoE,CAA5B,CAAnB,CAHJ,CAuwCoB,CA1vCL8V,QAAQ,CAAC3X,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAnB,CAFJ,CAyvCoB,CA7uCLma,QAAQ,CAAC5X,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAA0CoE,CAA1C,CAAnB,CAFJ,CA4uCoB,CAhuCLgW,QAAQ,CAAC7X,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACwB,EAAlC,EAAI+E,CAAA,CAAUpE,CAAV,CAAe,IAAA5D,EAAf,CAAJ,EAAqC5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrC,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAUzE,CAAV,CAAe,IAAA5D,EAAf,CAAnB,CAHJ,CA+tCoB;AAltCLqa,QAAQ,CAAC9X,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAA3D,EAAN2D,CAAmBS,CACI,EAA3B,EAAI4D,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAUzE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CAitCoB,CAnsCN2W,QAAQ,CAAC/X,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CADJ,CAksCoB,CAvrCNua,QAAQ,CAAChY,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6BuF,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CAA7B,CAAnB,CADJ,CAsrCoB,CA3qCLwa,QAAQ,CAACjY,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAUzE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CA0qCoB,CA5pCL8W,QAAQ,CAAClY,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM6E,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAUzE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CA2pCoB,CA7oCL+W,QAAQ,CAACnY,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CAFJ,CA4oCoB,CAhoCL2a,QAAQ,CAACpY,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV;AAA6BuF,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CAA7B,CAAnB,CAFJ,CA+nCoB,CAnnCL4a,QAAQ,CAACrY,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAUzE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CAknCoB,CApmCLkX,QAAQ,CAACtY,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM6E,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAUzE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CAmmCoB,CAichBuB,CAjcgB,CAkchBA,CAlcgB,CAmchBA,CAncgB,CAochBA,CApcgB,CAqchBA,CArcgB,CAschBA,CAtcgB,CAuchBA,CAvcgB,CAwchBA,CAxcgB,CAychBA,CAzcgB,CA0chBA,CA1cgB,CA2chBA,CA3cgB,CA4chBA,CA5cgB,CA6chBA,CA7cgB,CA8chBA,CA9cgB,CA+chBA,CA/cgB,CAgdhBA,CAhdgB,CAidhBA,CAjdgB,CAkdhBA,CAldgB,CAmdhBA,CAndgB,CAodhBA,CApdgB,CAqdhBA,CArdgB,CAsdhBA,CAtdgB,CAudhBA,CAvdgB,CAwdhBA,CAxdgB,CAydhBA,CAzdgB,CA0dhBA,CA1dgB,CA2dhBA,CA3dgB,CA4dhBA,CA5dgB,CA6dhBA,CA7dgB,CA8dhBA,CA9dgB,CA+dhBA,CA/dgB,CAgehBA,CAhegB,CAiehBA,CAjegB,CAkehBA,CAlegB,CAmehBA,CAnegB,CAoehBA,CApegB,CAqehBA,CAregB,CAsehBA,CAtegB,CAuehBA,CAvegB,CAwehBA,CAxegB,CAyehBA,CAzegB,CA0ehBA,CA1egB,CA2ehBA,CA3egB,CA4ehBA,CA5egB,CA6ehBA,CA7egB,CA8ehBA,CA9egB,CA+ehBA,CA/egB,CAgfhBA,CAhfgB,CAifhBA,CAjfgB,CAkfhBA,CAlfgB,CAmfhBA,CAnfgB,CAofhBA,CApfgB,CAqfhBA,CArfgB,CAsfhBA,CAtfgB,CAufhBA,CAvfgB,CAwfhBA,CAxfgB,CAyfhBA,CAzfgB,CA0fhBA,CA1fgB,CA2fhBA,CA3fgB,CA4fhBA,CA5fgB,CA6fhBA,CA7fgB,CA8fhBA,CA9fgB,CA+fhBA,CA/fgB,CAggBhBA,CAhgBgB,CAApB,CAmgBAC,GAAmB,CAxlDJ2V,QAAQ,CAACvY,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAulDmB,CA5kDHwY,QAAQ,CAACxY,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA2kDmB,CAhkDJyY,QAAQ,CAACzY,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA+jDmB,CApjDH0Y,QAAQ,CAAC1Y,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAmjDmB,CAxiDJ2Y,QAAQ,CAAC3Y,CAAD,CAAK4Y,CAAL,CACvB,CACI,OAAOA,CAAP,EACA,KAzpVgBC,CAypVhB,CACoB,CAAA,CAAA,IAAA/oB,EAAA,CAAc,IAAA2N,EAAd,CA/9MZltB,EAAJ,CA/sIYuoC,CA+sIZ,GA+9MAC,IA/9M6Bhb,EAA7B,EAA2C,OAA3C,CACIxtB;CAAJ,CAnsIYuoC,MAmsIZ,GA89MAC,IA99M6Bhb,EAA7B,EAA2C,OAA3C,CA+9MA,MACJ,SACI,IAAAd,EAAA,CAAiB+C,CAAjB,CALJ,CADJ,CAuiDmB,CArhDJgZ,QAAQ,CAAChZ,CAAD,CAAK4Y,CAAL,CACvB,CACI,OAAOA,CAAP,EACA,KA5qVgBC,CA4qVhB,CAjgNQh7B,CAAAA,CAAQ,CAkgNeo7B,KAjgNvBlb,EAAJ,CA3uIYkB,MA2uIZ,GAAoCphB,CAApC,EArtIYq7B,CAqtIZ,CAigN2BD,KAhgNvBlb,EAAJ,CA/tIWkB,MA+tIX,GAAoCphB,CAApC,EA3sIYq7B,KA2sIZ,CAggNA,KAAAtpB,EAAA,CAAe,IAAA6N,EAAf,CA//MO5f,CA+/MP,CACA,MACJ,SACI,IAAAof,EAAA,CAAiB+C,CAAjB,CALJ,CADJ,CAohDmB,CAlgDHmZ,QAAQ,CAACnZ,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAigDmB,CAt/CHoZ,QAAQ,CAACpZ,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAq/CmB,CAmCf7iB;QAnBEk8B,GAmBS,CAACC,CAAD,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,KAAN,CAAaA,CAAb,CAxsYQrwB,GAwsYR,CAGA,KAAAxR,EAAA,CADA,IAAA8hC,EACA,CADc,IAGd,KAAAC,EAAA,CAAe,CAACF,CAAA,KAChB,KAAAG,EAAA,CAAe,CAACH,CAAA,KAchB,KAAAI,EAAA,CAAiBJ,CAAA,MACY,SAA7B,EAAI,MAAO,KAAAI,EAAX,GACI,IAAAA,EADJ,CACqBzhC,IAAA,CAAK,IAAAyhC,EAAL,CADrB,CAIA,KAAAC,EAAA,CAAiBL,CAAA,KACjB,KAAAxmC,EAAA,CAAiB8mC,EAAA,CAAgB,IAAAD,EAAhB,CAEjB,IAAI,IAAAA,EAAJ,CAAoB,CACZE,CAAAA,CAAW,IAAAF,EAOf,KAAIG,EAAWC,EAAA,CAAiB,IAAAjnC,EAAjB,CA1+gBPknC,OA2+gBR,EAAIF,CAAJ,EAx+gBQE,KAw+gBR,EAAuCF,CAAvC,GACID,CADJ,CACeI,EAAA,EADf,CAC6E,uBAD7E,CACmF,IAAAN,EADnF,CAC4L,wCAD5L,CAGA,KAAIO,EAAM,IACVC,GAAA,CAAgBN,CAAhB,CAA0B,IAA1B,CAAgC,CAAA,CAAhC,CAAsCO,QAAiB,CAAC5kC,CAAD,CAAO6kC,CAAP,CAAkB7jC,CAAlB,CAA8B,CACjDA,CAyExC,EAzEQ0jC,CA0EJt2B,GAAA,CAAY,qCAAZ,CA1EoCpN,CA0EpC,CAAiE,IAAjE,CA1EmBhB,CA0EnB,CAA+E,GAA/E,CACA,CA3EI0kC,CA2EJP,EAAA,CAAiB,IAFrB,GAKIW,EAAA,CA9EIJ,CA8EyBt8B,GAA7B,CA9EmBpI,CA8EnB,CA9EyB6kC,CA8EzB,CAEA,CAAA,CADItkC,CACJ,CADewkC,EAAA,CA/EI/kC,CA+EJ,CA/EU6kC,CA+EV,CACf,GAhFIH,CAiFAX,EACA,CADcxjC,CAAAyB,GACd,CAlFA0iC,CAkFAziC,EAAA,CAAgB1B,CAAA0B,EAFpB,EAhFIyiC,CAoFAP,EAJJ,CAIqB,IAXzB,CAcAa,GAAA,CAvFQN,CAuFR,CAxFyF,CAArF,CAbgB,CA7BxB;AApBmBluB,EAAA5O,CAAjBi8B,EAAiBj8B,CAAAA,CAAAA,CA6EnB,GAAA,UAAA,GAAA,CAAA4P,QAAO,CAACtO,CAAD,CAAMD,CAAN,CAAWD,CAAX,CAAgBD,CAAhB,CACP,CACI,IAAAE,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CACXi8B,GAAA,CAAAA,IAAA,CAJJ,CAeA,GAAA,UAAA,GAAA,CAAAz1B,QAAO,EACP,CACQ,IAAAtN,EAAJ,GACQ,IAAA8G,EAOJ,EANIk8B,EAAA,CAAA,IAAAl8B,EAAA,CAAoB,IAAAhB,GAApB,CAA6B,IAAAi8B,EAA7B,CAA2C,IAAAC,EAA3C,CAAyD,IAAAhiC,EAAzD,CAMJ,CAAA,OAAO,IAAAA,EARX,CAUA,OAAO,CAAA,CAXX,CA2BA,GAAA,UAAA,GAAA,CAAAuN,QAAS,EACT,CACI,MAAO,CAAA,CADX,CAwCAw1B;QAAA,GAAO,CAAPA,CAAO,CACP,CACI,GAAI,CAAC/1B,EAAA,CAAAA,CAAA,CAAL,CAAqB,CACjB,GAAI,CAAAk1B,EAAJ,CAAoB,CAIhB,GAAI,CAAC,CAAAJ,EAAL,EAAoB,CAAC,CAAA96B,EAArB,CAA+B,MAK1B,EAAAg7B,EAAL,GACI,CAAAA,EADJ,CACmB,CAAAF,EAAAjmC,OADnB,CAGA,IAAI,CAAAimC,EAAAjmC,OAAJ,EAA0B,CAAAmmC,EAA1B,CAOIl1B,EAAA,CAAAA,CAAA,CAAc,YAAd,CA34fLyQ,CAAA,CA24fgD,CAAAukB,EAAAjmC,OA34fhD,CAAa,CAAb,CAAgB,CAAA,CAAhB,CA24fK,CAAiE,mCAAjE,CA34fL0hB,CAAA,CA24f0H,CAAAykB,EA34f1H,CAAa,CAAb,CAAgB,CAAA,CAAhB,CA24fK,CAAqI,GAArI,CAPJ,KASK,CAAgBD,IAAAA,EAAAA,CAAAA,EAuC7B,IAAI5mB,EAAA,CAvCa8nB,CAuCbj8B,EAAA,CAAmBoU,CAAnB,CAvCa6nB,CAuCYjB,EAAzB,CAAuC7jB,EAAvC,CAAJ,CAAkE,CAE9D,IAAInmB,CACJ,KAAKA,CAAL,CAAS,CAAT,CAAYA,CAAZ,CA1CairC,CA0CGnB,EAAAjmC,OAAhB,CAAoC7D,CAAA,EAApC,CACIkgB,EAAA,CA3CS+qB,CA2CTj8B,EAAA,CAAuBoU,CAAvB,CAA8BpjB,CAA9B,CA3CSirC,CA2CwBnB,EAAA,CAAY9pC,CAAZ,CAAjC,CAEJ,EAAA,CAAO,CAAA,CANuD,CAAlE,IAYA,EAAA,CAAO,CAAA,CAnDM,IAAI,CAAJ,CAA+B,CAE5BkrC,CAAAA,CAAU,EACe,SAA7B,EAAI,MAAO,EAAAjB,EAAX,CACIiB,CAAAjiC,KAAA,CAAa,CAAAghC,EAAb,CADJ,CAE6B,IAF7B,EAEW,CAAAA,EAFX,EAEqC,CAAAA,EAAApmC,OAFrC,GAGIqnC,CAHJ,CAGc,CAAAjB,EAHd,CAKA,KAASjqC,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoBkrC,CAAArnC,OAApB,CAAoC7D,CAAA,EAApC,CAAyC,CA5tVrD,IA6tVgBmrC,IAAAA,EAAAA,CAAAA,CAAc,EAAAD,CAAA,CAAQlrC,CAAR,CAAdmrC,CA4DFn8B,EAAAA,CAAAA,EA5DEm8B,CA4DqCnB,EAAAA,CAAAA,EA5DrCmB,CA/tVZC,EAAU,EA+tVED,CA9tVZ1oB,EA0xVmC,CAAAsnB,EA1xVnCtnB,GAAkB,CAAAV,EACtB,CAAc,CAAd,CAAOsB,CAAP,EAAmBZ,CAAnB,CAA4B,CAAAL,EAAAve,OAA5B,CAAA,CACIunC,CAAAniC,KAAA,CAAa,CAAAmZ,EAAA,CAAgBK,CAAA,EAAhB,CAAb,CACA,CAAAY,CAAA,EAtUcpB,KA8lWlBjT,EAAAA,CAAAA,CAAAA,EAA+Bg7B,EAAAA,CAAAA,CAAAA,EAlwV3BhqC,EAAAA,CAAI,CAER,KAgwVyBojB,CAhwVzB;AADsB,CAAArB,EACtB,CAAc,CAAd,CAAOsB,CAAP,EAAmBZ,CAAnB,CAA4B,CAAAL,EAAAve,OAA5B,CAAA,CAAoD,CAC5Cwe,CAAAA,CAAQ+oB,CAAA,CAAQprC,CAAA,EAAR,CAEZ,IAAI,CAACqiB,CAAL,CAAY,KAMZ,EAAAD,EAAA,CAAgBK,CAAA,EAAhB,CAAA,CAA4BJ,CAC5BgB,EAAA,EAxWcpB,KA8VkC,CAksVC,CAcrC,OAAO,CAAA6nB,EAtBqB,CAA/B,CArBW,CA+CpB70B,EAAA,CAAAA,CAAA,CAhDiB,CADzB,CAoIJyM,EAAA,CA5BIZ,QAAW,EACX,CAEI,IADA,IAAIuqB,EAAQ36B,CAAA,CAA6BsQ,QAA7B,CAAuCxQ,CAAvC,CAAuD,KAAvD,CAAZ,CACS86B,EAAO,CAAhB,CAAmBA,CAAnB,CAA0BD,CAAAxnC,OAA1B,CAAwCynC,CAAA,EAAxC,CAAgD,CAC5C,IAAIC,EAAOF,CAAA,CAAMC,CAAN,CAAX,CACIzB,EAAWx4B,EAAA,CAA4Bk6B,CAA5B,CACXd,EAAAA,CAAM,IAAIb,EAAJ,CAAaC,CAAb,CACVzoB,GAAA,CAAgCqpB,CAAhC,CAAqCc,CAArC,CAJ4C,CAFpD,CA2BJ,CA0BI79B;QAjBE89B,GAiBS,CAACC,CAAD,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,KAAN,CAAaA,CAAb,CAGA,KAAAzjC,EAAA,CADA,IAAAU,GACA,CADa,IAGb,KAAAgjC,EAAA,CAAe,CAACD,CAAA,KAChB,KAAAE,EAAA,CAAe,CAACF,CAAA,KAEhB,KAAAxjC,GAAA,CAAgBwjC,CAAA,KAChB,KAAAvjC,GAAA,CAAgBujC,CAAA,KACK,KAArB,EAAI,IAAAxjC,GAAJ,GAA2B,IAAAA,GAA3B,CAA2C,CAAC,IAAAA,GAA5C,CACqB,KAArB,EAAI,IAAAC,GAAJ,GAA2B,IAAAA,GAA3B,CAA2C,CAAC,IAAAA,GAA5C,CAGA,KAAA0jC,EAAA,CAAkB,IAAAxf,EAAlB,CAAgC,CAAA,CAEhC,KAAA8d,EAAA,CAAiBuB,CAAA,KACjB,KAAApoC,EAAA,CAAiB8mC,EAAA,CAAgB,IAAAD,EAAhB,CAEjB,IAAI,IAAAA,EAAJ,CAAoB,CACZE,CAAAA,CAAW,IAAAF,EAOf,KAAIG,EAAWC,EAAA,CAAiB,IAAAjnC,EAAjB,CA/whBPknC,OAgxhBR,EAAIF,CAAJ,EA7whBQE,KA6whBR,EAAuCF,CAAvC,GACID,CADJ,CACeI,EAAA,EADf,CAC6E,uBAD7E,CACmF,IAAAN,EADnF,CAC4L,wCAD5L,CAGA,KAAI2B,EAAM,IACVnB,GAAA,CAAgBN,CAAhB,CAA0B,IAA1B,CAAgC,CAAA,CAAhC,CAAsCO,QAAiB,CAAC5kC,CAAD,CAAO6kC,CAAP,CAAkB7jC,CAAlB,CAA8B,CACjDA,CAkFxC,EAlFQ8kC,CAmFJ13B,GAAA,CAAY,qCAAZ,CAnFoCpN,CAmFpC,CAAiE,IAAjE,CAnFmBhB,CAmFnB,CAA+E,GAA/E,CACA,CApFI8lC,CAoFJ3B,EAAA,CAAiB,IAFrB,GAKIW,EAAA,CAvFIgB,CAuFyB19B,GAA7B,CAvFmBpI,CAuFnB,CAvFyB6kC,CAuFzB,CAEA,CAAA,CADItkC,CACJ,CADewkC,EAAA,CAxFI/kC,CAwFJ;AAxFU6kC,CAwFV,CACf,GAzFIiB,CA0FAnjC,GAGA,CAHapC,CAAAoC,GAGb,CA7FAmjC,CA2FA7jC,EAEA,CAFgB1B,CAAA0B,EAEhB,CADqB,IACrB,EA7FA6jC,CA4FI5jC,GACJ,GA7FA4jC,CA4F2B5jC,GAC3B,CAD2C3B,CAAA2B,GAC3C,EAAqB,IAArB,EA7FA4jC,CA6FI3jC,GAAJ,GA7FA2jC,CA6F2B3jC,GAA3B,CAA2C5B,CAAA4B,GAA3C,CAJJ,EAzFI2jC,CA+FA3B,EANJ,CAMqB,IAbzB,CAgBA4B,GAAA,CAlGQD,CAkGR,CAnGyF,CAArF,CAbgB,CApBxB,CAlBmBtvB,EAAA5O,CAAjB69B,EAAiB79B,CAAAA,CAAAA,CAkEnB,GAAA,UAAA,GAAA,CAAA4P,QAAO,CAACtO,CAAD,CAAMD,CAAN,CAAWD,CAAX,CAAgBD,CAAhB,CACP,CACI,IAAAE,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CACXg9B,GAAA,CAAAA,IAAA,CAJJ,CAeA,GAAA,UAAA,GAAA,CAAAx2B,QAAO,CAACjN,CAAD,CAAOqV,CAAP,CACP,CACQ,IAAA1V,EAAJ,GACQ,IAAA8G,EAOJ,EANIk8B,EAAA,CAAA,IAAAl8B,EAAA,CAAoB,IAAAhB,GAApB,CAA6B,IAAA49B,EAA7B,CAA2C,IAAAC,EAA3C,CAAyD,IAAA3jC,EAAzD,CAMJ,CAAA,OAAO,IAAAA,EARX,CAUK0V,EAAL,EAMI,IAAAjB,MAAA,EAEJ,OAAO,CAAA,CAnBX,CA8BA,GAAA,UAAA,GAAA,CAAAlH,QAAS,EACT,CAOI,MAAO,CAAA,CAPX,CAgDAu2B;QAAA,GAAO,CAAPA,CAAO,CACP,CACI,GAAK,CAAA98B,EAAL,GAEI,CAAC,CAAA48B,EAOD,EAPoB,CAAAD,EAOpB,GANIxoB,EAAA,CAAA,CAAAnU,EAAA,CAAmB,CAAA08B,EAAnB,CAAiC,CAAAC,EAAjC,CArkUAI,CAqkUA,CAAJ,CACI,CAAAH,EADJ,CACsB,CAAA,CADtB,CAGI,CAAAD,EAHJ,CAGmB,CAGnB,EAAA,CAAC32B,EAAA,CAAAA,CAAA,CATL,EASqB,CACjB,GAAI,CAAC,CAAA42B,EAAL,CAzjcJjjC,CAAA,CA0jcwBjI,kBA1jcxB,CAyjcI,KAGK,IAAI,CAAAwpC,EAAJ,CAAoB,CAIrB,GAAI,CAAC,CAAAxhC,GAAL,CAAiB,MAEbsjC,GAAA,CAAAA,CAAA,CAAe,CAAAtjC,GAAf,CAA2B,CAAAT,GAA3B,CAA0C,CAAAC,GAA1C,CAAyD,CAAAwjC,EAAzD,CAAJ,CACI,CAAA/kC,OAAA,CAAY,gBAAZ,CAA+B,CAAAtD,EAA/B,CAAgD,GAAhD,CADJ,CAGI,CAAA8Q,GAAA,CAAY,uBAAZ,CAAsC,CAAA9Q,EAAtC,CAAuD,GAAvD,CATiB,CAkBzB,CAAA+oB,EAAA,CAAc,CAAA,CACdnX,GAAA,CAAAA,CAAA,CAvBiB,CAVzB;AA0CA,EAAA,UAAA,MAAA,CAAAwH,QAAK,EACL,CACI,GAAI,IAAAmvB,EAAJ,EAAuB,CAAC,IAAAxf,EAAxB,CAAqC,CAMjCpd,IAAAA,EAAAA,IAAAA,EAAAA,CAAoB08B,EAAAA,IAAAA,EAApB18B,CAAkC28B,EAAAA,IAAAA,EAAlC38B,CApnWA8X,EAAM1D,CAAN0D,CA5Oe1C,KA8OnB,KADahB,CACb,IADsB,CAAArB,EACtB,CAAc,CAAd,CAAOsB,CAAP,EAAmBZ,CAAnB,CAA4B,CAAAL,EAAAve,OAA5B,CAAA,CAAoD,CAChDooC,IAAAA,EAAAA,CAAA7pB,EAAA6pB,CAAgBxpB,CAAhBwpB,CAAAA,CAAkC5oB,EAAAA,CAAlC4oB,CAutBOC,EA05UyCA,CA15UzCA,EAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAU,CAAV,CAAAA,CAKXplB,EAAA,CAAMA,CAAN,EAAa,CACDpiB,KAAAA,EAAZ,GAAIynC,CAAJ,GAAuBA,CAAvB,CAA6B,CAAA9oB,KAA7B,CAQc,EAAd,CAAI6oB,CAAJ,EAAmBA,CAAnB,EAA8B,CAAC1Y,CAA/B,GACI0Y,CADJ,EACetrB,CADf,CAGAsrB,EAAA,CAAUjqC,IAAAE,MAAA,CAAWF,IAAAe,IAAA,CAASkpC,CAAT,CAAX,CAAV,CAA0CtrB,CAE1C,KAAK,IAAI5gB,EAAI8mB,CAAb,CAAkBqlB,CAAA,EAAlB,EAA2BnsC,CAA3B,CAA+B,CAAAqjB,KAA/B,CAA0CrjB,CAAA,EAA1C,CAA+C,CAAAqkB,EAAA,CAAqB6nB,CAArB,CAA8BplB,CAA9B,CAAmC,CAAA1D,EAAnC,CAA+C0D,CAA/C,CAzuB3CzD,EAAA,EAnPcpB,KAoPdQ,EAAA,EACAqE,EAAA,CAAM,CAJ0C,CAmnW5C,IAAApe,GAAJ,EACIsjC,EAAA,CAAAA,IAAA,CAAe,IAAAtjC,GAAf,CAA2B,IAAAT,GAA3B,CAA0C,IAAAC,GAA1C,CAAyD,IAAAwjC,EAAzD,CAAuE,CAAC,IAAA58B,EAAxE,CAR6B,CAWrC,IAAAsd,EAAA,CAAc,CAAA,CAZlB,CA6BA4f;QAAA,GAAS,CAATA,CAAS,CAACtjC,CAAD,CAAQT,CAAR,CAAkBC,CAAlB,CAA4BkkC,CAA5B,CAAsCC,CAAtC,CACT,CACI,IAAIC,EAAU,CAAA,CAEE,KAAhB,EAAIrkC,CAAJ,GACIA,CADJ,CACemkC,CADf,CAGA,IAAgB,IAAhB,EAAInkC,CAAJ,CAAsB,CAClB,IAASjI,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoB0I,CAAA7E,OAApB,CAAkC7D,CAAA,EAAlC,CACIkgB,EAAA,CAAA,CAAAlR,EAAA,CAAuB/G,CAAvB,CAAkCjI,CAAlC,CAAqC0I,CAAA,CAAM1I,CAAN,CAArC,CAEJssC,EAAA,CAAU,CAAA,CAJQ,CAMlBA,CAAJ,GASoB,IAIhB,EAJIpkC,CAIJ,GAHIsX,CAAA,CAAA,CAAAzQ,EAAA,CACA,CAAAs9B,CAAA,CAAS,CAAA,CAEb,EAAgB,IAAhB,EAAInkC,CAAJ,GACI6G,CAnuRR,CAmuRQA,CAAAA,EAnuRR,CAhCA,CAAAse,GAgCA,CAmuR0BnlB,CAnuR1B,CA9BAkX,CAAA,CAAAA,CAAA,CAiwR0BlX,CAjwR1B,CA8BA,CA5BImkC,CAAJ,CACS,CAAAj+B,MAAAK,EAAL,CAGU,CAAAL,MAAA+Q,EAHV,EAIII,EAAA,CAAAA,CAAA,CAJJ,CACI,CAAAnR,MAAAsa,GADJ,CAC2B,CAAA,CAF/B,CASQ,CAAA5Z,EAAJ,EAAgB,CAAAV,MAAAK,EAAhB,CAUS+Q,CAAA,CAAAA,CAAA,CAVT,EAU4B,CAAAvQ,EAAAb,MAAAqO,MAV5B,GAWQ6N,EAAA,CAAA,CAAAxb,EAAA,CACA,CAAAkR,CAAA,CAAA,CAAA/Q,EAAA,CAAyB,EAAzB,CAZR,EAeoB,CAAA,CAfpB,GAeSo9B,CAfT,EAgBI7sB,CAAA,CAAAA,CAAA,CAGR,CAAI,CAAC8c,CA1oCEluB,MAAA+Q,EA0oCP,EAAyB,CAAAnC,GAAzB,EAAqC,CAAAA,GAAAL,KAAA,EAkuRjC,CAbJ,CAiBA,OAAO2vB,EA7BX,CAuDJ5qB,EAAA,CAfIZ,QAAW,EACX,CAEI,IADA,IAAIyrB,EAAQ77B,CAAA,CAA6BsQ,QAA7B,CAAuCxQ,CAAvC,CAAuD,KAAvD,CAAZ,CACSg8B,EAAO,CAAhB,CAAmBA,CAAnB,CAA0BD,CAAA1oC,OAA1B,CAAwC2oC,CAAA,EAAxC,CAAgD,CAC5C,IAAIC,EAAOF,CAAA,CAAMC,CAAN,CAAX,CACIf,EAAWp6B,EAAA,CAA4Bo7B,CAA5B,CACXZ,EAAAA,CAAM,IAAIL,EAAJ,CAAaC,CAAb,CACVrqB,GAAA,CAAgCyqB,CAAhC,CAAqCY,CAArC,CAJ4C,CAFpD,CAcJ,CAuDI/+B;QArBEg/B,GAqBS,CAACC,CAAD,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,YAAN,CAAoBA,CAApB,CAvzZQ3yB,OAuzZR,CAGA,KAAA4yB,EAAA,CAAkBD,CAAA,UACY,SAA9B,EAAI,MAAO,KAAAC,EAAX,GAAwC,IAAAA,EAAxC,CAA8E,MAA9E,EAA2D,IAAAA,EAA3D,CAqCA,KAAAC,EAAA,CAAkB,CAAA,CAElB,KAAAC,EAAA,CAAiB,EAEb94B,EAAAA,CAAW24B,CAAA,QACf,IAAgB,SAAhB,EAAI34B,CAAJ,EAgBwCA,CAhBxC,CAjrcc,CACV,IAAI+4B,EAASv5B,EAAA,CAHmC1B,OAGnC,CAgsciB3C,IAhscmBrB,GAApC,CACTi/B,EAAJ,GACQ98B,CADR,CACkB88B,CAAA9+B,EAAA,CA8rckB+F,CA9rclB,CADlB,GA+rc8B7E,IA5rctBmC,GAAA,CAAqB,IAArB,CA4rc4B0C,CA5rc5B,CAAqC/D,CAArC,CALE,CAwscd,IAAA+8B,EAAA,CAAkB,IAAAC,EAAlB,CAAsD,IAKtD,KAAA,QAAA,CAAkB,CACd,QAAW,IAAAC,GADG,CAEd,YAAe,IAAAC,GAFD,CAGd,cAAiB,IAAAC,GAHH,CAId,cAAiB,IAAAC,GAJH,CA3EtB,CAtB0B9wB,EAAA5O,CAAxB++B,EAAwB/+B,CAAAA,CAAAA,CAmH1B,EAAA,CA/xiBJ,EAAA2/B,UA+xiBIz5B;CAAAvC,GAAA,CAAAA,QAAU,CAACQ,CAAD,CAAQkC,CAAR,CAAkB/D,CAAlB,CACV,CACI,GAAa,IAAb,EAAI6B,CAAJ,EAA8B,UAA9B,EAAqBA,CAArB,CAA0C,CAEtC,IAAIy7B,EAAS,IACb,KAAAt/B,EAAA,CAAc+F,CAAd,CAAA,CAA+C/D,CAU/CA,EAAAu9B,UAAA,CAAoBC,QAAkB,CAACpwB,CAAD,CAAQ,CAC1CA,CAAA,CAAQA,CAAR,EAAiBzW,MAAAyW,MACjB,KAAIqwB,EAAS,CAAb,CACIC,EAAUtwB,CAAAswB,QAriiBEC,EAgjiBhB,EAAID,CAAJ,CACID,CADJ,CACarwB,CAAAwwB,OAAA,CAAcC,EAAApxC,GAAd,CAAkCqxC,EAAA7sC,GAD/C,CAzhiBgB0sC,EA4hiBX,EAAID,CAAJ,CACDD,CADC,CACQI,EAAApxC,GADR,CAGI2gB,CAAA2wB,QAHJ,EAGqBL,CAHrB,EAGgCM,EAAAnwC,GAHhC,EAGgD6vC,CAHhD,EAG2DO,EAAA3uC,GAH3D,GAIDmuC,CAJC,CAIQC,CAJR,EAImBM,EAAAnwC,GAJnB,CAIkCqwC,EAAAhyC,GAJlC,EAMDuxC,EAAJ,GACQrwB,CAAAC,eACJ,EAD0BD,CAAAC,eAAA,EAC1B,CAAAiwB,CAAAJ,GAAA,CAAmBO,CAAnB,CAFJ,CAIA,OAAO,CAAA,CA3BmC,CA8B9Cz9B,EAAAm+B,WAAA,CAAqBC,QAAmB,CAAChxB,CAAD,CAAQ,CAM5CA,CAAA,CAAQA,CAAR,EAAiBzW,MAAAyW,MAKjB,IAAI,CAACA,CAAAixB,QAAL,CAAoB,CAChB,IAAIZ,EAASrwB,CAAAkxB,MAATb,EAAwBrwB,CAAAswB,QAKxBtwB,EAAAwwB,OAAJ,EACQH,CADR,EACkBc,EAAAzxC,GADlB,GAEQ2wC,CAFR,CAEiBe,EAAA7xC,GAFjB,CAKA2wC,EAAAJ,GAAA,CAAmBO,CAAnB,CAQIrwB,EAAAC,eAAJ,EAA0BD,CAAAC,eAAA,EAnBV,CAqBpB,MAAO,CAAA,CAhCqC,CAmChDrN,EAAAy+B,QAAA,CAAkBC,QAAmB,CAACtxB,CAAD,CAAQ,CACrCA,CAAAuxB,gBAAJ,EAA2BvxB,CAAAuxB,gBAAA,EACvBvxB;CAAAC,eAAJ,EAA0BD,CAAAC,eAAA,EAE1B,EADIuxB,CACJ,CADoBxxB,CAAAwxB,cACpB,EAD2CjoC,MAAAioC,cAC3C,GAKItB,CAAAJ,GAAA,CAAmB0B,CAAAC,QAAA,CAAsB,MAAtB,CAAnB,CATqC,CAkB7C7+B,EAAA8+B,gBAAA,CAAwB,UAAxB,CAEA,OAAO,CAAA,CAlG+B,CAoG1C,MAAO,CAAA,CArGX,CAiHAl7B,EAAA0J,GAAA,CAAAA,QAAO,CAACtO,CAAD,CAAMD,CAAN,CAAWD,CAAX,CAAgBD,CAAhB,CACP,CACI,IAAAG,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CAEXmG,GAAA,CAAAA,IAAA,CANJ,CA+BApB;CAAAq5B,GAAA,CAAAA,QAAc,CAACL,CAAD,CACd,CACI,GAAI,CAAC,IAAAG,EAAL,CAAsB,CAClB,IAAIgC,EAAc9kB,EAAA,CAAA,IAAAjb,EAAA,CAAwB,YAAxB,CAClB,IAAI+/B,CAAJ,CAAiB,CACb,IAAIC,EAAUD,CAAAhmC,MAAA,CAAkB,OAAlB,CACd,IAAsB,CAAtB,EAAIimC,CAAAprC,OAAJ,CAAyB,CACrB,IAAIqrC,EAAYC,EAAA,CAASF,CAAA,CAAQ,CAAR,CAAT,CAChB,IAAIC,CAAJ,EAAiB,IAAAhhC,GAAjB,CAAmC,MAC/BkhC,EAAAA,CAAYD,EAAA,CAASF,CAAA,CAAQ,CAAR,CAAT,CAEhB,IADA,IAAAjC,EACA,CADkB7rB,EAAA,CAA2BiuB,CAA3B,CAClB,CAAqB,CACjB,IAAI17B,EAAU,IAAAs5B,EAAA,QACd,IAAIt5B,CAAJ,CAAa,CACT,IAAI27B,EAAY37B,CAAA,QACZ27B,EAAJ,EAAeA,CAAA17B,KAAA,CAAe,IAAAq5B,EAAf,CAAgC,IAAAH,EAAhC,CAEf,IADA,IAAAI,EACA,CADgBv5B,CAAA,YAChB,CAAmB,CACf,IAAAm5B,EAAA,CAAkBA,CAElB,KAAAlmC,OAAA,CAAY,YAAZ,CAA2B,IAAAwH,GAA3B,CAA4C,GAA5C,CAAkD+gC,CAAlD,CAA8D,MAA9D,CAAuEE,CAAvE,CACA,OAJe,CAJV,CAFI,CALA,CAuBzB,IAAAzoC,OAAA,CAAY,kCAAZ,CAAiDqoC,CAAjD,CAzBa,CAFC,CAD1B,CAyCAn7B,EAAAyB,GAAA,CAAAA,QAAO,CAACjN,CAAD,CAAOqV,CAAP,CACP,CACI,GAAI,CAACA,CAAL,CAUI,GAFA,IAAAwvB,GAAA,CAAoB,IAAAL,EAApB,CAEI,CAAA,CAACxkC,CAAL,CACI,IAAAoU,MAAA,EADJ,KAGI,IAAI,CAAC,IAAAmB,QAAA,CAAavV,CAAb,CAAL,CAAyB,MAAO,CAAA,CAGxC,OAAO,CAAA,CAjBX,CA4BAwL;CAAA0B,GAAA,CAAAA,QAAS,CAACC,CAAD,CACT,CACI,MAAOA,EAAA,CAAO,IAAAqI,KAAA,EAAP,CAAqB,CAAA,CADhC,CASAhK,EAAA4I,MAAA,CAAAA,QAAK,EACL,EAYA5I,EAAAgK,KAAA,CAAAA,QAAI,EACJ,CACI,IAAIC,EAAQ,IAAIC,CAAJ,CAAU,IAAV,CACZD,EAAAE,IAAA,CAAU,CAAV,CAwCO,EAxCP,CACA,OAAOF,EAAAzV,KAAA,EAHX,CAeAwL,EAAA+J,QAAA,CAAAA,QAAO,EACP,CACI,MAYO,CAAA,CAbX,CAwCA/J,EAAAs5B,GAAA,CAAAA,QAAW,CAAC9kC,CAAD,CACX,CACI,GAAmB,QAAnB,EAAI,MAAOA,EAAX,CACI,IAAAykC,EAAA7jC,KAAA,CAAoBZ,CAApB,CADJ,KAGK,IAAmB,QAAnB,EAAI,MAAOA,EAAX,CAED,IAF8B,IAC1BqlC,EAAS,CADiB,CACd4B,CADc,CAErBtvC,EAAI,CAAb,CAAgBA,CAAhB,CAAoBqI,CAAAxE,OAApB,CAAiC7D,CAAA,EAAjC,CAAsC,CAClCsvC,CAAA,CAAa5B,CACbA,EAAA,CAASrlC,CAAAknC,WAAA,CAAgBvvC,CAAhB,CAMT,IA/zgBJwvC,EA+zgBI,EAAI9B,CAAJ,CAA4B,CACxB,GA/zgBR+B,EA+zgBQ,EAAIH,CAAJ,CAAgC,QAChC5B,EAAA,CAh0gBR+B,EA8zgBgC,CAI5B,IAAA3C,EAAA7jC,KAAA,CAAoBykC,CAApB,CAZkC,CAFrC,IAkBD,KAAAZ,EAAA,CAAiB,IAAAA,EAAAt1B,OAAA,CAAsBnP,CAAtB,CAGrB,OAAO,CAAA,CAzBX,CAgEAwL,EAAAu5B,GAAA,CAAAA,QAAa,EACb,EAWAv5B,EAAAw5B,GAAA,CAAAA,QAAa,CAACl+B,CAAD,CAAYhE,CAAZ,CACb,CACI,MAAK,KAAA6hC,EAAL,CAKO,CAAA,CALP,EACI,IAAAA,EAEO,CAFW79B,CAEX,CADP,IAAA89B,EACO,CADS9hC,CACT,CAAA,CAAA,CAHX,CADJ,CAwGJuW;EAAA,CAfIZ,QAAW,EACX,CAEI,IADA,IAAI4uB,EAAWh/B,CAAA,CAA6BsQ,QAA7B,CAAuCxQ,CAAvC,CAAuD,QAAvD,CAAf,CACSm/B,EAAU,CAAnB,CAAsBA,CAAtB,CAAgCD,CAAA7rC,OAAhC,CAAiD8rC,CAAA,EAAjD,CAA4D,CACxD,IAAIC,EAAUF,CAAA,CAASC,CAAT,CAAd,CACIhD,EAAct7B,EAAA,CAA4Bu+B,CAA5B,CACdrC,EAAAA,CAAS,IAAIb,EAAJ,CAAoBC,CAApB,CACbvrB,GAAA,CAAgCmsB,CAAhC,CAAwCqC,CAAxC,CAJwD,CAFhE,CAcJ,CAoEIliC,SAfEmiC,GAeS,CAACC,CAAD,CACX,CAGQ,CAAA,KAAA,CAAA,IAAA,CAAM,UAAN,CAAkBA,CAAlB,CAKA,KAAAC,EAAA,CAAa,CAACD,CAAA,KAAd,EAAkC,EAMlC,KAAAE,EAAA,CAAa,EAEb,KAAAC,EAAA,CAAgB,CAAC,GAAD,CAAK,GAAL,CAChB,KAAAC,GAAA,CAAkB,CAAC,GAAD,CAAK,GAAL,CAUlB,KAAApoB,EAAA,CAAe,CAMf,KAAAqoB,EAAA,CAAiB,CAAA,CAMjB,KAAAC,EAAA,CAAiB,EACjB,KAAAC,EAAA,CAAiB,EAiBjB,KAAAC,EAAA,CAAkB,EAzD1B,CAhBmB/zB,EAAA5O,CAAjBkiC,EAAiBliC,CAAAA,CAAAA,CAwFnB,GAAA,UAAA,GAAA,CAAA4iC,QAAW,EACX,CACI,MAAQ,EADZ,CAaA,GAAA,UAAA,GAAA,CAAAC,QAAW,EACX,EA+DAC;QAAA,GAAY,CAAZA,CAAY,CAACC,CAAD,CAAOl7B,CAAP,CAAcm7B,CAAd,CACZ,CACI,GAAIn7B,CAAJ,CACI,GAAKk7B,CAAL,CAMO,CACiB,CAApB,CAAI,CAAAN,EAAJ,EAAyB,CAAAC,EAAAxsC,OAAzB,GACI,CAAAusC,EADJ,CACoB,CADpB,CAGA,IAAoB,CAApB,CAAI,CAAAA,EAAJ,EAAyBM,CAAzB,EAAiC,CAAAL,EAAA,CAAe,CAAAD,EAAf,CAAjC,CACI,CAAAC,EAAAr9B,OAAA,CAAsB,CAAtB,CAAyB,CAAzB,CAA4B09B,CAA5B,CACA,CAAA,CAAAN,EAAA,CAAgB,CAEpB,EAAAA,EAAA,EARG,CANP,IACQ,EAAAD,EAAJ,CACIO,CADJ,CACW,KADX,CAGIA,CAHJ,CAGW,CAAAL,EAAA,CAAe,CAAAD,EAAf,CAA6B,CAA7B,CAaf5wC,EAAAA,CAAI,EACR,IAAIkxC,CAAJ,CAAU,CAaNA,CAAA,CAAOA,CAAAlvC,QAAA,CAAa,KAAb,CAAoB,GAApB,CAEHovC,EAAAA,CAAQ,CACZ,KAAIC,EAAU,IACdF,EAAA,CAAQA,CAAR,EAAiB,GAQjB,KAAK,IAAI3wC,EAAI,CAAb,CAAgBA,CAAhB,EAAqB0wC,CAAA7sC,OAArB,CAAkC7D,CAAA,EAAlC,CAAuC,CACnC,IAAIyB,EAAKivC,CAAAhvC,OAAA,CAAY1B,CAAZ,CACT,IAAU,GAAV,EAAIyB,CAAJ,EAAuB,GAAvB,EAAiBA,CAAjB,CACSovC,CAAL,CAEWpvC,CAFX,EAEiBovC,CAFjB,GAGIA,CAHJ,CAGc,IAHd,EACIA,CADJ,CACcpvC,CAFlB,KAOK,IAAIA,CAAJ,EAAUkvC,CAAV,EAAmB,CAACE,CAApB,EAA+B,CAACpvC,CAAhC,CAKDjC,CAAAyJ,KAAA,CAAOkmC,EAAA,CAASuB,CAAAI,UAAA,CAAeF,CAAf,CAAsB5wC,CAAtB,CAAT,CAAP,CACA,CAAA4wC,CAAA,CAAQ5wC,CAAR,CAAY,CAfmB,CAzBjC,CA4CV,MAAOR,EAhEX,CA+EAuxC,QAAA,GAAO,CAAPA,CAAO,CAACnf,CAAD,CAAMD,CAAN,CACP,CAUI,GAAkB,EAAlB,EAAI,CAAAqe,EAAJ,CACI,MAAOpe,EAAP,CAAaD,CAKjBC,EAAA,CAAMof,CAAA,CAAAA,CAAA,CAAcpf,CAAd,CAAmB,CAAnB,CAAsB,CAAA,CAAtB,CACND,EAAA,CAAMqf,CAAA,CAAAA,CAAA,CAAcrf,CAAd,CAAmB,CAAnB,CAAsB,CAAA,CAAtB,CACN,SAAWC,CAAX,CAAiBqf,EAAjB,CAAqC,CAArC,GAA4Ctf,CAA5C,CAAkDsf,EAAlD,CAAsE,CAAtE,GAA4EA,EAA5E,GAAoGrf,CAApG,CAA0GD,CAA1G,IAAmH,CAAnH,CAlBJ;AAmEAuf,QAAA,GAAO,CAAPA,CAAO,CAACtf,CAAD,CAAMD,CAAN,CACP,CAUI,GAAkB,EAAlB,EAAI,CAAAqe,EAAJ,CACI,MAAOpe,EAAP,CAAaD,CAKjBC,EAAA,CAAMof,CAAA,CAAAA,CAAA,CAAcpf,CAAd,CAAmB,CAAnB,CAAsB,CAAA,CAAtB,CACND,EAAA,CAAMqf,CAAA,CAAAA,CAAA,CAAcrf,CAAd,CAAmB,CAAnB,CAAsB,CAAA,CAAtB,CACN,SAAWC,CAAX,CAAiBqf,EAAjB,CAAqC,CAArC,GAA4Ctf,CAA5C,CAAkDsf,EAAlD,CAAsE,CAAtE,GAA4EA,EAA5E,GAAoGrf,CAApG,CAA0GD,CAA1G,IAAmH,CAAnH,CAlBJ,CAgCA,EAAA,UAAA,GAAA,CAAAwf,QAAO,CAACvf,CAAD,CAAMD,CAAN,CACP,CACI,MAAOC,EAAP,CAAaD,CADjB,CAaAqf,SAAA,EAAQ,CAARA,CAAQ,CAACnwC,CAAD,CAAImvC,CAAJ,CAAWoB,CAAX,CACR,CACI,IAAWC,EAAOxwC,CAClBmvC,EAAA,CAAQA,CAAR,EAAiB,CAAAA,EAEjB,IAAIoB,CAAJ,CACI,GAAa,EAAb,EAAIpB,CAAJ,CACIqB,CAAA,CAAOxwC,CAAP,GAAa,CADjB,KAGK,IAAY,EAAZ,CAAImvC,CAAJ,CACDqB,CAAA,CAAOxwC,CAAP,EAAa,CAAb,EAAkBmvC,CAAlB,EAA2B,CAD1B,KAKD,IADAsB,CACI,CADIrvC,IAAAC,IAAA,CAAS,CAAT,CAAY8tC,CAAZ,CACJ,CAAI,CAAJ,CAAAnvC,CAAA,EAASA,CAAT,EAAcywC,CAAlB,CACID,CACA,CADOxwC,CACP,CADWywC,CACX,CAAW,CAAX,CAAID,CAAJ,GAAcA,CAAd,EAAsBC,CAAtB,CAFJ,CATR,IAgBiB,GAAb,EAAItB,CAAJ,CACIqB,CADJ,CACYxwC,CADZ,EACkB,EADlB,CACuBmvC,CADvB,EACmC,EADnC,CACwCA,CADxC,EAIIsB,CACA,CADQrvC,IAAAC,IAAA,CAAS,CAAT,CAAY8tC,CAAZ,CAAoB,CAApB,CACR,CAAInvC,CAAJ,EAASywC,CAAT,EACID,CACA,CADQxwC,CACR,CADYywC,CACZ,EAAMzwC,CAAN,CAAUywC,CAAV,CAAiB,CAAjB,EAAsB,CAAtB,GAAyBD,CAAzB,EAAiCC,CAAjC,CAFJ,EAGWzwC,CAHX,CAGe,CAACywC,CAHhB,GAIID,CACA,CADQxwC,CACR,CADYywC,CACZ,CAAA,EAAO,CAACzwC,CAAR,CAAY,CAAZ,EAAiBywC,CAAjB,CAA0B,CAA1B,EAA+B,CAA/B,CACQD,CADR,GACcA,CADd,EACsBC,CADtB,EAISD,CAJT,GAIeA,CAJf,EAIuBC,CAJvB,CALJ,CALJ,CAmBAzwC,EAAJ,EAASwwC,CAAT,GAEIxwC,CAFJ,CAEQwwC,CAFR,CAIA,OAAOxwC,EA3CX;AAyEA0wC,QAAA,GAAO,CAAPA,CAAO,CAACC,CAAD,CAAQC,CAAR,CAAcC,CAAd,CACP,CACI,IAFiBA,CAEjB,CAFiB,IAAA,EAAA,GAAAA,CAAA,CAAQ,EAAR,CAAAA,CAEjB,CAAOA,CAAA,EAAP,EAAiBD,CAAA5tC,OAAjB,CAAA,CAA8B,CAC1B,IAAI8tC,EAAOF,CAAAG,IAAA,EACX,IAAmB,CAAnB,CAAIJ,CAAA3tC,OAAJ,CAAsB,MAAO,CAAA,CAC7B,KACIguC,EAAOL,CAAAI,IAAA,EACPE,KAAAA,EAAON,CAAAI,IAAA,EACX,QAAOD,CAAP,EACA,KAAK,GAAL,CACII,CAAA,CAAS,CAAAZ,GAAA,CAAaW,CAAb,CAAmBD,CAAnB,CACT,MACJ,MAAK,GAAL,CACI,GAAI,CAACA,CAAL,CAAW,MAAO,CAAA,CAClBE,EAAA,CAAS9vC,IAAAE,MAAA,CAAW2vC,CAAX,CAAkBD,CAAlB,CACT,MACJ,MAAK,IAAL,CACI,GAAI,CAACA,CAAL,CAAW,MAAO,CAAA,CACTC,EAAT,EAAgBD,CAChB,MACJ,MAAK,GAAL,CACaC,CAAT,EAAgBD,CAChB,MACJ,MAAK,GAAL,CACaC,CAAT,EAAgBD,CAChB,MACJ,MAAK,UAAL,CACaC,CAAT,GAAiBD,CACjB,MACJ,MAAK,UAAL,CACaC,CAAT,GAAiBD,CACjB,MACJ,MAAK,cAAL,CACaC,CAAT,IAAkBD,CAClB,MACJ,MAAK,MAAL,CACIE,CAAA,CAAUD,CAAA,CAAOD,CAAP,CAAa,CAAb,CAAiB,CAC3B,MACJ,MAAK,UAAL,CACIE,CAAA,CAAUD,CAAA,EAAQD,CAAR,CAAc,CAAd,CAAkB,CAC5B,MACJ,MAAK,MAAL,CACIE,CAAA,CAAUD,CAAA,CAAOD,CAAP,CAAa,CAAb,CAAiB,CAC3B,MACJ,MAAK,UAAL,CACIE,CAAA,CAAUD,CAAA,EAAQD,CAAR,CAAc,CAAd,CAAkB,CAC5B,MACJ,MAAK,UAAL,CACIE,CAAA;AAAUD,CAAA,EAAQD,CAAR,CAAc,CAAd,CAAkB,CAC5B,MACJ,MAAK,OAAL,CACIE,CAAA,CAAUD,CAAA,EAAQD,CAAR,CAAc,CAAd,CAAkB,CAC5B,MACJ,MAAK,MAAL,CACIE,CAAA,CAAShB,EAAA,CAAAA,CAAA,CAAae,CAAb,CAAmBD,CAAnB,CACT,MACJ,MAAK,GAAL,CACA,KAAK,GAAL,CAC0BC,CAAAA,CAAAA,CA1MZ,GAAlB,EA0MiBE,CA1MbhC,EAAJ,CACI,CADJ,CACWpe,CADX,CACiBD,CADjB,EAMAC,CAEA,CAFMof,CAAA,CAoMWgB,CApMX,CAAcpgB,CAAd,CAAmB,CAAnB,CAAsB,CAAA,CAAtB,CAEN,CADAD,CACA,CADMqf,CAAA,CAmMWgB,CAnMX,CAAcrgB,CAAd,CAAmB,CAAnB,CAAsB,CAAA,CAAtB,CACN,CAAA,CAAA,EAAWC,CAAX,CAAiBqf,EAAjB,CAAqC,CAArC,CAA4Ctf,CAA5C,CAAkDsf,EAAlD,CAAsE,CAAtE,EAA4EA,EAA5E,GAAoGrf,CAApG,CAA0GD,CAA1G,IAAmH,CAAnH,CARA,CA2MQ,MACJ,MAAK,IAAL,CACIogB,CAAA,CAASb,EAAA,CAAAA,CAAA,CAAaY,CAAb,CAAmBD,CAAnB,CACT,MACJ,MAAK,UAAL,CACIE,CAAA,CAAUD,CAAA,EAAQD,CAAR,CAAc,CAAd,CAAkB,CAC5B,MACJ,MAAK,IAAL,CACIE,CAAA,CAAUD,CAAA,EAAQD,CAAR,CAAc,CAAd,CAAkB,CAC5B,MACJ,MAAK,IAAL,CACIE,CAAA,CAASf,CAAA,CAAAA,CAAA,CAAcc,CAAd,CAAoB,EAApB,CAAwB,CAAA,CAAxB,CAAT,CAAyC7vC,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAzC,CAA2D8uC,CAAA,CAAAA,CAAA,CAAca,CAAd,CAAoB,EAApB,CAAwB,CAAA,CAAxB,CAC3D,MACJ,MAAK,GAAL,CACA,KAAK,IAAL,CAOgB,IAAZ,EAAIF,CAAJ,GAAkBE,CAAlB,CAAyB,EAAzB,EAA+BA,CAA/B,CAAsC,GAAtC,EACIA,EAAJ,GAKIE,CAEI,CAFKf,CAAA,CAAAA,CAAA,CAAce,CAAd,CAAsB,CAAtB,CAAyB,CAAA,CAAzB,CAEL,CAAAA,CAAA,CADO,CAAX,CAAIF,CAAJ,CACIE,CADJ,CACc9vC,IAAAC,IAAA,CAAS,CAAT,CAAY2vC,CAAZ,CADd,CAGa5vC,IAAAE,MAAA,CAAW4vC,CAAX,CAAoB9vC,IAAAC,IAAA,CAAS,CAAT,CAAY,CAAC2vC,CAAb,CAApB,CATjB,CAYA,MACJ,SACI,MAAO,CAAA,CAvFX,CAyFAL,CAAAvoC,KAAA,CAAW+nC,CAAA,CAAAA,CAAA,CAAce,CAAd,CAAX,CA/F0B,CAiG9B,MAAO,CAAA,CAlGX;AA2HAE,QAAA,GAAU,CAAVA,CAAU,CAACC,CAAD,CAAWC,CAAX,CAAmBC,CAAnB,CAA2BrC,CAA3B,CAAkCsC,CAAlC,CACV,CACI,IAAIjwC,CAAJ,CAEIkwC,EAAS,CAAA,CAFb,CAGIC,EAAS,CAHb,CAIIf,EAAQ,EAJZ,CAIgBC,EAAO,EAJvB,CAMIe,EAAY,CAAAzC,EAGhB,KAFA,CAAAA,EAEA,CAFaA,CAEb,CAAOoC,CAAP,CAAgBC,CAAhB,CAAA,CAAwB,CAEpB,IAAAtoC,EAASooC,CAAA,CAASC,CAAA,EAAT,CAAAhuC,KAAA,EACT,KAAAsuC,EAAON,CAAA,CAASC,CAAT,CAAiBF,CAAA,CAASC,CAAA,EAAT,CAAjB,CAAsC,EAE7C,IAAIroC,CAAJ,CACI,IAAAjJ,EAAI6xC,EAAA,CAAAA,CAAA,CAAgB5oC,CAAhB,CAAwB,IAAxB,CAA8BuoC,CAA9B,CAA0CE,CAA1C,CADR,KAGI,IAAW,GAAX,EAAIE,CAAJ,CAAgB,CACRE,CAAAA,CAAQ,CAEZ,KADIC,CACJ,CADaT,CACb,CAAOA,CAAP,CAAgBC,CAAhB,CAAA,CAGI,GAFkBD,CAAAhuC,EAEd,CADJsuC,CACI,CADGN,CAAA,CAASD,CAAAruC,OAAT,CAA0BquC,CAAA,CAASC,CAAA,EAAT,CAA1B,CAA+C,EAClD,CAAO,GAAP,EAAAM,CAAJ,CACIE,CAAA,EADJ,KAEO,IAAW,GAAX,EAAIF,CAAJ,EACC,CAAC,EAAEE,CADJ,CACW,KAGtB9xC,EAAA,CAAIoxC,EAAA,CAAAA,CAAA,CAAgBC,CAAhB,CAA0BU,CAA1B,CAAkCT,CAAlC,CAAyC,CAAzC,CAA4C,CAAApC,EAA5C,CAAwDsC,CAAxD,CACK,KAAT,EAAIxxC,CAAJ,EAAiB0xC,CAAjB,GACI1xC,CADJ,CACQgyC,EAAA,CAAAA,CAAA,CAAgBhyC,CAAhB,CAAmB0xC,CAAnB,CADR,CAGAzoC,EAAA,CAAUqoC,CAAA,CAASC,CAAT,CAAiBF,CAAA,CAASC,CAAA,EAAT,CAAAhuC,KAAA,EAAjB,CAA6C,EACvDsuC,EAAA,CAAON,CAAA,CAASC,CAAT,CAAiBF,CAAA,CAASC,CAAA,EAAT,CAAjB,CAAsC,EAjBjC,CAAhB,IAmBK,CAQD,GAAW,GAAX,EAAIM,CAAJ,CACI,QAEJ,IAAW,IAAX,EAAIA,CAAJ,CAAiB,CACb,CAAA1C,EAAA,CAAa,CACb,SAFa,CAIjB,GAAW,IAAX,EAAI0C,CAAJ,CAAiB,CACb,CAAA1C,EAAA,CAAa,CACb,SAFa,CAIjB,GAAW,IAAX,EAAI0C,CAAJ,CAAiB,CACb,CAAA1C,EAAA,CAAa,EACb,SAFa,CAIjB,GAAI,EAAEwC,CAAF,CAAY,WAAZ,CAAJ,CAAgC,CAC5B,GAAW,GAAX,EAAIE,CAAJ,CACI,QAEJ,IAAW,GAAX,EAAIA,CAAJ,CAAgB,CACZF,CAAA,CAAUA,CAAV,EAAoB,CAApB,CAAyB,CACzB,SAFY,CAIhB,GAAW,GAAX;AAAIE,CAAJ,EAAyB,IAAzB,EAAkBA,CAAlB,CAA+B,CAC3BF,CAAA,CAAUA,CAAV,EAAoB,CAApB,CAAyB,CACzB,SAF2B,CAI/B,GAAW,IAAX,EAAIE,CAAJ,CAAiB,CACbF,CAAA,CAAUA,CAAV,EAAoB,CAApB,CAAyB,CACzB,SAFa,CAZW,CAiBhCD,CAAA,CAAS,CAAA,CACT,MAzCC,CA6CT,GAAU5tC,IAAAA,EAAV,GAAI7D,CAAJ,CACI,GAAIwxC,CAAJ,CACIA,CAAAppC,KAAA,CAAgBa,CAAhB,CACA,CAAAjJ,CAAA,CAAI,CAFR,KAGO,CACHyxC,CAAA,CAAS,CAAA,CACTD,EAAA,CAAa,EACb,MAHG,CAOXb,CAAAvoC,KAAA,CAAW+nC,CAAA,CAAAA,CAAA,CAAcnwC,CAAd,CAAX,CASA,IAAW,GAAX,EAAI4xC,CAAJ,CACI,GAAIN,CAAJ,CAAaD,CAAAruC,OAAb,CAA+B,CAA/B,EAAoC,CAACquC,CAAA,CAASC,CAAT,CAArC,CACIA,CAAA,EACA,CAAAM,CAAA,CAAMP,CAAA,CAASC,CAAA,EAAT,CAFV,KAGO,CACHG,CAAA,CAAS,CAAA,CACT,MAFG,CAMX,GAAI,CAACG,CAAL,CAAU,KAENK,EAAAA,CAA8B,MAApB,EAAA,CAAA7C,EAAA,CAAc,CAAd,CAAA,CAAyB8C,EAAzB,CAAqDC,EACnE,IAAI,CAACF,CAAA,CAAOL,CAAP,CAAL,CAAkB,CACdH,CAAA,CAAS,CAAA,CACT,MAFc,CAIdb,CAAA5tC,OAAJ,EAAmBivC,CAAA,CAAOL,CAAP,CAAnB,EAAkCK,CAAA,CAAOrB,CAAA,CAAKA,CAAA5tC,OAAL,CAAmB,CAAnB,CAAP,CAAlC,EACI0tC,EAAA,CAAAA,CAAA,CAAaC,CAAb,CAAoBC,CAApB,CAA0B,CAA1B,CAEJA,EAAAxoC,KAAA,CAAUwpC,CAAV,CAMA,EAAA1C,EAAA,CAAqB,IAAR,EAAC0C,CAAD,CAAe,EAAf,CAAoB1C,CACjCwC,EAAA,CAAS,CAvHW,CA0HxB,GAAID,CAAJ,EAAc,CAACf,EAAA,CAAAA,CAAA,CAAaC,CAAb,CAAoBC,CAApB,CAAf,EAA4D,CAA5D,EAA4CD,CAAA3tC,OAA5C,CACIyuC,CAAA,CAAS,CAAA,CAGRA,EAAL,CAGYD,CAHZ,EAII,CAAAh+B,EAAA,CAAa,eAAb,EAAgCvK,CAAhC,EAA0C2oC,CAA1C,EAAiD,GAAjD,CAJJ,CACIrwC,CADJ,CACYovC,CAAAI,IAAA,EAMZ,EAAA7B,EAAA,CAAayC,CACb,OAAOpwC,EAhJX;AA6JA6wC,QAAA,GAAU,CAAVA,CAAU,CAACC,CAAD,CAAOC,CAAP,CAAgBnD,CAAhB,CAAuBoD,CAAvB,CACV,CAEI,IADA,IAAIpzC,CACJ,CAAsC,CAAtC,GAAQA,CAAR,CAAYkzC,CAAA3xC,QAAA,CAAa4xC,CAAb,CAAZ,EAAA,CAAyC,CAIrC,IAHA,IAAItyC,EAAI,CAAR,CACIZ,EAAID,CAAJC,CAAQ,CADZ,CAEIsC,EAAM6wC,CACV,CAAOnzC,CAAP,CAAWizC,CAAArvC,OAAX,CAAA,CAAwB,CACpB,IAAIpC,EAAKyxC,CAAA,CAAKjzC,CAAA,EAAL,CACT,IAAIwB,CAAJ,EAAU0xC,CAAV,CAAmB,CACf5wC,CAAA,CAAO,EACP,MAFe,CAInB,GAAI,CAACA,CAAL,CAAU,KACVA,EAAA,EACI7C,EAAAA,CAAI+B,CAAA8tC,WAAA,CAAc,CAAd,CACK,EAAb,EAAIS,CAAJ,CACItwC,CADJ,EACS,GADT,CAGIA,CAHJ,CAGSA,CAHT,CAGa,EAHb,CAGqB,EAErBmB,EAAA,CAAImwC,CAAA,CAAAA,CAAA,CAAcnwC,CAAd,CAAkBoB,IAAAC,IAAA,CAAS,CAAT,CAAY8tC,CAAZ,CAAlB,CAAuCtwC,CAAvC,CAA0CswC,CAA1C,CAAkDoD,CAAlD,CAA0D,CAAA,CAA1D,CAdgB,CAgBxB,GAAW,CAAX,EAAI7wC,CAAJ,CAAc,CACV,CAAA8R,EAAA,CAAa,eAAb,CAA+B8+B,CAA/B,CAAyCD,CAAzC,CAAgDC,CAAhD,CAA0D,GAA1D,CACA,OAFU,CAIVD,CAAA,CAAOA,CAAAvxC,OAAA,CAAY,CAAZ,CAAe3B,CAAf,CAAP,CAA2BqlB,CAAA,CAAAA,CAAA,CAAexkB,CAAf,CAAmB,EAAnB,CAA3B,CAAmDqyC,CAAAvxC,OAAA,CAAY1B,CAAZ,CAxBlB,CA2BzC,MAAOizC,EA7BX;AA6DAG,QAAA,GAAe,CAAfA,CAAe,CAACH,CAAD,CAAOI,CAAP,CACf,CACI,IAAIlxC,EAAQsC,IAAAA,EAAZ,CACI6uC,EAAqB,CAAA,CAArBA,GAAUD,CACVjB,EAAAA,CAAa5pC,KAAAmO,QAAA,CAAc08B,CAAd,CAAA,CAAuBA,CAAvB,CAAgC5uC,IAAAA,EAEjD,IAAIwuC,CAAJ,CAAU,CAYkB,GAAxB,EAAI,CAAAjD,EAAA,CAAc,CAAd,CAAJ,GACIiD,CADJ,CACWA,CAAAlqC,MAAA,CAAW,CAAAinC,EAAA,CAAc,CAAd,CAAX,CAAAuD,KAAA,CAAkC,GAAlC,CAAAxqC,MAAA,CAA6C,CAAAinC,EAAA,CAAc,CAAd,CAA7C,CAAAuD,KAAA,CAAoE,GAApE,CADX,CAQAN,EAAA,CAAOD,EAAA,CAAAA,CAAA,CAAgBC,CAAhB,CAAsB,GAAtB,CAA2B,CAA3B,CAA8B,CAA9B,CACP,IAAI,CAACA,CAAL,CAAW,MAAO9wC,EAClB8wC,EAAA,CAAOD,EAAA,CAAAA,CAAA,CAAgBC,CAAhB,CAAsB,GAAtB,CAA2B,CAA3B,CAA8B,CAA9B,CACP,IAAI,CAACA,CAAL,CAAW,MAAO9wC,EAsCA,GAAlB,EAAI,CAAA2tC,EAAJ,GACImD,CADJ,CACWA,CAAA1xC,QAAA,CAAa,2BAAb,CAA0C,QAA1C,CAAAA,QAAA,CAA4D,MAA5D,CAAoE,GAApE,CADX,CAGI0wC,EAAAA,CAAWgB,CAAAlqC,MAAA,CAJFyqC,qGAIE,CACfrxC,EAAA,CAAQ6vC,EAAA,CAAAA,CAAA,CAAgBC,CAAhB,CAA0B,CAA1B,CAA6BA,CAAAruC,OAA7B,CAA8C,CAAAksC,EAA9C,CAA0DsC,CAA1D,CACM3tC,KAAAA,EAAd,GAAItC,CAAJ,EAA2BmxC,CAA3B,EACIG,EAAA,CAAAA,CAAA,CAAgB,IAAhB,CAAsBtxC,CAAtB,CAnEE,CAsEV,MAAOA,EA3EX;AA4KAywC,QAAA,GAAU,CAAVA,CAAU,CAACzwC,CAAD,CAAQmwC,CAAR,CACV,CACI,IAAA,CAAOA,CAAP,CAAA,CAAe,CACX,OAAOA,CAAP,CAAgB,CAAhB,EACA,KAAK,CAAL,CACInwC,CAAA,CAAQ,CAAC4uC,CAAA,CAAAA,CAAA,CAAc5uC,CAAd,CACT,MACJ,MAAK,CAAL,CACIA,CAAA,CAAQ8uC,EAAA,CAAAA,CAAA,CAAa9uC,CAAb,CAAqB,EAArB,CACR,MACJ,MAAK,CAAL,CAEI,IADA,IAAIuxC,EAAM,EACV,CAAc,CAAd,EAAOA,CAAP,EAAmB,CAAC5C,EAAA,CAAAA,CAAA,CAAa3uC,CAAb,CAAoBH,IAAAC,IAAA,CAAS,CAAT,CAAYyxC,CAAZ,CAApB,CAApB,CAAA,CAA2DA,CAAA,EAC3DvxC,EAAA,CAAQ,EAAR,CAAauxC,CAVjB,CAaApB,CAAA,IAAY,CAdD,CAgBf,MAAOnwC,EAjBX;AA8BAswC,QAAA,GAAU,CAAVA,CAAU,CAAC5oC,CAAD,CAASuF,CAAT,CAAgBikC,CAAhB,CAAwBf,CAAxB,CACV,CADkCA,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAS,CAAT,CAAAA,CAE9B,KACIF,EAAa5pC,KAAAmO,QAAA,CAAc08B,CAAd,CAAA,CAAuBA,CAAvB,CAAgC5uC,IAAAA,EAEjD,IAAc,IAAd,EAAIoF,CAAJ,CAAoB,CACZ8pC,IAAAA,EAAO,CAAArD,GAAA,CAAiBzmC,CAAjB,CACX,IAAY,CAAZ,EAAI8pC,CAAJ,CACIxxC,CAAA,CAAQ,CAAAouC,GAAA,CAAiBoD,CAAjB,CADZ,KAII,IADyB9pC,CACrB,CADqBA,CACrB,CADI+pC,CAwIZvD,EAAA,CAAgBwD,CAAhB,CAAJ,CACI,CADJ,CAxIgBD,CAyILvD,EAAA,CAAgBwD,CAAhB,CAAA1xC,MADX,EAGA0xC,CACA,CADOA,CAAAnyC,OAAA,CAAY,CAAZ,CAAe,CAAf,CACP,CAAA,CAAA,CA5IgBkyC,CA4ITvD,EAAA,CAAgBwD,CAAhB,CAAP,EA5IgBD,CA4IgBvD,EAAA,CAAgBwD,CAAhB,CAAA1xC,MAJhC,CAvIY,CAAS,IAAT,EAAAA,CAAJ,CAAmB,CACf,IAAI2xC,EAAaC,CAsJtB1D,EAAA,CAtJ4CxmC,CAsJ5C,CAtJSiqC,EAAaC,CAsJG1D,EAAA,CAtJmBxmC,CAsJnB,CAAAiqC,GArJhBA,EAAJ,GACQ1B,CAAJ,CACIA,CAAAppC,KAAA,CAAgB8qC,CAAhB,CADJ,EAGQE,CACJ,CADqBZ,EAAA,CAAAA,CAAA,CAAqBU,CAArB,CAAiCT,CAAjC,CACrB,CAAuB5uC,IAAAA,EAAvB,GAAIuvC,CAAJ,CACI7xC,CADJ,EACa6xC,CADb,EAGSX,CAGL,EAFI,CAAAj/B,EAAA,CAAa,YAAb,EAA6BhF,CAA7B,EAAsC,OAAtC,EAAiD,IAAjD,CAAwDvF,CAAxD,CAAiE,IAAjE,CAAwEiqC,CAAxE,CAAqF,GAArF,CAEJ,CAAA3xC,CAAA,CAAQsC,IAAAA,EANZ,CAJJ,CADJ,CAFe,CAAnB,IAqBItC,EAAA,CAAQ2c,EAAA,CAAajV,CAAb,CAAqC,CAAhB,CAAAA,CAAAjG,OAAA,EAAkC,EAAlC,CAAqB,CAAAksC,EAArB,CAAsC,CAAAA,EAAtC,CAAmD,EAAxE,CAGH,KAAb,EAAI3tC,CAAJ,CACIA,CADJ,CACY4uC,CAAA,CAAAA,CAAA,CAAc6B,EAAA,CAAAA,CAAA,CAAgBzwC,CAAhB,CAAuBmwC,CAAvB,CAAd,CADZ,CAGSe,CAHT,EAIQ,CAAAj/B,EAAA,CAAa,UAAb,EAA2BhF,CAA3B,EAAoC,OAApC,EAA+C,IAA/C,CAAsDvF,CAAtD,CAlCQ,CAApB,IAsCSwpC,EAAL,EACI,CAAAj/B,EAAA,CAAa,UAAb,EAA2BhF,CAA3B,EAAoC,OAApC,EAGR,OAAOjN,EA9CX;AAyDAsxC,QAAA,GAAU,CAAVA,CAAU,CAACI,CAAD,CAAO1xC,CAAP,CACV,CACI,IACI8xC,EAAW,CAAA,CACf,IAAcxvC,IAAAA,EAAd,GAAItC,CAAJ,CAAyB,CACrB8xC,CAAA,CAAW,CAAA,CAEP,KAAApqC,EADc,CAAlB,EAAI,CAAAimC,EAAJ,CACa1qB,CAAA,CAAAA,CAAA,CAAejjB,CAAf,CAAsB,CAAA4tC,EAAtB,CAAkC,CAAlC,CAAqC,CAArC,CADb,CACuD,IADvD,CAC8D5tC,CAD9D,CACsE,GADtE,CAGaijB,CAAA,CAAAA,CAAA,CAAejjB,CAAf,CAAsB,CAAA4tC,EAAtB,CAAkC,EAAlC,CAAsC,CAAtC,CAHb,CAGwD,IAHxD,CAG+D3qB,CAAA,CAAAA,CAAA,CAAejjB,CAAf,CAAsB,CAAA4tC,EAAtB,CAAkC,CAAlC,CAAqC,CAArC,CAH/D,CAGyG,IAHzG,CAGgH3qB,CAAA,CAAAA,CAAA,CAAejjB,CAAf,CAAsB,CAAA4tC,EAAtB,CAAkC,CAAlC,CAAmD,EAAd,EAAA,CAAAA,EAAA,CAAkB,CAAlB,CAAsB,CAA3D,CAHhH,CAGgL,IAHhL,CAGuL5tC,CAHvL,CAG+L,GAElL,GAAb,EAAIA,CAAJ,EAA6B,GAA7B,CAAqBA,CAArB,GACI0H,CADJ,EACc,IADd,CACqBlH,MAAAC,aAAA,CAAoBT,CAApB,CADrB,CACkD,GADlD,CAPqB,CAYzB,CAAAiS,EAAA,EADgB,IAARy/B,EAAAA,CAAAA,CAAeA,CAAfA,CAAsB,IAAtBA,CAA8B,EACtC,EAAoBhqC,CAApB,CACA,OAAOoqC,EAhBX,CAyBAC,QAAA,GAAc,CAAdA,CAAc,CACd,CACI,IAAI30C,EAAI,CAAA8wC,EACR,EAAAA,EAAA,CAAkB,EAClB,OAAO9wC,EAHX,CAwBA40C,QAAA,GAAa,CAAbA,CAAa,CAACN,CAAD,CACb,CACI,IAAIO,EAAa,CACjB,IAAI,CAAA/D,EAAJ,CAAqB,CACjB,GAAIwD,CAAJ,CACI,MAAOJ,GAAA,CAAAA,CAAA,CAAgBI,CAAhB,CAAsB,CAAAxD,EAAA,CAAgBwD,CAAhB,CAAtB,EAA+C,CAAAxD,EAAA,CAAgBwD,CAAhB,CAAA1xC,MAA/C,CAEPkyC,EAAAA,CAAQv9B,MAAAw9B,KAAA,CAAY,CAAAjE,EAAZ,CACZgE,EAAAE,KAAA,EACA,KAAK,IAAIx0C,EAAI,CAAb,CAAgBA,CAAhB,CAAoBs0C,CAAAzwC,OAApB,CAAkC7D,CAAA,EAAlC,CACI0zC,EAAA,CAAAA,CAAA,CAAgBY,CAAA,CAAMt0C,CAAN,CAAhB,CAA0B,CAAAswC,EAAA,CAAgBgE,CAAA,CAAMt0C,CAAN,CAAhB,CAAAoC,MAA1B,CACA,CAAAiyC,CAAA,EARa,CAWrB,MAAoB,EAApB,CAAOA,CAbX;AA4FAhvB,QAAA,EAAS,CAATA,CAAS,CAAChlB,CAAD,CAAI2vC,CAAJ,CAAeD,CAAf,CAA0BttC,CAA1B,CACT,CADautC,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAQ,CAAR,CAAAA,CAAsBvtC,EAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAY,CAAZ,CAAAA,CAG/B,SAHoB,IAAA,EAAAstC,GAAAA,CAAAA,CAAQ,CAARA,CAAAA,CAGpB,GAAgB,CAAAA,EAAhB,EACA,KAAK,CAAL,CA3xkBA,CA4xkBqB,CA5xkBrB,CA4xkB6B,CAAR,CAAAC,CAAA,CAAWA,CAAX,CAAmB,CA5xkBxC,EAUiB,EAVjB,CAUWztC,CAVX,GAUqBA,CAVrB,CAU2B,EAV3B,GAEQ1B,CAEA,CAFIoB,IAAAe,IAAA,CA0xkBM3C,CA1xkBN,CAEJ,CAAAkC,CAAA,CADK,GAAT,EAAI1B,CAAJ,CACU,CADV,CAEgB,MAAT,EAAIA,CAAJ,CACG,EADH,CAGG,EARd,CAWA,EAAA,CAAOoC,EAAA,CAixkBW5C,CAjxkBX,CAAc,CAAd,CAAiBkC,CAAjB,CAAsB,EAAtB,CAixkBoCE,CAjxkBpC,CAkxkBH,MACJ,MAAK,CAAL,CACI/B,CAAA,CAAIsjB,EAAA,CAAU3jB,CAAV,CAAqB,CAAR,CAAA2vC,CAAA,EAAaA,CAAb,CAAqB,CAArB,EAAwB,CAAxB,CAA2B,CAA3B,CAA+B,CAA5C,CAA+C,CAAC,CAACvtC,CAAjD,CACJ,MACJ,MAAK,EAAL,CAII/B,CAAA,CAAI+zC,EAAA,CAAUp0C,CAAV,CAAqB,CAAR,CAAA2vC,CAAA,CAAW/tC,IAAAS,KAAA,CAAkB,EAAlB,CAAUstC,CAAV,CAAX,CAAoC,CAAjD,CACJ,MAEJ,SACItvC,CAAA,CAAI6kB,CAAA,CAAUllB,CAAV,CAAqB,CAAR,CAAA2vC,CAAA,CAAaA,CAAb,CAAqB,CAArB,EAA2B,CAA3B,CAAgC,CAA7C,CAAgD,CAAC,CAACvtC,CAAlD,CAfR,CAkBgB,CAAR,CAAAutC,CAAA,CAr1jBRtvC,CAq1jBQ,CAAWA,CAr1jBfc,QAAA,CAAU,kBAAV,CAA8B,IAA9B,CAq1jBI,CAAsCd,CAAtC,CAAsCA,CAA9C,OAAQ,EApBZ;AAqCA,IAAAsyC,GAA4B,CACxB,KAAQ,CADgB,CAExB,WAAQ,CAFgB,CAGxB,IAAQ,CAHgB,CAIxB,IAAQ,CAJgB,CAKxB,KAAQ,CALgB,CAMxB,OAAQ,CANgB,CAOxB,QAAQ,EAPgB,CAQxB,WAAQ,EARgB,CASxB,WAAQ,EATgB,CAUxB,OAAQ,EAVgB,CAWxB,WAAQ,EAXgB,CAYxB,OAAQ,EAZgB,CAaxB,eAAQ,EAbgB,CAcxB,WAAQ,EAdgB,CAexB,WAAQ,EAfgB,CAgBxB,IAAQ,EAhBgB,CAiBxB,IAAQ,EAjBgB,CAkBxB,KAAQ,EAlBgB,CAmBxB,IAAQ,EAnBgB,CAoBxB,IAAQ,EApBgB,CAqBxB,EAAQ,EArBgB,CAsBxB,KAAQ,EAtBgB,CAuBxB,IAAQ,EAvBgB,CAwBxB,IAAQ,EAxBgB,CAA5B,CA0BAD,GAA4B,CACxB,KAAQ,CADgB,CAExB,KAAQ,CAFgB,CAGxB,WAAQ,CAHgB,CAIxB,QAAQ,EAJgB,CAKxB,WAAQ,EALgB,CAMxB,WAAQ,EANgB,CAOxB,OAAQ,EAPgB,CAQxB,WAAQ,EARgB,CASxB,OAAQ,EATgB,CAUxB,eAAQ,EAVgB,CAWxB,WAAQ,EAXgB,CAYxB,WAAQ,EAZgB,CAaxB,IAAQ,EAbgB,CAcxB,IAAQ,EAdgB,CAexB,KAAQ,EAfgB,CAgBxB,IAAQ,EAhBgB,CAiBxB,IAAQ,EAjBgB,CAkBxB,IAAQ,EAlBgB,CAmBxB,IAAQ,EAnBgB,CAoBxB,KAAQ,EApBgB,CAqBxB,OAAQ,EArBgB,CAsBxB,EAAQ,EAtBgB,CAuBxB,KAAQ,EAvBgB,CAwBxB,IAAQ,EAxBgB,CAyBxB,IAAQ,EAzBgB,CA1B5B,CAyDA9B,GAAqBhvC,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAiDrBwL;QAjBEgnC,GAiBS,CAAC5E,CAAD,CACX,CAGQ,EAAA,KAAA,CAAA,IAAA,CAAMA,CAAN,CAKA,KAAAzlB,GAAA,CAAa,CAAA,CACb,KAAAxI,GAAA,CAAiB,EAEjB,KAAAmuB,EAAA,CAAa,EACb,KAAAC,EAAA,CAAgB,CAAC,MAAD,CAAK,MAAL,CAChB,KAAAC,GAAA,CAAkB,EASlB,KAAAyE,GAAA,CAAkBC,CAAA,EAClB,KAAAC,EAAA,CAAmBD,CAAA,CAAa,CAAb,CACnB,KAAAE,GAAA,CAAmBF,CAAA,CAAa,CAAb,CACnB,KAAAG,GAAA,CAAuBH,CAAA,CAAa,CAAb,CAcvB,KAAAI,EAAA,CAAoB,EAapB,KAAAC,EAAA,CAAkB,IAAA1tB,EAAlB,CAAoC,IAAAE,EAApC,CAAuD,EACvDytB,GAAA,CAAAA,IAAA,CAcA,KAAAC,EAAA,CARA,IAAAC,GAQA,CAR0B,CAS1B,KAAAC,EAAA,CAA2B,EAC3B,KAAAC,GAAA,CAAmB5wC,IAAAA,EACnB6wC,GAAA,CAAAA,IAAA,CAKA,KAAAzmC,EAAA,CAAW,IACX,KAAA0mC,GAAA,CAAkB,EAClB,KAAA3nC,GAAA,CAAsC,CACtC,KAAA4nC,GAAA,CAAoB,IACpB,KAAAC,EAAA,CAAsB,EACtBC,GAAA,CAAAA,IAAA,CAAiB7F,CAAA,SAAjB,CACA,KAAArlB,GAAA,CAAqBqlB,CAAA,SACrB,KAAAj9B,GAAA,CAAiB,EAMjB,KAAA+iC,EAAA,CAAa,CAEb,KAAAC,GAAA,CADA,IAAAC,GACA,CADqB,IAIrB,KAAAhuB,EAAA,CAAe,IAAAiuB,GAAf,CAAmC,IAAAC,GAAnC,CADA,IAAAC,GACA,CAFA,IAAAC,GAEA,CAFuB,CAWvB,KAAAC,GAAA,CAPA,IAAAn5B,GAOA,CARA,IAAAo5B,EAQA,CARoB,IAmBpB,KAAItnC,EAAM,IACNlI,OAAJ,CACmClC,IAAAA,EADnC,GACQkC,MAAA,CAAO4J,CAAP,CADR,GAEQ5J,MAAA,CAAO4J,CAAP,CAFR,CAEiC,QAAQ,CAAC9P,CAAD,CAAI,CAAE,MAAOiqB,GAAA,CAAA7b,CAAA;AAAepO,CAAf,CAAT,CAF7C,EAKmCgE,IAAAA,EALnC,GAKQ2xC,MAAA,CAAO7lC,CAAP,CALR,GAMQ6lC,MAAA,CAAO7lC,CAAP,CANR,CAMiC,QAAQ,CAAC9P,CAAD,CAAI,CAAE,MAAOiqB,GAAA,CAAA7b,CAAA,CAAepO,CAAf,CAAT,CAN7C,CAlHR,CAlBwB6b,EAAAszB,CAAtB6E,EAAsB7E,CAAAA,EAAAA,CAyJxByG,SAAA,GAAO,CAACC,CAAD,CACP,CACQnzB,CAAAA,CAAOmzB,CAAPnzB,EAAkBmzB,CAAAnzB,EACV,KAAZ,EAAIA,CAAJ,GAAkBA,CAAlB,CA/ieaozB,EA+ieb,CACA,OAAOpzB,EAHX,CAiBAwxB,QAAA,EAAO,CAACxxB,CAAD,CAAcqzB,CAAd,CAAiC1G,CAAjC,CACP,CACI,MAAO,CAAC3sB,EAFJ,IAAA,EAAAA,GAAAA,CAAAA,CAAO,IAAPA,CAAAA,CAEG,CAAaqzB,GAFH,IAAA,EAAAA,GAAAA,CAAAA,CAAY,CAAA,CAAZA,CAAAA,CAEV,CAAmCC,GAAY,CAAA,CAA/C,CAAsD3G,EAAOA,CAA7D,CADX,CAmCA4G,QAAA,GAAO,CAACJ,CAAD,CAAUnzB,CAAV,CAAgBqzB,CAAhB,CAA2B1G,CAA3B,CACP,CACIwG,CAAAnzB,EAAA,CAAeA,CACfmzB,EAAAE,GAAA,CAAoBA,CAApB,EAAiC,CAAA,CACjCF,EAAAG,GAAA,CAAqB,CAAA,CACrBH,EAAAxG,EAAA,CAAgBA,CAJpB,CAiBA6G,QAAA,GAAQ,CAACL,CAAD,CACR,CACI,MAAO,CAACA,CAAAnzB,EAAD,CAAemzB,CAAAE,GAAf,CAAkCF,CAAAG,GAAlC,CAAsDH,CAAAxG,EAAtD,CAAqEwG,CAAA7F,GAArE,CADX,CAaAmG,QAAA,GAAU,CAAVA,CAAU,CAACC,CAAD,CACV,CACI,IAAIP,EAAU3B,CAAA,CAAakC,CAAA,CAAM,CAAN,CAAb,CAAuBA,CAAA,CAAM,CAAN,CAAvB,CAAiCA,CAAA,CAAM,CAAN,CAAjC,CACdP,EAAAG,GAAA,CAAqBI,CAAA,CAAM,CAAN,CACjBA,EAAA,CAAM,CAAN,CAAJ,GACIP,CAAAQ,GADJ,CACoBtG,EAAA,CAAAA,CAAA,CAAkB8F,CAAA7F,GAAlB,CAAiCoG,CAAA,CAAM,CAAN,CAAjC,CADpB,CAGA,OAAOP,EANX,CAkBA,CAAA,CAr1mBJ,EAAAS,UAq1mBInjC;CAAA0J,GAAA,CAAAA,QAAO,CAACtO,CAAD,CAAMD,CAAN,CAAWD,CAAX,CAAgBD,CAAhB,CACP,CACI,IAAAE,EAAA,CAAWA,CACX,KAAAC,EAAA,CAAWA,CACX,KAAAF,EAAA,CAAWA,CACX,KAAAiO,GAAA,CAAa/N,CAAA+N,EACb,KAAA6E,GAAA,CAAiB7S,CAvkbV6S,EA6kbP,EADIo1B,CACJ,CADiD/sB,EAAA,CAAAjb,CAAA,CAAmB,UAAnB,CACjD,GAAe0mC,EAAA,CAAAA,IAAA,CAAiBsB,CAAjB,CAMf,IADIC,CACJ,CADiDhtB,EAAA,CAAAjb,CAAA,CAAmB,UAAnB,CACjD,CAAe,IAAAwb,GAAA,CAAqBysB,CAMpCC,GAAA,CAAAA,IAAA,CAAqCC,QAAkB,CAACC,CAAD,CAAS,CAqVpE,CAAA,CAAA,CA6CoBj1B,IAAAA,EAlYkDtT,CAkYlDE,EAAAoT,EAAAA,CAAqB,EAlYyCi1B,CAkYzC,CAAO,CAAP,CAArBj1B,CA5CFpiB,EAAVojB,CAAUpjB,CAAH,CA4CKoiB,CA5CK/hB,EAAI+qC,CAAAvnC,OAEzB,IAAIyzC,CAAJ,CAAW,CACPl0B,CAAA,CAAOkzB,EAAA,CAAaiB,EAAA,CAzV0CzoC,CAyV1C,CAAewoC,CAAf,CAzV0CxoC,CAyVpBgmC,GAAtB,CAAb,CACP,IAvgfS0B,EAugfT,GAAIpzB,CAAJ,CAAiC,CA1V6BtU,CA2V1DuF,EAAA,CAAa,mBAAb,CAAmCijC,CAAnC,CACA,OAAA,CAF6B,CAIjCt3C,CAAA,CAAIojB,CAAJ,GA9V8DtU,CA8VjDE,EAAA+S,EACb1hB,EAAA,CAAI,CAPG,CAxVuDyO,CAkWlEuF,EAAA,CAAa,sDAAb,CAlWkEvF,EAmWlEuF,EAAA,CAAa,sDAAb,CAEImjC,EAAAA,CAAY,EAChB,KADA,IAAmBC,EAAQ,CAC3B,CAAOp3C,CAAA,EAAP,CAAA,CAAY,CACR,IAAIgiB,EAAQ+oB,CAAA,CAAQprC,CAAR,CACRqiB,EAAArc,KAAJ,EAAkBwxC,CAAlB,CACSC,CAAA,EADT,EAxW8D3oC,CAyW5CuF,EAAA,CAAa,KAAb,CADlB,EAGImjC,CAMA,CANWn1B,CAAArc,KAMX,CALI8L,CAKJ,CALYiS,EAAA,CAAuByzB,CAAvB,CAKZ,CAJIn1B,CAIJ,EAjX0DvT,CA8WtDuF,EAAA,CAAakR,CAAA,CAAUlD,CAAAvU,GAAV,CAAoB,CAApB,CAAb,CAAsC,KAAtC;AAA8CyX,CAAA,CAAUvlB,CAAV,EA9WQ8O,CA8WOE,EAAA+S,EAAf,CAAqC,CAArC,CAA9C,CAAwF,KAAxF,CAAgGwD,CAAA,CAAUlD,CAAAe,EAAV,CAAsB,CAAtB,CAAhG,CAA2H,IAA3H,CAp4lBLmC,CAAA,CAo4lBqJlD,CAAAqB,GAp4lBrJ,CAAa,CAAb,CAAgB,CAAA,CAAhB,CAo4lBK,CAA8J,IAA9J,CAp4lBL6B,CAAA,CAo4lBwLlD,CAAAgB,KAp4lBxL,CAAa,CAAb,CAAgB,CAAA,CAAhB,CAo4lBK,CAAiM,IAAjM,CAAwMvR,CAAxM,CAGJ,CADI0lC,CACJ,EADgBtxB,EAChB,GADuCsxB,CACvC,CADmD,EACnD,EAAAC,CAAA,CAAQ,CATZ,CAWAr0B,EAAA,EAvgccnB,KAwgcdjiB,EAAA,EAdQ,CAjBhB,CArVoE,CAAhE,CAEAiV,GAAA,CAAAA,IAAA,CAzBJ,CAsCApB;CAAAvC,GAAA,CAAAA,QAAU,CAACQ,CAAD,CAAQkC,CAAR,CAAkB/D,CAAlB,CACV,CACI,IAAInB,EAAM,IACV,QAAQkF,CAAR,EAEA,KAAK,YAAL,CAiCI,MA/BA,KAAAoiC,EA+BO,CAhCP,IAAAnoC,EAAA,CAAc+F,CAAd,CAgCO,CAhCmB/D,CAgCnB,CAzBPA,CAAAu9B,UAyBO,CAzBaC,QAA4B,CAACpwB,CAAD,CAAQ,CAEpD,GA5nmBgBuwB,EA4nmBhB,EAAIvwB,CAAAswB,QAAJ,CAAsC,CAClC,IAAA+C,EAAO5hC,CAAAsnC,EAAAh0C,MACP0M,EAAAsnC,EAAAh0C,MAAA,CAAyB,EACzBuoB,GAAA,CAAA7b,CAAA,CAAe4hC,CAAf,CAAqB,CAAA,CAArB,CAHkC,CAAtC,IAKK,IA3nmBW9C,EA2nmBX,EAAIvwB,CAAAswB,QAAJ,CACD7+B,CAAAsnC,EAAAh0C,MAAA,CAAyBsuC,CAAzB,CAAgC,EAD/B,KAUD,IA9nmBY9C,EAwnmBZ,EAAIvwB,CAAAswB,QAAJ,EA38CR+C,CACJ,CADW,IACX,CA28CuB5hC,CA38CnBshC,EAAJ,CA28CuBthC,CA38CHuhC,EAAAxsC,OAApB,CAA4C,CAA5C,GACI6sC,CADJ,CA28CuB5hC,CA18CZuhC,EAAA,CAAe,EA08CHvhC,CA18CKshC,EAAjB,CADX,CA08CY,EArnmBYxC,EAqnmBZ,EAGSvwB,CAAAswB,QAHT,GA59CQ,CAApB,CAg+CuB7+B,CAh+CnBshC,EAAJ,CACIM,CADJ,CAg+CuB5hC,CA/9CZuhC,EAAA,CAAe,EA+9CHvhC,CA/9CKshC,EAAjB,CADX,EAGIM,CACA,CADO,EACP,CA49CmB5hC,CA59CnBshC,EAAA,CAAiB,EAJrB,CA49CY,CAMI,CAAQ,IAAR,EAAAM,CAAJ,CAAkB,CACd,IAAInuC,EAAMmuC,CAAA7sC,OACViL,EAAAsnC,EAAAh0C,MAAA,CAAyBsuC,CACzB5hC,EAAAsnC,EAAAsB,kBAAA,CAAmCn1C,CAAnC,CAAwCA,CAAxC,CAHc,CAMV,IAAZ,EAAImuC,CAAJ,EAAoBrzB,CAAAC,eAApB,EAA0CD,CAAAC,eAAA,EAvBU,CAyBjD,CAAA,CAAA,CAEX,MAAK,YAAL,CAgBI,MAfA,KAAArP,EAAA,CAAc+F,CAAd,CAeO,CAfmB/D,CAenB,CAdP0nC,EAAA,CACI1nC,CADJ,CAGI2nC,QAA0B,EAAU,CAChC,GAAI9oC,CAAAsnC,EAAJ,CAAsB,CAClB,IAAI1F,EAAO5hC,CAAAsnC,EAAAh0C,MACX0M;CAAAsnC,EAAAh0C,MAAA,CAAyB,EACzBuoB,GAAA,CAAA7b,CAAA,CAAe4hC,CAAf,CAAqB,CAAA,CAArB,CACA,OAAO,CAAA,CAJW,CAOtB,MAAO,CAAA,CARyB,CAHxC,CAcO,CAAA,CAAA,CAEX,MAAK,MAAL,CAeI,MAdA,KAAAziC,EAAA,CAAc+F,CAAd,CAcO,CAdmB/D,CAcnB,CAbP0nC,EAAA,CACI1nC,CADJ,CAGI4nC,QAAoB,CAACC,CAAD,CAAU,CAC1B,IAAIC,EAAa,CAAA,CACZ7iC,GAAA,CAAApG,CAAA,CAAW,CAAA,CAAX,CAAL,GACIsG,EAAA,CAAAtG,CAAA,CAAY,CAAA,CAAZ,CAEA,CADAipC,CACA,CADat4B,EAAA,CAAA3Q,CAAA,CAAYgpC,CAAA,CAAS,CAAT,CAAa,CAAzB,CAA4B,IAA5B,CACb,CAAA1iC,EAAA,CAAAtG,CAAA,CAAY,CAAA,CAAZ,CAHJ,CAKA,OAAOipC,EAPmB,CAHlC,CAaO,CAAA,CAAA,CAtEX,CA2EA,MAAO,CAAA,CA7EX,CAsFAvtB,SAAA,GAAQ,CAARA,CAAQ,CACR,CACI,GAAI,CAAA4rB,EAAJ,CAAuB,CAAA,IAMfr1C,EAAI,CANW,CAMRC,EAAI,CACC4F,OAAhB,GACI7F,CACA,CADI6F,MAAAoxC,QACJ,CAAAh3C,CAAA,CAAI4F,MAAAqxC,QAFR,CAKA,EAAA7B,EAAA8B,MAAA,EAEgBtxC,OAAhB,EACIA,MAAAuxC,SAAA,CAAgBp3C,CAAhB,CAAmBC,CAAnB,CAfe,CAD3B,CA6BA6S,CAAAukC,GAAA,CAAAC,QAAO,CAAC9B,CAAD,CAAUh2B,CAAV,CACP,CACI,IAAIzf,EA3yeSmmB,EA2yeb,CACI7D,EAAOkzB,EAAA,CAAaC,CAAb,CApzeEC,GAqzeb,GAAIpzB,CAAJ,GACItiB,CACA,CADIsf,EAAA,CAAA,IAAApR,EAAA,CAAuBoU,CAAvB,CACJ,CAAI7C,CAAJ,EAsJgB,IAtJhB,EAAsBg2B,CAsJtBnzB,EAtJA,GAAsBmzB,CAuJtBnzB,EAvJA,EAA+B7C,CAA/B,EAuJwB,CAvJxB,CAFJ,CAIA,OAAOzf,EAPX,CAkBA+S,EAAAykC,GAAA,CAAAC,QAAO,CAAChC,CAAD,CAAUz1C,CAAV,CAAayf,CAAb,CACP,CACI,IAAI6C,EAAOkzB,EAAA,CAAaC,CAAb,CAt0eEC,GAu0eb,GAAIpzB,CAAJ,GACIlD,EAAA,CAAA,IAAAlR,EAAA,CAAuBoU,CAAvB,CAA6BtiB,CAA7B,CAEA,CADIyf,CACJ,EAmIgB,IAnIhB,EADsBg2B,CAoItBnzB,EAnIA,GADsBmzB,CAqItBnzB,EApIA,EAD+B7C,CAC/B,EAoIwB,CApIxB,EAAAP,CAAA,CAAA,IAAA/Q,EAAA,CAAyB,EAAzB,CAHJ,CAFJ,CAmBA4E;CAAAs9B,GAAA,CAAAA,QAAO,CAACvf,CAAD,CAAMD,CAAN,CACP,CAKc,CAAV,CAAIC,CAAJ,GAAaA,CAAb,EAAoBhR,CAApB,CACU,EAAV,CAAI+Q,CAAJ,GAAaA,CAAb,EAAoB/Q,CAApB,CACI6V,EAAAA,CAASyD,EAAAvmB,KAAA,CAAiB,IAAA5E,EAAjB,CAA2B6iB,CAA3B,CAAgCD,CAAhC,CAAqC,CAAA,CAArC,CAA4C,CAAA,CAA5C,CACT8E,EAAJ,EAAcjD,CAAd,GAA+BiD,CAA/B,EAAyC7V,CAAzC,CASA,OAAO6V,EAjBX,CAmCA8gB;QAAA,GAAS,CAATA,CAAS,CAACD,CAAD,CAAQf,CAAR,CACT,CAAA,IACmBxG,CACVwG,EAAL,GAAcA,CAAd,CAAwB3B,CAAA,EAAxB,CACA,KAAIxxB,EAAOmzB,CAAAnzB,EACX,IAAc1e,IAAAA,EAAd,GAAI4yC,CAAJ,CAAyB,CAx6B7B,CAAA,CAAA,CAEQkB,CAAAA,CAu6BQC,CAv6BCxI,EAAA,CAAc,CAAd,CACb,KAAIyI,EAs6BQD,CAt6BExI,EAAA,CAAc,CAAd,CACV0I,KAAAA,EAAsB,GAAX,EAACH,CAAD,EAA4B,GAA5B,EAAkBA,CAAlB,EAA6C,GAA7C,EAAmCA,CAAnC,CAAmD,IAAnD,CAA0D,EACzE,KAAII,EAA2B,GAAV,EAAAJ,CAAA,CAAe,IAAf,CAAsB,EAE3C,KADIK,CACJ,CADe,IAAIrmC,MAAJ,CAAWmmC,CAAX,CAAsBH,CAAtB,CAA+B,KAA/B,CAAuCI,CAAvC,CAAuDJ,CAAvD,CAAgEI,CAAhE,CAAgFF,CAAhF,CAA0F,KAA1F,CAAkGC,CAAlG,CAA6GD,CAA7G,CACf,CAAOl5C,CAAP,CAAWkB,CAAAqB,MAAA,CAAQ82C,CAAR,CAAX,CAAA,CAA8B,CAC1B,IAAIz2C,EAAQixC,EAAA,CAi6BJoF,CAj6BI,CAAqBj5C,CAAA,CAAE,CAAF,CAArB,CACZ,IAAckF,IAAAA,EAAd,GAAItC,CAAJ,CAAyB,CAAA,CAAA,CAAA,IAAA,EAAA,OAAA,CAAA,CAazB1B,CAAA,CAAIA,CAAAc,QAAA,CAZUg3C,CAYV,CAZmBh5C,CAAA,CAAE,CAAF,CAYnB,CAZ0Bk5C,CAY1B,CAXoB,IAATI,EAAA12C,CAAA02C,CAAezzB,CAAA,CA85BtBozB,CA95BsB,CAAer2C,CAAf,CAAf02C,CAAuC,WAWlD,CAfsB,CAiB9B,GAi5BYL,CAj5BRvI,GAAArsC,OAAJ,CAMI,IALA20C,CAIA,CA44BQC,CAh5BCvI,GAAA,CAAgB,CAAhB,CAIT,CAHAwI,CAGA,CA44BQD,CA/4BEvI,GAAA,CAAgB,CAAhB,CAGV,CAFAyI,CAEA,CAFsB,GAAX,EAACH,CAAD,EAA4B,GAA5B,EAAkBA,CAAlB,EAA6C,GAA7C,EAAmCA,CAAnC,CAAmD,IAAnD,CAA0D,EAErE,CADAI,CACA,CAD2B,GAAV,EAAAJ,CAAA,CAAe,IAAf,CAAsB,EACvC,CAAAK,CAAA,CAAW,IAAIrmC,MAAJ,CAAWmmC,CAAX,CAAsBH,CAAtB,CAA+B,KAA/B,CAAuCI,CAAvC,CAAuDJ,CAAvD,CAAgEI,CAAhE,CAAgFF,CAAhF,CAA0F,KAA1F,CAAkGC,CAAlG,CAA6GD,CAA7G,CACX,CAAOl5C,CAAP,CAAWkB,CAAAqB,MAAA,CAAQ82C,CAAR,CAAX,CAAA,CACIn4C,CAAA,CAA4BA,CA5wB7Bc,QAAA,CAAU,GAAV,CA4wBgChC,CAAA83C,CAAE,CAAFA,CA5wBhC,CAAwB,GAAxB,CAA6B,eAA7B,CAgyBP,KAAA,CAAO93C,CAAP,CAAWkB,CAAAqB,MAAA,CAAQ,aAAR,CAAX,CAAA,CAAmC,CAC3BlB,CAAAA;AAAI,IACR,QAAOrB,CAAA,CAAE,CAAF,CAAAkE,YAAA,EAAP,EACA,KAAK,KAAL,CACI7C,CAAA,CAAI,CAFR,CAKA,GAAS,IAAT,EAAIA,CAAJ,CAAe,KACfH,EAAA,CAAIA,CAAAc,QAAA,CAAUhC,CAAA,CAAE,CAAF,CAAV,CAAgBqB,CAAAiT,SAAA,EAAhB,CAR2B,CAnDvC,CA26BQ,GAAU,GAAV,EADSwjC,CAAA51C,OAAAD,CAAa,CAAbA,CACT,CAAe,CACX,IAAAg1C,EAAY,CAAA,CACZa,EAAA,CAAQA,CAAA31C,OAAA,CAAa,CAAb,CAFG,CAIf,IAAIo3C,CAAiCzB,EAAAA,CAAAA,CAk7DzC,IAAI0B,CAAAj3C,MAAA,CAAc,qBAAd,CAAJ,CAEI,IADIk3C,CACKC,CADQF,CAAAG,YAAA,EACRD,CAAAA,CAAAA,CAAS,CAAlB,CAAqBA,CAArB,CAp7DiBE,CAo7DapE,EAAAnxC,OAA9B,CAAwDq1C,CAAA,EAAxD,CAGI,GADIG,CACA,CAv7DSD,CAq7DKpE,EAAAsE,CAAkBJ,CAAlBI,CACLtxC,EAAA,CAAqBixC,CAArB,CACT,CAAU,IAAV,EAAAI,CAAJ,CAAoB,CAChB,IAAAE,EAAYF,CAAA,EAUZ,MAXgB,CAeX,IAAjB,EAAIE,CAAJ,GACIhD,CADJ,CACc3B,CAAA,CAAa2E,CAAb,CADd,CAr8DI,IAAIR,CAAJ,CAAgB,MAAOA,EACI,EAA3B,EAAIzB,CAAA/1C,QAAA,CAAc,IAAd,CAAJ,CACIwuC,CADJ,CACY,EADZ,CAEkC,CAA3B,EAAIuH,CAAA/1C,QAAA,CAAc,IAAd,CAAJ,CACHwuC,CADG,CACK,CADL,CAE0B,CAF1B,EAEIuH,CAAA/1C,QAAA,CAAc,GAAd,CAFJ,GAGHwuC,CAHG,CAGK,EAHL,CAKP3sB,EAAA,CAAOiwB,EAAA,CAAAA,CAAA,CAAqBiE,CAArB,CAhBc,CAkBb,IAAZ,EAAIl0B,CAAJ,GACIA,CACA,CADOo2B,EAAA,CAAkBp2B,CAAlB,CAAwB,CAAAvB,GAAxB,CACP,CAAA80B,EAAA,CAAaJ,CAAb,CAAsBnzB,CAAtB,CAA4BqzB,CAA5B,CAAuC1G,CAAvC,CAFJ,CAIA,OAAOwG,EA1BX;AAoCAkD,QAAA,GAAgB,CAAhBA,CAAgB,CAAClD,CAAD,CAAUmD,CAAV,CAChB,CACQA,CAAJ,GACQl6C,CADR,CACYk6C,CAAA33C,MAAA,CAAe,eAAf,CADZ,IAGQw0C,CAAAQ,GAHR,CAGwBtG,EAAA,CAAAA,CAAA,CAAkB8F,CAAA7F,GAAlB,CAAiClxC,CAAA,CAAE,CAAF,CAAjC,CAHxB,CADJ,CAiBAg6C,QAAA,GAAY,CAAC14C,CAAD,CAAIu6B,CAAJ,CACZ,CAMY,CAAR,CAAIv6B,CAAJ,EAAaA,CAAb,EAAkB,CAAC0yB,CAAnB,GACI1yB,CADJ,EACS8f,CADT,CAOA,OAJY3e,KAAAE,MAAA,CAAWF,IAAAe,IAAA,CAASlC,CAAT,CAAX,CAIZ,CAJsCmB,IAAAC,IAAA,CAAS,CAAT,CAV1B,IAAA,EAAAm5B,GAAAA,CAAAA,CAAO,EAAPA,CAAAA,CAU0B,CAT1C,CA6DAse,QAAA,GAAS,CAATA,CAAS,CAAC74C,CAAD,CACT,CAKI,MAAOukB,EAAA,CAAAA,CAAA,CAAevkB,CAAf,CAAmB6uB,EAAnB,CAAqC,EAArC,CAAP,CAAkD,GAAlD,CAAwDtK,CAAA,CAAAA,CAAA,CAAevkB,CAAf,CAAmB6uB,EAAnB,CAAqC,EAArC,CAL5D;AAkMAgmB,QAAA,GAAW,CAAXA,CAAW,CAACiE,CAAD,CACX,CACI,CAAA9qC,EAAA,CAAW,CACX,EAAAjB,GAAA,CAAsC,SACtC,EAAA4nC,GAAA,CAAoB,IACpB,EAAAC,EAAA,CAAsB,EAKlBmE,EAAAA,CAAUpJ,EAAA,CAAAA,CAAA,CAAkBmJ,CAAAp4C,QAAA,CAAgB,MAAhB,CAAuB,KAAvB,CAAAA,QAAA,CAAsC,KAAtC,CAA4C,UAA5C,CAAlB,CAA2E,CAAA,CAA3E,CAAkF,GAAlF,CACd,IAAIq4C,CAAAh2C,OAAJ,CACI,IAAKzD,IAAIA,CAAT,GAAc4Y,GAAd,CAAwC,CAzzkBhD,CAAA,CAAA,CADqBhZ,IAAAA,EAAAA,IAAAA,EAEjB,IAAIyI,KAAArE,UAAA7C,QAAJ,CACI,CAAA,CAwzkBoBs4C,CAxzkBbt4C,QAAA,CAwzkBsBnB,CAxzkBtB,CAAaJ,CAAb,CADX,KAAA,CAGAA,CAAA,CAAIA,CAAJ,EAAS,CACD,EAAR,CAAIA,CAAJ,GAAWA,CAAX,EAqzkBwB65C,CArzkBRh2C,OAAhB,CACQ,EAAR,CAAI7D,CAAJ,GAAWA,CAAX,CAAe,CAAf,CACA,KAAK,IAAIK,EAmzkBew5C,CAnzkBXh2C,OAAb,CAAuB7D,CAAvB,CAA2BK,CAA3B,CAA8BL,CAAA,EAA9B,CACI,GAAIA,CAAJ,GAkzkBoB65C,EAlzkBpB,EAkzkBoBA,CAlzkBN,CAAE75C,CAAF,CAAd,GAkzkB6BI,CAlzkB7B,CAA0B,MAAA,CAE9B,EAAA,CAAQ,EATR,CADJ,CA0zkB2C,CAA/B,EAAI,CAAJ,GACI,CAAAyN,GACA,EADoBmL,EAAA,CAAyB5Y,CAAzB,CACpB,CAAA,CAAAiU,EAAA,CAAajU,CAAb,CAAiB,mBAAjB,CAFJ,CADoC,CAXhD,CA4BA+2C,QAAA,GAAW,CAAXA,CAAW,CAAa2C,CAAb,CACX,CACI,IAAK15C,IAAIA,CAAT,GAAc4Y,GAAd,CACI,GAnhfIK,EAmhfJ,EAAkBL,EAAA,CAAyB5Y,CAAzB,CAAlB,CAA+C,CAC3C,CAAAo1C,GAAA,CAAgBp1C,CAAhB,CAAA,CAAqB05C,CACrB,MAF2C,CAFvD,CAkBAjmC,CAAA08B,GAAA,CAAAA,QAAW,CAACwJ,CAAD,CACX,CACI,MAAOC,GAAAz4C,QAAA,CAA+Bw4C,CAAAZ,YAAA,EAA/B,CADX,CAuBAtlC;CAAA28B,GAAA,CAAAA,QAAW,CAACoD,CAAD,CACX,CACI,IACI7kC,EAAM,IAAAA,EACV,QAAO6kC,CAAP,EACA,KAAKqG,EAAL,CACI,IAAA73C,EAAQ2M,CA/0WL8R,EAg1WH,MACJ,MAAKq5B,EAAL,CACI93C,CAAA,CAAQ2M,CAAAkf,EACR,MACJ,MAAKksB,EAAL,CACI/3C,CAAA,CAAQ2M,CAAAif,EACR,MACJ,MAAKosB,EAAL,CACIh4C,CAAA,CAAQ2M,CAn+WJuf,EAm+WJ,CAn+WiBwD,CAo+WjB,MACJ,MAAKuoB,EAAL,CACIj4C,CAAA,CAAS2M,CAAAuf,EAAD,CApqfAkB,MAoqfA,CAAiC,CAAjC,CAAqC,CAC7C,MACJ,MAAK8qB,EAAL,CACIl4C,CAAA,CAAS2M,CAAAuf,EAAD,CAtqfAkB,KAsqfA,CAAiC,CAAjC,CAAqC,CAC7C,MACJ,MAAK+qB,EAAL,CACIn4C,CAAA,CAAS2M,CAAAuf,EAAD,CAxqfAkB,KAwqfA,CAAiC,CAAjC,CAAqC,CAC7C,MACJ,MAAKgrB,EAAL,CACIp4C,CAAA,CAAS2M,CAAAuf,EAAD,CAzqfAkB,IAyqfA,CAAgC,CAAhC,CAAoC,CAC5C,MACJ,MAAKirB,EAAL,CACIr4C,CAAA,CAAS2M,CAAAuf,EAAD,CAxqfAkB,EAwqfA,CAAgC,CAAhC,CAAoC,CAC5C,MACJ,MAAKkrB,EAAL,CACIt4C,CAAA,CAAS2M,CAAAuf,EAAD,CAtqfDkB,MAsqfC,CAAiC,CAAjC,CAAqC,CA7BjD,CAgCA,MAAOptB,EAnCX,CA2GAyR;CAAAjL,QAAA,CAAAA,QAAO,CAAC8G,CAAD,CAAWmG,CAAX,CACP,CACQA,CAAJ,GACInG,CADJ,EACgB,IADhB,CA/YO2V,CAAA,CAgZgBs1B,IAhZhB,CAgZ+B/F,CAAA2B,CAAa,IAAAxnC,EAr5W5Cmf,GAq5W+BqoB,CApYdnzB,EAZjB,CAAoB,EAApB,CA+YP,CAIA,IAAIqyB,CAAA,IAAAA,GAAJ,EAAyB/lC,CAAzB,EAAqC,IAAA+lC,GAArC,CAGA,GAFA,IAAAA,GAEI,CAFgB/lC,CAEhB,CAAA,IAAA7B,GAAA,CA/pfIyM,UA+pfR,CACI,IAAAo7B,EAAAzsC,KAAA,CAAyByG,CAAzB,CADJ,KAAA,CAKA,IAAIkrC,CACJ,IAAK,IAAA/sC,GAAL,CApqfQ0M,WAoqfR,EAA+C,IAAAxL,EAA/C,GAA4D6rC,CAA5D,CAAuE,IAAA7rC,EAvzZhEX,MAAA+Q,EAuzZP,GAAgGjK,EAAA,CAAAA,IAAA,CAAY,CAAA,CAAZ,CAAhG,CACIsK,EAAA,CAAAA,IAAA,CACA,CAAIo7B,CAAJ,GAAclrC,CAAd,EAA0B,eAA1B,CAGJ,KAAA2E,EAAA,CAAa3E,CAAb,CAUI,KAAAX,EAAJ,GAAcA,CAnqZd,CAmqZcA,IAAAA,EAnqZd,CAkuBAod,EAAA,CAAAA,CAAA,CAluBA,CAmuBA,CAAA5D,GAnuBA,CAmuBwB,CAnuBxB,CAyuBAvI,CAzuBI/Q,EAAJ,EAAc+Q,CAAA,CAyuBdA,CAzuBc/Q,EAAA,CAFHud,IAAAA,EAEG,CAmqZd,CArBA,CARJ,CAgEA+oB;QAAA,GAAW,CAAXA,CAAW,CACX,CACI,IAAIv1C,CACJ,IAAI,CAAC+vB,EAAA,CAAAA,CAAA,CAAL,CACQ,CAAAslB,EAIJ,EAJgC,CAAAA,EAAAxxC,OAIhC,EAHI,CAAAwQ,EAAA,CAAa,kCAAb,CAGJ,CADA,CAAA8gC,EACA,CAD2B,CAC3B,CAAA,CAAAE,EAAA,CAA2B,EAL/B,KAQA,IAAI,CAAC,CAAAA,EAAL,EAAiC,CAAC,CAAAA,EAAAxxC,OAAlC,CAAmE,CAC/D,CAAAwxC,EAAA,CAA+B5sC,KAAJ,CAAUoyC,EAAV,CAC3B,KAAK76C,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB,CAAAq1C,EAAAxxC,OAAhB,CAAiD7D,CAAA,EAAjD,CAKI,CAAAq1C,EAAA,CAAyBr1C,CAAzB,CAAA,CAA8B40C,CAAA,EAElC,EAAAO,EAAA,CAA2B,CAEvB,EAAA9gC,EAAA,CAAa,sCAAb,CAX2D,CAVvE,CAkCAkL,QAAA,GAAQ,CAARA,CAAQ,CAACqM,CAAD,CAAe0nB,CAAf,CACR,CACI,GAAI,CAACwH,EAAA,CAAAA,CAAA,CAAcxH,CAAd,CAAL,CAA4B,MAAO,CAAA,CACnC/zB,GAAA,CAAA,CAAAxQ,EAAA,CAAkB6c,CAAlB,CACA,OAAO,CAAA,CAHX;AAeAnM,QAAA,GAAO,CAAPA,CAAO,CAACqI,CAAD,CAAUizB,CAAV,CAAiBC,CAAjB,CACP,CACI,GAAI,CAACF,EAAA,CAAAA,CAAA,CAAL,CAAsB,MAAO,CAAA,CAE7B,KAAIpK,EAAO,EACG,KAAd,GAAIqK,CAAJ,GAEIrK,CAFJ,CAEW,CADPqK,CACO,CADE,CAAC,CAAAjF,GACH,EAD+C,IAC/C,EADyB,CAAAA,GACzB,EAAO,IAAP,CAAc,GAFzB,CAKA,EAAAhuB,EAAA,CAAe,CAEVA,EAAL,EAMQiI,EAAA,CAAAA,CAAA,CANR,EAM8BG,EAAA,CAAAA,CAAA,CAAsB,CAAAnhB,EA3jX7C8R,EA2jXuB,CAAwC,CAAxC,CAK9B,IAAI,CACAiH,CAAA,CAAUkE,EAAA,CAAA,CAAAjd,EAAA,CAAwB+Y,CAAxB,CACV,KAAIpI,EAAc,CAAA3Q,EAAA0Q,GAAA,CAAiBqI,CAAjB,CACA,EAAlB,CAAIpI,CAAJ,GACIC,EAAA,CAAA,CAAA5Q,EAAA,CAAsB2Q,CAAtB,CAIA,CAHA,CAAAoI,EAGA,EAHgBpI,CAGhB,CAFAE,EAAA,CAAA,CAAA7Q,EAAA,CAAmB2Q,CAAnB,CAAgC,CAAA,CAAhC,CAEA,CADAG,EAAA,CAAA,CAAA9Q,EAAA,CAAwB2Q,CAAxB,CACA,CAAA,CAAAu2B,GAAA,EALJ,CAHA,CAWJ,MAAMn2B,CAAN,CAAiB,CAKW,QAAxB,EAAI,MAAOA,EAAX,GACQlgB,CAEJ,CAFQkgB,CAER,CADA,CAAAgI,EACA,CADe,CACf,CAAAhT,EAAA,CAAA,CAAA/F,EAAA,CAAkBnP,CAAAmgB,MAAlB,EAA6BngB,CAAAgJ,QAA7B,CAHJ,CALa,CAiBO,CAAA,CAAxB,GAAIoyC,CAAJ,GACQ,CAAAh+B,GACJ,EADgB,CAAAA,GAAAL,KAAA,EAChB,CAAAqD,CAAA,CAAA,CAAA/Q,EAAA,CAAyB,EAAzB,CAFJ,CAKAqb,GAAA,CAAAA,CAAA,CAAkBywB,CAAlB,EAA2B,CAAA,CAA3B,CAAkCrK,CAAlC,CACA,OAAuB,EAAvB,CAAQ,CAAA5oB,EAxDZ,CAiEAtI,QAAA,GAAO,CAAPA,CAAO,CAACuN,CAAD,CACP,CACQ,CAAAhe,EAAJ,EAAcyQ,CAAA,CAAA,CAAAzQ,EAAA,CAAiBge,CAAjB,CADlB,CAWAzC,QAAA,GAAY,CAAZA,CAAY,CAACywB,CAAD,CAAerK,CAAf,CACZ,CADaqK,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAQ,CAAA,CAAR,CAAAA,CAEJ,EAAA1wB,GAAL,GAEIqmB,CAWJ,EAVI,CAAAr8B,EAAA,CAAa4mC,EAAb,CAAoCvK,CAApC,CAUJ,CAPAiG,EAAA,CAAa,CAAA9B,EAAb,CAA+B,CAAA9lC,EA/nXxB8R,EA+nXP,CAOA,CAAKk6B,CAAL,EAA4B,CAA5B,EAAc,CAAAnF,EAAd,CAGIsF,EAAA,CAAAA,CAAA,CAHJ,CACIC,EAAA,CAAAA,CAAA,CAdJ,CADJ;AA8BAL,QAAA,GAAQ,CAARA,CAAQ,CAACxH,CAAD,CACR,CACQ,IAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,EAAA,EAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,IAAoC,CAAA,CAAA,CAAA,EAAA,CA1hanC,CAAAllC,MAAAK,EAAL,CAIA,CAJA,CAIO,CAAA,CAJP,EACI,CAAA4F,EAAA,CAAa,CAAAP,SAAA,EAAb,CAA+B,cAA/B,CACA,CAAA,CAAA,CAAO,CAAA,CAFX,CA0hawC,CAAA,CAAA,CAAA,CAAA,CAApC,CAAJ,OAAI,EAAJ,EAAiE,CAAA/E,EA3ga1DX,MAAA+Q,EA2gaP,EACSm0B,CACE,EADM,CAAAj/B,EAAA,CAAa,0CAAb,CACN,CAAA,CAAA,CAFX,EAIO,CAACU,EAAA,CAAA,CAAAhG,EAAA,CALZ,CAgBA8E,CAAAyB,GAAA,CAAAA,QAAO,CAACjN,CAAD,CAAOqV,CAAP,CACP,CACI,MAAI,CAACA,CAAL,GAMI,IAAAjB,MAAA,CAAW,CAAA,CAAX,CAIIpU,CAAAA,CAVR,EAWe,IAAAuV,QAAA,CAAavV,CAAb,CAXf,CAcO,CAAA,CAfX,CA0BAwL,EAAA0B,GAAA,CAAAA,QAAS,CAACC,CAAD,CAAQC,CAAR,CACT,CACQA,CAAJ,EAAe,IAAApB,EAAA,CAAamB,CAAA,CAAO,YAAP,CAAsB,eAAnC,CACf,OAAOA,EAAA,CAAO,IAAAqI,KAAA,EAAP,CAAqB,CAAA,CAFhC,CAaAhK,EAAA4I,MAAA,CAAAA,QAAK,CAAC62B,CAAD,CACL,CACIiC,EAAA,CAAAA,IAAA,CACA,KAAAU,GAAA,CAA+C,CAC/C,KAAAR,GAAA,CAAoB,IACpB,KAAA3tB,EAAA,CAAe,CACf6uB,GAAA,CAAa,IAAA9B,EAAb,CAA+B,IAAA9lC,EAttXxB8R,EAstXP,CAMA,KAAAzS,MAAA+Q,EAAA,CAAqB,CAAA,CACrBi8B,GAAA,CAAAA,IAAA,CACK9H,EAAL,EAAahpB,EAAA,CAAAA,IAAA,CAbjB,CAwBAzW;CAAAgK,KAAA,CAAAA,QAAI,EACJ,CACI,IAAIC,EAAQ,IAAIC,CAAJ,CAAU,IAAV,CACZD,EAAAE,IAAA,CAAU,CAAV,CAAa44B,EAAA,CAAc,IAAA/B,EAAd,CAAb,CACA/2B,EAAAE,IAAA,CAAU,CAAV,CAAa44B,EAAA,CAAc,IAAA9B,GAAd,CAAb,CACAh3B,EAAAE,IAAA,CAAU,CAAV,CAAa44B,EAAA,CAAc,IAAA7B,GAAd,CAAb,CACAj3B,EAAAE,IAAA,CAAU,CAAV,CAAa,CAAC,IAAAqyB,EAAD,CAAiB,IAAAF,EAAjB,CAAiC,IAAAtiC,GAAjC,CAAb,CACAiQ,EAAAE,IAAA,CAAU,CAAV,CAAa,IAAAg3B,EAAb,CACA,OAAOl3B,EAAAzV,KAAA,EAPX,CAmBAwL,EAAA+J,QAAA,CAAAA,QAAO,CAACvV,CAAD,CACP,CACI,IAAIrI,EAAI,CACQ0E,KAAAA,EAAhB,GAAI2D,CAAA,CAAK,CAAL,CAAJ,GACI,IAAAwsC,EAMA,CANmBgC,EAAA,CAAAA,IAAA,CAAgBxuC,CAAA,CAAKrI,CAAA,EAAL,CAAhB,CAMnB,CALA,IAAA80C,GAKA,CALmB+B,EAAA,CAAAA,IAAA,CAAgBxuC,CAAA,CAAKrI,CAAA,EAAL,CAAhB,CAKnB,CAJA,IAAA+0C,GAIA,CAJuB8B,EAAA,CAAAA,IAAA,CAAgBxuC,CAAA,CAAKrI,CAAA,EAAL,CAAhB,CAIvB,CAHA,IAAAqwC,EAGA,CAHiBhoC,CAAA,CAAKrI,CAAL,CAAA,CAAQ,CAAR,CAGjB,CAF6B,QAE7B,EAFI,MAAO,KAAAqwC,EAEX,GAFuC,IAAAA,EAEvC,CAFwD,CAAC,IAAAA,EAAD,CAExD,EADA,IAAAF,EACA,CADiB9nC,CAAA,CAAKrI,CAAL,CAAA,CAAQ,CAAR,CACjB,CAAA,IAAA6N,GAAA,EAAoBxF,CAAA,CAAKrI,CAAL,CAAA,CAAQ,CAAR,CAPxB,CASIqI,EAAA,CAAK,CAAL,CAAJ,GAAa,IAAA2sC,EAAb,CAAiC3sC,CAAA,CAAK,CAAL,CAAjC,CACA,OAAO,CAAA,CAZX,CAwBAwL,EAAA8C,MAAA,CAAAA,QAAK,CAACrL,CAAD,CAAKwc,CAAL,CACL,CACS,IAAA8tB,EAAL,EAAiB,IAAAvhC,EAAA,CAAa,SAAb,CACjB,KAAAjG,MAAA+Q,EAAA,CAAqB,CAAA,CACrB,KAAA62B,GAAA,CAAe1qC,CACf,KAAAyqC,GAAA,CAAoBjuB,CAJxB,CAgBAjU;CAAA8I,KAAA,CAAAA,QAAI,CAACrR,CAAD,CAAKwc,CAAL,CACJ,CACI,GAAI,IAAA1Z,MAAA+Q,EAAJ,CAAwB,CACpB,IAAA/Q,MAAA+Q,EAAA,CAAqB,CAAA,CACrB,KAAA2I,EAAA,CAAeA,CAAf,CAAyB,IAAAiuB,GACzB,IAAI,CAAC,IAAAH,EAAL,CAAiB,CACTyF,CAAAA,CAAW,SACf,IAAI,IAAAvzB,EAAJ,CAAkB,CACAxc,CAAVgwC,EAAe,IAAAtF,GACnB,KAAIhuB,EAA8B,CAAV,CAAAszB,CAAA,CAAar5C,IAAAkmB,MAAA,CAA0B,GAA1B,CAAW,IAAAL,EAAX,CAAiCwzB,CAAjC,CAAb,CAAyD,CACjFD,EAAA,EAAY,IACRtrB,GAAA,CAAAA,IAAA,CAAJ,GACIsrB,CAOA,EAPY,IAAApF,GAOZ,CAPiC,iBAOjC,CAAA,IAAAA,GAAA,CAAqB,CARzB,CAUAoF,EAAA,EAAY,IAAAvzB,EAAZ,CAA2B,WAA3B,CAAyCwzB,CAAzC,CAAmD,OAAnD,CAA6DtzB,CAA7D,CAAgF,MAdlE,CAAlB,IAgBQtS,GAAA,CAAAA,IAAA,CA9hgBR6E,WA8hgBQ,CAAJ,GAMI8gC,CANJ,EAMgB,kDANhB,CASJ,KAAAhnC,EAAA,CAAagnC,CAAb,CA3Ba,CA6BjB/wB,EAAA,CAAAA,IAAA,CAAkB,CAAA,CAAlB,CACAE,GAAA,CAAAA,IAAA,CACA4wB,GAAA,CAAAA,IAAA,CAAyB,IAAArsC,EA30XtB8R,EA20XH,CACA,KAAA40B,GAAA,CAAoB,IAnCA,CAD5B,CAsDA1lB,SAAA,GAAa,CAAbA,CAAa,CACb,CACI,MAA+D,EAA/D,CAAsC,CAAAklB,EAAApxC,OAAtC,EAAoE,CAAC,CAAC,CAAAuxC,GAD1E;AAeAllB,QAAA,GAAgB,CAAhBA,CAAgB,CAAC9M,CAAD,CAAOm4B,CAAP,CAChB,CACI,IAAIC,EAAU,EAQTD,EAAL,GACIC,CACA,CADS,CAAAzsC,EAAAsR,EAAA,CAAkB+C,CAAlB,CACT,CA3tgBQzK,IA2tgBR,EAAK6iC,CAAL,EAvugBQ7iC,EAuugBR,EAA6D,CAAA5J,EAv1X1Dmf,GAu1XH,EAAqF9K,CAArF,GACIA,CADJ,CACWqM,EAAA,CAAA,CAAA1gB,EAAA,CAAmB,CAAnB,CADX,CAFJ,CAUA,IAAa,CAAb,CAAIwsC,CAAJ,GACQ,CAAAnG,GADR,EAEY,CAAC,EAAE,CAAAA,GAFf,EAIQ/tB,EAAA,CAAAA,CAAA,CAAqBjE,CAArB,CAA2B,CAA3B,CAA8B,CAAA6xB,EAA9B,CAJR,EAKQ,MAAO,CAAA,CAUD,EAAd,EAAIsG,CAAJ,EAAmB,CAAAlG,EAAAxxC,OAAnB,GACI,CAAAoyC,GAAA,EAIA,CAHa,CAGb,CAHIuF,CAGJ,GAFIA,CAEJ,CAFa,CAAAzsC,EAAAsR,EAAA,CAAkB+C,CAAlB,CAEb,EAAc,CAAd,EAAIo4B,CAAJ,GAEI7E,EAAA,CADc,CAAAtB,EAAAkB,CAAyB,CAAApB,EAAzBoB,CACd,CAAsBnzB,CAAtB,CAEA,CAAI,EAAE,CAAA+xB,EAAN,EAAkC,CAAAE,EAAAxxC,OAAlC,GAAmE,CAAAsxC,EAAnE,CAA8F,CAA9F,CAJJ,CALJ,CAYA,OAAO,CAAA,CA9CX;AA4IAsG,QAAA,GAAc,CAAdA,CAAc,CAAClF,CAAD,CAAUmF,CAAV,CAAoBC,CAApB,CACd,CACI,IAAIC,EAAYhH,CAAA,CAAa2B,CAAAnzB,EAAb,CAAhB,CACIo4B,EAAS,CAAAnD,GAAA,CAAa9B,CAAb,CAAsB,CAAtB,CADb,CAnFIsF,CAmFJ,CAnF2BC,EAAQ,CAmFnC,CAlFIvrB,EAoFkCirB,CApFlCjrB,CAAewrB,EAAfxrB,CAAsC,CAkF1C,CAhFS/P,CAAT,KAASA,CAAT,GAAiBw7B,GAAjB,CAGI,GADAH,CACA,CAFcG,EAAAC,CAAsBz7B,CAAtBy7B,CACN,CAAQ1rB,CAAR,CAAa/P,CAAb,CACR,CAAW,CACP,IAAA07B,EAAS,CAAC17B,CAMV+P,EAAA,GAAO,CACP,QAAO2rB,CAAP,EACA,KAnzgBIvjC,KAmzgBJ,CACI,IAAAwjC,EAASC,EACTN,EAAA,CAASvrB,CAAT,CAAc,CACd,MACJ,MAtzgBI5X,KAszgBJ,CACIwjC,CAAA,CAASE,EACTP,EAAA,CAASvrB,CAAT,CAAc,CACd,MACJ,MAzzgBI5X,KAyzgBJ,CACIwjC,CACA,CADSG,EACT,CAAAR,CAAA,EAAUvrB,CAAV,CAAe,EAAf,GAAwB,CAAxB,EAA+BA,CAA/B,CAAoC,CAApC,GAA4C,CAXhD,CAcA,KAtBO,CA0BXgsB,CAAAA,CAAQJ,CAARI,EAAkBJ,CAAA,CAAOL,CAAP,CAAlBS,EAAmC,EAC1B,IAAb,EAAIA,CAAJ,EAAoBV,CAApB,CAA4BW,EAA5B,GAAoDD,CAApD,CAA4D,GAA5D,CACIE,EAAAA,CAAaC,EAAA,CAAsBb,CAAtB,EAA+B,CAA/B,CAAbY,CAAiDF,CAKjD,IAAKV,CAAL,CAEO,CAEH,GA50gBIljC,KA40gBJ,EAAIujC,CAAJ,CACI77C,CACA,CAwC0Bm7C,CAxC1B,CADcmB,EACd,CA10gBAhkC,GA00gBA,CAAAikC,CAAA,CAAWv3B,CAAA,CAwCNw3B,CAxCM,CAAex8C,CAAf,CAAmB,EAAnB,CAFf,KAMI,KAFAA,CAESD,CAoCiBo7C,CApCjBp7C,EAx0gBTuY,EAw0gBSvY,CAv0gBTuY,EAu0gBSvY,CADTw8C,CACSx8C,CADEilB,CAAA,CAqCNw3B,CArCM,CAAex8C,CAAf,CAAmB,EAAnB,CACFD,CAAAA,CAAAA,CAAI,CAAb,CAAgBw8C,CAAhB,EAA4Bx8C,CAA5B,CAAgC08C,EAAAj5C,OAAhC,CAA6DzD,CAAA,EAA7D,CACI,GAAIy7C,CAAJ,EAAakB,EAAA,CAAqB38C,CAArB,CAAA,CAAwB,CAAxB,CAAb,GACQ48C,CADR,CACgBD,EAAA,CAAqB38C,CAArB,CAAA,CAAwBC,CAAxB,CADhB,EAEe,CACPo8C,CAAA,CAAaC,EAAA,CAAsBM,CAAtB,CACbJ,EAAA,CAAW,EACX,MAHO,CAQvBH,CAAA,CAAaQ,EAAA,CAAQR,CAAR,CAAoB,CAApB,CAAb,EAAuCG,CAAA,CAAUA,CAAV,CAAqB,GAArB,CAA2B,EAAlE,CAyB8BpB,EAxB9B,CAj1gBI7iC,OAi1gBJ,GAAmC8jC,CAAnC,EAAiD,GAAjD,CACAA,EAAA,EAAcp3B,CAAA,CAuBLw3B,CAvBK,CAuBgBrB,CAvBhB,CA70gBV7iC,MA60gBU,CAA8C,EAA9C,CAEd,EADI3Y,CACJ,CAqB8Bw7C,CArB9B,EAn1gBI7iC,EAm1gBJ,CAl1gBIA,EAk1gBJ,IAAO8jC,CAAP,EAAqB,GAArB,CAA2Bp3B,CAAA,CAqBlBw3B,CArBkB;AAAe78C,CAAf,CAAmB,EAAnB,CAA3B,CAAmD,GAAnD,CAvBG,CAFP,IACIy8C,EAAA,CAAaQ,EAAA,CAAQR,CAAR,CAAoB,CAApB,CAAb,CAAsC9C,EAAA,CA6C7BkD,CA7C6B,CA6CRrB,CA7CQ,CA2B9C,EAAA,CAAOiB,CAoBHS,EAAAA,CAAW,EACXC,EAAAA,CA19BG93B,CAAA,CA09BKs1B,CA19BL,CA09BoBiB,CA98BHx4B,EAZjB,CAAoB,EAApB,CA09BH+5B,CAAoC,GACxC,IAt7gBa3G,EAs7gBb,GAAIoF,CAAAx4B,EAAJ,EAt7gBaozB,EAs7gBb,GAA6CD,CAAAnzB,EAA7C,EACI,EAGI,IAFItiB,CAEA,CAFI,CAAAu3C,GAAA,CAAauD,CAAb,CAAwB,CAAxB,CAEJ,CADJsB,CACI,EADQ,GACR,CADcvD,EAAA,CAAAA,CAAA,CAAe74C,CAAf,CACd,CAAkB,IAAlB,EAAA86C,CAAAx4B,EAAJ,CAA4B,KAHhC,OAISw4B,CAAAx4B,EAJT,EAI2BmzB,CAAAnzB,EAJ3B,CADJ,CAQA+5B,CAAA,EAASF,EAAA,CAAQC,CAAR,CAAkB,EAAlB,CAAT,CAAiCT,CAE7Bf,EAAJ,GACIyB,CAKI,CALIF,EAAA,CAAQE,CAAR,CAAe,EAAf,CAKJ,CALyB,GAKzB,EALgCzB,CAKhC,EAL4C,EAK5C,EAAAyB,CAAA,CAJC,CAAApuC,EAAAX,MAAAua,GAAL,CAIIw0B,CAJJ,EAIa,YAJb,CAGkBryB,EAAAhD,CAAA,CAAA/Y,EAAA+Y,CACOhU,SAAA,EAJzB,CAI8C,SAJ9C,CAIuDyR,CAAA,CAAU,CAAAxW,EAAA6Z,GAAV,CAJvD,EACIu0B,CADJ,EAC2B,IAAb,EAAAxB,CAAA,CAAmB,MAAnB,CAAyBA,CAAA7nC,SAAA,EAAzB,CAAgD,EAD9D,CAFJ,CASA,OAAOqpC,EA1BX;AAuCAC,QAAA,GAAgB,CAAhBA,CAAgB,CAACC,CAAD,CAAUC,CAAV,CAAqBl6B,CAArB,CAA2BivB,CAA3B,CAChB,CACI,IAAImJ,EAAU,EAGd,IAAK6B,CAAL,CAOK,CAKD,IAJA,IAAIE,EAAYF,CAAAlE,YAAA,EAAhB,CAIS/4C,EAAI,CAAb,CAAgBA,CAAhB,CAAoB08C,EAAAj5C,OAApB,CAAiDzD,CAAA,EAAjD,CACI,IAAKC,IAAIA,CAAT,GAAc08C,GAAA,CAAqB38C,CAArB,CAAd,CACI,GAAK,CAACC,CAAN,CAAA,CACA,IAAAw7C,EAAQkB,EAAA,CAAqB38C,CAArB,CAAA,CAAwBC,CAAxB,CACR,IAAIk9C,CAAJ,EAAiBb,EAAA,CAAsBb,CAAtB,CAAjB,CAA+C,CAC3C0B,CAAA,CAAYb,EAAA,CAAsBK,EAAA,CAAqB38C,CAArB,CAAA,CAAwB,CAAxB,CAAtB,CACRk9C,EAAJ,GAAeA,CAAf,CAA2Bj4B,CAAA,CAAAA,CAAA,CAAe,CAAChlB,CAAhB,CAA3B,CAAgD,GAAhD,CAAsDi9C,CAAtD,CACA,MAH2C,CAF/C,CASR,IAAK98B,IAAIA,CAAT,GAAiBw7B,GAAjB,CAAwC,CAGpC,IAAAE,EAAS,CAAC17B,CACNy7B,EAAAA,CAAUD,EAAA,CAAsBx7B,CAAtB,CAEd,QAAQ07B,CAAR,EACA,KAh8gBIvjC,KAg8gBJ,CACIwjC,CAAA,CAASC,EACT,MACJ,MAl8gBIzjC,KAk8gBJ,CACIwjC,CAAA,CAASE,EACT,MACJ,MAp8gBI1jC,KAo8gBJ,CACIwjC,CAAA,CAASG,EACT,MACJ,SACIH,CAAA,CAAS,CAAC,EAAD,CAXb,CAeA,IAAK5rB,IAAIA,CAAT,GAAe0rB,EAAf,CAAwB,CACpBJ,CAAA,CAAQI,CAAA,CAAQ1rB,CAAR,CACR,KAAK,IAAIurB,EAAQ,CAAjB,CAAoBA,CAApB,CAA4BK,CAAAt4C,OAA5B,CAA2Ci4C,CAAA,EAA3C,CAAoD,CAEhD,IAAIS,EAAQJ,CAAA,CAAOL,CAAP,CACC,IAAb,EAAIS,CAAJ,EAAoBV,CAApB,CAA4BW,EAA5B,GAAoDD,CAApD,CAA4D,GAA5D,CAGA,IAAIgB,CAAJ,EAFiBb,EAAA,CAAsBb,CAAtB,CAEjB,CAFgDU,CAEhD,CAA6B,CAErBiB,CAAA,CAt9gBZ7kC,KAq9gBQ,EAAIujC,CAAJ,CACaJ,CADb,EAGeA,CAHf,CAGuB,CAHvB,GAG+B,CAH/B,EAGsCA,CAHtC,CAG8C,EAH9C,GAGuD,CAEvDN,EAAA,EAAUjrB,CAAV,CAAgBitB,CAAhB,EAA0B,CAA1B,EAAgCzB,EAChC,MAPyB,CANmB,CAgBpD,GAAc,CAAd,EAAIP,CAAJ,CAAiB,KAlBG,CAoBxB,GAAc,CAAd,EAAIA,CAAJ,CAAiB,KAzCmB,CA+CpC,EAAS,CAAT,CAAAA,CAAA,CAAJ,EAAoB8B,CAApB,EAAkCA,CAAAv7C,MAAA,CAAgB,gBAAhB,CAAlC;CACIu7C,CAEA,CAFYD,CAEZ,CAFsBC,CAEtB,CADAD,CACA,CADU,EACV,CAAA7B,CAAA,CAAS,CAHb,CA/DC,CAPL,IAKQ8B,EAAJ,GAAe9B,CAAf,CAAwBU,CAAxB,CAAiC,CAAjC,CAwEJ,IAAc,CAAd,EAAIV,CAAJ,EACQ8B,CADR,CAUQ,IAPIG,CAOKz9C,CAPOs9C,CAAAt0C,MAAA,CAAgB,GAAhB,CAOPhJ,CANc,CAMdA,CANLy9C,CAAA55C,OAMK7D,GALAqyC,CAEL,EAFiB,CAAAh+B,EAAA,CAAa,qBAAb,CAAqCipC,CAArC,CAEjB,CADAG,CAAA55C,OACA,CADmB,CACnB,CAAA23C,CAAA,CAAU,EAGLx7C,EAAAA,CAAAA,CAAI,CAAb,CAAgBA,CAAhB,CAAoBy9C,CAAA55C,OAApB,CAAsC7D,CAAA,EAAtC,CAGI,GADI48C,CACJ,CADea,CAAA,CAAUz9C,CAAV,CAAAmE,KAAA,EACf,CAAA,CAEIpC,CAAAA,CAAQ66C,CAAA76C,MAAA,CAAe,0BAAf,CACZ,IAAI,CAACA,CAAL,CAAY,CACHswC,CAAL,EAAiB,CAAAh+B,EAAA,CAAa,mBAAb,CAAmCuoC,CAAnC,CACjBpB,EAAA,CAAU,EACV,MAHQ,CAYRz5C,CAAA,CAAM,CAAN,CAAJ,GAAcy5C,CAAd,EA3/gBA7iC,OA2/gBA,CAGA,IADAikC,CACA,CADW76C,CAAA,CAAM,CAAN,CACX,CAAc,CACV27C,CAAA,CAAUrK,EAAA,CAAAA,CAAA,CAAqBuJ,CAArB,CAA+BvK,CAA/B,CACV,IAAe3tC,IAAAA,EAAf,EAAIg5C,CAAJ,CAA0B,CACtBlC,CAAA,CAAU,EACV,MAFsB,CAuB1BkC,CAAA,CAAUlnB,CAAA,CAAWwa,CAAA,CAAAA,CAAA,CAAc0M,CAAd,CAAuB,EAAvB,CAA2B,CAAA,CAA3B,CAAX,CACVlC,EAAA,EAAUkC,CA1BA,CA6Bdd,CAAA,CAAW76C,CAAA,CAAM,CAAN,CACX,IAAI/B,CAAJ,EAA6B,CAA7B,EAASy9C,CAAA55C,OAAT,CAOQ+4C,CAAA,CAHCA,CAAL,CAGeA,CAAAp7C,QAAA,CAAiB,eAAjB,CAAkC,IAAlC,CAjpCxB6jB,CAAA,CAipCiEs4B,CAjpCjE,CAipCkFv6B,CAjpClF,CAAoB,EAApB,CAipCwB,CAHf,CACe,GAMfs6B,EAAAA,CAAUrK,EAAA,CAAAA,CAAA,CAAqBuJ,CAArB,CAA+BvK,CAA/B,CACd,IAAe3tC,IAAAA,EAAf,EAAIg5C,CAAJ,CAA0B,CACtBlC,CAAA,CAAU,EACV,MAFsB,CAK1B,GAAI,CAACx7C,CAAL,EAA6B,CAA7B,CAAUy9C,CAAA55C,OAAV,CACI,GA3jhBJ8U,KA2jhBI,EAAIujC,CAAJ,CAAiC,CAC7B,GAAc,CAAd,CAAIwB,CAAJ,EAxjhBR/kC,GAwjhBQ,CAAmB+kC,CAAnB,CACIA,CAAA,EAzjhBZ/kC,GA4jhBQ6iC;CAAA,EAAWkC,CAAX,CAAqBf,EALQ,CAAjC,IAOK,CACD,GAAc,CAAd,CAAIe,CAAJ,EAxjhBR/kC,EAwjhBQ,CAAmB+kC,CAAnB,CACIA,CAAA,EAzjhBZ/kC,EA4jhBQ6iC,EAAA,EAAWkC,CAAX,EA7jhBR/kC,EAwjhBS,CART,IAAA,CA8BA,GAAI0kC,CAAJ,EAAer9C,CAAf,CACI,GAAc,CAAd,CAAI09C,CAAJ,EAvkhBJ/kC,MAukhBI,CAAmB+kC,CAAnB,CACIA,CAAA,EAAWrtB,EAInBmrB,EAAA,EAAUkC,CApCV,CAjEA,CAiHC,CAAb,CAAIlC,CAAJ,EAAkB,CAACnJ,CAAnB,EACI,CAAAh+B,EAAA,CAAa,uBAAb,CAAuCgpC,CAAvC,CAAiD,GAAjD,CAAuDC,CAAvD,CAGJ,OAAO9B,EAnNX,CAuTAtG,QAAA,GAAgB,CAAhBA,CAAgB,CAChB,CAAA,IACQl1C,CACJ,EAAAi1C,EAAA,CAAkB,CAAC,IAAD,CAClB,IAAwBvwC,IAAAA,EAAxB,GAAI,CAAA6iB,EAAJ,CACI,IAAKvnB,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB,CAAAunB,EAAA1jB,OAAhB,CAAwC7D,CAAA,EAAxC,CAA6C,CACzC,IAAAu2C,EAAU,CAAAhvB,EAAA,CAAgBvnB,CAAhB,CACVojB,EAAA,CAAOkzB,EAAA,CAAaC,CAAb,CACPjyB,GAAA,CAAA,CAAAtV,EAAA,CAAwBoU,CAAxB,CAA8B,CAAA,CAA9B,CAHyC,CAMjD,CAAAmE,EAAA,CAAkB,CAAC,IAAD,CAClB,IAAyB7iB,IAAAA,EAAzB,GAAI,CAAA+iB,EAAJ,CACI,IAAKznB,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB,CAAAynB,EAAA5jB,OAAhB,CAAyC7D,CAAA,EAAzC,CACIu2C,CAEA,CAFU,CAAA9uB,EAAA,CAAiBznB,CAAjB,CAEV,CADAojB,CACA,CADOkzB,EAAA,CAAaC,CAAb,CACP,CAAAjyB,EAAA,CAAA,CAAAtV,EAAA,CAAwBoU,CAAxB,CAA8B,CAAA,CAA9B,CAGR,EAAAqE,EAAA,CAAmB,CAAC,IAAD,CAKnB,EAAAyuB,GAAA,CAAuB,CACvB,EAAAd,GAAA,CAA0B,CAxB9B;AAsDAvhC,CAAAgT,GAAA,CAAAA,QAAa,CAAC+2B,CAAD,CAASrH,CAAT,CAAkBG,CAAlB,CACb,CACI,IAAI9jC,EAAW,CAAA,CAYV8jC,EAAL,EACImH,EAAA,CAAAA,IAAA,CAAoBD,CAApB,CAA4BrH,CAA5B,CAA2C,CAAA,CAA3C,CAAkD,CAAA,CAAlD,CAGJ,IAAIqH,CAAJ,EAAc,IAAA3I,EAAd,CAA+B,CAC3B,IAAI7xB,EAAOkzB,EAAA,CAAaC,CAAb,CACX,IAz1hBSC,EAy1hBT,GAAIpzB,CAAJ,CACI,IAAA/O,EAAA,CAAa,mBAAb,CA/3CDgR,CAAA,CA+3CoCs1B,IA/3CpC,CA+3CmDpE,CAn3ClCnzB,EAZjB,CAAoB,EAApB,CA+3CC,CACA,CAAAxQ,CAAA,CAAW,CAAA,CAFf,KAGO,CAEH5D,IAAAA,EAAAA,IAAAA,EAh4dJ,EAAAoT,EAAA,CAg4dyBgB,CAh4dzB,GADsB,CAAArB,EACtB,CAAA8E,GAAA,CAg4dyBzD,CAh4dzB,CAlcegB,KAkcf,CA+3dkBw5B,CA/3dlB,EA+3d4B,IAAAn2B,EA/3d5B,CA83dO,CALoB,CAW3B7U,CAAJ,GACIgrC,CAAA30C,KAAA,CAAYstC,CAAZ,CACA,CAAIG,CAAJ,CACIH,CAAAG,GADJ,CACyB,CAAA,CADzB,EAIIoH,EAAA,CAAAA,IAAA,CAAqBF,CAArB,CAA6BA,CAAA/5C,OAA7B,CAA2C,CAA3C,CAA8C,KAA9C,CACA,CAAA0xC,EAAA,CAAAA,IAAA,CALJ,CAFJ,CA5BJ,CAuDAsI,SAAA,GAAc,CAAdA,CAAc,CAACD,CAAD,CAASrH,CAAT,CAA2BG,CAA3B,CAAuCpD,CAAvC,CACd,CACI,IAAIyK,EAAS,CAAA,CACT36B,EAAAA,CAAOkzB,EAAA,CAAaC,CAAb,CACX,KAAK,IAAIv2C,EAAI,CAAb,CAAgBA,CAAhB,CAAoB49C,CAAA/5C,OAApB,CAAmC7D,CAAA,EAAnC,CAAwC,CACpC,IAAIg+C,EAAeJ,CAAA,CAAO59C,CAAP,CACnB,IAAIojB,CAAJ,EAAYkzB,EAAA,CAAa0H,CAAb,CAAZ,GACQ,CAACtH,CADT,EACuBsH,CAAAtH,GADvB,EACgD,CACxCqH,CAAA,CAAS,CAAA,CAEAC,EAAAtH,GAAL,EAAiCpD,CAAjC,EACIwK,EAAA,CAAAA,CAAA,CAAqBF,CAArB,CAA6B59C,CAA7B,CAAgC,SAAhC,CAEJ49C,EAAA5qC,OAAA,CAAchT,CAAd,CAAiB,CAAjB,CACI49C,EAAJ,EAAc,CAAA3I,EAAd,EAEI3wB,EAAA,CAAA,CAAAtV,EAAA,CAAwBoU,CAAxB,CADcw6B,CACd,EADwB,CAAAn2B,EACxB,CAMCu2B,EAAAtH,GAAL,EACInB,EAAA,CAAAA,CAAA,CAEJ,MAlBoC,CAHZ,CA4BxC,MAAOwI,EA/BX;AAyCAE,QAAA,GAAe,CAAfA,CAAe,CAACL,CAAD,CACf,CACI,IAAK,IAAI59C,EAAI,CAAb,CAAgBA,CAAhB,CAAoB49C,CAAA/5C,OAApB,CAAmC7D,CAAA,EAAnC,CACI89C,EAAA,CAAAA,CAAA,CAAqBF,CAArB,CAA6B59C,CAA7B,CAEJ,OAAO49C,EAAA/5C,OAAP,CAAuB,CAJ3B,CAeAi6C,QAAA,GAAe,CAAfA,CAAe,CAACF,CAAD,CAAS59C,CAAT,CAAYk+C,CAAZ,CACf,CACQ3H,CAAAA,CAAUqH,CAAA,CAAO59C,CAAP,CACd,EAAAqU,EAAA,CAAaupC,CAAA,CAAO,CAAP,CAAb,CAAyB,GAAzB,CA/9COv4B,CAAA,CA+9CwBs1B,CA/9CxB,CA+9CuCpE,CAn9CtBnzB,EAZjB,CAAoB,EAApB,CA+9CP,EAA0D86B,CAAA,CAAU,GAAV,CAAgBA,CAAhB,CAA4B3H,CAAA7F,GAAA,CAAe,IAAf,CAAsB6F,CAAA7F,GAAtB,CAAqC,GAArC,CAA4C,EAAlI,EAFJ,CAsBA0K,QAAA,GAAmB,CAAnBA,CAAmB,CAACh4B,CAAD,CACnB,CACI,GAAa1e,IAAAA,EAAb,GAAI0e,CAAJ,CACIiE,EAAA,CAAAA,CAAA,CAAqBjE,CAArB,CAA2B,CAA3B,CAA8B,CAAA6xB,EAA9B,CAA+C,CAAA,CAA/C,CACA,CAAA,CAAAW,EAAA,CAAa,CAFjB,KAII,KAAS51C,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoB,CAAAi1C,EAAApxC,OAApB,CAA4C7D,CAAA,EAA5C,CAAiD,CAC7C,IAAIg+C,EAAe,CAAA/I,EAAA,CAAgBj1C,CAAhB,CACnB,IAAIg+C,CAAAtH,GAAJ,CAA6B,CACzB,GAAI,CAACmH,EAAA,CAAAA,CAAA,CAAoB,CAAA5I,EAApB,CAAqC+I,CAArC,CAAyD,CAAA,CAAzD,CAAL,CAAqE,KACrEh+C,EAAA,CAAI,CAFqB,CAFgB,CALzD;AAyBAqnB,QAAA,GAAe,CAAfA,CAAe,CAACjE,CAAD,CAAOkE,CAAP,CAAWs2B,CAAX,CAAmBlH,CAAnB,CACf,CAKI,IAAIyH,EAAS,CAAA,CAEb,IAAI,CAAC,CAAAjI,GAAA,EAAL,CAEI,IAAK,IAAIl2C,EAAI,CAAb,CAAgB,CAACm+C,CAAjB,EAA2Bn+C,CAA3B,CAA+B49C,CAAA/5C,OAA/B,CAA8C7D,CAAA,EAA9C,CAAmD,CAE/C,IAAIg+C,EAAeJ,CAAA,CAAO59C,CAAP,CAEnB,IAAI02C,CAAAA,CAAJ,EAAmBsH,CAAAtH,GAAnB,CAQA,IADA,IAAI0H,EAAY9H,EAAA,CAAa0H,CAAb,CAAZI,EAA0CR,CAAA,EAAU,CAAA3I,EAAV,CAA2B,KAA3B,CAAqC,EAA/EmJ,CAAJ,CACS/9C,EAAI,CAAb,CAAgBA,CAAhB,CAAoBinB,CAApB,CAAwBjnB,CAAA,EAAxB,CAEI,GAAK+iB,CAAL,CAAY/iB,CAAZ,EAAkB+9C,CAAlB,CAAA,CAEA,IAAI5+C,CACJ2+C,EAAA,CAAS,CAAA,CACLH,EAAAtH,GAAJ,GACImH,EAAA,CAAAA,CAAA,CAAoBD,CAApB,CAA4BI,CAA5B,CAAgD,CAAA,CAAhD,CACA,CAAAtH,CAAA,CAAa,CAAA,CAFjB,CAIA,IAAIl3C,CAAJ,CAAQw+C,CAAAjH,GAAR,CAA4B,CAWxBoH,CAAA,CAAS,CAAA,CACT,KAAK,IAAIl+C,EAAI,CAAb,CAAgBA,CAAhB,CAAoBT,CAAAqE,OAApB,CAA8B5D,CAAA,EAA9B,CACI,GAAI,CAACo+C,EAAA,CAAAA,CAAA,CAAe7+C,CAAA,CAAES,CAAF,CAAf,CAAqB,CAAA,CAArB,CAAL,CAAiC,CAC7B,GAAIT,CAAA,CAAES,CAAF,CAAAsB,QAAA,CAAa,IAAb,CAAJ,CAAwB,CACpB48C,CAAA,CAAS,CAAA,CACT,MAFoB,CAKxB,IADA,IAAIj+C,EAAID,CAAJC,CAAQ,CACZ,CAAOA,CAAP,CAAWV,CAAAqE,OAAX,EACSrE,CAAA,CAAEU,CAAF,CAAAqB,QAAA,CAAa,MAAb,CADT,CAAqBrB,CAAA,EAArB,CAEID,CAAA,EAEJ,IAAIC,CAAJ,EAASV,CAAAqE,OAAT,CAAmB,CACfs6C,CAAA,CAAS,CAAA,CACT,MAFe,CAVU,CAoBhC,CAAApvC,EAz+bdX,MAAA+Q,EAy+bS,GAA2Bg/B,CAA3B,CAAoC,CAAA,CAApC,CAjCwB,CAmC5B,GAAIA,CAAJ,CAAY,CACHzH,CAAL,EAAiBoH,EAAA,CAAAA,CAAA,CAAqBF,CAArB,CAA6B59C,CAA7B,CAAgC,KAAhC,CACjB,MAFQ,CA3CZ,CAd2C,CAiEvD,CAAAk2C,GAAA,EAEA,OAAOiI,EA5EX;AAuIAG,QAAA,GAAU,CAAVA,CAAU,CAACC,CAAD,CACV,CADWA,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAQ,CAAA,CAAR,CAAAA,CAGP,KADA,IAAIC,EAAQ,EAAZ,CACSx+C,EAAI,CAAb,CAAoB,EAApB,CAAgBA,CAAhB,CAAwBA,CAAA,EAAxB,CAA6B,CACrBA,CAAAA,CAAJ,EAAWA,CAAX,CAAe,CAAf,GAAmBw+C,CAAnB,EAA4B,IAA5B,CACSC,KAAAA,EAAAA,CAAAA,CApDT1E,EAAO/1B,EAAA,CAoDoBhkB,CApDpB,CAAgB,CAAhB,CACX22C,GAAA,CAAa,CAAAhC,GAAb,CAmD+B30C,CAnD/B,CACA+5C,EAAA,EAAQ,MAAR,CAAc10B,CAAA,CAAAA,CAAA,CAAe,CAAAgzB,GAAA,CAAa,CAAA1D,GAAb,CAAf,CAA8C,EAA9C,CAAd,CAAkE,GAkD9D6J,EAAA,EAjDGzE,CA+CsB,CAI7B,GAAIwE,CAAJ,CAAA,CAvBIC,CAAAA,CAAQ,EACZ,KAASx+C,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoB0+C,EAAA76C,OAApB,CAAmD7D,CAAA,EAAnD,CACI,CAlBA+5C,CAkBA,CAh3CG4E,EAAA,CAg3CwB3+C,CAh3CxB,CAg3CH,EAh3CmC,EAg3CnC,IAfA+5C,CAeA,EAfQ,MAeR,CAfc10B,CAAA,CAoCSu5B,CApCT,CAoCSA,CApCMpO,GAAA,CAeFxwC,CAfE,CAAf,CAeaA,CAhBdgwC,EAAQqK,EAARrK,CAA+B,CAA/BA,CAgBchwC,CAhBsB,EAAQk6C,EAAR,CAA+B,EAA/B,CAAoC,EACvE,CAed,CAf8D,GAe9D,EAAAsE,CAAA,EAbGzE,CAkCIyE,EAAA,EAAS,IAAT,CAnBJA,CAmBP,CACA,MAAOA,EAPX,CAkBA3qC,CAAAgrC,GAAA,CAAAA,QAAY,CAACC,CAAD,CAAKC,CAAL,CACZ,CACI,MAAOD,EAAA,CAAG,CAAH,CAAA,CAAQC,CAAA,CAAG,CAAH,CAAR,CAAe,CAAf,CAAmBD,CAAA,CAAG,CAAH,CAAA,CAAQC,CAAA,CAAG,CAAH,CAAR,CAAgB,EAAhB,CAAoB,CADlD,CAiFA/T;QAAA,GAAU,CAAVA,CAAU,CAACgU,CAAD,CAAU57B,CAAV,CAAgB+oB,CAAhB,CAAqBnkC,CAArB,CACV,CAEI,IAAIi3C,EAAW,EAAf,CACSjG,CAAT,KAASA,CAAT,GAAoBhxC,EAApB,CAA8B,CAC1B,IAAIqxC,EAASrxC,CAAA,CAASgxC,CAAT,CACQ,SAArB,EAAI,MAAOK,EAAX,GACIrxC,CAAA,CAASgxC,CAAT,CADJ,CACwBK,CADxB,CACiC,CAAC,EAAKA,CAAN,CADjC,CAGA,KAAIE,EAAYF,CAAA,EAAhB,CACI6F,EAAc7F,CAAA,EAClB,IAAkB30C,IAAAA,EAAlB,GAAI60C,CAAJ,CAAA,CACqB0F,IAAAA,EAAAA,CAAU,EAAA,CAAA,CAAC1F,CAAD,GAAe,CAAf,CAAkBP,CAAlB,CArjoBnC,KAAI14B,EAAQ6+B,EAAA,CAAiB3/C,CAAjB,CAAoBqB,CAApB,CAqjoBmD,CAAAg+C,GArjoBnD,CACA,EAAZ,CAAIv+B,CAAJ,EACI9gB,CAAAwT,OAAA,CAAS,EAAEsN,CAAF,CAAU,CAAV,CAAT,CAAuB,CAAvB,CAA0Bzf,CAA1B,CAkjoBA,CAGIq+C,CAAJ,GAAiB7F,CAAA,EAAjB,CAA+B6F,CAAA19C,QAAA,CAAoB,KAApB,CAA2B,GAA3B,CAA/B,CAV0B,CAmB9B,CAAAwzC,EAAA/rC,KAAA,CAPkBqwC,CACd0F,GAASA,CADK1F,CAEdl2B,EAAMA,CAFQk2B,CAGdnN,GAAKA,CAHSmN,CAIdtxC,EAAUA,CAJIsxC,CAKd2F,GAAUA,CALI3F,CAOlB,CAtBJ,CA8DA8F,QAAA,GAAU,CAAVA,CAAU,CAAC7I,CAAD,CAAU8I,CAAV,CACV,CACI,IAAIC,EAAU,EAAd,CACIC,EAAajJ,EAAA,CAAaC,CAAb,CAAbgJ,GAAuC,CAC3C,KAASrG,CAAT,CAAkB,CAAlB,CAAqBA,CAArB,CAA8B,CAAAlE,EAAAnxC,OAA9B,CAAwDq1C,CAAA,EAAxD,CAAkE,CAC9D,IAAII,EAAc,CAAAtE,EAAA,CAAkBkE,CAAlB,CAAlB,CACI91B,EAAOk2B,CAAAl2B,EAAPA,GAA4B,CADhC,CAEI+oB,EAAMmN,CAAAnN,GACV,IAAIoT,CAAJ,EAAkBn8B,CAAlB,EAA0Bm8B,CAA1B,CAAuCn8B,CAAvC,CAA8C+oB,CAA9C,CAAmD,CAE3C1V,CAAAA,CAAS0oB,EAAA,CAAiB7F,CAAA2F,GAAjB,CAAuC,CADpCM,CACoC,CADvBn8B,CACuB,CAAvC,CAAoD,CAAAy7B,GAApD,CACC,EAAd,EAAIpoB,CAAJ,CACI+oB,EAAA,CAAAA,CAAA,CAAkBtG,CAAlB,CAA0BziB,CAA1B,CAAkC6oB,CAAlC,CADJ,CAGSD,CAHT,GAII5oB,CAEA,CAFS,CAACA,CAEV,CADA+oB,EAAA,CAAAA,CAAA,CAAkBtG,CAAlB,CAA0BziB,CAA1B,CAAiC,CAAjC,CAAoC6oB,CAApC,CACA,CAAAE,EAAA,CAAAA,CAAA,CAAkBtG,CAAlB,CAA0BziB,CAA1B,CAAkC6oB,CAAlC,CANJ,CAQA,MAX+C,CAJW,CAkBlE,MAAOA,EArBX;AAsEAtT,QAAA,GAAS,CAATA,CAAS,CAACyT,CAAD,CAASC,CAAT,CACT,CACI,IAAI1wC,EAAM,CAAAA,EAAV,CAEI2wC,EAAS,CAFb,CAEgBC,EAAS,IAFzB,CAE+BC,EAAS,CACxCJ,EAAAK,QAAA,CAAe,QAAQ,CAACh/C,CAAD,CAAIsiB,CAAJ,CAAU,CAC7BpU,CAn8eJoT,EAAA,EAm8egBgB,CAn8ehB,CAm8eIpU,CAp8eiByR,EACrB,IAm8eIzR,CAp8eoC+S,EACxC,CAAA5B,EAAA,CAm8esBrf,CAn8etB,CAm8egBsiB,CAn8ehB,CAlYmBgB,KAkYnB,CAm8egBhB,CAn8ehB,CAo8ekB,KAAd,EAAIw8B,CAAJ,GAAoBA,CAApB,CAA6Bx8B,CAA7B,CACIA,EAAJ,CAAWy8B,CAAX,GAAmBA,CAAnB,CAA4Bz8B,CAA5B,CACAu8B,EAAA,EAJ6B,CAAjC,CAMKA,EAAL,EAGQI,CAQJ,CARa,gBAQb,CAPiB,IAAjB,EAAIL,CAAJ,EACItgC,CAAA,CAAA,CAAArQ,EAAA,CAAe2wC,CAAf,CACA,CAAAK,CAAA,EAAU16B,CAAA,CAAAA,CAAA,CAAeq6B,CAAf,CAFd,EAIIK,CAJJ,EAIc,aAGd,CADA,CAAA1rC,EAAA,CAAasrC,CAAb,CAAsB,mBAAtB,CAA4Ct6B,CAAA,CAAAA,CAAA,CAAeu6B,CAAf,CAA5C,CAAqE,GAArE,CAA2Ev6B,CAAA,CAAAA,CAAA,CAAew6B,CAAf,CAA3E,CAAoG,IAApG,CAA2GE,CAA3G,CACA,CAAAz1B,EAAA,CAAAA,CAAA,CAXJ,EACI,CAAAjW,EAAA,CAAa,SAAb,CAXR,CAmCAmrC,QAAA,GAAY,CAAZA,CAAY,CAACtG,CAAD,CAAS8G,CAAT,CAAkBV,CAAlB,CACZ,CACI,IAAIjG,EAAS,EAAb,CACI4F,EAAW,CAAAjK,EAAA,CAAkBkE,CAAlB,CAAA+F,GADf,CAEIgB,EAAS,CAFb,CAEgBjH,EAAU,IACX,EAAf,EAAIgH,CAAJ,EAAoBA,CAApB,CAA8Bf,CAAAp7C,OAA9B,GACIo8C,CACA,CADShB,CAAA,CAASe,CAAT,CAAA,CAAkB,CAAlB,CACT,CAAAhH,CAAA,CAAUiG,CAAA,CAASe,CAAT,CAAA,CAAkB,CAAlB,CAFd,CAIIhH,EAAJ,GACIK,CACA,CADS,CAAArE,EAAA,CAAkBkE,CAAlB,CAAAlxC,EAAA,CAAmCgxC,CAAnC,CACT,CAAAA,CAAA,CAAgC,GAArB,EAAAA,CAAAt3C,OAAA,CAAe,CAAf,CAAA,CAA0B,IAA1B,CAAkC23C,CAAA,EAAlC,EAAiDL,CAFhE,CAIAsG,EAAAr2C,KAAA,CAAa+vC,CAAb,CACAsG,EAAAr2C,KAAA,CAAag3C,CAAb,CACAX,EAAAr2C,KAAA,CAAaowC,CAAA,EAAb,CACAiG,EAAAr2C,KAAA,CAAaowC,CAAA,EAAb,CAfJ;AAwEA6G,QAAA,GAAU,CAAVA,CAAU,CAAC7I,CAAD,CACV,CACI,IAAIqC,EAAWrC,CAAA,CAAO,CAAP,CAAA11C,OAAA,CAAiB,CAAjB,CAAf,CACI21C,EAAQD,CAAA,CAAO,CAAP,CAAA,EAA6B,GAA7B,EAAaA,CAAA,CAAO,CAAP,CAAA,CAAU,CAAV,CAAb,EAAoD,GAApD,EAAoCA,CAAA,CAAO,CAAP,CAAA,CAAU,CAAV,CAApC,CAAyDA,CAAA,CAAO,CAAP,CAAzD,CAAqE3yC,IAAAA,EADjF,CAEI24C,EAAU/F,CAAA,CAAOD,CAAA,CAAO,CAAP,CAAP,CAAmBA,CAAA,CAAO,CAAP,CAFjC,CAGId,EAAUgB,EAAA,CAAAA,CAAA,CAAeD,CAAf,CAAsB,CAAAvC,GAAtB,CAEd,IAAI,CAACsI,CAAL,CAII,MAHA,EAAAhpC,EAAA,CAAa,oBAAb,CAr/DGgR,CAAA,CAq/DiCs1B,CAr/DjC,CAq/DgDpE,CAz+D/BnzB,EAZjB,CAAoB,EAApB,CAq/DH,CAGO,CAFP,CAAA+sB,EAEO,CAFU,CAAA,CAEV,CADPnwB,CAAA,CAAA,CAAA/Q,EAAA,CACO,CAAA,CAAA,CAGX,KAAIlN,EAAQs7C,CAAAt7C,MAAA,CAAc,8CAAd,CACZ,IAAIA,CAAJ,GAAcA,CAAA,CAAM,CAAN,CAAd,EAA0BA,CAAA,CAAM,CAAN,CAA1B,EAAqC,CAGjCw0C,CAAA,CAAUgB,EAAA,CAAAA,CAAA,CAAeD,CAAf,CACV,IAAI,CAAAnB,GAAJ,CAHUrnC,CAINuF,EAAA,CAAY,8BAAZ,CADJ,KAGK,CACD,IAAI8rC,EAAQp+C,CAAA,CAAM,CAAN,CAARo+C,CAAmBp+C,CAAA,CAAM,CAAN,CAClBA,EAAA,CAAM,CAAN,CAAL,GAAe23C,CAAf,EAA2B,GAA3B,CACA,KAAIzxC,EAAWsuC,CAAAnzB,EAAf,CACI+yB,EAAU,CAAAA,GAAVA,CAAyB,IAAIiK,EAAJ,CAVvBtxC,CAUuB,CAC7BuxC,GAAA,CAAAlK,CAAA,CAAsBgK,CAAtB,CAA6Bl4C,CAA7B,CAAuCyxC,CAAvC,CAAiD4G,QAAoB,CAACv5C,CAAD,CAAahB,CAAb,CAAmB,CACpF,GAAI,CAACgB,CAAL,CAMI,GAAI,CACA,IAAI24C,EAAYvJ,CAw/D7BuJ,EAv/D8B,KAAjB,EAAIA,CAAJ,GAAuBA,CAAvB,CAAmCz3C,CAAnC,CACA+jC,GAAA,CArBNl9B,CAqBM,CAAcqnC,CAy+D3BsJ,EAz+Da,CAAkCC,CAAlC,CAHA,CAIF,MAAM9/C,CAAN,CAAS,CACS,QAAhB,EAAI,MAAOA,EAAX,CACImH,CADJ,CACiBnH,CADjB,EACuB,EADvB,EAvBNkP,CA0BUuF,EAAA,CAAYzU,CAAAgJ,QAAZ,CACA;AAAA7B,CAAA,CAAc,EAJlB,CADO,CASXA,CAAJ,EA/BE+H,CAgCEuF,EAAA,CAAY,SAAZ,CAAwBtN,CAAxB,CAAqC,eAArC,EAAwDhB,CAAxD,EAAgEo6C,CAAhE,EAhCFrxC,EAkCFqnC,GAAA,CAAc,IACTpvC,EAAL,EAAiB4jB,EAAA,CAnCf7b,CAmCe,CAxBmE,CAAxF,CALC,CAgCL,MAAO,CAAA,CAvC0B,CA0CrCuoC,CAAAv1C,MAAA,EACAu1C,EAAAv1C,MAAA,EACAu1C,EAAAv1C,MAAA,EAEI05C,EAAAA,CAAS4B,EAAA,CAAAA,CAAA,CAAsBC,CAAtB,CADGhG,CAAA7D,KAAA8J,CAAY,EAAZA,CACH,CAA0C/G,CAAAnzB,EAA1C,EAA0D,CAA1D,CAEC,EAAd,EAAIo4B,CAAJ,GACI,CAAAjD,GAAA,CAAahC,CAAb,CAAsBiF,CAAtB,CACA,CAAA,CAAAnnC,EAAA,CAAaonC,EAAA,CAAAA,CAAA,CAAoBlF,CAApB,CAAb,CAFJ,CAIA,OAAO,CAAA,CAlEX,CA4aAgK,QAAA,GAAK,CAALA,CAAK,CAAC7P,CAAD,CACL,CACI,IAAIlxC,EAAIkxC,CAAA3uC,MAAA,CAAW,yCAAX,CACR,IAAIvC,CAAJ,CAAO,CACH,GAAI,CAACA,CAAA,CAAE,CAAF,CAAL,CAEI,MADK40C,GAAA,CAAAA,CAAA,CACE,EADoB,CAAA//B,EAAA,CAAa,cAAb,CACpB,CAAA,CAAA,CAEX,IAAI,CAAC7U,CAAA,CAAE,CAAF,CAAL,CACI,MAAO40C,GAAA,CAAAA,CAAA,CAAmB50C,CAAA,CAAE,CAAF,CAAnB,CAEX,IAAI,CAACA,CAAA,CAAE,CAAF,CAAL,CAEI,MAlrGR,QAirGQghD,CAjrGDlQ,EAAA,CAirGkB9wC,CAAAs0C,CAAE,CAAFA,CAjrGlB,CAkrGQ,CAAA,CAAA,CAEPjzC,EAAAA,CAAIwyC,EAAA,CAAAA,CAAA,CAAqB7zC,CAAA,CAAE,CAAF,CAArB,CACR,OAAUkF,KAAAA,EAAV,GAAI7D,CAAJ,EACI4/C,CAjoGRnQ,EAAA,CAioGyB9wC,CAAAs0C,CAAE,CAAFA,CAjoGzB,CAkoGe,CAloGS,CAAC1xC,MAioGMvB,CAjoGP,CAAQkzC,GAioGxBA,IAAA,EAjoGgB,CAkoGT,CAAA,CAAA,CAFX,EAIO,CAAA,CAjBJ,CAmBP,CAAA1/B,EAAA,CAAa,qBAAb,CAAqCq8B,CAArC,CACA,OAAO,CAAA,CAtBX;AAiCAgQ,QAAA,GAAM,CAANA,CAAM,CAACpJ,CAAD,CAAQ/D,CAAR,CACN,CACI,IAAIyF,EAAU,IAEVzC,EAAAA,CAAUgB,EAAA,CAAAA,CAAA,CAAeD,CAAf,CAEd,KAAIgI,EAAUF,EAAA,CAAAA,CAAA,CAAgB7I,CAAhB,CAAyB,CAAA,CAAzB,CACd,IAAI+I,CAAAz7C,OAAJ,CAAoB,CAAA,IACZ88C,CACJ,IAAIrB,CAAA,CAAQ,CAAR,CAAJ,CAAgB,CACZ,IAAAsB,EAAS,EAET,EADAD,CACA,CADSpK,CAAAnzB,EACT,CADwBk8B,CAAA,CAAQ,CAAR,CACxB,IAAYsB,CAAZ,CAAqB,KAArB,CA5wqBDr7B,CAAA,CA4wqB4Co7B,CA5wqB5C,CAAa,CAAb,CAAgB,CAAA,CAAhB,CA4wqBC,CACAjgD,EAAA,CAAI4+C,CAAA,CAAQ,CAAR,CAAJ,CAAiB,IAAjB,CAz8EDj6B,CAAA,CAy8EyBs4B,CAz8EzB,CAy8E0C2B,CAAAx4B,CAAQ,CAARA,CAz8E1C,CAAoB,EAApB,CAy8EC,CAAuD,GAAvD,CAA6D85B,CACzDrN,EAAJ,EAAY,CAAAl/B,EAAA,CAAa3T,CAAb,CACZs4C,EAAA,CAAUt4C,CANE,CAQK,CAArB,CAAI4+C,CAAAz7C,OAAJ,EAA0By7C,CAAA,CAAQ,CAAR,CAA1B,GACIsB,CAKA,CALS,EAKT,EAJAD,CAIA,CAJSrB,CAAA,CAAQ,CAAR,CAIT,CAJsB/I,CAAAnzB,EAItB,IAHYw9B,CAGZ,CAHqB,KAGrB,CAvxqBDr7B,CAAA,CAoxqB4Co7B,CApxqB5C,CAAa,CAAb,CAAgB,CAAA,CAAhB,CAuxqBC,EAFAjgD,CAEA,CAFI4+C,CAAA,CAAQ,CAAR,CAEJ,CAFiB,IAEjB,CAn9EDj6B,CAAA,CAi9EyBs4B,CAj9EzB,CAi9E0C2B,CAAAx4B,CAAQ,CAARA,CAj9E1C,CAAoB,EAApB,CAm9EC,CAFuD,GAEvD,CAF6D85B,CAE7D,CADIrN,CACJ,EADY,CAAAl/B,EAAA,CAAa3T,CAAb,CACZ,CAAKs4C,CAAL,GAAcA,CAAd,CAAwBt4C,CAAxB,CANJ,CAVgB,CAApB,IAmBQ6yC,EAAJ,EAAY,CAAAl/B,EAAA,CAAa,YAAb,CAEhB,OAAO2kC,EA3BX;AA0MAkC,QAAA,GAAW,CAAXA,CAAW,CAAC7D,CAAD,CACX,CADoBwJ,IAAAA,CAEhB,IAAIxJ,CAAJ,EAA2B,GAA3B,EAAcA,CAAA,CAAO,CAAP,CAAd,CACI,CAAAhjC,EAAA,CAAa,oBAAb,CAGA,CAFA,CAAAA,EAAA,CAAa,qBAAb,CAEA,CADA,CAAAA,EAAA,CAAa,2BAAb,CACA,CAAA,CAAAA,EAAA,CAAa,yCAAb,CAJJ,KAAA,CAQA,IAAItF,EAAM,CAAAA,EAAV,CACIwvC,EAAQ75C,IAAAA,EACQ,KAApB,EAAIm8C,CAAJ,GAA0BA,CAA1B,CAAyC,CAAA,CAAzC,CAEA,IAAc,IAAd,EAAIxJ,CAAJ,EAAsC,CAAtC,CAAsBA,CAAAxzC,OAAtB,CAAyC,CACrC,IAAIk2C,EAAO1C,CAAA,CAAO,CAAP,CAEX,IAAY,GAAZ,EAAI0C,CAAJ,CACIwE,CAAA,CAAQ,CAAA,CADZ,KAGK,CAED,IAAIv+C,EAAI+5C,CAAAx4C,QAAA,CAAa,MAAb,CACR,IAAQ,CAAR,CAAIvB,CAAJ,CACI8J,CACA,CADSiwC,CAAAp4C,OAAA,CAAY3B,CAAZ,CAAgB,CAAhB,CACT,CAAA+5C,CAAA,CAAOA,CAAAp4C,OAAA,CAAY,CAAZ,CAAe3B,CAAf,CAFX,KAIK,IAAoB,CAApB,CAAIq3C,CAAAxzC,OAAJ,CACDiG,CAAA,CAASutC,CAAA,CAAO,CAAP,CADR,KAGA,CACD,CAAAhjC,EAAA,CAAa,oBAAb,CAAoCgjC,CAAA,CAAO,CAAP,CAApC,CACA,OAFC,CAKDj1C,CAAAA,CAAQixC,EAAA,CAAAA,CAAA,CAAqBvpC,CAArB,CACZ,IAAcpF,IAAAA,EAAd,GAAItC,CAAJ,CAAyB,MAErBwxC,EAAAA,CAAO,CAAArD,GAAA,CAAiBwJ,CAAjB,CACX,IAAW,CAAX,CAAInG,CAAJ,CAAc,CACV,CAAAv/B,EAAA,CAAa,oBAAb,CAAoC0lC,CAApC,CACA,OAFU,CA71ElB+G,CAAAA,CAAO,CACX,KAAI/xC,EAi2EIgyC,CAj2EEhyC,EAEV,QA+1EyB6kC,CA/1EzB,EACA,KAAKqG,EAAL,CACI76B,CAAA,CAAArQ,CAAA;AA61E2B3M,CA71E3B,CACAu0C,GAAA,CA41EIoK,CA51ESlM,EAAb,CAA+B9lC,CA/3W5B8R,EA+3WH,CACA,MACJ,MAAKu5B,EAAL,CACI7qB,EAAA,CAAAxgB,CAAA,CAy1E2B3M,CAz1E3B,CACA,MACJ,MAAKi4C,EAAL,CACIyG,CAAA,CA9sfQtxB,MA+sfR,MACJ,MAAK8qB,EAAL,CACIwG,CAAA,CAhtfQtxB,KAitfR,MACJ,MAAK+qB,EAAL,CACIuG,CAAA,CAltfQtxB,KAmtfR,MACJ,MAAKgrB,EAAL,CACIsG,CAAA,CAntfQtxB,IAotfR,MACJ,MAAKirB,EAAL,CACIqG,CAAA,CAltfQtxB,EAmtfR,MACJ,MAAKkrB,EAAL,CACIoG,CAAA,CAhtfOtxB,MAwrfX,CA2BIsxB,CAAJ,GAEQ/xC,CAAAuf,EAFR,CAo0E+BlsB,CAn0E3B,CACI2M,CAAAuf,EADJ,CACiBwyB,CADjB,CAGI/xC,CAAAuf,EAHJ,CAGiB,CAACwyB,CAJtB,CAs0EQ9gC,EAAA,CAAA,CAAA/Q,EAAA,CACA,EAAAoF,EAAA,CAAa,oBAAb,CA3BC,CANgC,CAqCzC,CAAAA,EAAA,CAAaiqC,EAAA,CAAAA,CAAA,CAAgBC,CAAhB,CAAb,CAEIsC,EAAJ,GACIlK,EAAA,CAAa,CAAA9B,EAAb,CAA+BjlB,EAAA,CAAA7gB,CAAA,CAA/B,CACA,CAAAosC,EAAA,CAAAA,CAAA,CA9rFG91B,CAAA,CA8rFes1B,CA9rFf,CA8rF8B,CAAA9F,EAlrFbzxB,EAZjB,CAAoB,EAApB,CA8rFH,CAFJ,CAnDA,CADJ,CAsFA49B,QAAA,GAAO,CAAPA,CAAO,CAACtQ,CAAD,CACP,CACIA,CAAA,CAAOvB,EAAA,CAASuB,CAAT,CACP,KAAIlxC,EAAIkxC,CAAA3uC,MAAA,CAAW,iBAAX,CACHvC,EAAL,CAGsB,CAAlB,CAAIA,CAAA,CAAE,CAAF,CAAAqE,OAAJ,CACI,CAAAwQ,EAAA,CAA8B7U,CAAAkB,CAAE,CAAFA,CAA9B,CADJ,CAGIgzC,EAAA,CAAAA,CAAA,CAAgB,IAAhB,CAAsBl0C,CAAA,CAAE,CAAF,CAAA+vC,WAAA,CAAgB,CAAhB,CAAtB,CANR,CACI8D,EAAA,CAAAA,CAAA,CAAqB3C,CAArB,CAA2B,CAAA,CAA3B,CAJR;AAmLAuQ,QAAA,GAAO,CAAPA,CAAO,CAACvQ,CAAD,CAAOwQ,CAAP,CACP,CACI,GAAc,GAAd,EAAIA,CAAJ,CACI,CAAA7sC,EAAA,CAAa,iBAAb,CAIA,CAHA,CAAAA,EAAA,CAAa,gCAAb,CAGA,CAFA,CAAAA,EAAA,CAAa,sDAAb,CAEA,CADA,CAAAA,EAAA,CAAa,0BAAb,CACA,CAAA,CAAAA,EAAA,CAAa,0DAAb,CALJ,KAAA,CAUA,IAAI0mC,EAAiB,GAAjBA,EAASrK,CACTyQ,EAAAA,CAASzO,EAAA,CAAAA,CAAA,CAAgBwO,CAAhB,CAAwB,IAAxB,CAA8B,CAAA,CAA9B,CAATC,EAAgD,CASpD,KAAIr5B,EAAU,CAEF,KAAZ,EAAI4oB,CAAJ,GACI5oB,CACA,CADUq5B,CACV,CAAAA,CAAA,CAAS,CAFb,CAIA,EAAArL,GAAA,CAAqBpF,CAErB0Q,GAAA,CACID,CADJ,CAEIE,QAAoB,EAAG,CACnB,MAAOjsC,GAAA,CAtBLtG,CAsBK,CAAY,CAAA,CAAZ,CAAP,EAA4B2Q,EAAA,CAtB1B3Q,CAsB0B,CAAYgZ,CAAZ,CAAqBizB,CAArB,CAA4B,CAAA,CAA5B,CADT,CAF3B,CAKIuG,QAA4B,EAAG,CAxBzBxyC,CA+BEkO,GAAJ,EA/BElO,CA+BakO,GAAAL,KAAA,EACfqD,EAAA,CAhCElR,CAgCFG,EAAA,CAAwB,EAAxB,CACAmG,GAAA,CAjCEtG,CAiCF,CAAY,CAAA,CAAZ,CAT2B,CALnC,CA5BA,CADJ;AAwDAqsC,QAAA,GAAY,CAAZA,CAAY,CAAC7D,CAAD,CAAQiK,CAAR,CAAkBC,CAAlB,CACZ,CACQjL,CAAAA,CAAUgB,EAAA,CAAAA,CAAA,CAAeD,CAAf,CAAsB,CAAAzC,EAAtB,CAECnwC,KAAAA,EAAf,GAAI88C,CAAJ,GAA0BA,CAA1B,CAAmC,CAAnC,CAEA,KAAIC,EAAS,GACb,IAAiB/8C,IAAAA,EAAjB,GAAI68C,CAAJ,CAEI,GAA0B,GAA1B,EAAIA,CAAA7/C,OAAA,CAAgB,CAAhB,CAAJ,CACQrB,CACJ,CADQqyC,EAAA,CAAAA,CAAA,CAAgB6O,CAAA5/C,OAAA,CAAgB,CAAhB,CAAhB,CACR,CAAS,IAAT,EAAItB,CAAJ,GAAemhD,CAAf,CAAwBnhD,CAAxB,CAFJ,KAIK,CACGqhD,CAAAA,CAAanK,EAAA,CAAAA,CAAA,CAAegK,CAAf,CACjB,IAAIG,CAAAt+B,EAAJ,CAAsBmzB,CAAAnzB,EAAtB,CAAoC,MAEpCq+B,EAAA,CAASC,CAAAt+B,EAAT,CAA2BmzB,CAAAnzB,EAC3B,IAAuB,GAAvB,CAAcq+B,CAAd,CAA8B,CAM1B,CAAAptC,EAAA,CAAa,iBAAb,CACA,OAP0B,CAS9BmtC,CAAA,CAAU,EAdT,CAoBT,IAFIG,CAEJ,CAFe,CAEf,CAAgB,CAAhB,CAAOF,CAAP,EAAqBD,CAAA,EAArB,CAAA,CAA+B,CAE3B,IAAI7F,EAAazmC,EAAA,CAAAA,CAAA,CAAY,CAAA,CAAZ,CAAD,EAAuB,CAAA0gC,EAAvB,CAAoC,CAAA9tB,EAApC,CAAmD,IAAnE,CACI4zB,EAAyB,IAAb,EAAAC,CAAA,CAAmB,QAAnB,CAA8B,IAD9C,CAEI2D,EAAUF,EAAA,CAAAA,CAAA,CAAgB7I,CAAhB,CAFd,CAIInzB,EAAOmzB,CAAAnzB,EAEX,IAAIk8B,CAAA,CAAQ,CAAR,CAAJ,EAAkBkC,CAAlB,GACQ,CAACG,CADT,EACqBH,CADrB,EACyD,CADzD,CAC+BlC,CAAA,CAAQ,CAAR,CAAA/9C,QAAA,CAAmB,GAAnB,CAD/B,EAC4D,CACpD,IAAIqgD,EAAStC,CAAA,CAAQ,CAAR,CAATsC,CAAsB,GACtBtC,EAAA,CAAQ,CAAR,CAAJ,GAAgBsC,CAAhB,EAA0B,GAA1B,CAAgCtC,CAAA,CAAQ,CAAR,CAAhC,CACA,EAAAjrC,EAAA,CAAautC,CAAb,CAHoD,CAMxDtC,CAAA,CAAQ,CAAR,CAAJ,GACI5D,CACA,CADW4D,CAAA,CAAQ,CAAR,CACX,CAAA3D,CAAA,CAAY,IAFhB,CAIc5G,EAAAA,CAAAA,CAAAA,GAAsBwB,EAAAA,CAAAA,CA34GxCA,EAAAnzB,EAAA,CAAey+B,CAAAz+B,EACfmzB,EAAAE,GAAA,CAAoBoL,CAAApL,GACpBF,EAAAG,GAAA,CAAqBmL,CAAAnL,GACrBH,EAAAxG,EAAA,CAAgB8R,CAAA9R,EAy4GZ,EAAA17B,EAAA,CAAaonC,EAAA,CAAAA,CAAA,CAAoBlF,CAApB,CAA6BmF,CAA7B,CAAuCC,CAAvC,CAAb,CACA8F,EAAA,EAAUlL,CAAAnzB,EAAV,CAAyBA,CACzBu+B,EAAA,EAtB2B,CAhCnC;AAuHAtD,QAAA,GAAS,CAATA,CAAS,CAAC3N,CAAD,CAAO4C,CAAP,CACT,CACI,IAAI7c,EAAS,CAAA,CAEb,IAAI,CAKKia,CAAA7sC,OAAL,EAA4B,KAA5B,EAAoB6sC,CAApB,CAOU4C,CAPV,EAQI,CAAAj/B,EAAA,CAAa4mC,EAAb,CAAoCvK,CAApC,CARJ,EACQ,CAAAP,EAIJ,GAHI,CAAA97B,EAAA,CAAa,oBAAb,CA9kGLgR,CAAA,CA8kGyCs1B,CA9kGzC,CA8kGwD,CAAA5F,GAlkGvC3xB,EAZjB,CAAoB,EAApB,CA8kGK,CACA,CAAA,CAAA+sB,EAAA,CAAiB,CAAA,CAErB,EAAAO,CAAA,CAAO,EALX,CAWA,KAAIjvC,EAAKivC,CAAAhvC,OAAA,CAAY,CAAZ,CACT,IAAU,GAAV,EAAID,CAAJ,EAAuB,GAAvB,EAAiBA,CAAjB,CAA4B,MAAO,CAAA,CAKnC,EAAAg0C,GAAA,CAAoB,IAKpB,IAAIzgC,EAAA,CAAAA,CAAA,CAAJ,EAAgE,CAAhE,CAAkD07B,CAAA7sC,OAAlD,CAAmE,CAE3D,CAAAssC,EAAJ,GACIO,CADJ,CACW,IADX,CApmGDrrB,CAAA,CAqmGmBs1B,CArmGnB,CAqmGkC,CAAA5F,GAzlGjB3xB,EAZjB,CAAoB,EAApB,CAomGC,CACyD,GADzD,CAC+DstB,CAD/D,CAIA,KAAI4B,EAAS,CAAA,CAAb,CAC4B5B,EAAAA,CA3FxB,KAAAoR,EAAA,IAAA,EAAA,GAAAA,CAAA,CAAS,GAAT,CAAAA,CAMZ,KAJA,IAAIzK,EAAS,EAAb,CACIxG,EAAU,EADd,CAEI7wC,EAAI,CAFR,CAEW+hD,EAAQ,CAEnB,CAAO/hD,CAAP,CAAW0wC,CAAA7sC,OAAX,CAAA,CAAwB,CACpB,IAAIpC,EAAKivC,CAAA,CAAK1wC,CAAA,EAAL,CACL6wC,EAAJ,CACQpvC,CADR,EACcovC,CADd,GAEQA,CAEA,CAFU,EAEV,CADAwG,CAAApuC,KAAA,CAAYynC,CAAA/uC,OAAA,CAAYogD,CAAZ,CAAmB/hD,CAAnB,CAAuB+hD,CAAvB,CAAZ,CACA,CAAAA,CAAA,CAAQ/hD,CAJhB,EAQU,GAAV,EAAIyB,CAAJ,EAAuB,GAAvB,EAAiBA,CAAjB,CACIovC,CADJ,CACcpvC,CADd,CAI0B,CAJ1B,EAIIqgD,CAAAvgD,QAAA,CAAeE,CAAf,CAJJ,GAKI41C,CAAApuC,KAAA,CAAYynC,CAAA/uC,OAAA,CAAYogD,CAAZ,CAAmB/hD,CAAnB,CAAuB+hD,CAAvB,CAA+B,CAA/B,CAAZ,CACA,CAAAA,CAAA,CAAQ/hD,CANZ,CAVoB,CAmBpB+hD,CAAJ,CAAY/hD,CAAZ,EACIq3C,CAAApuC,KAAA,CAAYynC,CAAA/uC,OAAA,CAAYogD,CAAZ,CAAmB/hD,CAAnB,CAAuB+hD,CAAvB,CAAZ,CAGJ1K,EAAA,CAAO,CAAP,CAAA,CAAYA,CAAA,CAAO,CAAP,CAAA3zC,YAAA,EACZ,IAAI2zC,CAAJ,EAAcA,CAAAxzC,OAAd,CAA6B,CACzB,IAAIm+C;AAAK3K,CAAA,CAAO,CAAP,CAAT,CACI4K,EAAMD,CAAAtgD,OAAA,CAAU,CAAV,CACV,KAAK1B,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgBgiD,CAAAn+C,OAAhB,CAA2B7D,CAAA,EAA3B,CAEI,GADAyB,CACI,CADCugD,CAAAtgD,OAAA,CAAU1B,CAAV,CACD,CAAO,GAAP,EAAAiiD,CAAA,EAAqB,GAArB,EAAcA,CAAd,EAAiC,GAAjC,CAA4BxgD,CAA5B,EAA6C,GAA7C,CAAwCA,CAA5C,CAAsD,CAClD41C,CAAA,CAAO,CAAP,CAAA,CAAY2K,CAAArgD,OAAA,CAAU3B,CAAV,CACZq3C,EAAA6K,QAAA,CAAeF,CAAArgD,OAAA,CAAU,CAAV,CAAa3B,CAAb,CAAf,CACA,MAHkD,CALjC,CA+DrB,OAnDDq3C,CAmDS,CAAO,CAAP,CAAA31C,OAAA,CAAiB,CAAjB,CAAR,EACA,KAAK,GAAL,CACI+0B,CAAA,CAASypB,EAAA,CAAAA,CAAA,CArDd7I,CAqDc,CACT,MACJ,MAAK,GAAL,CACiB,IAAA,GAxDlBA,CAwDkB,CAAO,CAAP,CAAA,CAAW,GAxD7BA,CAwD6B,CAAO,CAAP,CAAX,CAAsB3G,EAAAA,CAtiC/C,IAAa,GAAb,EAAI4G,EAAJ,CAsiCY6K,CAriCR9tC,EAAA,CAAa,sBAAb,CAMA,CA+hCQ8tC,CApiCR9tC,EAAA,CAAa,6BAAb,CAKA,CA+hCQ8tC,CAniCR9tC,EAAA,CAAa,6BAAb,CAIA,CA+hCQ8tC,CAliCR9tC,EAAA,CAAa,8BAAb,CAGA,CA+hCQ8tC,CAjiCR9tC,EAAA,CAAa,2CAAb,CAEA,CA+hCQ8tC,CAhiCR9tC,EAAA,CAAa,4BAAb,CACA,CA+hCQ8tC,CA/hCR9tC,EAAA,CAAa,wCAAb,CAPJ,KAAA,CAWA,IAAIjK;AAAQsmC,EAAAhvC,OAAA,CAAY,CAAZ,CACZ,IAAa,GAAb,EAAI0I,EAAJ,CAAkB,CAEd,IAAAg4C,GADcA,CACdA,CAAWnE,EAAA,CAwhCHkE,CAxhCG,CAwhCHA,CAxhCwBlN,EAArB,CACXmN,GAAA,EAAWnE,EAAA,CAuhCHkE,CAvhCG,CAuhCHA,CAvhCwB56B,EAArB,CAEX,EADA66B,EACA,EADWnE,EAAA,CAshCHkE,CAthCG,CAshCHA,CAthCwB16B,EAArB,CACX,GAqhCQ06B,CArhCM9tC,EAAA,CAAa,gBAAb,CALA,CAAlB,IASA,IAAa,GAAb,EAAIjK,EAAJ,CAAkB,CACd,IAAI/J,GAAI,CAACi3C,EAALj3C,EAAc,CACdi3C,GAAJ,GA+gCQ6K,CA/gCG/M,GAAX,CAAqC/0C,EAArC,CA+gCQ8hD,EA9gCR9tC,EAAA,CAAa,cAAb,CAA8BhU,EAA9B,CAAkC,iBAAlC,CAHc,CAAlB,IAOA,IAAcqE,IAAAA,EAAd,GAAI4yC,EAAJ,CA0gCY6K,CAzgCR9tC,EAAA,CAAa,4BAAb,CADJ,KAAA,CAKA,IAAIkiC,GAAmB,GAAT,EAAAe,EAAA,CAAc1C,CAAA,EAAd,CAA+B2C,EAAA,CAqgCjC4K,CArgCiC,CAAe7K,EAAf,CAqgCjC6K,CArgCuDtN,EAAtB,CAEhC,IAAb,EAAIzqC,EAAJ,CACwB,IAApB,EAAImsC,EAAAnzB,EAAJ,EACI8xB,EAAA,CAigCIiN,CAjgCJ,CACA,CAggCIA,CAhgCJ9tC,EAAA,CAAa,yBAAb,CAFJ,EAKIwpC,EAAA,CA6/BIsE,CA7/BJ,CA6/BIA,CA7/BgBlN,EAApB,CAAqCsB,EAArC,CALJ,EAOIsH,EAAA,CA2/BIsE,CA3/BJ,CA2/BIA,CA3/BgB56B,EAApB,CAAqCgvB,EAArC,CAPJ,EASIsH,EAAA,CAy/BIsE,CAz/BJ,CAy/BIA,CAz/BgB16B,EAApB,CAAsC8uB,EAAtC,CATJ,EAkgCQ4L,CAv/BR9tC,EAAA,CAAa,sBAAb,CAznEGgR,CAAA,CAgnGK88B,CAhnGL,CAynEkD5L,EA7mEjCnzB,EAZjB,CAAoB,EAApB,CAynEH,CAZJ,CAgBoB,IAhBpB,EAgBImzB,EAAAnzB,EAhBJ,GAkBAq2B,EAAA,CAi/BY0I,CAj/BZ,CAAsB5L,EAAtB,CAA+BmD,CAA/B,CAEA,CAAa,GAAb,EAAItvC,EAAJ,CA++BY+3C,CA9+BRt7B,GAAA,CA8+BQs7B,CA9+BWlN,EAAnB,CAAoCsB,EAApC,CADJ,CAIa,GAAb,EAAInsC,EAAJ,CA2+BY+3C,CA1+BRt7B,GAAA,CA0+BQs7B,CA1+BW56B,EAAnB,CAAoCgvB,EAApC,CADJ,CAIa,GAAb,EAAInsC,EAAJ,CAu+BY+3C,CAt+BRt7B,GAAA,CAs+BQs7B,CAt+BW16B,EAAnB,CAAqC8uB,EAArC,CADJ;AAu+BY4L,CAn+BZ9tC,EAAA,CAAa,8BAAb,CAA8CjK,EAA9C,CAhCA,CAPA,CA5BA,CAuiCY,KACJ,MAAK,GAAL,CA19BR6E,IAAAA,GA29BYozC,CA39BZpzC,EA2sHI,GAAAqzC,EAAJ,GACI,EAAAA,EAAAlgD,MADJ,CAC8B,EAD9B,CA/uFY,MACJ,MAAK,GAAL,CAn9BZ,CAAA,CAAA,CACI,IAAIhC,EAAJ,CACIswC,GAo5BG2G,CAp5BI,CAAO,CAAP,CADX,CAEIC,GAm5BGD,CAn5BK,CAAO,CAAP,CAFZ,CAGIkL,GAk5BGlL,CAl5BI,CAAO,CAAP,CAHX,CAIImL,GAi5BGnL,CAj5BM,CAAO,CAAP,CAEb,IAAa,GAAb,EAAIC,EAAJ,CAAkB,CACd,IAAImL,GAAW,EACf,KAAKriD,EAAL,GAAU4Y,GAAV,CAg9BQ0pC,CA/8BAlN,GAAA,CAAgBp1C,EAAhB,CAAJ,GACQqiD,EACO,GADGA,EACH,EADe,GACf,EAAAA,EAAA,EAAWriD,EAF1B,CAKJqiD,GAAA,EAAY,gBA08BJC,EAz8BRruC,EAAA,CAAa,uBAAb,CAy8BQquC,EAx8BRruC,EAAA,CAAa,2CAAb,CAw8BQquC,EAv8BRruC,EAAA,CAAa,mDAAb,CAu8BQquC,EAt8BRruC,EAAA,CAAa,6DAAb,CACIouC,GAAA5+C,OAAJ,EAq8BQ6+C,CAr8BaruC,EAAA,CAAa,8BAAb,CAA8CouC,EAA9C,CAbP,CAAlB,IAiBA,IAAa,OAAb;AAAInL,EAAJ,CAAsB,CAClB,IAAIqL,GAASC,EAAA,CAg8BLF,CAh8BKzzC,EAAA,CAAkB,CAAA,CAAlB,CACb,IAAY,SAAZ,EAAIszC,EAAJ,CAaI1tC,OAAAlS,IAAA,CAAYggD,EAAZ,CAbJ,KAcO,CAlDX1zC,IAAAA,GAm+BYyzC,CAn+BZzzC,EA2sHI,GAAAqzC,EAAJ,GACI,EAAAA,EAAAlgD,MADJ,CAC8B,EAD9B,CAvpHYugD,GAAJ,EA+6BID,CA/6BQruC,EAAA,CAAasuC,EAAb,CAFT,CAhBW,CAAtB,IAuBA,IAAa,SAAb,EAAIrL,EAAJ,CAnbA,IAAK,IAAI4B,GAAS,CAAlB,CAAqBA,EAArB,CA61CYwJ,CA71CkB1N,EAAAnxC,OAA9B,CAAwDq1C,EAAA,EAAxD,CAAkE,CAC9D,IAAII,GA41CIoJ,CA51CU1N,EAAA,CAAkBkE,EAAlB,CAAlB,CACSF,EAAT,KAASA,EAAT,GAAoBM,GAAAtxC,EAApB,CACI,GAAyB,GAAzB,EAAIgxC,EAAAt3C,OAAA,CAAe,CAAf,CAAJ,CAAA,CAEA,IAAI63C,GADSD,EAAAtxC,EAAAqxC,CAAqBL,EAArBK,CACG,EAChB,IAAkB30C,IAAAA,EAAlB,GAAI60C,EAAJ,CAAA,CACA,IAAIsJ,GAAcvJ,EAAAtxC,EAAA,CAAqBgxC,EAArB,CAAA,EACd6J,GAAJ,GAAiB7J,EAAjB,CAA2B6J,EAA3B,CAq1CIH,EAp1CJruC,EAAA,CAvyDDgR,CAAA,CA2nGKq9B,CA3nGL,CAuyD+BnJ,EAvyD/B,CAAoB,EAApB,CAuyDC,CAA2C,GAA3C,CAAiDP,EAAjD,CAHA,CAHA,CAH0D,CAmblE,IAAA,CAKA,GAAY,GAAZ,EAAItI,EAAJ,CAAiB,CACb,IAAKtwC,EAAL,GAAU4Y,GAAV,CACI,GAg2BDq+B,CAh2BK,CAAO,CAAP,CAAJ,EAAiBj3C,EAAjB,CAAoB,CAChB,IAAI05C,GAk6BJ4I,CAl6BelN,GAAA,CAAgBp1C,EAAhB,CACX05C,GAAJ,EA81BLzC,CA71BSv1C,MAAA,EAEA,CA21BTu1C,CA51BSv1C,MAAA,EACA,CAAAg4C,EAAA,CA21BTzC,CA31BS,CAHJ,EAi6BAqL,CA55BIruC,EAAA,CAAa,yBAAb,CAAyCijC,EAAzC,CAEJ,OAAA,CATgB,CAYnBA,EAAL,GAAY5G,EAAZ,CAu5BQgS,CAv5BW7M,GAAnB,EAAwC,IAAxC,CAda,CAAjB,IAq6BY6M,EAr5BR7M,GAAA,CAAoBnF,EAGxB,IAAY,IAAZ,EAAIA,EAAJ,CAAkB,CACG4G,IAAAA,GAAAA,EAAAA,CAAOiL,GAAAA,EAAPjL,CAtoEjBwL;AAAQ,EAsoESxL,CAroEjByL,GAAW,CAqoEMzL,CApoEjB0L,GAqhGQN,CArhGGvN,EAooEMmC,CAnoEjB2L,GAohGQP,CAphGGrN,EAEf,IAAI4N,EAAAp/C,OAAJ,CAAqB,CACjB,IAAIq/C,GAAQ,CAACC,EAATD,EAihGIR,CAjhGcpN,GAAtB,CACIkM,GAAS,CAAC4B,EAAV5B,EAAoB,EAEpBx/C,MAAA,CAAMkhD,EAAN,CAAJ,CACIA,EADJ,CACY1B,EADZ,CAGIsB,EAHJ,CAGY,OAGRI,GAAJ,CAAYD,EAAAp/C,OAAZ,GAwgGQ6+C,CAvgGJruC,EAAA,CAAa,aAAb,CAA6B4uC,EAAAp/C,OAA7B,CAA+C,YAA/C,CACA,CAAAq/C,EAAA,CAAQD,EAAAp/C,OAFZ,CAKAm/C,GAAA,EAAYE,EACG,EAAf,CAAIF,EAAJ,GAI8C,IAA1C,EAAIC,EAAA,CAASA,EAAAp/C,OAAT,CAA2B,CAA3B,CAAAuf,EAAJ,EACI8/B,EACA,CADQF,EACR,CADmBE,EACnB,CAAAF,EAAA,CAAW,CAFf,EAIIA,EAJJ,EAIgBC,EAAAp/C,OARpB,CAYA,KAAIw/C,GAAW,EACD,OAAd,EAAID,EAAJ,GACI5B,EACA,CADS,GACT,CAAA6B,EAAA,CAAW,CAAC,MAAD,CAFf,CAqBA,KAhBc3+C,IAAAA,EAgBd,GAhBIy+C,EAgBJ,EAg+FQT,CA/+FJruC,EAAA,CAAa6uC,EAAb,CAAqB,wBAArB,CAeJ,CAAgB,CAAhB,CAAO1B,EAAP,EAAqBwB,EAArB,EAg+FQN,CAh+FyBvN,EAAjC,CAAA,CAA2D,CAEvD,IAAIoB,GAAU0M,EAAA,CAASD,EAAA,EAAT,CACd,IAAoB,IAApB,EAAIzM,EAAAnzB,EAAJ,CAA0B,KAM1B,KAAIkgC,GAAa1O,CAAA,CAAa2B,EAAAnzB,EAAb,CAAjB,CAGIu4B,GAAYuH,EAAA,EAHhB,CAeIK,GAAe9H,EAAA,CAw8FfiH,CAx8Fe,CAAoBY,EAApB,CAbJ5H,SAaI,CAA0CC,EAA1C,CAEnB,EAAI,CAAC0H,EAAAx/C,OAAL,EAA6D,CAA7D,EAAwB0/C,EAAAhiD,QAAA,CAAqB8hD,EAAA,CAAS,CAAT,CAArB,CAAxB,GAs8FIX,CAr8FAruC,EAAA,CAAakvC,EAAb,CAOAD,GAAAE,GAAJ,GACIR,EAAoE,EAAxDM,EAAAE,GAAwD,CAAjChC,EAAiC,EAAvB8B,EAAAE,GAAuB,CAAAN,EAAA,EAASI,EAAAE,GADjF,CAIIR;EAAJ,EAAgBC,EAAAp/C,OAAhB,GAAiCm/C,EAAjC,CAA4C,CAA5C,CA07FIN,EAz7FJpN,GAAA,CAAmB4N,EACnBH,GAAA,EACAvB,GAAA,EAzCuD,CAlD1C,CAoGhBuB,EAAL,GA86FYL,CA76FRruC,EAAA,CAAa,KAAb,CAAqByuC,EAArB,CAA6B,mBAA7B,CACA,CA46FQJ,CA56FRpN,GAAA,CAAmB5wC,IAAAA,EAFvB,CA4hEkB,CAAlB,IAAA,CAKA,IAAIynC,GAAM,CAAV,CACIsX,GAAiB,IAAjBA,EAAS/S,EADb,CAEI6F,GAAUgB,EAAA,CA24BFmL,CA34BE,CAAepL,EAAf,CA24BFoL,CA34BwB5N,GAAtB,CAEVyN,GAAJ,GAC0B,GAAtB,EAAIA,EAAA7gD,OAAA,CAAY,CAAZ,CAAJ,EACI6gD,EACA,CADOA,EAAA5gD,OAAA,CAAY,CAAZ,CACP,EADyB6gD,EACzB,CAAArW,EAAA,CAAMuG,EAAA,CAs4BFgQ,CAt4BE,CAAgBH,EAAhB,CAFV,EAMIpW,EANJ,CAKqBoL,EAAAmK,CAm4BbgB,CAn4BahB,CAAea,EAAfb,CACXt+B,EANV,CAM4BmzB,EAAAnzB,EAG5B,CADU,CACV,CADI+oB,EACJ,GADaA,EACb,CADmB,CACnB,EAAU,KAAV,CAAIA,EAAJ,GAAmBA,EAAnB,CAAyB,KAAzB,CAVJ,CAaA,KAAI4D,GA43BQ2S,CA53BA3S,EACRwG,GAAAxG,EAAJ,GA23BY2S,CA33BO3S,EAAnB,CAAgCwG,EAAAxG,EAAhC,CAQA,KANA,IAAI1sB,GAAgB,IAAR,EAAAqtB,EAAA,CAAc,CAAd,CAAkB,CAA9B,CACIiP,GAASxT,EAATwT,EAAgB,EADpB,CAEI+D,GAAyB,CAAR,EAAArgC,EAAA,CAAW,CAAX,CAAe,CAFpC,CAGIm+B,IAAY7B,EAAZ6B,CAAqBkC,EAArBlC,CAAqC,CAArCA,EAA0CkC,EAA1ClC,CAAyD,CAAzDA,EAA+D,CAHnE,CAKIhD,GAAQ,EACZ,CAAOgD,EAAA,EAAP,EAA4B,CAA5B,CAAmB7B,EAAnB,CAAA,CAA+B,CAAA,IACvB73C,GAAQ,EADe,CACX67C,GAAS,EACzBrM,GAAA,CA1wEGjyB,CAAA,CA2nGKq9B,CA3nGL,CA0wEoBnM,EA9vEHnzB,EAZjB,CAAoB,EAApB,CA4wEH,KADA,IAAI/iB,GAAIqjD,EACR,CAAa,CAAb,CAAOrjD,EAAA,EAAP,EAA6B,CAA7B,CAAkBs/C,EAAA,EAAlB,CAAA,CAAgC,CAC5B,IAAI7+C,GA82BA4hD,CA92BIrK,GAAA,CAAa9B,EAAb,CAAsB,CAAtB,CACJkN,GAAJ,EACQ37C,EACJ,GADWA,EACX,EADoB,GACpB,EAAAA,EAAA,EAAShH,EAFb,GAIIgH,EACA,EADS6xC,EAAA,CAy2BT+I,CAz2BS,CAAe5hD,EAAf,CACT,CAAAgH,EAAA,EAAS,IALb,CAYA,KADA,IAAIhG;AAAQ,EAAZ,CACS9B,GAAI,CAAb,CAAwB,CAAxB,EAAgBqjB,EAAhB,EAAsC,CAAtC,EAA6BvhB,EAA7B,CAAyC9B,EAAA,EAAzC,CAA8C,CAC1C,IAAIN,GAAMoB,EAANpB,CAAUuC,IAAAC,IAAA,CAAS,CAAT,CAAYJ,EAAZ,CAAVpC,CAAgCuC,IAAAC,IAAA,CAAS,CAAT,CAH5B8tC,CAG4B,CACpCloC,GAAA,EAASud,CAAA,CA+1BTq9B,CA/1BS,CAAehjD,EAAf,CAJDswC,CAIC,CAAT,CAAoC,GACpCtwC,GAAA,EAAyB,CACzBikD,GAAA,EAAe,EAAJ,CAAAjkD,EAAA,CAAU,GAAV,CAAgBkD,MAAAC,aAAA,CAAoBnD,EAApB,CAC3BoC,GAAA,EAPQkuC,CAEkC,CAdlB,CAsB5BwO,EAAJ,GAAWA,EAAX,EAAoB,IAApB,CAEIA,GAAA,CADAiF,EAAJ,CACIjF,EADJ,EACa12C,EADb,CACqB,GADrB,EAGI02C,EAHJ,EAGalH,EAHb,CAGqB,IAHrB,CAG4BxvC,EAH5B,EAG0C,CAAL,CAACzH,EAAD,CAAU,GAAV,CAAgBsjD,EAAhB,CAA0B,EAH/D,EA3B2B,CAkC3BnF,EAAJ,EAi1BYkE,CAj1BDruC,EAAA,CAAamqC,EAAb,CAi1BCkE,EA/0BZ3S,EAAA,CAAaA,EAnEb,CAxBA,CA/CJ,CA09BgB,KACJ,MAAK,GAAL,CACI,GAAiB,MAAjB,EAtELsH,CAsES,CAAO,CAAP,CAAJ,CAAyB,KAx0BzC,KAEQ3G,GAgwBG2G,CAhwBI,CAAO,CAAP,CAFf,CAGQC,GA+vBGD,CA/vBK,CAAO,CAAP,CACZ,IAAY,GAAZ,EAAI3G,EAAJ,EAA2B,IAA3B,EAAmBA,EAAnB,CAAiC,CAC7B,IAAAkT,GAo0BQC,CAp0BAxL,GACR,KAAAyL,GAm0BQD,CAn0BAtL,GAFqB,CAAjC,IAIIjB,GAAA,CAAQ,IAEZ,IAAa,IAAb,EAAIA,EAAJ,CA+zBYuM,CA9zBRxvC,EAAA,CAAa,uBAAb,CACA,CA6zBQwvC,CA7zBRxvC,EAAA,CAAa,yCAAb,CAFJ,KAMA,KADA,IAAIkiC,GAAUgB,EAAA,CA0zBFsM,CA1zBE,CAAevM,EAAf,CA0zBFuM,CA1zBwB/O,GAAtB,CAAd,CACS90C,GAAI,CAAb,CAAgBA,EAAhB,CAkvBOq3C,CAlvBaxzC,OAApB,CAAmC7D,EAAA,EAAnC,CAAwC,CACpC,IAAIc,GAAIuyC,EAAA,CAwzBAwQ,CAxzBA,CAivBLxM,CAjvB0B,CAAOr3C,EAAP,CAArB,CACR,IAAU0E,IAAAA,EAAV;AAAI5D,EAAJ,CAAqB,KACrBA,GAAA,CAAI04C,EAAA,CAAkB14C,EAAlB,CAszBI+iD,EArzBRxvC,EAAA,CAAa,WAAb,CA10EGgR,CAAA,CA+nGKw+B,CA/nGL,CA00EuCtN,EA9zEtBnzB,EAZjB,CAAoB,EAApB,CA00EH,CAAqD,QAArD,CAAgEu2B,EAAA,CAqzBxDkK,CArzBwD,CAAeD,EAAAjwC,KAAA,CAqzBvEkwC,CArzBuE,CAAiBtN,EAAjB,CAAf,CAAhE,CAA4G,MAA5G,CAAqHoD,EAAA,CAqzB7GkK,CArzB6G,CAAe/iD,EAAf,CAArH,CACAgjD,GAAAnwC,KAAA,CAozBQkwC,CApzBR,CAAiBtN,EAAjB,CAA0Bz1C,EAA1B,CAA6B,CAA7B,CALoC,CA0zB5B,KACJ,MAAK,GAAL,CAC0B,IAAA,GA1E3Bu2C,CA0E2B,CAAO,CAAP,CAAA,CAAW3G,GAAAA,CArb7C,IAAchsC,IAAAA,EAAd,GAAI4yC,EAAJ,CAAyB,CACrB,IAAIf,GAAUgB,EAAA,CAobNwM,CApbM,CAAezM,EAAf,CACdmC,GAAA,CAmbQsK,CAnbR,CAAsBxN,EAAtB,CAA+BmD,EAA/B,CAmbQqK,EAxpDZl9B,GAAA,CAwpDYk9B,CAxpDO9O,EAAnB,CAsuC2BsB,EAtuC3B,CAA6C,CAAA,CAA7C,CAmuCyB,CAKzBh3B,EAAA,CAgbYwkC,CAhbZ,CAAc,CAAA,CAAd,CAgbmDzQ,CAhbnD,CAibY,MACJ,MAAK,GAAL,CACI0Q,CA7yBR51C,MAAA+Q,EAAJ,EA6yBwBm0B,CA3yBpB,EA2yBQ0Q,CA5yBK3vC,EAAA,CAAa,SAAb,CACb,CAAAmL,EAAA,CA2yBQwkC,CA3yBR,CAFJ,EAIQ9uC,EAAA,CAyyBI8uC,CAzyBJ,CAAY,CAAA,CAAZ,CAJR,EA6yBwB1Q,CA7yBxB,EA6yBY0Q,CAxyBK3vC,EAAA,CAAa,gBAAb,CAyyBL,MACJ,MAAK,GAAL,CACI,GAAiB,IAAjB,EAhFLgjC,CAgFS,CAAO,CAAP,CAAJ,CAAuB,CACJ,IAAA,GAAA3G,CAAA/uC,OAAA,CAAY,CAAZ,CAvxB/B+uC,GAAA,CAAOvB,EAAA,CAASuB,EAAT,CACP,IAAK2C,EAAA,CAsxBgB4Q,CAtxBhB,CAAqBvT,EAArB,CAAL,CAAA,CAsxB+C4C,CAlxB/C,EAkxBqB2Q,CAlxBR5vC,EAAA,CAAa,QAAb,CAAwBq8B,EAAxB,CACb,KAAA,GAAO,CAAA,CALP,CAAA,IAsxB+C4C,EApxB3C,EAoxBiB2Q,CArxBJ5vC,EAAA,CAAa,SAAb,CAAyBq8B,EAAzB,CACb,CAAA,EAAA,CAAO,CAAA,CAoxBU,GAAL,GACIja,CADJ,CACa,CAAA,CADb,CAGA,MAJmB,CAMvB6b,CAAA,CAAS,CAAA,CACT,MACJ,MAAK,GAAL,CACsB,IAAA,GAzFvB+E,CAyFuB,CAAO,CAAP,CAjU9B,IAAa,GAAb,EAwOOA,CAyFkCC,CAAO,CAAPA,CAjUzC,CAiUY4M,CAhUR7vC,EAAA,CAAa,uBAAb,CAEA;AA8TQ6vC,CA/TR7vC,EAAA,CAAa,2BAAb,CACA,CA8TQ6vC,CA9TR7vC,EAAA,CAAa,+BAAb,CAHJ,KAAA,CAOA,IAAkB8vC,GAAU,CAA5B,CACIC,GAAcxP,CAAA,EADlB,CAEIyP,GAAezP,CAAA,EAGnB,KAqTYsP,CAvTZ7vC,EAAA,CAAa,kBAAb,CA11FOgR,CAAA,CAipGK6+B,CAjpGL,CA01F0CG,EA90FzBjhC,EAZjB,CAAoB,EAApB,CA01FP,CAEA,CALckhC,EAKd,CAAOH,EAAP,CAAA,CAA0B,CAEtB,IAFsB,IAClBI,GAAQ,IADU,CACcC,GAAS,GAC7C,CAAmC,KAAnC,CAAQH,EAAAjhC,EAAR,GAA8B,CAA9B,CAAA,CAA4C,CACxCghC,EAAAhhC,EAAA,CAkTI8gC,CAlTe7L,GAAA,CAAagM,EAAb,CAA2B,CAA3B,CAKnB,IAAyB,IAAzB,EAAIA,EAAAjhC,EAAJ,EAAiC,CAACohC,EAAA,EAAlC,CAA4C,KAC5C,IAAI,EAAAJ,EAAAhhC,EAAA,CAAmB,CAAnB,CAAJ,CAAA,CAzDR,IAqWY8gC,IAAAA,GAAAA,CAAAA,CA3SiBE,GAAAA,EA2SjBF,CAxWRK,GAAQ,IAwWAL,CAvWR9gC,GAAOmzB,EAAAnzB,EAuWC8gC,CAtWRO,GAAWrhC,EAsWH8gC,CArWH7jD,GAAI,CAAb,CAAqB,CAArB,EAAgBA,EAAhB,EAA4B+iB,EAA5B,CAAkC/iB,EAAA,EAAlC,CAAuC,CACnC,GAAQ,CAAR,CAAIA,EAAJ,CAAW,CACPk2C,EAAAnzB,EAAA,CAAeA,EACf,KAAI1iB,GAAI+6C,EAAA,CAAAA,EAAA,CAAoBlF,EAApB,CACR,IAAwB,CAAxB,EAAI71C,EAAAa,QAAA,CAAU,KAAV,CAAJ,CAA2B,CAOvB,IAAIvB,GAAIU,EAAAa,QAAA,CAAU,GAAV,CAER,IAAI6hB,EAAJ,EADQ1iB,EAAAa,QAAAtB,CAAU,GAAVA,CAAeD,EAAfC,CAAiB,CAAjBA,CACR,CAAgBD,EAAhB,CAAoB,CAApB,EAAuB,CAAvB,EAA4BykD,EAA5B,CAAsC,CAClCF,EAAA,CAAQ7jD,EACR,MAFkC,CATf,CAHpB,CAkBX0iB,EAAA,EAAQ,CAnB2B,CAqBvCmzB,EAAAnzB,EAAA,CAAeqhC,EAsCP,IArCR,EAqCQ,CArCDF,EAqCC,CAAW,KAFX,CAPwC,CAiB5C,GAAI,CAACA,EAAL,EAlB8BG,IAkB9B,EAAcH,EAAd,CAAkC,KAClC,KAAIvL;AAAU,IACd,IAAY,IAAZ,EAAItI,EAAJ,CAAkB,CACd,IAAIlxC,GAAI+kD,EAAAxiD,MAAA,CAAY,YAAZ,CACJvC,GAAJ,GAAOw5C,EAAP,CAAiB0H,EAAA,CA8RbwD,CA9Ra,CAAY1kD,EAAA,CAAE,CAAF,CAAZ,CAAjB,CAFc,CAIlB+kD,EAAA,CAAQtH,EAAA,CAAQsH,EAAR,CAAe,EAAf,CAAR,CAA6B,KAA7B,EAAsCvL,EAAtC,EAAiD,WAAjD,CAr3FG3zB,CAAA,CAipGK6+B,CAjpGL,CAq3FwEG,EAz2FvDjhC,EAZjB,CAAoB,EAApB,CAq3FH,CA4RQ8gC,EA3RR7vC,EAAA,CAAakwC,EAAb,CAEAJ,GAAA,EA5BsB,CA8BrBA,EAAL,EAuRYD,CAvRE7vC,EAAA,CAAa,2BAAb,CA1Cd,CAkUY,KACJ,MAAK,GAAL,CACI,GAAiB,IAAjB,EA5FLgjC,CA4FS,CAAO,CAAP,CAAJ,CAAuB,CACnBqJ,EAAA,CAAAA,CAAA,CA7FTrJ,CA6FqB,CAAO,CAAP,CAAZ,CAAuB,CAAA,CAAvB,CACA,MAFmB,CAIvB/E,CAAA,CAAS,CAAA,CACT,MACJ,MAAK,GAAL,CAxrBZ,CAAA,CAAA,CACI,IAAIlyC,EAAJ,CACIukD,GAAY,IADhB,CAEIC,EAmlBGvN,CAnlBS,CAAO,CAAP,CACC,IAAjB,EAAIuN,CAAJ,GAAsBA,CAAtB,CAAkClgD,IAAAA,EAAlC,CAEA,IAAkBA,IAAAA,EAAlB,GAAIkgD,CAAJ,CAA6B,CACzB,IAAI/2C,GAAc,CAClB,IAAiB,KAAjB,EAAI+2C,CAAJ,CACI/2C,EACA,CADc,UACd,CAAA+2C,CAAA,CAAY,IAFhB,KAGO,IAAiB,IAAjB,EAAIA,CAAJ,CACHD,EACA,CADY,CAAA,CACZ,CAAAC,CAAA,CAAY,IAFT,KAGA,IAAiB,KAAjB,EAAIA,CAAJ,CACHD,EACA,CADY,CAAA,CACZ,CAAAC,CAAA,CAAY,IAFT,KAGA,CAKc,MAAjB,EAAIA,CAAJ,GAAyBA,CAAzB,CAAqC,KAArC,CACiB,MAAjB,EAAIA,CAAJ,GAAwBA,CAAxB,CAAoC,UAApC,CACA,KAAKxkD,EAAL,GAAU4Y,GAAV,CACI,GAAI4rC,CAAJ,EAAiBxkD,EAAjB,CAAoB,CAChByN,EAAA,CAAcmL,EAAA,CAAyB5Y,EAAzB,CACdukD,GAAA,CAAY,CAAC,EA8pBjBE,CA9pBmBh3C,GAAF,CAAqBA,EAArB,CACb,MAHgB,CAMxB,GAAI,CAACA,EAAL,CAAkB,CA0pBdg3C,CAzpBAxwC,EAAA,CAAa,4BAAb;AAA4CuwC,CAA5C,CACA,OAAA,CAFc,CAdf,CAmBP,GAAI/2C,EAAJ,CACI,GAAiB,IAAjB,EAijBDwpC,CAjjBK,CAAO,CAAP,CAAJ,CAopBIwN,CAnpBAh3C,GACA,EADoBA,EACpB,CAAA82C,EAAA,CAAY,CAAA,CAFhB,KAIK,IAAiB,KAAjB,EA6iBNtN,CA7iBU,CAAO,CAAP,CAAJ,GAgpBDwN,CA/oBAh3C,GAEI,EAFgB,CAACA,EAEjB,CADJ82C,EACI,CADQ,CAAA,CACR,CAvxjBRrqC,UAuxjBQ,EAAAzM,EAHH,EAGwC,CAErC,IADA,IAAI7N,GAAkC,GAA9B,EA4oBZ6kD,CA5oBYnP,EAAA7xC,OAAA,CA4oBZghD,CA5oBgDnP,EAAA7xC,OAApC,CAAiE,GAAjE,CAAwE,CAChF,CAAO7D,EAAP,CA2oBJ6kD,CA3oBenP,EAAA7xC,OAAX,CAAA,CA2oBJghD,CA1oBQxwC,EAAA,CA0oBRwwC,CA1oBqBnP,EAAA,CAAoB11C,EAAA,EAApB,CAAb,CA0oBR6kD,EAxoBInP,EAAA,CAAsB,EALe,CAtCxB,CAoD7B,IAAIr1C,GAAI,CAAR,CACIykD,GAAc,EAClB,KAAK1kD,EAAL,GAAU4Y,GAAV,CACI,GAAI,CAAC4rC,CAAL,EAAkBA,CAAlB,EAA+BxkD,EAA/B,CAAkC,CAE9B,IAAI2kD,GAAW,CAAC,EA0nBZF,CA1nBch3C,GAAF,CADCmL,EAAAgsC,CAAyB5kD,EAAzB4kD,CACD,CAChB,IAAkB,IAAlB,GAAIL,EAAJ,EAA0BA,EAA1B,EAAuCI,EAAvC,CACID,EAOJ,GAPiBA,EAOjB,EAPgC,GAOhC,EANM,EAAEzkD,EAMR,CANY,EAMZ,GANiBykD,EAMjB,EANgC,MAMhC,EADS,KACT,EADI1kD,EACJ,GADgBA,EAChB,CADoB,MACpB,EAAA0kD,EAAA,EAAe1kD,EAXe,CAepBsE,IAAAA,EAAlB,GAAIkgD,CAAJ,EA6mBYC,CA5mBRxwC,EAAA,CAAa,oEAAb,CA4mBQwwC,EAzmBZxwC,EAAA,EAA4B,IAAd,GAAAswC,EAAA,CAAqBA,EAAA,CAAW,gBAAX,CAA8B,gBAAnD,CAAuE,yBAArF;CAAmHG,EAAnH,EAAkI,MAAlI,EAEAvP,GAAA,CAumBYsP,CAvmBZ,CAlFJ,CA0rBgB,KACJ,MAAK,GAAL,CACI,GAAiB,OAAjB,EAtGLxN,CAsGS,CAAO,CAAP,CAAJ,CAA0B,CACtB2J,EAAA,CAAAA,CAAA,CAAatQ,CAAA/uC,OAAA,CAAY,CAAZ,CAAb,CACA,MAFsB,CAId,IAAA,GA1GjB01C,CA0GiB,CAAO,CAAP,CAAA,CA3apB4N,GAAiB,GAAR,EAAAvU,EAAA,CAAa,CAAb,CAA0B,IAAR,EAAAA,EAAA,CAAc,CAAd,CAAmB,EAElD,IAAe,GAAf,EA+TO2G,CA0G4B6N,CAAO,CAAPA,CAzanC,EAA8B,CAA9B,CAAsBD,EAAtB,CAyaYE,CAxaR9wC,EAAA,CAAa,gBAAb,CAEA,CAsaQ8wC,CAvaR9wC,EAAA,CAAa,4BAAb,CACA,CAsaQ8wC,CAtaR9wC,EAAA,CAAa,kDAAb,CAHJ,KAaA,IA4ZY8wC,CA5ZPvP,EAAL,CA4ZYuP,CAzYR9wC,EAAA,CAAa,kBAAb,CAnBJ,KAAiB,CACb,IAAIkiC,GAAU3B,CAAA,CA2ZNuQ,CA3ZmBp2C,EA/ybxB8R,EA+ybW,CA2ZNskC,EA1ZK9M,GAAA,CAAa9B,EAAb,CA0ZL4O,EAxZJvP,EAAJ,EAwZQuP,CAxrDZt+B,GAAA,CAwrDYs+B,CAxrDOlQ,EAAnB,CAiyC+BsB,EAjyC/B,CAA6C,CAAA,CAA7C,CAkyCQ,CAAKh3B,EAAA,CAsZD4lC,CAtZC,CAAL,GAsZIA,CArZIl2C,EACJ,EADcub,EAAA,CAqZd26B,CArZcl2C,EAAA,CACd,CAoZAk2C,CApZAvP,EAAA,CAAa,CAFjB,CAFJ,EAYIqL,EAAA,CA4YIkE,CA5YJ,CAAaF,EAAA,CAAO,IAAP,CAAc,GAA3B,CAhBS,CA6ZL,KACJ,MAAK,GAAL,CACI,GAAY,OAAZ,EAAIvU,CAAJ,CAAqB,CACb,CAAAzhC,EAAJ,EAAc,CAAAA,EAAAwN,MAAA,EACd,MAFiB,CAIrBy+B,EAAA,CAAAA,CAAA,CAjHL7D,CAiHK,CACA,MACJ,MAAK,GAAL,CA7mBZ,CAAA,CACI,OAyfOA,CAzfC,CAAO,CAAP,CAAR,EAEA,KAAK,MAAL,CACI,GAsfGA,CAtfC,CAAO,CAAP,CAAJ,CAAe,CACX,IAAItH,GAAQ,CAqfbsH,CArfc,CAAO,CAAP,CACb;GAAa,CAAb,EAAItH,EAAJ,EAA2B,CAA3B,EAAkBA,EAAlB,EAAyC,EAAzC,EAAgCA,EAAhC,EAAwD,EAAxD,EAA+CA,EAA/C,CAwmBIqV,CAvmBArV,EAAA,CAAaA,EADjB,KAEO,CAsmBHqV,CArmBA/wC,EAAA,CAAa,gBAAb,CAAgC07B,EAAhC,CACA,MAFG,CAJI,CA0mBPqV,CAjmBR/wC,EAAA,CAAa,gBAAb,CAimBQ+wC,CAjmBwBrV,EAAhC,CACA,MAEJ,MAAK,IAAL,CACI,IAAIjoB,EACcpjB,KAAAA,EAAlB,GAweG2yC,CAxeC,CAAO,CAAP,CAAJ,GAA6BvvB,EAA7B,CAAuC,CAwepCuvB,CAxeqC,CAAO,CAAP,CAAxC,CACA,QAueGA,CAveK,CAAO,CAAP,CAAR,EACI,KAAK,KAAL,CA0lBI+N,CAzlBAr2C,EAAAga,GAAA,CAAmCjB,EACnC,MACJ,MAAK,OAAL,CAulBIs9B,CAtlBAr2C,EAAA+Z,GAAA,CAAgChB,EAChC,MACJ,MAAK,MAAL,CAolBIs9B,CAnlBAr2C,EAAAia,GAAA,CAA+BlB,EAC/B,MACJ,SAilBIs9B,CAhlBA/wC,EAAA,CAAa,mBAAb,CACA,OAAA,CAZR,CAcgB3P,IAAAA,EAAhB,GAAIojB,EAAJ,EACIsC,EAAA,CA4kBIg7B,CA5kBJr2C,EAAA,CA4kBIq2C,EA1kBR/wC,EAAA,CAAa,YAAb,EA0kBQ+wC,CA1kBqBr2C,EAAAX,MAAAua,GAAA,CAAyB,SAAzB,CAAqC,UAAlE,EACA,MAEJ,MAAK,IAAL,CACsBjkB,IAAAA,EAAlB,GAkdG2yC,CAldC,CAAO,CAAP,CAAJ,GACSlsB,EAAA,CAqkBDi6B,CArkBCr2C,EAAA,CAAkB,CAidxBsoC,CAjdyB,CAAO,CAAP,CAAnB,CADT,EAskBQ+N,CApkBA/wC,EAAA,CAAa,2DAAb,CAFR,CAskBQ+wC,EAjkBR/wC,EAAA,CAAa,gBAAb,EAikBQ+wC,CAjkBwBr2C,EAzqd7BqZ,GAAAiD,QAAA,CAAuB,CAAvB,CAyqdH;AAzqd+B,KAyqd/B,EAA4D,IAA5D,CAikBQ+5B,CAjkB2Dr2C,EArsdhEkZ,GAqsdH,CAAyF,IAAzF,CACA,MAEJ,SACI,GAycGovB,CAzcC,CAAO,CAAP,CAAJ,CAAe,CA6jBP+N,CA5jBJ/wC,EAAA,CAAa,kBAAb,CAwcDgjC,CAxcmC,CAAO,CAAP,CAAlC,CACA,MAFW,CAMnB,KAAK,GAAL,CAujBY+N,CAtjBR/wC,EAAA,CAAa,mBAAb,CAKA,CAijBQ+wC,CArjBR/wC,EAAA,CAAa,mCAAb,CAIA,CAijBQ+wC,CApjBR/wC,EAAA,CAAa,8CAAb,CAGA,CAijBQ+wC,CAnjBR/wC,EAAA,CAAa,mDAAb,CAEA,CAijBQ+wC,CAljBR/wC,EAAA,CAAa,iDAAb,CACA,CAijBQ+wC,CAjjBR/wC,EAAA,CAAa,qCAAb,CA5DJ,CA8mBY,KACJ,MAAK,GAAL,CACI4sC,EAAA,CAAAA,CAAA,CAvHL5J,CAuHkB,CAAO,CAAP,CAAb,CAvHLA,CAuH6B,CAAO,CAAP,CAAxB,CACA,MACJ,MAAK,GAAL,CACI8D,EAAA,CAAAA,CAAA,CA1HL9D,CA0HuB,CAAO,CAAP,CAAlB,CA1HLA,CA0HkC,CAAO,CAAP,CAA7B,CAAwC,CAAxC,CACA,MACJ,MAAK,GAAL,CACI,GAAiB,KAAjB,EA7HLA,CA6HS,CAAO,CAAP,CAAJ,CAAwB,CACfkJ,EAAA,CAAAA,CAAA,CAAW7P,CAAA/uC,OAAA,CAAY,CAAZ,CAAX,CAAL,GACI80B,CADJ,CACa,CAAA,CADb,CAGA,MAJoB,CAMxB,GAAiB,KAAjB;AAnIL4gB,CAmIS,CAAO,CAAP,CAAJ,CAAwB,CACpB,CAAAhjC,EAAA,EAAc0E,EAAd,EAA+B,OAA/B,EAA2F,mBAA3F,CAAkG,CAAAhK,EAAAoe,GAAlG,CAAyL,WAAzL,CACA,EAAA9Y,EAAA,CA5wpBRzN,MAAA,CAAQA,MAAAsD,UAAAD,UAAR,CAAqC,EA4wpB7B,CACA,MAHoB,CAKxBqoC,CAAA,CAAS,CAAA,CACT,MACJ,MAAK,GAAL,CACI,GA3IL+E,CA2IS,CAAO,CAAP,CAAJ,CAAe,CACX2J,EAAA,CAAAA,CAAA,CAAatQ,CAAA/uC,OAAA,CAAY,CAAZ,CAAb,CACA,MAFW,CArwC3B,IAAIjB,GAAI,WAAR,CACSuS,EAAT,KAASA,EAAT,GAAqBoyC,GAArB,CACI3kD,EAAA,EAAK,IAAL,CAAYu8C,EAAA,CAAQhqC,EAAR,CAAkB,CAAlB,CAAZ,CAAmCoyC,EAAA,CAAuBpyC,EAAvB,CAElC8c,GAAA,CAqwCOu1B,CArwCP,CAAL,GAA2B5kD,EAA3B,EAAgC,iDAAhC,CAqwCY4kD,EApwCZjxC,EAAA,CAAa3T,EAAb,CAqwCY,MASJ,SACI4xC,CAAA,CAAS,CAAA,CAvGb,CA0GIA,CAAJ,GACI,CAAAj+B,EAAA,CAAa,mBAAb,CAAmCq8B,CAAnC,CACA,CAAAja,CAAA,CAAS,CAAA,CAFb,CAnH+D,CA3BnE,CAmJF,MAAM72B,EAAN,CAAS,CACP,CAAAyU,EAAA,CAAa,WAAb,EAA4BzU,EAAAmgB,MAA5B,EAAuCngB,EAAAgJ,QAAvC,EACA,CAAA6tB,CAAA,CAAS,CAAA,CAFF,CAIX,MAAOA,EA1JX;AAyKA9L,QAAA,GAAU,CAAVA,CAAU,CAACD,CAAD,CAAQlV,CAAR,CACV,CACiB,IAAb,EAAIkV,CAAJ,GACI,CAAA7X,GADJ,CACqB49B,EAAA,CAAAA,CAAA,CAAkB/lB,CAAlB,CAAyBlV,CAAzB,CADrB,CAIA,KAAA,CAAOk7B,CAAP,CAAc,CAAA79B,GAAA/Q,MAAA,EAAd,CAAA,CACI,GAAI,CAACu8C,EAAA,CAAAA,CAAA,CAAe3N,CAAf,CAAL,CAA2B,MAAO,CAAA,CAEtC,OAAO,CAAA,CARX;AAyGA,IAAA2U,GAAyB,CACrB,IAAY,YADS,CAErB,QAAY,UAFS,CAGrB,QAAY,YAHS,CAIrB,EAAY,cAJS,CAKrB,QAAY,aALS,CAMrB,QAAY,aANS,CAOrB,QAAY,WAPS,CAQrB,EAAY,MARS,CASrB,KAAY,iBATS,CAUrB,UAAY,mBAVS,CAWrB,EAAY,aAXS,CAYrB,GAAY,wBAZS,CAarB,EAAY,UAbS,CAcrB,EAAY,WAdS,CAerB,MAAY,kBAfS,CAgBrB,EAAY,oBAhBS,CAiBrB,MAAY,eAjBS,CAkBrB,EAAY,aAlBS,CAmBrB,QAAY,OAnBS,CAoBrB,QAAY,YApBS,CAqBrB,MAAY,iBArBS,CAsBrB,IAAY,eAtBS,CAAzB,CAkCoDE,GAAQA,EAlC5D,CA+DA7I,GAAwB,sgBAAA,MAAA,CAAA,GAAA,CA/DxB;AAgGI8I,GAAQA,CAhGZ,CAiGIC,GAAQA,CAjGZ,CAkGIC,GAAQA,CAlGZ,CAmGIC,GAAQA,CAnGZ,CAoGIC,GAAQA,CApGZ,CAqGIC,GAAQA,CArGZ,CAsGIC,GAAQA,CAtGZ,CAuGIC,GAAQA,CAvGZ,CAwGIC,GAAQA,CAxGZ,CAyGIC,GAAQA,CAzGZ,CA4GAtH,GAAyB,+BAAA,MAAA,CAAA,GAAA,CA5GzB,CAsHA,GAAwB,EAtHxB,CAsHA3C,IAAwB,EAAA,CA32lBRrjC,KA22lBQ,CAAA,CACE,CAClB,EAjEIutC,GAgEc,CADF,CAAA,EAAA,CAh3lBRvtC,KAg3lBQ,CAAA,CAIG,CACnB,KA9EoDwtC,EA6EjC,CAEnB,KA/EoCC,EA6EjB,CAGnB,KAjFoBC,EA8ED,CAInB,KA1FoCC,EAsFjB,CAKnB,KA3FoDC,EAsFjC,CAMnB,KA5FIC,EAsFe,CAOnB,KA5FIC,EAqFe,CAQnB,KA9FoBC,EAsFD,CASnB,MAxFoDC,EA+EjC,CAUnB,MA3FoDC,EAiFjC,CAWnB,MA5FoBC,EAiFD,CAYnB,MApFoDC,EAwEjC,CAanB,MA3FIC,EA8Ee,CAcnB,MA9FIC,EAgFe,CAenB,MAhGoCC,EAiFjB,CAgBnB,MAvGIC,EAuFe,CAiBnB,MAxGoBC,EAuFD,CAkBnB,MA7FIC,EA2Ee,CAmBnB,MA9FoBC,EA2ED,CAoBnB,MA3FoDC,EAuEjC,CAqBnB,MA5FIC,EAuEe,CAsBnB,MA9FoCC,EAwEjB,CAuBnB,MA7FoCC,EAsEjB,CAwBnB,MA/GoCC,EAuFjB,CAyBnB,MAhHoDC,EAuFjC,CA0BnB,MAhGoDC,EAsEjC,CA2BnB,MAlGoBC,EAuED,CA4BnB,MAnGoCC,EAuEjB,CA6BnB,MAnGIC,EAsEe,CA8BnB,MApGoBC,EAsED,CAJH,CAAA,EAAA,CA/2lBRrvC,KA+2lBQ,CAAA,CAoCG,CACnB,KA7GIsvC,EA4Ge,CAEnB,KAhHoCC,EA8GjB,CAGnB,KA/GoBC,EA4GD,CAInB,KAlHoDC,EA8GjC,CAKnB,KAjHoCC,EA4GjB,CAMnB,KAnHIC,EA6Ge,CAOnB,KAnHoDC,EA4GjC,CAQnB,KArHoBC,EA6GD,CASnB,KAjIIC,EAwHe,CAUnB,KAlIoBC,EAwHD,CAWnB,KAnIoCC,EAwHjB,CAYnB,KAASnM,EAZU;AAanB,KA5HIoM,EA+Ge,CAcnB,KA9HoDC,EAgHjC,CAenB,KA9HoCC,EA+GjB,CAgBnB,KA/HoBC,EA+GD,CAiBnB,MAjIoBC,EAgHD,CAkBnB,MAlIoCC,EAgHjB,CAmBnB,MAxIoBC,EAqHD,CAoBnB,MAxIoDC,EAoHjC,CAqBnB,MAxIIC,EAmHe,CAsBnB,MA1IoBC,EAoHD,CAuBnB,MA1IoBC,EAmHD,CAwBnB,MA7IoDC,EAqHjC,CAyBnB,MA3IoDC,EAkHjC,CA0BnB,MA7IoDC,EAmHjC,CA2BnB,MA9IoCC,EAmHjB,CA4BnB,MA7IIC,EAiHe,CA6BnB,MAjJIC,EAoHe,CA8BnB,MAhJIC,EAkHe,CA+BnB,MAnJoCC,EAoHjB,CAgCnB,MAlJoBC,EAkHD,CAiCnB,MAnJoCC,EAkHjB,CAkCnB,MAvJoCC,EAqHjB,CAmCnB,MA/JIC,CA4He,CAoCnB,MA/JIC,CA2He,CAqCnB,MAjKoBC,CA4HD,CAsCnB,MAjKoBC,CA2HD,CAuCnB,MAnKoCC,CA4HjB,CAwCnB,MAnKoCC,CA2HjB,CAyCnB,MArKoDC,CA4HjC,CA0CnB,MArKoDC,CA2HjC,CA2CnB,MArKIC,CA0He,CA4CnB,MArKIC,EAyHe,CA6CnB,MAvKoBC,EA0HD,CA8CnB,MAvKoBC,EAyHD,CA+CnB,MAzKoCC,EA0HjB,CAgDnB,MAzKoCC,EAyHjB,CAiDnB,MA3KoDC,EA0HjC,CAkDnB,MA3KoDC,EAyHjC,CApCH,CAAA,EAAA,CA92lBRtyC,KA82lBQ,CAAA,CAwFG,CACnB,MAhKoCuyC,EA+JjB,CAEnB,MAjKoDC,EA+JjC,CAGnB,MAjKIC,EA8Je,CAInB,MAlKoBC,EA8JD,CAKnB,MAnKoCC,EA8JjB,CAMnB,MApKoDC,EA8JjC,CAOnB,MApKIC,EA6Je,CAQnB,MArKoBC,EA6JD,CAxFH,CAAA,EAAA,CA72lBR9yC,KA62lBQ,CAAA,CAkGG,CACnB,MAxKoC+yC,EAuKjB,CAEnB,MAzKoDC,EAuKjC,CAGnB,MAzKIC,EAsKe,CAInB,MA1KoBC,EAsKD,CAlGH,CAAA,EAAA,CA52lBRlzC,KA42lBQ,CAAA,CAwGC,CACjB,MA1KImzC,EAyKa,CAEjB,MA3KoBC,EAyKH,CAGjB,MA5KoCC,EAyKnB,CAIjB,MA7KoDC,EAyKnC;AAKjB,MA7KIC,EAwKa,CAMjB,MA9KoBC,EAwKH,CAOjB,MA/KoCC,EAwKnB,CAQjB,MAhLoDC,GAwKnC,CAxGD,CAAA,EAAxBrQ,CAtHA,CA0OAI,GAAwB,CAAC,EAAD,CAAK,GAAL,CAAU,GAAV,CAAe,GAAf,CA1OxB,CA2OAC,GAAwB,kBAAA,MAAA,CAAA,GAAA,CA3OxB,CA4OAC,GAAwB,6CAAA,MAAA,CAAA,GAAA,CA5OxB,CAkQAS,GAAuB,CAhBFuP,CACjB,EAhMQ/E,EA+LS+E,CAEjB,EA7LwBC,GA2LPD,CAGjB,EA9LwCE,GA2LvBF,CAIjB,EA/LwDG,GA2LvCH,CAKjB,EA/LQI,GA0LSJ,CAMjB,EAhMwBK,GA0LPL,CAgBE,CAPFM,CACjB,EAzMwDtF,EAwMvCsF,CAEjB,EArMwCryC,GAmMvBqyC,CAGjB,EAtMwDC,GAmMvCD,CAIjB,GAtMQE,GAkMSF,CAOE,CAlQvB,CAsQA/R,GAA8C,GAtQ9C,CAwQAI,GAAuB,WAKvBv5B,GAAA,CArSAZ,QAAW,EACX,CAEI,IADA,IAAIisC,EAAQr8C,CAAA,CAA6BsQ,QAA7B,CAAuCxQ,CAAvC,CAAuD,UAAvD,CAAZ,CACSw8C,EAAO,CAAhB,CAAmBA,CAAnB,CAA0BD,CAAAlpD,OAA1B,CAAwCmpD,CAAA,EAAxC,CAAgD,CAC5C,IAAIC,EAAOF,CAAA,CAAMC,CAAN,CAAX,CACIld,EAAWz+B,EAAA,CAA4B47C,CAA5B,CACXn+C,EAAAA,CAAM,IAAI4lC,EAAJ,CAAkB5E,CAAlB,CACV1uB,GAAA,CAAgCtS,CAAhC,CAAqCm+C,CAArC,CAJ4C,CAFpD,CAoSA,CA2FAv/C,SAdE0yC,GAcS,CAACtxC,CAAD,CACX,CACI,IAAAA,EAAA,CAAWA,CADf;AA4BAgS,QAAA,GAAI,CAAJA,CAAI,CAAC7Y,CAAD,CAAWyxC,CAAX,CAAqBxzC,CAArB,CACJ,CACI,CAAA+B,GAAA,CAAgBA,CAChB,EAAAyxC,EAAA,CAAgBh2C,CAACg2C,CAADh2C,EAAa,EAAbA,aAAA,EAChB,EAAAwC,KAAA,CAAYA,CAEZ,EAAAgnD,EAAA,CAAY,CACZ,EAAAC,EAAA,CAAa,EAOb,EAAAC,EAAA,CAAe,EAOf,EAAAC,EAAA,CAAe,EA6Bf,EAAAC,EAAA,CAAiB,EAKjB,EAAAC,EAAA,CAAkB,EAKlB,EAAAC,EAAA,CAAiB,EAQjB,EAAAld,EAAA,CAAkB,EAKlB,EAAAmP,EAAA,CAAc,EAUd,EAAAgO,GAAA,CAAe,EAOf,EAAAC,EAAA,CAAiB,EAEjB,EAAAC,GAAA,CAAa,CACb,EAAAC,EAAA,CAAc,CACd,EAAAC,GAAA,CAAgB,CAKhB,EAAAC,EAAA,CAAiB,CAAA7lD,GAAjB,EAAkC,CAKlC,EAAA8lD,GAAA,CAAuB,EAKvB,EAAAC,EAAA,CAAmB,EAEnB,EAAAC,EAAA,CAAiB,IACjB,EAAAC,EAAA,CAAiB,CACjB,EAAAC,EAAA,CAAiB,IACjB,EAAAC,EAAA,CAAmB,CAAAC,EAAnB,CAAuC,EAWvC,EAAAC,GAAA,CAAc,2FAEd,EAAAC,EAAA,CAAiB,IAQjB,EAAAC,EAAA,CAAe,IAKf,EAAAC,EAAA,CAAc,EAEd,EAAA/O,EAAA,CAAiB,IA7IrB;AAgKAW,QAAA,GAAa,CAAbA,CAAa,CAACt6C,CAAD,CAAOkC,CAAP,CAAiByxC,CAAjB,CAA2BxzC,CAA3B,CACb,CACQwzC,CAAJ,EAAyC,CAAzC,EAAgBA,CAAAn4C,QAAA,CAAiB,GAAjB,CAAhB,EA0BAuf,EAAA,CAzBI4tC,CAyBJ,CAzB8BzmD,CAyB9B,CAzBwCyxC,CAyBxC,CAzBkDxzC,CAyBlD,CAOA,CAhCIwoD,CA2BJrB,EAKA,CAhCwBtnD,CA2BTiD,MAAA,CAAY,SAAZ,CAKf,CAhCI0lD,CA4BJtB,EAAAnkD,KAAA,CA5BIylD,CA4BcrB,EAAAxpD,OAAlB,CAIA,CAFA8qD,EAAA,CA9BID,CA8BJ,CAEA,CAhCIA,CAgCAxoD,KAAJ,EAhCIwoD,CAgCWxoD,KAAA,CAhCXwoD,CAgCqBd,EAAV,CAjCf,GAKA9sC,EAAA,CAAAA,CAAA,CAAU7Y,CAAV,CAAoByxC,CAApB,CAA8BxzC,CAA9B,CAIA,CAFA,CAAAinD,EAEA,CAFapnD,CAAAiD,MAAA,CAAW,GAAX,CAEb,CAAA4lD,EAAA,CAAAA,CAAA,CATA,CADJ;AA4CAA,QAAA,GAAgB,CAAhBA,CAAgB,CAChB,CACI,GAAI,CAAA1B,EAAJ,EAAiB,CAAAC,EAAAtpD,OAAjB,CACI8qD,EAAA,CAAAA,CAAA,CACA,CAAI,CAAAzoD,KAAJ,EAAe,CAAAA,KAAA,CAAU,CAAA0nD,EAAV,CAFnB,KAAA,CAOA,IAAI7nD,EAAO,CAAAonD,EAAA,CAAW,CAAAD,EAAX,CAEX,EAAA74C,EAAA,CAAa,UAAb,CAA0B81B,EAAA,CAAgBpkC,CAAhB,CAA1B,CAKwB,EAAxB,CAAIA,CAAAxE,QAAA,CAAa,GAAb,CAAJ,EAEoC,CAFpC,EAEQ,UAAAA,QAAA,CADOwE,CAAAlE,MAAA,CAAY,EAAZ,CAAAs3C,YAAA0V,EACP,CAFR,GAEuC9oD,CAFvC,EAE+C,MAF/C,CAKA2kC,GAAA,CAAgB3kC,CAAhB,CAAsB,IAAtB,CAA4B,CAAA,CAA5B,CAAkC+oD,QAAuB,CAAC3O,CAAD,CAAQ4O,CAAR,CAAmBhoD,CAAnB,CAA+B,CACpF,GAAIA,CAAJ,CAdUovC,CAeFjwC,KAAJ,EAfMiwC,CAeYjwC,KAAA,CAAaa,CAAb,CAAyBo5C,CAAzB,CADtB,KAAA,CAIIjwC,CAAAA,CAAQ6+C,CACZ,IAAIC,EAAA,CAAa7O,CAAb,CAAoB,OAApB,CAAJ,CAAkC,CAI9BjwC,CAAA,CAAQ,EAJsB,KAK1BnO,CACJ,KADWwQ,CACX,CADgB,0BAChB,CAAOxQ,CAAP,CAAewQ,CAAA7H,KAAA,CAAQqkD,CAAR,CAAf,CAAA,CACQruD,CAEJ,CAFQqB,CAAA,CAAM,CAAN,CAER,CADsB,CACtB,EADIrB,CAAAa,QAAA,CAAU,MAAV,CACJ,GADyBb,CACzB,CAD6BA,CAAAc,QAAA,CAAU,QAAV,CAAoB,MAApB,CAAAA,QAAA,CAAiC,QAAjC,CAA2C,MAA3C,CAAAA,QAAA,CAAwD,SAAxD,CAAmE,MAAnE,CAC7B,EAAA0O,CAAA,EAASxP,CAGb,EADAqB,CACA,CADQmO,CAAAnO,MAAA,CAAY,WAAZ,CACR,GAAWktD,EAAA,CA/BL9Y,CA+BK,CAAgB,4BAAhB,CAA+Cp0C,CAAA,CAAM,CAAN,CAA/C;AAA0D,GAA1D,CAZmB,CAsB9BsrD,CAAAA,CAAUn9C,CAAAlH,MAAA,CAAY,SAAZ,CACd,IAAIqkD,CAAAxpD,OAAJ,CAAqB,CAArB,CAEI,IADAnD,CACA,CADI2sD,CAAAzb,IAAA,EACJ,CACIqd,EAAA,CA7CE9Y,CA6CF,CAAgB,mBAAhB,CAAsCz1C,CAAtC,CAA0C,GAA1C,CAEA,CADA2sD,CAAApkD,KAAA,CAAavI,CAAb,CACA,CAAA2sD,CAAApkD,KAAA,CAAa,EAAb,CAHJ,CAFJ,IAQIgmD,GAAA,CAlDM9Y,CAkDN,CAAgB,8BAAhB,CAAiDkX,CAAAxpD,OAAjD,CAAkE,GAAlE,CAlDMsyC,EAqDVkX,EAAA,CArDUlX,CAqDQkX,EAAA71C,OAAA,CAAuB61C,CAAvB,CArDRlX,EAsDViX,EAAA,CAtDUjX,CAsDM+W,EAAhB,CAAA,CAAiCG,CAAAxpD,OAAjC,EAAmD,CAtDzCsyC,EAuDV+W,EAAA,EAEAjiD,WAAA,CAAW,QAAQ,EAAG,CAClB2jD,EAAA,CA1DMzY,CA0DN,CADkB,CAAtB,CAEG,CAFH,CA3CA,CADoF,CAAxF,CAnBA,CADJ;AAwGAwY,QAAA,GAAc,CAAdA,CAAc,CACd,CAMI,GAAkC,CAAlC,EAAI,CAAAjV,EAAAn4C,QAAA,CAAsB,GAAtB,CAAJ,CACI,CAAA8S,EAAA,CAAa,CAAAg5C,EAAA7Z,KAAA,CAAkB,EAAlB,CAAb,CADJ,KAAA,CAKA,IAAIh0C,EAAI20C,EAAA,CAAA,CAAArlC,EAAA,CAKRogD,GAAA,CAAAA,CAAA,CAAe,KAAf,CAAsB,CAAtB,CACAA,GAAA,CAAAA,CAAA,CAAe,IAAf,CAAsB,CAAtB,CAEA,IAAI,CACA,IAAK,IAAIlvD,EAAI,CAAb,CAAgBA,CAAhB,CAAoB,CAAAqtD,EAAAxpD,OAApB,CAAyC7D,CAAzC,EAA8C,CAA9C,CAAiD,CAE7C,CAAA2tD,GAAA,EAKkC,EAAlC,EAAI,CAAAjU,EAAAn4C,QAAA,CAAsB,GAAtB,CAAJ,EACI,CAAA8S,EAAA,CAAa86C,EAAA,CAAAA,CAAA,CAAb,CAAiC,IAAjC,CAAwC,CAAA9B,EAAA,CAAartD,CAAb,CAAxC,CASJ,IAAI,CAACovD,EAAA,CAAAA,CAAA,CAAe,CAAA/B,EAAA,CAAartD,CAAb,CAAf,CAAiC,MAAjC,CAAL,CAA+C,KAM/C,IAAuB,IAAvB,GAAI,CAAA0/C,EAAJ,CAA6B,KAvBgB,CA0B7C,CAAAwO,EAAJ,EACI,CAAAv/C,MAAA,CAAW,YAAX,CAAyB,CAAA2+C,EAAA,CAAe,CAAAa,EAAf,CAAAR,GAAzB,CAGA,EAAAK,EAAAnqD,OAAJ,EACI,CAAA8K,MAAA,CAAW,YAAX,CAAyB,CAAAq/C,EAAA,CAAiB,CAAjB,CAAAL,GAAzB,CAMJ0B,GAAA,CAAAA,CAAA,CAKAC,GAAA,CAAAA,CAAA,CAKA,EAAA7B,GAAA3N,QAAA,CAAqByP,QAAqB,CAACzlD,CAAD,CAASgkD,CAAT,CAAoB,CACtD1rD,CAAAA,CAAQixC,EAAA,CAnEN8C,CAmEM,CAAwBrsC,CAAxB,CAAgCpF,IAAAA,EAAhC,CAA2CopD,CAA3C,CAnEN3X,CAmE4DuX,EAAA,CAAkBI,CAAlB,CAAtD,CACEppD,KAAAA,EAAd,GAAItC,CAAJ,GACAA,CACA,EAtEM+zC,CAqEGsJ,EAAA,CAAeqO,CAAf,CACT,CAtEM3X,CAsENsJ,EAAA,CAAeqO,CAAf,CAAA,CAA4B9c,EAAA,CAtEtBmF,CAsEsB,CAAiB/zC,CAAjB,CAAwB0rD,CAAxB,CAF5B,CAF0D,CAA9D,CAhDA,CAuDF,MAAMpnD,CAAN,CAAW,CACT,CAAA2N,EAAA,CAAa3N,CAAAkC,QAAb,CACA,CAAA,CAAAglD,EAAA,CAAe,EAFN,CAKoB,CAAjC,CAAI,CAAAlU,EAAAn4C,QAAA,CAAsB,GAAtB,CAAJ,GAAoC,CAAAuN,EAj5JpCwhC,EAi5JA,CAA8D9wC,CAA9D,CAzEA,CANJ;AA8FA4vD,QAAA,GAAS,CAATA,CAAS,CAACjS,CAAD,CAAQ5yC,CAAR,CAAgBilD,CAAhB,CAAyBC,CAAzB,CACT,CAAA,IACQzvD,CAEgB,KAApB,EAAI,CAAAwuD,EAAJ,GACIrR,CADJ,CACYuS,EAAA,CAAAA,CAAA,CAAcvS,CAAd,CADZ,CAOA,KAHA,IAAIwS,EAAS,CAAA,CAAb,CACY1B,EAAY,EAExB,CAAO0B,CAAP,CAAA,CAAe,CACX,IAAAC,EAAYzS,CAAAp7C,MAAA,CAAY,CAAAusD,GAAZ,CACZ,IAAI,CAACsB,CAAL,EAAkBA,CAAA,CAAU,CAAV,CAAlB,EAA8D,GAA9D,EAAkCA,CAAA,CAAU,CAAV,CAAA/tD,OAAA,CAAmB,CAAnB,CAAlC,CAEI,MADA,EAAA8M,MAAA,CAAW,wBAAX,CAAsCwuC,CAAtC,CAA8C,GAA9C,CACO,CAAA,CAAA,CAEXwS,EAAA,CAAS,CAAA,CACT1B,EAAA,CAAY2B,CAAA,CAAU,CAAV,CAAAzW,YAAA,EAUZ,IAAI8U,CAAJ,EAAiB4B,EAAjB,EAA0C5B,CAA1C,EAAuD6B,EAAvD,CACIvlD,CAAA,CAAS,IAGb,IAAIA,CAAJ,CAAY,CACR,IAASwlD,CAAT,CAAiB,CAAjB,CAAoBA,CAApB,CAA4BxlD,CAAA1G,OAA5B,CAA2CksD,CAAA,EAA3C,CAAoD,CAChD,IAAI3lD,EAAQG,CAAA,CAAOwlD,CAAP,CAAZ,CAEIC,EAAW,CAAA1C,EAAA,CAAe,CAAAa,EAAf,CACf,IAAI,EAAA6B,CAAA,EAA8C,CAA9C,EAAYA,CAAAzlD,GAAAhJ,QAAA,CAAwB6I,CAAxB,CAAZ,CAAJ,CAAA,CAEI0uC,CAAAA,CAAW0W,CAAA,CAAQO,CAAR,CAAXjX,EAA6B2W,CAAA,CAAUM,CAAV,CAA7BjX,EAAiD,EAGrD,KAFA,IAAImX,EAAU,CAAd,CACI7d,EAAS+K,CAAAt5C,OAATuuC,CAAwBwd,CAAA,CAAU,CAAV,CAAA/rD,OAC5B,CAAOosD,CAAP,CAAiB7d,CAAjB,CAAA,CAAyB,CACrB,IAAI8d,EAAS/S,CAAA57C,QAAA,CAAc6I,CAAd,CAAqB6lD,CAArB,CACb,IAAa,CAAb,CAAIC,CAAJ,CAAgB,KAChBD,EAAA,CAAUC,CAAV,CAAmB,CACnB,KAAIC,EAAYD,CAAZC,CAAqB/lD,CAAAvG,OAAzB,CACIusD,GAAQ,EADZ,CACgBC,GAAS,EACnBH,EAAN,EAqwBPnuD,CArwB0CquD,EAqwB1CruD,CArwBkDo7C,CAAA,CAAM+S,CAAN,CAAe,CAAf,CAqwBlDnuD,OAAA,CAAS,cAAT,CArwBO,EAAmE,EAAAouD,CAAA,EAAahT,CAAAt5C,OAAb,CAAnE,EAqwBP9B,CArwB0HsuD,EAqwB1HtuD,CArwBmIo7C,CAAA,CAAMgT,CAAN,CAqwBnIpuD,OAAA,CAAS,cAAT,CArwBO;CAIiB,GAIb,EAJIquD,EAIJ,EAJkBF,CAAA,EAIlB,CAHc,GAGd,EAHIG,EAGJ,EAHmBF,CAAA,EAGnB,CAFAhT,CAEA,CAFQA,CAAAx7C,OAAA,CAAa,CAAb,CAAgBuuD,CAAhB,CAER,CAFkCpX,CAElC,CAF6CqE,CAAAx7C,OAAA,CAAawuD,CAAb,CAE7C,CADAF,CACA,CADUC,CACV,CADmBpX,CAAAj1C,OACnB,CAAA8rD,CAAA,CAAS,CAAA,CARb,CANqB,CALzB,CAJgD,CA2BpDplD,CAAA,CAAS,IA5BD,CA8BZ,GAAI,CAAA2jD,EAAJ,GAC0B,CAalBA,EAbA,CAAAA,EAaAA,GAZAluD,CACA,CADIm9C,CAAA57C,QAAA,CAAc,CAAA6sD,EAAd,CACJ,CAAS,CAAT,EAAIpuD,CAAJ,EACI,CAAAkuD,EAAA,EACA,CAAA/Q,CAAA,CAAQA,CAAAx7C,OAAA,CAAa3B,CAAb,CAAe,CAAf,CAFZ,EAII,CAAA2O,MAAA,CAAW,WAAX,CAAyB,CAAAs/C,EAAzB,CAA0C,kBAA1C,CAA+D9Q,CAA/D,CAAuE,GAAvE,CAOJ+Q,EAJiB,CAIjBA,CAJA,CAAAA,EAIAA,GAHA/Q,CACA,CADQmT,EAAA,CAAAA,CAAA,CAAiBnT,CAAjB,CACR,CAAAwS,CAAA,CAAS,CAAA,CAETzB,EAAA,CAAAA,EAdR,EAcwB,MAAO,CAAA,CAjEpB,CAqEftM,CAAA,CAASgO,CAAA,CAAU,CAAV,CACTW,EAAA,CAAaX,CAAA,CAAU,CAAV,CACbtS,EAAA,CAAYsS,CAAA,CAAU,CAAV,CAAAzrD,KAAA,EACZqsD,EAAA,CAAaZ,CAAA,CAAU,CAAV,CAAb,CAA4BA,CAAA,CAAU,CAAV,CAExBhO,EAAJ,GACIA,CACA,CADSA,CAAA//C,MAAA,CAAa,CAAb,CAAiB,EAAjB,CACT,CAAAqtD,EAAA,CAAAA,CAAA,CAAetN,CAAf,CAAuB,CAAAkM,EAAvB,CAAuC2C,EAAvC,CAFJ,CAKA,KAAIC,CACAzC,EAAJ,GAAkByC,CAAlB,CAA4BpT,CAAAv7C,MAAA,CAAgB,cAAhB,CAA5B,IACQ4uD,CAWJ,CAXY,CAWZ,CAVA/O,CAUA,CAVSqM,CAUT,CATAA,CASA,CATYyC,CAAA,CAAQ,CAAR,CASZ,CARApT,CAQA,CARYoT,CAAA,CAAQ,CAAR,CAQZ,CAPiB,UAAjB,EAAIzC,CAAJ,CACI0C,CADJ,EA62CIC,CA72CJ,CAGsB,OAHtB,EAGS3C,CAHT,GAII0C,CAJJ,EAIaE,EAJb,CAOA,CADA3B,EAAA,CAAAA,CAAA,CAAetN,CAAf,CAAuBtE,CAAvB,CAAkCqT,CAAlC,CACA,CAAA1C,CAAA,CAAY3Q,CAAZ,CAAwB,EAZ5B,CAeA,IAAI,CAAC2Q,CAAL,EAAkB,CAAC3Q,CAAnB,CAA8B,MAAO,CAAA,CAErC,EAAA2Q,EAAA,CAAiBA,CAQjB,IADI6C,CACJ,CADeC,EAAA,CAAAA,CAAA,CAAgBzT,CAAhB,CACf,CACIA,CACA,CADYA,CAAA97C,QAAA,CAAkBsvD,CAAlB,CAA4BE,EAAA,CAAAA,CAAA,CAAcC,EAAd,CAAyCF,EAAA,CAAAA,CAAA,CAAgBP,CAAhB,CAAzC,CAA5B,CACZ;AAAKD,CAAL,GAAiBA,CAAjB,CAA8B,IAA9B,CAOJ,KAAA,CAAOvX,CAAP,CAAiBkY,EAAA,CAAAA,CAAA,CAAiB5T,CAAjB,CAAjB,CAAA,CACIA,CAAA,CAAYA,CAAA97C,QAAA,CAAkBw3C,CAAlB,CAA2BA,CAAAn3C,MAAA,CAAc,CAAd,CAAkB,EAAlB,CAA3B,CAGhB,IAAI,CAACsvD,EAAA,CAAAA,CAAA,CAAgBlD,CAAhB,CAA2B3Q,CAA3B,CAAL,CAEI,OAAQ2Q,CAAR,EACA,KAAKmD,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACI5B,EAAA,CAAAA,CAAA,CAAcc,CAAd,CACA,MAEJ,MAAKe,EAAL,CACkBjU,CAAAA,CAAAA,CA88BlBx8C,EAAAA,CAAIuyC,EAAA,CA98BAme,CA88BA,CAAqBlU,CAArB,CACE54C,KAAAA,EAAV,GAAI5D,CAAJ,EAA4B,CAA5B,EAAuBA,CAAvB,EAAsC,MAAtC,EAAiCA,CAAjC,CA/8BQ0wD,CAg9BJ1D,EADJ,EACsBhtD,CADtB,CA/8BQ0wD,CAk9BJ7iD,MAAA,CAAW,iCAAX,CAA+C2uC,CAA/C,CAA2D,GAA3D,CAj9BI,MAEJ,MAAKmU,EAAL,CACiBnU,CAAAA,CAAAA,CA69BNoU,EAAAA,CAAX1hB,CAAW0hB,CAAH,CAEZ,KAF2BC,CAE3B,CAF4C,EAE5C,CAAO/U,CAAP,CAAkBgV,EAAA,CA/9BVC,CA+9BU,CAAmBvU,CAAnB,CAAlB,CAAA,CAAiD,CAC7CA,CAAA,CAAYA,CAAA37C,OAAA,CAAiBi7C,CAAA/4C,OAAjB,CAAAM,KAAA,EACR2F,EAAAA,CAAS8yC,CAEb,IADI76C,CACJ,CADY66C,CAAA76C,MAAA,CAAe,mBAAf,CACZ,CACQA,CAAA,CAAM,CAAN,CACJ,GADciuC,CACd,CADsBqD,EAAA,CAp+BtBwe,CAo+BsB,CAAqB,IAArB,CAA4B9vD,CAAA,CAAM,CAAN,CAA5B,CACtB,EAAA+H,CAAA,CAAS/H,CAAA,CAAM,CAAN,CAEb,IAAKiuC,CAAL,CAAA,CAQInvC,CAAAA,CAAIiJ,CAAA,CAAQupC,EAAA,CA/+BZwe,CA++BY,CAAqB/nD,CAArB,CAAR,CAAuC,CAC/C,IAAUpF,IAAAA,EAAV,GAAI7D,CAAJ,EAA+B,CAA/B,CAAuBmvC,CAAvB,EAA4C,EAA5C,CAAoCA,CAApC,CAAgD,CAh/B5C6hB,CAi/BAljD,MAAA,CAAW,2BAAX,CAAyCiuC,CAAzC,CACA,MAF4C,CAIhD/7C,CAAA,CAAImwC,CAAA,CAp/BA6gB,CAo/BA/iD,EAAA,CAAkBjO,CAAlB,CAAqBmvC,CAArB,CAA4B,CAAA,CAA5B,CACA2hB,EAAJ,CAAqB3hB,CAArB,GACI8hB,EAAA,CAt/BAD,CAs/BA,CAAaH,CAAb,CAEA,CADAA,CACA,CADS,CACT,CAAAC,CAAA,CAAiB,EAHrB,CAKAD,EAAA;AAAU7wD,CAAV,CAAcoB,IAAAC,IAAA,CAAS,CAAT,CAAYyvD,CAAZ,CAA6B3hB,CAA7B,CACd2hB,EAAA,EAAkB3hB,CApBlB,CAAA,IAKI8hB,GAAA,CA5+BAD,CA4+BA,CAAa,CAAb,CAbyC,CA8B5B,EAArB,CAAIF,CAAJ,EACIG,EAAA,CA9/BID,CA8/BJ,CAAaH,CAAb,CA7/BI,MAEJ,MAAKK,EAAL,CAygCJ,CAxgCoBzU,CAwgCpB,CAxgCoBA,CAwgCpB,GAxgCQ0U,CA2gCJtS,EACA,CADiBrM,EAAA,CA3gCb2e,CA2gCa,CAAqB1U,CAArB,CACjB,CAAuB54C,IAAAA,EAAvB,GA5gCIstD,CA4gCAtS,EAAJ,EA5gCIsS,CA6gCArjD,MAAA,CAAW,+BAAX,CAA6C2uC,CAA7C,CAAyD,GAAzD,CALR,EAxgCQ0U,CAygCJtS,EADJ,CAxgCQsS,CAygCa/pD,GAxgCb,MAEJ,MAAKgqD,EAAL,CACIC,EAAA,CAAAA,CAAA,CAAa5U,CAAb,CACA,MAEJ,MAAK6U,EAAL,CACI9C,EAAA,CAAAA,CAAA,CACA,MAEJ,MAAK+C,EAAL,CACIC,CAghCRvE,EAAA,CAAiBza,EAAA,CAhhCTgf,CAghCS,CAhhCQ/U,CAghCR,CAAjB,EAAoD,CA/gC5C,MAEJ,MAAKgV,EAAL,CACIhD,EAAA,CAAAA,CAAA,CACA,MAEJ,MAAKiD,EAAL,CAyhCJL,EAAA,CAxhCQM,CAwhCR,CAxhCoBlV,CAwhCP97C,QAAA,CAAkB,GAAlB,CAAuB,IAAvB,CAAb,CAvhCQ,MAEJ,MAAKixD,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKvD,EAAL,CACA,KAAKC,EAAL,CACA,KAAKuD,EAAL,CACA,KAAKC,EAAL,CACItC,EAAA,CAAAA,CAAA,CAAc/C,CAAd,CAAyBuC,CAAzB,CACA,MAEJ,MAAK+C,EAAL,CAwiCA/D,CAAAA,CAAUgE,EAAA,CAviCNC,CAuiCM,CAviCUnW,CAuiCV,CACd,KAASt9C,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoBwvD,CAAA3rD,OAApB,CAAoC7D,CAAA,EAApC,CAnmMA,OA2jKQyzD,CAyiCJ3kD,EApmMGwhC,EAAA,CAomMkBkf,CAAA1b,CAAQ9zC,CAAR8zC,CApmMlB,CAqmMH,CAAA,OA1iCI2f,CA0iCGlG,EAAA,CAAgBiC,CAAA,CAAQxvD,CAAR,CAAhB,CAziCH;KAEJ,MAAK0zD,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACI,KAEJ,SACI/B,EAAA,CAAAA,CAAA,CAAajE,CAAb,CAAwBsC,CAAxB,CAAoCjT,CAApC,CAzEJ,CA6EJ,MAAO,CAAA,CA/MX;AA0PA6T,QAAA,GAAU,CAAVA,CAAU,CAACpjD,CAAD,CAAOuvC,CAAP,CACV,CACI,IAAI4W,EAAQ,CAAA5G,EAAA,CAAev/C,CAAf,CACZ,IAAI,CAACmmD,CAAL,CAAY,MAAO,CAAA,CAEnB,IAAiB,IAAjB,EAAI5W,CAAJ,CAAuB,CAKnB,GAAI4W,CAAAC,GAAJ,EAAsBC,EAAtB,CAA8C,CAE1C,IAAItG,EAAY,CAAAA,EAChBuG,EAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CACA,IAAI49C,CAAJ,CAAgB,CAAAA,EAAhB,CAAgC,CAK5B,GAAI,CAACxQ,CAAL,CAAgB,MAAO,CAAA,CAEvBgX,GAAA,CAAAA,CAAA,CACAD,EAAA,CAAAA,CAAA,CAAe/W,CAAf,CACIx8C,EAAAA,CAAI,CAAA2+C,EAAA,CAAY,CAAZ,CACR,KAAI8U,EAAS,CAAA9G,GAAA,CAAa,CAAb,CACb+G,GAAA,CAAAA,CAAA,CACA,IAAU9vD,IAAAA,EAAV,GAAI5D,CAAJ,CAeI,MAdA,EAAA2+C,EAAA,CAAYqO,CAAZ,CAcO,EAdoBhtD,CAcpB,CAdyB,SAczB,CARP,CAAA2+C,EAAA,CAAYqO,CAAZ,CAQO,EARoBhtD,CAQpB,CAxynBX6X,OAwynBW,CAPH47C,CAOG,GAHC,CAAA9G,GAAA,CAAaK,CAAb,CAGD,CANE,CAAAL,GAAA,CAAaK,CAAb,CAAL,CAGI,CAAAL,GAAA,CAAaK,CAAb,CAHJ,EAG+B,GAH/B,CAGqCyG,CAHrC,EAC8BA,CAK3B,EAAA,CAAA,CA3BiB,CAkChC,CAAA5lD,MAAA,CAAW,SAAX,CAAuBZ,CAAvB,CAA8B,KAA9B,CAAsCuvC,CAAtC,CAAkD,UAAlD,CACA,OAAO,CAAA,CAvCmC,CAyC1CmX,CAAAA,CAAY,CAAAlG,EAChB,EAAAA,EAAA,CAAiB2F,CACjBA,EAAA1E,GAAA,CAAgBgE,EAAA,CAAAA,CAAA,CAAelW,CAAf,CAA0B,CAAA,CAA1B,CAChB+W,EAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CAA4BgkD,CAAA3pD,GAA5B,CAA0C2pD,CAAA1E,GAA1C,CAAyD0E,CAAAzE,GAAzD,CAQA,EAAAlB,EAAA,CAAiBkG,CACjB,OAAO,CAAA,CA1DY,CA6DvB,GAAe,GAAf,EAAI1mD,CAAA,CAAK,CAAL,CAAJ,CAAoB,MAAO,CAAA,CAI3B,QAFgBA,CAAApM,OAAAssD,CAAY,CAAZA,CAEhB,EACA,KAAK4E,EAAL,CACA,KAAKD,EAAL,CACA,KAAKQ,EAAL,CACSc,CAAAC,GAAL,EACIE,CAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CAEJ,MAEJ,MAAK4iD,EAAL,CACyB,CAArB,CAAIoB,CAAAC,GAAJ,EACIE,CAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CAEJ,MAEJ,MAAK6iD,EAAL,CAC0B,CAAtB;AAAImB,CAAAC,GAAJ,EACIE,CAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CAEJ,MAEJ,MAAK+iD,EAAL,CACyB,CAArB,CAAIiB,CAAAC,GAAJ,EACIE,CAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CAEJ,MAEJ,MAAKgjD,EAAL,CAC0B,CAAtB,EAAIgB,CAAAC,GAAJ,EACIE,CAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CAEJ,MAEJ,MAAKwiD,EAAL,CACA,KAAKS,EAAL,CACA,KAAKR,EAAL,CACA,KAAKK,EAAL,CACQkB,CAAAC,GAAJ,EACIE,CAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CAEJ,MAEJ,MAAK2/C,EAAL,CACA,KAAKC,EAAL,CACI,IAAS9vD,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoBk0D,CAAA1E,GAAA3rD,OAApB,CAA0C7D,CAAA,EAA1C,CACIq0D,CAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CAA4BgkD,CAAA3pD,GAA5B,CAA0C,CAAC2pD,CAAA1E,GAAA,CAAcxvD,CAAd,CAAD,CAA1C,CAA8D,EAA9D,CAEJ,MAEJ,MAAKszD,EAAL,CACI,IAAA,CAA0B,CAA1B,CAAOY,CAAAC,GAAA,EAAP,CAAA,CACIE,CAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CAEJ,MAEJ,SAC4BA,CAzJ5B,CAyJ4BgkD,CAAAhkD,GAzJ5B,CAFAokD,EAAA,CA2JII,CA3JJ,CA2JsB3mD,CA3JtB,CAEA,CADAsmD,CAAA,CA0JIK,CA1JJ,CAAexkD,CAAf,CACA,CAAAskD,EAAA,CAyJIE,CAzJJ,CAiGA,CA2DA,MAAO,CAAA,CAhIX,CA4IAL,QAAA,EAAS,CAATA,CAAS,CAACnkD,CAAD,CAAQ3F,CAAR,CAAgBilD,CAAhB,CAAyBC,CAAzB,CACT,CASQpC,CAAAA,CAAUn9C,CAAAlH,MAAA,CAAY,OAAZ,CACd,KAAK,IAAI2rD,EAAQ,CAAjB,CAAoBA,CAApB,CAA4BtH,CAAAxpD,OAA5B,EAESurD,EAAA,CAAAA,CAAA,CADO/B,CAAA,CAAQsH,CAAR,CACP,CADwB,MACxB,CAAsBpqD,CAAtB,CAA8BilD,CAA9B,CAAuCC,CAAvC,CAFT,CAA4CkF,CAAA,EAA5C,EAVJ;AAsBAL,QAAA,GAAS,CAATA,CAAS,CAACvmD,CAAD,CACT,CACI,CAAAigD,EAAA/kD,KAAA,CAAsB,CAClB8E,KAAAA,CADkB,CAElB0xC,EAAQ,CAAAA,EAFU,CAGlBgO,GAAS,CAAAA,GAHS,CAIlBK,EAAW,CAAAA,EAJO,CAKlBC,GAAgB,CAAAA,GALE,CAMlBJ,GAAO,CAAAA,GANW,CAAtB,CAQA,EAAAlO,EAAA,CAAc,EACd,EAAAgO,GAAA,CAAe,EACW,EAA1B,CAAI,CAAAM,GAAJ,GAA6B,CAAAA,GAA7B,CAAmD,CAAAD,EAAnD,CACA,EAAAA,EAAA,CAAiB,CAZrB,CAoBA0G,QAAA,GAAQ,CAARA,CAAQ,CACR,CACI,GAAK,CAAAxG,EAAAnqD,OAAL,CAAA,CAIA,IAAIkK,EAAO,CAAAigD,EAAA,CAAiB,CAAAA,EAAAnqD,OAAjB,CAA2C,CAA3C,CAAAkK,KACPA,EAAJ,EAAU,CAAAy/C,EAAAvkD,KAAA,CAAoB,CAAC8E,KAAAA,CAAD,CAAO0xC,EAAQ,CAAAA,EAAf,CAA4BgO,GAAS,CAAAA,GAArC,CAApB,CACNmH,EAAAA,CAAQ,CAAA5G,EAAApc,IAAA,EACZ,EAAA6N,EAAA,CAAcmV,CAAAnV,EACd,EAAAgO,GAAA,CAAemH,CAAAnH,GACf,EAAAK,EAAA,CAAiB8G,CAAA9G,EACjB,EAAAC,GAAA,CAAsB6G,CAAA7G,GACjB,EAAAC,EAAAnqD,OAAL,EAAwD,EAAxD,EAAgC,CAAAkqD,GAAhC,EACI,CAAAp/C,MAAA,CAAW,qBAAX,CAZJ,CAAA,IACI,EAAAA,MAAA,CAAW,qBAAX,CAFR;AA4BAijD,QAAA,GAAa,CAAbA,CAAa,CAACtU,CAAD,CACb,CADyB,IAAAwE,EAAA,IAAA,EAAA,GAAAA,CAAA,CAAS,GAAT,CAAAA,CAMrB,KAJA,IAAI9hD,EAAI,CAAR,CACI60D,EAAU,CAAA,CADd,CAEIjY,EAAW,IAFf,CAGIkY,EAAW,CACf,CAAO90D,CAAP,CAAWs9C,CAAAz5C,OAAX,CAAA,CAA6B,CACzB,IAAIpC,EAAK67C,CAAA,CAAUt9C,CAAA,EAAV,CACT,IAAU,GAAV,EAAIyB,CAAJ,CACIozD,CAAA,CAAU,CAACA,CADf,KAIA,IAAIA,CAAAA,CAAJ,CAAA,CACA,GAAI,CAACC,CAAL,EAAuC,CAAvC,EAAiBhT,CAAAvgD,QAAA,CAAeE,CAAf,CAAjB,CAA0C,CACtCzB,CAAA,EACA,MAFsC,CAI1C,GAAU,MAAV,EAAIyB,CAAJ,CACIqzD,CAAA,EADJ,KAEO,IAAU,MAAV,EAAIrzD,CAAJ,EACc,CADd,CACC,EAAEqzD,CADH,CACiB,CAChB,CAAAnmD,MAAA,CAAW,yBAAX,CAAuC2uC,CAAvC,CAAmD,GAAnD,CACA,MAFgB,CARxB,CANyB,CAoBxBwX,CAAL,CAGoB,CAHpB,CAGSA,CAHT,EAII,CAAAnmD,MAAA,CAAW,uBAAX,CAAqC2uC,CAArC,CAAiD,GAAjD,CAJJ,CACIV,CADJ,CACeU,CAAA37C,OAAA,CAAiB,CAAjB,CAAoB3B,CAApB,CAKf,OAAO48C,EA/BX;AAiDAvJ,QAAA,GAAe,CAAfA,CAAe,CAACH,CAAD,CAAOb,CAAP,CAAmByb,CAAnB,CAA8BH,CAA9B,CACf,CACI,IAAIl3B,EAAU,EAEI/xB,KAAAA,EAAlB,GAAIopD,CAAJ,GACIA,CADJ,CACwC,CAAvB,EAAA,CAAAC,GAAA,CAA0B,CAAAA,GAA1B,CAAgD,CAAAD,EADjE,CASA,KAAIiH,EAAQ7hB,CAAA1xC,QAAA,CAAa,uBAAb,CAAsC,MAAtC,CAAAA,QAAA,CAAsD,sBAAtD,CAA8E,MAA9E,CAOZ,IAAI6wC,CAAJ,CAAgB,CAEZ,IAAI4b,EAAY,EAAhB,CACI3Q,EAAYyX,CAChB,IAAIhzD,CAAJ,CAAYgzD,CAAAhzD,MAAA,CAAY,uBAAZ,CAAZ,CACIksD,CACA,CADYlsD,CAAA,CAAM,CAAN,CACZ,CAAAu7C,CAAA,CAAYv7C,CAAA,CAAM,CAAN,CAEhB00B,EAAA,CAAS2mB,EAAA,CAAA,CAAAtuC,EAAA,CAA0Bm/C,CAA1B,CAAqC3Q,CAArC,CAAgDwQ,CAAhD,CAA2Dzb,CAA3D,CARG,CAWH,CAAb,CAAI5b,CAAJ,GAYIs+B,CAEA,CAFQA,CAAAvzD,QAAA,CAAc,eAAd,CAA+B6jB,CAAA,CAAA,CAAAvW,EAAA,CAAmBg/C,CAAnB,CAA+B,EAA/B,CAA/B,CAAmE,IAAnE,CAER,CADAr3B,CACA,CADS4c,EAAA,CAAA,CAAAvkC,EAAA,CAAyBimD,CAAzB,CAAgC1iB,CAAhC,CACT,CAAe3tC,IAAAA,EAAf,GAAI+xB,CAAJ,EACI,CAAA9nB,MAAA,CAAW,8BAAX,CAA4CukC,CAA5C,CAAmD,GAAnD,CAAwDya,CAAxD,CAfR,CAkBA,OAAOl3B,EAhDX;AA4DAs6B,QAAA,GAAU,CAAVA,CAAU,CAACzT,CAAD,CACV,CAII,IAHA,IAAIwX,EAAW,CAAf,CACIhE,EAAW,EADf,CAEI9wD,EAAI,CAFR,CAEWg1D,EAAU,EAFrB,CAEwBC,EAAO3X,CAAAz5C,OAC/B,CAAO7D,CAAP,CAAWs9C,CAAAz5C,OAAX,CAAA,CAA6B,CACzB,IAAIpC,EAAK67C,CAAA,CAAUt9C,CAAV,CACT,IAAU,GAAV,EAAIyB,CAAJ,CAAe,KACL,IAAV,EAAIA,CAAJ,GACSqzD,CAAA,EADT,GACqBE,CADrB,CAC8Bh1D,CAD9B,EAGAA,EAAA,EACA,IAAU,GAAV,EAAIyB,CAAJ,EAA+B,CAA/B,EAAiB,EAAEqzD,CAAnB,CAAkC,CAC9BG,CAAA,CAAOj1D,CACP,MAF8B,CAPT,CAYd,CAAf,CAAI80D,CAAJ,EACI,CAAAnmD,MAAA,CAAW,yBAAX,CAAuC2uC,CAAvC,CAAmD,GAAnD,CAEU,EAAd,EAAI0X,CAAJ,GACIlE,CADJ,CACexT,CAAA37C,OAAA,CAAiBqzD,CAAjB,CAAyBC,CAAzB,CAAgCD,CAAhC,CADf,CAGA,OAAOlE,EAtBX,CAwDA3B,QAAA,GAAU,CAAVA,CAAU,CAACxB,CAAD,CACV,CADWA,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAQ,CAAAA,GAAR,CAAAA,CAGP,KADA,IAAIT,EAAO,CACX,CAAOS,CAAP,CAAe,CAAAP,EAAA,CAAaF,CAAb,CAAf,CAAA,CAEI,GADAS,CACI,EADK,CAAAP,EAAA,CAAaF,CAAb,CACL,CAAAA,CAAA,CAAO,CAAAC,EAAAtpD,OAAP,CAA2B,CAA/B,CACIqpD,CAAA,EADJ,KAGI,MAGR,OAAO/iB,GAAA,CAAgB,CAAAgjB,EAAA,CAAWD,CAAX,CAAhB,CAAmC,QAAnC,CAA8CS,CAA9C,CAVX;AAsBAuD,QAAA,GAAW,CAAXA,CAAW,CAAC5T,CAAD,CACX,CACI,IAAW4X,EAAY,IACvB,IAAInzD,CAAJ,CAAYu7C,CAAAv7C,MAAA,CAAgB,0BAAhB,CAAZ,CAAyD,CACrDmzD,CAAA,CAAYnzD,CAAA,CAAM,CAAN,CACR6/C,EAAAA,CAAS7/C,CAAA,CAAM,CAAN,CACb,KAAIgM,EAAO,GAAPA,CAAa6zC,CAIjB,IAA6Bl9C,IAAAA,EAA7B,GAAI,CAAA4oD,EAAA,CAAev/C,CAAf,CAAJ,CAAwC,CAAA,IACxB0hD,CADwB,CACbD,CACvB,KAAAjlD,EAASklD,CAATllD,CAAqBilD,CAArBjlD,CAA+B,EAC/B,EAAA+iD,EAAA,CAAev/C,CAAf,CAAA,CAAuB,CACnBA,KAAMA,CADa,CAEnBomD,GAAUgB,EAFS,CAGnB5qD,GAAAA,CAHmB,CAInBklD,GAAAA,CAJmB,CAKnBD,GAAAA,CALmB,CAMnBt/C,GAAO0xC,CAAP1xC,CAAgB,KANG,CAOnBy9C,GAAO,CAAAA,GAPY,CASvB,EAAArd,EAAArnC,KAAA,CAAqB8E,CAArB,CAZoC,CAPa,CAsBzD,MAAOmnD,EAxBX;AA4FA1B,QAAA,GAAS,CAATA,CAAS,CAAClW,CAAD,CAAY8X,CAAZ,CACT,CACI,IAAI5F,EAAU,EAEd,KADI4F,CACJ,GADa9X,CACb,CADyBA,CAAA97C,QAAA,CAAkB,eAAlB,CAAmC,IAAnC,CACzB,EAAO87C,CAAP,CAAA,CAAkB,CACdA,CAAA,CAAYA,CAAAn5C,KAAA,EACRy4C,EAAAA,CAAWgV,EAAA,CAAAA,CAAA,CAAmBtU,CAAnB,CACf,IAAI,CAACV,CAAL,CAAe,KACf,KAAI9yC,EAAS8yC,CACb,IAAmB,IAAnB,EAAIA,CAAA,CAAS,CAAT,CAAJ,CAAyB,CACrB,IAAIyY,EAAY,CAAhB,CACIC,EAAc,CACC,IAAnB,EAAI1Y,CAAA,CAAS,CAAT,CAAJ,EACIyY,CAAA,EACA,CAAAC,CAAA,CAAc,CAFlB,EAG0B,GAH1B,EAGW1Y,CAAA,CAAS,CAAT,CAHX,GAIIyY,CAAA,EACA,CAAAC,CAAA,CAAc,CALlB,CAOSC,EAAAA,CAAAA,CAAe,EAAA,CAAA3Y,CAAAj7C,OAAA,CAAgB0zD,CAAhB,CApElBC,EAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAc,CAAd,CAAAA,CAGd,KAAIlzD,EAAQixC,EAAA,CAAAA,CAAA,CAAqBvpC,CAArB,CACZ,IAAcpF,IAAAA,EAAd,GAAItC,CAAJ,CAAyB,CACrB,IAAIgxC,EAAS,CACb,QAAOkiB,CAAP,EACA,KAAK,CAAL,CACIxrD,CAAA,CAASub,CAAA,CAAA,CAAAvW,EAAA,CAAmB1M,CAAnB,CAA2B,EAA3B,CACT,MACJ,MAAK,CAAL,CACIgxC,CAAA,EAEJ,MAAK,CAAL,CAEI,IAAA,CAAOhxC,CAAP,EAAgBgxC,CAAA,EAAhB,CAAA,CAGIhxC,CAAA,CAAQH,IAAAE,MAAA,CAAWC,CAAX,CAAmBH,IAAAC,IAAA,CAAS,CAAT,CAAYozD,CAAZ,CAAnB,CAZhB,CAFqB,CAmBzB,CAAA,CAAOxrD,CAmCsB,CAYzB0lD,CAAAvmD,KAAA,CAAaa,CAAb,CACAwzC,EAAA,CAAYA,CAAA37C,OAAA,CAAiBi7C,CAAA/4C,OAAjB,CAAmC,CAAnC,CAlBE,CAoBlB,MAAO2rD,EAvBX;AAiFAE,QAAA,GAAQ,CAARA,CAAQ,CAACpS,CAAD,CACR,CACI,IAAIkY,EAAUlY,CACM,KAApB,EAAI,CAAAkR,EAAJ,GACI,CAAAA,EACA,CADe,CAAAC,EACf,CAD6B,EAC7B,CAAInR,CAAJ,GACI,CAAAkR,EACA,CADelR,CAAA,CAAU,CAAV,CACf,CAAAkY,CAAA,CAAUlY,CAAV,CAAsBA,CAAA37C,OAAA,CAAiB,CAAjB,CAF1B,CAFJ,CAOA,IAAI,CAAA6sD,EAAJ,CAAkB,CACd,IAAIxuD,EAAIs9C,CAAA/7C,QAAA,CAAkB,CAAAitD,EAAlB,CACA,EAAR,CAAIxuD,CAAJ,CACIw1D,CADJ,CACc,EADd,EAGIA,CAEA,CAFUlY,CAAA37C,OAAA,CAAiB3B,CAAjB,CAAqB,CAArB,CAEV,CADAs9C,CACA,CADYA,CAAA37C,OAAA,CAAiB,CAAjB,CAAoB3B,CAApB,CACZ,CAAA,CAAAwuD,EAAA,CAAe,IALnB,CAOA,EAAAC,EAAA,EAAenR,CATD,CAWlB,GAAoB,IAApB,EAAI,CAAAkR,EAAJ,CAAA,CA0gBW1tD,CAAAA,CAAPT,CAAOS,CAAH,CADZ,KAGQyB,EA3gBAkzD,CA2gBMhH,EAAA5qD,OA3gBN4xD,EA4gBAxH,EAAJ,EAAsBoD,EAAtB,EAA+C9uD,CAAA,EAC/C,KAAK,IAAIvC,EAAI,CAAb,CAAgBA,CAAhB,CAAoBuC,CAApB,CAAyBvC,CAAA,EAAzB,CAA8B,CAC1B,GAAI,CAACK,CAAL,CAAQ,CACJS,CAAA,CAAI,CAAG,KAAAgB,EAAQ,EAAI,KAAAu5B,EAAO,CA/gB9Bo6B,EAghBQxH,EAAJ,EAAsBqD,EAAtB,GACIj2B,CAAA,EAAQ,CAAAv5B,CAAA,EADZ,CAFI,CAWR,IAAIpC,EAzhBJ+1D,CAyhBQhH,EAAAlf,WAAA,CAAuBvvC,CAAvB,CAAJN,CAAgC,GAKxB,EAAZ,EAAI27B,CAAJ,GACa,EACT,EADI37B,CACJ,EADsB,GACtB,EADiBA,CACjB,GAD4BA,CAC5B,EADiC,EACjC,EAAAA,CAAA,CAAKA,CAAL,CAAS,EAAT,CAAiB,EAFrB,CAIAoB,EAAA,EAAKpB,CAAL,CAASuC,IAAAC,IAAA,CAAS,CAAT,CAAYJ,CAAZ,CACTA,EAAA,EAASu5B,CACTh7B,EAAA,EACY,EAAZ,CAAIyB,CAAJ,GACIgwD,EAAA,CAtiBJ2D,CAsiBI,CAAa30D,CAAb,CACA,CAAAT,CAAA,CAAI,CAFR,CAxB0B,CA6B1BA,CAAJ,EAAOyxD,EAAA,CA1iBH2D,CA0iBG,CAAa30D,CAAb,CA3iBP,CAGA,MAAO00D,EAvBX;AA8CAxE,QAAA,GAAQ,CAARA,CAAQ,CAAC/C,CAAD,CAAY3Q,CAAZ,CACR,CAAA,IAC0CmS,CAD1C,CACqDD,CAEjD,EAAApB,EAAA,CAAmB,MACnB,EAAAC,EAAA,CAAoB,MACpB,KAAA9jD,EAASklD,CAATllD,CAAqBilD,CAArBjlD,CAA+B,EAE/B,IAAI0jD,CAAJ,EAAiBwE,EAAjB,CAA2C,CAMvC,IAAA1wD,EAAQu7C,CAAAv7C,MAAA,CAAgB,6DAAhB,CACR,IAAI,CAACA,CAAL,CAEI,MADA,EAAA4M,MAAA,CAAW,eAAX,CAA6Bs/C,CAA7B,CAAyC,OAAzC,CAAmD3Q,CAAnD,CAA+D,GAA/D,CACOA,CAAAA,CAEX,KAAAvvC,EAAOhM,CAAA,CAAM,CAAN,CAIP,IAAIA,CAAA,CAAM,CAAN,CAAJ,EAA4B,GAA5B,EAAgBA,CAAA,CAAM,CAAN,CAAhB,CAAiC,CAEAwI,CAAAA,CAD7BA,CAC6BA,CADpBipD,EAAA,CAAAA,CAAA,CAAezxD,CAAA,CAAM,CAAN,CAAf,CAAyB,CAAA,CAAzB,CAjSb0tD,EAAAA,CAAY,EAChB,KAASzvD,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoBuK,CAAA1G,OAApB,CAAmC7D,CAAA,EAAnC,CAAwC,CAChCC,IAAAA,EAAIsK,CAAA,CAAOvK,CAAP,CAAAuB,QAAA,CAAkB,MAAlB,CACR,IAAS,CAAT,EAAItB,CAAJ,CAAY,CACR,IAAIC,EAAIqK,CAAA,CAAOvK,CAAP,CAAAuD,YAAA,CAAsB,MAAtB,CACA,EAAR,CAAIrD,CAAJ,GAAWA,CAAX,CAAeqK,CAAA,CAAOvK,CAAP,CAAA6D,OAAf,CACA4rD,EAAA,CAAUzvD,CAAV,CAAA,CAAeuK,CAAA,CAAOvK,CAAP,CAAA2B,OAAA,CAAiB1B,CAAjB,CAAoBC,CAApB,CAAwBD,CAAxB,CACfsK,EAAA,CAAOvK,CAAP,CAAA,CAAYuK,CAAA,CAAOvK,CAAP,CAAA2B,OAAA,CAAiB,CAAjB,CAAoB1B,CAApB,CAJJ,CAFwB,CASxC,CAAA,CAAOwvD,CAsR8B,CAIjC0E,CAAA,CAAWuB,EACXxF,EAAA,CAAS,CApB8B,CAA3C,IAsBK,IAAIjC,CAAJ,EAAiBoF,EAAjB,CAA0C,CAO3C,CAAAjF,EAAA,CAAmB,GACnB,EAAAC,EAAA,CAAoB,GACpBtsD,EAAA,CAAQu7C,CAAAv7C,MAAA,CAAgB,yCAAhB,CACR;GAAI,CAACA,CAAL,CAEI,MADA,EAAA4M,MAAA,CAAW,eAAX,CAA6Bs/C,CAA7B,CAAyC,OAAzC,CAAmD3Q,CAAnD,CAA+D,GAA/D,CACOA,CAAAA,CAEXvvC,EAAA,CAAOhM,CAAA,CAAM,CAAN,CACPoyD,EAAA,CAAWC,EACXlE,EAAA,CAAS,CAhBkC,CAA1C,IAkBA,IAAIjC,CAAJ,EAAiBgD,EAAjB,CAID,CAAA7C,EAQA,CARmB,GAQnB,CAPA,CAAAC,EAOA,CAPoB,GAOpB,CANAtgD,CAMA,CANO,GAMP,CANa0mC,EAAA,CAAU,EAAE,CAAAoZ,GAAZ,CAA2B,CAA3B,CAMb,CAL6BnpD,IAAAA,EAK7B,GALI,CAAA4oD,EAAA,CAAev/C,CAAf,CAKJ,EAJI,CAAAY,MAAA,CAAW,kBAAX,CAAgCZ,CAAhC,CAAuC,aAAvC,CAIJ,CAFAhM,CAEA,CAFQ,CAACu7C,CAAA,CAAU,CAAV,CAAD,CAAeA,CAAA37C,OAAA,CAAiB,CAAjB,CAAf,CAER,CADAwyD,CACA,CADWwB,EACX,CAAAzF,CAAA,CAAS,CAZR,KAcA,IAAIjC,CAAJ,EAAiB4B,EAAjB,EAA0C5B,CAA1C,EAAuD6B,EAAvD,CAA+E,CAO3E,CAAAvB,EAAL,EACI,CAAA5/C,MAAA,CAAWs/C,CAAX,CAAuB,mBAAvB,CAEJlsD,EAAA,CAAQu7C,CAAAv7C,MAAA,CAAgB,6CAAhB,CACR,IAAI,CAACA,CAAL,CAEI,MADA,EAAA4M,MAAA,CAAW,eAAX,CAA6Bs/C,CAA7B,CAAyC,aAAzC,CAAyD3Q,CAAzD,CAAqE,GAArE,CACOA,CAAAA,CAEX,KAAKt9C,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB,CAAAuuD,EAAAhkD,GAAA1G,OAAhB,EACQ9B,CAAA,CAAM,CAAN,CADR,EACoB,CAAAwsD,EAAAhkD,GAAA,CAAsBvK,CAAtB,CADpB,CAA8CA,CAAA,EAA9C,EAGA,GAAIA,CAAJ,EAAS,CAAAuuD,EAAAhkD,GAAA1G,OAAT,CAEI,MADA,EAAA8K,MAAA,CAAW,UAAX,CAAwBs/C,CAAxB,CAAoC,cAApC,CAAqDlsD,CAAA,CAAM,CAAN,CAArD;AAAgE,GAAhE,CACOu7C,CAAAA,CAEXvvC,EAAA,CAAO,GAAP,CAAakgD,CACb1jD,EAAA,CAAS,CAACxI,CAAA,CAAM,CAAN,CAAD,CACLksD,EAAJ,EAAiB6B,EAAjB,CACIN,CADJ,CACc,CAAAjB,EAAAiB,GAAA,CAAuBxvD,CAAvB,CAAAgJ,MAAA,CAAgC,EAAhC,CADd,CAGIwmD,CAHJ,CAGcgE,EAAA,CAAAA,CAAA,CAAe,CAAAjF,EAAAiB,GAAA,CAAuBxvD,CAAvB,CAAf,CAEdm0D,EAAA,CAAW3E,CAAA3rD,OACXqsD,EAAA,CAAS,CA9BuE,CAA/E,IAgCA,CAID,GAAIjC,CAAJ,EAAiByE,EAAjB,CACIyB,CACA,CADW,CACX,CAAoB,GAApB,EAAI7W,CAAA,CAAU,CAAV,CAAJ,GAAyBA,CAAzB,CAAqCA,CAAA37C,OAAA,CAAiB,CAAjB,CAAAwC,KAAA,EAArC,CAFJ,KAIK,CACGy4C,CAAAA,CAAWgV,EAAA,CAAAA,CAAA,CAAmBtU,CAAnB,CACf,IAAI,CAACV,CAAL,CAEI,MADA,EAAAjuC,MAAA,CAAW,UAAX,CAAwBs/C,CAAxB,CAAoC,eAApC,CAAsD3Q,CAAtD,CAAkE,GAAlE,CACOA,CAAAA,CAEXA,EAAA,CAAYA,CAAA37C,OAAA,CAAiBi7C,CAAA/4C,OAAjB,CAAmC,CAAnC,CACZ+4C,EAAA,CAAWA,CAAAz4C,KAAA,EACX,IAAI8pD,CAAJ,EAAiB2E,EAAjB,EAA4C3E,CAA5C,EAAyD+E,EAAzD,CAAkF,CAC1E4C,CAAAA,CAAYhE,EAAA,CAAAA,CAAA,CAAmBtU,CAAnB,CAChB,IAAI,CAACsY,CAAL,CAEI,MADA,EAAAjnD,MAAA,CAAW,iBAAX,CAA+Bs/C,CAA/B,CAA2C,eAA3C,CAA6D3Q,CAA7D,CAAyE,GAAzE,CACOA,CAAAA,CAEXA,EAAA,CAAYA,CAAA37C,OAAA,CAAiBi0D,CAAA/xD,OAAjB,CAAoC,CAApC,CANkE,CAW9EswD,CAAA,CADAlG,CAAJ,EAAiB0E,EAAjB,EAA4C1E,CAA5C,EAAyDmF,EAAzD,CAzMyB1uD,IAAAA,EA0MV,GAAAmxD,CA1MhBvI,EAAA,CA0M+B1Q,CA1M/B,CA0MgB,EA9LWl4C,IAAAA,EA8LX,GAAAmxD,CA9LhBtI,EAAA,CA8L+B3Q,CA9L/B,CA8LgB,EA5zLUl4C,IAAAA,EA4zLV,GAAAmxD,CAtN+B/mD,EAtmL/CwhC,EAAA,CA4zL+BsM,CA5zL/B,CA4zLgB,CAA0B,CAA1B,CAA8B,CAD7C,CAOevJ,EAAA,CAAAA,CAAA,CAAqBuJ,CAArB,CAPf,EAOiD,CAzBhD,CA4BL76C,CAAA,CAAQu7C,CAAAv7C,MAAA,CAAgB,mBAAhB,CACRgM,EAAA,CAAO,GAAP,CAAakgD,CACbiC,EAAA,CAAS,CAtCR,CA8CLniD,CAAA,CAAOA,CAAAorC,YAAA,EACP;CAAA+U,EAAA,CAAiB,CACjB,EAAAC,EAAA,CAAiBpgD,CACjB,EAAAu/C,EAAA,CAAev/C,CAAf,CAAA,CAAuB,CAACA,KAAAA,CAAD,CAAOomD,GAAAA,CAAP,CAAiB5pD,GAAAA,CAAjB,CAAyBklD,GAAAA,CAAzB,CAAoCD,GAAAA,CAApC,CAA6Ct/C,GAAO,EAApD,CAAwDy9C,GAAO,CAAAA,GAA/D,CAEnB5rD,EAAA,CAAMmuD,CAAN,CAAJ,GACI,CAAAhC,EACA,CADiB,CACjB,CAAAoC,EAAA,CAAAA,CAAA,CAAiBvuD,CAAA,CAAMmuD,CAAN,CAAe,CAAf,CAAjB,CAFJ,CAKA,OAAOniD,EArJX,CA+JAuiD,QAAA,GAAW,CAAXA,CAAW,CAACnT,CAAD,CACX,CAEI,IADA,IAAIqY,EAAU,EAAd,CACSx1D,EAAI,CAAb,CAAgBA,CAAhB,CAAoBm9C,CAAAt5C,OAApB,CAAkC7D,CAAA,EAAlC,CACI,GAAIm9C,CAAA,CAAMn9C,CAAN,CAAJ,EAAgB,CAAAouD,EAAhB,CACI,CAAAF,EAAA,EADJ,KAEO,IAAI/Q,CAAA,CAAMn9C,CAAN,CAAJ,EAAgB,CAAAquD,EAAhB,GACH,CAAAH,EAAA,EACI,CAAkB,CAAlB,EAAA,CAAAA,EAFD,EAEsB,CACrB,CAAAA,EAAA,CAAiB,CACjBsH,EAAA,CAAUrY,CAAAx7C,OAAA,CAAa3B,CAAb,CAAiB,CAAjB,CACVm9C,EAAA,CAAQA,CAAAx7C,OAAA,CAAa,CAAb,CAAgB3B,CAAhB,CACR,MAJqB,CAQ7B+N,CAAAA,CAAO,CAAAogD,EAAPpgD,EAAyB,EAC7B,EAAAu/C,EAAA,CAAev/C,CAAf,CAAAmC,GAAA,EAA8BitC,CACzB,EAAA+Q,EAAL,GACI,CAAAC,EACA,CADiB,IACjB,CAAAgD,EAAA,CAAAA,CAAA,CAAgBpjD,CAAhB,CAFJ,CAIA,OAAOynD,EArBX;AAgCAtG,QAAA,GAAS,CAATA,CAAS,CAACnhD,CAAD,CAAO3L,CAAP,CAAcuuD,CAAd,CACT,CADuBA,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAQ,CAAR,CAAAA,CAEnB5iD,EAAA,CAAOA,CAAAorC,YAAA,EAAAx3C,OAAA,CAA0B,CAA1B,CAA6B,CAA7B,CACP,IAAKgvD,CAAL,CAAaF,EAAb,EAAiE/rD,IAAAA,EAAjE,GAAuC,CAAA6oD,EAAA,CAAgBx/C,CAAhB,CAAvC,CACI,CAAAY,MAAA,CAAW,mBAAX,CAAiCZ,CAAjC,CAAwC,GAAxC,CADJ,KAAA,CAIA,IAAIgmC,EAAarvC,IAAAA,EACjB,IAAoB,QAApB,EAAI,MAAOtC,EAAX,CAA8B,CACtBiwC,CAAAA,CAAa,EACjB,KAAIxxC,EAAIwyC,EAAA,CAAAA,CAAA,CAAqBjxC,CAArB,CAA4BiwC,CAA5B,CACR,IAAU3tC,IAAAA,EAAV,GAAI7D,CAAJ,CAAqB,CACjB,CAAA8N,MAAA,CAAW,kBAAX,CAAgCZ,CAAhC,CAAuC,KAAvC,CAA+C3L,CAA/C,CACA,OAFiB,CAIG,CAAxB,CAAIiwC,CAAAxuC,OAAJ,EACI,CAAA8K,MAAA,CAAW,iCAAX,CAA+CZ,CAA/C,CAAsD,KAAtD,CAA8DskC,CAAAmB,KAAA,EAA9D,CAEJpxC,EAAA,CAAQvB,CACRkzC,EAAA,CAAa1B,CAAA,CAAW,CAAX,CAXa,CAc9B,CADIyjB,CACJ,CADU,CAAAvI,EAAA,CAAgBx/C,CAAhB,CACV,GACI+nD,CAAA1zD,MAEA,CAFYA,CAEZ,CADA0zD,CAAAnF,GACA,CADYA,CACZ,CAAAmF,CAAAnI,GAAA,CAAY,CAAAA,GAHhB,EAKI,CAAAJ,EAAA,CAAgBx/C,CAAhB,CALJ,CAK4B,CAACA,KAAAA,CAAD,CAAO3L,MAAAA,CAAP,CAAcuuD,GAAAA,CAAd,CAAqBhD,GAAO,CAAAA,GAA5B,CAE5B,EAAA7+C,EAp5LAwhC,EAAA,CAo5LqBviC,CAp5LrB,CAAA,CAAwB,CAAC3L,MAo5LEA,CAp5LH,CAAQ2xC,GAo5LEA,CAp5LV,CA03LxB,CAFJ;AA0JAme,QAAA,GAAO,CAAPA,CAAO,CAACjE,CAAD,CAAYsC,CAAZ,CAA6BjT,CAA7B,CACP,CACI,IAAIjL,EAAa,EACba,EAAAA,CAAO/uC,CAAC8pD,CAAD9pD,EAHI,IAAA,EAAAosD,GAAAA,CAAAA,CAAa,EAAbA,CAAAA,CAGJpsD,GAHqB,IAAA,EAAAm5C,GAAAA,CAAAA,CAAY,EAAZA,CAAAA,CAGrBn5C,OAAA,EACPrD,EAAAA,CAAIuyC,EAAA,CAAAA,CAAA,CAAqBH,CAArB,CAA2Bb,CAA3B,CACE3tC,KAAAA,EAAV,GAAI5D,CAAJ,CACSuxC,CAAAxuC,OAAL,CAEgC,CAAzB,EAAIwuC,CAAAxuC,OAAJ,CACHiuD,EAAA,CAAAA,CAAA,CAAahxD,CAAb,CAAgBuxC,CAAA,CAAW,CAAX,CAAhB,CADG,CAIHyf,EAAA,CAAAA,CAAA,CAAa,CAAb,CAAgB5e,CAAhB,CANJ,CACI4e,EAAA,CAAAA,CAAA,CAAahxD,CAAb,CAFR,CAUI,CAAA6N,MAAA,CAAW,gCAAX,CAA8CukC,CAA9C,CAAqD,GAArD,CAdR;AAsCAmc,QAAA,GAAU,CAAVA,CAAU,CACV,CAGI,IAFA,IAAI0G,EAAoB,CAAAjI,EAAxB,CAEA,EAAA,EAFA,CAES9tD,EAAI,CAAb,CAAgBA,CAAhB,CAAoB,CAAAwtD,EAAA3pD,OAApB,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,EAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,CAA2C7D,CAAA,EAA3C,CAAgD,CA4BxCg2D,CAAAA,GAAJ,CAAU,CAAAxI,EAAA,CAAextD,CAAf,CAKNy/C,EAAAA,EAAJ,CAAa,EACTE,EAAAA,GAAJ,CAAa,CACbqW,EAAAA,GAAAvW,EAAAK,QAAA,CAAmB,QAAA,CAAA,CAAA,CAAA,CAAA,MAAA,SAAQ,CAACh/C,CAAD,CAAIgtD,CAAJ,CAAe,CAClCA,CAAJ,GAAkBrO,CAAAA,EAAA57C,OAAlB,EAAiC47C,CAAAA,EAAAx2C,KAAA,CAAYnI,CAAZ,CACjC6+C,EAAAA,GAAA,EAFsC,CAAvB,CAAA,CAAA,CAAA,CAAnB,CAIA,IAAIA,CAAAA,GAAJ,EAAcF,CAAAA,EAAA57C,OAAd,CAKI,IAAK,IAAIiqD,EAAYiI,CAArB,CAAwCjI,CAAxC,CAAoDnO,CAAAA,GAApD,EAA8D,CAAAmO,EAA9D,CAA8EA,CAAA,EAA9E,CAA2F,CACvF,IAAIztD,EAAAA,IAAAA,EACJ,KAAKA,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgBs/C,CAAAA,GAAhB,EAQQF,CAAAA,EAAA,CAAOp/C,CAAP,CARR,GAQsB,CAAAo/C,EAAA,CAAYqO,CAAZ,CAAwBztD,CAAxB,CARtB,EAQoD21D,CAAAA,GAAAvI,GAAA,CAAYptD,CAAZ,CARpD,EAQsE,CAAAotD,GAAA,CAAaK,CAAb,CARtE,CAAwBztD,CAAA,EAAxB,EAUA,GAAIA,CAAJ,EAASs/C,CAAAA,GAAT,CAAiB,CACbuP,EAAA,CAAAA,CAAA,CAAe8G,CAAAA,GAAAjoD,KAAf,CAAyB+/C,CAAzB,CAAoC2C,EAApC,CACAuF,EAAAA,GAAA,CAAM,IACN,MAHa,CAZsE,CAmB/F,GAAIA,CAAAA,GAAJ,CAAS,CACL,IAAI7f,EAAU,CACd+Y,GAAA,CAAAA,CAAA,CAAe8G,CAAAA,GAAAjoD,KAAf,CAAyB,CAAA+/C,EAAzB,CAAyC2C,EAAzC,CACAuF,EAAAA,GAAAvW,EAAAK,QAAA,CAAmB,QAAA,CAAA,CAAA,CAAA,CAAA,MAAA,SAAQ,CAACh/C,CAAD,CAAIgtD,CAAJ,CAAe,CACtCgE,EAAA,CAAA3b,CAAA,CAAgBr1C,CAAhB,CAAmBk1D,CAAAA,GAAAvI,GAAA,CAAYK,CAAZ,CAAnB,CADsC,CAAvB,CAAA,CAAA,CAAA,CAAnB,CAHK,CA/DmC,CAuEhD,CAAAN,EAAA,CAAiB,EA1ErB;AAkFA8B,QAAA,GAAW,CAAXA,CAAW,CACX,CACI,IAAK,IAAItvD,EAAI,CAAb,CAAgBA,CAAhB,CAAoB,CAAAswC,EAAAzsC,OAApB,CAA4C7D,CAAA,EAA5C,CAAiD,CAC7C,IAAI+N,EAAO,CAAAuiC,EAAA,CAAgBtwC,CAAhB,CAAX,CACIk0D,EAAQ,CAAA5G,EAAA,CAAev/C,CAAf,CACPmmD,EAAL,CAOAG,CAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CAPA,CAII,CAAAvB,MAAA,CAAW,mCAAX,CAAiDZ,CAAjD,CAAwD,GAAxD,CAPyC,CAYjD,CAAAuiC,EAAA,CAAkB,EAbtB,CAoEAwhB,QAAA,GAAO,CAAPA,CAAO,CAAC1vD,CAAD,CAAQ2xC,CAAR,CACP,CACI,CAAA0L,EAAA,CAAY,CAAAqO,EAAZ,CAAA,CAA8B9c,EAAA,CAAAA,CAAA,CAAc5uC,CAAd,CACXsC,KAAAA,EAAnB,GAAIqvC,CAAJ,GAA8B,CAAA0Z,GAAA,CAAa,CAAAK,EAAb,CAA9B,CAA6D/Z,CAA7D,CACA,EAAA2Z,EAAA,CAAe,CAAAI,EAAf,CAAA,CAAiC,CAAAH,GACjC,EAAAG,EAAA,EAJJ,CAeA9c,QAAA,GAAQ,CAARA,CAAQ,CAAC5uC,CAAD,CAAQ0rD,CAAR,CACR,CADgBA,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAY,CAAAA,EAAZ,CAAAA,CAEZ,KAAIhtD,EAAIkwC,CAAA,CAAA,CAAAliC,EAAA,CAAkB1M,CAAlB,EAA2B,CAA3B,CAA8B,EAA9B,CAAkC,CAAA,CAAlC,CACR,EAAIA,CAAJ,CAAY,CAACoxB,CAAb,EAAgCpxB,CAAhC,EAAyCwe,CAAzC,GACIquC,EAAA,CAAAA,CAAA,CAAa,kBAAb,CAAkCjrC,EAAA,CAAU5hB,CAAV,CAAlC,CAAqD,eAArD,CAAuE4hB,EAAA,CAAU8pC,CAAV,CAAvE,CAA8F,MAA9F,CAAuG9pC,EAAA,CAAUljB,CAAV,CAAvG,CAEJ,OAAOA,EALX,CAgBA,EAAA,UAAA,MAAA,CAAA6N,QAAK,CAACsnD,CAAD,CAAStI,CAAT,CACL,CACI,KAAUvlD,MAAJ,CAAU,WAAV,CAAwB+mD,EAAA,CAAAA,IAAA,CAAgBxB,CAAhB,CAAxB,CAAiD,IAAjD,CAAwDsI,CAAxD,CAAN,CADJ,CAWAhH;QAAA,GAAO,CAAPA,CAAO,CAACiH,CAAD,CACP,CACI,CAAA7hD,EAAA,CAAa,aAAb,CAA6B86C,EAAA,CAAAA,CAAA,CAFfxB,IAAAA,EAEe,CAA7B,CAAsD,IAAtD,CAA6DuI,CAA7D,CADJ,CAUA,EAAA,UAAA,EAAA,CAAA7hD,QAAO,CAAC3T,CAAD,CACP,CACS,IAAAoO,EAAL,CAGI,IAAAA,EAAAuF,EAAA,CAAiB3T,CAAjB,CAHJ,CACImU,OAAAlS,IAAA,CAAYjC,CAAZ,CAFR,CAUAy1D;IAAAA,GAAYA,CAAZA,CAEAC,GAAYA,CAFZD,CAMAl6D,GAAYA,OANZk6D,CAOAE,GAAYA,OAPZF,CAQAG,GAAYA,OARZH,CASAI,GAAYA,MATZJ,CAUAK,GAAYA,QAVZL,CAWAM,GAAYA,KAXZN,CAYAO,GAAYA,KAZZP,CAaAQ,GAAYA,KAbZR,CAcAS,GAAYA,OAdZT,CAeAU,GAAYA,OAfZV,CAgBAW,GAAYA,KAhBZX,CAiBAY,GAAYA,KAjBZZ,CAkBAa,GAAYA,MAlBZb,CAmBAc,GAAYA,OAnBZd,CAoBAe,GAAYA,KApBZf,CAqBAgB,GAAYA,MArBZhB,CAsBAiB,GAAYA,KAtBZjB,CAuBAkB,GAAYA,QAvBZlB,CAwBAmB,GAAYA,KAxBZnB,CAyBAoB,GAAYA,MAzBZpB,CA0BAqB,GAAYA,MA1BZrB,CA2BAsB,GAAYA,KA3BZtB,CA4BAuB,GAAYA,SA5BZvB,CA6BAwB,GAAYA,MA7BZxB,CA8BAyB,GAAYA,KA9BZzB,CA+BA0B,GAAYA,OA/BZ1B,CAgCA2B,GAAYA,OAhCZ3B,CAiCA4B,GAAYA,MAjCZ5B,CAkCA6B,GAAYA,OAlCZ7B,CAmCA8B,GAAYA,QAnCZ9B,CAoCA+B,GAAYA,QApCZ/B,CAqCAgC,GAAYA,QArCZhC,CAsCAiC,GAAYA,OAtCZjC,CAuCAkC,GAAYA,KAvCZlC,CAwCAmC,GAAYA,MAxCZnC,CAyCAoC,GAAYA,KAzCZpC,CA0CAqC,GAAYA,OA1CZrC,CAmDAK,GAAiBA,EAnDjBL,CAoDA2B,GAAiBA,EApDjB3B,CAqDAuB,GAAiBA,EArDjBvB,CAsDAsC,GAAiBA,EAsEjB/qD;QA9DEgrD,GA8DS,CAACC,CAAD,CAAgBC,CAAhB,CAA8BC,CAA9B,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,UAAN,CAAkBF,CAAlB,CAx8pBQx+C,QAw8pBR,CAEA,KAAA/L,MAAAK,EAAA,CAAqB,CAAA,CAErB,KAAAmqD,EAAA,CAAoB,IACpBE,GAAA,CAAAA,IAAA,CAAqBF,CAArB,CAEA,KAAAG,EAAA,CAAkB7uC,EAAA,CAAAA,IAAA,CAAoB,WAApB,CAAiCyuC,CAAjC,CA3jwBVK,CA2jwBU,CAMlB,KAAAC,EAAA,CAAoB,CAKpB,KAAAp3C,EAAA,CAAiB,CAAC82C,CAAA,SAAlB,EAA+C,CAACA,CAAA,SAGhD,KAAAO,EAAA,CADA,IAAAC,EACA,CADmB,IAAAC,EACnB,CADqC,IAGrC,KAAAC,EAAA,CADA,IAAAC,EACA,CADkB,CAAA,CAElB,KAAAC,EAAA,CAAqB,IAAAC,EAArB,CAA0C,IAC1C,KAAAC,EAAA,CAAmC,IAAAC,EAAnC,CAAwD,CAAA,CAExD,KAAAC,GAAA,CAAkCzvC,EAAA,CAAAA,IAAA,CAAoB,KAApB,CAAlC,EAAgE,EAM9CpW,EAAC7R,IAAA23D,OAAA,EAAD9lD,CAAiB,EAAjBA,UAAAnS,CAA+B,EAA/BA,CAClB,KAAAk4D,EAAA,CAAeC,EAAA,CAAAA,IAAA,CAUf,IADA,IAAA/qD,EACA,CADyCyE,EAAA,CAA6B,KAA7B,CAAoC,IAAA1F,GAApC,CACzC,CAAA,CAIA,IAAAgB,EAAA,CAAyC0E,EAAA,CAA6B,UAA7B,CAAyC,IAAA1F,GAAzC,CAKzC,KAAAkB,EAAA,CAAW,IAAI2S,EAAJ,CAAa,CAAC,GAAM,IAAAxT,GAAN,CAAuB,MAAxB,CAAgC,SAAY,IAAA0T,EAA5C,CAAb,CAA0E,IAAA9S,EAA1E,CAAoF,IAAAD,EAApF,CAKX,KACI2C,EAAcyZ,EAAA,CAAwB,IAAApd,GAAxB,CAKlB,IAFA,IAAAw0C,EAEA,EAHA,IAAAtlC,EAGA,CAHwCxJ,EAAA,CAA6B,OAA7B,CAAsC,IAAA1F,GAAtC,CAGxC;AAFkC,IAAAkP,EAAA/O,EAAA,MAElC,CACI,IAAKgd,CAAL,CAAkB,CAAlB,CAAqBA,CAArB,CAAkCxZ,CAAA5N,OAAlC,CAAsDonB,CAAA,EAAtD,CAAoE,CAChE,IAAA9b,EAAYsC,CAAA,CAAYwZ,CAAZ,CAMZ9b,EAAAgF,GAAA,CAAmB,IAAA6I,EAAA7I,GACnBhF,EAAAmF,MAAA,CAAkB,IAAA0I,EAAA1I,MAClBnF,EAAAkF,EAAA,CAAoB,IAAA2I,EAAA3I,EAT4C,CAaxE,IAAAA,EAAA,CAAa0E,EAAb,CAt5yBMghD,mJAs5yBN,CAKA,KAAK9uC,CAAL,CAAkB,CAAlB,CAAqBA,CAArB,CAAkCxZ,CAAA5N,OAAlC,CAAsDonB,CAAA,EAAtD,CACI9b,CACA,CADYsC,CAAA,CAAYwZ,CAAZ,CACZ,CAAI9b,CAAAoO,GAAJ,EAAuBpO,CAAAoO,GAAA,CAAkB,IAAlB,CAAwB,IAAAvO,EAAxB,CAAkC,IAAAD,EAAlC,CAA4C,IAAAD,EAA5C,CAGvBsqD,EAAAA,CAAa,IACbY,EAAAA,CAAiC9vC,EAAA,CAAAA,IAAA,CAAoB,QAApB,CAA8ByuC,CAA9B,CACrBj0D,KAAAA,EAAhB,GAAIs1D,CAAJ,GAIyB,CAArB,CAAIA,CAAAn2D,OAAJ,CACIu1D,CADJ,CACiB,IAAAD,EADjB,CACoCa,CADpC,CAGI,IAAAC,EAHJ,CAGkB94D,QAAA,CAAS64D,CAAT,CAAkB,EAAlB,CAPtB,CAyBA,KAAIE,CAGJ,IAFIvX,CAEJ,CAFaz4B,EAAA,CAAAA,IAAA,CAAoB,OAApB,CAEb,GAF8CgwC,CAAD,CAAgB,CAAA,CAAhB,CAAyBvB,CAAA,MAEtE,EACI,IAAAS,EAKA,CALkBA,CAKlB,CAL+BzW,CAK/B,CAJKuX,CAIL,GAHI,IAAAb,EACA,CADoB,CAAA,CACpB,CAAA,IAAAY,EAAA,CAAcE,EAElB,EAAI,IAAAF,EAAJ;CACI,IAAAV,EACA,CADqB,IAAIx7C,CAAJ,CAAU,IAAV,CA38yBpBq8C,QA28yBoB,CACrB,CAAI,IAAAb,EAAAc,KAAA,EAAJ,CACIjB,CADJ,CACiB,IADjB,CAGI,OAAO,IAAAG,EALf,CAcA,EAACH,CAAL,EAAmB,IAAAa,EAAnB,GACIb,CADJ,CACiBkB,EAAA,CAAAA,IAAA,CADjB,IAEoB,IAAAjB,EAFpB,CAEwC,CAAA,CAFxC,CAKA,IAAKD,CAAL,CAEO,CACH,IAAInqD,EAAM,IACVy7B,GAAA,CAAgB0uB,CAAhB,CAA4B,IAA5B,CAAkC,CAAA,CAAlC,CAAwCmB,QAAsB,CAACx0D,CAAD,CAAOgpD,CAAP,CAAkBhoD,CAAlB,CAA8B,CACnDA,CA2I7C,EA3IQkI,CAkJJkqD,EAEA,CAFmB,IAEnB,CApJIlqD,CAmJJoqD,EACA,CADoB,CAAA,CACpB,CApJIpqD,CAoJJkF,GAAA,CAAY,kDAAZ,CApJyCpN,CAoJzC,EApJ8BgoD,CAoJiD,CAAY,IAAZ,CAAmB5f,EAAA,CApJpE4f,CAoJoE,CAAnB,CAA0C,EAAzH,EAA+H,GAA/H,CATJ,GA3IQ9/C,CA4IJiqD,EACA,CA7I8BnK,CA6I9B,CA7II9/C,CA6IJqqD,EAAA,CAAkB,CAAA,CAFtB,CAWArkD,GAAA,CAtJQhG,CAsJR,CAvJgG,CAA5F,CAFG,CAFP,IACIgG,GAAA,CAAAA,IAAA,CAQC,KAAAhH,EAAA,MAAL,GAA6B,IAAA8qD,EAA7B,CAA+C,CAAA,CAA/C,CAKI,EAACF,CAAL,EAAmB,IAAAE,EAAnB,EAAoC,IAAAyB,KAAA,CAAU,IAAAC,GAAV,CAjHpC,CAAA,IAv6sBA9xD,EAAA,CAw6sBoBjI,8BAx6sBpB,CA03sBJ,CA/DwB6b,EAAA5O,CAAtB+qD,EAAsB/qD,CAAAA,CAAAA,CA+PxBmrD;QAAA,GAAe,CAAfA,CAAe,CAACF,CAAD,CACf,CACI,GAAI,CAACA,CAAL,CAAmB,CACf,IAAItuD,CACJ,IAAwB,QAAxB,EAAI,MAAOtD,UAAX,GAAqCsD,CAArC,CAA8CtD,SAAA,MAA9C,EACI,GAAI,CACA4xD,CAAA,CAAsCpwD,IAAA,CAAK,GAAL,CAAW8B,CAAX,CAAoB,GAApB,CADtC,CAEF,MAAM1K,CAAN,CAAS,CAjktBnB+I,CAAA,CAkktB4B/I,CAAAgJ,QAlktB5B,CAkktBwC,IAlktBxC,CAkktB+C0B,CAlktB/C,CAkktBwD,GAlktBxD,CAiktBmB,CALA,CAUnB,CAAAsuD,EAAA,CAAoBA,CAXxB,CAmCA1uC,QAAA,GAAc,CAAdA,CAAc,CAAC9f,CAAD,CAAQswD,CAAR,CAAwB10D,CAAxB,CACd,CAOI,IAAI20D,EAAUvwD,CAAA1G,YAAA,EACVtB,EAAAA,CAAQw4D,EAAA,CAAexwD,CAAf,CAARhI,EAAiCw4D,EAAA,CAAeD,CAAf,CACvBj2D,KAAAA,EAAd,GAAItC,CAAJ,EAA2B,CAAAw2D,EAA3B,GAA8Cx2D,CAA9C,CAAsD,CAAAw2D,EAAA,CAAkBxuD,CAAlB,CAAtD,CACc1F,KAAAA,EAAd,GAAItC,CAAJ,EAA2Bs4D,CAA3B,GAA2Ct4D,CAA3C,CAAmDs4D,CAAA,CAAetwD,CAAf,CAAnD,CACc1F,KAAAA,EAAd,GAAItC,CAAJ,EAA+C,QAA/C,EAA2B,MAAO4E,UAAlC,EAA2DA,SAAA,CAAUoD,CAAV,CAA3D,GAA6EhI,CAA7E,CAAqFgI,CAArF,CACc1F,KAAAA,EAAd,GAAItC,CAAJ,GAAyBA,CAAzB,CAbwCy4D,IAAAA,EAaxC,CACA,IAAoB,QAApB,EAAI,MAAOz4D,EAAX,EAAgC4D,CAAhC,CACI,OAAOA,CAAP,EACA,KAzywBI80D,CAyywBJ,CACI14D,CAAA,CAAQ,CAACA,CACLJ,MAAA,CAA4BI,CAA5B,CAAJ,GAAyCA,CAAzC,CAAiE,CAAjE,CACA,MACJ,MA3ywBI42D,CA2ywBJ,CACI52D,CAAA,CAAkB,MAAlB,EAASA,CANb,CAUJ,MAAOA,EAxBX,CA2FA,CAAA,CAtpzBJ,EAAA24D,UAspzBIlnD;CAAA2mD,KAAA,CAAAA,QAAI,CAACrvD,CAAD,CAAKyC,CAAL,CACJ,CAGI,IAFA,IAAIgH,EAAW,IAAf,CACInD,EAAcyZ,EAAA,CAAwB,IAAApd,GAAxB,CADlB,CAESmd,EAAa,CAAtB,CAAyBA,CAAzB,EAAuCxZ,CAAA5N,OAAvC,CAA2DonB,CAAA,EAA3D,CAAyE,CACrE,IAAI9b,EAAa8b,CAAA,CAAaxZ,CAAA5N,OAAb,CAAkC4N,CAAA,CAAYwZ,CAAZ,CAAlC,CAA4D,IAC7E,IAAI,CAACjW,EAAA,CAAA7F,CAAA,CAAL,CAA0B,CACtB6F,EAAA,CAAA7F,CAAA,CAAkB6rD,QAAyB,EAAG,CAC1CpmD,CAAA4lD,KAAA,CAAcrvD,CAAd,CAAkByC,CAAlB,CAD0C,CAA9C,CAGA,OAJsB,CAF2C,CAUzEzC,CAAAwI,KAAA,CAAQ,IAAR,CAAc/F,CAAd,CAbJ,CAyBAqtD,SAAA,GAAa,CAAbA,CAAa,CAAC1B,CAAD,CACb,CAEI,IAAI2B,EAAgB,IAAIn9C,CAAJ,CAAU,CAAV,CA1qzBXq8C,QA0qzBW,CAAkCe,EAAlC,CACpB,IAAID,CAAAb,KAAA,EAAJ,EAA4B9xD,EAAA,CAAA2yD,CAAA,CAA5B,CAAmD,CAC/C,IAAIE,EAAqBF,CAAAG,IAAA,CAAkBC,EAAlB,CAAzB,CACIC,EAAqBhC,CAAA,CAAeA,CAAA8B,IAAA,CAAkBC,EAAlB,CAAf,CAAkE,SACvFF,EAAJ,EAA0BG,CAA1B,GACI,CAAApnD,GAAA,CAAY,qCAAZ,CAAoDinD,CAApD,CAAyE,OAAzE,CAAmFG,CAAnF,CAAwG,8CAAxG,CAEA,CAAKhC,CAAL,EAAoB2B,CAAAM,MAAA,EAHxB,CAH+C,CAHvD;AA2BA3nD,CAAA4mD,GAAA,CAAAA,QAAO,CAACR,CAAD,CACP,CACmBv1D,IAAAA,EAAf,GAAIu1D,CAAJ,GACIA,CADJ,CACa,IAAAA,EADb,GAC6B,IAAAf,EAAA,CAAiBuC,EAAjB,CAA6CtB,EAD1E,EAQA,IAAIlB,CAAA,IAAAA,EAAJ,CAAA,CAGA,IAAAA,EAAA,EAEA,KAAIv7C,EAAW,CAAA,CAAf,CACIg+C,EAAW,CAAA,CACf,KAAAhC,EAAA,CAAqB,CAAA,CACrB,KAAIH,EAAgB,IAAAA,EAAhBA,EAAsC,IAAIx7C,CAAJ,CAAU,IAAV,CArtzBjCq8C,QAqtzBiC,CAE1C,IAAIH,CAAJ,EAAc0B,EAAd,CACIj+C,CAAA,CAAW,CAAA,CADf,KAGK,IAAIu8C,CAAJ,CAAaE,EAAb,CAAwC,CACzC,GAAIZ,CAAAc,KAAA,CAAmB,IAAAnB,EAAnB,CAAJ,CAAyC,CAOrC,IAAAM,EAAA,CAAqB,IAAIz7C,CAAJ,CAAU,IAAV,CAluzBpBq8C,QAkuzBoB,CAAkCwB,EAAlC,CACjB,KAAApC,EAAAa,KAAA,EAAJ,GACIwB,EAAA,CAAAA,IAAA,CAAiBtC,CAAjB,CAWA,CALAU,CAKA,CALS6B,EAKT,CAAAC,EAAA,CAAA,IAAAvC,EAAA,CAZJ,CAeA,KAAAA,EAAAx7C,IAAA,CAAuBs9C,EAAvB,CAl4wBDU,EAAA,EAk4wBC,CACA,KAAAxC,EAAAyC,MAAA,EAEA,KAAIC,EAAY,IAAAjC,EAAZiC,EAA2B,CAAC,IAAA7C,EAChC,IAAIY,CAAJ,EAAcwB,EAAd,EAA2CU,EAAA,CAAsB,mCAAtB,CAA4DpjD,EAA5D,CAA4E,iDAA5E,CAA3C,CAA2K,CAEvK,GADA2iD,CACA,CADWnzD,EAAA,CAAAgxD,CAAA,CACX,CAAc,CACV,IAAI6C,EAA+B7C,CAAA8B,IAAA,CAtjzBvCgB,MAsjzBuC,CAAnC,CACIv0D,EAA+ByxD,CAAA8B,IAAA,CAtjzBvCgB,MAsjzBuC,CAC/BD,EAAJ,GApjzBJE,IAqjzBQ,EAAIF,CAAJ,CACI7C,CAAAc,KAAA,CAAmBvyD,CAAnB,CADJ,EApjzBRw0D,OA0jzBY,EAAIF,CAAJ;AApjzBZG,kBAojzBY,EAAkCz0D,CAAlC,EACI,IAAAqM,GAAA,CAAY,SAAZ,CAAwBrM,CAAxB,CACA,CAxjzBhBy0D,uBAwjzBgB,EAAIz0D,CAAJ,GAmoB5B00D,EAAA,CAAwBC,EAAxB,CAAoD,EAApD,CACA,CApoB8DC,IAooB9D7C,EAAA,CAAe,IApoBa,CAFJ,EAII,IAAAxlD,EAAA,CAAa+nD,CAAb,CAAqB,IAArB,CAA4Bt0D,CAA5B,CAOJ,CADAi0D,EAAA,CAAAxC,CAAA,CACA,CAAIA,CAAAc,KAAA,EAAJ,EACIqB,CACA,CADWnzD,EAAA,CAAAgxD,CAAA,CACX,CAAA2C,CAAA,CAAY,CAAA,CAFhB,EAIIR,CAJJ,CAIe,CAAA,CArBnB,CADJ,CAHU,CAoCVQ,CAAJ,EAAejB,EAAA,CAAAA,IAAA,CAAmBS,CAAA,CAAUnC,CAAV,CAA0B,IAA7C,CAtCwJ,CAA3K,IA2CQU,EAAJ,EAAc6B,EAAd,EAA2CvC,CAAAiC,MAAA,EAtEV,CAAzC,IA6EIP,GAAA,CAAAA,IAAA,CAEJ,QAAO,IAAA/B,EACP,QAAO,IAAAK,EAjFkC,CAwFzC9nD,CAAAA,CAAcyZ,EAAA,CAAwB,IAAApd,GAAxB,CAClB,KAASmd,CAAT,CAAsB,CAAtB,CAAyBA,CAAzB,CAAsCxZ,CAAA5N,OAAtC,CAA0DonB,CAAA,EAA1D,CACQ9b,CACJ,CADgBsC,CAAA,CAAYwZ,CAAZ,CAChB,CAAI9b,CAAJ,GAAkB,IAAlB,EAA0BA,CAA1B,EAAuC,IAAAJ,EAAvC,GACI2sD,CADJ,CACeiB,EAAA,CAAAA,IAAA,CAAkBxtD,CAAlB,CAA6BoqD,CAA7B,CAA4C77C,CAA5C,CAAsDg+C,CAAtD,CADf,CAUAnxD,EAAAA,CAAS,CAACgvD,CAAD,CAAgBU,CAAhB,CAAwByB,CAAxB,CAETzB,EAAJ,EAAc0B,EAAd,CACI,IAAAnB,KAAA,CAAU,IAAAoC,GAAV,CAA4BryD,CAA5B,CADJ,CAIA,IAAAqyD,GAAA,CAAiBryD,CAAjB,CAxHA,CATJ,CA8IAoyD;QAAA,GAAY,CAAZA,CAAY,CAACxtD,CAAD,CAAYoqD,CAAZ,CAA2B77C,CAA3B,CAAqCg+C,CAArC,CACZ,CACI,GAAI,CAACvsD,CAAAf,MAAAK,EAAL,CAA8B,CAM1BU,CAAAf,MAAAK,EAAA,CAA0B,CAAA,CAE1B,KAAIpG,EAAO,IAEX,IAAI,CA0EA,GAzEIqzD,CAyEA,IAxEArzD,CAwEA,CAxEOkxD,CAAA8B,IAAA,CAAkBlsD,CAAArB,GAAlB,CAwEP,IA5DIzF,CA4DJ,CA5DWkxD,CAAA8B,IAAA,CAAkBlsD,CAAArB,GAAAtM,QAAA,CAAqB,aAArB,CAAoC,GAApC,CAAlB,CA4DX,GA7CgB,QA6ChB,GA7CA,MAAO6G,EA6CP,GA7C0BA,CA6C1B,CA7CiC,IA6CjC,EAtCA,CAAC8G,CAAAmG,GAAA,CAAkBjN,CAAlB,CAAwBqV,CAAxB,CAsCD,EAtCsCrV,CAsCtC,GAr9tBZM,CAAA,CAi7tB4B,8BAj7tB5B,CAi7tB6DwG,CAAAnJ,KAj7tB7D,CAk9tBY,CAvBI,CAAAozD,EAAJ,EAAuB,CAAC,CAAAE,EAAxB,EACIC,CAAAiC,MAAA,EAztvBhB,CA0tvBgB,CAAAvB,EA1tvBhB,CA0tvB8BE,EA1tvB9B,CAAIvzD,MAAJ,EAAYA,MAAAC,SAAAg2D,OAAA,EAwtvBA,EASI,CAAAnD,EATJ,CASyB,CAAA,CAczB,CARAvqD,CAAAmG,GAAA,CAAkB,IAAlB,CAQA,CAAAomD,CAAA,CAAW,CAAA,CAGX,EAAA,CAACh+C,CAAD,EAAavO,CAAAnB,GAAjB,CAAoC,CAChC,IAAI8uD,EAAa3tD,CAAAnB,GAAAhF,MAAA,CAAwB,GAAxB,CACjB,KAAShJ,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoB88D,CAAAj5D,OAApB,CAAuC7D,CAAA,EAAvC,CACImP,CAAAxI,OAAA,CAAiBm2D,CAAA,CAAW98D,CAAX,CAAjB,CAH4B,CA1EpC,CAiFJ,MAAO0G,CAAP,CAAY,CA59tBhBiC,CAAA,CA69tBwB,4BA79tBxB,CA69tBuDwG,CAAAnJ,KA79tBvD,CA69tBwE,IA79tBxE,CA69tB+EU,CAAAkC,QA79tB/E,CA69tB6F,GA79tB7F,CA49tBgB,CA3Fc,CA+F9B,MAAO8yD,EAhGX;AA2GA7nD,CAAA+oD,GAAA,CAAAA,QAAW,CAACryD,CAAD,CACX,CACI,IAAIgvD,EAAgBhvD,CAAA,CAAO,CAAP,CAApB,CACImT,EAAwB,CAAxBA,CAAYnT,CAAA,CAAO,CAAP,CACZmxD,EAAAA,CAAWnxD,CAAA,CAAO,CAAP,CAMf,KAAAkvD,EAAA,CAAoB,CAAA,CACpB,KAAArrD,MAAAK,EAAA,CAAqB,CAAA,CACrB,KAAIsuD,EAAe,IAAA9uD,EAAA,MACf8uD,EAAJ,GAAkBA,CAAAxmD,YAAlB,CAA6C,UAA7C,CAMI,KAAAxH,EAAJ,GAII4tD,EAAA,CAAAA,IAAA,CAAkB,IAAA5tD,EAAlB,CAA4BwqD,CAA5B,CAA2C77C,CAA3C,CAAqDg+C,CAArD,CAEA,CADA17C,CAAA,CAAAA,IAAA,CAAqB,EAArB,CACA,CAAA,IAAAjR,EAAA2Z,GAAA,EANJ,CAaI,KAAAgxC,EAAJ,GACImC,EAAA,CAAAA,IAAA,CAAiBtC,CAAjB,CACA,CAAAA,CAAAiC,MAAA,EAFJ,CAKI,EAAC99C,CAAL,EAAiB,IAAA87C,EAAjB,GACI,IAAAA,EAAAgC,MAAA,EACA,CAAA,OAAO,IAAAhC,EAFX,CAKA,KAAAP,EAAA,CAAoB,CAzCxB,CA8EA4C;QAAA,GAAW,CAAXA,CAAW,CAACtC,CAAD,CACX,CACI,GAAI4C,EAAA,CAAsB,mCAAtB,CAA4DpjD,EAA5D,CAA4E,6DAA5E,CAA4IA,EAA5I,CAAqM,wCAArM,CAAJ,CAAA,CACoD4gD,IAAAA,EAAAA,CAAAA,GAhb7C,EAAA,CAgbuDqD,CAhbvDnD,EAAA,EAAgB,EAgb6E,EAAA,CAAAN,CAAAzlD,SAAA,EA7/vBpG,KAAImpD,EAAW,EACfA,EAAA,IAAA,CA4/vBmBlkD,EA3/vBnBkkD,EAAA,IAAA,CArhES7C,QAshET6C,EAAA,IAAA,CAAgCl3D,CAChCk3D,EAAA,KAAA,CAAiCC,CACjCD,EAAA,KAAA,CAt3DYE,KAu3DZF,EAAA,KAAA,CAAiCG,CAEjC1yB,GAAA,CADiB2yB,mCACjB,CAA4BJ,CAA5B,CAAsC,CAAA,CAAtC,CAo/vBA,CADJ;AAqCAra,QAAA,GAAQ,CAARA,CAAQ,CAACptC,CAAD,CAAQC,CAAR,CACR,CACI,IACIktC,EAAS,MAMb,IAAI,CAAAsW,EAAJ,CACI,MAAO,KAEX,EAAAA,EAAA,EAEA,KAAIM,EAAgB,IAAIx7C,CAAJ,CAAU,CAAV,CAjk0BXq8C,QAik0BW,CAApB,CACIc,EAAgB,IAAIn9C,CAAJ,CAAU,CAAV,CAlk0BXq8C,QAkk0BW,CAAkCe,EAAlC,CADpB,CAGImC,EAptxBGtB,EAAA,EAqtxBPd,EAAAl9C,IAAA,CAAkBs9C,EAAlB,CAAiDgC,CAAjD,CACA/D,EAAAv7C,IAAA,CAAkBs9C,EAAlB,CAAiDgC,CAAjD,CACA/D,EAAAv7C,IAAA,CAAkBu/C,EAAlB,CAvk0BSnD,QAuk0BT,CACAb,EAAAv7C,IAAA,CAAkBw/C,EAAlB,CAzhwBQ52D,MAAA,CAAQA,MAAAC,SAAA42D,KAAR,CAA+B,IAyhwBvC,CACAlE,EAAAv7C,IAAA,CAAkB0/C,EAAlB,CAtgwBQ92D,MAAA,CAAQA,MAAAsD,UAAAD,UAAR,CAAqC,EAsgwB7C,CAMA,IAAI,CAAA8E,EAAJ,EAAgB,CAAAA,EAAAwG,GAAhB,CAAoC,CAC5BE,CAAJ,GACQD,CACJ,GADW,CAAAzG,EAAAX,MAAAsa,GACX,CADsC,CAAA3Z,EAAAX,MAAA+Q,EACtC,EAAAK,CAAA,CAAA,CAAAzQ,EAAA,CAFJ,CAIA,KAAA1G,EAAO,CAAA0G,EAAAwG,GAAA,CAAmBC,CAAnB,CAA0BC,CAA1B,CACa,SAApB,GAAI,MAAOpN,EAAX,EAA8BkxD,CAAAv7C,IAAA,CAAkB,CAAAjP,EAAAjB,GAAlB,CAA+BzF,CAA/B,CAC1BoN,EAAJ,GACI,CAAA1G,EAAAX,MAAAK,EACA,CADyB,CAAA,CACzB,CAAa,CAAA,CAAb,GAAIpG,CAAJ,GAAoBs6C,CAApB,CAA6B,IAA7B,CAFJ,CAPgC,CAahClxC,CAAAA,CAAcyZ,EAAA,CAAwB,CAAApd,GAAxB,CAClB,KAAK,IAAImd,EAAa,CAAtB,CAAyBA,CAAzB,CAAsCxZ,CAAA5N,OAAtC,CAA0DonB,CAAA,EAA1D,CAAwE,CACpE,IAAI9b,EAAYsC,CAAA,CAAYwZ,CAAZ,CACZ9b,EAAAf,MAAAK,EAAJ,GACQU,CAAAoG,GAIJ,GAHIlN,CACA,CADO8G,CAAAoG,GAAA,CAAoBC,CAApB,CAA2BC,CAA3B,CACP,CAAoB,QAApB,GAAI,MAAOpN,EAAX,EAA8BkxD,CAAAv7C,IAAA,CAAkB7O,CAAArB,GAAlB;AAAgCzF,CAAhC,CAElC,EAAIoN,CAAJ,GACItG,CAAAf,MAAAK,EACA,CAD0B,CAAA,CAC1B,CAAa,CAAA,CAAb,GAAIpG,CAAJ,GAAoBs6C,CAApB,CAA6B,IAA7B,CAFJ,CALJ,CAFoE,CAcpEA,CAAJ,GACQltC,CAAJ,EAEQkoD,CAmCJ,CApCIC,CAoCJ,CApCa,CAAA,CAoCb,CAlCIpoD,CAAJ,EACQ,CAAAqkD,EAGJ,EAFIgE,EAAA,CAAAA,CAAA,CAAqB,CAAAhE,EAArB,CAAmCN,CAAAzlD,SAAA,EAAnC,CAEJ,CAAKonD,CAAAe,MAAA,EAAL,EAA+B1C,CAAA0C,MAAA,EAA/B,GACItZ,CAOA,CAPS,IAOT,CAAAib,CAAA,CAASD,CAAT,CAAqB,CAAA,CARzB,CAJJ,EA6BQ,CAAA1D,EA7BR,GA8BQ2D,CACA,CADS,CAAA,CACT,CAAAD,CAAA,CAAa,CAAA1D,EAAb,EAA4B6D,EA/BpC,CAkCA,CAAIF,CAAJ,EACIrE,CAAAiC,MAAA,CAAoBmC,CAApB,CAtCR,EAyCIhb,CAzCJ,CAyCa4W,CAAAzlD,SAAA,EA1CjB,CA8CI2B,EAAJ,GACI,CAAArH,MAAAK,EACIsuD,CADiB,CAAA,CACjBA,CAAAA,CAAAA,CAAe,CAAA9uD,EAAA,MAFvB,IAGsB8uD,CAAAxmD,YAHtB,CAGiD,OAHjD,CAMA,EAAA0iD,EAAA,CAAoB,CAEpB,OAAOtW,EA7GX;AA+HA9uC,CAAA4I,MAAA,CAAAA,QAAK,EACL,CACI,IAAArO,MAAAqO,MAAA,CAAmB,CAAA,CACf,KAAAzN,EAAJ,EAAgB,IAAAA,EAAAyN,MAAhB,GACI7G,EAAA,CAAAA,IAAA,CAAkB,YAAlB,CAAiC,IAAA5G,EAAAhJ,KAAjC,CACA,CAAA,IAAAgJ,EAAAyN,MAAA,EAFJ,CAII,KAAA1N,EAAJ,EAAgB,IAAAA,EAAA0N,MAAhB,GACI7G,EAAA,CAAAA,IAAA,CAAkB,YAAlB,CAAiC,IAAA7G,EAAA/I,KAAjC,CACA,CAAA,IAAA+I,EAAA0N,MAAA,EAFJ,CAKA,KADA,IAAIhL,EAAcyZ,EAAA,CAAwB,IAAApd,GAAxB,CAAlB,CACSmd,EAAa,CAAtB,CAAyBA,CAAzB,CAAsCxZ,CAAA5N,OAAtC,CAA0DonB,CAAA,EAA1D,CAAwE,CACpE,IAAI9b,EAAYsC,CAAA,CAAYwZ,CAAZ,CACZ9b,EAAJ,GAAkB,IAAlB,EAA0BA,CAA1B,GAAwC,IAAAH,EAAxC,EAAoDG,CAApD,GAAkE,IAAAJ,EAAlE,EAA8EI,CAAAsN,MAA9E,GACI7G,EAAA,CAAAA,IAAA,CAAkB,YAAlB,CAAiCzG,CAAAnJ,KAAjC,CACA,CAAAmJ,CAAAsN,MAAA,EAFJ,CAFoE,CAOxE,IAAArO,MAAAqO,MAAA,CAAmB,CAAA,CACnBuD,EAAA,CAAAA,IAAA,CAAqB,EAArB,CAnBJ,CAkCAnM,EAAA8C,MAAA,CAAAA,QAAK,CAACrL,CAAD,CAAKwc,CAAL,CACL,CAEI,IADA,IAAIrW,EAAcyZ,EAAA,CAAwB,IAAApd,GAAxB,CAAlB,CACSmd,EAAa,CAAtB,CAAyBA,CAAzB,CAAsCxZ,CAAA5N,OAAtC,CAA0DonB,CAAA,EAA1D,CAAwE,CACpE,IAAI9b,EAAYsC,CAAA,CAAYwZ,CAAZ,CACM,MAAtB,EAAI9b,CAAAnJ,KAAJ,EAA+BmJ,CAA/B,GAA6C,IAA7C,EACIA,CAAAwH,MADJ,EAEIxH,CAAAwH,MAAA,CAAgBrL,CAAhB,CAAoBwc,CAApB,CAJgE,CAOxE9H,CAAA,CAAAA,IAAA,CAAqB,EAArB,CATJ,CAwBAnM;CAAA8I,KAAA,CAAAA,QAAI,CAACrR,CAAD,CAAKwc,CAAL,CACJ,CAEI,IADA,IAAIrW,EAAcyZ,EAAA,CAAwB,IAAApd,GAAxB,CAAlB,CACSmd,EAAa,CAAtB,CAAyBA,CAAzB,CAAsCxZ,CAAA5N,OAAtC,CAA0DonB,CAAA,EAA1D,CAAwE,CACpE,IAAI9b,EAAYsC,CAAA,CAAYwZ,CAAZ,CACM,MAAtB,EAAI9b,CAAAnJ,KAAJ,EAA+BmJ,CAA/B,GAA6C,IAA7C,EACIA,CAAAwN,KADJ,EAEIxN,CAAAwN,KAAA,CAAerR,CAAf,CAAmBwc,CAAnB,CAJgE,CAOxE9H,CAAA,CAAAA,IAAA,CAAqB,EAArB,CATJ,CAoCAA;QAAA,EAAc,CAAdA,CAAc,CAACwM,CAAD,CACd,CASI,GAAI,CAAAzd,EAAJ,CAAA,CAAcA,IAAAA,EAAAA,CAAAA,EAAAA,CAAuB,EAAAyd,CAAA,EAAW,CAAlCzd,CAt3lBV+c,EAAe,CAAA7d,EAAA,MACf6d,EAAJ,GACmB,CADnB,EACQU,CADR,EArZqBuxC,EAqZrB,GACyB,CAAApjD,GADzB,EAC+C6R,CAD/C,KAEQV,CAAAvV,YACA,CAD2BynD,CA2J1B5vD,MAAA+Q,EAAD,CA3J2B6+C,CA2JJn0C,EAAAwB,QAAA,CAAiB,CAAjB,CAAvB,CAA6C,KAA7C,CAAsD,SA1JtD,CAAA,CAAA1Q,GAAA,CAAqB,CAH7B,CAq3lBA,CACA,GAAI,CAAAqC,EAAJ,GAAgBA,CA1vpBZpC,CA0vpBYoC,CAAAA,EA1vpBZpC,CA0vpBqC,CA1vpBrCA,CA0vpBqC4R,CA1vpBrC5R,EA0vpBgD,CA1vpBhDA,CAAA,CAAAA,EA0vpBJ,EA1vpBoB,CAEZggC,CAAAA,CAAW,CAAA7rC,EAgtDZX,MAAA+Q,EA/sDC8+C,EAAAA,CAi3GD,CAAC,EAj3GW,CAAAlvD,EAi3GT6f,EAAF,CAroJIqB,CAqoJJ,CAv2GA,IAAe,CAAf,EAAIzD,CAAJ,EAnkCauxC,EAmkCb,GAAqB,CAAApjD,EAArB,EAA2C6R,CAA3C,EAA2E,CAwjG5E3L,CAAAA,CAvjG6BA,CAAA9R,EAujG7B8R,EA5oHP,IAqlBYq9C,CArlBRjwD,EAAA,GAAJ,CAA2B,CAEvB,IAAI8hC,EAmlBImuB,CAnlBIpvD,EAARihC,EAmlBImuB,CAnlBgBpvD,EAAAihC,EAApBA,EAAsC,CAC1C2hB,EAAA,CAASA,CAAT,EAAmB,CAEfyM,EAAA,CAAgB,CAAT,EAAApuB,CAAA,CAAY/rB,EAAA,CAAU0tC,CAAV,CAPFnvD,IAAAA,EAOE,CAAZ,CAAqCgjB,CAAA,CAAUmsC,CAAV,CAP3BnvD,IAAAA,EAO2B,CAglBxC27D,EAtkBJjwD,EAAA,GAAAsI,YAAJ,EAAyC4nD,CAAzC,GAskBQD,CAtkBuCjwD,EAAA,GAAAsI,YAA/C,CAAmF4nD,CAAnF,CAfuB,CAslBf,CAAAxjD,EAAA,CAAqB,CAFkD,CAW5D,EAAf,CAAI6R,CAAJ,CACI,CAAA3R,EADJ,CACmB,CAAA9L,EA4iGpB8R,EA7iGC,CAEqB,CAFrB,CAEW2L,CAFX,EAE0BouB,CAF1B,EAEsC,CAACqjB,CAFvC,GAGI,CAAApjD,EAHJ,CAGmB,CAAA9L,EAkkGpB4f,GArkGC,CAMAvQ,GAAA,CAAAA,CAAA,CAAgB,CAAAvD,EAAhB,CACA+B,GAAA,CAAAA,CAAA,CAAgB,CAAA5B,EAAhB,CA/BY,CAgvpBxB;AAuBAnH,CAAAvC,GAAA,CAAAA,QAAU,CAACQ,CAAD,CAAQkC,CAAR,CAAkB/D,CAAlB,CACV,CACI,IAAI2E,EAAW,IAEf,QAAQZ,CAAR,EACA,KAAK,OAAL,CAKI,MAJA,KAAA/F,EAAA,CAAc+F,CAAd,CAIO,CAJmB/D,CAInB,CAHPA,CAAAgE,QAGO,CAHW+W,QAAqB,EAAG,CACtCpW,CA2QHqkD,EAAL,GA3QQrkD,CA4QCxG,MAAAK,EAAL,CAGIm0C,EAAA,CA/QAhuC,CA+QA,CAAc,CAAA,CAAd,CAAqB,CAAA,CAArB,CAHJ,CA5QIA,CA6QA4lD,KAAA,CA7QA5lD,CA6QU6lD,GAAV,CAFR,CA5Q8C,CAGnC,CAAA,CAAA,CAEX,MAAK,OAAL,CAKI,MAJA,KAAAxsD,EAAA,CAAc+F,CAAd,CAIO,CAJmB/D,CAInB,CAHPA,CAAAgE,QAGO,CAHW+W,QAAqB,EAAG,CA2R9C,GA1RQpW,CA0RHxG,MAAAK,EAAL,EAA2BwqD,CA1RnBrkD,CA0RmBqkD,EAA3B,CAWA,GArSQrkD,CAqSJqlD,EAAJ,EAAmB,CArSXrlD,CAqSYukD,EAApB,CAAsC,CAKlC,IAAI3jD,EAA2D2mD,EAAA,CAAsB,mCAAtB,CAA4DpjD,EAA5D,CAA4E,0EAA5E,CAC/D6pC,GAAA,CA3SIhuC,CA2SJ,CAAcY,CAAd,CAAqB,CAAA,CAArB,CAaI,EAACA,CAAL,EAxTIZ,CAwTUwkD,EAAd,CA77wBAxyD,MA67wBA,EA77wBQA,MAAAC,SAAAg2D,OAAA,EA67wBR,CAxTIjoD,CA6TJ6lD,GAAA,CAAaN,EAAb,CAxBkC,CAAtC,IArSQvlD,EAgUJ6H,MAAA,EACA,CAjUI7H,CAiUA7F,EAAJ,EAAgB,CAjUZ6F,CAiUa9F,EAAjB,EAjUI8F,CAiUuB7F,EAAA2Z,GAAA,EAlUe,CAGnC,CAAA,CAAA,CAQX,MAAK,MAAL,CAMI,GAAIsmC,EAAA,CAAaxkB,EAAA,EAAb,CAA4B,UAA5B,CAAJ,CASIv6B,CAAAU,WAAAytD,YAAA,CAAoDnuD,CAApD,CATJ;IA6CA,OAjCA,KAAAhC,EAAA,CAAc+F,CAAd,CAiCO,CAjCmB/D,CAiCnB,CAhCPA,CAAAgE,QAgCO,CAhCW+W,QAAoB,EAAG,CACrC,IAAI6uC,EAAUC,EAAA,CAAAllD,CAAA,CAAqB,CAAA,CAArB,CACd,IAAIilD,CAAJ,CAAa,CAQT,IAAIrkD,EAAQ,CAAC,EAAEZ,CAAAqlD,EAAF,EAAqB,CAACrlD,CAAAukD,EAAtB,EAA8CvkD,CAAAwkD,EAA9C,CAAb,CACIzW,EAASC,EAAA,CAAAhuC,CAAA,CAAkBY,CAAlB,CACTA,EAAJ,CACIqoD,EAAA,CAAAjpD,CAAA,CAAyBilD,CAAzB,CAAkClX,CAAlC,CADJ,CAGI/tC,CAAAT,GAAA,CAAgB,0CAAhB,CAbK,CAFwB,CAgClC,CAAA,CAAA,CAxEX,CA6EA,MAAO,CAAA,CAhFX,CAqGA2lD;QAAA,GAAW,CAAXA,CAAW,CAACuE,CAAD,CACX,CACI,IAAIxE,EAAU,CAAAA,EACTA,EAAL,GAEI,CADAA,CACI,CADMyE,EAAA,CAAwB7B,EAAxB,CACN,CAAY/3D,IAAAA,EAAZ,GAAAm1D,CAAJ,EACQ,CAACA,CADT,EACoBwE,CADpB,GA35uBAzzB,CAIJivB,CAJgB,IAIhBA,CAHIjzD,MAGJizD,GAFIjvB,CAEJivB,CAFgBjzD,MAAA23D,OAAA,CAg6uB2B1uD,wIAh6uB3B,CAA+C,EAA/C,CAEhBgqD,EAAA,CAAAA,CAAOjvB,CAu5uBH,KASYivB,CATZ,CASsB2E,EAAA,CAAAA,CAAA,CAAkB3E,CAAlB,CATtB,GAU0B,CAAA1lD,GAAA,CAAY,yBAAZ,CAV1B,EAaWkqD,CAbX,EAcI,CAAAlqD,GAAA,CAAY,wCAAZ,CAhBR,CAmBA,OAAO0lD,EArBX;AA+BA2E,QAAA,GAAY,CAAZA,CAAY,CAAC3E,CAAD,CACZ,CACI,CAAAA,EAAA,CAAe,IAIXrzD,EAAAA,CAAWkkC,EAAA,CADAF,EAAA,EACA,CADmH,wCACnH,CADyHqvB,CACzH,CAEf,KAAIjvB,EAAYpkC,CAAA,CAAS,CAAT,CAChB,IAAI,CAFaA,CAAAO,CAAS,CAATA,CAEjB,EAAmB6jC,CAAnB,CACI,GAAI,CACApkC,CACA,CADWgC,IAAA,CAAK,GAAL,CAAWoiC,CAAX,CAAuB,GAAvB,CACX,CAAIpkC,CAAAi4D,KAAJ,EAvv0BInC,IAuv0BJ,EAAqB91D,CAAAi4D,KAArB,GACIjC,EAAA,CAAwBC,EAAxB,CAAoDj2D,CAAA6B,KAApD,CAEA,CAAA,CAAAwxD,EAAA,CAAerzD,CAAA6B,KAHnB,CAFA,CASF,MAAOzI,CAAP,CAAU,CAl/uBhB+I,CAAA,CAm/uBwB/I,CAAAgJ,QAn/uBxB,CAm/uBoC,IAn/uBpC,CAm/uB2CgiC,CAn/uB3C,CAm/uBuD,GAn/uBvD,CAk/uBgB,CAMhB,MAAO,EAAAivB,EAxBX,CAiCAS,QAAA,GAAkB,CAAlBA,CAAkB,CAClB,CACI,IAAIlB,EAAa,IACb,EAAAS,EAAJ,GAIIT,CAJJ,CAIiB5uB,EAAA,EAJjB,CAIkI,sCAJlI,CAIwI,CAAAqvB,EAJxI,CAImL,eAJnL,CAIyL6E,EAAA,CAAU,CAAV,CA390BhLtE,QA290BgL,CAJzL,CAUA,OAAOhB,EAZX;AAsBAyE,QAAA,GAAe,CAAfA,CAAe,CAAChE,CAAD,CAAUlX,CAAV,CACf,CAOI,GAAIA,CAAJ,CAAY,CA0CZ,IAAIsa,EAAW,CAt20BH0B,IAQAC,OA810BG,CAEf3B,EAAA,KAAA,CAxCyCpD,CAyCzCoD,EAAA,MAAA,CAAgCyB,EAAA,CAzCbG,CAyCa,CAhi1BvBzE,QAgi1BuB,CAChC6C,EAAA,KAAA,CA1CkDta,CA+C1Cn8C,EAAAA,CAAWkkC,EAAA,CAJJF,EAAA,EAII,CAj30BPs0B,cAi30BO,CAA0B7B,CAA1B,CACXryB,EAAAA,CAAYpkC,CAAA,CAAS,CAAT,CAChB,IAAIA,CAAA,CAAS,CAAT,CAAJ,CAAiB,CACb,GAAIokC,CAAJ,CAAe,CACX,IAAI5qC,EAAI4qC,CAAArpC,QAAA,CAAkB,IAAlB,CACA,EAAR,CAAIvB,CAAJ,GAAW4qC,CAAX,CAAuBA,CAAAjpC,OAAA,CAAiB,CAAjB,CAAoB3B,CAApB,CAAvB,CACK4qC,EAAArpC,QAAA,CAAkB,SAAlB,CAAL,GAAmCqpC,CAAnC,CAA+CA,CAAAjpC,OAAA,CAAiB,CAAjB,CAA/C,CAHW,CAKfipC,CAAA,CAAY,UAAZ,CAA6CpkC,CAAA,CAAS,CAAT,CAA7C,CAAqF,WAArF,CAA6FokC,CAA7F,CAAyG,IAN5F,CASjB,CAAA,CAAOtiC,IAAAC,MAAA,CAAWqiC,CAAX,CAzDHpkC,EAAJ,EAjz0BQ81D,IAiz0BR,EAAgB91D,CAAA,KAAhB,CACI,CAAA2N,GAAA,CAAY,+BAAZ,CADJ,CAEWwuC,CAFX,GAGQsT,CAnHZ,CAmHsBzvD,CAnHtB,EAmHkCA,CAAA,KAnHlC,EAxr0BY+1D,8BAwr0BZ,CAqHYtG,CArHZ,CAhs0BYqG,OAoz0BJ,EAAI91D,CAAA,KAAJ,CACa,SADb,CACyByvD,CADzB,CAGa,QAHb,CAGwBzvD,CAAA,KAHxB,CAGqD,IAHrD,CAG4DyvD,CAvHpE,CAyHQ,CAAA9hD,GAAA,CAAY8hD,CAAZ,CAzHR,CADAuG,EAAA,CAAwBC,EAAxB,CAAoD,EAApD,CACA,CA0HQC,CA1HR7C,EAAA,CAAe,IAgHX,CALQ,CAPhB;AAsLArvC,QAAA,GAAQ,CAARA,CAAQ,CAACu0C,CAAD,CACR,CACI,GAAI,CAAAzc,EAAJ,CAAuB,CAAA,IAMfvhD,EAAI,CANW,CAMRC,EAAI,CACX,EAAC+9D,CAAL,EAAgBn4D,MAAhB,GACI7F,CACA,CADI6F,MAAAoxC,QACJ,CAAAh3C,CAAA,CAAI4F,MAAAqxC,QAFR,CAKA,EAAAqK,EAAApK,MAAA,EAEI,EAAC6mB,CAAL,EAAgBn4D,MAAhB,EACIA,MAAAuxC,SAAA,CAAgBp3C,CAAhB,CAAmBC,CAAnB,CAfe,CAD3B,CA2KJ,IAAA46D,GAAgC,UAAhC,CACAT,GAAgC,UADhC,CAEAG,GAAgC,WAFhC,CAGAiC,GAAgC,SAHhC,CAIAC,GAAgC,KAJhC,CAKAE,GAAgC,SALhC,CAMAjB,GAAgC,MANhC,CAaAd,GAAiC,EAbjC,CAcAxB,GAAiC,CAdjC,CAeAsB,GAAiC,CAfjC,CAgBAK,GAAiC,CAhBjC,CAiBAgC,GAAiC,CAKjCp8C,GAAA,CApKIZ,QAAW,EACX,CAQI,IAFA,IAAIk+C,EAAatuD,CAAA,CAA6BsQ,QAA7B,CAAuCxQ,CAAvC,CAAwD,UAAxD,CAAjB,CAESyuD,EAAW,CAApB,CAAuBA,CAAvB,CAAkCD,CAAAn7D,OAAlC,CAAqDo7D,CAAA,EAArD,CAAiE,CAE7D,IAAIC,EAAWF,CAAA,CAAWC,CAAX,CAAf,CACIrG,EAAevnD,EAAA,CAA4B6tD,CAA5B,CAEfC,EAAAA,CAAczuD,CAAA,CAA6BwuD,CAA7B,CAAuC1uD,CAAvC,CAAuD,UAAvD,CAElB,KAAK,IAAI4uD,EAAY,CAArB,CAAwBA,CAAxB,CAAoCD,CAAAt7D,OAApC,CAAwDu7D,CAAA,EAAxD,CAAqE,CAEjE,IAAIC,EAAYF,CAAA,CAAYC,CAAZ,CAAhB,CACIzG,EAAgBtnD,EAAA,CAA4BguD,CAA5B,CAMhBzqD,EAAAA,CAAW,IAAI8jD,EAAJ,CAAkBC,CAAlB,CAAiCC,CAAjC,CAA+C,CAAA,CAA/C,CAWfx3C,GAAA,CAAgCxM,CAAhC,CAA0CyqD,CAA1C,CAKIzqD,EAAAmkD,EAAJ,EAAyBnkD,CAAA4lD,KAAA,CAAc5lD,CAAA6lD,GAAd,CAzBwC,CAPR,CARrE,CAmKJ,CA70wBQhuD;EAAA,KAAAxD,KAAA,CAguwBJq2D,QAAW,EACX,CAEI,IADA,IAAIH,EAAczuD,CAAA,CAA6BsQ,QAA7B,CAAuCxQ,CAAvC,CAAuD,UAAvD,CAAlB,CACS4uD,EAAY,CAArB,CAAwBA,CAAxB,CAAoCD,CAAAt7D,OAApC,CAAwDu7D,CAAA,EAAxD,CAAqE,CAEjE,IAAIzG,EAAgBtnD,EAAA,CADJ8tD,CAAAE,CAAYD,CAAZC,CACI,CAEpB,IADIzqD,CACJ,CAD6CpB,EAAA,CAA6B,UAA7B,CAAyCmlD,CAAA,GAAzC,CAC7C,CAEI/jD,CAAAxG,MAAAM,GAWA,CAX2B,CAAA,CAW3B,CAAIkG,CAAA6kD,EAAJ,EAA6B,CAAC7kD,CAAAxG,MAAAK,EAA9B,EAIImG,CAAA6lD,GAAA,CAAiBkB,EAAjB,CArByD,CAFzE,CAjuwBI,CAYAlvD,GAAA,KAAAxD,KAAA,CA4wwBJs2D,QAAW,EACX,CAEI,IADA,IAAIJ,EAAczuD,CAAA,CAA6BsQ,QAA7B,CAAuCxQ,CAAvC,CAAuD,UAAvD,CAAlB,CACS4uD,EAAY,CAArB,CAAwBA,CAAxB,CAAoCD,CAAAt7D,OAApC,CAAwDu7D,CAAA,EAAxD,CAAqE,CAEjE,IAAIzG,EAAgBtnD,EAAA,CADJ8tD,CAAAE,CAAYD,CAAZC,CACI,CAEpB,IADIzqD,CACJ,CAD6CpB,EAAA,CAA6B,UAA7B,CAAyCmlD,CAAA,GAAzC,CAC7C,CAKI/jD,CAAAxG,MAAAM,GAMA,CAN2B,CAAA,CAM3B,CAAIkG,CAAAxG,MAAAK,EAAJ,EAMIm0C,EAAA,CAAAhuC,CAAA,CAAkB,EAAGqlD,CAAArlD,CAAAqlD,EAAH,EAAuBrlD,CAAAukD,EAAvB,CAAlB,CAAgE,CAAA,CAAhE,CArByD,CAFzE,CA7wwBI,CAq2wBJzrD,SAzBEqQ,EAyBS,CAAC5O,CAAD,CAAYqwD,CAAZ,CAAsB57D,CAAtB,CACX,CACI,IAAAkK,GAAA,CAAUqB,CAAArB,GAEV,KAAA2xD,EAAA,CAAY,EACZ,KAAA3hD,EAAA,CAAa,EACb,KAAAwuB,EAAA,CAAe,IAAAozB,EAAf,CAA8B,CAAA,CAC9B,KAAAC,IAAA,CAAWjB,EAAA,CAAUvvD,CAAV,CAAqBqwD,CAArB,CAA+B57D,CAA/B,CACXm4D,GAAA,CAAAA,IAAA,CAAY5sD,CAAAvB,GAAZ,CAPJ,CAiBA,CAAA,CAn61BJ,CAAAgyD,UAm61BI/rD,EAAAmK,IAAA,CAAAA,QAAG,CAAClQ,CAAD,CAAKzF,CAAL,CACH,CACI,GAAI,CACA,IAAAyV,EAAA,CAAWhQ,CAAX,CAAA,CAAiBzF,CADjB,CAEF,MAAMzI,CAAN,CAAS,EAHf,CAeAiU;CAAAwnD,IAAA,CAAAA,QAAG,CAACvtD,CAAD,CACH,CACI,MAAO,KAAAgQ,EAAA,CAAWhQ,CAAX,CAAP,EAAyB,IAD7B,CAUA+F,EAAAxL,KAAA,CAAAA,QAAI,EACJ,CACI,MAAO,KAAAyV,EADX,CAcAjK,EAAAwmD,KAAA,CAAAA,QAAI,CAACoF,CAAD,CACJ,CACI,MAAIA,EAAJ,EACI,IAAAA,EAGO,CAHKA,CAGL,CAFP,IAAAnzB,EAEO,CAFQ,CAAA,CAER,CADP,IAAAozB,EACO,CADQ,CAAA,CACR,CAAA,CAAA,CAJX,EAMI,IAAApzB,EAAJ,CAIW,CAAA,CAJX,CAMIuzB,EAAA,EAAJ,GACQn/D,CADR,CACY49D,EAAA,CAAwB,IAAAqB,IAAxB,CADZ,GAGQ,IAAAF,EACA,CADY/+D,CACZ,CAAA,IAAA4rC,EAAA,CAAe,CAAA,CAJvB,EASO,CAAA,CAtBX,CAmCA/jC,SAAA,GAAK,CAALA,CAAK,CACL,CACI,IAAIqK,EAAW,CAAA,CACf,IAAI,CAAC,CAAA8sD,EAAL,CACI,GAAI,CACA,CAAA5hD,EACA,CADaxV,IAAAC,MAAA,CAAW,CAAAk3D,EAAX,CACb,CAAA,CAAAC,EAAA,CAAe,CAAA,CAFf,CAGF,MAAO9/D,CAAP,CAAU,CA5hwBhB+I,CAAA,CA6hwBwB/I,CAAAgJ,QA7hwBxB,EA6hwBqChJ,CA7hwBrC,CA8hwBQ,CAAAgT,CAAA,CAAW,CAAA,CAFH,CAKhB,MAAOA,EAXX,CAoBAiB,CAAAooD,MAAA,CAAAA,QAAK,EACL,CACI,IAAIrpD,EAAW,CAAA,CACf,IAAIitD,EAAA,EAAJ,CAA2B,CACvB,IAAIn/D,EAAI4H,IAAAw3D,UAAA,CAAe,IAAAhiD,EAAf,CACJ0+C,GAAA,CAAwB,IAAAmD,IAAxB,CAAkCj/D,CAAlC,CAAJ,GA/iwBJiI,CAAA,CAwjwBwB,kBAxjwBxB,CAwjwB6CjI,CAAAmD,OAxjwB7C,CAwjwBwD,iCAxjwBxD,CAyjwBQ,CAAA+O,CAAA,CAAW,CAAA,CAVf,CAFuB,CAe3B,MAAOA,EAjBX,CA0BAiB;CAAAC,SAAA,CAAAA,QAAQ,EACR,CACI,MAAO,KAAAgK,EAAA,CAAYxV,IAAAw3D,UAAA,CAAe,IAAAhiD,EAAf,CAAZ,CAAyC,IAAA2hD,EADpD,CAcA1D,SAAA,GAAM,CAANA,CAAM,CAACnuD,CAAD,CACN,CACI,CAAA6xD,EAAA,CAAY,EACZ,EAAA3hD,EAAA,CAAa,EACb,EAAAwuB,EAAA,CAAe,CAAAozB,EAAf,CAA8B,CAAA,CAC1B9xD,EAAJ,EAAW,CAAAoQ,IAAA,CAAS,OAAT,CAAkBpQ,CAAlB,CAJf,CAgBAiG,CAAA2nD,MAAA,CAAAA,QAAK,CAACuE,CAAD,CACL,CACIhE,EAAA,CAAAA,IAAA,CAp5xBA,KAAIv8D,EAAI,EACR,IAAI,CACA,IADA,IACSQ,EAAI,CADb,CACgBN,EAAIkH,MAAA2C,aAAA1F,OAApB,CAAgD7D,CAAhD,CAAoDN,CAApD,CAAuDM,CAAA,EAAvD,CACIR,CAAAyJ,KAAA,CAAOrC,MAAA2C,aAAAo2D,IAAA,CAAwB3/D,CAAxB,CAAP,CAFJ,CAIF,MAAOJ,CAAP,CAAU,EAi5xBZ,IAASI,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CA94xBOR,CA84xBaqE,OAApB,CAAkC7D,CAAA,EAAlC,CAEI,IADI6J,CACJ,CAh5xBGrK,CA+4xBQ,CAAMQ,CAAN,CACX,IAAa+/D,CAAb,EAAqBl2D,CAAAlI,OAAA,CAAY,CAAZ,CAAe,IAAAg+D,IAAA97D,OAAf,CAArB,EAAwD,IAAA87D,IAAxD,EAAmE,CAt6xBvE,GAAI,CACA/4D,MAAA2C,aAAAI,WAAA,CAs6xB+BE,CAt6xB/B,CADA,CAEF,MAAOjK,CAAP,CAAU,EAoBLJ,CAm5xBCwT,OAAA,CAAahT,CAAb,CAAgB,CAAhB,CACAA,EAAA,CAAI,CAJ2D,CAL3E,CAwBA2/D;QAAO,GAAG,CAACxwD,CAAD,CAAYqwD,CAAZ,CAAsB57D,CAAtB,CACV,CACQ+7D,CAAAA,CAAMxwD,CAAArB,GACV,IAAI0xD,CAAJ,CAAc,CACV,IAAIx/D,EAAIw/D,CAAAj+D,QAAA,CAAiB,GAAjB,CACA,EAAR,CAAIvB,CAAJ,GAAW2/D,CAAX,EAAkB,IAAlB,CAAyBH,CAAA79D,OAAA,CAAgB,CAAhB,CAAmB3B,CAAnB,CAAzB,CAFU,CAIV4D,CAAJ,GACI+7D,CADJ,EACW,GADX,CACiB/7D,CADjB,CAGA,OAAO+7D,EATX,CA0JJ,IAAIK,GAAiB,CAoCrBC,SAASA,GAAO,CAACC,CAAD,CAAW/xD,CAAX,CAAgCoC,CAAhC,CAA2CjG,CAA3C,CAAmD2G,CAAnD,CAA2DkvD,CAA3D,CAAqEC,CAArE,CAA8El6D,CAA9E,CAChB,CASIk6D,CAAA,CAAQ,UAAR,CAAqBF,CAArB,CAAgC,KAAhC,CACAx1B,GAAA,CAAgBw1B,CAAhB,CAA0B,IAA1B,CAhDSj6D,CAAAA,CAgDT,CATkBo6D,QAAQ,CAACC,CAAD,CAAWC,CAAX,CAAiBx5D,CAAjB,CAA6B,CAC/CA,CAAJ,EACSw5D,CACL,GADWA,CACX,CADkB,iBAClB,CADsCL,CACtC,CADiD,IACjD,CADwDn5D,CACxD,CADqE,GACrE,EAAAb,CAAA,CAAKq6D,CAAL,CAAW,IAAX,CAFJ,EAKAC,EAAA,CAASD,CAAT,CAAeL,CAAf,CAAyB/xD,CAAzB,CAA8CoC,CAA9C,CAAyDjG,CAAzD,CAAiE2G,CAAjE,CAAyEkvD,CAAzE,CAAmFC,CAAnF,CAA4Fl6D,CAA5F,CANmD,CASvD,CAVJ;AA+BAs6D,QAASA,GAAQ,CAACD,CAAD,CAAOL,CAAP,CAAiB/xD,CAAjB,CAAsCoC,CAAtC,CAAiDjG,CAAjD,CAAyD2G,CAAzD,CAAiEkvD,CAAjE,CAA2EC,CAA3E,CAAoFl6D,CAApF,CACjB,CACmBu6D,QAAA,EAAQ,CAACF,CAAD,CAAOtK,CAAP,CAAe,CAClC,GAAIA,CAAJ,CACI/vD,CAAA,CAAK+vD,CAAL,CAAa,IAAb,CADJ,KAAA,CAIA,GAAI9nD,CAAJ,CAAe,CAMX08B,EAAA,CAA6B18B,CAA7B,CAAwC+xD,CAAxC,CAAkDK,CAAlD,CAGA,EADIx6D,CACJ,CADWm6D,CACX,GAAgC,CAAhC,CAAYn6D,CAAAxE,QAAA,CAAa,GAAb,CAAZ,EAA2E,GAA3E,EAAqCqF,MAAAC,SAAA65D,SAAA7+D,MAAA,CAAgC,EAAhC,CAArC,GACIkE,CADJ,CACWa,MAAAC,SAAA65D,SADX,CACsC36D,CADtC,CAOKuE,EAAL,CAE+B,GAAxB,EAAIA,CAAAzI,MAAA,CAAc,EAAd,CAAJ,EACHyI,CACA,CADSA,CAAAzI,MAAA,CAAa,CAAb,CAAiB,EAAjB,CACT,CAAoB,CAApB,CAAIyI,CAAAzG,OAAJ,GAAuByG,CAAvB,EAAiC,GAAjC,CAFG,EAIHA,CAJG,CAIM,UAJN,CAImBA,CAJnB,CAI4B,IANnC,CACIA,CADJ,CACa,GAObA,EAAA,EAAU,OAAV,CAAoBvE,CAApB,CAA2B,IAUH,SAAxB,EAAI,MAAOiB,UAAX,GAAkCjB,CAAlC,CAAyC,IAAzC,CACAuE,EAAA,CAASA,CAAA9I,QAAA,CAAe,KAAf,CAAsB,MAAtB,CACT,IAAIyP,CAAJ,CAAY,CAMR,IAAIlP,EAAQw+D,CAAAx+D,MAAA,CAAW,4CAAX,CACRA,EAAJ,GACIw+D,CACA,CADOA,CAAA/+D,QAAA,CAAaO,CAAA,CAAM,CAAN,CAAb,CAAuBA,CAAA,CAAM,CAAN,CAAvB,CAAkCA,CAAA,CAAM,CAAN,CAAlC,CAA6CkP,CAA7C,CAAsDlP,CAAA,CAAM,CAAN,CAAtD,CACP,CAAAkP,CAAA,CAAS,IAFb,CAPQ,CAYZsvD,CAAA,CAAOA,CAAA/+D,QAAA,CAAa,iCAAb;AAAgD,MAAhD,CAAyD2M,CAAzD,CAAqE,IAArE,EAA6E8C,CAAA,CAAQ,aAAR,CAAqBA,CAArB,CAA8B,GAA9B,CAAoC,EAAjH,GAAwH3G,CAAA,CAAQ,aAAR,CAAqBA,CAArB,CAA8B,GAA9B,CAAoC,EAA5J,GAAmKvE,CAAA,CAAM,WAAN,CAAiBA,CAAjB,CAAwB,GAAxB,CAA8B,EAAjM,EAhDI,CAmDVo6D,CAAL,GAKII,CACA,CADOA,CAAA/+D,QAAA,CAAa,sDAAb,CAAqE,WAArE,CACP,CAAA++D,CAAA,CAAOA,CAAA/+D,QAAA,CAAa,uDAAb,CAAsE,IAAtE,CAA6E+O,CAA7E,CAAyF,IAAzF,CANX,CAiCIowD,EAAAA,CAAS,IACb,IAAsB,MAAtB,EAAIJ,CAAA7+D,OAAA,CAAY,CAAZ,CAAJ,CACI,GAAI,CASKy+D,CASL,GARII,CAQJ,CARWA,CAAA/+D,QAAA,CAAa,4BAAb,CAA2C,EAA3C,CAQX,EAAIoF,MAAAM,cAAJ,EAA4B,eAA5B,EAA+CN,OAA/C,EACI+5D,CAEA,CAFS,IAAI/5D,MAAAM,cAAJ,CAAyB,kBAAzB,CAET,CADAy5D,CAAAC,MACA,CADe,CAAA,CACf,CAAAD,CAAA,QAAA,CAAkBJ,CAAlB,CAHJ,EAMII,CANJ,CAMaE,CAAC,IAAIj6D,MAAAk6D,UAALD,iBAAA,CAAyCN,CAAzC;AAA+C,UAA/C,CAxBb,CA0BF,MAAM3gE,CAAN,CAAS,CACP+gE,CACA,CADS,IACT,CAAAJ,CAAA,CAAO3gE,CAAAgJ,QAFA,CA3Bf,IAgCI23D,EAAA,CAAO,oBAAP,EAA6C,GAAd,CAAAA,CAAA18D,OAAA,CAAmB08D,CAAA5+D,OAAA,CAAY,CAAZ,CAAe,GAAf,CAAnB,CAAyC,KAAzC,CAAiD4+D,CAAhF,CAEJr6D,EAAA,CAAKq6D,CAAL,CAAWI,CAAX,CA3HA,CADkC,CA8HlCJ,CAAJ,CAEQJ,CAAJ,CACIY,EAAA,CAAWR,CAAX,CAAiBH,CAAjB,CAA0BK,CAA1B,CADJ,CAIAA,CAAA,CAASF,CAAT,CAAe,IAAf,CANJ,CASAr6D,CAAA,CAAK,SAAL,EAAkBg6D,CAAA,CAAU,aAAV,CAA0BA,CAA1B,CAAqC,EAAvD,EAA4D,IAA5D,CAxIJ;AAwJAa,QAASA,GAAU,CAACR,CAAD,CAAOH,CAAP,CAAgBl6D,CAAhB,CACnB,CACI,IAAI86D,CAGJ,IAAKA,CAAL,CAFYC,kCAEIv2D,KAAA,CAAW61D,CAAX,CAAhB,CAAmC,CAE/B,IAAIW,EAAWF,CAAA,CAAS,CAAT,CA2DfZ,EAAA,CAAQ,UAAR,CAAqBc,CAArB,CAAgC,KAAhC,CACAx2B,GAAA,CAAgBw2B,CAAhB,CAA0B,IAA1B,CAjSKj7D,CAAAA,CAiSL,CA1DkBk7D,QAAQ,CAACb,CAAD,CAAWc,CAAX,CAAoBr6D,CAApB,CAAgC,CACtD,GAAIA,CAAJ,EAAkB,CAACq6D,CAAnB,CACIl7D,CAAA,CAAKq6D,CAAL,CAAW,mCAAX,CAAiDS,CAAA,CAAS,CAAT,CAAjD,CAA+D,IAA/D,CAAsEj6D,CAAtE,CAAmF,GAAnF,CADJ,KAAA,CAUA,GADIs6D,CACJ,CADgBL,CAAA,CAAS,CAAT,CAChB,CAEI,GADIM,CACJ,CADiBF,CAAAr/D,MAAA,CAAc,IAAIyQ,MAAJ,CAAW,MAAX,CAAiBwuD,CAAA,CAAS,CAAT,CAAjB,CAA+B,cAA/B,CAAd,CACjB,CAAgB,CAOZ,IANA,IAAIO,EAAaD,CAAA,CAAW,CAAX,CAAjB,CAIIE,CAJJ,CAKIC,EAAS,2BACb,CAAQD,CAAR,CAAoBC,CAAA/2D,KAAA,CAAY22D,CAAZ,CAApB,CAAA,CAKQE,CAAA,CAJ+D,CAAnE,CAAIA,CAAA79D,YAAA,EAAAnC,QAAA,CAAiCigE,CAAA,CAAU,CAAV,CAAA99D,YAAA,EAAjC,CAAJ,CAIiB69D,CAAA//D,QAAA,CAAmB,MAAnB,CAAwBggE,CAAA,CAAU,CAAV,CAAxB,CAAuC,MAAvC,CAJjB,CASiBD,CAAA//D,QAAA,CAAmB,IAAIgR,MAAJ,CAAWgvD,CAAA,CAAU,CAAV,CAAX,CAA0B,iBAA1B,CAAnB,CAAiEA,CAAA,CAAU,CAAV,CAAjE,CAGjBF,EAAA,CAAW,CAAX,CAAJ,EAAqBC,CAArB,GACIH,CADJ,CACcA,CAAA5/D,QAAA,CAAgB8/D,CAAA,CAAW,CAAX,CAAhB,CAA+BC,CAA/B,CADd,CApBY,CAAhB,IAuBO,CACHr7D,CAAA,CAAKq6D,CAAL,CAAW,cAAX;AAAyBS,CAAA,CAAS,CAAT,CAAzB,CAAuC,UAAvC,CAAiDE,CAAjD,CACA,OAFG,CAcXE,CAAA,CAAUA,CAAA5/D,QAAA,CAAgB,qBAAhB,CAAuC,EAAvC,CAEV++D,EAAA,CAAOA,CAAA/+D,QAAA,CAAaw/D,CAAA,CAAS,CAAT,CAAb,CAA0BI,CAA1B,CAEPL,GAAA,CAAWR,CAAX,CAAiBH,CAAjB,CAA0Bl6D,CAA1B,CArDA,CADsD,CA0D1D,CA9D+B,CAAnC,IAiEAA,EAAA,CAAKq6D,CAAL,CAAW,IAAX,CArEJ;AAuFAmB,QAASA,GAAY,CAAWnxD,CAAX,CAAgCpC,CAAhC,CAA2C+xD,CAA3C,CAAqDyB,CAArD,CAA+Dr3D,CAA/D,CAAuE2G,CAAvE,CACrB,CAyByB2wD,QAAA,EAAQ,CAAClyD,CAAD,CAAW,CACpC,GAAiBhL,IAAAA,EAAjB,GAAIm9D,CAAJ,CAA4B,CAaxB,IAAIC,EAAa5C,CAAb4C,EAAyBpxD,CAAA,CAA6BwuD,CAA7B,CAAuC,iBAAvC,CAC7B2C,EAAA,CAAYC,CAAZ,EAAyBA,CAAA,CAAU,CAAV,CAAzB,EAA0C5C,CAdlB,CAgBxB2C,CAAJ,GAAcA,CAAAE,UAAd,CAAmCC,EAAA,CAAetyD,CAAf,CAAnC,CAjBoC,CAPrBuyD,QAAA,EAAQ,CAAChM,CAAD,CAAS,CAEhC2L,CAAA,CAAe,SAAf,CAA2B3L,CAA3B,CACIrjD,EAAJ,GARK,EAAEotD,EAQP,EAPgBkC,EAAA,CAAqB,CAAA,CAArB,CAOhB,CACAtvD,EAAA,CAAW,CAAA,CAJqB,CAlBxC,IACQssD,CADR,CACkB2C,CADlB,CAC4BjvD,EAAW,CAAA,CAE9BstD,EAAL,GACIA,CACA,CADW,aACX,CAAKyB,CAAL,GAAeA,CAAf,CAA0B,gBAA1B,CAFJ,CAKA3B,GAAA,EApwxBI1wD,GAAA,CAqwxBiBnB,CArwxBjB,CAAA,CAAgC,EAyyxBpC,IAAI,CAEA,GADA+wD,CACA,CADWl+C,QAAAmhD,eAAA,CAAwBh0D,CAAxB,CACX,CAAc,CAKV,IAAIi0D,CACJ,IAAwB,QAAxB,EAAI,MAAOp7D,UAAX,GAAqCo7D,CAArC,CAA2Cp7D,SAAA,IAA3C,EAA8D,CAC1D,IAAIq7D,EAAOrhD,QAAAqhD,KAAPA,EAAwBrhD,QAAA1O,qBAAA,CAA8B,MAA9B,CAAA,CAAsC,CAAtC,CAA5B,CACIoM,EAAQsC,QAAAshD,cAAA,CAAuB,OAAvB,CACZ5jD,EAAA1Y,KAAA,CAAa,UAET0Y,EAAA6jD,WAAJ,CAEI7jD,CAAA6jD,WAAAC,QAFJ,CAE+BJ,CAF/B,CAII1jD,CAAA+jD,YAAA,CAAkBzhD,QAAA0hD,eAAA,CAAwBN,CAAxB,CAAlB,CAEJC;CAAAI,YAAA,CAAiB/jD,CAAjB,CAX0D,CAczDijD,CAAL,GAQQgB,CAMA,CANapyD,CAMb,CAD8B,KAC9B,EADIA,CAAA5O,OAAA,CAAiB,CAAjB,CAAoB,CAApB,CACJ,GADqCghE,CACrC,CADkD,OAClD,EAAAhB,CAAA,CAAW,YAAX,CAA0BgB,CAA1B,CAAwD,wBAdhE,CAkBIC,EAAAA,CAAaA,QAAQ,CAACrC,CAAD,CAAOsC,CAAP,CAAY,CAC5BA,CAAL,CA0GA5C,EAAA,CAAQ0B,CAAR,EAAoB,EAApB,CAAwB,IAAxB,CAAwCpxD,CAAxC,CAAmD,IAAnD,CAAyD,IAAzD,CAA+D,CAAA,CAA/D,CAAsEqxD,CAAtE,CA1FmBkB,QAAQ,CAACC,CAAD,CAAOC,CAAP,CAAY,CAC9BA,CAAL,EAUAn4B,EAAA,CAA6B18B,CAA7B,CAAwCwzD,CAAxC,EAAoD,EAApD,CAAwDoB,CAAxD,CAsBA,CAPAnB,CAAA,CAAe,aAAf,CAA+B1B,CAA/B,CAA0C,KAA1C,CAOA,CAAIt5D,MAAAM,cAAJ,EAA4B,eAA5B,EAA+CN,OAA/C,CAEI,CADIq8D,CACJ,CADgBJ,CAAA,cAAA,CAAqBG,CAArB,CAChB,GACI9D,CAAAgE,UA7HpB,CA6HyCD,CA7HzC,CAAK,EAAEjD,EAAP,EACgBkC,EAAA,CAAqB,CAAA,CAArB,CA2HA,EAIID,CAAA,CAAa,8BAAb,CANR,CASSjhD,QAAAmiD,eAAJ,EAA+BniD,QAAAmiD,eAAAC,eAA/B,EACGC,CAGJ,CAHoB,IAAIC,aAGxB,CAFAD,CAAA,iBAAA,CAAkCL,CAAlC,CAEA,CAAA,CADIO,CACJ,CADgBF,CAAA,oBAAA,CAAqCR,CAArC,CAA0C7hD,QAA1C,CAChB,EASQk+C,CAAAvuD,WAAJ,EACIuuD,CAAAvuD,WAAA6yD,aAAA,CAAiCD,CAAjC;AAA4CrE,CAA5C,CAjJxB,CAAK,EAAEc,EAAP,EACgBkC,EAAA,CAAqB,CAAA,CAArB,CA+II,EAkBID,CAAA,CAAa,2BAAb,CAA2C9zD,CAA3C,CA3BR,CA8BI8zD,CAAA,CAAa,4BAAb,CAlCH,EA0CDA,CAAA,CAAa,8CAAb,CAnFJ,EACIA,CAAA,CAAac,CAAb,CAF+B,CA0FvC,CA1GA,CACId,CAAA,CAAa1B,CAAb,CAF6B,CA8GX,OAA1B,EAAIL,CAAAx+D,OAAA,CAAgB,CAAhB,CAAJ,CACIu+D,EAAA,CAAQC,CAAR,CAAkB/xD,CAAlB,CAAuCoC,CAAvC,CAAkDjG,CAAlD,CAA0D2G,CAA1D,CAAkE,CAAA,CAAlE,CAAwE2wD,CAAxE,CAAwFgB,CAAxF,CADJ,CAGIpC,EAAA,CAASN,CAAT,CAAmB,IAAnB,CAAyB/xD,CAAzB,CAA8CoC,CAA9C,CAAyDjG,CAAzD,CAAiE2G,CAAjE,CAAyE,CAAA,CAAzE,CAAgF2wD,CAAhF,CAAgGgB,CAAhG,CAvJM,CAAd,IA0JIX,EAAA,CAAa,2BAAb,CAA2C9zD,CAA3C,CA5JJ,CA8JF,MAAMvO,CAAN,CAAS,CACPqiE,CAAA,CAAariE,CAAAgJ,QAAb,CADO,CAGX,MAAOgK,EA9MX,CA0WIhM,MAAA,WAAA,CA/FJ68D,QAAmB,CAACt1D,CAAD,CAAY+xD,CAAZ,CAAsByB,CAAtB,CAAgCr3D,CAAhC,CAAwC2G,CAAxC,CACnB,CACgBixD,EAAA,CAAqB,CAAA,CAArB,CACZ,OAAOR,GAAA,CAAsB,OAAtB,CAA2CvzD,CAA3C,CAAsD+xD,CAAtD,CAAgEyB,CAAhE,CAA0Er3D,CAA1E,CAAkF2G,CAAlF,CAFX,CA+FIrK,OAAA,WAAA,CAhFJ88D,QAAmB,CAACv1D,CAAD,CAAY+xD,CAAZ,CAAsByB,CAAtB,CAAgCr3D,CAAhC,CAAwC2G,CAAxC,CACnB,CACgBixD,EAAA,CAAqB,CAAA,CAArB,CACZ,OAAOR,GAAA,CAAsB,OAAtB,CAA2CvzD,CAA3C,CAAsD+xD,CAAtD,CAAgEyB,CAAhE,CAA0Er3D,CAA1E,CAAkF2G,CAAlF,CAFX,CAkFArK;MAAA,eAAA,CAlDA+8D,QAAuB,CAAC1zD,CAAD,CAAU2zD,CAAV,CAAmBz1D,CAAnB,CAA8B01D,CAA9B,CAA0C5wD,CAA1C,CAAoDnJ,CAApD,CACvB,CACI,GAAgB,QAAhB,EAAImJ,CAAJ,CAA0B,CAl/wBlBL,CAAAA,CAAW,CAAA,CAm/wBazE,EAl/wB5B,EAAa,UACb,IAAI,CAi/wBmCrE,CAj/wBvC,CACI,OAAOgJ,EAAA,CAAmB3E,CAAnB,CACP,CAAAyE,CAAA,CAAW,CAAA,CAFf,KAIK,IAAsB,QAAtB,EAAI,MA6+wB8B9I,EA7+wBlC,EAAkC,CAACgJ,EAAA,CAAmB3E,CAAnB,CAAnC,CAAkE,CACnEyE,CAAA,CAAW,CAAA,CACXE,EAAAA,CAAAA,EA9DJ,KA8DuB3E,IAAAA,EAAAA,CAAAA,CAhEnB5L,EA2ixBmCuH,CA3ixB7BjG,OAgEasK,CA/DnB0E,EAAY,EA+DO1E,CA/DH4E,EAAU,EA+DP5E,CA/DW21D,EAAS,EA+DpB31D,CA/DwB0iC,EAAU,IA+DlC1iC,CA9DdnO,EAAI,CAAb,CAAgBA,CAAhB,CAAoBuC,CAApB,CAAyBvC,CAAA,EAAzB,CAA8B,CAC1B,IAAIyB,EAwixB+BqI,CAxixB1B,CAAQ9J,CAAR,CACT,IAAU,GAAV,EAAIyB,CAAJ,EAAuB,GAAvB,EAAiBA,CAAjB,CACQovC,CAAJ,EAAepvC,CAAf,EAAqBovC,CAArB,CACIizB,CADJ,EACcriE,CADd,EAIKovC,CAAL,CAGIA,CAHJ,CAGc,IAHd,CACIA,CADJ,CACcpvC,CAId,CAAIqiE,CAAJ,GACI/wD,CAAA9J,KAAA,CAAa66D,CAAb,CACA,CAAAA,CAAA,CAAS,EAFb,CATA,CADJ,KAAA,CAgBA,GAAI,CAACjzB,CAAL,CAAc,CACV,GAAU,IAAV,EAAIpvC,CAAJ,EAAwB,IAAxB,EAAkBA,CAAlB,CACIA,CAAA,CAAK,GAET,IAAU,GAAV,EAAIA,CAAJ,EAAuB,IAAvB,EAAiBA,CAAjB,EAAqC,GAArC,EAA+BA,CAA/B,CAA0C,CAClCqiE,CAAJ,GACI/wD,CAAA9J,KAAA,CAAa66D,CAAb,CACA,CAAAA,CAAA,CAAS,EAFb,CAIU,IAAV,EAAIriE,CAAJ,EAAiBsR,CAAAlP,OAAjB,GACIgP,CAAA5J,KAAA,CAAe8J,CAAf,CACA,CAAAA,CAAA,CAAU,EAFd,CAIA,SATsC,CAJhC,CAgBd+wD,CAAA,EAAUriE,CAhCV,CAF0B,CAoC1BqiE,CAAJ,EACI/wD,CAAA9J,KAAA,CAAa66D,CAAb,CAEA/wD,EAAAlP,OAAJ,EACIgP,CAAA5J,KAAA,CAAe8J,CAAf,CAsBAD,EAAA,CAAmB3E,CAAnB,CAAA,CApBG0E,CAqBEQ,GAAA,CAA0BlF,CAA1B,CAAL,GACIyE,CADJ,CACe,CAAA,CADf,CAHmE,CA6+wBvE,MAt+wBOA,EAs+wBP,EACQgxD,CACG,GADM3zD,CAAA8zD,SACN,CADyB,CAAA,CACzB;AAAA,CAAA,CAFX,EAIO,CAAA,CALe,CAO1B,GAAIF,CAAJ,GACQ10D,CADR,CACoBqE,EAAA,CAA6BqwD,CAA7B,CAAyC11D,CAAzC,CAAqD,UAArD,CADpB,IAGYuF,CAHZ,CAGsBvE,CAAA,QAHtB,IAKgBmE,CALhB,CAK4BI,CAAA,CAAQT,CAAR,CAL5B,EAOgB,MAAIK,EAAAK,KAAA,CAAexE,CAAf,CAA0BrF,CAA1B,CAAJ,EACQ85D,CACG,GADM3zD,CAAA8zD,SACN,CADyB,CAAA,CACzB,EAAA,CAAA,CAFX,EAIO,CAAA,CAKvBlvD,QAAAlS,IAAA,CAAY,iCAAZ,CAAgDwL,CAAhD,CAA4D,KAA5D,CAAoE01D,CAApE,CAAiF,KAAjF,CAAyF5wD,CAAzF,CAAoG,KAApG,CAA4GnJ,CAA5G,CAAqH,IAArH,CACA,OAAO,CAAA,CAzBX,CAmDAlD,OAAA,aAAA,CAAyBs7D,EACzBt7D,OAAA,UAAA,CAAyBoG;","sources":["versions/pdpjs/1.61.0/pdp10-uncompiled.js"," [synthetic:util/defineproperty] "," [synthetic:util/global] "," [synthetic:es6/symbol] "," [synthetic:util/objectcreate] "," [synthetic:es6/util/setprototypeof] "," [synthetic:es6/util/inherits] "," [synthetic:util/polyfill] "," [synthetic:es6/math/trunc] "," [synthetic:es6/number/parseint] "," [synthetic:es6/math/log2] "," [synthetic:es6/util/makeiterator] "],"names":["$jscomp.defineProperty","$jscomp.global","$jscomp.initSymbol","$jscomp.Symbol","$jscomp.SYMBOL_PREFIX","$jscomp.arrayIterator","$jscomp.initSymbolIterator","$jscomp.iteratorPrototype","$jscomp.objectCreate","$jscomp.setPrototypeOf","$jscomp.polyfill","ASCII","BREAK","CTRL_A","CTRL_B","CTRL_C","CTRL_D","CTRL_E","CTRL_F","CTRL_G","CTRL_H","CTRL_I","CTRL_J","CTRL_K","CTRL_L","CTRL_M","CTRL_N","CTRL_O","CTRL_P","CTRL_Q","CTRL_R","CTRL_S","CTRL_T","CTRL_U","CTRL_V","CTRL_W","CTRL_X","CTRL_Y","CTRL_Z","ESC","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","DEL","parseInt","base","chPrefix","fCommas","indexOf","replace","ch","charAt","substr","chSuffix","slice","shift","match","isNaN","Math","pow","trunc","value","toBase","radix","cch","sPrefix","nGrouping","ceil","log","String","fromCharCode","toOct","fPrefix","abs","Str.toBase","toDec","toHex","getBaseName","sFileName","sBaseName","lastIndexOf","getExtension","sExtension","toLowerCase","endsWith","sSuffix","length","escapeHTML","sHTML","Str.HTMLEscapeMap","pad","sPadding","trim","prototype","binarySearch","fnCompare","left","right","found","undefined","middle","compareResult","formatDate","date","sDate","Date","iHour","getHours","iDay","getDate","iMonth","getMonth","sFormat","Usr.asDays","getDay","Usr.asMonths","getMinutes","getSeconds","getFullYear","getResource","sURL","type","fAsync","done","callback","request","readyState","resource","fArrayBuffer","response","responseText","err","status","window","location","protocol","nErrorCode","resources","XMLHttpRequest","ActiveXObject","fXHR2","responseType","onreadystatechange","sPost","hasOwnProperty","encodeURIComponent","open","setRequestHeader","send","overrideMimeType","parseMemoryResource","sData","aBytes","aSymbols","addrLoad","addrExec","ib","Error","data","JSON","parse","eval","Array","aData","Component.alertUser","message","ab","asHexData","sHexData","split","push","getHost","host","SITEHOST","hasLocalStorage","Web.fLocalStorage","localStorage","setItem","Web.sLocalStorageTest","getItem","removeItem","getLocalStorageItem","sKey","sValue","setLocalStorageItem","isUserAgent","userAgent","navigator","getURLParm","sParm","Web.parmsURL","sParms","aParms","search","pl","exec","decodeURIComponent","onCountRepeat","fnRepeat","fnComplete","fnTimeout","doCountRepeat","setTimeout","onClickRepeat","fn","doClickRepeat","msRepeat","ms","timer","fIgnoreMouseEvents","onmousedown","e.onmousedown","msDelay","ontouchstart","e.ontouchstart","onmouseup","onmouseout","e.onmouseout","clearTimeout","ontouchend","ontouchcancel","e.ontouchcancel","onPageEvent","sFunc","fnPrev","onInit","Web.aPageEventHandlers","doPageEvent","afn","Web.fPageEventsEnabled","enablePageEvents","fEnable","Web.fPageLoaded","Web.sendPageEvent","Web.fPageShowed","sendPageEvent","sEvent","Web.doPageEvent","Web.onPageEvent","onPageLoad","onPageShow","Web.isUserAgent","onPageUnload","constructor","Component","parms","bitsMessage","id","name","comment","bindings","idComponent","idMachine","flags","ready","busy","busyCancel","initDone","powered","unloading","error","fnReady","clearError","dbg","cpu","bus","cmp","Component.components.push","component","addMachineResource","sName","Component.machines","getTime","now","alertUser","sMessage","alert","confirmUser","sPrompt","fResponse","confirm","appendControl","control","sText","scrollTop","scrollHeight","bindComponentControls","element","sAppClass","PDP10.APPCLASS","aeControls","Component.getElementsByClass","parentNode","iControl","aeChildNodes","childNodes","iNode","nodeType","sClass","getAttribute","aClasses","iClass","Component.getComponentParms","setBinding","getComponents","idRelated","aComponents","Component.components.length","Component.components","getComponentByID","getComponentByType","sType","componentPrev","getComponentParms","getElementsByClass","sObjClass","getElementsByClassName","ae","aeAll","getElementsByTagName","re","RegExp","test","className","processCommands","fSuccess","aCommands","Component.commands","aTokens","splice","sCommand","fnCallReady","Component.asyncCommands.indexOf","processNextCommand","Component.processCommands","fnCommand","Component.globalCommands","Component.getComponentByType","Component.componentCommands","exports","call","Component.prototype","?.prototype","toString","sHTMLType","sBinding","onclick","clearControl","notice","this.notice","println","print","printControl","Component.appendControl","printlnControl","Component.PRINT.PROGRESS","fPrintOnly","computer","console","setError","isError","isReady","setReady","isBusy","fCancel","setBusy","fBusy","powerUp","powerDown","fSave","fShutdown","messageEnabled","bitsEnabled","printMessage","fAddress","PROGRESS","Component.asyncCommands","scriptAlert","scriptSleep","fnCallback","sDelay","scriptSelect","aBindings","options","textContent","selectedIndex","Array.prototype.indexOf","obj","start","isArray","Array.isArray","arg","Object","Function","bind","Function.prototype.bind","fnBound","fToBind","apply","fnNOP","args","concat","arguments","TypeError","APPCLASS","APPNAME","ADDR_MASK","ADDR_LIMIT","HINT_MASK","HINT_LIMIT","HALF_MASK","HALF_SHIFT","INT_MASK","INT_LIMIT","WORD_MASK","WORD_LIMIT","TWO_POW32","TWO_POW34","TWO_POW36","OP_SCALE","OPCODE","IO_SCALE","A_SCALE","P_SCALE","PDP10.APPNAME","MessagesPDP10.CATEGORIES","CPU","TRAP","FAULT","INT","BUS","MEMORY","MMU","ROM","DEVICE","PANEL","KEYBOARD","KEYS","PAPER","READ","WRITE","SERIAL","TIMER","SPEAKER","COMPUTER","LOG","WARN","BUFFER","HALT","PanelPDP10","parmsPanel","fBindings","nDisplayCount","cLiveRegs","regAddr","regData","regSwitches","regDisplay","ledAddr","ledData","fDeposit","fExamine","fLEDTest","nAddrSel","PanelPDP10.ADDRSEL.CONS_PHY","leds","switches","processStart","processStep","processEnable","processContinue","processDeposit","processExamine","processLoadAddr","processLEDTest","processSRSwitch","holdSwitch","toggleSwitch","resetSwitches","setSwitch","$jscomp.inherits","PanelPDP10.prototype","reset","fPowerUp","stop","updateData","setDR","parent","parentElement","panel","onPressSwitch","pressSwitch","onReleaseSwitch","releaseSwitch","event","preventDefault","initBus","displayLEDs","displaySwitches","fRepower","PanelPDP10.init","restore","save","state","State","set","getAR","getDR","getSR","updateAddr","setAR","setSRSwitches","setSR","sw","displayLED","style","backgroundColor","override","displaySwitch","marginTop","Str.parseInt","PanelPDP10.SWITCH.STEP","PanelPDP10.SWITCH.DEP","PanelPDP10.SWITCH.EXAM","running","setPC","getSwitch","PanelPDP10.SWITCH.ENABLE","startCPU","stopCPU","stepCPU","nCyclesStep","updateTimers","addCycles","updateChecksum","exception","stack","updateDisplays","advanceAddr","setWordDirect","writeWord","getWordDirect","readWord","index","inc","mask","nBusMask","nLEDs","updateLEDArray","PDP10.WORD_LIMIT","regPC","init","aePanels","document","iPanel","ePanel","Component.getComponentByID","Component.bindComponentControls","CONS_PHY","DEP","ENABLE","EXAM","STEP","Web.onInit","BusPDP10","parmsBus","nBusWidth","addrTotal","nBlockShift","log2","nBlockSize","nBlockTotal","nDisableFaults","aBusBlocks","block","MemoryPDP10","initMemory","copyBreakpoints","iBlock","BusPDP10.prototype","saveMemory","adw","nBlockLen","iDst","aDst","iComp","aComp","restoreMemory","addMemory","addr","size","addrNext","sizeLeft","addrBlock","sizeBlock","used","sizeAvail","reportError","BusPDP10.ERROR.RANGE_INUSE","blockNew","MemoryPDP10.TYPE_NAMES","Str.toOct","BusPDP10.ERROR.RANGE_INVALID","getBlockDirect","readWordDirect","nBlockLimit","writeWordDirect","removeMemBreak","fWrite","removeBreakpoint","cWriteBreakpoints","resetWriteAccess","fReadOnly","writeNone","cReadBreakpoints","resetReadAccess","fDirty","fDirtyEver","iSrc","aSrc","iCompare","fault","toStrBase","errNum","Str.toHex","RANGE_INUSE","RANGE_INVALID","DevicePDP10","parmsDevice","DevicePDP10.prototype","aeDevice","iDevice","eDevice","device","MemoryPDP10.idBlock","MemoryPDP10.TYPE.NONE","MemoryPDP10.TYPE.ROM","readNone","aw","setAccess","MemoryPDP10.afnMemory","MemoryPDP10.prototype","MemoryPDP10.afnNone","setReadAccess","fDirect","setWriteAccess","addBreakpoint","off","MemoryPDP10.afnChecked","mem","WORD_INVALID","readWordMemory","writeWordMemory","readWordChecked","checkBreakpoint","nb","aBreakRead","writeWordChecked","aBreakWrite","NONE","CPUPDP10","parmsCPU","nCyclesDefault","nCycles","nMultiplier","nCyclesPerSecond","nCyclesMultiplier","mhzDefault","round","mhzTarget","msPerYield","nCyclesPerYield","nCyclesNextYield","nCyclesRecalc","starting","autoStart","checksum","nChecksum","nCyclesChecksumNext","nCyclesChecksumStart","nCyclesChecksumInterval","nCyclesChecksumStop","aTimers","onRunTimeout","runCPU","nTotalCycles","nRunCycles","nBurstCycles","nStepCycles","msStartRun","msStartThisRun","msEndThisRun","nCyclesThisRun","nYieldsSinceStatusUpdate","mhz","CPUPDP10.prototype","CPUPDP10.BUTTONS.length","CPUPDP10.BUTTONS","sAutoStart","getMachineParm","resetCycles","resetChecksum","fInit","updateStatus","fAutoStart","setFocus","sInitCommands","sCmds","doCommands","getChecksum","fDisplay","getCycles","displayChecksum","control.onclick","iComponent","Component.getComponents","setSpeed","getSpeedTarget","toFixed","fEndStep","calcCycles","fRecalc","vMultiplier","CPUPDP10.YIELDS_PER_SECOND","floor","fUpdateFocus","sSpeed","controlSpeed","Component.getTime","getBurstCycles","saveTimers","aTimerCycles","endBurst","fReset","calcStartTime","msDelta","CPUPDP10.YIELDS_PER_STATUS","nUpdate","calcRemainingTime","msYield","msRemainsThisRun","msElapsed","controlRun","CPUPDP10_prototype$stepCPU","fComplete","fStopped","complete","CPUStatePDP10","model","MODEL_KA10","addrReset","opDecode","PDP10.opKA10.bind","opUndefined","PDP10.opUndefined.bind","irqNext","aIRQs","CPUStatePDP10.prototype","initCPU","regLA","regOP","regEA","regRA","lastPC","regBP","regXC","regEX","regPS","regRes","regPow","regDiv","regRem","addrLast","opFlags","readWordFromPhysical","writeWordToPhysical","getSpeed","saveIRQs","aIRQVectors","irq","restoreIRQs","vector","next","restoreTimers","setPS","PSFLAG","advancePC","pc","PDP10.ADDR_LIMIT","getXC","nMinCycles","nDebugCheck","checksEnabled","nDebugState","OPFLAG","checkInstruction","fInterrupt","getOpcode","PDP10.ADDR_MASK","PDP10.OPCODE.A_SCALE","op","aeCPUs","iCPU","eCPU","PDP10.opKA10","PDP10.aOpXXX_KA10","PDP10.opUUO","PDP10.opIBP","PDP10.OPCODE.P_SCALE","PDP10.opLDB","ac","PDP10.opDPB","PDP10.opMOVE","PDP10.opMOVEI","PDP10.opMOVEM","PDP10.opSETZ","PDP10.opSETCA","PDP10.WORD_MASK","PDP10.opSETO","PDP10.opHLL","src","dst","PDP10.GETHR","PDP10.HALF_MASK","PDP10.opHLLI","PDP10.opHLLM","PDP10.opHLLS","PDP10.INT_MASK","PDP10.opHRL","PDP10.HALF_SHIFT","PDP10.opHRLI","PDP10.opHRLM","PDP10.opHRLS","PDP10.opHRR","PDP10.GETHL","PDP10.opHRRI","PDP10.opHRRM","PDP10.opHRRS","PDP10.HINT_MASK","PDP10.opHLR","PDP10.opHLRI","PDP10.opHLRM","PDP10.opHLRS","PDP10.opIO","PDP10.aOpIO_KA10","PDP10.opNOP","PDP10.opNOPM","PDP10.opUndefined","PDP10.doABS","PDP10.INT_LIMIT","PDP10.TWO_POW36","PDP10.doADD","res","PDP10.setAddFlags.call","PDP10.doDIV","ext","fNegQ","fNegR","extAbs","srcAbs","sign","dDst","lo","hi","PDP10.CMPD","PDP10.ADDD","dSrc","PDP10.ZEROD","PDP10.SHRD","PDP10.doMUL","fTruncate","fExternal","n1","n2","fNeg","n1d1","n1d2","n2d1","n2d2","m1d1","m1d2","PDP10.doNEG","PDP10.doSUB","PDP10.setAddFlags","dst01","PDP10.TWO_POW34","src01","res01","bitsCarry","PDP10.AND","PDP10.TWO_POW32","PDP10.CLR","PDP10.CMP","PDP10.EQV","PDP10.IOR","PDP10.SIGN","PDP10.XOR","PDP10.SWAP","result","PDP10.opUFA","PDP10.opDFN","PDP10.opFSC","PDP10.opILDB","PDP10.opIBP.call","PDP10.opLDB.call","PDP10.opIDPB","PDP10.opDPB.call","PDP10.opFAD","PDP10.opFADI","PDP10.opFADM","PDP10.opFADB","PDP10.opFADR","PDP10.opFADRI","PDP10.opFADRM","PDP10.opFADRB","PDP10.opFSB","PDP10.opFSBI","PDP10.opFSBM","PDP10.opFSBB","PDP10.opFSBR","PDP10.opFSBRI","PDP10.opFSBRM","PDP10.opFSBRB","PDP10.opFMP","PDP10.opFMPI","PDP10.opFMPM","PDP10.opFMPB","PDP10.opFMPR","PDP10.opFMPRI","PDP10.opFMPRM","PDP10.opFMPRB","PDP10.opFDV","PDP10.opFDVI","PDP10.opFDVM","PDP10.opFDVB","PDP10.opFDVR","PDP10.opFDVRI","PDP10.opFDVRM","PDP10.opFDVRB","PDP10.opMOVES","PDP10.opMOVS","PDP10.opMOVSI","PDP10.opMOVSM","PDP10.opMOVSS","PDP10.opMOVN","PDP10.doNEG.call","PDP10.opMOVNI","PDP10.opMOVNM","PDP10.opMOVNS","PDP10.opMOVM","PDP10.doABS.call","PDP10.opMOVMI","PDP10.opMOVMM","PDP10.opMOVMS","PDP10.opIMUL","PDP10.doMUL.call","PDP10.opIMULI","PDP10.opIMULM","PDP10.opIMULB","PDP10.opMUL","PDP10.opMULI","PDP10.opMULM","PDP10.opMULB","PDP10.opIDIV","PDP10.doDIV.call","PDP10.opIDIVI","PDP10.opIDIVM","PDP10.opIDIVB","PDP10.opDIV","PDP10.opDIVI","PDP10.opDIVM","PDP10.opDIVB","PDP10.opASH","PDP10.HINT_LIMIT","bits","PDP10.opROT","PDP10.opLSH","PDP10.opJFFO","PDP10.opASHC","wLeft","wRight","wLeftOrig","PDP10.opROTC","PDP10.opLSHC","PDP10.opEXCH","tmp","PDP10.opBLT","fUpdate","fDone","addrDst","addrSrc","isRunning","PDP10.opAOBJP","PDP10.opAOBJN","PDP10.opJRST","setUserMode","PDP10.opJFCL","bitsPS","PDP10.opXCT","PDP10.opPUSHJ","getPS","getPC","PDP10.opPUSH","PDP10.opPOP","PDP10.opPOPJ","PDP10.opJSR","PDP10.opJSP","PDP10.opJSA","PDP10.opJRA","acc","PDP10.opADD","PDP10.doADD.call","PDP10.opADDI","PDP10.opADDM","PDP10.opADDB","PDP10.opSUB","PDP10.doSUB.call","PDP10.opSUBI","PDP10.opSUBM","PDP10.opSUBB","PDP10.opCAIL","PDP10.opCAIE","PDP10.opCAILE","PDP10.opCAIA","PDP10.opCAIGE","PDP10.opCAIN","PDP10.opCAIG","PDP10.opCAML","PDP10.opCAME","PDP10.opCAMLE","PDP10.opCAMA","PDP10.opCAMGE","PDP10.opCAMN","PDP10.opCAMG","PDP10.opJUMPL","PDP10.opJUMPE","PDP10.opJUMPLE","PDP10.opJUMPA","PDP10.opJUMPGE","PDP10.opJUMPN","PDP10.opJUMPG","PDP10.opSKIP","PDP10.opSKIPL","PDP10.opSKIPE","PDP10.opSKIPLE","PDP10.opSKIPA","PDP10.opSKIPGE","PDP10.opSKIPN","PDP10.opSKIPG","PDP10.opAOJ","PDP10.opAOJL","PDP10.opAOJE","PDP10.opAOJLE","PDP10.opAOJA","PDP10.opAOJGE","PDP10.opAOJN","PDP10.opAOJG","PDP10.opAOS","PDP10.opAOSL","PDP10.opAOSE","PDP10.opAOSLE","PDP10.opAOSA","PDP10.opAOSGE","PDP10.opAOSN","PDP10.opAOSG","PDP10.opSOJ","PDP10.opSOJL","PDP10.opSOJE","PDP10.opSOJLE","PDP10.opSOJA","PDP10.opSOJGE","PDP10.opSOJN","PDP10.opSOJG","PDP10.opSOS","PDP10.opSOSL","PDP10.opSOSE","PDP10.opSOSLE","PDP10.opSOSA","PDP10.opSOSGE","PDP10.opSOSN","PDP10.opSOSG","PDP10.opSETZM","PDP10.opSETZB","PDP10.opAND","PDP10.opANDI","PDP10.opANDM","PDP10.opANDB","PDP10.opANDCA","PDP10.opANDCAI","PDP10.opANDCAM","PDP10.opANDCAB","PDP10.opANDCM","PDP10.opANDCMI","PDP10.opANDCMM","PDP10.opANDCMB","PDP10.opXOR","PDP10.opXORI","PDP10.opXORM","PDP10.opXORB","PDP10.opIOR","PDP10.opIORI","PDP10.opIORM","PDP10.opIORB","PDP10.opANDCB","PDP10.opANDCBI","PDP10.opANDCBM","PDP10.opANDCBB","PDP10.opEQV","PDP10.opEQVI","PDP10.opEQVM","PDP10.opEQVB","PDP10.opSETCAM","PDP10.opSETCAB","PDP10.opORCA","PDP10.opORCAI","PDP10.opORCAM","PDP10.opORCAB","PDP10.opSETCM","PDP10.opSETCMI","PDP10.opSETCMM","PDP10.opSETCMB","PDP10.opORCM","PDP10.opORCMI","PDP10.opORCMM","PDP10.opORCMB","PDP10.opORCB","PDP10.opORCBI","PDP10.opORCBM","PDP10.opORCBB","PDP10.opSETOM","PDP10.opSETOB","PDP10.opTRNE","PDP10.opTLNE","PDP10.opTRNA","PDP10.opTLNA","PDP10.opTRNN","PDP10.opTLNN","PDP10.opTDNE","PDP10.opTSNE","PDP10.opTDNA","PDP10.opTSNA","PDP10.opTDNN","PDP10.opTSNN","PDP10.opTRZ","PDP10.opTLZ","PDP10.opTRZE","PDP10.opTLZE","PDP10.opTRZA","PDP10.opTLZA","PDP10.opTRZN","PDP10.opTLZN","PDP10.opTDZ","PDP10.opTSZ","PDP10.opTDZE","PDP10.opTSZE","PDP10.opTDZA","PDP10.opTSZA","PDP10.opTDZN","PDP10.opTSZN","PDP10.opTRC","PDP10.opTLC","PDP10.opTRCE","PDP10.opTLCE","PDP10.opTRCA","PDP10.opTLCA","PDP10.opTRCN","PDP10.opTLCN","PDP10.opTDC","PDP10.opTSC","PDP10.opTDCE","PDP10.opTSCE","PDP10.opTDCA","PDP10.opTSCA","PDP10.opTDCN","PDP10.opTSCN","PDP10.opTRO","PDP10.opTLO","PDP10.opTROE","PDP10.opTLOE","PDP10.opTROA","PDP10.opTLOA","PDP10.opTRON","PDP10.opTLON","PDP10.opTDO","PDP10.opTSO","PDP10.opTDOE","PDP10.opTSOE","PDP10.opTDOA","PDP10.opTSOA","PDP10.opTDON","PDP10.opTSON","PDP10.opBLKI","PDP10.opDATAI","PDP10.opBLKO","PDP10.opDATAO","PDP10.opCONO","dev","DEVICES","WFLAG","writeFlags","PDP10.opCONI","readFlags","RFLAG","PDP10.opCONSZ","PDP10.opCONSO","ROMPDP10","parmsROM","abInit","addrROM","sizeROM","addrAlias","sFilePath","Str.getBaseName","sFileURL","sFileExt","Str.getExtension","FORMAT","Web.getHost","rom","Web.getResource","doneLoad","sResponse","Component.addMachineResource","Web.parseMemoryResource","initROM","addSymbols","addROM","aliases","cloneROM","aBlocks","aeROM","iROM","eROM","RAMPDP10","parmsRAM","addrRAM","sizeRAM","fAllocated","ram","initRAM","RAM","loadImage","zero","pattern","len","addrInit","fStart","fLoaded","aeRAM","iRAM","eRAM","SerialPortPDP10","parmsSerial","fUpperCase","fNullModem","abReceive","target","connection","sendData","initConnection","receiveData","receiveStatus","setConnection","SerialPortPDP10.prototype","serial","onkeydown","control.onkeydown","bASCII","keyCode","KEYCODE","altKey","Keys.ASCII.CTRL_H","Keys.ASCII.DEL","ctrlKey","Keys.ASCII.A","Keys.ASCII.Z","Keys.ASCII.CTRL_A","onkeypress","control.onkeypress","metaKey","which","Keys.ASCII.CTRL_M","Keys.ASCII.CTRL_J","onpaste","control.onpaste","stopPropagation","clipboardData","getData","removeAttribute","sConnection","asParts","sSourceID","Str.trim","sTargetID","fnConnect","bASCIIPrev","charCodeAt","LF","CR","aeSerial","iSerial","eSerial","Debugger","parmsDbg","nBase","nBits","achGroup","achAddress","fAssemble","iPrevCmd","aPrevCmds","aVariables","getRegIndex","getRegValue","parseCommand","sCmd","chSep","iPrev","chQuote","substring","evalAND","truncate","Debugger.TWO_POW32","evalXOR","evalMUL","fUnsigned","vNew","limit","evalOps","aVals","aOps","cOps","chOp","pop","val2","val1","valNew","evalIOR","parseArray","asValues","iValue","iLimit","aUndefined","fError","nUnary","nBasePrev","sOp","parseValue","cOpen","iStart","parseUnary","aBinOp","Debugger.aDECOpPrecedence","Debugger.aBinOpPrecedence","parseASCII","sExp","chDelim","cchMax","parseExpression","fQuiet","fPrint","join","regExp","printValue","bit","iReg","getVariable","sVar","sUndefined","getVariableFixup","valueUndefined","fDefined","resetVariables","printVariable","cVariables","aVars","keys","sort","Str.toDec","DebuggerPDP10","dbgAddrAcc","newAddr","dbgAddrCode","dbgAddrData","dbgAddrAssemble","aSymbolTable","aBreakExec","clearBreakpoints","iInstructionHistory","nBreakInstructions","aInstructionHistory","nextHistory","historyInit","afnDumpers","sMessagePrev","aMessageBuffer","messageInit","nStep","sCmdDumpPrev","sCmdTracePrev","nCyclesStart","msStart","cInstructions","nSuppressBreaks","macro10","controlDebug","global","getAddr","dbgAddr","ADDR_INVALID","fPhysical","fTemporary","setAddr","packAddr","unpackAddr","aAddr","aCmds","DebuggerPDP10.prototype","sMessages","sCommands","messageDump","onDumpBus","asArgs","sAddr","parseAddr","typePrev","cPrev","setSelectionRange","Web.onClickRepeat","onClickDebugEnter","onClickStep","fRepeat","fCompleted","scrollX","scrollY","focus","scrollTo","DebuggerPDP10_prototype$getWord","getWord","DebuggerPDP10_prototype$setWord","setWord","chOpen","parseReference","chClose","chEscape","chInnerEscape","reSubExp","sReplace","dbgAddrTmp","sSymbol","sUpperCase","iTable","toUpperCase","findSymbolAddr","symbol","symbolTable","offSymbol","validateWord","parseAddrOptions","sOptions","toStrWord","sEnable","aEnable","fnDumper","sReg","DebuggerPDP10.REGNAMES.indexOf","DebuggerPDP10.REGS.PC","DebuggerPDP10.REGS.RA","DebuggerPDP10.REGS.EA","DebuggerPDP10.REGS.PS","DebuggerPDP10.REGS.OV","DebuggerPDP10.REGS.C0","DebuggerPDP10.REGS.C1","DebuggerPDP10.REGS.BI","DebuggerPDP10.REGS.ND","DebuggerPDP10.REGS.PD","toStrAddr","fRunning","DebuggerPDP10.HISTORY_LIMIT","checkCPU","fRegs","fUpdateDisplays","DebuggerPDP10.PROMPT","doRegisters","doUnassemble","clearTempBreakpoint","sStopped","msTotal","nState","opCode","getInstruction","sComment","nSequence","dbgAddrOp","opNum","iMode","PDP10.OPCODE.OP_SCALE","DebuggerPDP10.OPTABLE","opMasks","opMask","aModes","DebuggerPDP10.OPMODES","DebuggerPDP10.OPCOMPS","DebuggerPDP10.OPTESTS","sMode","DebuggerPDP10.OPS.MOVM","sOperation","DebuggerPDP10.OPNAMES","PDP10.OPCODE.IO_SCALE","sOperand","findInstruction","DebuggerPDP10.ALTOPS.length","DebuggerPDP10.ALTOPS","opAlt","Str.pad","sOpcodes","sLine","parseInstruction","sOpcode","sOperands","sMnemonic","opMode","aOperands","operand","toStrOffset","aBreak","findBreakpoint","printBreakpoint","fFound","dbgAddrBreak","listBreakpoints","sAction","fBreak","addrBreak","doCommand","getRegDump","fMisc","sDump","getAccOutput","DebuggerPDP10.REGNAMES.length","DebuggerPDP10.REGNAMES","getMiscDump","comparePairs","p1","p2","sModule","aOffsets","sAnnotation","Usr.binarySearch","findSymbol","fNearest","aSymbol","addrSymbol","returnSymbol","aWords","addrStart","nWords","addrLo","addrHi","forEach","sStart","iOffset","offset","doAssemble","sFile","Macro10","assembleFiles","doneMacro10","doVar","delVariable","setVariable","doList","nDelta","sDelta","fInstruction","flag","setRegValue","doPrint","doTrace","sCount","nCount","Web.onCountRepeat","onCountStep","onCountStepComplete","sAddrEnd","nLines","nBytes","dbgAddrEnd","nPrinted","sLabel","dbgCopy","sDelim","iLast","s0","ch0","unshift","doBreak","cBreaks","doClear","controlPrint","sLen","sBytes","sDumpers","doDump","sState","powerOff","sSymbolOrig","sMore","cHistory","iHistory","aHistory","nPrev","sPrev","sLines","aFilters","dbgAddrNew","sInstruction","cOverrides","fJSON","nWordsPerLine","sChars","fnGet","doEdit","fnSet","doRun","doHalt","doIf","doStackTrace","cFrames","dbgAddrCall","dbgAddrStack","nFrames","sCall","cTests","addrOrig","sCallPrev","fCriteria","sCategory","doMessages","sCategories","fEnabled","bitMessage","nRegs","sOption","doStep","doOptions","DebuggerPDP10.COMMANDS","doHelp","MOVM","PC","RA","EA","PS","OV","C0","C1","BI","ND","PD","UUO","UFA","DFN","FSC","IBP","ILDB","LDB","IDPB","DPB","ASH","ROT","LSH","JFFO","ASHC","ROTC","LSHC","EXCH","BLT","AOBJP","AOBJN","JRST","JFCL","XCT","PUSHJ","PUSH","POP","POPJ","JSR","JSP","JSA","JRA","FAD","FADR","FSB","FSBR","FMP","FMPR","FDV","FDVR","MOVE","MOVS","MOVN","IMUL","MUL","IDIV","DIV","ADD","SUB","SETZ","AND","ANDCA","SETM","ANDCM","SETA","XOR","IOR","ANDCB","EQV","SETCA","ORCA","SETCM","ORCM","ORCB","SETO","HLL","HRL","HLLZ","HRLZ","HLLO","HRLO","HLLE","HRLE","HRR","HLR","HRRZ","HLRZ","HRRO","HLRO","HRRE","HLRE","CAI","CAM","JUMP","SKIP","AOJ","AOS","SOJ","SOS","TR","TL","TD","TS","BLKI","DATAI","BLKO","DATAO","CONO","CONI","CONSZ","CONSO","DebuggerPDP10.JFCL","JOV","JCRY0","JCRY1","JCRY","JFOV","DebuggerPDP10.JRST","JRSTF","JEN","aeDbg","iDbg","eDbg","iURL","aURLs","anLines","asLines","tblMacros","tblSymbols","aLiterals","aFixups","aLineRefs","nLine","nError","nLiteral","nLocation","nLocationScope","stackScopes","sOperator","nMacroDef","sMacroDef","chMacroOpen","chMacroClose","reLine","macroCall","chASCII","sASCII","assembleString","parseResources","loadNextResource","sExt","processMacro10","sResource","Str.endsWith","warning","addSymbol","getLineRef","parseLine","doLiterals","doVariables","processFixup","aValues","aDefaults","defASCII","fParse","matchLine","Macro10.PSEUDO_OP.IRP","Macro10.PSEUDO_OP.IRPC","iParm","macroDef","iSearch","iMatch","iMatchEnd","chPre","chPost","appendMacro","sSeparator","sRemainder","Macro10.SYMTYPE.LABEL","matchOp","nType","PRIVATE","Macro10.SYMTYPE.INTERNAL","sLiteral","getLiteral","defMacro","Macro10.PSEUDO_OP.LITERAL","getReserved","parseMacro","Macro10.PSEUDO_OP.ASCII","Macro10.PSEUDO_OP.ASCIZ","Macro10.PSEUDO_OP.SIXBIT","Macro10.PSEUDO_OP.BLOCK","defBLOCK","Macro10.PSEUDO_OP.BYTE","nValue","nBitsRemaining","getExpression","defBYTE","genWord","Macro10.PSEUDO_OP.END","defEND","Macro10.PSEUDO_OP.EXP","defWord","Macro10.PSEUDO_OP.LIT","Macro10.PSEUDO_OP.LOC","defLocation","Macro10.PSEUDO_OP.VAR","Macro10.PSEUDO_OP.XWD","defXWD","Macro10.PSEUDO_OP.DEFINE","Macro10.PSEUDO_OP.IF1","Macro10.PSEUDO_OP.IFDEF","Macro10.PSEUDO_OP.IFDIF","Macro10.PSEUDO_OP.IFE","Macro10.PSEUDO_OP.IFG","Macro10.PSEUDO_OP.IFGE","Macro10.PSEUDO_OP.IFIDN","Macro10.PSEUDO_OP.IFL","Macro10.PSEUDO_OP.IFLE","Macro10.PSEUDO_OP.IFN","Macro10.PSEUDO_OP.IFNDEF","Macro10.PSEUDO_OP.OPDEF","Macro10.PSEUDO_OP.REPEAT","Macro10.PSEUDO_OP.PURGE","getValues","delSymbols","Macro10.PSEUDO_OP.LALL","Macro10.PSEUDO_OP.LIST","Macro10.PSEUDO_OP.NOSYM","Macro10.PSEUDO_OP.PAGE","Macro10.PSEUDO_OP.SUBTTL","Macro10.PSEUDO_OP.TITLE","Macro10.PSEUDO_OP.XALL","Macro10.PSEUDO_OP.XLIST","macro","nOperand","Macro10.MACRO_OP.OPDEF","parseText","pushScope","sFixup","popScope","macroPrev","parseLiteral","iLine","scope","fQuotes","cNesting","sEval","iBegin","iEnd","sReserved","Macro10.MACRO_OP.RESERVED","fParens","cchPrefix","nConversion","getString","sRemain","genASCII","Macro10.MACRO_OP.DEFINE","Macro10.MACRO_OP.LITERAL","sOperand2","isDefined","sym","nLocationLiterals","lit","sError","sWarning","LABEL","INTERNAL","ASCIZ","BLOCK","BYTE","DEFINE","END","EXP","IF1","IFDEF","IFDIF","IFE","IFG","IFGE","IFIDN","IFL","IFLE","IFN","IFNDEF","IRP","IRPC","LALL","LIT","LITERAL","LIST","LOC","NOSYM","OPDEF","PAGE","PURGE","REPEAT","SIXBIT","SUBTTL","TITLE","VAR","XALL","XWD","XLIST","RESERVED","ComputerPDP10","parmsComputer","parmsMachine","fSuspended","setMachineParms","fAutoPower","BOOLEAN","nPowerChange","sStateData","sResumePath","sStatePath","fServerState","fStateData","stateComputer","stateFailSafe","fInitialized","fRestoreError","url","random","sUserID","queryUserID","LICENSE","sResume","resume","fAllowResume","ComputerPDP10.RESUME_NONE","APPVERSION","load","getServerStatePath","doneStateLoad","wait","powerOn","parmsComponent","sParmLC","Web.getURLParm","defaultValue","NUMBER","ComputerPDP10.prototype","onComponentReady","validateState","stateValidate","ComputerPDP10.STATE_VALIDATE","sTimestampValidate","get","ComputerPDP10.STATE_TIMESTAMP","sTimestampComputer","clear","ComputerPDP10.RESUME_AUTO","fRestore","ComputerPDP10.RESUME_REPOWER","ComputerPDP10.STATE_FAILSAFE","powerReport","ComputerPDP10.RESUME_PROMPT","unload","Usr.formatDate","store","fValidate","Component.confirmUser","sCode","RES","CODE","FAIL","Web.setLocalStorageItem","ComputerPDP10.STATE_USERID","resetUserID","powerRestore","donePowerOn","reload","asComments","controlPower","getUserID","dataPost","sUser","TYPE","sReport","sReportURL","sTimestamp","ComputerPDP10.STATE_VERSION","ComputerPDP10.STATE_HOSTURL","href","ComputerPDP10.STATE_BROWSER","fClearAll","fClear","saveServerState","ComputerPDP10.RESUME_DELETE","nDisplayLimit","getSpeedCurrent","fWaiting","displayValue","sVal","removeChild","fPrompt","Web.getLocalStorageItem","prompt","verifyUserID","code","State.key","QUERY","REQ","storeServerState","ENDPOINT","fScroll","aeMachines","iMachine","eMachine","aeComputers","iComputer","eComputer","show","exit","sVersion","json","fParsed","key","State.prototype","Web.hasLocalStorage","stringify","fAll","cAsyncMachines","loadXML","sXMLFile","fResolve","display","doneLoadXML","sURLName","sXML","parseXML","buildXML","pathname","xmlDoc","async","parseFromString","DOMParser","resolveXML","matchRef","reRef","sRefFile","doneReadXML","sXMLRef","sRefAttrs","aXMLRefTag","sXMLNewTag","matchAttr","reAttr","embedMachine","sXSLFile","displayMessage","eWarning","aeWarning","innerHTML","Str.escapeHTML","displayError","Web.enablePageEvents","getElementById","css","head","createElement","styleSheet","cssText","appendChild","createTextNode","sAppFolder","processXML","xml","transformXML","sXSL","xsl","sFragment","outerHTML","implementation","createDocument","xsltProcessor","XSLTProcessor","eFragment","replaceChild","embedPDP10","embedPDP11","commandMachine","fSingle","sComponent","sToken","disabled"],"sourcesContent":["\"use strict\";\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/defines.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @define {string}\n */\nvar APPVERSION = \"\"; // this @define is overridden by the Closure Compiler with the version in machines.json\n\nvar XMLVERSION = null; // this is set in non-COMPILED builds by embedMachine() if a version number was found in the machine XML\n\nvar COPYRIGHT = \"Copyright © 2012-2018 Jeff Parsons <Jeff@pcjs.org>\";\n\nvar LICENSE = \"License: GPL version 3 or later <http://gnu.org/licenses/gpl.html>\";\n\nvar CSSCLASS = \"pcjs\";\n\n/**\n * @define {string}\n */\nvar SITEHOST = \"localhost:8088\";// this @define is overridden by the Closure Compiler with \"www.pcjs.org\"\n\n/**\n * @define {boolean}\n */\nvar COMPILED = false; // this @define is overridden by the Closure Compiler (to true)\n\n/**\n * @define {boolean}\n */\nvar DEBUG = true; // this @define is overridden by the Closure Compiler (to false) to remove DEBUG-only code\n\n/**\n * @define {boolean}\n */\nvar MAXDEBUG = false; // this @define is overridden by the Closure Compiler (to false) to remove MAXDEBUG-only code\n\n/**\n * @define {boolean}\n */\nvar PRIVATE = false; // this @define is overridden by the Closure Compiler (to false) to enable PRIVATE code\n\n/*\n * RS-232 DB-25 Pin Definitions, mapped to bits 1-25 in a 32-bit status value.\n *\n * SerialPorts in PCjs machines are considered DTE (Data Terminal Equipment), which means they should be \"virtually\"\n * connected to each other via a null-modem cable, which assumes the following cross-wiring:\n *\n * G 1 <-> 1 G (Ground)\n * TD 2 <-> 3 RD (Received Data)\n * RD 3 <-> 2 TD (Transmitted Data)\n * RTS 4 <-> 5 CTS (Clear To Send)\n * CTS 5 <-> 4 RTS (Request To Send)\n * DSR 6+8 <-> 20 DTR (Data Terminal Ready)\n * SG 7 <-> 7 SG (Signal Ground)\n * DTR 20 <-> 6+8 DSR (Data Set Ready + Carrier Detect)\n * RI 22 <-> 22 RI (Ring Indicator)\n *\n * TODO: Move these definitions to a more appropriate shared file at some point.\n */\nvar RS232 = {\n RTS: {\n PIN: 4,\n MASK: 0x00000010\n },\n CTS: {\n PIN: 5,\n MASK: 0x00000020\n },\n DSR: {\n PIN: 6,\n MASK: 0x00000040\n },\n CD: {\n PIN: 8,\n MASK: 0x00000100\n },\n DTR: {\n PIN: 20,\n MASK: 0x00100000\n },\n RI: {\n PIN: 22,\n MASK: 0x00400000\n }\n};\n\n/*\n * NODE should be true if we're running under NodeJS (eg, command-line), false if not (eg, web browser)\n */\nvar NODE = false;\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/dumpapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Our \"DiskDump API\", such as it was, used to look like:\n *\n * http://jsmachines.net/bin/convdisk.php?disk=/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json&format=img\n *\n * To make it (a bit) more \"REST-like\", the above request now looks like:\n *\n * http://www.pcjs.org/api/v1/dump?disk=/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json&format=img\n *\n * Similarly, our \"FileDump API\" used to look like:\n *\n * http://jsmachines.net/bin/convrom.php?rom=/devices/pc/rom/5150/1981-04-24/PCBIOS-REV1.rom&format=json\n *\n * and that request now looks like:\n *\n * http://www.pcjs.org/api/v1/dump?file=/devices/pc/rom/5150/1981-04-24/PCBIOS-REV1.rom&format=json\n *\n * I don't think it makes sense to avoid \"query\" parameters, because blending the path of a disk image with the\n * the rest of the URL would be (a) confusing, and (b) more work to parse.\n */\nvar DumpAPI = {\n ENDPOINT: \"/api/v1/dump\",\n QUERY: {\n DIR: \"dir\", // value is path of a directory (DiskDump only)\n DISK: \"disk\", // value is path of a disk image (DiskDump only)\n FILE: \"file\", // value is path of a ROM image file (FileDump only)\n IMG: \"img\", // alias for DISK\n PATH: \"path\", // value is path of a one or more files (DiskDump only)\n FORMAT: \"format\", // value is one of FORMAT values below\n COMMENTS: \"comments\", // value is either \"true\" or \"false\"\n DECIMAL: \"decimal\", // value is either \"true\" to force all numbers to decimal, \"false\" or undefined otherwise\n MBHD: \"mbhd\", // value is hard drive size in Mb (formerly \"mbsize\") (DiskDump only) (DEPRECATED)\n SIZE: \"size\" // value is target disk size in Kb (supersedes \"mbhd\") (DiskDump only)\n },\n FORMAT: {\n JSON: \"json\", // default\n JSON_GZ: \"gz\", // gzip is currently used ONLY for compressed JSON\n DATA: \"data\", // same as \"json\", but built without JSON.stringify() (DiskDump only)\n HEX: \"hex\", // deprecated\n OCTAL: \"octal\", // displays data as octal words\n BYTES: \"bytes\", // displays data as hex bytes; normally used only when comments are enabled\n WORDS: \"words\", // displays data as hex words; normally used only when comments are enabled\n LONGS: \"longs\", // displays data as dwords\n IMG: \"img\", // returns the raw disk data (ie, using a Buffer object) (DiskDump only)\n ROM: \"rom\" // returns the raw file data (ie, using a Buffer object) (FileDump only)\n }\n};\n\n/*\n * Because we use an overloaded API endpoint (ie, one that's shared with the FileDump module), we must\n * also provide a list of commands which, when combined with the endpoint, define a unique request.\n */\nDumpAPI.asDiskCommands = [DumpAPI.QUERY.DIR, DumpAPI.QUERY.DISK, DumpAPI.QUERY.PATH];\nDumpAPI.asFileCommands = [DumpAPI.QUERY.FILE];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/reportapi.js (C) Jeff Parsons 2012-2018\n */\n\nvar ReportAPI = {\n ENDPOINT: \"/api/v1/report\",\n QUERY: {\n APP: \"app\",\n VER: \"ver\",\n URL: \"url\",\n USER: \"user\",\n TYPE: \"type\",\n DATA: \"data\"\n },\n TYPE: {\n BUG: \"bug\"\n },\n RES: {\n OK: \"Thank you\"\n }\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/userapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Examples of User API requests:\n *\n * web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.VERIFY + '&' + UserAPI.QUERY.USER + '=' + sUser;\n */\nvar UserAPI = {\n ENDPOINT: \"/api/v1/user\",\n QUERY: {\n REQ: \"req\", // specifies a request\n USER: \"user\", // specifies a user ID\n STATE: \"state\", // specifies a state ID\n DATA: \"data\" // specifies state data\n },\n REQ: {\n CREATE: \"create\", // creates a user ID\n VERIFY: \"verify\", // requests verification of a user ID\n STORE: \"store\", // stores a machine state on the server\n LOAD: \"load\" // loads a machine state from the server\n },\n RES: {\n CODE: \"code\",\n DATA: \"data\"\n },\n CODE: {\n OK: \"ok\",\n FAIL: \"error\"\n },\n FAIL: {\n DUPLICATE: \"user already exists\",\n VERIFY: \"unable to verify user\",\n BADSTATE: \"invalid state parameter\",\n NOSTATE: \"no machine state\",\n BADLOAD: \"unable to load machine state\",\n BADSTORE: \"unable to save machine state\"\n }\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/keys.js (C) Jeff Parsons 2012-2018\n */\n\nvar Keys = {\n /*\n * Keys and/or key combinations that generate common ASCII codes.\n *\n * NOTE: If you're looking for a general-purpose ASCII code table, see Str.ASCII in strlib.js;\n * if something's missing, that's probably the more appropriate table to add it to.\n *\n * TODO: The Closure Compiler doesn't inline all references to these values, at least those with\n * quoted property names, which is why I've 'unquoted' as many of them as possible. One solution\n * would be to add mnemonics for all of them, not just the non-printable ones (eg, SPACE instead\n * of ' ', AMP instead of '&', etc.)\n */\n ASCII: {\n BREAK: 0, CTRL_A: 1, CTRL_B: 2, CTRL_C: 3, CTRL_D: 4, CTRL_E: 5, CTRL_F: 6, CTRL_G: 7,\n CTRL_H: 8, CTRL_I: 9, CTRL_J: 10, CTRL_K: 11, CTRL_L: 12, CTRL_M: 13, CTRL_N: 14, CTRL_O: 15,\n CTRL_P: 16, CTRL_Q: 17, CTRL_R: 18, CTRL_S: 19, CTRL_T: 20, CTRL_U: 21, CTRL_V: 22, CTRL_W: 23,\n CTRL_X: 24, CTRL_Y: 25, CTRL_Z: 26, ESC: 27,\n ' ': 32, '!': 33, '\"': 34, '#': 35, '$': 36, '%': 37, '&': 38, \"'\": 39,\n '(': 40, ')': 41, '*': 42, '+': 43, ',': 44, '-': 45, '.': 46, '/': 47,\n '0': 48, '1': 49, '2': 50, '3': 51, '4': 52, '5': 53, '6': 54, '7': 55,\n '8': 56, '9': 57, ':': 58, ';': 59, '<': 60, '=': 61, '>': 62, '?': 63,\n '@': 64, A: 65, B: 66, C: 67, D: 68, E: 69, F: 70, G: 71,\n H: 72, I: 73, J: 74, K: 75, L: 76, M: 77, N: 78, O: 79,\n P: 80, Q: 81, R: 82, S: 83, T: 84, U: 85, V: 86, W: 87,\n X: 88, Y: 89, Z: 90, '[': 91, '\\\\':92, ']': 93, '^': 94, '_': 95,\n '`': 96, a: 97, b: 98, c: 99, d: 100, e: 101, f: 102, g: 103,\n h: 104, i: 105, j: 106, k: 107, l: 108, m: 109, n: 110, o: 111,\n p: 112, q: 113, r: 114, s: 115, t: 116, u: 117, v: 118, w: 119,\n x: 120, y: 121, z: 122, '{':123, '|':124, '}':125, '~':126, DEL: 127\n },\n /*\n * Browser keyCodes we must pay particular attention to. For the most part, these are non-alphanumeric\n * or function keys, some which may require special treatment (eg, preventDefault() if returning false on\n * the initial keyDown event is insufficient).\n *\n * keyCodes for most common ASCII keys can simply use the appropriate ASCII code above.\n *\n * Most of these represent non-ASCII keys (eg, the LEFT arrow key), yet for some reason, browsers defined\n * them using ASCII codes (eg, the LEFT arrow key uses the ASCII code for '%' or 37).\n */\n KEYCODE: {\n /* 0x08 */ BS: 8, // BACKSPACE (ASCII.CTRL_H)\n /* 0x09 */ TAB: 9, // TAB (ASCII.CTRL_I)\n /* 0x0A */ LF: 10, // LINE-FEED (ASCII.CTRL_J) (Some Windows-based browsers used to generate this via CTRL-ENTER)\n /* 0x0D */ CR: 13, // CARRIAGE RETURN (ASCII.CTRL_M)\n /* 0x10 */ SHIFT: 16,\n /* 0x11 */ CTRL: 17,\n /* 0x12 */ ALT: 18,\n /* 0x13 */ PAUSE: 19, // PAUSE/BREAK\n /* 0x14 */ CAPS_LOCK: 20,\n /* 0x1B */ ESC: 27,\n /* 0x20 */ SPACE: 32,\n /* 0x21 */ PGUP: 33,\n /* 0x22 */ PGDN: 34,\n /* 0x23 */ END: 35,\n /* 0x24 */ HOME: 36,\n /* 0x25 */ LEFT: 37,\n /* 0x26 */ UP: 38,\n /* 0x27 */ RIGHT: 39,\n /* 0x27 */ FF_QUOTE: 39,\n /* 0x28 */ DOWN: 40,\n /* 0x2C */ FF_COMMA: 44,\n /* 0x2C */ PRTSC: 44,\n /* 0x2D */ INS: 45,\n /* 0x2E */ DEL: 46,\n /* 0x2E */ FF_PERIOD: 46,\n /* 0x2F */ FF_SLASH: 47,\n /* 0x30 */ ZERO: 48,\n /* 0x31 */ ONE: 49,\n /* 0x32 */ TWO: 50,\n /* 0x33 */ THREE: 51,\n /* 0x34 */ FOUR: 52,\n /* 0x35 */ FIVE: 53,\n /* 0x36 */ SIX: 54,\n /* 0x37 */ SEVEN: 55,\n /* 0x38 */ EIGHT: 56,\n /* 0x39 */ NINE: 57,\n /* 0x3B */ FF_SEMI: 59,\n /* 0x3D */ FF_EQUALS: 61,\n /* 0x5B */ CMD: 91, // aka WIN\n /* 0x5B */ FF_LBRACK: 91,\n /* 0x5C */ FF_BSLASH: 92,\n /* 0x5D */ RCMD: 93, // aka MENU\n /* 0x5D */ FF_RBRACK: 93,\n /* 0x60 */ NUM_0: 96,\n /* 0x60 */ NUM_INS: 96,\n /* 0x60 */ FF_BQUOTE: 96,\n /* 0x61 */ NUM_1: 97,\n /* 0x61 */ NUM_END: 97,\n /* 0x62 */ NUM_2: 98,\n /* 0x62 */ NUM_DOWN: 98,\n /* 0x63 */ NUM_3: 99,\n /* 0x63 */ NUM_PGDN: 99,\n /* 0x64 */ NUM_4: 100,\n /* 0x64 */ NUM_LEFT: 100,\n /* 0x65 */ NUM_5: 101,\n /* 0x65 */ NUM_CENTER: 101,\n /* 0x66 */ NUM_6: 102,\n /* 0x66 */ NUM_RIGHT: 102,\n /* 0x67 */ NUM_7: 103,\n /* 0x67 */ NUM_HOME: 103,\n /* 0x68 */ NUM_8: 104,\n /* 0x68 */ NUM_UP: 104,\n /* 0x69 */ NUM_9: 105,\n /* 0x69 */ NUM_PGUP: 105,\n /* 0x6A */ NUM_MUL: 106,\n /* 0x6B */ NUM_ADD: 107,\n /* 0x6D */ NUM_SUB: 109,\n /* 0x6E */ NUM_DEL: 110, // aka PERIOD\n /* 0x6F */ NUM_DIV: 111,\n /* 0x70 */ F1: 112,\n /* 0x71 */ F2: 113,\n /* 0x72 */ F3: 114,\n /* 0x73 */ F4: 115,\n /* 0x74 */ F5: 116,\n /* 0x75 */ F6: 117,\n /* 0x76 */ F7: 118,\n /* 0x77 */ F8: 119,\n /* 0x78 */ F9: 120,\n /* 0x79 */ F10: 121,\n /* 0x7A */ F11: 122,\n /* 0x7B */ F12: 123,\n /* 0x90 */ NUM_LOCK: 144,\n /* 0x91 */ SCROLL_LOCK: 145,\n /* 0xAD */ FF_DASH: 173,\n /* 0xBA */ SEMI: 186, // Firefox: 59 (FF_SEMI)\n /* 0xBB */ EQUALS: 187, // Firefox: 61 (FF_EQUALS)\n /* 0xBC */ COMMA: 188,\n /* 0xBD */ DASH: 189, // Firefox: 173 (FF_DASH)\n /* 0xBE */ PERIOD: 190,\n /* 0xBF */ SLASH: 191,\n /* 0xC0 */ BQUOTE: 192,\n /* 0xDB */ LBRACK: 219,\n /* 0xDC */ BSLASH: 220,\n /* 0xDD */ RBRACK: 221,\n /* 0xDE */ QUOTE: 222,\n /* 0xE0 */ FF_CMD: 224, // Firefox only (used for both CMD and RCMD)\n //\n // The following biases use what I'll call Decimal Coded Binary or DCB (the opposite of BCD),\n // where the thousands digit is used to store the sum of \"binary\" digits 1 and/or 2 and/or 4.\n //\n // Technically, that makes it DCO (Decimal Coded Octal), but then again, BCD should have really\n // been called HCD (Hexadecimal Coded Decimal), so if \"they\" can take liberties, so can I.\n //\n // ONDOWN is a bias we add to browser keyCodes that we want to handle on \"down\" rather than on \"press\".\n //\n ONDOWN: 1000,\n //\n // ONRIGHT is a bias we add to browser keyCodes that need to check for a \"right\" location (default is \"left\")\n //\n ONRIGHT: 2000,\n //\n // FAKE is a bias we add to signal these are fake keyCodes corresponding to internal keystroke combinations.\n // The actual values are for internal use only and merely need to be unique and used consistently.\n //\n FAKE: 4000\n },\n /*\n * The set of values that a browser may store in the 'location' property of a keyboard event object\n * which we also support.\n */\n LOCATION: {\n LEFT: 1,\n RIGHT: 2,\n NUMPAD: 3\n }\n};\n\n/*\n * Check the event object's 'location' property for a non-zero value for the following ONRIGHT keys.\n */\nKeys.KEYCODE.NUM_CR = Keys.KEYCODE.CR + Keys.KEYCODE.ONRIGHT;\n\n\n/*\n * Maps Firefox keyCodes to their more common keyCode counterparts; a number of entries in this table\n * are no longer valid (if indeed they ever were), so they've been commented out. It's likely that I\n * simply extended this table to resolve additional differences in other browsers (ie, Opera), but without\n * browser-specific checks, it's not safe to perform all the mappings shown below.\n */\nKeys.FF_KEYCODES = {};\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_SEMI] = Keys.KEYCODE.SEMI; // 59 -> 186\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_EQUALS] = Keys.KEYCODE.EQUALS; // 61 -> 187\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.KEYCODE.DASH; // 173 -> 189\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_CMD] = Keys.KEYCODE.CMD; // 224 -> 91\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_COMMA] = Keys.KEYCODE.COMMA; // 44 -> 188\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_PERIOD] = Keys.KEYCODE.PERIOD; // 46 -> 190\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_SLASH] = Keys.KEYCODE.SLASH; // 47 -> 191\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_BQUOTE] = Keys.KEYCODE.BQUOTE; // 96 -> 192\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_LBRACK = Keys.KEYCODE.LBRACK; // 91 -> 219\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_BSLASH] = Keys.KEYCODE.BSLASH; // 92 -> 220\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_RBRACK] = Keys.KEYCODE.RBRACK; // 93 -> 221\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_QUOTE] = Keys.KEYCODE.QUOTE; // 39 -> 222\n\n/*\n * Maps non-ASCII keyCodes to their ASCII counterparts\n */\nKeys.NONASCII_KEYCODES = {};\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.ASCII['-']; // 173 -> 45\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.SEMI] = Keys.ASCII[';']; // 186 -> 59\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.EQUALS] = Keys.ASCII['=']; // 187 -> 61\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.DASH] = Keys.ASCII['-']; // 189 -> 45\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.COMMA] = Keys.ASCII[',']; // 188 -> 44\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.PERIOD] = Keys.ASCII['.']; // 190 -> 46\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.SLASH] = Keys.ASCII['/']; // 191 -> 47\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.BQUOTE] = Keys.ASCII['`']; // 192 -> 96\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.LBRACK] = Keys.ASCII['[']; // 219 -> 91\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.BSLASH] = Keys.ASCII['\\\\']; // 220 -> 92\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.RBRACK] = Keys.ASCII[']']; // 221 -> 93\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.QUOTE] = Keys.ASCII[\"'\"]; // 222 -> 39\n\n/*\n * Maps unshifted keyCodes to their shifted counterparts; to be used when a shift-key is down.\n * Alphabetic characters are handled in code, since they must also take CAPS_LOCK into consideration.\n */\nKeys.SHIFTED_KEYCODES = {};\nKeys.SHIFTED_KEYCODES[Keys.ASCII['1']] = Keys.ASCII['!'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['2']] = Keys.ASCII['@'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['3']] = Keys.ASCII['#'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['4']] = Keys.ASCII['$'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['5']] = Keys.ASCII['%'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['6']] = Keys.ASCII['^'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['7']] = Keys.ASCII['&'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['8']] = Keys.ASCII['*'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['9']] = Keys.ASCII['('];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['0']] = Keys.ASCII[')'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.SEMI] = Keys.ASCII[':'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.EQUALS] = Keys.ASCII['+'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.COMMA] = Keys.ASCII['<'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.DASH] = Keys.ASCII['_'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.PERIOD] = Keys.ASCII['>'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.SLASH] = Keys.ASCII['?'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.BQUOTE] = Keys.ASCII['~'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.LBRACK] = Keys.ASCII['{'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.BSLASH] = Keys.ASCII['|'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.RBRACK] = Keys.ASCII['}'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.QUOTE] = Keys.ASCII['\"'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.ASCII['_'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_EQUALS] = Keys.ASCII['+'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_SEMI] = Keys.ASCII[':'];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/strlib.js (C) Jeff Parsons 2012-2018\n */\n\nclass Str {\n /**\n * isValidInt(s, base)\n *\n * The built-in parseInt() function has the annoying feature of returning a partial value (ie,\n * up to the point where it encounters an invalid character); eg, parseInt(\"foo\", 16) returns 0xf.\n *\n * So it's best to use our own Str.parseInt() function, which will in turn use this function to\n * validate the entire string.\n *\n * @param {string} s is the string representation of some number\n * @param {number} [base] is the radix to use (default is 10); only 2, 8, 10 and 16 are supported\n * @return {boolean} true if valid, false if invalid (or the specified base isn't supported)\n */\n static isValidInt(s, base)\n {\n if (!base || base == 10) return s.match(/^-?[0-9]+$/) !== null;\n if (base == 16) return s.match(/^-?[0-9a-f]+$/i) !== null;\n if (base == 8) return s.match(/^-?[0-7]+$/) !== null;\n if (base == 2) return s.match(/^-?[01]+$/) !== null;\n return false;\n }\n\n /**\n * parseInt(s, base)\n *\n * This is a wrapper around the built-in parseInt() function. Our wrapper recognizes certain prefixes\n * ('$' or \"0x\" for hex, '#' or \"0o\" for octal) and suffixes ('.' for decimal, 'h' for hex, 'y' for\n * binary), and then calls isValidInt() to ensure we don't convert strings that contain partial values;\n * see isValidInt() for details.\n *\n * The use of multiple prefix/suffix combinations is undefined (although for the record, we process\n * prefixes first). We do NOT support the \"0b\" prefix to indicate binary UNLESS one or more commas are\n * also present (because \"0b\" is also a valid hex sequence), and we do NOT support a single leading zero\n * to indicate octal (because such a number could also be decimal or hex). Any number of commas are\n * allowed; we remove them all before calling the built-in parseInt().\n *\n * More recently, we've added support for \"^D\", \"^O\", and \"^B\" prefixes to accommodate the base overrides\n * that the PDP-10's MACRO-10 assembly language supports (decimal, octal, and binary, respectively).\n * If this support turns out to adversely affect other debuggers, then it will have to be \"conditionalized\".\n * Similarly, we've added support for \"K\", \"M\", and \"G\" MACRO-10-style suffixes that add 3, 6, or 9 zeros\n * to the value to be parsed, respectively.\n *\n * @param {string} s is the string representation of some number\n * @param {number} [base] is the radix to use (default is 10); can be overridden by prefixes/suffixes\n * @return {number|undefined} corresponding value, or undefined if invalid\n */\n static parseInt(s, base)\n {\n var value;\n\n if (s) {\n if (!base) base = 10;\n\n var ch, chPrefix, chSuffix;\n var fCommas = (s.indexOf(',') > 0);\n if (fCommas) s = s.replace(/,/g, '');\n\n ch = chPrefix = s.charAt(0);\n if (chPrefix == '#') {\n base = 8;\n chPrefix = '';\n }\n else if (chPrefix == '$') {\n base = 16;\n chPrefix = '';\n }\n if (ch != chPrefix) {\n s = s.substr(1);\n }\n else {\n ch = chPrefix = s.substr(0, 2);\n if (chPrefix == '0b' && fCommas || chPrefix == '^B') {\n base = 2;\n chPrefix = '';\n }\n else if (chPrefix == '0o' || chPrefix == '^O') {\n base = 8;\n chPrefix = '';\n }\n else if (chPrefix == '^D') {\n base = 10;\n chPrefix = '';\n }\n else if (chPrefix == '0x') {\n base = 16;\n chPrefix = '';\n }\n if (ch != chPrefix) s = s.substr(2);\n }\n ch = chSuffix = s.slice(-1);\n if (chSuffix == 'Y' || chSuffix == 'y') {\n base = 2;\n chSuffix = '';\n }\n else if (chSuffix == '.') {\n base = 10;\n chSuffix = '';\n }\n else if (chSuffix == 'H' || chSuffix == 'h') {\n base = 16;\n chSuffix = '';\n }\n else if (chSuffix == 'K') {\n chSuffix = '000';\n }\n else if (chSuffix == 'M') {\n chSuffix = '000000';\n }\n else if (chSuffix == 'G') {\n chSuffix = '000000000';\n }\n if (ch != chSuffix) s = s.slice(0, -1) + chSuffix;\n /*\n * This adds support for the MACRO-10 binary shifting (Bn) suffix, which must be stripped from the\n * number before parsing, and then applied to the value after parsing. If n is omitted, 35 is assumed,\n * which is a net shift of zero. If n < 35, then a left shift of (35 - n) is required; if n > 35, then\n * a right shift of -(35 - n) is required.\n */\n var v, shift = 0;\n if (base <= 10) {\n var match = s.match(/(-?[0-9]+)B([0-9]*)/);\n if (match) {\n s = match[1];\n shift = 35 - ((match[2] || 35) & 0xff);\n }\n }\n if (Str.isValidInt(s, base) && !isNaN(v = parseInt(s, base))) {\n /*\n * With the need to support larger (eg, 36-bit) integers, truncating to 32 bits is no longer helpful.\n *\n * value = v|0;\n */\n if (shift) {\n /*\n * Since binary shifting is a logical operation, and since shifting by division only works properly\n * with positive numbers, we must convert a negative value to a positive value, by computing the two's\n * complement.\n */\n if (v < 0) v += Math.pow(2, 36);\n if (shift > 0) {\n v *= Math.pow(2, shift);\n } else {\n v = Math.trunc(v / Math.pow(2, -shift));\n }\n }\n value = v;\n }\n }\n return value;\n }\n\n /**\n * toBase(n, radix, cch, sPrefix, nGrouping)\n *\n * Displays the given number as an unsigned integer using the specified radix and number of digits.\n *\n * @param {number|null|undefined} n\n * @param {number} radix (ie, the base)\n * @param {number} cch (the desired number of digits)\n * @param {string} [sPrefix] (default is none)\n * @param {number} [nGrouping]\n * @return {string}\n */\n static toBase(n, radix, cch, sPrefix = \"\", nGrouping = 0)\n {\n /*\n * An initial \"falsey\" check for null takes care of both null and undefined;\n * we can't rely entirely on isNaN(), because isNaN(null) returns false, oddly enough.\n *\n * Alternatively, we could mask and shift n regardless of whether it's null/undefined/NaN,\n * since JavaScript coerces such operands to zero, but I think there's \"value\" in seeing those\n * values displayed differently.\n */\n var s = \"\";\n if (isNaN(n)) {\n n = null;\n } else if (n != null) {\n /*\n * Callers that produced an input by dividing by a power of two rather than shifting (in order\n * to access more than 32 bits) may produce a fractional result, which ordinarily we would simply\n * ignore, but if the integer portion is zero and the sign is negative, we should probably treat\n * this value as a sign-extension.\n */\n if (n < 0 && n > -1) n = -1;\n /*\n * Negative values should be two's complemented according to the number of digits; for example,\n * 12 octal digits implies an upper limit 8^12.\n */\n if (n < 0) {\n n += Math.pow(radix, cch);\n }\n if (n >= Math.pow(radix, cch)) {\n cch = Math.ceil(Math.log(n) / Math.log(radix));\n }\n }\n var g = nGrouping || -1;\n while (cch-- > 0) {\n if (!g) {\n s = ',' + s;\n g = nGrouping;\n }\n if (n == null) {\n s = '?' + s;\n } else {\n var d = n % radix;\n d += (d >= 0 && d <= 9? 0x30 : 0x41 - 10);\n s = String.fromCharCode(d) + s;\n n = Math.trunc(n / radix);\n }\n g--;\n }\n return sPrefix + s;\n }\n\n /**\n * toBin(n, cch, nGrouping)\n *\n * Converts an integer to binary, with the specified number of digits (up to a maximum of 36).\n *\n * @param {number|null|undefined} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of binary digits (0 or undefined for default of either 8, 18, or 36)\n * @param {number} [nGrouping]\n * @return {string} the binary representation of n\n */\n static toBin(n, cch, nGrouping)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.LN2) || 1;\n var v = Math.abs(n);\n if (v <= 0b11111111) {\n cch = 8;\n } else if (v <= 0b111111111111111111) {\n cch = 18;\n } else {\n cch = 36;\n }\n } else if (cch > 36) cch = 36;\n return Str.toBase(n, 2, cch, \"\", nGrouping);\n }\n\n /**\n * toBinBytes(n, cb, fPrefix)\n *\n * Converts an integer to binary, with the specified number of bytes (up to the default of 4).\n *\n * @param {number|null|undefined} n (interpreted as a 32-bit value)\n * @param {number} [cb] is the desired number of binary bytes (4 is both the default and the maximum)\n * @param {boolean} [fPrefix]\n * @return {string} the binary representation of n\n */\n static toBinBytes(n, cb, fPrefix)\n {\n var s = \"\";\n if (!cb || cb > 4) cb = 4;\n for (var i = 0; i < cb; i++) {\n if (s) s = ',' + s;\n s = Str.toBin(n & 0xff, 8) + s;\n n >>= 8;\n }\n return (fPrefix? \"0b\" : \"\") + s;\n }\n\n /**\n * toOct(n, cch, fPrefix)\n *\n * Converts an integer to octal, with the specified number of digits (default of 6; max of 12)\n *\n * You might be tempted to use the built-in n.toString(8) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw\n * an exception, whereas this function will return '?' characters.\n *\n * @param {number|null|undefined} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of octal digits (0 or undefined for default of either 6, 8, or 12)\n * @param {boolean} [fPrefix]\n * @return {string} the octal representation of n\n */\n static toOct(n, cch, fPrefix)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.log(8)) || 1;\n var v = Math.abs(n);\n if (v <= 0o777777) {\n cch = 6;\n } else if (v <= 0o77777777) {\n cch = 8;\n } else {\n cch = 12;\n }\n } else if (cch > 12) cch = 12;\n return Str.toBase(n, 8, cch, fPrefix? \"0o\" : \"\");\n }\n\n /**\n * toDec(n, cch)\n *\n * Converts an integer to decimal, with the specified number of digits (default of 5; max of 11)\n *\n * You might be tempted to use the built-in n.toString(10) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw\n * an exception, whereas this function will return '?' characters.\n *\n * @param {number|null|undefined} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of decimal digits (0 or undefined for default of either 5 or 11)\n * @return {string} the decimal representation of n\n */\n static toDec(n, cch)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.LN10) || 1;\n var v = Math.abs(n);\n if (v <= 99999) {\n cch = 5;\n } else {\n cch = 11;\n }\n } else if (cch > 11) cch = 11;\n return Str.toBase(n, 10, cch);\n }\n\n /**\n * toHex(n, cch, fPrefix)\n *\n * Converts an integer to hex, with the specified number of digits (default of 4 or 8, max of 9).\n *\n * You might be tempted to use the built-in n.toString(16) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values; for example, if n is -2147483647, then n.toString(16)\n * will return \"-7fffffff\" instead of \"80000001\". Moreover, if n is undefined, n.toString() will\n * throw an exception, whereas this function will return '?' characters.\n *\n * NOTE: The following work-around (adapted from code found on StackOverflow) would be another solution,\n * taking care of negative values, zero-padding, and upper-casing, but not null/undefined/NaN values:\n *\n * s = (n < 0? n + 0x100000000 : n).toString(16);\n * s = \"00000000\".substr(0, 8 - s.length) + s;\n * s = s.substr(0, cch).toUpperCase();\n *\n * @param {number|null|undefined} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of hex digits (0 or undefined for default of either 4, 8, or 9)\n * @param {boolean} [fPrefix]\n * @return {string} the hex representation of n\n */\n static toHex(n, cch, fPrefix)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.log(16)) || 1;\n var v = Math.abs(n);\n if (v <= 0xffff) {\n cch = 4;\n } else if (v <= 0xffffffff) {\n cch = 8;\n } else {\n cch = 9;\n }\n } else if (cch > 9) cch = 9;\n return Str.toBase(n, 16, cch, fPrefix? \"0x\" : \"\");\n }\n\n /**\n * toHexByte(b)\n *\n * Alias for Str.toHex(b, 2, true)\n *\n * @param {number|null|undefined} b is a byte value\n * @return {string} the hex representation of b\n */\n static toHexByte(b)\n {\n return Str.toHex(b, 2, true);\n }\n\n /**\n * toHexWord(w)\n *\n * Alias for Str.toHex(w, 4, true)\n *\n * @param {number|null|undefined} w is a word (16-bit) value\n * @return {string} the hex representation of w\n */\n static toHexWord(w)\n {\n return Str.toHex(w, 4, true);\n }\n\n /**\n * toHexLong(l)\n *\n * Alias for Str.toHex(l, 8, true)\n *\n * @param {number|null|undefined} l is a dword (32-bit) value\n * @return {string} the hex representation of w\n */\n static toHexLong(l)\n {\n return Str.toHex(l, 8, true);\n }\n\n /**\n * getBaseName(sFileName, fStripExt)\n *\n * This is a poor-man's version of Node's path.basename(), which Node-only components should use instead.\n *\n * Note that if fStripExt is true, this strips ANY extension, whereas path.basename() strips the extension only\n * if it matches the second parameter (eg, path.basename(\"/foo/bar/baz/asdf/quux.html\", \".html\") returns \"quux\").\n *\n * @param {string} sFileName\n * @param {boolean} [fStripExt]\n * @return {string}\n */\n static getBaseName(sFileName, fStripExt)\n {\n var sBaseName = sFileName;\n\n var i = sFileName.lastIndexOf('/');\n if (i >= 0) sBaseName = sFileName.substr(i + 1);\n\n /*\n * This next bit is a kludge to clean up names that are part of a URL that includes unsightly query parameters.\n */\n i = sBaseName.indexOf('&');\n if (i > 0) sBaseName = sBaseName.substr(0, i);\n\n if (fStripExt) {\n i = sBaseName.lastIndexOf(\".\");\n if (i > 0) {\n sBaseName = sBaseName.substring(0, i);\n }\n }\n return sBaseName;\n }\n\n /**\n * getExtension(sFileName)\n *\n * This is a poor-man's version of Node's path.extname(), which Node-only components should use instead.\n *\n * Note that we EXCLUDE the period from the returned extension, whereas path.extname() includes it.\n *\n * @param {string} sFileName\n * @return {string} the filename's extension (in lower-case and EXCLUDING the \".\"), or an empty string\n */\n static getExtension(sFileName)\n {\n var sExtension = \"\";\n var i = sFileName.lastIndexOf(\".\");\n if (i >= 0) {\n sExtension = sFileName.substr(i + 1).toLowerCase();\n }\n return sExtension;\n }\n\n /**\n * endsWith(s, sSuffix)\n *\n * @param {string} s\n * @param {string} sSuffix\n * @return {boolean} true if s ends with sSuffix, false if not\n */\n static endsWith(s, sSuffix)\n {\n return s.indexOf(sSuffix, s.length - sSuffix.length) !== -1;\n }\n\n /**\n * escapeHTML(sHTML)\n *\n * @param {string} sHTML\n * @return {string} with HTML entities \"escaped\", similar to PHP's htmlspecialchars()\n */\n static escapeHTML(sHTML)\n {\n return sHTML.replace(/[&<>\"']/g, function(m)\n {\n return Str.HTMLEscapeMap[m];\n });\n }\n\n /**\n * replace(sSearch, sReplace, s)\n *\n * The JavaScript replace() function ALWAYS interprets \"$\" specially in replacement strings, even when\n * the search string is NOT a RegExp; specifically:\n *\n * $$ Inserts a \"$\"\n * $& Inserts the matched substring\n * $` Inserts the portion of the string that precedes the matched substring\n * $' Inserts the portion of the string that follows the matched substring\n * $n Where n is a positive integer less than 100, inserts the nth parenthesized sub-match string,\n * provided the first argument was a RegExp object\n *\n * So, if a replacement string containing dollar signs passes through a series of replace() calls, untold\n * problems could result. Hence, this function, which simply uses the replacement string as-is.\n *\n * Similar to the JavaScript replace() method (when sSearch is a string), this replaces only ONE occurrence\n * (ie, the FIRST occurrence); it might be nice to add options to replace the LAST occurrence and/or ALL\n * occurrences, but we'll revisit that later.\n *\n * @param {string} sSearch\n * @param {string} sReplace\n * @param {string} s\n * @return {string}\n */\n static replace(sSearch, sReplace, s)\n {\n var i = s.indexOf(sSearch);\n if (i >= 0) {\n s = s.substr(0, i) + sReplace + s.substr(i + sSearch.length);\n }\n return s;\n }\n\n /**\n * replaceAll(sSearch, sReplace, s)\n *\n * @param {string} sSearch\n * @param {string} sReplace\n * @param {string} s\n * @return {string}\n */\n static replaceAll(sSearch, sReplace, s)\n {\n var a = {};\n a[sSearch] = sReplace;\n return Str.replaceArray(a, s);\n }\n\n /**\n * replaceArray(a, s)\n *\n * @param {Object} a\n * @param {string} s\n * @return {string}\n */\n static replaceArray(a, s)\n {\n var sMatch = \"\";\n for (var k in a) {\n /*\n * As noted in:\n *\n * http://www.regexguru.com/2008/04/escape-characters-only-when-necessary/\n *\n * inside character classes, only backslash, caret, hyphen and the closing bracket need to be\n * escaped. And in fact, if you ensure that the closing bracket is first, the caret is not first,\n * and the hyphen is last, you can avoid escaping those as well.\n */\n k = k.replace(/([\\\\[\\]*{}().+?|$])/g, \"\\\\$1\");\n sMatch += (sMatch? '|' : '') + k;\n }\n return s.replace(new RegExp('(' + sMatch + ')', \"g\"), function(m)\n {\n return a[m];\n });\n }\n\n /**\n * pad(s, cch, fPadLeft)\n *\n * NOTE: the maximum amount of padding currently supported is 40 spaces.\n *\n * @param {string} s is a string\n * @param {number} cch is desired length\n * @param {boolean} [fPadLeft] (default is padding on the right)\n * @return {string} the original string (s) with spaces padding it to the specified length\n */\n static pad(s, cch, fPadLeft)\n {\n var sPadding = \" \";\n return fPadLeft? (sPadding + s).slice(-cch) : (s + sPadding).slice(0, cch);\n }\n\n /**\n * sprintf(format, ...args)\n *\n * Copied from the CCjs project (https://github.com/jeffpar/ccjs/blob/master/lib/stdio.js) and extended.\n *\n * Far from complete, let alone sprintf-compatible, but it's adequate for the handful of sprintf-style format\n * specifiers that I use.\n *\n * @param {string} format\n * @param {...} args\n * @return {string}\n */\n static sprintf(format, ...args)\n {\n let buffer = \"\";\n let aParts = format.split(/%([-+ 0#]?)([0-9]*)(\\.?)([0-9]*)([hlL]?)([A-Za-z%])/);\n\n let iArg = 0, iPart;\n for (iPart = 0; iPart < aParts.length - 7; iPart += 7) {\n\n buffer += aParts[iPart];\n\n let arg = args[iArg++];\n let flags = aParts[iPart+1];\n let minimum = +aParts[iPart+2] || 0;\n let precision = +aParts[iPart+4] || 0;\n let conversion = aParts[iPart+6];\n let ach = null, s;\n\n switch(conversion) {\n case 'd':\n /*\n * We could use \"arg |= 0\", but there may be some value to supporting integers > 32 bits.\n * \n * Also, unlike the 'X' and 'x' hexadecimal cases, there's no need to explicitly check for a string\n * arguments, because the call to trunc() automatically coerces any string value to a (decimal) number.\n */\n arg = Math.trunc(arg);\n /* falls through */\n\n case 'f':\n s = Math.trunc(arg) + \"\";\n if (precision) {\n minimum -= (precision + 1);\n }\n if (s.length < minimum) {\n if (flags == '0') {\n if (arg < 0) minimum--;\n s = (\"0000000000\" + Math.abs(arg)).slice(-minimum);\n if (arg < 0) s = '-' + s;\n } else {\n s = (\" \" + s).slice(-minimum);\n }\n }\n if (precision) {\n arg = Math.round((arg - Math.trunc(arg)) * Math.pow(10, precision));\n s += '.' + (\"0000000000\" + Math.abs(arg)).slice(-precision);\n }\n buffer += s;\n break;\n\n case 'c':\n arg = String.fromCharCode(arg);\n /* falls through */\n\n case 's':\n if (typeof arg == \"string\") {\n while (arg.length < minimum) {\n if (flags == '-') {\n arg += ' ';\n } else {\n arg = ' ' + arg;\n }\n }\n }\n buffer += arg;\n break;\n\n case 'X':\n ach = Str.HexUpperCase;\n /* falls through */\n\n case 'x':\n if (!ach) ach = Str.HexLowerCase;\n s = \"\";\n if (typeof arg == \"string\") {\n /*\n * Since we're advised to ALWAYS pass a radix to parseInt(), we must detect explicitly\n * hex values ourselves, because using a radix of 10 with any \"0x...\" value always returns 0.\n * \n * And if the value CAN be interpreted as decimal, then we MUST interpret it as decimal, because\n * we have sprintf() calls in /modules/lib/testmon.js that depend on this code to perform decimal\n * to hex conversion. We're allowed to make our own rules here, since passing numbers in string\n * form isn't part of the sprintf \"spec\". \n */\n arg = Number.parseInt(arg, arg.match(/(^0x|[a-f])/i)? 16 : 10);\n } \n do {\n s = ach[arg & 0xf] + s;\n arg >>>= 4;\n } while (--minimum > 0 || arg);\n buffer += s;\n break;\n\n default:\n /*\n * The supported ANSI C set of conversions: \"dioxXucsfeEgGpn%\"\n */\n buffer += \"(unrecognized printf conversion %\" + conversion + \")\";\n break;\n }\n }\n\n buffer += aParts[iPart];\n return buffer;\n }\n\n /**\n * stripLeadingZeros(s, fPad)\n *\n * @param {string} s\n * @param {boolean} [fPad]\n * @return {string}\n */\n static stripLeadingZeros(s, fPad)\n {\n var cch = s.length;\n s = s.replace(/^0+([0-9A-F]+)$/i, \"$1\");\n if (fPad) s = Str.pad(s, cch, true);\n return s;\n }\n\n /**\n * trim(s)\n *\n * @param {string} s\n * @return {string}\n */\n static trim(s)\n {\n if (String.prototype.trim) {\n return s.trim();\n }\n return s.replace(/^\\s+|\\s+$/g, \"\");\n }\n\n /**\n * toASCIICode(b)\n *\n * @param {number} b\n * @return {string}\n */\n static toASCIICode(b)\n {\n var s;\n if (b != Str.ASCII.CR && b != Str.ASCII.LF) {\n s = Str.ASCIICodeMap[b];\n }\n if (s) {\n s = '<' + s + '>';\n } else {\n s = String.fromCharCode(b);\n }\n return s;\n }\n}\n\n/*\n * Map special characters to their HTML escape sequences.\n */\nStr.HTMLEscapeMap = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n};\n\n/*\n * Map \"unprintable\" ASCII codes to mnemonics, to more clearly see what's being printed.\n */\nStr.ASCIICodeMap = {\n 0x00: \"NUL\",\n 0x01: \"SOH\", // (CTRL_A) Start of Heading\n 0x02: \"STX\", // (CTRL_B) Start of Text\n 0x03: \"ETX\", // (CTRL_C) End of Text\n 0x04: \"EOT\", // (CTRL_D) End of Transmission\n 0x05: \"ENQ\", // (CTRL_E) Enquiry\n 0x06: \"ACK\", // (CTRL_F) Acknowledge\n 0x07: \"BEL\", // (CTRL_G) Bell\n 0x08: \"BS\", // (CTRL_H) Backspace\n 0x09: \"TAB\", // (CTRL_I) Horizontal Tab (aka HT)\n 0x0A: \"LF\", // (CTRL_J) Line Feed (New Line)\n 0x0B: \"VT\", // (CTRL_K) Vertical Tab\n 0x0C: \"FF\", // (CTRL_L) Form Feed (New Page)\n 0x0D: \"CR\", // (CTRL_M) Carriage Return\n 0x0E: \"SO\", // (CTRL_N) Shift Out\n 0x0F: \"SI\", // (CTRL_O) Shift In\n 0x10: \"DLE\", // (CTRL_P) Data Link Escape\n 0x11: \"XON\", // (CTRL_Q) Device Control 1 (aka DC1)\n 0x12: \"DC2\", // (CTRL_R) Device Control 2\n 0x13: \"XOFF\", // (CTRL_S) Device Control 3 (aka DC3)\n 0x14: \"DC4\", // (CTRL_T) Device Control 4\n 0x15: \"NAK\", // (CTRL_U) Negative Acknowledge\n 0x16: \"SYN\", // (CTRL_V) Synchronous Idle\n 0x17: \"ETB\", // (CTRL_W) End of Transmission Block\n 0x18: \"CAN\", // (CTRL_X) Cancel\n 0x19: \"EM\", // (CTRL_Y) End of Medium\n 0x1A: \"SUB\", // (CTRL_Z) Substitute\n 0x1B: \"ESC\", // Escape\n 0x1C: \"FS\", // File Separator\n 0x1D: \"GS\", // Group Separator\n 0x1E: \"RS\", // Record Separator\n 0x1F: \"US\", // Unit Separator\n 0x7F: \"DEL\"\n};\n\n/*\n * Refer to: https://en.wikipedia.org/wiki/Code_page_437\n */\nStr.CP437ToUnicode = [\n '\\u0000', '\\u263A', '\\u263B', '\\u2665', '\\u2666', '\\u2663', '\\u2660', '\\u2022',\n '\\u25D8', '\\u25CB', '\\u25D9', '\\u2642', '\\u2640', '\\u266A', '\\u266B', '\\u263C',\n '\\u25BA', '\\u25C4', '\\u2195', '\\u203C', '\\u00B6', '\\u00A7', '\\u25AC', '\\u21A8',\n '\\u2191', '\\u2193', '\\u2192', '\\u2190', '\\u221F', '\\u2194', '\\u25B2', '\\u25BC',\n '\\u0020', '\\u0021', '\\u0022', '\\u0023', '\\u0024', '\\u0025', '\\u0026', '\\u0027',\n '\\u0028', '\\u0029', '\\u002A', '\\u002B', '\\u002C', '\\u002D', '\\u002E', '\\u002F',\n '\\u0030', '\\u0031', '\\u0032', '\\u0033', '\\u0034', '\\u0035', '\\u0036', '\\u0037',\n '\\u0038', '\\u0039', '\\u003A', '\\u003B', '\\u003C', '\\u003D', '\\u003E', '\\u003F',\n '\\u0040', '\\u0041', '\\u0042', '\\u0043', '\\u0044', '\\u0045', '\\u0046', '\\u0047',\n '\\u0048', '\\u0049', '\\u004A', '\\u004B', '\\u004C', '\\u004D', '\\u004E', '\\u004F',\n '\\u0050', '\\u0051', '\\u0052', '\\u0053', '\\u0054', '\\u0055', '\\u0056', '\\u0057',\n '\\u0058', '\\u0059', '\\u005A', '\\u005B', '\\u005C', '\\u005D', '\\u005E', '\\u005F',\n '\\u0060', '\\u0061', '\\u0062', '\\u0063', '\\u0064', '\\u0065', '\\u0066', '\\u0067',\n '\\u0068', '\\u0069', '\\u006A', '\\u006B', '\\u006C', '\\u006D', '\\u006E', '\\u006F',\n '\\u0070', '\\u0071', '\\u0072', '\\u0073', '\\u0074', '\\u0075', '\\u0076', '\\u0077',\n '\\u0078', '\\u0079', '\\u007A', '\\u007B', '\\u007C', '\\u007D', '\\u007E', '\\u2302',\n '\\u00C7', '\\u00FC', '\\u00E9', '\\u00E2', '\\u00E4', '\\u00E0', '\\u00E5', '\\u00E7',\n '\\u00EA', '\\u00EB', '\\u00E8', '\\u00EF', '\\u00EE', '\\u00EC', '\\u00C4', '\\u00C5',\n '\\u00C9', '\\u00E6', '\\u00C6', '\\u00F4', '\\u00F6', '\\u00F2', '\\u00FB', '\\u00F9',\n '\\u00FF', '\\u00D6', '\\u00DC', '\\u00A2', '\\u00A3', '\\u00A5', '\\u20A7', '\\u0192',\n '\\u00E1', '\\u00ED', '\\u00F3', '\\u00FA', '\\u00F1', '\\u00D1', '\\u00AA', '\\u00BA',\n '\\u00BF', '\\u2310', '\\u00AC', '\\u00BD', '\\u00BC', '\\u00A1', '\\u00AB', '\\u00BB',\n '\\u2591', '\\u2592', '\\u2593', '\\u2502', '\\u2524', '\\u2561', '\\u2562', '\\u2556',\n '\\u2555', '\\u2563', '\\u2551', '\\u2557', '\\u255D', '\\u255C', '\\u255B', '\\u2510',\n '\\u2514', '\\u2534', '\\u252C', '\\u251C', '\\u2500', '\\u253C', '\\u255E', '\\u255F',\n '\\u255A', '\\u2554', '\\u2569', '\\u2566', '\\u2560', '\\u2550', '\\u256C', '\\u2567',\n '\\u2568', '\\u2564', '\\u2565', '\\u2559', '\\u2558', '\\u2552', '\\u2553', '\\u256B',\n '\\u256A', '\\u2518', '\\u250C', '\\u2588', '\\u2584', '\\u258C', '\\u2590', '\\u2580',\n '\\u03B1', '\\u00DF', '\\u0393', '\\u03C0', '\\u03A3', '\\u03C3', '\\u00B5', '\\u03C4',\n '\\u03A6', '\\u0398', '\\u03A9', '\\u03B4', '\\u221E', '\\u03C6', '\\u03B5', '\\u2229',\n '\\u2261', '\\u00B1', '\\u2265', '\\u2264', '\\u2320', '\\u2321', '\\u00F7', '\\u2248',\n '\\u00B0', '\\u2219', '\\u00B7', '\\u221A', '\\u207F', '\\u00B2', '\\u25A0', '\\u00A0'\n];\n\n/*\n * TODO: Future home of a complete ASCII table.\n */\nStr.ASCII = {\n LF: 0x0A,\n CR: 0x0D\n};\n\nStr.TYPES = {\n NULL: 0,\n BYTE: 1,\n WORD: 2,\n DWORD: 3,\n NUMBER: 4,\n STRING: 5,\n BOOLEAN: 6,\n OBJECT: 7,\n ARRAY: 8\n};\n\nStr.HexLowerCase = \"0123456789abcdef\";\nStr.HexUpperCase = \"0123456789ABCDEF\";\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/usrlib.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @typedef {{\n * mask: number,\n * shift: number\n * }}\n */\nvar BitField;\n\n/**\n * @typedef {Object.<BitField>}\n */\nvar BitFields;\n\nclass Usr {\n /**\n * binarySearch(a, v, fnCompare)\n *\n * @param {Array} a is an array\n * @param {number|string|Array|Object} v\n * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]\n * @return {number} the index of matching entry if non-negative, otherwise the index of the insertion point\n */\n static binarySearch(a, v, fnCompare)\n {\n var left = 0;\n var right = a.length;\n var found = 0;\n if (fnCompare === undefined) {\n fnCompare = function(a, b)\n {\n return a > b ? 1 : a < b ? -1 : 0;\n };\n }\n while (left < right) {\n var middle = (left + right) >> 1;\n var compareResult;\n compareResult = fnCompare(v, a[middle]);\n if (compareResult > 0) {\n left = middle + 1;\n } else {\n right = middle;\n found = !compareResult;\n }\n }\n return found ? left : ~left;\n }\n\n /**\n * binaryInsert(a, v, fnCompare)\n *\n * If element v already exists in array a, the array is unchanged (we don't allow duplicates); otherwise, the\n * element is inserted into the array at the appropriate index.\n *\n * @param {Array} a is an array\n * @param {number|string|Array|Object} v is the value to insert\n * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]\n */\n static binaryInsert(a, v, fnCompare)\n {\n var index = Usr.binarySearch(a, v, fnCompare);\n if (index < 0) {\n a.splice(-(index + 1), 0, v);\n }\n }\n\n /**\n * getTimestamp()\n *\n * @return {string} timestamp containing the current date and time (\"yyyy-mm-dd hh:mm:ss\")\n */\n static getTimestamp()\n {\n return Usr.formatDate(\"Y-m-d H:i:s\");\n }\n\n /**\n * getMonthDays(nMonth, nYear)\n *\n * Note that if we're being called on behalf of the RTC, its year is always truncated to two digits (mod 100),\n * so we have no idea what century the year 0 might refer to. When using the normal leap-year formula, 0 fails\n * the mod 100 test but passes the mod 400 test, so as far as the RTC is concerned, every century year is a leap\n * year. Since we're most likely dealing with the year 2000, that's fine, since 2000 was also a leap year.\n *\n * TODO: There IS a separate CMOS byte that's supposed to be set to CMOS_ADDR.CENTURY_DATE; it's always BCD,\n * so theoretically it will contain values like 0x19 or 0x20 (for the 20th and 21st centuries, respectively), and\n * we could add that as another parameter to this function, to improve the accuracy, but that would go beyond what\n * a real RTC actually does.\n *\n * @param {number} nMonth (1-12)\n * @param {number} nYear (normally a 4-digit year, but it may also be mod 100)\n * @return {number} the maximum (1-based) day allowed for the specified month and year\n */\n static getMonthDays(nMonth, nYear)\n {\n var nDays = Usr.aMonthDays[nMonth - 1];\n if (nDays == 28) {\n if ((nYear % 4) === 0 && ((nYear % 100) || (nYear % 400) === 0)) {\n nDays++;\n }\n }\n return nDays;\n }\n\n /**\n * formatDate(sFormat, date)\n *\n * @param {string} sFormat (eg, \"F j, Y\", \"Y-m-d H:i:s\")\n * @param {Date} [date] (default is the current time)\n * @return {string}\n *\n * Supported identifiers in sFormat include:\n *\n * a: lowercase ante meridiem and post meridiem (am or pm)\n * d: day of the month, 2 digits with leading zeros (01,02,...,31)\n * D: 3-letter day of the week (\"Sun\",\"Mon\",...,\"Sat\")\n * F: month (\"January\",\"February\",...,\"December\")\n * g: hour in 12-hour format, without leading zeros (1,2,...,12)\n * h: hour in 24-hour format, without leading zeros (0,1,...,23)\n * H: hour in 24-hour format, with leading zeros (00,01,...,23)\n * i: minutes, with leading zeros (00,01,...,59)\n * j: day of the month, without leading zeros (1,2,...,31)\n * l: day of the week (\"Sunday\",\"Monday\",...,\"Saturday\")\n * m: month, with leading zeros (01,02,...,12)\n * M: 3-letter month (\"Jan\",\"Feb\",...,\"Dec\")\n * n: month, without leading zeros (1,2,...,12)\n * s: seconds, with leading zeros (00,01,...,59)\n * y: 2-digit year (eg, 14)\n * Y: 4-digit year (eg, 2014)\n *\n * For more inspiration, see: http://php.net/manual/en/function.date.php (of which we support ONLY a subset).\n */\n static formatDate(sFormat, date)\n {\n var sDate = \"\";\n if (!date) date = new Date();\n var iHour = date.getHours();\n var iDay = date.getDate();\n var iMonth = date.getMonth() + 1;\n for (var i = 0; i < sFormat.length; i++) {\n var ch;\n switch ((ch = sFormat.charAt(i))) {\n case 'a':\n sDate += (iHour < 12 ? \"am\" : \"pm\");\n break;\n case 'd':\n sDate += ('0' + iDay).slice(-2);\n break;\n case 'D':\n sDate += Usr.asDays[date.getDay()].substr(0, 3);\n break;\n case 'F':\n sDate += Usr.asMonths[iMonth - 1];\n break;\n case 'g':\n sDate += (!iHour ? 12 : (iHour > 12 ? iHour - 12 : iHour));\n break;\n case 'h':\n sDate += iHour;\n break;\n case 'H':\n sDate += ('0' + iHour).slice(-2);\n break;\n case 'i':\n sDate += ('0' + date.getMinutes()).slice(-2);\n break;\n case 'j':\n sDate += iDay;\n break;\n case 'l':\n sDate += Usr.asDays[date.getDay()];\n break;\n case 'm':\n sDate += ('0' + iMonth).slice(-2);\n break;\n case 'M':\n sDate += Usr.asMonths[iMonth - 1].substr(0, 3);\n break;\n case 'n':\n sDate += iMonth;\n break;\n case 's':\n sDate += ('0' + date.getSeconds()).slice(-2);\n break;\n case 'y':\n sDate += (\"\" + date.getFullYear()).slice(-2);\n break;\n case 'Y':\n sDate += date.getFullYear();\n break;\n default:\n sDate += ch;\n break;\n }\n }\n return sDate;\n }\n\n /**\n * defineBitFields(bfs)\n *\n * Prepares a bit field definition for use with getBitField() and setBitField(); eg:\n *\n * var bfs = Usr.defineBitFields({num:20, count:8, btmod:1, type:3});\n *\n * The above defines a set of bit fields containing four fields: num (bits 0-19), count (bits 20-27), btmod (bit 28), and type (bits 29-31).\n *\n * Usr.setBitField(bfs.num, n, 1);\n *\n * The above set bit field \"bfs.num\" in numeric variable \"n\" to the value 1.\n *\n * @param {Object} bfs\n * @return {BitFields}\n */\n static defineBitFields(bfs)\n {\n var bit = 0;\n for (var f in bfs) {\n var width = bfs[f];\n var mask = ((1 << width) - 1) << bit;\n bfs[f] = {mask: mask, shift: bit};\n bit += width;\n }\n return bfs;\n }\n\n /**\n * initBitFields(bfs, ...)\n *\n * @param {BitFields} bfs\n * @param {...number} var_args\n * @return {number} a value containing all supplied bit fields\n */\n static initBitFields(bfs, var_args)\n {\n var v = 0, i = 1;\n for (var f in bfs) {\n if (i >= arguments.length) break;\n v = Usr.setBitField(bfs[f], v, arguments[i++]);\n }\n return v;\n }\n\n /**\n * getBitField(bf, v)\n *\n * @param {BitField} bf\n * @param {number} v is a value containing bit fields\n * @return {number} the value of the bit field in v defined by bf\n */\n static getBitField(bf, v)\n {\n return (v & bf.mask) >> bf.shift;\n }\n\n /**\n * setBitField(bf, v, n)\n *\n * @param {BitField} bf\n * @param {number} v is a value containing bit fields\n * @param {number} n is a value to store in v in the bit field defined by bf\n * @return {number} updated v\n */\n static setBitField(bf, v, n)\n {\n return (v & ~bf.mask) | ((n << bf.shift) & bf.mask);\n }\n\n /**\n * indexOf(a, t, i)\n *\n * Use this instead of Array.prototype.indexOf() if you can't be sure the browser supports it.\n *\n * @param {Array} a\n * @param {*} t\n * @param {number} [i]\n * @returns {number}\n */\n static indexOf(a, t, i)\n {\n if (Array.prototype.indexOf) {\n return a.indexOf(t, i);\n }\n i = i || 0;\n if (i < 0) i += a.length;\n if (i < 0) i = 0;\n for (var n = a.length; i < n; i++) {\n if (i in a && a[i] === t) return i;\n }\n return -1;\n }\n}\n\nUsr.asDays = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\nUsr.asMonths = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\nUsr.aMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\n/**\n * getTime()\n *\n * @return {number} the current time, in milliseconds\n */\nUsr.getTime = Date.now || function() { return +new Date(); };\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/weblib.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * According to http://www.w3schools.com/jsref/jsref_obj_global.asp, these are the *global* properties\n * and functions of JavaScript-in-the-Browser:\n *\n * Property Description\n * ---\n * Infinity A numeric value that represents positive/negative infinity\n * NaN \"Not-a-Number\" value\n * undefined Indicates that a variable has not been assigned a value\n *\n * Function Description\n * ---\n * decodeURI() Decodes a URI\n * decodeURIComponent() Decodes a URI component\n * encodeURI() Encodes a URI\n * encodeURIComponent() Encodes a URI component\n * escape() Deprecated in version 1.5. Use encodeURI() or encodeURIComponent() instead\n * eval() Evaluates a string and executes it as if it was script code\n * isFinite() Determines whether a value is a finite, legal number\n * isNaN() Determines whether a value is an illegal number\n * Number() Converts an object's value to a number\n * parseFloat() Parses a string and returns a floating point number\n * parseInt() Parses a string and returns an integer\n * String() Converts an object's value to a string\n * unescape() Deprecated in version 1.5. Use decodeURI() or decodeURIComponent() instead\n *\n * And according to http://www.w3schools.com/jsref/obj_window.asp, these are the properties and functions\n * of the *window* object.\n *\n * Property Description\n * ---\n * closed Returns a Boolean value indicating whether a window has been closed or not\n * defaultStatus Sets or returns the default text in the statusbar of a window\n * document Returns the Document object for the window (See Document object)\n * frames Returns an array of all the frames (including iframes) in the current window\n * history Returns the History object for the window (See History object)\n * innerHeight Returns the inner height of a window's content area\n * innerWidth Returns the inner width of a window's content area\n * length Returns the number of frames (including iframes) in a window\n * location Returns the Location object for the window (See Location object)\n * name Sets or returns the name of a window\n * navigator Returns the Navigator object for the window (See Navigator object)\n * opener Returns a reference to the window that created the window\n * outerHeight Returns the outer height of a window, including toolbars/scrollbars\n * outerWidth Returns the outer width of a window, including toolbars/scrollbars\n * pageXOffset Returns the pixels the current document has been scrolled (horizontally) from the upper left corner of the window\n * pageYOffset Returns the pixels the current document has been scrolled (vertically) from the upper left corner of the window\n * parent Returns the parent window of the current window\n * screen Returns the Screen object for the window (See Screen object)\n * screenLeft Returns the x coordinate of the window relative to the screen\n * screenTop Returns the y coordinate of the window relative to the screen\n * screenX Returns the x coordinate of the window relative to the screen\n * screenY Returns the y coordinate of the window relative to the screen\n * self Returns the current window\n * status Sets or returns the text in the statusbar of a window\n * top Returns the topmost browser window\n *\n * Method Description\n * ---\n * alert() Displays an alert box with a message and an OK button\n * atob() Decodes a base-64 encoded string\n * blur() Removes focus from the current window\n * btoa() Encodes a string in base-64\n * clearInterval() Clears a timer set with setInterval()\n * clearTimeout() Clears a timer set with setTimeout()\n * close() Closes the current window\n * confirm() Displays a dialog box with a message and an OK and a Cancel button\n * createPopup() Creates a pop-up window\n * focus() Sets focus to the current window\n * moveBy() Moves a window relative to its current position\n * moveTo() Moves a window to the specified position\n * open() Opens a new browser window\n * print() Prints the content of the current window\n * prompt() Displays a dialog box that prompts the visitor for input\n * resizeBy() Resizes the window by the specified pixels\n * resizeTo() Resizes the window to the specified width and height\n * scroll() This method has been replaced by the scrollTo() method.\n * scrollBy() Scrolls the content by the specified number of pixels\n * scrollTo() Scrolls the content to the specified coordinates\n * setInterval() Calls a function or evaluates an expression at specified intervals (in milliseconds)\n * setTimeout() Calls a function or evaluates an expression after a specified number of milliseconds\n * stop() Stops the window from loading\n */\n\nclass Web {\n /**\n * log(s, type)\n *\n * For diagnostic output only. DEBUG must be true (or \"--debug\" specified via the command-line)\n * for Component.log() to display anything.\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n static log(s, type)\n {\n Component.log(s, type);\n }\n\n /**\n * notice(s, fPrintOnly, id)\n *\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n */\n static notice(s, fPrintOnly, id)\n {\n Component.notice(s, fPrintOnly, id);\n }\n\n /**\n * alertUser(sMessage)\n * \n * NOTE: Legacy function for older modules (eg, DiskDump); see Component.alertUser().\n *\n * @param {string} sMessage\n */\n static alertUser(sMessage)\n {\n if (window) {\n window.alert(sMessage);\n } else {\n Web.log(sMessage);\n }\n }\n\n /**\n * getResource(sURL, type, fAsync, done, progress)\n *\n * Request the specified resource (sURL), and once the request is complete, notify done().\n *\n * If fAsync is true, a done() callback should ALWAYS be supplied; otherwise, you'll have no\n * idea when the request is complete or what the response was. done() is passed three parameters:\n *\n * done(sURL, resource, nErrorCode)\n *\n * If nErrorCode is zero, resource should contain the requested data; otherwise, an error occurred.\n *\n * If type is set to a string, that string can be used to control the response format;\n * by default, the response format is plain text, but you can specify \"arraybuffer\" to request arbitrary\n * binary data, in which case the returned resource will be a ArrayBuffer rather than a string.\n *\n * @param {string} sURL\n * @param {string|Object|null} [type] (object for POST request, otherwise type of GET request)\n * @param {boolean} [fAsync] is true for an asynchronous request; false otherwise (MUST be set for IE)\n * @param {function(string,string,number)} [done]\n * @param {function(number)} [progress]\n * @return {Array|null} Array containing [resource, nErrorCode], or null if no response available (yet)\n */\n static getResource(sURL, type = \"text\", fAsync = false, done, progress)\n {\n var nErrorCode = 0, resource = null, response = null;\n\n if (typeof resources == 'object' && (resource = resources[sURL])) {\n if (done) done(sURL, resource, nErrorCode);\n return [resource, nErrorCode];\n }\n else if (fAsync && typeof resources == 'function') {\n resources(sURL, function(resource, nErrorCode)\n {\n if (done) done(sURL, resource, nErrorCode);\n });\n return response;\n }\n\n if (!DEBUG && !NODE) {\n /*\n * TODO: Perhaps it's time for our code in netlib.js to finally add support for HTTPS; for now\n * though, it's just as well that the NODE environment assumes all resources are available locally.\n */\n sURL = sURL.replace(/^\\/(pcjs-disks|private-disks)\\//, \"https://jeffpar.github.io/$1/\");\n }\n else {\n /*\n * The larger resources we put on archive.pcjs.org should also be available locally.\n *\n * NOTE: \"http://archive.pcjs.org\" is now \"https://s3-us-west-2.amazonaws.com/archive.pcjs.org\"\n */\n sURL = sURL.replace(/^(http:\\/\\/archive\\.pcjs\\.org|https:\\/\\/s3-us-west-2\\.amazonaws\\.com\\/archive\\.pcjs\\.org)(\\/.*)\\/([^\\/]*)$/, \"$2/archive/$3\");\n sURL = sURL.replace(/^https:\\/\\/jeffpar\\.github\\.io\\/(pcjs-disks|private-disks)\\/(.*)$/, \"/$1/$2\");\n }\n\n\n var request = (window.XMLHttpRequest? new window.XMLHttpRequest() : new window.ActiveXObject(\"Microsoft.XMLHTTP\"));\n var fArrayBuffer = false, fXHR2 = (typeof request.responseType === 'string');\n \n var callback = function() {\n if (request.readyState !== 4) {\n if (progress) progress(1);\n return null;\n }\n /*\n * The following line was recommended for WebKit, as a work-around to prevent the handler firing multiple\n * times when debugging. Unfortunately, that's not the only XMLHttpRequest problem that occurs when\n * debugging, so I think the WebKit problem is deeper than that. When we have multiple XMLHttpRequests\n * pending, any debugging activity means most of them simply get dropped on floor, so what may actually be\n * happening are mis-notifications rather than redundant notifications.\n *\n * request.onreadystatechange = undefined;\n */\n /*\n * If the request failed due to, say, a CORS policy denial; eg:\n * \n * Failed to load http://www.allbootdisks.com/downloads/Disks/Windows_95_Boot_Disk_Download48/Diskette%20Images/Windows95a.img:\n * Redirect from 'http://www.allbootdisks.com/downloads/Disks/Windows_95_Boot_Disk_Download48/Diskette%20Images/Windows95a.img' to\n * 'http://www.allbootdisks.com/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.\n * Origin 'http://pcjs:8088' is therefore not allowed access.\n * \n * and our request type was \"arraybuffer\", attempting to access responseText may trigger an exception; eg:\n * \n * Uncaught DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's\n * 'responseType' is '' or 'text' (was 'arraybuffer').\n * \n * We could tiptoe around these potential landmines, but the safest thing to do is wrap this code with try/catch.\n */\n try {\n resource = fArrayBuffer? request.response : request.responseText;\n } catch(err) {\n if (MAXDEBUG) Web.log(\"xmlHTTPRequest(\" + sURL + \") exception: \" + err.message);\n }\n /*\n * The normal \"success\" case is a non-null resource and an HTTP status code of 200, but when loading files from the\n * local file system (ie, when using the \"file:\" protocol), we have to be a bit more flexible.\n */\n if (resource != null && (request.status == 200 || !request.status && resource.length && Web.getHostProtocol() == \"file:\")) {\n if (MAXDEBUG) Web.log(\"xmlHTTPRequest(\" + sURL + \"): returned \" + resource.length + \" bytes\");\n }\n else {\n nErrorCode = request.status || -1;\n Web.log(\"xmlHTTPRequest(\" + sURL + \"): error code \" + nErrorCode);\n }\n if (progress) progress(2);\n if (done) done(sURL, resource, nErrorCode);\n return [resource, nErrorCode];\n };\n \n if (fAsync) {\n request.onreadystatechange = callback;\n }\n\n if (progress) progress(0);\n\n if (type && typeof type == \"object\") {\n var sPost = \"\";\n for (var p in type) {\n if (!type.hasOwnProperty(p)) continue;\n if (sPost) sPost += \"&\";\n sPost += p + '=' + encodeURIComponent(type[p]);\n }\n sPost = sPost.replace(/%20/g, '+');\n if (MAXDEBUG) Web.log(\"Web.getResource(POST \" + sURL + \"): \" + sPost.length + \" bytes\");\n request.open(\"POST\", sURL, fAsync);\n request.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\n request.send(sPost);\n } else {\n if (MAXDEBUG) Web.log(\"Web.getResource(GET \" + sURL + \")\");\n request.open(\"GET\", sURL, fAsync);\n if (type == \"arraybuffer\") {\n if (fXHR2) {\n fArrayBuffer = true;\n request.responseType = type;\n } else {\n request.overrideMimeType(\"text/plain; charset=x-user-defined\");\n }\n }\n request.send();\n }\n\n if (!fAsync) {\n request.readyState = 4; // this may already be set for synchronous requests, but I don't want to take any chances \n response = callback();\n }\n return response;\n }\n\n /**\n * parseMemoryResource(sURL, sData)\n *\n * This converts a variety of JSON-style data streams into an Object with the following properties:\n *\n * aBytes\n * aSymbols\n * addrLoad\n * addrExec\n *\n * If the source data contains a 'bytes' array, it's passed through to 'aBytes'; alternatively, if\n * it contains a 'words' array, the values are converted from 16-bit to 8-bit and stored in 'aBytes',\n * and if it contains a 'longs' array, the values are converted from 32-bit longs into bytes and\n * stored in 'aBytes'.\n *\n * Alternatively, if the source data contains a 'data' array, we simply pass that through to the output\n * object as:\n *\n * aData\n *\n * @param {string} sURL\n * @param {string} sData\n * @return {Object|null} (resource)\n */\n static parseMemoryResource(sURL, sData)\n {\n var i;\n var resource = {\n aBytes: null,\n aSymbols: null,\n addrLoad: null,\n addrExec: null\n };\n\n if (sData.charAt(0) == \"[\" || sData.charAt(0) == \"{\") {\n try {\n var a, ib, data;\n\n if (sData.substr(0, 1) == \"<\") { // if the \"data\" begins with a \"<\"...\n /*\n * Early server configs reported an error (via the nErrorCode parameter) if a tape URL was invalid,\n * but more recent server configs now display a somewhat friendlier HTML error page. The downside,\n * however, is that the original error has been buried, and we've received \"data\" that isn't actually\n * tape data. So if the data we've received appears to be \"HTML-like\", we treat it as an error message.\n */\n throw new Error(sData);\n }\n\n /*\n * TODO: IE9 is rather unfriendly and restrictive with regard to how much data it's willing to\n * eval(). In particular, the 10Mb disk image we use for the Windows 1.01 demo config fails in\n * IE9 with an \"Out of memory\" exception. One work-around would be to chop the data into chunks\n * (perhaps one track per chunk, using regular expressions) and then manually re-assemble it.\n *\n * However, it turns out that using JSON.parse(sDiskData) instead of eval(\"(\" + sDiskData + \")\")\n * is a much easier fix. The only drawback is that we must first quote any unquoted property names\n * and remove any comments, because while eval() was cool with them, JSON.parse() is more particular;\n * the following RegExp replacements take care of those requirements.\n *\n * The use of hex values is something else that eval() was OK with, but JSON.parse() is not, and\n * while I've stopped using hex values in DumpAPI responses (at least when \"format=json\" is specified),\n * I can't guarantee they won't show up in \"legacy\" images, and there's no simple RegExp replacement\n * for transforming hex values into decimal values, so I cop out and fall back to eval() if I detect\n * any hex prefixes (\"0x\") in the sequence. Ditto for error messages, which appear like so:\n *\n * [\"unrecognized disk path: test.img\"]\n */\n if (sData.indexOf(\"0x\") < 0 && sData.indexOf(\"0o\") < 0 && sData.substr(0, 2) != '[\"') {\n data = JSON.parse(sData.replace(/([a-z]+):/gm, '\"$1\":').replace(/\\/\\/[^\\n]*/gm, \"\"));\n } else {\n data = eval(\"(\" + sData + \")\");\n }\n\n resource.addrLoad = data['load'];\n resource.addrExec = data['exec'];\n\n if (a = data['bytes']) {\n resource.aBytes = a;\n }\n else if (a = data['words']) {\n /*\n * Convert all words into bytes\n */\n resource.aBytes = new Array(a.length * 2);\n for (i = 0, ib = 0; i < a.length; i++) {\n resource.aBytes[ib++] = a[i] & 0xff;\n resource.aBytes[ib++] = (a[i] >> 8) & 0xff;\n\n }\n }\n else if (a = data['longs']) {\n /*\n * Convert all dwords (longs) into bytes\n */\n resource.aBytes = new Array(a.length * 4);\n for (i = 0, ib = 0; i < a.length; i++) {\n resource.aBytes[ib++] = a[i] & 0xff;\n resource.aBytes[ib++] = (a[i] >> 8) & 0xff;\n resource.aBytes[ib++] = (a[i] >> 16) & 0xff;\n resource.aBytes[ib++] = (a[i] >> 24) & 0xff;\n }\n }\n else if (a = data['data']) {\n resource.aData = a;\n }\n else {\n resource.aBytes = data;\n }\n\n if (resource.aBytes) {\n if (!resource.aBytes.length) {\n Component.error(\"Empty resource: \" + sURL);\n resource = null;\n }\n else if (resource.aBytes.length == 1) {\n Component.error(resource.aBytes[0]);\n resource = null;\n }\n }\n resource.aSymbols = data['symbols'];\n\n } catch (e) {\n Component.error(\"Resource data error (\" + sURL + \"): \" + e.message);\n resource = null;\n }\n }\n else {\n /*\n * Parse the data manually; we assume it's a series of hex byte-values separated by whitespace.\n */\n var ab = [];\n var sHexData = sData.replace(/\\n/gm, \" \").replace(/ +$/, \"\");\n var asHexData = sHexData.split(\" \");\n for (i = 0; i < asHexData.length; i++) {\n var n = parseInt(asHexData[i], 16);\n if (isNaN(n)) {\n Component.error(\"Resource data error (\" + sURL + \"): invalid hex byte (\" + asHexData[i] + \")\");\n break;\n }\n ab.push(n & 0xff);\n }\n if (i == asHexData.length) resource.aBytes = ab;\n }\n return resource;\n }\n\n /**\n * sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)\n *\n * Send a report (eg, bug report) to the server.\n *\n * @param {string} sApp (eg, \"PCjs\")\n * @param {string} sVer (eg, \"1.02\")\n * @param {string} sURL (eg, \"/devices/pc/machine/5150/mda/64kb/machine.xml\")\n * @param {string} sUser (ie, the user key, if any)\n * @param {string} sType (eg, \"bug\"); one of ReportAPI.TYPE.*\n * @param {string} sReport (eg, unparsed state data)\n * @param {string} [sHostName] (default is http://SITEHOST)\n */\n static sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)\n {\n var dataPost = {};\n dataPost[ReportAPI.QUERY.APP] = sApp;\n dataPost[ReportAPI.QUERY.VER] = sVer;\n dataPost[ReportAPI.QUERY.URL] = sURL;\n dataPost[ReportAPI.QUERY.USER] = sUser;\n dataPost[ReportAPI.QUERY.TYPE] = sType;\n dataPost[ReportAPI.QUERY.DATA] = sReport;\n var sReportURL = (sHostName? sHostName : \"http://\" + SITEHOST) + ReportAPI.ENDPOINT;\n Web.getResource(sReportURL, dataPost, true);\n }\n\n /**\n * getHost()\n *\n * @return {string}\n */\n static getHost()\n {\n return (\"http://\" + (window? window.location.host : SITEHOST));\n }\n\n /**\n * getHostURL()\n *\n * @return {string|null}\n */\n static getHostURL()\n {\n return (window? window.location.href : null);\n }\n\n /**\n * getHostProtocol()\n *\n * @return {string}\n */\n static getHostProtocol()\n {\n return (window? window.location.protocol : \"file:\");\n }\n\n /**\n * getUserAgent()\n *\n * @return {string}\n */\n static getUserAgent()\n {\n return (window? window.navigator.userAgent : \"\");\n }\n\n /**\n * hasLocalStorage\n *\n * true if localStorage support exists, is enabled, and works; false otherwise\n *\n * @return {boolean}\n */\n static hasLocalStorage()\n {\n if (Web.fLocalStorage == null) {\n var f = false;\n if (window) {\n try {\n window.localStorage.setItem(Web.sLocalStorageTest, Web.sLocalStorageTest);\n f = (window.localStorage.getItem(Web.sLocalStorageTest) == Web.sLocalStorageTest);\n window.localStorage.removeItem(Web.sLocalStorageTest);\n } catch (e) {\n Web.logLocalStorageError(e);\n f = false;\n }\n }\n Web.fLocalStorage = f;\n }\n return Web.fLocalStorage;\n }\n\n /**\n * logLocalStorageError(e)\n *\n * @param {Error} e is an exception\n */\n static logLocalStorageError(e)\n {\n Web.log(e.message, \"localStorage error\");\n }\n\n /**\n * getLocalStorageItem(sKey)\n *\n * Returns the requested key value, or null if the key does not exist, or undefined if localStorage is not available\n *\n * @param {string} sKey\n * @return {string|null|undefined} sValue\n */\n static getLocalStorageItem(sKey)\n {\n var sValue;\n if (window) {\n try {\n sValue = window.localStorage.getItem(sKey);\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n }\n return sValue;\n }\n\n /**\n * setLocalStorageItem(sKey, sValue)\n *\n * @param {string} sKey\n * @param {string} sValue\n * @return {boolean} true if localStorage is available, false if not\n */\n static setLocalStorageItem(sKey, sValue)\n {\n try {\n window.localStorage.setItem(sKey, sValue);\n return true;\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n return false;\n }\n\n /**\n * removeLocalStorageItem(sKey)\n *\n * @param {string} sKey\n */\n static removeLocalStorageItem(sKey)\n {\n try {\n window.localStorage.removeItem(sKey);\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n }\n\n /**\n * getLocalStorageKeys()\n *\n * @return {Array}\n */\n static getLocalStorageKeys()\n {\n var a = [];\n try {\n for (var i = 0, c = window.localStorage.length; i < c; i++) {\n a.push(window.localStorage.key(i));\n }\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n return a;\n }\n\n /**\n * reloadPage()\n */\n static reloadPage()\n {\n if (window) window.location.reload();\n }\n\n /**\n * isUserAgent(s)\n *\n * Check the browser's user-agent string for the given substring; \"iOS\" and \"MSIE\" are special values you can\n * use that will match any iOS or MSIE browser, respectively (even IE11, in the case of \"MSIE\").\n *\n * 2013-11-06: In a questionable move, MSFT changed the user-agent reported by IE11 on Windows 8.1, eliminating\n * the \"MSIE\" string (which MSDN calls a \"version token\"; see http://msdn.microsoft.com/library/ms537503.aspx);\n * they say \"public websites should rely on feature detection, rather than browser detection, in order to design\n * their sites for browsers that don't support the features used by the website.\" So, in IE11, we get a user-agent\n * that tries to fool apps into thinking the browser is more like WebKit or Gecko:\n *\n * Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko\n *\n * That's a nice idea, but in the meantime, they hosed the XSL transform code in embed.js, which contained\n * some very critical browser-specific code; turning on IE's \"Compatibility Mode\" didn't help either, because\n * that's a sledgehammer solution which restores the old user-agent string but also disables other features like\n * HTML5 canvas support. As an interim solution, I'm treating any \"MSIE\" check as a check for either \"MSIE\" or\n * \"Trident\".\n *\n * UPDATE: I've since found ways to make the code in embed.js more browser-agnostic, so for now, there's isn't\n * any code that cares about \"MSIE\", but I've left the change in place, because I wouldn't be surprised if I'll\n * need more IE-specific code in the future, perhaps for things like copy/paste functionality, or mouse capture.\n *\n * @param {string} s is a substring to search for in the user-agent; as noted above, \"iOS\" and \"MSIE\" are special values\n * @return {boolean} is true if the string was found, false if not\n */\n static isUserAgent(s)\n {\n if (window) {\n var userAgent = Web.getUserAgent();\n /*\n * Here's one case where we have to be careful with Component, because when isUserAgent() is called by\n * the init code below, component.js hasn't been loaded yet. The simple solution for now is to remove the call.\n *\n * Web.log(\"agent: \" + userAgent);\n *\n * And yes, it would be pointless to use the conditional (?) operator below, if not for the Google Closure\n * Compiler (v20130823) failing to detect the entire expression as a boolean.\n */\n return s == \"iOS\" && !!userAgent.match(/(iPod|iPhone|iPad)/) && !!userAgent.match(/AppleWebKit/) || s == \"MSIE\" && !!userAgent.match(/(MSIE|Trident)/) || (userAgent.indexOf(s) >= 0);\n }\n return false;\n }\n\n /**\n * isMobile(sDevice)\n *\n * Checks the URL for a \"mobile\" parameter, and failing that, checks the browser's user-agent string for the\n * substring \"Mobi\", as per Mozilla recommendation:\n *\n * https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent\n *\n * @param {string} [sDevice] (eg, \"iPad\" to check for iPad, or \"!iPad\" to specifically exclude it) \n * @return {boolean} is true if the browser appears to be a mobile (ie, non-desktop) web browser, false if not\n */\n static isMobile(sDevice)\n {\n var sMobile = Web.getURLParm(\"mobile\");\n if (sMobile) return sMobile == \"true\";\n if (Web.isUserAgent(\"Mobi\")) {\n if (!sDevice) return true;\n var fInvert = sDevice[0] == '!';\n if (fInvert) sDevice = sDevice.substr(1);\n return Web.isUserAgent(sDevice) != fInvert;\n }\n return false;\n }\n\n /**\n * findProperty(obj, sProp, sSuffix)\n *\n * If both sProp and sSuffix are set, then any browser-specific prefixes are inserted between sProp and sSuffix,\n * and if a match is found, it is returned without sProp.\n *\n * For example, if findProperty(document, 'on', 'fullscreenchange') discovers that 'onwebkitfullscreenchange' exists,\n * it will return 'webkitfullscreenchange', in preparation for an addEventListener() call.\n *\n * More commonly, sSuffix is not used, so whatever property is found is returned as-is.\n *\n * @param {Object|null|undefined} obj\n * @param {string} sProp\n * @param {string} [sSuffix]\n * @return {string|null}\n */\n static findProperty(obj, sProp, sSuffix)\n {\n if (obj) {\n for (var i = 0; i < Web.asBrowserPrefixes.length; i++) {\n var sName = Web.asBrowserPrefixes[i];\n if (sSuffix) {\n sName += sSuffix;\n var sEvent = sProp + sName;\n if (sEvent in obj) return sName;\n } else {\n if (!sName) {\n sName = sProp[0];\n } else {\n sName += sProp[0].toUpperCase();\n }\n sName += sProp.substr(1);\n if (sName in obj) return sName;\n }\n }\n }\n return null;\n }\n\n /**\n * getURLParm(sParm)\n *\n * First looks for sParm exactly as specified, then looks for the lower-case version.\n *\n * @param {string} sParm\n * @return {string|undefined}\n */\n static getURLParm(sParm)\n {\n if (!Web.parmsURL) {\n Web.parmsURL = Web.parseURLParms();\n }\n return Web.parmsURL[sParm] || Web.parmsURL[sParm.toLowerCase()];\n }\n\n /**\n * parseURLParms(sParms)\n *\n * @param {string} [sParms] containing the parameter portion of a URL (ie, after the '?')\n * @return {Object} containing properties for each parameter found\n */\n static parseURLParms(sParms)\n {\n var aParms = {};\n if (window) { // an alternative to \"if (typeof module === 'undefined')\" if require(\"defines\") was used\n if (!sParms) {\n /*\n * Note that window.location.href returns the entire URL, whereas window.location.search\n * returns only the parameters, if any (starting with the '?', which we skip over with a substr() call).\n */\n sParms = window.location.search.substr(1);\n }\n var match;\n var pl = /\\+/g; // RegExp for replacing addition symbol with a space\n var search = /([^&=]+)=?([^&]*)/g;\n var decode = function(s)\n {\n return decodeURIComponent(s.replace(pl, \" \"));\n };\n\n while ((match = search.exec(sParms))) {\n aParms[decode(match[1])] = decode(match[2]);\n }\n }\n return aParms;\n }\n\n /**\n * downloadFile(sData, sType, fBase64, sFileName)\n *\n * @param {string} sData\n * @param {string} sType\n * @param {boolean} [fBase64]\n * @param {string} [sFileName]\n */\n static downloadFile(sData, sType, fBase64, sFileName)\n {\n var link = null, sAlert;\n var sURI = \"data:application/\" + sType + (fBase64? \";base64\" : \"\") + \",\";\n\n if (!Web.isUserAgent(\"Firefox\")) {\n sURI += (fBase64? sData : encodeURI(sData));\n } else {\n sURI += (fBase64? sData : encodeURIComponent(sData));\n }\n if (sFileName) {\n link = document.createElement('a');\n if (typeof link.download != 'string') link = null;\n }\n if (link) {\n link.href = sURI;\n link.download = sFileName;\n document.body.appendChild(link); // Firefox allegedly requires the link to be in the body\n link.click();\n document.body.removeChild(link);\n sAlert = 'Check your Downloads folder for ' + sFileName + '.';\n if (Web.isUserAgent(\"Chrome\")) {\n sAlert += '\\n\\nIn Chrome, after clicking OK, you may ALSO have to select the \"Window\" menu, choose \"Downloads\", and then locate this download and select \"Keep\".';\n sAlert += '\\n\\nThis is part of Chrome\\'s \"Security By Jumping Through Extra Hoops\" technology, which is much easier for Google to implement than actually checking for something malicious.';\n sAlert += '\\n\\nAnd for the record, there is nothing malicious on the PCjs website.';\n }\n } else {\n window.open(sURI);\n sAlert = 'Check your browser for a new window/tab containing the requested data' + (sFileName? (' (' + sFileName + ')') : '') + '.';\n }\n return sAlert;\n }\n\n /**\n * onCountRepeat(n, fnRepeat, fnComplete, msDelay)\n *\n * Call fnRepeat() n times with an msDelay millisecond delay between calls,\n * then call fnComplete() when n has been exhausted OR fnRepeat() returns false.\n *\n * @param {number} n\n * @param {function()} fnRepeat\n * @param {function()} fnComplete\n * @param {number} [msDelay]\n */\n static onCountRepeat(n, fnRepeat, fnComplete, msDelay)\n {\n var fnTimeout = function doCountRepeat()\n {\n n -= 1;\n if (n >= 0) {\n if (!fnRepeat()) n = 0;\n }\n if (n > 0) {\n setTimeout(fnTimeout, msDelay || 0);\n return;\n }\n fnComplete();\n };\n fnTimeout();\n }\n\n /**\n * onClickRepeat(e, msDelay, msRepeat, fn)\n *\n * Repeatedly call fn() with an initial msDelay, and an msRepeat delay thereafter,\n * as long as HTML control Object e has an active \"down\" event and fn() returns true.\n *\n * @param {Object} e\n * @param {number} msDelay\n * @param {number} msRepeat\n * @param {function(boolean)} fn is passed false on the first call, true on all repeated calls\n */\n static onClickRepeat(e, msDelay, msRepeat, fn)\n {\n var ms = 0, timer = null, fIgnoreMouseEvents = false;\n\n var fnRepeat = function doClickRepeat()\n {\n if (fn(ms === msRepeat)) {\n timer = setTimeout(fnRepeat, ms);\n ms = msRepeat;\n }\n };\n e.onmousedown = function()\n {\n // Web.log(\"onMouseDown()\");\n if (!fIgnoreMouseEvents) {\n if (!timer) {\n ms = msDelay;\n fnRepeat();\n }\n }\n };\n e.ontouchstart = function()\n {\n // Web.log(\"onTouchStart()\");\n if (!timer) {\n ms = msDelay;\n fnRepeat();\n }\n };\n e.onmouseup = e.onmouseout = function()\n {\n // Web.log(\"onMouseUp()/onMouseOut()\");\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n };\n e.ontouchend = e.ontouchcancel = function()\n {\n // Web.log(\"onTouchEnd()/onTouchCancel()\");\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n /*\n * Devices that generate ontouch* events ALSO generate onmouse* events,\n * and generally do so immediately after all the touch events are complete,\n * so unless we want double the action, we need to ignore mouse events.\n */\n fIgnoreMouseEvents = true;\n };\n }\n\n /**\n * onPageEvent(sName, fn)\n *\n * For 'onload', 'onunload', and 'onpageshow' events, most callers should NOT use this function, but\n * instead use Web.onInit(), Web.onShow(), and Web.onExit(), respectively.\n *\n * The only components that should still use onPageEvent() are THIS component (see the bottom of this file)\n * and components that need to capture other events (eg, the 'onresize' event in the Video component).\n *\n * This function creates a chain of callbacks, allowing multiple JavaScript modules to define handlers\n * for the same event, which wouldn't be possible if everyone modified window['onload'], window['onunload'],\n * etc, themselves. However, that's less of a concern now, because assuming everyone else is now using\n * onInit(), onExit(), etc, then there really IS only one component setting the window callback: this one.\n *\n * NOTE: It's risky to refer to obscure event handlers with \"dot\" names, because the Closure Compiler may\n * erroneously replace them (eg, window.onpageshow is a good example).\n *\n * @param {string} sFunc\n * @param {function()} fn\n */\n static onPageEvent(sFunc, fn)\n {\n if (window) {\n var fnPrev = window[sFunc];\n if (typeof fnPrev !== 'function') {\n window[sFunc] = fn;\n } else {\n /*\n * TODO: Determine whether there's any value in receiving/sending the Event object that the\n * browser provides when it generates the original event.\n */\n window[sFunc] = function onWindowEvent()\n {\n if (fnPrev) fnPrev();\n fn();\n };\n }\n }\n };\n\n /**\n * onInit(fn)\n *\n * Use this instead of setting window.onload. Allows multiple JavaScript modules to define their own 'onload' event handler.\n *\n * @param {function()} fn\n */\n static onInit(fn)\n {\n Web.aPageEventHandlers['init'].push(fn);\n };\n\n /**\n * onShow(fn)\n *\n * @param {function()} fn\n *\n * Use this instead of setting window.onpageshow. Allows multiple JavaScript modules to define their own 'onpageshow' event handler.\n */\n static onShow(fn)\n {\n Web.aPageEventHandlers['show'].push(fn);\n };\n\n /**\n * onExit(fn)\n *\n * @param {function()} fn\n *\n * Use this instead of setting window.onunload. Allows multiple JavaScript modules to define their own 'onunload' event handler.\n */\n static onExit(fn)\n {\n Web.aPageEventHandlers['exit'].push(fn);\n };\n\n /**\n * doPageEvent(afn)\n *\n * @param {Array.<function()>} afn\n */\n static doPageEvent(afn)\n {\n if (Web.fPageEventsEnabled) {\n try {\n for (var i = 0; i < afn.length; i++) {\n afn[i]();\n }\n } catch (e) {\n Web.notice(\"An unexpected error occurred: \" + e.message + \"\\n\\nIf it happens again, please send this information to support@pcjs.org. Thanks.\");\n }\n }\n };\n\n /**\n * enablePageEvents(fEnable)\n *\n * @param {boolean} fEnable is true to enable page events, false to disable (they're enabled by default)\n */\n static enablePageEvents(fEnable)\n {\n if (!Web.fPageEventsEnabled && fEnable) {\n Web.fPageEventsEnabled = true;\n if (Web.fPageLoaded) Web.sendPageEvent('init');\n if (Web.fPageShowed) Web.sendPageEvent('show');\n return;\n }\n Web.fPageEventsEnabled = fEnable;\n }\n\n /**\n * sendPageEvent(sEvent)\n *\n * This allows us to manually trigger page events.\n *\n * @param {string} sEvent (one of 'init', 'show' or 'exit')\n */\n static sendPageEvent(sEvent)\n {\n if (Web.aPageEventHandlers[sEvent]) {\n Web.doPageEvent(Web.aPageEventHandlers[sEvent]);\n }\n }\n}\n\nWeb.parmsURL = null; // initialized on first call to parseURLParms()\n\nWeb.aPageEventHandlers = {\n 'init': [], // list of window 'onload' handlers\n 'show': [], // list of window 'onpageshow' handlers\n 'exit': [] // list of window 'onunload' handlers (although we prefer to use 'onbeforeunload' if possible)\n};\n\nWeb.asBrowserPrefixes = ['', 'moz', 'ms', 'webkit'];\n\nWeb.fPageLoaded = false; // set once the page's first 'onload' event has occurred\nWeb.fPageShowed = false; // set once the page's first 'onpageshow' event has occurred\nWeb.fPageEventsEnabled = true; // default is true, set to false (or true) by enablePageEvents()\n\n/**\n * fLocalStorage\n *\n * true if localStorage support exists, is enabled, and works; \"falsey\" otherwise\n *\n * @type {boolean|null}\n */\nWeb.fLocalStorage = null;\n\n/**\n * TODO: Is there any way to get the Closure Compiler to stop inlining this string? This isn't cutting it.\n *\n * @const {string}\n */\nWeb.sLocalStorageTest = \"PCjs.localStorage\";\n\nWeb.onPageEvent('onload', function onPageLoad() {\n Web.fPageLoaded = true;\n Web.doPageEvent(Web.aPageEventHandlers['init']);\n});\n\nWeb.onPageEvent('onpageshow', function onPageShow() {\n Web.fPageShowed = true;\n Web.doPageEvent(Web.aPageEventHandlers['show']);\n});\n\nWeb.onPageEvent(Web.isUserAgent(\"iOS\")? 'onpagehide' : (Web.isUserAgent(\"Opera\")? 'onunload' : 'onbeforeunload'), function onPageUnload() {\n Web.doPageEvent(Web.aPageEventHandlers['exit']);\n});\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/component.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * All PCjs components now use JSDoc types, primarily so that Google's Closure Compiler will compile\n * everything with zero warnings when ADVANCED_OPTIMIZATIONS are enabled. For more information about\n * the JSDoc types supported by the Closure Compiler:\n *\n * https://developers.google.com/closure/compiler/docs/js-for-compiler#types\n *\n * I also attempted to validate this code with JSLint, but it complained too much; eg, it didn't like\n * \"while (true)\", a tried and \"true\" programming convention for decades, and it wanted me to replace\n * all \"++\" and \"--\" operators with \"+= 1\" and \"-= 1\", use \"(s || '')\" instead of \"(s? s : '')\", etc.\n *\n * I prefer sticking with traditional C-style idioms, in part because they are more portable. That\n * does NOT mean I'm trying to write \"portable JavaScript,\" but some of this code was ported from C code\n * I'd written long ago, so portability is good, and I'm not going to throw that away if there's no need.\n *\n * UPDATE: I've since switched from JSLint to JSHint, which seems to have more reasonable defaults.\n * And for new code, I have adopted some popular JavaScript idioms, like \"(s || '')\", although the need\n * for those kinds of expressions will be reduced as I also start adopting some ES6 features, like\n * default parameters.\n */\n\n\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * subclass (eg, SerialPort), because otherwise the Compiler won't allow us to *reference*\n * the named property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass Component {\n /**\n * Component(type, parms, bitsMessage)\n *\n * A Component object requires:\n *\n * type: a user-defined type name (eg, \"CPU\")\n *\n * and accepts any or all of the following (parms) properties:\n *\n * id: component ID (default is \"\")\n * name: component name (default is \"\"; if blank, toString() will use the type name only)\n * comment: component comment string (default is undefined)\n *\n * Component subclasses will usually have additional (parms) properties.\n *\n * @param {string} type\n * @param {Object} [parms]\n * @param {number} [bitsMessage] selects message(s) that the component wants to enable (default is 0)\n */\n constructor(type, parms, bitsMessage)\n {\n this.type = type;\n\n if (!parms) parms = {'id': \"\", 'name': \"\"};\n\n this.id = parms['id'] || \"\";\n this.name = parms['name'];\n this.comment = parms['comment'];\n this.parms = parms;\n\n /*\n * The following Component properties need to be accessible by other machines and/or command scripts;\n * well, OK, or we could have exported some new functions to walk the contents of these properties, as we\n * did with findMachineComponent(), but this works just as well.\n *\n * Also, while the double-assignment looks silly (ie, using both dot and bracket property notation), it\n * resolves a complaint from the Closure Compiler, because if we use ONLY bracket notation here, then the\n * Compiler wants us to change all the other references to bracket notation as well.\n */\n this.exports = this['exports'] = {};\n this.bindings = this['bindings'] = {};\n\n var i = this.id.indexOf('.');\n if (i < 0) {\n this.idComponent = this.id;\n } else {\n this.idMachine = this.id.substr(0, i);\n this.idComponent = this.id.substr(i + 1);\n }\n\n /*\n * Gather all the various component flags (booleans) into a single \"flags\" object, and encourage\n * subclasses to do the same, to reduce the property clutter we have to wade through while debugging.\n */\n this.flags = {\n ready: false,\n busy: false,\n busyCancel: false,\n initDone: false,\n powered: false,\n unloading: false,\n error: false\n };\n\n this.fnReady = null;\n this.clearError();\n this.bitsMessage = bitsMessage || 0;\n\n this.cmp = null;\n this.bus = null;\n this.cpu = null;\n this.dbg = null;\n\n /*\n * TODO: Consider adding another parameter to the Component() constructor that allows components to tell\n * us if they support single or multiple instances per machine. For example, there can be multiple SerialPort\n * components per machine, but only one CPU component (some machines also support an FPU, but that component\n * is considered separate from the CPU).\n *\n * It's not critical, but it would help catch machine configuration errors; for example, a machine that mistakenly\n * includes two CPU components may, aside from wasting memory, end up with odd side-effects, like unresponsive\n * CPU controls.\n */\n Component.add(this);\n }\n\n /**\n * Component.add(component)\n *\n * @param {Component} component\n */\n static add(component)\n {\n /*\n * This just generates a lot of useless noise, handy in the early days, not so much these days....\n *\n * if (DEBUG) Component.log(\"Component.add(\" + component.type + \",\" + component.id + \")\");\n */\n Component.components.push(component);\n }\n\n /**\n * Component.addMachine(idMachine)\n *\n * @param {string} idMachine\n */\n static addMachine(idMachine)\n {\n Component.machines[idMachine] = {};\n }\n\n /**\n * Component.addMachineResource(idMachine, sName, data)\n *\n * @param {string} idMachine\n * @param {string|null} sName (name of the resource)\n * @param {*} data\n */\n static addMachineResource(idMachine, sName, data)\n {\n /*\n * I used to assert(Component.machines[idMachine]), but when we're running as a Node app, embed.js is not used,\n * so addMachine() is never called, so resources do not need to be recorded.\n */\n if (Component.machines[idMachine] && sName) {\n Component.machines[idMachine][sName] = data;\n }\n }\n\n /**\n * Component.getMachineResources(idMachine)\n *\n * @param {string} idMachine\n * @return {Object|undefined}\n */\n static getMachineResources(idMachine)\n {\n return Component.machines[idMachine];\n }\n\n /**\n * Component.getTime()\n *\n * @return {number} the current time, in milliseconds\n */\n static getTime()\n {\n return Date.now() || +new Date();\n }\n\n /**\n * Component.log(s, type)\n *\n * For diagnostic output only.\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n static log(s, type)\n {\n if (!COMPILED) {\n if (s) {\n var sElapsed = \"\", sMsg = (type? (type + \": \") : \"\") + s;\n if (typeof Usr != \"undefined\") {\n if (Component.msStart === undefined) {\n Component.msStart = Component.getTime();\n }\n sElapsed = (Component.getTime() - Component.msStart) + \"ms: \";\n }\n sMsg = sMsg.replace(/\\r/g, '\\\\r').replace(/\\n/g, ' ');\n if (window && window.console) console.log(sElapsed + sMsg);\n }\n }\n }\n\n /**\n * Component.assert(f, s)\n *\n * Verifies conditions that must be true (for DEBUG builds only).\n *\n * The Closure Compiler should automatically remove all references to Component.assert() in non-DEBUG builds.\n * TODO: Add a task to the build process that \"asserts\" there are no instances of \"assertion failure\" in RELEASE builds.\n *\n * @param {boolean} f is the expression we are asserting to be true\n * @param {string} [s] is description of the assertion on failure\n */\n static assert(f, s)\n {\n if (DEBUG) {\n if (!f) {\n if (!s) s = \"assertion failure\";\n Component.log(s);\n throw new Error(s);\n }\n }\n }\n\n /**\n * Component.print(s)\n *\n * Components that inherit from this class should use this.print(), rather than Component.print(), because\n * if a Control Panel is loaded, it will override only the instance method, not the class method (overriding the\n * class method would improperly affect any other machines loaded on the same page).\n *\n * @this {Component}\n * @param {string} s\n */\n static print(s)\n {\n if (!COMPILED) {\n var i = s.lastIndexOf('\\n');\n if (i >= 0) {\n Component.println(s.substr(0, i));\n s = s.substr(i + 1);\n }\n Component.printBuffer += s;\n }\n }\n\n /**\n * Component.println(s, type, id)\n *\n * Components that inherit from this class should use this.println(), rather than Component.println(), because\n * if a Control Panel is loaded, it will override only the instance method, not the class method (overriding the\n * class method would improperly affect any other machines loaded on the same page).\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n * @param {string} [id] is the caller's ID, if any\n */\n static println(s, type, id)\n {\n if (!COMPILED) {\n s = Component.printBuffer + (s || \"\");\n Component.log((id? (id + \": \") : \"\") + (s? (\"\\\"\" + s + \"\\\"\") : \"\"), type);\n Component.printBuffer = \"\";\n }\n }\n\n /**\n * Component.notice(s, fPrintOnly, id)\n *\n * notice() is like println() but implies a need for user notification, so we alert() as well.\n *\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n * @return {boolean}\n */\n static notice(s, fPrintOnly, id)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.NOTICE, id);\n }\n if (!fPrintOnly) Component.alertUser((id? (id + \": \") : \"\") + s);\n return true;\n }\n\n /**\n * Component.warning(s)\n *\n * @param {string} s describes the warning\n */\n static warning(s)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.WARNING);\n }\n Component.alertUser(s);\n }\n\n /**\n * Component.error(s)\n *\n * @param {string} s describes the error; an alert() is displayed as well\n */\n static error(s)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.ERROR);\n }\n Component.alertUser(s);\n }\n\n /**\n * Component.alertUser(sMessage)\n *\n * @param {string} sMessage\n */\n static alertUser(sMessage)\n {\n if (window) {\n window.alert(sMessage);\n } else {\n Component.log(sMessage);\n }\n }\n\n /**\n * Component.confirmUser(sPrompt)\n *\n * @param {string} sPrompt\n * @returns {boolean} true if the user clicked OK, false if Cancel/Close\n */\n static confirmUser(sPrompt)\n {\n var fResponse = false;\n if (window) {\n fResponse = window.confirm(sPrompt);\n }\n return fResponse;\n }\n\n /**\n * Component.promptUser()\n *\n * @param {string} sPrompt\n * @param {string} [sDefault]\n * @returns {string|null}\n */\n static promptUser(sPrompt, sDefault)\n {\n var sResponse = null;\n if (window) {\n sResponse = window.prompt(sPrompt, sDefault === undefined? \"\" : sDefault);\n }\n return sResponse;\n }\n\n /**\n * Component.appendControl(control, sText)\n *\n * @param {Object} control\n * @param {string} sText\n */\n static appendControl(control, sText)\n {\n control.value += sText;\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (COMPILED) {\n sText = control.value;\n if (sText.length > 8192) control.value = sText.substr(sText.length - 4096);\n }\n control.scrollTop = control.scrollHeight;\n }\n\n /**\n * Component.replaceControl(control, sSearch, sReplace)\n *\n * @param {Object} control\n * @param {string} sSearch\n * @param {string} sReplace\n */\n static replaceControl(control, sSearch, sReplace)\n {\n var sText = control.value;\n var i = sText.lastIndexOf(sSearch);\n if (i < 0) {\n sText += sSearch + '\\n';\n } else {\n sText = sText.substr(0, i) + sReplace + sText.substr(i + sSearch.length);\n }\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (COMPILED && sText.length > 8192) sText = sText.substr(sText.length - 4096);\n control.value = sText;\n control.scrollTop = control.scrollHeight;\n }\n\n /**\n * Component.bindExternalControl(component, sBinding, sType)\n *\n * @param {Component} component\n * @param {string} sBinding\n * @param {string} [sType] is the external component type (default is \"Panel\")\n */\n static bindExternalControl(component, sBinding, sType = \"Panel\")\n {\n if (sBinding) {\n var target = Component.getComponentByType(sType, component.id);\n if (target) {\n var control = target.bindings[sBinding];\n if (control) {\n component.setBinding(null, sBinding, control);\n }\n }\n }\n }\n\n /**\n * Component.bindComponentControls(component, element, sAppClass)\n *\n * @param {Component} component\n * @param {HTMLElement} element from the DOM\n * @param {string} sAppClass\n */\n static bindComponentControls(component, element, sAppClass)\n {\n var aeControls = Component.getElementsByClass(element.parentNode, sAppClass + \"-control\");\n\n for (var iControl = 0; iControl < aeControls.length; iControl++) {\n\n var aeChildNodes = aeControls[iControl].childNodes;\n\n for (var iNode = 0; iNode < aeChildNodes.length; iNode++) {\n var control = aeChildNodes[iNode];\n if (control.nodeType !== 1 /* document.ELEMENT_NODE */) {\n continue;\n }\n var sClass = control.getAttribute(\"class\");\n if (!sClass) continue;\n var aClasses = sClass.split(\" \");\n for (var iClass = 0; iClass < aClasses.length; iClass++) {\n var parms;\n sClass = aClasses[iClass];\n switch (sClass) {\n case sAppClass + \"-binding\":\n parms = Component.getComponentParms(/** @type {HTMLElement} */(control));\n if (parms && parms['binding'] !== undefined) {\n component.setBinding(parms['type'], parms['binding'], /** @type {HTMLElement} */(control), parms['value']);\n } else if (!parms || parms['type'] != \"description\") {\n Component.log(\"Component '\" + component.toString() + \"' missing binding\" + (parms? \" for \" + parms['type'] : \"\"), \"warning\");\n }\n iClass = aClasses.length;\n break;\n default:\n // if (DEBUG) Component.log(\"Component.bindComponentControls(\" + component.toString() + \"): unrecognized control class \\\"\" + sClass + \"\\\"\", \"warning\");\n break;\n }\n }\n }\n }\n }\n\n /**\n * Component.getComponents(idRelated)\n *\n * We could store components as properties, using the component's ID, and change\n * this linear lookup into a property lookup, but some components may have no ID.\n *\n * @param {string} [idRelated] of related component\n * @return {Array} of components\n */\n static getComponents(idRelated)\n {\n var i;\n var aComponents = [];\n /*\n * getComponentByID(id, idRelated)\n *\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated) {\n if ((i = idRelated.indexOf('.')) > 0)\n idRelated = idRelated.substr(0, i + 1);\n else\n idRelated = \"\";\n }\n for (i = 0; i < Component.components.length; i++) {\n var component = Component.components[i];\n if (!idRelated || !component.id.indexOf(idRelated)) {\n aComponents.push(component);\n }\n }\n return aComponents;\n }\n\n /**\n * Component.getComponentByID(id, idRelated)\n *\n * We could store components as properties, using the component's ID, and change\n * this linear lookup into a property lookup, but some components may have no ID.\n *\n * @param {string} id of the desired component\n * @param {string} [idRelated] of related component\n * @return {Component|null}\n */\n static getComponentByID(id, idRelated)\n {\n if (id !== undefined) {\n var i;\n /*\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated && (i = idRelated.indexOf('.')) > 0) {\n id = idRelated.substr(0, i + 1) + id;\n }\n for (i = 0; i < Component.components.length; i++) {\n if (Component.components[i].id === id) {\n return Component.components[i];\n }\n }\n if (Component.components.length) {\n Component.log(\"Component ID '\" + id + \"' not found\", \"warning\");\n }\n }\n return null;\n }\n\n /**\n * Component.getComponentByType(sType, idRelated, componentPrev)\n *\n * @param {string} sType of the desired component\n * @param {string} [idRelated] of related component\n * @param {Component|null} [componentPrev] of previously returned component, if any\n * @return {Component|null}\n */\n static getComponentByType(sType, idRelated, componentPrev)\n {\n if (sType !== undefined) {\n var i;\n /*\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated) {\n if ((i = idRelated.indexOf('.')) > 0) {\n idRelated = idRelated.substr(0, i + 1);\n } else {\n idRelated = \"\";\n }\n }\n for (i = 0; i < Component.components.length; i++) {\n if (componentPrev) {\n if (componentPrev == Component.components[i]) componentPrev = null;\n continue;\n }\n if (sType == Component.components[i].type && (!idRelated || !Component.components[i].id.indexOf(idRelated))) {\n return Component.components[i];\n }\n }\n Component.log(\"Component type '\" + sType + \"' not found\", \"warning\");\n }\n return null;\n }\n\n /**\n * Component.getComponentParms(element)\n *\n * @param {HTMLElement} element from the DOM\n */\n static getComponentParms(element)\n {\n var parms = null;\n var sParms = element.getAttribute(\"data-value\");\n if (sParms) {\n try {\n parms = eval('(' + sParms + ')'); // jshint ignore:line\n /*\n * We can no longer invoke removeAttribute() because some components (eg, Panel) need\n * to run their initXXX() code more than once, to avoid initialization-order dependencies.\n *\n * if (!DEBUG) {\n * element.removeAttribute(\"data-value\");\n * }\n */\n } catch(e) {\n Component.error(e.message + \" (\" + sParms + \")\");\n }\n }\n return parms;\n }\n\n /**\n * Component.getElementsByClass(element, sClass, sObjClass)\n *\n * This is a cross-browser helper function, since not all browser's support getElementsByClassName()\n *\n * TODO: This should probably be moved into weblib.js at some point, along with the control binding functions above,\n * to keep all the browser-related code together.\n *\n * @param {HTMLDocument|HTMLElement|Node} element from the DOM\n * @param {string} sClass\n * @param {string} [sObjClass]\n * @return {Array|NodeList}\n */\n static getElementsByClass(element, sClass, sObjClass)\n {\n if (sObjClass) sClass += '-' + sObjClass + \"-object\";\n /*\n * Use the browser's built-in getElementsByClassName() if it appears to be available\n * (for example, it's not available in IE8, but it should be available in IE9 and up)\n */\n if (element.getElementsByClassName) {\n return element.getElementsByClassName(sClass);\n }\n var i, j, ae = [];\n var aeAll = element.getElementsByTagName(\"*\");\n var re = new RegExp('(^| )' + sClass + '( |$)');\n for (i = 0, j = aeAll.length; i < j; i++) {\n if (re.test(aeAll[i].className)) {\n ae.push(aeAll[i]);\n }\n }\n if (!ae.length) {\n Component.log('No elements of class \"' + sClass + '\" found');\n }\n return ae;\n }\n\n /**\n * Component.getScriptCommands(sScript)\n *\n * This is a simple parser that breaks sScript into an array of commands, where each command\n * is an array of tokens, where tokens are sequences of characters separated by any of: tab, space,\n * carriage-return (CR), line-feed (LF), semicolon, single-quote, or double-quote; if a quote is\n * used, all characters up to the next matching quote become part of the token, allowing any of the\n * other separators to be part of the token. CR, LF and semicolon also serve to terminate a command,\n * with semicolon being preferred, because it's 1) more visible, and 2) essential when the entire\n * script is a multi-line string where all CR/LF were replaced by spaces (which is what Jekyll does,\n * and since we can't change Jekyll, it's what our own MarkDown Front Matter parser does as well;\n * see convertMD() in markout.js, where the aCommandDefs array is built).\n *\n * Backslash sequences like \\n, \\r, and \\\\ have already been converted to LF, CR and backslash\n * characters, since the entire script string is injected into a JavaScript function call, so any\n * backslash sequence that JavaScript supports is automatically converted:\n *\n * \\0 \\' \\\" \\\\ \\n \\r \\v \\t \\b \\f \\uXXXX \\xXX\n * ^J ^M ^K ^I ^H ^L\n *\n * To support any other non-printable 8-bit character, such as ESC, you should use \\xXX, where XX\n * is the ASCII code in hex. For ESC, that would be \\x1B.\n *\n * @param {string} sScript\n * @return {Array}\n */\n static getScriptCommands(sScript)\n {\n var cch = sScript.length;\n var aCommands = [], aTokens = [], sToken = \"\", chQuote = null;\n for (var i = 0; i < cch; i++) {\n var ch = sScript[i];\n if (ch == '\"' || ch == \"'\") {\n if (chQuote && ch != chQuote) {\n sToken += ch;\n continue;\n }\n if (!chQuote) {\n chQuote = ch;\n } else {\n chQuote = null;\n }\n if (sToken) {\n aTokens.push(sToken);\n sToken = \"\";\n }\n continue;\n }\n if (!chQuote) {\n if (ch == '\\r' || ch == '\\n') {\n ch = ';';\n }\n if (ch == ' ' || ch == '\\t' || ch == ';') {\n if (sToken) {\n aTokens.push(sToken);\n sToken = \"\";\n }\n if (ch == ';' && aTokens.length) {\n aCommands.push(aTokens);\n aTokens = [];\n }\n continue;\n }\n }\n sToken += ch;\n }\n if (sToken) {\n aTokens.push(sToken);\n }\n if (aTokens.length) {\n aCommands.push(aTokens);\n }\n return aCommands;\n }\n\n /**\n * Component.processScript(idMachine, sScript)\n *\n * @param {string} idMachine\n * @param {string} [sScript]\n * @return {boolean}\n */\n static processScript(idMachine, sScript)\n {\n var fSuccess = false;\n idMachine += \".machine\";\n if (!sScript) {\n delete Component.commands[idMachine];\n fSuccess = true;\n }\n else if (typeof sScript == \"string\" && !Component.commands[idMachine]) {\n fSuccess = true;\n Component.commands[idMachine] = Component.getScriptCommands(sScript);\n if (!Component.processCommands(idMachine)) {\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * Component.processCommands(idMachine)\n *\n * @param {string} idMachine\n * @return {boolean}\n */\n static processCommands(idMachine)\n {\n var fSuccess = true;\n var aCommands = Component.commands[idMachine];\n\n // var dbg = Component.getComponentByType(\"Debugger\", idMachine);\n\n while (aCommands && aCommands.length) {\n\n var aTokens = aCommands.splice(0, 1)[0];\n var sCommand = aTokens[0];\n\n /*\n * It's possible to route this output to the Debugger window with dbg.println()\n * instead, but it's a bit too confusing mingling script output in a window that\n * already mingles Debugger and machine output.\n */\n Component.println(aTokens.join(' '), Component.PRINT.SCRIPT);\n\n var fnCallReady = null;\n if (Component.asyncCommands.indexOf(sCommand) >= 0) {\n fnCallReady = function processNextCommand() {\n return function() {\n Component.processCommands(idMachine);\n }\n }();\n }\n\n var fnCommand = Component.globalCommands[sCommand];\n if (fnCommand) {\n if (!fnCallReady) {\n fSuccess = fnCommand(aTokens[1], aTokens[2], aTokens[3]);\n } else {\n if (!fnCommand(fnCallReady, aTokens[1], aTokens[2], aTokens[3])) break;\n }\n }\n else {\n fSuccess = false;\n var component = Component.getComponentByType(aTokens[1], idMachine);\n if (component) {\n fnCommand = Component.componentCommands[sCommand];\n if (fnCommand) {\n fSuccess = fnCommand(component, aTokens[2], aTokens[3]);\n }\n else {\n var exports = component['exports'];\n if (exports) {\n fnCommand = exports[sCommand];\n if (fnCommand) {\n fSuccess = true;\n if (!fnCallReady) {\n fSuccess = fnCommand.call(component, aTokens[2], aTokens[3]);\n } else {\n if (!fnCommand.call(component, fnCallReady, aTokens[2], aTokens[3])) break;\n }\n }\n }\n }\n }\n }\n\n if (!fSuccess) {\n Component.alertUser(\"Script error: '\" + sCommand + \"' command \" + (fnCommand? \" failed\" : \" not recognized\"));\n break;\n }\n }\n\n if (aCommands && !aCommands.length) {\n delete Component.commands[idMachine];\n }\n\n return fSuccess;\n }\n\n /**\n * Component.scriptAlert(sMessage)\n *\n * @param {string} sMessage\n * @return {boolean}\n */\n static scriptAlert(sMessage)\n {\n Component.alertUser(sMessage);\n return true;\n }\n\n /**\n * Component.scriptSelect(component, sBinding, sValue)\n *\n * @param {Component} component\n * @param {string} sBinding\n * @param {string} sValue\n * @return {boolean}\n */\n static scriptSelect(component, sBinding, sValue)\n {\n var fSuccess = false;\n var aBindings = component['bindings'];\n var control = aBindings[sBinding];\n if (control) {\n for (var i = 0; i < control.options.length; i++) {\n if (control.options[i].textContent == sValue) {\n if (control.selectedIndex != i) {\n control.selectedIndex = i;\n }\n fSuccess = true;\n break;\n }\n }\n }\n return fSuccess;\n }\n\n /**\n * Component.scriptSleep(fnCallback, sDelay)\n *\n * @param {function()} fnCallback\n * @param {string} sDelay (in milliseconds)\n * @return {boolean}\n */\n static scriptSleep(fnCallback, sDelay)\n {\n setTimeout(fnCallback, +sDelay);\n return false;\n }\n\n /**\n * toString()\n *\n * @this {Component}\n * @return {string}\n */\n toString()\n {\n return (this.name? this.name : (this.id || this.type));\n }\n\n /**\n * getMachineNum()\n *\n * @this {Component}\n * @return {number} unique machine number\n */\n getMachineNum()\n {\n var nMachine = 1;\n if (this.idMachine) {\n var aDigits = this.idMachine.match(/\\d+/);\n if (aDigits !== null)\n nMachine = parseInt(aDigits[0], 10);\n }\n return nMachine;\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * Component's setBinding() method is intended to be overridden by subclasses.\n *\n * @this {Component}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, 'print')\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n switch (sBinding) {\n case 'clear':\n if (!this.bindings[sBinding]) {\n this.bindings[sBinding] = control;\n control.onclick = (function(component) {\n return function clearControl() {\n if (component.bindings['print']) {\n component.bindings['print'].value = \"\";\n }\n };\n }(this));\n }\n return true;\n case 'print':\n if (!this.bindings[sBinding]) {\n var controlTextArea = /** @type {HTMLTextAreaElement} */(control);\n this.bindings[sBinding] = controlTextArea;\n /**\n * Override this.notice() with a replacement function that eliminates the Component.alertUser() call.\n *\n * @this {Component}\n * @param {string} s\n * @return {boolean}\n */\n this.notice = function noticeControl(s /*, fPrintOnly, id*/) {\n this.println(s, this.type);\n return true;\n };\n /*\n * This was added for Firefox (Safari will clear the <textarea> on a page reload, but Firefox does not).\n */\n controlTextArea.value = \"\";\n this.print = function(control) {\n return function printControl(s) {\n Component.appendControl(control, s);\n };\n }(controlTextArea);\n this.println = function(component, control) {\n return function printlnControl(s, type, id) {\n if (!s) s = \"\";\n if (type != Component.PRINT.PROGRESS || s.slice(-3) != \"...\") {\n if (type) s = type + \": \" + s;\n Component.appendControl(control, s + '\\n');\n } else {\n Component.replaceControl(control, s, s + '.');\n }\n if (!COMPILED && window && window.console) Component.println(s, type, id);\n };\n }(this, controlTextArea);\n }\n return true;\n default:\n return false;\n }\n }\n\n /**\n * log(s, type)\n *\n * For diagnostic output only.\n *\n * WARNING: Even though this function's body is completely wrapped in DEBUG, that won't prevent the Closure Compiler\n * from including it, so all calls must still be prefixed with \"if (DEBUG) ....\". For this reason, the class method,\n * Component.log(), is preferred, because the compiler IS smart enough to remove those calls.\n *\n * @this {Component}\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n log(s, type)\n {\n if (!COMPILED) {\n Component.log(s, type || this.id || this.type);\n }\n }\n\n /**\n * assert(f, s)\n *\n * Verifies conditions that must be true (for DEBUG builds only).\n *\n * WARNING: Make sure you preface all calls to this.assert() with \"if (DEBUG)\", because unlike Component.assert(),\n * the Closure Compiler can't be sure that this instance method hasn't been overridden, so it refuses to treat it as\n * dead code in non-DEBUG builds.\n *\n * TODO: Add a task to the build process that \"asserts\" there are no instances of \"assertion failure\" in RELEASE builds.\n *\n * @this {Component}\n * @param {boolean|number} f is the expression asserted to be true\n * @param {string} [s] is a description of the assertion to be displayed or logged on failure\n */\n assert(f, s)\n {\n if (DEBUG) {\n if (!f) {\n s = \"assertion failure in \" + (this.id || this.type) + (s? \": \" + s : \"\");\n if (DEBUGGER && this.dbg) {\n this.dbg.stopCPU();\n /*\n * Why do we throw an Error only to immediately catch and ignore it? Simply to give\n * any IDE the opportunity to inspect the application's state. Even when the IDE has\n * control, you should still be able to invoke Debugger commands from the IDE's REPL,\n * using the global function that the Debugger constructor defines; eg:\n *\n * pcx86('r')\n * pcx86('dw 0:0')\n * pcx86('h')\n * ...\n *\n * If you have no desire to stop on assertions, consider this a no-op. However, another\n * potential benefit of creating an Error object is that, for browsers like Chrome, we get\n * a stack trace, too.\n */\n try {\n throw new Error(s);\n } catch(e) {\n this.println(e.stack || e.message);\n }\n return;\n }\n this.log(s);\n throw new Error(s);\n }\n }\n }\n\n /**\n * print(s)\n *\n * Components using this.print() should wait until after their constructor has run to display any messages, because\n * if a Control Panel has been loaded, its override will not take effect until its own constructor has run.\n *\n * @this {Component}\n * @param {string} s\n */\n print(s)\n {\n Component.print(s);\n }\n\n /**\n * println(s, type, id)\n *\n * Components using this.println() should wait until after their constructor has run to display any messages, because\n * if a Control Panel has been loaded, its override will not take effect until its own constructor has run.\n *\n * @this {Component}\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n * @param {string} [id] is the caller's ID, if any\n */\n println(s, type, id)\n {\n Component.println(s, type, id || this.id);\n }\n\n /**\n * status(s)\n *\n * status() is like println() but it also includes information about the component (ie, the component type),\n * which is why there is no corresponding Component.status() function.\n *\n * @this {Component}\n * @param {string} s is the message text\n */\n status(s)\n {\n this.println(this.type + \": \" + s);\n }\n\n /**\n * notice(s, fPrintOnly, id)\n *\n * notice() is like println() but implies a need for user notification, so we alert() as well; however, if this.println()\n * is overridden, this.notice will be replaced with a similar override, on the assumption that the override is taking care\n * of alerting the user.\n *\n * @this {Component}\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n * @return {boolean}\n */\n notice(s, fPrintOnly, id)\n {\n if (!fPrintOnly) {\n /*\n * See if the associated computer, if any, is \"unloading\"....\n */\n var computer = Component.getComponentByType(\"Computer\", this.id);\n if (computer && computer.flags.unloading) {\n console.log(\"ignoring notice during unload: \" + s);\n return false;\n }\n }\n Component.notice(s, fPrintOnly, id || this.type);\n return true;\n }\n\n /**\n * setError(s)\n *\n * Set a fatal error condition\n *\n * @this {Component}\n * @param {string} s describes a fatal error condition\n */\n setError(s)\n {\n this.flags.error = true;\n this.notice(s); // TODO: Any cases where we should still prefix this string with \"Fatal error: \"?\n }\n\n /**\n * clearError()\n *\n * Clear any fatal error condition\n *\n * @this {Component}\n */\n clearError() {\n this.flags.error = false;\n }\n\n /**\n * isError()\n *\n * Report any fatal error condition\n *\n * @this {Component}\n * @return {boolean} true if a fatal error condition exists, false if not\n */\n isError()\n {\n if (this.flags.error) {\n this.println(this.toString() + \" error\");\n return true;\n }\n return false;\n }\n\n /**\n * isReady(fnReady)\n *\n * Return the \"ready\" state of the component; if the component is not ready, it will queue the optional\n * notification function, otherwise it will immediately call the notification function, if any, without queuing it.\n *\n * NOTE: Since only the Computer component actually cares about the \"readiness\" of other components, the so-called\n * \"queue\" of notification functions supports exactly one function. This keeps things nice and simple.\n *\n * @this {Component}\n * @param {function()} [fnReady]\n * @return {boolean} true if the component is in a \"ready\" state, false if not\n */\n isReady(fnReady)\n {\n if (fnReady) {\n if (this.flags.ready) {\n fnReady();\n } else {\n if (MAXDEBUG) this.log(\"NOT ready\");\n this.fnReady = fnReady;\n }\n }\n return this.flags.ready;\n }\n\n /**\n * setReady(fReady)\n *\n * Set the \"ready\" state of the component to true, and call any queued notification functions.\n *\n * @this {Component}\n * @param {boolean} [fReady] is assumed to indicate \"ready\" unless EXPLICITLY set to false\n */\n setReady(fReady)\n {\n if (!this.flags.error) {\n this.flags.ready = (fReady !== false);\n if (this.flags.ready) {\n if (MAXDEBUG /* || this.name */) this.log(\"ready\");\n var fnReady = this.fnReady;\n this.fnReady = null;\n if (fnReady) fnReady();\n }\n }\n }\n\n /**\n * isBusy(fCancel)\n *\n * Return the \"busy\" state of the component\n *\n * @this {Component}\n * @param {boolean} [fCancel] is set to true to cancel a \"busy\" state\n * @return {boolean} true if \"busy\", false if not\n */\n isBusy(fCancel)\n {\n if (this.flags.busy) {\n if (fCancel) {\n this.flags.busyCancel = true;\n } else if (fCancel === undefined) {\n this.println(this.toString() + \" busy\");\n }\n }\n return this.flags.busy;\n }\n\n /**\n * setBusy(fBusy)\n *\n * Update the current busy state; if a busyCancel request is pending, it will be honored now.\n *\n * @this {Component}\n * @param {boolean} fBusy\n * @return {boolean}\n */\n setBusy(fBusy)\n {\n if (this.flags.busyCancel) {\n this.flags.busy = false;\n this.flags.busyCancel = false;\n return false;\n }\n if (this.flags.error) {\n this.println(this.toString() + \" error\");\n return false;\n }\n this.flags.busy = fBusy;\n return this.flags.busy;\n }\n\n /**\n * powerUp(fSave)\n *\n * @this {Component}\n * @param {Object|null} data\n * @param {boolean} [fRepower] is true if this is \"repower\" notification\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n this.flags.powered = true;\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Component}\n * @param {boolean} fSave\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n if (fShutdown) this.flags.powered = false;\n return true;\n }\n\n /**\n * messageEnabled(bitsMessage)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n *\n * @this {Component}\n * @param {number} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n * @return {boolean} true if all specified message enabled, false if not\n */\n messageEnabled(bitsMessage = 0)\n {\n if (DEBUGGER && this.dbg) {\n if (this !== this.dbg) {\n bitsMessage = bitsMessage || this.bitsMessage;\n }\n var bitsEnabled = this.dbg.bitsMessage & bitsMessage;\n /*\n * This next \"bit\" of logic is for PCx86 and any other machine where we've expanded the set of\n * messages by reusing bits in the low nibbles in combination with different bits in the high nibble.\n * If the input bits adhere to that format, then the mask we just produced must adhere to it as well,\n * and if it doesn't, zero the mask, ensuring that the test will return false.\n */\n if ((bitsMessage & 0xf0000000) && (bitsMessage & 0x0fffffff)) {\n if (!(bitsEnabled & 0xf0000000) || !(bitsEnabled & 0x0fffffff)) bitsEnabled = 0;\n }\n if (bitsMessage && bitsEnabled === bitsMessage) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * printf(format, ...args)\n *\n * @this {Component}\n * @param {string} format\n * @param {...} args\n */\n printf(format, ...args)\n {\n if (DEBUGGER && this.dbg) {\n if (this.messageEnabled()) {\n let s = Str.sprintf(format, ...args);\n /*\n * Since dbg.message() calls println(), we strip any ending linefeed.\n * \n * We could bypass the Debugger and go straight to this.print(), but we would lose\n * the benefits of debugger messages (eg, automatic buffering, halting, yielding, etc).\n */\n if (s.slice(-1) == '\\n') s = s.slice(0, -1);\n this.dbg.message(s);\n }\n }\n }\n\n /**\n * printMessage(sMessage, bitsMessage, fAddress)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n * If bitsMessage is true, the message is displayed regardless.\n *\n * @this {Component}\n * @param {string} sMessage is any caller-defined message string\n * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n * @param {boolean} [fAddress] is true to display the current address\n */\n printMessage(sMessage, bitsMessage, fAddress)\n {\n if (DEBUGGER && this.dbg) {\n if (bitsMessage === true || this.messageEnabled(bitsMessage | 0)) {\n this.dbg.message(sMessage, fAddress);\n }\n }\n }\n\n /**\n * printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n * If bitsMessage is true, the message is displayed as long as MESSAGE.PORT is enabled.\n *\n * @this {Component}\n * @param {number} port\n * @param {number|null} bOut if an output operation\n * @param {number|null} [addrFrom]\n * @param {string|null} [name] of the port, if any\n * @param {number|null} [bIn] is the input value, if known, on an input operation\n * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n */\n printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage)\n {\n if (DEBUGGER && this.dbg) {\n if (bitsMessage === true) {\n bitsMessage = 0;\n } else if (bitsMessage == null) {\n bitsMessage = this.bitsMessage;\n }\n this.dbg.messageIO(this, port, bOut, addrFrom, name, bIn, bitsMessage);\n }\n }\n}\n\n/*\n * Types recognized and supported by selected functions (eg, Computer.getMachineParm())\n */\nComponent.TYPE = {\n NUMBER: \"number\",\n OBJECT: \"object\",\n STRING: \"string\"\n};\n\n/*\n * These are the standard PRINT values you can pass as an optional argument to println(); in reality,\n * you can pass anything you want, because they are simply prepended to the message, although PROGRESS\n * messages may also be merged with earlier similar messages to keep the output buffer under control.\n */\nComponent.PRINT = {\n ERROR: \"error\",\n NOTICE: \"notice\",\n PROGRESS: \"progress\",\n SCRIPT: \"script\",\n WARNING: \"warning\"\n};\n\n/*\n * Every component created on the current page is recorded in this array (see Component.add()),\n * enabling any component to locate another component by ID (see Component.getComponentByID())\n * or by type (see Component.getComponentByType()).\n *\n * Every machine on the page are now recorded as well, by their machine ID. We then record the\n * various resources used by that machine.\n *\n * Includes a fallback for non-browser-based environments (ie, Node). TODO: This will need to be\n * tailored to Node, probably using the global object instead of the window object, if we ever want\n * to support multi-machine configs in that environment.\n */\nif (window) {\n if (!window['PCjs']) window['PCjs'] = {};\n if (!window['PCjs']['Machines']) window['PCjs']['Machines'] = {};\n if (!window['PCjs']['Components']) window['PCjs']['Components'] = [];\n if (!window['PCjs']['Commands']) window['PCjs']['Commands'] = {};\n}\nComponent.machines = window? window['PCjs']['Machines'] : {};\nComponent.components = window? window['PCjs']['Components'] : [];\nComponent.commands = window? window['PCjs']['Commands'] : {};\n\nComponent.asyncCommands = [\n 'hold', 'sleep', 'wait'\n];\nComponent.globalCommands = {\n 'alert': Component.scriptAlert,\n 'sleep': Component.scriptSleep\n};\nComponent.componentCommands = {\n 'select': Component.scriptSelect\n};\nComponent.printBuffer = \"\";\n\n/*\n * The following polyfills provide ES5 functionality that's missing in older browsers (eg, IE8),\n * allowing PCjs apps to run without slamming into exceptions; however, due to the lack of HTML5 canvas\n * support in those browsers, all you're likely to see are \"soft\" errors (eg, \"Missing <canvas> support\").\n *\n * Perhaps we can implement a text-only faux video display for a fun retro-browser experience someday.\n *\n * TODO: Come up with a better place to put these polyfills. We will likely have more if we decide to\n * make the leap from ES5 to ES6 features.\n */\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf\n */\nif (!Array.prototype.indexOf) {\n Array.prototype.indexOf = function(obj, start) {\n for (var i = (start || 0), j = this.length; i < j; i++) {\n if (this[i] === obj) { return i; }\n }\n return -1;\n }\n}\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray\n */\nif (!Array.isArray) {\n Array.isArray = function(arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n };\n}\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind\n */\nif (!Function.prototype.bind) {\n Function.prototype.bind = function(obj) {\n if (typeof this != \"function\") {\n // Closest thing possible to the ECMAScript 5 internal IsCallable function\n throw new TypeError(\"Function.prototype.bind: non-callable object\");\n }\n var args = Array.prototype.slice.call(arguments, 1);\n var fToBind = this;\n var fnNOP = /** @constructor */ (function() {});\n var fnBound = function() {\n return fToBind.apply(this instanceof fnNOP && obj? this : obj, args.concat(/** @type {Array} */(Array.prototype.slice.call(arguments))));\n };\n fnNOP.prototype = this.prototype;\n fnBound.prototype = new fnNOP();\n return fnBound;\n };\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/defines.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @define {string}\n */\nvar APPCLASS = \"pdp10\"; // this @define is the default application class (eg, \"pcx86\", \"c1pjs\")\n\n/**\n * APPNAME is used more for display purposes than anything else now. APPCLASS is what matters in terms\n * of folder and file names, CSS styles, etc.\n *\n * @define {string}\n */\nvar APPNAME = \"PDPjs\"; // this @define is the default application name (eg, \"PCx86\", \"C1Pjs\")\n\n/**\n * WARNING: DEBUGGER needs to accurately reflect whether or not the Debugger component is (or will be) loaded.\n * In the compiled case, we rely on the Closure Compiler to override DEBUGGER as appropriate. When it's *false*,\n * nearly all of debugger.js will be conditionally removed by the compiler, reducing it to little more than a\n * \"type skeleton\", which also solves some type-related warnings we would otherwise have if we tried to remove\n * debugger.js from the compilation process altogether.\n *\n * However, when we're in \"development mode\" and running uncompiled code in debugger-less configurations,\n * I would like to skip loading debugger.js altogether. When doing that, we must ALSO arrange for an additional file\n * (nodebugger.js) to be loaded immediately after this file, which *explicitly* overrides DEBUGGER with *false*.\n *\n * @define {boolean}\n */\nvar DEBUGGER = true; // this @define is overridden by the Closure Compiler to remove Debugger-related support\n\n/*\n * Set this to true to enable behavior compatible with SIMH.\n */\nvar SIMH = false;\n\n/*\n * Combine all the shared globals and machine-specific globals into one machine-specific global object,\n * which all machine components should start using; eg: \"if (PDP10.DEBUG) ...\" instead of \"if (DEBUG) ...\".\n */\nvar PDP10 = {\n APPCLASS: APPCLASS,\n APPNAME: APPNAME,\n APPVERSION: APPVERSION, // shared\n COMPILED: COMPILED, // shared\n CSSCLASS: CSSCLASS, // shared\n DEBUG: DEBUG, // shared\n DEBUGGER: DEBUGGER,\n MAXDEBUG: MAXDEBUG, // shared\n PRIVATE: PRIVATE, // shared\n SITEHOST: SITEHOST, // shared\n XMLVERSION: XMLVERSION, // shared\n\n /*\n * CPU model numbers (supported)\n */\n MODEL_KA10: 1001,\n\n /*\n * ADDR_INVALID is used to mark points in the code where the physical address being returned\n * is invalid and should not be used.\n *\n * In a 32-bit CPU, -1 (ie, 0xffffffff) could actually be a valid address, so consider changing\n * ADDR_INVALID to NaN or null (which is also why all ADDR_INVALID tests should use strict equality\n * operators).\n *\n * The main reason I'm NOT using NaN or null now is my concern that, by mixing non-numbers\n * (specifically, values outside the range of signed 32-bit integers), performance may suffer.\n *\n * WARNING: Like many of the properties defined here, ADDR_INVALID is a common constant, which the\n * Closure Compiler will happily inline (with or without @const annotations; in fact, I've yet to\n * see a @const annotation EVER improve automatic inlining). However, if you don't make ABSOLUTELY\n * certain that this file is included BEFORE the first reference to any of these properties, that\n * automatic inlining will no longer occur.\n */\n ADDR_INVALID: -1,\n ADDR_MASK: Math.pow(2, 18) - 1,\n ADDR_LIMIT: Math.pow(2, 18),\n\n /*\n * 18-bit and 36-bit largest positive (and smallest negative) values; however, since we store all\n * values as unsigned quantities, these are the unsigned equivalents.\n */\n WORD_INVALID: -1,\n HINT_MASK: Math.pow(2, 17) - 1, // 131,071 (377777) signed half-word (half-int) mask\n HINT_LIMIT: Math.pow(2, 17), // 131,072 (400000) signed half-word (half-int) limit\n HALF_MASK: Math.pow(2, 18) - 1, // 262,143 (000000 777777): unsigned half-word mask\n HALF_SHIFT: Math.pow(2, 18), // 262,144 (000001 000000): unsigned half-word shift\n INT_MASK: Math.pow(2, 35) - 1, // 34,359,738,367 (377777 777777): signed word (magnitude) mask\n INT_LIMIT: Math.pow(2, 35), // 34,359,738,368 (400000 000000): signed word (magnitude) limit\n WORD_MASK: Math.pow(2, 36) - 1, // 68,719,476,735 (777777 777777): unsigned word mask\n WORD_LIMIT: Math.pow(2, 36), // 68,719,476,736 (1 000000 000000): unsigned word limit\n\n TWO_POW32: Math.pow(2, 32),\n TWO_POW34: Math.pow(2, 34),\n TWO_POW36: Math.pow(2, 36), // the two's complement of a 36-bit value is (value? TWO_POW36 - value : 0)\n\n /*\n * PDP-10 opcodes are 36-bit values, most of which use the following layout:\n *\n * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3\n * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5\n * O O O O O O O M M A A A A I X X X X Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y\n *\n * or using modern bit-numbering:\n *\n * 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1\n * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0\n * O O O O O O O M M A A A A I X X X X Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y\n *\n * where OOOOOOOMM represents the operation, and MM (if used) represents the mode:\n *\n * Mode Suffix Source Destination\n * ---- ------ ----- -----------\n * 0: Basic None E AC\n * 1: Immediate I 0,E AC\n * 2: Memory M AC E\n * 3: Self/Both S or B E E (and AC if A is non-zero)\n *\n * Input-output instructions look like:\n *\n * 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1\n * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0\n * 1 1 1 D D D D D D D O O O I X X X X Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y\n *\n * Bits 0-22 (I,X,Y) contain what we call a \"reference address\" (R), which is used to calculate the\n * \"effective address\" (E). To determine E from R, we must extract I, X, and Y from R, set E to Y,\n * then add [X] to E if X is non-zero. If I is zero, then we're done; otherwise, we must set R to [E]\n * and repeat the process.\n */\n OPCODE: {\n OPMASK: 0o77700, // operation mask\n OPMODE: 0o77400, // operation with mode\n OPCOMP: 0o77000, // operation with compare\n OPTEST: 0o71100, // operation with test\n OPIO: 0o70034, // input-output operation\n OPUUO: 0o70000, // unimplemented user operation (UUO) mask\n OP_SCALE: Math.pow(2, 21), // operation scale\n IO_SCALE: Math.pow(2, 26), // input-output device code scale\n IO_MASK: 0o177, // input-output device code mask (after descale)\n A_SCALE: Math.pow(2, 23), // used to shift down the high 13 bits, with A starting at bit 0\n P_SCALE: Math.pow(2, 30), // P scale\n P_MASK: 0o77, // P mask (after descale)\n S_SHIFT: 24, // S shift\n S_MASK: 0o77, // S mask (after shift)\n A_SHIFT: 23, // A shift\n A_MASK: 0o17, // A mask (after shift)\n A_FIELD: 0o740000000, // A field mask\n I_FIELD: 0o20000000, // indirect bit mask\n X_SHIFT: 18, // X shift\n X_MASK: 0o17, // X mask (after shift)\n X_FIELD: 0o17000000, // X field mask\n Y_SHIFT: 0, // Y shift\n Y_MASK: 0o777777, // Y mask (after shift)\n Y_FIELD: 0o777777, // Y field mask\n R_MASK: 0o37777777, // used to isolate the low 23 bits (I,X,Y)\n PTR_MASK: 0o77777777, // used to isolate the low 24 bits (?,I,X,Y) of a byte pointer\n HALT: 0o5304 // operation code for HALT\n },\n\n /*\n * Internal operation state flags\n */\n OPFLAG: {\n IRQ_DELAY: 0x0001, // incremented until it becomes IRQ\n IRQ: 0x0002, // time to call checkInterrupts()\n IRQ_MASK: 0x0003,\n DEBUGGER: 0x0004, // set if the Debugger wants to perform checks\n WAIT: 0x0008, // WAIT operation in progress\n PRESERVE: 0x000F // OPFLAG bits to preserve prior to the next instruction\n },\n\n /*\n * Flags returned by getPS() for various program control operations.\n *\n * NOTE: I see SIMH setting PS bits like 0o000200 and 0o000400, which are not documented for the KA10.\n * The SIMH docs only refer to the KS10 (\"KS10 CPU with 1MW of memory\"), so I'm guessing it doesn't have\n * a KA10 emulation option. The `pdp10` SIMH binary does have some SET CPU options, but unlike the `pdp11`\n * binary, the only options you can set relate to the operating system to be run -- which seems very hacky.\n */\n PSFLAG: {\n AROV: 0o400000, // Arithmetic Overflow\n CRY0: 0o200000, // Carry 0\n CRY1: 0o100000, // Carry 1\n FOV: 0o040000, // Floating-Point Overflow\n BIS: 0o020000, // Byte Interrupt\n USERF: 0o010000, // User Mode Flag\n EXIOT: 0o004000, // User Privileged I/O Flag\n FXU: 0o000100, // Floating-Point Underflow\n DCK: 0o000040, // Divide Check (aka No Divide)\n /*\n * Only the low 18 bits (above) are returned by getPS(); the following (bits 18 to 31)\n * are defined for internal use only.\n */\n PDOV: 0o1000000, // Pushdown Overflow\n SET_MASK: 0o0760140 // flags that are always settable/clearable\n },\n\n /*\n * Readable CPU (or APR for \"Arithmetic Processor\") flags provided by the \"CONI APR,\" instruction; see opCONI().\n */\n RFLAG: {\n PIA: 0o000007, // Priority Interrupt Assignment\n AROV: 0o000010, // Arithmetic Overflow\n AROV_IE: 0o000020, // Arithmetic Overflow Interrupt Enabled\n TRAP_OFF: 0o000040, // Trap Offset\n FOV: 0o000100, // Floating-Point Overflow\n FOV_IE: 0o000200, // Floating-Point Overflow Interrupt Enabled\n CLK: 0o001000, // Clock Flag\n CLK_IE: 0o002000, // Clock Interrupt Enabled\n NXM: 0o010000, // Non-Existent Memory\n PRM: 0o020000, // Memory Protection\n ADB: 0o040000, // Address Break\n UIO: 0o100000, // User In-Out\n PDOV: 0o200000 // Pushdown Overflow (TODO: Verify this is correct; the May 1968 doc may have a typo)\n },\n\n /*\n * Writable CPU (or APR for \"Arithmetic Processor\") flags provided by the \"CONO APR,\" instruction; see opCONO().\n *\n * A set bit performs the function shown below, a clear bit does nothing.\n */\n WFLAG: {\n PIA: 0o000007, // Priority Interrupt Assignment\n AROV_CL: 0o000010, // Clear Overflow\n AROV_IE: 0o000020, // Enable Overflow Interrupt\n AROV_ID: 0o000040, // Disable Overflow Interrupt\n FOV_CL: 0o000100, // Clear Floating-Point Overflow\n FOV_IE: 0o000200, // Enable Floating-Point Overflow Interrupt\n FOV_ID: 0o000400, // Disable Floating-Point Overflow Interrupt\n CLK_CL: 0o001000, // Clear Clock Flag\n CLK_IE: 0o002000, // Enable Clock Interrupt\n CLK_ID: 0o004000, // Disable Clock Interrupt\n NXM_CL: 0o010000, // Clear Non-Existent Memory\n PRM_CL: 0o020000, // Clear Memory Protection\n ADB_CL: 0o040000, // Clear Address Break\n UIO_CL: 0o200000, // Clear All In-Out Devices\n PDOV_CL: 0o400000 // Clear Pushdown Overflow\n },\n\n /*\n * 7-bit device codes used by Input-Output instructions; see opIO().\n */\n DEVICES: {\n APR: 0o000, // Arithmetic Processor\n PI: 0o001 // Priority Interrupt\n }\n};\n\n/*\n * Combine all the shared globals and machine-specific globals into one machine-specific global object,\n * which all machine components should start using; eg: \"if (PDP10.DEBUGGER)\" instead of \"if (DEBUGGER)\".\n */\nPDP10.APPCLASS = APPCLASS;\nPDP10.APPNAME = APPNAME;\nPDP10.DEBUGGER = DEBUGGER;\nPDP10.SIMH = SIMH;\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/messages.js (C) Jeff Parsons 2012-2018\n */\n\nvar MessagesPDP10 = {\n CPU: 0x00000001,\n TRAP: 0x00000002,\n FAULT: 0x00000004,\n INT: 0x00000008,\n BUS: 0x00000010,\n MEMORY: 0x00000020,\n MMU: 0x00000040,\n ROM: 0x00000080,\n DEVICE: 0x00000100,\n PANEL: 0x00000200,\n KEYBOARD: 0x00000400,\n KEYS: 0x00000800,\n PAPER: 0x00001000,\n READ: 0x00004000,\n WRITE: 0x00008000,\n SERIAL: 0x00100000,\n TIMER: 0x00200000,\n SPEAKER: 0x01000000,\n COMPUTER: 0x02000000,\n LOG: 0x10000000,\n WARN: 0x20000000,\n BUFFER: 0x40000000,\n HALT: 0x80000000|0\n};\n\n/*\n * Message categories supported by the messageEnabled() function and other assorted message\n * functions. Each category has a corresponding bit value that can be combined (ie, OR'ed) as\n * needed. The Debugger's message command (\"m\") is used to turn message categories on and off,\n * like so:\n *\n * m port on\n * m port off\n * ...\n *\n * NOTE: The order of these categories can be rearranged, alphabetized, etc, as desired; just be\n * aware that changing the bit values could break saved Debugger states (not a huge concern, just\n * something to be aware of).\n */\nMessagesPDP10.CATEGORIES = {\n \"cpu\": MessagesPDP10.CPU,\n \"trap\": MessagesPDP10.TRAP,\n \"fault\": MessagesPDP10.FAULT,\n \"int\": MessagesPDP10.INT,\n \"bus\": MessagesPDP10.BUS,\n \"memory\": MessagesPDP10.MEMORY,\n \"mmu\": MessagesPDP10.MMU,\n \"rom\": MessagesPDP10.ROM,\n \"device\": MessagesPDP10.DEVICE,\n \"panel\": MessagesPDP10.PANEL,\n \"keyboard\": MessagesPDP10.KEYBOARD, // \"kbd\" is also allowed as shorthand for \"keyboard\"; see doMessages()\n \"key\": MessagesPDP10.KEYS, // using \"key\" instead of \"keys\", since the latter is a method on JavasScript objects\n \"paper\": MessagesPDP10.PAPER,\n \"read\": MessagesPDP10.READ,\n \"write\": MessagesPDP10.WRITE,\n \"serial\": MessagesPDP10.SERIAL,\n \"timer\": MessagesPDP10.TIMER,\n \"speaker\": MessagesPDP10.SPEAKER,\n \"computer\": MessagesPDP10.COMPUTER,\n \"log\": MessagesPDP10.LOG,\n \"warn\": MessagesPDP10.WARN,\n /*\n * Now we turn to message actions rather than message types; for example, setting \"halt\"\n * on or off doesn't enable \"halt\" messages, but rather halts the CPU on any message above.\n *\n * Similarly, \"m buffer on\" turns on message buffering, deferring the display of all messages\n * until \"m buffer off\" is issued.\n */\n \"buffer\": MessagesPDP10.BUFFER,\n \"halt\": MessagesPDP10.HALT\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/panel.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * Component class, because otherwise the Compiler won't allow us to *reference* the named\n * property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass PanelPDP10 extends Component {\n /**\n * PanelPDP10(parmsPanel)\n *\n * The PanelPDP10 component has no required (parmsPanel) properties.\n *\n * @param {Object} parmsPanel\n * @param {boolean} fBindings (true if panel may have bindings, otherwise not)\n */\n constructor(parmsPanel, fBindings)\n {\n super(\"Panel\", parmsPanel, MessagesPDP10.PANEL);\n\n /*\n * If there are any live registers, LEDs, etc, to display, this will provide a count.\n * TODO: Add some UI for fDisplayLiveRegs (either an XML property, or a UI checkbox, or both).\n */\n this.cLiveRegs = 0;\n this.nDisplayCount = 0;\n this.nDisplayLimit = 60;\n this.fDisplayLiveRegs = true;\n this.fBindings = fBindings;\n\n /*\n * regSwitches contains the Front Panel (aka Console) SWITCH register, which is also available\n * as a read-only register at 177570 (but only the low 16 bits). regDisplay contains the DISPLAY\n * register, a write-only register at the same address.\n *\n * regAddr is an internal register containing the contents of the Front Panel's ADDRESS display,\n * and regData corresponds to the DATA display. They are updated by updateAddr() and updateData(),\n * which in turn take care of calling updateLEDArray().\n *\n * The state of ALL switches is maintained in this.switches, and likewise all LED states are\n * maintained in this.leds, but for convenience, we also mirror some of those states in dedicated\n * variables (eg, regSwitches for the SWITCH register, fLEDTest for the 'TEST' switch, etc).\n */\n this.regDisplay = 0;\n this.regSwitches = 0;\n this.regAddr = this.regData = 0;\n this.ledAddr = this.ledData = -1;\n\n /*\n * The panel hardware has the following additional (supported) state; note that there are several\n * settings on a real Front Panel that we don't support (eg, stepping one cycle vs. one instruction).\n *\n * While my initial intent is to eventually support all the ADDRSEL switch settings, I probably\n * won't bother with any DATASEL switch settings; instead, I will automatically display the DISPLAY\n * register (regDisplay) [the equivalent of selecting 'DISPLAY REGISTER'] except when data is being\n * examined or deposited [the equivalent of selecting 'DATA PATHS'].\n */\n this.fLEDTest = false; // LED (lamp) test in progress\n this.fExamine = false; // true if the previously pressed switch was the 'EXAM' switch\n this.fDeposit = false; // true if the previously pressed switch was the 'DEP' switch\n this.nAddrSel = PanelPDP10.ADDRSEL.CONS_PHY;\n\n /*\n * Every LED has a simple numeric value, assigned when setBinding() is called:\n *\n * zero if \"off\", non-zero if \"on\"\n *\n * initBus() will call displayLEDs() to ensure that every LED is set to its initial value.\n */\n this.leds = {};\n\n /*\n * Every switch has an array associated with it:\n *\n * [0]: initial value of switch (0 if \"down\", 1 if \"up\")\n * [1]: current value of switch\n * [2]: true if the switch is momentary, false if not\n * [3]: true if the switch is currently pressed, false if released\n * [4]: optional handler to call whenever the switch is pressed or released\n * [5]: optional switch index (used with CNSW switches 'S0' through 'S21')\n *\n * initBus() will call displaySwitches() to ensure that every switch is the position represented below.\n *\n * NOTE: Not all switches have the same \"process\" criteria. For example, 'TEST' will perform a LED test\n * when it is momentarily pressed \"up\", whereas 'LOAD [ADRS]' will load the ADDRESS register from the\n * SWITCH register when it is momentarily pressed \"down\".\n *\n * This means that processLEDTest(value) must act when value == 1 (\"up\"), whereas processLoadAddr(value)\n * must act when value == 0 (\"down\"). You can infer all this from the table below, because the initial value\n * of any momentary switch is its \"inactive\" value, so the opposite is its \"active\" value.\n */\n this.switches = {\n 'START': [1, 1, true, false, this.processStart],\n 'STEP': [1, 1, false, false, this.processStep],\n 'ENABLE': [1, 1, false, false, this.processEnable],\n 'CONT': [1, 1, true, false, this.processContinue],\n 'DEP': [0, 0, true, false, this.processDeposit],\n 'EXAM': [1, 1, true, false, this.processExamine],\n 'LOAD': [1, 1, true, false, this.processLoadAddr],\n 'TEST': [0, 0, true, false, this.processLEDTest]\n };\n for (var i = 0; i < 22; i++) {\n this.switches['S'+i] = [0, 0, false, false, this.processSRSwitch, i];\n }\n\n /** @type {ComputerPDP10} */\n this.cmp = null;\n\n /** @type {BusPDP10} */\n this.bus = null;\n\n /** @type {CPUStatePDP10} */\n this.cpu = null;\n\n /** @type {DebuggerPDP10} */\n this.dbg = null;\n\n /*\n * The 'hold' and 'toggle' exports, which map to holdSwitch() and toggleSwitch(), both press and release\n * the specified switch, but processCommands() considers a 'hold' function to be asynchronous, which means\n * that holdSwitch() will be passed a callback function that can be used to implement a delay between the\n * press and the release, whereas toggleSwitch() will not.\n *\n * holdSwitch() only makes sense for momentary switches (eg, 'TEST'), where a visual delay might be nice.\n * If the switch isn't momentary, or no delay is desired, then use toggleSwitch(); it will be more efficient.\n *\n * Finally, for switches that are toggles (eg, 'ENABLE'), you can use setSwitch() to set it to a specific\n * state: zero for \"off\" and non-zero for \"on\". setSwitch() also supports meta-switches like \"SR\", using\n * the entire value to set a series of switches at once; the value is assumed to be octal unless overridden\n * by a prefix (eg, \"0x\") or suffix (eg, \".\").\n */\n this['exports'] = {\n 'hold': this.holdSwitch,\n 'toggle': this.toggleSwitch,\n 'reset': this.resetSwitches,\n 'set': this.setSwitch\n };\n\n this.setReady();\n }\n\n /**\n * getAR()\n *\n * @this {PanelPDP10}\n * @return {number} (current ADDRESS register)\n */\n getAR()\n {\n return this.regAddr;\n }\n\n /**\n * setAR(value)\n *\n * @this {PanelPDP10}\n * @param {number} value (new ADDRESS register)\n */\n setAR(value)\n {\n this.updateAddr(this.regAddr = value);\n }\n\n /**\n * getDR()\n *\n * @this {PanelPDP10}\n * @return {number} (current DISPLAY register)\n */\n getDR()\n {\n return this.regDisplay;\n }\n\n /**\n * setDR(value)\n *\n * @this {PanelPDP10}\n * @param {number} value (new DISPLAY register)\n * @return {number}\n */\n setDR(value)\n {\n return this.updateData(this.regDisplay = value);\n }\n\n /**\n * getSR()\n *\n * @this {PanelPDP10}\n * @return {number} (current SWITCH register)\n */\n getSR()\n {\n return this.regSwitches;\n }\n\n /**\n * setSR(value)\n *\n * @this {PanelPDP10}\n * @param {number} value (new SWITCH register)\n */\n setSR(value)\n {\n this.setSRSwitches(value);\n }\n\n /**\n * getSwitch(name)\n *\n * @this {PanelPDP10}\n * @param {string} name\n * @return {number|undefined} 0 if switch is off (\"down\"), 1 if on (\"up\"), or undefined if unrecognized\n */\n getSwitch(name)\n {\n return this.switches[name] && this.switches[name][1];\n }\n\n /**\n * reset(fPowerUp)\n *\n * NOTE: Since we've registered our handler with the Bus component, we will be called twice whenever\n * the entire machine is reset: once when the Computer's reset() handler calls the Bus's reset() handler,\n * and again when the Computer's reset() handler calls us directly. Multiple resets should be harmless.\n *\n * @this {PanelPDP10}\n * @param {boolean} [fPowerUp]\n */\n reset(fPowerUp)\n {\n /*\n * Simulate a call to our stop() handler, to update the panel's ADDRESS register with the current PC.\n */\n this.stop();\n if (fPowerUp) this.setDR(0);\n }\n\n /**\n * setBinding(sType, sBinding, control, sValue)\n *\n * Some panel layouts don't have bindings of their own, and even when they do, there may still be some\n * components (eg, the CPU) that prefer to update their own bindings, so we pass along all binding requests\n * to the Computer, CPU, Keyboard and Debugger components first. The order shouldn't matter, since any\n * component that doesn't recognize the specified binding should simply ignore it.\n *\n * @this {PanelPDP10}\n * @param {string|null} sType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sType, sBinding, control, sValue)\n {\n if (this.cmp && this.cmp.setBinding(sType, sBinding, control, sValue)) {\n return true;\n }\n if (this.cpu && this.cpu.setBinding(sType, sBinding, control, sValue)) {\n return true;\n }\n if (DEBUGGER && this.dbg && this.dbg.setBinding(sType, sBinding, control, sValue)) {\n return true;\n }\n\n switch (sBinding) {\n case 'PC':\n this.bindings[sBinding] = control;\n this.cLiveRegs++;\n return true;\n\n default:\n /*\n * Square (\"led\") or round (\"rled\") LEDs are defined in machine XML files like so:\n *\n * <control type=\"rled\" binding=\"A3\" value=\"1\" width=\"100%\" container=\"center\"/>\n *\n * Only *type* and *binding* attributes are required; if *value* is omitted, the default value is 0 (\"off\").\n */\n if (sType == \"led\" || sType == \"rled\") {\n this.bindings[sBinding] = control;\n this.leds[sBinding] = sValue? 1 : 0;\n this.cLiveRegs++;\n return true;\n }\n /*\n * Switches are defined in machine XML files like so:\n *\n * <control type=\"switch\" binding=\"S3\" value=\"1\" width=\"100%\" container=\"center\"/>\n *\n * Only *type* and *binding* attributes are required; if *value* is omitted, the default value is 0 (\"down\").\n *\n * Currently, there is no XML attribute to indicate whether a switch is \"momentary\"; only recognized switches\n * in our internal table can have that attribute.\n */\n if (sType == \"switch\") {\n /*\n * Like LEDs, we allow unrecognized switches to be defined as well, but they won't do anything useful,\n * since only recognized switches will have handlers that perform the appropriate operations.\n */\n if (this.switches[sBinding] === undefined) {\n this.switches[sBinding] = [sValue? 1 : 0, sValue? 1 : 0];\n }\n this.bindings[sBinding] = control;\n var parent = control.parentElement || control;\n parent = parent.parentElement || parent;\n parent.onmousedown = function(panel, sBinding) {\n return function onPressSwitch() {\n panel.pressSwitch(sBinding);\n };\n }(this, sBinding);\n parent.onmouseup = parent.onmouseout = function(panel, sBinding) {\n return function onReleaseSwitch() {\n panel.releaseSwitch(sBinding);\n };\n }(this, sBinding);\n parent.ontouchstart = function(panel, sBinding) {\n return function onPressSwitch(event) {\n panel.pressSwitch(sBinding);\n event.preventDefault();\n };\n }(this, sBinding);\n parent.ontouchend = function(panel, sBinding) {\n return function onReleaseSwitch() {\n panel.releaseSwitch(sBinding);\n };\n }(this, sBinding);\n return true;\n }\n return super.setBinding(sType, sBinding, control, sValue);\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {PanelPDP10}\n * @param {ComputerPDP10} cmp\n * @param {BusPDP10} bus\n * @param {CPUStatePDP10} cpu\n * @param {DebuggerPDP10} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n this.displayLEDs();\n this.displaySwitches();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {PanelPDP10}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n /*\n * As noted in init(), our powerUp() method gives us a second opportunity to notify any\n * components that that might care (eg, CPU, Keyboard, and Debugger) that we have some controls\n * (ie, bindings) they might want to use.\n */\n if (this.fBindings) PanelPDP10.init();\n\n if (!data) {\n this.reset(true);\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {PanelPDP10}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * save()\n *\n * This implements save support for the PanelPDP10 component.\n *\n * @this {PanelPDP10}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, [\n this.getAR(),\n this.getDR(),\n this.getSR()\n ]);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the PanelPDP10 component.\n *\n * @this {PanelPDP10}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var a = data[0];\n if (a) {\n this.setAR(a[0]);\n this.setDR(a[1]);\n this.setSR(a[2]);\n }\n return true;\n }\n\n /**\n * resetSwitches()\n *\n * @this {PanelPDP10}\n * @return {boolean}\n */\n resetSwitches()\n {\n for (var sBinding in this.switches) {\n var sw = this.switches[sBinding];\n sw[1] = sw[0];\n }\n this.displaySwitches();\n return true;\n }\n\n /**\n * displayLED(sBinding, value)\n *\n * @this {PanelPDP10}\n * @param {string} sBinding\n * @param {boolean|number} value (true or non-zero if the LED should be on, false or zero if off)\n */\n displayLED(sBinding, value)\n {\n var control = this.bindings[sBinding];\n if (control) {\n /*\n * TODO: Add support for user-definable LED colors?\n */\n control.style.backgroundColor = (value? \"#ff0000\" : \"#000000\");\n }\n }\n\n /**\n * displayLEDs(override)\n *\n * @this {PanelPDP10}\n * @param {boolean|number|null} [override] (true turn on all LEDs, false to turn off all LEDs, null or undefined for normal LED activity)\n */\n displayLEDs(override)\n {\n for (var sBinding in this.leds) {\n this.displayLED(sBinding, override != null? override : this.leds[sBinding]);\n }\n }\n\n /**\n * displaySwitch(sBinding, value)\n *\n * @this {PanelPDP10}\n * @param {string} sBinding\n * @param {boolean|number} value (true if the switch should be \"up\" (on), false if \"down\" (off))\n */\n displaySwitch(sBinding, value)\n {\n var control = this.bindings[sBinding];\n if (control) {\n control.style.marginTop = (value? \"0px\" : \"20px\");\n control.style.backgroundColor = (value? \"#00ff00\" : \"#228B22\");\n }\n }\n\n /**\n * displaySwitches()\n *\n * @this {PanelPDP10}\n */\n displaySwitches()\n {\n for (var sBinding in this.switches) {\n this.displaySwitch(sBinding, this.switches[sBinding][1]);\n }\n }\n\n /**\n * displayValue(sLabel, nValue, cch)\n *\n * This is principally for displaying register values, but in reality, it can be used to display any\n * numeric value bound to the given label.\n *\n * @this {PanelPDP10}\n * @param {string} sLabel\n * @param {number} nValue\n * @param {number} [cch]\n */\n displayValue(sLabel, nValue, cch)\n {\n if (this.bindings[sLabel]) {\n var sVal;\n var nBase = this.dbg && this.dbg.nBase || 8;\n nValue = nValue || 0;\n if (!this.cpu.isRunning() || this.fDisplayLiveRegs) {\n sVal = nBase == 8? Str.toOct(nValue, cch) : Str.toHex(nValue, cch);\n } else {\n sVal = \"--------\".substr(0, cch || 4);\n }\n /*\n * TODO: Determine if this test actually avoids any redrawing when a register hasn't changed, and/or if\n * we should maintain our own (numeric) cache of displayed register values (to avoid creating these temporary\n * string values that will have to garbage-collected), and/or if this is actually slower, and/or if I'm being\n * too obsessive.\n */\n if (this.bindings[sLabel].textContent != sVal) this.bindings[sLabel].textContent = sVal;\n }\n }\n\n /**\n * holdSwitch(fnCallback, sBinding, sDelay)\n *\n * @this {PanelPDP10}\n * @param {function()|null} fnCallback\n * @param {string} sBinding\n * @param {string} [sDelay]\n * @return {boolean} false if wait required, true otherwise\n */\n holdSwitch(fnCallback, sBinding, sDelay)\n {\n if (this.pressSwitch(sBinding)) {\n if (sDelay) {\n var panel = this;\n setTimeout(function() {\n panel.releaseSwitch(sBinding);\n if (fnCallback) fnCallback();\n }, +sDelay);\n return false;\n } else {\n this.releaseSwitch(sBinding);\n }\n }\n return true;\n }\n\n /**\n * setSwitch(sBinding, sValue)\n *\n * @this {PanelPDP10}\n * @param {string} sBinding\n * @param {string} sValue\n * @return {boolean}\n */\n setSwitch(sBinding, sValue)\n {\n if (sBinding == \"SR\") {\n return this.setSRSwitches(Str.parseInt(sValue, 8))\n }\n var sw = this.switches[sBinding];\n if (sw) {\n sw[1] = +sValue? 1 : 0;\n this.displaySwitch(sBinding, sw[1]);\n return true;\n }\n return false;\n }\n\n /**\n * toggleSwitch(sBinding)\n *\n * @this {PanelPDP10}\n * @param {string} sBinding\n * @return {boolean}\n */\n toggleSwitch(sBinding)\n {\n if (this.pressSwitch(sBinding)) {\n this.releaseSwitch(sBinding);\n return true;\n }\n return false;\n }\n\n /**\n * pressSwitch(sBinding)\n *\n * @this {PanelPDP10}\n * @param {string} sBinding\n * @return {boolean}\n */\n pressSwitch(sBinding)\n {\n var sw = this.switches[sBinding];\n if (sw) {\n /*\n * Set the new switch value in sw[1] and then immediately display it\n */\n this.displaySwitch(sBinding, (sw[1] = 1 - sw[1]));\n\n /*\n * Mark the switch as \"pressed\"\n */\n sw[3] = true;\n\n /*\n * Call the appropriate process handler with the current switch value (sw[1])\n */\n if (sw[4]) sw[4].call(this, sw[1], sw[5]);\n\n /*\n * This helps the next 'DEP' or 'EXAM' press determine if the previous press was the same,\n * while also ignoring any intervening 'STEP' presses (see processStep() for why we do that).\n */\n if (sBinding != PanelPDP10.SWITCH.STEP) {\n this.fDeposit = (sBinding == PanelPDP10.SWITCH.DEP);\n this.fExamine = (sBinding == PanelPDP10.SWITCH.EXAM);\n }\n return true;\n }\n return false;\n }\n\n /**\n * releaseSwitch(sBinding)\n *\n * @this {PanelPDP10}\n * @param {string} sBinding\n * @return {boolean}\n */\n releaseSwitch(sBinding)\n {\n /*\n * pressSwitch() is simple: flip the switch's current value in sw[1] and marked it \"pressed\" in sw[3].\n *\n * releaseSwitch() is more complicated, because we must handle both mouseUp and mouseOut events. The first time\n * we receive EITHER of those events AND the switch is marked momentary (sw[2]) AND the switch is pressed (sw[3]),\n * then we must flip the switch back to its original value.\n *\n * Otherwise, the only thing we have to do is mark the switch as \"released\" (ie, set sw[3] to false).\n */\n var sw = this.switches[sBinding];\n if (sw) {\n if (sw[2] && sw[3]) {\n /*\n * Set the new switch value in sw[1] and then immediately display it\n */\n this.displaySwitch(sBinding, (sw[1] = sw[0]));\n\n /*\n * Call the appropriate process handler with the current switch value (sw[1])\n */\n if (sw[4]) sw[4].call(this, sw[1], sw[5]);\n }\n /*\n * Mark the switch as \"released\"\n */\n sw[3] = false;\n return true;\n }\n return false;\n }\n\n /**\n * processStart(value, index)\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @param {number} [index]\n */\n processStart(value, index)\n {\n if (!value && !this.cpu.isRunning()) {\n\n this.cpu.setPC(this.regAddr);\n\n /*\n * The PDP-11/70 Handbook goes on to say: \"If the system needs to be initialized but execution\n * is not wanted, the START switch should be depressed while the HALT/ENABLE switch is in the HALT\n * position.\"\n */\n if (this.getSwitch(PanelPDP10.SWITCH.ENABLE)) {\n this.cpu.startCPU();\n }\n }\n }\n\n /**\n * processStep(value, index)\n *\n * If value == 1 (our initial value), then the 'STEP' switch is set to \"S INST\" (step one instruction);\n * otherwise, it's set to \"S BUS CYCLE\" (step one bus cycle).\n *\n * However, since we can't currently support cycle-stepping, I've decided to innovate a little and\n * change the meaning of this switch: the normal (\"up\") position means that successive 'EXAM' and 'DEP'\n * operations will first add 2 to the ADDRESS register, while the opposite (\"down\") position means\n * they will first subtract 2.\n *\n * See processLEDTest() for more of these exciting \"innovations\". ;-)\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @param {number} [index]\n */\n processStep(value, index)\n {\n /*\n * There's really nothing for us to do here, because the normal press and release handlers\n * already record the state of this switch, so it can be queried as needed, using getSwitch().\n */\n }\n\n /**\n * processEnable(value, index)\n *\n * If value == 1 (our initial value), then the 'ENABLE'/'HALT' switch is set to 'ENABLE', otherwise 'HALT'.\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @param {number} [index]\n */\n processEnable(value, index)\n {\n /*\n * The \"down\" (0) position is 'HALT', which stops the CPU; however, the \"up\" (1) position ('ENABLE')\n * does NOT start the CPU. You must press 'CONT' to continue execution, which will either continue for\n * one instruction if this switch to set to 'HALT' or indefinitely if it is set to 'ENABLE'.\n */\n if (!value) {\n this.cpu.stopCPU();\n }\n }\n\n /**\n * processContinue(value, index)\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @param {number} [index]\n */\n processContinue(value, index)\n {\n if (!value && !this.cpu.isRunning()) {\n /*\n * TODO: Technically, we're also supposed to check the 'STEP' switch to determine if we should\n * step one instruction or just one cycle, but we don't currently have the ability to do the latter.\n */\n if (!this.getSwitch(PanelPDP10.SWITCH.ENABLE)) {\n /*\n * Using the Debugger's stepCPU() function is more convenient, and has the pleasant side-effect\n * of updating the debugger's display; however, not all machines with a Front Panel will necessarily\n * also have the Debugger loaded.\n */\n var dbg = this.dbg;\n if (dbg && !dbg.isBusy(true)) {\n dbg.setBusy(true);\n dbg.stepCPU(0, null);\n dbg.setBusy(false);\n }\n else {\n /*\n * For this tiny single-instruction burst, mimic what runCPU() does.\n */\n try {\n var nCyclesStep = this.cpu.stepCPU(1);\n if (nCyclesStep > 0) {\n this.cpu.updateTimers(nCyclesStep);\n this.cpu.addCycles(nCyclesStep, true);\n this.cpu.updateChecksum(nCyclesStep);\n }\n }\n catch(exception) {\n /*\n * We assume that any numeric exception was explicitly thrown by the CPU to interrupt the\n * current instruction. For all other exceptions, we attempt a stack dump.\n */\n if (typeof exception != \"number\") {\n var e = exception;\n this.cpu.setError(e.stack || e.message);\n }\n }\n }\n\n /*\n * Simulate a call to our stop() handler, to update the panel's ADDRESS register with the new PC.\n */\n this.stop();\n\n /*\n * Going through the normal channels (ie, the Computer's updateDisplays() interface) ensures that\n * ALL updateDisplay() handlers will be called, including ours.\n *\n * NOTE: If we used the Debugger's stepCPU() function, then that includes a call to updateDisplay();\n * unfortunately, it will have happened BEFORE we called stop() to update the ADDRESS register, so\n * we still need to call it again.\n */\n if (this.cmp) this.cmp.updateDisplays();\n }\n else {\n this.cpu.startCPU();\n }\n }\n }\n\n /**\n * processDeposit(value, index)\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @param {number} [index]\n */\n processDeposit(value, index)\n {\n if (value && !this.cpu.isRunning()) {\n if (this.fDeposit) this.advanceAddr();\n /*\n * This used to be updateData(), but that only updates regData, whereas setDR() updates both regData and regDisplay,\n * and for these kinds of explicit Front Panel operations, I'm assuming the values should be synced.\n */\n var w = this.setDR(this.regSwitches);\n\n if (this.nAddrSel == PanelPDP10.ADDRSEL.CONS_PHY) {\n /*\n * TODO: Determine if this needs to take the UNIBUS map into consideration.\n */\n this.bus.setWordDirect(this.regAddr, w);\n } else {\n /*\n * TODO: This code is obviously incomplete, since it doesn't take into account the precise ADDRSEL mode.\n */\n this.cpu.writeWord(this.regAddr, w);\n }\n }\n }\n\n /**\n * processExamine(value, index)\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @param {number} [index]\n */\n processExamine(value, index)\n {\n if (!value && !this.cpu.isRunning()) {\n var w;\n if (this.fExamine) this.advanceAddr();\n if (this.nAddrSel == PanelPDP10.ADDRSEL.CONS_PHY) {\n /*\n * TODO: Determine if this needs to take the UNIBUS map into consideration.\n */\n w = this.bus.getWordDirect(this.regAddr);\n } else {\n /*\n * TODO: This code is obviously incomplete, since it doesn't take into account the precise ADDRSEL mode.\n */\n w = this.cpu.readWord(this.regAddr);\n }\n /*\n * This used to be updateData(), but that only updates regData, whereas setDR() updates both regData and regDisplay,\n * and for these kinds of explicit Front Panel operations, I'm assuming the values should be synced.\n */\n this.setDR(w);\n }\n }\n\n /**\n * processLoadAddr(value, index)\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @param {number} [index]\n */\n processLoadAddr(value, index)\n {\n if (!value && !this.cpu.isRunning()) {\n this.updateAddr(this.regSwitches);\n }\n }\n\n /**\n * processLEDTest(value, index)\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @param {number} [index]\n */\n processLEDTest(value, index)\n {\n if (value) {\n this.fLEDTest = true;\n this.displayLEDs(true);\n } else {\n this.fLEDTest = false;\n this.displayLEDs();\n /*\n * This is another one of my \"innovations\": when you're done testing the LEDs, all the switches reset as well.\n */\n this.setSRSwitches(0);\n }\n }\n\n /**\n * processSRSwitch(value, index)\n *\n * @this {PanelPDP10}\n * @param {number} value (normally 0 or 1, but we only depend on it being zero or non-zero)\n * @param {number} index\n */\n processSRSwitch(value, index)\n {\n if (value) {\n this.regSwitches |= 1 << index;\n } else {\n this.regSwitches &= ~(1 << index);\n }\n }\n\n /**\n * advanceAddr()\n *\n * This should also take care of the following Front Panel behaviors when the accessing the general-purpose\n * registers:\n *\n * 1) ADDRESS display incremented by 1 (instead of 2)\n * 2) The STEP after the last register is 177700, such that the addresses are looped\n *\n * A third behavior is NOT emulated: preventing the ADDRESS from stepping to the first General Register (177700)\n * from 177676.\n *\n * @this {PanelPDP10}\n * @return {number}\n */\n advanceAddr()\n {\n var inc = 1;\n var mask = this.bus.nBusMask;\n if (!this.getSwitch(PanelPDP10.SWITCH.STEP)) inc = -inc;\n return this.updateAddr((this.regAddr & ~mask) | ((this.regAddr + inc) & mask));\n }\n\n /**\n * updateAddr(value)\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @return {number}\n */\n updateAddr(value)\n {\n this.regAddr = value & this.bus.nBusMask;\n if (this.ledAddr !== this.regAddr) {\n this.ledAddr = this.regAddr;\n this.updateLEDArray(\"A\", this.ledAddr, 22);\n }\n return this.regAddr;\n }\n\n /**\n * updateData(value)\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @return {number}\n */\n updateData(value)\n {\n this.regData = value % PDP10.WORD_LIMIT;\n if (this.ledData !== this.regData) {\n this.ledData = this.regData;\n this.updateLEDArray(\"D\", this.ledData, 16);\n }\n return this.regData;\n }\n\n /**\n * updateLED(sBinding, value)\n *\n * @this {PanelPDP10}\n * @param {string} sBinding\n * @param {number} value\n * @return {number}\n */\n updateLED(sBinding, value)\n {\n this.leds[sBinding] = value;\n if (!this.fLEDTest) this.displayLED(sBinding, value);\n return value;\n }\n\n /**\n * updateLEDArray(sPrefix, value, nLEDs)\n *\n * @this {PanelPDP10}\n * @param {string} sPrefix\n * @param {number} value\n * @param {number} nLEDs\n */\n updateLEDArray(sPrefix, value, nLEDs)\n {\n for (var i = 0; i < nLEDs; i++) {\n var sBinding = sPrefix + i;\n this.updateLED(sBinding, value & (1 << i));\n }\n }\n\n /**\n * setSRSwitches(value)\n *\n * @this {PanelPDP10}\n * @param {number|undefined} value\n * @return {boolean}\n */\n setSRSwitches(value)\n {\n this.regSwitches = value | 0;\n for (var i = 0; i < 22; i++) {\n this.switches['S'+i][1] = (this.regSwitches & (1 << i))? 1 : 0;\n }\n /*\n * This (re)displays ALL switches, not merely the SR switches, but that's OK.\n */\n this.displaySwitches();\n return true;\n }\n\n /**\n * stop(ms, nCycles)\n *\n * This is a notification handler, called by the Computer, to inform us the CPU has now stopped.\n *\n * @this {PanelPDP10}\n * @param {number} [ms]\n * @param {number} [nCycles]\n */\n stop(ms, nCycles)\n {\n this.updateAddr(this.cpu.getPC());\n }\n\n /**\n * setAddr(value, fActive)\n *\n * This interface is for passing new addresses to the Front Panel. However, whether or not this will become the\n * ADDRESS actually displayed will depend on other settings (see updateStatus() for details).\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @param {boolean} [fActive] (true if this should become the \"active\" ADDRESS regardless of other settings)\n */\n setAddr(value, fActive)\n {\n this.regAddr = value;\n }\n\n /**\n * setData(value, fActive)\n *\n * This interface is for passing new data to the Front Panel. However, whether or not this will become the\n * DATA actually displayed will depend on the Front Panel's DATASEL switch setting, as well as the fActive flag.\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @param {boolean} [fActive] (true if this should become the \"active\" DATA regardless of the DATASEL switch setting)\n */\n setData(value, fActive)\n {\n if (!fActive) {\n this.regData = value;\n } else {\n this.regDisplay = value;\n }\n }\n\n /**\n * updateDisplay(nUpdate)\n *\n * Called by the Computer component at intervals to update registers, LEDs, etc.\n *\n * @this {PanelPDP10}\n * @param {number} [nUpdate] (-2 for power on, -1 for forced, > 0 for periodic, 0 or undefined otherwise)\n */\n updateDisplay(nUpdate)\n {\n if (this.cLiveRegs) {\n\n var fRunning = this.cpu.isRunning();\n var fWaiting = this.cpu.isWaiting();\n\n if (nUpdate < 0 || !fRunning || this.fDisplayLiveRegs) {\n\n /*\n * We arbitrarily separate the display elements into two categories: cheap and expensive.\n *\n * LEDs are considered cheap, register displays are not. So we'll skip the latter if this\n * is a periodic update AND our periodic update counter hasn't reached the periodic update limit.\n */\n if (nUpdate <= 0 || (this.nDisplayCount += nUpdate) >= this.nDisplayLimit) {\n this.displayValue(\"PC\", this.cpu.getPC());\n this.nDisplayCount = 0;\n }\n\n /*\n * Update the ADDRESS and DATA LEDs by selecting the appropriate values.\n *\n * TODO: There is currently no mechanism for selecting regData over regDisplay;\n * we are acting as if the DATASEL switch setting is locked to \"DISPLAY REGISTER\".\n */\n if (nUpdate < -1) {\n this.regAddr = this.cpu.getPC();\n } else if (nUpdate > 0 && fRunning && !fWaiting) {\n this.regAddr = this.cpu.getLastAddr();\n }\n\n this.updateAddr(this.regAddr);\n this.updateData(this.regDisplay);\n }\n }\n }\n\n /**\n * PanelPDP10.init()\n *\n * This function operates on every HTML element of class \"panel\", extracting the\n * JSON-encoded parameters for the PanelPDP10 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a PanelPDP10 component, and then binding\n * any associated HTML controls to the new component.\n *\n * NOTE: Unlike most other component init() functions, this one is designed to be\n * called multiple times: once at load time, so that we can bind our print()\n * function to the panel's output control ASAP, and again when the Computer component\n * is verifying that all components are ready and invoking their powerUp() functions.\n *\n * Our powerUp() method gives us a second opportunity to notify any components that\n * that might care (eg, CPU, Keyboard, and Debugger) that we have some controls they\n * might want to use.\n */\n static init()\n {\n var aePanels = Component.getElementsByClass(document, PDP10.APPCLASS, \"panel\");\n for (var iPanel=0; iPanel < aePanels.length; iPanel++) {\n var ePanel = aePanels[iPanel];\n var parmsPanel = Component.getComponentParms(ePanel);\n var panel = Component.getComponentByID(parmsPanel['id']);\n if (!panel) panel = new PanelPDP10(parmsPanel, true);\n Component.bindComponentControls(panel, ePanel, PDP10.APPCLASS);\n }\n }\n}\n\nPanelPDP10.ADDRSEL = {\n CONS_PHY: 7 // use a physical address to perform console operations (e.g., LOAD ADRS, EXAM, & DEP)\n};\n\n/*\n * To get the current state of a switch; eg::\n *\n * this.getSwitch(PanelPDP10.SWITCH.ENABLE)\n *\n * I haven't filled out this table, primarily it only needs to list switches we actually query\n * (eg, non-momentary ones like 'ENABLE' and 'STEP', and 'EXAM' and 'DEP' since they have special\n * \"step\" behavior when pressed more than once in a row). Ditto for the LED table.\n */\nPanelPDP10.SWITCH = {\n DEP: 'DEP',\n ENABLE: 'ENABLE',\n EXAM: 'EXAM',\n STEP: 'STEP'\n};\n\n/*\n * Initialize every Panel module on the page.\n */\nWeb.onInit(PanelPDP10.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/bus.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * Data types used by scanMemory()\n */\n\n/**\n * This defines the BlockInfo bit fields used by scanMemory() when it creates the aBlocks array.\n *\n * @typedef {{\n * num: BitField,\n * count: BitField,\n * btmod: BitField,\n * type: BitField\n * }}\n */\nvar BlockInfoPDP10 = Usr.defineBitFields({num:20, count:8, btmod:1, type:3});\n\n/**\n * BusInfoPDP10 object definition (returned by scanMemory())\n *\n * cbTotal: total bytes allocated\n * cBlocks: total Memory blocks allocated\n * aBlocks: array of allocated Memory block numbers\n *\n * @typedef {{\n * cbTotal: number,\n * cBlocks: number,\n * aBlocks: Array.<BlockInfoPDP10>\n * }}\n */\nvar BusInfoPDP10;\n\nclass BusPDP10 extends Component {\n /**\n * BusPDP10(parmsBus, cpu, dbg)\n *\n * The BusPDP10 component manages physical memory and I/O address spaces.\n *\n * The BusPDP10 component has no UI elements, so it does not require an init() handler,\n * but it still inherits from the Component class and must be allocated like any\n * other device component. It's currently allocated by the Computer's init() handler,\n * which then calls the initBus() method of all the other components.\n *\n * For memory beyond the simple needs of the ROM and RAM components (ie, memory-mapped\n * devices), the address space must still be allocated through the BusPDP10 component via\n * addMemory(). If the component needs something more than simple read/write storage,\n * it must provide a custom controller.\n *\n * @param {Object} parmsBus\n * @param {CPUStatePDP10} cpu\n * @param {DebuggerPDP10} dbg\n */\n constructor(parmsBus, cpu, dbg)\n {\n super(\"Bus\", parmsBus, MessagesPDP10.BUS);\n\n this.cpu = cpu;\n this.dbg = dbg;\n\n /*\n * Supported values for nBusWidth: 18 (default). This represents the maximum size of the bus for the\n * life of the machine, regardless what memory management mode the CPU has enabled.\n */\n this.nBusWidth = +parmsBus['busWidth'] || 18;\n\n /*\n * Compute all BusPDP10 memory block parameters now, based on the width of the bus.\n *\n * Note that all PCjs machines divide their address space into blocks, using a block size appropriate for\n * the machine's bus width. This allows us to efficiently allocate the entire address space, by reusing blocks\n * as appropriate, and to define to different address behaviors on a block-granular level.\n */\n this.addrTotal = 1 << this.nBusWidth;\n this.nBusMask = (this.addrTotal - 1);\n this.nBlockSize = 16384;\n this.nBlockShift = Math.log2(this.nBlockSize); // ES6 ALERT (alternatively: Math.log(this.nBlockSize) / Math.LN2)\n this.nBlockLen = this.nBlockSize >> 2;\n this.nBlockLimit = this.nBlockSize - 1;\n this.nBlockTotal = (this.addrTotal / this.nBlockSize) | 0;\n this.nBlockMask = this.nBlockTotal - 1;\n\n\n this.nDisableFaults = 0;\n this.fFault = false;\n\n /*\n * Define all the properties to be initialized by initMemory()\n */\n this.aBusBlocks = [];\n\n /*\n * We're ready to allocate empty Memory blocks to span the entire physical address space.\n */\n this.initMemory();\n\n this.setReady();\n }\n\n /**\n * initMemory()\n *\n * Allocate enough (empty) Memory blocks to span the entire physical address space.\n *\n * @this {BusPDP10}\n */\n initMemory()\n {\n var block = new MemoryPDP10(this);\n block.copyBreakpoints(this.dbg);\n\n this.aBusBlocks = new Array(this.nBlockTotal);\n for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {\n this.aBusBlocks[iBlock] = block;\n }\n }\n\n /**\n * reset()\n *\n * @this {BusPDP10}\n */\n reset()\n {\n }\n\n /**\n * getWidth()\n *\n * @this {BusPDP10}\n * @return {number}\n */\n getWidth()\n {\n return this.nBusWidth;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {BusPDP10}\n * @param {Object|null} data (always null because we supply no powerDown() handler)\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {BusPDP10}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * save()\n *\n * @this {BusPDP10}\n * @return {Object|null}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveMemory());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * @this {BusPDP10}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n return this.restoreMemory(data[0]);\n }\n\n /**\n * addMemory(addr, size, type)\n *\n * Adds new Memory blocks to the specified address range. Any Memory blocks previously\n * added to that range must first be removed via removeMemory(); otherwise, you'll get\n * an allocation conflict error. This helps prevent address calculation errors, redundant\n * allocations, etc.\n *\n * We've relaxed some of the original requirements (ie, that addresses must start at a\n * block-granular address, or that sizes must be equal to exactly one or more blocks),\n * because machines with large block sizes can make it impossible to load certain ROMs at\n * their required addresses. Every allocation still allocates a whole number of blocks.\n *\n * Even so, BusPDP10 memory management does NOT provide a general-purpose heap. Most memory\n * allocations occur during machine initialization and never change. In particular, there\n * is NO support for removing partial-block allocations.\n *\n * Each Memory block keeps track of a start address (addr) and length (used), indicating\n * the used space within the block; any free space that precedes or follows that used space\n * can be allocated later, by simply extending the beginning or ending of the previously used\n * space. However, any holes that might have existed between the original allocation and an\n * extension are subsumed by the extension.\n *\n * @this {BusPDP10}\n * @param {number} addr is the starting physical address of the request\n * @param {number} size of the request, in bytes\n * @param {number} type is one of the MemoryPDP10.TYPE constants\n * @return {boolean} true if successful, false if not\n */\n addMemory(addr, size, type)\n {\n var addrNext = addr;\n var sizeLeft = size;\n var iBlock = addrNext >>> this.nBlockShift;\n\n while (sizeLeft > 0 && iBlock < this.aBusBlocks.length) {\n\n var block = this.aBusBlocks[iBlock];\n var addrBlock = iBlock * this.nBlockSize;\n var sizeBlock = this.nBlockSize - (addrNext - addrBlock);\n if (sizeBlock > sizeLeft) sizeBlock = sizeLeft;\n\n if (block && block.size) {\n if (block.type == type) {\n /*\n * Where there is already a similar block with a non-zero size, we allow the allocation only if:\n *\n * 1) addrNext + sizeLeft <= block.addr (the request precedes the used portion of the current block), or\n * 2) addrNext >= block.addr + block.used (the request follows the used portion of the current block)\n */\n if (addrNext + sizeLeft <= block.addr) {\n block.used += (block.addr - addrNext);\n block.addr = addrNext;\n return true;\n }\n if (addrNext >= block.addr + block.used) {\n var sizeAvail = block.size - (addrNext - addrBlock);\n if (sizeAvail > sizeLeft) sizeAvail = sizeLeft;\n block.used = addrNext - block.addr + sizeAvail;\n addrNext = addrBlock + this.nBlockSize;\n sizeLeft -= sizeAvail;\n iBlock++;\n continue;\n }\n }\n return this.reportError(BusPDP10.ERROR.RANGE_INUSE, addrNext, sizeLeft);\n }\n\n var blockNew = new MemoryPDP10(this, addrNext, sizeBlock, this.nBlockSize, type);\n blockNew.copyBreakpoints(this.dbg, block);\n this.aBusBlocks[iBlock++] = blockNew;\n\n addrNext = addrBlock + this.nBlockSize;\n sizeLeft -= sizeBlock;\n }\n\n if (sizeLeft <= 0) {\n this.status(\"Added \" + (size >> 10) + \"Kb \" + MemoryPDP10.TYPE_NAMES[type] + \" at \" + Str.toOct(addr));\n return true;\n }\n\n return this.reportError(BusPDP10.ERROR.RANGE_INVALID, addr, size);\n }\n\n /**\n * cleanMemory(addr, size)\n *\n * @this {BusPDP10}\n * @param {number} addr\n * @param {number} size\n * @return {boolean} true if all blocks were clean, false if dirty; all blocks are cleaned in the process\n */\n cleanMemory(addr, size)\n {\n var fClean = true;\n var iBlock = addr >>> this.nBlockShift;\n var sizeBlock = this.nBlockSize - (addr & this.nBlockLimit);\n while (size > 0 && iBlock < this.aBusBlocks.length) {\n if (this.aBusBlocks[iBlock].fDirty) {\n this.aBusBlocks[iBlock].fDirty = fClean = false;\n this.aBusBlocks[iBlock].fDirtyEver = true;\n }\n size -= sizeBlock;\n sizeBlock = this.nBlockSize;\n iBlock++;\n }\n return fClean;\n }\n\n /**\n * zeroMemory(addr, size, pattern)\n *\n * @this {BusPDP10}\n * @param {number} addr\n * @param {number} size\n * @param {number} [pattern]\n */\n zeroMemory(addr, size, pattern)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0 && iBlock < this.aBusBlocks.length) {\n this.aBusBlocks[iBlock].zero(off, size, pattern);\n size -= this.nBlockSize;\n iBlock++;\n off = 0;\n }\n }\n\n /**\n * scanMemory(info, addr, size)\n *\n * Returns a BusInfoPDP10 object for the specified address range.\n *\n * @this {BusPDP10}\n * @param {BusInfoPDP10} [info] previous BusInfoPDP10, if any\n * @param {number} [addr] starting address of range (0 if none provided)\n * @param {number} [size] size of range, in bytes (up to end of address space if none provided)\n * @return {BusInfoPDP10} updated info (or new info if no previous info provided)\n */\n scanMemory(info, addr, size)\n {\n if (addr == null) addr = 0;\n if (size == null) size = (this.addrTotal - addr) | 0;\n if (info == null) info = {cbTotal: 0, cBlocks: 0, aBlocks: []};\n\n var iBlock = addr >>> this.nBlockShift;\n var iBlockMax = ((addr + size - 1) >>> this.nBlockShift);\n\n info.cbTotal = 0;\n info.cBlocks = 0;\n while (iBlock <= iBlockMax) {\n var block = this.aBusBlocks[iBlock];\n info.cbTotal += block.size;\n if (block.size) {\n info.aBlocks.push(/** @type {BlockInfoPDP10} */ (Usr.initBitFields(BlockInfoPDP10, iBlock, 0, 0, block.type)));\n info.cBlocks++\n }\n iBlock++;\n }\n return info;\n }\n\n /**\n * removeMemory(addr, size)\n *\n * Replaces every block in the specified address range with empty Memory blocks that ignore all reads/writes.\n *\n * TODO: Update the removeMemory() interface to reflect the relaxed requirements of the addMemory() interface.\n *\n * @this {BusPDP10}\n * @param {number} addr\n * @param {number} size\n * @return {boolean} true if successful, false if not\n */\n removeMemory(addr, size)\n {\n if (!(addr & this.nBlockLimit) && size && !(size & this.nBlockLimit)) {\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0) {\n var blockOld = this.aBusBlocks[iBlock];\n var blockNew = new MemoryPDP10(this, addr);\n blockNew.copyBreakpoints(this.dbg, blockOld);\n this.aBusBlocks[iBlock++] = blockNew;\n addr = iBlock * this.nBlockSize;\n size -= this.nBlockSize;\n }\n return true;\n }\n return this.reportError(BusPDP10.ERROR.RANGE_INVALID, addr, size);\n }\n\n /**\n * getMemoryBlocks(addr, size)\n *\n * @this {BusPDP10}\n * @param {number} addr is the starting physical address\n * @param {number} size of the request, in bytes\n * @return {Array} of Memory blocks\n */\n getMemoryBlocks(addr, size)\n {\n var aBlocks = [];\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0 && iBlock < this.aBusBlocks.length) {\n aBlocks.push(this.aBusBlocks[iBlock++]);\n size -= this.nBlockSize;\n }\n return aBlocks;\n }\n\n /**\n * setMemoryBlocks(addr, size, aBlocks, type)\n *\n * If no type is specified, then specified address range uses all the provided blocks as-is;\n * this form of setMemoryBlocks() is used for complete physical aliases.\n *\n * Otherwise, new blocks are allocated with the specified type; the underlying memory from the\n * provided blocks is still used, but the new blocks may have different access to that memory.\n *\n * @this {BusPDP10}\n * @param {number} addr is the starting physical address\n * @param {number} size of the request, in bytes\n * @param {Array} aBlocks as returned by getMemoryBlocks()\n * @param {number} [type] is one of the MemoryPDP10.TYPE constants\n */\n setMemoryBlocks(addr, size, aBlocks, type)\n {\n var i = 0;\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0 && iBlock < this.aBusBlocks.length) {\n var block = aBlocks[i++];\n\n if (!block) break;\n if (type !== undefined) {\n var blockNew = new MemoryPDP10(this, addr);\n blockNew.clone(block, type, this.dbg);\n block = blockNew;\n }\n this.aBusBlocks[iBlock++] = block;\n size -= this.nBlockSize;\n }\n }\n\n /**\n * getWord(addr)\n *\n * @this {BusPDP10}\n * @param {number} addr is a physical address\n * @return {number} word (36-bit) value at that address\n */\n getWord(addr)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n return this.aBusBlocks[iBlock].readWord(off, addr);\n }\n\n /**\n * setWord(addr, w)\n *\n * @this {BusPDP10}\n * @param {number} addr is a physical address\n * @param {number} w is the word (36-bit) value to write\n */\n setWord(addr, w)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n this.aBusBlocks[iBlock].writeWord(w, off, addr);\n }\n\n /**\n * getBlockDirect(addr)\n *\n * @this {BusPDP10}\n * @param {number} addr is a physical address\n * @return {MemoryPDP10}\n */\n getBlockDirect(addr)\n {\n return this.aBusBlocks[(addr & this.nBusMask) >>> this.nBlockShift];\n }\n\n /**\n * getWordDirect(addr)\n *\n * This is used for device I/O and Debugger physical memory requests, not the CPU.\n *\n * @this {BusPDP10}\n * @param {number} addr is a physical address\n * @return {number} word (36-bit) value at that address\n */\n getWordDirect(addr)\n {\n var w;\n var off = addr & this.nBlockLimit;\n var block = this.getBlockDirect(addr);\n this.nDisableFaults++;\n w = block.readWordDirect(off, addr);\n this.nDisableFaults--;\n return w;\n }\n\n /**\n * setWordDirect(addr, w)\n *\n * This is used for device I/O and Debugger physical memory requests, not the CPU.\n *\n * @this {BusPDP10}\n * @param {number} addr is a physical address\n * @param {number} w is the word (36-bit) value to write\n */\n setWordDirect(addr, w)\n {\n var off = addr & this.nBlockLimit;\n var block = this.getBlockDirect(addr);\n this.nDisableFaults++;\n block.writeWordDirect(w, off, addr);\n this.nDisableFaults--;\n }\n\n /**\n * addMemBreak(addr, fWrite)\n *\n * @this {BusPDP10}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint\n */\n addMemBreak(addr, fWrite)\n {\n if (DEBUGGER) {\n var iBlock = addr >>> this.nBlockShift;\n this.aBusBlocks[iBlock].addBreakpoint(addr & this.nBlockLimit, fWrite);\n }\n }\n\n /**\n * removeMemBreak(addr, fWrite)\n *\n * @this {BusPDP10}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint\n */\n removeMemBreak(addr, fWrite)\n {\n if (DEBUGGER) {\n var iBlock = addr >>> this.nBlockShift;\n this.aBusBlocks[iBlock].removeBreakpoint(addr & this.nBlockLimit, fWrite);\n }\n }\n\n /**\n * saveMemory(fAll)\n *\n * The only memory blocks we save are those marked as dirty, but most likely all of RAM will have been marked dirty,\n * and even if our dirty-memory flags were as smart as our dirty-sector flags (ie, were set only when a write changed\n * what was already there), it's unlikely that would reduce the number of RAM blocks we must save/restore. At least\n * all the ROM blocks should be clean (except in the unlikely event that the Debugger was used to modify them).\n *\n * All dirty blocks will be stored in a single array, as pairs of block numbers and data arrays, like so:\n *\n * [iBlock0, [dw0, dw1, ...], iBlock1, [dw0, dw1, ...], ...]\n *\n * In a normal 4Kb block, there will be 1K DWORD values in the data array. Remember that each DWORD is a signed 32-bit\n * integer (because they are formed using bitwise operator rather than floating-point math operators), so don't be\n * surprised to see negative numbers in the data.\n *\n * The above example assumes \"uncompressed\" data arrays. If we choose to use \"compressed\" data arrays, the data arrays\n * will look like:\n *\n * [count0, dw0, count1, dw1, ...]\n *\n * where each count indicates how many times the following DWORD value occurs. A data array length less than 1K indicates\n * that it's compressed, since we'll only store them in compressed form if they actually shrank, and we'll use State\n * helper methods compress() and decompress() to create and expand the compressed data arrays.\n *\n * @this {BusPDP10}\n * @param {boolean} [fAll] (true to save all non-ROM memory blocks, regardless of their dirty flags)\n * @return {Array} a\n */\n saveMemory(fAll)\n {\n var i = 0;\n var a = [];\n\n for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {\n var block = this.aBusBlocks[iBlock];\n /*\n * We have to check both fDirty and fDirtyEver, because we may have called cleanMemory() on some of\n * the memory blocks (eg, video memory), and while cleanMemory() will clear a dirty block's fDirty flag,\n * it also sets the dirty block's fDirtyEver flag, which is left set for the lifetime of the machine.\n */\n if (fAll && block.type != MemoryPDP10.TYPE.ROM || block.fDirty || block.fDirtyEver) {\n a[i++] = iBlock;\n a[i++] = State.compress(block.save());\n }\n }\n\n return a;\n }\n\n /**\n * restoreMemory(a)\n *\n * This restores the contents of all Memory blocks; called by CPUState.restore().\n *\n * In theory, we ONLY have to save/restore block contents. Other block attributes,\n * like the type, the memory controller (if any), and the active memory access functions,\n * should already be restored, since every component (re)allocates all the memory blocks\n * it was using when it's restored. And since the CPU is guaranteed to be the last\n * component to be restored, all those blocks (and their attributes) should be in place now.\n *\n * See saveMemory() for more information on how the memory block contents are saved.\n *\n * @this {BusPDP10}\n * @param {Array} a\n * @return {boolean} true if successful, false if not\n */\n restoreMemory(a)\n {\n var i;\n for (i = 0; i < a.length - 1; i += 2) {\n var iBlock = a[i];\n var adw = a[i+1];\n if (adw && adw.length < this.nBlockLen) {\n adw = State.decompress(adw, this.nBlockLen);\n }\n var block = this.aBusBlocks[iBlock];\n if (!block || !block.restore(adw)) {\n /*\n * Either the block to restore hasn't been allocated, indicating a change in the machine\n * configuration since it was last saved (the most likely explanation) or there's some internal\n * inconsistency (eg, the block size is wrong).\n */\n Component.error(\"Unable to restore memory block \" + iBlock);\n return false;\n }\n }\n return true;\n }\n\n /**\n * getMemoryLimit(type)\n *\n * @this {BusPDP10}\n * @param {number} type is one of the MemoryPDP10.TYPE constants\n * @return {number} (the limiting address of the specified memory type, zero if none)\n */\n getMemoryLimit(type)\n {\n var addr = 0;\n for (var iBlock = 0; iBlock < this.aBusBlocks.length; iBlock++) {\n var block = this.aBusBlocks[iBlock];\n if (block.type == type) {\n addr = block.addr + block.used;\n }\n }\n return addr;\n }\n\n /**\n * fault(addr, err, access)\n *\n * Bus interface for signaling alignment errors, invalid memory, etc.\n *\n * @this {BusPDP10}\n * @param {number} addr\n * @param {number} [err]\n * @param {number} [access] (for diagnostic purposes only)\n */\n fault(addr, err, access)\n {\n this.fFault = true;\n if (!this.nDisableFaults) {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP10.FAULT)) {\n this.dbg.printMessage(\"memory fault on \" + this.dbg.toStrBase(addr), true, true);\n }\n this.cpu.haltCPU();\n }\n }\n\n /**\n * checkFault()\n *\n * This also serves as a clearFault() function.\n *\n * @this {BusPDP10}\n * @return {boolean}\n */\n checkFault()\n {\n var f = this.fFault;\n this.fFault = false;\n return f;\n }\n\n /**\n * reportError(errNum, addr, size, fQuiet)\n *\n * @this {BusPDP10}\n * @param {number} errNum\n * @param {number} addr\n * @param {number} size\n * @param {boolean} [fQuiet] (true if any error should be quietly logged)\n * @return {boolean} false\n */\n reportError(errNum, addr, size, fQuiet)\n {\n var sError = \"Memory block error (\" + errNum + \": \" + Str.toHex(addr) + \",\" + Str.toHex(size) + \")\";\n if (fQuiet) {\n if (this.dbg) {\n this.dbg.message(sError);\n } else {\n this.log(sError);\n }\n } else {\n Component.error(sError);\n }\n return false;\n }\n}\n\nBusPDP10.ERROR = {\n RANGE_INUSE: 1,\n RANGE_INVALID: 2\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/device.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass DevicePDP10 extends Component {\n /**\n * DevicePDP10(parmsDevice)\n *\n * @param {Object} parmsDevice\n */\n constructor(parmsDevice)\n {\n super(\"Device\", parmsDevice, MessagesPDP10.DEVICE);\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {DevicePDP10}\n * @param {ComputerPDP10} cmp\n * @param {BusPDP10} bus\n * @param {CPUStatePDP10} cpu\n * @param {DebuggerPDP10} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cmp = cmp;\n this.cpu = cpu;\n this.dbg = dbg;\n\n this.setReady();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {DevicePDP10}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {DevicePDP10}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {DevicePDP10}\n */\n reset()\n {\n }\n\n /**\n * save()\n *\n * This implements save support for the DevicePDP10 component.\n *\n * @this {DevicePDP10}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the DevicePDP10 component.\n *\n * @this {DevicePDP10}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return true;\n }\n\n /**\n * DevicePDP10.init()\n *\n * This function operates on every HTML element of class \"device\", extracting the\n * JSON-encoded parameters for the DevicePDP10 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a DevicePDP10 component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeDevice = Component.getElementsByClass(document, PDP10.APPCLASS, \"device\");\n for (var iDevice = 0; iDevice < aeDevice.length; iDevice++) {\n var device;\n var eDevice = aeDevice[iDevice];\n var parmsDevice = Component.getComponentParms(eDevice);\n switch(parmsDevice['type']) {\n case 'default':\n device = new DevicePDP10(parmsDevice);\n Component.bindComponentControls(device, eDevice, PDP10.APPCLASS);\n break;\n }\n }\n }\n}\n\n/*\n * Initialize all the DevicePDP10 modules on the page.\n */\nWeb.onInit(DevicePDP10.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/memory.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * @class DataView\n * @property {function(number,boolean):number} getUint8\n * @property {function(number,number,boolean)} setUint8\n * @property {function(number,boolean):number} getUint16\n * @property {function(number,number,boolean)} setUint16\n * @property {function(number,boolean):number} getInt32\n * @property {function(number,number,boolean)} setInt32\n */\n\n/**\n * @class MemoryPDP10\n * @property {number} id\n * @property {number} used\n * @property {number} size\n * @property {Array.<number>} aw\n */\nclass MemoryPDP10 {\n /**\n * MemoryPDP10(bus, addr, used, size, type)\n *\n * The Bus component allocates Memory objects so that each has a memory buffer with a\n * block-granular starting address and an address range equal to bus.nBlockSize; however,\n * the size of any given Memory object's underlying buffer can be either zero or bus.nBlockSize;\n * memory read/write functions for empty (buffer-less) blocks are mapped to readNone/writeNone.\n *\n * The Bus allocates empty blocks for the entire address space during initialization, so that\n * any reads/writes to undefined addresses will have no effect. Later, the ROM and RAM\n * components will ask the Bus to allocate memory for specific ranges, and the Bus will allocate\n * as many new blockSize Memory objects as the ranges require. Partial Memory blocks could\n * also be supported in theory, but in practice, they're not.\n *\n * WARNING: Since Memory blocks are low-level objects that have no UI requirements, they\n * do not inherit from the Component class, so if you want to use any Component class methods,\n * such as Component.assert(), use the corresponding Debugger methods instead (assuming a debugger\n * is available).\n *\n * @param {BusPDP10} bus\n * @param {number|null} [addr] of lowest used address in block\n * @param {number} [used] portion of block in words (0 for none)\n * @param {number} [size] of block's buffer in words (0 for none)\n * @param {number} [type] is one of the MemoryPDP10.TYPE constants (default is MemoryPDP10.TYPE.NONE)\n */\n constructor(bus, addr, used, size, type)\n {\n var a, i;\n this.bus = bus;\n this.id = (MemoryPDP10.idBlock += 2);\n this.adw = null;\n this.offset = 0;\n this.addr = addr;\n this.used = used;\n this.size = size || 0;\n this.type = type || MemoryPDP10.TYPE.NONE;\n this.fReadOnly = (type == MemoryPDP10.TYPE.ROM);\n this.dbg = null;\n this.readWord = this.readWordDirect = this.readNone;\n this.writeWord = this.writeWordDirect = this.writeNone;\n this.cReadBreakpoints = this.cWriteBreakpoints = 0;\n this.copyBreakpoints(); // initialize the block's Debugger info; the caller will reinitialize\n\n /*\n * TODO: Study the impact of dirty block tracking. The original purposes were to allow saveMemory()\n * to save only dirty blocks, and to enable the Video component to quickly detect changes to the video buffer.\n *\n * However, a quick test with dirty block tracking disabled didn't yield a noticeable improvement in performance,\n * so I think the overhead of our block-based architecture is swamping the impact of these micro-updates.\n */\n this.fDirty = this.fDirtyEver = false;\n\n /*\n * For empty memory blocks, all we need to do is ensure all access functions are mapped to \"none\" handlers.\n */\n if (!this.size) {\n this.setAccess();\n return;\n }\n\n /*\n * This is the normal case: allocate a buffer that provides a word of data per address;\n * no controller is required because our default memory access functions (see afnMemory)\n * know how to deal with this simple 1-1 mapping of addresses to words.\n *\n * TODO: Consider initializing the memory array to random (or pseudo-random) values in DEBUG\n * mode; pseudo-random might be best, to help make any bugs reproducible.\n */\n a = this.aw = new Array(this.size);\n for (i = 0; i < a.length; i++) a[i] = 0;\n this.setAccess(MemoryPDP10.afnMemory);\n }\n\n /**\n * init(addr)\n *\n * Quick reinitializer when reusing a Memory block.\n *\n * @this {MemoryPDP10}\n * @param {number} addr\n */\n init(addr)\n {\n this.addr = addr;\n }\n\n /**\n * clone(mem, type, dbg)\n *\n * Converts the current Memory block (this) into a clone of the given Memory block (mem),\n * and optionally overrides the current block's type with the specified type.\n *\n * @this {MemoryPDP10}\n * @param {MemoryPDP10} mem\n * @param {number} [type]\n * @param {DebuggerPDP10} [dbg]\n */\n clone(mem, type, dbg)\n {\n /*\n * Original memory block IDs are even; cloned memory block IDs are odd;\n * the original ID of the current block is lost, but that's OK, since it was presumably\n * produced merely to become a clone.\n */\n this.id = mem.id | 0x1;\n this.used = mem.used;\n this.size = mem.size;\n if (type) {\n this.type = type;\n this.fReadOnly = (type == MemoryPDP10.TYPE.ROM);\n }\n this.aw = mem.aw;\n this.setAccess(MemoryPDP10.afnMemory);\n this.copyBreakpoints(dbg, mem);\n }\n\n /**\n * save()\n *\n * This gets the contents of a Memory block as an array of numeric values; used by Bus.saveMemory(),\n * which in turn is called by CPUState.save().\n *\n * @this {MemoryPDP10}\n * @return {Array.<number>|null}\n */\n save()\n {\n return this.aw;\n }\n\n /**\n * restore(aw)\n *\n * This restores the contents of a Memory block from an array of numeric values; used by Bus.restoreMemory(),\n * which is called by CPUState.restore(), after all other components have been restored and thus all Memory\n * blocks have been allocated by their respective components.\n *\n * @this {MemoryPDP10}\n * @param {Array.<number>|null} aw\n * @return {boolean} true if successful, false if block size mismatch\n */\n restore(aw)\n {\n if (aw && this.size == aw.length) {\n this.aw = aw;\n this.fDirty = true;\n return true;\n }\n return false;\n }\n\n /**\n * zero(off, len, pattern)\n *\n * @this {MemoryPDP10}\n * @param {number} [off] (optional starting word offset within block)\n * @param {number} [len] (optional maximum number of words; default is the entire block)\n * @param {number} [pattern] (default is zero)\n */\n zero(off, len, pattern = 0)\n {\n /*\n * NOTE: If len is larger than the block, that's OK, because we also bounds-check the index.\n */\n off = off || 0;\n if (len === undefined) len = this.size;\n\n\n /*\n * Although it's expected that most callers will supply unsigned 36-bit values, we're nice about\n * converting any signed values to their unsigned (two's complement) counterpart, provided they are\n * within the acceptable range. Any values outside that range will be dealt with afterward.\n */\n if (pattern < 0 && pattern >= -PDP10.INT_LIMIT) {\n pattern += PDP10.WORD_LIMIT;\n }\n pattern = Math.trunc(Math.abs(pattern)) % PDP10.WORD_LIMIT;\n\n for (var i = off; len-- && i < this.size; i++) this.writeWordDirect(pattern, off, this.addr + off);\n }\n\n /**\n * setAccess(afn, fDirect)\n *\n * The afn parameter should be a 2-entry function table containing word read and write handlers.\n * See the static afnMemory table for an example.\n *\n * If no function table is specified, a default is selected based on the Memory type; similarly,\n * any undefined entries in the table are filled with default handlers.\n *\n * fDirect indicates that both the default AND the direct handlers should be updated. Direct\n * handlers normally match the default handlers, except when \"checked\" handlers are installed;\n * this allows \"checked\" handlers to know where to dispatch the call after performing checks.\n * Examples of checks are read/write breakpoints, but it's really up to the Debugger to decide\n * what the check consists of.\n *\n * @this {MemoryPDP10}\n * @param {Array.<function()>} [afn] function table\n * @param {boolean} [fDirect] (true to update direct access functions as well; default is true)\n */\n setAccess(afn, fDirect)\n {\n if (!afn) {\n\n afn = MemoryPDP10.afnNone;\n }\n this.setReadAccess(afn, fDirect);\n this.setWriteAccess(afn, fDirect);\n }\n\n /**\n * setReadAccess(afn, fDirect)\n *\n * @this {MemoryPDP10}\n * @param {Array.<function()>} afn\n * @param {boolean} [fDirect]\n */\n setReadAccess(afn, fDirect)\n {\n if (!fDirect || !this.cReadBreakpoints) {\n this.readWord = afn[0] || this.readNone;\n }\n if (fDirect || fDirect === undefined) {\n this.readWordDirect = afn[0] || this.readNone;\n }\n }\n\n /**\n * setWriteAccess(afn, fDirect)\n *\n * @this {MemoryPDP10}\n * @param {Array.<function()>} afn\n * @param {boolean} [fDirect]\n */\n setWriteAccess(afn, fDirect)\n {\n if (!fDirect || !this.cWriteBreakpoints) {\n this.writeWord = !this.fReadOnly && afn[1] || this.writeNone;\n }\n if (fDirect || fDirect === undefined) {\n this.writeWordDirect = afn[1] || this.writeNone;\n }\n }\n\n /**\n * resetReadAccess()\n *\n * @this {MemoryPDP10}\n */\n resetReadAccess()\n {\n this.readWord = this.readWordDirect;\n }\n\n /**\n * resetWriteAccess()\n *\n * @this {MemoryPDP10}\n */\n resetWriteAccess()\n {\n this.writeWord = this.fReadOnly? this.writeNone : this.writeWordDirect;\n }\n\n /**\n * printAddr(sMessage)\n *\n * @this {MemoryPDP10}\n * @param {string} sMessage\n */\n printAddr(sMessage)\n {\n if (DEBUG && this.dbg && this.dbg.messageEnabled(MessagesPDP10.MEMORY)) {\n this.dbg.printMessage(sMessage + ' ' + (this.addr != null? ('@' + this.dbg.toStrBase(this.addr)) : '#' + this.id), true);\n }\n }\n\n /**\n * addBreakpoint(off, fWrite)\n *\n * @this {MemoryPDP10}\n * @param {number} off\n * @param {boolean} fWrite\n */\n addBreakpoint(off, fWrite)\n {\n if (!fWrite) {\n if (this.cReadBreakpoints++ === 0) {\n this.setReadAccess(MemoryPDP10.afnChecked, false);\n }\n if (DEBUG) this.printAddr(\"read breakpoint added to memory block\");\n }\n else {\n if (this.cWriteBreakpoints++ === 0) {\n this.setWriteAccess(MemoryPDP10.afnChecked, false);\n }\n if (DEBUG) this.printAddr(\"write breakpoint added to memory block\");\n }\n }\n\n /**\n * removeBreakpoint(off, fWrite)\n *\n * @this {MemoryPDP10}\n * @param {number} off\n * @param {boolean} fWrite\n */\n removeBreakpoint(off, fWrite)\n {\n if (!fWrite) {\n if (--this.cReadBreakpoints === 0) {\n this.resetReadAccess();\n if (DEBUG) this.printAddr(\"all read breakpoints removed from memory block\");\n }\n\n }\n else {\n if (--this.cWriteBreakpoints === 0) {\n this.resetWriteAccess();\n if (DEBUG) this.printAddr(\"all write breakpoints removed from memory block\");\n }\n\n }\n }\n\n /**\n * copyBreakpoints(dbg, mem)\n *\n * @this {MemoryPDP10}\n * @param {DebuggerPDP10} [dbg]\n * @param {MemoryPDP10} [mem] (outgoing MemoryPDP10 block to copy breakpoints from, if any)\n */\n copyBreakpoints(dbg, mem)\n {\n this.dbg = dbg;\n this.cReadBreakpoints = this.cWriteBreakpoints = 0;\n if (mem) {\n if ((this.cReadBreakpoints = mem.cReadBreakpoints)) {\n this.setReadAccess(MemoryPDP10.afnChecked, false);\n }\n if ((this.cWriteBreakpoints = mem.cWriteBreakpoints)) {\n this.setWriteAccess(MemoryPDP10.afnChecked, false);\n }\n }\n }\n\n /**\n * readNone(off, addr)\n *\n * @this {MemoryPDP10}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readNone(off, addr)\n {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP10.MEMORY) /* && !off */) {\n this.dbg.printMessage(\"attempt to read invalid address \" + this.dbg.toStrBase(addr), true);\n }\n this.bus.fault(addr);\n return PDP10.WORD_INVALID;\n }\n\n /**\n * writeNone(v, off, addr)\n *\n * @this {MemoryPDP10}\n * @param {number} v\n * @param {number} off\n * @param {number} addr\n */\n writeNone(v, off, addr)\n {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP10.MEMORY) /* && !off */) {\n this.dbg.printMessage(\"attempt to write \" + this.dbg.toStrBase(v) + \" to invalid addresses \" + this.dbg.toStrBase(addr), true);\n }\n this.bus.fault(addr);\n }\n\n /**\n * readWordMemory(off, addr)\n *\n * @this {MemoryPDP10}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readWordMemory(off, addr)\n {\n var w = this.aw[off];\n\n return w;\n }\n\n /**\n * writeWordMemory(w, off, addr)\n *\n * @this {MemoryPDP10}\n * @param {number} w\n * @param {number} off\n * @param {number} addr\n */\n writeWordMemory(w, off, addr)\n {\n\n if (this.aw[off] != w) {\n this.aw[off] = w;\n this.fDirty = true;\n }\n }\n\n /**\n * readWordChecked(off, addr)\n *\n * @this {MemoryPDP10}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readWordChecked(off, addr)\n {\n if (DEBUGGER && this.dbg && this.addr != null) {\n this.dbg.checkMemoryRead(this.addr + off, 2);\n }\n return this.readWordDirect(off, addr);\n }\n\n /**\n * writeWordChecked(w, off, addr)\n *\n * @this {MemoryPDP10}\n * @param {number} w\n * @param {number} off\n * @param {number} addr\n */\n writeWordChecked(w, off, addr)\n {\n if (DEBUGGER && this.dbg && this.addr != null) {\n this.dbg.checkMemoryWrite(this.addr + off, 2)\n }\n if (this.fReadOnly) this.writeNone(w, off, addr); else this.writeWordDirect(w, off, addr);\n }\n}\n\n/*\n * Basic memory types\n *\n * RAM is the most conventional memory type, providing full read/write capability. ROM is equally\n * conventional, except that the fReadOnly property is set. ROM can be written using the Bus setWordDirect()\n * interface (which in turn uses the Memory writeWordDirect() interface), allowing the ROM component to\n * initialize its own memory.\n */\nMemoryPDP10.TYPE = {\n NONE: 0,\n RAM: 1,\n ROM: 2\n};\nMemoryPDP10.TYPE_COLORS = [\"black\", \"blue\", \"green\"];\nMemoryPDP10.TYPE_NAMES = [\"NONE\", \"RAM\", \"ROM\"];\n\n/*\n * Last used block ID (used for debugging only)\n */\nMemoryPDP10.idBlock = 0;\n\n/*\n * This is the effective definition of afnNone, but we need not fully define it, because setAccess()\n * uses these defaults when any of the handlers are undefined.\n *\nMemoryPDP10.afnNone = [\n MemoryPDP10.prototype.readNone,\n MemoryPDP10.prototype.writeNone\n];\n */\nMemoryPDP10.afnNone = [];\n\nMemoryPDP10.afnMemory = [\n MemoryPDP10.prototype.readWordMemory,\n MemoryPDP10.prototype.writeWordMemory\n];\n\nMemoryPDP10.afnChecked = [\n MemoryPDP10.prototype.readWordChecked,\n MemoryPDP10.prototype.writeWordChecked\n];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/cpu.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * @class CPUPDP10\n * @unrestricted\n */\nclass CPUPDP10 extends Component {\n /**\n * CPUPDP10(parmsCPU, nCyclesDefault)\n *\n * The CPUPDP10 class supports the following (parmsCPU) properties:\n *\n * cycles: the machine's base cycles per second; the CPUStatePDP10 constructor\n * will provide us with a default (based on the CPU model) to use as a fallback.\n *\n * multiplier: base cycle multiplier; default is 1.\n *\n * autoStart: true to automatically start, false to not, or null if \"it depends\";\n * null is the default, which means do not autostart UNLESS there is no Debugger\n * and no \"Run\" button (ie, no way to manually start the machine).\n *\n * csStart: the number of cycles that runCPU() must wait before generating\n * checksum records; -1 if disabled. checksum records are a diagnostic aid\n * used to help compare one CPU run to another.\n *\n * csInterval: the number of cycles that runCPU() must execute before generating\n * a checksum record; -1 if disabled.\n *\n * csStop: the number of cycles to stop generating checksum records.\n *\n * This component is primarily responsible for interfacing the CPU with the outside\n * world (eg, Panel and Debugger components), and managing overall CPU operation.\n *\n * It is extended by the CPUStatePDP10 component, where the simulation control logic resides.\n *\n * @param {Object} parmsCPU\n * @param {number} nCyclesDefault\n */\n constructor(parmsCPU, nCyclesDefault)\n {\n super(\"CPU\", parmsCPU, MessagesPDP10.CPU);\n\n var nCycles = +parmsCPU['cycles'] || nCyclesDefault;\n\n var nMultiplier = +parmsCPU['multiplier'] || 1;\n\n this.nDisplayCount = 0;\n this.nDisplayLimit = 30;\n this.nCyclesPerSecond = nCycles;\n\n /*\n * nCyclesMultiplier replaces the old \"speed\" variable (0, 1, 2) and eliminates the need for\n * the constants (SPEED_SLOW, SPEED_FAST and SPEED_MAX). The UI simply doubles the multiplier\n * until we've exceeded the host's speed limit and then starts the multiplier over at 1.\n */\n this.nCyclesMultiplier = nMultiplier;\n this.mhzDefault = Math.round(this.nCyclesPerSecond / 10000) / 100;\n this.mhzTarget = this.mhzDefault * this.nCyclesMultiplier;\n this.msPerYield = this.nCyclesPerYield = this.nCyclesNextYield = this.nCyclesRecalc = 0;\n\n /*\n * We add a number of flags to the set initialized by Component\n */\n this.flags.running = this.flags.starting = false;\n this.flags.autoStart = parmsCPU['autoStart'];\n if (typeof this.flags.autoStart == \"string\") this.flags.autoStart = (this.flags.autoStart == \"true\");\n\n /*\n * Get checksum parameters, if any. runCPU() behavior is not affected until fChecksum\n * is true, which won't happen until resetChecksum() is called with nCyclesChecksumInterval\n * (\"csInterval\") set to a positive value.\n *\n * As above, any of these parameters can also be set with the Debugger's execution options\n * command (\"x\"); for example, \"x cs int 5000\" will set nCyclesChecksumInterval to 5000\n * and call resetChecksum().\n */\n this.flags.checksum = false;\n this.nChecksum = this.nCyclesChecksumNext = 0;\n this.nCyclesChecksumStart = +parmsCPU[\"csStart\"];\n this.nCyclesChecksumInterval = +parmsCPU[\"csInterval\"];\n this.nCyclesChecksumStop = +parmsCPU[\"csStop\"];\n\n /*\n * Array of countdown timers managed by addTimer() and setTimer().\n */\n this.aTimers = [];\n\n this.onRunTimeout = this.runCPU.bind(this); // function onRunTimeout() { cpu.runCPU(); };\n\n /*\n * Define the rest of the properties used by the class\n */\n this.mhz = 0;\n this.nYieldsSinceStatusUpdate = 0;\n this.msStartRun = this.msStartThisRun = this.msEndThisRun = this.nCyclesThisRun = 0;\n this.nTotalCycles = this.nRunCycles = this.nBurstCycles = this.nStepCycles = this.nSnapCycles = 0;\n this.panel = null;\n\n this.setReady();\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {CPUPDP10}\n * @param {ComputerPDP10} cmp\n * @param {BusPDP10} bus\n * @param {CPUPDP10} cpu\n * @param {DebuggerPDP10} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.dbg = dbg;\n this.panel = cmp.panel;\n for (var i = 0; i < CPUPDP10.BUTTONS.length; i++) {\n var control = this.bindings[CPUPDP10.BUTTONS[i]];\n if (control) this.cmp.setBinding(null, CPUPDP10.BUTTONS[i], control);\n }\n this.setReady();\n }\n\n /**\n * reset()\n *\n * Stub for reset notification (overridden by the CPUStatePDP10 component).\n *\n * @this {CPUPDP10}\n */\n reset()\n {\n }\n\n /**\n * save()\n *\n * Stub for save support (overridden by the CPUStatePDP10 component).\n *\n * @this {CPUPDP10}\n * @return {Object|null}\n */\n save()\n {\n return null;\n }\n\n /**\n * restore(data)\n *\n * Stub for restore support (overridden by the CPUStatePDP10 component).\n *\n * @this {CPUPDP10}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n return false;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {CPUPDP10}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n /*\n * We've already saved the parmsCPU 'autoStart' setting, but there may be a machine (or URL) override.\n */\n var sAutoStart = this.cmp.getMachineParm('autoStart');\n if (sAutoStart != null) {\n this.flags.autoStart = (sAutoStart == \"true\"? true : (sAutoStart == \"false\"? false : !!sAutoStart));\n }\n else if (this.flags.autoStart == null) {\n /*\n * If there's no explicit parmsCPU setting either, then we will autoStart if there's no Debugger and\n * no \"Run\" button.\n */\n this.flags.autoStart = ((!DEBUGGER || !this.dbg) && this.bindings[\"run\"] === undefined);\n }\n\n if (!fRepower) {\n if (!data) {\n this.reset();\n } else {\n this.resetCycles();\n if (!this.restore(data)) return false;\n this.resetChecksum();\n }\n /*\n * Give the Debugger a chance to do/print something once we've powered up.\n */\n if (DEBUGGER && this.dbg) {\n this.dbg.init(this.flags.autoStart);\n } else {\n this.status(\"No debugger detected\");\n }\n if (!this.flags.autoStart) {\n this.println(\"CPU will not be auto-started \" + (this.panel? \"(click Run to start)\" : \"(type 'go' to start)\"));\n }\n }\n /*\n * The Computer component (which is responsible for all powerDown and powerUp notifications)\n * is now responsible for managing a component's fPowered flag, not us.\n *\n * this.flags.powered = true;\n */\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {CPUPDP10}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * autoStart()\n *\n * @this {CPUPDP10}\n * @return {boolean} true if started, false if not\n */\n autoStart()\n {\n if (this.flags.running) {\n return true;\n }\n if (this.flags.autoStart) {\n /*\n * We used to also set fUpdateFocus when calling startCPU(), on the assumption that in the \"auto-starting\"\n * context, a machine without focus is like a day without sunshine, but in reality, focus should only be\n * forced when the user takes some other machine-related action.\n */\n this.startCPU();\n return true;\n }\n return false;\n }\n\n /**\n * isPowered()\n *\n * @this {CPUPDP10}\n * @return {boolean}\n */\n isPowered()\n {\n if (!this.flags.powered) {\n this.println(this.toString() + \" not powered\");\n return false;\n }\n return true;\n }\n\n /**\n * isRunning()\n *\n * @this {CPUPDP10}\n * @return {boolean}\n */\n isRunning()\n {\n return this.flags.running;\n }\n\n /**\n * getChecksum()\n *\n * This will be implemented by the CPUStatePDP10 component.\n *\n * @this {CPUPDP10}\n * @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code)\n */\n getChecksum()\n {\n return 0;\n }\n\n /**\n * resetChecksum()\n *\n * If checksum generation is enabled (fChecksum is true), this resets the running 32-bit checksum and the\n * cycle counter that will trigger the next displayChecksum(); called by resetCycles(), which is called whenever\n * the CPU is reset or restored.\n *\n * @this {CPUPDP10}\n * @return {boolean} true if checksum generation enabled, false if not\n */\n resetChecksum()\n {\n if (this.nCyclesChecksumStart === undefined) this.nCyclesChecksumStart = 0;\n if (this.nCyclesChecksumInterval === undefined) this.nCyclesChecksumInterval = -1;\n if (this.nCyclesChecksumStop === undefined) this.nCyclesChecksumStop = -1;\n this.flags.checksum = (this.nCyclesChecksumStart >= 0 && this.nCyclesChecksumInterval > 0);\n if (this.flags.checksum) {\n this.nChecksum = 0;\n this.nCyclesChecksumNext = this.nCyclesChecksumStart - this.nTotalCycles;\n /*\n * this.nCyclesChecksumNext = this.nCyclesChecksumStart + this.nCyclesChecksumInterval -\n * (this.nTotalCycles % this.nCyclesChecksumInterval);\n */\n return true;\n }\n return false;\n }\n\n /**\n * updateChecksum(nCycles)\n *\n * When checksum generation is enabled (fChecksum is true), runCPU() asks stepCPU() to execute a minimum\n * number of cycles (1), effectively limiting execution to a single instruction, and then we're called with\n * the exact number cycles that were actually executed. This should give us instruction-granular checksums\n * at precise intervals that are 100% repeatable.\n *\n * @this {CPUPDP10}\n * @param {number} nCycles\n */\n updateChecksum(nCycles)\n {\n if (this.flags.checksum) {\n /*\n * Get a 32-bit summation of the current CPU state and add it to our running 32-bit checksum\n */\n var fDisplay = false;\n this.nChecksum = (this.nChecksum + this.getChecksum())|0;\n this.nCyclesChecksumNext -= nCycles;\n if (this.nCyclesChecksumNext <= 0) {\n this.nCyclesChecksumNext += this.nCyclesChecksumInterval;\n fDisplay = true;\n }\n if (this.nCyclesChecksumStop >= 0) {\n if (this.nCyclesChecksumStop <= this.getCycles()) {\n this.nCyclesChecksumInterval = this.nCyclesChecksumStop = -1;\n this.resetChecksum();\n this.stopCPU();\n fDisplay = true;\n }\n }\n if (fDisplay) this.displayChecksum();\n }\n }\n\n /**\n * displayChecksum()\n *\n * When checksum generation is enabled (fChecksum is true), this is called to provide a crude log of all\n * checksums generated at the specified cycle intervals, as specified by the \"csStart\" and \"csInterval\" parmsCPU\n * properties).\n *\n * @this {CPUPDP10}\n */\n displayChecksum()\n {\n this.println(this.getCycles() + \" cycles: \" + \"checksum=\" + Str.toHex(this.nChecksum));\n }\n\n /**\n * setBinding(sType, sBinding, control, sValue)\n *\n * @this {CPUPDP10}\n * @param {string|null} sType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"run\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sType, sBinding, control, sValue)\n {\n var cpu = this;\n\n switch (sBinding) {\n case \"power\":\n case \"reset\":\n /*\n * The \"power\" and \"reset\" buttons are functions of the entire computer, not just the CPU,\n * but it's not always convenient to stick a power button in the Computer component definition,\n * so we record those bindings here and pass them on to the Computer component in initBus().\n */\n this.bindings[sBinding] = control;\n return true;\n\n case \"run\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickRun() {\n if (!cpu.cmp || !cpu.cmp.checkPower()) return;\n /*\n * We no longer pass true to these startCPU()/stopCPU() calls, on the theory that if the \"run\"\n * control is visible, then the computer is probably sufficiently visible as well; the problem\n * with setting fUpdateFocus to true is that it can jerk the web page around in annoying ways.\n */\n if (!cpu.flags.running)\n cpu.startCPU();\n else\n cpu.stopCPU();\n };\n return true;\n\n case \"speed\":\n this.bindings[sBinding] = control;\n return true;\n\n case \"setSpeed\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickSetSpeed() {\n cpu.setSpeed(cpu.nCyclesMultiplier << 1, true);\n };\n control.textContent = this.getSpeedTarget();\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * updateDisplays(nUpdate)\n *\n * Simpler wrapper around the Computer's updateDisplays() method.\n *\n * @this {CPUPDP10}\n * @param {number} [nUpdate] (1 for periodic, -1 for forced, 0 or undefined otherwise)\n */\n updateDisplays(nUpdate)\n {\n if (this.cmp) this.cmp.updateDisplays(nUpdate);\n }\n\n /**\n * updateDisplay(nUpdate)\n *\n * Some of the CPU bindings provide feedback and therefore need to be updated periodically.\n * However, this should be called via the Computer's updateDisplays() interface, not directly.\n *\n * @this {CPUPDP10}\n * @param {number} [nUpdate] (1 for periodic, -1 for forced, 0 otherwise)\n */\n updateDisplay(nUpdate)\n {\n var controlSpeed = this.bindings[\"speed\"];\n if (controlSpeed) {\n if (nUpdate <= 0 || (this.nDisplayCount += nUpdate) >= this.nDisplayLimit) {\n controlSpeed.textContent = this.getSpeedCurrent();\n this.nDisplayCount = 0;\n }\n }\n }\n\n /**\n * addCycles(nCycles, fEndStep)\n *\n * @this {CPUPDP10}\n * @param {number} nCycles\n * @param {boolean} [fEndStep]\n */\n addCycles(nCycles, fEndStep)\n {\n this.nTotalCycles += nCycles;\n if (fEndStep) {\n this.nBurstCycles = this.nStepCycles = this.nSnapCycles = 0;\n }\n }\n\n /**\n * calcCycles(fRecalc)\n *\n * Calculate the number of cycles to process for each \"burst\" of CPU activity. The size of a burst\n * is driven by YIELDS_PER_SECOND (eg, 30).\n *\n * At the end of each burst, we subtract burst cycles from the yield cycle \"threshold\" counter.\n * Whenever the \"next yield\" cycle counter goes to (or below) zero, we compare elapsed time to the time\n * we expected the virtual hardware to take (eg, 1000ms/50 or 20ms), and if we still have time remaining,\n * we sleep the remaining time (or 0ms if there's no remaining time), and then restart runCPU().\n *\n * @this {CPUPDP10}\n * @param {boolean} [fRecalc] is true if the caller wants to recalculate thresholds based on the most recent\n * speed calculation (see calcSpeed).\n */\n calcCycles(fRecalc)\n {\n /*\n * Calculate \"per\" yield values.\n */\n var vMultiplier = 1;\n if (fRecalc) {\n if (this.nCyclesMultiplier > 1 && this.mhz) {\n vMultiplier = (this.mhz / this.mhzDefault);\n }\n }\n\n this.msPerYield = Math.round(1000 / CPUPDP10.YIELDS_PER_SECOND);\n this.nCyclesPerYield = Math.floor(this.nCyclesPerSecond / CPUPDP10.YIELDS_PER_SECOND * vMultiplier);\n\n /*\n * And initialize \"next\" yield values to the \"per\" values.\n */\n if (!fRecalc) this.nCyclesNextYield = this.nCyclesPerYield;\n this.nCyclesRecalc = 0;\n }\n\n /**\n * getCycles(fScaled)\n *\n * getCycles() returns the number of cycles executed so far. Note that we can be called after\n * runCPU() OR during runCPU(), perhaps from a handler triggered during the current run's stepCPU(),\n * so nRunCycles must always be adjusted by number of cycles stepCPU() was asked to run (nBurstCycles),\n * less the number of cycles it has yet to run (nStepCycles).\n *\n * nRunCycles is zeroed whenever the CPU is halted or the CPU speed is changed, which is why we also\n * have nTotalCycles, which accumulates all nRunCycles before we zero it. However, nRunCycles and\n * nTotalCycles eventually get reset by calcSpeed(), to avoid overflow, so components that rely on\n * getCycles() returning steadily increasing values should also be prepared for a reset at any time.\n *\n * @this {CPUPDP10}\n * @param {boolean} [fScaled] is true if the caller wants a cycle count relative to a multiplier of 1\n * @return {number}\n */\n getCycles(fScaled)\n {\n var nCycles = this.nTotalCycles + this.nRunCycles + this.nBurstCycles - this.nStepCycles;\n if (fScaled && this.nCyclesMultiplier > 1 && this.mhz > this.mhzDefault) {\n /*\n * We could scale the current cycle count by the current effective speed (this.mhz); eg:\n *\n * nCycles = Math.round(nCycles / (this.mhz / this.mhzDefault));\n *\n * but that speed will fluctuate somewhat: large fluctuations at first, but increasingly smaller\n * fluctuations after each burst of instructions that runCPU() executes.\n *\n * Alternatively, we can scale the cycle count by the multiplier, which is good in that the\n * multiplier doesn't vary once the user changes it, but a potential downside is that the\n * multiplier might be set too high, resulting in a target speed that's higher than the effective\n * speed is able to reach.\n *\n * Also, if multipliers were always limited to a power-of-two, then this could be calculated\n * with a simple shift. However, only the \"setSpeed\" UI binding limits it that way; the Debugger\n * interface allows any value, as does the CPU \"multiplier\" parmsCPU property (from the machine's\n * XML file).\n */\n nCycles = Math.round(nCycles / this.nCyclesMultiplier);\n }\n return nCycles;\n }\n\n /**\n * getCyclesPerSecond()\n *\n * This returns the CPU's \"base\" speed (ie, the original cycles per second defined for the machine)\n *\n * @this {CPUPDP10}\n * @return {number}\n */\n getCyclesPerSecond()\n {\n return this.nCyclesPerSecond;\n }\n\n /**\n * resetCycles()\n *\n * Resets speed and cycle information as part of any reset() or restore(); this typically occurs during powerUp().\n * It's important that this be called BEFORE the actual restore() call, because restore() may want to call setSpeed(),\n * which in turn assumes that all the cycle counts have been initialized to sensible values.\n *\n * @this {CPUPDP10}\n */\n resetCycles()\n {\n this.mhz = 0;\n this.nYieldsSinceStatusUpdate = 0;\n this.nTotalCycles = this.nRunCycles = this.nBurstCycles = this.nStepCycles = this.nSnapCycles = 0;\n this.resetChecksum();\n this.setSpeed(1);\n }\n\n /**\n * getSpeed()\n *\n * @this {CPUPDP10}\n * @return {number} the current speed multiplier\n */\n getSpeed()\n {\n return this.nCyclesMultiplier;\n }\n\n /**\n * getSpeedCurrent()\n *\n * @this {CPUPDP10}\n * @return {string} the current speed, in mhz, as a string formatted to two decimal places\n */\n getSpeedCurrent()\n {\n /*\n * TODO: Has toFixed() been \"fixed\" in all browsers (eg, IE) to return a rounded value now?\n */\n return ((this.flags.running)? (this.mhz.toFixed(2) + \"Mhz\") : \"Stopped\");\n }\n\n /**\n * getSpeedTarget()\n *\n * @this {CPUPDP10}\n * @return {string} the target speed, in mhz, as a string formatted to two decimal places\n */\n getSpeedTarget()\n {\n /*\n * TODO: Has toFixed() been \"fixed\" in all browsers (eg, IE) to return a rounded value now?\n */\n return this.mhzTarget.toFixed(2) + \"Mhz\";\n }\n\n /**\n * setSpeed(nMultiplier, fUpdateFocus)\n *\n * NOTE: This used to return the target speed, in mhz, but no callers appear to care at this point.\n *\n * @desc Whenever the speed is changed, the running cycle count and corresponding start time must be reset,\n * so that the next effective speed calculation obtains sensible results. In fact, when runCPU() initially calls\n * setSpeed() with no parameters, that's all this function does (it doesn't change the current speed setting).\n *\n * @this {CPUPDP10}\n * @param {number} [nMultiplier] is the new proposed multiplier (reverts to 1 if the target was too high)\n * @param {boolean} [fUpdateFocus] is true to update Computer focus\n * @return {boolean} true if successful, false if not\n */\n setSpeed(nMultiplier, fUpdateFocus)\n {\n var fSuccess = false;\n if (nMultiplier !== undefined) {\n /*\n * If we haven't reached 80% (0.8) of the current target speed, revert to a multiplier of one (1).\n */\n if (this.mhz / this.mhzTarget < 0.8) {\n nMultiplier = 1;\n } else {\n fSuccess = true;\n }\n this.nCyclesMultiplier = nMultiplier;\n var mhz = this.mhzDefault * this.nCyclesMultiplier;\n if (this.mhzTarget != mhz) {\n this.mhzTarget = mhz;\n var sSpeed = this.getSpeedTarget();\n var controlSpeed = this.bindings[\"setSpeed\"];\n if (controlSpeed) controlSpeed.textContent = sSpeed;\n this.println(\"target speed: \" + sSpeed);\n }\n if (fUpdateFocus && this.cmp) this.cmp.setFocus();\n }\n this.addCycles(this.nRunCycles);\n this.nRunCycles = 0;\n this.msStartRun = Component.getTime();\n this.msEndThisRun = 0;\n this.calcCycles();\n return fSuccess;\n }\n\n /**\n * calcSpeed(nCycles, msElapsed)\n *\n * @this {CPUPDP10}\n * @param {number} nCycles\n * @param {number} msElapsed\n */\n calcSpeed(nCycles, msElapsed)\n {\n if (msElapsed) {\n this.mhz = Math.round(nCycles / (msElapsed * 10)) / 100;\n if (msElapsed >= 86400000) {\n this.nTotalCycles = 0;\n this.setSpeed(); // reset all counters once per day so that we never have to worry about overflow\n }\n }\n }\n\n /**\n * calcStartTime()\n *\n * @this {CPUPDP10}\n */\n calcStartTime()\n {\n if (this.nCyclesRecalc >= this.nCyclesPerSecond) {\n this.calcCycles(true);\n }\n this.nCyclesThisRun = 0;\n this.msStartThisRun = Component.getTime();\n\n /*\n * Try to detect situations where the browser may have throttled us, such as when the user switches\n * to a different tab; in those situations, Chrome and Safari may restrict setTimeout() callbacks\n * to roughly one per second.\n *\n * Another scenario: the user resizes the browser window. setTimeout() callbacks are not throttled,\n * but there can still be enough of a lag between the callbacks that CPU speed will be noticeably\n * erratic if we don't compensate for it here.\n *\n * We can detect throttling/lagging by verifying that msEndThisRun (which was set at the end of the\n * previous run and includes any requested sleep time) is comparable to the current msStartThisRun;\n * if the delta is significant, we compensate by bumping msStartRun forward by that delta.\n *\n * This shouldn't be triggered when the Debugger halts the CPU, because setSpeed() -- which is called\n * whenever the CPU starts running again -- zeroes msEndThisRun.\n *\n * This also won't do anything about other internal delays; for example, Debugger message() calls.\n * By the time the message() function has called yieldCPU(), the cost of the message has already been\n * incurred, so it will be end up being charged against the instruction(s) that triggered it.\n *\n * TODO: Consider calling yieldCPU() sooner from message(), so that it can arrange for the msEndThisRun\n * \"snapshot\" to occur sooner; it's unclear, however, whether that will really improve the CPU's ability\n * to hit its target speed, since you would expect any instruction that displays a message to be an\n * EXTREMELY slow instruction.\n */\n if (this.msEndThisRun) {\n var msDelta = this.msStartThisRun - this.msEndThisRun;\n if (msDelta > this.msPerYield) {\n if (MAXDEBUG) this.println(\"large time delay: \" + msDelta + \"ms\");\n this.msStartRun += msDelta;\n /*\n * Bumping msStartRun forward should NEVER cause it to exceed msStartThisRun; however, just\n * in case, I make absolutely sure it cannot happen, since doing so could result in negative\n * speed calculations.\n */\n\n if (this.msStartRun > this.msStartThisRun) {\n this.msStartRun = this.msStartThisRun;\n }\n }\n }\n }\n\n /**\n * calcRemainingTime()\n *\n * @this {CPUPDP10}\n * @return {number}\n */\n calcRemainingTime()\n {\n this.msEndThisRun = Component.getTime();\n\n var msYield = this.msPerYield;\n if (this.nCyclesThisRun) {\n /*\n * Normally, we would assume we executed a full quota of work over msPerYield, but since the CPU\n * now has the option of calling yieldCPU(), that might not be true. If nCyclesThisRun is correct, then\n * the ratio of nCyclesThisRun/nCyclesPerYield should represent the percentage of work we performed,\n * and so applying that percentage to msPerYield should give us a better estimate of work vs. time.\n */\n msYield = Math.round(msYield * this.nCyclesThisRun / this.nCyclesPerYield);\n }\n\n var msElapsedThisRun = this.msEndThisRun - this.msStartThisRun;\n var msRemainsThisRun = msYield - msElapsedThisRun;\n\n /*\n * We could pass only \"this run\" results to calcSpeed():\n *\n * nCycles = this.nCyclesThisRun;\n * msElapsed = msElapsedThisRun;\n *\n * but it seems preferable to use longer time periods and hopefully get a more accurate speed.\n *\n * Also, if msRemainsThisRun >= 0 && this.nCyclesMultiplier == 1, we could pass these results instead:\n *\n * nCycles = this.nCyclesThisRun;\n * msElapsed = this.msPerYield;\n *\n * to insure that we display a smooth, constant N Mhz. But for now, I prefer seeing any fluctuations.\n */\n var nCycles = this.nRunCycles;\n var msElapsed = this.msEndThisRun - this.msStartRun;\n\n if (MAXDEBUG && msRemainsThisRun < 0 && this.nCyclesMultiplier > 1) {\n this.println(\"warning: updates @\" + msElapsedThisRun + \"ms (prefer \" + Math.round(msYield) + \"ms)\");\n }\n\n this.calcSpeed(nCycles, msElapsed);\n\n if (msRemainsThisRun < 0 || this.mhz < this.mhzTarget) {\n /*\n * Try \"throwing out\" the effects of large anomalies, by moving the overall run start time up;\n * ordinarily, this should only happen when the someone is using an external Debugger or some other\n * tool or feature that is interfering with our overall execution.\n */\n if (msRemainsThisRun < -1000) {\n this.msStartRun -= msRemainsThisRun;\n }\n /*\n * If the last burst took MORE time than we allotted (ie, it's taking more than 1 second to simulate\n * nCyclesPerSecond), all we can do is yield for as little time as possible (ie, 0ms) and hope that the\n * simulation is at least usable.\n */\n msRemainsThisRun = 0;\n }\n\n /*\n * Last but not least, update nCyclesRecalc, so that when runCPU() starts up again and calls calcStartTime(),\n * it'll be ready to decide if calcCycles() should be called again.\n */\n this.nCyclesRecalc += this.nCyclesThisRun;\n\n if (DEBUG && this.messageEnabled(MessagesPDP10.LOG) && msRemainsThisRun) {\n this.log(\"calcRemainingTime: \" + msRemainsThisRun + \"ms to sleep after \" + this.msEndThisRun + \"ms\");\n }\n\n this.msEndThisRun += msRemainsThisRun;\n return msRemainsThisRun;\n }\n\n /**\n * addTimer(callBack)\n *\n * Components that want to have timers that periodically fire after some number of milliseconds call\n * addTimer() to create the timer, and then setTimer() every time they want to arm it. There is currently\n * no removeTimer() because these are generally used for the entire lifetime of a component.\n *\n * Internally, each timer entry is a preallocated Array with two entries: a cycle countdown in element [0]\n * and a callback function in element [1]. A timer is initially dormant; dormant timers have a countdown\n * value of -1 (although any negative number will suffice) and active timers have a non-negative value.\n *\n * Why not use JavaScript's setTimeout() instead? Good question. For a good answer, see setTimer() below.\n *\n * TODO: Consider making the addTimer() and setTimer() interfaces more like the addIRQ() and setIRQ()\n * interfaces (which return the underlying object instead of an array index) and maintaining a separate list\n * of active timers, in order of highest to lowest cycle countdown values, as this could speed up\n * getBurstCycles() and updateTimers() functions ever so slightly.\n *\n * @this {CPUPDP10}\n * @param {function()} callBack\n * @return {number} timer index\n */\n addTimer(callBack)\n {\n var iTimer = this.aTimers.length;\n this.aTimers.push([-1, callBack]);\n return iTimer;\n }\n\n /**\n * setTimer(iTimer, ms, fReset)\n *\n * Using the timer index from a previous addTimer() call, this sets that timer to fire after the\n * specified number of milliseconds.\n *\n * This is preferred over JavaScript's setTimeout(), because all our timers are effectively paused when\n * the CPU is paused (eg, when the Debugger halts execution). Moreover, setTimeout() handlers only run after\n * runCPU() yields, which is far too granular for some components (eg, when the SerialPort tries to simulate\n * interrupts at 9600 baud).\n *\n * Ideally, the only function that would use setTimeout() is runCPU(), while the rest of the components\n * use setTimer(); however, due to legacy code (ie, code that predates these functions) and/or laziness,\n * that may not be the case.\n *\n * @this {CPUPDP10}\n * @param {number} iTimer\n * @param {number} ms (converted into a cycle countdown internally)\n * @param {boolean} [fReset] (true if the timer should be reset even if already armed)\n * @return {number} (number of cycles used to arm timer, or -1 if error)\n */\n setTimer(iTimer, ms, fReset)\n {\n var nCycles = -1;\n if (iTimer >= 0 && iTimer < this.aTimers.length) {\n if (fReset || this.aTimers[iTimer][0] < 0) {\n nCycles = this.getMSCycles(ms);\n /*\n * We must now confront the following problem: if the CPU is currently executing a burst of cycles,\n * the number of cycles it has executed in that burst so far must NOT be charged against the cycle\n * timeout we're about to set. The simplest way to resolve that is to immediately call endBurst()\n * and bias the cycle timeout by the number of cycles that the burst executed.\n */\n if (this.flags.running) {\n nCycles += this.endBurst();\n }\n this.aTimers[iTimer][0] = nCycles;\n }\n }\n return nCycles;\n }\n\n /**\n * getMSCycles(ms)\n *\n * @this {CPUPDP10}\n * @param {number} ms\n * @return {number} number of corresponding cycles\n */\n getMSCycles(ms)\n {\n return ((this.nCyclesPerSecond * this.nCyclesMultiplier) / 1000 * ms)|0;\n }\n\n /**\n * getBurstCycles(nCycles)\n *\n * Used by runCPU() to get min(nCycles,[timer cycle counts])\n *\n * @this {CPUPDP10}\n * @param {number} nCycles (number of cycles about to execute)\n * @return {number} (either nCycles or less if a timer needs to fire)\n */\n getBurstCycles(nCycles)\n {\n for (var i = this.aTimers.length - 1; i >= 0; i--) {\n var timer = this.aTimers[i];\n\n if (timer[0] < 0) continue;\n if (nCycles > timer[0]) {\n nCycles = timer[0];\n }\n }\n return nCycles;\n }\n\n /**\n * saveTimers()\n *\n * @this {CPUPDP10}\n * @return {Array.<number>}\n */\n saveTimers()\n {\n var aTimerCycles = [];\n for (var i = 0; i < this.aTimers.length; i++) {\n var timer = this.aTimers[i];\n aTimerCycles.push(timer[0]);\n }\n return aTimerCycles;\n }\n\n /**\n * restoreTimers(aTimerCycles)\n *\n * @this {CPUPDP10}\n * @param {Array.<number>} aTimerCycles\n */\n restoreTimers(aTimerCycles)\n {\n\n for (var i = 0; i < this.aTimers.length && i < aTimerCycles.length; i++) {\n var timer = this.aTimers[i];\n timer[0] = aTimerCycles[i];\n }\n }\n\n /**\n * updateTimers(nCycles)\n *\n * Used by runCPU() to reduce all active timer countdown values by the number of cycles just executed;\n * this is the function that actually \"fires\" any timer(s) whose countdown has reached (or dropped below)\n * zero, invoking their callback function.\n *\n * @this {CPUPDP10}\n * @param {number} nCycles (number of cycles actually executed)\n */\n updateTimers(nCycles)\n {\n for (var i = this.aTimers.length - 1; i >= 0; i--) {\n var timer = this.aTimers[i];\n\n if (timer[0] < 0) continue;\n timer[0] -= nCycles;\n if (timer[0] <= 0) {\n timer[0] = -1; // zero is technically an \"active\" value, so ensure the timer is dormant now\n timer[1](); // safe to invoke the callback function now\n }\n }\n }\n\n /**\n * endBurst(fReset)\n *\n * @this {CPUPDP10}\n * @param {boolean} [fReset]\n * @return {number} (number of cycles executed in the most recent burst)\n */\n endBurst(fReset)\n {\n var nCycles = this.nBurstCycles -= this.nStepCycles;\n /*\n * In addition to zeroing nStepCycles, it's important that we also zero nSnapCycles, because if a CPU\n * burst is being ended after nStepCycles has been \"snapped\" (because a certain opcode has an unusual timing\n * calculation that must be based on a \"snapped\" cycle count rather the opcode's starting cycle count), we\n * could inadvertently undo the endBurst() if the original \"snapped\" value was used to update nStepCycles.\n */\n this.nStepCycles = this.nSnapCycles = 0;\n if (fReset) this.nBurstCycles = 0;\n return nCycles;\n }\n\n /**\n * runCPU()\n *\n * @this {CPUPDP10}\n */\n runCPU()\n {\n if (!this.flags.running) return;\n\n /*\n * calcStartTime() initializes the cycle counter and timestamp for this runCPU() invocation, and optionally\n * recalculates the the maximum number of cycles for each burst if the nCyclesRecalc threshold has been reached.\n */\n this.calcStartTime();\n\n try {\n do {\n /*\n * nCycles is how many cycles we WANT to run on each iteration of stepCPU(), and may be as\n * HIGH as nCyclesPerYield, but it may be significantly less. getBurstCycles() will adjust\n * nCycles downward if any CPU timers need to fire during the next burst.\n */\n var nCycles = this.getBurstCycles(this.flags.checksum? 1 : this.nCyclesPerYield);\n\n /*\n * Execute the burst.\n */\n try {\n this.stepCPU(nCycles);\n }\n catch(exception) {\n /*\n * We assume that any numeric exception was explicitly thrown by the CPU to interrupt the\n * current instruction (and by extension, the current burst, but not the current run). All\n * other exceptions are re-thrown to the catch below, which will attempt a stack dump.\n */\n if (typeof exception != \"number\") throw exception;\n }\n\n /*\n * Terminate the burst, returning the number of cycles that stepCPU() actually ran.\n */\n nCycles = this.endBurst(true);\n\n /*\n * Add nCycles to nCyclesThisRun, as well as nRunCycles (the cycle count since the CPU started).\n */\n this.nCyclesThisRun += nCycles;\n this.nRunCycles += nCycles;\n this.updateChecksum(nCycles);\n\n /*\n * Update any/all timers, firing those whose cycle countdowns have reached (or dropped below) zero.\n */\n this.updateTimers(nCycles);\n\n this.nCyclesNextYield -= nCycles;\n if (this.nCyclesNextYield <= 0) {\n this.nCyclesNextYield += this.nCyclesPerYield;\n if (++this.nYieldsSinceStatusUpdate >= CPUPDP10.YIELDS_PER_STATUS) {\n this.updateDisplays();\n this.nYieldsSinceStatusUpdate = 0;\n }\n break;\n }\n } while (this.flags.running);\n }\n catch (e) {\n this.stopCPU();\n if (this.cmp) this.cmp.stop(Component.getTime(), this.getCycles());\n this.setError(e.stack || e.message);\n return;\n }\n\n if (this.flags.running) setTimeout(this.onRunTimeout, this.calcRemainingTime());\n }\n\n /**\n * startCPU(fUpdateFocus)\n *\n * For use by any component that wants to start the CPU.\n *\n * @param {boolean} [fUpdateFocus]\n * @return {boolean}\n */\n startCPU(fUpdateFocus)\n {\n if (this.isError()) {\n return false;\n }\n if (this.flags.running) {\n this.println(this.toString() + \" busy\");\n return false;\n }\n /*\n * setSpeed() without a speed parameter leaves the selected speed in place, but also resets the\n * cycle counter and timestamp for the current series of runCPU() calls, calculates the maximum number\n * of cycles for each burst based on the last known effective CPU speed, and resets the nCyclesRecalc\n * threshold counter.\n */\n this.setSpeed();\n this.flags.running = true;\n this.flags.starting = true;\n var controlRun = this.bindings[\"run\"];\n if (controlRun) controlRun.textContent = \"Halt\";\n if (this.cmp) {\n if (fUpdateFocus) this.cmp.setFocus(true);\n this.cmp.start(this.msStartRun, this.getCycles());\n }\n if (!this.dbg) this.status(\"Started\");\n setTimeout(this.onRunTimeout, 0);\n return true;\n }\n\n /**\n * stepCPU(nMinCycles)\n *\n * This will be implemented by the CPUStatePDP10 component.\n *\n * @this {CPUPDP10}\n * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored)\n * @return {number} of cycles executed; 0 indicates that the last instruction was not executed\n */\n stepCPU(nMinCycles)\n {\n return 0;\n }\n\n /**\n * stopCPU(fComplete)\n *\n * For use by any component that wants to stop the CPU.\n *\n * This similar to yieldCPU(), but it doesn't need to zero nCyclesNextYield to break out of runCPU();\n * it simply needs to clear fRunning (well, \"simply\" may be oversimplifying a bit....)\n *\n * @this {CPUPDP10}\n * @param {boolean} [fComplete]\n * @return {boolean} true if the CPU was stopped, false if it was already stopped\n */\n stopCPU(fComplete)\n {\n var fStopped = false;\n if (this.flags.running) {\n this.endBurst();\n this.addCycles(this.nRunCycles);\n this.nRunCycles = 0;\n this.flags.running = false;\n var controlRun = this.bindings[\"run\"];\n if (controlRun) controlRun.textContent = \"Run\";\n if (this.cmp) {\n this.cmp.stop(Component.getTime(), this.getCycles());\n }\n fStopped = true;\n if (!this.dbg) this.status(\"Stopped\");\n }\n this.flags.complete = fComplete;\n return fStopped;\n }\n\n /**\n * yieldCPU()\n *\n * Similar to stopCPU() with regard to how it resets various cycle countdown values, but the CPU\n * remains in a \"running\" state.\n *\n * @this {CPUPDP10}\n */\n yieldCPU()\n {\n this.endBurst(); // this will break us out of stepCPU()\n this.nCyclesNextYield = 0; // this will break us out of runCPU(), once we break out of stepCPU()\n /*\n * The Debugger calls yieldCPU() after every message() to ensure browser responsiveness, but it looks\n * odd for those messages to show CPU state changes if the Control Panel, Video display, etc, does not,\n * so I've added this call to try to keep things looking synchronized.\n */\n this.updateDisplays();\n }\n}\n\n/*\n * Constants that control the frequency at which various updates should occur.\n *\n * These values do NOT control the simulation directly. Instead, they are used by\n * calcCycles(), which uses the nCyclesPerSecond passed to the constructor as a starting\n * point and computes the following variables:\n *\n * this.nCyclesPerYield: (this.nCyclesPerSecond / CPUPDP10.YIELDS_PER_SECOND)\n *\n * The above variables are also multiplied by any cycle multiplier in effect, via setSpeed(),\n * and then they're used to initialize another set of variables for each runCPU() iteration:\n *\n * this.nCyclesNextYield: this.nCyclesPerYield\n */\nCPUPDP10.YIELDS_PER_SECOND = 30; // just a gut feeling for the MINIMUM number of yields per second\nCPUPDP10.YIELDS_PER_STATUS = 15; // every 15 yields (ie, twice per second), perform CPU status updates\n\nCPUPDP10.BUTTONS = [\"power\", \"reset\"];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/cpustate.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * Overview of Device Interrupt Support\n *\n * Originally, the CPU maintained a queue of requested interrupts. Entries in this queue recorded a device's\n * priority, vector, and delay (ie, a number of instructions to execute before dispatching the interrupt). This\n * queue would constantly grow and shrink as requests were issued and dispatched, and as long as there was something\n * in the queue, the CPU was constantly examining it.\n *\n * Now we are trying something more efficient. First, for devices that require delays (like the SerialPort's receiver\n * and transmitter buffer registers, which are supposed to \"clock\" the data in and out at a specific baud rate), the\n * CPU offers timer services that will \"fire\" a callback after a specified delay, which are much more efficient than\n * requiring the CPU to dive into an interrupt queue and decrement delay counts on every instruction.\n *\n * Second, devices that generate interrupts will allocate an IRQ object during initialization; we will no longer\n * be creating and destroying interrupt event objects and inserting/deleting them in a constantly changing queue.\n * Each IRQ contains properties that never change (eg, the vector and priority), along with a \"next\" pointer that's\n * only used when the IRQ is active.\n *\n * When a device decides it's time to interrupt (either at the end of some I/O operation or when a timer has fired),\n * it will simply set the IRQ, which basically means that the IRQ will be linked onto a list of active IRQs, in\n * priority order, so that when the CPU is ready to acknowledge interrupts, it need only check the top of the active\n * IRQ list.\n */\n\n/**\n * @typedef {{\n * vector: number,\n * priority: number,\n * message: number,\n * name: (string|null),\n * next: (IRQ|null)\n * }}\n */\nvar IRQ;\n\n/**\n * @class CPUStatePDP10\n * @unrestricted\n */\nclass CPUStatePDP10 extends CPUPDP10 {\n /**\n * CPUStatePDP10(parmsCPU)\n *\n * The CPUStatePDP10 class uses the following (parmsCPU) properties:\n *\n * model: a number (eg, 1001) that should match one of the PDP10.MODEL_* values\n * addrReset: reset address (default is 0)\n *\n * This extends the CPU class and passes any remaining parmsCPU properties to the CPU class\n * constructor, along with a default speed (cycles per second) based on the specified (or default)\n * CPU model number.\n *\n * Speeds are highly instruction-specific and are not broken down into cycles; DEC documents them\n * as a number of microseconds, with two decimal places of accuracy. The simplest instructions\n * execute in 1-3us, a number of others require 5-6us, and the most time-consuming take anywhere\n * from 10us (MUL) to 17us (DIV). Of course, instructions that perform multiple indirect memory\n * accesses take even longer.\n *\n * I think we'll just say that the original PDP-10 was roughly a 1Mhz machine, and pretend that all\n * instructions completed in 1 or more multiples of a microsecond. I'm not sure that trying to be\n * accurate to the nearest 1/100 of a microsecond would have much observable benefit.\n *\n * @param {Object} parmsCPU\n */\n constructor(parmsCPU)\n {\n var nCyclesDefault = 0;\n var model = +parmsCPU['model'] || PDP10.MODEL_KA10;\n\n switch(model) {\n case PDP10.MODEL_KA10:\n default:\n nCyclesDefault = 1000000;\n break;\n }\n\n /*\n * ES6 ALERT: Classes cannot access \"this\" until all superclasses have been initialized as well.\n */\n super(parmsCPU, nCyclesDefault);\n\n this.model = model;\n this.addrReset = +parmsCPU['addrReset'] || 0;\n\n this.opDecode = PDP10.opKA10.bind(this);\n this.opUndefined = PDP10.opUndefined.bind(this);\n\n /** @type {IRQ|null} */\n this.irqNext = null; // the head of the active IRQ list, in priority order\n\n /** @type {Array.<IRQ>} */\n this.aIRQs = []; // list of all IRQs, active or not (to be used for auto-configuration)\n\n this.flags.complete = false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * Called once the Bus has been initialized.\n *\n * @this {CPUStatePDP10}\n * @param {ComputerPDP10} cmp\n * @param {BusPDP10} bus\n * @param {CPUPDP10} cpu\n * @param {DebuggerPDP10} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n super.initBus(cmp, bus, cpu, dbg);\n }\n\n /**\n * reset()\n *\n * @this {CPUStatePDP10}\n */\n reset()\n {\n this.status(\"Model \" + this.model);\n if (this.flags.running) this.stopCPU();\n this.initCPU();\n this.resetCycles();\n this.clearError(); // clear any fatal error/exception that setError() may have flagged\n super.reset();\n }\n\n /**\n * initCPU()\n *\n * @this {CPUStatePDP10}\n */\n initCPU()\n {\n /*\n * regEA is the last effective address, while regLA is the last fetch from an effective address\n * calculation. regRA is the last reference address used to calculate the last effective address.\n */\n this.regEA = this.regRA = 0;\n this.regLA = this.regOP = 0;\n this.regPC = this.lastPC = this.addrReset;\n this.regXC = -1; // if >= 0 this supersedes regPC (refers to an opcode from XCT)\n this.regBP = -1; // active byte pointer (-1 if none)\n this.regPS = 0; // assorted processor flags (see PSFLAG bit definitions)\n this.regEX = 0; // internal \"extension\" register used for 72-bit MUL and DIV calculations\n\n this.regRes = [0, 0]; // four internal \"double-length\" registers used for 72-bit DIV calculations\n this.regPow = [0, 0];\n this.regDiv = [0, 0];\n this.regRem = [0, 0];\n\n /*\n * This is queried and displayed by the Panel when it's not displaying its own ADDRESS register\n * (which takes precedence when, for example, you've manually halted the CPU and are independently\n * examining the contents of other addresses).\n *\n * We initialize it to the current PC.\n */\n this.addrLast = this.regPC;\n\n /*\n * opFlags contains various conditions that stepCPU() needs to be aware of.\n */\n this.opFlags = 0;\n\n this.setMemoryAccess();\n\n this.resetIRQs();\n }\n\n /**\n * setMemoryAccess()\n *\n * @this {CPUStatePDP10}\n */\n setMemoryAccess()\n {\n this.readWord = this.readWordFromPhysical;\n this.writeWord = this.writeWordToPhysical;\n }\n\n /**\n * setReset(addr, fStart, bUnit, addrStack)\n *\n * @this {CPUStatePDP10}\n * @param {number} addr\n * @param {boolean} [fStart] (true if a \"startable\" image was just loaded, false if not)\n * @param {number} [bUnit] (boot unit #)\n * @param {number} [addrStack]\n */\n setReset(addr, fStart, bUnit, addrStack)\n {\n this.addrReset = addr;\n\n this.setPC(addr);\n\n if (fStart) {\n if (!this.flags.powered) {\n this.flags.autoStart = true;\n }\n else if (!this.flags.running) {\n this.startCPU();\n }\n }\n else {\n if (this.dbg && this.flags.powered) {\n /*\n * TODO: Review the decision to always stop the CPU if the Debugger is loaded. Note that\n * when stopCPU() stops a running CPU, the Debugger gets notified, so no need to notify it again.\n *\n * TODO: There are more serious problems to deal with if another component is slamming a new PC down\n * the CPU's throat (presumably while also dropping some new code into RAM) while the CPU is running;\n * we should probably force a complete reset, but for now, it's up to the user to hit the reset button\n * themselves.\n */\n if (!this.stopCPU() && !this.cmp.flags.reset) {\n this.dbg.updateStatus();\n this.cmp.updateDisplays(-1);\n }\n }\n else if (fStart === false) {\n this.stopCPU();\n }\n }\n if (!this.isRunning() && this.panel) this.panel.stop();\n }\n\n /**\n * getChecksum()\n *\n * TODO: Implement\n *\n * @this {CPUStatePDP10}\n * @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code)\n */\n getChecksum()\n {\n return 0;\n }\n\n /**\n * save()\n *\n * @this {CPUStatePDP10}\n * @return {Object|null}\n */\n save()\n {\n var state = new State(this);\n state.set(0, [\n this.regEA,\n this.regRA,\n this.regLA,\n this.regOP,\n this.regPC,\n this.regXC,\n this.regBP,\n this.regPS,\n this.opFlags,\n this.lastPC,\n this.addrLast,\n this.addrReset\n ]);\n state.set(1, []);\n state.set(2, [this.nTotalCycles, this.getSpeed(), this.flags.autoStart]);\n state.set(3, this.saveIRQs());\n state.set(4, this.saveTimers());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * @this {CPUStatePDP10}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n /*\n * ES6 ALERT: A handy destructuring assignment, which makes it easy to perform the inverse\n * of what save() does when it collects a bunch of object properties into an array.\n */\n [\n this.regEA,\n this.regRA,\n this.regLA,\n this.regOP,\n this.regPC,\n this.regXC,\n this.regBP,\n this.regPS,\n this.opFlags,\n this.lastPC,\n this.addrLast,\n this.addrReset\n ] = data[0];\n\n var a = data[2];\n this.nTotalCycles = a[0];\n this.setSpeed(a[1]);\n this.flags.autoStart = a[2];\n\n this.restoreIRQs(data[3]);\n this.restoreTimers(data[4]);\n return true;\n }\n\n /**\n * getPS()\n *\n * Gets the processor state flags in the format required by various program control operations (eg, JSP).\n *\n * @this {CPUStatePDP10}\n * @return {number}\n */\n getPS()\n {\n return (this.regPS & PDP10.HALF_MASK);\n }\n\n /**\n * setPS(w)\n *\n * Sets the processor state flags in the format required by various program control operations (eg, JRST).\n *\n * @this {CPUStatePDP10}\n * @param {number} w\n */\n setPS(w)\n {\n this.regPS = (this.regPS & ~PDP10.PSFLAG.SET_MASK) | (w & PDP10.PSFLAG.SET_MASK);\n this.regPS |= (w & PDP10.PSFLAG.USERF);\n if (!(w & PDP10.PSFLAG.EXIOT)) {\n this.regPS &= ~PDP10.PSFLAG.EXIOT;\n } else {\n if (!(this.regPS & PDP10.PSFLAG.USERF)) this.regPS |= PDP10.PSFLAG.EXIOT;\n }\n }\n\n /**\n * setUserMode()\n *\n * Sets the processor's USER_MODE flag.\n *\n * @this {CPUStatePDP10}\n */\n setUserMode()\n {\n this.regPS |= PDP10.PSFLAG.USERF;\n }\n\n /**\n * readFlags()\n *\n * Used to implement the \"\"CONI APR,\" instruction; see opCONI().\n *\n * @this {CPUStatePDP10}\n * @return {number}\n */\n readFlags()\n {\n var flags = 0;\n if (this.regPS & PDP10.PSFLAG.AROV) flags |= PDP10.RFLAG.AROV;\n if (this.regPS & PDP10.PSFLAG.PDOV) flags |= PDP10.RFLAG.PDOV;\n return flags;\n }\n\n /**\n * writeFlags(w)\n *\n * Used to implement the \"\"CONO APR,\" instruction; see opCONO().\n *\n * @this {CPUStatePDP10}\n * @param {number} w\n */\n writeFlags(w)\n {\n if (w & PDP10.WFLAG.AROV_CL) this.regPS &= ~PDP10.PSFLAG.AROV;\n if (w & PDP10.WFLAG.PDOV_CL) this.regPS &= ~PDP10.PSFLAG.PDOV;\n }\n\n /**\n * getOpcode()\n *\n * Normally, this fetches the next opcode in regOP, decodes the low 23 bits (I,X,Y), records\n * the effective address (E) in regEA, updates regPC, and returns the high 13 bits of the opcode\n * for further decoding.\n *\n * However, if a reference address (R) in regRA still needs to be decoded (due to indirection),\n * we take care of that first.\n *\n * @this {CPUStatePDP10}\n * @return {number} (-1 if the reference address in regRA has not yet been fully decoded)\n */\n getOpcode()\n {\n if ((this.regRA & PDP10.OPCODE.I_FIELD)) {\n this.regRA = this.regLA = this.readWord(this.regEA);\n } else if (this.regXC >= 0) {\n this.regRA = this.regOP = this.readWord(this.regXC);\n this.regXC = -1;\n } else {\n this.regRA = this.regOP = this.readWord(this.lastPC = this.regPC);\n this.regPC = (this.regPC + 1) % PDP10.ADDR_LIMIT;\n }\n\n /*\n * Technically, we don't REALLY need to mask regRA with R_MASK, because all regRA accesses\n * ignore any higher bits, but let's keep things tidy.\n */\n this.regRA &= PDP10.OPCODE.R_MASK;\n\n /*\n * Bits 0-22 (I,X,Y) contain what we call a \"reference address\" (R), which is used to calculate an\n * 18-bit \"effective address\" (E). To determine E from R, we must extract I, X, and Y from R, set E\n * to Y, then add [X] to E if X is non-zero. If I is zero, then we're done; otherwise, we must set R\n * to [E] and repeat the process.\n *\n * However, we don't actually repeat the process immediately; we need to treat each indirection as a\n * separate decoding step, to ensure that the emulator can \"breathe\" periodically. So instead, we\n * return -1, indicating that the opcode is not fully decoded, and then on the next call, instead of\n * fetching another opcode, we fetch [E], update R, and decode R again.\n */\n this.regEA = this.regRA & PDP10.OPCODE.Y_MASK;\n var x = (this.regRA >> PDP10.OPCODE.X_SHIFT) & PDP10.OPCODE.X_MASK;\n if (x) this.regEA = (this.regEA + (this.regLA = this.readWord(x))) & PDP10.ADDR_MASK;\n\n return (this.regRA & PDP10.OPCODE.I_FIELD)? -1 : ((this.regOP / PDP10.OPCODE.A_SCALE)|0);\n }\n\n /**\n * advancePC(off)\n *\n * NOTE: This function is nothing more than a convenience, and we fully expect it to be inlined at runtime.\n *\n * @this {CPUStatePDP10}\n * @param {number} off\n * @return {number} (original PC)\n */\n advancePC(off)\n {\n var pc = this.regPC;\n this.regPC = (pc + off) % PDP10.ADDR_LIMIT;\n return pc;\n }\n\n /**\n * getPC()\n *\n * NOTE: This function is nothing more than a convenience, and we fully expect it to be inlined at runtime.\n *\n * @this {CPUStatePDP10}\n * @return {number}\n */\n getPC()\n {\n return this.regPC;\n }\n\n /**\n * getXC()\n *\n * NOTE: This function is nothing more than a convenience, and we fully expect it to be inlined at runtime.\n *\n * @this {CPUStatePDP10}\n * @return {number}\n */\n getXC()\n {\n return this.regXC >= 0? this.regXC : ((this.regRA & PDP10.OPCODE.I_FIELD)? this.lastPC : this.regPC);\n }\n\n /**\n * getLastAddr()\n *\n * @this {CPUStatePDP10}\n * @return {number}\n */\n getLastAddr()\n {\n return this.addrLast;\n }\n\n /**\n * getLastPC()\n *\n * @this {CPUStatePDP10}\n * @return {number}\n */\n getLastPC()\n {\n return this.lastPC;\n }\n\n /**\n * setPC(addr)\n *\n * Updates the PC register with the new address after masking it with ADDR_LIMIT (in case the\n * new address was the result of an unchecked calculation).\n *\n * @this {CPUStatePDP10}\n * @param {number} addr\n */\n setPC(addr)\n {\n this.regRA = 0;\n this.regXC = -1;\n this.regPC = addr % PDP10.ADDR_LIMIT;\n }\n\n /**\n * addIRQ(vector, priority, message)\n *\n * @this {CPUStatePDP10}\n * @param {number} vector (-1 for floating vector)\n * @param {number} priority\n * @param {number} [message]\n * @return {IRQ}\n */\n addIRQ(vector, priority, message)\n {\n var irq = {vector: vector, priority: priority, message: message || 0, name: null, next: null};\n this.aIRQs.push(/** @type {IRQ} */ (irq)); // TODO: Why the F*CK do I need a type override? Damn JSDoc types....\n return irq;\n }\n\n /**\n * insertIRQ(irq)\n *\n * @this {CPUStatePDP10}\n * @param {IRQ} irq\n */\n insertIRQ(irq)\n {\n if (irq != this.irqNext) {\n var irqPrev = this.irqNext;\n if (!irqPrev || irqPrev.priority <= irq.priority) {\n irq.next = irqPrev;\n this.irqNext = irq;\n } else {\n do {\n var irqNext = irqPrev.next;\n if (!irqNext || irqNext.priority <= irq.priority) {\n irq.next = irqNext;\n irqPrev.next = irq;\n break;\n }\n irqPrev = irqNext;\n } while (irqPrev);\n }\n }\n /*\n * See the writeXCSR() function for an explanation of why signalling an IRQ hardware interrupt\n * should be done using IRQ_DELAY rather than setting IRQ directly.\n */\n this.opFlags |= PDP10.OPFLAG.IRQ_DELAY;\n }\n\n /**\n * removeIRQ(irq)\n *\n * @this {CPUStatePDP10}\n * @param {IRQ} irq\n */\n removeIRQ(irq)\n {\n var irqPrev = this.irqNext;\n if (irqPrev == irq) {\n this.irqNext = irq.next;\n } else {\n while (irqPrev) {\n var irqNext = irqPrev.next;\n if (irqNext == irq) {\n irqPrev.next = irqNext.next;\n break;\n }\n irqPrev = irqNext;\n }\n }\n /*\n * We could also set irq.next to null now, but strictly speaking, that shouldn't be necessary.\n *\n * Last but not least, if there's still an IRQ on the active IRQ list, we need to make sure IRQ_DELAY\n * is still set.\n */\n if (this.irqNext) {\n this.opFlags |= PDP10.OPFLAG.IRQ_DELAY;\n }\n }\n\n /**\n * setIRQ(irq)\n *\n * @this {CPUStatePDP10}\n * @param {IRQ|null} irq\n */\n setIRQ(irq)\n {\n if (irq) {\n this.insertIRQ(irq);\n if (irq.message && this.messageEnabled(irq.message | MessagesPDP10.INT)) {\n this.printMessage(\"setIRQ(vector=\" + Str.toOct(irq.vector) + \",priority=\" + irq.priority + \")\", true, true);\n }\n }\n }\n\n /**\n * clearIRQ(irq)\n *\n * @this {CPUStatePDP10}\n * @param {IRQ|null} irq\n */\n clearIRQ(irq)\n {\n if (irq) {\n this.removeIRQ(irq);\n if (irq.message && this.messageEnabled(irq.message | MessagesPDP10.INT)) {\n this.printMessage(\"clearIRQ(vector=\" + Str.toOct(irq.vector) + \",priority=\" + irq.priority + \")\", true, true);\n }\n }\n }\n\n /**\n * findIRQ(vector)\n *\n * @this {CPUStatePDP10}\n * @param {number} vector\n * @return {IRQ|null}\n */\n findIRQ(vector)\n {\n for (var i = 0; i < this.aIRQs.length; i++) {\n var irq = this.aIRQs[i];\n if (irq.vector === vector) return irq;\n }\n return null;\n }\n\n /**\n * checkIRQs(priority)\n *\n * @this {CPUStatePDP10}\n * @param {number} priority\n * @return {IRQ|null}\n */\n checkIRQs(priority)\n {\n return (this.irqNext && this.irqNext.priority > priority)? this.irqNext : null;\n }\n\n /**\n * resetIRQs(priority)\n *\n * @this {CPUStatePDP10}\n */\n resetIRQs()\n {\n this.irqNext = null;\n }\n\n /**\n * saveIRQs()\n *\n * @this {CPUStatePDP10}\n * @return {Array.<number>}\n */\n saveIRQs()\n {\n var aIRQVectors = [];\n var irq = this.irqNext;\n while (irq) {\n aIRQVectors.push(irq.vector);\n irq = irq.next;\n }\n return aIRQVectors;\n }\n\n /**\n * restoreIRQs(aIRQVectors)\n *\n * @this {CPUStatePDP10}\n * @param {Array.<number>} aIRQVectors\n */\n restoreIRQs(aIRQVectors)\n {\n for (var i = aIRQVectors.length - 1; i >= 0; i--) {\n var irq = this.findIRQ(aIRQVectors[i]);\n\n if (irq) {\n irq.next = this.irqNext;\n this.irqNext = irq;\n }\n }\n }\n\n /**\n * checkInterrupts()\n *\n * @this {CPUStatePDP10}\n * @return {boolean} true if an interrupt was dispatched, false if not\n */\n checkInterrupts()\n {\n var fInterrupt = false;\n\n if (this.opFlags & PDP10.OPFLAG.IRQ) {\n\n // var vector = PDP10.TRAP.PIRQ;\n // var priority = (this.regPIR & PDP10.PSW.PRI) >> PDP10.PSW.SHIFT.PRI;\n //\n // var irq = this.checkIRQs(priority);\n // if (irq) {\n // vector = irq.vector;\n // priority = irq.priority;\n // }\n //\n // if (this.dispatchInterrupt(vector, priority)) {\n // if (irq) this.removeIRQ(irq);\n // fInterrupt = true;\n // }\n\n if (!this.irqNext) {\n this.opFlags &= ~PDP10.OPFLAG.IRQ;\n }\n }\n else if (this.opFlags & PDP10.OPFLAG.IRQ_DELAY) {\n /*\n * We know that IRQ (bit 2) is clear, so since IRQ_DELAY (bit 0) is set, incrementing opFlags\n * will eventually transform IRQ_DELAY into IRQ, without affecting any other (higher) bits.\n */\n this.opFlags++;\n }\n return fInterrupt;\n }\n\n /**\n * dispatchInterrupt(vector, priority)\n *\n * TODO: The process of dispatching an interrupt MUST cost some cycles; either trap() needs to assess\n * that cost, or we do.\n *\n * @this {CPUStatePDP10}\n * @param {number} vector\n * @param {number} priority\n * @return {boolean} (true if dispatched, false if not)\n */\n dispatchInterrupt(vector, priority)\n {\n return false;\n }\n\n /**\n * isWaiting()\n *\n * @this {CPUStatePDP10}\n * @return {boolean} (true if OPFLAG.WAIT is set, false otherwise)\n */\n isWaiting()\n {\n return !!(this.opFlags & PDP10.OPFLAG.WAIT);\n }\n\n /**\n * readWordFromPhysical(addr)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through readWord().\n *\n * @this {CPUStatePDP10}\n * @param {number} addr\n * @return {number}\n */\n readWordFromPhysical(addr)\n {\n return this.bus.getWord(this.addrLast = addr);\n }\n\n /**\n * writeWordToPhysical(addr, data)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through writeWord().\n *\n * @this {CPUStatePDP10}\n * @param {number} addr\n * @param {number} data\n * @return {number} (we return the data back to the caller to permit nested writes)\n */\n writeWordToPhysical(addr, data)\n {\n this.bus.setWord(this.addrLast = addr, data);\n return data;\n }\n\n /**\n * haltCPU()\n *\n * This is a temporary helper function for the Bus component, to force the CPU to stop executing the\n * current instruction.\n *\n * @this {CPUStatePDP10}\n */\n haltCPU()\n {\n this.stopCPU();\n throw -1;\n }\n\n /**\n * stepCPU(nMinCycles)\n *\n * NOTE: Single-stepping should not be confused with the Trap flag; single-stepping is a Debugger\n * operation that's completely independent of Trap status. The CPU can go in and out of Trap mode,\n * in and out of h/w interrupt service routines (ISRs), etc, but from the Debugger's perspective,\n * they're all one continuous stream of instructions that can be stepped or run at will. Moreover,\n * stepping vs. running should never change the behavior of the simulation.\n *\n * @this {CPUStatePDP10}\n * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored)\n * @return {number} of cycles executed; 0 indicates a pre-execution condition (ie, an execution breakpoint\n * was hit), -1 indicates a post-execution condition (eg, a read or write breakpoint was hit), and a positive\n * number indicates successful completion of that many cycles (which should always be >= nMinCycles).\n */\n stepCPU(nMinCycles)\n {\n /*\n * The Debugger uses complete to determine if the instruction completed (true) or was interrupted\n * by a breakpoint or some other exceptional condition (false). NOTE: this does NOT include JavaScript\n * exceptions, which stepCPU() expects the caller to catch using its own exception handler.\n *\n * The CPU relies on the use of stopCPU() rather than complete, because the CPU never single-steps\n * (ie, nMinCycles is always some large number), whereas the Debugger does. And conversely, when the\n * Debugger is single-stepping (even when performing multiple single-steps), fRunning is never set,\n * so stopCPU() would have no effect as far as the Debugger is concerned.\n */\n this.flags.complete = true;\n\n /*\n * nDebugCheck is 1 if we want the Debugger's checkInstruction() to check every instruction,\n * -1 if we want it to check just the first instruction, and 0 if there's no need for any checks.\n */\n var nDebugCheck = (DEBUGGER && this.dbg)? (this.dbg.checksEnabled()? 1 : (this.flags.starting? -1 : 0)) : 0;\n\n /*\n * nDebugState is needed only when nDebugCheck is non-zero; it is -1 if this is a single-step, 0 if\n * this is the start of a new run, and 1 if this is a continuation of a previous run. It is used by\n * checkInstruction() to determine if it should skip breakpoint checks and/or HALT instructions (ie,\n * if nDebugState is <= zero).\n */\n var nDebugState = (!nMinCycles)? -1 : (this.flags.starting? 0 : 1);\n this.flags.starting = false; // we've moved beyond \"starting\" and have officially \"started\" now\n\n /*\n * We move the minimum cycle count to nStepCycles (the number of cycles left to step), so that other\n * functions have the ability to force that number to zero (eg, stopCPU()), and thus we don't have to check\n * any other criteria to determine whether we should continue stepping or not.\n */\n this.nBurstCycles = this.nStepCycles = nMinCycles;\n\n /*\n * And finally, move the nDebugCheck state to an OPFLAG bit, so that the loop need check only one variable.\n */\n this.opFlags = (this.opFlags & ~PDP10.OPFLAG.DEBUGGER) | (nDebugCheck? PDP10.OPFLAG.DEBUGGER : 0);\n\n do {\n if (this.opFlags) {\n /*\n * NOTE: We still check DEBUGGER to ensure that this code will be compiled out of existence in\n * non-DEBUGGER builds.\n */\n if (DEBUGGER && (this.opFlags & PDP10.OPFLAG.DEBUGGER)) {\n if (this.dbg.checkInstruction(this.getXC(), nDebugState)) {\n this.stopCPU();\n break;\n }\n if (!++nDebugCheck) this.opFlags &= ~PDP10.OPFLAG.DEBUGGER;\n if (!nDebugState) nDebugState++;\n }\n /*\n * If we're in the IRQ or WAIT state, check for any pending interrupts.\n *\n * NOTE: It's no coincidence that we're checking this BEFORE any pending traps, because in rare\n * cases (including some presented by those pesky \"TRAP TEST\" diagnostics), the process of dispatching\n * an interrupt can trigger a TRAP_SP stack overflow condition, which must be dealt with BEFORE we\n * execute the first instruction of the interrupt handler.\n */\n if ((this.opFlags & (PDP10.OPFLAG.IRQ_MASK | PDP10.OPFLAG.WAIT)) /* && nDebugState >= 0 */) {\n if (this.checkInterrupts()) {\n if ((this.opFlags & PDP10.OPFLAG.DEBUGGER) && this.dbg.checkInstruction(this.getXC(), nDebugState)) {\n this.stopCPU();\n break;\n }\n /*\n * Since an interrupt was just dispatched, altering the normal flow of time and changing\n * the future as we knew it, let's break out immediately if we're single-stepping, so that\n * the Debugger gets to see the first instruction of the interrupt handler. NOTE: This\n * assumes that we've still commented out the nDebugState check above that used to bypass\n * checkInterrupts() when single-stepping.\n */\n if (nDebugState < 0) break;\n }\n }\n }\n\n this.opFlags &= PDP10.OPFLAG.PRESERVE;\n\n var op = this.getOpcode();\n if (op >= 0) {\n this.opDecode(op);\n }\n /*\n * TODO: This is a temporary cycle charge, required for CPU operational bookkeeping until we add\n * correct cycle counts for all instructions.\n */\n this.nStepCycles--;\n\n } while (this.nStepCycles > 0);\n\n return (this.flags.complete? this.nBurstCycles - this.nStepCycles : (this.flags.complete === false? -1 : 0));\n }\n\n /**\n * CPUStatePDP10.init()\n *\n * This function operates on every HTML element of class \"cpu\", extracting the\n * JSON-encoded parameters for the CPUStatePDP10 constructor from the element's \"data-value\"\n * attribute, invoking the constructor (which in turn invokes the CPU constructor)\n * to create a CPUStatePDP10 component, and then binding any associated HTML controls to the\n * new component.\n */\n static init()\n {\n var aeCPUs = Component.getElementsByClass(document, PDP10.APPCLASS, \"cpu\");\n for (var iCPU = 0; iCPU < aeCPUs.length; iCPU++) {\n var eCPU = aeCPUs[iCPU];\n var parmsCPU = Component.getComponentParms(eCPU);\n var cpu = new CPUStatePDP10(parmsCPU);\n Component.bindComponentControls(cpu, eCPU, PDP10.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize every CPU module on the page\n */\nWeb.onInit(CPUStatePDP10.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/cpuops.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n From the \"PDP-10 System Reference Manual\", May 1968, p. 1-4:\n\n 1.1 NUMBER SYSTEM\n\n The program can interpret a data word as a 36-digit, unsigned binary number, or the left and right\n halves of a word can be taken as separate 18-bit numbers. The PDP-10 repertoire includes instructions\n that effectively add or subtract one from both halves of a word, so the right half can be used for\n address modification when the word is addressed as an index register, while the left half is used to\n keep a control count.\n\n The standard arithmetic instructions in the PDP-10 use twos complement, fixed point conventions to do\n binary arithmetic. In a word used as a number, bit 0 (the leftmost bit) represents the sign, 0 for positive,\n 1 for negative. In a positive number the remaining 35 bits are the magnitude in ordinary binary notation.\n The negative of a number is obtained by taking its twos complement. If x is an n-digit binary number, its\n twos complement is 2^n - x, and its ones complement is (2^n - 1) - x, or equivalently (2^n - x) - 1.\n\n Subtracting a number from 2^n - 1 (ie, from all 1s) is equivalent to performing the logical complement,\n ie changing all 0s to 1s and all 1s to 0s. Therefore, to form the twos complement one takes the logical\n complement (usually referred to merely as the complement) of the entire word including the sign, and adds\n 1 to the result. In a negative number the sign bit is 1, and the remaining bits are the twos complement\n of the magnitude.\n\n Zero is represented by a word containing all 0s. Complementing this number produces all 1s, and adding\n 1 to that produces all 0s again. Hence there is only one zero representation and its sign is positive.\n Since the numbers are symmetrical in magnitude about a single zero representation, all even numbers both\n positive and negative end in 0, all odd numbers in 1 (a number all 1s represents -1). But since there are\n the same number of positive and negative numbers and zero is positive, there is one more negative number\n than there are nonzero positive numbers. This is the most negative number and it cannot be produced by\n negating any positive number (its octal representation is 400000 000000 and its magnitude is one greater\n than the largest positive number).\n\n If ones complements were used for negatives one could read a negative number by attaching significance\n to the as instead of the 1s. In twos complement notation each negative number is one greater than the\n complement of the positive number of the same magnitude, so one can read a negative number by attaching\n significance to the rightmost 1 and attaching significance to the 0s at the left of it (the negative number\n of largest magnitude has a 1 in only the sign position). In a negative integer, 1s may be discarded at the\n left, just as leading 0s may be dropped in a positive integer. In a negative fraction, 0s may be discarded\n at the right. So long as only 0s are discarded, the number remains in twos complement form because it\n still has a 1 that possesses significance; but if a portion including the rightmost 1 is discarded, the\n remaining part of the fraction is now a ones complement.\n\n The computer does not keep track of a binary point - the programmer must adopt a point convention and shift\n the magnitude of the result to conform to the convention used. Two common conventions are to regard a number\n as an integer (binary point at the right) or as a proper fraction (binary point at the left); in these two\n cases the range of numbers represented by a single word is -2^35 to 2^35 - 1, or -1 to 1 - 2^35. Since\n multiplication and division make use of double length numbers, there are special instructions for performing\n these operations with integral operands.\n\n SIDEBAR: Multiplication produces a double length product, and the programmer must remember that discarding\n the low order part of a double length negative leaves the high order part in correct twos complement form\n only if the low order part is null.\n\n ...\n\n 2.5 FIXED POINT ARITHMETIC\n\n For fixed point arithmetic the PDP-10 has instructions for arithmetic shifting (which is essentially\n multiplication by a power of 2) as well as for performing addition, subtraction, multiplication and division\n of numbers in fixed point format [§ 1.1]. In such numbers the position of the binary point is arbitrary\n (the programmer may adopt any point convention). The add and subtract instructions involve only single length\n numbers, whereas multiply supplies a double length product, and divide uses a double length dividend. The high\n and low order words respectively of a double length fixed point number are in accumulators A and A+1 (mod 20),\n where the magnitude is the 70-bit string in bits 1-35 of the two words and the signs of the two are identical.\n There are also integer multiply and divide instructions that involve only single length numbers and are\n especially suited for handling smaller integers, particularly those of eighteen bits or less such as addresses\n (of course they can be used for small fractions as well provided the programmer keeps track of the binary point).\n For convenience in the following, all operands are assumed to be integers (binary point at the right).\n\n The processor has four flags, Overflow, Carry 0, Carry 1 and No Divide, that indicate when the magnitude of a\n number is or would be larger than can be accommodated. Carry 0 and Carry 1 actually detect carries out of bits\n 0 and 1 in certain instructions that employ fixed point arithmetic operations: the add and subtract instructions\n treated here, the move instructions that produce the negative or magnitude of the word moved [§ 2.2], and the\n arithmetic test instructions that increment or decrement the test word [§ 2.7]. In these instructions an\n incorrect result is indicated - and the Overflow flag set - if the carries are different, ie if there is a carry\n into the sign but not out of it, or vice versa. The Overflow flag is also set by No Divide being set, which\n means the processor has failed to perform a division because the magnitude of the dividend is greater than or\n equal to that of the divisor, or in integer divide, simply that the divisor is zero. In other overflow cases\n only Overflow itself is set: these include too large a product in multiplication, and loss of significant bits\n in left arithmetic shifting.\n\n SIDEBAR: Overflow is determined directly from the carries, not from the carry flags, as their states may reflect\n events in previous instructions.\n\n */\n\n/**\n * opKA10(op)\n *\n * Originally, we received the full opcode (36 bits), then only the upper half-word (18 bits),\n * and now we receive only the upper 13 bits. However, the octal values shown in the table and\n * function comments below still include all 18 bits of the original upper half-word, so that\n * you don't have to mentally un-shift them 5 bits.\n *\n * @this {CPUStatePDP10}\n * @param {number} op (the top 13 bits of the original opcode, shifted right to bit 0)\n */\nPDP10.opKA10 = function(op)\n{\n /*\n * We shift op right 4 more bits, leaving only the 9 bits required for the table index. Those\n * 4 bits are normally an accumulator index, which we also mask and pass along, since most instructions\n * will use an accumulator, and those that don't simply ignore it.\n */\n PDP10.aOpXXX_KA10[op >> 4].call(this, op, op & PDP10.OPCODE.A_MASK);\n};\n\n/**\n * opUUO(0o0NN000): Unimplemented User Operation\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-64:\n *\n * Store the instruction code, A and the effective address E in bits 0-8, 9-12 and 18-35 respectively of\n * location 40; clear bits 13-17. Execute the instruction contained in location 41. The original contents\n * of location 40 are lost.\n *\n * All of these codes are equivalent when they occur in the Monitor or when time sharing is not in effect.\n * But when a UUO appears in a user program, a code in the range 001-037 uses relocated locations 40 and 41\n * (ie 40 and 41 in the user's block) and is thus entirely a part of and under control of the user program.\n *\n * A code in the range 040-077 on the other hand uses unrelocated 40 and 41, and the instruction in the latter\n * location is under control of the Monitor; these codes are thus specifically for user communication with\n * the Monitor, which interprets them (refer to the Monitor manual for the meanings of the various codes).\n *\n * The code 000 executes in the same way as 040-077 but is not a standard communication code: it is included\n * so that control returns to the Monitor should a user program wipe itself out.\n *\n * For a second processor connected to the same memory, the UUO trap is locations 140-141 instead of 40-41.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opUUO = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opUFA(0o130000): Unnormalized Floating Add\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-37:\n *\n * Floating add the contents of location E to AC. If the double length fraction in the sum is zero, clear\n * accumulator A+1. Otherwise normalize the sum only if the magnitude of its fractional part is >= 1, and place\n * the high order part of the result in AC A+1. The original contents of AC and E are unaffected.\n *\n * NOTE: The result is placed in accumulator A+1. T his is the only arithmetic instruction that stores the result\n * in a second accumulator, leaving the original operands intact.\n *\n * If the exponent of the sum following the one-step normalization is > 127, set Overflow and Floating Overflow;\n * the result stored has an exponent 256 less than the correct one.\n *\n * SIDEBAR: The exponent of the sum is equal to that of the larger summand unless addition of the fractions\n * overflows, in which case it is greater by 1. Exponent overflow can occur only in the latter case.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opUFA = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opDFN(0o131000): Double Floating Negate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-37:\n *\n * Negate the double length floating point number composed of the contents of AC and location E with AC on the left.\n * Do this by taking the twos complement of the number whose sign is AC bit 0, whose exponent is in AC bits 1-8, and\n * whose fraction is the 54-bit string in bits 9-35 of AC and location E. Place the high order word of the result\n * in AC; place the low order part of the fraction in bits 9-35 of location E without altering the original contents\n * of bits 0-8 of that location.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opDFN = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFSC(0o132000): Floating Scale\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-34:\n *\n * If the fractional part of AC is zero, clear AC. Otherwise add the scale factor given by E to the exponent part\n * of AC (thus multiplying AC by 2^E), normalize the resulting word bringing 0s into bit positions vacated at the\n * right, and place the result back in AC.\n *\n * NOTE: A negative E is represented in standard twos complement notation, but the hardware compensates for this\n * when scaling the exponent.\n *\n * If the exponent after normalization is > 127, set Overflow and Floating Overflow; the result stored has an\n * exponent 256 less than the correct one. If < -128, set Overflow, Floating Overflow and Floating Underflow;\n * the result stored has an exponent 256 greater than the correct one.\n *\n * SIDEBAR: This instruction can be used to float a fixed number with 27 or fewer significant bits. To float an\n * integer contained within AC bits 9-35,\n *\n * FSC AC,233\n *\n * inserts the correct exponent to move the binary point from the right end to the left of bit 9 and then normalizes\n * (233 [base 8] = 155 [base 10] = 128 + 27).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFSC = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opIBP(0o133000): Increment Byte Pointer\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-16:\n *\n * Increment the byte pointer in location E as explained [below]. The pointer has the format:\n *\n * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3\n * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5\n * P P P P P P S S S S S S - I X X X X Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y\n *\n * where S is the size of the byte as a number of bits, and P is its position as the number of bits\n * remaining at the right of the byte in the word (eg if P is 3 the rightmost bit of the byte is bit 32\n * of the word). The rest of the pointer is interpreted in the same way as in an instruction: I, X and Y\n * are used to calculate the address of the location that is the source or destination of the byte.\n *\n * To facilitate processing a series of bytes, several of the byte instructions increment the\n * pointer, ie, modify it so that it points to the next byte position in a set of memory locations.\n * Bytes are processed from left to right in a word, so incrementing merely replaces the current value\n * of P by P - S, unless there is insufficient space in the present location for another byte of the\n * specified size (P - S < 0). In this case Y is increased by one to point to the next consecutive\n * location, and P is set to 36 - S to point to the first byte at the left in the new location.\n *\n * CAUTION: Do not allow Y to reach maximum value. The whole pointer is incremented, so if Y is 2^18 - 1\n * it becomes zero and X is also incremented. The address calculation for the pointer uses the original X,\n * but if a priority interrupt should occur before the calculation is complete, the incremented X is used\n * when the instruction is repeated.\n *\n * SPECIAL CONSIDERATIONS: If S is greater than P and also greater than 36, incrementing produces a new\n * P equal to 100 - S rather than 36 - S. For S > 36 the byte is at most the entire word; for P >= 36 no\n * byte is processed (loading merely clears AC). If both P and S are less than 36 but P + S > 36,\n * a byte of size 36 - P is loaded from position P, or the right 36 - P bits of the byte are deposited\n * in position P.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIBP = function(op, ac)\n{\n var inc = 0;\n var w = this.readWord(this.regEA);\n var p = (w / PDP10.OPCODE.P_SCALE) & PDP10.OPCODE.P_MASK;\n var s = (w >> PDP10.OPCODE.S_SHIFT) & PDP10.OPCODE.S_MASK;\n p -= s;\n if (p < 0) {\n inc++;\n p = 36 - s;\n if (p < 0) p = 100 - s; // see SPECIAL CONSIDERATIONS and NOTE above\n }\n /*\n * Since the documentation above makes clear that the effect of the increment (of w) extends past the Y\n * bits and into (at least) the X bits, we first re-assemble a new pointer with updated P bits (along with\n * the original S bits and the remaining bits covered by PTR_MASK) and then increment as needed.\n *\n * Yes, PTR_MASK could have included the S bits as well and made the following expression a TINY bit simpler,\n * but I would like to keep PTR_MASK distinct from both the P and S fields.\n */\n w = (p * PDP10.OPCODE.P_SCALE) + (s << PDP10.OPCODE.S_SHIFT) + (w & PDP10.OPCODE.PTR_MASK);\n if (inc) w = (w + inc) % PDP10.WORD_LIMIT;\n this.writeWord(this.regEA, w);\n};\n\n/**\n * opILDB(0o134000): Increment Pointer and Load Byte\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-16:\n *\n * Increment the byte pointer in location E as explained above. Then retrieve a byte of S bits from the\n * location and position specified by the newly incremented pointer, load it into the right end of AC,\n * and clear the remaining AC bits. The location containing the byte is unaffected, the original contents\n * of AC are lost.\n *\n * SPECIAL CONSIDERATIONS: If S is greater than P and also greater than 36, incrementing produces a new\n * P equal to 100 - S rather than 36 - S. For S > 36 the byte is at most the entire word; for P >= 36 no\n * byte is processed (loading merely clears AC). If both P and S are less than 36 but P + S > 36,\n * a byte of size 36 - P is loaded from position P, or the right 36 - P bits of the byte are deposited\n * in position P.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opILDB = function(op, ac)\n{\n /*\n * We're called in two phases: phase 1 is with regEA containing the address of the pointer, and phase 2\n * is with regEA containing the address of the bits to be loaded.\n *\n * We can implement this as a simple combination of opIBP() and opLDB(), but taking care that we only call\n * opIBP() on phase 1 (and only if the BIS flag is not set).\n */\n if (!(this.regPS & PDP10.PSFLAG.BIS)) {\n PDP10.opIBP.call(this, op, ac);\n this.regPS |= PDP10.PSFLAG.BIS;\n }\n PDP10.opLDB.call(this, op, ac);\n};\n\n/**\n * opLDB(0o135000): Load Byte\n *z\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-16:\n *\n * Retrieve a byte of S bits from the location and position specified by the pointer contained in location E,\n * load it into the right end of AC, and clear the remaining AC bits. The location containing the byte is\n * unaffected, the original contents of AC are lost.\n *\n * SPECIAL CONSIDERATIONS: If S is greater than P and also greater than 36, incrementing produces a new\n * P equal to 100 - S rather than 36 - S. For S > 36 the byte is at most the entire word; for P >= 36 no\n * byte is processed (loading merely clears AC). If both P and S are less than 36 but P + S > 36,\n * a byte of size 36 - P is loaded from position P, or the right 36 - P bits of the byte are deposited\n * in position P.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opLDB = function(op, ac)\n{\n /*\n * We're called in two phases: phase 1 is with regEA containing the address of the pointer, and phase 2\n * is with regEA containing the address of the bits to be loaded.\n */\n var w = this.readWord(this.regEA);\n if (this.regBP < 0) {\n this.regBP = w;\n this.regRA = this.regEA | PDP10.OPCODE.I_FIELD;\n return;\n }\n var p = (this.regBP / PDP10.OPCODE.P_SCALE) & PDP10.OPCODE.P_MASK;\n var s = (this.regBP >> PDP10.OPCODE.S_SHIFT) & PDP10.OPCODE.S_MASK;\n if (p + s < 32) {\n /*\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n w = ((w >> p) & ((1 << s) - 1)) >>> 0;\n } else {\n /*\n * Regarding the SPECIAL CONSIDERATIONS above, even if the P (\"shift\") and/or S (\"mask\") values are\n * over-large, that should be fine, because nothing but additional zero bits will be included (provided\n * our memory is working properly and didn't give us more than 36 bits of unsigned data).\n */\n w = Math.trunc(w / Math.pow(2, p)) % Math.pow(2, s);\n }\n this.writeWord(ac, w);\n this.regPS &= ~PDP10.PSFLAG.BIS;\n this.regBP = -1;\n};\n\n/**\n * opIDPB(0o136000): Increment Pointer and Deposit Byte\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-16:\n *\n * Increment the byte pointer in location E as explained above. Then deposit the right S bits of AC into\n * the location and position specified by the newly incremented pointer. The original contents of the bits\n * that receive the byte are lost, AC and the remaining bits of the deposit location are unaffected.\n *\n * SPECIAL CONSIDERATIONS: If S is greater than P and also greater than 36, incrementing produces a new\n * P equal to 100 - S rather than 36 - S. For S > 36 the byte is at most the entire word; for P >= 36 no\n * byte is processed (loading merely clears AC). If both P and S are less than 36 but P + S > 36,\n * a byte of size 36 - P is loaded from position P, or the right 36 - P bits of the byte are deposited\n * in position P.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIDPB = function(op, ac)\n{\n /*\n * We're called in two phases: phase 1 is with regEA containing the address of the pointer, and phase 2\n * is with regEA containing the address of the bits to be stored.\n *\n * We can implement this as a simple combination of opIBP() and opDDB(), but taking care that we only call\n * opIBP() on phase 1 (and only if the BIS flag is not set).\n */\n if (!(this.regPS & PDP10.PSFLAG.BIS)) {\n PDP10.opIBP.call(this, op, ac);\n this.regPS |= PDP10.PSFLAG.BIS;\n }\n PDP10.opDPB.call(this, op, ac);\n};\n\n/**\n * opDPB(0o137000): Deposit Byte\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-16:\n *\n * Deposit the right S bits of AC into the location and position specified by the pointer contained\n * in location E. The original contents of the bits that receive the byte are lost, AC and the remaining\n * bits of the deposit location are unaffected.\n *\n * SPECIAL CONSIDERATIONS: If S is greater than P and also greater than 36, incrementing produces a new\n * P equal to 100 - S rather than 36 - S. For S > 36 the byte is at most the entire word; for P >= 36 no\n * byte is processed (loading merely clears AC). If both P and S are less than 36 but P + S > 36,\n * a byte of size 36 - P is loaded from position P, or the right 36 - P bits of the byte are deposited\n * in position P.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opDPB = function(op, ac)\n{\n /*\n * We're called in two phases: phase 1 is with regEA containing the address of the pointer, and phase 2\n * is with regEA containing the address of the bits to be stored.\n */\n var w = this.readWord(this.regEA);\n if (this.regBP < 0) {\n this.regBP = w;\n this.regRA = this.regEA | PDP10.OPCODE.I_FIELD;\n return;\n }\n var p = (this.regBP / PDP10.OPCODE.P_SCALE) & PDP10.OPCODE.P_MASK;\n var s = (this.regBP >> PDP10.OPCODE.S_SHIFT) & PDP10.OPCODE.S_MASK;\n /*\n * Regarding the SPECIAL CONSIDERATIONS above, even if the P (\"shift\") and/or S (\"mask\") values are\n * over-large, we \"mask\" the resulting byte value (b) to 36 bits, so that when we re-assemble the final\n * result (w), there shouldn't be any overlap or overflow.\n */\n var b = ((this.readWord(ac) % Math.pow(2, s)) * Math.pow(2, p)) % PDP10.WORD_LIMIT;\n w = (w - (w % Math.pow(2, p + s))) + b + (w % Math.pow(2, p));\n this.writeWord(this.regEA, w);\n this.regPS &= ~PDP10.PSFLAG.BIS;\n this.regBP = -1;\n};\n\n/**\n * opFAD(0o140000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFAD = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFADI(0o141000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFADI = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFADM(0o142000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFADM = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFADB(0o143000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFADB = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFADR(0o144000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFADR = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFADRI(0o145000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFADRI = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFADRM(0o146000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFADRM = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFADRB(0o147000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFADRB = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFSB(0o150000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFSB = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFSBI(0o151000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFSBI = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFSBM(0o152000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFSBM = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFSBB(0o153000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFSBB = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFSBR(0o154000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFSBR = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFSBRI(0o155000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFSBRI = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFSBRM(0o156000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFSBRM = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFSBRB(0o157000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFSBRB = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFMP(0o160000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFMP = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFMPI(0o161000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFMPI = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFMPM(0o162000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFMPM = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFMPB(0o163000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFMPB = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFMPR(0o164000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFMPR = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFMPRI(0o165000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFMPRI = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFMPRM(0o166000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFMPRM = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFMPRB(0o167000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFMPRB = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFDV(0o170000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFDV = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFDVI(0o171000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFDVI = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFDVM(0o172000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFDVM = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFDVB(0o173000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFDVB = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFDVR(0o174000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFDVR = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFDVRI(0o175000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFDVRI = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFDVRM(0o176000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFDVRM = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFDVRB(0o177000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFDVRB = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opMOVE(0o200000): Move\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Move one word from the source to the destination specified by M. The source is unaffected,\n * the original contents of the destination are lost.\n *\n * NOTE: This is a \"Basic\" mode instruction: the source is [E] and the destination is [A] (opposite of \"Memory\").\n *\n * Equivalents: opSETM(0o414000) and opSETMB(0o417000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVE = function(op, ac)\n{\n this.writeWord(ac, this.readWord(this.regEA));\n};\n\n/**\n * opMOVEI(0o201000): Move Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Move one word from the source to the destination specified by M. The source is unaffected,\n * the original contents of the destination are lost.\n *\n * SIDEBAR: MOVEI loads the word 0,E into AC and is thus equivalent to HRRZI.\n *\n * NOTE: This is an \"Immediate\" mode instruction: the source is the word 0,E and the destination is [A].\n *\n * Equivalents: opSETMI(0o415000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVEI = function(op, ac)\n{\n this.writeWord(ac, this.regEA);\n};\n\n/**\n * opMOVEM(0o202000): Move to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Move one word from the source to the destination specified by M. The source is unaffected,\n * the original contents of the destination are lost.\n *\n * NOTE: This is a \"Memory\" mode instruction: the source is [A] and the destination is [E] (opposite of \"Basic\").\n *\n * Equivalents: opSETAM(0o426000) and opSETAB(0o427000).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVEM = function(op, ac)\n{\n this.writeWord(this.regEA, this.readWord(ac));\n};\n\n/**\n * opMOVES(0o203000): Move to Self\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Move one word from the source to the destination specified by M. The source is unaffected,\n * the original contents of the destination are lost.\n *\n * SIDEBAR: If A is zero, MOVES is a no-op; otherwise it is equivalent to MOVE.\n *\n * NOTE: This is a \"Self\" mode instruction: the source AND destination is [E] (and also [A] if A is non-zero).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVES = function(op, ac)\n{\n if (ac) this.writeWord(ac, this.readWord(this.regEA));\n};\n\n/**\n * opMOVS(0o204000): Move Swapped\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Interchange the left and right halves of the word from the source specified by M and move it to the\n * specified destination. The source is unaffected, the original contents of the destination are lost.\n *\n * NOTE: This is a \"Basic\" mode instruction: the source is [E] and the destination is [A] (opposite of \"Memory\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVS = function(op, ac)\n{\n var src = this.readWord(this.regEA);\n src = ((src / PDP10.HALF_SHIFT)|0) + ((src & PDP10.HALF_MASK) * PDP10.HALF_SHIFT);\n this.writeWord(ac, src);\n};\n\n/**\n * opMOVSI(0o205000): Move Swapped Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Interchange the left and right halves of the word from the source specified by M and move it to the\n * specified destination. The source is unaffected, the original contents of the destination are lost.\n *\n * SIDEBAR: Swapping halves in immediate mode loads the word E,0 into AC. MOVSI is thus equivalent to HRLZI.\n *\n * NOTE: This is an \"Immediate\" mode instruction: the source is the word 0,E and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVSI = function(op, ac)\n{\n this.writeWord(ac, this.regEA * PDP10.HALF_SHIFT);\n};\n\n/**\n * opMOVSM(0o206000): Move Swapped to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Interchange the left and right halves of the word from the source specified by M and move it to the\n * specified destination. The source is unaffected, the original contents of the destination are lost.\n *\n * NOTE: This is a \"Memory\" mode instruction: the source is [A] and the destination is [E] (opposite of \"Basic\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVSM = function(op, ac)\n{\n var src = this.readWord(ac);\n src = ((src / PDP10.HALF_SHIFT)|0) + ((src & PDP10.HALF_MASK) * PDP10.HALF_SHIFT);\n this.writeWord(this.regEA, src);\n};\n\n/**\n * opMOVSS(0o207000): Move Swapped to Self\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Interchange the left and right halves of the word from the source specified by M and move it to the\n * specified destination. The source is unaffected, the original contents of the destination are lost.\n *\n * NOTE: This is a \"Self\" mode instruction: the source AND destination is [E] (and also [A] if A is non-zero).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVSS = function(op, ac)\n{\n var src = this.readWord(this.regEA);\n src = ((src / PDP10.HALF_SHIFT)|0) + ((src & PDP10.HALF_MASK) * PDP10.HALF_SHIFT);\n this.writeWord(this.regEA, src);\n if (ac) this.writeWord(ac, src)\n};\n\n/**\n * opMOVN(0o210000): Move Negative\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Negate the word from the source specified by M and move it to the specified destination.\n * If the source word is fixed point -2^35 (400000 000000) set the Overflow and Carry 1 flags.\n *\n * (Negating the equivalent floating point -1 * 2^127 sets the flags, but this is not a normalized\n * number).\n *\n * If the source word is zero, set Carry 0 and Carry 1. The source is unaffected, the original\n * contents of the destination are lost.\n *\n * NOTE: This is a \"Basic\" mode instruction: the source is [E] and the destination is [A] (opposite of \"Memory\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVN = function(op, ac)\n{\n this.writeWord(ac, PDP10.doNEG.call(this, this.readWord(this.regEA)));\n};\n\n/**\n * opMOVNI(0o211000): Move Negative Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Negate the word from the source specified by M and move it to the specified destination.\n * If the source word is fixed point -2^35 (400000 000000) set the Overflow and Carry 1 flags.\n *\n * (Negating the equivalent floating point -1 * 2^127 sets the flags, but this is not a normalized\n * number).\n *\n * If the source word is zero, set Carry 0 and Carry 1. The source is unaffected, the original\n * contents of the destination are lost.\n *\n * SIDEBAR: MOVNI loads AC with the negative of the word 0,E and can set no flags.\n *\n * NOTE: This is an \"Immediate\" mode instruction: the source is the word 0,E and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVNI = function(op, ac)\n{\n /*\n * We used to perform an in-line two's complement of regEA, since doNEG() updates the flags, and the\n * documentation above claimed that MOVNI must \"set no flags.\" It's certainly true that regEA, being an\n * 18-bit value, could never be -2^35, but it COULD be zero. However, SIMH doesn't treat zero any\n * differently for MOVNI, so we currently don't either.\n *\n * TODO: Verify the \"set no flags\" assertion on *real* (KA10) hardware.\n */\n this.writeWord(ac, PDP10.doNEG.call(this, this.regEA) /* this.regEA? PDP10.TWO_POW36 - this.regEA : 0 */);\n};\n\n/**\n * opMOVNM(0o212000): Move Negative to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Negate the word from the source specified by M and move it to the specified destination.\n * If the source word is fixed point -2^35 (400000 000000) set the Overflow and Carry 1 flags.\n *\n * (Negating the equivalent floating point -1 * 2^127 sets the flags, but this is not a normalized\n * number).\n *\n * If the source word is zero, set Carry 0 and Carry 1. The source is unaffected, the original\n * contents of the destination are lost.\n *\n * NOTE: This is a \"Memory\" mode instruction: the source is [A] and the destination is [E] (opposite of \"Basic\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVNM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.doNEG.call(this, this.readWord(ac)));\n};\n\n/**\n * opMOVNS(0o213000): Move Negative to Self\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Negate the word from the source specified by M and move it to the specified destination.\n * If the source word is fixed point -2^35 (400000 000000) set the Overflow and Carry 1 flags.\n *\n * (Negating the equivalent floating point -1 * 2^127 sets the flags, but this is not a normalized\n * number).\n *\n * If the source word is zero, set Carry 0 and Carry 1. The source is unaffected, the original\n * contents of the destination are lost.\n *\n * NOTE: This is a \"Self\" mode instruction: the source AND destination is [E] (and also [A] if A is non-zero).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVNS = function(op, ac)\n{\n var dst = PDP10.doNEG.call(this, this.readWord(this.regEA));\n this.writeWord(this.regEA, dst);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opMOVM(0o214000): Move Magnitude\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-12:\n *\n * Take the magnitude of the word contained in the source specified by M and move it to the\n * specified destination. If the source word is fixed point -2^35 (400000 000000) set the\n * Overflow and Carry 1 flags.\n *\n * (Negating the equivalent floating point -1 * 2^27 sets the flags, but this is not a normalized\n * number).\n *\n * The source is unaffected, the original contents of the destination are lost.\n *\n * NOTE: This is a \"Basic\" mode instruction: the source is [E] and the destination is [A] (opposite of \"Memory\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVM = function(op, ac)\n{\n this.writeWord(ac, PDP10.doABS.call(this, this.readWord(this.regEA)));\n};\n\n/**\n * opMOVMI(0o215000): Move Magnitude Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-12:\n *\n * Take the magnitude of the word contained in the source specified by M and move it to the\n * specified destination. If the source word is fixed point -2^35 (400000 000000) set the\n * Overflow and Carry 1 flags.\n *\n * (Negating the equivalent floating point -1 * 2^27 sets the flags, but this is not a normalized\n * number).\n *\n * The source is unaffected, the original contents of the destination are lost.\n *\n * SIDEBAR: The word 0,E is equivalent to its magnitude, so MOVMI is equivalent to MOVEI.\n *\n * NOTE: This is an \"Immediate\" mode instruction: the source is the word 0,E and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVMI = function(op, ac)\n{\n this.writeWord(ac, this.regEA); // src is an 18-bit immediate value, so there's no need to call doABS()\n};\n\n/**\n * opMOVMM(0o216000): Move Magnitude to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-12:\n *\n * Take the magnitude of the word contained in the source specified by M and move it to the\n * specified destination. If the source word is fixed point -2^35 (400000 000000) set the\n * Overflow and Carry 1 flags.\n *\n * (Negating the equivalent floating point -1 * 2^27 sets the flags, but this is not a normalized\n * number).\n *\n * The source is unaffected, the original contents of the destination are lost.\n *\n * NOTE: This is a \"Memory\" mode instruction: the source is [A] and the destination is [E] (opposite of \"Basic\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVMM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.doABS.call(this, this.readWord(ac)));\n};\n\n/**\n * opMOVMS(0o217000): Move Magnitude to Self\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-12:\n *\n * Take the magnitude of the word contained in the source specified by M and move it to the\n * specified destination. If the source word is fixed point -2^35 (400000 000000) set the\n * Overflow and Carry 1 flags.\n *\n * (Negating the equivalent floating point -1 * 2^27 sets the flags, but this is not a normalized\n * number).\n *\n * The source is unaffected, the original contents of the destination are lost.\n *\n * NOTE: This is a \"Self\" mode instruction: the source AND destination is [E] (and also [A] if A is non-zero).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVMS = function(op, ac)\n{\n var dst = PDP10.doABS.call(this, this.readWord(this.regEA));\n this.writeWord(this.regEA, dst);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opIMUL(0o220000): Integer Multiply\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28:\n *\n * Multiply AC by the operand specified by M, and place the sign and the 35 low order magnitude bits of the\n * product in the specified destination. Set Overflow if the product is >= 2^35 or < -2^35 (ie if the high order\n * word of the double length product is not null); the high order word is lost.\n *\n * NOTE: This is a \"Basic\" mode instruction: the source is [E] and the destination is [A] (opposite of \"Memory\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIMUL = function(op, ac)\n{\n this.writeWord(ac, PDP10.doMUL.call(this, this.readWord(ac), this.readWord(this.regEA), true));\n};\n\n/**\n * opIMULI(0o221000): Integer Multiply Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28:\n *\n * Multiply AC by the operand specified by M, and place the sign and the 35 low order magnitude bits of the\n * product in the specified destination. Set Overflow if the product is >= 2^35 or < -2^35 (ie if the high order\n * word of the double length product is not null); the high order word is lost.\n *\n * NOTE: This is an \"Immediate\" mode instruction: the source is the word 0,E and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIMULI = function(op, ac)\n{\n this.writeWord(ac, PDP10.doMUL.call(this, this.readWord(ac), this.regEA, true));\n};\n\n/**\n * opIMULM(0o222000): Integer Multiply to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28:\n *\n * Multiply AC by the operand specified by M, and place the sign and the 35 low order magnitude bits of the\n * product in the specified destination. Set Overflow if the product is >= 2^35 or < -2^35 (ie if the high order\n * word of the double length product is not null); the high order word is lost.\n *\n * NOTE: This is a \"Memory\" mode instruction: the source is [E] and the destination is [E] (opposite of \"Basic\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIMULM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.doMUL.call(this, this.readWord(ac), this.readWord(this.regEA), true));\n};\n\n/**\n * opIMULB(0o223000): Integer Multiply to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28:\n *\n * Multiply AC by the operand specified by M, and place the sign and the 35 low order magnitude bits of the\n * product in the specified destination. Set Overflow if the product is >= 2^35 or < -2^35 (ie if the high order\n * word of the double length product is not null); the high order word is lost.\n *\n * NOTE: This is a \"Both\" mode instruction: the source is [E] and the destination is [E] and [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIMULB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.doMUL.call(this, this.readWord(ac), this.readWord(this.regEA), true)));\n};\n\n/**\n * opMUL(0o224000): Multiply\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28:\n *\n * Multiply AC by the operand specified by M, and place the high order word of the double length result\n * in the specified destination. If M specifies AC as a destination, place the low order word in accumulator\n * A+1. If both operands are -2^35 set Overflow; the double length result stored is -2^70.\n *\n * NOTE: This is a \"Basic\" mode instruction: the source is [E] and the destination is [A],[A+1] (opposite of \"Memory\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMUL = function(op, ac)\n{\n this.writeWord(ac, PDP10.doMUL.call(this, this.readWord(ac), this.readWord(this.regEA)));\n this.writeWord((ac + 1) & 0o17, this.regEX);\n};\n\n/**\n * opMULI(0o225000): Multiply Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28:\n *\n * Multiply AC by the operand specified by M, and place the high order word of the double length result\n * in the specified destination. If M specifies AC as a destination, place the low order word in accumulator\n * A+1. If both operands are -2^35 set Overflow; the double length result stored is -2^70.\n *\n * NOTE: This is an \"Immediate\" mode instruction: the source is the word 0,E and the destination is [A],[A+1].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMULI = function(op, ac)\n{\n this.writeWord(ac, PDP10.doMUL.call(this, this.readWord(ac), this.regEA));\n this.writeWord((ac + 1) & 0o17, this.regEX);\n};\n\n/**\n * opMULM(0o226000): Multiply to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28:\n *\n * Multiply AC by the operand specified by M, and place the high order word of the double length result\n * in the specified destination. If M specifies AC as a destination, place the low order word in accumulator\n * A+1. If both operands are -2^35 set Overflow; the double length result stored is -2^70.\n *\n * NOTE: This is a \"Memory\" mode instruction: the source is [E] and the destination is [E] (opposite of \"Basic\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMULM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.doMUL.call(this, this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opMULB(0o227000): Multiply to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28:\n *\n * Multiply AC by the operand specified by M, and place the high order word of the double length result\n * in the specified destination. If M specifies AC as a destination, place the low order word in accumulator\n * A+1. If both operands are -2^35 set Overflow; the double length result stored is -2^70.\n *\n * NOTE: This is a \"Both\" mode instruction: the source is [E] and the destination is [E] and [A],[A+1].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMULB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.doMUL.call(this, this.readWord(ac), this.readWord(this.regEA))));\n this.writeWord((ac + 1) & 0o17, this.regEX);\n};\n\n/**\n * opIDIV(0o230000): Integer Divide\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29:\n *\n * If the operand specified by M is zero, set Overflow and No Divide, and go immediately to the next instruction\n * without affecting the original AC or memory operand in any way. Otherwise divide AC by the specified operand,\n * calculating a quotient of 35 magnitude bits including leading zeros. Place the unrounded quotient in the\n * specified destination. If M specifies AC as the destination, place the remainder, with the same sign as the\n * dividend, in accumulator A+1.\n *\n * NOTE: This is a \"Basic\" mode instruction: the source is [E] and the destination is [A],[A+1] (opposite of \"Memory\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIDIV = function(op, ac)\n{\n var dst = PDP10.doDIV.call(this, this.readWord(this.regEA), this.readWord(ac));\n if (dst < 0) return;\n this.writeWord(ac, dst);\n this.writeWord((ac + 1) & 0o17, this.regEX);\n};\n\n/**\n * opIDIVI(0o231000): Integer Divide Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29:\n *\n * If the operand specified by M is zero, set Overflow and No Divide, and go immediately to the next instruction\n * without affecting the original AC or memory operand in any way. Otherwise divide AC by the specified operand,\n * calculating a quotient of 35 magnitude bits including leading zeros. Place the unrounded quotient in the\n * specified destination. If M specifies AC as the destination, place the remainder, with the same sign as the\n * dividend, in accumulator A+1.\n *\n * NOTE: This is an \"Immediate\" mode instruction: the source is the word 0,E and the destination is [A],[A+1].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIDIVI = function(op, ac)\n{\n var dst = PDP10.doDIV.call(this, this.regEA, this.readWord(ac));\n if (dst < 0) return;\n this.writeWord(ac, dst);\n this.writeWord((ac + 1) & 0o17, this.regEX);\n};\n\n/**\n * opIDIVM(0o232000): Integer Divide to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29:\n *\n * If the operand specified by M is zero, set Overflow and No Divide, and go immediately to the next instruction\n * without affecting the original AC or memory operand in any way. Otherwise divide AC by the specified operand,\n * calculating a quotient of 35 magnitude bits including leading zeros. Place the unrounded quotient in the\n * specified destination. If M specifies AC as the destination, place the remainder, with the same sign as the\n * dividend, in accumulator A+1.\n *\n * NOTE: This is a \"Memory\" mode instruction: the source is [E] and the destination is [E] (opposite of \"Basic\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIDIVM = function(op, ac)\n{\n var dst = PDP10.doDIV.call(this, this.readWord(this.regEA), this.readWord(ac));\n if (dst < 0) return;\n this.writeWord(this.regEA, dst);\n};\n\n/**\n * opIDIVB(0o233000): Integer Divide to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29:\n *\n * If the operand specified by M is zero, set Overflow and No Divide, and go immediately to the next instruction\n * without affecting the original AC or memory operand in any way. Otherwise divide AC by the specified operand,\n * calculating a quotient of 35 magnitude bits including leading zeros. Place the unrounded quotient in the\n * specified destination. If M specifies AC as the destination, place the remainder, with the same sign as the\n * dividend, in accumulator A+1.\n *\n * NOTE: This is a \"Both\" mode instruction: the source is [E] and the destination is [E] and [A],[A+1].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIDIVB = function(op, ac)\n{\n var dst = PDP10.doDIV.call(this, this.readWord(this.regEA), this.readWord(ac));\n if (dst < 0) return;\n this.writeWord(this.regEA, this.writeWord(ac, dst));\n this.writeWord((ac + 1) & 0o17, this.regEX);\n};\n\n/**\n * opDIV(0o234000): Divide\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29:\n *\n * If the magnitude of the number in AC is greater than or equal to that of the operand specified by M,\n * set Overflow and No Divide, and go immediately to the next instruction without affecting the original AC\n * or memory operand in any way. Otherwise divide the double length number contained in accumulators A and A+1\n * by the specified operand, calculating a quotient of 35 magnitude bits including leading zeros. Place the\n * unrounded quotient in the specified destination. If M specifies AC as a destination, place the remainder,\n * with the same sign as the dividend, in accumulator A+1.\n *\n * NOTE: This is a \"Basic\" mode instruction: the source is [E] and the destination is [A],[A+1] (opposite of \"Memory\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opDIV = function(op, ac)\n{\n var ext = this.readWord(ac);\n var dst = this.readWord((ac + 1) & 0o17);\n dst = PDP10.doDIV.call(this, this.readWord(this.regEA), dst, ext);\n if (dst < 0) return;\n this.writeWord(ac, dst);\n this.writeWord((ac + 1) & 0o17, this.regEX);\n};\n\n/**\n * opDIVI(0o235000): Divide Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29:\n *\n * If the magnitude of the number in AC is greater than or equal to that of the operand specified by M,\n * set Overflow and No Divide, and go immediately to the next instruction without affecting the original AC\n * or memory operand in any way. Otherwise divide the double length number contained in accumulators A and A+1\n * by the specified operand, calculating a quotient of 35 magnitude bits including leading zeros. Place the\n * unrounded quotient in the specified destination. If M specifies AC as a destination, place the remainder,\n * with the same sign as the dividend, in accumulator A+1.\n *\n * NOTE: This is an \"Immediate\" mode instruction: the source is the word 0,E and the destination is [A],[A+1].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opDIVI = function(op, ac)\n{\n var ext = this.readWord(ac);\n var dst = this.readWord((ac + 1) & 0o17);\n dst = PDP10.doDIV.call(this, this.regEA, dst, ext);\n if (dst < 0) return;\n this.writeWord(ac, dst);\n this.writeWord((ac + 1) & 0o17, this.regEX);\n};\n\n/**\n * opDIVM(0o236000): Divide to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29:\n *\n * If the magnitude of the number in AC is greater than or equal to that of the operand specified by M,\n * set Overflow and No Divide, and go immediately to the next instruction without affecting the original AC\n * or memory operand in any way. Otherwise divide the double length number contained in accumulators A and A+1\n * by the specified operand, calculating a quotient of 35 magnitude bits including leading zeros. Place the\n * unrounded quotient in the specified destination. If M specifies AC as a destination, place the remainder,\n * with the same sign as the dividend, in accumulator A+1.\n *\n * NOTE: This is a \"Memory\" mode instruction: the source is [E] and the destination is [E] (opposite of \"Basic\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opDIVM = function(op, ac)\n{\n var ext = this.readWord(ac);\n var dst = this.readWord((ac + 1) & 0o17);\n dst = PDP10.doDIV.call(this, this.readWord(this.regEA), dst, ext);\n if (dst < 0) return;\n this.writeWord(this.regEA, dst);\n};\n\n/**\n * opDIVB(0o237000): Divide to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29:\n *\n * If the magnitude of the number in AC is greater than or equal to that of the operand specified by M,\n * set Overflow and No Divide, and go immediately to the next instruction without affecting the original AC\n * or memory operand in any way. Otherwise divide the double length number contained in accumulators A and A+1\n * by the specified operand, calculating a quotient of 35 magnitude bits including leading zeros. Place the\n * unrounded quotient in the specified destination. If M specifies AC as a destination, place the remainder,\n * with the same sign as the dividend, in accumulator A+1.\n *\n * NOTE: This is a \"Both\" mode instruction: the source is [E] and the destination is [E] and [A],[A+1].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opDIVB = function(op, ac)\n{\n var ext = this.readWord(ac);\n var dst = this.readWord((ac + 1) & 0o17);\n dst = PDP10.doDIV.call(this, this.readWord(this.regEA), dst, ext);\n if (dst < 0) return;\n this.writeWord(ac, this.writeWord(this.regEA, dst));\n this.writeWord((ac + 1) & 0o17, this.regEX);\n};\n\n/**\n * opASH(0o240000): Arithmetic Shift\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-31:\n *\n * Arithmetic Shifting\n *\n * These two instructions [ASH, ASHC] produce an arithmetic shift right or left of the number in AC\n * or the double length number in accumulators A and A+1. Shifting is the movement of the contents\n * of a register bit-to-bit. The operation discussed here is similar to logical shifting [see §2.4\n * and the illustration on page 2-24], but in an arithmetic shift only the magnitude part is\n * shifted - the sign is unaffected. In a double length number the 70-bit string made up of the\n * magnitude parts of the two words is shifted, but the sign of the low order word is made equal\n * to the sign of the high order word.\n *\n * Null bits are brought in at the end being vacated: a left shift brings in 0s at the right,\n * whereas a right shift brings in the equivalent of the sign bit at the left. In either case,\n * information shifted out at the other end is lost. A single shift left is equivalent to multiplying\n * the number by 2 (provided no bit of significance is shifted out); a shift right divides the number\n * by 2.\n *\n * The number of places shifted is specified by the result of the effective address calculation\n * taken as a signed number (in twos complement notation) modulo 2^8 in magnitude. In other words\n * the effective shift E is the number composed of bit 18 (which is the sign) and bits 28-35 of the\n * calculation result. Hence the programmer may specify the shift directly in the instruction\n * (perhaps indexed) or give an indirect address to be used in calculating the shift. A positive E\n * produces motion to the left, a negative E to the right; E is thus the power of 2 by which the\n * number is multiplied. Maximum movement is 255 places.\n *\n * ASH: Arithmetic Shift\n *\n * Shift AC arithmetically the number of places specified by E. Do not shift bit 0. If E is positive,\n * shift left bringing 0s into bit 35; data shifted out of bit 1 is lost; set Overflow if any bit of\n * significance is lost (a 1 in a positive number, a 0 in a negative one). If E is negative, shift right\n * bringing 0s into bit 1 if AC is positive, 1s if negative; data shifted out of bit 35 is lost.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opASH = function(op, ac)\n{\n /*\n * Convert the unsigned 18-bit value in regEA to a signed 8-bit value (-256 to 255).\n */\n var s = (((this.regEA & PDP10.HINT_LIMIT) << 14) >> 23) | (this.regEA & 0xff);\n if (s) {\n var v , bits;\n var w = this.readWord(ac);\n if (s > 0) {\n bits = PDP10.INT_MASK;\n v = (w < PDP10.INT_LIMIT)? 0 : PDP10.INT_LIMIT;\n if (s < 35) {\n v += (w * Math.pow(2, s)) % PDP10.INT_LIMIT;\n /*\n * bits must be set to the mask of all magnitude bits shifted out of\n * the original word. Using 8-bit signed words as an example, this table shows\n * the bits values that would correspond to shifting 1-7 bits left:\n *\n * shifts bits value calculation\n * ------ ----------- ------ -----------\n * 1 0b01000000 128-64 128-Math.pow(2, 7-1)\n * 2 0b01100000 128-32 128-Math.pow(2, 7-2)\n * 3 0b01110000 128-16 128-Math.pow(2, 7-3)\n * ...\n * 7 0b01111111 128-1 128-Math.pow(2, 7-7)\n */\n bits = PDP10.INT_LIMIT - Math.pow(2, 35 - s);\n }\n if (w < PDP10.INT_LIMIT) {\n /*\n * Since w was positive, overflow occurs ONLY if any of the bits we shifted out were 1s.\n * If all those bits in the original value (w) were 0s, then adding bits to it could NOT\n * produce a value > INT_MASK.\n */\n if (w + bits > PDP10.INT_MASK) {\n this.regPS |= PDP10.PSFLAG.AROV;\n }\n } else {\n /*\n * Since w was negative, overflow occurs ONLY if any of the bits we shifted out were 0s.\n * If all those bits in the original value (w) were 1s, subtracting bits from it could NOT\n * produce a value <= INT_MASK.\n */\n if (w - bits < PDP10.INT_LIMIT) {\n this.regPS |= PDP10.PSFLAG.AROV;\n }\n }\n } else {\n if (s <= -35) {\n v = (w < PDP10.INT_LIMIT)? 0 : PDP10.INT_MASK;\n } else {\n v = Math.trunc(w / Math.pow(2, -s));\n if (w > PDP10.INT_MASK) {\n bits = PDP10.WORD_LIMIT - Math.pow(2, 36 + s);\n v += bits;\n }\n }\n }\n\n this.writeWord(ac, v);\n }\n};\n\n/**\n * opROT(0o241000): Rotate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-25:\n *\n * Rotate AC the number of places specified by E. If E is positive, rotate left; bit 0 is rotated\n * into bit 35. If E is negative, rotate right; bit 35 is rotated into bit O.\n *\n * The number of places moved is specified by the result of the effective address calculation taken as\n * a signed number (in twos complement notation) modulo 2^8 in magnitude. In other words the effective\n * shift E is the number composed of bit 18 (which is the sign) and bits 28-35 of the calculation result.\n * Hence the programmer may specify the shift directly in the instruction (perhaps indexed) or give an\n * indirect address to be used in calculating the shift. A positive E produces motion to the left,\n * a negative E to the right; maximum movement is 255 places.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opROT = function(op, ac)\n{\n /*\n * Convert the unsigned 18-bit value in regEA to a signed 8-bit value, modulo 36 (+/-35).\n */\n var s = ((((this.regEA & PDP10.HINT_LIMIT) << 14) >> 23) | (this.regEA & 0xff)) % 36;\n if (s) {\n var w = this.readWord(ac);\n /*\n * Note that a right rotation (s < 0) of s bits is equivalent to a left rotation (s > 0) of 36 + s bits.\n */\n if (s < 0) s = 36 + s;\n w = ((w * Math.pow(2, s)) % PDP10.WORD_LIMIT) + Math.trunc(w / Math.pow(2, 36 - s));\n this.writeWord(ac, w);\n }\n};\n\n/**\n * opLSH(0o242000): Logical Shift\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-24:\n *\n * Shift and Rotate\n *\n * The remaining logical instructions shift or rotate right or left the contents of AC or the contents\n * of two accumulators, A and A+1 (mod 20 [base 8]), concatenated into a 72-bit register with A on the\n * left. The illustration below shows the movement of information these instructions produce in the\n * accumulators. In a (logical) shift the contents of a register are moved bit-to-bit with 0s brought\n * in at the end being vacated; information shifted out at the other end is lost. [For a discussion of\n * arithmetic shifting see § 2.5.] In rotation the contents are moved cyclically such that information\n * rotated out at one end is put in at the other.\n *\n * The number of places moved is specified by the result of the effective address calculation taken as a\n * signed number (in twos complement notation) modulo 2^8 in magnitude. In other words the effective shift\n * E is the number composed of bit 18 (which is the sign) and bits 28-35 of the calculation result. Hence\n * the programmer may specify the shift directly in the instruction (perhaps indexed) or give an indirect\n * address to be used in calculating the shift. A positive E produces motion to the left, a negative E to\n * the right; maximum movement is 255 places.\n *\n * LSH: Logical Shift\n *\n * Shift AC the number of places specified by E. If E is positive, shift left bringing 0s into bit 35;\n * data shifted out of bit 0 is lost. If E is negative, shift right bringing 0s into bit 0; data shifted\n * out of bit 35 is lost.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opLSH = function(op, ac)\n{\n /*\n * Convert the unsigned 18-bit value in regEA to a signed 8-bit value (-256 to 255).\n */\n var s = (((this.regEA & PDP10.HINT_LIMIT) << 14) >> 23) | (this.regEA & 0xff);\n if (s) {\n var w = this.readWord(ac);\n if (s > 0) {\n if (s >= 36) {\n w = 0;\n } else {\n w = (w * Math.pow(2, s)) % PDP10.WORD_LIMIT;\n }\n } else {\n if (s <= -36) {\n w = 0;\n } else {\n w = Math.trunc(w / Math.pow(2, -s));\n }\n }\n this.writeWord(ac, w);\n }\n};\n\n/**\n * opJFFO(0o243000): Jump if Find First One\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-56:\n *\n * If AC contains zero, clear AC A+1 and go on to the next instruction in sequence.\n *\n * If AC is not zero, count the number of leading 0s in it (0s to the left of the leftmost 1),\n * and place the count in AC A+1. Take the next instruction from location E and continue sequential\n * operation from there. In either case AC is unaffected, the original contents of AC A +1 are lost.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJFFO = function(op, ac)\n{\n var dst = 0;\n var src = this.readWord(ac);\n if (src) {\n while (src < PDP10.INT_LIMIT) {\n dst++;\n src *= 2;\n }\n this.setPC(this.regEA);\n }\n this.writeWord((ac + 1) & 0o17, dst);\n};\n\n/**\n * opASHC(0o244000): Arithmetic Shift\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-32:\n *\n * Concatenate the magnitude portions of accumulators A and A+1 with A on the left, and shift\n * the 70-bit combination in bits 1-35 and 37-71 the number of places specified by E. Do not shift\n * AC bit 0, but make bit 0 of AC A+1 equal to it if at least one shift occurs (ie if E is nonzero).\n *\n * If E is positive, shift left bringing 0s into bit 71 (bit 35 of AC A+1); bit 37 (bit 1 of AC A+1)\n * is shifted into bit 35; data shifted out of bit 1 is lost; set Overflow if any bit of significance\n * is lost (a 1 in a positive number, a 0 in a negative one). If E is negative, shift right bringing 0s\n * into bit 1 if AC is positive, 1s if negative; bit 35 is shifted into bit 37; data shifted out of\n * bit 71 is lost.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opASHC = function(op, ac)\n{\n /*\n * Convert the unsigned 18-bit value in regEA to a signed 8-bit value (-256 to 255).\n */\n var s = (((this.regEA & PDP10.HINT_LIMIT) << 14) >> 23) | (this.regEA & 0xff);\n if (s) {\n var bits;\n var wLeft = this.readWord(ac);\n var wRight = this.readWord((ac + 1) & 0o17);\n if (s > 0) {\n /*\n * Handle all the left shift cases below, which don't need to worry about sign-extension\n * but DO need to worry about overflow.\n */\n var wLeftOrig = wLeft;\n if (s >= 36) {\n /*\n * Since all wLeft bits are being shifted out, any positive value other than zero OR any negative value\n * other than WORD_MASK indicates an overflow.\n */\n if (wLeft > 0 && wLeft < PDP10.INT_LIMIT || wLeft > PDP10.INT_MASK && wLeft < PDP10.WORD_MASK) {\n this.regPS |= PDP10.PSFLAG.AROV;\n }\n if (s >= 71) {\n /*\n * Since all wRight bits are being shifted out, any positive value other than zero OR any negative value\n * other than WORD_MASK indicates an overflow.\n */\n if (wRight > 0 && wRight < PDP10.INT_LIMIT || wRight > PDP10.INT_MASK && wRight < PDP10.WORD_MASK) {\n this.regPS |= PDP10.PSFLAG.AROV;\n }\n wLeft = 0;\n } else {\n /*\n * Left shift 36-70 bits.\n */\n wLeft = (wRight * Math.pow(2, s - 35)) % PDP10.INT_LIMIT;\n bits = PDP10.INT_LIMIT - Math.pow(2, 70 - s);\n if (wLeftOrig <= PDP10.INT_MASK) {\n /*\n * Since wLeft was positive, overflow occurs ONLY if any of the bits we shifted out were 1s.\n * If all those bits in the original value were 0s, then adding bits to it could NOT produce\n * a value > INT_MASK.\n */\n if (wRight + bits > PDP10.INT_MASK) {\n this.regPS |= PDP10.PSFLAG.AROV;\n }\n } else {\n /*\n * Since wLeft was negative, overflow occurs ONLY if any of the bits we shifted out were 0s.\n * If all those bits in the original value were 1s, subtracting bits from it could NOT produce\n * a value <= INT_MASK.\n */\n if (wRight - bits <= PDP10.INT_MASK) {\n this.regPS |= PDP10.PSFLAG.AROV;\n }\n }\n }\n wRight = 0;\n if (wLeftOrig > PDP10.INT_MASK) {\n wLeft += PDP10.INT_LIMIT;\n wRight += PDP10.INT_LIMIT;\n }\n } else {\n /*\n * Left shift 1-35 bits.\n */\n wLeft = ((wLeft * Math.pow(2, s)) % PDP10.INT_LIMIT) + Math.trunc((wRight % PDP10.INT_LIMIT) / Math.pow(2, 35 - s));\n wRight = (wRight * Math.pow(2, s)) % PDP10.INT_LIMIT;\n /*\n * Determine overflow and update the sign bits.\n */\n bits = PDP10.INT_LIMIT - Math.pow(2, 35 - s);\n if (wLeftOrig <= PDP10.INT_MASK) {\n /*\n * Since wLeft was positive, overflow occurs ONLY if any of the bits we shifted out were 1s.\n * If all those bits in the original value were 0s, then adding bits to it could NOT produce\n * a value > INT_MASK.\n */\n if (wLeftOrig + bits > PDP10.INT_MASK) {\n this.regPS |= PDP10.PSFLAG.AROV;\n }\n } else {\n /*\n * Since wLeft was negative, overflow occurs ONLY if any of the bits we shifted out were 0s.\n * If all those bits in the original value were 1s, subtracting bits from it could NOT produce\n * a value <= INT_MASK.\n */\n if (wLeftOrig - bits <= PDP10.INT_MASK) {\n this.regPS |= PDP10.PSFLAG.AROV;\n }\n /*\n * Last but not least, update the sign bits of wLeft and wRight to indicate negative values.\n */\n wLeft += PDP10.INT_LIMIT;\n wRight += PDP10.INT_LIMIT;\n }\n }\n } else {\n /*\n * Handle all the right shift cases below, which don't need to worry about overflow but DO\n * need to worry about sign-extension.\n */\n if (s <= -36) {\n if (s <= -72) {\n wRight = (wLeft > PDP10.INT_MASK? PDP10.WORD_MASK : 0);\n } else {\n wRight = Math.trunc((wLeft % PDP10.INT_LIMIT) / Math.pow(2, -s - 35));\n }\n if (wLeft <= PDP10.INT_MASK) {\n wLeft = 0;\n } else {\n wLeft = PDP10.WORD_MASK;\n wRight += PDP10.INT_LIMIT;\n }\n } else {\n /*\n * For this right shift of 1-35 bits, determine the value of bits shifted in from the left.\n */\n bits = (wLeft > PDP10.INT_MASK? PDP10.WORD_LIMIT - Math.pow(2, 36 + s) : 0);\n /*\n * The bits that we add to wRight from wLeft must be shifted right one additional bit, because\n * they must \"skip over\" the sign bit of wRight. This means we must zero the sign bit of wRight,\n * which can be done by performing a \"mod\" with INT_LIMIT.\n */\n wRight = Math.trunc((wRight % PDP10.INT_LIMIT) / Math.pow(2, -s)) + (((wLeft % PDP10.INT_LIMIT) * Math.pow(2, 35 + s)) % PDP10.INT_LIMIT);\n wLeft = Math.trunc(wLeft / Math.pow(2, -s)) + bits;\n /*\n * Last but not least, we must set the sign of wRight to the sign of wLeft.\n */\n if (wLeft > PDP10.INT_MASK) wRight += PDP10.INT_LIMIT;\n }\n }\n this.writeWord(ac, wLeft);\n this.writeWord((ac + 1) & 0o17, wRight);\n }\n};\n\n/**\n * opROTC(0o245000): Rotate Combined\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-26:\n *\n * Concatenate accumulators A and A+1 with A on the left, and rotate the 72-bit combination the\n * number of places specified by E. If E is positive, rotate left; bit 0 is rotated into bit 71\n * (bit 35 of AC A+1) and bit 36 into bit 35. If E is negative, rotate right; bit 35 is rotated\n * into bit 36 and bit 71 into bit 0.\n *\n * The number of places moved is specified by the result of the effective address calculation taken as\n * a signed number (in twos complement notation) modulo 2^8 in magnitude. In other words the effective\n * shift E is the number composed of bit 18 (which is the sign) and bits 28-35 of the calculation result.\n * Hence the programmer may specify the shift directly in the instruction (perhaps indexed) or give an\n * indirect address to be used in calculating the shift. A positive E produces motion to the left,\n * a negative E to the right; maximum movement is 255 places.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opROTC = function(op, ac)\n{\n /*\n * Convert the unsigned 18-bit value in regEA to a signed 8-bit value, modulo 72 (+/-71).\n */\n var s = ((((this.regEA & PDP10.HINT_LIMIT) << 14) >> 23) | (this.regEA & 0xff)) % 72;\n if (s) {\n var wLeft = this.readWord(ac);\n var wRight = this.readWord((ac + 1) & 0o17);\n var wLeftOrig = wLeft;\n /*\n * Note that a right rotation (s < 0) of s bits is equivalent to a left rotation (s > 0) of 72 + s bits.\n */\n if (s < 0) s = 72 + s;\n if (s < 36) {\n wLeft = ((wLeft * Math.pow(2, s)) % PDP10.WORD_LIMIT) + Math.trunc(wRight / Math.pow(2, 36 - s));\n wRight = ((wRight * Math.pow(2, s)) % PDP10.WORD_LIMIT) + Math.trunc(wLeftOrig / Math.pow(2, 36 - s));\n } else {\n wLeft = ((wRight * Math.pow(2, s - 36)) % PDP10.WORD_LIMIT) + Math.trunc(wLeft / Math.pow(2, 72 - s));\n wRight = ((wLeftOrig * Math.pow(2, s - 36)) % PDP10.WORD_LIMIT) + Math.trunc(wRight / Math.pow(2, 72 - s));\n }\n this.writeWord(ac, wLeft);\n this.writeWord((ac + 1) & 0o17, wRight);\n }\n};\n\n/**\n * opLSHC(0o246000): Logical Shift Combined\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-25:\n *\n * Concatenate accumulators A and A+1 with A on the left, and shift the 72-bit combination the number\n * of places specified by E. If E is positive, shift left bringing 0s into bit 71 (bit 35 of AC A+1);\n * bit 36 is shifted into bit 35; data shifted out of bit 0 is lost. If E is negative, shift right\n * bringing 0s into bit 0; bit 35 is shifted into bit 36; data shifted out of bit 71 is lost.\n *\n * The number of places moved is specified by the result of the effective address calculation taken as\n * a signed number (in twos complement notation) modulo 2^8 in magnitude. In other words the effective\n * shift E is the number composed of bit 18 (which is the sign) and bits 28-35 of the calculation result.\n * Hence the programmer may specify the shift directly in the instruction (perhaps indexed) or give an\n * indirect address to be used in calculating the shift. A positive E produces motion to the left,\n * a negative E to the right; maximum movement is 255 places.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opLSHC = function(op, ac)\n{\n /*\n * Convert the unsigned 18-bit value in regEA to a signed 8-bit value (-256 to 255).\n */\n var s = (((this.regEA & PDP10.HINT_LIMIT) << 14) >> 23) | (this.regEA & 0xff);\n if (s) {\n var wLeft = this.readWord(ac);\n var wRight = this.readWord((ac + 1) & 0o17);\n if (s > 0) {\n if (s >= 36) {\n if (s >= 72) {\n wLeft = 0;\n } else {\n wLeft = (wRight * Math.pow(2, s - 36)) % PDP10.WORD_LIMIT;\n }\n wRight = 0;\n } else {\n wLeft = ((wLeft * Math.pow(2, s)) % PDP10.WORD_LIMIT) + Math.trunc(wRight / Math.pow(2, 36 - s));\n wRight = (wRight * Math.pow(2, s)) % PDP10.WORD_LIMIT;\n }\n } else {\n if (s <= -36) {\n if (s <= -72) {\n wRight = 0;\n } else {\n wRight = Math.trunc(wLeft / Math.pow(2, -s - 36));\n }\n wLeft = 0;\n } else {\n wRight = Math.trunc(wRight / Math.pow(2, -s)) + ((wLeft * Math.pow(2, 36 + s)) % PDP10.WORD_LIMIT);\n wLeft = Math.trunc(wLeft / Math.pow(2, -s));\n }\n }\n this.writeWord(ac, wLeft);\n this.writeWord((ac + 1) & 0o17, wRight);\n }\n};\n\n/**\n * opEXCH(0o250000): Exchange\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-9:\n *\n * Move the contents of location E to AC and move AC to location E.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opEXCH = function(op, ac)\n{\n var tmp = this.readWord(ac);\n this.writeWord(ac, this.readWord(this.regEA));\n this.writeWord(this.regEA, tmp);\n};\n\n/**\n * opBLT(0o251000): Block Transfer\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-10:\n *\n * Beginning at the location addressed by AC left, move words to another area of memory beginning at the\n * location addressed by AC right. Continue until a word is moved to location E. The total number of words\n * in the block is thus E - AC(right) + 1.\n *\n * CAUTION: Priority interrupts are allowed during the execution of this instruction, following the processing\n * of each word. If an interrupt occurs, the BLT stores the source and destination addresses for the next word\n * in AC, so when the processor restarts upon the return to the interrupted program, it actually resumes at\n * the correct point within the BLT. Therefore, unless the interrupt system is inactive, A and X must not address\n * the same register as this would produce a different effective address calculation upon resumption should an\n * interrupt occur; and the program must not attempt to load an accumulator addressed either by A or X unless it\n * is the final location being loaded. Furthermore, the program cannot assume that AC is the same after the BLT\n * as it was before.\n *\n * TODO: Determine the logic behind SIMH's treatment of the AC register when it's part of the memory being transferred.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opBLT = function(op, ac)\n{\n var fDone = false, fUpdate = false;\n var addrDst = this.readWord(ac);\n var addrSrc = (addrDst / PDP10.HALF_SHIFT)|0;\n addrDst &= PDP10.HALF_MASK;\n while (!fDone) {\n this.writeWord(addrDst, this.readWord(addrSrc));\n /*\n * NOTE: The PDP-10 specs (especially the KA10 Reference Manual) are not very clear on the exit criteria:\n * the transfer stops once AC left >= E, not AC left == E. They are also not very clear on whether the addresses\n * are incremented before or after the exit criteria is checked; however, the KA10 \"DAKAM\" diagnostic seems\n * pretty adamant that, at least after a one-word BLT operation, the addresses should NOT be incremented.\n */\n if (!(fDone = (addrDst >= this.regEA))) {\n addrSrc = (addrSrc + 1) & PDP10.HALF_MASK;\n addrDst = (addrDst + 1) & PDP10.HALF_MASK;\n fUpdate = true;\n }\n if (fDone || !this.isRunning()) {\n /*\n * If the CPU isn't currently running, the CPU is presumably being stepped, so we'll treat that the\n * same as the \"priority interrupt\" condition described above, update the addresses, rewind the PC, and leave.\n */\n if (fUpdate) this.writeWord(ac, addrSrc * PDP10.HALF_SHIFT + addrDst);\n if (!fDone) this.advancePC(-1);\n break;\n }\n }\n};\n\n/**\n * opAOBJP(0o252000): Add One to Both Halves of AC and Jump if Positive\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-41:\n *\n * Add 1000001 [base 8] to AC and place the result back in AC. If the result is greater than or equal\n * to zero (ie if bit 0 is 0, and hence a negative count in the left half has reached zero or a positive\n * count has not yet reached 2^17), take the next instruction from location E and continue sequential\n * operation from there.\n *\n * The incrementing of both halves of AC simultaneously is effected by adding 1000001 [base 8]. A count\n * of -2 in AC left is therefore increased to zero if 2^18 - 1 is incremented in AC right.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOBJP = function(op, ac)\n{\n var dst = (this.readWord(ac) + 0o000001000001) % PDP10.WORD_LIMIT;\n this.writeWord(ac, dst);\n if (dst < PDP10.INT_LIMIT) this.setPC(this.regEA);\n};\n\n/**\n * opAOBJN(0o253000): Add One to Both Halves of AC and Jump if Negative\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-41:\n *\n * Add 1000001 [base 8] to AC and place the result back in AC. If the result is less than zero\n * (ie if bit 0 is 1, and hence a negative count in the left half has not yet reached zero or a positive\n * count has reached 2^17), take the next instruction from location E and continue sequential operation\n * from there.\n *\n * The incrementing of both halves of AC simultaneously is effected by adding 1000001 [base 8]. A count\n * of -2 in AC left is therefore increased to zero if 2^18 - 1 is incremented in AC right.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOBJN = function(op, ac)\n{\n var dst = (this.readWord(ac) + 0o000001000001) % PDP10.WORD_LIMIT;\n this.writeWord(ac, dst);\n if (dst >= PDP10.INT_LIMIT) this.setPC(this.regEA);\n};\n\n/**\n * opJRST(0o254000): Jump and Restore\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-57:\n *\n * Perform the functions specified by F, then take the next instruction from location E and continue sequential\n * operation from there. Bits 9-12 are programmed as follows.\n *\n * 9 Restore the channel on which the highest priority interrupt is currently being held [§ 2.13].\n *\n * Unless the User In-out flag is set, this function cannot be executed in a user program. Instead\n * of restoring the channel, it stores its own instruction code, F and effective address E in bits 0-8,\n * 9-12 and 18-35 respectively of unrelocated location 40 (clearing bits 13-17), and then executes the\n * instruction contained in location 41, which is under control of the monitor [§ 2.15].\n *\n * 10 Halt the processor. When it stops, the MA lights on the console display an address one greater\n * than that of the location containing the instruction that caused the halt, and PC displays the jump\n * address (the location from which the next instruction will be taken if the operator causes the processor\n * to resume operation without changing PC).\n *\n * Unless the User In-out flag is set, this function cannot be executed in a user program. Instead of\n * halting the processor, it stores its own instruction code, F and effective address E in Bits 0-8, 9-12\n * and 18-35 respectively of unrelocated location 40 (clearing bits 13-17), and then executes the\n * instruction contained in location 41, which is under control of the monitor [§ 2.15].\n *\n * 11 Restore the flags listed above from the left half of the word in the last location referenced in the\n * effective address calculation. Hence to restore flags requires that the JRST instruction use indexing\n * or indirect addressing.\n *\n * Restoration of all but the user flags is directly according to the contents of the corresponding bits\n * as given above: a flag is set by a 1 in the bit, cleared by a 0. A 1 in bit 5 sets User but a 0 has no\n * effect, so the Monitor can restart a user program by restoring flags but the user cannot leave user\n * mode by this method. A 0 in bit 6 clears User In-out, but a 1 sets it only if the JRST is being\n * executed by the Monitor, ie if User is clear.\n *\n * 12 Enter user mode. The user program starts at relocated location E.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJRST = function(op, ac)\n{\n if (ac & 0b0001) {\n /*\n * Enter user mode.\n */\n this.setUserMode();\n }\n if (ac & 0b0010) {\n /*\n * Restore the flags.\n */\n this.setPS((this.regLA / PDP10.HALF_SHIFT)|0);\n }\n if (ac & 0b0100) {\n /*\n * Halt the processor.\n */\n this.stopCPU();\n }\n if (ac & 0b1000) {\n /*\n * Restore interrupt channel.\n */\n this.opUndefined(op);\n }\n this.setPC(this.regEA);\n};\n\n/**\n * opJFCL(0o255000): Jump on Flag and Clear\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-57:\n *\n * If any flag specified by F [ac] is set, clear it and take the next instruction from location E,\n * continuing sequential operation from there.\n *\n * To select one or a combination of these flags (which are among those described above) the programmer can specify\n * the equivalent of an AC address that places 1s in the appropriate bits, but MACRO recognizes mnemonics for some of\n * the 13-bit instruction codes (bits 0-12).\n *\n * JFCL JFCL 0, No-op 25500\n * JOV JFCL 10, Jump on Overflow 25540\n * JCRY0 JFCL 4, Jump on Carry 0 25520\n * JCRY1 JFCL 2, Jump on Carry 1 25510\n * JCRY JFCL 6, Jump on Carry 0 or 1 25530\n * JFOV JFCL 1, Jump on Floating Overflow 25504\n *\n * SIDEBAR: This instruction can be used simply to clear the selected flags by having the jump address point to the\n * next consecutive location, as in:\n *\n * JFCL 17,.+1\n *\n * which clears all four flags without disrupting the normal program sequence. A JFCL that selects no flag is the fastest\n * no-op as it neither fetches nor stores an operand, and bits 18-35 of the instruction word can be used to store information.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJFCL = function(op, ac)\n{\n /*\n * The ac (F) bits from the opcode align perfectly with the top 4 bits of regPS; all we have to do is shift ac left 14.\n */\n var bitsPS = ac << 14;\n if (this.regPS & bitsPS) {\n this.regPS &= ~bitsPS;\n this.setPC(this.regEA);\n }\n};\n\n/**\n * opXCT(0o256000): Execute\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-56:\n *\n * Execute the contents of location E as an instruction. Any instruction may be executed, including another XCT.\n * If an XCT executes a skip instruction, the skip is relative to the location of the XCT (the first XCT if there\n * are several in a chain). If an XCT executes a jump, program flow is altered as specified by the jump (no matter\n * how many XCTs precede a jump instruction, when PC is saved it contains an address one greater than the location\n * of the first XCT in the chain).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opXCT = function(op, ac)\n{\n this.regXC = this.regEA;\n};\n\n/**\n * opPUSHJ(0o260000): Push Down and Jump\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-62:\n *\n * Add 1000001 [base 8] to AC to increment both halves by one and place the result back in AC. If the addition\n * causes the count in AC left to reach zero, set the Pushdown Overflow flag. Then place the current contents of\n * the flags (as described above) in the left half of the location now addressed by AC right and the contents of\n * PC in the right half of that location (at this time PC contains an address one greater than the location of\n * the PUSHJ instruction). Take the next instruction from location E and continue sequential operation from there.\n *\n * The flags are unaffected except Byte Interrupt, which is cleared. The original contents of the location added\n * to the list are lost. If this instruction is executed as a result of a priority interrupt or in unrelocated\n * 41 or 61 while the processor is in user mode, bit 5 of the PC word stored is 1 and the processor leaves user mode.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opPUSHJ = function(op, ac)\n{\n var p = (this.readWord(ac) + 0o000001000001) % PDP10.WORD_LIMIT;\n this.writeWord(ac, p);\n if (!((p / PDP10.HALF_SHIFT)|0)) {\n this.regPS |= PDP10.PSFLAG.PDOV;\n }\n this.writeWord(p & PDP10.ADDR_MASK, this.getPS() * PDP10.HALF_SHIFT + this.getPC());\n this.regPS &= ~PDP10.PSFLAG.BIS; // TODO: Verify that BIS is cleared AFTER calling getPS()\n this.setPC(this.regEA);\n};\n\n/**\n * opPUSH(0o261000): Push Down\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-13:\n *\n * Add 000001 000001 to AC to increment both halves by one, then move the contents of location E to the\n * location now addressed by AC right. If the addition causes the count in AC left to reach zero, set the\n * Pushdown Overflow flag. The contents of E are unaffected, the original contents of the location added\n * to the list are lost.\n *\n * If we trusted SIMH, then we could not literally interpret this instruction as adding 000001 000001 to AC,\n * because if AC contained 777777 777777, adding 000001 000001 would result in 000001 000000, not 000000 000000,\n * and yet 000000 000000 is EXACTLY what we get in SIMH.\n *\n * And yet, DEC's documentation clearly contradicts what SIMH is doing:\n *\n * The incrementing and decrementing of both halves of AC simultaneously is effected by adding and subtracting\n * 000001 000001. Hence a count of -2 in AC left is increased to zero if 2^18 - 1 is incremented in AC right,\n * and conversely, 1 in AC left is decreased to -1 if zero is decremented in AC right.\n *\n * Perhaps SIMH is simply emulating the behavior of some later PDP-10 model, which performed independent increments?\n *\n * TODO: Investigate.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opPUSH = function(op, ac)\n{\n var p = this.readWord(ac);\n if (!PDP10.SIMH) {\n /*\n * This is the behavior that is clearly documented by DEC.\n */\n p += 0o000001000001;\n this.writeWord(p & PDP10.ADDR_MASK, this.readWord(this.regEA));\n if (p >= PDP10.WORD_LIMIT) p -= PDP10.WORD_LIMIT;\n if (!((p / PDP10.HALF_SHIFT)|0)) {\n this.regPS |= PDP10.PSFLAG.PDOV;\n }\n } else {\n /*\n * This is the SIMH behavior, which appears to increment each half of AC independently.\n */\n var addr = (p + 1) & PDP10.ADDR_MASK;\n this.writeWord(addr, this.readWord(this.regEA));\n p = (p + 0o000001000000) - (p & PDP10.ADDR_MASK) + addr;\n if (p >= PDP10.WORD_LIMIT) {\n p -= PDP10.WORD_LIMIT;\n this.regPS |= PDP10.PSFLAG.PDOV;\n }\n }\n this.writeWord(ac, p);\n};\n\n/**\n * opPOP(0o262000): Pop Up\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-13:\n *\n * Move the contents of the location addressed by AC right to location E, then subtract 000001 000001\n * from AC to decrement both halves by one. If the subtraction causes the count in AC left to reach -1,\n * set the Pushdown Overflow flag. The original contents of E are lost.\n *\n * NOTE: Because of the order in which the operands are stored, the instruction POP AC,AC would load the\n * contents of the location addressed by AC right into AC on top of the pushdown count, destroying it.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opPOP = function(op, ac)\n{\n var p = this.readWord(ac);\n var src = this.readWord(p & PDP10.ADDR_MASK);\n this.writeWord(this.regEA, src);\n if (this.regEA == ac) p = src; // this avoids re-reading the accumulator if the write just overwrote it\n p -= 0o000001000001;\n if (p < 0) p += PDP10.WORD_LIMIT;\n if (((p / PDP10.HALF_SHIFT)|0) == PDP10.HALF_MASK) {\n this.regPS |= PDP10.PSFLAG.PDOV;\n }\n this.writeWord(ac, p);\n};\n\n/**\n * opPOPJ(0o263000): Pop Up and Jump\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-63:\n *\n * Subtract 1000001 [base 8] from AC to decrement both halves by one and place the result back in AC.\n * If the subtraction causes the count in AC left to reach -1, set the Pushdown Overflow flag. Take the\n * next instruction from the location addressed by the right half of the location that was addressed by\n * AC right prior to the decrementing, and continue sequential operation from there.\n *\n * SIDEBAR: The effective address E is ignored.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opPOPJ = function(op, ac)\n{\n var p = this.readWord(ac);\n var pc = this.readWord(p & PDP10.ADDR_MASK);\n p -= 0o000001000001;\n if (p < 0) p += PDP10.WORD_LIMIT;\n if (((p / PDP10.HALF_SHIFT)|0) == PDP10.HALF_MASK) {\n this.regPS |= PDP10.PSFLAG.PDOV;\n }\n this.writeWord(ac, p);\n this.setPC(pc & PDP10.ADDR_MASK);\n};\n\n/**\n * opJSR(0o264000): Jump to Subroutine\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-57:\n *\n * Place the current contents of the flags (as described above) in the left half of location E and the\n * contents of PC in the right half (at this time PC contains an address one greater than the location of\n * the JSR instruction). Take the next instruction from location E + 1 and continue sequential operation\n * from there. The flags are unaffected except Byte Interrupt, which is cleared.\n *\n * If this instruction is executed as a result of a priority interrupt or in un-relocated 41 or 61 while\n * the processor is in user mode, bit 5 of the PC word stored is 1 and the processor leaves user mode.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJSR = function(op, ac)\n{\n this.writeWord(this.regEA, this.getPS() * PDP10.HALF_SHIFT + this.getPC());\n this.regPS &= ~PDP10.PSFLAG.BIS; // TODO: Verify that BIS is cleared AFTER calling getPS()\n this.setPC(this.regEA + 1);\n};\n\n/**\n * opJSP(0o265000): Jump and Save PC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-58:\n *\n * Place the current contents of the flags (as described above) in AC left and the contents of PC in AC right\n * (at this time PC contains an address one greater than the location of the JSP instruction). Take the next\n * instruction from location E and continue sequential operation from there. The flags are unaffected except\n * Byte Interrupt, which is cleared.\n *\n * If this instruction is executed as a result of a priority interrupt or in un-relocated 41 or 61 while the\n * processor is in user mode, bit 5 of the PC word stored is 1 and the processor leaves user mode.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJSP = function(op, ac)\n{\n this.writeWord(ac, this.getPS() * PDP10.HALF_SHIFT + this.getPC());\n this.regPS &= ~PDP10.PSFLAG.BIS; // TODO: Verify that BIS is cleared AFTER calling getPS()\n this.setPC(this.regEA);\n};\n\n/**\n * opJSA(0o266000): Jump and Save AC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-61:\n *\n * Place AC in location E, the effective address E in AC left, and the contents of PC in AC right (at this time\n * PC contains an address one greater than the location of the JSA instruction). Take the next instruction from\n * location E + 1 and continue sequential operation from there. The original contents of E are lost.\n *\n * If this instruction is executed as a result of a priority interrupt or in unrelocated 41 or 61 while the processor\n * is in user mode, bit 5 of the PC word stored is 1 and the processor leaves user mode.\n *\n * Regarding JSA and JRA:\n *\n * A JSA combines advantages of the JSR and JSP. JSA does modify memory, but it saves PC in an accumulator\n * without losing its previous contents (at a cost of not saving the flags). It is thus convenient for multiple-entry\n * subroutines. In a subroutine called by a JSR, the returning JRST must refer to the (single) entry point.\n * Since a JRA can retrieve the original PC by addressing AC as an index register, it is independent of any entry point\n * without tying up an accumulator to the extent a JSP would.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJSA = function(op, ac)\n{\n this.writeWord(this.regEA, this.readWord(ac));\n this.writeWord(ac, this.regEA * PDP10.HALF_SHIFT + this.getPC());\n this.setPC(this.regEA + 1);\n};\n\n/**\n * opJRA(0o267000): Jump and Restore AC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-61:\n *\n * Place the contents of the location addressed by AC left into AC. Take the next instruction from location E and\n * continue sequential operation from there.\n *\n * This opcode functions as the counterpart to JSA, but ONLY if location E (the effective address calculated by the JRA) indexes\n * with the same AC that was used with the JSA.\n *\n * JSA 17,F1\n * R1: ...\n * ...\n * F1: 0 ; location to save AC 17, as specified by the A field of \"JSA 17,F1\"\n * F2: ... ; first instruction executed after \"JSA 17,F1\"\n * JRA 17,(17) ; return to R1, after restoring AC 17\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJRA = function(op, ac)\n{\n var acc = this.readWord(ac);\n this.writeWord(ac, this.readWord((acc / PDP10.HALF_SHIFT)|0));\n this.setPC(this.regEA);\n};\n\n/**\n * opADD(0o270000): Add\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27:\n *\n * Add the operand specified by M to AC and place the result in the specified destination. If the sum is >= 2^35\n * set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the sum less 2^35.\n * If the sum is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but a magnitude in negative form equal\n * to the sum plus 2^35. Set both carry flags if both summands are negative, or their signs differ and their magnitudes\n * are equal or the positive one is the greater in magnitude.\n *\n * NOTE: This is a \"Basic\" mode instruction: the source is [E] and the destination is [A] (opposite of \"Memory\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opADD = function(op, ac)\n{\n this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opADDI(0o271000): Add Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27:\n *\n * Add the operand specified by M to AC and place the result in the specified destination. If the sum is >= 2^35\n * set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the sum less 2^35.\n * If the sum is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but a magnitude in negative form equal\n * to the sum plus 2^35. Set both carry flags if both summands are negative, or their signs differ and their magnitudes\n * are equal or the positive one is the greater in magnitude.\n *\n * NOTE: This is an \"Immediate\" mode instruction: the source is the word 0,E and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opADDI = function(op, ac)\n{\n this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), this.regEA));\n};\n\n/**\n * opADDM(0o272000): Add to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27:\n *\n * Add the operand specified by M to AC and place the result in the specified destination. If the sum is >= 2^35\n * set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the sum less 2^35.\n * If the sum is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but a magnitude in negative form equal\n * to the sum plus 2^35. Set both carry flags if both summands are negative, or their signs differ and their magnitudes\n * are equal or the positive one is the greater in magnitude.\n *\n * NOTE: This is a \"Memory\" mode instruction: the source is [E] and the destination is [E] (opposite of \"Basic\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opADDM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opADDB(0o273000): Add to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27:\n *\n * Add the operand specified by M to AC and place the result in the specified destination. If the sum is >= 2^35\n * set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the sum less 2^35.\n * If the sum is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but a magnitude in negative form equal\n * to the sum plus 2^35. Set both carry flags if both summands are negative, or their signs differ and their magnitudes\n * are equal or the positive one is the greater in magnitude.\n *\n * NOTE: This is a \"Both\" mode instruction: the source is [E] and the destination is [E] and [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opADDB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), this.readWord(this.regEA))));\n};\n\n/**\n * opSUB(0o274000): Subtract\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27:\n *\n * Subtract the operand specified by M from AC and place the result in the specified destination. If the difference\n * is >= 2^35 set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the\n * difference less 2^35. If the difference is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but\n * a magnitude in negative form equal to the difference plus 2^35. Set both carry flags if the signs of the operands are\n * the same and AC is the greater or the two are equal, or the signs of the operands differ and AC is negative.\n *\n * NOTE: This is a \"Basic\" mode instruction: the source is [E] and the destination is [A] (opposite of \"Memory\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSUB = function(op, ac)\n{\n this.writeWord(ac, PDP10.doSUB.call(this, this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opSUBI(0o275000): Subtract Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27:\n *\n * Subtract the operand specified by M from AC and place the result in the specified destination. If the difference\n * is >= 2^35 set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the\n * difference less 2^35. If the difference is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but\n * a magnitude in negative form equal to the difference plus 2^35. Set both carry flags if the signs of the operands are\n * the same and AC is the greater or the two are equal, or the signs of the operands differ and AC is negative.\n *\n * NOTE: This is an \"Immediate\" mode instruction: the source is the word 0,E and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSUBI = function(op, ac)\n{\n this.writeWord(ac, PDP10.doSUB.call(this, this.readWord(ac), this.regEA));\n};\n\n/**\n * opSUBM(0o276000): Subtract to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27:\n *\n * Subtract the operand specified by M from AC and place the result in the specified destination. If the difference\n * is >= 2^35 set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the\n * difference less 2^35. If the difference is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but\n * a magnitude in negative form equal to the difference plus 2^35. Set both carry flags if the signs of the operands are\n * the same and AC is the greater or the two are equal, or the signs of the operands differ and AC is negative.\n *\n * NOTE: This is a \"Memory\" mode instruction: the source is [E] and the destination is [E] (opposite of \"Basic\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSUBM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.doSUB.call(this, this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opSUBB(0o277000): Subtract to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27:\n *\n * Subtract the operand specified by M from AC and place the result in the specified destination. If the difference\n * is >= 2^35 set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the\n * difference less 2^35. If the difference is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but\n * a magnitude in negative form equal to the difference plus 2^35. Set both carry flags if the signs of the operands are\n * the same and AC is the greater or the two are equal, or the signs of the operands differ and AC is negative.\n *\n * NOTE: This is a \"Both\" mode instruction: the source is [E] and the destination is [E] and [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSUBB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.doSUB.call(this, this.readWord(ac), this.readWord(this.regEA))));\n};\n\n/**\n * opCAIL(0o301000): Compare AC Immediate and Skip if AC Less than E\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42:\n *\n * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition\n * specified by M is satisfied.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAIL = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.regEA) < 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAIE(0o302000): Compare AC Immediate and Skip if Equal\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42:\n *\n * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition\n * specified by M is satisfied.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAIE = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.regEA) == 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAILE(0o303000): Compare AC Immediate and Skip if AC Less than or Equal to E\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42:\n *\n * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition\n * specified by M is satisfied.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAILE = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.regEA) <= 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAIA(0o304000): Compare AC Immediate but Always Skip\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42:\n *\n * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition\n * specified by M is satisfied.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAIA = function(op, ac)\n{\n // TODO: Determine if there's any need to actually perform the comparison.\n this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAIGE(0o305000): Compare AC Immediate and Skip if AC Greater than or Equal to E\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42:\n *\n * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition\n * specified by M is satisfied.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAIGE = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.regEA) >= 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAIN(0o306000): Compare AC Immediate and Skip if Not Equal\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42:\n *\n * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition\n * specified by M is satisfied.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAIN = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.regEA) != 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAIG(0o307000): Compare AC Immediate and Skip if AC Greater than E\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42:\n *\n * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition\n * specified by M is satisfied.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAIG = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.regEA) > 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAML(0o311000): Compare AC with Memory and Skip if AC Less\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC with the contents of location E and skip the next instruction in sequence if the condition\n * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized\n * floating point.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAML = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.readWord(this.regEA)) < 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAME(0o312000): Compare AC with Memory and Skip if Equal\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC with the contents of location E and skip the next instruction in sequence if the condition\n * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized\n * floating point.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAME = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.readWord(this.regEA)) == 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAMLE(0o313000): Compare AC with Memory and Skip if AC Less or Equal\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC with the contents of location E and skip the next instruction in sequence if the condition\n * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized\n * floating point.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAMLE = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.readWord(this.regEA)) <= 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAMA(0o314000): Compare AC with Memory but Always Skip\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC with the contents of location E and skip the next instruction in sequence if the condition\n * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized\n * floating point.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAMA = function(op, ac)\n{\n // TODO: Determine if there's any need to actually perform the comparison.\n this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAMGE(0o315000): Compare AC with Memory and Skip if AC Greater or Equal\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC with the contents of location E and skip the next instruction in sequence if the condition\n * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized\n * floating point.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAMGE = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.readWord(this.regEA)) >= 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAMN(0o316000): Compare AC with Memory and Skip if Not Equal\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC with the contents of location E and skip the next instruction in sequence if the condition\n * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized\n * floating point.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAMN = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.readWord(this.regEA)) != 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAMG(0o317000): Compare AC with Memory and Skip if AC Greater\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC with the contents of location E and skip the next instruction in sequence if the condition\n * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized\n * floating point.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAMG = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.readWord(this.regEA)) > 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opJUMPL(0o321000): Jump if AC Less than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied,\n * take the next instruction from location E and continue sequential operation from there.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJUMPL = function(op, ac)\n{\n if (PDP10.SIGN(this.readWord(ac)) < 0) this.setPC(this.regEA);\n};\n\n/**\n * opJUMPE(0o322000): Jump if AC Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied,\n * take the next instruction from location E and continue sequential operation from there.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJUMPE = function(op, ac)\n{\n if (PDP10.SIGN(this.readWord(ac)) == 0) this.setPC(this.regEA);\n};\n\n/**\n * opJUMPLE(0o323000): Jump if AC Less than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied,\n * take the next instruction from location E and continue sequential operation from there.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJUMPLE = function(op, ac)\n{\n if (PDP10.SIGN(this.readWord(ac)) <= 0) this.setPC(this.regEA);\n};\n\n/**\n * opJUMPA(0o324000): Jump Always\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied,\n * take the next instruction from location E and continue sequential operation from there.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJUMPA = function(op, ac)\n{\n this.setPC(this.regEA);\n};\n\n/**\n * opJUMPGE(0o325000): Jump if AC Greater than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied,\n * take the next instruction from location E and continue sequential operation from there.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJUMPGE = function(op, ac)\n{\n if (PDP10.SIGN(this.readWord(ac)) >= 0) this.setPC(this.regEA);\n};\n\n/**\n * opJUMPN(0o326000): Jump if AC Not Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied,\n * take the next instruction from location E and continue sequential operation from there.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJUMPN = function(op, ac)\n{\n if (PDP10.SIGN(this.readWord(ac)) != 0) this.setPC(this.regEA);\n};\n\n/**\n * opJUMPG(0o327000): Jump if AC Greater than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied,\n * take the next instruction from location E and continue sequential operation from there.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJUMPG = function(op, ac)\n{\n if (PDP10.SIGN(this.readWord(ac)) > 0) this.setPC(this.regEA);\n};\n\n/**\n * opSKIP(0o330000): Do Not Skip\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction\n * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents\n * of location E in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSKIP = function(op, ac)\n{\n if (ac) this.writeWord(ac, this.readWord(this.regEA));\n};\n\n/**\n * opSKIPL(0o331000): Skip if Memory Less than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction\n * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents\n * of location E in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSKIPL = function(op, ac)\n{\n var dst = this.readWord(this.regEA);\n if (PDP10.SIGN(dst) < 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSKIPE(0o332000): Skip if Memory Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction\n * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents\n * of location E in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSKIPE = function(op, ac)\n{\n var dst = this.readWord(this.regEA);\n if (PDP10.SIGN(dst) == 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSKIPLE(0o333000): Skip if Memory Less than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction\n * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents\n * of location E in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSKIPLE = function(op, ac)\n{\n var dst = this.readWord(this.regEA);\n if (PDP10.SIGN(dst) <= 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSKIPA(0o334000): Skip Always\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction\n * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents\n * of location E in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSKIPA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, this.readWord(this.regEA));\n};\n\n/**\n * opSKIPGE(0o335000): Skip if Memory Greater than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction\n * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents\n * of location E in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSKIPGE = function(op, ac)\n{\n var dst = this.readWord(this.regEA);\n if (PDP10.SIGN(dst) >= 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSKIPN(0o336000): Skip if Memory Not Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction\n * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents\n * of location E in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSKIPN = function(op, ac)\n{\n var dst = this.readWord(this.regEA);\n if (PDP10.SIGN(dst) != 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSKIPG(0o337000): Skip if Memory Greater than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction\n * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents\n * of location E in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSKIPG = function(op, ac)\n{\n var dst = this.readWord(this.regEA);\n if (PDP10.SIGN(dst) > 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opAOJ(0o340000): Add One to AC but Do Not Jump\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Increment AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue\n * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1\n * flags; if -1, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOJ = function(op, ac)\n{\n this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1));\n};\n\n/**\n * opAOJL(0o341000): Add One to AC and Jump if Less than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Increment AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue\n * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1\n * flags; if -1, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOJL = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1));\n if (PDP10.SIGN(dst) < 0) this.setPC(this.regEA);\n};\n\n/**\n * opAOJE(0o342000): Add One to AC and Jump if Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Increment AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue\n * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1\n * flags; if -1, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOJE = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1));\n if (PDP10.SIGN(dst) == 0) this.setPC(this.regEA);\n};\n\n/**\n * opAOJLE(0o343000): Add One to AC and Jump if Less than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Increment AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue\n * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1\n * flags; if -1, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOJLE = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1));\n if (PDP10.SIGN(dst) <= 0) this.setPC(this.regEA);\n};\n\n/**\n * opAOJA(0o344000): Add One to AC and Jump Always\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Increment AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue\n * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1\n * flags; if -1, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOJA = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1));\n this.setPC(this.regEA);\n};\n\n/**\n * opAOJGE(0o345000): Add One to AC and Jump if Greater than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Increment AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue\n * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1\n * flags; if -1, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOJGE = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1));\n if (PDP10.SIGN(dst) >= 0) this.setPC(this.regEA);\n};\n\n/**\n * opAOJN(0o346000): Add One to AC and Jump if Not Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Increment AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue\n * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1\n * flags; if -1, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOJN = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1));\n if (PDP10.SIGN(dst) != 0) this.setPC(this.regEA);\n};\n\n/**\n * opAOJG(0o347000): Add One to AC and Jump if Greater than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Increment AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue\n * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1\n * flags; if -1, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOJG = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1));\n if (PDP10.SIGN(dst) > 0) this.setPC(this.regEA);\n};\n\n/**\n * opAOS(0o350000): Add One to Memory but Do Not Skip\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Increment the contents of location E by one and place the result back in E. Compare the result\n * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied.\n * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0\n * and Carry 1. If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOS = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1));\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opAOSL(0o351000): Add One to Memory and Skip if Less than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Increment the contents of location E by one and place the result back in E. Compare the result\n * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied.\n * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0\n * and Carry 1. If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOSL = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1));\n if (PDP10.SIGN(dst) < 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opAOSE(0o352000): Add One to Memory and Skip if Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Increment the contents of location E by one and place the result back in E. Compare the result\n * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied.\n * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0\n * and Carry 1. If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOSE = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1));\n if (PDP10.SIGN(dst) == 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opAOSLE(0o353000): Add One to Memory and Skip if Less than to Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Increment the contents of location E by one and place the result back in E. Compare the result\n * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied.\n * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0\n * and Carry 1. If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOSLE = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1));\n if (PDP10.SIGN(dst) <= 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opAOSA(0o354000): Add One to Memory and Skip Always\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Increment the contents of location E by one and place the result back in E. Compare the result\n * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied.\n * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0\n * and Carry 1. If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOSA = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1));\n this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opAOSGE(0o355000): Add One to Memory and Skip if Greater than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Increment the contents of location E by one and place the result back in E. Compare the result\n * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied.\n * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0\n * and Carry 1. If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOSGE = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1));\n if (PDP10.SIGN(dst) >= 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opAOSN(0o356000): Add One to Memory and Skip if Not Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Increment the contents of location E by one and place the result back in E. Compare the result\n * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied.\n * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0\n * and Carry 1. If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOSN = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1));\n if (PDP10.SIGN(dst) != 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opAOSG(0o357000): Add One to Memory and Skip if Greater than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Increment the contents of location E by one and place the result back in E. Compare the result\n * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied.\n * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0\n * and Carry 1. If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOSG = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1));\n if (PDP10.SIGN(dst) > 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSOJ(0o360000): Subtract One from AC but Do Not Jump\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue sequential\n * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any\n * other nonzero number, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOJ = function(op, ac)\n{\n this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK));\n};\n\n/**\n * opSOJL(0o361000): Subtract One from AC and Jump if Less than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue sequential\n * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any\n * other nonzero number, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOJL = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) < 0) this.setPC(this.regEA);\n};\n\n/**\n * opSOJE(0o362000): Subtract One from AC and Jump if Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue sequential\n * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any\n * other nonzero number, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOJE = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) == 0) this.setPC(this.regEA);\n};\n\n/**\n * opSOJLE(0o363000): Subtract One from AC and Jump if Less than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue sequential\n * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any\n * other nonzero number, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOJLE = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) <= 0) this.setPC(this.regEA);\n};\n\n/**\n * opSOJA(0o364000): Subtract One from AC and Jump Always\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue sequential\n * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any\n * other nonzero number, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOJA = function(op, ac)\n{\n this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK));\n this.setPC(this.regEA);\n};\n\n/**\n * opSOJGE(0o365000): Subtract One from AC and Jump if Greater than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue sequential\n * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any\n * other nonzero number, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOJGE = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) >= 0) this.setPC(this.regEA);\n};\n\n/**\n * opSOJN(0o366000): Subtract One from AC and Jump if Not Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue sequential\n * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any\n * other nonzero number, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOJN = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) != 0) this.setPC(this.regEA);\n};\n\n/**\n * opSOJG(0o367000): Subtract One from AC and Jump if Greater than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue sequential\n * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any\n * other nonzero number, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOJG = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) > 0) this.setPC(this.regEA);\n};\n\n/**\n * opSOS(0o370000): Subtract One from Memory but Do Not Skip\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46:\n *\n * Decrement the contents of location E by one and place the result back in E. Compare the result with zero,\n * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally\n * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1.\n * If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOS = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK));\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSOSL(0o371000): Subtract One from Memory and Skip if Less than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46:\n *\n * Decrement the contents of location E by one and place the result back in E. Compare the result with zero,\n * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally\n * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1.\n * If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOSL = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) < 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSOSE(0o372000): Subtract One from Memory and Skip if Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46:\n *\n * Decrement the contents of location E by one and place the result back in E. Compare the result with zero,\n * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally\n * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1.\n * If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOSE = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) == 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSOSLE(0o373000): Subtract One from Memory and Skip if Less than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46:\n *\n * Decrement the contents of location E by one and place the result back in E. Compare the result with zero,\n * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally\n * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1.\n * If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOSLE = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) <= 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSOSA(0o374000): Subtract One from Memory and Skip Always\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46:\n *\n * Decrement the contents of location E by one and place the result back in E. Compare the result with zero,\n * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally\n * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1.\n * If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOSA = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK));\n this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSOSGE(0o375000): Subtract One from Memory and Skip if Greater than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46:\n *\n * Decrement the contents of location E by one and place the result back in E. Compare the result with zero,\n * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally\n * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1.\n * If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOSGE = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) >= 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSOSN(0o376000): Subtract One from Memory and Skip if Not Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46:\n *\n * Decrement the contents of location E by one and place the result back in E. Compare the result with zero,\n * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally\n * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1.\n * If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOSN = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) != 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSOSG(0o377000): Subtract One from Memory and Skip if Greater than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46:\n *\n * Decrement the contents of location E by one and place the result back in E. Compare the result with zero,\n * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally\n * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1.\n * If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOSG = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) > 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSETZ(0o400000): Set to Zeros\n * opSETZI(0o401000): Set to Zeros Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-18:\n *\n * Change the contents of the destination specified by M to all 0s.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETZ = function(op, ac)\n{\n this.writeWord(ac, 0);\n};\n\n/**\n * opSETZM(0o402000): Set to Zeros Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-18:\n *\n * Change the contents of the destination specified by M to all 0s.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETZM = function(op, ac)\n{\n this.writeWord(this.regEA, 0);\n};\n\n/**\n * opSETZB(0o403000): Set to Zeros Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-18:\n *\n * Change the contents of the destination specified by M to all 0s.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETZB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, 0));\n};\n\n/**\n * opAND(0o404000): And with AC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([AC]) to the AND function of the specified operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAND = function(op, ac)\n{\n this.writeWord(ac, PDP10.AND(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opANDI(0o405000): And with AC Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([AC]) to the AND function of the specified operand (E) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDI = function(op, ac)\n{\n this.writeWord(ac, PDP10.AND(this.readWord(ac), this.regEA));\n};\n\n/**\n * opANDM(0o406000): And with AC to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([E]) to the AND function of the specified operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.AND(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opANDB(0o407000): And with AC to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the AND function of the specified operand ([E])\n * and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.AND(this.readWord(ac), this.readWord(this.regEA))));\n};\n\n/**\n * opANDCA(0o410000): And with Complement of AC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([AC]) to the AND function of the specified operand ([E])\n * and the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCA = function(op, ac)\n{\n this.writeWord(ac, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opANDCAI(0o411000): And with Complement of AC Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([AC]) to the AND function of the specified operand (E)\n * and the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCAI = function(op, ac)\n{\n this.writeWord(ac, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), this.regEA));\n};\n\n/**\n * opANDCAM(0o412000): And with Complement of AC to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([E]) to the AND function of the specified operand ([E])\n * and the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCAM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opANDCAB(0o413000): And with Complement of AC to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the AND function of the specified operand ([E])\n * and the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCAB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), this.readWord(this.regEA))));\n};\n\n/**\n * opANDCM(0o420000): And Complement of Memory with AC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([AC]) to the AND function of the complement of the specified\n * operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCM = function(op, ac)\n{\n this.writeWord(ac, PDP10.AND(this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA)));\n};\n\n/**\n * opANDCMI(0o421000): And Complement of Memory Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([AC]) to the AND function of the complement of the specified\n * operand (E) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCMI = function(op, ac)\n{\n this.writeWord(ac, PDP10.AND(this.readWord(ac), PDP10.WORD_MASK - this.regEA));\n};\n\n/**\n * opANDCMM(0o422000): And Complement of Memory to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([E]) to the AND function of the complement of the specified\n * operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCMM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.AND(this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA)));\n};\n\n/**\n * opANDCMB(0o423000): And Complement of Memory to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the AND function of the complement of the specified\n * operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCMB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.AND(this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA))));\n};\n\n/**\n * opXOR(0o430000): Exclusive Or with AC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([AC]) to the exclusive OR function of the specified\n * operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opXOR = function(op, ac)\n{\n this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opXORI(0o431000): Exclusive Or Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([AC]) to the exclusive OR function of the specified\n * operand (E) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opXORI = function(op, ac)\n{\n this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.regEA));\n};\n\n/**\n * opXORM(0o432000): Exclusive Or to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([E]) to the exclusive OR function of the specified\n * operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opXORM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.XOR(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opXORB(0o433000): Exclusive Or to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the exclusive OR function of the specified\n * operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opXORB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.readWord(this.regEA))));\n};\n\n/**\n * opIOR(0o434000): Inclusive Or with AC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the specified\n * operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIOR = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opIORI(0o435000): Inclusive Or with AC Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the specified\n * operand (E) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIORI = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.regEA));\n};\n\n/**\n * opIORM(0o436000): Inclusive Or with AC to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([E]) to the inclusive OR function of the specified\n * operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIORM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.IOR(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opIORB(0o437000): Inclusive Or with AC to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the inclusive OR function of the specified\n * operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIORB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.readWord(this.regEA))));\n};\n\n/**\n * opANDCB(0o440000): And Complements of Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([AC]) to the AND function of the complements of both\n * the specified operand ([E]) and [AC]. The result is the NOR function of the operands.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCB = function(op, ac)\n{\n this.writeWord(ac, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA)));\n};\n\n/**\n * opANDCBI(0o441000): And Complements of Both Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([AC]) to the AND function of the complements of both\n * the specified operand (E) and [AC]. The result is the NOR function of the operands.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCBI = function(op, ac)\n{\n this.writeWord(ac, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.regEA));\n};\n\n/**\n * opANDCBM(0o442000): And Complements of Both to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([E]) to the AND function of the complements of both\n * the specified operand ([E]) and [AC]. The result is the NOR function of the operands.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCBM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA)));\n};\n\n/**\n * opANDCBB(0o443000): And Complements of Both to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the AND function of the complements of both\n * the specified operand ([E]) and [AC]. The result is the NOR function of the operands.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCBB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA))));\n};\n\n/**\n * opEQV(0o444000): Equivalence with AC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-23:\n *\n * Change the contents of the destination specified by M ([AC]) to the complement of the exclusive OR function of the\n * specified operand ([E]) and [AC] (the result has 1s wherever the corresponding bits of the operands are the same).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opEQV = function(op, ac)\n{\n this.writeWord(ac, PDP10.EQV(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opEQVI(0o445000): Equivalence Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-23:\n *\n * Change the contents of the destination specified by M ([AC]) to the complement of the exclusive OR function of the\n * specified operand (E) and [AC] (the result has 1s wherever the corresponding bits of the operands are the same).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opEQVI = function(op, ac)\n{\n this.writeWord(ac, PDP10.EQV(this.readWord(ac), this.regEA));\n};\n\n/**\n * opEQVM(0o446000): Equivalence to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-23:\n *\n * Change the contents of the destination specified by M ([E]) to the complement of the exclusive OR function of the\n * specified operand ([E]) and [AC] (the result has 1s wherever the corresponding bits of the operands are the same).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opEQVM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.EQV(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opEQVB(0o447000): Equivalence to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-23:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the complement of the exclusive OR function of the\n * specified operand ([E]) and [AC] (the result has 1s wherever the corresponding bits of the operands are the same).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opEQVB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.EQV(this.readWord(ac), this.readWord(this.regEA))));\n};\n\n/**\n * opSETCA(0o450000): Set to Complement of AC\n * opSETCAI(0o451000): Set to Complement of AC Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19:\n *\n * Change the contents of the destination specified by M ([AC]) to the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETCA = function(op, ac)\n{\n this.writeWord(ac, PDP10.WORD_MASK - this.readWord(ac));\n};\n\n/**\n * opSETCAM(0o452000): Set to Complement of AC Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19:\n *\n * Change the contents of the destination specified by M ([E]) to the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETCAM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.WORD_MASK - this.readWord(ac));\n};\n\n/**\n * opSETCAB(0o453000): Set to Complement of AC Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETCAB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.WORD_MASK - this.readWord(ac)));\n};\n\n/**\n * opORCA(0o454000): Inclusive Or with Complement of AC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the specified\n * operand ([E]) and the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCA = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opORCAI(0o455000): Inclusive Or with Complement of AC Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the specified\n * operand (E) and the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCAI = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), this.regEA));\n};\n\n/**\n * opORCAM(0o456000): Inclusive Or with Complement of AC to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([E]) to the inclusive OR function of the specified\n * operand ([E]) and the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCAM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opORCAB(0o457000): Inclusive Or with Complement of AC to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the inclusive OR function of the specified\n * operand ([E]) and the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCAB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), this.readWord(this.regEA))));\n};\n\n/**\n * opSETCM(0o460000): Set to Complement of Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19:\n *\n * Change the contents of the destination specified by M ([AC]) to the complement of the specified source\n * operand ([E]).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETCM = function(op, ac)\n{\n this.writeWord(ac, PDP10.WORD_MASK - this.readWord(this.regEA));\n};\n\n/**\n * opSETCMI(0o461000): Set to Complement of Memory Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19:\n *\n * Change the contents of the destination specified by M ([AC]) to the complement of the specified source\n * operand (E).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETCMI = function(op, ac)\n{\n this.writeWord(ac, PDP10.WORD_MASK - this.regEA);\n};\n\n/**\n * opSETCMM(0o462000): Set to Complement of Memory Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19:\n *\n * Change the contents of the destination specified by M ([E]) to the complement of the specified source\n * operand ([E]).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETCMM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.WORD_MASK - this.readWord(this.regEA));\n};\n\n/**\n * opSETCMB(0o463000): Set to Complement of Memory Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the complement of the specified source\n * operand ([E]).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETCMB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.WORD_MASK - this.readWord(this.regEA)));\n};\n\n/**\n * opORCM(0o464000): Inclusive Or Complement of Memory with AC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the complement of the\n * specified operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCM = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA)));\n};\n\n/**\n * opORCMI(0o465000): Inclusive Or Complement of Memory Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the complement of the\n * specified operand (E) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCMI = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), PDP10.WORD_MASK - this.regEA));\n};\n\n/**\n * opORCMM(0o466000): Inclusive Or Complement of Memory to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([E]) to the inclusive OR function of the complement of the\n * specified operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCMM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.IOR(this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA)));\n};\n\n/**\n * opORCMB(0o467000): Inclusive Or Complement of Memory to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the inclusive OR function of the complement of the\n * specified operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCMB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.IOR(this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA))));\n};\n\n/**\n * opORCB(0o470000): Inclusive Or Complements of Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the complements of both\n * the specified operand ([E]) and [AC]. The result is the NAND function of the operands.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCB = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA)));\n};\n\n/**\n * opORCBI(0o471000): Inclusive Or Complements of Both Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the complements of both\n * the specified operand (E) and [AC]. The result is the NAND function of the operands.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCBI = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.regEA));\n};\n\n/**\n * opORCBM(0o472000): Inclusive Or Complements of Both To Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([E]) to the inclusive OR function of the complements of both\n * the specified operand ([E]) and [AC]. The result is the NAND function of the operands.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCBM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA)));\n};\n\n/**\n * opORCBB(0o473000): Inclusive Or Complements of Both to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the inclusive OR function of the complements of both\n * the specified operand ([E]) and [AC]. The result is the NAND function of the operands.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCBB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA))));\n};\n\n/**\n * opSETO(0o474000): Set to Ones\n * opSETOI(0o475000): Set to Ones Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-18:\n *\n * Change the contents of the destination specified by M (AC) to all 1s.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETO = function(op, ac)\n{\n this.writeWord(ac, PDP10.WORD_MASK);\n};\n\n/**\n * opSETOM(0o476000): Set to Ones Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-18:\n *\n * Change the contents of the destination specified by M ([E]) to all 1s.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETOM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.WORD_MASK);\n};\n\n/**\n * opSETOB(0o477000): Set to Ones Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-18:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to all 1s.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETOB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.WORD_MASK));\n};\n\n/**\n * opHLL(0o5N0000): Half Word Left to Left\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-3:\n *\n * Move the left half of the source word specified by M to the left half of the specified destination.\n * The source and the destination right half are unaffected; the original contents of the destination are lost.\n *\n * For HLL, the source is [E] and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHLL = function(op, ac)\n{\n var src = this.readWord(this.regEA);\n var dst = this.readWord(ac);\n this.writeWord(ac, PDP10.GETHR(op, dst, src) + (src - (src & PDP10.HALF_MASK)));\n};\n\n/**\n * opHLLI(0o5N1000): Half Word Left to Left, Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-3:\n *\n * Move the left half of the source word specified by M to the left half of the specified destination.\n * The source and the destination right half are unaffected; the original contents of the destination are lost.\n *\n * SIDEBAR: HLLI merely clears AC left.\n *\n * For HLLI, the source is 0,E and the destination is [A]. But since this is a left-half-only operation, src is\n * effectively 0.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHLLI = function(op, ac)\n{\n var dst = this.readWord(ac);\n this.writeWord(ac, PDP10.GETHR(op, dst, 0));\n};\n\n/**\n * opHLLM(0o5N2000): Half Word Left to Left, Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-3:\n *\n * Move the left half of the source word specified by M to the left half of the specified destination.\n * The source and the destination right half are unaffected; the original contents of the destination are lost.\n *\n * For HLLM, the source is [A] and the destination is [E].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHLLM = function(op, ac)\n{\n var src = this.readWord(ac);\n var dst = this.readWord(this.regEA);\n this.writeWord(this.regEA, PDP10.GETHR(op, dst, src) + (src - (src & PDP10.HALF_MASK)));\n};\n\n/**\n * opHLLS(0o5N3000): Half Word Left to Left, Self\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-3:\n *\n * Move the left half of the source word specified by M to the left half of the specified destination.\n * The source and the destination right half are unaffected; the original contents of the destination are lost.\n *\n * SIDEBAR: If A is zero, HLLS is a no-op, otherwise it is equivalent to HLL.\n *\n * For HLLS, the source AND destination is [E] (and also [A] if A is non-zero).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHLLS = function(op, ac)\n{\n var dst = this.readWord(this.regEA);\n dst = PDP10.SETHR(op, dst, dst);\n this.writeWord(this.regEA, dst);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opHRL(0o504000): Half Word Right to Left\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-4:\n *\n * Move the right half of the source word specified by M to the left half of the specified destination.\n * The source and the destination right half are unaffected; the original contents of the destination left\n * half are lost.\n *\n * For HRL, the source is [E] and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHRL = function(op, ac)\n{\n var src = (this.readWord(this.regEA) & PDP10.HALF_MASK) * PDP10.HALF_SHIFT;\n var dst = this.readWord(ac);\n this.writeWord(ac, PDP10.GETHR(op, dst, src) + src);\n};\n\n/**\n * opHRLI(0o505000): Half Word Right to Left, Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-4:\n *\n * Move the right half of the source word specified by M to the left half of the specified destination.\n * The source and the destination right half are unaffected; the original contents of the destination left\n * half are lost.\n *\n * For HRLI, the source is 0,E and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHRLI = function(op, ac)\n{\n var src = this.regEA * PDP10.HALF_SHIFT;\n var dst = this.readWord(ac);\n this.writeWord(ac, PDP10.GETHR(op, dst, src) + src);\n};\n\n/**\n * opHRLM(0o506000): Half Word Right to Left, Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-4:\n *\n * Move the right half of the source word specified by M to the left half of the specified destination.\n * The source and the destination right half are unaffected; the original contents of the destination left\n * half are lost.\n *\n * For HRLM, the source is [A] and the destination is [E].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHRLM = function(op, ac)\n{\n var src = (this.readWord(ac) & PDP10.HALF_MASK) * PDP10.HALF_SHIFT;\n var dst = this.readWord(this.regEA);\n this.writeWord(this.regEA, PDP10.GETHR(op, dst, src) + src);\n};\n\n/**\n * opHRLS(0o507000): Half Word Right to Left, Self\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-4:\n *\n * Move the right half of the source word specified by M to the left half of the specified destination.\n * The source and the destination right half are unaffected; the original contents of the destination left\n * half are lost.\n *\n * For HRLS, the source AND destination is [E] (and also [A] if A is non-zero).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHRLS = function(op, ac)\n{\n var dst = this.readWord(this.regEA);\n var src = (dst & PDP10.HALF_MASK) * PDP10.HALF_SHIFT;\n dst = PDP10.GETHR(op, dst, src) + src;\n this.writeWord(this.regEA, dst);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opHRR(0o540000): Half Word Right to Right\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-6:\n *\n * Move the right half of the source word specified by M to the right half of the specified destination.\n * The source and the destination left half are unaffected; the original contents of the destination right\n * half are lost.\n *\n * For HRR, the source is [E] and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHRR = function(op, ac)\n{\n var src = this.readWord(this.regEA) & PDP10.HALF_MASK;\n var dst = this.readWord(ac);\n this.writeWord(ac, PDP10.GETHL(op, dst, src) + src);\n};\n\n/**\n * opHRRI(0o541000): Half Word Right to Right, Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-6:\n *\n * Move the right half of the source word specified by M to the right half of the specified destination.\n * The source and the destination left half are unaffected; the original contents of the destination right\n * half are lost.\n *\n * For HRRI, the source is 0,E and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHRRI = function(op, ac)\n{\n var dst = this.readWord(ac);\n this.writeWord(ac, PDP10.GETHL(op, dst, this.regEA) + this.regEA);\n};\n\n/**\n * opHRRM(0o542000): Half Word Right to Right, Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-6:\n *\n * Move the right half of the source word specified by M to the right half of the specified destination.\n * The source and the destination left half are unaffected; the original contents of the destination right\n * half are lost.\n *\n * For HRRM, the source is [A] and the destination is [E].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHRRM = function(op, ac)\n{\n var src = this.readWord(ac) & PDP10.HALF_MASK;\n var dst = this.readWord(this.regEA);\n this.writeWord(this.regEA, PDP10.GETHL(op, dst, src) + src);\n};\n\n/**\n * opHRRS(0o543000): Half Word Right to Right, Self\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-6:\n *\n * Move the right half of the source word specified by M to the right half of the specified destination.\n * The source and the destination left half are unaffected; the original contents of the destination right\n * half are lost.\n *\n * SIDEBAR: If A is zero, HRRS is a no-op; otherwise it is equivalent to HRR.\n *\n * For HRRS, the source AND destination is [E] (and also [A] if A is non-zero).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHRRS = function(op, ac)\n{\n var dst = this.readWord(this.regEA);\n dst = PDP10.SETHL(op, dst, dst);\n this.writeWord(this.regEA, dst);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opHLR(0o544000): Half Word Left to Right\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-7:\n *\n * Move the left half of the source word specified by M to the right half of the specified destination.\n * The source and the destination left half are unaffected; the original contents of the destination right half are lost.\n *\n * For HLR, the source is [E] and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHLR = function(op, ac)\n{\n var src = (this.readWord(this.regEA) / PDP10.HALF_SHIFT)|0;\n var dst = this.readWord(ac);\n this.writeWord(ac, PDP10.GETHL(op, dst, src) + src);\n};\n\n/**\n * opHLRI(0o545000): Half Word Left to Right, Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-7:\n *\n * Move the left half of the source word specified by M to the right half of the specified destination.\n * The source and the destination left half are unaffected; the original contents of the destination right half are lost.\n *\n * SIDEBAR: HLRI merely clears AC right.\n *\n * For HLRI, the source is 0,E and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHLRI = function(op, ac)\n{\n var dst = this.readWord(ac);\n this.writeWord(ac, PDP10.GETHL(op, dst, 0));\n};\n\n/**\n * opHLRM(0o546000): Half Word Left to Right, Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-7:\n *\n * Move the left half of the source word specified by M to the right half of the specified destination.\n * The source and the destination left half are unaffected; the original contents of the destination right half are lost.\n *\n * For HLRM, the source is [A] and the destination is [E].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHLRM = function(op, ac)\n{\n var src = (this.readWord(ac) / PDP10.HALF_SHIFT)|0;\n var dst = this.readWord(this.regEA);\n this.writeWord(this.regEA, PDP10.GETHL(op, dst, src) + src);\n};\n\n/**\n * opHLRS(0o547000): Half Word Left to Right, Self\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-7:\n *\n * Move the left half of the source word specified by M to the right half of the specified destination.\n * The source and the destination left half are unaffected; the original contents of the destination right half are lost.\n *\n * For HLRS, the source AND destination is [E] (and also [A] if A is non-zero).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHLRS = function(op, ac)\n{\n var dst = this.readWord(this.regEA);\n var src = (dst / PDP10.HALF_SHIFT)|0;\n dst = PDP10.GETHL(op, dst, src) + src;\n this.writeWord(this.regEA, dst);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opTRNE(0o602000): Test Right, No Modification, and Skip if All Masked Bits Equal 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRNE = function(op, ac)\n{\n if (PDP10.AND(this.readWord(ac), this.regEA) == 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opTLNE(0o603000): Test Left, No Modification, and Skip if All Masked Bits Equal 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLNE = function(op, ac)\n{\n if (PDP10.AND(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT) == 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opTRNA(0o604000): Test Right, No Modification, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRNA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n};\n\n/**\n * opTLNA(0o605000): Test Left, No Modification, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLNA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n};\n\n/**\n * opTRNN(0o606000): Test Right, No Modification, and Skip if Not All Masked Bits Equal 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRNN = function(op, ac)\n{\n if (PDP10.AND(this.readWord(ac), this.regEA) != 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opTLNN(0o607000): Test Left, No Modification, and Skip if Not All Masked Bits Equal 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLNN = function(op, ac)\n{\n if (PDP10.AND(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT) != 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opTDNE(0o612000): Test Direct, No Modification, and Skip if All Masked Bits Equal 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDNE = function(op, ac)\n{\n if (PDP10.AND(this.readWord(ac), this.readWord(this.regEA)) == 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opTSNE(0o613000): Test Swapped, No Modification, and Skip if All Masked Bits Equal 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSNE = function(op, ac)\n{\n if (PDP10.AND(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA))) == 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opTDNA(0o614000): Test Direct, No Modification, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDNA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n};\n\n/**\n * opTSNA(0o615000): Test Swapped, No Modification, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSNA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n};\n\n/**\n * opTDNN(0o616000): Test Direct, No Modification, and Skip if Not All Masked Bits Equal 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDNN = function(op, ac)\n{\n if (PDP10.AND(this.readWord(ac), this.readWord(this.regEA)) != 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opTSNN(0o617000): Test Swapped, No Modification, and Skip if Not All Masked Bits Equal 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSNN = function(op, ac)\n{\n if (PDP10.AND(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA))) != 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opTRZ(0o620000): Test Right, Zeros, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRZ = function(op, ac)\n{\n this.writeWord(ac, PDP10.CLR(this.readWord(ac), this.regEA));\n};\n\n/**\n * opTLZ(0o621000): Test Left, Zeros, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLZ = function(op, ac)\n{\n this.writeWord(ac, PDP10.CLR(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT));\n};\n\n/**\n * opTRZE(0o622000): Test Right, Zeros, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRZE = function(op, ac)\n{\n var dst = this.readWord(ac);\n if (PDP10.AND(dst, this.regEA) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(dst, this.regEA));\n};\n\n/**\n * opTLZE(0o623000): Test Left, Zeros, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLZE = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.regEA * PDP10.HALF_SHIFT;\n if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(dst, src));\n};\n\n/**\n * opTRZA(0o624000): Test Right, Zeros, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRZA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(this.readWord(ac), this.regEA));\n};\n\n/**\n * opTLZA(0o625000): Test Left, Zeros, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLZA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT));\n};\n\n/**\n * opTRZN(0o626000): Test Right, Zeros, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRZN = function(op, ac)\n{\n var dst = this.readWord(ac);\n if (PDP10.AND(dst, this.regEA) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(dst, this.regEA));\n};\n\n/**\n * opTLZN(0o627000): Test Left, Zeros, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLZN = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.regEA * PDP10.HALF_SHIFT;\n if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(dst, src));\n};\n\n/**\n * opTDZ(0o630000): Test Direct, Zeros, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDZ = function(op, ac)\n{\n this.writeWord(ac, PDP10.CLR(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opTSZ(0o631000): Test Swapped, Zeros, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSZ = function(op, ac)\n{\n this.writeWord(ac, PDP10.CLR(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA))));\n};\n\n/**\n * opTDZE(0o632000): Test Direct, Zeros, and Skip if All Masked Bits Equaled a\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDZE = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.readWord(this.regEA);\n if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(dst, src));\n};\n\n/**\n * opTSZE(0o633000): Test Swapped, Zeros, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSZE = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = PDP10.SWAP(this.readWord(this.regEA));\n if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(dst, src));\n};\n\n/**\n * opTDZA(0o634000): Test Direct, Zeros, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDZA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opTSZA(0o635000): Test Swapped, Zeros, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSZA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA))));\n};\n\n/**\n * opTDZN(0o636000): Test Direct, Zeros, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDZN = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.readWord(this.regEA);\n if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(dst, src));\n};\n\n/**\n * opTSZN(0o637000): Test Swapped, Zeros, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSZN = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = PDP10.SWAP(this.readWord(this.regEA));\n if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(dst, src));\n};\n\n/**\n * opTRC(0o640000): Test Right, Complement, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRC = function(op, ac)\n{\n this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.regEA));\n};\n\n/**\n * opTLC(0o641000): Test Left, Complement, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLC = function(op, ac)\n{\n this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT));\n};\n\n/**\n * opTRCE(0o642000): Test Right, Complement, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRCE = function(op, ac)\n{\n var dst = this.readWord(ac);\n if (PDP10.AND(dst, this.regEA) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(dst, this.regEA));\n};\n\n/**\n * opTLCE(0o643000): Test Left, Complement, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLCE = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.regEA * PDP10.HALF_SHIFT;\n if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(dst, src));\n};\n\n/**\n * opTRCA(0o644000): Test Right, Complement, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRCA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.regEA));\n};\n\n/**\n * opTLCA(0o645000): Test Left, Complement, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLCA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT));\n};\n\n/**\n * opTRCN(0o646000): Test Right, Complement, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRCN = function(op, ac)\n{\n var dst = this.readWord(ac);\n if (PDP10.AND(dst, this.regEA) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(dst, this.regEA));\n};\n\n/**\n * opTLCN(0o647000): Test Left, Complement, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLCN = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.regEA * PDP10.HALF_SHIFT;\n if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(dst, src));\n};\n\n/**\n * opTDC(0o650000): Test Direct, Complement, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDC = function(op, ac)\n{\n this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opTSC(0o651000): Test Swapped, Complement, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSC = function(op, ac)\n{\n this.writeWord(ac, PDP10.XOR(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA))));\n};\n\n/**\n * opTDCE(0o652000): Test Direct, Complement, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDCE = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.readWord(this.regEA);\n if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(dst, src));\n};\n\n/**\n * opTSCE(0o653000): Test Swapped, Complement, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSCE = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = PDP10.SWAP(this.readWord(this.regEA));\n if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(dst, src));\n};\n\n/**\n * opTDCA(0o654000): Test Direct, Complement, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDCA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opTSCA(0o655000): Test Swapped, Complement, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSCA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA))));\n};\n\n/**\n * opTDCN(0o656000): Test Direct, Complement, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDCN = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.readWord(this.regEA);\n if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(dst, src));\n};\n\n/**\n * opTSCN(0o657000): Test Swapped, Complement, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSCN = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = PDP10.SWAP(this.readWord(this.regEA));\n if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(dst, src));\n};\n\n/**\n * opTRO(0o660000): Test Right, Ones, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRO = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.regEA));\n};\n\n/**\n * opTLO(0o661000): Test Left, Ones, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLO = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT));\n};\n\n/**\n * opTROE(0o662000): Test Right, Ones, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTROE = function(op, ac)\n{\n var dst = this.readWord(ac);\n if (PDP10.AND(dst, this.regEA) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(dst, this.regEA));\n};\n\n/**\n * opTLOE(0o663000): Test Left, Ones, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLOE = function(op, ac)\n{\n var dst = this.readWord(ac);\n if (PDP10.AND(dst, this.regEA * PDP10.HALF_SHIFT) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(dst, this.regEA * PDP10.HALF_SHIFT));\n};\n\n/**\n * opTROA(0o664000): Test Right, Ones, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTROA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.regEA));\n};\n\n/**\n * opTLOA(0o665000): Test Left, Ones, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLOA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT));\n};\n\n/**\n * opTRON(0o666000): Test Right, Ones, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRON = function(op, ac)\n{\n var dst = this.readWord(ac);\n if (PDP10.AND(dst, this.regEA) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(dst, this.regEA));\n};\n\n/**\n * opTLON(0o667000): Test Left, Ones, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLON = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.regEA * PDP10.HALF_SHIFT;\n if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(dst, src));\n};\n\n/**\n * opTDO(0o670000): Test Direct, Ones, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDO = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opTSO(0o671000): Test Swapped, Ones, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSO = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA))));\n};\n\n/**\n * opTDOE(0o672000): Test Direct, Ones, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDOE = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.readWord(this.regEA);\n if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(dst, src));\n};\n\n/**\n * opTSOE(0o673000): Test Swapped, Ones, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSOE = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = PDP10.SWAP(this.readWord(this.regEA));\n if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(dst, src));\n};\n\n/**\n * opTDOA(0o674000): Test Direct, Ones, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDOA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opTSOA(0o675000): Test Swapped, Ones, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSOA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA))));\n};\n\n/**\n * opTDON(0o676000): Test Direct, Ones, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDON = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.readWord(this.regEA);\n if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(dst, src));\n};\n\n/**\n * opTSON(0o677000): Test Swapped, Ones, and Skip if Not All Masked Bits Equaled a\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSON = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = PDP10.SWAP(this.readWord(this.regEA));\n if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(dst, src));\n};\n\n/**\n * opBLKI(0o700000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} dev\n */\nPDP10.opBLKI = function(op, dev)\n{\n this.opUndefined(op);\n};\n\n/**\n * opDATAI(0o700040)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} dev\n */\nPDP10.opDATAI = function(op, dev)\n{\n this.opUndefined(op);\n};\n\n/**\n * opBLKO(0o700100)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} dev\n */\nPDP10.opBLKO = function(op, dev)\n{\n this.opUndefined(op);\n};\n\n/**\n * opDATAO(0o700140)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} dev\n */\nPDP10.opDATAO = function(op, dev)\n{\n this.opUndefined(op);\n};\n\n/**\n * opCONO(0o700200)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} dev\n */\nPDP10.opCONO = function(op, dev)\n{\n switch(dev) {\n case PDP10.DEVICES.APR:\n this.writeFlags(this.readWord(this.regEA));\n break;\n default:\n this.opUndefined(op);\n break;\n }\n};\n\n/**\n * opCONI(0o700240)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} dev\n */\nPDP10.opCONI = function(op, dev)\n{\n switch(dev) {\n case PDP10.DEVICES.APR:\n this.writeWord(this.regEA, this.readFlags());\n break;\n default:\n this.opUndefined(op);\n break;\n }\n};\n\n/**\n * opCONSZ(0o700300)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} dev\n */\nPDP10.opCONSZ = function(op, dev)\n{\n this.opUndefined(op);\n};\n\n/**\n * opCONSO(0o700340)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} dev\n */\nPDP10.opCONSO = function(op, dev)\n{\n this.opUndefined(op);\n};\n\n/**\n * opIO(0o700xxx-0o777xxx): Input-Output Instructions\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-68:\n *\n * The input-output instructions govern all transfers of data to and from the peripheral equipment, and also\n * perform many operations within the processor. An instruction in the in-out class is designated by 111 in\n * bits 0-2, ie its left octal digit is 7. Bits 3-9 address the device that is to respond to the instruction.\n * The format thus allows for 128 codes, two of which, 000 and 004 respectively, address the processor and\n * priority interrupt, and are used for the console and time share hardware as well. A chart in Appendix A\n * lists all devices for which codes have been assigned, and gives their mnemonics and DEC option numbers.\n *\n * Bits 13-35 are the same as in all other instructions: they are the I, X, and Y parts, which are used to\n * calculate an effective address, set of conditions, or mask to be used in the execution of the instruction.\n * The remaining bits, 10-12, select one of the following eight 10 instructions.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n */\nPDP10.opIO = function(op)\n{\n PDP10.aOpIO_KA10[op & 7].call(this, op, (op >> 3) & 0o177);\n};\n\n/**\n * opNOP(op, ac)\n *\n * Used for all \"defined\" operations that, in fact, do nothing (eg, SETA, SETAI, CAI, JUMP).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opNOP = function(op, ac)\n{\n};\n\n/**\n * opNOPM(op, ac)\n *\n * Used for all \"defined\" operations that, in fact, do nothing (eg, SETMM, CAM) EXCEPT reference memory.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opNOPM = function(op, ac)\n{\n};\n\n/**\n * opUndefined(op, ac)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} [ac]\n */\nPDP10.opUndefined = function(op, ac)\n{\n this.println(\"undefined opcode: \" + Str.toOct(op));\n this.advancePC(-1);\n this.stopCPU();\n};\n\n/**\n * doABS(src)\n *\n * Returns the absolute value (ABS) of the 36-bit operand; used by the MOVM* (Move Magnitude) instructions.\n *\n * @this {CPUStatePDP10}\n * @param {number} src (36-bit)\n * @return {number} (absolute value of src)\n */\nPDP10.doABS = function(src)\n{\n if (src > PDP10.INT_MASK) {\n if (src != PDP10.INT_LIMIT) {\n src = PDP10.TWO_POW36 - src;\n } else {\n this.regPS |= (PDP10.PSFLAG.AROV | PDP10.PSFLAG.CRY1);\n }\n }\n return src;\n};\n\n/**\n * doADD(dst, src)\n *\n * Performs the addition (ADD) of two signed 36-bit operands.\n *\n * @this {CPUStatePDP10}\n * @param {number} dst (36-bit value)\n * @param {number} src (36-bit value)\n * @return {number} (dst + src)\n */\nPDP10.doADD = function(dst, src)\n{\n /*\n * Since, in our happy little world, 36-bit values are always unsigned, the\n * only possible out-of-bounds value is a result >= WORD_LIMIT, which the mod cures.\n */\n var res = (dst + src) % PDP10.WORD_LIMIT;\n PDP10.setAddFlags.call(this, dst, src, res);\n return res;\n};\n\n/**\n * doDIV(src, dst, ext)\n *\n * Performs the division (DIV) of a 72-bit operand by a 36-bit operand.\n *\n * @this {CPUStatePDP10}\n * @param {number} src (36-bit divisor)\n * @param {number} dst (36-bit value)\n * @param {number} [ext] (36-bit value extension)\n * @return {number} (dst / src) (the remainder is stored in regEX); -1 if error (no division performed)\n */\nPDP10.doDIV = function(src, dst, ext)\n{\n var fNegQ = false, fNegR = false;\n\n /*\n * Perform all the same up-front checks that the PDP-10 performs; if we do our job correctly, then it\n * will be impossible for the actual division operation to overflow (the asserts below should never fire).\n */\n if (ext === undefined) {\n if (!src) {\n this.regPS |= PDP10.PSFLAG.DCK | PDP10.PSFLAG.AROV;\n return -1;\n }\n ext = (dst > PDP10.INT_MASK)? PDP10.WORD_MASK : 0;\n } else {\n var srcAbs = (src < PDP10.INT_LIMIT? src : PDP10.TWO_POW36 - src);\n var extAbs = (ext < PDP10.INT_LIMIT? ext : PDP10.TWO_POW36 - ext - (dst? 1 : 0));\n if (extAbs >= srcAbs) {\n this.regPS |= PDP10.PSFLAG.DCK | PDP10.PSFLAG.AROV;\n return -1;\n }\n }\n\n /*\n * We're done with the PDP-10's \"dual sign\" operands now; produce a (unified) signed 72-bit dividend.\n */\n dst = PDP10.merge72.call(this, dst, ext);\n ext = this.regEX;\n\n /*\n * Make all the inputs positive now, to keep the division simple. Fix up the results when we're done.\n */\n if (src > PDP10.INT_MASK) {\n src = PDP10.WORD_LIMIT - src;\n fNegQ = !fNegQ;\n }\n if (ext > PDP10.INT_MASK) {\n if (dst) {\n ext = PDP10.WORD_MASK - ext;\n dst = PDP10.WORD_LIMIT - dst;\n }\n else {\n if (ext) ext = PDP10.WORD_LIMIT - ext;\n }\n fNegR = true; fNegQ = !fNegQ;\n }\n\n /*\n * Initialize the four double-length 72-bit values we need for the division process.\n *\n * The process involves shifting the divisor left 1 bit (ie, doubling it) until it equals\n * or exceeds the dividend, and then repeatedly subtracting the divisor from the dividend and\n * shifting the divisor right 1 bit until the divisor is \"exhausted\" (no bits left), with an\n * \"early out\" if the dividend gets \"exhausted\" first.\n *\n * Note that each element of these double arrays is a 36-bit value, so it's rarely a good idea\n * to use bitwise operators on them, because those would operate on only the low 32 bits.\n * Stick with the double worker functions I've created, and trust your JavaScript engine to\n * inline/optimize the code.\n */\n PDP10.INITD(this.regRes, 0, 0);\n PDP10.INITD(this.regPow, 1, 0);\n PDP10.INITD(this.regDiv, src, 0);\n PDP10.INITD(this.regRem, dst, ext);\n\n while (PDP10.CMPD(this.regRem, this.regDiv) > 0) {\n PDP10.ADDD(this.regDiv, this.regDiv);\n PDP10.ADDD(this.regPow, this.regPow);\n }\n do {\n if (PDP10.CMPD(this.regRem, this.regDiv) >= 0) {\n PDP10.SUBD(this.regRem, this.regDiv);\n PDP10.ADDD(this.regRes, this.regPow);\n if (PDP10.ZEROD(this.regRem)) break;\n }\n PDP10.SHRD(this.regDiv);\n PDP10.SHRD(this.regPow);\n } while (!PDP10.ZEROD(this.regPow));\n\n\n\n\n dst = this.regRes[0];\n this.regEX = this.regRem[0];\n\n if (fNegQ && dst) {\n dst = PDP10.WORD_LIMIT - dst;\n }\n\n if (fNegR && this.regEX) {\n this.regEX = PDP10.WORD_LIMIT - this.regEX;\n }\n\n return dst;\n};\n\n/**\n * doMUL(dst, src, fTruncate, fExternal)\n *\n * Performs the multiplication (MUL) of two signed 36-bit operands.\n *\n * To support 72-bit results, we perform the multiplication process as you would \"by hand\",\n * treating the operands to be multiplied as two 2-digit numbers, where each \"digit\" is an 18-bit\n * number (base 2^18). Each individual multiplication of these 18-bit \"digits\" will produce\n * a result within 2^36, well within JavaScript integer accuracy.\n *\n * PDP-10 Diagnostic Notes\n * -----------------------\n *\n * The \"DAKAK\" diagnostic contains the following code:\n *\n * 036174: 200240 043643 MOVE 5,43643 ; [43643] = 400000000000\n * 036175: 200300 043603 MOVE 6,43603 ; [43603] = 777777777777\n * 036176: 200140 043604 MOVE 3,43604 ; [43604] = 000000000001\n * 036177: 224240 000003 MUL 5,3 ; Multiply 400000000000 by 000000000001\n * 036200: 312240 043604 CAME 5,43604 ; high order result in AC should be: 000000000001\n * 036201: 003240 033721 UUO 5,33721 ;\n * 036202: 312300 043602 CAME 6,43602 ; low order result in AC+1 should be: 000000000000\n *\n * The \"natural\" result is:\n *\n * 05=777777777777 06=400000000000\n *\n * And SIMH seems to agree. So why does the DEC diagnostic expect:\n *\n * 05=000000000001 06=000000000000\n *\n * The answer can be found in the June 1982 \"DECSYSTEM-10 and DECSYSTEM-20 Processor Reference Manual\",\n * in the description of the MUL instruction:\n *\n * CAUTION: In the KA10, an AC operand of 2^35 is treated as though it were +2^35, producing the\n * incorrect sign in the product.\n *\n * This behavior is now simulated below for MODEL_KA10, at least to the extent that the diagnostic is happy.\n *\n * @this {CPUStatePDP10}\n * @param {number} dst (36-bit value)\n * @param {number} src (36-bit value)\n * @param {boolean} [fTruncate] (true to truncate the result to 36 bits; used by IMUL instructions)\n * @param {boolean} [fExternal] (true if external caller; avoids modifying the CPU state)\n * @return {number} (dst * src) (the high 36 bits of the result; the low 36 bits are stored in regEX)\n */\nPDP10.doMUL = function(dst, src, fTruncate, fExternal)\n{\n var n1 = dst, n2 = src;\n var fNeg = false, res, ext;\n\n /*\n * If either input is in the negative range, record the sign and make it positive;\n * we'll negate the result afterward if necessary.\n */\n if (n1 > PDP10.INT_MASK) {\n if (fExternal || this.model != PDP10.MODEL_KA10 || n1 != PDP10.INT_LIMIT) {\n n1 = PDP10.WORD_LIMIT - n1;\n fNeg = !fNeg;\n }\n }\n\n if (n2 > PDP10.INT_MASK) {\n n2 = PDP10.WORD_LIMIT - n2;\n fNeg = !fNeg;\n }\n\n if (n1 < PDP10.HALF_SHIFT && n2 < PDP10.HALF_SHIFT) {\n res = n1 * n2;\n ext = 0;\n }\n else {\n var n1d1 = (n1 & PDP10.HALF_MASK);\n var n1d2 = Math.trunc(n1 / PDP10.HALF_SHIFT);\n var n2d1 = (n2 & PDP10.HALF_MASK);\n var n2d2 = Math.trunc(n2 / PDP10.HALF_SHIFT);\n var m1d1 = n1d1 * n2d1;\n var m1d2 = (n1d2 * n2d1) + Math.trunc(m1d1 / PDP10.HALF_SHIFT);\n ext = Math.trunc(m1d2 / PDP10.HALF_SHIFT);\n m1d2 = (m1d2 & PDP10.HALF_MASK) + (n1d1 * n2d2);\n res = ((m1d2 * PDP10.HALF_SHIFT) + (m1d1 & PDP10.HALF_MASK)) % PDP10.WORD_LIMIT;\n ext += Math.trunc(m1d2 / PDP10.HALF_SHIFT) + (n1d2 * n2d2);\n }\n\n if (fNeg) {\n if (res) {\n ext = PDP10.WORD_MASK - ext;\n res = PDP10.WORD_LIMIT - res;\n }\n else {\n if (ext) ext = PDP10.WORD_LIMIT - ext;\n }\n }\n\n ext = PDP10.split72.call(this, res, ext, fExternal);\n\n if (fTruncate) {\n /*\n * Special code for IMUL. I originally tried to avoid calling split72() in this case, but the PDP-10\n * still appears to be splitting the result of the multiplication into separately signed 36-bit values,\n * so the simplest solution is to call split72() in all cases.\n */\n res = this.regEX;\n if (!fExternal) {\n /*\n * Regarding IMUL overflows, the original spec says:\n *\n * Set Overflow if the product is >= 2^35 or < -2^35 (ie, if the high order word of the double\n * length product is not null); the high order word is lost.\n *\n * However, when the \"DAKAL\" diagnostic performs a sequence like this:\n *\n * 00=000000000000 01=000000000000 02=000000000000 03=400000036755\n * 04=400000000000 05=000000000003 06=400000000000 07=000000000004\n * 10=000000000000 11=000000000011 12=777777400000 13=777777777776\n * 14=000000200000 15=400000037134 16=000000000016 17=000000000000\n * PC=037145 RA=00400000 EA=400000 PS=000000 OV=0 C0=0 C1=0 ND=0 PD=0\n * 037145: 220600 000013 IMUL 14,13 ;cycles=1\n *\n * it sets 14=777777400000 and leaves overflow clear; since the 'high order word\" would be 777777777777,\n * not null, I think the spec over-simplifies. So our check is more exhaustive: it verifies that ext is\n * nothing more than an extension of the sign bit of res (ie, 0 if res is positive, -1 if res is negative).\n * Any other combination of values implies an overflow.\n */\n if ((ext || res > PDP10.INT_MASK) && (ext != PDP10.WORD_MASK || res <= PDP10.INT_MASK)) {\n this.regPS |= PDP10.PSFLAG.AROV;\n }\n }\n ext = res;\n }\n return ext;\n};\n\n/**\n * doNEG(src)\n *\n * Returns the negation (NEG) of the 36-bit operand; used by the MOVN* (Move Negative) instructions.\n *\n * @this {CPUStatePDP10}\n * @param {number} src (36-bit)\n * @return {number} (src negated, but as an unsigned 36-bit result)\n */\nPDP10.doNEG = function(src)\n{\n if (!src) {\n this.regPS |= (PDP10.PSFLAG.CRY0 | PDP10.PSFLAG.CRY1);\n }\n else {\n /*\n * In the non-zero case, it's always safe to subtract src from TWO_POW36, but since we have to check for\n * the INT_LIMIT case anyway, and since subtraction in that case doesn't alter src, we skip the subtraction.\n */\n if (src == PDP10.INT_LIMIT) {\n this.regPS |= (PDP10.PSFLAG.AROV | PDP10.PSFLAG.CRY1);\n } else {\n src = PDP10.TWO_POW36 - src;\n }\n }\n return src;\n};\n\n/**\n * doSUB(dst, src)\n *\n * Performs the subtraction (SUB) of two signed 36-bit operands.\n *\n * @this {CPUStatePDP10}\n * @param {number} dst (36-bit value)\n * @param {number} src (36-bit value)\n * @return {number} (dst - src)\n */\nPDP10.doSUB = function(dst, src)\n{\n /*\n * Since, in our happy little world, 36-bit values are always unsigned, the\n * only possible out-of-bounds value is a result < 0, which adding WORD_LIMIT cures.\n */\n var res = (dst - src);\n if (res < 0) res += PDP10.WORD_LIMIT;\n /*\n * We can leverage setAddFlags() by treating the subtraction as addition;\n * since res = dst - src, it is also true that dst = res + src.\n */\n PDP10.setAddFlags.call(this, res, src, dst);\n return res;\n};\n\n/**\n * merge72(dst, ext)\n *\n * Returns a unified 72-bit result from two independently-signed 36-bit values.\n *\n * @this {CPUStatePDP10}\n * @param {number} dst (36-bit value)\n * @param {number} ext (36-bit value)\n * @return {number} (returns the lower 36 bits; the upper 36 bits are stored in regEX)\n */\nPDP10.merge72 = function(dst, ext)\n{\n var sign = (ext - (ext % PDP10.INT_LIMIT));\n\n /*\n * For 72-bit inputs, the PDP-10 doesn't care whether or not the low word's sign\n * matches the high word's sign. The high word's sign bit is the controlling bit.\n *\n *\n *\n * Compute value without the sign bit and add the low bit of extended in its place.\n */\n dst = (dst % PDP10.INT_LIMIT) + ((ext & 1) * PDP10.INT_LIMIT);\n this.regEX = sign + Math.trunc(ext / 2);\n return dst;\n};\n\n/**\n * split72(res, ext, fExternal)\n *\n * Returns two 36-bit values with matching sign bits from a unified 72-bit result.\n *\n * @this {CPUStatePDP10}\n * @param {number} res (36-bit value)\n * @param {number} ext (36-bit value)\n * @param {boolean} [fExternal] (true if external caller; avoids modifying the CPU state)\n * @return {number} (returns the upper 36 bits; the lower 36 bits are stored in regEX)\n */\nPDP10.split72 = function(res, ext, fExternal)\n{\n /*\n * We just produced a signed 72-bit result, whereas the PDP-10 stores 72-bit arithmetic values as two\n * signed 36-bit results with matching signs. Since that's effectively only 70 bits of magnitude (with\n * two sign bits), we lose one bit of magnitude.\n *\n * The conversion requires shifting ext left one bit so that we can move the high bit of res into the\n * low bit of ext, and then set the sign bit of res to match the sign bit of ext.\n */\n var sign = ext - (ext % PDP10.INT_LIMIT);\n ext = ((ext * 2) % PDP10.WORD_LIMIT) + Math.trunc(res / PDP10.INT_LIMIT);\n res = sign + (res % PDP10.INT_LIMIT);\n\n var signNew = ext - (ext % PDP10.INT_LIMIT);\n if (signNew != sign) {\n /*\n * I used to restore ext's original sign (ext = sign + (ext - signNew)), but the PDP-10's defined\n * behavior for multiplication overflow (ie, whenever both operands are 0o400000000000) is to set both\n * res and ext to 0o400000000000.\n *\n * To quote the original spec for the MUL instruction:\n *\n * If both operands are -2^35 set Overflow; the double length result stored is -2^70.\n */\n res = ext;\n }\n\n if (fExternal) return res;\n\n if (res == PDP10.INT_LIMIT && ext == PDP10.INT_LIMIT) {\n this.regPS |= PDP10.PSFLAG.AROV;\n }\n this.regEX = res;\n return ext;\n};\n\n/**\n * setAddFlags(dst, src, res)\n *\n * @this {CPUStatePDP10}\n * @param {number} dst (36-bit value)\n * @param {number} src (36-bit value)\n * @param {number} res (36-bit value)\n */\nPDP10.setAddFlags = function(dst, src, res)\n{\n /*\n * Isolate the top two bits of dst, src, and res by \"shifting\" them into bits 0 and 1 of the\n * following variables. Note that shifting with division only works when the values are unsigned\n * (which they MUST be).\n */\n\n var dst01 = Math.trunc(dst / PDP10.TWO_POW34);\n var src01 = Math.trunc(src / PDP10.TWO_POW34);\n var res01 = Math.trunc(res / PDP10.TWO_POW34);\n\n /*\n * Transform bits 0 and 1 into carry flags, based on the following truth table:\n *\n * D S R C Carry?\n * - - - - ------\n * 0 0 0 0 no\n * 0 0 1 0 no (there must have been a carry out of the preceding bit, but it was \"absorbed\")\n * 0 1 0 1 yes (there must have been a carry out of the preceding bit, but it was NOT \"absorbed\")\n * 0 1 1 0 no\n * 1 0 0 1 yes (same as the preceding \"yes\" case)\n * 1 0 1 0 no\n * 1 1 0 1 yes (since the addition of two ones must always produce a carry)\n * 1 1 1 1 yes (since the addition of two ones must always produce a carry)\n */\n var bitsCarry = (dst01 ^ ((dst01 ^ src01) & (src01 ^ res01)));\n var fCarry0 = bitsCarry & 0b10;\n var fCarry1 = bitsCarry & 0b01;\n\n /*\n * Similarly, we transform bit 1 into an overflow flag, based on the following truth table;\n * note that X is (D ^ R) and Y is (S ^ R):\n *\n * D S R X Y O Overflow?\n * - - - - - - ---------\n * 0 0 0 0 0 0 no\n * 0 0 1 1 1 1 yes (adding two positive values yielded a negative value)\n * 0 1 0 0 1 0 no\n * 0 1 1 1 0 0 no\n * 1 0 0 1 0 0 no\n * 1 0 1 0 1 0 no\n * 1 1 0 1 1 1 yes (adding two negative values yielded a positive value)\n * 1 1 1 0 0 0 no\n */\n var fOverflow = ((dst01 ^ res01) & (src01 ^ res01)) & 0b10;\n this.regPS |= (fCarry0? PDP10.PSFLAG.CRY0 : 0) | (fCarry1? PDP10.PSFLAG.CRY1 : 0) | (fOverflow? PDP10.PSFLAG.AROV : 0);\n};\n\n/**\n * AND(dst, src)\n *\n * Performs the logical \"and\" (AND) of two 36-bit operands.\n *\n * @param {number} dst (36-bit value)\n * @param {number} src (36-bit value)\n * @return {number} (dst & src)\n */\nPDP10.AND = function(dst, src)\n{\n /*\n * Since dst and src are 36-bit values, we must AND the low 32 bits separately from the higher bits,\n * and then combine them with addition. Since all bits above 36 will be zero, and since 0 AND 0 is 0,\n * no special masking for the higher bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n *\n * Finally, all 36-bit data within a PDP-10 machine should ALWAYS be unsigned, which we now assert,\n * because the divisions below would not yield correct results with negative inputs.\n */\n\n return ((((dst / PDP10.TWO_POW32)|0) & ((src / PDP10.TWO_POW32)|0)) * PDP10.TWO_POW32) + ((dst & src) >>> 0);\n};\n\n/**\n * CLR(dst, src)\n *\n * Performs the logical \"and\" (AND) of a 36-bit operand and its complement.\n *\n * @param {number} dst (36-bit value)\n * @param {number} src (36-bit value)\n * @return {number} (dst & ~src)\n */\nPDP10.CLR = function(dst, src)\n{\n return PDP10.AND(dst, PDP10.NOT(src));\n};\n\n/**\n * CMP(dst, src)\n *\n * Performs the SIGNED comparison (CMP) of two 36-bit operands.\n *\n * @param {number} dst (36-bit value)\n * @param {number} src (36-bit value)\n * @return {number} (dst - src)\n */\nPDP10.CMP = function(dst, src)\n{\n return (dst < PDP10.INT_LIMIT? dst : dst - PDP10.WORD_LIMIT) - (src < PDP10.INT_LIMIT? src : src - PDP10.WORD_LIMIT);\n};\n\n/**\n * EQV(dst, src)\n *\n * Performs the logical \"equivalence\" (EQV) of two 36-bit operands (ie, NOT XOR)\n *\n * @param {number} dst (36-bit value)\n * @param {number} src (36-bit value)\n * @return {number} (~(dst ^ src))\n */\nPDP10.EQV = function(dst, src)\n{\n /*\n * Since dst and src are 36-bit values, we must EQV the low 32 bits separately from the higher bits,\n * and then combine them with addition. Since all bits above 36 will be zero, and since 0 EQV 0 is 1,\n * we must mask the higher 4 bits with 0o17.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n *\n * Finally, all 36-bit data within a PDP-10 machine should ALWAYS be unsigned, which we now assert,\n * because the divisions below would not yield correct results with negative inputs.\n */\n\n return ((~(((dst / PDP10.TWO_POW32)|0) ^ ((src / PDP10.TWO_POW32)|0)) & 0o17) * PDP10.TWO_POW32) + (~(dst ^ src) >>> 0);\n};\n\n/**\n * IOR(dst, src)\n *\n * Performs the logical \"inclusive-or\" (OR) of two 36-bit operands.\n *\n * @param {number} dst (36-bit value)\n * @param {number} src (36-bit value)\n * @return {number} (dst | src)\n */\nPDP10.IOR = function(dst, src)\n{\n /*\n * Since dst and src are 36-bit values, we must OR the low 32 bits separately from the higher bits,\n * and then combine them with addition. Since all bits above 36 will be zero, and since 0 OR 0 is 0,\n * no special masking for the higher bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n *\n * Finally, all 36-bit data within a PDP-10 machine should ALWAYS be unsigned, which we now assert,\n * because the divisions below would not yield correct results with negative inputs.\n */\n\n return ((((dst / PDP10.TWO_POW32)|0) | ((src / PDP10.TWO_POW32)|0)) * PDP10.TWO_POW32) + ((dst | src) >>> 0);\n};\n\n/**\n * NOT(src)\n *\n * Performs the one's complement (NOT) of a 36-bit operand.\n *\n * @param {number} src (36-bit value)\n * @return {number} (~src)\n */\nPDP10.NOT = function(src)\n{\n /*\n * Since src is a 36-bit value, we must NOT the low 32 bits separately from the higher bits,\n * and then combine them with addition. Since all bits above 36 will be zero, and since ~0 is 1,\n * we must mask the higher 4 bits with 0o17.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n *\n * Finally, all 36-bit data within a PDP-10 machine should ALWAYS be unsigned, which we now assert,\n * because the divisions below would not yield correct results with negative inputs.\n */\n\n return ((~((src / PDP10.TWO_POW32)|0) & 0o17) * PDP10.TWO_POW32) + (~src >>> 0);\n};\n\n/**\n * SIGN(dst)\n *\n * Returns the signed form of the 36-bit operand; more efficient than doCMP(dst, 0).\n *\n * @param {number} dst (36-bit value)\n * @return {number}\n */\nPDP10.SIGN = function(dst)\n{\n return (dst < PDP10.INT_LIMIT? dst : dst - PDP10.WORD_LIMIT);\n};\n\n/**\n * XOR(dst, src)\n *\n * Performs the logical \"exclusive-or\" (XOR) of two 36-bit operands.\n *\n * @param {number} dst (36-bit value)\n * @param {number} src (36-bit value)\n * @return {number} (dst ^ src)\n */\nPDP10.XOR = function(dst, src)\n{\n /*\n * Since dst and src are 36-bit values, we must XOR the low 32 bits separately from the higher bits,\n * and then combine them with addition. Since all bits above 36 will be zero, and since 0 XOR 0 is 0,\n * no special masking for the higher bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n *\n * Finally, all 36-bit data within a PDP-10 machine should ALWAYS be unsigned, which we now assert,\n * because the divisions below would not yield correct results with negative inputs.\n */\n\n return ((((dst / PDP10.TWO_POW32)|0) ^ ((src / PDP10.TWO_POW32)|0)) * PDP10.TWO_POW32) + ((dst ^ src) >>> 0);\n};\n\n/**\n * SWAP(src)\n *\n * Used by callers to \"swap\" the left and right half-words of a 36-bit operand.\n *\n * NOTE: Since HALF_MASK is an 18-bit value, it's safe to use \"&\" with HALF_MASK (equivalent to \"%\" with HALF_SHIFT).\n *\n * @param {number} src\n * @return {number} (updated src)\n */\nPDP10.SWAP = function(src)\n{\n return ((src / PDP10.HALF_SHIFT)|0) + ((src & PDP10.HALF_MASK) * PDP10.HALF_SHIFT);\n};\n\n/**\n * GETHL(op, dst, src)\n *\n * Used by callers to obtain HL (half-word left) with HR (half-word right) zeroed.\n *\n * @param {number} op\n * @param {number} dst (36-bit value whose 18-bit left half is either preserved or modified)\n * @param {number} src (18-bit value used to determine the sign extension, if any, for the left half of dst)\n * @return {number} (updated dst)\n */\nPDP10.GETHL = function(op, dst, src)\n{\n switch(op & 0o600) {\n case 0o000:\n dst -= (dst & PDP10.HALF_MASK);\n break;\n case 0o200:\n dst = 0;\n break;\n case 0o400:\n dst = (PDP10.HALF_MASK * PDP10.HALF_SHIFT);\n break;\n case 0o600:\n dst = (src > PDP10.HINT_MASK? (PDP10.HALF_MASK * PDP10.HALF_SHIFT) : 0);\n break;\n }\n return dst;\n};\n\n/**\n * SETHL(op, dst, src)\n *\n * Used by callers to obtain HL (half-word left) with HR (half-word right) preserved.\n *\n * @param {number} op\n * @param {number} dst (36-bit value whose 18-bit left half is either preserved or modified)\n * @param {number} src (18-bit value used to determine the sign extension, if any, for the left half of dst)\n * @return {number} (updated dst)\n */\nPDP10.SETHL = function(op, dst, src)\n{\n if (op &= 0o600) {\n dst &= PDP10.HALF_MASK;\n switch(op) {\n case 0o400:\n dst += (PDP10.HALF_MASK * PDP10.HALF_SHIFT);\n break;\n case 0o600:\n dst += (src > PDP10.HINT_MASK? (PDP10.HALF_MASK * PDP10.HALF_SHIFT) : 0);\n break;\n }\n }\n return dst;\n};\n\n/**\n * GETHR(op, dst, src)\n *\n * Used by callers to obtain HR (half-word right) with HL (half-word left) zeroed.\n *\n * @param {number} op\n * @param {number} dst (36-bit value whose 18-bit right half is either preserved or modified)\n * @param {number} src (36-bit value used to determine the sign extension, if any, for the right half of dst)\n * @return {number} (updated dst)\n */\nPDP10.GETHR = function(op, dst, src)\n{\n switch(op & 0o600) {\n case 0o000:\n dst = (dst & PDP10.HALF_MASK);\n break;\n case 0o200:\n dst = 0;\n break;\n case 0o400:\n dst = PDP10.HALF_MASK;\n break;\n case 0o600:\n dst = (src > PDP10.INT_MASK? PDP10.HALF_MASK : 0);\n break;\n }\n return dst;\n};\n\n/**\n * SETHR(op, dst, src)\n *\n * Used by callers to obtain HR (half-word right) with HL (half-word left) preserved.\n *\n * @param {number} op\n * @param {number} dst (36-bit value whose 18-bit right half is either preserved or modified)\n * @param {number} src (36-bit value used to determine the sign extension, if any, for the right half of dst)\n * @return {number} (updated dst)\n */\nPDP10.SETHR = function(op, dst, src)\n{\n if (op &= 0o600) {\n dst -= (dst & PDP10.HALF_MASK);\n switch(op) {\n case 0o400:\n dst += PDP10.HALF_MASK;\n break;\n case 0o600:\n dst += (src > PDP10.INT_MASK? PDP10.HALF_MASK : 0);\n break;\n }\n }\n return dst;\n};\n\n/**\n * ADDD(dDst, dSrc)\n *\n * Adds a double-length value (dSrc) to another (dDst).\n *\n * @param {Array.<number>} dDst\n * @param {Array.<number>} dSrc\n */\nPDP10.ADDD = function(dDst, dSrc)\n{\n dDst[0] += dSrc[0];\n dDst[1] += dSrc[1];\n if (dDst[0] >= PDP10.WORD_LIMIT) {\n dDst[0] %= PDP10.WORD_LIMIT;\n dDst[1]++;\n }\n};\n\n/**\n * CMPD(dDst, dSrc)\n *\n * Compares double-length values (dDst and dSrc) by computing dDst - dSrc.\n *\n * @param {Array.<number>} dDst\n * @param {Array.<number>} dSrc\n * @return {number} > 0 if dDst > dSrc, == 0 if dDst == dSrc, < 0 if dDst < dSrc\n */\nPDP10.CMPD = function(dDst, dSrc)\n{\n var result = dDst[1] - dSrc[1];\n if (!result) result = dDst[0] - dSrc[0];\n return result;\n};\n\n/**\n * INITD(dDst, lo, hi)\n *\n * Initializes a double-length value (dDst).\n *\n * @param {Array.<number>} dDst\n * @param {number} lo\n * @param {number} hi\n */\nPDP10.INITD = function(dDst, lo, hi)\n{\n dDst[0] = lo;\n dDst[1] = hi;\n};\n\n/**\n * SHRD(dDst)\n *\n * Shifts a double-length value (dDst) right one bit.\n *\n * @param {Array.<number>} dDst\n */\nPDP10.SHRD = function(dDst)\n{\n if (dDst[1] % 2) {\n dDst[0] += PDP10.WORD_LIMIT;\n }\n dDst[0] = Math.trunc(dDst[0] / 2);\n dDst[1] = Math.trunc(dDst[1] / 2);\n};\n\n/**\n * SUBD(dDst, dSrc)\n *\n * Subtracts a double-length value (dSrc) from another (dDst).\n *\n * @param {Array.<number>} dDst\n * @param {Array.<number>} dSrc\n */\nPDP10.SUBD = function(dDst, dSrc)\n{\n dDst[0] -= dSrc[0];\n dDst[1] -= dSrc[1];\n if (dDst[0] < 0) {\n dDst[0] += PDP10.WORD_LIMIT;\n dDst[1]--;\n }\n};\n\n/**\n * ZEROD(d)\n *\n * True if all bits in the double-length value (d) are zero, false otherwise.\n *\n * @param {Array.<number>} d\n * @return {boolean}\n */\nPDP10.ZEROD = function(d)\n{\n return !d[0] && !d[1];\n};\n\n/*\n * If we want the basic half-word operations to handle all the sub-operations; ie:\n *\n * None\n * Zero-extend\n * One-extend\n * Sign-extend\n *\n * then we need to alias all the sub-functions to the corresponding primary functions.\n */\nPDP10.opHLLZ = PDP10.opHLL;\nPDP10.opHLLZI = PDP10.opHLLI;\nPDP10.opHLLZM = PDP10.opHLLM;\nPDP10.opHLLZS = PDP10.opHLLS;\nPDP10.opHLLO = PDP10.opHLL;\nPDP10.opHLLOI = PDP10.opHLLI;\nPDP10.opHLLOM = PDP10.opHLLM;\nPDP10.opHLLOS = PDP10.opHLLS;\nPDP10.opHLLE = PDP10.opHLL;\nPDP10.opHLLEI = PDP10.opHLLI;\nPDP10.opHLLEM = PDP10.opHLLM;\nPDP10.opHLLES = PDP10.opHLLS;\nPDP10.opHRLZ = PDP10.opHRL;\nPDP10.opHRLZI = PDP10.opHRLI;\nPDP10.opHRLZM = PDP10.opHRLM;\nPDP10.opHRLZS = PDP10.opHRLS;\nPDP10.opHRLO = PDP10.opHRL;\nPDP10.opHRLOI = PDP10.opHRLI;\nPDP10.opHRLOM = PDP10.opHRLM;\nPDP10.opHRLOS = PDP10.opHRLS;\nPDP10.opHRLE = PDP10.opHRL;\nPDP10.opHRLEI = PDP10.opHRLI;\nPDP10.opHRLEM = PDP10.opHRLM;\nPDP10.opHRLES = PDP10.opHRLS;\nPDP10.opHRRZ = PDP10.opHRR;\nPDP10.opHRRZI = PDP10.opHRRI;\nPDP10.opHRRZM = PDP10.opHRRM;\nPDP10.opHRRZS = PDP10.opHRRS;\nPDP10.opHRRO = PDP10.opHRR;\nPDP10.opHRROI = PDP10.opHRRI;\nPDP10.opHRROM = PDP10.opHRRM;\nPDP10.opHRROS = PDP10.opHRRS;\nPDP10.opHRRE = PDP10.opHRR;\nPDP10.opHRREI = PDP10.opHRRI;\nPDP10.opHRREM = PDP10.opHRRM;\nPDP10.opHRRES = PDP10.opHRRS;\nPDP10.opHLRZ = PDP10.opHLR;\nPDP10.opHLRZI = PDP10.opHLRI;\nPDP10.opHLRZM = PDP10.opHLRM;\nPDP10.opHLRZS = PDP10.opHLRS;\nPDP10.opHLRO = PDP10.opHLR;\nPDP10.opHLROI = PDP10.opHLRI;\nPDP10.opHLROM = PDP10.opHLRM;\nPDP10.opHLROS = PDP10.opHLRS;\nPDP10.opHLRE = PDP10.opHLR;\nPDP10.opHLREI = PDP10.opHLRI;\nPDP10.opHLREM = PDP10.opHLRM;\nPDP10.opHLRES = PDP10.opHLRS;\n\nPDP10.opSETZI = PDP10.opSETZ;\nPDP10.opSETOI = PDP10.opSETO;\nPDP10.opSETCAI = PDP10.opSETCA;\nPDP10.opSETA = PDP10.opNOP;\nPDP10.opSETAI = PDP10.opNOP;\nPDP10.opSETAM = PDP10.opMOVEM;\nPDP10.opSETAB = PDP10.opMOVEM;\nPDP10.opSETM = PDP10.opMOVE;\nPDP10.opSETMI = PDP10.opMOVEI;\nPDP10.opSETMM = PDP10.opNOPM;\nPDP10.opSETMB = PDP10.opMOVE;\nPDP10.opCAI = PDP10.opNOP;\nPDP10.opCAM = PDP10.opNOPM;\nPDP10.opJUMP = PDP10.opNOP;\nPDP10.opTRN = PDP10.opNOP;\nPDP10.opTLN = PDP10.opNOP;\nPDP10.opTDN = PDP10.opNOPM;\nPDP10.opTSN = PDP10.opNOPM;\n\nPDP10.aOpXXX_KA10 = [\n PDP10.opUUO, // 0o000xxx\n PDP10.opUUO, // 0o001xxx\n PDP10.opUUO, // 0o002xxx\n PDP10.opUUO, // 0o003xxx\n PDP10.opUUO, // 0o004xxx\n PDP10.opUUO, // 0o005xxx\n PDP10.opUUO, // 0o006xxx\n PDP10.opUUO, // 0o007xxx\n PDP10.opUUO, // 0o010xxx\n PDP10.opUUO, // 0o011xxx\n PDP10.opUUO, // 0o012xxx\n PDP10.opUUO, // 0o013xxx\n PDP10.opUUO, // 0o014xxx\n PDP10.opUUO, // 0o015xxx\n PDP10.opUUO, // 0o016xxx\n PDP10.opUUO, // 0o017xxx\n PDP10.opUUO, // 0o020xxx\n PDP10.opUUO, // 0o021xxx\n PDP10.opUUO, // 0o022xxx\n PDP10.opUUO, // 0o023xxx\n PDP10.opUUO, // 0o024xxx\n PDP10.opUUO, // 0o025xxx\n PDP10.opUUO, // 0o026xxx\n PDP10.opUUO, // 0o027xxx\n PDP10.opUUO, // 0o030xxx\n PDP10.opUUO, // 0o031xxx\n PDP10.opUUO, // 0o032xxx\n PDP10.opUUO, // 0o033xxx\n PDP10.opUUO, // 0o034xxx\n PDP10.opUUO, // 0o035xxx\n PDP10.opUUO, // 0o036xxx\n PDP10.opUUO, // 0o037xxx\n PDP10.opUUO, // 0o040xxx\n PDP10.opUUO, // 0o041xxx\n PDP10.opUUO, // 0o042xxx\n PDP10.opUUO, // 0o043xxx\n PDP10.opUUO, // 0o044xxx\n PDP10.opUUO, // 0o045xxx\n PDP10.opUUO, // 0o046xxx\n PDP10.opUUO, // 0o047xxx\n PDP10.opUUO, // 0o050xxx\n PDP10.opUUO, // 0o051xxx\n PDP10.opUUO, // 0o052xxx\n PDP10.opUUO, // 0o053xxx\n PDP10.opUUO, // 0o054xxx\n PDP10.opUUO, // 0o055xxx\n PDP10.opUUO, // 0o056xxx\n PDP10.opUUO, // 0o057xxx\n PDP10.opUUO, // 0o060xxx\n PDP10.opUUO, // 0o061xxx\n PDP10.opUUO, // 0o062xxx\n PDP10.opUUO, // 0o063xxx\n PDP10.opUUO, // 0o064xxx\n PDP10.opUUO, // 0o065xxx\n PDP10.opUUO, // 0o066xxx\n PDP10.opUUO, // 0o067xxx\n PDP10.opUUO, // 0o070xxx\n PDP10.opUUO, // 0o071xxx\n PDP10.opUUO, // 0o072xxx\n PDP10.opUUO, // 0o073xxx\n PDP10.opUUO, // 0o074xxx\n PDP10.opUUO, // 0o075xxx\n PDP10.opUUO, // 0o076xxx\n PDP10.opUUO, // 0o077xxx\n PDP10.opUndefined, // 0o100xxx\n PDP10.opUndefined, // 0o101xxx\n PDP10.opUndefined, // 0o102xxx\n PDP10.opUndefined, // 0o103xxx\n PDP10.opUndefined, // 0o104xxx\n PDP10.opUndefined, // 0o105xxx\n PDP10.opUndefined, // 0o106xxx\n PDP10.opUndefined, // 0o107xxx\n PDP10.opUndefined, // 0o110xxx\n PDP10.opUndefined, // 0o111xxx\n PDP10.opUndefined, // 0o112xxx\n PDP10.opUndefined, // 0o113xxx\n PDP10.opUndefined, // 0o114xxx\n PDP10.opUndefined, // 0o115xxx\n PDP10.opUndefined, // 0o116xxx\n PDP10.opUndefined, // 0o117xxx\n PDP10.opUndefined, // 0o120xxx\n PDP10.opUndefined, // 0o121xxx\n PDP10.opUndefined, // 0o122xxx\n PDP10.opUndefined, // 0o123xxx\n PDP10.opUndefined, // 0o124xxx\n PDP10.opUndefined, // 0o125xxx\n PDP10.opUndefined, // 0o126xxx\n PDP10.opUndefined, // 0o127xxx\n PDP10.opUFA, // 0o130xxx\n PDP10.opDFN, // 0o131xxx\n PDP10.opFSC, // 0o132xxx\n PDP10.opIBP, // 0o133xxx\n PDP10.opILDB, // 0o134xxx\n PDP10.opLDB, // 0o135xxx\n PDP10.opIDPB, // 0o136xxx\n PDP10.opDPB, // 0o137xxx\n PDP10.opFAD, // 0o140xxx\n PDP10.opFADI, // 0o141xxx\n PDP10.opFADM, // 0o142xxx\n PDP10.opFADB, // 0o143xxx\n PDP10.opFADR, // 0o144xxx\n PDP10.opFADRI, // 0o145xxx\n PDP10.opFADRM, // 0o146xxx\n PDP10.opFADRB, // 0o147xxx\n PDP10.opFSB, // 0o150xxx\n PDP10.opFSBI, // 0o151xxx\n PDP10.opFSBM, // 0o152xxx\n PDP10.opFSBB, // 0o153xxx\n PDP10.opFSBR, // 0o154xxx\n PDP10.opFSBRI, // 0o155xxx\n PDP10.opFSBRM, // 0o156xxx\n PDP10.opFSBRB, // 0o157xxx\n PDP10.opFMP, // 0o160xxx\n PDP10.opFMPI, // 0o161xxx\n PDP10.opFMPM, // 0o162xxx\n PDP10.opFMPB, // 0o163xxx\n PDP10.opFMPR, // 0o164xxx\n PDP10.opFMPRI, // 0o165xxx\n PDP10.opFMPRM, // 0o166xxx\n PDP10.opFMPRB, // 0o167xxx\n PDP10.opFDV, // 0o170xxx\n PDP10.opFDVI, // 0o171xxx\n PDP10.opFDVM, // 0o172xxx\n PDP10.opFDVB, // 0o173xxx\n PDP10.opFDVR, // 0o174xxx\n PDP10.opFDVRI, // 0o175xxx\n PDP10.opFDVRM, // 0o176xxx\n PDP10.opFDVRB, // 0o177xxx\n PDP10.opMOVE, // 0o200xxx\n PDP10.opMOVEI, // 0o201xxx\n PDP10.opMOVEM, // 0o202xxx\n PDP10.opMOVES, // 0o203xxx\n PDP10.opMOVS, // 0o204xxx\n PDP10.opMOVSI, // 0o205xxx\n PDP10.opMOVSM, // 0o206xxx\n PDP10.opMOVSS, // 0o207xxx\n PDP10.opMOVN, // 0o210xxx\n PDP10.opMOVNI, // 0o211xxx\n PDP10.opMOVNM, // 0o212xxx\n PDP10.opMOVNS, // 0o213xxx\n PDP10.opMOVM, // 0o214xxx\n PDP10.opMOVMI, // 0o215xxx\n PDP10.opMOVMM, // 0o216xxx\n PDP10.opMOVMS, // 0o217xxx\n PDP10.opIMUL, // 0o220xxx\n PDP10.opIMULI, // 0o221xxx\n PDP10.opIMULM, // 0o222xxx\n PDP10.opIMULB, // 0o223xxx\n PDP10.opMUL, // 0o224xxx\n PDP10.opMULI, // 0o225xxx\n PDP10.opMULM, // 0o226xxx\n PDP10.opMULB, // 0o227xxx\n PDP10.opIDIV, // 0o230xxx\n PDP10.opIDIVI, // 0o231xxx\n PDP10.opIDIVM, // 0o232xxx\n PDP10.opIDIVB, // 0o233xxx\n PDP10.opDIV, // 0o234xxx\n PDP10.opDIVI, // 0o235xxx\n PDP10.opDIVM, // 0o236xxx\n PDP10.opDIVB, // 0o237xxx\n PDP10.opASH, // 0o240xxx\n PDP10.opROT, // 0o241xxx\n PDP10.opLSH, // 0o242xxx\n PDP10.opJFFO, // 0o243xxx\n PDP10.opASHC, // 0o244xxx\n PDP10.opROTC, // 0o245xxx\n PDP10.opLSHC, // 0o246xxx\n PDP10.opUndefined, // 0o247xxx\n PDP10.opEXCH, // 0o250xxx\n PDP10.opBLT, // 0o251xxx\n PDP10.opAOBJP, // 0o252xxx\n PDP10.opAOBJN, // 0o253xxx\n PDP10.opJRST, // 0o254xxx\n PDP10.opJFCL, // 0o255xxx\n PDP10.opXCT, // 0o256xxx\n PDP10.opUndefined, // 0o257xxx\n PDP10.opPUSHJ, // 0o260xxx\n PDP10.opPUSH, // 0o261xxx\n PDP10.opPOP, // 0o262xxx\n PDP10.opPOPJ, // 0o263xxx\n PDP10.opJSR, // 0o264xxx\n PDP10.opJSP, // 0o265xxx\n PDP10.opJSA, // 0o266xxx\n PDP10.opJRA, // 0o267xxx\n PDP10.opADD, // 0o270xxx\n PDP10.opADDI, // 0o271xxx\n PDP10.opADDM, // 0o272xxx\n PDP10.opADDB, // 0o273xxx\n PDP10.opSUB, // 0o274xxx\n PDP10.opSUBI, // 0o275xxx\n PDP10.opSUBM, // 0o276xxx\n PDP10.opSUBB, // 0o277xxx\n PDP10.opCAI, // 0o300xxx\n PDP10.opCAIL, // 0o301xxx\n PDP10.opCAIE, // 0o302xxx\n PDP10.opCAILE, // 0o303xxx\n PDP10.opCAIA, // 0o304xxx\n PDP10.opCAIGE, // 0o305xxx\n PDP10.opCAIN, // 0o306xxx\n PDP10.opCAIG, // 0o307xxx\n PDP10.opCAM, // 0o310xxx\n PDP10.opCAML, // 0o311xxx\n PDP10.opCAME, // 0o312xxx\n PDP10.opCAMLE, // 0o313xxx\n PDP10.opCAMA, // 0o314xxx\n PDP10.opCAMGE, // 0o315xxx\n PDP10.opCAMN, // 0o316xxx\n PDP10.opCAMG, // 0o317xxx\n PDP10.opJUMP, // 0o320xxx\n PDP10.opJUMPL, // 0o321xxx\n PDP10.opJUMPE, // 0o322xxx\n PDP10.opJUMPLE, // 0o323xxx\n PDP10.opJUMPA, // 0o324xxx\n PDP10.opJUMPGE, // 0o325xxx\n PDP10.opJUMPN, // 0o326xxx\n PDP10.opJUMPG, // 0o327xxx\n PDP10.opSKIP, // 0o330xxx\n PDP10.opSKIPL, // 0o331xxx\n PDP10.opSKIPE, // 0o332xxx\n PDP10.opSKIPLE, // 0o333xxx\n PDP10.opSKIPA, // 0o334xxx\n PDP10.opSKIPGE, // 0o335xxx\n PDP10.opSKIPN, // 0o336xxx\n PDP10.opSKIPG, // 0o337xxx\n PDP10.opAOJ, // 0o340xxx\n PDP10.opAOJL, // 0o341xxx\n PDP10.opAOJE, // 0o342xxx\n PDP10.opAOJLE, // 0o343xxx\n PDP10.opAOJA, // 0o344xxx\n PDP10.opAOJGE, // 0o345xxx\n PDP10.opAOJN, // 0o346xxx\n PDP10.opAOJG, // 0o347xxx\n PDP10.opAOS, // 0o350xxx\n PDP10.opAOSL, // 0o351xxx\n PDP10.opAOSE, // 0o352xxx\n PDP10.opAOSLE, // 0o353xxx\n PDP10.opAOSA, // 0o354xxx\n PDP10.opAOSGE, // 0o355xxx\n PDP10.opAOSN, // 0o356xxx\n PDP10.opAOSG, // 0o357xxx\n PDP10.opSOJ, // 0o360xxx\n PDP10.opSOJL, // 0o361xxx\n PDP10.opSOJE, // 0o362xxx\n PDP10.opSOJLE, // 0o363xxx\n PDP10.opSOJA, // 0o364xxx\n PDP10.opSOJGE, // 0o365xxx\n PDP10.opSOJN, // 0o366xxx\n PDP10.opSOJG, // 0o367xxx\n PDP10.opSOS, // 0o370xxx\n PDP10.opSOSL, // 0o371xxx\n PDP10.opSOSE, // 0o372xxx\n PDP10.opSOSLE, // 0o373xxx\n PDP10.opSOSA, // 0o374xxx\n PDP10.opSOSGE, // 0o375xxx\n PDP10.opSOSN, // 0o376xxx\n PDP10.opSOSG, // 0o377xxx\n PDP10.opSETZ, // 0o400xxx\n PDP10.opSETZI, // 0o401xxx\n PDP10.opSETZM, // 0o402xxx\n PDP10.opSETZB, // 0o403xxx\n PDP10.opAND, // 0o404xxx\n PDP10.opANDI, // 0o405xxx\n PDP10.opANDM, // 0o406xxx\n PDP10.opANDB, // 0o407xxx\n PDP10.opANDCA, // 0o410xxx\n PDP10.opANDCAI, // 0o411xxx\n PDP10.opANDCAM, // 0o412xxx\n PDP10.opANDCAB, // 0o413xxx\n PDP10.opSETM, // 0o414xxx\n PDP10.opSETMI, // 0o415xxx\n PDP10.opSETMM, // 0o416xxx\n PDP10.opSETMB, // 0o417xxx\n PDP10.opANDCM, // 0o420xxx\n PDP10.opANDCMI, // 0o421xxx\n PDP10.opANDCMM, // 0o422xxx\n PDP10.opANDCMB, // 0o423xxx\n PDP10.opSETA, // 0o424xxx\n PDP10.opSETAI, // 0o425xxx\n PDP10.opSETAM, // 0o426xxx\n PDP10.opSETAB, // 0o427xxx\n PDP10.opXOR, // 0o430xxx\n PDP10.opXORI, // 0o431xxx\n PDP10.opXORM, // 0o432xxx\n PDP10.opXORB, // 0o433xxx\n PDP10.opIOR, // 0o434xxx\n PDP10.opIORI, // 0o435xxx\n PDP10.opIORM, // 0o436xxx\n PDP10.opIORB, // 0o437xxx\n PDP10.opANDCB, // 0o440xxx\n PDP10.opANDCBI, // 0o441xxx\n PDP10.opANDCBM, // 0o442xxx\n PDP10.opANDCBB, // 0o443xxx\n PDP10.opEQV, // 0o444xxx\n PDP10.opEQVI, // 0o445xxx\n PDP10.opEQVM, // 0o446xxx\n PDP10.opEQVB, // 0o447xxx\n PDP10.opSETCA, // 0o450xxx\n PDP10.opSETCAI, // 0o451xxx\n PDP10.opSETCAM, // 0o452xxx\n PDP10.opSETCAB, // 0o453xxx\n PDP10.opORCA, // 0o454xxx\n PDP10.opORCAI, // 0o455xxx\n PDP10.opORCAM, // 0o456xxx\n PDP10.opORCAB, // 0o457xxx\n PDP10.opSETCM, // 0o460xxx\n PDP10.opSETCMI, // 0o461xxx\n PDP10.opSETCMM, // 0o462xxx\n PDP10.opSETCMB, // 0o463xxx\n PDP10.opORCM, // 0o464xxx\n PDP10.opORCMI, // 0o465xxx\n PDP10.opORCMM, // 0o466xxx\n PDP10.opORCMB, // 0o467xxx\n PDP10.opORCB, // 0o470xxx\n PDP10.opORCBI, // 0o471xxx\n PDP10.opORCBM, // 0o472xxx\n PDP10.opORCBB, // 0o473xxx\n PDP10.opSETO, // 0o474xxx\n PDP10.opSETOI, // 0o475xxx\n PDP10.opSETOM, // 0o476xxx\n PDP10.opSETOB, // 0o477xxx\n PDP10.opHLL, // 0o500xxx\n PDP10.opHLLI, // 0o501xxx\n PDP10.opHLLM, // 0o502xxx\n PDP10.opHLLS, // 0o503xxx\n PDP10.opHRL, // 0o504xxx\n PDP10.opHRLI, // 0o505xxx\n PDP10.opHRLM, // 0o506xxx\n PDP10.opHRLS, // 0o507xxx\n PDP10.opHLLZ, // 0o510xxx\n PDP10.opHLLZI, // 0o511xxx\n PDP10.opHLLZM, // 0o512xxx\n PDP10.opHLLZS, // 0o513xxx\n PDP10.opHRLZ, // 0o514xxx\n PDP10.opHRLZI, // 0o515xxx\n PDP10.opHRLZM, // 0o516xxx\n PDP10.opHRLZS, // 0o517xxx\n PDP10.opHLLO, // 0o520xxx\n PDP10.opHLLOI, // 0o521xxx\n PDP10.opHLLOM, // 0o522xxx\n PDP10.opHLLOS, // 0o523xxx\n PDP10.opHRLO, // 0o524xxx\n PDP10.opHRLOI, // 0o525xxx\n PDP10.opHRLOM, // 0o526xxx\n PDP10.opHRLOS, // 0o527xxx\n PDP10.opHLLE, // 0o530xxx\n PDP10.opHLLEI, // 0o531xxx\n PDP10.opHLLEM, // 0o532xxx\n PDP10.opHLLES, // 0o533xxx\n PDP10.opHRLE, // 0o534xxx\n PDP10.opHRLEI, // 0o535xxx\n PDP10.opHRLEM, // 0o536xxx\n PDP10.opHRLES, // 0o537xxx\n PDP10.opHRR, // 0o540xxx\n PDP10.opHRRI, // 0o541xxx\n PDP10.opHRRM, // 0o542xxx\n PDP10.opHRRS, // 0o543xxx\n PDP10.opHLR, // 0o544xxx\n PDP10.opHLRI, // 0o545xxx\n PDP10.opHLRM, // 0o546xxx\n PDP10.opHLRS, // 0o547xxx\n PDP10.opHRRZ, // 0o550xxx\n PDP10.opHRRZI, // 0o551xxx\n PDP10.opHRRZM, // 0o552xxx\n PDP10.opHRRZS, // 0o553xxx\n PDP10.opHLRZ, // 0o554xxx\n PDP10.opHLRZI, // 0o555xxx\n PDP10.opHLRZM, // 0o556xxx\n PDP10.opHLRZS, // 0o557xxx\n PDP10.opHRRO, // 0o560xxx\n PDP10.opHRROI, // 0o561xxx\n PDP10.opHRROM, // 0o562xxx\n PDP10.opHRROS, // 0o563xxx\n PDP10.opHLRO, // 0o564xxx\n PDP10.opHLROI, // 0o565xxx\n PDP10.opHLROM, // 0o566xxx\n PDP10.opHLROS, // 0o567xxx\n PDP10.opHRRE, // 0o570xxx\n PDP10.opHRREI, // 0o571xxx\n PDP10.opHRREM, // 0o572xxx\n PDP10.opHRRES, // 0o573xxx\n PDP10.opHLRE, // 0o574xxx\n PDP10.opHLREI, // 0o575xxx\n PDP10.opHLREM, // 0o576xxx\n PDP10.opHLRES, // 0o577xxx\n PDP10.opTRN, // 0o600xxx\n PDP10.opTLN, // 0o601xxx\n PDP10.opTRNE, // 0o602xxx\n PDP10.opTLNE, // 0o603xxx\n PDP10.opTRNA, // 0o604xxx\n PDP10.opTLNA, // 0o605xxx\n PDP10.opTRNN, // 0o606xxx\n PDP10.opTLNN, // 0o607xxx\n PDP10.opTDN, // 0o610xxx\n PDP10.opTSN, // 0o611xxx\n PDP10.opTDNE, // 0o612xxx\n PDP10.opTSNE, // 0o613xxx\n PDP10.opTDNA, // 0o614xxx\n PDP10.opTSNA, // 0o615xxx\n PDP10.opTDNN, // 0o616xxx\n PDP10.opTSNN, // 0o617xxx\n PDP10.opTRZ, // 0o620xxx\n PDP10.opTLZ, // 0o621xxx\n PDP10.opTRZE, // 0o622xxx\n PDP10.opTLZE, // 0o623xxx\n PDP10.opTRZA, // 0o624xxx\n PDP10.opTLZA, // 0o625xxx\n PDP10.opTRZN, // 0o626xxx\n PDP10.opTLZN, // 0o627xxx\n PDP10.opTDZ, // 0o630xxx\n PDP10.opTSZ, // 0o631xxx\n PDP10.opTDZE, // 0o632xxx\n PDP10.opTSZE, // 0o633xxx\n PDP10.opTDZA, // 0o634xxx\n PDP10.opTSZA, // 0o635xxx\n PDP10.opTDZN, // 0o636xxx\n PDP10.opTSZN, // 0o637xxx\n PDP10.opTRC, // 0o640xxx\n PDP10.opTLC, // 0o641xxx\n PDP10.opTRCE, // 0o642xxx\n PDP10.opTLCE, // 0o643xxx\n PDP10.opTRCA, // 0o644xxx\n PDP10.opTLCA, // 0o645xxx\n PDP10.opTRCN, // 0o646xxx\n PDP10.opTLCN, // 0o647xxx\n PDP10.opTDC, // 0o650xxx\n PDP10.opTSC, // 0o651xxx\n PDP10.opTDCE, // 0o652xxx\n PDP10.opTSCE, // 0o653xxx\n PDP10.opTDCA, // 0o654xxx\n PDP10.opTSCA, // 0o655xxx\n PDP10.opTDCN, // 0o656xxx\n PDP10.opTSCN, // 0o657xxx\n PDP10.opTRO, // 0o660xxx\n PDP10.opTLO, // 0o661xxx\n PDP10.opTROE, // 0o662xxx\n PDP10.opTLOE, // 0o663xxx\n PDP10.opTROA, // 0o664xxx\n PDP10.opTLOA, // 0o665xxx\n PDP10.opTRON, // 0o666xxx\n PDP10.opTLON, // 0o667xxx\n PDP10.opTDO, // 0o670xxx\n PDP10.opTSO, // 0o671xxx\n PDP10.opTDOE, // 0o672xxx\n PDP10.opTSOE, // 0o673xxx\n PDP10.opTDOA, // 0o674xxx\n PDP10.opTSOA, // 0o675xxx\n PDP10.opTDON, // 0o676xxx\n PDP10.opTSON, // 0o677xxx\n PDP10.opIO, // 0o700xxx\n PDP10.opIO, // 0o701xxx\n PDP10.opIO, // 0o702xxx\n PDP10.opIO, // 0o703xxx\n PDP10.opIO, // 0o704xxx\n PDP10.opIO, // 0o705xxx\n PDP10.opIO, // 0o706xxx\n PDP10.opIO, // 0o707xxx\n PDP10.opIO, // 0o710xxx\n PDP10.opIO, // 0o711xxx\n PDP10.opIO, // 0o712xxx\n PDP10.opIO, // 0o713xxx\n PDP10.opIO, // 0o714xxx\n PDP10.opIO, // 0o715xxx\n PDP10.opIO, // 0o716xxx\n PDP10.opIO, // 0o717xxx\n PDP10.opIO, // 0o720xxx\n PDP10.opIO, // 0o721xxx\n PDP10.opIO, // 0o722xxx\n PDP10.opIO, // 0o723xxx\n PDP10.opIO, // 0o724xxx\n PDP10.opIO, // 0o725xxx\n PDP10.opIO, // 0o726xxx\n PDP10.opIO, // 0o727xxx\n PDP10.opIO, // 0o730xxx\n PDP10.opIO, // 0o731xxx\n PDP10.opIO, // 0o732xxx\n PDP10.opIO, // 0o733xxx\n PDP10.opIO, // 0o734xxx\n PDP10.opIO, // 0o735xxx\n PDP10.opIO, // 0o736xxx\n PDP10.opIO, // 0o737xxx\n PDP10.opIO, // 0o740xxx\n PDP10.opIO, // 0o741xxx\n PDP10.opIO, // 0o742xxx\n PDP10.opIO, // 0o743xxx\n PDP10.opIO, // 0o744xxx\n PDP10.opIO, // 0o745xxx\n PDP10.opIO, // 0o746xxx\n PDP10.opIO, // 0o747xxx\n PDP10.opIO, // 0o750xxx\n PDP10.opIO, // 0o751xxx\n PDP10.opIO, // 0o752xxx\n PDP10.opIO, // 0o753xxx\n PDP10.opIO, // 0o754xxx\n PDP10.opIO, // 0o755xxx\n PDP10.opIO, // 0o756xxx\n PDP10.opIO, // 0o757xxx\n PDP10.opIO, // 0o760xxx\n PDP10.opIO, // 0o761xxx\n PDP10.opIO, // 0o762xxx\n PDP10.opIO, // 0o763xxx\n PDP10.opIO, // 0o764xxx\n PDP10.opIO, // 0o765xxx\n PDP10.opIO, // 0o766xxx\n PDP10.opIO, // 0o767xxx\n PDP10.opIO, // 0o770xxx\n PDP10.opIO, // 0o771xxx\n PDP10.opIO, // 0o772xxx\n PDP10.opIO, // 0o773xxx\n PDP10.opIO, // 0o774xxx\n PDP10.opIO, // 0o775xxx\n PDP10.opIO, // 0o776xxx\n PDP10.opIO // 0o777xxx\n];\n\nPDP10.aOpIO_KA10 = [\n PDP10.opBLKI, // 0o70000x\n PDP10.opDATAI, // 0o70004x\n PDP10.opBLKO, // 0o70010x\n PDP10.opDATAO, // 0o70014x\n PDP10.opCONO, // 0o70020x\n PDP10.opCONI, // 0o70024x\n PDP10.opCONSZ, // 0o70030x\n PDP10.opCONSO // 0o70034x\n];\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/rom.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass ROMPDP10 extends Component {\n /**\n * ROMPDP10(parmsROM)\n *\n * The ROMPDP10 component expects the following (parmsROM) properties:\n *\n * addr: physical address of ROM\n * size: amount of ROM, in bytes\n * alias: physical alias address (null if none)\n * file: name of ROM data file\n *\n * NOTE: The ROM data will not be copied into place until the Bus is ready (see initBus()) AND\n * the ROM data file has finished loading (see finishLoad()).\n *\n * Also, while the size parameter may seem redundant, I consider it useful to confirm that the ROM\n * you received is the ROM you expected.\n *\n * @param {Object} parmsROM\n */\n constructor(parmsROM)\n {\n super(\"ROM\", parmsROM, MessagesPDP10.ROM);\n\n this.abInit = null;\n this.aSymbols = null;\n\n this.addrROM = +parmsROM['addr'];\n this.sizeROM = +parmsROM['size'];\n this.fRetainROM = false;\n\n /*\n * The new 'alias' property can now be EITHER a single physical address (like 'addr') OR an array of\n * physical addresses; eg:\n *\n * [0xf0000,0xffff0000,0xffff8000]\n *\n * We could have overloaded 'addr' to accomplish the same thing, but I think it's better to have any\n * aliased locations listed under a separate property.\n *\n * Most ROMs are not aliased, in which case the 'alias' property should have the default value of null.\n */\n this.addrAlias = parmsROM['alias'];\n if (typeof this.addrAlias == \"string\") {\n this.addrAlias = eval(this.addrAlias);\n }\n\n this.sFilePath = parmsROM['file'];\n this.sFileName = Str.getBaseName(this.sFilePath);\n\n if (this.sFilePath) {\n var sFileURL = this.sFilePath;\n if (DEBUG) this.log('load(\"' + sFileURL + '\")');\n /*\n * If the selected ROM file has a \".json\" extension, then we assume it's pre-converted\n * JSON-encoded ROM data, so we load it as-is; ditto for ROM files with a \".hex\" extension.\n * Otherwise, we ask our server-side ROM converter to return the file in a JSON-compatible format.\n */\n var sFileExt = Str.getExtension(this.sFileName);\n if (sFileExt != DumpAPI.FORMAT.JSON && sFileExt != DumpAPI.FORMAT.HEX) {\n sFileURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFilePath + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES + '&' + DumpAPI.QUERY.DECIMAL + '=true';\n }\n var rom = this;\n Web.getResource(sFileURL, null, true, function doneLoad(sURL, sResponse, nErrorCode) {\n rom.finishLoad(sURL, sResponse, nErrorCode);\n });\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {ROMPDP10}\n * @param {ComputerPDP10} cmp\n * @param {BusPDP10} bus\n * @param {CPUStatePDP10} cpu\n * @param {DebuggerPDP10} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.initROM();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {ROMPDP10}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (this.aSymbols) {\n if (this.dbg) {\n this.dbg.addSymbols(this.id, this.addrROM, this.sizeROM, this.aSymbols);\n }\n /*\n * Our only role in the handling of symbols is to hand them off to the Debugger at our\n * first opportunity. Now that we've done that, our copy of the symbols, if any, are toast.\n */\n delete this.aSymbols;\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * Since we have nothing to do on powerDown(), and no state to return, we could simply omit\n * this function. But it doesn't hurt anything, and maybe we'll use our state to save something\n * useful down the road, like user-defined symbols (ie, symbols that the Debugger may have\n * created, above and beyond those symbols we automatically loaded, if any, along with the ROM).\n *\n * @this {ROMPDP10}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return true;\n }\n\n /**\n * finishLoad(sURL, sData, nErrorCode)\n *\n * @this {ROMPDP10}\n * @param {string} sURL\n * @param {string} sData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n finishLoad(sURL, sData, nErrorCode)\n {\n if (nErrorCode) {\n this.notice(\"Unable to load ROM resource (error \" + nErrorCode + \": \" + sURL + \")\");\n this.sFilePath = null;\n }\n else {\n Component.addMachineResource(this.idMachine, sURL, sData);\n var resource = Web.parseMemoryResource(sURL, sData);\n if (resource) {\n this.abInit = resource.aBytes;\n this.aSymbols = resource.aSymbols;\n } else {\n this.sFilePath = null;\n }\n }\n this.initROM();\n }\n\n /**\n * initROM()\n *\n * This function is called by both initBus() and finishLoad(), but it cannot copy the initial data into place\n * until after initBus() has received the Bus component AND finishLoad() has received the data. When both those\n * criteria are satisfied, the component becomes \"ready\".\n *\n * @this {ROMPDP10}\n */\n initROM()\n {\n if (!this.isReady()) {\n if (this.sFilePath) {\n /*\n * Too early...\n */\n if (!this.abInit || !this.bus) return;\n\n /*\n * If no explicit size was specified, then use whatever the actual size is.\n */\n if (!this.sizeROM) {\n this.sizeROM = this.abInit.length;\n }\n if (this.abInit.length != this.sizeROM) {\n /*\n * Note that setError() sets the component's fError flag, which in turn prevents setReady() from\n * marking the component ready. TODO: Revisit this decision. On the one hand, it sounds like a\n * good idea to stop the machine in its tracks whenever a setError() occurs, but there may also be\n * times when we'd like to forge ahead anyway.\n */\n this.setError(\"ROM size (\" + Str.toHexLong(this.abInit.length) + \") does not match specified size (\" + Str.toHexLong(this.sizeROM) + \")\");\n }\n else if (this.addROM(this.addrROM)) {\n\n var aliases = [];\n if (typeof this.addrAlias == \"number\") {\n aliases.push(this.addrAlias);\n } else if (this.addrAlias != null && this.addrAlias.length) {\n aliases = this.addrAlias;\n }\n for (var i = 0; i < aliases.length; i++) {\n this.cloneROM(aliases[i]);\n }\n /*\n * We used to hang onto the initial ROM data so that we could restore any bytes the CPU overwrote,\n * using memory write-notification handlers, but with the introduction of read-only memory blocks, that's\n * no longer necessary.\n *\n * TODO: Consider an option to retain the ROM data, and give the user some way of restoring ROMs.\n * That may be useful for \"resumable\" machines that save/restore all dirty block of memory, regardless\n * whether they're ROM or RAM. However, the only way to modify a machine's ROM is with the Debugger,\n * and Debugger users should know better.\n */\n if (!this.fRetainROM) {\n delete this.abInit;\n }\n }\n }\n this.setReady();\n }\n }\n\n /**\n * addROM(addr)\n *\n * @this {ROMPDP10}\n * @param {number} addr\n * @return {boolean}\n */\n addROM(addr)\n {\n if (this.bus.addMemory(addr, this.sizeROM, MemoryPDP10.TYPE.ROM)) {\n if (DEBUG) this.log(\"addROM(): copying ROM to \" + Str.toHexLong(addr) + \" (\" + Str.toHexLong(this.abInit.length) + \" bytes)\");\n var i;\n for (i = 0; i < this.abInit.length; i++) {\n this.bus.setWordDirect(addr + i, this.abInit[i]);\n }\n return true;\n }\n\n /*\n * We don't need to report an error here, because addMemory() already takes care of that.\n */\n return false;\n }\n\n /**\n * cloneROM(addr)\n *\n * For ROMs with one or more alias addresses, we used to call addROM() for each address. However,\n * that obviously wasted memory, since each alias was an independent copy, and if you used the\n * Debugger to edit the ROM in one location, the changes would not appear in the other location(s).\n *\n * Now that the Bus component provides low-level getMemoryBlocks() and setMemoryBlocks() methods\n * to manually get and set the blocks of any memory range, it is now possible to create true aliases.\n *\n * @this {ROMPDP10}\n * @param {number} addr\n */\n cloneROM(addr)\n {\n var aBlocks = this.bus.getMemoryBlocks(this.addrROM, this.sizeROM);\n this.bus.setMemoryBlocks(addr, this.sizeROM, aBlocks);\n }\n\n /**\n * ROMPDP10.init()\n *\n * This function operates on every HTML element of class \"rom\", extracting the\n * JSON-encoded parameters for the ROMPDP10 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a ROMPDP10 component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeROM = Component.getElementsByClass(document, PDP10.APPCLASS, \"rom\");\n for (var iROM = 0; iROM < aeROM.length; iROM++) {\n var eROM = aeROM[iROM];\n var parmsROM = Component.getComponentParms(eROM);\n var rom = new ROMPDP10(parmsROM);\n Component.bindComponentControls(rom, eROM, PDP10.APPCLASS);\n }\n }\n}\n\n/*\n * NOTE: There's currently no need for this component to have a reset() function, since\n * once the ROM data is loaded, it can't be changed, so there's nothing to reinitialize.\n *\n * OK, well, I take that back, because the Debugger, if installed, has the ability to modify\n * ROM contents, so in that case, having a reset() function that restores the original ROM data\n * might be useful; then again, it might not, depending on what you're trying to debug.\n *\n * If we do add reset(), then we'll want to change initROM() to hang onto the original\n * ROM data; currently, we release it after copying it into the read-only memory allocated\n * via bus.addMemory().\n */\n\n/*\n * Initialize all the ROMPDP10 modules on the page.\n */\nWeb.onInit(ROMPDP10.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/ram.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass RAMPDP10 extends Component {\n /**\n * RAMPDP10(parmsRAM)\n *\n * The RAMPDP10 component expects the following (parmsRAM) properties:\n *\n * addr: starting physical address of RAM (default is 0)\n * size: amount of RAM, in bytes (default is 0, which means defer to motherboard switch settings)\n * file: name of optional data file to load into RAM (default is \"\")\n * load: optional file load address (overrides any load address specified in the data file; default is null)\n * exec: optional file exec address (overrides any exec address specified in the data file; default is null)\n *\n * NOTE: We make a note of the specified size, but no memory is initially allocated for the RAM until the\n * Computer component calls powerUp().\n *\n * @param {Object} parmsRAM\n */\n constructor(parmsRAM)\n {\n super(\"RAM\", parmsRAM);\n\n this.aData = null;\n this.aSymbols = null;\n\n this.addrRAM = +parmsRAM['addr'];\n this.sizeRAM = +parmsRAM['size'];\n\n this.addrLoad = parmsRAM['load'];\n this.addrExec = parmsRAM['exec'];\n if (this.addrLoad != null) this.addrLoad = +this.addrLoad;\n if (this.addrExec != null) this.addrExec = +this.addrExec;\n\n this.fInstalled = (!!this.sizeRAM); // 0 is the default value for 'size' when none is specified\n this.fAllocated = this.fReset = false;\n\n this.sFilePath = parmsRAM['file'];\n this.sFileName = Str.getBaseName(this.sFilePath);\n\n if (this.sFilePath) {\n var sFileURL = this.sFilePath;\n if (DEBUG) this.log('load(\"' + sFileURL + '\")');\n /*\n * If the selected data file has a \".json\" extension, then we assume it's pre-converted\n * JSON-encoded data, so we load it as-is; ditto for ROM files with a \".hex\" extension.\n * Otherwise, we ask our server-side converter to return the file in a JSON-compatible format.\n */\n var sFileExt = Str.getExtension(this.sFileName);\n if (sFileExt != DumpAPI.FORMAT.JSON && sFileExt != DumpAPI.FORMAT.HEX) {\n sFileURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFilePath + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES + '&' + DumpAPI.QUERY.DECIMAL + '=true';\n }\n var ram = this;\n Web.getResource(sFileURL, null, true, function doneLoad(sURL, sResponse, nErrorCode) {\n ram.finishLoad(sURL, sResponse, nErrorCode);\n });\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {RAMPDP10}\n * @param {ComputerPDP10} cmp\n * @param {BusPDP10} bus\n * @param {CPUStatePDP10} cpu\n * @param {DebuggerPDP10} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.initRAM();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {RAMPDP10}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (this.aSymbols) {\n if (this.dbg) {\n this.dbg.addSymbols(this.id, this.addrRAM, this.sizeRAM, this.aSymbols);\n }\n /*\n * Our only role in the handling of symbols is to hand them off to the Debugger at our\n * first opportunity. Now that we've done that, our copy of the symbols, if any, are toast.\n */\n delete this.aSymbols;\n }\n if (!fRepower) {\n /*\n * Since we use the Bus to allocate all our memory, memory contents are already restored for us,\n * so we don't save any state, and therefore no state should be restored. Just do a reset().\n */\n\n this.reset();\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {RAMPDP10}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n /*\n * The Computer powers down the CPU first, at which point CPUState state is saved,\n * which includes the Bus state, and since we use the Bus component to allocate all\n * our memory, memory contents are already saved for us, so we don't need the usual\n * save logic.\n */\n return true;\n }\n\n /**\n * finishLoad(sURL, sData, nErrorCode)\n *\n * @this {RAMPDP10}\n * @param {string} sURL\n * @param {string} sData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n finishLoad(sURL, sData, nErrorCode)\n {\n if (nErrorCode) {\n this.notice(\"Unable to load RAM resource (error \" + nErrorCode + \": \" + sURL + \")\");\n this.sFilePath = null;\n }\n else {\n Component.addMachineResource(this.idMachine, sURL, sData);\n var resource = Web.parseMemoryResource(sURL, sData);\n if (resource) {\n this.aData = resource.aData;\n this.aSymbols = resource.aSymbols;\n if (this.addrLoad == null) this.addrLoad = resource.addrLoad;\n if (this.addrExec == null) this.addrExec = resource.addrExec;\n } else {\n this.sFilePath = null;\n }\n }\n this.initRAM();\n }\n\n /**\n * initRAM()\n *\n * This function is called by both initBus() and finishLoad(), but it cannot copy the initial data into place\n * until after initBus() has received the Bus component AND finishLoad() has received the data. When both those\n * criteria are satisfied, the component becomes \"ready\".\n *\n * @this {RAMPDP10}\n */\n initRAM()\n {\n if (!this.bus) return;\n\n if (!this.fAllocated && this.sizeRAM) {\n if (this.bus.addMemory(this.addrRAM, this.sizeRAM, MemoryPDP10.TYPE.RAM)) {\n this.fAllocated = true;\n } else {\n this.sizeRAM = 0; // don't bother trying again (it just results in redundant error messages)\n }\n }\n if (!this.isReady()) {\n if (!this.fAllocated) {\n Component.error(\"No RAM allocated\");\n }\n else if (this.sFilePath) {\n /*\n * Too early...\n */\n if (!this.aData) return;\n\n if (this.loadImage(this.aData, this.addrLoad, this.addrExec, this.addrRAM)) {\n this.status('Loaded image \"' + this.sFileName + '\"');\n } else {\n this.notice('Error loading image \"' + this.sFileName + '\"');\n }\n\n /*\n * NOTE: We now retain this data, so that reset() can return the RAM to its predefined state.\n *\n * delete this.aData;\n */\n }\n this.fReset = true;\n this.setReady();\n }\n }\n\n /**\n * reset()\n *\n * @this {RAMPDP10}\n */\n reset()\n {\n if (this.fAllocated && !this.fReset) {\n /*\n * TODO: Add a configuration parameter for selecting the byte pattern on reset?\n * Note that when memory blocks are originally created, they are currently always\n * zero-initialized, so this would only affect resets.\n */\n this.bus.zeroMemory(this.addrRAM, this.sizeRAM, 0);\n if (this.aData) {\n this.loadImage(this.aData, this.addrLoad, this.addrExec, this.addrRAM, !this.dbg);\n }\n }\n this.fReset = false;\n }\n\n /**\n * loadImage(aData, addrLoad, addrExec, addrInit, fStart)\n *\n * If the array contains a PAPER tape image in the \"Absolute Format,\" load it as specified\n * by the format; otherwise, load it as-is using the address(es) supplied.\n *\n * @this {RAMPDP10}\n * @param {Array} aData\n * @param {number|null} [addrLoad]\n * @param {number|null} [addrExec] (this CAN override any starting address INSIDE the image)\n * @param {number|null} [addrInit]\n * @param {boolean} [fStart]\n * @return {boolean} (true if loaded, false if not)\n */\n loadImage(aData, addrLoad, addrExec, addrInit, fStart)\n {\n var fLoaded = false;\n\n if (addrLoad == null) {\n addrLoad = addrInit;\n }\n if (addrLoad != null) {\n for (var i = 0; i < aData.length; i++) {\n this.bus.setWordDirect(addrLoad + i, aData[i]);\n }\n fLoaded = true;\n }\n if (fLoaded) {\n /*\n * Set the start address to whatever the caller provided, or failing that, whatever start\n * address was specified inside the image.\n *\n * For example, the diagnostic \"MAINDEC-11-D0AA-PB\" doesn't include a start address inside the\n * image, but we know that the directions for that diagnostic say to \"Start and Restart at 200\",\n * so we have manually inserted an \"exec\":128 in the JSON containing the image.\n */\n if (addrExec == null) {\n this.cpu.stopCPU();\n fStart = false;\n }\n if (addrExec != null) {\n this.cpu.setReset(addrExec, fStart);\n }\n }\n return fLoaded;\n }\n\n /**\n * RAMPDP10.init()\n *\n * This function operates on every HTML element of class \"ram\", extracting the\n * JSON-encoded parameters for the RAMPDP10 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a RAMPDP10 component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeRAM = Component.getElementsByClass(document, PDP10.APPCLASS, \"ram\");\n for (var iRAM = 0; iRAM < aeRAM.length; iRAM++) {\n var eRAM = aeRAM[iRAM];\n var parmsRAM = Component.getComponentParms(eRAM);\n var ram = new RAMPDP10(parmsRAM);\n Component.bindComponentControls(ram, eRAM, PDP10.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize all the RAMPDP10 modules on the page.\n */\nWeb.onInit(RAMPDP10.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/serial.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * Component class, because otherwise the Compiler won't allow us to *reference* the named\n * property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass SerialPortPDP10 extends Component {\n /**\n * SerialPortPDP10(parmsSerial)\n *\n * The SerialPort component has the following component-specific (parmsSerial) properties:\n *\n * adapter: adapter number; 0 if not defined (the PCx86 SerialPort component uses this\n * value to set the device's internal COM number, which in turn determines other properties,\n * such as I/O ports and IRQ; for the PDP-10, this currently has no defined use)\n *\n * binding: name of a control (based on its \"binding\" attribute) to bind to this port's I/O\n *\n * tabSize: set to a non-zero number to convert tabs to spaces (applies only to output to\n * the above binding); default is 0 (no conversion)\n *\n * upperCase: if true, all received input is upper-cased; it is normally the responsibility\n * of the sending device to ensure this, but sometimes it's more convenient to enforce\n * on the receiving end.\n *\n * @param {Object} parmsSerial\n */\n constructor(parmsSerial)\n {\n super(\"SerialPort\", parmsSerial, MessagesPDP10.SERIAL);\n\n this.iAdapter = +parmsSerial['adapter'];\n this.fUpperCase = parmsSerial['upperCase'];\n if (typeof this.fUpperCase == \"string\") this.fUpperCase = (this.fUpperCase == \"true\");\n /**\n * consoleBuffer becomes a string that records serial port output if the 'binding' property is set to the\n * reserved name \"console\". Nothing is written to the console, however, until a linefeed (0x0A) is output\n * or the string length reaches a threshold (currently, 1024 characters).\n *\n * @type {string|null}\n */\n this.consoleBuffer = null;\n\n /**\n * controlBuffer is a DOM element bound to the port (currently used for output only; see transmitByte()).\n *\n * Example: CTTY COM2\n *\n * The CTTY DOS command redirects all CON I/O to the specified serial port (eg, COM2), which it assumes is\n * connected to a serial terminal, and therefore anything it *transmits* via COM2 will be displayed by the\n * terminal. It further assumes that anything typed on such a terminal is NOT displayed, so as DOS *receives*\n * serial input, DOS *transmits* the appropriate characters back to the terminal via COM2.\n *\n * As a result, controlBuffer only needs to be updated by the transmitByte() function.\n *\n * @type {Object}\n */\n this.controlBuffer = null;\n\n /*\n * If controlBuffer is being used AND 'tabSize' is set, then we make an attempt to monitor the characters\n * being echoed via transmitByte(), maintain a logical column position, and convert any tabs into the appropriate\n * number of spaces.\n *\n * charBOL, if nonzero, is a character to automatically output at the beginning of every line. This probably\n * isn't generally useful; I use it internally to preformat serial output.\n */\n this.tabSize = +parmsSerial['tabSize'];\n this.charBOL = +parmsSerial['charBOL'];\n this.iLogicalCol = 0;\n this.fNullModem = true;\n\n this.abReceive = [];\n\n var sBinding = parmsSerial['binding'];\n if (sBinding == \"console\") {\n this.consoleBuffer = \"\";\n } else {\n /*\n * If the SerialPort wants to bind to a control (eg, \"print\") in a DIFFERENT component (eg, \"Panel\"),\n * then it specifies the name of that control with the 'binding' property. The SerialPort constructor\n * will then call bindExternalControl(), which looks up the control, and then passes it to our own\n * setBinding() handler.\n * \n * For bindExternalControl() to succeed, it also need to know the target component; for now, that's\n * been hard-coded to \"Panel\", in part because that's one of the few components we can rely upon\n * initializing before we do, but it would be a simple matter to include a component type or ID as part\n * of the 'binding' property as well, if we need more flexibility later.\n * \n * NOTE: If sBinding is not the name of a valid Control Panel DOM element, this call does nothing.\n */\n Component.bindExternalControl(this, sBinding);\n }\n\n /*\n * No connection until initConnection() is called.\n */\n this.sDataReceived = \"\";\n this.connection = this.sendData = this.updateStatus = null;\n\n /*\n * Export all functions required by initConnection().\n */\n this['exports'] = {\n 'connect': this.initConnection,\n 'receiveData': this.receiveData,\n 'receiveStatus': this.receiveStatus,\n 'setConnection': this.setConnection\n };\n }\n\n /**\n * setBinding(sType, sBinding, control, sValue)\n *\n * @this {SerialPortPDP10}\n * @param {string|null} sType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"buffer\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sType, sBinding, control, sValue)\n {\n if (sType == null || sType == \"textarea\") {\n\n var serial = this;\n this.bindings[sBinding] = this.controlBuffer = control;\n\n /*\n * An onkeydown handler is required for certain keys that browsers tend to consume themselves;\n * for example, BACKSPACE is often defined as going back to the previous web page, and certain\n * CTRL keys are often used for browser shortcuts (usually on Windows-based browsers).\n *\n * NOTE: We don't bother with a keyUp handler, because for the most part, we're only intercepting\n * keys that require special treatment; in general, we're content with keyPress events.\n */\n control.onkeydown = function onKeyDown(event) {\n event = event || window.event;\n var bASCII = 0;\n var keyCode = event.keyCode;\n /*\n * Perform the same remapping of BACKSPACE and DELETE that our VT100 emulation performs,\n * for PCjs-wide consistency; see the KEYMAP table in /modules/pc8080/lib/keyboard.js for\n * the rationale. Ditto for ALT-DELETE; see onKeyDown() in /modules/pc8080/lib/keyboard.js\n * for details.\n *\n * NOTE: keyDown (and keyUp) events supply us with KEYCODE values, which are NOT the same as\n * ASCII values, which is why we are comparing with KEYCODE values but assigning ASCII values,\n * because receiveData() requires ASCII values.\n */\n if (keyCode == Keys.KEYCODE.BS) {\n bASCII = event.altKey? Keys.ASCII.CTRL_H : Keys.ASCII.DEL;\n }\n else if (keyCode == Keys.KEYCODE.DEL) {\n bASCII = Keys.ASCII.CTRL_H;\n }\n else if (event.ctrlKey && keyCode >= Keys.ASCII.A && keyCode <= Keys.ASCII.Z) {\n bASCII = keyCode - (Keys.ASCII.A - Keys.ASCII.CTRL_A);\n }\n if (bASCII) {\n if (event.preventDefault) event.preventDefault();\n serial.receiveData(bASCII);\n }\n return true;\n };\n\n control.onkeypress = function onKeyPress(event) {\n /*\n * NOTE: Unlike keyDown events, keyPress events generally supply us with ASCII values,\n * despite the fact that, as above, they come to us via the keyCode property. Yes, it's\n * brilliant (or rather, the opposite of brilliant), but that's life.\n */\n event = event || window.event;\n /*\n * Not sure why COMMAND-key combinations are coming through here (on Safari at least),\n * but in any case, let's make sure we don't act on them.\n */\n if (!event.metaKey) {\n var bASCII = event.which || event.keyCode;\n /*\n * Perform the same remapping of ALT-ENTER (to LINE-FEED) that our VT100 emulation performs,\n * for PCjs-wide consistency; see onKeyDown() in /modules/pc8080/lib/keyboard.js for details.\n */\n if (event.altKey) {\n if (bASCII == Keys.ASCII.CTRL_M) {\n bASCII = Keys.ASCII.CTRL_J;\n }\n }\n serial.receiveData(bASCII);\n /*\n * Since we're going to remove the \"readonly\" attribute from the <textarea> control\n * (so that the soft keyboard activates on iOS), instead of calling preventDefault() for\n * selected keys (eg, the SPACE key, whose default behavior is to scroll the page), we must\n * now call it for *all* keys, so that the keyCode isn't added to the control immediately,\n * on top of whatever the machine is echoing back, resulting in double characters.\n */\n if (event.preventDefault) event.preventDefault();\n }\n return true;\n };\n\n control.onpaste = function onKeyPress(event) {\n if (event.stopPropagation) event.stopPropagation();\n if (event.preventDefault) event.preventDefault();\n var clipboardData = event.clipboardData || window.clipboardData;\n if (clipboardData) {\n /*\n * NOTE: Multiple lines of pasted text will (at least on macOS) contain LFs instead of CRs;\n * this is dealt with in receiveData() whenever it receives a string of characters.\n */\n serial.receiveData(clipboardData.getData('Text'));\n }\n };\n\n /*\n * Now that we've added an onkeypress handler that calls preventDefault() for ALL keys, the control\n * itself no longer needs the \"readonly\" attribute; we primarily need to remove it for iOS browsers,\n * so that the soft keyboard will activate, but it shouldn't hurt to remove the attribute for all browsers.\n */\n control.removeAttribute(\"readonly\");\n\n return true;\n }\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {SerialPortPDP10}\n * @param {ComputerPDP10} cmp\n * @param {BusPDP10} bus\n * @param {CPUStatePDP10} cpu\n * @param {DebuggerPDP10} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n this.setReady();\n }\n\n /**\n * initConnection(fNullModem)\n *\n * If a machine 'connection' parameter exists of the form \"{sourcePort}->{targetMachine}.{targetPort}\",\n * and \"{sourcePort}\" matches our idComponent, then look for a component with id \"{targetMachine}.{targetPort}\".\n *\n * If the target component is found, then verify that it has exported functions with the following names:\n *\n * receiveData(data): called when we have data to transmit; aliased internally to sendData(data)\n * receiveStatus(pins): called when our control signals have changed; aliased internally to updateStatus(pins)\n *\n * For now, we're not going to worry about communication in the other direction, because when the target component\n * performs its own initConnection(), it will find our receiveData() and receiveStatus() functions, at which point\n * communication in both directions should be established, and the circle of life complete.\n *\n * For added robustness, if the target machine initializes much more slowly than we do, and our connection attempt\n * fails, that's OK, because when it finally initializes, its initConnection() will call our initConnection();\n * if we've already initialized, no harm done.\n *\n * @this {SerialPortPDP10}\n * @param {boolean} [fNullModem] (caller's null-modem setting, to ensure our settings are in agreement)\n */\n initConnection(fNullModem)\n {\n if (!this.connection) {\n var sConnection = this.cmp.getMachineParm(\"connection\");\n if (sConnection) {\n var asParts = sConnection.split('->');\n if (asParts.length == 2) {\n var sSourceID = Str.trim(asParts[0]);\n if (sSourceID != this.idComponent) return; // this connection string is intended for another instance\n var sTargetID = Str.trim(asParts[1]);\n this.connection = Component.getComponentByID(sTargetID);\n if (this.connection) {\n var exports = this.connection['exports'];\n if (exports) {\n var fnConnect = exports['connect'];\n if (fnConnect) fnConnect.call(this.connection, this.fNullModem);\n this.sendData = exports['receiveData'];\n if (this.sendData) {\n this.fNullModem = fNullModem;\n this.updateStatus = exports['receiveStatus'];\n this.status(\"Connected \" + this.idMachine + '.' + sSourceID + \" to \" + sTargetID);\n return;\n }\n }\n }\n }\n /*\n * Changed from notice() to status() because sometimes a connection fails simply because one of us is a laggard.\n */\n this.status(\"Unable to establish connection: \" + sConnection);\n }\n }\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {SerialPortPDP10}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n\n /*\n * This is as late as we can currently wait to make our first inter-machine connection attempt;\n * even so, the target machine's initialization process may still be ongoing, so any connection\n * may be not fully resolved until the target machine performs its own initConnection(), which will\n * in turn invoke our initConnection() again.\n */\n this.initConnection(this.fNullModem);\n\n if (!data) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {SerialPortPDP10}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {SerialPortPDP10}\n */\n reset()\n {\n this.initState();\n }\n\n /**\n * save()\n *\n * This implements save support for the SerialPort component.\n *\n * @this {SerialPortPDP10}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveRegisters());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the SerialPort component.\n *\n * @this {SerialPortPDP10}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return this.initState(data[0]);\n }\n\n /**\n * initState(a)\n *\n * @this {SerialPortPDP10}\n * @param {Array} [a]\n * @return {boolean} true if successful, false if failure\n */\n initState(a)\n {\n return true;\n }\n\n /**\n * saveRegisters()\n *\n * Basically, the inverse of initState().\n *\n * @this {SerialPortPDP10}\n * @return {Array}\n */\n saveRegisters()\n {\n return [];\n }\n\n /**\n * receiveData(data)\n *\n * This replaces the old sendRBR() function, which expected an Array of bytes. We still support that,\n * but in order to support connections with other SerialPort components (ie, the PC8080 SerialPort), we\n * have added support for numbers and strings as well.\n *\n * @this {SerialPortPDP10}\n * @param {number|string|Array} data\n * @return {boolean} true if received, false if not\n */\n receiveData(data)\n {\n if (typeof data == \"number\") {\n this.abReceive.push(data);\n }\n else if (typeof data == \"string\") {\n var bASCII = 0, bASCIIPrev;\n for (var i = 0; i < data.length; i++) {\n bASCIIPrev = bASCII;\n bASCII = data.charCodeAt(i);\n /*\n * NOTE: Multiple lines of pasted text will (at least on macOS) contain LFs instead of CRs;\n * we convert them to CRs below. Windows may do something different, but in the worst case,\n * even if we receive CR/LF pairs, this code should keep the CRs and lose the LFs.\n */\n if (bASCII == Str.ASCII.LF) {\n if (bASCIIPrev == Str.ASCII.CR) continue;\n bASCII = Str.ASCII.CR;\n }\n this.abReceive.push(bASCII);\n }\n }\n else {\n this.abReceive = this.abReceive.concat(data);\n }\n\n return true; // for now, return true regardless, since we're buffering everything anyway\n }\n\n /**\n * receiveByte()\n *\n * @this {SerialPortPDP10}\n * @return {number} (0x00-0xff if byte available, -1 if not)\n */\n receiveByte()\n {\n var b = -1;\n if (this.abReceive.length) {\n /*\n * Here, as elsewhere (eg, the PC11 component), even if I trusted all incoming data\n * to be byte values (which I don't), there's also the risk that it could be signed data\n * (eg, -128 to 127, instead of 0 to 255). Both risks are good reasons to always mask\n * the data assigned to RBUF with 0xff.\n */\n b = this.abReceive.shift() & 0xff;\n this.printMessage(\"receiveByte(\" + Str.toHexByte(b) + \")\");\n if (this.fUpperCase) {\n /*\n * Automatically transform lower-case ASCII codes to upper-case; fUpperCase should\n * only be set when a terminal or some sort of pseudo-display is being used and we don't\n * trust it to have its CAPS-LOCK setting correct.\n */\n if (b >= 0x61 && b < 0x7A) b -= 0x20;\n }\n }\n return b;\n }\n\n /**\n * receiveStatus(pins)\n *\n * @this {SerialPortPDP10}\n * @param {number} pins\n */\n receiveStatus(pins)\n {\n }\n\n /**\n * setConnection(component, fn)\n *\n * @this {SerialPortPDP10}\n * @param {Object|null} component\n * @param {function(number)} fn\n * @return {boolean}\n */\n setConnection(component, fn)\n {\n if (!this.connection) {\n this.connection = component;\n this.sendData = fn;\n return true;\n }\n return false;\n }\n\n /**\n * transmitByte(b)\n *\n * @this {SerialPortPDP10}\n * @param {number} b\n * @return {boolean} true if transmitted, false if not\n */\n transmitByte(b)\n {\n var fTransmitted = false;\n\n if (MAXDEBUG) this.printMessage(\"transmitByte(\" + Str.toHexByte(b) + \")\");\n\n if (this.sendData) {\n if (this.sendData.call(this.connection, b)) {\n fTransmitted = true;\n }\n }\n\n /*\n * TODO: Why do DEC diagnostics like to output bytes with bit 7 set?\n */\n b &= 0x7F;\n if (this.controlBuffer) {\n if (b == 0x0D) {\n this.iLogicalCol = 0;\n }\n else if (b == 0x08) {\n this.controlBuffer.value = this.controlBuffer.value.slice(0, -1);\n /*\n * TODO: Back up the correct number of columns if the character erased was a tab.\n */\n if (this.iLogicalCol > 0) this.iLogicalCol--;\n }\n else if (b) {\n /*\n * RT-11 outputs lots of NULL characters, at least after a \"D 56=5015\" (0x0A0D) command has\n * been issued, hence the \"if (b)\" check above.\n *\n * TODO: Also consider a check for Keys.ASCII.CTRL_C, because by default, RT-11 outputs \"raw\"\n * CTRL_C characters, which we capture below and render as <ETX>. RT-11 does this for other keys\n * as well, such as CTRL_K (<VT>) and CTRL_L (<FF>).\n */\n var s = Str.toASCIICode(b); // formerly: String.fromCharCode(b);\n var nChars = s.length; // formerly: (b >= 0x20? 1 : 0);\n if (b < 0x20 && nChars == 1) nChars = 0;\n if (b == 0x09) {\n var tabSize = this.tabSize || 8;\n nChars = tabSize - (this.iLogicalCol % tabSize);\n if (this.tabSize) s = Str.pad(\"\", nChars);\n }\n if (this.charBOL && !this.iLogicalCol && nChars) s = String.fromCharCode(this.charBOL) + s;\n this.controlBuffer.value += s;\n this.controlBuffer.scrollTop = this.controlBuffer.scrollHeight;\n this.iLogicalCol += nChars;\n }\n fTransmitted = true;\n }\n else if (this.consoleBuffer != null) {\n if (b == 0x0A || this.consoleBuffer.length >= 1024) {\n this.println(this.consoleBuffer);\n this.consoleBuffer = \"\";\n }\n if (b != 0x0A) {\n this.consoleBuffer += String.fromCharCode(b);\n }\n fTransmitted = true;\n }\n\n return fTransmitted;\n }\n\n /**\n * SerialPortPDP10.init()\n *\n * This function operates on every HTML element of class \"serial\", extracting the\n * JSON-encoded parameters for the SerialPort constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a SerialPort component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeSerial = Component.getElementsByClass(document, PDP10.APPCLASS, \"serial\");\n for (var iSerial = 0; iSerial < aeSerial.length; iSerial++) {\n var eSerial = aeSerial[iSerial];\n var parmsSerial = Component.getComponentParms(eSerial);\n var serial = new SerialPortPDP10(parmsSerial);\n Component.bindComponentControls(serial, eSerial, PDP10.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize every SerialPort module on the page.\n */\nWeb.onInit(SerialPortPDP10.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/debugger.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Debugger Address Object\n *\n * This is the basic structure; other debuggers may extend it.\n *\n * addr address\n * fTemporary true if this is a temporary breakpoint address\n * sCmd set for breakpoint addresses if there's an associated command string\n * aCmds preprocessed commands (from sCmd)\n *\n * @typedef {{\n * addr:(number|undefined),\n * fTemporary:(boolean|undefined),\n * sCmd:(string|undefined),\n * aCmds:(Array.<string>|undefined)\n * }}\n */\nvar DbgAddr;\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * subclass (eg, SerialPort), because otherwise the Compiler won't allow us to *reference*\n * the named property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass Debugger extends Component\n{\n /**\n * Debugger(parmsDbg)\n *\n * The Debugger component supports the following optional (parmsDbg) properties:\n *\n * base: the base to use for most numeric input/output (default is 16)\n *\n * The Debugger component is a shared component containing a subset of functionality used by\n * the other CPU-specific Debuggers (eg, DebuggerX86). Over time, the goal is to factor out as\n * much common debugging support as possible from those components into this one.\n *\n * @param {Object} parmsDbg\n */\n constructor(parmsDbg)\n {\n if (DEBUGGER) {\n\n super(\"Debugger\", parmsDbg);\n\n /*\n * Default base used to display all values; modified with the \"s base\" command.\n */\n this.nBase = +parmsDbg['base'] || 16;\n\n /*\n * Default number of bits of integer precision; it can be overridden by the Debugger\n * but there is no command to adjust it.\n */\n this.nBits = 32;\n\n this.achGroup = ['{','}'];\n this.achAddress = ['[',']'];\n\n /*\n * These keep track of instruction activity, but only when tracing or when Debugger checks\n * have been enabled (eg, one or more breakpoints have been set).\n *\n * They are zeroed by the reset() notification handler. cInstructions is advanced by\n * stepCPU() and checkInstruction() calls. nCycles is updated by every stepCPU() or stop()\n * call and simply represents the number of cycles performed by the last run of instructions.\n */\n this.nCycles = 0;\n this.cOpcodes = this.cOpcodesStart = 0;\n\n /*\n * fAssemble is true when \"assemble mode\" is active, false when not.\n */\n this.fAssemble = false;\n\n /*\n * This maintains command history. New commands are inserted at index 0 of the array.\n * When Enter is pressed on an empty input buffer, we default to the command at aPrevCmds[0].\n */\n this.iPrevCmd = -1;\n this.aPrevCmds = [];\n\n /*\n * aVariables is an object with properties that grow as setVariable() assigns more variables;\n * each property corresponds to one variable, where the property name is the variable name (ie,\n * a string beginning with a non-digit, followed by zero or more symbol characters and/or digits)\n * and the property value is the variable's numeric value. See doVar() and setVariable() for\n * details.\n *\n * Note that parseValue() parses variables before numbers, so any variable that looks like a\n * unprefixed hex value (eg, \"a5\" as opposed to \"0xa5\") will trump the numeric value. Unprefixed\n * hex values are a convenience of parseValue(), which always calls Str.parseInt() with a default\n * base of 16; however, that default be overridden with a variety of explicit prefixes or suffixes\n * (eg, a leading \"0o\" to indicate octal, a trailing period to indicate decimal, etc.)\n *\n * See Str.parseInt() for more details about supported numbers.\n */\n this.aVariables = {};\n\n } // endif DEBUGGER\n }\n\n /**\n * getRegIndex(sReg, off)\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {string} sReg\n * @param {number} [off] optional offset into sReg\n * @return {number} register index, or -1 if not found\n */\n getRegIndex(sReg, off)\n {\n return -1;\n }\n\n /**\n * getRegValue(iReg)\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {number} iReg\n * @return {number|undefined}\n */\n getRegValue(iReg)\n {\n return undefined;\n }\n\n /**\n * parseAddrReference(s, sAddr)\n *\n * Returns the given string with the given address reference replaced with the contents of that address.\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {string} s\n * @param {string} sAddr\n * @return {string}\n */\n parseAddrReference(s, sAddr)\n {\n return s.replace('[' + sAddr + ']', \"unimplemented\");\n }\n\n /**\n * getNextCommand()\n *\n * @this {Debugger}\n * @return {string}\n */\n getNextCommand()\n {\n var sCmd;\n if (this.iPrevCmd > 0) {\n sCmd = this.aPrevCmds[--this.iPrevCmd];\n } else {\n sCmd = \"\";\n this.iPrevCmd = -1;\n }\n return sCmd;\n }\n\n /**\n * getPrevCommand()\n *\n * @this {Debugger}\n * @return {string|null}\n */\n getPrevCommand()\n {\n var sCmd = null;\n if (this.iPrevCmd < this.aPrevCmds.length - 1) {\n sCmd = this.aPrevCmds[++this.iPrevCmd];\n }\n return sCmd;\n }\n\n /**\n * parseCommand(sCmd, fSave, chSep)\n *\n * @this {Debugger}\n * @param {string|undefined} sCmd\n * @param {boolean} [fSave] is true to save the command, false if not\n * @param {string} [chSep] is the command separator character (default is ';')\n * @return {Array.<string>}\n */\n parseCommand(sCmd, fSave, chSep)\n {\n if (fSave) {\n if (!sCmd) {\n if (this.fAssemble) {\n sCmd = \"end\";\n } else {\n sCmd = this.aPrevCmds[this.iPrevCmd+1];\n }\n } else {\n if (this.iPrevCmd < 0 && this.aPrevCmds.length) {\n this.iPrevCmd = 0;\n }\n if (this.iPrevCmd < 0 || sCmd != this.aPrevCmds[this.iPrevCmd]) {\n this.aPrevCmds.splice(0, 0, sCmd);\n this.iPrevCmd = 0;\n }\n this.iPrevCmd--;\n }\n }\n var a = [];\n if (sCmd) {\n /*\n * With the introduction of breakpoint commands (ie, quoted command sequences\n * associated with a breakpoint), we can no longer perform simplistic splitting.\n *\n * a = sCmd.split(chSep || ';');\n * for (var i = 0; i < a.length; i++) a[i] = Str.trim(a[i]);\n *\n * We may now split on semi-colons ONLY if they are outside a quoted sequence.\n *\n * Also, to allow quoted strings *inside* breakpoint commands, we first replace all\n * DOUBLE double-quotes with single quotes.\n */\n sCmd = sCmd.replace(/\"\"/g, \"'\");\n\n var iPrev = 0;\n var chQuote = null;\n chSep = chSep || ';';\n /*\n * NOTE: Processing charAt() up to and INCLUDING length is not a typo; we're taking\n * advantage of the fact that charAt() with an invalid index returns an empty string,\n * allowing us to use the same substring() call to capture the final portion of sCmd.\n *\n * In a sense, it allows us to pretend that the string ends with a zero terminator.\n */\n for (var i = 0; i <= sCmd.length; i++) {\n var ch = sCmd.charAt(i);\n if (ch == '\"' || ch == \"'\") {\n if (!chQuote) {\n chQuote = ch;\n } else if (ch == chQuote) {\n chQuote = null;\n }\n }\n else if (ch == chSep && !chQuote || !ch) {\n /*\n * Recall that substring() accepts starting (inclusive) and ending (exclusive)\n * indexes, whereas substr() accepts a starting index and a length. We need the former.\n */\n a.push(Str.trim(sCmd.substring(iPrev, i)));\n iPrev = i + 1;\n }\n }\n }\n return a;\n }\n\n /**\n * evalAND(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.AND().\n *\n * Performs the bitwise \"and\" (AND) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst & src)\n */\n evalAND(dst, src)\n {\n /*\n * We AND the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 AND 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst & src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) & ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst & src) >>> 0);\n }\n\n /**\n * evalIOR(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.IOR().\n *\n * Performs the logical \"inclusive-or\" (OR) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst | src)\n */\n evalIOR(dst, src)\n {\n /*\n * We OR the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 OR 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst | src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) | ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst | src) >>> 0);\n }\n\n /**\n * evalXOR(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.XOR().\n *\n * Performs the logical \"exclusive-or\" (XOR) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst ^ src)\n */\n evalXOR(dst, src)\n {\n /*\n * We XOR the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 XOR 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst | src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) ^ ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst ^ src) >>> 0);\n }\n\n /**\n * evalMUL(dst, src)\n *\n * I could have adapted the code from /modules/pdp10/lib/cpuops.js:PDP10.doMUL(), but it was simpler to\n * write this base method and let the PDP-10 Debugger override it with a call to the *actual* doMUL() method.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst * src)\n */\n evalMUL(dst, src)\n {\n return dst * src;\n }\n\n /**\n * truncate(v, nBits, fUnsigned)\n *\n * @this {Debugger}\n * @param {number} v\n * @param {number} [nBits]\n * @param {boolean} [fUnsigned]\n * @return {number}\n */\n truncate(v, nBits, fUnsigned)\n {\n var limit, vNew = v;\n nBits = nBits || this.nBits;\n\n if (fUnsigned) {\n if (nBits == 32) {\n vNew = v >>> 0;\n }\n else if (nBits < 32) {\n vNew = v & ((1 << nBits) - 1);\n }\n else {\n limit = Math.pow(2, nBits);\n if (v < 0 || v >= limit) {\n vNew = v % limit;\n if (vNew < 0) vNew += limit;\n }\n }\n }\n else {\n if (nBits <= 32) {\n vNew = (v << (32 - nBits)) >> (32 - nBits);\n }\n else {\n limit = Math.pow(2, nBits - 1);\n if (v >= limit) {\n vNew = (v % limit);\n if (((v / limit)|0) & 1) vNew -= limit;\n } else if (v < -limit) {\n vNew = (v % limit);\n if ((((-v - 1) / limit) | 0) & 1) {\n if (vNew) vNew += limit;\n }\n else {\n if (!vNew) vNew -= limit;\n }\n }\n }\n }\n if (v != vNew) {\n if (MAXDEBUG) this.println(\"warning: value \" + v + \" truncated to \" + vNew);\n v = vNew;\n }\n return v;\n }\n\n /**\n * evalOps(aVals, aOps, cOps)\n *\n * Some of our clients want a specific number of bits of integer precision. If that precision is\n * greater than 32, some of the operations below will fail; for example, JavaScript bitwise operators\n * always truncate the result to 32 bits, so beware when using shift operations. Similarly, it would\n * be wrong to always \"|0\" the final result, which is why we rely on truncate() now.\n *\n * Note that JavaScript integer precision is limited to 52 bits. For example, in Node, if you set a\n * variable to 0x80000001:\n *\n * foo=0x80000001|0\n *\n * then calculate foo*foo and display the result in binary using \"(foo*foo).toString(2)\":\n *\n * '11111111111111111111111111111100000000000000000000000000000000'\n *\n * which is slightly incorrect because it has overflowed JavaScript's floating-point precision.\n *\n * 0x80000001 in decimal is -2147483647, so the product is 4611686014132420609, which is 0x3FFFFFFF00000001.\n *\n * @this {Debugger}\n * @param {Array.<number>} aVals\n * @param {Array.<string>} aOps\n * @param {number} [cOps] (default is -1 for all)\n * @return {boolean} true if successful, false if error\n */\n evalOps(aVals, aOps, cOps = -1)\n {\n while (cOps-- && aOps.length) {\n var chOp = aOps.pop();\n if (aVals.length < 2) return false;\n var valNew;\n var val2 = aVals.pop();\n var val1 = aVals.pop();\n switch(chOp) {\n case '*':\n valNew = this.evalMUL(val1, val2);\n break;\n case '/':\n if (!val2) return false;\n valNew = Math.trunc(val1 / val2);\n break;\n case '^/':\n if (!val2) return false;\n valNew = val1 % val2;\n break;\n case '+':\n valNew = val1 + val2;\n break;\n case '-':\n valNew = val1 - val2;\n break;\n case '<<':\n valNew = val1 << val2;\n break;\n case '>>':\n valNew = val1 >> val2;\n break;\n case '>>>':\n valNew = val1 >>> val2;\n break;\n case '<':\n valNew = (val1 < val2? 1 : 0);\n break;\n case '<=':\n valNew = (val1 <= val2? 1 : 0);\n break;\n case '>':\n valNew = (val1 > val2? 1 : 0);\n break;\n case '>=':\n valNew = (val1 >= val2? 1 : 0);\n break;\n case '==':\n valNew = (val1 == val2? 1 : 0);\n break;\n case '!=':\n valNew = (val1 != val2? 1 : 0);\n break;\n case '&':\n valNew = this.evalAND(val1, val2);\n break;\n case '!': // alias for MACRO-10 to perform a bitwise inclusive-or (OR)\n case '|':\n valNew = this.evalIOR(val1, val2);\n break;\n case '^!': // since MACRO-10 uses '^' for base overrides, '^!' is used for bitwise exclusive-or (XOR)\n valNew = this.evalXOR(val1, val2);\n break;\n case '&&':\n valNew = (val1 && val2? 1 : 0);\n break;\n case '||':\n valNew = (val1 || val2? 1 : 0);\n break;\n case ',,':\n valNew = this.truncate(val1, 18, true) * Math.pow(2, 18) + this.truncate(val2, 18, true);\n break;\n case '_':\n case '^_':\n valNew = val1;\n /*\n * While we always try to avoid assuming any particular number of bits of precision, the 'B' shift\n * operator (which we've converted to '^_') is unique to the MACRO-10 environment, which imposes the\n * following restrictions on the shift count.\n */\n if (chOp == '^_') val2 = 35 - (val2 & 0xff);\n if (val2) {\n /*\n * Since binary shifting is a logical (not arithmetic) operation, and since shifting by division only\n * works properly with positive numbers, we call truncate() to produce an unsigned value.\n */\n valNew = this.truncate(valNew, 0, true);\n if (val2 > 0) {\n valNew *= Math.pow(2, val2);\n } else {\n valNew = Math.trunc(valNew / Math.pow(2, -val2));\n }\n }\n break;\n default:\n return false;\n }\n aVals.push(this.truncate(valNew));\n }\n return true;\n }\n\n /**\n * parseArray(asValues, iValue, iLimit, nBase, aUndefined)\n *\n * parseExpression() takes a complete expression and divides it into array elements, where even elements\n * are values (which may be empty if two or more operators appear consecutively) and odd elements are operators.\n *\n * For example, if the original expression was \"2*{3+{4/2}}\", parseExpression() would call parseArray() with:\n *\n * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14\n * - - - - - - - - - - -- -- -- -- --\n * 2 * { 3 + { 4 / 2 } }\n *\n * This function takes care of recursively processing grouped expressions, by processing subsets of the array,\n * as well as handling certain base overrides (eg, temporarily switching to base-10 for binary shift suffixes).\n *\n * @param {Array.<string>} asValues\n * @param {number} iValue\n * @param {number} iLimit\n * @param {number} nBase\n * @param {Array|undefined} [aUndefined]\n * @return {number|undefined}\n */\n parseArray(asValues, iValue, iLimit, nBase, aUndefined)\n {\n var value;\n var sValue, sOp;\n var fError = false;\n var nUnary = 0;\n var aVals = [], aOps = [];\n\n var nBasePrev = this.nBase;\n this.nBase = nBase;\n\n while (iValue < iLimit) {\n var v;\n sValue = asValues[iValue++].trim();\n sOp = (iValue < iLimit? asValues[iValue++] : \"\");\n\n if (sValue) {\n v = this.parseValue(sValue, null, aUndefined, nUnary);\n } else {\n if (sOp == '{') {\n var cOpen = 1;\n var iStart = iValue;\n while (iValue < iLimit) {\n sValue = asValues[iValue++].trim();\n sOp = (iValue < asValues.length? asValues[iValue++] : \"\");\n if (sOp == '{') {\n cOpen++;\n } else if (sOp == '}') {\n if (!--cOpen) break;\n }\n }\n v = this.parseArray(asValues, iStart, iValue-1, this.nBase, aUndefined);\n if (v != null && nUnary) {\n v = this.parseUnary(v, nUnary);\n }\n sValue = (iValue < iLimit? asValues[iValue++].trim() : \"\");\n sOp = (iValue < iLimit? asValues[iValue++] : \"\");\n }\n else {\n /*\n * When parseExpression() calls us, it has collapsed all runs of whitespace into single spaces,\n * and although it allows single spaces to divide the elements of the expression, a space is neither\n * a unary nor binary operator. It's essentially a no-op. If we encounter it here, then it followed\n * another operator and is easily ignored (although perhaps it should still trigger a reset of nBase\n * and nUnary -- TBD).\n */\n if (sOp == ' ') {\n continue;\n }\n if (sOp == '^B') {\n this.nBase = 2;\n continue;\n }\n if (sOp == '^O') {\n this.nBase = 8;\n continue;\n }\n if (sOp == '^D') {\n this.nBase = 10;\n continue;\n }\n if (!(nUnary & (0xC0000000|0))) {\n if (sOp == '+') {\n continue;\n }\n if (sOp == '-') {\n nUnary = (nUnary << 2) | 1;\n continue;\n }\n if (sOp == '~' || sOp == '^-') {\n nUnary = (nUnary << 2) | 2;\n continue;\n }\n if (sOp == '^L') {\n nUnary = (nUnary << 2) | 3;\n continue;\n }\n }\n fError = true;\n break;\n }\n }\n\n if (v === undefined) {\n if (aUndefined) {\n aUndefined.push(sValue);\n v = 0;\n } else {\n fError = true;\n aUndefined = [];\n break;\n }\n }\n\n aVals.push(this.truncate(v));\n\n /*\n * When parseExpression() calls us, it has collapsed all runs of whitespace into single spaces,\n * and although it allows single spaces to divide the elements of the expression, a space is neither\n * a unary nor binary operator. It's essentially a no-op. If we encounter it here, then it followed\n * a value, and since we don't want to misinterpret the next operator as a unary operator, we look\n * ahead and grab the next operator if it's not preceded by a value.\n */\n if (sOp == ' ') {\n if (iValue < asValues.length - 1 && !asValues[iValue]) {\n iValue++;\n sOp = asValues[iValue++]\n } else {\n fError = true;\n break;\n }\n }\n\n if (!sOp) break;\n\n var aBinOp = (this.achGroup[0] == '<'? Debugger.aDECOpPrecedence : Debugger.aBinOpPrecedence);\n if (!aBinOp[sOp]) {\n fError = true;\n break;\n }\n if (aOps.length && aBinOp[sOp] <= aBinOp[aOps[aOps.length - 1]]) {\n this.evalOps(aVals, aOps, 1);\n }\n aOps.push(sOp);\n\n /*\n * The MACRO-10 binary shifting operator assumes a base-10 shift count, regardless of the current\n * base, so we must override the current base to ensure the count is parsed correctly.\n */\n this.nBase = (sOp == '^_')? 10 : nBase;\n nUnary = 0;\n }\n\n if (fError || !this.evalOps(aVals, aOps) || aVals.length != 1) {\n fError = true;\n }\n\n if (!fError) {\n value = aVals.pop();\n\n } else if (!aUndefined) {\n this.println(\"parse error (\" + (sValue || sOp) + \")\");\n }\n\n this.nBase = nBasePrev;\n return value;\n }\n\n /**\n * parseASCII(sExp, chDelim, nBits, cchMax)\n *\n * @this {Debugger}\n * @param {string} sExp\n * @param {string} chDelim\n * @param {number} nBits\n * @param {number} cchMax\n * @return {string|undefined}\n */\n parseASCII(sExp, chDelim, nBits, cchMax)\n {\n var i;\n while ((i = sExp.indexOf(chDelim)) >= 0) {\n var v = 0;\n var j = i + 1;\n var cch = cchMax;\n while (j < sExp.length) {\n var ch = sExp[j++];\n if (ch == chDelim) {\n cch = -1;\n break;\n }\n if (!cch) break;\n cch--;\n var c = ch.charCodeAt(0);\n if (nBits == 7) {\n c &= 0x7F;\n } else {\n c = (c - 0x20) & 0x3F;\n }\n v = this.truncate(v * Math.pow(2, nBits) + c, nBits * cchMax, true);\n }\n if (cch >= 0) {\n this.println(\"parse error (\" + chDelim + sExp + chDelim + \")\");\n return undefined;\n } else {\n sExp = sExp.substr(0, i) + this.toStrBase(v, -1) + sExp.substr(j);\n }\n }\n return sExp;\n }\n\n /**\n * parseExpression(sExp, fQuiet)\n *\n * A quick-and-dirty expression parser. It takes an expression like:\n *\n * EDX+EDX*4+12345678\n *\n * and builds a value stack in aVals and a \"binop\" (binary operator) stack in aOps:\n *\n * aVals aOps\n * ----- ----\n * EDX +\n * EDX *\n * 4 +\n * ...\n *\n * We pop 1 \"binop\" from aOps and 2 values from aVals whenever a \"binop\" of lower priority than its\n * predecessor is encountered, evaluate, and push the result back onto aVals. Only selected unary\n * operators are supported (eg, negate and complement); no ternary operators like '?:' are supported.\n *\n * fQuiet can be used to pass an array that collects any undefined variables that parseExpression()\n * encounters; the value of an undefined variable is zero. This mode was added for components that need\n * to support expressions containing \"fixups\" (ie, values that must be determined later).\n *\n * @this {Debugger}\n * @param {string|undefined} sExp\n * @param {Array|undefined|boolean} [fQuiet]\n * @return {number|undefined} numeric value, or undefined if sExp contains any undefined or invalid values\n */\n parseExpression(sExp, fQuiet)\n {\n var value = undefined;\n var fPrint = (fQuiet === false);\n var aUndefined = Array.isArray(fQuiet)? fQuiet : undefined;\n\n if (sExp) {\n\n /*\n * The default delimiting characters for grouped expressions are braces; they can be changed by altering\n * achGroup, but when that happens, instead of changing our regular expressions and operator tables,\n * we simply replace all achGroup characters with braces in the given expression.\n *\n * Why not use parentheses for grouped expressions? Because some debuggers use parseReference() to perform\n * parenthetical value replacements in message strings, and they don't want parentheses taking on a different\n * meaning. And for some machines, like the PDP-10, the convention is to use parentheses for other things,\n * like indexed addressing, and to use angle brackets for grouped expressions.\n */\n if (this.achGroup[0] != '{') {\n sExp = sExp.split(this.achGroup[0]).join('{').split(this.achGroup[1]).join('}');\n }\n\n /*\n * Quoted ASCII characters can have a numeric value, too, which must be converted now, to avoid any\n * conflicts with the operators below.\n */\n sExp = this.parseASCII(sExp, '\"', 7, 5); // MACRO-10 packs up to 5 7-bit ASCII codes into a value\n if (!sExp) return value;\n sExp = this.parseASCII(sExp, \"'\", 6, 6); // MACRO-10 packs up to 6 6-bit ASCII (SIXBIT) codes into a value\n if (!sExp) return value;\n\n /*\n * All browsers (including, I believe, IE9 and up) support the following idiosyncrasy of a RegExp split():\n * when the RegExp uses a capturing pattern, the resulting array will include entries for all the pattern\n * matches along with the non-matches. This effectively means that, in the set of expressions that we\n * support, all even entries in asValues will contain \"values\" and all odd entries will contain \"operators\".\n *\n * Although I started listing the operators in the RegExp in \"precedential\" order, that's not important;\n * what IS important is listing operators than contain shorter operators first. For example, bitwise\n * shift operators must be listed BEFORE the logical less-than or greater-than operators. The aBinOp tables\n * (aBinOpPrecedence and aDECOpPrecedence) are what determine precedence, not the RegExp.\n *\n * Also, to better accommodate MACRO-10 syntax, I've replaced the single '^' for XOR with '^!', and I've\n * added '!' as an alias for '|' (bitwise inclusive-or), '^-' as an alias for '~' (one's complement operator),\n * and '_' as a shift operator (+/- values specify a left/right shift, and the count is not limited to 32).\n *\n * And to avoid conflicts with MACRO-10 syntax, I've replaced the original mod operator ('%') with '^/'.\n *\n * The MACRO-10 binary shifting suffix ('B') is a bit more problematic, since a capital B can also appear\n * inside symbols, or inside hex values. So if the default base is NOT 16, then I pre-scan for that suffix\n * and replace all non-symbolic occurrences with an internal shift operator ('^_').\n *\n * Note that Str.parseInt(), which parseValue() relies on, supports both the MACRO-10 base prefix overrides\n * and the binary shifting suffix ('B'), but since that suffix can also be a bracketed expression, we have to\n * support it here as well.\n *\n * MACRO-10 supports only a subset of all the PCjs operators; for example, MACRO-10 doesn't support any of\n * the boolean logical/compare operators. But unless we run into conflicts, I prefer sticking with this\n * common set of operators.\n *\n * All whitespace in the expression is collapsed to single spaces, and space has been added to the list\n * of \"operators\", but its sole function is as a separator, not as an operator. parseArray() will ignore\n * single spaces as long as they are preceded and/or followed by a \"real\" operator. It would be dangerous\n * to remove spaces entirely, because if an operator-less expression like \"A B\" was passed in, we would want\n * that to generate an error; if we converted it to \"AB\", evaluation might inadvertently succeed.\n */\n var regExp = /({|}|\\|\\||&&|\\||\\^!|\\^B|\\^O|\\^D|\\^L|\\^-|~|\\^_|_|&|!=|!|==|>=|>>>|>>|>|<=|<<|<|-|\\+|\\^\\/|\\/|\\*|,,| )/;\n if (this.nBase != 16) {\n sExp = sExp.replace(/(^|[^A-Z0-9$%.])([0-9]+)B/, \"$1$2^_\").replace(/\\s+/g, ' ');\n }\n var asValues = sExp.split(regExp);\n value = this.parseArray(asValues, 0, asValues.length, this.nBase, aUndefined);\n if (value !== undefined && fPrint) {\n this.printValue(null, value);\n }\n }\n return value;\n }\n\n /**\n * parseReference(s)\n *\n * Returns the given string with any \"{expression}\" sequences replaced with the value of the expression,\n * and any \"[address]\" references replaced with the contents of the address. Expressions are parsed BEFORE\n * addresses.\n *\n * @this {Debugger}\n * @param {string} s\n * @return {string|undefined}\n */\n parseReference(s)\n {\n var a;\n var chOpen = this.achGroup[0];\n var chClose = this.achGroup[1];\n var chEscape = (chOpen == '(' || chOpen == '{' || chOpen == '[')? '\\\\' : '';\n var chInnerEscape = (chOpen == '['? '\\\\' : '');\n var reSubExp = new RegExp(chEscape + chOpen + \"([^\" + chInnerEscape + chOpen + chInnerEscape + chClose + \"]+)\" + chEscape + chClose);\n while (a = s.match(reSubExp)) {\n var value = this.parseExpression(a[1]);\n if (value === undefined) return undefined;\n var sSearch = chOpen + a[1] + chClose;\n var sReplace = value != null? this.toStrBase(value) : \"undefined\";\n /*\n * Note that by default, the String replace() method only replaces the FIRST occurrence,\n * and there MIGHT be more than one occurrence of the expression we just parsed, so we could\n * do this instead:\n *\n * s = s.split(sSearch).join(sReplace);\n *\n * However, that's knd of an expensive (slow) solution, and it's not strictly necessary, since\n * any additional identical expressions will be picked up on a subsequent iteration through this loop.\n */\n s = s.replace(sSearch, sReplace);\n }\n if (this.achAddress.length) {\n chOpen = this.achAddress[0];\n chClose = this.achAddress[1];\n chEscape = (chOpen == '(' || chOpen == '{' || chOpen == '[')? '\\\\' : '';\n chInnerEscape = (chOpen == '['? '\\\\' : '');\n reSubExp = new RegExp(chEscape + chOpen + \"([^\" + chInnerEscape + chOpen + chInnerEscape + chClose + \"]+)\" + chEscape + chClose);\n while (a = s.match(reSubExp)) {\n s = this.parseAddrReference(s, a[1]);\n }\n }\n return this.parseSysVars(s);\n }\n\n /**\n * parseSysVars(s)\n *\n * Returns the given string with any recognized \"$var\" replaced with its value; eg:\n *\n * $ops: the number of opcodes executed since the last time it was displayed (or reset)\n *\n * @this {Debugger}\n * @param {string} s\n * @return {string}\n */\n parseSysVars(s)\n {\n var a;\n while (a = s.match(/\\$([a-z]+)/i)) {\n var v = null;\n switch(a[1].toLowerCase()) {\n case \"ops\":\n v = this.cOpcodes - this.cOpcodesStart;\n break;\n }\n if (v == null) break;\n s = s.replace(a[0], v.toString());\n }\n return s;\n }\n\n /**\n * parseUnary(value, nUnary)\n *\n * nUnary is actually a small \"stack\" of unary operations encoded in successive pairs of bits.\n * As parseExpression() encounters each unary operator, nUnary is shifted left 2 bits, and the\n * new unary operator is encoded in bits 0 and 1 (0b00 is none, 0b01 is negate, 0b10 is complement,\n * and 0b11 is reserved). Here, we process the bits in reverse order (hence the stack-like nature),\n * ensuring that we process the unary operators associated with this value right-to-left.\n *\n * Since bitwise operators see only 32 bits, more than 16 unary operators cannot be supported\n * using this method. We'll let parseExpression() worry about that; if it ever happens in practice,\n * then we'll have to switch to a more \"expensive\" approach (eg, an actual array of unary operators).\n *\n * @this {Debugger}\n * @param {number} value\n * @param {number} nUnary\n * @return {number}\n */\n parseUnary(value, nUnary)\n {\n while (nUnary) {\n switch(nUnary & 0o3) {\n case 1:\n value = -this.truncate(value);\n break;\n case 2:\n value = this.evalXOR(value, -1); // this is easier than adding an evalNOT()...\n break;\n case 3:\n var bit = 35; // simple left-to-right zero-bit-counting loop...\n while (bit >= 0 && !this.evalAND(value, Math.pow(2, bit))) bit--;\n value = 35 - bit;\n break;\n }\n nUnary >>>= 2;\n }\n return value;\n }\n\n /**\n * parseValue(sValue, sName, fQuiet, nUnary)\n *\n * @this {Debugger}\n * @param {string|undefined} sValue\n * @param {string|null} [sName] is the name of the value, if any\n * @param {Array|undefined|boolean} [fQuiet]\n * @param {number} [nUnary] (0 for none, 1 for negate, 2 for complement, 3 for leading zeros)\n * @return {number|undefined} numeric value, or undefined if sValue is either undefined or invalid\n */\n parseValue(sValue, sName, fQuiet, nUnary = 0)\n {\n var value;\n var aUndefined = Array.isArray(fQuiet)? fQuiet : undefined;\n\n if (sValue != null) {\n var iReg = this.getRegIndex(sValue);\n if (iReg >= 0) {\n value = this.getRegValue(iReg);\n } else {\n value = this.getVariable(sValue);\n if (value != null) {\n var sUndefined = this.getVariableFixup(sValue);\n if (sUndefined) {\n if (aUndefined) {\n aUndefined.push(sUndefined);\n } else {\n var valueUndefined = this.parseExpression(sUndefined, fQuiet);\n if (valueUndefined !== undefined) {\n value += valueUndefined;\n } else {\n if (!fQuiet) {\n this.println(\"undefined \" + (sName || \"value\") + \": \" + sValue + \" (\" + sUndefined + \")\");\n }\n value = undefined;\n }\n }\n }\n } else {\n /*\n * A feature of MACRO-10 is that any single-digit number is automatically interpreted as base-10.\n */\n value = Str.parseInt(sValue, sValue.length > 1 || this.nBase > 10? this.nBase : 10);\n }\n }\n if (value != null) {\n value = this.truncate(this.parseUnary(value, nUnary));\n } else {\n if (!fQuiet) {\n this.println(\"invalid \" + (sName || \"value\") + \": \" + sValue);\n }\n }\n } else {\n if (!fQuiet) {\n this.println(\"missing \" + (sName || \"value\"));\n }\n }\n return value;\n }\n\n /**\n * printValue(sVar, value)\n *\n * @this {Debugger}\n * @param {string|null} sVar\n * @param {number|undefined} value\n * @return {boolean} true if value defined, false if not\n */\n printValue(sVar, value)\n {\n var sValue;\n var fDefined = false;\n if (value !== undefined) {\n fDefined = true;\n if (this.nBase == 8) {\n sValue = this.toStrBase(value, this.nBits, 8, 1) + \" \" + value + '.';\n } else {\n sValue = this.toStrBase(value, this.nBits, 16, 1) + \" \" + this.toStrBase(value, this.nBits, 8, 1) + \" \" + this.toStrBase(value, this.nBits, 2, this.nBits <= 32? 8 : 6) + \" \" + value + '.';\n }\n if (value >= 0x20 && value < 0x7F) {\n sValue += \" '\" + String.fromCharCode(value) + \"'\";\n }\n }\n sVar = (sVar != null? (sVar + \": \") : \"\");\n this.println(sVar + sValue);\n return fDefined;\n }\n\n /**\n * resetVariables()\n *\n * @this {Debugger}\n * @return {Object}\n */\n resetVariables()\n {\n var a = this.aVariables;\n this.aVariables = {};\n return a;\n }\n\n /**\n * restoreVariables(a)\n *\n * @this {Debugger}\n * @param {Object} a (from previous resetVariables() call)\n */\n restoreVariables(a)\n {\n this.aVariables = a;\n }\n\n /**\n * printVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} [sVar]\n * @return {boolean} true if all value(s) defined, false if not\n */\n printVariable(sVar)\n {\n var cVariables = 0;\n if (this.aVariables) {\n if (sVar) {\n return this.printValue(sVar, this.aVariables[sVar] && this.aVariables[sVar].value);\n }\n var aVars = Object.keys(this.aVariables);\n aVars.sort();\n for (var i = 0; i < aVars.length; i++) {\n this.printValue(aVars[i], this.aVariables[aVars[i]].value);\n cVariables++;\n }\n }\n return cVariables > 0;\n }\n\n /**\n * delVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n */\n delVariable(sVar)\n {\n delete this.aVariables[sVar];\n }\n\n /**\n * getVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {number|undefined}\n */\n getVariable(sVar)\n {\n if (this.aVariables[sVar]) {\n return this.aVariables[sVar].value;\n }\n sVar = sVar.substr(0, 6);\n return this.aVariables[sVar] && this.aVariables[sVar].value;\n }\n\n /**\n * getVariableFixup(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {string|undefined}\n */\n getVariableFixup(sVar)\n {\n return this.aVariables[sVar] && this.aVariables[sVar].sUndefined;\n }\n\n /**\n * isVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {boolean}\n */\n isVariable(sVar)\n {\n return this.aVariables[sVar] !== undefined;\n }\n\n /**\n * setVariable(sVar, value, sUndefined)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @param {number} value\n * @param {string|undefined} [sUndefined]\n */\n setVariable(sVar, value, sUndefined)\n {\n this.aVariables[sVar] = {value, sUndefined};\n }\n\n /**\n * toStrBase(n, nBits, nBase, nGrouping)\n *\n * Use this instead of Str's toOct()/toDec()/toHex() to convert numbers to the Debugger's default base.\n *\n * @this {Debugger}\n * @param {number|null|undefined} n\n * @param {number} [nBits] (-1 to strip leading zeros, 0 to allow a variable number of digits)\n * @param {number} [nBase]\n * @param {number} [nGrouping] (if nBase is 2, this is a grouping; otherwise, it's a prefix condition)\n * @return {string}\n */\n toStrBase(n, nBits = 0, nBase = 0, nGrouping = 0)\n {\n var s;\n switch(nBase || this.nBase) {\n case 2:\n s = Str.toBin(n, nBits > 0? nBits : 0, nGrouping);\n break;\n case 8:\n s = Str.toOct(n, nBits > 0? ((nBits + 2)/3)|0 : 0, !!nGrouping);\n break;\n case 10:\n /*\n * The multiplier is actually Math.log(2)/Math.log(10), but an approximation is more than adequate.\n */\n s = Str.toDec(n, nBits > 0? Math.ceil(nBits * 0.3) : 0);\n break;\n case 16:\n default:\n s = Str.toHex(n, nBits > 0? ((nBits + 3) >> 2) : 0, !!nGrouping);\n break;\n }\n return (nBits < 0? Str.stripLeadingZeros(s) : s);\n }\n}\n\nif (DEBUGGER) {\n\n /*\n * These are our operator precedence tables. Operators toward the bottom (with higher values) have\n * higher precedence. aBinOpPrecedence was our original table; we had to add aDECOpPrecedence because\n * the precedence of operators in DEC's MACRO-10 expressions differ. Having separate tables also allows\n * us to remove operators that shouldn't be supported, but unless some operator creates a problem,\n * I prefer to keep as much commonality between the tables as possible.\n *\n * Missing from these tables are the (limited) set of unary operators we support (negate and complement),\n * since this is only a BINARY operator precedence, not a general-purpose precedence table. Assume that\n * all unary operators take precedence over all binary operators.\n */\n Debugger.aBinOpPrecedence = {\n '||': 5, // logical OR\n '&&': 6, // logical AND\n '!': 7, // bitwise OR (conflicts with logical NOT, but we never supported that)\n '|': 7, // bitwise OR\n '^!': 8, // bitwise XOR (added by MACRO-10 sometime between the 1972 and 1978 versions)\n '&': 9, // bitwise AND\n '!=': 10, // inequality\n '==': 10, // equality\n '>=': 11, // greater than or equal to\n '>': 11, // greater than\n '<=': 11, // less than or equal to\n '<': 11, // less than\n '>>>': 12, // unsigned bitwise right shift\n '>>': 12, // bitwise right shift\n '<<': 12, // bitwise left shift\n '-': 13, // subtraction\n '+': 13, // addition\n '^/': 14, // remainder\n '/': 14, // division\n '*': 14, // multiplication\n '_': 19, // MACRO-10 shift operator\n '^_': 19, // MACRO-10 internal shift operator (converted from 'B' suffix form that MACRO-10 uses)\n '{': 20, // open grouped expression (converted from achGroup[0])\n '}': 20 // close grouped expression (converted from achGroup[1])\n };\n Debugger.aDECOpPrecedence = {\n ',,': 1, // high-word,,low-word\n '||': 5, // logical OR\n '&&': 6, // logical AND\n '!=': 10, // inequality\n '==': 10, // equality\n '>=': 11, // greater than or equal to\n '>': 11, // greater than\n '<=': 11, // less than or equal to\n '<': 11, // less than\n '>>>': 12, // unsigned bitwise right shift\n '>>': 12, // bitwise right shift\n '<<': 12, // bitwise left shift\n '-': 13, // subtraction\n '+': 13, // addition\n '^/': 14, // remainder\n '/': 14, // division\n '*': 14, // multiplication\n '!': 15, // bitwise OR (conflicts with logical NOT, but we never supported that)\n '|': 15, // bitwise OR\n '^!': 15, // bitwise XOR (added by MACRO-10 sometime between the 1972 and 1978 versions)\n '&': 15, // bitwise AND\n '_': 19, // MACRO-10 shift operator\n '^_': 19, // MACRO-10 internal shift operator (converted from 'B' suffix form that MACRO-10 uses)\n '{': 20, // open grouped expression (converted from achGroup[0])\n '}': 20 // close grouped expression (converted from achGroup[1])\n };\n\n /*\n * Assorted constants\n */\n Debugger.TWO_POW32 = Math.pow(2, 32);\n\n} // endif DEBUGGER\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/debugger.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * DebuggerPDP10 Address Object\n *\n * addr address\n * fPhysical true if this is a physical address\n * fTemporary true if this is a temporary breakpoint address\n * nBase set if the address contained an explicit base (eg, 16, 10, 8, etc)\n * sCmd set for breakpoint addresses if there's an associated command string\n * aCmds preprocessed commands (from sCmd)\n *\n * @typedef {{\n * addr:(number|null),\n * fPhysical:(boolean),\n * fTemporary:(boolean),\n * nBase:(number|undefined),\n * sCmd:(string|undefined),\n * aCmds:(Array.<string>|undefined)\n * }}\n */\nvar DbgAddrPDP10;\n\nclass DebuggerPDP10 extends Debugger {\n /**\n * DebuggerPDP10(parmsDbg)\n *\n * The DebuggerPDP10 component supports the following optional (parmsDbg) properties:\n *\n * commands: string containing zero or more commands, separated by ';'\n *\n * messages: string containing zero or more message categories to enable;\n * multiple categories must be separated by '|' or ';'. Parsed by messageInit().\n *\n * The DebuggerPDP10 component is an optional component that implements a variety of user\n * commands for controlling the CPU, dumping and editing memory, etc.\n *\n * @this {DebuggerPDP10}\n * @param {Object} parmsDbg\n */\n constructor(parmsDbg)\n {\n if (DEBUGGER) {\n\n super(parmsDbg);\n\n /*\n * Since this Debugger doesn't use replaceRegs(), we can use parentheses instead of braces.\n */\n this.fInit = false;\n this.nBusWidth = 18; // default value, updated by initBus()\n\n this.nBits = 36; // default integer precision\n this.achGroup = ['<','>'];\n this.achAddress = [];\n\n /*\n * Most commands that require an address call parseAddr(), and if a dbgAddr parameter is supplied\n * as as well (eg, dbgAddrCode, dbgAddrData), then that address will be used as the default.\n *\n * For TEMPORARY breakpoint addresses, we set fTemporary to true, so that they can be automatically\n * cleared when they're hit.\n */\n this.dbgAddrAcc = this.newAddr();\n this.dbgAddrCode = this.newAddr(0);\n this.dbgAddrData = this.newAddr(0);\n this.dbgAddrAssemble = this.newAddr(0);\n\n /*\n * aSymbolTable is an array of SymbolTable objects, one per ROM or other chunk of address space,\n * where each object contains the following properties:\n *\n * sModule\n * addr (physical address, if any; eg, symbols for a ROM)\n * len\n * aSymbols\n * aOffsets\n *\n * See addSymbols() for more details, since that's how callers add sets of symbols to the table.\n */\n this.aSymbolTable = [];\n\n /*\n * clearBreakpoints() initializes the breakpoints lists: aBreakExec is a list of addresses\n * to halt on whenever attempting to execute an instruction at the corresponding address,\n * and aBreakRead and aBreakWrite are lists of addresses to halt on whenever a read or write,\n * respectively, occurs at the corresponding address.\n *\n * NOTE: Curiously, after upgrading the Google Closure Compiler from v20141215 to v20150609,\n * the resulting compiled code would crash in clearBreakpoints(), because the (renamed) aBreakRead\n * property was already defined. To eliminate whatever was confusing the Closure Compiler, I've\n * explicitly initialized all the properties that clearBreakpoints() (re)initializes.\n */\n this.aBreakExec = this.aBreakRead = this.aBreakWrite = [];\n this.clearBreakpoints();\n\n /*\n * The new \"bn\" command allows you to specify a number of instructions to execute and then stop;\n * \"bn 0\" disables any outstanding count.\n */\n this.nBreakInstructions = 0;\n\n /*\n * Execution history is allocated by historyInit() whenever checksEnabled() conditions change.\n * Execution history is updated whenever the CPU calls checkInstruction(), which will happen\n * only when checksEnabled() returns true (eg, whenever one or more breakpoints have been set).\n * This ensures that, by default, the CPU runs as fast as possible.\n */\n this.iInstructionHistory = 0;\n this.aInstructionHistory = [];\n this.nextHistory = undefined;\n this.historyInit();\n\n /*\n * Initialize DebuggerPDP10 message support.\n */\n this.dbg = this;\n this.afnDumpers = {};\n this.bitsMessage = this.bitsWarning = 0;\n this.sMessagePrev = null;\n this.aMessageBuffer = [];\n this.messageInit(parmsDbg['messages']);\n this.sInitCommands = parmsDbg['commands'];\n this.aCommands = [];\n\n /*\n * Define remaining miscellaneous DebuggerPDP10 properties.\n */\n this.aOpReserved = [];\n this.nStep = 0;\n this.sCmdTracePrev = null;\n this.sCmdDumpPrev = null;\n this.nSuppressBreaks = 0;\n this.cInstructions = this.cInstructionsStart = 0;\n this.nCycles = this.nCyclesStart = this.msStart = 0;\n this.controlDebug = null;\n this.panel = null;\n\n /**\n * This records any active Macro10 assembler object.\n *\n * @type {Macro10|null}\n */\n this.macro10 = null;\n\n /*\n * Make it easier to access DebuggerPDP10 commands from an external REPL;\n * eg, the WebStorm \"live\" console window:\n *\n * pdp10('r')\n * pdp10('dw 0:0')\n * pdp10('h')\n * ...\n */\n var dbg = this;\n if (window) {\n if (window[PDP10.APPCLASS] === undefined) {\n window[PDP10.APPCLASS] = function(s) { return dbg.doCommands(s); };\n }\n } else {\n if (global[PDP10.APPCLASS] === undefined) {\n global[PDP10.APPCLASS] = function(s) { return dbg.doCommands(s); };\n }\n }\n\n } // endif DEBUGGER\n }\n\n /**\n * getAddr(dbgAddr, fWrite)\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10|null} [dbgAddr]\n * @param {boolean} [fWrite]\n * @return {number} is the corresponding linear address, or PDP10.ADDR_INVALID\n */\n getAddr(dbgAddr, fWrite)\n {\n var addr = dbgAddr && dbgAddr.addr;\n if (addr == null) addr = PDP10.ADDR_INVALID;\n return addr;\n }\n\n /**\n * newAddr(addr, fPhysical, nBase)\n *\n * Returns a NEW DbgAddrPDP10 object, initialized with specified values and/or defaults.\n *\n * @this {DebuggerPDP10}\n * @param {number|null} [addr]\n * @param {boolean} [fPhysical]\n * @param {number} [nBase]\n * @return {DbgAddrPDP10}\n */\n newAddr(addr = null, fPhysical = false, nBase)\n {\n return {addr: addr, fPhysical: fPhysical, fTemporary: false, nBase: nBase};\n }\n\n /**\n * copyAddr(dbgAddr, dbgCopy)\n *\n * Updates an EXISTING DbgAddrPDP10 object, initialized with specified values and/or defaults.\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @param {DbgAddrPDP10} dbgCopy\n * @return {DbgAddrPDP10}\n */\n copyAddr(dbgAddr, dbgCopy)\n {\n dbgAddr.addr = dbgCopy.addr;\n dbgAddr.fPhysical = dbgCopy.fPhysical;\n dbgAddr.fTemporary = dbgCopy.fTemporary;\n dbgAddr.nBase = dbgCopy.nBase;\n return dbgAddr;\n }\n\n /**\n * setAddr(dbgAddr, addr, fPhysical, nBase)\n *\n * Updates an EXISTING DbgAddrPDP10 object, initialized with specified values and/or defaults.\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @param {number} addr\n * @param {boolean} [fPhysical]\n * @param {number} [nBase]\n * @return {DbgAddrPDP10}\n */\n setAddr(dbgAddr, addr, fPhysical, nBase)\n {\n dbgAddr.addr = addr;\n dbgAddr.fPhysical = fPhysical || false;\n dbgAddr.fTemporary = false;\n dbgAddr.nBase = nBase;\n return dbgAddr;\n }\n\n /**\n * packAddr(dbgAddr)\n *\n * Packs a DbgAddrPDP10 object into an Array suitable for saving in a machine state object.\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @return {Array}\n */\n packAddr(dbgAddr)\n {\n return [dbgAddr.addr, dbgAddr.fPhysical, dbgAddr.fTemporary, dbgAddr.nBase, dbgAddr.sCmd];\n }\n\n /**\n * unpackAddr(aAddr)\n *\n * Unpacks a DbgAddrPDP10 object from an Array created by packAddr() and restored from a saved machine state.\n *\n * @this {DebuggerPDP10}\n * @param {Array} aAddr\n * @return {DbgAddrPDP10}\n */\n unpackAddr(aAddr)\n {\n var dbgAddr = this.newAddr(aAddr[0], aAddr[1], aAddr[2]);\n dbgAddr.fTemporary = aAddr[3];\n if (aAddr[4]) {\n dbgAddr.aCmds = this.parseCommand(dbgAddr.sCmd = aAddr[4]);\n }\n return dbgAddr;\n }\n\n /**\n * initBus(bus, cpu, dbg)\n *\n * @this {DebuggerPDP10}\n * @param {ComputerPDP10} cmp\n * @param {BusPDP10} bus\n * @param {CPUStatePDP10} cpu\n * @param {DebuggerPDP10} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cmp = cmp;\n this.cpu = cpu;\n this.panel = cmp.panel;\n this.nBusWidth = bus.getWidth();\n\n /*\n * Override the Debugger's message configuration if specified.\n */\n var sMessages = /** @type {string|undefined} */ (cmp.getMachineParm('messages'));\n if (sMessages) this.messageInit(sMessages);\n\n /*\n * Override the Debugger's initialization commands if specified.\n */\n var sCommands = /** @type {string|undefined} */ (cmp.getMachineParm('commands'));\n if (sCommands) this.sInitCommands = sCommands;\n\n /*\n * Update aOpReserved as appropriate for the current model\n */\n\n this.messageDump(MessagesPDP10.BUS, function onDumpBus(asArgs) { dbg.dumpBus(asArgs); });\n\n this.setReady();\n }\n\n /**\n * setBinding(sType, sBinding, control, sValue)\n *\n * @this {DebuggerPDP10}\n * @param {string|null} sType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"debugInput\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sType, sBinding, control, sValue)\n {\n var dbg = this;\n switch (sBinding) {\n\n case \"debugInput\":\n this.bindings[sBinding] = control;\n this.controlDebug = /** @type {HTMLInputElement} */ (control);\n /*\n * For halted machines, this is fine, but for auto-start machines, it can be annoying.\n *\n * control.focus();\n */\n control.onkeydown = function onKeyDownDebugInput(event) {\n var sCmd;\n if (event.keyCode == Keys.KEYCODE.CR) {\n sCmd = dbg.controlDebug.value;\n dbg.controlDebug.value = \"\";\n dbg.doCommands(sCmd, true);\n }\n else if (event.keyCode == Keys.KEYCODE.ESC) {\n dbg.controlDebug.value = sCmd = \"\";\n }\n else {\n if (event.keyCode == Keys.KEYCODE.UP) {\n sCmd = dbg.getPrevCommand();\n }\n else if (event.keyCode == Keys.KEYCODE.DOWN) {\n sCmd = dbg.getNextCommand();\n }\n if (sCmd != null) {\n var cch = sCmd.length;\n dbg.controlDebug.value = sCmd;\n dbg.controlDebug.setSelectionRange(cch, cch);\n }\n }\n if (sCmd != null && event.preventDefault) event.preventDefault();\n };\n return true;\n\n case \"debugEnter\":\n this.bindings[sBinding] = control;\n Web.onClickRepeat(\n control,\n 500, 100,\n function onClickDebugEnter(fRepeat) {\n if (dbg.controlDebug) {\n var sCmd = dbg.controlDebug.value;\n dbg.controlDebug.value = \"\";\n dbg.doCommands(sCmd, true);\n return true;\n }\n if (DEBUG) dbg.log(\"no debugger input buffer\");\n return false;\n }\n );\n return true;\n\n case \"step\":\n this.bindings[sBinding] = control;\n Web.onClickRepeat(\n control,\n 500, 100,\n function onClickStep(fRepeat) {\n var fCompleted = false;\n if (!dbg.isBusy(true)) {\n dbg.setBusy(true);\n fCompleted = dbg.stepCPU(fRepeat? 1 : 0, null);\n dbg.setBusy(false);\n }\n return fCompleted;\n }\n );\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * setFocus(fScroll)\n *\n * @this {DebuggerPDP10}\n * @param {boolean} [fScroll] (true if you really want the control scrolled into view)\n */\n setFocus(fScroll)\n {\n if (this.controlDebug) {\n /*\n * This is the recommended work-around to prevent the browser from scrolling the focused element\n * into view. The CPU is not a visual component, so when the CPU wants to set focus, the primary intent\n * is to ensure that keyboard input is fielded properly.\n */\n var x = 0, y = 0;\n if (!fScroll && window) {\n x = window.scrollX;\n y = window.scrollY;\n }\n\n this.controlDebug.focus();\n\n if (!fScroll && window) {\n window.scrollTo(x, y);\n }\n }\n }\n\n /**\n * getWord(dbgAddr, inc)\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @param {number} [inc]\n * @return {number}\n */\n getWord(dbgAddr, inc)\n {\n var w = PDP10.WORD_INVALID;\n var addr = this.getAddr(dbgAddr, false);\n if (addr !== PDP10.ADDR_INVALID) {\n w = this.bus.getWordDirect(addr);\n if (inc) this.incAddr(dbgAddr, inc);\n }\n return w;\n }\n\n /**\n * setWord(dbgAddr, w, inc)\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @param {number} w\n * @param {number} [inc]\n */\n setWord(dbgAddr, w, inc)\n {\n var addr = this.getAddr(dbgAddr, true);\n if (addr !== PDP10.ADDR_INVALID) {\n this.bus.setWordDirect(addr, w);\n if (inc) this.incAddr(dbgAddr, inc);\n this.cmp.updateDisplays(-1);\n }\n }\n\n /**\n * evalMUL(dst, src)\n *\n * Overrides the standard multiplication function with one that honors PDP-10 semantics and precision.\n *\n * @this {DebuggerPDP10}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst * src)\n */\n evalMUL(dst, src)\n {\n /*\n * The CPU requires that all 36-bit inputs/outputs be UNSIGNED, whereas our expression evaluator allows signed\n * inputs/outputs. So we perform two's complement conversions on all inputs/outputs as needed.\n */\n if (dst < 0) dst += PDP10.WORD_LIMIT;\n if (src < 0) src += PDP10.WORD_LIMIT;\n var result = PDP10.doMUL.call(this.cpu, dst, src, false, true);\n if (result >= PDP10.INT_LIMIT) result -= PDP10.WORD_LIMIT;\n if (MAXDEBUG) {\n var resultJS = this.truncate(dst * src);\n if (resultJS !== result) {\n var sReference = this.macro10? (\" @\" + this.toStrBase(this.macro10.nLocation)) : \"\";\n var sResults = \"PDP-10: \" + this.toStrBase(result, 36) + \" JavaScript: \" + this.toStrBase(resultJS, 36);\n this.println(\"MUL(\" + this.toStrBase(dst, 36) + \",\" + this.toStrBase(src, 36) + \") \" + sResults + sReference);\n }\n }\n return result;\n }\n\n /**\n * parseAddr(sAddr, dbgAddr)\n *\n * Address evaluation and validation (eg, range checks) are no longer performed at this stage. That's\n * done later, by getAddr(), which returns PDP10.ADDR_INVALID for invalid segments, out-of-range offsets,\n * etc. The Debugger's low-level get/set memory functions verify all getAddr() results, but even if an\n * invalid address is passed through to the Bus memory interfaces, the address will simply be masked with\n * bus.nBusMask; in the case of PDP10.ADDR_INVALID, that will generally refer to the top of the physical\n * address space.\n *\n * @this {DebuggerPDP10}\n * @param {string|undefined} sAddr\n * @param {DbgAddrPDP10} [dbgAddr]\n * @return {DbgAddrPDP10}\n */\n parseAddr(sAddr, dbgAddr)\n {\n var fPhysical, nBase;\n if (!dbgAddr) dbgAddr = this.newAddr();\n var addr = dbgAddr.addr;\n if (sAddr !== undefined) {\n sAddr = this.parseReference(sAddr);\n var ch = sAddr.charAt(0);\n if (ch == '%') {\n fPhysical = true;\n sAddr = sAddr.substr(1);\n }\n var dbgAddrTmp = this.findSymbolAddr(sAddr);\n if (dbgAddrTmp) return dbgAddrTmp;\n if (sAddr.indexOf(\"0x\") >= 0) {\n nBase = 16\n } else if (sAddr.indexOf(\"0o\") >= 0) {\n nBase = 8;\n } else if (sAddr.indexOf('.') >= 0) {\n nBase = 10;\n }\n addr = this.parseExpression(sAddr);\n }\n if (addr != null) {\n addr = this.validateWord(addr, this.nBusWidth);\n this.setAddr(dbgAddr, addr, fPhysical, nBase);\n }\n return dbgAddr;\n }\n\n /**\n * parseAddrOptions(dbdAddr, sOptions)\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @param {string} [sOptions]\n */\n parseAddrOptions(dbgAddr, sOptions)\n {\n if (sOptions) {\n var a = sOptions.match(/(['\"])(.*?)\\1/);\n if (a) {\n dbgAddr.aCmds = this.parseCommand(dbgAddr.sCmd = a[2]);\n }\n }\n }\n\n /**\n * validateWord(w, bits)\n *\n * @this {DebuggerPDP10}\n * @param {number} w\n * @param {number} [bits]\n * @return {number}\n */\n validateWord(w, bits = 36)\n {\n /*\n * Although it's expected that most callers will supply unsigned 36-bit values, we're nice about\n * converting any signed values to their unsigned (two's complement) counterpart, provided they are\n * within the acceptable range. Any values outside that range will be dealt with afterward.\n */\n if (w < 0 && w >= -PDP10.INT_LIMIT) {\n w += PDP10.WORD_LIMIT;\n }\n var value = Math.trunc(Math.abs(w)) % Math.pow(2, bits);\n if (DEBUG && w !== value) {\n this.println(\"validateWord(\" + Str.toOct(w) + \"): out of range, truncated to \" + Str.toOct(value));\n }\n return value;\n }\n\n /**\n * incAddr(dbgAddr, inc)\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @param {number} [inc] contains value to increment dbgAddr by (default is 1)\n */\n incAddr(dbgAddr, inc)\n {\n if (dbgAddr.addr != null) {\n dbgAddr.addr += (inc || 1);\n }\n }\n\n /**\n * toStrOffset(off)\n *\n * @this {DebuggerPDP10}\n * @param {number|null|undefined} [off]\n * @return {string} default base representation of off\n */\n toStrOffset(off)\n {\n return this.toStrBase(off, 18);\n }\n\n /**\n * toStrAddr(dbgAddr)\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @return {string} default base representation of the address\n */\n toStrAddr(dbgAddr)\n {\n return this.toStrOffset(dbgAddr.addr);\n }\n\n /**\n * toStrWord(w)\n *\n * @this {DebuggerPDP10}\n * @param {number} w (up to, but not including, WORD_LIMIT)\n * @return {string} octal representation of the 36-bit word, as two 18-bit values\n */\n toStrWord(w)\n {\n /*\n * ADDR_LIMIT is not derived from WORD_LIMIT; we're just taking advantage of the fact\n * that ADDR_LIMIT happens to be exactly half of WORD_LIMIT, and they are both powers of two.\n */\n return this.toStrBase(w / PDP10.ADDR_LIMIT, 18) + ' ' + this.toStrBase(w % PDP10.ADDR_LIMIT, 18);\n }\n\n /**\n * dumpBlocks(aBlocks, sAddr)\n *\n * @this {DebuggerPDP10}\n * @param {Array} aBlocks\n * @param {string} [sAddr] (optional block address)\n */\n dumpBlocks(aBlocks, sAddr)\n {\n var addr = 0, i = 0, n = aBlocks.length;\n\n if (sAddr) {\n addr = this.getAddr(this.parseAddr(sAddr, this.dbgAddrData));\n if (addr === PDP10.ADDR_INVALID) {\n this.println(\"invalid address: \" + sAddr);\n return;\n }\n i = addr >>> this.bus.nBlockShift;\n n = 1;\n }\n\n this.println(\"blockid physical blockaddr used size type\");\n this.println(\"-------- --------- --------- ------ ------ ----\");\n\n var typePrev = -1, cPrev = 0;\n while (n--) {\n var block = aBlocks[i];\n if (block.type == typePrev) {\n if (!cPrev++) this.println(\"...\");\n } else {\n typePrev = block.type;\n var sType = MemoryPDP10.TYPE_NAMES[typePrev];\n if (block) {\n this.println(Str.toHex(block.id, 8) + \" %\" + Str.toHex(i << this.bus.nBlockShift, 8) + \" %\" + Str.toHex(block.addr, 8) + \" \" + Str.toHexWord(block.used) + \" \" + Str.toHexWord(block.size) + \" \" + sType);\n }\n if (typePrev != MemoryPDP10.TYPE.NONE) typePrev = -1;\n cPrev = 0;\n }\n addr += this.bus.nBlockSize;\n i++;\n }\n }\n\n /**\n * dumpBus(asArgs)\n *\n * Dumps Bus allocations.\n *\n * @this {DebuggerPDP10}\n * @param {Array.<string>} asArgs (asArgs[0] is an optional block address)\n */\n dumpBus(asArgs)\n {\n this.dumpBlocks(this.bus.aBusBlocks, asArgs[0]);\n }\n\n /**\n * dumpHistory(sPrev, sLines)\n *\n * If sLines is not a number, it can be a instruction filter. However, for the moment, the only\n * supported filter is \"call\", which filters the history buffer for all CALL and RET instructions\n * from the specified previous point forward.\n *\n * @this {DebuggerPDP10}\n * @param {string} [sPrev] is a (decimal) number of instructions to rewind to (default is 10)\n * @param {string} [sLines] is a (decimal) number of instructions to print (default is, again, 10)\n */\n dumpHistory(sPrev, sLines)\n {\n var sMore = \"\";\n var cHistory = 0;\n var iHistory = this.iInstructionHistory;\n var aHistory = this.aInstructionHistory;\n\n if (aHistory.length) {\n var nPrev = +sPrev || this.nextHistory;\n var nLines = +sLines || 10;\n\n if (isNaN(nPrev)) {\n nPrev = nLines;\n } else {\n sMore = \"more \";\n }\n\n if (nPrev > aHistory.length) {\n this.println(\"note: only \" + aHistory.length + \" available\");\n nPrev = aHistory.length;\n }\n\n iHistory -= nPrev;\n if (iHistory < 0) {\n /*\n * If the dbgAddr of the last aHistory element contains a valid selector, wrap around.\n */\n if (aHistory[aHistory.length - 1].addr == null) {\n nPrev = iHistory + nPrev;\n iHistory = 0;\n } else {\n iHistory += aHistory.length;\n }\n }\n\n var aFilters = [];\n if (sLines == \"call\") {\n nLines = 100000;\n aFilters = [\"CALL\"];\n }\n\n if (sPrev !== undefined) {\n this.println(nPrev + \" instructions earlier:\");\n }\n\n /*\n * TODO: The following is necessary to prevent dumpHistory() from causing additional (or worse, recursive)\n * faults due to segmented addresses that are no longer valid, but the only alternative is to dramatically\n * increase the amount of memory used to store instruction history (eg, storing copies of all the instruction\n * bytes alongside the execution addresses).\n *\n * For now, we're living dangerously, so that our history dumps actually work.\n *\n * this.nSuppressBreaks++;\n *\n * If you re-enable this protection, be sure to re-enable the decrement below, too.\n */\n while (nLines > 0 && iHistory != this.iInstructionHistory) {\n\n var dbgAddr = aHistory[iHistory++];\n if (dbgAddr.addr == null) break;\n\n /*\n * We must create a new dbgAddr from the address in aHistory, because dbgAddr was\n * a reference, not a copy, and we don't want getInstruction() modifying the original.\n */\n var dbgAddrNew = this.newAddr(dbgAddr.addr);\n\n var sComment = \"history\";\n var nSequence = nPrev--;\n\n /*\n * TODO: Need to some UI to control whether cycle counts are displayed as part of the history.\n * It's currently disabled in checkInstruction(), so it's disable here, too.\n *\n if (DEBUG && dbgAddr.cycleCount != null) {\n sComment = \"cycles\";\n nSequence = dbgAddr.cycleCount;\n }\n */\n\n var sInstruction = this.getInstruction(dbgAddrNew, sComment, nSequence);\n\n if (!aFilters.length || sInstruction.indexOf(aFilters[0]) >= 0) {\n this.println(sInstruction);\n }\n\n /*\n * If there were OPERAND or ADDRESS overrides on the previous instruction, getInstruction()\n * will have automatically disassembled additional bytes, so skip additional history entries.\n */\n if (dbgAddrNew.cOverrides) {\n iHistory += dbgAddrNew.cOverrides; nLines -= dbgAddrNew.cOverrides; nPrev -= dbgAddrNew.cOverrides;\n }\n\n if (iHistory >= aHistory.length) iHistory = 0;\n this.nextHistory = nPrev;\n cHistory++;\n nLines--;\n }\n /*\n * See comments above.\n *\n * this.nSuppressBreaks--;\n */\n }\n\n if (!cHistory) {\n this.println(\"no \" + sMore + \"history available\");\n this.nextHistory = undefined;\n }\n }\n\n /**\n * messageInit(sEnable)\n *\n * @this {DebuggerPDP10}\n * @param {string|undefined} sEnable contains zero or more message categories to enable, separated by '|'\n */\n messageInit(sEnable)\n {\n this.dbg = this;\n this.bitsMessage = this.bitsWarning = MessagesPDP10.FAULT | MessagesPDP10.WARN;\n this.sMessagePrev = null;\n this.aMessageBuffer = [];\n /*\n * Internally, we use \"key\" instead of \"keys\", since the latter is a method on JavasScript objects,\n * but externally, we allow the user to specify \"keys\"; \"kbd\" is also allowed as shorthand for \"keyboard\".\n */\n var aEnable = this.parseCommand(sEnable.replace(\"keys\",\"key\").replace(\"kbd\",\"keyboard\"), false, '|');\n if (aEnable.length) {\n for (var m in MessagesPDP10.CATEGORIES) {\n if (Usr.indexOf(aEnable, m) >= 0) {\n this.bitsMessage |= MessagesPDP10.CATEGORIES[m];\n this.println(m + \" messages enabled\");\n }\n }\n }\n }\n\n /**\n * messageDump(bitMessage, fnDumper)\n *\n * @this {DebuggerPDP10}\n * @param {number} bitMessage is one Messages category flag\n * @param {function(Array.<string>)} fnDumper is a function the Debugger can use to dump data for that category\n * @return {boolean} true if successfully registered, false if not\n */\n messageDump(bitMessage, fnDumper)\n {\n for (var m in MessagesPDP10.CATEGORIES) {\n if (bitMessage == MessagesPDP10.CATEGORIES[m]) {\n this.afnDumpers[m] = fnDumper;\n return true;\n }\n }\n return false;\n }\n\n /**\n * getRegIndex(sReg, off)\n *\n * @this {DebuggerPDP10}\n * @param {string} sReg\n * @param {number} [off] optional offset into sReg\n * @return {number} register index, or -1 if not found\n */\n getRegIndex(sReg, off)\n {\n return DebuggerPDP10.REGNAMES.indexOf(sReg.toUpperCase());\n }\n\n /**\n * getRegName(iReg)\n *\n * @this {DebuggerPDP10}\n * @param {number} iReg (0-7; not used for other registers)\n * @return {string}\n */\n getRegName(iReg)\n {\n return DebuggerPDP10.REGNAMES[iReg] || \"\";\n }\n\n /**\n * getRegValue(iReg)\n *\n * @this {DebuggerPDP10}\n * @param {number} iReg\n * @return {number|undefined}\n */\n getRegValue(iReg)\n {\n var value;\n var cpu = this.cpu;\n switch(iReg) {\n case DebuggerPDP10.REGS.PC:\n value = cpu.getPC();\n break;\n case DebuggerPDP10.REGS.RA:\n value = cpu.regRA;\n break;\n case DebuggerPDP10.REGS.EA:\n value = cpu.regEA;\n break;\n case DebuggerPDP10.REGS.PS:\n value = cpu.getPS();\n break;\n case DebuggerPDP10.REGS.OV:\n value = (cpu.regPS & PDP10.PSFLAG.AROV)? 1 : 0;\n break;\n case DebuggerPDP10.REGS.C0:\n value = (cpu.regPS & PDP10.PSFLAG.CRY0)? 1 : 0;\n break;\n case DebuggerPDP10.REGS.C1:\n value = (cpu.regPS & PDP10.PSFLAG.CRY1)? 1 : 0;\n break;\n case DebuggerPDP10.REGS.BI:\n value = (cpu.regPS & PDP10.PSFLAG.BIS)? 1 : 0;\n break;\n case DebuggerPDP10.REGS.ND:\n value = (cpu.regPS & PDP10.PSFLAG.DCK)? 1 : 0;\n break;\n case DebuggerPDP10.REGS.PD:\n value = (cpu.regPS & PDP10.PSFLAG.PDOV)? 1 : 0;\n break;\n }\n return value;\n }\n\n /**\n * setRegValue(iReg, value)\n *\n * @this {DebuggerPDP10}\n * @param {number} iReg\n * @param {number} value\n */\n setRegValue(iReg, value)\n {\n var flag = 0;\n var cpu = this.cpu;\n\n switch(iReg) {\n case DebuggerPDP10.REGS.PC:\n cpu.setPC(value);\n this.setAddr(this.dbgAddrCode, cpu.getPC());\n break;\n case DebuggerPDP10.REGS.PS:\n cpu.setPS(value);\n break;\n case DebuggerPDP10.REGS.OV:\n flag = PDP10.PSFLAG.AROV;\n break;\n case DebuggerPDP10.REGS.C0:\n flag = PDP10.PSFLAG.CRY0;\n break;\n case DebuggerPDP10.REGS.C1:\n flag = PDP10.PSFLAG.CRY1;\n break;\n case DebuggerPDP10.REGS.BI:\n flag = PDP10.PSFLAG.BIS;\n break;\n case DebuggerPDP10.REGS.ND:\n flag = PDP10.PSFLAG.DCK;\n break;\n case DebuggerPDP10.REGS.PD:\n flag = PDP10.PSFLAG.PDOV;\n break;\n }\n if (flag) {\n if (value) {\n cpu.regPS |= flag;\n } else {\n cpu.regPS &= ~flag;\n }\n }\n }\n\n /**\n * replaceRegs(s)\n *\n * TODO: Implement or eliminate.\n *\n * @this {DebuggerPDP10}\n * @param {string} s\n * @return {string}\n */\n replaceRegs(s)\n {\n return s;\n }\n\n /**\n * message(sMessage, fAddress)\n *\n * @this {DebuggerPDP10}\n * @param {string} sMessage is any caller-defined message string\n * @param {boolean} [fAddress] is true to display the current address\n */\n message(sMessage, fAddress)\n {\n if (fAddress) {\n sMessage += \" @\" + this.toStrAddr(this.newAddr(this.cpu.getLastPC()));\n }\n\n if (this.sMessagePrev && sMessage == this.sMessagePrev) return;\n this.sMessagePrev = sMessage;\n\n if (this.bitsMessage & MessagesPDP10.BUFFER) {\n this.aMessageBuffer.push(sMessage);\n return;\n }\n\n var fRunning;\n if ((this.bitsMessage & MessagesPDP10.HALT) && this.cpu && (fRunning = this.cpu.isRunning()) || this.isBusy(true)) {\n this.stopCPU();\n if (fRunning) sMessage += \" (cpu halted)\";\n }\n\n this.println(sMessage); // + \" (\" + this.cpu.getCycles() + \" cycles)\"\n\n /*\n * We have no idea what the frequency of println() calls might be; all we know is that they easily\n * screw up the CPU's careful assumptions about cycles per burst. So we call yieldCPU() after every\n * message, to effectively end the current burst and start fresh.\n *\n * TODO: See CPUPDP10.calcStartTime() for a discussion of why we might want to call yieldCPU() *before*\n * we display the message.\n */\n if (this.cpu) this.cpu.yieldCPU();\n }\n\n /**\n * init()\n *\n * @this {DebuggerPDP10}\n * @param {boolean} [fAutoStart]\n */\n init(fAutoStart)\n {\n this.fInit = true;\n this.println(\"Type ? for help with PDPjs Debugger commands\");\n this.updateStatus();\n if (!fAutoStart) this.setFocus();\n if (this.sInitCommands) {\n var sCmds = this.sInitCommands;\n this.sInitCommands = null;\n this.doCommands(sCmds, true);\n }\n }\n\n /**\n * historyInit(fQuiet)\n *\n * This function is intended to be called by the constructor, reset(), addBreakpoint(), findBreakpoint()\n * and any other function that changes the checksEnabled() criteria used to decide whether checkInstruction()\n * should be called.\n *\n * That is, if the history arrays need to be allocated and haven't already been allocated, then allocate them,\n * and if the arrays are no longer needed, then deallocate them.\n *\n * @this {DebuggerPDP10}\n * @param {boolean} [fQuiet]\n */\n historyInit(fQuiet)\n {\n var i;\n if (!this.checksEnabled()) {\n if (this.aInstructionHistory && this.aInstructionHistory.length && !fQuiet) {\n this.println(\"instruction history buffer freed\");\n }\n this.iInstructionHistory = 0;\n this.aInstructionHistory = [];\n return;\n }\n if (!this.aInstructionHistory || !this.aInstructionHistory.length) {\n this.aInstructionHistory = new Array(DebuggerPDP10.HISTORY_LIMIT);\n for (i = 0; i < this.aInstructionHistory.length; i++) {\n /*\n * Preallocate dummy Addr (Array) objects in every history slot, so that\n * checkInstruction() doesn't need to call newAddr() on every slot update.\n */\n this.aInstructionHistory[i] = this.newAddr();\n }\n this.iInstructionHistory = 0;\n if (!fQuiet) {\n this.println(\"instruction history buffer allocated\");\n }\n }\n }\n\n /**\n * startCPU(fUpdateFocus, fQuiet)\n *\n * @this {DebuggerPDP10}\n * @param {boolean} [fUpdateFocus] is true to update focus\n * @param {boolean} [fQuiet]\n * @return {boolean} true if run request successful, false if not\n */\n startCPU(fUpdateFocus, fQuiet)\n {\n if (!this.checkCPU(fQuiet)) return false;\n this.cpu.startCPU(fUpdateFocus);\n return true;\n }\n\n /**\n * stepCPU(nCycles, fRegs, fUpdateDisplays)\n *\n * @this {DebuggerPDP10}\n * @param {number} nCycles (0 for one instruction without checking breakpoints)\n * @param {boolean|null} [fRegs] is true to display registers after step (default is false; use null for previous setting)\n * @param {boolean} [fUpdateDisplays] is false to disable Computer display updates (default is true)\n * @return {boolean}\n */\n stepCPU(nCycles, fRegs, fUpdateDisplays)\n {\n if (!this.checkCPU()) return false;\n\n var sCmd = \"\";\n if (fRegs === null) {\n fRegs = (!this.sCmdTracePrev || this.sCmdTracePrev == \"tr\");\n sCmd = fRegs? \"tr\" : \"t\";\n }\n\n this.nCycles = 0;\n\n if (!nCycles) {\n /*\n * When single-stepping, the CPU won't call checkInstruction(), which is good for\n * avoiding breakpoints, but bad for instruction data collection if checks are enabled.\n * So we call checkInstruction() ourselves.\n */\n if (this.checksEnabled()) this.checkInstruction(this.cpu.getPC(), 0);\n }\n /*\n * For our typically tiny bursts (usually single instructions), mimic what runCPU() does.\n */\n try {\n nCycles = this.cpu.getBurstCycles(nCycles);\n var nCyclesStep = this.cpu.stepCPU(nCycles);\n if (nCyclesStep > 0) {\n this.cpu.updateTimers(nCyclesStep);\n this.nCycles += nCyclesStep;\n this.cpu.addCycles(nCyclesStep, true);\n this.cpu.updateChecksum(nCyclesStep);\n this.cInstructions++;\n }\n }\n catch(exception) {\n /*\n * We assume that any numeric exception was explicitly thrown by the CPU to interrupt the\n * current instruction. For all other exceptions, we attempt a stack dump.\n */\n if (typeof exception != \"number\") {\n var e = exception;\n this.nCycles = 0;\n this.cpu.setError(e.stack || e.message);\n }\n }\n\n /*\n * Because we called cpu.stepCPU() and not cpu.startCPU(), we must nudge the Computer's update code,\n * and then update our own state. Normally, the only time fUpdateDisplays will be false is when doTrace()\n * is calling us in a loop, in which case it will perform its own updateDisplays() when it's done.\n */\n if (fUpdateDisplays !== false) {\n if (this.panel) this.panel.stop();\n this.cmp.updateDisplays(-1);\n }\n\n this.updateStatus(fRegs || false, sCmd);\n return (this.nCycles > 0);\n }\n\n /**\n * stopCPU()\n *\n * @this {DebuggerPDP10}\n * @param {boolean} [fComplete]\n */\n stopCPU(fComplete)\n {\n if (this.cpu) this.cpu.stopCPU(fComplete);\n }\n\n /**\n * updateStatus(fRegs, sCmd)\n *\n * @this {DebuggerPDP10}\n * @param {boolean} [fRegs] (default is true)\n * @param {string} [sCmd]\n */\n updateStatus(fRegs = true, sCmd)\n {\n if (!this.fInit) return;\n\n if (sCmd) {\n this.println(DebuggerPDP10.PROMPT + sCmd);\n }\n\n this.setAddr(this.dbgAddrCode, this.cpu.getPC());\n\n /*\n * this.nStep used to be a simple boolean, but now it's 0 (or undefined)\n * if inactive, 1 if stepping over an instruction without a register dump, or 2\n * if stepping over an instruction with a register dump.\n */\n if (!fRegs || this.nStep == 1) {\n this.doUnassemble();\n } else {\n this.doRegisters();\n }\n }\n\n /**\n * checkCPU(fQuiet)\n *\n * Make sure the CPU is ready (finished initializing), powered, not already running, and not in an error state.\n *\n * @this {DebuggerPDP10}\n * @param {boolean} [fQuiet]\n * @return {boolean}\n */\n checkCPU(fQuiet)\n {\n if (!this.cpu || !this.cpu.isReady() || !this.cpu.isPowered() || this.cpu.isRunning()) {\n if (!fQuiet) this.println(\"cpu busy or unavailable, command ignored\");\n return false;\n }\n return !this.cpu.isError();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {DebuggerPDP10}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n /*\n * Because Debugger save/restore support is somewhat limited (and didn't always exist),\n * we deviate from the typical save/restore design pattern: instead of reset OR restore,\n * we always reset and then perform a (potentially limited) restore.\n */\n this.reset(true);\n\n // this.println(data? \"resuming\" : \"powering up\");\n\n if (data) {\n return this.restore(data);\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {DebuggerPDP10}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean}\n */\n powerDown(fSave, fShutdown)\n {\n if (fShutdown) this.println(fSave? \"suspending\" : \"shutting down\");\n return fSave? this.save() : true;\n }\n\n /**\n * reset(fQuiet)\n *\n * This is a notification handler, called by the Computer, to inform us of a reset.\n *\n * @this {DebuggerPDP10}\n * @param {boolean} fQuiet (true only when called from our own powerUp handler)\n */\n reset(fQuiet)\n {\n this.historyInit();\n this.cInstructions = this.cInstructionsStart = 0;\n this.sMessagePrev = null;\n this.nCycles = 0;\n this.setAddr(this.dbgAddrCode, this.cpu.getPC());\n /*\n * fRunning is set by start() and cleared by stop(). In addition, we clear\n * it here, so that if the CPU is reset while running, we can prevent stop()\n * from unnecessarily dumping the CPU state.\n */\n this.flags.running = false;\n this.clearTempBreakpoint();\n if (!fQuiet) this.updateStatus();\n }\n\n /**\n * save()\n *\n * This implements (very rudimentary) save support for the Debugger component.\n *\n * @this {DebuggerPDP10}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.packAddr(this.dbgAddrCode));\n state.set(1, this.packAddr(this.dbgAddrData));\n state.set(2, this.packAddr(this.dbgAddrAssemble));\n state.set(3, [this.aPrevCmds, this.fAssemble, this.bitsMessage]);\n state.set(4, this.aSymbolTable);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements (very rudimentary) restore support for the Debugger component.\n *\n * @this {DebuggerPDP10}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var i = 0;\n if (data[3] !== undefined) {\n this.dbgAddrCode = this.unpackAddr(data[i++]);\n this.dbgAddrData = this.unpackAddr(data[i++]);\n this.dbgAddrAssemble = this.unpackAddr(data[i++]);\n this.aPrevCmds = data[i][0];\n if (typeof this.aPrevCmds == \"string\") this.aPrevCmds = [this.aPrevCmds];\n this.fAssemble = data[i][1];\n this.bitsMessage |= data[i][2]; // keep our current message bits set, and simply \"add\" any extra bits defined by the saved state\n }\n if (data[4]) this.aSymbolTable = data[4];\n return true;\n }\n\n /**\n * start(ms, nCycles)\n *\n * This is a notification handler, called by the Computer, to inform us the CPU has started.\n *\n * @this {DebuggerPDP10}\n * @param {number} ms\n * @param {number} nCycles\n */\n start(ms, nCycles)\n {\n if (!this.nStep) this.println(\"running\");\n this.flags.running = true;\n this.msStart = ms;\n this.nCyclesStart = nCycles;\n }\n\n /**\n * stop(ms, nCycles)\n *\n * This is a notification handler, called by the Computer, to inform us the CPU has now stopped.\n *\n * @this {DebuggerPDP10}\n * @param {number} ms\n * @param {number} nCycles\n */\n stop(ms, nCycles)\n {\n if (this.flags.running) {\n this.flags.running = false;\n this.nCycles = nCycles - this.nCyclesStart;\n if (!this.nStep) {\n var sStopped = \"stopped\";\n if (this.nCycles) {\n var msTotal = ms - this.msStart;\n var nCyclesPerSecond = (msTotal > 0? Math.round(this.nCycles * 1000 / msTotal) : 0);\n sStopped += \" (\";\n if (this.checksEnabled()) {\n sStopped += this.cInstructions + \" instructions, \";\n /*\n * $ops displays progress by calculating cInstructions - cInstructionsStart, so before\n * zeroing cInstructions, we should subtract cInstructions from cInstructionsStart (since\n * we're effectively subtracting cInstructions from cInstructions as well).\n */\n this.cInstructionsStart -= this.cInstructions;\n this.cInstructions = 0;\n }\n sStopped += this.nCycles + \" cycles, \" + msTotal + \" ms, \" + nCyclesPerSecond + \" hz)\";\n } else {\n if (this.messageEnabled(MessagesPDP10.HALT)) {\n /*\n * It's possible the user is trying to 'g' past a fault that was blocked by helpCheckFault()\n * for the Debugger's benefit; if so, it will continue to be blocked, so try displaying a helpful\n * message (another helpful tip would be to simply turn off the \"halt\" message category).\n */\n sStopped += \" (use the 't' command to execute blocked faults)\";\n }\n }\n this.println(sStopped);\n }\n this.updateStatus(true);\n this.setFocus();\n this.clearTempBreakpoint(this.cpu.getPC());\n this.sMessagePrev = null;\n }\n }\n\n /**\n * checksEnabled(fRelease)\n *\n * This \"check\" function is called by the CPU; we indicate whether or not every instruction needs to be checked.\n *\n * Originally, this returned true even when there were only read and/or write breakpoints, but those breakpoints\n * no longer require the intervention of checkInstruction(); the Bus component automatically swaps in/out appropriate\n * \"checked\" Memory access functions to deal with those breakpoints in the corresponding Memory blocks. So I've\n * simplified the test below.\n *\n * @this {DebuggerPDP10}\n * @param {boolean} [fRelease] is true for release criteria only; default is false (any criteria)\n * @return {boolean} true if every instruction needs to pass through checkInstruction(), false if not\n */\n checksEnabled(fRelease)\n {\n return ((DEBUG && !fRelease)? true : (this.aBreakExec.length > 1 || !!this.nBreakInstructions));\n }\n\n /**\n * checkInstruction(addr, nState)\n *\n * This \"check\" function is called by the CPU to inform us about the next instruction to be executed,\n * giving us an opportunity to look for \"exec\" breakpoints and update opcode instruction history.\n *\n * @this {DebuggerPDP10}\n * @param {number} addr\n * @param {number} nState is < 0 if stepping, 0 if starting, or > 0 if running\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkInstruction(addr, nState)\n {\n var opCode = -1;\n var cpu = this.cpu;\n\n /*\n * If opHalt() calls our stopInstruction() function, it will effectively rewind the PC back to the HALT,\n * purely for our debugging benefit, so we must compensate for that here by advancing the PC past the HALT\n * when the machine starts up again.\n */\n if (!nState) {\n opCode = this.cpu.readWord(addr);\n if ((opCode >> PDP10.OPCODE.A_SHIFT) == PDP10.OPCODE.HALT && this.cpu.getLastPC() == addr) {\n addr = this.cpu.advancePC(1);\n }\n }\n\n /*\n * If the CPU stopped on a breakpoint, we're not interested in stopping again if the machine is starting.\n */\n if (nState > 0) {\n if (this.nBreakInstructions) {\n if (!--this.nBreakInstructions) return true;\n }\n if (this.checkBreakpoint(addr, 1, this.aBreakExec)) {\n return true;\n }\n }\n\n /*\n * The rest of the instruction tracking logic can only be performed if historyInit() has allocated the\n * necessary data structures. Note that there is no explicit UI for enabling/disabling history, other than\n * adding/removing breakpoints, simply because it's breakpoints that trigger the call to checkInstruction();\n * well, OK, and a few other things now, like enabling MessagesPDP10.INT messages.\n */\n if (nState >= 0 && this.aInstructionHistory.length) {\n this.cInstructions++;\n if (opCode < 0) {\n opCode = this.cpu.readWord(addr);\n }\n if (opCode >= 0) {\n var dbgAddr = this.aInstructionHistory[this.iInstructionHistory];\n this.setAddr(dbgAddr, addr);\n // if (DEBUG) dbgAddr.cycleCount = cpu.getCycles();\n if (++this.iInstructionHistory == this.aInstructionHistory.length) this.iInstructionHistory = 0;\n }\n }\n return false;\n }\n\n /**\n * findInstruction(opCode, fOperands)\n *\n * @this {DebuggerPDP10}\n * @param {number} opCode\n * @param {boolean} [fOperands] (optional; default is true)\n * @return {string}\n */\n findInstruction(opCode, fOperands = true)\n {\n var opNum, opMask, aModes, iMode = 0;\n var op = (opCode / PDP10.OPCODE.OP_SCALE)|0;\n\n for (var mask in DebuggerPDP10.OPTABLE) {\n var opMasks = DebuggerPDP10.OPTABLE[mask];\n opNum = opMasks[op & mask];\n if (opNum) {\n opMask = +mask;\n /*\n * When we extracted op from opCode using OP_SCALE, we included 6 additional bits\n * to help distinguish OPIO instructions from non-OPIO instructions. But for the\n * following tests, we don't need those bits, so we get rid of them now.\n */\n op >>= 6;\n switch(opMask) {\n case PDP10.OPCODE.OPMODE:\n aModes = DebuggerPDP10.OPMODES;\n iMode = (op & 3);\n break;\n case PDP10.OPCODE.OPCOMP:\n aModes = DebuggerPDP10.OPCOMPS;\n iMode = (op & 7);\n break;\n case PDP10.OPCODE.OPTEST:\n aModes = DebuggerPDP10.OPTESTS;\n iMode = ((op & 0o60) >> 2) | ((op & 0o6) >> 1);\n break;\n }\n break;\n }\n }\n\n var sMode = aModes && aModes[iMode] || \"\";\n if (sMode == \"S\" && opNum > DebuggerPDP10.OPS.MOVM) sMode = \"B\";\n var sOperation = DebuggerPDP10.OPNAMES[opNum || 0] + sMode;\n\n if (!fOperands) {\n if (!opNum) sOperation = \"\";\n } else {\n if (!opNum) {\n sOperation = Str.pad(sOperation, 8) + this.toStrWord(opCode);\n } else {\n var n, sOperand;\n if (opMask == PDP10.OPCODE.OPIO) {\n n = (opCode / PDP10.OPCODE.IO_SCALE) & PDP10.OPCODE.IO_MASK;\n sOperand = this.toStrBase(n, -1);\n } else {\n n = (opCode >> PDP10.OPCODE.A_SHIFT) & PDP10.OPCODE.A_MASK;\n sOperand = this.toStrBase(n, -1);\n for (var m = 0; sOperand && m < DebuggerPDP10.ALTOPS.length; m++) {\n if (opNum == DebuggerPDP10.ALTOPS[m][0]) {\n var opAlt = DebuggerPDP10.ALTOPS[m][n];\n if (opAlt) {\n sOperation = DebuggerPDP10.OPNAMES[opAlt];\n sOperand = \"\";\n break;\n }\n }\n }\n }\n sOperation = Str.pad(sOperation, 8) + (sOperand? sOperand + ',' : \"\");\n if (opCode & PDP10.OPCODE.I_FIELD) sOperation += '@';\n sOperation += this.toStrBase(opCode & PDP10.OPCODE.Y_MASK, -1);\n var i = (opCode >> PDP10.OPCODE.X_SHIFT) & PDP10.OPCODE.X_MASK;\n if (i) sOperation += '(' + this.toStrBase(i, -1) + ')';\n }\n }\n return sOperation;\n }\n\n /**\n * getInstruction(dbgAddr, sComment, nSequence)\n *\n * Get the next instruction, by decoding the opcode and any operands.\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @param {string} [sComment] is an associated comment\n * @param {number|null} [nSequence] is an associated sequence number, undefined if none\n * @return {string} (and dbgAddr is updated to the next instruction)\n */\n getInstruction(dbgAddr, sComment, nSequence)\n {\n var dbgAddrOp = this.newAddr(dbgAddr.addr);\n var opCode = this.getWord(dbgAddr, 1);\n var sOperation = this.findInstruction(opCode);\n\n var sOpcodes = \"\";\n var sLine = this.toStrAddr(dbgAddrOp) + \":\";\n if (dbgAddrOp.addr !== PDP10.ADDR_INVALID && dbgAddr.addr !== PDP10.ADDR_INVALID) {\n do {\n var w = this.getWord(dbgAddrOp, 1);\n sOpcodes += ' ' + this.toStrWord(w);\n if (dbgAddrOp.addr == null) break;\n } while (dbgAddrOp.addr != dbgAddr.addr);\n }\n\n sLine += Str.pad(sOpcodes, 16) + sOperation;\n\n if (sComment) {\n sLine = Str.pad(sLine, 48) + ';' + (sComment || \"\");\n if (!this.cpu.flags.checksum) {\n sLine += (nSequence != null? '=' + nSequence.toString() : \"\");\n } else {\n var nCycles = this.cpu.getCycles();\n sLine += \"cycles=\" + nCycles.toString() + \" cs=\" + Str.toHex(this.cpu.nChecksum);\n }\n }\n return sLine;\n }\n\n /**\n * parseInstruction(sOpcode, sOperands, addr, aUndefined)\n *\n * @this {DebuggerPDP10}\n * @param {string} sOpcode\n * @param {string} [sOperands]\n * @param {number} [addr] of memory where this instruction is being assembled\n * @param {Array} [aUndefined]\n * @return {number} (opcode, or -1 if unrecognized instruction)\n */\n parseInstruction(sOpcode, sOperands, addr, aUndefined)\n {\n var opCode = -1;\n var opMask, opNum;\n\n if (!sOpcode) {\n /*\n * MACRO-10 also allows instructions to be assembled without an opcode (ie, just an address expression),\n * so if that's all we have, skip the opcode parsing.\n */\n if (sOperands) opCode = opMask = 0;\n }\n else {\n var sMnemonic = sOpcode.toUpperCase();\n /*\n * Perform any alternate mnemonic substitutions first\n */\n for (var m = 0; m < DebuggerPDP10.ALTOPS.length; m++) {\n for (var n in DebuggerPDP10.ALTOPS[m]) {\n if (!+n) continue;\n opNum = DebuggerPDP10.ALTOPS[m][n];\n if (sMnemonic == DebuggerPDP10.OPNAMES[opNum]) {\n sMnemonic = DebuggerPDP10.OPNAMES[DebuggerPDP10.ALTOPS[m][0]];\n if (sOperands) sOperands = this.toStrBase(+n) + ',' + sOperands;\n break;\n }\n }\n }\n for (var mask in DebuggerPDP10.OPTABLE) {\n\n var aModes;\n opMask = +mask;\n var opMasks = DebuggerPDP10.OPTABLE[mask];\n\n switch (opMask) {\n case PDP10.OPCODE.OPMODE:\n aModes = DebuggerPDP10.OPMODES;\n break;\n case PDP10.OPCODE.OPCOMP:\n aModes = DebuggerPDP10.OPCOMPS;\n break;\n case PDP10.OPCODE.OPTEST:\n aModes = DebuggerPDP10.OPTESTS;\n break;\n default:\n aModes = [\"\"];\n break;\n }\n var opMode = 0;\n for (var op in opMasks) {\n opNum = opMasks[op];\n for (var iMode = 0; iMode < aModes.length; iMode++) {\n\n var sMode = aModes[iMode];\n if (sMode == \"S\" && opNum > DebuggerPDP10.OPS.MOVM) sMode = \"B\";\n var sCandidate = DebuggerPDP10.OPNAMES[opNum] + sMode;\n\n if (sMnemonic == sCandidate) {\n if (opMask != PDP10.OPCODE.OPTEST) {\n opMode = iMode;\n } else {\n opMode = ((iMode & 0o3) << 1) | ((iMode & 0o14) << 2);\n }\n opCode = (op | (opMode << 6)) * PDP10.OPCODE.OP_SCALE;\n break;\n }\n }\n if (opCode >= 0) break;\n }\n if (opCode >= 0) break;\n }\n /*\n * MACRO-10 also allows instructions to be assembled without an opcode (ie, just an address expression),\n * so we'll give that a try next (as long as we're not mashing two symbols together).\n */\n if (opCode < 0 && (!sOperands || !sOperands.match(/^[0-9A-Z$%.?]/i))) {\n sOperands = sOpcode + sOperands;\n sOpcode = \"\";\n opCode = 0;\n }\n }\n\n if (opCode >= 0) {\n if (sOperands) {\n\n var aOperands = sOperands.split(',');\n if (aOperands.length > 2) {\n if (!aUndefined) this.println(\"too many operands: \" + sOperands);\n aOperands.length = 0;\n opCode = -1;\n }\n\n for (var i = 0; i < aOperands.length; i++) {\n\n var sOperand = aOperands[i].trim();\n if (!sOperand) continue;\n\n var match = sOperand.match(/(@?)([^(]*)\\(?([^)]*)\\)?/);\n if (!match) {\n if (!aUndefined) this.println(\"unknown operand: \" + sOperand);\n opCode = -1;\n break;\n }\n\n /*\n * If the operand contains an indirection operator (@) and/or index register (X), we parse those\n * first and update the indirect (I) bit and index (X) bits as appropriate. The order is important,\n * because if we parse them AFTER parsing the address expression, we might lose an undefined symbol\n * indication, and if the caller needs to handle address fixups, that would be bad.\n */\n if (match[1]) opCode += PDP10.OPCODE.I_FIELD;\n\n sOperand = match[3];\n if (sOperand) {\n operand = this.parseExpression(sOperand, aUndefined);\n if (operand == undefined) {\n opCode = -1;\n break;\n }\n /*\n * Here's a fun tidbit from the April 1978 MACRO-10 manual, p. 4-5:\n *\n * NOTE: To assemble the index, MACRO places the index register address in a fullword of storage,\n * swaps its halfwords, and then adds the swapped word to the instruction word.\n *\n * Which means that an instruction like this (where AC is zero):\n *\n * 8839 037653 205 00 0 00 400000 MOVSI AC,(1B<^O<AC>>) ;INITIALIZE AC\n *\n * produces an instruction that does NOT use indexing at all, even though it is coded as such. So my\n * simplistic masking of the index operand with PDP10.OPCODE.X_MASK, while logical, was completely wrong:\n *\n * if (operand < 0 || operand > PDP10.OPCODE.X_MASK) {\n * operand &= PDP10.OPCODE.X_MASK;\n * if (MAXDEBUG) this.println(\"index (\" + sOperand + \") truncated to \" + this.toStrBase(operand));\n * }\n * opCode += operand << PDP10.OPCODE.X_SHIFT;\n */\n operand = PDP10.SWAP(this.truncate(operand, 36, true));\n opCode += operand;\n }\n\n sOperand = match[2];\n if (i || aOperands.length == 1) {\n /*\n * If this is NOT the first operand, replace all periods NOT preceded by a digit with the current address.\n */\n if (!sOperand) {\n sOperand = \"0\";\n } else {\n sOperand = sOperand.replace(/(^|[^0-9])\\./g, \"$1\" + this.toStrOffset(addr));\n }\n }\n\n var operand = this.parseExpression(sOperand, aUndefined);\n if (operand == undefined) {\n opCode = -1;\n break;\n }\n\n if (!i && aOperands.length > 1) {\n if (opMask == PDP10.OPCODE.OPIO) {\n if (operand < 0 || operand > PDP10.OPCODE.IO_MASK) {\n operand &= PDP10.OPCODE.IO_MASK;\n if (MAXDEBUG) this.println(\"device code (\" + sOperand + \") truncated to \" + this.toStrBase(operand));\n }\n opCode += (operand * PDP10.OPCODE.IO_SCALE);\n }\n else {\n if (operand < 0 || operand > PDP10.OPCODE.A_MASK) {\n operand &= PDP10.OPCODE.A_MASK;\n if (MAXDEBUG) this.println(\"accumulator (\" + sOperand + \") truncated to \" + this.toStrBase(operand));\n }\n opCode += (operand << PDP10.OPCODE.A_SHIFT);\n }\n continue;\n }\n\n /*\n * I came across what I believe is a typo in the DEC \"DAKAC\" diagnostic:\n *\n * CAME [0,-1] ;PASS TEST IF C(AC)=0,,-1\n *\n * Based on the comment, it's clear what they really meant was either \"[0,,-1]\" or \"[XWD 0,-1]\".\n * However, they still got the desired result, which means when the assembler parses an mnemonic-less\n * instruction like \"0,-1\", it must truncate the second (address) operand.\n *\n * TODO: Determine if I should ALWAYS truncate. I'm trying to retain the flexibility of allowing\n * a full 36-bit instruction to be encoded with a single numeric expression (ie, one operand).\n */\n if (sOpcode || i) {\n if (operand < 0 || operand > PDP10.OPCODE.Y_MASK) {\n operand &= PDP10.ADDR_MASK;\n if (MAXDEBUG) this.println(\"address (\" + sOperand + \") truncated to \" + this.toStrBase(operand));\n }\n }\n opCode += operand;\n }\n }\n //\n // TODO: Complain about missing operands only if we know the instruction requires them.\n //\n // else {\n // this.println(\"missing operand(s)\");\n // opCode = -1;\n // }\n }\n\n if (opCode < 0 && !aUndefined) {\n this.println(\"unknown instruction: \" + sOpcode + ' ' + sOperands);\n }\n\n return opCode;\n }\n\n /**\n * stopInstruction(sMessage)\n *\n * TODO: Currently, the only way to prevent this call from stopping the CPU is when you're single-stepping.\n *\n * @this {DebuggerPDP10}\n * @param {string} [sMessage]\n * @return {boolean} true if stopping is enabled, false if not\n */\n stopInstruction(sMessage)\n {\n var cpu = this.cpu;\n if (cpu.isRunning()) {\n cpu.setPC(this.cpu.getLastPC());\n if (sMessage) this.println(sMessage);\n this.stopCPU();\n /*\n * TODO: Review the appropriate-ness of throwing a bogus vector number in order to immediately stop\n * the instruction. It's handy, but it also means that we no longer actually return true, so callers\n * of either stopInstruction() or undefinedInstruction() may have unreachable code paths.\n */\n throw -1;\n }\n return false;\n }\n\n /**\n * undefinedInstruction(opCode)\n *\n * @this {DebuggerPDP10}\n * @param {number} opCode\n * @return {boolean} true if stopping is enabled, false if not\n */\n undefinedInstruction(opCode)\n {\n if (this.messageEnabled(MessagesPDP10.CPU)) {\n this.printMessage(\"undefined opcode \" + this.toStrBase(opCode), true, true);\n return this.stopInstruction(); // allow the caller to step over it if they really want a trap generated\n }\n return false;\n }\n\n /**\n * checkMemoryRead(addr, nb)\n *\n * This \"check\" function is called by a Memory block to inform us that a memory read occurred, giving us an\n * opportunity to track the read if we want, and look for a matching \"read\" breakpoint, if any.\n *\n * In the \"old days\", it would be an error for this call to fail to find a matching Debugger breakpoint, but now\n * Memory blocks have no idea whether the Debugger or the machine's Debug register(s) triggered this \"checked\" read.\n *\n * If we return true, we \"trump\" the machine's Debug register(s); false allows normal Debug register processing.\n *\n * @this {DebuggerPDP10}\n * @param {number} addr\n * @param {number} [nb] (# of bytes; default is 1)\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkMemoryRead(addr, nb)\n {\n if (this.checkBreakpoint(addr, nb || 1, this.aBreakRead)) {\n this.stopCPU(false);\n return true;\n }\n return false;\n }\n\n /**\n * checkMemoryWrite(addr, nb)\n *\n * This \"check\" function is called by a Memory block to inform us that a memory write occurred, giving us an\n * opportunity to track the write if we want, and look for a matching \"write\" breakpoint, if any.\n *\n * In the \"old days\", it would be an error for this call to fail to find a matching Debugger breakpoint, but now\n * Memory blocks have no idea whether the Debugger or the machine's Debug register(s) triggered this \"checked\" write.\n *\n * If we return true, we \"trump\" the machine's Debug register(s); false allows normal Debug register processing.\n *\n * @this {DebuggerPDP10}\n * @param {number} addr\n * @param {number} [nb] (# of bytes; default is 1)\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkMemoryWrite(addr, nb)\n {\n if (this.checkBreakpoint(addr, nb || 1, this.aBreakWrite)) {\n this.stopCPU(false);\n return true;\n }\n return false;\n }\n\n /**\n * clearBreakpoints()\n *\n * @this {DebuggerPDP10}\n */\n clearBreakpoints()\n {\n var i, dbgAddr, addr;\n this.aBreakExec = [\"bp\"];\n if (this.aBreakRead !== undefined) {\n for (i = 1; i < this.aBreakRead.length; i++) {\n dbgAddr = this.aBreakRead[i];\n addr = this.getAddr(dbgAddr);\n this.bus.removeMemBreak(addr, false);\n }\n }\n this.aBreakRead = [\"br\"];\n if (this.aBreakWrite !== undefined) {\n for (i = 1; i < this.aBreakWrite.length; i++) {\n dbgAddr = this.aBreakWrite[i];\n addr = this.getAddr(dbgAddr);\n this.bus.removeMemBreak(addr, true);\n }\n }\n this.aBreakWrite = [\"bw\"];\n /*\n * nSuppressBreaks ensures we can't get into an infinite loop where a breakpoint lookup\n * requires reading memory that triggers more memory reads, which triggers more breakpoint checks.\n */\n this.nSuppressBreaks = 0;\n this.nBreakInstructions = 0;\n }\n\n /**\n * addBreakpoint(aBreak, dbgAddr, fTemporary)\n *\n * In case you haven't already figured this out, all our breakpoint commands use the address\n * to identify a breakpoint, not an incrementally assigned breakpoint index like other debuggers;\n * see doBreak() for details.\n *\n * This has a few implications, one being that you CANNOT set more than one kind of breakpoint\n * on a single address. In practice, that's rarely a problem, because you can almost always set\n * a different breakpoint on a neighboring address.\n *\n * Also, there is one exception to the \"one address, one breakpoint\" rule, and that involves\n * temporary breakpoints (ie, one-time execution breakpoints that either a \"p\" or \"g\" command\n * may create to step over a chunk of code). Those breakpoints automatically clear themselves,\n * so there usually isn't any need to refer to them using breakpoint commands.\n *\n * TODO: Consider supporting the more \"traditional\" breakpoint index syntax; the current\n * address-based syntax was implemented solely for expediency and consistency. At the same time,\n * also consider a more WDEB386-like syntax, where \"br\" is used to set a variety of access-specific\n * breakpoints, using modifiers like \"r1\", \"r2\", \"w1\", \"w2, etc.\n *\n * @this {DebuggerPDP10}\n * @param {Array} aBreak\n * @param {DbgAddrPDP10} dbgAddr\n * @param {boolean} [fTemporary]\n * @return {boolean} true if breakpoint added, false if already exists\n */\n addBreakpoint(aBreak, dbgAddr, fTemporary)\n {\n var fSuccess = true;\n\n // this.nSuppressBreaks++;\n\n /*\n * Instead of complaining that a breakpoint already exists (as we used to do), we now\n * allow breakpoints to be re-set; this makes it easier to update any commands that may\n * be associated with the breakpoint.\n *\n * The only exception: we DO allow a temporary breakpoint at an address where there may\n * already be a breakpoint, so that you can easily step (\"p\" or \"g\") over such addresses.\n */\n if (!fTemporary) {\n this.findBreakpoint(aBreak, dbgAddr, true, false, true);\n }\n\n if (aBreak != this.aBreakExec) {\n var addr = this.getAddr(dbgAddr);\n if (addr === PDP10.ADDR_INVALID) {\n this.println(\"invalid address: \" + this.toStrAddr(dbgAddr));\n fSuccess = false;\n } else {\n var fWrite = (aBreak == this.aBreakWrite);\n this.bus.addMemBreak(addr, fWrite);\n }\n }\n\n if (fSuccess) {\n aBreak.push(dbgAddr);\n if (fTemporary) {\n dbgAddr.fTemporary = true;\n }\n else {\n this.printBreakpoint(aBreak, aBreak.length-1, \"set\");\n this.historyInit();\n }\n }\n\n // this.nSuppressBreaks--;\n\n return fSuccess;\n }\n\n /**\n * findBreakpoint(aBreak, dbgAddr, fRemove, fTemporary, fQuiet)\n *\n * @this {DebuggerPDP10}\n * @param {Array} aBreak\n * @param {DbgAddrPDP10} dbgAddr\n * @param {boolean} [fRemove]\n * @param {boolean} [fTemporary]\n * @param {boolean} [fQuiet]\n * @return {boolean} true if found, false if not\n */\n findBreakpoint(aBreak, dbgAddr, fRemove, fTemporary, fQuiet)\n {\n var fFound = false;\n var addr = this.getAddr(dbgAddr);\n for (var i = 1; i < aBreak.length; i++) {\n var dbgAddrBreak = aBreak[i];\n if (addr == this.getAddr(dbgAddrBreak)) {\n if (!fTemporary || dbgAddrBreak.fTemporary) {\n fFound = true;\n if (fRemove) {\n if (!dbgAddrBreak.fTemporary && !fQuiet) {\n this.printBreakpoint(aBreak, i, \"cleared\");\n }\n aBreak.splice(i, 1);\n if (aBreak != this.aBreakExec) {\n var fWrite = (aBreak == this.aBreakWrite);\n this.bus.removeMemBreak(addr, fWrite);\n }\n /*\n * We'll mirror the logic in addBreakpoint() and leave the history buffer alone if this\n * was a temporary breakpoint.\n */\n if (!dbgAddrBreak.fTemporary) {\n this.historyInit();\n }\n break;\n }\n if (!fQuiet) this.printBreakpoint(aBreak, i, \"exists\");\n break;\n }\n }\n }\n return fFound;\n }\n\n /**\n * listBreakpoints(aBreak)\n *\n * @this {DebuggerPDP10}\n * @param {Array} aBreak\n * @return {number} of breakpoints listed, 0 if none\n */\n listBreakpoints(aBreak)\n {\n for (var i = 1; i < aBreak.length; i++) {\n this.printBreakpoint(aBreak, i);\n }\n return aBreak.length - 1;\n }\n\n /**\n * printBreakpoint(aBreak, i, sAction)\n *\n * @this {DebuggerPDP10}\n * @param {Array} aBreak\n * @param {number} i\n * @param {string} [sAction]\n */\n printBreakpoint(aBreak, i, sAction)\n {\n var dbgAddr = aBreak[i];\n this.println(aBreak[0] + ' ' + this.toStrAddr(dbgAddr) + (sAction? (' ' + sAction) : (dbgAddr.sCmd? (' \"' + dbgAddr.sCmd + '\"') : '')));\n }\n\n /**\n * setTempBreakpoint(dbgAddr)\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr of new temp breakpoint\n */\n setTempBreakpoint(dbgAddr)\n {\n this.addBreakpoint(this.aBreakExec, dbgAddr, true);\n }\n\n /**\n * clearTempBreakpoint(addr)\n *\n * @this {DebuggerPDP10}\n * @param {number|undefined} [addr] clear all temp breakpoints if no address specified\n */\n clearTempBreakpoint(addr)\n {\n if (addr !== undefined) {\n this.checkBreakpoint(addr, 1, this.aBreakExec, true);\n this.nStep = 0;\n } else {\n for (var i = 1; i < this.aBreakExec.length; i++) {\n var dbgAddrBreak = this.aBreakExec[i];\n if (dbgAddrBreak.fTemporary) {\n if (!this.findBreakpoint(this.aBreakExec, dbgAddrBreak, true, true)) break;\n i = 0;\n }\n }\n }\n }\n\n /**\n * checkBreakpoint(addr, nb, aBreak, fTemporary)\n *\n * @this {DebuggerPDP10}\n * @param {number} addr\n * @param {number} nb (# of bytes)\n * @param {Array} aBreak\n * @param {boolean} [fTemporary]\n * @return {boolean} true if breakpoint has been hit, false if not\n */\n checkBreakpoint(addr, nb, aBreak, fTemporary)\n {\n /*\n * Time to check for breakpoints; note that this should be done BEFORE updating history data\n * (see checkInstruction), since we might not actually execute the current instruction.\n */\n var fBreak = false;\n\n if (!this.nSuppressBreaks++) {\n\n for (var i = 1; !fBreak && i < aBreak.length; i++) {\n\n var dbgAddrBreak = aBreak[i];\n\n if (fTemporary && !dbgAddrBreak.fTemporary) continue;\n\n /*\n * If we're checking an execution address, which is always virtual, and virtual\n * addresses are always restricted to 16 bits, let's mask the breakpoint address to match\n * (the user should know better, but we'll be nice).\n */\n var addrBreak = this.getAddr(dbgAddrBreak) & (aBreak == this.aBreakExec? 0xffff : -1);\n for (var n = 0; n < nb; n++) {\n\n if ((addr + n) != addrBreak) continue;\n\n var a;\n fBreak = true;\n if (dbgAddrBreak.fTemporary) {\n this.findBreakpoint(aBreak, dbgAddrBreak, true, true);\n fTemporary = true;\n }\n if (a = dbgAddrBreak.aCmds) {\n /*\n * When one or more commands are attached to a breakpoint, we don't halt by default.\n * Instead, we set fBreak to true only if, at the completion of all the commands, the\n * CPU is halted; in other words, you should include \"h\" as one of the breakpoint commands\n * if you want the breakpoint to stop execution.\n *\n * Another useful command is \"if\", which will return false if the expression is false,\n * at which point we'll jump ahead to the next \"else\" command, and if there isn't an \"else\",\n * we abort.\n */\n fBreak = false;\n for (var j = 0; j < a.length; j++) {\n if (!this.doCommand(a[j], true)) {\n if (a[j].indexOf(\"if\")) {\n fBreak = true; // the failed command wasn't \"if\", so abort\n break;\n }\n var k = j + 1;\n for (; k < a.length; k++) {\n if (!a[k].indexOf(\"else\")) break;\n j++;\n }\n if (k == a.length) { // couldn't find an \"else\" after the \"if\", so abort\n fBreak = true;\n break;\n }\n /*\n * If we're still here, we'll execute the \"else\" command (which is just a no-op),\n * followed by any remaining commands.\n */\n }\n }\n if (!this.cpu.isRunning()) fBreak = true;\n }\n if (fBreak) {\n if (!fTemporary) this.printBreakpoint(aBreak, i, \"hit\");\n break;\n }\n }\n }\n }\n\n this.nSuppressBreaks--;\n\n return fBreak;\n }\n\n /**\n * getAccOutput(iAcc)\n *\n * @this {DebuggerPDP10}\n * @param {number} iAcc\n * @return {string}\n */\n getAccOutput(iAcc)\n {\n var sReg = Str.toOct(iAcc, 2);\n this.setAddr(this.dbgAddrAcc, iAcc);\n sReg += '=' + this.toStrBase(this.getWord(this.dbgAddrAcc), 36) + ' ';\n return sReg;\n }\n\n /**\n * getRegOutput(iReg)\n *\n * @this {DebuggerPDP10}\n * @param {number} iReg\n * @return {string}\n */\n getRegOutput(iReg)\n {\n var sReg = this.getRegName(iReg);\n if (sReg) {\n var nBits = (iReg >= DebuggerPDP10.REGS.OV? 1 : (iReg == DebuggerPDP10.REGS.RA? 23 : 18));\n sReg += '=' + this.toStrBase(this.getRegValue(iReg), nBits) + ' ';\n }\n return sReg;\n }\n\n /**\n * getMiscDump()\n *\n * @this {DebuggerPDP10}\n * @return {string}\n */\n getMiscDump()\n {\n var sDump = \"\";\n for (var i = 0; i < DebuggerPDP10.REGNAMES.length; i++) {\n sDump += this.getRegOutput(i);\n }\n return sDump;\n }\n\n /**\n * getRegDump(fMisc)\n *\n * For now, fMisc defaults to true, providing a full register dump by default.\n *\n * @this {DebuggerPDP10}\n * @param {boolean|undefined} [fMisc] (true to include misc registers)\n * @return {string}\n */\n getRegDump(fMisc = true)\n {\n var sDump = \"\";\n for (var i = 0; i < 16; i++) {\n if (i && !(i & 3)) sDump += '\\n';\n sDump += this.getAccOutput(i);\n }\n if (fMisc) sDump += '\\n' + this.getMiscDump();\n return sDump;\n }\n\n /**\n * comparePairs(p1, p2)\n *\n * @this {DebuggerPDP10}\n * @param {number|string|Array|Object} p1\n * @param {number|string|Array|Object} p2\n * @return {number}\n */\n comparePairs(p1, p2)\n {\n return p1[0] > p2[0]? 1 : p1[0] < p2[0]? -1 : 0;\n }\n\n /**\n * addSymbols(sModule, addr, len, aSymbols)\n *\n * As filedump.js (formerly convrom.php) explains, aSymbols is a JSON-encoded object whose properties consist\n * of all the symbols (in upper-case), and the values of those properties are objects containing any or all of\n * the following properties:\n *\n * 'v': the value of an absolute (unsized) value\n * 'b': either 1, 2, 4 or undefined if an unsized value\n * 's': either a hard-coded segment or undefined\n * 'o': the offset of the symbol within the associated address space\n * 'l': the original-case version of the symbol, present only if it wasn't originally upper-case\n * 'a': annotation for the specified offset; eg, the original assembly language, with optional comment\n *\n * To that list of properties, we also add:\n *\n * 'p': the physical address (calculated whenever both 's' and 'o' properties are defined)\n *\n * Note that values for any 'v', 'b', 's' and 'o' properties are unquoted decimal values, and the values\n * for any 'l' or 'a' properties are quoted strings. Also, if double-quotes were used in any of the original\n * annotation ('a') values, they will have been converted to two single-quotes, so we're responsible for\n * converting them back to individual double-quotes.\n *\n * For example:\n * {\n * 'HF_PORT': {\n * 'v':800\n * },\n * 'HDISK_INT': {\n * 'b':4, 's':0, 'o':52\n * },\n * 'ORG_VECTOR': {\n * 'b':4, 's':0, 'o':76\n * },\n * 'CMD_BLOCK': {\n * 'b':1, 's':64, 'o':66\n * },\n * 'DISK_SETUP': {\n * 'o':3\n * },\n * '.40': {\n * 'o':40, 'a':\"MOV AX,WORD PTR ORG_VECTOR ;GET DISKETTE VECTOR\"\n * }\n * }\n *\n * If a symbol only has an offset, then that offset value can be assigned to the symbol property directly:\n *\n * 'DISK_SETUP': 3\n *\n * The last property is an example of an \"anonymous\" entry, for offsets where there is no associated symbol.\n * Such entries are identified by a period followed by a unique number (usually the offset of the entry), and\n * they usually only contain offset ('o') and annotation ('a') properties. I could eliminate the leading\n * period, but it offers a very convenient way of quickly discriminating among genuine vs. anonymous symbols.\n *\n * We add all these entries to our internal symbol table, which is an array of 4-element arrays, each of which\n * look like:\n *\n * [addr, len, aSymbols, aOffsets]\n *\n * There are two basic symbol operations: findSymbol(), which takes an address and finds the symbol, if any,\n * at that address, and findSymbolAddr(), which takes a string and attempts to match it to a non-anonymous\n * symbol with a matching offset ('o') property.\n *\n * To implement findSymbol() efficiently, addSymbols() creates an array of [offset, sSymbol] pairs\n * (aOffsets), one pair for each symbol that corresponds to an offset within the specified address space.\n *\n * We guarantee the elements of aOffsets are in offset order, because we build it using binaryInsert();\n * it's quite likely that the MAP file already ordered all its symbols in offset order, but since they're\n * hand-edited files, we can't assume that, and we need to ensure that findSymbol()'s binarySearch() operates\n * properly.\n *\n * @this {DebuggerPDP10}\n * @param {string|null} sModule\n * @param {number|null} addr (physical address where the symbols are located, if the memory is physical; eg, ROM)\n * @param {number} len (the size of the region, in bytes)\n * @param {Object} aSymbols (collection of symbols in this group; the format of this collection is described below)\n */\n addSymbols(sModule, addr, len, aSymbols)\n {\n var dbgAddr = {};\n var aOffsets = [];\n for (var sSymbol in aSymbols) {\n var symbol = aSymbols[sSymbol];\n if (typeof symbol == \"number\") {\n aSymbols[sSymbol] = symbol = {'o': symbol};\n }\n var offSymbol = symbol['o'];\n var sAnnotation = symbol['a'];\n if (offSymbol !== undefined) {\n Usr.binaryInsert(aOffsets, [offSymbol >>> 0, sSymbol], this.comparePairs);\n }\n if (sAnnotation) symbol['a'] = sAnnotation.replace(/''/g, \"\\\"\");\n }\n var symbolTable = {\n sModule: sModule,\n addr: addr,\n len: len,\n aSymbols: aSymbols,\n aOffsets: aOffsets\n };\n this.aSymbolTable.push(symbolTable);\n }\n\n /**\n * dumpSymbols()\n *\n * TODO: Add \"numerical\" and \"alphabetical\" dump options. This is simply dumping them in whatever\n * order they appeared in the original MAP file.\n *\n * @this {DebuggerPDP10}\n */\n dumpSymbols()\n {\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n for (var sSymbol in symbolTable.aSymbols) {\n if (sSymbol.charAt(0) == '.') continue;\n var symbol = symbolTable.aSymbols[sSymbol];\n var offSymbol = symbol['o'];\n if (offSymbol === undefined) continue;\n var sSymbolOrig = symbolTable.aSymbols[sSymbol]['l'];\n if (sSymbolOrig) sSymbol = sSymbolOrig;\n this.println(this.toStrOffset(offSymbol) + ' ' + sSymbol);\n }\n }\n }\n\n /**\n * findSymbol(dbgAddr, fNearest)\n *\n * Search aSymbolTable for dbgAddr, and return an Array for the corresponding symbol (empty if not found).\n *\n * If fNearest is true, and no exact match was found, then the Array returned will contain TWO sets of\n * entries: [0]-[3] will refer to closest preceding symbol, and [4]-[7] will refer to the closest subsequent symbol.\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @param {boolean} [fNearest]\n * @return {Array} where [0] == symbol name, [1] == symbol value, [2] == any annotation, and [3] == any associated comment\n */\n findSymbol(dbgAddr, fNearest)\n {\n var aSymbol = [];\n var addrSymbol = this.getAddr(dbgAddr) >>> 0;\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n var addr = symbolTable.addr >>> 0;\n var len = symbolTable.len;\n if (addrSymbol >= addr && addrSymbol < addr + len) {\n var offSymbol = addrSymbol - addr;\n var result = Usr.binarySearch(symbolTable.aOffsets, [offSymbol], this.comparePairs);\n if (result >= 0) {\n this.returnSymbol(iTable, result, aSymbol);\n }\n else if (fNearest) {\n result = ~result;\n this.returnSymbol(iTable, result-1, aSymbol);\n this.returnSymbol(iTable, result, aSymbol);\n }\n break;\n }\n }\n return aSymbol;\n }\n\n /**\n * findSymbolAddr(sSymbol)\n *\n * Search our symbol tables for sSymbol, and if found, return a dbgAddr (same as parseAddr()).\n *\n * @this {DebuggerPDP10}\n * @param {string} sSymbol\n * @return {DbgAddrPDP10|undefined}\n */\n findSymbolAddr(sSymbol)\n {\n var dbgAddr, offSymbol;\n\n if (sSymbol.match(/^[a-z_][a-z0-9_]*$/i)) {\n var sUpperCase = sSymbol.toUpperCase();\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n var symbol = symbolTable.aSymbols[sUpperCase];\n if (symbol != null) {\n offSymbol = symbol['o'];\n /*\n * If the symbol matched but there's no 'o' offset (ie, it wasn't for an address), there's\n * no point looking any farther, since each symbol appears only once.\n *\n * NOTE: We assume that every ROM is ORG'ed at 0x0000, and therefore unless the symbol has an\n * explicitly-defined segment, we return the segment associated with the entire group; for a ROM,\n * that segment is normally \"addrROM >>> 4\". Down the road, we may want/need to support a special\n * symbol entry (eg, \".ORG\") that defines an alternate origin.\n */\n break;\n }\n }\n }\n if (offSymbol != null) {\n dbgAddr = this.newAddr(offSymbol);\n }\n return dbgAddr;\n }\n\n /**\n * loadImage(aWords, addrStart)\n *\n * @this {DebuggerPDP10}\n * @param {Array.<number>} aWords\n * @param {number|null|undefined} addrStart\n */\n loadImage(aWords, addrStart)\n {\n var bus = this.bus;\n var dbg = this.dbg;\n var nWords = 0, addrLo = null, addrHi = 0;\n aWords.forEach(function(w, addr) {\n bus.setWord(addr, w);\n if (addrLo == null) addrLo = addr;\n if (addr > addrHi) addrHi = addr;\n nWords++;\n });\n if (!nWords) {\n this.println(\"no data\");\n } else {\n var sStart = \"start address \";\n if (addrStart != null) {\n this.cpu.setPC(addrStart);\n sStart += this.toStrBase(addrStart);\n } else {\n sStart += \"unspecified\";\n }\n this.println(nWords + \" words loaded at \" + this.toStrBase(addrLo) + '-' + this.toStrBase(addrHi) + \", \" + sStart);\n this.updateStatus();\n }\n }\n\n /**\n * returnSymbol(iTable, iOffset, aSymbol)\n *\n * Helper function for findSymbol().\n *\n * @this {DebuggerPDP10}\n * @param {number} iTable\n * @param {number} iOffset\n * @param {Array} aSymbol is updated with the specified symbol, if it exists\n */\n returnSymbol(iTable, iOffset, aSymbol)\n {\n var symbol = {};\n var aOffsets = this.aSymbolTable[iTable].aOffsets;\n var offset = 0, sSymbol = null;\n if (iOffset >= 0 && iOffset < aOffsets.length) {\n offset = aOffsets[iOffset][0];\n sSymbol = aOffsets[iOffset][1];\n }\n if (sSymbol) {\n symbol = this.aSymbolTable[iTable].aSymbols[sSymbol];\n sSymbol = (sSymbol.charAt(0) == '.'? null : (symbol['l'] || sSymbol));\n }\n aSymbol.push(sSymbol);\n aSymbol.push(offset);\n aSymbol.push(symbol['a']);\n aSymbol.push(symbol['c']);\n }\n\n /**\n * doHelp()\n *\n * @this {DebuggerPDP10}\n */\n doHelp()\n {\n var s = \"commands:\";\n for (var sCommand in DebuggerPDP10.COMMANDS) {\n s += '\\n' + Str.pad(sCommand, 9) + DebuggerPDP10.COMMANDS[sCommand];\n }\n if (!this.checksEnabled()) s += \"\\nnote: history disabled if no exec breakpoints\";\n this.println(s);\n }\n\n /**\n * doAssemble(asArgs)\n *\n * This always receives the complete argument array, where the order of the arguments is:\n *\n * [0]: the assemble command (assumed to be \"a\")\n * [1]: the target address (eg, \"200\")\n * [2]: the opcode mnemonic (eg, \"hrli\")\n * [3]: the operands, if any\n *\n * The Debugger enters \"assemble mode\" whenever only the first (or first and second) arguments are present.\n * As long as \"assemble mode is active, the user can omit the first two arguments on all later assemble commands\n * until \"assemble mode\" is cancelled with an empty command line; the command processor automatically prepends \"a\"\n * and the next available target address to the argument array.\n *\n * Entering \"assemble mode\" is optional; one could enter a series of fully-qualified assemble commands; eg:\n *\n * a 100 hrli 1,111111\n * a 101 hrri 1,444444\n * ...\n *\n * without ever entering \"assemble mode\", but of course, that requires more typing and doesn't take advantage\n * of automatic target address advancement (see dbgAddrAssemble).\n *\n * When filename(s) or URL(s) are provided in lieu of an opcode, we pass those on to the Macro10 component for\n * assembling (multiple files must be separated by semicolons), along with any option letters that were included\n * with the \"a\" command; for example, if \"ap\" was specified, then \"p\" will be passed to Macro10 as an option.\n *\n * See the Macro10 component for a list of supported options.\n *\n * When assembling a file, the target address determines the initial location counter for the assembly process,\n * but that can always be overridden by a LOC (or RELOC) pseudo-op in the file. The target address will also be\n * used as the starting address unless that's overridden by an END pseudo-op. In the absence of a target address,\n * the location counter starts at zero, and the starting address defaults to the PC register.\n *\n * @this {DebuggerPDP10}\n * @param {Array.<string>} asArgs is the complete argument array, beginning with the \"a\" command in asArgs[0]\n * @return {boolean}\n */\n doAssemble(asArgs)\n {\n var sOptions = asArgs[0].substr(1);\n var sAddr = asArgs[1] && asArgs[1][0] >= '0' && asArgs[1][0] <= '9'? asArgs[1] : undefined;\n var sOpcode = sAddr? asArgs[2] : asArgs[1];\n var dbgAddr = this.parseAddr(sAddr, this.dbgAddrAssemble);\n\n if (!sOpcode) {\n this.println(\"begin assemble at \" + this.toStrAddr(dbgAddr));\n this.fAssemble = true;\n this.cmp.updateDisplays();\n return true;\n }\n\n var match = sOpcode.match(/^(['\"]?)(.*?)(\\.klm|\\.mac|\\.html|\\.txt|)\\1$/i);\n if (match && (match[1] || match[3])) {\n var dbg = this;\n var cpu = this.cpu;\n dbgAddr = this.parseAddr(sAddr);\n if (this.macro10) {\n dbg.println(\"assembly already in progress\");\n }\n else {\n var sFile = match[2] + match[3];\n if (!match[3]) sOptions += 's';\n var addrLoad = dbgAddr.addr;\n var macro10 = this.macro10 = new Macro10(dbg);\n macro10.assembleFiles(sFile, addrLoad, sOptions, function doneMacro10(nErrorCode, sURL) {\n if (!nErrorCode) {\n /*\n * NOTE: Most Debugger operations run in the context of doCommand(), which catches any exceptions;\n * however, this callback may be running in a different context (eg, a network request callback), so\n * better safe than sorry.\n */\n try {\n var addrStart = macro10.getStart();\n if (addrStart == null) addrStart = addrLoad;\n dbg.loadImage(macro10.getImage(), addrStart);\n } catch(e) {\n if (typeof e == \"number\") {\n nErrorCode = e || -1;\n } else {\n dbg.println(e.message);\n nErrorCode = -1; // fake error so that command processing stops\n }\n }\n }\n if (nErrorCode) {\n dbg.println(\"error (\" + nErrorCode + \") processing \" + (sURL || sFile));\n }\n dbg.macro10 = null;\n if (!nErrorCode) dbg.doCommands();\n });\n }\n return false;\n }\n\n asArgs.shift();\n asArgs.shift();\n asArgs.shift();\n var sOperands = asArgs.join(\"\");\n var opCode = this.parseInstruction(sOpcode, sOperands, dbgAddr.addr || 0);\n\n if (opCode >= 0) {\n this.setWord(dbgAddr, opCode);\n this.println(this.getInstruction(dbgAddr));\n }\n return true;\n }\n\n /**\n * doBreak(sCmd, sAddr, sOptions)\n *\n * As the \"help\" output below indicates, the following breakpoint commands are supported:\n *\n * bp # set exec breakpoint\n * br # set read breakpoint\n * bw # set write breakpoint\n * bc # clear breakpoint (* to clear all)\n * bl list all breakpoints\n * bn [#] break after # instruction(s)\n *\n * The \"bn\" command, like the \"dh\" command and all other commands that use an instruction count,\n * assumes a decimal value, regardless of the current base. Use \"bn\" without an argument to display\n * the break count, and use \"bn 0\" to clear the break count.\n *\n * @this {DebuggerPDP10}\n * @param {string} sCmd\n * @param {string|undefined} [sAddr]\n * @param {string} [sOptions] (the rest of the breakpoint command-line)\n */\n doBreak(sCmd, sAddr, sOptions)\n {\n if (sAddr == '?') {\n this.println(\"breakpoint commands:\");\n this.println(\"\\tbp #\\tset exec breakpoint\");\n this.println(\"\\tbr #\\tset read breakpoint\");\n this.println(\"\\tbw #\\tset write breakpoint\");\n this.println(\"\\tbc #\\tclear breakpoint (* to clear all)\");\n this.println(\"\\tbl\\tlist all breakpoints\");\n this.println(\"\\tbn [#]\\tbreak after # instruction(s)\");\n return;\n }\n\n var sParm = sCmd.charAt(1);\n if (sParm == 'l') {\n var cBreaks = 0;\n cBreaks += this.listBreakpoints(this.aBreakExec);\n cBreaks += this.listBreakpoints(this.aBreakRead);\n cBreaks += this.listBreakpoints(this.aBreakWrite);\n if (!cBreaks) this.println(\"no breakpoints\");\n return;\n }\n\n if (sParm == 'n') {\n var n = +sAddr || 0;\n if (sAddr) this.nBreakInstructions = n;\n this.println(\"break after \" + n + \" instruction(s)\");\n return;\n }\n\n if (sAddr === undefined) {\n this.println(\"missing breakpoint address\");\n return;\n }\n\n var dbgAddr = sAddr == '*'? this.newAddr() : this.parseAddr(sAddr, this.dbgAddrCode);\n\n if (sParm == 'c') {\n if (dbgAddr.addr == null) {\n this.clearBreakpoints();\n this.println(\"all breakpoints cleared\");\n return;\n }\n if (this.findBreakpoint(this.aBreakExec, dbgAddr, true))\n return;\n if (this.findBreakpoint(this.aBreakRead, dbgAddr, true))\n return;\n if (this.findBreakpoint(this.aBreakWrite, dbgAddr, true))\n return;\n this.println(\"breakpoint missing: \" + this.toStrAddr(dbgAddr));\n return;\n }\n\n if (dbgAddr.addr == null) return;\n\n this.parseAddrOptions(dbgAddr, sOptions);\n\n if (sParm == 'p') {\n this.addBreakpoint(this.aBreakExec, dbgAddr);\n return;\n }\n if (sParm == 'r') {\n this.addBreakpoint(this.aBreakRead, dbgAddr);\n return;\n }\n if (sParm == 'w') {\n this.addBreakpoint(this.aBreakWrite, dbgAddr);\n return;\n }\n this.println(\"unknown breakpoint command: \" + sParm);\n }\n\n /**\n * doClear(sCmd)\n *\n * @this {DebuggerPDP10}\n * @param {string} [sCmd] (eg, \"cls\" or \"clear\")\n */\n doClear(sCmd)\n {\n this.cmp.clearPanel();\n }\n\n /**\n * doDump(asArgs)\n *\n * @this {DebuggerPDP10}\n * @param {Array.<string>} asArgs (formerly sCmd, [sAddr], [sLen] and [sBytes])\n */\n doDump(asArgs)\n {\n var m;\n var sCmd = asArgs[0];\n var sAddr = asArgs[1];\n var sLen = asArgs[2];\n var sBytes = asArgs[3];\n\n if (sAddr == '?') {\n var sDumpers = \"\";\n for (m in MessagesPDP10.CATEGORIES) {\n if (this.afnDumpers[m]) {\n if (sDumpers) sDumpers += ',';\n sDumpers = sDumpers + m;\n }\n }\n sDumpers += \",state,symbols\";\n this.println(\"dump memory commands:\");\n this.println(\"\\tdw [a] [n] dump n words at address a\");\n this.println(\"\\tds [a] [n] dump n words at address a as JSON\");\n this.println(\"\\tdh [p] [n] dump n instructions from history position p\");\n if (sDumpers.length) this.println(\"dump extension commands:\\n\\t\" + sDumpers);\n return;\n }\n\n if (sAddr == \"state\") {\n var sState = this.cmp.powerOff(true);\n if (sLen == \"console\") {\n /*\n * Console buffers are notoriously small, and even the following code, which breaks the\n * data into parts (eg, \"d state console 1\", \"d state console 2\", etc) just isn't that helpful.\n *\n * var nPart = +sBytes;\n * if (nPart) sState = sState.substr(1000000 * (nPart-1), 1000000);\n *\n * So, the best way to capture a large machine state is to use the new \"Save Machine\" link\n * that downloads a machine's entire state. Alternatively, run your own local server and use\n * server-side storage. Take a look at the \"Save\" binding in computer.js, which binds an HTML\n * control to the computer.powerOff() and computer.saveServerState() functions.\n */\n console.log(sState);\n } else {\n this.doClear();\n if (sState) this.println(sState);\n }\n return;\n }\n\n if (sAddr == \"symbols\") {\n this.dumpSymbols();\n return;\n }\n\n if (sCmd == \"d\") {\n for (m in MessagesPDP10.CATEGORIES) {\n if (asArgs[1] == m) {\n var fnDumper = this.afnDumpers[m];\n if (fnDumper) {\n asArgs.shift();\n asArgs.shift();\n fnDumper(asArgs);\n } else {\n this.println(\"no dump registered for \" + sAddr);\n }\n return;\n }\n }\n if (!sAddr) sCmd = this.sCmdDumpPrev || \"dw\";\n } else {\n this.sCmdDumpPrev = sCmd;\n }\n\n if (sCmd == \"dh\") {\n this.dumpHistory(sAddr, sLen);\n return;\n }\n\n var len = 0;\n var fJSON = (sCmd == \"ds\");\n var dbgAddr = this.parseAddr(sAddr, this.dbgAddrData);\n\n if (sLen) {\n if (sLen.charAt(0) == 'l') {\n sLen = sLen.substr(1) || sBytes;\n len = this.parseValue(sLen);\n }\n else {\n var dbgAddrEnd = this.parseAddr(sLen);\n len = dbgAddrEnd.addr - dbgAddr.addr;\n }\n if (len < 0) len = 0;\n if (len > 0x10000) len = 0x10000;\n }\n\n var nBase = this.nBase;\n if (dbgAddr.nBase) this.nBase = dbgAddr.nBase;\n\n var size = (sCmd == \"db\"? 1 : 2);\n var nWords = len || 32;\n var nWordsPerLine = (size == 1? 1 : 4);\n var nLines = (((nWords + nWordsPerLine - 1) / nWordsPerLine)|0) || 1;\n\n var sDump = \"\";\n while (nLines-- && nWords > 0) {\n var sData = \"\", sChars = \"\";\n sAddr = this.toStrAddr(dbgAddr);\n var n = nWordsPerLine;\n while (n-- > 0 && nWords-- > 0) {\n var w = this.getWord(dbgAddr, 1);\n if (fJSON) {\n if (sData) sData += ',';\n sData += w;\n } else {\n sData += this.toStrWord(w);\n sData += ' ';\n }\n /*\n * TODO: Provide some UI for choosing whether to dump SIXBIT or ASCII data.\n */\n var nBits = 7;\n var shift = 36 - nBits;\n for (var i = 0; size == 1 && shift >= 0; i++) {\n var c = ((w / Math.pow(2, shift)) % Math.pow(2, nBits));\n sData += this.toStrBase(c, nBits) + ' ';\n c += (nBits == 6? 0x20 : 0);\n sChars += (c < 0x20? '.' : String.fromCharCode(c));\n shift -= nBits;\n }\n }\n if (sDump) sDump += \"\\n\";\n if (fJSON) {\n sDump += sData + \",\";\n } else {\n sDump += sAddr + \": \" + sData + ((n < 0)? (' ' + sChars) : \"\");\n }\n }\n\n if (sDump) this.println(sDump);\n\n this.nBase = nBase;\n }\n\n /**\n * doEdit(asArgs)\n *\n * @this {DebuggerPDP10}\n * @param {Array.<string>} asArgs\n */\n doEdit(asArgs)\n {\n var fnGet, fnSet;\n var sCmd = asArgs[0];\n var sAddr = asArgs[1];\n if (sCmd == \"e\" || sCmd == \"ew\") {\n fnGet = this.getWord;\n fnSet = this.setWord;\n } else {\n sAddr = null;\n }\n if (sAddr == null) {\n this.println(\"edit memory commands:\");\n this.println(\"\\tew [a] [...] edit words at address a\");\n return;\n }\n var dbgAddr = this.parseAddr(sAddr, this.dbgAddrData);\n for (var i = 2; i < asArgs.length; i++) {\n var w = this.parseExpression(asArgs[i]);\n if (w === undefined) break;\n w = this.validateWord(w);\n this.println(\"changing \" + this.toStrAddr(dbgAddr) + \" from \" + this.toStrWord(fnGet.call(this, dbgAddr)) + \" to \" + this.toStrWord(w));\n fnSet.call(this, dbgAddr, w, 1);\n }\n }\n\n /**\n * doHalt(fQuiet)\n *\n * @this {DebuggerPDP10}\n * @param {boolean} [fQuiet]\n */\n doHalt(fQuiet)\n {\n var sMsg;\n if (this.flags.running) {\n if (!fQuiet) this.println(\"halting\");\n this.stopCPU();\n } else {\n if (this.isBusy(true)) return;\n if (!fQuiet) this.println(\"already halted\");\n }\n }\n\n /**\n * doIf(sCmd, fQuiet)\n *\n * NOTE: Don't forget that the default base for all numeric constants is 16 (hex), so when you evaluate\n * an expression like \"a==10\", it will compare the value of the variable \"a\" to 0x10; use a trailing period\n * (eg, \"10.\") if you really intend decimal.\n *\n * Also, if no variable named \"a\" exists, \"a\" will evaluate to 0x0A, so the expression \"a==10\" becomes\n * \"0x0A==0x10\" (false), whereas the expression \"a==10.\" becomes \"0x0A==0x0A\" (true).\n *\n * @this {DebuggerPDP10}\n * @param {string} sCmd\n * @param {boolean} [fQuiet]\n * @return {boolean} true if expression is non-zero, false if zero (or undefined due to a parse error)\n */\n doIf(sCmd, fQuiet)\n {\n sCmd = Str.trim(sCmd);\n if (!this.parseExpression(sCmd)) {\n if (!fQuiet) this.println(\"false: \" + sCmd);\n return false;\n }\n if (!fQuiet) this.println(\"true: \" + sCmd);\n return true;\n }\n\n /**\n * doInfo(asArgs)\n *\n * @this {DebuggerPDP10}\n * @param {Array.<string>} asArgs\n * @return {boolean} true only if the instruction info command (\"n\") is supported\n */\n doInfo(asArgs)\n {\n if (DEBUG) {\n this.println(\"msPerYield: \" + this.cpu.msPerYield);\n this.println(\"nCyclesPerYield: \" + this.cpu.nCyclesPerYield);\n return true;\n }\n return false;\n }\n\n /**\n * doVar(sCmd)\n *\n * The command must be of the form \"{variable} = [{expression}]\", where expression may contain constants,\n * operators, registers, symbols, other variables, or nothing at all; in the latter case, the variable, if\n * any, is deleted.\n *\n * Other supported shorthand: \"var\" with no parameters prints the values of all variables, and \"var {variable}\"\n * prints the value of the specified variable.\n *\n * @this {DebuggerPDP10}\n * @param {string} sCmd\n * @return {boolean} true if valid \"var\" assignment, false if not\n */\n doVar(sCmd)\n {\n var a = sCmd.match(/^\\s*([A-Z_]?[A-Z0-9_]*)\\s*(=?)\\s*(.*)$/i);\n if (a) {\n if (!a[1]) {\n if (!this.printVariable()) this.println(\"no variables\");\n return true; // it's not considered an error to print an empty list of variables\n }\n if (!a[2]) {\n return this.printVariable(a[1]);\n }\n if (!a[3]) {\n this.delVariable(a[1]);\n return true; // it's not considered an error to delete a variable that didn't exist\n }\n var v = this.parseExpression(a[3]);\n if (v !== undefined) {\n this.setVariable(a[1], v);\n return true;\n }\n return false;\n }\n this.println(\"invalid assignment:\" + sCmd);\n return false;\n }\n\n /**\n * doList(sAddr, fPrint)\n *\n * @this {DebuggerPDP10}\n * @param {string} sAddr\n * @param {boolean} [fPrint]\n * @return {string|null}\n */\n doList(sAddr, fPrint)\n {\n var sSymbol = null;\n\n var dbgAddr = this.parseAddr(sAddr);\n var addr = this.getAddr(dbgAddr);\n var aSymbol = this.findSymbol(dbgAddr, true);\n if (aSymbol.length) {\n var nDelta, sDelta, s;\n if (aSymbol[0]) {\n sDelta = \"\";\n nDelta = dbgAddr.addr - aSymbol[1];\n if (nDelta) sDelta = \" + \" + Str.toHexWord(nDelta);\n s = aSymbol[0] + \" (\" + this.toStrOffset(aSymbol[1]) + ')' + sDelta;\n if (fPrint) this.println(s);\n sSymbol = s;\n }\n if (aSymbol.length > 4 && aSymbol[4]) {\n sDelta = \"\";\n nDelta = aSymbol[5] - dbgAddr.addr;\n if (nDelta) sDelta = \" - \" + Str.toHexWord(nDelta);\n s = aSymbol[4] + \" (\" + this.toStrOffset(aSymbol[5]) + ')' + sDelta;\n if (fPrint) this.println(s);\n if (!sSymbol) sSymbol = s;\n }\n } else {\n if (fPrint) this.println(\"no symbols\");\n }\n return sSymbol;\n }\n\n /**\n * doMessages(asArgs)\n *\n * @this {DebuggerPDP10}\n * @param {Array.<string>} asArgs\n */\n doMessages(asArgs)\n {\n var m;\n var fCriteria = null;\n var sCategory = asArgs[1];\n if (sCategory == '?') sCategory = undefined;\n\n if (sCategory !== undefined) {\n var bitsMessage = 0;\n if (sCategory == \"all\") {\n bitsMessage = (0xffffffff|0) & ~(MessagesPDP10.HALT | MessagesPDP10.KEYS | MessagesPDP10.LOG);\n sCategory = null;\n } else if (sCategory == \"on\") {\n fCriteria = true;\n sCategory = null;\n } else if (sCategory == \"off\") {\n fCriteria = false;\n sCategory = null;\n } else {\n /*\n * Internally, we use \"key\" instead of \"keys\", since the latter is a method on JavasScript objects,\n * but externally, we allow the user to specify \"keys\"; \"kbd\" is also allowed as shorthand for \"keyboard\".\n */\n if (sCategory == \"keys\") sCategory = \"key\";\n if (sCategory == \"kbd\") sCategory = \"keyboard\";\n for (m in MessagesPDP10.CATEGORIES) {\n if (sCategory == m) {\n bitsMessage = MessagesPDP10.CATEGORIES[m];\n fCriteria = !!(this.bitsMessage & bitsMessage);\n break;\n }\n }\n if (!bitsMessage) {\n this.println(\"unknown message category: \" + sCategory);\n return;\n }\n }\n if (bitsMessage) {\n if (asArgs[2] == \"on\") {\n this.bitsMessage |= bitsMessage;\n fCriteria = true;\n }\n else if (asArgs[2] == \"off\") {\n this.bitsMessage &= ~bitsMessage;\n fCriteria = false;\n if (bitsMessage == MessagesPDP10.BUFFER) {\n var i = this.aMessageBuffer.length >= 1000? this.aMessageBuffer.length - 1000 : 0;\n while (i < this.aMessageBuffer.length) {\n this.println(this.aMessageBuffer[i++]);\n }\n this.aMessageBuffer = [];\n }\n }\n }\n }\n\n /*\n * Display those message categories that match the current criteria (on or off)\n */\n var n = 0;\n var sCategories = \"\";\n for (m in MessagesPDP10.CATEGORIES) {\n if (!sCategory || sCategory == m) {\n var bitMessage = MessagesPDP10.CATEGORIES[m];\n var fEnabled = !!(this.bitsMessage & bitMessage);\n if (fCriteria !== null && fCriteria != fEnabled) continue;\n if (sCategories) sCategories += ',';\n if (!(++n % 10)) sCategories += \"\\n\\t\"; // jshint ignore:line\n /*\n * Internally, we use \"key\" instead of \"keys\", since the latter is a method on JavasScript objects,\n * but externally, we allow the user to specify \"keys\".\n */\n if (m == \"key\") m = \"keys\";\n sCategories += m;\n }\n }\n\n if (sCategory === undefined) {\n this.println(\"message commands:\\n\\tm [category] [on|off]\\tturn categories on/off\");\n }\n\n this.println((fCriteria !== null? (fCriteria? \"messages on: \" : \"messages off: \") : \"message categories:\\n\\t\") + (sCategories || \"none\"));\n\n this.historyInit(); // call this just in case MessagesPDP10.INT was turned on\n }\n\n /**\n * doOptions(asArgs)\n *\n * @this {DebuggerPDP10}\n * @param {Array.<string>} asArgs\n */\n doOptions(asArgs)\n {\n switch (asArgs[1]) {\n\n case \"base\":\n if (asArgs[2]) {\n var nBase = +asArgs[2];\n if (nBase == 2 || nBase == 8 || nBase == 10 || nBase == 16) {\n this.nBase = nBase;\n } else {\n this.println(\"invalid base: \" + nBase);\n break;\n }\n }\n this.println(\"default base: \" + this.nBase);\n break;\n\n case \"cs\":\n var nCycles;\n if (asArgs[3] !== undefined) nCycles = +asArgs[3]; // warning: decimal instead of hex conversion\n switch (asArgs[2]) {\n case \"int\":\n this.cpu.nCyclesChecksumInterval = nCycles;\n break;\n case \"start\":\n this.cpu.nCyclesChecksumStart = nCycles;\n break;\n case \"stop\":\n this.cpu.nCyclesChecksumStop = nCycles;\n break;\n default:\n this.println(\"unknown cs option\");\n return;\n }\n if (nCycles !== undefined) {\n this.cpu.resetChecksum();\n }\n this.println(\"checksums \" + (this.cpu.flags.checksum? \"enabled\" : \"disabled\"));\n return;\n\n case \"sp\":\n if (asArgs[2] !== undefined) {\n if (!this.cpu.setSpeed(+asArgs[2])) {\n this.println(\"warning: using 1x multiplier, previous target not reached\");\n }\n }\n this.println(\"target speed: \" + this.cpu.getSpeedTarget() + \" (\" + this.cpu.getSpeed() + \"x)\");\n return;\n\n default:\n if (asArgs[1]) {\n this.println(\"unknown option: \" + asArgs[1]);\n return;\n }\n /* falls through */\n\n case \"?\":\n this.println(\"debugger options:\");\n this.println(\"\\tbase #\\t\\tset default base to #\");\n this.println(\"\\tcs int #\\tset checksum cycle interval to #\");\n this.println(\"\\tcs start #\\tset checksum cycle start count to #\");\n this.println(\"\\tcs stop #\\tset checksum cycle stop count to #\");\n this.println(\"\\tsp #\\t\\tset speed multiplier to #\");\n break;\n }\n }\n\n /**\n * doRegisters(asArgs, fInstruction)\n *\n * @this {DebuggerPDP10}\n * @param {Array.<string>} [asArgs]\n * @param {boolean} [fInstruction] (true to include the current instruction; default is true)\n */\n doRegisters(asArgs, fInstruction)\n {\n if (asArgs && asArgs[1] == '?') {\n this.println(\"register commands:\");\n this.println(\"\\tr\\tdump registers\");\n this.println(\"\\trm\\tdump misc registers\");\n this.println(\"\\trx [#]\\tset flag or register x to [#]\");\n return;\n }\n\n var cpu = this.cpu;\n var fMisc = undefined;\n if (fInstruction == null) fInstruction = true;\n\n if (asArgs != null && asArgs.length > 1) {\n var sReg = asArgs[1];\n\n if (sReg == 'm') {\n fMisc = true;\n }\n else {\n var sValue = null;\n var i = sReg.indexOf('=');\n if (i > 0) {\n sValue = sReg.substr(i + 1);\n sReg = sReg.substr(0, i);\n }\n else if (asArgs.length > 2) {\n sValue = asArgs[2];\n }\n else {\n this.println(\"missing value for \" + asArgs[1]);\n return;\n }\n\n var value = this.parseExpression(sValue);\n if (value === undefined) return;\n\n var iReg = this.getRegIndex(sReg);\n if (iReg < 0) {\n this.println(\"unknown register: \" + sReg);\n return;\n }\n\n this.setRegValue(iReg, value);\n\n this.cmp.updateDisplays();\n this.println(\"updated registers:\");\n }\n }\n\n this.println(this.getRegDump(fMisc));\n\n if (fInstruction) {\n this.setAddr(this.dbgAddrCode, cpu.getXC());\n this.doUnassemble(this.toStrAddr(this.dbgAddrCode));\n }\n }\n\n /**\n * doRun(sCmd, sAddr, sOptions, fQuiet)\n *\n * @this {DebuggerPDP10}\n * @param {string} sCmd\n * @param {string|undefined} [sAddr]\n * @param {string} [sOptions] (the rest of the breakpoint command-line)\n * @param {boolean} [fQuiet]\n */\n doRun(sCmd, sAddr, sOptions, fQuiet)\n {\n if (sAddr !== undefined) {\n var dbgAddr = this.parseAddr(sAddr);\n this.parseAddrOptions(dbgAddr, sOptions);\n this.setTempBreakpoint(dbgAddr);\n }\n this.startCPU(true, fQuiet);\n }\n\n /**\n * doPrint(sCmd)\n *\n * NOTE: If the string to print is a quoted string, then we run it through replaceRegs(), so that\n * you can take advantage of all the special replacement options used for software interrupt logging.\n *\n * @this {DebuggerPDP10}\n * @param {string} sCmd\n */\n doPrint(sCmd)\n {\n sCmd = Str.trim(sCmd);\n var a = sCmd.match(/^(['\"])(.*?)\\1$/);\n if (!a) {\n this.parseExpression(sCmd, false);\n } else {\n if (a[2].length > 1) {\n this.println(this.replaceRegs(a[2]));\n } else {\n this.printValue(null, a[2].charCodeAt(0));\n }\n }\n }\n\n /**\n * doStep(sCmd, sOption)\n *\n * @this {DebuggerPDP10}\n * @param {string} [sCmd] \"p\" or \"pr\"\n * @param {string} [sOption]\n */\n doStep(sCmd, sOption)\n {\n var fCallStep = true;\n var nRegs = (sCmd == \"p\"? 0 : (sCmd == \"pr\"? 1 : -1));\n\n if (sOption == '?' || nRegs < 0) {\n this.println(\"step commands:\");\n this.println(\"\\tp\\tstep over instruction\");\n this.println(\"\\tpr\\tstep over instruction with register update\");\n return;\n }\n\n /*\n * Set up the value for this.nStep (ie, 1 or 2) depending on whether the user wants\n * a subsequent register dump (\"pr\") or not (\"p\").\n */\n var nStep = 1 + nRegs;\n\n if (!this.nStep) {\n var dbgAddr = this.newAddr(this.cpu.getPC());\n var opCode = this.getWord(dbgAddr);\n\n if (this.nStep) {\n this.setTempBreakpoint(dbgAddr);\n if (!this.startCPU()) {\n if (this.cmp) this.cmp.setFocus();\n this.nStep = 0;\n }\n /*\n * A successful run will ultimately call stop(), which will in turn call clearTempBreakpoint(),\n * which will clear nStep, so there's your assurance that nStep will be reset. Now we may have\n * stopped for reasons unrelated to the temporary breakpoint, but that's OK.\n */\n } else {\n this.doTrace(nRegs? \"tr\" : \"t\");\n }\n } else {\n this.println(\"step in progress\");\n }\n }\n\n /**\n * getCall(dbgAddr)\n *\n * Given a possible return address (typically from the stack), look for a matching CALL (or INT) that\n * immediately precedes that address.\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @return {string|null} CALL instruction at or near dbgAddr, or null if none\n */\n getCall(dbgAddr)\n {\n var sCall = null;\n var addr = dbgAddr.addr;\n var addrOrig = addr;\n for (var n = 1; n <= 6 && !!addr; n++) {\n if (n > 2) {\n dbgAddr.addr = addr;\n var s = this.getInstruction(dbgAddr);\n if (s.indexOf(\"JSR\") >= 0) {\n /*\n * Verify that the length of this call, when added to the address of the call, matches\n * the original return address. We do this by getting the string index of the opcode bytes,\n * subtracting that from the string index of the next space, and dividing that difference\n * by two, to yield the length of the CALL (or INT) instruction, in bytes.\n */\n var i = s.indexOf(' ');\n var j = s.indexOf(' ', i+1);\n if (addr + (j - i - 1)/2 == addrOrig) {\n sCall = s;\n break;\n }\n }\n }\n addr -= 2;\n }\n dbgAddr.addr = addrOrig;\n return sCall;\n }\n\n /**\n * doStackTrace(sCmd, sAddr)\n *\n * Use \"k\" for a normal stack trace and \"ks\" for a stack trace with symbolic info.\n *\n * @this {DebuggerPDP10}\n * @param {string} [sCmd]\n * @param {string} [sAddr] (not used yet)\n */\n doStackTrace(sCmd, sAddr)\n {\n if (sAddr == '?') {\n this.println(\"stack trace commands:\");\n this.println(\"\\tk\\tshow frame addresses\");\n this.println(\"\\tks\\tshow symbol information\");\n return;\n }\n\n var nFrames = 10, cFrames = 0;\n var dbgAddrCall = this.newAddr();\n var dbgAddrStack = this.newAddr(/*this.cpu.getSP()*/);\n this.println(\"stack trace for \" + this.toStrAddr(dbgAddrStack));\n\n while (cFrames < nFrames) {\n var sCall = null, sCallPrev = null, cTests = 256;\n while ((dbgAddrStack.addr >>> 0) < 0x10000) {\n dbgAddrCall.addr = this.getWord(dbgAddrStack, 2);\n /*\n * Because we're using the auto-increment feature of getWord(), and because that will automatically\n * wrap the offset around the end of the segment, we must also check the addr property to detect the wrap.\n */\n if (dbgAddrStack.addr == null || !cTests--) break;\n if (dbgAddrCall.addr & 0x1) continue; // an odd address on the PDP-11 is not a valid instruction boundary\n sCall = this.getCall(dbgAddrCall);\n if (sCall) break;\n }\n /*\n * The sCallPrev check eliminates duplicate sequential calls, which are usually (but not always)\n * indicative of a false positive, in which case the previous call is probably bogus as well, but\n * at least we won't duplicate that mistake. Of course, there are always exceptions, recursion\n * being one of them, but it's rare that we're debugging recursive code.\n */\n if (!sCall || sCall == sCallPrev) break;\n var sSymbol = null;\n if (sCmd == \"ks\") {\n var a = sCall.match(/[0-9A-F]+$/);\n if (a) sSymbol = this.doList(a[0]);\n }\n sCall = Str.pad(sCall, 50) + \" ;\" + (sSymbol || \"stack=\" + this.toStrAddr(dbgAddrStack)); // + \" return=\" + this.toStrAddr(dbgAddrCall));\n this.println(sCall);\n sCallPrev = sCall;\n cFrames++;\n }\n if (!cFrames) this.println(\"no return addresses found\");\n }\n\n /**\n * doTrace(sCmd, sCount)\n *\n * The \"t\" and \"tr\" commands interpret the count as a number of instructions, and since\n * we call the Debugger's stepCPU() for each iteration, a single instruction includes\n * any/all prefixes; the CPU's stepCPU() treats prefixes as discrete operations. The only\n * difference between \"t\" and \"tr\": the former displays only the next instruction, while\n * the latter also displays the (updated) registers.\n *\n * The \"tc\" command interprets the count as a number of cycles rather than instructions,\n * allowing you to quickly execute large chunks of instructions with a single command; it\n * doesn't display anything until the the chunk has finished. \"tc 1\" is also a useful\n * command in that it doesn't inhibit interrupts like \"t\" or \"tr\" does.\n *\n * However, generally a more useful command is \"bn\", which allows you to break after some\n * number of instructions have been executed (as opposed to some number of cycles).\n *\n * @this {DebuggerPDP10}\n * @param {string} [sCmd] (\"t\", \"tc\", or \"tr\")\n * @param {string} [sCount] # of instructions to step\n */\n doTrace(sCmd, sCount)\n {\n if (sCount == '?') {\n this.println(\"trace commands:\");\n this.println(\"\\tt [#]\\ttrace # instructions\");\n this.println(\"\\ttr [#]\\ttrace # instructions with register updates\");\n this.println(\"\\ttc [#]\\ttrace # cycles\");\n this.println(\"note: bn [#] breaks after # instructions without updates\");\n return;\n }\n\n var dbg = this;\n var fRegs = (sCmd != \"t\");\n var nCount = this.parseValue(sCount, null, true) || 1;\n\n /*\n * We used to set nCycles to 1 when a count > 1 was specified, because nCycles set\n * to 0 used to mean \"execute the next instruction without checking for interrupts\".\n * Well, this machine's stepCPU() doesn't do that; it ALWAYS checks for interrupts,\n * so we should leave nCycles set to 0, so that if an interrupt is dispatched, we will\n * get to see the first instruction of the interrupt handler.\n */\n var nCycles = 0; // (nCount == 1? 0 : 1);\n\n if (sCmd == \"tc\") {\n nCycles = nCount;\n nCount = 1;\n }\n this.sCmdTracePrev = sCmd;\n\n Web.onCountRepeat(\n nCount,\n function onCountStep() {\n return dbg.setBusy(true) && dbg.stepCPU(nCycles, fRegs, false);\n },\n function onCountStepComplete() {\n /*\n * We explicitly called stepCPU() with fUpdateDisplays set to false, because repeatedly\n * calling updateDisplays() can be very slow, especially if a Control Panel is present with\n * displayLiveRegs enabled, so once the repeat count has been exhausted, we must perform\n * a final updateDisplays().\n */\n if (dbg.panel) dbg.panel.stop();\n dbg.cmp.updateDisplays(-1);\n dbg.setBusy(false);\n }\n );\n }\n\n /**\n * doUnassemble(sAddr, sAddrEnd, nLines)\n *\n * @this {DebuggerPDP10}\n * @param {string} [sAddr]\n * @param {string} [sAddrEnd]\n * @param {number} [nLines]\n */\n doUnassemble(sAddr, sAddrEnd, nLines)\n {\n var dbgAddr = this.parseAddr(sAddr, this.dbgAddrCode);\n\n if (nLines === undefined) nLines = 1;\n\n var nBytes = 0x100;\n if (sAddrEnd !== undefined) {\n\n if (sAddrEnd.charAt(0) == 'l') {\n var n = this.parseValue(sAddrEnd.substr(1));\n if (n != null) nLines = n;\n }\n else {\n var dbgAddrEnd = this.parseAddr(sAddrEnd);\n if (dbgAddrEnd.addr < dbgAddr.addr) return;\n\n nBytes = dbgAddrEnd.addr - dbgAddr.addr;\n if (!DEBUG && nBytes > 0x100) {\n /*\n * Limiting the amount of disassembled code to 256 bytes in non-DEBUG builds is partly to\n * prevent the user from wedging the browser by dumping too many lines, but also a recognition\n * that, in non-DEBUG builds, this.println() keeps print output buffer truncated to 8Kb anyway.\n */\n this.println(\"range too large\");\n return;\n }\n nLines = -1;\n }\n }\n\n var nPrinted = 0;\n\n while (nBytes > 0 && nLines--) {\n\n var nSequence = (this.isBusy(false) || this.nStep)? this.nCycles : null;\n var sComment = (nSequence != null? \"cycles\" : null);\n var aSymbol = this.findSymbol(dbgAddr);\n\n var addr = dbgAddr.addr; // we snap dbgAddr.addr *after* calling findSymbol(), which re-evaluates it\n\n if (aSymbol[0] && nLines) {\n if (!nPrinted && nLines || aSymbol[0].indexOf('+') < 0) {\n var sLabel = aSymbol[0] + ':';\n if (aSymbol[2]) sLabel += ' ' + aSymbol[2];\n this.println(sLabel);\n }\n }\n if (aSymbol[3]) {\n sComment = aSymbol[3];\n nSequence = null;\n }\n this.copyAddr(this.dbgAddrAssemble, dbgAddr);\n this.println(this.getInstruction(dbgAddr, sComment, nSequence));\n nBytes -= dbgAddr.addr - addr;\n nPrinted++;\n }\n }\n\n /**\n * splitArgs(sCmd, sDelim)\n *\n * @this {DebuggerPDP10}\n * @param {string} sCmd\n * @param {string} [sDelim]\n * @return {Array.<string>}\n */\n splitArgs(sCmd, sDelim = \" \")\n {\n var asArgs = [];\n var chQuote = \"\";\n var i = 0, iLast = 0;\n\n while (i < sCmd.length) {\n var ch = sCmd[i++];\n if (chQuote) {\n if (ch == chQuote) {\n chQuote = \"\";\n asArgs.push(sCmd.substr(iLast, i - iLast));\n iLast = i;\n }\n continue;\n }\n if (ch == '\"' || ch == \"'\") {\n chQuote = ch;\n continue;\n }\n if (sDelim.indexOf(ch) >= 0) {\n asArgs.push(sCmd.substr(iLast, i - iLast - 1));\n iLast = i;\n }\n }\n if (iLast < i) {\n asArgs.push(sCmd.substr(iLast, i - iLast));\n }\n\n asArgs[0] = asArgs[0].toLowerCase();\n if (asArgs && asArgs.length) {\n var s0 = asArgs[0];\n var ch0 = s0.charAt(0);\n for (i = 1; i < s0.length; i++) {\n ch = s0.charAt(i);\n if (ch0 == '?' || ch0 == 'r' || ch < 'a' || ch > 'z') {\n asArgs[0] = s0.substr(i);\n asArgs.unshift(s0.substr(0, i));\n break;\n }\n }\n }\n return asArgs;\n }\n\n /**\n * doCommand(sCmd, fQuiet)\n *\n * @this {DebuggerPDP10}\n * @param {string} sCmd\n * @param {boolean} [fQuiet]\n * @return {boolean} true if command processed, false if unrecognized\n */\n doCommand(sCmd, fQuiet)\n {\n var result = true;\n\n try {\n if (DEBUG && sCmd == \"test\") {\n this.doTest();\n return true;\n }\n if (!sCmd.length || sCmd == \"end\") {\n if (this.fAssemble) {\n this.println(\"ended assemble at \" + this.toStrAddr(this.dbgAddrAssemble));\n this.fAssemble = false;\n }\n sCmd = \"\";\n }\n else if (!fQuiet) {\n this.println(DebuggerPDP10.PROMPT + sCmd);\n }\n\n var ch = sCmd.charAt(0);\n if (ch == '\"' || ch == \"'\") return true;\n\n /*\n * Zap the previous message buffer to ensure the new command's output is not tossed out as a repeat.\n */\n this.sMessagePrev = null;\n\n /*\n * I've relaxed the !isBusy() requirement, to maximize our ability to issue Debugger commands externally.\n */\n if (this.isReady() /* && !this.isBusy(true) */ && sCmd.length > 0) {\n\n if (this.fAssemble) {\n sCmd = \"a \" + this.toStrAddr(this.dbgAddrAssemble) + ' ' + sCmd;\n }\n\n var fError = false;\n var asArgs = this.splitArgs(sCmd);\n\n switch (asArgs[0].charAt(0)) {\n case 'a':\n result = this.doAssemble(asArgs);\n break;\n case 'b':\n this.doBreak(asArgs[0], asArgs[1], sCmd);\n break;\n case 'c':\n this.doClear(asArgs[0]);\n break;\n case 'd':\n if (!COMPILED && sCmd == \"debug\") {\n window.DEBUG = true;\n this.println(\"DEBUG checks on\");\n break;\n }\n this.doDump(asArgs);\n break;\n case 'e':\n if (asArgs[0] == \"else\") break;\n this.doEdit(asArgs);\n break;\n case 'g':\n this.doRun(asArgs[0], asArgs[1], sCmd, fQuiet);\n break;\n case 'h':\n this.doHalt(fQuiet);\n break;\n case 'i':\n if (asArgs[0] == \"if\") {\n if (!this.doIf(sCmd.substr(2), fQuiet)) {\n result = false;\n }\n break;\n }\n fError = true;\n break;\n case 'k':\n this.doStackTrace(asArgs[0], asArgs[1]);\n break;\n case 'l':\n if (asArgs[0] == \"ln\") {\n this.doList(asArgs[1], true);\n break;\n }\n fError = true;\n break;\n case 'm':\n this.doMessages(asArgs);\n break;\n case 'p':\n if (asArgs[0] == \"print\") {\n this.doPrint(sCmd.substr(5));\n break;\n }\n this.doStep(asArgs[0], asArgs[1]);\n break;\n case 'r':\n if (sCmd == \"reset\") {\n if (this.cmp) this.cmp.reset();\n break;\n }\n this.doRegisters(asArgs);\n break;\n case 's':\n this.doOptions(asArgs);\n break;\n case 't':\n this.doTrace(asArgs[0], asArgs[1]);\n break;\n case 'u':\n this.doUnassemble(asArgs[1], asArgs[2], 8);\n break;\n case 'v':\n if (asArgs[0] == \"var\") {\n if (!this.doVar(sCmd.substr(3))) {\n result = false;\n }\n break;\n }\n if (asArgs[0] == \"ver\") {\n this.println((PDP10.APPNAME || \"PDP10\") + \" version \" + (XMLVERSION || PDP10.APPVERSION) + \" (\" + this.cpu.model + (PDP10.COMPILED? \",RELEASE\" : (PDP10.DEBUG? \",DEBUG\" : \",NODEBUG\")) + ')');\n this.println(Web.getUserAgent());\n break;\n }\n fError = true;\n break;\n case '?':\n if (asArgs[1]) {\n this.doPrint(sCmd.substr(1));\n break;\n }\n this.doHelp();\n break;\n case 'n':\n if (!COMPILED && sCmd == \"nodebug\") {\n window.DEBUG = false;\n this.println(\"DEBUG checks off\");\n break;\n }\n if (this.doInfo(asArgs)) break;\n /* falls through */\n default:\n fError = true;\n break;\n }\n if (fError) {\n this.println(\"unknown command: \" + sCmd);\n result = false;\n }\n }\n } catch(e) {\n this.println(\"Debugger \" + (e.stack || e.message));\n result = false;\n }\n return result;\n }\n\n /**\n * doCommands(sCmds, fSave)\n *\n * This function is now written so that if any async command, such as assemble ('a'), stopped the\n * flow of commands by returning false, it can call us from its callback handler with no arguments,\n * and command processing should continue where it left off.\n *\n * @this {DebuggerPDP10}\n * @param {string} [sCmds]\n * @param {boolean} [fSave]\n * @return {boolean} true if all commands processed, false if not\n */\n doCommands(sCmds, fSave)\n {\n if (sCmds != null) {\n this.aCommands = this.parseCommand(sCmds, fSave);\n }\n var sCmd;\n while (sCmd = this.aCommands.shift()) {\n if (!this.doCommand(sCmd)) return false;\n }\n return true;\n }\n\n /**\n * doTest()\n *\n * This function exercises the disassembler by performing look-ups for all possible operation codes\n * and displaying the results. It's not intended to be included in the compiled version of the Debugger\n * (DEBUG only).\n *\n * @this {DebuggerPDP10}\n */\n doTest()\n {\n if (MAXDEBUG) {\n var ops = {}, aOpXXX = [];\n var op, opXXX, opCode, sOperation;\n for (op = 0o00000; op <= 0o77774; op += 4) {\n opCode = op * Math.pow(2, 21);\n sOperation = this.findInstruction(opCode, false);\n if (!sOperation) continue;\n if (ops[sOperation] === undefined) {\n ops[sOperation] = op;\n } else {\n ops[sOperation] &= op;\n }\n opXXX = op >> 6;\n if (!aOpXXX[opXXX]) {\n aOpXXX[opXXX] = sOperation;\n } else if (aOpXXX[opXXX] != sOperation) {\n aOpXXX[opXXX] = \"XXX\";\n }\n }\n for (sOperation in ops) {\n op = ops[sOperation];\n this.println(Str.pad(sOperation + \":\", 8) + this.toStrWord(op * Math.pow(2, 21)));\n //\n // The following code leveraged the disassembler to generate opcode handlers.\n //\n // this.println(\"/**\");\n // this.println(\" * op\" + sOperation + \"(\" + this.toStrWord(op * Math.pow(2, 21)) + \")\");\n // this.println(\" *\");\n // this.println(\" * @this {CPUStatePDP10}\");\n // this.println(\" * @param {number} opCode\");\n // this.println(\" */\");\n // this.println(\"PDP10.op\" + sOperation + \" = function(opCode)\");\n // this.println(\"{\");\n // this.println(\" this.opUndefined(op);\");\n // this.println(\"};\\n\");\n }\n //\n // The following code generated an opcode dispatch table.\n //\n // this.println(\"PDP10.aOpXXX = [\");\n // for (opXXX = 0o000; opXXX <= 0o777; opXXX++) {\n // sOperation = aOpXXX[opXXX];\n // sOperation = sOperation? (\" PDP10.op\" + sOperation + \",\") : \" PDP10.opUndefined,\";\n // sOperation = Str.pad(sOperation, 32);\n // sOperation += \"// \" + Str.toOct(opXXX, 3, true) + \"xxx\";\n // this.println(sOperation);\n // }\n // this.println(\"];\");\n }\n }\n\n /**\n * DebuggerPDP10.init()\n *\n * This function operates on every HTML element of class \"debugger\", extracting the\n * JSON-encoded parameters for the Debugger constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Debugger component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeDbg = Component.getElementsByClass(document, PDP10.APPCLASS, \"debugger\");\n for (var iDbg = 0; iDbg < aeDbg.length; iDbg++) {\n var eDbg = aeDbg[iDbg];\n var parmsDbg = Component.getComponentParms(eDbg);\n var dbg = new DebuggerPDP10(parmsDbg);\n Component.bindComponentControls(dbg, eDbg, PDP10.APPCLASS);\n }\n }\n}\n\nif (DEBUGGER) {\n\n /*\n * NOTE: Every DebuggerPDP10 property from here to the first prototype function definition (initBus()) is\n * considered a \"class constant\"; most of them use our \"all-caps\" convention (and all of them SHOULD, but\n * that wouldn't help us catch any bugs).\n *\n * Technically, all of them should ALSO be preceded by a \"@const\" annotation, but that's a lot of work and it\n * really clutters the code. I wish the Closure Compiler had a way to annotate every definition with a given\n * section with a single annotation....\n */\n\n DebuggerPDP10.COMMANDS = {\n '?': \"help/print\",\n 'a [#]': \"assemble\", // TODO: Implement this command someday\n 'b [#]': \"breakpoint\", // multiple variations (use b? to list them)\n 'c': \"clear output\",\n 'd [#]': \"dump memory\", // additional syntax: d [#] [l#], where l# is a number of bytes to dump\n 'e [#]': \"edit memory\",\n 'g [#]': \"go [to #]\",\n 'h': \"halt\",\n 'if': \"eval expression\",\n 'int [#]': \"request interrupt\",\n 'k': \"stack trace\",\n \"ln\": \"list nearest symbol(s)\",\n 'm': \"messages\",\n 'p': \"step over\", // other variations: pr (step and dump registers)\n 'print': \"print expression\",\n 'r': \"dump/set registers\",\n 'reset': \"reset machine\",\n 's': \"set options\",\n 't [#]': \"trace\", // other variations: tr (trace and dump registers)\n 'u [#]': \"unassemble\",\n 'var': \"assign variable\",\n 'ver': \"print version\"\n };\n\n /*\n * CPU opcode IDs\n */\n DebuggerPDP10.OPS = {\n NONE: 0,\n HLL: 1, HLLZ: 2, HLLO: 3, HLLE: 4,\n HRL: 5, HRLZ: 6, HRLO: 7, HRLE: 8,\n HRR: 9, HRRZ: 10, HRRO: 11, HRRE: 12,\n HLR: 13, HLRZ: 14, HLRO: 15, HLRE: 16,\n MOVE: 17, MOVS: 18, MOVN: 19, MOVM: 20,\n EXCH: 21, BLT: 22, PUSH: 23, POP: 24,\n LDB: 25, DPB: 26, IBP: 27, ILDB: 28,\n IDPB: 29, SETZ: 30, SETO: 31, SETA: 32,\n SETCA: 33, SETM: 34, SETCM: 35, AND: 36,\n ANDCA: 37, ANDCM: 38, ANDCB: 39, IOR: 40,\n ORCA: 41, ORCM: 42, ORCB: 43, XOR: 44,\n EQV: 45, LSH: 46, LSHC: 47, ROT: 48,\n ROTC: 49, ADD: 50, SUB: 51, MUL: 52,\n IMUL: 53, DIV: 54, IDIV: 55, ASH: 56,\n ASHC: 57, FSC: 58, FADR: 59, FSBR: 60,\n FMPR: 61, FDVR: 62, DFN: 63, UFA: 64,\n FAD: 65, FSB: 66, FMP: 67, FDV: 68,\n AOBJP: 69, AOBJN: 70, CAI: 71, CAM: 72,\n JUMP: 73, SKIP: 74, AOJ: 75, AOS: 76,\n SOJ: 77, SOS: 78, TR: 79, TL: 80,\n TD: 81, TS: 82, XCT: 83, JFFO: 84,\n JFCL: 85, JSR: 86, JSP: 87, JRST: 88,\n JSA: 89, JRA: 90, PUSHJ: 91, POPJ: 92,\n BLKI: 93, DATAI: 94, BLKO: 95, DATAO: 96,\n CONO: 97, CONI: 98, CONSZ: 99, CONSO: 100,\n UUO: 101, JOV: 102, JCRY0: 103, JCRY1: 104,\n JCRY: 105, JFOV: 106, HALT: 107, JRSTF: 108,\n JEN: 109\n };\n\n /*\n * CPU opcode names, indexed by CPU opcode ordinal (above)\n */\n DebuggerPDP10.OPNAMES = [\n \".WORD\",\n \"HLL\", \"HLLZ\", \"HLLO\", \"HLLE\",\n \"HRL\", \"HRLZ\", \"HRLO\", \"HRLE\",\n \"HRR\", \"HRRZ\", \"HRRO\", \"HRRE\",\n \"HLR\", \"HLRZ\", \"HLRO\", \"HLRE\",\n \"MOVE\", \"MOVS\", \"MOVN\", \"MOVM\",\n \"EXCH\", \"BLT\", \"PUSH\", \"POP\",\n \"LDB\", \"DPB\", \"IBP\", \"ILDB\",\n \"IDPB\", \"SETZ\", \"SETO\", \"SETA\",\n \"SETCA\", \"SETM\", \"SETCM\", \"AND\",\n \"ANDCA\", \"ANDCM\", \"ANDCB\", \"IOR\",\n \"ORCA\", \"ORCM\", \"ORCB\", \"XOR\",\n \"EQV\", \"LSH\", \"LSHC\", \"ROT\",\n \"ROTC\", \"ADD\", \"SUB\", \"MUL\",\n \"IMUL\", \"DIV\", \"IDIV\", \"ASH\",\n \"ASHC\", \"FSC\", \"FADR\", \"FSBR\",\n \"FMPR\", \"FDVR\", \"DFN\", \"UFA\",\n \"FAD\", \"FSB\", \"FMP\", \"FDV\",\n \"AOBJP\", \"AOBJN\", \"CAI\", \"CAM\",\n \"JUMP\", \"SKIP\", \"AOJ\", \"AOS\",\n \"SOJ\", \"SOS\", \"TR\", \"TL\",\n \"TD\", \"TS\", \"XCT\", \"JFFO\",\n \"JFCL\", \"JSR\", \"JSP\", \"JRST\",\n \"JSA\", \"JRA\", \"PUSHJ\", \"POPJ\",\n \"BLKI\", \"DATAI\", \"BLKO\", \"DATAO\",\n \"CONO\", \"CONI\", \"CONSZ\", \"CONSO\",\n \"UUO\", \"JOV\", \"JCRY0\", \"JCRY1\",\n \"JCRY\", \"JFOV\", \"HALT\", 'JRSTF',\n \"JEN\"\n ];\n\n DebuggerPDP10.REGS = {\n PC: 0,\n RA: 1,\n EA: 2,\n PS: 3,\n OV: 4, // single-bit \"register\" representing the Overflow flag\n C0: 5, // single-bit \"register\" representing the Carry 0 flag\n C1: 6, // single-bit \"register\" representing the Carry 1 flag\n BI: 7, // single-bit \"register\" representing the Byte Interrupt flag\n ND: 8, // single-bit \"register\" representing the No Divide flag\n PD: 9, // single-bit \"register\" representing the Pushdown Overflow flag\n };\n\n DebuggerPDP10.REGNAMES = [\n \"PC\", \"RA\", \"EA\", \"PS\", \"OV\", \"C0\", \"C1\", \"BI\", \"ND\", \"PD\"\n ];\n\n /*\n * OPTABLE is a collection of masks, and each mask refers to a collection of opcode\n * patterns associated with that mask; the disassembler applies each mask to the opcode,\n * and when a masked opcode matches one of the associated patterns, the corresponding\n * instruction is considered a match.\n */\n DebuggerPDP10.OPTABLE = {\n [PDP10.OPCODE.OPUUO]: { // 0o70000\n 0o00000: DebuggerPDP10.OPS.UUO\n },\n [PDP10.OPCODE.OPMASK]: { // 0o77700\n 0o13000: DebuggerPDP10.OPS.UFA,\n 0o13100: DebuggerPDP10.OPS.DFN,\n 0o13200: DebuggerPDP10.OPS.FSC,\n 0o13300: DebuggerPDP10.OPS.IBP,\n 0o13400: DebuggerPDP10.OPS.ILDB,\n 0o13500: DebuggerPDP10.OPS.LDB,\n 0o13600: DebuggerPDP10.OPS.IDPB,\n 0o13700: DebuggerPDP10.OPS.DPB,\n 0o24000: DebuggerPDP10.OPS.ASH,\n 0o24100: DebuggerPDP10.OPS.ROT,\n 0o24200: DebuggerPDP10.OPS.LSH,\n 0o24300: DebuggerPDP10.OPS.JFFO,\n 0o24400: DebuggerPDP10.OPS.ASHC,\n 0o24500: DebuggerPDP10.OPS.ROTC,\n 0o24600: DebuggerPDP10.OPS.LSHC,\n 0o25000: DebuggerPDP10.OPS.EXCH,\n 0o25100: DebuggerPDP10.OPS.BLT,\n 0o25200: DebuggerPDP10.OPS.AOBJP,\n 0o25300: DebuggerPDP10.OPS.AOBJN,\n 0o25400: DebuggerPDP10.OPS.JRST, // includes HALT, JRSTF, and JEN\n 0o25500: DebuggerPDP10.OPS.JFCL, // includes JOV, JCRY0, JCRY1, JCRY, and JFOV\n 0o25600: DebuggerPDP10.OPS.XCT,\n 0o26000: DebuggerPDP10.OPS.PUSHJ,\n 0o26100: DebuggerPDP10.OPS.PUSH,\n 0o26200: DebuggerPDP10.OPS.POP,\n 0o26300: DebuggerPDP10.OPS.POPJ,\n 0o26400: DebuggerPDP10.OPS.JSR,\n 0o26500: DebuggerPDP10.OPS.JSP,\n 0o26600: DebuggerPDP10.OPS.JSA,\n 0o26700: DebuggerPDP10.OPS.JRA,\n },\n [PDP10.OPCODE.OPMODE]: { // 0o77400\n 0o14000: DebuggerPDP10.OPS.FAD,\n 0o14400: DebuggerPDP10.OPS.FADR,\n 0o15000: DebuggerPDP10.OPS.FSB,\n 0o15400: DebuggerPDP10.OPS.FSBR,\n 0o16000: DebuggerPDP10.OPS.FMP,\n 0o16400: DebuggerPDP10.OPS.FMPR,\n 0o17000: DebuggerPDP10.OPS.FDV,\n 0o17400: DebuggerPDP10.OPS.FDVR,\n 0o20000: DebuggerPDP10.OPS.MOVE,\n 0o20400: DebuggerPDP10.OPS.MOVS,\n 0o21000: DebuggerPDP10.OPS.MOVN,\n 0o21400: DebuggerPDP10.OPS.MOVM,\n 0o22000: DebuggerPDP10.OPS.IMUL,\n 0o22400: DebuggerPDP10.OPS.MUL,\n 0o23000: DebuggerPDP10.OPS.IDIV,\n 0o23400: DebuggerPDP10.OPS.DIV,\n 0o27000: DebuggerPDP10.OPS.ADD,\n 0o27400: DebuggerPDP10.OPS.SUB,\n 0o40000: DebuggerPDP10.OPS.SETZ, // MACRO alias: CLEAR\n 0o40400: DebuggerPDP10.OPS.AND,\n 0o41000: DebuggerPDP10.OPS.ANDCA,\n 0o41400: DebuggerPDP10.OPS.SETM,\n 0o42000: DebuggerPDP10.OPS.ANDCM,\n 0o42400: DebuggerPDP10.OPS.SETA,\n 0o43000: DebuggerPDP10.OPS.XOR,\n 0o43400: DebuggerPDP10.OPS.IOR, // MACRO alias: OR\n 0o44000: DebuggerPDP10.OPS.ANDCB,\n 0o44400: DebuggerPDP10.OPS.EQV,\n 0o45000: DebuggerPDP10.OPS.SETCA,\n 0o45400: DebuggerPDP10.OPS.ORCA,\n 0o46000: DebuggerPDP10.OPS.SETCM,\n 0o46400: DebuggerPDP10.OPS.ORCM,\n 0o47000: DebuggerPDP10.OPS.ORCB,\n 0o47400: DebuggerPDP10.OPS.SETO,\n 0o50000: DebuggerPDP10.OPS.HLL,\n 0o50400: DebuggerPDP10.OPS.HRL,\n 0o51000: DebuggerPDP10.OPS.HLLZ,\n 0o51400: DebuggerPDP10.OPS.HRLZ,\n 0o52000: DebuggerPDP10.OPS.HLLO,\n 0o52400: DebuggerPDP10.OPS.HRLO,\n 0o53000: DebuggerPDP10.OPS.HLLE,\n 0o53400: DebuggerPDP10.OPS.HRLE,\n 0o54000: DebuggerPDP10.OPS.HRR,\n 0o54400: DebuggerPDP10.OPS.HLR,\n 0o55000: DebuggerPDP10.OPS.HRRZ,\n 0o55400: DebuggerPDP10.OPS.HLRZ,\n 0o56000: DebuggerPDP10.OPS.HRRO,\n 0o56400: DebuggerPDP10.OPS.HLRO,\n 0o57000: DebuggerPDP10.OPS.HRRE,\n 0o57400: DebuggerPDP10.OPS.HLRE\n },\n [PDP10.OPCODE.OPCOMP]: { // 0o77000\n 0o30000: DebuggerPDP10.OPS.CAI,\n 0o31000: DebuggerPDP10.OPS.CAM,\n 0o32000: DebuggerPDP10.OPS.JUMP,\n 0o33000: DebuggerPDP10.OPS.SKIP,\n 0o34000: DebuggerPDP10.OPS.AOJ,\n 0o35000: DebuggerPDP10.OPS.AOS,\n 0o36000: DebuggerPDP10.OPS.SOJ,\n 0o37000: DebuggerPDP10.OPS.SOS,\n },\n [PDP10.OPCODE.OPTEST]: { // 0o71100\n 0o60000: DebuggerPDP10.OPS.TR,\n 0o60100: DebuggerPDP10.OPS.TL,\n 0o61000: DebuggerPDP10.OPS.TD,\n 0o61100: DebuggerPDP10.OPS.TS,\n },\n [PDP10.OPCODE.OPIO]: { // 0o70034\n 0o70000: DebuggerPDP10.OPS.BLKI,\n 0o70004: DebuggerPDP10.OPS.DATAI,\n 0o70010: DebuggerPDP10.OPS.BLKO,\n 0o70014: DebuggerPDP10.OPS.DATAO,\n 0o70020: DebuggerPDP10.OPS.CONO,\n 0o70024: DebuggerPDP10.OPS.CONI,\n 0o70030: DebuggerPDP10.OPS.CONSZ,\n 0o70034: DebuggerPDP10.OPS.CONSO\n }\n };\n\n DebuggerPDP10.OPMODES = [\"\", \"I\", \"M\", \"S\"];\n DebuggerPDP10.OPCOMPS = [\"\", \"L\", \"E\", \"LE\", \"A\", \"GE\", \"N\", \"G\"];\n DebuggerPDP10.OPTESTS = [\"N\", \"NE\", \"NA\", \"NN\", \"Z\", \"ZE\", \"ZA\", \"ZN\", \"C\", \"CE\", \"CA\", \"CN\", \"O\", \"OE\", \"OA\", \"ON\"];\n\n /*\n * Apparently, DEC's MACRO program permits \"JFCL xxx\" (with a single argument) as an alternate for \"JFCL 0,xxx\"\n * (which in turn is long-hand for \"No-op\", since JFCL with 0 does nothing).\n */\n DebuggerPDP10.JFCL = {\n 0o00: DebuggerPDP10.OPS.JFCL,\n 0o10: DebuggerPDP10.OPS.JOV,\n 0o04: DebuggerPDP10.OPS.JCRY0,\n 0o02: DebuggerPDP10.OPS.JCRY1,\n 0o06: DebuggerPDP10.OPS.JCRY,\n 0o01: DebuggerPDP10.OPS.JFOV\n };\n\n DebuggerPDP10.JRST = {\n 0o00: DebuggerPDP10.OPS.JRST,\n 0o04: DebuggerPDP10.OPS.HALT,\n 0o02: DebuggerPDP10.OPS.JRSTF,\n 0o12: DebuggerPDP10.OPS.JEN\n };\n\n DebuggerPDP10.ALTOPS = [\n DebuggerPDP10.JFCL, DebuggerPDP10.JRST\n ];\n\n DebuggerPDP10.HISTORY_LIMIT = DEBUG? 100000 : 1000;\n\n DebuggerPDP10.PROMPT = \">> \";\n\n /*\n * Initialize every Debugger module on the page (as IF there's ever going to be more than one ;-))\n */\n Web.onInit(DebuggerPDP10.init);\n\n} // endif DEBUGGER\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/macro10.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Elements of tblMacros.\n *\n * @typedef {{\n * name:(string),\n * nOperand:(number),\n * aParms:(Array.<string>),\n * aDefaults:(Array.<string>),\n * aValues:(Array.<string>),\n * sText:(string),\n * nLine:(number)\n * }}\n */\nvar Mac;\n\n/**\n * Elements of tblSymbols.\n *\n * @typedef {{\n * name:(string),\n * value:(number),\n * nType:(number),\n * nLine:(number)\n * }}\n */\nvar Sym;\n\n/**\n * Elements of aLiterals.\n *\n * @typedef {{\n * name:(string),\n * aWords:(Array.<number>),\n * aFixups:(Array.<string>)\n * }}\n */\nvar Lit;\n\n/**\n * Elements of stackScopes.\n *\n * @typedef {{\n * name:(string|undefined),\n * aWords:(Array.<number>),\n * aFixups:(Array.<string>),\n * nLocation:(number),\n * nLocationScope:(number),\n * nLine:(number)\n * }}\n */\nvar Scope;\n\n/**\n * @class Macro10\n * @property {string} sURL\n * @property {number|null} addrLoad\n * @property {string} sOptions\n * @property {DebuggerPDP10} dbg\n * @property {function(...)|undefined} done\n * @property {number} iURL\n * @property {Array.<string>} aURLs\n * @property {Array.<number>} anLines\n * @property {Array.<string>} asLines\n * @property {number|null|undefined} addrStart\n * @unrestricted\n */\nclass Macro10 {\n /**\n * Macro10(dbg)\n *\n * A \"mini\" version of DEC's MACRO-10 assembler, with just enough features to support the handful\n * of DEC diagnostic source code files that we choose to throw at it.\n *\n * We rely on the calling component (dbg) to provide a variety of helper services (eg, println(),\n * parseExpression(), etc). This is NOT a subclass of Component, so Component services are not part\n * of this class.\n *\n * @this {Macro10}\n * @param {DebuggerPDP10} dbg (used to provide helper services to the Macro10 class)\n */\n constructor(dbg)\n {\n this.dbg = dbg;\n }\n\n /**\n * init(addrLoad, sOptions, done)\n *\n * Initializes all instance properties. Called by assembleFiles() and assembleString().\n *\n * Supported options include:\n *\n * 'd': leave all symbols in the debugger's variable table\n * 'p': print the preprocessed resource(s) without assembling them\n * 'l': print lines as they are parsed\n * 's': treat the URL as a string and assemble it (assembleFiles() only)\n *\n * The done() callback is called after the resource(s) have been loaded (if necessary), parsed, and\n * assembled. The caller must use other methods to obtain further results (eg, getImage(), getStart()).\n *\n * The callback includes a non-zero error code if there was an error (and the URL):\n *\n * done(nErrorCode, sURL)\n *\n * @this {Macro10}\n * @param {number|null} [addrLoad] (the absolute address to assemble the code at, if any)\n * @param {string|undefined} [sOptions] (zero or more letter codes to control the assembly process)\n * @param {function(...)|undefined} [done]\n */\n init(addrLoad, sOptions, done)\n {\n this.addrLoad = addrLoad;\n this.sOptions = (sOptions || \"\").toLowerCase();\n this.done = done;\n\n this.iURL = 0;\n this.aURLs = [];\n\n /**\n * Number of lines per file.\n *\n * @type {Array.<number>}\n */\n this.anLines = [];\n\n /**\n * Lines from all the resources.\n *\n * @type {Array.<string>}\n */\n this.asLines = [];\n\n if (MAXDEBUG) this.println(\"starting PCjs MACRO-10 Mini-Assembler...\");\n\n /*\n * Initialize all the tables and other data structures that MACRO-10 uses.\n *\n * The Macros (tblMacros) and Symbols (tblSymbols) tables are fairly straightforward: they are\n * indexed by a macro or symbol name, and each element is a Mac or Sym object, respectively.\n *\n * We also treat REPEAT blocks and CONDITIONAL (eg, IFE) blocks like macros, except that they are\n * anonymous, parameter-less, and immediately invoked. REPEAT blocks are always immediately invoked\n * (repeatedly, based on the repeat count), whereas CONDITIONAL blocks are either immediately\n * invoked if the associated condition is true or skipped if the condition is false.\n *\n * Finally, we have LITERAL blocks, which are semi-anonymous (we give each one an auto-generated\n * name based on the current location) and are automatically but not immediately invoked. Instead,\n * after we've finished processing all the lines in the original input file, we run through all\n * the LITERAL blocks in tblMacros and process the associated statement(s) at that time.\n *\n * Macros have the name that was assigned to them, REPEAT and conditional blocks have generated names\n * that match the pseudo-op (eg, \"?REPEAT\", \"?IFE\"), and LITERAL blocks have generated location-based\n * names. All generated names use a leading question mark ('?') so that they don't conflict with\n * normal MACRO-10 symbols.\n */\n\n /**\n * @type {Object.<Mac>}\n */\n this.tblMacros = {};\n\n /**\n * @type {Object.<Sym>}\n */\n this.tblSymbols = {};\n\n /**\n * @type {Array.<Lit>}\n */\n this.aLiterals = []; // array of literals\n\n /**\n * This keeps track of symbols suffixed with '#', which are later assembled into a variable pool,\n * following the literal pool.\n *\n * @type {Array.<string>}\n */\n this.aVariables = [];\n\n /**\n * @type {Array.<number>}\n */\n this.aWords = []; // filled in by the various genXXX() functions\n\n /**\n * This sparse array is indexed by location, and each used entry contains any undefined symbols that\n * must be evaluated to fully resolve the word at the corresponding location. NOTE: There's no requirement\n * that the array be sparse; we could certainly fill each unused entry with null (ie, for locations that\n * don't require a fixup).\n *\n * @type {Array.<string>}\n */\n this.aFixups = [];\n\n /**\n * This array parallels aFixups, providing context (ie, line numbers) for any fixups that we want to analyze.\n *\n * @type {Array.<number>}\n */\n this.aLineRefs = [];\n\n this.nLine = 0;\n this.nError = 0;\n this.nLiteral = 0; // used to uniquely number literals\n\n /**\n * @type {number}\n */\n this.nLocation = this.addrLoad || 0;\n\n /**\n * @type {number}\n */\n this.nLocationScope = -1;\n\n /**\n * @type {Array.<Scope>}\n */\n this.stackScopes = [];\n\n this.sOperator = null; // the active operator, if any\n this.nMacroDef = 0; // the active macro definition state\n this.sMacroDef = null; // the active macro definition name\n this.chMacroOpen = this.chMacroClose = '';\n\n /*\n * This regular expression breaks each MACRO-10 line into the following elements:\n *\n * [1]: label (with trailing colon), if any\n * [2]: operator (eg, opcode mnemonic or pseudo-op), if any\n * [3]: operator/operand whitespace separator, if any\n * [4]: operand(s), if any\n * [5]: comment, if any\n */\n this.reLine = /^[ \\t]*([A-Z$%.?][0-9A-Z$%.]*:|)[ \\t]*([A-Z$%.][0-9A-Z$%.]*|)([ \\t]*)([^;]+|)(;?[\\s\\S]*)/i;\n\n this.macroCall = null; // the active macro being called, if any\n\n /**\n * If an ASCII/ASCIZ/SIXBIT pseudo-op is active, chASCII is set to the separator\n * and sASCII collects the intervening character(s).\n *\n * @type {null|string}\n */\n this.chASCII = null;\n\n /**\n * @type {string}\n */\n this.sASCII = \"\";\n\n this.addrStart = null;\n }\n\n /**\n * assembleFiles(sURL, addrLoad, sOptions, done)\n *\n * Requests the resource(s) specified by sURL; multiple resources can be requested by separating\n * them with semicolons. The resources are requested and combined in the same order they are listed,\n * and after the last resource has been received, they are assembled as a single unit.\n *\n * As a courtesy to the Debugger's doAssemble() function, we allow it to select between assembleFiles()\n * and assembleString() by specifying an 's' option here, rather than having two separate code paths.\n *\n * @this {Macro10}\n * @param {string} sURL (the URL(s) of the resource to be assembled)\n * @param {number|null} [addrLoad] (the absolute address to assemble the code at, if any)\n * @param {string|undefined} [sOptions] (zero or more letter codes to control the assembly process)\n * @param {function(...)|undefined} [done]\n */\n assembleFiles(sURL, addrLoad, sOptions, done)\n {\n if (sOptions && sOptions.indexOf('s') >= 0) {\n this.assembleString(sURL, addrLoad, sOptions, done);\n return;\n }\n\n this.init(addrLoad, sOptions, done);\n\n this.aURLs = sURL.split(';');\n\n this.loadNextResource();\n }\n\n /**\n * assembleString(sText, addrLoad, sOptions, done)\n *\n * Assembles the given text.\n *\n * @this {Macro10}\n * @param {string} sText\n * @param {number|null} [addrLoad] (the absolute address to assemble the code at, if any)\n * @param {string|undefined} [sOptions] (zero or more letter codes to control the assembly process)\n * @param {function(...)|undefined} [done]\n * @return {number}\n */\n assembleString(sText, addrLoad, sOptions, done)\n {\n this.init(addrLoad, sOptions, done);\n\n this.asLines = sText.split(/(\\r?\\n)/);\n this.anLines.push(this.asLines.length);\n\n this.parseResources();\n\n if (this.done) this.done(this.nError);\n\n return this.nError;\n }\n\n /**\n * loadNextResource()\n *\n * @this {Macro10}\n */\n loadNextResource()\n {\n if (this.iURL == this.aURLs.length) {\n this.parseResources();\n if (this.done) this.done(this.nError);\n return;\n }\n\n var macro10 = this;\n var sURL = this.aURLs[this.iURL];\n\n this.println(\"loading \" + Str.getBaseName(sURL));\n\n /*\n * We know that local resources ending with \".MAC\" are actually stored with a \".txt\" extension.\n */\n if (sURL.indexOf(':') < 0) {\n var sExt = sURL.slice(-4).toUpperCase();\n if (\".MAC.KLM\".indexOf(sExt) >= 0) sURL += \".txt\";\n }\n\n Web.getResource(sURL, null, true, function processMacro10(sFile, sResource, nErrorCode) {\n if (nErrorCode) {\n if (macro10.done) macro10.done(nErrorCode, sFile);\n return;\n }\n var sText = sResource;\n if (Str.endsWith(sFile, \".html\")) {\n /*\n * We want to parse ONLY the text between <PRE>...</PRE> tags, and eliminate any HTML entities.\n */\n sText = \"\";\n var match, re = /<pre>([\\s\\S]*?)<\\/pre>/gi;\n while (match = re.exec(sResource)) {\n var s = match[1];\n if (s.indexOf('&') >= 0) s = s.replace(/</gi, '<').replace(/>/gi, '>').replace(/&/gi, '&');\n sText += s;\n }\n match = sText.match(/&[a-z]+;/i);\n if (match) macro10.warning(\"unrecognized HTML entity '\" + match[0] + \"'\");\n }\n\n /*\n * For a file containing N lines, split() will return an array of N*2+1 entries, with every even entry\n * containing the characters, if any, preceding a line-ending, and every odd entry (including the final\n * entry) containing a line-ending.\n *\n * If, for some reason, split() doesn't do that, then we try to warn and patch things up as best we can.\n */\n var asLines = sText.split(/(\\r?\\n)/);\n if (asLines.length & 1) {\n s = asLines.pop();\n if (s) {\n macro10.warning(\"unexpected line '\" + s + \"'\");\n asLines.push(s);\n asLines.push(\"\");\n }\n } else {\n macro10.warning(\"unexpected number of lines (\" + asLines.length + \")\");\n }\n\n macro10.asLines = macro10.asLines.concat(asLines);\n macro10.anLines[macro10.iURL] = (asLines.length >> 1);\n macro10.iURL++;\n\n setTimeout(function() {\n macro10.loadNextResource();\n }, 0);\n });\n }\n\n /**\n * getImage()\n *\n * Service for the Debugger to obtain the assembled data after a (hopefully) successful assembly process.\n *\n * @this {Macro10}\n * @return {Array.<number>}\n */\n getImage()\n {\n return this.aWords;\n }\n\n /**\n * getStart()\n *\n * Service for the Debugger to obtain the starting address after a (hopefully) successful assembly process.\n *\n * @this {Macro10}\n * @return {number|null|undefined}\n */\n getStart()\n {\n return this.addrStart;\n }\n\n /**\n * parseResources()\n *\n * Begin the assembly process.\n *\n * @this {Macro10}\n * @return {number}\n */\n parseResources()\n {\n var macro10 = this;\n\n /*\n * If the \"preprocess\" option is set, then print everything without assembling.\n */\n if (this.sOptions.indexOf('p') >= 0) {\n this.println(this.asLines.join(\"\"));\n return 0;\n }\n\n var a = this.dbg.resetVariables();\n\n /*\n * Add predefined device codes\n */\n this.addSymbol(\"APR\", 0); // Priority Interrupt\n this.addSymbol(\"PI\", 4); // Arithmetic Processor\n\n try {\n for (let i = 0; i < this.asLines.length; i += 2) {\n\n this.nLine++;\n\n /*\n * If the \"line\" option is set, then print all the lines as they are parsed.\n */\n if (this.sOptions.indexOf('l') >= 0) {\n this.println(this.getLineRef() + \": \" + this.asLines[i]);\n }\n\n /*\n * Since, at this early stage, I'm not sure whether all the resources I'm interested in\n * assembling have had their original CR/LF line endings preserved (eg, some files may have\n * been converted to LF-only line endings), I'm going to skip over whatever line endings\n * are in the array (stored in every OTHER entry) and insert my own uniform CR/LF sequences.\n */\n if (!this.parseLine(this.asLines[i] + '\\r\\n')) break;\n\n /*\n * When an END statement is encountered, addrStart will change from null to either undefined\n * or a starting address.\n */\n if (this.addrStart !== null) break;\n }\n\n if (this.nMacroDef) {\n this.error(\"open block\", this.tblMacros[this.sMacroDef].nLine);\n }\n\n if (this.stackScopes.length) {\n this.error(\"open scope\", this.stackScopes[0].nLine);\n }\n\n /*\n * Process all literals next.\n */\n this.doLiterals();\n\n /*\n * Process all variables next.\n */\n this.doVariables();\n\n /*\n * And last but not least, perform all fixups.\n */\n this.aFixups.forEach(function processFixup(sValue, nLocation) {\n let value = macro10.parseExpression(sValue, undefined, nLocation, macro10.aLineRefs[nLocation]);\n if (value === undefined) return;\n value += macro10.aWords[nLocation];\n macro10.aWords[nLocation] = macro10.truncate(value, nLocation);\n });\n\n } catch(err) {\n this.println(err.message);\n this.nError = -1;\n }\n\n if (this.sOptions.indexOf('d') < 0) this.dbg.restoreVariables(a);\n\n return this.nError;\n }\n\n /**\n * parseLine(sLine, aParms, aValues, aDefaults)\n *\n * @this {Macro10}\n * @param {string} sLine (line contents)\n * @param {Array.<string>} [aParms]\n * @param {Array.<string>} [aValues]\n * @param {Array.<string>} [aDefaults]\n * @return {boolean}\n */\n parseLine(sLine, aParms, aValues, aDefaults)\n {\n var i, matchLine;\n\n if (this.chASCII != null) {\n sLine = this.defASCII(sLine);\n }\n\n var fParse = true;\n var sLabel, sOperator = \"\", sSeparator, sOperands, sRemainder;\n\n while (fParse) {\n matchLine = sLine.match(this.reLine);\n if (!matchLine || matchLine[5] && matchLine[5].slice(0, 1) != ';') {\n this.error(\"failed to parse line '\" + sLine + \"'\");\n return false;\n }\n fParse = false;\n sOperator = matchLine[2].toUpperCase();\n\n /*\n * TODO: The following kludge needs to be fixed at some point. The goal here is to prevent any\n * of the caller's parameters from replacing any IRP/IRPC call parameters, but the goal is actually\n * much bigger than that, because it's not just IRP/IRPC call parameters that must be left intact,\n * but ANY macro call parameters; IRP/IRPC macros are just easier to pick out. Unfortunately, as\n * the code is currently structured, we won't know if we're dealing with any macro call parameters\n * on this line until parseMacro() is called, below.\n */\n if (sOperator == Macro10.PSEUDO_OP.IRP || sOperator == Macro10.PSEUDO_OP.IRPC) {\n aParms = null;\n }\n\n if (aParms) {\n for (var iParm = 0; iParm < aParms.length; iParm++) {\n var sParm = aParms[iParm];\n\n var macroDef = this.tblMacros[this.sMacroDef];\n if (macroDef && macroDef.aParms.indexOf(sParm) >= 0) continue;\n\n var sReplace = aValues[iParm] || aDefaults[iParm] || \"\";\n var iSearch = 0;\n var iLimit = sLine.length - matchLine[5].length; // set the limit at the start of the comment, if any\n while (iSearch < iLimit) {\n var iMatch = sLine.indexOf(sParm, iSearch);\n if (iMatch < 0) break;\n iSearch = iMatch + 1;\n var iMatchEnd = iMatch + sParm.length;\n var chPre = '', chPost = '';\n if ((!iMatch || !this.isSymbolChar(chPre = sLine[iMatch - 1])) && (iMatchEnd >= sLine.length || !this.isSymbolChar(chPost = sLine[iMatchEnd]))) {\n /*\n * If the \"concatenation character\" (') appears before (or after) the symbol being replaced, remove it.\n */\n if (chPre == \"'\") iMatch--;\n if (chPost == \"'\") iMatchEnd++;\n sLine = sLine.substr(0, iMatch) + sReplace + sLine.substr(iMatchEnd);\n iSearch = iMatch + sReplace.length;\n fParse = true;\n }\n }\n }\n aParms = null;\n }\n if (this.nMacroDef) {\n if (this.nMacroDef == 1) {\n i = sLine.indexOf(this.chMacroOpen);\n if (i >= 0) {\n this.nMacroDef++;\n sLine = sLine.substr(i+1);\n } else {\n this.error(\"expected \" + this.sOperator + \" definition in '\" + sLine + \"'\");\n }\n }\n if (this.nMacroDef > 1) {\n sLine = this.appendMacro(sLine);\n fParse = true;\n }\n if (this.nMacroDef) return true;\n }\n }\n\n sLabel = matchLine[1];\n sSeparator = matchLine[3];\n sOperands = matchLine[4].trim();\n sRemainder = matchLine[4] + matchLine[5];\n\n if (sLabel) {\n sLabel = sLabel.slice(0, -1);\n this.addSymbol(sLabel, this.nLocation, Macro10.SYMTYPE.LABEL);\n }\n\n var matchOp;\n if (sOperator && (matchOp = sOperands.match(/^([=:]+)(.*)/))) {\n var nType = 0;\n sLabel = sOperator;\n sOperator = matchOp[1];\n sOperands = matchOp[2];\n if (sOperator == '==') {\n nType |= Macro10.SYMTYPE.PRIVATE;\n }\n else if (sOperator == '=:') {\n nType |= Macro10.SYMTYPE.INTERNAL;\n }\n this.addSymbol(sLabel, sOperands, nType);\n sOperator = sOperands = \"\";\n }\n\n if (!sOperator && !sOperands) return true;\n\n this.sOperator = sOperator;\n\n /*\n * Check the operands for a literal. If the line contains and/or ends with a literal\n * we record it and replace it with an internal symbol. We assume only one literal per line,\n * especially since they can be open-ended (ie, continue for multiple lines).\n */\n var sLiteral = this.getLiteral(sOperands);\n if (sLiteral) {\n sOperands = sOperands.replace(sLiteral, this.defMacro(Macro10.PSEUDO_OP.LITERAL, this.getLiteral(sRemainder)));\n if (!sSeparator) sSeparator = \"\\t\";\n }\n\n /*\n * Check the operands for any reserved symbols (ie, symbols with a trailing '#', such as \"USER#\").\n */\n var sSymbol;\n while (sSymbol = this.getReserved(sOperands)) {\n sOperands = sOperands.replace(sSymbol, sSymbol.slice(0, -1));\n }\n\n if (!this.parseMacro(sOperator, sOperands)) {\n\n switch (sOperator) {\n case Macro10.PSEUDO_OP.ASCII:\n case Macro10.PSEUDO_OP.ASCIZ:\n case Macro10.PSEUDO_OP.SIXBIT:\n this.defASCII(sRemainder);\n break;\n\n case Macro10.PSEUDO_OP.BLOCK:\n this.defBLOCK(sOperands);\n break;\n\n case Macro10.PSEUDO_OP.BYTE:\n this.defBYTE(sOperands);\n break;\n\n case Macro10.PSEUDO_OP.END:\n this.defEND(sOperands);\n break;\n\n case Macro10.PSEUDO_OP.EXP:\n this.defWord(sOperands);\n break;\n\n case Macro10.PSEUDO_OP.LIT:\n this.doLiterals();\n break;\n\n case Macro10.PSEUDO_OP.LOC:\n this.defLocation(sOperands);\n break;\n\n case Macro10.PSEUDO_OP.VAR:\n this.doVariables();\n break;\n\n case Macro10.PSEUDO_OP.XWD:\n this.defXWD(sOperands);\n break;\n\n case Macro10.PSEUDO_OP.DEFINE:\n case Macro10.PSEUDO_OP.IF1:\n case Macro10.PSEUDO_OP.IFDEF:\n case Macro10.PSEUDO_OP.IFDIF:\n case Macro10.PSEUDO_OP.IFE:\n case Macro10.PSEUDO_OP.IFG:\n case Macro10.PSEUDO_OP.IFGE:\n case Macro10.PSEUDO_OP.IFIDN:\n case Macro10.PSEUDO_OP.IFL:\n case Macro10.PSEUDO_OP.IFLE:\n case Macro10.PSEUDO_OP.IFN:\n case Macro10.PSEUDO_OP.IFNDEF:\n case Macro10.PSEUDO_OP.IRP:\n case Macro10.PSEUDO_OP.IRPC:\n case Macro10.PSEUDO_OP.OPDEF:\n case Macro10.PSEUDO_OP.REPEAT:\n this.defMacro(sOperator, sRemainder);\n break;\n\n case Macro10.PSEUDO_OP.PURGE:\n this.delSymbols(sOperands);\n break;\n\n case Macro10.PSEUDO_OP.LALL: // TODO\n case Macro10.PSEUDO_OP.LIST: // TODO\n case Macro10.PSEUDO_OP.NOSYM: // TODO\n case Macro10.PSEUDO_OP.PAGE: // TODO\n case Macro10.PSEUDO_OP.SUBTTL: // TODO\n case Macro10.PSEUDO_OP.TITLE: // TODO\n case Macro10.PSEUDO_OP.XALL: // TODO\n case Macro10.PSEUDO_OP.XLIST: // TODO\n break;\n\n default:\n this.defWord(sOperator, sSeparator, sOperands);\n break;\n }\n }\n return true;\n }\n\n /**\n * parseLiteral(name, sText)\n *\n * This is like parseText() except that we set up a new scope, including new aWords and aFixups arrays.\n *\n * @this {Macro10}\n * @param {string} name\n * @param {string} sText\n */\n parseLiteral(name, sText)\n {\n this.pushScope(name);\n this.parseText(sText);\n this.popScope();\n }\n\n /**\n * parseMacro(name, sOperands)\n *\n * For OPDEF macros, the operands are opcode values rather than conventional macro parameter values.\n * As the MACRO-10 manual explains:\n *\n * Defines the symbol as an operator equivalent to expression, giving the symbol a fullword value.\n * When the operator is later used with operands, the accumulator fields are added, the indirect bits\n * are ORed, the memory addresses are added, and the index register addresses are added.\n *\n * EXAMPLE: OPDEF CAL [MOVE 1,@SYM(2)]\n * CAL 1,BOL(2)\n *\n * RESULT: MOVE 2,@SYM+BOL(4)\n *\n * The easiest thing to do is parse the OPDEF text, allowing it to generate its default \"fullword value\",\n * then parse the operands in their own scope, extract the bits generated from the operands, and merge them\n * into the generated OPDEF value.\n *\n * @this {Macro10}\n * @param {string} name\n * @param {string} [sOperands]\n * @return {boolean}\n */\n parseMacro(name, sOperands)\n {\n var macro = this.tblMacros[name];\n if (!macro) return false;\n\n if (sOperands != null) {\n /*\n * If this is an OPDEF, then a two-step process is required: generate the OPDEF's value, then parse\n * the operands and merge their bits with the OPDEF's bits.\n */\n if (macro.nOperand == Macro10.MACRO_OP.OPDEF) {\n\n var nLocation = this.nLocation;\n this.parseText(macro.sText);\n if (nLocation < this.nLocation) {\n\n /*\n * An OPDEF invocation *may* have operands, but it's not required to.\n */\n if (!sOperands) return true;\n\n this.pushScope();\n this.parseText(sOperands);\n var w = this.aWords[0];\n var sFixup = this.aFixups[0];\n this.popScope();\n if (w !== undefined) {\n this.aWords[nLocation] += (w & (PDP10.OPCODE.A_FIELD | PDP10.OPCODE.X_FIELD | PDP10.OPCODE.Y_FIELD));\n /*\n * We can't \"OR\" (|=) the I_FIELD bit into the target word, because it's a 36-bit value and bitwise\n * operators truncate to 32 bits, so we'll use addition, trusting that the field was initially zero.\n */\n\n this.aWords[nLocation] += (w & PDP10.OPCODE.I_FIELD);\n if (sFixup) {\n if (!this.aFixups[nLocation]) {\n this.aFixups[nLocation] = sFixup;\n } else {\n this.aFixups[nLocation] += '+' + sFixup;\n }\n }\n return true;\n }\n }\n\n /*\n * Either the OPDEF didn't generate any data OR the OPDEF's operands failed to evaluate.\n */\n this.error(\"OPDEF '\" + name + \"' (\" + sOperands + \") failed\");\n return false;\n }\n var macroPrev = this.macroCall;\n this.macroCall = macro;\n macro.aValues = this.getValues(sOperands, true);\n this.parseText(macro.sText, macro.aParms, macro.aValues, macro.aDefaults);\n /*\n * WARNING: Our simplistic approach to macro expansion and processing means that recursive macros\n * (such as the SHIFT macro in /apps/pdp10/tests/macro10/TEXT.MAC) could blow the stack. Nothing bad\n * should happen (other than a JavaScript stack limit exception aborting the assembly), but it begs\n * the question: did MACRO-10 perform any tail recursion optimizations or other tricks to prevent macros\n * from gobbling stack, or could they blow MACRO-10's stack just as easily?\n */\n this.macroCall = macroPrev;\n return true;\n }\n\n if (name[0] != '?') return false;\n\n var sOperator = name.substr(1);\n\n switch(sOperator) {\n case Macro10.PSEUDO_OP.IFE:\n case Macro10.PSEUDO_OP.IFDIF:\n case Macro10.PSEUDO_OP.IFNDEF:\n if (!macro.nOperand) {\n this.parseText(macro.sText);\n }\n break;\n\n case Macro10.PSEUDO_OP.IFG:\n if (macro.nOperand > 0) {\n this.parseText(macro.sText);\n }\n break;\n\n case Macro10.PSEUDO_OP.IFGE:\n if (macro.nOperand >= 0) {\n this.parseText(macro.sText);\n }\n break;\n\n case Macro10.PSEUDO_OP.IFL:\n if (macro.nOperand < 0) {\n this.parseText(macro.sText);\n }\n break;\n\n case Macro10.PSEUDO_OP.IFLE:\n if (macro.nOperand <= 0) {\n this.parseText(macro.sText);\n }\n break;\n\n case Macro10.PSEUDO_OP.IF1:\n case Macro10.PSEUDO_OP.IFN:\n case Macro10.PSEUDO_OP.IFDEF:\n case Macro10.PSEUDO_OP.IFIDN:\n if (macro.nOperand) {\n this.parseText(macro.sText);\n }\n break;\n\n case Macro10.PSEUDO_OP.IRP:\n case Macro10.PSEUDO_OP.IRPC:\n for (let i = 0; i < macro.aValues.length; i++) {\n this.parseText(macro.sText, macro.aParms, [macro.aValues[i]], []);\n }\n break;\n\n case Macro10.PSEUDO_OP.REPEAT:\n while (macro.nOperand-- > 0) {\n this.parseText(macro.sText);\n }\n break;\n\n default:\n this.parseLiteral(name, macro.sText);\n break;\n }\n return true;\n }\n\n /**\n * parseText(sText, aParms, aValues, aDefaults)\n *\n * @this {Macro10}\n * @param {string} sText\n * @param {Array.<string>} [aParms]\n * @param {Array.<string>} [aValues]\n * @param {Array.<string>} [aDefaults]\n */\n parseText(sText, aParms, aValues, aDefaults)\n {\n /*\n * Unlike the caller of parseResources(), we don't split the text using a capture group,\n * so all line separators are tossed, and just like parseResources(), we always include a\n * uniform CR/LF sequence at the end of each line.\n *\n * TODO: Consider whether callers should always store their text snippets as line arrays, too,\n * to avoid this re-splitting.\n */\n var asLines = sText.split(/\\r?\\n/);\n for (var iLine = 0; iLine < asLines.length; iLine++) {\n var sLine = asLines[iLine] + '\\r\\n';\n if (!this.parseLine(sLine, aParms, aValues, aDefaults)) break;\n }\n }\n\n /**\n * pushScope(name)\n *\n * @this {Macro10}\n * @param {string} [name] (must be defined for literals only)\n */\n pushScope(name)\n {\n this.stackScopes.push({\n name,\n aWords: this.aWords,\n aFixups: this.aFixups,\n nLocation: this.nLocation,\n nLocationScope: this.nLocationScope,\n nLine: this.nLine\n });\n this.aWords = [];\n this.aFixups = [];\n if (this.nLocationScope < 0) this.nLocationScope = this.nLocation;\n this.nLocation = 0;\n }\n\n /**\n * popScope()\n *\n * @this {Macro10}\n */\n popScope()\n {\n if (!this.stackScopes.length) {\n this.error(\"scope nesting error\");\n return;\n }\n var name = this.stackScopes[this.stackScopes.length - 1].name;\n if (name) this.aLiterals.push({name, aWords: this.aWords, aFixups: this.aFixups});\n var scope = this.stackScopes.pop();\n this.aWords = scope.aWords;\n this.aFixups = scope.aFixups;\n this.nLocation = scope.nLocation;\n this.nLocationScope = scope.nLocationScope;\n if (!this.stackScopes.length && this.nLocationScope != -1) {\n this.error(\"scope restore error\");\n }\n }\n\n /**\n * getExpression(sOperands, sDelim)\n *\n * TODO: Add support for IFIDN, IFDIF, IFB and IFNB: if the first non-blank, non-tab character is\n * a character other than '<', then that becomes the delimiter, allowing angle brackets in the string.\n *\n * @this {Macro10}\n * @param {string} sOperands\n * @param {string} [sDelim] (eg, comma, closing parenthesis)\n * @return {string|null} (if the operands begin with an expression, return it)\n */\n getExpression(sOperands, sDelim = \",\")\n {\n var i = 0;\n var fQuotes = false;\n var sOperand = null;\n var cNesting = 0;\n while (i < sOperands.length) {\n var ch = sOperands[i++];\n if (ch == '\"') {\n fQuotes = !fQuotes;\n continue;\n }\n if (fQuotes) continue;\n if (!cNesting && sDelim.indexOf(ch) >= 0) {\n i--;\n break;\n }\n if (ch == '<') {\n cNesting++;\n } else if (ch == '>') {\n if (--cNesting < 0) {\n this.error(\"missing bracket(s) in '\" + sOperands + \"'\");\n break;\n }\n }\n }\n if (!cNesting) {\n sOperand = sOperands.substr(0, i);\n }\n else if (cNesting > 0) {\n this.error(\"extra bracket(s) in '\" + sOperands + \"'\");\n }\n return sOperand;\n }\n\n /**\n * parseExpression(sExp, aUndefined, nLocation, nLine)\n *\n * This is a wrapper around the Debugger's parseExpression() function to take care of some\n * additional requirements we have, such as interpreting a period as the current location and\n * interpreting two expressions separated by two commas as the left and right 18-bit halves\n * of a 36-bit value.\n *\n * @this {Macro10}\n * @param {string} sExp\n * @param {Array|undefined} [aUndefined]\n * @param {number|undefined} [nLocation]\n * @param {number|undefined} [nLine]\n * @return {number|undefined}\n */\n parseExpression(sExp, aUndefined, nLocation, nLine)\n {\n var result = -1;\n\n if (nLocation === undefined) {\n nLocation = (this.nLocationScope >= 0? this.nLocationScope : this.nLocation);\n }\n\n /*\n * The SIXBIT (and presumably ASCII; not sure about ASCIZ) pseudo-ops can also be used in expressions\n * (or at least assignments), so we check for those in the given expression and convert them to quoted\n * sequences that the Debugger's parseExpression() understands.\n */\n var sEval = sExp.replace(/SIXBIT\\s*(\\S)(.*?)\\1/g, \"'$2'\").replace(/ASCII\\s*(\\S)(.*?)\\1/g, '\"$2\"');\n\n /*\n * If this is NOT a first-pass call, then let's not waste time calling parseInstruction(); not only\n * may it generate redundant error messages, but it shouldn't be necessary, because we should be down\n * to fixup expressions.\n */\n if (aUndefined) {\n var match;\n var sOperator = \"\";\n var sOperands = sEval;\n if (match = sEval.match(/^([^\\s]+)\\s*(.*?)\\s*$/)) {\n sOperator = match[1];\n sOperands = match[2];\n }\n result = this.dbg.parseInstruction(sOperator, sOperands, nLocation, aUndefined);\n }\n\n if (result < 0) {\n /*\n * Check for the \"period\" syntax that MACRO-10 uses to represent the value of the current location.\n * The Debugger's parseInstruction() method understands that syntax, but its parseExpression() method\n * does not.\n *\n * Note that the Debugger's parseInstruction() replaces any period not PRECEDED by a decimal\n * digit with the current address, because our Debuggers' only other interpretation of a period\n * is as the suffix of a decimal integer, whereas MACRO-10's only other interpretation of a period\n * is (I think) as the decimal point within a floating-point number, so here we only replace periods\n * that are not FOLLOWED by a decimal digit.\n */\n sEval = sEval.replace(/\\.([^0-9]|$)/g, this.dbg.toStrBase(nLocation, -1) + \"$1\");\n result = this.dbg.parseExpression(sEval, aUndefined);\n if (result === undefined) {\n this.error(\"unable to parse expression '\" + sExp + \"'\", nLine);\n }\n }\n return result;\n }\n\n /**\n * getLiteral(sOperands)\n *\n * Check the operands for a literal (ie, an expression starting with a square bracket).\n *\n * @this {Macro10}\n * @param {string} sOperands\n * @return {string} (if the operands contain a literal, return it)\n */\n getLiteral(sOperands)\n {\n var cNesting = 0;\n var sLiteral = \"\";\n var i = 0, iBegin = -1, iEnd = sOperands.length;\n while (i < sOperands.length) {\n var ch = sOperands[i];\n if (ch == ';') break;\n if (ch == '[') {\n if (!cNesting++) iBegin = i;\n }\n i++;\n if (ch == ']' && --cNesting <= 0) {\n iEnd = i;\n break;\n }\n }\n if (cNesting < 0) {\n this.error(\"missing bracket(s) in '\" + sOperands + \"'\");\n }\n if (iBegin >= 0) {\n sLiteral = sOperands.substr(iBegin, iEnd - iBegin);\n }\n return sLiteral;\n }\n\n /**\n * getDefaults(aParms)\n *\n * Check the given array of macro parameters for default values, remove them, and return them in a parallel array.\n *\n * @this {Macro10}\n * @param {Array.<string>} aParms\n * @return {Array.<string>}\n */\n getDefaults(aParms)\n {\n var aDefaults = [];\n for (var i = 0; i < aParms.length; i++) {\n var j = aParms[i].indexOf('<');\n if (j >= 0) {\n var k = aParms[i].lastIndexOf('>');\n if (k < 0) k = aParms[i].length;\n aDefaults[i] = aParms[i].substr(j, k - j);\n aParms[i] = aParms[i].substr(0, j);\n }\n }\n return aDefaults;\n }\n\n /**\n * getLineRef(nLine)\n *\n * @this {Macro10}\n * @param {number|undefined} [nLine]\n * @return {string}\n */\n getLineRef(nLine = this.nLine)\n {\n var iURL = 0;\n while (nLine > this.anLines[iURL]) {\n nLine -= this.anLines[iURL];\n if (iURL < this.aURLs.length - 1) {\n iURL++;\n } else {\n break;\n }\n }\n return Str.getBaseName(this.aURLs[iURL] + \" line \" + nLine);\n }\n\n /**\n * getReserved(sOperands)\n *\n * Check the operands for any reserved symbols (ie, symbols with a trailing '#', such as \"USER#\").\n *\n * @this {Macro10}\n * @param {string} sOperands\n * @return {string|null} (if the operands contain a reserved symbol, return it)\n */\n getReserved(sOperands)\n {\n var match, sReserved = null;\n if (match = sOperands.match(/([A-Z$%.][0-9A-Z$%.]*)#/i)) {\n sReserved = match[0];\n var sLabel = match[1];\n var name = '?' + sLabel;\n /*\n * We now allow reserved symbols to reused (which would make sense if they appeared in a macro).\n */\n if (this.tblMacros[name] === undefined) {\n var aParms, aDefaults, aValues;\n aParms = aDefaults = aValues = [];\n this.tblMacros[name] = {\n name: name,\n nOperand: Macro10.MACRO_OP.RESERVED,\n aParms,\n aDefaults,\n aValues,\n sText: sLabel + \": 0\",\n nLine: this.nLine\n };\n this.aVariables.push(name);\n }\n }\n return sReserved;\n }\n\n /**\n * getString(sValue, nConversion)\n *\n * Converts the given expression string (sValue) to one of the following, based on the conversion code (nConversion):\n *\n * 0: numeric string (default)\n * 1: SIXBIT string\n * 2: ASCII string\n *\n * If the expression cannot be evaluated, or if the requested conversion isn't recognized, the original value is returned.\n *\n * @this {Macro10}\n * @param {string} sValue\n * @param {number} [nConversion]\n * @return {string}\n */\n getString(sValue, nConversion = 0)\n {\n var c, s;\n var value = this.parseExpression(sValue);\n if (value !== undefined) {\n var cchMax = 5;\n switch(nConversion) {\n case 0:\n sValue = this.dbg.toStrBase(value, -1);\n break;\n case 6:\n cchMax++;\n /* falls through */\n case 7:\n s = \"\";\n while (value && cchMax--) {\n c = value & (Math.pow(2, nConversion) - 1);\n s = String.fromCharCode(c + (nConversion == 6? 0x20 : 0)) + s;\n value = Math.trunc(value / Math.pow(2, nConversion));\n }\n break;\n }\n }\n return sValue;\n }\n\n /**\n * getSymbol(sOperands)\n *\n * Check the operands for a symbol. TODO: Use this method?\n *\n * @this {Macro10}\n * @param {string} sOperands\n * @return {string|null} (if the operands contain a symbol, return it)\n */\n getSymbol(sOperands)\n {\n var match = sOperands.match(/([A-Z$%.][0-9A-Z$%.]*)/i);\n return match && match[1] || null;\n }\n\n /**\n * getValues(sOperands, fParens)\n *\n * @this {Macro10}\n * @param {string} sOperands\n * @param {boolean} [fParens] (true to strip any parens from around the entire operands)\n * @return {Array.<string>}\n */\n getValues(sOperands, fParens)\n {\n var aValues = [];\n if (fParens) sOperands = sOperands.replace(/^\\(?(.*?)\\)?$/, \"$1\");\n while (sOperands) {\n sOperands = sOperands.trim();\n var sOperand = this.getExpression(sOperands);\n if (!sOperand) break;\n var sValue = sOperand;\n if (sOperand[0] == '\\\\') {\n var cchPrefix = 1;\n var nConversion = 0;\n if (sOperand[1] == \"'\") {\n cchPrefix++;\n nConversion = 6;\n } else if (sOperand[1] == '\"') {\n cchPrefix++;\n nConversion = 7;\n }\n sValue = this.getString(sOperand.substr(cchPrefix), nConversion);\n }\n aValues.push(sValue);\n sOperands = sOperands.substr(sOperand.length + 1);\n }\n return aValues;\n }\n\n /**\n * isDefined(sName)\n *\n * @this {Macro10}\n * @param {string} sName\n * @return {boolean}\n */\n isDefined(sName)\n {\n return this.isMacro(sName) || this.isSymbol(sName) || this.dbg.isVariable(sName);\n }\n\n /**\n * isMacro(sName)\n *\n * @this {Macro10}\n * @param {string} sName\n * @return {boolean}\n */\n isMacro(sName)\n {\n return this.tblMacros[sName] !== undefined;\n }\n\n /**\n * isSymbol(sName)\n *\n * @this {Macro10}\n * @param {string} sName\n * @return {boolean}\n */\n isSymbol(sName)\n {\n return this.tblSymbols[sName] !== undefined;\n }\n\n /**\n * isSymbolChar(ch)\n *\n * @this {Macro10}\n * @param {string} ch\n * @return {boolean}\n */\n isSymbolChar(ch)\n {\n return !!ch.match(/[0-9A-Z$%.]/i);\n }\n\n /**\n * defASCII(sOperands)\n *\n * @this {Macro10}\n * @param {string} sOperands\n * @return {string} (returns whatever portion of the string was not part of an ASCII pseudo-op)\n */\n defASCII(sOperands)\n {\n var sRemain = sOperands;\n if (this.chASCII == null) {\n this.chASCII = this.sASCII = \"\";\n if (sOperands) {\n this.chASCII = sOperands[0];\n sRemain = sOperands = sOperands.substr(1);\n }\n }\n if (this.chASCII) {\n var i = sOperands.indexOf(this.chASCII);\n if (i < 0) {\n sRemain = \"\";\n } else {\n sRemain = sOperands.substr(i + 1);\n sOperands = sOperands.substr(0, i);\n this.chASCII = null;\n }\n this.sASCII += sOperands;\n }\n if (this.chASCII == null) {\n this.genASCII();\n }\n return sRemain;\n }\n\n /**\n * defMacro(sOperator, sOperands)\n *\n * If sOperator is DEFINE (or OPDEF), then a macro definition is expected. If it's REPEAT, then we're\n * starting a REPEAT block instead.\n *\n * REPEAT blocks piggy-back on this code because they're essentially anonymous immediately-invoked macros;\n * we use an illegal MACRO-10 symbol ('?REPEAT') to name the anonymous macro while it's being defined, and the\n * macro's nOperand field will contain the repeat count.\n *\n * The piggy-backing continues with other pseudo-ops like IFE, which again contain an anonymous block of text\n * that is immediately invoked if the criteria associated with the expression stored in the nOperand field is\n * satisfied. That satisfaction occurs (or doesn't occur) when parseMacro() is called, once the macro has\n * been fully defined.\n *\n * @this {Macro10}\n * @param {string} sOperator\n * @param {string} sOperands\n * @return {string}\n */\n defMacro(sOperator, sOperands)\n {\n var i, match, name, nOperand, aParms, aDefaults, aValues, iMatch;\n\n this.chMacroOpen = '<';\n this.chMacroClose = '>';\n aParms = aDefaults = aValues = [];\n\n if (sOperator == Macro10.PSEUDO_OP.DEFINE) {\n /*\n * This is a DEFINE (macro) block. At present, this requires that all\n * (parenthesized) parameters exist on the same line, but the (angle-bracketed)\n * definition can continue on for multiple lines.\n */\n match = sOperands.match(/([A-Z$%.][0-9A-Z$%.]*)\\s*(\\([^)]*\\)|)\\s*,?\\s*(<|)([\\s\\S]*)/i);\n if (!match) {\n this.error(\"unrecognized \" + sOperator + \" in '\" + sOperands + \"'\");\n return sOperands;\n }\n name = match[1];\n /*\n * If this macro has defined parameters, parse them (and any defaults) now.\n */\n if (match[2] && match[2] != ',') {\n aParms = this.getValues(match[2], true);\n aDefaults = this.getDefaults(aParms);\n }\n nOperand = Macro10.MACRO_OP.DEFINE;\n iMatch = 3;\n }\n else if (sOperator == Macro10.PSEUDO_OP.OPDEF) {\n /*\n * This is a OPDEF block. Unlike DEFINE blocks, I'm assuming that the\n * (square-bracketed) definition begins on the same line, but I'm not requiring\n * it to end on the same line (I'm not sure that MACRO-10 allowed multi-line\n * OPDEFs, but it doesn't matter to us).\n */\n this.chMacroOpen = '[';\n this.chMacroClose = ']';\n match = sOperands.match(/([A-Z$%.][0-9A-Z$%.]*)\\s*(\\[)([\\s\\S]*)/i);\n if (!match) {\n this.error(\"unrecognized \" + sOperator + \" in '\" + sOperands + \"'\");\n return sOperands;\n }\n name = match[1];\n nOperand = Macro10.MACRO_OP.OPDEF;\n iMatch = 2;\n }\n else if (sOperator == Macro10.PSEUDO_OP.LITERAL) {\n /*\n * This is a LITERAL block.\n */\n this.chMacroOpen = '[';\n this.chMacroClose = ']';\n name = '?' + Str.toDec(++this.nLiteral, 5);\n if (this.tblMacros[name] !== undefined) {\n this.error(\"literal symbol '\" + name + \"' redefined\");\n }\n match = [sOperands[0], sOperands.substr(1)];\n nOperand = Macro10.MACRO_OP.LITERAL;\n iMatch = 0;\n }\n else if (sOperator == Macro10.PSEUDO_OP.IRP || sOperator == Macro10.PSEUDO_OP.IRPC) {\n /*\n * IRP (and IRPC) blocks are very similar to DEFINE blocks, but they define exactly ONE macro parameter\n * with NO parentheses (whereas regular macros always define their parameters, if any, WITH parentheses),\n * and then the IRP (or IRPC) block is immediately invoked with the corresponding value from the\n * enclosing macro.\n */\n if (!this.macroCall) {\n this.error(sOperator + \" outside of macro\");\n }\n match = sOperands.match(/([A-Z$%.][0-9A-Z$%.]*)\\s*,\\s*(<|)([\\s\\S]*)/i);\n if (!match) {\n this.error(\"unrecognized \" + sOperator + \" operands '\" + sOperands + \"'\");\n return sOperands;\n }\n for (i = 0; i < this.macroCall.aParms.length; i++) {\n if (match[1] == this.macroCall.aParms[i]) break;\n }\n if (i == this.macroCall.aParms.length) {\n this.error(\"invalid \" + sOperator + \" parameter '\" + match[1] + \"'\");\n return sOperands;\n }\n name = '?' + sOperator;\n aParms = [match[1]];\n if (sOperator == Macro10.PSEUDO_OP.IRPC) {\n aValues = this.macroCall.aValues[i].split(\"\");\n } else {\n aValues = this.getValues(this.macroCall.aValues[i]);\n }\n nOperand = aValues.length;\n iMatch = 2;\n }\n else {\n /*\n * This must be a REPEAT or CONDITIONAL block.\n */\n if (sOperator == Macro10.PSEUDO_OP.IF1) {\n nOperand = 1;\n if (sOperands[0] == ',') sOperands = sOperands.substr(1).trim();\n }\n else {\n var sOperand = this.getExpression(sOperands);\n if (!sOperand) {\n this.error(\"missing \" + sOperator + \" expression '\" + sOperands + \"'\");\n return sOperands;\n }\n sOperands = sOperands.substr(sOperand.length + 1);\n sOperand = sOperand.trim();\n if (sOperator == Macro10.PSEUDO_OP.IFDIF || sOperator == Macro10.PSEUDO_OP.IFIDN) {\n var sOperand2 = this.getExpression(sOperands);\n if (!sOperand2) {\n this.error(\"missing second \" + sOperator + \" expression '\" + sOperands + \"'\");\n return sOperands;\n }\n sOperands = sOperands.substr(sOperand2.length + 1);\n sOperand2 = sOperand2.trim();\n nOperand = (sOperand == sOperand2)? 1 : 0;\n }\n if (sOperator == Macro10.PSEUDO_OP.IFDEF || sOperator == Macro10.PSEUDO_OP.IFNDEF) {\n nOperand = this.isDefined(sOperand)? 1 : 0;\n } else {\n /*\n * The expression is either a repeat count or a condition. Either way, we must be able to\n * resolve it now, so we don't set fPass1 (but that doesn't mean it's the second pass, either).\n */\n nOperand = this.parseExpression(sOperand) || 0;\n }\n }\n match = sOperands.match(/\\s*(<|)([\\s\\S]*)/i);\n name = '?' + sOperator;\n iMatch = 1;\n }\n\n /*\n * Now we need to set a global parsing state: we are either about to receive a macro definition on\n * subsequent lines (1), the definition has already started on the current line (2), or the definition\n * started and ended on the current line (0).\n */\n name = name.toUpperCase();\n this.nMacroDef = 1;\n this.sMacroDef = name;\n this.tblMacros[name] = {name, nOperand, aParms, aDefaults, aValues, sText: \"\", nLine: this.nLine};\n\n if (match[iMatch]) { // if there is an opening bracket\n this.nMacroDef = 2; // then the macro definition has started\n this.appendMacro(match[iMatch + 1]);\n }\n\n return name;\n }\n\n /**\n * appendMacro(sLine)\n *\n * @this {Macro10}\n * @param {string} sLine\n * @return {string}\n */\n appendMacro(sLine)\n {\n var sRemain = \"\";\n for (var i = 0; i < sLine.length; i++) {\n if (sLine[i] == this.chMacroOpen) {\n this.nMacroDef++;\n } else if (sLine[i] == this.chMacroClose) {\n this.nMacroDef--;\n if (this.nMacroDef == 1) {\n this.nMacroDef = 0;\n sRemain = sLine.substr(i + 1);\n sLine = sLine.substr(0, i);\n break;\n }\n }\n }\n var name = this.sMacroDef || \"\";\n this.tblMacros[name].sText += sLine;\n if (!this.nMacroDef) {\n this.sMacroDef = null;\n this.parseMacro(name);\n }\n return sRemain;\n }\n\n /**\n * addSymbol(name, value, nType)\n *\n * @this {Macro10}\n * @param {string} name\n * @param {number|string} value\n * @param {number} [nType]\n */\n addSymbol(name, value, nType = 0)\n {\n name = name.toUpperCase().substr(0, 6);\n if ((nType & Macro10.SYMTYPE.LABEL) && this.tblSymbols[name] !== undefined) {\n this.error(\"redefined label '\" + name + \"'\");\n return;\n }\n var sUndefined = undefined;\n if (typeof value == 'string') {\n var aUndefined = [];\n var v = this.parseExpression(value, aUndefined);\n if (v === undefined) {\n this.error(\"invalid symbol '\" + name + \"': \" + value);\n return;\n }\n if (aUndefined.length > 1) {\n this.error(\"too many undefined symbols in '\" + name + \"': \" + aUndefined.join());\n }\n value = v;\n sUndefined = aUndefined[0];\n }\n var sym = this.tblSymbols[name];\n if (sym) {\n sym.value = value;\n sym.nType = nType;\n sym.nLine = this.nLine;\n } else {\n this.tblSymbols[name] = {name, value, nType, nLine: this.nLine};\n }\n this.dbg.setVariable(name, value, sUndefined);\n }\n\n /**\n * defBLOCK()\n *\n * Processes the BLOCK pseudo-op.\n *\n * @this {Macro10}\n * @param {string} sOperands\n */\n defBLOCK(sOperands)\n {\n var w = this.parseExpression(sOperands);\n if (w !== undefined && w >= 0 && w <= 0o777777) {\n this.nLocation += w; // while (w--) this.genWord(0);\n } else {\n this.error(\"unrecognized BLOCK expression '\" + sOperands + \"'\");\n }\n }\n\n /**\n * defBYTE()\n *\n * Processes the BYTE pseudo-op.\n *\n * @this {Macro10}\n * @param {string} sOperands\n */\n defBYTE(sOperands)\n {\n var sOperand;\n var nBits = 0, nValue = 0, nBitsRemaining = 36;\n\n while (sOperand = this.getExpression(sOperands)) {\n sOperands = sOperands.substr(sOperand.length).trim();\n var sValue = sOperand;\n var match = sOperand.match(/^\\((.*)\\)\\s*(.*)$/);\n if (match) {\n if (match[1]) nBits = this.parseExpression(\"^D\" + match[1]);\n sValue = match[2];\n }\n if (!nBits) {\n /*\n * According the the 1978 MACRO-10 spec, \"If the byte size is 0 or is missing (empty parentheses), a zero word\n * is generated.\" I'm not clear exactly on how to interpret this, so I'll make a simplistic assumption for now.\n */\n this.genWord(0);\n continue;\n }\n var v = sValue? this.parseExpression(sValue) : 0;\n if (v === undefined || nBits < 0 || nBits > 36) {\n this.error(\"unexpected BYTE operand: \" + sOperand);\n break;\n }\n v = this.dbg.truncate(v, nBits, true);\n if (nBitsRemaining < nBits) {\n this.genWord(nValue);\n nValue = 0;\n nBitsRemaining = 36;\n }\n nValue += v * Math.pow(2, nBitsRemaining - nBits);\n nBitsRemaining -= nBits;\n }\n if (nBitsRemaining < 36) {\n this.genWord(nValue);\n }\n }\n\n /**\n * defEND()\n *\n * Processes the END pseudo-op.\n *\n * @this {Macro10}\n * @param {string} sOperands\n */\n defEND(sOperands)\n {\n if (!sOperands) {\n this.addrStart = this.addrLoad;\n } else {\n this.addrStart = this.parseExpression(sOperands);\n if (this.addrStart === undefined) {\n this.error(\"unrecognized END expression '\" + sOperands + \"'\");\n }\n }\n }\n\n /**\n * defLocation(sOperands)\n *\n * Processes the LOC pseudo-op.\n *\n * @this {Macro10}\n * @param {string} sOperands\n */\n defLocation(sOperands)\n {\n this.nLocation = this.parseExpression(sOperands) || 0;\n }\n\n /**\n * defXWD()\n *\n * Processes the XWD pseudo-op.\n *\n * Since the XWD pseudo-op appears to be equivalent to two values separated by two commas, which defWord() must also\n * support, we can piggy-back on defWord().\n *\n * @this {Macro10}\n * @param {string} sOperands\n */\n defXWD(sOperands)\n {\n this.defWord(sOperands.replace(\",\", \",,\"));\n }\n\n /**\n * defWord(sOperator, sSeparator, sOperands)\n *\n * @this {Macro10}\n * @param {string} sOperator\n * @param {string} [sSeparator]\n * @param {string} [sOperands]\n */\n defWord(sOperator, sSeparator = \"\", sOperands = \"\")\n {\n var aUndefined = [];\n var sExp = (sOperator + sSeparator + sOperands).trim();\n var w = this.parseExpression(sExp, aUndefined);\n if (w !== undefined) {\n if (!aUndefined.length) {\n this.genWord(w);\n } else if (aUndefined.length == 1) {\n this.genWord(w, aUndefined[0]);\n }\n else {\n this.genWord(0, sExp);\n }\n } else {\n this.error(\"unrecognized word expression '\" + sExp + \"'\");\n }\n }\n\n /**\n * delSymbols(sOperands)\n *\n * @this {Macro10}\n * @param {string} sOperands\n */\n delSymbols(sOperands)\n {\n var aValues = this.getValues(sOperands);\n for (var i = 0; i < aValues.length; i++) {\n this.dbg.delVariable(aValues[i]);\n delete this.tblSymbols[aValues[i]];\n }\n }\n\n /**\n * doLiterals()\n *\n * @this {Macro10}\n */\n doLiterals()\n {\n let nLocationLiterals = this.nLocation;\n\n for (let i = 0; i < this.aLiterals.length; i++) {\n /*\n * Apparently, the time has come to implement \"literal collapsing\"; I was treating it as just\n * a nice optimization, but it turns out that DEC has written tests that actually DEPEND on it:\n *\n * C26300: HRRZI [135531,,246642] ;PRELOAD AC0 WITH 0,, LITERAL ADDRESS\n * JRA .+1 ;*JRA SHOULD PLACE C(AC0) INTO AC0\n * CAIE [135531,,246642] ;PASS IF JRA PLACED C(AC0) INTO AC0\n * STOP\n *\n * If the HRRZI and CAIE instructions don't refer to the same exact literal, the test will fail.\n * For purposes of this particular test, the values they stuffed into the literals are essentially\n * gibberish, but the same literal may be used in another test where the values are significant.\n *\n * However, I'm still going to keep it simple. In this example from p. 2-8 of the April 1978\n * MACRO-10 manual, I will NOT be attempting to collapse null words at the end of ASCIZ sequences\n * with other null words, especially if they were defined before the ASCIZ:\n *\n * Literals having the same value are collapsed in MACRO's literal pool.\n * Thus for the statements:\n *\n * PUSH P,[0]\n * PUSH P,[0]\n * MOVEI 1,[ASCIZ /TEST1/]\n *\n * the same address is shared by the two literals [0], and by the null word\n * generated at the end of [ASCIZ /TEST1/].\n */\n let lit = this.aLiterals[i];\n /*\n * First things first: verify that the literal is one contiguous zero-based set of words (I'm not sure\n * how it couldn't be, but better safe than sorry).\n */\n let aWords = [];\n let nWords = 0;\n lit.aWords.forEach(function(w, nLocation) {\n if (nLocation === aWords.length) aWords.push(w);\n nWords++;\n });\n if (nWords == aWords.length) {\n /*\n * So far, so good. Now we'll simply brute-force-search our way through the existing set of\n * literals, looking for a complete match.\n */\n for (let nLocation = nLocationLiterals; nLocation + nWords <= this.nLocation; nLocation++) {\n let n;\n for (n = 0; n < nWords; n++) {\n /*\n * This check requires that the initial values of the words in the literals match AND that\n * their fixup expressions, if any, match as well. Here again, MACRO-10 may be more aggressive\n * in either verifying fixup equality or evaluating any fixups that it can immediately, but\n * but I prefer to leave all fixup evaluation where it is (below), after all literals and then\n * all variables have been added to the output.\n */\n if (aWords[n] !== this.aWords[nLocation + n] || lit.aFixups[n] != this.aFixups[nLocation]) break;\n }\n if (n == nWords) {\n this.addSymbol(lit.name, nLocation, Macro10.SYMTYPE.LABEL);\n lit = null;\n break;\n }\n }\n }\n if (lit) {\n var macro10 = this;\n this.addSymbol(lit.name, this.nLocation, Macro10.SYMTYPE.LABEL);\n lit.aWords.forEach(function(w, nLocation) {\n macro10.genWord(w, lit.aFixups[nLocation]);\n });\n }\n }\n this.aLiterals = [];\n }\n\n /**\n * doVariables()\n *\n * @this {Macro10}\n */\n doVariables()\n {\n for (let i = 0; i < this.aVariables.length; i++) {\n let name = this.aVariables[i];\n let macro = this.tblMacros[name];\n if (!macro) {\n /*\n * This is more of an assert(), because it should never happen, regardless of input.\n */\n this.error(\"missing definition for variable '\" + name + \"'\");\n continue;\n }\n this.parseText(macro.sText);\n }\n this.aVariables = [];\n }\n\n /**\n * genASCII()\n *\n * Based on the last operator, generate the appropriate ASCII/ASCIZ/SIXBIT data.\n *\n * @this {Macro10}\n */\n genASCII()\n {\n var n = 0, w = 0; // number of characters in current word, and current word\n var bits, shift; // bits per character, and bits to left-shift next character\n var cch = this.sASCII.length;\n if (this.sOperator == Macro10.PSEUDO_OP.ASCIZ) cch++;\n for (var i = 0; i < cch; i++) {\n if (!n) {\n w = 0; shift = 29; bits = 7;\n if (this.sOperator == Macro10.PSEUDO_OP.SIXBIT) {\n bits--; shift++;\n }\n }\n /*\n * If we're processing an ASCIZ pseudo-op, then yes, we will fetch one character beyond\n * the end of sASCII, which will return NaN, but when we mask a falsey value like NaN, we\n * get zero, so it's all good.\n */\n var c = this.sASCII.charCodeAt(i) & 0o177;\n /*\n * If we're doing 6-bit encoding, then perform the conversion of lower-case to upper-case,\n * and then adjust/mask.\n */\n if (bits == 6) {\n if (c >= 0x61 && c <= 0x7A) c -= 0x20;\n c = (c + 0o40) & 0o77;\n }\n w += c * Math.pow(2, shift);\n shift -= bits;\n n++;\n if (shift < 0) {\n this.genWord(w);\n n = 0;\n }\n }\n if (n) this.genWord(w);\n }\n\n /**\n * genWord(value, sUndefined)\n *\n * @this {Macro10}\n * @param {number} value (default value for the current location)\n * @param {string} [sUndefined] (optional fixup to evaluate later)\n */\n genWord(value, sUndefined)\n {\n this.aWords[this.nLocation] = this.truncate(value);\n if (sUndefined !== undefined) this.aFixups[this.nLocation] = sUndefined;\n this.aLineRefs[this.nLocation] = this.nLine;\n this.nLocation++;\n }\n\n /**\n * truncate(value, nLocation)\n *\n * @this {Macro10}\n * @param {number} value\n * @param {number} [nLocation]\n * @return {number}\n */\n truncate(value, nLocation = this.nLocation)\n {\n var w = this.dbg.truncate(value || 0, 36, true);\n if (value < -PDP10.INT_LIMIT || value >= PDP10.WORD_LIMIT) {\n this.warning(\"truncated value \" + Str.toOct(value) + \" at location \" + Str.toOct(nLocation) + \" to \" + Str.toOct(w));\n }\n return w;\n }\n\n /**\n * error(sError, nLine)\n *\n * @this {Macro10}\n * @param {string} sError\n * @param {number} [nLine]\n * @throws {Error}\n */\n error(sError, nLine)\n {\n throw new Error(\"error in \" + this.getLineRef(nLine) + \": \" + sError);\n }\n\n /**\n * warning(sWarning, nLine)\n *\n * @this {Macro10}\n * @param {string} sWarning\n * @param {number} [nLine]\n */\n warning(sWarning, nLine)\n {\n this.println(\"warning in \" + this.getLineRef(nLine) + \": \" + sWarning);\n }\n\n /**\n * println(s)\n *\n * @this {Macro10}\n * @param {string} s\n */\n println(s)\n {\n if (!this.dbg) {\n console.log(s);\n } else {\n this.dbg.println(s);\n }\n }\n}\n\nMacro10.SYMTYPE = {\n LABEL: 0x01,\n PRIVATE: 0x02,\n INTERNAL: 0x04\n};\n\nMacro10.PSEUDO_OP = {\n ASCII: \"ASCII\",\n ASCIZ: \"ASCIZ\",\n BLOCK: \"BLOCK\",\n BYTE: \"BYTE\",\n DEFINE: \"DEFINE\",\n END: \"END\",\n EXP: \"EXP\",\n IF1: \"IF1\",\n IFDEF: \"IFDEF\",\n IFDIF: \"IFDIF\",\n IFE: \"IFE\",\n IFG: \"IFG\",\n IFGE: \"IFGE\",\n IFIDN: \"IFIDN\",\n IFL: \"IFL\",\n IFLE: \"IFLE\",\n IFN: \"IFN\",\n IFNDEF: \"IFNDEF\",\n IRP: \"IRP\",\n IRPC: \"IRPC\",\n LALL: \"LALL\",\n LIT: \"LIT\",\n LITERAL: \"LITERAL\", // this is a pseudo-pseudo-op, for internal use only\n LIST: \"LIST\",\n LOC: \"LOC\",\n NOSYM: \"NOSYM\",\n OPDEF: \"OPDEF\",\n PAGE: \"PAGE\",\n PURGE: \"PURGE\",\n REPEAT: \"REPEAT\",\n SIXBIT: \"SIXBIT\",\n SUBTTL: \"SUBTTL\",\n TITLE: \"TITLE\",\n VAR: \"VAR\",\n XALL: \"XALL\",\n XWD: \"XWD\",\n XLIST: \"XLIST\"\n};\n\n/*\n * This enumerates the kinds of macros stored in tblMacros. The nOperand field should contain\n * one of these values, unless it's a REPEAT or CONDITIONAL block, in which case it will contain\n * either a repeat count or conditional value.\n */\nMacro10.MACRO_OP = {\n DEFINE: -1,\n OPDEF: -2,\n LITERAL: -3,\n RESERVED: -4,\n};\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/computer.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass ComputerPDP10 extends Component {\n /**\n * ComputerPDP10(parmsComputer, parmsMachine, fSuspended)\n *\n * The ComputerPDP10 component has no required (parmsComputer) properties, but it does\n * support the following:\n *\n * autoPower: true to automatically power the computer (default), false to wait;\n * false is honored only if a \"power\" button binding exists.\n *\n * busWidth: number of memory address lines (address bits) on the computer's \"bus\";\n * 20 is the minimum (and the default), which implies 8086/8088 real-mode addressing,\n * while 24 is required for 80286 protected-mode addressing. This value is passed\n * directly through to the Bus component; see that component for more details.\n *\n * resume: one of the ComputerPDP10.RESUME constants, which are as follows:\n * '0' if resume disabled (default)\n * '1' if enabled without prompting\n * '2' if enabled with prompting\n * '3' if enabled with prompting and auto-delete\n * or a string containing the path of a predefined JSON-encoded state\n *\n * state: the path to JSON-encoded state file (see details regarding 'state' below)\n *\n * The parmsMachine object, if provided, may contain any of:\n *\n * autoMount: if set, this should override any 'autoMount' property in the FDC's\n * parmsFDC object.\n *\n * autoPower: if set, this should override any 'autoPower' property in the ComputerPDP10's\n * parmsComputer object.\n *\n * messages: if set, this should override any 'messages' property in the Debugger's\n * parmsDbg object.\n *\n * state: if set, this should override any 'state' property in the ComputerPDP10's\n * parmsComputer object.\n *\n * url: the location of the machine XML file\n *\n * If a predefined state is supplied AND it's successfully loaded, then resume behavior\n * defaults to '1' (ie, resume enabled without prompting).\n *\n * This component insures that all components are ready before \"powering\" them.\n *\n * Different components become ready at different times, and initialization order (ie,\n * the order the scripts are combined on the page) only partially determines readiness.\n * This is because components like ROM and Video must finish loading their resource files\n * before they are ready. Other components become ready after we call their initBus()\n * function, because they have a Bus or CPU dependency, such as access to memory management\n * functions. And other components, like CPU and Panel, are ready as soon as their\n * constructor finishes.\n *\n * Once a component has indicated it's ready, we call its powerUp() notification\n * function (if it has one--it's optional). We call the CPU's powerUp() function last,\n * so that the CPU is assured that all other components are ready and \"powered\".\n *\n * @this {ComputerPDP10}\n * @param {Object} parmsComputer\n * @param {Object} [parmsMachine]\n * @param {boolean} [fSuspended]\n */\n constructor(parmsComputer, parmsMachine, fSuspended)\n {\n super(\"Computer\", parmsComputer, MessagesPDP10.COMPUTER);\n\n this.flags.powered = false;\n\n this.parmsMachine = null;\n this.setMachineParms(parmsMachine);\n\n this.fAutoPower = this.getMachineParm('autoPower', parmsComputer, Str.TYPES.BOOLEAN);\n\n /*\n * nPowerChange is 0 while the power state is stable, 1 while power is transitioning\n * to \"on\", and -1 while power is transitioning to \"off\".\n */\n this.nPowerChange = 0;\n\n /*\n * TODO: Deprecate 'buswidth' (it should have always used camelCase)\n */\n this.nBusWidth = +parmsComputer['busWidth'] || +parmsComputer['buswidth'];\n\n this.sResumePath = this.sStatePath = null;\n this.sStateData = null;\n this.fStateData = false; // remembers if sStateData was loaded\n this.fServerState = false;\n this.stateComputer = this.stateFailSafe = null;\n this.fInitialized = this.fReload = this.fRestoreError = false;\n\n this.url = /** @type {string} */ (this.getMachineParm('url') || \"\");\n\n /*\n * Generate a random number x (where 0 <= x < 1), add 0.1 so that it's guaranteed to be\n * non-zero, convert to base 36, and chop off the leading digit and \"decimal\" point.\n */\n this.sMachineID = (Math.random() + 0.1).toString(36).substr(2,12);\n this.sUserID = this.queryUserID();\n\n /*\n * Find the appropriate CPU (and Debugger and Control Panel, if any).\n *\n * CLOSURE COMPILER TIP: To override the type of a right-hand expression (as we need to do here,\n * where we know getComponentByType() will only return an CPUState object or null), wrap the expression\n * in parentheses. I never knew this until I stumbled across it in \"Closure: The Definitive Guide\".\n */\n this.cpu = /** @type {CPUStatePDP10} */ (Component.getComponentByType(\"CPU\", this.id));\n if (!this.cpu) {\n Component.error(\"Unable to find CPU component\");\n return;\n }\n this.dbg = /** @type {DebuggerPDP10} */ (Component.getComponentByType(\"Debugger\", this.id));\n\n /*\n * Initialize the Bus component\n */\n this.bus = new BusPDP10({'id': this.idMachine + '.bus', 'busWidth': this.nBusWidth}, this.cpu, this.dbg);\n\n /*\n * Iterate through all the components and connect them to the Control Panel, if any\n */\n var iComponent, component;\n var aComponents = Component.getComponents(this.id);\n\n this.panel = /** @type {PanelPDP10} */ (Component.getComponentByType(\"Panel\", this.id));\n this.controlPrint = this.panel && this.panel.bindings['print'];\n\n if (this.controlPrint) {\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n /*\n * I can think of many \"cleaner\" ways for the Control Panel component to pass its\n * notice(), println(), etc, overrides on to all the other components, but it's just\n * too darn convenient to slam those overrides into the components directly.\n */\n component.notice = this.panel.notice;\n component.print = this.panel.print;\n component.println = this.panel.println;\n }\n }\n\n this.println(PDP10.APPNAME + \" v\" + PDP10.APPVERSION + \"\\n\" + COPYRIGHT + \"\\n\" + LICENSE);\n\n /*\n * Iterate through all the components again and call their initBus() handler, if any\n */\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component.initBus) component.initBus(this, this.bus, this.cpu, this.dbg);\n }\n\n var sStatePath = null;\n var sResume = /** @type {string} */ (this.getMachineParm('resume', parmsComputer));\n if (sResume !== undefined) {\n /*\n * Decide whether the 'resume' property is a number or the path of a state file to resume.\n */\n if (sResume.length > 1) {\n sStatePath = this.sResumePath = sResume;\n } else {\n this.resume = parseInt(sResume, 10);\n }\n }\n\n /*\n * The Computer 'state' property allows a state file to be specified independent of the 'resume' feature;\n * previously, you could only use 'resume' to load a state file -- which we still support, but loading a state\n * file that way prevents the machine's state from being saved, since we always resume from the 'resume' file.\n *\n * The other wrinkle is on the restore side: we need to IGNORE the 'state' property if a saved state now exists.\n * So we have to peek at localStorage, and unfortunately, the only way to \"peek\" is to actually load the data,\n * but we're not ready to use it yet, so powerUp() has been changed to use any existing stateComputer that we've\n * already loaded.\n *\n * However, there's now a wrinkle to the wrinkle: if a 'state' parameter has been passed via the URL, then that\n * OVERRIDES everything; it overrides any 'state' Computer parameter AND it disables resume of any saved state in\n * localStorage (in other words, it prevents fAllowResume from being true, and forcing resume off).\n */\n var fAllowResume;\n var sState = this.getMachineParm('state') || (fAllowResume = true) && parmsComputer['state'];\n\n if (sState) {\n this.sStatePath = sStatePath = sState;\n if (!fAllowResume) {\n this.fServerState = true;\n this.resume = ComputerPDP10.RESUME_NONE;\n }\n if (this.resume) {\n this.stateComputer = new State(this, PDP10.APPVERSION);\n if (this.stateComputer.load()) {\n sStatePath = null;\n } else {\n delete this.stateComputer;\n }\n }\n }\n\n /*\n * If sStatePath is set, we must use it. But if there's no sStatePath AND resume is set,\n * then we have the option of resuming from a server-side state, assuming a valid USERID.\n */\n if (!sStatePath && this.resume) {\n sStatePath = this.getServerStatePath();\n if (sStatePath) this.fServerState = true;\n }\n\n if (!sStatePath) {\n this.setReady();\n } else {\n var cmp = this;\n Web.getResource(sStatePath, null, true, function doneStateLoad(sURL, sResource, nErrorCode) {\n cmp.finishStateLoad(sURL, sResource, nErrorCode);\n });\n }\n\n if (!this.bindings[\"power\"]) this.fAutoPower = true;\n\n /*\n * Power on the computer, giving every component the opportunity to reset or restore itself.\n */\n if (!fSuspended && this.fAutoPower) this.wait(this.powerOn);\n }\n\n /**\n * clearPanel()\n *\n * @this {ComputerPDP10}\n */\n clearPanel()\n {\n if (this.controlPrint) {\n this.controlPrint.value = \"\";\n }\n }\n\n /**\n * getMachineID()\n *\n * @this {ComputerPDP10}\n * @return {string}\n */\n getMachineID()\n {\n return this.sMachineID;\n }\n\n /**\n * setMachineParms(parmsMachine)\n *\n * If no explicit machine parms were provided, then we check for 'parms' in the bundled resources (if any).\n *\n * @this {ComputerPDP10}\n * @param {Object} [parmsMachine]\n */\n setMachineParms(parmsMachine)\n {\n if (!parmsMachine) {\n var sParms;\n if (typeof resources == 'object' && (sParms = resources['parms'])) {\n try {\n parmsMachine = /** @type {Object} */ (eval(\"(\" + sParms + \")\"));\n } catch(e) {\n Component.error(e.message + \" (\" + sParms + \")\");\n }\n }\n }\n this.parmsMachine = parmsMachine;\n }\n\n /**\n * getMachineParm(sParm, parmsComponent, type, defaultValue)\n *\n * If the machine parameter doesn't exist, we check for a matching component parameter\n * (if parmsComponent is provided), and failing that, we check the bundled resources (if any).\n *\n * At the moment, the only bundled resource request we expect to encounter is 'state'; if it exists,\n * then we return 'state' back to the caller (ie, the name of the resource), so that the caller will\n * then attempt to load the 'state' resource to obtain the actual state.\n *\n * TODO: It would be nice if we could tell the Closure Compiler that when a specific type parameter\n * (eg, Str.TYPES.NUMBER) is used, the return value will be that type; unfortunately, every caller\n * must coerce their own return value.\n *\n * @this {ComputerPDP10}\n * @param {string} sParm\n * @param {Object|null} [parmsComponent]\n * @param {number} [type] (from Str.TYPES)\n * @param {*} [defaultValue]\n * @return {*}\n */\n getMachineParm(sParm, parmsComponent, type, defaultValue)\n {\n /*\n * When checking parmsURL, the check is allowed be a bit looser, because URL parameters are\n * user-supplied, whereas most other parameters are developer-supplied. Granted, a developer\n * may also be sloppy and neglect to use correct case (eg, 'automount' instead of 'autoMount'),\n * but there are limits to my paranoia.\n */\n var sParmLC = sParm.toLowerCase();\n var value = Web.getURLParm(sParm) || Web.getURLParm(sParmLC);\n if (value === undefined && this.parmsMachine) value = this.parmsMachine[sParm];\n if (value === undefined && parmsComponent) value = parmsComponent[sParm];\n if (value === undefined && typeof resources == 'object' && resources[sParm]) value = sParm;\n if (value === undefined) value = defaultValue;\n if (typeof value == \"string\" && type) {\n switch(type) {\n case Str.TYPES.NUMBER:\n value = +value;\n if (isNaN(/** @type {number} */(value))) value = defaultValue || 0;\n break;\n case Str.TYPES.BOOLEAN:\n value = (value == \"true\");\n break;\n }\n }\n return value;\n }\n\n /**\n * saveMachineParms()\n *\n * @this {ComputerPDP10}\n * @return {string|null}\n */\n saveMachineParms()\n {\n return this.parmsMachine? JSON.stringify(this.parmsMachine) : null;\n }\n\n /**\n * getUserID()\n *\n * @this {ComputerPDP10}\n * @return {string}\n */\n getUserID()\n {\n return this.sUserID || \"\";\n }\n\n /**\n * finishStateLoad(sURL, sStateData, nErrorCode)\n *\n * @this {ComputerPDP10}\n * @param {string} sURL\n * @param {string} sStateData\n * @param {number} nErrorCode\n */\n finishStateLoad(sURL, sStateData, nErrorCode)\n {\n if (!nErrorCode) {\n this.sStateData = sStateData;\n this.fStateData = true;\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"loaded state file \" + sURL.replace(this.sUserID || \"xxx\", \"xxx\"));\n }\n } else {\n this.sResumePath = null;\n this.fServerState = false;\n this.notice('Unable to load machine state from server (error ' + nErrorCode + (sStateData? ': ' + Str.trim(sStateData) : '') + ')');\n }\n this.setReady();\n }\n\n /**\n * wait(fn, parms)\n *\n * wait() waits until every component is ready (including ourselves, the last component we check), then calls the\n * specified Computer method.\n *\n * TODO: The Closure Compiler makes it difficult for us to define a function type for \"fn\" that works in all cases;\n * sometimes we want to pass a function that takes only a \"number\", and other times we want to pass a function that\n * takes only an \"Array\" (the type will mirror that of the \"parms\" parameter). However, the Closure Compiler insists\n * that both functions must be declared as accepting both types of parameters. So once again, we must use an untyped\n * function declaration, instead of something stricter like:\n *\n * param {function(this:Computer, (number|Array|undefined)): undefined} fn\n *\n * @this {ComputerPDP10}\n * @param {function(...)} fn\n * @param {number|Array} [parms] optional parameters\n */\n wait(fn, parms)\n {\n var computer = this;\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent <= aComponents.length; iComponent++) {\n var component = (iComponent < aComponents.length ? aComponents[iComponent] : this);\n if (!component.isReady()) {\n component.isReady(function onComponentReady() {\n computer.wait(fn, parms);\n });\n return;\n }\n }\n if (DEBUG && this.messageEnabled()) this.printMessage(\"ComputerPDP10.wait(ready)\");\n fn.call(this, parms);\n }\n\n /**\n * validateState(stateComputer)\n *\n * NOTE: We clear() stateValidate only when there's no stateComputer.\n *\n * @this {ComputerPDP10}\n * @param {State|null} [stateComputer]\n * @return {boolean} true if state passes validation, false if not\n */\n validateState(stateComputer)\n {\n var fValid = true;\n var stateValidate = new State(this, PDP10.APPVERSION, ComputerPDP10.STATE_VALIDATE);\n if (stateValidate.load() && stateValidate.parse()) {\n var sTimestampValidate = stateValidate.get(ComputerPDP10.STATE_TIMESTAMP);\n var sTimestampComputer = stateComputer? stateComputer.get(ComputerPDP10.STATE_TIMESTAMP) : \"unknown\";\n if (sTimestampValidate != sTimestampComputer) {\n this.notice(\"Machine state may be out-of-date\\n(\" + sTimestampValidate + \" vs. \" + sTimestampComputer + \")\\nCheck your browser's local storage limits\");\n fValid = false;\n if (!stateComputer) stateValidate.clear();\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"Last state: \" + sTimestampComputer + \" (validate: \" + sTimestampValidate + \")\");\n }\n }\n }\n return fValid;\n }\n\n /**\n * powerOn(resume)\n *\n * Power every component \"up\", applying any previously available state information.\n *\n * @this {ComputerPDP10}\n * @param {number} [resume] is a valid RESUME value; default is this.resume\n */\n powerOn(resume)\n {\n if (resume === undefined) {\n resume = this.resume || (this.sStateData? ComputerPDP10.RESUME_AUTO : ComputerPDP10.RESUME_NONE);\n }\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"ComputerPDP10.powerOn(\" + (resume == ComputerPDP10.RESUME_REPOWER ? \"repower\" : (resume ? \"resume\" : \"\")) + \")\");\n }\n\n if (this.nPowerChange) {\n return;\n }\n this.nPowerChange++;\n\n var fRepower = false;\n var fRestore = false;\n this.fRestoreError = false;\n var stateComputer = this.stateComputer || new State(this, PDP10.APPVERSION);\n\n if (resume == ComputerPDP10.RESUME_REPOWER) {\n fRepower = true;\n }\n else if (resume > ComputerPDP10.RESUME_NONE) {\n if (stateComputer.load(this.sStateData)) {\n /*\n * Since we're resuming something (either a predefined state or a state from localStorage), let's\n * create a \"failsafe\" checkpoint in localStorage, and destroy it at the end of a successful powerOn().\n * Which means, of course, that if a previous \"failsafe\" checkpoint already exists, something bad\n * may have happened the last time around.\n */\n this.stateFailSafe = new State(this, PDP10.APPVERSION, ComputerPDP10.STATE_FAILSAFE);\n if (this.stateFailSafe.load()) {\n this.powerReport(stateComputer);\n /*\n * We already know resume is something other than RESUME_NONE, so we'll go ahead and bump it\n * all the way to RESUME_PROMPT, so that the user will be prompted, and if the user declines to\n * restore, the state will be removed.\n */\n resume = ComputerPDP10.RESUME_PROMPT;\n /*\n * To ensure that the set() below succeeds, we need to call unload(), otherwise it may fail\n * with a \"read only\" error (eg, \"TypeError: Cannot assign to read only property 'timestamp'\").\n */\n this.stateFailSafe.unload();\n }\n\n this.stateFailSafe.set(ComputerPDP10.STATE_TIMESTAMP, Usr.getTimestamp());\n this.stateFailSafe.store();\n\n var fValidate = this.resume && !this.fServerState;\n if (resume == ComputerPDP10.RESUME_AUTO || Component.confirmUser(\"Click OK to restore the previous \" + PDP10.APPNAME + \" machine state, or CANCEL to reset the machine.\")) {\n fRestore = stateComputer.parse();\n if (fRestore) {\n var sCode = /** @type {string} */ (stateComputer.get(UserAPI.RES.CODE));\n var sData = /** @type {string} */ (stateComputer.get(UserAPI.RES.DATA));\n if (sCode) {\n if (sCode == UserAPI.CODE.OK) {\n stateComputer.load(sData);\n } else {\n /*\n * A missing (or not yet created) state file is no cause for alarm, but other errors might be\n */\n if (sCode == UserAPI.CODE.FAIL && sData != UserAPI.FAIL.NOSTATE) {\n this.notice(\"Error: \" + sData);\n if (sData == UserAPI.FAIL.VERIFY) this.resetUserID();\n } else {\n this.println(sCode + \": \" + sData);\n }\n /*\n * Try falling back to the state that we should have saved in localStorage, as a backup to the\n * server-side state.\n */\n stateComputer.unload(); // discard the invalid server-side state first\n if (stateComputer.load()) {\n fRestore = stateComputer.parse();\n fValidate = true;\n } else {\n fRestore = false; // hmmm, there was nothing in localStorage either\n }\n }\n }\n }\n /*\n * If the load/parse was successful, and it was from localStorage (not sStateData),\n * then we should to try verify that localStorage snapshot is current. One reason it may\n * NOT be current is if localStorage was full and we got a quota error during the last\n * powerOff().\n */\n if (fValidate) this.validateState(fRestore? stateComputer : null);\n } else {\n /*\n * RESUME_PROMPT indicates we should delete the state if they clicked Cancel to confirm() above.\n */\n if (resume == ComputerPDP10.RESUME_PROMPT) stateComputer.clear();\n }\n } else {\n /*\n * If there's no state, then there should also be no validation timestamp; if there is, then once again,\n * we're probably dealing with a quota error.\n */\n this.validateState();\n }\n delete this.sStateData;\n delete this.stateComputer;\n }\n\n /*\n * Start powering all components, including any data they may need to restore their state;\n * we restore power to the CPU last.\n */\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component !== this && component != this.cpu) {\n fRestore = this.powerRestore(component, stateComputer, fRepower, fRestore);\n }\n }\n\n /*\n * Assuming this is not a repower, we must perform another wait, because some components may\n * have marked themselves as \"not ready\" again (eg, the FDC component, if the restore forced it\n * to mount one or more additional disk images).\n */\n var aParms = [stateComputer, resume, fRestore];\n\n if (resume != ComputerPDP10.RESUME_REPOWER) {\n this.wait(this.donePowerOn, aParms);\n return;\n }\n this.donePowerOn(aParms);\n }\n\n /**\n * powerRestore(component, stateComputer, fRepower, fRestore)\n *\n * @this {ComputerPDP10}\n * @param {Component} component\n * @param {State} stateComputer\n * @param {boolean} fRepower\n * @param {boolean} fRestore\n * @return {boolean} true if restore should continue, false if not\n */\n powerRestore(component, stateComputer, fRepower, fRestore)\n {\n if (!component.flags.powered) {\n\n /*\n * TODO: If all components called super.powerUp(), the powered flag would be set automatically.\n */\n\n component.flags.powered = true;\n\n var data = null;\n\n try {\n if (fRestore) {\n data = stateComputer.get(component.id);\n if (!data) {\n /*\n * This is a hack that makes it possible for a machine whose ID has been\n * supplemented with a suffix (a single letter or digit) to find object IDs\n * in states created from a machine without the suffix.\n *\n * For example, if a state file was created from a machine with ID \"ibm5160\"\n * but the current machine is \"ibm5160a\", this attempts a second lookup with\n * \"ibm5160\", enabling us to find objects that match the original machine ID\n * (eg, \"ibm5160.romEGA\").\n */\n data = stateComputer.get(component.id.replace(/[a-z0-9]\\./i, '.'));\n }\n }\n\n /*\n * State.get() will return whatever was originally passed to State.set() (eg, an\n * Object or a string), but components are supposed to store only Objects, so if a\n * string comes back, something went wrong. By explicitly eliminating \"string\" data,\n * the Closure Compiler stops complaining that we might be passing strings to our\n * powerUp() functions (even though we know we're not).\n *\n * TODO: Determine if there's some way to coerce the Closure Compiler into treating\n * data as Object or null, without having to include this runtime check. An assert\n * would be a good idea, but this is overkill.\n */\n if (typeof data === \"string\") data = null;\n\n /*\n * If computer is null, this is simply a repower notification, which most components\n * don't do anything with. Exceptions include: CPU (since it may be halted) and Video\n * (since its screen may be \"turned off\").\n */\n if (!component.powerUp(data, fRepower) && data) {\n\n Component.error(\"Unable to restore state for \" + component.type);\n /*\n * If this is a resume error for a machine that also has a predefined state\n * AND we're not restoring from that state, then throw away the current state,\n * prevent any new state from being created, and then force a reload, which will\n * hopefully restore us to the functioning predefined state.\n *\n * TODO: Considering doing this in ALL cases, not just in situations where a\n * 'state' exists but we're not actually resuming from it.\n */\n if (this.sStatePath && !this.fStateData) {\n stateComputer.clear();\n this.resume = ComputerPDP10.RESUME_NONE;\n Web.reloadPage();\n } else {\n /*\n * In all other cases, we set fRestoreError, which should trigger a call to\n * powerReport() and then delete the offending state.\n */\n this.fRestoreError = true;\n }\n /*\n * Any failure triggers an automatic to call powerUp() again, without any state,\n * in the hopes that the component can recover by performing a reset.\n */\n component.powerUp(null);\n /*\n * We also disable the rest of the restore operation, because it's not clear\n * the remaining state information can be trusted; the machine is already in an\n * inconsistent state, so we're not likely to make things worse, and the only\n * alternative (starting over and performing a state-less reset) isn't likely to make\n * the user any happier. But, we'll see... we need some experience with the code.\n */\n fRestore = false;\n }\n\n if (!fRepower && component.comment) {\n var asComments = component.comment.split(\"|\");\n for (var i = 0; i < asComments.length; i++) {\n component.status(asComments[i]);\n }\n }\n }\n catch (err) {\n Component.error(\"Error restoring state for \" + component.type + \" (\" + err.message + \")\");\n }\n }\n return fRestore;\n }\n\n /**\n * donePowerOn(aParms)\n *\n * This is nothing more than a continuation of powerOn(), giving us the option of calling wait() one more time.\n *\n * @this {ComputerPDP10}\n * @param {Array} aParms containing [stateComputer, resume, fRestore]\n */\n donePowerOn(aParms)\n {\n var stateComputer = aParms[0];\n var fRepower = (aParms[1] < 0);\n var fRestore = aParms[2];\n\n if (DEBUG && this.flags.powered && this.messageEnabled()) {\n this.printMessage(\"ComputerPDP10.donePowerOn(): redundant\");\n }\n\n this.fInitialized = true;\n this.flags.powered = true;\n var controlPower = this.bindings[\"power\"];\n if (controlPower) controlPower.textContent = \"Shutdown\";\n\n /*\n * Once we get to this point, we're guaranteed that all components are ready, so it's safe to power the CPU;\n * the CPU should begin executing immediately, unless a debugger is attached.\n */\n if (this.cpu) {\n /*\n * TODO: Do we not care about the return value here? (ie, is checking fRestoreError sufficient)?\n */\n this.powerRestore(this.cpu, stateComputer, fRepower, fRestore);\n this.updateDisplays(-2);\n this.cpu.autoStart();\n }\n\n /*\n * If the state was bad, offer to report it and then delete it. Deleting may be moot, since invariably a new\n * state will be created on powerOff() before the next powerOn(), but it seems like good paranoia all the same.\n */\n if (this.fRestoreError) {\n this.powerReport(stateComputer);\n stateComputer.clear();\n }\n\n if (!fRepower && this.stateFailSafe) {\n this.stateFailSafe.clear();\n delete this.stateFailSafe;\n }\n\n this.nPowerChange = 0;\n }\n\n /**\n * checkPower()\n *\n * @this {ComputerPDP10}\n * @return {boolean} true if the computer is fully powered, false otherwise\n */\n checkPower()\n {\n if (this.flags.powered) return true;\n\n var component = null, iComponent;\n var aComponents = Component.getComponents(this.id);\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component !== this && !component.flags.ready) break;\n }\n if (iComponent == aComponents.length) {\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component !== this && !component.flags.powered) break;\n }\n }\n if (iComponent == aComponents.length) component = this;\n var s = \"The \" + component.type + \" component (\" + component.id + \") is not \" + (!component.flags.ready? \"ready yet\" + (component.fnReady? \" (waiting for notification)\" : \"\") : \"powered yet\") + \".\";\n Component.alertUser(s);\n return false;\n }\n\n /**\n * powerReport(stateComputer)\n *\n * @this {ComputerPDP10}\n * @param {State} stateComputer\n */\n powerReport(stateComputer)\n {\n if (Component.confirmUser(\"There may be a problem with your \" + PDP10.APPNAME + \" machine.\\n\\nTo help us diagnose it, click OK to send this \" + PDP10.APPNAME + \" machine state to http://\" + SITEHOST + \".\")) {\n Web.sendReport(PDP10.APPNAME, PDP10.APPVERSION, this.url, this.getUserID(), ReportAPI.TYPE.BUG, stateComputer.toString());\n }\n }\n\n /**\n * powerOff(fSave, fShutdown)\n *\n * Power every component \"down\" and optionally save the machine state.\n *\n * There's one scenario that powerOff() isn't currently able to deal with very effectively: what to do when\n * the user switches away while it's still being restored, causing Disk getResource() calls to fail. The\n * Disk component calls notify() when that happens -- see Disk.mount() -- but the FDC and HDC controllers don't\n * notify *us* of those problems, so Computer assumes that the restore was completely successful, when in fact\n * it was only partially successful.\n *\n * Then we immediately arrive here to perform a save, following that incomplete restore. It would be wrong to\n * deal with that incomplete restore by setting fRestoreError, because we don't want to trigger a powerReport()\n * and the deletion of the previous state, because the state itself was presumably OK. Unfortunately, the new\n * state we now save will no longer include manually mounted disk images whose remounts were interrupted, so future\n * restores won't remount them either.\n *\n * We could perhaps solve this by having the Disk component notify us in those situations, set a new flag\n * (fRestoreIncomplete?), and set fSave to false if that's ever set. Be careful though: when fSave is false,\n * that means MORE than not saving; it also means deleting any previous state, which is NOT what you'd want to\n * do in a \"fRestoreIncomplete\" situation. Also, we have to worry about Disk operations that fail for other reasons,\n * making sure those failures don't interfere with the save process in the same way.\n *\n * As it stands, the worst that happens is any manually mounted disk images might have to be manually remounted,\n * which doesn't seem like a huge problem.\n *\n * @this {ComputerPDP10}\n * @param {boolean} [fSave] is true to request a saved state\n * @param {boolean} [fShutdown] is true if the machine is being shut down\n * @return {string|null} string representing the saved state (or null if error)\n */\n powerOff(fSave, fShutdown)\n {\n var data;\n var sState = \"none\";\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"ComputerPDP10.powerOff(\" + (fSave ? \"save\" : \"nosave\") + (fShutdown ? \",shutdown\" : \"\") + \")\");\n }\n\n if (this.nPowerChange) {\n return null;\n }\n this.nPowerChange--;\n\n var stateComputer = new State(this, PDP10.APPVERSION);\n var stateValidate = new State(this, PDP10.APPVERSION, ComputerPDP10.STATE_VALIDATE);\n\n var sTimestamp = Usr.getTimestamp();\n stateValidate.set(ComputerPDP10.STATE_TIMESTAMP, sTimestamp);\n stateComputer.set(ComputerPDP10.STATE_TIMESTAMP, sTimestamp);\n stateComputer.set(ComputerPDP10.STATE_VERSION, APPVERSION);\n stateComputer.set(ComputerPDP10.STATE_HOSTURL, Web.getHostURL());\n stateComputer.set(ComputerPDP10.STATE_BROWSER, Web.getUserAgent());\n\n /*\n * Always power the CPU \"down\" first, just to help insure it doesn't ask other components to do anything\n * after they're no longer ready.\n */\n if (this.cpu && this.cpu.powerDown) {\n if (fShutdown) {\n if (fSave) this.cpu.flags.autoStart = this.cpu.flags.running;\n this.cpu.stopCPU();\n }\n data = this.cpu.powerDown(fSave, fShutdown);\n if (typeof data === \"object\") stateComputer.set(this.cpu.id, data);\n if (fShutdown) {\n this.cpu.flags.powered = false;\n if (data === false) sState = null;\n }\n }\n\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.flags.powered) {\n if (component.powerDown) {\n data = component.powerDown(fSave, fShutdown);\n if (typeof data === \"object\") stateComputer.set(component.id, data);\n }\n if (fShutdown) {\n component.flags.powered = false;\n if (data === false) sState = null;\n }\n }\n }\n\n if (sState) {\n if (fShutdown) {\n var fClear = false;\n var fClearAll = false;\n if (fSave) {\n if (this.sUserID) {\n this.saveServerState(this.sUserID, stateComputer.toString());\n }\n if (!stateValidate.store() || !stateComputer.store()) {\n sState = null;\n /*\n * New behavior as of v1.13.2: if it appears that localStorage is full, we blow it ALL away.\n * Dedicated server-side storage is the only way we'll ever be able to reliably preserve a\n * particular machine's state. Historically, attempting to limp along with whatever localStorage\n * is left just generates the same useless and annoying warnings over and over.\n */\n fClear = fClearAll = true;\n }\n }\n else {\n /*\n * I used to ALWAYS clear (ie, delete) any associated computer state, but now I do this only if the\n * current machine is \"resumable\", because there are situations where I have two configurations\n * for the same machine -- one resumable and one not -- and I don't want the latter throwing away the\n * state of the former.\n *\n * So this code is here now strictly for callers to delete the state of a \"resumable\" machine, not as\n * some paranoid clean-up operation.\n *\n * An undocumented feature of this operation is that if your configuration uses the special 'resume=\"3\"'\n * value, and you click the \"Reset\" button, and then you click OK to reset the everything, this will\n * actually reset EVERYTHING (ie, all localStorage for ALL configs will be reclaimed).\n */\n if (this.resume) {\n fClear = true;\n fClearAll = (this.resume == ComputerPDP10.RESUME_DELETE);\n }\n }\n if (fClear) {\n stateComputer.clear(fClearAll);\n }\n } else {\n sState = stateComputer.toString();\n }\n }\n\n if (fShutdown) {\n this.flags.powered = false;\n var controlPower = this.bindings[\"power\"];\n if (controlPower) controlPower.textContent = \"Power\";\n }\n\n this.nPowerChange = 0;\n\n return sState;\n }\n\n /**\n * reset()\n *\n * Notify all (other) components with a reset() method that the Computer is being reset.\n *\n * NOTE: We'd like to reset the Bus first (due to the importance of the A20 line), but since we\n * allocated the Bus object ourselves, after all the other components were allocated, it ends\n * up near the end of Component's list of components. Hence the special case for this.bus below.\n *\n * Ditto for the CPU, in part because if the Front Panel resets before the CPU, it will end up\n * snapping/displaying the PC as of the last instruction executed, before the CPU resets the PC,\n * causing the Front Panel to display a stale address when we call updateDisplays() at the end.\n *\n * @this {ComputerPDP10}\n */\n reset()\n {\n this.flags.reset = true;\n if (this.bus && this.bus.reset) {\n this.printMessage(\"Resetting \" + this.bus.type);\n this.bus.reset();\n }\n if (this.cpu && this.cpu.reset) {\n this.printMessage(\"Resetting \" + this.cpu.type);\n this.cpu.reset();\n }\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component !== this && component !== this.bus && component !== this.cpu && component.reset) {\n this.printMessage(\"Resetting \" + component.type);\n component.reset();\n }\n }\n this.flags.reset = false;\n this.updateDisplays(-1);\n }\n\n /**\n * start(ms, nCycles)\n *\n * Notify all (other) components with a start() method that the CPU has started.\n *\n * Note that we're called by startCPU(), which is why we exclude the CPU component,\n * as well as ourselves.\n *\n * @this {ComputerPDP10}\n * @param {number} ms\n * @param {number} nCycles\n */\n start(ms, nCycles)\n {\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.type == \"CPU\" || component === this) continue;\n if (component.start) {\n component.start(ms, nCycles);\n }\n }\n this.updateDisplays(-1);\n }\n\n /**\n * stop(ms, nCycles)\n *\n * Notify all (other) components with a stop() method that the CPU has stopped.\n *\n * Note that we're called by stopCPU(), which is why we exclude the CPU component,\n * as well as ourselves.\n *\n * @this {ComputerPDP10}\n * @param {number} ms\n * @param {number} nCycles\n */\n stop(ms, nCycles)\n {\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.type == \"CPU\" || component === this) continue;\n if (component.stop) {\n component.stop(ms, nCycles);\n }\n }\n this.updateDisplays(-1);\n }\n\n /**\n * updateDisplays(nUpdate)\n *\n * TODO: Notify all components with an updateDisplay() method that the computer's state has changed (not\n * just the hard-coded ones below).\n *\n * If any DOM controls were bound to the CPU, then we need to call its updateDisplay() handler; if there are no\n * such bindings, then cpu.updateDisplay() does nothing.\n *\n * Similarly, if there's a Panel, then we need to call its updateDisplay() handler, in case it created its own canvas\n * and implemented its own register display (eg, dumpRegisters()); if not, then panel.updateDisplay() also does nothing.\n *\n * In practice, there will *either* be a Panel with a custom canvas *or* a set of DOM controls bound to the CPU *or*\n * neither. In theory, there could be BOTH, but that would be unusual.\n *\n * TODO: Consider alternate approaches to these largely register-oriented display updates. Ordinarily, we like to\n * separate logic from presentation, and currently the CPUState contains both, since it's the component that intimately\n * knows the names, number, sizes, etc, of all the active registers. The Panel component is the logical candidate,\n * but Panel is an optional component; it's often the case that only machines that include the Debugger also include\n * Panel.\n *\n * @this {ComputerPDP10}\n * @param {number} [nUpdate] (1 for periodic, -1 for forced, 0 or undefined otherwise)\n */\n updateDisplays(nUpdate)\n {\n /*\n * nUpdate is generally set to -1 whenever the CPU is transitioning to/from a running state, in which case\n * cpu.updateDisplay() will definitely want to hide/show register contents; however, at other times, when the\n * CPU is running, constantly updating the DOM controls too frequently can adversely impact overall performance.\n *\n * nUpdate will also be -1 whenever the Debugger has modified the state of the machine, implying that we're\n * not sure what, if anything, actually changed.\n */\n if (this.cpu) this.cpu.updateDisplay(nUpdate || 0);\n if (this.panel) this.panel.updateDisplay(nUpdate || 0);\n }\n\n /**\n * setBinding(sType, sBinding, control, sValue)\n *\n * @this {ComputerPDP10}\n * @param {string|null} sType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sType, sBinding, control, sValue)\n {\n var computer = this;\n\n switch (sBinding) {\n case \"power\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickPower() {\n computer.onPower();\n };\n return true;\n\n case \"reset\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickReset() {\n computer.onReset();\n };\n return true;\n\n /*\n * Technically, this binding should now be called \"saveState\", to clearly distinguish it from\n * the \"Save Machine\" control that's normally bound to the savePC() function in save.js. Saving\n * an entire machine includes everything needed to start/restore the machine; eg, the machine\n * XML configuration file(s) *and* the JSON-encoded machine state.\n */\n case \"save\":\n /*\n * Since this feature depends on the server supporting the PCjs User API (see userapi.js),\n * and since pcjs.org is no longer running a Node web server, we disable the feature for that\n * particular host.\n */\n if (Str.endsWith(Web.getHost(), \"pcjs.org\")) {\n if (DEBUG) this.log(\"Remote user API not available\");\n /*\n * We could also simply hide the control; eg:\n *\n * control.style.display = \"none\";\n *\n * but removing the control altogether seems better.\n */\n control.parentNode.removeChild(/** @type {Node} */ (control));\n return false;\n }\n this.bindings[sBinding] = control;\n control.onclick = function onClickSave() {\n var sUserID = computer.queryUserID(true);\n if (sUserID) {\n /*\n * I modified the test to include a check for sStatePath so that I could save new states\n * for machines with existing states; otherwise, I'd have no (easy) way of capturing and\n * updating their state. Making the machine (even temporarily) resumable would have been\n * one work-around, but it's not appropriate for some machines, as their state is simply\n * too large (for localStorage anyway, which is the default storage solution).\n */\n var fSave = !!(computer.resume && !computer.sResumePath || computer.sStatePath);\n var sState = computer.powerOff(fSave);\n if (fSave) {\n computer.saveServerState(sUserID, sState);\n } else {\n computer.notice(\"Resume disabled, machine state not saved\");\n }\n }\n /*\n * This seemed like a handy alternative, but it turned out to be a no-go, at least for large states:\n *\n * var sState = computer.powerOff(true);\n * if (sState) {\n * sState = \"data:text/json;charset=utf-8,\" + encodeURIComponent(sState);\n * window.open(sState);\n * }\n *\n * Perhaps if I embedded the data in a link on the current page instead; eg:\n *\n * $('<a href=\"' + sState + '\" download=\"state.json\">Download</a>').appendTo('#container');\n */\n };\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * resetUserID()\n *\n * @this {ComputerPDP10}\n */\n resetUserID()\n {\n Web.setLocalStorageItem(ComputerPDP10.STATE_USERID, \"\");\n this.sUserID = null;\n }\n\n /**\n * queryUserID(fPrompt)\n *\n * @this {ComputerPDP10}\n * @param {boolean} [fPrompt]\n * @returns {string|null|undefined}\n */\n queryUserID(fPrompt)\n {\n var sUserID = this.sUserID;\n if (!sUserID) {\n sUserID = Web.getLocalStorageItem(ComputerPDP10.STATE_USERID);\n if (sUserID !== undefined) {\n if (!sUserID && fPrompt) {\n /*\n * NOTE: Warning the user here that \"Save\" operations are not currently supported by pcjs.org is\n * merely a precaution, because ordinarily, setBinding() should have already determined if we are\n * running from pcjs.org and disabled any \"Save\" button.\n */\n sUserID = Component.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.\");\n if (sUserID) {\n sUserID = this.verifyUserID(sUserID);\n if (!sUserID) this.notice(\"The user ID is invalid.\");\n }\n }\n } else if (fPrompt) {\n this.notice(\"Browser local storage is not available\");\n }\n }\n return sUserID;\n }\n\n /**\n * verifyUserID(sUserID)\n *\n * @this {ComputerPDP10}\n * @param {string} sUserID\n * @return {string} validated user ID, or null if error\n */\n verifyUserID(sUserID)\n {\n this.sUserID = null;\n var fMessages = DEBUG && this.messageEnabled();\n if (fMessages) this.printMessage(\"verifyUserID(\" + sUserID + \")\");\n var sRequest = Web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.VERIFY + '&' + UserAPI.QUERY.USER + '=' + sUserID;\n var response = Web.getResource(sRequest);\n var nErrorCode = response[0];\n var sResponse = response[1];\n if (!nErrorCode && sResponse) {\n try {\n response = eval(\"(\" + sResponse + \")\");\n if (response.code && response.code == UserAPI.CODE.OK) {\n Web.setLocalStorageItem(ComputerPDP10.STATE_USERID, response.data);\n if (fMessages) this.printMessage(ComputerPDP10.STATE_USERID + \" updated: \" + response.data);\n this.sUserID = response.data;\n } else {\n if (fMessages) this.printMessage(response.code + \": \" + response.data);\n }\n } catch (e) {\n Component.error(e.message + \" (\" + sResponse + \")\");\n }\n } else {\n if (fMessages) this.printMessage(\"invalid response (error \" + nErrorCode + \")\");\n }\n return this.sUserID;\n }\n\n /**\n * getServerStatePath()\n *\n * @this {ComputerPDP10}\n * @return {string|null} sStatePath (null if no localStorage or no USERID stored in localStorage)\n */\n getServerStatePath()\n {\n var sStatePath = null;\n if (this.sUserID) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(ComputerPDP10.STATE_USERID + \" for load: \" + this.sUserID);\n }\n sStatePath = Web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.LOAD + '&' + UserAPI.QUERY.USER + '=' + this.sUserID + '&' + UserAPI.QUERY.STATE + '=' + State.key(this, PDP10.APPVERSION);\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(ComputerPDP10.STATE_USERID + \" unavailable\");\n }\n }\n return sStatePath;\n }\n\n /**\n * saveServerState(sUserID, sState)\n *\n * @this {ComputerPDP10}\n * @param {string} sUserID\n * @param {string|null} sState\n */\n saveServerState(sUserID, sState)\n {\n /*\n * We must pass fSync == true, because (as I understand it) browsers will blow off any async\n * requests when a page is being closed. Since our request is synchronous, storeServerState()\n * should also return a result, but there's not much we can do with it, since browsers ALSO\n * tend to blow off alerts() and the like when closing down.\n */\n if (sState) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"size of server state: \" + sState.length + \" bytes\");\n }\n var response = this.storeServerState(sUserID, sState, true);\n if (response && response[UserAPI.RES.CODE] == UserAPI.CODE.OK) {\n this.notice(\"Machine state saved to server\");\n } else if (sState) {\n var sError = (response && response[UserAPI.RES.DATA]) || UserAPI.FAIL.BADSTORE;\n if (response[UserAPI.RES.CODE] == UserAPI.CODE.FAIL) {\n sError = \"Error: \" + sError;\n } else {\n sError = \"Error \" + response[UserAPI.RES.CODE] + \": \" + sError;\n }\n this.notice(sError);\n this.resetUserID();\n }\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"no state to store\");\n }\n }\n }\n\n /**\n * storeServerState(sUserID, sState, fSync)\n *\n * @this {ComputerPDP10}\n * @param {string} sUserID\n * @param {string} sState\n * @param {boolean} [fSync] is true if we're powering down and should perform a synchronous request (default is async)\n * @return {*} server response if fSync is true and a response was received; otherwise null\n */\n storeServerState(sUserID, sState, fSync)\n {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(ComputerPDP10.STATE_USERID + \" for store: \" + sUserID);\n }\n /*\n * TODO: Determine whether or not any browsers cancel our request if we're called during a browser \"shutdown\" event,\n * and whether or not it matters if we do an async request (currently, we're not, to try to ensure the request goes through).\n */\n var dataPost = {};\n dataPost[UserAPI.QUERY.REQ] = UserAPI.REQ.STORE;\n dataPost[UserAPI.QUERY.USER] = sUserID;\n dataPost[UserAPI.QUERY.STATE] = State.key(this, PDP10.APPVERSION);\n dataPost[UserAPI.QUERY.DATA] = sState;\n var sRequest = Web.getHost() + UserAPI.ENDPOINT;\n if (!fSync) {\n Web.getResource(sRequest, dataPost, true);\n } else {\n var response = Web.getResource(sRequest, dataPost);\n var sResponse = response[0];\n if (response[1]) {\n if (sResponse) {\n var i = sResponse.indexOf('\\n');\n if (i > 0) sResponse = sResponse.substr(0, i);\n if (!sResponse.indexOf(\"Error: \")) sResponse = sResponse.substr(7);\n }\n sResponse = '{\"' + UserAPI.RES.CODE + '\":' + response[1] + ',\"' + UserAPI.RES.DATA + '\":\"' + sResponse + '\"}';\n }\n if (DEBUG && this.messageEnabled()) this.printMessage(sResponse);\n return JSON.parse(sResponse);\n }\n return null;\n }\n\n /**\n * onPower()\n *\n * This handles UI requests to toggle the computer's power (eg, see the \"power\" button binding).\n *\n * @this {ComputerPDP10}\n */\n onPower()\n {\n if (!this.nPowerChange) {\n if (!this.flags.powered) {\n this.wait(this.powerOn);\n } else {\n this.powerOff(false, true);\n }\n }\n }\n\n /**\n * onReset()\n *\n * This handles UI requests to reset the computer's state (eg, see the \"reset\" button binding).\n *\n * @this {ComputerPDP10}\n */\n onReset()\n {\n /*\n * I'm going to start with the presumption that it makes little sense for an \"unpowered\" computer to be \"reset\";\n * ditto if the power state is currently being changed.\n */\n if (!this.flags.powered || this.nPowerChange) return;\n\n /*\n * If this is a \"resumable\" machine (and it's not using a predefined state), then we overload the reset\n * operation to offer an explicit \"save or discard\" option first. This is currently the only UI we offer to\n * discard a machine's state, including any disk changes. The traditional \"reset\" operation is still available\n * for non-resumable machines.\n *\n * TODO: Break this behavior out into a separate \"discard\" operation, in case the designer of the machine really\n * wants to clutter the UI with confusing options. ;-)\n */\n if (this.resume && !this.sResumePath) {\n /*\n * I used to bypass the prompt if this.resume == ComputerPDP10.RESUME_AUTO, setting fSave to true automatically,\n * but that gives the user no means of resetting a resumable machine that contains errors in its resume state.\n */\n var fSave = (/* this.resume == ComputerPDP10.RESUME_AUTO || */ Component.confirmUser(\"Click OK to save changes to this \" + PDP10.APPNAME + \" machine.\\n\\nWARNING: If you CANCEL, all disk changes will be discarded.\"));\n this.powerOff(fSave, true);\n /*\n * Forcing the page to reload is an expedient option, but ugly. It's preferable to call powerOn()\n * and rely on all the components to reset themselves to their default state. The components with\n * the greatest burden here are FDC and HDC, which must rely on the fReload flag to determine whether\n * or not to unload/reload all their original auto-mounted disk images.\n *\n * However, if we started with a predefined state (ie, sStatePath is set), we take this shortcut, because\n * we don't (yet) have code in place to gracefully reload the initial state (requires calling getResource()\n * again); alternatively, we could avoid throwing that state away, but it seems better to save the memory.\n *\n * TODO: Make this more graceful, so that we can stop using the reloadPage() sledgehammer.\n */\n if (!fSave && this.sStatePath) {\n Web.reloadPage();\n return;\n }\n if (!fSave) this.fReload = true;\n this.powerOn(ComputerPDP10.RESUME_NONE);\n this.fReload = false;\n } else {\n this.reset();\n if (this.cpu && !this.dbg) this.cpu.autoStart();\n }\n }\n\n /**\n * getMachineComponent(sType, componentPrev)\n *\n * @this {ComputerPDP10}\n * @param {string} sType\n * @param {Component|null} [componentPrev] of previously returned component, if any\n * @return {Component|null}\n */\n getMachineComponent(sType, componentPrev)\n {\n var componentLast = componentPrev;\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (componentPrev) {\n if (componentPrev == component) componentPrev = null;\n continue;\n }\n if (component.type == sType) return component;\n }\n if (!componentLast) Component.log(\"Machine component type '\" + sType + \"' not found\", \"warning\");\n return null;\n }\n\n /**\n * setFocus(fScroll)\n *\n * NOTE: When soft keyboard buttons call us to return focus to the machine (and away from the button),\n * the browser's default behavior is to scroll the element into view, which can be annoying, especially on iOS,\n * where the display is more constrained, so we no longer do it by default (fScroll must be true).\n *\n * @this {ComputerPDP10}\n * @param {boolean} [fScroll] (true if you really want the control scrolled into view)\n */\n setFocus(fScroll)\n {\n if (this.controlPrint) {\n /*\n * This seems to be recommended work-around to prevent the browser from scrolling the focused element\n * into view. The CPU is not a visual component, so when the CPU wants to set focus, the primary intent\n * is to ensure that keyboard input is fielded properly.\n */\n var x = 0, y = 0;\n if (!fScroll && window) {\n x = window.scrollX;\n y = window.scrollY;\n }\n\n this.controlPrint.focus();\n\n if (!fScroll && window) {\n window.scrollTo(x, y);\n }\n }\n }\n\n /**\n * ComputerPDP10.init()\n *\n * For every machine represented by an HTML element of class \"PDP10-machine\", this function\n * locates the HTML element of class \"computer\", extracting the JSON-encoded parameters for the\n * Computer constructor from the element's \"data-value\" attribute, invoking the constructor to\n * create a Computer component, and then binding any associated HTML controls to the new component.\n */\n static init()\n {\n /*\n * In non-COMPILED builds, embedMachine() may have set XMLVERSION.\n */\n if (!COMPILED && XMLVERSION) PDP10.APPVERSION = XMLVERSION;\n\n var aeMachines = Component.getElementsByClass(document, PDP10.APPCLASS + \"-machine\");\n\n for (var iMachine = 0; iMachine < aeMachines.length; iMachine++) {\n\n var eMachine = aeMachines[iMachine];\n var parmsMachine = Component.getComponentParms(eMachine);\n\n var aeComputers = Component.getElementsByClass(eMachine, PDP10.APPCLASS, \"computer\");\n\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n\n /*\n * We set fSuspended in the Computer constructor because we want to \"power up\" the\n * computer ourselves, after any/all bindings are in place.\n */\n var computer = new ComputerPDP10(parmsComputer, parmsMachine, true);\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onInit(\" + computer.flags.powered + \")\");\n }\n\n /*\n * Bind any \"power\", \"reset\" and \"save\" buttons. An \"erase\" button was also considered,\n * but \"reset\" now provides a way to force the machine to start from scratch again, so \"erase\"\n * may be redundant now.\n */\n Component.bindComponentControls(computer, eComputer, PDP10.APPCLASS);\n\n /*\n * Power on the computer, giving every component the opportunity to reset or restore itself.\n */\n if (computer.fAutoPower) computer.wait(computer.powerOn);\n }\n }\n }\n\n /**\n * ComputerPDP10.show()\n *\n * When exit() is using an \"onbeforeunload\" handler, this \"onpageshow\" handler allows us to repower everything,\n * without either resetting or restoring. We call powerOn() with a special resume value (RESUME_REPOWER) if the\n * computer is already marked as \"ready\", meaning the browser didn't change anything. This \"repower\" process\n * should be very quick, essentially just marking all components as powered again (so that, for example, the Video\n * component will start drawing again) and firing the CPU up again.\n */\n static show()\n {\n var aeComputers = Component.getElementsByClass(document, PDP10.APPCLASS, \"computer\");\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n var computer = /** @type {ComputerPDP10} */ (Component.getComponentByType(\"Computer\", parmsComputer['id']));\n if (computer) {\n\n computer.flags.unloading = false;\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onShow(\" + computer.fInitialized + \",\" + computer.flags.powered + \")\");\n }\n\n /*\n * Note that the FIRST 'onpageshow' event, and therefore the first show() callback, occurs\n * AFTER the the initial 'onload' event, and at that point in time, fInitialized will not be set yet.\n * So, practically speaking, the first show() callback isn't all that useful.\n */\n if (computer.fInitialized && !computer.flags.powered) {\n /**\n * Repower the computer, notifying every component to continue running as-is.\n */\n computer.powerOn(ComputerPDP10.RESUME_REPOWER);\n }\n }\n }\n }\n\n /**\n * ComputerPDP10.exit()\n *\n * The Computer is currently the only component that uses an \"exit\" handler, which Web.onExit() defines as\n * either an \"unload\" or \"onbeforeunload\" handler. This gives us the opportunity to save the machine state,\n * using our powerOff() function, before the page goes away.\n *\n * It's worth noting that \"onbeforeunload\" offers one nice feature when used instead of \"onload\": the entire\n * page (and therefore this entire application) is retained in its current state by the browser (well, some\n * browsers), so that if you go to a new URL, either by entering a new URL in the same window/tab, or by pressing\n * the FORWARD button, and then you press the BACK button, the page is immediately restored to its previous state.\n *\n * In fact, that's how some browsers operate whether you have an \"onbeforeunload\" handler or not; in other words,\n * an \"onbeforeunload\" handler doesn't change the page retention behavior of the browser. By contrast, the mere\n * presence of an \"onunload\" handler generally causes a browser to throw the page away once the handler returns.\n *\n * However, in order to safely use \"onbeforeunload\", we must add yet another handler (\"onpageshow\") to repower\n * everything, without either resetting or restoring. Hence, the ComputerPDP10.show() function, which calls powerOn()\n * with a special resume value (RESUME_REPOWER) if the computer is already marked as \"ready\", meaning the browser\n * didn't change anything. This \"repower\" process should be very quick, essentially just marking all components as\n * powered again (so that, for example, the Video component will start drawing again) and firing the CPU up again.\n *\n * Reportedly, some browsers (eg, Opera) don't support \"onbeforeunload\", in which case Component will have to use\n * \"unload\" instead. But even when the page must be rebuilt from scratch, the combination of browser cache and\n * localStorage means the simulation should be restored and become operational almost immediately.\n */\n static exit()\n {\n var aeComputers = Component.getElementsByClass(document, PDP10.APPCLASS, \"computer\");\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n var computer = /** @type {ComputerPDP10} */ (Component.getComponentByType(\"Computer\", parmsComputer['id']));\n if (computer) {\n\n /*\n * Added a new flag that Component functions (eg, notice()) should check before alerting the user.\n */\n computer.flags.unloading = true;\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onExit(\" + computer.flags.powered + \")\");\n }\n\n if (computer.flags.powered) {\n /**\n * Power off the computer, giving every component an opportunity to save its state,\n * but only if 'resume' has been set AND there is no valid resume path (because if a valid resume\n * path exists, we'll always load our state from there, and not from whatever we save here).\n */\n computer.powerOff(!!(computer.resume && !computer.sResumePath), true);\n }\n }\n }\n }\n}\n\nComputerPDP10.STATE_FAILSAFE = \"failsafe\";\nComputerPDP10.STATE_VALIDATE = \"validate\";\nComputerPDP10.STATE_TIMESTAMP = \"timestamp\";\nComputerPDP10.STATE_VERSION = \"version\";\nComputerPDP10.STATE_HOSTURL = \"url\";\nComputerPDP10.STATE_BROWSER = \"browser\";\nComputerPDP10.STATE_USERID = \"user\";\n\n/*\n * The following constants define all the resume options. Negative values (eg, RESUME_REPOWER) are for\n * internal use only, and RESUME_DELETE is not documented (it provides a way of deleting ALL saved states\n * whenever a resume is declined). As a result, the only \"end-user\" values are 0, 1 and 2.\n */\nComputerPDP10.RESUME_REPOWER = -1; // resume without changing any state (for internal use only)\nComputerPDP10.RESUME_NONE = 0; // default (no resume)\nComputerPDP10.RESUME_AUTO = 1; // automatically save/restore state\nComputerPDP10.RESUME_PROMPT = 2; // automatically save but conditionally restore (WARNING: if restore is declined, any state is discarded)\nComputerPDP10.RESUME_DELETE = 3; // same as RESUME_PROMPT but discards ALL machines states whenever ANY machine restore is declined (undocumented)\n\n/*\n * Initialize every Computer on the page.\n */\nWeb.onInit(ComputerPDP10.init);\nWeb.onShow(ComputerPDP10.show);\nWeb.onExit(ComputerPDP10.exit);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/state.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass State {\n /**\n * State(component, sVersion, sSuffix)\n *\n * State objects are used by components to save/restore their state.\n *\n * During a save operation, components add data to a State object via set(), and then return\n * the resulting data using data().\n *\n * During a restore operation, the Computer component passes the results of each data() call\n * back to the originating component.\n *\n * WARNING: Since State objects are low-level objects that have no UI requirements, they do not\n * inherit from the Component class, so you should only use class methods of Component, such as\n * Component.assert() (or Debugger methods if the Debugger is available).\n *\n * NOTE: 1.01 is the first version to provide limited save/restore support using localStorage.\n * From that point on, care must be taken to insure that any new version that's incompatible with\n * previous localStorage data be released with a version number that is at least 1 greater,\n * since we're tagging the localStorage data with the integer portion of the version string.\n *\n * @param {Component} component\n * @param {string} [sVersion] is used to append a major version number to the key\n * @param {string} [sSuffix] is used to append any additional suffixes to the key\n */\n constructor(component, sVersion, sSuffix)\n {\n this.id = component.id;\n this.dbg = component.dbg;\n this.json = \"\";\n this.state = {};\n this.fLoaded = this.fParsed = false;\n this.key = State.key(component, sVersion, sSuffix);\n this.unload(component.parms);\n }\n\n /**\n * set(id, data)\n *\n * @this {State}\n * @param {number|string} id\n * @param {Object|string} data\n */\n set(id, data)\n {\n try {\n this.state[id] = data;\n } catch(e) {\n Component.log(e.message);\n }\n }\n\n /**\n * get(id)\n *\n * @this {State}\n * @param {number|string} id\n * @return {Object|string|null}\n */\n get(id)\n {\n return this.state[id] || null;\n }\n\n /**\n * data()\n *\n * @this {State}\n * @return {Object}\n */\n data()\n {\n return this.state;\n }\n\n /**\n * load(json)\n *\n * WARNING: Make sure you follow this call with either a call to parse() or unload(),\n * because any stringified data that we've loaded isn't usable until it's been parsed.\n *\n * @this {State}\n * @param {string|null} [json]\n * @return {boolean} true if state exists in localStorage, false if not\n */\n load(json)\n {\n if (json) {\n this.json = json;\n this.fLoaded = true;\n this.fParsed = false;\n return true;\n }\n if (this.fLoaded) {\n /*\n * This is assumed to be a redundant load().\n */\n return true;\n }\n if (Web.hasLocalStorage()) {\n var s = Web.getLocalStorageItem(this.key);\n if (s) {\n this.json = s;\n this.fLoaded = true;\n if (DEBUG) Component.log(\"localStorage(\" + this.key + \"): \" + s.length + \" bytes loaded\");\n return true;\n }\n }\n return false;\n }\n\n /**\n * parse()\n *\n * This completes the load() operation, by parsing what was loaded, on the assumption there\n * might be some benefit to deferring parsing until we've given the user a chance to confirm.\n * Otherwise, load() could have just as easily done this, too.\n *\n * @this {State}\n * @return {boolean} true if successful, false if error\n */\n parse()\n {\n var fSuccess = true;\n if (!this.fParsed) {\n try {\n this.state = JSON.parse(this.json);\n this.fParsed = true;\n } catch (e) {\n Component.error(e.message || e);\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * store()\n *\n * @this {State}\n * @return {boolean} true if successful, false if error\n */\n store()\n {\n var fSuccess = true;\n if (Web.hasLocalStorage()) {\n var s = JSON.stringify(this.state);\n if (Web.setLocalStorageItem(this.key, s)) {\n if (DEBUG) Component.log(\"localStorage(\" + this.key + \"): \" + s.length + \" bytes stored\");\n } else {\n /*\n * WARNING: Because browsers tend to disable all alerts() during an \"unload\" operation,\n * it's unlikely anyone will ever see the \"quota\" errors that occur at this point. Need to\n * think of some way to notify the user that there's a problem, and offer a way of cleaning\n * up old states.\n */\n Component.error(\"Unable to store \" + s.length + \" bytes in browser local storage\");\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * toString()\n *\n * @this {State}\n * @return {string} JSON-encoded state\n */\n toString()\n {\n return this.state? JSON.stringify(this.state) : this.json;\n }\n\n /**\n * unload(parms)\n *\n * This discards any data saved via set() or loaded via load(), creating an empty State object.\n * Note that you have to follow this call with an explicit call to store() if you want to remove\n * the state from localStorage as well.\n *\n * @this {State}\n * @param {Object} [parms]\n */\n unload(parms)\n {\n this.json = \"\";\n this.state = {};\n this.fLoaded = this.fParsed = false;\n if (parms) this.set(\"parms\", parms);\n }\n\n /**\n * clear(fAll)\n *\n * This unloads the current state, and then clears ALL localStorage for the current machine,\n * independent of version, to reduce the chance of orphaned states wasting part of our limited allocation.\n *\n * @this {State}\n * @param {boolean} [fAll] true to unconditionally clear ALL localStorage for the current domain\n */\n clear(fAll)\n {\n this.unload();\n var aKeys = Web.getLocalStorageKeys();\n for (var i = 0; i < aKeys.length; i++) {\n var sKey = aKeys[i];\n if (sKey && (fAll || sKey.substr(0, this.key.length) == this.key)) {\n Web.removeLocalStorageItem(sKey);\n if (DEBUG) Component.log(\"localStorage(\" + sKey + \") removed\");\n aKeys.splice(i, 1);\n i = 0;\n }\n }\n }\n\n /**\n * State.key(component, sVersion, sSuffix)\n *\n * This encapsulates the key generation code.\n *\n * @param {Component} component\n * @param {string} [sVersion] is used to append a major version number to the key\n * @param {string} [sSuffix] is used to append any additional suffixes to the key\n * @return {string} key\n */\n static key(component, sVersion, sSuffix)\n {\n var key = component.id;\n if (sVersion) {\n var i = sVersion.indexOf('.');\n if (i > 0) key += \".v\" + sVersion.substr(0, i);\n }\n if (sSuffix) {\n key += \".\" + sSuffix;\n }\n return key;\n }\n\n /**\n * State.compress(aSrc)\n *\n * @param {Array.<number>|null} aSrc\n * @return {Array.<number>|null} is either the original array (aSrc), or a smaller array of \"count, value\" pairs (aComp)\n */\n static compress(aSrc)\n {\n if (aSrc) {\n var iSrc = 0;\n var iComp = 0;\n var aComp = [];\n while (iSrc < aSrc.length) {\n var n = aSrc[iSrc];\n\n var iCompare = iSrc + 1;\n while (iCompare < aSrc.length && aSrc[iCompare] === n) iCompare++;\n aComp[iComp++] = iCompare - iSrc;\n aComp[iComp++] = n;\n iSrc = iCompare;\n }\n if (aComp.length < aSrc.length) return aComp;\n }\n return aSrc;\n }\n\n /**\n * State.decompress(aComp)\n *\n * @param {Array.<number>} aComp\n * @param {number} nLength is expected length of decompressed data\n * @return {Array.<number>}\n */\n static decompress(aComp, nLength)\n {\n var iDst = 0;\n var aDst = new Array(nLength);\n var iComp = 0;\n while (iComp < aComp.length - 1) {\n var c = aComp[iComp++];\n var n = aComp[iComp++];\n while (c--) {\n aDst[iDst++] = n;\n }\n }\n\n return aDst;\n }\n\n /**\n * State.compressEvenOdd(aSrc)\n *\n * This is a very simple variation on compress() that compresses all the EVEN elements of aSrc first,\n * followed by all the ODD elements. This tends to work better on EGA video memory, because when odd/even\n * addressing is enabled (eg, for text modes), the DWORD values tend to alternate, which is the worst case\n * for compress(), but the best case for compressEvenOdd().\n *\n * One wrinkle we support: if the first element is uninitialized, then we assume the entire array is undefined,\n * and return an empty compressed array. Conversely, decompressEvenOdd() will take an empty compressed array\n * and return an uninitialized array.\n *\n * @param {Array.<number>|null} aSrc\n * @return {Array.<number>|null} is either the original array (aSrc), or a smaller array of \"count, value\" pairs (aComp)\n */\n static compressEvenOdd(aSrc)\n {\n if (aSrc) {\n var iComp = 0, aComp = [];\n if (aSrc[0] !== undefined) {\n for (var off = 0; off < 2; off++) {\n var iSrc = off;\n while (iSrc < aSrc.length) {\n var n = aSrc[iSrc];\n var iCompare = iSrc + 2;\n while (iCompare < aSrc.length && aSrc[iCompare] === n) iCompare += 2;\n aComp[iComp++] = (iCompare - iSrc) >> 1;\n aComp[iComp++] = n;\n iSrc = iCompare;\n }\n }\n }\n if (aComp.length < aSrc.length) return aComp;\n }\n return aSrc;\n }\n\n /**\n * State.decompressEvenOdd(aComp, nLength)\n *\n * This is the counterpart to compressEvenOdd(). Note that because there's nothing in the compressed sequence\n * that differentiates a compress() sequence from a compressEvenOdd() sequence, you simply have to be consistent:\n * if you used even/odd compression, then you must use even/odd decompression.\n *\n * @param {Array.<number>} aComp\n * @param {number} nLength is expected length of decompressed data\n * @return {Array.<number>}\n */\n static decompressEvenOdd(aComp, nLength)\n {\n var iDst = 0;\n var aDst = new Array(nLength);\n var iComp = 0;\n while (iComp < aComp.length - 1) {\n var c = aComp[iComp++];\n var n = aComp[iComp++];\n while (c--) {\n aDst[iDst] = n;\n iDst += 2;\n }\n /*\n * The output of a \"count,value\" pair will never exceed the end of the output array, so as soon as we reach it\n * the first time, we know it's time to switch to ODD elements, and as soon as we reach it again, we should be\n * done.\n */\n\n if (iDst == nLength) iDst = 1;\n }\n\n return aDst;\n }\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/embed.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * We now support asynchronous XML and XSL file loads; simply set fAsync (below) to true.\n *\n * NOTE: For that support to work, we have to keep track of the number of machines on the page\n * (ie, how many embedMachine() calls were issued), reduce the count as each machine XML file\n * is fully transformed into HTML, and when the count finally returns to zero, notify all the\n * machine component init() handlers.\n *\n * Also, to prevent those init() handlers from running prematurely, we must disable all page\n * notification events at the start of the embedding process (Web.enablePageEvents(false)) and\n * re-enable them at the end (Web.enablePageEvents(true)).\n */\nvar fAsync = true;\nvar cAsyncMachines = 0;\n\n/**\n * loadXML(sFile, idMachine, sAppName, sAppClass, sParms, fResolve, display, done)\n *\n * This is the preferred way to load all XML and XSL files. It uses getResource()\n * to load them as strings, which parseXML() can massage before parsing/transforming them.\n *\n * For example, since I've been unable to get the XSLT document() function to work inside any\n * XSL document loaded by JavaScript's XSLT processor, that has prevented me from dynamically\n * loading any XML machine file that uses the \"ref\" attribute to refer to and incorporate\n * another XML document.\n *\n * To solve that, I've added an fResolve parameter that tells parseXML() to fetch any\n * referenced documents ITSELF and insert them into the XML string prior to parsing, instead\n * of relying on the XSLT template to pull them in. That fetching is handled by resolveXML(),\n * which iterates over the XML until all \"refs\" have been resolved (including any nested\n * references).\n *\n * Also, XSL files with a <!DOCTYPE [...]> cause MSIE's Microsoft.XMLDOM.loadXML() function\n * to choke, so I strip that out prior to parsing as well.\n *\n * TODO: Figure out why the XSLT document() function works great when the web browser loads an\n * XML file (and the associated XSL file) itself, but does not work when loading documents via\n * JavaScript XSLT support. Is it broken, is it a security issue, or am I just calling it wrong?\n *\n * @param {string} sXMLFile\n * @param {string|null|undefined} idMachine\n * @param {string|null|undefined} sAppName\n * @param {string|null|undefined} sAppClass\n * @param {string|null|undefined} sParms (machine parameters, if any)\n * @param {string|null|undefined} sClass (an optional machine class name used to style the machine)\n * @param {boolean} fResolve is true to resolve any \"ref\" attributes\n * @param {function(string)} display\n * @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)\n */\nfunction loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n{\n var doneLoadXML = function(sURLName, sXML, nErrorCode) {\n if (nErrorCode) {\n if (!sXML) sXML = \"unable to load \" + sXMLFile + \" (\" + nErrorCode + \")\";\n done(sXML, null);\n return;\n }\n parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done);\n };\n display(\"Loading \" + sXMLFile + \"...\");\n Web.getResource(sXMLFile, null, fAsync, doneLoadXML);\n}\n\n/**\n * parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n *\n * Generates an XML document from an XML string. This function also provides a work-around for XSLT's\n * lack of support for the document() function (at least on some browsers), by replacing every reference\n * tag (ie, a tag with a \"ref\" attribute) with the contents of the referenced file.\n *\n * @param {string} sXML\n * @param {string|null} sXMLFile\n * @param {string|null|undefined} idMachine\n * @param {string|null|undefined} sAppName\n * @param {string|null|undefined} sAppClass\n * @param {string|null|undefined} sParms (machine parameters, if any)\n * @param {string|null|undefined} sClass (an optional machine class name used to style the machine)\n * @param {boolean} fResolve is true to resolve any \"ref\" attributes; default is false\n * @param {function(string)} display\n * @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)\n */\nfunction parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n{\n var buildXML = function(sXML, sError) {\n if (sError) {\n done(sError, null);\n return;\n }\n if (idMachine) {\n\n /*\n * A more sensible place to record the machine XML would be embedMachine(), like we do for the\n * XSL file, but since we're about to modify the original machine XML, it's best to record it now.\n */\n Component.addMachineResource(idMachine, sXMLFile, sXML);\n\n var sURL = sXMLFile;\n if (sURL && sURL.indexOf('/') < 0 && window.location.pathname.slice(-1) == '/') {\n sURL = window.location.pathname + sURL;\n }\n /*\n * We embed the URL of the XML file both as a separate \"xml\" attribute for easy access from the\n * XSL file, and as part of the \"parms\" attribute for easy access from machines (see getMachineParm()).\n */\n if (!sParms) {\n sParms = '{';\n } else if (sParms.slice(-1) == '}') {\n sParms = sParms.slice(0, -1);\n if (sParms.length > 1) sParms += ',';\n } else { // sParms must just be a \"state\" file, so encode it as a \"state\" property\n sParms = '{state:\"' + sParms + '\",';\n }\n sParms += 'url:\"' + sURL + '\"}';\n /*\n * Note that while we no longer generate a machine XML file with a \"state\" attribute (because it's\n * encoded inside the \"parms\" attribute), the XSL file must still cope with \"state\" attributes inside\n * other XML files; for example, manifest XML files like /apps/pcx86/1981/visicalc/manifest.xml contain\n * machine elements with \"state\" attributes that must still be passed down to the computer element\n * \"the old fashioned way\".\n *\n * Until/unless that changes, components.xsl cannot be simplified as much as I might have hoped.\n */\n if (typeof resources == 'object') sURL = null; // turn off URL inclusion if we have embedded resources\n sParms = sParms.replace(/\\$/g, \"$$$$\");\n if (sClass) {\n /*\n * If there's no hard-coded \"class\" attribute in the machine tag, then we can set one in the final\n * replacement below, just like we do for sParms and sURL. However, if a \"class\" attribute already\n * exists, we need alter it and then zap the sClass variable.\n */\n var match = sXML.match(/(<machine[^>]*\\sclass=)(['\"])(.*?)(\\2.*?>)/);\n if (match) {\n sXML = sXML.replace(match[0], match[1] + match[2] + sClass + match[4]);\n sClass = null;\n }\n }\n sXML = sXML.replace(/(<machine[^>]*\\sid=)(['\"]).*?\\2/, \"$1$2\" + idMachine + \"$2\" + (sClass? ' class=\"' + sClass + '\"' : '') + (sParms? \" parms='\" + sParms + \"'\" : \"\") + (sURL? ' url=\"' + sURL + '\"' : ''));\n }\n\n if (!fResolve) {\n /*\n * I'm trying to switch to a shared components.xsl (at least for all PC-class machines),\n * but in the interim, that means hacking the XSL file on the fly to reflect the actual class.\n */\n sXML = sXML.replace(/(<xsl:variable name=\"APPNAME\">).*?(<\\/xsl:variable>)/, \"$1\" + sAppName + \"$2\");\n sXML = sXML.replace(/(<xsl:variable name=\"APPCLASS\">).*?(<\\/xsl:variable>)/, \"$1\" + sAppClass + \"$2\");\n\n /*\n * Non-COMPILED kludge to replace the version number template in the XSL file (which we assume we're reading,\n * since fResolve is false) with whatever XMLVERSION we extracted from the XML file (see corresponding kludge below).\n *\n * ES6 ALERT: Template strings.\n */\n if (!COMPILED && XMLVERSION) {\n sXML = sXML.replace(/<xsl:variable name=\"APPVERSION\"\\/>/, `<xsl:variable name=\"APPVERSION\">${XMLVERSION}</xsl:variable>`);\n }\n }\n\n /*\n * If the resource we requested is not really an XML file (or the file didn't exist and the server simply returned\n * a message like \"Cannot GET /devices/pc/machine/5150/cga/64kb/donkey/machine.xml\"), we'd like to display a more\n * meaningful message, because the XML DOM parsers will blithely return a document that contains nothing useful; eg:\n *\n * This page contains the following errors:error on line 1 at column 1:\n * Document is empty Below is a rendering of the page up to the first error.\n *\n * Supposedly, the IE XML DOM parser will throw an exception, but I haven't tested that, and unless all other\n * browsers do that, that's not helpful.\n *\n * The best I can do at this stage (assuming Web.getResource() didn't drop any error information on the floor)\n * is verify that the requested resource \"looks like\" valid XML (in other words, it begins with a '<').\n */\n var xmlDoc = null;\n if (sXML.charAt(0) == '<') {\n try {\n /*\n * Another hack for MSIE, which fails to load XSL documents containing a <!DOCTYPE [...]> tag.\n *\n * This is also why the XSLTProcessor 'transformToFragment' method in Microsoft Edge silently failed,\n * so I had pull this hack out of the \"ActiveXObject\" code. And rather than add yet-another Microsoft\n * browser check, I'm going to try doing this across the board, and hope that none of the other XSLT\n * processors fail *without* the DOCTYPE tag.\n */\n if (!fResolve) {\n sXML = sXML.replace(/<!DOCTYPE(.|[\\r\\n])*]>\\s*/g, \"\");\n }\n /*\n * Beginning with Microsoft Edge and the corresponding release of Windows 10, all the\n * 'ActiveXObject' crud has gone away; but of course, this code must remain in place if\n * we want to continue supporting older Internet Explorer browsers (ie, back to IE9).\n */\n /** @namespace window.ActiveXObject */\n if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1\n xmlDoc = new window.ActiveXObject(\"Microsoft.XMLDOM\");\n xmlDoc.async = false;\n xmlDoc['loadXML'](sXML);\n } else {\n /** @namespace window.DOMParser */\n xmlDoc = (new window.DOMParser()).parseFromString(sXML, \"text/xml\");\n }\n } catch(e) {\n xmlDoc = null;\n sXML = e.message;\n }\n } else {\n sXML = \"unrecognized XML: \" + (sXML.length > 255? sXML.substr(0, 255) + \"...\" : sXML);\n }\n done(sXML, xmlDoc);\n };\n if (sXML) {\n if (PRIVATE) sXML = sXML.replace(/\\/library.xml/, \"/private/library.xml\");\n if (fResolve) {\n resolveXML(sXML, display, buildXML);\n return;\n }\n buildXML(sXML, null);\n return;\n }\n done(\"no data\" + (sXMLFile? \" for file: \" + sXMLFile : \"\"), null);\n}\n\n/**\n * resolveXML(sXML, display, done)\n *\n * Replaces every tag with a \"ref\" attribute with the contents of the corresponding file.\n *\n * TODO: Fix some of the limitations of this code, such as: 1) requiring the \"ref\" attribute\n * to appear as the tag's first attribute, 2) requiring the \"ref\" attribute to be double-quoted,\n * and 3) requiring the \"ref\" tag to be self-closing.\n *\n * @param {string} sXML\n * @param {function(string)} display\n * @param {function(string,(string|null))} done (the first string contains the resolved XML data, the second is for any error message)\n */\nfunction resolveXML(sXML, display, done)\n{\n var matchRef;\n var reRef = /<([a-z]+)\\s+ref=\"(.*?)\"(.*?)\\/>/g;\n\n if ((matchRef = reRef.exec(sXML))) {\n\n var sRefFile = matchRef[2];\n\n var doneReadXML = function(sURLName, sXMLRef, nErrorCode) {\n if (nErrorCode || !sXMLRef) {\n done(sXML, \"unable to resolve XML reference: \" + matchRef[0] + \" (\" + nErrorCode + \")\");\n return;\n }\n /*\n * If there are additional attributes in the \"referring\" XML tag, we want to insert them\n * into the \"referred\" XML tag; attributes that don't exist in the referred tag should be\n * appended, and attributes that DO exist should be overwritten.\n */\n var sRefAttrs = matchRef[3];\n if (sRefAttrs) {\n var aXMLRefTag = sXMLRef.match(new RegExp(\"<\" + matchRef[1] + \"[^>]*>\"));\n if (aXMLRefTag) {\n var sXMLNewTag = aXMLRefTag[0];\n /*\n * Iterate over all the attributes in the \"referring\" XML tag (sRefAttrs)\n */\n var matchAttr;\n var reAttr = /( [a-z]+=)(['\"])(.*?)\\2/gi;\n while ((matchAttr = reAttr.exec(sRefAttrs))) {\n if (sXMLNewTag.toLowerCase().indexOf(matchAttr[1].toLowerCase()) < 0) {\n /*\n * This is the append case....\n */\n sXMLNewTag = sXMLNewTag.replace(\">\", matchAttr[0] + \">\");\n } else {\n /*\n * This is the overwrite case....\n */\n sXMLNewTag = sXMLNewTag.replace(new RegExp(matchAttr[1] + \"(['\\\"])(.*?)\\\\1\"), matchAttr[0]);\n }\n }\n if (aXMLRefTag[0] != sXMLNewTag) {\n sXMLRef = sXMLRef.replace(aXMLRefTag[0], sXMLNewTag);\n }\n } else {\n done(sXML, \"missing <\" + matchRef[1] + \"> in \" + sRefFile);\n return;\n }\n }\n\n /*\n * Apparently when a Windows Azure server delivers one of my XML files, it may modify the first line:\n *\n * <?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n\n *\n * I didn't determine exactly what it was doing at this point (probably just changing the \\n to \\r\\n),\n * but in any case, relaxing the following replace() solved it.\n */\n sXMLRef = sXMLRef.replace(/<\\?xml[^>]*>[\\r\\n]*/, \"\");\n\n sXML = sXML.replace(matchRef[0], sXMLRef);\n\n resolveXML(sXML, display, done);\n };\n\n display(\"Loading \" + sRefFile + \"...\");\n Web.getResource(sRefFile, null, fAsync, doneReadXML);\n return;\n }\n done(sXML, null);\n}\n\n/**\n * embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * This allows to you embed a machine on a web page, by transforming the machine XML into HTML.\n *\n * @param {string} sAppName is the app name (eg, \"PCx86\")\n * @param {string} sAppClass is the app class (eg, \"pcx86\"); also known as the machine class\n * @param {string} sVersion is the app version (eg, \"1.15.7\")\n * @param {string} idMachine\n * @param {string|undefined} sXMLFile\n * @param {string|undefined} sXSLFile\n * @param {string|undefined} sParms (machine parameters, if any)\n * @param {string|undefined} sClass (an optional machine class name used to style the machine)\n * @return {boolean} true if successful, false if error\n */\nfunction embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n var eMachine, eWarning, fSuccess = true;\n\n if (!sXMLFile) {\n sXMLFile = \"machine.xml\";\n if (!sXSLFile) sXSLFile = \"components.xsl\";\n }\n \n cAsyncMachines++;\n Component.addMachine(idMachine);\n\n var doneMachine = function() {\n\n if (!--cAsyncMachines) {\n if (fAsync) Web.enablePageEvents(true);\n }\n };\n\n var displayError = function(sError) {\n Component.log(sError);\n displayMessage(\"Error: \" + sError);\n if (fSuccess) doneMachine();\n fSuccess = false;\n };\n\n var displayMessage = function(sMessage) {\n if (eWarning === undefined) {\n /*\n * Our MarkOut module (in convertMDMachineLinks()) creates machine containers that look like:\n *\n * <div id=\"' + sMachineID + '\" class=\"machine-placeholder\"><p>Embedded PC</p><p class=\"machine-warning\">...</p></div>\n *\n * with the \"machine-warning\" paragraph pre-populated with a warning message that the user will\n * see if nothing at all happens. But hopefully, in the normal case (and especially the error case),\n * *something* will have happened.\n *\n * Note that it is the HTMLOut module (in processMachines()) that ultimately decides which scripts to\n * include and then generates the embedXXX() call.\n */\n var aeWarning = (eMachine && Component.getElementsByClass(eMachine, \"machine-warning\"));\n eWarning = (aeWarning && aeWarning[0]) || eMachine;\n }\n if (eWarning) eWarning.innerHTML = Str.escapeHTML(sMessage);\n };\n\n try {\n eMachine = document.getElementById(idMachine);\n if (eMachine) {\n\n /*\n * If we have a 'css' resource, add it to the page first.\n */\n var css;\n if (typeof resources == \"object\" && (css = resources['css'])) {\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n // noinspection JSDeprecatedSymbols\n if (style.styleSheet) {\n // noinspection JSDeprecatedSymbols\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n head.appendChild(style);\n }\n\n if (!sXSLFile) {\n /*\n * Now that PCjs is an open-source project, we can make the following test more flexible,\n * and revert to the internal template if DEBUG *or* internal version (instead of *and*).\n *\n * Third-party sites that don't use the PCjs server will ALWAYS want to specify a fully-qualified\n * path to the XSL file, unless they choose to mirror our folder structure.\n */\n var sAppFolder = sAppClass;\n if (DEBUG || !sVersion) {\n if (sAppClass != \"c1pjs\") sAppFolder = \"shared\";\n sXSLFile = \"/modules/\" + sAppFolder + \"/templates/components.xsl\";\n } else {\n if (sAppClass.substr(0, 3) == \"pdp\") sAppFolder = \"pdpjs\";\n sXSLFile = \"/versions/\" + sAppFolder + \"/\" + sVersion + \"/components.xsl\";\n }\n }\n\n var processXML = function(sXML, xml) {\n if (!xml) {\n displayError(sXML);\n return;\n }\n\n /*\n * Non-COMPILED kludge to extract the version number from the stylesheet path in the machine XML file;\n * we don't need this code in COMPILED (non-DEBUG) releases, because APPVERSION is hard-coded into them.\n */\n if (!COMPILED) {\n var aMatch = sXML.match(/<\\?xml-stylesheet[^>]* href=(['\"])[^'\"]*?\\/([0-9.]*)\\/([^'\"]*)\\1/);\n if (aMatch) {\n XMLVERSION = aMatch[2];\n }\n }\n\n var transformXML = function(sXSL, xsl) {\n if (!xsl) {\n displayError(sXSL);\n return;\n }\n\n /*\n * Record the XSL file, in case someone wants to save the entire machine later.\n * \n * NOTE: sXSLFile will never be undefined by this point, but apparently the Closure Compiler doesn't realize that. \n */\n Component.addMachineResource(idMachine, sXSLFile || \"\", sXSL);\n\n /*\n * The <machine> template in components.xsl now generates a \"machine div\" that makes\n * the div we required the caller of embedMachine() to provide redundant, so instead\n * of appending this fragment to the caller's node, we REPLACE the caller's node.\n * This works only because because we ALSO inject the caller's \"machine div\" ID into\n * the fragment's ID during parseXML().\n *\n * eMachine.innerHTML = sFragment;\n *\n * Also, if the transform function fails, make sure you're using the appropriate\n * \"components.xsl\" and not a \"machine.xsl\", because the latter will not produce valid\n * embeddable HTML (and is the most common cause of failure at this final stage).\n */\n displayMessage(\"Processing \" + sXMLFile + \"...\");\n\n /*\n * Beginning with Microsoft Edge and the corresponding release of Windows 10, all the\n * 'ActiveXObject' crud has gone away; but of course, this code must remain in place if\n * we want to continue supporting older Internet Explorer browsers (ie, back to IE9).\n */\n if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1\n var sFragment = xml['transformNode'](xsl);\n if (sFragment) {\n eMachine.outerHTML = sFragment;\n doneMachine();\n } else {\n displayError(\"transformNodeToObject failed\");\n }\n }\n else if (document.implementation && document.implementation.createDocument) {\n var xsltProcessor = new XSLTProcessor();\n xsltProcessor['importStylesheet'](xsl);\n var eFragment = xsltProcessor['transformToFragment'](xml, document);\n if (eFragment) {\n /*\n * This fails in Microsoft Edge...\n *\n var machine = eFragment.getElementById(idMachine);\n if (!machine) {\n displayError(\"machine generation failed: \" + idMachine);\n } else\n */\n if (eMachine.parentNode) {\n eMachine.parentNode.replaceChild(eFragment, eMachine);\n doneMachine();\n } else {\n /*\n * NOTE: This error can occur if our Node web server, when processing a folder with\n * both a manifest.xml with a machine.xml reference AND a README.md containing a\n * machine link, generates duplicate embedXXX() calls for the same machine; if the\n * first embedXXX() call finds its target, subsequent calls for the same target will\n * fail.\n *\n * Technically, such a folder is in a misconfigured state, but it happens, in part\n * because when we switched to the Jekyll web server, we had to add machine links to\n * all README.md files where we had previously relied on manifest.xml or machine.xml\n * processing. This is because the Jekyll web server currently doesn't process XML\n * files, nor is support for that likely to be added any time soon; it was a nice\n * feature of the Node web server, but it's not clear that it's worth doing for Jekyll.\n */\n displayError(\"invalid machine element: \" + idMachine);\n }\n } else {\n displayError(\"transformToFragment failed\");\n }\n } else {\n /*\n * Perhaps I should have performed this test at the outset; on the other hand, I'm\n * not aware of any browsers don't support one or both of the above XSLT transformation\n * methods, so treat this as a bug.\n */\n displayError(\"unable to transform XML: unsupported browser\");\n }\n };\n /*\n * NOTE: sXSLFile will never be undefined by this point, but apparently the Closure Compiler doesn't realize that. \n */\n loadXML(sXSLFile || \"\", null, sAppName, sAppClass, null, null, false, displayMessage, transformXML);\n };\n\n if (sXMLFile.charAt(0) != '<') {\n loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, true, displayMessage, processXML);\n } else {\n parseXML(sXMLFile, null, idMachine, sAppName, sAppClass, sParms, sClass, false, displayMessage, processXML);\n }\n } else {\n displayError(\"missing machine element: \" + idMachine);\n }\n } catch(e) {\n displayError(e.message);\n }\n return fSuccess;\n}\n\n/**\n * embedC1P(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedC1P(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"C1Pjs\", \"c1pjs\", APPVERSION, idMachine, sXMLFile, sXSLFile, undefined, sClass);\n}\n\n/**\n * embedPCx86(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPCx86(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PCx86\", \"pcx86\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPC8080(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPC8080(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PC8080\", \"pc8080\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPDP10(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPDP10(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PDPjs\", \"pdp10\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPDP11(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPDP11(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PDPjs\", \"pdp11\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * findMachineComponent(idMachine, sType)\n *\n * @param {string} idMachine\n * @param {string} sType\n * @return {Component|null}\n */\nfunction findMachineComponent(idMachine, sType)\n{\n return Component.getComponentByType(sType, idMachine + \".machine\");\n}\n\n/**\n * commandMachine(control, fSingle, idMachine, sComponent, sCommand, sValue)\n *\n * Use Component methods to find the requested component for a specific machine, and if the component is found,\n * then check its 'exports' table for an entry matching the specified command string, and if an entry is found, then\n * the corresponding function is called with the specified data.\n *\n * @param {Object} control\n * @param {boolean} fSingle\n * @param {string} idMachine\n * @param {string} sComponent\n * @param {string} sCommand\n * @param {string} [sValue]\n * @return {boolean}\n */\nfunction commandMachine(control, fSingle, idMachine, sComponent, sCommand, sValue)\n{\n if (sCommand == \"script\") {\n if (Component.processScript(idMachine, sValue)) {\n if (fSingle) control.disabled = true;\n return true;\n }\n return false;\n }\n if (sComponent) {\n var component = Component.getComponentByType(sComponent, idMachine + \".machine\");\n if (component) {\n var exports = component['exports'];\n if (exports) {\n var fnCommand = exports[sCommand];\n if (fnCommand) {\n if (fnCommand.call(component, sValue)) {\n if (fSingle) control.disabled = true;\n return true;\n }\n return false;\n }\n }\n }\n }\n console.log(\"unimplemented: commandMachine('\" + idMachine + \"','\" + sComponent + \"','\" + sCommand + \"','\" + sValue + \"')\");\n return false;\n}\n\n/**\n * Prevent the Closure Compiler from renaming functions we want to export, by adding them as global properties.\n *\n * TODO: Consider making all these functions properties on a single global object (eg, 'PCjs'), to minimize global\n * pollution and risk of name collision.\n */\nif (APPNAME == \"C1Pjs\") {\n window['embedC1P'] = embedC1P;\n}\nif (APPNAME == \"PCx86\") {\n window['embedPC'] = embedPCx86; // WARNING: embedPC() deprecated as of v1.23.0\n window['embedPCx86'] = embedPCx86;\n}\nif (APPNAME == \"PC8080\") {\n window['embedPC8080'] = embedPC8080;\n}\nif (APPNAME == \"PDPjs\") {\n window['embedPDP10'] = embedPDP10;\n window['embedPDP11'] = embedPDP11;\n}\n\nwindow['commandMachine'] = commandMachine;\n\nwindow['enableEvents'] = Web.enablePageEvents;\nwindow['sendEvent'] = Web.sendPageEvent;\n"]} \ No newline at end of file +{"version":3,"file":"pdp10.js","lineCount":311,"mappings":"A;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAA,CAAA,CCoCAA,GAC4D,UAAxD,EAAsB,MAAO,OAAA,iBAA7B,CACA,MAAA,eADA,CAEA,QAAQ,CAAC,CAAD,CAAS,CAAT,CAAmB,CAAnB,CAA+B,CAOjC,CAAJ,EAAc,KAAA,UAAd,EAAiC,CAAjC,EAA2C,MAAA,UAA3C,GACA,CAAA,CAAO,CAAP,CADA,CACmB,CAAA,MADnB,CAPqC,CDvC3C,CE2CAC,GAb2B,WAAlB,EAAC,MAAO,OAAR,EAAiC,MAAjC,GAa0B,IAb1B,CAa0B,IAb1B,CAEe,WAAlB,EAAC,MAAO,OAAR,EAA2C,IAA3C,EAAiC,MAAjC,CAAmD,MAAnD,CAW6B,IChBd,SAAA,GAAQ,EAAG,CAE9BC,EAAA,CAAqB,QAAQ,EAAG,EAE3BD,GAAA,OAAL,GACEA,EAAA,OADF,CAC6BE,EAD7B,CAJ8B,CAehC,IAAAA,GAAuD,QAAQ,EAAG,CAChE,IAAI,EAAU,CAUd,OAJA,SAAe,CAAC,CAAD,CAAkB,CAC/B,MA9BoBC,gBA8BpB,EAC6B,CAD7B,EACgD,EADhD,EACuD,CAAA,EAFxB,CAP+B,CAAZ,EAoBzB;QAAA,GAAQ,EAAG,CACtCF,EAAA,EACA,KAAI,EAAiBD,EAAA,OAAA,SAChB,EAAL,GACE,CADF,CACmBA,EAAA,OAAA,SADnB,CAEMA,EAAA,OAAA,CAAyB,UAAzB,CAFN,CAK8C,WAA9C,EAAI,MAAO,MAAA,UAAA,CAAgB,CAAhB,CAAX,EACED,EAAA,CACI,KAAA,UADJ,CACqB,CADrB,CACqC,CAC/B,aAAc,CAAA,CADiB,CAE/B,SAAU,CAAA,CAFqB,CAO/B,MAAO,QAAQ,EAAG,CAChB,MAAOK,GAAA,CAAsB,IAAtB,CADS,CAPa,CADrC,CAeFC,GAAA,CAA6B,QAAQ,EAAG,EAxBF,CAkChB,QAAA,GAAQ,CAAC,CAAD,CAAQ,CACtC,IAAI,EAAQ,CACZ,OAAOC,GAAA,CAA0B,QAAQ,EAAG,CAC1C,MAAI,EAAJ,CAAY,CAAA,OAAZ,CACS,CACL,KAAM,CAAA,CADD,CAEL,MAAO,CAAA,CAAM,CAAA,EAAN,CAFF,CADT,CAMS,CAAC,KAAM,CAAA,CAAP,CAPiC,CAArC,CAF+B,CA0BZ,QAAA,GAAQ,CAAC,CAAD,CAAO,CACzCD,EAAA,EAEI,EAAA,CAAW,CAAC,KAAM,CAAP,CAKf,EAAA,CAASL,EAAA,OAAA,SAAT,CAAA,CAA8C,QAAQ,EAAG,CAAE,MAAO,KAAT,CACzD,OAAyC,EATA;AC5F3C,IAAAO,GACmD,UAA/C,EAAuB,MAAO,OAAA,OAA9B,CACA,MAAA,OADA,CAEA,QAAQ,CAAC,CAAD,CAAY,CAEP,QAAA,EAAQ,EAAG,EACtB,CAAA,UAAA,CAAiB,CACjB,OAAO,KAAI,CAJO,CAHxB,CCgByB,EAAA,IAAiC,UAAjC,EAAC,MAAO,OAAA,eAAR,CACrB,EAAA,CAAA,MAAA,eADqB,KAAA,CAErB,IAAA,EAvByC,EAAA,CAAA,CAC3C,IAAI,GAAI,CAAC,GAAG,CAAA,CAAJ,CAAR,CACI,GAAI,EACR,IAAI,CACF,EAAA,UAAA,CAAc,EACd,GAAA,CAAO,EAAA,GAAP,OAAA,CAFE,CAGF,MAAO,CAAP,CAAU,EAGZ,EAAA,CAAO,CAAA,CAToC,CAuBzC,EAAA,CAAA,EAAA,CAAA,QAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,UAAA,CAAA,CAAA,IAAA,CAAA,UAAA,GAAA,CAAA,CAAA,KAAA,KAAA,SAAA,CAAA,CAAA,CAAA,oBAAA,CAAA,CAAA,MAAA,EAAA,CAAA,CAAA,IAFqB,CAAzB,IAAAC,GAAyB,ECSN;QAAA,GAAQ,CAAC,CAAD,CAAY,CAAZ,CAAwB,CACjD,CAAA,UAAA,CAAsBD,EAAA,CAAqB,CAAA,UAArB,CACL,EAAA,UAAA,YAAA,CAAkC,CACnD,IAAIC,EAAJ,CAGuBA,EACrB,CAAe,CAAf,CAA0B,CAA1B,CAJF,KAQE,KAAK,IAAI,CAAT,GAAc,EAAd,CACE,GAAS,WAAT,EAAI,CAAJ,CAIA,GAAI,MAAA,iBAAJ,CAA6B,CAC3B,IAAI,EAAa,MAAA,yBAAA,CAAgC,CAAhC,CAA4C,CAA5C,CACb,EAAJ,EACE,MAAA,eAAA,CAAsB,CAAtB,CAAiC,CAAjC,CAAoC,CAApC,CAHyB,CAA7B,IAOE,EAAA,CAAU,CAAV,CAAA,CAAe,CAAA,CAAW,CAAX,CAKrB,EAAA,GAAA,CAAwB,CAAA,UA5ByB,CCXhC,QAAA,GAAQ,CAAC,CAAD,CAAS,CAAT,CAAqC,CAC9D,GAAK,CAAL,CAAA,CACA,IAAI,EAAMR,EACN,EAAA,CAAQ,CAAA,MAAA,CAAa,GAAb,CACZ,KAAK,IAAI,EAAI,CAAb,CAAgB,CAAhB,CAAoB,CAAA,OAApB,CAAmC,CAAnC,CAAsC,CAAA,EAAtC,CAA2C,CACzC,IAAI,EAAM,CAAA,CAAM,CAAN,CACJ,EAAN,GAAa,EAAb,GAAmB,CAAA,CAAI,CAAJ,CAAnB,CAA8B,EAA9B,CACA,EAAA,CAAM,CAAA,CAAI,CAAJ,CAHmC,CAKvC,CAAA,CAAW,CAAA,CAAM,CAAA,OAAN,CAAqB,CAArB,CACX,EAAA,CAAO,CAAA,CAAI,CAAJ,CACP,EAAA,CAAO,CAAA,CAAS,CAAT,CACP,EAAJ,EAAY,CAAZ,EAA4B,IAA5B,EAAoB,CAApB,EACAD,EAAA,CACI,CADJ,CACS,CADT,CACmB,CAAC,aAAc,CAAA,CAAf,CAAqB,SAAU,CAAA,CAA/B,CAAqC,MAAO,CAA5C,CADnB,CAZA,CAD8D;AC1BhEU,EAAA,CAAiB,YAAjB,CAA+B,QAAQ,CAAC,CAAD,CAAO,CAC5C,MAAI,EAAJ,CAAiB,CAAjB,CAUe,QAAQ,CAAC,CAAD,CAAI,CACzB,CAAA,CAAI,MAAA,CAAO,CAAP,CACJ,IAAI,KAAA,CAAM,CAAN,CAAJ,EAAsB,QAAtB,GAAgB,CAAhB,EAAwC,CAAC,QAAzC,GAAkC,CAAlC,EAA2D,CAA3D,GAAqD,CAArD,CAA8D,MAAO,EACrE,KAAI,EAAI,IAAA,MAAA,CAAW,IAAA,IAAA,CAAS,CAAT,CAAX,CACR,OAAW,EAAJ,CAAA,CAAA,CAAQ,CAAC,CAAT,CAAa,CAJK,CAXiB,CAA9C,CCAAA,GAAA,CAAiB,iBAAjB,CAAoC,QAAQ,CAAC,CAAD,CAAO,CACjD,MAAO,EAAP,EAAe,QADkC,CAAnD,CCAAA,GAAA,CAAiB,WAAjB,CAA8B,QAAQ,CAAC,CAAD,CAAO,CAC3C,MAAI,EAAJ,CAAiB,CAAjB,CAUe,QAAQ,CAAC,CAAD,CAAI,CACzB,MAAO,KAAA,IAAA,CAAS,CAAT,CAAP,CAAqB,IAAA,IADI,CAXgB,CAA7C,CV6NIC;IAAAA,GAAOA,CACDC,GAAQD,CADPA,CACUE,GAASF,CADnBA,CACsBG,GAASH,CAD/BA,CACkCI,GAASJ,CAD3CA,CAC8CK,GAASL,CADvDA,CAC0DM,GAASN,CADnEA,CACsEO,GAASP,CAD/EA,CACkFQ,GAASR,CAD3FA,CAEFS,GAAST,CAFPA,CAEUU,GAASV,CAFnBA,CAEsBW,GAAQX,EAF9BA,CAEkCY,GAAQZ,EAF1CA,CAE8Ca,GAAQb,EAFtDA,CAE0Dc,GAAQd,EAFlEA,CAEsEe,GAAQf,EAF9EA,CAEkFgB,GAAQhB,EAF1FA,CAGFiB,GAAQjB,EAHNA,CAGUkB,GAAQlB,EAHlBA,CAGsBmB,GAAQnB,EAH9BA,CAGkCoB,GAAQpB,EAH1CA,CAG8CqB,GAAQrB,EAHtDA,CAG0DsB,GAAQtB,EAHlEA,CAGsEuB,GAAQvB,EAH9EA,CAGkFwB,GAAQxB,EAH1FA,CAIFyB,GAAQzB,EAJNA,CAIU0B,GAAQ1B,EAJlBA,CAIsB2B,GAAQ3B,EAJ9BA,CAIkC4B,GAAQ5B,EAJ1CA,CAKCA,IAAKA,EALNA,CAKaA,IAAKA,EALlBA,CAKyBA,IAAKA,EAL9BA,CAKqCA,IAAKA,EAL1CA,CAKiDA,EAAKA,EALtDA,CAK6DA,IAAKA,EALlEA,CAKyEA,OAAKA,EAL9EA,CAKqFA,IAAKA,EAL1FA,CAMCA,IAAKA,EANNA,CAMaA,IAAKA,EANlBA,CAMyBA,IAAKA,EAN9BA,CAMqCA,IAAKA,EAN1CA,CAMiDA,IAAKA,EANtDA,CAM6DA,IAAKA,EANlEA,CAMyEA,IAAKA,EAN9EA,CAMqFA,IAAKA,EAN1FA,CAOCA,EAAKA,EAPNA,CAOaA,EAAKA,EAPlBA,CAOyBA,EAAKA,EAP9BA,CAOqCA,EAAKA,EAP1CA,CAOiDA,EAAKA,EAPtDA,CAO6DA,EAAKA,EAPlEA,CAOyEA,EAAKA,EAP9EA,CAOqFA,EAAKA,EAP1FA,CAQCA,EAAKA,EARNA,CAQaA,EAAKA,EARlBA,CAQyBA,IAAKA,EAR9BA,CAQqCA,IAAKA,EAR1CA,CAQiDA,OAAKA,EARtDA,CAQ6DA,OAAKA,EARlEA,CAQyEA,OAAKA,EAR9EA,CAQqFA,IAAKA,EAR1FA,CASCA,IAAKA,EATNA,CASc6B,GAAI7B,EATlBA,CAS0B8B,GAAI9B,EAT9BA,CASsC+B,GAAI/B,EAT1CA,CASkDgC,GAAIhC,EATtDA,CAS8DiC,EAAIjC,EATlEA,CAS0EkC,GAAIlC,EAT9EA,CASsFmC,GAAInC,EAT1FA,CAUEoC,GAAIpC,EAVNA,CAUcqC,GAAIrC,EAVlBA,CAU0BsC,GAAItC,EAV9BA,CAUsCuC,GAAIvC,EAV1CA,CAUkDwC,GAAIxC,EAVtDA,CAU8DyC,GAAIzC,EAVlEA,CAU0E0C,GAAI1C,EAV9EA,CAUsF2C,GAAI3C,EAV1FA,CAWE4C,GAAI5C,EAXNA,CAWc6C,EAAI7C,EAXlBA,CAW0B8C,GAAI9C,EAX9BA,CAWsC+C,GAAI/C,EAX1CA,CAWkDgD,GAAIhD,EAXtDA;AAW8DiD,GAAIjD,EAXlEA,CAW0EkD,GAAIlD,EAX9EA,CAWsFmD,GAAInD,EAX1FA,CAYEoD,GAAIpD,EAZNA,CAYcqD,GAAIrD,EAZlBA,CAY0BsD,GAAItD,EAZ9BA,CAYqCA,IAAKA,EAZ1CA,CAYiDA,KAAKA,EAZtDA,CAY6DA,IAAKA,EAZlEA,CAYyEA,IAAKA,EAZ9EA,CAYqFA,EAAKA,EAZ1FA,CAaCA,IAAKA,EAbNA,CAacuD,GAAIvD,EAblBA,CAa0BwD,GAAIxD,EAb9BA,CAasCyD,GAAIzD,EAb1CA,CAakD0D,EAAG1D,GAbrDA,CAa8D2D,EAAG3D,GAbjEA,CAa0E4D,GAAG5D,GAb7EA,CAasF6D,GAAG7D,GAbzFA,CAcE8D,GAAI9D,GAdNA,CAcc+D,GAAG/D,GAdjBA,CAc0BgE,GAAGhE,GAd7BA,CAcsCiE,EAAGjE,GAdzCA,CAckDkE,GAAGlE,GAdrDA,CAc8DmE,GAAGnE,GAdjEA,CAc0EoE,EAAGpE,GAd7EA,CAcsFqE,GAAGrE,GAdzFA,CAeEsE,EAAItE,GAfNA,CAecuE,EAAGvE,GAfjBA,CAe0BwE,EAAGxE,GAf7BA,CAesCyE,GAAGzE,GAfzCA,CAekD0E,EAAG1E,GAfrDA,CAe8D2E,GAAG3E,GAfjEA,CAe0E4E,GAAG5E,GAf7EA,CAesF6E,GAAG7E,GAfzFA,CAgBE8E,EAAI9E,GAhBNA,CAgBc+E,EAAG/E,GAhBjBA,CAgB0BgF,EAAGhF,GAhB7BA,CAgBqCA,IAAIA,GAhBzCA,CAgBiDA,IAAIA,GAhBrDA,CAgB6DA,IAAIA,GAhBjEA,CAgByEA,IAAIA,GAhB7EA,CAgBoFiF,GAAKjF,GAhBzFA,CA0RPkF;QAAO,GAAQ,CAACT,CAAD,CAAIU,CAAJ,CACf,CAGI,GAAIV,CAAJ,CAAO,CACEU,CAAL,GAAWA,CAAX,CAAkB,EAAlB,CADG,KAGKC,CAHL,CAICC,EAA4B,CAA5BA,CAAWZ,CAAAa,QAAA,CAAU,GAAV,CACXD,EAAJ,GAAaZ,CAAb,CAAiBA,CAAAc,QAAA,CAAU,IAAV,CAAgB,EAAhB,CAAjB,CAEA,KAAAC,EAAKJ,CAALI,CAAgBf,CAAAgB,OAAA,CAAS,CAAT,CACA,IAAhB,EAAIL,CAAJ,EACID,CACA,CADO,CACP,CAAAC,CAAA,CAAW,EAFf,EAIqB,GAJrB,EAISA,CAJT,GAKID,CACA,CADO,EACP,CAAAC,CAAA,CAAW,EANf,CAQII,EAAJ,EAAUJ,CAAV,CACIX,CADJ,CACQA,CAAAiB,OAAA,CAAS,CAAT,CADR,EAIIF,CAiBA,CAjBKJ,CAiBL,CAjBgBX,CAAAiB,OAAA,CAAS,CAAT,CAAY,CAAZ,CAiBhB,CAhBgB,IAAhB,EAAIN,CAAJ,EAAwBC,CAAxB,EAA+C,IAA/C,EAAmCD,CAAnC,EACID,CACA,CADO,CACP,CAAAC,CAAA,CAAW,EAFf,EAIqB,IAAhB,EAAIA,CAAJ,EAAoC,IAApC,EAAwBA,CAAxB,EACDD,CACA,CADO,CACP,CAAAC,CAAA,CAAW,EAFV,EAIgB,IAAhB,EAAIA,CAAJ,EACDD,CACA,CADO,EACP,CAAAC,CAAA,CAAW,EAFV,EAIgB,IAJhB,EAIIA,CAJJ,GAKDD,CACA,CADO,EACP,CAAAC,CAAA,CAAW,EANV,CAQL,CAAII,CAAJ,EAAUJ,CAAV,GAAoBX,CAApB,CAAwBA,CAAAiB,OAAA,CAAS,CAAT,CAAxB,CArBJ,CAuBAF,EAAA,CAAKG,CAAL,CAAgBlB,CAAAmB,MAAA,CAAS,EAAT,CACA,IAAhB,EAAID,CAAJ,EAAmC,GAAnC,EAAuBA,CAAvB,EACIR,CACA,CADO,CACP,CAAAQ,CAAA,CAAW,EAFf,EAIqB,GAAhB,EAAIA,CAAJ,EACDR,CACA,CADO,EACP,CAAAQ,CAAA,CAAW,EAFV,EAIgB,GAAhB,EAAIA,CAAJ,EAAmC,GAAnC,EAAuBA,CAAvB,EACDR,CACA,CADO,EACP,CAAAQ,CAAA,CAAW,EAFV,EAIgB,GAAhB,EAAIA,CAAJ,CACDA,CADC,CACU,KADV,CAGgB,GAAhB,EAAIA,CAAJ,CACDA,CADC,CACU,QADV,CAGgB,GAHhB,EAGIA,CAHJ,GAIDA,CAJC,CAIU,WAJV,CAMDH,EAAJ,EAAUG,CAAV,GAAoBlB,CAApB,CAAwBA,CAAAmB,MAAA,CAAQ,CAAR,CAAY,EAAZ,CAAxB,CAAyCD,CAAzC,CA7DG,KAoECf,CAAGiB,EAAAA,CAAQ,CACH,GAAZ,EAAIV,CAAJ,GACQW,CADR,CACgBrB,CAAAqB,MAAA,CAAQ,qBAAR,CADhB;CAGQrB,CACA,CADIqB,CAAA,CAAM,CAAN,CACJ,CAAAD,CAAA,CAAQ,EAAR,GAAeC,CAAA,CAAM,CAAN,CAAf,EAA2B,EAA3B,EAAiC,GAAjC,CAJR,CAOmBrB,EAAAA,CAAAA,CAAnB,KA/GJ,CA+G0BU,CA/G1B,CA+G0BA,CA/G1B,GAAqB,EAArB,EAAaA,CAAb,CACY,EAAZ,EAAIA,CAAJ,CAAqD,IAArD,GAAuBV,CAAAqB,MAAA,CAAQ,gBAAR,CAAvB,CACY,CAAZ,EAAIX,CAAJ,CAAgD,IAAhD,GAAsBV,CAAAqB,MAAA,CAAQ,YAAR,CAAtB,CACY,CADZ,EACIX,CADJ,EAC+C,IAD/C,GACsBV,CAAAqB,MAAA,CAAQ,WAAR,CAHtB,CAA0D,IAA1D,GAAgCrB,CAAAqB,MAAA,CAAQ,YAAR,CA+G5B,GAA+B,CAACC,KAAA,CAAMnB,CAAN,CAAUM,QAAA,CAAST,CAAT,CAAYU,CAAZ,CAAV,CAAhC,CAA8D,CAMtDU,CAAJ,GAMY,CAEJ,CAFAjB,CAEA,GAFOA,CAEP,EAFYoB,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAEZ,EAAArB,CAAA,CADQ,CAAZ,CAAIiB,CAAJ,CACIjB,CADJ,CACSoB,IAAAC,IAAA,CAAS,CAAT,CAAYJ,CAAZ,CADT,CAGQG,IAAAE,MAAA,CAAWtB,CAAX,CAAeoB,IAAAC,IAAA,CAAS,CAAT,CAAY,CAACJ,CAAb,CAAf,CAVZ,CAaA,KAAAM,EAAQvB,CAnBkD,CA5E3D,CAkGP,MAAOuB,EArGX;AAoHAC,QAAO,GAAM,CAAChC,CAAD,CAAIiC,CAAJ,CAAWC,CAAX,CAAgBC,CAAhB,CAA8BC,CAA9B,CACb,CAD2CA,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAY,CAAZ,CAAAA,CAUvC,KAAI/B,EAAI,EACJsB,MAAA,CAAM3B,CAAN,CAAJ,EAA4B,QAA5B,EAAgB,MAAOA,EAAvB,CACIA,CADJ,CACQ,IADR,EASY,CAQR,CARIA,CAQJ,EARkB,EAQlB,CARaA,CAQb,GARqBA,CAQrB,CAR0B,EAQ1B,EAHQ,CAGR,CAHIA,CAGJ,GAFIA,CAEJ,EAFS4B,IAAAC,IAAA,CAASI,CAAT,CAAgBC,CAAhB,CAET,EAAIlC,CAAJ,EAAS4B,IAAAC,IAAA,CAASI,CAAT,CAAgBC,CAAhB,CAAT,GACIA,CADJ,CACUN,IAAAS,KAAA,CAAUT,IAAAU,IAAA,CAAStC,CAAT,CAAV,CAAwB4B,IAAAU,IAAA,CAASL,CAAT,CAAxB,CADV,CAjBJ,CAsBA,KADA,IAAIxC,EAAI2C,CAAJ3C,EAAkB,EACtB,CAAe,CAAf,CAAOyC,CAAA,EAAP,CAAA,CAAkB,CACTzC,CAAL,GACIY,CACA,CADI,GACJ,CADUA,CACV,CAAAZ,CAAA,CAAI2C,CAFR,CAIA,IAAS,IAAT,EAAIpC,CAAJ,CACIK,CAAA,CAAI,GAAJ,CAAUA,CADd,KAEO,CACH,IAAIf,EAAIU,CAAJV,CAAQ2C,CACZ3C,EAAA,EAAW,CAAL,EAAAA,CAAA,EAAe,CAAf,EAAUA,CAAV,CAAkB,EAAlB,CAAyB,EAC/Be,EAAA,CAAIkC,MAAAC,aAAA,CAAoBlD,CAApB,CAAJ,CAA6Be,CAC7BL,EAAA,CAAI4B,IAAAE,MAAA,CAAW9B,CAAX,CAAeiC,CAAf,CAJD,CAMPxC,CAAA,EAbc,CAelB,OAhDyB,IAAA,EAAA0C,GAAAA,CAAAA,CAAU,EAAVA,CAAAA,CAgDzB,EAAiB9B,CA/CrB,CAgHAoC,QAAO,GAAK,CAACzC,CAAD,CAAIkC,CAAJ,CAASQ,CAAT,CACZ,CACSR,CAAL,CAUiB,EAVjB,CAUWA,CAVX,GAUqBA,CAVrB,CAU2B,EAV3B,GAEQ1B,CAEA,CAFIoB,IAAAe,IAAA,CAAS3C,CAAT,CAEJ,CAAAkC,CAAA,CADK,MAAT,EAAI1B,CAAJ,CACU,CADV,CAEgB,QAAT,EAAIA,CAAJ,CACG,CADH,CAGG,EARd,CAWA,OAAOoC,GAAA,CAAW5C,CAAX,CAAc,CAAd,CAAiBkC,CAAjB,CAAsBQ,CAAA,CAAS,IAAT,CAAgB,EAAtC,CAZX;AA4BAG,QAAO,GAAK,CAAC7C,CAAD,CAAIkC,CAAJ,CACZ,CACSA,CAAL,CAQiB,EARjB,CAQWA,CARX,GAQqBA,CARrB,CAQ2B,EAR3B,EAIQA,CAJR,CAGa,KAAT,EADQN,IAAAe,IAAAnC,CAASR,CAATQ,CACR,CACU,CADV,CAGU,EAGd,OAAOoC,GAAA,CAAW5C,CAAX,CAAc,EAAd,CAAkBkC,CAAlB,CAVX,CAmCAY,QAAO,EAAK,CAAC9C,CAAD,CAAIkC,CAAJ,CAASQ,CAAT,CACZ,CACSR,CAAL,CAUiB,CAVjB,CAUWA,CAVX,GAUoBA,CAVpB,CAU0B,CAV1B,GAEQ1B,CAEA,CAFIoB,IAAAe,IAAA,CAAS3C,CAAT,CAEJ,CAAAkC,CAAA,CADK,KAAT,EAAI1B,CAAJ,CACU,CADV,CAEgB,UAAT,EAAIA,CAAJ,CACG,CADH,CAGG,CARd,CAWA,OAAOoC,GAAA,CAAW5C,CAAX,CAAc,EAAd,CAAkBkC,CAAlB,CAAuBQ,CAAA,CAAS,IAAT,CAAgB,EAAvC,CAZX,CAkEAK,QAAO,GAAW,CAACC,CAAD,CAClB,CACI,IAAIC,EAAYD,CAAhB,CAEIrD,EAAIqD,CAAAE,YAAA,CAAsB,GAAtB,CACC,EAAT,EAAIvD,CAAJ,GAAYsD,CAAZ,CAAwBD,CAAA1B,OAAA,CAAiB3B,CAAjB,CAAqB,CAArB,CAAxB,CAKAA,EAAA,CAAIsD,CAAA/B,QAAA,CAAkB,MAAlB,CACI,EAAR,CAAIvB,CAAJ,GAAWsD,CAAX,CAAuBA,CAAA3B,OAAA,CAAiB,CAAjB,CAAoB3B,CAApB,CAAvB,CAQA,OAAOsD,EAlBX,CA+BAE,QAAO,GAAY,CAACH,CAAD,CACnB,CACI,IAAII,EAAa,EAAjB,CACIzD,EAAIqD,CAAAE,YAAA,CAAsB,GAAtB,CACC,EAAT,EAAIvD,CAAJ,GACIyD,CADJ,CACiBJ,CAAA1B,OAAA,CAAiB3B,CAAjB,CAAqB,CAArB,CAAA0D,YAAA,EADjB,CAGA,OAAOD,EANX,CAgBAE,QAAO,GAAQ,CAACjD,CAAD,CAAIkD,CAAJ,CACf,CACI,MAA0D,EAA1D,GAAOlD,CAAAa,QAAA,CAAUqC,CAAV,CAAmBlD,CAAAmD,OAAnB,CAA8BD,CAAAC,OAA9B,CADX;AAUAC,QAAO,GAAU,CAACC,CAAD,CACjB,CACI,MAAOA,EAAAvC,QAAA,CAAc,UAAd,CAA0B,QAAQ,CAACpB,CAAD,CACzC,CACI,MAAO4D,GAAA,CAAkB5D,CAAlB,CADX,CADO,CADX,CA+FA6D,QAAO,GAAG,CAACvD,CAAD,CAAI6B,CAAJ,CACV,CAEI,MAA8CV,CAACnB,CAADmB,CAD/BqC,0CAC+BrC,OAAA,CAAqB,CAArB,CAAwBU,CAAxB,CAFlD,CA+IA4B,QAAO,GAAI,CAACzD,CAAD,CACX,CACI,MAAIkC,OAAAwB,UAAAD,KAAJ,CACWzD,CAAAyD,KAAA,EADX,CAGOzD,CAAAc,QAAA,CAAU,YAAV,CAAwB,EAAxB,CAJX,CA+BJ,IAAAwC,GAAoB,CAChB,OAAK,UADW,CAEhB,OAAK,SAFW,CAGhB,OAAK,SAHW,CAIhB,IAAK,WAJW,CAKhB,IAAK,WALW,CAwIhBK,SAAO,GAAY,CAAC7E,CAAD,CAAIqB,CAAJ,CAAOyD,CAAP,CACnB,CACI,IAAIC,EAAO,CAAX,CACIC,EAAQhF,CAAAqE,OADZ,CAEIY,EAAQ,CAOZ,KANkBC,IAAAA,EAMlB,GANIJ,CAMJ,GALIA,CAKJ,CALgBA,QAAQ,CAAC9E,CAAD,CAAIC,CAAJ,CACpB,CACI,MAAOD,EAAA,CAAIC,CAAJ,CAAQ,CAAR,CAAYD,CAAA,CAAIC,CAAJ,CAAS,EAAT,CAAa,CADpC,CAIJ,EAAO8E,CAAP,CAAcC,CAAd,CAAA,CAAqB,CACjB,IAAIG,EAAUJ,CAAVI,CAAiBH,CAAjBG,EAA2B,CAE/B,KAAAC,EAAgBN,CAAA,CAAUzD,CAAV,CAAarB,CAAA,CAAEmF,CAAF,CAAb,CACI,EAApB,CAAIC,CAAJ,CACIL,CADJ,CACWI,CADX,CACoB,CADpB,EAGIH,CACA,CADQG,CACR,CAAAF,CAAA,CAAQ,CAACG,CAJb,CAJiB,CAWrB,MAAOH,EAAA,CAAQF,CAAR,CAAe,CAACA,CArB3B;AA4GAM,QAAO,GAAU,EACjB,CAD2BC,IAAAA,CAAAA,CAEnBC,EAAQ,EACPD,EAAL,GAAWA,CAAX,CAAkB,IAAIE,IAAtB,CAIA,KAHA,IAAIC,EAAQH,CAAAI,SAAA,EAAZ,CACIC,EAAOL,CAAAM,QAAA,EADX,CAEIC,EAASP,CAAAQ,SAAA,EAATD,CAA2B,CAF/B,CAGSrF,EAAI,CAAb,CAAoB6D,EAApB,CAAgB7D,CAAhB,CAAoCA,CAAA,EAApC,CAAyC,CACrC,IAAIyB,CACJ,QAASA,CAAT,CApEkB8D,aAoEJ7D,OAAA,CAAe1B,CAAf,CAAd,EACA,KAAK,GAAL,CACI+E,CAAA,EAAkB,EAAR,CAAAE,CAAA,CAAa,IAAb,CAAoB,IAC9B,MACJ,MAAK,GAAL,CACIF,CAAA,EAASlD,CAAC,GAADA,CAAOsD,CAAPtD,OAAA,CAAoB,EAApB,CACT,MACJ,MAAK,GAAL,CACIkD,CAAA,EAASS,EAAA,CAAWV,CAAAW,OAAA,EAAX,CAAA9D,OAAA,CAAiC,CAAjC,CAAoC,CAApC,CACT,MACJ,MAAK,GAAL,CACIoD,CAAA,EAASW,EAAA,CAAaL,CAAb,CAAsB,CAAtB,CACT,MACJ,MAAK,GAAL,CACIN,CAAA,EAAWE,CAAD,CAAuB,EAAR,CAAAA,CAAA,CAAaA,CAAb,CAAqB,EAArB,CAA0BA,CAAzC,CAAS,EACnB,MACJ,MAAK,GAAL,CACIF,CAAA,EAASE,CACT,MACJ,MAAK,GAAL,CACIF,CAAA,EAASlD,CAAC,GAADA,CAAOoD,CAAPpD,OAAA,CAAqB,EAArB,CACT,MACJ,MAAK,GAAL,CACIkD,CAAA,EAASlD,CAAC,GAADA,CAAOiD,CAAAa,WAAA,EAAP9D,OAAA,CAAiC,EAAjC,CACT,MACJ,MAAK,GAAL,CACIkD,CAAA,EAASI,CACT,MACJ,MAAK,GAAL,CACIJ,CAAA,EAASS,EAAA,CAAWV,CAAAW,OAAA,EAAX,CACT,MACJ,MAAK,GAAL,CACIV,CAAA,EAASlD,CAAC,GAADA,CAAOwD,CAAPxD,OAAA,CAAsB,EAAtB,CACT;KACJ,MAAK,GAAL,CACIkD,CAAA,EAASW,EAAA,CAAaL,CAAb,CAAsB,CAAtB,CAAA1D,OAAA,CAAgC,CAAhC,CAAmC,CAAnC,CACT,MACJ,MAAK,GAAL,CACIoD,CAAA,EAASM,CACT,MACJ,MAAK,GAAL,CACIN,CAAA,EAASlD,CAAC,GAADA,CAAOiD,CAAAc,WAAA,EAAP/D,OAAA,CAAiC,EAAjC,CACT,MACJ,MAAK,GAAL,CACIkD,CAAA,EAASlD,CAAC,EAADA,CAAMiD,CAAAe,YAAA,EAANhE,OAAA,CAAiC,EAAjC,CACT,MACJ,MAAK,GAAL,CACIkD,CAAA,EAASD,CAAAe,YAAA,EACT,MACJ,SACId,CAAA,EAAStD,CAlDb,CAFqC,CAwDzC,MAAOsD,EA9DX,CAgKJ,IAAAS,GAAa,0DAAA,MAAA,CAAA,GAAA,CAAb,CACAE,GAAe,uFAAA,MAAA,CAAA,GAAA,CAuKXI;QAAO,GAAW,CAACC,CAAD,CAAOC,CAAP,CAAsBC,CAAtB,CAAsCC,CAAtC,CAClB,CAoCmBC,QAAA,EAAQ,EAAG,CACtB,GAA2B,CAA3B,GAAIC,CAAAC,WAAJ,CAEI,MAAO,KA0BX,IAAI,CACAC,CAAA,CAAWC,CAAA,CAAcH,CAAAI,SAAd,CAAiCJ,CAAAK,aAD5C,CAEF,MAAMC,CAAN,CAAW,EAOb,GAAgB,IAAhB,EAAIJ,CAAJ,EAA2C,GAA3C,EAAyBF,CAAAO,OAAzB,GAAmDP,CAAAO,OAAnD,EAAqE9C,CAAAyC,CAAAzC,OAArE,EAAiH,OAAjH,GA0PI+C,MAAA,CAAQA,MAAAC,SAAAC,SAAR,CAAmC,OA1PvC,GAIIC,CAAA,CAAaX,CAAAO,OAAb,EAAgC,EAIhCT,EAAJ,EAAUA,CAAA,CAAKH,CAAL,CAAWO,CAAX,CAAqBS,CAArB,CACV,OAAO,CAACT,CAAD,CAAWS,CAAX,CA/Ce,CArCLf,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAO,MAAP,CAAAA,CAAeC,EAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAS,CAAA,CAAT,CAAAA,CACxC,KACQc,EAAa,CADrB,CACwBT,EAAW,IADnC,CACyCE,EAAW,IAEhD,IAAwB,QAAxB,EAAI,MAAOQ,UAAX,GAAqCV,CAArC,CAAgDU,SAAA,CAAUjB,CAAV,CAAhD,EAEI,MADIG,EACG,EADGA,CAAA,CAAKH,CAAL,CAAWO,CAAX,CAAqBS,CAArB,CACH,CAAA,CAACT,CAAD,CAAWS,CAAX,CAEN,IAAId,CAAJ,EAAkC,UAAlC,EAAc,MAAOe,UAArB,CAKD,MAJAA,UAAA,CAAUjB,CAAV,CAAgB,QAAQ,CAACO,CAAD,CAAWS,CAAX,CACxB,CACQb,CAAJ,EAAUA,CAAA,CAAKH,CAAL,CAAWO,CAAX,CAAqBS,CAArB,CADd,CADA,CAIOP,CAAAA,CAQPT,EAAA,CAAOA,CAAAvE,QAAA,CAAa,iCAAb;AAAgD,+BAAhD,CAaX,KAAI4E,EAAWQ,MAAAK,eAAA,CAAuB,IAAIL,MAAAK,eAA3B,CAAqD,IAAIL,MAAAM,cAAJ,CAAyB,mBAAzB,CAApE,CACIX,EAAe,CAAA,CADnB,CAC0BY,EAAyC,QAAzCA,GAAS,MAAOf,EAAAgB,aAoDtCnB,EAAJ,GACIG,CAAAiB,mBADJ,CACiClB,CADjC,CAMA,IAAIH,CAAJ,EAA2B,QAA3B,EAAY,MAAOA,EAAnB,CAAqC,CAC7BsB,CAAAA,CAAQ,EACZ,KAAK/G,IAAIA,CAAT,GAAcyF,EAAd,CACSA,CAAAuB,eAAA,CAAoBhH,CAApB,CAAL,GACI+G,CACJ,GADWA,CACX,EADoB,MACpB,EAAAA,CAAA,EAAS/G,CAAT,CAAa,MAAb,CAAmBiH,kBAAA,CAAmBxB,CAAA,CAAKzF,CAAL,CAAnB,CAFnB,CAIJ+G,EAAA,CAAQA,CAAA9F,QAAA,CAAc,MAAd,CAAsB,GAAtB,CAER4E,EAAAqB,KAAA,CAAa,MAAb,CAAqB1B,CAArB,CAA2BE,CAA3B,CACAG,EAAAsB,iBAAA,CAAyB,cAAzB,CAAyC,mCAAzC,CACAtB,EAAAuB,KAAA,CAAaL,CAAb,CAXiC,CAArC,IAcIlB,EAAAqB,KAAA,CAAa,KAAb,CAAoB1B,CAApB,CAA0BE,CAA1B,CASA,CARY,aAQZ,EARID,CAQJ,GAPQmB,CAAJ,EACIZ,CACA,CADe,CAAA,CACf,CAAAH,CAAAgB,aAAA;AAAuBpB,CAF3B,EAIII,CAAAwB,iBAAA,CAAyB,uCAAzB,CAGR,EAAAxB,CAAAuB,KAAA,EAGC1B,EAAL,GACIG,CAAAC,WACA,CADqB,CACrB,CAAAG,CAAA,CAAWL,CAAA,EAFf,CAIA,OAAOK,EA1HX;AAqJAqB,QAAO,GAAmB,CAAC9B,CAAD,CAAO+B,CAAP,CAC1B,CACI,IAAI9H,CAAJ,CACIsG,EAAW,CACXyB,GAAQ,IADG,CAEXC,EAAU,IAFC,CAGXC,GAAU,IAHC,CAIXC,GAAU,IAJC,CAOf,IAAuB,GAAvB,EAAIJ,CAAApG,OAAA,CAAa,CAAb,CAAJ,EAAiD,GAAjD,EAA8BoG,CAAApG,OAAA,CAAa,CAAb,CAA9B,CACI,GAAI,CAAA,IACIlC,CADJ,CACO2I,CAEP,IAA0B,MAA1B,EAAIL,CAAAnG,OAAA,CAAa,CAAb,CAAJ,CAOI,KAAUyG,MAAJ,CAAUN,CAAV,CAAN,CAuBA,IAAAO,EADsB,CAA1B,CAAIP,CAAAvG,QAAA,CAAc,IAAd,CAAJ,EAAqD,CAArD,CAA+BuG,CAAAvG,QAAA,CAAc,IAAd,CAA/B,EAAgF,IAAhF,EAA0DuG,CAAAnG,OAAA,CAAa,CAAb,CAAgB,CAAhB,CAA1D,CACW2G,IAAAC,MAAA,CAAWT,CAAAtG,QAAA,CAAc,aAAd,CAA6B,OAA7B,CAAAA,QAAA,CAA8C,cAA9C,CAA8D,EAA9D,CAAX,CADX,CAGWgH,IAAA,CAAK,GAAL,CAAWV,CAAX,CAAmB,GAAnB,CAGXxB,EAAA2B,GAAA,CAAoBI,CAAA,KACpB/B,EAAA4B,GAAA,CAAoBG,CAAA,KAEpB,IAAI7I,CAAJ,CAAQ6I,CAAA,MAAR,CACI/B,CAAAyB,GAAA,CAAkBvI,CADtB,KAGK,IAAIA,CAAJ,CAAQ6I,CAAA,MAAR,CAKD,IADA/B,CAAAyB,GACY,CADUU,KAAJ,CAAqB,CAArB,CAAUjJ,CAAAqE,OAAV,CACN,CAAAsE,CAAA,CAAPnI,CAAO,CAAH,CAAT,CAAoBA,CAApB,CAAwBR,CAAAqE,OAAxB,CAAkC7D,CAAA,EAAlC,CACIsG,CAAAyB,GAAA,CAAgBI,CAAA,EAAhB,CACA,CADwB3I,CAAA,CAAEQ,CAAF,CACxB,CAD+B,GAC/B,CAAAsG,CAAAyB,GAAA,CAAgBI,CAAA,EAAhB,CAAA,CAAyB3I,CAAA,CAAEQ,CAAF,CAAzB,EAAiC,CAAjC,CAAsC,GAPzC,KAWA,IAAIR,CAAJ,CAAQ6I,CAAA,MAAR,CAKD,IADA/B,CAAAyB,GACY,CADUU,KAAJ,CAAqB,CAArB,CAAUjJ,CAAAqE,OAAV,CACN,CAAAsE,CAAA,CAAPnI,CAAO,CAAH,CAAT,CAAoBA,CAApB;AAAwBR,CAAAqE,OAAxB,CAAkC7D,CAAA,EAAlC,CACIsG,CAAAyB,GAAA,CAAgBI,CAAA,EAAhB,CAGA,CAHwB3I,CAAA,CAAEQ,CAAF,CAGxB,CAH+B,GAG/B,CAFAsG,CAAAyB,GAAA,CAAgBI,CAAA,EAAhB,CAEA,CAFyB3I,CAAA,CAAEQ,CAAF,CAEzB,EAFiC,CAEjC,CAFsC,GAEtC,CADAsG,CAAAyB,GAAA,CAAgBI,CAAA,EAAhB,CACA,CADyB3I,CAAA,CAAEQ,CAAF,CACzB,EADiC,EACjC,CADuC,GACvC,CAAAsG,CAAAyB,GAAA,CAAgBI,CAAA,EAAhB,CAAA,CAAyB3I,CAAA,CAAEQ,CAAF,CAAzB,EAAiC,EAAjC,CAAuC,GAT1C,KAYA,CAAIR,CAAJ,CAAQ6I,CAAA,KAAR,EACD/B,CAAAoC,GADC,CACgBlJ,CADhB,CAID8G,CAAAyB,GAJC,CAIiBM,CAGlB/B,EAAAyB,GAAJ,GACSzB,CAAAyB,GAAAlE,OAAL,CAImC,CAJnC,EAISyC,CAAAyB,GAAAlE,OAJT,GAm/BZ8E,CAAA,CA9+BgCrC,CAAAyB,GAAArH,CAAgB,CAAhBA,CA8+BhC,CA7+BgB,CAAA4F,CAAA,CAAW,IANf,GAm/BZqC,CAAA,CAl/BgC,kBAk/BhC,CAl/BqD5C,CAk/BrD,CAj/BgB,CAAAO,CAAA,CAAW,IAFf,CADJ,CAUAA,EAAA0B,EAAA,CAAoBK,CAAA,QApFpB,CAsFF,MAAOzI,CAAP,CAAU,CAw+BhB+I,CAAA,CAv+BwB,uBAu+BxB,CAv+BkD5C,CAu+BlD,CAv+ByD,KAu+BzD,CAv+BiEnG,CAAAgJ,QAu+BjE,CAt+BQ,CAAAtC,CAAA,CAAW,IAFH,CAvFhB,IA4FK,CAIGuC,CAAAA,CAAK,EAELC,EAAAA,CADWhB,CAAAtG,QAAA,CAAc,MAAd,CAAsB,GAAtB,CAAAA,QAAAuH,CAAmC,KAAnCA,CAA0C,EAA1CA,CACCC,MAAA,CAAe,GAAf,CAChB,KAAKhJ,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB8I,CAAAjF,OAAhB,CAAkC7D,CAAA,EAAlC,CAAuC,CAC/BK,CAAAA,CAAIc,QAAA,CAAS2H,CAAA,CAAU9I,CAAV,CAAT,CAAuB,EAAvB,CACR,IAAIgC,KAAA,CAAM3B,CAAN,CAAJ,CAAc,CA09BtBsI,CAAA,CAz9B4B,uBAy9B5B,CAz9BsD5C,CAy9BtD,CAz9B6D,uBAy9B7D,CAz9BuF+C,CAAA,CAAU9I,CAAV,CAy9BvF,CAz9BsG,GAy9BtG,CAx9BY,MAFU,CAId6I,CAAAI,KAAA,CAAQ5I,CAAR,CAAY,GAAZ,CANmC,CAQnCL,CAAJ,EAAS8I,CAAAjF,OAAT;CAA2ByC,CAAAyB,GAA3B,CAA6Cc,CAA7C,CAfC,CAiBL,MAAOvC,EAtHX,CAwJA4C,QAAO,GAAO,EACd,CACI,MAAQ,SAAR,EAAqBtC,MAAA,CAAQA,MAAAC,SAAAsC,KAAR,CAxhEdC,cAwhEP,CADJ,CAyCAC,QAAO,GAAe,EACtB,CACI,GAAyB,IAAzB,EAAIC,EAAJ,CAA+B,CAC3B,IAAIzJ,EAAI,CAAA,CACR,IAAI+G,MAAJ,CACI,GAAI,CACAA,MAAA2C,aAAAC,QAAA,CAgiBIC,mBAhiBJ,CAgiBIA,mBAhiBJ,CAEA,CADA5J,CACA,CA8hBI4J,mBA9hBJ,EADK7C,MAAA2C,aAAAG,QAAA,CA+hBDD,mBA/hBC,CACL,CAAA7C,MAAA2C,aAAAI,WAAA,CA8hBIF,mBA9hBJ,CAHA,CAIF,MAAO7J,CAAP,CAAU,CAERC,CAAA,CAAI,CAAA,CAFI,CAKhByJ,EAAA,CAAoBzJ,CAZO,CAc/B,MAAOyJ,GAfX,CAoCAM,QAAO,GAAmB,CAACC,CAAD,CAC1B,CAEI,GAAIjD,MAAJ,CACI,GAAI,CACA,IAAAkD,EAASlD,MAAA2C,aAAAG,QAAA,CAA4BG,CAA5B,CADT,CAEF,MAAOjK,CAAP,CAAU,EAIhB,MAAOkK,EATX;AAmBAC,QAAO,GAAmB,CAACF,CAAD,CAAOC,CAAP,CAC1B,CACI,GAAI,CAEA,MADAlD,OAAA2C,aAAAC,QAAA,CAA4BK,CAA5B,CAAkCC,CAAlC,CACO,CAAA,CAAA,CAFP,CAGF,MAAOlK,CAAP,CAAU,EAGZ,MAAO,CAAA,CAPX,CA6EAoK,QAAO,GAAW,CAACtJ,CAAD,CAClB,CACI,GAAIkG,MAAJ,CAAY,CACR,IAAIqD,EApJArD,MAAA,CAAQA,MAAAsD,UAAAD,UAAR,CAAqC,EA8JzC,OAAY,KAAZ,EAAOvJ,CAAP,EAAqB,CAAC,CAACuJ,CAAAlI,MAAA,CAAgB,oBAAhB,CAAvB,EAAgE,CAAC,CAACkI,CAAAlI,MAAA,CAAgB,aAAhB,CAAlE,EAAyG,MAAzG,EAAoGrB,CAApG,EAAmH,CAAC,CAACuJ,CAAAlI,MAAA,CAAgB,gBAAhB,CAArH,EAAmL,CAAnL,EAA2JkI,CAAA1I,QAAA,CAAkBb,CAAlB,CAXnJ,CAaZ,MAAO,CAAA,CAdX;AAwFAyJ,QAAO,GAAU,CAACC,CAAD,CACjB,CACI,GAAKC,CAAAA,EAAL,CAAA,CAYiBC,IAAAA,CAAAA,CAEbC,EAAS,EACb,IAAI3D,MAAJ,CAAY,CACH0D,CAAL,GAKIA,CALJ,CAKa1D,MAAAC,SAAA2D,OAAA7I,OAAA,CAA8B,CAA9B,CALb,CAeA,KARA,IAAII,CAAJ,CACI0I,EAAK,KADT,CAEID,EAAS,oBAMb,CAAQzI,CAAR,CAAgByI,CAAAE,KAAA,CAAYJ,CAAZ,CAAhB,CAAA,CACIC,CAAA,CAJOI,kBAAA,CAIO5I,CAAArB,CAAM,CAANA,CAJYc,QAAA,CAAUiJ,CAAV,CAAc,GAAd,CAAnB,CAIP,CAAA,CAJOE,kBAAA,CAI2B5I,CAAArB,CAAM,CAANA,CAJRc,QAAA,CAAUiJ,CAAV,CAAc,GAAd,CAAnB,CAbH,CAoBZ,EAAA,CAAOF,CAnCP,CAGA,MAAOF,GAAA,CAAaD,CAAb,CAAP,EAA8BC,EAAA,CAAaD,CAAA1G,YAAA,EAAb,CAJlC,CA2FAkH,QAAO,GAAa,CAACvK,CAAD,CAAIwK,CAAJ,CAAcC,CAAd,CACpB,CACoBC,QAASC,EAAa,EACtC,CACI,EAAA3K,CACS,EAAT,EAAIA,CAAJ,GACSwK,CAAA,EADT,GACqBxK,CADrB,CACyB,CADzB,EAGQ,EAAR,CAAIA,CAAJ,CACI4K,UAAA,CAAWF,CAAX,CAAiC,CAAjC,CADJ,CAIAD,CAAA,EATJ,CAWAC,CAAA,EAbJ;AA2BAG,QAAO,GAAa,CAACtL,CAAD,CAAuBuL,CAAvB,CACpB,CAGmBN,QAASO,EAAa,EACrC,CACQD,CAAA,CA8+hBKE,GA9+hBL,GAAGC,CAAH,CAAJ,GACIC,CACA,CADQN,UAAA,CAAWJ,CAAX,CAAqBS,CAArB,CACR,CAAAA,CAAA,CA4+hBKD,GA9+hBT,CADJ,CAJJ,IACQC,EAAK,CADb,CACgBC,EAAQ,IADxB,CAC8BC,EAAqB,CAAA,CAS/C5L,EAAA6L,YAAA,CAAgBC,QAAQ,EACxB,CAESF,CAAL,EACSD,CADT,GAEQD,CACA,CAm+hBJK,GAn+hBI,CAAAd,CAAA,EAHR,CAFJ,CASAjL,EAAAgM,aAAA,CAAiBC,QAAQ,EACzB,CAESN,CAAL,GACID,CACA,CA09hBAK,GA19hBA,CAAAd,CAAA,EAFJ,CAFJ,CAOAjL,EAAAkM,UAAA,CAAclM,CAAAmM,WAAd,CAA6BC,QAAQ,EACrC,CAEQT,CAAJ,GACIU,YAAA,CAAaV,CAAb,CACA,CAAAA,CAAA,CAAQ,IAFZ,CAFJ,CAOA3L,EAAAsM,WAAA,CAAetM,CAAAuM,cAAf,CAAiCC,QAAQ,EACzC,CAEQb,CAAJ,GACIU,YAAA,CAAaV,CAAb,CACA,CAAAA,CAAA,CAAQ,IAFZ,CASAC,EAAA,CAAqB,CAAA,CAXzB,CArCJ,CAwEAa,QAAO,GAAW,CAACC,CAAD,CAAQnB,CAAR,CAClB,CACI,GAAIvE,MAAJ,CAAY,CACR,IAAI2F,EAAS3F,MAAA,CAAO0F,CAAP,CAET1F,OAAA,CAAO0F,CAAP,CAAA,CADkB,UAAtB,GAAI,MAAOC,EAAX,CACoBpB,CADpB,CAOoB,QAAsB,EACtC,CACQoB,CAAJ,EAAYA,CAAA,EACZpB,EAAA,EAFJ,CAVI,CADhB,CA0BAqB,QAAO,GAAM,CAACrB,CAAD,CACb,CACIsB,EAAA,KAAAxD,KAAA,CAAoCkC,CAApC,CADJ;AAiCAuB,QAAO,GAAW,CAACC,CAAD,CAClB,CACI,GAAIC,EAAJ,CACI,GAAI,CACA,IAAK,IAAI5M,EAAI,CAAb,CAAgBA,CAAhB,CAAoB2M,CAAA9I,OAApB,CAAgC7D,CAAA,EAAhC,CACI2M,CAAA,CAAI3M,CAAJ,CAAA,EAFJ,CAIF,MAAOJ,CAAP,CAAU,CAsYC+I,CAAA,CAAuC,EAAvC,EArYE,gCAqYF,CArYqC/I,CAAAgJ,QAqYrC,CArYiD,oFAqYjD,EAtYD,CANpB,CAiBAiE,QAAO,GAAgB,CAACC,CAAD,CACvB,CACQ,CAACF,EAAL,EAA+BE,CAA/B,EACIF,EAEA,CAFyB,CAAA,CAEzB,CADIG,EACJ,EADqBC,EAAA,CAAkB,MAAlB,CACrB,CAAIC,EAAJ,EAAqBD,EAAA,CAAkB,MAAlB,CAHzB,EAMAJ,EANA,CAMyBE,CAP7B,CAiBAI,QAAO,GAAa,CAACC,CAAD,CACpB,CACQV,EAAA,CAAuBU,CAAvB,CAAJ,EACIC,EAAA,CAAgBX,EAAA,CAAuBU,CAAvB,CAAhB,CAFR,CAOJ,IAAA9C,GAAe,IAAf,CAEAoC,GAAyB,CACrB,KAAQ,EADa,CAErB,KAAQ,EAFa,CAGrB,KAAQ,EAHa,CAFzB,CAUAM,GAAkB,CAAA,CAVlB,CAWAE,GAAkB,CAAA,CAXlB,CAYAL,GAAyB,CAAA,CAZzB,CAqBAtD,GAAoB,IASpB+D,GAAA,CAAgB,QAAhB,CAA0BC,QAAmB,EAAG,CAC5CP,EAAA,CAAkB,CAAA,CAClBK,GAAA,CAAgBX,EAAA,KAAhB,CAF4C,CAAhD,CAKAY,GAAA,CAAgB,YAAhB,CAA8BE,QAAmB,EAAG,CAChDN,EAAA,CAAkB,CAAA,CAClBG,GAAA,CAAgBX,EAAA,KAAhB,CAFgD,CAApD,CAKAY;EAAA,CAAgBG,EAAA,CAAgB,KAAhB,CAAA,CAAwB,YAAxB,CAAwCA,EAAA,CAAgB,OAAhB,CAAA,CAA0B,UAA1B,CAAuC,gBAA/F,CAAkHC,QAAqB,EAAG,CACtIL,EAAA,CAAgBX,EAAA,KAAhB,CADsI,CAA1I,CA8EIiB,SApBEC,EAoBS,CAAC3H,CAAD,CAAO4H,CAAP,CAAcC,CAAd,CACX,CACI,IAAA7H,KAAA,CAAYA,CAEP4H,EAAL,GAAYA,CAAZ,CAAoB,CAAC,GAAM,EAAP,CAAW,KAAQ,EAAnB,CAApB,CAEA,KAAAE,GAAA,CAAUF,CAAA,GAAV,EAAyB,EACzB,KAAAG,KAAA,CAAYH,CAAA,KACZ,KAAAI,GAAA,CAAeJ,CAAA,QACf,KAAAA,GAAA,CAAaA,CAWE,KAAA,QAAf,CAAiC,EACjC,KAAAK,EAAA,CAAgB,IAAA,SAAhB,CAAmC,EAE/BjO,EAAAA,CAAI,IAAA8N,GAAAvM,QAAA,CAAgB,GAAhB,CACA,EAAR,CAAIvB,CAAJ,CACI,IAAAkO,GADJ,CACuB,IAAAJ,GADvB,EAGI,IAAAK,GACA,CADiB,IAAAL,GAAAnM,OAAA,CAAe,CAAf,CAAkB3B,CAAlB,CACjB,CAAA,IAAAkO,GAAA,CAAmB,IAAAJ,GAAAnM,OAAA,CAAe3B,CAAf,CAAmB,CAAnB,CAJvB,CAWA,KAAAoO,MAAA,CAAa,CACTC,MAAY,CAAA,CADH,CAETC,GAAY,CAAA,CAFH,CAGTC,GAAY,CAAA,CAHH,CAITC,GAAY,CAAA,CAJH,CAKTC,EAAY,CAAA,CALH,CAMTC,GAAY,CAAA,CANH,CAOTC,MAAY,CAAA,CAPH,CAUb,KAAAC,GAAA,CAAe,IACfC,KA8gCAT,MAAAO,MAAA,CAAmB,CAAA,CA7gCnB,KAAAd,GAAA,CAAmBA,CAAnB,EAAkC,CAKlC,KAAAiB,EAAA,CADA,IAAAC,EACA,CAFA,IAAAC,EAEA,CAHA,IAAAC,EAGA,CAHW,IA8BXC,GAAAjG,KAAA,CAfckG,IAed,CA9EJ;AAkGAC,QAAO,GAAkB,CAACjB,CAAD,CAAYkB,CAAZ,CAAmBhH,CAAnB,CACzB,CAKQiH,EAAA,CAAmBnB,CAAnB,CAAJ,EAAqCkB,CAArC,GACIC,EAAA,CAAmBnB,CAAnB,CAAA,CAA8BkB,CAA9B,CADJ,CAC2ChH,CAD3C,CALJ,CA0BAkH,QAAO,GAAO,EACd,CACI,MAAOvK,KAAAwK,IAAA,EAAP,EAAqB,CAAC,IAAIxK,IAD9B,CA+IAyK,QAAO,EAAS,CAACC,CAAD,CAChB,CACQ9I,MAAJ,EACIA,MAAA+I,MAAA,CAAaD,CAAb,CAFR,CAcAE,QAAO,GAAW,CAACC,CAAD,CAClB,CACI,IAAIC,EAAY,CAAA,CACZlJ,OAAJ,GACIkJ,CADJ,CACgBlJ,MAAAmJ,QAAA,CAAeF,CAAf,CADhB,CAGA,OAAOC,EALX,CA8BAE,QAAO,GAAa,CAACC,CAAD,CAAUC,CAAV,CACpB,CACID,CAAA7N,MAAA,EAAiB8N,CAKbA,EAAA,CAAQD,CAAA7N,MACW,KAAnB,CAAI8N,CAAArM,OAAJ,GAAyBoM,CAAA7N,MAAzB,CAAyC8N,CAAAvO,OAAA,CAAauO,CAAArM,OAAb,CAA4B,IAA5B,CAAzC,CAEJoM,EAAAE,UAAA,CAAoBF,CAAAG,aATxB;AA+DAC,QAAO,GAAqB,CAAClB,CAAD,CAAYmB,CAAZ,CAC5B,CADiDC,IAAAA,EAmhFMC,CAjhF/CC,EAAAA,CAAaC,CAAA,CAA6BJ,CAAAK,WAA7B,CAAiDJ,CAAjD,CAA6D,UAA7D,CAEjB,KAAK,IAAIK,EAAW,CAApB,CAAuBA,CAAvB,CAAkCH,CAAA5M,OAAlC,CAAqD+M,CAAA,EAArD,CAII,IAFA,IAAIC,EAAeJ,CAAA,CAAWG,CAAX,CAAAE,WAAnB,CAESC,EAAQ,CAAjB,CAAoBA,CAApB,CAA4BF,CAAAhN,OAA5B,CAAiDkN,CAAA,EAAjD,CAA0D,CACtD,IAAId,EAAUY,CAAA,CAAaE,CAAb,CACd,IAAyB,CAAzB,GAAId,CAAAe,SAAJ,CAAA,CAGA,IAAIC,EAAShB,CAAAiB,aAAA,CAAqB,OAArB,CACb,IAAKD,CAAL,CAEA,IADA,IAAIE,EAAWF,CAAAjI,MAAA,CAAa,GAAb,CAAf,CACSoI,EAAS,CAAlB,CAAqBA,CAArB,CAA8BD,CAAAtN,OAA9B,CAA+CuN,CAAA,EAA/C,CAGI,OADAH,CACQA,CADCE,CAAA,CAASC,CAAT,CACDH,CAAAA,CAAR,EACI,KAAKV,CAAL,CAAiB,UAAjB,CAOI,CANA3C,CAMA,CANQyD,EAAA,CAAuDpB,CAAvD,CAMR,GALkCvL,IAAAA,EAKlC,GALakJ,CAAA,QAKb,EAJIuB,CAAAmC,GAAA,CAAqB1D,CAAA,KAArB,CAAoCA,CAAA,QAApC,CAAiFqC,CAAjF,CAA2FrC,CAAA,MAA3F,CAIJ,CAAAwD,CAAA,CAASD,CAAAtN,OARjB,CATJ,CAFsD,CAPlE,CA8CA0N,QAAO,GAAa,CAACC,CAAD,CACpB,CACI,IAAIxR,CAAJ,CACIyR,EAAc,EAQdD,EAAJ,GAEQA,CAFR,CACuC,CAAnC,EAAKxR,CAAL,CAASwR,CAAAjQ,QAAA,CAAkB,GAAlB,CAAT,EACgBiQ,CAAA7P,OAAA,CAAiB,CAAjB,CAAoB3B,CAApB,CAAwB,CAAxB,CADhB,CAGgB,EAJpB,CAMA,KAAKA,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB0R,EAAA7N,OAAhB,CAA6C7D,CAAA,EAA7C,CAAkD,CAC9C,IAAImP,EAAYwC,EAAA,CAAqB3R,CAArB,CACXwR,EAAL,EAAmBrC,CAAArB,GAAAvM,QAAA,CAAqBiQ,CAArB,CAAnB,EACIC,CAAAxI,KAAA,CAAiBkG,CAAjB,CAH0C,CAMlD,MAAOsC,EAtBX;AAmCAG,QAAO,GAAgB,CAAC9D,CAAD,CACvB,CACI,GAAWpJ,IAAAA,EAAX,GAAIoJ,CAAJ,CAAsB,CAClB,IAAI9N,CASJ,KAAKA,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB0R,EAAA7N,OAAhB,CAA6C7D,CAAA,EAA7C,CACI,GAAI2R,EAAA,CAAqB3R,CAArB,CAAA8N,GAAJ,GAAmCA,CAAnC,CACI,MAAO6D,GAAA,CAAqB3R,CAArB,CAZG,CAmBtB,MAAO,KApBX,CA+BA6R,QAAO,GAAkB,CAACC,CAAD,CAAQN,CAAR,CACzB,CAD4CO,IAAAA,CAExC,IAAcrN,IAAAA,EAAd,GAAIoN,CAAJ,CAAyB,CACrB,IAAI9R,CAMAwR,EAAJ,GAEQA,CAFR,CACuC,CAAnC,EAAKxR,CAAL,CAASwR,CAAAjQ,QAAA,CAAkB,GAAlB,CAAT,EACgBiQ,CAAA7P,OAAA,CAAiB,CAAjB,CAAoB3B,CAApB,CAAwB,CAAxB,CADhB,CAGgB,EAJpB,CAOA,KAAKA,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB0R,EAAA7N,OAAhB,CAA6C7D,CAAA,EAA7C,CACI,GAAI+R,CAAJ,CACQA,CAAJ,EAAqBJ,EAAA,CAAqB3R,CAArB,CAArB,GAA8C+R,CAA9C,CAA8D,IAA9D,CADJ,KAIA,IAAI,EAAAD,CAAA,EAASH,EAAA,CAAqB3R,CAArB,CAAAgG,KAAT,EAA2CwL,CAA3C,EAAyDG,EAAA,CAAqB3R,CAArB,CAAA8N,GAAAvM,QAAA,CAAmCiQ,CAAnC,CAAzD,CAAJ,CACI,MAAOG,GAAA,CAAqB3R,CAArB,CApBM,CAyBzB,MAAO,KA1BX,CAkCAgS,QAAO,GAAiB,CAAC1B,CAAD,CACxB,CACI,IAAI1C,EAAQ,IAEZ,IADItD,CACJ,CADagG,CAAAY,aAAA,CAAqB,YAArB,CACb,CACI,GAAI,CACAtD,CAAA,CAAQpF,IAAA,CAAK,GAAL,CAAW8B,CAAX,CAAoB,GAApB,CADR,CAUF,MAAM1K,CAAN,CAAS,CA3Rf+I,CAAA,CA4RwB/I,CAAAgJ,QA5RxB,CA4RoC,IA5RpC,CA4R2C0B,CA5R3C,CA4RoD,GA5RpD,CA2Re,CAIf,MAAOsD,EAlBX;AAkCAqE,QAAO,EAAkB,CAAC3B,CAAD,CAAUW,CAAV,CAAkBiB,CAAlB,CACzB,CACQA,CAAJ,GAAejB,CAAf,EAAyB,GAAzB,CAA+BiB,CAA/B,CAA2C,SAA3C,CAKA,IAAI5B,CAAA6B,uBAAJ,CACI,MAAO7B,EAAA6B,uBAAA,CAA+BlB,CAA/B,CAPf,KASWhR,CAAGmS,EAAAA,CAAK,EACXC,EAAAA,CAAQ/B,CAAAgC,qBAAA,CAA6B,GAA7B,CACZ,KAAIC,EAAK,IAAIC,MAAJ,CAAW,OAAX,CAAqBvB,CAArB,CAA8B,OAA9B,CACJjR,EAAA,CAAI,CAAT,KAAYC,CAAZ,CAAgBoS,CAAAxO,OAAhB,CAA8B7D,CAA9B,CAAkCC,CAAlC,CAAqCD,CAAA,EAArC,CACQuS,CAAAE,KAAA,CAAQJ,CAAA,CAAMrS,CAAN,CAAA0S,UAAR,CAAJ,EACIN,CAAAnJ,KAAA,CAAQoJ,CAAA,CAAMrS,CAAN,CAAR,CAMR,OAAOoS,EApBX;AAiIAO,QAAO,GAAe,CAACxE,CAAD,CACtB,CAMI,IALA,IAAIyE,EAAW,CAAA,CAAf,CACIC,EAAYC,EAAA,CAAmB3E,CAAnB,CAIhB,CAAO0E,CAAP,EAAoBA,CAAAhP,OAApB,CAAA,CAAsC,CAElC,IAAIkP,EAAUF,CAAAG,OAAA,CAAiB,CAAjB,CAAoB,CAApB,CAAA,CAAuB,CAAvB,CAAd,CACIC,EAAWF,CAAA,CAAQ,CAAR,CADf,CAUIG,EAAc,IAC+B,EAAjD,EAAIC,EAAA5R,QAAA,CAAgC0R,CAAhC,CAAJ,GACIC,CADJ,CACkBE,QAA2B,EAAG,CACxC,MAAO,SAAQ,EAAG,CACdC,EAAA,CAA0BlF,CAA1B,CADc,CADsB,CAA9B,EADlB,CAQA,KAAImF,EAAYC,EAAA,CAAyBN,CAAzB,CAChB,IAAIK,CAAJ,CACI,GAAI,CAACJ,CAAL,CACIN,CAAA,CAAWU,CAAA,CAAUP,CAAA,CAAQ,CAAR,CAAV,CAAsBA,CAAA,CAAQ,CAAR,CAAtB,CAAkCA,CAAA,CAAQ,CAAR,CAAlC,CADf,KAGI,IAAI,CAACO,CAAA,CAAUJ,CAAV,CAAuBH,CAAA,CAAQ,CAAR,CAAvB,CAAmCA,CAAA,CAAQ,CAAR,CAAnC,CAA+CA,CAAA,CAAQ,CAAR,CAA/C,CAAL,CAAiE,KAAjE,CAJR,IAOK,CACDH,CAAA,CAAW,CAAA,CACX,KAAIzD,EAAYqE,EAAA,CAA6BT,CAAA,CAAQ,CAAR,CAA7B,CAAyC5E,CAAzC,CAChB,IAAIgB,CAAJ,CAEI,GADAmE,CACA,CADYG,EAAA,CAA4BR,CAA5B,CACZ,CACIL,CAAA,CAAWU,CAAA,CAAUnE,CAAV,CAAqB4D,CAAA,CAAQ,CAAR,CAArB,CAAiCA,CAAA,CAAQ,CAAR,CAAjC,CADf,KAGK,CACD,IAAIW,EAAUvE,CAAA,QACd,IAAIuE,CAAJ,GACIJ,CADJ,CACgBI,CAAA,CAAQT,CAAR,CADhB,EAIQ,GADAL,CACI,CADO,CAAA,CACP,CAAA,CAACM,CAAL,CACIN,CAAA,CAAWU,CAAAK,KAAA,CAAexE,CAAf,CAA0B4D,CAAA,CAAQ,CAAR,CAA1B,CAAsCA,CAAA,CAAQ,CAAR,CAAtC,CADf,KAGI,IAAI,CAACO,CAAAK,KAAA,CAAexE,CAAf,CAA0B+D,CAA1B,CAAuCH,CAAA,CAAQ,CAAR,CAAvC,CAAmDA,CAAA,CAAQ,CAAR,CAAnD,CAAL,CAAqE,KAThF,CARR,CAyBL,GAAI,CAACH,CAAL,CAAe,CACXjK,CAAA,CAAoB,iBAApB,CAAwCsK,CAAxC,CAAmD,YAAnD,EAAmEK,CAAA,CAAW,SAAX,CAAuB,iBAA1F,EACA,MAFW,CAtDmB,CA4DlCT,CAAJ,EAAiB,CAACA,CAAAhP,OAAlB,EACI,OAAOiP,EAAA,CAAmB3E,CAAnB,CAGX;MAAOyE,EAtEX,CAmIA,CAAA,CAjhHJ,CAAAgB,UAihHIC,EAAAC,SAAA,CAAAA,QAAQ,EACR,CACI,MAAQ,KAAA/F,KAAA,CAAW,IAAAA,KAAX,CAAwB,IAAAD,GAAxB,EAAmC,IAAA9H,KAD/C,CAiCA6N;CAAAvC,GAAA,CAAAA,QAAU,CAACyC,CAAD,CAAYC,CAAZ,CAAsB/D,CAAtB,CACV,CACI,OAAQ+D,CAAR,EACA,KAAK,OAAL,CAWI,MAVK,KAAA/F,EAAA,CAAc+F,CAAd,CAUE,GATH,IAAA/F,EAAA,CAAc+F,CAAd,CACA,CAD0B/D,CAC1B,CAAAA,CAAAgE,QAAA,CAAmB,QAAQ,CAAC9E,CAAD,CAAY,CACnC,MAAO+E,SAAqB,EAAG,CACvB/E,CAAAlB,EAAA,MAAJ,GACIkB,CAAAlB,EAAA,MAAA7L,MADJ,CACwC,EADxC,CAD2B,CADI,CAApB,CAMjB,IANiB,CAQhB,EAAA,CAAA,CACX,MAAK,OAAL,CAqCI,MApCK,KAAA6L,EAAA,CAAc+F,CAAd,CAoCE,GAlCH,IAAA/F,EAAA,CAAc+F,CAAd,CAqBA,CAtByD/D,CAsBzD,CAbA,IAAAkE,GAaA,CAbcC,QAAsB,CAAC1T,CAAD,CAAyB,CACzD,IAAA2T,EAAA,CAAa3T,CAAb,CAAgB,IAAAsF,KAAhB,CACA,OAAO,CAAA,CAFkD,CAa7D,CAtByDiK,CAgBzD7N,MAMA,CANwB,EAMxB,CALA,IAAAkS,MAKA,CALa,QAAQ,CAACrE,CAAD,CAAU,CAC3B,MAAOsE,SAAqB,CAAC7T,CAAD,CAAI,CAC5B8T,EAAA,CAAwBvE,CAAxB,CAAiCvP,CAAjC,CAD4B,CADL,CAAlB,CAjB4CuP,CAiB5C,CAKb,CAAA,IAAAoE,EAAA,CAAe,QAAQ,CAAClF,CAAD,CAAYc,CAAZ,CAAqB,CACxC,MAAOwE,SAAuB,CAAC/T,CAAD,CAAIsF,CAAJ,CAAc,CACnCtF,CAAL,GAAQA,CAAR,CAAY,EAAZ,CACA,IAAIsF,CAAJ,EAAY0O,EAAZ,EAAuD,KAAvD,EAAwChU,CAAAmB,MAAA,CAAS,EAAT,CAAxC,CACQmE,CACJ,GADUtF,CACV,CADcsF,CACd,CADqB,IACrB,CAD4BtF,CAC5B,EAAA8T,EAAA,CAAwBvE,CAAxB,CAAiCvP,CAAjC,CAAqC,IAArC,CAFJ,KAGO,CAxjBnBwP,CAAAA,CAyjByCD,CAzjBjC7N,MACZ,KAAIpC,EAAIkQ,CAAA3M,YAAA,CAwjB8C7C,CAxjB9C,CACA,EAAR,CAAIV,CAAJ,CACIkQ,CADJ,EAujBsDxP,CAvjBtD,CACuB,IADvB,CAGIwP,CAHJ,CAGYA,CAAAvO,OAAA,CAAa,CAAb,CAAgB3B,CAAhB,CAHZ,EAujByDU,CAvjBzD,CAujB6D,GAvjB7D;AAG4CwP,CAAAvO,OAAA,CAAa3B,CAAb,CAojBUU,CApjBOmD,OAAjB,CAKb,KAA/B,CAAgBqM,CAAArM,OAAhB,GAAqCqM,CAArC,CAA6CA,CAAAvO,OAAA,CAAauO,CAAArM,OAAb,CAA4B,IAA5B,CAA7C,CA+iB6CoM,EA9iB7C7N,MAAA,CAAgB8N,CA8iB6BD,EA7iB7CE,UAAA,CA6iB6CF,CA7iBzBG,aA4iBG,CALiC,CADJ,CAA7B,CAWb,IAXa,CAtB0CH,CAsB1C,CAaZ,EAAA,CAAA,CACX,SACI,MAAO,CAAA,CApDX,CADJ,CAsEA4D,EAAAlR,IAAA,CAAAA,QAAG,EACH,EAiEAkR,EAAAS,MAAA,CAAAA,QAAK,EACL,EAeAT,EAAAQ,EAAA,CAAAA,QAAO,EACP,EAaAR,EAAAlN,OAAA,CAAAA,QAAM,CAACjG,CAAD,CACN,CACI,IAAA2T,EAAA,CAAa,IAAArO,KAAb,CAAyB,IAAzB,CAAgCtF,CAAhC,CADJ,CAiBAmT,EAAAM,GAAA,CAAAA,QAAM,CAACzT,CAAD,CAAIiU,CAAJ,CAAgB7G,CAAhB,CACN,CACI,GAAI,CAAC6G,CAAL,CAAiB,CAIb,IAAIC,EAAWpB,EAAA,CAA6B,UAA7B,CAAyC,IAAA1F,GAAzC,CACf,IAAI8G,CAAJ,EAAgBA,CAAAxG,MAAAM,GAAhB,CAEI,MADAmG,QAAAlS,IAAA,CAAY,iCAAZ,CAAgDjC,CAAhD,CACO,CAAA,CAAA,CAPE,CAUe,CAAA,CAAAoN,CAAA,EAAM,IAAA9H,KAAlB2O,EAvzBpB,EAAiBhM,CAAA,EAAqBmF,CAAA,CAAKA,CAAL,CAAU,IAAV,CAAkB,EAAvC,EAuzBApN,CAvzBA,CAwzBjB,OAAO,CAAA,CAZX,CAuBAoU,SAAA,GAAQ,CAARA,CAAQ,CAACpU,CAAD,CACR,CACI,CAAA0N,MAAAO,MAAA,CAAmB,CAAA,CACnB,EAAAwF,GAAA,CAAYzT,CAAZ,CAFJ;AAwBAqU,QAAA,GAAO,CAAPA,CAAO,CACP,CACI,MAAI,EAAA3G,MAAAO,MAAJ,EACI,CAAA0F,EAAA,CAAa,CAAAP,SAAA,EAAb,CAA+B,QAA/B,CACO,CAAA,CAAA,CAFX,EAIO,CAAA,CALX,CAqBAkB,QAAA,GAAO,CAAPA,CAAO,CAACpG,CAAD,CACP,CACQA,CAAJ,GACQ,CAAAR,MAAAC,MAAJ,CACIO,CAAA,EADJ,CAII,CAAAA,GAJJ,CAImBA,CALvB,CAQA,OAAO,EAAAR,MAAAC,MATX,CAoBA4G,QAAA,GAAQ,CAARA,CAAQ,CACR,CACI,GAAI,CAAC,CAAA7G,MAAAO,MAAL,GACI,CAAAP,MAAAC,MACIA,CADgB,CAAA,CAChBA,CAAA,CAAAD,MAAAC,MAFR,EAE0B,CAElB,IAAIO,EAAU,CAAAA,GACd,EAAAA,GAAA,CAAe,IACXA,EAAJ,EAAaA,CAAA,EAJK,CAH9B,CAqBAsG,QAAA,GAAM,CAANA,CAAM,CAACC,CAAD,CACN,CACQ,CAAA/G,MAAAE,GAAJ,GACQ6G,CAAJ,CACI,CAAA/G,MAAAG,GADJ,CAC4B,CAAA,CAD5B,CAEuB7J,IAAAA,EAFvB,GAEWyQ,CAFX,EAGI,CAAAd,EAAA,CAAa,CAAAP,SAAA,EAAb,CAA+B,OAA/B,CAJR,CAOA,OAAO,EAAA1F,MAAAE,GARX,CAoBA8G,QAAA,GAAO,CAAPA,CAAO,CAACC,CAAD,CACP,CACI,GAAI,CAAAjH,MAAAG,GAAJ,CAGI,MAFA,EAAAH,MAAAE,GACA,CADkB,CAAA,CAClB,CAAA,CAAAF,MAAAG,GAAA,CAAwB,CAAA,CAG5B,IAAI,CAAAH,MAAAO,MAAJ,CAEI,MADA,EAAA0F,EAAA,CAAa,CAAAP,SAAA,EAAb,CAA+B,QAA/B,CACO,CAAA,CAAA,CAEX,EAAA1F,MAAAE,GAAA,CAAkB+G,CAClB,OAAO,EAAAjH,MAAAE,GAXX;AAsBAuF,CAAAyB,GAAA,CAAAA,QAAO,EACP,CAEI,MADA,KAAAlH,MAAAK,EACA,CADqB,CAAA,CADzB,CAaAoF,EAAA0B,GAAA,CAAAA,QAAS,CAACC,CAAD,CAAQC,CAAR,CACT,CACQA,CAAJ,GAAe,IAAArH,MAAAK,EAAf,CAAoC,CAAA,CAApC,CACA,OAAO,CAAA,CAFX,CAcAiH,SAAA,GAAc,CAAdA,CAAc,CAAC7H,CAAD,CACd,CADeA,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAc,CAAd,CAAAA,CAEX,OAAgB,EAAAiB,EAAhB,GACQ,CAaA,GAbS,CAAAA,EAaT,GAZAjB,CAYA,CAZcA,CAYd,EAZ6B,CAAAA,GAY7B,EAVA8H,CAUA,CAVc,CAAA7G,EAAAjB,GAUd,CAVqCA,CAUrC,CAHCA,CAGD,CAHe,UAGf,EAH+BA,CAG/B,CAH6C,SAG7C,GAFM8H,CAEN,CAFoB,UAEpB,EAFqCA,CAErC,CAFmD,SAEnD,GAFgEA,CAEhE,CAF8E,CAE9E,GAAA9H,CAAA,EAAe8H,CAAf,GAA+B9H,CAdvC,EAee,CAAA,CAff,CAkBO,CAAA,CAnBX,CAyDA+H,QAAA,GAAY,CAAZA,CAAY,CAAClG,CAAD,CAAW7B,CAAX,CAAwBgI,CAAxB,CACZ,CACoB,CAAA/G,EAAhB,GACwB,CAAA,CADxB,GACQjB,CADR,EACgC6H,EAAA,CAAAA,CAAA,CAAoB7H,CAApB,CAAkC,CAAlC,CADhC,GAEQ,CAAAiB,EAAAlG,QAAA,CAAiB8G,CAAjB,CAA2BmG,CAA3B,CAHZ,CAoDAC,IAAAA,GAAYA,UAiBZlP;MAAJ,GACSA,MAAA,KAGL,GAHqBA,MAAA,KAGrB,CAHsC,EAGtC,EAFKA,MAAA,KAAA,SAEL,GAFiCA,MAAA,KAAA,SAEjC,CAF8D,EAE9D,EADKA,MAAA,KAAA,WACL,GADmCA,MAAA,KAAA,WACnC,CADkE,EAClE,EAAKA,MAAA,KAAA,SAAL,GAAiCA,MAAA,KAAA,SAAjC,CAA8D,EAA9D,CAJJ,CAMA;IAAA0I,GAAqB1I,MAAA,CAAQA,MAAA,KAAA,SAAR,CAAqC,EAA1D,CACA+K,GAAuB/K,MAAA,CAAQA,MAAA,KAAA,WAAR,CAAuC,EAD9D,CAEAkM,GAAqBlM,MAAA,CAAQA,MAAA,KAAA,SAAR,CAAqC,EAF1D,CAIAmP,GAA0B,CACtB,MADsB,CACd,OADc,CACL,MADK,CAJ1B,CAOAxC,GAA2B,CACvB,MAxlBAyC,QAAkB,CAACtG,CAAD,CAClB,CACI/G,CAAA,CAAoB+G,CAApB,CACA,OAAO,CAAA,CAFX,CAslBuB,CAEvB,MAjjBAuG,QAAkB,CAACC,CAAD,CAAaC,CAAb,CAClB,CACIlL,UAAA,CAAWiL,CAAX,CAAuB,CAACC,CAAxB,CACA,OAAO,CAAA,CAFX,CA8iBuB,CAP3B,CAWA1C,GAA8B,CAC1B,OA9kBA2C,QAAmB,CAACjH,CAAD,CAAY6E,CAAZ,CAAsBlK,CAAtB,CACnB,CACI,IAAI8I,EAAW,CAAA,CAGf,IADI3C,CACJ,CAFgBd,CAAAkH,SACF,CAAUrC,CAAV,CACd,CACI,IAAShU,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoBiQ,CAAAqG,QAAAzS,OAApB,CAA4C7D,CAAA,EAA5C,CACI,GAAIiQ,CAAAqG,QAAA,CAAgBtW,CAAhB,CAAAuW,YAAJ,EAAsCzM,CAAtC,CAA8C,CACtCmG,CAAAuG,cAAJ,EAA6BxW,CAA7B,GACIiQ,CAAAuG,cADJ,CAC4BxW,CAD5B,CAGA4S,EAAA,CAAW,CAAA,CACX,MAL0C,CAStD,MAAOA,EAfX,CA4kB0B,CAmBzBnK;KAAArE,UAAA7C,QAAL,GACIkH,KAAArE,UAAA7C,QADJ,CAC8BkV,QAAQ,CAACC,CAAD,CAAMC,CAAN,CAAa,CAClC3W,CAAAA,CAAK2W,CAAL3W,EAAc,CAAvB,KAAK,IAAsBC,EAAI,IAAA4D,OAA/B,CAA4C7D,CAA5C,CAAgDC,CAAhD,CAAmDD,CAAA,EAAnD,CACI,GAAI,IAAA,CAAKA,CAAL,CAAJ,GAAgB0W,CAAhB,CAAuB,MAAO1W,EAElC,OAAQ,EAJmC,CADnD,CAYKyI,MAAAmO,QAAL,GACInO,KAAAmO,QADJ,CACoBC,QAAQ,CAACC,CAAD,CAAM,CAC1B,MAA+C,gBAA/C,GAAOC,MAAA3S,UAAA0P,SAAAH,KAAA,CAA+BmD,CAA/B,CADmB,CADlC,CASKE;QAAA5S,UAAA6S,KAAL,GACID,QAAA5S,UAAA6S,KADJ,CAC8BC,QAAQ,CAACR,CAAD,CAAM,CAQtBS,QAAA,EAAQ,EAAG,CACrB,MAAOC,EAAAC,MAAA,CAAc,IAAA,WAAgBC,EAAhB,EAAyBZ,CAAzB,CAA8B,IAA9B,CAAqCA,CAAnD,CAAwDa,CAAAC,OAAA,CAAiC/O,KAAArE,UAAAvC,MAAA8R,KAAA,CAA2B8D,SAA3B,CAAjC,CAAxD,CADc,CADQH,QAAA,EAAQ,EAAG,EAN5C,GAAmB,UAAnB,EAAI,MAAO,KAAX,CAEI,KAAM,KAAII,SAAJ,CAAc,8CAAd,CAAN,CAEJ,IAAIH,EAAO9O,KAAArE,UAAAvC,MAAA8R,KAAA,CAA2B8D,SAA3B,CAAsC,CAAtC,CAAX,CACIL,EAAU,IAKdE,EAAAlT,UAAA,CAAkB,IAAAA,UAClB+S,EAAA/S,UAAA,CAAoB,IAAIkT,CACxB,OAAOH,EAb6B,CAD5C,CA8DIQ;IAAAA,EAnCWA,OAmCXA,CACAC,GA5BUA,OA2BVD,CAmCAE,GAAgB5V,IAAAC,IAAA2V,CAASA,CAATA,CAAYA,EAAZA,CAAhBA,CAAkCA,CAnClCF,CAoCAG,GAAgB7V,IAAAC,IAAA4V,CAASA,CAATA,CAAYA,EAAZA,CApChBH,CA2CAI,GAAgB9V,IAAAC,IAAA6V,CAASA,CAATA,CAAYA,EAAZA,CAAhBA,CAAkCA,CA3ClCJ,CA4CAK,GAAgB/V,IAAAC,IAAA8V,CAASA,CAATA,CAAYA,EAAZA,CA5ChBL,CA6CAM,EAAgBhW,IAAAC,IAAA+V,CAASA,CAATA,CAAYA,EAAZA,CAAhBA,CAAkCA,CA7ClCN,CA8CAO,EAAgBjW,IAAAC,IAAAgW,CAASA,CAATA,CAAYA,EAAZA,CA9ChBP,CA+CAQ,EAAgBlW,IAAAC,IAAAiW,CAASA,CAATA,CAAYA,EAAZA,CAAhBA,CAAkCA,CA/ClCR,CAgDAS,EAAgBnW,IAAAC,IAAAkW,CAASA,CAATA,CAAYA,EAAZA,CAhDhBT,CAiDAU,EAAgBpW,IAAAC,IAAAmW,CAASA,CAATA,CAAYA,EAAZA,CAAhBA,CAAkCA,CAjDlCV,CAkDAW,EAAgBrW,IAAAC,IAAAoW,CAASA,CAATA,CAAYA,EAAZA,CAlDhBX,CAoDAY,EAAgBtW,IAAAC,IAAAqW,CAASA,CAATA,CAAYA,EAAZA,CApDhBZ,CAqDAa,GAAgBvW,IAAAC,IAAAsW,CAASA,CAATA,CAAYA,EAAZA,CArDhBb,CAsDAc,GAAgBxW,IAAAC,IAAAuW,CAASA,CAATA,CAAYA,EAAZA,CAtDhBd,CAgGIe,GAAYzW,IAAAC,IAAAyW,CAASA,CAATA,CAAYA,EAAZA,CAhGhBhB,CAiGIiB,GAAY3W,IAAAC,IAAAyW,CAASA,CAATA,CAAYA,EAAZA,CAjGhBhB,CAmGIkB,GAAY5W,IAAAC,IAAAyW,CAASA,CAATA,CAAYA,EAAZA,CAnGhBhB,CAoGImB,GAAY7W,IAAAC,IAAAyW,CAASA,CAATA,CAAYA,EAAZA,CAgHpBnI,EAAA,CAvPemH,OAwPfoB,GAAA,CAhPcnB,OAiSd;IAAAoB,GAA2B,CACvB,IAxCYC,CAuCW,CAEvB,KAxCYC,CAsCW,CAGvB,MAxCYC,CAqCW,CAIvB,MAxCYC,CAoCW,CAKvB,IAxCYC,EAmCW,CAMvB,OAxCYC,EAkCW,CAOvB,IAxCYC,EAiCW,CAQvB,IAxCYC,GAgCW,CASvB,OAxCYC,GA+BW,CAUvB,MAxCYC,GA8BW,CAWvB,SAxCYC,IA6BW,CAYvB,IAxCYC,IA4BW,CAavB,MAxCYC,IA2BW,CAcvB,KAxCYC,KA0BW,CAevB,MAxCYC,KAyBW,CAgBvB,OAxCYC,OAwBW,CAiBvB,MAxCYC,OAuBW,CAkBvB,QAxCYC,QAsBW,CAmBvB,SAxCYC,QAqBW,CAoBvB,IAxCYC,SAoBW,CAqBvB,KAxCYC,SAmBW,CA6BvB,OA/CYC,UAkBW,CA8BvB,KA/CYC,WAiBW,CA0EvB7M;QATE8M,GASS,CAACC,CAAD,CAAaC,CAAb,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,OAAN,CAAeD,CAAf,CA1GQf,GA0GR,CAOA,KAAAiB,EAAA,CADA,IAAAC,EACA,CADiB,CAIjB,KAAAF,EAAA,CAAiBA,CAiBjB,KAAAG,EAAA,CAAe,IAAAC,EAAf,CADA,IAAAC,EACA,CAFA,IAAAC,EAEA,CAFkB,CAGlB,KAAAC,EAAA,CAAe,IAAAC,EAAf,CAA+B,EAa/B,KAAAC,EAAA,CADA,IAAAC,EACA,CAFA,IAAAC,EAEA,CAFgB,CAAA,CAGhB,KAAAC,EAAA,CAAgBC,EAShB,KAAAC,EAAA,CAAY,EAsBZ,KAAAC,EAAA,CAAgB,CACZ,MAAY,CAAC,CAAD,CAAI,CAAJ,CAAO,CAAA,CAAP,CAAc,CAAA,CAAd,CAAqB,IAAAC,GAArB,CADA,CAEZ,KAAY,CAAC,CAAD,CAAI,CAAJ,CAAO,CAAA,CAAP,CAAc,CAAA,CAAd,CAAqB,IAAAC,GAArB,CAFA,CAGZ,OAAY,CAAC,CAAD,CAAI,CAAJ,CAAO,CAAA,CAAP,CAAc,CAAA,CAAd,CAAqB,IAAAC,GAArB,CAHA,CAIZ,KAAY,CAAC,CAAD,CAAI,CAAJ,CAAO,CAAA,CAAP,CAAc,CAAA,CAAd,CAAqB,IAAAC,GAArB,CAJA,CAKZ,IAAY,CAAC,CAAD,CAAI,CAAJ,CAAO,CAAA,CAAP,CAAc,CAAA,CAAd,CAAqB,IAAAC,GAArB,CALA,CAMZ,KAAY,CAAC,CAAD,CAAI,CAAJ,CAAO,CAAA,CAAP,CAAc,CAAA,CAAd,CAAqB,IAAAC,GAArB,CANA,CAOZ,KAAY,CAAC,CAAD,CAAI,CAAJ,CAAO,CAAA,CAAP,CAAc,CAAA,CAAd,CAAqB,IAAAC,GAArB,CAPA,CAQZ,KAAY,CAAC,CAAD,CAAI,CAAJ,CAAO,CAAA,CAAP,CAAc,CAAA,CAAd,CAAqB,IAAAC,GAArB,CARA,CAUhB,KAASjc,CAAT,CAAa,CAAb,CAAoB,EAApB,CAAgBA,CAAhB,CAAwBA,CAAA,EAAxB,CACI,IAAAyb,EAAA,CAAc,GAAd,CAAkBzb,CAAlB,CAAA,CAAuB,CAAC,CAAD,CAAI,CAAJ,CAAO,CAAA,CAAP,CAAc,CAAA,CAAd,CAAqB,IAAAkc,GAArB,CAA2Clc,CAA3C,CAa3B,KAAA8O,EAAA,CAHA,IAAAC,EAGA,CANA,IAAAC,EAMA,CATA,IAAAC,EASA,CATW,IAyBX,KAAA,QAAA,CAAkB,CACd,KAAQ,IAAAkN,GADM,CAEd,OAAU,IAAAC,GAFI,CAGd,MAAS,IAAAC,GAHK;AAId,IAAO,IAAAC,GAJO,CAOlBrH,GAAA,CAAAA,IAAA,CAzHJ,CAVqBsH,EAAA5O,CAAnB6M,EAAmB7M,CAAAA,CAAAA,CA+NrB,EAAA,CApsJJ,EAAA6O,UAosJI3I,EAAA4I,MAAA,CAAAA,QAAK,CAACC,CAAD,CACL,CAII,IAAAC,KAAA,EACID,EAAJ,EArDOE,EAAA,CAqDOC,IArDP,CAqDOA,IArDS7B,EAAhB,CAqDkB5Y,CArDlB,CAgDX,CAuBAyR;CAAAvC,GAAA,CAAAA,QAAU,CAACyC,CAAD,CAAYC,CAAZ,CAAsB/D,CAAtB,CAA+BnG,CAA/B,CACV,CAGI,GAFI,IAAAmF,EAEJ,EAFgB,IAAAA,EAAAqC,GAAA,CAAoByC,CAApB,CAA+BC,CAA/B,CAAyC/D,CAAzC,CAAkDnG,CAAlD,CAEhB,EADI,IAAAiF,EACJ,EADgB,IAAAA,EAAAuC,GAAA,CAAoByC,CAApB,CAA+BC,CAA/B,CAAyC/D,CAAzC,CAAkDnG,CAAlD,CAChB,EAAgB,IAAAgF,EAAhB,EAA4B,IAAAA,EAAAwC,GAAA,CAAoByC,CAApB,CAA+BC,CAA/B,CAAyC/D,CAAzC,CAAkDnG,CAAlD,CAA5B,CAAuF,MAAO,CAAA,CAE9F,QAAQkK,CAAR,EACA,KAAK,IAAL,CAGI,MAFA,KAAA/F,EAAA,CAAc+F,CAAd,CAEO,CAFmB/D,CAEnB,CADP,IAAA2K,EAAA,EACO,CAAA,CAAA,CAEX,SAQI,MAAiB,KAAjB,EAAI7G,CAAJ,EAAuC,MAAvC,EAA0BA,CAA1B,EACI,IAAA9F,EAAA,CAAc+F,CAAd,CAGO,CAHmB/D,CAGnB,CAFP,IAAAuL,EAAA,CAAUxH,CAAV,CAEO,CAFelK,CAAA,CAAQ,CAAR,CAAY,CAE3B,CADP,IAAA8Q,EAAA,EACO,CAAA,CAAA,CAJX,EAgBiB,QAAjB,EAAI7G,CAAJ,EAKoCrP,IAAAA,EA2BzB,GA3BH,IAAA+W,EAAA,CAAczH,CAAd,CA2BG,GA1BH,IAAAyH,EAAA,CAAczH,CAAd,CA0BG,CA1BuB,CAAClK,CAAA,CAAQ,CAAR,CAAY,CAAb,CAAgBA,CAAA,CAAQ,CAAR,CAAY,CAA5B,CA0BvB,EAxBP,IAAAmE,EAAA,CAAc+F,CAAd,CAwBO,CAxBmB/D,CAwBnB,CAvBH6M,CAuBG,CAvBM7M,CAAA8M,cAuBN,EAvB+B9M,CAuB/B,CAtBP6M,CAsBO,CAtBEA,CAAAC,cAsBF,EAtB0BD,CAsB1B,CArBPA,CAAArR,YAqBO,CArBc,QAAQ,CAACuR,CAAD,CAAQhJ,CAAR,CAAkB,CAC3C,MAAOiJ,SAAsB,EAAG,CAC5BC,EAAA,CAAAF,CAAA,CAAkBhJ,CAAlB,CAD4B,CADW,CAA1B,CAInB,IAJmB,CAIbA,CAJa,CAqBd,CAhBP8I,CAAAhR,UAgBO,CAhBYgR,CAAA/Q,WAgBZ,CAhBgC,QAAQ,CAACiR,CAAD,CAAQhJ,CAAR,CAAkB,CAC7D,MAAOmJ,SAAwB,EAAG,CAC9BC,EAAA,CAAAJ,CAAA,CAAoBhJ,CAApB,CAD8B,CAD2B,CAA1B,CAIrC,IAJqC,CAI/BA,CAJ+B,CAgBhC,CAXP8I,CAAAlR,aAWO;AAXe,QAAQ,CAACoR,CAAD,CAAQhJ,CAAR,CAAkB,CAC5C,MAAOiJ,SAAsB,CAACI,CAAD,CAAQ,CACjCH,EAAA,CAAAF,CAAA,CAAkBhJ,CAAlB,CACAqJ,EAAAC,eAAA,EAFiC,CADO,CAA1B,CAKpB,IALoB,CAKdtJ,CALc,CAWf,CALP8I,CAAA5Q,WAKO,CALa,QAAQ,CAAC8Q,CAAD,CAAQhJ,CAAR,CAAkB,CAC1C,MAAOmJ,SAAwB,EAAG,CAC9BC,EAAA,CAAAJ,CAAA,CAAoBhJ,CAApB,CAD8B,CADQ,CAA1B,CAIlB,IAJkB,CAIZA,CAJY,CAKb,CAAA,CAAA,CAhCX,EAkCO1C,CAAAA,UAAAA,GAAAA,KAAAA,CAAAA,IAAAA,CAAiByC,CAAjBzC,CAA4B0C,CAA5B1C,CAAsCrB,CAAtCqB,CAA+CxH,CAA/CwH,CAhEX,CALJ,CAkFAuC,EAAA0J,GAAA,CAAAA,QAAO,CAACtO,CAAD,CAAMD,CAAN,CAAWD,CAAX,CAAgBD,CAAhB,CACP,CACI,IAAAG,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CAEX0O,GAAA,CAAAA,IAAA,CACAC,GAAA,CAAAA,IAAA,CAPJ,CAkBA5J,EAAAyB,GAAA,CAAAA,QAAO,CAACjN,CAAD,CAAOqV,CAAP,CACP,CACI,GAAI,CAACA,CAAL,CAQI,GAFI,IAAAhD,EAEA,EAFgBiD,EAAA,EAEhB,CAAA,CAACtV,CAAL,CACI,IAAAoU,MAAA,CAAW,CAAA,CAAX,CADJ,KAGI,IAAI,CAAC,IAAAmB,QAAA,CAAavV,CAAb,CAAL,CAAyB,MAAO,CAAA,CAGxC,OAAO,CAAA,CAfX,CA0BAwL,EAAA0B,GAAA,CAAAA,QAAS,CAACC,CAAD,CACT,CACI,MAAOA,EAAA,CAAO,IAAAqI,KAAA,EAAP,CAAqB,CAAA,CADhC,CAYAhK,EAAAgK,KAAA,CAAAA,QAAI,EACJ,CACI,IAAIC,EAAQ,IAAIC,CAAJ,CAAU,IAAV,CACZD,EAAAE,IAAA,CAAU,CAAV,CAAa,CACTC,IA3PGpD,EA0PM,CAETqD,IAtOGlD,EAoOM,CAGTmD,IAhNGpD,EA6MM,CAAb,CAKA,OAAO+C,EAAAzV,KAAA,EAPX,CAmBAwL;CAAA+J,QAAA,CAAAA,QAAO,CAACvV,CAAD,CACP,CAEI,GADI7I,CACJ,CADQ6I,CAAA,CAAK,CAAL,CACR,CAnQA+V,EAAA,CAoQIC,IApQJ,CAoQIA,IApQYxD,EAAhB,CAoQerb,CAAA4C,CAAE,CAAFA,CApQf,CA6CA,CAtBOwa,EAAA,CA8OHC,IA9OG,CA8OHA,IA9OmB7B,EAAhB,CA8OQxb,CAAA4C,CAAE,CAAFA,CA9OR,CAsBP,CAAAkc,EAAA,CAyNIC,IAzNJ,CAyNe/e,CAAA4C,CAAE,CAAFA,CAzNf,CA2NA,OAAO,CAAA,CAPX,CAgBAyR,EAAAwI,GAAA,CAAAA,QAAa,EACb,CACI,IAAKrI,IAAIA,CAAT,GAAqB,KAAAyH,EAArB,CAAoC,CAChC,IAAI+C,EAAK,IAAA/C,EAAA,CAAczH,CAAd,CACTwK,EAAA,CAAG,CAAH,CAAA,CAAQA,CAAA,CAAG,CAAH,CAFwB,CAIpCf,EAAA,CAAAA,IAAA,CACA,OAAO,CAAA,CANX,CAgBAgB,SAAA,GAAU,CAAVA,CAAU,CAACzK,CAAD,CAAW5R,CAAX,CACV,CAEI,GADI6N,CACJ,CADc,CAAAhC,EAAA,CAAc+F,CAAd,CACd,CAII/D,CAAAyO,MAAAC,gBAAA,CAAiCvc,CAAA,CAAO,SAAP,CAAmB,SAN5D,CAgBAob,QAAA,GAAW,CAAXA,CAAW,CAACoB,CAAD,CACX,CACI,IAAK5K,IAAIA,CAAT,GAAqB,EAAAwH,EAArB,CACIiD,EAAA,CAAAA,CAAA,CAAgBzK,CAAhB,CAAsC,IAAZ,EAAA4K,CAAA,CAAkBA,CAAlB,CAA6B,CAAApD,EAAA,CAAUxH,CAAV,CAAvD,CAFR,CAaA6K,QAAA,GAAa,CAAbA,CAAa,CAAC7K,CAAD,CAAW5R,CAAX,CACb,CAEI,GADI6N,CACJ,CADc,CAAAhC,EAAA,CAAc+F,CAAd,CACd,CACI/D,CAAAyO,MAAAI,UACA,CAD2B1c,CAAA,CAAO,KAAP,CAAe,MAC1C,CAAA6N,CAAAyO,MAAAC,gBAAA,CAAiCvc,CAAA,CAAO,SAAP,CAAmB,SAJ5D,CAaAqb,QAAA,GAAe,CAAfA,CAAe,CACf,CACI,IAAKzJ,IAAIA,CAAT,GAAqB,EAAAyH,EAArB,CACIoD,EAAA,CAAAA,CAAA,CAAmB7K,CAAnB,CAA6B,CAAAyH,EAAA,CAAczH,CAAd,CAAA,CAAwB,CAAxB,CAA7B,CAFR;AA+CAH,CAAAsI,GAAA,CAAAA,QAAU,CAACjG,CAAD,CAAalC,CAAb,CAAuBmC,CAAvB,CACV,CACI,GAAI+G,EAAA,CAAAA,IAAA,CAAiBlJ,CAAjB,CAAJ,CAAgC,CAC5B,GAAImC,CAAJ,CAAY,CACR,IAAI6G,EAAQ,IACZ/R,WAAA,CAAW,QAAQ,EAAG,CAClBmS,EAAA,CAAAJ,CAAA,CAAoBhJ,CAApB,CACIkC,EAAJ,EAAgBA,CAAA,EAFE,CAAtB,CAGG,CAACC,CAHJ,CAIA,OAAO,CAAA,CANC,CAQRiH,EAAA,CAAAA,IAAA,CAAmBpJ,CAAnB,CATwB,CAYhC,MAAO,CAAA,CAbX,CAwBAH,EAAAyI,GAAA,CAAAA,QAAS,CAACtI,CAAD,CAAWlK,CAAX,CACT,CACI,GAAgB,IAAhB,EAAIkK,CAAJ,CACI,MAAOsK,GAAA,CAAAA,IAAA,CAAmBS,EAAA,CAAajV,CAAb,CAAqB,CAArB,CAAnB,CAEX,KAAI0U,EAAK,IAAA/C,EAAA,CAAczH,CAAd,CACT,OAAIwK,EAAJ,EACIA,CAAA,CAAG,CAAH,CAEO,CAFC,CAAC1U,CAAD,CAAS,CAAT,CAAa,CAEd,CADP+U,EAAA,CAAAA,IAAA,CAAmB7K,CAAnB,CAA6BwK,CAAA,CAAG,CAAH,CAA7B,CACO,CAAA,CAAA,CAHX,EAKO,CAAA,CAVX,CAoBA3K,EAAAuI,GAAA,CAAAA,QAAY,CAACpI,CAAD,CACZ,CACI,MAAIkJ,GAAA,CAAAA,IAAA,CAAiBlJ,CAAjB,CAAJ,EACIoJ,EAAA,CAAAA,IAAA,CAAmBpJ,CAAnB,CACO,CAAA,CAAA,CAFX,EAIO,CAAA,CALX,CAeAkJ,SAAA,GAAW,CAAXA,CAAW,CAAClJ,CAAD,CACX,CACI,IAAIwK,EAAK,CAAA/C,EAAA,CAAczH,CAAd,CACT,OAAIwK,EAAJ,EAIIK,EAAA,CAAAA,CAAA,CAAmB7K,CAAnB,CAA8BwK,CAAA,CAAG,CAAH,CAA9B,CAAsC,CAAtC,CAA0CA,CAAA,CAAG,CAAH,CAA1C,CAoBO,CAfPA,CAAA,CAAG,CAAH,CAeO,CAfC,CAAA,CAeD,CAVHA,CAAA,CAAG,CAAH,CAUG,EAVIA,CAAA,CAAG,CAAH,CAAA7K,KAAA,CAAW,CAAX,CAAiB6K,CAAA,CAAG,CAAH,CAAjB,CAAwBA,CAAA,CAAG,CAAH,CAAxB,CAUJ,CAJHxK,CAIG,EAJSgL,EAIT,GAHH,CAAA7D,EACA,CADiBnH,CACjB,EAD6BiL,EAC7B,CAAA,CAAA7D,EAAA,CAAiBpH,CAAjB,EAA6BkL,EAE1B,EAAA,CAAA,CAxBX,EA0BO,CAAA,CA5BX;AAsCA9B,QAAA,GAAa,CAAbA,CAAa,CAACpJ,CAAD,CACb,CAUI,IAAIwK,EAAK,CAAA/C,EAAA,CAAczH,CAAd,CACLwK,EAAJ,GACQA,CAAA,CAAG,CAAH,CAcJ,EAdaA,CAAA,CAAG,CAAH,CAcb,GAVIK,EAAA,CAAAA,CAAA,CAAmB7K,CAAnB,CAA8BwK,CAAA,CAAG,CAAH,CAA9B,CAAsCA,CAAA,CAAG,CAAH,CAAtC,CAKA,CAAIA,CAAA,CAAG,CAAH,CAAJ,EAAWA,CAAA,CAAG,CAAH,CAAA7K,KAAA,CAAW,CAAX,CAAiB6K,CAAA,CAAG,CAAH,CAAjB,CAAwBA,CAAA,CAAG,CAAH,CAAxB,CAKf,EAAAA,CAAA,CAAG,CAAH,CAAA,CAAQ,CAAA,CAfZ,CAXJ,CAuCA3K,CAAA6H,GAAA,CAAAA,QAAY,CAACtZ,CAAD,CACZ,CACSA,CAAL,EAAe,IAAA2M,EA8mERX,MAAA+Q,EA9mEP,GAEIC,CAAA,CAAA,IAAArQ,EAAA,CAAe,IAAA8L,EAAf,CAOA,CAAIwE,IA9dD5D,EAAA,CA8dgB6D,EA9dhB,CA8dH,EAAID,IA9dsB5D,EAAA,CA8dP6D,EA9dO,CAAA,CAAoB,CAApB,CA8d1B,EACIC,EAAA,CAAA,IAAAxQ,EAAA,CAVR,CADJ,CAiCA8E,EAAA8H,GAAA,CAAAA,QAAW,EACX,EAgBA9H,EAAA+H,GAAA,CAAAA,QAAa,CAACxZ,CAAD,CACb,CAMSA,CAAL,EACIod,CAAA,CAAA,IAAAzQ,EAAA,CAPR,CAkBA8E;CAAAgI,GAAA,CAAAA,QAAe,CAACzZ,CAAD,CACf,CACI,GAAI,CAACA,CAAL,EAAc,CAAC,IAAA2M,EAwiERX,MAAA+Q,EAxiEP,CAKI,GAAKE,IAhiBF5D,EAAA,CAgiBiB6D,EAhiBjB,CAgiBH,EAAKD,IAhiBqB5D,EAAA,CAgiBN6D,EAhiBM,CAAA,CAAoB,CAApB,CAgiB1B,CAoDIC,EAAA,CAAA,IAAAxQ,EAAA,CApDJ,KAA+C,CAO3C,IADID,CACJ,CADU,IAAAA,EACV,GAAW,CAACoG,EAAA,CAAApG,CAAA,CAAW,CAAA,CAAX,CAAZ,CACIsG,EAAA,CAAAtG,CAAA,CAAY,CAAA,CAAZ,CAEA,CADA2Q,EAAA,CAAA3Q,CAAA,CAAY,CAAZ,CAAe,IAAf,CACA,CAAAsG,EAAA,CAAAtG,CAAA,CAAY,CAAA,CAAZ,CAHJ,KASI,IAAI,CACA,IAAI4Q,EAAc,IAAA3Q,EAAA0Q,GAAA,CAAiB,CAAjB,CACA,EAAlB,CAAIC,CAAJ,GACIC,EAAA,CAAA,IAAA5Q,EAAA,CAAsB2Q,CAAtB,CAEA,CADAE,EAAA,CAAA,IAAA7Q,EAAA,CAAmB2Q,CAAnB,CAAgC,CAAA,CAAhC,CACA,CAAAG,EAAA,CAAA,IAAA9Q,EAAA,CAAwB2Q,CAAxB,CAHJ,CAFA,CAQJ,MAAMI,CAAN,CAAiB,CAKW,QAAxB,EAAI,MAAOA,EAAX,GACQlgB,CACJ,CADQkgB,CACR,CAAAhL,EAAA,CAAA,IAAA/F,EAAA,CAAkBnP,CAAAmgB,MAAlB,EAA6BngB,CAAAgJ,QAA7B,CAFJ,CALa,CAerB,IAAA+T,KAAA,EAUI,KAAA1N,EAAJ,EAAc+Q,CAAA,CAAA,IAAA/Q,EAAA,CAjD6B,CANvD,CAsEA4E,EAAAiI,GAAA,CAAAA,QAAc,CAAC1Z,CAAD,CACd,CACQA,CAAJ,EAAa,CAAC,IAAA2M,EAi+DPX,MAAA+Q,EAj+DP,GACQ,IAAAhE,EAOJ,EAPmB8E,EAAA,CAAAA,IAAA,CAOnB,CAFInf,CAEJ,CA5oBG8b,EAAA,CA0oBKC,IA1oBL,CA0oBKA,IA1oBW7B,EAAhB,CA0oBgB,IAAAD,EA1oBhB,CA4oBH,CAAI,IAAAO,EAAJ,EAAqBC,EAArB,CAII2E,EAAA,CAAA,IAAAlR,EAAA,CAAuB,IAAA6L,EAAvB,CAAqC/Z,CAArC,CAJJ,CASI,IAAAiO,EAAAoR,EAAA,CAAmB,IAAAtF,EAAnB,CAAiC/Z,CAAjC,CAjBR,CADJ,CA8BA+S;CAAAkI,GAAA,CAAAA,QAAc,CAAC3Z,CAAD,CACd,CACI,GAAI,CAACA,CAAL,EAAc,CAAC,IAAA2M,EAk8DRX,MAAA+Q,EAl8DP,CAAqC,CACjC,IAAIre,CACA,KAAAsa,EAAJ,EAAmB6E,EAAA,CAAAA,IAAA,CACf,KAAA3E,EAAJ,EAAqBC,EAArB,CAIIza,CAJJ,CAIQsf,EAAA,CAAA,IAAApR,EAAA,CAAuB,IAAA6L,EAAvB,CAJR,CASI/Z,CATJ,CASQ,IAAAiO,EAAAsR,EAAA,CAAkB,IAAAxF,EAAlB,CA/qBL+B,GAAA,CAqrBHC,IArrBG,CAqrBHA,IArrBmB7B,EAAhB,CAqrBQla,CArrBR,CAmqB8B,CADzC,CA8BA+S,EAAAmI,GAAA,CAAAA,QAAe,CAAC5Z,CAAD,CACf,CACSA,CAAL,EAAe,IAAA2M,EAm6DRX,MAAA+Q,EAn6DP,EACIf,EAAA,CAAAA,IAAA,CAAgB,IAAArD,EAAhB,CAFR,CAaAlH,EAAAoI,GAAA,CAAAA,QAAc,CAAC7Z,CAAD,CACd,CACQA,CAAJ,EACI,IAAAiZ,EACA,CADgB,CAAA,CAChB,CAAAmC,EAAA,CAAAA,IAAA,CAAiB,CAAA,CAAjB,CAFJ,GAII,IAAAnC,EAKA,CALgB,CAAA,CAKhB,CAJAmC,EAAA,CAAAA,IAAA,CAIA,CAAAc,EAAA,CAAAA,IAAA,CAAmB,CAAnB,CATJ,CADJ,CAqBAzK,EAAAqI,GAAA,CAAAA,QAAe,CAAC9Z,CAAD,CAAQke,CAAR,CACf,CAEQ,IAAAvF,EAAA,CADA3Y,CAAJ,CACI,IAAA2Y,EADJ,CACwB,CADxB,EAC6BuF,CAD7B,CAGI,IAAAvF,EAHJ,CAGwB,EAAE,CAAF,EAAOuF,CAAP,CAJ5B,CAuBAL,SAAA,GAAW,CAAXA,CAAW,CACX,CACI,IAAIM,EAAM,CAAV,CACIC,EAAO,CAAAxR,EAAAyR,EACNpB,EA9tBE5D,EAAA,CA8tBauD,EA9tBb,CA8tBP,EAAKK,CA9tByB5D,EAAA,CA8tBVuD,EA9tBU,CAAA,CAAoB,CAApB,CA8tB9B,GAA6CuB,CAA7C,CAAmD,CAACA,CAApD,CACOnC,GAAA,CAAAA,CAAA,CAAiB,CAAAvD,EAAjB,CAAgC,CAAC2F,CAAjC,CAA2C,CAAA3F,EAA3C,CAA0D0F,CAA1D,CAAiEC,CAAjE,CAJX;AAcApC,QAAA,GAAU,CAAVA,CAAU,CAAChc,CAAD,CACV,CACI,CAAAyY,EAAA,CAAezY,CAAf,CAAuB,CAAA4M,EAAAyR,EACvB,IAAI,CAAAxF,EAAJ,GAAqB,CAAAJ,EAArB,CAAmC,CAC/B,CAAAI,EAAA,CAAe,CAAAJ,EACUI,EAAAA,CAAAA,CAAAA,EA+C7B,KAAK,IAAIjb,EAAI,CAAb,CA/C2C0gB,EA+C3C,CAAgB1gB,CAAhB,CAA2BA,CAAA,EAA3B,CAAgC,CA/C5B2gB,IAAAA,EAAAA,CAAAA,CAgDe3M,EAhDKxR,GAgDLwR,CAAUhU,CAhDzB2gB,CAiDyB,EAAAve,CAAA,CAAS,CAAT,EAAcpC,CAjB3C,EAAAwb,EAAA,CAAUxH,CAAV,CAAA,CAAsB5R,CACjB,EAAAiZ,EAAL,EAAoBoD,EAAA,CAAAA,CAAA,CAAgBzK,CAAhB,CAA0B5R,CAA1B,CAcY,CAjDG,CAFvC,CAgBAwa,QAAA,GAAU,CAAVA,CAAU,CAACxa,CAAD,CACV,CACI,CAAA0Y,EAAA,CAAe1Y,CAAf,CAAuBwe,CACvB,IAAI,CAAA1F,EAAJ,GAAqB,CAAAJ,EAArB,CAAmC,CAC/B,CAAAI,EAAA,CAAe,CAAAJ,EACUI,EAAAA,CAAAA,CAAAA,EA8B7B,KAAK,IAAIlb,EAAI,CAAb,CA9B2C0gB,EA8B3C,CAAgB1gB,CAAhB,CAA2BA,CAAA,EAA3B,CAAgC,CA9B5B2gB,IAAAA,EAAAA,CAAAA,CA+Be3M,EA/BKxR,GA+BLwR,CAAUhU,CA/BzB2gB,CAgCyB,EAAAve,CAAA,CAAS,CAAT,EAAcpC,CAjB3C,EAAAwb,EAAA,CAAUxH,CAAV,CAAA,CAAsB5R,CACjB,EAAAiZ,EAAL,EAAoBoD,EAAA,CAAAA,CAAA,CAAgBzK,CAAhB,CAA0B5R,CAA1B,CAcY,CAhCG,CAInC,MAAO,EAAA0Y,EANX,CA+CAwD,QAAA,GAAa,CAAbA,CAAa,CAAClc,CAAD,CACb,CACI,CAAA2Y,EAAA,CAAmB3Y,CAAnB,CAA2B,CAC3B,KAASpC,CAAT,CAAa,CAAb,CAAoB,EAApB,CAAgBA,CAAhB,CAAwBA,CAAA,EAAxB,CACI,CAAAyb,EAAA,CAAc,GAAd,CAAkBzb,CAAlB,CAAA,CAAqB,CAArB,CAAA,CAA2B,CAAA+a,EAAD,CAAqB,CAArB,EAA0B/a,CAA1B,CAA+B,CAA/B,CAAmC,CAKjEyd,GAAA,CAAAA,CAAA,CACA,OAAO,CAAA,CATX,CAqBA5J,CAAA8I,KAAA,CAAAA,QAAI,EACJ,CACIyB,EAAA,CAAAA,IAAA,CAAgB,IAAArP,EAonGT8R,EApnGP,CADJ,CAqGAC;QAAO,GAAI,EACX,CAEI,IADA,IAAIC,EAAWrQ,CAAA,CAA6BsQ,QAA7B,CAAuCxQ,CAAvC,CAAuD,OAAvD,CAAf,CACSyQ,EAAO,CAAhB,CAAmBA,CAAnB,CAA4BF,CAAAld,OAA5B,CAA6Cod,CAAA,EAA7C,CAAuD,CACnD,IAAIC,EAASH,CAAA,CAASE,CAAT,CAAb,CACIxG,EAAapJ,EAAA,CAA4B6P,CAA5B,CADjB,CAEIlE,EAAQmE,EAAA,CAA2B1G,CAAA,GAA3B,CACPuC,EAAL,GAAYA,CAAZ,CAAoB,IAAIxC,EAAJ,CAAeC,CAAf,CAA2B,CAAA,CAA3B,CAApB,CACA2G,GAAA,CAAgCpE,CAAhC,CAAuCkE,CAAvC,CALmD,CAF3D,CAaAG,IAAAA,GAAYA,CAAZA,CAaAC,GAAQA,KAbRD,CAcAE,GAAQA,QAdRF,CAeAG,GAAQA,MAfRH,CAgBAI,GAAQA,MAMZC,GAAA,CAAW/D,EAAX,CA4DIjQ,SApBEiU,GAoBS,CAACC,CAAD,CAAW7S,CAAX,CAAgBD,CAAhB,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,KAAN,CAAa8S,CAAb,CA9zCQvI,EA8zCR,CAEA,KAAAtK,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CAMX,KAAA+S,EAAA,CAAiB,CAACD,CAAA,SAAlB,EAA0C,EAS1C,KAAAE,EAAA,CAAiB,CAAjB,EAAsB,IAAAD,EACtB,KAAApB,EAAA,CAAiB,IAAAqB,EAAjB,CAAkC,CAElC,KAAAC,EAAA,CAAmB9f,IAAA+f,KAAA,CADDC,KACC,CAGnB,KAAAC,EAAA,CAAoB,IAAAJ,EAApB,CAJkBG,KAIlB,CAAwD,CAIxD,KAAAE,EAAA,CAAsB,CAMtB,KAAAC,EAAA,CAAkB,EAmBdC,EAAAA,CAAQ,IAAIC,EAAJ,CAdZC,IAcY,CACZC,GAAA,CAAAH,CAAA,CAfAE,IAesBzT,EAAtB,CAfAyT,KAiBAH,EAAA,CAAsB3Z,KAAJ,CAjBlB8Z,IAiB4BL,EAAV,CAClB,KAASO,CAAT,CAAkB,CAAlB,CAAqBA,CAArB,CAlBAF,IAkB8BL,EAA9B,CAAgDO,CAAA,EAAhD,CAlBAF,IAmBIH,EAAA,CAAgBK,CAAhB,CAAA,CAA0BJ,CAjB9BpN,GAAA,CAAAA,IAAA,CA1CJ,CArBmBsH,EAAA5O,CAAjBgU,EAAiBhU,CAAAA,CAAAA,CAyFnB,EAAA,CAlwLJ,EAAA+U,UAkwLI7O,EAAA4I,MAAA,CAAAA,QAAK,EACL,EAsBA5I;CAAAyB,GAAA,CAAAA,QAAO,CAACjN,CAAD,CAAOqV,CAAP,CACP,CACI,GAAI,CAACA,CAAL,CACI,GAAI,CAACrV,CAAL,CACI,IAAAoU,MAAA,EADJ,KAGI,IAAI,CAAC,IAAAmB,QAAA,CAAavV,CAAb,CAAL,CAAyB,MAAO,CAAA,CAGxC,OAAO,CAAA,CARX,CAmBAwL,EAAA0B,GAAA,CAAAA,QAAS,CAACC,CAAD,CACT,CACI,MAAOA,EAAA,CAAO,IAAAqI,KAAA,EAAP,CAAqB,CAAA,CADhC,CAUAhK,EAAAgK,KAAA,CAAAA,QAAI,EACJ,CACI,IAAIC,EAAQ,IAAIC,CAAJ,CAAU,IAAV,CACZD,EAAAE,IAAA,CAAU,CAAV,CAAa2E,EAAA,CAAAA,IAAA,CAAb,CACA,OAAO7E,EAAAzV,KAAA,EAHX,CAaAwL,EAAA+J,QAAA,CAAAA,QAAO,CAACvV,CAAD,CACP,CAwaA,CAAA,CAAA,CAva8B,CAAA,CAAAA,CAAA,CAAK,CAAL,CAwa1B,KAAIrI,CACJ,KAAKA,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgBR,CAAAqE,OAAhB,CAA2B,CAA3B,CAA8B7D,CAA9B,EAAmC,CAAnC,CAAsC,CAClC,IAAIyiB,EAASjjB,CAAA,CAAEQ,CAAF,CAAb,CACI4iB,EAAMpjB,CAAA,CAAEQ,CAAF,CAAI,CAAJ,CACV,IAAI4iB,CAAJ,EA/hBaC,IA+hBb,CAAWD,CAAA/e,OAAX,CAAA,CAm5pBJ,IAHA,IAAIif,EAAO,CAAX,CACIC,EAAWta,KAAJ,CAh7qBMoa,IAg7qBN,CADX,CAEIG,EAAQ,CACZ,CAAOA,CAAP,CAAeC,CAAApf,OAAf,CAA8B,CAA9B,CAAA,CAGI,IAFA,IAAInE,EAAIujB,CAAA,CAAMD,CAAA,EAAN,CAAR,CACI3iB,EAAI4iB,CAAA,CAAMD,CAAA,EAAN,CACR,CAAOtjB,CAAA,EAAP,CAAA,CACIqjB,CAAA,CAAKD,CAAA,EAAL,CAAA,CAAeziB,CAIvB,EAAA,CAAO0iB,CA35pBH,CAGIV,CAAAA,CA/aDa,IA+aSd,EAAA,CAAgBK,CAAhB,CACZ,IAAI,CAACJ,CAAL,EAAc,CAACA,CAAAzE,QAAA,CAAcgF,CAAd,CAAf,CAAmC,CA5xGvCja,CAAA,CAkyGwB,iCAlyGxB,CAkyG4D8Z,CAlyG5D,CAmyGQ,EAAA,CAAO,CAAA,CAAP,OAAA,CAP+B,CAPD,CAiBtC,CAAA,CAAO,CAAA,CAnBX,CAvaI,MAAO,EADX,CAiCAU;QAAA,GAAS,CAATA,CAAS,CAACC,CAAD,CAAOC,CAAP,CAAard,CAAb,CACT,CAKI,IAJA,IAAIsd,EAAWF,CAAf,CACIG,EAAWF,CADf,CAEIZ,EAASa,CAATb,GAAsB,CAAAV,EAE1B,CAAkB,CAAlB,CAAOwB,CAAP,EAAuBd,CAAvB,CAAgC,CAAAL,EAAAve,OAAhC,CAAA,CAAwD,CAEpD,IAAIwe,EAAQ,CAAAD,EAAA,CAAgBK,CAAhB,CAAZ,CACIe,EA9JUvB,KA8JVuB,CAAYf,CADhB,CAEIgB,EA/JUxB,KA+JVwB,EAA+BH,CAA/BG,CAA0CD,CAA1CC,CACAA,EAAJ,CAAgBF,CAAhB,GAA0BE,CAA1B,CAAsCF,CAAtC,CAEA,IAAIlB,CAAJ,EAAaA,CAAAgB,KAAb,CAAyB,CACrB,GAAIhB,CAAArc,KAAJ,EAAkBA,CAAlB,CAAwB,CAOpB,GAAIsd,CAAJ,CAAeC,CAAf,EAA2BlB,CAAAe,EAA3B,CAGI,MAFAf,EAAAqB,GAEO,EAFQrB,CAAAe,EAER,CAFqBE,CAErB,CADPjB,CAAAe,EACO,CADME,CACN,CAAA,CAAA,CAEX,IAAIA,CAAJ,EAAgBjB,CAAAe,EAAhB,CAA6Bf,CAAAqB,GAA7B,CAAyC,CACjCC,CAAAA,CAAYtB,CAAAgB,KAAZM,EAA0BL,CAA1BK,CAAqCH,CAArCG,CACAA,EAAJ,CAAgBJ,CAAhB,GAA0BI,CAA1B,CAAsCJ,CAAtC,CACAlB,EAAAqB,GAAA,CAAaJ,CAAb,CAAwBjB,CAAAe,EAAxB,CAAqCO,CACrCL,EAAA,CAAWE,CAAX,CAnLEvB,KAoLFsB,EAAA,EAAYI,CACZlB,EAAA,EACA,SAPqC,CAZrB,CAsBxB,MAAOmB,GAAA,CAAiBC,EAAjB,CAA6CP,CAA7C,CAAuDC,CAAvD,CAvBc,CA0BrBO,CAAAA,CAAW,IAAIxB,EAAJ,CAAgB,CAAhB,CAAsBgB,CAAtB,CAAgCG,CAAhC,CA5LDxB,KA4LC,CAA4Djc,CAA5D,CACfwc,GAAA,CAAAsB,CAAA,CAAyB,CAAAhV,EAAzB,CAAmCuT,CAAnC,CACA,EAAAD,EAAA,CAAgBK,CAAA,EAAhB,CAAA,CAA4BqB,CAE5BR,EAAA,CAAWE,CAAX,CAhMcvB,KAiMdsB,EAAA,EAAYE,CAtCwC,CAyCxD,MAAgB,EAAhB,EAAIF,CAAJ,EACI,CAAA5c,OAAA,CAAY,QAAZ,EAAwB0c,CAAxB,EAAgC,EAAhC,EAAsC,KAAtC,CAA8CU,EAAA,CAAuB/d,CAAvB,CAA9C,CAA6E,MAA7E,CAAsFge,EAAA,CAAUZ,CAAV,CAAtF,CACO,CAAA,CAAA,CAFX,EAKOQ,EAAA,CAAiBK,EAAjB,CAA+Cb,CAA/C,CAAqDC,CAArD,CAnDX;AAuQAjD,QAAA,GAAa,CAAbA,CAAa,CAACgD,CAAD,CACb,CAGI,IAAIf,EAAQ6B,CAhBL9B,EAAA,EAgByBgB,CAhBzB,CAgBKc,CAhBmBzD,EAAxB,IAgBKyD,CAhBsCnC,EAA3C,CAiBP,EAAAI,EAAA,EACArhB,EAAA,CAAIuhB,CAAA8B,EAAA,CAHMf,CAGN,CAhaegB,KAgaf,CAA0BhB,CAA1B,CACJ,EAAAjB,EAAA,EACA,OAAOrhB,EAPX,CAmBAof,QAAA,GAAa,CAAbA,CAAa,CAACkD,CAAD,CAAOtiB,CAAP,CACb,CAEI,IAAIuhB,EAAQ6B,CAnCL9B,EAAA,EAmCyBgB,CAnCzB,CAmCKc,CAnCmBzD,EAAxB,IAmCKyD,CAnCsCnC,EAA3C,CAoCP,EAAAI,EAAA,EACAE,EAAAgC,EAAA,CAAsBvjB,CAAtB,CAHUsiB,CAGV,CAnbmBgB,KAmbnB,CAA8BhB,CAA9B,CACA,EAAAjB,EAAA,EALJ,CA8BAmC,QAAA,GAAc,CAAdA,CAAc,CAAClB,CAAD,CAAOmB,CAAP,CACd,CAGQC,CAAAA,CAAAA,CAAApC,EAAAoC,CADapB,CACboB,GADsBA,CAAAzC,EACtByC,CAAkED,EA2oBtE,CAQqC,CARrC,GAQQ,EAAE,CAAAE,EARV,GASQC,CAzDRvE,EAgDA,CASQuE,CAzDSC,EAAA,CAyDTD,CAzDyBE,GAAhB,CAyDTF,CAzD0CL,EAgDlD,EACoC,CADpC,GACQ,EAAE,CAAAQ,EADV,GAEQC,CA5DRzE,EA0DA,CAEQyE,CA5DQX,EA0DhB,CA9oBJ,CAoCAxB,QAAA,GAAU,CAAVA,CAAU,CACV,CAII,IAHA,IAAI3iB,EAAI,CAAR,CACIR,EAAI,EADR,CAGSijB,EAAS,CAAlB,CAAqBA,CAArB,CAA8B,CAAAP,EAA9B,CAAgDO,CAAA,EAAhD,CAA0D,CACtD,IAAIJ,EAAQ,CAAAD,EAAA,CAAgBK,CAAhB,CAMZ,IAAkDJ,CAAA0C,GAAlD,EAAkE1C,CAAA2C,GAAlE,CAAoF,CAChFxlB,CAAA,CAAEQ,CAAA,EAAF,CAAA,CAASyiB,CACP,KAAA,EAAAziB,CAAA,EAm5pBV,IAn5pBgC,CAm5pBhC,CAn5pBgCqiB,CAAAxE,KAAA,EAm5pBhC,CAAU,CAIN,IAHA,IAAIoH,EAAO,CAAX,CACIjC,EAAQ,CADZ,CAEIC,EAAQ,EACZ,CAAOgC,CAAP,CAAcC,CAAArhB,OAAd,CAAA,CAA2B,CAIvB,IAHA,IAAIxD,EAAI6kB,CAAA,CAAKD,CAAL,CAAR,CAEIE,EAAWF,CAAXE,CAAkB,CACtB,CAAOA,CAAP,CAAkBD,CAAArhB,OAAlB,EAAiCqhB,CAAA,CAAKC,CAAL,CAAjC,GAAoD9kB,CAApD,CAAA,CAAuD8kB,CAAA,EACvDlC,EAAA,CAAMD,CAAA,EAAN,CAAA,CAAiBmC,CAAjB,CAA4BF,CAC5BhC,EAAA,CAAMD,CAAA,EAAN,CAAA,CAAiB3iB,CACjB4kB,EAAA,CAAOE,CAPgB,CASvBlC,CAAApf,OAAJ,CAAmBqhB,CAAArhB,OAAnB,GAAgC,CAAhC,CAAuCof,CAAvC,CAbM,CAn5pBFzjB,CAAA,CAAE,CAAF,CAAA,CAAS,CAFuE,CAP9B,CAa1D,MAAOA,EAjBX;AAyFAqU,CAAAuR,GAAA,CAAAA,QAAK,CAAChC,CAAD,CACL,CAEI,GAAI,CAAC,IAAAjB,EAAL,CAmqFA,KAlqFoB,KAAArT,EAkqFb,EAlqFyB4G,EAAA,CAAA,IAAA5G,EAAA,CAv6DxBqK,CAu6DwB,CAkqFzB,EAjqFCvD,EAAA,CAAA,IAAA9G,EAAA,CAAsB,kBAAtB,CAA2CuW,CAAA,CAAA,IAAAvW,EAAA,CAAmBsU,CAAnB,CAA3C,CAAqE,CAAA,CAArE,CAA2E,CAAA,CAA3E,CAiqFD,CADP5D,CAAA,CA9pFI,IAAAzQ,EA8pFJ,CACO,CAAA,EAAP,CArqFJ,CAmCA6U,SAAA,GAAW,CAAC0B,CAAD,CAASlC,CAAT,CAAeC,CAAf,CACX,CA32GI1a,CAAA,CA42Ga,sBA52Gb,CA42GsC2c,CA52GtC,CA42G+C,IA52G/C,CA42GsDC,CAAA,CAAUnC,CAAV,CA52GtD,CA42GwE,GA52GxE,CA42G8EmC,CAAA,CAAUlC,CAAV,CA52G9E,CA42GgG,GA52GhG,CAs3GA,OAAO,CAAA,CAXX,CAgBAmC,IAAAA,GAAoBA,CAApBA,CACAC,GAAoBA,CAgBpB/X,SANEgY,GAMS,CAACC,CAAD,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,QAAN,CAAgBA,CAAhB,CAr+DQlM,GAq+DR,CADJ,CAPsB8C,EAAA5O,CAApB+X,EAAoB/X,CAAAA,CAAAA,CAoBtB,EAAA,CAt3MJ,EAAAiY,UAs3MI/R,EAAA0J,GAAA,CAAAA,QAAO,CAACtO,CAAD,CAAMD,CAAN,CAAWD,CAAX,CAAgBD,CAAhB,CACP,CACI,IAAAE,EAAA,CAAWA,CACX,KAAAC,EAAA,CAAWA,CACX,KAAAF,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CAEXmG,GAAA,CAAAA,IAAA,CANJ,CAiBApB,EAAAyB,GAAA,CAAAA,QAAO,CAACjN,CAAD,CAAOqV,CAAP,CACP,CACI,GAAI,CAACA,CAAL,CACI,GAAI,CAACrV,CAAL,CACI,IAAAoU,MAAA,EADJ,KAGI,IAAI,CAAC,IAAAmB,QAAA,CAAavV,CAAb,CAAL,CAAyB,MAAO,CAAA,CAGxC,OAAO,CAAA,CARX,CAmBAwL,EAAA0B,GAAA,CAAAA,QAAS,CAACC,CAAD,CACT,CACI,MAAOA,EAAA,CAAO,IAAAqI,KAAA,EAAP,CAAqB,CAAA,CADhC,CASAhK,EAAA4I,MAAA,CAAAA,QAAK,EACL,EAWA5I;CAAAgK,KAAA,CAAAA,QAAI,EACJ,CAEI,MAAOxV,CADKyV,IAAIC,CAAJD,CAAU,IAAVA,CACLzV,MAAA,EAFX,CAcAwL,EAAA+J,QAAA,CAAAA,QAAO,EACP,CACI,MAAO,CAAA,CADX,CAgCJ8D,GAAA,CApBIZ,QAAW,EACX,CAEI,IADA,IAAI+E,EAAWnV,CAAA,CAA6BsQ,QAA7B,CAAuCxQ,CAAvC,CAAuD,QAAvD,CAAf,CACSsV,EAAU,CAAnB,CAAsBA,CAAtB,CAAgCD,CAAAhiB,OAAhC,CAAiDiiB,CAAA,EAAjD,CAA4D,CACxD,IACIC,EAAUF,CAAA,CAASC,CAAT,CACVH,KAAAA,EAActU,EAAA,CAA4B0U,CAA5B,CAClB,QAAOJ,CAAA,KAAP,EACA,KAAK,SAAL,CACIK,CACA,CADS,IAAIN,EAAJ,CAAgBC,CAAhB,CACT,CAAAvE,EAAA,CAAgC4E,CAAhC,CAAwCD,CAAxC,CAHJ,CAJwD,CAFhE,CAmBJ,CAoDIrY;QA1BE4U,GA0BS,CAACtT,CAAD,CAAMoU,CAAN,CAAYM,CAAZ,CAAkBL,CAAlB,CAAwBrd,CAAxB,CACX,CAEI,IAAAgJ,EAAA,CAAWA,CACX,KAAAlB,GAAA,CAAWmY,EAAX,EAAkC,CAGlC,KAAA7C,EAAA,CAAYA,CACZ,KAAAM,GAAA,CAAYA,CACZ,KAAAL,KAAA,CAAYA,CAAZ,EAAoB,CACpB,KAAArd,KAAA,CAAYA,CAAZ,EAAoBkgB,EACpB,KAAAvB,EAAA,CAAkB3e,CAAlB,EAA0BmgB,EAC1B,KAAArX,EAAA,CAAW,IACX,KAAAuR,EAAA,CAAgB,IAAA8D,EAAhB,CAAsC,IAAAiC,GACtC,KAAAjG,EAAA,CAAiB,IAAAkE,EAAjB,CAAwC,IAAAO,GACxC,KAAAC,EAAA,CAAwB,IAAAJ,EAAxB,CAAiD,CACjDjC,GAAA,CAAAA,IAAA,CASA,KAAAuC,GAAA,CAAc,IAAAC,GAAd,CAAgC,CAAA,CAKhC,IAAK,IAAA3B,KAAL,CAAA,CAaA7jB,CAAA,CAAI,IAAA6mB,EAAJ,CAAkB5d,KAAJ,CAAU,IAAA4a,KAAV,CACd,KAAKrjB,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgBR,CAAAqE,OAAhB,CAA0B7D,CAAA,EAA1B,CAA+BR,CAAA,CAAEQ,CAAF,CAAA,CAAO,CACtCsmB,GAAA,CAAAA,IAAA,CAAeC,EAAf,CAfA,CAAA,IACID,GAAA,CAAAA,IAAA,CA9BR,CAmGA,CAAA,CA1nNJ,EAAAE,UA0nNI3S,EAAAgK,KAAA,CAAAA,QAAI,EACJ,CACI,MAAO,KAAAwI,EADX,CAeAxS,EAAA+J,QAAA,CAAAA,QAAO,CAACyI,CAAD,CACP,CACI,MAAIA,EAAJ,EAAU,IAAAhD,KAAV,EAAuBgD,CAAAxiB,OAAvB,EACI,IAAAwiB,EACA,CADUA,CACV,CAAA,IAAAtB,GAAA,CAAc,CAAA,CAFlB,EAKO,CAAA,CANX,CA0DAuB,SAAA,GAAS,CAATA,CAAS,CAAC3Z,CAAD,CACT,CACSA,CAAL,GAEIA,CAFJ,CAEU8Z,EAFV,CAIAC,GAAA,CAAAA,CAAA,CAAmB/Z,CAAnB,CANWga,IAAAA,EAMX,CACAC,GAAA,CAAAA,CAAA,CAAoBja,CAApB,CAPWga,IAAAA,EAOX,CANJ;AAgBAD,QAAA,GAAa,CAAbA,CAAa,CAAC/Z,CAAD,CAAMga,CAAN,CACb,CACSA,CAAL,EAAiB,CAAA9B,EAAjB,GACI,CAAAxE,EADJ,CACoB1T,CAAA,CAAI,CAAJ,CADpB,EAC8B,CAAAyZ,GAD9B,CAGA,IAAIO,CAAJ,EAA2BjiB,IAAAA,EAA3B,GAAeiiB,CAAf,CACI,CAAAxC,EAAA,CAAsBxX,CAAA,CAAI,CAAJ,CAAtB,EAAgC,CAAAyZ,GALxC,CAgBAQ,QAAA,GAAc,CAAdA,CAAc,CAACja,CAAD,CAAMga,CAAN,CACd,CACSA,CAAL,EAAiB,CAAAlC,EAAjB,GACI,CAAAtE,EADJ,CACqB,CAAC,CAAAwE,EADtB,EACwChY,CAAA,CAAI,CAAJ,CADxC,EACkD,CAAAiY,GADlD,CAGA,IAAI+B,CAAJ,EAA2BjiB,IAAAA,EAA3B,GAAeiiB,CAAf,CACI,CAAAtC,EAAA,CAAuB1X,CAAA,CAAI,CAAJ,CAAvB,EAAiC,CAAAiY,GALzC,CAiDA/Q,CAAAgT,GAAA,CAAAA,QAAa,CAACC,CAAD,CAAMvC,CAAN,CACb,CACSA,CAAL,CAOqC,CAPrC,GAOQ,IAAAE,EAAA,EAPR,EAQQmC,EAAA,CAAAA,IAAA,CAAoBG,EAApB,CAA4C,CAAA,CAA5C,CARR,CACoC,CADpC,GACQ,IAAAlC,EAAA,EADR,EAEQ6B,EAAA,CAAAA,IAAA,CAAmBK,EAAnB,CAA2C,CAAA,CAA3C,CAHZ,CA+CAvE,SAAA,GAAe,CAAfA,CAAe,CAAC1T,CAAD,CAAMkY,CAAN,CACf,CACI,CAAAlY,EAAA,CAAWA,CACX,EAAA+V,EAAA,CAAwB,CAAAJ,EAAxB,CAAiD,CAC7CuC,EAAJ,GAII,CAHK,CAAAnC,EAGL,CAH6BmC,CAAAnC,EAG7B,GAFI6B,EAAA,CAAAA,CAAA,CAAmBK,EAAnB,CAA2C,CAAA,CAA3C,CAEJ,EAAK,CAAAtC,EAAL,CAA8BuC,CAAAvC,EAA9B,GACImC,EAAA,CAAAA,CAAA,CAAoBG,EAApB,CAA4C,CAAA,CAA5C,CALR,CAHJ,CAqBAlT,CAAAuS,GAAA,CAAAA,QAAQ,CAACU,CAAD,CAAM1D,CAAN,CACR,CACoB,IAAAtU,EAAhB,EAA4B4G,EAAA,CAAA,IAAA5G,EAAA,CA/9EpBwK,EA+9EoB,CAA5B,EACI1D,EAAA,CAAA,IAAA9G,EAAA,CAAsB,kCAAtB,CAA2DuW,CAAA,CAAA,IAAAvW,EAAA,CAAmBsU,CAAnB,CAA3D,CAAqF,CAAA,CAArF,CAEJ,KAAApU,EAAAoW,GAAA,CAAehC,CAAf,CACA,OA7pFa6D,EAwpFjB,CAgBApT;CAAA+Q,GAAA,CAAAA,QAAS,CAAC/jB,CAAD,CAAIimB,CAAJ,CAAS1D,CAAT,CACT,CACoB,IAAAtU,EAAhB,EAA4B4G,EAAA,CAAA,IAAA5G,EAAA,CAh/EpBwK,EAg/EoB,CAA5B,EACI1D,EAAA,CAAA,IAAA9G,EAAA,CAAsB,mBAAtB,CAA4CuW,CAAA,CAAA,IAAAvW,EAAA,CAAmBjO,CAAnB,CAA5C,CAAoE,wBAApE,CAA+FwkB,CAAA,CAAA,IAAAvW,EAAA,CAAmBsU,CAAnB,CAA/F,CAAyH,CAAA,CAAzH,CAEJ,KAAApU,EAAAoW,GAAA,CAAehC,CAAf,CAJJ,CAeAvP,EAAAqT,GAAA,CAAAA,QAAc,CAACJ,CAAD,CACd,CAGI,MAFQ,KAAAT,EAAAvlB,CAAQgmB,CAARhmB,CADZ,CAcA+S,EAAAsT,GAAA,CAAAA,QAAe,CAACrmB,CAAD,CAAIgmB,CAAJ,CACf,CAEQ,IAAAT,EAAA,CAAQS,CAAR,CAAJ,EAAoBhmB,CAApB,GACI,IAAAulB,EAAA,CAAQS,CAAR,CACA,CADehmB,CACf,CAAA,IAAAikB,GAAA,CAAc,CAAA,CAFlB,CAFJ,CAgBAlR,EAAAuT,GAAA,CAAAA,QAAe,CAACN,CAAD,CAAM1D,CAAN,CACf,CACI,GAAgB,IAAAtU,EAAhB,EAAyC,IAAzC,EAA4B,IAAAsU,EAA5B,CAAA,CACItU,IAAAA,EAAAA,IAAAA,EAggcAuY,GAAA,CAAAA,CAAA,CAhgcyB,IAAAjE,EAggczB,CAhgcqC0D,CAggcrC,CAhgc0CQ,CAggc1C,CAAoC,CAAAC,EAApC,CAAJ,EACI/H,EAAA,CAAAA,CAAA,CAAa,CAAA,CAAb,CAlgcJ,CAGA,MAAO,KAAA2E,EAAA,CAAoB2C,CAApB,CAAyB1D,CAAzB,CAJX,CAeAvP,EAAA2T,GAAA,CAAAA,QAAgB,CAAC1mB,CAAD,CAAIgmB,CAAJ,CAAS1D,CAAT,CAChB,CACI,GAAgB,IAAAtU,EAAhB,EAAyC,IAAzC,EAA4B,IAAAsU,EAA5B,CAAA,CACItU,IAAAA,EAAAA,IAAAA,EAygcAuY,GAAA,CAAAA,CAAA,CAzgc0B,IAAAjE,EAygc1B,CAzgcsC0D,CAygctC,CAzgc2CQ,CAygc3C,CAAoC,CAAAG,EAApC,CAAJ,EACIjI,EAAA,CAAAA,CAAA,CAAa,CAAA,CAAb,CA3gcJ,CAGI,IAAAmF,EAAJ,CAAoB,IAAAC,GAAA,CAAe9jB,CAAf,CAAkBgmB,CAAlB,CAAuB1D,CAAvB,CAApB,CAAuD,IAAAiB,EAAA,CAAqBvjB,CAArB,CAAwBgmB,CAAxB,CAA6B1D,CAA7B,CAJ3D,CAiBAsE;IAAAA,GAAYA,CAAZA,CAEAlO,GAAYA,CAFZkO,CAKJ3D,GAA0B,CAAC,MAAD,CAAU,KAAV,CAAkB,KAAlB,CALtB2D,CAUJzB,GAAsB,CAVlByB,CAqBJjB,GAAsB,EArBlBiB,CAuBJnB,GAAwB,CACpBjE,EAAAle,UAAA8iB,GADoB,CAEpB5E,EAAAle,UAAA+iB,GAFoB,CAvBpBO,CA4BJX,GAAyB,CACrBzE,EAAAle,UAAAgjB,GADqB,CAErB9E,EAAAle,UAAAojB,GAFqB,CAgDrB9Z;QAhCEia,GAgCS,CAACC,CAAD,CAAWC,CAAX,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,KAAN,CAAaD,CAAb,CAnpFQ3O,CAmpFR,CAEI6O,EAAAA,CAAU,CAACF,CAAA,OAAXE,EAAiCD,CAErC,KAAIE,EAAc,CAACH,CAAA,WAAfG,EAAyC,CAE7C,KAAApN,GAAA,CAAqB,CAErB,KAAAqN,GAAA,CAAwBF,CAOxB,KAAAG,GAAA,CAAyBF,CACzB,KAAAG,GAAA,CAAkBjmB,IAAAkmB,MAAA,CAAW,IAAAH,GAAX,CAAmC,GAAnC,CAAlB,CAA8D,GAC9D,KAAAI,GAAA,CAAiB,IAAAF,GAAjB,CAAmC,IAAAD,GACnC,KAAAI,GAAA,CAAkB,IAAAC,GAAlB,CAAyC,IAAAC,GAAzC,CAAiE,IAAAC,GAAjE,CAAsF,CAKtF,KAAApa,MAAA+Q,EAAA,CAAqB,IAAA/Q,MAAAqa,GAArB,CAA2C,CAAA,CAC3C,KAAAra,MAAAsa,GAAA,CAAuBd,CAAA,UACY,SAAnC,EAAI,MAAO,KAAAxZ,MAAAsa,GAAX,GAA6C,IAAAta,MAAAsa,GAA7C,CAA6F,MAA7F,EAAqE,IAAAta,MAAAsa,GAArE,CAWA,KAAAta,MAAAua,GAAA,CAAsB,CAAA,CACtB,KAAAC,GAAA,CAAiB,IAAAC,GAAjB,CAA4C,CAC5C,KAAAC,GAAA,CAA4B,CAAClB,CAAA,QAC7B,KAAAmB,GAAA,CAA+B,CAACnB,CAAA,WAChC,KAAAoB,GAAA,CAA2B,CAACpB,CAAA,OAK5B,KAAAqB,EAAA,CAAe,EAEf,KAAAC,GAAA,CAAoB,IAAAC,GAAAlS,KAAA,CAAiB,IAAjB,CAQpB,KAAAmS,EAAA,CAAoB,IAAAC,EAApB,CAAsC,IAAAC,EAAtC,CAA0D,IAAAC,EAA1D,CADA,IAAAC,EACA,CADkB,IAAAC,GAClB;AADwC,IAAAC,EACxC,CAD4D,IAAAC,GAC5D,CAFA,IAAAC,GAEA,CAHA,IAAAC,EAGA,CAHW,CAIX,KAAA7M,GAAA,CAAa,IAEb/H,GAAA,CAAAA,IAAA,CA3DJ,CAjCmBsH,EAAA5O,CAAjBga,EAAiBha,CAAAA,CAAAA,CAwGnB,EAAA,CAtlOJ,EAAAmc,UAslOIjW,EAAA0J,GAAA,CAAAA,QAAO,CAACtO,CAAD,CAAMD,CAAN,CAAWD,CAAX,CAAgBD,CAAhB,CACP,CACI,IAAAG,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CACX,KAAAF,EAAA,CAAWA,CACX,KAAAkO,GAAA,CAAa/N,CAAA+N,EACb,KAAShd,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoB+pB,EAAAlmB,OAApB,CAA6C7D,CAAA,EAA7C,CAEI,CADIiQ,CACJ,CADc,IAAAhC,EAAA,CAAc+b,EAAA,CAAiBhqB,CAAjB,CAAd,CACd,GAAa,IAAAiP,EAAAqC,GAAA,CAAoB,EAApB,CAAwB0Y,EAAA,CAAiBhqB,CAAjB,CAAxB,CAA6CiQ,CAA7C,CAEjBgF,GAAA,CAAAA,IAAA,CATJ,CAmBApB,EAAA4I,MAAA,CAAAA,QAAK,EACL,EAWA5I,EAAAgK,KAAA,CAAAA,QAAI,EACJ,CACI,MAAO,KADX,CAaAhK,EAAA+J,QAAA,CAAAA,QAAO,EACP,CACI,MAAO,CAAA,CADX,CAYA/J;CAAAyB,GAAA,CAAAA,QAAO,CAACjN,CAAD,CAAOqV,CAAP,CACP,CAII,IAAIuM,EAAaC,EAAA,CAAA,IAAAjb,EAAA,CAAwB,WAAxB,CACC,KAAlB,EAAIgb,CAAJ,CACI,IAAA7b,MAAAsa,GADJ,CAC0C,MAAd,EAAAuB,CAAA,CAAsB,CAAA,CAAtB,CAA6C,OAAf,EAAAA,CAAA,CAAwB,CAAA,CAAxB,CAAgC,CAAC,CAACA,CAD5F,CAGiC,IAHjC,EAGS,IAAA7b,MAAAsa,GAHT,GAQI,IAAAta,MAAAsa,GARJ,CAQ0C,CAAC,IAAA5Z,EAR3C,EAQiFpK,IAAAA,EARjF,GAQwD,IAAAuJ,EAAA,IARxD,CAWA,IAAI,CAACyP,CAAL,CAAe,CACX,GAAKrV,CAAL,CAEO,CACH8hB,EAAA,CAAAA,IAAA,CACA,IAAI,CAAC,IAAAvM,QAAA,CAAavV,CAAb,CAAL,CAAyB,MAAO,CAAA,CAChC+hB,GAAA,CAAAA,IAAA,CAHG,CAFP,IACI,KAAA3N,MAAA,EASY,KAAA3N,EAAhB,EACIA,CAi6ZR,CAj6ZQA,IAAAA,EAi6ZR,CAj6ZsB4Z,CAi6ZtB,CAj6ZsBA,IAAAta,MAAAsa,GAi6ZtB,CAJA,CAAA2B,GAIA,CAJa,CAAA,CAIb,CAHA,CAAAhW,EAAA,CAAa,8CAAb,CAGA,CAFAiW,EAAA,CAAAA,CAAA,CAEA,CADKC,CACL,EADiBC,EAAA,CAAAA,CAAA,CACjB,CAAI,CAAAC,GAAJ,GACQC,CAEJ,CAFY,CAAAD,GAEZ,CADA,CAAAA,GACA,CADqB,IACrB,CAAAE,EAAA,CAAAA,CAAA,CAAgBD,CAAhB,CAAuB,CAAA,CAAvB,CAHJ,CAl6ZI,EAGI,IAAA/jB,OAAA,CAAY,sBAAZ,CAEC,KAAAyH,MAAAsa,GAAL,EACI,IAAArU,EAAA,CAAa,+BAAb,EAAgD,IAAA2I,GAAA,CAAY,sBAAZ;AAAqC,sBAArF,EAjBO,CA0Bf,MAAO,CAAA,CA1CX,CAqDAnJ,EAAA0B,GAAA,CAAAA,QAAS,CAACC,CAAD,CACT,CACI,MAAOA,EAAA,CAAO,IAAAqI,KAAA,EAAP,CAAqB,CAAA,CADhC,CAUAhK,EAAA6U,GAAA,CAAAA,QAAS,EACT,CACI,MAAI,KAAAta,MAAA+Q,EAAJ,CACW,CAAA,CADX,CAGI,IAAA/Q,MAAAsa,GAAJ,EAMInJ,EAAA,CAAAA,IAAA,CACO,CAAA,CAAA,CAPX,EASO,CAAA,CAbX,CAkDA1L,EAAA+W,GAAA,CAAAA,QAAW,EACX,CACI,MAAO,EADX,CAcAR,SAAA,GAAa,CAAbA,CAAa,CACb,CACsC1lB,IAAAA,EAAlC,GAAI,CAAAokB,GAAJ,GAA6C,CAAAA,GAA7C,CAAyE,CAAzE,CACqCpkB,KAAAA,EAArC,GAAI,CAAAqkB,GAAJ,GAAgD,CAAAA,GAAhD,CAAgF,EAAhF,CACiCrkB,KAAAA,EAAjC,GAAI,CAAAskB,GAAJ,GAA4C,CAAAA,GAA5C,CAAwE,EAAxE,CACA,EAAA5a,MAAAua,GAAA,CAAoD,CAApD,EAAuB,CAAAG,GAAvB,EAAwF,CAAxF,CAAyD,CAAAC,GACrD,EAAA3a,MAAAua,GAAJ,GACI,CAAAC,GACA,CADiB,CACjB,CAAA,CAAAC,GAAA,CAA2B,CAAAC,GAA3B,CAAuD,CAAAM,EAF3D,CALJ;AA4BAvJ,QAAA,GAAc,CAAdA,CAAc,CAACiI,CAAD,CACd,CACI,GAAI,CAAA1Z,MAAAua,GAAJ,CAAyB,CAIrB,IAAIkC,EAAW,CAAA,CACf,EAAAjC,GAAA,CAAkB,CAAAA,GAAlB,CAAmC,CAAAgC,GAAA,EAAnC,CAAuD,CACvD,EAAA/B,GAAA,EAA4Bf,CACI,EAAhC,EAAI,CAAAe,GAAJ,GACI,CAAAA,GACA,EAD4B,CAAAE,GAC5B,CAAA8B,CAAA,CAAW,CAAA,CAFf,CAIgC,EAAhC,EAAI,CAAA7B,GAAJ,EACQ,CAAAA,GADR,EACoC8B,EAAA,CAAAA,CAAA,CADpC,GAEQ,CAAA/B,GAGA,CAH+B,CAAAC,GAG/B,CAH2D,EAG3D,CAFAoB,EAAA,CAAAA,CAAA,CAEA,CADA5K,CAAA,CAAAA,CAAA,CACA,CAAAqL,CAAA,CAAW,CAAA,CALnB,CAQIA,EAAJ,EAAcE,CAelB1W,EAAA,CAAayW,EAAA,CAfKC,CAeL,CAAb,CAA8C,uBAA9C,CAA4DxF,CAAA,CAf1CwF,CAeoDnC,GAAV,CAA5D,CAlCyB,CAD7B;AAgDA/U,CAAAvC,GAAA,CAAAA,QAAU,CAACyC,CAAD,CAAYC,CAAZ,CAAsB/D,CAAtB,CACV,CACI,IAAIlB,EAAM,IAEV,QAAQiF,CAAR,EACA,KAAK,OAAL,CACA,KAAK,OAAL,CAOI,MADA,KAAA/F,EAAA,CAAc+F,CAAd,CACO,CADmB/D,CACnB,CAAA,CAAA,CAEX,MAAK,KAAL,CAcI,MAbA,KAAAhC,EAAA,CAAc+F,CAAd,CAaO,CAbmB/D,CAanB,CAZPA,CAAAgE,QAYO,CAZW+W,QAAmB,EAAG,CAChC,IAAA,CAAA,IAAC/b,CAAD,CAACA,CAAAA,EAAD,CAkolBZ,GAlolByB,CAkolBrBR,CAlolBqB,CAAA,EAkolBrBA,CAAA,CAAAL,MAAAK,EAAJ,CAAwB,CAAA,CAAO,CAAA,CAA/B,KAAA,CADJ,IAGQU,EAAY,IAHpB,CAG0B8b,CAH1B,CAIQxZ,EAAcyZ,EAAA,CAAwB,CAAApd,GAAxB,CAClB,KAAKmd,CAAL,CAAkB,CAAlB,CAAqBA,CAArB,CAAkCxZ,CAAA5N,OAAlC,GACIsL,CACI,CADQsC,CAAA,CAAYwZ,CAAZ,CACR,CAAA9b,CAAA,GAAc,CAAd,EAAuBA,CAAAf,MAAAC,MAF/B,EAAsD4c,CAAA,EAAtD,EAIA,GAAIA,CAAJ,EAAkBxZ,CAAA5N,OAAlB,CACI,IAAKonB,CAAL,CAAkB,CAAlB,CAAqBA,CAArB,CAAkCxZ,CAAA5N,OAAlC,GACIsL,CACI,CADQsC,CAAA,CAAYwZ,CAAZ,CACR,CAAA9b,CAAA,GAAc,CAAd,EAAuBA,CAAAf,MAAAK,EAF/B,EAAsDwc,CAAA,EAAtD,EAKAA,CAAJ,EAAkBxZ,CAAA5N,OAAlB,GAAsCsL,CAAtC,CAAkD,CAAlD,CAEAxG,EAAA,CADQ,MACR,CADiBwG,CAAAnJ,KACjB,CADkC,cAClC,CADmDmJ,CAAArB,GACnD,CADkE,WAClE,EADkFqB,CAAAf,MAAAC,MAAD,CAAgG,aAAhG,CAAwB,WAAxB,EAAuCc,CAAAP,GAAA,CAAmB,6BAAnB,CAAmD,EAA1F,CACjF,EADkM,GAClM,CACA,EAAA,CAAO,CAAA,CAjBP,CAlolBY,CAAJ,GAMKG,CAAAX,MAAA+Q,EAAL;AAGIK,CAAA,CAAAzQ,CAAA,CAHJ,CACIwQ,EAAA,CAAAxQ,CAAA,CAPJ,CADoC,CAYjC,CAAA,CAAA,CAEX,MAAK,OAAL,CAEI,MADA,KAAAd,EAAA,CAAc+F,CAAd,CACO,CADmB/D,CACnB,CAAA,CAAA,CAEX,MAAK,UAAL,CAMI,MALA,KAAAhC,EAAA,CAAc+F,CAAd,CAKO,CALmB/D,CAKnB,CAJPA,CAAAgE,QAIO,CAJW+W,QAAwB,EAAG,CACzCG,EAAA,CAAApc,CAAA,CAAaA,CAAAkZ,GAAb,EAAsC,CAAtC,CAAyC,CAAA,CAAzC,CADyC,CAItC,CADPhY,CAAAsG,YACO,CADe6U,IA6MnBhD,GAAAiD,QAAA,CAAuB,CAAvB,CA5MI,CA4MwB,KA5MxB,CAAA,CAAA,CArCX,CA0CA,MAAO,CAAA,CA7CX,CAwFAzL,SAAA,GAAS,CAATA,CAAS,CAACkI,CAAD,CAAUwD,CAAV,CACT,CACI,CAAAlC,EAAA,EAAqBtB,CACjBwD,EAAJ,GACI,CAAAhC,EADJ,CACwB,CAAAC,EADxB,CAC8D,CAD9D,CAFJ,CAsBAgC,QAAA,GAAU,CAAVA,CAAU,CAACC,CAAD,CACV,CAII,IAAIC,EAAc,CACdD,EAAJ,EACiC,CADjC,CACQ,CAAAvD,GADR,EACsC,CAAA4B,EADtC,GAEQ4B,CAFR,CAEuB,CAAA5B,EAFvB,CAEkC,CAAA3B,GAFlC,CAMA,EAAAG,GAAA,CAAkBpmB,IAAAkmB,MAAA,CAAW,GAAX,CAAkBuD,EAAlB,CAClB,EAAApD,GAAA,CAAuBrmB,IAAA0pB,MAAA,CAAW,CAAA3D,GAAX,CAAmC0D,EAAnC,CAAgED,CAAhE,CAKlBD,EAAL,GAAc,CAAAjD,GAAd,CAAsC,CAAAD,GAAtC,CACA,EAAAE,GAAA,CAAqB,CAlBzB,CAsCAsC,QAAA,GAAS,CAATA,CAAS,CACT,CAuBI,MAtBc,EAAA1B,EAsBd,CAtBkC,CAAAC,EAsBlC,CAtBoD,CAAAC,EAsBpD,CAtBwE,CAAAC,EAD5E,CAgDAY,QAAA,GAAW,CAAXA,CAAW,CACX,CACI,CAAAN,EAAA,CAAW,CACX,EAAAD,GAAA,CAAgC,CAChC,EAAAR,EAAA,CAAoB,CAAAC,EAApB,CAAsC,CAAAC,EAAtC,CAA0D,CAAAC,EAA1D,CAAgG,CAChGa,GAAA,CAAAA,CAAA,CACAe,GAAA,CAAAA,CAAA,CAAc,CAAd,CALJ;AA6DAA,QAAA,GAAQ,CAARA,CAAQ,CAACpD,CAAD,CAAc6D,CAAd,CACR,CACI,IAAIhZ,EAAW,CAAA,CACf,IAAoBlO,IAAAA,EAApB,GAAIqjB,CAAJ,CAA+B,CAIK,EAAhC,CAAI,CAAA8B,EAAJ,CAAe,CAAAzB,GAAf,CACIL,CADJ,CACkB,CADlB,CAGInV,CAHJ,CAGe,CAAA,CAEf,EAAAqV,GAAA,CAAyBF,CACrB8B,EAAAA,CAAM,CAAA3B,GAAN2B,CAAwB,CAAA5B,GAC5B,IAAI,CAAAG,GAAJ,EAAsByB,CAAtB,CAA2B,CACvB,CAAAzB,GAAA,CAAiByB,CACbgC,EAAAA,CAAST,CAjCdhD,GAAAiD,QAAA,CAAuB,CAAvB,CAiCKQ,CAjCuB,KAkC3B,KAAIC,EAAe,CAAA7d,EAAA,SACf6d,EAAJ,GAAkBA,CAAAvV,YAAlB,CAA6CsV,CAA7C,CACA,EAAAxX,EAAA,CAAa,gBAAb,CAAgCwX,CAAhC,CALuB,CAOvBD,CAAJ,EAAoB,CAAA3c,EAApB,EAA8Bub,EAAA,CAAA,CAAAvb,EAAA,CAlBH,CAoB/B2Q,EAAA,CAAAA,CAAA,CAAe,CAAAyJ,EAAf,CACA,EAAAA,EAAA,CAAkB,CAClB,EAAAG,EAAA,CAAkBuC,EAAA,EAClB,EAAArC,EAAA,CAAoB,CACpB6B,GAAA,CAAAA,CAAA,CACA,OAAO3Y,EA3BX,CAmRAoZ,QAAA,GAAc,CAAdA,CAAc,CAAClE,CAAD,CACd,CACI,IAAK,IAAI9nB,EAAI,CAAAipB,EAAAplB,OAAJ7D,CAA0B,CAAnC,CAA2C,CAA3C,EAAsCA,CAAtC,CAA8CA,CAAA,EAA9C,CAAmD,CAC/C,IAAIuL,EAAQ,CAAA0d,EAAA,CAAajpB,CAAb,CAEG,EAAf,CAAIuL,CAAA,CAAM,CAAN,CAAJ,EACIuc,CADJ,CACcvc,CAAA,CAAM,CAAN,CADd,GAEIuc,CAFJ,CAEcvc,CAAA,CAAM,CAAN,CAFd,CAH+C,CAQnD,MAAOuc,EATX,CAkBAmE,QAAA,GAAU,CAAVA,CAAU,CACV,CAEI,IADA,IAAIC,EAAe,EAAnB,CACSlsB,EAAI,CAAb,CAAgBA,CAAhB,CAAoB,CAAAipB,EAAAplB,OAApB,CAAyC7D,CAAA,EAAzC,CAEIksB,CAAAjjB,KAAA,CADY,CAAAggB,EAAA1d,CAAavL,CAAbuL,CACM,CAAM,CAAN,CAAlB,CAEJ,OAAO2gB,EANX;AAkCAvM,QAAA,GAAY,CAAZA,CAAY,CAACmI,CAAD,CACZ,CACI,IAAK,IAAI9nB,EAAI,CAAAipB,EAAAplB,OAAJ7D,CAA0B,CAAnC,CAA2C,CAA3C,EAAsCA,CAAtC,CAA8CA,CAAA,EAA9C,CAAmD,CAC/C,IAAIuL,EAAQ,CAAA0d,EAAA,CAAajpB,CAAb,CAEG,EAAf,CAAIuL,CAAA,CAAM,CAAN,CAAJ,GACAA,CAAA,CAAM,CAAN,CACA,EADYuc,CACZ,CAAgB,CAAhB,EAAIvc,CAAA,CAAM,CAAN,CAAJ,GACIA,CAAA,CAAM,CAAN,CACA,CADY,EACZ,CAAAA,CAAA,CAAM,CAAN,CAAA,EAFJ,CAFA,CAH+C,CADvD,CAoBA4gB,QAAA,GAAQ,CAARA,CAAQ,CAACC,CAAD,CACR,CACI,IAAItE,EAAU,CAAAwB,EAAVxB,EAA+B,CAAAyB,EAOnC,EAAAA,EAAA,CAAsC,CAClC6C,EAAJ,GAAY,CAAA9C,EAAZ,CAAgC,CAAhC,CACA,OAAOxB,EAVX;AAkBAjU,CAAAsV,GAAA,CAAAA,QAAM,EACN,CACI,GAAK,IAAA/a,MAAA+Q,EAAL,CAAA,CAMAkN,IAlUI7D,GAAJ,EAkUA6D,IAlU0BrE,GAA1B,EACIuD,EAAA,CAiUJc,IAjUI,CAAgB,CAAA,CAAhB,CAiUJA,KA/TA1C,GAAA,CAAsB,CA+TtB0C,KA9TA5C,GAAA,CAAsBsC,EAAA,EA2BtB,IAmSAM,IAnSI3C,EAAJ,CAAuB,CACnB,IAAI4C,EAkSRD,IAlSkB5C,GAAV6C,CAkSRD,IAlSwC3C,EAChC4C,EAAJ,CAiSJD,IAjSkBhE,GAAd,GAiSJgE,IA/RQ7C,EAOA,EAPmB8C,CAOnB,CAwRRD,IAxRY7C,EAAJ,CAwRR6C,IAxR8B5C,GAAtB,GAwRR4C,IAvRY7C,EADJ,CAwRR6C,IAvR8B5C,GADtB,CATJ,CAFmB,CAqSvB,GAAI,CACA,EAAG,CAMC,IAAI3B,EAAUkE,EAAA,CAAAA,IAAA,CAAoB,IAAA5d,MAAAua,GAAA,CAAqB,CAArB,CAAyB,IAAAL,GAA7C,CAKd,IAAI,CACA,IAAA7I,GAAA,CAAaqI,CAAb,CADA,CAGJ,MAAMhI,CAAN,CAAiB,CAMb,GAAwB,QAAxB,EAAI,MAAOA,EAAX,CAAkC,KAAMA,EAAN,CANrB,CAYjBgI,CAAA,CAAUqE,EAAA,CAAAA,IAAA,CAAc,CAAA,CAAd,CAKV,KAAAxC,GAAA,EAAuB7B,CACvB,KAAAuB,EAAA,EAAmBvB,CACnBjI,GAAA,CAAAA,IAAA,CAAoBiI,CAApB,CAKAnI,GAAA,CAAAA,IAAA,CAAkBmI,CAAlB,CAEA,KAAAS,GAAA,EAAyBT,CACzB,IAA6B,CAA7B,EAAI,IAAAS,GAAJ,CAAgC,CAC5B,IAAAA,GAAA,EAAyB,IAAAD,GACrB,GAAE,IAAAsB,GAAN,EAAuC2C,EAAvC,GACIvM,IApnBZ/Q,EAqnBY,EArnBF+Q,CAAA,CAonBEA,IApnBF/Q,EAAA,CAFHud,IAAAA,EAEG,CAqnBE,CAAA,IAAA5C,GAAA,CAAgC,CAFpC,CAIA,MAN4B,CAzCjC,CAAH,MAiDS,IAAAxb,MAAA+Q,EAjDT,CADA,CAoDJ,MAAOvf,CAAP,CAAU,CACN4f,CAAA,CAAAA,IAAA,CACI,KAAAvQ,EAAJ,EAAc,IAAAA,EAAA0N,KAAA,CAAcoP,EAAA,EAAd,CAAmCjB,EAAA,CAAAA,IAAA,CAAnC,CACdhW;EAAA,CAAAA,IAAA,CAAclV,CAAAmgB,MAAd,EAAyBngB,CAAAgJ,QAAzB,CACA,OAJM,CAOV,GAAI,IAAAwF,MAAA+Q,EAAJ,CAAA,CAAwBlU,CAAAA,CAAAA,UAAWie,EAAAA,CAAA,IAAAA,GAAmBuD,KAtUtD/C,EAAA,CAAoBqC,EAAA,EAEpB,KAAIW,EAoUkDD,IApUxCpE,GAoUwCoE,KAnUlD9C,GAAJ,GAOI+C,CAPJ,CAOczqB,IAAAkmB,MAAA,CAAWuE,CAAX,CA4TwCD,IA5TnB9C,GAArB,CA4TwC8C,IA5TGnE,GAA3C,CAPd,CAWuBoE,EAAnBC,EAwTkDF,IAzT/B/C,EACnBiD,CAwTkDF,IAzTXhD,GAmB3BmD,KAAAA,EAsSsCH,IAtStC/C,EAAAkD,CAsSsCH,IAtSlBjD,EAzGhCoD,EAAJ,GA+YsDH,IA9YlD5C,EACA,CADW5nB,IAAAkmB,MAAA,CA8YuCsE,IAvSxCpD,EAvGC,EAAkC,EAAlC,CAAsBuD,CAAtB,EACX,CADoD,GACpD,CAAiB,KAAjB,EAAIA,CAAJ,GA6YkDH,IA5Y9CrD,EACA,CADoB,CACpB,CAAA+B,EAAA,CA2Y8CsB,IA3Y9C,CAFJ,CAFJ,CAiHA,IAAuB,CAAvB,CAAIE,CAAJ,EA8RsDF,IA9R1B5C,EAA5B,CA8RsD4C,IA9RfrE,GAAvC,CAM4B,IAQxB,CARIuE,CAQJ,GAgRkDF,IAvR9CjD,EAOJ,EAPuBmD,CAOvB,EAAAA,CAAA,CAAmB,CAgR+BF,KAzQtDjE,GAAA,EAyQsDiE,IAzQhC9C,GAyQgC8C,KAnQtD/C,EAAA,EAAqBiD,CAmQG1hB,EAAA,CAAWie,CAAX,CAlQjByD,CAkQiB,CAAxB,CAnEA,CADJ,CA+EApN;QAAA,GAAQ,CAARA,CAAQ,CAACqM,CAAD,CACR,CACI,GAAI,CAAA7W,EAAA,CAAAA,CAAA,CAAJ,CAGA,GAAI,CAAA3G,MAAA+Q,EAAJ,CACI,CAAA9K,EAAA,CAAa,CAAAP,SAAA,EAAb,CAA+B,OAA/B,CADJ,KAAA,CAUAqX,EAAA,CAAAA,CAAA,CACA,EAAA/c,MAAA+Q,EAAA,CAAqB,CAAA,CACrB,EAAA/Q,MAAAqa,GAAA,CAAsB,CAAA,CACtB,KAAIoE,EAAa,CAAA5e,EAAA,IACb4e,EAAJ,GAAgBA,CAAAtW,YAAhB,CAAyC,MAAzC,CACI,EAAAtH,EAAJ,GACQ2c,CACJ,EADkBpB,EAAA,CAAA,CAAAvb,EAAA,CAAkB,CAAA,CAAlB,CAClB,CAAA,CAAAA,EAAA0H,MAAA,CAAe,CAAA6S,EAAf,CAAgCsB,EAAA,CAAAA,CAAA,CAAhC,CAFJ,CAIK,EAAAhc,EAAL,EAAe,CAAAnI,OAAA,CAAY,SAAZ,CACfsE,WAAA,CAAW,CAAAie,GAAX,CAA8B,CAA9B,CApBA,CAJJ,CAqCArV,CAAAiZ,GAAA,CAAArN,QAAO,EACP,CACI,MAAO,EADX,CAgBAD,SAAA,EAAO,CAAPA,CAAO,CAACuN,CAAD,CACP,CACI,IAAIC,EAAW,CAAA,CACf,IAAI,CAAA5e,MAAA+Q,EAAJ,CAAwB,CACpBgN,EAAA,CAAAA,CAAA,CACAvM,GAAA,CAAAA,CAAA,CAAe,CAAAyJ,EAAf,CACA,EAAAA,EAAA,CAAkB,CAClB,EAAAjb,MAAA+Q,EAAA,CAAqB,CAAA,CAErB,IADI0N,CACJ,CADiB,CAAA5e,EAAA,IACjB,CAAgB4e,CAAAtW,YAAA,CAAyB,KACrC,EAAAtH,EAAJ,EACI,CAAAA,EAAA0N,KAAA,CAAcoP,EAAA,EAAd,CAAmCjB,EAAA,CAAAA,CAAA,CAAnC,CAEJkC,EAAA,CAAW,CAAA,CACN,EAAAle,EAAL,EAAe,CAAAnI,OAAA,CAAY,SAAZ,CAXK,CAaxB,CAAAyH,MAAA6e,SAAA,CAAsBF,CACtB,OAAOC,EAhBX,CAsDJ,IAAAtB,GAAkC,EAAlC,CACAa,GAAkC,EADlC,CAGAvC,GAAmB,CAAC,OAAD,CAAU,OAAV,CAyEftc;QAzBEwf,GAyBS,CAACtF,CAAD,CACX,CAEI,IAAIuF,EAAQ,CAACvF,CAAA,MAATuF,EA1jIIC,IAskIR,GAAA,KAAA,CAAA,IAAA,CAAMxF,CAAN,CAPqBC,GAOrB,CAEA,KAAAsF,GAAA,CAAaA,CACb,KAAAE,GAAA,CAAiB,CAACzF,CAAA,UAAlB,EAA2C,CAE3C,KAAA0F,GAAA,CAAgBC,EAAAtW,KAAA,CAAkB,IAAlB,CAChB,KAAAuW,EAAA,CAAmBC,CAAAxW,KAAA,CAAuB,IAAvB,CAGnB,KAAAyW,GAAA,CAAe,IAGf,KAAAC,GAAA,CAAa,EAEb,KAAAvf,MAAA6e,SAAA,CAAsB,CAAA,CA5B1B,CA1BwB1Q,EAAAoL,CAAtBuF,EAAsBvF,CAAAA,EAAAA,CA8ExB,EAAA,CAzxQJ,EAAAiG,UAyxQI/Z;CAAA4I,MAAA,CAAAA,QAAK,EACL,CACI,IAAA9V,OAAA,CAAY,QAAZ,CAAuB,IAAAwmB,GAAvB,CACI,KAAA/e,MAAA+Q,EAAJ,EAAwBK,CAAA,CAAAA,IAAA,CACxBqO,KAkBAC,GAAA,CAlBAD,IAkBcE,GAAd,CAlBAF,IAiBAG,EACA,CAlBAH,IAiBcI,EACd,CAD2B,CAjB3BJ,KAmBAhN,EAAA,CAnBAgN,IAmBcK,GAAd,CAnBAL,IAmB4BR,GAnB5BQ,KAqBAM,EAAA,CArBAN,IAoBAO,EACA,CADe,EApBfP,KAuBAQ,EAAA,CAvBAR,IAsBAS,EACA,CADe,CAtBfT,KAyBAU,GAAA,CAAc,CAAC,CAAD,CAAI,CAAJ,CAzBdV,KA0BAW,GAAA,CAAc,CAAC,CAAD,CAAI,CAAJ,CA1BdX,KA2BAY,GAAA,CAAc,CAAC,CAAD,CAAI,CAAJ,CA3BdZ,KA4BAa,GAAA,CAAc,CAAC,CAAD,CAAI,CAAJ,CA5Bdb,KAqCAc,GAAA,CArCAd,IAqCgBhN,EArChBgN,KA0CAe,EAAA,CAAe,CA1Cff,KAwDAxN,EAAA,CAxDAwN,IAwDgBgB,GAxDhBhB,KAyDA1N,EAAA,CAzDA0N,IAyDiBiB,GAzDjBjB,KAyhBAH,GAAA,CAAe,IAxhBfvD,GAAA,CAAAA,IAAA,CACAtb,KA7gJAT,MAAAO,MAAA,CAAmB,CAAA,CA8gJnB8N,GAAAA,UAAAA,MAAAA,KAAAA,CAAAA,IAAAA,CANJ,CAqHA5I,EAAA+W,GAAA,CAAAA,QAAW,EACX,CACI,MAAO,EADX,CAUA/W;CAAAgK,KAAA,CAAAA,QAAI,EACJ,CACI,IAAIC,EAAQ,IAAIC,CAAJ,CAAU,IAAV,CACZD,EAAAE,IAAA,CAAU,CAAV,CAAa,CACT,IAAAgQ,EADS,CAET,IAAAC,EAFS,CAGT,IAAAH,GAHS,CAIT,IAAAC,GAJS,CAKT,IAAAlN,EALS,CAMT,IAAAuN,EANS,CAOT,IAAAD,EAPS,CAQT,IAAAG,EARS,CAST,IAAAM,EATS,CAUT,IAAAV,GAVS,CAWT,IAAAS,GAXS,CAYT,IAAAtB,GAZS,CAAb,CAcAvP,EAAAE,IAAA,CAAU,CAAV,CAAa,EAAb,CACAF,EAAAE,IAAA,CAAU,CAAV,CAAa,CAAC,IAAAoL,EAAD,CAAoB2F,IAj3B1B9G,GAi3BM,CAAqC,IAAA7Z,MAAAsa,GAArC,CAAb,CACA5K,EAAAE,IAAA,CAAU,CAAV,CAAagR,EAAA,CAAAA,IAAA,CAAb,CACAlR,EAAAE,IAAA,CAAU,CAAV,CAAaiO,EAAA,CAAAA,IAAA,CAAb,CACA,OAAOnO,EAAAzV,KAAA,EApBX,CA8BAwL;CAAA+J,QAAA,CAAAA,QAAO,CAACvV,CAAD,CACP,CAkBQ,IAAA,EAAAA,CAAA,CAAK,CAAL,CW76QVzM,GAAA,EAGAJ,GAAA,EAAAI,GAAA,EAAA,KAAI,EAAqC,CAAD,CAAW,MAAA,SAAX,CACxC,EAAA,CAAO,CAAA,CAAmB,CAAA,KAAA,CAAsB,CAAtB,CAAnB,CACHD,EAAA,CAA6C,CAA7C,CX45QM,KAAAqyB,EADJ,CAAA,CAAA,KAAA,EAAA,MAEI,KAAAC,EAFJ,CAAA,CAAA,KAAA,EAAA,MAGI,KAAAH,GAHJ,CAAA,CAAA,KAAA,EAAA,MAII,KAAAC,GAJJ,CAAA,CAAA,KAAA,EAAA,MAKI,KAAAlN,EALJ,CAAA,CAAA,KAAA,EAAA,MAMI,KAAAuN,EANJ,CAAA,CAAA,KAAA,EAAA,MAOI,KAAAD,EAPJ,CAAA,CAAA,KAAA,EAAA,MAQI,KAAAG,EARJ,CAAA,CAAA,KAAA,EAAA,MASI,KAAAM,EATJ,CAAA,CAAA,KAAA,EAAA,MAUI,KAAAV,GAVJ,CAAA,CAAA,KAAA,EAAA,MAWI,KAAAS,GAXJ,CAAA,CAAA,KAAA,EAAA,MAYI,KAAAtB,GAZJ,CAAA,CAAA,KAAA,EAAA,MAeI7tB,EAAAA,CAAI6I,CAAA,CAAK,CAAL,CACR,KAAA+gB,EAAA,CAAoB5pB,CAAA,CAAE,CAAF,CACpB2rB,GAAA,CAAAA,IAAA,CAAc3rB,CAAA,CAAE,CAAF,CAAd,CACA,KAAA4O,MAAAsa,GAAA,CAAuBlpB,CAAA,CAAE,CAAF,CAEN,EAAA,CAAA6I,CAAA,CAAK,CAAL,CA+XjB,KAASrI,CAAT,CAAaivB,CAAAprB,OAAb,CAAkC,CAAlC,CAA0C,CAA1C,EAAqC7D,CAArC,CAA6CA,CAAA,EAA7C,CAAkD,CAC9C,IAAIkvB,CAxDZ,EAAA,CAAA,CACI,IAASlvB,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAzUAmvB,IAyUoBxB,GAAA9pB,OAApB,CAAuC7D,CAAA,EAAvC,CAA4C,CACxC,IAAIkvB,EA1URC,IA0UcxB,GAAA,CAAW3tB,CAAX,CACV;GAAIkvB,CAAAE,GAAJ,GAqDuBH,CAAAG,CAAYpvB,CAAZovB,CArDvB,CAA2B,CAAA,CAAA,CAAOF,CAAP,OAAA,CAAA,CAFa,CAI5C,CAAA,CAAO,IALX,CA0DYA,CAAJ,GACIA,CAAAG,KACA,CApYRF,IAmYmBzB,GACX,CApYRyB,IAoYQzB,GAAA,CAAewB,CAFnB,CAH8C,CA9X/B,CAAA,CAAA7mB,CAAA,CAAK,CAAL,CAljBnB,KAASrI,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAkjBAsvB,IAljBoBrG,EAAAplB,OAApB,EAA2C7D,CAA3C,CAA+CksB,CAAAroB,OAA/C,CAAoE7D,CAAA,EAApE,CAkjBAsvB,IAjjBgBrG,EAAA1d,CAAavL,CAAbuL,CACZ,CAAM,CAAN,CAAA,CAAW2gB,CAAA,CAAalsB,CAAb,CAijBf,OAAO,CAAA,CA3BX,CAmDAuvB,SAAA,GAAK,CAALA,CAAK,CAACzuB,CAAD,CACL,CACI,CAAAwtB,EAAA,CAAc,CAAAA,EAAd,CAA2B,OAA3B,CAAsDxtB,CAAtD,CAvrIW0uB,MAwrIX,EAAAlB,EAAA,EAAextB,CAAf,CAjsIY0uB,IAksIN1uB,EAAN,CAjsIY0uB,IAisIZ,CAGU,CAAAlB,EAHV,CAlsIYkB,IAksIZ,GAG4C,CAAAlB,EAH5C,EAjsIYkB,IAisIZ,EACI,CAAAlB,EADJ,EACkB,KAJtB,CA8GAmB,QAAA,GAAS,CAATA,CAAS,CAAC3I,CAAD,CACT,CACI,IAAI4I,EAAK,CAAA7O,EACT,EAAAA,EAAA,EAAc6O,CAAd,CAAmB5I,CAAnB,EAA0B6I,EAC1B,OAAOD,EAHX,CA2BAE,QAAA,GAAK,CAALA,CAAK,CACL,CACI,MAAqB,EAAd,EAAA,CAAAxB,EAAA,CAAiB,CAAAA,EAAjB,CAAgC,CAAAH,EAAD,CAj3I1BtV,OAi3I0B,CAAqC,CAAAuV,GAArC,CAAmD,CAAArN,EAD7F,CAmCAzB,QAAA,EAAK,CAALA,CAAK,CAACgE,CAAD,CACL,CACI,CAAA6K,EAAA,CAAa,CACb,EAAAG,EAAA,CAAc,EACd,EAAAvN,EAAA,CAAauC,CAAb,CAAoBuM,EAHxB,CAkKAX,QAAA,GAAQ,CAARA,CAAQ,CACR,CACI,IAAIC,EAAc,EAElB,KADIC,CACJ,CADU,CAAAxB,GACV,CAAOwB,CAAP,CAAA,CACID,CAAAhmB,KAAA,CAAiBimB,CAAAE,GAAjB,CACA,CAAAF,CAAA,CAAMA,CAAAG,KAEV,OAAOJ,EAPX;AAwGApb,CAAAgb,GAAA,CAAAA,QAAoB,CAACzL,CAAD,CACpB,CACWpU,IAAAA,EAAAA,IAAAA,EAAiB,EAAA,CAAA,IAAA2f,GAAA,CAAgBvL,CAAxC,OAh2FO,EAAAhB,EAAA,EADOgB,CACP,CADc,CAAA3C,EACd,IADiC,CAAAsB,EACjC,CAAA1B,EAAA,CAFG+C,CAEH,CApXYgB,KAoXZ,CAAsChB,CAAtC,CA+1FX,CAcAvP,EAAAib,GAAA,CAAAA,QAAmB,CAAC1L,CAAD,CAAO/a,CAAP,CACnB,CACI2G,IAAAA,EAAAA,IAAAA,EAAiB,EAAA,CAAA,IAAA2f,GAAA,CAAgBvL,CAj2FjC,EAAAhB,EAAA,EADcgB,CACd,CADqB,CAAA3C,EACrB,IADwC,CAAAsB,EACxC,CAAA5B,EAAA,CAi2FuC9X,CAj2FvC,CAFU+a,CAEV,CAlYmBgB,KAkYnB,CAA0ChB,CAA1C,CAk2FA,OAAO/a,EAFX,CAkCAwL;CAAAiZ,GAAA,CAAArN,QAAO,CAACoQ,CAAD,CACP,CAWI,IAAAzhB,MAAA6e,SAAA,CAAsB,CAAA,CAMtB,KAAI6C,EAA2B,IAAAhhB,EAAb,CAAyBihB,EAAA,CAAA,IAAAjhB,EAAA,CAAA,CAA0B,CAA1B,CAA+B,IAAAV,MAAAqa,GAAA,CAAsB,EAAtB,CAA0B,CAAlF,CAAwF,CAA1G,CAQIuH,EAAgBH,CAAF,CAAqB,IAAAzhB,MAAAqa,GAAA,CAAqB,CAArB,CAAyB,CAA9C,CAAgB,EAClC,KAAAra,MAAAqa,GAAA,CAAsB,CAAA,CAOtB,KAAAa,EAAA,CAAoB,IAAAC,EAApB,CAAuCsG,CAKvC,KAAAjB,EAAA,CAAgB,IAAAA,EAAhB,CAA+B,EAA/B,EAA0DkB,CAAA,CAruJ9CG,CAquJ8C,CAAqC,CAA/F,CAEA,GAAG,CACC,GAAI,IAAArB,EAAJ,CAAkB,CAKd,GAAiB,IAAAA,EAAjB,CA7uJIqB,CA6uJJ,CAAwD,CACpD,GAAIC,EAAA,CAAA,IAAAphB,EAAA,CAA0B8gB,EAAA,CAAAA,IAAA,CAA1B,CAAwCI,CAAxC,CAAJ,CAA0D,CACtDxQ,CAAA,CAAAA,IAAA,CACA,MAFsD,CAIrD,EAAEsQ,CAAP,GAAoB,IAAAlB,EAApB,EAAoC,EAApC,CACKoB,EAAL,EAAkBA,CAAA,EANkC,CAgBnD,GAAA,CAAA,CAAA,IAAA,EAAA,CAAA,EAAA,CACG,IApLZpB,EAAJ,CA5kJYqB,CA4kJZ,CAoLgB,IApKPvC,GAhBT,GAoLgB,IAnKRkB,EAjBR,EAiBwB,EAjBxB,EAoLgB,IAhKPA,EApBT,CA7kJYqB,CA6kJZ,EAoLgB,IA3JZrB,EAAA,EAEJ,CAAA,CAAA,CA7BiBuB,CAAAA,CAqLT,IAAK,CAAL,CACgC,CACxB,GAAK,IAAAvB,EAAL,CA/vJJqB,CA+vJI,EAA8CC,EAAA,CAAA,IAAAphB,EAAA,CAA0B8gB,EAAA,CAAAA,IAAA,CAA1B,CAAwCI,CAAxC,CAA9C,CAAoG,CAChGxQ,CAAA,CAAAA,IAAA,CACA,MAFgG,CAWpG,GAAkB,CAAlB,CAAIwQ,CAAJ,CAAqB,KAZG,CAtBlB,CAuClB,IAAApB,EAAA,EA7wJQqB,EA+wJCG,KA5fRnC,EAAL,CAxyIYtV,OAwyIZ,CA4fayX,IA3fTnC,EADJ,CA4famC,IA3fItC,GADjB,CA4fasC,IA3fiB/P,EAAA,CA2fjB+P,IA3f+BpC,EAAd,CAD9B,CAEyB,CAAlB,EA0fMoC,IA1fFhC,EAAJ,EA0fMgC,IAzfTnC,EACA,CAwfSmC,IAzfIrC,GACb,CAwfSqC,IAzfiB/P,EAAA,CAyfjB+P,IAzf+BhC,EAAd,CAC1B,CAwfSgC,IAxfThC,EAAA;AAAc,EAFX,GA0fMgC,IAtfTnC,EACA,CAqfSmC,IAtfIrC,GACb,CAqfSqC,IAtfiB/P,EAAA,CAsfjB+P,IAtf+BlC,GAAd,CAsfjBkC,IAtf6CvP,EAA5B,CAC1B,CAqfSuP,IArfTvP,EAAA,EAqfSuP,IArfKvP,EAAd,CAA2B,CAA3B,EAAgC8O,EAL7B,CA0fMS,KA9ebnC,EAAA,EA/yIYtV,OA6xJCyX,KAjebpC,EAAA,CAieaoC,IAjeAnC,EAAb,CA9zIYtV,MAg0IZ,IADI5X,CACJ,CA+daqvB,IAheJnC,EACT,EAp0IYtV,EAo0IZ,CAn0IYA,EAm0IZ,CA+dayX,IA/dNpC,EAAA,CA+dMoC,IA/dQpC,EAAd,EA+dMoC,IA/dsBtC,GAA5B,CA+dMsC,IA/dmC/P,EAAA,CAActf,CAAd,CAAzC,EAA8DsvB,EAErE,EAAA,CA6daD,IA7dLnC,EAAD,CAv0IKtV,OAu0IL,CAAsC,EAAtC,CA6dMyX,IA7dsCrC,GAA5C,CAAyDuC,EAAzD,CAA+E,CA8dxE,EAAV,EAAIC,CAAJ,EACI,IAAAjD,GAAA,CAAciD,CAAd,CAMJ,KAAAhH,EAAA,EAlDD,CAAH,MAoD4B,CApD5B,CAoDS,IAAAA,EApDT,CAsDA,OAAQ,KAAAnb,MAAA6e,SAAA,CAAqB,IAAA3D,EAArB,CAAyC,IAAAC,EAAzC,CAAqF,CAAA,CAAxB,GAAA,IAAAnb,MAAA6e,SAAA,CAAgC,EAAhC,CAAoC,CA9F7G,CAyHJvL,GAAA,CAfIZ,QAAW,EACX,CAEI,IADA,IAAI0P,EAAS9f,CAAA,CAA6BsQ,QAA7B,CAAuCxQ,CAAvC,CAAuD,KAAvD,CAAb,CACSigB,EAAO,CAAhB,CAAmBA,CAAnB,CAA0BD,CAAA3sB,OAA1B,CAAyC4sB,CAAA,EAAzC,CAAiD,CAC7C,IAAIC,EAAOF,CAAA,CAAOC,CAAP,CAAX,CACI7I,EAAWvW,EAAA,CAA4Bqf,CAA5B,CACX3hB,EAAAA,CAAM,IAAIme,EAAJ,CAAkBtF,CAAlB,CACVxG,GAAA,CAAgCrS,CAAhC,CAAqC2hB,CAArC,CAJ6C,CAFrD,CAcJ,CA0GeC,SAAA,GAAQ,CAACJ,CAAD,CACvB,CAMIK,EAAA,CAAkBL,CAAlB,EAAwB,CAAxB,CAAA5c,KAAA,CAAgC,IAAhC,CAAsC4c,CAAtC,CAA0CA,CAA1C,CA97JgB5X,EA87JhB,CANJ,CAmCckY,QAAA,EAAQ,CAACN,CAAD,CACtB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ;AA0HcO,QAAA,GAAQ,EACtB,CACI,IAAIvQ,EAAM,CAAV,CACIzf,EAAI,IAAAuf,EAAA,CAAc,IAAA2N,EAAd,CADR,CAEIztB,EAAKO,CAALP,CAASwwB,EAATxwB,CA9lKYoY,EA4lKhB,CAGIjY,EAAKI,CAALJ,EA9lKYiY,EA8lKZjY,CA7lKYiY,EA8lKhBpY,EAAA,EAAKG,CACG,EAAR,CAAIH,CAAJ,GACIggB,CAAA,EAEA,CADAhgB,CACA,CADI,EACJ,CADSG,CACT,CAAQ,CAAR,CAAIH,CAAJ,GAAWA,CAAX,CAAe,GAAf,CAAqBG,CAArB,CAHJ,CAaAI,EAAA,CAAKP,CAAL,CAASwwB,EAAT,EAAkCrwB,CAAlC,EA7mKgBiY,EA6mKhB,GAAgE7X,CAAhE,CAhmKgB6X,QAgmKhB,CACI4H,EAAJ,GAASzf,CAAT,EAAcA,CAAd,CAAkByf,CAAlB,EAAyBK,CAAzB,CACA,KAAAT,EAAA,CAAe,IAAA6N,EAAf,CAA2BltB,CAA3B,CArBJ,CA+EckwB,QAAA,GAAQ,CAACT,CAAD,CAAKU,CAAL,CACtB,CAKQnwB,CAAAA,CAAI,IAAAuf,EAAA,CAAc,IAAA2N,EAAd,CACR,IAAiB,CAAjB,CAAI,IAAAG,EAAJ,CACI,IAAAA,EACA,CADartB,CACb,CAAA,IAAAmtB,EAAA,CAAa,IAAAD,EAAb,CA7qKYrV,OA2qKhB,KAAA,CAKA,IAAIpY,EAAK,IAAA4tB,EAAL5tB,CAAkBwwB,EAAlBxwB,CAtrKYoY,EAsrKhB,CACIjY,EAAK,IAAAytB,EAALztB,EAtrKYiY,EAsrKZjY,CArrKYiY,EA4rKZ7X,EAAA,CANQ,EAAZ,CAAIP,CAAJ,CAAQG,CAAR,EAMUI,CANV,EAMeP,CANf,EAMsB,CANtB,EAM2BG,CAN3B,EAMgC,CANhC,IAMwC,CANxC,CAaQuB,IAAAE,MAAA,CAAWrB,CAAX,CAAemB,IAAAC,IAAA,CAAS,CAAT,CAAY3B,CAAZ,CAAf,CAbR,CAayC0B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAEzC,KAAAyf,EAAA,CAAe8Q,CAAf,CAAmBnwB,CAAnB,CACA,KAAAwtB,EAAA,EAAc,KACd,KAAAH,EAAA,CAAc,EAxBd,CANJ;AAuFc+C,QAAA,GAAQ,CAACX,CAAD,CAAKU,CAAL,CACtB,CAKQnwB,CAAAA,CAAI,IAAAuf,EAAA,CAAc,IAAA2N,EAAd,CACR,IAAiB,CAAjB,CAAI,IAAAG,EAAJ,CACI,IAAAA,EACA,CADartB,CACb,CAAA,IAAAmtB,EAAA,CAAa,IAAAD,EAAb,CArwKYrV,OAmwKhB,KAAA,CAKA,IAAIpY,EAAK,IAAA4tB,EAAL5tB,CAAkBwwB,EAAlBxwB,CA9wKYoY,EA8wKhB,CACIjY,EAAK,IAAAytB,EAALztB,EA9wKYiY,EA8wKZjY,CA7wKYiY,EAmxKZlZ,EAAAA,CAAM,IAAA4gB,EAAA,CAAc4Q,CAAd,CAANxxB,CAA0BwC,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAA1BjB,CAA4CwC,IAAAC,IAAA,CAAS,CAAT,CAAY3B,CAAZ,CAA5Cd,CAA8DmhB,CAClE9f,EAAA,CAAKA,CAAL,CAAUA,CAAV,CAAcmB,IAAAC,IAAA,CAAS,CAAT,CAAY3B,CAAZ,CAAgBG,CAAhB,CAAd,CAAqCjB,CAArC,CAA0CqB,CAA1C,CAA8CmB,IAAAC,IAAA,CAAS,CAAT,CAAY3B,CAAZ,CAC9C,KAAA4f,EAAA,CAAe,IAAA6N,EAAf,CAA2BltB,CAA3B,CACA,KAAAwtB,EAAA,EAAc,KACd,KAAAH,EAAA,CAAc,EAhBd,CANJ,CAyaegD,QAAA,GAAQ,CAACZ,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAAnB,CADJ,CAsBgBoD,QAAA,GAAQ,CAACb,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB,IAAAjD,EAAnB,CADJ,CAoBgBqD,QAAA,GAAQ,CAACd,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA3N,EAAA,CAAc4Q,CAAd,CAA3B,CADJ,CAq/FeK,QAAA,GAAQ,CAACf,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB,CAAnB,CADJ,CAygBgBM,QAAA,GAAQ,CAAChB,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBO,CAAnB,CAAqC,IAAAnR,EAAA,CAAc4Q,CAAd,CAArC,CADJ,CAgUeQ,QAAA,GAAQ,CAAClB,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBO,CAAnB,CADJ;AAkDcE,QAAA,GAAQ,CAACnB,CAAD,CAAKU,CAAL,CACtB,CACI,IAAIU,EAAM,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CAAV,CACI4D,EAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBY,EAAA,CAAYtB,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAAnB,EAAgDA,CAAhD,EAAuDA,CAAvD,CAA6DG,CAA7D,GAHJ,CAuBeC,QAAA,GAAQ,CAACxB,CAAD,CAAKU,CAAL,CACvB,CACI,IAAIW,EAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBY,EAAA,CAAYtB,CAAZ,CAAgBqB,CAAhB,CAAqB,CAArB,CAAnB,CAFJ,CAmBeI,QAAA,GAAQ,CAACzB,CAAD,CAAKU,CAAL,CACvB,CACQU,CAAAA,CAAM,IAAAtR,EAAA,CAAc4Q,CAAd,CACV,KAAIW,EAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CACV,KAAA7N,EAAA,CAAe,IAAA6N,EAAf,CAA2B6D,EAAA,CAAYtB,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAA3B,EAAwDA,CAAxD,EAA+DA,CAA/D,CAAqEG,CAArE,GAHJ,CAsBeG,QAAA,GAAQ,CAAC1B,CAAD,CAAKU,CAAL,CACvB,CACI,IAAIW,EAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CAAV,CACsB4D,EAAAA,CA68DtB,IA78DkBrB,CA68DlB,EAAU,GAAV,CAEI,OADAqB,CACOrB,EADCqB,CACDrB,CADOuB,CACPvB,CAAAA,CAAP,EACA,KAAK,GAAL,CACIqB,CAAA,EAAOE,CACP,MACJ,MAAK,GAAL,CACIF,CAAA,EAp9DmBA,CAo9DX,CAAMM,CAAN,CAAsBJ,CAAtB,CAAwC,CALpD,CASJ,CAAA,CAAOF,CAv9DP,KAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B4D,CAA3B,CACIX,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAJZ,CAsBcO,QAAA,GAAQ,CAAC5B,CAAD,CAAKU,CAAL,CACtB,CACI,IAAIU,GAAO,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CAAP2D,CAAmCG,CAAnCH,EAAsDS,CAA1D,CACIR,EAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBY,EAAA,CAAYtB,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAAnB,CAA+CA,CAA/C,CAHJ;AAqBeU,QAAA,GAAQ,CAAC9B,CAAD,CAAKU,CAAL,CACvB,CACI,IAAIU,EAAM,IAAA3D,EAAN2D,CAAmBS,CAAvB,CACIR,EAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBY,EAAA,CAAYtB,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAAnB,CAA+CA,CAA/C,CAHJ,CAqBeW,QAAA,GAAQ,CAAC/B,CAAD,CAAKU,CAAL,CACvB,CACQU,CAAAA,EAAO,IAAAtR,EAAA,CAAc4Q,CAAd,CAAPU,CAA2BG,CAA3BH,EAA8CS,CAClD,KAAIR,EAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CACV,KAAA7N,EAAA,CAAe,IAAA6N,EAAf,CAA2B6D,EAAA,CAAYtB,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAA3B,CAAuDA,CAAvD,CAHJ,CAqBeY,QAAA,GAAQ,CAAChC,CAAD,CAAKU,CAAL,CACvB,CACI,IAAIW,EAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CAAV,CACI2D,GAAOC,CAAPD,CAAaG,CAAbH,EAAgCS,CACpCR,EAAA,CAAMC,EAAA,CAAYtB,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAAN,CAAkCA,CAClC,KAAAxR,EAAA,CAAe,IAAA6N,EAAf,CAA2B4D,CAA3B,CACIX,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CALZ,CAuBcY,QAAA,GAAQ,CAACjC,CAAD,CAAKU,CAAL,CACtB,CACI,IAAIU,EAAM,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CAAN2D,CAAkCG,CAAtC,CACIF,EAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBwB,EAAA,CAAYlC,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAAnB,CAA+CA,CAA/C,CAHJ,CAqBee,QAAA,GAAQ,CAACnC,CAAD,CAAKU,CAAL,CACvB,CACI,IAAIW,EAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBwB,EAAA,CAAYlC,CAAZ,CAAgBqB,CAAhB,CAAqB,IAAA5D,EAArB,CAAnB,CAAsD,IAAAA,EAAtD,CAFJ,CAoBe2E,QAAA,GAAQ,CAACpC,CAAD,CAAKU,CAAL,CACvB,CACQU,CAAAA,CAAM,IAAAtR,EAAA,CAAc4Q,CAAd,CAANU,CAA0BG,CAC9B,KAAIF,EAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CACV,KAAA7N,EAAA,CAAe,IAAA6N,EAAf,CAA2ByE,EAAA,CAAYlC,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAA3B,CAAuDA,CAAvD,CAHJ;AAuBeiB,QAAA,GAAQ,CAACrC,CAAD,CAAKU,CAAL,CACvB,CACI,IAAIW,EAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CAAV,CACsB4D,EAAAA,CAkuDtB,IAluDkBrB,CAkuDlB,EAAU,GAAV,CAEI,OADAqB,CACOrB,EADAuB,CACAvB,CAAAA,CAAP,EACA,KAAK,GAAL,CACIqB,CAAA,EAAQE,CAAR,CAA0BM,CAC1B,MACJ,MAAK,GAAL,CACIR,CAAA,EAzuDmBA,CAyuDX,CAAMiB,EAAN,CAAwBf,CAAxB,CAA0CM,CAA1C,CAA8D,CAL1E,CASJ,CAAA,CAAOR,CA5uDP,KAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B4D,CAA3B,CACIX,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAJZ,CAqBckB,QAAA,GAAQ,CAACvC,CAAD,CAAKU,CAAL,CACtB,CACI,IAAIU,EAAO,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CAAP2D,CAAmCS,CAAnCT,CAAqD,CAAzD,CACIC,EAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBwB,EAAA,CAAYlC,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAAnB,CAA+CA,CAA/C,CAHJ,CAsBeoB,QAAA,GAAQ,CAACxC,CAAD,CAAKU,CAAL,CACvB,CACI,IAAIW,EAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBwB,EAAA,CAAYlC,CAAZ,CAAgBqB,CAAhB,CAAqB,CAArB,CAAnB,CAFJ,CAmBeoB,QAAA,GAAQ,CAACzC,CAAD,CAAKU,CAAL,CACvB,CACQU,CAAAA,CAAO,IAAAtR,EAAA,CAAc4Q,CAAd,CAAPU,CAA2BS,CAA3BT,CAA6C,CACjD,KAAIC,EAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CACV,KAAA7N,EAAA,CAAe,IAAA6N,EAAf,CAA2ByE,EAAA,CAAYlC,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAA3B,CAAuDA,CAAvD,CAHJ,CAoBesB,QAAA,GAAQ,CAAC1C,CAAD,CAAKU,CAAL,CACvB,CACI,IAAIW,EAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CAAV,CACI2D,EAAOC,CAAPD,CAAaS,CAAbT,CAA+B,CACnCC,EAAA,CAAMa,EAAA,CAAYlC,CAAZ,CAAgBqB,CAAhB,CAAqBD,CAArB,CAAN,CAAkCA,CAClC,KAAAxR,EAAA,CAAe,IAAA6N,EAAf,CAA2B4D,CAA3B,CACIX,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CALZ,CAs6BasB,QAAA,EAAQ,CAAC3C,CAAD,CACrB,CACI4C,EAAA,CAAiB5C,CAAjB,CAAsB,CAAtB,CAAA5c,KAAA,CAA8B,IAA9B,CAAoC4c,CAApC,CAAyCA,CAAzC,EAA+C,CAA/C,CAAoD,GAApD,CADJ;AAac6C,QAAA,GAAQ,EACtB,EAYeC,QAAA,GAAQ,EACvB,EAUoBC,QAAA,EAAQ,CAAC/C,CAAD,CAC5B,CACI,IAAAlc,EAAA,CAAa,oBAAb,CAAoC2P,EAAA,CAAUuM,CAAV,CAApC,CACAd,GAAA,CAAAA,IAAA,CAAgB,EAAhB,CACAjQ,EAAA,CAAAA,IAAA,CAHJ,CAec+T,QAAA,GAAQ,CAAC5B,CAAD,CACtB,CACQA,CAAJ,CAAUO,CAAV,GACQP,CAAJ,EAAW6B,CAAX,CACI7B,CADJ,CACU8B,EADV,CAC4B9B,CAD5B,CAGI,IAAArD,EAHJ,EAGmB,MAJvB,CAOA,OAAOqD,EARX,CAqBc+B,QAAA,EAAQ,CAAC9B,CAAD,CAAMD,CAAN,CACtB,CAKI,IAAIgC,GAAO/B,CAAP+B,CAAahC,CAAbgC,EAAoB/S,CACxBgT,GAAAjgB,KAAA,CAAuB,IAAvB,CAA6Bie,CAA7B,CAAkCD,CAAlC,CAAuCgC,CAAvC,CACA,OAAOA,EAPX;AAqBcE,QAAA,GAAQ,CAAClC,CAAD,CAAMC,CAAN,CAAWkC,CAAX,CACtB,CAAA,IACQC,EAAQ,CAAA,CADhB,CACuBC,EAAQ,CAAA,CAM3B,IAAYtvB,IAAAA,EAAZ,GAAIovB,CAAJ,CAAuB,CACnB,GAAI,CAACnC,CAAL,CAEI,MADA,KAAArD,EACQ,EADM,MACN,CAAA,EAEZwF,EAAA,CAAOlC,CAAD,CAAOM,CAAP,CAAwBV,CAAxB,CAA0C,CAL7B,CAAvB,IASI,KADcsC,CAAAG,CAAMT,CAANS,CAAuBH,CAAvBG,CAA6BR,EAA7BQ,CAA+CH,CAA/CG,EAAsDrC,CAAA,CAAK,CAAL,CAAS,CAA/DqC,CACd,IAFctC,CAAAuC,CAAMV,CAANU,CAAuBvC,CAAvBuC,CAA6BT,EAA7BS,CAA+CvC,CAE7D,EAEI,MADA,KAAArD,EACQ,EADM,MACN,CAAA,EAoRhB,KAAI6F,EA7QgCL,CA6QhCK,CA7QgCL,CA6QhCK,CAAqBX,CAUzB5B,EAAA,CAvR+BA,CAuR/B,CAAa4B,CAAb,EAvRoCM,CAuRpC,CAAwC,CAAxC,EAA6CN,CAtR7CM,EAAA,CAuRA,IAAAzF,EAvRA,CAuRa8F,CAvRb,CAuRoBlyB,IAAAE,MAAA,CAxRgB2xB,CAwRhB,CAAiB,CAAjB,CAlRhBnC,EAAJ,CAAUO,CAAV,GACIP,CACA,CADM/Q,CACN,CADyB+Q,CACzB,CAAAoC,CAAA,CAAQ,CAACA,CAFb,CAIID,EAAJ,CAAU5B,CAAV,GACQN,CAAJ,EACIkC,CACA,CADMtC,CACN,CADwBsC,CACxB,CAAAlC,CAAA,CAAMhR,CAAN,CAAyBgR,CAF7B,EAKQkC,CALR,GAKaA,CALb,CAKmBlT,CALnB,CAKsCkT,CALtC,CAOc,CAAdE,CAAc,CAAN,CAAA,CAAM,CAAAD,CAAA,CAAQ,CAACA,CAR3B,CAwBYxF,EAAAA,CAAAA,IAAAA,GA4rBZ6F,EAAA,CAAK,CAAL,CAAA,CA5rByBC,CA6rBzBD,EAAA,CAAK,CAAL,CAAA,CA7rB4BE,CAChB9F,EAAAA,CAAAA,IAAAA,GA2rBZ4F,EAAA,CAAK,CAAL,CAAA,CA3rByBC,CA4rBzBD,EAAA,CAAK,CAAL,CAAA,CA5rB4BE,CAChB7F,EAAAA,CAAAA,IAAAA,GA0rBZ2F,EAAA,CAAK,CAAL,CAAA,CA1rByBzC,CA2rBzByC,EAAA,CAAK,CAAL,CAAA,CA3rB8BE,CAClB5F,EAAAA,CAAAA,IAAAA,GAyrBZ0F,EAAA,CAAK,CAAL,CAAA,CAzrByBxC,CAEzB,KAwrBAwC,CAAA,CAAK,CAAL,CAxrBA,CAF8BN,CAE9B,CAA8C,CAA9C,CAAOS,EAAA,CAAW,IAAA7F,GAAX,CAAwB,IAAAD,GAAxB,CAAP,CAAA,CACI+F,EAAA,CAAW,IAAA/F,GAAX,CAAwB,IAAAA,GAAxB,CACA,CAAA+F,EAAA,CAAW,IAAAhG,GAAX,CAAwB,IAAAA,GAAxB,CAEJ,GAAG,CACC,GAA4C,CAA5C,EAAI+F,EAAA,CAAW,IAAA7F,GAAX,CAAwB,IAAAD,GAAxB,CAAJ,GACeC,CAEP,CAFOA,IAAAA,GAEP,CAFoBD,CAEpB,CAFoBA,IAAAA,GAEpB,CA6sBZ2F,CAAA,CAAK,CAAL,CA7sBY,EA6sBDK,CAAA,CAAK,CAAL,CA7sBC,CA8sBZL,CAAA,CAAK,CAAL,CA9sBY;AA8sBDK,CAAA,CAAK,CAAL,CA9sBC,CA+sBE,CA/sBF,CA+sBRL,CAAA,CAAK,CAAL,CA/sBQ,GAgtBRA,CAAA,CAAK,CAAL,CACA,EADWxT,CACX,CAAAwT,CAAA,CAAK,CAAL,CAAA,EAjtBQ,EADJI,EAAA,CAAW,IAAAjG,GAAX,CAAwB,IAAAC,GAAxB,CACI,CAAAkG,EAAA,CAAY,IAAAhG,GAAZ,CAHR,EAGkC,KAElCiG,GAAA,CAAW,IAAAlG,GAAX,CACAkG,GAAA,CAAW,IAAAnG,GAAX,CAPD,CAAH,MAQS,CAACkG,EAAA,CAAY,IAAAlG,GAAZ,CARV,CAaAoD,EAAA,CAAM,IAAArD,GAAA,CAAY,CAAZ,CACN,KAAAF,EAAA,CAAa,IAAAK,GAAA,CAAY,CAAZ,CAETqF,EAAJ,EAAanC,CAAb,GACIA,CADJ,CACUhR,CADV,CAC6BgR,CAD7B,CAIIoC,EAAJ,EAAa,IAAA3F,EAAb,GACI,IAAAA,EADJ,CACiBzN,CADjB,CACoC,IAAAyN,EADpC,CAIA,OAAOuD,EA5FX;AA6IcgD,QAAA,GAAQ,CAAChD,CAAD,CAAMD,CAAN,CAAWkD,CAAX,CAAsBC,CAAtB,CACtB,CAAA,IACQC,EAAKnD,CADb,CACkBoD,EAAKrD,CACfsD,EAAAA,CAAO,CAAA,CAMPF,EAAJ,CAAS7C,CAAT,GACQ4C,CADR,EA/oWY1H,IA+oWZ,EACqB,IAAAD,GADrB,EACuD4H,CADvD,EAC6DvB,CAD7D,IAEQuB,CACA,CADKnU,CACL,CADwBmU,CACxB,CAAAE,CAAA,CAAO,CAACA,CAHhB,CAOID,EAAJ,CAAS9C,CAAT,GACI8C,CACA,CADKpU,CACL,CADwBoU,CACxB,CAAAC,CAAA,CAAO,CAACA,CAFZ,CAKA,IAAIF,CAAJ,CAAS3C,CAAT,EAA6B4C,CAA7B,CAAkC5C,CAAlC,CAAoD,CAChDuB,CAAA,CAAMoB,CAAN,CAAWC,CACX,KAAAlB,EAAM,CAF0C,CAApD,IAIK,CACGoB,CAAAA,CAAQH,CAARG,CAAapD,CACbqD,EAAAA,CAAOlzB,IAAAE,MAAA,CAAW4yB,CAAX,CAAgB3C,CAAhB,CACPgD,EAAAA,CAAQJ,CAARI,CAAatD,CACbuD,EAAAA,CAAOpzB,IAAAE,MAAA,CAAW6yB,CAAX,CAAgB5C,CAAhB,CACX,KAAIkD,EAAOJ,CAAPI,CAAcF,CAAlB,CACIG,EAAQJ,CAARI,CAAeH,CAAfG,CAAuBtzB,IAAAE,MAAA,CAAWmzB,CAAX,CAAkBlD,CAAlB,CAC3B0B,EAAA,CAAM7xB,IAAAE,MAAA,CAAWozB,CAAX,CAAkBnD,CAAlB,CACNmD,EAAA,EAAQA,CAAR,CAAezD,CAAf,EAAmCoD,CAAnC,CAA0CG,CAC1C1B,EAAA,EAAQ4B,CAAR,CAAenD,CAAf,EAAoCkD,CAApC,CAA2CxD,CAA3C,GAA+DlR,CAC/DkT,EAAA,EAAO7xB,IAAAE,MAAA,CAAWozB,CAAX,CAAkBnD,CAAlB,CAAP,CAA8C+C,CAA9C,CAAqDE,CAVpD,CAaDJ,CAAJ,GACQtB,CAAJ,EACIG,CACA,CADMtC,CACN,CADwBsC,CACxB,CAAAH,CAAA,CAAM/S,CAAN,CAAyB+S,CAF7B,EAKQG,CALR,GAKaA,CALb,CAKmBlT,CALnB,CAKsCkT,CALtC,CADJ,CAU+BH,EAAAA,CAAAA,CAAKG,EAAAA,CAAAA,CA6IhCK,EAAAA,CAAOL,CAAPK,CAAcL,CAAdK,CAAoBX,CACxBM,EAAA,CAAc,CAAd,CAAQA,CAAR,CAAmBlT,CAAnB,CAAuC3e,IAAAE,MAAA,CAAWwxB,CAAX,CAAiBH,CAAjB,CACvCG,EAAA,CAAMQ,CAAN,CAAcR,CAAd,CAAoBH,CAENM,EACd,CADqBA,CACrB,CAD2BN,CAC3B,EAAeW,CAAf,GAUIR,CAVJ,CAUUG,CAVV,CAlJyCgB,EA+JzC,CAAe,CAAf,CAAsBnB,CAAtB,EAEIA,CAIJ,EAJWH,CAIX,EAJ8BM,CAI9B,EAJqCN,CAIrC,GAHI,IAAAlF,EAGJ,EA9tWgBkB,MA8tWhB,EADA,IAAAnB,EACA,CADasF,CACb,CAAA,CAAA,CAAOG,CANP,CA7JIe,EAAJ,GAMIlB,CA0BA,CA1BM,IAAAtF,EA0BN,CAzBI,CAACyG,CAyBL,GAJShB,CAIT,EAJgBH,CAIhB,CAJsBzB,CAItB,IAJ0C4B,CAI1C,EAJiDtC,CAIjD,EAJoEmC,CAIpE,EAJ2EzB,CAI3E,IAHQ,IAAA5D,EAGR,EA3lWYkB,MA2lWZ,EAAAsE,CAAA,CAAMH,CAhCV,CAkCA,OAAOG,EAnFX;AA+Fc0B,QAAA,GAAQ,CAAC7D,CAAD,CACtB,CACSA,CAAL,CAQQA,CAAJ,EAAW6B,CAAX,CACI,IAAAlF,EADJ,EACmB,MADnB,CAGIqD,CAHJ,CAGU8B,EAHV,CAG4B9B,CAXhC,CACI,IAAArD,EADJ,EACmB,KAanB,OAAOqD,EAfX,CA4Bc8D,QAAA,GAAQ,CAAC7D,CAAD,CAAMD,CAAN,CACtB,CAKI,IAAIgC,EAAO/B,CAAP+B,CAAahC,CACP,EAAV,CAAIgC,CAAJ,GAAaA,CAAb,EAAoB/S,CAApB,CAKAgT,GAAAjgB,KAAA,CAAuB,IAAvB,CAA6BggB,CAA7B,CAAkChC,CAAlC,CAAuCC,CAAvC,CACA,OAAO+B,EAZX,CAkGoB+B,QAAA,GAAQ,CAAC9D,CAAD,CAAMD,CAAN,CAAWgC,CAAX,CAC5B,CAOQgC,CAAAA,CAAQ1zB,IAAAE,MAAA,CAAWyvB,CAAX,CAAiBgE,EAAjB,CACRC,EAAAA,CAAQ5zB,IAAAE,MAAA,CAAWwvB,CAAX,CAAiBiE,EAAjB,CACRE,EAAAA,CAAQ7zB,IAAAE,MAAA,CAAWwxB,CAAX,CAAiBiC,EAAjB,CAgBZ,KAAIG,EAAaJ,CAAbI,EAAuBJ,CAAvBI,CAA+BF,CAA/BE,GAAyCF,CAAzCE,CAAiDD,CAAjDC,CAoBJ,KAAAzH,EAAA,CAAA,IAAAA,EAAA,EAnBcyH,CAmBC,CAnBW,CAmBX,CAtxWCvG,KAsxWD,CAA6B,CAA5C,GAlBcuG,CAkBoC,CAlBxB,CAkBwB,CArxWlCvG,KAqxWkC,CAA6B,CAA/E,GAAqF,CADnEmG,CACmE,CAD3DG,CAC2D,GADjDD,CACiD,CADzCC,CACyC,EAD/B,CAC+B,CAvxWrEtG,MAuxWqE,CAA+B,CAApH,CA7CJ,CAyDYwG,QAAA,EAAQ,CAACpE,CAAD,CAAMD,CAAN,CACpB,CAcI,QAAWC,CAAX,CAAiBqE,CAAjB,CAAkC,CAAlC,GAAyCtE,CAAzC,CAA+CsE,CAA/C,CAAgE,CAAhE,GAAsEA,CAAtE,GAA2FrE,CAA3F,CAAiGD,CAAjG,IAA0G,CAA1G,CAdJ,CA0BYuE,QAAA,EAAQ,CAACtE,CAAD,CAAMD,CAAN,CACpB,CACI,MAAOqE,EAAA,CAAUpE,CAAV,EA8FE,EA9FuBD,CA8FvB,CAASsE,CAAT,CAA0B,CAA1B,CA9FF,CA8FiC,EA9FjC,EA8FyCA,CA9FzC,EA8F6D,CA9FpCtE,CAAzB,GA8FsE,CA9FtE,EADX,CAaYwE,QAAA,GAAQ,CAACvE,CAAD,CAAMD,CAAN,CACpB,CACI,OAAQC,CAAA,CAAM4B,CAAN,CAAuB5B,CAAvB,CAA6BA,CAA7B,CAAmChR,CAA3C,GAAgE+Q,CAAA,CAAM6B,CAAN,CAAuB7B,CAAvB,CAA6BA,CAA7B,CAAmC/Q,CAAnG,CADJ;AAaYwV,QAAA,GAAQ,CAACxE,CAAD,CAAMD,CAAN,CACpB,CAcI,OAAS,GAAIC,CAAJ,CAAUqE,CAAV,CAA2B,CAA3B,GAAkCtE,CAAlC,CAAwCsE,CAAxC,CAAyD,CAAzD,EAAT,CAAwE,EAAxE,EAAgFA,CAAhF,EAAoG,EAAErE,CAAF,CAAQD,CAAR,CAApG,GAAqH,CAArH,CAdJ,CA0BY0E,QAAA,EAAQ,CAACzE,CAAD,CAAMD,CAAN,CACpB,CAcI,OAAWC,CAAX,CAAiBqE,CAAjB,CAAkC,CAAlC,CAAyCtE,CAAzC,CAA+CsE,CAA/C,CAAgE,CAAhE,EAAsEA,CAAtE,GAA2FrE,CAA3F,CAAiGD,CAAjG,IAA0G,CAA1G,CAdJ,CAmDa2E,QAAA,EAAQ,CAAC1E,CAAD,CACrB,CACI,MAAQA,EAAA,CAAM4B,CAAN,CAAuB5B,CAAvB,CAA6BA,CAA7B,CAAmChR,CAD/C,CAaY2V,QAAA,EAAQ,CAAC3E,CAAD,CAAMD,CAAN,CACpB,CAcI,QAAWC,CAAX,CAAiBqE,CAAjB,CAAkC,CAAlC,GAAyCtE,CAAzC,CAA+CsE,CAA/C,CAAgE,CAAhE,GAAsEA,CAAtE,GAA2FrE,CAA3F,CAAiGD,CAAjG,IAA0G,CAA1G,CAdJ,CA2Ba6E,QAAA,EAAQ,CAAC7E,CAAD,CACrB,CACI,OAASA,CAAT,CAAeS,CAAf,CAAiC,CAAjC,GAAwCT,CAAxC,CAA8CG,CAA9C,EAAiEM,CADrE,CAccK,QAAA,GAAQ,CAAClC,CAAD,CAAKqB,CAAL,CAAUD,CAAV,CACtB,CACI,OAAOpB,CAAP,CAAY,GAAZ,EACA,KAAK,CAAL,CACIqB,CAAA,EAAQA,CAAR,CAAcE,CACd,MACJ,MAAK,GAAL,CACIF,CAAA,CAAM,CACN,MACJ,MAAK,GAAL,CACIA,CAAA,CAAOE,CAAP,CAAyBM,CACzB,MACJ,MAAK,GAAL,CACIR,CAAA,CAAOD,CAAA,CAAMkB,EAAN,CAAwBf,CAAxB,CAA0CM,CAA1C,CAA8D,CAXzE,CAcA,MAAOR,EAfX,CAsDcC,QAAA,GAAQ,CAACtB,CAAD,CAAKqB,CAAL,CAAUD,CAAV,CACtB,CACI,OAAOpB,CAAP,CAAY,GAAZ,EACA,KAAK,CAAL,CACWqB,CAAP,EAAaE,CACb,MACJ,MAAK,GAAL,CACIF,CAAA,CAAM,CACN,MACJ,MAAK,GAAL,CACIA,CAAA,CAAME,CACN,MACJ,MAAK,GAAL,CACIF,CAAA,CAAOD,CAAA,CAAMO,CAAN,CAAsBJ,CAAtB,CAAwC,CAXnD,CAcA,MAAOF,EAfX;AAoDa4C,QAAA,GAAQ,CAACJ,CAAD,CAAOK,CAAP,CACrB,CACIL,CAAA,CAAK,CAAL,CAAA,EAAWK,CAAA,CAAK,CAAL,CACXL,EAAA,CAAK,CAAL,CAAA,EAAWK,CAAA,CAAK,CAAL,CACPL,EAAA,CAAK,CAAL,CAAJ,EAAexT,CAAf,GACIwT,CAAA,CAAK,CAAL,CACA,EADWxT,CACX,CAAAwT,CAAA,CAAK,CAAL,CAAA,EAFJ,CAHJ,CAkBaG,QAAA,GAAQ,CAACH,CAAD,CAAOK,CAAP,CACrB,CACI,IAAIgC,EAASrC,CAAA,CAAK,CAAL,CAATqC,CAAmBhC,CAAA,CAAK,CAAL,CAClBgC,EAAL,GAAaA,CAAb,CAAsBrC,CAAA,CAAK,CAAL,CAAtB,CAAgCK,CAAA,CAAK,CAAL,CAAhC,CACA,OAAOgC,EAHX,CA4Ba9B,QAAA,GAAQ,CAACP,CAAD,CACrB,CACQA,CAAA,CAAK,CAAL,CAAJ,CAAc,CAAd,GACIA,CAAA,CAAK,CAAL,CADJ,EACexT,CADf,CAGAwT,EAAA,CAAK,CAAL,CAAA,CAAUnyB,IAAAE,MAAA,CAAWiyB,CAAA,CAAK,CAAL,CAAX,CAAqB,CAArB,CACVA,EAAA,CAAK,CAAL,CAAA,CAAUnyB,IAAAE,MAAA,CAAWiyB,CAAA,CAAK,CAAL,CAAX,CAAqB,CAArB,CALd,CAkCcM,QAAA,GAAQ,CAAC/0B,CAAD,CACtB,CACI,MAAO,CAACA,CAAA,CAAE,CAAF,CAAR,EAAgB,CAACA,CAAA,CAAE,CAAF,CADrB;AAkFA,IAAAixB,GAAoB,CAChBC,CADgB,CAEhBA,CAFgB,CAGhBA,CAHgB,CAIhBA,CAJgB,CAKhBA,CALgB,CAMhBA,CANgB,CAOhBA,CAPgB,CAQhBA,CARgB,CAShBA,CATgB,CAUhBA,CAVgB,CAWhBA,CAXgB,CAYhBA,CAZgB,CAahBA,CAbgB,CAchBA,CAdgB,CAehBA,CAfgB,CAgBhBA,CAhBgB,CAiBhBA,CAjBgB,CAkBhBA,CAlBgB,CAmBhBA,CAnBgB,CAoBhBA,CApBgB,CAqBhBA,CArBgB,CAsBhBA,CAtBgB,CAuBhBA,CAvBgB,CAwBhBA,CAxBgB,CAyBhBA,CAzBgB,CA0BhBA,CA1BgB,CA2BhBA,CA3BgB,CA4BhBA,CA5BgB,CA6BhBA,CA7BgB,CA8BhBA,CA9BgB,CA+BhBA,CA/BgB,CAgChBA,CAhCgB,CAiChBA,CAjCgB,CAkChBA,CAlCgB,CAmChBA,CAnCgB,CAoChBA,CApCgB,CAqChBA,CArCgB,CAsChBA,CAtCgB,CAuChBA,CAvCgB,CAwChBA,CAxCgB,CAyChBA,CAzCgB,CA0ChBA,CA1CgB,CA2ChBA,CA3CgB,CA4ChBA,CA5CgB,CA6ChBA,CA7CgB,CA8ChBA,CA9CgB,CA+ChBA,CA/CgB,CAgDhBA,CAhDgB,CAiDhBA,CAjDgB,CAkDhBA,CAlDgB,CAmDhBA,CAnDgB,CAoDhBA,CApDgB,CAqDhBA,CArDgB,CAsDhBA,CAtDgB,CAuDhBA,CAvDgB,CAwDhBA,CAxDgB,CAyDhBA,CAzDgB,CA0DhBA,CA1DgB,CA2DhBA,CA3DgB,CA4DhBA,CA5DgB,CA6DhBA,CA7DgB,CA8DhBA,CA9DgB,CA+DhBA,CA/DgB,CAgEhBA,CAhEgB,CAiEhByC,CAjEgB,CAkEhBA,CAlEgB,CAmEhBA,CAnEgB,CAoEhBA,CApEgB,CAqEhBA,CArEgB,CAsEhBA,CAtEgB,CAuEhBA,CAvEgB,CAwEhBA,CAxEgB,CAyEhBA,CAzEgB,CA0EhBA,CA1EgB,CA2EhBA,CA3EgB,CA4EhBA,CA5EgB,CA6EhBA,CA7EgB,CA8EhBA,CA9EgB,CA+EhBA,CA/EgB,CAgFhBA,CAhFgB,CAiFhBA,CAjFgB,CAkFhBA,CAlFgB,CAmFhBA,CAnFgB,CAoFhBA,CApFgB,CAqFhBA,CArFgB,CAsFhBA,CAtFgB,CAuFhBA,CAvFgB,CAwFhBA,CAxFgB,CAjyNNoD,QAAQ,CAACnG,CAAD,CACtB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAgyNoB,CA7wNNoG,QAAQ,CAACpG,CAAD,CACtB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA4wNoB,CA5uNNqG,QAAQ,CAACrG,CAAD,CACtB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA2uNoB,CA4FhBO,EA5FgB,CAppNL+F,QAAQ,CAACtG,CAAD,CAAKU,CAAL,CACvB,CAQU,IAAA3C,EAAN,CArmKgBkB,IAqmKhB,GACIsH,EAAAnjB,KAAA,CAAiB,IAAjB,CAAuB4c,CAAvB,CAA2BU,CAA3B,CACA,CAAA,IAAA3C,EAAA,EAvmKYkB,IAqmKhB,CAIAuH,GAAApjB,KAAA,CAAiB,IAAjB,CAAuB4c,CAAvB,CAA2BU,CAA3B,CAZJ,CAmpNoB,CA8FhBD,EA9FgB,CA5jNLgG,QAAQ,CAACzG,CAAD,CAAKU,CAAL,CACvB,CAQU,IAAA3C,EAAN,CA7rKgBkB,IA6rKhB,GACIsH,EAAAnjB,KAAA,CAAiB,IAAjB,CAAuB4c,CAAvB,CAA2BU,CAA3B,CACA,CAAA,IAAA3C,EAAA,EA/rKYkB,IA6rKhB,CAIAyH,GAAAtjB,KAAA,CAAiB,IAAjB,CAAuB4c,CAAvB,CAA2BU,CAA3B,CAZJ,CA2jNoB,CAgGhBC,EAhGgB,CAx/MNgG,QAAQ,CAAC3G,CAAD,CACtB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAu/MoB,CA5+ML4G,QAAQ,CAAC5G,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA2+MoB,CAh+ML6G,QAAQ,CAAC7G,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA+9MoB,CAp9ML8G,QAAQ,CAAC9G,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAm9MoB;AAx8ML+G,QAAQ,CAAC/G,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAu8MoB,CA57MJgH,QAAQ,CAAChH,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA27MoB,CAh7MJiH,QAAQ,CAACjH,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA+6MoB,CAp6MJkH,QAAQ,CAAClH,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAm6MoB,CAx5MNmH,QAAQ,CAACnH,CAAD,CACtB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAu5MoB,CA54MLoH,QAAQ,CAACpH,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA24MoB,CAh4MLqH,QAAQ,CAACrH,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA+3MoB,CAp3MLsH,QAAQ,CAACtH,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAm3MoB,CAx2MLuH,QAAQ,CAACvH,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAu2MoB,CA51MJwH,QAAQ,CAACxH,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA21MoB,CAh1MJyH,QAAQ,CAACzH,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA+0MoB,CAp0MJ0H,QAAQ,CAAC1H,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAm0MoB,CAxzMN2H,QAAQ,CAAC3H,CAAD,CACtB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAuzMoB,CA5yML4H,QAAQ,CAAC5H,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA2yMoB,CAhyML6H,QAAQ,CAAC7H,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA+xMoB,CApxML8H,QAAQ,CAAC9H,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAmxMoB,CAxwML+H,QAAQ,CAAC/H,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAuwMoB,CA5vMJgI,QAAQ,CAAChI,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA2vMoB,CAhvMJiI,QAAQ,CAACjI,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA+uMoB,CApuMJkI,QAAQ,CAAClI,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAmuMoB,CAxtMNmI,QAAQ,CAACnI,CAAD,CACtB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAutMoB,CA5sMLoI,QAAQ,CAACpI,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA2sMoB;AAhsMLqI,QAAQ,CAACrI,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA+rMoB,CAprMLsI,QAAQ,CAACtI,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAmrMoB,CAxqMLuI,QAAQ,CAACvI,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAuqMoB,CA5pMJwI,QAAQ,CAACxI,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA2pMoB,CAhpMJyI,QAAQ,CAACzI,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA+oMoB,CApoMJ0I,QAAQ,CAAC1I,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAmoMoB,CAiIhBY,EAjIgB,CAkIhBC,EAlIgB,CAmIhBC,EAnIgB,CA9iMJ6H,QAAQ,CAAC3I,CAAD,CAAKU,CAAL,CACxB,CACQA,CAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAAnB,CADZ,CA6iMoB,CA3hMLmL,QAAQ,CAAC5I,CAAD,CAAKU,CAAL,CACvB,CACQU,CAAAA,CAAM,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CACV2D,EAAA,EAAQA,CAAR,CAAcS,CAAd,CAAgC,CAAhC,GAAuCT,CAAvC,CAA6CG,CAA7C,EAAgEM,CAChE,KAAAjS,EAAA,CAAe8Q,CAAf,CAAmBU,CAAnB,CAHJ,CA0hMoB,CApgMJyH,QAAQ,CAAC7I,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB,IAAAjD,EAAnB,CAAgCoE,CAAhC,CADJ,CAmgMoB,CAj/LJiH,QAAQ,CAAC9I,CAAD,CAAKU,CAAL,CACxB,CACQU,CAAAA,CAAM,IAAAtR,EAAA,CAAc4Q,CAAd,CACVU,EAAA,EAAQA,CAAR,CAAcS,CAAd,CAAgC,CAAhC,GAAuCT,CAAvC,CAA6CG,CAA7C,EAAgEM,CAChE,KAAAjS,EAAA,CAAe,IAAA6N,EAAf,CAA2B2D,CAA3B,CAHJ,CAg/LoB,CA59LJ2H,QAAQ,CAAC/I,CAAD,CAAKU,CAAL,CACxB,CACQU,CAAAA,CAAM,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CACV2D,EAAA,EAAQA,CAAR,CAAcS,CAAd,CAAgC,CAAhC,GAAuCT,CAAvC,CAA6CG,CAA7C,EAAgEM,CAChE,KAAAjS,EAAA,CAAe,IAAA6N,EAAf,CAA2B2D,CAA3B,CACIV,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBU,CAAnB,CAJZ,CA29LoB,CAh8LL4H,QAAQ,CAAChJ,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBuI,EAAA7lB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAnB,CADJ,CA+7LoB,CAr6LJyL,QAAQ,CAAClJ,CAAD,CAAKU,CAAL,CACxB,CASI,IAAA9Q,EAAA,CAAe8Q,CAAf;AAAmBuI,EAAA7lB,KAAA,CAAiB,IAAjB,CAAuB,IAAAqa,EAAvB,CAAnB,CATJ,CAo6LoB,CAp4LJ0L,QAAQ,CAACnJ,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BwL,EAAA7lB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA3B,CADJ,CAm4LoB,CA32LJ0I,QAAQ,CAACpJ,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM4H,EAAA7lB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CACV,KAAA7N,EAAA,CAAe,IAAA6N,EAAf,CAA2B4D,CAA3B,CACIX,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA02LoB,CAh1LLgI,QAAQ,CAACrJ,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB4I,EAAAlmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAnB,CADJ,CA+0LoB,CArzLJ8L,QAAQ,CAACvJ,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB,IAAAjD,EAAnB,CADJ,CAozLoB,CA5xLJ+L,QAAQ,CAACxJ,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B6L,EAAAlmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA3B,CADJ,CA2xLoB,CAnwLJ+I,QAAQ,CAACzJ,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAMiI,EAAAlmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CACV,KAAA7N,EAAA,CAAe,IAAA6N,EAAf,CAA2B4D,CAA3B,CACIX,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAkwLoB,CA7uLLqI,QAAQ,CAAC1J,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBiJ,EAAAvmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAAqE,CAAA,CAArE,CAAnB,CADJ,CA4uLoB,CAztLJmM,QAAQ,CAAC5J,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBiJ,EAAAvmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAAjD,EAA1C,CAAsD,CAAA,CAAtD,CAAnB,CADJ,CAwtLoB,CArsLJoM,QAAQ,CAAC7J,CAAD;AAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BkM,EAAAvmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAAqE,CAAA,CAArE,CAA3B,CADJ,CAosLoB,CAjrLJqM,QAAQ,CAAC9J,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBiJ,EAAAvmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAAqE,CAAA,CAArE,CAAnB,CAA3B,CADJ,CAgrLoB,CA7pLNsM,QAAQ,CAAC/J,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBiJ,EAAAvmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAAnB,CACA,KAAA7N,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC,IAAA5C,EAAhC,CAFJ,CA4pLoB,CAxoLLkM,QAAQ,CAAChK,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBiJ,EAAAvmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAAjD,EAA1C,CAAnB,CACA,KAAA7N,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC,IAAA5C,EAAhC,CAFJ,CAuoLoB,CAnnLLmM,QAAQ,CAACjK,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BkM,EAAAvmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAA3B,CADJ,CAknLoB,CA/lLLyM,QAAQ,CAAClK,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBiJ,EAAAvmB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAAnB,CAA3B,CACA,KAAA7N,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC,IAAA5C,EAAhC,CAFJ,CA8lLoB,CAxkLLqM,QAAQ,CAACnK,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM+I,EAAAhnB,KAAA,CAAiB,IAAjB;AAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,IAAA3N,EAAA,CAAc4Q,CAAd,CAAlD,CACA,EAAV,CAAIW,CAAJ,GACA,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CACA,CAAA,IAAAzR,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC,IAAA5C,EAAhC,CAFA,CAFJ,CAukLoB,CA/iLJuM,QAAQ,CAACrK,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM+I,EAAAhnB,KAAA,CAAiB,IAAjB,CAAuB,IAAAqa,EAAvB,CAAmC,IAAA3N,EAAA,CAAc4Q,CAAd,CAAnC,CACA,EAAV,CAAIW,CAAJ,GACA,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CACA,CAAA,IAAAzR,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC,IAAA5C,EAAhC,CAFA,CAFJ,CA8iLoB,CAthLJwM,QAAQ,CAACtK,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM+I,EAAAhnB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,IAAA3N,EAAA,CAAc4Q,CAAd,CAAlD,CACA,EAAV,CAAIW,CAAJ,EACA,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B4D,CAA3B,CAHJ,CAqhLoB,CA9/KJkJ,QAAQ,CAACvK,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM+I,EAAAhnB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,IAAA3N,EAAA,CAAc4Q,CAAd,CAAlD,CACA,EAAV,CAAIW,CAAJ,GACA,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAA3B,CACA,CAAA,IAAAzR,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC,IAAA5C,EAAhC,CAFA,CAFJ,CA6/KoB,CAp+KN0M,QAAQ,CAACxK,CAAD,CAAKU,CAAL,CACtB,CACQ6C,CAAAA,CAAM,IAAAzT,EAAA,CAAc4Q,CAAd,CACV,KAAIW,EAAM,IAAAvR,EAAA,CAAe4Q,CAAf,CAAoB,CAApB,CAAyB,EAAzB,CACVW,EAAA,CAAM+I,EAAAhnB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD4D,CAAlD,CAAuDkC,CAAvD,CACI,EAAV,CAAIlC,CAAJ,GACA,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CACA,CAAA,IAAAzR,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC,IAAA5C,EAAhC,CAFA,CAJJ,CAm+KoB,CAx8KL2M,QAAQ,CAACzK,CAAD,CAAKU,CAAL,CACvB,CACQ6C,CAAAA,CAAM,IAAAzT,EAAA,CAAc4Q,CAAd,CACV,KAAIW;AAAM,IAAAvR,EAAA,CAAe4Q,CAAf,CAAoB,CAApB,CAAyB,EAAzB,CACVW,EAAA,CAAM+I,EAAAhnB,KAAA,CAAiB,IAAjB,CAAuB,IAAAqa,EAAvB,CAAmC4D,CAAnC,CAAwCkC,CAAxC,CACI,EAAV,CAAIlC,CAAJ,GACA,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CACA,CAAA,IAAAzR,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC,IAAA5C,EAAhC,CAFA,CAJJ,CAu8KoB,CA56KL4M,QAAQ,CAAC1K,CAAD,CAAKU,CAAL,CACvB,CACQ6C,CAAAA,CAAM,IAAAzT,EAAA,CAAc4Q,CAAd,CACNW,EAAAA,CAAM,IAAAvR,EAAA,CAAe4Q,CAAf,CAAoB,CAApB,CAAyB,EAAzB,CACVW,EAAA,CAAM+I,EAAAhnB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD4D,CAAlD,CAAuDkC,CAAvD,CACI,EAAV,CAAIlC,CAAJ,EACA,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B4D,CAA3B,CALJ,CA26KoB,CAj5KLsJ,QAAQ,CAAC3K,CAAD,CAAKU,CAAL,CACvB,CACQ6C,CAAAA,CAAM,IAAAzT,EAAA,CAAc4Q,CAAd,CACV,KAAIW,EAAM,IAAAvR,EAAA,CAAe4Q,CAAf,CAAoB,CAApB,CAAyB,EAAzB,CACVW,EAAA,CAAM+I,EAAAhnB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD4D,CAAlD,CAAuDkC,CAAvD,CACI,EAAV,CAAIlC,CAAJ,GACA,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmB,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B4D,CAA3B,CAAnB,CACA,CAAA,IAAAzR,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC,IAAA5C,EAAhC,CAFA,CAJJ,CAg5KoB,CA/1KN8M,QAAQ,CAAC5K,CAAD,CAAKU,CAAL,CACtB,CAKI,GADIvwB,CACJ,EADW,IAAAstB,EACX,CADwBoN,EACxB,GAD6C,EAC7C,EADoD,EACpD,CAD2D,IAAApN,EAC3D,CADwE,GACxE,CAAO,CAAA,IAECltB,EAAI,IAAAuf,EAAA,CAAc4Q,CAAd,CACR,IAAQ,CAAR,CAAIvwB,CAAJ,CAAW,CACP,IAAA26B,EAAOnJ,CACP,KAAArxB,EAAKC,CAAD,CAAK0yB,CAAL,CAAuB,CAAvB,CAA2BA,CACvB,GAAR,CAAI9yB,CAAJ,GACIG,CAcA,EAdMC,CAcN,CAdUmB,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAcV,CAd4B8yB,CAc5B,CAAA6H,CAAA,CAAO7H,CAAP,CAAyBvxB,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAf7B,CAiBII,EAAJ,CAAQ0yB,CAAR,CAMQ1yB,CANR,CAMYu6B,CANZ,CAMmBnJ,CANnB,GAOQ,IAAA5D,EAPR,EAl7MQkB,MAk7MR,EAeQ1uB,CAfR;AAeYu6B,CAfZ,CAemB7H,CAfnB,GAgBQ,IAAAlF,EAhBR,EAl7MQkB,MAk7MR,CApBO,CAAX,IAwCc,GAAV,EAAI9uB,CAAJ,CACIG,CADJ,CACSC,CAAD,CAAK0yB,CAAL,CAAuB,CAAvB,CAA2BtB,CADnC,EAGIrxB,CACA,CADIoB,IAAAE,MAAA,CAAWrB,CAAX,CAAemB,IAAAC,IAAA,CAAS,CAAT,CAAY,CAACxB,CAAb,CAAf,CACJ,CAAII,CAAJ,CAAQoxB,CAAR,GACImJ,CACA,CADOza,CACP,CAD0B3e,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAC1B,CAAAG,CAAA,EAAKw6B,CAFT,CAJJ,CAWJ,KAAAlb,EAAA,CAAe8Q,CAAf,CAAmBpwB,CAAnB,CAtDG,CALX,CA81KoB,CA5wKNy6B,QAAQ,CAAC/K,CAAD,CAAKU,CAAL,CACtB,CAKI,GADIvwB,CACJ,GADY,IAAAstB,EACZ,CADyBoN,EACzB,GAD8C,EAC9C,EADqD,EACrD,CAD4D,IAAApN,EAC5D,CADyE,GACzE,EADkF,EAClF,CAAO,CACH,IAAIltB,EAAI,IAAAuf,EAAA,CAAc4Q,CAAd,CAIA,EAAR,CAAIvwB,CAAJ,GAAWA,CAAX,CAAe,EAAf,CAAoBA,CAApB,CACAI,EAAA,CAAMA,CAAN,CAAUmB,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAAV,CAA4BkgB,CAA5B,CAAgD3e,IAAAE,MAAA,CAAWrB,CAAX,CAAemB,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAAf,CAChD,KAAAyf,EAAA,CAAe8Q,CAAf,CAAmBnwB,CAAnB,CAPG,CALX,CA2wKoB,CA3tKNy6B,QAAQ,CAAChL,CAAD,CAAKU,CAAL,CACtB,CAKI,GADIvwB,CACJ,EADW,IAAAstB,EACX,CADwBoN,EACxB,GAD6C,EAC7C,EADoD,EACpD,CAD2D,IAAApN,EAC3D,CADwE,GACxE,CAAO,CACH,IAAIltB,EAAI,IAAAuf,EAAA,CAAc4Q,CAAd,CAGAnwB,EAAA,CAFA,CAAR,CAAIJ,CAAJ,CACa,EAAT,EAAIA,CAAJ,CACQ,CADR,CAGSI,CAHT,CAGamB,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAHb,CAG+BkgB,CAJnC,CAOc,GAAV,EAAIlgB,CAAJ,CACQ,CADR,CAGQuB,IAAAE,MAAA,CAAWrB,CAAX,CAAemB,IAAAC,IAAA,CAAS,CAAT,CAAY,CAACxB,CAAb,CAAf,CAGZ,KAAAyf,EAAA,CAAe8Q,CAAf,CAAmBnwB,CAAnB,CAfG,CALX,CA0tKoB,CAnrKL06B,QAAQ,CAACjL,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,CACV,KAAID,EAAM,IAAAtR,EAAA,CAAc4Q,CAAd,CACV,IAAIU,CAAJ,CAAS,CACL,IAAA,CAAOA,CAAP,CAAa6B,CAAb,CAAA,CACI5B,CAAA,EACA,CAAAD,CAAA,EAAO,CAEXvS,EAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CALK,CAOT,IAAA7N,EAAA,CAAgB8Q,CAAhB;AAAqB,CAArB,CAA0B,EAA1B,CAAgCW,CAAhC,CAVJ,CAkrKoB,CAlpKL6J,QAAQ,CAAClL,CAAD,CAAKU,CAAL,CACvB,CAKI,GADIvwB,CACJ,EADW,IAAAstB,EACX,CADwBoN,EACxB,GAD6C,EAC7C,EADoD,EACpD,CAD2D,IAAApN,EAC3D,CADwE,GACxE,CAAO,CACH,IACI0N,EAAQ,IAAArb,EAAA,CAAc4Q,CAAd,CADZ,CAEI0K,EAAS,IAAAtb,EAAA,CAAe4Q,CAAf,CAAoB,CAApB,CAAyB,EAAzB,CACb,IAAQ,CAAR,CAAIvwB,CAAJ,CAAW,CAKP,IAAIk7B,EAAYF,CAChB,IAAS,EAAT,EAAIh7B,CAAJ,CAAa,CAKT,GAAY,CAAZ,CAAIg7B,CAAJ,EAAiBA,CAAjB,CAAyBlI,CAAzB,EAA4CkI,CAA5C,CAAoDxJ,CAApD,EAAsEwJ,CAAtE,CAA8ElK,CAA9E,CACI,IAAAlD,EAAA,EAxnNAkB,MA0nNJ,IAAS,EAAT,EAAI9uB,CAAJ,CAAa,CAKT,GAAa,CAAb,CAAIi7B,CAAJ,EAAkBA,CAAlB,CAA2BnI,CAA3B,EAA8CmI,CAA9C,CAAuDzJ,CAAvD,EAAyEyJ,CAAzE,CAAkFnK,CAAlF,CACI,IAAAlD,EAAA,EAhoNJkB,MAkoNAkM,EAAA,CAAQ,CARC,CAAb,IASO,CAIHA,CAAA,CAASC,CAAT,CAAkB15B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAAgB,EAAhB,CAAlB,CAAyC8yB,CACzC,KAAA6H,EAAO7H,CAAP6H,CAAyBp5B,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CACrBk7B,EAAJ,EAAiB1J,CAAjB,CAMQyJ,CANR,CAMiBN,CANjB,CAMwBnJ,CANxB,GAOQ,IAAA5D,EAPR,EAzoNAkB,MAyoNA,EAeQmM,CAfR,CAeiBN,CAfjB,EAeyBnJ,CAfzB,GAgBQ,IAAA5D,EAhBR,EAzoNAkB,MAyoNA,CANG,CA0BPmM,CAAA,CAAS,CACLC,EAAJ,CAAgB1J,CAAhB,GACIwJ,CACA,EADSlI,CACT,CAAAmI,CAAA,EAAUnI,CAFd,CA5CS,CAAb,IAoDIkI,EAMA,CANUA,CAMV,CANkBz5B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAMlB,CANoC8yB,CAMpC,CANuDvxB,IAAAE,MAAA,CAAYw5B,CAAZ,CAAqBnI,CAArB,CAAwCvxB,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAAxC,CAMvD,CALAi7B,CAKA,CALUA,CAKV,CALmB15B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAKnB,CALqC8yB,CAKrC,CADA6H,CACA,CADO7H,CACP,CADyBvxB,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CACzB,CAAIk7B,CAAJ,EAAiB1J,CAAjB,CAMQ0J,CANR,CAMoBP,CANpB,CAM2BnJ,CAN3B,GAOQ,IAAA5D,EAPR,EA5qNIkB,MA4qNJ,GAeQoM,CAOJ,CAPgBP,CAOhB,EAPwBnJ,CAOxB,GANI,IAAA5D,EAMJ,EAlsNAkB,MAksNA,EADAkM,CACA,EADSlI,CACT,CAAAmI,CAAA,EAAUnI,CAtBd,CAhEG,CAAX,IA8Fc,GAAV;AAAI9yB,CAAJ,EAEQi7B,CAIJ,CALU,GAAV,EAAIj7B,CAAJ,CACcg7B,CAAA,CAAQxJ,CAAR,CAAwBV,CAAxB,CAA0C,CADxD,CAGavvB,IAAAE,MAAA,CAAYu5B,CAAZ,CAAoBlI,CAApB,CAAuCvxB,IAAAC,IAAA,CAAS,CAAT,CAAY,CAACxB,CAAb,CAAiB,EAAjB,CAAvC,CAEb,CAAIg7B,CAAJ,EAAaxJ,CAAb,CACIwJ,CADJ,CACY,CADZ,EAGIA,CACA,CADQlK,CACR,CAAAmK,CAAA,EAAUnI,CAJd,CANJ,GAgBI6H,CAWA,CAXQK,CAAA,CAAQxJ,CAAR,CAAwBtR,CAAxB,CAA2C3e,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAA3C,CAAiE,CAWzE,CALAi7B,CAKA,CALS15B,IAAAE,MAAA,CAAYw5B,CAAZ,CAAqBnI,CAArB,CAAwCvxB,IAAAC,IAAA,CAAS,CAAT,CAAY,CAACxB,CAAb,CAAxC,CAKT,CALuEg7B,CAKvE,CAL+ElI,CAK/E,CALkGvxB,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAKlG,CALyH8yB,CAKzH,CAJAkI,CAIA,CAJQz5B,IAAAE,MAAA,CAAWu5B,CAAX,CAAmBz5B,IAAAC,IAAA,CAAS,CAAT,CAAY,CAACxB,CAAb,CAAnB,CAIR,CAJ8C26B,CAI9C,CAAIK,CAAJ,CAAYxJ,CAAZ,GAA4ByJ,CAA5B,EAAsCnI,CAAtC,CA3BJ,CA8BJ,KAAArT,EAAA,CAAe8Q,CAAf,CAAmByK,CAAnB,CACA,KAAAvb,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC0K,CAAhC,CAjIG,CALX,CAipKoB,CAl/JLE,QAAQ,CAACtL,CAAD,CAAKU,CAAL,CACvB,CAKI,GADIvwB,CACJ,GADY,IAAAstB,EACZ,CADyBoN,EACzB,GAD8C,EAC9C,EADqD,EACrD,CAD4D,IAAApN,EAC5D,CADyE,GACzE,EADkF,EAClF,CAAO,CACH,IAAI0N,EAAQ,IAAArb,EAAA,CAAc4Q,CAAd,CAAZ,CACI0K,EAAS,IAAAtb,EAAA,CAAe4Q,CAAf,CAAoB,CAApB,CAAyB,EAAzB,CADb,CAEI2K,EAAYF,CAIR,EAAR,CAAIh7B,CAAJ,GAAWA,CAAX,CAAe,EAAf,CAAoBA,CAApB,CACQ,GAAR,CAAIA,CAAJ,EACIg7B,CACA,CADUA,CACV,CADkBz5B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAClB,CADoCkgB,CACpC,CADwD3e,IAAAE,MAAA,CAAWw5B,CAAX,CAAoB15B,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAApB,CACxD,CAAAi7B,CAAA,CAAWA,CAAX,CAAoB15B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAApB,CAAsCkgB,CAAtC,CAA0D3e,IAAAE,MAAA,CAAWy5B,CAAX,CAAuB35B,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAAvB,CAF9D,GAIIg7B,CACA,CADUC,CACV,CADmB15B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAAgB,EAAhB,CACnB,CAD0CkgB,CAC1C,CAD8D3e,IAAAE,MAAA,CAAWu5B,CAAX,CAAmBz5B,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ;AAAiBxB,CAAjB,CAAnB,CAC9D,CAAAi7B,CAAA,CAAWC,CAAX,CAAuB35B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAAgB,EAAhB,CAAvB,CAA8CkgB,CAA9C,CAAkE3e,IAAAE,MAAA,CAAWw5B,CAAX,CAAoB15B,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAApB,CALtE,CAOA,KAAAyf,EAAA,CAAe8Q,CAAf,CAAmByK,CAAnB,CACA,KAAAvb,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC0K,CAAhC,CAhBG,CALX,CAi/JoB,CAn8JLG,QAAQ,CAACvL,CAAD,CAAKU,CAAL,CACvB,CAKI,GADIvwB,CACJ,EADW,IAAAstB,EACX,CADwBoN,EACxB,GAD6C,EAC7C,EADoD,EACpD,CAD2D,IAAApN,EAC3D,CADwE,GACxE,CAAO,CACH,IAAI0N,EAAQ,IAAArb,EAAA,CAAc4Q,CAAd,CAAZ,CACI0K,EAAS,IAAAtb,EAAA,CAAe4Q,CAAf,CAAoB,CAApB,CAAyB,EAAzB,CACL,EAAR,CAAIvwB,CAAJ,CACa,EAAT,EAAIA,CAAJ,EAEQg7B,CAIJ,CALS,EAAT,EAAIh7B,CAAJ,CACY,CADZ,CAGai7B,CAHb,CAGsB15B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAAgB,EAAhB,CAHtB,CAG6CkgB,CAE7C,CAAA+a,CAAA,CAAS,CANb,GAQID,CACA,CADUA,CACV,CADkBz5B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAClB,CADoCkgB,CACpC,CADwD3e,IAAAE,MAAA,CAAWw5B,CAAX,CAAoB15B,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAApB,CACxD,CAAAi7B,CAAA,CAAUA,CAAV,CAAmB15B,IAAAC,IAAA,CAAS,CAAT,CAAYxB,CAAZ,CAAnB,CAAqCkgB,CATzC,CADJ,CAac,GAAV,EAAIlgB,CAAJ,EAEQi7B,CAIJ,CALU,GAAV,EAAIj7B,CAAJ,CACa,CADb,CAGauB,IAAAE,MAAA,CAAWu5B,CAAX,CAAmBz5B,IAAAC,IAAA,CAAS,CAAT,CAAY,CAACxB,CAAb,CAAiB,EAAjB,CAAnB,CAEb,CAAAg7B,CAAA,CAAQ,CANZ,GAQIC,CACA,CADS15B,IAAAE,MAAA,CAAWw5B,CAAX,CAAoB15B,IAAAC,IAAA,CAAS,CAAT,CAAY,CAACxB,CAAb,CAApB,CACT,CADkDg7B,CAClD,CAD0Dz5B,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAiBxB,CAAjB,CAC1D,CADiFkgB,CACjF,CAAA8a,CAAA,CAAQz5B,IAAAE,MAAA,CAAWu5B,CAAX,CAAmBz5B,IAAAC,IAAA,CAAS,CAAT,CAAY,CAACxB,CAAb,CAAnB,CATZ,CAYJ,KAAAyf,EAAA,CAAe8Q,CAAf,CAAmByK,CAAnB,CACA,KAAAvb,EAAA,CAAgB8Q,CAAhB,CAAqB,CAArB,CAA0B,EAA1B,CAAgC0K,CAAhC,CA7BG,CALX,CAk8JoB,CAwKhBrI,CAxKgB,CAj5JLyI,QAAQ,CAACxL,CAAD,CAAKU,CAAL,CACvB,CACQ+K,CAAAA,CAAM,IAAA3b,EAAA,CAAc4Q,CAAd,CACV,KAAA9Q,EAAA,CAAe8Q,CAAf;AAAmB,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAAnB,CACA,KAAA7N,EAAA,CAAe,IAAA6N,EAAf,CAA2BgO,CAA3B,CAHJ,CAg5JoB,CAl3JNC,QAAQ,CAAC1L,CAAD,CAAKU,CAAL,CACtB,CACI,IAAmBiL,EAAfC,CAAeD,CAAP,CAAA,CAAZ,CACIE,EAAU,IAAA/b,EAAA,CAAc4Q,CAAd,CADd,CAEIoL,EAAWD,CAAXC,CAAqBjK,CAArBiK,CAAuC,CAE3C,KADAD,CACA,EADWtK,CACX,CAAO,CAACqK,CAAR,CAAA,CAaI,GAZA,IAAAhc,EAAA,CAAeic,CAAf,CAAwB,IAAA/b,EAAA,CAAcgc,CAAd,CAAxB,CAYI,EALEF,CAKF,CALWC,CAKX,EALsB,IAAApO,EAKtB,IAJAqO,CAEA,CAFWA,CAEX,CAFqB,CAErB,CAF0BvK,CAE1B,CADAsK,CACA,CADWA,CACX,CADqB,CACrB,CAD0BtK,CAC1B,CAAAoK,CAAA,CAAU,CAAA,CAEV,EAAAC,CAAA,EAAS,CAACG,IAr8HPluB,MAAA+Q,EAq8HP,CAAgC,CAKxB+c,CAAJ,EAAa,IAAA/b,EAAA,CAAe8Q,CAAf,CAAmBoL,CAAnB,CAA6BjK,CAA7B,CAAgDgK,CAAhD,CACRD,EAAL,EAAY1M,EAAA,CAAAA,IAAA,CAAgB,EAAhB,CACZ,MAP4B,CAlBxC,CAi3JoB,CAl0JJ8M,QAAQ,CAAChM,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,EAAO,IAAAvR,EAAA,CAAc4Q,CAAd,CAAPW,CAA2B,MAA3BA,EAA6ChR,CACjD,KAAAT,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CACIA,EAAJ,CAAU4B,CAAV,EAA2BpU,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAH/B,CAi0JoB,CA1yJJwO,QAAQ,CAACjM,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,EAAO,IAAAvR,EAAA,CAAc4Q,CAAd,CAAPW,CAA2B,MAA3BA,EAA6ChR,CACjD,KAAAT,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CACIA,EAAJ,EAAW4B,CAAX,EAA4BpU,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAHhC,CAyyJoB,CA1vJLyO,QAAQ,CAAClM,CAAD,CAAKU,CAAL,CACvB,CACQA,CAAJ,CAAS,CAAT,GAIIyL,IAzyFApO,EAqyFJ,EAv/NgBkB,IAu/NhB,CAMIyB,EAAJ,CAAS,CAAT,EAII1B,EAAA,CAAAA,IAAA,CAAY,IAAAzB,GAAZ,CAAyBsE,CAAzB,CAA2C,CAA3C,CAEAnB,EAAJ,CAAS,CAAT,EAIIzR,CAAA,CAAAA,IAAA,CAEAyR,EAAJ,CAAS,CAAT,EAII,IAAAzD,EAAA,CAAiB+C,CAAjB,CAEJnR,EAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAzBJ,CAyvJoB,CA9rJL2O,QAAQ,CAACpM,CAAD,CAAKU,CAAL,CACvB,CAIQ2L,CAAAA,CAAS3L,CAAT2L,EAAe,EACf,KAAAtO,EAAJ,CAAiBsO,CAAjB,GACI,IAAAtO,EACA,EADc,CAACsO,CACf;AAAAxd,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAFJ,CALJ,CA6rJoB,CAnqJN6O,QAAQ,EACtB,CACI,IAAAzO,EAAA,CAAa,IAAAJ,EADjB,CAkqJoB,CAgLhBsF,CAhLgB,CA3oJJwJ,QAAQ,CAACvM,CAAD,CAAKU,CAAL,CACxB,CACQ1wB,CAAAA,EAAK,IAAA8f,EAAA,CAAc4Q,CAAd,CAAL1wB,CAAyB,MAAzBA,EAA2CqgB,CAC/C,KAAAT,EAAA,CAAe8Q,CAAf,CAAmB1wB,CAAnB,CACOA,EAAP,CAAW6xB,CAAX,CAA6B,CAA7B,GACI,IAAA9D,EADJ,EAhmOekB,MAgmOf,CAGA,KAAArP,EAAA,CAAe5f,CAAf,CAAmB8vB,EAAnB,EAAoC0M,IAx7FxBzO,EAw7FZ,CAx7FyBwD,CAw7FzB,EAAmDM,CAAnD,CAAsE4K,IA7yF3Dnc,EA6yFX,CACA,KAAAyN,EAAA,EAAc,KACdlP,EAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CARJ,CA0oJoB,CAnmJLiP,QAAQ,CAAC1M,CAAD,CAAKU,CAAL,CACvB,CACQ1wB,CAAAA,CAAI,IAAA8f,EAAA,CAAc4Q,CAAd,CAKJ1wB,EAAA,EAAK,MACL,KAAA4f,EAAA,CAAe5f,CAAf,CAAmB8vB,EAAnB,CAAoC,IAAAhQ,EAAA,CAAc,IAAA2N,EAAd,CAApC,CACIztB,EAAJ,EAASqgB,CAAT,GAA2BrgB,CAA3B,EAAgCqgB,CAAhC,CACOrgB,EAAP,CAAW6xB,CAAX,CAA6B,CAA7B,GACI,IAAA9D,EADJ,EA9oOWkB,MA8oOX,CAeJ,KAAArP,EAAA,CAAe8Q,CAAf,CAAmB1wB,CAAnB,CAxBJ,CAkmJoB,CAvjJN28B,QAAQ,CAAC3M,CAAD,CAAKU,CAAL,CACtB,CACQ1wB,CAAAA,CAAI,IAAA8f,EAAA,CAAc4Q,CAAd,CACR,KAAIU,EAAM,IAAAtR,EAAA,CAAc9f,CAAd,CAAkB8vB,EAAlB,CACV,KAAAlQ,EAAA,CAAe,IAAA6N,EAAf,CAA2B2D,CAA3B,CACI,KAAA3D,EAAJ,EAAkBiD,CAAlB,GAAsB1wB,CAAtB,CAA0BoxB,CAA1B,CACApxB,EAAA,EAAK,MACG,EAAR,CAAIA,CAAJ,GAAWA,CAAX,EAAgBqgB,CAAhB,CACA,EAAMrgB,CAAN,CAAU6xB,CAAV,CAA4B,CAA5B,GAAkCN,CAAlC,GACI,IAAAxD,EADJ,EAxrOekB,MAwrOf,CAGA,KAAArP,EAAA,CAAe8Q,CAAf,CAAmB1wB,CAAnB,CAVJ,CAsjJoB,CAzhJL48B,QAAQ,CAAC5M,CAAD,CAAKU,CAAL,CACvB,CACQ1wB,CAAAA,CAAI,IAAA8f,EAAA,CAAc4Q,CAAd,CACR,KAAIvB,EAAK,IAAArP,EAAA,CAAc9f,CAAd,CAAkB8vB,EAAlB,CACT9vB,EAAA,EAAK,MACG,EAAR,CAAIA,CAAJ,GAAWA,CAAX;AAAgBqgB,CAAhB,CACA,EAAMrgB,CAAN,CAAU6xB,CAAV,CAA4B,CAA5B,GAAkCN,CAAlC,GACI,IAAAxD,EADJ,EAptOekB,MAotOf,CAGA,KAAArP,EAAA,CAAe8Q,CAAf,CAAmB1wB,CAAnB,CACA6e,EAAA,CAAAA,IAAA,CAAWsQ,CAAX,CAAgBW,EAAhB,CATJ,CAwhJoB,CA3/IN+M,QAAQ,EACtB,CACI,IAAAjd,EAAA,CAAe,IAAA6N,EAAf,EAA2B+O,IAnkGfzO,EAmkGZ,CAnkGyBwD,CAmkGzB,EAA0CM,CAA1C,CAA6D4K,IAx7FlDnc,EAw7FX,CACA,KAAAyN,EAAA,EAAc,KACdlP,EAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAAwB,CAAxB,CAHJ,CA0/IoB,CAn+INqP,QAAQ,CAAC9M,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,EAAmB8L,IA3lGPzO,EA2lGZ,CA3lGyBwD,CA2lGzB,EAAkCM,CAAlC,CAAqD4K,IAh9F1Cnc,EAg9FX,CACA,KAAAyN,EAAA,EAAc,KACdlP,EAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAHJ,CAk+IoB,CAp8INsP,QAAQ,CAAC/M,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA3N,EAAA,CAAc4Q,CAAd,CAA3B,CACA,KAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB,IAAAjD,EAAnB,CAAgCoE,CAAhC,CAAmD4K,IAh/FxCnc,EAg/FX,CACAzB,EAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAAwB,CAAxB,CAHJ,CAm8IoB,CAv6INuP,QAAQ,CAAChN,CAAD,CAAKU,CAAL,CACtB,CACQuM,CAAAA,CAAM,IAAAnd,EAAA,CAAc4Q,CAAd,CACV,KAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB,IAAA5Q,EAAA,CAAemd,CAAf,CAAqBpL,CAArB,CAAuC,CAAvC,CAAnB,CACAhT,EAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAHJ,CAs6IoB,CA/4INyP,QAAQ,CAAClN,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAAnB,CADJ,CA84IoB,CAz3IL2P,QAAQ,CAACpN,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAAjD,EAA1C,CAAnB,CADJ,CAw3IoB,CAn2IL4P,QAAQ,CAACrN,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf;AAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAA3B,CADJ,CAk2IoB,CA70IL6P,QAAQ,CAACtN,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAAnB,CAA3B,CADJ,CA40IoB,CAvzIN8P,QAAQ,CAACvN,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB8M,EAAApqB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAAnB,CADJ,CAszIoB,CAjyILgQ,QAAQ,CAACzN,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB8M,EAAApqB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAAjD,EAA1C,CAAnB,CADJ,CAgyIoB,CA3wILiQ,QAAQ,CAAC1N,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B+P,EAAApqB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAA3B,CADJ,CA0wIoB,CArvILkQ,QAAQ,CAAC3N,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmB8M,EAAApqB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA1C,CAAnB,CAA3B,CADJ,CAovIoB,CARFoF,EAQE,CApuIL+K,QAAQ,CAAC5N,CAAD,CAAKU,CAAL,CACvB,CACmD,CAA/C,CAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAJ,EAAkD5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADtD,CAmuIoB,CAntILud,QAAQ,CAAC7N,CAAD,CAAKU,CAAL,CACvB,CACoD,CAAhD,EAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAJ,EAAmD5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADvD,CAktIoB;AAlsIJwd,QAAQ,CAAC9N,CAAD,CAAKU,CAAL,CACxB,CACoD,CAAhD,EAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAJ,EAAmD5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADvD,CAisIoB,CAjrILyd,QAAQ,EACvB,CAEIlf,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAFJ,CAgrIoB,CA/pIJ0d,QAAQ,CAAChO,CAAD,CAAKU,CAAL,CACxB,CACoD,CAAhD,EAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAJ,EAAmD5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADvD,CA8pIoB,CA9oIL2d,QAAQ,CAACjO,CAAD,CAAKU,CAAL,CACvB,CACoD,CAAhD,EAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAJ,EAAmD5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADvD,CA6oIoB,CA7nIL4d,QAAQ,CAAClO,CAAD,CAAKU,CAAL,CACvB,CACmD,CAA/C,CAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAJ,EAAkD5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADtD,CA4nIoB,CAPFwS,EAOE,CA3mILqL,QAAQ,CAACnO,CAAD,CAAKU,CAAL,CACvB,CACkE,CAA9D,CAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAJ,EAAiE5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADrE,CA0mIoB,CAzlIL8d,QAAQ,CAACpO,CAAD,CAAKU,CAAL,CACvB,CACmE,CAA/D,EAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAJ,EAAkE5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADtE,CAwlIoB,CAvkIJ+d,QAAQ,CAACrO,CAAD,CAAKU,CAAL,CACxB,CACmE,CAA/D,EAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAJ,EAAkE5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADtE,CAskIoB,CArjILge,QAAQ,EACvB,CAEIzf,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAFJ,CAojIoB,CAliIJie,QAAQ,CAACvO,CAAD,CAAKU,CAAL,CACxB,CACmE,CAA/D,EAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV;AAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAJ,EAAkE5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADtE,CAiiIoB,CAhhILke,QAAQ,CAACxO,CAAD,CAAKU,CAAL,CACvB,CACmE,CAA/D,EAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAJ,EAAkE5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADtE,CA+gIoB,CA9/HLme,QAAQ,CAACzO,CAAD,CAAKU,CAAL,CACvB,CACkE,CAA9D,CAAIkF,EAAA,CAAU,IAAA9V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAJ,EAAiE5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADrE,CA6/HoB,CANFuS,EAME,CA7+HJ6L,QAAQ,CAAC1O,CAAD,CAAKU,CAAL,CACxB,CACwC,CAApC,CAAIqF,CAAA,CAAW,IAAAjW,EAAA,CAAc4Q,CAAd,CAAX,CAAJ,EAAuC7R,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAD3C,CA4+HoB,CA59HJkR,QAAQ,CAAC3O,CAAD,CAAKU,CAAL,CACxB,CACyC,CAArC,EAAIqF,CAAA,CAAW,IAAAjW,EAAA,CAAc4Q,CAAd,CAAX,CAAJ,EAAwC7R,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAD5C,CA29HoB,CA38HHmR,QAAQ,CAAC5O,CAAD,CAAKU,CAAL,CACzB,CACyC,CAArC,EAAIqF,CAAA,CAAW,IAAAjW,EAAA,CAAc4Q,CAAd,CAAX,CAAJ,EAAwC7R,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAD5C,CA08HoB,CA17HJoR,QAAQ,EACxB,CACIhgB,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CADJ,CAy7HoB,CAz6HHqR,QAAQ,CAAC9O,CAAD,CAAKU,CAAL,CACzB,CACyC,CAArC,EAAIqF,CAAA,CAAW,IAAAjW,EAAA,CAAc4Q,CAAd,CAAX,CAAJ,EAAwC7R,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAD5C,CAw6HoB,CAx5HJsR,QAAQ,CAAC/O,CAAD,CAAKU,CAAL,CACxB,CACyC,CAArC,EAAIqF,CAAA,CAAW,IAAAjW,EAAA,CAAc4Q,CAAd,CAAX,CAAJ,EAAwC7R,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAD5C,CAu5HoB,CAv4HJuR,QAAQ,CAAChP,CAAD,CAAKU,CAAL,CACxB,CACwC,CAApC,CAAIqF,CAAA,CAAW,IAAAjW,EAAA,CAAc4Q,CAAd,CAAX,CAAJ,EAAuC7R,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAD3C,CAs4HoB,CAr3HLwR,QAAQ,CAACjP,CAAD,CAAKU,CAAL,CACvB,CACQA,CAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAAnB,CADZ,CAo3HoB;AAn2HJyR,QAAQ,CAAClP,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CACY,EAAtB,CAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAAyBxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAk2HoB,CA/0HJ8N,QAAQ,CAACnP,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CACa,EAAvB,EAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA80HoB,CA3zHH+N,QAAQ,CAACpP,CAAD,CAAKU,CAAL,CACzB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CACa,EAAvB,EAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA0zHoB,CAvyHJgO,QAAQ,CAACrP,CAAD,CAAKU,CAAL,CACxB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACIoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAAnB,CAFZ,CAsyHoB,CApxHH6R,QAAQ,CAACtP,CAAD,CAAKU,CAAL,CACzB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CACa,EAAvB,EAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAmxHoB,CAhwHJkO,QAAQ,CAACvP,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CACa,EAAvB,EAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA+vHoB,CA5uHJmO,QAAQ,CAACxP,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc,IAAA2N,EAAd,CACY,EAAtB,CAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAAyBxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA2uHoB,CAvtHNoO,QAAQ,CAACzP,CAAD;AAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,CAA1C,CAAnB,CADJ,CAstHoB,CApsHLgP,QAAQ,CAAC1P,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,CAA1C,CAAnB,CACY,EAAtB,CAAIqF,CAAA,CAAW1E,CAAX,CAAJ,EAAyBxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF7B,CAmsHoB,CAhrHLkS,QAAQ,CAAC3P,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,CAA1C,CAAnB,CACa,EAAvB,EAAIqF,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF9B,CA+qHoB,CA5pHJmS,QAAQ,CAAC5P,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,CAA1C,CAAnB,CACa,EAAvB,EAAIqF,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF9B,CA2pHoB,CAxoHLoS,QAAQ,CAAC7P,CAAD,CAAKU,CAAL,CACvB,CACc,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,CAA1C,CAAnB,CACV7R,EAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAFJ,CAuoHoB,CApnHJqS,QAAQ,CAAC9P,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,CAA1C,CAAnB,CACa,EAAvB,EAAIqF,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF9B,CAmnHoB,CAhmHLsS,QAAQ,CAAC/P,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,CAA1C,CAAnB,CACa,EAAvB,EAAIqF,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF9B,CA+lHoB,CA5kHLuS,QAAQ,CAAChQ,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf;AAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0C,CAA1C,CAAnB,CACY,EAAtB,CAAIqF,CAAA,CAAW1E,CAAX,CAAJ,EAAyBxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF7B,CA2kHoB,CAxjHNwS,QAAQ,CAACjQ,CAAD,CAAKU,CAAL,CACtB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,CAAlD,CAA3B,CACNiD,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAFZ,CAujHoB,CApiHL6O,QAAQ,CAAClQ,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,CAAlD,CAA3B,CACY,EAAtB,CAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAAyBxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAmiHoB,CA/gHL8O,QAAQ,CAACnQ,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,CAAlD,CAA3B,CACa,EAAvB,EAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA8gHoB,CA1/GJ+O,QAAQ,CAACpQ,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,CAAlD,CAA3B,CACa,EAAvB,EAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAy/GoB,CAr+GLgP,QAAQ,CAACrQ,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,CAAlD,CAA3B,CACV5O,EAAA,CAAAA,IAAA;AAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACIoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAo+GoB,CAh9GJiP,QAAQ,CAACtQ,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,CAAlD,CAA3B,CACa,EAAvB,EAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA+8GoB,CA37GLkP,QAAQ,CAACvQ,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,CAAlD,CAA3B,CACa,EAAvB,EAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA07GoB,CAt6GLmP,QAAQ,CAACxQ,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkD,CAAlD,CAA3B,CACY,EAAtB,CAAIsI,CAAA,CAAW1E,CAAX,CAAJ,EAAyBxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAq6GoB,CAj5GNoP,QAAQ,CAACzQ,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0CO,CAA1C,CAAnB,CADJ,CAg5GoB,CA93GLyP,QAAQ,CAAC1Q,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0CO,CAA1C,CAAnB,CACY,EAAtB,CAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAAyBxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF7B,CA63GoB,CA12GLkT,QAAQ,CAAC3Q,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB;AAA0CO,CAA1C,CAAnB,CACa,EAAvB,EAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF9B,CAy2GoB,CAt1GJmT,QAAQ,CAAC5Q,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0CO,CAA1C,CAAnB,CACa,EAAvB,EAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF9B,CAq1GoB,CAl0GLoT,QAAQ,CAAC7Q,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0CO,CAA1C,CAAnB,CACApS,EAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAFJ,CAi0GoB,CA9yGJqT,QAAQ,CAAC9Q,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0CO,CAA1C,CAAnB,CACa,EAAvB,EAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF9B,CA6yGoB,CA1xGLsT,QAAQ,CAAC/Q,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0CO,CAA1C,CAAnB,CACa,EAAvB,EAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF9B,CAyxGoB,CAtwGLuT,QAAQ,CAAChR,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe8Q,CAAf,CAAmByM,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc4Q,CAAd,CAAvB,CAA0CO,CAA1C,CAAnB,CACY,EAAtB,CAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAAyBxS,CAAA,CAAAA,IAAA,CAAW,IAAA4O,EAAX,CAF7B,CAqwGoB,CAlvGNwT,QAAQ,CAACjR,CAAD,CAAKU,CAAL,CACtB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkDwD,CAAlD,CAA3B,CACNP,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAFZ,CAivGoB,CA9tGL6P,QAAQ,CAAClR,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf;AAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkDwD,CAAlD,CAA3B,CACY,EAAtB,CAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAAyBxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA6tGoB,CAzsGL8P,QAAQ,CAACnR,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkDwD,CAAlD,CAA3B,CACa,EAAvB,EAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAwsGoB,CAprGJ+P,QAAQ,CAACpR,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkDwD,CAAlD,CAA3B,CACa,EAAvB,EAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAmrGoB,CA/pGLgQ,QAAQ,CAACrR,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkDwD,CAAlD,CAA3B,CACVpS,EAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACIoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA8pGoB,CA1oGJiQ,QAAQ,CAACtR,CAAD,CAAKU,CAAL,CACxB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkDwD,CAAlD,CAA3B,CACa,EAAvB,EAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAyoGoB,CArnGLkQ,QAAQ,CAACvR,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf;AAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkDwD,CAAlD,CAA3B,CACa,EAAvB,EAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAA0BxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACtBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CAonGoB,CAhmGLmQ,QAAQ,CAACxR,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAzR,EAAA,CAAe,IAAA6N,EAAf,CAA2B0P,CAAA/pB,KAAA,CAAiB,IAAjB,CAAuB,IAAA0M,EAAA,CAAc,IAAA2N,EAAd,CAAvB,CAAkDwD,CAAlD,CAA3B,CACY,EAAtB,CAAI8E,CAAA,CAAW1E,CAAX,CAAJ,EAAyBxS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrBoQ,EAAJ,EAAQ,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBW,CAAnB,CAHZ,CA+lGoB,CAiQhBN,EAjQgB,CAnBFA,EAmBE,CA7jGJ0Q,QAAQ,EACxB,CACI,IAAA7hB,EAAA,CAAe,IAAA6N,EAAf,CAA2B,CAA3B,CADJ,CA4jGoB,CA7iGJiU,QAAQ,CAAC1R,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmB,CAAnB,CAA3B,CADJ,CA4iGoB,CA7hGNiR,QAAQ,CAAC3R,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CADJ,CA4hGoB,CA7gGLmU,QAAQ,CAAC5R,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAnB,CADJ,CA4gGoB,CA7/FLoU,QAAQ,CAAC7R,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BgI,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAA3B,CADJ,CA4/FoB,CA5+FLqU,QAAQ,CAAC9R,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CAA3B,CADJ,CA2+FoB,CA39FJsU,QAAQ,CAAC/R,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAUxE,CAAV;AAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAAnB,CADJ,CA09FoB,CA18FHuU,QAAQ,CAAChS,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAUxE,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+C,IAAAjD,EAA/C,CAAnB,CADJ,CAy8FoB,CAz7FHwU,QAAQ,CAACjS,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BgI,CAAA,CAAUxE,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAA3B,CADJ,CAw7FoB,CAx6FHyU,QAAQ,CAAClS,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAUxE,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAAnB,CAA3B,CADJ,CAu6FoB,CAZFmD,EAYE,CAXFC,EAWE,CAVFiC,EAUE,CATFlC,EASE,CAv5FJuR,QAAQ,CAACnS,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6BO,CAA7B,CAA+C,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAAnB,CADJ,CAs5FoB,CAt4FH2U,QAAQ,CAACpS,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6BO,CAA7B,CAA+C,IAAAxD,EAA/C,CAAnB,CADJ,CAq4FoB,CAr3FH4U,QAAQ,CAACrS,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BgI,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6BO,CAA7B,CAA+C,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAA3B,CADJ,CAo3FoB,CAp2FH6U,QAAQ,CAACtS,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6BO,CAA7B,CAA+C,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAAnB,CAA3B,CADJ,CAm2FoB,CAhBFoF,EAgBE,CAfFA,EAeE,CAdF/B,EAcE,CAbFA,EAaE,CAn1FNyR,QAAQ,CAACvS,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CADJ,CAk1FoB;AAl0FL+U,QAAQ,CAACxS,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAnB,CADJ,CAi0FoB,CAjzFLgV,QAAQ,CAACzS,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BuI,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAA3B,CADJ,CAgzFoB,CAhyFLiV,QAAQ,CAAC1S,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CAA3B,CADJ,CA+xFoB,CA/wFNkV,QAAQ,CAAC3S,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CADJ,CA8wFoB,CA9vFLmV,QAAQ,CAAC5S,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAnB,CADJ,CA6vFoB,CA7uFLoV,QAAQ,CAAC7S,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BqI,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAA3B,CADJ,CA4uFoB,CA5tFLqV,QAAQ,CAAC9S,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CAA3B,CADJ,CA2tFoB,CA3sFJsV,QAAQ,CAAC/S,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAUxE,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+CO,CAA/C,CAAiE,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAAjE,CAAnB,CADJ,CA0sFoB,CA1rFHuV,QAAQ,CAAChT,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAUxE,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+CO,CAA/C,CAAiE,IAAAxD,EAAjE,CAAnB,CADJ,CAyrFoB;AAzqFHwV,QAAQ,CAACjT,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BgI,CAAA,CAAUxE,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+CO,CAA/C,CAAiE,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAAjE,CAA3B,CADJ,CAwqFoB,CAxpFHyV,QAAQ,CAAClT,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmB+E,CAAA,CAAUxE,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+CO,CAA/C,CAAiE,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAAjE,CAAnB,CAA3B,CADJ,CAupFoB,CAvoFN0V,QAAQ,CAACnT,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBmF,EAAA,CAAU,IAAA/V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CADJ,CAsoFoB,CAtnFL2V,QAAQ,CAACpT,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBmF,EAAA,CAAU,IAAA/V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAnB,CADJ,CAqnFoB,CArmFL4V,QAAQ,CAACrT,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BoI,EAAA,CAAU,IAAA/V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAA3B,CADJ,CAomFoB,CAplFL6V,QAAQ,CAACtT,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBmF,EAAA,CAAU,IAAA/V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CAA3B,CADJ,CAmlFoB,CAyShBuD,EAzSgB,CAjBFA,EAiBE,CAnjFHuS,QAAQ,CAACvT,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BwD,CAA3B,CAA6C,IAAAnR,EAAA,CAAc4Q,CAAd,CAA7C,CADJ,CAkjFoB,CAniFH8S,QAAQ,CAACxT,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBO,CAAnB,CAAqC,IAAAnR,EAAA,CAAc4Q,CAAd,CAArC,CAA3B,CADJ,CAkiFoB,CAlhFL+S,QAAQ,CAACzT,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU7E,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAAnB,CADJ,CAihFoB;AAjgFJiW,QAAQ,CAAC1T,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU7E,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+C,IAAAjD,EAA/C,CAAnB,CADJ,CAggFoB,CAh/EJkW,QAAQ,CAAC3T,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BqI,CAAA,CAAU7E,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAA3B,CADJ,CA++EoB,CA/9EJmW,QAAQ,CAAC5T,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU7E,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+C,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAAnB,CAA3B,CADJ,CA89EoB,CA98EJoW,QAAQ,CAAC7T,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBO,CAAnB,CAAqC,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAArC,CADJ,CA68EoB,CA77EHqW,QAAQ,CAAC9T,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBO,CAAnB,CAAqC,IAAAxD,EAArC,CADJ,CA47EoB,CA56EHsW,QAAQ,EACzB,CACI,IAAAnkB,EAAA,CAAe,IAAA6N,EAAf,CAA2BwD,CAA3B,CAA6C,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAA7C,CADJ,CA26EoB,CA35EHuW,QAAQ,CAAChU,CAAD,CAAKU,CAAL,CACzB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBO,CAAnB,CAAqC,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAArC,CAA3B,CADJ,CA05EoB,CA14ELwW,QAAQ,CAACjU,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6BO,CAA7B,CAA+C,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAAnB,CADJ,CAy4EoB,CAz3EJyW,QAAQ,CAAClU,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6BO,CAA7B,CAA+C,IAAAxD,EAA/C,CAAnB,CADJ,CAw3EoB,CAx2EJ0W,QAAQ,CAACnU,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BqI,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6BO,CAA7B,CAA+C,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAA3B,CADJ,CAu2EoB;AAv1EJ2W,QAAQ,CAACpU,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6BO,CAA7B,CAA+C,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAA/C,CAAnB,CAA3B,CADJ,CAs1EoB,CAt0EL4W,QAAQ,CAACrU,CAAD,CAAKU,CAAL,CACvB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU7E,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+CO,CAA/C,CAAiE,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAAjE,CAAnB,CADJ,CAq0EoB,CArzEJ6W,QAAQ,CAACtU,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU7E,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+CO,CAA/C,CAAiE,IAAAxD,EAAjE,CAAnB,CADJ,CAozEoB,CApyEJ8W,QAAQ,CAACvU,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2BqI,CAAA,CAAU7E,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+CO,CAA/C,CAAiE,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAAjE,CAA3B,CADJ,CAmyEoB,CAnxEJ+W,QAAQ,CAACxU,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU7E,CAAV,CAA4B,IAAAnR,EAAA,CAAc4Q,CAAd,CAA5B,CAA+CO,CAA/C,CAAiE,IAAAnR,EAAA,CAAc,IAAA2N,EAAd,CAAjE,CAAnB,CAA3B,CADJ,CAkxEoB,CA6ThByD,EA7TgB,CAlBFA,EAkBE,CAlvEJuT,QAAQ,EACxB,CACI,IAAA7kB,EAAA,CAAe,IAAA6N,EAAf,CAA2BwD,CAA3B,CADJ,CAivEoB,CAluEJyT,QAAQ,CAAC1U,CAAD,CAAKU,CAAL,CACxB,CACI,IAAA9Q,EAAA,CAAe,IAAA6N,EAAf,CAA2B,IAAA7N,EAAA,CAAe8Q,CAAf,CAAmBO,CAAnB,CAA3B,CADJ,CAiuEoB,CAiUhBE,EAjUgB,CAkUhBK,EAlUgB,CAmUhBC,EAnUgB,CAoUhBC,EApUgB,CAqUhBE,EArUgB,CAsUhBE,EAtUgB,CAuUhBC,EAvUgB,CAwUhBC,EAxUgB,CApEFb,EAoEE,CAnEFK,EAmEE,CAlEFC,EAkEE,CAjEFC,EAiEE,CAxDFE,EAwDE,CAvDFE,EAuDE,CAtDFC,EAsDE,CArDFC,EAqDE,CAhEFb,EAgEE,CA/DFK,EA+DE,CA9DFC,EA8DE,CA7DFC,EA6DE,CApDFE,EAoDE,CAnDFE,EAmDE,CAlDFC,EAkDE,CAjDFC,EAiDE,CA5DFb,EA4DE,CA3DFK,EA2DE,CA1DFC,EA0DE,CAzDFC,EAyDE,CAhDFE,EAgDE,CA/CFE,EA+CE,CA9CFC,EA8CE,CA7CFC,EA6CE,CAiWhBC,EAjWgB,CAkWhBE,EAlWgB,CAmWhBC,EAnWgB,CAoWhBC,EApWgB,CAqWhBE,EArWgB,CAsWhBC,EAtWgB;AAuWhBC,EAvWgB,CAwWhBC,EAxWgB,CA5CFT,EA4CE,CA3CFE,EA2CE,CA1CFC,EA0CE,CAzCFC,EAyCE,CAhCFE,EAgCE,CA/BFC,EA+BE,CA9BFC,EA8BE,CA7BFC,EA6BE,CAxCFT,EAwCE,CAvCFE,EAuCE,CAtCFC,EAsCE,CArCFC,EAqCE,CA5BFE,EA4BE,CA3BFC,EA2BE,CA1BFC,EA0BE,CAzBFC,EAyBE,CApCFT,EAoCE,CAnCFE,EAmCE,CAlCFC,EAkCE,CAjCFC,EAiCE,CAxBFE,EAwBE,CAvBFC,EAuBE,CAtBFC,EAsBE,CArBFC,EAqBE,CALFG,EAKE,CAJFA,EAIE,CAl3DL8R,QAAQ,CAAC3U,CAAD,CAAKU,CAAL,CACvB,CACoD,CAAhD,EAAI+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAJ,EAAmD5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADvD,CAi3DoB,CAt2DLskB,QAAQ,CAAC5U,CAAD,CAAKU,CAAL,CACvB,CACuE,CAAnE,EAAI+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAA0CoE,CAA1C,CAAJ,EAAsEhT,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAD1E,CAq2DoB,CA11DLukB,QAAQ,EACvB,CACIhmB,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADJ,CAy1DoB,CA90DLwkB,QAAQ,EACvB,CACIjmB,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADJ,CA60DoB,CAl0DLykB,QAAQ,CAAC/U,CAAD,CAAKU,CAAL,CACvB,CACoD,CAAhD,EAAI+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAJ,EAAmD5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADvD,CAi0DoB,CAtzDL0kB,QAAQ,CAAChV,CAAD,CAAKU,CAAL,CACvB,CACuE,CAAnE,EAAI+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAA0CoE,CAA1C,CAAJ,EAAsEhT,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAD1E,CAqzDoB,CAHFwS,EAGE,CAFFA,EAEE,CA1yDLmS,QAAQ,CAACjV,CAAD,CAAKU,CAAL,CACvB,CACmE,CAA/D,EAAI+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAJ,EAAkE5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADtE,CAyyDoB,CA9xDL4kB,QAAQ,CAAClV,CAAD,CAAKU,CAAL,CACvB,CAC+E,CAA3E,EAAI+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6BuF,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CAA7B,CAAJ,EAA8E5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX;AAAwB,CAAxB,CADlF,CA6xDoB,CAlxDL6kB,QAAQ,EACvB,CACItmB,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADJ,CAixDoB,CAtwDL8kB,QAAQ,EACvB,CACIvmB,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADJ,CAqwDoB,CA1vDL+kB,QAAQ,CAACrV,CAAD,CAAKU,CAAL,CACvB,CACmE,CAA/D,EAAI+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAJ,EAAkE5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADtE,CAyvDoB,CA9uDLglB,QAAQ,CAACtV,CAAD,CAAKU,CAAL,CACvB,CAC+E,CAA3E,EAAI+E,CAAA,CAAU,IAAA3V,EAAA,CAAc4Q,CAAd,CAAV,CAA6BuF,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CAA7B,CAAJ,EAA8E5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CADlF,CA6uDoB,CAluDNilB,QAAQ,CAACvV,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAU,IAAA7V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAnB,CADJ,CAiuDoB,CAttDN+X,QAAQ,CAACxV,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAU,IAAA7V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAA0CoE,CAA1C,CAAnB,CADJ,CAqtDoB,CA1sDL4T,QAAQ,CAACzV,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACwB,EAAlC,EAAI+E,CAAA,CAAUpE,CAAV,CAAe,IAAA5D,EAAf,CAAJ,EAAqC5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrC,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAUtE,CAAV,CAAe,IAAA5D,EAAf,CAAnB,CAHJ,CAysDoB,CA5rDLiY,QAAQ,CAAC1V,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAA3D,EAAN2D,CAAmBS,CACI,EAA3B,EAAI4D,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAUtE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CA2rDoB,CA7qDLuU,QAAQ,CAAC3V,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAU,IAAA7V,EAAA,CAAc4Q,CAAd,CAAV;AAA6B,IAAAjD,EAA7B,CAAnB,CAFJ,CA4qDoB,CAhqDLmY,QAAQ,CAAC5V,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAU,IAAA7V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAA0CoE,CAA1C,CAAnB,CAFJ,CA+pDoB,CAnpDLgU,QAAQ,CAAC7V,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACwB,EAAlC,EAAI+E,CAAA,CAAUpE,CAAV,CAAe,IAAA5D,EAAf,CAAJ,EAAqC5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrC,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAUtE,CAAV,CAAe,IAAA5D,EAAf,CAAnB,CAHJ,CAkpDoB,CAroDLqY,QAAQ,CAAC9V,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAA3D,EAAN2D,CAAmBS,CACI,EAA3B,EAAI4D,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAUtE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CAooDoB,CAtnDN2U,QAAQ,CAAC/V,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAU,IAAA7V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CADJ,CAqnDoB,CA1mDNuY,QAAQ,CAAChW,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAU,IAAA7V,EAAA,CAAc4Q,CAAd,CAAV,CAA6BuF,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CAA7B,CAAnB,CADJ,CAymDoB,CA9lDLwY,QAAQ,CAACjW,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAUtE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CA6lDoB,CA/kDL8U,QAAQ,CAAClW,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM6E,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV;AAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAUtE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CA8kDoB,CAhkDL+U,QAAQ,CAACnW,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAU,IAAA7V,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CAFJ,CA+jDoB,CAnjDL2Y,QAAQ,CAACpW,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAU,IAAA7V,EAAA,CAAc4Q,CAAd,CAAV,CAA6BuF,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CAA7B,CAAnB,CAFJ,CAkjDoB,CAtiDL4Y,QAAQ,CAACrW,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAUtE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CAqiDoB,CAvhDLkV,QAAQ,CAACtW,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM6E,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBiF,CAAA,CAAUtE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CAshDoB,CAxgDNmV,QAAQ,CAACvW,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAnB,CADJ,CAugDoB,CA5/CN+Y,QAAQ,CAACxW,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAA0CoE,CAA1C,CAAnB,CADJ,CA2/CoB,CAh/CL4U,QAAQ,CAACzW,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACwB,EAAlC,EAAI+E,CAAA,CAAUpE,CAAV,CAAe,IAAA5D,EAAf,CAAJ;AAAqC5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrC,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU3E,CAAV,CAAe,IAAA5D,EAAf,CAAnB,CAHJ,CA++CoB,CAl+CLiZ,QAAQ,CAAC1W,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAA3D,EAAN2D,CAAmBS,CACI,EAA3B,EAAI4D,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU3E,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CAi+CoB,CAn9CLuV,QAAQ,CAAC3W,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAnB,CAFJ,CAk9CoB,CAt8CLmZ,QAAQ,CAAC5W,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAA0CoE,CAA1C,CAAnB,CAFJ,CAq8CoB,CAz7CLgV,QAAQ,CAAC7W,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACwB,EAAlC,EAAI+E,CAAA,CAAUpE,CAAV,CAAe,IAAA5D,EAAf,CAAJ,EAAqC5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrC,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU3E,CAAV,CAAe,IAAA5D,EAAf,CAAnB,CAHJ,CAw7CoB,CA36CLqZ,QAAQ,CAAC9W,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAA3D,EAAN2D,CAAmBS,CACI,EAA3B,EAAI4D,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU3E,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CA06CoB,CA55CN2V,QAAQ,CAAC/W,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CADJ,CA25CoB,CAh5CNuZ,QAAQ,CAAChX,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV;AAA6BuF,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CAA7B,CAAnB,CADJ,CA+4CoB,CAp4CLwZ,QAAQ,CAACjX,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU3E,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CAm4CoB,CAr3CL8V,QAAQ,CAAClX,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM6E,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU3E,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CAo3CoB,CAt2CL+V,QAAQ,CAACnX,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CAFJ,CAq2CoB,CAz1CL2Z,QAAQ,CAACpX,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU,IAAAlW,EAAA,CAAc4Q,CAAd,CAAV,CAA6BuF,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CAA7B,CAAnB,CAFJ,CAw1CoB,CA50CL4Z,QAAQ,CAACrX,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU3E,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CA20CoB,CA7zCLkW,QAAQ,CAACtX,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM6E,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV;AAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBsF,CAAA,CAAU3E,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CA4zCoB,CA9yCNmW,QAAQ,CAACvX,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAnB,CADJ,CA6yCoB,CAlyCN+Z,QAAQ,CAACxX,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAA0CoE,CAA1C,CAAnB,CADJ,CAiyCoB,CAtxCL4V,QAAQ,CAACzX,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACwB,EAAlC,EAAI+E,CAAA,CAAUpE,CAAV,CAAe,IAAA5D,EAAf,CAAJ,EAAqC5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrC,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAUzE,CAAV,CAAe,IAAA5D,EAAf,CAAnB,CAHJ,CAqxCoB,CAxwCLia,QAAQ,CAAC1X,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CAC2C,EAArD,EAAI+E,CAAA,CAAUpE,CAAV,CAAe,IAAA5D,EAAf,CAA4BoE,CAA5B,CAAJ,EAAwDhT,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACxD,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAUzE,CAAV,CAAe,IAAA5D,EAAf,CAA4BoE,CAA5B,CAAnB,CAHJ,CAuwCoB,CA1vCL8V,QAAQ,CAAC3X,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAAnB,CAFJ,CAyvCoB,CA7uCLma,QAAQ,CAAC5X,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAAjD,EAA7B,CAA0CoE,CAA1C,CAAnB,CAFJ,CA4uCoB,CAhuCLgW,QAAQ,CAAC7X,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACwB,EAAlC,EAAI+E,CAAA,CAAUpE,CAAV,CAAe,IAAA5D,EAAf,CAAJ,EAAqC5O,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACrC,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAUzE,CAAV,CAAe,IAAA5D,EAAf,CAAnB,CAHJ,CA+tCoB;AAltCLqa,QAAQ,CAAC9X,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAA3D,EAAN2D,CAAmBS,CACI,EAA3B,EAAI4D,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAUzE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CAitCoB,CAnsCN2W,QAAQ,CAAC/X,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CADJ,CAksCoB,CAvrCNua,QAAQ,CAAChY,CAAD,CAAKU,CAAL,CACtB,CACI,IAAA9Q,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6BuF,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CAA7B,CAAnB,CADJ,CAsrCoB,CA3qCLwa,QAAQ,CAACjY,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAUzE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CA0qCoB,CA5pCL8W,QAAQ,CAAClY,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM6E,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAUzE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CA2pCoB,CA7oCL+W,QAAQ,CAACnY,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV,CAA6B,IAAA5Q,EAAA,CAAc,IAAA2N,EAAd,CAA7B,CAAnB,CAFJ,CA4oCoB,CAhoCL2a,QAAQ,CAACpY,CAAD,CAAKU,CAAL,CACvB,CACI7R,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CACA,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAU,IAAAhW,EAAA,CAAc4Q,CAAd,CAAV;AAA6BuF,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CAA7B,CAAnB,CAFJ,CA+nCoB,CAnnCL4a,QAAQ,CAACrY,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM,IAAAtR,EAAA,CAAc,IAAA2N,EAAd,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAUzE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CAknCoB,CApmCLkX,QAAQ,CAACtY,CAAD,CAAKU,CAAL,CACvB,CACQW,CAAAA,CAAM,IAAAvR,EAAA,CAAc4Q,CAAd,CACV,KAAIU,EAAM6E,CAAA,CAAW,IAAAnW,EAAA,CAAc,IAAA2N,EAAd,CAAX,CACiB,EAA3B,EAAIgI,CAAA,CAAUpE,CAAV,CAAeD,CAAf,CAAJ,EAA8BvS,CAAA,CAAAA,IAAA,CAAW,IAAAyB,EAAX,CAAwB,CAAxB,CAC9B,KAAAV,EAAA,CAAe8Q,CAAf,CAAmBoF,CAAA,CAAUzE,CAAV,CAAeD,CAAf,CAAnB,CAJJ,CAmmCoB,CAichBuB,CAjcgB,CAkchBA,CAlcgB,CAmchBA,CAncgB,CAochBA,CApcgB,CAqchBA,CArcgB,CAschBA,CAtcgB,CAuchBA,CAvcgB,CAwchBA,CAxcgB,CAychBA,CAzcgB,CA0chBA,CA1cgB,CA2chBA,CA3cgB,CA4chBA,CA5cgB,CA6chBA,CA7cgB,CA8chBA,CA9cgB,CA+chBA,CA/cgB,CAgdhBA,CAhdgB,CAidhBA,CAjdgB,CAkdhBA,CAldgB,CAmdhBA,CAndgB,CAodhBA,CApdgB,CAqdhBA,CArdgB,CAsdhBA,CAtdgB,CAudhBA,CAvdgB,CAwdhBA,CAxdgB,CAydhBA,CAzdgB,CA0dhBA,CA1dgB,CA2dhBA,CA3dgB,CA4dhBA,CA5dgB,CA6dhBA,CA7dgB,CA8dhBA,CA9dgB,CA+dhBA,CA/dgB,CAgehBA,CAhegB,CAiehBA,CAjegB,CAkehBA,CAlegB,CAmehBA,CAnegB,CAoehBA,CApegB,CAqehBA,CAregB,CAsehBA,CAtegB,CAuehBA,CAvegB,CAwehBA,CAxegB,CAyehBA,CAzegB,CA0ehBA,CA1egB,CA2ehBA,CA3egB,CA4ehBA,CA5egB,CA6ehBA,CA7egB,CA8ehBA,CA9egB,CA+ehBA,CA/egB,CAgfhBA,CAhfgB,CAifhBA,CAjfgB,CAkfhBA,CAlfgB,CAmfhBA,CAnfgB,CAofhBA,CApfgB,CAqfhBA,CArfgB,CAsfhBA,CAtfgB,CAufhBA,CAvfgB,CAwfhBA,CAxfgB,CAyfhBA,CAzfgB,CA0fhBA,CA1fgB,CA2fhBA,CA3fgB,CA4fhBA,CA5fgB,CA6fhBA,CA7fgB,CA8fhBA,CA9fgB,CA+fhBA,CA/fgB,CAggBhBA,CAhgBgB,CAApB,CAmgBAC,GAAmB,CAxlDJ2V,QAAQ,CAACvY,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAulDmB,CA5kDHwY,QAAQ,CAACxY,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA2kDmB,CAhkDJyY,QAAQ,CAACzY,CAAD,CACvB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CA+jDmB,CApjDH0Y,QAAQ,CAAC1Y,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAmjDmB,CAxiDJ2Y,QAAQ,CAAC3Y,CAAD,CAAK4Y,CAAL,CACvB,CACI,OAAOA,CAAP,EACA,KAnpVgBC,CAmpVhB,CACoB,CAAA,CAAA,IAAA/oB,EAAA,CAAc,IAAA2N,EAAd,CA/9MZltB,EAAJ,CAzsIYuoC,CAysIZ,GA+9MAC,IA/9M6Bhb,EAA7B,EAA2C,OAA3C,CACIxtB;CAAJ,CA7rIYuoC,MA6rIZ,GA89MAC,IA99M6Bhb,EAA7B,EAA2C,OAA3C,CA+9MA,MACJ,SACI,IAAAd,EAAA,CAAiB+C,CAAjB,CALJ,CADJ,CAuiDmB,CArhDJgZ,QAAQ,CAAChZ,CAAD,CAAK4Y,CAAL,CACvB,CACI,OAAOA,CAAP,EACA,KAtqVgBC,CAsqVhB,CAjgNQh7B,CAAAA,CAAQ,CAkgNeo7B,KAjgNvBlb,EAAJ,CAruIYkB,MAquIZ,GAAoCphB,CAApC,EA/sIYq7B,CA+sIZ,CAigN2BD,KAhgNvBlb,EAAJ,CAztIWkB,MAytIX,GAAoCphB,CAApC,EArsIYq7B,KAqsIZ,CAggNA,KAAAtpB,EAAA,CAAe,IAAA6N,EAAf,CA//MO5f,CA+/MP,CACA,MACJ,SACI,IAAAof,EAAA,CAAiB+C,CAAjB,CALJ,CADJ,CAohDmB,CAlgDHmZ,QAAQ,CAACnZ,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAigDmB,CAt/CHoZ,QAAQ,CAACpZ,CAAD,CACxB,CACI,IAAA/C,EAAA,CAAiB+C,CAAjB,CADJ,CAq/CmB,CAmCf7iB;QAnBEk8B,GAmBS,CAACC,CAAD,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,KAAN,CAAaA,CAAb,CAlsYQrwB,GAksYR,CAGA,KAAAxR,EAAA,CADA,IAAA8hC,EACA,CADc,IAGd,KAAAC,EAAA,CAAe,CAACF,CAAA,KAChB,KAAAG,EAAA,CAAe,CAACH,CAAA,KAchB,KAAAI,EAAA,CAAiBJ,CAAA,MACY,SAA7B,EAAI,MAAO,KAAAI,EAAX,GACI,IAAAA,EADJ,CACqBzhC,IAAA,CAAK,IAAAyhC,EAAL,CADrB,CAIA,KAAAC,EAAA,CAAiBL,CAAA,KACjB,KAAAxmC,EAAA,CAAiB8mC,EAAA,CAAgB,IAAAD,EAAhB,CAEjB,IAAI,IAAAA,EAAJ,CAAoB,CACZE,CAAAA,CAAW,IAAAF,EAOf,KAAIG,EAAWC,EAAA,CAAiB,IAAAjnC,EAAjB,CAp+gBPknC,OAq+gBR,EAAIF,CAAJ,EAl+gBQE,KAk+gBR,EAAuCF,CAAvC,GACID,CADJ,CACeI,EAAA,EADf,CAC6E,uBAD7E,CACmF,IAAAN,EADnF,CAC4L,wCAD5L,CAGA,KAAIO,EAAM,IACVC,GAAA,CAAgBN,CAAhB,CAA0B,IAA1B,CAAgC,CAAA,CAAhC,CAAsCO,QAAiB,CAAC5kC,CAAD,CAAO6kC,CAAP,CAAkB7jC,CAAlB,CAA8B,CACjDA,CAyExC,EAzEQ0jC,CA0EJt2B,GAAA,CAAY,qCAAZ,CA1EoCpN,CA0EpC,CAAiE,IAAjE,CA1EmBhB,CA0EnB,CAA+E,GAA/E,CACA,CA3EI0kC,CA2EJP,EAAA,CAAiB,IAFrB,GAKIW,EAAA,CA9EIJ,CA8EyBt8B,GAA7B,CA9EmBpI,CA8EnB,CA9EyB6kC,CA8EzB,CAEA,CAAA,CADItkC,CACJ,CADewkC,EAAA,CA/EI/kC,CA+EJ,CA/EU6kC,CA+EV,CACf,GAhFIH,CAiFAX,EACA,CADcxjC,CAAAyB,GACd,CAlFA0iC,CAkFAziC,EAAA,CAAgB1B,CAAA0B,EAFpB,EAhFIyiC,CAoFAP,EAJJ,CAIqB,IAXzB,CAcAa,GAAA,CAvFQN,CAuFR,CAxFyF,CAArF,CAbgB,CA7BxB;AApBmBluB,EAAA5O,CAAjBi8B,EAAiBj8B,CAAAA,CAAAA,CA6EnB,GAAA,UAAA,GAAA,CAAA4P,QAAO,CAACtO,CAAD,CAAMD,CAAN,CAAWD,CAAX,CAAgBD,CAAhB,CACP,CACI,IAAAE,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CACXi8B,GAAA,CAAAA,IAAA,CAJJ,CAeA,GAAA,UAAA,GAAA,CAAAz1B,QAAO,EACP,CACQ,IAAAtN,EAAJ,GACQ,IAAA8G,EAOJ,EANIk8B,EAAA,CAAA,IAAAl8B,EAAA,CAAoB,IAAAhB,GAApB,CAA6B,IAAAi8B,EAA7B,CAA2C,IAAAC,EAA3C,CAAyD,IAAAhiC,EAAzD,CAMJ,CAAA,OAAO,IAAAA,EARX,CAUA,OAAO,CAAA,CAXX,CA2BA,GAAA,UAAA,GAAA,CAAAuN,QAAS,EACT,CACI,MAAO,CAAA,CADX,CAwCAw1B;QAAA,GAAO,CAAPA,CAAO,CACP,CACI,GAAI,CAAC/1B,EAAA,CAAAA,CAAA,CAAL,CAAqB,CACjB,GAAI,CAAAk1B,EAAJ,CAAoB,CAIhB,GAAI,CAAC,CAAAJ,EAAL,EAAoB,CAAC,CAAA96B,EAArB,CAA+B,MAK1B,EAAAg7B,EAAL,GACI,CAAAA,EADJ,CACmB,CAAAF,EAAAjmC,OADnB,CAGA,IAAI,CAAAimC,EAAAjmC,OAAJ,EAA0B,CAAAmmC,EAA1B,CAOIl1B,EAAA,CAAAA,CAAA,CAAc,YAAd,CAr4fLyQ,CAAA,CAq4fgD,CAAAukB,EAAAjmC,OAr4fhD,CAAa,CAAb,CAAgB,CAAA,CAAhB,CAq4fK,CAAiE,mCAAjE,CAr4fL0hB,CAAA,CAq4f0H,CAAAykB,EAr4f1H,CAAa,CAAb,CAAgB,CAAA,CAAhB,CAq4fK,CAAqI,GAArI,CAPJ,KASK,CAAgBD,IAAAA,EAAAA,CAAAA,EAuC7B,IAAI5mB,EAAA,CAvCa8nB,CAuCbj8B,EAAA,CAAmBoU,CAAnB,CAvCa6nB,CAuCYjB,EAAzB,CAAuC7jB,EAAvC,CAAJ,CAAkE,CAE9D,IAAInmB,CACJ,KAAKA,CAAL,CAAS,CAAT,CAAYA,CAAZ,CA1CairC,CA0CGnB,EAAAjmC,OAAhB,CAAoC7D,CAAA,EAApC,CACIkgB,EAAA,CA3CS+qB,CA2CTj8B,EAAA,CAAuBoU,CAAvB,CAA8BpjB,CAA9B,CA3CSirC,CA2CwBnB,EAAA,CAAY9pC,CAAZ,CAAjC,CAEJ,EAAA,CAAO,CAAA,CANuD,CAAlE,IAYA,EAAA,CAAO,CAAA,CAnDM,IAAI,CAAJ,CAA+B,CAE5BkrC,CAAAA,CAAU,EACe,SAA7B,EAAI,MAAO,EAAAjB,EAAX,CACIiB,CAAAjiC,KAAA,CAAa,CAAAghC,EAAb,CADJ,CAE6B,IAF7B,EAEW,CAAAA,EAFX,EAEqC,CAAAA,EAAApmC,OAFrC,GAGIqnC,CAHJ,CAGc,CAAAjB,EAHd,CAKA,KAASjqC,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoBkrC,CAAArnC,OAApB,CAAoC7D,CAAA,EAApC,CAAyC,CA5tVrD,IA6tVgBmrC,IAAAA,EAAAA,CAAAA,CAAc,EAAAD,CAAA,CAAQlrC,CAAR,CAAdmrC,CA4DFn8B,EAAAA,CAAAA,EA5DEm8B,CA4DqCnB,EAAAA,CAAAA,EA5DrCmB,CA/tVZC,EAAU,EA+tVED,CA9tVZ1oB,EA0xVmC,CAAAsnB,EA1xVnCtnB,GAAkB,CAAAV,EACtB,CAAc,CAAd,CAAOsB,CAAP,EAAmBZ,CAAnB,CAA4B,CAAAL,EAAAve,OAA5B,CAAA,CACIunC,CAAAniC,KAAA,CAAa,CAAAmZ,EAAA,CAAgBK,CAAA,EAAhB,CAAb,CACA,CAAAY,CAAA,EAtUcpB,KA8lWlBjT,EAAAA,CAAAA,CAAAA,EAA+Bg7B,EAAAA,CAAAA,CAAAA,EAlwV3BhqC,EAAAA,CAAI,CAER,KAgwVyBojB,CAhwVzB;AADsB,CAAArB,EACtB,CAAc,CAAd,CAAOsB,CAAP,EAAmBZ,CAAnB,CAA4B,CAAAL,EAAAve,OAA5B,CAAA,CAAoD,CAC5Cwe,CAAAA,CAAQ+oB,CAAA,CAAQprC,CAAA,EAAR,CAEZ,IAAI,CAACqiB,CAAL,CAAY,KAMZ,EAAAD,EAAA,CAAgBK,CAAA,EAAhB,CAAA,CAA4BJ,CAC5BgB,EAAA,EAxWcpB,KA8VkC,CAksVC,CAcrC,OAAO,CAAA6nB,EAtBqB,CAA/B,CArBW,CA+CpB70B,EAAA,CAAAA,CAAA,CAhDiB,CADzB,CAoIJyM,EAAA,CA5BIZ,QAAW,EACX,CAEI,IADA,IAAIuqB,EAAQ36B,CAAA,CAA6BsQ,QAA7B,CAAuCxQ,CAAvC,CAAuD,KAAvD,CAAZ,CACS86B,EAAO,CAAhB,CAAmBA,CAAnB,CAA0BD,CAAAxnC,OAA1B,CAAwCynC,CAAA,EAAxC,CAAgD,CAC5C,IAAIC,EAAOF,CAAA,CAAMC,CAAN,CAAX,CACIzB,EAAWx4B,EAAA,CAA4Bk6B,CAA5B,CACXd,EAAAA,CAAM,IAAIb,EAAJ,CAAaC,CAAb,CACVzoB,GAAA,CAAgCqpB,CAAhC,CAAqCc,CAArC,CAJ4C,CAFpD,CA2BJ,CA0BI79B;QAjBE89B,GAiBS,CAACC,CAAD,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,KAAN,CAAaA,CAAb,CAGA,KAAAzjC,EAAA,CADA,IAAAU,GACA,CADa,IAGb,KAAAgjC,EAAA,CAAe,CAACD,CAAA,KAChB,KAAAE,EAAA,CAAe,CAACF,CAAA,KAEhB,KAAAxjC,GAAA,CAAgBwjC,CAAA,KAChB,KAAAvjC,GAAA,CAAgBujC,CAAA,KACK,KAArB,EAAI,IAAAxjC,GAAJ,GAA2B,IAAAA,GAA3B,CAA2C,CAAC,IAAAA,GAA5C,CACqB,KAArB,EAAI,IAAAC,GAAJ,GAA2B,IAAAA,GAA3B,CAA2C,CAAC,IAAAA,GAA5C,CAGA,KAAA0jC,EAAA,CAAkB,IAAAxf,EAAlB,CAAgC,CAAA,CAEhC,KAAA8d,EAAA,CAAiBuB,CAAA,KACjB,KAAApoC,EAAA,CAAiB8mC,EAAA,CAAgB,IAAAD,EAAhB,CAEjB,IAAI,IAAAA,EAAJ,CAAoB,CACZE,CAAAA,CAAW,IAAAF,EAOf,KAAIG,EAAWC,EAAA,CAAiB,IAAAjnC,EAAjB,CAzwhBPknC,OA0whBR,EAAIF,CAAJ,EAvwhBQE,KAuwhBR,EAAuCF,CAAvC,GACID,CADJ,CACeI,EAAA,EADf,CAC6E,uBAD7E,CACmF,IAAAN,EADnF,CAC4L,wCAD5L,CAGA,KAAI2B,EAAM,IACVnB,GAAA,CAAgBN,CAAhB,CAA0B,IAA1B,CAAgC,CAAA,CAAhC,CAAsCO,QAAiB,CAAC5kC,CAAD,CAAO6kC,CAAP,CAAkB7jC,CAAlB,CAA8B,CACjDA,CAkFxC,EAlFQ8kC,CAmFJ13B,GAAA,CAAY,qCAAZ,CAnFoCpN,CAmFpC,CAAiE,IAAjE,CAnFmBhB,CAmFnB,CAA+E,GAA/E,CACA,CApFI8lC,CAoFJ3B,EAAA,CAAiB,IAFrB,GAKIW,EAAA,CAvFIgB,CAuFyB19B,GAA7B,CAvFmBpI,CAuFnB,CAvFyB6kC,CAuFzB,CAEA,CAAA,CADItkC,CACJ,CADewkC,EAAA,CAxFI/kC,CAwFJ;AAxFU6kC,CAwFV,CACf,GAzFIiB,CA0FAnjC,GAGA,CAHapC,CAAAoC,GAGb,CA7FAmjC,CA2FA7jC,EAEA,CAFgB1B,CAAA0B,EAEhB,CADqB,IACrB,EA7FA6jC,CA4FI5jC,GACJ,GA7FA4jC,CA4F2B5jC,GAC3B,CAD2C3B,CAAA2B,GAC3C,EAAqB,IAArB,EA7FA4jC,CA6FI3jC,GAAJ,GA7FA2jC,CA6F2B3jC,GAA3B,CAA2C5B,CAAA4B,GAA3C,CAJJ,EAzFI2jC,CA+FA3B,EANJ,CAMqB,IAbzB,CAgBA4B,GAAA,CAlGQD,CAkGR,CAnGyF,CAArF,CAbgB,CApBxB,CAlBmBtvB,EAAA5O,CAAjB69B,EAAiB79B,CAAAA,CAAAA,CAkEnB,GAAA,UAAA,GAAA,CAAA4P,QAAO,CAACtO,CAAD,CAAMD,CAAN,CAAWD,CAAX,CAAgBD,CAAhB,CACP,CACI,IAAAE,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CACXg9B,GAAA,CAAAA,IAAA,CAJJ,CAeA,GAAA,UAAA,GAAA,CAAAx2B,QAAO,CAACjN,CAAD,CAAOqV,CAAP,CACP,CACQ,IAAA1V,EAAJ,GACQ,IAAA8G,EAOJ,EANIk8B,EAAA,CAAA,IAAAl8B,EAAA,CAAoB,IAAAhB,GAApB,CAA6B,IAAA49B,EAA7B,CAA2C,IAAAC,EAA3C,CAAyD,IAAA3jC,EAAzD,CAMJ,CAAA,OAAO,IAAAA,EARX,CAUK0V,EAAL,EAMI,IAAAjB,MAAA,EAEJ,OAAO,CAAA,CAnBX,CA8BA,GAAA,UAAA,GAAA,CAAAlH,QAAS,EACT,CAOI,MAAO,CAAA,CAPX,CAgDAu2B;QAAA,GAAO,CAAPA,CAAO,CACP,CACI,GAAK,CAAA98B,EAAL,GAEI,CAAC,CAAA48B,EAOD,EAPoB,CAAAD,EAOpB,GANIxoB,EAAA,CAAA,CAAAnU,EAAA,CAAmB,CAAA08B,EAAnB,CAAiC,CAAAC,EAAjC,CArkUAI,CAqkUA,CAAJ,CACI,CAAAH,EADJ,CACsB,CAAA,CADtB,CAGI,CAAAD,EAHJ,CAGmB,CAGnB,EAAA,CAAC32B,EAAA,CAAAA,CAAA,CATL,EASqB,CACjB,GAAI,CAAC,CAAA42B,EAAL,CAnjcJjjC,CAAA,CAojcwBjI,kBApjcxB,CAmjcI,KAGK,IAAI,CAAAwpC,EAAJ,CAAoB,CAIrB,GAAI,CAAC,CAAAxhC,GAAL,CAAiB,MAEbsjC,GAAA,CAAAA,CAAA,CAAe,CAAAtjC,GAAf,CAA2B,CAAAT,GAA3B,CAA0C,CAAAC,GAA1C,CAAyD,CAAAwjC,EAAzD,CAAJ,CACI,CAAA/kC,OAAA,CAAY,gBAAZ,CAA+B,CAAAtD,EAA/B,CAAgD,GAAhD,CADJ,CAGI,CAAA8Q,GAAA,CAAY,uBAAZ,CAAsC,CAAA9Q,EAAtC,CAAuD,GAAvD,CATiB,CAkBzB,CAAA+oB,EAAA,CAAc,CAAA,CACdnX,GAAA,CAAAA,CAAA,CAvBiB,CAVzB;AA0CA,EAAA,UAAA,MAAA,CAAAwH,QAAK,EACL,CACI,GAAI,IAAAmvB,EAAJ,EAAuB,CAAC,IAAAxf,EAAxB,CAAqC,CAMjCpd,IAAAA,EAAAA,IAAAA,EAAAA,CAAoB08B,EAAAA,IAAAA,EAApB18B,CAAkC28B,EAAAA,IAAAA,EAAlC38B,CApnWA8X,EAAM1D,CAAN0D,CA5Oe1C,KA8OnB,KADahB,CACb,IADsB,CAAArB,EACtB,CAAc,CAAd,CAAOsB,CAAP,EAAmBZ,CAAnB,CAA4B,CAAAL,EAAAve,OAA5B,CAAA,CAAoD,CAChDooC,IAAAA,EAAAA,CAAA7pB,EAAA6pB,CAAgBxpB,CAAhBwpB,CAAAA,CAAkC5oB,EAAAA,CAAlC4oB,CAutBOC,EA05UyCA,CA15UzCA,EAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAU,CAAV,CAAAA,CAKXplB,EAAA,CAAMA,CAAN,EAAa,CACDpiB,KAAAA,EAAZ,GAAIynC,CAAJ,GAAuBA,CAAvB,CAA6B,CAAA9oB,KAA7B,CAQc,EAAd,CAAI6oB,CAAJ,EAAmBA,CAAnB,EAA8B,CAAC1Y,CAA/B,GACI0Y,CADJ,EACetrB,CADf,CAGAsrB,EAAA,CAAUjqC,IAAAE,MAAA,CAAWF,IAAAe,IAAA,CAASkpC,CAAT,CAAX,CAAV,CAA0CtrB,CAE1C,KAAK,IAAI5gB,EAAI8mB,CAAb,CAAkBqlB,CAAA,EAAlB,EAA2BnsC,CAA3B,CAA+B,CAAAqjB,KAA/B,CAA0CrjB,CAAA,EAA1C,CAA+C,CAAAqkB,EAAA,CAAqB6nB,CAArB,CAA8BplB,CAA9B,CAAmC,CAAA1D,EAAnC,CAA+C0D,CAA/C,CAzuB3CzD,EAAA,EAnPcpB,KAoPdQ,EAAA,EACAqE,EAAA,CAAM,CAJ0C,CAmnW5C,IAAApe,GAAJ,EACIsjC,EAAA,CAAAA,IAAA,CAAe,IAAAtjC,GAAf,CAA2B,IAAAT,GAA3B,CAA0C,IAAAC,GAA1C,CAAyD,IAAAwjC,EAAzD,CAAuE,CAAC,IAAA58B,EAAxE,CAR6B,CAWrC,IAAAsd,EAAA,CAAc,CAAA,CAZlB,CA6BA4f;QAAA,GAAS,CAATA,CAAS,CAACtjC,CAAD,CAAQT,CAAR,CAAkBC,CAAlB,CAA4BkkC,CAA5B,CAAsCC,CAAtC,CACT,CACI,IAAIC,EAAU,CAAA,CAEE,KAAhB,EAAIrkC,CAAJ,GACIA,CADJ,CACemkC,CADf,CAGA,IAAgB,IAAhB,EAAInkC,CAAJ,CAAsB,CAClB,IAASjI,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoB0I,CAAA7E,OAApB,CAAkC7D,CAAA,EAAlC,CACIkgB,EAAA,CAAA,CAAAlR,EAAA,CAAuB/G,CAAvB,CAAkCjI,CAAlC,CAAqC0I,CAAA,CAAM1I,CAAN,CAArC,CAEJssC,EAAA,CAAU,CAAA,CAJQ,CAMlBA,CAAJ,GASoB,IAIhB,EAJIpkC,CAIJ,GAHIsX,CAAA,CAAA,CAAAzQ,EAAA,CACA,CAAAs9B,CAAA,CAAS,CAAA,CAEb,EAAgB,IAAhB,EAAInkC,CAAJ,GACI6G,CAnuRR,CAmuRQA,CAAAA,EAnuRR,CAhCA,CAAAse,GAgCA,CAmuR0BnlB,CAnuR1B,CA9BAkX,CAAA,CAAAA,CAAA,CAiwR0BlX,CAjwR1B,CA8BA,CA5BImkC,CAAJ,CACS,CAAAj+B,MAAAK,EAAL,CAGU,CAAAL,MAAA+Q,EAHV,EAIII,EAAA,CAAAA,CAAA,CAJJ,CACI,CAAAnR,MAAAsa,GADJ,CAC2B,CAAA,CAF/B,CASQ,CAAA5Z,EAAJ,EAAgB,CAAAV,MAAAK,EAAhB,CAUS+Q,CAAA,CAAAA,CAAA,CAVT,EAU4B,CAAAvQ,EAAAb,MAAAqO,MAV5B,GAWQ6N,EAAA,CAAA,CAAAxb,EAAA,CACA,CAAAkR,CAAA,CAAA,CAAA/Q,EAAA,CAAyB,EAAzB,CAZR,EAeoB,CAAA,CAfpB,GAeSo9B,CAfT,EAgBI7sB,CAAA,CAAAA,CAAA,CAGR,CAAI,CAAC8c,CA1oCEluB,MAAA+Q,EA0oCP,EAAyB,CAAAnC,GAAzB,EAAqC,CAAAA,GAAAL,KAAA,EAkuRjC,CAbJ,CAiBA,OAAO2vB,EA7BX,CAuDJ5qB,EAAA,CAfIZ,QAAW,EACX,CAEI,IADA,IAAIyrB,EAAQ77B,CAAA,CAA6BsQ,QAA7B,CAAuCxQ,CAAvC,CAAuD,KAAvD,CAAZ,CACSg8B,EAAO,CAAhB,CAAmBA,CAAnB,CAA0BD,CAAA1oC,OAA1B,CAAwC2oC,CAAA,EAAxC,CAAgD,CAC5C,IAAIC,EAAOF,CAAA,CAAMC,CAAN,CAAX,CACIf,EAAWp6B,EAAA,CAA4Bo7B,CAA5B,CACXZ,EAAAA,CAAM,IAAIL,EAAJ,CAAaC,CAAb,CACVrqB,GAAA,CAAgCyqB,CAAhC,CAAqCY,CAArC,CAJ4C,CAFpD,CAcJ,CAuDI/+B;QArBEg/B,GAqBS,CAACC,CAAD,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,YAAN,CAAoBA,CAApB,CAjzZQ3yB,OAizZR,CAGA,KAAA4yB,EAAA,CAAkBD,CAAA,UACY,SAA9B,EAAI,MAAO,KAAAC,EAAX,GAAwC,IAAAA,EAAxC,CAA8E,MAA9E,EAA2D,IAAAA,EAA3D,CAqCA,KAAAC,EAAA,CAAkB,CAAA,CAElB,KAAAC,EAAA,CAAiB,EAEb94B,EAAAA,CAAW24B,CAAA,QACf,IAAgB,SAAhB,EAAI34B,CAAJ,EAgBwCA,CAhBxC,CA3qcc,CACV,IAAI+4B,EAASv5B,EAAA,CAHmC1B,OAGnC,CA0rciB3C,IA1rcmBrB,GAApC,CACTi/B,EAAJ,GACQ98B,CADR,CACkB88B,CAAA9+B,EAAA,CAwrckB+F,CAxrclB,CADlB,GAyrc8B7E,IAtrctBmC,GAAA,CAAqB,EAArB,CAsrc4B0C,CAtrc5B,CAAmC/D,CAAnC,CALE,CAkscd,IAAA+8B,EAAA,CAAkB,IAAAC,EAAlB,CAAsD,IAKtD,KAAA,QAAA,CAAkB,CACd,QAAW,IAAAC,GADG,CAEd,YAAe,IAAAC,GAFD,CAGd,cAAiB,IAAAC,GAHH,CAId,cAAiB,IAAAC,GAJH,CA3EtB,CAtB0B9wB,EAAA5O,CAAxB++B,EAAwB/+B,CAAAA,CAAAA,CAmH1B,EAAA,CAzxiBJ,EAAA2/B,UAyxiBIz5B;CAAAvC,GAAA,CAAAA,QAAU,CAACyC,CAAD,CAAYC,CAAZ,CAAsB/D,CAAtB,CACV,CACI,GAAI,CAAC8D,CAAL,EAA+B,UAA/B,EAAkBA,CAAlB,CAA2C,CAEvC,IAAIw5B,EAAS,IACb,KAAAt/B,EAAA,CAAc+F,CAAd,CAAA,CAA+C/D,CAU/CA,EAAAu9B,UAAA,CAAoBC,QAAkB,CAACpwB,CAAD,CAAQ,CAC1CA,CAAA,CAAQA,CAAR,EAAiBzW,MAAAyW,MACjB,KAAIqwB,EAAS,CAAb,CACIC,EAAUtwB,CAAAswB,QA/hiBEC,EA0iiBhB,EAAID,CAAJ,CACID,CADJ,CACarwB,CAAAwwB,OAAA,CAAcC,EAAApxC,GAAd,CAAkCqxC,EAAA7sC,GAD/C,CAnhiBgB0sC,EAshiBX,EAAID,CAAJ,CACDD,CADC,CACQI,EAAApxC,GADR,CAGI2gB,CAAA2wB,QAHJ,EAGqBL,CAHrB,EAGgCM,EAAAnwC,GAHhC,EAGgD6vC,CAHhD,EAG2DO,EAAA3uC,GAH3D,GAIDmuC,CAJC,CAIQC,CAJR,EAImBM,EAAAnwC,GAJnB,CAIkCqwC,EAAAhyC,GAJlC,EAMDuxC,EAAJ,GACQrwB,CAAAC,eACJ,EAD0BD,CAAAC,eAAA,EAC1B,CAAAiwB,CAAAJ,GAAA,CAAmBO,CAAnB,CAFJ,CAIA,OAAO,CAAA,CA3BmC,CA8B9Cz9B,EAAAm+B,WAAA,CAAqBC,QAAmB,CAAChxB,CAAD,CAAQ,CAM5CA,CAAA,CAAQA,CAAR,EAAiBzW,MAAAyW,MAKjB,IAAI,CAACA,CAAAixB,QAAL,CAAoB,CAChB,IAAIZ,EAASrwB,CAAAkxB,MAATb,EAAwBrwB,CAAAswB,QAKxBtwB,EAAAwwB,OAAJ,EACQH,CADR,EACkBc,EAAAzxC,GADlB,GAEQ2wC,CAFR,CAEiBe,EAAA7xC,GAFjB,CAKA2wC,EAAAJ,GAAA,CAAmBO,CAAnB,CAQIrwB,EAAAC,eAAJ,EAA0BD,CAAAC,eAAA,EAnBV,CAqBpB,MAAO,CAAA,CAhCqC,CAmChDrN,EAAAy+B,QAAA,CAAkBC,QAAmB,CAACtxB,CAAD,CAAQ,CACrCA,CAAAuxB,gBAAJ,EAA2BvxB,CAAAuxB,gBAAA,EACvBvxB;CAAAC,eAAJ,EAA0BD,CAAAC,eAAA,EAE1B,EADIuxB,CACJ,CADoBxxB,CAAAwxB,cACpB,EAD2CjoC,MAAAioC,cAC3C,GAKItB,CAAAJ,GAAA,CAAmB0B,CAAAC,QAAA,CAAsB,MAAtB,CAAnB,CATqC,CAkB7C7+B,EAAA8+B,gBAAA,CAAwB,UAAxB,CAEA,OAAO,CAAA,CAlGgC,CAoG3C,MAAO,CAAA,CArGX,CAiHAl7B,EAAA0J,GAAA,CAAAA,QAAO,CAACtO,CAAD,CAAMD,CAAN,CAAWD,CAAX,CAAgBD,CAAhB,CACP,CACI,IAAAG,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CACX,KAAAD,EAAA,CAAWA,CAEXmG,GAAA,CAAAA,IAAA,CANJ,CA+BApB;CAAAq5B,GAAA,CAAAA,QAAc,CAACL,CAAD,CACd,CACI,GAAI,CAAC,IAAAG,EAAL,CAAsB,CAClB,IAAIgC,EAAc9kB,EAAA,CAAA,IAAAjb,EAAA,CAAwB,YAAxB,CAClB,IAAI+/B,CAAJ,CAAiB,CACb,IAAIC,EAAUD,CAAAhmC,MAAA,CAAkB,OAAlB,CACd,IAAsB,CAAtB,EAAIimC,CAAAprC,OAAJ,CAAyB,CACrB,IAAIqrC,EAAYC,EAAA,CAASF,CAAA,CAAQ,CAAR,CAAT,CAChB,IAAIC,CAAJ,EAAiB,IAAAhhC,GAAjB,CAAmC,MAC/BkhC,EAAAA,CAAYD,EAAA,CAASF,CAAA,CAAQ,CAAR,CAAT,CAEhB,IADA,IAAAjC,EACA,CADkB7rB,EAAA,CAA2BiuB,CAA3B,CAClB,CAAqB,CACjB,IAAI17B,EAAU,IAAAs5B,EAAA,QACd,IAAIt5B,CAAJ,CAAa,CACT,IAAI27B,EAAY37B,CAAA,QACZ27B,EAAJ,EAAeA,CAAA17B,KAAA,CAAe,IAAAq5B,EAAf,CAAgC,IAAAH,EAAhC,CAEf,IADA,IAAAI,EACA,CADgBv5B,CAAA,YAChB,CAAmB,CACf,IAAAm5B,EAAA,CAAkBA,CAElB,KAAAlmC,OAAA,CAAY,YAAZ,CAA2B,IAAAwH,GAA3B,CAA4C,GAA5C,CAAkD+gC,CAAlD,CAA8D,MAA9D,CAAuEE,CAAvE,CACA,OAJe,CAJV,CAFI,CALA,CAuBzB,IAAAzoC,OAAA,CAAY,kCAAZ,CAAiDqoC,CAAjD,CAzBa,CAFC,CAD1B,CAyCAn7B,EAAAyB,GAAA,CAAAA,QAAO,CAACjN,CAAD,CAAOqV,CAAP,CACP,CACI,GAAI,CAACA,CAAL,CAUI,GAFA,IAAAwvB,GAAA,CAAoB,IAAAL,EAApB,CAEI,CAAA,CAACxkC,CAAL,CACI,IAAAoU,MAAA,EADJ,KAGI,IAAI,CAAC,IAAAmB,QAAA,CAAavV,CAAb,CAAL,CAAyB,MAAO,CAAA,CAGxC,OAAO,CAAA,CAjBX,CA4BAwL;CAAA0B,GAAA,CAAAA,QAAS,CAACC,CAAD,CACT,CACI,MAAOA,EAAA,CAAO,IAAAqI,KAAA,EAAP,CAAqB,CAAA,CADhC,CASAhK,EAAA4I,MAAA,CAAAA,QAAK,EACL,EAYA5I,EAAAgK,KAAA,CAAAA,QAAI,EACJ,CACI,IAAIC,EAAQ,IAAIC,CAAJ,CAAU,IAAV,CACZD,EAAAE,IAAA,CAAU,CAAV,CAwCO,EAxCP,CACA,OAAOF,EAAAzV,KAAA,EAHX,CAeAwL,EAAA+J,QAAA,CAAAA,QAAO,EACP,CACI,MAYO,CAAA,CAbX,CAwCA/J,EAAAs5B,GAAA,CAAAA,QAAW,CAAC9kC,CAAD,CACX,CACI,GAAmB,QAAnB,EAAI,MAAOA,EAAX,CACI,IAAAykC,EAAA7jC,KAAA,CAAoBZ,CAApB,CADJ,KAGK,IAAmB,QAAnB,EAAI,MAAOA,EAAX,CAED,IAF8B,IAC1BqlC,EAAS,CADiB,CACd4B,CADc,CAErBtvC,EAAI,CAAb,CAAgBA,CAAhB,CAAoBqI,CAAAxE,OAApB,CAAiC7D,CAAA,EAAjC,CAAsC,CAClCsvC,CAAA,CAAa5B,CACbA,EAAA,CAASrlC,CAAAknC,WAAA,CAAgBvvC,CAAhB,CAMT,IAzzgBJwvC,EAyzgBI,EAAI9B,CAAJ,CAA4B,CACxB,GAzzgBR+B,EAyzgBQ,EAAIH,CAAJ,CAAgC,QAChC5B,EAAA,CA1zgBR+B,EAwzgBgC,CAI5B,IAAA3C,EAAA7jC,KAAA,CAAoBykC,CAApB,CAZkC,CAFrC,IAkBD,KAAAZ,EAAA,CAAiB,IAAAA,EAAAt1B,OAAA,CAAsBnP,CAAtB,CAGrB,OAAO,CAAA,CAzBX,CAgEAwL,EAAAu5B,GAAA,CAAAA,QAAa,EACb,EAWAv5B,EAAAw5B,GAAA,CAAAA,QAAa,CAACl+B,CAAD,CAAYhE,CAAZ,CACb,CACI,MAAK,KAAA6hC,EAAL,CAKO,CAAA,CALP,EACI,IAAAA,EAEO,CAFW79B,CAEX,CADP,IAAA89B,EACO,CADS9hC,CACT,CAAA,CAAA,CAHX,CADJ,CAwGJuW;EAAA,CAfIZ,QAAW,EACX,CAEI,IADA,IAAI4uB,EAAWh/B,CAAA,CAA6BsQ,QAA7B,CAAuCxQ,CAAvC,CAAuD,QAAvD,CAAf,CACSm/B,EAAU,CAAnB,CAAsBA,CAAtB,CAAgCD,CAAA7rC,OAAhC,CAAiD8rC,CAAA,EAAjD,CAA4D,CACxD,IAAIC,EAAUF,CAAA,CAASC,CAAT,CAAd,CACIhD,EAAct7B,EAAA,CAA4Bu+B,CAA5B,CACdrC,EAAAA,CAAS,IAAIb,EAAJ,CAAoBC,CAApB,CACbvrB,GAAA,CAAgCmsB,CAAhC,CAAwCqC,CAAxC,CAJwD,CAFhE,CAcJ,CAoEIliC,SAfEmiC,GAeS,CAACC,CAAD,CACX,CAGQ,CAAA,KAAA,CAAA,IAAA,CAAM,UAAN,CAAkBA,CAAlB,CAKA,KAAAC,EAAA,CAAa,CAACD,CAAA,KAAd,EAAkC,EAMlC,KAAAE,EAAA,CAAa,EAEb,KAAAC,EAAA,CAAgB,CAAC,GAAD,CAAK,GAAL,CAChB,KAAAC,GAAA,CAAkB,CAAC,GAAD,CAAK,GAAL,CAUlB,KAAApoB,EAAA,CAAe,CAMf,KAAAqoB,EAAA,CAAiB,CAAA,CAMjB,KAAAC,EAAA,CAAiB,EACjB,KAAAC,EAAA,CAAiB,EAiBjB,KAAAC,EAAA,CAAkB,EAzD1B,CAhBmB/zB,EAAA5O,CAAjBkiC,EAAiBliC,CAAAA,CAAAA,CAwFnB,GAAA,UAAA,GAAA,CAAA4iC,QAAW,EACX,CACI,MAAQ,EADZ,CAaA,GAAA,UAAA,GAAA,CAAAC,QAAW,EACX,EA+DAC;QAAA,GAAY,CAAZA,CAAY,CAACC,CAAD,CAAOl7B,CAAP,CAAcm7B,CAAd,CACZ,CACI,GAAIn7B,CAAJ,CACI,GAAKk7B,CAAL,CAMO,CACiB,CAApB,CAAI,CAAAN,EAAJ,EAAyB,CAAAC,EAAAxsC,OAAzB,GACI,CAAAusC,EADJ,CACoB,CADpB,CAGA,IAAoB,CAApB,CAAI,CAAAA,EAAJ,EAAyBM,CAAzB,EAAiC,CAAAL,EAAA,CAAe,CAAAD,EAAf,CAAjC,CACI,CAAAC,EAAAr9B,OAAA,CAAsB,CAAtB,CAAyB,CAAzB,CAA4B09B,CAA5B,CACA,CAAA,CAAAN,EAAA,CAAgB,CAEpB,EAAAA,EAAA,EARG,CANP,IACQ,EAAAD,EAAJ,CACIO,CADJ,CACW,KADX,CAGIA,CAHJ,CAGW,CAAAL,EAAA,CAAe,CAAAD,EAAf,CAA6B,CAA7B,CAaf5wC,EAAAA,CAAI,EACR,IAAIkxC,CAAJ,CAAU,CAaNA,CAAA,CAAOA,CAAAlvC,QAAA,CAAa,KAAb,CAAoB,GAApB,CAEHovC,EAAAA,CAAQ,CACZ,KAAIC,EAAU,IACdF,EAAA,CAAQA,CAAR,EAAiB,GAQjB,KAAK,IAAI3wC,EAAI,CAAb,CAAgBA,CAAhB,EAAqB0wC,CAAA7sC,OAArB,CAAkC7D,CAAA,EAAlC,CAAuC,CACnC,IAAIyB,EAAKivC,CAAAhvC,OAAA,CAAY1B,CAAZ,CACT,IAAU,GAAV,EAAIyB,CAAJ,EAAuB,GAAvB,EAAiBA,CAAjB,CACSovC,CAAL,CAEWpvC,CAFX,EAEiBovC,CAFjB,GAGIA,CAHJ,CAGc,IAHd,EACIA,CADJ,CACcpvC,CAFlB,KAOK,IAAIA,CAAJ,EAAUkvC,CAAV,EAAmB,CAACE,CAApB,EAA+B,CAACpvC,CAAhC,CAKDjC,CAAAyJ,KAAA,CAAOkmC,EAAA,CAASuB,CAAAI,UAAA,CAAeF,CAAf,CAAsB5wC,CAAtB,CAAT,CAAP,CACA,CAAA4wC,CAAA,CAAQ5wC,CAAR,CAAY,CAfmB,CAzBjC,CA4CV,MAAOR,EAhEX,CA+EAuxC,QAAA,GAAO,CAAPA,CAAO,CAACnf,CAAD,CAAMD,CAAN,CACP,CAUI,GAAkB,EAAlB,EAAI,CAAAqe,EAAJ,CACI,MAAOpe,EAAP,CAAaD,CAKjBC,EAAA,CAAMof,CAAA,CAAAA,CAAA,CAAcpf,CAAd,CAAmB,CAAnB,CAAsB,CAAA,CAAtB,CACND,EAAA,CAAMqf,CAAA,CAAAA,CAAA,CAAcrf,CAAd,CAAmB,CAAnB,CAAsB,CAAA,CAAtB,CACN,SAAWC,CAAX,CAAiBqf,EAAjB,CAAqC,CAArC,GAA4Ctf,CAA5C,CAAkDsf,EAAlD,CAAsE,CAAtE,GAA4EA,EAA5E,GAAoGrf,CAApG,CAA0GD,CAA1G,IAAmH,CAAnH,CAlBJ;AAmEAuf,QAAA,GAAO,CAAPA,CAAO,CAACtf,CAAD,CAAMD,CAAN,CACP,CAUI,GAAkB,EAAlB,EAAI,CAAAqe,EAAJ,CACI,MAAOpe,EAAP,CAAaD,CAKjBC,EAAA,CAAMof,CAAA,CAAAA,CAAA,CAAcpf,CAAd,CAAmB,CAAnB,CAAsB,CAAA,CAAtB,CACND,EAAA,CAAMqf,CAAA,CAAAA,CAAA,CAAcrf,CAAd,CAAmB,CAAnB,CAAsB,CAAA,CAAtB,CACN,SAAWC,CAAX,CAAiBqf,EAAjB,CAAqC,CAArC,GAA4Ctf,CAA5C,CAAkDsf,EAAlD,CAAsE,CAAtE,GAA4EA,EAA5E,GAAoGrf,CAApG,CAA0GD,CAA1G,IAAmH,CAAnH,CAlBJ,CAgCA,EAAA,UAAA,GAAA,CAAAwf,QAAO,CAACvf,CAAD,CAAMD,CAAN,CACP,CACI,MAAOC,EAAP,CAAaD,CADjB,CAaAqf,SAAA,EAAQ,CAARA,CAAQ,CAACnwC,CAAD,CAAImvC,CAAJ,CAAWoB,CAAX,CACR,CACI,IAAWC,EAAOxwC,CAClBmvC,EAAA,CAAQA,CAAR,EAAiB,CAAAA,EAEjB,IAAIoB,CAAJ,CACI,GAAa,EAAb,EAAIpB,CAAJ,CACIqB,CAAA,CAAOxwC,CAAP,GAAa,CADjB,KAGK,IAAY,EAAZ,CAAImvC,CAAJ,CACDqB,CAAA,CAAOxwC,CAAP,EAAa,CAAb,EAAkBmvC,CAAlB,EAA2B,CAD1B,KAKD,IADAsB,CACI,CADIrvC,IAAAC,IAAA,CAAS,CAAT,CAAY8tC,CAAZ,CACJ,CAAI,CAAJ,CAAAnvC,CAAA,EAASA,CAAT,EAAcywC,CAAlB,CACID,CACA,CADOxwC,CACP,CADWywC,CACX,CAAW,CAAX,CAAID,CAAJ,GAAcA,CAAd,EAAsBC,CAAtB,CAFJ,CATR,IAgBiB,GAAb,EAAItB,CAAJ,CACIqB,CADJ,CACYxwC,CADZ,EACkB,EADlB,CACuBmvC,CADvB,EACmC,EADnC,CACwCA,CADxC,EAIIsB,CACA,CADQrvC,IAAAC,IAAA,CAAS,CAAT,CAAY8tC,CAAZ,CAAoB,CAApB,CACR,CAAInvC,CAAJ,EAASywC,CAAT,EACID,CACA,CADQxwC,CACR,CADYywC,CACZ,EAAMzwC,CAAN,CAAUywC,CAAV,CAAiB,CAAjB,EAAsB,CAAtB,GAAyBD,CAAzB,EAAiCC,CAAjC,CAFJ,EAGWzwC,CAHX,CAGe,CAACywC,CAHhB,GAIID,CACA,CADQxwC,CACR,CADYywC,CACZ,CAAA,EAAO,CAACzwC,CAAR,CAAY,CAAZ,EAAiBywC,CAAjB,CAA0B,CAA1B,EAA+B,CAA/B,CACQD,CADR,GACcA,CADd,EACsBC,CADtB,EAISD,CAJT,GAIeA,CAJf,EAIuBC,CAJvB,CALJ,CALJ,CAmBAzwC,EAAJ,EAASwwC,CAAT,GAEIxwC,CAFJ,CAEQwwC,CAFR,CAIA,OAAOxwC,EA3CX;AAyEA0wC,QAAA,GAAO,CAAPA,CAAO,CAACC,CAAD,CAAQC,CAAR,CAAcC,CAAd,CACP,CACI,IAFiBA,CAEjB,CAFiB,IAAA,EAAA,GAAAA,CAAA,CAAQ,EAAR,CAAAA,CAEjB,CAAOA,CAAA,EAAP,EAAiBD,CAAA5tC,OAAjB,CAAA,CAA8B,CAC1B,IAAI8tC,EAAOF,CAAAG,IAAA,EACX,IAAmB,CAAnB,CAAIJ,CAAA3tC,OAAJ,CAAsB,MAAO,CAAA,CAC7B,KACIguC,EAAOL,CAAAI,IAAA,EACPE,KAAAA,EAAON,CAAAI,IAAA,EACX,QAAOD,CAAP,EACA,KAAK,GAAL,CACII,CAAA,CAAS,CAAAZ,GAAA,CAAaW,CAAb,CAAmBD,CAAnB,CACT,MACJ,MAAK,GAAL,CACI,GAAI,CAACA,CAAL,CAAW,MAAO,CAAA,CAClBE,EAAA,CAAS9vC,IAAAE,MAAA,CAAW2vC,CAAX,CAAkBD,CAAlB,CACT,MACJ,MAAK,IAAL,CACI,GAAI,CAACA,CAAL,CAAW,MAAO,CAAA,CACTC,EAAT,EAAgBD,CAChB,MACJ,MAAK,GAAL,CACaC,CAAT,EAAgBD,CAChB,MACJ,MAAK,GAAL,CACaC,CAAT,EAAgBD,CAChB,MACJ,MAAK,UAAL,CACaC,CAAT,GAAiBD,CACjB,MACJ,MAAK,UAAL,CACaC,CAAT,GAAiBD,CACjB,MACJ,MAAK,cAAL,CACaC,CAAT,IAAkBD,CAClB,MACJ,MAAK,MAAL,CACIE,CAAA,CAAUD,CAAA,CAAOD,CAAP,CAAa,CAAb,CAAiB,CAC3B,MACJ,MAAK,UAAL,CACIE,CAAA,CAAUD,CAAA,EAAQD,CAAR,CAAc,CAAd,CAAkB,CAC5B,MACJ,MAAK,MAAL,CACIE,CAAA,CAAUD,CAAA,CAAOD,CAAP,CAAa,CAAb,CAAiB,CAC3B,MACJ,MAAK,UAAL,CACIE,CAAA,CAAUD,CAAA,EAAQD,CAAR,CAAc,CAAd,CAAkB,CAC5B,MACJ,MAAK,UAAL,CACIE,CAAA;AAAUD,CAAA,EAAQD,CAAR,CAAc,CAAd,CAAkB,CAC5B,MACJ,MAAK,OAAL,CACIE,CAAA,CAAUD,CAAA,EAAQD,CAAR,CAAc,CAAd,CAAkB,CAC5B,MACJ,MAAK,MAAL,CACIE,CAAA,CAAShB,EAAA,CAAAA,CAAA,CAAae,CAAb,CAAmBD,CAAnB,CACT,MACJ,MAAK,GAAL,CACA,KAAK,GAAL,CAC0BC,CAAAA,CAAAA,CA1MZ,GAAlB,EA0MiBE,CA1MbhC,EAAJ,CACI,CADJ,CACWpe,CADX,CACiBD,CADjB,EAMAC,CAEA,CAFMof,CAAA,CAoMWgB,CApMX,CAAcpgB,CAAd,CAAmB,CAAnB,CAAsB,CAAA,CAAtB,CAEN,CADAD,CACA,CADMqf,CAAA,CAmMWgB,CAnMX,CAAcrgB,CAAd,CAAmB,CAAnB,CAAsB,CAAA,CAAtB,CACN,CAAA,CAAA,EAAWC,CAAX,CAAiBqf,EAAjB,CAAqC,CAArC,CAA4Ctf,CAA5C,CAAkDsf,EAAlD,CAAsE,CAAtE,EAA4EA,EAA5E,GAAoGrf,CAApG,CAA0GD,CAA1G,IAAmH,CAAnH,CARA,CA2MQ,MACJ,MAAK,IAAL,CACIogB,CAAA,CAASb,EAAA,CAAAA,CAAA,CAAaY,CAAb,CAAmBD,CAAnB,CACT,MACJ,MAAK,UAAL,CACIE,CAAA,CAAUD,CAAA,EAAQD,CAAR,CAAc,CAAd,CAAkB,CAC5B,MACJ,MAAK,IAAL,CACIE,CAAA,CAAUD,CAAA,EAAQD,CAAR,CAAc,CAAd,CAAkB,CAC5B,MACJ,MAAK,IAAL,CACIE,CAAA,CAASf,CAAA,CAAAA,CAAA,CAAcc,CAAd,CAAoB,EAApB,CAAwB,CAAA,CAAxB,CAAT,CAAyC7vC,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAAzC,CAA2D8uC,CAAA,CAAAA,CAAA,CAAca,CAAd,CAAoB,EAApB,CAAwB,CAAA,CAAxB,CAC3D,MACJ,MAAK,GAAL,CACA,KAAK,IAAL,CAOgB,IAAZ,EAAIF,CAAJ,GAAkBE,CAAlB,CAAyB,EAAzB,EAA+BA,CAA/B,CAAsC,GAAtC,EACIA,EAAJ,GAKIE,CAEI,CAFKf,CAAA,CAAAA,CAAA,CAAce,CAAd,CAAsB,CAAtB,CAAyB,CAAA,CAAzB,CAEL,CAAAA,CAAA,CADO,CAAX,CAAIF,CAAJ,CACIE,CADJ,CACc9vC,IAAAC,IAAA,CAAS,CAAT,CAAY2vC,CAAZ,CADd,CAGa5vC,IAAAE,MAAA,CAAW4vC,CAAX,CAAoB9vC,IAAAC,IAAA,CAAS,CAAT,CAAY,CAAC2vC,CAAb,CAApB,CATjB,CAYA,MACJ,SACI,MAAO,CAAA,CAvFX,CAyFAL,CAAAvoC,KAAA,CAAW+nC,CAAA,CAAAA,CAAA,CAAce,CAAd,CAAX,CA/F0B,CAiG9B,MAAO,CAAA,CAlGX;AA2HAE,QAAA,GAAU,CAAVA,CAAU,CAACC,CAAD,CAAWC,CAAX,CAAmBC,CAAnB,CAA2BrC,CAA3B,CAAkCsC,CAAlC,CACV,CACI,IAAIjwC,CAAJ,CAEIkwC,EAAS,CAAA,CAFb,CAGIC,EAAS,CAHb,CAIIf,EAAQ,EAJZ,CAIgBC,EAAO,EAJvB,CAMIe,EAAY,CAAAzC,EAGhB,KAFA,CAAAA,EAEA,CAFaA,CAEb,CAAOoC,CAAP,CAAgBC,CAAhB,CAAA,CAAwB,CAEpB,IAAAtoC,EAASooC,CAAA,CAASC,CAAA,EAAT,CAAAhuC,KAAA,EACT,KAAAsuC,EAAON,CAAA,CAASC,CAAT,CAAiBF,CAAA,CAASC,CAAA,EAAT,CAAjB,CAAsC,EAE7C,IAAIroC,CAAJ,CACI,IAAAjJ,EAAI6xC,EAAA,CAAAA,CAAA,CAAgB5oC,CAAhB,CAAwB,IAAxB,CAA8BuoC,CAA9B,CAA0CE,CAA1C,CADR,KAGI,IAAW,GAAX,EAAIE,CAAJ,CAAgB,CACRE,CAAAA,CAAQ,CAEZ,KADIC,CACJ,CADaT,CACb,CAAOA,CAAP,CAAgBC,CAAhB,CAAA,CAGI,GAFkBD,CAAAhuC,EAEd,CADJsuC,CACI,CADGN,CAAA,CAASD,CAAAruC,OAAT,CAA0BquC,CAAA,CAASC,CAAA,EAAT,CAA1B,CAA+C,EAClD,CAAO,GAAP,EAAAM,CAAJ,CACIE,CAAA,EADJ,KAEO,IAAW,GAAX,EAAIF,CAAJ,EACC,CAAC,EAAEE,CADJ,CACW,KAGtB9xC,EAAA,CAAIoxC,EAAA,CAAAA,CAAA,CAAgBC,CAAhB,CAA0BU,CAA1B,CAAkCT,CAAlC,CAAyC,CAAzC,CAA4C,CAAApC,EAA5C,CAAwDsC,CAAxD,CACK,KAAT,EAAIxxC,CAAJ,EAAiB0xC,CAAjB,GACI1xC,CADJ,CACQgyC,EAAA,CAAAA,CAAA,CAAgBhyC,CAAhB,CAAmB0xC,CAAnB,CADR,CAGAzoC,EAAA,CAAUqoC,CAAA,CAASC,CAAT,CAAiBF,CAAA,CAASC,CAAA,EAAT,CAAAhuC,KAAA,EAAjB,CAA6C,EACvDsuC,EAAA,CAAON,CAAA,CAASC,CAAT,CAAiBF,CAAA,CAASC,CAAA,EAAT,CAAjB,CAAsC,EAjBjC,CAAhB,IAmBK,CAQD,GAAW,GAAX,EAAIM,CAAJ,CACI,QAEJ,IAAW,IAAX,EAAIA,CAAJ,CAAiB,CACb,CAAA1C,EAAA,CAAa,CACb,SAFa,CAIjB,GAAW,IAAX,EAAI0C,CAAJ,CAAiB,CACb,CAAA1C,EAAA,CAAa,CACb,SAFa,CAIjB,GAAW,IAAX,EAAI0C,CAAJ,CAAiB,CACb,CAAA1C,EAAA,CAAa,EACb,SAFa,CAIjB,GAAI,EAAEwC,CAAF,CAAY,WAAZ,CAAJ,CAAgC,CAC5B,GAAW,GAAX,EAAIE,CAAJ,CACI,QAEJ,IAAW,GAAX,EAAIA,CAAJ,CAAgB,CACZF,CAAA,CAAUA,CAAV,EAAoB,CAApB,CAAyB,CACzB,SAFY,CAIhB,GAAW,GAAX;AAAIE,CAAJ,EAAyB,IAAzB,EAAkBA,CAAlB,CAA+B,CAC3BF,CAAA,CAAUA,CAAV,EAAoB,CAApB,CAAyB,CACzB,SAF2B,CAI/B,GAAW,IAAX,EAAIE,CAAJ,CAAiB,CACbF,CAAA,CAAUA,CAAV,EAAoB,CAApB,CAAyB,CACzB,SAFa,CAZW,CAiBhCD,CAAA,CAAS,CAAA,CACT,MAzCC,CA6CT,GAAU5tC,IAAAA,EAAV,GAAI7D,CAAJ,CACI,GAAIwxC,CAAJ,CACIA,CAAAppC,KAAA,CAAgBa,CAAhB,CACA,CAAAjJ,CAAA,CAAI,CAFR,KAGO,CACHyxC,CAAA,CAAS,CAAA,CACTD,EAAA,CAAa,EACb,MAHG,CAOXb,CAAAvoC,KAAA,CAAW+nC,CAAA,CAAAA,CAAA,CAAcnwC,CAAd,CAAX,CASA,IAAW,GAAX,EAAI4xC,CAAJ,CACI,GAAIN,CAAJ,CAAaD,CAAAruC,OAAb,CAA+B,CAA/B,EAAoC,CAACquC,CAAA,CAASC,CAAT,CAArC,CACIA,CAAA,EACA,CAAAM,CAAA,CAAMP,CAAA,CAASC,CAAA,EAAT,CAFV,KAGO,CACHG,CAAA,CAAS,CAAA,CACT,MAFG,CAMX,GAAI,CAACG,CAAL,CAAU,KAENK,EAAAA,CAA8B,MAApB,EAAA,CAAA7C,EAAA,CAAc,CAAd,CAAA,CAAyB8C,EAAzB,CAAqDC,EACnE,IAAI,CAACF,CAAA,CAAOL,CAAP,CAAL,CAAkB,CACdH,CAAA,CAAS,CAAA,CACT,MAFc,CAIdb,CAAA5tC,OAAJ,EAAmBivC,CAAA,CAAOL,CAAP,CAAnB,EAAkCK,CAAA,CAAOrB,CAAA,CAAKA,CAAA5tC,OAAL,CAAmB,CAAnB,CAAP,CAAlC,EACI0tC,EAAA,CAAAA,CAAA,CAAaC,CAAb,CAAoBC,CAApB,CAA0B,CAA1B,CAEJA,EAAAxoC,KAAA,CAAUwpC,CAAV,CAMA,EAAA1C,EAAA,CAAqB,IAAR,EAAC0C,CAAD,CAAe,EAAf,CAAoB1C,CACjCwC,EAAA,CAAS,CAvHW,CA0HxB,GAAID,CAAJ,EAAc,CAACf,EAAA,CAAAA,CAAA,CAAaC,CAAb,CAAoBC,CAApB,CAAf,EAA4D,CAA5D,EAA4CD,CAAA3tC,OAA5C,CACIyuC,CAAA,CAAS,CAAA,CAGRA,EAAL,CAGYD,CAHZ,EAII,CAAAh+B,EAAA,CAAa,eAAb,EAAgCvK,CAAhC,EAA0C2oC,CAA1C,EAAiD,GAAjD,CAJJ,CACIrwC,CADJ,CACYovC,CAAAI,IAAA,EAMZ,EAAA7B,EAAA,CAAayC,CACb,OAAOpwC,EAhJX;AA6JA6wC,QAAA,GAAU,CAAVA,CAAU,CAACC,CAAD,CAAOC,CAAP,CAAgBnD,CAAhB,CAAuBoD,CAAvB,CACV,CAEI,IADA,IAAIpzC,CACJ,CAAsC,CAAtC,GAAQA,CAAR,CAAYkzC,CAAA3xC,QAAA,CAAa4xC,CAAb,CAAZ,EAAA,CAAyC,CAIrC,IAHA,IAAItyC,EAAI,CAAR,CACIZ,EAAID,CAAJC,CAAQ,CADZ,CAEIsC,EAAM6wC,CACV,CAAOnzC,CAAP,CAAWizC,CAAArvC,OAAX,CAAA,CAAwB,CACpB,IAAIpC,EAAKyxC,CAAA,CAAKjzC,CAAA,EAAL,CACT,IAAIwB,CAAJ,EAAU0xC,CAAV,CAAmB,CACf5wC,CAAA,CAAO,EACP,MAFe,CAInB,GAAI,CAACA,CAAL,CAAU,KACVA,EAAA,EACI7C,EAAAA,CAAI+B,CAAA8tC,WAAA,CAAc,CAAd,CACK,EAAb,EAAIS,CAAJ,CACItwC,CADJ,EACS,GADT,CAGIA,CAHJ,CAGSA,CAHT,CAGa,EAHb,CAGqB,EAErBmB,EAAA,CAAImwC,CAAA,CAAAA,CAAA,CAAcnwC,CAAd,CAAkBoB,IAAAC,IAAA,CAAS,CAAT,CAAY8tC,CAAZ,CAAlB,CAAuCtwC,CAAvC,CAA0CswC,CAA1C,CAAkDoD,CAAlD,CAA0D,CAAA,CAA1D,CAdgB,CAgBxB,GAAW,CAAX,EAAI7wC,CAAJ,CAAc,CACV,CAAA8R,EAAA,CAAa,eAAb,CAA+B8+B,CAA/B,CAAyCD,CAAzC,CAAgDC,CAAhD,CAA0D,GAA1D,CACA,OAFU,CAIVD,CAAA,CAAOA,CAAAvxC,OAAA,CAAY,CAAZ,CAAe3B,CAAf,CAAP,CAA2BqlB,CAAA,CAAAA,CAAA,CAAexkB,CAAf,CAAmB,EAAnB,CAA3B,CAAmDqyC,CAAAvxC,OAAA,CAAY1B,CAAZ,CAxBlB,CA2BzC,MAAOizC,EA7BX;AA6DAG,QAAA,GAAe,CAAfA,CAAe,CAACH,CAAD,CAAOI,CAAP,CACf,CACI,IAAIlxC,EAAQsC,IAAAA,EAAZ,CACI6uC,EAAqB,CAAA,CAArBA,GAAUD,CACVjB,EAAAA,CAAa5pC,KAAAmO,QAAA,CAAc08B,CAAd,CAAA,CAAuBA,CAAvB,CAAgC5uC,IAAAA,EAEjD,IAAIwuC,CAAJ,CAAU,CAYkB,GAAxB,EAAI,CAAAjD,EAAA,CAAc,CAAd,CAAJ,GACIiD,CADJ,CACWA,CAAAlqC,MAAA,CAAW,CAAAinC,EAAA,CAAc,CAAd,CAAX,CAAAuD,KAAA,CAAkC,GAAlC,CAAAxqC,MAAA,CAA6C,CAAAinC,EAAA,CAAc,CAAd,CAA7C,CAAAuD,KAAA,CAAoE,GAApE,CADX,CAQAN,EAAA,CAAOD,EAAA,CAAAA,CAAA,CAAgBC,CAAhB,CAAsB,GAAtB,CAA2B,CAA3B,CAA8B,CAA9B,CACP,IAAI,CAACA,CAAL,CAAW,MAAO9wC,EAClB8wC,EAAA,CAAOD,EAAA,CAAAA,CAAA,CAAgBC,CAAhB,CAAsB,GAAtB,CAA2B,CAA3B,CAA8B,CAA9B,CACP,IAAI,CAACA,CAAL,CAAW,MAAO9wC,EAsCA,GAAlB,EAAI,CAAA2tC,EAAJ,GACImD,CADJ,CACWA,CAAA1xC,QAAA,CAAa,2BAAb,CAA0C,QAA1C,CAAAA,QAAA,CAA4D,MAA5D,CAAoE,GAApE,CADX,CAGI0wC,EAAAA,CAAWgB,CAAAlqC,MAAA,CAJFyqC,qGAIE,CACfrxC,EAAA,CAAQ6vC,EAAA,CAAAA,CAAA,CAAgBC,CAAhB,CAA0B,CAA1B,CAA6BA,CAAAruC,OAA7B,CAA8C,CAAAksC,EAA9C,CAA0DsC,CAA1D,CACM3tC,KAAAA,EAAd,GAAItC,CAAJ,EAA2BmxC,CAA3B,EACIG,EAAA,CAAAA,CAAA,CAAgB,IAAhB,CAAsBtxC,CAAtB,CAnEE,CAsEV,MAAOA,EA3EX;AA4KAywC,QAAA,GAAU,CAAVA,CAAU,CAACzwC,CAAD,CAAQmwC,CAAR,CACV,CACI,IAAA,CAAOA,CAAP,CAAA,CAAe,CACX,OAAOA,CAAP,CAAgB,CAAhB,EACA,KAAK,CAAL,CACInwC,CAAA,CAAQ,CAAC4uC,CAAA,CAAAA,CAAA,CAAc5uC,CAAd,CACT,MACJ,MAAK,CAAL,CACIA,CAAA,CAAQ8uC,EAAA,CAAAA,CAAA,CAAa9uC,CAAb,CAAqB,EAArB,CACR,MACJ,MAAK,CAAL,CAEI,IADA,IAAIuxC,EAAM,EACV,CAAc,CAAd,EAAOA,CAAP,EAAmB,CAAC5C,EAAA,CAAAA,CAAA,CAAa3uC,CAAb,CAAoBH,IAAAC,IAAA,CAAS,CAAT,CAAYyxC,CAAZ,CAApB,CAApB,CAAA,CAA2DA,CAAA,EAC3DvxC,EAAA,CAAQ,EAAR,CAAauxC,CAVjB,CAaApB,CAAA,IAAY,CAdD,CAgBf,MAAOnwC,EAjBX;AA8BAswC,QAAA,GAAU,CAAVA,CAAU,CAAC5oC,CAAD,CAASuF,CAAT,CAAgBikC,CAAhB,CAAwBf,CAAxB,CACV,CADkCA,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAS,CAAT,CAAAA,CAE9B,KACIF,EAAa5pC,KAAAmO,QAAA,CAAc08B,CAAd,CAAA,CAAuBA,CAAvB,CAAgC5uC,IAAAA,EAEjD,IAAc,IAAd,EAAIoF,CAAJ,CAAoB,CACZ8pC,IAAAA,EAAO,CAAArD,GAAA,CAAiBzmC,CAAjB,CACX,IAAY,CAAZ,EAAI8pC,CAAJ,CACIxxC,CAAA,CAAQ,CAAAouC,GAAA,CAAiBoD,CAAjB,CADZ,KAII,IADyB9pC,CACrB,CADqBA,CACrB,CADI+pC,CAwIZvD,EAAA,CAAgBwD,CAAhB,CAAJ,CACI,CADJ,CAxIgBD,CAyILvD,EAAA,CAAgBwD,CAAhB,CAAA1xC,MADX,EAGA0xC,CACA,CADOA,CAAAnyC,OAAA,CAAY,CAAZ,CAAe,CAAf,CACP,CAAA,CAAA,CA5IgBkyC,CA4ITvD,EAAA,CAAgBwD,CAAhB,CAAP,EA5IgBD,CA4IgBvD,EAAA,CAAgBwD,CAAhB,CAAA1xC,MAJhC,CAvIY,CAAS,IAAT,EAAAA,CAAJ,CAAmB,CACf,IAAI2xC,EAAaC,CAsJtB1D,EAAA,CAtJ4CxmC,CAsJ5C,CAtJSiqC,EAAaC,CAsJG1D,EAAA,CAtJmBxmC,CAsJnB,CAAAiqC,GArJhBA,EAAJ,GACQ1B,CAAJ,CACIA,CAAAppC,KAAA,CAAgB8qC,CAAhB,CADJ,EAGQE,CACJ,CADqBZ,EAAA,CAAAA,CAAA,CAAqBU,CAArB,CAAiCT,CAAjC,CACrB,CAAuB5uC,IAAAA,EAAvB,GAAIuvC,CAAJ,CACI7xC,CADJ,EACa6xC,CADb,EAGSX,CAGL,EAFI,CAAAj/B,EAAA,CAAa,YAAb,EAA6BhF,CAA7B,EAAsC,OAAtC,EAAiD,IAAjD,CAAwDvF,CAAxD,CAAiE,IAAjE,CAAwEiqC,CAAxE,CAAqF,GAArF,CAEJ,CAAA3xC,CAAA,CAAQsC,IAAAA,EANZ,CAJJ,CADJ,CAFe,CAAnB,IAqBItC,EAAA,CAAQ2c,EAAA,CAAajV,CAAb,CAAqC,CAAhB,CAAAA,CAAAjG,OAAA,EAAkC,EAAlC,CAAqB,CAAAksC,EAArB,CAAsC,CAAAA,EAAtC,CAAmD,EAAxE,CAGH,KAAb,EAAI3tC,CAAJ,CACIA,CADJ,CACY4uC,CAAA,CAAAA,CAAA,CAAc6B,EAAA,CAAAA,CAAA,CAAgBzwC,CAAhB,CAAuBmwC,CAAvB,CAAd,CADZ,CAGSe,CAHT,EAIQ,CAAAj/B,EAAA,CAAa,UAAb,EAA2BhF,CAA3B,EAAoC,OAApC,EAA+C,IAA/C,CAAsDvF,CAAtD,CAlCQ,CAApB,IAsCSwpC,EAAL,EACI,CAAAj/B,EAAA,CAAa,UAAb,EAA2BhF,CAA3B,EAAoC,OAApC,EAGR,OAAOjN,EA9CX;AAyDAsxC,QAAA,GAAU,CAAVA,CAAU,CAACI,CAAD,CAAO1xC,CAAP,CACV,CACI,IACI8xC,EAAW,CAAA,CACf,IAAcxvC,IAAAA,EAAd,GAAItC,CAAJ,CAAyB,CACrB8xC,CAAA,CAAW,CAAA,CAEP,KAAApqC,EADc,CAAlB,EAAI,CAAAimC,EAAJ,CACa1qB,CAAA,CAAAA,CAAA,CAAejjB,CAAf,CAAsB,CAAA4tC,EAAtB,CAAkC,CAAlC,CAAqC,CAArC,CADb,CACuD,IADvD,CAC8D5tC,CAD9D,CACsE,GADtE,CAGaijB,CAAA,CAAAA,CAAA,CAAejjB,CAAf,CAAsB,CAAA4tC,EAAtB,CAAkC,EAAlC,CAAsC,CAAtC,CAHb,CAGwD,IAHxD,CAG+D3qB,CAAA,CAAAA,CAAA,CAAejjB,CAAf,CAAsB,CAAA4tC,EAAtB,CAAkC,CAAlC,CAAqC,CAArC,CAH/D,CAGyG,IAHzG,CAGgH3qB,CAAA,CAAAA,CAAA,CAAejjB,CAAf,CAAsB,CAAA4tC,EAAtB,CAAkC,CAAlC,CAAmD,EAAd,EAAA,CAAAA,EAAA,CAAkB,CAAlB,CAAsB,CAA3D,CAHhH,CAGgL,IAHhL,CAGuL5tC,CAHvL,CAG+L,GAElL,GAAb,EAAIA,CAAJ,EAA6B,GAA7B,CAAqBA,CAArB,GACI0H,CADJ,EACc,IADd,CACqBlH,MAAAC,aAAA,CAAoBT,CAApB,CADrB,CACkD,GADlD,CAPqB,CAYzB,CAAAiS,EAAA,EADgB,IAARy/B,EAAAA,CAAAA,CAAeA,CAAfA,CAAsB,IAAtBA,CAA8B,EACtC,EAAoBhqC,CAApB,CACA,OAAOoqC,EAhBX,CAyBAC,QAAA,GAAc,CAAdA,CAAc,CACd,CACI,IAAI30C,EAAI,CAAA8wC,EACR,EAAAA,EAAA,CAAkB,EAClB,OAAO9wC,EAHX,CAwBA40C,QAAA,GAAa,CAAbA,CAAa,CAACN,CAAD,CACb,CACI,IAAIO,EAAa,CACjB,IAAI,CAAA/D,EAAJ,CAAqB,CACjB,GAAIwD,CAAJ,CACI,MAAOJ,GAAA,CAAAA,CAAA,CAAgBI,CAAhB,CAAsB,CAAAxD,EAAA,CAAgBwD,CAAhB,CAAtB,EAA+C,CAAAxD,EAAA,CAAgBwD,CAAhB,CAAA1xC,MAA/C,CAEPkyC,EAAAA,CAAQv9B,MAAAw9B,KAAA,CAAY,CAAAjE,EAAZ,CACZgE,EAAAE,KAAA,EACA,KAAK,IAAIx0C,EAAI,CAAb,CAAgBA,CAAhB,CAAoBs0C,CAAAzwC,OAApB,CAAkC7D,CAAA,EAAlC,CACI0zC,EAAA,CAAAA,CAAA,CAAgBY,CAAA,CAAMt0C,CAAN,CAAhB,CAA0B,CAAAswC,EAAA,CAAgBgE,CAAA,CAAMt0C,CAAN,CAAhB,CAAAoC,MAA1B,CACA,CAAAiyC,CAAA,EARa,CAWrB,MAAoB,EAApB,CAAOA,CAbX;AA4FAhvB,QAAA,EAAS,CAATA,CAAS,CAAChlB,CAAD,CAAI2vC,CAAJ,CAAeD,CAAf,CAA0BttC,CAA1B,CACT,CADautC,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAQ,CAAR,CAAAA,CAAsBvtC,EAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAY,CAAZ,CAAAA,CAG/B,SAHoB,IAAA,EAAAstC,GAAAA,CAAAA,CAAQ,CAARA,CAAAA,CAGpB,GAAgB,CAAAA,EAAhB,EACA,KAAK,CAAL,CArxkBA,CAsxkBqB,CAtxkBrB,CAsxkB6B,CAAR,CAAAC,CAAA,CAAWA,CAAX,CAAmB,CAtxkBxC,EAUiB,EAVjB,CAUWztC,CAVX,GAUqBA,CAVrB,CAU2B,EAV3B,GAEQ1B,CAEA,CAFIoB,IAAAe,IAAA,CAoxkBM3C,CApxkBN,CAEJ,CAAAkC,CAAA,CADK,GAAT,EAAI1B,CAAJ,CACU,CADV,CAEgB,MAAT,EAAIA,CAAJ,CACG,EADH,CAGG,EARd,CAWA,EAAA,CAAOoC,EAAA,CA2wkBW5C,CA3wkBX,CAAc,CAAd,CAAiBkC,CAAjB,CAAsB,EAAtB,CA2wkBoCE,CA3wkBpC,CA4wkBH,MACJ,MAAK,CAAL,CACI/B,CAAA,CAAIsjB,EAAA,CAAU3jB,CAAV,CAAqB,CAAR,CAAA2vC,CAAA,EAAaA,CAAb,CAAqB,CAArB,EAAwB,CAAxB,CAA2B,CAA3B,CAA+B,CAA5C,CAA+C,CAAC,CAACvtC,CAAjD,CACJ,MACJ,MAAK,EAAL,CAII/B,CAAA,CAAI+zC,EAAA,CAAUp0C,CAAV,CAAqB,CAAR,CAAA2vC,CAAA,CAAW/tC,IAAAS,KAAA,CAAkB,EAAlB,CAAUstC,CAAV,CAAX,CAAoC,CAAjD,CACJ,MAEJ,SACItvC,CAAA,CAAI6kB,CAAA,CAAUllB,CAAV,CAAqB,CAAR,CAAA2vC,CAAA,CAAaA,CAAb,CAAqB,CAArB,EAA2B,CAA3B,CAAgC,CAA7C,CAAgD,CAAC,CAACvtC,CAAlD,CAfR,CAkBgB,CAAR,CAAAutC,CAAA,CA/0jBRtvC,CA+0jBQ,CAAWA,CA/0jBfc,QAAA,CAAU,kBAAV,CAA8B,IAA9B,CA+0jBI,CAAsCd,CAAtC,CAAsCA,CAA9C,OAAQ,EApBZ;AAqCA,IAAAsyC,GAA4B,CACxB,KAAQ,CADgB,CAExB,WAAQ,CAFgB,CAGxB,IAAQ,CAHgB,CAIxB,IAAQ,CAJgB,CAKxB,KAAQ,CALgB,CAMxB,OAAQ,CANgB,CAOxB,QAAQ,EAPgB,CAQxB,WAAQ,EARgB,CASxB,WAAQ,EATgB,CAUxB,OAAQ,EAVgB,CAWxB,WAAQ,EAXgB,CAYxB,OAAQ,EAZgB,CAaxB,eAAQ,EAbgB,CAcxB,WAAQ,EAdgB,CAexB,WAAQ,EAfgB,CAgBxB,IAAQ,EAhBgB,CAiBxB,IAAQ,EAjBgB,CAkBxB,KAAQ,EAlBgB,CAmBxB,IAAQ,EAnBgB,CAoBxB,IAAQ,EApBgB,CAqBxB,EAAQ,EArBgB,CAsBxB,KAAQ,EAtBgB,CAuBxB,IAAQ,EAvBgB,CAwBxB,IAAQ,EAxBgB,CAA5B,CA0BAD,GAA4B,CACxB,KAAQ,CADgB,CAExB,KAAQ,CAFgB,CAGxB,WAAQ,CAHgB,CAIxB,QAAQ,EAJgB,CAKxB,WAAQ,EALgB,CAMxB,WAAQ,EANgB,CAOxB,OAAQ,EAPgB,CAQxB,WAAQ,EARgB,CASxB,OAAQ,EATgB,CAUxB,eAAQ,EAVgB,CAWxB,WAAQ,EAXgB,CAYxB,WAAQ,EAZgB,CAaxB,IAAQ,EAbgB,CAcxB,IAAQ,EAdgB,CAexB,KAAQ,EAfgB,CAgBxB,IAAQ,EAhBgB,CAiBxB,IAAQ,EAjBgB,CAkBxB,IAAQ,EAlBgB,CAmBxB,IAAQ,EAnBgB,CAoBxB,KAAQ,EApBgB,CAqBxB,OAAQ,EArBgB,CAsBxB,EAAQ,EAtBgB,CAuBxB,KAAQ,EAvBgB,CAwBxB,IAAQ,EAxBgB,CAyBxB,IAAQ,EAzBgB,CA1B5B,CAyDA9B,GAAqBhvC,IAAAC,IAAA,CAAS,CAAT,CAAY,EAAZ,CAiDrBwL;QAjBEgnC,GAiBS,CAAC5E,CAAD,CACX,CAGQ,EAAA,KAAA,CAAA,IAAA,CAAMA,CAAN,CAKA,KAAAzlB,GAAA,CAAa,CAAA,CACb,KAAAxI,GAAA,CAAiB,EAEjB,KAAAmuB,EAAA,CAAa,EACb,KAAAC,EAAA,CAAgB,CAAC,MAAD,CAAK,MAAL,CAChB,KAAAC,GAAA,CAAkB,EASlB,KAAAyE,GAAA,CAAkBC,CAAA,EAClB,KAAAC,EAAA,CAAmBD,CAAA,CAAa,CAAb,CACnB,KAAAE,GAAA,CAAmBF,CAAA,CAAa,CAAb,CACnB,KAAAG,GAAA,CAAuBH,CAAA,CAAa,CAAb,CAcvB,KAAAI,EAAA,CAAoB,EAapB,KAAAC,EAAA,CAAkB,IAAA1tB,EAAlB,CAAoC,IAAAE,EAApC,CAAuD,EACvDytB,GAAA,CAAAA,IAAA,CAcA,KAAAC,EAAA,CARA,IAAAC,GAQA,CAR0B,CAS1B,KAAAC,EAAA,CAA2B,EAC3B,KAAAC,GAAA,CAAmB5wC,IAAAA,EACnB6wC,GAAA,CAAAA,IAAA,CAKA,KAAAzmC,EAAA,CAAW,IACX,KAAA0mC,GAAA,CAAkB,EAClB,KAAA3nC,GAAA,CAAsC,CACtC,KAAA4nC,GAAA,CAAoB,IACpB,KAAAC,EAAA,CAAsB,EACtBC,GAAA,CAAAA,IAAA,CAAiB7F,CAAA,SAAjB,CACA,KAAArlB,GAAA,CAAqBqlB,CAAA,SACrB,KAAAj9B,GAAA,CAAiB,EAMjB,KAAA+iC,EAAA,CAAa,CAEb,KAAAC,GAAA,CADA,IAAAC,GACA,CADqB,IAIrB,KAAAhuB,EAAA,CAAe,IAAAiuB,GAAf,CAAmC,IAAAC,GAAnC,CADA,IAAAC,GACA,CAFA,IAAAC,GAEA,CAFuB,CAWvB,KAAAC,GAAA,CAPA,IAAAn5B,GAOA,CARA,IAAAo5B,EAQA,CARoB,IAmBpB,KAAItnC,EAAM,IACNlI,OAAJ,CACmClC,IAAAA,EADnC,GACQkC,MAAA,CAAO4J,CAAP,CADR,GAEQ5J,MAAA,CAAO4J,CAAP,CAFR,CAEiC,QAAQ,CAAC9P,CAAD,CAAI,CAAE,MAAOiqB,GAAA,CAAA7b,CAAA;AAAepO,CAAf,CAAT,CAF7C,EAKmCgE,IAAAA,EALnC,GAKQ2xC,MAAA,CAAO7lC,CAAP,CALR,GAMQ6lC,MAAA,CAAO7lC,CAAP,CANR,CAMiC,QAAQ,CAAC9P,CAAD,CAAI,CAAE,MAAOiqB,GAAA,CAAA7b,CAAA,CAAepO,CAAf,CAAT,CAN7C,CAlHR,CAlBwB6b,EAAAszB,CAAtB6E,EAAsB7E,CAAAA,EAAAA,CAyJxByG,SAAA,GAAO,CAACC,CAAD,CACP,CACQnzB,CAAAA,CAAOmzB,CAAPnzB,EAAkBmzB,CAAAnzB,EACV,KAAZ,EAAIA,CAAJ,GAAkBA,CAAlB,CAzieaozB,EAyieb,CACA,OAAOpzB,EAHX,CAiBAwxB,QAAA,EAAO,CAACxxB,CAAD,CAAcqzB,CAAd,CAAiC1G,CAAjC,CACP,CACI,MAAO,CAAC3sB,EAFJ,IAAA,EAAAA,GAAAA,CAAAA,CAAO,IAAPA,CAAAA,CAEG,CAAaqzB,GAFH,IAAA,EAAAA,GAAAA,CAAAA,CAAY,CAAA,CAAZA,CAAAA,CAEV,CAAmCC,GAAY,CAAA,CAA/C,CAAsD3G,EAAOA,CAA7D,CADX,CAmCA4G,QAAA,GAAO,CAACJ,CAAD,CAAUnzB,CAAV,CAAgBqzB,CAAhB,CAA2B1G,CAA3B,CACP,CACIwG,CAAAnzB,EAAA,CAAeA,CACfmzB,EAAAE,GAAA,CAAoBA,CAApB,EAAiC,CAAA,CACjCF,EAAAG,GAAA,CAAqB,CAAA,CACrBH,EAAAxG,EAAA,CAAgBA,CAJpB,CAiBA6G,QAAA,GAAQ,CAACL,CAAD,CACR,CACI,MAAO,CAACA,CAAAnzB,EAAD,CAAemzB,CAAAE,GAAf,CAAkCF,CAAAG,GAAlC,CAAsDH,CAAAxG,EAAtD,CAAqEwG,CAAA7F,GAArE,CADX,CAaAmG,QAAA,GAAU,CAAVA,CAAU,CAACC,CAAD,CACV,CACI,IAAIP,EAAU3B,CAAA,CAAakC,CAAA,CAAM,CAAN,CAAb,CAAuBA,CAAA,CAAM,CAAN,CAAvB,CAAiCA,CAAA,CAAM,CAAN,CAAjC,CACdP,EAAAG,GAAA,CAAqBI,CAAA,CAAM,CAAN,CACjBA,EAAA,CAAM,CAAN,CAAJ,GACIP,CAAAQ,GADJ,CACoBtG,EAAA,CAAAA,CAAA,CAAkB8F,CAAA7F,GAAlB,CAAiCoG,CAAA,CAAM,CAAN,CAAjC,CADpB,CAGA,OAAOP,EANX,CAkBA,CAAA,CA/0mBJ,EAAAS,UA+0mBInjC;CAAA0J,GAAA,CAAAA,QAAO,CAACtO,CAAD,CAAMD,CAAN,CAAWD,CAAX,CAAgBD,CAAhB,CACP,CACI,IAAAE,EAAA,CAAWA,CACX,KAAAC,EAAA,CAAWA,CACX,KAAAF,EAAA,CAAWA,CACX,KAAAiO,GAAA,CAAa/N,CAAA+N,EACb,KAAA6E,GAAA,CAAiB7S,CAvkbV6S,EA6kbP,EADIo1B,CACJ,CADiD/sB,EAAA,CAAAjb,CAAA,CAAmB,UAAnB,CACjD,GAAe0mC,EAAA,CAAAA,IAAA,CAAiBsB,CAAjB,CAMf,IADIC,CACJ,CADiDhtB,EAAA,CAAAjb,CAAA,CAAmB,UAAnB,CACjD,CAAe,IAAAwb,GAAA,CAAqBysB,CAMpCC,GAAA,CAAAA,IAAA,CAAqCC,QAAkB,CAACC,CAAD,CAAS,CAqVpE,CAAA,CAAA,CA6CoBj1B,IAAAA,EAlYkDtT,CAkYlDE,EAAAoT,EAAAA,CAAqB,EAlYyCi1B,CAkYzC,CAAO,CAAP,CAArBj1B,CA5CFpiB,EAAVojB,CAAUpjB,CAAH,CA4CKoiB,CA5CK/hB,EAAI+qC,CAAAvnC,OAEzB,IAAIyzC,CAAJ,CAAW,CACPl0B,CAAA,CAAOkzB,EAAA,CAAaiB,EAAA,CAzV0CzoC,CAyV1C,CAAewoC,CAAf,CAzV0CxoC,CAyVpBgmC,GAAtB,CAAb,CACP,IAjgfS0B,EAigfT,GAAIpzB,CAAJ,CAAiC,CA1V6BtU,CA2V1DuF,EAAA,CAAa,mBAAb,CAAmCijC,CAAnC,CACA,OAAA,CAF6B,CAIjCt3C,CAAA,CAAIojB,CAAJ,GA9V8DtU,CA8VjDE,EAAA+S,EACb1hB,EAAA,CAAI,CAPG,CAxVuDyO,CAkWlEuF,EAAA,CAAa,sDAAb,CAlWkEvF,EAmWlEuF,EAAA,CAAa,sDAAb,CAEImjC,EAAAA,CAAY,EAChB,KADA,IAAmBC,EAAQ,CAC3B,CAAOp3C,CAAA,EAAP,CAAA,CAAY,CACR,IAAIgiB,EAAQ+oB,CAAA,CAAQprC,CAAR,CACRqiB,EAAArc,KAAJ,EAAkBwxC,CAAlB,CACSC,CAAA,EADT,EAxW8D3oC,CAyW5CuF,EAAA,CAAa,KAAb,CADlB,EAGImjC,CAMA,CANWn1B,CAAArc,KAMX,CALI8L,CAKJ,CALYiS,EAAA,CAAuByzB,CAAvB,CAKZ,CAJIn1B,CAIJ,EAjX0DvT,CA8WtDuF,EAAA,CAAakR,CAAA,CAAUlD,CAAAvU,GAAV,CAAoB,CAApB,CAAb,CAAsC,KAAtC;AAA8CyX,CAAA,CAAUvlB,CAAV,EA9WQ8O,CA8WOE,EAAA+S,EAAf,CAAqC,CAArC,CAA9C,CAAwF,KAAxF,CAAgGwD,CAAA,CAAUlD,CAAAe,EAAV,CAAsB,CAAtB,CAAhG,CAA2H,IAA3H,CA93lBLmC,CAAA,CA83lBqJlD,CAAAqB,GA93lBrJ,CAAa,CAAb,CAAgB,CAAA,CAAhB,CA83lBK,CAA8J,IAA9J,CA93lBL6B,CAAA,CA83lBwLlD,CAAAgB,KA93lBxL,CAAa,CAAb,CAAgB,CAAA,CAAhB,CA83lBK,CAAiM,IAAjM,CAAwMvR,CAAxM,CAGJ,CADI0lC,CACJ,EADgBtxB,EAChB,GADuCsxB,CACvC,CADmD,EACnD,EAAAC,CAAA,CAAQ,CATZ,CAWAr0B,EAAA,EAvgccnB,KAwgcdjiB,EAAA,EAdQ,CAjBhB,CArVoE,CAAhE,CAEAiV,GAAA,CAAAA,IAAA,CAzBJ,CAsCApB;CAAAvC,GAAA,CAAAA,QAAU,CAACyC,CAAD,CAAYC,CAAZ,CAAsB/D,CAAtB,CACV,CACI,IAAInB,EAAM,IACV,QAAQkF,CAAR,EAEA,KAAK,YAAL,CAiCI,MA/BA,KAAAoiC,EA+BO,CAhCP,IAAAnoC,EAAA,CAAc+F,CAAd,CAgCO,CAhCmB/D,CAgCnB,CAzBPA,CAAAu9B,UAyBO,CAzBaC,QAA4B,CAACpwB,CAAD,CAAQ,CAEpD,GAtnmBgBuwB,EAsnmBhB,EAAIvwB,CAAAswB,QAAJ,CAAsC,CAClC,IAAA+C,EAAO5hC,CAAAsnC,EAAAh0C,MACP0M,EAAAsnC,EAAAh0C,MAAA,CAAyB,EACzBuoB,GAAA,CAAA7b,CAAA,CAAe4hC,CAAf,CAAqB,CAAA,CAArB,CAHkC,CAAtC,IAKK,IArnmBW9C,EAqnmBX,EAAIvwB,CAAAswB,QAAJ,CACD7+B,CAAAsnC,EAAAh0C,MAAA,CAAyBsuC,CAAzB,CAAgC,EAD/B,KAUD,IAxnmBY9C,EAknmBZ,EAAIvwB,CAAAswB,QAAJ,EA38CR+C,CACJ,CADW,IACX,CA28CuB5hC,CA38CnBshC,EAAJ,CA28CuBthC,CA38CHuhC,EAAAxsC,OAApB,CAA4C,CAA5C,GACI6sC,CADJ,CA28CuB5hC,CA18CZuhC,EAAA,CAAe,EA08CHvhC,CA18CKshC,EAAjB,CADX,CA08CY,EA/mmBYxC,EA+mmBZ,EAGSvwB,CAAAswB,QAHT,GA59CQ,CAApB,CAg+CuB7+B,CAh+CnBshC,EAAJ,CACIM,CADJ,CAg+CuB5hC,CA/9CZuhC,EAAA,CAAe,EA+9CHvhC,CA/9CKshC,EAAjB,CADX,EAGIM,CACA,CADO,EACP,CA49CmB5hC,CA59CnBshC,EAAA,CAAiB,EAJrB,CA49CY,CAMI,CAAQ,IAAR,EAAAM,CAAJ,CAAkB,CACd,IAAInuC,EAAMmuC,CAAA7sC,OACViL,EAAAsnC,EAAAh0C,MAAA,CAAyBsuC,CACzB5hC,EAAAsnC,EAAAsB,kBAAA,CAAmCn1C,CAAnC,CAAwCA,CAAxC,CAHc,CAMV,IAAZ,EAAImuC,CAAJ,EAAoBrzB,CAAAC,eAApB,EAA0CD,CAAAC,eAAA,EAvBU,CAyBjD,CAAA,CAAA,CAEX,MAAK,YAAL,CAgBI,MAfA,KAAArP,EAAA,CAAc+F,CAAd,CAeO,CAfmB/D,CAenB,CAdP0nC,EAAA,CACI1nC,CADJ,CAGI2nC,QAA0B,EAAU,CAChC,GAAI9oC,CAAAsnC,EAAJ,CAAsB,CAClB,IAAI1F,EAAO5hC,CAAAsnC,EAAAh0C,MACX0M;CAAAsnC,EAAAh0C,MAAA,CAAyB,EACzBuoB,GAAA,CAAA7b,CAAA,CAAe4hC,CAAf,CAAqB,CAAA,CAArB,CACA,OAAO,CAAA,CAJW,CAOtB,MAAO,CAAA,CARyB,CAHxC,CAcO,CAAA,CAAA,CAEX,MAAK,MAAL,CAeI,MAdA,KAAAziC,EAAA,CAAc+F,CAAd,CAcO,CAdmB/D,CAcnB,CAbP0nC,EAAA,CACI1nC,CADJ,CAGI4nC,QAAoB,CAACC,CAAD,CAAU,CAC1B,IAAIC,EAAa,CAAA,CACZ7iC,GAAA,CAAApG,CAAA,CAAW,CAAA,CAAX,CAAL,GACIsG,EAAA,CAAAtG,CAAA,CAAY,CAAA,CAAZ,CAEA,CADAipC,CACA,CADat4B,EAAA,CAAA3Q,CAAA,CAAYgpC,CAAA,CAAS,CAAT,CAAa,CAAzB,CAA4B,IAA5B,CACb,CAAA1iC,EAAA,CAAAtG,CAAA,CAAY,CAAA,CAAZ,CAHJ,CAKA,OAAOipC,EAPmB,CAHlC,CAaO,CAAA,CAAA,CAtEX,CA2EA,MAAO,CAAA,CA7EX,CAsFAvtB,SAAA,GAAQ,CAARA,CAAQ,CACR,CACI,GAAI,CAAA4rB,EAAJ,CAAuB,CAAA,IAMfr1C,EAAI,CANW,CAMRC,EAAI,CACC4F,OAAhB,GACI7F,CACA,CADI6F,MAAAoxC,QACJ,CAAAh3C,CAAA,CAAI4F,MAAAqxC,QAFR,CAKA,EAAA7B,EAAA8B,MAAA,EAEgBtxC,OAAhB,EACIA,MAAAuxC,SAAA,CAAgBp3C,CAAhB,CAAmBC,CAAnB,CAfe,CAD3B,CA6BA6S,CAAAukC,GAAA,CAAAC,QAAO,CAAC9B,CAAD,CAAUh2B,CAAV,CACP,CACI,IAAIzf,EAryeSmmB,EAqyeb,CACI7D,EAAOkzB,EAAA,CAAaC,CAAb,CA9yeEC,GA+yeb,GAAIpzB,CAAJ,GACItiB,CACA,CADIsf,EAAA,CAAA,IAAApR,EAAA,CAAuBoU,CAAvB,CACJ,CAAI7C,CAAJ,EAsJgB,IAtJhB,EAAsBg2B,CAsJtBnzB,EAtJA,GAAsBmzB,CAuJtBnzB,EAvJA,EAA+B7C,CAA/B,EAuJwB,CAvJxB,CAFJ,CAIA,OAAOzf,EAPX,CAkBA+S,EAAAykC,GAAA,CAAAC,QAAO,CAAChC,CAAD,CAAUz1C,CAAV,CAAayf,CAAb,CACP,CACI,IAAI6C,EAAOkzB,EAAA,CAAaC,CAAb,CAh0eEC,GAi0eb,GAAIpzB,CAAJ,GACIlD,EAAA,CAAA,IAAAlR,EAAA,CAAuBoU,CAAvB,CAA6BtiB,CAA7B,CAEA,CADIyf,CACJ,EAmIgB,IAnIhB,EADsBg2B,CAoItBnzB,EAnIA,GADsBmzB,CAqItBnzB,EApIA,EAD+B7C,CAC/B,EAoIwB,CApIxB,EAAAP,CAAA,CAAA,IAAA/Q,EAAA,CAAyB,EAAzB,CAHJ,CAFJ,CAmBA4E;CAAAs9B,GAAA,CAAAA,QAAO,CAACvf,CAAD,CAAMD,CAAN,CACP,CAKc,CAAV,CAAIC,CAAJ,GAAaA,CAAb,EAAoBhR,CAApB,CACU,EAAV,CAAI+Q,CAAJ,GAAaA,CAAb,EAAoB/Q,CAApB,CACI6V,EAAAA,CAASyD,EAAAvmB,KAAA,CAAiB,IAAA5E,EAAjB,CAA2B6iB,CAA3B,CAAgCD,CAAhC,CAAqC,CAAA,CAArC,CAA4C,CAAA,CAA5C,CACT8E,EAAJ,EAAcjD,CAAd,GAA+BiD,CAA/B,EAAyC7V,CAAzC,CASA,OAAO6V,EAjBX,CAmCA8gB;QAAA,GAAS,CAATA,CAAS,CAACD,CAAD,CAAQf,CAAR,CACT,CAAA,IACmBxG,CACVwG,EAAL,GAAcA,CAAd,CAAwB3B,CAAA,EAAxB,CACA,KAAIxxB,EAAOmzB,CAAAnzB,EACX,IAAc1e,IAAAA,EAAd,GAAI4yC,CAAJ,CAAyB,CAx6B7B,CAAA,CAAA,CAEQkB,CAAAA,CAu6BQC,CAv6BCxI,EAAA,CAAc,CAAd,CACb,KAAIyI,EAs6BQD,CAt6BExI,EAAA,CAAc,CAAd,CACV0I,KAAAA,EAAsB,GAAX,EAACH,CAAD,EAA4B,GAA5B,EAAkBA,CAAlB,EAA6C,GAA7C,EAAmCA,CAAnC,CAAmD,IAAnD,CAA0D,EACzE,KAAII,EAA2B,GAAV,EAAAJ,CAAA,CAAe,IAAf,CAAsB,EAE3C,KADIK,CACJ,CADe,IAAIrmC,MAAJ,CAAWmmC,CAAX,CAAsBH,CAAtB,CAA+B,KAA/B,CAAuCI,CAAvC,CAAuDJ,CAAvD,CAAgEI,CAAhE,CAAgFF,CAAhF,CAA0F,KAA1F,CAAkGC,CAAlG,CAA6GD,CAA7G,CACf,CAAOl5C,CAAP,CAAWkB,CAAAqB,MAAA,CAAQ82C,CAAR,CAAX,CAAA,CAA8B,CAC1B,IAAIz2C,EAAQixC,EAAA,CAi6BJoF,CAj6BI,CAAqBj5C,CAAA,CAAE,CAAF,CAArB,CACZ,IAAckF,IAAAA,EAAd,GAAItC,CAAJ,CAAyB,CAAA,CAAA,CAAA,IAAA,EAAA,OAAA,CAAA,CAazB1B,CAAA,CAAIA,CAAAc,QAAA,CAZUg3C,CAYV,CAZmBh5C,CAAA,CAAE,CAAF,CAYnB,CAZ0Bk5C,CAY1B,CAXoB,IAATI,EAAA12C,CAAA02C,CAAezzB,CAAA,CA85BtBozB,CA95BsB,CAAer2C,CAAf,CAAf02C,CAAuC,WAWlD,CAfsB,CAiB9B,GAi5BYL,CAj5BRvI,GAAArsC,OAAJ,CAMI,IALA20C,CAIA,CA44BQC,CAh5BCvI,GAAA,CAAgB,CAAhB,CAIT,CAHAwI,CAGA,CA44BQD,CA/4BEvI,GAAA,CAAgB,CAAhB,CAGV,CAFAyI,CAEA,CAFsB,GAAX,EAACH,CAAD,EAA4B,GAA5B,EAAkBA,CAAlB,EAA6C,GAA7C,EAAmCA,CAAnC,CAAmD,IAAnD,CAA0D,EAErE,CADAI,CACA,CAD2B,GAAV,EAAAJ,CAAA,CAAe,IAAf,CAAsB,EACvC,CAAAK,CAAA,CAAW,IAAIrmC,MAAJ,CAAWmmC,CAAX,CAAsBH,CAAtB,CAA+B,KAA/B,CAAuCI,CAAvC,CAAuDJ,CAAvD,CAAgEI,CAAhE,CAAgFF,CAAhF,CAA0F,KAA1F,CAAkGC,CAAlG,CAA6GD,CAA7G,CACX,CAAOl5C,CAAP,CAAWkB,CAAAqB,MAAA,CAAQ82C,CAAR,CAAX,CAAA,CACIn4C,CAAA,CAA4BA,CA5wB7Bc,QAAA,CAAU,GAAV,CA4wBgChC,CAAA83C,CAAE,CAAFA,CA5wBhC,CAAwB,GAAxB,CAA6B,eAA7B,CAgyBP,KAAA,CAAO93C,CAAP,CAAWkB,CAAAqB,MAAA,CAAQ,aAAR,CAAX,CAAA,CAAmC,CAC3BlB,CAAAA;AAAI,IACR,QAAOrB,CAAA,CAAE,CAAF,CAAAkE,YAAA,EAAP,EACA,KAAK,KAAL,CACI7C,CAAA,CAAI,CAFR,CAKA,GAAS,IAAT,EAAIA,CAAJ,CAAe,KACfH,EAAA,CAAIA,CAAAc,QAAA,CAAUhC,CAAA,CAAE,CAAF,CAAV,CAAgBqB,CAAAiT,SAAA,EAAhB,CAR2B,CAnDvC,CA26BQ,GAAU,GAAV,EADSwjC,CAAA51C,OAAAD,CAAa,CAAbA,CACT,CAAe,CACX,IAAAg1C,EAAY,CAAA,CACZa,EAAA,CAAQA,CAAA31C,OAAA,CAAa,CAAb,CAFG,CAIf,IAAIo3C,CAAiCzB,EAAAA,CAAAA,CAk7DzC,IAAI0B,CAAAj3C,MAAA,CAAc,qBAAd,CAAJ,CAEI,IADIk3C,CACKC,CADQF,CAAAG,YAAA,EACRD,CAAAA,CAAAA,CAAS,CAAlB,CAAqBA,CAArB,CAp7DiBE,CAo7DapE,EAAAnxC,OAA9B,CAAwDq1C,CAAA,EAAxD,CAGI,GADIG,CACA,CAv7DSD,CAq7DKpE,EAAAsE,CAAkBJ,CAAlBI,CACLtxC,EAAA,CAAqBixC,CAArB,CACT,CAAU,IAAV,EAAAI,CAAJ,CAAoB,CAChB,IAAAE,EAAYF,CAAA,EAUZ,MAXgB,CAeX,IAAjB,EAAIE,CAAJ,GACIhD,CADJ,CACc3B,CAAA,CAAa2E,CAAb,CADd,CAr8DI,IAAIR,CAAJ,CAAgB,MAAOA,EACI,EAA3B,EAAIzB,CAAA/1C,QAAA,CAAc,IAAd,CAAJ,CACIwuC,CADJ,CACY,EADZ,CAEkC,CAA3B,EAAIuH,CAAA/1C,QAAA,CAAc,IAAd,CAAJ,CACHwuC,CADG,CACK,CADL,CAE0B,CAF1B,EAEIuH,CAAA/1C,QAAA,CAAc,GAAd,CAFJ,GAGHwuC,CAHG,CAGK,EAHL,CAKP3sB,EAAA,CAAOiwB,EAAA,CAAAA,CAAA,CAAqBiE,CAArB,CAhBc,CAkBb,IAAZ,EAAIl0B,CAAJ,GACIA,CACA,CADOo2B,EAAA,CAAkBp2B,CAAlB,CAAwB,CAAAvB,GAAxB,CACP,CAAA80B,EAAA,CAAaJ,CAAb,CAAsBnzB,CAAtB,CAA4BqzB,CAA5B,CAAuC1G,CAAvC,CAFJ,CAIA,OAAOwG,EA1BX;AAoCAkD,QAAA,GAAgB,CAAhBA,CAAgB,CAAClD,CAAD,CAAUmD,CAAV,CAChB,CACQA,CAAJ,GACQl6C,CADR,CACYk6C,CAAA33C,MAAA,CAAe,eAAf,CADZ,IAGQw0C,CAAAQ,GAHR,CAGwBtG,EAAA,CAAAA,CAAA,CAAkB8F,CAAA7F,GAAlB,CAAiClxC,CAAA,CAAE,CAAF,CAAjC,CAHxB,CADJ,CAiBAg6C,QAAA,GAAY,CAAC14C,CAAD,CAAIu6B,CAAJ,CACZ,CAMY,CAAR,CAAIv6B,CAAJ,EAAaA,CAAb,EAAkB,CAAC0yB,CAAnB,GACI1yB,CADJ,EACS8f,CADT,CAOA,OAJY3e,KAAAE,MAAA,CAAWF,IAAAe,IAAA,CAASlC,CAAT,CAAX,CAIZ,CAJsCmB,IAAAC,IAAA,CAAS,CAAT,CAV1B,IAAA,EAAAm5B,GAAAA,CAAAA,CAAO,EAAPA,CAAAA,CAU0B,CAT1C,CA6DAse,QAAA,GAAS,CAATA,CAAS,CAAC74C,CAAD,CACT,CAKI,MAAOukB,EAAA,CAAAA,CAAA,CAAevkB,CAAf,CAAmB6uB,EAAnB,CAAqC,EAArC,CAAP,CAAkD,GAAlD,CAAwDtK,CAAA,CAAAA,CAAA,CAAevkB,CAAf,CAAmB6uB,EAAnB,CAAqC,EAArC,CAL5D;AAkMAgmB,QAAA,GAAW,CAAXA,CAAW,CAACiE,CAAD,CACX,CACI,CAAA9qC,EAAA,CAAW,CACX,EAAAjB,GAAA,CAAsC,SACtC,EAAA4nC,GAAA,CAAoB,IACpB,EAAAC,EAAA,CAAsB,EAKlBmE,EAAAA,CAAUpJ,EAAA,CAAAA,CAAA,CAAkBmJ,CAAAp4C,QAAA,CAAgB,MAAhB,CAAuB,KAAvB,CAAAA,QAAA,CAAsC,KAAtC,CAA4C,UAA5C,CAAlB,CAA2E,CAAA,CAA3E,CAAkF,GAAlF,CACd,IAAIq4C,CAAAh2C,OAAJ,CACI,IAAKzD,IAAIA,CAAT,GAAc4Y,GAAd,CAAwC,CAnzkBhD,CAAA,CAAA,CADqBhZ,IAAAA,EAAAA,IAAAA,EAEjB,IAAIyI,KAAArE,UAAA7C,QAAJ,CACI,CAAA,CAkzkBoBs4C,CAlzkBbt4C,QAAA,CAkzkBsBnB,CAlzkBtB,CAAaJ,CAAb,CADX,KAAA,CAGAA,CAAA,CAAIA,CAAJ,EAAS,CACD,EAAR,CAAIA,CAAJ,GAAWA,CAAX,EA+ykBwB65C,CA/ykBRh2C,OAAhB,CACQ,EAAR,CAAI7D,CAAJ,GAAWA,CAAX,CAAe,CAAf,CACA,KAAK,IAAIK,EA6ykBew5C,CA7ykBXh2C,OAAb,CAAuB7D,CAAvB,CAA2BK,CAA3B,CAA8BL,CAAA,EAA9B,CACI,GAAIA,CAAJ,GA4ykBoB65C,EA5ykBpB,EA4ykBoBA,CA5ykBN,CAAE75C,CAAF,CAAd,GA4ykB6BI,CA5ykB7B,CAA0B,MAAA,CAE9B,EAAA,CAAQ,EATR,CADJ,CAozkB2C,CAA/B,EAAI,CAAJ,GACI,CAAAyN,GACA,EADoBmL,EAAA,CAAyB5Y,CAAzB,CACpB,CAAA,CAAAiU,EAAA,CAAajU,CAAb,CAAiB,mBAAjB,CAFJ,CADoC,CAXhD,CA4BA+2C,QAAA,GAAW,CAAXA,CAAW,CAAa2C,CAAb,CACX,CACI,IAAK15C,IAAIA,CAAT,GAAc4Y,GAAd,CACI,GA7gfIK,EA6gfJ,EAAkBL,EAAA,CAAyB5Y,CAAzB,CAAlB,CAA+C,CAC3C,CAAAo1C,GAAA,CAAgBp1C,CAAhB,CAAA,CAAqB05C,CACrB,MAF2C,CAFvD,CAkBAjmC,CAAA08B,GAAA,CAAAA,QAAW,CAACwJ,CAAD,CACX,CACI,MAAOC,GAAAz4C,QAAA,CAA+Bw4C,CAAAZ,YAAA,EAA/B,CADX,CAuBAtlC;CAAA28B,GAAA,CAAAA,QAAW,CAACoD,CAAD,CACX,CACI,IACI7kC,EAAM,IAAAA,EACV,QAAO6kC,CAAP,EACA,KAAKqG,EAAL,CACI,IAAA73C,EAAQ2M,CA/0WL8R,EAg1WH,MACJ,MAAKq5B,EAAL,CACI93C,CAAA,CAAQ2M,CAAAkf,EACR,MACJ,MAAKksB,EAAL,CACI/3C,CAAA,CAAQ2M,CAAAif,EACR,MACJ,MAAKosB,EAAL,CACIh4C,CAAA,CAAQ2M,CAn+WJuf,EAm+WJ,CAn+WiBwD,CAo+WjB,MACJ,MAAKuoB,EAAL,CACIj4C,CAAA,CAAS2M,CAAAuf,EAAD,CA9pfAkB,MA8pfA,CAAiC,CAAjC,CAAqC,CAC7C,MACJ,MAAK8qB,EAAL,CACIl4C,CAAA,CAAS2M,CAAAuf,EAAD,CAhqfAkB,KAgqfA,CAAiC,CAAjC,CAAqC,CAC7C,MACJ,MAAK+qB,EAAL,CACIn4C,CAAA,CAAS2M,CAAAuf,EAAD,CAlqfAkB,KAkqfA,CAAiC,CAAjC,CAAqC,CAC7C,MACJ,MAAKgrB,EAAL,CACIp4C,CAAA,CAAS2M,CAAAuf,EAAD,CAnqfAkB,IAmqfA,CAAgC,CAAhC,CAAoC,CAC5C,MACJ,MAAKirB,EAAL,CACIr4C,CAAA,CAAS2M,CAAAuf,EAAD,CAlqfAkB,EAkqfA,CAAgC,CAAhC,CAAoC,CAC5C,MACJ,MAAKkrB,EAAL,CACIt4C,CAAA,CAAS2M,CAAAuf,EAAD,CAhqfDkB,MAgqfC,CAAiC,CAAjC,CAAqC,CA7BjD,CAgCA,MAAOptB,EAnCX,CA2GAyR;CAAAjL,QAAA,CAAAA,QAAO,CAAC8G,CAAD,CAAWmG,CAAX,CACP,CACQA,CAAJ,GACInG,CADJ,EACgB,IADhB,CA/YO2V,CAAA,CAgZgBs1B,IAhZhB,CAgZ+B/F,CAAA2B,CAAa,IAAAxnC,EAr5W5Cmf,GAq5W+BqoB,CApYdnzB,EAZjB,CAAoB,EAApB,CA+YP,CAIA,IAAIqyB,CAAA,IAAAA,GAAJ,EAAyB/lC,CAAzB,EAAqC,IAAA+lC,GAArC,CAGA,GAFA,IAAAA,GAEI,CAFgB/lC,CAEhB,CAAA,IAAA7B,GAAA,CAzpfIyM,UAypfR,CACI,IAAAo7B,EAAAzsC,KAAA,CAAyByG,CAAzB,CADJ,KAAA,CAKA,IAAIkrC,CACJ,IAAK,IAAA/sC,GAAL,CA9pfQ0M,WA8pfR,EAA+C,IAAAxL,EAA/C,GAA4D6rC,CAA5D,CAAuE,IAAA7rC,EAvzZhEX,MAAA+Q,EAuzZP,GAAgGjK,EAAA,CAAAA,IAAA,CAAY,CAAA,CAAZ,CAAhG,CACIsK,EAAA,CAAAA,IAAA,CACA,CAAIo7B,CAAJ,GAAclrC,CAAd,EAA0B,eAA1B,CAGJ,KAAA2E,EAAA,CAAa3E,CAAb,CAUI,KAAAX,EAAJ,GAAcA,CAnqZd,CAmqZcA,IAAAA,EAnqZd,CAkuBAod,EAAA,CAAAA,CAAA,CAluBA,CAmuBA,CAAA5D,GAnuBA,CAmuBwB,CAnuBxB,CAyuBAvI,CAzuBI/Q,EAAJ,EAAc+Q,CAAA,CAyuBdA,CAzuBc/Q,EAAA,CAFHud,IAAAA,EAEG,CAmqZd,CArBA,CARJ,CAgEA+oB;QAAA,GAAW,CAAXA,CAAW,CACX,CACI,IAAIv1C,CACJ,IAAI,CAAC+vB,EAAA,CAAAA,CAAA,CAAL,CACQ,CAAAslB,EAIJ,EAJgC,CAAAA,EAAAxxC,OAIhC,EAHI,CAAAwQ,EAAA,CAAa,kCAAb,CAGJ,CADA,CAAA8gC,EACA,CAD2B,CAC3B,CAAA,CAAAE,EAAA,CAA2B,EAL/B,KAQA,IAAI,CAAC,CAAAA,EAAL,EAAiC,CAAC,CAAAA,EAAAxxC,OAAlC,CAAmE,CAC/D,CAAAwxC,EAAA,CAA+B5sC,KAAJ,CAAUoyC,EAAV,CAC3B,KAAK76C,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB,CAAAq1C,EAAAxxC,OAAhB,CAAiD7D,CAAA,EAAjD,CAKI,CAAAq1C,EAAA,CAAyBr1C,CAAzB,CAAA,CAA8B40C,CAAA,EAElC,EAAAO,EAAA,CAA2B,CAEvB,EAAA9gC,EAAA,CAAa,sCAAb,CAX2D,CAVvE,CAkCAkL,QAAA,GAAQ,CAARA,CAAQ,CAACqM,CAAD,CAAe0nB,CAAf,CACR,CACI,GAAI,CAACwH,EAAA,CAAAA,CAAA,CAAcxH,CAAd,CAAL,CAA4B,MAAO,CAAA,CACnC/zB,GAAA,CAAA,CAAAxQ,EAAA,CAAkB6c,CAAlB,CACA,OAAO,CAAA,CAHX;AAeAnM,QAAA,GAAO,CAAPA,CAAO,CAACqI,CAAD,CAAUizB,CAAV,CAAiBC,CAAjB,CACP,CACI,GAAI,CAACF,EAAA,CAAAA,CAAA,CAAL,CAAsB,MAAO,CAAA,CAE7B,KAAIpK,EAAO,EACG,KAAd,GAAIqK,CAAJ,GAEIrK,CAFJ,CAEW,CADPqK,CACO,CADE,CAAC,CAAAjF,GACH,EAD+C,IAC/C,EADyB,CAAAA,GACzB,EAAO,IAAP,CAAc,GAFzB,CAKA,EAAAhuB,EAAA,CAAe,CAEVA,EAAL,EAMQiI,EAAA,CAAAA,CAAA,CANR,EAM8BG,EAAA,CAAAA,CAAA,CAAsB,CAAAnhB,EA3jX7C8R,EA2jXuB,CAAwC,CAAxC,CAK9B,IAAI,CACAiH,CAAA,CAAUkE,EAAA,CAAA,CAAAjd,EAAA,CAAwB+Y,CAAxB,CACV,KAAIpI,EAAc,CAAA3Q,EAAA0Q,GAAA,CAAiBqI,CAAjB,CACA,EAAlB,CAAIpI,CAAJ,GACIC,EAAA,CAAA,CAAA5Q,EAAA,CAAsB2Q,CAAtB,CAIA,CAHA,CAAAoI,EAGA,EAHgBpI,CAGhB,CAFAE,EAAA,CAAA,CAAA7Q,EAAA,CAAmB2Q,CAAnB,CAAgC,CAAA,CAAhC,CAEA,CADAG,EAAA,CAAA,CAAA9Q,EAAA,CAAwB2Q,CAAxB,CACA,CAAA,CAAAu2B,GAAA,EALJ,CAHA,CAWJ,MAAMn2B,CAAN,CAAiB,CAKW,QAAxB,EAAI,MAAOA,EAAX,GACQlgB,CAEJ,CAFQkgB,CAER,CADA,CAAAgI,EACA,CADe,CACf,CAAAhT,EAAA,CAAA,CAAA/F,EAAA,CAAkBnP,CAAAmgB,MAAlB,EAA6BngB,CAAAgJ,QAA7B,CAHJ,CALa,CAiBO,CAAA,CAAxB,GAAIoyC,CAAJ,GACQ,CAAAh+B,GACJ,EADgB,CAAAA,GAAAL,KAAA,EAChB,CAAAqD,CAAA,CAAA,CAAA/Q,EAAA,CAAyB,EAAzB,CAFJ,CAKAqb,GAAA,CAAAA,CAAA,CAAkBywB,CAAlB,EAA2B,CAAA,CAA3B,CAAkCrK,CAAlC,CACA,OAAuB,EAAvB,CAAQ,CAAA5oB,EAxDZ,CAiEAtI,QAAA,GAAO,CAAPA,CAAO,CAACuN,CAAD,CACP,CACQ,CAAAhe,EAAJ,EAAcyQ,CAAA,CAAA,CAAAzQ,EAAA,CAAiBge,CAAjB,CADlB,CAWAzC,QAAA,GAAY,CAAZA,CAAY,CAACywB,CAAD,CAAerK,CAAf,CACZ,CADaqK,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAQ,CAAA,CAAR,CAAAA,CAEJ,EAAA1wB,GAAL,GAEIqmB,CAWJ,EAVI,CAAAr8B,EAAA,CAAa4mC,EAAb,CAAoCvK,CAApC,CAUJ,CAPAiG,EAAA,CAAa,CAAA9B,EAAb,CAA+B,CAAA9lC,EA/nXxB8R,EA+nXP,CAOA,CAAKk6B,CAAL,EAA4B,CAA5B,EAAc,CAAAnF,EAAd,CAGIsF,EAAA,CAAAA,CAAA,CAHJ,CACIC,EAAA,CAAAA,CAAA,CAdJ,CADJ;AA8BAL,QAAA,GAAQ,CAARA,CAAQ,CAACxH,CAAD,CACR,CACQ,IAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,EAAA,EAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,IAAoC,CAAA,CAAA,CAAA,EAAA,CA1hanC,CAAAllC,MAAAK,EAAL,CAIA,CAJA,CAIO,CAAA,CAJP,EACI,CAAA4F,EAAA,CAAa,CAAAP,SAAA,EAAb,CAA+B,cAA/B,CACA,CAAA,CAAA,CAAO,CAAA,CAFX,CA0hawC,CAAA,CAAA,CAAA,CAAA,CAApC,CAAJ,OAAI,EAAJ,EAAiE,CAAA/E,EA3ga1DX,MAAA+Q,EA2gaP,EACSm0B,CACE,EADM,CAAAj/B,EAAA,CAAa,0CAAb,CACN,CAAA,CAAA,CAFX,EAIO,CAACU,EAAA,CAAA,CAAAhG,EAAA,CALZ,CAgBA8E,CAAAyB,GAAA,CAAAA,QAAO,CAACjN,CAAD,CAAOqV,CAAP,CACP,CACI,MAAI,CAACA,CAAL,GAMI,IAAAjB,MAAA,CAAW,CAAA,CAAX,CAIIpU,CAAAA,CAVR,EAWe,IAAAuV,QAAA,CAAavV,CAAb,CAXf,CAcO,CAAA,CAfX,CA0BAwL,EAAA0B,GAAA,CAAAA,QAAS,CAACC,CAAD,CAAQC,CAAR,CACT,CACQA,CAAJ,EAAe,IAAApB,EAAA,CAAamB,CAAA,CAAO,YAAP,CAAsB,eAAnC,CACf,OAAOA,EAAA,CAAO,IAAAqI,KAAA,EAAP,CAAqB,CAAA,CAFhC,CAaAhK,EAAA4I,MAAA,CAAAA,QAAK,CAAC62B,CAAD,CACL,CACIiC,EAAA,CAAAA,IAAA,CACA,KAAAU,GAAA,CAA+C,CAC/C,KAAAR,GAAA,CAAoB,IACpB,KAAA3tB,EAAA,CAAe,CACf6uB,GAAA,CAAa,IAAA9B,EAAb,CAA+B,IAAA9lC,EAttXxB8R,EAstXP,CAMA,KAAAzS,MAAA+Q,EAAA,CAAqB,CAAA,CACrBi8B,GAAA,CAAAA,IAAA,CACK9H,EAAL,EAAahpB,EAAA,CAAAA,IAAA,CAbjB,CAwBAzW;CAAAgK,KAAA,CAAAA,QAAI,EACJ,CACI,IAAIC,EAAQ,IAAIC,CAAJ,CAAU,IAAV,CACZD,EAAAE,IAAA,CAAU,CAAV,CAAa44B,EAAA,CAAc,IAAA/B,EAAd,CAAb,CACA/2B,EAAAE,IAAA,CAAU,CAAV,CAAa44B,EAAA,CAAc,IAAA9B,GAAd,CAAb,CACAh3B,EAAAE,IAAA,CAAU,CAAV,CAAa44B,EAAA,CAAc,IAAA7B,GAAd,CAAb,CACAj3B,EAAAE,IAAA,CAAU,CAAV,CAAa,CAAC,IAAAqyB,EAAD,CAAiB,IAAAF,EAAjB,CAAiC,IAAAtiC,GAAjC,CAAb,CACAiQ,EAAAE,IAAA,CAAU,CAAV,CAAa,IAAAg3B,EAAb,CACA,OAAOl3B,EAAAzV,KAAA,EAPX,CAmBAwL,EAAA+J,QAAA,CAAAA,QAAO,CAACvV,CAAD,CACP,CACI,IAAIrI,EAAI,CACQ0E,KAAAA,EAAhB,GAAI2D,CAAA,CAAK,CAAL,CAAJ,GACI,IAAAwsC,EAMA,CANmBgC,EAAA,CAAAA,IAAA,CAAgBxuC,CAAA,CAAKrI,CAAA,EAAL,CAAhB,CAMnB,CALA,IAAA80C,GAKA,CALmB+B,EAAA,CAAAA,IAAA,CAAgBxuC,CAAA,CAAKrI,CAAA,EAAL,CAAhB,CAKnB,CAJA,IAAA+0C,GAIA,CAJuB8B,EAAA,CAAAA,IAAA,CAAgBxuC,CAAA,CAAKrI,CAAA,EAAL,CAAhB,CAIvB,CAHA,IAAAqwC,EAGA,CAHiBhoC,CAAA,CAAKrI,CAAL,CAAA,CAAQ,CAAR,CAGjB,CAF6B,QAE7B,EAFI,MAAO,KAAAqwC,EAEX,GAFuC,IAAAA,EAEvC,CAFwD,CAAC,IAAAA,EAAD,CAExD,EADA,IAAAF,EACA,CADiB9nC,CAAA,CAAKrI,CAAL,CAAA,CAAQ,CAAR,CACjB,CAAA,IAAA6N,GAAA,EAAoBxF,CAAA,CAAKrI,CAAL,CAAA,CAAQ,CAAR,CAPxB,CASIqI,EAAA,CAAK,CAAL,CAAJ,GAAa,IAAA2sC,EAAb,CAAiC3sC,CAAA,CAAK,CAAL,CAAjC,CACA,OAAO,CAAA,CAZX,CAwBAwL,EAAA8C,MAAA,CAAAA,QAAK,CAACrL,CAAD,CAAKwc,CAAL,CACL,CACS,IAAA8tB,EAAL,EAAiB,IAAAvhC,EAAA,CAAa,SAAb,CACjB,KAAAjG,MAAA+Q,EAAA,CAAqB,CAAA,CACrB,KAAA62B,GAAA,CAAe1qC,CACf,KAAAyqC,GAAA,CAAoBjuB,CAJxB,CAgBAjU;CAAA8I,KAAA,CAAAA,QAAI,CAACrR,CAAD,CAAKwc,CAAL,CACJ,CACI,GAAI,IAAA1Z,MAAA+Q,EAAJ,CAAwB,CACpB,IAAA/Q,MAAA+Q,EAAA,CAAqB,CAAA,CACrB,KAAA2I,EAAA,CAAeA,CAAf,CAAyB,IAAAiuB,GACzB,IAAI,CAAC,IAAAH,EAAL,CAAiB,CACTyF,CAAAA,CAAW,SACf,IAAI,IAAAvzB,EAAJ,CAAkB,CACAxc,CAAVgwC,EAAe,IAAAtF,GACnB,KAAIhuB,EAA8B,CAAV,CAAAszB,CAAA,CAAar5C,IAAAkmB,MAAA,CAA0B,GAA1B,CAAW,IAAAL,EAAX,CAAiCwzB,CAAjC,CAAb,CAAyD,CACjFD,EAAA,EAAY,IACRtrB,GAAA,CAAAA,IAAA,CAAJ,GACIsrB,CAOA,EAPY,IAAApF,GAOZ,CAPiC,iBAOjC,CAAA,IAAAA,GAAA,CAAqB,CARzB,CAUAoF,EAAA,EAAY,IAAAvzB,EAAZ,CAA2B,WAA3B,CAAyCwzB,CAAzC,CAAmD,OAAnD,CAA6DtzB,CAA7D,CAAgF,MAdlE,CAAlB,IAgBQtS,GAAA,CAAAA,IAAA,CAxhgBR6E,WAwhgBQ,CAAJ,GAMI8gC,CANJ,EAMgB,kDANhB,CASJ,KAAAhnC,EAAA,CAAagnC,CAAb,CA3Ba,CA6BjB/wB,EAAA,CAAAA,IAAA,CAAkB,CAAA,CAAlB,CACAE,GAAA,CAAAA,IAAA,CACA4wB,GAAA,CAAAA,IAAA,CAAyB,IAAArsC,EA30XtB8R,EA20XH,CACA,KAAA40B,GAAA,CAAoB,IAnCA,CAD5B,CAsDA1lB,SAAA,GAAa,CAAbA,CAAa,CACb,CACI,MAA+D,EAA/D,CAAsC,CAAAklB,EAAApxC,OAAtC,EAAoE,CAAC,CAAC,CAAAuxC,GAD1E;AAeAllB,QAAA,GAAgB,CAAhBA,CAAgB,CAAC9M,CAAD,CAAOm4B,CAAP,CAChB,CACI,IAAIC,EAAU,EAQTD,EAAL,GACIC,CACA,CADS,CAAAzsC,EAAAsR,EAAA,CAAkB+C,CAAlB,CACT,CArtgBQzK,IAqtgBR,EAAK6iC,CAAL,EAjugBQ7iC,EAiugBR,EAA6D,CAAA5J,EAv1X1Dmf,GAu1XH,EAAqF9K,CAArF,GACIA,CADJ,CACWqM,EAAA,CAAA,CAAA1gB,EAAA,CAAmB,CAAnB,CADX,CAFJ,CAUA,IAAa,CAAb,CAAIwsC,CAAJ,GACQ,CAAAnG,GADR,EAEY,CAAC,EAAE,CAAAA,GAFf,EAIQ/tB,EAAA,CAAAA,CAAA,CAAqBjE,CAArB,CAA2B,CAA3B,CAA8B,CAAA6xB,EAA9B,CAJR,EAKQ,MAAO,CAAA,CAUD,EAAd,EAAIsG,CAAJ,EAAmB,CAAAlG,EAAAxxC,OAAnB,GACI,CAAAoyC,GAAA,EAIA,CAHa,CAGb,CAHIuF,CAGJ,GAFIA,CAEJ,CAFa,CAAAzsC,EAAAsR,EAAA,CAAkB+C,CAAlB,CAEb,EAAc,CAAd,EAAIo4B,CAAJ,GAEI7E,EAAA,CADc,CAAAtB,EAAAkB,CAAyB,CAAApB,EAAzBoB,CACd,CAAsBnzB,CAAtB,CAEA,CAAI,EAAE,CAAA+xB,EAAN,EAAkC,CAAAE,EAAAxxC,OAAlC,GAAmE,CAAAsxC,EAAnE,CAA8F,CAA9F,CAJJ,CALJ,CAYA,OAAO,CAAA,CA9CX;AA4IAsG,QAAA,GAAc,CAAdA,CAAc,CAAClF,CAAD,CAAUmF,CAAV,CAAoBC,CAApB,CACd,CACI,IAAIC,EAAYhH,CAAA,CAAa2B,CAAAnzB,EAAb,CAAhB,CACIo4B,EAAS,CAAAnD,GAAA,CAAa9B,CAAb,CAAsB,CAAtB,CADb,CAnFIsF,CAmFJ,CAnF2BC,EAAQ,CAmFnC,CAlFIvrB,EAoFkCirB,CApFlCjrB,CAAewrB,EAAfxrB,CAAsC,CAkF1C,CAhFS/P,CAAT,KAASA,CAAT,GAAiBw7B,GAAjB,CAGI,GADAH,CACA,CAFcG,EAAAC,CAAsBz7B,CAAtBy7B,CACN,CAAQ1rB,CAAR,CAAa/P,CAAb,CACR,CAAW,CACP,IAAA07B,EAAS,CAAC17B,CAMV+P,EAAA,GAAO,CACP,QAAO2rB,CAAP,EACA,KA7ygBIvjC,KA6ygBJ,CACI,IAAAwjC,EAASC,EACTN,EAAA,CAASvrB,CAAT,CAAc,CACd,MACJ,MAhzgBI5X,KAgzgBJ,CACIwjC,CAAA,CAASE,EACTP,EAAA,CAASvrB,CAAT,CAAc,CACd,MACJ,MAnzgBI5X,KAmzgBJ,CACIwjC,CACA,CADSG,EACT,CAAAR,CAAA,EAAUvrB,CAAV,CAAe,EAAf,GAAwB,CAAxB,EAA+BA,CAA/B,CAAoC,CAApC,GAA4C,CAXhD,CAcA,KAtBO,CA0BXgsB,CAAAA,CAAQJ,CAARI,EAAkBJ,CAAA,CAAOL,CAAP,CAAlBS,EAAmC,EAC1B,IAAb,EAAIA,CAAJ,EAAoBV,CAApB,CAA4BW,EAA5B,GAAoDD,CAApD,CAA4D,GAA5D,CACIE,EAAAA,CAAaC,EAAA,CAAsBb,CAAtB,EAA+B,CAA/B,CAAbY,CAAiDF,CAKjD,IAAKV,CAAL,CAEO,CAEH,GAt0gBIljC,KAs0gBJ,EAAIujC,CAAJ,CACI77C,CACA,CAwC0Bm7C,CAxC1B,CADcmB,EACd,CAp0gBAhkC,GAo0gBA,CAAAikC,CAAA,CAAWv3B,CAAA,CAwCNw3B,CAxCM,CAAex8C,CAAf,CAAmB,EAAnB,CAFf,KAMI,KAFAA,CAESD,CAoCiBo7C,CApCjBp7C,EAl0gBTuY,EAk0gBSvY,CAj0gBTuY,EAi0gBSvY,CADTw8C,CACSx8C,CADEilB,CAAA,CAqCNw3B,CArCM,CAAex8C,CAAf,CAAmB,EAAnB,CACFD,CAAAA,CAAAA,CAAI,CAAb,CAAgBw8C,CAAhB,EAA4Bx8C,CAA5B,CAAgC08C,EAAAj5C,OAAhC,CAA6DzD,CAAA,EAA7D,CACI,GAAIy7C,CAAJ,EAAakB,EAAA,CAAqB38C,CAArB,CAAA,CAAwB,CAAxB,CAAb,GACQ48C,CADR,CACgBD,EAAA,CAAqB38C,CAArB,CAAA,CAAwBC,CAAxB,CADhB,EAEe,CACPo8C,CAAA,CAAaC,EAAA,CAAsBM,CAAtB,CACbJ,EAAA,CAAW,EACX,MAHO,CAQvBH,CAAA,CAAaQ,EAAA,CAAQR,CAAR,CAAoB,CAApB,CAAb,EAAuCG,CAAA,CAAUA,CAAV,CAAqB,GAArB,CAA2B,EAAlE,CAyB8BpB,EAxB9B,CA30gBI7iC,OA20gBJ,GAAmC8jC,CAAnC,EAAiD,GAAjD,CACAA,EAAA,EAAcp3B,CAAA,CAuBLw3B,CAvBK,CAuBgBrB,CAvBhB,CAv0gBV7iC,MAu0gBU,CAA8C,EAA9C,CAEd,EADI3Y,CACJ,CAqB8Bw7C,CArB9B,EA70gBI7iC,EA60gBJ,CA50gBIA,EA40gBJ,IAAO8jC,CAAP,EAAqB,GAArB,CAA2Bp3B,CAAA,CAqBlBw3B,CArBkB;AAAe78C,CAAf,CAAmB,EAAnB,CAA3B,CAAmD,GAAnD,CAvBG,CAFP,IACIy8C,EAAA,CAAaQ,EAAA,CAAQR,CAAR,CAAoB,CAApB,CAAb,CAAsC9C,EAAA,CA6C7BkD,CA7C6B,CA6CRrB,CA7CQ,CA2B9C,EAAA,CAAOiB,CAoBHS,EAAAA,CAAW,EACXC,EAAAA,CA19BG93B,CAAA,CA09BKs1B,CA19BL,CA09BoBiB,CA98BHx4B,EAZjB,CAAoB,EAApB,CA09BH+5B,CAAoC,GACxC,IAh7gBa3G,EAg7gBb,GAAIoF,CAAAx4B,EAAJ,EAh7gBaozB,EAg7gBb,GAA6CD,CAAAnzB,EAA7C,EACI,EAGI,IAFItiB,CAEA,CAFI,CAAAu3C,GAAA,CAAauD,CAAb,CAAwB,CAAxB,CAEJ,CADJsB,CACI,EADQ,GACR,CADcvD,EAAA,CAAAA,CAAA,CAAe74C,CAAf,CACd,CAAkB,IAAlB,EAAA86C,CAAAx4B,EAAJ,CAA4B,KAHhC,OAISw4B,CAAAx4B,EAJT,EAI2BmzB,CAAAnzB,EAJ3B,CADJ,CAQA+5B,CAAA,EAASF,EAAA,CAAQC,CAAR,CAAkB,EAAlB,CAAT,CAAiCT,CAE7Bf,EAAJ,GACIyB,CAKI,CALIF,EAAA,CAAQE,CAAR,CAAe,EAAf,CAKJ,CALyB,GAKzB,EALgCzB,CAKhC,EAL4C,EAK5C,EAAAyB,CAAA,CAJC,CAAApuC,EAAAX,MAAAua,GAAL,CAIIw0B,CAJJ,EAIa,YAJb,CAGkBryB,EAAAhD,CAAA,CAAA/Y,EAAA+Y,CACOhU,SAAA,EAJzB,CAI8C,SAJ9C,CAIuDyR,CAAA,CAAU,CAAAxW,EAAA6Z,GAAV,CAJvD,EACIu0B,CADJ,EAC2B,IAAb,EAAAxB,CAAA,CAAmB,MAAnB,CAAyBA,CAAA7nC,SAAA,EAAzB,CAAgD,EAD9D,CAFJ,CASA,OAAOqpC,EA1BX;AAuCAC,QAAA,GAAgB,CAAhBA,CAAgB,CAACC,CAAD,CAAUC,CAAV,CAAqBl6B,CAArB,CAA2BivB,CAA3B,CAChB,CACI,IAAImJ,EAAU,EAGd,IAAK6B,CAAL,CAOK,CAKD,IAJA,IAAIE,EAAYF,CAAAlE,YAAA,EAAhB,CAIS/4C,EAAI,CAAb,CAAgBA,CAAhB,CAAoB08C,EAAAj5C,OAApB,CAAiDzD,CAAA,EAAjD,CACI,IAAKC,IAAIA,CAAT,GAAc08C,GAAA,CAAqB38C,CAArB,CAAd,CACI,GAAK,CAACC,CAAN,CAAA,CACA,IAAAw7C,EAAQkB,EAAA,CAAqB38C,CAArB,CAAA,CAAwBC,CAAxB,CACR,IAAIk9C,CAAJ,EAAiBb,EAAA,CAAsBb,CAAtB,CAAjB,CAA+C,CAC3C0B,CAAA,CAAYb,EAAA,CAAsBK,EAAA,CAAqB38C,CAArB,CAAA,CAAwB,CAAxB,CAAtB,CACRk9C,EAAJ,GAAeA,CAAf,CAA2Bj4B,CAAA,CAAAA,CAAA,CAAe,CAAChlB,CAAhB,CAA3B,CAAgD,GAAhD,CAAsDi9C,CAAtD,CACA,MAH2C,CAF/C,CASR,IAAK98B,IAAIA,CAAT,GAAiBw7B,GAAjB,CAAwC,CAGpC,IAAAE,EAAS,CAAC17B,CACNy7B,EAAAA,CAAUD,EAAA,CAAsBx7B,CAAtB,CAEd,QAAQ07B,CAAR,EACA,KA17gBIvjC,KA07gBJ,CACIwjC,CAAA,CAASC,EACT,MACJ,MA57gBIzjC,KA47gBJ,CACIwjC,CAAA,CAASE,EACT,MACJ,MA97gBI1jC,KA87gBJ,CACIwjC,CAAA,CAASG,EACT,MACJ,SACIH,CAAA,CAAS,CAAC,EAAD,CAXb,CAeA,IAAK5rB,IAAIA,CAAT,GAAe0rB,EAAf,CAAwB,CACpBJ,CAAA,CAAQI,CAAA,CAAQ1rB,CAAR,CACR,KAAK,IAAIurB,EAAQ,CAAjB,CAAoBA,CAApB,CAA4BK,CAAAt4C,OAA5B,CAA2Ci4C,CAAA,EAA3C,CAAoD,CAEhD,IAAIS,EAAQJ,CAAA,CAAOL,CAAP,CACC,IAAb,EAAIS,CAAJ,EAAoBV,CAApB,CAA4BW,EAA5B,GAAoDD,CAApD,CAA4D,GAA5D,CAGA,IAAIgB,CAAJ,EAFiBb,EAAA,CAAsBb,CAAtB,CAEjB,CAFgDU,CAEhD,CAA6B,CAErBiB,CAAA,CAh9gBZ7kC,KA+8gBQ,EAAIujC,CAAJ,CACaJ,CADb,EAGeA,CAHf,CAGuB,CAHvB,GAG+B,CAH/B,EAGsCA,CAHtC,CAG8C,EAH9C,GAGuD,CAEvDN,EAAA,EAAUjrB,CAAV,CAAgBitB,CAAhB,EAA0B,CAA1B,EAAgCzB,EAChC,MAPyB,CANmB,CAgBpD,GAAc,CAAd,EAAIP,CAAJ,CAAiB,KAlBG,CAoBxB,GAAc,CAAd,EAAIA,CAAJ,CAAiB,KAzCmB,CA+CpC,EAAS,CAAT,CAAAA,CAAA,CAAJ,EAAoB8B,CAApB,EAAkCA,CAAAv7C,MAAA,CAAgB,gBAAhB,CAAlC;CACIu7C,CAEA,CAFYD,CAEZ,CAFsBC,CAEtB,CADAD,CACA,CADU,EACV,CAAA7B,CAAA,CAAS,CAHb,CA/DC,CAPL,IAKQ8B,EAAJ,GAAe9B,CAAf,CAAwBU,CAAxB,CAAiC,CAAjC,CAwEJ,IAAc,CAAd,EAAIV,CAAJ,EACQ8B,CADR,CAUQ,IAPIG,CAOKz9C,CAPOs9C,CAAAt0C,MAAA,CAAgB,GAAhB,CAOPhJ,CANc,CAMdA,CANLy9C,CAAA55C,OAMK7D,GALAqyC,CAEL,EAFiB,CAAAh+B,EAAA,CAAa,qBAAb,CAAqCipC,CAArC,CAEjB,CADAG,CAAA55C,OACA,CADmB,CACnB,CAAA23C,CAAA,CAAU,EAGLx7C,EAAAA,CAAAA,CAAI,CAAb,CAAgBA,CAAhB,CAAoBy9C,CAAA55C,OAApB,CAAsC7D,CAAA,EAAtC,CAGI,GADI48C,CACJ,CADea,CAAA,CAAUz9C,CAAV,CAAAmE,KAAA,EACf,CAAA,CAEIpC,CAAAA,CAAQ66C,CAAA76C,MAAA,CAAe,0BAAf,CACZ,IAAI,CAACA,CAAL,CAAY,CACHswC,CAAL,EAAiB,CAAAh+B,EAAA,CAAa,mBAAb,CAAmCuoC,CAAnC,CACjBpB,EAAA,CAAU,EACV,MAHQ,CAYRz5C,CAAA,CAAM,CAAN,CAAJ,GAAcy5C,CAAd,EAr/gBA7iC,OAq/gBA,CAGA,IADAikC,CACA,CADW76C,CAAA,CAAM,CAAN,CACX,CAAc,CACV27C,CAAA,CAAUrK,EAAA,CAAAA,CAAA,CAAqBuJ,CAArB,CAA+BvK,CAA/B,CACV,IAAe3tC,IAAAA,EAAf,EAAIg5C,CAAJ,CAA0B,CACtBlC,CAAA,CAAU,EACV,MAFsB,CAuB1BkC,CAAA,CAAUlnB,CAAA,CAAWwa,CAAA,CAAAA,CAAA,CAAc0M,CAAd,CAAuB,EAAvB,CAA2B,CAAA,CAA3B,CAAX,CACVlC,EAAA,EAAUkC,CA1BA,CA6Bdd,CAAA,CAAW76C,CAAA,CAAM,CAAN,CACX,IAAI/B,CAAJ,EAA6B,CAA7B,EAASy9C,CAAA55C,OAAT,CAOQ+4C,CAAA,CAHCA,CAAL,CAGeA,CAAAp7C,QAAA,CAAiB,eAAjB,CAAkC,IAAlC,CAjpCxB6jB,CAAA,CAipCiEs4B,CAjpCjE,CAipCkFv6B,CAjpClF,CAAoB,EAApB,CAipCwB,CAHf,CACe,GAMfs6B,EAAAA,CAAUrK,EAAA,CAAAA,CAAA,CAAqBuJ,CAArB,CAA+BvK,CAA/B,CACd,IAAe3tC,IAAAA,EAAf,EAAIg5C,CAAJ,CAA0B,CACtBlC,CAAA,CAAU,EACV,MAFsB,CAK1B,GAAI,CAACx7C,CAAL,EAA6B,CAA7B,CAAUy9C,CAAA55C,OAAV,CACI,GArjhBJ8U,KAqjhBI,EAAIujC,CAAJ,CAAiC,CAC7B,GAAc,CAAd,CAAIwB,CAAJ,EAljhBR/kC,GAkjhBQ,CAAmB+kC,CAAnB,CACIA,CAAA,EAnjhBZ/kC,GAsjhBQ6iC;CAAA,EAAWkC,CAAX,CAAqBf,EALQ,CAAjC,IAOK,CACD,GAAc,CAAd,CAAIe,CAAJ,EAljhBR/kC,EAkjhBQ,CAAmB+kC,CAAnB,CACIA,CAAA,EAnjhBZ/kC,EAsjhBQ6iC,EAAA,EAAWkC,CAAX,EAvjhBR/kC,EAkjhBS,CART,IAAA,CA8BA,GAAI0kC,CAAJ,EAAer9C,CAAf,CACI,GAAc,CAAd,CAAI09C,CAAJ,EAjkhBJ/kC,MAikhBI,CAAmB+kC,CAAnB,CACIA,CAAA,EAAWrtB,EAInBmrB,EAAA,EAAUkC,CApCV,CAjEA,CAiHC,CAAb,CAAIlC,CAAJ,EAAkB,CAACnJ,CAAnB,EACI,CAAAh+B,EAAA,CAAa,uBAAb,CAAuCgpC,CAAvC,CAAiD,GAAjD,CAAuDC,CAAvD,CAGJ,OAAO9B,EAnNX,CAuTAtG,QAAA,GAAgB,CAAhBA,CAAgB,CAChB,CAAA,IACQl1C,CACJ,EAAAi1C,EAAA,CAAkB,CAAC,IAAD,CAClB,IAAwBvwC,IAAAA,EAAxB,GAAI,CAAA6iB,EAAJ,CACI,IAAKvnB,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB,CAAAunB,EAAA1jB,OAAhB,CAAwC7D,CAAA,EAAxC,CAA6C,CACzC,IAAAu2C,EAAU,CAAAhvB,EAAA,CAAgBvnB,CAAhB,CACVojB,EAAA,CAAOkzB,EAAA,CAAaC,CAAb,CACPjyB,GAAA,CAAA,CAAAtV,EAAA,CAAwBoU,CAAxB,CAA8B,CAAA,CAA9B,CAHyC,CAMjD,CAAAmE,EAAA,CAAkB,CAAC,IAAD,CAClB,IAAyB7iB,IAAAA,EAAzB,GAAI,CAAA+iB,EAAJ,CACI,IAAKznB,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB,CAAAynB,EAAA5jB,OAAhB,CAAyC7D,CAAA,EAAzC,CACIu2C,CAEA,CAFU,CAAA9uB,EAAA,CAAiBznB,CAAjB,CAEV,CADAojB,CACA,CADOkzB,EAAA,CAAaC,CAAb,CACP,CAAAjyB,EAAA,CAAA,CAAAtV,EAAA,CAAwBoU,CAAxB,CAA8B,CAAA,CAA9B,CAGR,EAAAqE,EAAA,CAAmB,CAAC,IAAD,CAKnB,EAAAyuB,GAAA,CAAuB,CACvB,EAAAd,GAAA,CAA0B,CAxB9B;AAsDAvhC,CAAAgT,GAAA,CAAAA,QAAa,CAAC+2B,CAAD,CAASrH,CAAT,CAAkBG,CAAlB,CACb,CACI,IAAI9jC,EAAW,CAAA,CAYV8jC,EAAL,EACImH,EAAA,CAAAA,IAAA,CAAoBD,CAApB,CAA4BrH,CAA5B,CAA2C,CAAA,CAA3C,CAAkD,CAAA,CAAlD,CAGJ,IAAIqH,CAAJ,EAAc,IAAA3I,EAAd,CAA+B,CAC3B,IAAI7xB,EAAOkzB,EAAA,CAAaC,CAAb,CACX,IAn1hBSC,EAm1hBT,GAAIpzB,CAAJ,CACI,IAAA/O,EAAA,CAAa,mBAAb,CA/3CDgR,CAAA,CA+3CoCs1B,IA/3CpC,CA+3CmDpE,CAn3ClCnzB,EAZjB,CAAoB,EAApB,CA+3CC,CACA,CAAAxQ,CAAA,CAAW,CAAA,CAFf,KAGO,CAEH5D,IAAAA,EAAAA,IAAAA,EAh4dJ,EAAAoT,EAAA,CAg4dyBgB,CAh4dzB,GADsB,CAAArB,EACtB,CAAA8E,GAAA,CAg4dyBzD,CAh4dzB,CAlcegB,KAkcf,CA+3dkBw5B,CA/3dlB,EA+3d4B,IAAAn2B,EA/3d5B,CA83dO,CALoB,CAW3B7U,CAAJ,GACIgrC,CAAA30C,KAAA,CAAYstC,CAAZ,CACA,CAAIG,CAAJ,CACIH,CAAAG,GADJ,CACyB,CAAA,CADzB,EAIIoH,EAAA,CAAAA,IAAA,CAAqBF,CAArB,CAA6BA,CAAA/5C,OAA7B,CAA2C,CAA3C,CAA8C,KAA9C,CACA,CAAA0xC,EAAA,CAAAA,IAAA,CALJ,CAFJ,CA5BJ,CAuDAsI,SAAA,GAAc,CAAdA,CAAc,CAACD,CAAD,CAASrH,CAAT,CAA2BG,CAA3B,CAAuCpD,CAAvC,CACd,CACI,IAAIyK,EAAS,CAAA,CACT36B,EAAAA,CAAOkzB,EAAA,CAAaC,CAAb,CACX,KAAK,IAAIv2C,EAAI,CAAb,CAAgBA,CAAhB,CAAoB49C,CAAA/5C,OAApB,CAAmC7D,CAAA,EAAnC,CAAwC,CACpC,IAAIg+C,EAAeJ,CAAA,CAAO59C,CAAP,CACnB,IAAIojB,CAAJ,EAAYkzB,EAAA,CAAa0H,CAAb,CAAZ,GACQ,CAACtH,CADT,EACuBsH,CAAAtH,GADvB,EACgD,CACxCqH,CAAA,CAAS,CAAA,CAEAC,EAAAtH,GAAL,EAAiCpD,CAAjC,EACIwK,EAAA,CAAAA,CAAA,CAAqBF,CAArB,CAA6B59C,CAA7B,CAAgC,SAAhC,CAEJ49C,EAAA5qC,OAAA,CAAchT,CAAd,CAAiB,CAAjB,CACI49C,EAAJ,EAAc,CAAA3I,EAAd,EAEI3wB,EAAA,CAAA,CAAAtV,EAAA,CAAwBoU,CAAxB,CADcw6B,CACd,EADwB,CAAAn2B,EACxB,CAMCu2B,EAAAtH,GAAL,EACInB,EAAA,CAAAA,CAAA,CAEJ,MAlBoC,CAHZ,CA4BxC,MAAOwI,EA/BX;AAyCAE,QAAA,GAAe,CAAfA,CAAe,CAACL,CAAD,CACf,CACI,IAAK,IAAI59C,EAAI,CAAb,CAAgBA,CAAhB,CAAoB49C,CAAA/5C,OAApB,CAAmC7D,CAAA,EAAnC,CACI89C,EAAA,CAAAA,CAAA,CAAqBF,CAArB,CAA6B59C,CAA7B,CAEJ,OAAO49C,EAAA/5C,OAAP,CAAuB,CAJ3B,CAeAi6C,QAAA,GAAe,CAAfA,CAAe,CAACF,CAAD,CAAS59C,CAAT,CAAYk+C,CAAZ,CACf,CACQ3H,CAAAA,CAAUqH,CAAA,CAAO59C,CAAP,CACd,EAAAqU,EAAA,CAAaupC,CAAA,CAAO,CAAP,CAAb,CAAyB,GAAzB,CA/9COv4B,CAAA,CA+9CwBs1B,CA/9CxB,CA+9CuCpE,CAn9CtBnzB,EAZjB,CAAoB,EAApB,CA+9CP,EAA0D86B,CAAA,CAAU,GAAV,CAAgBA,CAAhB,CAA4B3H,CAAA7F,GAAA,CAAe,IAAf,CAAsB6F,CAAA7F,GAAtB,CAAqC,GAArC,CAA4C,EAAlI,EAFJ,CAsBA0K,QAAA,GAAmB,CAAnBA,CAAmB,CAACh4B,CAAD,CACnB,CACI,GAAa1e,IAAAA,EAAb,GAAI0e,CAAJ,CACIiE,EAAA,CAAAA,CAAA,CAAqBjE,CAArB,CAA2B,CAA3B,CAA8B,CAAA6xB,EAA9B,CAA+C,CAAA,CAA/C,CACA,CAAA,CAAAW,EAAA,CAAa,CAFjB,KAII,KAAS51C,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoB,CAAAi1C,EAAApxC,OAApB,CAA4C7D,CAAA,EAA5C,CAAiD,CAC7C,IAAIg+C,EAAe,CAAA/I,EAAA,CAAgBj1C,CAAhB,CACnB,IAAIg+C,CAAAtH,GAAJ,CAA6B,CACzB,GAAI,CAACmH,EAAA,CAAAA,CAAA,CAAoB,CAAA5I,EAApB,CAAqC+I,CAArC,CAAyD,CAAA,CAAzD,CAAL,CAAqE,KACrEh+C,EAAA,CAAI,CAFqB,CAFgB,CALzD;AAyBAqnB,QAAA,GAAe,CAAfA,CAAe,CAACjE,CAAD,CAAOkE,CAAP,CAAWs2B,CAAX,CAAmBlH,CAAnB,CACf,CAKI,IAAIyH,EAAS,CAAA,CAEb,IAAI,CAAC,CAAAjI,GAAA,EAAL,CAEI,IAAK,IAAIl2C,EAAI,CAAb,CAAgB,CAACm+C,CAAjB,EAA2Bn+C,CAA3B,CAA+B49C,CAAA/5C,OAA/B,CAA8C7D,CAAA,EAA9C,CAAmD,CAE/C,IAAIg+C,EAAeJ,CAAA,CAAO59C,CAAP,CAEnB,IAAI02C,CAAAA,CAAJ,EAAmBsH,CAAAtH,GAAnB,CAQA,IADA,IAAI0H,EAAY9H,EAAA,CAAa0H,CAAb,CAAZI,EAA0CR,CAAA,EAAU,CAAA3I,EAAV,CAA2B,KAA3B,CAAqC,EAA/EmJ,CAAJ,CACS/9C,EAAI,CAAb,CAAgBA,CAAhB,CAAoBinB,CAApB,CAAwBjnB,CAAA,EAAxB,CAEI,GAAK+iB,CAAL,CAAY/iB,CAAZ,EAAkB+9C,CAAlB,CAAA,CAEA,IAAI5+C,CACJ2+C,EAAA,CAAS,CAAA,CACLH,EAAAtH,GAAJ,GACImH,EAAA,CAAAA,CAAA,CAAoBD,CAApB,CAA4BI,CAA5B,CAAgD,CAAA,CAAhD,CACA,CAAAtH,CAAA,CAAa,CAAA,CAFjB,CAIA,IAAIl3C,CAAJ,CAAQw+C,CAAAjH,GAAR,CAA4B,CAWxBoH,CAAA,CAAS,CAAA,CACT,KAAK,IAAIl+C,EAAI,CAAb,CAAgBA,CAAhB,CAAoBT,CAAAqE,OAApB,CAA8B5D,CAAA,EAA9B,CACI,GAAI,CAACo+C,EAAA,CAAAA,CAAA,CAAe7+C,CAAA,CAAES,CAAF,CAAf,CAAqB,CAAA,CAArB,CAAL,CAAiC,CAC7B,GAAIT,CAAA,CAAES,CAAF,CAAAsB,QAAA,CAAa,IAAb,CAAJ,CAAwB,CACpB48C,CAAA,CAAS,CAAA,CACT,MAFoB,CAKxB,IADA,IAAIj+C,EAAID,CAAJC,CAAQ,CACZ,CAAOA,CAAP,CAAWV,CAAAqE,OAAX,EACSrE,CAAA,CAAEU,CAAF,CAAAqB,QAAA,CAAa,MAAb,CADT,CAAqBrB,CAAA,EAArB,CAEID,CAAA,EAEJ,IAAIC,CAAJ,EAASV,CAAAqE,OAAT,CAAmB,CACfs6C,CAAA,CAAS,CAAA,CACT,MAFe,CAVU,CAoBhC,CAAApvC,EAz+bdX,MAAA+Q,EAy+bS,GAA2Bg/B,CAA3B,CAAoC,CAAA,CAApC,CAjCwB,CAmC5B,GAAIA,CAAJ,CAAY,CACHzH,CAAL,EAAiBoH,EAAA,CAAAA,CAAA,CAAqBF,CAArB,CAA6B59C,CAA7B,CAAgC,KAAhC,CACjB,MAFQ,CA3CZ,CAd2C,CAiEvD,CAAAk2C,GAAA,EAEA,OAAOiI,EA5EX;AAuIAG,QAAA,GAAU,CAAVA,CAAU,CAACC,CAAD,CACV,CADWA,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAQ,CAAA,CAAR,CAAAA,CAGP,KADA,IAAIC,EAAQ,EAAZ,CACSx+C,EAAI,CAAb,CAAoB,EAApB,CAAgBA,CAAhB,CAAwBA,CAAA,EAAxB,CAA6B,CACrBA,CAAAA,CAAJ,EAAWA,CAAX,CAAe,CAAf,GAAmBw+C,CAAnB,EAA4B,IAA5B,CACSC,KAAAA,EAAAA,CAAAA,CApDT1E,EAAO/1B,EAAA,CAoDoBhkB,CApDpB,CAAgB,CAAhB,CACX22C,GAAA,CAAa,CAAAhC,GAAb,CAmD+B30C,CAnD/B,CACA+5C,EAAA,EAAQ,MAAR,CAAc10B,CAAA,CAAAA,CAAA,CAAe,CAAAgzB,GAAA,CAAa,CAAA1D,GAAb,CAAf,CAA8C,EAA9C,CAAd,CAAkE,GAkD9D6J,EAAA,EAjDGzE,CA+CsB,CAI7B,GAAIwE,CAAJ,CAAA,CAvBIC,CAAAA,CAAQ,EACZ,KAASx+C,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoB0+C,EAAA76C,OAApB,CAAmD7D,CAAA,EAAnD,CACI,CAlBA+5C,CAkBA,CAh3CG4E,EAAA,CAg3CwB3+C,CAh3CxB,CAg3CH,EAh3CmC,EAg3CnC,IAfA+5C,CAeA,EAfQ,MAeR,CAfc10B,CAAA,CAoCSu5B,CApCT,CAoCSA,CApCMpO,GAAA,CAeFxwC,CAfE,CAAf,CAeaA,CAhBdgwC,EAAQqK,EAARrK,CAA+B,CAA/BA,CAgBchwC,CAhBsB,EAAQk6C,EAAR,CAA+B,EAA/B,CAAoC,EACvE,CAed,CAf8D,GAe9D,EAAAsE,CAAA,EAbGzE,CAkCIyE,EAAA,EAAS,IAAT,CAnBJA,CAmBP,CACA,MAAOA,EAPX,CAkBA3qC,CAAAgrC,GAAA,CAAAA,QAAY,CAACC,CAAD,CAAKC,CAAL,CACZ,CACI,MAAOD,EAAA,CAAG,CAAH,CAAA,CAAQC,CAAA,CAAG,CAAH,CAAR,CAAe,CAAf,CAAmBD,CAAA,CAAG,CAAH,CAAA,CAAQC,CAAA,CAAG,CAAH,CAAR,CAAgB,EAAhB,CAAoB,CADlD,CAiFA/T;QAAA,GAAU,CAAVA,CAAU,CAACgU,CAAD,CAAU57B,CAAV,CAAgB+oB,CAAhB,CAAqBnkC,CAArB,CACV,CAEI,IAAIi3C,EAAW,EAAf,CACSjG,CAAT,KAASA,CAAT,GAAoBhxC,EAApB,CAA8B,CAC1B,IAAIqxC,EAASrxC,CAAA,CAASgxC,CAAT,CACQ,SAArB,EAAI,MAAOK,EAAX,GACIrxC,CAAA,CAASgxC,CAAT,CADJ,CACwBK,CADxB,CACiC,CAAC,EAAKA,CAAN,CADjC,CAGA,KAAIE,EAAYF,CAAA,EAAhB,CACI6F,EAAc7F,CAAA,EAClB,IAAkB30C,IAAAA,EAAlB,GAAI60C,CAAJ,CAAA,CACqB0F,IAAAA,EAAAA,CAAU,EAAA,CAAA,CAAC1F,CAAD,GAAe,CAAf,CAAkBP,CAAlB,CA/ioBnC,KAAI14B,EAAQ6+B,EAAA,CAAiB3/C,CAAjB,CAAoBqB,CAApB,CA+ioBmD,CAAAg+C,GA/ioBnD,CACA,EAAZ,CAAIv+B,CAAJ,EACI9gB,CAAAwT,OAAA,CAAS,EAAEsN,CAAF,CAAU,CAAV,CAAT,CAAuB,CAAvB,CAA0Bzf,CAA1B,CA4ioBA,CAGIq+C,CAAJ,GAAiB7F,CAAA,EAAjB,CAA+B6F,CAAA19C,QAAA,CAAoB,KAApB,CAA2B,GAA3B,CAA/B,CAV0B,CAmB9B,CAAAwzC,EAAA/rC,KAAA,CAPkBqwC,CACd0F,GAASA,CADK1F,CAEdl2B,EAAMA,CAFQk2B,CAGdnN,GAAKA,CAHSmN,CAIdtxC,EAAUA,CAJIsxC,CAKd2F,GAAUA,CALI3F,CAOlB,CAtBJ,CA8DA8F,QAAA,GAAU,CAAVA,CAAU,CAAC7I,CAAD,CAAU8I,CAAV,CACV,CACI,IAAIC,EAAU,EAAd,CACIC,EAAajJ,EAAA,CAAaC,CAAb,CAAbgJ,GAAuC,CAC3C,KAASrG,CAAT,CAAkB,CAAlB,CAAqBA,CAArB,CAA8B,CAAAlE,EAAAnxC,OAA9B,CAAwDq1C,CAAA,EAAxD,CAAkE,CAC9D,IAAII,EAAc,CAAAtE,EAAA,CAAkBkE,CAAlB,CAAlB,CACI91B,EAAOk2B,CAAAl2B,EAAPA,GAA4B,CADhC,CAEI+oB,EAAMmN,CAAAnN,GACV,IAAIoT,CAAJ,EAAkBn8B,CAAlB,EAA0Bm8B,CAA1B,CAAuCn8B,CAAvC,CAA8C+oB,CAA9C,CAAmD,CAE3C1V,CAAAA,CAAS0oB,EAAA,CAAiB7F,CAAA2F,GAAjB,CAAuC,CADpCM,CACoC,CADvBn8B,CACuB,CAAvC,CAAoD,CAAAy7B,GAApD,CACC,EAAd,EAAIpoB,CAAJ,CACI+oB,EAAA,CAAAA,CAAA,CAAkBtG,CAAlB,CAA0BziB,CAA1B,CAAkC6oB,CAAlC,CADJ,CAGSD,CAHT,GAII5oB,CAEA,CAFS,CAACA,CAEV,CADA+oB,EAAA,CAAAA,CAAA,CAAkBtG,CAAlB,CAA0BziB,CAA1B,CAAiC,CAAjC,CAAoC6oB,CAApC,CACA,CAAAE,EAAA,CAAAA,CAAA,CAAkBtG,CAAlB,CAA0BziB,CAA1B,CAAkC6oB,CAAlC,CANJ,CAQA,MAX+C,CAJW,CAkBlE,MAAOA,EArBX;AAsEAtT,QAAA,GAAS,CAATA,CAAS,CAACyT,CAAD,CAASC,CAAT,CACT,CACI,IAAI1wC,EAAM,CAAAA,EAAV,CAEI2wC,EAAS,CAFb,CAEgBC,EAAS,IAFzB,CAE+BC,EAAS,CACxCJ,EAAAK,QAAA,CAAe,QAAQ,CAACh/C,CAAD,CAAIsiB,CAAJ,CAAU,CAC7BpU,CAn8eJoT,EAAA,EAm8egBgB,CAn8ehB,CAm8eIpU,CAp8eiByR,EACrB,IAm8eIzR,CAp8eoC+S,EACxC,CAAA5B,EAAA,CAm8esBrf,CAn8etB,CAm8egBsiB,CAn8ehB,CAlYmBgB,KAkYnB,CAm8egBhB,CAn8ehB,CAo8ekB,KAAd,EAAIw8B,CAAJ,GAAoBA,CAApB,CAA6Bx8B,CAA7B,CACIA,EAAJ,CAAWy8B,CAAX,GAAmBA,CAAnB,CAA4Bz8B,CAA5B,CACAu8B,EAAA,EAJ6B,CAAjC,CAMKA,EAAL,EAGQI,CAQJ,CARa,gBAQb,CAPiB,IAAjB,EAAIL,CAAJ,EACItgC,CAAA,CAAA,CAAArQ,EAAA,CAAe2wC,CAAf,CACA,CAAAK,CAAA,EAAU16B,CAAA,CAAAA,CAAA,CAAeq6B,CAAf,CAFd,EAIIK,CAJJ,EAIc,aAGd,CADA,CAAA1rC,EAAA,CAAasrC,CAAb,CAAsB,mBAAtB,CAA4Ct6B,CAAA,CAAAA,CAAA,CAAeu6B,CAAf,CAA5C,CAAqE,GAArE,CAA2Ev6B,CAAA,CAAAA,CAAA,CAAew6B,CAAf,CAA3E,CAAoG,IAApG,CAA2GE,CAA3G,CACA,CAAAz1B,EAAA,CAAAA,CAAA,CAXJ,EACI,CAAAjW,EAAA,CAAa,SAAb,CAXR,CAmCAmrC,QAAA,GAAY,CAAZA,CAAY,CAACtG,CAAD,CAAS8G,CAAT,CAAkBV,CAAlB,CACZ,CACI,IAAIjG,EAAS,EAAb,CACI4F,EAAW,CAAAjK,EAAA,CAAkBkE,CAAlB,CAAA+F,GADf,CAEIgB,EAAS,CAFb,CAEgBjH,EAAU,IACX,EAAf,EAAIgH,CAAJ,EAAoBA,CAApB,CAA8Bf,CAAAp7C,OAA9B,GACIo8C,CACA,CADShB,CAAA,CAASe,CAAT,CAAA,CAAkB,CAAlB,CACT,CAAAhH,CAAA,CAAUiG,CAAA,CAASe,CAAT,CAAA,CAAkB,CAAlB,CAFd,CAIIhH,EAAJ,GACIK,CACA,CADS,CAAArE,EAAA,CAAkBkE,CAAlB,CAAAlxC,EAAA,CAAmCgxC,CAAnC,CACT,CAAAA,CAAA,CAAgC,GAArB,EAAAA,CAAAt3C,OAAA,CAAe,CAAf,CAAA,CAA0B,IAA1B,CAAkC23C,CAAA,EAAlC,EAAiDL,CAFhE,CAIAsG,EAAAr2C,KAAA,CAAa+vC,CAAb,CACAsG,EAAAr2C,KAAA,CAAag3C,CAAb,CACAX,EAAAr2C,KAAA,CAAaowC,CAAA,EAAb,CACAiG,EAAAr2C,KAAA,CAAaowC,CAAA,EAAb,CAfJ;AAwEA6G,QAAA,GAAU,CAAVA,CAAU,CAAC7I,CAAD,CACV,CACI,IAAIqC,EAAWrC,CAAA,CAAO,CAAP,CAAA11C,OAAA,CAAiB,CAAjB,CAAf,CACI21C,EAAQD,CAAA,CAAO,CAAP,CAAA,EAA6B,GAA7B,EAAaA,CAAA,CAAO,CAAP,CAAA,CAAU,CAAV,CAAb,EAAoD,GAApD,EAAoCA,CAAA,CAAO,CAAP,CAAA,CAAU,CAAV,CAApC,CAAyDA,CAAA,CAAO,CAAP,CAAzD,CAAqE3yC,IAAAA,EADjF,CAEI24C,EAAU/F,CAAA,CAAOD,CAAA,CAAO,CAAP,CAAP,CAAmBA,CAAA,CAAO,CAAP,CAFjC,CAGId,EAAUgB,EAAA,CAAAA,CAAA,CAAeD,CAAf,CAAsB,CAAAvC,GAAtB,CAEd,IAAI,CAACsI,CAAL,CAII,MAHA,EAAAhpC,EAAA,CAAa,oBAAb,CAr/DGgR,CAAA,CAq/DiCs1B,CAr/DjC,CAq/DgDpE,CAz+D/BnzB,EAZjB,CAAoB,EAApB,CAq/DH,CAGO,CAFP,CAAA+sB,EAEO,CAFU,CAAA,CAEV,CADPnwB,CAAA,CAAA,CAAA/Q,EAAA,CACO,CAAA,CAAA,CAGX,KAAIlN,EAAQs7C,CAAAt7C,MAAA,CAAc,8CAAd,CACZ,IAAIA,CAAJ,GAAcA,CAAA,CAAM,CAAN,CAAd,EAA0BA,CAAA,CAAM,CAAN,CAA1B,EAAqC,CAGjCw0C,CAAA,CAAUgB,EAAA,CAAAA,CAAA,CAAeD,CAAf,CACV,IAAI,CAAAnB,GAAJ,CAHUrnC,CAINuF,EAAA,CAAY,8BAAZ,CADJ,KAGK,CACD,IAAI8rC,EAAQp+C,CAAA,CAAM,CAAN,CAARo+C,CAAmBp+C,CAAA,CAAM,CAAN,CAClBA,EAAA,CAAM,CAAN,CAAL,GAAe23C,CAAf,EAA2B,GAA3B,CACA,KAAIzxC,EAAWsuC,CAAAnzB,EAAf,CACI+yB,EAAU,CAAAA,GAAVA,CAAyB,IAAIiK,EAAJ,CAVvBtxC,CAUuB,CAC7BuxC,GAAA,CAAAlK,CAAA,CAAsBgK,CAAtB,CAA6Bl4C,CAA7B,CAAuCyxC,CAAvC,CAAiD4G,QAAoB,CAACv5C,CAAD,CAAahB,CAAb,CAAmB,CACpF,GAAI,CAACgB,CAAL,CAMI,GAAI,CACA,IAAI24C,EAAYvJ,CAw/D7BuJ,EAv/D8B,KAAjB,EAAIA,CAAJ,GAAuBA,CAAvB,CAAmCz3C,CAAnC,CACA+jC,GAAA,CArBNl9B,CAqBM,CAAcqnC,CAy+D3BsJ,EAz+Da,CAAkCC,CAAlC,CAHA,CAIF,MAAM9/C,CAAN,CAAS,CACS,QAAhB,EAAI,MAAOA,EAAX,CACImH,CADJ,CACiBnH,CADjB,EACuB,EADvB,EAvBNkP,CA0BUuF,EAAA,CAAYzU,CAAAgJ,QAAZ,CACA;AAAA7B,CAAA,CAAc,EAJlB,CADO,CASXA,CAAJ,EA/BE+H,CAgCEuF,EAAA,CAAY,SAAZ,CAAwBtN,CAAxB,CAAqC,eAArC,EAAwDhB,CAAxD,EAAgEo6C,CAAhE,EAhCFrxC,EAkCFqnC,GAAA,CAAc,IACTpvC,EAAL,EAAiB4jB,EAAA,CAnCf7b,CAmCe,CAxBmE,CAAxF,CALC,CAgCL,MAAO,CAAA,CAvC0B,CA0CrCuoC,CAAAv1C,MAAA,EACAu1C,EAAAv1C,MAAA,EACAu1C,EAAAv1C,MAAA,EAEI05C,EAAAA,CAAS4B,EAAA,CAAAA,CAAA,CAAsBC,CAAtB,CADGhG,CAAA7D,KAAA8J,CAAY,EAAZA,CACH,CAA0C/G,CAAAnzB,EAA1C,EAA0D,CAA1D,CAEC,EAAd,EAAIo4B,CAAJ,GACI,CAAAjD,GAAA,CAAahC,CAAb,CAAsBiF,CAAtB,CACA,CAAA,CAAAnnC,EAAA,CAAaonC,EAAA,CAAAA,CAAA,CAAoBlF,CAApB,CAAb,CAFJ,CAIA,OAAO,CAAA,CAlEX,CA4aAgK,QAAA,GAAK,CAALA,CAAK,CAAC7P,CAAD,CACL,CACI,IAAIlxC,EAAIkxC,CAAA3uC,MAAA,CAAW,yCAAX,CACR,IAAIvC,CAAJ,CAAO,CACH,GAAI,CAACA,CAAA,CAAE,CAAF,CAAL,CAEI,MADK40C,GAAA,CAAAA,CAAA,CACE,EADoB,CAAA//B,EAAA,CAAa,cAAb,CACpB,CAAA,CAAA,CAEX,IAAI,CAAC7U,CAAA,CAAE,CAAF,CAAL,CACI,MAAO40C,GAAA,CAAAA,CAAA,CAAmB50C,CAAA,CAAE,CAAF,CAAnB,CAEX,IAAI,CAACA,CAAA,CAAE,CAAF,CAAL,CAEI,MAlrGR,QAirGQghD,CAjrGDlQ,EAAA,CAirGkB9wC,CAAAs0C,CAAE,CAAFA,CAjrGlB,CAkrGQ,CAAA,CAAA,CAEPjzC,EAAAA,CAAIwyC,EAAA,CAAAA,CAAA,CAAqB7zC,CAAA,CAAE,CAAF,CAArB,CACR,OAAUkF,KAAAA,EAAV,GAAI7D,CAAJ,EACI4/C,CAjoGRnQ,EAAA,CAioGyB9wC,CAAAs0C,CAAE,CAAFA,CAjoGzB,CAkoGe,CAloGS,CAAC1xC,MAioGMvB,CAjoGP,CAAQkzC,GAioGxBA,IAAA,EAjoGgB,CAkoGT,CAAA,CAAA,CAFX,EAIO,CAAA,CAjBJ,CAmBP,CAAA1/B,EAAA,CAAa,qBAAb,CAAqCq8B,CAArC,CACA,OAAO,CAAA,CAtBX;AAiCAgQ,QAAA,GAAM,CAANA,CAAM,CAACpJ,CAAD,CAAQ/D,CAAR,CACN,CACI,IAAIyF,EAAU,IAEVzC,EAAAA,CAAUgB,EAAA,CAAAA,CAAA,CAAeD,CAAf,CAEd,KAAIgI,EAAUF,EAAA,CAAAA,CAAA,CAAgB7I,CAAhB,CAAyB,CAAA,CAAzB,CACd,IAAI+I,CAAAz7C,OAAJ,CAAoB,CAAA,IACZ88C,CACJ,IAAIrB,CAAA,CAAQ,CAAR,CAAJ,CAAgB,CACZ,IAAAsB,EAAS,EAET,EADAD,CACA,CADSpK,CAAAnzB,EACT,CADwBk8B,CAAA,CAAQ,CAAR,CACxB,IAAYsB,CAAZ,CAAqB,KAArB,CAtwqBDr7B,CAAA,CAswqB4Co7B,CAtwqB5C,CAAa,CAAb,CAAgB,CAAA,CAAhB,CAswqBC,CACAjgD,EAAA,CAAI4+C,CAAA,CAAQ,CAAR,CAAJ,CAAiB,IAAjB,CAz8EDj6B,CAAA,CAy8EyBs4B,CAz8EzB,CAy8E0C2B,CAAAx4B,CAAQ,CAARA,CAz8E1C,CAAoB,EAApB,CAy8EC,CAAuD,GAAvD,CAA6D85B,CACzDrN,EAAJ,EAAY,CAAAl/B,EAAA,CAAa3T,CAAb,CACZs4C,EAAA,CAAUt4C,CANE,CAQK,CAArB,CAAI4+C,CAAAz7C,OAAJ,EAA0By7C,CAAA,CAAQ,CAAR,CAA1B,GACIsB,CAKA,CALS,EAKT,EAJAD,CAIA,CAJSrB,CAAA,CAAQ,CAAR,CAIT,CAJsB/I,CAAAnzB,EAItB,IAHYw9B,CAGZ,CAHqB,KAGrB,CAjxqBDr7B,CAAA,CA8wqB4Co7B,CA9wqB5C,CAAa,CAAb,CAAgB,CAAA,CAAhB,CAixqBC,EAFAjgD,CAEA,CAFI4+C,CAAA,CAAQ,CAAR,CAEJ,CAFiB,IAEjB,CAn9EDj6B,CAAA,CAi9EyBs4B,CAj9EzB,CAi9E0C2B,CAAAx4B,CAAQ,CAARA,CAj9E1C,CAAoB,EAApB,CAm9EC,CAFuD,GAEvD,CAF6D85B,CAE7D,CADIrN,CACJ,EADY,CAAAl/B,EAAA,CAAa3T,CAAb,CACZ,CAAKs4C,CAAL,GAAcA,CAAd,CAAwBt4C,CAAxB,CANJ,CAVgB,CAApB,IAmBQ6yC,EAAJ,EAAY,CAAAl/B,EAAA,CAAa,YAAb,CAEhB,OAAO2kC,EA3BX;AA0MAkC,QAAA,GAAW,CAAXA,CAAW,CAAC7D,CAAD,CACX,CADoBwJ,IAAAA,CAEhB,IAAIxJ,CAAJ,EAA2B,GAA3B,EAAcA,CAAA,CAAO,CAAP,CAAd,CACI,CAAAhjC,EAAA,CAAa,oBAAb,CAGA,CAFA,CAAAA,EAAA,CAAa,qBAAb,CAEA,CADA,CAAAA,EAAA,CAAa,2BAAb,CACA,CAAA,CAAAA,EAAA,CAAa,yCAAb,CAJJ,KAAA,CAQA,IAAItF,EAAM,CAAAA,EAAV,CACIwvC,EAAQ75C,IAAAA,EACQ,KAApB,EAAIm8C,CAAJ,GAA0BA,CAA1B,CAAyC,CAAA,CAAzC,CAEA,IAAc,IAAd,EAAIxJ,CAAJ,EAAsC,CAAtC,CAAsBA,CAAAxzC,OAAtB,CAAyC,CACrC,IAAIk2C,EAAO1C,CAAA,CAAO,CAAP,CAEX,IAAY,GAAZ,EAAI0C,CAAJ,CACIwE,CAAA,CAAQ,CAAA,CADZ,KAGK,CAED,IAAIv+C,EAAI+5C,CAAAx4C,QAAA,CAAa,MAAb,CACR,IAAQ,CAAR,CAAIvB,CAAJ,CACI8J,CACA,CADSiwC,CAAAp4C,OAAA,CAAY3B,CAAZ,CAAgB,CAAhB,CACT,CAAA+5C,CAAA,CAAOA,CAAAp4C,OAAA,CAAY,CAAZ,CAAe3B,CAAf,CAFX,KAIK,IAAoB,CAApB,CAAIq3C,CAAAxzC,OAAJ,CACDiG,CAAA,CAASutC,CAAA,CAAO,CAAP,CADR,KAGA,CACD,CAAAhjC,EAAA,CAAa,oBAAb,CAAoCgjC,CAAA,CAAO,CAAP,CAApC,CACA,OAFC,CAKDj1C,CAAAA,CAAQixC,EAAA,CAAAA,CAAA,CAAqBvpC,CAArB,CACZ,IAAcpF,IAAAA,EAAd,GAAItC,CAAJ,CAAyB,MAErBwxC,EAAAA,CAAO,CAAArD,GAAA,CAAiBwJ,CAAjB,CACX,IAAW,CAAX,CAAInG,CAAJ,CAAc,CACV,CAAAv/B,EAAA,CAAa,oBAAb,CAAoC0lC,CAApC,CACA,OAFU,CA71ElB+G,CAAAA,CAAO,CACX,KAAI/xC,EAi2EIgyC,CAj2EEhyC,EAEV,QA+1EyB6kC,CA/1EzB,EACA,KAAKqG,EAAL,CACI76B,CAAA,CAAArQ,CAAA;AA61E2B3M,CA71E3B,CACAu0C,GAAA,CA41EIoK,CA51ESlM,EAAb,CAA+B9lC,CA/3W5B8R,EA+3WH,CACA,MACJ,MAAKu5B,EAAL,CACI7qB,EAAA,CAAAxgB,CAAA,CAy1E2B3M,CAz1E3B,CACA,MACJ,MAAKi4C,EAAL,CACIyG,CAAA,CAxsfQtxB,MAysfR,MACJ,MAAK8qB,EAAL,CACIwG,CAAA,CA1sfQtxB,KA2sfR,MACJ,MAAK+qB,EAAL,CACIuG,CAAA,CA5sfQtxB,KA6sfR,MACJ,MAAKgrB,EAAL,CACIsG,CAAA,CA7sfQtxB,IA8sfR,MACJ,MAAKirB,EAAL,CACIqG,CAAA,CA5sfQtxB,EA6sfR,MACJ,MAAKkrB,EAAL,CACIoG,CAAA,CA1sfOtxB,MAkrfX,CA2BIsxB,CAAJ,GAEQ/xC,CAAAuf,EAFR,CAo0E+BlsB,CAn0E3B,CACI2M,CAAAuf,EADJ,CACiBwyB,CADjB,CAGI/xC,CAAAuf,EAHJ,CAGiB,CAACwyB,CAJtB,CAs0EQ9gC,EAAA,CAAA,CAAA/Q,EAAA,CACA,EAAAoF,EAAA,CAAa,oBAAb,CA3BC,CANgC,CAqCzC,CAAAA,EAAA,CAAaiqC,EAAA,CAAAA,CAAA,CAAgBC,CAAhB,CAAb,CAEIsC,EAAJ,GACIlK,EAAA,CAAa,CAAA9B,EAAb,CAA+BjlB,EAAA,CAAA7gB,CAAA,CAA/B,CACA,CAAAosC,EAAA,CAAAA,CAAA,CA9rFG91B,CAAA,CA8rFes1B,CA9rFf,CA8rF8B,CAAA9F,EAlrFbzxB,EAZjB,CAAoB,EAApB,CA8rFH,CAFJ,CAnDA,CADJ,CAsFA49B,QAAA,GAAO,CAAPA,CAAO,CAACtQ,CAAD,CACP,CACIA,CAAA,CAAOvB,EAAA,CAASuB,CAAT,CACP,KAAIlxC,EAAIkxC,CAAA3uC,MAAA,CAAW,iBAAX,CACHvC,EAAL,CAGsB,CAAlB,CAAIA,CAAA,CAAE,CAAF,CAAAqE,OAAJ,CACI,CAAAwQ,EAAA,CAA8B7U,CAAAkB,CAAE,CAAFA,CAA9B,CADJ,CAGIgzC,EAAA,CAAAA,CAAA,CAAgB,IAAhB,CAAsBl0C,CAAA,CAAE,CAAF,CAAA+vC,WAAA,CAAgB,CAAhB,CAAtB,CANR,CACI8D,EAAA,CAAAA,CAAA,CAAqB3C,CAArB,CAA2B,CAAA,CAA3B,CAJR;AAmLAuQ,QAAA,GAAO,CAAPA,CAAO,CAACvQ,CAAD,CAAOwQ,CAAP,CACP,CACI,GAAc,GAAd,EAAIA,CAAJ,CACI,CAAA7sC,EAAA,CAAa,iBAAb,CAIA,CAHA,CAAAA,EAAA,CAAa,gCAAb,CAGA,CAFA,CAAAA,EAAA,CAAa,sDAAb,CAEA,CADA,CAAAA,EAAA,CAAa,0BAAb,CACA,CAAA,CAAAA,EAAA,CAAa,0DAAb,CALJ,KAAA,CAUA,IAAI0mC,EAAiB,GAAjBA,EAASrK,CACTyQ,EAAAA,CAASzO,EAAA,CAAAA,CAAA,CAAgBwO,CAAhB,CAAwB,IAAxB,CAA8B,CAAA,CAA9B,CAATC,EAAgD,CASpD,KAAIr5B,EAAU,CAEF,KAAZ,EAAI4oB,CAAJ,GACI5oB,CACA,CADUq5B,CACV,CAAAA,CAAA,CAAS,CAFb,CAIA,EAAArL,GAAA,CAAqBpF,CAErB0Q,GAAA,CACID,CADJ,CAEIE,QAAoB,EAAG,CACnB,MAAOjsC,GAAA,CAtBLtG,CAsBK,CAAY,CAAA,CAAZ,CAAP,EAA4B2Q,EAAA,CAtB1B3Q,CAsB0B,CAAYgZ,CAAZ,CAAqBizB,CAArB,CAA4B,CAAA,CAA5B,CADT,CAF3B,CAKIuG,QAA4B,EAAG,CAxBzBxyC,CA+BEkO,GAAJ,EA/BElO,CA+BakO,GAAAL,KAAA,EACfqD,EAAA,CAhCElR,CAgCFG,EAAA,CAAwB,EAAxB,CACAmG,GAAA,CAjCEtG,CAiCF,CAAY,CAAA,CAAZ,CAT2B,CALnC,CA5BA,CADJ;AAwDAqsC,QAAA,GAAY,CAAZA,CAAY,CAAC7D,CAAD,CAAQiK,CAAR,CAAkBC,CAAlB,CACZ,CACQjL,CAAAA,CAAUgB,EAAA,CAAAA,CAAA,CAAeD,CAAf,CAAsB,CAAAzC,EAAtB,CAECnwC,KAAAA,EAAf,GAAI88C,CAAJ,GAA0BA,CAA1B,CAAmC,CAAnC,CAEA,KAAIC,EAAS,GACb,IAAiB/8C,IAAAA,EAAjB,GAAI68C,CAAJ,CAEI,GAA0B,GAA1B,EAAIA,CAAA7/C,OAAA,CAAgB,CAAhB,CAAJ,CACQrB,CACJ,CADQqyC,EAAA,CAAAA,CAAA,CAAgB6O,CAAA5/C,OAAA,CAAgB,CAAhB,CAAhB,CACR,CAAS,IAAT,EAAItB,CAAJ,GAAemhD,CAAf,CAAwBnhD,CAAxB,CAFJ,KAIK,CACGqhD,CAAAA,CAAanK,EAAA,CAAAA,CAAA,CAAegK,CAAf,CACjB,IAAIG,CAAAt+B,EAAJ,CAAsBmzB,CAAAnzB,EAAtB,CAAoC,MAEpCq+B,EAAA,CAASC,CAAAt+B,EAAT,CAA2BmzB,CAAAnzB,EAC3B,IAAuB,GAAvB,CAAcq+B,CAAd,CAA8B,CAM1B,CAAAptC,EAAA,CAAa,iBAAb,CACA,OAP0B,CAS9BmtC,CAAA,CAAU,EAdT,CAoBT,IAFIG,CAEJ,CAFe,CAEf,CAAgB,CAAhB,CAAOF,CAAP,EAAqBD,CAAA,EAArB,CAAA,CAA+B,CAE3B,IAAI7F,EAAazmC,EAAA,CAAAA,CAAA,CAAY,CAAA,CAAZ,CAAD,EAAuB,CAAA0gC,EAAvB,CAAoC,CAAA9tB,EAApC,CAAmD,IAAnE,CACI4zB,EAAyB,IAAb,EAAAC,CAAA,CAAmB,QAAnB,CAA8B,IAD9C,CAEI2D,EAAUF,EAAA,CAAAA,CAAA,CAAgB7I,CAAhB,CAFd,CAIInzB,EAAOmzB,CAAAnzB,EAEX,IAAIk8B,CAAA,CAAQ,CAAR,CAAJ,EAAkBkC,CAAlB,GACQ,CAACG,CADT,EACqBH,CADrB,EACyD,CADzD,CAC+BlC,CAAA,CAAQ,CAAR,CAAA/9C,QAAA,CAAmB,GAAnB,CAD/B,EAC4D,CACpD,IAAIqgD,EAAStC,CAAA,CAAQ,CAAR,CAATsC,CAAsB,GACtBtC,EAAA,CAAQ,CAAR,CAAJ,GAAgBsC,CAAhB,EAA0B,GAA1B,CAAgCtC,CAAA,CAAQ,CAAR,CAAhC,CACA,EAAAjrC,EAAA,CAAautC,CAAb,CAHoD,CAMxDtC,CAAA,CAAQ,CAAR,CAAJ,GACI5D,CACA,CADW4D,CAAA,CAAQ,CAAR,CACX,CAAA3D,CAAA,CAAY,IAFhB,CAIc5G,EAAAA,CAAAA,CAAAA,GAAsBwB,EAAAA,CAAAA,CA34GxCA,EAAAnzB,EAAA,CAAey+B,CAAAz+B,EACfmzB,EAAAE,GAAA,CAAoBoL,CAAApL,GACpBF,EAAAG,GAAA,CAAqBmL,CAAAnL,GACrBH,EAAAxG,EAAA,CAAgB8R,CAAA9R,EAy4GZ,EAAA17B,EAAA,CAAaonC,EAAA,CAAAA,CAAA,CAAoBlF,CAApB,CAA6BmF,CAA7B,CAAuCC,CAAvC,CAAb,CACA8F,EAAA,EAAUlL,CAAAnzB,EAAV,CAAyBA,CACzBu+B,EAAA,EAtB2B,CAhCnC;AAuHAtD,QAAA,GAAS,CAATA,CAAS,CAAC3N,CAAD,CAAO4C,CAAP,CACT,CACI,IAAI7c,EAAS,CAAA,CAEb,IAAI,CAKKia,CAAA7sC,OAAL,EAA4B,KAA5B,EAAoB6sC,CAApB,CAOU4C,CAPV,EAQI,CAAAj/B,EAAA,CAAa4mC,EAAb,CAAoCvK,CAApC,CARJ,EACQ,CAAAP,EAIJ,GAHI,CAAA97B,EAAA,CAAa,oBAAb,CA9kGLgR,CAAA,CA8kGyCs1B,CA9kGzC,CA8kGwD,CAAA5F,GAlkGvC3xB,EAZjB,CAAoB,EAApB,CA8kGK,CACA,CAAA,CAAA+sB,EAAA,CAAiB,CAAA,CAErB,EAAAO,CAAA,CAAO,EALX,CAWA,KAAIjvC,EAAKivC,CAAAhvC,OAAA,CAAY,CAAZ,CACT,IAAU,GAAV,EAAID,CAAJ,EAAuB,GAAvB,EAAiBA,CAAjB,CAA4B,MAAO,CAAA,CAKnC,EAAAg0C,GAAA,CAAoB,IAKpB,IAAIzgC,EAAA,CAAAA,CAAA,CAAJ,EAAgE,CAAhE,CAAkD07B,CAAA7sC,OAAlD,CAAmE,CAE3D,CAAAssC,EAAJ,GACIO,CADJ,CACW,IADX,CApmGDrrB,CAAA,CAqmGmBs1B,CArmGnB,CAqmGkC,CAAA5F,GAzlGjB3xB,EAZjB,CAAoB,EAApB,CAomGC,CACyD,GADzD,CAC+DstB,CAD/D,CAIA,KAAI4B,EAAS,CAAA,CAAb,CAC4B5B,EAAAA,CA3FxB,KAAAoR,EAAA,IAAA,EAAA,GAAAA,CAAA,CAAS,GAAT,CAAAA,CAMZ,KAJA,IAAIzK,EAAS,EAAb,CACIxG,EAAU,EADd,CAEI7wC,EAAI,CAFR,CAEW+hD,EAAQ,CAEnB,CAAO/hD,CAAP,CAAW0wC,CAAA7sC,OAAX,CAAA,CAAwB,CACpB,IAAIpC,EAAKivC,CAAA,CAAK1wC,CAAA,EAAL,CACL6wC,EAAJ,CACQpvC,CADR,EACcovC,CADd,GAEQA,CAEA,CAFU,EAEV,CADAwG,CAAApuC,KAAA,CAAYynC,CAAA/uC,OAAA,CAAYogD,CAAZ,CAAmB/hD,CAAnB,CAAuB+hD,CAAvB,CAAZ,CACA,CAAAA,CAAA,CAAQ/hD,CAJhB,EAQU,GAAV,EAAIyB,CAAJ,EAAuB,GAAvB,EAAiBA,CAAjB,CACIovC,CADJ,CACcpvC,CADd,CAI0B,CAJ1B,EAIIqgD,CAAAvgD,QAAA,CAAeE,CAAf,CAJJ,GAKI41C,CAAApuC,KAAA,CAAYynC,CAAA/uC,OAAA,CAAYogD,CAAZ,CAAmB/hD,CAAnB,CAAuB+hD,CAAvB,CAA+B,CAA/B,CAAZ,CACA,CAAAA,CAAA,CAAQ/hD,CANZ,CAVoB,CAmBpB+hD,CAAJ,CAAY/hD,CAAZ,EACIq3C,CAAApuC,KAAA,CAAYynC,CAAA/uC,OAAA,CAAYogD,CAAZ,CAAmB/hD,CAAnB,CAAuB+hD,CAAvB,CAAZ,CAGJ1K,EAAA,CAAO,CAAP,CAAA,CAAYA,CAAA,CAAO,CAAP,CAAA3zC,YAAA,EACZ,IAAI2zC,CAAJ,EAAcA,CAAAxzC,OAAd,CAA6B,CACzB,IAAIm+C;AAAK3K,CAAA,CAAO,CAAP,CAAT,CACI4K,EAAMD,CAAAtgD,OAAA,CAAU,CAAV,CACV,KAAK1B,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgBgiD,CAAAn+C,OAAhB,CAA2B7D,CAAA,EAA3B,CAEI,GADAyB,CACI,CADCugD,CAAAtgD,OAAA,CAAU1B,CAAV,CACD,CAAO,GAAP,EAAAiiD,CAAA,EAAqB,GAArB,EAAcA,CAAd,EAAiC,GAAjC,CAA4BxgD,CAA5B,EAA6C,GAA7C,CAAwCA,CAA5C,CAAsD,CAClD41C,CAAA,CAAO,CAAP,CAAA,CAAY2K,CAAArgD,OAAA,CAAU3B,CAAV,CACZq3C,EAAA6K,QAAA,CAAeF,CAAArgD,OAAA,CAAU,CAAV,CAAa3B,CAAb,CAAf,CACA,MAHkD,CALjC,CA+DrB,OAnDDq3C,CAmDS,CAAO,CAAP,CAAA31C,OAAA,CAAiB,CAAjB,CAAR,EACA,KAAK,GAAL,CACI+0B,CAAA,CAASypB,EAAA,CAAAA,CAAA,CArDd7I,CAqDc,CACT,MACJ,MAAK,GAAL,CACiB,IAAA,GAxDlBA,CAwDkB,CAAO,CAAP,CAAA,CAAW,GAxD7BA,CAwD6B,CAAO,CAAP,CAAX,CAAsB3G,EAAAA,CAtiC/C,IAAa,GAAb,EAAI4G,EAAJ,CAsiCY6K,CAriCR9tC,EAAA,CAAa,sBAAb,CAMA,CA+hCQ8tC,CApiCR9tC,EAAA,CAAa,6BAAb,CAKA,CA+hCQ8tC,CAniCR9tC,EAAA,CAAa,6BAAb,CAIA,CA+hCQ8tC,CAliCR9tC,EAAA,CAAa,8BAAb,CAGA,CA+hCQ8tC,CAjiCR9tC,EAAA,CAAa,2CAAb,CAEA,CA+hCQ8tC,CAhiCR9tC,EAAA,CAAa,4BAAb,CACA,CA+hCQ8tC,CA/hCR9tC,EAAA,CAAa,wCAAb,CAPJ,KAAA,CAWA,IAAIjK;AAAQsmC,EAAAhvC,OAAA,CAAY,CAAZ,CACZ,IAAa,GAAb,EAAI0I,EAAJ,CAAkB,CAEd,IAAAg4C,GADcA,CACdA,CAAWnE,EAAA,CAwhCHkE,CAxhCG,CAwhCHA,CAxhCwBlN,EAArB,CACXmN,GAAA,EAAWnE,EAAA,CAuhCHkE,CAvhCG,CAuhCHA,CAvhCwB56B,EAArB,CAEX,EADA66B,EACA,EADWnE,EAAA,CAshCHkE,CAthCG,CAshCHA,CAthCwB16B,EAArB,CACX,GAqhCQ06B,CArhCM9tC,EAAA,CAAa,gBAAb,CALA,CAAlB,IASA,IAAa,GAAb,EAAIjK,EAAJ,CAAkB,CACd,IAAI/J,GAAI,CAACi3C,EAALj3C,EAAc,CACdi3C,GAAJ,GA+gCQ6K,CA/gCG/M,GAAX,CAAqC/0C,EAArC,CA+gCQ8hD,EA9gCR9tC,EAAA,CAAa,cAAb,CAA8BhU,EAA9B,CAAkC,iBAAlC,CAHc,CAAlB,IAOA,IAAcqE,IAAAA,EAAd,GAAI4yC,EAAJ,CA0gCY6K,CAzgCR9tC,EAAA,CAAa,4BAAb,CADJ,KAAA,CAKA,IAAIkiC,GAAmB,GAAT,EAAAe,EAAA,CAAc1C,CAAA,EAAd,CAA+B2C,EAAA,CAqgCjC4K,CArgCiC,CAAe7K,EAAf,CAqgCjC6K,CArgCuDtN,EAAtB,CAEhC,IAAb,EAAIzqC,EAAJ,CACwB,IAApB,EAAImsC,EAAAnzB,EAAJ,EACI8xB,EAAA,CAigCIiN,CAjgCJ,CACA,CAggCIA,CAhgCJ9tC,EAAA,CAAa,yBAAb,CAFJ,EAKIwpC,EAAA,CA6/BIsE,CA7/BJ,CA6/BIA,CA7/BgBlN,EAApB,CAAqCsB,EAArC,CALJ,EAOIsH,EAAA,CA2/BIsE,CA3/BJ,CA2/BIA,CA3/BgB56B,EAApB,CAAqCgvB,EAArC,CAPJ,EASIsH,EAAA,CAy/BIsE,CAz/BJ,CAy/BIA,CAz/BgB16B,EAApB,CAAsC8uB,EAAtC,CATJ,EAkgCQ4L,CAv/BR9tC,EAAA,CAAa,sBAAb,CAznEGgR,CAAA,CAgnGK88B,CAhnGL,CAynEkD5L,EA7mEjCnzB,EAZjB,CAAoB,EAApB,CAynEH,CAZJ,CAgBoB,IAhBpB,EAgBImzB,EAAAnzB,EAhBJ,GAkBAq2B,EAAA,CAi/BY0I,CAj/BZ,CAAsB5L,EAAtB,CAA+BmD,CAA/B,CAEA,CAAa,GAAb,EAAItvC,EAAJ,CA++BY+3C,CA9+BRt7B,GAAA,CA8+BQs7B,CA9+BWlN,EAAnB,CAAoCsB,EAApC,CADJ,CAIa,GAAb,EAAInsC,EAAJ,CA2+BY+3C,CA1+BRt7B,GAAA,CA0+BQs7B,CA1+BW56B,EAAnB,CAAoCgvB,EAApC,CADJ,CAIa,GAAb,EAAInsC,EAAJ,CAu+BY+3C,CAt+BRt7B,GAAA,CAs+BQs7B,CAt+BW16B,EAAnB,CAAqC8uB,EAArC,CADJ;AAu+BY4L,CAn+BZ9tC,EAAA,CAAa,8BAAb,CAA8CjK,EAA9C,CAhCA,CAPA,CA5BA,CAuiCY,KACJ,MAAK,GAAL,CA19BR6E,IAAAA,GA29BYozC,CA39BZpzC,EA2sHI,GAAAqzC,EAAJ,GACI,EAAAA,EAAAlgD,MADJ,CAC8B,EAD9B,CA/uFY,MACJ,MAAK,GAAL,CAn9BZ,CAAA,CAAA,CACI,IAAIhC,EAAJ,CACIswC,GAo5BG2G,CAp5BI,CAAO,CAAP,CADX,CAEIC,GAm5BGD,CAn5BK,CAAO,CAAP,CAFZ,CAGIkL,GAk5BGlL,CAl5BI,CAAO,CAAP,CAHX,CAIImL,GAi5BGnL,CAj5BM,CAAO,CAAP,CAEb,IAAa,GAAb,EAAIC,EAAJ,CAAkB,CACd,IAAImL,GAAW,EACf,KAAKriD,EAAL,GAAU4Y,GAAV,CAg9BQ0pC,CA/8BAlN,GAAA,CAAgBp1C,EAAhB,CAAJ,GACQqiD,EACO,GADGA,EACH,EADe,GACf,EAAAA,EAAA,EAAWriD,EAF1B,CAKJqiD,GAAA,EAAY,gBA08BJC,EAz8BRruC,EAAA,CAAa,uBAAb,CAy8BQquC,EAx8BRruC,EAAA,CAAa,2CAAb,CAw8BQquC,EAv8BRruC,EAAA,CAAa,mDAAb,CAu8BQquC,EAt8BRruC,EAAA,CAAa,6DAAb,CACIouC,GAAA5+C,OAAJ,EAq8BQ6+C,CAr8BaruC,EAAA,CAAa,8BAAb,CAA8CouC,EAA9C,CAbP,CAAlB,IAiBA,IAAa,OAAb;AAAInL,EAAJ,CAAsB,CAClB,IAAIqL,GAASC,EAAA,CAg8BLF,CAh8BKzzC,EAAA,CAAkB,CAAA,CAAlB,CACb,IAAY,SAAZ,EAAIszC,EAAJ,CAaI1tC,OAAAlS,IAAA,CAAYggD,EAAZ,CAbJ,KAcO,CAlDX1zC,IAAAA,GAm+BYyzC,CAn+BZzzC,EA2sHI,GAAAqzC,EAAJ,GACI,EAAAA,EAAAlgD,MADJ,CAC8B,EAD9B,CAvpHYugD,GAAJ,EA+6BID,CA/6BQruC,EAAA,CAAasuC,EAAb,CAFT,CAhBW,CAAtB,IAuBA,IAAa,SAAb,EAAIrL,EAAJ,CAnbA,IAAK,IAAI4B,GAAS,CAAlB,CAAqBA,EAArB,CA61CYwJ,CA71CkB1N,EAAAnxC,OAA9B,CAAwDq1C,EAAA,EAAxD,CAAkE,CAC9D,IAAII,GA41CIoJ,CA51CU1N,EAAA,CAAkBkE,EAAlB,CAAlB,CACSF,EAAT,KAASA,EAAT,GAAoBM,GAAAtxC,EAApB,CACI,GAAyB,GAAzB,EAAIgxC,EAAAt3C,OAAA,CAAe,CAAf,CAAJ,CAAA,CAEA,IAAI63C,GADSD,EAAAtxC,EAAAqxC,CAAqBL,EAArBK,CACG,EAChB,IAAkB30C,IAAAA,EAAlB,GAAI60C,EAAJ,CAAA,CACA,IAAIsJ,GAAcvJ,EAAAtxC,EAAA,CAAqBgxC,EAArB,CAAA,EACd6J,GAAJ,GAAiB7J,EAAjB,CAA2B6J,EAA3B,CAq1CIH,EAp1CJruC,EAAA,CAvyDDgR,CAAA,CA2nGKq9B,CA3nGL,CAuyD+BnJ,EAvyD/B,CAAoB,EAApB,CAuyDC,CAA2C,GAA3C,CAAiDP,EAAjD,CAHA,CAHA,CAH0D,CAmblE,IAAA,CAKA,GAAY,GAAZ,EAAItI,EAAJ,CAAiB,CACb,IAAKtwC,EAAL,GAAU4Y,GAAV,CACI,GAg2BDq+B,CAh2BK,CAAO,CAAP,CAAJ,EAAiBj3C,EAAjB,CAAoB,CAChB,IAAI05C,GAk6BJ4I,CAl6BelN,GAAA,CAAgBp1C,EAAhB,CACX05C,GAAJ,EA81BLzC,CA71BSv1C,MAAA,EAEA,CA21BTu1C,CA51BSv1C,MAAA,EACA,CAAAg4C,EAAA,CA21BTzC,CA31BS,CAHJ,EAi6BAqL,CA55BIruC,EAAA,CAAa,yBAAb,CAAyCijC,EAAzC,CAEJ,OAAA,CATgB,CAYnBA,EAAL,GAAY5G,EAAZ,CAu5BQgS,CAv5BW7M,GAAnB,EAAwC,IAAxC,CAda,CAAjB,IAq6BY6M,EAr5BR7M,GAAA,CAAoBnF,EAGxB,IAAY,IAAZ,EAAIA,EAAJ,CAAkB,CACG4G,IAAAA,GAAAA,EAAAA,CAAOiL,GAAAA,EAAPjL,CAtoEjBwL;AAAQ,EAsoESxL,CAroEjByL,GAAW,CAqoEMzL,CApoEjB0L,GAqhGQN,CArhGGvN,EAooEMmC,CAnoEjB2L,GAohGQP,CAphGGrN,EAEf,IAAI4N,EAAAp/C,OAAJ,CAAqB,CACjB,IAAIq/C,GAAQ,CAACC,EAATD,EAihGIR,CAjhGcpN,GAAtB,CACIkM,GAAS,CAAC4B,EAAV5B,EAAoB,EAEpBx/C,MAAA,CAAMkhD,EAAN,CAAJ,CACIA,EADJ,CACY1B,EADZ,CAGIsB,EAHJ,CAGY,OAGRI,GAAJ,CAAYD,EAAAp/C,OAAZ,GAwgGQ6+C,CAvgGJruC,EAAA,CAAa,aAAb,CAA6B4uC,EAAAp/C,OAA7B,CAA+C,YAA/C,CACA,CAAAq/C,EAAA,CAAQD,EAAAp/C,OAFZ,CAKAm/C,GAAA,EAAYE,EACG,EAAf,CAAIF,EAAJ,GAI8C,IAA1C,EAAIC,EAAA,CAASA,EAAAp/C,OAAT,CAA2B,CAA3B,CAAAuf,EAAJ,EACI8/B,EACA,CADQF,EACR,CADmBE,EACnB,CAAAF,EAAA,CAAW,CAFf,EAIIA,EAJJ,EAIgBC,EAAAp/C,OARpB,CAYA,KAAIw/C,GAAW,EACD,OAAd,EAAID,EAAJ,GACI5B,EACA,CADS,GACT,CAAA6B,EAAA,CAAW,CAAC,MAAD,CAFf,CAqBA,KAhBc3+C,IAAAA,EAgBd,GAhBIy+C,EAgBJ,EAg+FQT,CA/+FJruC,EAAA,CAAa6uC,EAAb,CAAqB,wBAArB,CAeJ,CAAgB,CAAhB,CAAO1B,EAAP,EAAqBwB,EAArB,EAg+FQN,CAh+FyBvN,EAAjC,CAAA,CAA2D,CAEvD,IAAIoB,GAAU0M,EAAA,CAASD,EAAA,EAAT,CACd,IAAoB,IAApB,EAAIzM,EAAAnzB,EAAJ,CAA0B,KAM1B,KAAIkgC,GAAa1O,CAAA,CAAa2B,EAAAnzB,EAAb,CAAjB,CAGIu4B,GAAYuH,EAAA,EAHhB,CAeIK,GAAe9H,EAAA,CAw8FfiH,CAx8Fe,CAAoBY,EAApB,CAbJ5H,SAaI,CAA0CC,EAA1C,CAEnB,EAAI,CAAC0H,EAAAx/C,OAAL,EAA6D,CAA7D,EAAwB0/C,EAAAhiD,QAAA,CAAqB8hD,EAAA,CAAS,CAAT,CAArB,CAAxB,GAs8FIX,CAr8FAruC,EAAA,CAAakvC,EAAb,CAOAD,GAAAE,GAAJ,GACIR,EAAoE,EAAxDM,EAAAE,GAAwD,CAAjChC,EAAiC,EAAvB8B,EAAAE,GAAuB,CAAAN,EAAA,EAASI,EAAAE,GADjF,CAIIR;EAAJ,EAAgBC,EAAAp/C,OAAhB,GAAiCm/C,EAAjC,CAA4C,CAA5C,CA07FIN,EAz7FJpN,GAAA,CAAmB4N,EACnBH,GAAA,EACAvB,GAAA,EAzCuD,CAlD1C,CAoGhBuB,EAAL,GA86FYL,CA76FRruC,EAAA,CAAa,KAAb,CAAqByuC,EAArB,CAA6B,mBAA7B,CACA,CA46FQJ,CA56FRpN,GAAA,CAAmB5wC,IAAAA,EAFvB,CA4hEkB,CAAlB,IAAA,CAKA,IAAIynC,GAAM,CAAV,CACIsX,GAAiB,IAAjBA,EAAS/S,EADb,CAEI6F,GAAUgB,EAAA,CA24BFmL,CA34BE,CAAepL,EAAf,CA24BFoL,CA34BwB5N,GAAtB,CAEVyN,GAAJ,GAC0B,GAAtB,EAAIA,EAAA7gD,OAAA,CAAY,CAAZ,CAAJ,EACI6gD,EACA,CADOA,EAAA5gD,OAAA,CAAY,CAAZ,CACP,EADyB6gD,EACzB,CAAArW,EAAA,CAAMuG,EAAA,CAs4BFgQ,CAt4BE,CAAgBH,EAAhB,CAFV,EAMIpW,EANJ,CAKqBoL,EAAAmK,CAm4BbgB,CAn4BahB,CAAea,EAAfb,CACXt+B,EANV,CAM4BmzB,EAAAnzB,EAG5B,CADU,CACV,CADI+oB,EACJ,GADaA,EACb,CADmB,CACnB,EAAU,KAAV,CAAIA,EAAJ,GAAmBA,EAAnB,CAAyB,KAAzB,CAVJ,CAaA,KAAI4D,GA43BQ2S,CA53BA3S,EACRwG,GAAAxG,EAAJ,GA23BY2S,CA33BO3S,EAAnB,CAAgCwG,EAAAxG,EAAhC,CAQA,KANA,IAAI1sB,GAAgB,IAAR,EAAAqtB,EAAA,CAAc,CAAd,CAAkB,CAA9B,CACIiP,GAASxT,EAATwT,EAAgB,EADpB,CAEI+D,GAAyB,CAAR,EAAArgC,EAAA,CAAW,CAAX,CAAe,CAFpC,CAGIm+B,IAAY7B,EAAZ6B,CAAqBkC,EAArBlC,CAAqC,CAArCA,EAA0CkC,EAA1ClC,CAAyD,CAAzDA,EAA+D,CAHnE,CAKIhD,GAAQ,EACZ,CAAOgD,EAAA,EAAP,EAA4B,CAA5B,CAAmB7B,EAAnB,CAAA,CAA+B,CAAA,IACvB73C,GAAQ,EADe,CACX67C,GAAS,EACzBrM,GAAA,CA1wEGjyB,CAAA,CA2nGKq9B,CA3nGL,CA0wEoBnM,EA9vEHnzB,EAZjB,CAAoB,EAApB,CA4wEH,KADA,IAAI/iB,GAAIqjD,EACR,CAAa,CAAb,CAAOrjD,EAAA,EAAP,EAA6B,CAA7B,CAAkBs/C,EAAA,EAAlB,CAAA,CAAgC,CAC5B,IAAI7+C,GA82BA4hD,CA92BIrK,GAAA,CAAa9B,EAAb,CAAsB,CAAtB,CACJkN,GAAJ,EACQ37C,EACJ,GADWA,EACX,EADoB,GACpB,EAAAA,EAAA,EAAShH,EAFb,GAIIgH,EACA,EADS6xC,EAAA,CAy2BT+I,CAz2BS,CAAe5hD,EAAf,CACT,CAAAgH,EAAA,EAAS,IALb,CAYA,KADA,IAAIhG;AAAQ,EAAZ,CACS9B,GAAI,CAAb,CAAwB,CAAxB,EAAgBqjB,EAAhB,EAAsC,CAAtC,EAA6BvhB,EAA7B,CAAyC9B,EAAA,EAAzC,CAA8C,CAC1C,IAAIN,GAAMoB,EAANpB,CAAUuC,IAAAC,IAAA,CAAS,CAAT,CAAYJ,EAAZ,CAAVpC,CAAgCuC,IAAAC,IAAA,CAAS,CAAT,CAH5B8tC,CAG4B,CACpCloC,GAAA,EAASud,CAAA,CA+1BTq9B,CA/1BS,CAAehjD,EAAf,CAJDswC,CAIC,CAAT,CAAoC,GACpCtwC,GAAA,EAAyB,CACzBikD,GAAA,EAAe,EAAJ,CAAAjkD,EAAA,CAAU,GAAV,CAAgBkD,MAAAC,aAAA,CAAoBnD,EAApB,CAC3BoC,GAAA,EAPQkuC,CAEkC,CAdlB,CAsB5BwO,EAAJ,GAAWA,EAAX,EAAoB,IAApB,CAEIA,GAAA,CADAiF,EAAJ,CACIjF,EADJ,EACa12C,EADb,CACqB,GADrB,EAGI02C,EAHJ,EAGalH,EAHb,CAGqB,IAHrB,CAG4BxvC,EAH5B,EAG0C,CAAL,CAACzH,EAAD,CAAU,GAAV,CAAgBsjD,EAAhB,CAA0B,EAH/D,EA3B2B,CAkC3BnF,EAAJ,EAi1BYkE,CAj1BDruC,EAAA,CAAamqC,EAAb,CAi1BCkE,EA/0BZ3S,EAAA,CAAaA,EAnEb,CAxBA,CA/CJ,CA09BgB,KACJ,MAAK,GAAL,CACI,GAAiB,MAAjB,EAtELsH,CAsES,CAAO,CAAP,CAAJ,CAAyB,KAx0BzC,KAEQ3G,GAgwBG2G,CAhwBI,CAAO,CAAP,CAFf,CAGQC,GA+vBGD,CA/vBK,CAAO,CAAP,CACZ,IAAY,GAAZ,EAAI3G,EAAJ,EAA2B,IAA3B,EAAmBA,EAAnB,CAAiC,CAC7B,IAAAkT,GAo0BQC,CAp0BAxL,GACR,KAAAyL,GAm0BQD,CAn0BAtL,GAFqB,CAAjC,IAIIjB,GAAA,CAAQ,IAEZ,IAAa,IAAb,EAAIA,EAAJ,CA+zBYuM,CA9zBRxvC,EAAA,CAAa,uBAAb,CACA,CA6zBQwvC,CA7zBRxvC,EAAA,CAAa,yCAAb,CAFJ,KAMA,KADA,IAAIkiC,GAAUgB,EAAA,CA0zBFsM,CA1zBE,CAAevM,EAAf,CA0zBFuM,CA1zBwB/O,GAAtB,CAAd,CACS90C,GAAI,CAAb,CAAgBA,EAAhB,CAkvBOq3C,CAlvBaxzC,OAApB,CAAmC7D,EAAA,EAAnC,CAAwC,CACpC,IAAIc,GAAIuyC,EAAA,CAwzBAwQ,CAxzBA,CAivBLxM,CAjvB0B,CAAOr3C,EAAP,CAArB,CACR,IAAU0E,IAAAA,EAAV;AAAI5D,EAAJ,CAAqB,KACrBA,GAAA,CAAI04C,EAAA,CAAkB14C,EAAlB,CAszBI+iD,EArzBRxvC,EAAA,CAAa,WAAb,CA10EGgR,CAAA,CA+nGKw+B,CA/nGL,CA00EuCtN,EA9zEtBnzB,EAZjB,CAAoB,EAApB,CA00EH,CAAqD,QAArD,CAAgEu2B,EAAA,CAqzBxDkK,CArzBwD,CAAeD,EAAAjwC,KAAA,CAqzBvEkwC,CArzBuE,CAAiBtN,EAAjB,CAAf,CAAhE,CAA4G,MAA5G,CAAqHoD,EAAA,CAqzB7GkK,CArzB6G,CAAe/iD,EAAf,CAArH,CACAgjD,GAAAnwC,KAAA,CAozBQkwC,CApzBR,CAAiBtN,EAAjB,CAA0Bz1C,EAA1B,CAA6B,CAA7B,CALoC,CA0zB5B,KACJ,MAAK,GAAL,CAC0B,IAAA,GA1E3Bu2C,CA0E2B,CAAO,CAAP,CAAA,CAAW3G,GAAAA,CArb7C,IAAchsC,IAAAA,EAAd,GAAI4yC,EAAJ,CAAyB,CACrB,IAAIf,GAAUgB,EAAA,CAobNwM,CApbM,CAAezM,EAAf,CACdmC,GAAA,CAmbQsK,CAnbR,CAAsBxN,EAAtB,CAA+BmD,EAA/B,CAmbQqK,EAxpDZl9B,GAAA,CAwpDYk9B,CAxpDO9O,EAAnB,CAsuC2BsB,EAtuC3B,CAA6C,CAAA,CAA7C,CAmuCyB,CAKzBh3B,EAAA,CAgbYwkC,CAhbZ,CAAc,CAAA,CAAd,CAgbmDzQ,CAhbnD,CAibY,MACJ,MAAK,GAAL,CACI0Q,CA7yBR51C,MAAA+Q,EAAJ,EA6yBwBm0B,CA3yBpB,EA2yBQ0Q,CA5yBK3vC,EAAA,CAAa,SAAb,CACb,CAAAmL,EAAA,CA2yBQwkC,CA3yBR,CAFJ,EAIQ9uC,EAAA,CAyyBI8uC,CAzyBJ,CAAY,CAAA,CAAZ,CAJR,EA6yBwB1Q,CA7yBxB,EA6yBY0Q,CAxyBK3vC,EAAA,CAAa,gBAAb,CAyyBL,MACJ,MAAK,GAAL,CACI,GAAiB,IAAjB,EAhFLgjC,CAgFS,CAAO,CAAP,CAAJ,CAAuB,CACJ,IAAA,GAAA3G,CAAA/uC,OAAA,CAAY,CAAZ,CAvxB/B+uC,GAAA,CAAOvB,EAAA,CAASuB,EAAT,CACP,IAAK2C,EAAA,CAsxBgB4Q,CAtxBhB,CAAqBvT,EAArB,CAAL,CAAA,CAsxB+C4C,CAlxB/C,EAkxBqB2Q,CAlxBR5vC,EAAA,CAAa,QAAb,CAAwBq8B,EAAxB,CACb,KAAA,GAAO,CAAA,CALP,CAAA,IAsxB+C4C,EApxB3C,EAoxBiB2Q,CArxBJ5vC,EAAA,CAAa,SAAb,CAAyBq8B,EAAzB,CACb,CAAA,EAAA,CAAO,CAAA,CAoxBU,GAAL,GACIja,CADJ,CACa,CAAA,CADb,CAGA,MAJmB,CAMvB6b,CAAA,CAAS,CAAA,CACT,MACJ,MAAK,GAAL,CACsB,IAAA,GAzFvB+E,CAyFuB,CAAO,CAAP,CAjU9B,IAAa,GAAb,EAwOOA,CAyFkCC,CAAO,CAAPA,CAjUzC,CAiUY4M,CAhUR7vC,EAAA,CAAa,uBAAb,CAEA;AA8TQ6vC,CA/TR7vC,EAAA,CAAa,2BAAb,CACA,CA8TQ6vC,CA9TR7vC,EAAA,CAAa,+BAAb,CAHJ,KAAA,CAOA,IAAkB8vC,GAAU,CAA5B,CACIC,GAAcxP,CAAA,EADlB,CAEIyP,GAAezP,CAAA,EAGnB,KAqTYsP,CAvTZ7vC,EAAA,CAAa,kBAAb,CA11FOgR,CAAA,CAipGK6+B,CAjpGL,CA01F0CG,EA90FzBjhC,EAZjB,CAAoB,EAApB,CA01FP,CAEA,CALckhC,EAKd,CAAOH,EAAP,CAAA,CAA0B,CAEtB,IAFsB,IAClBI,GAAQ,IADU,CACcC,GAAS,GAC7C,CAAmC,KAAnC,CAAQH,EAAAjhC,EAAR,GAA8B,CAA9B,CAAA,CAA4C,CACxCghC,EAAAhhC,EAAA,CAkTI8gC,CAlTe7L,GAAA,CAAagM,EAAb,CAA2B,CAA3B,CAKnB,IAAyB,IAAzB,EAAIA,EAAAjhC,EAAJ,EAAiC,CAACohC,EAAA,EAAlC,CAA4C,KAC5C,IAAI,EAAAJ,EAAAhhC,EAAA,CAAmB,CAAnB,CAAJ,CAAA,CAzDR,IAqWY8gC,IAAAA,GAAAA,CAAAA,CA3SiBE,GAAAA,EA2SjBF,CAxWRK,GAAQ,IAwWAL,CAvWR9gC,GAAOmzB,EAAAnzB,EAuWC8gC,CAtWRO,GAAWrhC,EAsWH8gC,CArWH7jD,GAAI,CAAb,CAAqB,CAArB,EAAgBA,EAAhB,EAA4B+iB,EAA5B,CAAkC/iB,EAAA,EAAlC,CAAuC,CACnC,GAAQ,CAAR,CAAIA,EAAJ,CAAW,CACPk2C,EAAAnzB,EAAA,CAAeA,EACf,KAAI1iB,GAAI+6C,EAAA,CAAAA,EAAA,CAAoBlF,EAApB,CACR,IAAwB,CAAxB,EAAI71C,EAAAa,QAAA,CAAU,KAAV,CAAJ,CAA2B,CAOvB,IAAIvB,GAAIU,EAAAa,QAAA,CAAU,GAAV,CAER,IAAI6hB,EAAJ,EADQ1iB,EAAAa,QAAAtB,CAAU,GAAVA,CAAeD,EAAfC,CAAiB,CAAjBA,CACR,CAAgBD,EAAhB,CAAoB,CAApB,EAAuB,CAAvB,EAA4BykD,EAA5B,CAAsC,CAClCF,EAAA,CAAQ7jD,EACR,MAFkC,CATf,CAHpB,CAkBX0iB,EAAA,EAAQ,CAnB2B,CAqBvCmzB,EAAAnzB,EAAA,CAAeqhC,EAsCP,IArCR,EAqCQ,CArCDF,EAqCC,CAAW,KAFX,CAPwC,CAiB5C,GAAI,CAACA,EAAL,EAlB8BG,IAkB9B,EAAcH,EAAd,CAAkC,KAClC,KAAIvL;AAAU,IACd,IAAY,IAAZ,EAAItI,EAAJ,CAAkB,CACd,IAAIlxC,GAAI+kD,EAAAxiD,MAAA,CAAY,YAAZ,CACJvC,GAAJ,GAAOw5C,EAAP,CAAiB0H,EAAA,CA8RbwD,CA9Ra,CAAY1kD,EAAA,CAAE,CAAF,CAAZ,CAAjB,CAFc,CAIlB+kD,EAAA,CAAQtH,EAAA,CAAQsH,EAAR,CAAe,EAAf,CAAR,CAA6B,KAA7B,EAAsCvL,EAAtC,EAAiD,WAAjD,CAr3FG3zB,CAAA,CAipGK6+B,CAjpGL,CAq3FwEG,EAz2FvDjhC,EAZjB,CAAoB,EAApB,CAq3FH,CA4RQ8gC,EA3RR7vC,EAAA,CAAakwC,EAAb,CAEAJ,GAAA,EA5BsB,CA8BrBA,EAAL,EAuRYD,CAvRE7vC,EAAA,CAAa,2BAAb,CA1Cd,CAkUY,KACJ,MAAK,GAAL,CACI,GAAiB,IAAjB,EA5FLgjC,CA4FS,CAAO,CAAP,CAAJ,CAAuB,CACnBqJ,EAAA,CAAAA,CAAA,CA7FTrJ,CA6FqB,CAAO,CAAP,CAAZ,CAAuB,CAAA,CAAvB,CACA,MAFmB,CAIvB/E,CAAA,CAAS,CAAA,CACT,MACJ,MAAK,GAAL,CAxrBZ,CAAA,CAAA,CACI,IAAIlyC,EAAJ,CACIukD,GAAY,IADhB,CAEIC,EAmlBGvN,CAnlBS,CAAO,CAAP,CACC,IAAjB,EAAIuN,CAAJ,GAAsBA,CAAtB,CAAkClgD,IAAAA,EAAlC,CAEA,IAAkBA,IAAAA,EAAlB,GAAIkgD,CAAJ,CAA6B,CACzB,IAAI/2C,GAAc,CAClB,IAAiB,KAAjB,EAAI+2C,CAAJ,CACI/2C,EACA,CADc,UACd,CAAA+2C,CAAA,CAAY,IAFhB,KAGO,IAAiB,IAAjB,EAAIA,CAAJ,CACHD,EACA,CADY,CAAA,CACZ,CAAAC,CAAA,CAAY,IAFT,KAGA,IAAiB,KAAjB,EAAIA,CAAJ,CACHD,EACA,CADY,CAAA,CACZ,CAAAC,CAAA,CAAY,IAFT,KAGA,CAKc,MAAjB,EAAIA,CAAJ,GAAyBA,CAAzB,CAAqC,KAArC,CACiB,MAAjB,EAAIA,CAAJ,GAAwBA,CAAxB,CAAoC,UAApC,CACA,KAAKxkD,EAAL,GAAU4Y,GAAV,CACI,GAAI4rC,CAAJ,EAAiBxkD,EAAjB,CAAoB,CAChByN,EAAA,CAAcmL,EAAA,CAAyB5Y,EAAzB,CACdukD,GAAA,CAAY,CAAC,EA8pBjBE,CA9pBmBh3C,GAAF,CAAqBA,EAArB,CACb,MAHgB,CAMxB,GAAI,CAACA,EAAL,CAAkB,CA0pBdg3C,CAzpBAxwC,EAAA,CAAa,4BAAb;AAA4CuwC,CAA5C,CACA,OAAA,CAFc,CAdf,CAmBP,GAAI/2C,EAAJ,CACI,GAAiB,IAAjB,EAijBDwpC,CAjjBK,CAAO,CAAP,CAAJ,CAopBIwN,CAnpBAh3C,GACA,EADoBA,EACpB,CAAA82C,EAAA,CAAY,CAAA,CAFhB,KAIK,IAAiB,KAAjB,EA6iBNtN,CA7iBU,CAAO,CAAP,CAAJ,GAgpBDwN,CA/oBAh3C,GAEI,EAFgB,CAACA,EAEjB,CADJ82C,EACI,CADQ,CAAA,CACR,CAjxjBRrqC,UAixjBQ,EAAAzM,EAHH,EAGwC,CAErC,IADA,IAAI7N,GAAkC,GAA9B,EA4oBZ6kD,CA5oBYnP,EAAA7xC,OAAA,CA4oBZghD,CA5oBgDnP,EAAA7xC,OAApC,CAAiE,GAAjE,CAAwE,CAChF,CAAO7D,EAAP,CA2oBJ6kD,CA3oBenP,EAAA7xC,OAAX,CAAA,CA2oBJghD,CA1oBQxwC,EAAA,CA0oBRwwC,CA1oBqBnP,EAAA,CAAoB11C,EAAA,EAApB,CAAb,CA0oBR6kD,EAxoBInP,EAAA,CAAsB,EALe,CAtCxB,CAoD7B,IAAIr1C,GAAI,CAAR,CACIykD,GAAc,EAClB,KAAK1kD,EAAL,GAAU4Y,GAAV,CACI,GAAI,CAAC4rC,CAAL,EAAkBA,CAAlB,EAA+BxkD,EAA/B,CAAkC,CAE9B,IAAI2kD,GAAW,CAAC,EA0nBZF,CA1nBch3C,GAAF,CADCmL,EAAAgsC,CAAyB5kD,EAAzB4kD,CACD,CAChB,IAAkB,IAAlB,GAAIL,EAAJ,EAA0BA,EAA1B,EAAuCI,EAAvC,CACID,EAOJ,GAPiBA,EAOjB,EAPgC,GAOhC,EANM,EAAEzkD,EAMR,CANY,EAMZ,GANiBykD,EAMjB,EANgC,MAMhC,EADS,KACT,EADI1kD,EACJ,GADgBA,EAChB,CADoB,MACpB,EAAA0kD,EAAA,EAAe1kD,EAXe,CAepBsE,IAAAA,EAAlB,GAAIkgD,CAAJ,EA6mBYC,CA5mBRxwC,EAAA,CAAa,oEAAb,CA4mBQwwC,EAzmBZxwC,EAAA,EAA4B,IAAd,GAAAswC,EAAA,CAAqBA,EAAA,CAAW,gBAAX,CAA8B,gBAAnD,CAAuE,yBAArF;CAAmHG,EAAnH,EAAkI,MAAlI,EAEAvP,GAAA,CAumBYsP,CAvmBZ,CAlFJ,CA0rBgB,KACJ,MAAK,GAAL,CACI,GAAiB,OAAjB,EAtGLxN,CAsGS,CAAO,CAAP,CAAJ,CAA0B,CACtB2J,EAAA,CAAAA,CAAA,CAAatQ,CAAA/uC,OAAA,CAAY,CAAZ,CAAb,CACA,MAFsB,CAId,IAAA,GA1GjB01C,CA0GiB,CAAO,CAAP,CAAA,CA3apB4N,GAAiB,GAAR,EAAAvU,EAAA,CAAa,CAAb,CAA0B,IAAR,EAAAA,EAAA,CAAc,CAAd,CAAmB,EAElD,IAAe,GAAf,EA+TO2G,CA0G4B6N,CAAO,CAAPA,CAzanC,EAA8B,CAA9B,CAAsBD,EAAtB,CAyaYE,CAxaR9wC,EAAA,CAAa,gBAAb,CAEA,CAsaQ8wC,CAvaR9wC,EAAA,CAAa,4BAAb,CACA,CAsaQ8wC,CAtaR9wC,EAAA,CAAa,kDAAb,CAHJ,KAaA,IA4ZY8wC,CA5ZPvP,EAAL,CA4ZYuP,CAzYR9wC,EAAA,CAAa,kBAAb,CAnBJ,KAAiB,CACb,IAAIkiC,GAAU3B,CAAA,CA2ZNuQ,CA3ZmBp2C,EA/ybxB8R,EA+ybW,CA2ZNskC,EA1ZK9M,GAAA,CAAa9B,EAAb,CA0ZL4O,EAxZJvP,EAAJ,EAwZQuP,CAxrDZt+B,GAAA,CAwrDYs+B,CAxrDOlQ,EAAnB,CAiyC+BsB,EAjyC/B,CAA6C,CAAA,CAA7C,CAkyCQ,CAAKh3B,EAAA,CAsZD4lC,CAtZC,CAAL,GAsZIA,CArZIl2C,EACJ,EADcub,EAAA,CAqZd26B,CArZcl2C,EAAA,CACd,CAoZAk2C,CApZAvP,EAAA,CAAa,CAFjB,CAFJ,EAYIqL,EAAA,CA4YIkE,CA5YJ,CAAaF,EAAA,CAAO,IAAP,CAAc,GAA3B,CAhBS,CA6ZL,KACJ,MAAK,GAAL,CACI,GAAY,OAAZ,EAAIvU,CAAJ,CAAqB,CACb,CAAAzhC,EAAJ,EAAc,CAAAA,EAAAwN,MAAA,EACd,MAFiB,CAIrBy+B,EAAA,CAAAA,CAAA,CAjHL7D,CAiHK,CACA,MACJ,MAAK,GAAL,CA7mBZ,CAAA,CACI,OAyfOA,CAzfC,CAAO,CAAP,CAAR,EAEA,KAAK,MAAL,CACI,GAsfGA,CAtfC,CAAO,CAAP,CAAJ,CAAe,CACX,IAAItH,GAAQ,CAqfbsH,CArfc,CAAO,CAAP,CACb;GAAa,CAAb,EAAItH,EAAJ,EAA2B,CAA3B,EAAkBA,EAAlB,EAAyC,EAAzC,EAAgCA,EAAhC,EAAwD,EAAxD,EAA+CA,EAA/C,CAwmBIqV,CAvmBArV,EAAA,CAAaA,EADjB,KAEO,CAsmBHqV,CArmBA/wC,EAAA,CAAa,gBAAb,CAAgC07B,EAAhC,CACA,MAFG,CAJI,CA0mBPqV,CAjmBR/wC,EAAA,CAAa,gBAAb,CAimBQ+wC,CAjmBwBrV,EAAhC,CACA,MAEJ,MAAK,IAAL,CACI,IAAIjoB,EACcpjB,KAAAA,EAAlB,GAweG2yC,CAxeC,CAAO,CAAP,CAAJ,GAA6BvvB,EAA7B,CAAuC,CAwepCuvB,CAxeqC,CAAO,CAAP,CAAxC,CACA,QAueGA,CAveK,CAAO,CAAP,CAAR,EACI,KAAK,KAAL,CA0lBI+N,CAzlBAr2C,EAAAga,GAAA,CAAmCjB,EACnC,MACJ,MAAK,OAAL,CAulBIs9B,CAtlBAr2C,EAAA+Z,GAAA,CAAgChB,EAChC,MACJ,MAAK,MAAL,CAolBIs9B,CAnlBAr2C,EAAAia,GAAA,CAA+BlB,EAC/B,MACJ,SAilBIs9B,CAhlBA/wC,EAAA,CAAa,mBAAb,CACA,OAAA,CAZR,CAcgB3P,IAAAA,EAAhB,GAAIojB,EAAJ,EACIsC,EAAA,CA4kBIg7B,CA5kBJr2C,EAAA,CA4kBIq2C,EA1kBR/wC,EAAA,CAAa,YAAb,EA0kBQ+wC,CA1kBqBr2C,EAAAX,MAAAua,GAAA,CAAyB,SAAzB,CAAqC,UAAlE,EACA,MAEJ,MAAK,IAAL,CACsBjkB,IAAAA,EAAlB,GAkdG2yC,CAldC,CAAO,CAAP,CAAJ,GACSlsB,EAAA,CAqkBDi6B,CArkBCr2C,EAAA,CAAkB,CAidxBsoC,CAjdyB,CAAO,CAAP,CAAnB,CADT,EAskBQ+N,CApkBA/wC,EAAA,CAAa,2DAAb,CAFR,CAskBQ+wC,EAjkBR/wC,EAAA,CAAa,gBAAb,EAikBQ+wC,CAjkBwBr2C,EAzqd7BqZ,GAAAiD,QAAA,CAAuB,CAAvB,CAyqdH;AAzqd+B,KAyqd/B,EAA4D,IAA5D,CAikBQ+5B,CAjkB2Dr2C,EArsdhEkZ,GAqsdH,CAAyF,IAAzF,CACA,MAEJ,SACI,GAycGovB,CAzcC,CAAO,CAAP,CAAJ,CAAe,CA6jBP+N,CA5jBJ/wC,EAAA,CAAa,kBAAb,CAwcDgjC,CAxcmC,CAAO,CAAP,CAAlC,CACA,MAFW,CAMnB,KAAK,GAAL,CAujBY+N,CAtjBR/wC,EAAA,CAAa,mBAAb,CAKA,CAijBQ+wC,CArjBR/wC,EAAA,CAAa,mCAAb,CAIA,CAijBQ+wC,CApjBR/wC,EAAA,CAAa,8CAAb,CAGA,CAijBQ+wC,CAnjBR/wC,EAAA,CAAa,mDAAb,CAEA,CAijBQ+wC,CAljBR/wC,EAAA,CAAa,iDAAb,CACA,CAijBQ+wC,CAjjBR/wC,EAAA,CAAa,qCAAb,CA5DJ,CA8mBY,KACJ,MAAK,GAAL,CACI4sC,EAAA,CAAAA,CAAA,CAvHL5J,CAuHkB,CAAO,CAAP,CAAb,CAvHLA,CAuH6B,CAAO,CAAP,CAAxB,CACA,MACJ,MAAK,GAAL,CACI8D,EAAA,CAAAA,CAAA,CA1HL9D,CA0HuB,CAAO,CAAP,CAAlB,CA1HLA,CA0HkC,CAAO,CAAP,CAA7B,CAAwC,CAAxC,CACA,MACJ,MAAK,GAAL,CACI,GAAiB,KAAjB,EA7HLA,CA6HS,CAAO,CAAP,CAAJ,CAAwB,CACfkJ,EAAA,CAAAA,CAAA,CAAW7P,CAAA/uC,OAAA,CAAY,CAAZ,CAAX,CAAL,GACI80B,CADJ,CACa,CAAA,CADb,CAGA,MAJoB,CAMxB,GAAiB,KAAjB;AAnIL4gB,CAmIS,CAAO,CAAP,CAAJ,CAAwB,CACpB,CAAAhjC,EAAA,EAAc0E,EAAd,EAA+B,OAA/B,EAA2F,mBAA3F,CAAkG,CAAAhK,EAAAoe,GAAlG,CAAyL,WAAzL,CACA,EAAA9Y,EAAA,CAtwpBRzN,MAAA,CAAQA,MAAAsD,UAAAD,UAAR,CAAqC,EAswpB7B,CACA,MAHoB,CAKxBqoC,CAAA,CAAS,CAAA,CACT,MACJ,MAAK,GAAL,CACI,GA3IL+E,CA2IS,CAAO,CAAP,CAAJ,CAAe,CACX2J,EAAA,CAAAA,CAAA,CAAatQ,CAAA/uC,OAAA,CAAY,CAAZ,CAAb,CACA,MAFW,CArwC3B,IAAIjB,GAAI,WAAR,CACSuS,EAAT,KAASA,EAAT,GAAqBoyC,GAArB,CACI3kD,EAAA,EAAK,IAAL,CAAYu8C,EAAA,CAAQhqC,EAAR,CAAkB,CAAlB,CAAZ,CAAmCoyC,EAAA,CAAuBpyC,EAAvB,CAElC8c,GAAA,CAqwCOu1B,CArwCP,CAAL,GAA2B5kD,EAA3B,EAAgC,iDAAhC,CAqwCY4kD,EApwCZjxC,EAAA,CAAa3T,EAAb,CAqwCY,MASJ,SACI4xC,CAAA,CAAS,CAAA,CAvGb,CA0GIA,CAAJ,GACI,CAAAj+B,EAAA,CAAa,mBAAb,CAAmCq8B,CAAnC,CACA,CAAAja,CAAA,CAAS,CAAA,CAFb,CAnH+D,CA3BnE,CAmJF,MAAM72B,EAAN,CAAS,CACP,CAAAyU,EAAA,CAAa,WAAb,EAA4BzU,EAAAmgB,MAA5B,EAAuCngB,EAAAgJ,QAAvC,EACA,CAAA6tB,CAAA,CAAS,CAAA,CAFF,CAIX,MAAOA,EA1JX;AAyKA9L,QAAA,GAAU,CAAVA,CAAU,CAACD,CAAD,CAAQlV,CAAR,CACV,CACiB,IAAb,EAAIkV,CAAJ,GACI,CAAA7X,GADJ,CACqB49B,EAAA,CAAAA,CAAA,CAAkB/lB,CAAlB,CAAyBlV,CAAzB,CADrB,CAIA,KAAA,CAAOk7B,CAAP,CAAc,CAAA79B,GAAA/Q,MAAA,EAAd,CAAA,CACI,GAAI,CAACu8C,EAAA,CAAAA,CAAA,CAAe3N,CAAf,CAAL,CAA2B,MAAO,CAAA,CAEtC,OAAO,CAAA,CARX;AAyGA,IAAA2U,GAAyB,CACrB,IAAY,YADS,CAErB,QAAY,UAFS,CAGrB,QAAY,YAHS,CAIrB,EAAY,cAJS,CAKrB,QAAY,aALS,CAMrB,QAAY,aANS,CAOrB,QAAY,WAPS,CAQrB,EAAY,MARS,CASrB,KAAY,iBATS,CAUrB,UAAY,mBAVS,CAWrB,EAAY,aAXS,CAYrB,GAAY,wBAZS,CAarB,EAAY,UAbS,CAcrB,EAAY,WAdS,CAerB,MAAY,kBAfS,CAgBrB,EAAY,oBAhBS,CAiBrB,MAAY,eAjBS,CAkBrB,EAAY,aAlBS,CAmBrB,QAAY,OAnBS,CAoBrB,QAAY,YApBS,CAqBrB,MAAY,iBArBS,CAsBrB,IAAY,eAtBS,CAAzB,CAkCoDE,GAAQA,EAlC5D,CA+DA7I,GAAwB,sgBAAA,MAAA,CAAA,GAAA,CA/DxB;AAgGI8I,GAAQA,CAhGZ,CAiGIC,GAAQA,CAjGZ,CAkGIC,GAAQA,CAlGZ,CAmGIC,GAAQA,CAnGZ,CAoGIC,GAAQA,CApGZ,CAqGIC,GAAQA,CArGZ,CAsGIC,GAAQA,CAtGZ,CAuGIC,GAAQA,CAvGZ,CAwGIC,GAAQA,CAxGZ,CAyGIC,GAAQA,CAzGZ,CA4GAtH,GAAyB,+BAAA,MAAA,CAAA,GAAA,CA5GzB,CAsHA,GAAwB,EAtHxB,CAsHA3C,IAAwB,EAAA,CAr2lBRrjC,KAq2lBQ,CAAA,CACE,CAClB,EAjEIutC,GAgEc,CADF,CAAA,EAAA,CA12lBRvtC,KA02lBQ,CAAA,CAIG,CACnB,KA9EoDwtC,EA6EjC,CAEnB,KA/EoCC,EA6EjB,CAGnB,KAjFoBC,EA8ED,CAInB,KA1FoCC,EAsFjB,CAKnB,KA3FoDC,EAsFjC,CAMnB,KA5FIC,EAsFe,CAOnB,KA5FIC,EAqFe,CAQnB,KA9FoBC,EAsFD,CASnB,MAxFoDC,EA+EjC,CAUnB,MA3FoDC,EAiFjC,CAWnB,MA5FoBC,EAiFD,CAYnB,MApFoDC,EAwEjC,CAanB,MA3FIC,EA8Ee,CAcnB,MA9FIC,EAgFe,CAenB,MAhGoCC,EAiFjB,CAgBnB,MAvGIC,EAuFe,CAiBnB,MAxGoBC,EAuFD,CAkBnB,MA7FIC,EA2Ee,CAmBnB,MA9FoBC,EA2ED,CAoBnB,MA3FoDC,EAuEjC,CAqBnB,MA5FIC,EAuEe,CAsBnB,MA9FoCC,EAwEjB,CAuBnB,MA7FoCC,EAsEjB,CAwBnB,MA/GoCC,EAuFjB,CAyBnB,MAhHoDC,EAuFjC,CA0BnB,MAhGoDC,EAsEjC,CA2BnB,MAlGoBC,EAuED,CA4BnB,MAnGoCC,EAuEjB,CA6BnB,MAnGIC,EAsEe,CA8BnB,MApGoBC,EAsED,CAJH,CAAA,EAAA,CAz2lBRrvC,KAy2lBQ,CAAA,CAoCG,CACnB,KA7GIsvC,EA4Ge,CAEnB,KAhHoCC,EA8GjB,CAGnB,KA/GoBC,EA4GD,CAInB,KAlHoDC,EA8GjC,CAKnB,KAjHoCC,EA4GjB,CAMnB,KAnHIC,EA6Ge,CAOnB,KAnHoDC,EA4GjC,CAQnB,KArHoBC,EA6GD,CASnB,KAjIIC,EAwHe,CAUnB,KAlIoBC,EAwHD,CAWnB,KAnIoCC,EAwHjB,CAYnB,KAASnM,EAZU;AAanB,KA5HIoM,EA+Ge,CAcnB,KA9HoDC,EAgHjC,CAenB,KA9HoCC,EA+GjB,CAgBnB,KA/HoBC,EA+GD,CAiBnB,MAjIoBC,EAgHD,CAkBnB,MAlIoCC,EAgHjB,CAmBnB,MAxIoBC,EAqHD,CAoBnB,MAxIoDC,EAoHjC,CAqBnB,MAxIIC,EAmHe,CAsBnB,MA1IoBC,EAoHD,CAuBnB,MA1IoBC,EAmHD,CAwBnB,MA7IoDC,EAqHjC,CAyBnB,MA3IoDC,EAkHjC,CA0BnB,MA7IoDC,EAmHjC,CA2BnB,MA9IoCC,EAmHjB,CA4BnB,MA7IIC,EAiHe,CA6BnB,MAjJIC,EAoHe,CA8BnB,MAhJIC,EAkHe,CA+BnB,MAnJoCC,EAoHjB,CAgCnB,MAlJoBC,EAkHD,CAiCnB,MAnJoCC,EAkHjB,CAkCnB,MAvJoCC,EAqHjB,CAmCnB,MA/JIC,CA4He,CAoCnB,MA/JIC,CA2He,CAqCnB,MAjKoBC,CA4HD,CAsCnB,MAjKoBC,CA2HD,CAuCnB,MAnKoCC,CA4HjB,CAwCnB,MAnKoCC,CA2HjB,CAyCnB,MArKoDC,CA4HjC,CA0CnB,MArKoDC,CA2HjC,CA2CnB,MArKIC,CA0He,CA4CnB,MArKIC,EAyHe,CA6CnB,MAvKoBC,EA0HD,CA8CnB,MAvKoBC,EAyHD,CA+CnB,MAzKoCC,EA0HjB,CAgDnB,MAzKoCC,EAyHjB,CAiDnB,MA3KoDC,EA0HjC,CAkDnB,MA3KoDC,EAyHjC,CApCH,CAAA,EAAA,CAx2lBRtyC,KAw2lBQ,CAAA,CAwFG,CACnB,MAhKoCuyC,EA+JjB,CAEnB,MAjKoDC,EA+JjC,CAGnB,MAjKIC,EA8Je,CAInB,MAlKoBC,EA8JD,CAKnB,MAnKoCC,EA8JjB,CAMnB,MApKoDC,EA8JjC,CAOnB,MApKIC,EA6Je,CAQnB,MArKoBC,EA6JD,CAxFH,CAAA,EAAA,CAv2lBR9yC,KAu2lBQ,CAAA,CAkGG,CACnB,MAxKoC+yC,EAuKjB,CAEnB,MAzKoDC,EAuKjC,CAGnB,MAzKIC,EAsKe,CAInB,MA1KoBC,EAsKD,CAlGH,CAAA,EAAA,CAt2lBRlzC,KAs2lBQ,CAAA,CAwGC,CACjB,MA1KImzC,EAyKa,CAEjB,MA3KoBC,EAyKH,CAGjB,MA5KoCC,EAyKnB,CAIjB,MA7KoDC,EAyKnC;AAKjB,MA7KIC,EAwKa,CAMjB,MA9KoBC,EAwKH,CAOjB,MA/KoCC,EAwKnB,CAQjB,MAhLoDC,GAwKnC,CAxGD,CAAA,EAAxBrQ,CAtHA,CA0OAI,GAAwB,CAAC,EAAD,CAAK,GAAL,CAAU,GAAV,CAAe,GAAf,CA1OxB,CA2OAC,GAAwB,kBAAA,MAAA,CAAA,GAAA,CA3OxB,CA4OAC,GAAwB,6CAAA,MAAA,CAAA,GAAA,CA5OxB,CAkQAS,GAAuB,CAhBFuP,CACjB,EAhMQ/E,EA+LS+E,CAEjB,EA7LwBC,GA2LPD,CAGjB,EA9LwCE,GA2LvBF,CAIjB,EA/LwDG,GA2LvCH,CAKjB,EA/LQI,GA0LSJ,CAMjB,EAhMwBK,GA0LPL,CAgBE,CAPFM,CACjB,EAzMwDtF,EAwMvCsF,CAEjB,EArMwCryC,GAmMvBqyC,CAGjB,EAtMwDC,GAmMvCD,CAIjB,GAtMQE,GAkMSF,CAOE,CAlQvB,CAsQA/R,GAA8C,GAtQ9C,CAwQAI,GAAuB,WAKvBv5B,GAAA,CArSAZ,QAAW,EACX,CAEI,IADA,IAAIisC,EAAQr8C,CAAA,CAA6BsQ,QAA7B,CAAuCxQ,CAAvC,CAAuD,UAAvD,CAAZ,CACSw8C,EAAO,CAAhB,CAAmBA,CAAnB,CAA0BD,CAAAlpD,OAA1B,CAAwCmpD,CAAA,EAAxC,CAAgD,CAC5C,IAAIC,EAAOF,CAAA,CAAMC,CAAN,CAAX,CACIld,EAAWz+B,EAAA,CAA4B47C,CAA5B,CACXn+C,EAAAA,CAAM,IAAI4lC,EAAJ,CAAkB5E,CAAlB,CACV1uB,GAAA,CAAgCtS,CAAhC,CAAqCm+C,CAArC,CAJ4C,CAFpD,CAoSA,CA2FAv/C,SAdE0yC,GAcS,CAACtxC,CAAD,CACX,CACI,IAAAA,EAAA,CAAWA,CADf;AA4BAgS,QAAA,GAAI,CAAJA,CAAI,CAAC7Y,CAAD,CAAWyxC,CAAX,CAAqBxzC,CAArB,CACJ,CACI,CAAA+B,GAAA,CAAgBA,CAChB,EAAAyxC,EAAA,CAAgBh2C,CAACg2C,CAADh2C,EAAa,EAAbA,aAAA,EAChB,EAAAwC,KAAA,CAAYA,CAEZ,EAAAgnD,EAAA,CAAY,CACZ,EAAAC,EAAA,CAAa,EAOb,EAAAC,EAAA,CAAe,EAOf,EAAAC,EAAA,CAAe,EA6Bf,EAAAC,EAAA,CAAiB,EAKjB,EAAAC,EAAA,CAAkB,EAKlB,EAAAC,EAAA,CAAiB,EAQjB,EAAAld,EAAA,CAAkB,EAKlB,EAAAmP,EAAA,CAAc,EAUd,EAAAgO,GAAA,CAAe,EAOf,EAAAC,EAAA,CAAiB,EAEjB,EAAAC,GAAA,CAAa,CACb,EAAAC,EAAA,CAAc,CACd,EAAAC,GAAA,CAAgB,CAKhB,EAAAC,EAAA,CAAiB,CAAA7lD,GAAjB,EAAkC,CAKlC,EAAA8lD,GAAA,CAAuB,EAKvB,EAAAC,EAAA,CAAmB,EAEnB,EAAAC,EAAA,CAAiB,IACjB,EAAAC,EAAA,CAAiB,CACjB,EAAAC,EAAA,CAAiB,IACjB,EAAAC,EAAA,CAAmB,CAAAC,EAAnB,CAAuC,EAWvC,EAAAC,GAAA,CAAc,2FAEd,EAAAC,EAAA,CAAiB,IAQjB,EAAAC,EAAA,CAAe,IAKf,EAAAC,EAAA,CAAc,EAEd,EAAA/O,EAAA,CAAiB,IA7IrB;AAgKAW,QAAA,GAAa,CAAbA,CAAa,CAACt6C,CAAD,CAAOkC,CAAP,CAAiByxC,CAAjB,CAA2BxzC,CAA3B,CACb,CACQwzC,CAAJ,EAAyC,CAAzC,EAAgBA,CAAAn4C,QAAA,CAAiB,GAAjB,CAAhB,EA0BAuf,EAAA,CAzBI4tC,CAyBJ,CAzB8BzmD,CAyB9B,CAzBwCyxC,CAyBxC,CAzBkDxzC,CAyBlD,CAOA,CAhCIwoD,CA2BJrB,EAKA,CAhCwBtnD,CA2BTiD,MAAA,CAAY,SAAZ,CAKf,CAhCI0lD,CA4BJtB,EAAAnkD,KAAA,CA5BIylD,CA4BcrB,EAAAxpD,OAAlB,CAIA,CAFA8qD,EAAA,CA9BID,CA8BJ,CAEA,CAhCIA,CAgCAxoD,KAAJ,EAhCIwoD,CAgCWxoD,KAAA,CAhCXwoD,CAgCqBd,EAAV,CAjCf,GAKA9sC,EAAA,CAAAA,CAAA,CAAU7Y,CAAV,CAAoByxC,CAApB,CAA8BxzC,CAA9B,CAIA,CAFA,CAAAinD,EAEA,CAFapnD,CAAAiD,MAAA,CAAW,GAAX,CAEb,CAAA4lD,EAAA,CAAAA,CAAA,CATA,CADJ;AA4CAA,QAAA,GAAgB,CAAhBA,CAAgB,CAChB,CACI,GAAI,CAAA1B,EAAJ,EAAiB,CAAAC,EAAAtpD,OAAjB,CACI8qD,EAAA,CAAAA,CAAA,CACA,CAAI,CAAAzoD,KAAJ,EAAe,CAAAA,KAAA,CAAU,CAAA0nD,EAAV,CAFnB,KAAA,CAOA,IAAI7nD,EAAO,CAAAonD,EAAA,CAAW,CAAAD,EAAX,CAEX,EAAA74C,EAAA,CAAa,UAAb,CAA0B81B,EAAA,CAAgBpkC,CAAhB,CAA1B,CAKwB,EAAxB,CAAIA,CAAAxE,QAAA,CAAa,GAAb,CAAJ,EAEoC,CAFpC,EAEQ,UAAAA,QAAA,CADOwE,CAAAlE,MAAA,CAAY,EAAZ,CAAAs3C,YAAA0V,EACP,CAFR,GAEuC9oD,CAFvC,EAE+C,MAF/C,CAKA2kC,GAAA,CAAgB3kC,CAAhB,CAAsB,IAAtB,CAA4B,CAAA,CAA5B,CAAkC+oD,QAAuB,CAAC3O,CAAD,CAAQ4O,CAAR,CAAmBhoD,CAAnB,CAA+B,CACpF,GAAIA,CAAJ,CAdUovC,CAeFjwC,KAAJ,EAfMiwC,CAeYjwC,KAAA,CAAaa,CAAb,CAAyBo5C,CAAzB,CADtB,KAAA,CAIIjwC,CAAAA,CAAQ6+C,CACZ,IAAIC,EAAA,CAAa7O,CAAb,CAAoB,OAApB,CAAJ,CAAkC,CAI9BjwC,CAAA,CAAQ,EAJsB,KAK1BnO,CACJ,KADWwQ,CACX,CADgB,0BAChB,CAAOxQ,CAAP,CAAewQ,CAAA7H,KAAA,CAAQqkD,CAAR,CAAf,CAAA,CACQruD,CAEJ,CAFQqB,CAAA,CAAM,CAAN,CAER,CADsB,CACtB,EADIrB,CAAAa,QAAA,CAAU,MAAV,CACJ,GADyBb,CACzB,CAD6BA,CAAAc,QAAA,CAAU,QAAV,CAAoB,MAApB,CAAAA,QAAA,CAAiC,QAAjC,CAA2C,MAA3C,CAAAA,QAAA,CAAwD,SAAxD,CAAmE,MAAnE,CAC7B,EAAA0O,CAAA,EAASxP,CAGb,EADAqB,CACA,CADQmO,CAAAnO,MAAA,CAAY,WAAZ,CACR,GAAWktD,EAAA,CA/BL9Y,CA+BK,CAAgB,4BAAhB,CAA+Cp0C,CAAA,CAAM,CAAN,CAA/C;AAA0D,GAA1D,CAZmB,CAsB9BsrD,CAAAA,CAAUn9C,CAAAlH,MAAA,CAAY,SAAZ,CACd,IAAIqkD,CAAAxpD,OAAJ,CAAqB,CAArB,CAEI,IADAnD,CACA,CADI2sD,CAAAzb,IAAA,EACJ,CACIqd,EAAA,CA7CE9Y,CA6CF,CAAgB,mBAAhB,CAAsCz1C,CAAtC,CAA0C,GAA1C,CAEA,CADA2sD,CAAApkD,KAAA,CAAavI,CAAb,CACA,CAAA2sD,CAAApkD,KAAA,CAAa,EAAb,CAHJ,CAFJ,IAQIgmD,GAAA,CAlDM9Y,CAkDN,CAAgB,8BAAhB,CAAiDkX,CAAAxpD,OAAjD,CAAkE,GAAlE,CAlDMsyC,EAqDVkX,EAAA,CArDUlX,CAqDQkX,EAAA71C,OAAA,CAAuB61C,CAAvB,CArDRlX,EAsDViX,EAAA,CAtDUjX,CAsDM+W,EAAhB,CAAA,CAAiCG,CAAAxpD,OAAjC,EAAmD,CAtDzCsyC,EAuDV+W,EAAA,EAEAjiD,WAAA,CAAW,QAAQ,EAAG,CAClB2jD,EAAA,CA1DMzY,CA0DN,CADkB,CAAtB,CAEG,CAFH,CA3CA,CADoF,CAAxF,CAnBA,CADJ;AAwGAwY,QAAA,GAAc,CAAdA,CAAc,CACd,CAMI,GAAkC,CAAlC,EAAI,CAAAjV,EAAAn4C,QAAA,CAAsB,GAAtB,CAAJ,CACI,CAAA8S,EAAA,CAAa,CAAAg5C,EAAA7Z,KAAA,CAAkB,EAAlB,CAAb,CADJ,KAAA,CAKA,IAAIh0C,EAAI20C,EAAA,CAAA,CAAArlC,EAAA,CAKRogD,GAAA,CAAAA,CAAA,CAAe,KAAf,CAAsB,CAAtB,CACAA,GAAA,CAAAA,CAAA,CAAe,IAAf,CAAsB,CAAtB,CAEA,IAAI,CACA,IAAK,IAAIlvD,EAAI,CAAb,CAAgBA,CAAhB,CAAoB,CAAAqtD,EAAAxpD,OAApB,CAAyC7D,CAAzC,EAA8C,CAA9C,CAAiD,CAE7C,CAAA2tD,GAAA,EAKkC,EAAlC,EAAI,CAAAjU,EAAAn4C,QAAA,CAAsB,GAAtB,CAAJ,EACI,CAAA8S,EAAA,CAAa86C,EAAA,CAAAA,CAAA,CAAb,CAAiC,IAAjC,CAAwC,CAAA9B,EAAA,CAAartD,CAAb,CAAxC,CASJ,IAAI,CAACovD,EAAA,CAAAA,CAAA,CAAe,CAAA/B,EAAA,CAAartD,CAAb,CAAf,CAAiC,MAAjC,CAAL,CAA+C,KAM/C,IAAuB,IAAvB,GAAI,CAAA0/C,EAAJ,CAA6B,KAvBgB,CA0B7C,CAAAwO,EAAJ,EACI,CAAAv/C,MAAA,CAAW,YAAX,CAAyB,CAAA2+C,EAAA,CAAe,CAAAa,EAAf,CAAAR,GAAzB,CAGA,EAAAK,EAAAnqD,OAAJ,EACI,CAAA8K,MAAA,CAAW,YAAX,CAAyB,CAAAq/C,EAAA,CAAiB,CAAjB,CAAAL,GAAzB,CAMJ0B,GAAA,CAAAA,CAAA,CAKAC,GAAA,CAAAA,CAAA,CAKA,EAAA7B,GAAA3N,QAAA,CAAqByP,QAAqB,CAACzlD,CAAD,CAASgkD,CAAT,CAAoB,CACtD1rD,CAAAA,CAAQixC,EAAA,CAnEN8C,CAmEM,CAAwBrsC,CAAxB,CAAgCpF,IAAAA,EAAhC,CAA2CopD,CAA3C,CAnEN3X,CAmE4DuX,EAAA,CAAkBI,CAAlB,CAAtD,CACEppD,KAAAA,EAAd,GAAItC,CAAJ,GACAA,CACA,EAtEM+zC,CAqEGsJ,EAAA,CAAeqO,CAAf,CACT,CAtEM3X,CAsENsJ,EAAA,CAAeqO,CAAf,CAAA,CAA4B9c,EAAA,CAtEtBmF,CAsEsB,CAAiB/zC,CAAjB,CAAwB0rD,CAAxB,CAF5B,CAF0D,CAA9D,CAhDA,CAuDF,MAAMpnD,CAAN,CAAW,CACT,CAAA2N,EAAA,CAAa3N,CAAAkC,QAAb,CACA,CAAA,CAAAglD,EAAA,CAAe,EAFN,CAKoB,CAAjC,CAAI,CAAAlU,EAAAn4C,QAAA,CAAsB,GAAtB,CAAJ,GAAoC,CAAAuN,EAj5JpCwhC,EAi5JA,CAA8D9wC,CAA9D,CAzEA,CANJ;AA8FA4vD,QAAA,GAAS,CAATA,CAAS,CAACjS,CAAD,CAAQ5yC,CAAR,CAAgBilD,CAAhB,CAAyBC,CAAzB,CACT,CAAA,IACQzvD,CAEgB,KAApB,EAAI,CAAAwuD,EAAJ,GACIrR,CADJ,CACYuS,EAAA,CAAAA,CAAA,CAAcvS,CAAd,CADZ,CAOA,KAHA,IAAIwS,EAAS,CAAA,CAAb,CACY1B,EAAY,EAExB,CAAO0B,CAAP,CAAA,CAAe,CACX,IAAAC,EAAYzS,CAAAp7C,MAAA,CAAY,CAAAusD,GAAZ,CACZ,IAAI,CAACsB,CAAL,EAAkBA,CAAA,CAAU,CAAV,CAAlB,EAA8D,GAA9D,EAAkCA,CAAA,CAAU,CAAV,CAAA/tD,OAAA,CAAmB,CAAnB,CAAlC,CAEI,MADA,EAAA8M,MAAA,CAAW,wBAAX,CAAsCwuC,CAAtC,CAA8C,GAA9C,CACO,CAAA,CAAA,CAEXwS,EAAA,CAAS,CAAA,CACT1B,EAAA,CAAY2B,CAAA,CAAU,CAAV,CAAAzW,YAAA,EAUZ,IAAI8U,CAAJ,EAAiB4B,EAAjB,EAA0C5B,CAA1C,EAAuD6B,EAAvD,CACIvlD,CAAA,CAAS,IAGb,IAAIA,CAAJ,CAAY,CACR,IAASwlD,CAAT,CAAiB,CAAjB,CAAoBA,CAApB,CAA4BxlD,CAAA1G,OAA5B,CAA2CksD,CAAA,EAA3C,CAAoD,CAChD,IAAI3lD,EAAQG,CAAA,CAAOwlD,CAAP,CAAZ,CAEIC,EAAW,CAAA1C,EAAA,CAAe,CAAAa,EAAf,CACf,IAAI,EAAA6B,CAAA,EAA8C,CAA9C,EAAYA,CAAAzlD,GAAAhJ,QAAA,CAAwB6I,CAAxB,CAAZ,CAAJ,CAAA,CAEI0uC,CAAAA,CAAW0W,CAAA,CAAQO,CAAR,CAAXjX,EAA6B2W,CAAA,CAAUM,CAAV,CAA7BjX,EAAiD,EAGrD,KAFA,IAAImX,EAAU,CAAd,CACI7d,EAAS+K,CAAAt5C,OAATuuC,CAAwBwd,CAAA,CAAU,CAAV,CAAA/rD,OAC5B,CAAOosD,CAAP,CAAiB7d,CAAjB,CAAA,CAAyB,CACrB,IAAI8d,EAAS/S,CAAA57C,QAAA,CAAc6I,CAAd,CAAqB6lD,CAArB,CACb,IAAa,CAAb,CAAIC,CAAJ,CAAgB,KAChBD,EAAA,CAAUC,CAAV,CAAmB,CACnB,KAAIC,EAAYD,CAAZC,CAAqB/lD,CAAAvG,OAAzB,CACIusD,GAAQ,EADZ,CACgBC,GAAS,EACnBH,EAAN,EAqwBPnuD,CArwB0CquD,EAqwB1CruD,CArwBkDo7C,CAAA,CAAM+S,CAAN,CAAe,CAAf,CAqwBlDnuD,OAAA,CAAS,cAAT,CArwBO,EAAmE,EAAAouD,CAAA,EAAahT,CAAAt5C,OAAb,CAAnE,EAqwBP9B,CArwB0HsuD,EAqwB1HtuD,CArwBmIo7C,CAAA,CAAMgT,CAAN,CAqwBnIpuD,OAAA,CAAS,cAAT,CArwBO;CAIiB,GAIb,EAJIquD,EAIJ,EAJkBF,CAAA,EAIlB,CAHc,GAGd,EAHIG,EAGJ,EAHmBF,CAAA,EAGnB,CAFAhT,CAEA,CAFQA,CAAAx7C,OAAA,CAAa,CAAb,CAAgBuuD,CAAhB,CAER,CAFkCpX,CAElC,CAF6CqE,CAAAx7C,OAAA,CAAawuD,CAAb,CAE7C,CADAF,CACA,CADUC,CACV,CADmBpX,CAAAj1C,OACnB,CAAA8rD,CAAA,CAAS,CAAA,CARb,CANqB,CALzB,CAJgD,CA2BpDplD,CAAA,CAAS,IA5BD,CA8BZ,GAAI,CAAA2jD,EAAJ,GAC0B,CAalBA,EAbA,CAAAA,EAaAA,GAZAluD,CACA,CADIm9C,CAAA57C,QAAA,CAAc,CAAA6sD,EAAd,CACJ,CAAS,CAAT,EAAIpuD,CAAJ,EACI,CAAAkuD,EAAA,EACA,CAAA/Q,CAAA,CAAQA,CAAAx7C,OAAA,CAAa3B,CAAb,CAAe,CAAf,CAFZ,EAII,CAAA2O,MAAA,CAAW,WAAX,CAAyB,CAAAs/C,EAAzB,CAA0C,kBAA1C,CAA+D9Q,CAA/D,CAAuE,GAAvE,CAOJ+Q,EAJiB,CAIjBA,CAJA,CAAAA,EAIAA,GAHA/Q,CACA,CADQmT,EAAA,CAAAA,CAAA,CAAiBnT,CAAjB,CACR,CAAAwS,CAAA,CAAS,CAAA,CAETzB,EAAA,CAAAA,EAdR,EAcwB,MAAO,CAAA,CAjEpB,CAqEftM,CAAA,CAASgO,CAAA,CAAU,CAAV,CACTW,EAAA,CAAaX,CAAA,CAAU,CAAV,CACbtS,EAAA,CAAYsS,CAAA,CAAU,CAAV,CAAAzrD,KAAA,EACZqsD,EAAA,CAAaZ,CAAA,CAAU,CAAV,CAAb,CAA4BA,CAAA,CAAU,CAAV,CAExBhO,EAAJ,GACIA,CACA,CADSA,CAAA//C,MAAA,CAAa,CAAb,CAAiB,EAAjB,CACT,CAAAqtD,EAAA,CAAAA,CAAA,CAAetN,CAAf,CAAuB,CAAAkM,EAAvB,CAAuC2C,EAAvC,CAFJ,CAKA,KAAIC,CACAzC,EAAJ,GAAkByC,CAAlB,CAA4BpT,CAAAv7C,MAAA,CAAgB,cAAhB,CAA5B,IACQ4uD,CAWJ,CAXY,CAWZ,CAVA/O,CAUA,CAVSqM,CAUT,CATAA,CASA,CATYyC,CAAA,CAAQ,CAAR,CASZ,CARApT,CAQA,CARYoT,CAAA,CAAQ,CAAR,CAQZ,CAPiB,UAAjB,EAAIzC,CAAJ,CACI0C,CADJ,EA62CIC,CA72CJ,CAGsB,OAHtB,EAGS3C,CAHT,GAII0C,CAJJ,EAIaE,EAJb,CAOA,CADA3B,EAAA,CAAAA,CAAA,CAAetN,CAAf,CAAuBtE,CAAvB,CAAkCqT,CAAlC,CACA,CAAA1C,CAAA,CAAY3Q,CAAZ,CAAwB,EAZ5B,CAeA,IAAI,CAAC2Q,CAAL,EAAkB,CAAC3Q,CAAnB,CAA8B,MAAO,CAAA,CAErC,EAAA2Q,EAAA,CAAiBA,CAQjB,IADI6C,CACJ,CADeC,EAAA,CAAAA,CAAA,CAAgBzT,CAAhB,CACf,CACIA,CACA,CADYA,CAAA97C,QAAA,CAAkBsvD,CAAlB,CAA4BE,EAAA,CAAAA,CAAA,CAAcC,EAAd,CAAyCF,EAAA,CAAAA,CAAA,CAAgBP,CAAhB,CAAzC,CAA5B,CACZ;AAAKD,CAAL,GAAiBA,CAAjB,CAA8B,IAA9B,CAOJ,KAAA,CAAOvX,CAAP,CAAiBkY,EAAA,CAAAA,CAAA,CAAiB5T,CAAjB,CAAjB,CAAA,CACIA,CAAA,CAAYA,CAAA97C,QAAA,CAAkBw3C,CAAlB,CAA2BA,CAAAn3C,MAAA,CAAc,CAAd,CAAkB,EAAlB,CAA3B,CAGhB,IAAI,CAACsvD,EAAA,CAAAA,CAAA,CAAgBlD,CAAhB,CAA2B3Q,CAA3B,CAAL,CAEI,OAAQ2Q,CAAR,EACA,KAAKmD,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACI5B,EAAA,CAAAA,CAAA,CAAcc,CAAd,CACA,MAEJ,MAAKe,EAAL,CACkBjU,CAAAA,CAAAA,CA88BlBx8C,EAAAA,CAAIuyC,EAAA,CA98BAme,CA88BA,CAAqBlU,CAArB,CACE54C,KAAAA,EAAV,GAAI5D,CAAJ,EAA4B,CAA5B,EAAuBA,CAAvB,EAAsC,MAAtC,EAAiCA,CAAjC,CA/8BQ0wD,CAg9BJ1D,EADJ,EACsBhtD,CADtB,CA/8BQ0wD,CAk9BJ7iD,MAAA,CAAW,iCAAX,CAA+C2uC,CAA/C,CAA2D,GAA3D,CAj9BI,MAEJ,MAAKmU,EAAL,CACiBnU,CAAAA,CAAAA,CA69BNoU,EAAAA,CAAX1hB,CAAW0hB,CAAH,CAEZ,KAF2BC,CAE3B,CAF4C,EAE5C,CAAO/U,CAAP,CAAkBgV,EAAA,CA/9BVC,CA+9BU,CAAmBvU,CAAnB,CAAlB,CAAA,CAAiD,CAC7CA,CAAA,CAAYA,CAAA37C,OAAA,CAAiBi7C,CAAA/4C,OAAjB,CAAAM,KAAA,EACR2F,EAAAA,CAAS8yC,CAEb,IADI76C,CACJ,CADY66C,CAAA76C,MAAA,CAAe,mBAAf,CACZ,CACQA,CAAA,CAAM,CAAN,CACJ,GADciuC,CACd,CADsBqD,EAAA,CAp+BtBwe,CAo+BsB,CAAqB,IAArB,CAA4B9vD,CAAA,CAAM,CAAN,CAA5B,CACtB,EAAA+H,CAAA,CAAS/H,CAAA,CAAM,CAAN,CAEb,IAAKiuC,CAAL,CAAA,CAQInvC,CAAAA,CAAIiJ,CAAA,CAAQupC,EAAA,CA/+BZwe,CA++BY,CAAqB/nD,CAArB,CAAR,CAAuC,CAC/C,IAAUpF,IAAAA,EAAV,GAAI7D,CAAJ,EAA+B,CAA/B,CAAuBmvC,CAAvB,EAA4C,EAA5C,CAAoCA,CAApC,CAAgD,CAh/B5C6hB,CAi/BAljD,MAAA,CAAW,2BAAX,CAAyCiuC,CAAzC,CACA,MAF4C,CAIhD/7C,CAAA,CAAImwC,CAAA,CAp/BA6gB,CAo/BA/iD,EAAA,CAAkBjO,CAAlB,CAAqBmvC,CAArB,CAA4B,CAAA,CAA5B,CACA2hB,EAAJ,CAAqB3hB,CAArB,GACI8hB,EAAA,CAt/BAD,CAs/BA,CAAaH,CAAb,CAEA,CADAA,CACA,CADS,CACT,CAAAC,CAAA,CAAiB,EAHrB,CAKAD,EAAA;AAAU7wD,CAAV,CAAcoB,IAAAC,IAAA,CAAS,CAAT,CAAYyvD,CAAZ,CAA6B3hB,CAA7B,CACd2hB,EAAA,EAAkB3hB,CApBlB,CAAA,IAKI8hB,GAAA,CA5+BAD,CA4+BA,CAAa,CAAb,CAbyC,CA8B5B,EAArB,CAAIF,CAAJ,EACIG,EAAA,CA9/BID,CA8/BJ,CAAaH,CAAb,CA7/BI,MAEJ,MAAKK,EAAL,CAygCJ,CAxgCoBzU,CAwgCpB,CAxgCoBA,CAwgCpB,GAxgCQ0U,CA2gCJtS,EACA,CADiBrM,EAAA,CA3gCb2e,CA2gCa,CAAqB1U,CAArB,CACjB,CAAuB54C,IAAAA,EAAvB,GA5gCIstD,CA4gCAtS,EAAJ,EA5gCIsS,CA6gCArjD,MAAA,CAAW,+BAAX,CAA6C2uC,CAA7C,CAAyD,GAAzD,CALR,EAxgCQ0U,CAygCJtS,EADJ,CAxgCQsS,CAygCa/pD,GAxgCb,MAEJ,MAAKgqD,EAAL,CACIC,EAAA,CAAAA,CAAA,CAAa5U,CAAb,CACA,MAEJ,MAAK6U,EAAL,CACI9C,EAAA,CAAAA,CAAA,CACA,MAEJ,MAAK+C,EAAL,CACIC,CAghCRvE,EAAA,CAAiBza,EAAA,CAhhCTgf,CAghCS,CAhhCQ/U,CAghCR,CAAjB,EAAoD,CA/gC5C,MAEJ,MAAKgV,EAAL,CACIhD,EAAA,CAAAA,CAAA,CACA,MAEJ,MAAKiD,EAAL,CAyhCJL,EAAA,CAxhCQM,CAwhCR,CAxhCoBlV,CAwhCP97C,QAAA,CAAkB,GAAlB,CAAuB,IAAvB,CAAb,CAvhCQ,MAEJ,MAAKixD,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKvD,EAAL,CACA,KAAKC,EAAL,CACA,KAAKuD,EAAL,CACA,KAAKC,EAAL,CACItC,EAAA,CAAAA,CAAA,CAAc/C,CAAd,CAAyBuC,CAAzB,CACA,MAEJ,MAAK+C,EAAL,CAwiCA/D,CAAAA,CAAUgE,EAAA,CAviCNC,CAuiCM,CAviCUnW,CAuiCV,CACd,KAASt9C,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoBwvD,CAAA3rD,OAApB,CAAoC7D,CAAA,EAApC,CAnmMA,OA2jKQyzD,CAyiCJ3kD,EApmMGwhC,EAAA,CAomMkBkf,CAAA1b,CAAQ9zC,CAAR8zC,CApmMlB,CAqmMH,CAAA,OA1iCI2f,CA0iCGlG,EAAA,CAAgBiC,CAAA,CAAQxvD,CAAR,CAAhB,CAziCH;KAEJ,MAAK0zD,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACA,KAAKC,EAAL,CACI,KAEJ,SACI/B,EAAA,CAAAA,CAAA,CAAajE,CAAb,CAAwBsC,CAAxB,CAAoCjT,CAApC,CAzEJ,CA6EJ,MAAO,CAAA,CA/MX;AA0PA6T,QAAA,GAAU,CAAVA,CAAU,CAACpjD,CAAD,CAAOuvC,CAAP,CACV,CACI,IAAI4W,EAAQ,CAAA5G,EAAA,CAAev/C,CAAf,CACZ,IAAI,CAACmmD,CAAL,CAAY,MAAO,CAAA,CAEnB,IAAiB,IAAjB,EAAI5W,CAAJ,CAAuB,CAKnB,GAAI4W,CAAAC,GAAJ,EAAsBC,EAAtB,CAA8C,CAE1C,IAAItG,EAAY,CAAAA,EAChBuG,EAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CACA,IAAI49C,CAAJ,CAAgB,CAAAA,EAAhB,CAAgC,CAK5B,GAAI,CAACxQ,CAAL,CAAgB,MAAO,CAAA,CAEvBgX,GAAA,CAAAA,CAAA,CACAD,EAAA,CAAAA,CAAA,CAAe/W,CAAf,CACIx8C,EAAAA,CAAI,CAAA2+C,EAAA,CAAY,CAAZ,CACR,KAAI8U,EAAS,CAAA9G,GAAA,CAAa,CAAb,CACb+G,GAAA,CAAAA,CAAA,CACA,IAAU9vD,IAAAA,EAAV,GAAI5D,CAAJ,CAeI,MAdA,EAAA2+C,EAAA,CAAYqO,CAAZ,CAcO,EAdoBhtD,CAcpB,CAdyB,SAczB,CARP,CAAA2+C,EAAA,CAAYqO,CAAZ,CAQO,EARoBhtD,CAQpB,CAlynBX6X,OAkynBW,CAPH47C,CAOG,GAHC,CAAA9G,GAAA,CAAaK,CAAb,CAGD,CANE,CAAAL,GAAA,CAAaK,CAAb,CAAL,CAGI,CAAAL,GAAA,CAAaK,CAAb,CAHJ,EAG+B,GAH/B,CAGqCyG,CAHrC,EAC8BA,CAK3B,EAAA,CAAA,CA3BiB,CAkChC,CAAA5lD,MAAA,CAAW,SAAX,CAAuBZ,CAAvB,CAA8B,KAA9B,CAAsCuvC,CAAtC,CAAkD,UAAlD,CACA,OAAO,CAAA,CAvCmC,CAyC1CmX,CAAAA,CAAY,CAAAlG,EAChB,EAAAA,EAAA,CAAiB2F,CACjBA,EAAA1E,GAAA,CAAgBgE,EAAA,CAAAA,CAAA,CAAelW,CAAf,CAA0B,CAAA,CAA1B,CAChB+W,EAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CAA4BgkD,CAAA3pD,GAA5B,CAA0C2pD,CAAA1E,GAA1C,CAAyD0E,CAAAzE,GAAzD,CAQA,EAAAlB,EAAA,CAAiBkG,CACjB,OAAO,CAAA,CA1DY,CA6DvB,GAAe,GAAf,EAAI1mD,CAAA,CAAK,CAAL,CAAJ,CAAoB,MAAO,CAAA,CAI3B,QAFgBA,CAAApM,OAAAssD,CAAY,CAAZA,CAEhB,EACA,KAAK4E,EAAL,CACA,KAAKD,EAAL,CACA,KAAKQ,EAAL,CACSc,CAAAC,GAAL,EACIE,CAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CAEJ,MAEJ,MAAK4iD,EAAL,CACyB,CAArB,CAAIoB,CAAAC,GAAJ,EACIE,CAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CAEJ,MAEJ,MAAK6iD,EAAL,CAC0B,CAAtB;AAAImB,CAAAC,GAAJ,EACIE,CAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CAEJ,MAEJ,MAAK+iD,EAAL,CACyB,CAArB,CAAIiB,CAAAC,GAAJ,EACIE,CAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CAEJ,MAEJ,MAAKgjD,EAAL,CAC0B,CAAtB,EAAIgB,CAAAC,GAAJ,EACIE,CAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CAEJ,MAEJ,MAAKwiD,EAAL,CACA,KAAKS,EAAL,CACA,KAAKR,EAAL,CACA,KAAKK,EAAL,CACQkB,CAAAC,GAAJ,EACIE,CAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CAEJ,MAEJ,MAAK2/C,EAAL,CACA,KAAKC,EAAL,CACI,IAAS9vD,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoBk0D,CAAA1E,GAAA3rD,OAApB,CAA0C7D,CAAA,EAA1C,CACIq0D,CAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CAA4BgkD,CAAA3pD,GAA5B,CAA0C,CAAC2pD,CAAA1E,GAAA,CAAcxvD,CAAd,CAAD,CAA1C,CAA8D,EAA9D,CAEJ,MAEJ,MAAKszD,EAAL,CACI,IAAA,CAA0B,CAA1B,CAAOY,CAAAC,GAAA,EAAP,CAAA,CACIE,CAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CAEJ,MAEJ,SAC4BA,CAzJ5B,CAyJ4BgkD,CAAAhkD,GAzJ5B,CAFAokD,EAAA,CA2JII,CA3JJ,CA2JsB3mD,CA3JtB,CAEA,CADAsmD,CAAA,CA0JIK,CA1JJ,CAAexkD,CAAf,CACA,CAAAskD,EAAA,CAyJIE,CAzJJ,CAiGA,CA2DA,MAAO,CAAA,CAhIX,CA4IAL,QAAA,EAAS,CAATA,CAAS,CAACnkD,CAAD,CAAQ3F,CAAR,CAAgBilD,CAAhB,CAAyBC,CAAzB,CACT,CASQpC,CAAAA,CAAUn9C,CAAAlH,MAAA,CAAY,OAAZ,CACd,KAAK,IAAI2rD,EAAQ,CAAjB,CAAoBA,CAApB,CAA4BtH,CAAAxpD,OAA5B,EAESurD,EAAA,CAAAA,CAAA,CADO/B,CAAA,CAAQsH,CAAR,CACP,CADwB,MACxB,CAAsBpqD,CAAtB,CAA8BilD,CAA9B,CAAuCC,CAAvC,CAFT,CAA4CkF,CAAA,EAA5C,EAVJ;AAsBAL,QAAA,GAAS,CAATA,CAAS,CAACvmD,CAAD,CACT,CACI,CAAAigD,EAAA/kD,KAAA,CAAsB,CAClB8E,KAAAA,CADkB,CAElB0xC,EAAQ,CAAAA,EAFU,CAGlBgO,GAAS,CAAAA,GAHS,CAIlBK,EAAW,CAAAA,EAJO,CAKlBC,GAAgB,CAAAA,GALE,CAMlBJ,GAAO,CAAAA,GANW,CAAtB,CAQA,EAAAlO,EAAA,CAAc,EACd,EAAAgO,GAAA,CAAe,EACW,EAA1B,CAAI,CAAAM,GAAJ,GAA6B,CAAAA,GAA7B,CAAmD,CAAAD,EAAnD,CACA,EAAAA,EAAA,CAAiB,CAZrB,CAoBA0G,QAAA,GAAQ,CAARA,CAAQ,CACR,CACI,GAAK,CAAAxG,EAAAnqD,OAAL,CAAA,CAIA,IAAIkK,EAAO,CAAAigD,EAAA,CAAiB,CAAAA,EAAAnqD,OAAjB,CAA2C,CAA3C,CAAAkK,KACPA,EAAJ,EAAU,CAAAy/C,EAAAvkD,KAAA,CAAoB,CAAC8E,KAAAA,CAAD,CAAO0xC,EAAQ,CAAAA,EAAf,CAA4BgO,GAAS,CAAAA,GAArC,CAApB,CACNmH,EAAAA,CAAQ,CAAA5G,EAAApc,IAAA,EACZ,EAAA6N,EAAA,CAAcmV,CAAAnV,EACd,EAAAgO,GAAA,CAAemH,CAAAnH,GACf,EAAAK,EAAA,CAAiB8G,CAAA9G,EACjB,EAAAC,GAAA,CAAsB6G,CAAA7G,GACjB,EAAAC,EAAAnqD,OAAL,EAAwD,EAAxD,EAAgC,CAAAkqD,GAAhC,EACI,CAAAp/C,MAAA,CAAW,qBAAX,CAZJ,CAAA,IACI,EAAAA,MAAA,CAAW,qBAAX,CAFR;AA4BAijD,QAAA,GAAa,CAAbA,CAAa,CAACtU,CAAD,CACb,CADyB,IAAAwE,EAAA,IAAA,EAAA,GAAAA,CAAA,CAAS,GAAT,CAAAA,CAMrB,KAJA,IAAI9hD,EAAI,CAAR,CACI60D,EAAU,CAAA,CADd,CAEIjY,EAAW,IAFf,CAGIkY,EAAW,CACf,CAAO90D,CAAP,CAAWs9C,CAAAz5C,OAAX,CAAA,CAA6B,CACzB,IAAIpC,EAAK67C,CAAA,CAAUt9C,CAAA,EAAV,CACT,IAAU,GAAV,EAAIyB,CAAJ,CACIozD,CAAA,CAAU,CAACA,CADf,KAIA,IAAIA,CAAAA,CAAJ,CAAA,CACA,GAAI,CAACC,CAAL,EAAuC,CAAvC,EAAiBhT,CAAAvgD,QAAA,CAAeE,CAAf,CAAjB,CAA0C,CACtCzB,CAAA,EACA,MAFsC,CAI1C,GAAU,MAAV,EAAIyB,CAAJ,CACIqzD,CAAA,EADJ,KAEO,IAAU,MAAV,EAAIrzD,CAAJ,EACc,CADd,CACC,EAAEqzD,CADH,CACiB,CAChB,CAAAnmD,MAAA,CAAW,yBAAX,CAAuC2uC,CAAvC,CAAmD,GAAnD,CACA,MAFgB,CARxB,CANyB,CAoBxBwX,CAAL,CAGoB,CAHpB,CAGSA,CAHT,EAII,CAAAnmD,MAAA,CAAW,uBAAX,CAAqC2uC,CAArC,CAAiD,GAAjD,CAJJ,CACIV,CADJ,CACeU,CAAA37C,OAAA,CAAiB,CAAjB,CAAoB3B,CAApB,CAKf,OAAO48C,EA/BX;AAiDAvJ,QAAA,GAAe,CAAfA,CAAe,CAACH,CAAD,CAAOb,CAAP,CAAmByb,CAAnB,CAA8BH,CAA9B,CACf,CACI,IAAIl3B,EAAU,EAEI/xB,KAAAA,EAAlB,GAAIopD,CAAJ,GACIA,CADJ,CACwC,CAAvB,EAAA,CAAAC,GAAA,CAA0B,CAAAA,GAA1B,CAAgD,CAAAD,EADjE,CASA,KAAIiH,EAAQ7hB,CAAA1xC,QAAA,CAAa,uBAAb,CAAsC,MAAtC,CAAAA,QAAA,CAAsD,sBAAtD,CAA8E,MAA9E,CAOZ,IAAI6wC,CAAJ,CAAgB,CAEZ,IAAI4b,EAAY,EAAhB,CACI3Q,EAAYyX,CAChB,IAAIhzD,CAAJ,CAAYgzD,CAAAhzD,MAAA,CAAY,uBAAZ,CAAZ,CACIksD,CACA,CADYlsD,CAAA,CAAM,CAAN,CACZ,CAAAu7C,CAAA,CAAYv7C,CAAA,CAAM,CAAN,CAEhB00B,EAAA,CAAS2mB,EAAA,CAAA,CAAAtuC,EAAA,CAA0Bm/C,CAA1B,CAAqC3Q,CAArC,CAAgDwQ,CAAhD,CAA2Dzb,CAA3D,CARG,CAWH,CAAb,CAAI5b,CAAJ,GAYIs+B,CAEA,CAFQA,CAAAvzD,QAAA,CAAc,eAAd,CAA+B6jB,CAAA,CAAA,CAAAvW,EAAA,CAAmBg/C,CAAnB,CAA+B,EAA/B,CAA/B,CAAmE,IAAnE,CAER,CADAr3B,CACA,CADS4c,EAAA,CAAA,CAAAvkC,EAAA,CAAyBimD,CAAzB,CAAgC1iB,CAAhC,CACT,CAAe3tC,IAAAA,EAAf,GAAI+xB,CAAJ,EACI,CAAA9nB,MAAA,CAAW,8BAAX,CAA4CukC,CAA5C,CAAmD,GAAnD,CAAwDya,CAAxD,CAfR,CAkBA,OAAOl3B,EAhDX;AA4DAs6B,QAAA,GAAU,CAAVA,CAAU,CAACzT,CAAD,CACV,CAII,IAHA,IAAIwX,EAAW,CAAf,CACIhE,EAAW,EADf,CAEI9wD,EAAI,CAFR,CAEWg1D,EAAU,EAFrB,CAEwBC,EAAO3X,CAAAz5C,OAC/B,CAAO7D,CAAP,CAAWs9C,CAAAz5C,OAAX,CAAA,CAA6B,CACzB,IAAIpC,EAAK67C,CAAA,CAAUt9C,CAAV,CACT,IAAU,GAAV,EAAIyB,CAAJ,CAAe,KACL,IAAV,EAAIA,CAAJ,GACSqzD,CAAA,EADT,GACqBE,CADrB,CAC8Bh1D,CAD9B,EAGAA,EAAA,EACA,IAAU,GAAV,EAAIyB,CAAJ,EAA+B,CAA/B,EAAiB,EAAEqzD,CAAnB,CAAkC,CAC9BG,CAAA,CAAOj1D,CACP,MAF8B,CAPT,CAYd,CAAf,CAAI80D,CAAJ,EACI,CAAAnmD,MAAA,CAAW,yBAAX,CAAuC2uC,CAAvC,CAAmD,GAAnD,CAEU,EAAd,EAAI0X,CAAJ,GACIlE,CADJ,CACexT,CAAA37C,OAAA,CAAiBqzD,CAAjB,CAAyBC,CAAzB,CAAgCD,CAAhC,CADf,CAGA,OAAOlE,EAtBX,CAwDA3B,QAAA,GAAU,CAAVA,CAAU,CAACxB,CAAD,CACV,CADWA,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAQ,CAAAA,GAAR,CAAAA,CAGP,KADA,IAAIT,EAAO,CACX,CAAOS,CAAP,CAAe,CAAAP,EAAA,CAAaF,CAAb,CAAf,CAAA,CAEI,GADAS,CACI,EADK,CAAAP,EAAA,CAAaF,CAAb,CACL,CAAAA,CAAA,CAAO,CAAAC,EAAAtpD,OAAP,CAA2B,CAA/B,CACIqpD,CAAA,EADJ,KAGI,MAGR,OAAO/iB,GAAA,CAAgB,CAAAgjB,EAAA,CAAWD,CAAX,CAAhB,CAAmC,QAAnC,CAA8CS,CAA9C,CAVX;AAsBAuD,QAAA,GAAW,CAAXA,CAAW,CAAC5T,CAAD,CACX,CACI,IAAW4X,EAAY,IACvB,IAAInzD,CAAJ,CAAYu7C,CAAAv7C,MAAA,CAAgB,0BAAhB,CAAZ,CAAyD,CACrDmzD,CAAA,CAAYnzD,CAAA,CAAM,CAAN,CACR6/C,EAAAA,CAAS7/C,CAAA,CAAM,CAAN,CACb,KAAIgM,EAAO,GAAPA,CAAa6zC,CAIjB,IAA6Bl9C,IAAAA,EAA7B,GAAI,CAAA4oD,EAAA,CAAev/C,CAAf,CAAJ,CAAwC,CAAA,IACxB0hD,CADwB,CACbD,CACvB,KAAAjlD,EAASklD,CAATllD,CAAqBilD,CAArBjlD,CAA+B,EAC/B,EAAA+iD,EAAA,CAAev/C,CAAf,CAAA,CAAuB,CACnBA,KAAMA,CADa,CAEnBomD,GAAUgB,EAFS,CAGnB5qD,GAAAA,CAHmB,CAInBklD,GAAAA,CAJmB,CAKnBD,GAAAA,CALmB,CAMnBt/C,GAAO0xC,CAAP1xC,CAAgB,KANG,CAOnBy9C,GAAO,CAAAA,GAPY,CASvB,EAAArd,EAAArnC,KAAA,CAAqB8E,CAArB,CAZoC,CAPa,CAsBzD,MAAOmnD,EAxBX;AA4FA1B,QAAA,GAAS,CAATA,CAAS,CAAClW,CAAD,CAAY8X,CAAZ,CACT,CACI,IAAI5F,EAAU,EAEd,KADI4F,CACJ,GADa9X,CACb,CADyBA,CAAA97C,QAAA,CAAkB,eAAlB,CAAmC,IAAnC,CACzB,EAAO87C,CAAP,CAAA,CAAkB,CACdA,CAAA,CAAYA,CAAAn5C,KAAA,EACRy4C,EAAAA,CAAWgV,EAAA,CAAAA,CAAA,CAAmBtU,CAAnB,CACf,IAAI,CAACV,CAAL,CAAe,KACf,KAAI9yC,EAAS8yC,CACb,IAAmB,IAAnB,EAAIA,CAAA,CAAS,CAAT,CAAJ,CAAyB,CACrB,IAAIyY,EAAY,CAAhB,CACIC,EAAc,CACC,IAAnB,EAAI1Y,CAAA,CAAS,CAAT,CAAJ,EACIyY,CAAA,EACA,CAAAC,CAAA,CAAc,CAFlB,EAG0B,GAH1B,EAGW1Y,CAAA,CAAS,CAAT,CAHX,GAIIyY,CAAA,EACA,CAAAC,CAAA,CAAc,CALlB,CAOSC,EAAAA,CAAAA,CAAe,EAAA,CAAA3Y,CAAAj7C,OAAA,CAAgB0zD,CAAhB,CApElBC,EAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAc,CAAd,CAAAA,CAGd,KAAIlzD,EAAQixC,EAAA,CAAAA,CAAA,CAAqBvpC,CAArB,CACZ,IAAcpF,IAAAA,EAAd,GAAItC,CAAJ,CAAyB,CACrB,IAAIgxC,EAAS,CACb,QAAOkiB,CAAP,EACA,KAAK,CAAL,CACIxrD,CAAA,CAASub,CAAA,CAAA,CAAAvW,EAAA,CAAmB1M,CAAnB,CAA2B,EAA3B,CACT,MACJ,MAAK,CAAL,CACIgxC,CAAA,EAEJ,MAAK,CAAL,CAEI,IAAA,CAAOhxC,CAAP,EAAgBgxC,CAAA,EAAhB,CAAA,CAGIhxC,CAAA,CAAQH,IAAAE,MAAA,CAAWC,CAAX,CAAmBH,IAAAC,IAAA,CAAS,CAAT,CAAYozD,CAAZ,CAAnB,CAZhB,CAFqB,CAmBzB,CAAA,CAAOxrD,CAmCsB,CAYzB0lD,CAAAvmD,KAAA,CAAaa,CAAb,CACAwzC,EAAA,CAAYA,CAAA37C,OAAA,CAAiBi7C,CAAA/4C,OAAjB,CAAmC,CAAnC,CAlBE,CAoBlB,MAAO2rD,EAvBX;AAiFAE,QAAA,GAAQ,CAARA,CAAQ,CAACpS,CAAD,CACR,CACI,IAAIkY,EAAUlY,CACM,KAApB,EAAI,CAAAkR,EAAJ,GACI,CAAAA,EACA,CADe,CAAAC,EACf,CAD6B,EAC7B,CAAInR,CAAJ,GACI,CAAAkR,EACA,CADelR,CAAA,CAAU,CAAV,CACf,CAAAkY,CAAA,CAAUlY,CAAV,CAAsBA,CAAA37C,OAAA,CAAiB,CAAjB,CAF1B,CAFJ,CAOA,IAAI,CAAA6sD,EAAJ,CAAkB,CACd,IAAIxuD,EAAIs9C,CAAA/7C,QAAA,CAAkB,CAAAitD,EAAlB,CACA,EAAR,CAAIxuD,CAAJ,CACIw1D,CADJ,CACc,EADd,EAGIA,CAEA,CAFUlY,CAAA37C,OAAA,CAAiB3B,CAAjB,CAAqB,CAArB,CAEV,CADAs9C,CACA,CADYA,CAAA37C,OAAA,CAAiB,CAAjB,CAAoB3B,CAApB,CACZ,CAAA,CAAAwuD,EAAA,CAAe,IALnB,CAOA,EAAAC,EAAA,EAAenR,CATD,CAWlB,GAAoB,IAApB,EAAI,CAAAkR,EAAJ,CAAA,CA0gBW1tD,CAAAA,CAAPT,CAAOS,CAAH,CADZ,KAGQyB,EA3gBAkzD,CA2gBMhH,EAAA5qD,OA3gBN4xD,EA4gBAxH,EAAJ,EAAsBoD,EAAtB,EAA+C9uD,CAAA,EAC/C,KAAK,IAAIvC,EAAI,CAAb,CAAgBA,CAAhB,CAAoBuC,CAApB,CAAyBvC,CAAA,EAAzB,CAA8B,CAC1B,GAAI,CAACK,CAAL,CAAQ,CACJS,CAAA,CAAI,CAAG,KAAAgB,EAAQ,EAAI,KAAAu5B,EAAO,CA/gB9Bo6B,EAghBQxH,EAAJ,EAAsBqD,EAAtB,GACIj2B,CAAA,EAAQ,CAAAv5B,CAAA,EADZ,CAFI,CAWR,IAAIpC,EAzhBJ+1D,CAyhBQhH,EAAAlf,WAAA,CAAuBvvC,CAAvB,CAAJN,CAAgC,GAKxB,EAAZ,EAAI27B,CAAJ,GACa,EACT,EADI37B,CACJ,EADsB,GACtB,EADiBA,CACjB,GAD4BA,CAC5B,EADiC,EACjC,EAAAA,CAAA,CAAKA,CAAL,CAAS,EAAT,CAAiB,EAFrB,CAIAoB,EAAA,EAAKpB,CAAL,CAASuC,IAAAC,IAAA,CAAS,CAAT,CAAYJ,CAAZ,CACTA,EAAA,EAASu5B,CACTh7B,EAAA,EACY,EAAZ,CAAIyB,CAAJ,GACIgwD,EAAA,CAtiBJ2D,CAsiBI,CAAa30D,CAAb,CACA,CAAAT,CAAA,CAAI,CAFR,CAxB0B,CA6B1BA,CAAJ,EAAOyxD,EAAA,CA1iBH2D,CA0iBG,CAAa30D,CAAb,CA3iBP,CAGA,MAAO00D,EAvBX;AA8CAxE,QAAA,GAAQ,CAARA,CAAQ,CAAC/C,CAAD,CAAY3Q,CAAZ,CACR,CAAA,IAC0CmS,CAD1C,CACqDD,CAEjD,EAAApB,EAAA,CAAmB,MACnB,EAAAC,EAAA,CAAoB,MACpB,KAAA9jD,EAASklD,CAATllD,CAAqBilD,CAArBjlD,CAA+B,EAE/B,IAAI0jD,CAAJ,EAAiBwE,EAAjB,CAA2C,CAMvC,IAAA1wD,EAAQu7C,CAAAv7C,MAAA,CAAgB,6DAAhB,CACR,IAAI,CAACA,CAAL,CAEI,MADA,EAAA4M,MAAA,CAAW,eAAX,CAA6Bs/C,CAA7B,CAAyC,OAAzC,CAAmD3Q,CAAnD,CAA+D,GAA/D,CACOA,CAAAA,CAEX,KAAAvvC,EAAOhM,CAAA,CAAM,CAAN,CAIP,IAAIA,CAAA,CAAM,CAAN,CAAJ,EAA4B,GAA5B,EAAgBA,CAAA,CAAM,CAAN,CAAhB,CAAiC,CAEAwI,CAAAA,CAD7BA,CAC6BA,CADpBipD,EAAA,CAAAA,CAAA,CAAezxD,CAAA,CAAM,CAAN,CAAf,CAAyB,CAAA,CAAzB,CAjSb0tD,EAAAA,CAAY,EAChB,KAASzvD,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoBuK,CAAA1G,OAApB,CAAmC7D,CAAA,EAAnC,CAAwC,CAChCC,IAAAA,EAAIsK,CAAA,CAAOvK,CAAP,CAAAuB,QAAA,CAAkB,MAAlB,CACR,IAAS,CAAT,EAAItB,CAAJ,CAAY,CACR,IAAIC,EAAIqK,CAAA,CAAOvK,CAAP,CAAAuD,YAAA,CAAsB,MAAtB,CACA,EAAR,CAAIrD,CAAJ,GAAWA,CAAX,CAAeqK,CAAA,CAAOvK,CAAP,CAAA6D,OAAf,CACA4rD,EAAA,CAAUzvD,CAAV,CAAA,CAAeuK,CAAA,CAAOvK,CAAP,CAAA2B,OAAA,CAAiB1B,CAAjB,CAAoBC,CAApB,CAAwBD,CAAxB,CACfsK,EAAA,CAAOvK,CAAP,CAAA,CAAYuK,CAAA,CAAOvK,CAAP,CAAA2B,OAAA,CAAiB,CAAjB,CAAoB1B,CAApB,CAJJ,CAFwB,CASxC,CAAA,CAAOwvD,CAsR8B,CAIjC0E,CAAA,CAAWuB,EACXxF,EAAA,CAAS,CApB8B,CAA3C,IAsBK,IAAIjC,CAAJ,EAAiBoF,EAAjB,CAA0C,CAO3C,CAAAjF,EAAA,CAAmB,GACnB,EAAAC,EAAA,CAAoB,GACpBtsD,EAAA,CAAQu7C,CAAAv7C,MAAA,CAAgB,yCAAhB,CACR;GAAI,CAACA,CAAL,CAEI,MADA,EAAA4M,MAAA,CAAW,eAAX,CAA6Bs/C,CAA7B,CAAyC,OAAzC,CAAmD3Q,CAAnD,CAA+D,GAA/D,CACOA,CAAAA,CAEXvvC,EAAA,CAAOhM,CAAA,CAAM,CAAN,CACPoyD,EAAA,CAAWC,EACXlE,EAAA,CAAS,CAhBkC,CAA1C,IAkBA,IAAIjC,CAAJ,EAAiBgD,EAAjB,CAID,CAAA7C,EAQA,CARmB,GAQnB,CAPA,CAAAC,EAOA,CAPoB,GAOpB,CANAtgD,CAMA,CANO,GAMP,CANa0mC,EAAA,CAAU,EAAE,CAAAoZ,GAAZ,CAA2B,CAA3B,CAMb,CAL6BnpD,IAAAA,EAK7B,GALI,CAAA4oD,EAAA,CAAev/C,CAAf,CAKJ,EAJI,CAAAY,MAAA,CAAW,kBAAX,CAAgCZ,CAAhC,CAAuC,aAAvC,CAIJ,CAFAhM,CAEA,CAFQ,CAACu7C,CAAA,CAAU,CAAV,CAAD,CAAeA,CAAA37C,OAAA,CAAiB,CAAjB,CAAf,CAER,CADAwyD,CACA,CADWwB,EACX,CAAAzF,CAAA,CAAS,CAZR,KAcA,IAAIjC,CAAJ,EAAiB4B,EAAjB,EAA0C5B,CAA1C,EAAuD6B,EAAvD,CAA+E,CAO3E,CAAAvB,EAAL,EACI,CAAA5/C,MAAA,CAAWs/C,CAAX,CAAuB,mBAAvB,CAEJlsD,EAAA,CAAQu7C,CAAAv7C,MAAA,CAAgB,6CAAhB,CACR,IAAI,CAACA,CAAL,CAEI,MADA,EAAA4M,MAAA,CAAW,eAAX,CAA6Bs/C,CAA7B,CAAyC,aAAzC,CAAyD3Q,CAAzD,CAAqE,GAArE,CACOA,CAAAA,CAEX,KAAKt9C,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB,CAAAuuD,EAAAhkD,GAAA1G,OAAhB,EACQ9B,CAAA,CAAM,CAAN,CADR,EACoB,CAAAwsD,EAAAhkD,GAAA,CAAsBvK,CAAtB,CADpB,CAA8CA,CAAA,EAA9C,EAGA,GAAIA,CAAJ,EAAS,CAAAuuD,EAAAhkD,GAAA1G,OAAT,CAEI,MADA,EAAA8K,MAAA,CAAW,UAAX,CAAwBs/C,CAAxB,CAAoC,cAApC,CAAqDlsD,CAAA,CAAM,CAAN,CAArD;AAAgE,GAAhE,CACOu7C,CAAAA,CAEXvvC,EAAA,CAAO,GAAP,CAAakgD,CACb1jD,EAAA,CAAS,CAACxI,CAAA,CAAM,CAAN,CAAD,CACLksD,EAAJ,EAAiB6B,EAAjB,CACIN,CADJ,CACc,CAAAjB,EAAAiB,GAAA,CAAuBxvD,CAAvB,CAAAgJ,MAAA,CAAgC,EAAhC,CADd,CAGIwmD,CAHJ,CAGcgE,EAAA,CAAAA,CAAA,CAAe,CAAAjF,EAAAiB,GAAA,CAAuBxvD,CAAvB,CAAf,CAEdm0D,EAAA,CAAW3E,CAAA3rD,OACXqsD,EAAA,CAAS,CA9BuE,CAA/E,IAgCA,CAID,GAAIjC,CAAJ,EAAiByE,EAAjB,CACIyB,CACA,CADW,CACX,CAAoB,GAApB,EAAI7W,CAAA,CAAU,CAAV,CAAJ,GAAyBA,CAAzB,CAAqCA,CAAA37C,OAAA,CAAiB,CAAjB,CAAAwC,KAAA,EAArC,CAFJ,KAIK,CACGy4C,CAAAA,CAAWgV,EAAA,CAAAA,CAAA,CAAmBtU,CAAnB,CACf,IAAI,CAACV,CAAL,CAEI,MADA,EAAAjuC,MAAA,CAAW,UAAX,CAAwBs/C,CAAxB,CAAoC,eAApC,CAAsD3Q,CAAtD,CAAkE,GAAlE,CACOA,CAAAA,CAEXA,EAAA,CAAYA,CAAA37C,OAAA,CAAiBi7C,CAAA/4C,OAAjB,CAAmC,CAAnC,CACZ+4C,EAAA,CAAWA,CAAAz4C,KAAA,EACX,IAAI8pD,CAAJ,EAAiB2E,EAAjB,EAA4C3E,CAA5C,EAAyD+E,EAAzD,CAAkF,CAC1E4C,CAAAA,CAAYhE,EAAA,CAAAA,CAAA,CAAmBtU,CAAnB,CAChB,IAAI,CAACsY,CAAL,CAEI,MADA,EAAAjnD,MAAA,CAAW,iBAAX,CAA+Bs/C,CAA/B,CAA2C,eAA3C,CAA6D3Q,CAA7D,CAAyE,GAAzE,CACOA,CAAAA,CAEXA,EAAA,CAAYA,CAAA37C,OAAA,CAAiBi0D,CAAA/xD,OAAjB,CAAoC,CAApC,CANkE,CAW9EswD,CAAA,CADAlG,CAAJ,EAAiB0E,EAAjB,EAA4C1E,CAA5C,EAAyDmF,EAAzD,CAzMyB1uD,IAAAA,EA0MV,GAAAmxD,CA1MhBvI,EAAA,CA0M+B1Q,CA1M/B,CA0MgB,EA9LWl4C,IAAAA,EA8LX,GAAAmxD,CA9LhBtI,EAAA,CA8L+B3Q,CA9L/B,CA8LgB,EA5zLUl4C,IAAAA,EA4zLV,GAAAmxD,CAtN+B/mD,EAtmL/CwhC,EAAA,CA4zL+BsM,CA5zL/B,CA4zLgB,CAA0B,CAA1B,CAA8B,CAD7C,CAOevJ,EAAA,CAAAA,CAAA,CAAqBuJ,CAArB,CAPf,EAOiD,CAzBhD,CA4BL76C,CAAA,CAAQu7C,CAAAv7C,MAAA,CAAgB,mBAAhB,CACRgM,EAAA,CAAO,GAAP,CAAakgD,CACbiC,EAAA,CAAS,CAtCR,CA8CLniD,CAAA,CAAOA,CAAAorC,YAAA,EACP;CAAA+U,EAAA,CAAiB,CACjB,EAAAC,EAAA,CAAiBpgD,CACjB,EAAAu/C,EAAA,CAAev/C,CAAf,CAAA,CAAuB,CAACA,KAAAA,CAAD,CAAOomD,GAAAA,CAAP,CAAiB5pD,GAAAA,CAAjB,CAAyBklD,GAAAA,CAAzB,CAAoCD,GAAAA,CAApC,CAA6Ct/C,GAAO,EAApD,CAAwDy9C,GAAO,CAAAA,GAA/D,CAEnB5rD,EAAA,CAAMmuD,CAAN,CAAJ,GACI,CAAAhC,EACA,CADiB,CACjB,CAAAoC,EAAA,CAAAA,CAAA,CAAiBvuD,CAAA,CAAMmuD,CAAN,CAAe,CAAf,CAAjB,CAFJ,CAKA,OAAOniD,EArJX,CA+JAuiD,QAAA,GAAW,CAAXA,CAAW,CAACnT,CAAD,CACX,CAEI,IADA,IAAIqY,EAAU,EAAd,CACSx1D,EAAI,CAAb,CAAgBA,CAAhB,CAAoBm9C,CAAAt5C,OAApB,CAAkC7D,CAAA,EAAlC,CACI,GAAIm9C,CAAA,CAAMn9C,CAAN,CAAJ,EAAgB,CAAAouD,EAAhB,CACI,CAAAF,EAAA,EADJ,KAEO,IAAI/Q,CAAA,CAAMn9C,CAAN,CAAJ,EAAgB,CAAAquD,EAAhB,GACH,CAAAH,EAAA,EACI,CAAkB,CAAlB,EAAA,CAAAA,EAFD,EAEsB,CACrB,CAAAA,EAAA,CAAiB,CACjBsH,EAAA,CAAUrY,CAAAx7C,OAAA,CAAa3B,CAAb,CAAiB,CAAjB,CACVm9C,EAAA,CAAQA,CAAAx7C,OAAA,CAAa,CAAb,CAAgB3B,CAAhB,CACR,MAJqB,CAQ7B+N,CAAAA,CAAO,CAAAogD,EAAPpgD,EAAyB,EAC7B,EAAAu/C,EAAA,CAAev/C,CAAf,CAAAmC,GAAA,EAA8BitC,CACzB,EAAA+Q,EAAL,GACI,CAAAC,EACA,CADiB,IACjB,CAAAgD,EAAA,CAAAA,CAAA,CAAgBpjD,CAAhB,CAFJ,CAIA,OAAOynD,EArBX;AAgCAtG,QAAA,GAAS,CAATA,CAAS,CAACnhD,CAAD,CAAO3L,CAAP,CAAcuuD,CAAd,CACT,CADuBA,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAQ,CAAR,CAAAA,CAEnB5iD,EAAA,CAAOA,CAAAorC,YAAA,EAAAx3C,OAAA,CAA0B,CAA1B,CAA6B,CAA7B,CACP,IAAKgvD,CAAL,CAAaF,EAAb,EAAiE/rD,IAAAA,EAAjE,GAAuC,CAAA6oD,EAAA,CAAgBx/C,CAAhB,CAAvC,CACI,CAAAY,MAAA,CAAW,mBAAX,CAAiCZ,CAAjC,CAAwC,GAAxC,CADJ,KAAA,CAIA,IAAIgmC,EAAarvC,IAAAA,EACjB,IAAoB,QAApB,EAAI,MAAOtC,EAAX,CAA8B,CACtBiwC,CAAAA,CAAa,EACjB,KAAIxxC,EAAIwyC,EAAA,CAAAA,CAAA,CAAqBjxC,CAArB,CAA4BiwC,CAA5B,CACR,IAAU3tC,IAAAA,EAAV,GAAI7D,CAAJ,CAAqB,CACjB,CAAA8N,MAAA,CAAW,kBAAX,CAAgCZ,CAAhC,CAAuC,KAAvC,CAA+C3L,CAA/C,CACA,OAFiB,CAIG,CAAxB,CAAIiwC,CAAAxuC,OAAJ,EACI,CAAA8K,MAAA,CAAW,iCAAX,CAA+CZ,CAA/C,CAAsD,KAAtD,CAA8DskC,CAAAmB,KAAA,EAA9D,CAEJpxC,EAAA,CAAQvB,CACRkzC,EAAA,CAAa1B,CAAA,CAAW,CAAX,CAXa,CAc9B,CADIyjB,CACJ,CADU,CAAAvI,EAAA,CAAgBx/C,CAAhB,CACV,GACI+nD,CAAA1zD,MAEA,CAFYA,CAEZ,CADA0zD,CAAAnF,GACA,CADYA,CACZ,CAAAmF,CAAAnI,GAAA,CAAY,CAAAA,GAHhB,EAKI,CAAAJ,EAAA,CAAgBx/C,CAAhB,CALJ,CAK4B,CAACA,KAAAA,CAAD,CAAO3L,MAAAA,CAAP,CAAcuuD,GAAAA,CAAd,CAAqBhD,GAAO,CAAAA,GAA5B,CAE5B,EAAA7+C,EAp5LAwhC,EAAA,CAo5LqBviC,CAp5LrB,CAAA,CAAwB,CAAC3L,MAo5LEA,CAp5LH,CAAQ2xC,GAo5LEA,CAp5LV,CA03LxB,CAFJ;AA0JAme,QAAA,GAAO,CAAPA,CAAO,CAACjE,CAAD,CAAYsC,CAAZ,CAA6BjT,CAA7B,CACP,CACI,IAAIjL,EAAa,EACba,EAAAA,CAAO/uC,CAAC8pD,CAAD9pD,EAHI,IAAA,EAAAosD,GAAAA,CAAAA,CAAa,EAAbA,CAAAA,CAGJpsD,GAHqB,IAAA,EAAAm5C,GAAAA,CAAAA,CAAY,EAAZA,CAAAA,CAGrBn5C,OAAA,EACPrD,EAAAA,CAAIuyC,EAAA,CAAAA,CAAA,CAAqBH,CAArB,CAA2Bb,CAA3B,CACE3tC,KAAAA,EAAV,GAAI5D,CAAJ,CACSuxC,CAAAxuC,OAAL,CAEgC,CAAzB,EAAIwuC,CAAAxuC,OAAJ,CACHiuD,EAAA,CAAAA,CAAA,CAAahxD,CAAb,CAAgBuxC,CAAA,CAAW,CAAX,CAAhB,CADG,CAIHyf,EAAA,CAAAA,CAAA,CAAa,CAAb,CAAgB5e,CAAhB,CANJ,CACI4e,EAAA,CAAAA,CAAA,CAAahxD,CAAb,CAFR,CAUI,CAAA6N,MAAA,CAAW,gCAAX,CAA8CukC,CAA9C,CAAqD,GAArD,CAdR;AAsCAmc,QAAA,GAAU,CAAVA,CAAU,CACV,CAGI,IAFA,IAAI0G,EAAoB,CAAAjI,EAAxB,CAEA,EAAA,EAFA,CAES9tD,EAAI,CAAb,CAAgBA,CAAhB,CAAoB,CAAAwtD,EAAA3pD,OAApB,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,EAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,CAA2C7D,CAAA,EAA3C,CAAgD,CA4BxCg2D,CAAAA,GAAJ,CAAU,CAAAxI,EAAA,CAAextD,CAAf,CAKNy/C,EAAAA,EAAJ,CAAa,EACTE,EAAAA,GAAJ,CAAa,CACbqW,EAAAA,GAAAvW,EAAAK,QAAA,CAAmB,QAAA,CAAA,CAAA,CAAA,CAAA,MAAA,SAAQ,CAACh/C,CAAD,CAAIgtD,CAAJ,CAAe,CAClCA,CAAJ,GAAkBrO,CAAAA,EAAA57C,OAAlB,EAAiC47C,CAAAA,EAAAx2C,KAAA,CAAYnI,CAAZ,CACjC6+C,EAAAA,GAAA,EAFsC,CAAvB,CAAA,CAAA,CAAA,CAAnB,CAIA,IAAIA,CAAAA,GAAJ,EAAcF,CAAAA,EAAA57C,OAAd,CAKI,IAAK,IAAIiqD,EAAYiI,CAArB,CAAwCjI,CAAxC,CAAoDnO,CAAAA,GAApD,EAA8D,CAAAmO,EAA9D,CAA8EA,CAAA,EAA9E,CAA2F,CACvF,IAAIztD,EAAAA,IAAAA,EACJ,KAAKA,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgBs/C,CAAAA,GAAhB,EAQQF,CAAAA,EAAA,CAAOp/C,CAAP,CARR,GAQsB,CAAAo/C,EAAA,CAAYqO,CAAZ,CAAwBztD,CAAxB,CARtB,EAQoD21D,CAAAA,GAAAvI,GAAA,CAAYptD,CAAZ,CARpD,EAQsE,CAAAotD,GAAA,CAAaK,CAAb,CARtE,CAAwBztD,CAAA,EAAxB,EAUA,GAAIA,CAAJ,EAASs/C,CAAAA,GAAT,CAAiB,CACbuP,EAAA,CAAAA,CAAA,CAAe8G,CAAAA,GAAAjoD,KAAf,CAAyB+/C,CAAzB,CAAoC2C,EAApC,CACAuF,EAAAA,GAAA,CAAM,IACN,MAHa,CAZsE,CAmB/F,GAAIA,CAAAA,GAAJ,CAAS,CACL,IAAI7f,EAAU,CACd+Y,GAAA,CAAAA,CAAA,CAAe8G,CAAAA,GAAAjoD,KAAf,CAAyB,CAAA+/C,EAAzB,CAAyC2C,EAAzC,CACAuF,EAAAA,GAAAvW,EAAAK,QAAA,CAAmB,QAAA,CAAA,CAAA,CAAA,CAAA,MAAA,SAAQ,CAACh/C,CAAD,CAAIgtD,CAAJ,CAAe,CACtCgE,EAAA,CAAA3b,CAAA,CAAgBr1C,CAAhB,CAAmBk1D,CAAAA,GAAAvI,GAAA,CAAYK,CAAZ,CAAnB,CADsC,CAAvB,CAAA,CAAA,CAAA,CAAnB,CAHK,CA/DmC,CAuEhD,CAAAN,EAAA,CAAiB,EA1ErB;AAkFA8B,QAAA,GAAW,CAAXA,CAAW,CACX,CACI,IAAK,IAAItvD,EAAI,CAAb,CAAgBA,CAAhB,CAAoB,CAAAswC,EAAAzsC,OAApB,CAA4C7D,CAAA,EAA5C,CAAiD,CAC7C,IAAI+N,EAAO,CAAAuiC,EAAA,CAAgBtwC,CAAhB,CAAX,CACIk0D,EAAQ,CAAA5G,EAAA,CAAev/C,CAAf,CACPmmD,EAAL,CAOAG,CAAA,CAAAA,CAAA,CAAeH,CAAAhkD,GAAf,CAPA,CAII,CAAAvB,MAAA,CAAW,mCAAX,CAAiDZ,CAAjD,CAAwD,GAAxD,CAPyC,CAYjD,CAAAuiC,EAAA,CAAkB,EAbtB,CAoEAwhB,QAAA,GAAO,CAAPA,CAAO,CAAC1vD,CAAD,CAAQ2xC,CAAR,CACP,CACI,CAAA0L,EAAA,CAAY,CAAAqO,EAAZ,CAAA,CAA8B9c,EAAA,CAAAA,CAAA,CAAc5uC,CAAd,CACXsC,KAAAA,EAAnB,GAAIqvC,CAAJ,GAA8B,CAAA0Z,GAAA,CAAa,CAAAK,EAAb,CAA9B,CAA6D/Z,CAA7D,CACA,EAAA2Z,EAAA,CAAe,CAAAI,EAAf,CAAA,CAAiC,CAAAH,GACjC,EAAAG,EAAA,EAJJ,CAeA9c,QAAA,GAAQ,CAARA,CAAQ,CAAC5uC,CAAD,CAAQ0rD,CAAR,CACR,CADgBA,CAAA,CAAA,IAAA,EAAA,GAAAA,CAAA,CAAY,CAAAA,EAAZ,CAAAA,CAEZ,KAAIhtD,EAAIkwC,CAAA,CAAA,CAAAliC,EAAA,CAAkB1M,CAAlB,EAA2B,CAA3B,CAA8B,EAA9B,CAAkC,CAAA,CAAlC,CACR,EAAIA,CAAJ,CAAY,CAACoxB,CAAb,EAAgCpxB,CAAhC,EAAyCwe,CAAzC,GACIquC,EAAA,CAAAA,CAAA,CAAa,kBAAb,CAAkCjrC,EAAA,CAAU5hB,CAAV,CAAlC,CAAqD,eAArD,CAAuE4hB,EAAA,CAAU8pC,CAAV,CAAvE,CAA8F,MAA9F,CAAuG9pC,EAAA,CAAUljB,CAAV,CAAvG,CAEJ,OAAOA,EALX,CAgBA,EAAA,UAAA,MAAA,CAAA6N,QAAK,CAACsnD,CAAD,CAAStI,CAAT,CACL,CACI,KAAUvlD,MAAJ,CAAU,WAAV,CAAwB+mD,EAAA,CAAAA,IAAA,CAAgBxB,CAAhB,CAAxB,CAAiD,IAAjD,CAAwDsI,CAAxD,CAAN,CADJ,CAWAhH;QAAA,GAAO,CAAPA,CAAO,CAACiH,CAAD,CACP,CACI,CAAA7hD,EAAA,CAAa,aAAb,CAA6B86C,EAAA,CAAAA,CAAA,CAFfxB,IAAAA,EAEe,CAA7B,CAAsD,IAAtD,CAA6DuI,CAA7D,CADJ,CAUA,EAAA,UAAA,EAAA,CAAA7hD,QAAO,CAAC3T,CAAD,CACP,CACS,IAAAoO,EAAL,CAGI,IAAAA,EAAAuF,EAAA,CAAiB3T,CAAjB,CAHJ,CACImU,OAAAlS,IAAA,CAAYjC,CAAZ,CAFR,CAUAy1D;IAAAA,GAAYA,CAAZA,CAEAC,GAAYA,CAFZD,CAMAl6D,GAAYA,OANZk6D,CAOAE,GAAYA,OAPZF,CAQAG,GAAYA,OARZH,CASAI,GAAYA,MATZJ,CAUAK,GAAYA,QAVZL,CAWAM,GAAYA,KAXZN,CAYAO,GAAYA,KAZZP,CAaAQ,GAAYA,KAbZR,CAcAS,GAAYA,OAdZT,CAeAU,GAAYA,OAfZV,CAgBAW,GAAYA,KAhBZX,CAiBAY,GAAYA,KAjBZZ,CAkBAa,GAAYA,MAlBZb,CAmBAc,GAAYA,OAnBZd,CAoBAe,GAAYA,KApBZf,CAqBAgB,GAAYA,MArBZhB,CAsBAiB,GAAYA,KAtBZjB,CAuBAkB,GAAYA,QAvBZlB,CAwBAmB,GAAYA,KAxBZnB,CAyBAoB,GAAYA,MAzBZpB,CA0BAqB,GAAYA,MA1BZrB,CA2BAsB,GAAYA,KA3BZtB,CA4BAuB,GAAYA,SA5BZvB,CA6BAwB,GAAYA,MA7BZxB,CA8BAyB,GAAYA,KA9BZzB,CA+BA0B,GAAYA,OA/BZ1B,CAgCA2B,GAAYA,OAhCZ3B,CAiCA4B,GAAYA,MAjCZ5B,CAkCA6B,GAAYA,OAlCZ7B,CAmCA8B,GAAYA,QAnCZ9B,CAoCA+B,GAAYA,QApCZ/B,CAqCAgC,GAAYA,QArCZhC,CAsCAiC,GAAYA,OAtCZjC,CAuCAkC,GAAYA,KAvCZlC,CAwCAmC,GAAYA,MAxCZnC,CAyCAoC,GAAYA,KAzCZpC,CA0CAqC,GAAYA,OA1CZrC,CAmDAK,GAAiBA,EAnDjBL,CAoDA2B,GAAiBA,EApDjB3B,CAqDAuB,GAAiBA,EArDjBvB,CAsDAsC,GAAiBA,EAsEjB/qD;QA9DEgrD,GA8DS,CAACC,CAAD,CAAgBC,CAAhB,CAA8BC,CAA9B,CACX,CACI,CAAA,KAAA,CAAA,IAAA,CAAM,UAAN,CAAkBF,CAAlB,CAl8pBQx+C,QAk8pBR,CAEA,KAAA/L,MAAAK,EAAA,CAAqB,CAAA,CAErB,KAAAmqD,EAAA,CAAoB,IACpBE,GAAA,CAAAA,IAAA,CAAqBF,CAArB,CAEA,KAAAG,EAAA,CAAkB7uC,EAAA,CAAAA,IAAA,CAAoB,WAApB,CAAiCyuC,CAAjC,CArjwBVK,CAqjwBU,CAMlB,KAAAC,EAAA,CAAoB,CAKpB,KAAAp3C,EAAA,CAAiB,CAAC82C,CAAA,SAAlB,EAA+C,CAACA,CAAA,SAGhD,KAAAO,EAAA,CADA,IAAAC,EACA,CADmB,IAAAC,EACnB,CADqC,IAGrC,KAAAC,EAAA,CADA,IAAAC,EACA,CADkB,CAAA,CAElB,KAAAC,EAAA,CAAqB,IAAAC,EAArB,CAA0C,IAC1C,KAAAC,EAAA,CAAmC,IAAAC,EAAnC,CAAwD,CAAA,CAExD,KAAAC,GAAA,CAAkCzvC,EAAA,CAAAA,IAAA,CAAoB,KAApB,CAAlC,EAAgE,EAM9CpW,EAAC7R,IAAA23D,OAAA,EAAD9lD,CAAiB,EAAjBA,UAAAnS,CAA+B,EAA/BA,CAClB,KAAAk4D,EAAA,CAAeC,EAAA,CAAAA,IAAA,CAUf,IADA,IAAA/qD,EACA,CADyCyE,EAAA,CAA6B,KAA7B,CAAoC,IAAA1F,GAApC,CACzC,CAAA,CAIA,IAAAgB,EAAA,CAAyC0E,EAAA,CAA6B,UAA7B,CAAyC,IAAA1F,GAAzC,CAKzC,KAAAkB,EAAA,CAAW,IAAI2S,EAAJ,CAAa,CAAC,GAAM,IAAAxT,GAAN,CAAuB,MAAxB,CAAgC,SAAY,IAAA0T,EAA5C,CAAb,CAA0E,IAAA9S,EAA1E,CAAoF,IAAAD,EAApF,CAKX,KACI2C,EAAcyZ,EAAA,CAAwB,IAAApd,GAAxB,CAKlB,IAFA,IAAAw0C,EAEA,EAHA,IAAAtlC,EAGA,CAHwCxJ,EAAA,CAA6B,OAA7B,CAAsC,IAAA1F,GAAtC,CAGxC;AAFkC,IAAAkP,EAAA/O,EAAA,MAElC,CACI,IAAKgd,CAAL,CAAkB,CAAlB,CAAqBA,CAArB,CAAkCxZ,CAAA5N,OAAlC,CAAsDonB,CAAA,EAAtD,CAAoE,CAChE,IAAA9b,EAAYsC,CAAA,CAAYwZ,CAAZ,CAMZ9b,EAAAgF,GAAA,CAAmB,IAAA6I,EAAA7I,GACnBhF,EAAAmF,MAAA,CAAkB,IAAA0I,EAAA1I,MAClBnF,EAAAkF,EAAA,CAAoB,IAAA2I,EAAA3I,EAT4C,CAaxE,IAAAA,EAAA,CAAa0E,EAAb,CAh5yBMghD,mJAg5yBN,CAKA,KAAK9uC,CAAL,CAAkB,CAAlB,CAAqBA,CAArB,CAAkCxZ,CAAA5N,OAAlC,CAAsDonB,CAAA,EAAtD,CACI9b,CACA,CADYsC,CAAA,CAAYwZ,CAAZ,CACZ,CAAI9b,CAAAoO,GAAJ,EAAuBpO,CAAAoO,GAAA,CAAkB,IAAlB,CAAwB,IAAAvO,EAAxB,CAAkC,IAAAD,EAAlC,CAA4C,IAAAD,EAA5C,CAGvBsqD,EAAAA,CAAa,IACbY,EAAAA,CAAiC9vC,EAAA,CAAAA,IAAA,CAAoB,QAApB,CAA8ByuC,CAA9B,CACrBj0D,KAAAA,EAAhB,GAAIs1D,CAAJ,GAIyB,CAArB,CAAIA,CAAAn2D,OAAJ,CACIu1D,CADJ,CACiB,IAAAD,EADjB,CACoCa,CADpC,CAGI,IAAAC,EAHJ,CAGkB94D,QAAA,CAAS64D,CAAT,CAAkB,EAAlB,CAPtB,CAyBA,KAAIE,CAGJ,IAFIvX,CAEJ,CAFaz4B,EAAA,CAAAA,IAAA,CAAoB,OAApB,CAEb,GAF8CgwC,CAAD,CAAgB,CAAA,CAAhB,CAAyBvB,CAAA,MAEtE,EACI,IAAAS,EAKA,CALkBA,CAKlB,CAL+BzW,CAK/B,CAJKuX,CAIL,GAHI,IAAAb,EACA,CADoB,CAAA,CACpB,CAAA,IAAAY,EAAA,CAAcE,EAElB,EAAI,IAAAF,EAAJ;CACI,IAAAV,EACA,CADqB,IAAIx7C,CAAJ,CAAU,IAAV,CAr8yBpBq8C,QAq8yBoB,CACrB,CAAI,IAAAb,EAAAc,KAAA,EAAJ,CACIjB,CADJ,CACiB,IADjB,CAGI,OAAO,IAAAG,EALf,CAcA,EAACH,CAAL,EAAmB,IAAAa,EAAnB,GACIb,CADJ,CACiBkB,EAAA,CAAAA,IAAA,CADjB,IAEoB,IAAAjB,EAFpB,CAEwC,CAAA,CAFxC,CAKA,IAAKD,CAAL,CAEO,CACH,IAAInqD,EAAM,IACVy7B,GAAA,CAAgB0uB,CAAhB,CAA4B,IAA5B,CAAkC,CAAA,CAAlC,CAAwCmB,QAAsB,CAACx0D,CAAD,CAAOgpD,CAAP,CAAkBhoD,CAAlB,CAA8B,CACnDA,CA2I7C,EA3IQkI,CAkJJkqD,EAEA,CAFmB,IAEnB,CApJIlqD,CAmJJoqD,EACA,CADoB,CAAA,CACpB,CApJIpqD,CAoJJkF,GAAA,CAAY,kDAAZ,CApJyCpN,CAoJzC,EApJ8BgoD,CAoJiD,CAAY,IAAZ,CAAmB5f,EAAA,CApJpE4f,CAoJoE,CAAnB,CAA0C,EAAzH,EAA+H,GAA/H,CATJ,GA3IQ9/C,CA4IJiqD,EACA,CA7I8BnK,CA6I9B,CA7II9/C,CA6IJqqD,EAAA,CAAkB,CAAA,CAFtB,CAWArkD,GAAA,CAtJQhG,CAsJR,CAvJgG,CAA5F,CAFG,CAFP,IACIgG,GAAA,CAAAA,IAAA,CAQC,KAAAhH,EAAA,MAAL,GAA6B,IAAA8qD,EAA7B,CAA+C,CAAA,CAA/C,CAKI,EAACF,CAAL,EAAmB,IAAAE,EAAnB,EAAoC,IAAAyB,KAAA,CAAU,IAAAC,GAAV,CAjHpC,CAAA,IAj6sBA9xD,EAAA,CAk6sBoBjI,8BAl6sBpB,CAo3sBJ,CA/DwB6b,EAAA5O,CAAtB+qD,EAAsB/qD,CAAAA,CAAAA,CA+PxBmrD;QAAA,GAAe,CAAfA,CAAe,CAACF,CAAD,CACf,CACI,GAAI,CAACA,CAAL,CAAmB,CACf,IAAItuD,CACJ,IAAwB,QAAxB,EAAI,MAAOtD,UAAX,GAAqCsD,CAArC,CAA8CtD,SAAA,MAA9C,EACI,GAAI,CACA4xD,CAAA,CAAsCpwD,IAAA,CAAK,GAAL,CAAW8B,CAAX,CAAoB,GAApB,CADtC,CAEF,MAAM1K,CAAN,CAAS,CA3jtBnB+I,CAAA,CA4jtB4B/I,CAAAgJ,QA5jtB5B,CA4jtBwC,IA5jtBxC,CA4jtB+C0B,CA5jtB/C,CA4jtBwD,GA5jtBxD,CA2jtBmB,CALA,CAUnB,CAAAsuD,EAAA,CAAoBA,CAXxB,CAmCA1uC,QAAA,GAAc,CAAdA,CAAc,CAAC9f,CAAD,CAAQswD,CAAR,CAAwB10D,CAAxB,CACd,CAOI,IAAI20D,EAAUvwD,CAAA1G,YAAA,EACVtB,EAAAA,CAAQw4D,EAAA,CAAexwD,CAAf,CAARhI,EAAiCw4D,EAAA,CAAeD,CAAf,CACvBj2D,KAAAA,EAAd,GAAItC,CAAJ,EAA2B,CAAAw2D,EAA3B,GAA8Cx2D,CAA9C,CAAsD,CAAAw2D,EAAA,CAAkBxuD,CAAlB,CAAtD,CACc1F,KAAAA,EAAd,GAAItC,CAAJ,EAA2Bs4D,CAA3B,GAA2Ct4D,CAA3C,CAAmDs4D,CAAA,CAAetwD,CAAf,CAAnD,CACc1F,KAAAA,EAAd,GAAItC,CAAJ,EAA+C,QAA/C,EAA2B,MAAO4E,UAAlC,EAA2DA,SAAA,CAAUoD,CAAV,CAA3D,GAA6EhI,CAA7E,CAAqFgI,CAArF,CACc1F,KAAAA,EAAd,GAAItC,CAAJ,GAAyBA,CAAzB,CAbwCy4D,IAAAA,EAaxC,CACA,IAAoB,QAApB,EAAI,MAAOz4D,EAAX,EAAgC4D,CAAhC,CACI,OAAOA,CAAP,EACA,KAnywBI80D,CAmywBJ,CACI14D,CAAA,CAAQ,CAACA,CACLJ,MAAA,CAA4BI,CAA5B,CAAJ,GAAyCA,CAAzC,CAAiE,CAAjE,CACA,MACJ,MArywBI42D,CAqywBJ,CACI52D,CAAA,CAAkB,MAAlB,EAASA,CANb,CAUJ,MAAOA,EAxBX,CA2FA,CAAA,CAhpzBJ,EAAA24D,UAgpzBIlnD;CAAA2mD,KAAA,CAAAA,QAAI,CAACrvD,CAAD,CAAKyC,CAAL,CACJ,CAGI,IAFA,IAAIgH,EAAW,IAAf,CACInD,EAAcyZ,EAAA,CAAwB,IAAApd,GAAxB,CADlB,CAESmd,EAAa,CAAtB,CAAyBA,CAAzB,EAAuCxZ,CAAA5N,OAAvC,CAA2DonB,CAAA,EAA3D,CAAyE,CACrE,IAAI9b,EAAa8b,CAAA,CAAaxZ,CAAA5N,OAAb,CAAkC4N,CAAA,CAAYwZ,CAAZ,CAAlC,CAA4D,IAC7E,IAAI,CAACjW,EAAA,CAAA7F,CAAA,CAAL,CAA0B,CACtB6F,EAAA,CAAA7F,CAAA,CAAkB6rD,QAAyB,EAAG,CAC1CpmD,CAAA4lD,KAAA,CAAcrvD,CAAd,CAAkByC,CAAlB,CAD0C,CAA9C,CAGA,OAJsB,CAF2C,CAUzEzC,CAAAwI,KAAA,CAAQ,IAAR,CAAc/F,CAAd,CAbJ,CAyBAqtD,SAAA,GAAa,CAAbA,CAAa,CAAC1B,CAAD,CACb,CAEI,IAAI2B,EAAgB,IAAIn9C,CAAJ,CAAU,CAAV,CApqzBXq8C,QAoqzBW,CAAkCe,EAAlC,CACpB,IAAID,CAAAb,KAAA,EAAJ,EAA4B9xD,EAAA,CAAA2yD,CAAA,CAA5B,CAAmD,CAC/C,IAAIE,EAAqBF,CAAAG,IAAA,CAAkBC,EAAlB,CAAzB,CACIC,EAAqBhC,CAAA,CAAeA,CAAA8B,IAAA,CAAkBC,EAAlB,CAAf,CAAkE,SACvFF,EAAJ,EAA0BG,CAA1B,GACI,CAAApnD,GAAA,CAAY,qCAAZ,CAAoDinD,CAApD,CAAyE,OAAzE,CAAmFG,CAAnF,CAAwG,8CAAxG,CAEA,CAAKhC,CAAL,EAAoB2B,CAAAM,MAAA,EAHxB,CAH+C,CAHvD;AA2BA3nD,CAAA4mD,GAAA,CAAAA,QAAO,CAACR,CAAD,CACP,CACmBv1D,IAAAA,EAAf,GAAIu1D,CAAJ,GACIA,CADJ,CACa,IAAAA,EADb,GAC6B,IAAAf,EAAA,CAAiBuC,EAAjB,CAA6CtB,EAD1E,EAQA,IAAIlB,CAAA,IAAAA,EAAJ,CAAA,CAGA,IAAAA,EAAA,EAEA,KAAIv7C,EAAW,CAAA,CAAf,CACIg+C,EAAW,CAAA,CACf,KAAAhC,EAAA,CAAqB,CAAA,CACrB,KAAIH,EAAgB,IAAAA,EAAhBA,EAAsC,IAAIx7C,CAAJ,CAAU,IAAV,CA/szBjCq8C,QA+szBiC,CAE1C,IAAIH,CAAJ,EAAc0B,EAAd,CACIj+C,CAAA,CAAW,CAAA,CADf,KAGK,IAAIu8C,CAAJ,CAAaE,EAAb,CAAwC,CACzC,GAAIZ,CAAAc,KAAA,CAAmB,IAAAnB,EAAnB,CAAJ,CAAyC,CAOrC,IAAAM,EAAA,CAAqB,IAAIz7C,CAAJ,CAAU,IAAV,CA5tzBpBq8C,QA4tzBoB,CAAkCwB,EAAlC,CACjB,KAAApC,EAAAa,KAAA,EAAJ,GACIwB,EAAA,CAAAA,IAAA,CAAiBtC,CAAjB,CAWA,CALAU,CAKA,CALS6B,EAKT,CAAAC,EAAA,CAAA,IAAAvC,EAAA,CAZJ,CAeA,KAAAA,EAAAx7C,IAAA,CAAuBs9C,EAAvB,CA53wBDU,EAAA,EA43wBC,CACA,KAAAxC,EAAAyC,MAAA,EAEA,KAAIC,EAAY,IAAAjC,EAAZiC,EAA2B,CAAC,IAAA7C,EAChC,IAAIY,CAAJ,EAAcwB,EAAd,EAA2CU,EAAA,CAAsB,mCAAtB,CAA4DpjD,EAA5D,CAA4E,iDAA5E,CAA3C,CAA2K,CAEvK,GADA2iD,CACA,CADWnzD,EAAA,CAAAgxD,CAAA,CACX,CAAc,CACV,IAAI6C,EAA+B7C,CAAA8B,IAAA,CAhjzBvCgB,MAgjzBuC,CAAnC,CACIv0D,EAA+ByxD,CAAA8B,IAAA,CAhjzBvCgB,MAgjzBuC,CAC/BD,EAAJ,GA9izBJE,IA+izBQ,EAAIF,CAAJ,CACI7C,CAAAc,KAAA,CAAmBvyD,CAAnB,CADJ,EA9izBRw0D,OAojzBY,EAAIF,CAAJ;AA9izBZG,kBA8izBY,EAAkCz0D,CAAlC,EACI,IAAAqM,GAAA,CAAY,SAAZ,CAAwBrM,CAAxB,CACA,CAljzBhBy0D,uBAkjzBgB,EAAIz0D,CAAJ,GAmoB5B00D,EAAA,CAAwBC,EAAxB,CAAoD,EAApD,CACA,CApoB8DC,IAooB9D7C,EAAA,CAAe,IApoBa,CAFJ,EAII,IAAAxlD,EAAA,CAAa+nD,CAAb,CAAqB,IAArB,CAA4Bt0D,CAA5B,CAOJ,CADAi0D,EAAA,CAAAxC,CAAA,CACA,CAAIA,CAAAc,KAAA,EAAJ,EACIqB,CACA,CADWnzD,EAAA,CAAAgxD,CAAA,CACX,CAAA2C,CAAA,CAAY,CAAA,CAFhB,EAIIR,CAJJ,CAIe,CAAA,CArBnB,CADJ,CAHU,CAoCVQ,CAAJ,EAAejB,EAAA,CAAAA,IAAA,CAAmBS,CAAA,CAAUnC,CAAV,CAA0B,IAA7C,CAtCwJ,CAA3K,IA2CQU,EAAJ,EAAc6B,EAAd,EAA2CvC,CAAAiC,MAAA,EAtEV,CAAzC,IA6EIP,GAAA,CAAAA,IAAA,CAEJ,QAAO,IAAA/B,EACP,QAAO,IAAAK,EAjFkC,CAwFzC9nD,CAAAA,CAAcyZ,EAAA,CAAwB,IAAApd,GAAxB,CAClB,KAASmd,CAAT,CAAsB,CAAtB,CAAyBA,CAAzB,CAAsCxZ,CAAA5N,OAAtC,CAA0DonB,CAAA,EAA1D,CACQ9b,CACJ,CADgBsC,CAAA,CAAYwZ,CAAZ,CAChB,CAAI9b,CAAJ,GAAkB,IAAlB,EAA0BA,CAA1B,EAAuC,IAAAJ,EAAvC,GACI2sD,CADJ,CACeiB,EAAA,CAAAA,IAAA,CAAkBxtD,CAAlB,CAA6BoqD,CAA7B,CAA4C77C,CAA5C,CAAsDg+C,CAAtD,CADf,CAUAnxD,EAAAA,CAAS,CAACgvD,CAAD,CAAgBU,CAAhB,CAAwByB,CAAxB,CAETzB,EAAJ,EAAc0B,EAAd,CACI,IAAAnB,KAAA,CAAU,IAAAoC,GAAV,CAA4BryD,CAA5B,CADJ,CAIA,IAAAqyD,GAAA,CAAiBryD,CAAjB,CAxHA,CATJ,CA8IAoyD;QAAA,GAAY,CAAZA,CAAY,CAACxtD,CAAD,CAAYoqD,CAAZ,CAA2B77C,CAA3B,CAAqCg+C,CAArC,CACZ,CACI,GAAI,CAACvsD,CAAAf,MAAAK,EAAL,CAA8B,CAM1BU,CAAAf,MAAAK,EAAA,CAA0B,CAAA,CAE1B,KAAIpG,EAAO,IAEX,IAAI,CA0EA,GAzEIqzD,CAyEA,IAxEArzD,CAwEA,CAxEOkxD,CAAA8B,IAAA,CAAkBlsD,CAAArB,GAAlB,CAwEP,IA5DIzF,CA4DJ,CA5DWkxD,CAAA8B,IAAA,CAAkBlsD,CAAArB,GAAAtM,QAAA,CAAqB,aAArB,CAAoC,GAApC,CAAlB,CA4DX,GA7CgB,QA6ChB,GA7CA,MAAO6G,EA6CP,GA7C0BA,CA6C1B,CA7CiC,IA6CjC,EAtCA,CAAC8G,CAAAmG,GAAA,CAAkBjN,CAAlB,CAAwBqV,CAAxB,CAsCD,EAtCsCrV,CAsCtC,GA/8tBZM,CAAA,CA26tB4B,8BA36tB5B,CA26tB6DwG,CAAAnJ,KA36tB7D,CA48tBY,CAvBI,CAAAozD,EAAJ,EAAuB,CAAC,CAAAE,EAAxB,EACIC,CAAAiC,MAAA,EAntvBhB,CAotvBgB,CAAAvB,EAptvBhB,CAotvB8BE,EAptvB9B,CAAIvzD,MAAJ,EAAYA,MAAAC,SAAAg2D,OAAA,EAktvBA,EASI,CAAAnD,EATJ,CASyB,CAAA,CAczB,CARAvqD,CAAAmG,GAAA,CAAkB,IAAlB,CAQA,CAAAomD,CAAA,CAAW,CAAA,CAGX,EAAA,CAACh+C,CAAD,EAAavO,CAAAnB,GAAjB,CAAoC,CAChC,IAAI8uD,EAAa3tD,CAAAnB,GAAAhF,MAAA,CAAwB,GAAxB,CACjB,KAAShJ,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoB88D,CAAAj5D,OAApB,CAAuC7D,CAAA,EAAvC,CACImP,CAAAxI,OAAA,CAAiBm2D,CAAA,CAAW98D,CAAX,CAAjB,CAH4B,CA1EpC,CAiFJ,MAAO0G,CAAP,CAAY,CAt9tBhBiC,CAAA,CAu9tBwB,4BAv9tBxB,CAu9tBuDwG,CAAAnJ,KAv9tBvD,CAu9tBwE,IAv9tBxE,CAu9tB+EU,CAAAkC,QAv9tB/E,CAu9tB6F,GAv9tB7F,CAs9tBgB,CA3Fc,CA+F9B,MAAO8yD,EAhGX;AA2GA7nD,CAAA+oD,GAAA,CAAAA,QAAW,CAACryD,CAAD,CACX,CACI,IAAIgvD,EAAgBhvD,CAAA,CAAO,CAAP,CAApB,CACImT,EAAwB,CAAxBA,CAAYnT,CAAA,CAAO,CAAP,CACZmxD,EAAAA,CAAWnxD,CAAA,CAAO,CAAP,CAMf,KAAAkvD,EAAA,CAAoB,CAAA,CACpB,KAAArrD,MAAAK,EAAA,CAAqB,CAAA,CACrB,KAAIsuD,EAAe,IAAA9uD,EAAA,MACf8uD,EAAJ,GAAkBA,CAAAxmD,YAAlB,CAA6C,UAA7C,CAMI,KAAAxH,EAAJ,GAII4tD,EAAA,CAAAA,IAAA,CAAkB,IAAA5tD,EAAlB,CAA4BwqD,CAA5B,CAA2C77C,CAA3C,CAAqDg+C,CAArD,CAEA,CADA17C,CAAA,CAAAA,IAAA,CAAqB,EAArB,CACA,CAAA,IAAAjR,EAAA2Z,GAAA,EANJ,CAaI,KAAAgxC,EAAJ,GACImC,EAAA,CAAAA,IAAA,CAAiBtC,CAAjB,CACA,CAAAA,CAAAiC,MAAA,EAFJ,CAKI,EAAC99C,CAAL,EAAiB,IAAA87C,EAAjB,GACI,IAAAA,EAAAgC,MAAA,EACA,CAAA,OAAO,IAAAhC,EAFX,CAKA,KAAAP,EAAA,CAAoB,CAzCxB,CA8EA4C;QAAA,GAAW,CAAXA,CAAW,CAACtC,CAAD,CACX,CACI,GAAI4C,EAAA,CAAsB,mCAAtB,CAA4DpjD,EAA5D,CAA4E,6DAA5E,CAA4IA,EAA5I,CAAqM,wCAArM,CAAJ,CAAA,CACoD4gD,IAAAA,EAAAA,CAAAA,GAhb7C,EAAA,CAgbuDqD,CAhbvDnD,EAAA,EAAgB,EAgb6E,EAAA,CAAAN,CAAAzlD,SAAA,EAv/vBpG,KAAImpD,EAAW,EACfA,EAAA,IAAA,CAs/vBmBlkD,EAr/vBnBkkD,EAAA,IAAA,CArhES7C,QAshET6C,EAAA,IAAA,CAAgCl3D,CAChCk3D,EAAA,KAAA,CAAiCC,CACjCD,EAAA,KAAA,CAt3DYE,KAu3DZF,EAAA,KAAA,CAAiCG,CAEjC1yB,GAAA,CADiB2yB,mCACjB,CAA4BJ,CAA5B,CAAsC,CAAA,CAAtC,CA8+vBA,CADJ;AAqCAra,QAAA,GAAQ,CAARA,CAAQ,CAACptC,CAAD,CAAQC,CAAR,CACR,CACI,IACIktC,EAAS,MAMb,IAAI,CAAAsW,EAAJ,CACI,MAAO,KAEX,EAAAA,EAAA,EAEA,KAAIM,EAAgB,IAAIx7C,CAAJ,CAAU,CAAV,CA3j0BXq8C,QA2j0BW,CAApB,CACIc,EAAgB,IAAIn9C,CAAJ,CAAU,CAAV,CA5j0BXq8C,QA4j0BW,CAAkCe,EAAlC,CADpB,CAGImC,EA9sxBGtB,EAAA,EA+sxBPd,EAAAl9C,IAAA,CAAkBs9C,EAAlB,CAAiDgC,CAAjD,CACA/D,EAAAv7C,IAAA,CAAkBs9C,EAAlB,CAAiDgC,CAAjD,CACA/D,EAAAv7C,IAAA,CAAkBu/C,EAAlB,CAjk0BSnD,QAik0BT,CACAb,EAAAv7C,IAAA,CAAkBw/C,EAAlB,CAnhwBQ52D,MAAA,CAAQA,MAAAC,SAAA42D,KAAR,CAA+B,IAmhwBvC,CACAlE,EAAAv7C,IAAA,CAAkB0/C,EAAlB,CAhgwBQ92D,MAAA,CAAQA,MAAAsD,UAAAD,UAAR,CAAqC,EAggwB7C,CAMA,IAAI,CAAA8E,EAAJ,EAAgB,CAAAA,EAAAwG,GAAhB,CAAoC,CAC5BE,CAAJ,GACQD,CACJ,GADW,CAAAzG,EAAAX,MAAAsa,GACX,CADsC,CAAA3Z,EAAAX,MAAA+Q,EACtC,EAAAK,CAAA,CAAA,CAAAzQ,EAAA,CAFJ,CAIA,KAAA1G,EAAO,CAAA0G,EAAAwG,GAAA,CAAmBC,CAAnB,CAA0BC,CAA1B,CACa,SAApB,GAAI,MAAOpN,EAAX,EAA8BkxD,CAAAv7C,IAAA,CAAkB,CAAAjP,EAAAjB,GAAlB,CAA+BzF,CAA/B,CAC1BoN,EAAJ,GACI,CAAA1G,EAAAX,MAAAK,EACA,CADyB,CAAA,CACzB,CAAa,CAAA,CAAb,GAAIpG,CAAJ,GAAoBs6C,CAApB,CAA6B,IAA7B,CAFJ,CAPgC,CAahClxC,CAAAA,CAAcyZ,EAAA,CAAwB,CAAApd,GAAxB,CAClB,KAAK,IAAImd,EAAa,CAAtB,CAAyBA,CAAzB,CAAsCxZ,CAAA5N,OAAtC,CAA0DonB,CAAA,EAA1D,CAAwE,CACpE,IAAI9b,EAAYsC,CAAA,CAAYwZ,CAAZ,CACZ9b,EAAAf,MAAAK,EAAJ,GACQU,CAAAoG,GAIJ,GAHIlN,CACA,CADO8G,CAAAoG,GAAA,CAAoBC,CAApB,CAA2BC,CAA3B,CACP,CAAoB,QAApB,GAAI,MAAOpN,EAAX,EAA8BkxD,CAAAv7C,IAAA,CAAkB7O,CAAArB,GAAlB;AAAgCzF,CAAhC,CAElC,EAAIoN,CAAJ,GACItG,CAAAf,MAAAK,EACA,CAD0B,CAAA,CAC1B,CAAa,CAAA,CAAb,GAAIpG,CAAJ,GAAoBs6C,CAApB,CAA6B,IAA7B,CAFJ,CALJ,CAFoE,CAcpEA,CAAJ,GACQltC,CAAJ,EAEQkoD,CAmCJ,CApCIC,CAoCJ,CApCa,CAAA,CAoCb,CAlCIpoD,CAAJ,EACQ,CAAAqkD,EAGJ,EAFIgE,EAAA,CAAAA,CAAA,CAAqB,CAAAhE,EAArB,CAAmCN,CAAAzlD,SAAA,EAAnC,CAEJ,CAAKonD,CAAAe,MAAA,EAAL,EAA+B1C,CAAA0C,MAAA,EAA/B,GACItZ,CAOA,CAPS,IAOT,CAAAib,CAAA,CAASD,CAAT,CAAqB,CAAA,CARzB,CAJJ,EA6BQ,CAAA1D,EA7BR,GA8BQ2D,CACA,CADS,CAAA,CACT,CAAAD,CAAA,CAAa,CAAA1D,EAAb,EAA4B6D,EA/BpC,CAkCA,CAAIF,CAAJ,EACIrE,CAAAiC,MAAA,CAAoBmC,CAApB,CAtCR,EAyCIhb,CAzCJ,CAyCa4W,CAAAzlD,SAAA,EA1CjB,CA8CI2B,EAAJ,GACI,CAAArH,MAAAK,EACIsuD,CADiB,CAAA,CACjBA,CAAAA,CAAAA,CAAe,CAAA9uD,EAAA,MAFvB,IAGsB8uD,CAAAxmD,YAHtB,CAGiD,OAHjD,CAMA,EAAA0iD,EAAA,CAAoB,CAEpB,OAAOtW,EA7GX;AA+HA9uC,CAAA4I,MAAA,CAAAA,QAAK,EACL,CACI,IAAArO,MAAAqO,MAAA,CAAmB,CAAA,CACf,KAAAzN,EAAJ,EAAgB,IAAAA,EAAAyN,MAAhB,GACI7G,EAAA,CAAAA,IAAA,CAAkB,YAAlB,CAAiC,IAAA5G,EAAAhJ,KAAjC,CACA,CAAA,IAAAgJ,EAAAyN,MAAA,EAFJ,CAII,KAAA1N,EAAJ,EAAgB,IAAAA,EAAA0N,MAAhB,GACI7G,EAAA,CAAAA,IAAA,CAAkB,YAAlB,CAAiC,IAAA7G,EAAA/I,KAAjC,CACA,CAAA,IAAA+I,EAAA0N,MAAA,EAFJ,CAKA,KADA,IAAIhL,EAAcyZ,EAAA,CAAwB,IAAApd,GAAxB,CAAlB,CACSmd,EAAa,CAAtB,CAAyBA,CAAzB,CAAsCxZ,CAAA5N,OAAtC,CAA0DonB,CAAA,EAA1D,CAAwE,CACpE,IAAI9b,EAAYsC,CAAA,CAAYwZ,CAAZ,CACZ9b,EAAJ,GAAkB,IAAlB,EAA0BA,CAA1B,GAAwC,IAAAH,EAAxC,EAAoDG,CAApD,GAAkE,IAAAJ,EAAlE,EAA8EI,CAAAsN,MAA9E,GACI7G,EAAA,CAAAA,IAAA,CAAkB,YAAlB,CAAiCzG,CAAAnJ,KAAjC,CACA,CAAAmJ,CAAAsN,MAAA,EAFJ,CAFoE,CAOxE,IAAArO,MAAAqO,MAAA,CAAmB,CAAA,CACnBuD,EAAA,CAAAA,IAAA,CAAqB,EAArB,CAnBJ,CAkCAnM,EAAA8C,MAAA,CAAAA,QAAK,CAACrL,CAAD,CAAKwc,CAAL,CACL,CAEI,IADA,IAAIrW,EAAcyZ,EAAA,CAAwB,IAAApd,GAAxB,CAAlB,CACSmd,EAAa,CAAtB,CAAyBA,CAAzB,CAAsCxZ,CAAA5N,OAAtC,CAA0DonB,CAAA,EAA1D,CAAwE,CACpE,IAAI9b,EAAYsC,CAAA,CAAYwZ,CAAZ,CACM,MAAtB,EAAI9b,CAAAnJ,KAAJ,EAA+BmJ,CAA/B,GAA6C,IAA7C,EACIA,CAAAwH,MADJ,EAEIxH,CAAAwH,MAAA,CAAgBrL,CAAhB,CAAoBwc,CAApB,CAJgE,CAOxE9H,CAAA,CAAAA,IAAA,CAAqB,EAArB,CATJ,CAwBAnM;CAAA8I,KAAA,CAAAA,QAAI,CAACrR,CAAD,CAAKwc,CAAL,CACJ,CAEI,IADA,IAAIrW,EAAcyZ,EAAA,CAAwB,IAAApd,GAAxB,CAAlB,CACSmd,EAAa,CAAtB,CAAyBA,CAAzB,CAAsCxZ,CAAA5N,OAAtC,CAA0DonB,CAAA,EAA1D,CAAwE,CACpE,IAAI9b,EAAYsC,CAAA,CAAYwZ,CAAZ,CACM,MAAtB,EAAI9b,CAAAnJ,KAAJ,EAA+BmJ,CAA/B,GAA6C,IAA7C,EACIA,CAAAwN,KADJ,EAEIxN,CAAAwN,KAAA,CAAerR,CAAf,CAAmBwc,CAAnB,CAJgE,CAOxE9H,CAAA,CAAAA,IAAA,CAAqB,EAArB,CATJ,CAoCAA;QAAA,EAAc,CAAdA,CAAc,CAACwM,CAAD,CACd,CASI,GAAI,CAAAzd,EAAJ,CAAA,CAAcA,IAAAA,EAAAA,CAAAA,EAAAA,CAAuB,EAAAyd,CAAA,EAAW,CAAlCzd,CAt3lBV+c,EAAe,CAAA7d,EAAA,MACf6d,EAAJ,GACmB,CADnB,EACQU,CADR,EArZqBuxC,EAqZrB,GACyB,CAAApjD,GADzB,EAC+C6R,CAD/C,KAEQV,CAAAvV,YACA,CAD2BynD,CA2J1B5vD,MAAA+Q,EAAD,CA3J2B6+C,CA2JJn0C,EAAAwB,QAAA,CAAiB,CAAjB,CAAvB,CAA6C,KAA7C,CAAsD,SA1JtD,CAAA,CAAA1Q,GAAA,CAAqB,CAH7B,CAq3lBA,CACA,GAAI,CAAAqC,EAAJ,GAAgBA,CA1vpBZpC,CA0vpBYoC,CAAAA,EA1vpBZpC,CA0vpBqC,CA1vpBrCA,CA0vpBqC4R,CA1vpBrC5R,EA0vpBgD,CA1vpBhDA,CAAA,CAAAA,EA0vpBJ,EA1vpBoB,CAEZggC,CAAAA,CAAW,CAAA7rC,EAgtDZX,MAAA+Q,EA/sDC8+C,EAAAA,CAi3GD,CAAC,EAj3GW,CAAAlvD,EAi3GT6f,EAAF,CA/nJIqB,CA+nJJ,CAv2GA,IAAe,CAAf,EAAIzD,CAAJ,EA7jCauxC,EA6jCb,GAAqB,CAAApjD,EAArB,EAA2C6R,CAA3C,EAA2E,CAwjG5E3L,CAAAA,CAvjG6BA,CAAA9R,EAujG7B8R,EA5oHP,IAqlBYq9C,CArlBRjwD,EAAA,GAAJ,CAA2B,CAEvB,IAAI8hC,EAmlBImuB,CAnlBIpvD,EAARihC,EAmlBImuB,CAnlBgBpvD,EAAAihC,EAApBA,EAAsC,CAC1C2hB,EAAA,CAASA,CAAT,EAAmB,CAEfyM,EAAA,CAAgB,CAAT,EAAApuB,CAAA,CAAY/rB,EAAA,CAAU0tC,CAAV,CAPFnvD,IAAAA,EAOE,CAAZ,CAAqCgjB,CAAA,CAAUmsC,CAAV,CAP3BnvD,IAAAA,EAO2B,CAglBxC27D,EAtkBJjwD,EAAA,GAAAsI,YAAJ,EAAyC4nD,CAAzC,GAskBQD,CAtkBuCjwD,EAAA,GAAAsI,YAA/C,CAAmF4nD,CAAnF,CAfuB,CAslBf,CAAAxjD,EAAA,CAAqB,CAFkD,CAW5D,EAAf,CAAI6R,CAAJ,CACI,CAAA3R,EADJ,CACmB,CAAA9L,EA4iGpB8R,EA7iGC,CAEqB,CAFrB,CAEW2L,CAFX,EAE0BouB,CAF1B,EAEsC,CAACqjB,CAFvC,GAGI,CAAApjD,EAHJ,CAGmB,CAAA9L,EAkkGpB4f,GArkGC,CAMAvQ,GAAA,CAAAA,CAAA,CAAgB,CAAAvD,EAAhB,CACA+B,GAAA,CAAAA,CAAA,CAAgB,CAAA5B,EAAhB,CA/BY,CAgvpBxB;AAuBAnH,CAAAvC,GAAA,CAAAA,QAAU,CAACyC,CAAD,CAAYC,CAAZ,CAAsB/D,CAAtB,CACV,CACI,IAAI2E,EAAW,IAEf,QAAQZ,CAAR,EACA,KAAK,OAAL,CAKI,MAJA,KAAA/F,EAAA,CAAc+F,CAAd,CAIO,CAJmB/D,CAInB,CAHPA,CAAAgE,QAGO,CAHW+W,QAAqB,EAAG,CACtCpW,CA2QHqkD,EAAL,GA3QQrkD,CA4QCxG,MAAAK,EAAL,CAGIm0C,EAAA,CA/QAhuC,CA+QA,CAAc,CAAA,CAAd,CAAqB,CAAA,CAArB,CAHJ,CA5QIA,CA6QA4lD,KAAA,CA7QA5lD,CA6QU6lD,GAAV,CAFR,CA5Q8C,CAGnC,CAAA,CAAA,CAEX,MAAK,OAAL,CAKI,MAJA,KAAAxsD,EAAA,CAAc+F,CAAd,CAIO,CAJmB/D,CAInB,CAHPA,CAAAgE,QAGO,CAHW+W,QAAqB,EAAG,CA2R9C,GA1RQpW,CA0RHxG,MAAAK,EAAL,EAA2BwqD,CA1RnBrkD,CA0RmBqkD,EAA3B,CAWA,GArSQrkD,CAqSJqlD,EAAJ,EAAmB,CArSXrlD,CAqSYukD,EAApB,CAAsC,CAKlC,IAAI3jD,EAA2D2mD,EAAA,CAAsB,mCAAtB,CAA4DpjD,EAA5D,CAA4E,0EAA5E,CAC/D6pC,GAAA,CA3SIhuC,CA2SJ,CAAcY,CAAd,CAAqB,CAAA,CAArB,CAaI,EAACA,CAAL,EAxTIZ,CAwTUwkD,EAAd,CAv7wBAxyD,MAu7wBA,EAv7wBQA,MAAAC,SAAAg2D,OAAA,EAu7wBR,CAxTIjoD,CA6TJ6lD,GAAA,CAAaN,EAAb,CAxBkC,CAAtC,IArSQvlD,EAgUJ6H,MAAA,EACA,CAjUI7H,CAiUA7F,EAAJ,EAAgB,CAjUZ6F,CAiUa9F,EAAjB,EAjUI8F,CAiUuB7F,EAAA2Z,GAAA,EAlUe,CAGnC,CAAA,CAAA,CAQX,MAAK,MAAL,CAMI,GAAIsmC,EAAA,CAAaxkB,EAAA,EAAb,CAA4B,UAA5B,CAAJ,CASIv6B,CAAAU,WAAAytD,YAAA,CAAoDnuD,CAApD,CATJ;IA6CA,OAjCA,KAAAhC,EAAA,CAAc+F,CAAd,CAiCO,CAjCmB/D,CAiCnB,CAhCPA,CAAAgE,QAgCO,CAhCW+W,QAAoB,EAAG,CACrC,IAAI6uC,EAAUC,EAAA,CAAAllD,CAAA,CAAqB,CAAA,CAArB,CACd,IAAIilD,CAAJ,CAAa,CAQT,IAAIrkD,EAAQ,CAAC,EAAEZ,CAAAqlD,EAAF,EAAqB,CAACrlD,CAAAukD,EAAtB,EAA8CvkD,CAAAwkD,EAA9C,CAAb,CACIzW,EAASC,EAAA,CAAAhuC,CAAA,CAAkBY,CAAlB,CACTA,EAAJ,CACIqoD,EAAA,CAAAjpD,CAAA,CAAyBilD,CAAzB,CAAkClX,CAAlC,CADJ,CAGI/tC,CAAAT,GAAA,CAAgB,0CAAhB,CAbK,CAFwB,CAgClC,CAAA,CAAA,CAxEX,CA6EA,MAAO,CAAA,CAhFX,CAqGA2lD;QAAA,GAAW,CAAXA,CAAW,CAACuE,CAAD,CACX,CACI,IAAIxE,EAAU,CAAAA,EACTA,EAAL,GAEI,CADAA,CACI,CADMyE,EAAA,CAAwB7B,EAAxB,CACN,CAAY/3D,IAAAA,EAAZ,GAAAm1D,CAAJ,EACQ,CAACA,CADT,EACoBwE,CADpB,GAr5uBAzzB,CAIJivB,CAJgB,IAIhBA,CAHIjzD,MAGJizD,GAFIjvB,CAEJivB,CAFgBjzD,MAAA23D,OAAA,CA05uB2B1uD,wIA15uB3B,CAA+C,EAA/C,CAEhBgqD,EAAA,CAAAA,CAAOjvB,CAi5uBH,KASYivB,CATZ,CASsB2E,EAAA,CAAAA,CAAA,CAAkB3E,CAAlB,CATtB,GAU0B,CAAA1lD,GAAA,CAAY,yBAAZ,CAV1B,EAaWkqD,CAbX,EAcI,CAAAlqD,GAAA,CAAY,wCAAZ,CAhBR,CAmBA,OAAO0lD,EArBX;AA+BA2E,QAAA,GAAY,CAAZA,CAAY,CAAC3E,CAAD,CACZ,CACI,CAAAA,EAAA,CAAe,IAIXrzD,EAAAA,CAAWkkC,EAAA,CADAF,EAAA,EACA,CADmH,wCACnH,CADyHqvB,CACzH,CAEf,KAAIjvB,EAAYpkC,CAAA,CAAS,CAAT,CAChB,IAAI,CAFaA,CAAAO,CAAS,CAATA,CAEjB,EAAmB6jC,CAAnB,CACI,GAAI,CACApkC,CACA,CADWgC,IAAA,CAAK,GAAL,CAAWoiC,CAAX,CAAuB,GAAvB,CACX,CAAIpkC,CAAAi4D,KAAJ,EAjv0BInC,IAiv0BJ,EAAqB91D,CAAAi4D,KAArB,GACIjC,EAAA,CAAwBC,EAAxB,CAAoDj2D,CAAA6B,KAApD,CAEA,CAAA,CAAAwxD,EAAA,CAAerzD,CAAA6B,KAHnB,CAFA,CASF,MAAOzI,CAAP,CAAU,CA5+uBhB+I,CAAA,CA6+uBwB/I,CAAAgJ,QA7+uBxB,CA6+uBoC,IA7+uBpC,CA6+uB2CgiC,CA7+uB3C,CA6+uBuD,GA7+uBvD,CA4+uBgB,CAMhB,MAAO,EAAAivB,EAxBX,CAiCAS,QAAA,GAAkB,CAAlBA,CAAkB,CAClB,CACI,IAAIlB,EAAa,IACb,EAAAS,EAAJ,GAIIT,CAJJ,CAIiB5uB,EAAA,EAJjB,CAIkI,sCAJlI,CAIwI,CAAAqvB,EAJxI,CAImL,eAJnL,CAIyL6E,EAAA,CAAU,CAAV,CAr90BhLtE,QAq90BgL,CAJzL,CAUA,OAAOhB,EAZX;AAsBAyE,QAAA,GAAe,CAAfA,CAAe,CAAChE,CAAD,CAAUlX,CAAV,CACf,CAOI,GAAIA,CAAJ,CAAY,CA0CZ,IAAIsa,EAAW,CAh20BH0B,IAQAC,OAw10BG,CAEf3B,EAAA,KAAA,CAxCyCpD,CAyCzCoD,EAAA,MAAA,CAAgCyB,EAAA,CAzCbG,CAyCa,CA1h1BvBzE,QA0h1BuB,CAChC6C,EAAA,KAAA,CA1CkDta,CA+C1Cn8C,EAAAA,CAAWkkC,EAAA,CAJJF,EAAA,EAII,CA320BPs0B,cA220BO,CAA0B7B,CAA1B,CACXryB,EAAAA,CAAYpkC,CAAA,CAAS,CAAT,CAChB,IAAIA,CAAA,CAAS,CAAT,CAAJ,CAAiB,CACb,GAAIokC,CAAJ,CAAe,CACX,IAAI5qC,EAAI4qC,CAAArpC,QAAA,CAAkB,IAAlB,CACA,EAAR,CAAIvB,CAAJ,GAAW4qC,CAAX,CAAuBA,CAAAjpC,OAAA,CAAiB,CAAjB,CAAoB3B,CAApB,CAAvB,CACK4qC,EAAArpC,QAAA,CAAkB,SAAlB,CAAL,GAAmCqpC,CAAnC,CAA+CA,CAAAjpC,OAAA,CAAiB,CAAjB,CAA/C,CAHW,CAKfipC,CAAA,CAAY,UAAZ,CAA6CpkC,CAAA,CAAS,CAAT,CAA7C,CAAqF,WAArF,CAA6FokC,CAA7F,CAAyG,IAN5F,CASjB,CAAA,CAAOtiC,IAAAC,MAAA,CAAWqiC,CAAX,CAzDHpkC,EAAJ,EA3y0BQ81D,IA2y0BR,EAAgB91D,CAAA,KAAhB,CACI,CAAA2N,GAAA,CAAY,+BAAZ,CADJ,CAEWwuC,CAFX,GAGQsT,CAnHZ,CAmHsBzvD,CAnHtB,EAmHkCA,CAAA,KAnHlC,EAlr0BY+1D,8BAkr0BZ,CAqHYtG,CArHZ,CA1r0BYqG,OA8y0BJ,EAAI91D,CAAA,KAAJ,CACa,SADb,CACyByvD,CADzB,CAGa,QAHb,CAGwBzvD,CAAA,KAHxB,CAGqD,IAHrD,CAG4DyvD,CAvHpE,CAyHQ,CAAA9hD,GAAA,CAAY8hD,CAAZ,CAzHR,CADAuG,EAAA,CAAwBC,EAAxB,CAAoD,EAApD,CACA,CA0HQC,CA1HR7C,EAAA,CAAe,IAgHX,CALQ,CAPhB;AAsLArvC,QAAA,GAAQ,CAARA,CAAQ,CAACu0C,CAAD,CACR,CACI,GAAI,CAAAzc,EAAJ,CAAuB,CAAA,IAMfvhD,EAAI,CANW,CAMRC,EAAI,CACX,EAAC+9D,CAAL,EAAgBn4D,MAAhB,GACI7F,CACA,CADI6F,MAAAoxC,QACJ,CAAAh3C,CAAA,CAAI4F,MAAAqxC,QAFR,CAKA,EAAAqK,EAAApK,MAAA,EAEI,EAAC6mB,CAAL,EAAgBn4D,MAAhB,EACIA,MAAAuxC,SAAA,CAAgBp3C,CAAhB,CAAmBC,CAAnB,CAfe,CAD3B,CA2KJ,IAAA46D,GAAgC,UAAhC,CACAT,GAAgC,UADhC,CAEAG,GAAgC,WAFhC,CAGAiC,GAAgC,SAHhC,CAIAC,GAAgC,KAJhC,CAKAE,GAAgC,SALhC,CAMAjB,GAAgC,MANhC,CAaAd,GAAiC,EAbjC,CAcAxB,GAAiC,CAdjC,CAeAsB,GAAiC,CAfjC,CAgBAK,GAAiC,CAhBjC,CAiBAgC,GAAiC,CAKjCp8C,GAAA,CApKIZ,QAAW,EACX,CAQI,IAFA,IAAIk+C,EAAatuD,CAAA,CAA6BsQ,QAA7B,CAAuCxQ,CAAvC,CAAwD,UAAxD,CAAjB,CAESyuD,EAAW,CAApB,CAAuBA,CAAvB,CAAkCD,CAAAn7D,OAAlC,CAAqDo7D,CAAA,EAArD,CAAiE,CAE7D,IAAIC,EAAWF,CAAA,CAAWC,CAAX,CAAf,CACIrG,EAAevnD,EAAA,CAA4B6tD,CAA5B,CAEfC,EAAAA,CAAczuD,CAAA,CAA6BwuD,CAA7B,CAAuC1uD,CAAvC,CAAuD,UAAvD,CAElB,KAAK,IAAI4uD,EAAY,CAArB,CAAwBA,CAAxB,CAAoCD,CAAAt7D,OAApC,CAAwDu7D,CAAA,EAAxD,CAAqE,CAEjE,IAAIC,EAAYF,CAAA,CAAYC,CAAZ,CAAhB,CACIzG,EAAgBtnD,EAAA,CAA4BguD,CAA5B,CAMhBzqD,EAAAA,CAAW,IAAI8jD,EAAJ,CAAkBC,CAAlB,CAAiCC,CAAjC,CAA+C,CAAA,CAA/C,CAWfx3C,GAAA,CAAgCxM,CAAhC,CAA0CyqD,CAA1C,CAKIzqD,EAAAmkD,EAAJ,EAAyBnkD,CAAA4lD,KAAA,CAAc5lD,CAAA6lD,GAAd,CAzBwC,CAPR,CARrE,CAmKJ,CAv0wBQhuD;EAAA,KAAAxD,KAAA,CA0twBJq2D,QAAW,EACX,CAEI,IADA,IAAIH,EAAczuD,CAAA,CAA6BsQ,QAA7B,CAAuCxQ,CAAvC,CAAuD,UAAvD,CAAlB,CACS4uD,EAAY,CAArB,CAAwBA,CAAxB,CAAoCD,CAAAt7D,OAApC,CAAwDu7D,CAAA,EAAxD,CAAqE,CAEjE,IAAIzG,EAAgBtnD,EAAA,CADJ8tD,CAAAE,CAAYD,CAAZC,CACI,CAEpB,IADIzqD,CACJ,CAD6CpB,EAAA,CAA6B,UAA7B,CAAyCmlD,CAAA,GAAzC,CAC7C,CAEI/jD,CAAAxG,MAAAM,GAWA,CAX2B,CAAA,CAW3B,CAAIkG,CAAA6kD,EAAJ,EAA6B,CAAC7kD,CAAAxG,MAAAK,EAA9B,EAIImG,CAAA6lD,GAAA,CAAiBkB,EAAjB,CArByD,CAFzE,CA3twBI,CAYAlvD,GAAA,KAAAxD,KAAA,CAswwBJs2D,QAAW,EACX,CAEI,IADA,IAAIJ,EAAczuD,CAAA,CAA6BsQ,QAA7B,CAAuCxQ,CAAvC,CAAuD,UAAvD,CAAlB,CACS4uD,EAAY,CAArB,CAAwBA,CAAxB,CAAoCD,CAAAt7D,OAApC,CAAwDu7D,CAAA,EAAxD,CAAqE,CAEjE,IAAIzG,EAAgBtnD,EAAA,CADJ8tD,CAAAE,CAAYD,CAAZC,CACI,CAEpB,IADIzqD,CACJ,CAD6CpB,EAAA,CAA6B,UAA7B,CAAyCmlD,CAAA,GAAzC,CAC7C,CAKI/jD,CAAAxG,MAAAM,GAMA,CAN2B,CAAA,CAM3B,CAAIkG,CAAAxG,MAAAK,EAAJ,EAMIm0C,EAAA,CAAAhuC,CAAA,CAAkB,EAAGqlD,CAAArlD,CAAAqlD,EAAH,EAAuBrlD,CAAAukD,EAAvB,CAAlB,CAAgE,CAAA,CAAhE,CArByD,CAFzE,CAvwwBI,CA+1wBJzrD,SAzBEqQ,EAyBS,CAAC5O,CAAD,CAAYqwD,CAAZ,CAAsB57D,CAAtB,CACX,CACI,IAAAkK,GAAA,CAAUqB,CAAArB,GAEV,KAAA2xD,EAAA,CAAY,EACZ,KAAA3hD,EAAA,CAAa,EACb,KAAAwuB,EAAA,CAAe,IAAAozB,EAAf,CAA8B,CAAA,CAC9B,KAAAC,IAAA,CAAWjB,EAAA,CAAUvvD,CAAV,CAAqBqwD,CAArB,CAA+B57D,CAA/B,CACXm4D,GAAA,CAAAA,IAAA,CAAY5sD,CAAAvB,GAAZ,CAPJ,CAiBA,CAAA,CA751BJ,CAAAgyD,UA651BI/rD,EAAAmK,IAAA,CAAAA,QAAG,CAAClQ,CAAD,CAAKzF,CAAL,CACH,CACI,GAAI,CACA,IAAAyV,EAAA,CAAWhQ,CAAX,CAAA,CAAiBzF,CADjB,CAEF,MAAMzI,CAAN,CAAS,EAHf,CAeAiU;CAAAwnD,IAAA,CAAAA,QAAG,CAACvtD,CAAD,CACH,CACI,MAAO,KAAAgQ,EAAA,CAAWhQ,CAAX,CAAP,EAAyB,IAD7B,CAUA+F,EAAAxL,KAAA,CAAAA,QAAI,EACJ,CACI,MAAO,KAAAyV,EADX,CAcAjK,EAAAwmD,KAAA,CAAAA,QAAI,CAACoF,CAAD,CACJ,CACI,MAAIA,EAAJ,EACI,IAAAA,EAGO,CAHKA,CAGL,CAFP,IAAAnzB,EAEO,CAFQ,CAAA,CAER,CADP,IAAAozB,EACO,CADQ,CAAA,CACR,CAAA,CAAA,CAJX,EAMI,IAAApzB,EAAJ,CAIW,CAAA,CAJX,CAMIuzB,EAAA,EAAJ,GACQn/D,CADR,CACY49D,EAAA,CAAwB,IAAAqB,IAAxB,CADZ,GAGQ,IAAAF,EACA,CADY/+D,CACZ,CAAA,IAAA4rC,EAAA,CAAe,CAAA,CAJvB,EASO,CAAA,CAtBX,CAmCA/jC,SAAA,GAAK,CAALA,CAAK,CACL,CACI,IAAIqK,EAAW,CAAA,CACf,IAAI,CAAC,CAAA8sD,EAAL,CACI,GAAI,CACA,CAAA5hD,EACA,CADaxV,IAAAC,MAAA,CAAW,CAAAk3D,EAAX,CACb,CAAA,CAAAC,EAAA,CAAe,CAAA,CAFf,CAGF,MAAO9/D,CAAP,CAAU,CAthwBhB+I,CAAA,CAuhwBwB/I,CAAAgJ,QAvhwBxB,EAuhwBqChJ,CAvhwBrC,CAwhwBQ,CAAAgT,CAAA,CAAW,CAAA,CAFH,CAKhB,MAAOA,EAXX,CAoBAiB,CAAAooD,MAAA,CAAAA,QAAK,EACL,CACI,IAAIrpD,EAAW,CAAA,CACf,IAAIitD,EAAA,EAAJ,CAA2B,CACvB,IAAIn/D,EAAI4H,IAAAw3D,UAAA,CAAe,IAAAhiD,EAAf,CACJ0+C,GAAA,CAAwB,IAAAmD,IAAxB,CAAkCj/D,CAAlC,CAAJ,GAziwBJiI,CAAA,CAkjwBwB,kBAljwBxB,CAkjwB6CjI,CAAAmD,OAljwB7C,CAkjwBwD,iCAljwBxD,CAmjwBQ,CAAA+O,CAAA,CAAW,CAAA,CAVf,CAFuB,CAe3B,MAAOA,EAjBX,CA0BAiB;CAAAC,SAAA,CAAAA,QAAQ,EACR,CACI,MAAO,KAAAgK,EAAA,CAAYxV,IAAAw3D,UAAA,CAAe,IAAAhiD,EAAf,CAAZ,CAAyC,IAAA2hD,EADpD,CAcA1D,SAAA,GAAM,CAANA,CAAM,CAACnuD,CAAD,CACN,CACI,CAAA6xD,EAAA,CAAY,EACZ,EAAA3hD,EAAA,CAAa,EACb,EAAAwuB,EAAA,CAAe,CAAAozB,EAAf,CAA8B,CAAA,CAC1B9xD,EAAJ,EAAW,CAAAoQ,IAAA,CAAS,OAAT,CAAkBpQ,CAAlB,CAJf,CAgBAiG,CAAA2nD,MAAA,CAAAA,QAAK,CAACuE,CAAD,CACL,CACIhE,EAAA,CAAAA,IAAA,CA94xBA,KAAIv8D,EAAI,EACR,IAAI,CACA,IADA,IACSQ,EAAI,CADb,CACgBN,EAAIkH,MAAA2C,aAAA1F,OAApB,CAAgD7D,CAAhD,CAAoDN,CAApD,CAAuDM,CAAA,EAAvD,CACIR,CAAAyJ,KAAA,CAAOrC,MAAA2C,aAAAo2D,IAAA,CAAwB3/D,CAAxB,CAAP,CAFJ,CAIF,MAAOJ,CAAP,CAAU,EA24xBZ,IAASI,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAx4xBOR,CAw4xBaqE,OAApB,CAAkC7D,CAAA,EAAlC,CAEI,IADI6J,CACJ,CA14xBGrK,CAy4xBQ,CAAMQ,CAAN,CACX,IAAa+/D,CAAb,EAAqBl2D,CAAAlI,OAAA,CAAY,CAAZ,CAAe,IAAAg+D,IAAA97D,OAAf,CAArB,EAAwD,IAAA87D,IAAxD,EAAmE,CAh6xBvE,GAAI,CACA/4D,MAAA2C,aAAAI,WAAA,CAg6xB+BE,CAh6xB/B,CADA,CAEF,MAAOjK,CAAP,CAAU,EAoBLJ,CA64xBCwT,OAAA,CAAahT,CAAb,CAAgB,CAAhB,CACAA,EAAA,CAAI,CAJ2D,CAL3E,CAwBA2/D;QAAO,GAAG,CAACxwD,CAAD,CAAYqwD,CAAZ,CAAsB57D,CAAtB,CACV,CACQ+7D,CAAAA,CAAMxwD,CAAArB,GACV,IAAI0xD,CAAJ,CAAc,CACV,IAAIx/D,EAAIw/D,CAAAj+D,QAAA,CAAiB,GAAjB,CACA,EAAR,CAAIvB,CAAJ,GAAW2/D,CAAX,EAAkB,IAAlB,CAAyBH,CAAA79D,OAAA,CAAgB,CAAhB,CAAmB3B,CAAnB,CAAzB,CAFU,CAIV4D,CAAJ,GACI+7D,CADJ,EACW,GADX,CACiB/7D,CADjB,CAGA,OAAO+7D,EATX,CA0JJ,IAAIK,GAAiB,CAoCrBC,SAASA,GAAO,CAACC,CAAD,CAAW/xD,CAAX,CAAgCoC,CAAhC,CAA2CjG,CAA3C,CAAmD2G,CAAnD,CAA2DkvD,CAA3D,CAAqEC,CAArE,CAA8El6D,CAA9E,CAChB,CASIk6D,CAAA,CAAQ,UAAR,CAAqBF,CAArB,CAAgC,KAAhC,CACAx1B,GAAA,CAAgBw1B,CAAhB,CAA0B,IAA1B,CAhDSj6D,CAAAA,CAgDT,CATkBo6D,QAAQ,CAACC,CAAD,CAAWC,CAAX,CAAiBx5D,CAAjB,CAA6B,CAC/CA,CAAJ,EACSw5D,CACL,GADWA,CACX,CADkB,iBAClB,CADsCL,CACtC,CADiD,IACjD,CADwDn5D,CACxD,CADqE,GACrE,EAAAb,CAAA,CAAKq6D,CAAL,CAAW,IAAX,CAFJ,EAKAC,EAAA,CAASD,CAAT,CAAeL,CAAf,CAAyB/xD,CAAzB,CAA8CoC,CAA9C,CAAyDjG,CAAzD,CAAiE2G,CAAjE,CAAyEkvD,CAAzE,CAAmFC,CAAnF,CAA4Fl6D,CAA5F,CANmD,CASvD,CAVJ;AA+BAs6D,QAASA,GAAQ,CAACD,CAAD,CAAOL,CAAP,CAAiB/xD,CAAjB,CAAsCoC,CAAtC,CAAiDjG,CAAjD,CAAyD2G,CAAzD,CAAiEkvD,CAAjE,CAA2EC,CAA3E,CAAoFl6D,CAApF,CACjB,CACmBu6D,QAAA,EAAQ,CAACF,CAAD,CAAOtK,CAAP,CAAe,CAClC,GAAIA,CAAJ,CACI/vD,CAAA,CAAK+vD,CAAL,CAAa,IAAb,CADJ,KAAA,CAIA,GAAI9nD,CAAJ,CAAe,CAMX08B,EAAA,CAA6B18B,CAA7B,CAAwC+xD,CAAxC,CAAkDK,CAAlD,CAGA,EADIx6D,CACJ,CADWm6D,CACX,GAAgC,CAAhC,CAAYn6D,CAAAxE,QAAA,CAAa,GAAb,CAAZ,EAA2E,GAA3E,EAAqCqF,MAAAC,SAAA65D,SAAA7+D,MAAA,CAAgC,EAAhC,CAArC,GACIkE,CADJ,CACWa,MAAAC,SAAA65D,SADX,CACsC36D,CADtC,CAOKuE,EAAL,CAE+B,GAAxB,EAAIA,CAAAzI,MAAA,CAAc,EAAd,CAAJ,EACHyI,CACA,CADSA,CAAAzI,MAAA,CAAa,CAAb,CAAiB,EAAjB,CACT,CAAoB,CAApB,CAAIyI,CAAAzG,OAAJ,GAAuByG,CAAvB,EAAiC,GAAjC,CAFG,EAIHA,CAJG,CAIM,UAJN,CAImBA,CAJnB,CAI4B,IANnC,CACIA,CADJ,CACa,GAObA,EAAA,EAAU,OAAV,CAAoBvE,CAApB,CAA2B,IAUH,SAAxB,EAAI,MAAOiB,UAAX,GAAkCjB,CAAlC,CAAyC,IAAzC,CACAuE,EAAA,CAASA,CAAA9I,QAAA,CAAe,KAAf,CAAsB,MAAtB,CACT,IAAIyP,CAAJ,CAAY,CAMR,IAAIlP,EAAQw+D,CAAAx+D,MAAA,CAAW,4CAAX,CACRA,EAAJ,GACIw+D,CACA,CADOA,CAAA/+D,QAAA,CAAaO,CAAA,CAAM,CAAN,CAAb,CAAuBA,CAAA,CAAM,CAAN,CAAvB,CAAkCA,CAAA,CAAM,CAAN,CAAlC,CAA6CkP,CAA7C,CAAsDlP,CAAA,CAAM,CAAN,CAAtD,CACP,CAAAkP,CAAA,CAAS,IAFb,CAPQ,CAYZsvD,CAAA,CAAOA,CAAA/+D,QAAA,CAAa,iCAAb;AAAgD,MAAhD,CAAyD2M,CAAzD,CAAqE,IAArE,EAA6E8C,CAAA,CAAQ,aAAR,CAAqBA,CAArB,CAA8B,GAA9B,CAAoC,EAAjH,GAAwH3G,CAAA,CAAQ,aAAR,CAAqBA,CAArB,CAA8B,GAA9B,CAAoC,EAA5J,GAAmKvE,CAAA,CAAM,WAAN,CAAiBA,CAAjB,CAAwB,GAAxB,CAA8B,EAAjM,EAhDI,CAmDVo6D,CAAL,GAKII,CACA,CADOA,CAAA/+D,QAAA,CAAa,sDAAb,CAAqE,WAArE,CACP,CAAA++D,CAAA,CAAOA,CAAA/+D,QAAA,CAAa,uDAAb,CAAsE,IAAtE,CAA6E+O,CAA7E,CAAyF,IAAzF,CANX,CAiCIowD,EAAAA,CAAS,IACb,IAAsB,MAAtB,EAAIJ,CAAA7+D,OAAA,CAAY,CAAZ,CAAJ,CACI,GAAI,CASKy+D,CASL,GARII,CAQJ,CARWA,CAAA/+D,QAAA,CAAa,4BAAb,CAA2C,EAA3C,CAQX,EAAIoF,MAAAM,cAAJ,EAA4B,eAA5B,EAA+CN,OAA/C,EACI+5D,CAEA,CAFS,IAAI/5D,MAAAM,cAAJ,CAAyB,kBAAzB,CAET,CADAy5D,CAAAC,MACA,CADe,CAAA,CACf,CAAAD,CAAA,QAAA,CAAkBJ,CAAlB,CAHJ,EAMII,CANJ,CAMaE,CAAC,IAAIj6D,MAAAk6D,UAALD,iBAAA,CAAyCN,CAAzC;AAA+C,UAA/C,CAxBb,CA0BF,MAAM3gE,CAAN,CAAS,CACP+gE,CACA,CADS,IACT,CAAAJ,CAAA,CAAO3gE,CAAAgJ,QAFA,CA3Bf,IAgCI23D,EAAA,CAAO,oBAAP,EAA6C,GAAd,CAAAA,CAAA18D,OAAA,CAAmB08D,CAAA5+D,OAAA,CAAY,CAAZ,CAAe,GAAf,CAAnB,CAAyC,KAAzC,CAAiD4+D,CAAhF,CAEJr6D,EAAA,CAAKq6D,CAAL,CAAWI,CAAX,CA3HA,CADkC,CA8HlCJ,CAAJ,CAEQJ,CAAJ,CACIY,EAAA,CAAWR,CAAX,CAAiBH,CAAjB,CAA0BK,CAA1B,CADJ,CAIAA,CAAA,CAASF,CAAT,CAAe,IAAf,CANJ,CASAr6D,CAAA,CAAK,SAAL,EAAkBg6D,CAAA,CAAU,aAAV,CAA0BA,CAA1B,CAAqC,EAAvD,EAA4D,IAA5D,CAxIJ;AAwJAa,QAASA,GAAU,CAACR,CAAD,CAAOH,CAAP,CAAgBl6D,CAAhB,CACnB,CACI,IAAI86D,CAGJ,IAAKA,CAAL,CAFYC,kCAEIv2D,KAAA,CAAW61D,CAAX,CAAhB,CAAmC,CAE/B,IAAIW,EAAWF,CAAA,CAAS,CAAT,CA2DfZ,EAAA,CAAQ,UAAR,CAAqBc,CAArB,CAAgC,KAAhC,CACAx2B,GAAA,CAAgBw2B,CAAhB,CAA0B,IAA1B,CAjSKj7D,CAAAA,CAiSL,CA1DkBk7D,QAAQ,CAACb,CAAD,CAAWc,CAAX,CAAoBr6D,CAApB,CAAgC,CACtD,GAAIA,CAAJ,EAAkB,CAACq6D,CAAnB,CACIl7D,CAAA,CAAKq6D,CAAL,CAAW,mCAAX,CAAiDS,CAAA,CAAS,CAAT,CAAjD,CAA+D,IAA/D,CAAsEj6D,CAAtE,CAAmF,GAAnF,CADJ,KAAA,CAUA,GADIs6D,CACJ,CADgBL,CAAA,CAAS,CAAT,CAChB,CAEI,GADIM,CACJ,CADiBF,CAAAr/D,MAAA,CAAc,IAAIyQ,MAAJ,CAAW,MAAX,CAAiBwuD,CAAA,CAAS,CAAT,CAAjB,CAA+B,cAA/B,CAAd,CACjB,CAAgB,CAOZ,IANA,IAAIO,EAAaD,CAAA,CAAW,CAAX,CAAjB,CAIIE,CAJJ,CAKIC,EAAS,2BACb,CAAQD,CAAR,CAAoBC,CAAA/2D,KAAA,CAAY22D,CAAZ,CAApB,CAAA,CAKQE,CAAA,CAJ+D,CAAnE,CAAIA,CAAA79D,YAAA,EAAAnC,QAAA,CAAiCigE,CAAA,CAAU,CAAV,CAAA99D,YAAA,EAAjC,CAAJ,CAIiB69D,CAAA//D,QAAA,CAAmB,MAAnB,CAAwBggE,CAAA,CAAU,CAAV,CAAxB,CAAuC,MAAvC,CAJjB,CASiBD,CAAA//D,QAAA,CAAmB,IAAIgR,MAAJ,CAAWgvD,CAAA,CAAU,CAAV,CAAX,CAA0B,iBAA1B,CAAnB,CAAiEA,CAAA,CAAU,CAAV,CAAjE,CAGjBF,EAAA,CAAW,CAAX,CAAJ,EAAqBC,CAArB,GACIH,CADJ,CACcA,CAAA5/D,QAAA,CAAgB8/D,CAAA,CAAW,CAAX,CAAhB,CAA+BC,CAA/B,CADd,CApBY,CAAhB,IAuBO,CACHr7D,CAAA,CAAKq6D,CAAL,CAAW,cAAX;AAAyBS,CAAA,CAAS,CAAT,CAAzB,CAAuC,UAAvC,CAAiDE,CAAjD,CACA,OAFG,CAcXE,CAAA,CAAUA,CAAA5/D,QAAA,CAAgB,qBAAhB,CAAuC,EAAvC,CAEV++D,EAAA,CAAOA,CAAA/+D,QAAA,CAAaw/D,CAAA,CAAS,CAAT,CAAb,CAA0BI,CAA1B,CAEPL,GAAA,CAAWR,CAAX,CAAiBH,CAAjB,CAA0Bl6D,CAA1B,CArDA,CADsD,CA0D1D,CA9D+B,CAAnC,IAiEAA,EAAA,CAAKq6D,CAAL,CAAW,IAAX,CArEJ;AAuFAmB,QAASA,GAAY,CAAWnxD,CAAX,CAAgCpC,CAAhC,CAA2C+xD,CAA3C,CAAqDyB,CAArD,CAA+Dr3D,CAA/D,CAAuE2G,CAAvE,CACrB,CAyByB2wD,QAAA,EAAQ,CAAClyD,CAAD,CAAW,CACpC,GAAiBhL,IAAAA,EAAjB,GAAIm9D,CAAJ,CAA4B,CAaxB,IAAIC,EAAa5C,CAAb4C,EAAyBpxD,CAAA,CAA6BwuD,CAA7B,CAAuC,iBAAvC,CAC7B2C,EAAA,CAAYC,CAAZ,EAAyBA,CAAA,CAAU,CAAV,CAAzB,EAA0C5C,CAdlB,CAgBxB2C,CAAJ,GAAcA,CAAAE,UAAd,CAAmCC,EAAA,CAAetyD,CAAf,CAAnC,CAjBoC,CAPrBuyD,QAAA,EAAQ,CAAChM,CAAD,CAAS,CAEhC2L,CAAA,CAAe,SAAf,CAA2B3L,CAA3B,CACIrjD,EAAJ,GARK,EAAEotD,EAQP,EAPgBkC,EAAA,CAAqB,CAAA,CAArB,CAOhB,CACAtvD,EAAA,CAAW,CAAA,CAJqB,CAlBxC,IACQssD,CADR,CACkB2C,CADlB,CAC4BjvD,EAAW,CAAA,CAE9BstD,EAAL,GACIA,CACA,CADW,aACX,CAAKyB,CAAL,GAAeA,CAAf,CAA0B,gBAA1B,CAFJ,CAKA3B,GAAA,EA9vxBI1wD,GAAA,CA+vxBiBnB,CA/vxBjB,CAAA,CAAgC,EAmyxBpC,IAAI,CAEA,GADA+wD,CACA,CADWl+C,QAAAmhD,eAAA,CAAwBh0D,CAAxB,CACX,CAAc,CAKV,IAAIi0D,CACJ,IAAwB,QAAxB,EAAI,MAAOp7D,UAAX,GAAqCo7D,CAArC,CAA2Cp7D,SAAA,IAA3C,EAA8D,CAC1D,IAAIq7D,EAAOrhD,QAAAqhD,KAAPA,EAAwBrhD,QAAA1O,qBAAA,CAA8B,MAA9B,CAAA,CAAsC,CAAtC,CAA5B,CACIoM,EAAQsC,QAAAshD,cAAA,CAAuB,OAAvB,CACZ5jD,EAAA1Y,KAAA,CAAa,UAET0Y,EAAA6jD,WAAJ,CAEI7jD,CAAA6jD,WAAAC,QAFJ,CAE+BJ,CAF/B,CAII1jD,CAAA+jD,YAAA,CAAkBzhD,QAAA0hD,eAAA,CAAwBN,CAAxB,CAAlB,CAEJC;CAAAI,YAAA,CAAiB/jD,CAAjB,CAX0D,CAczDijD,CAAL,GAQQgB,CAMA,CANapyD,CAMb,CAD8B,KAC9B,EADIA,CAAA5O,OAAA,CAAiB,CAAjB,CAAoB,CAApB,CACJ,GADqCghE,CACrC,CADkD,OAClD,EAAAhB,CAAA,CAAW,YAAX,CAA0BgB,CAA1B,CAAwD,wBAdhE,CAkBIC,EAAAA,CAAaA,QAAQ,CAACrC,CAAD,CAAOsC,CAAP,CAAY,CAC5BA,CAAL,CA0GA5C,EAAA,CAAQ0B,CAAR,EAAoB,EAApB,CAAwB,IAAxB,CAAwCpxD,CAAxC,CAAmD,IAAnD,CAAyD,IAAzD,CAA+D,CAAA,CAA/D,CAAsEqxD,CAAtE,CA1FmBkB,QAAQ,CAACC,CAAD,CAAOC,CAAP,CAAY,CAC9BA,CAAL,EAUAn4B,EAAA,CAA6B18B,CAA7B,CAAwCwzD,CAAxC,EAAoD,EAApD,CAAwDoB,CAAxD,CAsBA,CAPAnB,CAAA,CAAe,aAAf,CAA+B1B,CAA/B,CAA0C,KAA1C,CAOA,CAAIt5D,MAAAM,cAAJ,EAA4B,eAA5B,EAA+CN,OAA/C,CAEI,CADIq8D,CACJ,CADgBJ,CAAA,cAAA,CAAqBG,CAArB,CAChB,GACI9D,CAAAgE,UA7HpB,CA6HyCD,CA7HzC,CAAK,EAAEjD,EAAP,EACgBkC,EAAA,CAAqB,CAAA,CAArB,CA2HA,EAIID,CAAA,CAAa,8BAAb,CANR,CASSjhD,QAAAmiD,eAAJ,EAA+BniD,QAAAmiD,eAAAC,eAA/B,EACGC,CAGJ,CAHoB,IAAIC,aAGxB,CAFAD,CAAA,iBAAA,CAAkCL,CAAlC,CAEA,CAAA,CADIO,CACJ,CADgBF,CAAA,oBAAA,CAAqCR,CAArC,CAA0C7hD,QAA1C,CAChB,EASQk+C,CAAAvuD,WAAJ,EACIuuD,CAAAvuD,WAAA6yD,aAAA,CAAiCD,CAAjC;AAA4CrE,CAA5C,CAjJxB,CAAK,EAAEc,EAAP,EACgBkC,EAAA,CAAqB,CAAA,CAArB,CA+II,EAkBID,CAAA,CAAa,2BAAb,CAA2C9zD,CAA3C,CA3BR,CA8BI8zD,CAAA,CAAa,4BAAb,CAlCH,EA0CDA,CAAA,CAAa,8CAAb,CAnFJ,EACIA,CAAA,CAAac,CAAb,CAF+B,CA0FvC,CA1GA,CACId,CAAA,CAAa1B,CAAb,CAF6B,CA8GX,OAA1B,EAAIL,CAAAx+D,OAAA,CAAgB,CAAhB,CAAJ,CACIu+D,EAAA,CAAQC,CAAR,CAAkB/xD,CAAlB,CAAuCoC,CAAvC,CAAkDjG,CAAlD,CAA0D2G,CAA1D,CAAkE,CAAA,CAAlE,CAAwE2wD,CAAxE,CAAwFgB,CAAxF,CADJ,CAGIpC,EAAA,CAASN,CAAT,CAAmB,IAAnB,CAAyB/xD,CAAzB,CAA8CoC,CAA9C,CAAyDjG,CAAzD,CAAiE2G,CAAjE,CAAyE,CAAA,CAAzE,CAAgF2wD,CAAhF,CAAgGgB,CAAhG,CAvJM,CAAd,IA0JIX,EAAA,CAAa,2BAAb,CAA2C9zD,CAA3C,CA5JJ,CA8JF,MAAMvO,CAAN,CAAS,CACPqiE,CAAA,CAAariE,CAAAgJ,QAAb,CADO,CAGX,MAAOgK,EA9MX,CA0WIhM,MAAA,WAAA,CA/FJ68D,QAAmB,CAACt1D,CAAD,CAAY+xD,CAAZ,CAAsByB,CAAtB,CAAgCr3D,CAAhC,CAAwC2G,CAAxC,CACnB,CACgBixD,EAAA,CAAqB,CAAA,CAArB,CACZ,OAAOR,GAAA,CAAsB,OAAtB,CAA2CvzD,CAA3C,CAAsD+xD,CAAtD,CAAgEyB,CAAhE,CAA0Er3D,CAA1E,CAAkF2G,CAAlF,CAFX,CA+FIrK,OAAA,WAAA,CAhFJ88D,QAAmB,CAACv1D,CAAD,CAAY+xD,CAAZ,CAAsByB,CAAtB,CAAgCr3D,CAAhC,CAAwC2G,CAAxC,CACnB,CACgBixD,EAAA,CAAqB,CAAA,CAArB,CACZ,OAAOR,GAAA,CAAsB,OAAtB,CAA2CvzD,CAA3C,CAAsD+xD,CAAtD,CAAgEyB,CAAhE,CAA0Er3D,CAA1E,CAAkF2G,CAAlF,CAFX,CAkFArK;MAAA,eAAA,CAlDA+8D,QAAuB,CAAC1zD,CAAD,CAAU2zD,CAAV,CAAmBz1D,CAAnB,CAA8B01D,CAA9B,CAA0C5wD,CAA1C,CAAoDnJ,CAApD,CACvB,CACI,GAAgB,QAAhB,EAAImJ,CAAJ,CAA0B,CA5+wBlBL,CAAAA,CAAW,CAAA,CA6+wBazE,EA5+wB5B,EAAa,UACb,IAAI,CA2+wBmCrE,CA3+wBvC,CACI,OAAOgJ,EAAA,CAAmB3E,CAAnB,CACP,CAAAyE,CAAA,CAAW,CAAA,CAFf,KAIK,IAAsB,QAAtB,EAAI,MAu+wB8B9I,EAv+wBlC,EAAkC,CAACgJ,EAAA,CAAmB3E,CAAnB,CAAnC,CAAkE,CACnEyE,CAAA,CAAW,CAAA,CACXE,EAAAA,CAAAA,EA9DJ,KA8DuB3E,IAAAA,EAAAA,CAAAA,CAhEnB5L,EAqixBmCuH,CArixB7BjG,OAgEasK,CA/DnB0E,EAAY,EA+DO1E,CA/DH4E,EAAU,EA+DP5E,CA/DW21D,EAAS,EA+DpB31D,CA/DwB0iC,EAAU,IA+DlC1iC,CA9DdnO,EAAI,CAAb,CAAgBA,CAAhB,CAAoBuC,CAApB,CAAyBvC,CAAA,EAAzB,CAA8B,CAC1B,IAAIyB,EAkixB+BqI,CAlixB1B,CAAQ9J,CAAR,CACT,IAAU,GAAV,EAAIyB,CAAJ,EAAuB,GAAvB,EAAiBA,CAAjB,CACQovC,CAAJ,EAAepvC,CAAf,EAAqBovC,CAArB,CACIizB,CADJ,EACcriE,CADd,EAIKovC,CAAL,CAGIA,CAHJ,CAGc,IAHd,CACIA,CADJ,CACcpvC,CAId,CAAIqiE,CAAJ,GACI/wD,CAAA9J,KAAA,CAAa66D,CAAb,CACA,CAAAA,CAAA,CAAS,EAFb,CATA,CADJ,KAAA,CAgBA,GAAI,CAACjzB,CAAL,CAAc,CACV,GAAU,IAAV,EAAIpvC,CAAJ,EAAwB,IAAxB,EAAkBA,CAAlB,CACIA,CAAA,CAAK,GAET,IAAU,GAAV,EAAIA,CAAJ,EAAuB,IAAvB,EAAiBA,CAAjB,EAAqC,GAArC,EAA+BA,CAA/B,CAA0C,CAClCqiE,CAAJ,GACI/wD,CAAA9J,KAAA,CAAa66D,CAAb,CACA,CAAAA,CAAA,CAAS,EAFb,CAIU,IAAV,EAAIriE,CAAJ,EAAiBsR,CAAAlP,OAAjB,GACIgP,CAAA5J,KAAA,CAAe8J,CAAf,CACA,CAAAA,CAAA,CAAU,EAFd,CAIA,SATsC,CAJhC,CAgBd+wD,CAAA,EAAUriE,CAhCV,CAF0B,CAoC1BqiE,CAAJ,EACI/wD,CAAA9J,KAAA,CAAa66D,CAAb,CAEA/wD,EAAAlP,OAAJ,EACIgP,CAAA5J,KAAA,CAAe8J,CAAf,CAsBAD,EAAA,CAAmB3E,CAAnB,CAAA,CApBG0E,CAqBEQ,GAAA,CAA0BlF,CAA1B,CAAL,GACIyE,CADJ,CACe,CAAA,CADf,CAHmE,CAu+wBvE,MAh+wBOA,EAg+wBP,EACQgxD,CACG,GADM3zD,CAAA8zD,SACN,CADyB,CAAA,CACzB;AAAA,CAAA,CAFX,EAIO,CAAA,CALe,CAO1B,GAAIF,CAAJ,GACQ10D,CADR,CACoBqE,EAAA,CAA6BqwD,CAA7B,CAAyC11D,CAAzC,CAAqD,UAArD,CADpB,IAGYuF,CAHZ,CAGsBvE,CAAA,QAHtB,IAKgBmE,CALhB,CAK4BI,CAAA,CAAQT,CAAR,CAL5B,EAOgB,MAAIK,EAAAK,KAAA,CAAexE,CAAf,CAA0BrF,CAA1B,CAAJ,EACQ85D,CACG,GADM3zD,CAAA8zD,SACN,CADyB,CAAA,CACzB,EAAA,CAAA,CAFX,EAIO,CAAA,CAKvBlvD,QAAAlS,IAAA,CAAY,iCAAZ,CAAgDwL,CAAhD,CAA4D,KAA5D,CAAoE01D,CAApE,CAAiF,KAAjF,CAAyF5wD,CAAzF,CAAoG,KAApG,CAA4GnJ,CAA5G,CAAqH,IAArH,CACA,OAAO,CAAA,CAzBX,CAmDAlD,OAAA,aAAA,CAAyBs7D,EACzBt7D,OAAA,UAAA,CAAyBoG;","sources":["versions/pdpjs/1.61.0/pdp10-uncompiled.js"," [synthetic:util/defineproperty] "," [synthetic:util/global] "," [synthetic:es6/symbol] "," [synthetic:util/objectcreate] "," [synthetic:es6/util/setprototypeof] "," [synthetic:es6/util/inherits] "," [synthetic:util/polyfill] "," [synthetic:es6/math/trunc] "," [synthetic:es6/number/parseint] "," [synthetic:es6/math/log2] "," [synthetic:es6/util/makeiterator] "],"names":["$jscomp.defineProperty","$jscomp.global","$jscomp.initSymbol","$jscomp.Symbol","$jscomp.SYMBOL_PREFIX","$jscomp.arrayIterator","$jscomp.initSymbolIterator","$jscomp.iteratorPrototype","$jscomp.objectCreate","$jscomp.setPrototypeOf","$jscomp.polyfill","ASCII","BREAK","CTRL_A","CTRL_B","CTRL_C","CTRL_D","CTRL_E","CTRL_F","CTRL_G","CTRL_H","CTRL_I","CTRL_J","CTRL_K","CTRL_L","CTRL_M","CTRL_N","CTRL_O","CTRL_P","CTRL_Q","CTRL_R","CTRL_S","CTRL_T","CTRL_U","CTRL_V","CTRL_W","CTRL_X","CTRL_Y","CTRL_Z","ESC","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","DEL","parseInt","base","chPrefix","fCommas","indexOf","replace","ch","charAt","substr","chSuffix","slice","shift","match","isNaN","Math","pow","trunc","value","toBase","radix","cch","sPrefix","nGrouping","ceil","log","String","fromCharCode","toOct","fPrefix","abs","Str.toBase","toDec","toHex","getBaseName","sFileName","sBaseName","lastIndexOf","getExtension","sExtension","toLowerCase","endsWith","sSuffix","length","escapeHTML","sHTML","Str.HTMLEscapeMap","pad","sPadding","trim","prototype","binarySearch","fnCompare","left","right","found","undefined","middle","compareResult","formatDate","date","sDate","Date","iHour","getHours","iDay","getDate","iMonth","getMonth","sFormat","Usr.asDays","getDay","Usr.asMonths","getMinutes","getSeconds","getFullYear","getResource","sURL","type","fAsync","done","callback","request","readyState","resource","fArrayBuffer","response","responseText","err","status","window","location","protocol","nErrorCode","resources","XMLHttpRequest","ActiveXObject","fXHR2","responseType","onreadystatechange","sPost","hasOwnProperty","encodeURIComponent","open","setRequestHeader","send","overrideMimeType","parseMemoryResource","sData","aBytes","aSymbols","addrLoad","addrExec","ib","Error","data","JSON","parse","eval","Array","aData","Component.alertUser","message","ab","asHexData","sHexData","split","push","getHost","host","SITEHOST","hasLocalStorage","Web.fLocalStorage","localStorage","setItem","Web.sLocalStorageTest","getItem","removeItem","getLocalStorageItem","sKey","sValue","setLocalStorageItem","isUserAgent","userAgent","navigator","getURLParm","sParm","Web.parmsURL","sParms","aParms","search","pl","exec","decodeURIComponent","onCountRepeat","fnRepeat","fnComplete","fnTimeout","doCountRepeat","setTimeout","onClickRepeat","fn","doClickRepeat","msRepeat","ms","timer","fIgnoreMouseEvents","onmousedown","e.onmousedown","msDelay","ontouchstart","e.ontouchstart","onmouseup","onmouseout","e.onmouseout","clearTimeout","ontouchend","ontouchcancel","e.ontouchcancel","onPageEvent","sFunc","fnPrev","onInit","Web.aPageEventHandlers","doPageEvent","afn","Web.fPageEventsEnabled","enablePageEvents","fEnable","Web.fPageLoaded","Web.sendPageEvent","Web.fPageShowed","sendPageEvent","sEvent","Web.doPageEvent","Web.onPageEvent","onPageLoad","onPageShow","Web.isUserAgent","onPageUnload","constructor","Component","parms","bitsMessage","id","name","comment","bindings","idComponent","idMachine","flags","ready","busy","busyCancel","initDone","powered","unloading","error","fnReady","clearError","dbg","cpu","bus","cmp","Component.components.push","component","addMachineResource","sName","Component.machines","getTime","now","alertUser","sMessage","alert","confirmUser","sPrompt","fResponse","confirm","appendControl","control","sText","scrollTop","scrollHeight","bindComponentControls","element","sAppClass","PDP10.APPCLASS","aeControls","Component.getElementsByClass","parentNode","iControl","aeChildNodes","childNodes","iNode","nodeType","sClass","getAttribute","aClasses","iClass","Component.getComponentParms","setBinding","getComponents","idRelated","aComponents","Component.components.length","Component.components","getComponentByID","getComponentByType","sType","componentPrev","getComponentParms","getElementsByClass","sObjClass","getElementsByClassName","ae","aeAll","getElementsByTagName","re","RegExp","test","className","processCommands","fSuccess","aCommands","Component.commands","aTokens","splice","sCommand","fnCallReady","Component.asyncCommands.indexOf","processNextCommand","Component.processCommands","fnCommand","Component.globalCommands","Component.getComponentByType","Component.componentCommands","exports","call","Component.prototype","?.prototype","toString","sHTMLType","sBinding","onclick","clearControl","notice","this.notice","println","print","printControl","Component.appendControl","printlnControl","Component.PRINT.PROGRESS","fPrintOnly","computer","console","setError","isError","isReady","setReady","isBusy","fCancel","setBusy","fBusy","powerUp","powerDown","fSave","fShutdown","messageEnabled","bitsEnabled","printMessage","fAddress","PROGRESS","Component.asyncCommands","scriptAlert","scriptSleep","fnCallback","sDelay","scriptSelect","aBindings","options","textContent","selectedIndex","Array.prototype.indexOf","obj","start","isArray","Array.isArray","arg","Object","Function","bind","Function.prototype.bind","fnBound","fToBind","apply","fnNOP","args","concat","arguments","TypeError","APPCLASS","APPNAME","ADDR_MASK","ADDR_LIMIT","HINT_MASK","HINT_LIMIT","HALF_MASK","HALF_SHIFT","INT_MASK","INT_LIMIT","WORD_MASK","WORD_LIMIT","TWO_POW32","TWO_POW34","TWO_POW36","OP_SCALE","OPCODE","IO_SCALE","A_SCALE","P_SCALE","PDP10.APPNAME","MessagesPDP10.CATEGORIES","CPU","TRAP","FAULT","INT","BUS","MEMORY","MMU","ROM","DEVICE","PANEL","KEYBOARD","KEYS","PAPER","READ","WRITE","SERIAL","TIMER","SPEAKER","COMPUTER","LOG","WARN","BUFFER","HALT","PanelPDP10","parmsPanel","fBindings","nDisplayCount","cLiveRegs","regAddr","regData","regSwitches","regDisplay","ledAddr","ledData","fDeposit","fExamine","fLEDTest","nAddrSel","PanelPDP10.ADDRSEL.CONS_PHY","leds","switches","processStart","processStep","processEnable","processContinue","processDeposit","processExamine","processLoadAddr","processLEDTest","processSRSwitch","holdSwitch","toggleSwitch","resetSwitches","setSwitch","$jscomp.inherits","PanelPDP10.prototype","reset","fPowerUp","stop","updateData","setDR","parent","parentElement","panel","onPressSwitch","pressSwitch","onReleaseSwitch","releaseSwitch","event","preventDefault","initBus","displayLEDs","displaySwitches","fRepower","PanelPDP10.init","restore","save","state","State","set","getAR","getDR","getSR","updateAddr","setAR","setSRSwitches","setSR","sw","displayLED","style","backgroundColor","override","displaySwitch","marginTop","Str.parseInt","PanelPDP10.SWITCH.STEP","PanelPDP10.SWITCH.DEP","PanelPDP10.SWITCH.EXAM","running","setPC","getSwitch","PanelPDP10.SWITCH.ENABLE","startCPU","stopCPU","stepCPU","nCyclesStep","updateTimers","addCycles","updateChecksum","exception","stack","updateDisplays","advanceAddr","setWordDirect","writeWord","getWordDirect","readWord","index","inc","mask","nBusMask","nLEDs","updateLEDArray","PDP10.WORD_LIMIT","regPC","init","aePanels","document","iPanel","ePanel","Component.getComponentByID","Component.bindComponentControls","CONS_PHY","DEP","ENABLE","EXAM","STEP","Web.onInit","BusPDP10","parmsBus","nBusWidth","addrTotal","nBlockShift","log2","nBlockSize","nBlockTotal","nDisableFaults","aBusBlocks","block","MemoryPDP10","initMemory","copyBreakpoints","iBlock","BusPDP10.prototype","saveMemory","adw","nBlockLen","iDst","aDst","iComp","aComp","restoreMemory","addMemory","addr","size","addrNext","sizeLeft","addrBlock","sizeBlock","used","sizeAvail","reportError","BusPDP10.ERROR.RANGE_INUSE","blockNew","MemoryPDP10.TYPE_NAMES","Str.toOct","BusPDP10.ERROR.RANGE_INVALID","getBlockDirect","readWordDirect","nBlockLimit","writeWordDirect","removeMemBreak","fWrite","removeBreakpoint","cWriteBreakpoints","resetWriteAccess","fReadOnly","writeNone","cReadBreakpoints","resetReadAccess","fDirty","fDirtyEver","iSrc","aSrc","iCompare","fault","toStrBase","errNum","Str.toHex","RANGE_INUSE","RANGE_INVALID","DevicePDP10","parmsDevice","DevicePDP10.prototype","aeDevice","iDevice","eDevice","device","MemoryPDP10.idBlock","MemoryPDP10.TYPE.NONE","MemoryPDP10.TYPE.ROM","readNone","aw","setAccess","MemoryPDP10.afnMemory","MemoryPDP10.prototype","MemoryPDP10.afnNone","setReadAccess","fDirect","setWriteAccess","addBreakpoint","off","MemoryPDP10.afnChecked","mem","WORD_INVALID","readWordMemory","writeWordMemory","readWordChecked","checkBreakpoint","nb","aBreakRead","writeWordChecked","aBreakWrite","NONE","CPUPDP10","parmsCPU","nCyclesDefault","nCycles","nMultiplier","nCyclesPerSecond","nCyclesMultiplier","mhzDefault","round","mhzTarget","msPerYield","nCyclesPerYield","nCyclesNextYield","nCyclesRecalc","starting","autoStart","checksum","nChecksum","nCyclesChecksumNext","nCyclesChecksumStart","nCyclesChecksumInterval","nCyclesChecksumStop","aTimers","onRunTimeout","runCPU","nTotalCycles","nRunCycles","nBurstCycles","nStepCycles","msStartRun","msStartThisRun","msEndThisRun","nCyclesThisRun","nYieldsSinceStatusUpdate","mhz","CPUPDP10.prototype","CPUPDP10.BUTTONS.length","CPUPDP10.BUTTONS","sAutoStart","getMachineParm","resetCycles","resetChecksum","fInit","updateStatus","fAutoStart","setFocus","sInitCommands","sCmds","doCommands","getChecksum","fDisplay","getCycles","displayChecksum","control.onclick","iComponent","Component.getComponents","setSpeed","getSpeedTarget","toFixed","fEndStep","calcCycles","fRecalc","vMultiplier","CPUPDP10.YIELDS_PER_SECOND","floor","fUpdateFocus","sSpeed","controlSpeed","Component.getTime","getBurstCycles","saveTimers","aTimerCycles","endBurst","fReset","calcStartTime","msDelta","CPUPDP10.YIELDS_PER_STATUS","nUpdate","calcRemainingTime","msYield","msRemainsThisRun","msElapsed","controlRun","CPUPDP10_prototype$stepCPU","fComplete","fStopped","complete","CPUStatePDP10","model","MODEL_KA10","addrReset","opDecode","PDP10.opKA10.bind","opUndefined","PDP10.opUndefined.bind","irqNext","aIRQs","CPUStatePDP10.prototype","initCPU","regLA","regOP","regEA","regRA","lastPC","regBP","regXC","regEX","regPS","regRes","regPow","regDiv","regRem","addrLast","opFlags","readWordFromPhysical","writeWordToPhysical","getSpeed","saveIRQs","aIRQVectors","irq","restoreIRQs","vector","next","restoreTimers","setPS","PSFLAG","advancePC","pc","PDP10.ADDR_LIMIT","getXC","nMinCycles","nDebugCheck","checksEnabled","nDebugState","OPFLAG","checkInstruction","fInterrupt","getOpcode","PDP10.ADDR_MASK","PDP10.OPCODE.A_SCALE","op","aeCPUs","iCPU","eCPU","PDP10.opKA10","PDP10.aOpXXX_KA10","PDP10.opUUO","PDP10.opIBP","PDP10.OPCODE.P_SCALE","PDP10.opLDB","ac","PDP10.opDPB","PDP10.opMOVE","PDP10.opMOVEI","PDP10.opMOVEM","PDP10.opSETZ","PDP10.opSETCA","PDP10.WORD_MASK","PDP10.opSETO","PDP10.opHLL","src","dst","PDP10.GETHR","PDP10.HALF_MASK","PDP10.opHLLI","PDP10.opHLLM","PDP10.opHLLS","PDP10.INT_MASK","PDP10.opHRL","PDP10.HALF_SHIFT","PDP10.opHRLI","PDP10.opHRLM","PDP10.opHRLS","PDP10.opHRR","PDP10.GETHL","PDP10.opHRRI","PDP10.opHRRM","PDP10.opHRRS","PDP10.HINT_MASK","PDP10.opHLR","PDP10.opHLRI","PDP10.opHLRM","PDP10.opHLRS","PDP10.opIO","PDP10.aOpIO_KA10","PDP10.opNOP","PDP10.opNOPM","PDP10.opUndefined","PDP10.doABS","PDP10.INT_LIMIT","PDP10.TWO_POW36","PDP10.doADD","res","PDP10.setAddFlags.call","PDP10.doDIV","ext","fNegQ","fNegR","extAbs","srcAbs","sign","dDst","lo","hi","PDP10.CMPD","PDP10.ADDD","dSrc","PDP10.ZEROD","PDP10.SHRD","PDP10.doMUL","fTruncate","fExternal","n1","n2","fNeg","n1d1","n1d2","n2d1","n2d2","m1d1","m1d2","PDP10.doNEG","PDP10.doSUB","PDP10.setAddFlags","dst01","PDP10.TWO_POW34","src01","res01","bitsCarry","PDP10.AND","PDP10.TWO_POW32","PDP10.CLR","PDP10.CMP","PDP10.EQV","PDP10.IOR","PDP10.SIGN","PDP10.XOR","PDP10.SWAP","result","PDP10.opUFA","PDP10.opDFN","PDP10.opFSC","PDP10.opILDB","PDP10.opIBP.call","PDP10.opLDB.call","PDP10.opIDPB","PDP10.opDPB.call","PDP10.opFAD","PDP10.opFADI","PDP10.opFADM","PDP10.opFADB","PDP10.opFADR","PDP10.opFADRI","PDP10.opFADRM","PDP10.opFADRB","PDP10.opFSB","PDP10.opFSBI","PDP10.opFSBM","PDP10.opFSBB","PDP10.opFSBR","PDP10.opFSBRI","PDP10.opFSBRM","PDP10.opFSBRB","PDP10.opFMP","PDP10.opFMPI","PDP10.opFMPM","PDP10.opFMPB","PDP10.opFMPR","PDP10.opFMPRI","PDP10.opFMPRM","PDP10.opFMPRB","PDP10.opFDV","PDP10.opFDVI","PDP10.opFDVM","PDP10.opFDVB","PDP10.opFDVR","PDP10.opFDVRI","PDP10.opFDVRM","PDP10.opFDVRB","PDP10.opMOVES","PDP10.opMOVS","PDP10.opMOVSI","PDP10.opMOVSM","PDP10.opMOVSS","PDP10.opMOVN","PDP10.doNEG.call","PDP10.opMOVNI","PDP10.opMOVNM","PDP10.opMOVNS","PDP10.opMOVM","PDP10.doABS.call","PDP10.opMOVMI","PDP10.opMOVMM","PDP10.opMOVMS","PDP10.opIMUL","PDP10.doMUL.call","PDP10.opIMULI","PDP10.opIMULM","PDP10.opIMULB","PDP10.opMUL","PDP10.opMULI","PDP10.opMULM","PDP10.opMULB","PDP10.opIDIV","PDP10.doDIV.call","PDP10.opIDIVI","PDP10.opIDIVM","PDP10.opIDIVB","PDP10.opDIV","PDP10.opDIVI","PDP10.opDIVM","PDP10.opDIVB","PDP10.opASH","PDP10.HINT_LIMIT","bits","PDP10.opROT","PDP10.opLSH","PDP10.opJFFO","PDP10.opASHC","wLeft","wRight","wLeftOrig","PDP10.opROTC","PDP10.opLSHC","PDP10.opEXCH","tmp","PDP10.opBLT","fUpdate","fDone","addrDst","addrSrc","isRunning","PDP10.opAOBJP","PDP10.opAOBJN","PDP10.opJRST","setUserMode","PDP10.opJFCL","bitsPS","PDP10.opXCT","PDP10.opPUSHJ","getPS","getPC","PDP10.opPUSH","PDP10.opPOP","PDP10.opPOPJ","PDP10.opJSR","PDP10.opJSP","PDP10.opJSA","PDP10.opJRA","acc","PDP10.opADD","PDP10.doADD.call","PDP10.opADDI","PDP10.opADDM","PDP10.opADDB","PDP10.opSUB","PDP10.doSUB.call","PDP10.opSUBI","PDP10.opSUBM","PDP10.opSUBB","PDP10.opCAIL","PDP10.opCAIE","PDP10.opCAILE","PDP10.opCAIA","PDP10.opCAIGE","PDP10.opCAIN","PDP10.opCAIG","PDP10.opCAML","PDP10.opCAME","PDP10.opCAMLE","PDP10.opCAMA","PDP10.opCAMGE","PDP10.opCAMN","PDP10.opCAMG","PDP10.opJUMPL","PDP10.opJUMPE","PDP10.opJUMPLE","PDP10.opJUMPA","PDP10.opJUMPGE","PDP10.opJUMPN","PDP10.opJUMPG","PDP10.opSKIP","PDP10.opSKIPL","PDP10.opSKIPE","PDP10.opSKIPLE","PDP10.opSKIPA","PDP10.opSKIPGE","PDP10.opSKIPN","PDP10.opSKIPG","PDP10.opAOJ","PDP10.opAOJL","PDP10.opAOJE","PDP10.opAOJLE","PDP10.opAOJA","PDP10.opAOJGE","PDP10.opAOJN","PDP10.opAOJG","PDP10.opAOS","PDP10.opAOSL","PDP10.opAOSE","PDP10.opAOSLE","PDP10.opAOSA","PDP10.opAOSGE","PDP10.opAOSN","PDP10.opAOSG","PDP10.opSOJ","PDP10.opSOJL","PDP10.opSOJE","PDP10.opSOJLE","PDP10.opSOJA","PDP10.opSOJGE","PDP10.opSOJN","PDP10.opSOJG","PDP10.opSOS","PDP10.opSOSL","PDP10.opSOSE","PDP10.opSOSLE","PDP10.opSOSA","PDP10.opSOSGE","PDP10.opSOSN","PDP10.opSOSG","PDP10.opSETZM","PDP10.opSETZB","PDP10.opAND","PDP10.opANDI","PDP10.opANDM","PDP10.opANDB","PDP10.opANDCA","PDP10.opANDCAI","PDP10.opANDCAM","PDP10.opANDCAB","PDP10.opANDCM","PDP10.opANDCMI","PDP10.opANDCMM","PDP10.opANDCMB","PDP10.opXOR","PDP10.opXORI","PDP10.opXORM","PDP10.opXORB","PDP10.opIOR","PDP10.opIORI","PDP10.opIORM","PDP10.opIORB","PDP10.opANDCB","PDP10.opANDCBI","PDP10.opANDCBM","PDP10.opANDCBB","PDP10.opEQV","PDP10.opEQVI","PDP10.opEQVM","PDP10.opEQVB","PDP10.opSETCAM","PDP10.opSETCAB","PDP10.opORCA","PDP10.opORCAI","PDP10.opORCAM","PDP10.opORCAB","PDP10.opSETCM","PDP10.opSETCMI","PDP10.opSETCMM","PDP10.opSETCMB","PDP10.opORCM","PDP10.opORCMI","PDP10.opORCMM","PDP10.opORCMB","PDP10.opORCB","PDP10.opORCBI","PDP10.opORCBM","PDP10.opORCBB","PDP10.opSETOM","PDP10.opSETOB","PDP10.opTRNE","PDP10.opTLNE","PDP10.opTRNA","PDP10.opTLNA","PDP10.opTRNN","PDP10.opTLNN","PDP10.opTDNE","PDP10.opTSNE","PDP10.opTDNA","PDP10.opTSNA","PDP10.opTDNN","PDP10.opTSNN","PDP10.opTRZ","PDP10.opTLZ","PDP10.opTRZE","PDP10.opTLZE","PDP10.opTRZA","PDP10.opTLZA","PDP10.opTRZN","PDP10.opTLZN","PDP10.opTDZ","PDP10.opTSZ","PDP10.opTDZE","PDP10.opTSZE","PDP10.opTDZA","PDP10.opTSZA","PDP10.opTDZN","PDP10.opTSZN","PDP10.opTRC","PDP10.opTLC","PDP10.opTRCE","PDP10.opTLCE","PDP10.opTRCA","PDP10.opTLCA","PDP10.opTRCN","PDP10.opTLCN","PDP10.opTDC","PDP10.opTSC","PDP10.opTDCE","PDP10.opTSCE","PDP10.opTDCA","PDP10.opTSCA","PDP10.opTDCN","PDP10.opTSCN","PDP10.opTRO","PDP10.opTLO","PDP10.opTROE","PDP10.opTLOE","PDP10.opTROA","PDP10.opTLOA","PDP10.opTRON","PDP10.opTLON","PDP10.opTDO","PDP10.opTSO","PDP10.opTDOE","PDP10.opTSOE","PDP10.opTDOA","PDP10.opTSOA","PDP10.opTDON","PDP10.opTSON","PDP10.opBLKI","PDP10.opDATAI","PDP10.opBLKO","PDP10.opDATAO","PDP10.opCONO","dev","DEVICES","WFLAG","writeFlags","PDP10.opCONI","readFlags","RFLAG","PDP10.opCONSZ","PDP10.opCONSO","ROMPDP10","parmsROM","abInit","addrROM","sizeROM","addrAlias","sFilePath","Str.getBaseName","sFileURL","sFileExt","Str.getExtension","FORMAT","Web.getHost","rom","Web.getResource","doneLoad","sResponse","Component.addMachineResource","Web.parseMemoryResource","initROM","addSymbols","addROM","aliases","cloneROM","aBlocks","aeROM","iROM","eROM","RAMPDP10","parmsRAM","addrRAM","sizeRAM","fAllocated","ram","initRAM","RAM","loadImage","zero","pattern","len","addrInit","fStart","fLoaded","aeRAM","iRAM","eRAM","SerialPortPDP10","parmsSerial","fUpperCase","fNullModem","abReceive","target","connection","sendData","initConnection","receiveData","receiveStatus","setConnection","SerialPortPDP10.prototype","serial","onkeydown","control.onkeydown","bASCII","keyCode","KEYCODE","altKey","Keys.ASCII.CTRL_H","Keys.ASCII.DEL","ctrlKey","Keys.ASCII.A","Keys.ASCII.Z","Keys.ASCII.CTRL_A","onkeypress","control.onkeypress","metaKey","which","Keys.ASCII.CTRL_M","Keys.ASCII.CTRL_J","onpaste","control.onpaste","stopPropagation","clipboardData","getData","removeAttribute","sConnection","asParts","sSourceID","Str.trim","sTargetID","fnConnect","bASCIIPrev","charCodeAt","LF","CR","aeSerial","iSerial","eSerial","Debugger","parmsDbg","nBase","nBits","achGroup","achAddress","fAssemble","iPrevCmd","aPrevCmds","aVariables","getRegIndex","getRegValue","parseCommand","sCmd","chSep","iPrev","chQuote","substring","evalAND","truncate","Debugger.TWO_POW32","evalXOR","evalMUL","fUnsigned","vNew","limit","evalOps","aVals","aOps","cOps","chOp","pop","val2","val1","valNew","evalIOR","parseArray","asValues","iValue","iLimit","aUndefined","fError","nUnary","nBasePrev","sOp","parseValue","cOpen","iStart","parseUnary","aBinOp","Debugger.aDECOpPrecedence","Debugger.aBinOpPrecedence","parseASCII","sExp","chDelim","cchMax","parseExpression","fQuiet","fPrint","join","regExp","printValue","bit","iReg","getVariable","sVar","sUndefined","getVariableFixup","valueUndefined","fDefined","resetVariables","printVariable","cVariables","aVars","keys","sort","Str.toDec","DebuggerPDP10","dbgAddrAcc","newAddr","dbgAddrCode","dbgAddrData","dbgAddrAssemble","aSymbolTable","aBreakExec","clearBreakpoints","iInstructionHistory","nBreakInstructions","aInstructionHistory","nextHistory","historyInit","afnDumpers","sMessagePrev","aMessageBuffer","messageInit","nStep","sCmdDumpPrev","sCmdTracePrev","nCyclesStart","msStart","cInstructions","nSuppressBreaks","macro10","controlDebug","global","getAddr","dbgAddr","ADDR_INVALID","fPhysical","fTemporary","setAddr","packAddr","unpackAddr","aAddr","aCmds","DebuggerPDP10.prototype","sMessages","sCommands","messageDump","onDumpBus","asArgs","sAddr","parseAddr","typePrev","cPrev","setSelectionRange","Web.onClickRepeat","onClickDebugEnter","onClickStep","fRepeat","fCompleted","scrollX","scrollY","focus","scrollTo","DebuggerPDP10_prototype$getWord","getWord","DebuggerPDP10_prototype$setWord","setWord","chOpen","parseReference","chClose","chEscape","chInnerEscape","reSubExp","sReplace","dbgAddrTmp","sSymbol","sUpperCase","iTable","toUpperCase","findSymbolAddr","symbol","symbolTable","offSymbol","validateWord","parseAddrOptions","sOptions","toStrWord","sEnable","aEnable","fnDumper","sReg","DebuggerPDP10.REGNAMES.indexOf","DebuggerPDP10.REGS.PC","DebuggerPDP10.REGS.RA","DebuggerPDP10.REGS.EA","DebuggerPDP10.REGS.PS","DebuggerPDP10.REGS.OV","DebuggerPDP10.REGS.C0","DebuggerPDP10.REGS.C1","DebuggerPDP10.REGS.BI","DebuggerPDP10.REGS.ND","DebuggerPDP10.REGS.PD","toStrAddr","fRunning","DebuggerPDP10.HISTORY_LIMIT","checkCPU","fRegs","fUpdateDisplays","DebuggerPDP10.PROMPT","doRegisters","doUnassemble","clearTempBreakpoint","sStopped","msTotal","nState","opCode","getInstruction","sComment","nSequence","dbgAddrOp","opNum","iMode","PDP10.OPCODE.OP_SCALE","DebuggerPDP10.OPTABLE","opMasks","opMask","aModes","DebuggerPDP10.OPMODES","DebuggerPDP10.OPCOMPS","DebuggerPDP10.OPTESTS","sMode","DebuggerPDP10.OPS.MOVM","sOperation","DebuggerPDP10.OPNAMES","PDP10.OPCODE.IO_SCALE","sOperand","findInstruction","DebuggerPDP10.ALTOPS.length","DebuggerPDP10.ALTOPS","opAlt","Str.pad","sOpcodes","sLine","parseInstruction","sOpcode","sOperands","sMnemonic","opMode","aOperands","operand","toStrOffset","aBreak","findBreakpoint","printBreakpoint","fFound","dbgAddrBreak","listBreakpoints","sAction","fBreak","addrBreak","doCommand","getRegDump","fMisc","sDump","getAccOutput","DebuggerPDP10.REGNAMES.length","DebuggerPDP10.REGNAMES","getMiscDump","comparePairs","p1","p2","sModule","aOffsets","sAnnotation","Usr.binarySearch","findSymbol","fNearest","aSymbol","addrSymbol","returnSymbol","aWords","addrStart","nWords","addrLo","addrHi","forEach","sStart","iOffset","offset","doAssemble","sFile","Macro10","assembleFiles","doneMacro10","doVar","delVariable","setVariable","doList","nDelta","sDelta","fInstruction","flag","setRegValue","doPrint","doTrace","sCount","nCount","Web.onCountRepeat","onCountStep","onCountStepComplete","sAddrEnd","nLines","nBytes","dbgAddrEnd","nPrinted","sLabel","dbgCopy","sDelim","iLast","s0","ch0","unshift","doBreak","cBreaks","doClear","controlPrint","sLen","sBytes","sDumpers","doDump","sState","powerOff","sSymbolOrig","sMore","cHistory","iHistory","aHistory","nPrev","sPrev","sLines","aFilters","dbgAddrNew","sInstruction","cOverrides","fJSON","nWordsPerLine","sChars","fnGet","doEdit","fnSet","doRun","doHalt","doIf","doStackTrace","cFrames","dbgAddrCall","dbgAddrStack","nFrames","sCall","cTests","addrOrig","sCallPrev","fCriteria","sCategory","doMessages","sCategories","fEnabled","bitMessage","nRegs","sOption","doStep","doOptions","DebuggerPDP10.COMMANDS","doHelp","MOVM","PC","RA","EA","PS","OV","C0","C1","BI","ND","PD","UUO","UFA","DFN","FSC","IBP","ILDB","LDB","IDPB","DPB","ASH","ROT","LSH","JFFO","ASHC","ROTC","LSHC","EXCH","BLT","AOBJP","AOBJN","JRST","JFCL","XCT","PUSHJ","PUSH","POP","POPJ","JSR","JSP","JSA","JRA","FAD","FADR","FSB","FSBR","FMP","FMPR","FDV","FDVR","MOVE","MOVS","MOVN","IMUL","MUL","IDIV","DIV","ADD","SUB","SETZ","AND","ANDCA","SETM","ANDCM","SETA","XOR","IOR","ANDCB","EQV","SETCA","ORCA","SETCM","ORCM","ORCB","SETO","HLL","HRL","HLLZ","HRLZ","HLLO","HRLO","HLLE","HRLE","HRR","HLR","HRRZ","HLRZ","HRRO","HLRO","HRRE","HLRE","CAI","CAM","JUMP","SKIP","AOJ","AOS","SOJ","SOS","TR","TL","TD","TS","BLKI","DATAI","BLKO","DATAO","CONO","CONI","CONSZ","CONSO","DebuggerPDP10.JFCL","JOV","JCRY0","JCRY1","JCRY","JFOV","DebuggerPDP10.JRST","JRSTF","JEN","aeDbg","iDbg","eDbg","iURL","aURLs","anLines","asLines","tblMacros","tblSymbols","aLiterals","aFixups","aLineRefs","nLine","nError","nLiteral","nLocation","nLocationScope","stackScopes","sOperator","nMacroDef","sMacroDef","chMacroOpen","chMacroClose","reLine","macroCall","chASCII","sASCII","assembleString","parseResources","loadNextResource","sExt","processMacro10","sResource","Str.endsWith","warning","addSymbol","getLineRef","parseLine","doLiterals","doVariables","processFixup","aValues","aDefaults","defASCII","fParse","matchLine","Macro10.PSEUDO_OP.IRP","Macro10.PSEUDO_OP.IRPC","iParm","macroDef","iSearch","iMatch","iMatchEnd","chPre","chPost","appendMacro","sSeparator","sRemainder","Macro10.SYMTYPE.LABEL","matchOp","nType","PRIVATE","Macro10.SYMTYPE.INTERNAL","sLiteral","getLiteral","defMacro","Macro10.PSEUDO_OP.LITERAL","getReserved","parseMacro","Macro10.PSEUDO_OP.ASCII","Macro10.PSEUDO_OP.ASCIZ","Macro10.PSEUDO_OP.SIXBIT","Macro10.PSEUDO_OP.BLOCK","defBLOCK","Macro10.PSEUDO_OP.BYTE","nValue","nBitsRemaining","getExpression","defBYTE","genWord","Macro10.PSEUDO_OP.END","defEND","Macro10.PSEUDO_OP.EXP","defWord","Macro10.PSEUDO_OP.LIT","Macro10.PSEUDO_OP.LOC","defLocation","Macro10.PSEUDO_OP.VAR","Macro10.PSEUDO_OP.XWD","defXWD","Macro10.PSEUDO_OP.DEFINE","Macro10.PSEUDO_OP.IF1","Macro10.PSEUDO_OP.IFDEF","Macro10.PSEUDO_OP.IFDIF","Macro10.PSEUDO_OP.IFE","Macro10.PSEUDO_OP.IFG","Macro10.PSEUDO_OP.IFGE","Macro10.PSEUDO_OP.IFIDN","Macro10.PSEUDO_OP.IFL","Macro10.PSEUDO_OP.IFLE","Macro10.PSEUDO_OP.IFN","Macro10.PSEUDO_OP.IFNDEF","Macro10.PSEUDO_OP.OPDEF","Macro10.PSEUDO_OP.REPEAT","Macro10.PSEUDO_OP.PURGE","getValues","delSymbols","Macro10.PSEUDO_OP.LALL","Macro10.PSEUDO_OP.LIST","Macro10.PSEUDO_OP.NOSYM","Macro10.PSEUDO_OP.PAGE","Macro10.PSEUDO_OP.SUBTTL","Macro10.PSEUDO_OP.TITLE","Macro10.PSEUDO_OP.XALL","Macro10.PSEUDO_OP.XLIST","macro","nOperand","Macro10.MACRO_OP.OPDEF","parseText","pushScope","sFixup","popScope","macroPrev","parseLiteral","iLine","scope","fQuotes","cNesting","sEval","iBegin","iEnd","sReserved","Macro10.MACRO_OP.RESERVED","fParens","cchPrefix","nConversion","getString","sRemain","genASCII","Macro10.MACRO_OP.DEFINE","Macro10.MACRO_OP.LITERAL","sOperand2","isDefined","sym","nLocationLiterals","lit","sError","sWarning","LABEL","INTERNAL","ASCIZ","BLOCK","BYTE","DEFINE","END","EXP","IF1","IFDEF","IFDIF","IFE","IFG","IFGE","IFIDN","IFL","IFLE","IFN","IFNDEF","IRP","IRPC","LALL","LIT","LITERAL","LIST","LOC","NOSYM","OPDEF","PAGE","PURGE","REPEAT","SIXBIT","SUBTTL","TITLE","VAR","XALL","XWD","XLIST","RESERVED","ComputerPDP10","parmsComputer","parmsMachine","fSuspended","setMachineParms","fAutoPower","BOOLEAN","nPowerChange","sStateData","sResumePath","sStatePath","fServerState","fStateData","stateComputer","stateFailSafe","fInitialized","fRestoreError","url","random","sUserID","queryUserID","LICENSE","sResume","resume","fAllowResume","ComputerPDP10.RESUME_NONE","APPVERSION","load","getServerStatePath","doneStateLoad","wait","powerOn","parmsComponent","sParmLC","Web.getURLParm","defaultValue","NUMBER","ComputerPDP10.prototype","onComponentReady","validateState","stateValidate","ComputerPDP10.STATE_VALIDATE","sTimestampValidate","get","ComputerPDP10.STATE_TIMESTAMP","sTimestampComputer","clear","ComputerPDP10.RESUME_AUTO","fRestore","ComputerPDP10.RESUME_REPOWER","ComputerPDP10.STATE_FAILSAFE","powerReport","ComputerPDP10.RESUME_PROMPT","unload","Usr.formatDate","store","fValidate","Component.confirmUser","sCode","RES","CODE","FAIL","Web.setLocalStorageItem","ComputerPDP10.STATE_USERID","resetUserID","powerRestore","donePowerOn","reload","asComments","controlPower","getUserID","dataPost","sUser","TYPE","sReport","sReportURL","sTimestamp","ComputerPDP10.STATE_VERSION","ComputerPDP10.STATE_HOSTURL","href","ComputerPDP10.STATE_BROWSER","fClearAll","fClear","saveServerState","ComputerPDP10.RESUME_DELETE","nDisplayLimit","getSpeedCurrent","fWaiting","displayValue","sVal","removeChild","fPrompt","Web.getLocalStorageItem","prompt","verifyUserID","code","State.key","QUERY","REQ","storeServerState","ENDPOINT","fScroll","aeMachines","iMachine","eMachine","aeComputers","iComputer","eComputer","show","exit","sVersion","json","fParsed","key","State.prototype","Web.hasLocalStorage","stringify","fAll","cAsyncMachines","loadXML","sXMLFile","fResolve","display","doneLoadXML","sURLName","sXML","parseXML","buildXML","pathname","xmlDoc","async","parseFromString","DOMParser","resolveXML","matchRef","reRef","sRefFile","doneReadXML","sXMLRef","sRefAttrs","aXMLRefTag","sXMLNewTag","matchAttr","reAttr","embedMachine","sXSLFile","displayMessage","eWarning","aeWarning","innerHTML","Str.escapeHTML","displayError","Web.enablePageEvents","getElementById","css","head","createElement","styleSheet","cssText","appendChild","createTextNode","sAppFolder","processXML","xml","transformXML","sXSL","xsl","sFragment","outerHTML","implementation","createDocument","xsltProcessor","XSLTProcessor","eFragment","replaceChild","embedPDP10","embedPDP11","commandMachine","fSingle","sComponent","sToken","disabled"],"sourcesContent":["\"use strict\";\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/defines.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @define {string}\n */\nvar APPVERSION = \"\"; // this @define is overridden by the Closure Compiler with the version in machines.json\n\nvar XMLVERSION = null; // this is set in non-COMPILED builds by embedMachine() if a version number was found in the machine XML\n\nvar COPYRIGHT = \"Copyright © 2012-2018 Jeff Parsons <Jeff@pcjs.org>\";\n\nvar LICENSE = \"License: GPL version 3 or later <http://gnu.org/licenses/gpl.html>\";\n\nvar CSSCLASS = \"pcjs\";\n\n/**\n * @define {string}\n */\nvar SITEHOST = \"localhost:8088\";// this @define is overridden by the Closure Compiler with \"www.pcjs.org\"\n\n/**\n * @define {boolean}\n */\nvar COMPILED = false; // this @define is overridden by the Closure Compiler (to true)\n\n/**\n * @define {boolean}\n */\nvar DEBUG = true; // this @define is overridden by the Closure Compiler (to false) to remove DEBUG-only code\n\n/**\n * @define {boolean}\n */\nvar MAXDEBUG = false; // this @define is overridden by the Closure Compiler (to false) to remove MAXDEBUG-only code\n\n/**\n * @define {boolean}\n */\nvar PRIVATE = false; // this @define is overridden by the Closure Compiler (to false) to enable PRIVATE code\n\n/*\n * RS-232 DB-25 Pin Definitions, mapped to bits 1-25 in a 32-bit status value.\n *\n * SerialPorts in PCjs machines are considered DTE (Data Terminal Equipment), which means they should be \"virtually\"\n * connected to each other via a null-modem cable, which assumes the following cross-wiring:\n *\n * G 1 <-> 1 G (Ground)\n * TD 2 <-> 3 RD (Received Data)\n * RD 3 <-> 2 TD (Transmitted Data)\n * RTS 4 <-> 5 CTS (Clear To Send)\n * CTS 5 <-> 4 RTS (Request To Send)\n * DSR 6+8 <-> 20 DTR (Data Terminal Ready)\n * SG 7 <-> 7 SG (Signal Ground)\n * DTR 20 <-> 6+8 DSR (Data Set Ready + Carrier Detect)\n * RI 22 <-> 22 RI (Ring Indicator)\n *\n * TODO: Move these definitions to a more appropriate shared file at some point.\n */\nvar RS232 = {\n RTS: {\n PIN: 4,\n MASK: 0x00000010\n },\n CTS: {\n PIN: 5,\n MASK: 0x00000020\n },\n DSR: {\n PIN: 6,\n MASK: 0x00000040\n },\n CD: {\n PIN: 8,\n MASK: 0x00000100\n },\n DTR: {\n PIN: 20,\n MASK: 0x00100000\n },\n RI: {\n PIN: 22,\n MASK: 0x00400000\n }\n};\n\n/*\n * NODE should be true if we're running under NodeJS (eg, command-line), false if not (eg, web browser)\n */\nvar NODE = false;\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/dumpapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Our \"DiskDump API\", such as it was, used to look like:\n *\n * http://jsmachines.net/bin/convdisk.php?disk=/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json&format=img\n *\n * To make it (a bit) more \"REST-like\", the above request now looks like:\n *\n * http://www.pcjs.org/api/v1/dump?disk=/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json&format=img\n *\n * Similarly, our \"FileDump API\" used to look like:\n *\n * http://jsmachines.net/bin/convrom.php?rom=/devices/pc/rom/5150/1981-04-24/PCBIOS-REV1.rom&format=json\n *\n * and that request now looks like:\n *\n * http://www.pcjs.org/api/v1/dump?file=/devices/pc/rom/5150/1981-04-24/PCBIOS-REV1.rom&format=json\n *\n * I don't think it makes sense to avoid \"query\" parameters, because blending the path of a disk image with the\n * the rest of the URL would be (a) confusing, and (b) more work to parse.\n */\nvar DumpAPI = {\n ENDPOINT: \"/api/v1/dump\",\n QUERY: {\n DIR: \"dir\", // value is path of a directory (DiskDump only)\n DISK: \"disk\", // value is path of a disk image (DiskDump only)\n FILE: \"file\", // value is path of a ROM image file (FileDump only)\n IMG: \"img\", // alias for DISK\n PATH: \"path\", // value is path of a one or more files (DiskDump only)\n FORMAT: \"format\", // value is one of FORMAT values below\n COMMENTS: \"comments\", // value is either \"true\" or \"false\"\n DECIMAL: \"decimal\", // value is either \"true\" to force all numbers to decimal, \"false\" or undefined otherwise\n MBHD: \"mbhd\", // value is hard drive size in Mb (formerly \"mbsize\") (DiskDump only) (DEPRECATED)\n SIZE: \"size\" // value is target disk size in Kb (supersedes \"mbhd\") (DiskDump only)\n },\n FORMAT: {\n JSON: \"json\", // default\n JSON_GZ: \"gz\", // gzip is currently used ONLY for compressed JSON\n DATA: \"data\", // same as \"json\", but built without JSON.stringify() (DiskDump only)\n HEX: \"hex\", // deprecated\n OCTAL: \"octal\", // displays data as octal words\n BYTES: \"bytes\", // displays data as hex bytes; normally used only when comments are enabled\n WORDS: \"words\", // displays data as hex words; normally used only when comments are enabled\n LONGS: \"longs\", // displays data as dwords\n IMG: \"img\", // returns the raw disk data (ie, using a Buffer object) (DiskDump only)\n ROM: \"rom\" // returns the raw file data (ie, using a Buffer object) (FileDump only)\n }\n};\n\n/*\n * Because we use an overloaded API endpoint (ie, one that's shared with the FileDump module), we must\n * also provide a list of commands which, when combined with the endpoint, define a unique request.\n */\nDumpAPI.asDiskCommands = [DumpAPI.QUERY.DIR, DumpAPI.QUERY.DISK, DumpAPI.QUERY.PATH];\nDumpAPI.asFileCommands = [DumpAPI.QUERY.FILE];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/reportapi.js (C) Jeff Parsons 2012-2018\n */\n\nvar ReportAPI = {\n ENDPOINT: \"/api/v1/report\",\n QUERY: {\n APP: \"app\",\n VER: \"ver\",\n URL: \"url\",\n USER: \"user\",\n TYPE: \"type\",\n DATA: \"data\"\n },\n TYPE: {\n BUG: \"bug\"\n },\n RES: {\n OK: \"Thank you\"\n }\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/userapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Examples of User API requests:\n *\n * web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.VERIFY + '&' + UserAPI.QUERY.USER + '=' + sUser;\n */\nvar UserAPI = {\n ENDPOINT: \"/api/v1/user\",\n QUERY: {\n REQ: \"req\", // specifies a request\n USER: \"user\", // specifies a user ID\n STATE: \"state\", // specifies a state ID\n DATA: \"data\" // specifies state data\n },\n REQ: {\n CREATE: \"create\", // creates a user ID\n VERIFY: \"verify\", // requests verification of a user ID\n STORE: \"store\", // stores a machine state on the server\n LOAD: \"load\" // loads a machine state from the server\n },\n RES: {\n CODE: \"code\",\n DATA: \"data\"\n },\n CODE: {\n OK: \"ok\",\n FAIL: \"error\"\n },\n FAIL: {\n DUPLICATE: \"user already exists\",\n VERIFY: \"unable to verify user\",\n BADSTATE: \"invalid state parameter\",\n NOSTATE: \"no machine state\",\n BADLOAD: \"unable to load machine state\",\n BADSTORE: \"unable to save machine state\"\n }\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/keys.js (C) Jeff Parsons 2012-2018\n */\n\nvar Keys = {\n /*\n * Keys and/or key combinations that generate common ASCII codes.\n *\n * NOTE: If you're looking for a general-purpose ASCII code table, see Str.ASCII in strlib.js;\n * if something's missing, that's probably the more appropriate table to add it to.\n *\n * TODO: The Closure Compiler doesn't inline all references to these values, at least those with\n * quoted property names, which is why I've 'unquoted' as many of them as possible. One solution\n * would be to add mnemonics for all of them, not just the non-printable ones (eg, SPACE instead\n * of ' ', AMP instead of '&', etc.)\n */\n ASCII: {\n BREAK: 0, CTRL_A: 1, CTRL_B: 2, CTRL_C: 3, CTRL_D: 4, CTRL_E: 5, CTRL_F: 6, CTRL_G: 7,\n CTRL_H: 8, CTRL_I: 9, CTRL_J: 10, CTRL_K: 11, CTRL_L: 12, CTRL_M: 13, CTRL_N: 14, CTRL_O: 15,\n CTRL_P: 16, CTRL_Q: 17, CTRL_R: 18, CTRL_S: 19, CTRL_T: 20, CTRL_U: 21, CTRL_V: 22, CTRL_W: 23,\n CTRL_X: 24, CTRL_Y: 25, CTRL_Z: 26, ESC: 27,\n ' ': 32, '!': 33, '\"': 34, '#': 35, '$': 36, '%': 37, '&': 38, \"'\": 39,\n '(': 40, ')': 41, '*': 42, '+': 43, ',': 44, '-': 45, '.': 46, '/': 47,\n '0': 48, '1': 49, '2': 50, '3': 51, '4': 52, '5': 53, '6': 54, '7': 55,\n '8': 56, '9': 57, ':': 58, ';': 59, '<': 60, '=': 61, '>': 62, '?': 63,\n '@': 64, A: 65, B: 66, C: 67, D: 68, E: 69, F: 70, G: 71,\n H: 72, I: 73, J: 74, K: 75, L: 76, M: 77, N: 78, O: 79,\n P: 80, Q: 81, R: 82, S: 83, T: 84, U: 85, V: 86, W: 87,\n X: 88, Y: 89, Z: 90, '[': 91, '\\\\':92, ']': 93, '^': 94, '_': 95,\n '`': 96, a: 97, b: 98, c: 99, d: 100, e: 101, f: 102, g: 103,\n h: 104, i: 105, j: 106, k: 107, l: 108, m: 109, n: 110, o: 111,\n p: 112, q: 113, r: 114, s: 115, t: 116, u: 117, v: 118, w: 119,\n x: 120, y: 121, z: 122, '{':123, '|':124, '}':125, '~':126, DEL: 127\n },\n /*\n * Browser keyCodes we must pay particular attention to. For the most part, these are non-alphanumeric\n * or function keys, some which may require special treatment (eg, preventDefault() if returning false on\n * the initial keyDown event is insufficient).\n *\n * keyCodes for most common ASCII keys can simply use the appropriate ASCII code above.\n *\n * Most of these represent non-ASCII keys (eg, the LEFT arrow key), yet for some reason, browsers defined\n * them using ASCII codes (eg, the LEFT arrow key uses the ASCII code for '%' or 37).\n */\n KEYCODE: {\n /* 0x08 */ BS: 8, // BACKSPACE (ASCII.CTRL_H)\n /* 0x09 */ TAB: 9, // TAB (ASCII.CTRL_I)\n /* 0x0A */ LF: 10, // LINE-FEED (ASCII.CTRL_J) (Some Windows-based browsers used to generate this via CTRL-ENTER)\n /* 0x0D */ CR: 13, // CARRIAGE RETURN (ASCII.CTRL_M)\n /* 0x10 */ SHIFT: 16,\n /* 0x11 */ CTRL: 17,\n /* 0x12 */ ALT: 18,\n /* 0x13 */ PAUSE: 19, // PAUSE/BREAK\n /* 0x14 */ CAPS_LOCK: 20,\n /* 0x1B */ ESC: 27,\n /* 0x20 */ SPACE: 32,\n /* 0x21 */ PGUP: 33,\n /* 0x22 */ PGDN: 34,\n /* 0x23 */ END: 35,\n /* 0x24 */ HOME: 36,\n /* 0x25 */ LEFT: 37,\n /* 0x26 */ UP: 38,\n /* 0x27 */ RIGHT: 39,\n /* 0x27 */ FF_QUOTE: 39,\n /* 0x28 */ DOWN: 40,\n /* 0x2C */ FF_COMMA: 44,\n /* 0x2C */ PRTSC: 44,\n /* 0x2D */ INS: 45,\n /* 0x2E */ DEL: 46,\n /* 0x2E */ FF_PERIOD: 46,\n /* 0x2F */ FF_SLASH: 47,\n /* 0x30 */ ZERO: 48,\n /* 0x31 */ ONE: 49,\n /* 0x32 */ TWO: 50,\n /* 0x33 */ THREE: 51,\n /* 0x34 */ FOUR: 52,\n /* 0x35 */ FIVE: 53,\n /* 0x36 */ SIX: 54,\n /* 0x37 */ SEVEN: 55,\n /* 0x38 */ EIGHT: 56,\n /* 0x39 */ NINE: 57,\n /* 0x3B */ FF_SEMI: 59,\n /* 0x3D */ FF_EQUALS: 61,\n /* 0x5B */ CMD: 91, // aka WIN\n /* 0x5B */ FF_LBRACK: 91,\n /* 0x5C */ FF_BSLASH: 92,\n /* 0x5D */ RCMD: 93, // aka MENU\n /* 0x5D */ FF_RBRACK: 93,\n /* 0x60 */ NUM_0: 96,\n /* 0x60 */ NUM_INS: 96,\n /* 0x60 */ FF_BQUOTE: 96,\n /* 0x61 */ NUM_1: 97,\n /* 0x61 */ NUM_END: 97,\n /* 0x62 */ NUM_2: 98,\n /* 0x62 */ NUM_DOWN: 98,\n /* 0x63 */ NUM_3: 99,\n /* 0x63 */ NUM_PGDN: 99,\n /* 0x64 */ NUM_4: 100,\n /* 0x64 */ NUM_LEFT: 100,\n /* 0x65 */ NUM_5: 101,\n /* 0x65 */ NUM_CENTER: 101,\n /* 0x66 */ NUM_6: 102,\n /* 0x66 */ NUM_RIGHT: 102,\n /* 0x67 */ NUM_7: 103,\n /* 0x67 */ NUM_HOME: 103,\n /* 0x68 */ NUM_8: 104,\n /* 0x68 */ NUM_UP: 104,\n /* 0x69 */ NUM_9: 105,\n /* 0x69 */ NUM_PGUP: 105,\n /* 0x6A */ NUM_MUL: 106,\n /* 0x6B */ NUM_ADD: 107,\n /* 0x6D */ NUM_SUB: 109,\n /* 0x6E */ NUM_DEL: 110, // aka PERIOD\n /* 0x6F */ NUM_DIV: 111,\n /* 0x70 */ F1: 112,\n /* 0x71 */ F2: 113,\n /* 0x72 */ F3: 114,\n /* 0x73 */ F4: 115,\n /* 0x74 */ F5: 116,\n /* 0x75 */ F6: 117,\n /* 0x76 */ F7: 118,\n /* 0x77 */ F8: 119,\n /* 0x78 */ F9: 120,\n /* 0x79 */ F10: 121,\n /* 0x7A */ F11: 122,\n /* 0x7B */ F12: 123,\n /* 0x90 */ NUM_LOCK: 144,\n /* 0x91 */ SCROLL_LOCK: 145,\n /* 0xAD */ FF_DASH: 173,\n /* 0xBA */ SEMI: 186, // Firefox: 59 (FF_SEMI)\n /* 0xBB */ EQUALS: 187, // Firefox: 61 (FF_EQUALS)\n /* 0xBC */ COMMA: 188,\n /* 0xBD */ DASH: 189, // Firefox: 173 (FF_DASH)\n /* 0xBE */ PERIOD: 190,\n /* 0xBF */ SLASH: 191,\n /* 0xC0 */ BQUOTE: 192,\n /* 0xDB */ LBRACK: 219,\n /* 0xDC */ BSLASH: 220,\n /* 0xDD */ RBRACK: 221,\n /* 0xDE */ QUOTE: 222,\n /* 0xE0 */ FF_CMD: 224, // Firefox only (used for both CMD and RCMD)\n //\n // The following biases use what I'll call Decimal Coded Binary or DCB (the opposite of BCD),\n // where the thousands digit is used to store the sum of \"binary\" digits 1 and/or 2 and/or 4.\n //\n // Technically, that makes it DCO (Decimal Coded Octal), but then again, BCD should have really\n // been called HCD (Hexadecimal Coded Decimal), so if \"they\" can take liberties, so can I.\n //\n // ONDOWN is a bias we add to browser keyCodes that we want to handle on \"down\" rather than on \"press\".\n //\n ONDOWN: 1000,\n //\n // ONRIGHT is a bias we add to browser keyCodes that need to check for a \"right\" location (default is \"left\")\n //\n ONRIGHT: 2000,\n //\n // FAKE is a bias we add to signal these are fake keyCodes corresponding to internal keystroke combinations.\n // The actual values are for internal use only and merely need to be unique and used consistently.\n //\n FAKE: 4000\n },\n /*\n * The set of values that a browser may store in the 'location' property of a keyboard event object\n * which we also support.\n */\n LOCATION: {\n LEFT: 1,\n RIGHT: 2,\n NUMPAD: 3\n }\n};\n\n/*\n * Check the event object's 'location' property for a non-zero value for the following ONRIGHT keys.\n */\nKeys.KEYCODE.NUM_CR = Keys.KEYCODE.CR + Keys.KEYCODE.ONRIGHT;\n\n\n/*\n * Maps Firefox keyCodes to their more common keyCode counterparts; a number of entries in this table\n * are no longer valid (if indeed they ever were), so they've been commented out. It's likely that I\n * simply extended this table to resolve additional differences in other browsers (ie, Opera), but without\n * browser-specific checks, it's not safe to perform all the mappings shown below.\n */\nKeys.FF_KEYCODES = {};\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_SEMI] = Keys.KEYCODE.SEMI; // 59 -> 186\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_EQUALS] = Keys.KEYCODE.EQUALS; // 61 -> 187\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.KEYCODE.DASH; // 173 -> 189\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_CMD] = Keys.KEYCODE.CMD; // 224 -> 91\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_COMMA] = Keys.KEYCODE.COMMA; // 44 -> 188\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_PERIOD] = Keys.KEYCODE.PERIOD; // 46 -> 190\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_SLASH] = Keys.KEYCODE.SLASH; // 47 -> 191\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_BQUOTE] = Keys.KEYCODE.BQUOTE; // 96 -> 192\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_LBRACK = Keys.KEYCODE.LBRACK; // 91 -> 219\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_BSLASH] = Keys.KEYCODE.BSLASH; // 92 -> 220\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_RBRACK] = Keys.KEYCODE.RBRACK; // 93 -> 221\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_QUOTE] = Keys.KEYCODE.QUOTE; // 39 -> 222\n\n/*\n * Maps non-ASCII keyCodes to their ASCII counterparts\n */\nKeys.NONASCII_KEYCODES = {};\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.ASCII['-']; // 173 -> 45\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.SEMI] = Keys.ASCII[';']; // 186 -> 59\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.EQUALS] = Keys.ASCII['=']; // 187 -> 61\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.DASH] = Keys.ASCII['-']; // 189 -> 45\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.COMMA] = Keys.ASCII[',']; // 188 -> 44\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.PERIOD] = Keys.ASCII['.']; // 190 -> 46\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.SLASH] = Keys.ASCII['/']; // 191 -> 47\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.BQUOTE] = Keys.ASCII['`']; // 192 -> 96\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.LBRACK] = Keys.ASCII['[']; // 219 -> 91\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.BSLASH] = Keys.ASCII['\\\\']; // 220 -> 92\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.RBRACK] = Keys.ASCII[']']; // 221 -> 93\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.QUOTE] = Keys.ASCII[\"'\"]; // 222 -> 39\n\n/*\n * Maps unshifted keyCodes to their shifted counterparts; to be used when a shift-key is down.\n * Alphabetic characters are handled in code, since they must also take CAPS_LOCK into consideration.\n */\nKeys.SHIFTED_KEYCODES = {};\nKeys.SHIFTED_KEYCODES[Keys.ASCII['1']] = Keys.ASCII['!'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['2']] = Keys.ASCII['@'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['3']] = Keys.ASCII['#'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['4']] = Keys.ASCII['$'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['5']] = Keys.ASCII['%'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['6']] = Keys.ASCII['^'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['7']] = Keys.ASCII['&'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['8']] = Keys.ASCII['*'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['9']] = Keys.ASCII['('];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['0']] = Keys.ASCII[')'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.SEMI] = Keys.ASCII[':'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.EQUALS] = Keys.ASCII['+'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.COMMA] = Keys.ASCII['<'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.DASH] = Keys.ASCII['_'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.PERIOD] = Keys.ASCII['>'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.SLASH] = Keys.ASCII['?'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.BQUOTE] = Keys.ASCII['~'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.LBRACK] = Keys.ASCII['{'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.BSLASH] = Keys.ASCII['|'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.RBRACK] = Keys.ASCII['}'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.QUOTE] = Keys.ASCII['\"'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.ASCII['_'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_EQUALS] = Keys.ASCII['+'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_SEMI] = Keys.ASCII[':'];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/strlib.js (C) Jeff Parsons 2012-2018\n */\n\nclass Str {\n /**\n * isValidInt(s, base)\n *\n * The built-in parseInt() function has the annoying feature of returning a partial value (ie,\n * up to the point where it encounters an invalid character); eg, parseInt(\"foo\", 16) returns 0xf.\n *\n * So it's best to use our own Str.parseInt() function, which will in turn use this function to\n * validate the entire string.\n *\n * @param {string} s is the string representation of some number\n * @param {number} [base] is the radix to use (default is 10); only 2, 8, 10 and 16 are supported\n * @return {boolean} true if valid, false if invalid (or the specified base isn't supported)\n */\n static isValidInt(s, base)\n {\n if (!base || base == 10) return s.match(/^-?[0-9]+$/) !== null;\n if (base == 16) return s.match(/^-?[0-9a-f]+$/i) !== null;\n if (base == 8) return s.match(/^-?[0-7]+$/) !== null;\n if (base == 2) return s.match(/^-?[01]+$/) !== null;\n return false;\n }\n\n /**\n * parseInt(s, base)\n *\n * This is a wrapper around the built-in parseInt() function. Our wrapper recognizes certain prefixes\n * ('$' or \"0x\" for hex, '#' or \"0o\" for octal) and suffixes ('.' for decimal, 'h' for hex, 'y' for\n * binary), and then calls isValidInt() to ensure we don't convert strings that contain partial values;\n * see isValidInt() for details.\n *\n * The use of multiple prefix/suffix combinations is undefined (although for the record, we process\n * prefixes first). We do NOT support the \"0b\" prefix to indicate binary UNLESS one or more commas are\n * also present (because \"0b\" is also a valid hex sequence), and we do NOT support a single leading zero\n * to indicate octal (because such a number could also be decimal or hex). Any number of commas are\n * allowed; we remove them all before calling the built-in parseInt().\n *\n * More recently, we've added support for \"^D\", \"^O\", and \"^B\" prefixes to accommodate the base overrides\n * that the PDP-10's MACRO-10 assembly language supports (decimal, octal, and binary, respectively).\n * If this support turns out to adversely affect other debuggers, then it will have to be \"conditionalized\".\n * Similarly, we've added support for \"K\", \"M\", and \"G\" MACRO-10-style suffixes that add 3, 6, or 9 zeros\n * to the value to be parsed, respectively.\n *\n * @param {string} s is the string representation of some number\n * @param {number} [base] is the radix to use (default is 10); can be overridden by prefixes/suffixes\n * @return {number|undefined} corresponding value, or undefined if invalid\n */\n static parseInt(s, base)\n {\n var value;\n\n if (s) {\n if (!base) base = 10;\n\n var ch, chPrefix, chSuffix;\n var fCommas = (s.indexOf(',') > 0);\n if (fCommas) s = s.replace(/,/g, '');\n\n ch = chPrefix = s.charAt(0);\n if (chPrefix == '#') {\n base = 8;\n chPrefix = '';\n }\n else if (chPrefix == '$') {\n base = 16;\n chPrefix = '';\n }\n if (ch != chPrefix) {\n s = s.substr(1);\n }\n else {\n ch = chPrefix = s.substr(0, 2);\n if (chPrefix == '0b' && fCommas || chPrefix == '^B') {\n base = 2;\n chPrefix = '';\n }\n else if (chPrefix == '0o' || chPrefix == '^O') {\n base = 8;\n chPrefix = '';\n }\n else if (chPrefix == '^D') {\n base = 10;\n chPrefix = '';\n }\n else if (chPrefix == '0x') {\n base = 16;\n chPrefix = '';\n }\n if (ch != chPrefix) s = s.substr(2);\n }\n ch = chSuffix = s.slice(-1);\n if (chSuffix == 'Y' || chSuffix == 'y') {\n base = 2;\n chSuffix = '';\n }\n else if (chSuffix == '.') {\n base = 10;\n chSuffix = '';\n }\n else if (chSuffix == 'H' || chSuffix == 'h') {\n base = 16;\n chSuffix = '';\n }\n else if (chSuffix == 'K') {\n chSuffix = '000';\n }\n else if (chSuffix == 'M') {\n chSuffix = '000000';\n }\n else if (chSuffix == 'G') {\n chSuffix = '000000000';\n }\n if (ch != chSuffix) s = s.slice(0, -1) + chSuffix;\n /*\n * This adds support for the MACRO-10 binary shifting (Bn) suffix, which must be stripped from the\n * number before parsing, and then applied to the value after parsing. If n is omitted, 35 is assumed,\n * which is a net shift of zero. If n < 35, then a left shift of (35 - n) is required; if n > 35, then\n * a right shift of -(35 - n) is required.\n */\n var v, shift = 0;\n if (base <= 10) {\n var match = s.match(/(-?[0-9]+)B([0-9]*)/);\n if (match) {\n s = match[1];\n shift = 35 - ((match[2] || 35) & 0xff);\n }\n }\n if (Str.isValidInt(s, base) && !isNaN(v = parseInt(s, base))) {\n /*\n * With the need to support larger (eg, 36-bit) integers, truncating to 32 bits is no longer helpful.\n *\n * value = v|0;\n */\n if (shift) {\n /*\n * Since binary shifting is a logical operation, and since shifting by division only works properly\n * with positive numbers, we must convert a negative value to a positive value, by computing the two's\n * complement.\n */\n if (v < 0) v += Math.pow(2, 36);\n if (shift > 0) {\n v *= Math.pow(2, shift);\n } else {\n v = Math.trunc(v / Math.pow(2, -shift));\n }\n }\n value = v;\n }\n }\n return value;\n }\n\n /**\n * toBase(n, radix, cch, sPrefix, nGrouping)\n *\n * Displays the given number as an unsigned integer using the specified radix and number of digits.\n *\n * @param {number|*} n\n * @param {number} radix (ie, the base)\n * @param {number} cch (the desired number of digits)\n * @param {string} [sPrefix] (default is none)\n * @param {number} [nGrouping]\n * @return {string}\n */\n static toBase(n, radix, cch, sPrefix = \"\", nGrouping = 0)\n {\n /*\n * We can't rely entirely on isNaN(), because isNaN(null) returns false, and we can't rely\n * entirely on typeof either, because typeof Nan returns \"number\". Sigh.\n *\n * Alternatively, we could mask and shift n regardless of whether it's null/undefined/NaN,\n * since JavaScript coerces such operands to zero, but I think there's \"value\" in seeing those\n * values displayed differently.\n */\n var s = \"\";\n if (isNaN(n) || typeof n != \"number\") {\n n = null;\n } else {\n /*\n * Callers that produced an input by dividing by a power of two rather than shifting (in order\n * to access more than 32 bits) may produce a fractional result, which ordinarily we would simply\n * ignore, but if the integer portion is zero and the sign is negative, we should probably treat\n * this value as a sign-extension.\n */\n if (n < 0 && n > -1) n = -1;\n /*\n * Negative values should be two's complemented according to the number of digits; for example,\n * 12 octal digits implies an upper limit 8^12.\n */\n if (n < 0) {\n n += Math.pow(radix, cch);\n }\n if (n >= Math.pow(radix, cch)) {\n cch = Math.ceil(Math.log(n) / Math.log(radix));\n }\n }\n var g = nGrouping || -1;\n while (cch-- > 0) {\n if (!g) {\n s = ',' + s;\n g = nGrouping;\n }\n if (n == null) {\n s = '?' + s;\n } else {\n var d = n % radix;\n d += (d >= 0 && d <= 9? 0x30 : 0x41 - 10);\n s = String.fromCharCode(d) + s;\n n = Math.trunc(n / radix);\n }\n g--;\n }\n return sPrefix + s;\n }\n\n /**\n * toBin(n, cch, nGrouping)\n *\n * Converts an integer to binary, with the specified number of digits (up to a maximum of 36).\n *\n * @param {number|*} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of binary digits (0 or undefined for default of either 8, 18, or 36)\n * @param {number} [nGrouping]\n * @return {string} the binary representation of n\n */\n static toBin(n, cch, nGrouping)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.LN2) || 1;\n var v = Math.abs(n);\n if (v <= 0b11111111) {\n cch = 8;\n } else if (v <= 0b111111111111111111) {\n cch = 18;\n } else {\n cch = 36;\n }\n } else if (cch > 36) cch = 36;\n return Str.toBase(n, 2, cch, \"\", nGrouping);\n }\n\n /**\n * toBinBytes(n, cb, fPrefix)\n *\n * Converts an integer to binary, with the specified number of bytes (up to the default of 4).\n *\n * @param {number|null|undefined} n (interpreted as a 32-bit value)\n * @param {number} [cb] is the desired number of binary bytes (4 is both the default and the maximum)\n * @param {boolean} [fPrefix]\n * @return {string} the binary representation of n\n */\n static toBinBytes(n, cb, fPrefix)\n {\n var s = \"\";\n if (!cb || cb > 4) cb = 4;\n for (var i = 0; i < cb; i++) {\n if (s) s = ',' + s;\n s = Str.toBin(n & 0xff, 8) + s;\n n >>= 8;\n }\n return (fPrefix? \"0b\" : \"\") + s;\n }\n\n /**\n * toOct(n, cch, fPrefix)\n *\n * Converts an integer to octal, with the specified number of digits (default of 6; max of 12)\n *\n * You might be tempted to use the built-in n.toString(8) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw\n * an exception, whereas this function will return '?' characters.\n *\n * @param {number|*} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of octal digits (0 or undefined for default of either 6, 8, or 12)\n * @param {boolean} [fPrefix]\n * @return {string} the octal representation of n\n */\n static toOct(n, cch, fPrefix)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.log(8)) || 1;\n var v = Math.abs(n);\n if (v <= 0o777777) {\n cch = 6;\n } else if (v <= 0o77777777) {\n cch = 8;\n } else {\n cch = 12;\n }\n } else if (cch > 12) cch = 12;\n return Str.toBase(n, 8, cch, fPrefix? \"0o\" : \"\");\n }\n\n /**\n * toDec(n, cch)\n *\n * Converts an integer to decimal, with the specified number of digits (default of 5; max of 11)\n *\n * You might be tempted to use the built-in n.toString(10) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw\n * an exception, whereas this function will return '?' characters.\n *\n * @param {number|*} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of decimal digits (0 or undefined for default of either 5 or 11)\n * @return {string} the decimal representation of n\n */\n static toDec(n, cch)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.LN10) || 1;\n var v = Math.abs(n);\n if (v <= 99999) {\n cch = 5;\n } else {\n cch = 11;\n }\n } else if (cch > 11) cch = 11;\n return Str.toBase(n, 10, cch);\n }\n\n /**\n * toHex(n, cch, fPrefix)\n *\n * Converts an integer to hex, with the specified number of digits (default of 4 or 8, max of 9).\n *\n * You might be tempted to use the built-in n.toString(16) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values; for example, if n is -2147483647, then n.toString(16)\n * will return \"-7fffffff\" instead of \"80000001\". Moreover, if n is undefined, n.toString() will\n * throw an exception, whereas this function will return '?' characters.\n *\n * NOTE: The following work-around (adapted from code found on StackOverflow) would be another solution,\n * taking care of negative values, zero-padding, and upper-casing, but not null/undefined/NaN values:\n *\n * s = (n < 0? n + 0x100000000 : n).toString(16);\n * s = \"00000000\".substr(0, 8 - s.length) + s;\n * s = s.substr(0, cch).toUpperCase();\n *\n * @param {number|*} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of hex digits (0 or undefined for default of either 4, 8, or 9)\n * @param {boolean} [fPrefix]\n * @return {string} the hex representation of n\n */\n static toHex(n, cch, fPrefix)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.log(16)) || 1;\n var v = Math.abs(n);\n if (v <= 0xffff) {\n cch = 4;\n } else if (v <= 0xffffffff) {\n cch = 8;\n } else {\n cch = 9;\n }\n } else if (cch > 9) cch = 9;\n return Str.toBase(n, 16, cch, fPrefix? \"0x\" : \"\");\n }\n\n /**\n * toHexByte(b)\n *\n * Alias for Str.toHex(b, 2, true)\n *\n * @param {number|null|undefined} b is a byte value\n * @return {string} the hex representation of b\n */\n static toHexByte(b)\n {\n return Str.toHex(b, 2, true);\n }\n\n /**\n * toHexWord(w)\n *\n * Alias for Str.toHex(w, 4, true)\n *\n * @param {number|null|undefined} w is a word (16-bit) value\n * @return {string} the hex representation of w\n */\n static toHexWord(w)\n {\n return Str.toHex(w, 4, true);\n }\n\n /**\n * toHexLong(l)\n *\n * Alias for Str.toHex(l, 8, true)\n *\n * @param {number|null|undefined} l is a dword (32-bit) value\n * @return {string} the hex representation of w\n */\n static toHexLong(l)\n {\n return Str.toHex(l, 8, true);\n }\n\n /**\n * getBaseName(sFileName, fStripExt)\n *\n * This is a poor-man's version of Node's path.basename(), which Node-only components should use instead.\n *\n * Note that if fStripExt is true, this strips ANY extension, whereas path.basename() strips the extension only\n * if it matches the second parameter (eg, path.basename(\"/foo/bar/baz/asdf/quux.html\", \".html\") returns \"quux\").\n *\n * @param {string} sFileName\n * @param {boolean} [fStripExt]\n * @return {string}\n */\n static getBaseName(sFileName, fStripExt)\n {\n var sBaseName = sFileName;\n\n var i = sFileName.lastIndexOf('/');\n if (i >= 0) sBaseName = sFileName.substr(i + 1);\n\n /*\n * This next bit is a kludge to clean up names that are part of a URL that includes unsightly query parameters.\n */\n i = sBaseName.indexOf('&');\n if (i > 0) sBaseName = sBaseName.substr(0, i);\n\n if (fStripExt) {\n i = sBaseName.lastIndexOf(\".\");\n if (i > 0) {\n sBaseName = sBaseName.substring(0, i);\n }\n }\n return sBaseName;\n }\n\n /**\n * getExtension(sFileName)\n *\n * This is a poor-man's version of Node's path.extname(), which Node-only components should use instead.\n *\n * Note that we EXCLUDE the period from the returned extension, whereas path.extname() includes it.\n *\n * @param {string} sFileName\n * @return {string} the filename's extension (in lower-case and EXCLUDING the \".\"), or an empty string\n */\n static getExtension(sFileName)\n {\n var sExtension = \"\";\n var i = sFileName.lastIndexOf(\".\");\n if (i >= 0) {\n sExtension = sFileName.substr(i + 1).toLowerCase();\n }\n return sExtension;\n }\n\n /**\n * endsWith(s, sSuffix)\n *\n * @param {string} s\n * @param {string} sSuffix\n * @return {boolean} true if s ends with sSuffix, false if not\n */\n static endsWith(s, sSuffix)\n {\n return s.indexOf(sSuffix, s.length - sSuffix.length) !== -1;\n }\n\n /**\n * escapeHTML(sHTML)\n *\n * @param {string} sHTML\n * @return {string} with HTML entities \"escaped\", similar to PHP's htmlspecialchars()\n */\n static escapeHTML(sHTML)\n {\n return sHTML.replace(/[&<>\"']/g, function(m)\n {\n return Str.HTMLEscapeMap[m];\n });\n }\n\n /**\n * replace(sSearch, sReplace, s)\n *\n * The JavaScript replace() function ALWAYS interprets \"$\" specially in replacement strings, even when\n * the search string is NOT a RegExp; specifically:\n *\n * $$ Inserts a \"$\"\n * $& Inserts the matched substring\n * $` Inserts the portion of the string that precedes the matched substring\n * $' Inserts the portion of the string that follows the matched substring\n * $n Where n is a positive integer less than 100, inserts the nth parenthesized sub-match string,\n * provided the first argument was a RegExp object\n *\n * So, if a replacement string containing dollar signs passes through a series of replace() calls, untold\n * problems could result. Hence, this function, which simply uses the replacement string as-is.\n *\n * Similar to the JavaScript replace() method (when sSearch is a string), this replaces only ONE occurrence\n * (ie, the FIRST occurrence); it might be nice to add options to replace the LAST occurrence and/or ALL\n * occurrences, but we'll revisit that later.\n *\n * @param {string} sSearch\n * @param {string} sReplace\n * @param {string} s\n * @return {string}\n */\n static replace(sSearch, sReplace, s)\n {\n var i = s.indexOf(sSearch);\n if (i >= 0) {\n s = s.substr(0, i) + sReplace + s.substr(i + sSearch.length);\n }\n return s;\n }\n\n /**\n * replaceAll(sSearch, sReplace, s)\n *\n * @param {string} sSearch\n * @param {string} sReplace\n * @param {string} s\n * @return {string}\n */\n static replaceAll(sSearch, sReplace, s)\n {\n var a = {};\n a[sSearch] = sReplace;\n return Str.replaceArray(a, s);\n }\n\n /**\n * replaceArray(a, s)\n *\n * @param {Object} a\n * @param {string} s\n * @return {string}\n */\n static replaceArray(a, s)\n {\n var sMatch = \"\";\n for (var k in a) {\n /*\n * As noted in:\n *\n * http://www.regexguru.com/2008/04/escape-characters-only-when-necessary/\n *\n * inside character classes, only backslash, caret, hyphen and the closing bracket need to be\n * escaped. And in fact, if you ensure that the closing bracket is first, the caret is not first,\n * and the hyphen is last, you can avoid escaping those as well.\n */\n k = k.replace(/([\\\\[\\]*{}().+?|$])/g, \"\\\\$1\");\n sMatch += (sMatch? '|' : '') + k;\n }\n return s.replace(new RegExp('(' + sMatch + ')', \"g\"), function(m)\n {\n return a[m];\n });\n }\n\n /**\n * pad(s, cch, fPadLeft)\n *\n * NOTE: the maximum amount of padding currently supported is 40 spaces.\n *\n * @param {string} s is a string\n * @param {number} cch is desired length\n * @param {boolean} [fPadLeft] (default is padding on the right)\n * @return {string} the original string (s) with spaces padding it to the specified length\n */\n static pad(s, cch, fPadLeft)\n {\n var sPadding = \" \";\n return fPadLeft? (sPadding + s).slice(-cch) : (s + sPadding).slice(0, cch);\n }\n\n /**\n * sprintf(format, ...args)\n *\n * Copied from the CCjs project (https://github.com/jeffpar/ccjs/blob/master/lib/stdio.js) and extended.\n *\n * Far from complete, let alone sprintf-compatible, but it's adequate for the handful of sprintf-style format\n * specifiers that I use.\n *\n * @param {string} format\n * @param {...} args\n * @return {string}\n */\n static sprintf(format, ...args)\n {\n let buffer = \"\";\n let aParts = format.split(/%([-+ 0#]?)([0-9]*)(\\.?)([0-9]*)([hlL]?)([A-Za-z%])/);\n\n let iArg = 0, iPart;\n for (iPart = 0; iPart < aParts.length - 7; iPart += 7) {\n\n buffer += aParts[iPart];\n\n let arg = args[iArg++];\n let flags = aParts[iPart+1];\n let minimum = +aParts[iPart+2] || 0;\n let precision = +aParts[iPart+4] || 0;\n let conversion = aParts[iPart+6];\n let ach = null, s;\n\n switch(conversion) {\n case 'd':\n /*\n * We could use \"arg |= 0\", but there may be some value to supporting integers > 32 bits.\n * \n * Also, unlike the 'X' and 'x' hexadecimal cases, there's no need to explicitly check for a string\n * arguments, because the call to trunc() automatically coerces any string value to a (decimal) number.\n */\n arg = Math.trunc(arg);\n /* falls through */\n\n case 'f':\n s = Math.trunc(arg) + \"\";\n if (precision) {\n minimum -= (precision + 1);\n }\n if (s.length < minimum) {\n if (flags == '0') {\n if (arg < 0) minimum--;\n s = (\"0000000000\" + Math.abs(arg)).slice(-minimum);\n if (arg < 0) s = '-' + s;\n } else {\n s = (\" \" + s).slice(-minimum);\n }\n }\n if (precision) {\n arg = Math.round((arg - Math.trunc(arg)) * Math.pow(10, precision));\n s += '.' + (\"0000000000\" + Math.abs(arg)).slice(-precision);\n }\n buffer += s;\n break;\n\n case 'c':\n arg = String.fromCharCode(arg);\n /* falls through */\n\n case 's':\n if (typeof arg == \"string\") {\n while (arg.length < minimum) {\n if (flags == '-') {\n arg += ' ';\n } else {\n arg = ' ' + arg;\n }\n }\n }\n buffer += arg;\n break;\n\n case 'X':\n ach = Str.HexUpperCase;\n /* falls through */\n\n case 'x':\n if (!ach) ach = Str.HexLowerCase;\n s = \"\";\n if (typeof arg == \"string\") {\n /*\n * Since we're advised to ALWAYS pass a radix to parseInt(), we must detect explicitly\n * hex values ourselves, because using a radix of 10 with any \"0x...\" value always returns 0.\n * \n * And if the value CAN be interpreted as decimal, then we MUST interpret it as decimal, because\n * we have sprintf() calls in /modules/lib/testmon.js that depend on this code to perform decimal\n * to hex conversion. We're allowed to make our own rules here, since passing numbers in string\n * form isn't part of the sprintf \"spec\". \n */\n arg = Number.parseInt(arg, arg.match(/(^0x|[a-f])/i)? 16 : 10);\n } \n do {\n s = ach[arg & 0xf] + s;\n arg >>>= 4;\n } while (--minimum > 0 || arg);\n buffer += s;\n break;\n\n default:\n /*\n * The supported ANSI C set of conversions: \"dioxXucsfeEgGpn%\"\n */\n buffer += \"(unrecognized printf conversion %\" + conversion + \")\";\n break;\n }\n }\n\n buffer += aParts[iPart];\n return buffer;\n }\n\n /**\n * stripLeadingZeros(s, fPad)\n *\n * @param {string} s\n * @param {boolean} [fPad]\n * @return {string}\n */\n static stripLeadingZeros(s, fPad)\n {\n var cch = s.length;\n s = s.replace(/^0+([0-9A-F]+)$/i, \"$1\");\n if (fPad) s = Str.pad(s, cch, true);\n return s;\n }\n\n /**\n * trim(s)\n *\n * @param {string} s\n * @return {string}\n */\n static trim(s)\n {\n if (String.prototype.trim) {\n return s.trim();\n }\n return s.replace(/^\\s+|\\s+$/g, \"\");\n }\n\n /**\n * toASCIICode(b)\n *\n * @param {number} b\n * @return {string}\n */\n static toASCIICode(b)\n {\n var s;\n if (b != Str.ASCII.CR && b != Str.ASCII.LF) {\n s = Str.ASCIICodeMap[b];\n }\n if (s) {\n s = '<' + s + '>';\n } else {\n s = String.fromCharCode(b);\n }\n return s;\n }\n}\n\n/*\n * Map special characters to their HTML escape sequences.\n */\nStr.HTMLEscapeMap = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n};\n\n/*\n * Map \"unprintable\" ASCII codes to mnemonics, to more clearly see what's being printed.\n */\nStr.ASCIICodeMap = {\n 0x00: \"NUL\",\n 0x01: \"SOH\", // (CTRL_A) Start of Heading\n 0x02: \"STX\", // (CTRL_B) Start of Text\n 0x03: \"ETX\", // (CTRL_C) End of Text\n 0x04: \"EOT\", // (CTRL_D) End of Transmission\n 0x05: \"ENQ\", // (CTRL_E) Enquiry\n 0x06: \"ACK\", // (CTRL_F) Acknowledge\n 0x07: \"BEL\", // (CTRL_G) Bell\n 0x08: \"BS\", // (CTRL_H) Backspace\n 0x09: \"TAB\", // (CTRL_I) Horizontal Tab (aka HT)\n 0x0A: \"LF\", // (CTRL_J) Line Feed (New Line)\n 0x0B: \"VT\", // (CTRL_K) Vertical Tab\n 0x0C: \"FF\", // (CTRL_L) Form Feed (New Page)\n 0x0D: \"CR\", // (CTRL_M) Carriage Return\n 0x0E: \"SO\", // (CTRL_N) Shift Out\n 0x0F: \"SI\", // (CTRL_O) Shift In\n 0x10: \"DLE\", // (CTRL_P) Data Link Escape\n 0x11: \"XON\", // (CTRL_Q) Device Control 1 (aka DC1)\n 0x12: \"DC2\", // (CTRL_R) Device Control 2\n 0x13: \"XOFF\", // (CTRL_S) Device Control 3 (aka DC3)\n 0x14: \"DC4\", // (CTRL_T) Device Control 4\n 0x15: \"NAK\", // (CTRL_U) Negative Acknowledge\n 0x16: \"SYN\", // (CTRL_V) Synchronous Idle\n 0x17: \"ETB\", // (CTRL_W) End of Transmission Block\n 0x18: \"CAN\", // (CTRL_X) Cancel\n 0x19: \"EM\", // (CTRL_Y) End of Medium\n 0x1A: \"SUB\", // (CTRL_Z) Substitute\n 0x1B: \"ESC\", // Escape\n 0x1C: \"FS\", // File Separator\n 0x1D: \"GS\", // Group Separator\n 0x1E: \"RS\", // Record Separator\n 0x1F: \"US\", // Unit Separator\n 0x7F: \"DEL\"\n};\n\n/*\n * Refer to: https://en.wikipedia.org/wiki/Code_page_437\n */\nStr.CP437ToUnicode = [\n '\\u0000', '\\u263A', '\\u263B', '\\u2665', '\\u2666', '\\u2663', '\\u2660', '\\u2022',\n '\\u25D8', '\\u25CB', '\\u25D9', '\\u2642', '\\u2640', '\\u266A', '\\u266B', '\\u263C',\n '\\u25BA', '\\u25C4', '\\u2195', '\\u203C', '\\u00B6', '\\u00A7', '\\u25AC', '\\u21A8',\n '\\u2191', '\\u2193', '\\u2192', '\\u2190', '\\u221F', '\\u2194', '\\u25B2', '\\u25BC',\n '\\u0020', '\\u0021', '\\u0022', '\\u0023', '\\u0024', '\\u0025', '\\u0026', '\\u0027',\n '\\u0028', '\\u0029', '\\u002A', '\\u002B', '\\u002C', '\\u002D', '\\u002E', '\\u002F',\n '\\u0030', '\\u0031', '\\u0032', '\\u0033', '\\u0034', '\\u0035', '\\u0036', '\\u0037',\n '\\u0038', '\\u0039', '\\u003A', '\\u003B', '\\u003C', '\\u003D', '\\u003E', '\\u003F',\n '\\u0040', '\\u0041', '\\u0042', '\\u0043', '\\u0044', '\\u0045', '\\u0046', '\\u0047',\n '\\u0048', '\\u0049', '\\u004A', '\\u004B', '\\u004C', '\\u004D', '\\u004E', '\\u004F',\n '\\u0050', '\\u0051', '\\u0052', '\\u0053', '\\u0054', '\\u0055', '\\u0056', '\\u0057',\n '\\u0058', '\\u0059', '\\u005A', '\\u005B', '\\u005C', '\\u005D', '\\u005E', '\\u005F',\n '\\u0060', '\\u0061', '\\u0062', '\\u0063', '\\u0064', '\\u0065', '\\u0066', '\\u0067',\n '\\u0068', '\\u0069', '\\u006A', '\\u006B', '\\u006C', '\\u006D', '\\u006E', '\\u006F',\n '\\u0070', '\\u0071', '\\u0072', '\\u0073', '\\u0074', '\\u0075', '\\u0076', '\\u0077',\n '\\u0078', '\\u0079', '\\u007A', '\\u007B', '\\u007C', '\\u007D', '\\u007E', '\\u2302',\n '\\u00C7', '\\u00FC', '\\u00E9', '\\u00E2', '\\u00E4', '\\u00E0', '\\u00E5', '\\u00E7',\n '\\u00EA', '\\u00EB', '\\u00E8', '\\u00EF', '\\u00EE', '\\u00EC', '\\u00C4', '\\u00C5',\n '\\u00C9', '\\u00E6', '\\u00C6', '\\u00F4', '\\u00F6', '\\u00F2', '\\u00FB', '\\u00F9',\n '\\u00FF', '\\u00D6', '\\u00DC', '\\u00A2', '\\u00A3', '\\u00A5', '\\u20A7', '\\u0192',\n '\\u00E1', '\\u00ED', '\\u00F3', '\\u00FA', '\\u00F1', '\\u00D1', '\\u00AA', '\\u00BA',\n '\\u00BF', '\\u2310', '\\u00AC', '\\u00BD', '\\u00BC', '\\u00A1', '\\u00AB', '\\u00BB',\n '\\u2591', '\\u2592', '\\u2593', '\\u2502', '\\u2524', '\\u2561', '\\u2562', '\\u2556',\n '\\u2555', '\\u2563', '\\u2551', '\\u2557', '\\u255D', '\\u255C', '\\u255B', '\\u2510',\n '\\u2514', '\\u2534', '\\u252C', '\\u251C', '\\u2500', '\\u253C', '\\u255E', '\\u255F',\n '\\u255A', '\\u2554', '\\u2569', '\\u2566', '\\u2560', '\\u2550', '\\u256C', '\\u2567',\n '\\u2568', '\\u2564', '\\u2565', '\\u2559', '\\u2558', '\\u2552', '\\u2553', '\\u256B',\n '\\u256A', '\\u2518', '\\u250C', '\\u2588', '\\u2584', '\\u258C', '\\u2590', '\\u2580',\n '\\u03B1', '\\u00DF', '\\u0393', '\\u03C0', '\\u03A3', '\\u03C3', '\\u00B5', '\\u03C4',\n '\\u03A6', '\\u0398', '\\u03A9', '\\u03B4', '\\u221E', '\\u03C6', '\\u03B5', '\\u2229',\n '\\u2261', '\\u00B1', '\\u2265', '\\u2264', '\\u2320', '\\u2321', '\\u00F7', '\\u2248',\n '\\u00B0', '\\u2219', '\\u00B7', '\\u221A', '\\u207F', '\\u00B2', '\\u25A0', '\\u00A0'\n];\n\n/*\n * TODO: Future home of a complete ASCII table.\n */\nStr.ASCII = {\n LF: 0x0A,\n CR: 0x0D\n};\n\nStr.TYPES = {\n NULL: 0,\n BYTE: 1,\n WORD: 2,\n DWORD: 3,\n NUMBER: 4,\n STRING: 5,\n BOOLEAN: 6,\n OBJECT: 7,\n ARRAY: 8\n};\n\nStr.HexLowerCase = \"0123456789abcdef\";\nStr.HexUpperCase = \"0123456789ABCDEF\";\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/usrlib.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @typedef {{\n * mask: number,\n * shift: number\n * }}\n */\nvar BitField;\n\n/**\n * @typedef {Object.<BitField>}\n */\nvar BitFields;\n\nclass Usr {\n /**\n * binarySearch(a, v, fnCompare)\n *\n * @param {Array} a is an array\n * @param {number|string|Array|Object} v\n * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]\n * @return {number} the index of matching entry if non-negative, otherwise the index of the insertion point\n */\n static binarySearch(a, v, fnCompare)\n {\n var left = 0;\n var right = a.length;\n var found = 0;\n if (fnCompare === undefined) {\n fnCompare = function(a, b)\n {\n return a > b ? 1 : a < b ? -1 : 0;\n };\n }\n while (left < right) {\n var middle = (left + right) >> 1;\n var compareResult;\n compareResult = fnCompare(v, a[middle]);\n if (compareResult > 0) {\n left = middle + 1;\n } else {\n right = middle;\n found = !compareResult;\n }\n }\n return found ? left : ~left;\n }\n\n /**\n * binaryInsert(a, v, fnCompare)\n *\n * If element v already exists in array a, the array is unchanged (we don't allow duplicates); otherwise, the\n * element is inserted into the array at the appropriate index.\n *\n * @param {Array} a is an array\n * @param {number|string|Array|Object} v is the value to insert\n * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]\n */\n static binaryInsert(a, v, fnCompare)\n {\n var index = Usr.binarySearch(a, v, fnCompare);\n if (index < 0) {\n a.splice(-(index + 1), 0, v);\n }\n }\n\n /**\n * getTimestamp()\n *\n * @return {string} timestamp containing the current date and time (\"yyyy-mm-dd hh:mm:ss\")\n */\n static getTimestamp()\n {\n return Usr.formatDate(\"Y-m-d H:i:s\");\n }\n\n /**\n * getMonthDays(nMonth, nYear)\n *\n * Note that if we're being called on behalf of the RTC, its year is always truncated to two digits (mod 100),\n * so we have no idea what century the year 0 might refer to. When using the normal leap-year formula, 0 fails\n * the mod 100 test but passes the mod 400 test, so as far as the RTC is concerned, every century year is a leap\n * year. Since we're most likely dealing with the year 2000, that's fine, since 2000 was also a leap year.\n *\n * TODO: There IS a separate CMOS byte that's supposed to be set to CMOS_ADDR.CENTURY_DATE; it's always BCD,\n * so theoretically it will contain values like 0x19 or 0x20 (for the 20th and 21st centuries, respectively), and\n * we could add that as another parameter to this function, to improve the accuracy, but that would go beyond what\n * a real RTC actually does.\n *\n * @param {number} nMonth (1-12)\n * @param {number} nYear (normally a 4-digit year, but it may also be mod 100)\n * @return {number} the maximum (1-based) day allowed for the specified month and year\n */\n static getMonthDays(nMonth, nYear)\n {\n var nDays = Usr.aMonthDays[nMonth - 1];\n if (nDays == 28) {\n if ((nYear % 4) === 0 && ((nYear % 100) || (nYear % 400) === 0)) {\n nDays++;\n }\n }\n return nDays;\n }\n\n /**\n * formatDate(sFormat, date)\n *\n * @param {string} sFormat (eg, \"F j, Y\", \"Y-m-d H:i:s\")\n * @param {Date} [date] (default is the current time)\n * @return {string}\n *\n * Supported identifiers in sFormat include:\n *\n * a: lowercase ante meridiem and post meridiem (am or pm)\n * d: day of the month, 2 digits with leading zeros (01,02,...,31)\n * D: 3-letter day of the week (\"Sun\",\"Mon\",...,\"Sat\")\n * F: month (\"January\",\"February\",...,\"December\")\n * g: hour in 12-hour format, without leading zeros (1,2,...,12)\n * h: hour in 24-hour format, without leading zeros (0,1,...,23)\n * H: hour in 24-hour format, with leading zeros (00,01,...,23)\n * i: minutes, with leading zeros (00,01,...,59)\n * j: day of the month, without leading zeros (1,2,...,31)\n * l: day of the week (\"Sunday\",\"Monday\",...,\"Saturday\")\n * m: month, with leading zeros (01,02,...,12)\n * M: 3-letter month (\"Jan\",\"Feb\",...,\"Dec\")\n * n: month, without leading zeros (1,2,...,12)\n * s: seconds, with leading zeros (00,01,...,59)\n * y: 2-digit year (eg, 14)\n * Y: 4-digit year (eg, 2014)\n *\n * For more inspiration, see: http://php.net/manual/en/function.date.php (of which we support ONLY a subset).\n */\n static formatDate(sFormat, date)\n {\n var sDate = \"\";\n if (!date) date = new Date();\n var iHour = date.getHours();\n var iDay = date.getDate();\n var iMonth = date.getMonth() + 1;\n for (var i = 0; i < sFormat.length; i++) {\n var ch;\n switch ((ch = sFormat.charAt(i))) {\n case 'a':\n sDate += (iHour < 12 ? \"am\" : \"pm\");\n break;\n case 'd':\n sDate += ('0' + iDay).slice(-2);\n break;\n case 'D':\n sDate += Usr.asDays[date.getDay()].substr(0, 3);\n break;\n case 'F':\n sDate += Usr.asMonths[iMonth - 1];\n break;\n case 'g':\n sDate += (!iHour ? 12 : (iHour > 12 ? iHour - 12 : iHour));\n break;\n case 'h':\n sDate += iHour;\n break;\n case 'H':\n sDate += ('0' + iHour).slice(-2);\n break;\n case 'i':\n sDate += ('0' + date.getMinutes()).slice(-2);\n break;\n case 'j':\n sDate += iDay;\n break;\n case 'l':\n sDate += Usr.asDays[date.getDay()];\n break;\n case 'm':\n sDate += ('0' + iMonth).slice(-2);\n break;\n case 'M':\n sDate += Usr.asMonths[iMonth - 1].substr(0, 3);\n break;\n case 'n':\n sDate += iMonth;\n break;\n case 's':\n sDate += ('0' + date.getSeconds()).slice(-2);\n break;\n case 'y':\n sDate += (\"\" + date.getFullYear()).slice(-2);\n break;\n case 'Y':\n sDate += date.getFullYear();\n break;\n default:\n sDate += ch;\n break;\n }\n }\n return sDate;\n }\n\n /**\n * defineBitFields(bfs)\n *\n * Prepares a bit field definition for use with getBitField() and setBitField(); eg:\n *\n * var bfs = Usr.defineBitFields({num:20, count:8, btmod:1, type:3});\n *\n * The above defines a set of bit fields containing four fields: num (bits 0-19), count (bits 20-27), btmod (bit 28), and type (bits 29-31).\n *\n * Usr.setBitField(bfs.num, n, 1);\n *\n * The above set bit field \"bfs.num\" in numeric variable \"n\" to the value 1.\n *\n * @param {Object} bfs\n * @return {BitFields}\n */\n static defineBitFields(bfs)\n {\n var bit = 0;\n for (var f in bfs) {\n var width = bfs[f];\n var mask = ((1 << width) - 1) << bit;\n bfs[f] = {mask: mask, shift: bit};\n bit += width;\n }\n return bfs;\n }\n\n /**\n * initBitFields(bfs, ...)\n *\n * @param {BitFields} bfs\n * @param {...number} var_args\n * @return {number} a value containing all supplied bit fields\n */\n static initBitFields(bfs, var_args)\n {\n var v = 0, i = 1;\n for (var f in bfs) {\n if (i >= arguments.length) break;\n v = Usr.setBitField(bfs[f], v, arguments[i++]);\n }\n return v;\n }\n\n /**\n * getBitField(bf, v)\n *\n * @param {BitField} bf\n * @param {number} v is a value containing bit fields\n * @return {number} the value of the bit field in v defined by bf\n */\n static getBitField(bf, v)\n {\n return (v & bf.mask) >> bf.shift;\n }\n\n /**\n * setBitField(bf, v, n)\n *\n * @param {BitField} bf\n * @param {number} v is a value containing bit fields\n * @param {number} n is a value to store in v in the bit field defined by bf\n * @return {number} updated v\n */\n static setBitField(bf, v, n)\n {\n return (v & ~bf.mask) | ((n << bf.shift) & bf.mask);\n }\n\n /**\n * indexOf(a, t, i)\n *\n * Use this instead of Array.prototype.indexOf() if you can't be sure the browser supports it.\n *\n * @param {Array} a\n * @param {*} t\n * @param {number} [i]\n * @returns {number}\n */\n static indexOf(a, t, i)\n {\n if (Array.prototype.indexOf) {\n return a.indexOf(t, i);\n }\n i = i || 0;\n if (i < 0) i += a.length;\n if (i < 0) i = 0;\n for (var n = a.length; i < n; i++) {\n if (i in a && a[i] === t) return i;\n }\n return -1;\n }\n}\n\nUsr.asDays = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\nUsr.asMonths = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\nUsr.aMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\n/**\n * getTime()\n *\n * @return {number} the current time, in milliseconds\n */\nUsr.getTime = Date.now || function() { return +new Date(); };\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/weblib.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * According to http://www.w3schools.com/jsref/jsref_obj_global.asp, these are the *global* properties\n * and functions of JavaScript-in-the-Browser:\n *\n * Property Description\n * ---\n * Infinity A numeric value that represents positive/negative infinity\n * NaN \"Not-a-Number\" value\n * undefined Indicates that a variable has not been assigned a value\n *\n * Function Description\n * ---\n * decodeURI() Decodes a URI\n * decodeURIComponent() Decodes a URI component\n * encodeURI() Encodes a URI\n * encodeURIComponent() Encodes a URI component\n * escape() Deprecated in version 1.5. Use encodeURI() or encodeURIComponent() instead\n * eval() Evaluates a string and executes it as if it was script code\n * isFinite() Determines whether a value is a finite, legal number\n * isNaN() Determines whether a value is an illegal number\n * Number() Converts an object's value to a number\n * parseFloat() Parses a string and returns a floating point number\n * parseInt() Parses a string and returns an integer\n * String() Converts an object's value to a string\n * unescape() Deprecated in version 1.5. Use decodeURI() or decodeURIComponent() instead\n *\n * And according to http://www.w3schools.com/jsref/obj_window.asp, these are the properties and functions\n * of the *window* object.\n *\n * Property Description\n * ---\n * closed Returns a Boolean value indicating whether a window has been closed or not\n * defaultStatus Sets or returns the default text in the statusbar of a window\n * document Returns the Document object for the window (See Document object)\n * frames Returns an array of all the frames (including iframes) in the current window\n * history Returns the History object for the window (See History object)\n * innerHeight Returns the inner height of a window's content area\n * innerWidth Returns the inner width of a window's content area\n * length Returns the number of frames (including iframes) in a window\n * location Returns the Location object for the window (See Location object)\n * name Sets or returns the name of a window\n * navigator Returns the Navigator object for the window (See Navigator object)\n * opener Returns a reference to the window that created the window\n * outerHeight Returns the outer height of a window, including toolbars/scrollbars\n * outerWidth Returns the outer width of a window, including toolbars/scrollbars\n * pageXOffset Returns the pixels the current document has been scrolled (horizontally) from the upper left corner of the window\n * pageYOffset Returns the pixels the current document has been scrolled (vertically) from the upper left corner of the window\n * parent Returns the parent window of the current window\n * screen Returns the Screen object for the window (See Screen object)\n * screenLeft Returns the x coordinate of the window relative to the screen\n * screenTop Returns the y coordinate of the window relative to the screen\n * screenX Returns the x coordinate of the window relative to the screen\n * screenY Returns the y coordinate of the window relative to the screen\n * self Returns the current window\n * status Sets or returns the text in the statusbar of a window\n * top Returns the topmost browser window\n *\n * Method Description\n * ---\n * alert() Displays an alert box with a message and an OK button\n * atob() Decodes a base-64 encoded string\n * blur() Removes focus from the current window\n * btoa() Encodes a string in base-64\n * clearInterval() Clears a timer set with setInterval()\n * clearTimeout() Clears a timer set with setTimeout()\n * close() Closes the current window\n * confirm() Displays a dialog box with a message and an OK and a Cancel button\n * createPopup() Creates a pop-up window\n * focus() Sets focus to the current window\n * moveBy() Moves a window relative to its current position\n * moveTo() Moves a window to the specified position\n * open() Opens a new browser window\n * print() Prints the content of the current window\n * prompt() Displays a dialog box that prompts the visitor for input\n * resizeBy() Resizes the window by the specified pixels\n * resizeTo() Resizes the window to the specified width and height\n * scroll() This method has been replaced by the scrollTo() method.\n * scrollBy() Scrolls the content by the specified number of pixels\n * scrollTo() Scrolls the content to the specified coordinates\n * setInterval() Calls a function or evaluates an expression at specified intervals (in milliseconds)\n * setTimeout() Calls a function or evaluates an expression after a specified number of milliseconds\n * stop() Stops the window from loading\n */\n\nclass Web {\n /**\n * log(s, type)\n *\n * For diagnostic output only. DEBUG must be true (or \"--debug\" specified via the command-line)\n * for Component.log() to display anything.\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n static log(s, type)\n {\n Component.log(s, type);\n }\n\n /**\n * notice(s, fPrintOnly, id)\n *\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n */\n static notice(s, fPrintOnly, id)\n {\n Component.notice(s, fPrintOnly, id);\n }\n\n /**\n * alertUser(sMessage)\n * \n * NOTE: Legacy function for older modules (eg, DiskDump); see Component.alertUser().\n *\n * @param {string} sMessage\n */\n static alertUser(sMessage)\n {\n if (window) {\n window.alert(sMessage);\n } else {\n Web.log(sMessage);\n }\n }\n\n /**\n * getResource(sURL, type, fAsync, done, progress)\n *\n * Request the specified resource (sURL), and once the request is complete, notify done().\n *\n * If fAsync is true, a done() callback should ALWAYS be supplied; otherwise, you'll have no\n * idea when the request is complete or what the response was. done() is passed three parameters:\n *\n * done(sURL, resource, nErrorCode)\n *\n * If nErrorCode is zero, resource should contain the requested data; otherwise, an error occurred.\n *\n * If type is set to a string, that string can be used to control the response format;\n * by default, the response format is plain text, but you can specify \"arraybuffer\" to request arbitrary\n * binary data, in which case the returned resource will be a ArrayBuffer rather than a string.\n *\n * @param {string} sURL\n * @param {string|Object|null} [type] (object for POST request, otherwise type of GET request)\n * @param {boolean} [fAsync] is true for an asynchronous request; false otherwise (MUST be set for IE)\n * @param {function(string,string,number)} [done]\n * @param {function(number)} [progress]\n * @return {Array|null} Array containing [resource, nErrorCode], or null if no response available (yet)\n */\n static getResource(sURL, type = \"text\", fAsync = false, done, progress)\n {\n var nErrorCode = 0, resource = null, response = null;\n\n if (typeof resources == 'object' && (resource = resources[sURL])) {\n if (done) done(sURL, resource, nErrorCode);\n return [resource, nErrorCode];\n }\n else if (fAsync && typeof resources == 'function') {\n resources(sURL, function(resource, nErrorCode)\n {\n if (done) done(sURL, resource, nErrorCode);\n });\n return response;\n }\n\n if (!DEBUG && !NODE) {\n /*\n * TODO: Perhaps it's time for our code in netlib.js to finally add support for HTTPS; for now\n * though, it's just as well that the NODE environment assumes all resources are available locally.\n */\n sURL = sURL.replace(/^\\/(pcjs-disks|private-disks)\\//, \"https://jeffpar.github.io/$1/\");\n }\n else {\n /*\n * The larger resources we put on archive.pcjs.org should also be available locally.\n *\n * NOTE: \"http://archive.pcjs.org\" is now \"https://s3-us-west-2.amazonaws.com/archive.pcjs.org\"\n */\n sURL = sURL.replace(/^(http:\\/\\/archive\\.pcjs\\.org|https:\\/\\/s3-us-west-2\\.amazonaws\\.com\\/archive\\.pcjs\\.org)(\\/.*)\\/([^\\/]*)$/, \"$2/archive/$3\");\n sURL = sURL.replace(/^https:\\/\\/jeffpar\\.github\\.io\\/(pcjs-disks|private-disks)\\/(.*)$/, \"/$1/$2\");\n }\n\n\n var request = (window.XMLHttpRequest? new window.XMLHttpRequest() : new window.ActiveXObject(\"Microsoft.XMLHTTP\"));\n var fArrayBuffer = false, fXHR2 = (typeof request.responseType === 'string');\n \n var callback = function() {\n if (request.readyState !== 4) {\n if (progress) progress(1);\n return null;\n }\n /*\n * The following line was recommended for WebKit, as a work-around to prevent the handler firing multiple\n * times when debugging. Unfortunately, that's not the only XMLHttpRequest problem that occurs when\n * debugging, so I think the WebKit problem is deeper than that. When we have multiple XMLHttpRequests\n * pending, any debugging activity means most of them simply get dropped on floor, so what may actually be\n * happening are mis-notifications rather than redundant notifications.\n *\n * request.onreadystatechange = undefined;\n */\n /*\n * If the request failed due to, say, a CORS policy denial; eg:\n * \n * Failed to load http://www.allbootdisks.com/downloads/Disks/Windows_95_Boot_Disk_Download48/Diskette%20Images/Windows95a.img:\n * Redirect from 'http://www.allbootdisks.com/downloads/Disks/Windows_95_Boot_Disk_Download48/Diskette%20Images/Windows95a.img' to\n * 'http://www.allbootdisks.com/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.\n * Origin 'http://pcjs:8088' is therefore not allowed access.\n * \n * and our request type was \"arraybuffer\", attempting to access responseText may trigger an exception; eg:\n * \n * Uncaught DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's\n * 'responseType' is '' or 'text' (was 'arraybuffer').\n * \n * We could tiptoe around these potential landmines, but the safest thing to do is wrap this code with try/catch.\n */\n try {\n resource = fArrayBuffer? request.response : request.responseText;\n } catch(err) {\n if (MAXDEBUG) Web.log(\"xmlHTTPRequest(\" + sURL + \") exception: \" + err.message);\n }\n /*\n * The normal \"success\" case is a non-null resource and an HTTP status code of 200, but when loading files from the\n * local file system (ie, when using the \"file:\" protocol), we have to be a bit more flexible.\n */\n if (resource != null && (request.status == 200 || !request.status && resource.length && Web.getHostProtocol() == \"file:\")) {\n if (MAXDEBUG) Web.log(\"xmlHTTPRequest(\" + sURL + \"): returned \" + resource.length + \" bytes\");\n }\n else {\n nErrorCode = request.status || -1;\n Web.log(\"xmlHTTPRequest(\" + sURL + \"): error code \" + nErrorCode);\n }\n if (progress) progress(2);\n if (done) done(sURL, resource, nErrorCode);\n return [resource, nErrorCode];\n };\n \n if (fAsync) {\n request.onreadystatechange = callback;\n }\n\n if (progress) progress(0);\n\n if (type && typeof type == \"object\") {\n var sPost = \"\";\n for (var p in type) {\n if (!type.hasOwnProperty(p)) continue;\n if (sPost) sPost += \"&\";\n sPost += p + '=' + encodeURIComponent(type[p]);\n }\n sPost = sPost.replace(/%20/g, '+');\n if (MAXDEBUG) Web.log(\"Web.getResource(POST \" + sURL + \"): \" + sPost.length + \" bytes\");\n request.open(\"POST\", sURL, fAsync);\n request.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\n request.send(sPost);\n } else {\n if (MAXDEBUG) Web.log(\"Web.getResource(GET \" + sURL + \")\");\n request.open(\"GET\", sURL, fAsync);\n if (type == \"arraybuffer\") {\n if (fXHR2) {\n fArrayBuffer = true;\n request.responseType = type;\n } else {\n request.overrideMimeType(\"text/plain; charset=x-user-defined\");\n }\n }\n request.send();\n }\n\n if (!fAsync) {\n request.readyState = 4; // this may already be set for synchronous requests, but I don't want to take any chances \n response = callback();\n }\n return response;\n }\n\n /**\n * parseMemoryResource(sURL, sData)\n *\n * This converts a variety of JSON-style data streams into an Object with the following properties:\n *\n * aBytes\n * aSymbols\n * addrLoad\n * addrExec\n *\n * If the source data contains a 'bytes' array, it's passed through to 'aBytes'; alternatively, if\n * it contains a 'words' array, the values are converted from 16-bit to 8-bit and stored in 'aBytes',\n * and if it contains a 'longs' array, the values are converted from 32-bit longs into bytes and\n * stored in 'aBytes'.\n *\n * Alternatively, if the source data contains a 'data' array, we simply pass that through to the output\n * object as:\n *\n * aData\n *\n * @param {string} sURL\n * @param {string} sData\n * @return {Object|null} (resource)\n */\n static parseMemoryResource(sURL, sData)\n {\n var i;\n var resource = {\n aBytes: null,\n aSymbols: null,\n addrLoad: null,\n addrExec: null\n };\n\n if (sData.charAt(0) == \"[\" || sData.charAt(0) == \"{\") {\n try {\n var a, ib, data;\n\n if (sData.substr(0, 1) == \"<\") { // if the \"data\" begins with a \"<\"...\n /*\n * Early server configs reported an error (via the nErrorCode parameter) if a tape URL was invalid,\n * but more recent server configs now display a somewhat friendlier HTML error page. The downside,\n * however, is that the original error has been buried, and we've received \"data\" that isn't actually\n * tape data. So if the data we've received appears to be \"HTML-like\", we treat it as an error message.\n */\n throw new Error(sData);\n }\n\n /*\n * TODO: IE9 is rather unfriendly and restrictive with regard to how much data it's willing to\n * eval(). In particular, the 10Mb disk image we use for the Windows 1.01 demo config fails in\n * IE9 with an \"Out of memory\" exception. One work-around would be to chop the data into chunks\n * (perhaps one track per chunk, using regular expressions) and then manually re-assemble it.\n *\n * However, it turns out that using JSON.parse(sDiskData) instead of eval(\"(\" + sDiskData + \")\")\n * is a much easier fix. The only drawback is that we must first quote any unquoted property names\n * and remove any comments, because while eval() was cool with them, JSON.parse() is more particular;\n * the following RegExp replacements take care of those requirements.\n *\n * The use of hex values is something else that eval() was OK with, but JSON.parse() is not, and\n * while I've stopped using hex values in DumpAPI responses (at least when \"format=json\" is specified),\n * I can't guarantee they won't show up in \"legacy\" images, and there's no simple RegExp replacement\n * for transforming hex values into decimal values, so I cop out and fall back to eval() if I detect\n * any hex prefixes (\"0x\") in the sequence. Ditto for error messages, which appear like so:\n *\n * [\"unrecognized disk path: test.img\"]\n */\n if (sData.indexOf(\"0x\") < 0 && sData.indexOf(\"0o\") < 0 && sData.substr(0, 2) != '[\"') {\n data = JSON.parse(sData.replace(/([a-z]+):/gm, '\"$1\":').replace(/\\/\\/[^\\n]*/gm, \"\"));\n } else {\n data = eval(\"(\" + sData + \")\");\n }\n\n resource.addrLoad = data['load'];\n resource.addrExec = data['exec'];\n\n if (a = data['bytes']) {\n resource.aBytes = a;\n }\n else if (a = data['words']) {\n /*\n * Convert all words into bytes\n */\n resource.aBytes = new Array(a.length * 2);\n for (i = 0, ib = 0; i < a.length; i++) {\n resource.aBytes[ib++] = a[i] & 0xff;\n resource.aBytes[ib++] = (a[i] >> 8) & 0xff;\n\n }\n }\n else if (a = data['longs']) {\n /*\n * Convert all dwords (longs) into bytes\n */\n resource.aBytes = new Array(a.length * 4);\n for (i = 0, ib = 0; i < a.length; i++) {\n resource.aBytes[ib++] = a[i] & 0xff;\n resource.aBytes[ib++] = (a[i] >> 8) & 0xff;\n resource.aBytes[ib++] = (a[i] >> 16) & 0xff;\n resource.aBytes[ib++] = (a[i] >> 24) & 0xff;\n }\n }\n else if (a = data['data']) {\n resource.aData = a;\n }\n else {\n resource.aBytes = data;\n }\n\n if (resource.aBytes) {\n if (!resource.aBytes.length) {\n Component.error(\"Empty resource: \" + sURL);\n resource = null;\n }\n else if (resource.aBytes.length == 1) {\n Component.error(resource.aBytes[0]);\n resource = null;\n }\n }\n resource.aSymbols = data['symbols'];\n\n } catch (e) {\n Component.error(\"Resource data error (\" + sURL + \"): \" + e.message);\n resource = null;\n }\n }\n else {\n /*\n * Parse the data manually; we assume it's a series of hex byte-values separated by whitespace.\n */\n var ab = [];\n var sHexData = sData.replace(/\\n/gm, \" \").replace(/ +$/, \"\");\n var asHexData = sHexData.split(\" \");\n for (i = 0; i < asHexData.length; i++) {\n var n = parseInt(asHexData[i], 16);\n if (isNaN(n)) {\n Component.error(\"Resource data error (\" + sURL + \"): invalid hex byte (\" + asHexData[i] + \")\");\n break;\n }\n ab.push(n & 0xff);\n }\n if (i == asHexData.length) resource.aBytes = ab;\n }\n return resource;\n }\n\n /**\n * sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)\n *\n * Send a report (eg, bug report) to the server.\n *\n * @param {string} sApp (eg, \"PCjs\")\n * @param {string} sVer (eg, \"1.02\")\n * @param {string} sURL (eg, \"/devices/pc/machine/5150/mda/64kb/machine.xml\")\n * @param {string} sUser (ie, the user key, if any)\n * @param {string} sType (eg, \"bug\"); one of ReportAPI.TYPE.*\n * @param {string} sReport (eg, unparsed state data)\n * @param {string} [sHostName] (default is http://SITEHOST)\n */\n static sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)\n {\n var dataPost = {};\n dataPost[ReportAPI.QUERY.APP] = sApp;\n dataPost[ReportAPI.QUERY.VER] = sVer;\n dataPost[ReportAPI.QUERY.URL] = sURL;\n dataPost[ReportAPI.QUERY.USER] = sUser;\n dataPost[ReportAPI.QUERY.TYPE] = sType;\n dataPost[ReportAPI.QUERY.DATA] = sReport;\n var sReportURL = (sHostName? sHostName : \"http://\" + SITEHOST) + ReportAPI.ENDPOINT;\n Web.getResource(sReportURL, dataPost, true);\n }\n\n /**\n * getHost()\n *\n * @return {string}\n */\n static getHost()\n {\n return (\"http://\" + (window? window.location.host : SITEHOST));\n }\n\n /**\n * getHostURL()\n *\n * @return {string|null}\n */\n static getHostURL()\n {\n return (window? window.location.href : null);\n }\n\n /**\n * getHostProtocol()\n *\n * @return {string}\n */\n static getHostProtocol()\n {\n return (window? window.location.protocol : \"file:\");\n }\n\n /**\n * getUserAgent()\n *\n * @return {string}\n */\n static getUserAgent()\n {\n return (window? window.navigator.userAgent : \"\");\n }\n\n /**\n * hasLocalStorage\n *\n * true if localStorage support exists, is enabled, and works; false otherwise\n *\n * @return {boolean}\n */\n static hasLocalStorage()\n {\n if (Web.fLocalStorage == null) {\n var f = false;\n if (window) {\n try {\n window.localStorage.setItem(Web.sLocalStorageTest, Web.sLocalStorageTest);\n f = (window.localStorage.getItem(Web.sLocalStorageTest) == Web.sLocalStorageTest);\n window.localStorage.removeItem(Web.sLocalStorageTest);\n } catch (e) {\n Web.logLocalStorageError(e);\n f = false;\n }\n }\n Web.fLocalStorage = f;\n }\n return Web.fLocalStorage;\n }\n\n /**\n * logLocalStorageError(e)\n *\n * @param {Error} e is an exception\n */\n static logLocalStorageError(e)\n {\n Web.log(e.message, \"localStorage error\");\n }\n\n /**\n * getLocalStorageItem(sKey)\n *\n * Returns the requested key value, or null if the key does not exist, or undefined if localStorage is not available\n *\n * @param {string} sKey\n * @return {string|null|undefined} sValue\n */\n static getLocalStorageItem(sKey)\n {\n var sValue;\n if (window) {\n try {\n sValue = window.localStorage.getItem(sKey);\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n }\n return sValue;\n }\n\n /**\n * setLocalStorageItem(sKey, sValue)\n *\n * @param {string} sKey\n * @param {string} sValue\n * @return {boolean} true if localStorage is available, false if not\n */\n static setLocalStorageItem(sKey, sValue)\n {\n try {\n window.localStorage.setItem(sKey, sValue);\n return true;\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n return false;\n }\n\n /**\n * removeLocalStorageItem(sKey)\n *\n * @param {string} sKey\n */\n static removeLocalStorageItem(sKey)\n {\n try {\n window.localStorage.removeItem(sKey);\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n }\n\n /**\n * getLocalStorageKeys()\n *\n * @return {Array}\n */\n static getLocalStorageKeys()\n {\n var a = [];\n try {\n for (var i = 0, c = window.localStorage.length; i < c; i++) {\n a.push(window.localStorage.key(i));\n }\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n return a;\n }\n\n /**\n * reloadPage()\n */\n static reloadPage()\n {\n if (window) window.location.reload();\n }\n\n /**\n * isUserAgent(s)\n *\n * Check the browser's user-agent string for the given substring; \"iOS\" and \"MSIE\" are special values you can\n * use that will match any iOS or MSIE browser, respectively (even IE11, in the case of \"MSIE\").\n *\n * 2013-11-06: In a questionable move, MSFT changed the user-agent reported by IE11 on Windows 8.1, eliminating\n * the \"MSIE\" string (which MSDN calls a \"version token\"; see http://msdn.microsoft.com/library/ms537503.aspx);\n * they say \"public websites should rely on feature detection, rather than browser detection, in order to design\n * their sites for browsers that don't support the features used by the website.\" So, in IE11, we get a user-agent\n * that tries to fool apps into thinking the browser is more like WebKit or Gecko:\n *\n * Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko\n *\n * That's a nice idea, but in the meantime, they hosed the XSL transform code in embed.js, which contained\n * some very critical browser-specific code; turning on IE's \"Compatibility Mode\" didn't help either, because\n * that's a sledgehammer solution which restores the old user-agent string but also disables other features like\n * HTML5 canvas support. As an interim solution, I'm treating any \"MSIE\" check as a check for either \"MSIE\" or\n * \"Trident\".\n *\n * UPDATE: I've since found ways to make the code in embed.js more browser-agnostic, so for now, there's isn't\n * any code that cares about \"MSIE\", but I've left the change in place, because I wouldn't be surprised if I'll\n * need more IE-specific code in the future, perhaps for things like copy/paste functionality, or mouse capture.\n *\n * @param {string} s is a substring to search for in the user-agent; as noted above, \"iOS\" and \"MSIE\" are special values\n * @return {boolean} is true if the string was found, false if not\n */\n static isUserAgent(s)\n {\n if (window) {\n var userAgent = Web.getUserAgent();\n /*\n * Here's one case where we have to be careful with Component, because when isUserAgent() is called by\n * the init code below, component.js hasn't been loaded yet. The simple solution for now is to remove the call.\n *\n * Web.log(\"agent: \" + userAgent);\n *\n * And yes, it would be pointless to use the conditional (?) operator below, if not for the Google Closure\n * Compiler (v20130823) failing to detect the entire expression as a boolean.\n */\n return s == \"iOS\" && !!userAgent.match(/(iPod|iPhone|iPad)/) && !!userAgent.match(/AppleWebKit/) || s == \"MSIE\" && !!userAgent.match(/(MSIE|Trident)/) || (userAgent.indexOf(s) >= 0);\n }\n return false;\n }\n\n /**\n * isMobile(sDevice)\n *\n * Checks the URL for a \"mobile\" parameter, and failing that, checks the browser's user-agent string for the\n * substring \"Mobi\", as per Mozilla recommendation:\n *\n * https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent\n *\n * @param {string} [sDevice] (eg, \"iPad\" to check for iPad, or \"!iPad\" to specifically exclude it) \n * @return {boolean} is true if the browser appears to be a mobile (ie, non-desktop) web browser, false if not\n */\n static isMobile(sDevice)\n {\n var sMobile = Web.getURLParm(\"mobile\");\n if (sMobile) return sMobile == \"true\";\n if (Web.isUserAgent(\"Mobi\")) {\n if (!sDevice) return true;\n var fInvert = sDevice[0] == '!';\n if (fInvert) sDevice = sDevice.substr(1);\n return Web.isUserAgent(sDevice) != fInvert;\n }\n return false;\n }\n\n /**\n * findProperty(obj, sProp, sSuffix)\n *\n * If both sProp and sSuffix are set, then any browser-specific prefixes are inserted between sProp and sSuffix,\n * and if a match is found, it is returned without sProp.\n *\n * For example, if findProperty(document, 'on', 'fullscreenchange') discovers that 'onwebkitfullscreenchange' exists,\n * it will return 'webkitfullscreenchange', in preparation for an addEventListener() call.\n *\n * More commonly, sSuffix is not used, so whatever property is found is returned as-is.\n *\n * @param {Object|null|undefined} obj\n * @param {string} sProp\n * @param {string} [sSuffix]\n * @return {string|null}\n */\n static findProperty(obj, sProp, sSuffix)\n {\n if (obj) {\n for (var i = 0; i < Web.asBrowserPrefixes.length; i++) {\n var sName = Web.asBrowserPrefixes[i];\n if (sSuffix) {\n sName += sSuffix;\n var sEvent = sProp + sName;\n if (sEvent in obj) return sName;\n } else {\n if (!sName) {\n sName = sProp[0];\n } else {\n sName += sProp[0].toUpperCase();\n }\n sName += sProp.substr(1);\n if (sName in obj) return sName;\n }\n }\n }\n return null;\n }\n\n /**\n * getURLParm(sParm)\n *\n * First looks for sParm exactly as specified, then looks for the lower-case version.\n *\n * @param {string} sParm\n * @return {string|undefined}\n */\n static getURLParm(sParm)\n {\n if (!Web.parmsURL) {\n Web.parmsURL = Web.parseURLParms();\n }\n return Web.parmsURL[sParm] || Web.parmsURL[sParm.toLowerCase()];\n }\n\n /**\n * parseURLParms(sParms)\n *\n * @param {string} [sParms] containing the parameter portion of a URL (ie, after the '?')\n * @return {Object} containing properties for each parameter found\n */\n static parseURLParms(sParms)\n {\n var aParms = {};\n if (window) { // an alternative to \"if (typeof module === 'undefined')\" if require(\"defines\") was used\n if (!sParms) {\n /*\n * Note that window.location.href returns the entire URL, whereas window.location.search\n * returns only the parameters, if any (starting with the '?', which we skip over with a substr() call).\n */\n sParms = window.location.search.substr(1);\n }\n var match;\n var pl = /\\+/g; // RegExp for replacing addition symbol with a space\n var search = /([^&=]+)=?([^&]*)/g;\n var decode = function(s)\n {\n return decodeURIComponent(s.replace(pl, \" \"));\n };\n\n while ((match = search.exec(sParms))) {\n aParms[decode(match[1])] = decode(match[2]);\n }\n }\n return aParms;\n }\n\n /**\n * downloadFile(sData, sType, fBase64, sFileName)\n *\n * @param {string} sData\n * @param {string} sType\n * @param {boolean} [fBase64]\n * @param {string} [sFileName]\n */\n static downloadFile(sData, sType, fBase64, sFileName)\n {\n var link = null, sAlert;\n var sURI = \"data:application/\" + sType + (fBase64? \";base64\" : \"\") + \",\";\n\n if (!Web.isUserAgent(\"Firefox\")) {\n sURI += (fBase64? sData : encodeURI(sData));\n } else {\n sURI += (fBase64? sData : encodeURIComponent(sData));\n }\n if (sFileName) {\n link = document.createElement('a');\n if (typeof link.download != 'string') link = null;\n }\n if (link) {\n link.href = sURI;\n link.download = sFileName;\n document.body.appendChild(link); // Firefox allegedly requires the link to be in the body\n link.click();\n document.body.removeChild(link);\n sAlert = 'Check your Downloads folder for ' + sFileName + '.';\n if (Web.isUserAgent(\"Chrome\")) {\n sAlert += '\\n\\nIn Chrome, after clicking OK, you may ALSO have to select the \"Window\" menu, choose \"Downloads\", and then locate this download and select \"Keep\".';\n sAlert += '\\n\\nThis is part of Chrome\\'s \"Security By Jumping Through Extra Hoops\" technology, which is much easier for Google to implement than actually checking for something malicious.';\n sAlert += '\\n\\nAnd for the record, there is nothing malicious on the PCjs website.';\n }\n } else {\n window.open(sURI);\n sAlert = 'Check your browser for a new window/tab containing the requested data' + (sFileName? (' (' + sFileName + ')') : '') + '.';\n }\n return sAlert;\n }\n\n /**\n * onCountRepeat(n, fnRepeat, fnComplete, msDelay)\n *\n * Call fnRepeat() n times with an msDelay millisecond delay between calls,\n * then call fnComplete() when n has been exhausted OR fnRepeat() returns false.\n *\n * @param {number} n\n * @param {function()} fnRepeat\n * @param {function()} fnComplete\n * @param {number} [msDelay]\n */\n static onCountRepeat(n, fnRepeat, fnComplete, msDelay)\n {\n var fnTimeout = function doCountRepeat()\n {\n n -= 1;\n if (n >= 0) {\n if (!fnRepeat()) n = 0;\n }\n if (n > 0) {\n setTimeout(fnTimeout, msDelay || 0);\n return;\n }\n fnComplete();\n };\n fnTimeout();\n }\n\n /**\n * onClickRepeat(e, msDelay, msRepeat, fn)\n *\n * Repeatedly call fn() with an initial msDelay, and an msRepeat delay thereafter,\n * as long as HTML control Object e has an active \"down\" event and fn() returns true.\n *\n * @param {Object} e\n * @param {number} msDelay\n * @param {number} msRepeat\n * @param {function(boolean)} fn is passed false on the first call, true on all repeated calls\n */\n static onClickRepeat(e, msDelay, msRepeat, fn)\n {\n var ms = 0, timer = null, fIgnoreMouseEvents = false;\n\n var fnRepeat = function doClickRepeat()\n {\n if (fn(ms === msRepeat)) {\n timer = setTimeout(fnRepeat, ms);\n ms = msRepeat;\n }\n };\n e.onmousedown = function()\n {\n // Web.log(\"onMouseDown()\");\n if (!fIgnoreMouseEvents) {\n if (!timer) {\n ms = msDelay;\n fnRepeat();\n }\n }\n };\n e.ontouchstart = function()\n {\n // Web.log(\"onTouchStart()\");\n if (!timer) {\n ms = msDelay;\n fnRepeat();\n }\n };\n e.onmouseup = e.onmouseout = function()\n {\n // Web.log(\"onMouseUp()/onMouseOut()\");\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n };\n e.ontouchend = e.ontouchcancel = function()\n {\n // Web.log(\"onTouchEnd()/onTouchCancel()\");\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n /*\n * Devices that generate ontouch* events ALSO generate onmouse* events,\n * and generally do so immediately after all the touch events are complete,\n * so unless we want double the action, we need to ignore mouse events.\n */\n fIgnoreMouseEvents = true;\n };\n }\n\n /**\n * onPageEvent(sName, fn)\n *\n * For 'onload', 'onunload', and 'onpageshow' events, most callers should NOT use this function, but\n * instead use Web.onInit(), Web.onShow(), and Web.onExit(), respectively.\n *\n * The only components that should still use onPageEvent() are THIS component (see the bottom of this file)\n * and components that need to capture other events (eg, the 'onresize' event in the Video component).\n *\n * This function creates a chain of callbacks, allowing multiple JavaScript modules to define handlers\n * for the same event, which wouldn't be possible if everyone modified window['onload'], window['onunload'],\n * etc, themselves. However, that's less of a concern now, because assuming everyone else is now using\n * onInit(), onExit(), etc, then there really IS only one component setting the window callback: this one.\n *\n * NOTE: It's risky to refer to obscure event handlers with \"dot\" names, because the Closure Compiler may\n * erroneously replace them (eg, window.onpageshow is a good example).\n *\n * @param {string} sFunc\n * @param {function()} fn\n */\n static onPageEvent(sFunc, fn)\n {\n if (window) {\n var fnPrev = window[sFunc];\n if (typeof fnPrev !== 'function') {\n window[sFunc] = fn;\n } else {\n /*\n * TODO: Determine whether there's any value in receiving/sending the Event object that the\n * browser provides when it generates the original event.\n */\n window[sFunc] = function onWindowEvent()\n {\n if (fnPrev) fnPrev();\n fn();\n };\n }\n }\n };\n\n /**\n * onInit(fn)\n *\n * Use this instead of setting window.onload. Allows multiple JavaScript modules to define their own 'onload' event handler.\n *\n * @param {function()} fn\n */\n static onInit(fn)\n {\n Web.aPageEventHandlers['init'].push(fn);\n };\n\n /**\n * onShow(fn)\n *\n * @param {function()} fn\n *\n * Use this instead of setting window.onpageshow. Allows multiple JavaScript modules to define their own 'onpageshow' event handler.\n */\n static onShow(fn)\n {\n Web.aPageEventHandlers['show'].push(fn);\n };\n\n /**\n * onExit(fn)\n *\n * @param {function()} fn\n *\n * Use this instead of setting window.onunload. Allows multiple JavaScript modules to define their own 'onunload' event handler.\n */\n static onExit(fn)\n {\n Web.aPageEventHandlers['exit'].push(fn);\n };\n\n /**\n * doPageEvent(afn)\n *\n * @param {Array.<function()>} afn\n */\n static doPageEvent(afn)\n {\n if (Web.fPageEventsEnabled) {\n try {\n for (var i = 0; i < afn.length; i++) {\n afn[i]();\n }\n } catch (e) {\n Web.notice(\"An unexpected error occurred: \" + e.message + \"\\n\\nIf it happens again, please send this information to support@pcjs.org. Thanks.\");\n }\n }\n };\n\n /**\n * enablePageEvents(fEnable)\n *\n * @param {boolean} fEnable is true to enable page events, false to disable (they're enabled by default)\n */\n static enablePageEvents(fEnable)\n {\n if (!Web.fPageEventsEnabled && fEnable) {\n Web.fPageEventsEnabled = true;\n if (Web.fPageLoaded) Web.sendPageEvent('init');\n if (Web.fPageShowed) Web.sendPageEvent('show');\n return;\n }\n Web.fPageEventsEnabled = fEnable;\n }\n\n /**\n * sendPageEvent(sEvent)\n *\n * This allows us to manually trigger page events.\n *\n * @param {string} sEvent (one of 'init', 'show' or 'exit')\n */\n static sendPageEvent(sEvent)\n {\n if (Web.aPageEventHandlers[sEvent]) {\n Web.doPageEvent(Web.aPageEventHandlers[sEvent]);\n }\n }\n}\n\nWeb.parmsURL = null; // initialized on first call to parseURLParms()\n\nWeb.aPageEventHandlers = {\n 'init': [], // list of window 'onload' handlers\n 'show': [], // list of window 'onpageshow' handlers\n 'exit': [] // list of window 'onunload' handlers (although we prefer to use 'onbeforeunload' if possible)\n};\n\nWeb.asBrowserPrefixes = ['', 'moz', 'ms', 'webkit'];\n\nWeb.fPageLoaded = false; // set once the page's first 'onload' event has occurred\nWeb.fPageShowed = false; // set once the page's first 'onpageshow' event has occurred\nWeb.fPageEventsEnabled = true; // default is true, set to false (or true) by enablePageEvents()\n\n/**\n * fLocalStorage\n *\n * true if localStorage support exists, is enabled, and works; \"falsey\" otherwise\n *\n * @type {boolean|null}\n */\nWeb.fLocalStorage = null;\n\n/**\n * TODO: Is there any way to get the Closure Compiler to stop inlining this string? This isn't cutting it.\n *\n * @const {string}\n */\nWeb.sLocalStorageTest = \"PCjs.localStorage\";\n\nWeb.onPageEvent('onload', function onPageLoad() {\n Web.fPageLoaded = true;\n Web.doPageEvent(Web.aPageEventHandlers['init']);\n});\n\nWeb.onPageEvent('onpageshow', function onPageShow() {\n Web.fPageShowed = true;\n Web.doPageEvent(Web.aPageEventHandlers['show']);\n});\n\nWeb.onPageEvent(Web.isUserAgent(\"iOS\")? 'onpagehide' : (Web.isUserAgent(\"Opera\")? 'onunload' : 'onbeforeunload'), function onPageUnload() {\n Web.doPageEvent(Web.aPageEventHandlers['exit']);\n});\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/component.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * All PCjs components now use JSDoc types, primarily so that Google's Closure Compiler will compile\n * everything with zero warnings when ADVANCED_OPTIMIZATIONS are enabled. For more information about\n * the JSDoc types supported by the Closure Compiler:\n *\n * https://developers.google.com/closure/compiler/docs/js-for-compiler#types\n *\n * I also attempted to validate this code with JSLint, but it complained too much; eg, it didn't like\n * \"while (true)\", a tried and \"true\" programming convention for decades, and it wanted me to replace\n * all \"++\" and \"--\" operators with \"+= 1\" and \"-= 1\", use \"(s || '')\" instead of \"(s? s : '')\", etc.\n *\n * I prefer sticking with traditional C-style idioms, in part because they are more portable. That\n * does NOT mean I'm trying to write \"portable JavaScript,\" but some of this code was ported from C code\n * I'd written long ago, so portability is good, and I'm not going to throw that away if there's no need.\n *\n * UPDATE: I've since switched from JSLint to JSHint, which seems to have more reasonable defaults.\n * And for new code, I have adopted some popular JavaScript idioms, like \"(s || '')\", although the need\n * for those kinds of expressions will be reduced as I also start adopting some ES6 features, like\n * default parameters.\n */\n\n\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * subclass (eg, SerialPort), because otherwise the Compiler won't allow us to *reference*\n * the named property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass Component {\n /**\n * Component(type, parms, bitsMessage)\n *\n * A Component object requires:\n *\n * type: a user-defined type name (eg, \"CPU\")\n *\n * and accepts any or all of the following (parms) properties:\n *\n * id: component ID (default is \"\")\n * name: component name (default is \"\"; if blank, toString() will use the type name only)\n * comment: component comment string (default is undefined)\n *\n * Component subclasses will usually have additional (parms) properties.\n *\n * @param {string} type\n * @param {Object} [parms]\n * @param {number} [bitsMessage] selects message(s) that the component wants to enable (default is 0)\n */\n constructor(type, parms, bitsMessage)\n {\n this.type = type;\n\n if (!parms) parms = {'id': \"\", 'name': \"\"};\n\n this.id = parms['id'] || \"\";\n this.name = parms['name'];\n this.comment = parms['comment'];\n this.parms = parms;\n\n /*\n * The following Component properties need to be accessible by other machines and/or command scripts;\n * well, OK, or we could have exported some new functions to walk the contents of these properties, as we\n * did with findMachineComponent(), but this works just as well.\n *\n * Also, while the double-assignment looks silly (ie, using both dot and bracket property notation), it\n * resolves a complaint from the Closure Compiler, because if we use ONLY bracket notation here, then the\n * Compiler wants us to change all the other references to bracket notation as well.\n */\n this.exports = this['exports'] = {};\n this.bindings = this['bindings'] = {};\n\n var i = this.id.indexOf('.');\n if (i < 0) {\n this.idComponent = this.id;\n } else {\n this.idMachine = this.id.substr(0, i);\n this.idComponent = this.id.substr(i + 1);\n }\n\n /*\n * Gather all the various component flags (booleans) into a single \"flags\" object, and encourage\n * subclasses to do the same, to reduce the property clutter we have to wade through while debugging.\n */\n this.flags = {\n ready: false,\n busy: false,\n busyCancel: false,\n initDone: false,\n powered: false,\n unloading: false,\n error: false\n };\n\n this.fnReady = null;\n this.clearError();\n this.bitsMessage = bitsMessage || 0;\n\n this.cmp = null;\n this.bus = null;\n this.cpu = null;\n this.dbg = null;\n\n /*\n * TODO: Consider adding another parameter to the Component() constructor that allows components to tell\n * us if they support single or multiple instances per machine. For example, there can be multiple SerialPort\n * components per machine, but only one CPU component (some machines also support an FPU, but that component\n * is considered separate from the CPU).\n *\n * It's not critical, but it would help catch machine configuration errors; for example, a machine that mistakenly\n * includes two CPU components may, aside from wasting memory, end up with odd side-effects, like unresponsive\n * CPU controls.\n */\n Component.add(this);\n }\n\n /**\n * Component.add(component)\n *\n * @param {Component} component\n */\n static add(component)\n {\n /*\n * This just generates a lot of useless noise, handy in the early days, not so much these days....\n *\n * if (DEBUG) Component.log(\"Component.add(\" + component.type + \",\" + component.id + \")\");\n */\n Component.components.push(component);\n }\n\n /**\n * Component.addMachine(idMachine)\n *\n * @param {string} idMachine\n */\n static addMachine(idMachine)\n {\n Component.machines[idMachine] = {};\n }\n\n /**\n * Component.addMachineResource(idMachine, sName, data)\n *\n * @param {string} idMachine\n * @param {string|null} sName (name of the resource)\n * @param {*} data\n */\n static addMachineResource(idMachine, sName, data)\n {\n /*\n * I used to assert(Component.machines[idMachine]), but when we're running as a Node app, embed.js is not used,\n * so addMachine() is never called, so resources do not need to be recorded.\n */\n if (Component.machines[idMachine] && sName) {\n Component.machines[idMachine][sName] = data;\n }\n }\n\n /**\n * Component.getMachineResources(idMachine)\n *\n * @param {string} idMachine\n * @return {Object|undefined}\n */\n static getMachineResources(idMachine)\n {\n return Component.machines[idMachine];\n }\n\n /**\n * Component.getTime()\n *\n * @return {number} the current time, in milliseconds\n */\n static getTime()\n {\n return Date.now() || +new Date();\n }\n\n /**\n * Component.log(s, type)\n *\n * For diagnostic output only.\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n static log(s, type)\n {\n if (!COMPILED) {\n if (s) {\n var sElapsed = \"\", sMsg = (type? (type + \": \") : \"\") + s;\n if (typeof Usr != \"undefined\") {\n if (Component.msStart === undefined) {\n Component.msStart = Component.getTime();\n }\n sElapsed = (Component.getTime() - Component.msStart) + \"ms: \";\n }\n sMsg = sMsg.replace(/\\r/g, '\\\\r').replace(/\\n/g, ' ');\n if (window && window.console) console.log(sElapsed + sMsg);\n }\n }\n }\n\n /**\n * Component.assert(f, s)\n *\n * Verifies conditions that must be true (for DEBUG builds only).\n *\n * The Closure Compiler should automatically remove all references to Component.assert() in non-DEBUG builds.\n * TODO: Add a task to the build process that \"asserts\" there are no instances of \"assertion failure\" in RELEASE builds.\n *\n * @param {boolean} f is the expression we are asserting to be true\n * @param {string} [s] is description of the assertion on failure\n */\n static assert(f, s)\n {\n if (DEBUG) {\n if (!f) {\n if (!s) s = \"assertion failure\";\n Component.log(s);\n throw new Error(s);\n }\n }\n }\n\n /**\n * Component.print(s)\n *\n * Components that inherit from this class should use this.print(), rather than Component.print(), because\n * if a Control Panel is loaded, it will override only the instance method, not the class method (overriding the\n * class method would improperly affect any other machines loaded on the same page).\n *\n * @this {Component}\n * @param {string} s\n */\n static print(s)\n {\n if (!COMPILED) {\n var i = s.lastIndexOf('\\n');\n if (i >= 0) {\n Component.println(s.substr(0, i));\n s = s.substr(i + 1);\n }\n Component.printBuffer += s;\n }\n }\n\n /**\n * Component.println(s, type, id)\n *\n * Components that inherit from this class should use this.println(), rather than Component.println(), because\n * if a Control Panel is loaded, it will override only the instance method, not the class method (overriding the\n * class method would improperly affect any other machines loaded on the same page).\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n * @param {string} [id] is the caller's ID, if any\n */\n static println(s, type, id)\n {\n if (!COMPILED) {\n s = Component.printBuffer + (s || \"\");\n Component.log((id? (id + \": \") : \"\") + (s? (\"\\\"\" + s + \"\\\"\") : \"\"), type);\n Component.printBuffer = \"\";\n }\n }\n\n /**\n * Component.notice(s, fPrintOnly, id)\n *\n * notice() is like println() but implies a need for user notification, so we alert() as well.\n *\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n * @return {boolean}\n */\n static notice(s, fPrintOnly, id)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.NOTICE, id);\n }\n if (!fPrintOnly) Component.alertUser((id? (id + \": \") : \"\") + s);\n return true;\n }\n\n /**\n * Component.warning(s)\n *\n * @param {string} s describes the warning\n */\n static warning(s)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.WARNING);\n }\n Component.alertUser(s);\n }\n\n /**\n * Component.error(s)\n *\n * @param {string} s describes the error; an alert() is displayed as well\n */\n static error(s)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.ERROR);\n }\n Component.alertUser(s);\n }\n\n /**\n * Component.alertUser(sMessage)\n *\n * @param {string} sMessage\n */\n static alertUser(sMessage)\n {\n if (window) {\n window.alert(sMessage);\n } else {\n Component.log(sMessage);\n }\n }\n\n /**\n * Component.confirmUser(sPrompt)\n *\n * @param {string} sPrompt\n * @returns {boolean} true if the user clicked OK, false if Cancel/Close\n */\n static confirmUser(sPrompt)\n {\n var fResponse = false;\n if (window) {\n fResponse = window.confirm(sPrompt);\n }\n return fResponse;\n }\n\n /**\n * Component.promptUser()\n *\n * @param {string} sPrompt\n * @param {string} [sDefault]\n * @returns {string|null}\n */\n static promptUser(sPrompt, sDefault)\n {\n var sResponse = null;\n if (window) {\n sResponse = window.prompt(sPrompt, sDefault === undefined? \"\" : sDefault);\n }\n return sResponse;\n }\n\n /**\n * Component.appendControl(control, sText)\n *\n * @param {Object} control\n * @param {string} sText\n */\n static appendControl(control, sText)\n {\n control.value += sText;\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (COMPILED) {\n sText = control.value;\n if (sText.length > 8192) control.value = sText.substr(sText.length - 4096);\n }\n control.scrollTop = control.scrollHeight;\n }\n\n /**\n * Component.replaceControl(control, sSearch, sReplace)\n *\n * @param {Object} control\n * @param {string} sSearch\n * @param {string} sReplace\n */\n static replaceControl(control, sSearch, sReplace)\n {\n var sText = control.value;\n var i = sText.lastIndexOf(sSearch);\n if (i < 0) {\n sText += sSearch + '\\n';\n } else {\n sText = sText.substr(0, i) + sReplace + sText.substr(i + sSearch.length);\n }\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (COMPILED && sText.length > 8192) sText = sText.substr(sText.length - 4096);\n control.value = sText;\n control.scrollTop = control.scrollHeight;\n }\n\n /**\n * Component.bindExternalControl(component, sBinding, sType)\n *\n * @param {Component} component\n * @param {string} sBinding\n * @param {string} [sType] is the external component type (default is \"Panel\")\n */\n static bindExternalControl(component, sBinding, sType = \"Panel\")\n {\n if (sBinding) {\n var target = Component.getComponentByType(sType, component.id);\n if (target) {\n var control = target.bindings[sBinding];\n if (control) {\n component.setBinding(\"\", sBinding, control);\n }\n }\n }\n }\n\n /**\n * Component.bindComponentControls(component, element, sAppClass)\n *\n * @param {Component} component\n * @param {HTMLElement} element from the DOM\n * @param {string} sAppClass\n */\n static bindComponentControls(component, element, sAppClass)\n {\n var aeControls = Component.getElementsByClass(element.parentNode, sAppClass + \"-control\");\n\n for (var iControl = 0; iControl < aeControls.length; iControl++) {\n\n var aeChildNodes = aeControls[iControl].childNodes;\n\n for (var iNode = 0; iNode < aeChildNodes.length; iNode++) {\n var control = aeChildNodes[iNode];\n if (control.nodeType !== 1 /* document.ELEMENT_NODE */) {\n continue;\n }\n var sClass = control.getAttribute(\"class\");\n if (!sClass) continue;\n var aClasses = sClass.split(\" \");\n for (var iClass = 0; iClass < aClasses.length; iClass++) {\n var parms;\n sClass = aClasses[iClass];\n switch (sClass) {\n case sAppClass + \"-binding\":\n parms = Component.getComponentParms(/** @type {HTMLElement} */(control));\n if (parms && parms['binding'] !== undefined) {\n component.setBinding(parms['type'], parms['binding'], /** @type {HTMLElement} */(control), parms['value']);\n } else if (!parms || parms['type'] != \"description\") {\n Component.log(\"Component '\" + component.toString() + \"' missing binding\" + (parms? \" for \" + parms['type'] : \"\"), \"warning\");\n }\n iClass = aClasses.length;\n break;\n default:\n // if (DEBUG) Component.log(\"Component.bindComponentControls(\" + component.toString() + \"): unrecognized control class \\\"\" + sClass + \"\\\"\", \"warning\");\n break;\n }\n }\n }\n }\n }\n\n /**\n * Component.getComponents(idRelated)\n *\n * We could store components as properties, using the component's ID, and change\n * this linear lookup into a property lookup, but some components may have no ID.\n *\n * @param {string} [idRelated] of related component\n * @return {Array} of components\n */\n static getComponents(idRelated)\n {\n var i;\n var aComponents = [];\n /*\n * getComponentByID(id, idRelated)\n *\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated) {\n if ((i = idRelated.indexOf('.')) > 0)\n idRelated = idRelated.substr(0, i + 1);\n else\n idRelated = \"\";\n }\n for (i = 0; i < Component.components.length; i++) {\n var component = Component.components[i];\n if (!idRelated || !component.id.indexOf(idRelated)) {\n aComponents.push(component);\n }\n }\n return aComponents;\n }\n\n /**\n * Component.getComponentByID(id, idRelated)\n *\n * We could store components as properties, using the component's ID, and change\n * this linear lookup into a property lookup, but some components may have no ID.\n *\n * @param {string} id of the desired component\n * @param {string} [idRelated] of related component\n * @return {Component|null}\n */\n static getComponentByID(id, idRelated)\n {\n if (id !== undefined) {\n var i;\n /*\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated && (i = idRelated.indexOf('.')) > 0) {\n id = idRelated.substr(0, i + 1) + id;\n }\n for (i = 0; i < Component.components.length; i++) {\n if (Component.components[i].id === id) {\n return Component.components[i];\n }\n }\n if (Component.components.length) {\n Component.log(\"Component ID '\" + id + \"' not found\", \"warning\");\n }\n }\n return null;\n }\n\n /**\n * Component.getComponentByType(sType, idRelated, componentPrev)\n *\n * @param {string} sType of the desired component\n * @param {string} [idRelated] of related component\n * @param {Component|null} [componentPrev] of previously returned component, if any\n * @return {Component|null}\n */\n static getComponentByType(sType, idRelated, componentPrev)\n {\n if (sType !== undefined) {\n var i;\n /*\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated) {\n if ((i = idRelated.indexOf('.')) > 0) {\n idRelated = idRelated.substr(0, i + 1);\n } else {\n idRelated = \"\";\n }\n }\n for (i = 0; i < Component.components.length; i++) {\n if (componentPrev) {\n if (componentPrev == Component.components[i]) componentPrev = null;\n continue;\n }\n if (sType == Component.components[i].type && (!idRelated || !Component.components[i].id.indexOf(idRelated))) {\n return Component.components[i];\n }\n }\n Component.log(\"Component type '\" + sType + \"' not found\", \"warning\");\n }\n return null;\n }\n\n /**\n * Component.getComponentParms(element)\n *\n * @param {HTMLElement} element from the DOM\n */\n static getComponentParms(element)\n {\n var parms = null;\n var sParms = element.getAttribute(\"data-value\");\n if (sParms) {\n try {\n parms = eval('(' + sParms + ')'); // jshint ignore:line\n /*\n * We can no longer invoke removeAttribute() because some components (eg, Panel) need\n * to run their initXXX() code more than once, to avoid initialization-order dependencies.\n *\n * if (!DEBUG) {\n * element.removeAttribute(\"data-value\");\n * }\n */\n } catch(e) {\n Component.error(e.message + \" (\" + sParms + \")\");\n }\n }\n return parms;\n }\n\n /**\n * Component.getElementsByClass(element, sClass, sObjClass)\n *\n * This is a cross-browser helper function, since not all browser's support getElementsByClassName()\n *\n * TODO: This should probably be moved into weblib.js at some point, along with the control binding functions above,\n * to keep all the browser-related code together.\n *\n * @param {HTMLDocument|HTMLElement|Node} element from the DOM\n * @param {string} sClass\n * @param {string} [sObjClass]\n * @return {Array|NodeList}\n */\n static getElementsByClass(element, sClass, sObjClass)\n {\n if (sObjClass) sClass += '-' + sObjClass + \"-object\";\n /*\n * Use the browser's built-in getElementsByClassName() if it appears to be available\n * (for example, it's not available in IE8, but it should be available in IE9 and up)\n */\n if (element.getElementsByClassName) {\n return element.getElementsByClassName(sClass);\n }\n var i, j, ae = [];\n var aeAll = element.getElementsByTagName(\"*\");\n var re = new RegExp('(^| )' + sClass + '( |$)');\n for (i = 0, j = aeAll.length; i < j; i++) {\n if (re.test(aeAll[i].className)) {\n ae.push(aeAll[i]);\n }\n }\n if (!ae.length) {\n Component.log('No elements of class \"' + sClass + '\" found');\n }\n return ae;\n }\n\n /**\n * Component.getScriptCommands(sScript)\n *\n * This is a simple parser that breaks sScript into an array of commands, where each command\n * is an array of tokens, where tokens are sequences of characters separated by any of: tab, space,\n * carriage-return (CR), line-feed (LF), semicolon, single-quote, or double-quote; if a quote is\n * used, all characters up to the next matching quote become part of the token, allowing any of the\n * other separators to be part of the token. CR, LF and semicolon also serve to terminate a command,\n * with semicolon being preferred, because it's 1) more visible, and 2) essential when the entire\n * script is a multi-line string where all CR/LF were replaced by spaces (which is what Jekyll does,\n * and since we can't change Jekyll, it's what our own MarkDown Front Matter parser does as well;\n * see convertMD() in markout.js, where the aCommandDefs array is built).\n *\n * Backslash sequences like \\n, \\r, and \\\\ have already been converted to LF, CR and backslash\n * characters, since the entire script string is injected into a JavaScript function call, so any\n * backslash sequence that JavaScript supports is automatically converted:\n *\n * \\0 \\' \\\" \\\\ \\n \\r \\v \\t \\b \\f \\uXXXX \\xXX\n * ^J ^M ^K ^I ^H ^L\n *\n * To support any other non-printable 8-bit character, such as ESC, you should use \\xXX, where XX\n * is the ASCII code in hex. For ESC, that would be \\x1B.\n *\n * @param {string} sScript\n * @return {Array}\n */\n static getScriptCommands(sScript)\n {\n var cch = sScript.length;\n var aCommands = [], aTokens = [], sToken = \"\", chQuote = null;\n for (var i = 0; i < cch; i++) {\n var ch = sScript[i];\n if (ch == '\"' || ch == \"'\") {\n if (chQuote && ch != chQuote) {\n sToken += ch;\n continue;\n }\n if (!chQuote) {\n chQuote = ch;\n } else {\n chQuote = null;\n }\n if (sToken) {\n aTokens.push(sToken);\n sToken = \"\";\n }\n continue;\n }\n if (!chQuote) {\n if (ch == '\\r' || ch == '\\n') {\n ch = ';';\n }\n if (ch == ' ' || ch == '\\t' || ch == ';') {\n if (sToken) {\n aTokens.push(sToken);\n sToken = \"\";\n }\n if (ch == ';' && aTokens.length) {\n aCommands.push(aTokens);\n aTokens = [];\n }\n continue;\n }\n }\n sToken += ch;\n }\n if (sToken) {\n aTokens.push(sToken);\n }\n if (aTokens.length) {\n aCommands.push(aTokens);\n }\n return aCommands;\n }\n\n /**\n * Component.processScript(idMachine, sScript)\n *\n * @param {string} idMachine\n * @param {string} [sScript]\n * @return {boolean}\n */\n static processScript(idMachine, sScript)\n {\n var fSuccess = false;\n idMachine += \".machine\";\n if (!sScript) {\n delete Component.commands[idMachine];\n fSuccess = true;\n }\n else if (typeof sScript == \"string\" && !Component.commands[idMachine]) {\n fSuccess = true;\n Component.commands[idMachine] = Component.getScriptCommands(sScript);\n if (!Component.processCommands(idMachine)) {\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * Component.processCommands(idMachine)\n *\n * @param {string} idMachine\n * @return {boolean}\n */\n static processCommands(idMachine)\n {\n var fSuccess = true;\n var aCommands = Component.commands[idMachine];\n\n // var dbg = Component.getComponentByType(\"Debugger\", idMachine);\n\n while (aCommands && aCommands.length) {\n\n var aTokens = aCommands.splice(0, 1)[0];\n var sCommand = aTokens[0];\n\n /*\n * It's possible to route this output to the Debugger window with dbg.println()\n * instead, but it's a bit too confusing mingling script output in a window that\n * already mingles Debugger and machine output.\n */\n Component.println(aTokens.join(' '), Component.PRINT.SCRIPT);\n\n var fnCallReady = null;\n if (Component.asyncCommands.indexOf(sCommand) >= 0) {\n fnCallReady = function processNextCommand() {\n return function() {\n Component.processCommands(idMachine);\n }\n }();\n }\n\n var fnCommand = Component.globalCommands[sCommand];\n if (fnCommand) {\n if (!fnCallReady) {\n fSuccess = fnCommand(aTokens[1], aTokens[2], aTokens[3]);\n } else {\n if (!fnCommand(fnCallReady, aTokens[1], aTokens[2], aTokens[3])) break;\n }\n }\n else {\n fSuccess = false;\n var component = Component.getComponentByType(aTokens[1], idMachine);\n if (component) {\n fnCommand = Component.componentCommands[sCommand];\n if (fnCommand) {\n fSuccess = fnCommand(component, aTokens[2], aTokens[3]);\n }\n else {\n var exports = component['exports'];\n if (exports) {\n fnCommand = exports[sCommand];\n if (fnCommand) {\n fSuccess = true;\n if (!fnCallReady) {\n fSuccess = fnCommand.call(component, aTokens[2], aTokens[3]);\n } else {\n if (!fnCommand.call(component, fnCallReady, aTokens[2], aTokens[3])) break;\n }\n }\n }\n }\n }\n }\n\n if (!fSuccess) {\n Component.alertUser(\"Script error: '\" + sCommand + \"' command \" + (fnCommand? \" failed\" : \" not recognized\"));\n break;\n }\n }\n\n if (aCommands && !aCommands.length) {\n delete Component.commands[idMachine];\n }\n\n return fSuccess;\n }\n\n /**\n * Component.scriptAlert(sMessage)\n *\n * @param {string} sMessage\n * @return {boolean}\n */\n static scriptAlert(sMessage)\n {\n Component.alertUser(sMessage);\n return true;\n }\n\n /**\n * Component.scriptSelect(component, sBinding, sValue)\n *\n * @param {Component} component\n * @param {string} sBinding\n * @param {string} sValue\n * @return {boolean}\n */\n static scriptSelect(component, sBinding, sValue)\n {\n var fSuccess = false;\n var aBindings = component['bindings'];\n var control = aBindings[sBinding];\n if (control) {\n for (var i = 0; i < control.options.length; i++) {\n if (control.options[i].textContent == sValue) {\n if (control.selectedIndex != i) {\n control.selectedIndex = i;\n }\n fSuccess = true;\n break;\n }\n }\n }\n return fSuccess;\n }\n\n /**\n * Component.scriptSleep(fnCallback, sDelay)\n *\n * @param {function()} fnCallback\n * @param {string} sDelay (in milliseconds)\n * @return {boolean}\n */\n static scriptSleep(fnCallback, sDelay)\n {\n setTimeout(fnCallback, +sDelay);\n return false;\n }\n\n /**\n * toString()\n *\n * @this {Component}\n * @return {string}\n */\n toString()\n {\n return (this.name? this.name : (this.id || this.type));\n }\n\n /**\n * getMachineNum()\n *\n * @this {Component}\n * @return {number} unique machine number\n */\n getMachineNum()\n {\n var nMachine = 1;\n if (this.idMachine) {\n var aDigits = this.idMachine.match(/\\d+/);\n if (aDigits !== null)\n nMachine = parseInt(aDigits[0], 10);\n }\n return nMachine;\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * Component's setBinding() method is intended to be overridden by subclasses.\n *\n * @this {Component}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, 'print')\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n switch (sBinding) {\n case 'clear':\n if (!this.bindings[sBinding]) {\n this.bindings[sBinding] = control;\n control.onclick = (function(component) {\n return function clearControl() {\n if (component.bindings['print']) {\n component.bindings['print'].value = \"\";\n }\n };\n }(this));\n }\n return true;\n case 'print':\n if (!this.bindings[sBinding]) {\n var controlTextArea = /** @type {HTMLTextAreaElement} */(control);\n this.bindings[sBinding] = controlTextArea;\n /**\n * Override this.notice() with a replacement function that eliminates the Component.alertUser() call.\n *\n * @this {Component}\n * @param {string} s\n * @return {boolean}\n */\n this.notice = function noticeControl(s /*, fPrintOnly, id*/) {\n this.println(s, this.type);\n return true;\n };\n /*\n * This was added for Firefox (Safari will clear the <textarea> on a page reload, but Firefox does not).\n */\n controlTextArea.value = \"\";\n this.print = function(control) {\n return function printControl(s) {\n Component.appendControl(control, s);\n };\n }(controlTextArea);\n this.println = function(component, control) {\n return function printlnControl(s, type, id) {\n if (!s) s = \"\";\n if (type != Component.PRINT.PROGRESS || s.slice(-3) != \"...\") {\n if (type) s = type + \": \" + s;\n Component.appendControl(control, s + '\\n');\n } else {\n Component.replaceControl(control, s, s + '.');\n }\n if (!COMPILED && window && window.console) Component.println(s, type, id);\n };\n }(this, controlTextArea);\n }\n return true;\n default:\n return false;\n }\n }\n\n /**\n * log(s, type)\n *\n * For diagnostic output only.\n *\n * WARNING: Even though this function's body is completely wrapped in DEBUG, that won't prevent the Closure Compiler\n * from including it, so all calls must still be prefixed with \"if (DEBUG) ....\". For this reason, the class method,\n * Component.log(), is preferred, because the compiler IS smart enough to remove those calls.\n *\n * @this {Component}\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n log(s, type)\n {\n if (!COMPILED) {\n Component.log(s, type || this.id || this.type);\n }\n }\n\n /**\n * assert(f, s)\n *\n * Verifies conditions that must be true (for DEBUG builds only).\n *\n * WARNING: Make sure you preface all calls to this.assert() with \"if (DEBUG)\", because unlike Component.assert(),\n * the Closure Compiler can't be sure that this instance method hasn't been overridden, so it refuses to treat it as\n * dead code in non-DEBUG builds.\n *\n * TODO: Add a task to the build process that \"asserts\" there are no instances of \"assertion failure\" in RELEASE builds.\n *\n * @this {Component}\n * @param {boolean|number} f is the expression asserted to be true\n * @param {string} [s] is a description of the assertion to be displayed or logged on failure\n */\n assert(f, s)\n {\n if (DEBUG) {\n if (!f) {\n s = \"assertion failure in \" + (this.id || this.type) + (s? \": \" + s : \"\");\n if (DEBUGGER && this.dbg) {\n this.dbg.stopCPU();\n /*\n * Why do we throw an Error only to immediately catch and ignore it? Simply to give\n * any IDE the opportunity to inspect the application's state. Even when the IDE has\n * control, you should still be able to invoke Debugger commands from the IDE's REPL,\n * using the global function that the Debugger constructor defines; eg:\n *\n * pcx86('r')\n * pcx86('dw 0:0')\n * pcx86('h')\n * ...\n *\n * If you have no desire to stop on assertions, consider this a no-op. However, another\n * potential benefit of creating an Error object is that, for browsers like Chrome, we get\n * a stack trace, too.\n */\n try {\n throw new Error(s);\n } catch(e) {\n this.println(e.stack || e.message);\n }\n return;\n }\n this.log(s);\n throw new Error(s);\n }\n }\n }\n\n /**\n * print(s)\n *\n * Components using this.print() should wait until after their constructor has run to display any messages, because\n * if a Control Panel has been loaded, its override will not take effect until its own constructor has run.\n *\n * @this {Component}\n * @param {string} s\n */\n print(s)\n {\n Component.print(s);\n }\n\n /**\n * println(s, type, id)\n *\n * Components using this.println() should wait until after their constructor has run to display any messages, because\n * if a Control Panel has been loaded, its override will not take effect until its own constructor has run.\n *\n * @this {Component}\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n * @param {string} [id] is the caller's ID, if any\n */\n println(s, type, id)\n {\n Component.println(s, type, id || this.id);\n }\n\n /**\n * status(s)\n *\n * status() is like println() but it also includes information about the component (ie, the component type),\n * which is why there is no corresponding Component.status() function.\n *\n * @this {Component}\n * @param {string} s is the message text\n */\n status(s)\n {\n this.println(this.type + \": \" + s);\n }\n\n /**\n * notice(s, fPrintOnly, id)\n *\n * notice() is like println() but implies a need for user notification, so we alert() as well; however, if this.println()\n * is overridden, this.notice will be replaced with a similar override, on the assumption that the override is taking care\n * of alerting the user.\n *\n * @this {Component}\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n * @return {boolean}\n */\n notice(s, fPrintOnly, id)\n {\n if (!fPrintOnly) {\n /*\n * See if the associated computer, if any, is \"unloading\"....\n */\n var computer = Component.getComponentByType(\"Computer\", this.id);\n if (computer && computer.flags.unloading) {\n console.log(\"ignoring notice during unload: \" + s);\n return false;\n }\n }\n Component.notice(s, fPrintOnly, id || this.type);\n return true;\n }\n\n /**\n * setError(s)\n *\n * Set a fatal error condition\n *\n * @this {Component}\n * @param {string} s describes a fatal error condition\n */\n setError(s)\n {\n this.flags.error = true;\n this.notice(s); // TODO: Any cases where we should still prefix this string with \"Fatal error: \"?\n }\n\n /**\n * clearError()\n *\n * Clear any fatal error condition\n *\n * @this {Component}\n */\n clearError() {\n this.flags.error = false;\n }\n\n /**\n * isError()\n *\n * Report any fatal error condition\n *\n * @this {Component}\n * @return {boolean} true if a fatal error condition exists, false if not\n */\n isError()\n {\n if (this.flags.error) {\n this.println(this.toString() + \" error\");\n return true;\n }\n return false;\n }\n\n /**\n * isReady(fnReady)\n *\n * Return the \"ready\" state of the component; if the component is not ready, it will queue the optional\n * notification function, otherwise it will immediately call the notification function, if any, without queuing it.\n *\n * NOTE: Since only the Computer component actually cares about the \"readiness\" of other components, the so-called\n * \"queue\" of notification functions supports exactly one function. This keeps things nice and simple.\n *\n * @this {Component}\n * @param {function()} [fnReady]\n * @return {boolean} true if the component is in a \"ready\" state, false if not\n */\n isReady(fnReady)\n {\n if (fnReady) {\n if (this.flags.ready) {\n fnReady();\n } else {\n if (MAXDEBUG) this.log(\"NOT ready\");\n this.fnReady = fnReady;\n }\n }\n return this.flags.ready;\n }\n\n /**\n * setReady(fReady)\n *\n * Set the \"ready\" state of the component to true, and call any queued notification functions.\n *\n * @this {Component}\n * @param {boolean} [fReady] is assumed to indicate \"ready\" unless EXPLICITLY set to false\n */\n setReady(fReady)\n {\n if (!this.flags.error) {\n this.flags.ready = (fReady !== false);\n if (this.flags.ready) {\n if (MAXDEBUG /* || this.name */) this.log(\"ready\");\n var fnReady = this.fnReady;\n this.fnReady = null;\n if (fnReady) fnReady();\n }\n }\n }\n\n /**\n * isBusy(fCancel)\n *\n * Return the \"busy\" state of the component\n *\n * @this {Component}\n * @param {boolean} [fCancel] is set to true to cancel a \"busy\" state\n * @return {boolean} true if \"busy\", false if not\n */\n isBusy(fCancel)\n {\n if (this.flags.busy) {\n if (fCancel) {\n this.flags.busyCancel = true;\n } else if (fCancel === undefined) {\n this.println(this.toString() + \" busy\");\n }\n }\n return this.flags.busy;\n }\n\n /**\n * setBusy(fBusy)\n *\n * Update the current busy state; if a busyCancel request is pending, it will be honored now.\n *\n * @this {Component}\n * @param {boolean} fBusy\n * @return {boolean}\n */\n setBusy(fBusy)\n {\n if (this.flags.busyCancel) {\n this.flags.busy = false;\n this.flags.busyCancel = false;\n return false;\n }\n if (this.flags.error) {\n this.println(this.toString() + \" error\");\n return false;\n }\n this.flags.busy = fBusy;\n return this.flags.busy;\n }\n\n /**\n * powerUp(fSave)\n *\n * @this {Component}\n * @param {Object|null} data\n * @param {boolean} [fRepower] is true if this is \"repower\" notification\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n this.flags.powered = true;\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Component}\n * @param {boolean} fSave\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n if (fShutdown) this.flags.powered = false;\n return true;\n }\n\n /**\n * messageEnabled(bitsMessage)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n *\n * @this {Component}\n * @param {number} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n * @return {boolean} true if all specified message enabled, false if not\n */\n messageEnabled(bitsMessage = 0)\n {\n if (DEBUGGER && this.dbg) {\n if (this !== this.dbg) {\n bitsMessage = bitsMessage || this.bitsMessage;\n }\n var bitsEnabled = this.dbg.bitsMessage & bitsMessage;\n /*\n * This next \"bit\" of logic is for PCx86 and any other machine where we've expanded the set of\n * messages by reusing bits in the low nibbles in combination with different bits in the high nibble.\n * If the input bits adhere to that format, then the mask we just produced must adhere to it as well,\n * and if it doesn't, zero the mask, ensuring that the test will return false.\n */\n if ((bitsMessage & 0xf0000000) && (bitsMessage & 0x0fffffff)) {\n if (!(bitsEnabled & 0xf0000000) || !(bitsEnabled & 0x0fffffff)) bitsEnabled = 0;\n }\n if (bitsMessage && bitsEnabled === bitsMessage) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * printf(format, ...args)\n *\n * @this {Component}\n * @param {string} format\n * @param {...} args\n */\n printf(format, ...args)\n {\n if (DEBUGGER && this.dbg) {\n if (this.messageEnabled()) {\n let s = Str.sprintf(format, ...args);\n /*\n * Since dbg.message() calls println(), we strip any ending linefeed.\n * \n * We could bypass the Debugger and go straight to this.print(), but we would lose\n * the benefits of debugger messages (eg, automatic buffering, halting, yielding, etc).\n */\n if (s.slice(-1) == '\\n') s = s.slice(0, -1);\n this.dbg.message(s);\n }\n }\n }\n\n /**\n * printMessage(sMessage, bitsMessage, fAddress)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n * If bitsMessage is true, the message is displayed regardless.\n *\n * @this {Component}\n * @param {string} sMessage is any caller-defined message string\n * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n * @param {boolean} [fAddress] is true to display the current address\n */\n printMessage(sMessage, bitsMessage, fAddress)\n {\n if (DEBUGGER && this.dbg) {\n if (bitsMessage === true || this.messageEnabled(bitsMessage | 0)) {\n this.dbg.message(sMessage, fAddress);\n }\n }\n }\n\n /**\n * printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n * If bitsMessage is true, the message is displayed as long as MESSAGE.PORT is enabled.\n *\n * @this {Component}\n * @param {number} port\n * @param {number|null|*} bOut if an output operation\n * @param {number|null|*} [addrFrom]\n * @param {string|null|*} [name] of the port, if any\n * @param {number|null|*} [bIn] is the input value, if known, on an input operation\n * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n */\n printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage)\n {\n if (DEBUGGER && this.dbg) {\n if (bitsMessage === true) {\n bitsMessage = 0;\n } else if (bitsMessage == null) {\n bitsMessage = this.bitsMessage;\n }\n this.dbg.messageIO(this, port, bOut, addrFrom, name, bIn, bitsMessage);\n }\n }\n}\n\n/*\n * Types recognized and supported by selected functions (eg, Computer.getMachineParm())\n */\nComponent.TYPE = {\n NUMBER: \"number\",\n OBJECT: \"object\",\n STRING: \"string\"\n};\n\n/*\n * These are the standard PRINT values you can pass as an optional argument to println(); in reality,\n * you can pass anything you want, because they are simply prepended to the message, although PROGRESS\n * messages may also be merged with earlier similar messages to keep the output buffer under control.\n */\nComponent.PRINT = {\n ERROR: \"error\",\n NOTICE: \"notice\",\n PROGRESS: \"progress\",\n SCRIPT: \"script\",\n WARNING: \"warning\"\n};\n\n/*\n * Every component created on the current page is recorded in this array (see Component.add()),\n * enabling any component to locate another component by ID (see Component.getComponentByID())\n * or by type (see Component.getComponentByType()).\n *\n * Every machine on the page are now recorded as well, by their machine ID. We then record the\n * various resources used by that machine.\n *\n * Includes a fallback for non-browser-based environments (ie, Node). TODO: This will need to be\n * tailored to Node, probably using the global object instead of the window object, if we ever want\n * to support multi-machine configs in that environment.\n */\nif (window) {\n if (!window['PCjs']) window['PCjs'] = {};\n if (!window['PCjs']['Machines']) window['PCjs']['Machines'] = {};\n if (!window['PCjs']['Components']) window['PCjs']['Components'] = [];\n if (!window['PCjs']['Commands']) window['PCjs']['Commands'] = {};\n}\nComponent.machines = window? window['PCjs']['Machines'] : {};\nComponent.components = window? window['PCjs']['Components'] : [];\nComponent.commands = window? window['PCjs']['Commands'] : {};\n\nComponent.asyncCommands = [\n 'hold', 'sleep', 'wait'\n];\nComponent.globalCommands = {\n 'alert': Component.scriptAlert,\n 'sleep': Component.scriptSleep\n};\nComponent.componentCommands = {\n 'select': Component.scriptSelect\n};\nComponent.printBuffer = \"\";\n\n/*\n * The following polyfills provide ES5 functionality that's missing in older browsers (eg, IE8),\n * allowing PCjs apps to run without slamming into exceptions; however, due to the lack of HTML5 canvas\n * support in those browsers, all you're likely to see are \"soft\" errors (eg, \"Missing <canvas> support\").\n *\n * Perhaps we can implement a text-only faux video display for a fun retro-browser experience someday.\n *\n * TODO: Come up with a better place to put these polyfills. We will likely have more if we decide to\n * make the leap from ES5 to ES6 features.\n */\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf\n */\nif (!Array.prototype.indexOf) {\n Array.prototype.indexOf = function(obj, start) {\n for (var i = (start || 0), j = this.length; i < j; i++) {\n if (this[i] === obj) { return i; }\n }\n return -1;\n }\n}\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray\n */\nif (!Array.isArray) {\n Array.isArray = function(arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n };\n}\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind\n */\nif (!Function.prototype.bind) {\n Function.prototype.bind = function(obj) {\n if (typeof this != \"function\") {\n // Closest thing possible to the ECMAScript 5 internal IsCallable function\n throw new TypeError(\"Function.prototype.bind: non-callable object\");\n }\n var args = Array.prototype.slice.call(arguments, 1);\n var fToBind = this;\n var fnNOP = /** @constructor */ (function() {});\n var fnBound = function() {\n return fToBind.apply(this instanceof fnNOP && obj? this : obj, args.concat(/** @type {Array} */(Array.prototype.slice.call(arguments))));\n };\n fnNOP.prototype = this.prototype;\n fnBound.prototype = new fnNOP();\n return fnBound;\n };\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/defines.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @define {string}\n */\nvar APPCLASS = \"pdp10\"; // this @define is the default application class (eg, \"pcx86\", \"c1pjs\")\n\n/**\n * APPNAME is used more for display purposes than anything else now. APPCLASS is what matters in terms\n * of folder and file names, CSS styles, etc.\n *\n * @define {string}\n */\nvar APPNAME = \"PDPjs\"; // this @define is the default application name (eg, \"PCx86\", \"C1Pjs\")\n\n/**\n * WARNING: DEBUGGER needs to accurately reflect whether or not the Debugger component is (or will be) loaded.\n * In the compiled case, we rely on the Closure Compiler to override DEBUGGER as appropriate. When it's *false*,\n * nearly all of debugger.js will be conditionally removed by the compiler, reducing it to little more than a\n * \"type skeleton\", which also solves some type-related warnings we would otherwise have if we tried to remove\n * debugger.js from the compilation process altogether.\n *\n * However, when we're in \"development mode\" and running uncompiled code in debugger-less configurations,\n * I would like to skip loading debugger.js altogether. When doing that, we must ALSO arrange for an additional file\n * (nodebugger.js) to be loaded immediately after this file, which *explicitly* overrides DEBUGGER with *false*.\n *\n * @define {boolean}\n */\nvar DEBUGGER = true; // this @define is overridden by the Closure Compiler to remove Debugger-related support\n\n/*\n * Set this to true to enable behavior compatible with SIMH.\n */\nvar SIMH = false;\n\n/*\n * Combine all the shared globals and machine-specific globals into one machine-specific global object,\n * which all machine components should start using; eg: \"if (PDP10.DEBUG) ...\" instead of \"if (DEBUG) ...\".\n */\nvar PDP10 = {\n APPCLASS: APPCLASS,\n APPNAME: APPNAME,\n APPVERSION: APPVERSION, // shared\n COMPILED: COMPILED, // shared\n CSSCLASS: CSSCLASS, // shared\n DEBUG: DEBUG, // shared\n DEBUGGER: DEBUGGER,\n MAXDEBUG: MAXDEBUG, // shared\n PRIVATE: PRIVATE, // shared\n SITEHOST: SITEHOST, // shared\n XMLVERSION: XMLVERSION, // shared\n\n /*\n * CPU model numbers (supported)\n */\n MODEL_KA10: 1001,\n\n /*\n * ADDR_INVALID is used to mark points in the code where the physical address being returned\n * is invalid and should not be used.\n *\n * In a 32-bit CPU, -1 (ie, 0xffffffff) could actually be a valid address, so consider changing\n * ADDR_INVALID to NaN or null (which is also why all ADDR_INVALID tests should use strict equality\n * operators).\n *\n * The main reason I'm NOT using NaN or null now is my concern that, by mixing non-numbers\n * (specifically, values outside the range of signed 32-bit integers), performance may suffer.\n *\n * WARNING: Like many of the properties defined here, ADDR_INVALID is a common constant, which the\n * Closure Compiler will happily inline (with or without @const annotations; in fact, I've yet to\n * see a @const annotation EVER improve automatic inlining). However, if you don't make ABSOLUTELY\n * certain that this file is included BEFORE the first reference to any of these properties, that\n * automatic inlining will no longer occur.\n */\n ADDR_INVALID: -1,\n ADDR_MASK: Math.pow(2, 18) - 1,\n ADDR_LIMIT: Math.pow(2, 18),\n\n /*\n * 18-bit and 36-bit largest positive (and smallest negative) values; however, since we store all\n * values as unsigned quantities, these are the unsigned equivalents.\n */\n WORD_INVALID: -1,\n HINT_MASK: Math.pow(2, 17) - 1, // 131,071 (377777) signed half-word (half-int) mask\n HINT_LIMIT: Math.pow(2, 17), // 131,072 (400000) signed half-word (half-int) limit\n HALF_MASK: Math.pow(2, 18) - 1, // 262,143 (000000 777777): unsigned half-word mask\n HALF_SHIFT: Math.pow(2, 18), // 262,144 (000001 000000): unsigned half-word shift\n INT_MASK: Math.pow(2, 35) - 1, // 34,359,738,367 (377777 777777): signed word (magnitude) mask\n INT_LIMIT: Math.pow(2, 35), // 34,359,738,368 (400000 000000): signed word (magnitude) limit\n WORD_MASK: Math.pow(2, 36) - 1, // 68,719,476,735 (777777 777777): unsigned word mask\n WORD_LIMIT: Math.pow(2, 36), // 68,719,476,736 (1 000000 000000): unsigned word limit\n\n TWO_POW32: Math.pow(2, 32),\n TWO_POW34: Math.pow(2, 34),\n TWO_POW36: Math.pow(2, 36), // the two's complement of a 36-bit value is (value? TWO_POW36 - value : 0)\n\n /*\n * PDP-10 opcodes are 36-bit values, most of which use the following layout:\n *\n * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3\n * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5\n * O O O O O O O M M A A A A I X X X X Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y\n *\n * or using modern bit-numbering:\n *\n * 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1\n * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0\n * O O O O O O O M M A A A A I X X X X Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y\n *\n * where OOOOOOOMM represents the operation, and MM (if used) represents the mode:\n *\n * Mode Suffix Source Destination\n * ---- ------ ----- -----------\n * 0: Basic None E AC\n * 1: Immediate I 0,E AC\n * 2: Memory M AC E\n * 3: Self/Both S or B E E (and AC if A is non-zero)\n *\n * Input-output instructions look like:\n *\n * 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1\n * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0\n * 1 1 1 D D D D D D D O O O I X X X X Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y\n *\n * Bits 0-22 (I,X,Y) contain what we call a \"reference address\" (R), which is used to calculate the\n * \"effective address\" (E). To determine E from R, we must extract I, X, and Y from R, set E to Y,\n * then add [X] to E if X is non-zero. If I is zero, then we're done; otherwise, we must set R to [E]\n * and repeat the process.\n */\n OPCODE: {\n OPMASK: 0o77700, // operation mask\n OPMODE: 0o77400, // operation with mode\n OPCOMP: 0o77000, // operation with compare\n OPTEST: 0o71100, // operation with test\n OPIO: 0o70034, // input-output operation\n OPUUO: 0o70000, // unimplemented user operation (UUO) mask\n OP_SCALE: Math.pow(2, 21), // operation scale\n IO_SCALE: Math.pow(2, 26), // input-output device code scale\n IO_MASK: 0o177, // input-output device code mask (after descale)\n A_SCALE: Math.pow(2, 23), // used to shift down the high 13 bits, with A starting at bit 0\n P_SCALE: Math.pow(2, 30), // P scale\n P_MASK: 0o77, // P mask (after descale)\n S_SHIFT: 24, // S shift\n S_MASK: 0o77, // S mask (after shift)\n A_SHIFT: 23, // A shift\n A_MASK: 0o17, // A mask (after shift)\n A_FIELD: 0o740000000, // A field mask\n I_FIELD: 0o20000000, // indirect bit mask\n X_SHIFT: 18, // X shift\n X_MASK: 0o17, // X mask (after shift)\n X_FIELD: 0o17000000, // X field mask\n Y_SHIFT: 0, // Y shift\n Y_MASK: 0o777777, // Y mask (after shift)\n Y_FIELD: 0o777777, // Y field mask\n R_MASK: 0o37777777, // used to isolate the low 23 bits (I,X,Y)\n PTR_MASK: 0o77777777, // used to isolate the low 24 bits (?,I,X,Y) of a byte pointer\n HALT: 0o5304 // operation code for HALT\n },\n\n /*\n * Internal operation state flags\n */\n OPFLAG: {\n IRQ_DELAY: 0x0001, // incremented until it becomes IRQ\n IRQ: 0x0002, // time to call checkInterrupts()\n IRQ_MASK: 0x0003,\n DEBUGGER: 0x0004, // set if the Debugger wants to perform checks\n WAIT: 0x0008, // WAIT operation in progress\n PRESERVE: 0x000F // OPFLAG bits to preserve prior to the next instruction\n },\n\n /*\n * Flags returned by getPS() for various program control operations.\n *\n * NOTE: I see SIMH setting PS bits like 0o000200 and 0o000400, which are not documented for the KA10.\n * The SIMH docs only refer to the KS10 (\"KS10 CPU with 1MW of memory\"), so I'm guessing it doesn't have\n * a KA10 emulation option. The `pdp10` SIMH binary does have some SET CPU options, but unlike the `pdp11`\n * binary, the only options you can set relate to the operating system to be run -- which seems very hacky.\n */\n PSFLAG: {\n AROV: 0o400000, // Arithmetic Overflow\n CRY0: 0o200000, // Carry 0\n CRY1: 0o100000, // Carry 1\n FOV: 0o040000, // Floating-Point Overflow\n BIS: 0o020000, // Byte Interrupt\n USERF: 0o010000, // User Mode Flag\n EXIOT: 0o004000, // User Privileged I/O Flag\n FXU: 0o000100, // Floating-Point Underflow\n DCK: 0o000040, // Divide Check (aka No Divide)\n /*\n * Only the low 18 bits (above) are returned by getPS(); the following (bits 18 to 31)\n * are defined for internal use only.\n */\n PDOV: 0o1000000, // Pushdown Overflow\n SET_MASK: 0o0760140 // flags that are always settable/clearable\n },\n\n /*\n * Readable CPU (or APR for \"Arithmetic Processor\") flags provided by the \"CONI APR,\" instruction; see opCONI().\n */\n RFLAG: {\n PIA: 0o000007, // Priority Interrupt Assignment\n AROV: 0o000010, // Arithmetic Overflow\n AROV_IE: 0o000020, // Arithmetic Overflow Interrupt Enabled\n TRAP_OFF: 0o000040, // Trap Offset\n FOV: 0o000100, // Floating-Point Overflow\n FOV_IE: 0o000200, // Floating-Point Overflow Interrupt Enabled\n CLK: 0o001000, // Clock Flag\n CLK_IE: 0o002000, // Clock Interrupt Enabled\n NXM: 0o010000, // Non-Existent Memory\n PRM: 0o020000, // Memory Protection\n ADB: 0o040000, // Address Break\n UIO: 0o100000, // User In-Out\n PDOV: 0o200000 // Pushdown Overflow (TODO: Verify this is correct; the May 1968 doc may have a typo)\n },\n\n /*\n * Writable CPU (or APR for \"Arithmetic Processor\") flags provided by the \"CONO APR,\" instruction; see opCONO().\n *\n * A set bit performs the function shown below, a clear bit does nothing.\n */\n WFLAG: {\n PIA: 0o000007, // Priority Interrupt Assignment\n AROV_CL: 0o000010, // Clear Overflow\n AROV_IE: 0o000020, // Enable Overflow Interrupt\n AROV_ID: 0o000040, // Disable Overflow Interrupt\n FOV_CL: 0o000100, // Clear Floating-Point Overflow\n FOV_IE: 0o000200, // Enable Floating-Point Overflow Interrupt\n FOV_ID: 0o000400, // Disable Floating-Point Overflow Interrupt\n CLK_CL: 0o001000, // Clear Clock Flag\n CLK_IE: 0o002000, // Enable Clock Interrupt\n CLK_ID: 0o004000, // Disable Clock Interrupt\n NXM_CL: 0o010000, // Clear Non-Existent Memory\n PRM_CL: 0o020000, // Clear Memory Protection\n ADB_CL: 0o040000, // Clear Address Break\n UIO_CL: 0o200000, // Clear All In-Out Devices\n PDOV_CL: 0o400000 // Clear Pushdown Overflow\n },\n\n /*\n * 7-bit device codes used by Input-Output instructions; see opIO().\n */\n DEVICES: {\n APR: 0o000, // Arithmetic Processor\n PI: 0o001 // Priority Interrupt\n }\n};\n\n/*\n * Combine all the shared globals and machine-specific globals into one machine-specific global object,\n * which all machine components should start using; eg: \"if (PDP10.DEBUGGER)\" instead of \"if (DEBUGGER)\".\n */\nPDP10.APPCLASS = APPCLASS;\nPDP10.APPNAME = APPNAME;\nPDP10.DEBUGGER = DEBUGGER;\nPDP10.SIMH = SIMH;\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/messages.js (C) Jeff Parsons 2012-2018\n */\n\nvar MessagesPDP10 = {\n CPU: 0x00000001,\n TRAP: 0x00000002,\n FAULT: 0x00000004,\n INT: 0x00000008,\n BUS: 0x00000010,\n MEMORY: 0x00000020,\n MMU: 0x00000040,\n ROM: 0x00000080,\n DEVICE: 0x00000100,\n PANEL: 0x00000200,\n KEYBOARD: 0x00000400,\n KEYS: 0x00000800,\n PAPER: 0x00001000,\n READ: 0x00004000,\n WRITE: 0x00008000,\n SERIAL: 0x00100000,\n TIMER: 0x00200000,\n SPEAKER: 0x01000000,\n COMPUTER: 0x02000000,\n LOG: 0x10000000,\n WARN: 0x20000000,\n BUFFER: 0x40000000,\n HALT: 0x80000000|0\n};\n\n/*\n * Message categories supported by the messageEnabled() function and other assorted message\n * functions. Each category has a corresponding bit value that can be combined (ie, OR'ed) as\n * needed. The Debugger's message command (\"m\") is used to turn message categories on and off,\n * like so:\n *\n * m port on\n * m port off\n * ...\n *\n * NOTE: The order of these categories can be rearranged, alphabetized, etc, as desired; just be\n * aware that changing the bit values could break saved Debugger states (not a huge concern, just\n * something to be aware of).\n */\nMessagesPDP10.CATEGORIES = {\n \"cpu\": MessagesPDP10.CPU,\n \"trap\": MessagesPDP10.TRAP,\n \"fault\": MessagesPDP10.FAULT,\n \"int\": MessagesPDP10.INT,\n \"bus\": MessagesPDP10.BUS,\n \"memory\": MessagesPDP10.MEMORY,\n \"mmu\": MessagesPDP10.MMU,\n \"rom\": MessagesPDP10.ROM,\n \"device\": MessagesPDP10.DEVICE,\n \"panel\": MessagesPDP10.PANEL,\n \"keyboard\": MessagesPDP10.KEYBOARD, // \"kbd\" is also allowed as shorthand for \"keyboard\"; see doMessages()\n \"key\": MessagesPDP10.KEYS, // using \"key\" instead of \"keys\", since the latter is a method on JavasScript objects\n \"paper\": MessagesPDP10.PAPER,\n \"read\": MessagesPDP10.READ,\n \"write\": MessagesPDP10.WRITE,\n \"serial\": MessagesPDP10.SERIAL,\n \"timer\": MessagesPDP10.TIMER,\n \"speaker\": MessagesPDP10.SPEAKER,\n \"computer\": MessagesPDP10.COMPUTER,\n \"log\": MessagesPDP10.LOG,\n \"warn\": MessagesPDP10.WARN,\n /*\n * Now we turn to message actions rather than message types; for example, setting \"halt\"\n * on or off doesn't enable \"halt\" messages, but rather halts the CPU on any message above.\n *\n * Similarly, \"m buffer on\" turns on message buffering, deferring the display of all messages\n * until \"m buffer off\" is issued.\n */\n \"buffer\": MessagesPDP10.BUFFER,\n \"halt\": MessagesPDP10.HALT\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/panel.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * Component class, because otherwise the Compiler won't allow us to *reference* the named\n * property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass PanelPDP10 extends Component {\n /**\n * PanelPDP10(parmsPanel)\n *\n * The PanelPDP10 component has no required (parmsPanel) properties.\n *\n * @param {Object} parmsPanel\n * @param {boolean} fBindings (true if panel may have bindings, otherwise not)\n */\n constructor(parmsPanel, fBindings)\n {\n super(\"Panel\", parmsPanel, MessagesPDP10.PANEL);\n\n /*\n * If there are any live registers, LEDs, etc, to display, this will provide a count.\n * TODO: Add some UI for fDisplayLiveRegs (either an XML property, or a UI checkbox, or both).\n */\n this.cLiveRegs = 0;\n this.nDisplayCount = 0;\n this.nDisplayLimit = 60;\n this.fDisplayLiveRegs = true;\n this.fBindings = fBindings;\n\n /*\n * regSwitches contains the Front Panel (aka Console) SWITCH register, which is also available\n * as a read-only register at 177570 (but only the low 16 bits). regDisplay contains the DISPLAY\n * register, a write-only register at the same address.\n *\n * regAddr is an internal register containing the contents of the Front Panel's ADDRESS display,\n * and regData corresponds to the DATA display. They are updated by updateAddr() and updateData(),\n * which in turn take care of calling updateLEDArray().\n *\n * The state of ALL switches is maintained in this.switches, and likewise all LED states are\n * maintained in this.leds, but for convenience, we also mirror some of those states in dedicated\n * variables (eg, regSwitches for the SWITCH register, fLEDTest for the 'TEST' switch, etc).\n */\n this.regDisplay = 0;\n this.regSwitches = 0;\n this.regAddr = this.regData = 0;\n this.ledAddr = this.ledData = -1;\n\n /*\n * The panel hardware has the following additional (supported) state; note that there are several\n * settings on a real Front Panel that we don't support (eg, stepping one cycle vs. one instruction).\n *\n * While my initial intent is to eventually support all the ADDRSEL switch settings, I probably\n * won't bother with any DATASEL switch settings; instead, I will automatically display the DISPLAY\n * register (regDisplay) [the equivalent of selecting 'DISPLAY REGISTER'] except when data is being\n * examined or deposited [the equivalent of selecting 'DATA PATHS'].\n */\n this.fLEDTest = false; // LED (lamp) test in progress\n this.fExamine = false; // true if the previously pressed switch was the 'EXAM' switch\n this.fDeposit = false; // true if the previously pressed switch was the 'DEP' switch\n this.nAddrSel = PanelPDP10.ADDRSEL.CONS_PHY;\n\n /*\n * Every LED has a simple numeric value, assigned when setBinding() is called:\n *\n * zero if \"off\", non-zero if \"on\"\n *\n * initBus() will call displayLEDs() to ensure that every LED is set to its initial value.\n */\n this.leds = {};\n\n /*\n * Every switch has an array associated with it:\n *\n * [0]: initial value of switch (0 if \"down\", 1 if \"up\")\n * [1]: current value of switch\n * [2]: true if the switch is momentary, false if not\n * [3]: true if the switch is currently pressed, false if released\n * [4]: optional handler to call whenever the switch is pressed or released\n * [5]: optional switch index (used with CNSW switches 'S0' through 'S21')\n *\n * initBus() will call displaySwitches() to ensure that every switch is the position represented below.\n *\n * NOTE: Not all switches have the same \"process\" criteria. For example, 'TEST' will perform a LED test\n * when it is momentarily pressed \"up\", whereas 'LOAD [ADRS]' will load the ADDRESS register from the\n * SWITCH register when it is momentarily pressed \"down\".\n *\n * This means that processLEDTest(value) must act when value == 1 (\"up\"), whereas processLoadAddr(value)\n * must act when value == 0 (\"down\"). You can infer all this from the table below, because the initial value\n * of any momentary switch is its \"inactive\" value, so the opposite is its \"active\" value.\n */\n this.switches = {\n 'START': [1, 1, true, false, this.processStart],\n 'STEP': [1, 1, false, false, this.processStep],\n 'ENABLE': [1, 1, false, false, this.processEnable],\n 'CONT': [1, 1, true, false, this.processContinue],\n 'DEP': [0, 0, true, false, this.processDeposit],\n 'EXAM': [1, 1, true, false, this.processExamine],\n 'LOAD': [1, 1, true, false, this.processLoadAddr],\n 'TEST': [0, 0, true, false, this.processLEDTest]\n };\n for (var i = 0; i < 22; i++) {\n this.switches['S'+i] = [0, 0, false, false, this.processSRSwitch, i];\n }\n\n /** @type {ComputerPDP10} */\n this.cmp = null;\n\n /** @type {BusPDP10} */\n this.bus = null;\n\n /** @type {CPUStatePDP10} */\n this.cpu = null;\n\n /** @type {DebuggerPDP10} */\n this.dbg = null;\n\n /*\n * The 'hold' and 'toggle' exports, which map to holdSwitch() and toggleSwitch(), both press and release\n * the specified switch, but processCommands() considers a 'hold' function to be asynchronous, which means\n * that holdSwitch() will be passed a callback function that can be used to implement a delay between the\n * press and the release, whereas toggleSwitch() will not.\n *\n * holdSwitch() only makes sense for momentary switches (eg, 'TEST'), where a visual delay might be nice.\n * If the switch isn't momentary, or no delay is desired, then use toggleSwitch(); it will be more efficient.\n *\n * Finally, for switches that are toggles (eg, 'ENABLE'), you can use setSwitch() to set it to a specific\n * state: zero for \"off\" and non-zero for \"on\". setSwitch() also supports meta-switches like \"SR\", using\n * the entire value to set a series of switches at once; the value is assumed to be octal unless overridden\n * by a prefix (eg, \"0x\") or suffix (eg, \".\").\n */\n this['exports'] = {\n 'hold': this.holdSwitch,\n 'toggle': this.toggleSwitch,\n 'reset': this.resetSwitches,\n 'set': this.setSwitch\n };\n\n this.setReady();\n }\n\n /**\n * getAR()\n *\n * @this {PanelPDP10}\n * @return {number} (current ADDRESS register)\n */\n getAR()\n {\n return this.regAddr;\n }\n\n /**\n * setAR(value)\n *\n * @this {PanelPDP10}\n * @param {number} value (new ADDRESS register)\n */\n setAR(value)\n {\n this.updateAddr(this.regAddr = value);\n }\n\n /**\n * getDR()\n *\n * @this {PanelPDP10}\n * @return {number} (current DISPLAY register)\n */\n getDR()\n {\n return this.regDisplay;\n }\n\n /**\n * setDR(value)\n *\n * @this {PanelPDP10}\n * @param {number} value (new DISPLAY register)\n * @return {number}\n */\n setDR(value)\n {\n return this.updateData(this.regDisplay = value);\n }\n\n /**\n * getSR()\n *\n * @this {PanelPDP10}\n * @return {number} (current SWITCH register)\n */\n getSR()\n {\n return this.regSwitches;\n }\n\n /**\n * setSR(value)\n *\n * @this {PanelPDP10}\n * @param {number} value (new SWITCH register)\n */\n setSR(value)\n {\n this.setSRSwitches(value);\n }\n\n /**\n * getSwitch(name)\n *\n * @this {PanelPDP10}\n * @param {string} name\n * @return {number|undefined} 0 if switch is off (\"down\"), 1 if on (\"up\"), or undefined if unrecognized\n */\n getSwitch(name)\n {\n return this.switches[name] && this.switches[name][1];\n }\n\n /**\n * reset(fPowerUp)\n *\n * NOTE: Since we've registered our handler with the Bus component, we will be called twice whenever\n * the entire machine is reset: once when the Computer's reset() handler calls the Bus's reset() handler,\n * and again when the Computer's reset() handler calls us directly. Multiple resets should be harmless.\n *\n * @this {PanelPDP10}\n * @param {boolean} [fPowerUp]\n */\n reset(fPowerUp)\n {\n /*\n * Simulate a call to our stop() handler, to update the panel's ADDRESS register with the current PC.\n */\n this.stop();\n if (fPowerUp) this.setDR(0);\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * Some panel layouts don't have bindings of their own, and even when they do, there may still be some\n * components (eg, the CPU) that prefer to update their own bindings, so we pass along all binding requests\n * to the Computer, CPU, Keyboard and Debugger components first. The order shouldn't matter, since any\n * component that doesn't recognize the specified binding should simply ignore it.\n *\n * @this {PanelPDP10}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n if (this.cmp && this.cmp.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (this.cpu && this.cpu.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (DEBUGGER && this.dbg && this.dbg.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n\n switch (sBinding) {\n case 'PC':\n this.bindings[sBinding] = control;\n this.cLiveRegs++;\n return true;\n\n default:\n /*\n * Square (\"led\") or round (\"rled\") LEDs are defined in machine XML files like so:\n *\n * <control type=\"rled\" binding=\"A3\" value=\"1\" width=\"100%\" container=\"center\"/>\n *\n * Only *type* and *binding* attributes are required; if *value* is omitted, the default value is 0 (\"off\").\n */\n if (sHTMLType == \"led\" || sHTMLType == \"rled\") {\n this.bindings[sBinding] = control;\n this.leds[sBinding] = sValue? 1 : 0;\n this.cLiveRegs++;\n return true;\n }\n /*\n * Switches are defined in machine XML files like so:\n *\n * <control type=\"switch\" binding=\"S3\" value=\"1\" width=\"100%\" container=\"center\"/>\n *\n * Only *type* and *binding* attributes are required; if *value* is omitted, the default value is 0 (\"down\").\n *\n * Currently, there is no XML attribute to indicate whether a switch is \"momentary\"; only recognized switches\n * in our internal table can have that attribute.\n */\n if (sHTMLType == \"switch\") {\n /*\n * Like LEDs, we allow unrecognized switches to be defined as well, but they won't do anything useful,\n * since only recognized switches will have handlers that perform the appropriate operations.\n */\n if (this.switches[sBinding] === undefined) {\n this.switches[sBinding] = [sValue? 1 : 0, sValue? 1 : 0];\n }\n this.bindings[sBinding] = control;\n var parent = control.parentElement || control;\n parent = parent.parentElement || parent;\n parent.onmousedown = function(panel, sBinding) {\n return function onPressSwitch() {\n panel.pressSwitch(sBinding);\n };\n }(this, sBinding);\n parent.onmouseup = parent.onmouseout = function(panel, sBinding) {\n return function onReleaseSwitch() {\n panel.releaseSwitch(sBinding);\n };\n }(this, sBinding);\n parent.ontouchstart = function(panel, sBinding) {\n return function onPressSwitch(event) {\n panel.pressSwitch(sBinding);\n event.preventDefault();\n };\n }(this, sBinding);\n parent.ontouchend = function(panel, sBinding) {\n return function onReleaseSwitch() {\n panel.releaseSwitch(sBinding);\n };\n }(this, sBinding);\n return true;\n }\n return super.setBinding(sHTMLType, sBinding, control, sValue);\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {PanelPDP10}\n * @param {ComputerPDP10} cmp\n * @param {BusPDP10} bus\n * @param {CPUStatePDP10} cpu\n * @param {DebuggerPDP10} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n this.displayLEDs();\n this.displaySwitches();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {PanelPDP10}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n /*\n * As noted in init(), our powerUp() method gives us a second opportunity to notify any\n * components that that might care (eg, CPU, Keyboard, and Debugger) that we have some controls\n * (ie, bindings) they might want to use.\n */\n if (this.fBindings) PanelPDP10.init();\n\n if (!data) {\n this.reset(true);\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {PanelPDP10}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * save()\n *\n * This implements save support for the PanelPDP10 component.\n *\n * @this {PanelPDP10}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, [\n this.getAR(),\n this.getDR(),\n this.getSR()\n ]);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the PanelPDP10 component.\n *\n * @this {PanelPDP10}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var a = data[0];\n if (a) {\n this.setAR(a[0]);\n this.setDR(a[1]);\n this.setSR(a[2]);\n }\n return true;\n }\n\n /**\n * resetSwitches()\n *\n * @this {PanelPDP10}\n * @return {boolean}\n */\n resetSwitches()\n {\n for (var sBinding in this.switches) {\n var sw = this.switches[sBinding];\n sw[1] = sw[0];\n }\n this.displaySwitches();\n return true;\n }\n\n /**\n * displayLED(sBinding, value)\n *\n * @this {PanelPDP10}\n * @param {string} sBinding\n * @param {boolean|number} value (true or non-zero if the LED should be on, false or zero if off)\n */\n displayLED(sBinding, value)\n {\n var control = this.bindings[sBinding];\n if (control) {\n /*\n * TODO: Add support for user-definable LED colors?\n */\n control.style.backgroundColor = (value? \"#ff0000\" : \"#000000\");\n }\n }\n\n /**\n * displayLEDs(override)\n *\n * @this {PanelPDP10}\n * @param {boolean|number|null} [override] (true turn on all LEDs, false to turn off all LEDs, null or undefined for normal LED activity)\n */\n displayLEDs(override)\n {\n for (var sBinding in this.leds) {\n this.displayLED(sBinding, override != null? override : this.leds[sBinding]);\n }\n }\n\n /**\n * displaySwitch(sBinding, value)\n *\n * @this {PanelPDP10}\n * @param {string} sBinding\n * @param {boolean|number} value (true if the switch should be \"up\" (on), false if \"down\" (off))\n */\n displaySwitch(sBinding, value)\n {\n var control = this.bindings[sBinding];\n if (control) {\n control.style.marginTop = (value? \"0px\" : \"20px\");\n control.style.backgroundColor = (value? \"#00ff00\" : \"#228B22\");\n }\n }\n\n /**\n * displaySwitches()\n *\n * @this {PanelPDP10}\n */\n displaySwitches()\n {\n for (var sBinding in this.switches) {\n this.displaySwitch(sBinding, this.switches[sBinding][1]);\n }\n }\n\n /**\n * displayValue(sLabel, nValue, cch)\n *\n * This is principally for displaying register values, but in reality, it can be used to display any\n * numeric value bound to the given label.\n *\n * @this {PanelPDP10}\n * @param {string} sLabel\n * @param {number} nValue\n * @param {number} [cch]\n */\n displayValue(sLabel, nValue, cch)\n {\n if (this.bindings[sLabel]) {\n var sVal;\n var nBase = this.dbg && this.dbg.nBase || 8;\n nValue = nValue || 0;\n if (!this.cpu.isRunning() || this.fDisplayLiveRegs) {\n sVal = nBase == 8? Str.toOct(nValue, cch) : Str.toHex(nValue, cch);\n } else {\n sVal = \"--------\".substr(0, cch || 4);\n }\n /*\n * TODO: Determine if this test actually avoids any redrawing when a register hasn't changed, and/or if\n * we should maintain our own (numeric) cache of displayed register values (to avoid creating these temporary\n * string values that will have to garbage-collected), and/or if this is actually slower, and/or if I'm being\n * too obsessive.\n */\n if (this.bindings[sLabel].textContent != sVal) this.bindings[sLabel].textContent = sVal;\n }\n }\n\n /**\n * holdSwitch(fnCallback, sBinding, sDelay)\n *\n * @this {PanelPDP10}\n * @param {function()|null} fnCallback\n * @param {string} sBinding\n * @param {string} [sDelay]\n * @return {boolean} false if wait required, true otherwise\n */\n holdSwitch(fnCallback, sBinding, sDelay)\n {\n if (this.pressSwitch(sBinding)) {\n if (sDelay) {\n var panel = this;\n setTimeout(function() {\n panel.releaseSwitch(sBinding);\n if (fnCallback) fnCallback();\n }, +sDelay);\n return false;\n } else {\n this.releaseSwitch(sBinding);\n }\n }\n return true;\n }\n\n /**\n * setSwitch(sBinding, sValue)\n *\n * @this {PanelPDP10}\n * @param {string} sBinding\n * @param {string} sValue\n * @return {boolean}\n */\n setSwitch(sBinding, sValue)\n {\n if (sBinding == \"SR\") {\n return this.setSRSwitches(Str.parseInt(sValue, 8))\n }\n var sw = this.switches[sBinding];\n if (sw) {\n sw[1] = +sValue? 1 : 0;\n this.displaySwitch(sBinding, sw[1]);\n return true;\n }\n return false;\n }\n\n /**\n * toggleSwitch(sBinding)\n *\n * @this {PanelPDP10}\n * @param {string} sBinding\n * @return {boolean}\n */\n toggleSwitch(sBinding)\n {\n if (this.pressSwitch(sBinding)) {\n this.releaseSwitch(sBinding);\n return true;\n }\n return false;\n }\n\n /**\n * pressSwitch(sBinding)\n *\n * @this {PanelPDP10}\n * @param {string} sBinding\n * @return {boolean}\n */\n pressSwitch(sBinding)\n {\n var sw = this.switches[sBinding];\n if (sw) {\n /*\n * Set the new switch value in sw[1] and then immediately display it\n */\n this.displaySwitch(sBinding, (sw[1] = 1 - sw[1]));\n\n /*\n * Mark the switch as \"pressed\"\n */\n sw[3] = true;\n\n /*\n * Call the appropriate process handler with the current switch value (sw[1])\n */\n if (sw[4]) sw[4].call(this, sw[1], sw[5]);\n\n /*\n * This helps the next 'DEP' or 'EXAM' press determine if the previous press was the same,\n * while also ignoring any intervening 'STEP' presses (see processStep() for why we do that).\n */\n if (sBinding != PanelPDP10.SWITCH.STEP) {\n this.fDeposit = (sBinding == PanelPDP10.SWITCH.DEP);\n this.fExamine = (sBinding == PanelPDP10.SWITCH.EXAM);\n }\n return true;\n }\n return false;\n }\n\n /**\n * releaseSwitch(sBinding)\n *\n * @this {PanelPDP10}\n * @param {string} sBinding\n * @return {boolean}\n */\n releaseSwitch(sBinding)\n {\n /*\n * pressSwitch() is simple: flip the switch's current value in sw[1] and marked it \"pressed\" in sw[3].\n *\n * releaseSwitch() is more complicated, because we must handle both mouseUp and mouseOut events. The first time\n * we receive EITHER of those events AND the switch is marked momentary (sw[2]) AND the switch is pressed (sw[3]),\n * then we must flip the switch back to its original value.\n *\n * Otherwise, the only thing we have to do is mark the switch as \"released\" (ie, set sw[3] to false).\n */\n var sw = this.switches[sBinding];\n if (sw) {\n if (sw[2] && sw[3]) {\n /*\n * Set the new switch value in sw[1] and then immediately display it\n */\n this.displaySwitch(sBinding, (sw[1] = sw[0]));\n\n /*\n * Call the appropriate process handler with the current switch value (sw[1])\n */\n if (sw[4]) sw[4].call(this, sw[1], sw[5]);\n }\n /*\n * Mark the switch as \"released\"\n */\n sw[3] = false;\n return true;\n }\n return false;\n }\n\n /**\n * processStart(value, index)\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @param {number} [index]\n */\n processStart(value, index)\n {\n if (!value && !this.cpu.isRunning()) {\n\n this.cpu.setPC(this.regAddr);\n\n /*\n * The PDP-11/70 Handbook goes on to say: \"If the system needs to be initialized but execution\n * is not wanted, the START switch should be depressed while the HALT/ENABLE switch is in the HALT\n * position.\"\n */\n if (this.getSwitch(PanelPDP10.SWITCH.ENABLE)) {\n this.cpu.startCPU();\n }\n }\n }\n\n /**\n * processStep(value, index)\n *\n * If value == 1 (our initial value), then the 'STEP' switch is set to \"S INST\" (step one instruction);\n * otherwise, it's set to \"S BUS CYCLE\" (step one bus cycle).\n *\n * However, since we can't currently support cycle-stepping, I've decided to innovate a little and\n * change the meaning of this switch: the normal (\"up\") position means that successive 'EXAM' and 'DEP'\n * operations will first add 2 to the ADDRESS register, while the opposite (\"down\") position means\n * they will first subtract 2.\n *\n * See processLEDTest() for more of these exciting \"innovations\". ;-)\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @param {number} [index]\n */\n processStep(value, index)\n {\n /*\n * There's really nothing for us to do here, because the normal press and release handlers\n * already record the state of this switch, so it can be queried as needed, using getSwitch().\n */\n }\n\n /**\n * processEnable(value, index)\n *\n * If value == 1 (our initial value), then the 'ENABLE'/'HALT' switch is set to 'ENABLE', otherwise 'HALT'.\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @param {number} [index]\n */\n processEnable(value, index)\n {\n /*\n * The \"down\" (0) position is 'HALT', which stops the CPU; however, the \"up\" (1) position ('ENABLE')\n * does NOT start the CPU. You must press 'CONT' to continue execution, which will either continue for\n * one instruction if this switch to set to 'HALT' or indefinitely if it is set to 'ENABLE'.\n */\n if (!value) {\n this.cpu.stopCPU();\n }\n }\n\n /**\n * processContinue(value, index)\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @param {number} [index]\n */\n processContinue(value, index)\n {\n if (!value && !this.cpu.isRunning()) {\n /*\n * TODO: Technically, we're also supposed to check the 'STEP' switch to determine if we should\n * step one instruction or just one cycle, but we don't currently have the ability to do the latter.\n */\n if (!this.getSwitch(PanelPDP10.SWITCH.ENABLE)) {\n /*\n * Using the Debugger's stepCPU() function is more convenient, and has the pleasant side-effect\n * of updating the debugger's display; however, not all machines with a Front Panel will necessarily\n * also have the Debugger loaded.\n */\n var dbg = this.dbg;\n if (dbg && !dbg.isBusy(true)) {\n dbg.setBusy(true);\n dbg.stepCPU(0, null);\n dbg.setBusy(false);\n }\n else {\n /*\n * For this tiny single-instruction burst, mimic what runCPU() does.\n */\n try {\n var nCyclesStep = this.cpu.stepCPU(1);\n if (nCyclesStep > 0) {\n this.cpu.updateTimers(nCyclesStep);\n this.cpu.addCycles(nCyclesStep, true);\n this.cpu.updateChecksum(nCyclesStep);\n }\n }\n catch(exception) {\n /*\n * We assume that any numeric exception was explicitly thrown by the CPU to interrupt the\n * current instruction. For all other exceptions, we attempt a stack dump.\n */\n if (typeof exception != \"number\") {\n var e = exception;\n this.cpu.setError(e.stack || e.message);\n }\n }\n }\n\n /*\n * Simulate a call to our stop() handler, to update the panel's ADDRESS register with the new PC.\n */\n this.stop();\n\n /*\n * Going through the normal channels (ie, the Computer's updateDisplays() interface) ensures that\n * ALL updateDisplay() handlers will be called, including ours.\n *\n * NOTE: If we used the Debugger's stepCPU() function, then that includes a call to updateDisplay();\n * unfortunately, it will have happened BEFORE we called stop() to update the ADDRESS register, so\n * we still need to call it again.\n */\n if (this.cmp) this.cmp.updateDisplays();\n }\n else {\n this.cpu.startCPU();\n }\n }\n }\n\n /**\n * processDeposit(value, index)\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @param {number} [index]\n */\n processDeposit(value, index)\n {\n if (value && !this.cpu.isRunning()) {\n if (this.fDeposit) this.advanceAddr();\n /*\n * This used to be updateData(), but that only updates regData, whereas setDR() updates both regData and regDisplay,\n * and for these kinds of explicit Front Panel operations, I'm assuming the values should be synced.\n */\n var w = this.setDR(this.regSwitches);\n\n if (this.nAddrSel == PanelPDP10.ADDRSEL.CONS_PHY) {\n /*\n * TODO: Determine if this needs to take the UNIBUS map into consideration.\n */\n this.bus.setWordDirect(this.regAddr, w);\n } else {\n /*\n * TODO: This code is obviously incomplete, since it doesn't take into account the precise ADDRSEL mode.\n */\n this.cpu.writeWord(this.regAddr, w);\n }\n }\n }\n\n /**\n * processExamine(value, index)\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @param {number} [index]\n */\n processExamine(value, index)\n {\n if (!value && !this.cpu.isRunning()) {\n var w;\n if (this.fExamine) this.advanceAddr();\n if (this.nAddrSel == PanelPDP10.ADDRSEL.CONS_PHY) {\n /*\n * TODO: Determine if this needs to take the UNIBUS map into consideration.\n */\n w = this.bus.getWordDirect(this.regAddr);\n } else {\n /*\n * TODO: This code is obviously incomplete, since it doesn't take into account the precise ADDRSEL mode.\n */\n w = this.cpu.readWord(this.regAddr);\n }\n /*\n * This used to be updateData(), but that only updates regData, whereas setDR() updates both regData and regDisplay,\n * and for these kinds of explicit Front Panel operations, I'm assuming the values should be synced.\n */\n this.setDR(w);\n }\n }\n\n /**\n * processLoadAddr(value, index)\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @param {number} [index]\n */\n processLoadAddr(value, index)\n {\n if (!value && !this.cpu.isRunning()) {\n this.updateAddr(this.regSwitches);\n }\n }\n\n /**\n * processLEDTest(value, index)\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @param {number} [index]\n */\n processLEDTest(value, index)\n {\n if (value) {\n this.fLEDTest = true;\n this.displayLEDs(true);\n } else {\n this.fLEDTest = false;\n this.displayLEDs();\n /*\n * This is another one of my \"innovations\": when you're done testing the LEDs, all the switches reset as well.\n */\n this.setSRSwitches(0);\n }\n }\n\n /**\n * processSRSwitch(value, index)\n *\n * @this {PanelPDP10}\n * @param {number} value (normally 0 or 1, but we only depend on it being zero or non-zero)\n * @param {number} index\n */\n processSRSwitch(value, index)\n {\n if (value) {\n this.regSwitches |= 1 << index;\n } else {\n this.regSwitches &= ~(1 << index);\n }\n }\n\n /**\n * advanceAddr()\n *\n * This should also take care of the following Front Panel behaviors when the accessing the general-purpose\n * registers:\n *\n * 1) ADDRESS display incremented by 1 (instead of 2)\n * 2) The STEP after the last register is 177700, such that the addresses are looped\n *\n * A third behavior is NOT emulated: preventing the ADDRESS from stepping to the first General Register (177700)\n * from 177676.\n *\n * @this {PanelPDP10}\n * @return {number}\n */\n advanceAddr()\n {\n var inc = 1;\n var mask = this.bus.nBusMask;\n if (!this.getSwitch(PanelPDP10.SWITCH.STEP)) inc = -inc;\n return this.updateAddr((this.regAddr & ~mask) | ((this.regAddr + inc) & mask));\n }\n\n /**\n * updateAddr(value)\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @return {number}\n */\n updateAddr(value)\n {\n this.regAddr = value & this.bus.nBusMask;\n if (this.ledAddr !== this.regAddr) {\n this.ledAddr = this.regAddr;\n this.updateLEDArray(\"A\", this.ledAddr, 22);\n }\n return this.regAddr;\n }\n\n /**\n * updateData(value)\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @return {number}\n */\n updateData(value)\n {\n this.regData = value % PDP10.WORD_LIMIT;\n if (this.ledData !== this.regData) {\n this.ledData = this.regData;\n this.updateLEDArray(\"D\", this.ledData, 16);\n }\n return this.regData;\n }\n\n /**\n * updateLED(sBinding, value)\n *\n * @this {PanelPDP10}\n * @param {string} sBinding\n * @param {number} value\n * @return {number}\n */\n updateLED(sBinding, value)\n {\n this.leds[sBinding] = value;\n if (!this.fLEDTest) this.displayLED(sBinding, value);\n return value;\n }\n\n /**\n * updateLEDArray(sPrefix, value, nLEDs)\n *\n * @this {PanelPDP10}\n * @param {string} sPrefix\n * @param {number} value\n * @param {number} nLEDs\n */\n updateLEDArray(sPrefix, value, nLEDs)\n {\n for (var i = 0; i < nLEDs; i++) {\n var sBinding = sPrefix + i;\n this.updateLED(sBinding, value & (1 << i));\n }\n }\n\n /**\n * setSRSwitches(value)\n *\n * @this {PanelPDP10}\n * @param {number|undefined} value\n * @return {boolean}\n */\n setSRSwitches(value)\n {\n this.regSwitches = value | 0;\n for (var i = 0; i < 22; i++) {\n this.switches['S'+i][1] = (this.regSwitches & (1 << i))? 1 : 0;\n }\n /*\n * This (re)displays ALL switches, not merely the SR switches, but that's OK.\n */\n this.displaySwitches();\n return true;\n }\n\n /**\n * stop(ms, nCycles)\n *\n * This is a notification handler, called by the Computer, to inform us the CPU has now stopped.\n *\n * @this {PanelPDP10}\n * @param {number} [ms]\n * @param {number} [nCycles]\n */\n stop(ms, nCycles)\n {\n this.updateAddr(this.cpu.getPC());\n }\n\n /**\n * setAddr(value, fActive)\n *\n * This interface is for passing new addresses to the Front Panel. However, whether or not this will become the\n * ADDRESS actually displayed will depend on other settings (see updateStatus() for details).\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @param {boolean} [fActive] (true if this should become the \"active\" ADDRESS regardless of other settings)\n */\n setAddr(value, fActive)\n {\n this.regAddr = value;\n }\n\n /**\n * setData(value, fActive)\n *\n * This interface is for passing new data to the Front Panel. However, whether or not this will become the\n * DATA actually displayed will depend on the Front Panel's DATASEL switch setting, as well as the fActive flag.\n *\n * @this {PanelPDP10}\n * @param {number} value\n * @param {boolean} [fActive] (true if this should become the \"active\" DATA regardless of the DATASEL switch setting)\n */\n setData(value, fActive)\n {\n if (!fActive) {\n this.regData = value;\n } else {\n this.regDisplay = value;\n }\n }\n\n /**\n * updateDisplay(nUpdate)\n *\n * Called by the Computer component at intervals to update registers, LEDs, etc.\n *\n * @this {PanelPDP10}\n * @param {number} [nUpdate] (-2 for power on, -1 for forced, > 0 for periodic, 0 or undefined otherwise)\n */\n updateDisplay(nUpdate)\n {\n if (this.cLiveRegs) {\n\n var fRunning = this.cpu.isRunning();\n var fWaiting = this.cpu.isWaiting();\n\n if (nUpdate < 0 || !fRunning || this.fDisplayLiveRegs) {\n\n /*\n * We arbitrarily separate the display elements into two categories: cheap and expensive.\n *\n * LEDs are considered cheap, register displays are not. So we'll skip the latter if this\n * is a periodic update AND our periodic update counter hasn't reached the periodic update limit.\n */\n if (nUpdate <= 0 || (this.nDisplayCount += nUpdate) >= this.nDisplayLimit) {\n this.displayValue(\"PC\", this.cpu.getPC());\n this.nDisplayCount = 0;\n }\n\n /*\n * Update the ADDRESS and DATA LEDs by selecting the appropriate values.\n *\n * TODO: There is currently no mechanism for selecting regData over regDisplay;\n * we are acting as if the DATASEL switch setting is locked to \"DISPLAY REGISTER\".\n */\n if (nUpdate < -1) {\n this.regAddr = this.cpu.getPC();\n } else if (nUpdate > 0 && fRunning && !fWaiting) {\n this.regAddr = this.cpu.getLastAddr();\n }\n\n this.updateAddr(this.regAddr);\n this.updateData(this.regDisplay);\n }\n }\n }\n\n /**\n * PanelPDP10.init()\n *\n * This function operates on every HTML element of class \"panel\", extracting the\n * JSON-encoded parameters for the PanelPDP10 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a PanelPDP10 component, and then binding\n * any associated HTML controls to the new component.\n *\n * NOTE: Unlike most other component init() functions, this one is designed to be\n * called multiple times: once at load time, so that we can bind our print()\n * function to the panel's output control ASAP, and again when the Computer component\n * is verifying that all components are ready and invoking their powerUp() functions.\n *\n * Our powerUp() method gives us a second opportunity to notify any components that\n * that might care (eg, CPU, Keyboard, and Debugger) that we have some controls they\n * might want to use.\n */\n static init()\n {\n var aePanels = Component.getElementsByClass(document, PDP10.APPCLASS, \"panel\");\n for (var iPanel=0; iPanel < aePanels.length; iPanel++) {\n var ePanel = aePanels[iPanel];\n var parmsPanel = Component.getComponentParms(ePanel);\n var panel = Component.getComponentByID(parmsPanel['id']);\n if (!panel) panel = new PanelPDP10(parmsPanel, true);\n Component.bindComponentControls(panel, ePanel, PDP10.APPCLASS);\n }\n }\n}\n\nPanelPDP10.ADDRSEL = {\n CONS_PHY: 7 // use a physical address to perform console operations (e.g., LOAD ADRS, EXAM, & DEP)\n};\n\n/*\n * To get the current state of a switch; eg::\n *\n * this.getSwitch(PanelPDP10.SWITCH.ENABLE)\n *\n * I haven't filled out this table, primarily it only needs to list switches we actually query\n * (eg, non-momentary ones like 'ENABLE' and 'STEP', and 'EXAM' and 'DEP' since they have special\n * \"step\" behavior when pressed more than once in a row). Ditto for the LED table.\n */\nPanelPDP10.SWITCH = {\n DEP: 'DEP',\n ENABLE: 'ENABLE',\n EXAM: 'EXAM',\n STEP: 'STEP'\n};\n\n/*\n * Initialize every Panel module on the page.\n */\nWeb.onInit(PanelPDP10.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/bus.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * Data types used by scanMemory()\n */\n\n/**\n * This defines the BlockInfo bit fields used by scanMemory() when it creates the aBlocks array.\n *\n * @typedef {{\n * num: BitField,\n * count: BitField,\n * btmod: BitField,\n * type: BitField\n * }}\n */\nvar BlockInfoPDP10 = Usr.defineBitFields({num:20, count:8, btmod:1, type:3});\n\n/**\n * BusInfoPDP10 object definition (returned by scanMemory())\n *\n * cbTotal: total bytes allocated\n * cBlocks: total Memory blocks allocated\n * aBlocks: array of allocated Memory block numbers\n *\n * @typedef {{\n * cbTotal: number,\n * cBlocks: number,\n * aBlocks: Array.<BlockInfoPDP10>\n * }}\n */\nvar BusInfoPDP10;\n\nclass BusPDP10 extends Component {\n /**\n * BusPDP10(parmsBus, cpu, dbg)\n *\n * The BusPDP10 component manages physical memory and I/O address spaces.\n *\n * The BusPDP10 component has no UI elements, so it does not require an init() handler,\n * but it still inherits from the Component class and must be allocated like any\n * other device component. It's currently allocated by the Computer's init() handler,\n * which then calls the initBus() method of all the other components.\n *\n * For memory beyond the simple needs of the ROM and RAM components (ie, memory-mapped\n * devices), the address space must still be allocated through the BusPDP10 component via\n * addMemory(). If the component needs something more than simple read/write storage,\n * it must provide a custom controller.\n *\n * @param {Object} parmsBus\n * @param {CPUStatePDP10} cpu\n * @param {DebuggerPDP10} dbg\n */\n constructor(parmsBus, cpu, dbg)\n {\n super(\"Bus\", parmsBus, MessagesPDP10.BUS);\n\n this.cpu = cpu;\n this.dbg = dbg;\n\n /*\n * Supported values for nBusWidth: 18 (default). This represents the maximum size of the bus for the\n * life of the machine, regardless what memory management mode the CPU has enabled.\n */\n this.nBusWidth = +parmsBus['busWidth'] || 18;\n\n /*\n * Compute all BusPDP10 memory block parameters now, based on the width of the bus.\n *\n * Note that all PCjs machines divide their address space into blocks, using a block size appropriate for\n * the machine's bus width. This allows us to efficiently allocate the entire address space, by reusing blocks\n * as appropriate, and to define to different address behaviors on a block-granular level.\n */\n this.addrTotal = 1 << this.nBusWidth;\n this.nBusMask = (this.addrTotal - 1);\n this.nBlockSize = 16384;\n this.nBlockShift = Math.log2(this.nBlockSize); // ES6 ALERT (alternatively: Math.log(this.nBlockSize) / Math.LN2)\n this.nBlockLen = this.nBlockSize >> 2;\n this.nBlockLimit = this.nBlockSize - 1;\n this.nBlockTotal = (this.addrTotal / this.nBlockSize) | 0;\n this.nBlockMask = this.nBlockTotal - 1;\n\n\n this.nDisableFaults = 0;\n this.fFault = false;\n\n /*\n * Define all the properties to be initialized by initMemory()\n */\n this.aBusBlocks = [];\n\n /*\n * We're ready to allocate empty Memory blocks to span the entire physical address space.\n */\n this.initMemory();\n\n this.setReady();\n }\n\n /**\n * initMemory()\n *\n * Allocate enough (empty) Memory blocks to span the entire physical address space.\n *\n * @this {BusPDP10}\n */\n initMemory()\n {\n var block = new MemoryPDP10(this);\n block.copyBreakpoints(this.dbg);\n\n this.aBusBlocks = new Array(this.nBlockTotal);\n for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {\n this.aBusBlocks[iBlock] = block;\n }\n }\n\n /**\n * reset()\n *\n * @this {BusPDP10}\n */\n reset()\n {\n }\n\n /**\n * getWidth()\n *\n * @this {BusPDP10}\n * @return {number}\n */\n getWidth()\n {\n return this.nBusWidth;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {BusPDP10}\n * @param {Object|null} data (always null because we supply no powerDown() handler)\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {BusPDP10}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * save()\n *\n * @this {BusPDP10}\n * @return {Object|null}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveMemory());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * @this {BusPDP10}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n return this.restoreMemory(data[0]);\n }\n\n /**\n * addMemory(addr, size, type)\n *\n * Adds new Memory blocks to the specified address range. Any Memory blocks previously\n * added to that range must first be removed via removeMemory(); otherwise, you'll get\n * an allocation conflict error. This helps prevent address calculation errors, redundant\n * allocations, etc.\n *\n * We've relaxed some of the original requirements (ie, that addresses must start at a\n * block-granular address, or that sizes must be equal to exactly one or more blocks),\n * because machines with large block sizes can make it impossible to load certain ROMs at\n * their required addresses. Every allocation still allocates a whole number of blocks.\n *\n * Even so, BusPDP10 memory management does NOT provide a general-purpose heap. Most memory\n * allocations occur during machine initialization and never change. In particular, there\n * is NO support for removing partial-block allocations.\n *\n * Each Memory block keeps track of a start address (addr) and length (used), indicating\n * the used space within the block; any free space that precedes or follows that used space\n * can be allocated later, by simply extending the beginning or ending of the previously used\n * space. However, any holes that might have existed between the original allocation and an\n * extension are subsumed by the extension.\n *\n * @this {BusPDP10}\n * @param {number} addr is the starting physical address of the request\n * @param {number} size of the request, in bytes\n * @param {number} type is one of the MemoryPDP10.TYPE constants\n * @return {boolean} true if successful, false if not\n */\n addMemory(addr, size, type)\n {\n var addrNext = addr;\n var sizeLeft = size;\n var iBlock = addrNext >>> this.nBlockShift;\n\n while (sizeLeft > 0 && iBlock < this.aBusBlocks.length) {\n\n var block = this.aBusBlocks[iBlock];\n var addrBlock = iBlock * this.nBlockSize;\n var sizeBlock = this.nBlockSize - (addrNext - addrBlock);\n if (sizeBlock > sizeLeft) sizeBlock = sizeLeft;\n\n if (block && block.size) {\n if (block.type == type) {\n /*\n * Where there is already a similar block with a non-zero size, we allow the allocation only if:\n *\n * 1) addrNext + sizeLeft <= block.addr (the request precedes the used portion of the current block), or\n * 2) addrNext >= block.addr + block.used (the request follows the used portion of the current block)\n */\n if (addrNext + sizeLeft <= block.addr) {\n block.used += (block.addr - addrNext);\n block.addr = addrNext;\n return true;\n }\n if (addrNext >= block.addr + block.used) {\n var sizeAvail = block.size - (addrNext - addrBlock);\n if (sizeAvail > sizeLeft) sizeAvail = sizeLeft;\n block.used = addrNext - block.addr + sizeAvail;\n addrNext = addrBlock + this.nBlockSize;\n sizeLeft -= sizeAvail;\n iBlock++;\n continue;\n }\n }\n return this.reportError(BusPDP10.ERROR.RANGE_INUSE, addrNext, sizeLeft);\n }\n\n var blockNew = new MemoryPDP10(this, addrNext, sizeBlock, this.nBlockSize, type);\n blockNew.copyBreakpoints(this.dbg, block);\n this.aBusBlocks[iBlock++] = blockNew;\n\n addrNext = addrBlock + this.nBlockSize;\n sizeLeft -= sizeBlock;\n }\n\n if (sizeLeft <= 0) {\n this.status(\"Added \" + (size >> 10) + \"Kb \" + MemoryPDP10.TYPE_NAMES[type] + \" at \" + Str.toOct(addr));\n return true;\n }\n\n return this.reportError(BusPDP10.ERROR.RANGE_INVALID, addr, size);\n }\n\n /**\n * cleanMemory(addr, size)\n *\n * @this {BusPDP10}\n * @param {number} addr\n * @param {number} size\n * @return {boolean} true if all blocks were clean, false if dirty; all blocks are cleaned in the process\n */\n cleanMemory(addr, size)\n {\n var fClean = true;\n var iBlock = addr >>> this.nBlockShift;\n var sizeBlock = this.nBlockSize - (addr & this.nBlockLimit);\n while (size > 0 && iBlock < this.aBusBlocks.length) {\n if (this.aBusBlocks[iBlock].fDirty) {\n this.aBusBlocks[iBlock].fDirty = fClean = false;\n this.aBusBlocks[iBlock].fDirtyEver = true;\n }\n size -= sizeBlock;\n sizeBlock = this.nBlockSize;\n iBlock++;\n }\n return fClean;\n }\n\n /**\n * zeroMemory(addr, size, pattern)\n *\n * @this {BusPDP10}\n * @param {number} addr\n * @param {number} size\n * @param {number} [pattern]\n */\n zeroMemory(addr, size, pattern)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0 && iBlock < this.aBusBlocks.length) {\n this.aBusBlocks[iBlock].zero(off, size, pattern);\n size -= this.nBlockSize;\n iBlock++;\n off = 0;\n }\n }\n\n /**\n * scanMemory(info, addr, size)\n *\n * Returns a BusInfoPDP10 object for the specified address range.\n *\n * @this {BusPDP10}\n * @param {BusInfoPDP10} [info] previous BusInfoPDP10, if any\n * @param {number} [addr] starting address of range (0 if none provided)\n * @param {number} [size] size of range, in bytes (up to end of address space if none provided)\n * @return {BusInfoPDP10} updated info (or new info if no previous info provided)\n */\n scanMemory(info, addr, size)\n {\n if (addr == null) addr = 0;\n if (size == null) size = (this.addrTotal - addr) | 0;\n if (info == null) info = {cbTotal: 0, cBlocks: 0, aBlocks: []};\n\n var iBlock = addr >>> this.nBlockShift;\n var iBlockMax = ((addr + size - 1) >>> this.nBlockShift);\n\n info.cbTotal = 0;\n info.cBlocks = 0;\n while (iBlock <= iBlockMax) {\n var block = this.aBusBlocks[iBlock];\n info.cbTotal += block.size;\n if (block.size) {\n info.aBlocks.push(/** @type {BlockInfoPDP10} */ (Usr.initBitFields(BlockInfoPDP10, iBlock, 0, 0, block.type)));\n info.cBlocks++\n }\n iBlock++;\n }\n return info;\n }\n\n /**\n * removeMemory(addr, size)\n *\n * Replaces every block in the specified address range with empty Memory blocks that ignore all reads/writes.\n *\n * TODO: Update the removeMemory() interface to reflect the relaxed requirements of the addMemory() interface.\n *\n * @this {BusPDP10}\n * @param {number} addr\n * @param {number} size\n * @return {boolean} true if successful, false if not\n */\n removeMemory(addr, size)\n {\n if (!(addr & this.nBlockLimit) && size && !(size & this.nBlockLimit)) {\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0) {\n var blockOld = this.aBusBlocks[iBlock];\n var blockNew = new MemoryPDP10(this, addr);\n blockNew.copyBreakpoints(this.dbg, blockOld);\n this.aBusBlocks[iBlock++] = blockNew;\n addr = iBlock * this.nBlockSize;\n size -= this.nBlockSize;\n }\n return true;\n }\n return this.reportError(BusPDP10.ERROR.RANGE_INVALID, addr, size);\n }\n\n /**\n * getMemoryBlocks(addr, size)\n *\n * @this {BusPDP10}\n * @param {number} addr is the starting physical address\n * @param {number} size of the request, in bytes\n * @return {Array} of Memory blocks\n */\n getMemoryBlocks(addr, size)\n {\n var aBlocks = [];\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0 && iBlock < this.aBusBlocks.length) {\n aBlocks.push(this.aBusBlocks[iBlock++]);\n size -= this.nBlockSize;\n }\n return aBlocks;\n }\n\n /**\n * setMemoryBlocks(addr, size, aBlocks, type)\n *\n * If no type is specified, then specified address range uses all the provided blocks as-is;\n * this form of setMemoryBlocks() is used for complete physical aliases.\n *\n * Otherwise, new blocks are allocated with the specified type; the underlying memory from the\n * provided blocks is still used, but the new blocks may have different access to that memory.\n *\n * @this {BusPDP10}\n * @param {number} addr is the starting physical address\n * @param {number} size of the request, in bytes\n * @param {Array} aBlocks as returned by getMemoryBlocks()\n * @param {number} [type] is one of the MemoryPDP10.TYPE constants\n */\n setMemoryBlocks(addr, size, aBlocks, type)\n {\n var i = 0;\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0 && iBlock < this.aBusBlocks.length) {\n var block = aBlocks[i++];\n\n if (!block) break;\n if (type !== undefined) {\n var blockNew = new MemoryPDP10(this, addr);\n blockNew.clone(block, type, this.dbg);\n block = blockNew;\n }\n this.aBusBlocks[iBlock++] = block;\n size -= this.nBlockSize;\n }\n }\n\n /**\n * getWord(addr)\n *\n * @this {BusPDP10}\n * @param {number} addr is a physical address\n * @return {number} word (36-bit) value at that address\n */\n getWord(addr)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n return this.aBusBlocks[iBlock].readWord(off, addr);\n }\n\n /**\n * setWord(addr, w)\n *\n * @this {BusPDP10}\n * @param {number} addr is a physical address\n * @param {number} w is the word (36-bit) value to write\n */\n setWord(addr, w)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;\n this.aBusBlocks[iBlock].writeWord(w, off, addr);\n }\n\n /**\n * getBlockDirect(addr)\n *\n * @this {BusPDP10}\n * @param {number} addr is a physical address\n * @return {MemoryPDP10}\n */\n getBlockDirect(addr)\n {\n return this.aBusBlocks[(addr & this.nBusMask) >>> this.nBlockShift];\n }\n\n /**\n * getWordDirect(addr)\n *\n * This is used for device I/O and Debugger physical memory requests, not the CPU.\n *\n * @this {BusPDP10}\n * @param {number} addr is a physical address\n * @return {number} word (36-bit) value at that address\n */\n getWordDirect(addr)\n {\n var w;\n var off = addr & this.nBlockLimit;\n var block = this.getBlockDirect(addr);\n this.nDisableFaults++;\n w = block.readWordDirect(off, addr);\n this.nDisableFaults--;\n return w;\n }\n\n /**\n * setWordDirect(addr, w)\n *\n * This is used for device I/O and Debugger physical memory requests, not the CPU.\n *\n * @this {BusPDP10}\n * @param {number} addr is a physical address\n * @param {number} w is the word (36-bit) value to write\n */\n setWordDirect(addr, w)\n {\n var off = addr & this.nBlockLimit;\n var block = this.getBlockDirect(addr);\n this.nDisableFaults++;\n block.writeWordDirect(w, off, addr);\n this.nDisableFaults--;\n }\n\n /**\n * addMemBreak(addr, fWrite)\n *\n * @this {BusPDP10}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint\n */\n addMemBreak(addr, fWrite)\n {\n if (DEBUGGER) {\n var iBlock = addr >>> this.nBlockShift;\n this.aBusBlocks[iBlock].addBreakpoint(addr & this.nBlockLimit, fWrite);\n }\n }\n\n /**\n * removeMemBreak(addr, fWrite)\n *\n * @this {BusPDP10}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint\n */\n removeMemBreak(addr, fWrite)\n {\n if (DEBUGGER) {\n var iBlock = addr >>> this.nBlockShift;\n this.aBusBlocks[iBlock].removeBreakpoint(addr & this.nBlockLimit, fWrite);\n }\n }\n\n /**\n * saveMemory(fAll)\n *\n * The only memory blocks we save are those marked as dirty, but most likely all of RAM will have been marked dirty,\n * and even if our dirty-memory flags were as smart as our dirty-sector flags (ie, were set only when a write changed\n * what was already there), it's unlikely that would reduce the number of RAM blocks we must save/restore. At least\n * all the ROM blocks should be clean (except in the unlikely event that the Debugger was used to modify them).\n *\n * All dirty blocks will be stored in a single array, as pairs of block numbers and data arrays, like so:\n *\n * [iBlock0, [dw0, dw1, ...], iBlock1, [dw0, dw1, ...], ...]\n *\n * In a normal 4Kb block, there will be 1K DWORD values in the data array. Remember that each DWORD is a signed 32-bit\n * integer (because they are formed using bitwise operator rather than floating-point math operators), so don't be\n * surprised to see negative numbers in the data.\n *\n * The above example assumes \"uncompressed\" data arrays. If we choose to use \"compressed\" data arrays, the data arrays\n * will look like:\n *\n * [count0, dw0, count1, dw1, ...]\n *\n * where each count indicates how many times the following DWORD value occurs. A data array length less than 1K indicates\n * that it's compressed, since we'll only store them in compressed form if they actually shrank, and we'll use State\n * helper methods compress() and decompress() to create and expand the compressed data arrays.\n *\n * @this {BusPDP10}\n * @param {boolean} [fAll] (true to save all non-ROM memory blocks, regardless of their dirty flags)\n * @return {Array} a\n */\n saveMemory(fAll)\n {\n var i = 0;\n var a = [];\n\n for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {\n var block = this.aBusBlocks[iBlock];\n /*\n * We have to check both fDirty and fDirtyEver, because we may have called cleanMemory() on some of\n * the memory blocks (eg, video memory), and while cleanMemory() will clear a dirty block's fDirty flag,\n * it also sets the dirty block's fDirtyEver flag, which is left set for the lifetime of the machine.\n */\n if (fAll && block.type != MemoryPDP10.TYPE.ROM || block.fDirty || block.fDirtyEver) {\n a[i++] = iBlock;\n a[i++] = State.compress(block.save());\n }\n }\n\n return a;\n }\n\n /**\n * restoreMemory(a)\n *\n * This restores the contents of all Memory blocks; called by CPUState.restore().\n *\n * In theory, we ONLY have to save/restore block contents. Other block attributes,\n * like the type, the memory controller (if any), and the active memory access functions,\n * should already be restored, since every component (re)allocates all the memory blocks\n * it was using when it's restored. And since the CPU is guaranteed to be the last\n * component to be restored, all those blocks (and their attributes) should be in place now.\n *\n * See saveMemory() for more information on how the memory block contents are saved.\n *\n * @this {BusPDP10}\n * @param {Array} a\n * @return {boolean} true if successful, false if not\n */\n restoreMemory(a)\n {\n var i;\n for (i = 0; i < a.length - 1; i += 2) {\n var iBlock = a[i];\n var adw = a[i+1];\n if (adw && adw.length < this.nBlockLen) {\n adw = State.decompress(adw, this.nBlockLen);\n }\n var block = this.aBusBlocks[iBlock];\n if (!block || !block.restore(adw)) {\n /*\n * Either the block to restore hasn't been allocated, indicating a change in the machine\n * configuration since it was last saved (the most likely explanation) or there's some internal\n * inconsistency (eg, the block size is wrong).\n */\n Component.error(\"Unable to restore memory block \" + iBlock);\n return false;\n }\n }\n return true;\n }\n\n /**\n * getMemoryLimit(type)\n *\n * @this {BusPDP10}\n * @param {number} type is one of the MemoryPDP10.TYPE constants\n * @return {number} (the limiting address of the specified memory type, zero if none)\n */\n getMemoryLimit(type)\n {\n var addr = 0;\n for (var iBlock = 0; iBlock < this.aBusBlocks.length; iBlock++) {\n var block = this.aBusBlocks[iBlock];\n if (block.type == type) {\n addr = block.addr + block.used;\n }\n }\n return addr;\n }\n\n /**\n * fault(addr, err, access)\n *\n * Bus interface for signaling alignment errors, invalid memory, etc.\n *\n * @this {BusPDP10}\n * @param {number} addr\n * @param {number} [err]\n * @param {number} [access] (for diagnostic purposes only)\n */\n fault(addr, err, access)\n {\n this.fFault = true;\n if (!this.nDisableFaults) {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP10.FAULT)) {\n this.dbg.printMessage(\"memory fault on \" + this.dbg.toStrBase(addr), true, true);\n }\n this.cpu.haltCPU();\n }\n }\n\n /**\n * checkFault()\n *\n * This also serves as a clearFault() function.\n *\n * @this {BusPDP10}\n * @return {boolean}\n */\n checkFault()\n {\n var f = this.fFault;\n this.fFault = false;\n return f;\n }\n\n /**\n * reportError(errNum, addr, size, fQuiet)\n *\n * @this {BusPDP10}\n * @param {number} errNum\n * @param {number} addr\n * @param {number} size\n * @param {boolean} [fQuiet] (true if any error should be quietly logged)\n * @return {boolean} false\n */\n reportError(errNum, addr, size, fQuiet)\n {\n var sError = \"Memory block error (\" + errNum + \": \" + Str.toHex(addr) + \",\" + Str.toHex(size) + \")\";\n if (fQuiet) {\n if (this.dbg) {\n this.dbg.message(sError);\n } else {\n this.log(sError);\n }\n } else {\n Component.error(sError);\n }\n return false;\n }\n}\n\nBusPDP10.ERROR = {\n RANGE_INUSE: 1,\n RANGE_INVALID: 2\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/device.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass DevicePDP10 extends Component {\n /**\n * DevicePDP10(parmsDevice)\n *\n * @param {Object} parmsDevice\n */\n constructor(parmsDevice)\n {\n super(\"Device\", parmsDevice, MessagesPDP10.DEVICE);\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {DevicePDP10}\n * @param {ComputerPDP10} cmp\n * @param {BusPDP10} bus\n * @param {CPUStatePDP10} cpu\n * @param {DebuggerPDP10} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cmp = cmp;\n this.cpu = cpu;\n this.dbg = dbg;\n\n this.setReady();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {DevicePDP10}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {DevicePDP10}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {DevicePDP10}\n */\n reset()\n {\n }\n\n /**\n * save()\n *\n * This implements save support for the DevicePDP10 component.\n *\n * @this {DevicePDP10}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the DevicePDP10 component.\n *\n * @this {DevicePDP10}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return true;\n }\n\n /**\n * DevicePDP10.init()\n *\n * This function operates on every HTML element of class \"device\", extracting the\n * JSON-encoded parameters for the DevicePDP10 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a DevicePDP10 component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeDevice = Component.getElementsByClass(document, PDP10.APPCLASS, \"device\");\n for (var iDevice = 0; iDevice < aeDevice.length; iDevice++) {\n var device;\n var eDevice = aeDevice[iDevice];\n var parmsDevice = Component.getComponentParms(eDevice);\n switch(parmsDevice['type']) {\n case 'default':\n device = new DevicePDP10(parmsDevice);\n Component.bindComponentControls(device, eDevice, PDP10.APPCLASS);\n break;\n }\n }\n }\n}\n\n/*\n * Initialize all the DevicePDP10 modules on the page.\n */\nWeb.onInit(DevicePDP10.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/memory.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * @class DataView\n * @property {function(number,boolean):number} getUint8\n * @property {function(number,number,boolean)} setUint8\n * @property {function(number,boolean):number} getUint16\n * @property {function(number,number,boolean)} setUint16\n * @property {function(number,boolean):number} getInt32\n * @property {function(number,number,boolean)} setInt32\n */\n\n/**\n * @class MemoryPDP10\n * @property {number} id\n * @property {number} used\n * @property {number} size\n * @property {Array.<number>} aw\n */\nclass MemoryPDP10 {\n /**\n * MemoryPDP10(bus, addr, used, size, type)\n *\n * The Bus component allocates Memory objects so that each has a memory buffer with a\n * block-granular starting address and an address range equal to bus.nBlockSize; however,\n * the size of any given Memory object's underlying buffer can be either zero or bus.nBlockSize;\n * memory read/write functions for empty (buffer-less) blocks are mapped to readNone/writeNone.\n *\n * The Bus allocates empty blocks for the entire address space during initialization, so that\n * any reads/writes to undefined addresses will have no effect. Later, the ROM and RAM\n * components will ask the Bus to allocate memory for specific ranges, and the Bus will allocate\n * as many new blockSize Memory objects as the ranges require. Partial Memory blocks could\n * also be supported in theory, but in practice, they're not.\n *\n * WARNING: Since Memory blocks are low-level objects that have no UI requirements, they\n * do not inherit from the Component class, so if you want to use any Component class methods,\n * such as Component.assert(), use the corresponding Debugger methods instead (assuming a debugger\n * is available).\n *\n * @param {BusPDP10} bus\n * @param {number|null} [addr] of lowest used address in block\n * @param {number} [used] portion of block in words (0 for none)\n * @param {number} [size] of block's buffer in words (0 for none)\n * @param {number} [type] is one of the MemoryPDP10.TYPE constants (default is MemoryPDP10.TYPE.NONE)\n */\n constructor(bus, addr, used, size, type)\n {\n var a, i;\n this.bus = bus;\n this.id = (MemoryPDP10.idBlock += 2);\n this.adw = null;\n this.offset = 0;\n this.addr = addr;\n this.used = used;\n this.size = size || 0;\n this.type = type || MemoryPDP10.TYPE.NONE;\n this.fReadOnly = (type == MemoryPDP10.TYPE.ROM);\n this.dbg = null;\n this.readWord = this.readWordDirect = this.readNone;\n this.writeWord = this.writeWordDirect = this.writeNone;\n this.cReadBreakpoints = this.cWriteBreakpoints = 0;\n this.copyBreakpoints(); // initialize the block's Debugger info; the caller will reinitialize\n\n /*\n * TODO: Study the impact of dirty block tracking. The original purposes were to allow saveMemory()\n * to save only dirty blocks, and to enable the Video component to quickly detect changes to the video buffer.\n *\n * However, a quick test with dirty block tracking disabled didn't yield a noticeable improvement in performance,\n * so I think the overhead of our block-based architecture is swamping the impact of these micro-updates.\n */\n this.fDirty = this.fDirtyEver = false;\n\n /*\n * For empty memory blocks, all we need to do is ensure all access functions are mapped to \"none\" handlers.\n */\n if (!this.size) {\n this.setAccess();\n return;\n }\n\n /*\n * This is the normal case: allocate a buffer that provides a word of data per address;\n * no controller is required because our default memory access functions (see afnMemory)\n * know how to deal with this simple 1-1 mapping of addresses to words.\n *\n * TODO: Consider initializing the memory array to random (or pseudo-random) values in DEBUG\n * mode; pseudo-random might be best, to help make any bugs reproducible.\n */\n a = this.aw = new Array(this.size);\n for (i = 0; i < a.length; i++) a[i] = 0;\n this.setAccess(MemoryPDP10.afnMemory);\n }\n\n /**\n * init(addr)\n *\n * Quick reinitializer when reusing a Memory block.\n *\n * @this {MemoryPDP10}\n * @param {number} addr\n */\n init(addr)\n {\n this.addr = addr;\n }\n\n /**\n * clone(mem, type, dbg)\n *\n * Converts the current Memory block (this) into a clone of the given Memory block (mem),\n * and optionally overrides the current block's type with the specified type.\n *\n * @this {MemoryPDP10}\n * @param {MemoryPDP10} mem\n * @param {number} [type]\n * @param {DebuggerPDP10} [dbg]\n */\n clone(mem, type, dbg)\n {\n /*\n * Original memory block IDs are even; cloned memory block IDs are odd;\n * the original ID of the current block is lost, but that's OK, since it was presumably\n * produced merely to become a clone.\n */\n this.id = mem.id | 0x1;\n this.used = mem.used;\n this.size = mem.size;\n if (type) {\n this.type = type;\n this.fReadOnly = (type == MemoryPDP10.TYPE.ROM);\n }\n this.aw = mem.aw;\n this.setAccess(MemoryPDP10.afnMemory);\n this.copyBreakpoints(dbg, mem);\n }\n\n /**\n * save()\n *\n * This gets the contents of a Memory block as an array of numeric values; used by Bus.saveMemory(),\n * which in turn is called by CPUState.save().\n *\n * @this {MemoryPDP10}\n * @return {Array.<number>|null}\n */\n save()\n {\n return this.aw;\n }\n\n /**\n * restore(aw)\n *\n * This restores the contents of a Memory block from an array of numeric values; used by Bus.restoreMemory(),\n * which is called by CPUState.restore(), after all other components have been restored and thus all Memory\n * blocks have been allocated by their respective components.\n *\n * @this {MemoryPDP10}\n * @param {Array.<number>|null} aw\n * @return {boolean} true if successful, false if block size mismatch\n */\n restore(aw)\n {\n if (aw && this.size == aw.length) {\n this.aw = aw;\n this.fDirty = true;\n return true;\n }\n return false;\n }\n\n /**\n * zero(off, len, pattern)\n *\n * @this {MemoryPDP10}\n * @param {number} [off] (optional starting word offset within block)\n * @param {number} [len] (optional maximum number of words; default is the entire block)\n * @param {number} [pattern] (default is zero)\n */\n zero(off, len, pattern = 0)\n {\n /*\n * NOTE: If len is larger than the block, that's OK, because we also bounds-check the index.\n */\n off = off || 0;\n if (len === undefined) len = this.size;\n\n\n /*\n * Although it's expected that most callers will supply unsigned 36-bit values, we're nice about\n * converting any signed values to their unsigned (two's complement) counterpart, provided they are\n * within the acceptable range. Any values outside that range will be dealt with afterward.\n */\n if (pattern < 0 && pattern >= -PDP10.INT_LIMIT) {\n pattern += PDP10.WORD_LIMIT;\n }\n pattern = Math.trunc(Math.abs(pattern)) % PDP10.WORD_LIMIT;\n\n for (var i = off; len-- && i < this.size; i++) this.writeWordDirect(pattern, off, this.addr + off);\n }\n\n /**\n * setAccess(afn, fDirect)\n *\n * The afn parameter should be a 2-entry function table containing word read and write handlers.\n * See the static afnMemory table for an example.\n *\n * If no function table is specified, a default is selected based on the Memory type; similarly,\n * any undefined entries in the table are filled with default handlers.\n *\n * fDirect indicates that both the default AND the direct handlers should be updated. Direct\n * handlers normally match the default handlers, except when \"checked\" handlers are installed;\n * this allows \"checked\" handlers to know where to dispatch the call after performing checks.\n * Examples of checks are read/write breakpoints, but it's really up to the Debugger to decide\n * what the check consists of.\n *\n * @this {MemoryPDP10}\n * @param {Array.<function()>} [afn] function table\n * @param {boolean} [fDirect] (true to update direct access functions as well; default is true)\n */\n setAccess(afn, fDirect)\n {\n if (!afn) {\n\n afn = MemoryPDP10.afnNone;\n }\n this.setReadAccess(afn, fDirect);\n this.setWriteAccess(afn, fDirect);\n }\n\n /**\n * setReadAccess(afn, fDirect)\n *\n * @this {MemoryPDP10}\n * @param {Array.<function()>} afn\n * @param {boolean} [fDirect]\n */\n setReadAccess(afn, fDirect)\n {\n if (!fDirect || !this.cReadBreakpoints) {\n this.readWord = afn[0] || this.readNone;\n }\n if (fDirect || fDirect === undefined) {\n this.readWordDirect = afn[0] || this.readNone;\n }\n }\n\n /**\n * setWriteAccess(afn, fDirect)\n *\n * @this {MemoryPDP10}\n * @param {Array.<function()>} afn\n * @param {boolean} [fDirect]\n */\n setWriteAccess(afn, fDirect)\n {\n if (!fDirect || !this.cWriteBreakpoints) {\n this.writeWord = !this.fReadOnly && afn[1] || this.writeNone;\n }\n if (fDirect || fDirect === undefined) {\n this.writeWordDirect = afn[1] || this.writeNone;\n }\n }\n\n /**\n * resetReadAccess()\n *\n * @this {MemoryPDP10}\n */\n resetReadAccess()\n {\n this.readWord = this.readWordDirect;\n }\n\n /**\n * resetWriteAccess()\n *\n * @this {MemoryPDP10}\n */\n resetWriteAccess()\n {\n this.writeWord = this.fReadOnly? this.writeNone : this.writeWordDirect;\n }\n\n /**\n * printAddr(sMessage)\n *\n * @this {MemoryPDP10}\n * @param {string} sMessage\n */\n printAddr(sMessage)\n {\n if (DEBUG && this.dbg && this.dbg.messageEnabled(MessagesPDP10.MEMORY)) {\n this.dbg.printMessage(sMessage + ' ' + (this.addr != null? ('@' + this.dbg.toStrBase(this.addr)) : '#' + this.id), true);\n }\n }\n\n /**\n * addBreakpoint(off, fWrite)\n *\n * @this {MemoryPDP10}\n * @param {number} off\n * @param {boolean} fWrite\n */\n addBreakpoint(off, fWrite)\n {\n if (!fWrite) {\n if (this.cReadBreakpoints++ === 0) {\n this.setReadAccess(MemoryPDP10.afnChecked, false);\n }\n if (DEBUG) this.printAddr(\"read breakpoint added to memory block\");\n }\n else {\n if (this.cWriteBreakpoints++ === 0) {\n this.setWriteAccess(MemoryPDP10.afnChecked, false);\n }\n if (DEBUG) this.printAddr(\"write breakpoint added to memory block\");\n }\n }\n\n /**\n * removeBreakpoint(off, fWrite)\n *\n * @this {MemoryPDP10}\n * @param {number} off\n * @param {boolean} fWrite\n */\n removeBreakpoint(off, fWrite)\n {\n if (!fWrite) {\n if (--this.cReadBreakpoints === 0) {\n this.resetReadAccess();\n if (DEBUG) this.printAddr(\"all read breakpoints removed from memory block\");\n }\n\n }\n else {\n if (--this.cWriteBreakpoints === 0) {\n this.resetWriteAccess();\n if (DEBUG) this.printAddr(\"all write breakpoints removed from memory block\");\n }\n\n }\n }\n\n /**\n * copyBreakpoints(dbg, mem)\n *\n * @this {MemoryPDP10}\n * @param {DebuggerPDP10} [dbg]\n * @param {MemoryPDP10} [mem] (outgoing MemoryPDP10 block to copy breakpoints from, if any)\n */\n copyBreakpoints(dbg, mem)\n {\n this.dbg = dbg;\n this.cReadBreakpoints = this.cWriteBreakpoints = 0;\n if (mem) {\n if ((this.cReadBreakpoints = mem.cReadBreakpoints)) {\n this.setReadAccess(MemoryPDP10.afnChecked, false);\n }\n if ((this.cWriteBreakpoints = mem.cWriteBreakpoints)) {\n this.setWriteAccess(MemoryPDP10.afnChecked, false);\n }\n }\n }\n\n /**\n * readNone(off, addr)\n *\n * @this {MemoryPDP10}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readNone(off, addr)\n {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP10.MEMORY) /* && !off */) {\n this.dbg.printMessage(\"attempt to read invalid address \" + this.dbg.toStrBase(addr), true);\n }\n this.bus.fault(addr);\n return PDP10.WORD_INVALID;\n }\n\n /**\n * writeNone(v, off, addr)\n *\n * @this {MemoryPDP10}\n * @param {number} v\n * @param {number} off\n * @param {number} addr\n */\n writeNone(v, off, addr)\n {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP10.MEMORY) /* && !off */) {\n this.dbg.printMessage(\"attempt to write \" + this.dbg.toStrBase(v) + \" to invalid addresses \" + this.dbg.toStrBase(addr), true);\n }\n this.bus.fault(addr);\n }\n\n /**\n * readWordMemory(off, addr)\n *\n * @this {MemoryPDP10}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readWordMemory(off, addr)\n {\n var w = this.aw[off];\n\n return w;\n }\n\n /**\n * writeWordMemory(w, off, addr)\n *\n * @this {MemoryPDP10}\n * @param {number} w\n * @param {number} off\n * @param {number} addr\n */\n writeWordMemory(w, off, addr)\n {\n\n if (this.aw[off] != w) {\n this.aw[off] = w;\n this.fDirty = true;\n }\n }\n\n /**\n * readWordChecked(off, addr)\n *\n * @this {MemoryPDP10}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readWordChecked(off, addr)\n {\n if (DEBUGGER && this.dbg && this.addr != null) {\n this.dbg.checkMemoryRead(this.addr + off, 2);\n }\n return this.readWordDirect(off, addr);\n }\n\n /**\n * writeWordChecked(w, off, addr)\n *\n * @this {MemoryPDP10}\n * @param {number} w\n * @param {number} off\n * @param {number} addr\n */\n writeWordChecked(w, off, addr)\n {\n if (DEBUGGER && this.dbg && this.addr != null) {\n this.dbg.checkMemoryWrite(this.addr + off, 2)\n }\n if (this.fReadOnly) this.writeNone(w, off, addr); else this.writeWordDirect(w, off, addr);\n }\n}\n\n/*\n * Basic memory types\n *\n * RAM is the most conventional memory type, providing full read/write capability. ROM is equally\n * conventional, except that the fReadOnly property is set. ROM can be written using the Bus setWordDirect()\n * interface (which in turn uses the Memory writeWordDirect() interface), allowing the ROM component to\n * initialize its own memory.\n */\nMemoryPDP10.TYPE = {\n NONE: 0,\n RAM: 1,\n ROM: 2\n};\nMemoryPDP10.TYPE_COLORS = [\"black\", \"blue\", \"green\"];\nMemoryPDP10.TYPE_NAMES = [\"NONE\", \"RAM\", \"ROM\"];\n\n/*\n * Last used block ID (used for debugging only)\n */\nMemoryPDP10.idBlock = 0;\n\n/*\n * This is the effective definition of afnNone, but we need not fully define it, because setAccess()\n * uses these defaults when any of the handlers are undefined.\n *\nMemoryPDP10.afnNone = [\n MemoryPDP10.prototype.readNone,\n MemoryPDP10.prototype.writeNone\n];\n */\nMemoryPDP10.afnNone = [];\n\nMemoryPDP10.afnMemory = [\n MemoryPDP10.prototype.readWordMemory,\n MemoryPDP10.prototype.writeWordMemory\n];\n\nMemoryPDP10.afnChecked = [\n MemoryPDP10.prototype.readWordChecked,\n MemoryPDP10.prototype.writeWordChecked\n];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/cpu.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * @class CPUPDP10\n * @unrestricted\n */\nclass CPUPDP10 extends Component {\n /**\n * CPUPDP10(parmsCPU, nCyclesDefault)\n *\n * The CPUPDP10 class supports the following (parmsCPU) properties:\n *\n * cycles: the machine's base cycles per second; the CPUStatePDP10 constructor\n * will provide us with a default (based on the CPU model) to use as a fallback.\n *\n * multiplier: base cycle multiplier; default is 1.\n *\n * autoStart: true to automatically start, false to not, or null if \"it depends\";\n * null is the default, which means do not autostart UNLESS there is no Debugger\n * and no \"Run\" button (ie, no way to manually start the machine).\n *\n * csStart: the number of cycles that runCPU() must wait before generating\n * checksum records; -1 if disabled. checksum records are a diagnostic aid\n * used to help compare one CPU run to another.\n *\n * csInterval: the number of cycles that runCPU() must execute before generating\n * a checksum record; -1 if disabled.\n *\n * csStop: the number of cycles to stop generating checksum records.\n *\n * This component is primarily responsible for interfacing the CPU with the outside\n * world (eg, Panel and Debugger components), and managing overall CPU operation.\n *\n * It is extended by the CPUStatePDP10 component, where the simulation control logic resides.\n *\n * @param {Object} parmsCPU\n * @param {number} nCyclesDefault\n */\n constructor(parmsCPU, nCyclesDefault)\n {\n super(\"CPU\", parmsCPU, MessagesPDP10.CPU);\n\n var nCycles = +parmsCPU['cycles'] || nCyclesDefault;\n\n var nMultiplier = +parmsCPU['multiplier'] || 1;\n\n this.nDisplayCount = 0;\n this.nDisplayLimit = 30;\n this.nCyclesPerSecond = nCycles;\n\n /*\n * nCyclesMultiplier replaces the old \"speed\" variable (0, 1, 2) and eliminates the need for\n * the constants (SPEED_SLOW, SPEED_FAST and SPEED_MAX). The UI simply doubles the multiplier\n * until we've exceeded the host's speed limit and then starts the multiplier over at 1.\n */\n this.nCyclesMultiplier = nMultiplier;\n this.mhzDefault = Math.round(this.nCyclesPerSecond / 10000) / 100;\n this.mhzTarget = this.mhzDefault * this.nCyclesMultiplier;\n this.msPerYield = this.nCyclesPerYield = this.nCyclesNextYield = this.nCyclesRecalc = 0;\n\n /*\n * We add a number of flags to the set initialized by Component\n */\n this.flags.running = this.flags.starting = false;\n this.flags.autoStart = parmsCPU['autoStart'];\n if (typeof this.flags.autoStart == \"string\") this.flags.autoStart = (this.flags.autoStart == \"true\");\n\n /*\n * Get checksum parameters, if any. runCPU() behavior is not affected until fChecksum\n * is true, which won't happen until resetChecksum() is called with nCyclesChecksumInterval\n * (\"csInterval\") set to a positive value.\n *\n * As above, any of these parameters can also be set with the Debugger's execution options\n * command (\"x\"); for example, \"x cs int 5000\" will set nCyclesChecksumInterval to 5000\n * and call resetChecksum().\n */\n this.flags.checksum = false;\n this.nChecksum = this.nCyclesChecksumNext = 0;\n this.nCyclesChecksumStart = +parmsCPU[\"csStart\"];\n this.nCyclesChecksumInterval = +parmsCPU[\"csInterval\"];\n this.nCyclesChecksumStop = +parmsCPU[\"csStop\"];\n\n /*\n * Array of countdown timers managed by addTimer() and setTimer().\n */\n this.aTimers = [];\n\n this.onRunTimeout = this.runCPU.bind(this); // function onRunTimeout() { cpu.runCPU(); };\n\n /*\n * Define the rest of the properties used by the class\n */\n this.mhz = 0;\n this.nYieldsSinceStatusUpdate = 0;\n this.msStartRun = this.msStartThisRun = this.msEndThisRun = this.nCyclesThisRun = 0;\n this.nTotalCycles = this.nRunCycles = this.nBurstCycles = this.nStepCycles = this.nSnapCycles = 0;\n this.panel = null;\n\n this.setReady();\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {CPUPDP10}\n * @param {ComputerPDP10} cmp\n * @param {BusPDP10} bus\n * @param {CPUPDP10} cpu\n * @param {DebuggerPDP10} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.dbg = dbg;\n this.panel = cmp.panel;\n for (var i = 0; i < CPUPDP10.BUTTONS.length; i++) {\n var control = this.bindings[CPUPDP10.BUTTONS[i]];\n if (control) this.cmp.setBinding(\"\", CPUPDP10.BUTTONS[i], control);\n }\n this.setReady();\n }\n\n /**\n * reset()\n *\n * Stub for reset notification (overridden by the CPUStatePDP10 component).\n *\n * @this {CPUPDP10}\n */\n reset()\n {\n }\n\n /**\n * save()\n *\n * Stub for save support (overridden by the CPUStatePDP10 component).\n *\n * @this {CPUPDP10}\n * @return {Object|null}\n */\n save()\n {\n return null;\n }\n\n /**\n * restore(data)\n *\n * Stub for restore support (overridden by the CPUStatePDP10 component).\n *\n * @this {CPUPDP10}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n return false;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {CPUPDP10}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n /*\n * We've already saved the parmsCPU 'autoStart' setting, but there may be a machine (or URL) override.\n */\n var sAutoStart = this.cmp.getMachineParm('autoStart');\n if (sAutoStart != null) {\n this.flags.autoStart = (sAutoStart == \"true\"? true : (sAutoStart == \"false\"? false : !!sAutoStart));\n }\n else if (this.flags.autoStart == null) {\n /*\n * If there's no explicit parmsCPU setting either, then we will autoStart if there's no Debugger and\n * no \"Run\" button.\n */\n this.flags.autoStart = ((!DEBUGGER || !this.dbg) && this.bindings[\"run\"] === undefined);\n }\n\n if (!fRepower) {\n if (!data) {\n this.reset();\n } else {\n this.resetCycles();\n if (!this.restore(data)) return false;\n this.resetChecksum();\n }\n /*\n * Give the Debugger a chance to do/print something once we've powered up.\n */\n if (DEBUGGER && this.dbg) {\n this.dbg.init(this.flags.autoStart);\n } else {\n this.status(\"No debugger detected\");\n }\n if (!this.flags.autoStart) {\n this.println(\"CPU will not be auto-started \" + (this.panel? \"(click Run to start)\" : \"(type 'go' to start)\"));\n }\n }\n /*\n * The Computer component (which is responsible for all powerDown and powerUp notifications)\n * is now responsible for managing a component's fPowered flag, not us.\n *\n * this.flags.powered = true;\n */\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {CPUPDP10}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * autoStart()\n *\n * @this {CPUPDP10}\n * @return {boolean} true if started, false if not\n */\n autoStart()\n {\n if (this.flags.running) {\n return true;\n }\n if (this.flags.autoStart) {\n /*\n * We used to also set fUpdateFocus when calling startCPU(), on the assumption that in the \"auto-starting\"\n * context, a machine without focus is like a day without sunshine, but in reality, focus should only be\n * forced when the user takes some other machine-related action.\n */\n this.startCPU();\n return true;\n }\n return false;\n }\n\n /**\n * isPowered()\n *\n * @this {CPUPDP10}\n * @return {boolean}\n */\n isPowered()\n {\n if (!this.flags.powered) {\n this.println(this.toString() + \" not powered\");\n return false;\n }\n return true;\n }\n\n /**\n * isRunning()\n *\n * @this {CPUPDP10}\n * @return {boolean}\n */\n isRunning()\n {\n return this.flags.running;\n }\n\n /**\n * getChecksum()\n *\n * This will be implemented by the CPUStatePDP10 component.\n *\n * @this {CPUPDP10}\n * @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code)\n */\n getChecksum()\n {\n return 0;\n }\n\n /**\n * resetChecksum()\n *\n * If checksum generation is enabled (fChecksum is true), this resets the running 32-bit checksum and the\n * cycle counter that will trigger the next displayChecksum(); called by resetCycles(), which is called whenever\n * the CPU is reset or restored.\n *\n * @this {CPUPDP10}\n * @return {boolean} true if checksum generation enabled, false if not\n */\n resetChecksum()\n {\n if (this.nCyclesChecksumStart === undefined) this.nCyclesChecksumStart = 0;\n if (this.nCyclesChecksumInterval === undefined) this.nCyclesChecksumInterval = -1;\n if (this.nCyclesChecksumStop === undefined) this.nCyclesChecksumStop = -1;\n this.flags.checksum = (this.nCyclesChecksumStart >= 0 && this.nCyclesChecksumInterval > 0);\n if (this.flags.checksum) {\n this.nChecksum = 0;\n this.nCyclesChecksumNext = this.nCyclesChecksumStart - this.nTotalCycles;\n /*\n * this.nCyclesChecksumNext = this.nCyclesChecksumStart + this.nCyclesChecksumInterval -\n * (this.nTotalCycles % this.nCyclesChecksumInterval);\n */\n return true;\n }\n return false;\n }\n\n /**\n * updateChecksum(nCycles)\n *\n * When checksum generation is enabled (fChecksum is true), runCPU() asks stepCPU() to execute a minimum\n * number of cycles (1), effectively limiting execution to a single instruction, and then we're called with\n * the exact number cycles that were actually executed. This should give us instruction-granular checksums\n * at precise intervals that are 100% repeatable.\n *\n * @this {CPUPDP10}\n * @param {number} nCycles\n */\n updateChecksum(nCycles)\n {\n if (this.flags.checksum) {\n /*\n * Get a 32-bit summation of the current CPU state and add it to our running 32-bit checksum\n */\n var fDisplay = false;\n this.nChecksum = (this.nChecksum + this.getChecksum())|0;\n this.nCyclesChecksumNext -= nCycles;\n if (this.nCyclesChecksumNext <= 0) {\n this.nCyclesChecksumNext += this.nCyclesChecksumInterval;\n fDisplay = true;\n }\n if (this.nCyclesChecksumStop >= 0) {\n if (this.nCyclesChecksumStop <= this.getCycles()) {\n this.nCyclesChecksumInterval = this.nCyclesChecksumStop = -1;\n this.resetChecksum();\n this.stopCPU();\n fDisplay = true;\n }\n }\n if (fDisplay) this.displayChecksum();\n }\n }\n\n /**\n * displayChecksum()\n *\n * When checksum generation is enabled (fChecksum is true), this is called to provide a crude log of all\n * checksums generated at the specified cycle intervals, as specified by the \"csStart\" and \"csInterval\" parmsCPU\n * properties).\n *\n * @this {CPUPDP10}\n */\n displayChecksum()\n {\n this.println(this.getCycles() + \" cycles: \" + \"checksum=\" + Str.toHex(this.nChecksum));\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {CPUPDP10}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"run\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var cpu = this;\n\n switch (sBinding) {\n case \"power\":\n case \"reset\":\n /*\n * The \"power\" and \"reset\" buttons are functions of the entire computer, not just the CPU,\n * but it's not always convenient to stick a power button in the Computer component definition,\n * so we record those bindings here and pass them on to the Computer component in initBus().\n */\n this.bindings[sBinding] = control;\n return true;\n\n case \"run\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickRun() {\n if (!cpu.cmp || !cpu.cmp.checkPower()) return;\n /*\n * We no longer pass true to these startCPU()/stopCPU() calls, on the theory that if the \"run\"\n * control is visible, then the computer is probably sufficiently visible as well; the problem\n * with setting fUpdateFocus to true is that it can jerk the web page around in annoying ways.\n */\n if (!cpu.flags.running)\n cpu.startCPU();\n else\n cpu.stopCPU();\n };\n return true;\n\n case \"speed\":\n this.bindings[sBinding] = control;\n return true;\n\n case \"setSpeed\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickSetSpeed() {\n cpu.setSpeed(cpu.nCyclesMultiplier << 1, true);\n };\n control.textContent = this.getSpeedTarget();\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * updateDisplays(nUpdate)\n *\n * Simpler wrapper around the Computer's updateDisplays() method.\n *\n * @this {CPUPDP10}\n * @param {number} [nUpdate] (1 for periodic, -1 for forced, 0 or undefined otherwise)\n */\n updateDisplays(nUpdate)\n {\n if (this.cmp) this.cmp.updateDisplays(nUpdate);\n }\n\n /**\n * updateDisplay(nUpdate)\n *\n * Some of the CPU bindings provide feedback and therefore need to be updated periodically.\n * However, this should be called via the Computer's updateDisplays() interface, not directly.\n *\n * @this {CPUPDP10}\n * @param {number} [nUpdate] (1 for periodic, -1 for forced, 0 otherwise)\n */\n updateDisplay(nUpdate)\n {\n var controlSpeed = this.bindings[\"speed\"];\n if (controlSpeed) {\n if (nUpdate <= 0 || (this.nDisplayCount += nUpdate) >= this.nDisplayLimit) {\n controlSpeed.textContent = this.getSpeedCurrent();\n this.nDisplayCount = 0;\n }\n }\n }\n\n /**\n * addCycles(nCycles, fEndStep)\n *\n * @this {CPUPDP10}\n * @param {number} nCycles\n * @param {boolean} [fEndStep]\n */\n addCycles(nCycles, fEndStep)\n {\n this.nTotalCycles += nCycles;\n if (fEndStep) {\n this.nBurstCycles = this.nStepCycles = this.nSnapCycles = 0;\n }\n }\n\n /**\n * calcCycles(fRecalc)\n *\n * Calculate the number of cycles to process for each \"burst\" of CPU activity. The size of a burst\n * is driven by YIELDS_PER_SECOND (eg, 30).\n *\n * At the end of each burst, we subtract burst cycles from the yield cycle \"threshold\" counter.\n * Whenever the \"next yield\" cycle counter goes to (or below) zero, we compare elapsed time to the time\n * we expected the virtual hardware to take (eg, 1000ms/50 or 20ms), and if we still have time remaining,\n * we sleep the remaining time (or 0ms if there's no remaining time), and then restart runCPU().\n *\n * @this {CPUPDP10}\n * @param {boolean} [fRecalc] is true if the caller wants to recalculate thresholds based on the most recent\n * speed calculation (see calcSpeed).\n */\n calcCycles(fRecalc)\n {\n /*\n * Calculate \"per\" yield values.\n */\n var vMultiplier = 1;\n if (fRecalc) {\n if (this.nCyclesMultiplier > 1 && this.mhz) {\n vMultiplier = (this.mhz / this.mhzDefault);\n }\n }\n\n this.msPerYield = Math.round(1000 / CPUPDP10.YIELDS_PER_SECOND);\n this.nCyclesPerYield = Math.floor(this.nCyclesPerSecond / CPUPDP10.YIELDS_PER_SECOND * vMultiplier);\n\n /*\n * And initialize \"next\" yield values to the \"per\" values.\n */\n if (!fRecalc) this.nCyclesNextYield = this.nCyclesPerYield;\n this.nCyclesRecalc = 0;\n }\n\n /**\n * getCycles(fScaled)\n *\n * getCycles() returns the number of cycles executed so far. Note that we can be called after\n * runCPU() OR during runCPU(), perhaps from a handler triggered during the current run's stepCPU(),\n * so nRunCycles must always be adjusted by number of cycles stepCPU() was asked to run (nBurstCycles),\n * less the number of cycles it has yet to run (nStepCycles).\n *\n * nRunCycles is zeroed whenever the CPU is halted or the CPU speed is changed, which is why we also\n * have nTotalCycles, which accumulates all nRunCycles before we zero it. However, nRunCycles and\n * nTotalCycles eventually get reset by calcSpeed(), to avoid overflow, so components that rely on\n * getCycles() returning steadily increasing values should also be prepared for a reset at any time.\n *\n * @this {CPUPDP10}\n * @param {boolean} [fScaled] is true if the caller wants a cycle count relative to a multiplier of 1\n * @return {number}\n */\n getCycles(fScaled)\n {\n var nCycles = this.nTotalCycles + this.nRunCycles + this.nBurstCycles - this.nStepCycles;\n if (fScaled && this.nCyclesMultiplier > 1 && this.mhz > this.mhzDefault) {\n /*\n * We could scale the current cycle count by the current effective speed (this.mhz); eg:\n *\n * nCycles = Math.round(nCycles / (this.mhz / this.mhzDefault));\n *\n * but that speed will fluctuate somewhat: large fluctuations at first, but increasingly smaller\n * fluctuations after each burst of instructions that runCPU() executes.\n *\n * Alternatively, we can scale the cycle count by the multiplier, which is good in that the\n * multiplier doesn't vary once the user changes it, but a potential downside is that the\n * multiplier might be set too high, resulting in a target speed that's higher than the effective\n * speed is able to reach.\n *\n * Also, if multipliers were always limited to a power-of-two, then this could be calculated\n * with a simple shift. However, only the \"setSpeed\" UI binding limits it that way; the Debugger\n * interface allows any value, as does the CPU \"multiplier\" parmsCPU property (from the machine's\n * XML file).\n */\n nCycles = Math.round(nCycles / this.nCyclesMultiplier);\n }\n return nCycles;\n }\n\n /**\n * getCyclesPerSecond()\n *\n * This returns the CPU's \"base\" speed (ie, the original cycles per second defined for the machine)\n *\n * @this {CPUPDP10}\n * @return {number}\n */\n getCyclesPerSecond()\n {\n return this.nCyclesPerSecond;\n }\n\n /**\n * resetCycles()\n *\n * Resets speed and cycle information as part of any reset() or restore(); this typically occurs during powerUp().\n * It's important that this be called BEFORE the actual restore() call, because restore() may want to call setSpeed(),\n * which in turn assumes that all the cycle counts have been initialized to sensible values.\n *\n * @this {CPUPDP10}\n */\n resetCycles()\n {\n this.mhz = 0;\n this.nYieldsSinceStatusUpdate = 0;\n this.nTotalCycles = this.nRunCycles = this.nBurstCycles = this.nStepCycles = this.nSnapCycles = 0;\n this.resetChecksum();\n this.setSpeed(1);\n }\n\n /**\n * getSpeed()\n *\n * @this {CPUPDP10}\n * @return {number} the current speed multiplier\n */\n getSpeed()\n {\n return this.nCyclesMultiplier;\n }\n\n /**\n * getSpeedCurrent()\n *\n * @this {CPUPDP10}\n * @return {string} the current speed, in mhz, as a string formatted to two decimal places\n */\n getSpeedCurrent()\n {\n /*\n * TODO: Has toFixed() been \"fixed\" in all browsers (eg, IE) to return a rounded value now?\n */\n return ((this.flags.running)? (this.mhz.toFixed(2) + \"Mhz\") : \"Stopped\");\n }\n\n /**\n * getSpeedTarget()\n *\n * @this {CPUPDP10}\n * @return {string} the target speed, in mhz, as a string formatted to two decimal places\n */\n getSpeedTarget()\n {\n /*\n * TODO: Has toFixed() been \"fixed\" in all browsers (eg, IE) to return a rounded value now?\n */\n return this.mhzTarget.toFixed(2) + \"Mhz\";\n }\n\n /**\n * setSpeed(nMultiplier, fUpdateFocus)\n *\n * NOTE: This used to return the target speed, in mhz, but no callers appear to care at this point.\n *\n * @desc Whenever the speed is changed, the running cycle count and corresponding start time must be reset,\n * so that the next effective speed calculation obtains sensible results. In fact, when runCPU() initially calls\n * setSpeed() with no parameters, that's all this function does (it doesn't change the current speed setting).\n *\n * @this {CPUPDP10}\n * @param {number} [nMultiplier] is the new proposed multiplier (reverts to 1 if the target was too high)\n * @param {boolean} [fUpdateFocus] is true to update Computer focus\n * @return {boolean} true if successful, false if not\n */\n setSpeed(nMultiplier, fUpdateFocus)\n {\n var fSuccess = false;\n if (nMultiplier !== undefined) {\n /*\n * If we haven't reached 80% (0.8) of the current target speed, revert to a multiplier of one (1).\n */\n if (this.mhz / this.mhzTarget < 0.8) {\n nMultiplier = 1;\n } else {\n fSuccess = true;\n }\n this.nCyclesMultiplier = nMultiplier;\n var mhz = this.mhzDefault * this.nCyclesMultiplier;\n if (this.mhzTarget != mhz) {\n this.mhzTarget = mhz;\n var sSpeed = this.getSpeedTarget();\n var controlSpeed = this.bindings[\"setSpeed\"];\n if (controlSpeed) controlSpeed.textContent = sSpeed;\n this.println(\"target speed: \" + sSpeed);\n }\n if (fUpdateFocus && this.cmp) this.cmp.setFocus();\n }\n this.addCycles(this.nRunCycles);\n this.nRunCycles = 0;\n this.msStartRun = Component.getTime();\n this.msEndThisRun = 0;\n this.calcCycles();\n return fSuccess;\n }\n\n /**\n * calcSpeed(nCycles, msElapsed)\n *\n * @this {CPUPDP10}\n * @param {number} nCycles\n * @param {number} msElapsed\n */\n calcSpeed(nCycles, msElapsed)\n {\n if (msElapsed) {\n this.mhz = Math.round(nCycles / (msElapsed * 10)) / 100;\n if (msElapsed >= 86400000) {\n this.nTotalCycles = 0;\n this.setSpeed(); // reset all counters once per day so that we never have to worry about overflow\n }\n }\n }\n\n /**\n * calcStartTime()\n *\n * @this {CPUPDP10}\n */\n calcStartTime()\n {\n if (this.nCyclesRecalc >= this.nCyclesPerSecond) {\n this.calcCycles(true);\n }\n this.nCyclesThisRun = 0;\n this.msStartThisRun = Component.getTime();\n\n /*\n * Try to detect situations where the browser may have throttled us, such as when the user switches\n * to a different tab; in those situations, Chrome and Safari may restrict setTimeout() callbacks\n * to roughly one per second.\n *\n * Another scenario: the user resizes the browser window. setTimeout() callbacks are not throttled,\n * but there can still be enough of a lag between the callbacks that CPU speed will be noticeably\n * erratic if we don't compensate for it here.\n *\n * We can detect throttling/lagging by verifying that msEndThisRun (which was set at the end of the\n * previous run and includes any requested sleep time) is comparable to the current msStartThisRun;\n * if the delta is significant, we compensate by bumping msStartRun forward by that delta.\n *\n * This shouldn't be triggered when the Debugger halts the CPU, because setSpeed() -- which is called\n * whenever the CPU starts running again -- zeroes msEndThisRun.\n *\n * This also won't do anything about other internal delays; for example, Debugger message() calls.\n * By the time the message() function has called yieldCPU(), the cost of the message has already been\n * incurred, so it will be end up being charged against the instruction(s) that triggered it.\n *\n * TODO: Consider calling yieldCPU() sooner from message(), so that it can arrange for the msEndThisRun\n * \"snapshot\" to occur sooner; it's unclear, however, whether that will really improve the CPU's ability\n * to hit its target speed, since you would expect any instruction that displays a message to be an\n * EXTREMELY slow instruction.\n */\n if (this.msEndThisRun) {\n var msDelta = this.msStartThisRun - this.msEndThisRun;\n if (msDelta > this.msPerYield) {\n if (MAXDEBUG) this.println(\"large time delay: \" + msDelta + \"ms\");\n this.msStartRun += msDelta;\n /*\n * Bumping msStartRun forward should NEVER cause it to exceed msStartThisRun; however, just\n * in case, I make absolutely sure it cannot happen, since doing so could result in negative\n * speed calculations.\n */\n\n if (this.msStartRun > this.msStartThisRun) {\n this.msStartRun = this.msStartThisRun;\n }\n }\n }\n }\n\n /**\n * calcRemainingTime()\n *\n * @this {CPUPDP10}\n * @return {number}\n */\n calcRemainingTime()\n {\n this.msEndThisRun = Component.getTime();\n\n var msYield = this.msPerYield;\n if (this.nCyclesThisRun) {\n /*\n * Normally, we would assume we executed a full quota of work over msPerYield, but since the CPU\n * now has the option of calling yieldCPU(), that might not be true. If nCyclesThisRun is correct, then\n * the ratio of nCyclesThisRun/nCyclesPerYield should represent the percentage of work we performed,\n * and so applying that percentage to msPerYield should give us a better estimate of work vs. time.\n */\n msYield = Math.round(msYield * this.nCyclesThisRun / this.nCyclesPerYield);\n }\n\n var msElapsedThisRun = this.msEndThisRun - this.msStartThisRun;\n var msRemainsThisRun = msYield - msElapsedThisRun;\n\n /*\n * We could pass only \"this run\" results to calcSpeed():\n *\n * nCycles = this.nCyclesThisRun;\n * msElapsed = msElapsedThisRun;\n *\n * but it seems preferable to use longer time periods and hopefully get a more accurate speed.\n *\n * Also, if msRemainsThisRun >= 0 && this.nCyclesMultiplier == 1, we could pass these results instead:\n *\n * nCycles = this.nCyclesThisRun;\n * msElapsed = this.msPerYield;\n *\n * to insure that we display a smooth, constant N Mhz. But for now, I prefer seeing any fluctuations.\n */\n var nCycles = this.nRunCycles;\n var msElapsed = this.msEndThisRun - this.msStartRun;\n\n if (MAXDEBUG && msRemainsThisRun < 0 && this.nCyclesMultiplier > 1) {\n this.println(\"warning: updates @\" + msElapsedThisRun + \"ms (prefer \" + Math.round(msYield) + \"ms)\");\n }\n\n this.calcSpeed(nCycles, msElapsed);\n\n if (msRemainsThisRun < 0 || this.mhz < this.mhzTarget) {\n /*\n * Try \"throwing out\" the effects of large anomalies, by moving the overall run start time up;\n * ordinarily, this should only happen when the someone is using an external Debugger or some other\n * tool or feature that is interfering with our overall execution.\n */\n if (msRemainsThisRun < -1000) {\n this.msStartRun -= msRemainsThisRun;\n }\n /*\n * If the last burst took MORE time than we allotted (ie, it's taking more than 1 second to simulate\n * nCyclesPerSecond), all we can do is yield for as little time as possible (ie, 0ms) and hope that the\n * simulation is at least usable.\n */\n msRemainsThisRun = 0;\n }\n\n /*\n * Last but not least, update nCyclesRecalc, so that when runCPU() starts up again and calls calcStartTime(),\n * it'll be ready to decide if calcCycles() should be called again.\n */\n this.nCyclesRecalc += this.nCyclesThisRun;\n\n if (DEBUG && this.messageEnabled(MessagesPDP10.LOG) && msRemainsThisRun) {\n this.log(\"calcRemainingTime: \" + msRemainsThisRun + \"ms to sleep after \" + this.msEndThisRun + \"ms\");\n }\n\n this.msEndThisRun += msRemainsThisRun;\n return msRemainsThisRun;\n }\n\n /**\n * addTimer(callBack)\n *\n * Components that want to have timers that periodically fire after some number of milliseconds call\n * addTimer() to create the timer, and then setTimer() every time they want to arm it. There is currently\n * no removeTimer() because these are generally used for the entire lifetime of a component.\n *\n * Internally, each timer entry is a preallocated Array with two entries: a cycle countdown in element [0]\n * and a callback function in element [1]. A timer is initially dormant; dormant timers have a countdown\n * value of -1 (although any negative number will suffice) and active timers have a non-negative value.\n *\n * Why not use JavaScript's setTimeout() instead? Good question. For a good answer, see setTimer() below.\n *\n * TODO: Consider making the addTimer() and setTimer() interfaces more like the addIRQ() and setIRQ()\n * interfaces (which return the underlying object instead of an array index) and maintaining a separate list\n * of active timers, in order of highest to lowest cycle countdown values, as this could speed up\n * getBurstCycles() and updateTimers() functions ever so slightly.\n *\n * @this {CPUPDP10}\n * @param {function()} callBack\n * @return {number} timer index\n */\n addTimer(callBack)\n {\n var iTimer = this.aTimers.length;\n this.aTimers.push([-1, callBack]);\n return iTimer;\n }\n\n /**\n * setTimer(iTimer, ms, fReset)\n *\n * Using the timer index from a previous addTimer() call, this sets that timer to fire after the\n * specified number of milliseconds.\n *\n * This is preferred over JavaScript's setTimeout(), because all our timers are effectively paused when\n * the CPU is paused (eg, when the Debugger halts execution). Moreover, setTimeout() handlers only run after\n * runCPU() yields, which is far too granular for some components (eg, when the SerialPort tries to simulate\n * interrupts at 9600 baud).\n *\n * Ideally, the only function that would use setTimeout() is runCPU(), while the rest of the components\n * use setTimer(); however, due to legacy code (ie, code that predates these functions) and/or laziness,\n * that may not be the case.\n *\n * @this {CPUPDP10}\n * @param {number} iTimer\n * @param {number} ms (converted into a cycle countdown internally)\n * @param {boolean} [fReset] (true if the timer should be reset even if already armed)\n * @return {number} (number of cycles used to arm timer, or -1 if error)\n */\n setTimer(iTimer, ms, fReset)\n {\n var nCycles = -1;\n if (iTimer >= 0 && iTimer < this.aTimers.length) {\n if (fReset || this.aTimers[iTimer][0] < 0) {\n nCycles = this.getMSCycles(ms);\n /*\n * We must now confront the following problem: if the CPU is currently executing a burst of cycles,\n * the number of cycles it has executed in that burst so far must NOT be charged against the cycle\n * timeout we're about to set. The simplest way to resolve that is to immediately call endBurst()\n * and bias the cycle timeout by the number of cycles that the burst executed.\n */\n if (this.flags.running) {\n nCycles += this.endBurst();\n }\n this.aTimers[iTimer][0] = nCycles;\n }\n }\n return nCycles;\n }\n\n /**\n * getMSCycles(ms)\n *\n * @this {CPUPDP10}\n * @param {number} ms\n * @return {number} number of corresponding cycles\n */\n getMSCycles(ms)\n {\n return ((this.nCyclesPerSecond * this.nCyclesMultiplier) / 1000 * ms)|0;\n }\n\n /**\n * getBurstCycles(nCycles)\n *\n * Used by runCPU() to get min(nCycles,[timer cycle counts])\n *\n * @this {CPUPDP10}\n * @param {number} nCycles (number of cycles about to execute)\n * @return {number} (either nCycles or less if a timer needs to fire)\n */\n getBurstCycles(nCycles)\n {\n for (var i = this.aTimers.length - 1; i >= 0; i--) {\n var timer = this.aTimers[i];\n\n if (timer[0] < 0) continue;\n if (nCycles > timer[0]) {\n nCycles = timer[0];\n }\n }\n return nCycles;\n }\n\n /**\n * saveTimers()\n *\n * @this {CPUPDP10}\n * @return {Array.<number>}\n */\n saveTimers()\n {\n var aTimerCycles = [];\n for (var i = 0; i < this.aTimers.length; i++) {\n var timer = this.aTimers[i];\n aTimerCycles.push(timer[0]);\n }\n return aTimerCycles;\n }\n\n /**\n * restoreTimers(aTimerCycles)\n *\n * @this {CPUPDP10}\n * @param {Array.<number>} aTimerCycles\n */\n restoreTimers(aTimerCycles)\n {\n\n for (var i = 0; i < this.aTimers.length && i < aTimerCycles.length; i++) {\n var timer = this.aTimers[i];\n timer[0] = aTimerCycles[i];\n }\n }\n\n /**\n * updateTimers(nCycles)\n *\n * Used by runCPU() to reduce all active timer countdown values by the number of cycles just executed;\n * this is the function that actually \"fires\" any timer(s) whose countdown has reached (or dropped below)\n * zero, invoking their callback function.\n *\n * @this {CPUPDP10}\n * @param {number} nCycles (number of cycles actually executed)\n */\n updateTimers(nCycles)\n {\n for (var i = this.aTimers.length - 1; i >= 0; i--) {\n var timer = this.aTimers[i];\n\n if (timer[0] < 0) continue;\n timer[0] -= nCycles;\n if (timer[0] <= 0) {\n timer[0] = -1; // zero is technically an \"active\" value, so ensure the timer is dormant now\n timer[1](); // safe to invoke the callback function now\n }\n }\n }\n\n /**\n * endBurst(fReset)\n *\n * @this {CPUPDP10}\n * @param {boolean} [fReset]\n * @return {number} (number of cycles executed in the most recent burst)\n */\n endBurst(fReset)\n {\n var nCycles = this.nBurstCycles -= this.nStepCycles;\n /*\n * In addition to zeroing nStepCycles, it's important that we also zero nSnapCycles, because if a CPU\n * burst is being ended after nStepCycles has been \"snapped\" (because a certain opcode has an unusual timing\n * calculation that must be based on a \"snapped\" cycle count rather the opcode's starting cycle count), we\n * could inadvertently undo the endBurst() if the original \"snapped\" value was used to update nStepCycles.\n */\n this.nStepCycles = this.nSnapCycles = 0;\n if (fReset) this.nBurstCycles = 0;\n return nCycles;\n }\n\n /**\n * runCPU()\n *\n * @this {CPUPDP10}\n */\n runCPU()\n {\n if (!this.flags.running) return;\n\n /*\n * calcStartTime() initializes the cycle counter and timestamp for this runCPU() invocation, and optionally\n * recalculates the the maximum number of cycles for each burst if the nCyclesRecalc threshold has been reached.\n */\n this.calcStartTime();\n\n try {\n do {\n /*\n * nCycles is how many cycles we WANT to run on each iteration of stepCPU(), and may be as\n * HIGH as nCyclesPerYield, but it may be significantly less. getBurstCycles() will adjust\n * nCycles downward if any CPU timers need to fire during the next burst.\n */\n var nCycles = this.getBurstCycles(this.flags.checksum? 1 : this.nCyclesPerYield);\n\n /*\n * Execute the burst.\n */\n try {\n this.stepCPU(nCycles);\n }\n catch(exception) {\n /*\n * We assume that any numeric exception was explicitly thrown by the CPU to interrupt the\n * current instruction (and by extension, the current burst, but not the current run). All\n * other exceptions are re-thrown to the catch below, which will attempt a stack dump.\n */\n if (typeof exception != \"number\") throw exception;\n }\n\n /*\n * Terminate the burst, returning the number of cycles that stepCPU() actually ran.\n */\n nCycles = this.endBurst(true);\n\n /*\n * Add nCycles to nCyclesThisRun, as well as nRunCycles (the cycle count since the CPU started).\n */\n this.nCyclesThisRun += nCycles;\n this.nRunCycles += nCycles;\n this.updateChecksum(nCycles);\n\n /*\n * Update any/all timers, firing those whose cycle countdowns have reached (or dropped below) zero.\n */\n this.updateTimers(nCycles);\n\n this.nCyclesNextYield -= nCycles;\n if (this.nCyclesNextYield <= 0) {\n this.nCyclesNextYield += this.nCyclesPerYield;\n if (++this.nYieldsSinceStatusUpdate >= CPUPDP10.YIELDS_PER_STATUS) {\n this.updateDisplays();\n this.nYieldsSinceStatusUpdate = 0;\n }\n break;\n }\n } while (this.flags.running);\n }\n catch (e) {\n this.stopCPU();\n if (this.cmp) this.cmp.stop(Component.getTime(), this.getCycles());\n this.setError(e.stack || e.message);\n return;\n }\n\n if (this.flags.running) setTimeout(this.onRunTimeout, this.calcRemainingTime());\n }\n\n /**\n * startCPU(fUpdateFocus)\n *\n * For use by any component that wants to start the CPU.\n *\n * @param {boolean} [fUpdateFocus]\n * @return {boolean}\n */\n startCPU(fUpdateFocus)\n {\n if (this.isError()) {\n return false;\n }\n if (this.flags.running) {\n this.println(this.toString() + \" busy\");\n return false;\n }\n /*\n * setSpeed() without a speed parameter leaves the selected speed in place, but also resets the\n * cycle counter and timestamp for the current series of runCPU() calls, calculates the maximum number\n * of cycles for each burst based on the last known effective CPU speed, and resets the nCyclesRecalc\n * threshold counter.\n */\n this.setSpeed();\n this.flags.running = true;\n this.flags.starting = true;\n var controlRun = this.bindings[\"run\"];\n if (controlRun) controlRun.textContent = \"Halt\";\n if (this.cmp) {\n if (fUpdateFocus) this.cmp.setFocus(true);\n this.cmp.start(this.msStartRun, this.getCycles());\n }\n if (!this.dbg) this.status(\"Started\");\n setTimeout(this.onRunTimeout, 0);\n return true;\n }\n\n /**\n * stepCPU(nMinCycles)\n *\n * This will be implemented by the CPUStatePDP10 component.\n *\n * @this {CPUPDP10}\n * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored)\n * @return {number} of cycles executed; 0 indicates that the last instruction was not executed\n */\n stepCPU(nMinCycles)\n {\n return 0;\n }\n\n /**\n * stopCPU(fComplete)\n *\n * For use by any component that wants to stop the CPU.\n *\n * This similar to yieldCPU(), but it doesn't need to zero nCyclesNextYield to break out of runCPU();\n * it simply needs to clear fRunning (well, \"simply\" may be oversimplifying a bit....)\n *\n * @this {CPUPDP10}\n * @param {boolean} [fComplete]\n * @return {boolean} true if the CPU was stopped, false if it was already stopped\n */\n stopCPU(fComplete)\n {\n var fStopped = false;\n if (this.flags.running) {\n this.endBurst();\n this.addCycles(this.nRunCycles);\n this.nRunCycles = 0;\n this.flags.running = false;\n var controlRun = this.bindings[\"run\"];\n if (controlRun) controlRun.textContent = \"Run\";\n if (this.cmp) {\n this.cmp.stop(Component.getTime(), this.getCycles());\n }\n fStopped = true;\n if (!this.dbg) this.status(\"Stopped\");\n }\n this.flags.complete = fComplete;\n return fStopped;\n }\n\n /**\n * yieldCPU()\n *\n * Similar to stopCPU() with regard to how it resets various cycle countdown values, but the CPU\n * remains in a \"running\" state.\n *\n * @this {CPUPDP10}\n */\n yieldCPU()\n {\n this.endBurst(); // this will break us out of stepCPU()\n this.nCyclesNextYield = 0; // this will break us out of runCPU(), once we break out of stepCPU()\n /*\n * The Debugger calls yieldCPU() after every message() to ensure browser responsiveness, but it looks\n * odd for those messages to show CPU state changes if the Control Panel, Video display, etc, does not,\n * so I've added this call to try to keep things looking synchronized.\n */\n this.updateDisplays();\n }\n}\n\n/*\n * Constants that control the frequency at which various updates should occur.\n *\n * These values do NOT control the simulation directly. Instead, they are used by\n * calcCycles(), which uses the nCyclesPerSecond passed to the constructor as a starting\n * point and computes the following variables:\n *\n * this.nCyclesPerYield: (this.nCyclesPerSecond / CPUPDP10.YIELDS_PER_SECOND)\n *\n * The above variables are also multiplied by any cycle multiplier in effect, via setSpeed(),\n * and then they're used to initialize another set of variables for each runCPU() iteration:\n *\n * this.nCyclesNextYield: this.nCyclesPerYield\n */\nCPUPDP10.YIELDS_PER_SECOND = 30; // just a gut feeling for the MINIMUM number of yields per second\nCPUPDP10.YIELDS_PER_STATUS = 15; // every 15 yields (ie, twice per second), perform CPU status updates\n\nCPUPDP10.BUTTONS = [\"power\", \"reset\"];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/cpustate.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * Overview of Device Interrupt Support\n *\n * Originally, the CPU maintained a queue of requested interrupts. Entries in this queue recorded a device's\n * priority, vector, and delay (ie, a number of instructions to execute before dispatching the interrupt). This\n * queue would constantly grow and shrink as requests were issued and dispatched, and as long as there was something\n * in the queue, the CPU was constantly examining it.\n *\n * Now we are trying something more efficient. First, for devices that require delays (like the SerialPort's receiver\n * and transmitter buffer registers, which are supposed to \"clock\" the data in and out at a specific baud rate), the\n * CPU offers timer services that will \"fire\" a callback after a specified delay, which are much more efficient than\n * requiring the CPU to dive into an interrupt queue and decrement delay counts on every instruction.\n *\n * Second, devices that generate interrupts will allocate an IRQ object during initialization; we will no longer\n * be creating and destroying interrupt event objects and inserting/deleting them in a constantly changing queue.\n * Each IRQ contains properties that never change (eg, the vector and priority), along with a \"next\" pointer that's\n * only used when the IRQ is active.\n *\n * When a device decides it's time to interrupt (either at the end of some I/O operation or when a timer has fired),\n * it will simply set the IRQ, which basically means that the IRQ will be linked onto a list of active IRQs, in\n * priority order, so that when the CPU is ready to acknowledge interrupts, it need only check the top of the active\n * IRQ list.\n */\n\n/**\n * @typedef {{\n * vector: number,\n * priority: number,\n * message: number,\n * name: (string|null),\n * next: (IRQ|null)\n * }}\n */\nvar IRQ;\n\n/**\n * @class CPUStatePDP10\n * @unrestricted\n */\nclass CPUStatePDP10 extends CPUPDP10 {\n /**\n * CPUStatePDP10(parmsCPU)\n *\n * The CPUStatePDP10 class uses the following (parmsCPU) properties:\n *\n * model: a number (eg, 1001) that should match one of the PDP10.MODEL_* values\n * addrReset: reset address (default is 0)\n *\n * This extends the CPU class and passes any remaining parmsCPU properties to the CPU class\n * constructor, along with a default speed (cycles per second) based on the specified (or default)\n * CPU model number.\n *\n * Speeds are highly instruction-specific and are not broken down into cycles; DEC documents them\n * as a number of microseconds, with two decimal places of accuracy. The simplest instructions\n * execute in 1-3us, a number of others require 5-6us, and the most time-consuming take anywhere\n * from 10us (MUL) to 17us (DIV). Of course, instructions that perform multiple indirect memory\n * accesses take even longer.\n *\n * I think we'll just say that the original PDP-10 was roughly a 1Mhz machine, and pretend that all\n * instructions completed in 1 or more multiples of a microsecond. I'm not sure that trying to be\n * accurate to the nearest 1/100 of a microsecond would have much observable benefit.\n *\n * @param {Object} parmsCPU\n */\n constructor(parmsCPU)\n {\n var nCyclesDefault = 0;\n var model = +parmsCPU['model'] || PDP10.MODEL_KA10;\n\n switch(model) {\n case PDP10.MODEL_KA10:\n default:\n nCyclesDefault = 1000000;\n break;\n }\n\n /*\n * ES6 ALERT: Classes cannot access \"this\" until all superclasses have been initialized as well.\n */\n super(parmsCPU, nCyclesDefault);\n\n this.model = model;\n this.addrReset = +parmsCPU['addrReset'] || 0;\n\n this.opDecode = PDP10.opKA10.bind(this);\n this.opUndefined = PDP10.opUndefined.bind(this);\n\n /** @type {IRQ|null} */\n this.irqNext = null; // the head of the active IRQ list, in priority order\n\n /** @type {Array.<IRQ>} */\n this.aIRQs = []; // list of all IRQs, active or not (to be used for auto-configuration)\n\n this.flags.complete = false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * Called once the Bus has been initialized.\n *\n * @this {CPUStatePDP10}\n * @param {ComputerPDP10} cmp\n * @param {BusPDP10} bus\n * @param {CPUPDP10} cpu\n * @param {DebuggerPDP10} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n super.initBus(cmp, bus, cpu, dbg);\n }\n\n /**\n * reset()\n *\n * @this {CPUStatePDP10}\n */\n reset()\n {\n this.status(\"Model \" + this.model);\n if (this.flags.running) this.stopCPU();\n this.initCPU();\n this.resetCycles();\n this.clearError(); // clear any fatal error/exception that setError() may have flagged\n super.reset();\n }\n\n /**\n * initCPU()\n *\n * @this {CPUStatePDP10}\n */\n initCPU()\n {\n /*\n * regEA is the last effective address, while regLA is the last fetch from an effective address\n * calculation. regRA is the last reference address used to calculate the last effective address.\n */\n this.regEA = this.regRA = 0;\n this.regLA = this.regOP = 0;\n this.regPC = this.lastPC = this.addrReset;\n this.regXC = -1; // if >= 0 this supersedes regPC (refers to an opcode from XCT)\n this.regBP = -1; // active byte pointer (-1 if none)\n this.regPS = 0; // assorted processor flags (see PSFLAG bit definitions)\n this.regEX = 0; // internal \"extension\" register used for 72-bit MUL and DIV calculations\n\n this.regRes = [0, 0]; // four internal \"double-length\" registers used for 72-bit DIV calculations\n this.regPow = [0, 0];\n this.regDiv = [0, 0];\n this.regRem = [0, 0];\n\n /*\n * This is queried and displayed by the Panel when it's not displaying its own ADDRESS register\n * (which takes precedence when, for example, you've manually halted the CPU and are independently\n * examining the contents of other addresses).\n *\n * We initialize it to the current PC.\n */\n this.addrLast = this.regPC;\n\n /*\n * opFlags contains various conditions that stepCPU() needs to be aware of.\n */\n this.opFlags = 0;\n\n this.setMemoryAccess();\n\n this.resetIRQs();\n }\n\n /**\n * setMemoryAccess()\n *\n * @this {CPUStatePDP10}\n */\n setMemoryAccess()\n {\n this.readWord = this.readWordFromPhysical;\n this.writeWord = this.writeWordToPhysical;\n }\n\n /**\n * setReset(addr, fStart, bUnit, addrStack)\n *\n * @this {CPUStatePDP10}\n * @param {number} addr\n * @param {boolean} [fStart] (true if a \"startable\" image was just loaded, false if not)\n * @param {number} [bUnit] (boot unit #)\n * @param {number} [addrStack]\n */\n setReset(addr, fStart, bUnit, addrStack)\n {\n this.addrReset = addr;\n\n this.setPC(addr);\n\n if (fStart) {\n if (!this.flags.powered) {\n this.flags.autoStart = true;\n }\n else if (!this.flags.running) {\n this.startCPU();\n }\n }\n else {\n if (this.dbg && this.flags.powered) {\n /*\n * TODO: Review the decision to always stop the CPU if the Debugger is loaded. Note that\n * when stopCPU() stops a running CPU, the Debugger gets notified, so no need to notify it again.\n *\n * TODO: There are more serious problems to deal with if another component is slamming a new PC down\n * the CPU's throat (presumably while also dropping some new code into RAM) while the CPU is running;\n * we should probably force a complete reset, but for now, it's up to the user to hit the reset button\n * themselves.\n */\n if (!this.stopCPU() && !this.cmp.flags.reset) {\n this.dbg.updateStatus();\n this.cmp.updateDisplays(-1);\n }\n }\n else if (fStart === false) {\n this.stopCPU();\n }\n }\n if (!this.isRunning() && this.panel) this.panel.stop();\n }\n\n /**\n * getChecksum()\n *\n * TODO: Implement\n *\n * @this {CPUStatePDP10}\n * @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code)\n */\n getChecksum()\n {\n return 0;\n }\n\n /**\n * save()\n *\n * @this {CPUStatePDP10}\n * @return {Object|null}\n */\n save()\n {\n var state = new State(this);\n state.set(0, [\n this.regEA,\n this.regRA,\n this.regLA,\n this.regOP,\n this.regPC,\n this.regXC,\n this.regBP,\n this.regPS,\n this.opFlags,\n this.lastPC,\n this.addrLast,\n this.addrReset\n ]);\n state.set(1, []);\n state.set(2, [this.nTotalCycles, this.getSpeed(), this.flags.autoStart]);\n state.set(3, this.saveIRQs());\n state.set(4, this.saveTimers());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * @this {CPUStatePDP10}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n /*\n * ES6 ALERT: A handy destructuring assignment, which makes it easy to perform the inverse\n * of what save() does when it collects a bunch of object properties into an array.\n */\n [\n this.regEA,\n this.regRA,\n this.regLA,\n this.regOP,\n this.regPC,\n this.regXC,\n this.regBP,\n this.regPS,\n this.opFlags,\n this.lastPC,\n this.addrLast,\n this.addrReset\n ] = data[0];\n\n var a = data[2];\n this.nTotalCycles = a[0];\n this.setSpeed(a[1]);\n this.flags.autoStart = a[2];\n\n this.restoreIRQs(data[3]);\n this.restoreTimers(data[4]);\n return true;\n }\n\n /**\n * getPS()\n *\n * Gets the processor state flags in the format required by various program control operations (eg, JSP).\n *\n * @this {CPUStatePDP10}\n * @return {number}\n */\n getPS()\n {\n return (this.regPS & PDP10.HALF_MASK);\n }\n\n /**\n * setPS(w)\n *\n * Sets the processor state flags in the format required by various program control operations (eg, JRST).\n *\n * @this {CPUStatePDP10}\n * @param {number} w\n */\n setPS(w)\n {\n this.regPS = (this.regPS & ~PDP10.PSFLAG.SET_MASK) | (w & PDP10.PSFLAG.SET_MASK);\n this.regPS |= (w & PDP10.PSFLAG.USERF);\n if (!(w & PDP10.PSFLAG.EXIOT)) {\n this.regPS &= ~PDP10.PSFLAG.EXIOT;\n } else {\n if (!(this.regPS & PDP10.PSFLAG.USERF)) this.regPS |= PDP10.PSFLAG.EXIOT;\n }\n }\n\n /**\n * setUserMode()\n *\n * Sets the processor's USER_MODE flag.\n *\n * @this {CPUStatePDP10}\n */\n setUserMode()\n {\n this.regPS |= PDP10.PSFLAG.USERF;\n }\n\n /**\n * readFlags()\n *\n * Used to implement the \"\"CONI APR,\" instruction; see opCONI().\n *\n * @this {CPUStatePDP10}\n * @return {number}\n */\n readFlags()\n {\n var flags = 0;\n if (this.regPS & PDP10.PSFLAG.AROV) flags |= PDP10.RFLAG.AROV;\n if (this.regPS & PDP10.PSFLAG.PDOV) flags |= PDP10.RFLAG.PDOV;\n return flags;\n }\n\n /**\n * writeFlags(w)\n *\n * Used to implement the \"\"CONO APR,\" instruction; see opCONO().\n *\n * @this {CPUStatePDP10}\n * @param {number} w\n */\n writeFlags(w)\n {\n if (w & PDP10.WFLAG.AROV_CL) this.regPS &= ~PDP10.PSFLAG.AROV;\n if (w & PDP10.WFLAG.PDOV_CL) this.regPS &= ~PDP10.PSFLAG.PDOV;\n }\n\n /**\n * getOpcode()\n *\n * Normally, this fetches the next opcode in regOP, decodes the low 23 bits (I,X,Y), records\n * the effective address (E) in regEA, updates regPC, and returns the high 13 bits of the opcode\n * for further decoding.\n *\n * However, if a reference address (R) in regRA still needs to be decoded (due to indirection),\n * we take care of that first.\n *\n * @this {CPUStatePDP10}\n * @return {number} (-1 if the reference address in regRA has not yet been fully decoded)\n */\n getOpcode()\n {\n if ((this.regRA & PDP10.OPCODE.I_FIELD)) {\n this.regRA = this.regLA = this.readWord(this.regEA);\n } else if (this.regXC >= 0) {\n this.regRA = this.regOP = this.readWord(this.regXC);\n this.regXC = -1;\n } else {\n this.regRA = this.regOP = this.readWord(this.lastPC = this.regPC);\n this.regPC = (this.regPC + 1) % PDP10.ADDR_LIMIT;\n }\n\n /*\n * Technically, we don't REALLY need to mask regRA with R_MASK, because all regRA accesses\n * ignore any higher bits, but let's keep things tidy.\n */\n this.regRA &= PDP10.OPCODE.R_MASK;\n\n /*\n * Bits 0-22 (I,X,Y) contain what we call a \"reference address\" (R), which is used to calculate an\n * 18-bit \"effective address\" (E). To determine E from R, we must extract I, X, and Y from R, set E\n * to Y, then add [X] to E if X is non-zero. If I is zero, then we're done; otherwise, we must set R\n * to [E] and repeat the process.\n *\n * However, we don't actually repeat the process immediately; we need to treat each indirection as a\n * separate decoding step, to ensure that the emulator can \"breathe\" periodically. So instead, we\n * return -1, indicating that the opcode is not fully decoded, and then on the next call, instead of\n * fetching another opcode, we fetch [E], update R, and decode R again.\n */\n this.regEA = this.regRA & PDP10.OPCODE.Y_MASK;\n var x = (this.regRA >> PDP10.OPCODE.X_SHIFT) & PDP10.OPCODE.X_MASK;\n if (x) this.regEA = (this.regEA + (this.regLA = this.readWord(x))) & PDP10.ADDR_MASK;\n\n return (this.regRA & PDP10.OPCODE.I_FIELD)? -1 : ((this.regOP / PDP10.OPCODE.A_SCALE)|0);\n }\n\n /**\n * advancePC(off)\n *\n * NOTE: This function is nothing more than a convenience, and we fully expect it to be inlined at runtime.\n *\n * @this {CPUStatePDP10}\n * @param {number} off\n * @return {number} (original PC)\n */\n advancePC(off)\n {\n var pc = this.regPC;\n this.regPC = (pc + off) % PDP10.ADDR_LIMIT;\n return pc;\n }\n\n /**\n * getPC()\n *\n * NOTE: This function is nothing more than a convenience, and we fully expect it to be inlined at runtime.\n *\n * @this {CPUStatePDP10}\n * @return {number}\n */\n getPC()\n {\n return this.regPC;\n }\n\n /**\n * getXC()\n *\n * NOTE: This function is nothing more than a convenience, and we fully expect it to be inlined at runtime.\n *\n * @this {CPUStatePDP10}\n * @return {number}\n */\n getXC()\n {\n return this.regXC >= 0? this.regXC : ((this.regRA & PDP10.OPCODE.I_FIELD)? this.lastPC : this.regPC);\n }\n\n /**\n * getLastAddr()\n *\n * @this {CPUStatePDP10}\n * @return {number}\n */\n getLastAddr()\n {\n return this.addrLast;\n }\n\n /**\n * getLastPC()\n *\n * @this {CPUStatePDP10}\n * @return {number}\n */\n getLastPC()\n {\n return this.lastPC;\n }\n\n /**\n * setPC(addr)\n *\n * Updates the PC register with the new address after masking it with ADDR_LIMIT (in case the\n * new address was the result of an unchecked calculation).\n *\n * @this {CPUStatePDP10}\n * @param {number} addr\n */\n setPC(addr)\n {\n this.regRA = 0;\n this.regXC = -1;\n this.regPC = addr % PDP10.ADDR_LIMIT;\n }\n\n /**\n * addIRQ(vector, priority, message)\n *\n * @this {CPUStatePDP10}\n * @param {number} vector (-1 for floating vector)\n * @param {number} priority\n * @param {number} [message]\n * @return {IRQ}\n */\n addIRQ(vector, priority, message)\n {\n var irq = {vector: vector, priority: priority, message: message || 0, name: null, next: null};\n this.aIRQs.push(/** @type {IRQ} */ (irq)); // TODO: Why the F*CK do I need a type override? Damn JSDoc types....\n return irq;\n }\n\n /**\n * insertIRQ(irq)\n *\n * @this {CPUStatePDP10}\n * @param {IRQ} irq\n */\n insertIRQ(irq)\n {\n if (irq != this.irqNext) {\n var irqPrev = this.irqNext;\n if (!irqPrev || irqPrev.priority <= irq.priority) {\n irq.next = irqPrev;\n this.irqNext = irq;\n } else {\n do {\n var irqNext = irqPrev.next;\n if (!irqNext || irqNext.priority <= irq.priority) {\n irq.next = irqNext;\n irqPrev.next = irq;\n break;\n }\n irqPrev = irqNext;\n } while (irqPrev);\n }\n }\n /*\n * See the writeXCSR() function for an explanation of why signalling an IRQ hardware interrupt\n * should be done using IRQ_DELAY rather than setting IRQ directly.\n */\n this.opFlags |= PDP10.OPFLAG.IRQ_DELAY;\n }\n\n /**\n * removeIRQ(irq)\n *\n * @this {CPUStatePDP10}\n * @param {IRQ} irq\n */\n removeIRQ(irq)\n {\n var irqPrev = this.irqNext;\n if (irqPrev == irq) {\n this.irqNext = irq.next;\n } else {\n while (irqPrev) {\n var irqNext = irqPrev.next;\n if (irqNext == irq) {\n irqPrev.next = irqNext.next;\n break;\n }\n irqPrev = irqNext;\n }\n }\n /*\n * We could also set irq.next to null now, but strictly speaking, that shouldn't be necessary.\n *\n * Last but not least, if there's still an IRQ on the active IRQ list, we need to make sure IRQ_DELAY\n * is still set.\n */\n if (this.irqNext) {\n this.opFlags |= PDP10.OPFLAG.IRQ_DELAY;\n }\n }\n\n /**\n * setIRQ(irq)\n *\n * @this {CPUStatePDP10}\n * @param {IRQ|null} irq\n */\n setIRQ(irq)\n {\n if (irq) {\n this.insertIRQ(irq);\n if (irq.message && this.messageEnabled(irq.message | MessagesPDP10.INT)) {\n this.printMessage(\"setIRQ(vector=\" + Str.toOct(irq.vector) + \",priority=\" + irq.priority + \")\", true, true);\n }\n }\n }\n\n /**\n * clearIRQ(irq)\n *\n * @this {CPUStatePDP10}\n * @param {IRQ|null} irq\n */\n clearIRQ(irq)\n {\n if (irq) {\n this.removeIRQ(irq);\n if (irq.message && this.messageEnabled(irq.message | MessagesPDP10.INT)) {\n this.printMessage(\"clearIRQ(vector=\" + Str.toOct(irq.vector) + \",priority=\" + irq.priority + \")\", true, true);\n }\n }\n }\n\n /**\n * findIRQ(vector)\n *\n * @this {CPUStatePDP10}\n * @param {number} vector\n * @return {IRQ|null}\n */\n findIRQ(vector)\n {\n for (var i = 0; i < this.aIRQs.length; i++) {\n var irq = this.aIRQs[i];\n if (irq.vector === vector) return irq;\n }\n return null;\n }\n\n /**\n * checkIRQs(priority)\n *\n * @this {CPUStatePDP10}\n * @param {number} priority\n * @return {IRQ|null}\n */\n checkIRQs(priority)\n {\n return (this.irqNext && this.irqNext.priority > priority)? this.irqNext : null;\n }\n\n /**\n * resetIRQs(priority)\n *\n * @this {CPUStatePDP10}\n */\n resetIRQs()\n {\n this.irqNext = null;\n }\n\n /**\n * saveIRQs()\n *\n * @this {CPUStatePDP10}\n * @return {Array.<number>}\n */\n saveIRQs()\n {\n var aIRQVectors = [];\n var irq = this.irqNext;\n while (irq) {\n aIRQVectors.push(irq.vector);\n irq = irq.next;\n }\n return aIRQVectors;\n }\n\n /**\n * restoreIRQs(aIRQVectors)\n *\n * @this {CPUStatePDP10}\n * @param {Array.<number>} aIRQVectors\n */\n restoreIRQs(aIRQVectors)\n {\n for (var i = aIRQVectors.length - 1; i >= 0; i--) {\n var irq = this.findIRQ(aIRQVectors[i]);\n\n if (irq) {\n irq.next = this.irqNext;\n this.irqNext = irq;\n }\n }\n }\n\n /**\n * checkInterrupts()\n *\n * @this {CPUStatePDP10}\n * @return {boolean} true if an interrupt was dispatched, false if not\n */\n checkInterrupts()\n {\n var fInterrupt = false;\n\n if (this.opFlags & PDP10.OPFLAG.IRQ) {\n\n // var vector = PDP10.TRAP.PIRQ;\n // var priority = (this.regPIR & PDP10.PSW.PRI) >> PDP10.PSW.SHIFT.PRI;\n //\n // var irq = this.checkIRQs(priority);\n // if (irq) {\n // vector = irq.vector;\n // priority = irq.priority;\n // }\n //\n // if (this.dispatchInterrupt(vector, priority)) {\n // if (irq) this.removeIRQ(irq);\n // fInterrupt = true;\n // }\n\n if (!this.irqNext) {\n this.opFlags &= ~PDP10.OPFLAG.IRQ;\n }\n }\n else if (this.opFlags & PDP10.OPFLAG.IRQ_DELAY) {\n /*\n * We know that IRQ (bit 2) is clear, so since IRQ_DELAY (bit 0) is set, incrementing opFlags\n * will eventually transform IRQ_DELAY into IRQ, without affecting any other (higher) bits.\n */\n this.opFlags++;\n }\n return fInterrupt;\n }\n\n /**\n * dispatchInterrupt(vector, priority)\n *\n * TODO: The process of dispatching an interrupt MUST cost some cycles; either trap() needs to assess\n * that cost, or we do.\n *\n * @this {CPUStatePDP10}\n * @param {number} vector\n * @param {number} priority\n * @return {boolean} (true if dispatched, false if not)\n */\n dispatchInterrupt(vector, priority)\n {\n return false;\n }\n\n /**\n * isWaiting()\n *\n * @this {CPUStatePDP10}\n * @return {boolean} (true if OPFLAG.WAIT is set, false otherwise)\n */\n isWaiting()\n {\n return !!(this.opFlags & PDP10.OPFLAG.WAIT);\n }\n\n /**\n * readWordFromPhysical(addr)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through readWord().\n *\n * @this {CPUStatePDP10}\n * @param {number} addr\n * @return {number}\n */\n readWordFromPhysical(addr)\n {\n return this.bus.getWord(this.addrLast = addr);\n }\n\n /**\n * writeWordToPhysical(addr, data)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through writeWord().\n *\n * @this {CPUStatePDP10}\n * @param {number} addr\n * @param {number} data\n * @return {number} (we return the data back to the caller to permit nested writes)\n */\n writeWordToPhysical(addr, data)\n {\n this.bus.setWord(this.addrLast = addr, data);\n return data;\n }\n\n /**\n * haltCPU()\n *\n * This is a temporary helper function for the Bus component, to force the CPU to stop executing the\n * current instruction.\n *\n * @this {CPUStatePDP10}\n */\n haltCPU()\n {\n this.stopCPU();\n throw -1;\n }\n\n /**\n * stepCPU(nMinCycles)\n *\n * NOTE: Single-stepping should not be confused with the Trap flag; single-stepping is a Debugger\n * operation that's completely independent of Trap status. The CPU can go in and out of Trap mode,\n * in and out of h/w interrupt service routines (ISRs), etc, but from the Debugger's perspective,\n * they're all one continuous stream of instructions that can be stepped or run at will. Moreover,\n * stepping vs. running should never change the behavior of the simulation.\n *\n * @this {CPUStatePDP10}\n * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored)\n * @return {number} of cycles executed; 0 indicates a pre-execution condition (ie, an execution breakpoint\n * was hit), -1 indicates a post-execution condition (eg, a read or write breakpoint was hit), and a positive\n * number indicates successful completion of that many cycles (which should always be >= nMinCycles).\n */\n stepCPU(nMinCycles)\n {\n /*\n * The Debugger uses complete to determine if the instruction completed (true) or was interrupted\n * by a breakpoint or some other exceptional condition (false). NOTE: this does NOT include JavaScript\n * exceptions, which stepCPU() expects the caller to catch using its own exception handler.\n *\n * The CPU relies on the use of stopCPU() rather than complete, because the CPU never single-steps\n * (ie, nMinCycles is always some large number), whereas the Debugger does. And conversely, when the\n * Debugger is single-stepping (even when performing multiple single-steps), fRunning is never set,\n * so stopCPU() would have no effect as far as the Debugger is concerned.\n */\n this.flags.complete = true;\n\n /*\n * nDebugCheck is 1 if we want the Debugger's checkInstruction() to check every instruction,\n * -1 if we want it to check just the first instruction, and 0 if there's no need for any checks.\n */\n var nDebugCheck = (DEBUGGER && this.dbg)? (this.dbg.checksEnabled()? 1 : (this.flags.starting? -1 : 0)) : 0;\n\n /*\n * nDebugState is needed only when nDebugCheck is non-zero; it is -1 if this is a single-step, 0 if\n * this is the start of a new run, and 1 if this is a continuation of a previous run. It is used by\n * checkInstruction() to determine if it should skip breakpoint checks and/or HALT instructions (ie,\n * if nDebugState is <= zero).\n */\n var nDebugState = (!nMinCycles)? -1 : (this.flags.starting? 0 : 1);\n this.flags.starting = false; // we've moved beyond \"starting\" and have officially \"started\" now\n\n /*\n * We move the minimum cycle count to nStepCycles (the number of cycles left to step), so that other\n * functions have the ability to force that number to zero (eg, stopCPU()), and thus we don't have to check\n * any other criteria to determine whether we should continue stepping or not.\n */\n this.nBurstCycles = this.nStepCycles = nMinCycles;\n\n /*\n * And finally, move the nDebugCheck state to an OPFLAG bit, so that the loop need check only one variable.\n */\n this.opFlags = (this.opFlags & ~PDP10.OPFLAG.DEBUGGER) | (nDebugCheck? PDP10.OPFLAG.DEBUGGER : 0);\n\n do {\n if (this.opFlags) {\n /*\n * NOTE: We still check DEBUGGER to ensure that this code will be compiled out of existence in\n * non-DEBUGGER builds.\n */\n if (DEBUGGER && (this.opFlags & PDP10.OPFLAG.DEBUGGER)) {\n if (this.dbg.checkInstruction(this.getXC(), nDebugState)) {\n this.stopCPU();\n break;\n }\n if (!++nDebugCheck) this.opFlags &= ~PDP10.OPFLAG.DEBUGGER;\n if (!nDebugState) nDebugState++;\n }\n /*\n * If we're in the IRQ or WAIT state, check for any pending interrupts.\n *\n * NOTE: It's no coincidence that we're checking this BEFORE any pending traps, because in rare\n * cases (including some presented by those pesky \"TRAP TEST\" diagnostics), the process of dispatching\n * an interrupt can trigger a TRAP_SP stack overflow condition, which must be dealt with BEFORE we\n * execute the first instruction of the interrupt handler.\n */\n if ((this.opFlags & (PDP10.OPFLAG.IRQ_MASK | PDP10.OPFLAG.WAIT)) /* && nDebugState >= 0 */) {\n if (this.checkInterrupts()) {\n if ((this.opFlags & PDP10.OPFLAG.DEBUGGER) && this.dbg.checkInstruction(this.getXC(), nDebugState)) {\n this.stopCPU();\n break;\n }\n /*\n * Since an interrupt was just dispatched, altering the normal flow of time and changing\n * the future as we knew it, let's break out immediately if we're single-stepping, so that\n * the Debugger gets to see the first instruction of the interrupt handler. NOTE: This\n * assumes that we've still commented out the nDebugState check above that used to bypass\n * checkInterrupts() when single-stepping.\n */\n if (nDebugState < 0) break;\n }\n }\n }\n\n this.opFlags &= PDP10.OPFLAG.PRESERVE;\n\n var op = this.getOpcode();\n if (op >= 0) {\n this.opDecode(op);\n }\n /*\n * TODO: This is a temporary cycle charge, required for CPU operational bookkeeping until we add\n * correct cycle counts for all instructions.\n */\n this.nStepCycles--;\n\n } while (this.nStepCycles > 0);\n\n return (this.flags.complete? this.nBurstCycles - this.nStepCycles : (this.flags.complete === false? -1 : 0));\n }\n\n /**\n * CPUStatePDP10.init()\n *\n * This function operates on every HTML element of class \"cpu\", extracting the\n * JSON-encoded parameters for the CPUStatePDP10 constructor from the element's \"data-value\"\n * attribute, invoking the constructor (which in turn invokes the CPU constructor)\n * to create a CPUStatePDP10 component, and then binding any associated HTML controls to the\n * new component.\n */\n static init()\n {\n var aeCPUs = Component.getElementsByClass(document, PDP10.APPCLASS, \"cpu\");\n for (var iCPU = 0; iCPU < aeCPUs.length; iCPU++) {\n var eCPU = aeCPUs[iCPU];\n var parmsCPU = Component.getComponentParms(eCPU);\n var cpu = new CPUStatePDP10(parmsCPU);\n Component.bindComponentControls(cpu, eCPU, PDP10.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize every CPU module on the page\n */\nWeb.onInit(CPUStatePDP10.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/cpuops.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n From the \"PDP-10 System Reference Manual\", May 1968, p. 1-4:\n\n 1.1 NUMBER SYSTEM\n\n The program can interpret a data word as a 36-digit, unsigned binary number, or the left and right\n halves of a word can be taken as separate 18-bit numbers. The PDP-10 repertoire includes instructions\n that effectively add or subtract one from both halves of a word, so the right half can be used for\n address modification when the word is addressed as an index register, while the left half is used to\n keep a control count.\n\n The standard arithmetic instructions in the PDP-10 use twos complement, fixed point conventions to do\n binary arithmetic. In a word used as a number, bit 0 (the leftmost bit) represents the sign, 0 for positive,\n 1 for negative. In a positive number the remaining 35 bits are the magnitude in ordinary binary notation.\n The negative of a number is obtained by taking its twos complement. If x is an n-digit binary number, its\n twos complement is 2^n - x, and its ones complement is (2^n - 1) - x, or equivalently (2^n - x) - 1.\n\n Subtracting a number from 2^n - 1 (ie, from all 1s) is equivalent to performing the logical complement,\n ie changing all 0s to 1s and all 1s to 0s. Therefore, to form the twos complement one takes the logical\n complement (usually referred to merely as the complement) of the entire word including the sign, and adds\n 1 to the result. In a negative number the sign bit is 1, and the remaining bits are the twos complement\n of the magnitude.\n\n Zero is represented by a word containing all 0s. Complementing this number produces all 1s, and adding\n 1 to that produces all 0s again. Hence there is only one zero representation and its sign is positive.\n Since the numbers are symmetrical in magnitude about a single zero representation, all even numbers both\n positive and negative end in 0, all odd numbers in 1 (a number all 1s represents -1). But since there are\n the same number of positive and negative numbers and zero is positive, there is one more negative number\n than there are nonzero positive numbers. This is the most negative number and it cannot be produced by\n negating any positive number (its octal representation is 400000 000000 and its magnitude is one greater\n than the largest positive number).\n\n If ones complements were used for negatives one could read a negative number by attaching significance\n to the as instead of the 1s. In twos complement notation each negative number is one greater than the\n complement of the positive number of the same magnitude, so one can read a negative number by attaching\n significance to the rightmost 1 and attaching significance to the 0s at the left of it (the negative number\n of largest magnitude has a 1 in only the sign position). In a negative integer, 1s may be discarded at the\n left, just as leading 0s may be dropped in a positive integer. In a negative fraction, 0s may be discarded\n at the right. So long as only 0s are discarded, the number remains in twos complement form because it\n still has a 1 that possesses significance; but if a portion including the rightmost 1 is discarded, the\n remaining part of the fraction is now a ones complement.\n\n The computer does not keep track of a binary point - the programmer must adopt a point convention and shift\n the magnitude of the result to conform to the convention used. Two common conventions are to regard a number\n as an integer (binary point at the right) or as a proper fraction (binary point at the left); in these two\n cases the range of numbers represented by a single word is -2^35 to 2^35 - 1, or -1 to 1 - 2^35. Since\n multiplication and division make use of double length numbers, there are special instructions for performing\n these operations with integral operands.\n\n SIDEBAR: Multiplication produces a double length product, and the programmer must remember that discarding\n the low order part of a double length negative leaves the high order part in correct twos complement form\n only if the low order part is null.\n\n ...\n\n 2.5 FIXED POINT ARITHMETIC\n\n For fixed point arithmetic the PDP-10 has instructions for arithmetic shifting (which is essentially\n multiplication by a power of 2) as well as for performing addition, subtraction, multiplication and division\n of numbers in fixed point format [§ 1.1]. In such numbers the position of the binary point is arbitrary\n (the programmer may adopt any point convention). The add and subtract instructions involve only single length\n numbers, whereas multiply supplies a double length product, and divide uses a double length dividend. The high\n and low order words respectively of a double length fixed point number are in accumulators A and A+1 (mod 20),\n where the magnitude is the 70-bit string in bits 1-35 of the two words and the signs of the two are identical.\n There are also integer multiply and divide instructions that involve only single length numbers and are\n especially suited for handling smaller integers, particularly those of eighteen bits or less such as addresses\n (of course they can be used for small fractions as well provided the programmer keeps track of the binary point).\n For convenience in the following, all operands are assumed to be integers (binary point at the right).\n\n The processor has four flags, Overflow, Carry 0, Carry 1 and No Divide, that indicate when the magnitude of a\n number is or would be larger than can be accommodated. Carry 0 and Carry 1 actually detect carries out of bits\n 0 and 1 in certain instructions that employ fixed point arithmetic operations: the add and subtract instructions\n treated here, the move instructions that produce the negative or magnitude of the word moved [§ 2.2], and the\n arithmetic test instructions that increment or decrement the test word [§ 2.7]. In these instructions an\n incorrect result is indicated - and the Overflow flag set - if the carries are different, ie if there is a carry\n into the sign but not out of it, or vice versa. The Overflow flag is also set by No Divide being set, which\n means the processor has failed to perform a division because the magnitude of the dividend is greater than or\n equal to that of the divisor, or in integer divide, simply that the divisor is zero. In other overflow cases\n only Overflow itself is set: these include too large a product in multiplication, and loss of significant bits\n in left arithmetic shifting.\n\n SIDEBAR: Overflow is determined directly from the carries, not from the carry flags, as their states may reflect\n events in previous instructions.\n\n */\n\n/**\n * opKA10(op)\n *\n * Originally, we received the full opcode (36 bits), then only the upper half-word (18 bits),\n * and now we receive only the upper 13 bits. However, the octal values shown in the table and\n * function comments below still include all 18 bits of the original upper half-word, so that\n * you don't have to mentally un-shift them 5 bits.\n *\n * @this {CPUStatePDP10}\n * @param {number} op (the top 13 bits of the original opcode, shifted right to bit 0)\n */\nPDP10.opKA10 = function(op)\n{\n /*\n * We shift op right 4 more bits, leaving only the 9 bits required for the table index. Those\n * 4 bits are normally an accumulator index, which we also mask and pass along, since most instructions\n * will use an accumulator, and those that don't simply ignore it.\n */\n PDP10.aOpXXX_KA10[op >> 4].call(this, op, op & PDP10.OPCODE.A_MASK);\n};\n\n/**\n * opUUO(0o0NN000): Unimplemented User Operation\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-64:\n *\n * Store the instruction code, A and the effective address E in bits 0-8, 9-12 and 18-35 respectively of\n * location 40; clear bits 13-17. Execute the instruction contained in location 41. The original contents\n * of location 40 are lost.\n *\n * All of these codes are equivalent when they occur in the Monitor or when time sharing is not in effect.\n * But when a UUO appears in a user program, a code in the range 001-037 uses relocated locations 40 and 41\n * (ie 40 and 41 in the user's block) and is thus entirely a part of and under control of the user program.\n *\n * A code in the range 040-077 on the other hand uses unrelocated 40 and 41, and the instruction in the latter\n * location is under control of the Monitor; these codes are thus specifically for user communication with\n * the Monitor, which interprets them (refer to the Monitor manual for the meanings of the various codes).\n *\n * The code 000 executes in the same way as 040-077 but is not a standard communication code: it is included\n * so that control returns to the Monitor should a user program wipe itself out.\n *\n * For a second processor connected to the same memory, the UUO trap is locations 140-141 instead of 40-41.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opUUO = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opUFA(0o130000): Unnormalized Floating Add\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-37:\n *\n * Floating add the contents of location E to AC. If the double length fraction in the sum is zero, clear\n * accumulator A+1. Otherwise normalize the sum only if the magnitude of its fractional part is >= 1, and place\n * the high order part of the result in AC A+1. The original contents of AC and E are unaffected.\n *\n * NOTE: The result is placed in accumulator A+1. T his is the only arithmetic instruction that stores the result\n * in a second accumulator, leaving the original operands intact.\n *\n * If the exponent of the sum following the one-step normalization is > 127, set Overflow and Floating Overflow;\n * the result stored has an exponent 256 less than the correct one.\n *\n * SIDEBAR: The exponent of the sum is equal to that of the larger summand unless addition of the fractions\n * overflows, in which case it is greater by 1. Exponent overflow can occur only in the latter case.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opUFA = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opDFN(0o131000): Double Floating Negate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-37:\n *\n * Negate the double length floating point number composed of the contents of AC and location E with AC on the left.\n * Do this by taking the twos complement of the number whose sign is AC bit 0, whose exponent is in AC bits 1-8, and\n * whose fraction is the 54-bit string in bits 9-35 of AC and location E. Place the high order word of the result\n * in AC; place the low order part of the fraction in bits 9-35 of location E without altering the original contents\n * of bits 0-8 of that location.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opDFN = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFSC(0o132000): Floating Scale\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-34:\n *\n * If the fractional part of AC is zero, clear AC. Otherwise add the scale factor given by E to the exponent part\n * of AC (thus multiplying AC by 2^E), normalize the resulting word bringing 0s into bit positions vacated at the\n * right, and place the result back in AC.\n *\n * NOTE: A negative E is represented in standard twos complement notation, but the hardware compensates for this\n * when scaling the exponent.\n *\n * If the exponent after normalization is > 127, set Overflow and Floating Overflow; the result stored has an\n * exponent 256 less than the correct one. If < -128, set Overflow, Floating Overflow and Floating Underflow;\n * the result stored has an exponent 256 greater than the correct one.\n *\n * SIDEBAR: This instruction can be used to float a fixed number with 27 or fewer significant bits. To float an\n * integer contained within AC bits 9-35,\n *\n * FSC AC,233\n *\n * inserts the correct exponent to move the binary point from the right end to the left of bit 9 and then normalizes\n * (233 [base 8] = 155 [base 10] = 128 + 27).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFSC = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opIBP(0o133000): Increment Byte Pointer\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-16:\n *\n * Increment the byte pointer in location E as explained [below]. The pointer has the format:\n *\n * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3\n * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5\n * P P P P P P S S S S S S - I X X X X Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y\n *\n * where S is the size of the byte as a number of bits, and P is its position as the number of bits\n * remaining at the right of the byte in the word (eg if P is 3 the rightmost bit of the byte is bit 32\n * of the word). The rest of the pointer is interpreted in the same way as in an instruction: I, X and Y\n * are used to calculate the address of the location that is the source or destination of the byte.\n *\n * To facilitate processing a series of bytes, several of the byte instructions increment the\n * pointer, ie, modify it so that it points to the next byte position in a set of memory locations.\n * Bytes are processed from left to right in a word, so incrementing merely replaces the current value\n * of P by P - S, unless there is insufficient space in the present location for another byte of the\n * specified size (P - S < 0). In this case Y is increased by one to point to the next consecutive\n * location, and P is set to 36 - S to point to the first byte at the left in the new location.\n *\n * CAUTION: Do not allow Y to reach maximum value. The whole pointer is incremented, so if Y is 2^18 - 1\n * it becomes zero and X is also incremented. The address calculation for the pointer uses the original X,\n * but if a priority interrupt should occur before the calculation is complete, the incremented X is used\n * when the instruction is repeated.\n *\n * SPECIAL CONSIDERATIONS: If S is greater than P and also greater than 36, incrementing produces a new\n * P equal to 100 - S rather than 36 - S. For S > 36 the byte is at most the entire word; for P >= 36 no\n * byte is processed (loading merely clears AC). If both P and S are less than 36 but P + S > 36,\n * a byte of size 36 - P is loaded from position P, or the right 36 - P bits of the byte are deposited\n * in position P.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIBP = function(op, ac)\n{\n var inc = 0;\n var w = this.readWord(this.regEA);\n var p = (w / PDP10.OPCODE.P_SCALE) & PDP10.OPCODE.P_MASK;\n var s = (w >> PDP10.OPCODE.S_SHIFT) & PDP10.OPCODE.S_MASK;\n p -= s;\n if (p < 0) {\n inc++;\n p = 36 - s;\n if (p < 0) p = 100 - s; // see SPECIAL CONSIDERATIONS and NOTE above\n }\n /*\n * Since the documentation above makes clear that the effect of the increment (of w) extends past the Y\n * bits and into (at least) the X bits, we first re-assemble a new pointer with updated P bits (along with\n * the original S bits and the remaining bits covered by PTR_MASK) and then increment as needed.\n *\n * Yes, PTR_MASK could have included the S bits as well and made the following expression a TINY bit simpler,\n * but I would like to keep PTR_MASK distinct from both the P and S fields.\n */\n w = (p * PDP10.OPCODE.P_SCALE) + (s << PDP10.OPCODE.S_SHIFT) + (w & PDP10.OPCODE.PTR_MASK);\n if (inc) w = (w + inc) % PDP10.WORD_LIMIT;\n this.writeWord(this.regEA, w);\n};\n\n/**\n * opILDB(0o134000): Increment Pointer and Load Byte\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-16:\n *\n * Increment the byte pointer in location E as explained above. Then retrieve a byte of S bits from the\n * location and position specified by the newly incremented pointer, load it into the right end of AC,\n * and clear the remaining AC bits. The location containing the byte is unaffected, the original contents\n * of AC are lost.\n *\n * SPECIAL CONSIDERATIONS: If S is greater than P and also greater than 36, incrementing produces a new\n * P equal to 100 - S rather than 36 - S. For S > 36 the byte is at most the entire word; for P >= 36 no\n * byte is processed (loading merely clears AC). If both P and S are less than 36 but P + S > 36,\n * a byte of size 36 - P is loaded from position P, or the right 36 - P bits of the byte are deposited\n * in position P.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opILDB = function(op, ac)\n{\n /*\n * We're called in two phases: phase 1 is with regEA containing the address of the pointer, and phase 2\n * is with regEA containing the address of the bits to be loaded.\n *\n * We can implement this as a simple combination of opIBP() and opLDB(), but taking care that we only call\n * opIBP() on phase 1 (and only if the BIS flag is not set).\n */\n if (!(this.regPS & PDP10.PSFLAG.BIS)) {\n PDP10.opIBP.call(this, op, ac);\n this.regPS |= PDP10.PSFLAG.BIS;\n }\n PDP10.opLDB.call(this, op, ac);\n};\n\n/**\n * opLDB(0o135000): Load Byte\n *z\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-16:\n *\n * Retrieve a byte of S bits from the location and position specified by the pointer contained in location E,\n * load it into the right end of AC, and clear the remaining AC bits. The location containing the byte is\n * unaffected, the original contents of AC are lost.\n *\n * SPECIAL CONSIDERATIONS: If S is greater than P and also greater than 36, incrementing produces a new\n * P equal to 100 - S rather than 36 - S. For S > 36 the byte is at most the entire word; for P >= 36 no\n * byte is processed (loading merely clears AC). If both P and S are less than 36 but P + S > 36,\n * a byte of size 36 - P is loaded from position P, or the right 36 - P bits of the byte are deposited\n * in position P.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opLDB = function(op, ac)\n{\n /*\n * We're called in two phases: phase 1 is with regEA containing the address of the pointer, and phase 2\n * is with regEA containing the address of the bits to be loaded.\n */\n var w = this.readWord(this.regEA);\n if (this.regBP < 0) {\n this.regBP = w;\n this.regRA = this.regEA | PDP10.OPCODE.I_FIELD;\n return;\n }\n var p = (this.regBP / PDP10.OPCODE.P_SCALE) & PDP10.OPCODE.P_MASK;\n var s = (this.regBP >> PDP10.OPCODE.S_SHIFT) & PDP10.OPCODE.S_MASK;\n if (p + s < 32) {\n /*\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n w = ((w >> p) & ((1 << s) - 1)) >>> 0;\n } else {\n /*\n * Regarding the SPECIAL CONSIDERATIONS above, even if the P (\"shift\") and/or S (\"mask\") values are\n * over-large, that should be fine, because nothing but additional zero bits will be included (provided\n * our memory is working properly and didn't give us more than 36 bits of unsigned data).\n */\n w = Math.trunc(w / Math.pow(2, p)) % Math.pow(2, s);\n }\n this.writeWord(ac, w);\n this.regPS &= ~PDP10.PSFLAG.BIS;\n this.regBP = -1;\n};\n\n/**\n * opIDPB(0o136000): Increment Pointer and Deposit Byte\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-16:\n *\n * Increment the byte pointer in location E as explained above. Then deposit the right S bits of AC into\n * the location and position specified by the newly incremented pointer. The original contents of the bits\n * that receive the byte are lost, AC and the remaining bits of the deposit location are unaffected.\n *\n * SPECIAL CONSIDERATIONS: If S is greater than P and also greater than 36, incrementing produces a new\n * P equal to 100 - S rather than 36 - S. For S > 36 the byte is at most the entire word; for P >= 36 no\n * byte is processed (loading merely clears AC). If both P and S are less than 36 but P + S > 36,\n * a byte of size 36 - P is loaded from position P, or the right 36 - P bits of the byte are deposited\n * in position P.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIDPB = function(op, ac)\n{\n /*\n * We're called in two phases: phase 1 is with regEA containing the address of the pointer, and phase 2\n * is with regEA containing the address of the bits to be stored.\n *\n * We can implement this as a simple combination of opIBP() and opDDB(), but taking care that we only call\n * opIBP() on phase 1 (and only if the BIS flag is not set).\n */\n if (!(this.regPS & PDP10.PSFLAG.BIS)) {\n PDP10.opIBP.call(this, op, ac);\n this.regPS |= PDP10.PSFLAG.BIS;\n }\n PDP10.opDPB.call(this, op, ac);\n};\n\n/**\n * opDPB(0o137000): Deposit Byte\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-16:\n *\n * Deposit the right S bits of AC into the location and position specified by the pointer contained\n * in location E. The original contents of the bits that receive the byte are lost, AC and the remaining\n * bits of the deposit location are unaffected.\n *\n * SPECIAL CONSIDERATIONS: If S is greater than P and also greater than 36, incrementing produces a new\n * P equal to 100 - S rather than 36 - S. For S > 36 the byte is at most the entire word; for P >= 36 no\n * byte is processed (loading merely clears AC). If both P and S are less than 36 but P + S > 36,\n * a byte of size 36 - P is loaded from position P, or the right 36 - P bits of the byte are deposited\n * in position P.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opDPB = function(op, ac)\n{\n /*\n * We're called in two phases: phase 1 is with regEA containing the address of the pointer, and phase 2\n * is with regEA containing the address of the bits to be stored.\n */\n var w = this.readWord(this.regEA);\n if (this.regBP < 0) {\n this.regBP = w;\n this.regRA = this.regEA | PDP10.OPCODE.I_FIELD;\n return;\n }\n var p = (this.regBP / PDP10.OPCODE.P_SCALE) & PDP10.OPCODE.P_MASK;\n var s = (this.regBP >> PDP10.OPCODE.S_SHIFT) & PDP10.OPCODE.S_MASK;\n /*\n * Regarding the SPECIAL CONSIDERATIONS above, even if the P (\"shift\") and/or S (\"mask\") values are\n * over-large, we \"mask\" the resulting byte value (b) to 36 bits, so that when we re-assemble the final\n * result (w), there shouldn't be any overlap or overflow.\n */\n var b = ((this.readWord(ac) % Math.pow(2, s)) * Math.pow(2, p)) % PDP10.WORD_LIMIT;\n w = (w - (w % Math.pow(2, p + s))) + b + (w % Math.pow(2, p));\n this.writeWord(this.regEA, w);\n this.regPS &= ~PDP10.PSFLAG.BIS;\n this.regBP = -1;\n};\n\n/**\n * opFAD(0o140000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFAD = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFADI(0o141000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFADI = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFADM(0o142000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFADM = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFADB(0o143000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFADB = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFADR(0o144000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFADR = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFADRI(0o145000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFADRI = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFADRM(0o146000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFADRM = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFADRB(0o147000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFADRB = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFSB(0o150000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFSB = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFSBI(0o151000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFSBI = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFSBM(0o152000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFSBM = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFSBB(0o153000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFSBB = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFSBR(0o154000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFSBR = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFSBRI(0o155000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFSBRI = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFSBRM(0o156000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFSBRM = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFSBRB(0o157000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFSBRB = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFMP(0o160000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFMP = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFMPI(0o161000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFMPI = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFMPM(0o162000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFMPM = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFMPB(0o163000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFMPB = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFMPR(0o164000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFMPR = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFMPRI(0o165000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFMPRI = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFMPRM(0o166000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFMPRM = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFMPRB(0o167000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFMPRB = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFDV(0o170000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFDV = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFDVI(0o171000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFDVI = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFDVM(0o172000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFDVM = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFDVB(0o173000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFDVB = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFDVR(0o174000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFDVR = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFDVRI(0o175000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFDVRI = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFDVRM(0o176000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFDVRM = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opFDVRB(0o177000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opFDVRB = function(op, ac)\n{\n this.opUndefined(op);\n};\n\n/**\n * opMOVE(0o200000): Move\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Move one word from the source to the destination specified by M. The source is unaffected,\n * the original contents of the destination are lost.\n *\n * NOTE: This is a \"Basic\" mode instruction: the source is [E] and the destination is [A] (opposite of \"Memory\").\n *\n * Equivalents: opSETM(0o414000) and opSETMB(0o417000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVE = function(op, ac)\n{\n this.writeWord(ac, this.readWord(this.regEA));\n};\n\n/**\n * opMOVEI(0o201000): Move Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Move one word from the source to the destination specified by M. The source is unaffected,\n * the original contents of the destination are lost.\n *\n * SIDEBAR: MOVEI loads the word 0,E into AC and is thus equivalent to HRRZI.\n *\n * NOTE: This is an \"Immediate\" mode instruction: the source is the word 0,E and the destination is [A].\n *\n * Equivalents: opSETMI(0o415000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVEI = function(op, ac)\n{\n this.writeWord(ac, this.regEA);\n};\n\n/**\n * opMOVEM(0o202000): Move to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Move one word from the source to the destination specified by M. The source is unaffected,\n * the original contents of the destination are lost.\n *\n * NOTE: This is a \"Memory\" mode instruction: the source is [A] and the destination is [E] (opposite of \"Basic\").\n *\n * Equivalents: opSETAM(0o426000) and opSETAB(0o427000).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVEM = function(op, ac)\n{\n this.writeWord(this.regEA, this.readWord(ac));\n};\n\n/**\n * opMOVES(0o203000): Move to Self\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Move one word from the source to the destination specified by M. The source is unaffected,\n * the original contents of the destination are lost.\n *\n * SIDEBAR: If A is zero, MOVES is a no-op; otherwise it is equivalent to MOVE.\n *\n * NOTE: This is a \"Self\" mode instruction: the source AND destination is [E] (and also [A] if A is non-zero).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVES = function(op, ac)\n{\n if (ac) this.writeWord(ac, this.readWord(this.regEA));\n};\n\n/**\n * opMOVS(0o204000): Move Swapped\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Interchange the left and right halves of the word from the source specified by M and move it to the\n * specified destination. The source is unaffected, the original contents of the destination are lost.\n *\n * NOTE: This is a \"Basic\" mode instruction: the source is [E] and the destination is [A] (opposite of \"Memory\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVS = function(op, ac)\n{\n var src = this.readWord(this.regEA);\n src = ((src / PDP10.HALF_SHIFT)|0) + ((src & PDP10.HALF_MASK) * PDP10.HALF_SHIFT);\n this.writeWord(ac, src);\n};\n\n/**\n * opMOVSI(0o205000): Move Swapped Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Interchange the left and right halves of the word from the source specified by M and move it to the\n * specified destination. The source is unaffected, the original contents of the destination are lost.\n *\n * SIDEBAR: Swapping halves in immediate mode loads the word E,0 into AC. MOVSI is thus equivalent to HRLZI.\n *\n * NOTE: This is an \"Immediate\" mode instruction: the source is the word 0,E and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVSI = function(op, ac)\n{\n this.writeWord(ac, this.regEA * PDP10.HALF_SHIFT);\n};\n\n/**\n * opMOVSM(0o206000): Move Swapped to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Interchange the left and right halves of the word from the source specified by M and move it to the\n * specified destination. The source is unaffected, the original contents of the destination are lost.\n *\n * NOTE: This is a \"Memory\" mode instruction: the source is [A] and the destination is [E] (opposite of \"Basic\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVSM = function(op, ac)\n{\n var src = this.readWord(ac);\n src = ((src / PDP10.HALF_SHIFT)|0) + ((src & PDP10.HALF_MASK) * PDP10.HALF_SHIFT);\n this.writeWord(this.regEA, src);\n};\n\n/**\n * opMOVSS(0o207000): Move Swapped to Self\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Interchange the left and right halves of the word from the source specified by M and move it to the\n * specified destination. The source is unaffected, the original contents of the destination are lost.\n *\n * NOTE: This is a \"Self\" mode instruction: the source AND destination is [E] (and also [A] if A is non-zero).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVSS = function(op, ac)\n{\n var src = this.readWord(this.regEA);\n src = ((src / PDP10.HALF_SHIFT)|0) + ((src & PDP10.HALF_MASK) * PDP10.HALF_SHIFT);\n this.writeWord(this.regEA, src);\n if (ac) this.writeWord(ac, src)\n};\n\n/**\n * opMOVN(0o210000): Move Negative\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Negate the word from the source specified by M and move it to the specified destination.\n * If the source word is fixed point -2^35 (400000 000000) set the Overflow and Carry 1 flags.\n *\n * (Negating the equivalent floating point -1 * 2^127 sets the flags, but this is not a normalized\n * number).\n *\n * If the source word is zero, set Carry 0 and Carry 1. The source is unaffected, the original\n * contents of the destination are lost.\n *\n * NOTE: This is a \"Basic\" mode instruction: the source is [E] and the destination is [A] (opposite of \"Memory\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVN = function(op, ac)\n{\n this.writeWord(ac, PDP10.doNEG.call(this, this.readWord(this.regEA)));\n};\n\n/**\n * opMOVNI(0o211000): Move Negative Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Negate the word from the source specified by M and move it to the specified destination.\n * If the source word is fixed point -2^35 (400000 000000) set the Overflow and Carry 1 flags.\n *\n * (Negating the equivalent floating point -1 * 2^127 sets the flags, but this is not a normalized\n * number).\n *\n * If the source word is zero, set Carry 0 and Carry 1. The source is unaffected, the original\n * contents of the destination are lost.\n *\n * SIDEBAR: MOVNI loads AC with the negative of the word 0,E and can set no flags.\n *\n * NOTE: This is an \"Immediate\" mode instruction: the source is the word 0,E and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVNI = function(op, ac)\n{\n /*\n * We used to perform an in-line two's complement of regEA, since doNEG() updates the flags, and the\n * documentation above claimed that MOVNI must \"set no flags.\" It's certainly true that regEA, being an\n * 18-bit value, could never be -2^35, but it COULD be zero. However, SIMH doesn't treat zero any\n * differently for MOVNI, so we currently don't either.\n *\n * TODO: Verify the \"set no flags\" assertion on *real* (KA10) hardware.\n */\n this.writeWord(ac, PDP10.doNEG.call(this, this.regEA) /* this.regEA? PDP10.TWO_POW36 - this.regEA : 0 */);\n};\n\n/**\n * opMOVNM(0o212000): Move Negative to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Negate the word from the source specified by M and move it to the specified destination.\n * If the source word is fixed point -2^35 (400000 000000) set the Overflow and Carry 1 flags.\n *\n * (Negating the equivalent floating point -1 * 2^127 sets the flags, but this is not a normalized\n * number).\n *\n * If the source word is zero, set Carry 0 and Carry 1. The source is unaffected, the original\n * contents of the destination are lost.\n *\n * NOTE: This is a \"Memory\" mode instruction: the source is [A] and the destination is [E] (opposite of \"Basic\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVNM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.doNEG.call(this, this.readWord(ac)));\n};\n\n/**\n * opMOVNS(0o213000): Move Negative to Self\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-11:\n *\n * Negate the word from the source specified by M and move it to the specified destination.\n * If the source word is fixed point -2^35 (400000 000000) set the Overflow and Carry 1 flags.\n *\n * (Negating the equivalent floating point -1 * 2^127 sets the flags, but this is not a normalized\n * number).\n *\n * If the source word is zero, set Carry 0 and Carry 1. The source is unaffected, the original\n * contents of the destination are lost.\n *\n * NOTE: This is a \"Self\" mode instruction: the source AND destination is [E] (and also [A] if A is non-zero).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVNS = function(op, ac)\n{\n var dst = PDP10.doNEG.call(this, this.readWord(this.regEA));\n this.writeWord(this.regEA, dst);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opMOVM(0o214000): Move Magnitude\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-12:\n *\n * Take the magnitude of the word contained in the source specified by M and move it to the\n * specified destination. If the source word is fixed point -2^35 (400000 000000) set the\n * Overflow and Carry 1 flags.\n *\n * (Negating the equivalent floating point -1 * 2^27 sets the flags, but this is not a normalized\n * number).\n *\n * The source is unaffected, the original contents of the destination are lost.\n *\n * NOTE: This is a \"Basic\" mode instruction: the source is [E] and the destination is [A] (opposite of \"Memory\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVM = function(op, ac)\n{\n this.writeWord(ac, PDP10.doABS.call(this, this.readWord(this.regEA)));\n};\n\n/**\n * opMOVMI(0o215000): Move Magnitude Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-12:\n *\n * Take the magnitude of the word contained in the source specified by M and move it to the\n * specified destination. If the source word is fixed point -2^35 (400000 000000) set the\n * Overflow and Carry 1 flags.\n *\n * (Negating the equivalent floating point -1 * 2^27 sets the flags, but this is not a normalized\n * number).\n *\n * The source is unaffected, the original contents of the destination are lost.\n *\n * SIDEBAR: The word 0,E is equivalent to its magnitude, so MOVMI is equivalent to MOVEI.\n *\n * NOTE: This is an \"Immediate\" mode instruction: the source is the word 0,E and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVMI = function(op, ac)\n{\n this.writeWord(ac, this.regEA); // src is an 18-bit immediate value, so there's no need to call doABS()\n};\n\n/**\n * opMOVMM(0o216000): Move Magnitude to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-12:\n *\n * Take the magnitude of the word contained in the source specified by M and move it to the\n * specified destination. If the source word is fixed point -2^35 (400000 000000) set the\n * Overflow and Carry 1 flags.\n *\n * (Negating the equivalent floating point -1 * 2^27 sets the flags, but this is not a normalized\n * number).\n *\n * The source is unaffected, the original contents of the destination are lost.\n *\n * NOTE: This is a \"Memory\" mode instruction: the source is [A] and the destination is [E] (opposite of \"Basic\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVMM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.doABS.call(this, this.readWord(ac)));\n};\n\n/**\n * opMOVMS(0o217000): Move Magnitude to Self\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-12:\n *\n * Take the magnitude of the word contained in the source specified by M and move it to the\n * specified destination. If the source word is fixed point -2^35 (400000 000000) set the\n * Overflow and Carry 1 flags.\n *\n * (Negating the equivalent floating point -1 * 2^27 sets the flags, but this is not a normalized\n * number).\n *\n * The source is unaffected, the original contents of the destination are lost.\n *\n * NOTE: This is a \"Self\" mode instruction: the source AND destination is [E] (and also [A] if A is non-zero).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMOVMS = function(op, ac)\n{\n var dst = PDP10.doABS.call(this, this.readWord(this.regEA));\n this.writeWord(this.regEA, dst);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opIMUL(0o220000): Integer Multiply\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28:\n *\n * Multiply AC by the operand specified by M, and place the sign and the 35 low order magnitude bits of the\n * product in the specified destination. Set Overflow if the product is >= 2^35 or < -2^35 (ie if the high order\n * word of the double length product is not null); the high order word is lost.\n *\n * NOTE: This is a \"Basic\" mode instruction: the source is [E] and the destination is [A] (opposite of \"Memory\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIMUL = function(op, ac)\n{\n this.writeWord(ac, PDP10.doMUL.call(this, this.readWord(ac), this.readWord(this.regEA), true));\n};\n\n/**\n * opIMULI(0o221000): Integer Multiply Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28:\n *\n * Multiply AC by the operand specified by M, and place the sign and the 35 low order magnitude bits of the\n * product in the specified destination. Set Overflow if the product is >= 2^35 or < -2^35 (ie if the high order\n * word of the double length product is not null); the high order word is lost.\n *\n * NOTE: This is an \"Immediate\" mode instruction: the source is the word 0,E and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIMULI = function(op, ac)\n{\n this.writeWord(ac, PDP10.doMUL.call(this, this.readWord(ac), this.regEA, true));\n};\n\n/**\n * opIMULM(0o222000): Integer Multiply to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28:\n *\n * Multiply AC by the operand specified by M, and place the sign and the 35 low order magnitude bits of the\n * product in the specified destination. Set Overflow if the product is >= 2^35 or < -2^35 (ie if the high order\n * word of the double length product is not null); the high order word is lost.\n *\n * NOTE: This is a \"Memory\" mode instruction: the source is [E] and the destination is [E] (opposite of \"Basic\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIMULM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.doMUL.call(this, this.readWord(ac), this.readWord(this.regEA), true));\n};\n\n/**\n * opIMULB(0o223000): Integer Multiply to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28:\n *\n * Multiply AC by the operand specified by M, and place the sign and the 35 low order magnitude bits of the\n * product in the specified destination. Set Overflow if the product is >= 2^35 or < -2^35 (ie if the high order\n * word of the double length product is not null); the high order word is lost.\n *\n * NOTE: This is a \"Both\" mode instruction: the source is [E] and the destination is [E] and [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIMULB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.doMUL.call(this, this.readWord(ac), this.readWord(this.regEA), true)));\n};\n\n/**\n * opMUL(0o224000): Multiply\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28:\n *\n * Multiply AC by the operand specified by M, and place the high order word of the double length result\n * in the specified destination. If M specifies AC as a destination, place the low order word in accumulator\n * A+1. If both operands are -2^35 set Overflow; the double length result stored is -2^70.\n *\n * NOTE: This is a \"Basic\" mode instruction: the source is [E] and the destination is [A],[A+1] (opposite of \"Memory\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMUL = function(op, ac)\n{\n this.writeWord(ac, PDP10.doMUL.call(this, this.readWord(ac), this.readWord(this.regEA)));\n this.writeWord((ac + 1) & 0o17, this.regEX);\n};\n\n/**\n * opMULI(0o225000): Multiply Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28:\n *\n * Multiply AC by the operand specified by M, and place the high order word of the double length result\n * in the specified destination. If M specifies AC as a destination, place the low order word in accumulator\n * A+1. If both operands are -2^35 set Overflow; the double length result stored is -2^70.\n *\n * NOTE: This is an \"Immediate\" mode instruction: the source is the word 0,E and the destination is [A],[A+1].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMULI = function(op, ac)\n{\n this.writeWord(ac, PDP10.doMUL.call(this, this.readWord(ac), this.regEA));\n this.writeWord((ac + 1) & 0o17, this.regEX);\n};\n\n/**\n * opMULM(0o226000): Multiply to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28:\n *\n * Multiply AC by the operand specified by M, and place the high order word of the double length result\n * in the specified destination. If M specifies AC as a destination, place the low order word in accumulator\n * A+1. If both operands are -2^35 set Overflow; the double length result stored is -2^70.\n *\n * NOTE: This is a \"Memory\" mode instruction: the source is [E] and the destination is [E] (opposite of \"Basic\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMULM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.doMUL.call(this, this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opMULB(0o227000): Multiply to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-28:\n *\n * Multiply AC by the operand specified by M, and place the high order word of the double length result\n * in the specified destination. If M specifies AC as a destination, place the low order word in accumulator\n * A+1. If both operands are -2^35 set Overflow; the double length result stored is -2^70.\n *\n * NOTE: This is a \"Both\" mode instruction: the source is [E] and the destination is [E] and [A],[A+1].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opMULB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.doMUL.call(this, this.readWord(ac), this.readWord(this.regEA))));\n this.writeWord((ac + 1) & 0o17, this.regEX);\n};\n\n/**\n * opIDIV(0o230000): Integer Divide\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29:\n *\n * If the operand specified by M is zero, set Overflow and No Divide, and go immediately to the next instruction\n * without affecting the original AC or memory operand in any way. Otherwise divide AC by the specified operand,\n * calculating a quotient of 35 magnitude bits including leading zeros. Place the unrounded quotient in the\n * specified destination. If M specifies AC as the destination, place the remainder, with the same sign as the\n * dividend, in accumulator A+1.\n *\n * NOTE: This is a \"Basic\" mode instruction: the source is [E] and the destination is [A],[A+1] (opposite of \"Memory\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIDIV = function(op, ac)\n{\n var dst = PDP10.doDIV.call(this, this.readWord(this.regEA), this.readWord(ac));\n if (dst < 0) return;\n this.writeWord(ac, dst);\n this.writeWord((ac + 1) & 0o17, this.regEX);\n};\n\n/**\n * opIDIVI(0o231000): Integer Divide Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29:\n *\n * If the operand specified by M is zero, set Overflow and No Divide, and go immediately to the next instruction\n * without affecting the original AC or memory operand in any way. Otherwise divide AC by the specified operand,\n * calculating a quotient of 35 magnitude bits including leading zeros. Place the unrounded quotient in the\n * specified destination. If M specifies AC as the destination, place the remainder, with the same sign as the\n * dividend, in accumulator A+1.\n *\n * NOTE: This is an \"Immediate\" mode instruction: the source is the word 0,E and the destination is [A],[A+1].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIDIVI = function(op, ac)\n{\n var dst = PDP10.doDIV.call(this, this.regEA, this.readWord(ac));\n if (dst < 0) return;\n this.writeWord(ac, dst);\n this.writeWord((ac + 1) & 0o17, this.regEX);\n};\n\n/**\n * opIDIVM(0o232000): Integer Divide to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29:\n *\n * If the operand specified by M is zero, set Overflow and No Divide, and go immediately to the next instruction\n * without affecting the original AC or memory operand in any way. Otherwise divide AC by the specified operand,\n * calculating a quotient of 35 magnitude bits including leading zeros. Place the unrounded quotient in the\n * specified destination. If M specifies AC as the destination, place the remainder, with the same sign as the\n * dividend, in accumulator A+1.\n *\n * NOTE: This is a \"Memory\" mode instruction: the source is [E] and the destination is [E] (opposite of \"Basic\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIDIVM = function(op, ac)\n{\n var dst = PDP10.doDIV.call(this, this.readWord(this.regEA), this.readWord(ac));\n if (dst < 0) return;\n this.writeWord(this.regEA, dst);\n};\n\n/**\n * opIDIVB(0o233000): Integer Divide to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29:\n *\n * If the operand specified by M is zero, set Overflow and No Divide, and go immediately to the next instruction\n * without affecting the original AC or memory operand in any way. Otherwise divide AC by the specified operand,\n * calculating a quotient of 35 magnitude bits including leading zeros. Place the unrounded quotient in the\n * specified destination. If M specifies AC as the destination, place the remainder, with the same sign as the\n * dividend, in accumulator A+1.\n *\n * NOTE: This is a \"Both\" mode instruction: the source is [E] and the destination is [E] and [A],[A+1].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIDIVB = function(op, ac)\n{\n var dst = PDP10.doDIV.call(this, this.readWord(this.regEA), this.readWord(ac));\n if (dst < 0) return;\n this.writeWord(this.regEA, this.writeWord(ac, dst));\n this.writeWord((ac + 1) & 0o17, this.regEX);\n};\n\n/**\n * opDIV(0o234000): Divide\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29:\n *\n * If the magnitude of the number in AC is greater than or equal to that of the operand specified by M,\n * set Overflow and No Divide, and go immediately to the next instruction without affecting the original AC\n * or memory operand in any way. Otherwise divide the double length number contained in accumulators A and A+1\n * by the specified operand, calculating a quotient of 35 magnitude bits including leading zeros. Place the\n * unrounded quotient in the specified destination. If M specifies AC as a destination, place the remainder,\n * with the same sign as the dividend, in accumulator A+1.\n *\n * NOTE: This is a \"Basic\" mode instruction: the source is [E] and the destination is [A],[A+1] (opposite of \"Memory\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opDIV = function(op, ac)\n{\n var ext = this.readWord(ac);\n var dst = this.readWord((ac + 1) & 0o17);\n dst = PDP10.doDIV.call(this, this.readWord(this.regEA), dst, ext);\n if (dst < 0) return;\n this.writeWord(ac, dst);\n this.writeWord((ac + 1) & 0o17, this.regEX);\n};\n\n/**\n * opDIVI(0o235000): Divide Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29:\n *\n * If the magnitude of the number in AC is greater than or equal to that of the operand specified by M,\n * set Overflow and No Divide, and go immediately to the next instruction without affecting the original AC\n * or memory operand in any way. Otherwise divide the double length number contained in accumulators A and A+1\n * by the specified operand, calculating a quotient of 35 magnitude bits including leading zeros. Place the\n * unrounded quotient in the specified destination. If M specifies AC as a destination, place the remainder,\n * with the same sign as the dividend, in accumulator A+1.\n *\n * NOTE: This is an \"Immediate\" mode instruction: the source is the word 0,E and the destination is [A],[A+1].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opDIVI = function(op, ac)\n{\n var ext = this.readWord(ac);\n var dst = this.readWord((ac + 1) & 0o17);\n dst = PDP10.doDIV.call(this, this.regEA, dst, ext);\n if (dst < 0) return;\n this.writeWord(ac, dst);\n this.writeWord((ac + 1) & 0o17, this.regEX);\n};\n\n/**\n * opDIVM(0o236000): Divide to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29:\n *\n * If the magnitude of the number in AC is greater than or equal to that of the operand specified by M,\n * set Overflow and No Divide, and go immediately to the next instruction without affecting the original AC\n * or memory operand in any way. Otherwise divide the double length number contained in accumulators A and A+1\n * by the specified operand, calculating a quotient of 35 magnitude bits including leading zeros. Place the\n * unrounded quotient in the specified destination. If M specifies AC as a destination, place the remainder,\n * with the same sign as the dividend, in accumulator A+1.\n *\n * NOTE: This is a \"Memory\" mode instruction: the source is [E] and the destination is [E] (opposite of \"Basic\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opDIVM = function(op, ac)\n{\n var ext = this.readWord(ac);\n var dst = this.readWord((ac + 1) & 0o17);\n dst = PDP10.doDIV.call(this, this.readWord(this.regEA), dst, ext);\n if (dst < 0) return;\n this.writeWord(this.regEA, dst);\n};\n\n/**\n * opDIVB(0o237000): Divide to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-29:\n *\n * If the magnitude of the number in AC is greater than or equal to that of the operand specified by M,\n * set Overflow and No Divide, and go immediately to the next instruction without affecting the original AC\n * or memory operand in any way. Otherwise divide the double length number contained in accumulators A and A+1\n * by the specified operand, calculating a quotient of 35 magnitude bits including leading zeros. Place the\n * unrounded quotient in the specified destination. If M specifies AC as a destination, place the remainder,\n * with the same sign as the dividend, in accumulator A+1.\n *\n * NOTE: This is a \"Both\" mode instruction: the source is [E] and the destination is [E] and [A],[A+1].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opDIVB = function(op, ac)\n{\n var ext = this.readWord(ac);\n var dst = this.readWord((ac + 1) & 0o17);\n dst = PDP10.doDIV.call(this, this.readWord(this.regEA), dst, ext);\n if (dst < 0) return;\n this.writeWord(ac, this.writeWord(this.regEA, dst));\n this.writeWord((ac + 1) & 0o17, this.regEX);\n};\n\n/**\n * opASH(0o240000): Arithmetic Shift\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-31:\n *\n * Arithmetic Shifting\n *\n * These two instructions [ASH, ASHC] produce an arithmetic shift right or left of the number in AC\n * or the double length number in accumulators A and A+1. Shifting is the movement of the contents\n * of a register bit-to-bit. The operation discussed here is similar to logical shifting [see §2.4\n * and the illustration on page 2-24], but in an arithmetic shift only the magnitude part is\n * shifted - the sign is unaffected. In a double length number the 70-bit string made up of the\n * magnitude parts of the two words is shifted, but the sign of the low order word is made equal\n * to the sign of the high order word.\n *\n * Null bits are brought in at the end being vacated: a left shift brings in 0s at the right,\n * whereas a right shift brings in the equivalent of the sign bit at the left. In either case,\n * information shifted out at the other end is lost. A single shift left is equivalent to multiplying\n * the number by 2 (provided no bit of significance is shifted out); a shift right divides the number\n * by 2.\n *\n * The number of places shifted is specified by the result of the effective address calculation\n * taken as a signed number (in twos complement notation) modulo 2^8 in magnitude. In other words\n * the effective shift E is the number composed of bit 18 (which is the sign) and bits 28-35 of the\n * calculation result. Hence the programmer may specify the shift directly in the instruction\n * (perhaps indexed) or give an indirect address to be used in calculating the shift. A positive E\n * produces motion to the left, a negative E to the right; E is thus the power of 2 by which the\n * number is multiplied. Maximum movement is 255 places.\n *\n * ASH: Arithmetic Shift\n *\n * Shift AC arithmetically the number of places specified by E. Do not shift bit 0. If E is positive,\n * shift left bringing 0s into bit 35; data shifted out of bit 1 is lost; set Overflow if any bit of\n * significance is lost (a 1 in a positive number, a 0 in a negative one). If E is negative, shift right\n * bringing 0s into bit 1 if AC is positive, 1s if negative; data shifted out of bit 35 is lost.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opASH = function(op, ac)\n{\n /*\n * Convert the unsigned 18-bit value in regEA to a signed 8-bit value (-256 to 255).\n */\n var s = (((this.regEA & PDP10.HINT_LIMIT) << 14) >> 23) | (this.regEA & 0xff);\n if (s) {\n var v , bits;\n var w = this.readWord(ac);\n if (s > 0) {\n bits = PDP10.INT_MASK;\n v = (w < PDP10.INT_LIMIT)? 0 : PDP10.INT_LIMIT;\n if (s < 35) {\n v += (w * Math.pow(2, s)) % PDP10.INT_LIMIT;\n /*\n * bits must be set to the mask of all magnitude bits shifted out of\n * the original word. Using 8-bit signed words as an example, this table shows\n * the bits values that would correspond to shifting 1-7 bits left:\n *\n * shifts bits value calculation\n * ------ ----------- ------ -----------\n * 1 0b01000000 128-64 128-Math.pow(2, 7-1)\n * 2 0b01100000 128-32 128-Math.pow(2, 7-2)\n * 3 0b01110000 128-16 128-Math.pow(2, 7-3)\n * ...\n * 7 0b01111111 128-1 128-Math.pow(2, 7-7)\n */\n bits = PDP10.INT_LIMIT - Math.pow(2, 35 - s);\n }\n if (w < PDP10.INT_LIMIT) {\n /*\n * Since w was positive, overflow occurs ONLY if any of the bits we shifted out were 1s.\n * If all those bits in the original value (w) were 0s, then adding bits to it could NOT\n * produce a value > INT_MASK.\n */\n if (w + bits > PDP10.INT_MASK) {\n this.regPS |= PDP10.PSFLAG.AROV;\n }\n } else {\n /*\n * Since w was negative, overflow occurs ONLY if any of the bits we shifted out were 0s.\n * If all those bits in the original value (w) were 1s, subtracting bits from it could NOT\n * produce a value <= INT_MASK.\n */\n if (w - bits < PDP10.INT_LIMIT) {\n this.regPS |= PDP10.PSFLAG.AROV;\n }\n }\n } else {\n if (s <= -35) {\n v = (w < PDP10.INT_LIMIT)? 0 : PDP10.INT_MASK;\n } else {\n v = Math.trunc(w / Math.pow(2, -s));\n if (w > PDP10.INT_MASK) {\n bits = PDP10.WORD_LIMIT - Math.pow(2, 36 + s);\n v += bits;\n }\n }\n }\n\n this.writeWord(ac, v);\n }\n};\n\n/**\n * opROT(0o241000): Rotate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-25:\n *\n * Rotate AC the number of places specified by E. If E is positive, rotate left; bit 0 is rotated\n * into bit 35. If E is negative, rotate right; bit 35 is rotated into bit O.\n *\n * The number of places moved is specified by the result of the effective address calculation taken as\n * a signed number (in twos complement notation) modulo 2^8 in magnitude. In other words the effective\n * shift E is the number composed of bit 18 (which is the sign) and bits 28-35 of the calculation result.\n * Hence the programmer may specify the shift directly in the instruction (perhaps indexed) or give an\n * indirect address to be used in calculating the shift. A positive E produces motion to the left,\n * a negative E to the right; maximum movement is 255 places.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opROT = function(op, ac)\n{\n /*\n * Convert the unsigned 18-bit value in regEA to a signed 8-bit value, modulo 36 (+/-35).\n */\n var s = ((((this.regEA & PDP10.HINT_LIMIT) << 14) >> 23) | (this.regEA & 0xff)) % 36;\n if (s) {\n var w = this.readWord(ac);\n /*\n * Note that a right rotation (s < 0) of s bits is equivalent to a left rotation (s > 0) of 36 + s bits.\n */\n if (s < 0) s = 36 + s;\n w = ((w * Math.pow(2, s)) % PDP10.WORD_LIMIT) + Math.trunc(w / Math.pow(2, 36 - s));\n this.writeWord(ac, w);\n }\n};\n\n/**\n * opLSH(0o242000): Logical Shift\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-24:\n *\n * Shift and Rotate\n *\n * The remaining logical instructions shift or rotate right or left the contents of AC or the contents\n * of two accumulators, A and A+1 (mod 20 [base 8]), concatenated into a 72-bit register with A on the\n * left. The illustration below shows the movement of information these instructions produce in the\n * accumulators. In a (logical) shift the contents of a register are moved bit-to-bit with 0s brought\n * in at the end being vacated; information shifted out at the other end is lost. [For a discussion of\n * arithmetic shifting see § 2.5.] In rotation the contents are moved cyclically such that information\n * rotated out at one end is put in at the other.\n *\n * The number of places moved is specified by the result of the effective address calculation taken as a\n * signed number (in twos complement notation) modulo 2^8 in magnitude. In other words the effective shift\n * E is the number composed of bit 18 (which is the sign) and bits 28-35 of the calculation result. Hence\n * the programmer may specify the shift directly in the instruction (perhaps indexed) or give an indirect\n * address to be used in calculating the shift. A positive E produces motion to the left, a negative E to\n * the right; maximum movement is 255 places.\n *\n * LSH: Logical Shift\n *\n * Shift AC the number of places specified by E. If E is positive, shift left bringing 0s into bit 35;\n * data shifted out of bit 0 is lost. If E is negative, shift right bringing 0s into bit 0; data shifted\n * out of bit 35 is lost.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opLSH = function(op, ac)\n{\n /*\n * Convert the unsigned 18-bit value in regEA to a signed 8-bit value (-256 to 255).\n */\n var s = (((this.regEA & PDP10.HINT_LIMIT) << 14) >> 23) | (this.regEA & 0xff);\n if (s) {\n var w = this.readWord(ac);\n if (s > 0) {\n if (s >= 36) {\n w = 0;\n } else {\n w = (w * Math.pow(2, s)) % PDP10.WORD_LIMIT;\n }\n } else {\n if (s <= -36) {\n w = 0;\n } else {\n w = Math.trunc(w / Math.pow(2, -s));\n }\n }\n this.writeWord(ac, w);\n }\n};\n\n/**\n * opJFFO(0o243000): Jump if Find First One\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-56:\n *\n * If AC contains zero, clear AC A+1 and go on to the next instruction in sequence.\n *\n * If AC is not zero, count the number of leading 0s in it (0s to the left of the leftmost 1),\n * and place the count in AC A+1. Take the next instruction from location E and continue sequential\n * operation from there. In either case AC is unaffected, the original contents of AC A +1 are lost.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJFFO = function(op, ac)\n{\n var dst = 0;\n var src = this.readWord(ac);\n if (src) {\n while (src < PDP10.INT_LIMIT) {\n dst++;\n src *= 2;\n }\n this.setPC(this.regEA);\n }\n this.writeWord((ac + 1) & 0o17, dst);\n};\n\n/**\n * opASHC(0o244000): Arithmetic Shift\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-32:\n *\n * Concatenate the magnitude portions of accumulators A and A+1 with A on the left, and shift\n * the 70-bit combination in bits 1-35 and 37-71 the number of places specified by E. Do not shift\n * AC bit 0, but make bit 0 of AC A+1 equal to it if at least one shift occurs (ie if E is nonzero).\n *\n * If E is positive, shift left bringing 0s into bit 71 (bit 35 of AC A+1); bit 37 (bit 1 of AC A+1)\n * is shifted into bit 35; data shifted out of bit 1 is lost; set Overflow if any bit of significance\n * is lost (a 1 in a positive number, a 0 in a negative one). If E is negative, shift right bringing 0s\n * into bit 1 if AC is positive, 1s if negative; bit 35 is shifted into bit 37; data shifted out of\n * bit 71 is lost.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opASHC = function(op, ac)\n{\n /*\n * Convert the unsigned 18-bit value in regEA to a signed 8-bit value (-256 to 255).\n */\n var s = (((this.regEA & PDP10.HINT_LIMIT) << 14) >> 23) | (this.regEA & 0xff);\n if (s) {\n var bits;\n var wLeft = this.readWord(ac);\n var wRight = this.readWord((ac + 1) & 0o17);\n if (s > 0) {\n /*\n * Handle all the left shift cases below, which don't need to worry about sign-extension\n * but DO need to worry about overflow.\n */\n var wLeftOrig = wLeft;\n if (s >= 36) {\n /*\n * Since all wLeft bits are being shifted out, any positive value other than zero OR any negative value\n * other than WORD_MASK indicates an overflow.\n */\n if (wLeft > 0 && wLeft < PDP10.INT_LIMIT || wLeft > PDP10.INT_MASK && wLeft < PDP10.WORD_MASK) {\n this.regPS |= PDP10.PSFLAG.AROV;\n }\n if (s >= 71) {\n /*\n * Since all wRight bits are being shifted out, any positive value other than zero OR any negative value\n * other than WORD_MASK indicates an overflow.\n */\n if (wRight > 0 && wRight < PDP10.INT_LIMIT || wRight > PDP10.INT_MASK && wRight < PDP10.WORD_MASK) {\n this.regPS |= PDP10.PSFLAG.AROV;\n }\n wLeft = 0;\n } else {\n /*\n * Left shift 36-70 bits.\n */\n wLeft = (wRight * Math.pow(2, s - 35)) % PDP10.INT_LIMIT;\n bits = PDP10.INT_LIMIT - Math.pow(2, 70 - s);\n if (wLeftOrig <= PDP10.INT_MASK) {\n /*\n * Since wLeft was positive, overflow occurs ONLY if any of the bits we shifted out were 1s.\n * If all those bits in the original value were 0s, then adding bits to it could NOT produce\n * a value > INT_MASK.\n */\n if (wRight + bits > PDP10.INT_MASK) {\n this.regPS |= PDP10.PSFLAG.AROV;\n }\n } else {\n /*\n * Since wLeft was negative, overflow occurs ONLY if any of the bits we shifted out were 0s.\n * If all those bits in the original value were 1s, subtracting bits from it could NOT produce\n * a value <= INT_MASK.\n */\n if (wRight - bits <= PDP10.INT_MASK) {\n this.regPS |= PDP10.PSFLAG.AROV;\n }\n }\n }\n wRight = 0;\n if (wLeftOrig > PDP10.INT_MASK) {\n wLeft += PDP10.INT_LIMIT;\n wRight += PDP10.INT_LIMIT;\n }\n } else {\n /*\n * Left shift 1-35 bits.\n */\n wLeft = ((wLeft * Math.pow(2, s)) % PDP10.INT_LIMIT) + Math.trunc((wRight % PDP10.INT_LIMIT) / Math.pow(2, 35 - s));\n wRight = (wRight * Math.pow(2, s)) % PDP10.INT_LIMIT;\n /*\n * Determine overflow and update the sign bits.\n */\n bits = PDP10.INT_LIMIT - Math.pow(2, 35 - s);\n if (wLeftOrig <= PDP10.INT_MASK) {\n /*\n * Since wLeft was positive, overflow occurs ONLY if any of the bits we shifted out were 1s.\n * If all those bits in the original value were 0s, then adding bits to it could NOT produce\n * a value > INT_MASK.\n */\n if (wLeftOrig + bits > PDP10.INT_MASK) {\n this.regPS |= PDP10.PSFLAG.AROV;\n }\n } else {\n /*\n * Since wLeft was negative, overflow occurs ONLY if any of the bits we shifted out were 0s.\n * If all those bits in the original value were 1s, subtracting bits from it could NOT produce\n * a value <= INT_MASK.\n */\n if (wLeftOrig - bits <= PDP10.INT_MASK) {\n this.regPS |= PDP10.PSFLAG.AROV;\n }\n /*\n * Last but not least, update the sign bits of wLeft and wRight to indicate negative values.\n */\n wLeft += PDP10.INT_LIMIT;\n wRight += PDP10.INT_LIMIT;\n }\n }\n } else {\n /*\n * Handle all the right shift cases below, which don't need to worry about overflow but DO\n * need to worry about sign-extension.\n */\n if (s <= -36) {\n if (s <= -72) {\n wRight = (wLeft > PDP10.INT_MASK? PDP10.WORD_MASK : 0);\n } else {\n wRight = Math.trunc((wLeft % PDP10.INT_LIMIT) / Math.pow(2, -s - 35));\n }\n if (wLeft <= PDP10.INT_MASK) {\n wLeft = 0;\n } else {\n wLeft = PDP10.WORD_MASK;\n wRight += PDP10.INT_LIMIT;\n }\n } else {\n /*\n * For this right shift of 1-35 bits, determine the value of bits shifted in from the left.\n */\n bits = (wLeft > PDP10.INT_MASK? PDP10.WORD_LIMIT - Math.pow(2, 36 + s) : 0);\n /*\n * The bits that we add to wRight from wLeft must be shifted right one additional bit, because\n * they must \"skip over\" the sign bit of wRight. This means we must zero the sign bit of wRight,\n * which can be done by performing a \"mod\" with INT_LIMIT.\n */\n wRight = Math.trunc((wRight % PDP10.INT_LIMIT) / Math.pow(2, -s)) + (((wLeft % PDP10.INT_LIMIT) * Math.pow(2, 35 + s)) % PDP10.INT_LIMIT);\n wLeft = Math.trunc(wLeft / Math.pow(2, -s)) + bits;\n /*\n * Last but not least, we must set the sign of wRight to the sign of wLeft.\n */\n if (wLeft > PDP10.INT_MASK) wRight += PDP10.INT_LIMIT;\n }\n }\n this.writeWord(ac, wLeft);\n this.writeWord((ac + 1) & 0o17, wRight);\n }\n};\n\n/**\n * opROTC(0o245000): Rotate Combined\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-26:\n *\n * Concatenate accumulators A and A+1 with A on the left, and rotate the 72-bit combination the\n * number of places specified by E. If E is positive, rotate left; bit 0 is rotated into bit 71\n * (bit 35 of AC A+1) and bit 36 into bit 35. If E is negative, rotate right; bit 35 is rotated\n * into bit 36 and bit 71 into bit 0.\n *\n * The number of places moved is specified by the result of the effective address calculation taken as\n * a signed number (in twos complement notation) modulo 2^8 in magnitude. In other words the effective\n * shift E is the number composed of bit 18 (which is the sign) and bits 28-35 of the calculation result.\n * Hence the programmer may specify the shift directly in the instruction (perhaps indexed) or give an\n * indirect address to be used in calculating the shift. A positive E produces motion to the left,\n * a negative E to the right; maximum movement is 255 places.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opROTC = function(op, ac)\n{\n /*\n * Convert the unsigned 18-bit value in regEA to a signed 8-bit value, modulo 72 (+/-71).\n */\n var s = ((((this.regEA & PDP10.HINT_LIMIT) << 14) >> 23) | (this.regEA & 0xff)) % 72;\n if (s) {\n var wLeft = this.readWord(ac);\n var wRight = this.readWord((ac + 1) & 0o17);\n var wLeftOrig = wLeft;\n /*\n * Note that a right rotation (s < 0) of s bits is equivalent to a left rotation (s > 0) of 72 + s bits.\n */\n if (s < 0) s = 72 + s;\n if (s < 36) {\n wLeft = ((wLeft * Math.pow(2, s)) % PDP10.WORD_LIMIT) + Math.trunc(wRight / Math.pow(2, 36 - s));\n wRight = ((wRight * Math.pow(2, s)) % PDP10.WORD_LIMIT) + Math.trunc(wLeftOrig / Math.pow(2, 36 - s));\n } else {\n wLeft = ((wRight * Math.pow(2, s - 36)) % PDP10.WORD_LIMIT) + Math.trunc(wLeft / Math.pow(2, 72 - s));\n wRight = ((wLeftOrig * Math.pow(2, s - 36)) % PDP10.WORD_LIMIT) + Math.trunc(wRight / Math.pow(2, 72 - s));\n }\n this.writeWord(ac, wLeft);\n this.writeWord((ac + 1) & 0o17, wRight);\n }\n};\n\n/**\n * opLSHC(0o246000): Logical Shift Combined\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-25:\n *\n * Concatenate accumulators A and A+1 with A on the left, and shift the 72-bit combination the number\n * of places specified by E. If E is positive, shift left bringing 0s into bit 71 (bit 35 of AC A+1);\n * bit 36 is shifted into bit 35; data shifted out of bit 0 is lost. If E is negative, shift right\n * bringing 0s into bit 0; bit 35 is shifted into bit 36; data shifted out of bit 71 is lost.\n *\n * The number of places moved is specified by the result of the effective address calculation taken as\n * a signed number (in twos complement notation) modulo 2^8 in magnitude. In other words the effective\n * shift E is the number composed of bit 18 (which is the sign) and bits 28-35 of the calculation result.\n * Hence the programmer may specify the shift directly in the instruction (perhaps indexed) or give an\n * indirect address to be used in calculating the shift. A positive E produces motion to the left,\n * a negative E to the right; maximum movement is 255 places.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opLSHC = function(op, ac)\n{\n /*\n * Convert the unsigned 18-bit value in regEA to a signed 8-bit value (-256 to 255).\n */\n var s = (((this.regEA & PDP10.HINT_LIMIT) << 14) >> 23) | (this.regEA & 0xff);\n if (s) {\n var wLeft = this.readWord(ac);\n var wRight = this.readWord((ac + 1) & 0o17);\n if (s > 0) {\n if (s >= 36) {\n if (s >= 72) {\n wLeft = 0;\n } else {\n wLeft = (wRight * Math.pow(2, s - 36)) % PDP10.WORD_LIMIT;\n }\n wRight = 0;\n } else {\n wLeft = ((wLeft * Math.pow(2, s)) % PDP10.WORD_LIMIT) + Math.trunc(wRight / Math.pow(2, 36 - s));\n wRight = (wRight * Math.pow(2, s)) % PDP10.WORD_LIMIT;\n }\n } else {\n if (s <= -36) {\n if (s <= -72) {\n wRight = 0;\n } else {\n wRight = Math.trunc(wLeft / Math.pow(2, -s - 36));\n }\n wLeft = 0;\n } else {\n wRight = Math.trunc(wRight / Math.pow(2, -s)) + ((wLeft * Math.pow(2, 36 + s)) % PDP10.WORD_LIMIT);\n wLeft = Math.trunc(wLeft / Math.pow(2, -s));\n }\n }\n this.writeWord(ac, wLeft);\n this.writeWord((ac + 1) & 0o17, wRight);\n }\n};\n\n/**\n * opEXCH(0o250000): Exchange\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-9:\n *\n * Move the contents of location E to AC and move AC to location E.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opEXCH = function(op, ac)\n{\n var tmp = this.readWord(ac);\n this.writeWord(ac, this.readWord(this.regEA));\n this.writeWord(this.regEA, tmp);\n};\n\n/**\n * opBLT(0o251000): Block Transfer\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-10:\n *\n * Beginning at the location addressed by AC left, move words to another area of memory beginning at the\n * location addressed by AC right. Continue until a word is moved to location E. The total number of words\n * in the block is thus E - AC(right) + 1.\n *\n * CAUTION: Priority interrupts are allowed during the execution of this instruction, following the processing\n * of each word. If an interrupt occurs, the BLT stores the source and destination addresses for the next word\n * in AC, so when the processor restarts upon the return to the interrupted program, it actually resumes at\n * the correct point within the BLT. Therefore, unless the interrupt system is inactive, A and X must not address\n * the same register as this would produce a different effective address calculation upon resumption should an\n * interrupt occur; and the program must not attempt to load an accumulator addressed either by A or X unless it\n * is the final location being loaded. Furthermore, the program cannot assume that AC is the same after the BLT\n * as it was before.\n *\n * TODO: Determine the logic behind SIMH's treatment of the AC register when it's part of the memory being transferred.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opBLT = function(op, ac)\n{\n var fDone = false, fUpdate = false;\n var addrDst = this.readWord(ac);\n var addrSrc = (addrDst / PDP10.HALF_SHIFT)|0;\n addrDst &= PDP10.HALF_MASK;\n while (!fDone) {\n this.writeWord(addrDst, this.readWord(addrSrc));\n /*\n * NOTE: The PDP-10 specs (especially the KA10 Reference Manual) are not very clear on the exit criteria:\n * the transfer stops once AC left >= E, not AC left == E. They are also not very clear on whether the addresses\n * are incremented before or after the exit criteria is checked; however, the KA10 \"DAKAM\" diagnostic seems\n * pretty adamant that, at least after a one-word BLT operation, the addresses should NOT be incremented.\n */\n if (!(fDone = (addrDst >= this.regEA))) {\n addrSrc = (addrSrc + 1) & PDP10.HALF_MASK;\n addrDst = (addrDst + 1) & PDP10.HALF_MASK;\n fUpdate = true;\n }\n if (fDone || !this.isRunning()) {\n /*\n * If the CPU isn't currently running, the CPU is presumably being stepped, so we'll treat that the\n * same as the \"priority interrupt\" condition described above, update the addresses, rewind the PC, and leave.\n */\n if (fUpdate) this.writeWord(ac, addrSrc * PDP10.HALF_SHIFT + addrDst);\n if (!fDone) this.advancePC(-1);\n break;\n }\n }\n};\n\n/**\n * opAOBJP(0o252000): Add One to Both Halves of AC and Jump if Positive\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-41:\n *\n * Add 1000001 [base 8] to AC and place the result back in AC. If the result is greater than or equal\n * to zero (ie if bit 0 is 0, and hence a negative count in the left half has reached zero or a positive\n * count has not yet reached 2^17), take the next instruction from location E and continue sequential\n * operation from there.\n *\n * The incrementing of both halves of AC simultaneously is effected by adding 1000001 [base 8]. A count\n * of -2 in AC left is therefore increased to zero if 2^18 - 1 is incremented in AC right.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOBJP = function(op, ac)\n{\n var dst = (this.readWord(ac) + 0o000001000001) % PDP10.WORD_LIMIT;\n this.writeWord(ac, dst);\n if (dst < PDP10.INT_LIMIT) this.setPC(this.regEA);\n};\n\n/**\n * opAOBJN(0o253000): Add One to Both Halves of AC and Jump if Negative\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-41:\n *\n * Add 1000001 [base 8] to AC and place the result back in AC. If the result is less than zero\n * (ie if bit 0 is 1, and hence a negative count in the left half has not yet reached zero or a positive\n * count has reached 2^17), take the next instruction from location E and continue sequential operation\n * from there.\n *\n * The incrementing of both halves of AC simultaneously is effected by adding 1000001 [base 8]. A count\n * of -2 in AC left is therefore increased to zero if 2^18 - 1 is incremented in AC right.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOBJN = function(op, ac)\n{\n var dst = (this.readWord(ac) + 0o000001000001) % PDP10.WORD_LIMIT;\n this.writeWord(ac, dst);\n if (dst >= PDP10.INT_LIMIT) this.setPC(this.regEA);\n};\n\n/**\n * opJRST(0o254000): Jump and Restore\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-57:\n *\n * Perform the functions specified by F, then take the next instruction from location E and continue sequential\n * operation from there. Bits 9-12 are programmed as follows.\n *\n * 9 Restore the channel on which the highest priority interrupt is currently being held [§ 2.13].\n *\n * Unless the User In-out flag is set, this function cannot be executed in a user program. Instead\n * of restoring the channel, it stores its own instruction code, F and effective address E in bits 0-8,\n * 9-12 and 18-35 respectively of unrelocated location 40 (clearing bits 13-17), and then executes the\n * instruction contained in location 41, which is under control of the monitor [§ 2.15].\n *\n * 10 Halt the processor. When it stops, the MA lights on the console display an address one greater\n * than that of the location containing the instruction that caused the halt, and PC displays the jump\n * address (the location from which the next instruction will be taken if the operator causes the processor\n * to resume operation without changing PC).\n *\n * Unless the User In-out flag is set, this function cannot be executed in a user program. Instead of\n * halting the processor, it stores its own instruction code, F and effective address E in Bits 0-8, 9-12\n * and 18-35 respectively of unrelocated location 40 (clearing bits 13-17), and then executes the\n * instruction contained in location 41, which is under control of the monitor [§ 2.15].\n *\n * 11 Restore the flags listed above from the left half of the word in the last location referenced in the\n * effective address calculation. Hence to restore flags requires that the JRST instruction use indexing\n * or indirect addressing.\n *\n * Restoration of all but the user flags is directly according to the contents of the corresponding bits\n * as given above: a flag is set by a 1 in the bit, cleared by a 0. A 1 in bit 5 sets User but a 0 has no\n * effect, so the Monitor can restart a user program by restoring flags but the user cannot leave user\n * mode by this method. A 0 in bit 6 clears User In-out, but a 1 sets it only if the JRST is being\n * executed by the Monitor, ie if User is clear.\n *\n * 12 Enter user mode. The user program starts at relocated location E.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJRST = function(op, ac)\n{\n if (ac & 0b0001) {\n /*\n * Enter user mode.\n */\n this.setUserMode();\n }\n if (ac & 0b0010) {\n /*\n * Restore the flags.\n */\n this.setPS((this.regLA / PDP10.HALF_SHIFT)|0);\n }\n if (ac & 0b0100) {\n /*\n * Halt the processor.\n */\n this.stopCPU();\n }\n if (ac & 0b1000) {\n /*\n * Restore interrupt channel.\n */\n this.opUndefined(op);\n }\n this.setPC(this.regEA);\n};\n\n/**\n * opJFCL(0o255000): Jump on Flag and Clear\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-57:\n *\n * If any flag specified by F [ac] is set, clear it and take the next instruction from location E,\n * continuing sequential operation from there.\n *\n * To select one or a combination of these flags (which are among those described above) the programmer can specify\n * the equivalent of an AC address that places 1s in the appropriate bits, but MACRO recognizes mnemonics for some of\n * the 13-bit instruction codes (bits 0-12).\n *\n * JFCL JFCL 0, No-op 25500\n * JOV JFCL 10, Jump on Overflow 25540\n * JCRY0 JFCL 4, Jump on Carry 0 25520\n * JCRY1 JFCL 2, Jump on Carry 1 25510\n * JCRY JFCL 6, Jump on Carry 0 or 1 25530\n * JFOV JFCL 1, Jump on Floating Overflow 25504\n *\n * SIDEBAR: This instruction can be used simply to clear the selected flags by having the jump address point to the\n * next consecutive location, as in:\n *\n * JFCL 17,.+1\n *\n * which clears all four flags without disrupting the normal program sequence. A JFCL that selects no flag is the fastest\n * no-op as it neither fetches nor stores an operand, and bits 18-35 of the instruction word can be used to store information.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJFCL = function(op, ac)\n{\n /*\n * The ac (F) bits from the opcode align perfectly with the top 4 bits of regPS; all we have to do is shift ac left 14.\n */\n var bitsPS = ac << 14;\n if (this.regPS & bitsPS) {\n this.regPS &= ~bitsPS;\n this.setPC(this.regEA);\n }\n};\n\n/**\n * opXCT(0o256000): Execute\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-56:\n *\n * Execute the contents of location E as an instruction. Any instruction may be executed, including another XCT.\n * If an XCT executes a skip instruction, the skip is relative to the location of the XCT (the first XCT if there\n * are several in a chain). If an XCT executes a jump, program flow is altered as specified by the jump (no matter\n * how many XCTs precede a jump instruction, when PC is saved it contains an address one greater than the location\n * of the first XCT in the chain).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opXCT = function(op, ac)\n{\n this.regXC = this.regEA;\n};\n\n/**\n * opPUSHJ(0o260000): Push Down and Jump\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-62:\n *\n * Add 1000001 [base 8] to AC to increment both halves by one and place the result back in AC. If the addition\n * causes the count in AC left to reach zero, set the Pushdown Overflow flag. Then place the current contents of\n * the flags (as described above) in the left half of the location now addressed by AC right and the contents of\n * PC in the right half of that location (at this time PC contains an address one greater than the location of\n * the PUSHJ instruction). Take the next instruction from location E and continue sequential operation from there.\n *\n * The flags are unaffected except Byte Interrupt, which is cleared. The original contents of the location added\n * to the list are lost. If this instruction is executed as a result of a priority interrupt or in unrelocated\n * 41 or 61 while the processor is in user mode, bit 5 of the PC word stored is 1 and the processor leaves user mode.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opPUSHJ = function(op, ac)\n{\n var p = (this.readWord(ac) + 0o000001000001) % PDP10.WORD_LIMIT;\n this.writeWord(ac, p);\n if (!((p / PDP10.HALF_SHIFT)|0)) {\n this.regPS |= PDP10.PSFLAG.PDOV;\n }\n this.writeWord(p & PDP10.ADDR_MASK, this.getPS() * PDP10.HALF_SHIFT + this.getPC());\n this.regPS &= ~PDP10.PSFLAG.BIS; // TODO: Verify that BIS is cleared AFTER calling getPS()\n this.setPC(this.regEA);\n};\n\n/**\n * opPUSH(0o261000): Push Down\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-13:\n *\n * Add 000001 000001 to AC to increment both halves by one, then move the contents of location E to the\n * location now addressed by AC right. If the addition causes the count in AC left to reach zero, set the\n * Pushdown Overflow flag. The contents of E are unaffected, the original contents of the location added\n * to the list are lost.\n *\n * If we trusted SIMH, then we could not literally interpret this instruction as adding 000001 000001 to AC,\n * because if AC contained 777777 777777, adding 000001 000001 would result in 000001 000000, not 000000 000000,\n * and yet 000000 000000 is EXACTLY what we get in SIMH.\n *\n * And yet, DEC's documentation clearly contradicts what SIMH is doing:\n *\n * The incrementing and decrementing of both halves of AC simultaneously is effected by adding and subtracting\n * 000001 000001. Hence a count of -2 in AC left is increased to zero if 2^18 - 1 is incremented in AC right,\n * and conversely, 1 in AC left is decreased to -1 if zero is decremented in AC right.\n *\n * Perhaps SIMH is simply emulating the behavior of some later PDP-10 model, which performed independent increments?\n *\n * TODO: Investigate.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opPUSH = function(op, ac)\n{\n var p = this.readWord(ac);\n if (!PDP10.SIMH) {\n /*\n * This is the behavior that is clearly documented by DEC.\n */\n p += 0o000001000001;\n this.writeWord(p & PDP10.ADDR_MASK, this.readWord(this.regEA));\n if (p >= PDP10.WORD_LIMIT) p -= PDP10.WORD_LIMIT;\n if (!((p / PDP10.HALF_SHIFT)|0)) {\n this.regPS |= PDP10.PSFLAG.PDOV;\n }\n } else {\n /*\n * This is the SIMH behavior, which appears to increment each half of AC independently.\n */\n var addr = (p + 1) & PDP10.ADDR_MASK;\n this.writeWord(addr, this.readWord(this.regEA));\n p = (p + 0o000001000000) - (p & PDP10.ADDR_MASK) + addr;\n if (p >= PDP10.WORD_LIMIT) {\n p -= PDP10.WORD_LIMIT;\n this.regPS |= PDP10.PSFLAG.PDOV;\n }\n }\n this.writeWord(ac, p);\n};\n\n/**\n * opPOP(0o262000): Pop Up\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-13:\n *\n * Move the contents of the location addressed by AC right to location E, then subtract 000001 000001\n * from AC to decrement both halves by one. If the subtraction causes the count in AC left to reach -1,\n * set the Pushdown Overflow flag. The original contents of E are lost.\n *\n * NOTE: Because of the order in which the operands are stored, the instruction POP AC,AC would load the\n * contents of the location addressed by AC right into AC on top of the pushdown count, destroying it.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opPOP = function(op, ac)\n{\n var p = this.readWord(ac);\n var src = this.readWord(p & PDP10.ADDR_MASK);\n this.writeWord(this.regEA, src);\n if (this.regEA == ac) p = src; // this avoids re-reading the accumulator if the write just overwrote it\n p -= 0o000001000001;\n if (p < 0) p += PDP10.WORD_LIMIT;\n if (((p / PDP10.HALF_SHIFT)|0) == PDP10.HALF_MASK) {\n this.regPS |= PDP10.PSFLAG.PDOV;\n }\n this.writeWord(ac, p);\n};\n\n/**\n * opPOPJ(0o263000): Pop Up and Jump\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-63:\n *\n * Subtract 1000001 [base 8] from AC to decrement both halves by one and place the result back in AC.\n * If the subtraction causes the count in AC left to reach -1, set the Pushdown Overflow flag. Take the\n * next instruction from the location addressed by the right half of the location that was addressed by\n * AC right prior to the decrementing, and continue sequential operation from there.\n *\n * SIDEBAR: The effective address E is ignored.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opPOPJ = function(op, ac)\n{\n var p = this.readWord(ac);\n var pc = this.readWord(p & PDP10.ADDR_MASK);\n p -= 0o000001000001;\n if (p < 0) p += PDP10.WORD_LIMIT;\n if (((p / PDP10.HALF_SHIFT)|0) == PDP10.HALF_MASK) {\n this.regPS |= PDP10.PSFLAG.PDOV;\n }\n this.writeWord(ac, p);\n this.setPC(pc & PDP10.ADDR_MASK);\n};\n\n/**\n * opJSR(0o264000): Jump to Subroutine\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-57:\n *\n * Place the current contents of the flags (as described above) in the left half of location E and the\n * contents of PC in the right half (at this time PC contains an address one greater than the location of\n * the JSR instruction). Take the next instruction from location E + 1 and continue sequential operation\n * from there. The flags are unaffected except Byte Interrupt, which is cleared.\n *\n * If this instruction is executed as a result of a priority interrupt or in un-relocated 41 or 61 while\n * the processor is in user mode, bit 5 of the PC word stored is 1 and the processor leaves user mode.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJSR = function(op, ac)\n{\n this.writeWord(this.regEA, this.getPS() * PDP10.HALF_SHIFT + this.getPC());\n this.regPS &= ~PDP10.PSFLAG.BIS; // TODO: Verify that BIS is cleared AFTER calling getPS()\n this.setPC(this.regEA + 1);\n};\n\n/**\n * opJSP(0o265000): Jump and Save PC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-58:\n *\n * Place the current contents of the flags (as described above) in AC left and the contents of PC in AC right\n * (at this time PC contains an address one greater than the location of the JSP instruction). Take the next\n * instruction from location E and continue sequential operation from there. The flags are unaffected except\n * Byte Interrupt, which is cleared.\n *\n * If this instruction is executed as a result of a priority interrupt or in un-relocated 41 or 61 while the\n * processor is in user mode, bit 5 of the PC word stored is 1 and the processor leaves user mode.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJSP = function(op, ac)\n{\n this.writeWord(ac, this.getPS() * PDP10.HALF_SHIFT + this.getPC());\n this.regPS &= ~PDP10.PSFLAG.BIS; // TODO: Verify that BIS is cleared AFTER calling getPS()\n this.setPC(this.regEA);\n};\n\n/**\n * opJSA(0o266000): Jump and Save AC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-61:\n *\n * Place AC in location E, the effective address E in AC left, and the contents of PC in AC right (at this time\n * PC contains an address one greater than the location of the JSA instruction). Take the next instruction from\n * location E + 1 and continue sequential operation from there. The original contents of E are lost.\n *\n * If this instruction is executed as a result of a priority interrupt or in unrelocated 41 or 61 while the processor\n * is in user mode, bit 5 of the PC word stored is 1 and the processor leaves user mode.\n *\n * Regarding JSA and JRA:\n *\n * A JSA combines advantages of the JSR and JSP. JSA does modify memory, but it saves PC in an accumulator\n * without losing its previous contents (at a cost of not saving the flags). It is thus convenient for multiple-entry\n * subroutines. In a subroutine called by a JSR, the returning JRST must refer to the (single) entry point.\n * Since a JRA can retrieve the original PC by addressing AC as an index register, it is independent of any entry point\n * without tying up an accumulator to the extent a JSP would.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJSA = function(op, ac)\n{\n this.writeWord(this.regEA, this.readWord(ac));\n this.writeWord(ac, this.regEA * PDP10.HALF_SHIFT + this.getPC());\n this.setPC(this.regEA + 1);\n};\n\n/**\n * opJRA(0o267000): Jump and Restore AC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-61:\n *\n * Place the contents of the location addressed by AC left into AC. Take the next instruction from location E and\n * continue sequential operation from there.\n *\n * This opcode functions as the counterpart to JSA, but ONLY if location E (the effective address calculated by the JRA) indexes\n * with the same AC that was used with the JSA.\n *\n * JSA 17,F1\n * R1: ...\n * ...\n * F1: 0 ; location to save AC 17, as specified by the A field of \"JSA 17,F1\"\n * F2: ... ; first instruction executed after \"JSA 17,F1\"\n * JRA 17,(17) ; return to R1, after restoring AC 17\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJRA = function(op, ac)\n{\n var acc = this.readWord(ac);\n this.writeWord(ac, this.readWord((acc / PDP10.HALF_SHIFT)|0));\n this.setPC(this.regEA);\n};\n\n/**\n * opADD(0o270000): Add\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27:\n *\n * Add the operand specified by M to AC and place the result in the specified destination. If the sum is >= 2^35\n * set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the sum less 2^35.\n * If the sum is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but a magnitude in negative form equal\n * to the sum plus 2^35. Set both carry flags if both summands are negative, or their signs differ and their magnitudes\n * are equal or the positive one is the greater in magnitude.\n *\n * NOTE: This is a \"Basic\" mode instruction: the source is [E] and the destination is [A] (opposite of \"Memory\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opADD = function(op, ac)\n{\n this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opADDI(0o271000): Add Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27:\n *\n * Add the operand specified by M to AC and place the result in the specified destination. If the sum is >= 2^35\n * set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the sum less 2^35.\n * If the sum is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but a magnitude in negative form equal\n * to the sum plus 2^35. Set both carry flags if both summands are negative, or their signs differ and their magnitudes\n * are equal or the positive one is the greater in magnitude.\n *\n * NOTE: This is an \"Immediate\" mode instruction: the source is the word 0,E and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opADDI = function(op, ac)\n{\n this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), this.regEA));\n};\n\n/**\n * opADDM(0o272000): Add to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27:\n *\n * Add the operand specified by M to AC and place the result in the specified destination. If the sum is >= 2^35\n * set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the sum less 2^35.\n * If the sum is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but a magnitude in negative form equal\n * to the sum plus 2^35. Set both carry flags if both summands are negative, or their signs differ and their magnitudes\n * are equal or the positive one is the greater in magnitude.\n *\n * NOTE: This is a \"Memory\" mode instruction: the source is [E] and the destination is [E] (opposite of \"Basic\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opADDM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opADDB(0o273000): Add to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27:\n *\n * Add the operand specified by M to AC and place the result in the specified destination. If the sum is >= 2^35\n * set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the sum less 2^35.\n * If the sum is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but a magnitude in negative form equal\n * to the sum plus 2^35. Set both carry flags if both summands are negative, or their signs differ and their magnitudes\n * are equal or the positive one is the greater in magnitude.\n *\n * NOTE: This is a \"Both\" mode instruction: the source is [E] and the destination is [E] and [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opADDB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), this.readWord(this.regEA))));\n};\n\n/**\n * opSUB(0o274000): Subtract\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27:\n *\n * Subtract the operand specified by M from AC and place the result in the specified destination. If the difference\n * is >= 2^35 set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the\n * difference less 2^35. If the difference is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but\n * a magnitude in negative form equal to the difference plus 2^35. Set both carry flags if the signs of the operands are\n * the same and AC is the greater or the two are equal, or the signs of the operands differ and AC is negative.\n *\n * NOTE: This is a \"Basic\" mode instruction: the source is [E] and the destination is [A] (opposite of \"Memory\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSUB = function(op, ac)\n{\n this.writeWord(ac, PDP10.doSUB.call(this, this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opSUBI(0o275000): Subtract Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27:\n *\n * Subtract the operand specified by M from AC and place the result in the specified destination. If the difference\n * is >= 2^35 set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the\n * difference less 2^35. If the difference is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but\n * a magnitude in negative form equal to the difference plus 2^35. Set both carry flags if the signs of the operands are\n * the same and AC is the greater or the two are equal, or the signs of the operands differ and AC is negative.\n *\n * NOTE: This is an \"Immediate\" mode instruction: the source is the word 0,E and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSUBI = function(op, ac)\n{\n this.writeWord(ac, PDP10.doSUB.call(this, this.readWord(ac), this.regEA));\n};\n\n/**\n * opSUBM(0o276000): Subtract to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27:\n *\n * Subtract the operand specified by M from AC and place the result in the specified destination. If the difference\n * is >= 2^35 set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the\n * difference less 2^35. If the difference is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but\n * a magnitude in negative form equal to the difference plus 2^35. Set both carry flags if the signs of the operands are\n * the same and AC is the greater or the two are equal, or the signs of the operands differ and AC is negative.\n *\n * NOTE: This is a \"Memory\" mode instruction: the source is [E] and the destination is [E] (opposite of \"Basic\").\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSUBM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.doSUB.call(this, this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opSUBB(0o277000): Subtract to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-27:\n *\n * Subtract the operand specified by M from AC and place the result in the specified destination. If the difference\n * is >= 2^35 set Overflow and Carry 1; the result stored has a minus sign but a magnitude in positive form equal to the\n * difference less 2^35. If the difference is < -2^35 set Overflow and Carry 0; the result stored has a plus sign but\n * a magnitude in negative form equal to the difference plus 2^35. Set both carry flags if the signs of the operands are\n * the same and AC is the greater or the two are equal, or the signs of the operands differ and AC is negative.\n *\n * NOTE: This is a \"Both\" mode instruction: the source is [E] and the destination is [E] and [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSUBB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.doSUB.call(this, this.readWord(ac), this.readWord(this.regEA))));\n};\n\n/**\n * opCAIL(0o301000): Compare AC Immediate and Skip if AC Less than E\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42:\n *\n * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition\n * specified by M is satisfied.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAIL = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.regEA) < 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAIE(0o302000): Compare AC Immediate and Skip if Equal\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42:\n *\n * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition\n * specified by M is satisfied.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAIE = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.regEA) == 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAILE(0o303000): Compare AC Immediate and Skip if AC Less than or Equal to E\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42:\n *\n * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition\n * specified by M is satisfied.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAILE = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.regEA) <= 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAIA(0o304000): Compare AC Immediate but Always Skip\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42:\n *\n * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition\n * specified by M is satisfied.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAIA = function(op, ac)\n{\n // TODO: Determine if there's any need to actually perform the comparison.\n this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAIGE(0o305000): Compare AC Immediate and Skip if AC Greater than or Equal to E\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42:\n *\n * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition\n * specified by M is satisfied.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAIGE = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.regEA) >= 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAIN(0o306000): Compare AC Immediate and Skip if Not Equal\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42:\n *\n * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition\n * specified by M is satisfied.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAIN = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.regEA) != 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAIG(0o307000): Compare AC Immediate and Skip if AC Greater than E\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-42:\n *\n * Compare AC with E (ie with the word 0,E) and skip the next instruction in sequence if the condition\n * specified by M is satisfied.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAIG = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.regEA) > 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAML(0o311000): Compare AC with Memory and Skip if AC Less\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC with the contents of location E and skip the next instruction in sequence if the condition\n * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized\n * floating point.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAML = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.readWord(this.regEA)) < 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAME(0o312000): Compare AC with Memory and Skip if Equal\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC with the contents of location E and skip the next instruction in sequence if the condition\n * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized\n * floating point.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAME = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.readWord(this.regEA)) == 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAMLE(0o313000): Compare AC with Memory and Skip if AC Less or Equal\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC with the contents of location E and skip the next instruction in sequence if the condition\n * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized\n * floating point.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAMLE = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.readWord(this.regEA)) <= 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAMA(0o314000): Compare AC with Memory but Always Skip\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC with the contents of location E and skip the next instruction in sequence if the condition\n * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized\n * floating point.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAMA = function(op, ac)\n{\n // TODO: Determine if there's any need to actually perform the comparison.\n this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAMGE(0o315000): Compare AC with Memory and Skip if AC Greater or Equal\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC with the contents of location E and skip the next instruction in sequence if the condition\n * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized\n * floating point.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAMGE = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.readWord(this.regEA)) >= 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAMN(0o316000): Compare AC with Memory and Skip if Not Equal\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC with the contents of location E and skip the next instruction in sequence if the condition\n * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized\n * floating point.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAMN = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.readWord(this.regEA)) != 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opCAMG(0o317000): Compare AC with Memory and Skip if AC Greater\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC with the contents of location E and skip the next instruction in sequence if the condition\n * specified by M is satisfied. The pair of numbers compared may be either both fixed or both normalized\n * floating point.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opCAMG = function(op, ac)\n{\n if (PDP10.CMP(this.readWord(ac), this.readWord(this.regEA)) > 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opJUMPL(0o321000): Jump if AC Less than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied,\n * take the next instruction from location E and continue sequential operation from there.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJUMPL = function(op, ac)\n{\n if (PDP10.SIGN(this.readWord(ac)) < 0) this.setPC(this.regEA);\n};\n\n/**\n * opJUMPE(0o322000): Jump if AC Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied,\n * take the next instruction from location E and continue sequential operation from there.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJUMPE = function(op, ac)\n{\n if (PDP10.SIGN(this.readWord(ac)) == 0) this.setPC(this.regEA);\n};\n\n/**\n * opJUMPLE(0o323000): Jump if AC Less than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied,\n * take the next instruction from location E and continue sequential operation from there.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJUMPLE = function(op, ac)\n{\n if (PDP10.SIGN(this.readWord(ac)) <= 0) this.setPC(this.regEA);\n};\n\n/**\n * opJUMPA(0o324000): Jump Always\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied,\n * take the next instruction from location E and continue sequential operation from there.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJUMPA = function(op, ac)\n{\n this.setPC(this.regEA);\n};\n\n/**\n * opJUMPGE(0o325000): Jump if AC Greater than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied,\n * take the next instruction from location E and continue sequential operation from there.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJUMPGE = function(op, ac)\n{\n if (PDP10.SIGN(this.readWord(ac)) >= 0) this.setPC(this.regEA);\n};\n\n/**\n * opJUMPN(0o326000): Jump if AC Not Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied,\n * take the next instruction from location E and continue sequential operation from there.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJUMPN = function(op, ac)\n{\n if (PDP10.SIGN(this.readWord(ac)) != 0) this.setPC(this.regEA);\n};\n\n/**\n * opJUMPG(0o327000): Jump if AC Greater than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-43:\n *\n * Compare AC (fixed or floating) with zero, and if the condition specified by M is satisfied,\n * take the next instruction from location E and continue sequential operation from there.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opJUMPG = function(op, ac)\n{\n if (PDP10.SIGN(this.readWord(ac)) > 0) this.setPC(this.regEA);\n};\n\n/**\n * opSKIP(0o330000): Do Not Skip\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction\n * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents\n * of location E in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSKIP = function(op, ac)\n{\n if (ac) this.writeWord(ac, this.readWord(this.regEA));\n};\n\n/**\n * opSKIPL(0o331000): Skip if Memory Less than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction\n * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents\n * of location E in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSKIPL = function(op, ac)\n{\n var dst = this.readWord(this.regEA);\n if (PDP10.SIGN(dst) < 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSKIPE(0o332000): Skip if Memory Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction\n * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents\n * of location E in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSKIPE = function(op, ac)\n{\n var dst = this.readWord(this.regEA);\n if (PDP10.SIGN(dst) == 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSKIPLE(0o333000): Skip if Memory Less than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction\n * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents\n * of location E in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSKIPLE = function(op, ac)\n{\n var dst = this.readWord(this.regEA);\n if (PDP10.SIGN(dst) <= 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSKIPA(0o334000): Skip Always\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction\n * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents\n * of location E in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSKIPA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, this.readWord(this.regEA));\n};\n\n/**\n * opSKIPGE(0o335000): Skip if Memory Greater than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction\n * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents\n * of location E in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSKIPGE = function(op, ac)\n{\n var dst = this.readWord(this.regEA);\n if (PDP10.SIGN(dst) >= 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSKIPN(0o336000): Skip if Memory Not Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction\n * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents\n * of location E in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSKIPN = function(op, ac)\n{\n var dst = this.readWord(this.regEA);\n if (PDP10.SIGN(dst) != 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSKIPG(0o337000): Skip if Memory Greater than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Compare the contents (fixed or floating) of location E with zero, and skip the next instruction\n * in sequence if the condition specified by M is satisfied. If A is nonzero also place the contents\n * of location E in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSKIPG = function(op, ac)\n{\n var dst = this.readWord(this.regEA);\n if (PDP10.SIGN(dst) > 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opAOJ(0o340000): Add One to AC but Do Not Jump\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Increment AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue\n * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1\n * flags; if -1, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOJ = function(op, ac)\n{\n this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1));\n};\n\n/**\n * opAOJL(0o341000): Add One to AC and Jump if Less than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Increment AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue\n * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1\n * flags; if -1, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOJL = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1));\n if (PDP10.SIGN(dst) < 0) this.setPC(this.regEA);\n};\n\n/**\n * opAOJE(0o342000): Add One to AC and Jump if Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Increment AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue\n * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1\n * flags; if -1, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOJE = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1));\n if (PDP10.SIGN(dst) == 0) this.setPC(this.regEA);\n};\n\n/**\n * opAOJLE(0o343000): Add One to AC and Jump if Less than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Increment AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue\n * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1\n * flags; if -1, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOJLE = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1));\n if (PDP10.SIGN(dst) <= 0) this.setPC(this.regEA);\n};\n\n/**\n * opAOJA(0o344000): Add One to AC and Jump Always\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Increment AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue\n * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1\n * flags; if -1, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOJA = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1));\n this.setPC(this.regEA);\n};\n\n/**\n * opAOJGE(0o345000): Add One to AC and Jump if Greater than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Increment AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue\n * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1\n * flags; if -1, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOJGE = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1));\n if (PDP10.SIGN(dst) >= 0) this.setPC(this.regEA);\n};\n\n/**\n * opAOJN(0o346000): Add One to AC and Jump if Not Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Increment AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue\n * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1\n * flags; if -1, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOJN = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1));\n if (PDP10.SIGN(dst) != 0) this.setPC(this.regEA);\n};\n\n/**\n * opAOJG(0o347000): Add One to AC and Jump if Greater than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-44:\n *\n * Increment AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue\n * sequential operation from there. If AC originally contained 2^35 - 1, set the Overflow and Carry 1\n * flags; if -1, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOJG = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), 1));\n if (PDP10.SIGN(dst) > 0) this.setPC(this.regEA);\n};\n\n/**\n * opAOS(0o350000): Add One to Memory but Do Not Skip\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Increment the contents of location E by one and place the result back in E. Compare the result\n * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied.\n * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0\n * and Carry 1. If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOS = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1));\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opAOSL(0o351000): Add One to Memory and Skip if Less than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Increment the contents of location E by one and place the result back in E. Compare the result\n * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied.\n * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0\n * and Carry 1. If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOSL = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1));\n if (PDP10.SIGN(dst) < 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opAOSE(0o352000): Add One to Memory and Skip if Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Increment the contents of location E by one and place the result back in E. Compare the result\n * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied.\n * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0\n * and Carry 1. If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOSE = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1));\n if (PDP10.SIGN(dst) == 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opAOSLE(0o353000): Add One to Memory and Skip if Less than to Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Increment the contents of location E by one and place the result back in E. Compare the result\n * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied.\n * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0\n * and Carry 1. If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOSLE = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1));\n if (PDP10.SIGN(dst) <= 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opAOSA(0o354000): Add One to Memory and Skip Always\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Increment the contents of location E by one and place the result back in E. Compare the result\n * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied.\n * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0\n * and Carry 1. If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOSA = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1));\n this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opAOSGE(0o355000): Add One to Memory and Skip if Greater than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Increment the contents of location E by one and place the result back in E. Compare the result\n * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied.\n * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0\n * and Carry 1. If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOSGE = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1));\n if (PDP10.SIGN(dst) >= 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opAOSN(0o356000): Add One to Memory and Skip if Not Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Increment the contents of location E by one and place the result back in E. Compare the result\n * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied.\n * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0\n * and Carry 1. If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOSN = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1));\n if (PDP10.SIGN(dst) != 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opAOSG(0o357000): Add One to Memory and Skip if Greater than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Increment the contents of location E by one and place the result back in E. Compare the result\n * with zero, and skip the next instruction in sequence if the condition specified by M is satisfied.\n * If location E originally contained 2^35 - 1, set the Overflow and Carry 1 flags; if -1, set Carry 0\n * and Carry 1. If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAOSG = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), 1));\n if (PDP10.SIGN(dst) > 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSOJ(0o360000): Subtract One from AC but Do Not Jump\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue sequential\n * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any\n * other nonzero number, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOJ = function(op, ac)\n{\n this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK));\n};\n\n/**\n * opSOJL(0o361000): Subtract One from AC and Jump if Less than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue sequential\n * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any\n * other nonzero number, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOJL = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) < 0) this.setPC(this.regEA);\n};\n\n/**\n * opSOJE(0o362000): Subtract One from AC and Jump if Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue sequential\n * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any\n * other nonzero number, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOJE = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) == 0) this.setPC(this.regEA);\n};\n\n/**\n * opSOJLE(0o363000): Subtract One from AC and Jump if Less than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue sequential\n * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any\n * other nonzero number, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOJLE = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) <= 0) this.setPC(this.regEA);\n};\n\n/**\n * opSOJA(0o364000): Subtract One from AC and Jump Always\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue sequential\n * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any\n * other nonzero number, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOJA = function(op, ac)\n{\n this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK));\n this.setPC(this.regEA);\n};\n\n/**\n * opSOJGE(0o365000): Subtract One from AC and Jump if Greater than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue sequential\n * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any\n * other nonzero number, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOJGE = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) >= 0) this.setPC(this.regEA);\n};\n\n/**\n * opSOJN(0o366000): Subtract One from AC and Jump if Not Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue sequential\n * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any\n * other nonzero number, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOJN = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) != 0) this.setPC(this.regEA);\n};\n\n/**\n * opSOJG(0o367000): Subtract One from AC and Jump if Greater than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-45:\n *\n * Decrement AC by one and place the result back in AC. Compare the result with zero, and if the\n * condition specified by M is satisfied, take the next instruction from location E and continue sequential\n * operation from there. If AC originally contained - 2^35 , set the Overflow and Carry 0 flags; if any\n * other nonzero number, set Carry 0 and Carry 1.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOJG = function(op, ac)\n{\n var dst = this.writeWord(ac, PDP10.doADD.call(this, this.readWord(ac), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) > 0) this.setPC(this.regEA);\n};\n\n/**\n * opSOS(0o370000): Subtract One from Memory but Do Not Skip\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46:\n *\n * Decrement the contents of location E by one and place the result back in E. Compare the result with zero,\n * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally\n * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1.\n * If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOS = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK));\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSOSL(0o371000): Subtract One from Memory and Skip if Less than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46:\n *\n * Decrement the contents of location E by one and place the result back in E. Compare the result with zero,\n * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally\n * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1.\n * If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOSL = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) < 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSOSE(0o372000): Subtract One from Memory and Skip if Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46:\n *\n * Decrement the contents of location E by one and place the result back in E. Compare the result with zero,\n * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally\n * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1.\n * If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOSE = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) == 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSOSLE(0o373000): Subtract One from Memory and Skip if Less than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46:\n *\n * Decrement the contents of location E by one and place the result back in E. Compare the result with zero,\n * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally\n * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1.\n * If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOSLE = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) <= 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSOSA(0o374000): Subtract One from Memory and Skip Always\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46:\n *\n * Decrement the contents of location E by one and place the result back in E. Compare the result with zero,\n * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally\n * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1.\n * If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOSA = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK));\n this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSOSGE(0o375000): Subtract One from Memory and Skip if Greater than or Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46:\n *\n * Decrement the contents of location E by one and place the result back in E. Compare the result with zero,\n * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally\n * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1.\n * If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOSGE = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) >= 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSOSN(0o376000): Subtract One from Memory and Skip if Not Equal to Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46:\n *\n * Decrement the contents of location E by one and place the result back in E. Compare the result with zero,\n * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally\n * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1.\n * If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOSN = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) != 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSOSG(0o377000): Subtract One from Memory and Skip if Greater than Zero\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-46:\n *\n * Decrement the contents of location E by one and place the result back in E. Compare the result with zero,\n * and skip the next instruction in sequence if the condition specified by M is satisfied. If location E originally\n * contained -2^35 , set the Overflow and Carry 0 flags; if any other nonzero number, set Carry 0 and Carry 1.\n * If A is nonzero also place the result in AC.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSOSG = function(op, ac)\n{\n var dst = this.writeWord(this.regEA, PDP10.doADD.call(this, this.readWord(this.regEA), PDP10.WORD_MASK));\n if (PDP10.SIGN(dst) > 0) this.setPC(this.regPC + 1);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opSETZ(0o400000): Set to Zeros\n * opSETZI(0o401000): Set to Zeros Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-18:\n *\n * Change the contents of the destination specified by M to all 0s.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETZ = function(op, ac)\n{\n this.writeWord(ac, 0);\n};\n\n/**\n * opSETZM(0o402000): Set to Zeros Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-18:\n *\n * Change the contents of the destination specified by M to all 0s.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETZM = function(op, ac)\n{\n this.writeWord(this.regEA, 0);\n};\n\n/**\n * opSETZB(0o403000): Set to Zeros Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-18:\n *\n * Change the contents of the destination specified by M to all 0s.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETZB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, 0));\n};\n\n/**\n * opAND(0o404000): And with AC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([AC]) to the AND function of the specified operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opAND = function(op, ac)\n{\n this.writeWord(ac, PDP10.AND(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opANDI(0o405000): And with AC Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([AC]) to the AND function of the specified operand (E) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDI = function(op, ac)\n{\n this.writeWord(ac, PDP10.AND(this.readWord(ac), this.regEA));\n};\n\n/**\n * opANDM(0o406000): And with AC to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([E]) to the AND function of the specified operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.AND(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opANDB(0o407000): And with AC to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the AND function of the specified operand ([E])\n * and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.AND(this.readWord(ac), this.readWord(this.regEA))));\n};\n\n/**\n * opANDCA(0o410000): And with Complement of AC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([AC]) to the AND function of the specified operand ([E])\n * and the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCA = function(op, ac)\n{\n this.writeWord(ac, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opANDCAI(0o411000): And with Complement of AC Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([AC]) to the AND function of the specified operand (E)\n * and the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCAI = function(op, ac)\n{\n this.writeWord(ac, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), this.regEA));\n};\n\n/**\n * opANDCAM(0o412000): And with Complement of AC to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([E]) to the AND function of the specified operand ([E])\n * and the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCAM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opANDCAB(0o413000): And with Complement of AC to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the AND function of the specified operand ([E])\n * and the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCAB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), this.readWord(this.regEA))));\n};\n\n/**\n * opANDCM(0o420000): And Complement of Memory with AC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([AC]) to the AND function of the complement of the specified\n * operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCM = function(op, ac)\n{\n this.writeWord(ac, PDP10.AND(this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA)));\n};\n\n/**\n * opANDCMI(0o421000): And Complement of Memory Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([AC]) to the AND function of the complement of the specified\n * operand (E) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCMI = function(op, ac)\n{\n this.writeWord(ac, PDP10.AND(this.readWord(ac), PDP10.WORD_MASK - this.regEA));\n};\n\n/**\n * opANDCMM(0o422000): And Complement of Memory to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([E]) to the AND function of the complement of the specified\n * operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCMM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.AND(this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA)));\n};\n\n/**\n * opANDCMB(0o423000): And Complement of Memory to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-20:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the AND function of the complement of the specified\n * operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCMB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.AND(this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA))));\n};\n\n/**\n * opXOR(0o430000): Exclusive Or with AC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([AC]) to the exclusive OR function of the specified\n * operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opXOR = function(op, ac)\n{\n this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opXORI(0o431000): Exclusive Or Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([AC]) to the exclusive OR function of the specified\n * operand (E) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opXORI = function(op, ac)\n{\n this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.regEA));\n};\n\n/**\n * opXORM(0o432000): Exclusive Or to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([E]) to the exclusive OR function of the specified\n * operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opXORM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.XOR(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opXORB(0o433000): Exclusive Or to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the exclusive OR function of the specified\n * operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opXORB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.readWord(this.regEA))));\n};\n\n/**\n * opIOR(0o434000): Inclusive Or with AC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the specified\n * operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIOR = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opIORI(0o435000): Inclusive Or with AC Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the specified\n * operand (E) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIORI = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.regEA));\n};\n\n/**\n * opIORM(0o436000): Inclusive Or with AC to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([E]) to the inclusive OR function of the specified\n * operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIORM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.IOR(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opIORB(0o437000): Inclusive Or with AC to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the inclusive OR function of the specified\n * operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opIORB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.readWord(this.regEA))));\n};\n\n/**\n * opANDCB(0o440000): And Complements of Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([AC]) to the AND function of the complements of both\n * the specified operand ([E]) and [AC]. The result is the NOR function of the operands.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCB = function(op, ac)\n{\n this.writeWord(ac, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA)));\n};\n\n/**\n * opANDCBI(0o441000): And Complements of Both Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([AC]) to the AND function of the complements of both\n * the specified operand (E) and [AC]. The result is the NOR function of the operands.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCBI = function(op, ac)\n{\n this.writeWord(ac, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.regEA));\n};\n\n/**\n * opANDCBM(0o442000): And Complements of Both to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([E]) to the AND function of the complements of both\n * the specified operand ([E]) and [AC]. The result is the NOR function of the operands.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCBM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA)));\n};\n\n/**\n * opANDCBB(0o443000): And Complements of Both to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the AND function of the complements of both\n * the specified operand ([E]) and [AC]. The result is the NOR function of the operands.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opANDCBB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.AND(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA))));\n};\n\n/**\n * opEQV(0o444000): Equivalence with AC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-23:\n *\n * Change the contents of the destination specified by M ([AC]) to the complement of the exclusive OR function of the\n * specified operand ([E]) and [AC] (the result has 1s wherever the corresponding bits of the operands are the same).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opEQV = function(op, ac)\n{\n this.writeWord(ac, PDP10.EQV(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opEQVI(0o445000): Equivalence Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-23:\n *\n * Change the contents of the destination specified by M ([AC]) to the complement of the exclusive OR function of the\n * specified operand (E) and [AC] (the result has 1s wherever the corresponding bits of the operands are the same).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opEQVI = function(op, ac)\n{\n this.writeWord(ac, PDP10.EQV(this.readWord(ac), this.regEA));\n};\n\n/**\n * opEQVM(0o446000): Equivalence to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-23:\n *\n * Change the contents of the destination specified by M ([E]) to the complement of the exclusive OR function of the\n * specified operand ([E]) and [AC] (the result has 1s wherever the corresponding bits of the operands are the same).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opEQVM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.EQV(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opEQVB(0o447000): Equivalence to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-23:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the complement of the exclusive OR function of the\n * specified operand ([E]) and [AC] (the result has 1s wherever the corresponding bits of the operands are the same).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opEQVB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.EQV(this.readWord(ac), this.readWord(this.regEA))));\n};\n\n/**\n * opSETCA(0o450000): Set to Complement of AC\n * opSETCAI(0o451000): Set to Complement of AC Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19:\n *\n * Change the contents of the destination specified by M ([AC]) to the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETCA = function(op, ac)\n{\n this.writeWord(ac, PDP10.WORD_MASK - this.readWord(ac));\n};\n\n/**\n * opSETCAM(0o452000): Set to Complement of AC Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19:\n *\n * Change the contents of the destination specified by M ([E]) to the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETCAM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.WORD_MASK - this.readWord(ac));\n};\n\n/**\n * opSETCAB(0o453000): Set to Complement of AC Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETCAB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.WORD_MASK - this.readWord(ac)));\n};\n\n/**\n * opORCA(0o454000): Inclusive Or with Complement of AC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the specified\n * operand ([E]) and the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCA = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opORCAI(0o455000): Inclusive Or with Complement of AC Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the specified\n * operand (E) and the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCAI = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), this.regEA));\n};\n\n/**\n * opORCAM(0o456000): Inclusive Or with Complement of AC to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([E]) to the inclusive OR function of the specified\n * operand ([E]) and the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCAM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opORCAB(0o457000): Inclusive Or with Complement of AC to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-21:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the inclusive OR function of the specified\n * operand ([E]) and the complement of [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCAB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), this.readWord(this.regEA))));\n};\n\n/**\n * opSETCM(0o460000): Set to Complement of Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19:\n *\n * Change the contents of the destination specified by M ([AC]) to the complement of the specified source\n * operand ([E]).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETCM = function(op, ac)\n{\n this.writeWord(ac, PDP10.WORD_MASK - this.readWord(this.regEA));\n};\n\n/**\n * opSETCMI(0o461000): Set to Complement of Memory Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19:\n *\n * Change the contents of the destination specified by M ([AC]) to the complement of the specified source\n * operand (E).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETCMI = function(op, ac)\n{\n this.writeWord(ac, PDP10.WORD_MASK - this.regEA);\n};\n\n/**\n * opSETCMM(0o462000): Set to Complement of Memory Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19:\n *\n * Change the contents of the destination specified by M ([E]) to the complement of the specified source\n * operand ([E]).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETCMM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.WORD_MASK - this.readWord(this.regEA));\n};\n\n/**\n * opSETCMB(0o463000): Set to Complement of Memory Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-19:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the complement of the specified source\n * operand ([E]).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETCMB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.WORD_MASK - this.readWord(this.regEA)));\n};\n\n/**\n * opORCM(0o464000): Inclusive Or Complement of Memory with AC\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the complement of the\n * specified operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCM = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA)));\n};\n\n/**\n * opORCMI(0o465000): Inclusive Or Complement of Memory Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the complement of the\n * specified operand (E) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCMI = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), PDP10.WORD_MASK - this.regEA));\n};\n\n/**\n * opORCMM(0o466000): Inclusive Or Complement of Memory to Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([E]) to the inclusive OR function of the complement of the\n * specified operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCMM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.IOR(this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA)));\n};\n\n/**\n * opORCMB(0o467000): Inclusive Or Complement of Memory to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the inclusive OR function of the complement of the\n * specified operand ([E]) and [AC].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCMB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.IOR(this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA))));\n};\n\n/**\n * opORCB(0o470000): Inclusive Or Complements of Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the complements of both\n * the specified operand ([E]) and [AC]. The result is the NAND function of the operands.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCB = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA)));\n};\n\n/**\n * opORCBI(0o471000): Inclusive Or Complements of Both Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([AC]) to the inclusive OR function of the complements of both\n * the specified operand (E) and [AC]. The result is the NAND function of the operands.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCBI = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.regEA));\n};\n\n/**\n * opORCBM(0o472000): Inclusive Or Complements of Both To Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([E]) to the inclusive OR function of the complements of both\n * the specified operand ([E]) and [AC]. The result is the NAND function of the operands.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCBM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA)));\n};\n\n/**\n * opORCBB(0o473000): Inclusive Or Complements of Both to Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-22:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to the inclusive OR function of the complements of both\n * the specified operand ([E]) and [AC]. The result is the NAND function of the operands.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opORCBB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.IOR(PDP10.WORD_MASK - this.readWord(ac), PDP10.WORD_MASK - this.readWord(this.regEA))));\n};\n\n/**\n * opSETO(0o474000): Set to Ones\n * opSETOI(0o475000): Set to Ones Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-18:\n *\n * Change the contents of the destination specified by M (AC) to all 1s.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETO = function(op, ac)\n{\n this.writeWord(ac, PDP10.WORD_MASK);\n};\n\n/**\n * opSETOM(0o476000): Set to Ones Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-18:\n *\n * Change the contents of the destination specified by M ([E]) to all 1s.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETOM = function(op, ac)\n{\n this.writeWord(this.regEA, PDP10.WORD_MASK);\n};\n\n/**\n * opSETOB(0o477000): Set to Ones Both\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-18:\n *\n * Change the contents of the destination specified by M ([E] and [AC]) to all 1s.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opSETOB = function(op, ac)\n{\n this.writeWord(this.regEA, this.writeWord(ac, PDP10.WORD_MASK));\n};\n\n/**\n * opHLL(0o5N0000): Half Word Left to Left\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-3:\n *\n * Move the left half of the source word specified by M to the left half of the specified destination.\n * The source and the destination right half are unaffected; the original contents of the destination are lost.\n *\n * For HLL, the source is [E] and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHLL = function(op, ac)\n{\n var src = this.readWord(this.regEA);\n var dst = this.readWord(ac);\n this.writeWord(ac, PDP10.GETHR(op, dst, src) + (src - (src & PDP10.HALF_MASK)));\n};\n\n/**\n * opHLLI(0o5N1000): Half Word Left to Left, Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-3:\n *\n * Move the left half of the source word specified by M to the left half of the specified destination.\n * The source and the destination right half are unaffected; the original contents of the destination are lost.\n *\n * SIDEBAR: HLLI merely clears AC left.\n *\n * For HLLI, the source is 0,E and the destination is [A]. But since this is a left-half-only operation, src is\n * effectively 0.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHLLI = function(op, ac)\n{\n var dst = this.readWord(ac);\n this.writeWord(ac, PDP10.GETHR(op, dst, 0));\n};\n\n/**\n * opHLLM(0o5N2000): Half Word Left to Left, Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-3:\n *\n * Move the left half of the source word specified by M to the left half of the specified destination.\n * The source and the destination right half are unaffected; the original contents of the destination are lost.\n *\n * For HLLM, the source is [A] and the destination is [E].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHLLM = function(op, ac)\n{\n var src = this.readWord(ac);\n var dst = this.readWord(this.regEA);\n this.writeWord(this.regEA, PDP10.GETHR(op, dst, src) + (src - (src & PDP10.HALF_MASK)));\n};\n\n/**\n * opHLLS(0o5N3000): Half Word Left to Left, Self\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-3:\n *\n * Move the left half of the source word specified by M to the left half of the specified destination.\n * The source and the destination right half are unaffected; the original contents of the destination are lost.\n *\n * SIDEBAR: If A is zero, HLLS is a no-op, otherwise it is equivalent to HLL.\n *\n * For HLLS, the source AND destination is [E] (and also [A] if A is non-zero).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHLLS = function(op, ac)\n{\n var dst = this.readWord(this.regEA);\n dst = PDP10.SETHR(op, dst, dst);\n this.writeWord(this.regEA, dst);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opHRL(0o504000): Half Word Right to Left\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-4:\n *\n * Move the right half of the source word specified by M to the left half of the specified destination.\n * The source and the destination right half are unaffected; the original contents of the destination left\n * half are lost.\n *\n * For HRL, the source is [E] and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHRL = function(op, ac)\n{\n var src = (this.readWord(this.regEA) & PDP10.HALF_MASK) * PDP10.HALF_SHIFT;\n var dst = this.readWord(ac);\n this.writeWord(ac, PDP10.GETHR(op, dst, src) + src);\n};\n\n/**\n * opHRLI(0o505000): Half Word Right to Left, Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-4:\n *\n * Move the right half of the source word specified by M to the left half of the specified destination.\n * The source and the destination right half are unaffected; the original contents of the destination left\n * half are lost.\n *\n * For HRLI, the source is 0,E and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHRLI = function(op, ac)\n{\n var src = this.regEA * PDP10.HALF_SHIFT;\n var dst = this.readWord(ac);\n this.writeWord(ac, PDP10.GETHR(op, dst, src) + src);\n};\n\n/**\n * opHRLM(0o506000): Half Word Right to Left, Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-4:\n *\n * Move the right half of the source word specified by M to the left half of the specified destination.\n * The source and the destination right half are unaffected; the original contents of the destination left\n * half are lost.\n *\n * For HRLM, the source is [A] and the destination is [E].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHRLM = function(op, ac)\n{\n var src = (this.readWord(ac) & PDP10.HALF_MASK) * PDP10.HALF_SHIFT;\n var dst = this.readWord(this.regEA);\n this.writeWord(this.regEA, PDP10.GETHR(op, dst, src) + src);\n};\n\n/**\n * opHRLS(0o507000): Half Word Right to Left, Self\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-4:\n *\n * Move the right half of the source word specified by M to the left half of the specified destination.\n * The source and the destination right half are unaffected; the original contents of the destination left\n * half are lost.\n *\n * For HRLS, the source AND destination is [E] (and also [A] if A is non-zero).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHRLS = function(op, ac)\n{\n var dst = this.readWord(this.regEA);\n var src = (dst & PDP10.HALF_MASK) * PDP10.HALF_SHIFT;\n dst = PDP10.GETHR(op, dst, src) + src;\n this.writeWord(this.regEA, dst);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opHRR(0o540000): Half Word Right to Right\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-6:\n *\n * Move the right half of the source word specified by M to the right half of the specified destination.\n * The source and the destination left half are unaffected; the original contents of the destination right\n * half are lost.\n *\n * For HRR, the source is [E] and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHRR = function(op, ac)\n{\n var src = this.readWord(this.regEA) & PDP10.HALF_MASK;\n var dst = this.readWord(ac);\n this.writeWord(ac, PDP10.GETHL(op, dst, src) + src);\n};\n\n/**\n * opHRRI(0o541000): Half Word Right to Right, Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-6:\n *\n * Move the right half of the source word specified by M to the right half of the specified destination.\n * The source and the destination left half are unaffected; the original contents of the destination right\n * half are lost.\n *\n * For HRRI, the source is 0,E and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHRRI = function(op, ac)\n{\n var dst = this.readWord(ac);\n this.writeWord(ac, PDP10.GETHL(op, dst, this.regEA) + this.regEA);\n};\n\n/**\n * opHRRM(0o542000): Half Word Right to Right, Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-6:\n *\n * Move the right half of the source word specified by M to the right half of the specified destination.\n * The source and the destination left half are unaffected; the original contents of the destination right\n * half are lost.\n *\n * For HRRM, the source is [A] and the destination is [E].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHRRM = function(op, ac)\n{\n var src = this.readWord(ac) & PDP10.HALF_MASK;\n var dst = this.readWord(this.regEA);\n this.writeWord(this.regEA, PDP10.GETHL(op, dst, src) + src);\n};\n\n/**\n * opHRRS(0o543000): Half Word Right to Right, Self\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-6:\n *\n * Move the right half of the source word specified by M to the right half of the specified destination.\n * The source and the destination left half are unaffected; the original contents of the destination right\n * half are lost.\n *\n * SIDEBAR: If A is zero, HRRS is a no-op; otherwise it is equivalent to HRR.\n *\n * For HRRS, the source AND destination is [E] (and also [A] if A is non-zero).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHRRS = function(op, ac)\n{\n var dst = this.readWord(this.regEA);\n dst = PDP10.SETHL(op, dst, dst);\n this.writeWord(this.regEA, dst);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opHLR(0o544000): Half Word Left to Right\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-7:\n *\n * Move the left half of the source word specified by M to the right half of the specified destination.\n * The source and the destination left half are unaffected; the original contents of the destination right half are lost.\n *\n * For HLR, the source is [E] and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHLR = function(op, ac)\n{\n var src = (this.readWord(this.regEA) / PDP10.HALF_SHIFT)|0;\n var dst = this.readWord(ac);\n this.writeWord(ac, PDP10.GETHL(op, dst, src) + src);\n};\n\n/**\n * opHLRI(0o545000): Half Word Left to Right, Immediate\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-7:\n *\n * Move the left half of the source word specified by M to the right half of the specified destination.\n * The source and the destination left half are unaffected; the original contents of the destination right half are lost.\n *\n * SIDEBAR: HLRI merely clears AC right.\n *\n * For HLRI, the source is 0,E and the destination is [A].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHLRI = function(op, ac)\n{\n var dst = this.readWord(ac);\n this.writeWord(ac, PDP10.GETHL(op, dst, 0));\n};\n\n/**\n * opHLRM(0o546000): Half Word Left to Right, Memory\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-7:\n *\n * Move the left half of the source word specified by M to the right half of the specified destination.\n * The source and the destination left half are unaffected; the original contents of the destination right half are lost.\n *\n * For HLRM, the source is [A] and the destination is [E].\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHLRM = function(op, ac)\n{\n var src = (this.readWord(ac) / PDP10.HALF_SHIFT)|0;\n var dst = this.readWord(this.regEA);\n this.writeWord(this.regEA, PDP10.GETHL(op, dst, src) + src);\n};\n\n/**\n * opHLRS(0o547000): Half Word Left to Right, Self\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-7:\n *\n * Move the left half of the source word specified by M to the right half of the specified destination.\n * The source and the destination left half are unaffected; the original contents of the destination right half are lost.\n *\n * For HLRS, the source AND destination is [E] (and also [A] if A is non-zero).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opHLRS = function(op, ac)\n{\n var dst = this.readWord(this.regEA);\n var src = (dst / PDP10.HALF_SHIFT)|0;\n dst = PDP10.GETHL(op, dst, src) + src;\n this.writeWord(this.regEA, dst);\n if (ac) this.writeWord(ac, dst);\n};\n\n/**\n * opTRNE(0o602000): Test Right, No Modification, and Skip if All Masked Bits Equal 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRNE = function(op, ac)\n{\n if (PDP10.AND(this.readWord(ac), this.regEA) == 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opTLNE(0o603000): Test Left, No Modification, and Skip if All Masked Bits Equal 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLNE = function(op, ac)\n{\n if (PDP10.AND(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT) == 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opTRNA(0o604000): Test Right, No Modification, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRNA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n};\n\n/**\n * opTLNA(0o605000): Test Left, No Modification, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLNA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n};\n\n/**\n * opTRNN(0o606000): Test Right, No Modification, and Skip if Not All Masked Bits Equal 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRNN = function(op, ac)\n{\n if (PDP10.AND(this.readWord(ac), this.regEA) != 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opTLNN(0o607000): Test Left, No Modification, and Skip if Not All Masked Bits Equal 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLNN = function(op, ac)\n{\n if (PDP10.AND(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT) != 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opTDNE(0o612000): Test Direct, No Modification, and Skip if All Masked Bits Equal 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDNE = function(op, ac)\n{\n if (PDP10.AND(this.readWord(ac), this.readWord(this.regEA)) == 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opTSNE(0o613000): Test Swapped, No Modification, and Skip if All Masked Bits Equal 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSNE = function(op, ac)\n{\n if (PDP10.AND(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA))) == 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opTDNA(0o614000): Test Direct, No Modification, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDNA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n};\n\n/**\n * opTSNA(0o615000): Test Swapped, No Modification, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSNA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n};\n\n/**\n * opTDNN(0o616000): Test Direct, No Modification, and Skip if Not All Masked Bits Equal 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDNN = function(op, ac)\n{\n if (PDP10.AND(this.readWord(ac), this.readWord(this.regEA)) != 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opTSNN(0o617000): Test Swapped, No Modification, and Skip if Not All Masked Bits Equal 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSNN = function(op, ac)\n{\n if (PDP10.AND(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA))) != 0) this.setPC(this.regPC + 1);\n};\n\n/**\n * opTRZ(0o620000): Test Right, Zeros, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRZ = function(op, ac)\n{\n this.writeWord(ac, PDP10.CLR(this.readWord(ac), this.regEA));\n};\n\n/**\n * opTLZ(0o621000): Test Left, Zeros, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLZ = function(op, ac)\n{\n this.writeWord(ac, PDP10.CLR(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT));\n};\n\n/**\n * opTRZE(0o622000): Test Right, Zeros, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRZE = function(op, ac)\n{\n var dst = this.readWord(ac);\n if (PDP10.AND(dst, this.regEA) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(dst, this.regEA));\n};\n\n/**\n * opTLZE(0o623000): Test Left, Zeros, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLZE = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.regEA * PDP10.HALF_SHIFT;\n if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(dst, src));\n};\n\n/**\n * opTRZA(0o624000): Test Right, Zeros, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRZA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(this.readWord(ac), this.regEA));\n};\n\n/**\n * opTLZA(0o625000): Test Left, Zeros, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLZA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT));\n};\n\n/**\n * opTRZN(0o626000): Test Right, Zeros, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRZN = function(op, ac)\n{\n var dst = this.readWord(ac);\n if (PDP10.AND(dst, this.regEA) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(dst, this.regEA));\n};\n\n/**\n * opTLZN(0o627000): Test Left, Zeros, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLZN = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.regEA * PDP10.HALF_SHIFT;\n if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(dst, src));\n};\n\n/**\n * opTDZ(0o630000): Test Direct, Zeros, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDZ = function(op, ac)\n{\n this.writeWord(ac, PDP10.CLR(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opTSZ(0o631000): Test Swapped, Zeros, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSZ = function(op, ac)\n{\n this.writeWord(ac, PDP10.CLR(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA))));\n};\n\n/**\n * opTDZE(0o632000): Test Direct, Zeros, and Skip if All Masked Bits Equaled a\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDZE = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.readWord(this.regEA);\n if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(dst, src));\n};\n\n/**\n * opTSZE(0o633000): Test Swapped, Zeros, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSZE = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = PDP10.SWAP(this.readWord(this.regEA));\n if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(dst, src));\n};\n\n/**\n * opTDZA(0o634000): Test Direct, Zeros, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDZA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opTSZA(0o635000): Test Swapped, Zeros, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSZA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA))));\n};\n\n/**\n * opTDZN(0o636000): Test Direct, Zeros, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDZN = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.readWord(this.regEA);\n if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(dst, src));\n};\n\n/**\n * opTSZN(0o637000): Test Swapped, Zeros, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSZN = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = PDP10.SWAP(this.readWord(this.regEA));\n if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.CLR(dst, src));\n};\n\n/**\n * opTRC(0o640000): Test Right, Complement, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRC = function(op, ac)\n{\n this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.regEA));\n};\n\n/**\n * opTLC(0o641000): Test Left, Complement, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLC = function(op, ac)\n{\n this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT));\n};\n\n/**\n * opTRCE(0o642000): Test Right, Complement, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRCE = function(op, ac)\n{\n var dst = this.readWord(ac);\n if (PDP10.AND(dst, this.regEA) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(dst, this.regEA));\n};\n\n/**\n * opTLCE(0o643000): Test Left, Complement, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLCE = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.regEA * PDP10.HALF_SHIFT;\n if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(dst, src));\n};\n\n/**\n * opTRCA(0o644000): Test Right, Complement, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRCA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.regEA));\n};\n\n/**\n * opTLCA(0o645000): Test Left, Complement, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLCA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT));\n};\n\n/**\n * opTRCN(0o646000): Test Right, Complement, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRCN = function(op, ac)\n{\n var dst = this.readWord(ac);\n if (PDP10.AND(dst, this.regEA) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(dst, this.regEA));\n};\n\n/**\n * opTLCN(0o647000): Test Left, Complement, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLCN = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.regEA * PDP10.HALF_SHIFT;\n if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(dst, src));\n};\n\n/**\n * opTDC(0o650000): Test Direct, Complement, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDC = function(op, ac)\n{\n this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opTSC(0o651000): Test Swapped, Complement, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSC = function(op, ac)\n{\n this.writeWord(ac, PDP10.XOR(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA))));\n};\n\n/**\n * opTDCE(0o652000): Test Direct, Complement, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDCE = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.readWord(this.regEA);\n if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(dst, src));\n};\n\n/**\n * opTSCE(0o653000): Test Swapped, Complement, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSCE = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = PDP10.SWAP(this.readWord(this.regEA));\n if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(dst, src));\n};\n\n/**\n * opTDCA(0o654000): Test Direct, Complement, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDCA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opTSCA(0o655000): Test Swapped, Complement, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSCA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA))));\n};\n\n/**\n * opTDCN(0o656000): Test Direct, Complement, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDCN = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.readWord(this.regEA);\n if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(dst, src));\n};\n\n/**\n * opTSCN(0o657000): Test Swapped, Complement, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSCN = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = PDP10.SWAP(this.readWord(this.regEA));\n if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.XOR(dst, src));\n};\n\n/**\n * opTRO(0o660000): Test Right, Ones, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRO = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.regEA));\n};\n\n/**\n * opTLO(0o661000): Test Left, Ones, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLO = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT));\n};\n\n/**\n * opTROE(0o662000): Test Right, Ones, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTROE = function(op, ac)\n{\n var dst = this.readWord(ac);\n if (PDP10.AND(dst, this.regEA) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(dst, this.regEA));\n};\n\n/**\n * opTLOE(0o663000): Test Left, Ones, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLOE = function(op, ac)\n{\n var dst = this.readWord(ac);\n if (PDP10.AND(dst, this.regEA * PDP10.HALF_SHIFT) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(dst, this.regEA * PDP10.HALF_SHIFT));\n};\n\n/**\n * opTROA(0o664000): Test Right, Ones, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTROA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.regEA));\n};\n\n/**\n * opTLOA(0o665000): Test Left, Ones, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLOA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.regEA * PDP10.HALF_SHIFT));\n};\n\n/**\n * opTRON(0o666000): Test Right, Ones, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTRON = function(op, ac)\n{\n var dst = this.readWord(ac);\n if (PDP10.AND(dst, this.regEA) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(dst, this.regEA));\n};\n\n/**\n * opTLON(0o667000): Test Left, Ones, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTLON = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.regEA * PDP10.HALF_SHIFT;\n if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(dst, src));\n};\n\n/**\n * opTDO(0o670000): Test Direct, Ones, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDO = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opTSO(0o671000): Test Swapped, Ones, but Do Not Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSO = function(op, ac)\n{\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA))));\n};\n\n/**\n * opTDOE(0o672000): Test Direct, Ones, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDOE = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.readWord(this.regEA);\n if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(dst, src));\n};\n\n/**\n * opTSOE(0o673000): Test Swapped, Ones, and Skip if All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSOE = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = PDP10.SWAP(this.readWord(this.regEA));\n if (PDP10.AND(dst, src) == 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(dst, src));\n};\n\n/**\n * opTDOA(0o674000): Test Direct, Ones, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDOA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), this.readWord(this.regEA)));\n};\n\n/**\n * opTSOA(0o675000): Test Swapped, Ones, but Always Skip\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSOA = function(op, ac)\n{\n this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(this.readWord(ac), PDP10.SWAP(this.readWord(this.regEA))));\n};\n\n/**\n * opTDON(0o676000): Test Direct, Ones, and Skip if Not All Masked Bits Equaled 0\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTDON = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = this.readWord(this.regEA);\n if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(dst, src));\n};\n\n/**\n * opTSON(0o677000): Test Swapped, Ones, and Skip if Not All Masked Bits Equaled a\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opTSON = function(op, ac)\n{\n var dst = this.readWord(ac);\n var src = PDP10.SWAP(this.readWord(this.regEA));\n if (PDP10.AND(dst, src) != 0) this.setPC(this.regPC + 1);\n this.writeWord(ac, PDP10.IOR(dst, src));\n};\n\n/**\n * opBLKI(0o700000)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} dev\n */\nPDP10.opBLKI = function(op, dev)\n{\n this.opUndefined(op);\n};\n\n/**\n * opDATAI(0o700040)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} dev\n */\nPDP10.opDATAI = function(op, dev)\n{\n this.opUndefined(op);\n};\n\n/**\n * opBLKO(0o700100)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} dev\n */\nPDP10.opBLKO = function(op, dev)\n{\n this.opUndefined(op);\n};\n\n/**\n * opDATAO(0o700140)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} dev\n */\nPDP10.opDATAO = function(op, dev)\n{\n this.opUndefined(op);\n};\n\n/**\n * opCONO(0o700200)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} dev\n */\nPDP10.opCONO = function(op, dev)\n{\n switch(dev) {\n case PDP10.DEVICES.APR:\n this.writeFlags(this.readWord(this.regEA));\n break;\n default:\n this.opUndefined(op);\n break;\n }\n};\n\n/**\n * opCONI(0o700240)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} dev\n */\nPDP10.opCONI = function(op, dev)\n{\n switch(dev) {\n case PDP10.DEVICES.APR:\n this.writeWord(this.regEA, this.readFlags());\n break;\n default:\n this.opUndefined(op);\n break;\n }\n};\n\n/**\n * opCONSZ(0o700300)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} dev\n */\nPDP10.opCONSZ = function(op, dev)\n{\n this.opUndefined(op);\n};\n\n/**\n * opCONSO(0o700340)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} dev\n */\nPDP10.opCONSO = function(op, dev)\n{\n this.opUndefined(op);\n};\n\n/**\n * opIO(0o700xxx-0o777xxx): Input-Output Instructions\n *\n * From the DEC PDP-10 System Reference Manual (May 1968), p. 2-68:\n *\n * The input-output instructions govern all transfers of data to and from the peripheral equipment, and also\n * perform many operations within the processor. An instruction in the in-out class is designated by 111 in\n * bits 0-2, ie its left octal digit is 7. Bits 3-9 address the device that is to respond to the instruction.\n * The format thus allows for 128 codes, two of which, 000 and 004 respectively, address the processor and\n * priority interrupt, and are used for the console and time share hardware as well. A chart in Appendix A\n * lists all devices for which codes have been assigned, and gives their mnemonics and DEC option numbers.\n *\n * Bits 13-35 are the same as in all other instructions: they are the I, X, and Y parts, which are used to\n * calculate an effective address, set of conditions, or mask to be used in the execution of the instruction.\n * The remaining bits, 10-12, select one of the following eight 10 instructions.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n */\nPDP10.opIO = function(op)\n{\n PDP10.aOpIO_KA10[op & 7].call(this, op, (op >> 3) & 0o177);\n};\n\n/**\n * opNOP(op, ac)\n *\n * Used for all \"defined\" operations that, in fact, do nothing (eg, SETA, SETAI, CAI, JUMP).\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opNOP = function(op, ac)\n{\n};\n\n/**\n * opNOPM(op, ac)\n *\n * Used for all \"defined\" operations that, in fact, do nothing (eg, SETMM, CAM) EXCEPT reference memory.\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} ac\n */\nPDP10.opNOPM = function(op, ac)\n{\n};\n\n/**\n * opUndefined(op, ac)\n *\n * @this {CPUStatePDP10}\n * @param {number} op\n * @param {number} [ac]\n */\nPDP10.opUndefined = function(op, ac)\n{\n this.println(\"undefined opcode: \" + Str.toOct(op));\n this.advancePC(-1);\n this.stopCPU();\n};\n\n/**\n * doABS(src)\n *\n * Returns the absolute value (ABS) of the 36-bit operand; used by the MOVM* (Move Magnitude) instructions.\n *\n * @this {CPUStatePDP10}\n * @param {number} src (36-bit)\n * @return {number} (absolute value of src)\n */\nPDP10.doABS = function(src)\n{\n if (src > PDP10.INT_MASK) {\n if (src != PDP10.INT_LIMIT) {\n src = PDP10.TWO_POW36 - src;\n } else {\n this.regPS |= (PDP10.PSFLAG.AROV | PDP10.PSFLAG.CRY1);\n }\n }\n return src;\n};\n\n/**\n * doADD(dst, src)\n *\n * Performs the addition (ADD) of two signed 36-bit operands.\n *\n * @this {CPUStatePDP10}\n * @param {number} dst (36-bit value)\n * @param {number} src (36-bit value)\n * @return {number} (dst + src)\n */\nPDP10.doADD = function(dst, src)\n{\n /*\n * Since, in our happy little world, 36-bit values are always unsigned, the\n * only possible out-of-bounds value is a result >= WORD_LIMIT, which the mod cures.\n */\n var res = (dst + src) % PDP10.WORD_LIMIT;\n PDP10.setAddFlags.call(this, dst, src, res);\n return res;\n};\n\n/**\n * doDIV(src, dst, ext)\n *\n * Performs the division (DIV) of a 72-bit operand by a 36-bit operand.\n *\n * @this {CPUStatePDP10}\n * @param {number} src (36-bit divisor)\n * @param {number} dst (36-bit value)\n * @param {number} [ext] (36-bit value extension)\n * @return {number} (dst / src) (the remainder is stored in regEX); -1 if error (no division performed)\n */\nPDP10.doDIV = function(src, dst, ext)\n{\n var fNegQ = false, fNegR = false;\n\n /*\n * Perform all the same up-front checks that the PDP-10 performs; if we do our job correctly, then it\n * will be impossible for the actual division operation to overflow (the asserts below should never fire).\n */\n if (ext === undefined) {\n if (!src) {\n this.regPS |= PDP10.PSFLAG.DCK | PDP10.PSFLAG.AROV;\n return -1;\n }\n ext = (dst > PDP10.INT_MASK)? PDP10.WORD_MASK : 0;\n } else {\n var srcAbs = (src < PDP10.INT_LIMIT? src : PDP10.TWO_POW36 - src);\n var extAbs = (ext < PDP10.INT_LIMIT? ext : PDP10.TWO_POW36 - ext - (dst? 1 : 0));\n if (extAbs >= srcAbs) {\n this.regPS |= PDP10.PSFLAG.DCK | PDP10.PSFLAG.AROV;\n return -1;\n }\n }\n\n /*\n * We're done with the PDP-10's \"dual sign\" operands now; produce a (unified) signed 72-bit dividend.\n */\n dst = PDP10.merge72.call(this, dst, ext);\n ext = this.regEX;\n\n /*\n * Make all the inputs positive now, to keep the division simple. Fix up the results when we're done.\n */\n if (src > PDP10.INT_MASK) {\n src = PDP10.WORD_LIMIT - src;\n fNegQ = !fNegQ;\n }\n if (ext > PDP10.INT_MASK) {\n if (dst) {\n ext = PDP10.WORD_MASK - ext;\n dst = PDP10.WORD_LIMIT - dst;\n }\n else {\n if (ext) ext = PDP10.WORD_LIMIT - ext;\n }\n fNegR = true; fNegQ = !fNegQ;\n }\n\n /*\n * Initialize the four double-length 72-bit values we need for the division process.\n *\n * The process involves shifting the divisor left 1 bit (ie, doubling it) until it equals\n * or exceeds the dividend, and then repeatedly subtracting the divisor from the dividend and\n * shifting the divisor right 1 bit until the divisor is \"exhausted\" (no bits left), with an\n * \"early out\" if the dividend gets \"exhausted\" first.\n *\n * Note that each element of these double arrays is a 36-bit value, so it's rarely a good idea\n * to use bitwise operators on them, because those would operate on only the low 32 bits.\n * Stick with the double worker functions I've created, and trust your JavaScript engine to\n * inline/optimize the code.\n */\n PDP10.INITD(this.regRes, 0, 0);\n PDP10.INITD(this.regPow, 1, 0);\n PDP10.INITD(this.regDiv, src, 0);\n PDP10.INITD(this.regRem, dst, ext);\n\n while (PDP10.CMPD(this.regRem, this.regDiv) > 0) {\n PDP10.ADDD(this.regDiv, this.regDiv);\n PDP10.ADDD(this.regPow, this.regPow);\n }\n do {\n if (PDP10.CMPD(this.regRem, this.regDiv) >= 0) {\n PDP10.SUBD(this.regRem, this.regDiv);\n PDP10.ADDD(this.regRes, this.regPow);\n if (PDP10.ZEROD(this.regRem)) break;\n }\n PDP10.SHRD(this.regDiv);\n PDP10.SHRD(this.regPow);\n } while (!PDP10.ZEROD(this.regPow));\n\n\n\n\n dst = this.regRes[0];\n this.regEX = this.regRem[0];\n\n if (fNegQ && dst) {\n dst = PDP10.WORD_LIMIT - dst;\n }\n\n if (fNegR && this.regEX) {\n this.regEX = PDP10.WORD_LIMIT - this.regEX;\n }\n\n return dst;\n};\n\n/**\n * doMUL(dst, src, fTruncate, fExternal)\n *\n * Performs the multiplication (MUL) of two signed 36-bit operands.\n *\n * To support 72-bit results, we perform the multiplication process as you would \"by hand\",\n * treating the operands to be multiplied as two 2-digit numbers, where each \"digit\" is an 18-bit\n * number (base 2^18). Each individual multiplication of these 18-bit \"digits\" will produce\n * a result within 2^36, well within JavaScript integer accuracy.\n *\n * PDP-10 Diagnostic Notes\n * -----------------------\n *\n * The \"DAKAK\" diagnostic contains the following code:\n *\n * 036174: 200240 043643 MOVE 5,43643 ; [43643] = 400000000000\n * 036175: 200300 043603 MOVE 6,43603 ; [43603] = 777777777777\n * 036176: 200140 043604 MOVE 3,43604 ; [43604] = 000000000001\n * 036177: 224240 000003 MUL 5,3 ; Multiply 400000000000 by 000000000001\n * 036200: 312240 043604 CAME 5,43604 ; high order result in AC should be: 000000000001\n * 036201: 003240 033721 UUO 5,33721 ;\n * 036202: 312300 043602 CAME 6,43602 ; low order result in AC+1 should be: 000000000000\n *\n * The \"natural\" result is:\n *\n * 05=777777777777 06=400000000000\n *\n * And SIMH seems to agree. So why does the DEC diagnostic expect:\n *\n * 05=000000000001 06=000000000000\n *\n * The answer can be found in the June 1982 \"DECSYSTEM-10 and DECSYSTEM-20 Processor Reference Manual\",\n * in the description of the MUL instruction:\n *\n * CAUTION: In the KA10, an AC operand of 2^35 is treated as though it were +2^35, producing the\n * incorrect sign in the product.\n *\n * This behavior is now simulated below for MODEL_KA10, at least to the extent that the diagnostic is happy.\n *\n * @this {CPUStatePDP10}\n * @param {number} dst (36-bit value)\n * @param {number} src (36-bit value)\n * @param {boolean} [fTruncate] (true to truncate the result to 36 bits; used by IMUL instructions)\n * @param {boolean} [fExternal] (true if external caller; avoids modifying the CPU state)\n * @return {number} (dst * src) (the high 36 bits of the result; the low 36 bits are stored in regEX)\n */\nPDP10.doMUL = function(dst, src, fTruncate, fExternal)\n{\n var n1 = dst, n2 = src;\n var fNeg = false, res, ext;\n\n /*\n * If either input is in the negative range, record the sign and make it positive;\n * we'll negate the result afterward if necessary.\n */\n if (n1 > PDP10.INT_MASK) {\n if (fExternal || this.model != PDP10.MODEL_KA10 || n1 != PDP10.INT_LIMIT) {\n n1 = PDP10.WORD_LIMIT - n1;\n fNeg = !fNeg;\n }\n }\n\n if (n2 > PDP10.INT_MASK) {\n n2 = PDP10.WORD_LIMIT - n2;\n fNeg = !fNeg;\n }\n\n if (n1 < PDP10.HALF_SHIFT && n2 < PDP10.HALF_SHIFT) {\n res = n1 * n2;\n ext = 0;\n }\n else {\n var n1d1 = (n1 & PDP10.HALF_MASK);\n var n1d2 = Math.trunc(n1 / PDP10.HALF_SHIFT);\n var n2d1 = (n2 & PDP10.HALF_MASK);\n var n2d2 = Math.trunc(n2 / PDP10.HALF_SHIFT);\n var m1d1 = n1d1 * n2d1;\n var m1d2 = (n1d2 * n2d1) + Math.trunc(m1d1 / PDP10.HALF_SHIFT);\n ext = Math.trunc(m1d2 / PDP10.HALF_SHIFT);\n m1d2 = (m1d2 & PDP10.HALF_MASK) + (n1d1 * n2d2);\n res = ((m1d2 * PDP10.HALF_SHIFT) + (m1d1 & PDP10.HALF_MASK)) % PDP10.WORD_LIMIT;\n ext += Math.trunc(m1d2 / PDP10.HALF_SHIFT) + (n1d2 * n2d2);\n }\n\n if (fNeg) {\n if (res) {\n ext = PDP10.WORD_MASK - ext;\n res = PDP10.WORD_LIMIT - res;\n }\n else {\n if (ext) ext = PDP10.WORD_LIMIT - ext;\n }\n }\n\n ext = PDP10.split72.call(this, res, ext, fExternal);\n\n if (fTruncate) {\n /*\n * Special code for IMUL. I originally tried to avoid calling split72() in this case, but the PDP-10\n * still appears to be splitting the result of the multiplication into separately signed 36-bit values,\n * so the simplest solution is to call split72() in all cases.\n */\n res = this.regEX;\n if (!fExternal) {\n /*\n * Regarding IMUL overflows, the original spec says:\n *\n * Set Overflow if the product is >= 2^35 or < -2^35 (ie, if the high order word of the double\n * length product is not null); the high order word is lost.\n *\n * However, when the \"DAKAL\" diagnostic performs a sequence like this:\n *\n * 00=000000000000 01=000000000000 02=000000000000 03=400000036755\n * 04=400000000000 05=000000000003 06=400000000000 07=000000000004\n * 10=000000000000 11=000000000011 12=777777400000 13=777777777776\n * 14=000000200000 15=400000037134 16=000000000016 17=000000000000\n * PC=037145 RA=00400000 EA=400000 PS=000000 OV=0 C0=0 C1=0 ND=0 PD=0\n * 037145: 220600 000013 IMUL 14,13 ;cycles=1\n *\n * it sets 14=777777400000 and leaves overflow clear; since the 'high order word\" would be 777777777777,\n * not null, I think the spec over-simplifies. So our check is more exhaustive: it verifies that ext is\n * nothing more than an extension of the sign bit of res (ie, 0 if res is positive, -1 if res is negative).\n * Any other combination of values implies an overflow.\n */\n if ((ext || res > PDP10.INT_MASK) && (ext != PDP10.WORD_MASK || res <= PDP10.INT_MASK)) {\n this.regPS |= PDP10.PSFLAG.AROV;\n }\n }\n ext = res;\n }\n return ext;\n};\n\n/**\n * doNEG(src)\n *\n * Returns the negation (NEG) of the 36-bit operand; used by the MOVN* (Move Negative) instructions.\n *\n * @this {CPUStatePDP10}\n * @param {number} src (36-bit)\n * @return {number} (src negated, but as an unsigned 36-bit result)\n */\nPDP10.doNEG = function(src)\n{\n if (!src) {\n this.regPS |= (PDP10.PSFLAG.CRY0 | PDP10.PSFLAG.CRY1);\n }\n else {\n /*\n * In the non-zero case, it's always safe to subtract src from TWO_POW36, but since we have to check for\n * the INT_LIMIT case anyway, and since subtraction in that case doesn't alter src, we skip the subtraction.\n */\n if (src == PDP10.INT_LIMIT) {\n this.regPS |= (PDP10.PSFLAG.AROV | PDP10.PSFLAG.CRY1);\n } else {\n src = PDP10.TWO_POW36 - src;\n }\n }\n return src;\n};\n\n/**\n * doSUB(dst, src)\n *\n * Performs the subtraction (SUB) of two signed 36-bit operands.\n *\n * @this {CPUStatePDP10}\n * @param {number} dst (36-bit value)\n * @param {number} src (36-bit value)\n * @return {number} (dst - src)\n */\nPDP10.doSUB = function(dst, src)\n{\n /*\n * Since, in our happy little world, 36-bit values are always unsigned, the\n * only possible out-of-bounds value is a result < 0, which adding WORD_LIMIT cures.\n */\n var res = (dst - src);\n if (res < 0) res += PDP10.WORD_LIMIT;\n /*\n * We can leverage setAddFlags() by treating the subtraction as addition;\n * since res = dst - src, it is also true that dst = res + src.\n */\n PDP10.setAddFlags.call(this, res, src, dst);\n return res;\n};\n\n/**\n * merge72(dst, ext)\n *\n * Returns a unified 72-bit result from two independently-signed 36-bit values.\n *\n * @this {CPUStatePDP10}\n * @param {number} dst (36-bit value)\n * @param {number} ext (36-bit value)\n * @return {number} (returns the lower 36 bits; the upper 36 bits are stored in regEX)\n */\nPDP10.merge72 = function(dst, ext)\n{\n var sign = (ext - (ext % PDP10.INT_LIMIT));\n\n /*\n * For 72-bit inputs, the PDP-10 doesn't care whether or not the low word's sign\n * matches the high word's sign. The high word's sign bit is the controlling bit.\n *\n *\n *\n * Compute value without the sign bit and add the low bit of extended in its place.\n */\n dst = (dst % PDP10.INT_LIMIT) + ((ext & 1) * PDP10.INT_LIMIT);\n this.regEX = sign + Math.trunc(ext / 2);\n return dst;\n};\n\n/**\n * split72(res, ext, fExternal)\n *\n * Returns two 36-bit values with matching sign bits from a unified 72-bit result.\n *\n * @this {CPUStatePDP10}\n * @param {number} res (36-bit value)\n * @param {number} ext (36-bit value)\n * @param {boolean} [fExternal] (true if external caller; avoids modifying the CPU state)\n * @return {number} (returns the upper 36 bits; the lower 36 bits are stored in regEX)\n */\nPDP10.split72 = function(res, ext, fExternal)\n{\n /*\n * We just produced a signed 72-bit result, whereas the PDP-10 stores 72-bit arithmetic values as two\n * signed 36-bit results with matching signs. Since that's effectively only 70 bits of magnitude (with\n * two sign bits), we lose one bit of magnitude.\n *\n * The conversion requires shifting ext left one bit so that we can move the high bit of res into the\n * low bit of ext, and then set the sign bit of res to match the sign bit of ext.\n */\n var sign = ext - (ext % PDP10.INT_LIMIT);\n ext = ((ext * 2) % PDP10.WORD_LIMIT) + Math.trunc(res / PDP10.INT_LIMIT);\n res = sign + (res % PDP10.INT_LIMIT);\n\n var signNew = ext - (ext % PDP10.INT_LIMIT);\n if (signNew != sign) {\n /*\n * I used to restore ext's original sign (ext = sign + (ext - signNew)), but the PDP-10's defined\n * behavior for multiplication overflow (ie, whenever both operands are 0o400000000000) is to set both\n * res and ext to 0o400000000000.\n *\n * To quote the original spec for the MUL instruction:\n *\n * If both operands are -2^35 set Overflow; the double length result stored is -2^70.\n */\n res = ext;\n }\n\n if (fExternal) return res;\n\n if (res == PDP10.INT_LIMIT && ext == PDP10.INT_LIMIT) {\n this.regPS |= PDP10.PSFLAG.AROV;\n }\n this.regEX = res;\n return ext;\n};\n\n/**\n * setAddFlags(dst, src, res)\n *\n * @this {CPUStatePDP10}\n * @param {number} dst (36-bit value)\n * @param {number} src (36-bit value)\n * @param {number} res (36-bit value)\n */\nPDP10.setAddFlags = function(dst, src, res)\n{\n /*\n * Isolate the top two bits of dst, src, and res by \"shifting\" them into bits 0 and 1 of the\n * following variables. Note that shifting with division only works when the values are unsigned\n * (which they MUST be).\n */\n\n var dst01 = Math.trunc(dst / PDP10.TWO_POW34);\n var src01 = Math.trunc(src / PDP10.TWO_POW34);\n var res01 = Math.trunc(res / PDP10.TWO_POW34);\n\n /*\n * Transform bits 0 and 1 into carry flags, based on the following truth table:\n *\n * D S R C Carry?\n * - - - - ------\n * 0 0 0 0 no\n * 0 0 1 0 no (there must have been a carry out of the preceding bit, but it was \"absorbed\")\n * 0 1 0 1 yes (there must have been a carry out of the preceding bit, but it was NOT \"absorbed\")\n * 0 1 1 0 no\n * 1 0 0 1 yes (same as the preceding \"yes\" case)\n * 1 0 1 0 no\n * 1 1 0 1 yes (since the addition of two ones must always produce a carry)\n * 1 1 1 1 yes (since the addition of two ones must always produce a carry)\n */\n var bitsCarry = (dst01 ^ ((dst01 ^ src01) & (src01 ^ res01)));\n var fCarry0 = bitsCarry & 0b10;\n var fCarry1 = bitsCarry & 0b01;\n\n /*\n * Similarly, we transform bit 1 into an overflow flag, based on the following truth table;\n * note that X is (D ^ R) and Y is (S ^ R):\n *\n * D S R X Y O Overflow?\n * - - - - - - ---------\n * 0 0 0 0 0 0 no\n * 0 0 1 1 1 1 yes (adding two positive values yielded a negative value)\n * 0 1 0 0 1 0 no\n * 0 1 1 1 0 0 no\n * 1 0 0 1 0 0 no\n * 1 0 1 0 1 0 no\n * 1 1 0 1 1 1 yes (adding two negative values yielded a positive value)\n * 1 1 1 0 0 0 no\n */\n var fOverflow = ((dst01 ^ res01) & (src01 ^ res01)) & 0b10;\n this.regPS |= (fCarry0? PDP10.PSFLAG.CRY0 : 0) | (fCarry1? PDP10.PSFLAG.CRY1 : 0) | (fOverflow? PDP10.PSFLAG.AROV : 0);\n};\n\n/**\n * AND(dst, src)\n *\n * Performs the logical \"and\" (AND) of two 36-bit operands.\n *\n * @param {number} dst (36-bit value)\n * @param {number} src (36-bit value)\n * @return {number} (dst & src)\n */\nPDP10.AND = function(dst, src)\n{\n /*\n * Since dst and src are 36-bit values, we must AND the low 32 bits separately from the higher bits,\n * and then combine them with addition. Since all bits above 36 will be zero, and since 0 AND 0 is 0,\n * no special masking for the higher bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n *\n * Finally, all 36-bit data within a PDP-10 machine should ALWAYS be unsigned, which we now assert,\n * because the divisions below would not yield correct results with negative inputs.\n */\n\n return ((((dst / PDP10.TWO_POW32)|0) & ((src / PDP10.TWO_POW32)|0)) * PDP10.TWO_POW32) + ((dst & src) >>> 0);\n};\n\n/**\n * CLR(dst, src)\n *\n * Performs the logical \"and\" (AND) of a 36-bit operand and its complement.\n *\n * @param {number} dst (36-bit value)\n * @param {number} src (36-bit value)\n * @return {number} (dst & ~src)\n */\nPDP10.CLR = function(dst, src)\n{\n return PDP10.AND(dst, PDP10.NOT(src));\n};\n\n/**\n * CMP(dst, src)\n *\n * Performs the SIGNED comparison (CMP) of two 36-bit operands.\n *\n * @param {number} dst (36-bit value)\n * @param {number} src (36-bit value)\n * @return {number} (dst - src)\n */\nPDP10.CMP = function(dst, src)\n{\n return (dst < PDP10.INT_LIMIT? dst : dst - PDP10.WORD_LIMIT) - (src < PDP10.INT_LIMIT? src : src - PDP10.WORD_LIMIT);\n};\n\n/**\n * EQV(dst, src)\n *\n * Performs the logical \"equivalence\" (EQV) of two 36-bit operands (ie, NOT XOR)\n *\n * @param {number} dst (36-bit value)\n * @param {number} src (36-bit value)\n * @return {number} (~(dst ^ src))\n */\nPDP10.EQV = function(dst, src)\n{\n /*\n * Since dst and src are 36-bit values, we must EQV the low 32 bits separately from the higher bits,\n * and then combine them with addition. Since all bits above 36 will be zero, and since 0 EQV 0 is 1,\n * we must mask the higher 4 bits with 0o17.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n *\n * Finally, all 36-bit data within a PDP-10 machine should ALWAYS be unsigned, which we now assert,\n * because the divisions below would not yield correct results with negative inputs.\n */\n\n return ((~(((dst / PDP10.TWO_POW32)|0) ^ ((src / PDP10.TWO_POW32)|0)) & 0o17) * PDP10.TWO_POW32) + (~(dst ^ src) >>> 0);\n};\n\n/**\n * IOR(dst, src)\n *\n * Performs the logical \"inclusive-or\" (OR) of two 36-bit operands.\n *\n * @param {number} dst (36-bit value)\n * @param {number} src (36-bit value)\n * @return {number} (dst | src)\n */\nPDP10.IOR = function(dst, src)\n{\n /*\n * Since dst and src are 36-bit values, we must OR the low 32 bits separately from the higher bits,\n * and then combine them with addition. Since all bits above 36 will be zero, and since 0 OR 0 is 0,\n * no special masking for the higher bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n *\n * Finally, all 36-bit data within a PDP-10 machine should ALWAYS be unsigned, which we now assert,\n * because the divisions below would not yield correct results with negative inputs.\n */\n\n return ((((dst / PDP10.TWO_POW32)|0) | ((src / PDP10.TWO_POW32)|0)) * PDP10.TWO_POW32) + ((dst | src) >>> 0);\n};\n\n/**\n * NOT(src)\n *\n * Performs the one's complement (NOT) of a 36-bit operand.\n *\n * @param {number} src (36-bit value)\n * @return {number} (~src)\n */\nPDP10.NOT = function(src)\n{\n /*\n * Since src is a 36-bit value, we must NOT the low 32 bits separately from the higher bits,\n * and then combine them with addition. Since all bits above 36 will be zero, and since ~0 is 1,\n * we must mask the higher 4 bits with 0o17.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n *\n * Finally, all 36-bit data within a PDP-10 machine should ALWAYS be unsigned, which we now assert,\n * because the divisions below would not yield correct results with negative inputs.\n */\n\n return ((~((src / PDP10.TWO_POW32)|0) & 0o17) * PDP10.TWO_POW32) + (~src >>> 0);\n};\n\n/**\n * SIGN(dst)\n *\n * Returns the signed form of the 36-bit operand; more efficient than doCMP(dst, 0).\n *\n * @param {number} dst (36-bit value)\n * @return {number}\n */\nPDP10.SIGN = function(dst)\n{\n return (dst < PDP10.INT_LIMIT? dst : dst - PDP10.WORD_LIMIT);\n};\n\n/**\n * XOR(dst, src)\n *\n * Performs the logical \"exclusive-or\" (XOR) of two 36-bit operands.\n *\n * @param {number} dst (36-bit value)\n * @param {number} src (36-bit value)\n * @return {number} (dst ^ src)\n */\nPDP10.XOR = function(dst, src)\n{\n /*\n * Since dst and src are 36-bit values, we must XOR the low 32 bits separately from the higher bits,\n * and then combine them with addition. Since all bits above 36 will be zero, and since 0 XOR 0 is 0,\n * no special masking for the higher bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n *\n * Finally, all 36-bit data within a PDP-10 machine should ALWAYS be unsigned, which we now assert,\n * because the divisions below would not yield correct results with negative inputs.\n */\n\n return ((((dst / PDP10.TWO_POW32)|0) ^ ((src / PDP10.TWO_POW32)|0)) * PDP10.TWO_POW32) + ((dst ^ src) >>> 0);\n};\n\n/**\n * SWAP(src)\n *\n * Used by callers to \"swap\" the left and right half-words of a 36-bit operand.\n *\n * NOTE: Since HALF_MASK is an 18-bit value, it's safe to use \"&\" with HALF_MASK (equivalent to \"%\" with HALF_SHIFT).\n *\n * @param {number} src\n * @return {number} (updated src)\n */\nPDP10.SWAP = function(src)\n{\n return ((src / PDP10.HALF_SHIFT)|0) + ((src & PDP10.HALF_MASK) * PDP10.HALF_SHIFT);\n};\n\n/**\n * GETHL(op, dst, src)\n *\n * Used by callers to obtain HL (half-word left) with HR (half-word right) zeroed.\n *\n * @param {number} op\n * @param {number} dst (36-bit value whose 18-bit left half is either preserved or modified)\n * @param {number} src (18-bit value used to determine the sign extension, if any, for the left half of dst)\n * @return {number} (updated dst)\n */\nPDP10.GETHL = function(op, dst, src)\n{\n switch(op & 0o600) {\n case 0o000:\n dst -= (dst & PDP10.HALF_MASK);\n break;\n case 0o200:\n dst = 0;\n break;\n case 0o400:\n dst = (PDP10.HALF_MASK * PDP10.HALF_SHIFT);\n break;\n case 0o600:\n dst = (src > PDP10.HINT_MASK? (PDP10.HALF_MASK * PDP10.HALF_SHIFT) : 0);\n break;\n }\n return dst;\n};\n\n/**\n * SETHL(op, dst, src)\n *\n * Used by callers to obtain HL (half-word left) with HR (half-word right) preserved.\n *\n * @param {number} op\n * @param {number} dst (36-bit value whose 18-bit left half is either preserved or modified)\n * @param {number} src (18-bit value used to determine the sign extension, if any, for the left half of dst)\n * @return {number} (updated dst)\n */\nPDP10.SETHL = function(op, dst, src)\n{\n if (op &= 0o600) {\n dst &= PDP10.HALF_MASK;\n switch(op) {\n case 0o400:\n dst += (PDP10.HALF_MASK * PDP10.HALF_SHIFT);\n break;\n case 0o600:\n dst += (src > PDP10.HINT_MASK? (PDP10.HALF_MASK * PDP10.HALF_SHIFT) : 0);\n break;\n }\n }\n return dst;\n};\n\n/**\n * GETHR(op, dst, src)\n *\n * Used by callers to obtain HR (half-word right) with HL (half-word left) zeroed.\n *\n * @param {number} op\n * @param {number} dst (36-bit value whose 18-bit right half is either preserved or modified)\n * @param {number} src (36-bit value used to determine the sign extension, if any, for the right half of dst)\n * @return {number} (updated dst)\n */\nPDP10.GETHR = function(op, dst, src)\n{\n switch(op & 0o600) {\n case 0o000:\n dst = (dst & PDP10.HALF_MASK);\n break;\n case 0o200:\n dst = 0;\n break;\n case 0o400:\n dst = PDP10.HALF_MASK;\n break;\n case 0o600:\n dst = (src > PDP10.INT_MASK? PDP10.HALF_MASK : 0);\n break;\n }\n return dst;\n};\n\n/**\n * SETHR(op, dst, src)\n *\n * Used by callers to obtain HR (half-word right) with HL (half-word left) preserved.\n *\n * @param {number} op\n * @param {number} dst (36-bit value whose 18-bit right half is either preserved or modified)\n * @param {number} src (36-bit value used to determine the sign extension, if any, for the right half of dst)\n * @return {number} (updated dst)\n */\nPDP10.SETHR = function(op, dst, src)\n{\n if (op &= 0o600) {\n dst -= (dst & PDP10.HALF_MASK);\n switch(op) {\n case 0o400:\n dst += PDP10.HALF_MASK;\n break;\n case 0o600:\n dst += (src > PDP10.INT_MASK? PDP10.HALF_MASK : 0);\n break;\n }\n }\n return dst;\n};\n\n/**\n * ADDD(dDst, dSrc)\n *\n * Adds a double-length value (dSrc) to another (dDst).\n *\n * @param {Array.<number>} dDst\n * @param {Array.<number>} dSrc\n */\nPDP10.ADDD = function(dDst, dSrc)\n{\n dDst[0] += dSrc[0];\n dDst[1] += dSrc[1];\n if (dDst[0] >= PDP10.WORD_LIMIT) {\n dDst[0] %= PDP10.WORD_LIMIT;\n dDst[1]++;\n }\n};\n\n/**\n * CMPD(dDst, dSrc)\n *\n * Compares double-length values (dDst and dSrc) by computing dDst - dSrc.\n *\n * @param {Array.<number>} dDst\n * @param {Array.<number>} dSrc\n * @return {number} > 0 if dDst > dSrc, == 0 if dDst == dSrc, < 0 if dDst < dSrc\n */\nPDP10.CMPD = function(dDst, dSrc)\n{\n var result = dDst[1] - dSrc[1];\n if (!result) result = dDst[0] - dSrc[0];\n return result;\n};\n\n/**\n * INITD(dDst, lo, hi)\n *\n * Initializes a double-length value (dDst).\n *\n * @param {Array.<number>} dDst\n * @param {number} lo\n * @param {number} hi\n */\nPDP10.INITD = function(dDst, lo, hi)\n{\n dDst[0] = lo;\n dDst[1] = hi;\n};\n\n/**\n * SHRD(dDst)\n *\n * Shifts a double-length value (dDst) right one bit.\n *\n * @param {Array.<number>} dDst\n */\nPDP10.SHRD = function(dDst)\n{\n if (dDst[1] % 2) {\n dDst[0] += PDP10.WORD_LIMIT;\n }\n dDst[0] = Math.trunc(dDst[0] / 2);\n dDst[1] = Math.trunc(dDst[1] / 2);\n};\n\n/**\n * SUBD(dDst, dSrc)\n *\n * Subtracts a double-length value (dSrc) from another (dDst).\n *\n * @param {Array.<number>} dDst\n * @param {Array.<number>} dSrc\n */\nPDP10.SUBD = function(dDst, dSrc)\n{\n dDst[0] -= dSrc[0];\n dDst[1] -= dSrc[1];\n if (dDst[0] < 0) {\n dDst[0] += PDP10.WORD_LIMIT;\n dDst[1]--;\n }\n};\n\n/**\n * ZEROD(d)\n *\n * True if all bits in the double-length value (d) are zero, false otherwise.\n *\n * @param {Array.<number>} d\n * @return {boolean}\n */\nPDP10.ZEROD = function(d)\n{\n return !d[0] && !d[1];\n};\n\n/*\n * If we want the basic half-word operations to handle all the sub-operations; ie:\n *\n * None\n * Zero-extend\n * One-extend\n * Sign-extend\n *\n * then we need to alias all the sub-functions to the corresponding primary functions.\n */\nPDP10.opHLLZ = PDP10.opHLL;\nPDP10.opHLLZI = PDP10.opHLLI;\nPDP10.opHLLZM = PDP10.opHLLM;\nPDP10.opHLLZS = PDP10.opHLLS;\nPDP10.opHLLO = PDP10.opHLL;\nPDP10.opHLLOI = PDP10.opHLLI;\nPDP10.opHLLOM = PDP10.opHLLM;\nPDP10.opHLLOS = PDP10.opHLLS;\nPDP10.opHLLE = PDP10.opHLL;\nPDP10.opHLLEI = PDP10.opHLLI;\nPDP10.opHLLEM = PDP10.opHLLM;\nPDP10.opHLLES = PDP10.opHLLS;\nPDP10.opHRLZ = PDP10.opHRL;\nPDP10.opHRLZI = PDP10.opHRLI;\nPDP10.opHRLZM = PDP10.opHRLM;\nPDP10.opHRLZS = PDP10.opHRLS;\nPDP10.opHRLO = PDP10.opHRL;\nPDP10.opHRLOI = PDP10.opHRLI;\nPDP10.opHRLOM = PDP10.opHRLM;\nPDP10.opHRLOS = PDP10.opHRLS;\nPDP10.opHRLE = PDP10.opHRL;\nPDP10.opHRLEI = PDP10.opHRLI;\nPDP10.opHRLEM = PDP10.opHRLM;\nPDP10.opHRLES = PDP10.opHRLS;\nPDP10.opHRRZ = PDP10.opHRR;\nPDP10.opHRRZI = PDP10.opHRRI;\nPDP10.opHRRZM = PDP10.opHRRM;\nPDP10.opHRRZS = PDP10.opHRRS;\nPDP10.opHRRO = PDP10.opHRR;\nPDP10.opHRROI = PDP10.opHRRI;\nPDP10.opHRROM = PDP10.opHRRM;\nPDP10.opHRROS = PDP10.opHRRS;\nPDP10.opHRRE = PDP10.opHRR;\nPDP10.opHRREI = PDP10.opHRRI;\nPDP10.opHRREM = PDP10.opHRRM;\nPDP10.opHRRES = PDP10.opHRRS;\nPDP10.opHLRZ = PDP10.opHLR;\nPDP10.opHLRZI = PDP10.opHLRI;\nPDP10.opHLRZM = PDP10.opHLRM;\nPDP10.opHLRZS = PDP10.opHLRS;\nPDP10.opHLRO = PDP10.opHLR;\nPDP10.opHLROI = PDP10.opHLRI;\nPDP10.opHLROM = PDP10.opHLRM;\nPDP10.opHLROS = PDP10.opHLRS;\nPDP10.opHLRE = PDP10.opHLR;\nPDP10.opHLREI = PDP10.opHLRI;\nPDP10.opHLREM = PDP10.opHLRM;\nPDP10.opHLRES = PDP10.opHLRS;\n\nPDP10.opSETZI = PDP10.opSETZ;\nPDP10.opSETOI = PDP10.opSETO;\nPDP10.opSETCAI = PDP10.opSETCA;\nPDP10.opSETA = PDP10.opNOP;\nPDP10.opSETAI = PDP10.opNOP;\nPDP10.opSETAM = PDP10.opMOVEM;\nPDP10.opSETAB = PDP10.opMOVEM;\nPDP10.opSETM = PDP10.opMOVE;\nPDP10.opSETMI = PDP10.opMOVEI;\nPDP10.opSETMM = PDP10.opNOPM;\nPDP10.opSETMB = PDP10.opMOVE;\nPDP10.opCAI = PDP10.opNOP;\nPDP10.opCAM = PDP10.opNOPM;\nPDP10.opJUMP = PDP10.opNOP;\nPDP10.opTRN = PDP10.opNOP;\nPDP10.opTLN = PDP10.opNOP;\nPDP10.opTDN = PDP10.opNOPM;\nPDP10.opTSN = PDP10.opNOPM;\n\nPDP10.aOpXXX_KA10 = [\n PDP10.opUUO, // 0o000xxx\n PDP10.opUUO, // 0o001xxx\n PDP10.opUUO, // 0o002xxx\n PDP10.opUUO, // 0o003xxx\n PDP10.opUUO, // 0o004xxx\n PDP10.opUUO, // 0o005xxx\n PDP10.opUUO, // 0o006xxx\n PDP10.opUUO, // 0o007xxx\n PDP10.opUUO, // 0o010xxx\n PDP10.opUUO, // 0o011xxx\n PDP10.opUUO, // 0o012xxx\n PDP10.opUUO, // 0o013xxx\n PDP10.opUUO, // 0o014xxx\n PDP10.opUUO, // 0o015xxx\n PDP10.opUUO, // 0o016xxx\n PDP10.opUUO, // 0o017xxx\n PDP10.opUUO, // 0o020xxx\n PDP10.opUUO, // 0o021xxx\n PDP10.opUUO, // 0o022xxx\n PDP10.opUUO, // 0o023xxx\n PDP10.opUUO, // 0o024xxx\n PDP10.opUUO, // 0o025xxx\n PDP10.opUUO, // 0o026xxx\n PDP10.opUUO, // 0o027xxx\n PDP10.opUUO, // 0o030xxx\n PDP10.opUUO, // 0o031xxx\n PDP10.opUUO, // 0o032xxx\n PDP10.opUUO, // 0o033xxx\n PDP10.opUUO, // 0o034xxx\n PDP10.opUUO, // 0o035xxx\n PDP10.opUUO, // 0o036xxx\n PDP10.opUUO, // 0o037xxx\n PDP10.opUUO, // 0o040xxx\n PDP10.opUUO, // 0o041xxx\n PDP10.opUUO, // 0o042xxx\n PDP10.opUUO, // 0o043xxx\n PDP10.opUUO, // 0o044xxx\n PDP10.opUUO, // 0o045xxx\n PDP10.opUUO, // 0o046xxx\n PDP10.opUUO, // 0o047xxx\n PDP10.opUUO, // 0o050xxx\n PDP10.opUUO, // 0o051xxx\n PDP10.opUUO, // 0o052xxx\n PDP10.opUUO, // 0o053xxx\n PDP10.opUUO, // 0o054xxx\n PDP10.opUUO, // 0o055xxx\n PDP10.opUUO, // 0o056xxx\n PDP10.opUUO, // 0o057xxx\n PDP10.opUUO, // 0o060xxx\n PDP10.opUUO, // 0o061xxx\n PDP10.opUUO, // 0o062xxx\n PDP10.opUUO, // 0o063xxx\n PDP10.opUUO, // 0o064xxx\n PDP10.opUUO, // 0o065xxx\n PDP10.opUUO, // 0o066xxx\n PDP10.opUUO, // 0o067xxx\n PDP10.opUUO, // 0o070xxx\n PDP10.opUUO, // 0o071xxx\n PDP10.opUUO, // 0o072xxx\n PDP10.opUUO, // 0o073xxx\n PDP10.opUUO, // 0o074xxx\n PDP10.opUUO, // 0o075xxx\n PDP10.opUUO, // 0o076xxx\n PDP10.opUUO, // 0o077xxx\n PDP10.opUndefined, // 0o100xxx\n PDP10.opUndefined, // 0o101xxx\n PDP10.opUndefined, // 0o102xxx\n PDP10.opUndefined, // 0o103xxx\n PDP10.opUndefined, // 0o104xxx\n PDP10.opUndefined, // 0o105xxx\n PDP10.opUndefined, // 0o106xxx\n PDP10.opUndefined, // 0o107xxx\n PDP10.opUndefined, // 0o110xxx\n PDP10.opUndefined, // 0o111xxx\n PDP10.opUndefined, // 0o112xxx\n PDP10.opUndefined, // 0o113xxx\n PDP10.opUndefined, // 0o114xxx\n PDP10.opUndefined, // 0o115xxx\n PDP10.opUndefined, // 0o116xxx\n PDP10.opUndefined, // 0o117xxx\n PDP10.opUndefined, // 0o120xxx\n PDP10.opUndefined, // 0o121xxx\n PDP10.opUndefined, // 0o122xxx\n PDP10.opUndefined, // 0o123xxx\n PDP10.opUndefined, // 0o124xxx\n PDP10.opUndefined, // 0o125xxx\n PDP10.opUndefined, // 0o126xxx\n PDP10.opUndefined, // 0o127xxx\n PDP10.opUFA, // 0o130xxx\n PDP10.opDFN, // 0o131xxx\n PDP10.opFSC, // 0o132xxx\n PDP10.opIBP, // 0o133xxx\n PDP10.opILDB, // 0o134xxx\n PDP10.opLDB, // 0o135xxx\n PDP10.opIDPB, // 0o136xxx\n PDP10.opDPB, // 0o137xxx\n PDP10.opFAD, // 0o140xxx\n PDP10.opFADI, // 0o141xxx\n PDP10.opFADM, // 0o142xxx\n PDP10.opFADB, // 0o143xxx\n PDP10.opFADR, // 0o144xxx\n PDP10.opFADRI, // 0o145xxx\n PDP10.opFADRM, // 0o146xxx\n PDP10.opFADRB, // 0o147xxx\n PDP10.opFSB, // 0o150xxx\n PDP10.opFSBI, // 0o151xxx\n PDP10.opFSBM, // 0o152xxx\n PDP10.opFSBB, // 0o153xxx\n PDP10.opFSBR, // 0o154xxx\n PDP10.opFSBRI, // 0o155xxx\n PDP10.opFSBRM, // 0o156xxx\n PDP10.opFSBRB, // 0o157xxx\n PDP10.opFMP, // 0o160xxx\n PDP10.opFMPI, // 0o161xxx\n PDP10.opFMPM, // 0o162xxx\n PDP10.opFMPB, // 0o163xxx\n PDP10.opFMPR, // 0o164xxx\n PDP10.opFMPRI, // 0o165xxx\n PDP10.opFMPRM, // 0o166xxx\n PDP10.opFMPRB, // 0o167xxx\n PDP10.opFDV, // 0o170xxx\n PDP10.opFDVI, // 0o171xxx\n PDP10.opFDVM, // 0o172xxx\n PDP10.opFDVB, // 0o173xxx\n PDP10.opFDVR, // 0o174xxx\n PDP10.opFDVRI, // 0o175xxx\n PDP10.opFDVRM, // 0o176xxx\n PDP10.opFDVRB, // 0o177xxx\n PDP10.opMOVE, // 0o200xxx\n PDP10.opMOVEI, // 0o201xxx\n PDP10.opMOVEM, // 0o202xxx\n PDP10.opMOVES, // 0o203xxx\n PDP10.opMOVS, // 0o204xxx\n PDP10.opMOVSI, // 0o205xxx\n PDP10.opMOVSM, // 0o206xxx\n PDP10.opMOVSS, // 0o207xxx\n PDP10.opMOVN, // 0o210xxx\n PDP10.opMOVNI, // 0o211xxx\n PDP10.opMOVNM, // 0o212xxx\n PDP10.opMOVNS, // 0o213xxx\n PDP10.opMOVM, // 0o214xxx\n PDP10.opMOVMI, // 0o215xxx\n PDP10.opMOVMM, // 0o216xxx\n PDP10.opMOVMS, // 0o217xxx\n PDP10.opIMUL, // 0o220xxx\n PDP10.opIMULI, // 0o221xxx\n PDP10.opIMULM, // 0o222xxx\n PDP10.opIMULB, // 0o223xxx\n PDP10.opMUL, // 0o224xxx\n PDP10.opMULI, // 0o225xxx\n PDP10.opMULM, // 0o226xxx\n PDP10.opMULB, // 0o227xxx\n PDP10.opIDIV, // 0o230xxx\n PDP10.opIDIVI, // 0o231xxx\n PDP10.opIDIVM, // 0o232xxx\n PDP10.opIDIVB, // 0o233xxx\n PDP10.opDIV, // 0o234xxx\n PDP10.opDIVI, // 0o235xxx\n PDP10.opDIVM, // 0o236xxx\n PDP10.opDIVB, // 0o237xxx\n PDP10.opASH, // 0o240xxx\n PDP10.opROT, // 0o241xxx\n PDP10.opLSH, // 0o242xxx\n PDP10.opJFFO, // 0o243xxx\n PDP10.opASHC, // 0o244xxx\n PDP10.opROTC, // 0o245xxx\n PDP10.opLSHC, // 0o246xxx\n PDP10.opUndefined, // 0o247xxx\n PDP10.opEXCH, // 0o250xxx\n PDP10.opBLT, // 0o251xxx\n PDP10.opAOBJP, // 0o252xxx\n PDP10.opAOBJN, // 0o253xxx\n PDP10.opJRST, // 0o254xxx\n PDP10.opJFCL, // 0o255xxx\n PDP10.opXCT, // 0o256xxx\n PDP10.opUndefined, // 0o257xxx\n PDP10.opPUSHJ, // 0o260xxx\n PDP10.opPUSH, // 0o261xxx\n PDP10.opPOP, // 0o262xxx\n PDP10.opPOPJ, // 0o263xxx\n PDP10.opJSR, // 0o264xxx\n PDP10.opJSP, // 0o265xxx\n PDP10.opJSA, // 0o266xxx\n PDP10.opJRA, // 0o267xxx\n PDP10.opADD, // 0o270xxx\n PDP10.opADDI, // 0o271xxx\n PDP10.opADDM, // 0o272xxx\n PDP10.opADDB, // 0o273xxx\n PDP10.opSUB, // 0o274xxx\n PDP10.opSUBI, // 0o275xxx\n PDP10.opSUBM, // 0o276xxx\n PDP10.opSUBB, // 0o277xxx\n PDP10.opCAI, // 0o300xxx\n PDP10.opCAIL, // 0o301xxx\n PDP10.opCAIE, // 0o302xxx\n PDP10.opCAILE, // 0o303xxx\n PDP10.opCAIA, // 0o304xxx\n PDP10.opCAIGE, // 0o305xxx\n PDP10.opCAIN, // 0o306xxx\n PDP10.opCAIG, // 0o307xxx\n PDP10.opCAM, // 0o310xxx\n PDP10.opCAML, // 0o311xxx\n PDP10.opCAME, // 0o312xxx\n PDP10.opCAMLE, // 0o313xxx\n PDP10.opCAMA, // 0o314xxx\n PDP10.opCAMGE, // 0o315xxx\n PDP10.opCAMN, // 0o316xxx\n PDP10.opCAMG, // 0o317xxx\n PDP10.opJUMP, // 0o320xxx\n PDP10.opJUMPL, // 0o321xxx\n PDP10.opJUMPE, // 0o322xxx\n PDP10.opJUMPLE, // 0o323xxx\n PDP10.opJUMPA, // 0o324xxx\n PDP10.opJUMPGE, // 0o325xxx\n PDP10.opJUMPN, // 0o326xxx\n PDP10.opJUMPG, // 0o327xxx\n PDP10.opSKIP, // 0o330xxx\n PDP10.opSKIPL, // 0o331xxx\n PDP10.opSKIPE, // 0o332xxx\n PDP10.opSKIPLE, // 0o333xxx\n PDP10.opSKIPA, // 0o334xxx\n PDP10.opSKIPGE, // 0o335xxx\n PDP10.opSKIPN, // 0o336xxx\n PDP10.opSKIPG, // 0o337xxx\n PDP10.opAOJ, // 0o340xxx\n PDP10.opAOJL, // 0o341xxx\n PDP10.opAOJE, // 0o342xxx\n PDP10.opAOJLE, // 0o343xxx\n PDP10.opAOJA, // 0o344xxx\n PDP10.opAOJGE, // 0o345xxx\n PDP10.opAOJN, // 0o346xxx\n PDP10.opAOJG, // 0o347xxx\n PDP10.opAOS, // 0o350xxx\n PDP10.opAOSL, // 0o351xxx\n PDP10.opAOSE, // 0o352xxx\n PDP10.opAOSLE, // 0o353xxx\n PDP10.opAOSA, // 0o354xxx\n PDP10.opAOSGE, // 0o355xxx\n PDP10.opAOSN, // 0o356xxx\n PDP10.opAOSG, // 0o357xxx\n PDP10.opSOJ, // 0o360xxx\n PDP10.opSOJL, // 0o361xxx\n PDP10.opSOJE, // 0o362xxx\n PDP10.opSOJLE, // 0o363xxx\n PDP10.opSOJA, // 0o364xxx\n PDP10.opSOJGE, // 0o365xxx\n PDP10.opSOJN, // 0o366xxx\n PDP10.opSOJG, // 0o367xxx\n PDP10.opSOS, // 0o370xxx\n PDP10.opSOSL, // 0o371xxx\n PDP10.opSOSE, // 0o372xxx\n PDP10.opSOSLE, // 0o373xxx\n PDP10.opSOSA, // 0o374xxx\n PDP10.opSOSGE, // 0o375xxx\n PDP10.opSOSN, // 0o376xxx\n PDP10.opSOSG, // 0o377xxx\n PDP10.opSETZ, // 0o400xxx\n PDP10.opSETZI, // 0o401xxx\n PDP10.opSETZM, // 0o402xxx\n PDP10.opSETZB, // 0o403xxx\n PDP10.opAND, // 0o404xxx\n PDP10.opANDI, // 0o405xxx\n PDP10.opANDM, // 0o406xxx\n PDP10.opANDB, // 0o407xxx\n PDP10.opANDCA, // 0o410xxx\n PDP10.opANDCAI, // 0o411xxx\n PDP10.opANDCAM, // 0o412xxx\n PDP10.opANDCAB, // 0o413xxx\n PDP10.opSETM, // 0o414xxx\n PDP10.opSETMI, // 0o415xxx\n PDP10.opSETMM, // 0o416xxx\n PDP10.opSETMB, // 0o417xxx\n PDP10.opANDCM, // 0o420xxx\n PDP10.opANDCMI, // 0o421xxx\n PDP10.opANDCMM, // 0o422xxx\n PDP10.opANDCMB, // 0o423xxx\n PDP10.opSETA, // 0o424xxx\n PDP10.opSETAI, // 0o425xxx\n PDP10.opSETAM, // 0o426xxx\n PDP10.opSETAB, // 0o427xxx\n PDP10.opXOR, // 0o430xxx\n PDP10.opXORI, // 0o431xxx\n PDP10.opXORM, // 0o432xxx\n PDP10.opXORB, // 0o433xxx\n PDP10.opIOR, // 0o434xxx\n PDP10.opIORI, // 0o435xxx\n PDP10.opIORM, // 0o436xxx\n PDP10.opIORB, // 0o437xxx\n PDP10.opANDCB, // 0o440xxx\n PDP10.opANDCBI, // 0o441xxx\n PDP10.opANDCBM, // 0o442xxx\n PDP10.opANDCBB, // 0o443xxx\n PDP10.opEQV, // 0o444xxx\n PDP10.opEQVI, // 0o445xxx\n PDP10.opEQVM, // 0o446xxx\n PDP10.opEQVB, // 0o447xxx\n PDP10.opSETCA, // 0o450xxx\n PDP10.opSETCAI, // 0o451xxx\n PDP10.opSETCAM, // 0o452xxx\n PDP10.opSETCAB, // 0o453xxx\n PDP10.opORCA, // 0o454xxx\n PDP10.opORCAI, // 0o455xxx\n PDP10.opORCAM, // 0o456xxx\n PDP10.opORCAB, // 0o457xxx\n PDP10.opSETCM, // 0o460xxx\n PDP10.opSETCMI, // 0o461xxx\n PDP10.opSETCMM, // 0o462xxx\n PDP10.opSETCMB, // 0o463xxx\n PDP10.opORCM, // 0o464xxx\n PDP10.opORCMI, // 0o465xxx\n PDP10.opORCMM, // 0o466xxx\n PDP10.opORCMB, // 0o467xxx\n PDP10.opORCB, // 0o470xxx\n PDP10.opORCBI, // 0o471xxx\n PDP10.opORCBM, // 0o472xxx\n PDP10.opORCBB, // 0o473xxx\n PDP10.opSETO, // 0o474xxx\n PDP10.opSETOI, // 0o475xxx\n PDP10.opSETOM, // 0o476xxx\n PDP10.opSETOB, // 0o477xxx\n PDP10.opHLL, // 0o500xxx\n PDP10.opHLLI, // 0o501xxx\n PDP10.opHLLM, // 0o502xxx\n PDP10.opHLLS, // 0o503xxx\n PDP10.opHRL, // 0o504xxx\n PDP10.opHRLI, // 0o505xxx\n PDP10.opHRLM, // 0o506xxx\n PDP10.opHRLS, // 0o507xxx\n PDP10.opHLLZ, // 0o510xxx\n PDP10.opHLLZI, // 0o511xxx\n PDP10.opHLLZM, // 0o512xxx\n PDP10.opHLLZS, // 0o513xxx\n PDP10.opHRLZ, // 0o514xxx\n PDP10.opHRLZI, // 0o515xxx\n PDP10.opHRLZM, // 0o516xxx\n PDP10.opHRLZS, // 0o517xxx\n PDP10.opHLLO, // 0o520xxx\n PDP10.opHLLOI, // 0o521xxx\n PDP10.opHLLOM, // 0o522xxx\n PDP10.opHLLOS, // 0o523xxx\n PDP10.opHRLO, // 0o524xxx\n PDP10.opHRLOI, // 0o525xxx\n PDP10.opHRLOM, // 0o526xxx\n PDP10.opHRLOS, // 0o527xxx\n PDP10.opHLLE, // 0o530xxx\n PDP10.opHLLEI, // 0o531xxx\n PDP10.opHLLEM, // 0o532xxx\n PDP10.opHLLES, // 0o533xxx\n PDP10.opHRLE, // 0o534xxx\n PDP10.opHRLEI, // 0o535xxx\n PDP10.opHRLEM, // 0o536xxx\n PDP10.opHRLES, // 0o537xxx\n PDP10.opHRR, // 0o540xxx\n PDP10.opHRRI, // 0o541xxx\n PDP10.opHRRM, // 0o542xxx\n PDP10.opHRRS, // 0o543xxx\n PDP10.opHLR, // 0o544xxx\n PDP10.opHLRI, // 0o545xxx\n PDP10.opHLRM, // 0o546xxx\n PDP10.opHLRS, // 0o547xxx\n PDP10.opHRRZ, // 0o550xxx\n PDP10.opHRRZI, // 0o551xxx\n PDP10.opHRRZM, // 0o552xxx\n PDP10.opHRRZS, // 0o553xxx\n PDP10.opHLRZ, // 0o554xxx\n PDP10.opHLRZI, // 0o555xxx\n PDP10.opHLRZM, // 0o556xxx\n PDP10.opHLRZS, // 0o557xxx\n PDP10.opHRRO, // 0o560xxx\n PDP10.opHRROI, // 0o561xxx\n PDP10.opHRROM, // 0o562xxx\n PDP10.opHRROS, // 0o563xxx\n PDP10.opHLRO, // 0o564xxx\n PDP10.opHLROI, // 0o565xxx\n PDP10.opHLROM, // 0o566xxx\n PDP10.opHLROS, // 0o567xxx\n PDP10.opHRRE, // 0o570xxx\n PDP10.opHRREI, // 0o571xxx\n PDP10.opHRREM, // 0o572xxx\n PDP10.opHRRES, // 0o573xxx\n PDP10.opHLRE, // 0o574xxx\n PDP10.opHLREI, // 0o575xxx\n PDP10.opHLREM, // 0o576xxx\n PDP10.opHLRES, // 0o577xxx\n PDP10.opTRN, // 0o600xxx\n PDP10.opTLN, // 0o601xxx\n PDP10.opTRNE, // 0o602xxx\n PDP10.opTLNE, // 0o603xxx\n PDP10.opTRNA, // 0o604xxx\n PDP10.opTLNA, // 0o605xxx\n PDP10.opTRNN, // 0o606xxx\n PDP10.opTLNN, // 0o607xxx\n PDP10.opTDN, // 0o610xxx\n PDP10.opTSN, // 0o611xxx\n PDP10.opTDNE, // 0o612xxx\n PDP10.opTSNE, // 0o613xxx\n PDP10.opTDNA, // 0o614xxx\n PDP10.opTSNA, // 0o615xxx\n PDP10.opTDNN, // 0o616xxx\n PDP10.opTSNN, // 0o617xxx\n PDP10.opTRZ, // 0o620xxx\n PDP10.opTLZ, // 0o621xxx\n PDP10.opTRZE, // 0o622xxx\n PDP10.opTLZE, // 0o623xxx\n PDP10.opTRZA, // 0o624xxx\n PDP10.opTLZA, // 0o625xxx\n PDP10.opTRZN, // 0o626xxx\n PDP10.opTLZN, // 0o627xxx\n PDP10.opTDZ, // 0o630xxx\n PDP10.opTSZ, // 0o631xxx\n PDP10.opTDZE, // 0o632xxx\n PDP10.opTSZE, // 0o633xxx\n PDP10.opTDZA, // 0o634xxx\n PDP10.opTSZA, // 0o635xxx\n PDP10.opTDZN, // 0o636xxx\n PDP10.opTSZN, // 0o637xxx\n PDP10.opTRC, // 0o640xxx\n PDP10.opTLC, // 0o641xxx\n PDP10.opTRCE, // 0o642xxx\n PDP10.opTLCE, // 0o643xxx\n PDP10.opTRCA, // 0o644xxx\n PDP10.opTLCA, // 0o645xxx\n PDP10.opTRCN, // 0o646xxx\n PDP10.opTLCN, // 0o647xxx\n PDP10.opTDC, // 0o650xxx\n PDP10.opTSC, // 0o651xxx\n PDP10.opTDCE, // 0o652xxx\n PDP10.opTSCE, // 0o653xxx\n PDP10.opTDCA, // 0o654xxx\n PDP10.opTSCA, // 0o655xxx\n PDP10.opTDCN, // 0o656xxx\n PDP10.opTSCN, // 0o657xxx\n PDP10.opTRO, // 0o660xxx\n PDP10.opTLO, // 0o661xxx\n PDP10.opTROE, // 0o662xxx\n PDP10.opTLOE, // 0o663xxx\n PDP10.opTROA, // 0o664xxx\n PDP10.opTLOA, // 0o665xxx\n PDP10.opTRON, // 0o666xxx\n PDP10.opTLON, // 0o667xxx\n PDP10.opTDO, // 0o670xxx\n PDP10.opTSO, // 0o671xxx\n PDP10.opTDOE, // 0o672xxx\n PDP10.opTSOE, // 0o673xxx\n PDP10.opTDOA, // 0o674xxx\n PDP10.opTSOA, // 0o675xxx\n PDP10.opTDON, // 0o676xxx\n PDP10.opTSON, // 0o677xxx\n PDP10.opIO, // 0o700xxx\n PDP10.opIO, // 0o701xxx\n PDP10.opIO, // 0o702xxx\n PDP10.opIO, // 0o703xxx\n PDP10.opIO, // 0o704xxx\n PDP10.opIO, // 0o705xxx\n PDP10.opIO, // 0o706xxx\n PDP10.opIO, // 0o707xxx\n PDP10.opIO, // 0o710xxx\n PDP10.opIO, // 0o711xxx\n PDP10.opIO, // 0o712xxx\n PDP10.opIO, // 0o713xxx\n PDP10.opIO, // 0o714xxx\n PDP10.opIO, // 0o715xxx\n PDP10.opIO, // 0o716xxx\n PDP10.opIO, // 0o717xxx\n PDP10.opIO, // 0o720xxx\n PDP10.opIO, // 0o721xxx\n PDP10.opIO, // 0o722xxx\n PDP10.opIO, // 0o723xxx\n PDP10.opIO, // 0o724xxx\n PDP10.opIO, // 0o725xxx\n PDP10.opIO, // 0o726xxx\n PDP10.opIO, // 0o727xxx\n PDP10.opIO, // 0o730xxx\n PDP10.opIO, // 0o731xxx\n PDP10.opIO, // 0o732xxx\n PDP10.opIO, // 0o733xxx\n PDP10.opIO, // 0o734xxx\n PDP10.opIO, // 0o735xxx\n PDP10.opIO, // 0o736xxx\n PDP10.opIO, // 0o737xxx\n PDP10.opIO, // 0o740xxx\n PDP10.opIO, // 0o741xxx\n PDP10.opIO, // 0o742xxx\n PDP10.opIO, // 0o743xxx\n PDP10.opIO, // 0o744xxx\n PDP10.opIO, // 0o745xxx\n PDP10.opIO, // 0o746xxx\n PDP10.opIO, // 0o747xxx\n PDP10.opIO, // 0o750xxx\n PDP10.opIO, // 0o751xxx\n PDP10.opIO, // 0o752xxx\n PDP10.opIO, // 0o753xxx\n PDP10.opIO, // 0o754xxx\n PDP10.opIO, // 0o755xxx\n PDP10.opIO, // 0o756xxx\n PDP10.opIO, // 0o757xxx\n PDP10.opIO, // 0o760xxx\n PDP10.opIO, // 0o761xxx\n PDP10.opIO, // 0o762xxx\n PDP10.opIO, // 0o763xxx\n PDP10.opIO, // 0o764xxx\n PDP10.opIO, // 0o765xxx\n PDP10.opIO, // 0o766xxx\n PDP10.opIO, // 0o767xxx\n PDP10.opIO, // 0o770xxx\n PDP10.opIO, // 0o771xxx\n PDP10.opIO, // 0o772xxx\n PDP10.opIO, // 0o773xxx\n PDP10.opIO, // 0o774xxx\n PDP10.opIO, // 0o775xxx\n PDP10.opIO, // 0o776xxx\n PDP10.opIO // 0o777xxx\n];\n\nPDP10.aOpIO_KA10 = [\n PDP10.opBLKI, // 0o70000x\n PDP10.opDATAI, // 0o70004x\n PDP10.opBLKO, // 0o70010x\n PDP10.opDATAO, // 0o70014x\n PDP10.opCONO, // 0o70020x\n PDP10.opCONI, // 0o70024x\n PDP10.opCONSZ, // 0o70030x\n PDP10.opCONSO // 0o70034x\n];\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/rom.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass ROMPDP10 extends Component {\n /**\n * ROMPDP10(parmsROM)\n *\n * The ROMPDP10 component expects the following (parmsROM) properties:\n *\n * addr: physical address of ROM\n * size: amount of ROM, in bytes\n * alias: physical alias address (null if none)\n * file: name of ROM data file\n *\n * NOTE: The ROM data will not be copied into place until the Bus is ready (see initBus()) AND\n * the ROM data file has finished loading (see finishLoad()).\n *\n * Also, while the size parameter may seem redundant, I consider it useful to confirm that the ROM\n * you received is the ROM you expected.\n *\n * @param {Object} parmsROM\n */\n constructor(parmsROM)\n {\n super(\"ROM\", parmsROM, MessagesPDP10.ROM);\n\n this.abInit = null;\n this.aSymbols = null;\n\n this.addrROM = +parmsROM['addr'];\n this.sizeROM = +parmsROM['size'];\n this.fRetainROM = false;\n\n /*\n * The new 'alias' property can now be EITHER a single physical address (like 'addr') OR an array of\n * physical addresses; eg:\n *\n * [0xf0000,0xffff0000,0xffff8000]\n *\n * We could have overloaded 'addr' to accomplish the same thing, but I think it's better to have any\n * aliased locations listed under a separate property.\n *\n * Most ROMs are not aliased, in which case the 'alias' property should have the default value of null.\n */\n this.addrAlias = parmsROM['alias'];\n if (typeof this.addrAlias == \"string\") {\n this.addrAlias = eval(this.addrAlias);\n }\n\n this.sFilePath = parmsROM['file'];\n this.sFileName = Str.getBaseName(this.sFilePath);\n\n if (this.sFilePath) {\n var sFileURL = this.sFilePath;\n if (DEBUG) this.log('load(\"' + sFileURL + '\")');\n /*\n * If the selected ROM file has a \".json\" extension, then we assume it's pre-converted\n * JSON-encoded ROM data, so we load it as-is; ditto for ROM files with a \".hex\" extension.\n * Otherwise, we ask our server-side ROM converter to return the file in a JSON-compatible format.\n */\n var sFileExt = Str.getExtension(this.sFileName);\n if (sFileExt != DumpAPI.FORMAT.JSON && sFileExt != DumpAPI.FORMAT.HEX) {\n sFileURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFilePath + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES + '&' + DumpAPI.QUERY.DECIMAL + '=true';\n }\n var rom = this;\n Web.getResource(sFileURL, null, true, function doneLoad(sURL, sResponse, nErrorCode) {\n rom.finishLoad(sURL, sResponse, nErrorCode);\n });\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {ROMPDP10}\n * @param {ComputerPDP10} cmp\n * @param {BusPDP10} bus\n * @param {CPUStatePDP10} cpu\n * @param {DebuggerPDP10} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.initROM();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {ROMPDP10}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (this.aSymbols) {\n if (this.dbg) {\n this.dbg.addSymbols(this.id, this.addrROM, this.sizeROM, this.aSymbols);\n }\n /*\n * Our only role in the handling of symbols is to hand them off to the Debugger at our\n * first opportunity. Now that we've done that, our copy of the symbols, if any, are toast.\n */\n delete this.aSymbols;\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * Since we have nothing to do on powerDown(), and no state to return, we could simply omit\n * this function. But it doesn't hurt anything, and maybe we'll use our state to save something\n * useful down the road, like user-defined symbols (ie, symbols that the Debugger may have\n * created, above and beyond those symbols we automatically loaded, if any, along with the ROM).\n *\n * @this {ROMPDP10}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return true;\n }\n\n /**\n * finishLoad(sURL, sData, nErrorCode)\n *\n * @this {ROMPDP10}\n * @param {string} sURL\n * @param {string} sData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n finishLoad(sURL, sData, nErrorCode)\n {\n if (nErrorCode) {\n this.notice(\"Unable to load ROM resource (error \" + nErrorCode + \": \" + sURL + \")\");\n this.sFilePath = null;\n }\n else {\n Component.addMachineResource(this.idMachine, sURL, sData);\n var resource = Web.parseMemoryResource(sURL, sData);\n if (resource) {\n this.abInit = resource.aBytes;\n this.aSymbols = resource.aSymbols;\n } else {\n this.sFilePath = null;\n }\n }\n this.initROM();\n }\n\n /**\n * initROM()\n *\n * This function is called by both initBus() and finishLoad(), but it cannot copy the initial data into place\n * until after initBus() has received the Bus component AND finishLoad() has received the data. When both those\n * criteria are satisfied, the component becomes \"ready\".\n *\n * @this {ROMPDP10}\n */\n initROM()\n {\n if (!this.isReady()) {\n if (this.sFilePath) {\n /*\n * Too early...\n */\n if (!this.abInit || !this.bus) return;\n\n /*\n * If no explicit size was specified, then use whatever the actual size is.\n */\n if (!this.sizeROM) {\n this.sizeROM = this.abInit.length;\n }\n if (this.abInit.length != this.sizeROM) {\n /*\n * Note that setError() sets the component's fError flag, which in turn prevents setReady() from\n * marking the component ready. TODO: Revisit this decision. On the one hand, it sounds like a\n * good idea to stop the machine in its tracks whenever a setError() occurs, but there may also be\n * times when we'd like to forge ahead anyway.\n */\n this.setError(\"ROM size (\" + Str.toHexLong(this.abInit.length) + \") does not match specified size (\" + Str.toHexLong(this.sizeROM) + \")\");\n }\n else if (this.addROM(this.addrROM)) {\n\n var aliases = [];\n if (typeof this.addrAlias == \"number\") {\n aliases.push(this.addrAlias);\n } else if (this.addrAlias != null && this.addrAlias.length) {\n aliases = this.addrAlias;\n }\n for (var i = 0; i < aliases.length; i++) {\n this.cloneROM(aliases[i]);\n }\n /*\n * We used to hang onto the initial ROM data so that we could restore any bytes the CPU overwrote,\n * using memory write-notification handlers, but with the introduction of read-only memory blocks, that's\n * no longer necessary.\n *\n * TODO: Consider an option to retain the ROM data, and give the user some way of restoring ROMs.\n * That may be useful for \"resumable\" machines that save/restore all dirty block of memory, regardless\n * whether they're ROM or RAM. However, the only way to modify a machine's ROM is with the Debugger,\n * and Debugger users should know better.\n */\n if (!this.fRetainROM) {\n delete this.abInit;\n }\n }\n }\n this.setReady();\n }\n }\n\n /**\n * addROM(addr)\n *\n * @this {ROMPDP10}\n * @param {number} addr\n * @return {boolean}\n */\n addROM(addr)\n {\n if (this.bus.addMemory(addr, this.sizeROM, MemoryPDP10.TYPE.ROM)) {\n if (DEBUG) this.log(\"addROM(): copying ROM to \" + Str.toHexLong(addr) + \" (\" + Str.toHexLong(this.abInit.length) + \" bytes)\");\n var i;\n for (i = 0; i < this.abInit.length; i++) {\n this.bus.setWordDirect(addr + i, this.abInit[i]);\n }\n return true;\n }\n\n /*\n * We don't need to report an error here, because addMemory() already takes care of that.\n */\n return false;\n }\n\n /**\n * cloneROM(addr)\n *\n * For ROMs with one or more alias addresses, we used to call addROM() for each address. However,\n * that obviously wasted memory, since each alias was an independent copy, and if you used the\n * Debugger to edit the ROM in one location, the changes would not appear in the other location(s).\n *\n * Now that the Bus component provides low-level getMemoryBlocks() and setMemoryBlocks() methods\n * to manually get and set the blocks of any memory range, it is now possible to create true aliases.\n *\n * @this {ROMPDP10}\n * @param {number} addr\n */\n cloneROM(addr)\n {\n var aBlocks = this.bus.getMemoryBlocks(this.addrROM, this.sizeROM);\n this.bus.setMemoryBlocks(addr, this.sizeROM, aBlocks);\n }\n\n /**\n * ROMPDP10.init()\n *\n * This function operates on every HTML element of class \"rom\", extracting the\n * JSON-encoded parameters for the ROMPDP10 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a ROMPDP10 component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeROM = Component.getElementsByClass(document, PDP10.APPCLASS, \"rom\");\n for (var iROM = 0; iROM < aeROM.length; iROM++) {\n var eROM = aeROM[iROM];\n var parmsROM = Component.getComponentParms(eROM);\n var rom = new ROMPDP10(parmsROM);\n Component.bindComponentControls(rom, eROM, PDP10.APPCLASS);\n }\n }\n}\n\n/*\n * NOTE: There's currently no need for this component to have a reset() function, since\n * once the ROM data is loaded, it can't be changed, so there's nothing to reinitialize.\n *\n * OK, well, I take that back, because the Debugger, if installed, has the ability to modify\n * ROM contents, so in that case, having a reset() function that restores the original ROM data\n * might be useful; then again, it might not, depending on what you're trying to debug.\n *\n * If we do add reset(), then we'll want to change initROM() to hang onto the original\n * ROM data; currently, we release it after copying it into the read-only memory allocated\n * via bus.addMemory().\n */\n\n/*\n * Initialize all the ROMPDP10 modules on the page.\n */\nWeb.onInit(ROMPDP10.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/ram.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass RAMPDP10 extends Component {\n /**\n * RAMPDP10(parmsRAM)\n *\n * The RAMPDP10 component expects the following (parmsRAM) properties:\n *\n * addr: starting physical address of RAM (default is 0)\n * size: amount of RAM, in bytes (default is 0, which means defer to motherboard switch settings)\n * file: name of optional data file to load into RAM (default is \"\")\n * load: optional file load address (overrides any load address specified in the data file; default is null)\n * exec: optional file exec address (overrides any exec address specified in the data file; default is null)\n *\n * NOTE: We make a note of the specified size, but no memory is initially allocated for the RAM until the\n * Computer component calls powerUp().\n *\n * @param {Object} parmsRAM\n */\n constructor(parmsRAM)\n {\n super(\"RAM\", parmsRAM);\n\n this.aData = null;\n this.aSymbols = null;\n\n this.addrRAM = +parmsRAM['addr'];\n this.sizeRAM = +parmsRAM['size'];\n\n this.addrLoad = parmsRAM['load'];\n this.addrExec = parmsRAM['exec'];\n if (this.addrLoad != null) this.addrLoad = +this.addrLoad;\n if (this.addrExec != null) this.addrExec = +this.addrExec;\n\n this.fInstalled = (!!this.sizeRAM); // 0 is the default value for 'size' when none is specified\n this.fAllocated = this.fReset = false;\n\n this.sFilePath = parmsRAM['file'];\n this.sFileName = Str.getBaseName(this.sFilePath);\n\n if (this.sFilePath) {\n var sFileURL = this.sFilePath;\n if (DEBUG) this.log('load(\"' + sFileURL + '\")');\n /*\n * If the selected data file has a \".json\" extension, then we assume it's pre-converted\n * JSON-encoded data, so we load it as-is; ditto for ROM files with a \".hex\" extension.\n * Otherwise, we ask our server-side converter to return the file in a JSON-compatible format.\n */\n var sFileExt = Str.getExtension(this.sFileName);\n if (sFileExt != DumpAPI.FORMAT.JSON && sFileExt != DumpAPI.FORMAT.HEX) {\n sFileURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFilePath + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES + '&' + DumpAPI.QUERY.DECIMAL + '=true';\n }\n var ram = this;\n Web.getResource(sFileURL, null, true, function doneLoad(sURL, sResponse, nErrorCode) {\n ram.finishLoad(sURL, sResponse, nErrorCode);\n });\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {RAMPDP10}\n * @param {ComputerPDP10} cmp\n * @param {BusPDP10} bus\n * @param {CPUStatePDP10} cpu\n * @param {DebuggerPDP10} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.initRAM();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {RAMPDP10}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (this.aSymbols) {\n if (this.dbg) {\n this.dbg.addSymbols(this.id, this.addrRAM, this.sizeRAM, this.aSymbols);\n }\n /*\n * Our only role in the handling of symbols is to hand them off to the Debugger at our\n * first opportunity. Now that we've done that, our copy of the symbols, if any, are toast.\n */\n delete this.aSymbols;\n }\n if (!fRepower) {\n /*\n * Since we use the Bus to allocate all our memory, memory contents are already restored for us,\n * so we don't save any state, and therefore no state should be restored. Just do a reset().\n */\n\n this.reset();\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {RAMPDP10}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n /*\n * The Computer powers down the CPU first, at which point CPUState state is saved,\n * which includes the Bus state, and since we use the Bus component to allocate all\n * our memory, memory contents are already saved for us, so we don't need the usual\n * save logic.\n */\n return true;\n }\n\n /**\n * finishLoad(sURL, sData, nErrorCode)\n *\n * @this {RAMPDP10}\n * @param {string} sURL\n * @param {string} sData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n finishLoad(sURL, sData, nErrorCode)\n {\n if (nErrorCode) {\n this.notice(\"Unable to load RAM resource (error \" + nErrorCode + \": \" + sURL + \")\");\n this.sFilePath = null;\n }\n else {\n Component.addMachineResource(this.idMachine, sURL, sData);\n var resource = Web.parseMemoryResource(sURL, sData);\n if (resource) {\n this.aData = resource.aData;\n this.aSymbols = resource.aSymbols;\n if (this.addrLoad == null) this.addrLoad = resource.addrLoad;\n if (this.addrExec == null) this.addrExec = resource.addrExec;\n } else {\n this.sFilePath = null;\n }\n }\n this.initRAM();\n }\n\n /**\n * initRAM()\n *\n * This function is called by both initBus() and finishLoad(), but it cannot copy the initial data into place\n * until after initBus() has received the Bus component AND finishLoad() has received the data. When both those\n * criteria are satisfied, the component becomes \"ready\".\n *\n * @this {RAMPDP10}\n */\n initRAM()\n {\n if (!this.bus) return;\n\n if (!this.fAllocated && this.sizeRAM) {\n if (this.bus.addMemory(this.addrRAM, this.sizeRAM, MemoryPDP10.TYPE.RAM)) {\n this.fAllocated = true;\n } else {\n this.sizeRAM = 0; // don't bother trying again (it just results in redundant error messages)\n }\n }\n if (!this.isReady()) {\n if (!this.fAllocated) {\n Component.error(\"No RAM allocated\");\n }\n else if (this.sFilePath) {\n /*\n * Too early...\n */\n if (!this.aData) return;\n\n if (this.loadImage(this.aData, this.addrLoad, this.addrExec, this.addrRAM)) {\n this.status('Loaded image \"' + this.sFileName + '\"');\n } else {\n this.notice('Error loading image \"' + this.sFileName + '\"');\n }\n\n /*\n * NOTE: We now retain this data, so that reset() can return the RAM to its predefined state.\n *\n * delete this.aData;\n */\n }\n this.fReset = true;\n this.setReady();\n }\n }\n\n /**\n * reset()\n *\n * @this {RAMPDP10}\n */\n reset()\n {\n if (this.fAllocated && !this.fReset) {\n /*\n * TODO: Add a configuration parameter for selecting the byte pattern on reset?\n * Note that when memory blocks are originally created, they are currently always\n * zero-initialized, so this would only affect resets.\n */\n this.bus.zeroMemory(this.addrRAM, this.sizeRAM, 0);\n if (this.aData) {\n this.loadImage(this.aData, this.addrLoad, this.addrExec, this.addrRAM, !this.dbg);\n }\n }\n this.fReset = false;\n }\n\n /**\n * loadImage(aData, addrLoad, addrExec, addrInit, fStart)\n *\n * If the array contains a PAPER tape image in the \"Absolute Format,\" load it as specified\n * by the format; otherwise, load it as-is using the address(es) supplied.\n *\n * @this {RAMPDP10}\n * @param {Array} aData\n * @param {number|null} [addrLoad]\n * @param {number|null} [addrExec] (this CAN override any starting address INSIDE the image)\n * @param {number|null} [addrInit]\n * @param {boolean} [fStart]\n * @return {boolean} (true if loaded, false if not)\n */\n loadImage(aData, addrLoad, addrExec, addrInit, fStart)\n {\n var fLoaded = false;\n\n if (addrLoad == null) {\n addrLoad = addrInit;\n }\n if (addrLoad != null) {\n for (var i = 0; i < aData.length; i++) {\n this.bus.setWordDirect(addrLoad + i, aData[i]);\n }\n fLoaded = true;\n }\n if (fLoaded) {\n /*\n * Set the start address to whatever the caller provided, or failing that, whatever start\n * address was specified inside the image.\n *\n * For example, the diagnostic \"MAINDEC-11-D0AA-PB\" doesn't include a start address inside the\n * image, but we know that the directions for that diagnostic say to \"Start and Restart at 200\",\n * so we have manually inserted an \"exec\":128 in the JSON containing the image.\n */\n if (addrExec == null) {\n this.cpu.stopCPU();\n fStart = false;\n }\n if (addrExec != null) {\n this.cpu.setReset(addrExec, fStart);\n }\n }\n return fLoaded;\n }\n\n /**\n * RAMPDP10.init()\n *\n * This function operates on every HTML element of class \"ram\", extracting the\n * JSON-encoded parameters for the RAMPDP10 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a RAMPDP10 component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeRAM = Component.getElementsByClass(document, PDP10.APPCLASS, \"ram\");\n for (var iRAM = 0; iRAM < aeRAM.length; iRAM++) {\n var eRAM = aeRAM[iRAM];\n var parmsRAM = Component.getComponentParms(eRAM);\n var ram = new RAMPDP10(parmsRAM);\n Component.bindComponentControls(ram, eRAM, PDP10.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize all the RAMPDP10 modules on the page.\n */\nWeb.onInit(RAMPDP10.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/serial.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * Component class, because otherwise the Compiler won't allow us to *reference* the named\n * property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass SerialPortPDP10 extends Component {\n /**\n * SerialPortPDP10(parmsSerial)\n *\n * The SerialPort component has the following component-specific (parmsSerial) properties:\n *\n * adapter: adapter number; 0 if not defined (the PCx86 SerialPort component uses this\n * value to set the device's internal COM number, which in turn determines other properties,\n * such as I/O ports and IRQ; for the PDP-10, this currently has no defined use)\n *\n * binding: name of a control (based on its \"binding\" attribute) to bind to this port's I/O\n *\n * tabSize: set to a non-zero number to convert tabs to spaces (applies only to output to\n * the above binding); default is 0 (no conversion)\n *\n * upperCase: if true, all received input is upper-cased; it is normally the responsibility\n * of the sending device to ensure this, but sometimes it's more convenient to enforce\n * on the receiving end.\n *\n * @param {Object} parmsSerial\n */\n constructor(parmsSerial)\n {\n super(\"SerialPort\", parmsSerial, MessagesPDP10.SERIAL);\n\n this.iAdapter = +parmsSerial['adapter'];\n this.fUpperCase = parmsSerial['upperCase'];\n if (typeof this.fUpperCase == \"string\") this.fUpperCase = (this.fUpperCase == \"true\");\n /**\n * consoleBuffer becomes a string that records serial port output if the 'binding' property is set to the\n * reserved name \"console\". Nothing is written to the console, however, until a linefeed (0x0A) is output\n * or the string length reaches a threshold (currently, 1024 characters).\n *\n * @type {string|null}\n */\n this.consoleBuffer = null;\n\n /**\n * controlBuffer is a DOM element bound to the port (currently used for output only; see transmitByte()).\n *\n * Example: CTTY COM2\n *\n * The CTTY DOS command redirects all CON I/O to the specified serial port (eg, COM2), which it assumes is\n * connected to a serial terminal, and therefore anything it *transmits* via COM2 will be displayed by the\n * terminal. It further assumes that anything typed on such a terminal is NOT displayed, so as DOS *receives*\n * serial input, DOS *transmits* the appropriate characters back to the terminal via COM2.\n *\n * As a result, controlBuffer only needs to be updated by the transmitByte() function.\n *\n * @type {Object}\n */\n this.controlBuffer = null;\n\n /*\n * If controlBuffer is being used AND 'tabSize' is set, then we make an attempt to monitor the characters\n * being echoed via transmitByte(), maintain a logical column position, and convert any tabs into the appropriate\n * number of spaces.\n *\n * charBOL, if nonzero, is a character to automatically output at the beginning of every line. This probably\n * isn't generally useful; I use it internally to preformat serial output.\n */\n this.tabSize = +parmsSerial['tabSize'];\n this.charBOL = +parmsSerial['charBOL'];\n this.iLogicalCol = 0;\n this.fNullModem = true;\n\n this.abReceive = [];\n\n var sBinding = parmsSerial['binding'];\n if (sBinding == \"console\") {\n this.consoleBuffer = \"\";\n } else {\n /*\n * If the SerialPort wants to bind to a control (eg, \"print\") in a DIFFERENT component (eg, \"Panel\"),\n * then it specifies the name of that control with the 'binding' property. The SerialPort constructor\n * will then call bindExternalControl(), which looks up the control, and then passes it to our own\n * setBinding() handler.\n * \n * For bindExternalControl() to succeed, it also need to know the target component; for now, that's\n * been hard-coded to \"Panel\", in part because that's one of the few components we can rely upon\n * initializing before we do, but it would be a simple matter to include a component type or ID as part\n * of the 'binding' property as well, if we need more flexibility later.\n * \n * NOTE: If sBinding is not the name of a valid Control Panel DOM element, this call does nothing.\n */\n Component.bindExternalControl(this, sBinding);\n }\n\n /*\n * No connection until initConnection() is called.\n */\n this.sDataReceived = \"\";\n this.connection = this.sendData = this.updateStatus = null;\n\n /*\n * Export all functions required by initConnection().\n */\n this['exports'] = {\n 'connect': this.initConnection,\n 'receiveData': this.receiveData,\n 'receiveStatus': this.receiveStatus,\n 'setConnection': this.setConnection\n };\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {SerialPortPDP10}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"buffer\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n if (!sHTMLType || sHTMLType == \"textarea\") {\n\n var serial = this;\n this.bindings[sBinding] = this.controlBuffer = control;\n\n /*\n * An onkeydown handler is required for certain keys that browsers tend to consume themselves;\n * for example, BACKSPACE is often defined as going back to the previous web page, and certain\n * CTRL keys are often used for browser shortcuts (usually on Windows-based browsers).\n *\n * NOTE: We don't bother with a keyUp handler, because for the most part, we're only intercepting\n * keys that require special treatment; in general, we're content with keyPress events.\n */\n control.onkeydown = function onKeyDown(event) {\n event = event || window.event;\n var bASCII = 0;\n var keyCode = event.keyCode;\n /*\n * Perform the same remapping of BACKSPACE and DELETE that our VT100 emulation performs,\n * for PCjs-wide consistency; see the KEYMAP table in /modules/pc8080/lib/keyboard.js for\n * the rationale. Ditto for ALT-DELETE; see onKeyDown() in /modules/pc8080/lib/keyboard.js\n * for details.\n *\n * NOTE: keyDown (and keyUp) events supply us with KEYCODE values, which are NOT the same as\n * ASCII values, which is why we are comparing with KEYCODE values but assigning ASCII values,\n * because receiveData() requires ASCII values.\n */\n if (keyCode == Keys.KEYCODE.BS) {\n bASCII = event.altKey? Keys.ASCII.CTRL_H : Keys.ASCII.DEL;\n }\n else if (keyCode == Keys.KEYCODE.DEL) {\n bASCII = Keys.ASCII.CTRL_H;\n }\n else if (event.ctrlKey && keyCode >= Keys.ASCII.A && keyCode <= Keys.ASCII.Z) {\n bASCII = keyCode - (Keys.ASCII.A - Keys.ASCII.CTRL_A);\n }\n if (bASCII) {\n if (event.preventDefault) event.preventDefault();\n serial.receiveData(bASCII);\n }\n return true;\n };\n\n control.onkeypress = function onKeyPress(event) {\n /*\n * NOTE: Unlike keyDown events, keyPress events generally supply us with ASCII values,\n * despite the fact that, as above, they come to us via the keyCode property. Yes, it's\n * brilliant (or rather, the opposite of brilliant), but that's life.\n */\n event = event || window.event;\n /*\n * Not sure why COMMAND-key combinations are coming through here (on Safari at least),\n * but in any case, let's make sure we don't act on them.\n */\n if (!event.metaKey) {\n var bASCII = event.which || event.keyCode;\n /*\n * Perform the same remapping of ALT-ENTER (to LINE-FEED) that our VT100 emulation performs,\n * for PCjs-wide consistency; see onKeyDown() in /modules/pc8080/lib/keyboard.js for details.\n */\n if (event.altKey) {\n if (bASCII == Keys.ASCII.CTRL_M) {\n bASCII = Keys.ASCII.CTRL_J;\n }\n }\n serial.receiveData(bASCII);\n /*\n * Since we're going to remove the \"readonly\" attribute from the <textarea> control\n * (so that the soft keyboard activates on iOS), instead of calling preventDefault() for\n * selected keys (eg, the SPACE key, whose default behavior is to scroll the page), we must\n * now call it for *all* keys, so that the keyCode isn't added to the control immediately,\n * on top of whatever the machine is echoing back, resulting in double characters.\n */\n if (event.preventDefault) event.preventDefault();\n }\n return true;\n };\n\n control.onpaste = function onKeyPress(event) {\n if (event.stopPropagation) event.stopPropagation();\n if (event.preventDefault) event.preventDefault();\n var clipboardData = event.clipboardData || window.clipboardData;\n if (clipboardData) {\n /*\n * NOTE: Multiple lines of pasted text will (at least on macOS) contain LFs instead of CRs;\n * this is dealt with in receiveData() whenever it receives a string of characters.\n */\n serial.receiveData(clipboardData.getData('Text'));\n }\n };\n\n /*\n * Now that we've added an onkeypress handler that calls preventDefault() for ALL keys, the control\n * itself no longer needs the \"readonly\" attribute; we primarily need to remove it for iOS browsers,\n * so that the soft keyboard will activate, but it shouldn't hurt to remove the attribute for all browsers.\n */\n control.removeAttribute(\"readonly\");\n\n return true;\n }\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {SerialPortPDP10}\n * @param {ComputerPDP10} cmp\n * @param {BusPDP10} bus\n * @param {CPUStatePDP10} cpu\n * @param {DebuggerPDP10} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n this.setReady();\n }\n\n /**\n * initConnection(fNullModem)\n *\n * If a machine 'connection' parameter exists of the form \"{sourcePort}->{targetMachine}.{targetPort}\",\n * and \"{sourcePort}\" matches our idComponent, then look for a component with id \"{targetMachine}.{targetPort}\".\n *\n * If the target component is found, then verify that it has exported functions with the following names:\n *\n * receiveData(data): called when we have data to transmit; aliased internally to sendData(data)\n * receiveStatus(pins): called when our control signals have changed; aliased internally to updateStatus(pins)\n *\n * For now, we're not going to worry about communication in the other direction, because when the target component\n * performs its own initConnection(), it will find our receiveData() and receiveStatus() functions, at which point\n * communication in both directions should be established, and the circle of life complete.\n *\n * For added robustness, if the target machine initializes much more slowly than we do, and our connection attempt\n * fails, that's OK, because when it finally initializes, its initConnection() will call our initConnection();\n * if we've already initialized, no harm done.\n *\n * @this {SerialPortPDP10}\n * @param {boolean} [fNullModem] (caller's null-modem setting, to ensure our settings are in agreement)\n */\n initConnection(fNullModem)\n {\n if (!this.connection) {\n var sConnection = this.cmp.getMachineParm(\"connection\");\n if (sConnection) {\n var asParts = sConnection.split('->');\n if (asParts.length == 2) {\n var sSourceID = Str.trim(asParts[0]);\n if (sSourceID != this.idComponent) return; // this connection string is intended for another instance\n var sTargetID = Str.trim(asParts[1]);\n this.connection = Component.getComponentByID(sTargetID);\n if (this.connection) {\n var exports = this.connection['exports'];\n if (exports) {\n var fnConnect = exports['connect'];\n if (fnConnect) fnConnect.call(this.connection, this.fNullModem);\n this.sendData = exports['receiveData'];\n if (this.sendData) {\n this.fNullModem = fNullModem;\n this.updateStatus = exports['receiveStatus'];\n this.status(\"Connected \" + this.idMachine + '.' + sSourceID + \" to \" + sTargetID);\n return;\n }\n }\n }\n }\n /*\n * Changed from notice() to status() because sometimes a connection fails simply because one of us is a laggard.\n */\n this.status(\"Unable to establish connection: \" + sConnection);\n }\n }\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {SerialPortPDP10}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n\n /*\n * This is as late as we can currently wait to make our first inter-machine connection attempt;\n * even so, the target machine's initialization process may still be ongoing, so any connection\n * may be not fully resolved until the target machine performs its own initConnection(), which will\n * in turn invoke our initConnection() again.\n */\n this.initConnection(this.fNullModem);\n\n if (!data) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {SerialPortPDP10}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {SerialPortPDP10}\n */\n reset()\n {\n this.initState();\n }\n\n /**\n * save()\n *\n * This implements save support for the SerialPort component.\n *\n * @this {SerialPortPDP10}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveRegisters());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the SerialPort component.\n *\n * @this {SerialPortPDP10}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return this.initState(data[0]);\n }\n\n /**\n * initState(a)\n *\n * @this {SerialPortPDP10}\n * @param {Array} [a]\n * @return {boolean} true if successful, false if failure\n */\n initState(a)\n {\n return true;\n }\n\n /**\n * saveRegisters()\n *\n * Basically, the inverse of initState().\n *\n * @this {SerialPortPDP10}\n * @return {Array}\n */\n saveRegisters()\n {\n return [];\n }\n\n /**\n * receiveData(data)\n *\n * This replaces the old sendRBR() function, which expected an Array of bytes. We still support that,\n * but in order to support connections with other SerialPort components (ie, the PC8080 SerialPort), we\n * have added support for numbers and strings as well.\n *\n * @this {SerialPortPDP10}\n * @param {number|string|Array} data\n * @return {boolean} true if received, false if not\n */\n receiveData(data)\n {\n if (typeof data == \"number\") {\n this.abReceive.push(data);\n }\n else if (typeof data == \"string\") {\n var bASCII = 0, bASCIIPrev;\n for (var i = 0; i < data.length; i++) {\n bASCIIPrev = bASCII;\n bASCII = data.charCodeAt(i);\n /*\n * NOTE: Multiple lines of pasted text will (at least on macOS) contain LFs instead of CRs;\n * we convert them to CRs below. Windows may do something different, but in the worst case,\n * even if we receive CR/LF pairs, this code should keep the CRs and lose the LFs.\n */\n if (bASCII == Str.ASCII.LF) {\n if (bASCIIPrev == Str.ASCII.CR) continue;\n bASCII = Str.ASCII.CR;\n }\n this.abReceive.push(bASCII);\n }\n }\n else {\n this.abReceive = this.abReceive.concat(data);\n }\n\n return true; // for now, return true regardless, since we're buffering everything anyway\n }\n\n /**\n * receiveByte()\n *\n * @this {SerialPortPDP10}\n * @return {number} (0x00-0xff if byte available, -1 if not)\n */\n receiveByte()\n {\n var b = -1;\n if (this.abReceive.length) {\n /*\n * Here, as elsewhere (eg, the PC11 component), even if I trusted all incoming data\n * to be byte values (which I don't), there's also the risk that it could be signed data\n * (eg, -128 to 127, instead of 0 to 255). Both risks are good reasons to always mask\n * the data assigned to RBUF with 0xff.\n */\n b = this.abReceive.shift() & 0xff;\n this.printMessage(\"receiveByte(\" + Str.toHexByte(b) + \")\");\n if (this.fUpperCase) {\n /*\n * Automatically transform lower-case ASCII codes to upper-case; fUpperCase should\n * only be set when a terminal or some sort of pseudo-display is being used and we don't\n * trust it to have its CAPS-LOCK setting correct.\n */\n if (b >= 0x61 && b < 0x7A) b -= 0x20;\n }\n }\n return b;\n }\n\n /**\n * receiveStatus(pins)\n *\n * @this {SerialPortPDP10}\n * @param {number} pins\n */\n receiveStatus(pins)\n {\n }\n\n /**\n * setConnection(component, fn)\n *\n * @this {SerialPortPDP10}\n * @param {Object|null} component\n * @param {function(number)} fn\n * @return {boolean}\n */\n setConnection(component, fn)\n {\n if (!this.connection) {\n this.connection = component;\n this.sendData = fn;\n return true;\n }\n return false;\n }\n\n /**\n * transmitByte(b)\n *\n * @this {SerialPortPDP10}\n * @param {number} b\n * @return {boolean} true if transmitted, false if not\n */\n transmitByte(b)\n {\n var fTransmitted = false;\n\n if (MAXDEBUG) this.printMessage(\"transmitByte(\" + Str.toHexByte(b) + \")\");\n\n if (this.sendData) {\n if (this.sendData.call(this.connection, b)) {\n fTransmitted = true;\n }\n }\n\n /*\n * TODO: Why do DEC diagnostics like to output bytes with bit 7 set?\n */\n b &= 0x7F;\n if (this.controlBuffer) {\n if (b == 0x0D) {\n this.iLogicalCol = 0;\n }\n else if (b == 0x08) {\n this.controlBuffer.value = this.controlBuffer.value.slice(0, -1);\n /*\n * TODO: Back up the correct number of columns if the character erased was a tab.\n */\n if (this.iLogicalCol > 0) this.iLogicalCol--;\n }\n else if (b) {\n /*\n * RT-11 outputs lots of NULL characters, at least after a \"D 56=5015\" (0x0A0D) command has\n * been issued, hence the \"if (b)\" check above.\n *\n * TODO: Also consider a check for Keys.ASCII.CTRL_C, because by default, RT-11 outputs \"raw\"\n * CTRL_C characters, which we capture below and render as <ETX>. RT-11 does this for other keys\n * as well, such as CTRL_K (<VT>) and CTRL_L (<FF>).\n */\n var s = Str.toASCIICode(b); // formerly: String.fromCharCode(b);\n var nChars = s.length; // formerly: (b >= 0x20? 1 : 0);\n if (b < 0x20 && nChars == 1) nChars = 0;\n if (b == 0x09) {\n var tabSize = this.tabSize || 8;\n nChars = tabSize - (this.iLogicalCol % tabSize);\n if (this.tabSize) s = Str.pad(\"\", nChars);\n }\n if (this.charBOL && !this.iLogicalCol && nChars) s = String.fromCharCode(this.charBOL) + s;\n this.controlBuffer.value += s;\n this.controlBuffer.scrollTop = this.controlBuffer.scrollHeight;\n this.iLogicalCol += nChars;\n }\n fTransmitted = true;\n }\n else if (this.consoleBuffer != null) {\n if (b == 0x0A || this.consoleBuffer.length >= 1024) {\n this.println(this.consoleBuffer);\n this.consoleBuffer = \"\";\n }\n if (b != 0x0A) {\n this.consoleBuffer += String.fromCharCode(b);\n }\n fTransmitted = true;\n }\n\n return fTransmitted;\n }\n\n /**\n * SerialPortPDP10.init()\n *\n * This function operates on every HTML element of class \"serial\", extracting the\n * JSON-encoded parameters for the SerialPort constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a SerialPort component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeSerial = Component.getElementsByClass(document, PDP10.APPCLASS, \"serial\");\n for (var iSerial = 0; iSerial < aeSerial.length; iSerial++) {\n var eSerial = aeSerial[iSerial];\n var parmsSerial = Component.getComponentParms(eSerial);\n var serial = new SerialPortPDP10(parmsSerial);\n Component.bindComponentControls(serial, eSerial, PDP10.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize every SerialPort module on the page.\n */\nWeb.onInit(SerialPortPDP10.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/debugger.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Debugger Address Object\n *\n * This is the basic structure; other debuggers may extend it.\n *\n * addr address\n * fTemporary true if this is a temporary breakpoint address\n * sCmd set for breakpoint addresses if there's an associated command string\n * aCmds preprocessed commands (from sCmd)\n *\n * @typedef {{\n * addr:(number|undefined),\n * fTemporary:(boolean|undefined),\n * sCmd:(string|undefined),\n * aCmds:(Array.<string>|undefined)\n * }}\n */\nvar DbgAddr;\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * subclass (eg, SerialPort), because otherwise the Compiler won't allow us to *reference*\n * the named property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass Debugger extends Component\n{\n /**\n * Debugger(parmsDbg)\n *\n * The Debugger component supports the following optional (parmsDbg) properties:\n *\n * base: the base to use for most numeric input/output (default is 16)\n *\n * The Debugger component is a shared component containing a subset of functionality used by\n * the other CPU-specific Debuggers (eg, DebuggerX86). Over time, the goal is to factor out as\n * much common debugging support as possible from those components into this one.\n *\n * @param {Object} parmsDbg\n */\n constructor(parmsDbg)\n {\n if (DEBUGGER) {\n\n super(\"Debugger\", parmsDbg);\n\n /*\n * Default base used to display all values; modified with the \"s base\" command.\n */\n this.nBase = +parmsDbg['base'] || 16;\n\n /*\n * Default number of bits of integer precision; it can be overridden by the Debugger\n * but there is no command to adjust it.\n */\n this.nBits = 32;\n\n this.achGroup = ['{','}'];\n this.achAddress = ['[',']'];\n\n /*\n * These keep track of instruction activity, but only when tracing or when Debugger checks\n * have been enabled (eg, one or more breakpoints have been set).\n *\n * They are zeroed by the reset() notification handler. cInstructions is advanced by\n * stepCPU() and checkInstruction() calls. nCycles is updated by every stepCPU() or stop()\n * call and simply represents the number of cycles performed by the last run of instructions.\n */\n this.nCycles = 0;\n this.cOpcodes = this.cOpcodesStart = 0;\n\n /*\n * fAssemble is true when \"assemble mode\" is active, false when not.\n */\n this.fAssemble = false;\n\n /*\n * This maintains command history. New commands are inserted at index 0 of the array.\n * When Enter is pressed on an empty input buffer, we default to the command at aPrevCmds[0].\n */\n this.iPrevCmd = -1;\n this.aPrevCmds = [];\n\n /*\n * aVariables is an object with properties that grow as setVariable() assigns more variables;\n * each property corresponds to one variable, where the property name is the variable name (ie,\n * a string beginning with a non-digit, followed by zero or more symbol characters and/or digits)\n * and the property value is the variable's numeric value. See doVar() and setVariable() for\n * details.\n *\n * Note that parseValue() parses variables before numbers, so any variable that looks like a\n * unprefixed hex value (eg, \"a5\" as opposed to \"0xa5\") will trump the numeric value. Unprefixed\n * hex values are a convenience of parseValue(), which always calls Str.parseInt() with a default\n * base of 16; however, that default be overridden with a variety of explicit prefixes or suffixes\n * (eg, a leading \"0o\" to indicate octal, a trailing period to indicate decimal, etc.)\n *\n * See Str.parseInt() for more details about supported numbers.\n */\n this.aVariables = {};\n\n } // endif DEBUGGER\n }\n\n /**\n * getRegIndex(sReg, off)\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {string} sReg\n * @param {number} [off] optional offset into sReg\n * @return {number} register index, or -1 if not found\n */\n getRegIndex(sReg, off)\n {\n return -1;\n }\n\n /**\n * getRegValue(iReg)\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {number} iReg\n * @return {number|undefined}\n */\n getRegValue(iReg)\n {\n return undefined;\n }\n\n /**\n * parseAddrReference(s, sAddr)\n *\n * Returns the given string with the given address reference replaced with the contents of that address.\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {string} s\n * @param {string} sAddr\n * @return {string}\n */\n parseAddrReference(s, sAddr)\n {\n return s.replace('[' + sAddr + ']', \"unimplemented\");\n }\n\n /**\n * getNextCommand()\n *\n * @this {Debugger}\n * @return {string}\n */\n getNextCommand()\n {\n var sCmd;\n if (this.iPrevCmd > 0) {\n sCmd = this.aPrevCmds[--this.iPrevCmd];\n } else {\n sCmd = \"\";\n this.iPrevCmd = -1;\n }\n return sCmd;\n }\n\n /**\n * getPrevCommand()\n *\n * @this {Debugger}\n * @return {string|null}\n */\n getPrevCommand()\n {\n var sCmd = null;\n if (this.iPrevCmd < this.aPrevCmds.length - 1) {\n sCmd = this.aPrevCmds[++this.iPrevCmd];\n }\n return sCmd;\n }\n\n /**\n * parseCommand(sCmd, fSave, chSep)\n *\n * @this {Debugger}\n * @param {string|undefined} sCmd\n * @param {boolean} [fSave] is true to save the command, false if not\n * @param {string} [chSep] is the command separator character (default is ';')\n * @return {Array.<string>}\n */\n parseCommand(sCmd, fSave, chSep)\n {\n if (fSave) {\n if (!sCmd) {\n if (this.fAssemble) {\n sCmd = \"end\";\n } else {\n sCmd = this.aPrevCmds[this.iPrevCmd+1];\n }\n } else {\n if (this.iPrevCmd < 0 && this.aPrevCmds.length) {\n this.iPrevCmd = 0;\n }\n if (this.iPrevCmd < 0 || sCmd != this.aPrevCmds[this.iPrevCmd]) {\n this.aPrevCmds.splice(0, 0, sCmd);\n this.iPrevCmd = 0;\n }\n this.iPrevCmd--;\n }\n }\n var a = [];\n if (sCmd) {\n /*\n * With the introduction of breakpoint commands (ie, quoted command sequences\n * associated with a breakpoint), we can no longer perform simplistic splitting.\n *\n * a = sCmd.split(chSep || ';');\n * for (var i = 0; i < a.length; i++) a[i] = Str.trim(a[i]);\n *\n * We may now split on semi-colons ONLY if they are outside a quoted sequence.\n *\n * Also, to allow quoted strings *inside* breakpoint commands, we first replace all\n * DOUBLE double-quotes with single quotes.\n */\n sCmd = sCmd.replace(/\"\"/g, \"'\");\n\n var iPrev = 0;\n var chQuote = null;\n chSep = chSep || ';';\n /*\n * NOTE: Processing charAt() up to and INCLUDING length is not a typo; we're taking\n * advantage of the fact that charAt() with an invalid index returns an empty string,\n * allowing us to use the same substring() call to capture the final portion of sCmd.\n *\n * In a sense, it allows us to pretend that the string ends with a zero terminator.\n */\n for (var i = 0; i <= sCmd.length; i++) {\n var ch = sCmd.charAt(i);\n if (ch == '\"' || ch == \"'\") {\n if (!chQuote) {\n chQuote = ch;\n } else if (ch == chQuote) {\n chQuote = null;\n }\n }\n else if (ch == chSep && !chQuote || !ch) {\n /*\n * Recall that substring() accepts starting (inclusive) and ending (exclusive)\n * indexes, whereas substr() accepts a starting index and a length. We need the former.\n */\n a.push(Str.trim(sCmd.substring(iPrev, i)));\n iPrev = i + 1;\n }\n }\n }\n return a;\n }\n\n /**\n * evalAND(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.AND().\n *\n * Performs the bitwise \"and\" (AND) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst & src)\n */\n evalAND(dst, src)\n {\n /*\n * We AND the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 AND 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst & src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) & ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst & src) >>> 0);\n }\n\n /**\n * evalIOR(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.IOR().\n *\n * Performs the logical \"inclusive-or\" (OR) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst | src)\n */\n evalIOR(dst, src)\n {\n /*\n * We OR the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 OR 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst | src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) | ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst | src) >>> 0);\n }\n\n /**\n * evalXOR(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.XOR().\n *\n * Performs the logical \"exclusive-or\" (XOR) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst ^ src)\n */\n evalXOR(dst, src)\n {\n /*\n * We XOR the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 XOR 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst | src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) ^ ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst ^ src) >>> 0);\n }\n\n /**\n * evalMUL(dst, src)\n *\n * I could have adapted the code from /modules/pdp10/lib/cpuops.js:PDP10.doMUL(), but it was simpler to\n * write this base method and let the PDP-10 Debugger override it with a call to the *actual* doMUL() method.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst * src)\n */\n evalMUL(dst, src)\n {\n return dst * src;\n }\n\n /**\n * truncate(v, nBits, fUnsigned)\n *\n * @this {Debugger}\n * @param {number} v\n * @param {number} [nBits]\n * @param {boolean} [fUnsigned]\n * @return {number}\n */\n truncate(v, nBits, fUnsigned)\n {\n var limit, vNew = v;\n nBits = nBits || this.nBits;\n\n if (fUnsigned) {\n if (nBits == 32) {\n vNew = v >>> 0;\n }\n else if (nBits < 32) {\n vNew = v & ((1 << nBits) - 1);\n }\n else {\n limit = Math.pow(2, nBits);\n if (v < 0 || v >= limit) {\n vNew = v % limit;\n if (vNew < 0) vNew += limit;\n }\n }\n }\n else {\n if (nBits <= 32) {\n vNew = (v << (32 - nBits)) >> (32 - nBits);\n }\n else {\n limit = Math.pow(2, nBits - 1);\n if (v >= limit) {\n vNew = (v % limit);\n if (((v / limit)|0) & 1) vNew -= limit;\n } else if (v < -limit) {\n vNew = (v % limit);\n if ((((-v - 1) / limit) | 0) & 1) {\n if (vNew) vNew += limit;\n }\n else {\n if (!vNew) vNew -= limit;\n }\n }\n }\n }\n if (v != vNew) {\n if (MAXDEBUG) this.println(\"warning: value \" + v + \" truncated to \" + vNew);\n v = vNew;\n }\n return v;\n }\n\n /**\n * evalOps(aVals, aOps, cOps)\n *\n * Some of our clients want a specific number of bits of integer precision. If that precision is\n * greater than 32, some of the operations below will fail; for example, JavaScript bitwise operators\n * always truncate the result to 32 bits, so beware when using shift operations. Similarly, it would\n * be wrong to always \"|0\" the final result, which is why we rely on truncate() now.\n *\n * Note that JavaScript integer precision is limited to 52 bits. For example, in Node, if you set a\n * variable to 0x80000001:\n *\n * foo=0x80000001|0\n *\n * then calculate foo*foo and display the result in binary using \"(foo*foo).toString(2)\":\n *\n * '11111111111111111111111111111100000000000000000000000000000000'\n *\n * which is slightly incorrect because it has overflowed JavaScript's floating-point precision.\n *\n * 0x80000001 in decimal is -2147483647, so the product is 4611686014132420609, which is 0x3FFFFFFF00000001.\n *\n * @this {Debugger}\n * @param {Array.<number>} aVals\n * @param {Array.<string>} aOps\n * @param {number} [cOps] (default is -1 for all)\n * @return {boolean} true if successful, false if error\n */\n evalOps(aVals, aOps, cOps = -1)\n {\n while (cOps-- && aOps.length) {\n var chOp = aOps.pop();\n if (aVals.length < 2) return false;\n var valNew;\n var val2 = aVals.pop();\n var val1 = aVals.pop();\n switch(chOp) {\n case '*':\n valNew = this.evalMUL(val1, val2);\n break;\n case '/':\n if (!val2) return false;\n valNew = Math.trunc(val1 / val2);\n break;\n case '^/':\n if (!val2) return false;\n valNew = val1 % val2;\n break;\n case '+':\n valNew = val1 + val2;\n break;\n case '-':\n valNew = val1 - val2;\n break;\n case '<<':\n valNew = val1 << val2;\n break;\n case '>>':\n valNew = val1 >> val2;\n break;\n case '>>>':\n valNew = val1 >>> val2;\n break;\n case '<':\n valNew = (val1 < val2? 1 : 0);\n break;\n case '<=':\n valNew = (val1 <= val2? 1 : 0);\n break;\n case '>':\n valNew = (val1 > val2? 1 : 0);\n break;\n case '>=':\n valNew = (val1 >= val2? 1 : 0);\n break;\n case '==':\n valNew = (val1 == val2? 1 : 0);\n break;\n case '!=':\n valNew = (val1 != val2? 1 : 0);\n break;\n case '&':\n valNew = this.evalAND(val1, val2);\n break;\n case '!': // alias for MACRO-10 to perform a bitwise inclusive-or (OR)\n case '|':\n valNew = this.evalIOR(val1, val2);\n break;\n case '^!': // since MACRO-10 uses '^' for base overrides, '^!' is used for bitwise exclusive-or (XOR)\n valNew = this.evalXOR(val1, val2);\n break;\n case '&&':\n valNew = (val1 && val2? 1 : 0);\n break;\n case '||':\n valNew = (val1 || val2? 1 : 0);\n break;\n case ',,':\n valNew = this.truncate(val1, 18, true) * Math.pow(2, 18) + this.truncate(val2, 18, true);\n break;\n case '_':\n case '^_':\n valNew = val1;\n /*\n * While we always try to avoid assuming any particular number of bits of precision, the 'B' shift\n * operator (which we've converted to '^_') is unique to the MACRO-10 environment, which imposes the\n * following restrictions on the shift count.\n */\n if (chOp == '^_') val2 = 35 - (val2 & 0xff);\n if (val2) {\n /*\n * Since binary shifting is a logical (not arithmetic) operation, and since shifting by division only\n * works properly with positive numbers, we call truncate() to produce an unsigned value.\n */\n valNew = this.truncate(valNew, 0, true);\n if (val2 > 0) {\n valNew *= Math.pow(2, val2);\n } else {\n valNew = Math.trunc(valNew / Math.pow(2, -val2));\n }\n }\n break;\n default:\n return false;\n }\n aVals.push(this.truncate(valNew));\n }\n return true;\n }\n\n /**\n * parseArray(asValues, iValue, iLimit, nBase, aUndefined)\n *\n * parseExpression() takes a complete expression and divides it into array elements, where even elements\n * are values (which may be empty if two or more operators appear consecutively) and odd elements are operators.\n *\n * For example, if the original expression was \"2*{3+{4/2}}\", parseExpression() would call parseArray() with:\n *\n * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14\n * - - - - - - - - - - -- -- -- -- --\n * 2 * { 3 + { 4 / 2 } }\n *\n * This function takes care of recursively processing grouped expressions, by processing subsets of the array,\n * as well as handling certain base overrides (eg, temporarily switching to base-10 for binary shift suffixes).\n *\n * @param {Array.<string>} asValues\n * @param {number} iValue\n * @param {number} iLimit\n * @param {number} nBase\n * @param {Array|undefined} [aUndefined]\n * @return {number|undefined}\n */\n parseArray(asValues, iValue, iLimit, nBase, aUndefined)\n {\n var value;\n var sValue, sOp;\n var fError = false;\n var nUnary = 0;\n var aVals = [], aOps = [];\n\n var nBasePrev = this.nBase;\n this.nBase = nBase;\n\n while (iValue < iLimit) {\n var v;\n sValue = asValues[iValue++].trim();\n sOp = (iValue < iLimit? asValues[iValue++] : \"\");\n\n if (sValue) {\n v = this.parseValue(sValue, null, aUndefined, nUnary);\n } else {\n if (sOp == '{') {\n var cOpen = 1;\n var iStart = iValue;\n while (iValue < iLimit) {\n sValue = asValues[iValue++].trim();\n sOp = (iValue < asValues.length? asValues[iValue++] : \"\");\n if (sOp == '{') {\n cOpen++;\n } else if (sOp == '}') {\n if (!--cOpen) break;\n }\n }\n v = this.parseArray(asValues, iStart, iValue-1, this.nBase, aUndefined);\n if (v != null && nUnary) {\n v = this.parseUnary(v, nUnary);\n }\n sValue = (iValue < iLimit? asValues[iValue++].trim() : \"\");\n sOp = (iValue < iLimit? asValues[iValue++] : \"\");\n }\n else {\n /*\n * When parseExpression() calls us, it has collapsed all runs of whitespace into single spaces,\n * and although it allows single spaces to divide the elements of the expression, a space is neither\n * a unary nor binary operator. It's essentially a no-op. If we encounter it here, then it followed\n * another operator and is easily ignored (although perhaps it should still trigger a reset of nBase\n * and nUnary -- TBD).\n */\n if (sOp == ' ') {\n continue;\n }\n if (sOp == '^B') {\n this.nBase = 2;\n continue;\n }\n if (sOp == '^O') {\n this.nBase = 8;\n continue;\n }\n if (sOp == '^D') {\n this.nBase = 10;\n continue;\n }\n if (!(nUnary & (0xC0000000|0))) {\n if (sOp == '+') {\n continue;\n }\n if (sOp == '-') {\n nUnary = (nUnary << 2) | 1;\n continue;\n }\n if (sOp == '~' || sOp == '^-') {\n nUnary = (nUnary << 2) | 2;\n continue;\n }\n if (sOp == '^L') {\n nUnary = (nUnary << 2) | 3;\n continue;\n }\n }\n fError = true;\n break;\n }\n }\n\n if (v === undefined) {\n if (aUndefined) {\n aUndefined.push(sValue);\n v = 0;\n } else {\n fError = true;\n aUndefined = [];\n break;\n }\n }\n\n aVals.push(this.truncate(v));\n\n /*\n * When parseExpression() calls us, it has collapsed all runs of whitespace into single spaces,\n * and although it allows single spaces to divide the elements of the expression, a space is neither\n * a unary nor binary operator. It's essentially a no-op. If we encounter it here, then it followed\n * a value, and since we don't want to misinterpret the next operator as a unary operator, we look\n * ahead and grab the next operator if it's not preceded by a value.\n */\n if (sOp == ' ') {\n if (iValue < asValues.length - 1 && !asValues[iValue]) {\n iValue++;\n sOp = asValues[iValue++]\n } else {\n fError = true;\n break;\n }\n }\n\n if (!sOp) break;\n\n var aBinOp = (this.achGroup[0] == '<'? Debugger.aDECOpPrecedence : Debugger.aBinOpPrecedence);\n if (!aBinOp[sOp]) {\n fError = true;\n break;\n }\n if (aOps.length && aBinOp[sOp] <= aBinOp[aOps[aOps.length - 1]]) {\n this.evalOps(aVals, aOps, 1);\n }\n aOps.push(sOp);\n\n /*\n * The MACRO-10 binary shifting operator assumes a base-10 shift count, regardless of the current\n * base, so we must override the current base to ensure the count is parsed correctly.\n */\n this.nBase = (sOp == '^_')? 10 : nBase;\n nUnary = 0;\n }\n\n if (fError || !this.evalOps(aVals, aOps) || aVals.length != 1) {\n fError = true;\n }\n\n if (!fError) {\n value = aVals.pop();\n\n } else if (!aUndefined) {\n this.println(\"parse error (\" + (sValue || sOp) + \")\");\n }\n\n this.nBase = nBasePrev;\n return value;\n }\n\n /**\n * parseASCII(sExp, chDelim, nBits, cchMax)\n *\n * @this {Debugger}\n * @param {string} sExp\n * @param {string} chDelim\n * @param {number} nBits\n * @param {number} cchMax\n * @return {string|undefined}\n */\n parseASCII(sExp, chDelim, nBits, cchMax)\n {\n var i;\n while ((i = sExp.indexOf(chDelim)) >= 0) {\n var v = 0;\n var j = i + 1;\n var cch = cchMax;\n while (j < sExp.length) {\n var ch = sExp[j++];\n if (ch == chDelim) {\n cch = -1;\n break;\n }\n if (!cch) break;\n cch--;\n var c = ch.charCodeAt(0);\n if (nBits == 7) {\n c &= 0x7F;\n } else {\n c = (c - 0x20) & 0x3F;\n }\n v = this.truncate(v * Math.pow(2, nBits) + c, nBits * cchMax, true);\n }\n if (cch >= 0) {\n this.println(\"parse error (\" + chDelim + sExp + chDelim + \")\");\n return undefined;\n } else {\n sExp = sExp.substr(0, i) + this.toStrBase(v, -1) + sExp.substr(j);\n }\n }\n return sExp;\n }\n\n /**\n * parseExpression(sExp, fQuiet)\n *\n * A quick-and-dirty expression parser. It takes an expression like:\n *\n * EDX+EDX*4+12345678\n *\n * and builds a value stack in aVals and a \"binop\" (binary operator) stack in aOps:\n *\n * aVals aOps\n * ----- ----\n * EDX +\n * EDX *\n * 4 +\n * ...\n *\n * We pop 1 \"binop\" from aOps and 2 values from aVals whenever a \"binop\" of lower priority than its\n * predecessor is encountered, evaluate, and push the result back onto aVals. Only selected unary\n * operators are supported (eg, negate and complement); no ternary operators like '?:' are supported.\n *\n * fQuiet can be used to pass an array that collects any undefined variables that parseExpression()\n * encounters; the value of an undefined variable is zero. This mode was added for components that need\n * to support expressions containing \"fixups\" (ie, values that must be determined later).\n *\n * @this {Debugger}\n * @param {string|undefined} sExp\n * @param {Array|undefined|boolean} [fQuiet]\n * @return {number|undefined} numeric value, or undefined if sExp contains any undefined or invalid values\n */\n parseExpression(sExp, fQuiet)\n {\n var value = undefined;\n var fPrint = (fQuiet === false);\n var aUndefined = Array.isArray(fQuiet)? fQuiet : undefined;\n\n if (sExp) {\n\n /*\n * The default delimiting characters for grouped expressions are braces; they can be changed by altering\n * achGroup, but when that happens, instead of changing our regular expressions and operator tables,\n * we simply replace all achGroup characters with braces in the given expression.\n *\n * Why not use parentheses for grouped expressions? Because some debuggers use parseReference() to perform\n * parenthetical value replacements in message strings, and they don't want parentheses taking on a different\n * meaning. And for some machines, like the PDP-10, the convention is to use parentheses for other things,\n * like indexed addressing, and to use angle brackets for grouped expressions.\n */\n if (this.achGroup[0] != '{') {\n sExp = sExp.split(this.achGroup[0]).join('{').split(this.achGroup[1]).join('}');\n }\n\n /*\n * Quoted ASCII characters can have a numeric value, too, which must be converted now, to avoid any\n * conflicts with the operators below.\n */\n sExp = this.parseASCII(sExp, '\"', 7, 5); // MACRO-10 packs up to 5 7-bit ASCII codes into a value\n if (!sExp) return value;\n sExp = this.parseASCII(sExp, \"'\", 6, 6); // MACRO-10 packs up to 6 6-bit ASCII (SIXBIT) codes into a value\n if (!sExp) return value;\n\n /*\n * All browsers (including, I believe, IE9 and up) support the following idiosyncrasy of a RegExp split():\n * when the RegExp uses a capturing pattern, the resulting array will include entries for all the pattern\n * matches along with the non-matches. This effectively means that, in the set of expressions that we\n * support, all even entries in asValues will contain \"values\" and all odd entries will contain \"operators\".\n *\n * Although I started listing the operators in the RegExp in \"precedential\" order, that's not important;\n * what IS important is listing operators than contain shorter operators first. For example, bitwise\n * shift operators must be listed BEFORE the logical less-than or greater-than operators. The aBinOp tables\n * (aBinOpPrecedence and aDECOpPrecedence) are what determine precedence, not the RegExp.\n *\n * Also, to better accommodate MACRO-10 syntax, I've replaced the single '^' for XOR with '^!', and I've\n * added '!' as an alias for '|' (bitwise inclusive-or), '^-' as an alias for '~' (one's complement operator),\n * and '_' as a shift operator (+/- values specify a left/right shift, and the count is not limited to 32).\n *\n * And to avoid conflicts with MACRO-10 syntax, I've replaced the original mod operator ('%') with '^/'.\n *\n * The MACRO-10 binary shifting suffix ('B') is a bit more problematic, since a capital B can also appear\n * inside symbols, or inside hex values. So if the default base is NOT 16, then I pre-scan for that suffix\n * and replace all non-symbolic occurrences with an internal shift operator ('^_').\n *\n * Note that Str.parseInt(), which parseValue() relies on, supports both the MACRO-10 base prefix overrides\n * and the binary shifting suffix ('B'), but since that suffix can also be a bracketed expression, we have to\n * support it here as well.\n *\n * MACRO-10 supports only a subset of all the PCjs operators; for example, MACRO-10 doesn't support any of\n * the boolean logical/compare operators. But unless we run into conflicts, I prefer sticking with this\n * common set of operators.\n *\n * All whitespace in the expression is collapsed to single spaces, and space has been added to the list\n * of \"operators\", but its sole function is as a separator, not as an operator. parseArray() will ignore\n * single spaces as long as they are preceded and/or followed by a \"real\" operator. It would be dangerous\n * to remove spaces entirely, because if an operator-less expression like \"A B\" was passed in, we would want\n * that to generate an error; if we converted it to \"AB\", evaluation might inadvertently succeed.\n */\n var regExp = /({|}|\\|\\||&&|\\||\\^!|\\^B|\\^O|\\^D|\\^L|\\^-|~|\\^_|_|&|!=|!|==|>=|>>>|>>|>|<=|<<|<|-|\\+|\\^\\/|\\/|\\*|,,| )/;\n if (this.nBase != 16) {\n sExp = sExp.replace(/(^|[^A-Z0-9$%.])([0-9]+)B/, \"$1$2^_\").replace(/\\s+/g, ' ');\n }\n var asValues = sExp.split(regExp);\n value = this.parseArray(asValues, 0, asValues.length, this.nBase, aUndefined);\n if (value !== undefined && fPrint) {\n this.printValue(null, value);\n }\n }\n return value;\n }\n\n /**\n * parseReference(s)\n *\n * Returns the given string with any \"{expression}\" sequences replaced with the value of the expression,\n * and any \"[address]\" references replaced with the contents of the address. Expressions are parsed BEFORE\n * addresses.\n *\n * @this {Debugger}\n * @param {string} s\n * @return {string|undefined}\n */\n parseReference(s)\n {\n var a;\n var chOpen = this.achGroup[0];\n var chClose = this.achGroup[1];\n var chEscape = (chOpen == '(' || chOpen == '{' || chOpen == '[')? '\\\\' : '';\n var chInnerEscape = (chOpen == '['? '\\\\' : '');\n var reSubExp = new RegExp(chEscape + chOpen + \"([^\" + chInnerEscape + chOpen + chInnerEscape + chClose + \"]+)\" + chEscape + chClose);\n while (a = s.match(reSubExp)) {\n var value = this.parseExpression(a[1]);\n if (value === undefined) return undefined;\n var sSearch = chOpen + a[1] + chClose;\n var sReplace = value != null? this.toStrBase(value) : \"undefined\";\n /*\n * Note that by default, the String replace() method only replaces the FIRST occurrence,\n * and there MIGHT be more than one occurrence of the expression we just parsed, so we could\n * do this instead:\n *\n * s = s.split(sSearch).join(sReplace);\n *\n * However, that's knd of an expensive (slow) solution, and it's not strictly necessary, since\n * any additional identical expressions will be picked up on a subsequent iteration through this loop.\n */\n s = s.replace(sSearch, sReplace);\n }\n if (this.achAddress.length) {\n chOpen = this.achAddress[0];\n chClose = this.achAddress[1];\n chEscape = (chOpen == '(' || chOpen == '{' || chOpen == '[')? '\\\\' : '';\n chInnerEscape = (chOpen == '['? '\\\\' : '');\n reSubExp = new RegExp(chEscape + chOpen + \"([^\" + chInnerEscape + chOpen + chInnerEscape + chClose + \"]+)\" + chEscape + chClose);\n while (a = s.match(reSubExp)) {\n s = this.parseAddrReference(s, a[1]);\n }\n }\n return this.parseSysVars(s);\n }\n\n /**\n * parseSysVars(s)\n *\n * Returns the given string with any recognized \"$var\" replaced with its value; eg:\n *\n * $ops: the number of opcodes executed since the last time it was displayed (or reset)\n *\n * @this {Debugger}\n * @param {string} s\n * @return {string}\n */\n parseSysVars(s)\n {\n var a;\n while (a = s.match(/\\$([a-z]+)/i)) {\n var v = null;\n switch(a[1].toLowerCase()) {\n case \"ops\":\n v = this.cOpcodes - this.cOpcodesStart;\n break;\n }\n if (v == null) break;\n s = s.replace(a[0], v.toString());\n }\n return s;\n }\n\n /**\n * parseUnary(value, nUnary)\n *\n * nUnary is actually a small \"stack\" of unary operations encoded in successive pairs of bits.\n * As parseExpression() encounters each unary operator, nUnary is shifted left 2 bits, and the\n * new unary operator is encoded in bits 0 and 1 (0b00 is none, 0b01 is negate, 0b10 is complement,\n * and 0b11 is reserved). Here, we process the bits in reverse order (hence the stack-like nature),\n * ensuring that we process the unary operators associated with this value right-to-left.\n *\n * Since bitwise operators see only 32 bits, more than 16 unary operators cannot be supported\n * using this method. We'll let parseExpression() worry about that; if it ever happens in practice,\n * then we'll have to switch to a more \"expensive\" approach (eg, an actual array of unary operators).\n *\n * @this {Debugger}\n * @param {number} value\n * @param {number} nUnary\n * @return {number}\n */\n parseUnary(value, nUnary)\n {\n while (nUnary) {\n switch(nUnary & 0o3) {\n case 1:\n value = -this.truncate(value);\n break;\n case 2:\n value = this.evalXOR(value, -1); // this is easier than adding an evalNOT()...\n break;\n case 3:\n var bit = 35; // simple left-to-right zero-bit-counting loop...\n while (bit >= 0 && !this.evalAND(value, Math.pow(2, bit))) bit--;\n value = 35 - bit;\n break;\n }\n nUnary >>>= 2;\n }\n return value;\n }\n\n /**\n * parseValue(sValue, sName, fQuiet, nUnary)\n *\n * @this {Debugger}\n * @param {string|undefined} sValue\n * @param {string|null|*} [sName] is the name of the value, if any\n * @param {Array|undefined|boolean} [fQuiet]\n * @param {number} [nUnary] (0 for none, 1 for negate, 2 for complement, 3 for leading zeros)\n * @return {number|undefined} numeric value, or undefined if sValue is either undefined or invalid\n */\n parseValue(sValue, sName, fQuiet, nUnary = 0)\n {\n var value;\n var aUndefined = Array.isArray(fQuiet)? fQuiet : undefined;\n\n if (sValue != null) {\n var iReg = this.getRegIndex(sValue);\n if (iReg >= 0) {\n value = this.getRegValue(iReg);\n } else {\n value = this.getVariable(sValue);\n if (value != null) {\n var sUndefined = this.getVariableFixup(sValue);\n if (sUndefined) {\n if (aUndefined) {\n aUndefined.push(sUndefined);\n } else {\n var valueUndefined = this.parseExpression(sUndefined, fQuiet);\n if (valueUndefined !== undefined) {\n value += valueUndefined;\n } else {\n if (!fQuiet) {\n this.println(\"undefined \" + (sName || \"value\") + \": \" + sValue + \" (\" + sUndefined + \")\");\n }\n value = undefined;\n }\n }\n }\n } else {\n /*\n * A feature of MACRO-10 is that any single-digit number is automatically interpreted as base-10.\n */\n value = Str.parseInt(sValue, sValue.length > 1 || this.nBase > 10? this.nBase : 10);\n }\n }\n if (value != null) {\n value = this.truncate(this.parseUnary(value, nUnary));\n } else {\n if (!fQuiet) {\n this.println(\"invalid \" + (sName || \"value\") + \": \" + sValue);\n }\n }\n } else {\n if (!fQuiet) {\n this.println(\"missing \" + (sName || \"value\"));\n }\n }\n return value;\n }\n\n /**\n * printValue(sVar, value)\n *\n * @this {Debugger}\n * @param {string|null} sVar\n * @param {number|undefined} value\n * @return {boolean} true if value defined, false if not\n */\n printValue(sVar, value)\n {\n var sValue;\n var fDefined = false;\n if (value !== undefined) {\n fDefined = true;\n if (this.nBase == 8) {\n sValue = this.toStrBase(value, this.nBits, 8, 1) + \" \" + value + '.';\n } else {\n sValue = this.toStrBase(value, this.nBits, 16, 1) + \" \" + this.toStrBase(value, this.nBits, 8, 1) + \" \" + this.toStrBase(value, this.nBits, 2, this.nBits <= 32? 8 : 6) + \" \" + value + '.';\n }\n if (value >= 0x20 && value < 0x7F) {\n sValue += \" '\" + String.fromCharCode(value) + \"'\";\n }\n }\n sVar = (sVar != null? (sVar + \": \") : \"\");\n this.println(sVar + sValue);\n return fDefined;\n }\n\n /**\n * resetVariables()\n *\n * @this {Debugger}\n * @return {Object}\n */\n resetVariables()\n {\n var a = this.aVariables;\n this.aVariables = {};\n return a;\n }\n\n /**\n * restoreVariables(a)\n *\n * @this {Debugger}\n * @param {Object} a (from previous resetVariables() call)\n */\n restoreVariables(a)\n {\n this.aVariables = a;\n }\n\n /**\n * printVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} [sVar]\n * @return {boolean} true if all value(s) defined, false if not\n */\n printVariable(sVar)\n {\n var cVariables = 0;\n if (this.aVariables) {\n if (sVar) {\n return this.printValue(sVar, this.aVariables[sVar] && this.aVariables[sVar].value);\n }\n var aVars = Object.keys(this.aVariables);\n aVars.sort();\n for (var i = 0; i < aVars.length; i++) {\n this.printValue(aVars[i], this.aVariables[aVars[i]].value);\n cVariables++;\n }\n }\n return cVariables > 0;\n }\n\n /**\n * delVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n */\n delVariable(sVar)\n {\n delete this.aVariables[sVar];\n }\n\n /**\n * getVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {number|undefined}\n */\n getVariable(sVar)\n {\n if (this.aVariables[sVar]) {\n return this.aVariables[sVar].value;\n }\n sVar = sVar.substr(0, 6);\n return this.aVariables[sVar] && this.aVariables[sVar].value;\n }\n\n /**\n * getVariableFixup(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {string|undefined}\n */\n getVariableFixup(sVar)\n {\n return this.aVariables[sVar] && this.aVariables[sVar].sUndefined;\n }\n\n /**\n * isVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {boolean}\n */\n isVariable(sVar)\n {\n return this.aVariables[sVar] !== undefined;\n }\n\n /**\n * setVariable(sVar, value, sUndefined)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @param {number} value\n * @param {string|undefined} [sUndefined]\n */\n setVariable(sVar, value, sUndefined)\n {\n this.aVariables[sVar] = {value, sUndefined};\n }\n\n /**\n * toStrBase(n, nBits, nBase, nGrouping)\n *\n * Use this instead of Str's toOct()/toDec()/toHex() to convert numbers to the Debugger's default base.\n *\n * @this {Debugger}\n * @param {number|null|undefined} n\n * @param {number} [nBits] (-1 to strip leading zeros, 0 to allow a variable number of digits)\n * @param {number} [nBase]\n * @param {number} [nGrouping] (if nBase is 2, this is a grouping; otherwise, it's a prefix condition)\n * @return {string}\n */\n toStrBase(n, nBits = 0, nBase = 0, nGrouping = 0)\n {\n var s;\n switch(nBase || this.nBase) {\n case 2:\n s = Str.toBin(n, nBits > 0? nBits : 0, nGrouping);\n break;\n case 8:\n s = Str.toOct(n, nBits > 0? ((nBits + 2)/3)|0 : 0, !!nGrouping);\n break;\n case 10:\n /*\n * The multiplier is actually Math.log(2)/Math.log(10), but an approximation is more than adequate.\n */\n s = Str.toDec(n, nBits > 0? Math.ceil(nBits * 0.3) : 0);\n break;\n case 16:\n default:\n s = Str.toHex(n, nBits > 0? ((nBits + 3) >> 2) : 0, !!nGrouping);\n break;\n }\n return (nBits < 0? Str.stripLeadingZeros(s) : s);\n }\n}\n\nif (DEBUGGER) {\n\n /*\n * These are our operator precedence tables. Operators toward the bottom (with higher values) have\n * higher precedence. aBinOpPrecedence was our original table; we had to add aDECOpPrecedence because\n * the precedence of operators in DEC's MACRO-10 expressions differ. Having separate tables also allows\n * us to remove operators that shouldn't be supported, but unless some operator creates a problem,\n * I prefer to keep as much commonality between the tables as possible.\n *\n * Missing from these tables are the (limited) set of unary operators we support (negate and complement),\n * since this is only a BINARY operator precedence, not a general-purpose precedence table. Assume that\n * all unary operators take precedence over all binary operators.\n */\n Debugger.aBinOpPrecedence = {\n '||': 5, // logical OR\n '&&': 6, // logical AND\n '!': 7, // bitwise OR (conflicts with logical NOT, but we never supported that)\n '|': 7, // bitwise OR\n '^!': 8, // bitwise XOR (added by MACRO-10 sometime between the 1972 and 1978 versions)\n '&': 9, // bitwise AND\n '!=': 10, // inequality\n '==': 10, // equality\n '>=': 11, // greater than or equal to\n '>': 11, // greater than\n '<=': 11, // less than or equal to\n '<': 11, // less than\n '>>>': 12, // unsigned bitwise right shift\n '>>': 12, // bitwise right shift\n '<<': 12, // bitwise left shift\n '-': 13, // subtraction\n '+': 13, // addition\n '^/': 14, // remainder\n '/': 14, // division\n '*': 14, // multiplication\n '_': 19, // MACRO-10 shift operator\n '^_': 19, // MACRO-10 internal shift operator (converted from 'B' suffix form that MACRO-10 uses)\n '{': 20, // open grouped expression (converted from achGroup[0])\n '}': 20 // close grouped expression (converted from achGroup[1])\n };\n Debugger.aDECOpPrecedence = {\n ',,': 1, // high-word,,low-word\n '||': 5, // logical OR\n '&&': 6, // logical AND\n '!=': 10, // inequality\n '==': 10, // equality\n '>=': 11, // greater than or equal to\n '>': 11, // greater than\n '<=': 11, // less than or equal to\n '<': 11, // less than\n '>>>': 12, // unsigned bitwise right shift\n '>>': 12, // bitwise right shift\n '<<': 12, // bitwise left shift\n '-': 13, // subtraction\n '+': 13, // addition\n '^/': 14, // remainder\n '/': 14, // division\n '*': 14, // multiplication\n '!': 15, // bitwise OR (conflicts with logical NOT, but we never supported that)\n '|': 15, // bitwise OR\n '^!': 15, // bitwise XOR (added by MACRO-10 sometime between the 1972 and 1978 versions)\n '&': 15, // bitwise AND\n '_': 19, // MACRO-10 shift operator\n '^_': 19, // MACRO-10 internal shift operator (converted from 'B' suffix form that MACRO-10 uses)\n '{': 20, // open grouped expression (converted from achGroup[0])\n '}': 20 // close grouped expression (converted from achGroup[1])\n };\n\n /*\n * Assorted constants\n */\n Debugger.TWO_POW32 = Math.pow(2, 32);\n\n} // endif DEBUGGER\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/debugger.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * DebuggerPDP10 Address Object\n *\n * addr address\n * fPhysical true if this is a physical address\n * fTemporary true if this is a temporary breakpoint address\n * nBase set if the address contained an explicit base (eg, 16, 10, 8, etc)\n * sCmd set for breakpoint addresses if there's an associated command string\n * aCmds preprocessed commands (from sCmd)\n *\n * @typedef {{\n * addr:(number|null),\n * fPhysical:(boolean),\n * fTemporary:(boolean),\n * nBase:(number|undefined),\n * sCmd:(string|undefined),\n * aCmds:(Array.<string>|undefined)\n * }}\n */\nvar DbgAddrPDP10;\n\nclass DebuggerPDP10 extends Debugger {\n /**\n * DebuggerPDP10(parmsDbg)\n *\n * The DebuggerPDP10 component supports the following optional (parmsDbg) properties:\n *\n * commands: string containing zero or more commands, separated by ';'\n *\n * messages: string containing zero or more message categories to enable;\n * multiple categories must be separated by '|' or ';'. Parsed by messageInit().\n *\n * The DebuggerPDP10 component is an optional component that implements a variety of user\n * commands for controlling the CPU, dumping and editing memory, etc.\n *\n * @this {DebuggerPDP10}\n * @param {Object} parmsDbg\n */\n constructor(parmsDbg)\n {\n if (DEBUGGER) {\n\n super(parmsDbg);\n\n /*\n * Since this Debugger doesn't use replaceRegs(), we can use parentheses instead of braces.\n */\n this.fInit = false;\n this.nBusWidth = 18; // default value, updated by initBus()\n\n this.nBits = 36; // default integer precision\n this.achGroup = ['<','>'];\n this.achAddress = [];\n\n /*\n * Most commands that require an address call parseAddr(), and if a dbgAddr parameter is supplied\n * as as well (eg, dbgAddrCode, dbgAddrData), then that address will be used as the default.\n *\n * For TEMPORARY breakpoint addresses, we set fTemporary to true, so that they can be automatically\n * cleared when they're hit.\n */\n this.dbgAddrAcc = this.newAddr();\n this.dbgAddrCode = this.newAddr(0);\n this.dbgAddrData = this.newAddr(0);\n this.dbgAddrAssemble = this.newAddr(0);\n\n /*\n * aSymbolTable is an array of SymbolTable objects, one per ROM or other chunk of address space,\n * where each object contains the following properties:\n *\n * sModule\n * addr (physical address, if any; eg, symbols for a ROM)\n * len\n * aSymbols\n * aOffsets\n *\n * See addSymbols() for more details, since that's how callers add sets of symbols to the table.\n */\n this.aSymbolTable = [];\n\n /*\n * clearBreakpoints() initializes the breakpoints lists: aBreakExec is a list of addresses\n * to halt on whenever attempting to execute an instruction at the corresponding address,\n * and aBreakRead and aBreakWrite are lists of addresses to halt on whenever a read or write,\n * respectively, occurs at the corresponding address.\n *\n * NOTE: Curiously, after upgrading the Google Closure Compiler from v20141215 to v20150609,\n * the resulting compiled code would crash in clearBreakpoints(), because the (renamed) aBreakRead\n * property was already defined. To eliminate whatever was confusing the Closure Compiler, I've\n * explicitly initialized all the properties that clearBreakpoints() (re)initializes.\n */\n this.aBreakExec = this.aBreakRead = this.aBreakWrite = [];\n this.clearBreakpoints();\n\n /*\n * The new \"bn\" command allows you to specify a number of instructions to execute and then stop;\n * \"bn 0\" disables any outstanding count.\n */\n this.nBreakInstructions = 0;\n\n /*\n * Execution history is allocated by historyInit() whenever checksEnabled() conditions change.\n * Execution history is updated whenever the CPU calls checkInstruction(), which will happen\n * only when checksEnabled() returns true (eg, whenever one or more breakpoints have been set).\n * This ensures that, by default, the CPU runs as fast as possible.\n */\n this.iInstructionHistory = 0;\n this.aInstructionHistory = [];\n this.nextHistory = undefined;\n this.historyInit();\n\n /*\n * Initialize DebuggerPDP10 message support.\n */\n this.dbg = this;\n this.afnDumpers = {};\n this.bitsMessage = this.bitsWarning = 0;\n this.sMessagePrev = null;\n this.aMessageBuffer = [];\n this.messageInit(parmsDbg['messages']);\n this.sInitCommands = parmsDbg['commands'];\n this.aCommands = [];\n\n /*\n * Define remaining miscellaneous DebuggerPDP10 properties.\n */\n this.aOpReserved = [];\n this.nStep = 0;\n this.sCmdTracePrev = null;\n this.sCmdDumpPrev = null;\n this.nSuppressBreaks = 0;\n this.cInstructions = this.cInstructionsStart = 0;\n this.nCycles = this.nCyclesStart = this.msStart = 0;\n this.controlDebug = null;\n this.panel = null;\n\n /**\n * This records any active Macro10 assembler object.\n *\n * @type {Macro10|null}\n */\n this.macro10 = null;\n\n /*\n * Make it easier to access DebuggerPDP10 commands from an external REPL;\n * eg, the WebStorm \"live\" console window:\n *\n * pdp10('r')\n * pdp10('dw 0:0')\n * pdp10('h')\n * ...\n */\n var dbg = this;\n if (window) {\n if (window[PDP10.APPCLASS] === undefined) {\n window[PDP10.APPCLASS] = function(s) { return dbg.doCommands(s); };\n }\n } else {\n if (global[PDP10.APPCLASS] === undefined) {\n global[PDP10.APPCLASS] = function(s) { return dbg.doCommands(s); };\n }\n }\n\n } // endif DEBUGGER\n }\n\n /**\n * getAddr(dbgAddr, fWrite)\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10|null} [dbgAddr]\n * @param {boolean} [fWrite]\n * @return {number} is the corresponding linear address, or PDP10.ADDR_INVALID\n */\n getAddr(dbgAddr, fWrite)\n {\n var addr = dbgAddr && dbgAddr.addr;\n if (addr == null) addr = PDP10.ADDR_INVALID;\n return addr;\n }\n\n /**\n * newAddr(addr, fPhysical, nBase)\n *\n * Returns a NEW DbgAddrPDP10 object, initialized with specified values and/or defaults.\n *\n * @this {DebuggerPDP10}\n * @param {number|null} [addr]\n * @param {boolean} [fPhysical]\n * @param {number} [nBase]\n * @return {DbgAddrPDP10}\n */\n newAddr(addr = null, fPhysical = false, nBase)\n {\n return {addr: addr, fPhysical: fPhysical, fTemporary: false, nBase: nBase};\n }\n\n /**\n * copyAddr(dbgAddr, dbgCopy)\n *\n * Updates an EXISTING DbgAddrPDP10 object, initialized with specified values and/or defaults.\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @param {DbgAddrPDP10} dbgCopy\n * @return {DbgAddrPDP10}\n */\n copyAddr(dbgAddr, dbgCopy)\n {\n dbgAddr.addr = dbgCopy.addr;\n dbgAddr.fPhysical = dbgCopy.fPhysical;\n dbgAddr.fTemporary = dbgCopy.fTemporary;\n dbgAddr.nBase = dbgCopy.nBase;\n return dbgAddr;\n }\n\n /**\n * setAddr(dbgAddr, addr, fPhysical, nBase)\n *\n * Updates an EXISTING DbgAddrPDP10 object, initialized with specified values and/or defaults.\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @param {number} addr\n * @param {boolean} [fPhysical]\n * @param {number} [nBase]\n * @return {DbgAddrPDP10}\n */\n setAddr(dbgAddr, addr, fPhysical, nBase)\n {\n dbgAddr.addr = addr;\n dbgAddr.fPhysical = fPhysical || false;\n dbgAddr.fTemporary = false;\n dbgAddr.nBase = nBase;\n return dbgAddr;\n }\n\n /**\n * packAddr(dbgAddr)\n *\n * Packs a DbgAddrPDP10 object into an Array suitable for saving in a machine state object.\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @return {Array}\n */\n packAddr(dbgAddr)\n {\n return [dbgAddr.addr, dbgAddr.fPhysical, dbgAddr.fTemporary, dbgAddr.nBase, dbgAddr.sCmd];\n }\n\n /**\n * unpackAddr(aAddr)\n *\n * Unpacks a DbgAddrPDP10 object from an Array created by packAddr() and restored from a saved machine state.\n *\n * @this {DebuggerPDP10}\n * @param {Array} aAddr\n * @return {DbgAddrPDP10}\n */\n unpackAddr(aAddr)\n {\n var dbgAddr = this.newAddr(aAddr[0], aAddr[1], aAddr[2]);\n dbgAddr.fTemporary = aAddr[3];\n if (aAddr[4]) {\n dbgAddr.aCmds = this.parseCommand(dbgAddr.sCmd = aAddr[4]);\n }\n return dbgAddr;\n }\n\n /**\n * initBus(bus, cpu, dbg)\n *\n * @this {DebuggerPDP10}\n * @param {ComputerPDP10} cmp\n * @param {BusPDP10} bus\n * @param {CPUStatePDP10} cpu\n * @param {DebuggerPDP10} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cmp = cmp;\n this.cpu = cpu;\n this.panel = cmp.panel;\n this.nBusWidth = bus.getWidth();\n\n /*\n * Override the Debugger's message configuration if specified.\n */\n var sMessages = /** @type {string|undefined} */ (cmp.getMachineParm('messages'));\n if (sMessages) this.messageInit(sMessages);\n\n /*\n * Override the Debugger's initialization commands if specified.\n */\n var sCommands = /** @type {string|undefined} */ (cmp.getMachineParm('commands'));\n if (sCommands) this.sInitCommands = sCommands;\n\n /*\n * Update aOpReserved as appropriate for the current model\n */\n\n this.messageDump(MessagesPDP10.BUS, function onDumpBus(asArgs) { dbg.dumpBus(asArgs); });\n\n this.setReady();\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {DebuggerPDP10}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"debugInput\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var dbg = this;\n switch (sBinding) {\n\n case \"debugInput\":\n this.bindings[sBinding] = control;\n this.controlDebug = /** @type {HTMLInputElement} */ (control);\n /*\n * For halted machines, this is fine, but for auto-start machines, it can be annoying.\n *\n * control.focus();\n */\n control.onkeydown = function onKeyDownDebugInput(event) {\n var sCmd;\n if (event.keyCode == Keys.KEYCODE.CR) {\n sCmd = dbg.controlDebug.value;\n dbg.controlDebug.value = \"\";\n dbg.doCommands(sCmd, true);\n }\n else if (event.keyCode == Keys.KEYCODE.ESC) {\n dbg.controlDebug.value = sCmd = \"\";\n }\n else {\n if (event.keyCode == Keys.KEYCODE.UP) {\n sCmd = dbg.getPrevCommand();\n }\n else if (event.keyCode == Keys.KEYCODE.DOWN) {\n sCmd = dbg.getNextCommand();\n }\n if (sCmd != null) {\n var cch = sCmd.length;\n dbg.controlDebug.value = sCmd;\n dbg.controlDebug.setSelectionRange(cch, cch);\n }\n }\n if (sCmd != null && event.preventDefault) event.preventDefault();\n };\n return true;\n\n case \"debugEnter\":\n this.bindings[sBinding] = control;\n Web.onClickRepeat(\n control,\n 500, 100,\n function onClickDebugEnter(fRepeat) {\n if (dbg.controlDebug) {\n var sCmd = dbg.controlDebug.value;\n dbg.controlDebug.value = \"\";\n dbg.doCommands(sCmd, true);\n return true;\n }\n if (DEBUG) dbg.log(\"no debugger input buffer\");\n return false;\n }\n );\n return true;\n\n case \"step\":\n this.bindings[sBinding] = control;\n Web.onClickRepeat(\n control,\n 500, 100,\n function onClickStep(fRepeat) {\n var fCompleted = false;\n if (!dbg.isBusy(true)) {\n dbg.setBusy(true);\n fCompleted = dbg.stepCPU(fRepeat? 1 : 0, null);\n dbg.setBusy(false);\n }\n return fCompleted;\n }\n );\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * setFocus(fScroll)\n *\n * @this {DebuggerPDP10}\n * @param {boolean} [fScroll] (true if you really want the control scrolled into view)\n */\n setFocus(fScroll)\n {\n if (this.controlDebug) {\n /*\n * This is the recommended work-around to prevent the browser from scrolling the focused element\n * into view. The CPU is not a visual component, so when the CPU wants to set focus, the primary intent\n * is to ensure that keyboard input is fielded properly.\n */\n var x = 0, y = 0;\n if (!fScroll && window) {\n x = window.scrollX;\n y = window.scrollY;\n }\n\n this.controlDebug.focus();\n\n if (!fScroll && window) {\n window.scrollTo(x, y);\n }\n }\n }\n\n /**\n * getWord(dbgAddr, inc)\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @param {number} [inc]\n * @return {number}\n */\n getWord(dbgAddr, inc)\n {\n var w = PDP10.WORD_INVALID;\n var addr = this.getAddr(dbgAddr, false);\n if (addr !== PDP10.ADDR_INVALID) {\n w = this.bus.getWordDirect(addr);\n if (inc) this.incAddr(dbgAddr, inc);\n }\n return w;\n }\n\n /**\n * setWord(dbgAddr, w, inc)\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @param {number} w\n * @param {number} [inc]\n */\n setWord(dbgAddr, w, inc)\n {\n var addr = this.getAddr(dbgAddr, true);\n if (addr !== PDP10.ADDR_INVALID) {\n this.bus.setWordDirect(addr, w);\n if (inc) this.incAddr(dbgAddr, inc);\n this.cmp.updateDisplays(-1);\n }\n }\n\n /**\n * evalMUL(dst, src)\n *\n * Overrides the standard multiplication function with one that honors PDP-10 semantics and precision.\n *\n * @this {DebuggerPDP10}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst * src)\n */\n evalMUL(dst, src)\n {\n /*\n * The CPU requires that all 36-bit inputs/outputs be UNSIGNED, whereas our expression evaluator allows signed\n * inputs/outputs. So we perform two's complement conversions on all inputs/outputs as needed.\n */\n if (dst < 0) dst += PDP10.WORD_LIMIT;\n if (src < 0) src += PDP10.WORD_LIMIT;\n var result = PDP10.doMUL.call(this.cpu, dst, src, false, true);\n if (result >= PDP10.INT_LIMIT) result -= PDP10.WORD_LIMIT;\n if (MAXDEBUG) {\n var resultJS = this.truncate(dst * src);\n if (resultJS !== result) {\n var sReference = this.macro10? (\" @\" + this.toStrBase(this.macro10.nLocation)) : \"\";\n var sResults = \"PDP-10: \" + this.toStrBase(result, 36) + \" JavaScript: \" + this.toStrBase(resultJS, 36);\n this.println(\"MUL(\" + this.toStrBase(dst, 36) + \",\" + this.toStrBase(src, 36) + \") \" + sResults + sReference);\n }\n }\n return result;\n }\n\n /**\n * parseAddr(sAddr, dbgAddr)\n *\n * Address evaluation and validation (eg, range checks) are no longer performed at this stage. That's\n * done later, by getAddr(), which returns PDP10.ADDR_INVALID for invalid segments, out-of-range offsets,\n * etc. The Debugger's low-level get/set memory functions verify all getAddr() results, but even if an\n * invalid address is passed through to the Bus memory interfaces, the address will simply be masked with\n * bus.nBusMask; in the case of PDP10.ADDR_INVALID, that will generally refer to the top of the physical\n * address space.\n *\n * @this {DebuggerPDP10}\n * @param {string|undefined} sAddr\n * @param {DbgAddrPDP10} [dbgAddr]\n * @return {DbgAddrPDP10}\n */\n parseAddr(sAddr, dbgAddr)\n {\n var fPhysical, nBase;\n if (!dbgAddr) dbgAddr = this.newAddr();\n var addr = dbgAddr.addr;\n if (sAddr !== undefined) {\n sAddr = this.parseReference(sAddr);\n var ch = sAddr.charAt(0);\n if (ch == '%') {\n fPhysical = true;\n sAddr = sAddr.substr(1);\n }\n var dbgAddrTmp = this.findSymbolAddr(sAddr);\n if (dbgAddrTmp) return dbgAddrTmp;\n if (sAddr.indexOf(\"0x\") >= 0) {\n nBase = 16\n } else if (sAddr.indexOf(\"0o\") >= 0) {\n nBase = 8;\n } else if (sAddr.indexOf('.') >= 0) {\n nBase = 10;\n }\n addr = this.parseExpression(sAddr);\n }\n if (addr != null) {\n addr = this.validateWord(addr, this.nBusWidth);\n this.setAddr(dbgAddr, addr, fPhysical, nBase);\n }\n return dbgAddr;\n }\n\n /**\n * parseAddrOptions(dbdAddr, sOptions)\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @param {string} [sOptions]\n */\n parseAddrOptions(dbgAddr, sOptions)\n {\n if (sOptions) {\n var a = sOptions.match(/(['\"])(.*?)\\1/);\n if (a) {\n dbgAddr.aCmds = this.parseCommand(dbgAddr.sCmd = a[2]);\n }\n }\n }\n\n /**\n * validateWord(w, bits)\n *\n * @this {DebuggerPDP10}\n * @param {number} w\n * @param {number} [bits]\n * @return {number}\n */\n validateWord(w, bits = 36)\n {\n /*\n * Although it's expected that most callers will supply unsigned 36-bit values, we're nice about\n * converting any signed values to their unsigned (two's complement) counterpart, provided they are\n * within the acceptable range. Any values outside that range will be dealt with afterward.\n */\n if (w < 0 && w >= -PDP10.INT_LIMIT) {\n w += PDP10.WORD_LIMIT;\n }\n var value = Math.trunc(Math.abs(w)) % Math.pow(2, bits);\n if (DEBUG && w !== value) {\n this.println(\"validateWord(\" + Str.toOct(w) + \"): out of range, truncated to \" + Str.toOct(value));\n }\n return value;\n }\n\n /**\n * incAddr(dbgAddr, inc)\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @param {number} [inc] contains value to increment dbgAddr by (default is 1)\n */\n incAddr(dbgAddr, inc)\n {\n if (dbgAddr.addr != null) {\n dbgAddr.addr += (inc || 1);\n }\n }\n\n /**\n * toStrOffset(off)\n *\n * @this {DebuggerPDP10}\n * @param {number|null|undefined} [off]\n * @return {string} default base representation of off\n */\n toStrOffset(off)\n {\n return this.toStrBase(off, 18);\n }\n\n /**\n * toStrAddr(dbgAddr)\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @return {string} default base representation of the address\n */\n toStrAddr(dbgAddr)\n {\n return this.toStrOffset(dbgAddr.addr);\n }\n\n /**\n * toStrWord(w)\n *\n * @this {DebuggerPDP10}\n * @param {number} w (up to, but not including, WORD_LIMIT)\n * @return {string} octal representation of the 36-bit word, as two 18-bit values\n */\n toStrWord(w)\n {\n /*\n * ADDR_LIMIT is not derived from WORD_LIMIT; we're just taking advantage of the fact\n * that ADDR_LIMIT happens to be exactly half of WORD_LIMIT, and they are both powers of two.\n */\n return this.toStrBase(w / PDP10.ADDR_LIMIT, 18) + ' ' + this.toStrBase(w % PDP10.ADDR_LIMIT, 18);\n }\n\n /**\n * dumpBlocks(aBlocks, sAddr)\n *\n * @this {DebuggerPDP10}\n * @param {Array} aBlocks\n * @param {string} [sAddr] (optional block address)\n */\n dumpBlocks(aBlocks, sAddr)\n {\n var addr = 0, i = 0, n = aBlocks.length;\n\n if (sAddr) {\n addr = this.getAddr(this.parseAddr(sAddr, this.dbgAddrData));\n if (addr === PDP10.ADDR_INVALID) {\n this.println(\"invalid address: \" + sAddr);\n return;\n }\n i = addr >>> this.bus.nBlockShift;\n n = 1;\n }\n\n this.println(\"blockid physical blockaddr used size type\");\n this.println(\"-------- --------- --------- ------ ------ ----\");\n\n var typePrev = -1, cPrev = 0;\n while (n--) {\n var block = aBlocks[i];\n if (block.type == typePrev) {\n if (!cPrev++) this.println(\"...\");\n } else {\n typePrev = block.type;\n var sType = MemoryPDP10.TYPE_NAMES[typePrev];\n if (block) {\n this.println(Str.toHex(block.id, 8) + \" %\" + Str.toHex(i << this.bus.nBlockShift, 8) + \" %\" + Str.toHex(block.addr, 8) + \" \" + Str.toHexWord(block.used) + \" \" + Str.toHexWord(block.size) + \" \" + sType);\n }\n if (typePrev != MemoryPDP10.TYPE.NONE) typePrev = -1;\n cPrev = 0;\n }\n addr += this.bus.nBlockSize;\n i++;\n }\n }\n\n /**\n * dumpBus(asArgs)\n *\n * Dumps Bus allocations.\n *\n * @this {DebuggerPDP10}\n * @param {Array.<string>} asArgs (asArgs[0] is an optional block address)\n */\n dumpBus(asArgs)\n {\n this.dumpBlocks(this.bus.aBusBlocks, asArgs[0]);\n }\n\n /**\n * dumpHistory(sPrev, sLines)\n *\n * If sLines is not a number, it can be a instruction filter. However, for the moment, the only\n * supported filter is \"call\", which filters the history buffer for all CALL and RET instructions\n * from the specified previous point forward.\n *\n * @this {DebuggerPDP10}\n * @param {string} [sPrev] is a (decimal) number of instructions to rewind to (default is 10)\n * @param {string} [sLines] is a (decimal) number of instructions to print (default is, again, 10)\n */\n dumpHistory(sPrev, sLines)\n {\n var sMore = \"\";\n var cHistory = 0;\n var iHistory = this.iInstructionHistory;\n var aHistory = this.aInstructionHistory;\n\n if (aHistory.length) {\n var nPrev = +sPrev || this.nextHistory;\n var nLines = +sLines || 10;\n\n if (isNaN(nPrev)) {\n nPrev = nLines;\n } else {\n sMore = \"more \";\n }\n\n if (nPrev > aHistory.length) {\n this.println(\"note: only \" + aHistory.length + \" available\");\n nPrev = aHistory.length;\n }\n\n iHistory -= nPrev;\n if (iHistory < 0) {\n /*\n * If the dbgAddr of the last aHistory element contains a valid selector, wrap around.\n */\n if (aHistory[aHistory.length - 1].addr == null) {\n nPrev = iHistory + nPrev;\n iHistory = 0;\n } else {\n iHistory += aHistory.length;\n }\n }\n\n var aFilters = [];\n if (sLines == \"call\") {\n nLines = 100000;\n aFilters = [\"CALL\"];\n }\n\n if (sPrev !== undefined) {\n this.println(nPrev + \" instructions earlier:\");\n }\n\n /*\n * TODO: The following is necessary to prevent dumpHistory() from causing additional (or worse, recursive)\n * faults due to segmented addresses that are no longer valid, but the only alternative is to dramatically\n * increase the amount of memory used to store instruction history (eg, storing copies of all the instruction\n * bytes alongside the execution addresses).\n *\n * For now, we're living dangerously, so that our history dumps actually work.\n *\n * this.nSuppressBreaks++;\n *\n * If you re-enable this protection, be sure to re-enable the decrement below, too.\n */\n while (nLines > 0 && iHistory != this.iInstructionHistory) {\n\n var dbgAddr = aHistory[iHistory++];\n if (dbgAddr.addr == null) break;\n\n /*\n * We must create a new dbgAddr from the address in aHistory, because dbgAddr was\n * a reference, not a copy, and we don't want getInstruction() modifying the original.\n */\n var dbgAddrNew = this.newAddr(dbgAddr.addr);\n\n var sComment = \"history\";\n var nSequence = nPrev--;\n\n /*\n * TODO: Need to some UI to control whether cycle counts are displayed as part of the history.\n * It's currently disabled in checkInstruction(), so it's disable here, too.\n *\n if (DEBUG && dbgAddr.cycleCount != null) {\n sComment = \"cycles\";\n nSequence = dbgAddr.cycleCount;\n }\n */\n\n var sInstruction = this.getInstruction(dbgAddrNew, sComment, nSequence);\n\n if (!aFilters.length || sInstruction.indexOf(aFilters[0]) >= 0) {\n this.println(sInstruction);\n }\n\n /*\n * If there were OPERAND or ADDRESS overrides on the previous instruction, getInstruction()\n * will have automatically disassembled additional bytes, so skip additional history entries.\n */\n if (dbgAddrNew.cOverrides) {\n iHistory += dbgAddrNew.cOverrides; nLines -= dbgAddrNew.cOverrides; nPrev -= dbgAddrNew.cOverrides;\n }\n\n if (iHistory >= aHistory.length) iHistory = 0;\n this.nextHistory = nPrev;\n cHistory++;\n nLines--;\n }\n /*\n * See comments above.\n *\n * this.nSuppressBreaks--;\n */\n }\n\n if (!cHistory) {\n this.println(\"no \" + sMore + \"history available\");\n this.nextHistory = undefined;\n }\n }\n\n /**\n * messageInit(sEnable)\n *\n * @this {DebuggerPDP10}\n * @param {string|undefined} sEnable contains zero or more message categories to enable, separated by '|'\n */\n messageInit(sEnable)\n {\n this.dbg = this;\n this.bitsMessage = this.bitsWarning = MessagesPDP10.FAULT | MessagesPDP10.WARN;\n this.sMessagePrev = null;\n this.aMessageBuffer = [];\n /*\n * Internally, we use \"key\" instead of \"keys\", since the latter is a method on JavasScript objects,\n * but externally, we allow the user to specify \"keys\"; \"kbd\" is also allowed as shorthand for \"keyboard\".\n */\n var aEnable = this.parseCommand(sEnable.replace(\"keys\",\"key\").replace(\"kbd\",\"keyboard\"), false, '|');\n if (aEnable.length) {\n for (var m in MessagesPDP10.CATEGORIES) {\n if (Usr.indexOf(aEnable, m) >= 0) {\n this.bitsMessage |= MessagesPDP10.CATEGORIES[m];\n this.println(m + \" messages enabled\");\n }\n }\n }\n }\n\n /**\n * messageDump(bitMessage, fnDumper)\n *\n * @this {DebuggerPDP10}\n * @param {number} bitMessage is one Messages category flag\n * @param {function(Array.<string>)} fnDumper is a function the Debugger can use to dump data for that category\n * @return {boolean} true if successfully registered, false if not\n */\n messageDump(bitMessage, fnDumper)\n {\n for (var m in MessagesPDP10.CATEGORIES) {\n if (bitMessage == MessagesPDP10.CATEGORIES[m]) {\n this.afnDumpers[m] = fnDumper;\n return true;\n }\n }\n return false;\n }\n\n /**\n * getRegIndex(sReg, off)\n *\n * @this {DebuggerPDP10}\n * @param {string} sReg\n * @param {number} [off] optional offset into sReg\n * @return {number} register index, or -1 if not found\n */\n getRegIndex(sReg, off)\n {\n return DebuggerPDP10.REGNAMES.indexOf(sReg.toUpperCase());\n }\n\n /**\n * getRegName(iReg)\n *\n * @this {DebuggerPDP10}\n * @param {number} iReg (0-7; not used for other registers)\n * @return {string}\n */\n getRegName(iReg)\n {\n return DebuggerPDP10.REGNAMES[iReg] || \"\";\n }\n\n /**\n * getRegValue(iReg)\n *\n * @this {DebuggerPDP10}\n * @param {number} iReg\n * @return {number|undefined}\n */\n getRegValue(iReg)\n {\n var value;\n var cpu = this.cpu;\n switch(iReg) {\n case DebuggerPDP10.REGS.PC:\n value = cpu.getPC();\n break;\n case DebuggerPDP10.REGS.RA:\n value = cpu.regRA;\n break;\n case DebuggerPDP10.REGS.EA:\n value = cpu.regEA;\n break;\n case DebuggerPDP10.REGS.PS:\n value = cpu.getPS();\n break;\n case DebuggerPDP10.REGS.OV:\n value = (cpu.regPS & PDP10.PSFLAG.AROV)? 1 : 0;\n break;\n case DebuggerPDP10.REGS.C0:\n value = (cpu.regPS & PDP10.PSFLAG.CRY0)? 1 : 0;\n break;\n case DebuggerPDP10.REGS.C1:\n value = (cpu.regPS & PDP10.PSFLAG.CRY1)? 1 : 0;\n break;\n case DebuggerPDP10.REGS.BI:\n value = (cpu.regPS & PDP10.PSFLAG.BIS)? 1 : 0;\n break;\n case DebuggerPDP10.REGS.ND:\n value = (cpu.regPS & PDP10.PSFLAG.DCK)? 1 : 0;\n break;\n case DebuggerPDP10.REGS.PD:\n value = (cpu.regPS & PDP10.PSFLAG.PDOV)? 1 : 0;\n break;\n }\n return value;\n }\n\n /**\n * setRegValue(iReg, value)\n *\n * @this {DebuggerPDP10}\n * @param {number} iReg\n * @param {number} value\n */\n setRegValue(iReg, value)\n {\n var flag = 0;\n var cpu = this.cpu;\n\n switch(iReg) {\n case DebuggerPDP10.REGS.PC:\n cpu.setPC(value);\n this.setAddr(this.dbgAddrCode, cpu.getPC());\n break;\n case DebuggerPDP10.REGS.PS:\n cpu.setPS(value);\n break;\n case DebuggerPDP10.REGS.OV:\n flag = PDP10.PSFLAG.AROV;\n break;\n case DebuggerPDP10.REGS.C0:\n flag = PDP10.PSFLAG.CRY0;\n break;\n case DebuggerPDP10.REGS.C1:\n flag = PDP10.PSFLAG.CRY1;\n break;\n case DebuggerPDP10.REGS.BI:\n flag = PDP10.PSFLAG.BIS;\n break;\n case DebuggerPDP10.REGS.ND:\n flag = PDP10.PSFLAG.DCK;\n break;\n case DebuggerPDP10.REGS.PD:\n flag = PDP10.PSFLAG.PDOV;\n break;\n }\n if (flag) {\n if (value) {\n cpu.regPS |= flag;\n } else {\n cpu.regPS &= ~flag;\n }\n }\n }\n\n /**\n * replaceRegs(s)\n *\n * TODO: Implement or eliminate.\n *\n * @this {DebuggerPDP10}\n * @param {string} s\n * @return {string}\n */\n replaceRegs(s)\n {\n return s;\n }\n\n /**\n * message(sMessage, fAddress)\n *\n * @this {DebuggerPDP10}\n * @param {string} sMessage is any caller-defined message string\n * @param {boolean} [fAddress] is true to display the current address\n */\n message(sMessage, fAddress)\n {\n if (fAddress) {\n sMessage += \" @\" + this.toStrAddr(this.newAddr(this.cpu.getLastPC()));\n }\n\n if (this.sMessagePrev && sMessage == this.sMessagePrev) return;\n this.sMessagePrev = sMessage;\n\n if (this.bitsMessage & MessagesPDP10.BUFFER) {\n this.aMessageBuffer.push(sMessage);\n return;\n }\n\n var fRunning;\n if ((this.bitsMessage & MessagesPDP10.HALT) && this.cpu && (fRunning = this.cpu.isRunning()) || this.isBusy(true)) {\n this.stopCPU();\n if (fRunning) sMessage += \" (cpu halted)\";\n }\n\n this.println(sMessage); // + \" (\" + this.cpu.getCycles() + \" cycles)\"\n\n /*\n * We have no idea what the frequency of println() calls might be; all we know is that they easily\n * screw up the CPU's careful assumptions about cycles per burst. So we call yieldCPU() after every\n * message, to effectively end the current burst and start fresh.\n *\n * TODO: See CPUPDP10.calcStartTime() for a discussion of why we might want to call yieldCPU() *before*\n * we display the message.\n */\n if (this.cpu) this.cpu.yieldCPU();\n }\n\n /**\n * init()\n *\n * @this {DebuggerPDP10}\n * @param {boolean} [fAutoStart]\n */\n init(fAutoStart)\n {\n this.fInit = true;\n this.println(\"Type ? for help with PDPjs Debugger commands\");\n this.updateStatus();\n if (!fAutoStart) this.setFocus();\n if (this.sInitCommands) {\n var sCmds = this.sInitCommands;\n this.sInitCommands = null;\n this.doCommands(sCmds, true);\n }\n }\n\n /**\n * historyInit(fQuiet)\n *\n * This function is intended to be called by the constructor, reset(), addBreakpoint(), findBreakpoint()\n * and any other function that changes the checksEnabled() criteria used to decide whether checkInstruction()\n * should be called.\n *\n * That is, if the history arrays need to be allocated and haven't already been allocated, then allocate them,\n * and if the arrays are no longer needed, then deallocate them.\n *\n * @this {DebuggerPDP10}\n * @param {boolean} [fQuiet]\n */\n historyInit(fQuiet)\n {\n var i;\n if (!this.checksEnabled()) {\n if (this.aInstructionHistory && this.aInstructionHistory.length && !fQuiet) {\n this.println(\"instruction history buffer freed\");\n }\n this.iInstructionHistory = 0;\n this.aInstructionHistory = [];\n return;\n }\n if (!this.aInstructionHistory || !this.aInstructionHistory.length) {\n this.aInstructionHistory = new Array(DebuggerPDP10.HISTORY_LIMIT);\n for (i = 0; i < this.aInstructionHistory.length; i++) {\n /*\n * Preallocate dummy Addr (Array) objects in every history slot, so that\n * checkInstruction() doesn't need to call newAddr() on every slot update.\n */\n this.aInstructionHistory[i] = this.newAddr();\n }\n this.iInstructionHistory = 0;\n if (!fQuiet) {\n this.println(\"instruction history buffer allocated\");\n }\n }\n }\n\n /**\n * startCPU(fUpdateFocus, fQuiet)\n *\n * @this {DebuggerPDP10}\n * @param {boolean} [fUpdateFocus] is true to update focus\n * @param {boolean} [fQuiet]\n * @return {boolean} true if run request successful, false if not\n */\n startCPU(fUpdateFocus, fQuiet)\n {\n if (!this.checkCPU(fQuiet)) return false;\n this.cpu.startCPU(fUpdateFocus);\n return true;\n }\n\n /**\n * stepCPU(nCycles, fRegs, fUpdateDisplays)\n *\n * @this {DebuggerPDP10}\n * @param {number} nCycles (0 for one instruction without checking breakpoints)\n * @param {boolean|null} [fRegs] is true to display registers after step (default is false; use null for previous setting)\n * @param {boolean} [fUpdateDisplays] is false to disable Computer display updates (default is true)\n * @return {boolean}\n */\n stepCPU(nCycles, fRegs, fUpdateDisplays)\n {\n if (!this.checkCPU()) return false;\n\n var sCmd = \"\";\n if (fRegs === null) {\n fRegs = (!this.sCmdTracePrev || this.sCmdTracePrev == \"tr\");\n sCmd = fRegs? \"tr\" : \"t\";\n }\n\n this.nCycles = 0;\n\n if (!nCycles) {\n /*\n * When single-stepping, the CPU won't call checkInstruction(), which is good for\n * avoiding breakpoints, but bad for instruction data collection if checks are enabled.\n * So we call checkInstruction() ourselves.\n */\n if (this.checksEnabled()) this.checkInstruction(this.cpu.getPC(), 0);\n }\n /*\n * For our typically tiny bursts (usually single instructions), mimic what runCPU() does.\n */\n try {\n nCycles = this.cpu.getBurstCycles(nCycles);\n var nCyclesStep = this.cpu.stepCPU(nCycles);\n if (nCyclesStep > 0) {\n this.cpu.updateTimers(nCyclesStep);\n this.nCycles += nCyclesStep;\n this.cpu.addCycles(nCyclesStep, true);\n this.cpu.updateChecksum(nCyclesStep);\n this.cInstructions++;\n }\n }\n catch(exception) {\n /*\n * We assume that any numeric exception was explicitly thrown by the CPU to interrupt the\n * current instruction. For all other exceptions, we attempt a stack dump.\n */\n if (typeof exception != \"number\") {\n var e = exception;\n this.nCycles = 0;\n this.cpu.setError(e.stack || e.message);\n }\n }\n\n /*\n * Because we called cpu.stepCPU() and not cpu.startCPU(), we must nudge the Computer's update code,\n * and then update our own state. Normally, the only time fUpdateDisplays will be false is when doTrace()\n * is calling us in a loop, in which case it will perform its own updateDisplays() when it's done.\n */\n if (fUpdateDisplays !== false) {\n if (this.panel) this.panel.stop();\n this.cmp.updateDisplays(-1);\n }\n\n this.updateStatus(fRegs || false, sCmd);\n return (this.nCycles > 0);\n }\n\n /**\n * stopCPU()\n *\n * @this {DebuggerPDP10}\n * @param {boolean} [fComplete]\n */\n stopCPU(fComplete)\n {\n if (this.cpu) this.cpu.stopCPU(fComplete);\n }\n\n /**\n * updateStatus(fRegs, sCmd)\n *\n * @this {DebuggerPDP10}\n * @param {boolean} [fRegs] (default is true)\n * @param {string} [sCmd]\n */\n updateStatus(fRegs = true, sCmd)\n {\n if (!this.fInit) return;\n\n if (sCmd) {\n this.println(DebuggerPDP10.PROMPT + sCmd);\n }\n\n this.setAddr(this.dbgAddrCode, this.cpu.getPC());\n\n /*\n * this.nStep used to be a simple boolean, but now it's 0 (or undefined)\n * if inactive, 1 if stepping over an instruction without a register dump, or 2\n * if stepping over an instruction with a register dump.\n */\n if (!fRegs || this.nStep == 1) {\n this.doUnassemble();\n } else {\n this.doRegisters();\n }\n }\n\n /**\n * checkCPU(fQuiet)\n *\n * Make sure the CPU is ready (finished initializing), powered, not already running, and not in an error state.\n *\n * @this {DebuggerPDP10}\n * @param {boolean} [fQuiet]\n * @return {boolean}\n */\n checkCPU(fQuiet)\n {\n if (!this.cpu || !this.cpu.isReady() || !this.cpu.isPowered() || this.cpu.isRunning()) {\n if (!fQuiet) this.println(\"cpu busy or unavailable, command ignored\");\n return false;\n }\n return !this.cpu.isError();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {DebuggerPDP10}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n /*\n * Because Debugger save/restore support is somewhat limited (and didn't always exist),\n * we deviate from the typical save/restore design pattern: instead of reset OR restore,\n * we always reset and then perform a (potentially limited) restore.\n */\n this.reset(true);\n\n // this.println(data? \"resuming\" : \"powering up\");\n\n if (data) {\n return this.restore(data);\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {DebuggerPDP10}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean}\n */\n powerDown(fSave, fShutdown)\n {\n if (fShutdown) this.println(fSave? \"suspending\" : \"shutting down\");\n return fSave? this.save() : true;\n }\n\n /**\n * reset(fQuiet)\n *\n * This is a notification handler, called by the Computer, to inform us of a reset.\n *\n * @this {DebuggerPDP10}\n * @param {boolean} fQuiet (true only when called from our own powerUp handler)\n */\n reset(fQuiet)\n {\n this.historyInit();\n this.cInstructions = this.cInstructionsStart = 0;\n this.sMessagePrev = null;\n this.nCycles = 0;\n this.setAddr(this.dbgAddrCode, this.cpu.getPC());\n /*\n * fRunning is set by start() and cleared by stop(). In addition, we clear\n * it here, so that if the CPU is reset while running, we can prevent stop()\n * from unnecessarily dumping the CPU state.\n */\n this.flags.running = false;\n this.clearTempBreakpoint();\n if (!fQuiet) this.updateStatus();\n }\n\n /**\n * save()\n *\n * This implements (very rudimentary) save support for the Debugger component.\n *\n * @this {DebuggerPDP10}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.packAddr(this.dbgAddrCode));\n state.set(1, this.packAddr(this.dbgAddrData));\n state.set(2, this.packAddr(this.dbgAddrAssemble));\n state.set(3, [this.aPrevCmds, this.fAssemble, this.bitsMessage]);\n state.set(4, this.aSymbolTable);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements (very rudimentary) restore support for the Debugger component.\n *\n * @this {DebuggerPDP10}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var i = 0;\n if (data[3] !== undefined) {\n this.dbgAddrCode = this.unpackAddr(data[i++]);\n this.dbgAddrData = this.unpackAddr(data[i++]);\n this.dbgAddrAssemble = this.unpackAddr(data[i++]);\n this.aPrevCmds = data[i][0];\n if (typeof this.aPrevCmds == \"string\") this.aPrevCmds = [this.aPrevCmds];\n this.fAssemble = data[i][1];\n this.bitsMessage |= data[i][2]; // keep our current message bits set, and simply \"add\" any extra bits defined by the saved state\n }\n if (data[4]) this.aSymbolTable = data[4];\n return true;\n }\n\n /**\n * start(ms, nCycles)\n *\n * This is a notification handler, called by the Computer, to inform us the CPU has started.\n *\n * @this {DebuggerPDP10}\n * @param {number} ms\n * @param {number} nCycles\n */\n start(ms, nCycles)\n {\n if (!this.nStep) this.println(\"running\");\n this.flags.running = true;\n this.msStart = ms;\n this.nCyclesStart = nCycles;\n }\n\n /**\n * stop(ms, nCycles)\n *\n * This is a notification handler, called by the Computer, to inform us the CPU has now stopped.\n *\n * @this {DebuggerPDP10}\n * @param {number} ms\n * @param {number} nCycles\n */\n stop(ms, nCycles)\n {\n if (this.flags.running) {\n this.flags.running = false;\n this.nCycles = nCycles - this.nCyclesStart;\n if (!this.nStep) {\n var sStopped = \"stopped\";\n if (this.nCycles) {\n var msTotal = ms - this.msStart;\n var nCyclesPerSecond = (msTotal > 0? Math.round(this.nCycles * 1000 / msTotal) : 0);\n sStopped += \" (\";\n if (this.checksEnabled()) {\n sStopped += this.cInstructions + \" instructions, \";\n /*\n * $ops displays progress by calculating cInstructions - cInstructionsStart, so before\n * zeroing cInstructions, we should subtract cInstructions from cInstructionsStart (since\n * we're effectively subtracting cInstructions from cInstructions as well).\n */\n this.cInstructionsStart -= this.cInstructions;\n this.cInstructions = 0;\n }\n sStopped += this.nCycles + \" cycles, \" + msTotal + \" ms, \" + nCyclesPerSecond + \" hz)\";\n } else {\n if (this.messageEnabled(MessagesPDP10.HALT)) {\n /*\n * It's possible the user is trying to 'g' past a fault that was blocked by helpCheckFault()\n * for the Debugger's benefit; if so, it will continue to be blocked, so try displaying a helpful\n * message (another helpful tip would be to simply turn off the \"halt\" message category).\n */\n sStopped += \" (use the 't' command to execute blocked faults)\";\n }\n }\n this.println(sStopped);\n }\n this.updateStatus(true);\n this.setFocus();\n this.clearTempBreakpoint(this.cpu.getPC());\n this.sMessagePrev = null;\n }\n }\n\n /**\n * checksEnabled(fRelease)\n *\n * This \"check\" function is called by the CPU; we indicate whether or not every instruction needs to be checked.\n *\n * Originally, this returned true even when there were only read and/or write breakpoints, but those breakpoints\n * no longer require the intervention of checkInstruction(); the Bus component automatically swaps in/out appropriate\n * \"checked\" Memory access functions to deal with those breakpoints in the corresponding Memory blocks. So I've\n * simplified the test below.\n *\n * @this {DebuggerPDP10}\n * @param {boolean} [fRelease] is true for release criteria only; default is false (any criteria)\n * @return {boolean} true if every instruction needs to pass through checkInstruction(), false if not\n */\n checksEnabled(fRelease)\n {\n return ((DEBUG && !fRelease)? true : (this.aBreakExec.length > 1 || !!this.nBreakInstructions));\n }\n\n /**\n * checkInstruction(addr, nState)\n *\n * This \"check\" function is called by the CPU to inform us about the next instruction to be executed,\n * giving us an opportunity to look for \"exec\" breakpoints and update opcode instruction history.\n *\n * @this {DebuggerPDP10}\n * @param {number} addr\n * @param {number} nState is < 0 if stepping, 0 if starting, or > 0 if running\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkInstruction(addr, nState)\n {\n var opCode = -1;\n var cpu = this.cpu;\n\n /*\n * If opHalt() calls our stopInstruction() function, it will effectively rewind the PC back to the HALT,\n * purely for our debugging benefit, so we must compensate for that here by advancing the PC past the HALT\n * when the machine starts up again.\n */\n if (!nState) {\n opCode = this.cpu.readWord(addr);\n if ((opCode >> PDP10.OPCODE.A_SHIFT) == PDP10.OPCODE.HALT && this.cpu.getLastPC() == addr) {\n addr = this.cpu.advancePC(1);\n }\n }\n\n /*\n * If the CPU stopped on a breakpoint, we're not interested in stopping again if the machine is starting.\n */\n if (nState > 0) {\n if (this.nBreakInstructions) {\n if (!--this.nBreakInstructions) return true;\n }\n if (this.checkBreakpoint(addr, 1, this.aBreakExec)) {\n return true;\n }\n }\n\n /*\n * The rest of the instruction tracking logic can only be performed if historyInit() has allocated the\n * necessary data structures. Note that there is no explicit UI for enabling/disabling history, other than\n * adding/removing breakpoints, simply because it's breakpoints that trigger the call to checkInstruction();\n * well, OK, and a few other things now, like enabling MessagesPDP10.INT messages.\n */\n if (nState >= 0 && this.aInstructionHistory.length) {\n this.cInstructions++;\n if (opCode < 0) {\n opCode = this.cpu.readWord(addr);\n }\n if (opCode >= 0) {\n var dbgAddr = this.aInstructionHistory[this.iInstructionHistory];\n this.setAddr(dbgAddr, addr);\n // if (DEBUG) dbgAddr.cycleCount = cpu.getCycles();\n if (++this.iInstructionHistory == this.aInstructionHistory.length) this.iInstructionHistory = 0;\n }\n }\n return false;\n }\n\n /**\n * findInstruction(opCode, fOperands)\n *\n * @this {DebuggerPDP10}\n * @param {number} opCode\n * @param {boolean} [fOperands] (optional; default is true)\n * @return {string}\n */\n findInstruction(opCode, fOperands = true)\n {\n var opNum, opMask, aModes, iMode = 0;\n var op = (opCode / PDP10.OPCODE.OP_SCALE)|0;\n\n for (var mask in DebuggerPDP10.OPTABLE) {\n var opMasks = DebuggerPDP10.OPTABLE[mask];\n opNum = opMasks[op & mask];\n if (opNum) {\n opMask = +mask;\n /*\n * When we extracted op from opCode using OP_SCALE, we included 6 additional bits\n * to help distinguish OPIO instructions from non-OPIO instructions. But for the\n * following tests, we don't need those bits, so we get rid of them now.\n */\n op >>= 6;\n switch(opMask) {\n case PDP10.OPCODE.OPMODE:\n aModes = DebuggerPDP10.OPMODES;\n iMode = (op & 3);\n break;\n case PDP10.OPCODE.OPCOMP:\n aModes = DebuggerPDP10.OPCOMPS;\n iMode = (op & 7);\n break;\n case PDP10.OPCODE.OPTEST:\n aModes = DebuggerPDP10.OPTESTS;\n iMode = ((op & 0o60) >> 2) | ((op & 0o6) >> 1);\n break;\n }\n break;\n }\n }\n\n var sMode = aModes && aModes[iMode] || \"\";\n if (sMode == \"S\" && opNum > DebuggerPDP10.OPS.MOVM) sMode = \"B\";\n var sOperation = DebuggerPDP10.OPNAMES[opNum || 0] + sMode;\n\n if (!fOperands) {\n if (!opNum) sOperation = \"\";\n } else {\n if (!opNum) {\n sOperation = Str.pad(sOperation, 8) + this.toStrWord(opCode);\n } else {\n var n, sOperand;\n if (opMask == PDP10.OPCODE.OPIO) {\n n = (opCode / PDP10.OPCODE.IO_SCALE) & PDP10.OPCODE.IO_MASK;\n sOperand = this.toStrBase(n, -1);\n } else {\n n = (opCode >> PDP10.OPCODE.A_SHIFT) & PDP10.OPCODE.A_MASK;\n sOperand = this.toStrBase(n, -1);\n for (var m = 0; sOperand && m < DebuggerPDP10.ALTOPS.length; m++) {\n if (opNum == DebuggerPDP10.ALTOPS[m][0]) {\n var opAlt = DebuggerPDP10.ALTOPS[m][n];\n if (opAlt) {\n sOperation = DebuggerPDP10.OPNAMES[opAlt];\n sOperand = \"\";\n break;\n }\n }\n }\n }\n sOperation = Str.pad(sOperation, 8) + (sOperand? sOperand + ',' : \"\");\n if (opCode & PDP10.OPCODE.I_FIELD) sOperation += '@';\n sOperation += this.toStrBase(opCode & PDP10.OPCODE.Y_MASK, -1);\n var i = (opCode >> PDP10.OPCODE.X_SHIFT) & PDP10.OPCODE.X_MASK;\n if (i) sOperation += '(' + this.toStrBase(i, -1) + ')';\n }\n }\n return sOperation;\n }\n\n /**\n * getInstruction(dbgAddr, sComment, nSequence)\n *\n * Get the next instruction, by decoding the opcode and any operands.\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @param {string} [sComment] is an associated comment\n * @param {number|null} [nSequence] is an associated sequence number, undefined if none\n * @return {string} (and dbgAddr is updated to the next instruction)\n */\n getInstruction(dbgAddr, sComment, nSequence)\n {\n var dbgAddrOp = this.newAddr(dbgAddr.addr);\n var opCode = this.getWord(dbgAddr, 1);\n var sOperation = this.findInstruction(opCode);\n\n var sOpcodes = \"\";\n var sLine = this.toStrAddr(dbgAddrOp) + \":\";\n if (dbgAddrOp.addr !== PDP10.ADDR_INVALID && dbgAddr.addr !== PDP10.ADDR_INVALID) {\n do {\n var w = this.getWord(dbgAddrOp, 1);\n sOpcodes += ' ' + this.toStrWord(w);\n if (dbgAddrOp.addr == null) break;\n } while (dbgAddrOp.addr != dbgAddr.addr);\n }\n\n sLine += Str.pad(sOpcodes, 16) + sOperation;\n\n if (sComment) {\n sLine = Str.pad(sLine, 48) + ';' + (sComment || \"\");\n if (!this.cpu.flags.checksum) {\n sLine += (nSequence != null? '=' + nSequence.toString() : \"\");\n } else {\n var nCycles = this.cpu.getCycles();\n sLine += \"cycles=\" + nCycles.toString() + \" cs=\" + Str.toHex(this.cpu.nChecksum);\n }\n }\n return sLine;\n }\n\n /**\n * parseInstruction(sOpcode, sOperands, addr, aUndefined)\n *\n * @this {DebuggerPDP10}\n * @param {string} sOpcode\n * @param {string} [sOperands]\n * @param {number} [addr] of memory where this instruction is being assembled\n * @param {Array} [aUndefined]\n * @return {number} (opcode, or -1 if unrecognized instruction)\n */\n parseInstruction(sOpcode, sOperands, addr, aUndefined)\n {\n var opCode = -1;\n var opMask, opNum;\n\n if (!sOpcode) {\n /*\n * MACRO-10 also allows instructions to be assembled without an opcode (ie, just an address expression),\n * so if that's all we have, skip the opcode parsing.\n */\n if (sOperands) opCode = opMask = 0;\n }\n else {\n var sMnemonic = sOpcode.toUpperCase();\n /*\n * Perform any alternate mnemonic substitutions first\n */\n for (var m = 0; m < DebuggerPDP10.ALTOPS.length; m++) {\n for (var n in DebuggerPDP10.ALTOPS[m]) {\n if (!+n) continue;\n opNum = DebuggerPDP10.ALTOPS[m][n];\n if (sMnemonic == DebuggerPDP10.OPNAMES[opNum]) {\n sMnemonic = DebuggerPDP10.OPNAMES[DebuggerPDP10.ALTOPS[m][0]];\n if (sOperands) sOperands = this.toStrBase(+n) + ',' + sOperands;\n break;\n }\n }\n }\n for (var mask in DebuggerPDP10.OPTABLE) {\n\n var aModes;\n opMask = +mask;\n var opMasks = DebuggerPDP10.OPTABLE[mask];\n\n switch (opMask) {\n case PDP10.OPCODE.OPMODE:\n aModes = DebuggerPDP10.OPMODES;\n break;\n case PDP10.OPCODE.OPCOMP:\n aModes = DebuggerPDP10.OPCOMPS;\n break;\n case PDP10.OPCODE.OPTEST:\n aModes = DebuggerPDP10.OPTESTS;\n break;\n default:\n aModes = [\"\"];\n break;\n }\n var opMode = 0;\n for (var op in opMasks) {\n opNum = opMasks[op];\n for (var iMode = 0; iMode < aModes.length; iMode++) {\n\n var sMode = aModes[iMode];\n if (sMode == \"S\" && opNum > DebuggerPDP10.OPS.MOVM) sMode = \"B\";\n var sCandidate = DebuggerPDP10.OPNAMES[opNum] + sMode;\n\n if (sMnemonic == sCandidate) {\n if (opMask != PDP10.OPCODE.OPTEST) {\n opMode = iMode;\n } else {\n opMode = ((iMode & 0o3) << 1) | ((iMode & 0o14) << 2);\n }\n opCode = (op | (opMode << 6)) * PDP10.OPCODE.OP_SCALE;\n break;\n }\n }\n if (opCode >= 0) break;\n }\n if (opCode >= 0) break;\n }\n /*\n * MACRO-10 also allows instructions to be assembled without an opcode (ie, just an address expression),\n * so we'll give that a try next (as long as we're not mashing two symbols together).\n */\n if (opCode < 0 && (!sOperands || !sOperands.match(/^[0-9A-Z$%.?]/i))) {\n sOperands = sOpcode + sOperands;\n sOpcode = \"\";\n opCode = 0;\n }\n }\n\n if (opCode >= 0) {\n if (sOperands) {\n\n var aOperands = sOperands.split(',');\n if (aOperands.length > 2) {\n if (!aUndefined) this.println(\"too many operands: \" + sOperands);\n aOperands.length = 0;\n opCode = -1;\n }\n\n for (var i = 0; i < aOperands.length; i++) {\n\n var sOperand = aOperands[i].trim();\n if (!sOperand) continue;\n\n var match = sOperand.match(/(@?)([^(]*)\\(?([^)]*)\\)?/);\n if (!match) {\n if (!aUndefined) this.println(\"unknown operand: \" + sOperand);\n opCode = -1;\n break;\n }\n\n /*\n * If the operand contains an indirection operator (@) and/or index register (X), we parse those\n * first and update the indirect (I) bit and index (X) bits as appropriate. The order is important,\n * because if we parse them AFTER parsing the address expression, we might lose an undefined symbol\n * indication, and if the caller needs to handle address fixups, that would be bad.\n */\n if (match[1]) opCode += PDP10.OPCODE.I_FIELD;\n\n sOperand = match[3];\n if (sOperand) {\n operand = this.parseExpression(sOperand, aUndefined);\n if (operand == undefined) {\n opCode = -1;\n break;\n }\n /*\n * Here's a fun tidbit from the April 1978 MACRO-10 manual, p. 4-5:\n *\n * NOTE: To assemble the index, MACRO places the index register address in a fullword of storage,\n * swaps its halfwords, and then adds the swapped word to the instruction word.\n *\n * Which means that an instruction like this (where AC is zero):\n *\n * 8839 037653 205 00 0 00 400000 MOVSI AC,(1B<^O<AC>>) ;INITIALIZE AC\n *\n * produces an instruction that does NOT use indexing at all, even though it is coded as such. So my\n * simplistic masking of the index operand with PDP10.OPCODE.X_MASK, while logical, was completely wrong:\n *\n * if (operand < 0 || operand > PDP10.OPCODE.X_MASK) {\n * operand &= PDP10.OPCODE.X_MASK;\n * if (MAXDEBUG) this.println(\"index (\" + sOperand + \") truncated to \" + this.toStrBase(operand));\n * }\n * opCode += operand << PDP10.OPCODE.X_SHIFT;\n */\n operand = PDP10.SWAP(this.truncate(operand, 36, true));\n opCode += operand;\n }\n\n sOperand = match[2];\n if (i || aOperands.length == 1) {\n /*\n * If this is NOT the first operand, replace all periods NOT preceded by a digit with the current address.\n */\n if (!sOperand) {\n sOperand = \"0\";\n } else {\n sOperand = sOperand.replace(/(^|[^0-9])\\./g, \"$1\" + this.toStrOffset(addr));\n }\n }\n\n var operand = this.parseExpression(sOperand, aUndefined);\n if (operand == undefined) {\n opCode = -1;\n break;\n }\n\n if (!i && aOperands.length > 1) {\n if (opMask == PDP10.OPCODE.OPIO) {\n if (operand < 0 || operand > PDP10.OPCODE.IO_MASK) {\n operand &= PDP10.OPCODE.IO_MASK;\n if (MAXDEBUG) this.println(\"device code (\" + sOperand + \") truncated to \" + this.toStrBase(operand));\n }\n opCode += (operand * PDP10.OPCODE.IO_SCALE);\n }\n else {\n if (operand < 0 || operand > PDP10.OPCODE.A_MASK) {\n operand &= PDP10.OPCODE.A_MASK;\n if (MAXDEBUG) this.println(\"accumulator (\" + sOperand + \") truncated to \" + this.toStrBase(operand));\n }\n opCode += (operand << PDP10.OPCODE.A_SHIFT);\n }\n continue;\n }\n\n /*\n * I came across what I believe is a typo in the DEC \"DAKAC\" diagnostic:\n *\n * CAME [0,-1] ;PASS TEST IF C(AC)=0,,-1\n *\n * Based on the comment, it's clear what they really meant was either \"[0,,-1]\" or \"[XWD 0,-1]\".\n * However, they still got the desired result, which means when the assembler parses an mnemonic-less\n * instruction like \"0,-1\", it must truncate the second (address) operand.\n *\n * TODO: Determine if I should ALWAYS truncate. I'm trying to retain the flexibility of allowing\n * a full 36-bit instruction to be encoded with a single numeric expression (ie, one operand).\n */\n if (sOpcode || i) {\n if (operand < 0 || operand > PDP10.OPCODE.Y_MASK) {\n operand &= PDP10.ADDR_MASK;\n if (MAXDEBUG) this.println(\"address (\" + sOperand + \") truncated to \" + this.toStrBase(operand));\n }\n }\n opCode += operand;\n }\n }\n //\n // TODO: Complain about missing operands only if we know the instruction requires them.\n //\n // else {\n // this.println(\"missing operand(s)\");\n // opCode = -1;\n // }\n }\n\n if (opCode < 0 && !aUndefined) {\n this.println(\"unknown instruction: \" + sOpcode + ' ' + sOperands);\n }\n\n return opCode;\n }\n\n /**\n * stopInstruction(sMessage)\n *\n * TODO: Currently, the only way to prevent this call from stopping the CPU is when you're single-stepping.\n *\n * @this {DebuggerPDP10}\n * @param {string} [sMessage]\n * @return {boolean} true if stopping is enabled, false if not\n */\n stopInstruction(sMessage)\n {\n var cpu = this.cpu;\n if (cpu.isRunning()) {\n cpu.setPC(this.cpu.getLastPC());\n if (sMessage) this.println(sMessage);\n this.stopCPU();\n /*\n * TODO: Review the appropriate-ness of throwing a bogus vector number in order to immediately stop\n * the instruction. It's handy, but it also means that we no longer actually return true, so callers\n * of either stopInstruction() or undefinedInstruction() may have unreachable code paths.\n */\n throw -1;\n }\n return false;\n }\n\n /**\n * undefinedInstruction(opCode)\n *\n * @this {DebuggerPDP10}\n * @param {number} opCode\n * @return {boolean} true if stopping is enabled, false if not\n */\n undefinedInstruction(opCode)\n {\n if (this.messageEnabled(MessagesPDP10.CPU)) {\n this.printMessage(\"undefined opcode \" + this.toStrBase(opCode), true, true);\n return this.stopInstruction(); // allow the caller to step over it if they really want a trap generated\n }\n return false;\n }\n\n /**\n * checkMemoryRead(addr, nb)\n *\n * This \"check\" function is called by a Memory block to inform us that a memory read occurred, giving us an\n * opportunity to track the read if we want, and look for a matching \"read\" breakpoint, if any.\n *\n * In the \"old days\", it would be an error for this call to fail to find a matching Debugger breakpoint, but now\n * Memory blocks have no idea whether the Debugger or the machine's Debug register(s) triggered this \"checked\" read.\n *\n * If we return true, we \"trump\" the machine's Debug register(s); false allows normal Debug register processing.\n *\n * @this {DebuggerPDP10}\n * @param {number} addr\n * @param {number} [nb] (# of bytes; default is 1)\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkMemoryRead(addr, nb)\n {\n if (this.checkBreakpoint(addr, nb || 1, this.aBreakRead)) {\n this.stopCPU(false);\n return true;\n }\n return false;\n }\n\n /**\n * checkMemoryWrite(addr, nb)\n *\n * This \"check\" function is called by a Memory block to inform us that a memory write occurred, giving us an\n * opportunity to track the write if we want, and look for a matching \"write\" breakpoint, if any.\n *\n * In the \"old days\", it would be an error for this call to fail to find a matching Debugger breakpoint, but now\n * Memory blocks have no idea whether the Debugger or the machine's Debug register(s) triggered this \"checked\" write.\n *\n * If we return true, we \"trump\" the machine's Debug register(s); false allows normal Debug register processing.\n *\n * @this {DebuggerPDP10}\n * @param {number} addr\n * @param {number} [nb] (# of bytes; default is 1)\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkMemoryWrite(addr, nb)\n {\n if (this.checkBreakpoint(addr, nb || 1, this.aBreakWrite)) {\n this.stopCPU(false);\n return true;\n }\n return false;\n }\n\n /**\n * clearBreakpoints()\n *\n * @this {DebuggerPDP10}\n */\n clearBreakpoints()\n {\n var i, dbgAddr, addr;\n this.aBreakExec = [\"bp\"];\n if (this.aBreakRead !== undefined) {\n for (i = 1; i < this.aBreakRead.length; i++) {\n dbgAddr = this.aBreakRead[i];\n addr = this.getAddr(dbgAddr);\n this.bus.removeMemBreak(addr, false);\n }\n }\n this.aBreakRead = [\"br\"];\n if (this.aBreakWrite !== undefined) {\n for (i = 1; i < this.aBreakWrite.length; i++) {\n dbgAddr = this.aBreakWrite[i];\n addr = this.getAddr(dbgAddr);\n this.bus.removeMemBreak(addr, true);\n }\n }\n this.aBreakWrite = [\"bw\"];\n /*\n * nSuppressBreaks ensures we can't get into an infinite loop where a breakpoint lookup\n * requires reading memory that triggers more memory reads, which triggers more breakpoint checks.\n */\n this.nSuppressBreaks = 0;\n this.nBreakInstructions = 0;\n }\n\n /**\n * addBreakpoint(aBreak, dbgAddr, fTemporary)\n *\n * In case you haven't already figured this out, all our breakpoint commands use the address\n * to identify a breakpoint, not an incrementally assigned breakpoint index like other debuggers;\n * see doBreak() for details.\n *\n * This has a few implications, one being that you CANNOT set more than one kind of breakpoint\n * on a single address. In practice, that's rarely a problem, because you can almost always set\n * a different breakpoint on a neighboring address.\n *\n * Also, there is one exception to the \"one address, one breakpoint\" rule, and that involves\n * temporary breakpoints (ie, one-time execution breakpoints that either a \"p\" or \"g\" command\n * may create to step over a chunk of code). Those breakpoints automatically clear themselves,\n * so there usually isn't any need to refer to them using breakpoint commands.\n *\n * TODO: Consider supporting the more \"traditional\" breakpoint index syntax; the current\n * address-based syntax was implemented solely for expediency and consistency. At the same time,\n * also consider a more WDEB386-like syntax, where \"br\" is used to set a variety of access-specific\n * breakpoints, using modifiers like \"r1\", \"r2\", \"w1\", \"w2, etc.\n *\n * @this {DebuggerPDP10}\n * @param {Array} aBreak\n * @param {DbgAddrPDP10} dbgAddr\n * @param {boolean} [fTemporary]\n * @return {boolean} true if breakpoint added, false if already exists\n */\n addBreakpoint(aBreak, dbgAddr, fTemporary)\n {\n var fSuccess = true;\n\n // this.nSuppressBreaks++;\n\n /*\n * Instead of complaining that a breakpoint already exists (as we used to do), we now\n * allow breakpoints to be re-set; this makes it easier to update any commands that may\n * be associated with the breakpoint.\n *\n * The only exception: we DO allow a temporary breakpoint at an address where there may\n * already be a breakpoint, so that you can easily step (\"p\" or \"g\") over such addresses.\n */\n if (!fTemporary) {\n this.findBreakpoint(aBreak, dbgAddr, true, false, true);\n }\n\n if (aBreak != this.aBreakExec) {\n var addr = this.getAddr(dbgAddr);\n if (addr === PDP10.ADDR_INVALID) {\n this.println(\"invalid address: \" + this.toStrAddr(dbgAddr));\n fSuccess = false;\n } else {\n var fWrite = (aBreak == this.aBreakWrite);\n this.bus.addMemBreak(addr, fWrite);\n }\n }\n\n if (fSuccess) {\n aBreak.push(dbgAddr);\n if (fTemporary) {\n dbgAddr.fTemporary = true;\n }\n else {\n this.printBreakpoint(aBreak, aBreak.length-1, \"set\");\n this.historyInit();\n }\n }\n\n // this.nSuppressBreaks--;\n\n return fSuccess;\n }\n\n /**\n * findBreakpoint(aBreak, dbgAddr, fRemove, fTemporary, fQuiet)\n *\n * @this {DebuggerPDP10}\n * @param {Array} aBreak\n * @param {DbgAddrPDP10} dbgAddr\n * @param {boolean} [fRemove]\n * @param {boolean} [fTemporary]\n * @param {boolean} [fQuiet]\n * @return {boolean} true if found, false if not\n */\n findBreakpoint(aBreak, dbgAddr, fRemove, fTemporary, fQuiet)\n {\n var fFound = false;\n var addr = this.getAddr(dbgAddr);\n for (var i = 1; i < aBreak.length; i++) {\n var dbgAddrBreak = aBreak[i];\n if (addr == this.getAddr(dbgAddrBreak)) {\n if (!fTemporary || dbgAddrBreak.fTemporary) {\n fFound = true;\n if (fRemove) {\n if (!dbgAddrBreak.fTemporary && !fQuiet) {\n this.printBreakpoint(aBreak, i, \"cleared\");\n }\n aBreak.splice(i, 1);\n if (aBreak != this.aBreakExec) {\n var fWrite = (aBreak == this.aBreakWrite);\n this.bus.removeMemBreak(addr, fWrite);\n }\n /*\n * We'll mirror the logic in addBreakpoint() and leave the history buffer alone if this\n * was a temporary breakpoint.\n */\n if (!dbgAddrBreak.fTemporary) {\n this.historyInit();\n }\n break;\n }\n if (!fQuiet) this.printBreakpoint(aBreak, i, \"exists\");\n break;\n }\n }\n }\n return fFound;\n }\n\n /**\n * listBreakpoints(aBreak)\n *\n * @this {DebuggerPDP10}\n * @param {Array} aBreak\n * @return {number} of breakpoints listed, 0 if none\n */\n listBreakpoints(aBreak)\n {\n for (var i = 1; i < aBreak.length; i++) {\n this.printBreakpoint(aBreak, i);\n }\n return aBreak.length - 1;\n }\n\n /**\n * printBreakpoint(aBreak, i, sAction)\n *\n * @this {DebuggerPDP10}\n * @param {Array} aBreak\n * @param {number} i\n * @param {string} [sAction]\n */\n printBreakpoint(aBreak, i, sAction)\n {\n var dbgAddr = aBreak[i];\n this.println(aBreak[0] + ' ' + this.toStrAddr(dbgAddr) + (sAction? (' ' + sAction) : (dbgAddr.sCmd? (' \"' + dbgAddr.sCmd + '\"') : '')));\n }\n\n /**\n * setTempBreakpoint(dbgAddr)\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr of new temp breakpoint\n */\n setTempBreakpoint(dbgAddr)\n {\n this.addBreakpoint(this.aBreakExec, dbgAddr, true);\n }\n\n /**\n * clearTempBreakpoint(addr)\n *\n * @this {DebuggerPDP10}\n * @param {number|undefined} [addr] clear all temp breakpoints if no address specified\n */\n clearTempBreakpoint(addr)\n {\n if (addr !== undefined) {\n this.checkBreakpoint(addr, 1, this.aBreakExec, true);\n this.nStep = 0;\n } else {\n for (var i = 1; i < this.aBreakExec.length; i++) {\n var dbgAddrBreak = this.aBreakExec[i];\n if (dbgAddrBreak.fTemporary) {\n if (!this.findBreakpoint(this.aBreakExec, dbgAddrBreak, true, true)) break;\n i = 0;\n }\n }\n }\n }\n\n /**\n * checkBreakpoint(addr, nb, aBreak, fTemporary)\n *\n * @this {DebuggerPDP10}\n * @param {number} addr\n * @param {number} nb (# of bytes)\n * @param {Array} aBreak\n * @param {boolean} [fTemporary]\n * @return {boolean} true if breakpoint has been hit, false if not\n */\n checkBreakpoint(addr, nb, aBreak, fTemporary)\n {\n /*\n * Time to check for breakpoints; note that this should be done BEFORE updating history data\n * (see checkInstruction), since we might not actually execute the current instruction.\n */\n var fBreak = false;\n\n if (!this.nSuppressBreaks++) {\n\n for (var i = 1; !fBreak && i < aBreak.length; i++) {\n\n var dbgAddrBreak = aBreak[i];\n\n if (fTemporary && !dbgAddrBreak.fTemporary) continue;\n\n /*\n * If we're checking an execution address, which is always virtual, and virtual\n * addresses are always restricted to 16 bits, let's mask the breakpoint address to match\n * (the user should know better, but we'll be nice).\n */\n var addrBreak = this.getAddr(dbgAddrBreak) & (aBreak == this.aBreakExec? 0xffff : -1);\n for (var n = 0; n < nb; n++) {\n\n if ((addr + n) != addrBreak) continue;\n\n var a;\n fBreak = true;\n if (dbgAddrBreak.fTemporary) {\n this.findBreakpoint(aBreak, dbgAddrBreak, true, true);\n fTemporary = true;\n }\n if (a = dbgAddrBreak.aCmds) {\n /*\n * When one or more commands are attached to a breakpoint, we don't halt by default.\n * Instead, we set fBreak to true only if, at the completion of all the commands, the\n * CPU is halted; in other words, you should include \"h\" as one of the breakpoint commands\n * if you want the breakpoint to stop execution.\n *\n * Another useful command is \"if\", which will return false if the expression is false,\n * at which point we'll jump ahead to the next \"else\" command, and if there isn't an \"else\",\n * we abort.\n */\n fBreak = false;\n for (var j = 0; j < a.length; j++) {\n if (!this.doCommand(a[j], true)) {\n if (a[j].indexOf(\"if\")) {\n fBreak = true; // the failed command wasn't \"if\", so abort\n break;\n }\n var k = j + 1;\n for (; k < a.length; k++) {\n if (!a[k].indexOf(\"else\")) break;\n j++;\n }\n if (k == a.length) { // couldn't find an \"else\" after the \"if\", so abort\n fBreak = true;\n break;\n }\n /*\n * If we're still here, we'll execute the \"else\" command (which is just a no-op),\n * followed by any remaining commands.\n */\n }\n }\n if (!this.cpu.isRunning()) fBreak = true;\n }\n if (fBreak) {\n if (!fTemporary) this.printBreakpoint(aBreak, i, \"hit\");\n break;\n }\n }\n }\n }\n\n this.nSuppressBreaks--;\n\n return fBreak;\n }\n\n /**\n * getAccOutput(iAcc)\n *\n * @this {DebuggerPDP10}\n * @param {number} iAcc\n * @return {string}\n */\n getAccOutput(iAcc)\n {\n var sReg = Str.toOct(iAcc, 2);\n this.setAddr(this.dbgAddrAcc, iAcc);\n sReg += '=' + this.toStrBase(this.getWord(this.dbgAddrAcc), 36) + ' ';\n return sReg;\n }\n\n /**\n * getRegOutput(iReg)\n *\n * @this {DebuggerPDP10}\n * @param {number} iReg\n * @return {string}\n */\n getRegOutput(iReg)\n {\n var sReg = this.getRegName(iReg);\n if (sReg) {\n var nBits = (iReg >= DebuggerPDP10.REGS.OV? 1 : (iReg == DebuggerPDP10.REGS.RA? 23 : 18));\n sReg += '=' + this.toStrBase(this.getRegValue(iReg), nBits) + ' ';\n }\n return sReg;\n }\n\n /**\n * getMiscDump()\n *\n * @this {DebuggerPDP10}\n * @return {string}\n */\n getMiscDump()\n {\n var sDump = \"\";\n for (var i = 0; i < DebuggerPDP10.REGNAMES.length; i++) {\n sDump += this.getRegOutput(i);\n }\n return sDump;\n }\n\n /**\n * getRegDump(fMisc)\n *\n * For now, fMisc defaults to true, providing a full register dump by default.\n *\n * @this {DebuggerPDP10}\n * @param {boolean|undefined} [fMisc] (true to include misc registers)\n * @return {string}\n */\n getRegDump(fMisc = true)\n {\n var sDump = \"\";\n for (var i = 0; i < 16; i++) {\n if (i && !(i & 3)) sDump += '\\n';\n sDump += this.getAccOutput(i);\n }\n if (fMisc) sDump += '\\n' + this.getMiscDump();\n return sDump;\n }\n\n /**\n * comparePairs(p1, p2)\n *\n * @this {DebuggerPDP10}\n * @param {number|string|Array|Object} p1\n * @param {number|string|Array|Object} p2\n * @return {number}\n */\n comparePairs(p1, p2)\n {\n return p1[0] > p2[0]? 1 : p1[0] < p2[0]? -1 : 0;\n }\n\n /**\n * addSymbols(sModule, addr, len, aSymbols)\n *\n * As filedump.js (formerly convrom.php) explains, aSymbols is a JSON-encoded object whose properties consist\n * of all the symbols (in upper-case), and the values of those properties are objects containing any or all of\n * the following properties:\n *\n * 'v': the value of an absolute (unsized) value\n * 'b': either 1, 2, 4 or undefined if an unsized value\n * 's': either a hard-coded segment or undefined\n * 'o': the offset of the symbol within the associated address space\n * 'l': the original-case version of the symbol, present only if it wasn't originally upper-case\n * 'a': annotation for the specified offset; eg, the original assembly language, with optional comment\n *\n * To that list of properties, we also add:\n *\n * 'p': the physical address (calculated whenever both 's' and 'o' properties are defined)\n *\n * Note that values for any 'v', 'b', 's' and 'o' properties are unquoted decimal values, and the values\n * for any 'l' or 'a' properties are quoted strings. Also, if double-quotes were used in any of the original\n * annotation ('a') values, they will have been converted to two single-quotes, so we're responsible for\n * converting them back to individual double-quotes.\n *\n * For example:\n * {\n * 'HF_PORT': {\n * 'v':800\n * },\n * 'HDISK_INT': {\n * 'b':4, 's':0, 'o':52\n * },\n * 'ORG_VECTOR': {\n * 'b':4, 's':0, 'o':76\n * },\n * 'CMD_BLOCK': {\n * 'b':1, 's':64, 'o':66\n * },\n * 'DISK_SETUP': {\n * 'o':3\n * },\n * '.40': {\n * 'o':40, 'a':\"MOV AX,WORD PTR ORG_VECTOR ;GET DISKETTE VECTOR\"\n * }\n * }\n *\n * If a symbol only has an offset, then that offset value can be assigned to the symbol property directly:\n *\n * 'DISK_SETUP': 3\n *\n * The last property is an example of an \"anonymous\" entry, for offsets where there is no associated symbol.\n * Such entries are identified by a period followed by a unique number (usually the offset of the entry), and\n * they usually only contain offset ('o') and annotation ('a') properties. I could eliminate the leading\n * period, but it offers a very convenient way of quickly discriminating among genuine vs. anonymous symbols.\n *\n * We add all these entries to our internal symbol table, which is an array of 4-element arrays, each of which\n * look like:\n *\n * [addr, len, aSymbols, aOffsets]\n *\n * There are two basic symbol operations: findSymbol(), which takes an address and finds the symbol, if any,\n * at that address, and findSymbolAddr(), which takes a string and attempts to match it to a non-anonymous\n * symbol with a matching offset ('o') property.\n *\n * To implement findSymbol() efficiently, addSymbols() creates an array of [offset, sSymbol] pairs\n * (aOffsets), one pair for each symbol that corresponds to an offset within the specified address space.\n *\n * We guarantee the elements of aOffsets are in offset order, because we build it using binaryInsert();\n * it's quite likely that the MAP file already ordered all its symbols in offset order, but since they're\n * hand-edited files, we can't assume that, and we need to ensure that findSymbol()'s binarySearch() operates\n * properly.\n *\n * @this {DebuggerPDP10}\n * @param {string|null} sModule\n * @param {number|null} addr (physical address where the symbols are located, if the memory is physical; eg, ROM)\n * @param {number} len (the size of the region, in bytes)\n * @param {Object} aSymbols (collection of symbols in this group; the format of this collection is described below)\n */\n addSymbols(sModule, addr, len, aSymbols)\n {\n var dbgAddr = {};\n var aOffsets = [];\n for (var sSymbol in aSymbols) {\n var symbol = aSymbols[sSymbol];\n if (typeof symbol == \"number\") {\n aSymbols[sSymbol] = symbol = {'o': symbol};\n }\n var offSymbol = symbol['o'];\n var sAnnotation = symbol['a'];\n if (offSymbol !== undefined) {\n Usr.binaryInsert(aOffsets, [offSymbol >>> 0, sSymbol], this.comparePairs);\n }\n if (sAnnotation) symbol['a'] = sAnnotation.replace(/''/g, \"\\\"\");\n }\n var symbolTable = {\n sModule: sModule,\n addr: addr,\n len: len,\n aSymbols: aSymbols,\n aOffsets: aOffsets\n };\n this.aSymbolTable.push(symbolTable);\n }\n\n /**\n * dumpSymbols()\n *\n * TODO: Add \"numerical\" and \"alphabetical\" dump options. This is simply dumping them in whatever\n * order they appeared in the original MAP file.\n *\n * @this {DebuggerPDP10}\n */\n dumpSymbols()\n {\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n for (var sSymbol in symbolTable.aSymbols) {\n if (sSymbol.charAt(0) == '.') continue;\n var symbol = symbolTable.aSymbols[sSymbol];\n var offSymbol = symbol['o'];\n if (offSymbol === undefined) continue;\n var sSymbolOrig = symbolTable.aSymbols[sSymbol]['l'];\n if (sSymbolOrig) sSymbol = sSymbolOrig;\n this.println(this.toStrOffset(offSymbol) + ' ' + sSymbol);\n }\n }\n }\n\n /**\n * findSymbol(dbgAddr, fNearest)\n *\n * Search aSymbolTable for dbgAddr, and return an Array for the corresponding symbol (empty if not found).\n *\n * If fNearest is true, and no exact match was found, then the Array returned will contain TWO sets of\n * entries: [0]-[3] will refer to closest preceding symbol, and [4]-[7] will refer to the closest subsequent symbol.\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @param {boolean} [fNearest]\n * @return {Array} where [0] == symbol name, [1] == symbol value, [2] == any annotation, and [3] == any associated comment\n */\n findSymbol(dbgAddr, fNearest)\n {\n var aSymbol = [];\n var addrSymbol = this.getAddr(dbgAddr) >>> 0;\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n var addr = symbolTable.addr >>> 0;\n var len = symbolTable.len;\n if (addrSymbol >= addr && addrSymbol < addr + len) {\n var offSymbol = addrSymbol - addr;\n var result = Usr.binarySearch(symbolTable.aOffsets, [offSymbol], this.comparePairs);\n if (result >= 0) {\n this.returnSymbol(iTable, result, aSymbol);\n }\n else if (fNearest) {\n result = ~result;\n this.returnSymbol(iTable, result-1, aSymbol);\n this.returnSymbol(iTable, result, aSymbol);\n }\n break;\n }\n }\n return aSymbol;\n }\n\n /**\n * findSymbolAddr(sSymbol)\n *\n * Search our symbol tables for sSymbol, and if found, return a dbgAddr (same as parseAddr()).\n *\n * @this {DebuggerPDP10}\n * @param {string} sSymbol\n * @return {DbgAddrPDP10|undefined}\n */\n findSymbolAddr(sSymbol)\n {\n var dbgAddr, offSymbol;\n\n if (sSymbol.match(/^[a-z_][a-z0-9_]*$/i)) {\n var sUpperCase = sSymbol.toUpperCase();\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n var symbol = symbolTable.aSymbols[sUpperCase];\n if (symbol != null) {\n offSymbol = symbol['o'];\n /*\n * If the symbol matched but there's no 'o' offset (ie, it wasn't for an address), there's\n * no point looking any farther, since each symbol appears only once.\n *\n * NOTE: We assume that every ROM is ORG'ed at 0x0000, and therefore unless the symbol has an\n * explicitly-defined segment, we return the segment associated with the entire group; for a ROM,\n * that segment is normally \"addrROM >>> 4\". Down the road, we may want/need to support a special\n * symbol entry (eg, \".ORG\") that defines an alternate origin.\n */\n break;\n }\n }\n }\n if (offSymbol != null) {\n dbgAddr = this.newAddr(offSymbol);\n }\n return dbgAddr;\n }\n\n /**\n * loadImage(aWords, addrStart)\n *\n * @this {DebuggerPDP10}\n * @param {Array.<number>} aWords\n * @param {number|null|undefined} addrStart\n */\n loadImage(aWords, addrStart)\n {\n var bus = this.bus;\n var dbg = this.dbg;\n var nWords = 0, addrLo = null, addrHi = 0;\n aWords.forEach(function(w, addr) {\n bus.setWord(addr, w);\n if (addrLo == null) addrLo = addr;\n if (addr > addrHi) addrHi = addr;\n nWords++;\n });\n if (!nWords) {\n this.println(\"no data\");\n } else {\n var sStart = \"start address \";\n if (addrStart != null) {\n this.cpu.setPC(addrStart);\n sStart += this.toStrBase(addrStart);\n } else {\n sStart += \"unspecified\";\n }\n this.println(nWords + \" words loaded at \" + this.toStrBase(addrLo) + '-' + this.toStrBase(addrHi) + \", \" + sStart);\n this.updateStatus();\n }\n }\n\n /**\n * returnSymbol(iTable, iOffset, aSymbol)\n *\n * Helper function for findSymbol().\n *\n * @this {DebuggerPDP10}\n * @param {number} iTable\n * @param {number} iOffset\n * @param {Array} aSymbol is updated with the specified symbol, if it exists\n */\n returnSymbol(iTable, iOffset, aSymbol)\n {\n var symbol = {};\n var aOffsets = this.aSymbolTable[iTable].aOffsets;\n var offset = 0, sSymbol = null;\n if (iOffset >= 0 && iOffset < aOffsets.length) {\n offset = aOffsets[iOffset][0];\n sSymbol = aOffsets[iOffset][1];\n }\n if (sSymbol) {\n symbol = this.aSymbolTable[iTable].aSymbols[sSymbol];\n sSymbol = (sSymbol.charAt(0) == '.'? null : (symbol['l'] || sSymbol));\n }\n aSymbol.push(sSymbol);\n aSymbol.push(offset);\n aSymbol.push(symbol['a']);\n aSymbol.push(symbol['c']);\n }\n\n /**\n * doHelp()\n *\n * @this {DebuggerPDP10}\n */\n doHelp()\n {\n var s = \"commands:\";\n for (var sCommand in DebuggerPDP10.COMMANDS) {\n s += '\\n' + Str.pad(sCommand, 9) + DebuggerPDP10.COMMANDS[sCommand];\n }\n if (!this.checksEnabled()) s += \"\\nnote: history disabled if no exec breakpoints\";\n this.println(s);\n }\n\n /**\n * doAssemble(asArgs)\n *\n * This always receives the complete argument array, where the order of the arguments is:\n *\n * [0]: the assemble command (assumed to be \"a\")\n * [1]: the target address (eg, \"200\")\n * [2]: the opcode mnemonic (eg, \"hrli\")\n * [3]: the operands, if any\n *\n * The Debugger enters \"assemble mode\" whenever only the first (or first and second) arguments are present.\n * As long as \"assemble mode is active, the user can omit the first two arguments on all later assemble commands\n * until \"assemble mode\" is cancelled with an empty command line; the command processor automatically prepends \"a\"\n * and the next available target address to the argument array.\n *\n * Entering \"assemble mode\" is optional; one could enter a series of fully-qualified assemble commands; eg:\n *\n * a 100 hrli 1,111111\n * a 101 hrri 1,444444\n * ...\n *\n * without ever entering \"assemble mode\", but of course, that requires more typing and doesn't take advantage\n * of automatic target address advancement (see dbgAddrAssemble).\n *\n * When filename(s) or URL(s) are provided in lieu of an opcode, we pass those on to the Macro10 component for\n * assembling (multiple files must be separated by semicolons), along with any option letters that were included\n * with the \"a\" command; for example, if \"ap\" was specified, then \"p\" will be passed to Macro10 as an option.\n *\n * See the Macro10 component for a list of supported options.\n *\n * When assembling a file, the target address determines the initial location counter for the assembly process,\n * but that can always be overridden by a LOC (or RELOC) pseudo-op in the file. The target address will also be\n * used as the starting address unless that's overridden by an END pseudo-op. In the absence of a target address,\n * the location counter starts at zero, and the starting address defaults to the PC register.\n *\n * @this {DebuggerPDP10}\n * @param {Array.<string>} asArgs is the complete argument array, beginning with the \"a\" command in asArgs[0]\n * @return {boolean}\n */\n doAssemble(asArgs)\n {\n var sOptions = asArgs[0].substr(1);\n var sAddr = asArgs[1] && asArgs[1][0] >= '0' && asArgs[1][0] <= '9'? asArgs[1] : undefined;\n var sOpcode = sAddr? asArgs[2] : asArgs[1];\n var dbgAddr = this.parseAddr(sAddr, this.dbgAddrAssemble);\n\n if (!sOpcode) {\n this.println(\"begin assemble at \" + this.toStrAddr(dbgAddr));\n this.fAssemble = true;\n this.cmp.updateDisplays();\n return true;\n }\n\n var match = sOpcode.match(/^(['\"]?)(.*?)(\\.klm|\\.mac|\\.html|\\.txt|)\\1$/i);\n if (match && (match[1] || match[3])) {\n var dbg = this;\n var cpu = this.cpu;\n dbgAddr = this.parseAddr(sAddr);\n if (this.macro10) {\n dbg.println(\"assembly already in progress\");\n }\n else {\n var sFile = match[2] + match[3];\n if (!match[3]) sOptions += 's';\n var addrLoad = dbgAddr.addr;\n var macro10 = this.macro10 = new Macro10(dbg);\n macro10.assembleFiles(sFile, addrLoad, sOptions, function doneMacro10(nErrorCode, sURL) {\n if (!nErrorCode) {\n /*\n * NOTE: Most Debugger operations run in the context of doCommand(), which catches any exceptions;\n * however, this callback may be running in a different context (eg, a network request callback), so\n * better safe than sorry.\n */\n try {\n var addrStart = macro10.getStart();\n if (addrStart == null) addrStart = addrLoad;\n dbg.loadImage(macro10.getImage(), addrStart);\n } catch(e) {\n if (typeof e == \"number\") {\n nErrorCode = e || -1;\n } else {\n dbg.println(e.message);\n nErrorCode = -1; // fake error so that command processing stops\n }\n }\n }\n if (nErrorCode) {\n dbg.println(\"error (\" + nErrorCode + \") processing \" + (sURL || sFile));\n }\n dbg.macro10 = null;\n if (!nErrorCode) dbg.doCommands();\n });\n }\n return false;\n }\n\n asArgs.shift();\n asArgs.shift();\n asArgs.shift();\n var sOperands = asArgs.join(\"\");\n var opCode = this.parseInstruction(sOpcode, sOperands, dbgAddr.addr || 0);\n\n if (opCode >= 0) {\n this.setWord(dbgAddr, opCode);\n this.println(this.getInstruction(dbgAddr));\n }\n return true;\n }\n\n /**\n * doBreak(sCmd, sAddr, sOptions)\n *\n * As the \"help\" output below indicates, the following breakpoint commands are supported:\n *\n * bp # set exec breakpoint\n * br # set read breakpoint\n * bw # set write breakpoint\n * bc # clear breakpoint (* to clear all)\n * bl list all breakpoints\n * bn [#] break after # instruction(s)\n *\n * The \"bn\" command, like the \"dh\" command and all other commands that use an instruction count,\n * assumes a decimal value, regardless of the current base. Use \"bn\" without an argument to display\n * the break count, and use \"bn 0\" to clear the break count.\n *\n * @this {DebuggerPDP10}\n * @param {string} sCmd\n * @param {string|undefined} [sAddr]\n * @param {string} [sOptions] (the rest of the breakpoint command-line)\n */\n doBreak(sCmd, sAddr, sOptions)\n {\n if (sAddr == '?') {\n this.println(\"breakpoint commands:\");\n this.println(\"\\tbp #\\tset exec breakpoint\");\n this.println(\"\\tbr #\\tset read breakpoint\");\n this.println(\"\\tbw #\\tset write breakpoint\");\n this.println(\"\\tbc #\\tclear breakpoint (* to clear all)\");\n this.println(\"\\tbl\\tlist all breakpoints\");\n this.println(\"\\tbn [#]\\tbreak after # instruction(s)\");\n return;\n }\n\n var sParm = sCmd.charAt(1);\n if (sParm == 'l') {\n var cBreaks = 0;\n cBreaks += this.listBreakpoints(this.aBreakExec);\n cBreaks += this.listBreakpoints(this.aBreakRead);\n cBreaks += this.listBreakpoints(this.aBreakWrite);\n if (!cBreaks) this.println(\"no breakpoints\");\n return;\n }\n\n if (sParm == 'n') {\n var n = +sAddr || 0;\n if (sAddr) this.nBreakInstructions = n;\n this.println(\"break after \" + n + \" instruction(s)\");\n return;\n }\n\n if (sAddr === undefined) {\n this.println(\"missing breakpoint address\");\n return;\n }\n\n var dbgAddr = sAddr == '*'? this.newAddr() : this.parseAddr(sAddr, this.dbgAddrCode);\n\n if (sParm == 'c') {\n if (dbgAddr.addr == null) {\n this.clearBreakpoints();\n this.println(\"all breakpoints cleared\");\n return;\n }\n if (this.findBreakpoint(this.aBreakExec, dbgAddr, true))\n return;\n if (this.findBreakpoint(this.aBreakRead, dbgAddr, true))\n return;\n if (this.findBreakpoint(this.aBreakWrite, dbgAddr, true))\n return;\n this.println(\"breakpoint missing: \" + this.toStrAddr(dbgAddr));\n return;\n }\n\n if (dbgAddr.addr == null) return;\n\n this.parseAddrOptions(dbgAddr, sOptions);\n\n if (sParm == 'p') {\n this.addBreakpoint(this.aBreakExec, dbgAddr);\n return;\n }\n if (sParm == 'r') {\n this.addBreakpoint(this.aBreakRead, dbgAddr);\n return;\n }\n if (sParm == 'w') {\n this.addBreakpoint(this.aBreakWrite, dbgAddr);\n return;\n }\n this.println(\"unknown breakpoint command: \" + sParm);\n }\n\n /**\n * doClear(sCmd)\n *\n * @this {DebuggerPDP10}\n * @param {string} [sCmd] (eg, \"cls\" or \"clear\")\n */\n doClear(sCmd)\n {\n this.cmp.clearPanel();\n }\n\n /**\n * doDump(asArgs)\n *\n * @this {DebuggerPDP10}\n * @param {Array.<string>} asArgs (formerly sCmd, [sAddr], [sLen] and [sBytes])\n */\n doDump(asArgs)\n {\n var m;\n var sCmd = asArgs[0];\n var sAddr = asArgs[1];\n var sLen = asArgs[2];\n var sBytes = asArgs[3];\n\n if (sAddr == '?') {\n var sDumpers = \"\";\n for (m in MessagesPDP10.CATEGORIES) {\n if (this.afnDumpers[m]) {\n if (sDumpers) sDumpers += ',';\n sDumpers = sDumpers + m;\n }\n }\n sDumpers += \",state,symbols\";\n this.println(\"dump memory commands:\");\n this.println(\"\\tdw [a] [n] dump n words at address a\");\n this.println(\"\\tds [a] [n] dump n words at address a as JSON\");\n this.println(\"\\tdh [p] [n] dump n instructions from history position p\");\n if (sDumpers.length) this.println(\"dump extension commands:\\n\\t\" + sDumpers);\n return;\n }\n\n if (sAddr == \"state\") {\n var sState = this.cmp.powerOff(true);\n if (sLen == \"console\") {\n /*\n * Console buffers are notoriously small, and even the following code, which breaks the\n * data into parts (eg, \"d state console 1\", \"d state console 2\", etc) just isn't that helpful.\n *\n * var nPart = +sBytes;\n * if (nPart) sState = sState.substr(1000000 * (nPart-1), 1000000);\n *\n * So, the best way to capture a large machine state is to use the new \"Save Machine\" link\n * that downloads a machine's entire state. Alternatively, run your own local server and use\n * server-side storage. Take a look at the \"Save\" binding in computer.js, which binds an HTML\n * control to the computer.powerOff() and computer.saveServerState() functions.\n */\n console.log(sState);\n } else {\n this.doClear();\n if (sState) this.println(sState);\n }\n return;\n }\n\n if (sAddr == \"symbols\") {\n this.dumpSymbols();\n return;\n }\n\n if (sCmd == \"d\") {\n for (m in MessagesPDP10.CATEGORIES) {\n if (asArgs[1] == m) {\n var fnDumper = this.afnDumpers[m];\n if (fnDumper) {\n asArgs.shift();\n asArgs.shift();\n fnDumper(asArgs);\n } else {\n this.println(\"no dump registered for \" + sAddr);\n }\n return;\n }\n }\n if (!sAddr) sCmd = this.sCmdDumpPrev || \"dw\";\n } else {\n this.sCmdDumpPrev = sCmd;\n }\n\n if (sCmd == \"dh\") {\n this.dumpHistory(sAddr, sLen);\n return;\n }\n\n var len = 0;\n var fJSON = (sCmd == \"ds\");\n var dbgAddr = this.parseAddr(sAddr, this.dbgAddrData);\n\n if (sLen) {\n if (sLen.charAt(0) == 'l') {\n sLen = sLen.substr(1) || sBytes;\n len = this.parseValue(sLen);\n }\n else {\n var dbgAddrEnd = this.parseAddr(sLen);\n len = dbgAddrEnd.addr - dbgAddr.addr;\n }\n if (len < 0) len = 0;\n if (len > 0x10000) len = 0x10000;\n }\n\n var nBase = this.nBase;\n if (dbgAddr.nBase) this.nBase = dbgAddr.nBase;\n\n var size = (sCmd == \"db\"? 1 : 2);\n var nWords = len || 32;\n var nWordsPerLine = (size == 1? 1 : 4);\n var nLines = (((nWords + nWordsPerLine - 1) / nWordsPerLine)|0) || 1;\n\n var sDump = \"\";\n while (nLines-- && nWords > 0) {\n var sData = \"\", sChars = \"\";\n sAddr = this.toStrAddr(dbgAddr);\n var n = nWordsPerLine;\n while (n-- > 0 && nWords-- > 0) {\n var w = this.getWord(dbgAddr, 1);\n if (fJSON) {\n if (sData) sData += ',';\n sData += w;\n } else {\n sData += this.toStrWord(w);\n sData += ' ';\n }\n /*\n * TODO: Provide some UI for choosing whether to dump SIXBIT or ASCII data.\n */\n var nBits = 7;\n var shift = 36 - nBits;\n for (var i = 0; size == 1 && shift >= 0; i++) {\n var c = ((w / Math.pow(2, shift)) % Math.pow(2, nBits));\n sData += this.toStrBase(c, nBits) + ' ';\n c += (nBits == 6? 0x20 : 0);\n sChars += (c < 0x20? '.' : String.fromCharCode(c));\n shift -= nBits;\n }\n }\n if (sDump) sDump += \"\\n\";\n if (fJSON) {\n sDump += sData + \",\";\n } else {\n sDump += sAddr + \": \" + sData + ((n < 0)? (' ' + sChars) : \"\");\n }\n }\n\n if (sDump) this.println(sDump);\n\n this.nBase = nBase;\n }\n\n /**\n * doEdit(asArgs)\n *\n * @this {DebuggerPDP10}\n * @param {Array.<string>} asArgs\n */\n doEdit(asArgs)\n {\n var fnGet, fnSet;\n var sCmd = asArgs[0];\n var sAddr = asArgs[1];\n if (sCmd == \"e\" || sCmd == \"ew\") {\n fnGet = this.getWord;\n fnSet = this.setWord;\n } else {\n sAddr = null;\n }\n if (sAddr == null) {\n this.println(\"edit memory commands:\");\n this.println(\"\\tew [a] [...] edit words at address a\");\n return;\n }\n var dbgAddr = this.parseAddr(sAddr, this.dbgAddrData);\n for (var i = 2; i < asArgs.length; i++) {\n var w = this.parseExpression(asArgs[i]);\n if (w === undefined) break;\n w = this.validateWord(w);\n this.println(\"changing \" + this.toStrAddr(dbgAddr) + \" from \" + this.toStrWord(fnGet.call(this, dbgAddr)) + \" to \" + this.toStrWord(w));\n fnSet.call(this, dbgAddr, w, 1);\n }\n }\n\n /**\n * doHalt(fQuiet)\n *\n * @this {DebuggerPDP10}\n * @param {boolean} [fQuiet]\n */\n doHalt(fQuiet)\n {\n var sMsg;\n if (this.flags.running) {\n if (!fQuiet) this.println(\"halting\");\n this.stopCPU();\n } else {\n if (this.isBusy(true)) return;\n if (!fQuiet) this.println(\"already halted\");\n }\n }\n\n /**\n * doIf(sCmd, fQuiet)\n *\n * NOTE: Don't forget that the default base for all numeric constants is 16 (hex), so when you evaluate\n * an expression like \"a==10\", it will compare the value of the variable \"a\" to 0x10; use a trailing period\n * (eg, \"10.\") if you really intend decimal.\n *\n * Also, if no variable named \"a\" exists, \"a\" will evaluate to 0x0A, so the expression \"a==10\" becomes\n * \"0x0A==0x10\" (false), whereas the expression \"a==10.\" becomes \"0x0A==0x0A\" (true).\n *\n * @this {DebuggerPDP10}\n * @param {string} sCmd\n * @param {boolean} [fQuiet]\n * @return {boolean} true if expression is non-zero, false if zero (or undefined due to a parse error)\n */\n doIf(sCmd, fQuiet)\n {\n sCmd = Str.trim(sCmd);\n if (!this.parseExpression(sCmd)) {\n if (!fQuiet) this.println(\"false: \" + sCmd);\n return false;\n }\n if (!fQuiet) this.println(\"true: \" + sCmd);\n return true;\n }\n\n /**\n * doInfo(asArgs)\n *\n * @this {DebuggerPDP10}\n * @param {Array.<string>} asArgs\n * @return {boolean} true only if the instruction info command (\"n\") is supported\n */\n doInfo(asArgs)\n {\n if (DEBUG) {\n this.println(\"msPerYield: \" + this.cpu.msPerYield);\n this.println(\"nCyclesPerYield: \" + this.cpu.nCyclesPerYield);\n return true;\n }\n return false;\n }\n\n /**\n * doVar(sCmd)\n *\n * The command must be of the form \"{variable} = [{expression}]\", where expression may contain constants,\n * operators, registers, symbols, other variables, or nothing at all; in the latter case, the variable, if\n * any, is deleted.\n *\n * Other supported shorthand: \"var\" with no parameters prints the values of all variables, and \"var {variable}\"\n * prints the value of the specified variable.\n *\n * @this {DebuggerPDP10}\n * @param {string} sCmd\n * @return {boolean} true if valid \"var\" assignment, false if not\n */\n doVar(sCmd)\n {\n var a = sCmd.match(/^\\s*([A-Z_]?[A-Z0-9_]*)\\s*(=?)\\s*(.*)$/i);\n if (a) {\n if (!a[1]) {\n if (!this.printVariable()) this.println(\"no variables\");\n return true; // it's not considered an error to print an empty list of variables\n }\n if (!a[2]) {\n return this.printVariable(a[1]);\n }\n if (!a[3]) {\n this.delVariable(a[1]);\n return true; // it's not considered an error to delete a variable that didn't exist\n }\n var v = this.parseExpression(a[3]);\n if (v !== undefined) {\n this.setVariable(a[1], v);\n return true;\n }\n return false;\n }\n this.println(\"invalid assignment:\" + sCmd);\n return false;\n }\n\n /**\n * doList(sAddr, fPrint)\n *\n * @this {DebuggerPDP10}\n * @param {string} sAddr\n * @param {boolean} [fPrint]\n * @return {string|null}\n */\n doList(sAddr, fPrint)\n {\n var sSymbol = null;\n\n var dbgAddr = this.parseAddr(sAddr);\n var addr = this.getAddr(dbgAddr);\n var aSymbol = this.findSymbol(dbgAddr, true);\n if (aSymbol.length) {\n var nDelta, sDelta, s;\n if (aSymbol[0]) {\n sDelta = \"\";\n nDelta = dbgAddr.addr - aSymbol[1];\n if (nDelta) sDelta = \" + \" + Str.toHexWord(nDelta);\n s = aSymbol[0] + \" (\" + this.toStrOffset(aSymbol[1]) + ')' + sDelta;\n if (fPrint) this.println(s);\n sSymbol = s;\n }\n if (aSymbol.length > 4 && aSymbol[4]) {\n sDelta = \"\";\n nDelta = aSymbol[5] - dbgAddr.addr;\n if (nDelta) sDelta = \" - \" + Str.toHexWord(nDelta);\n s = aSymbol[4] + \" (\" + this.toStrOffset(aSymbol[5]) + ')' + sDelta;\n if (fPrint) this.println(s);\n if (!sSymbol) sSymbol = s;\n }\n } else {\n if (fPrint) this.println(\"no symbols\");\n }\n return sSymbol;\n }\n\n /**\n * doMessages(asArgs)\n *\n * @this {DebuggerPDP10}\n * @param {Array.<string>} asArgs\n */\n doMessages(asArgs)\n {\n var m;\n var fCriteria = null;\n var sCategory = asArgs[1];\n if (sCategory == '?') sCategory = undefined;\n\n if (sCategory !== undefined) {\n var bitsMessage = 0;\n if (sCategory == \"all\") {\n bitsMessage = (0xffffffff|0) & ~(MessagesPDP10.HALT | MessagesPDP10.KEYS | MessagesPDP10.LOG);\n sCategory = null;\n } else if (sCategory == \"on\") {\n fCriteria = true;\n sCategory = null;\n } else if (sCategory == \"off\") {\n fCriteria = false;\n sCategory = null;\n } else {\n /*\n * Internally, we use \"key\" instead of \"keys\", since the latter is a method on JavasScript objects,\n * but externally, we allow the user to specify \"keys\"; \"kbd\" is also allowed as shorthand for \"keyboard\".\n */\n if (sCategory == \"keys\") sCategory = \"key\";\n if (sCategory == \"kbd\") sCategory = \"keyboard\";\n for (m in MessagesPDP10.CATEGORIES) {\n if (sCategory == m) {\n bitsMessage = MessagesPDP10.CATEGORIES[m];\n fCriteria = !!(this.bitsMessage & bitsMessage);\n break;\n }\n }\n if (!bitsMessage) {\n this.println(\"unknown message category: \" + sCategory);\n return;\n }\n }\n if (bitsMessage) {\n if (asArgs[2] == \"on\") {\n this.bitsMessage |= bitsMessage;\n fCriteria = true;\n }\n else if (asArgs[2] == \"off\") {\n this.bitsMessage &= ~bitsMessage;\n fCriteria = false;\n if (bitsMessage == MessagesPDP10.BUFFER) {\n var i = this.aMessageBuffer.length >= 1000? this.aMessageBuffer.length - 1000 : 0;\n while (i < this.aMessageBuffer.length) {\n this.println(this.aMessageBuffer[i++]);\n }\n this.aMessageBuffer = [];\n }\n }\n }\n }\n\n /*\n * Display those message categories that match the current criteria (on or off)\n */\n var n = 0;\n var sCategories = \"\";\n for (m in MessagesPDP10.CATEGORIES) {\n if (!sCategory || sCategory == m) {\n var bitMessage = MessagesPDP10.CATEGORIES[m];\n var fEnabled = !!(this.bitsMessage & bitMessage);\n if (fCriteria !== null && fCriteria != fEnabled) continue;\n if (sCategories) sCategories += ',';\n if (!(++n % 10)) sCategories += \"\\n\\t\"; // jshint ignore:line\n /*\n * Internally, we use \"key\" instead of \"keys\", since the latter is a method on JavasScript objects,\n * but externally, we allow the user to specify \"keys\".\n */\n if (m == \"key\") m = \"keys\";\n sCategories += m;\n }\n }\n\n if (sCategory === undefined) {\n this.println(\"message commands:\\n\\tm [category] [on|off]\\tturn categories on/off\");\n }\n\n this.println((fCriteria !== null? (fCriteria? \"messages on: \" : \"messages off: \") : \"message categories:\\n\\t\") + (sCategories || \"none\"));\n\n this.historyInit(); // call this just in case MessagesPDP10.INT was turned on\n }\n\n /**\n * doOptions(asArgs)\n *\n * @this {DebuggerPDP10}\n * @param {Array.<string>} asArgs\n */\n doOptions(asArgs)\n {\n switch (asArgs[1]) {\n\n case \"base\":\n if (asArgs[2]) {\n var nBase = +asArgs[2];\n if (nBase == 2 || nBase == 8 || nBase == 10 || nBase == 16) {\n this.nBase = nBase;\n } else {\n this.println(\"invalid base: \" + nBase);\n break;\n }\n }\n this.println(\"default base: \" + this.nBase);\n break;\n\n case \"cs\":\n var nCycles;\n if (asArgs[3] !== undefined) nCycles = +asArgs[3]; // warning: decimal instead of hex conversion\n switch (asArgs[2]) {\n case \"int\":\n this.cpu.nCyclesChecksumInterval = nCycles;\n break;\n case \"start\":\n this.cpu.nCyclesChecksumStart = nCycles;\n break;\n case \"stop\":\n this.cpu.nCyclesChecksumStop = nCycles;\n break;\n default:\n this.println(\"unknown cs option\");\n return;\n }\n if (nCycles !== undefined) {\n this.cpu.resetChecksum();\n }\n this.println(\"checksums \" + (this.cpu.flags.checksum? \"enabled\" : \"disabled\"));\n return;\n\n case \"sp\":\n if (asArgs[2] !== undefined) {\n if (!this.cpu.setSpeed(+asArgs[2])) {\n this.println(\"warning: using 1x multiplier, previous target not reached\");\n }\n }\n this.println(\"target speed: \" + this.cpu.getSpeedTarget() + \" (\" + this.cpu.getSpeed() + \"x)\");\n return;\n\n default:\n if (asArgs[1]) {\n this.println(\"unknown option: \" + asArgs[1]);\n return;\n }\n /* falls through */\n\n case \"?\":\n this.println(\"debugger options:\");\n this.println(\"\\tbase #\\t\\tset default base to #\");\n this.println(\"\\tcs int #\\tset checksum cycle interval to #\");\n this.println(\"\\tcs start #\\tset checksum cycle start count to #\");\n this.println(\"\\tcs stop #\\tset checksum cycle stop count to #\");\n this.println(\"\\tsp #\\t\\tset speed multiplier to #\");\n break;\n }\n }\n\n /**\n * doRegisters(asArgs, fInstruction)\n *\n * @this {DebuggerPDP10}\n * @param {Array.<string>} [asArgs]\n * @param {boolean} [fInstruction] (true to include the current instruction; default is true)\n */\n doRegisters(asArgs, fInstruction)\n {\n if (asArgs && asArgs[1] == '?') {\n this.println(\"register commands:\");\n this.println(\"\\tr\\tdump registers\");\n this.println(\"\\trm\\tdump misc registers\");\n this.println(\"\\trx [#]\\tset flag or register x to [#]\");\n return;\n }\n\n var cpu = this.cpu;\n var fMisc = undefined;\n if (fInstruction == null) fInstruction = true;\n\n if (asArgs != null && asArgs.length > 1) {\n var sReg = asArgs[1];\n\n if (sReg == 'm') {\n fMisc = true;\n }\n else {\n var sValue = null;\n var i = sReg.indexOf('=');\n if (i > 0) {\n sValue = sReg.substr(i + 1);\n sReg = sReg.substr(0, i);\n }\n else if (asArgs.length > 2) {\n sValue = asArgs[2];\n }\n else {\n this.println(\"missing value for \" + asArgs[1]);\n return;\n }\n\n var value = this.parseExpression(sValue);\n if (value === undefined) return;\n\n var iReg = this.getRegIndex(sReg);\n if (iReg < 0) {\n this.println(\"unknown register: \" + sReg);\n return;\n }\n\n this.setRegValue(iReg, value);\n\n this.cmp.updateDisplays();\n this.println(\"updated registers:\");\n }\n }\n\n this.println(this.getRegDump(fMisc));\n\n if (fInstruction) {\n this.setAddr(this.dbgAddrCode, cpu.getXC());\n this.doUnassemble(this.toStrAddr(this.dbgAddrCode));\n }\n }\n\n /**\n * doRun(sCmd, sAddr, sOptions, fQuiet)\n *\n * @this {DebuggerPDP10}\n * @param {string} sCmd\n * @param {string|undefined} [sAddr]\n * @param {string} [sOptions] (the rest of the breakpoint command-line)\n * @param {boolean} [fQuiet]\n */\n doRun(sCmd, sAddr, sOptions, fQuiet)\n {\n if (sAddr !== undefined) {\n var dbgAddr = this.parseAddr(sAddr);\n this.parseAddrOptions(dbgAddr, sOptions);\n this.setTempBreakpoint(dbgAddr);\n }\n this.startCPU(true, fQuiet);\n }\n\n /**\n * doPrint(sCmd)\n *\n * NOTE: If the string to print is a quoted string, then we run it through replaceRegs(), so that\n * you can take advantage of all the special replacement options used for software interrupt logging.\n *\n * @this {DebuggerPDP10}\n * @param {string} sCmd\n */\n doPrint(sCmd)\n {\n sCmd = Str.trim(sCmd);\n var a = sCmd.match(/^(['\"])(.*?)\\1$/);\n if (!a) {\n this.parseExpression(sCmd, false);\n } else {\n if (a[2].length > 1) {\n this.println(this.replaceRegs(a[2]));\n } else {\n this.printValue(null, a[2].charCodeAt(0));\n }\n }\n }\n\n /**\n * doStep(sCmd, sOption)\n *\n * @this {DebuggerPDP10}\n * @param {string} [sCmd] \"p\" or \"pr\"\n * @param {string} [sOption]\n */\n doStep(sCmd, sOption)\n {\n var fCallStep = true;\n var nRegs = (sCmd == \"p\"? 0 : (sCmd == \"pr\"? 1 : -1));\n\n if (sOption == '?' || nRegs < 0) {\n this.println(\"step commands:\");\n this.println(\"\\tp\\tstep over instruction\");\n this.println(\"\\tpr\\tstep over instruction with register update\");\n return;\n }\n\n /*\n * Set up the value for this.nStep (ie, 1 or 2) depending on whether the user wants\n * a subsequent register dump (\"pr\") or not (\"p\").\n */\n var nStep = 1 + nRegs;\n\n if (!this.nStep) {\n var dbgAddr = this.newAddr(this.cpu.getPC());\n var opCode = this.getWord(dbgAddr);\n\n if (this.nStep) {\n this.setTempBreakpoint(dbgAddr);\n if (!this.startCPU()) {\n if (this.cmp) this.cmp.setFocus();\n this.nStep = 0;\n }\n /*\n * A successful run will ultimately call stop(), which will in turn call clearTempBreakpoint(),\n * which will clear nStep, so there's your assurance that nStep will be reset. Now we may have\n * stopped for reasons unrelated to the temporary breakpoint, but that's OK.\n */\n } else {\n this.doTrace(nRegs? \"tr\" : \"t\");\n }\n } else {\n this.println(\"step in progress\");\n }\n }\n\n /**\n * getCall(dbgAddr)\n *\n * Given a possible return address (typically from the stack), look for a matching CALL (or INT) that\n * immediately precedes that address.\n *\n * @this {DebuggerPDP10}\n * @param {DbgAddrPDP10} dbgAddr\n * @return {string|null} CALL instruction at or near dbgAddr, or null if none\n */\n getCall(dbgAddr)\n {\n var sCall = null;\n var addr = dbgAddr.addr;\n var addrOrig = addr;\n for (var n = 1; n <= 6 && !!addr; n++) {\n if (n > 2) {\n dbgAddr.addr = addr;\n var s = this.getInstruction(dbgAddr);\n if (s.indexOf(\"JSR\") >= 0) {\n /*\n * Verify that the length of this call, when added to the address of the call, matches\n * the original return address. We do this by getting the string index of the opcode bytes,\n * subtracting that from the string index of the next space, and dividing that difference\n * by two, to yield the length of the CALL (or INT) instruction, in bytes.\n */\n var i = s.indexOf(' ');\n var j = s.indexOf(' ', i+1);\n if (addr + (j - i - 1)/2 == addrOrig) {\n sCall = s;\n break;\n }\n }\n }\n addr -= 2;\n }\n dbgAddr.addr = addrOrig;\n return sCall;\n }\n\n /**\n * doStackTrace(sCmd, sAddr)\n *\n * Use \"k\" for a normal stack trace and \"ks\" for a stack trace with symbolic info.\n *\n * @this {DebuggerPDP10}\n * @param {string} [sCmd]\n * @param {string} [sAddr] (not used yet)\n */\n doStackTrace(sCmd, sAddr)\n {\n if (sAddr == '?') {\n this.println(\"stack trace commands:\");\n this.println(\"\\tk\\tshow frame addresses\");\n this.println(\"\\tks\\tshow symbol information\");\n return;\n }\n\n var nFrames = 10, cFrames = 0;\n var dbgAddrCall = this.newAddr();\n var dbgAddrStack = this.newAddr(/*this.cpu.getSP()*/);\n this.println(\"stack trace for \" + this.toStrAddr(dbgAddrStack));\n\n while (cFrames < nFrames) {\n var sCall = null, sCallPrev = null, cTests = 256;\n while ((dbgAddrStack.addr >>> 0) < 0x10000) {\n dbgAddrCall.addr = this.getWord(dbgAddrStack, 2);\n /*\n * Because we're using the auto-increment feature of getWord(), and because that will automatically\n * wrap the offset around the end of the segment, we must also check the addr property to detect the wrap.\n */\n if (dbgAddrStack.addr == null || !cTests--) break;\n if (dbgAddrCall.addr & 0x1) continue; // an odd address on the PDP-11 is not a valid instruction boundary\n sCall = this.getCall(dbgAddrCall);\n if (sCall) break;\n }\n /*\n * The sCallPrev check eliminates duplicate sequential calls, which are usually (but not always)\n * indicative of a false positive, in which case the previous call is probably bogus as well, but\n * at least we won't duplicate that mistake. Of course, there are always exceptions, recursion\n * being one of them, but it's rare that we're debugging recursive code.\n */\n if (!sCall || sCall == sCallPrev) break;\n var sSymbol = null;\n if (sCmd == \"ks\") {\n var a = sCall.match(/[0-9A-F]+$/);\n if (a) sSymbol = this.doList(a[0]);\n }\n sCall = Str.pad(sCall, 50) + \" ;\" + (sSymbol || \"stack=\" + this.toStrAddr(dbgAddrStack)); // + \" return=\" + this.toStrAddr(dbgAddrCall));\n this.println(sCall);\n sCallPrev = sCall;\n cFrames++;\n }\n if (!cFrames) this.println(\"no return addresses found\");\n }\n\n /**\n * doTrace(sCmd, sCount)\n *\n * The \"t\" and \"tr\" commands interpret the count as a number of instructions, and since\n * we call the Debugger's stepCPU() for each iteration, a single instruction includes\n * any/all prefixes; the CPU's stepCPU() treats prefixes as discrete operations. The only\n * difference between \"t\" and \"tr\": the former displays only the next instruction, while\n * the latter also displays the (updated) registers.\n *\n * The \"tc\" command interprets the count as a number of cycles rather than instructions,\n * allowing you to quickly execute large chunks of instructions with a single command; it\n * doesn't display anything until the the chunk has finished. \"tc 1\" is also a useful\n * command in that it doesn't inhibit interrupts like \"t\" or \"tr\" does.\n *\n * However, generally a more useful command is \"bn\", which allows you to break after some\n * number of instructions have been executed (as opposed to some number of cycles).\n *\n * @this {DebuggerPDP10}\n * @param {string} [sCmd] (\"t\", \"tc\", or \"tr\")\n * @param {string} [sCount] # of instructions to step\n */\n doTrace(sCmd, sCount)\n {\n if (sCount == '?') {\n this.println(\"trace commands:\");\n this.println(\"\\tt [#]\\ttrace # instructions\");\n this.println(\"\\ttr [#]\\ttrace # instructions with register updates\");\n this.println(\"\\ttc [#]\\ttrace # cycles\");\n this.println(\"note: bn [#] breaks after # instructions without updates\");\n return;\n }\n\n var dbg = this;\n var fRegs = (sCmd != \"t\");\n var nCount = this.parseValue(sCount, null, true) || 1;\n\n /*\n * We used to set nCycles to 1 when a count > 1 was specified, because nCycles set\n * to 0 used to mean \"execute the next instruction without checking for interrupts\".\n * Well, this machine's stepCPU() doesn't do that; it ALWAYS checks for interrupts,\n * so we should leave nCycles set to 0, so that if an interrupt is dispatched, we will\n * get to see the first instruction of the interrupt handler.\n */\n var nCycles = 0; // (nCount == 1? 0 : 1);\n\n if (sCmd == \"tc\") {\n nCycles = nCount;\n nCount = 1;\n }\n this.sCmdTracePrev = sCmd;\n\n Web.onCountRepeat(\n nCount,\n function onCountStep() {\n return dbg.setBusy(true) && dbg.stepCPU(nCycles, fRegs, false);\n },\n function onCountStepComplete() {\n /*\n * We explicitly called stepCPU() with fUpdateDisplays set to false, because repeatedly\n * calling updateDisplays() can be very slow, especially if a Control Panel is present with\n * displayLiveRegs enabled, so once the repeat count has been exhausted, we must perform\n * a final updateDisplays().\n */\n if (dbg.panel) dbg.panel.stop();\n dbg.cmp.updateDisplays(-1);\n dbg.setBusy(false);\n }\n );\n }\n\n /**\n * doUnassemble(sAddr, sAddrEnd, nLines)\n *\n * @this {DebuggerPDP10}\n * @param {string} [sAddr]\n * @param {string} [sAddrEnd]\n * @param {number} [nLines]\n */\n doUnassemble(sAddr, sAddrEnd, nLines)\n {\n var dbgAddr = this.parseAddr(sAddr, this.dbgAddrCode);\n\n if (nLines === undefined) nLines = 1;\n\n var nBytes = 0x100;\n if (sAddrEnd !== undefined) {\n\n if (sAddrEnd.charAt(0) == 'l') {\n var n = this.parseValue(sAddrEnd.substr(1));\n if (n != null) nLines = n;\n }\n else {\n var dbgAddrEnd = this.parseAddr(sAddrEnd);\n if (dbgAddrEnd.addr < dbgAddr.addr) return;\n\n nBytes = dbgAddrEnd.addr - dbgAddr.addr;\n if (!DEBUG && nBytes > 0x100) {\n /*\n * Limiting the amount of disassembled code to 256 bytes in non-DEBUG builds is partly to\n * prevent the user from wedging the browser by dumping too many lines, but also a recognition\n * that, in non-DEBUG builds, this.println() keeps print output buffer truncated to 8Kb anyway.\n */\n this.println(\"range too large\");\n return;\n }\n nLines = -1;\n }\n }\n\n var nPrinted = 0;\n\n while (nBytes > 0 && nLines--) {\n\n var nSequence = (this.isBusy(false) || this.nStep)? this.nCycles : null;\n var sComment = (nSequence != null? \"cycles\" : null);\n var aSymbol = this.findSymbol(dbgAddr);\n\n var addr = dbgAddr.addr; // we snap dbgAddr.addr *after* calling findSymbol(), which re-evaluates it\n\n if (aSymbol[0] && nLines) {\n if (!nPrinted && nLines || aSymbol[0].indexOf('+') < 0) {\n var sLabel = aSymbol[0] + ':';\n if (aSymbol[2]) sLabel += ' ' + aSymbol[2];\n this.println(sLabel);\n }\n }\n if (aSymbol[3]) {\n sComment = aSymbol[3];\n nSequence = null;\n }\n this.copyAddr(this.dbgAddrAssemble, dbgAddr);\n this.println(this.getInstruction(dbgAddr, sComment, nSequence));\n nBytes -= dbgAddr.addr - addr;\n nPrinted++;\n }\n }\n\n /**\n * splitArgs(sCmd, sDelim)\n *\n * @this {DebuggerPDP10}\n * @param {string} sCmd\n * @param {string} [sDelim]\n * @return {Array.<string>}\n */\n splitArgs(sCmd, sDelim = \" \")\n {\n var asArgs = [];\n var chQuote = \"\";\n var i = 0, iLast = 0;\n\n while (i < sCmd.length) {\n var ch = sCmd[i++];\n if (chQuote) {\n if (ch == chQuote) {\n chQuote = \"\";\n asArgs.push(sCmd.substr(iLast, i - iLast));\n iLast = i;\n }\n continue;\n }\n if (ch == '\"' || ch == \"'\") {\n chQuote = ch;\n continue;\n }\n if (sDelim.indexOf(ch) >= 0) {\n asArgs.push(sCmd.substr(iLast, i - iLast - 1));\n iLast = i;\n }\n }\n if (iLast < i) {\n asArgs.push(sCmd.substr(iLast, i - iLast));\n }\n\n asArgs[0] = asArgs[0].toLowerCase();\n if (asArgs && asArgs.length) {\n var s0 = asArgs[0];\n var ch0 = s0.charAt(0);\n for (i = 1; i < s0.length; i++) {\n ch = s0.charAt(i);\n if (ch0 == '?' || ch0 == 'r' || ch < 'a' || ch > 'z') {\n asArgs[0] = s0.substr(i);\n asArgs.unshift(s0.substr(0, i));\n break;\n }\n }\n }\n return asArgs;\n }\n\n /**\n * doCommand(sCmd, fQuiet)\n *\n * @this {DebuggerPDP10}\n * @param {string} sCmd\n * @param {boolean} [fQuiet]\n * @return {boolean} true if command processed, false if unrecognized\n */\n doCommand(sCmd, fQuiet)\n {\n var result = true;\n\n try {\n if (DEBUG && sCmd == \"test\") {\n this.doTest();\n return true;\n }\n if (!sCmd.length || sCmd == \"end\") {\n if (this.fAssemble) {\n this.println(\"ended assemble at \" + this.toStrAddr(this.dbgAddrAssemble));\n this.fAssemble = false;\n }\n sCmd = \"\";\n }\n else if (!fQuiet) {\n this.println(DebuggerPDP10.PROMPT + sCmd);\n }\n\n var ch = sCmd.charAt(0);\n if (ch == '\"' || ch == \"'\") return true;\n\n /*\n * Zap the previous message buffer to ensure the new command's output is not tossed out as a repeat.\n */\n this.sMessagePrev = null;\n\n /*\n * I've relaxed the !isBusy() requirement, to maximize our ability to issue Debugger commands externally.\n */\n if (this.isReady() /* && !this.isBusy(true) */ && sCmd.length > 0) {\n\n if (this.fAssemble) {\n sCmd = \"a \" + this.toStrAddr(this.dbgAddrAssemble) + ' ' + sCmd;\n }\n\n var fError = false;\n var asArgs = this.splitArgs(sCmd);\n\n switch (asArgs[0].charAt(0)) {\n case 'a':\n result = this.doAssemble(asArgs);\n break;\n case 'b':\n this.doBreak(asArgs[0], asArgs[1], sCmd);\n break;\n case 'c':\n this.doClear(asArgs[0]);\n break;\n case 'd':\n if (!COMPILED && sCmd == \"debug\") {\n window.DEBUG = true;\n this.println(\"DEBUG checks on\");\n break;\n }\n this.doDump(asArgs);\n break;\n case 'e':\n if (asArgs[0] == \"else\") break;\n this.doEdit(asArgs);\n break;\n case 'g':\n this.doRun(asArgs[0], asArgs[1], sCmd, fQuiet);\n break;\n case 'h':\n this.doHalt(fQuiet);\n break;\n case 'i':\n if (asArgs[0] == \"if\") {\n if (!this.doIf(sCmd.substr(2), fQuiet)) {\n result = false;\n }\n break;\n }\n fError = true;\n break;\n case 'k':\n this.doStackTrace(asArgs[0], asArgs[1]);\n break;\n case 'l':\n if (asArgs[0] == \"ln\") {\n this.doList(asArgs[1], true);\n break;\n }\n fError = true;\n break;\n case 'm':\n this.doMessages(asArgs);\n break;\n case 'p':\n if (asArgs[0] == \"print\") {\n this.doPrint(sCmd.substr(5));\n break;\n }\n this.doStep(asArgs[0], asArgs[1]);\n break;\n case 'r':\n if (sCmd == \"reset\") {\n if (this.cmp) this.cmp.reset();\n break;\n }\n this.doRegisters(asArgs);\n break;\n case 's':\n this.doOptions(asArgs);\n break;\n case 't':\n this.doTrace(asArgs[0], asArgs[1]);\n break;\n case 'u':\n this.doUnassemble(asArgs[1], asArgs[2], 8);\n break;\n case 'v':\n if (asArgs[0] == \"var\") {\n if (!this.doVar(sCmd.substr(3))) {\n result = false;\n }\n break;\n }\n if (asArgs[0] == \"ver\") {\n this.println((PDP10.APPNAME || \"PDP10\") + \" version \" + (XMLVERSION || PDP10.APPVERSION) + \" (\" + this.cpu.model + (PDP10.COMPILED? \",RELEASE\" : (PDP10.DEBUG? \",DEBUG\" : \",NODEBUG\")) + ')');\n this.println(Web.getUserAgent());\n break;\n }\n fError = true;\n break;\n case '?':\n if (asArgs[1]) {\n this.doPrint(sCmd.substr(1));\n break;\n }\n this.doHelp();\n break;\n case 'n':\n if (!COMPILED && sCmd == \"nodebug\") {\n window.DEBUG = false;\n this.println(\"DEBUG checks off\");\n break;\n }\n if (this.doInfo(asArgs)) break;\n /* falls through */\n default:\n fError = true;\n break;\n }\n if (fError) {\n this.println(\"unknown command: \" + sCmd);\n result = false;\n }\n }\n } catch(e) {\n this.println(\"Debugger \" + (e.stack || e.message));\n result = false;\n }\n return result;\n }\n\n /**\n * doCommands(sCmds, fSave)\n *\n * This function is now written so that if any async command, such as assemble ('a'), stopped the\n * flow of commands by returning false, it can call us from its callback handler with no arguments,\n * and command processing should continue where it left off.\n *\n * @this {DebuggerPDP10}\n * @param {string} [sCmds]\n * @param {boolean} [fSave]\n * @return {boolean} true if all commands processed, false if not\n */\n doCommands(sCmds, fSave)\n {\n if (sCmds != null) {\n this.aCommands = this.parseCommand(sCmds, fSave);\n }\n var sCmd;\n while (sCmd = this.aCommands.shift()) {\n if (!this.doCommand(sCmd)) return false;\n }\n return true;\n }\n\n /**\n * doTest()\n *\n * This function exercises the disassembler by performing look-ups for all possible operation codes\n * and displaying the results. It's not intended to be included in the compiled version of the Debugger\n * (DEBUG only).\n *\n * @this {DebuggerPDP10}\n */\n doTest()\n {\n if (MAXDEBUG) {\n var ops = {}, aOpXXX = [];\n var op, opXXX, opCode, sOperation;\n for (op = 0o00000; op <= 0o77774; op += 4) {\n opCode = op * Math.pow(2, 21);\n sOperation = this.findInstruction(opCode, false);\n if (!sOperation) continue;\n if (ops[sOperation] === undefined) {\n ops[sOperation] = op;\n } else {\n ops[sOperation] &= op;\n }\n opXXX = op >> 6;\n if (!aOpXXX[opXXX]) {\n aOpXXX[opXXX] = sOperation;\n } else if (aOpXXX[opXXX] != sOperation) {\n aOpXXX[opXXX] = \"XXX\";\n }\n }\n for (sOperation in ops) {\n op = ops[sOperation];\n this.println(Str.pad(sOperation + \":\", 8) + this.toStrWord(op * Math.pow(2, 21)));\n //\n // The following code leveraged the disassembler to generate opcode handlers.\n //\n // this.println(\"/**\");\n // this.println(\" * op\" + sOperation + \"(\" + this.toStrWord(op * Math.pow(2, 21)) + \")\");\n // this.println(\" *\");\n // this.println(\" * @this {CPUStatePDP10}\");\n // this.println(\" * @param {number} opCode\");\n // this.println(\" */\");\n // this.println(\"PDP10.op\" + sOperation + \" = function(opCode)\");\n // this.println(\"{\");\n // this.println(\" this.opUndefined(op);\");\n // this.println(\"};\\n\");\n }\n //\n // The following code generated an opcode dispatch table.\n //\n // this.println(\"PDP10.aOpXXX = [\");\n // for (opXXX = 0o000; opXXX <= 0o777; opXXX++) {\n // sOperation = aOpXXX[opXXX];\n // sOperation = sOperation? (\" PDP10.op\" + sOperation + \",\") : \" PDP10.opUndefined,\";\n // sOperation = Str.pad(sOperation, 32);\n // sOperation += \"// \" + Str.toOct(opXXX, 3, true) + \"xxx\";\n // this.println(sOperation);\n // }\n // this.println(\"];\");\n }\n }\n\n /**\n * DebuggerPDP10.init()\n *\n * This function operates on every HTML element of class \"debugger\", extracting the\n * JSON-encoded parameters for the Debugger constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Debugger component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeDbg = Component.getElementsByClass(document, PDP10.APPCLASS, \"debugger\");\n for (var iDbg = 0; iDbg < aeDbg.length; iDbg++) {\n var eDbg = aeDbg[iDbg];\n var parmsDbg = Component.getComponentParms(eDbg);\n var dbg = new DebuggerPDP10(parmsDbg);\n Component.bindComponentControls(dbg, eDbg, PDP10.APPCLASS);\n }\n }\n}\n\nif (DEBUGGER) {\n\n /*\n * NOTE: Every DebuggerPDP10 property from here to the first prototype function definition (initBus()) is\n * considered a \"class constant\"; most of them use our \"all-caps\" convention (and all of them SHOULD, but\n * that wouldn't help us catch any bugs).\n *\n * Technically, all of them should ALSO be preceded by a \"@const\" annotation, but that's a lot of work and it\n * really clutters the code. I wish the Closure Compiler had a way to annotate every definition with a given\n * section with a single annotation....\n */\n\n DebuggerPDP10.COMMANDS = {\n '?': \"help/print\",\n 'a [#]': \"assemble\", // TODO: Implement this command someday\n 'b [#]': \"breakpoint\", // multiple variations (use b? to list them)\n 'c': \"clear output\",\n 'd [#]': \"dump memory\", // additional syntax: d [#] [l#], where l# is a number of bytes to dump\n 'e [#]': \"edit memory\",\n 'g [#]': \"go [to #]\",\n 'h': \"halt\",\n 'if': \"eval expression\",\n 'int [#]': \"request interrupt\",\n 'k': \"stack trace\",\n \"ln\": \"list nearest symbol(s)\",\n 'm': \"messages\",\n 'p': \"step over\", // other variations: pr (step and dump registers)\n 'print': \"print expression\",\n 'r': \"dump/set registers\",\n 'reset': \"reset machine\",\n 's': \"set options\",\n 't [#]': \"trace\", // other variations: tr (trace and dump registers)\n 'u [#]': \"unassemble\",\n 'var': \"assign variable\",\n 'ver': \"print version\"\n };\n\n /*\n * CPU opcode IDs\n */\n DebuggerPDP10.OPS = {\n NONE: 0,\n HLL: 1, HLLZ: 2, HLLO: 3, HLLE: 4,\n HRL: 5, HRLZ: 6, HRLO: 7, HRLE: 8,\n HRR: 9, HRRZ: 10, HRRO: 11, HRRE: 12,\n HLR: 13, HLRZ: 14, HLRO: 15, HLRE: 16,\n MOVE: 17, MOVS: 18, MOVN: 19, MOVM: 20,\n EXCH: 21, BLT: 22, PUSH: 23, POP: 24,\n LDB: 25, DPB: 26, IBP: 27, ILDB: 28,\n IDPB: 29, SETZ: 30, SETO: 31, SETA: 32,\n SETCA: 33, SETM: 34, SETCM: 35, AND: 36,\n ANDCA: 37, ANDCM: 38, ANDCB: 39, IOR: 40,\n ORCA: 41, ORCM: 42, ORCB: 43, XOR: 44,\n EQV: 45, LSH: 46, LSHC: 47, ROT: 48,\n ROTC: 49, ADD: 50, SUB: 51, MUL: 52,\n IMUL: 53, DIV: 54, IDIV: 55, ASH: 56,\n ASHC: 57, FSC: 58, FADR: 59, FSBR: 60,\n FMPR: 61, FDVR: 62, DFN: 63, UFA: 64,\n FAD: 65, FSB: 66, FMP: 67, FDV: 68,\n AOBJP: 69, AOBJN: 70, CAI: 71, CAM: 72,\n JUMP: 73, SKIP: 74, AOJ: 75, AOS: 76,\n SOJ: 77, SOS: 78, TR: 79, TL: 80,\n TD: 81, TS: 82, XCT: 83, JFFO: 84,\n JFCL: 85, JSR: 86, JSP: 87, JRST: 88,\n JSA: 89, JRA: 90, PUSHJ: 91, POPJ: 92,\n BLKI: 93, DATAI: 94, BLKO: 95, DATAO: 96,\n CONO: 97, CONI: 98, CONSZ: 99, CONSO: 100,\n UUO: 101, JOV: 102, JCRY0: 103, JCRY1: 104,\n JCRY: 105, JFOV: 106, HALT: 107, JRSTF: 108,\n JEN: 109\n };\n\n /*\n * CPU opcode names, indexed by CPU opcode ordinal (above)\n */\n DebuggerPDP10.OPNAMES = [\n \".WORD\",\n \"HLL\", \"HLLZ\", \"HLLO\", \"HLLE\",\n \"HRL\", \"HRLZ\", \"HRLO\", \"HRLE\",\n \"HRR\", \"HRRZ\", \"HRRO\", \"HRRE\",\n \"HLR\", \"HLRZ\", \"HLRO\", \"HLRE\",\n \"MOVE\", \"MOVS\", \"MOVN\", \"MOVM\",\n \"EXCH\", \"BLT\", \"PUSH\", \"POP\",\n \"LDB\", \"DPB\", \"IBP\", \"ILDB\",\n \"IDPB\", \"SETZ\", \"SETO\", \"SETA\",\n \"SETCA\", \"SETM\", \"SETCM\", \"AND\",\n \"ANDCA\", \"ANDCM\", \"ANDCB\", \"IOR\",\n \"ORCA\", \"ORCM\", \"ORCB\", \"XOR\",\n \"EQV\", \"LSH\", \"LSHC\", \"ROT\",\n \"ROTC\", \"ADD\", \"SUB\", \"MUL\",\n \"IMUL\", \"DIV\", \"IDIV\", \"ASH\",\n \"ASHC\", \"FSC\", \"FADR\", \"FSBR\",\n \"FMPR\", \"FDVR\", \"DFN\", \"UFA\",\n \"FAD\", \"FSB\", \"FMP\", \"FDV\",\n \"AOBJP\", \"AOBJN\", \"CAI\", \"CAM\",\n \"JUMP\", \"SKIP\", \"AOJ\", \"AOS\",\n \"SOJ\", \"SOS\", \"TR\", \"TL\",\n \"TD\", \"TS\", \"XCT\", \"JFFO\",\n \"JFCL\", \"JSR\", \"JSP\", \"JRST\",\n \"JSA\", \"JRA\", \"PUSHJ\", \"POPJ\",\n \"BLKI\", \"DATAI\", \"BLKO\", \"DATAO\",\n \"CONO\", \"CONI\", \"CONSZ\", \"CONSO\",\n \"UUO\", \"JOV\", \"JCRY0\", \"JCRY1\",\n \"JCRY\", \"JFOV\", \"HALT\", 'JRSTF',\n \"JEN\"\n ];\n\n DebuggerPDP10.REGS = {\n PC: 0,\n RA: 1,\n EA: 2,\n PS: 3,\n OV: 4, // single-bit \"register\" representing the Overflow flag\n C0: 5, // single-bit \"register\" representing the Carry 0 flag\n C1: 6, // single-bit \"register\" representing the Carry 1 flag\n BI: 7, // single-bit \"register\" representing the Byte Interrupt flag\n ND: 8, // single-bit \"register\" representing the No Divide flag\n PD: 9, // single-bit \"register\" representing the Pushdown Overflow flag\n };\n\n DebuggerPDP10.REGNAMES = [\n \"PC\", \"RA\", \"EA\", \"PS\", \"OV\", \"C0\", \"C1\", \"BI\", \"ND\", \"PD\"\n ];\n\n /*\n * OPTABLE is a collection of masks, and each mask refers to a collection of opcode\n * patterns associated with that mask; the disassembler applies each mask to the opcode,\n * and when a masked opcode matches one of the associated patterns, the corresponding\n * instruction is considered a match.\n */\n DebuggerPDP10.OPTABLE = {\n [PDP10.OPCODE.OPUUO]: { // 0o70000\n 0o00000: DebuggerPDP10.OPS.UUO\n },\n [PDP10.OPCODE.OPMASK]: { // 0o77700\n 0o13000: DebuggerPDP10.OPS.UFA,\n 0o13100: DebuggerPDP10.OPS.DFN,\n 0o13200: DebuggerPDP10.OPS.FSC,\n 0o13300: DebuggerPDP10.OPS.IBP,\n 0o13400: DebuggerPDP10.OPS.ILDB,\n 0o13500: DebuggerPDP10.OPS.LDB,\n 0o13600: DebuggerPDP10.OPS.IDPB,\n 0o13700: DebuggerPDP10.OPS.DPB,\n 0o24000: DebuggerPDP10.OPS.ASH,\n 0o24100: DebuggerPDP10.OPS.ROT,\n 0o24200: DebuggerPDP10.OPS.LSH,\n 0o24300: DebuggerPDP10.OPS.JFFO,\n 0o24400: DebuggerPDP10.OPS.ASHC,\n 0o24500: DebuggerPDP10.OPS.ROTC,\n 0o24600: DebuggerPDP10.OPS.LSHC,\n 0o25000: DebuggerPDP10.OPS.EXCH,\n 0o25100: DebuggerPDP10.OPS.BLT,\n 0o25200: DebuggerPDP10.OPS.AOBJP,\n 0o25300: DebuggerPDP10.OPS.AOBJN,\n 0o25400: DebuggerPDP10.OPS.JRST, // includes HALT, JRSTF, and JEN\n 0o25500: DebuggerPDP10.OPS.JFCL, // includes JOV, JCRY0, JCRY1, JCRY, and JFOV\n 0o25600: DebuggerPDP10.OPS.XCT,\n 0o26000: DebuggerPDP10.OPS.PUSHJ,\n 0o26100: DebuggerPDP10.OPS.PUSH,\n 0o26200: DebuggerPDP10.OPS.POP,\n 0o26300: DebuggerPDP10.OPS.POPJ,\n 0o26400: DebuggerPDP10.OPS.JSR,\n 0o26500: DebuggerPDP10.OPS.JSP,\n 0o26600: DebuggerPDP10.OPS.JSA,\n 0o26700: DebuggerPDP10.OPS.JRA,\n },\n [PDP10.OPCODE.OPMODE]: { // 0o77400\n 0o14000: DebuggerPDP10.OPS.FAD,\n 0o14400: DebuggerPDP10.OPS.FADR,\n 0o15000: DebuggerPDP10.OPS.FSB,\n 0o15400: DebuggerPDP10.OPS.FSBR,\n 0o16000: DebuggerPDP10.OPS.FMP,\n 0o16400: DebuggerPDP10.OPS.FMPR,\n 0o17000: DebuggerPDP10.OPS.FDV,\n 0o17400: DebuggerPDP10.OPS.FDVR,\n 0o20000: DebuggerPDP10.OPS.MOVE,\n 0o20400: DebuggerPDP10.OPS.MOVS,\n 0o21000: DebuggerPDP10.OPS.MOVN,\n 0o21400: DebuggerPDP10.OPS.MOVM,\n 0o22000: DebuggerPDP10.OPS.IMUL,\n 0o22400: DebuggerPDP10.OPS.MUL,\n 0o23000: DebuggerPDP10.OPS.IDIV,\n 0o23400: DebuggerPDP10.OPS.DIV,\n 0o27000: DebuggerPDP10.OPS.ADD,\n 0o27400: DebuggerPDP10.OPS.SUB,\n 0o40000: DebuggerPDP10.OPS.SETZ, // MACRO alias: CLEAR\n 0o40400: DebuggerPDP10.OPS.AND,\n 0o41000: DebuggerPDP10.OPS.ANDCA,\n 0o41400: DebuggerPDP10.OPS.SETM,\n 0o42000: DebuggerPDP10.OPS.ANDCM,\n 0o42400: DebuggerPDP10.OPS.SETA,\n 0o43000: DebuggerPDP10.OPS.XOR,\n 0o43400: DebuggerPDP10.OPS.IOR, // MACRO alias: OR\n 0o44000: DebuggerPDP10.OPS.ANDCB,\n 0o44400: DebuggerPDP10.OPS.EQV,\n 0o45000: DebuggerPDP10.OPS.SETCA,\n 0o45400: DebuggerPDP10.OPS.ORCA,\n 0o46000: DebuggerPDP10.OPS.SETCM,\n 0o46400: DebuggerPDP10.OPS.ORCM,\n 0o47000: DebuggerPDP10.OPS.ORCB,\n 0o47400: DebuggerPDP10.OPS.SETO,\n 0o50000: DebuggerPDP10.OPS.HLL,\n 0o50400: DebuggerPDP10.OPS.HRL,\n 0o51000: DebuggerPDP10.OPS.HLLZ,\n 0o51400: DebuggerPDP10.OPS.HRLZ,\n 0o52000: DebuggerPDP10.OPS.HLLO,\n 0o52400: DebuggerPDP10.OPS.HRLO,\n 0o53000: DebuggerPDP10.OPS.HLLE,\n 0o53400: DebuggerPDP10.OPS.HRLE,\n 0o54000: DebuggerPDP10.OPS.HRR,\n 0o54400: DebuggerPDP10.OPS.HLR,\n 0o55000: DebuggerPDP10.OPS.HRRZ,\n 0o55400: DebuggerPDP10.OPS.HLRZ,\n 0o56000: DebuggerPDP10.OPS.HRRO,\n 0o56400: DebuggerPDP10.OPS.HLRO,\n 0o57000: DebuggerPDP10.OPS.HRRE,\n 0o57400: DebuggerPDP10.OPS.HLRE\n },\n [PDP10.OPCODE.OPCOMP]: { // 0o77000\n 0o30000: DebuggerPDP10.OPS.CAI,\n 0o31000: DebuggerPDP10.OPS.CAM,\n 0o32000: DebuggerPDP10.OPS.JUMP,\n 0o33000: DebuggerPDP10.OPS.SKIP,\n 0o34000: DebuggerPDP10.OPS.AOJ,\n 0o35000: DebuggerPDP10.OPS.AOS,\n 0o36000: DebuggerPDP10.OPS.SOJ,\n 0o37000: DebuggerPDP10.OPS.SOS,\n },\n [PDP10.OPCODE.OPTEST]: { // 0o71100\n 0o60000: DebuggerPDP10.OPS.TR,\n 0o60100: DebuggerPDP10.OPS.TL,\n 0o61000: DebuggerPDP10.OPS.TD,\n 0o61100: DebuggerPDP10.OPS.TS,\n },\n [PDP10.OPCODE.OPIO]: { // 0o70034\n 0o70000: DebuggerPDP10.OPS.BLKI,\n 0o70004: DebuggerPDP10.OPS.DATAI,\n 0o70010: DebuggerPDP10.OPS.BLKO,\n 0o70014: DebuggerPDP10.OPS.DATAO,\n 0o70020: DebuggerPDP10.OPS.CONO,\n 0o70024: DebuggerPDP10.OPS.CONI,\n 0o70030: DebuggerPDP10.OPS.CONSZ,\n 0o70034: DebuggerPDP10.OPS.CONSO\n }\n };\n\n DebuggerPDP10.OPMODES = [\"\", \"I\", \"M\", \"S\"];\n DebuggerPDP10.OPCOMPS = [\"\", \"L\", \"E\", \"LE\", \"A\", \"GE\", \"N\", \"G\"];\n DebuggerPDP10.OPTESTS = [\"N\", \"NE\", \"NA\", \"NN\", \"Z\", \"ZE\", \"ZA\", \"ZN\", \"C\", \"CE\", \"CA\", \"CN\", \"O\", \"OE\", \"OA\", \"ON\"];\n\n /*\n * Apparently, DEC's MACRO program permits \"JFCL xxx\" (with a single argument) as an alternate for \"JFCL 0,xxx\"\n * (which in turn is long-hand for \"No-op\", since JFCL with 0 does nothing).\n */\n DebuggerPDP10.JFCL = {\n 0o00: DebuggerPDP10.OPS.JFCL,\n 0o10: DebuggerPDP10.OPS.JOV,\n 0o04: DebuggerPDP10.OPS.JCRY0,\n 0o02: DebuggerPDP10.OPS.JCRY1,\n 0o06: DebuggerPDP10.OPS.JCRY,\n 0o01: DebuggerPDP10.OPS.JFOV\n };\n\n DebuggerPDP10.JRST = {\n 0o00: DebuggerPDP10.OPS.JRST,\n 0o04: DebuggerPDP10.OPS.HALT,\n 0o02: DebuggerPDP10.OPS.JRSTF,\n 0o12: DebuggerPDP10.OPS.JEN\n };\n\n DebuggerPDP10.ALTOPS = [\n DebuggerPDP10.JFCL, DebuggerPDP10.JRST\n ];\n\n DebuggerPDP10.HISTORY_LIMIT = DEBUG? 100000 : 1000;\n\n DebuggerPDP10.PROMPT = \">> \";\n\n /*\n * Initialize every Debugger module on the page (as IF there's ever going to be more than one ;-))\n */\n Web.onInit(DebuggerPDP10.init);\n\n} // endif DEBUGGER\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/macro10.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Elements of tblMacros.\n *\n * @typedef {{\n * name:(string),\n * nOperand:(number),\n * aParms:(Array.<string>),\n * aDefaults:(Array.<string>),\n * aValues:(Array.<string>),\n * sText:(string),\n * nLine:(number)\n * }}\n */\nvar Mac;\n\n/**\n * Elements of tblSymbols.\n *\n * @typedef {{\n * name:(string),\n * value:(number),\n * nType:(number),\n * nLine:(number)\n * }}\n */\nvar Sym;\n\n/**\n * Elements of aLiterals.\n *\n * @typedef {{\n * name:(string),\n * aWords:(Array.<number>),\n * aFixups:(Array.<string>)\n * }}\n */\nvar Lit;\n\n/**\n * Elements of stackScopes.\n *\n * @typedef {{\n * name:(string|undefined),\n * aWords:(Array.<number>),\n * aFixups:(Array.<string>),\n * nLocation:(number),\n * nLocationScope:(number),\n * nLine:(number)\n * }}\n */\nvar Scope;\n\n/**\n * @class Macro10\n * @property {string} sURL\n * @property {number|null} addrLoad\n * @property {string} sOptions\n * @property {DebuggerPDP10} dbg\n * @property {function(...)|undefined} done\n * @property {number} iURL\n * @property {Array.<string>} aURLs\n * @property {Array.<number>} anLines\n * @property {Array.<string>} asLines\n * @property {number|null|undefined} addrStart\n * @unrestricted\n */\nclass Macro10 {\n /**\n * Macro10(dbg)\n *\n * A \"mini\" version of DEC's MACRO-10 assembler, with just enough features to support the handful\n * of DEC diagnostic source code files that we choose to throw at it.\n *\n * We rely on the calling component (dbg) to provide a variety of helper services (eg, println(),\n * parseExpression(), etc). This is NOT a subclass of Component, so Component services are not part\n * of this class.\n *\n * @this {Macro10}\n * @param {DebuggerPDP10} dbg (used to provide helper services to the Macro10 class)\n */\n constructor(dbg)\n {\n this.dbg = dbg;\n }\n\n /**\n * init(addrLoad, sOptions, done)\n *\n * Initializes all instance properties. Called by assembleFiles() and assembleString().\n *\n * Supported options include:\n *\n * 'd': leave all symbols in the debugger's variable table\n * 'p': print the preprocessed resource(s) without assembling them\n * 'l': print lines as they are parsed\n * 's': treat the URL as a string and assemble it (assembleFiles() only)\n *\n * The done() callback is called after the resource(s) have been loaded (if necessary), parsed, and\n * assembled. The caller must use other methods to obtain further results (eg, getImage(), getStart()).\n *\n * The callback includes a non-zero error code if there was an error (and the URL):\n *\n * done(nErrorCode, sURL)\n *\n * @this {Macro10}\n * @param {number|null} [addrLoad] (the absolute address to assemble the code at, if any)\n * @param {string|undefined} [sOptions] (zero or more letter codes to control the assembly process)\n * @param {function(...)|undefined} [done]\n */\n init(addrLoad, sOptions, done)\n {\n this.addrLoad = addrLoad;\n this.sOptions = (sOptions || \"\").toLowerCase();\n this.done = done;\n\n this.iURL = 0;\n this.aURLs = [];\n\n /**\n * Number of lines per file.\n *\n * @type {Array.<number>}\n */\n this.anLines = [];\n\n /**\n * Lines from all the resources.\n *\n * @type {Array.<string>}\n */\n this.asLines = [];\n\n if (MAXDEBUG) this.println(\"starting PCjs MACRO-10 Mini-Assembler...\");\n\n /*\n * Initialize all the tables and other data structures that MACRO-10 uses.\n *\n * The Macros (tblMacros) and Symbols (tblSymbols) tables are fairly straightforward: they are\n * indexed by a macro or symbol name, and each element is a Mac or Sym object, respectively.\n *\n * We also treat REPEAT blocks and CONDITIONAL (eg, IFE) blocks like macros, except that they are\n * anonymous, parameter-less, and immediately invoked. REPEAT blocks are always immediately invoked\n * (repeatedly, based on the repeat count), whereas CONDITIONAL blocks are either immediately\n * invoked if the associated condition is true or skipped if the condition is false.\n *\n * Finally, we have LITERAL blocks, which are semi-anonymous (we give each one an auto-generated\n * name based on the current location) and are automatically but not immediately invoked. Instead,\n * after we've finished processing all the lines in the original input file, we run through all\n * the LITERAL blocks in tblMacros and process the associated statement(s) at that time.\n *\n * Macros have the name that was assigned to them, REPEAT and conditional blocks have generated names\n * that match the pseudo-op (eg, \"?REPEAT\", \"?IFE\"), and LITERAL blocks have generated location-based\n * names. All generated names use a leading question mark ('?') so that they don't conflict with\n * normal MACRO-10 symbols.\n */\n\n /**\n * @type {Object.<Mac>}\n */\n this.tblMacros = {};\n\n /**\n * @type {Object.<Sym>}\n */\n this.tblSymbols = {};\n\n /**\n * @type {Array.<Lit>}\n */\n this.aLiterals = []; // array of literals\n\n /**\n * This keeps track of symbols suffixed with '#', which are later assembled into a variable pool,\n * following the literal pool.\n *\n * @type {Array.<string>}\n */\n this.aVariables = [];\n\n /**\n * @type {Array.<number>}\n */\n this.aWords = []; // filled in by the various genXXX() functions\n\n /**\n * This sparse array is indexed by location, and each used entry contains any undefined symbols that\n * must be evaluated to fully resolve the word at the corresponding location. NOTE: There's no requirement\n * that the array be sparse; we could certainly fill each unused entry with null (ie, for locations that\n * don't require a fixup).\n *\n * @type {Array.<string>}\n */\n this.aFixups = [];\n\n /**\n * This array parallels aFixups, providing context (ie, line numbers) for any fixups that we want to analyze.\n *\n * @type {Array.<number>}\n */\n this.aLineRefs = [];\n\n this.nLine = 0;\n this.nError = 0;\n this.nLiteral = 0; // used to uniquely number literals\n\n /**\n * @type {number}\n */\n this.nLocation = this.addrLoad || 0;\n\n /**\n * @type {number}\n */\n this.nLocationScope = -1;\n\n /**\n * @type {Array.<Scope>}\n */\n this.stackScopes = [];\n\n this.sOperator = null; // the active operator, if any\n this.nMacroDef = 0; // the active macro definition state\n this.sMacroDef = null; // the active macro definition name\n this.chMacroOpen = this.chMacroClose = '';\n\n /*\n * This regular expression breaks each MACRO-10 line into the following elements:\n *\n * [1]: label (with trailing colon), if any\n * [2]: operator (eg, opcode mnemonic or pseudo-op), if any\n * [3]: operator/operand whitespace separator, if any\n * [4]: operand(s), if any\n * [5]: comment, if any\n */\n this.reLine = /^[ \\t]*([A-Z$%.?][0-9A-Z$%.]*:|)[ \\t]*([A-Z$%.][0-9A-Z$%.]*|)([ \\t]*)([^;]+|)(;?[\\s\\S]*)/i;\n\n this.macroCall = null; // the active macro being called, if any\n\n /**\n * If an ASCII/ASCIZ/SIXBIT pseudo-op is active, chASCII is set to the separator\n * and sASCII collects the intervening character(s).\n *\n * @type {null|string}\n */\n this.chASCII = null;\n\n /**\n * @type {string}\n */\n this.sASCII = \"\";\n\n this.addrStart = null;\n }\n\n /**\n * assembleFiles(sURL, addrLoad, sOptions, done)\n *\n * Requests the resource(s) specified by sURL; multiple resources can be requested by separating\n * them with semicolons. The resources are requested and combined in the same order they are listed,\n * and after the last resource has been received, they are assembled as a single unit.\n *\n * As a courtesy to the Debugger's doAssemble() function, we allow it to select between assembleFiles()\n * and assembleString() by specifying an 's' option here, rather than having two separate code paths.\n *\n * @this {Macro10}\n * @param {string} sURL (the URL(s) of the resource to be assembled)\n * @param {number|null} [addrLoad] (the absolute address to assemble the code at, if any)\n * @param {string|undefined} [sOptions] (zero or more letter codes to control the assembly process)\n * @param {function(...)|undefined} [done]\n */\n assembleFiles(sURL, addrLoad, sOptions, done)\n {\n if (sOptions && sOptions.indexOf('s') >= 0) {\n this.assembleString(sURL, addrLoad, sOptions, done);\n return;\n }\n\n this.init(addrLoad, sOptions, done);\n\n this.aURLs = sURL.split(';');\n\n this.loadNextResource();\n }\n\n /**\n * assembleString(sText, addrLoad, sOptions, done)\n *\n * Assembles the given text.\n *\n * @this {Macro10}\n * @param {string} sText\n * @param {number|null} [addrLoad] (the absolute address to assemble the code at, if any)\n * @param {string|undefined} [sOptions] (zero or more letter codes to control the assembly process)\n * @param {function(...)|undefined} [done]\n * @return {number}\n */\n assembleString(sText, addrLoad, sOptions, done)\n {\n this.init(addrLoad, sOptions, done);\n\n this.asLines = sText.split(/(\\r?\\n)/);\n this.anLines.push(this.asLines.length);\n\n this.parseResources();\n\n if (this.done) this.done(this.nError);\n\n return this.nError;\n }\n\n /**\n * loadNextResource()\n *\n * @this {Macro10}\n */\n loadNextResource()\n {\n if (this.iURL == this.aURLs.length) {\n this.parseResources();\n if (this.done) this.done(this.nError);\n return;\n }\n\n var macro10 = this;\n var sURL = this.aURLs[this.iURL];\n\n this.println(\"loading \" + Str.getBaseName(sURL));\n\n /*\n * We know that local resources ending with \".MAC\" are actually stored with a \".txt\" extension.\n */\n if (sURL.indexOf(':') < 0) {\n var sExt = sURL.slice(-4).toUpperCase();\n if (\".MAC.KLM\".indexOf(sExt) >= 0) sURL += \".txt\";\n }\n\n Web.getResource(sURL, null, true, function processMacro10(sFile, sResource, nErrorCode) {\n if (nErrorCode) {\n if (macro10.done) macro10.done(nErrorCode, sFile);\n return;\n }\n var sText = sResource;\n if (Str.endsWith(sFile, \".html\")) {\n /*\n * We want to parse ONLY the text between <PRE>...</PRE> tags, and eliminate any HTML entities.\n */\n sText = \"\";\n var match, re = /<pre>([\\s\\S]*?)<\\/pre>/gi;\n while (match = re.exec(sResource)) {\n var s = match[1];\n if (s.indexOf('&') >= 0) s = s.replace(/</gi, '<').replace(/>/gi, '>').replace(/&/gi, '&');\n sText += s;\n }\n match = sText.match(/&[a-z]+;/i);\n if (match) macro10.warning(\"unrecognized HTML entity '\" + match[0] + \"'\");\n }\n\n /*\n * For a file containing N lines, split() will return an array of N*2+1 entries, with every even entry\n * containing the characters, if any, preceding a line-ending, and every odd entry (including the final\n * entry) containing a line-ending.\n *\n * If, for some reason, split() doesn't do that, then we try to warn and patch things up as best we can.\n */\n var asLines = sText.split(/(\\r?\\n)/);\n if (asLines.length & 1) {\n s = asLines.pop();\n if (s) {\n macro10.warning(\"unexpected line '\" + s + \"'\");\n asLines.push(s);\n asLines.push(\"\");\n }\n } else {\n macro10.warning(\"unexpected number of lines (\" + asLines.length + \")\");\n }\n\n macro10.asLines = macro10.asLines.concat(asLines);\n macro10.anLines[macro10.iURL] = (asLines.length >> 1);\n macro10.iURL++;\n\n setTimeout(function() {\n macro10.loadNextResource();\n }, 0);\n });\n }\n\n /**\n * getImage()\n *\n * Service for the Debugger to obtain the assembled data after a (hopefully) successful assembly process.\n *\n * @this {Macro10}\n * @return {Array.<number>}\n */\n getImage()\n {\n return this.aWords;\n }\n\n /**\n * getStart()\n *\n * Service for the Debugger to obtain the starting address after a (hopefully) successful assembly process.\n *\n * @this {Macro10}\n * @return {number|null|undefined}\n */\n getStart()\n {\n return this.addrStart;\n }\n\n /**\n * parseResources()\n *\n * Begin the assembly process.\n *\n * @this {Macro10}\n * @return {number}\n */\n parseResources()\n {\n var macro10 = this;\n\n /*\n * If the \"preprocess\" option is set, then print everything without assembling.\n */\n if (this.sOptions.indexOf('p') >= 0) {\n this.println(this.asLines.join(\"\"));\n return 0;\n }\n\n var a = this.dbg.resetVariables();\n\n /*\n * Add predefined device codes\n */\n this.addSymbol(\"APR\", 0); // Priority Interrupt\n this.addSymbol(\"PI\", 4); // Arithmetic Processor\n\n try {\n for (let i = 0; i < this.asLines.length; i += 2) {\n\n this.nLine++;\n\n /*\n * If the \"line\" option is set, then print all the lines as they are parsed.\n */\n if (this.sOptions.indexOf('l') >= 0) {\n this.println(this.getLineRef() + \": \" + this.asLines[i]);\n }\n\n /*\n * Since, at this early stage, I'm not sure whether all the resources I'm interested in\n * assembling have had their original CR/LF line endings preserved (eg, some files may have\n * been converted to LF-only line endings), I'm going to skip over whatever line endings\n * are in the array (stored in every OTHER entry) and insert my own uniform CR/LF sequences.\n */\n if (!this.parseLine(this.asLines[i] + '\\r\\n')) break;\n\n /*\n * When an END statement is encountered, addrStart will change from null to either undefined\n * or a starting address.\n */\n if (this.addrStart !== null) break;\n }\n\n if (this.nMacroDef) {\n this.error(\"open block\", this.tblMacros[this.sMacroDef].nLine);\n }\n\n if (this.stackScopes.length) {\n this.error(\"open scope\", this.stackScopes[0].nLine);\n }\n\n /*\n * Process all literals next.\n */\n this.doLiterals();\n\n /*\n * Process all variables next.\n */\n this.doVariables();\n\n /*\n * And last but not least, perform all fixups.\n */\n this.aFixups.forEach(function processFixup(sValue, nLocation) {\n let value = macro10.parseExpression(sValue, undefined, nLocation, macro10.aLineRefs[nLocation]);\n if (value === undefined) return;\n value += macro10.aWords[nLocation];\n macro10.aWords[nLocation] = macro10.truncate(value, nLocation);\n });\n\n } catch(err) {\n this.println(err.message);\n this.nError = -1;\n }\n\n if (this.sOptions.indexOf('d') < 0) this.dbg.restoreVariables(a);\n\n return this.nError;\n }\n\n /**\n * parseLine(sLine, aParms, aValues, aDefaults)\n *\n * @this {Macro10}\n * @param {string} sLine (line contents)\n * @param {Array.<string>} [aParms]\n * @param {Array.<string>} [aValues]\n * @param {Array.<string>} [aDefaults]\n * @return {boolean}\n */\n parseLine(sLine, aParms, aValues, aDefaults)\n {\n var i, matchLine;\n\n if (this.chASCII != null) {\n sLine = this.defASCII(sLine);\n }\n\n var fParse = true;\n var sLabel, sOperator = \"\", sSeparator, sOperands, sRemainder;\n\n while (fParse) {\n matchLine = sLine.match(this.reLine);\n if (!matchLine || matchLine[5] && matchLine[5].slice(0, 1) != ';') {\n this.error(\"failed to parse line '\" + sLine + \"'\");\n return false;\n }\n fParse = false;\n sOperator = matchLine[2].toUpperCase();\n\n /*\n * TODO: The following kludge needs to be fixed at some point. The goal here is to prevent any\n * of the caller's parameters from replacing any IRP/IRPC call parameters, but the goal is actually\n * much bigger than that, because it's not just IRP/IRPC call parameters that must be left intact,\n * but ANY macro call parameters; IRP/IRPC macros are just easier to pick out. Unfortunately, as\n * the code is currently structured, we won't know if we're dealing with any macro call parameters\n * on this line until parseMacro() is called, below.\n */\n if (sOperator == Macro10.PSEUDO_OP.IRP || sOperator == Macro10.PSEUDO_OP.IRPC) {\n aParms = null;\n }\n\n if (aParms) {\n for (var iParm = 0; iParm < aParms.length; iParm++) {\n var sParm = aParms[iParm];\n\n var macroDef = this.tblMacros[this.sMacroDef];\n if (macroDef && macroDef.aParms.indexOf(sParm) >= 0) continue;\n\n var sReplace = aValues[iParm] || aDefaults[iParm] || \"\";\n var iSearch = 0;\n var iLimit = sLine.length - matchLine[5].length; // set the limit at the start of the comment, if any\n while (iSearch < iLimit) {\n var iMatch = sLine.indexOf(sParm, iSearch);\n if (iMatch < 0) break;\n iSearch = iMatch + 1;\n var iMatchEnd = iMatch + sParm.length;\n var chPre = '', chPost = '';\n if ((!iMatch || !this.isSymbolChar(chPre = sLine[iMatch - 1])) && (iMatchEnd >= sLine.length || !this.isSymbolChar(chPost = sLine[iMatchEnd]))) {\n /*\n * If the \"concatenation character\" (') appears before (or after) the symbol being replaced, remove it.\n */\n if (chPre == \"'\") iMatch--;\n if (chPost == \"'\") iMatchEnd++;\n sLine = sLine.substr(0, iMatch) + sReplace + sLine.substr(iMatchEnd);\n iSearch = iMatch + sReplace.length;\n fParse = true;\n }\n }\n }\n aParms = null;\n }\n if (this.nMacroDef) {\n if (this.nMacroDef == 1) {\n i = sLine.indexOf(this.chMacroOpen);\n if (i >= 0) {\n this.nMacroDef++;\n sLine = sLine.substr(i+1);\n } else {\n this.error(\"expected \" + this.sOperator + \" definition in '\" + sLine + \"'\");\n }\n }\n if (this.nMacroDef > 1) {\n sLine = this.appendMacro(sLine);\n fParse = true;\n }\n if (this.nMacroDef) return true;\n }\n }\n\n sLabel = matchLine[1];\n sSeparator = matchLine[3];\n sOperands = matchLine[4].trim();\n sRemainder = matchLine[4] + matchLine[5];\n\n if (sLabel) {\n sLabel = sLabel.slice(0, -1);\n this.addSymbol(sLabel, this.nLocation, Macro10.SYMTYPE.LABEL);\n }\n\n var matchOp;\n if (sOperator && (matchOp = sOperands.match(/^([=:]+)(.*)/))) {\n var nType = 0;\n sLabel = sOperator;\n sOperator = matchOp[1];\n sOperands = matchOp[2];\n if (sOperator == '==') {\n nType |= Macro10.SYMTYPE.PRIVATE;\n }\n else if (sOperator == '=:') {\n nType |= Macro10.SYMTYPE.INTERNAL;\n }\n this.addSymbol(sLabel, sOperands, nType);\n sOperator = sOperands = \"\";\n }\n\n if (!sOperator && !sOperands) return true;\n\n this.sOperator = sOperator;\n\n /*\n * Check the operands for a literal. If the line contains and/or ends with a literal\n * we record it and replace it with an internal symbol. We assume only one literal per line,\n * especially since they can be open-ended (ie, continue for multiple lines).\n */\n var sLiteral = this.getLiteral(sOperands);\n if (sLiteral) {\n sOperands = sOperands.replace(sLiteral, this.defMacro(Macro10.PSEUDO_OP.LITERAL, this.getLiteral(sRemainder)));\n if (!sSeparator) sSeparator = \"\\t\";\n }\n\n /*\n * Check the operands for any reserved symbols (ie, symbols with a trailing '#', such as \"USER#\").\n */\n var sSymbol;\n while (sSymbol = this.getReserved(sOperands)) {\n sOperands = sOperands.replace(sSymbol, sSymbol.slice(0, -1));\n }\n\n if (!this.parseMacro(sOperator, sOperands)) {\n\n switch (sOperator) {\n case Macro10.PSEUDO_OP.ASCII:\n case Macro10.PSEUDO_OP.ASCIZ:\n case Macro10.PSEUDO_OP.SIXBIT:\n this.defASCII(sRemainder);\n break;\n\n case Macro10.PSEUDO_OP.BLOCK:\n this.defBLOCK(sOperands);\n break;\n\n case Macro10.PSEUDO_OP.BYTE:\n this.defBYTE(sOperands);\n break;\n\n case Macro10.PSEUDO_OP.END:\n this.defEND(sOperands);\n break;\n\n case Macro10.PSEUDO_OP.EXP:\n this.defWord(sOperands);\n break;\n\n case Macro10.PSEUDO_OP.LIT:\n this.doLiterals();\n break;\n\n case Macro10.PSEUDO_OP.LOC:\n this.defLocation(sOperands);\n break;\n\n case Macro10.PSEUDO_OP.VAR:\n this.doVariables();\n break;\n\n case Macro10.PSEUDO_OP.XWD:\n this.defXWD(sOperands);\n break;\n\n case Macro10.PSEUDO_OP.DEFINE:\n case Macro10.PSEUDO_OP.IF1:\n case Macro10.PSEUDO_OP.IFDEF:\n case Macro10.PSEUDO_OP.IFDIF:\n case Macro10.PSEUDO_OP.IFE:\n case Macro10.PSEUDO_OP.IFG:\n case Macro10.PSEUDO_OP.IFGE:\n case Macro10.PSEUDO_OP.IFIDN:\n case Macro10.PSEUDO_OP.IFL:\n case Macro10.PSEUDO_OP.IFLE:\n case Macro10.PSEUDO_OP.IFN:\n case Macro10.PSEUDO_OP.IFNDEF:\n case Macro10.PSEUDO_OP.IRP:\n case Macro10.PSEUDO_OP.IRPC:\n case Macro10.PSEUDO_OP.OPDEF:\n case Macro10.PSEUDO_OP.REPEAT:\n this.defMacro(sOperator, sRemainder);\n break;\n\n case Macro10.PSEUDO_OP.PURGE:\n this.delSymbols(sOperands);\n break;\n\n case Macro10.PSEUDO_OP.LALL: // TODO\n case Macro10.PSEUDO_OP.LIST: // TODO\n case Macro10.PSEUDO_OP.NOSYM: // TODO\n case Macro10.PSEUDO_OP.PAGE: // TODO\n case Macro10.PSEUDO_OP.SUBTTL: // TODO\n case Macro10.PSEUDO_OP.TITLE: // TODO\n case Macro10.PSEUDO_OP.XALL: // TODO\n case Macro10.PSEUDO_OP.XLIST: // TODO\n break;\n\n default:\n this.defWord(sOperator, sSeparator, sOperands);\n break;\n }\n }\n return true;\n }\n\n /**\n * parseLiteral(name, sText)\n *\n * This is like parseText() except that we set up a new scope, including new aWords and aFixups arrays.\n *\n * @this {Macro10}\n * @param {string} name\n * @param {string} sText\n */\n parseLiteral(name, sText)\n {\n this.pushScope(name);\n this.parseText(sText);\n this.popScope();\n }\n\n /**\n * parseMacro(name, sOperands)\n *\n * For OPDEF macros, the operands are opcode values rather than conventional macro parameter values.\n * As the MACRO-10 manual explains:\n *\n * Defines the symbol as an operator equivalent to expression, giving the symbol a fullword value.\n * When the operator is later used with operands, the accumulator fields are added, the indirect bits\n * are ORed, the memory addresses are added, and the index register addresses are added.\n *\n * EXAMPLE: OPDEF CAL [MOVE 1,@SYM(2)]\n * CAL 1,BOL(2)\n *\n * RESULT: MOVE 2,@SYM+BOL(4)\n *\n * The easiest thing to do is parse the OPDEF text, allowing it to generate its default \"fullword value\",\n * then parse the operands in their own scope, extract the bits generated from the operands, and merge them\n * into the generated OPDEF value.\n *\n * @this {Macro10}\n * @param {string} name\n * @param {string} [sOperands]\n * @return {boolean}\n */\n parseMacro(name, sOperands)\n {\n var macro = this.tblMacros[name];\n if (!macro) return false;\n\n if (sOperands != null) {\n /*\n * If this is an OPDEF, then a two-step process is required: generate the OPDEF's value, then parse\n * the operands and merge their bits with the OPDEF's bits.\n */\n if (macro.nOperand == Macro10.MACRO_OP.OPDEF) {\n\n var nLocation = this.nLocation;\n this.parseText(macro.sText);\n if (nLocation < this.nLocation) {\n\n /*\n * An OPDEF invocation *may* have operands, but it's not required to.\n */\n if (!sOperands) return true;\n\n this.pushScope();\n this.parseText(sOperands);\n var w = this.aWords[0];\n var sFixup = this.aFixups[0];\n this.popScope();\n if (w !== undefined) {\n this.aWords[nLocation] += (w & (PDP10.OPCODE.A_FIELD | PDP10.OPCODE.X_FIELD | PDP10.OPCODE.Y_FIELD));\n /*\n * We can't \"OR\" (|=) the I_FIELD bit into the target word, because it's a 36-bit value and bitwise\n * operators truncate to 32 bits, so we'll use addition, trusting that the field was initially zero.\n */\n\n this.aWords[nLocation] += (w & PDP10.OPCODE.I_FIELD);\n if (sFixup) {\n if (!this.aFixups[nLocation]) {\n this.aFixups[nLocation] = sFixup;\n } else {\n this.aFixups[nLocation] += '+' + sFixup;\n }\n }\n return true;\n }\n }\n\n /*\n * Either the OPDEF didn't generate any data OR the OPDEF's operands failed to evaluate.\n */\n this.error(\"OPDEF '\" + name + \"' (\" + sOperands + \") failed\");\n return false;\n }\n var macroPrev = this.macroCall;\n this.macroCall = macro;\n macro.aValues = this.getValues(sOperands, true);\n this.parseText(macro.sText, macro.aParms, macro.aValues, macro.aDefaults);\n /*\n * WARNING: Our simplistic approach to macro expansion and processing means that recursive macros\n * (such as the SHIFT macro in /apps/pdp10/tests/macro10/TEXT.MAC) could blow the stack. Nothing bad\n * should happen (other than a JavaScript stack limit exception aborting the assembly), but it begs\n * the question: did MACRO-10 perform any tail recursion optimizations or other tricks to prevent macros\n * from gobbling stack, or could they blow MACRO-10's stack just as easily?\n */\n this.macroCall = macroPrev;\n return true;\n }\n\n if (name[0] != '?') return false;\n\n var sOperator = name.substr(1);\n\n switch(sOperator) {\n case Macro10.PSEUDO_OP.IFE:\n case Macro10.PSEUDO_OP.IFDIF:\n case Macro10.PSEUDO_OP.IFNDEF:\n if (!macro.nOperand) {\n this.parseText(macro.sText);\n }\n break;\n\n case Macro10.PSEUDO_OP.IFG:\n if (macro.nOperand > 0) {\n this.parseText(macro.sText);\n }\n break;\n\n case Macro10.PSEUDO_OP.IFGE:\n if (macro.nOperand >= 0) {\n this.parseText(macro.sText);\n }\n break;\n\n case Macro10.PSEUDO_OP.IFL:\n if (macro.nOperand < 0) {\n this.parseText(macro.sText);\n }\n break;\n\n case Macro10.PSEUDO_OP.IFLE:\n if (macro.nOperand <= 0) {\n this.parseText(macro.sText);\n }\n break;\n\n case Macro10.PSEUDO_OP.IF1:\n case Macro10.PSEUDO_OP.IFN:\n case Macro10.PSEUDO_OP.IFDEF:\n case Macro10.PSEUDO_OP.IFIDN:\n if (macro.nOperand) {\n this.parseText(macro.sText);\n }\n break;\n\n case Macro10.PSEUDO_OP.IRP:\n case Macro10.PSEUDO_OP.IRPC:\n for (let i = 0; i < macro.aValues.length; i++) {\n this.parseText(macro.sText, macro.aParms, [macro.aValues[i]], []);\n }\n break;\n\n case Macro10.PSEUDO_OP.REPEAT:\n while (macro.nOperand-- > 0) {\n this.parseText(macro.sText);\n }\n break;\n\n default:\n this.parseLiteral(name, macro.sText);\n break;\n }\n return true;\n }\n\n /**\n * parseText(sText, aParms, aValues, aDefaults)\n *\n * @this {Macro10}\n * @param {string} sText\n * @param {Array.<string>} [aParms]\n * @param {Array.<string>} [aValues]\n * @param {Array.<string>} [aDefaults]\n */\n parseText(sText, aParms, aValues, aDefaults)\n {\n /*\n * Unlike the caller of parseResources(), we don't split the text using a capture group,\n * so all line separators are tossed, and just like parseResources(), we always include a\n * uniform CR/LF sequence at the end of each line.\n *\n * TODO: Consider whether callers should always store their text snippets as line arrays, too,\n * to avoid this re-splitting.\n */\n var asLines = sText.split(/\\r?\\n/);\n for (var iLine = 0; iLine < asLines.length; iLine++) {\n var sLine = asLines[iLine] + '\\r\\n';\n if (!this.parseLine(sLine, aParms, aValues, aDefaults)) break;\n }\n }\n\n /**\n * pushScope(name)\n *\n * @this {Macro10}\n * @param {string} [name] (must be defined for literals only)\n */\n pushScope(name)\n {\n this.stackScopes.push({\n name,\n aWords: this.aWords,\n aFixups: this.aFixups,\n nLocation: this.nLocation,\n nLocationScope: this.nLocationScope,\n nLine: this.nLine\n });\n this.aWords = [];\n this.aFixups = [];\n if (this.nLocationScope < 0) this.nLocationScope = this.nLocation;\n this.nLocation = 0;\n }\n\n /**\n * popScope()\n *\n * @this {Macro10}\n */\n popScope()\n {\n if (!this.stackScopes.length) {\n this.error(\"scope nesting error\");\n return;\n }\n var name = this.stackScopes[this.stackScopes.length - 1].name;\n if (name) this.aLiterals.push({name, aWords: this.aWords, aFixups: this.aFixups});\n var scope = this.stackScopes.pop();\n this.aWords = scope.aWords;\n this.aFixups = scope.aFixups;\n this.nLocation = scope.nLocation;\n this.nLocationScope = scope.nLocationScope;\n if (!this.stackScopes.length && this.nLocationScope != -1) {\n this.error(\"scope restore error\");\n }\n }\n\n /**\n * getExpression(sOperands, sDelim)\n *\n * TODO: Add support for IFIDN, IFDIF, IFB and IFNB: if the first non-blank, non-tab character is\n * a character other than '<', then that becomes the delimiter, allowing angle brackets in the string.\n *\n * @this {Macro10}\n * @param {string} sOperands\n * @param {string} [sDelim] (eg, comma, closing parenthesis)\n * @return {string|null} (if the operands begin with an expression, return it)\n */\n getExpression(sOperands, sDelim = \",\")\n {\n var i = 0;\n var fQuotes = false;\n var sOperand = null;\n var cNesting = 0;\n while (i < sOperands.length) {\n var ch = sOperands[i++];\n if (ch == '\"') {\n fQuotes = !fQuotes;\n continue;\n }\n if (fQuotes) continue;\n if (!cNesting && sDelim.indexOf(ch) >= 0) {\n i--;\n break;\n }\n if (ch == '<') {\n cNesting++;\n } else if (ch == '>') {\n if (--cNesting < 0) {\n this.error(\"missing bracket(s) in '\" + sOperands + \"'\");\n break;\n }\n }\n }\n if (!cNesting) {\n sOperand = sOperands.substr(0, i);\n }\n else if (cNesting > 0) {\n this.error(\"extra bracket(s) in '\" + sOperands + \"'\");\n }\n return sOperand;\n }\n\n /**\n * parseExpression(sExp, aUndefined, nLocation, nLine)\n *\n * This is a wrapper around the Debugger's parseExpression() function to take care of some\n * additional requirements we have, such as interpreting a period as the current location and\n * interpreting two expressions separated by two commas as the left and right 18-bit halves\n * of a 36-bit value.\n *\n * @this {Macro10}\n * @param {string} sExp\n * @param {Array|undefined} [aUndefined]\n * @param {number|undefined} [nLocation]\n * @param {number|undefined} [nLine]\n * @return {number|undefined}\n */\n parseExpression(sExp, aUndefined, nLocation, nLine)\n {\n var result = -1;\n\n if (nLocation === undefined) {\n nLocation = (this.nLocationScope >= 0? this.nLocationScope : this.nLocation);\n }\n\n /*\n * The SIXBIT (and presumably ASCII; not sure about ASCIZ) pseudo-ops can also be used in expressions\n * (or at least assignments), so we check for those in the given expression and convert them to quoted\n * sequences that the Debugger's parseExpression() understands.\n */\n var sEval = sExp.replace(/SIXBIT\\s*(\\S)(.*?)\\1/g, \"'$2'\").replace(/ASCII\\s*(\\S)(.*?)\\1/g, '\"$2\"');\n\n /*\n * If this is NOT a first-pass call, then let's not waste time calling parseInstruction(); not only\n * may it generate redundant error messages, but it shouldn't be necessary, because we should be down\n * to fixup expressions.\n */\n if (aUndefined) {\n var match;\n var sOperator = \"\";\n var sOperands = sEval;\n if (match = sEval.match(/^([^\\s]+)\\s*(.*?)\\s*$/)) {\n sOperator = match[1];\n sOperands = match[2];\n }\n result = this.dbg.parseInstruction(sOperator, sOperands, nLocation, aUndefined);\n }\n\n if (result < 0) {\n /*\n * Check for the \"period\" syntax that MACRO-10 uses to represent the value of the current location.\n * The Debugger's parseInstruction() method understands that syntax, but its parseExpression() method\n * does not.\n *\n * Note that the Debugger's parseInstruction() replaces any period not PRECEDED by a decimal\n * digit with the current address, because our Debuggers' only other interpretation of a period\n * is as the suffix of a decimal integer, whereas MACRO-10's only other interpretation of a period\n * is (I think) as the decimal point within a floating-point number, so here we only replace periods\n * that are not FOLLOWED by a decimal digit.\n */\n sEval = sEval.replace(/\\.([^0-9]|$)/g, this.dbg.toStrBase(nLocation, -1) + \"$1\");\n result = this.dbg.parseExpression(sEval, aUndefined);\n if (result === undefined) {\n this.error(\"unable to parse expression '\" + sExp + \"'\", nLine);\n }\n }\n return result;\n }\n\n /**\n * getLiteral(sOperands)\n *\n * Check the operands for a literal (ie, an expression starting with a square bracket).\n *\n * @this {Macro10}\n * @param {string} sOperands\n * @return {string} (if the operands contain a literal, return it)\n */\n getLiteral(sOperands)\n {\n var cNesting = 0;\n var sLiteral = \"\";\n var i = 0, iBegin = -1, iEnd = sOperands.length;\n while (i < sOperands.length) {\n var ch = sOperands[i];\n if (ch == ';') break;\n if (ch == '[') {\n if (!cNesting++) iBegin = i;\n }\n i++;\n if (ch == ']' && --cNesting <= 0) {\n iEnd = i;\n break;\n }\n }\n if (cNesting < 0) {\n this.error(\"missing bracket(s) in '\" + sOperands + \"'\");\n }\n if (iBegin >= 0) {\n sLiteral = sOperands.substr(iBegin, iEnd - iBegin);\n }\n return sLiteral;\n }\n\n /**\n * getDefaults(aParms)\n *\n * Check the given array of macro parameters for default values, remove them, and return them in a parallel array.\n *\n * @this {Macro10}\n * @param {Array.<string>} aParms\n * @return {Array.<string>}\n */\n getDefaults(aParms)\n {\n var aDefaults = [];\n for (var i = 0; i < aParms.length; i++) {\n var j = aParms[i].indexOf('<');\n if (j >= 0) {\n var k = aParms[i].lastIndexOf('>');\n if (k < 0) k = aParms[i].length;\n aDefaults[i] = aParms[i].substr(j, k - j);\n aParms[i] = aParms[i].substr(0, j);\n }\n }\n return aDefaults;\n }\n\n /**\n * getLineRef(nLine)\n *\n * @this {Macro10}\n * @param {number|undefined} [nLine]\n * @return {string}\n */\n getLineRef(nLine = this.nLine)\n {\n var iURL = 0;\n while (nLine > this.anLines[iURL]) {\n nLine -= this.anLines[iURL];\n if (iURL < this.aURLs.length - 1) {\n iURL++;\n } else {\n break;\n }\n }\n return Str.getBaseName(this.aURLs[iURL] + \" line \" + nLine);\n }\n\n /**\n * getReserved(sOperands)\n *\n * Check the operands for any reserved symbols (ie, symbols with a trailing '#', such as \"USER#\").\n *\n * @this {Macro10}\n * @param {string} sOperands\n * @return {string|null} (if the operands contain a reserved symbol, return it)\n */\n getReserved(sOperands)\n {\n var match, sReserved = null;\n if (match = sOperands.match(/([A-Z$%.][0-9A-Z$%.]*)#/i)) {\n sReserved = match[0];\n var sLabel = match[1];\n var name = '?' + sLabel;\n /*\n * We now allow reserved symbols to reused (which would make sense if they appeared in a macro).\n */\n if (this.tblMacros[name] === undefined) {\n var aParms, aDefaults, aValues;\n aParms = aDefaults = aValues = [];\n this.tblMacros[name] = {\n name: name,\n nOperand: Macro10.MACRO_OP.RESERVED,\n aParms,\n aDefaults,\n aValues,\n sText: sLabel + \": 0\",\n nLine: this.nLine\n };\n this.aVariables.push(name);\n }\n }\n return sReserved;\n }\n\n /**\n * getString(sValue, nConversion)\n *\n * Converts the given expression string (sValue) to one of the following, based on the conversion code (nConversion):\n *\n * 0: numeric string (default)\n * 1: SIXBIT string\n * 2: ASCII string\n *\n * If the expression cannot be evaluated, or if the requested conversion isn't recognized, the original value is returned.\n *\n * @this {Macro10}\n * @param {string} sValue\n * @param {number} [nConversion]\n * @return {string}\n */\n getString(sValue, nConversion = 0)\n {\n var c, s;\n var value = this.parseExpression(sValue);\n if (value !== undefined) {\n var cchMax = 5;\n switch(nConversion) {\n case 0:\n sValue = this.dbg.toStrBase(value, -1);\n break;\n case 6:\n cchMax++;\n /* falls through */\n case 7:\n s = \"\";\n while (value && cchMax--) {\n c = value & (Math.pow(2, nConversion) - 1);\n s = String.fromCharCode(c + (nConversion == 6? 0x20 : 0)) + s;\n value = Math.trunc(value / Math.pow(2, nConversion));\n }\n break;\n }\n }\n return sValue;\n }\n\n /**\n * getSymbol(sOperands)\n *\n * Check the operands for a symbol. TODO: Use this method?\n *\n * @this {Macro10}\n * @param {string} sOperands\n * @return {string|null} (if the operands contain a symbol, return it)\n */\n getSymbol(sOperands)\n {\n var match = sOperands.match(/([A-Z$%.][0-9A-Z$%.]*)/i);\n return match && match[1] || null;\n }\n\n /**\n * getValues(sOperands, fParens)\n *\n * @this {Macro10}\n * @param {string} sOperands\n * @param {boolean} [fParens] (true to strip any parens from around the entire operands)\n * @return {Array.<string>}\n */\n getValues(sOperands, fParens)\n {\n var aValues = [];\n if (fParens) sOperands = sOperands.replace(/^\\(?(.*?)\\)?$/, \"$1\");\n while (sOperands) {\n sOperands = sOperands.trim();\n var sOperand = this.getExpression(sOperands);\n if (!sOperand) break;\n var sValue = sOperand;\n if (sOperand[0] == '\\\\') {\n var cchPrefix = 1;\n var nConversion = 0;\n if (sOperand[1] == \"'\") {\n cchPrefix++;\n nConversion = 6;\n } else if (sOperand[1] == '\"') {\n cchPrefix++;\n nConversion = 7;\n }\n sValue = this.getString(sOperand.substr(cchPrefix), nConversion);\n }\n aValues.push(sValue);\n sOperands = sOperands.substr(sOperand.length + 1);\n }\n return aValues;\n }\n\n /**\n * isDefined(sName)\n *\n * @this {Macro10}\n * @param {string} sName\n * @return {boolean}\n */\n isDefined(sName)\n {\n return this.isMacro(sName) || this.isSymbol(sName) || this.dbg.isVariable(sName);\n }\n\n /**\n * isMacro(sName)\n *\n * @this {Macro10}\n * @param {string} sName\n * @return {boolean}\n */\n isMacro(sName)\n {\n return this.tblMacros[sName] !== undefined;\n }\n\n /**\n * isSymbol(sName)\n *\n * @this {Macro10}\n * @param {string} sName\n * @return {boolean}\n */\n isSymbol(sName)\n {\n return this.tblSymbols[sName] !== undefined;\n }\n\n /**\n * isSymbolChar(ch)\n *\n * @this {Macro10}\n * @param {string} ch\n * @return {boolean}\n */\n isSymbolChar(ch)\n {\n return !!ch.match(/[0-9A-Z$%.]/i);\n }\n\n /**\n * defASCII(sOperands)\n *\n * @this {Macro10}\n * @param {string} sOperands\n * @return {string} (returns whatever portion of the string was not part of an ASCII pseudo-op)\n */\n defASCII(sOperands)\n {\n var sRemain = sOperands;\n if (this.chASCII == null) {\n this.chASCII = this.sASCII = \"\";\n if (sOperands) {\n this.chASCII = sOperands[0];\n sRemain = sOperands = sOperands.substr(1);\n }\n }\n if (this.chASCII) {\n var i = sOperands.indexOf(this.chASCII);\n if (i < 0) {\n sRemain = \"\";\n } else {\n sRemain = sOperands.substr(i + 1);\n sOperands = sOperands.substr(0, i);\n this.chASCII = null;\n }\n this.sASCII += sOperands;\n }\n if (this.chASCII == null) {\n this.genASCII();\n }\n return sRemain;\n }\n\n /**\n * defMacro(sOperator, sOperands)\n *\n * If sOperator is DEFINE (or OPDEF), then a macro definition is expected. If it's REPEAT, then we're\n * starting a REPEAT block instead.\n *\n * REPEAT blocks piggy-back on this code because they're essentially anonymous immediately-invoked macros;\n * we use an illegal MACRO-10 symbol ('?REPEAT') to name the anonymous macro while it's being defined, and the\n * macro's nOperand field will contain the repeat count.\n *\n * The piggy-backing continues with other pseudo-ops like IFE, which again contain an anonymous block of text\n * that is immediately invoked if the criteria associated with the expression stored in the nOperand field is\n * satisfied. That satisfaction occurs (or doesn't occur) when parseMacro() is called, once the macro has\n * been fully defined.\n *\n * @this {Macro10}\n * @param {string} sOperator\n * @param {string} sOperands\n * @return {string}\n */\n defMacro(sOperator, sOperands)\n {\n var i, match, name, nOperand, aParms, aDefaults, aValues, iMatch;\n\n this.chMacroOpen = '<';\n this.chMacroClose = '>';\n aParms = aDefaults = aValues = [];\n\n if (sOperator == Macro10.PSEUDO_OP.DEFINE) {\n /*\n * This is a DEFINE (macro) block. At present, this requires that all\n * (parenthesized) parameters exist on the same line, but the (angle-bracketed)\n * definition can continue on for multiple lines.\n */\n match = sOperands.match(/([A-Z$%.][0-9A-Z$%.]*)\\s*(\\([^)]*\\)|)\\s*,?\\s*(<|)([\\s\\S]*)/i);\n if (!match) {\n this.error(\"unrecognized \" + sOperator + \" in '\" + sOperands + \"'\");\n return sOperands;\n }\n name = match[1];\n /*\n * If this macro has defined parameters, parse them (and any defaults) now.\n */\n if (match[2] && match[2] != ',') {\n aParms = this.getValues(match[2], true);\n aDefaults = this.getDefaults(aParms);\n }\n nOperand = Macro10.MACRO_OP.DEFINE;\n iMatch = 3;\n }\n else if (sOperator == Macro10.PSEUDO_OP.OPDEF) {\n /*\n * This is a OPDEF block. Unlike DEFINE blocks, I'm assuming that the\n * (square-bracketed) definition begins on the same line, but I'm not requiring\n * it to end on the same line (I'm not sure that MACRO-10 allowed multi-line\n * OPDEFs, but it doesn't matter to us).\n */\n this.chMacroOpen = '[';\n this.chMacroClose = ']';\n match = sOperands.match(/([A-Z$%.][0-9A-Z$%.]*)\\s*(\\[)([\\s\\S]*)/i);\n if (!match) {\n this.error(\"unrecognized \" + sOperator + \" in '\" + sOperands + \"'\");\n return sOperands;\n }\n name = match[1];\n nOperand = Macro10.MACRO_OP.OPDEF;\n iMatch = 2;\n }\n else if (sOperator == Macro10.PSEUDO_OP.LITERAL) {\n /*\n * This is a LITERAL block.\n */\n this.chMacroOpen = '[';\n this.chMacroClose = ']';\n name = '?' + Str.toDec(++this.nLiteral, 5);\n if (this.tblMacros[name] !== undefined) {\n this.error(\"literal symbol '\" + name + \"' redefined\");\n }\n match = [sOperands[0], sOperands.substr(1)];\n nOperand = Macro10.MACRO_OP.LITERAL;\n iMatch = 0;\n }\n else if (sOperator == Macro10.PSEUDO_OP.IRP || sOperator == Macro10.PSEUDO_OP.IRPC) {\n /*\n * IRP (and IRPC) blocks are very similar to DEFINE blocks, but they define exactly ONE macro parameter\n * with NO parentheses (whereas regular macros always define their parameters, if any, WITH parentheses),\n * and then the IRP (or IRPC) block is immediately invoked with the corresponding value from the\n * enclosing macro.\n */\n if (!this.macroCall) {\n this.error(sOperator + \" outside of macro\");\n }\n match = sOperands.match(/([A-Z$%.][0-9A-Z$%.]*)\\s*,\\s*(<|)([\\s\\S]*)/i);\n if (!match) {\n this.error(\"unrecognized \" + sOperator + \" operands '\" + sOperands + \"'\");\n return sOperands;\n }\n for (i = 0; i < this.macroCall.aParms.length; i++) {\n if (match[1] == this.macroCall.aParms[i]) break;\n }\n if (i == this.macroCall.aParms.length) {\n this.error(\"invalid \" + sOperator + \" parameter '\" + match[1] + \"'\");\n return sOperands;\n }\n name = '?' + sOperator;\n aParms = [match[1]];\n if (sOperator == Macro10.PSEUDO_OP.IRPC) {\n aValues = this.macroCall.aValues[i].split(\"\");\n } else {\n aValues = this.getValues(this.macroCall.aValues[i]);\n }\n nOperand = aValues.length;\n iMatch = 2;\n }\n else {\n /*\n * This must be a REPEAT or CONDITIONAL block.\n */\n if (sOperator == Macro10.PSEUDO_OP.IF1) {\n nOperand = 1;\n if (sOperands[0] == ',') sOperands = sOperands.substr(1).trim();\n }\n else {\n var sOperand = this.getExpression(sOperands);\n if (!sOperand) {\n this.error(\"missing \" + sOperator + \" expression '\" + sOperands + \"'\");\n return sOperands;\n }\n sOperands = sOperands.substr(sOperand.length + 1);\n sOperand = sOperand.trim();\n if (sOperator == Macro10.PSEUDO_OP.IFDIF || sOperator == Macro10.PSEUDO_OP.IFIDN) {\n var sOperand2 = this.getExpression(sOperands);\n if (!sOperand2) {\n this.error(\"missing second \" + sOperator + \" expression '\" + sOperands + \"'\");\n return sOperands;\n }\n sOperands = sOperands.substr(sOperand2.length + 1);\n sOperand2 = sOperand2.trim();\n nOperand = (sOperand == sOperand2)? 1 : 0;\n }\n if (sOperator == Macro10.PSEUDO_OP.IFDEF || sOperator == Macro10.PSEUDO_OP.IFNDEF) {\n nOperand = this.isDefined(sOperand)? 1 : 0;\n } else {\n /*\n * The expression is either a repeat count or a condition. Either way, we must be able to\n * resolve it now, so we don't set fPass1 (but that doesn't mean it's the second pass, either).\n */\n nOperand = this.parseExpression(sOperand) || 0;\n }\n }\n match = sOperands.match(/\\s*(<|)([\\s\\S]*)/i);\n name = '?' + sOperator;\n iMatch = 1;\n }\n\n /*\n * Now we need to set a global parsing state: we are either about to receive a macro definition on\n * subsequent lines (1), the definition has already started on the current line (2), or the definition\n * started and ended on the current line (0).\n */\n name = name.toUpperCase();\n this.nMacroDef = 1;\n this.sMacroDef = name;\n this.tblMacros[name] = {name, nOperand, aParms, aDefaults, aValues, sText: \"\", nLine: this.nLine};\n\n if (match[iMatch]) { // if there is an opening bracket\n this.nMacroDef = 2; // then the macro definition has started\n this.appendMacro(match[iMatch + 1]);\n }\n\n return name;\n }\n\n /**\n * appendMacro(sLine)\n *\n * @this {Macro10}\n * @param {string} sLine\n * @return {string}\n */\n appendMacro(sLine)\n {\n var sRemain = \"\";\n for (var i = 0; i < sLine.length; i++) {\n if (sLine[i] == this.chMacroOpen) {\n this.nMacroDef++;\n } else if (sLine[i] == this.chMacroClose) {\n this.nMacroDef--;\n if (this.nMacroDef == 1) {\n this.nMacroDef = 0;\n sRemain = sLine.substr(i + 1);\n sLine = sLine.substr(0, i);\n break;\n }\n }\n }\n var name = this.sMacroDef || \"\";\n this.tblMacros[name].sText += sLine;\n if (!this.nMacroDef) {\n this.sMacroDef = null;\n this.parseMacro(name);\n }\n return sRemain;\n }\n\n /**\n * addSymbol(name, value, nType)\n *\n * @this {Macro10}\n * @param {string} name\n * @param {number|string} value\n * @param {number} [nType]\n */\n addSymbol(name, value, nType = 0)\n {\n name = name.toUpperCase().substr(0, 6);\n if ((nType & Macro10.SYMTYPE.LABEL) && this.tblSymbols[name] !== undefined) {\n this.error(\"redefined label '\" + name + \"'\");\n return;\n }\n var sUndefined = undefined;\n if (typeof value == 'string') {\n var aUndefined = [];\n var v = this.parseExpression(value, aUndefined);\n if (v === undefined) {\n this.error(\"invalid symbol '\" + name + \"': \" + value);\n return;\n }\n if (aUndefined.length > 1) {\n this.error(\"too many undefined symbols in '\" + name + \"': \" + aUndefined.join());\n }\n value = v;\n sUndefined = aUndefined[0];\n }\n var sym = this.tblSymbols[name];\n if (sym) {\n sym.value = value;\n sym.nType = nType;\n sym.nLine = this.nLine;\n } else {\n this.tblSymbols[name] = {name, value, nType, nLine: this.nLine};\n }\n this.dbg.setVariable(name, value, sUndefined);\n }\n\n /**\n * defBLOCK()\n *\n * Processes the BLOCK pseudo-op.\n *\n * @this {Macro10}\n * @param {string} sOperands\n */\n defBLOCK(sOperands)\n {\n var w = this.parseExpression(sOperands);\n if (w !== undefined && w >= 0 && w <= 0o777777) {\n this.nLocation += w; // while (w--) this.genWord(0);\n } else {\n this.error(\"unrecognized BLOCK expression '\" + sOperands + \"'\");\n }\n }\n\n /**\n * defBYTE()\n *\n * Processes the BYTE pseudo-op.\n *\n * @this {Macro10}\n * @param {string} sOperands\n */\n defBYTE(sOperands)\n {\n var sOperand;\n var nBits = 0, nValue = 0, nBitsRemaining = 36;\n\n while (sOperand = this.getExpression(sOperands)) {\n sOperands = sOperands.substr(sOperand.length).trim();\n var sValue = sOperand;\n var match = sOperand.match(/^\\((.*)\\)\\s*(.*)$/);\n if (match) {\n if (match[1]) nBits = this.parseExpression(\"^D\" + match[1]);\n sValue = match[2];\n }\n if (!nBits) {\n /*\n * According the the 1978 MACRO-10 spec, \"If the byte size is 0 or is missing (empty parentheses), a zero word\n * is generated.\" I'm not clear exactly on how to interpret this, so I'll make a simplistic assumption for now.\n */\n this.genWord(0);\n continue;\n }\n var v = sValue? this.parseExpression(sValue) : 0;\n if (v === undefined || nBits < 0 || nBits > 36) {\n this.error(\"unexpected BYTE operand: \" + sOperand);\n break;\n }\n v = this.dbg.truncate(v, nBits, true);\n if (nBitsRemaining < nBits) {\n this.genWord(nValue);\n nValue = 0;\n nBitsRemaining = 36;\n }\n nValue += v * Math.pow(2, nBitsRemaining - nBits);\n nBitsRemaining -= nBits;\n }\n if (nBitsRemaining < 36) {\n this.genWord(nValue);\n }\n }\n\n /**\n * defEND()\n *\n * Processes the END pseudo-op.\n *\n * @this {Macro10}\n * @param {string} sOperands\n */\n defEND(sOperands)\n {\n if (!sOperands) {\n this.addrStart = this.addrLoad;\n } else {\n this.addrStart = this.parseExpression(sOperands);\n if (this.addrStart === undefined) {\n this.error(\"unrecognized END expression '\" + sOperands + \"'\");\n }\n }\n }\n\n /**\n * defLocation(sOperands)\n *\n * Processes the LOC pseudo-op.\n *\n * @this {Macro10}\n * @param {string} sOperands\n */\n defLocation(sOperands)\n {\n this.nLocation = this.parseExpression(sOperands) || 0;\n }\n\n /**\n * defXWD()\n *\n * Processes the XWD pseudo-op.\n *\n * Since the XWD pseudo-op appears to be equivalent to two values separated by two commas, which defWord() must also\n * support, we can piggy-back on defWord().\n *\n * @this {Macro10}\n * @param {string} sOperands\n */\n defXWD(sOperands)\n {\n this.defWord(sOperands.replace(\",\", \",,\"));\n }\n\n /**\n * defWord(sOperator, sSeparator, sOperands)\n *\n * @this {Macro10}\n * @param {string} sOperator\n * @param {string} [sSeparator]\n * @param {string} [sOperands]\n */\n defWord(sOperator, sSeparator = \"\", sOperands = \"\")\n {\n var aUndefined = [];\n var sExp = (sOperator + sSeparator + sOperands).trim();\n var w = this.parseExpression(sExp, aUndefined);\n if (w !== undefined) {\n if (!aUndefined.length) {\n this.genWord(w);\n } else if (aUndefined.length == 1) {\n this.genWord(w, aUndefined[0]);\n }\n else {\n this.genWord(0, sExp);\n }\n } else {\n this.error(\"unrecognized word expression '\" + sExp + \"'\");\n }\n }\n\n /**\n * delSymbols(sOperands)\n *\n * @this {Macro10}\n * @param {string} sOperands\n */\n delSymbols(sOperands)\n {\n var aValues = this.getValues(sOperands);\n for (var i = 0; i < aValues.length; i++) {\n this.dbg.delVariable(aValues[i]);\n delete this.tblSymbols[aValues[i]];\n }\n }\n\n /**\n * doLiterals()\n *\n * @this {Macro10}\n */\n doLiterals()\n {\n let nLocationLiterals = this.nLocation;\n\n for (let i = 0; i < this.aLiterals.length; i++) {\n /*\n * Apparently, the time has come to implement \"literal collapsing\"; I was treating it as just\n * a nice optimization, but it turns out that DEC has written tests that actually DEPEND on it:\n *\n * C26300: HRRZI [135531,,246642] ;PRELOAD AC0 WITH 0,, LITERAL ADDRESS\n * JRA .+1 ;*JRA SHOULD PLACE C(AC0) INTO AC0\n * CAIE [135531,,246642] ;PASS IF JRA PLACED C(AC0) INTO AC0\n * STOP\n *\n * If the HRRZI and CAIE instructions don't refer to the same exact literal, the test will fail.\n * For purposes of this particular test, the values they stuffed into the literals are essentially\n * gibberish, but the same literal may be used in another test where the values are significant.\n *\n * However, I'm still going to keep it simple. In this example from p. 2-8 of the April 1978\n * MACRO-10 manual, I will NOT be attempting to collapse null words at the end of ASCIZ sequences\n * with other null words, especially if they were defined before the ASCIZ:\n *\n * Literals having the same value are collapsed in MACRO's literal pool.\n * Thus for the statements:\n *\n * PUSH P,[0]\n * PUSH P,[0]\n * MOVEI 1,[ASCIZ /TEST1/]\n *\n * the same address is shared by the two literals [0], and by the null word\n * generated at the end of [ASCIZ /TEST1/].\n */\n let lit = this.aLiterals[i];\n /*\n * First things first: verify that the literal is one contiguous zero-based set of words (I'm not sure\n * how it couldn't be, but better safe than sorry).\n */\n let aWords = [];\n let nWords = 0;\n lit.aWords.forEach(function(w, nLocation) {\n if (nLocation === aWords.length) aWords.push(w);\n nWords++;\n });\n if (nWords == aWords.length) {\n /*\n * So far, so good. Now we'll simply brute-force-search our way through the existing set of\n * literals, looking for a complete match.\n */\n for (let nLocation = nLocationLiterals; nLocation + nWords <= this.nLocation; nLocation++) {\n let n;\n for (n = 0; n < nWords; n++) {\n /*\n * This check requires that the initial values of the words in the literals match AND that\n * their fixup expressions, if any, match as well. Here again, MACRO-10 may be more aggressive\n * in either verifying fixup equality or evaluating any fixups that it can immediately, but\n * but I prefer to leave all fixup evaluation where it is (below), after all literals and then\n * all variables have been added to the output.\n */\n if (aWords[n] !== this.aWords[nLocation + n] || lit.aFixups[n] != this.aFixups[nLocation]) break;\n }\n if (n == nWords) {\n this.addSymbol(lit.name, nLocation, Macro10.SYMTYPE.LABEL);\n lit = null;\n break;\n }\n }\n }\n if (lit) {\n var macro10 = this;\n this.addSymbol(lit.name, this.nLocation, Macro10.SYMTYPE.LABEL);\n lit.aWords.forEach(function(w, nLocation) {\n macro10.genWord(w, lit.aFixups[nLocation]);\n });\n }\n }\n this.aLiterals = [];\n }\n\n /**\n * doVariables()\n *\n * @this {Macro10}\n */\n doVariables()\n {\n for (let i = 0; i < this.aVariables.length; i++) {\n let name = this.aVariables[i];\n let macro = this.tblMacros[name];\n if (!macro) {\n /*\n * This is more of an assert(), because it should never happen, regardless of input.\n */\n this.error(\"missing definition for variable '\" + name + \"'\");\n continue;\n }\n this.parseText(macro.sText);\n }\n this.aVariables = [];\n }\n\n /**\n * genASCII()\n *\n * Based on the last operator, generate the appropriate ASCII/ASCIZ/SIXBIT data.\n *\n * @this {Macro10}\n */\n genASCII()\n {\n var n = 0, w = 0; // number of characters in current word, and current word\n var bits, shift; // bits per character, and bits to left-shift next character\n var cch = this.sASCII.length;\n if (this.sOperator == Macro10.PSEUDO_OP.ASCIZ) cch++;\n for (var i = 0; i < cch; i++) {\n if (!n) {\n w = 0; shift = 29; bits = 7;\n if (this.sOperator == Macro10.PSEUDO_OP.SIXBIT) {\n bits--; shift++;\n }\n }\n /*\n * If we're processing an ASCIZ pseudo-op, then yes, we will fetch one character beyond\n * the end of sASCII, which will return NaN, but when we mask a falsey value like NaN, we\n * get zero, so it's all good.\n */\n var c = this.sASCII.charCodeAt(i) & 0o177;\n /*\n * If we're doing 6-bit encoding, then perform the conversion of lower-case to upper-case,\n * and then adjust/mask.\n */\n if (bits == 6) {\n if (c >= 0x61 && c <= 0x7A) c -= 0x20;\n c = (c + 0o40) & 0o77;\n }\n w += c * Math.pow(2, shift);\n shift -= bits;\n n++;\n if (shift < 0) {\n this.genWord(w);\n n = 0;\n }\n }\n if (n) this.genWord(w);\n }\n\n /**\n * genWord(value, sUndefined)\n *\n * @this {Macro10}\n * @param {number} value (default value for the current location)\n * @param {string} [sUndefined] (optional fixup to evaluate later)\n */\n genWord(value, sUndefined)\n {\n this.aWords[this.nLocation] = this.truncate(value);\n if (sUndefined !== undefined) this.aFixups[this.nLocation] = sUndefined;\n this.aLineRefs[this.nLocation] = this.nLine;\n this.nLocation++;\n }\n\n /**\n * truncate(value, nLocation)\n *\n * @this {Macro10}\n * @param {number} value\n * @param {number} [nLocation]\n * @return {number}\n */\n truncate(value, nLocation = this.nLocation)\n {\n var w = this.dbg.truncate(value || 0, 36, true);\n if (value < -PDP10.INT_LIMIT || value >= PDP10.WORD_LIMIT) {\n this.warning(\"truncated value \" + Str.toOct(value) + \" at location \" + Str.toOct(nLocation) + \" to \" + Str.toOct(w));\n }\n return w;\n }\n\n /**\n * error(sError, nLine)\n *\n * @this {Macro10}\n * @param {string} sError\n * @param {number} [nLine]\n * @throws {Error}\n */\n error(sError, nLine)\n {\n throw new Error(\"error in \" + this.getLineRef(nLine) + \": \" + sError);\n }\n\n /**\n * warning(sWarning, nLine)\n *\n * @this {Macro10}\n * @param {string} sWarning\n * @param {number} [nLine]\n */\n warning(sWarning, nLine)\n {\n this.println(\"warning in \" + this.getLineRef(nLine) + \": \" + sWarning);\n }\n\n /**\n * println(s)\n *\n * @this {Macro10}\n * @param {string} s\n */\n println(s)\n {\n if (!this.dbg) {\n console.log(s);\n } else {\n this.dbg.println(s);\n }\n }\n}\n\nMacro10.SYMTYPE = {\n LABEL: 0x01,\n PRIVATE: 0x02,\n INTERNAL: 0x04\n};\n\nMacro10.PSEUDO_OP = {\n ASCII: \"ASCII\",\n ASCIZ: \"ASCIZ\",\n BLOCK: \"BLOCK\",\n BYTE: \"BYTE\",\n DEFINE: \"DEFINE\",\n END: \"END\",\n EXP: \"EXP\",\n IF1: \"IF1\",\n IFDEF: \"IFDEF\",\n IFDIF: \"IFDIF\",\n IFE: \"IFE\",\n IFG: \"IFG\",\n IFGE: \"IFGE\",\n IFIDN: \"IFIDN\",\n IFL: \"IFL\",\n IFLE: \"IFLE\",\n IFN: \"IFN\",\n IFNDEF: \"IFNDEF\",\n IRP: \"IRP\",\n IRPC: \"IRPC\",\n LALL: \"LALL\",\n LIT: \"LIT\",\n LITERAL: \"LITERAL\", // this is a pseudo-pseudo-op, for internal use only\n LIST: \"LIST\",\n LOC: \"LOC\",\n NOSYM: \"NOSYM\",\n OPDEF: \"OPDEF\",\n PAGE: \"PAGE\",\n PURGE: \"PURGE\",\n REPEAT: \"REPEAT\",\n SIXBIT: \"SIXBIT\",\n SUBTTL: \"SUBTTL\",\n TITLE: \"TITLE\",\n VAR: \"VAR\",\n XALL: \"XALL\",\n XWD: \"XWD\",\n XLIST: \"XLIST\"\n};\n\n/*\n * This enumerates the kinds of macros stored in tblMacros. The nOperand field should contain\n * one of these values, unless it's a REPEAT or CONDITIONAL block, in which case it will contain\n * either a repeat count or conditional value.\n */\nMacro10.MACRO_OP = {\n DEFINE: -1,\n OPDEF: -2,\n LITERAL: -3,\n RESERVED: -4,\n};\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp10/lib/computer.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass ComputerPDP10 extends Component {\n /**\n * ComputerPDP10(parmsComputer, parmsMachine, fSuspended)\n *\n * The ComputerPDP10 component has no required (parmsComputer) properties, but it does\n * support the following:\n *\n * autoPower: true to automatically power the computer (default), false to wait;\n * false is honored only if a \"power\" button binding exists.\n *\n * busWidth: number of memory address lines (address bits) on the computer's \"bus\";\n * 20 is the minimum (and the default), which implies 8086/8088 real-mode addressing,\n * while 24 is required for 80286 protected-mode addressing. This value is passed\n * directly through to the Bus component; see that component for more details.\n *\n * resume: one of the ComputerPDP10.RESUME constants, which are as follows:\n * '0' if resume disabled (default)\n * '1' if enabled without prompting\n * '2' if enabled with prompting\n * '3' if enabled with prompting and auto-delete\n * or a string containing the path of a predefined JSON-encoded state\n *\n * state: the path to JSON-encoded state file (see details regarding 'state' below)\n *\n * The parmsMachine object, if provided, may contain any of:\n *\n * autoMount: if set, this should override any 'autoMount' property in the FDC's\n * parmsFDC object.\n *\n * autoPower: if set, this should override any 'autoPower' property in the ComputerPDP10's\n * parmsComputer object.\n *\n * messages: if set, this should override any 'messages' property in the Debugger's\n * parmsDbg object.\n *\n * state: if set, this should override any 'state' property in the ComputerPDP10's\n * parmsComputer object.\n *\n * url: the location of the machine XML file\n *\n * If a predefined state is supplied AND it's successfully loaded, then resume behavior\n * defaults to '1' (ie, resume enabled without prompting).\n *\n * This component insures that all components are ready before \"powering\" them.\n *\n * Different components become ready at different times, and initialization order (ie,\n * the order the scripts are combined on the page) only partially determines readiness.\n * This is because components like ROM and Video must finish loading their resource files\n * before they are ready. Other components become ready after we call their initBus()\n * function, because they have a Bus or CPU dependency, such as access to memory management\n * functions. And other components, like CPU and Panel, are ready as soon as their\n * constructor finishes.\n *\n * Once a component has indicated it's ready, we call its powerUp() notification\n * function (if it has one--it's optional). We call the CPU's powerUp() function last,\n * so that the CPU is assured that all other components are ready and \"powered\".\n *\n * @this {ComputerPDP10}\n * @param {Object} parmsComputer\n * @param {Object} [parmsMachine]\n * @param {boolean} [fSuspended]\n */\n constructor(parmsComputer, parmsMachine, fSuspended)\n {\n super(\"Computer\", parmsComputer, MessagesPDP10.COMPUTER);\n\n this.flags.powered = false;\n\n this.parmsMachine = null;\n this.setMachineParms(parmsMachine);\n\n this.fAutoPower = this.getMachineParm('autoPower', parmsComputer, Str.TYPES.BOOLEAN);\n\n /*\n * nPowerChange is 0 while the power state is stable, 1 while power is transitioning\n * to \"on\", and -1 while power is transitioning to \"off\".\n */\n this.nPowerChange = 0;\n\n /*\n * TODO: Deprecate 'buswidth' (it should have always used camelCase)\n */\n this.nBusWidth = +parmsComputer['busWidth'] || +parmsComputer['buswidth'];\n\n this.sResumePath = this.sStatePath = null;\n this.sStateData = null;\n this.fStateData = false; // remembers if sStateData was loaded\n this.fServerState = false;\n this.stateComputer = this.stateFailSafe = null;\n this.fInitialized = this.fReload = this.fRestoreError = false;\n\n this.url = /** @type {string} */ (this.getMachineParm('url') || \"\");\n\n /*\n * Generate a random number x (where 0 <= x < 1), add 0.1 so that it's guaranteed to be\n * non-zero, convert to base 36, and chop off the leading digit and \"decimal\" point.\n */\n this.sMachineID = (Math.random() + 0.1).toString(36).substr(2,12);\n this.sUserID = this.queryUserID();\n\n /*\n * Find the appropriate CPU (and Debugger and Control Panel, if any).\n *\n * CLOSURE COMPILER TIP: To override the type of a right-hand expression (as we need to do here,\n * where we know getComponentByType() will only return an CPUState object or null), wrap the expression\n * in parentheses. I never knew this until I stumbled across it in \"Closure: The Definitive Guide\".\n */\n this.cpu = /** @type {CPUStatePDP10} */ (Component.getComponentByType(\"CPU\", this.id));\n if (!this.cpu) {\n Component.error(\"Unable to find CPU component\");\n return;\n }\n this.dbg = /** @type {DebuggerPDP10} */ (Component.getComponentByType(\"Debugger\", this.id));\n\n /*\n * Initialize the Bus component\n */\n this.bus = new BusPDP10({'id': this.idMachine + '.bus', 'busWidth': this.nBusWidth}, this.cpu, this.dbg);\n\n /*\n * Iterate through all the components and connect them to the Control Panel, if any\n */\n var iComponent, component;\n var aComponents = Component.getComponents(this.id);\n\n this.panel = /** @type {PanelPDP10} */ (Component.getComponentByType(\"Panel\", this.id));\n this.controlPrint = this.panel && this.panel.bindings['print'];\n\n if (this.controlPrint) {\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n /*\n * I can think of many \"cleaner\" ways for the Control Panel component to pass its\n * notice(), println(), etc, overrides on to all the other components, but it's just\n * too darn convenient to slam those overrides into the components directly.\n */\n component.notice = this.panel.notice;\n component.print = this.panel.print;\n component.println = this.panel.println;\n }\n }\n\n this.println(PDP10.APPNAME + \" v\" + PDP10.APPVERSION + \"\\n\" + COPYRIGHT + \"\\n\" + LICENSE);\n\n /*\n * Iterate through all the components again and call their initBus() handler, if any\n */\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component.initBus) component.initBus(this, this.bus, this.cpu, this.dbg);\n }\n\n var sStatePath = null;\n var sResume = /** @type {string} */ (this.getMachineParm('resume', parmsComputer));\n if (sResume !== undefined) {\n /*\n * Decide whether the 'resume' property is a number or the path of a state file to resume.\n */\n if (sResume.length > 1) {\n sStatePath = this.sResumePath = sResume;\n } else {\n this.resume = parseInt(sResume, 10);\n }\n }\n\n /*\n * The Computer 'state' property allows a state file to be specified independent of the 'resume' feature;\n * previously, you could only use 'resume' to load a state file -- which we still support, but loading a state\n * file that way prevents the machine's state from being saved, since we always resume from the 'resume' file.\n *\n * The other wrinkle is on the restore side: we need to IGNORE the 'state' property if a saved state now exists.\n * So we have to peek at localStorage, and unfortunately, the only way to \"peek\" is to actually load the data,\n * but we're not ready to use it yet, so powerUp() has been changed to use any existing stateComputer that we've\n * already loaded.\n *\n * However, there's now a wrinkle to the wrinkle: if a 'state' parameter has been passed via the URL, then that\n * OVERRIDES everything; it overrides any 'state' Computer parameter AND it disables resume of any saved state in\n * localStorage (in other words, it prevents fAllowResume from being true, and forcing resume off).\n */\n var fAllowResume;\n var sState = this.getMachineParm('state') || (fAllowResume = true) && parmsComputer['state'];\n\n if (sState) {\n this.sStatePath = sStatePath = sState;\n if (!fAllowResume) {\n this.fServerState = true;\n this.resume = ComputerPDP10.RESUME_NONE;\n }\n if (this.resume) {\n this.stateComputer = new State(this, PDP10.APPVERSION);\n if (this.stateComputer.load()) {\n sStatePath = null;\n } else {\n delete this.stateComputer;\n }\n }\n }\n\n /*\n * If sStatePath is set, we must use it. But if there's no sStatePath AND resume is set,\n * then we have the option of resuming from a server-side state, assuming a valid USERID.\n */\n if (!sStatePath && this.resume) {\n sStatePath = this.getServerStatePath();\n if (sStatePath) this.fServerState = true;\n }\n\n if (!sStatePath) {\n this.setReady();\n } else {\n var cmp = this;\n Web.getResource(sStatePath, null, true, function doneStateLoad(sURL, sResource, nErrorCode) {\n cmp.finishStateLoad(sURL, sResource, nErrorCode);\n });\n }\n\n if (!this.bindings[\"power\"]) this.fAutoPower = true;\n\n /*\n * Power on the computer, giving every component the opportunity to reset or restore itself.\n */\n if (!fSuspended && this.fAutoPower) this.wait(this.powerOn);\n }\n\n /**\n * clearPanel()\n *\n * @this {ComputerPDP10}\n */\n clearPanel()\n {\n if (this.controlPrint) {\n this.controlPrint.value = \"\";\n }\n }\n\n /**\n * getMachineID()\n *\n * @this {ComputerPDP10}\n * @return {string}\n */\n getMachineID()\n {\n return this.sMachineID;\n }\n\n /**\n * setMachineParms(parmsMachine)\n *\n * If no explicit machine parms were provided, then we check for 'parms' in the bundled resources (if any).\n *\n * @this {ComputerPDP10}\n * @param {Object} [parmsMachine]\n */\n setMachineParms(parmsMachine)\n {\n if (!parmsMachine) {\n var sParms;\n if (typeof resources == 'object' && (sParms = resources['parms'])) {\n try {\n parmsMachine = /** @type {Object} */ (eval(\"(\" + sParms + \")\"));\n } catch(e) {\n Component.error(e.message + \" (\" + sParms + \")\");\n }\n }\n }\n this.parmsMachine = parmsMachine;\n }\n\n /**\n * getMachineParm(sParm, parmsComponent, type, defaultValue)\n *\n * If the machine parameter doesn't exist, we check for a matching component parameter\n * (if parmsComponent is provided), and failing that, we check the bundled resources (if any).\n *\n * At the moment, the only bundled resource request we expect to encounter is 'state'; if it exists,\n * then we return 'state' back to the caller (ie, the name of the resource), so that the caller will\n * then attempt to load the 'state' resource to obtain the actual state.\n *\n * TODO: It would be nice if we could tell the Closure Compiler that when a specific type parameter\n * (eg, Str.TYPES.NUMBER) is used, the return value will be that type; unfortunately, every caller\n * must coerce their own return value.\n *\n * @this {ComputerPDP10}\n * @param {string} sParm\n * @param {Object|null} [parmsComponent]\n * @param {number} [type] (from Str.TYPES)\n * @param {*} [defaultValue]\n * @return {*}\n */\n getMachineParm(sParm, parmsComponent, type, defaultValue)\n {\n /*\n * When checking parmsURL, the check is allowed be a bit looser, because URL parameters are\n * user-supplied, whereas most other parameters are developer-supplied. Granted, a developer\n * may also be sloppy and neglect to use correct case (eg, 'automount' instead of 'autoMount'),\n * but there are limits to my paranoia.\n */\n var sParmLC = sParm.toLowerCase();\n var value = Web.getURLParm(sParm) || Web.getURLParm(sParmLC);\n if (value === undefined && this.parmsMachine) value = this.parmsMachine[sParm];\n if (value === undefined && parmsComponent) value = parmsComponent[sParm];\n if (value === undefined && typeof resources == 'object' && resources[sParm]) value = sParm;\n if (value === undefined) value = defaultValue;\n if (typeof value == \"string\" && type) {\n switch(type) {\n case Str.TYPES.NUMBER:\n value = +value;\n if (isNaN(/** @type {number} */(value))) value = defaultValue || 0;\n break;\n case Str.TYPES.BOOLEAN:\n value = (value == \"true\");\n break;\n }\n }\n return value;\n }\n\n /**\n * saveMachineParms()\n *\n * @this {ComputerPDP10}\n * @return {string|null}\n */\n saveMachineParms()\n {\n return this.parmsMachine? JSON.stringify(this.parmsMachine) : null;\n }\n\n /**\n * getUserID()\n *\n * @this {ComputerPDP10}\n * @return {string}\n */\n getUserID()\n {\n return this.sUserID || \"\";\n }\n\n /**\n * finishStateLoad(sURL, sStateData, nErrorCode)\n *\n * @this {ComputerPDP10}\n * @param {string} sURL\n * @param {string} sStateData\n * @param {number} nErrorCode\n */\n finishStateLoad(sURL, sStateData, nErrorCode)\n {\n if (!nErrorCode) {\n this.sStateData = sStateData;\n this.fStateData = true;\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"loaded state file \" + sURL.replace(this.sUserID || \"xxx\", \"xxx\"));\n }\n } else {\n this.sResumePath = null;\n this.fServerState = false;\n this.notice('Unable to load machine state from server (error ' + nErrorCode + (sStateData? ': ' + Str.trim(sStateData) : '') + ')');\n }\n this.setReady();\n }\n\n /**\n * wait(fn, parms)\n *\n * wait() waits until every component is ready (including ourselves, the last component we check), then calls the\n * specified Computer method.\n *\n * TODO: The Closure Compiler makes it difficult for us to define a function type for \"fn\" that works in all cases;\n * sometimes we want to pass a function that takes only a \"number\", and other times we want to pass a function that\n * takes only an \"Array\" (the type will mirror that of the \"parms\" parameter). However, the Closure Compiler insists\n * that both functions must be declared as accepting both types of parameters. So once again, we must use an untyped\n * function declaration, instead of something stricter like:\n *\n * param {function(this:Computer, (number|Array|undefined)): undefined} fn\n *\n * @this {ComputerPDP10}\n * @param {function(...)} fn\n * @param {number|Array} [parms] optional parameters\n */\n wait(fn, parms)\n {\n var computer = this;\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent <= aComponents.length; iComponent++) {\n var component = (iComponent < aComponents.length ? aComponents[iComponent] : this);\n if (!component.isReady()) {\n component.isReady(function onComponentReady() {\n computer.wait(fn, parms);\n });\n return;\n }\n }\n if (DEBUG && this.messageEnabled()) this.printMessage(\"ComputerPDP10.wait(ready)\");\n fn.call(this, parms);\n }\n\n /**\n * validateState(stateComputer)\n *\n * NOTE: We clear() stateValidate only when there's no stateComputer.\n *\n * @this {ComputerPDP10}\n * @param {State|null} [stateComputer]\n * @return {boolean} true if state passes validation, false if not\n */\n validateState(stateComputer)\n {\n var fValid = true;\n var stateValidate = new State(this, PDP10.APPVERSION, ComputerPDP10.STATE_VALIDATE);\n if (stateValidate.load() && stateValidate.parse()) {\n var sTimestampValidate = stateValidate.get(ComputerPDP10.STATE_TIMESTAMP);\n var sTimestampComputer = stateComputer? stateComputer.get(ComputerPDP10.STATE_TIMESTAMP) : \"unknown\";\n if (sTimestampValidate != sTimestampComputer) {\n this.notice(\"Machine state may be out-of-date\\n(\" + sTimestampValidate + \" vs. \" + sTimestampComputer + \")\\nCheck your browser's local storage limits\");\n fValid = false;\n if (!stateComputer) stateValidate.clear();\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"Last state: \" + sTimestampComputer + \" (validate: \" + sTimestampValidate + \")\");\n }\n }\n }\n return fValid;\n }\n\n /**\n * powerOn(resume)\n *\n * Power every component \"up\", applying any previously available state information.\n *\n * @this {ComputerPDP10}\n * @param {number} [resume] is a valid RESUME value; default is this.resume\n */\n powerOn(resume)\n {\n if (resume === undefined) {\n resume = this.resume || (this.sStateData? ComputerPDP10.RESUME_AUTO : ComputerPDP10.RESUME_NONE);\n }\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"ComputerPDP10.powerOn(\" + (resume == ComputerPDP10.RESUME_REPOWER ? \"repower\" : (resume ? \"resume\" : \"\")) + \")\");\n }\n\n if (this.nPowerChange) {\n return;\n }\n this.nPowerChange++;\n\n var fRepower = false;\n var fRestore = false;\n this.fRestoreError = false;\n var stateComputer = this.stateComputer || new State(this, PDP10.APPVERSION);\n\n if (resume == ComputerPDP10.RESUME_REPOWER) {\n fRepower = true;\n }\n else if (resume > ComputerPDP10.RESUME_NONE) {\n if (stateComputer.load(this.sStateData)) {\n /*\n * Since we're resuming something (either a predefined state or a state from localStorage), let's\n * create a \"failsafe\" checkpoint in localStorage, and destroy it at the end of a successful powerOn().\n * Which means, of course, that if a previous \"failsafe\" checkpoint already exists, something bad\n * may have happened the last time around.\n */\n this.stateFailSafe = new State(this, PDP10.APPVERSION, ComputerPDP10.STATE_FAILSAFE);\n if (this.stateFailSafe.load()) {\n this.powerReport(stateComputer);\n /*\n * We already know resume is something other than RESUME_NONE, so we'll go ahead and bump it\n * all the way to RESUME_PROMPT, so that the user will be prompted, and if the user declines to\n * restore, the state will be removed.\n */\n resume = ComputerPDP10.RESUME_PROMPT;\n /*\n * To ensure that the set() below succeeds, we need to call unload(), otherwise it may fail\n * with a \"read only\" error (eg, \"TypeError: Cannot assign to read only property 'timestamp'\").\n */\n this.stateFailSafe.unload();\n }\n\n this.stateFailSafe.set(ComputerPDP10.STATE_TIMESTAMP, Usr.getTimestamp());\n this.stateFailSafe.store();\n\n var fValidate = this.resume && !this.fServerState;\n if (resume == ComputerPDP10.RESUME_AUTO || Component.confirmUser(\"Click OK to restore the previous \" + PDP10.APPNAME + \" machine state, or CANCEL to reset the machine.\")) {\n fRestore = stateComputer.parse();\n if (fRestore) {\n var sCode = /** @type {string} */ (stateComputer.get(UserAPI.RES.CODE));\n var sData = /** @type {string} */ (stateComputer.get(UserAPI.RES.DATA));\n if (sCode) {\n if (sCode == UserAPI.CODE.OK) {\n stateComputer.load(sData);\n } else {\n /*\n * A missing (or not yet created) state file is no cause for alarm, but other errors might be\n */\n if (sCode == UserAPI.CODE.FAIL && sData != UserAPI.FAIL.NOSTATE) {\n this.notice(\"Error: \" + sData);\n if (sData == UserAPI.FAIL.VERIFY) this.resetUserID();\n } else {\n this.println(sCode + \": \" + sData);\n }\n /*\n * Try falling back to the state that we should have saved in localStorage, as a backup to the\n * server-side state.\n */\n stateComputer.unload(); // discard the invalid server-side state first\n if (stateComputer.load()) {\n fRestore = stateComputer.parse();\n fValidate = true;\n } else {\n fRestore = false; // hmmm, there was nothing in localStorage either\n }\n }\n }\n }\n /*\n * If the load/parse was successful, and it was from localStorage (not sStateData),\n * then we should to try verify that localStorage snapshot is current. One reason it may\n * NOT be current is if localStorage was full and we got a quota error during the last\n * powerOff().\n */\n if (fValidate) this.validateState(fRestore? stateComputer : null);\n } else {\n /*\n * RESUME_PROMPT indicates we should delete the state if they clicked Cancel to confirm() above.\n */\n if (resume == ComputerPDP10.RESUME_PROMPT) stateComputer.clear();\n }\n } else {\n /*\n * If there's no state, then there should also be no validation timestamp; if there is, then once again,\n * we're probably dealing with a quota error.\n */\n this.validateState();\n }\n delete this.sStateData;\n delete this.stateComputer;\n }\n\n /*\n * Start powering all components, including any data they may need to restore their state;\n * we restore power to the CPU last.\n */\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component !== this && component != this.cpu) {\n fRestore = this.powerRestore(component, stateComputer, fRepower, fRestore);\n }\n }\n\n /*\n * Assuming this is not a repower, we must perform another wait, because some components may\n * have marked themselves as \"not ready\" again (eg, the FDC component, if the restore forced it\n * to mount one or more additional disk images).\n */\n var aParms = [stateComputer, resume, fRestore];\n\n if (resume != ComputerPDP10.RESUME_REPOWER) {\n this.wait(this.donePowerOn, aParms);\n return;\n }\n this.donePowerOn(aParms);\n }\n\n /**\n * powerRestore(component, stateComputer, fRepower, fRestore)\n *\n * @this {ComputerPDP10}\n * @param {Component} component\n * @param {State} stateComputer\n * @param {boolean} fRepower\n * @param {boolean} fRestore\n * @return {boolean} true if restore should continue, false if not\n */\n powerRestore(component, stateComputer, fRepower, fRestore)\n {\n if (!component.flags.powered) {\n\n /*\n * TODO: If all components called super.powerUp(), the powered flag would be set automatically.\n */\n\n component.flags.powered = true;\n\n var data = null;\n\n try {\n if (fRestore) {\n data = stateComputer.get(component.id);\n if (!data) {\n /*\n * This is a hack that makes it possible for a machine whose ID has been\n * supplemented with a suffix (a single letter or digit) to find object IDs\n * in states created from a machine without the suffix.\n *\n * For example, if a state file was created from a machine with ID \"ibm5160\"\n * but the current machine is \"ibm5160a\", this attempts a second lookup with\n * \"ibm5160\", enabling us to find objects that match the original machine ID\n * (eg, \"ibm5160.romEGA\").\n */\n data = stateComputer.get(component.id.replace(/[a-z0-9]\\./i, '.'));\n }\n }\n\n /*\n * State.get() will return whatever was originally passed to State.set() (eg, an\n * Object or a string), but components are supposed to store only Objects, so if a\n * string comes back, something went wrong. By explicitly eliminating \"string\" data,\n * the Closure Compiler stops complaining that we might be passing strings to our\n * powerUp() functions (even though we know we're not).\n *\n * TODO: Determine if there's some way to coerce the Closure Compiler into treating\n * data as Object or null, without having to include this runtime check. An assert\n * would be a good idea, but this is overkill.\n */\n if (typeof data === \"string\") data = null;\n\n /*\n * If computer is null, this is simply a repower notification, which most components\n * don't do anything with. Exceptions include: CPU (since it may be halted) and Video\n * (since its screen may be \"turned off\").\n */\n if (!component.powerUp(data, fRepower) && data) {\n\n Component.error(\"Unable to restore state for \" + component.type);\n /*\n * If this is a resume error for a machine that also has a predefined state\n * AND we're not restoring from that state, then throw away the current state,\n * prevent any new state from being created, and then force a reload, which will\n * hopefully restore us to the functioning predefined state.\n *\n * TODO: Considering doing this in ALL cases, not just in situations where a\n * 'state' exists but we're not actually resuming from it.\n */\n if (this.sStatePath && !this.fStateData) {\n stateComputer.clear();\n this.resume = ComputerPDP10.RESUME_NONE;\n Web.reloadPage();\n } else {\n /*\n * In all other cases, we set fRestoreError, which should trigger a call to\n * powerReport() and then delete the offending state.\n */\n this.fRestoreError = true;\n }\n /*\n * Any failure triggers an automatic to call powerUp() again, without any state,\n * in the hopes that the component can recover by performing a reset.\n */\n component.powerUp(null);\n /*\n * We also disable the rest of the restore operation, because it's not clear\n * the remaining state information can be trusted; the machine is already in an\n * inconsistent state, so we're not likely to make things worse, and the only\n * alternative (starting over and performing a state-less reset) isn't likely to make\n * the user any happier. But, we'll see... we need some experience with the code.\n */\n fRestore = false;\n }\n\n if (!fRepower && component.comment) {\n var asComments = component.comment.split(\"|\");\n for (var i = 0; i < asComments.length; i++) {\n component.status(asComments[i]);\n }\n }\n }\n catch (err) {\n Component.error(\"Error restoring state for \" + component.type + \" (\" + err.message + \")\");\n }\n }\n return fRestore;\n }\n\n /**\n * donePowerOn(aParms)\n *\n * This is nothing more than a continuation of powerOn(), giving us the option of calling wait() one more time.\n *\n * @this {ComputerPDP10}\n * @param {Array} aParms containing [stateComputer, resume, fRestore]\n */\n donePowerOn(aParms)\n {\n var stateComputer = aParms[0];\n var fRepower = (aParms[1] < 0);\n var fRestore = aParms[2];\n\n if (DEBUG && this.flags.powered && this.messageEnabled()) {\n this.printMessage(\"ComputerPDP10.donePowerOn(): redundant\");\n }\n\n this.fInitialized = true;\n this.flags.powered = true;\n var controlPower = this.bindings[\"power\"];\n if (controlPower) controlPower.textContent = \"Shutdown\";\n\n /*\n * Once we get to this point, we're guaranteed that all components are ready, so it's safe to power the CPU;\n * the CPU should begin executing immediately, unless a debugger is attached.\n */\n if (this.cpu) {\n /*\n * TODO: Do we not care about the return value here? (ie, is checking fRestoreError sufficient)?\n */\n this.powerRestore(this.cpu, stateComputer, fRepower, fRestore);\n this.updateDisplays(-2);\n this.cpu.autoStart();\n }\n\n /*\n * If the state was bad, offer to report it and then delete it. Deleting may be moot, since invariably a new\n * state will be created on powerOff() before the next powerOn(), but it seems like good paranoia all the same.\n */\n if (this.fRestoreError) {\n this.powerReport(stateComputer);\n stateComputer.clear();\n }\n\n if (!fRepower && this.stateFailSafe) {\n this.stateFailSafe.clear();\n delete this.stateFailSafe;\n }\n\n this.nPowerChange = 0;\n }\n\n /**\n * checkPower()\n *\n * @this {ComputerPDP10}\n * @return {boolean} true if the computer is fully powered, false otherwise\n */\n checkPower()\n {\n if (this.flags.powered) return true;\n\n var component = null, iComponent;\n var aComponents = Component.getComponents(this.id);\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component !== this && !component.flags.ready) break;\n }\n if (iComponent == aComponents.length) {\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component !== this && !component.flags.powered) break;\n }\n }\n if (iComponent == aComponents.length) component = this;\n var s = \"The \" + component.type + \" component (\" + component.id + \") is not \" + (!component.flags.ready? \"ready yet\" + (component.fnReady? \" (waiting for notification)\" : \"\") : \"powered yet\") + \".\";\n Component.alertUser(s);\n return false;\n }\n\n /**\n * powerReport(stateComputer)\n *\n * @this {ComputerPDP10}\n * @param {State} stateComputer\n */\n powerReport(stateComputer)\n {\n if (Component.confirmUser(\"There may be a problem with your \" + PDP10.APPNAME + \" machine.\\n\\nTo help us diagnose it, click OK to send this \" + PDP10.APPNAME + \" machine state to http://\" + SITEHOST + \".\")) {\n Web.sendReport(PDP10.APPNAME, PDP10.APPVERSION, this.url, this.getUserID(), ReportAPI.TYPE.BUG, stateComputer.toString());\n }\n }\n\n /**\n * powerOff(fSave, fShutdown)\n *\n * Power every component \"down\" and optionally save the machine state.\n *\n * There's one scenario that powerOff() isn't currently able to deal with very effectively: what to do when\n * the user switches away while it's still being restored, causing Disk getResource() calls to fail. The\n * Disk component calls notify() when that happens -- see Disk.mount() -- but the FDC and HDC controllers don't\n * notify *us* of those problems, so Computer assumes that the restore was completely successful, when in fact\n * it was only partially successful.\n *\n * Then we immediately arrive here to perform a save, following that incomplete restore. It would be wrong to\n * deal with that incomplete restore by setting fRestoreError, because we don't want to trigger a powerReport()\n * and the deletion of the previous state, because the state itself was presumably OK. Unfortunately, the new\n * state we now save will no longer include manually mounted disk images whose remounts were interrupted, so future\n * restores won't remount them either.\n *\n * We could perhaps solve this by having the Disk component notify us in those situations, set a new flag\n * (fRestoreIncomplete?), and set fSave to false if that's ever set. Be careful though: when fSave is false,\n * that means MORE than not saving; it also means deleting any previous state, which is NOT what you'd want to\n * do in a \"fRestoreIncomplete\" situation. Also, we have to worry about Disk operations that fail for other reasons,\n * making sure those failures don't interfere with the save process in the same way.\n *\n * As it stands, the worst that happens is any manually mounted disk images might have to be manually remounted,\n * which doesn't seem like a huge problem.\n *\n * @this {ComputerPDP10}\n * @param {boolean} [fSave] is true to request a saved state\n * @param {boolean} [fShutdown] is true if the machine is being shut down\n * @return {string|null} string representing the saved state (or null if error)\n */\n powerOff(fSave, fShutdown)\n {\n var data;\n var sState = \"none\";\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"ComputerPDP10.powerOff(\" + (fSave ? \"save\" : \"nosave\") + (fShutdown ? \",shutdown\" : \"\") + \")\");\n }\n\n if (this.nPowerChange) {\n return null;\n }\n this.nPowerChange--;\n\n var stateComputer = new State(this, PDP10.APPVERSION);\n var stateValidate = new State(this, PDP10.APPVERSION, ComputerPDP10.STATE_VALIDATE);\n\n var sTimestamp = Usr.getTimestamp();\n stateValidate.set(ComputerPDP10.STATE_TIMESTAMP, sTimestamp);\n stateComputer.set(ComputerPDP10.STATE_TIMESTAMP, sTimestamp);\n stateComputer.set(ComputerPDP10.STATE_VERSION, APPVERSION);\n stateComputer.set(ComputerPDP10.STATE_HOSTURL, Web.getHostURL());\n stateComputer.set(ComputerPDP10.STATE_BROWSER, Web.getUserAgent());\n\n /*\n * Always power the CPU \"down\" first, just to help insure it doesn't ask other components to do anything\n * after they're no longer ready.\n */\n if (this.cpu && this.cpu.powerDown) {\n if (fShutdown) {\n if (fSave) this.cpu.flags.autoStart = this.cpu.flags.running;\n this.cpu.stopCPU();\n }\n data = this.cpu.powerDown(fSave, fShutdown);\n if (typeof data === \"object\") stateComputer.set(this.cpu.id, data);\n if (fShutdown) {\n this.cpu.flags.powered = false;\n if (data === false) sState = null;\n }\n }\n\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.flags.powered) {\n if (component.powerDown) {\n data = component.powerDown(fSave, fShutdown);\n if (typeof data === \"object\") stateComputer.set(component.id, data);\n }\n if (fShutdown) {\n component.flags.powered = false;\n if (data === false) sState = null;\n }\n }\n }\n\n if (sState) {\n if (fShutdown) {\n var fClear = false;\n var fClearAll = false;\n if (fSave) {\n if (this.sUserID) {\n this.saveServerState(this.sUserID, stateComputer.toString());\n }\n if (!stateValidate.store() || !stateComputer.store()) {\n sState = null;\n /*\n * New behavior as of v1.13.2: if it appears that localStorage is full, we blow it ALL away.\n * Dedicated server-side storage is the only way we'll ever be able to reliably preserve a\n * particular machine's state. Historically, attempting to limp along with whatever localStorage\n * is left just generates the same useless and annoying warnings over and over.\n */\n fClear = fClearAll = true;\n }\n }\n else {\n /*\n * I used to ALWAYS clear (ie, delete) any associated computer state, but now I do this only if the\n * current machine is \"resumable\", because there are situations where I have two configurations\n * for the same machine -- one resumable and one not -- and I don't want the latter throwing away the\n * state of the former.\n *\n * So this code is here now strictly for callers to delete the state of a \"resumable\" machine, not as\n * some paranoid clean-up operation.\n *\n * An undocumented feature of this operation is that if your configuration uses the special 'resume=\"3\"'\n * value, and you click the \"Reset\" button, and then you click OK to reset the everything, this will\n * actually reset EVERYTHING (ie, all localStorage for ALL configs will be reclaimed).\n */\n if (this.resume) {\n fClear = true;\n fClearAll = (this.resume == ComputerPDP10.RESUME_DELETE);\n }\n }\n if (fClear) {\n stateComputer.clear(fClearAll);\n }\n } else {\n sState = stateComputer.toString();\n }\n }\n\n if (fShutdown) {\n this.flags.powered = false;\n var controlPower = this.bindings[\"power\"];\n if (controlPower) controlPower.textContent = \"Power\";\n }\n\n this.nPowerChange = 0;\n\n return sState;\n }\n\n /**\n * reset()\n *\n * Notify all (other) components with a reset() method that the Computer is being reset.\n *\n * NOTE: We'd like to reset the Bus first (due to the importance of the A20 line), but since we\n * allocated the Bus object ourselves, after all the other components were allocated, it ends\n * up near the end of Component's list of components. Hence the special case for this.bus below.\n *\n * Ditto for the CPU, in part because if the Front Panel resets before the CPU, it will end up\n * snapping/displaying the PC as of the last instruction executed, before the CPU resets the PC,\n * causing the Front Panel to display a stale address when we call updateDisplays() at the end.\n *\n * @this {ComputerPDP10}\n */\n reset()\n {\n this.flags.reset = true;\n if (this.bus && this.bus.reset) {\n this.printMessage(\"Resetting \" + this.bus.type);\n this.bus.reset();\n }\n if (this.cpu && this.cpu.reset) {\n this.printMessage(\"Resetting \" + this.cpu.type);\n this.cpu.reset();\n }\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component !== this && component !== this.bus && component !== this.cpu && component.reset) {\n this.printMessage(\"Resetting \" + component.type);\n component.reset();\n }\n }\n this.flags.reset = false;\n this.updateDisplays(-1);\n }\n\n /**\n * start(ms, nCycles)\n *\n * Notify all (other) components with a start() method that the CPU has started.\n *\n * Note that we're called by startCPU(), which is why we exclude the CPU component,\n * as well as ourselves.\n *\n * @this {ComputerPDP10}\n * @param {number} ms\n * @param {number} nCycles\n */\n start(ms, nCycles)\n {\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.type == \"CPU\" || component === this) continue;\n if (component.start) {\n component.start(ms, nCycles);\n }\n }\n this.updateDisplays(-1);\n }\n\n /**\n * stop(ms, nCycles)\n *\n * Notify all (other) components with a stop() method that the CPU has stopped.\n *\n * Note that we're called by stopCPU(), which is why we exclude the CPU component,\n * as well as ourselves.\n *\n * @this {ComputerPDP10}\n * @param {number} ms\n * @param {number} nCycles\n */\n stop(ms, nCycles)\n {\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.type == \"CPU\" || component === this) continue;\n if (component.stop) {\n component.stop(ms, nCycles);\n }\n }\n this.updateDisplays(-1);\n }\n\n /**\n * updateDisplays(nUpdate)\n *\n * TODO: Notify all components with an updateDisplay() method that the computer's state has changed (not\n * just the hard-coded ones below).\n *\n * If any DOM controls were bound to the CPU, then we need to call its updateDisplay() handler; if there are no\n * such bindings, then cpu.updateDisplay() does nothing.\n *\n * Similarly, if there's a Panel, then we need to call its updateDisplay() handler, in case it created its own canvas\n * and implemented its own register display (eg, dumpRegisters()); if not, then panel.updateDisplay() also does nothing.\n *\n * In practice, there will *either* be a Panel with a custom canvas *or* a set of DOM controls bound to the CPU *or*\n * neither. In theory, there could be BOTH, but that would be unusual.\n *\n * TODO: Consider alternate approaches to these largely register-oriented display updates. Ordinarily, we like to\n * separate logic from presentation, and currently the CPUState contains both, since it's the component that intimately\n * knows the names, number, sizes, etc, of all the active registers. The Panel component is the logical candidate,\n * but Panel is an optional component; it's often the case that only machines that include the Debugger also include\n * Panel.\n *\n * @this {ComputerPDP10}\n * @param {number} [nUpdate] (1 for periodic, -1 for forced, 0 or undefined otherwise)\n */\n updateDisplays(nUpdate)\n {\n /*\n * nUpdate is generally set to -1 whenever the CPU is transitioning to/from a running state, in which case\n * cpu.updateDisplay() will definitely want to hide/show register contents; however, at other times, when the\n * CPU is running, constantly updating the DOM controls too frequently can adversely impact overall performance.\n *\n * nUpdate will also be -1 whenever the Debugger has modified the state of the machine, implying that we're\n * not sure what, if anything, actually changed.\n */\n if (this.cpu) this.cpu.updateDisplay(nUpdate || 0);\n if (this.panel) this.panel.updateDisplay(nUpdate || 0);\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {ComputerPDP10}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var computer = this;\n\n switch (sBinding) {\n case \"power\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickPower() {\n computer.onPower();\n };\n return true;\n\n case \"reset\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickReset() {\n computer.onReset();\n };\n return true;\n\n /*\n * Technically, this binding should now be called \"saveState\", to clearly distinguish it from\n * the \"Save Machine\" control that's normally bound to the savePC() function in save.js. Saving\n * an entire machine includes everything needed to start/restore the machine; eg, the machine\n * XML configuration file(s) *and* the JSON-encoded machine state.\n */\n case \"save\":\n /*\n * Since this feature depends on the server supporting the PCjs User API (see userapi.js),\n * and since pcjs.org is no longer running a Node web server, we disable the feature for that\n * particular host.\n */\n if (Str.endsWith(Web.getHost(), \"pcjs.org\")) {\n if (DEBUG) this.log(\"Remote user API not available\");\n /*\n * We could also simply hide the control; eg:\n *\n * control.style.display = \"none\";\n *\n * but removing the control altogether seems better.\n */\n control.parentNode.removeChild(/** @type {Node} */ (control));\n return false;\n }\n this.bindings[sBinding] = control;\n control.onclick = function onClickSave() {\n var sUserID = computer.queryUserID(true);\n if (sUserID) {\n /*\n * I modified the test to include a check for sStatePath so that I could save new states\n * for machines with existing states; otherwise, I'd have no (easy) way of capturing and\n * updating their state. Making the machine (even temporarily) resumable would have been\n * one work-around, but it's not appropriate for some machines, as their state is simply\n * too large (for localStorage anyway, which is the default storage solution).\n */\n var fSave = !!(computer.resume && !computer.sResumePath || computer.sStatePath);\n var sState = computer.powerOff(fSave);\n if (fSave) {\n computer.saveServerState(sUserID, sState);\n } else {\n computer.notice(\"Resume disabled, machine state not saved\");\n }\n }\n /*\n * This seemed like a handy alternative, but it turned out to be a no-go, at least for large states:\n *\n * var sState = computer.powerOff(true);\n * if (sState) {\n * sState = \"data:text/json;charset=utf-8,\" + encodeURIComponent(sState);\n * window.open(sState);\n * }\n *\n * Perhaps if I embedded the data in a link on the current page instead; eg:\n *\n * $('<a href=\"' + sState + '\" download=\"state.json\">Download</a>').appendTo('#container');\n */\n };\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * resetUserID()\n *\n * @this {ComputerPDP10}\n */\n resetUserID()\n {\n Web.setLocalStorageItem(ComputerPDP10.STATE_USERID, \"\");\n this.sUserID = null;\n }\n\n /**\n * queryUserID(fPrompt)\n *\n * @this {ComputerPDP10}\n * @param {boolean} [fPrompt]\n * @returns {string|null|undefined}\n */\n queryUserID(fPrompt)\n {\n var sUserID = this.sUserID;\n if (!sUserID) {\n sUserID = Web.getLocalStorageItem(ComputerPDP10.STATE_USERID);\n if (sUserID !== undefined) {\n if (!sUserID && fPrompt) {\n /*\n * NOTE: Warning the user here that \"Save\" operations are not currently supported by pcjs.org is\n * merely a precaution, because ordinarily, setBinding() should have already determined if we are\n * running from pcjs.org and disabled any \"Save\" button.\n */\n sUserID = Component.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.\");\n if (sUserID) {\n sUserID = this.verifyUserID(sUserID);\n if (!sUserID) this.notice(\"The user ID is invalid.\");\n }\n }\n } else if (fPrompt) {\n this.notice(\"Browser local storage is not available\");\n }\n }\n return sUserID;\n }\n\n /**\n * verifyUserID(sUserID)\n *\n * @this {ComputerPDP10}\n * @param {string} sUserID\n * @return {string} validated user ID, or null if error\n */\n verifyUserID(sUserID)\n {\n this.sUserID = null;\n var fMessages = DEBUG && this.messageEnabled();\n if (fMessages) this.printMessage(\"verifyUserID(\" + sUserID + \")\");\n var sRequest = Web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.VERIFY + '&' + UserAPI.QUERY.USER + '=' + sUserID;\n var response = Web.getResource(sRequest);\n var nErrorCode = response[0];\n var sResponse = response[1];\n if (!nErrorCode && sResponse) {\n try {\n response = eval(\"(\" + sResponse + \")\");\n if (response.code && response.code == UserAPI.CODE.OK) {\n Web.setLocalStorageItem(ComputerPDP10.STATE_USERID, response.data);\n if (fMessages) this.printMessage(ComputerPDP10.STATE_USERID + \" updated: \" + response.data);\n this.sUserID = response.data;\n } else {\n if (fMessages) this.printMessage(response.code + \": \" + response.data);\n }\n } catch (e) {\n Component.error(e.message + \" (\" + sResponse + \")\");\n }\n } else {\n if (fMessages) this.printMessage(\"invalid response (error \" + nErrorCode + \")\");\n }\n return this.sUserID;\n }\n\n /**\n * getServerStatePath()\n *\n * @this {ComputerPDP10}\n * @return {string|null} sStatePath (null if no localStorage or no USERID stored in localStorage)\n */\n getServerStatePath()\n {\n var sStatePath = null;\n if (this.sUserID) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(ComputerPDP10.STATE_USERID + \" for load: \" + this.sUserID);\n }\n sStatePath = Web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.LOAD + '&' + UserAPI.QUERY.USER + '=' + this.sUserID + '&' + UserAPI.QUERY.STATE + '=' + State.key(this, PDP10.APPVERSION);\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(ComputerPDP10.STATE_USERID + \" unavailable\");\n }\n }\n return sStatePath;\n }\n\n /**\n * saveServerState(sUserID, sState)\n *\n * @this {ComputerPDP10}\n * @param {string} sUserID\n * @param {string|null} sState\n */\n saveServerState(sUserID, sState)\n {\n /*\n * We must pass fSync == true, because (as I understand it) browsers will blow off any async\n * requests when a page is being closed. Since our request is synchronous, storeServerState()\n * should also return a result, but there's not much we can do with it, since browsers ALSO\n * tend to blow off alerts() and the like when closing down.\n */\n if (sState) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"size of server state: \" + sState.length + \" bytes\");\n }\n var response = this.storeServerState(sUserID, sState, true);\n if (response && response[UserAPI.RES.CODE] == UserAPI.CODE.OK) {\n this.notice(\"Machine state saved to server\");\n } else if (sState) {\n var sError = (response && response[UserAPI.RES.DATA]) || UserAPI.FAIL.BADSTORE;\n if (response[UserAPI.RES.CODE] == UserAPI.CODE.FAIL) {\n sError = \"Error: \" + sError;\n } else {\n sError = \"Error \" + response[UserAPI.RES.CODE] + \": \" + sError;\n }\n this.notice(sError);\n this.resetUserID();\n }\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"no state to store\");\n }\n }\n }\n\n /**\n * storeServerState(sUserID, sState, fSync)\n *\n * @this {ComputerPDP10}\n * @param {string} sUserID\n * @param {string} sState\n * @param {boolean} [fSync] is true if we're powering down and should perform a synchronous request (default is async)\n * @return {*} server response if fSync is true and a response was received; otherwise null\n */\n storeServerState(sUserID, sState, fSync)\n {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(ComputerPDP10.STATE_USERID + \" for store: \" + sUserID);\n }\n /*\n * TODO: Determine whether or not any browsers cancel our request if we're called during a browser \"shutdown\" event,\n * and whether or not it matters if we do an async request (currently, we're not, to try to ensure the request goes through).\n */\n var dataPost = {};\n dataPost[UserAPI.QUERY.REQ] = UserAPI.REQ.STORE;\n dataPost[UserAPI.QUERY.USER] = sUserID;\n dataPost[UserAPI.QUERY.STATE] = State.key(this, PDP10.APPVERSION);\n dataPost[UserAPI.QUERY.DATA] = sState;\n var sRequest = Web.getHost() + UserAPI.ENDPOINT;\n if (!fSync) {\n Web.getResource(sRequest, dataPost, true);\n } else {\n var response = Web.getResource(sRequest, dataPost);\n var sResponse = response[0];\n if (response[1]) {\n if (sResponse) {\n var i = sResponse.indexOf('\\n');\n if (i > 0) sResponse = sResponse.substr(0, i);\n if (!sResponse.indexOf(\"Error: \")) sResponse = sResponse.substr(7);\n }\n sResponse = '{\"' + UserAPI.RES.CODE + '\":' + response[1] + ',\"' + UserAPI.RES.DATA + '\":\"' + sResponse + '\"}';\n }\n if (DEBUG && this.messageEnabled()) this.printMessage(sResponse);\n return JSON.parse(sResponse);\n }\n return null;\n }\n\n /**\n * onPower()\n *\n * This handles UI requests to toggle the computer's power (eg, see the \"power\" button binding).\n *\n * @this {ComputerPDP10}\n */\n onPower()\n {\n if (!this.nPowerChange) {\n if (!this.flags.powered) {\n this.wait(this.powerOn);\n } else {\n this.powerOff(false, true);\n }\n }\n }\n\n /**\n * onReset()\n *\n * This handles UI requests to reset the computer's state (eg, see the \"reset\" button binding).\n *\n * @this {ComputerPDP10}\n */\n onReset()\n {\n /*\n * I'm going to start with the presumption that it makes little sense for an \"unpowered\" computer to be \"reset\";\n * ditto if the power state is currently being changed.\n */\n if (!this.flags.powered || this.nPowerChange) return;\n\n /*\n * If this is a \"resumable\" machine (and it's not using a predefined state), then we overload the reset\n * operation to offer an explicit \"save or discard\" option first. This is currently the only UI we offer to\n * discard a machine's state, including any disk changes. The traditional \"reset\" operation is still available\n * for non-resumable machines.\n *\n * TODO: Break this behavior out into a separate \"discard\" operation, in case the designer of the machine really\n * wants to clutter the UI with confusing options. ;-)\n */\n if (this.resume && !this.sResumePath) {\n /*\n * I used to bypass the prompt if this.resume == ComputerPDP10.RESUME_AUTO, setting fSave to true automatically,\n * but that gives the user no means of resetting a resumable machine that contains errors in its resume state.\n */\n var fSave = (/* this.resume == ComputerPDP10.RESUME_AUTO || */ Component.confirmUser(\"Click OK to save changes to this \" + PDP10.APPNAME + \" machine.\\n\\nWARNING: If you CANCEL, all disk changes will be discarded.\"));\n this.powerOff(fSave, true);\n /*\n * Forcing the page to reload is an expedient option, but ugly. It's preferable to call powerOn()\n * and rely on all the components to reset themselves to their default state. The components with\n * the greatest burden here are FDC and HDC, which must rely on the fReload flag to determine whether\n * or not to unload/reload all their original auto-mounted disk images.\n *\n * However, if we started with a predefined state (ie, sStatePath is set), we take this shortcut, because\n * we don't (yet) have code in place to gracefully reload the initial state (requires calling getResource()\n * again); alternatively, we could avoid throwing that state away, but it seems better to save the memory.\n *\n * TODO: Make this more graceful, so that we can stop using the reloadPage() sledgehammer.\n */\n if (!fSave && this.sStatePath) {\n Web.reloadPage();\n return;\n }\n if (!fSave) this.fReload = true;\n this.powerOn(ComputerPDP10.RESUME_NONE);\n this.fReload = false;\n } else {\n this.reset();\n if (this.cpu && !this.dbg) this.cpu.autoStart();\n }\n }\n\n /**\n * getMachineComponent(sType, componentPrev)\n *\n * @this {ComputerPDP10}\n * @param {string} sType\n * @param {Component|null} [componentPrev] of previously returned component, if any\n * @return {Component|null}\n */\n getMachineComponent(sType, componentPrev)\n {\n var componentLast = componentPrev;\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (componentPrev) {\n if (componentPrev == component) componentPrev = null;\n continue;\n }\n if (component.type == sType) return component;\n }\n if (!componentLast) Component.log(\"Machine component type '\" + sType + \"' not found\", \"warning\");\n return null;\n }\n\n /**\n * setFocus(fScroll)\n *\n * NOTE: When soft keyboard buttons call us to return focus to the machine (and away from the button),\n * the browser's default behavior is to scroll the element into view, which can be annoying, especially on iOS,\n * where the display is more constrained, so we no longer do it by default (fScroll must be true).\n *\n * @this {ComputerPDP10}\n * @param {boolean} [fScroll] (true if you really want the control scrolled into view)\n */\n setFocus(fScroll)\n {\n if (this.controlPrint) {\n /*\n * This seems to be recommended work-around to prevent the browser from scrolling the focused element\n * into view. The CPU is not a visual component, so when the CPU wants to set focus, the primary intent\n * is to ensure that keyboard input is fielded properly.\n */\n var x = 0, y = 0;\n if (!fScroll && window) {\n x = window.scrollX;\n y = window.scrollY;\n }\n\n this.controlPrint.focus();\n\n if (!fScroll && window) {\n window.scrollTo(x, y);\n }\n }\n }\n\n /**\n * ComputerPDP10.init()\n *\n * For every machine represented by an HTML element of class \"PDP10-machine\", this function\n * locates the HTML element of class \"computer\", extracting the JSON-encoded parameters for the\n * Computer constructor from the element's \"data-value\" attribute, invoking the constructor to\n * create a Computer component, and then binding any associated HTML controls to the new component.\n */\n static init()\n {\n /*\n * In non-COMPILED builds, embedMachine() may have set XMLVERSION.\n */\n if (!COMPILED && XMLVERSION) PDP10.APPVERSION = XMLVERSION;\n\n var aeMachines = Component.getElementsByClass(document, PDP10.APPCLASS + \"-machine\");\n\n for (var iMachine = 0; iMachine < aeMachines.length; iMachine++) {\n\n var eMachine = aeMachines[iMachine];\n var parmsMachine = Component.getComponentParms(eMachine);\n\n var aeComputers = Component.getElementsByClass(eMachine, PDP10.APPCLASS, \"computer\");\n\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n\n /*\n * We set fSuspended in the Computer constructor because we want to \"power up\" the\n * computer ourselves, after any/all bindings are in place.\n */\n var computer = new ComputerPDP10(parmsComputer, parmsMachine, true);\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onInit(\" + computer.flags.powered + \")\");\n }\n\n /*\n * Bind any \"power\", \"reset\" and \"save\" buttons. An \"erase\" button was also considered,\n * but \"reset\" now provides a way to force the machine to start from scratch again, so \"erase\"\n * may be redundant now.\n */\n Component.bindComponentControls(computer, eComputer, PDP10.APPCLASS);\n\n /*\n * Power on the computer, giving every component the opportunity to reset or restore itself.\n */\n if (computer.fAutoPower) computer.wait(computer.powerOn);\n }\n }\n }\n\n /**\n * ComputerPDP10.show()\n *\n * When exit() is using an \"onbeforeunload\" handler, this \"onpageshow\" handler allows us to repower everything,\n * without either resetting or restoring. We call powerOn() with a special resume value (RESUME_REPOWER) if the\n * computer is already marked as \"ready\", meaning the browser didn't change anything. This \"repower\" process\n * should be very quick, essentially just marking all components as powered again (so that, for example, the Video\n * component will start drawing again) and firing the CPU up again.\n */\n static show()\n {\n var aeComputers = Component.getElementsByClass(document, PDP10.APPCLASS, \"computer\");\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n var computer = /** @type {ComputerPDP10} */ (Component.getComponentByType(\"Computer\", parmsComputer['id']));\n if (computer) {\n\n computer.flags.unloading = false;\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onShow(\" + computer.fInitialized + \",\" + computer.flags.powered + \")\");\n }\n\n /*\n * Note that the FIRST 'onpageshow' event, and therefore the first show() callback, occurs\n * AFTER the the initial 'onload' event, and at that point in time, fInitialized will not be set yet.\n * So, practically speaking, the first show() callback isn't all that useful.\n */\n if (computer.fInitialized && !computer.flags.powered) {\n /**\n * Repower the computer, notifying every component to continue running as-is.\n */\n computer.powerOn(ComputerPDP10.RESUME_REPOWER);\n }\n }\n }\n }\n\n /**\n * ComputerPDP10.exit()\n *\n * The Computer is currently the only component that uses an \"exit\" handler, which Web.onExit() defines as\n * either an \"unload\" or \"onbeforeunload\" handler. This gives us the opportunity to save the machine state,\n * using our powerOff() function, before the page goes away.\n *\n * It's worth noting that \"onbeforeunload\" offers one nice feature when used instead of \"onload\": the entire\n * page (and therefore this entire application) is retained in its current state by the browser (well, some\n * browsers), so that if you go to a new URL, either by entering a new URL in the same window/tab, or by pressing\n * the FORWARD button, and then you press the BACK button, the page is immediately restored to its previous state.\n *\n * In fact, that's how some browsers operate whether you have an \"onbeforeunload\" handler or not; in other words,\n * an \"onbeforeunload\" handler doesn't change the page retention behavior of the browser. By contrast, the mere\n * presence of an \"onunload\" handler generally causes a browser to throw the page away once the handler returns.\n *\n * However, in order to safely use \"onbeforeunload\", we must add yet another handler (\"onpageshow\") to repower\n * everything, without either resetting or restoring. Hence, the ComputerPDP10.show() function, which calls powerOn()\n * with a special resume value (RESUME_REPOWER) if the computer is already marked as \"ready\", meaning the browser\n * didn't change anything. This \"repower\" process should be very quick, essentially just marking all components as\n * powered again (so that, for example, the Video component will start drawing again) and firing the CPU up again.\n *\n * Reportedly, some browsers (eg, Opera) don't support \"onbeforeunload\", in which case Component will have to use\n * \"unload\" instead. But even when the page must be rebuilt from scratch, the combination of browser cache and\n * localStorage means the simulation should be restored and become operational almost immediately.\n */\n static exit()\n {\n var aeComputers = Component.getElementsByClass(document, PDP10.APPCLASS, \"computer\");\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n var computer = /** @type {ComputerPDP10} */ (Component.getComponentByType(\"Computer\", parmsComputer['id']));\n if (computer) {\n\n /*\n * Added a new flag that Component functions (eg, notice()) should check before alerting the user.\n */\n computer.flags.unloading = true;\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onExit(\" + computer.flags.powered + \")\");\n }\n\n if (computer.flags.powered) {\n /**\n * Power off the computer, giving every component an opportunity to save its state,\n * but only if 'resume' has been set AND there is no valid resume path (because if a valid resume\n * path exists, we'll always load our state from there, and not from whatever we save here).\n */\n computer.powerOff(!!(computer.resume && !computer.sResumePath), true);\n }\n }\n }\n }\n}\n\nComputerPDP10.STATE_FAILSAFE = \"failsafe\";\nComputerPDP10.STATE_VALIDATE = \"validate\";\nComputerPDP10.STATE_TIMESTAMP = \"timestamp\";\nComputerPDP10.STATE_VERSION = \"version\";\nComputerPDP10.STATE_HOSTURL = \"url\";\nComputerPDP10.STATE_BROWSER = \"browser\";\nComputerPDP10.STATE_USERID = \"user\";\n\n/*\n * The following constants define all the resume options. Negative values (eg, RESUME_REPOWER) are for\n * internal use only, and RESUME_DELETE is not documented (it provides a way of deleting ALL saved states\n * whenever a resume is declined). As a result, the only \"end-user\" values are 0, 1 and 2.\n */\nComputerPDP10.RESUME_REPOWER = -1; // resume without changing any state (for internal use only)\nComputerPDP10.RESUME_NONE = 0; // default (no resume)\nComputerPDP10.RESUME_AUTO = 1; // automatically save/restore state\nComputerPDP10.RESUME_PROMPT = 2; // automatically save but conditionally restore (WARNING: if restore is declined, any state is discarded)\nComputerPDP10.RESUME_DELETE = 3; // same as RESUME_PROMPT but discards ALL machines states whenever ANY machine restore is declined (undocumented)\n\n/*\n * Initialize every Computer on the page.\n */\nWeb.onInit(ComputerPDP10.init);\nWeb.onShow(ComputerPDP10.show);\nWeb.onExit(ComputerPDP10.exit);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/state.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass State {\n /**\n * State(component, sVersion, sSuffix)\n *\n * State objects are used by components to save/restore their state.\n *\n * During a save operation, components add data to a State object via set(), and then return\n * the resulting data using data().\n *\n * During a restore operation, the Computer component passes the results of each data() call\n * back to the originating component.\n *\n * WARNING: Since State objects are low-level objects that have no UI requirements, they do not\n * inherit from the Component class, so you should only use class methods of Component, such as\n * Component.assert() (or Debugger methods if the Debugger is available).\n *\n * NOTE: 1.01 is the first version to provide limited save/restore support using localStorage.\n * From that point on, care must be taken to insure that any new version that's incompatible with\n * previous localStorage data be released with a version number that is at least 1 greater,\n * since we're tagging the localStorage data with the integer portion of the version string.\n *\n * @param {Component} component\n * @param {string} [sVersion] is used to append a major version number to the key\n * @param {string} [sSuffix] is used to append any additional suffixes to the key\n */\n constructor(component, sVersion, sSuffix)\n {\n this.id = component.id;\n this.dbg = component.dbg;\n this.json = \"\";\n this.state = {};\n this.fLoaded = this.fParsed = false;\n this.key = State.key(component, sVersion, sSuffix);\n this.unload(component.parms);\n }\n\n /**\n * set(id, data)\n *\n * @this {State}\n * @param {number|string} id\n * @param {Object|string} data\n */\n set(id, data)\n {\n try {\n this.state[id] = data;\n } catch(e) {\n Component.log(e.message);\n }\n }\n\n /**\n * get(id)\n *\n * @this {State}\n * @param {number|string} id\n * @return {Object|string|null}\n */\n get(id)\n {\n return this.state[id] || null;\n }\n\n /**\n * data()\n *\n * @this {State}\n * @return {Object}\n */\n data()\n {\n return this.state;\n }\n\n /**\n * load(json)\n *\n * WARNING: Make sure you follow this call with either a call to parse() or unload(),\n * because any stringified data that we've loaded isn't usable until it's been parsed.\n *\n * @this {State}\n * @param {string|null} [json]\n * @return {boolean} true if state exists in localStorage, false if not\n */\n load(json)\n {\n if (json) {\n this.json = json;\n this.fLoaded = true;\n this.fParsed = false;\n return true;\n }\n if (this.fLoaded) {\n /*\n * This is assumed to be a redundant load().\n */\n return true;\n }\n if (Web.hasLocalStorage()) {\n var s = Web.getLocalStorageItem(this.key);\n if (s) {\n this.json = s;\n this.fLoaded = true;\n if (DEBUG) Component.log(\"localStorage(\" + this.key + \"): \" + s.length + \" bytes loaded\");\n return true;\n }\n }\n return false;\n }\n\n /**\n * parse()\n *\n * This completes the load() operation, by parsing what was loaded, on the assumption there\n * might be some benefit to deferring parsing until we've given the user a chance to confirm.\n * Otherwise, load() could have just as easily done this, too.\n *\n * @this {State}\n * @return {boolean} true if successful, false if error\n */\n parse()\n {\n var fSuccess = true;\n if (!this.fParsed) {\n try {\n this.state = JSON.parse(this.json);\n this.fParsed = true;\n } catch (e) {\n Component.error(e.message || e);\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * store()\n *\n * @this {State}\n * @return {boolean} true if successful, false if error\n */\n store()\n {\n var fSuccess = true;\n if (Web.hasLocalStorage()) {\n var s = JSON.stringify(this.state);\n if (Web.setLocalStorageItem(this.key, s)) {\n if (DEBUG) Component.log(\"localStorage(\" + this.key + \"): \" + s.length + \" bytes stored\");\n } else {\n /*\n * WARNING: Because browsers tend to disable all alerts() during an \"unload\" operation,\n * it's unlikely anyone will ever see the \"quota\" errors that occur at this point. Need to\n * think of some way to notify the user that there's a problem, and offer a way of cleaning\n * up old states.\n */\n Component.error(\"Unable to store \" + s.length + \" bytes in browser local storage\");\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * toString()\n *\n * @this {State}\n * @return {string} JSON-encoded state\n */\n toString()\n {\n return this.state? JSON.stringify(this.state) : this.json;\n }\n\n /**\n * unload(parms)\n *\n * This discards any data saved via set() or loaded via load(), creating an empty State object.\n * Note that you have to follow this call with an explicit call to store() if you want to remove\n * the state from localStorage as well.\n *\n * @this {State}\n * @param {Object} [parms]\n */\n unload(parms)\n {\n this.json = \"\";\n this.state = {};\n this.fLoaded = this.fParsed = false;\n if (parms) this.set(\"parms\", parms);\n }\n\n /**\n * clear(fAll)\n *\n * This unloads the current state, and then clears ALL localStorage for the current machine,\n * independent of version, to reduce the chance of orphaned states wasting part of our limited allocation.\n *\n * @this {State}\n * @param {boolean} [fAll] true to unconditionally clear ALL localStorage for the current domain\n */\n clear(fAll)\n {\n this.unload();\n var aKeys = Web.getLocalStorageKeys();\n for (var i = 0; i < aKeys.length; i++) {\n var sKey = aKeys[i];\n if (sKey && (fAll || sKey.substr(0, this.key.length) == this.key)) {\n Web.removeLocalStorageItem(sKey);\n if (DEBUG) Component.log(\"localStorage(\" + sKey + \") removed\");\n aKeys.splice(i, 1);\n i = 0;\n }\n }\n }\n\n /**\n * State.key(component, sVersion, sSuffix)\n *\n * This encapsulates the key generation code.\n *\n * @param {Component} component\n * @param {string} [sVersion] is used to append a major version number to the key\n * @param {string} [sSuffix] is used to append any additional suffixes to the key\n * @return {string} key\n */\n static key(component, sVersion, sSuffix)\n {\n var key = component.id;\n if (sVersion) {\n var i = sVersion.indexOf('.');\n if (i > 0) key += \".v\" + sVersion.substr(0, i);\n }\n if (sSuffix) {\n key += \".\" + sSuffix;\n }\n return key;\n }\n\n /**\n * State.compress(aSrc)\n *\n * @param {Array.<number>|null} aSrc\n * @return {Array.<number>|null} is either the original array (aSrc), or a smaller array of \"count, value\" pairs (aComp)\n */\n static compress(aSrc)\n {\n if (aSrc) {\n var iSrc = 0;\n var iComp = 0;\n var aComp = [];\n while (iSrc < aSrc.length) {\n var n = aSrc[iSrc];\n\n var iCompare = iSrc + 1;\n while (iCompare < aSrc.length && aSrc[iCompare] === n) iCompare++;\n aComp[iComp++] = iCompare - iSrc;\n aComp[iComp++] = n;\n iSrc = iCompare;\n }\n if (aComp.length < aSrc.length) return aComp;\n }\n return aSrc;\n }\n\n /**\n * State.decompress(aComp)\n *\n * @param {Array.<number>} aComp\n * @param {number} nLength is expected length of decompressed data\n * @return {Array.<number>}\n */\n static decompress(aComp, nLength)\n {\n var iDst = 0;\n var aDst = new Array(nLength);\n var iComp = 0;\n while (iComp < aComp.length - 1) {\n var c = aComp[iComp++];\n var n = aComp[iComp++];\n while (c--) {\n aDst[iDst++] = n;\n }\n }\n\n return aDst;\n }\n\n /**\n * State.compressEvenOdd(aSrc)\n *\n * This is a very simple variation on compress() that compresses all the EVEN elements of aSrc first,\n * followed by all the ODD elements. This tends to work better on EGA video memory, because when odd/even\n * addressing is enabled (eg, for text modes), the DWORD values tend to alternate, which is the worst case\n * for compress(), but the best case for compressEvenOdd().\n *\n * One wrinkle we support: if the first element is uninitialized, then we assume the entire array is undefined,\n * and return an empty compressed array. Conversely, decompressEvenOdd() will take an empty compressed array\n * and return an uninitialized array.\n *\n * @param {Array.<number>|null} aSrc\n * @return {Array.<number>|null} is either the original array (aSrc), or a smaller array of \"count, value\" pairs (aComp)\n */\n static compressEvenOdd(aSrc)\n {\n if (aSrc) {\n var iComp = 0, aComp = [];\n if (aSrc[0] !== undefined) {\n for (var off = 0; off < 2; off++) {\n var iSrc = off;\n while (iSrc < aSrc.length) {\n var n = aSrc[iSrc];\n var iCompare = iSrc + 2;\n while (iCompare < aSrc.length && aSrc[iCompare] === n) iCompare += 2;\n aComp[iComp++] = (iCompare - iSrc) >> 1;\n aComp[iComp++] = n;\n iSrc = iCompare;\n }\n }\n }\n if (aComp.length < aSrc.length) return aComp;\n }\n return aSrc;\n }\n\n /**\n * State.decompressEvenOdd(aComp, nLength)\n *\n * This is the counterpart to compressEvenOdd(). Note that because there's nothing in the compressed sequence\n * that differentiates a compress() sequence from a compressEvenOdd() sequence, you simply have to be consistent:\n * if you used even/odd compression, then you must use even/odd decompression.\n *\n * @param {Array.<number>} aComp\n * @param {number} nLength is expected length of decompressed data\n * @return {Array.<number>}\n */\n static decompressEvenOdd(aComp, nLength)\n {\n var iDst = 0;\n var aDst = new Array(nLength);\n var iComp = 0;\n while (iComp < aComp.length - 1) {\n var c = aComp[iComp++];\n var n = aComp[iComp++];\n while (c--) {\n aDst[iDst] = n;\n iDst += 2;\n }\n /*\n * The output of a \"count,value\" pair will never exceed the end of the output array, so as soon as we reach it\n * the first time, we know it's time to switch to ODD elements, and as soon as we reach it again, we should be\n * done.\n */\n\n if (iDst == nLength) iDst = 1;\n }\n\n return aDst;\n }\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/embed.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * We now support asynchronous XML and XSL file loads; simply set fAsync (below) to true.\n *\n * NOTE: For that support to work, we have to keep track of the number of machines on the page\n * (ie, how many embedMachine() calls were issued), reduce the count as each machine XML file\n * is fully transformed into HTML, and when the count finally returns to zero, notify all the\n * machine component init() handlers.\n *\n * Also, to prevent those init() handlers from running prematurely, we must disable all page\n * notification events at the start of the embedding process (Web.enablePageEvents(false)) and\n * re-enable them at the end (Web.enablePageEvents(true)).\n */\nvar fAsync = true;\nvar cAsyncMachines = 0;\n\n/**\n * loadXML(sFile, idMachine, sAppName, sAppClass, sParms, fResolve, display, done)\n *\n * This is the preferred way to load all XML and XSL files. It uses getResource()\n * to load them as strings, which parseXML() can massage before parsing/transforming them.\n *\n * For example, since I've been unable to get the XSLT document() function to work inside any\n * XSL document loaded by JavaScript's XSLT processor, that has prevented me from dynamically\n * loading any XML machine file that uses the \"ref\" attribute to refer to and incorporate\n * another XML document.\n *\n * To solve that, I've added an fResolve parameter that tells parseXML() to fetch any\n * referenced documents ITSELF and insert them into the XML string prior to parsing, instead\n * of relying on the XSLT template to pull them in. That fetching is handled by resolveXML(),\n * which iterates over the XML until all \"refs\" have been resolved (including any nested\n * references).\n *\n * Also, XSL files with a <!DOCTYPE [...]> cause MSIE's Microsoft.XMLDOM.loadXML() function\n * to choke, so I strip that out prior to parsing as well.\n *\n * TODO: Figure out why the XSLT document() function works great when the web browser loads an\n * XML file (and the associated XSL file) itself, but does not work when loading documents via\n * JavaScript XSLT support. Is it broken, is it a security issue, or am I just calling it wrong?\n *\n * @param {string} sXMLFile\n * @param {string|null|undefined} idMachine\n * @param {string|null|undefined} sAppName\n * @param {string|null|undefined} sAppClass\n * @param {string|null|undefined} sParms (machine parameters, if any)\n * @param {string|null|undefined} sClass (an optional machine class name used to style the machine)\n * @param {boolean} fResolve is true to resolve any \"ref\" attributes\n * @param {function(string)} display\n * @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)\n */\nfunction loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n{\n var doneLoadXML = function(sURLName, sXML, nErrorCode) {\n if (nErrorCode) {\n if (!sXML) sXML = \"unable to load \" + sXMLFile + \" (\" + nErrorCode + \")\";\n done(sXML, null);\n return;\n }\n parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done);\n };\n display(\"Loading \" + sXMLFile + \"...\");\n Web.getResource(sXMLFile, null, fAsync, doneLoadXML);\n}\n\n/**\n * parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n *\n * Generates an XML document from an XML string. This function also provides a work-around for XSLT's\n * lack of support for the document() function (at least on some browsers), by replacing every reference\n * tag (ie, a tag with a \"ref\" attribute) with the contents of the referenced file.\n *\n * @param {string} sXML\n * @param {string|null} sXMLFile\n * @param {string|null|undefined} idMachine\n * @param {string|null|undefined} sAppName\n * @param {string|null|undefined} sAppClass\n * @param {string|null|undefined} sParms (machine parameters, if any)\n * @param {string|null|undefined} sClass (an optional machine class name used to style the machine)\n * @param {boolean} fResolve is true to resolve any \"ref\" attributes; default is false\n * @param {function(string)} display\n * @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)\n */\nfunction parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n{\n var buildXML = function(sXML, sError) {\n if (sError) {\n done(sError, null);\n return;\n }\n if (idMachine) {\n\n /*\n * A more sensible place to record the machine XML would be embedMachine(), like we do for the\n * XSL file, but since we're about to modify the original machine XML, it's best to record it now.\n */\n Component.addMachineResource(idMachine, sXMLFile, sXML);\n\n var sURL = sXMLFile;\n if (sURL && sURL.indexOf('/') < 0 && window.location.pathname.slice(-1) == '/') {\n sURL = window.location.pathname + sURL;\n }\n /*\n * We embed the URL of the XML file both as a separate \"xml\" attribute for easy access from the\n * XSL file, and as part of the \"parms\" attribute for easy access from machines (see getMachineParm()).\n */\n if (!sParms) {\n sParms = '{';\n } else if (sParms.slice(-1) == '}') {\n sParms = sParms.slice(0, -1);\n if (sParms.length > 1) sParms += ',';\n } else { // sParms must just be a \"state\" file, so encode it as a \"state\" property\n sParms = '{state:\"' + sParms + '\",';\n }\n sParms += 'url:\"' + sURL + '\"}';\n /*\n * Note that while we no longer generate a machine XML file with a \"state\" attribute (because it's\n * encoded inside the \"parms\" attribute), the XSL file must still cope with \"state\" attributes inside\n * other XML files; for example, manifest XML files like /apps/pcx86/1981/visicalc/manifest.xml contain\n * machine elements with \"state\" attributes that must still be passed down to the computer element\n * \"the old fashioned way\".\n *\n * Until/unless that changes, components.xsl cannot be simplified as much as I might have hoped.\n */\n if (typeof resources == 'object') sURL = null; // turn off URL inclusion if we have embedded resources\n sParms = sParms.replace(/\\$/g, \"$$$$\");\n if (sClass) {\n /*\n * If there's no hard-coded \"class\" attribute in the machine tag, then we can set one in the final\n * replacement below, just like we do for sParms and sURL. However, if a \"class\" attribute already\n * exists, we need alter it and then zap the sClass variable.\n */\n var match = sXML.match(/(<machine[^>]*\\sclass=)(['\"])(.*?)(\\2.*?>)/);\n if (match) {\n sXML = sXML.replace(match[0], match[1] + match[2] + sClass + match[4]);\n sClass = null;\n }\n }\n sXML = sXML.replace(/(<machine[^>]*\\sid=)(['\"]).*?\\2/, \"$1$2\" + idMachine + \"$2\" + (sClass? ' class=\"' + sClass + '\"' : '') + (sParms? \" parms='\" + sParms + \"'\" : \"\") + (sURL? ' url=\"' + sURL + '\"' : ''));\n }\n\n if (!fResolve) {\n /*\n * I'm trying to switch to a shared components.xsl (at least for all PC-class machines),\n * but in the interim, that means hacking the XSL file on the fly to reflect the actual class.\n */\n sXML = sXML.replace(/(<xsl:variable name=\"APPNAME\">).*?(<\\/xsl:variable>)/, \"$1\" + sAppName + \"$2\");\n sXML = sXML.replace(/(<xsl:variable name=\"APPCLASS\">).*?(<\\/xsl:variable>)/, \"$1\" + sAppClass + \"$2\");\n\n /*\n * Non-COMPILED kludge to replace the version number template in the XSL file (which we assume we're reading,\n * since fResolve is false) with whatever XMLVERSION we extracted from the XML file (see corresponding kludge below).\n *\n * ES6 ALERT: Template strings.\n */\n if (!COMPILED && XMLVERSION) {\n sXML = sXML.replace(/<xsl:variable name=\"APPVERSION\"\\/>/, `<xsl:variable name=\"APPVERSION\">${XMLVERSION}</xsl:variable>`);\n }\n }\n\n /*\n * If the resource we requested is not really an XML file (or the file didn't exist and the server simply returned\n * a message like \"Cannot GET /devices/pc/machine/5150/cga/64kb/donkey/machine.xml\"), we'd like to display a more\n * meaningful message, because the XML DOM parsers will blithely return a document that contains nothing useful; eg:\n *\n * This page contains the following errors:error on line 1 at column 1:\n * Document is empty Below is a rendering of the page up to the first error.\n *\n * Supposedly, the IE XML DOM parser will throw an exception, but I haven't tested that, and unless all other\n * browsers do that, that's not helpful.\n *\n * The best I can do at this stage (assuming Web.getResource() didn't drop any error information on the floor)\n * is verify that the requested resource \"looks like\" valid XML (in other words, it begins with a '<').\n */\n var xmlDoc = null;\n if (sXML.charAt(0) == '<') {\n try {\n /*\n * Another hack for MSIE, which fails to load XSL documents containing a <!DOCTYPE [...]> tag.\n *\n * This is also why the XSLTProcessor 'transformToFragment' method in Microsoft Edge silently failed,\n * so I had pull this hack out of the \"ActiveXObject\" code. And rather than add yet-another Microsoft\n * browser check, I'm going to try doing this across the board, and hope that none of the other XSLT\n * processors fail *without* the DOCTYPE tag.\n */\n if (!fResolve) {\n sXML = sXML.replace(/<!DOCTYPE(.|[\\r\\n])*]>\\s*/g, \"\");\n }\n /*\n * Beginning with Microsoft Edge and the corresponding release of Windows 10, all the\n * 'ActiveXObject' crud has gone away; but of course, this code must remain in place if\n * we want to continue supporting older Internet Explorer browsers (ie, back to IE9).\n */\n /** @namespace window.ActiveXObject */\n if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1\n xmlDoc = new window.ActiveXObject(\"Microsoft.XMLDOM\");\n xmlDoc.async = false;\n xmlDoc['loadXML'](sXML);\n } else {\n /** @namespace window.DOMParser */\n xmlDoc = (new window.DOMParser()).parseFromString(sXML, \"text/xml\");\n }\n } catch(e) {\n xmlDoc = null;\n sXML = e.message;\n }\n } else {\n sXML = \"unrecognized XML: \" + (sXML.length > 255? sXML.substr(0, 255) + \"...\" : sXML);\n }\n done(sXML, xmlDoc);\n };\n if (sXML) {\n if (PRIVATE) sXML = sXML.replace(/\\/library.xml/, \"/private/library.xml\");\n if (fResolve) {\n resolveXML(sXML, display, buildXML);\n return;\n }\n buildXML(sXML, null);\n return;\n }\n done(\"no data\" + (sXMLFile? \" for file: \" + sXMLFile : \"\"), null);\n}\n\n/**\n * resolveXML(sXML, display, done)\n *\n * Replaces every tag with a \"ref\" attribute with the contents of the corresponding file.\n *\n * TODO: Fix some of the limitations of this code, such as: 1) requiring the \"ref\" attribute\n * to appear as the tag's first attribute, 2) requiring the \"ref\" attribute to be double-quoted,\n * and 3) requiring the \"ref\" tag to be self-closing.\n *\n * @param {string} sXML\n * @param {function(string)} display\n * @param {function(string,(string|null))} done (the first string contains the resolved XML data, the second is for any error message)\n */\nfunction resolveXML(sXML, display, done)\n{\n var matchRef;\n var reRef = /<([a-z]+)\\s+ref=\"(.*?)\"(.*?)\\/>/g;\n\n if ((matchRef = reRef.exec(sXML))) {\n\n var sRefFile = matchRef[2];\n\n var doneReadXML = function(sURLName, sXMLRef, nErrorCode) {\n if (nErrorCode || !sXMLRef) {\n done(sXML, \"unable to resolve XML reference: \" + matchRef[0] + \" (\" + nErrorCode + \")\");\n return;\n }\n /*\n * If there are additional attributes in the \"referring\" XML tag, we want to insert them\n * into the \"referred\" XML tag; attributes that don't exist in the referred tag should be\n * appended, and attributes that DO exist should be overwritten.\n */\n var sRefAttrs = matchRef[3];\n if (sRefAttrs) {\n var aXMLRefTag = sXMLRef.match(new RegExp(\"<\" + matchRef[1] + \"[^>]*>\"));\n if (aXMLRefTag) {\n var sXMLNewTag = aXMLRefTag[0];\n /*\n * Iterate over all the attributes in the \"referring\" XML tag (sRefAttrs)\n */\n var matchAttr;\n var reAttr = /( [a-z]+=)(['\"])(.*?)\\2/gi;\n while ((matchAttr = reAttr.exec(sRefAttrs))) {\n if (sXMLNewTag.toLowerCase().indexOf(matchAttr[1].toLowerCase()) < 0) {\n /*\n * This is the append case....\n */\n sXMLNewTag = sXMLNewTag.replace(\">\", matchAttr[0] + \">\");\n } else {\n /*\n * This is the overwrite case....\n */\n sXMLNewTag = sXMLNewTag.replace(new RegExp(matchAttr[1] + \"(['\\\"])(.*?)\\\\1\"), matchAttr[0]);\n }\n }\n if (aXMLRefTag[0] != sXMLNewTag) {\n sXMLRef = sXMLRef.replace(aXMLRefTag[0], sXMLNewTag);\n }\n } else {\n done(sXML, \"missing <\" + matchRef[1] + \"> in \" + sRefFile);\n return;\n }\n }\n\n /*\n * Apparently when a Windows Azure server delivers one of my XML files, it may modify the first line:\n *\n * <?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n\n *\n * I didn't determine exactly what it was doing at this point (probably just changing the \\n to \\r\\n),\n * but in any case, relaxing the following replace() solved it.\n */\n sXMLRef = sXMLRef.replace(/<\\?xml[^>]*>[\\r\\n]*/, \"\");\n\n sXML = sXML.replace(matchRef[0], sXMLRef);\n\n resolveXML(sXML, display, done);\n };\n\n display(\"Loading \" + sRefFile + \"...\");\n Web.getResource(sRefFile, null, fAsync, doneReadXML);\n return;\n }\n done(sXML, null);\n}\n\n/**\n * embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * This allows to you embed a machine on a web page, by transforming the machine XML into HTML.\n *\n * @param {string} sAppName is the app name (eg, \"PCx86\")\n * @param {string} sAppClass is the app class (eg, \"pcx86\"); also known as the machine class\n * @param {string} sVersion is the app version (eg, \"1.15.7\")\n * @param {string} idMachine\n * @param {string|undefined} sXMLFile\n * @param {string|undefined} sXSLFile\n * @param {string|undefined} sParms (machine parameters, if any)\n * @param {string|undefined} sClass (an optional machine class name used to style the machine)\n * @return {boolean} true if successful, false if error\n */\nfunction embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n var eMachine, eWarning, fSuccess = true;\n\n if (!sXMLFile) {\n sXMLFile = \"machine.xml\";\n if (!sXSLFile) sXSLFile = \"components.xsl\";\n }\n \n cAsyncMachines++;\n Component.addMachine(idMachine);\n\n var doneMachine = function() {\n\n if (!--cAsyncMachines) {\n if (fAsync) Web.enablePageEvents(true);\n }\n };\n\n var displayError = function(sError) {\n Component.log(sError);\n displayMessage(\"Error: \" + sError);\n if (fSuccess) doneMachine();\n fSuccess = false;\n };\n\n var displayMessage = function(sMessage) {\n if (eWarning === undefined) {\n /*\n * Our MarkOut module (in convertMDMachineLinks()) creates machine containers that look like:\n *\n * <div id=\"' + sMachineID + '\" class=\"machine-placeholder\"><p>Embedded PC</p><p class=\"machine-warning\">...</p></div>\n *\n * with the \"machine-warning\" paragraph pre-populated with a warning message that the user will\n * see if nothing at all happens. But hopefully, in the normal case (and especially the error case),\n * *something* will have happened.\n *\n * Note that it is the HTMLOut module (in processMachines()) that ultimately decides which scripts to\n * include and then generates the embedXXX() call.\n */\n var aeWarning = (eMachine && Component.getElementsByClass(eMachine, \"machine-warning\"));\n eWarning = (aeWarning && aeWarning[0]) || eMachine;\n }\n if (eWarning) eWarning.innerHTML = Str.escapeHTML(sMessage);\n };\n\n try {\n eMachine = document.getElementById(idMachine);\n if (eMachine) {\n\n /*\n * If we have a 'css' resource, add it to the page first.\n */\n var css;\n if (typeof resources == \"object\" && (css = resources['css'])) {\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n // noinspection JSDeprecatedSymbols\n if (style.styleSheet) {\n // noinspection JSDeprecatedSymbols\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n head.appendChild(style);\n }\n\n if (!sXSLFile) {\n /*\n * Now that PCjs is an open-source project, we can make the following test more flexible,\n * and revert to the internal template if DEBUG *or* internal version (instead of *and*).\n *\n * Third-party sites that don't use the PCjs server will ALWAYS want to specify a fully-qualified\n * path to the XSL file, unless they choose to mirror our folder structure.\n */\n var sAppFolder = sAppClass;\n if (DEBUG || !sVersion) {\n if (sAppClass != \"c1pjs\") sAppFolder = \"shared\";\n sXSLFile = \"/modules/\" + sAppFolder + \"/templates/components.xsl\";\n } else {\n if (sAppClass.substr(0, 3) == \"pdp\") sAppFolder = \"pdpjs\";\n sXSLFile = \"/versions/\" + sAppFolder + \"/\" + sVersion + \"/components.xsl\";\n }\n }\n\n var processXML = function(sXML, xml) {\n if (!xml) {\n displayError(sXML);\n return;\n }\n\n /*\n * Non-COMPILED kludge to extract the version number from the stylesheet path in the machine XML file;\n * we don't need this code in COMPILED (non-DEBUG) releases, because APPVERSION is hard-coded into them.\n */\n if (!COMPILED) {\n var aMatch = sXML.match(/<\\?xml-stylesheet[^>]* href=(['\"])[^'\"]*?\\/([0-9.]*)\\/([^'\"]*)\\1/);\n if (aMatch) {\n XMLVERSION = aMatch[2];\n }\n }\n\n var transformXML = function(sXSL, xsl) {\n if (!xsl) {\n displayError(sXSL);\n return;\n }\n\n /*\n * Record the XSL file, in case someone wants to save the entire machine later.\n * \n * NOTE: sXSLFile will never be undefined by this point, but apparently the Closure Compiler doesn't realize that. \n */\n Component.addMachineResource(idMachine, sXSLFile || \"\", sXSL);\n\n /*\n * The <machine> template in components.xsl now generates a \"machine div\" that makes\n * the div we required the caller of embedMachine() to provide redundant, so instead\n * of appending this fragment to the caller's node, we REPLACE the caller's node.\n * This works only because because we ALSO inject the caller's \"machine div\" ID into\n * the fragment's ID during parseXML().\n *\n * eMachine.innerHTML = sFragment;\n *\n * Also, if the transform function fails, make sure you're using the appropriate\n * \"components.xsl\" and not a \"machine.xsl\", because the latter will not produce valid\n * embeddable HTML (and is the most common cause of failure at this final stage).\n */\n displayMessage(\"Processing \" + sXMLFile + \"...\");\n\n /*\n * Beginning with Microsoft Edge and the corresponding release of Windows 10, all the\n * 'ActiveXObject' crud has gone away; but of course, this code must remain in place if\n * we want to continue supporting older Internet Explorer browsers (ie, back to IE9).\n */\n if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1\n var sFragment = xml['transformNode'](xsl);\n if (sFragment) {\n eMachine.outerHTML = sFragment;\n doneMachine();\n } else {\n displayError(\"transformNodeToObject failed\");\n }\n }\n else if (document.implementation && document.implementation.createDocument) {\n var xsltProcessor = new XSLTProcessor();\n xsltProcessor['importStylesheet'](xsl);\n var eFragment = xsltProcessor['transformToFragment'](xml, document);\n if (eFragment) {\n /*\n * This fails in Microsoft Edge...\n *\n var machine = eFragment.getElementById(idMachine);\n if (!machine) {\n displayError(\"machine generation failed: \" + idMachine);\n } else\n */\n if (eMachine.parentNode) {\n eMachine.parentNode.replaceChild(eFragment, eMachine);\n doneMachine();\n } else {\n /*\n * NOTE: This error can occur if our Node web server, when processing a folder with\n * both a manifest.xml with a machine.xml reference AND a README.md containing a\n * machine link, generates duplicate embedXXX() calls for the same machine; if the\n * first embedXXX() call finds its target, subsequent calls for the same target will\n * fail.\n *\n * Technically, such a folder is in a misconfigured state, but it happens, in part\n * because when we switched to the Jekyll web server, we had to add machine links to\n * all README.md files where we had previously relied on manifest.xml or machine.xml\n * processing. This is because the Jekyll web server currently doesn't process XML\n * files, nor is support for that likely to be added any time soon; it was a nice\n * feature of the Node web server, but it's not clear that it's worth doing for Jekyll.\n */\n displayError(\"invalid machine element: \" + idMachine);\n }\n } else {\n displayError(\"transformToFragment failed\");\n }\n } else {\n /*\n * Perhaps I should have performed this test at the outset; on the other hand, I'm\n * not aware of any browsers don't support one or both of the above XSLT transformation\n * methods, so treat this as a bug.\n */\n displayError(\"unable to transform XML: unsupported browser\");\n }\n };\n /*\n * NOTE: sXSLFile will never be undefined by this point, but apparently the Closure Compiler doesn't realize that. \n */\n loadXML(sXSLFile || \"\", null, sAppName, sAppClass, null, null, false, displayMessage, transformXML);\n };\n\n if (sXMLFile.charAt(0) != '<') {\n loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, true, displayMessage, processXML);\n } else {\n parseXML(sXMLFile, null, idMachine, sAppName, sAppClass, sParms, sClass, false, displayMessage, processXML);\n }\n } else {\n displayError(\"missing machine element: \" + idMachine);\n }\n } catch(e) {\n displayError(e.message);\n }\n return fSuccess;\n}\n\n/**\n * embedC1P(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedC1P(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"C1Pjs\", \"c1pjs\", APPVERSION, idMachine, sXMLFile, sXSLFile, undefined, sClass);\n}\n\n/**\n * embedPCx86(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPCx86(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PCx86\", \"pcx86\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPC8080(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPC8080(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PC8080\", \"pc8080\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPDP10(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPDP10(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PDPjs\", \"pdp10\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPDP11(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPDP11(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PDPjs\", \"pdp11\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * findMachineComponent(idMachine, sType)\n *\n * @param {string} idMachine\n * @param {string} sType\n * @return {Component|null}\n */\nfunction findMachineComponent(idMachine, sType)\n{\n return Component.getComponentByType(sType, idMachine + \".machine\");\n}\n\n/**\n * commandMachine(control, fSingle, idMachine, sComponent, sCommand, sValue)\n *\n * Use Component methods to find the requested component for a specific machine, and if the component is found,\n * then check its 'exports' table for an entry matching the specified command string, and if an entry is found, then\n * the corresponding function is called with the specified data.\n *\n * @param {Object} control\n * @param {boolean} fSingle\n * @param {string} idMachine\n * @param {string} sComponent\n * @param {string} sCommand\n * @param {string} [sValue]\n * @return {boolean}\n */\nfunction commandMachine(control, fSingle, idMachine, sComponent, sCommand, sValue)\n{\n if (sCommand == \"script\") {\n if (Component.processScript(idMachine, sValue)) {\n if (fSingle) control.disabled = true;\n return true;\n }\n return false;\n }\n if (sComponent) {\n var component = Component.getComponentByType(sComponent, idMachine + \".machine\");\n if (component) {\n var exports = component['exports'];\n if (exports) {\n var fnCommand = exports[sCommand];\n if (fnCommand) {\n if (fnCommand.call(component, sValue)) {\n if (fSingle) control.disabled = true;\n return true;\n }\n return false;\n }\n }\n }\n }\n console.log(\"unimplemented: commandMachine('\" + idMachine + \"','\" + sComponent + \"','\" + sCommand + \"','\" + sValue + \"')\");\n return false;\n}\n\n/**\n * Prevent the Closure Compiler from renaming functions we want to export, by adding them as global properties.\n *\n * TODO: Consider making all these functions properties on a single global object (eg, 'PCjs'), to minimize global\n * pollution and risk of name collision.\n */\nif (APPNAME == \"C1Pjs\") {\n window['embedC1P'] = embedC1P;\n}\nif (APPNAME == \"PCx86\") {\n window['embedPC'] = embedPCx86; // WARNING: embedPC() deprecated as of v1.23.0\n window['embedPCx86'] = embedPCx86;\n}\nif (APPNAME == \"PC8080\") {\n window['embedPC8080'] = embedPC8080;\n}\nif (APPNAME == \"PDPjs\") {\n window['embedPDP10'] = embedPDP10;\n window['embedPDP11'] = embedPDP11;\n}\n\nwindow['commandMachine'] = commandMachine;\n\nwindow['enableEvents'] = Web.enablePageEvents;\nwindow['sendEvent'] = Web.sendPageEvent;\n"]} \ No newline at end of file diff --git a/versions/pdpjs/1.61.0/pdp11-uncompiled.js b/versions/pdpjs/1.61.0/pdp11-uncompiled.js index 7283bcf49f..441c640a02 100644 --- a/versions/pdpjs/1.61.0/pdp11-uncompiled.js +++ b/versions/pdpjs/1.61.0/pdp11-uncompiled.js @@ -857,7 +857,7 @@ class Str { * * Displays the given number as an unsigned integer using the specified radix and number of digits. * - * @param {number|null|undefined} n + * @param {number|*} n * @param {number} radix (ie, the base) * @param {number} cch (the desired number of digits) * @param {string} [sPrefix] (default is none) @@ -867,17 +867,17 @@ class Str { static toBase(n, radix, cch, sPrefix = "", nGrouping = 0) { /* - * An initial "falsey" check for null takes care of both null and undefined; - * we can't rely entirely on isNaN(), because isNaN(null) returns false, oddly enough. + * We can't rely entirely on isNaN(), because isNaN(null) returns false, and we can't rely + * entirely on typeof either, because typeof Nan returns "number". Sigh. * * Alternatively, we could mask and shift n regardless of whether it's null/undefined/NaN, * since JavaScript coerces such operands to zero, but I think there's "value" in seeing those * values displayed differently. */ var s = ""; - if (isNaN(n)) { + if (isNaN(n) || typeof n != "number") { n = null; - } else if (n != null) { + } else { /* * Callers that produced an input by dividing by a power of two rather than shifting (in order * to access more than 32 bits) may produce a fractional result, which ordinarily we would simply @@ -920,7 +920,7 @@ class Str { * * Converts an integer to binary, with the specified number of digits (up to a maximum of 36). * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of binary digits (0 or undefined for default of either 8, 18, or 36) * @param {number} [nGrouping] * @return {string} the binary representation of n @@ -972,7 +972,7 @@ class Str { * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw * an exception, whereas this function will return '?' characters. * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of octal digits (0 or undefined for default of either 6, 8, or 12) * @param {boolean} [fPrefix] * @return {string} the octal representation of n @@ -1002,7 +1002,7 @@ class Str { * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw * an exception, whereas this function will return '?' characters. * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of decimal digits (0 or undefined for default of either 5 or 11) * @return {string} the decimal representation of n */ @@ -1037,7 +1037,7 @@ class Str { * s = "00000000".substr(0, 8 - s.length) + s; * s = s.substr(0, cch).toUpperCase(); * - * @param {number|null|undefined} n (supports integers up to 36 bits now) + * @param {number|*} n (supports integers up to 36 bits now) * @param {number} [cch] is the desired number of hex digits (0 or undefined for default of either 4, 8, or 9) * @param {boolean} [fPrefix] * @return {string} the hex representation of n @@ -3367,7 +3367,7 @@ class Component { if (target) { var control = target.bindings[sBinding]; if (control) { - component.setBinding(null, sBinding, control); + component.setBinding("", sBinding, control); } } } @@ -3855,7 +3855,7 @@ class Component { * Component's setBinding() method is intended to be overridden by subclasses. * * @this {Component} - * @param {string|null} sHTMLType is the type of the HTML control (eg, "button", "list", "text", "submit", "textarea", "canvas") + * @param {string} 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, 'print') * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement) * @param {string} [sValue] optional data value @@ -4308,10 +4308,10 @@ class Component { * * @this {Component} * @param {number} port - * @param {number|null} bOut if an output operation - * @param {number|null} [addrFrom] - * @param {string|null} [name] of the port, if any - * @param {number|null} [bIn] is the input value, if known, on an input operation + * @param {number|null|*} bOut if an output operation + * @param {number|null|*} [addrFrom] + * @param {string|null|*} [name] of the port, if any + * @param {number|null|*} [bIn] is the input value, if known, on an input operation * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s) */ printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage) @@ -5758,7 +5758,7 @@ class PanelPDP11 extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * Some panel layouts don't have bindings of their own, and even when they do, there may still be some * components (eg, the CPU) that prefer to update their own bindings, so we pass along all binding requests @@ -5766,23 +5766,17 @@ class PanelPDP11 extends Component { * component that doesn't recognize the specified binding should simply ignore it. * * @this {PanelPDP11} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "reset") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { - if (this.cmp && this.cmp.setBinding(sType, sBinding, control, sValue)) { - return true; - } - if (this.cpu && this.cpu.setBinding(sType, sBinding, control, sValue)) { - return true; - } - if (DEBUGGER && this.dbg && this.dbg.setBinding(sType, sBinding, control, sValue)) { - return true; - } + 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; switch (sBinding) { case 'R0': @@ -5810,7 +5804,7 @@ class PanelPDP11 extends Component { * * Only *type* and *binding* attributes are required; if *value* is omitted, the default value is 0 ("off"). */ - if (sType == "led" || sType == "rled") { + if (sHTMLType == "led" || sHTMLType == "rled") { this.bindings[sBinding] = control; this.leds[sBinding] = sValue? 1 : 0; this.cLiveRegs++; @@ -5826,7 +5820,7 @@ class PanelPDP11 extends Component { * Currently, there is no XML attribute to indicate whether a switch is "momentary"; only recognized switches * in our internal table can have that attribute. */ - if (sType == "switch") { + if (sHTMLType == "switch") { /* * Like LEDs, we allow unrecognized switches to be defined as well, but they won't do anything useful, * since only recognized switches will have handlers that perform the appropriate operations. @@ -5860,7 +5854,7 @@ class PanelPDP11 extends Component { }(this, sBinding); return true; } - return super.setBinding(sType, sBinding, control, sValue); + return super.setBinding(sHTMLType, sBinding, control, sValue); } } @@ -10563,7 +10557,7 @@ class CPUPDP11 extends Component { this.panel = cmp.panel; 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); + if (control) this.cmp.setBinding("", CPUPDP11.BUTTONS[i], control); } this.setReady(); } @@ -10813,16 +10807,16 @@ class CPUPDP11 extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {CPUPDP11} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "run") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { var cpu = this; @@ -17976,16 +17970,16 @@ class KeyboardPDP11 extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {KeyboardPDP11} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "esc") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { return false; } @@ -18187,18 +18181,18 @@ class SerialPortPDP11 extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {SerialPortPDP11} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "buffer") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { - if (sType == null || sType == "textarea") { + if (!sHTMLType || sHTMLType == "textarea") { var serial = this; this.bindings[sBinding] = this.controlBuffer = control; @@ -19013,16 +19007,16 @@ class PC11 extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {PC11} - * @param {string|null} sType is the type of the HTML control (eg, "button", "list", "text", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "list", "text", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "listTapes") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { var pc11 = this; var nTapeTarget = PC11.TARGET.NONE; @@ -21239,16 +21233,16 @@ class DriveController extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {DriveController} - * @param {string|null} sType is the type of the HTML control (eg, "button", "list", "text", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "list", "text", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "listDisks") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { var dc = this; @@ -25145,7 +25139,7 @@ class Debugger extends Component * * @this {Debugger} * @param {string|undefined} sValue - * @param {string|null} [sName] is the name of the value, if any + * @param {string|null|*} [sName] is the name of the value, if any * @param {Array|undefined|boolean} [fQuiet] * @param {number} [nUnary] (0 for none, 1 for negate, 2 for complement, 3 for leading zeros) * @return {number|undefined} numeric value, or undefined if sValue is either undefined or invalid @@ -25733,16 +25727,16 @@ class DebuggerPDP11 extends Debugger { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {DebuggerPDP11} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "debugInput") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { var dbg = this; switch (sBinding) { @@ -30810,16 +30804,16 @@ class ComputerPDP11 extends Component { } /** - * setBinding(sType, sBinding, control, sValue) + * setBinding(sHTMLType, sBinding, control, sValue) * * @this {ComputerPDP11} - * @param {string|null} sType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) + * @param {string} sHTMLType is the type of the HTML control (eg, "button", "textarea", "register", "flag", "rled", etc) * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's "data-value" attribute (eg, "reset") * @param {HTMLElement} 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 */ - setBinding(sType, sBinding, control, sValue) + setBinding(sHTMLType, sBinding, control, sValue) { var computer = this; diff --git a/versions/pdpjs/1.61.0/pdp11.js b/versions/pdpjs/1.61.0/pdp11.js index 4712b55805..917d852ef9 100644 --- a/versions/pdpjs/1.61.0/pdp11.js +++ b/versions/pdpjs/1.61.0/pdp11.js @@ -45,7 +45,7 @@ $:36,"%":37,"\x26":38,"'":39,"(":40,")":41,"*":42,"+":43,",":44,"-":45,".":46,"/ Gk:115,t:116,Kk:117,Lk:118,Mk:119,x:120,y:121,z:122,"{":123,"|":124,"}":125,"~":126,ac:127}; function ua(a,b){if(a){b||(b=10);var c,d=0<a.indexOf(",");d&&(a=a.replace(/,/g,""));var e=c=a.charAt(0);"#"==c?(b=8,c=""):"$"==c&&(b=16,c="");e!=c?a=a.substr(1):(e=c=a.substr(0,2),"0b"==c&&d||"^B"==c?(b=2,c=""):"0o"==c||"^O"==c?(b=8,c=""):"^D"==c?(b=10,c=""):"0x"==c&&(b=16,c=""),e!=c&&(a=a.substr(2)));e=c=a.slice(-1);"Y"==c||"y"==c?(b=2,c=""):"."==c?(b=10,c=""):"H"==c||"h"==c?(b=16,c=""):"K"==c?c="000":"M"==c?c="000000":"G"==c&&(c="000000000");e!=c&&(a=a.slice(0,-1)+c);var f;e=0;10>=b&&(c=a.match(/(-?[0-9]+)B([0-9]*)/))&& (a=c[1],e=35-((c[2]||35)&255));c=a;if(((d=b)&&10!=d?16==d?null!==c.match(/^-?[0-9a-f]+$/i):8==d?null!==c.match(/^-?[0-7]+$/):2==d&&null!==c.match(/^-?[01]+$/):null!==c.match(/^-?[0-9]+$/))&&!isNaN(f=parseInt(a,b))){e&&(0>f&&(f+=Math.pow(2,36)),f=0<e?f*Math.pow(2,e):Math.trunc(f/Math.pow(2,-e)));var g=f}}return g} -function va(a,b,c,d,e){e=void 0===e?0:e;var f="";isNaN(a)?a=null:null!=a&&(0>a&&-1<a&&(a=-1),0>a&&(a+=Math.pow(b,c)),a>=Math.pow(b,c)&&(c=Math.ceil(Math.log(a)/Math.log(b))));for(var g=e||-1;0<c--;){g||(f=","+f,g=e);if(null==a)f="?"+f;else{var k=a%b;k+=0<=k&&9>=k?48:55;f=String.fromCharCode(k)+f;a=Math.trunc(a/b)}g--}return(void 0===d?"":d)+f}function wa(a,b,c){b?36<b&&(b=36):(b=Math.abs(a),b=255>=b?8:262143>=b?18:36);return va(a,2,b,"",c)} +function va(a,b,c,d,e){e=void 0===e?0:e;var f="";isNaN(a)||"number"!=typeof a?a=null:(0>a&&-1<a&&(a=-1),0>a&&(a+=Math.pow(b,c)),a>=Math.pow(b,c)&&(c=Math.ceil(Math.log(a)/Math.log(b))));for(var g=e||-1;0<c--;){g||(f=","+f,g=e);if(null==a)f="?"+f;else{var k=a%b;k+=0<=k&&9>=k?48:55;f=String.fromCharCode(k)+f;a=Math.trunc(a/b)}g--}return(void 0===d?"":d)+f}function wa(a,b,c){b?36<b&&(b=36):(b=Math.abs(a),b=255>=b?8:262143>=b?18:36);return va(a,2,b,"",c)} function u(a,b,c){b?12<b&&(b=12):(b=Math.abs(a),b=262143>=b?6:16777215>=b?8:12);return va(a,8,b,c?"0o":"")}function xa(a,b){b?11<b&&(b=11):b=99999>=Math.abs(a)?5:11;return va(a,10,b)}function v(a,b,c){b?9<b&&(b=9):(b=Math.abs(a),b=65535>=b?4:4294967295>=b?8:9);return va(a,16,b,c?"0x":"")}function ya(a){return v(a,4,!0)}function za(a,b){var c=a,d=a.lastIndexOf("/");0<=d&&(c=a.substr(d+1));d=c.indexOf("\x26");0<d&&(c=c.substr(0,d));b&&(d=c.lastIndexOf("."),0<d&&(c=c.substring(0,d)));return c} function Aa(a){var b="",c=a.lastIndexOf(".");0<=c&&(b=a.substr(c+1).toLowerCase());return b}function Ba(a,b){return-1!==a.indexOf(b,a.length-b.length)}function Ca(a){return a.replace(/[&<>"']/g,function(a){return Da[a]})}function Fa(a,b){return(a+" ").slice(0,b)}function Ga(a){return String.prototype.trim?a.trim():a.replace(/^\s+|\s+$/g,"")} var Da={"\x26":"\x26amp;","\x3c":"\x26lt;","\x3e":"\x26gt;",'"':"\x26quot;","'":"\x26#039;"},Ha={0:"NUL",1:"SOH",2:"STX",3:"ETX",4:"EOT",5:"ENQ",6:"ACK",7:"BEL",8:"BS",9:"TAB",10:"LF",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",127:"DEL"}; @@ -135,7 +135,7 @@ h.Zg=function(a,b){Ub&&a&1&&this.C.Ma(b,64,2);a=!Vb&&a&1?this.g[a]|this.g[a+1]<< h.oi=function(a,b,c){Ub&&a&1&&this.C.Ma(c,64,4);!Vb&&a&1?(this.g[a]=b,this.g[a+1]=b>>8):this.F[a>>1]=b;this.bb=!0;this.f&&E(this.f,32)&&F(this.f,"Memory.writeWord("+K(this.f,c)+","+K(this.f,b)+")",!0)};var $d=0,sd=1,ae=2,hd=4,md=["NONE","RAM","ROM","VID","H/W"],Zd=0,ge=[],fe=[J.prototype.Wf,J.prototype.ph,J.prototype.$g,J.prototype.pi],je=[J.prototype.Uf,J.prototype.nh,J.prototype.Wg,J.prototype.ni]; if(Qb)var ee=[J.prototype.Tf,J.prototype.mh,J.prototype.Vg,J.prototype.mi],de=[J.prototype.Vf,J.prototype.oh,J.prototype.Zg,J.prototype.oi];var me;if(Qb){var ne=new ArrayBuffer(2);(new DataView(ne)).setUint16(0,256,!0);me=256===(new Uint16Array(ne))[0]}else me=!1;var ce=me; function oe(a,b){x.call(this,"CPU",a,1);b=+a.cycles||b;var c=+a.multiplier||1;this.Xc=0;this.Vc=b;this.jb=c;this.hd=Math.round(this.Vc/1E4)/100;this.ub=this.hd*this.jb;this.jd=this.pc=this.xb=this.uc=0;this.flags.U=this.flags.Oc=!1;this.flags.pa=a.autoStart;"string"==typeof this.flags.pa&&(this.flags.pa="true"==this.flags.pa);this.flags.Kb=!1;this.mc=this.Lb=0;this.nc=+a.csStart;this.Jb=+a.csInterval;this.Nb=+a.csStop;this.fa=[];this.Wd=this.fh.bind(this);this.kb=this.Ia=this.ib=this.b=this.ka=this.Ha= -this.lc=this.hb=this.Ob=this.kd=this.tb=0;this.ra=null;D(this)}q(oe,x);h=oe.prototype;h.za=function(a,b,c,d){this.I=a;this.C=b;this.D=d;this.ra=a.i;for(a=0;a<pe.length;a++)(b=this.G[pe[a]])&&this.I.ua(null,pe[a],b);D(this)};h.reset=function(){};h.save=function(){return null};h.restore=function(){return!1}; +this.lc=this.hb=this.Ob=this.kd=this.tb=0;this.ra=null;D(this)}q(oe,x);h=oe.prototype;h.za=function(a,b,c,d){this.I=a;this.C=b;this.D=d;this.ra=a.i;for(a=0;a<pe.length;a++)(b=this.G[pe[a]])&&this.I.ua("",pe[a],b);D(this)};h.reset=function(){};h.save=function(){return null};h.restore=function(){return!1}; h.Ba=function(a,b){var c=qe(this.I,"autoStart");null!=c?this.flags.pa="true"==c?!0:"false"==c?!1:!!c:null==this.flags.pa&&(this.flags.pa=!this.D&&void 0===this.G.run);if(!b){if(a){re(this);if(!this.restore(a))return!1;se(this)}else this.reset();this.D?(a=this.D,b=this.flags.pa,a.Fa=!0,a.v("Type ? for help with PDPjs Debugger commands"),te(a),b||ue(a),a.wa&&(b=a.wa,a.wa=null,ve(a,b))):this.status("No debugger detected");this.flags.pa||this.v("CPU will not be auto-started "+(this.ra?"(click Run to start)": "(type 'go' to start)"))}return!0};h.Aa=function(a){return a?this.save():!0};h.pa=function(){return this.flags.U?!0:this.flags.pa?Cc(this):!1};h.ne=function(){return 0};function se(a){void 0===a.nc&&(a.nc=0);void 0===a.Jb&&(a.Jb=-1);void 0===a.Nb&&(a.Nb=-1);a.flags.Kb=0<=a.nc&&0<a.Jb;a.flags.Kb&&(a.mc=0,a.Lb=a.nc-a.kb)} function Gc(a,b){if(a.flags.Kb){var c=!1;a.mc=a.mc+a.ne()|0;a.Lb-=b;0>=a.Lb&&(a.Lb+=a.Jb,c=!0);0<=a.Nb&&a.Nb<=we(a)&&(a.Jb=a.Nb=-1,se(a),I(a),c=!0);c&&a.v(we(a)+" cycles: checksum\x3d"+v(a.mc))}} @@ -212,10 +212,10 @@ Jh.prototype.reset=function(){if(this.u&&!this.A){var a=this.C,b=this.i,c=this.j function Lh(a,b,c,d,e,f){var g=!1,k=!1;if(null==c)for(var l=0;l<b.length-1;){var m=b[l]&255|(b[l+1]&255)<<8;if(m)if(m&255){var n=l;if(1!=m){F(a,"invalid signature ("+ya(m)+") at offset "+ya(n),4096);break}if(l+6>=b.length){F(a,"invalid block at offset "+ya(n),4096);break}l+=2;var r=b[l++]&255|(b[l++]&255)<<8,t=b[l++]&255|(b[l++]&255)<<8;m+=(r&255)+(r>>8)+(t&255)+(t>>8);for(var p=l,z=r-=6;0<r&&l<b.length;)m+=b[l++]&255,r--;if(0!=r||l>=b.length){F(a,"insufficient data for block at offset "+ya(n),4096); break}m+=b[l++]&255;if(m&255){F(a,"invalid checksum ("+v(m,2,!0)+") for block at offset "+ya(n),4096);break}if(z)for(F(a,"loading "+ya(z)+" bytes at "+ya(t)+"-"+ya(t+z),4096);z--;)pd(a.C,t++,b[p++]&255);else t&1?g=!0:null==d&&(d=t),null!=d&&F(a,"starting address: "+ya(d),4096);k=!0}else l++;else l+=2}if(!k&&(null==c&&(c=e),null!=c)){for(e=0;e<b.length;e++)pd(a.C,c+e,b[e]);k=!0}if(k){if(null==d||g)I(a.f),f=!1;null!=d&&Je(a.f,d,f)}return k} eb(function(){for(var a=A(document,y,"ram"),b=0;b<a.length;b++){var c=a[b],d=wb(c);d=new Jh(d);vb(d,c)}});function Mh(a){x.call(this,"Keyboard",a,1024);D(this)}q(Mh,x);Mh.prototype.ua=function(){return!1};Mh.prototype.za=function(a,b,c,d){this.I=a;this.f=c;this.D=d};eb(function(){for(var a=A(document,y,"keyboard"),b=0;b<a.length;b++){var c=a[b],d=wb(c);d=new Mh(d);vb(d,c)}}); -function Nh(a){x.call(this,"SerialPort",a,1048576);this.L=+a.adapter;this.R=+a.baudReceive||9600;this.Y=+a.baudTransmit||9600;this.K=a.upperCase;"string"==typeof this.K&&(this.K="true"==this.K);this.u=this.w=null;this.V=+a.tabSize;this.T=+a.charBOL;this.A=0;this.H=!0;this.O=this.M=null;this.P=this.X=-1;this.B=this.b=this.g=0;this.j=[];a=a.binding;if("console"==a)this.w="";else if(a){var b=Eb("Panel",this.id);b&&(b=b.G[a])&&this.ua(null,a,b)}this.i=this.F=this.N=null;this.exports={connect:this.re, -receiveData:this.Kc,receiveStatus:this.dh,setConnection:this.ih}}q(Nh,x);h=Nh.prototype; -h.ua=function(a,b,c){if(null==a||"textarea"==a){var d=this;this.G[b]=this.u=c;c.onkeydown=function(a){a=a||window.event;var b=0,c=a.keyCode;8==c?b=a.altKey?ta.Ld:ta.ac:46==c?b=ta.Ld:a.ctrlKey&&c>=ta.Hd&&c<=ta.vf&&(b=c-(ta.Hd-ta.Ce));b&&(a.preventDefault&&a.preventDefault(),d.Kc(b));return!0};c.onkeypress=function(a){a=a||window.event;if(!a.metaKey){var b=a.which||a.keyCode;a.altKey&&b==ta.Ee&&(b=ta.De);d.Kc(b);a.preventDefault&&a.preventDefault()}return!0};c.onpaste=function(a){a.stopPropagation&& -a.stopPropagation();a.preventDefault&&a.preventDefault();(a=a.clipboardData||window.clipboardData)&&d.Kc(a.getData("Text"))};c.removeAttribute("readonly");return!0}return!1}; +function Nh(a){x.call(this,"SerialPort",a,1048576);this.L=+a.adapter;this.R=+a.baudReceive||9600;this.Y=+a.baudTransmit||9600;this.K=a.upperCase;"string"==typeof this.K&&(this.K="true"==this.K);this.u=this.w=null;this.V=+a.tabSize;this.T=+a.charBOL;this.A=0;this.H=!0;this.O=this.M=null;this.P=this.X=-1;this.B=this.b=this.g=0;this.j=[];a=a.binding;if("console"==a)this.w="";else if(a){var b=Eb("Panel",this.id);b&&(b=b.G[a])&&this.ua("",a,b)}this.i=this.F=this.N=null;this.exports={connect:this.re,receiveData:this.Kc, +receiveStatus:this.dh,setConnection:this.ih}}q(Nh,x);h=Nh.prototype; +h.ua=function(a,b,c){if(!a||"textarea"==a){var d=this;this.G[b]=this.u=c;c.onkeydown=function(a){a=a||window.event;var b=0,c=a.keyCode;8==c?b=a.altKey?ta.Ld:ta.ac:46==c?b=ta.Ld:a.ctrlKey&&c>=ta.Hd&&c<=ta.vf&&(b=c-(ta.Hd-ta.Ce));b&&(a.preventDefault&&a.preventDefault(),d.Kc(b));return!0};c.onkeypress=function(a){a=a||window.event;if(!a.metaKey){var b=a.which||a.keyCode;a.altKey&&b==ta.Ee&&(b=ta.De);d.Kc(b);a.preventDefault&&a.preventDefault()}return!0};c.onpaste=function(a){a.stopPropagation&&a.stopPropagation(); +a.preventDefault&&a.preventDefault();(a=a.clipboardData||window.clipboardData)&&d.Kc(a.getData("Text"))};c.removeAttribute("readonly");return!0}return!1}; h.za=function(a,b,c,d){this.I=a;this.C=b;this.f=c;this.D=d;var e=this;this.O=zd(this.f,this.L?-1:48,4,1048576);this.P=wd(this.f,function(){var a=-1;e.j.length&&(a=e.j.shift()&255,F(e,"receiveByte("+v(a,2,!0)+")"),e.K&&97<=a&&122>a&&(a-=32),yd(e.f,e.P,1E3/Math.round(e.R/10)));0<=a&&(e.B=a,e.b&128?e.B|=49152:e.b|=128,e.b&64&&xd(c,e.O))});this.M=zd(this.f,this.L?-1:52,4,1048576);this.X=wd(this.f,function(){e.g|=128;e.g&64&&xd(c,e.M)});nc(b,this,Oh,this.L?64832+8*(this.L-1)-65392:0);pc(b,this.reset.bind(this)); D(this)};h.re=function(a){if(!this.i){var b=qe(this.I,"connection");if(b){var c=b.split("-\x3e");if(2==c.length){var d=Ga(c[0]);if(d!=this.Uc)return;c=Ga(c[1]);if(this.i=yb(c)){var e=this.i.exports;if(e){var f=e.connect;f&&f.call(this.i,this.H);if(this.F=e.receiveData){this.H=a;this.N=e.receiveStatus;this.status("Connected "+this.sb+"."+d+" to "+c);return}}}}this.status("Unable to establish connection: "+b)}}}; h.Ba=function(a,b){if(!b)if(this.re(this.H),!a)this.reset();else if(!this.restore(a))return!1;return!0};h.Aa=function(a){return a?this.save():!0};h.reset=function(){Ph(this)};h.save=function(){var a=new H(this);a.set(0,[this.B,this.b,this.g,this.j]);return a.data()};h.restore=function(a){return Ph(this,a[0])};function Ph(a,b){b||(b=[0,8192,128,a.j]);b=ja(b);a.B=b.next().value;a.b=b.next().value;a.g=b.next().value;a.j=b.next().value;return!0} diff --git a/versions/pdpjs/1.61.0/pdp11.js.map b/versions/pdpjs/1.61.0/pdp11.js.map index 42c961adcc..bbd1516af8 100644 --- a/versions/pdpjs/1.61.0/pdp11.js.map +++ b/versions/pdpjs/1.61.0/pdp11.js.map @@ -1 +1 @@ -{"version":3,"file":"pdp11.js","lineCount":410,"mappings":"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","sources":["versions/pdpjs/1.61.0/pdp11-uncompiled.js"," [synthetic:util/defineproperty] "," [synthetic:util/global] "," [synthetic:es6/symbol] "," [synthetic:es6/util/makeiterator] "," [synthetic:util/objectcreate] "," [synthetic:es6/util/setprototypeof] "," [synthetic:es6/util/inherits] "," [synthetic:util/polyfill] "," [synthetic:es6/math/trunc] "," [synthetic:es6/number/parseint] "," [synthetic:es6/math/log2] "," [synthetic:es6/array/fill] "],"names":["$jscomp.defineProperty","$jscomp.global","$jscomp.initSymbol","$jscomp.Symbol","$jscomp.SYMBOL_PREFIX","$jscomp.arrayIterator","$jscomp.initSymbolIterator","$jscomp.iteratorPrototype","$jscomp.objectCreate","$jscomp.setPrototypeOf","$jscomp.polyfill","DiskAPI.GEOMETRIES","ASCII","BREAK","CTRL_A","CTRL_B","CTRL_C","CTRL_D","CTRL_E","CTRL_F","CTRL_G","CTRL_H","CTRL_I","CTRL_J","CTRL_K","CTRL_L","CTRL_M","CTRL_N","CTRL_O","CTRL_P","CTRL_Q","CTRL_R","CTRL_S","CTRL_T","CTRL_U","CTRL_V","CTRL_W","CTRL_X","CTRL_Y","CTRL_Z","ESC","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","DEL","parseInt","base","chPrefix","fCommas","indexOf","replace","ch","charAt","substr","chSuffix","slice","shift","match","isNaN","Math","pow","trunc","value","toBase","radix","cch","sPrefix","nGrouping","ceil","log","String","fromCharCode","toBin","abs","Str.toBase","toOct","fPrefix","toDec","toHex","toHexWord","Str.toHex","getBaseName","sFileName","fStripExt","sBaseName","lastIndexOf","substring","getExtension","sExtension","toLowerCase","endsWith","sSuffix","length","escapeHTML","sHTML","Str.HTMLEscapeMap","pad","sPadding","trim","prototype","Str.ASCIICodeMap","binarySearch","fnCompare","left","right","found","undefined","middle","compareResult","formatDate","date","sDate","Date","iHour","getHours","iDay","getDate","iMonth","getMonth","sFormat","Usr.asDays","getDay","Usr.asMonths","getMinutes","getSeconds","getFullYear","getResource","sURL","type","fAsync","done","callback","request","readyState","resource","fArrayBuffer","response","responseText","err","status","window","location","protocol","nErrorCode","resources","XMLHttpRequest","ActiveXObject","fXHR2","responseType","onreadystatechange","sPost","hasOwnProperty","encodeURIComponent","open","setRequestHeader","send","overrideMimeType","parseMemoryResource","sData","aBytes","aSymbols","addrLoad","addrExec","ib","Error","data","JSON","parse","eval","Array","aData","Component.alertUser","message","ab","asHexData","sHexData","split","push","getHost","host","SITEHOST","hasLocalStorage","Web.fLocalStorage","localStorage","setItem","Web.sLocalStorageTest","getItem","removeItem","getLocalStorageItem","sKey","sValue","setLocalStorageItem","isUserAgent","userAgent","navigator","isMobile","sDevice","sMobile","Web.getURLParm","Web.isUserAgent","fInvert","getURLParm","sParm","Web.parmsURL","sParms","aParms","search","pl","exec","decodeURIComponent","onCountRepeat","fnRepeat","fnComplete","fnTimeout","doCountRepeat","setTimeout","onClickRepeat","fn","doClickRepeat","msRepeat","ms","timer","fIgnoreMouseEvents","onmousedown","e.onmousedown","msDelay","ontouchstart","e.ontouchstart","onmouseup","onmouseout","e.onmouseout","clearTimeout","ontouchend","ontouchcancel","e.ontouchcancel","onPageEvent","sFunc","fnPrev","onInit","Web.aPageEventHandlers","doPageEvent","afn","Web.fPageEventsEnabled","enablePageEvents","fEnable","Web.fPageLoaded","Web.sendPageEvent","Web.fPageShowed","sendPageEvent","sEvent","Web.doPageEvent","Web.onPageEvent","onPageLoad","onPageShow","onPageUnload","constructor","Component","parms","bitsMessage","id","name","comment","bindings","idComponent","idMachine","flags","ready","busy","busyCancel","initDone","powered","unloading","error","fnReady","clearError","dbg","cpu","bus","cmp","Component.components.push","component","addMachineResource","sName","Component.machines","getTime","now","alertUser","sMessage","alert","confirmUser","sPrompt","fResponse","confirm","appendControl","control","sText","scrollTop","scrollHeight","bindComponentControls","element","sAppClass","PDP11.APPCLASS","aeControls","Component.getElementsByClass","parentNode","iControl","aeChildNodes","childNodes","iNode","nodeType","sClass","getAttribute","aClasses","iClass","Component.getComponentParms","setBinding","getComponents","idRelated","aComponents","Component.components.length","Component.components","getComponentByID","getComponentByType","sType","componentPrev","getComponentParms","getElementsByClass","sObjClass","getElementsByClassName","ae","aeAll","getElementsByTagName","re","RegExp","test","className","processCommands","fSuccess","aCommands","Component.commands","aTokens","splice","sCommand","fnCallReady","Component.asyncCommands.indexOf","processNextCommand","Component.processCommands","fnCommand","Component.globalCommands","Component.getComponentByType","Component.componentCommands","exports","call","Component.prototype","?.prototype","toString","sHTMLType","sBinding","onclick","clearControl","notice","this.notice","println","print","printControl","Component.appendControl","printlnControl","Component.PRINT.PROGRESS","fPrintOnly","computer","console","setError","isError","isReady","setReady","fReady","isBusy","fCancel","setBusy","fBusy","powerUp","powerDown","fSave","fShutdown","messageEnabled","bitsEnabled","printMessage","fAddress","PROGRESS","Component.asyncCommands","scriptAlert","scriptSleep","fnCallback","sDelay","scriptSelect","aBindings","options","textContent","selectedIndex","Array.prototype.indexOf","obj","start","isArray","Array.isArray","arg","Object","Function","bind","Function.prototype.bind","fnBound","fToBind","apply","fnNOP","args","concat","arguments","TypeError","TYPEDARRAYS","ArrayBuffer","APPCLASS","APPNAME","BYTEARRAYS","MEMFAULT","WORDBUS","REASONS","RK11","PRI","VEC","DRIVES","RKDS","SC","SCESA","WPS","RRDY","DRDY","SOK","SIN","DRU","RK05","DPL","ID","SHIFT","RKER","WCE","CSE","SE","UNUSED","NXS","NXC","NXD","TE","DLT","NXM","PGE","SKE","WLO","OVR","DRE","HE","RKCS","GO","FUNC","MEX","IE","CRDY","SSE","EXB","FMT","IBA","SCP","ERR","RMASK","WMASK","RKDA","SA","HS","CA","DS","CRESET","WRITE","READ","WCHK","SEEK","RCHK","DRESET","WLOCK","RL11","PREFIX","RLCS","BAE","ERRC","DE","CLEAR","SET","RLBA","RLDA","SEEK_CMD","SEEK_DIR","SEEK_HS","SEEK_CAD","RW_SA","RW_HS","RW_CA","GS_CMD","GS_RST","RLMP","GS_ST","LOADC","SPINUP","BRUSHC","LOADH","LOCKON","UNLOADH","SPINDN","GS_BH","GS_HO","GS_CO","GS_HS","GS_DT","GS_DSE","GS_VC","GS_WGE","GS_SPE","GS_SKTO","GS_WL","GS_CHE","GS_WDE","RLBE","MASK","OPI","DCRC","HCRC","HNF","MPE","NOP","STATUS","RHDR","WDATA","RDATA","RDNC","RX11","RXCS","UNIT","DONE","TR","INIT","RXDB","RXTA","RXSA","RXES","CRC","PARITY","FILL","EMPTY","RDSTAT","WRDEL","RDERR","ERROR","HOME0","HOME1","BAD_HOME","NO_TRACK","FOUND_HOME","SELF_DIAG","NO_SECTOR","NO_SEP","NO_PREAM","NO_IOMARK","CRC_HEADER","BAD_TRACK","NO_ID","NO_DATA","CRC_DATA","BAD_PARITY","VECTORS","PDP11.RX11.RX01","RX01","PDP11.RK11.RK05","PDP11.RK11.RKDS.RK05","PDP11.RK11.RKDS.SOK","PDP11.RK11.RKDS.RRDY","PDP11.RL11.RL02K","RL02K","PDP11.RL11.RLMP.GS_ST.LOCKON","PDP11.RL11.RLMP.GS_BH","PDP11.RL11.RLMP.GS_HO","PDP11.APPNAME","PDP11.BYTEARRAYS","PDP11.TYPEDARRAYS","PDP11.WORDBUS","PDP11.MEMFAULT","MessagesPDP11.CATEGORIES","CPU","TRAP","FAULT","INT","BUS","MEMORY","MMU","ROM","DEVICE","PANEL","KEYBOARD","KEYS","PC11","PAPER","DISK","DL11","SERIAL","KW11","TIMER","SPEAKER","COMPUTER","BUFFER","WARN","HALT","PanelPDP11","parmsPanel","fBindings","nDisplayCount","cLiveRegs","regAddr","regData","regSwitches","regDisplay","ledAddr","ledData","fAutoInc","fLEDTest","nAddrSel","PanelPDP11.ADDRSEL.CONS_PHY","leds","switches","processStart","processStep","processEnable","processContinue","processDeposit","processExamine","processLoadAddr","processLEDTest","processSRSwitch","holdSwitch","toggleSwitch","resetSwitches","setSwitch","$jscomp.inherits","setDR","updateData","PanelPDP11.prototype","reset","fPowerUp","stop","parent","parentElement","panel","onPressSwitch","pressSwitch","onReleaseSwitch","releaseSwitch","event","preventDefault","initBus","addIOTable","PanelPDP11.UNIBUS_IOTABLE","addResetHandler","displayLEDs","displaySwitches","fRepower","PanelPDP11.init","restore","save","state","State","set","getAR","getDR","getSR","updateAddr","setAR","setSRSwitches","setSR","sw","displayLED","style","backgroundColor","override","displaySwitch","marginTop","displayValue","sLabel","nValue","nBase","sVal","Str.toOct","Str.parseInt","PanelPDP11.SWITCH.LOAD","running","setPC","initMMU","getSwitch","PanelPDP11.SWITCH.ENABLE","startCPU","stopCPU","stepCPU","nCyclesStep","updateTimers","addCycles","updateChecksum","exception","stack","updateDisplays","advanceAddr","setWordDirect","nDisableTraps","setWord","mapVirtualToPhysical","addr","PDP11.ACCESS.WRITE_WORD","getWordDirect","getWordSafe","index","nRegs","MODEL_1140","model","fGenRegs","UNIBUS","inc","mask","nBusMask","PanelPDP11.SWITCH.STEP","nLEDs","updateLED","updateLEDArray","regsGen","setAddr","setData","fActive","readCNSW","fPreWrite","writeCNSW","init","aePanels","document","iPanel","ePanel","Component.getComponentByID","Component.bindComponentControls","CONS_PHY","ENABLE","LOAD","STEP","Web.onInit","BusPDP11","parmsBus","nBusWidth","addrTotal","nBlockSize","BusPDP11.IOPAGE_LENGTH","nBlockShift","log2","nBlockLen","nBlockLimit","nBlockTotal","nBlockMask","aIOHandlers","nDisableFaults","fFault","afnReset","afnIOPage","BusPDP11.IOController.readByte","BusPDP11.IOController.writeByte","BusPDP11.IOController.readWord","BusPDP11.IOController.writeWord","aBusBlocks","aMemBlocks","addrIOPage","nIOPageRange","nMemMask","iBlockIOPageBus","iBlockIOPageMem","block","MemoryPDP11","initMemory","copyBreakpoints","iBlock","addMemory","MemoryPDP11.TYPE.CONTROLLER","setIOPageRange","nRange","BusPDP11.prototype","saveMemory","adw","restoreMemory","iDst","aDst","iComp","aComp","size","controller","addrNext","sizeLeft","addrBlock","sizeBlock","used","sizeAvail","reportError","BusPDP11.ERROR.RANGE_INUSE","blockNew","MemoryPDP11.TYPE_NAMES","BusPDP11.ERROR.RANGE_INVALID","BusPDP11_prototype$getByte","getByte","readByte","BusPDP11_prototype$getWord","getWord","off","readWord","BusPDP11_prototype$setByte","setByte","writeByte","BusPDP11_prototype$setWord","writeWord","getBlockDirect","readWordDirect","readByteDirect","setByteDirect","writeByteDirect","writeWordDirect","removeMemBreak","fWrite","removeBreakpoint","cWriteBreakpoints","resetWriteAccess","fReadOnly","writeNone","writeWordDefault","cReadBreakpoints","resetReadAccess","fDirty","fDirtyEver","iSrc","aSrc","iCompare","getMemoryLimit","MemoryPDP11.TYPE.RAM","addIOHandlers","end","fnReadByte","fnWriteByte","fnReadWord","fnWriteWord","BusPDP11.IOPAGE_MASK","table","offReg","reg","readByteIORegister","writeByteIORegister","sReg","iReg","fnReset","fault","access","toStrBase","regErr","trap","checkFault","errNum","RANGE_INUSE","RANGE_INVALID","addrMasked","READ_BYTE","READ_WORD","MSG_CATEGORY","REG_NAME","CPUERR","PDP11.ACCESS.READ_BYTE","WRITE_BYTE","WRITE_WORD","PDP11.ACCESS.WRITE_BYTE","PDP11.ACCESS.READ_WORD","DevicePDP11","parmsDevice","kw11","lks","DevicePDP11.prototype","device","addTimer","setIRQ","irq","setTimer","addIRQ","DevicePDP11.UNIBUS_IOTABLE","messageDump","onDumpMMU","asArgs","dumpRegs","regsPDR","regsPAR","regMMR3","MMR3","regsUniMap","aRegs","offset","sFilter","fBreak","toUpperCase","nBits","sDump","fIndex","nWidth","Str.toDec","$jscomp.makeIterator","readLKS","writeLKS","clearIRQ","readMMR0","getMMR0","writeMMR0","setMMR0","regMMR0","MMR0","readMMR1","getMMR1","readMMR2","getMMR2","readMMR3","writeMMR3","setMMR3","readUNIMAP","word","writeUNIMAP","readSIPDR","writeSIPDR","readSDPDR","writeSDPDR","readSIPAR","writeSIPAR","readSDPAR","writeSDPAR","readKIPDR","writeKIPDR","readKDPDR","writeKDPDR","readKIPAR","writeKIPAR","readKDPAR","writeKDPAR","readUIPDR","writeUIPDR","readUDPDR","writeUDPDR","readUIPAR","writeUIPAR","readUDPAR","writeUDPAR","readRSET0","regPSW","PSW","regsAlt","writeRSET0","readR6KERNEL","regsAltStack","writeR6KERNEL","readR7KERNEL","writeR7KERNEL","readRSET1","writeRSET1","readR6SUPER","MODE","writeR6SUPER","readR6USER","writeR6USER","readCTRL","regsControl","writeCTRL","readSIZE","writeSIZE","readSYSID","writeSYSID","readCPUERR","writeCPUERR","readMBR","regMBR","writeMBR","readPIR","regPIR","writePIR","setPIR","readSLR","regSLR","writeSLR","readPSW","getPSW","writePSW","setPSW","writeIgnored","MODEL_1170","MODEL_1145","aeDevice","iDevice","eDevice","MemoryPDP11.idBlock","MemoryPDP11.TYPE.NONE","MemoryPDP11.TYPE.ROM","readNone","readWordDefault","setAccess","buffer","dv","DataView","Uint8Array","aw","Uint16Array","Int32Array","littleEndian","MemoryPDP11.afnArrayLE","MemoryPDP11.afnArrayBE","MemoryPDP11.afnMemory","MemoryPDP11.prototype","getInt32","setInt32","MemoryPDP11.afnNone","setReadAccess","fDirect","setWriteAccess","addBreakpoint","MemoryPDP11.afnChecked","mem","ACCESS","readByteMemory","readWordMemory","idw","nShift","dw","writeByteMemory","writeWordMemory","readByteChecked","checkMemoryRead","readWordChecked","writeByteChecked","checkMemoryWrite","writeWordChecked","readByteBE","readByteLE","readWordBE","getUint16","readWordLE","writeByteBE","writeByteLE","writeWordBE","setUint16","writeWordLE","NONE","RAM","CONTROLLER","CPUPDP11","parmsCPU","nCyclesDefault","nCycles","nMultiplier","nCyclesPerSecond","nCyclesMultiplier","mhzDefault","round","mhzTarget","msPerYield","nCyclesPerYield","nCyclesNextYield","nCyclesRecalc","starting","autoStart","checksum","nChecksum","nCyclesChecksumNext","nCyclesChecksumStart","nCyclesChecksumInterval","nCyclesChecksumStop","aTimers","onRunTimeout","runCPU","nTotalCycles","nRunCycles","nBurstCycles","nStepCycles","nSnapCycles","msStartRun","msStartThisRun","msEndThisRun","nCyclesThisRun","nYieldsSinceStatusUpdate","mhz","CPUPDP11.prototype","CPUPDP11.BUTTONS.length","CPUPDP11.BUTTONS","sAutoStart","getMachineParm","resetCycles","resetChecksum","fInit","updateStatus","fAutoStart","setFocus","sInitCommands","sCmds","doCommands","getChecksum","fDisplay","getCycles","displayChecksum","control.onclick","iComponent","Component.getComponents","setSpeed","getSpeedTarget","toFixed","fEndStep","calcCycles","fRecalc","vMultiplier","CPUPDP11.YIELDS_PER_SECOND","floor","fUpdateFocus","sSpeed","controlSpeed","Component.getTime","callBack","iTimer","fReset","getMSCycles","endBurst","getBurstCycles","saveTimers","aTimerCycles","calcStartTime","msDelta","CPUPDP11.YIELDS_PER_STATUS","nUpdate","calcRemainingTime","msYield","msRemainsThisRun","msElapsed","controlRun","CPUPDP11_prototype$stepCPU","fComplete","fStopped","complete","CPUStatePDP11","addrReset","pswTrap","pswMode","flagC","flagV","flagZ","flagN","addrLast","opLast","addrInvalid","mmuEnable","mmuLastMode","mmuLastPage","mmuMask","regMMR1","regMMR2","opFlags","mapMMR3","offRegSrc","maskRegSrcByte","MODEL_1120","opDecode","PDP11.op1120.bind","checkStackLimit","checkStackLimit1120","pswUsed","pswRegSet","PDP11.op1140.bind","checkStackLimit1140","trapVector","trapReason","irqNext","aIRQs","getByteDirect","getByteChecked","getWordChecked","setByteChecked","setWordChecked","addrDSpace","nReadBreaks","nWriteBreaks","getAddr","getVirtualAddrByMode","readWordFromVirtual","writeWordToVirtual","dstMode","dstReg","dstAddr","srcMode","srcReg","CPUStatePDP11.prototype","vectorFloating","vector","initCPU","resetIRQs","setMemoryAccess","BusPDP11.IOPAGE_22BIT","BusPDP11.IOPAGE_18BIT","readWordFromVirtualChecked","writeWordToVirtualChecked","BusPDP11.IOPAGE_16BIT","getPhysicalAddrByMode","readWordFromPhysicalChecked","readWordFromPhysical","writeWordToPhysicalChecked","writeWordToPhysical","newMMR0","result","newMMR3","BusPDP11.MASK_22BIT","BusPDP11.MASK_18BIT","setReset","fStart","bUnit","resetCPU","isRunning","getMMR3","getSpeed","saveIRQs","aIRQVectors","restoreIRQs","next","restoreTimers","getCF","getVF","getZF","getNF","advancePC","pc","REG","branch","opCode","condition","getPC","priority","PDP11.VECTORS","removeIRQ","irqPrev","OPFLAG","insertIRQ","checkTraps","REASON","newPSW","tmp","oldMode","newPIR","PIR","bits","updateNZVFlags","updateAllFlags","overflow","updateShiftFlags","updateSubFlags","src","dst","flag","reason","newPC","pushWord","trapReturn","popWord","mapUnibus","idx","getAddrInfo","fPhysical","addrPhysical","mode","page","paf","BusPDP11.UNIBUS_22BIT","addrVirtual","pdr","PDR","getAddrByMode","step","readWordFromPrevSpace","OPREG","OPMODE","writeWordToPrevSpace","readSrcByte","SRCMODE","readSrcWord","readDstAddr","readDstByte","readDstWord","updateDstByte","fnOp","PDP11.ACCESS.UPDATE_BYTE","updateDstWord","PDP11.ACCESS.UPDATE_WORD","writeDstByte","writeFlags","fnFlags","writeDstWord","nMinCycles","nDebugCheck","checksEnabled","nDebugState","checkInstruction","fInterrupt","checkIRQs","dispatchInterrupt","getOpcode","aeCPUs","iCPU","eCPU","PDP11.fnADD","updateAddFlags","PDP11.fnADDB","PDP11.fnASL","PDP11.fnASLB","PDP11.fnASR","PDP11.fnASRB","PDP11.fnBIC","PDP11.fnBICB","PDP11.fnBIS","PDP11.fnBISB","PDP11.fnCOM","PDP11.fnCOMB","PDP11.fnDEC","updateDecFlags","PDP11.fnDECB","PDP11.fnINC","updateIncFlags","PDP11.fnINCB","PDP11.fnNEG","PDP11.fnNEGB","PDP11.fnROL","PDP11.fnROLB","PDP11.fnROR","PDP11.fnRORB","PDP11.fnSUB","PDP11.fnSUBB","PDP11.fnSWAB","updateNZVCFlags","PDP11.fnXOR","PDP11.opADD","PDP11.opASH","PDP11.opASHC","PDP11.opBCC","PDP11.opBCS","PDP11.opBIC","PDP11.opBICB","PDP11.opBIS","PDP11.opBISB","PDP11.opBIT","PDP11.opBITB","PDP11.opBEQ","PDP11.opBGE","PDP11.opBGT","PDP11.opBHI","PDP11.opBLE","PDP11.opBLOS","PDP11.opBLT","PDP11.opBMI","PDP11.opBNE","PDP11.opBPL","PDP11.opBPT","PDP11.opBR","PDP11.opBVC","PDP11.opBVS","PDP11.opCLx","clearCF","clearVF","clearZF","clearNF","PDP11.opCMP","PDP11.opCMPB","PDP11.opDIV","PDP11.opEMT","PDP11.opHALT","stopInstruction","PDP11.opIOT","PDP11.JMP_CYCLES","PDP11.opJMP","PDP11.JSR_CYCLES","PDP11.opJSR","PDP11.MOV_CYCLES","PDP11.opMOV","PDP11.opMOVB","PDP11.MTP_CYCLES","PDP11.opMUL","updateMulFlags","PDP11.opNOP","PDP11.opRESET","PDP11.opRTS","PDP11.opUndefined.call","PDP11.opRTT","PDP11.opSEx","setCF","setVF","setZF","setNF","PDP11.opSOB","DSTMODE","PDP11.opSUB","PDP11.opSWAB","PDP11.opTRAP","PDP11.opWAIT","PDP11.opXOR","PDP11.opUndefined","PDP11.op1120","PDP11.aOpXnnn_1120","PDP11.op0AXn_1120","PDP11.aOp0AXn_1120","PDP11.op0BXn_1120","PDP11.aOp0BXn_1120","PDP11.op0CXn_1120","PDP11.aOp0CXn_1120","PDP11.op00AX_1120","PDP11.aOp00AX_1120","PDP11.op00BX_1120","PDP11.aOp00BX_1120","PDP11.op8AXn_1120","PDP11.aOp8AXn_1120","PDP11.op8BXn_1120","PDP11.aOp8BXn_1120","PDP11.op8CXn_1120","PDP11.aOp8CXn_1120","PDP11.op0Xnn_1120","PDP11.aOp0Xnn_1120","PDP11.op8Xnn_1120","PDP11.aOp8Xnn_1120","PDP11.op00Xn_1120","PDP11.aOp00Xn_1120","PDP11.opCLR","PDP11.opCOM","PDP11.opINC","PDP11.opDEC","PDP11.opNEG","PDP11.opADC","PDP11.opSBC","PDP11.opTST","PDP11.opROR","PDP11.opROL","PDP11.opASR","PDP11.opASL","PDP11.op000X_1120","PDP11.aOp000X_1120","PDP11.opCLC","PDP11.opCLV","PDP11.opCLZ","PDP11.opCLN","PDP11.opSEC","PDP11.opSEV","PDP11.opSEZ","PDP11.opSEN","PDP11.opCLRB","PDP11.opCOMB","PDP11.opINCB","PDP11.opDECB","PDP11.opNEGB","PDP11.opADCB","PDP11.opSBCB","PDP11.opTSTB","PDP11.opRORB","PDP11.opROLB","PDP11.opASRB","PDP11.opASLB","PDP11.op1140","PDP11.aOpXnnn_1140","PDP11.op0Xnn_1140","PDP11.aOp0Xnn_1140","PDP11.op7Xnn_1140","PDP11.aOp7Xnn_1140","PDP11.op8Xnn_1140","PDP11.aOp8Xnn_1140","PDP11.op00Xn_1140","PDP11.aOp00Xn_1140","PDP11.op0DXn_1140","PDP11.aOp0DXn_1140","PDP11.opMARK","setSP","PDP11.opMFPI","PDP11.opMTPI","PDP11.opSXT","PDP11.op000X_1140","PDP11.aOp000X_1140","PDP11.opSPL","PDP11.opRTI","PDP11.opMFPT","PDP11.op8DXn_1140","PDP11.aOp8DXn_1140","PDP11.opMTPS","PDP11.opMFPD","PDP11.opMTPD","PDP11.opMFPS","ROMPDP11","parmsROM","abInit","addrROM","sizeROM","fRetainROM","addrAlias","sFilePath","Str.getBaseName","sFileURL","sFileExt","Str.getExtension","FORMAT","Web.getHost","rom","Web.getResource","doneLoad","sResponse","Component.addMachineResource","Web.parseMemoryResource","initROM","ROMPDP11.prototype","addSymbols","IOTable","readROMByte","writeROMByte","addROM","aliases","cloneROM","aBlocks","aeROM","iROM","eROM","RAMPDP11","parmsRAM","addrRAM","sizeRAM","fAllocated","ram","initRAM","loadImage","zero","pattern","len","addrInit","fStop","fLoaded","offBlock","Str.toHexWord","offData","cbData","aeRAM","iRAM","eRAM","KeyboardPDP11","parmsKbd","aeKbd","iKbd","eKbd","kbd","SerialPortPDP11","parmsSerial","iAdapter","nBaudReceive","nBaudTransmit","fUpperCase","controlBuffer","consoleBuffer","tabSize","charBOL","iLogicalCol","fNullModem","irqReceiver","irqTransmitter","timerReceiveInterrupt","timerTransmitInterrupt","regRBUF","regRCSR","regXCSR","abReceive","target","connection","sendData","initConnection","receiveData","receiveStatus","setConnection","SerialPortPDP11.prototype","serial","onkeydown","control.onkeydown","bASCII","keyCode","KEYCODE","altKey","Keys.ASCII.CTRL_H","Keys.ASCII.DEL","ctrlKey","Keys.ASCII.A","Keys.ASCII.Z","Keys.ASCII.CTRL_A","onkeypress","control.onkeypress","metaKey","which","Keys.ASCII.CTRL_M","Keys.ASCII.CTRL_J","onpaste","control.onpaste","stopPropagation","clipboardData","getData","removeAttribute","readyReceiver","nBytesPerSecond","readyTransmitter","SerialPortPDP11.UNIBUS_IOTABLE","sConnection","asParts","sSourceID","Str.trim","sTargetID","fnConnect","initState","saveRegisters","bASCIIPrev","charCodeAt","LF","CR","pins","oldRCSR","CTS","CD","readRCSR","writeRCSR","delta","RTS","DTR","readRBUF","writeRBUF","readXCSR","writeXCSR","readXBUF","writeXBUF","transmitByte","nChars","Str.pad","aeSerial","iSerial","eSerial","configMount","parseConfig","cAutoMount","regPRB","regPRS","regPPS","iTapeData","regPPB","aTapeData","sTapeSource","PC11.SOURCE.NONE","nTapeTarget","PC11.TARGET.NONE","sTapeName","sTapePath","nLastPercent","fLocalTapes","Web.isMobile","irqReader","timerReader","config","PC11.prototype","pc11","onchange","controlSelect.onchange","controlDesc","controlOption","dataValue","sHRef","innerHTML","PC11.TARGET.MEMORY","PC11.TARGET.READER","controlTapes","loadSelectedTape","text","removeChild","addEventListener","fieldset","children","submit","disabled","files","onsubmit","controlInput.onsubmit","file","currentTarget","PC11.BINDING.READ_PROGRESS","getMachineComponent","readyReader","displayProgress","PC11.UNIBUS_IOTABLE","addTape","PC11.SOURCE.LOCAL","PC11.SOURCE.REMOTE","autoMount","sPath","loadTape","displayTape","prompt","unloadTape","fAutoMount","nResult","load","parseTape","sTapeURL","reader","FileReader","onload","reader.onload","byteLength","readAsArrayBuffer","ENDPOINT","sTapeExt","encodeURI","fTop","createElement","insertBefore","appendChild","sTargetPath","nPercent","controlBar","PC11.CSSCLASS.PROGRESS_BAR","width","fLoading","readPRS","writePRS","readPRB","writePRB","readPPS","writePPS","readPPB","writePPB","LOCAL","REMOTE","READER","READ_PROGRESS","PROGRESS_BAR","DiskPDP11","drive","DiskPDP11.nDisks","sDiskName","sDiskPath","sDiskFile","fRemovable","nCylinders","nHeads","nSectors","cbSector","aDiskData","dwChecksum","fWriteProtected","create","fnNotify","controllerNotify","DiskPDP11.prototype","aCylinders","iCylinder","aHeads","iHead","aSectors","iSector","initSector","sDiskURL","disk","cbDiskData","diskFormat","cdw","cylinder","head","sector","dwPattern","cModify","sDiskExt","sDiskParm","QUERY","sSizeParm","Str.endsWith","sDiskData","iEOL","sConfig","cb","fill","iModify","seek","track","bFormatting","bSectorEnd","nBytes","bSector","read","ibSector","write","getSector","pba","nSectorsPerCylinder","nSectorsRemaining","getSectorData","deltas","mods","iModifyLimit","nChanges","sReason","aDiskInfo","mod","DriveController","configDC","configDrive","configIO","nDrives","aDrives","fLocalDisks","aDiskHistory","bootSelectedDisk","loadSelectedDisk","selectDrive","waitDrives","DriveController.prototype","dc","control.onchange","updateSelectedDisk","iDrive","displayDisk","controlDrives","btoa","link","sURI","download","href","body","click","sAlert","sDrive","addDisk","DriveController.SOURCE.NONE","DriveController.SOURCE.LOCAL","DriveController.SOURCE.REMOTE","fReload","unloadAllDrives","unloadDrive","firstChild","getDriveName","initController","initDrives","saveController","saveHistory","saveDrives","aHistory","initHistory","aConfigDisks","initDrive","configDisk","fLocal","iCylinderBoot","iHeadBoot","iSectorBoot","cbSectorBoot","bHead","bCylinder","doneLoadDrive","loadDrive","addDiskHistory","updateDiskHistory","fRemount","controlDisks","stringify","readData","notifyLoad","fUpdateDrive","iDriveSelected","writeData","PDP11.RK11","RK11.UNIBUS_IOTABLE","regRKDS","regRKER","regRKCS","regRKWC","regRKBA","regRKDA","regRKDB","RK11.prototype","RK11.RKDS.RK05","RK11.RKDS.SOK","RK11.RKDS.RRDY","RK11.RKCS.CRDY","nWords","fCheck","nError","RK11.RKER.NXD","RK11.RKER.NXC","RK11.RKER.SKE","b0","b1","RK11.RKER.NXS","RK11.RKER.NXM","RK11.RKER.WCE","RK11_prototype$doneReadWrite","doneReadWrite","RK11.RKCS.MEX","RK11.RKCS.SHIFT.MEX","RK11.RKDA.SA","updateErrors","RK11.RKCS.ERR","RK11.RKER.DRE","RK11.RKER.HE","RK11.RKCS.HE","readRKDS","writeRKDS","readRKER","writeRKER","readRKCS","RK11.RKCS.RMASK","writeRKCS","RK11.RKCS.WMASK","RK11.RKCS.GO","func","processCommand","RK11.RKDA.DS","RK11.RKDA.SHIFT.DS","RK11.RKCS.SCP","RK11.RKER.SE","RK11.RKCS.FUNC","RK11.FUNC.CRESET","RK11.FUNC.RCHK","RK11.FUNC.READ","fnReadWrite","RK11.FUNC.WCHK","RK11.FUNC.WRITE","RK11.RKDA.CA","RK11.RKDA.SHIFT.CA","RK11.RKDA.HS","RK11.RKDA.SHIFT.HS","RK11.RKCS.IBA","RK11.FUNC.SEEK","RK11.FUNC.DRESET","RK11.RKDS.DRDY","RK11.RKDS.SHIFT.ID","RK11.RKDS.SC","RK11.RKCS.IE","readRKWC","writeRKWC","readRKBA","writeRKBA","readRKDA","writeRKDA","readRKDB","writeRKDB","RK11.RKDS","PDP11.RK11.RKDS","RK11.RKER","PDP11.RK11.RKER","RK11.RKCS","PDP11.RK11.RKCS","RK11.RKDA","PDP11.RK11.RKDA","RK11.FUNC","PDP11.RK11.FUNC","PDP11.RL11","RL11.UNIBUS_IOTABLE","regRLCS","regRLBA","regRLDA","tmpRLDA","regRLMP","regRLBE","RL11.prototype","RL11.RLCS.DRDY","RL11.RLCS.CRDY","RL11.ERRC.HNF","RL11.ERRC.NXM","RL11_prototype$doneReadWrite","RL11.RLCS.BAE","RL11.RLCS.SHIFT.BAE","RL11.RLBE.MASK","RL11.RLDA.SHIFT.RW_CA","RL11.RLDA.RW_HS","RL11.RLDA.RW_SA","RL11.RLCS.ERR","readRLCS","RL11.RLCS.RMASK","writeRLCS","RL11.RLCS.WMASK","RL11.RLCS.DS","RL11.RLCS.SHIFT.DS","RL11.RLCS.FUNC","RL11.FUNC.STATUS","RL11.RLMP.GS_BH","RL11.RLMP.GS_DT","RL11.FUNC.SEEK","RL11.RLDA.GS_CMD","RL11.RLDA.SEEK_CMD","darCA","RL11.RLDA.RW_CA","darHS","RL11.RLDA.SEEK_HS","RL11.RLDA.SEEK_DIR","RL11.FUNC.RHDR","RL11.FUNC.RDATA","RL11.FUNC.WDATA","RL11.RLCS.IE","readRLBA","writeRLBA","RL11.RLBA.WMASK","readRLDA","writeRLDA","readRLMP","writeRLMP","readRLBE","writeRLBE","RL11.RLCS","PDP11.RL11.RLCS","RL11.RLBA","PDP11.RL11.RLBA","RL11.RLDA","PDP11.RL11.RLDA","RL11.RLMP","PDP11.RL11.RLMP","RL11.RLBE","PDP11.RL11.RLBE","RL11.ERRC","PDP11.RL11.ERRC","RL11.FUNC","PDP11.RL11.FUNC","PDP11.RX11","RX11.UNIBUS_IOTABLE","regRXTA","regRXSA","regRXES","regError","regRXCS","regRXDB","funCode","RX11.FUNC.UNUSED","iBuffer","abBuffer","RX11.prototype","RX11.FUNC.READ","readSector","doneCommand","RX11.RXCS.ERR","RX11.RXCS.DONE","RX11.RXCS.IE","RX11.ERROR.HOME1","RX11.ERROR.HOME0","RX11.ERROR.NO_TRACK","RX11.ERROR.NO_SECTOR","RX11.ERROR.NO_DATA","RX11.RXCS.UNIT","RX11.RXTA.MASK","nSector","RX11.RXSA.MASK","RX11.RXES.CRC","RX11.RXES.PARITY","RX11.RXES.DEL","RX11.RXES.DRDY","deleted","readRXCS","RX11.RXCS.RMASK","RX11.FUNC.FILL","RX11.FUNC.EMPTY","RX11.RXCS.TR","RX11.FUNC.WRITE","RX11.FUNC.WRDEL","writeRXCS","RX11.RXCS.WMASK","RX11.RXCS.INIT","RX11.RXCS.GO","RX11.RXCS.FUNC","RX11.FUNCS","RX11.FUNC.RDSTAT","RX11.FUNC.RDERR","readRXDB","writeRXDB","writeSector","fDeleted","RX11.RXCS","PDP11.RX11.RXCS","RX11.RXTA","PDP11.RX11.RXTA","RX11.RXSA","PDP11.RX11.RXSA","RX11.RXES","PDP11.RX11.RXES","RX11.FUNC","PDP11.RX11.FUNC","RX11.ERROR","PDP11.RX11.ERROR","Debugger","parmsDbg","achGroup","achAddress","fAssemble","iPrevCmd","aPrevCmds","aVariables","getRegIndex","getRegValue","parseCommand","sCmd","chSep","iPrev","chQuote","truncate","fUnsigned","vNew","limit","evalOps","aVals","aOps","cOps","chOp","pop","val2","val1","valNew","parseArray","asValues","iValue","iLimit","aUndefined","fError","nUnary","nBasePrev","sOp","parseValue","cOpen","iStart","parseUnary","aBinOp","Debugger.aDECOpPrecedence","Debugger.aBinOpPrecedence","parseASCII","sExp","chDelim","cchMax","parseExpression","fQuiet","fPrint","join","regExp","printValue","bit","getVariable","sVar","sUndefined","getVariableFixup","valueUndefined","fDefined","printVariable","cVariables","aVars","keys","sort","Str.toBin","DebuggerPDP11","dbgAddrNextCode","newAddr","dbgAddrNextData","dbgAddrAssemble","aSymbolTable","aBreakExec","aBreakRead","aBreakWrite","clearBreakpoints","iInstructionHistory","nBreakInstructions","aInstructionHistory","nextHistory","historyInit","afnDumpers","sMessagePrev","aMessageBuffer","messageInit","opTable","DebuggerPDP11.OPTABLE","aOpReserved","nStep","sCmdDumpPrev","sCmdTracePrev","nCyclesStart","msStart","cInstructions","nSuppressBreaks","controlDebug","global","dbgAddr","ADDR_INVALID","fTemporary","DebuggerPDP11.prototype","packAddr","unpackAddr","aAddr","aCmds","sMessages","DebuggerPDP11.OP1140","DebuggerPDP11.OP1145","onDumpBus","sAddr","parseAddr","typePrev","cPrev","setSelectionRange","Web.onClickRepeat","onClickDebugEnter","onClickStep","fRepeat","fCompleted","scrollX","scrollY","focus","scrollTo","DebuggerPDP11_prototype$getByte","incAddr","DebuggerPDP11_prototype$getWord","DebuggerPDP11_prototype$setByte","DebuggerPDP11_prototype$setWord","fCode","dbgAddrNext","chOpen","parseReference","chClose","chEscape","chInnerEscape","reSubExp","sReplace","findSymbolAddr","sSymbol","offSymbol","sUpperCase","iTable","symbol","symbolTable","parseAddrOptions","sOptions","toStrAddr","toStrOffset","sEnable","aEnable","bitMessage","fnDumper","DebuggerPDP11.REGS","getRegName","DebuggerPDP11.REG_AR","DebuggerPDP11.REGNAMES","DebuggerPDP11.REG_PS","DebuggerPDP11.REG_PI","DebuggerPDP11.REG_ER","DebuggerPDP11.REG_SL","DebuggerPDP11.REG_M0","DebuggerPDP11.REG_M1","DebuggerPDP11.REG_M2","DebuggerPDP11.REG_M3","DebuggerPDP11.REG_DR","DebuggerPDP11.REG_SR","fRunning","DebuggerPDP11.HISTORY_LIMIT","checkCPU","fRegs","fUpdateDisplays","DebuggerPDP11.PROMPT","trapStatus","PDP11.REASONS","doRegisters","doUnassemble","clearTempBreakpoint","sStopped","msTotal","nState","OPCODE","checkBreakpoint","nb","nBreaks","aBreak","findBreakpoint","printBreakpoint","fFound","dbgAddrBreak","listBreakpoints","sAction","addrBreak","doCommand","getInstruction","sComment","nSequence","dbgAddrOp","opDesc","opMasks","DebuggerPDP11.OPNONE","opNum","sTarget","sOperands","sOpName","DebuggerPDP11.OPNAMES","cOperands","iOperand","opType","getOperand","sOperand","opTypeOther","DebuggerPDP11.OP_OTHER","DebuggerPDP11.OP_BRANCH","DebuggerPDP11.OP_DSTOFF","DebuggerPDP11.OP_DSTNUM3","DebuggerPDP11.OP_DSTNUM6","DebuggerPDP11.OP_DSTNUM8","opMode","DebuggerPDP11.OP_SRC","DebuggerPDP11.OP_DST","DebuggerPDP11.OP_DSTREG","DebuggerPDP11.OP_DSTMODE","getTarget","wIndex","sOpCodes","sLine","getFlagOutput","sFlag","getRegOutput","getRegDump","fMisc","getMiscDump","comparePairs","p1","p2","sModule","aOffsets","sAnnotation","Usr.binarySearch","findSymbol","fNearest","aSymbol","addrSymbol","returnSymbol","iOffset","doVar","delVariable","setVariable","doList","nDelta","sDelta","fInstruction","sRegMatch","doPrint","doTrace","sCount","nCount","Web.onCountRepeat","onCountStep","onCountStepComplete","sAddrEnd","nLines","dbgAddrEnd","nPrinted","sInstruction","s0","ch0","unshift","doAssemble","aOpBytes","doBreak","cBreaks","doClear","controlPrint","sLen","sBytes","sDumpers","doDump","sState","powerOff","sSymbolOrig","sMore","cHistory","iHistory","nPrev","sPrev","sLines","aFilters","dbgAddrNew","cOverrides","DebuggerPDP11.MODES","fJSON","nBytesPerLine","sChars","fnGet","doEdit","fnSet","doRun","doHalt","doIf","doStackTrace","cFrames","dbgAddrCall","dbgAddrStack","nFrames","sCall","cTests","addrOrig","sCallPrev","fCriteria","sCategory","doMessages","sCategories","fEnabled","sOption","doStep","doOptions","DebuggerPDP11.COMMANDS","doHelp","MOV","CMP","BIT","BIC","BIS","ADD","MOVB","CMPB","BITB","BICB","BISB","SUB","JSR","DebuggerPDP11.OP_SRCREG","MUL","DIV","ASH","ASHC","XOR","SOB","BR","BNE","BEQ","BGE","BLT","BGT","BLE","BPL","BMI","BHI","BLOS","BVC","BVS","BCC","BCS","EMT","JMP","SWAB","CLR","COM","INC","DEC","NEG","ADC","SBC","TST","ROR","ROL","ASR","ASL","MARK","MFPI","MTPI","SXT","CLRB","COMB","INCB","DECB","NEGB","ADCB","SBCB","TSTB","RORB","ROLB","ASRB","ASLB","MTPS","MFPD","MTPD","MFPS","SPL","WAIT","RTI","BPT","IOT","RESET","RTT","MFPT","CLC","CLV","CLCV","CLZ","CLCZ","CLVZ","CLCVZ","CLN","CLCN","CLVN","CLCVN","CLZN","CLCZN","CLVZN","CCC","SEC","SEV","SECV","SEZ","SECZ","SEVZ","SECVZ","SEN","SECN","SEVN","SECVN","SEZN","SECZN","SEVZN","SCC","aeDbg","iDbg","eDbg","ComputerPDP11","parmsComputer","parmsMachine","fSuspended","setMachineParms","fAutoPower","BOOLEAN","nPowerChange","sStateData","sResumePath","sStatePath","fServerState","fStateData","stateComputer","stateFailSafe","fInitialized","fRestoreError","url","random","sUserID","queryUserID","LICENSE","sResume","resume","fAllowResume","ComputerPDP11.RESUME_NONE","APPVERSION","getServerStatePath","doneStateLoad","sResource","wait","powerOn","parmsComponent","sParmLC","defaultValue","NUMBER","ComputerPDP11.prototype","onComponentReady","validateState","stateValidate","ComputerPDP11.STATE_VALIDATE","sTimestampValidate","get","ComputerPDP11.STATE_TIMESTAMP","sTimestampComputer","clear","ComputerPDP11.RESUME_AUTO","fRestore","ComputerPDP11.RESUME_REPOWER","ComputerPDP11.STATE_FAILSAFE","powerReport","ComputerPDP11.RESUME_PROMPT","unload","Usr.formatDate","store","fValidate","Component.confirmUser","sCode","RES","CODE","FAIL","Web.setLocalStorageItem","ComputerPDP11.STATE_USERID","resetUserID","powerRestore","donePowerOn","reload","asComments","controlPower","getUserID","dataPost","sUser","TYPE","sReport","sReportURL","sTimestamp","ComputerPDP11.STATE_VERSION","ComputerPDP11.STATE_HOSTURL","ComputerPDP11.STATE_BROWSER","fClearAll","fClear","saveServerState","ComputerPDP11.RESUME_DELETE","nDisplayLimit","getSpeedCurrent","fWaiting","B22","B18","B16","fPrompt","Web.getLocalStorageItem","verifyUserID","code","State.key","REQ","storeServerState","sError","fScroll","aeMachines","iMachine","eMachine","aeComputers","iComputer","eComputer","show","exit","sVersion","json","fParsed","key","State.prototype","Web.hasLocalStorage","fAll","cAsyncMachines","loadXML","sXMLFile","fResolve","display","doneLoadXML","sURLName","sXML","parseXML","buildXML","pathname","xmlDoc","async","parseFromString","DOMParser","resolveXML","matchRef","reRef","sRefFile","doneReadXML","sXMLRef","sRefAttrs","aXMLRefTag","sXMLNewTag","matchAttr","reAttr","embedMachine","sXSLFile","displayMessage","eWarning","aeWarning","Str.escapeHTML","displayError","Web.enablePageEvents","getElementById","css","styleSheet","cssText","createTextNode","sAppFolder","processXML","xml","transformXML","sXSL","xsl","sFragment","outerHTML","implementation","createDocument","xsltProcessor","XSLTProcessor","eFragment","replaceChild","embedPDP10","embedPDP11","commandMachine","fSingle","sComponent","sToken"],"sourcesContent":["\"use strict\";\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/defines.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @define {string}\n */\nvar APPVERSION = \"\"; // this @define is overridden by the Closure Compiler with the version in machines.json\n\nvar XMLVERSION = null; // this is set in non-COMPILED builds by embedMachine() if a version number was found in the machine XML\n\nvar COPYRIGHT = \"Copyright © 2012-2018 Jeff Parsons <Jeff@pcjs.org>\";\n\nvar LICENSE = \"License: GPL version 3 or later <http://gnu.org/licenses/gpl.html>\";\n\nvar CSSCLASS = \"pcjs\";\n\n/**\n * @define {string}\n */\nvar SITEHOST = \"localhost:8088\";// this @define is overridden by the Closure Compiler with \"www.pcjs.org\"\n\n/**\n * @define {boolean}\n */\nvar COMPILED = false; // this @define is overridden by the Closure Compiler (to true)\n\n/**\n * @define {boolean}\n */\nvar DEBUG = true; // this @define is overridden by the Closure Compiler (to false) to remove DEBUG-only code\n\n/**\n * @define {boolean}\n */\nvar MAXDEBUG = false; // this @define is overridden by the Closure Compiler (to false) to remove MAXDEBUG-only code\n\n/**\n * @define {boolean}\n */\nvar PRIVATE = false; // this @define is overridden by the Closure Compiler (to false) to enable PRIVATE code\n\n/*\n * RS-232 DB-25 Pin Definitions, mapped to bits 1-25 in a 32-bit status value.\n *\n * SerialPorts in PCjs machines are considered DTE (Data Terminal Equipment), which means they should be \"virtually\"\n * connected to each other via a null-modem cable, which assumes the following cross-wiring:\n *\n * G 1 <-> 1 G (Ground)\n * TD 2 <-> 3 RD (Received Data)\n * RD 3 <-> 2 TD (Transmitted Data)\n * RTS 4 <-> 5 CTS (Clear To Send)\n * CTS 5 <-> 4 RTS (Request To Send)\n * DSR 6+8 <-> 20 DTR (Data Terminal Ready)\n * SG 7 <-> 7 SG (Signal Ground)\n * DTR 20 <-> 6+8 DSR (Data Set Ready + Carrier Detect)\n * RI 22 <-> 22 RI (Ring Indicator)\n *\n * TODO: Move these definitions to a more appropriate shared file at some point.\n */\nvar RS232 = {\n RTS: {\n PIN: 4,\n MASK: 0x00000010\n },\n CTS: {\n PIN: 5,\n MASK: 0x00000020\n },\n DSR: {\n PIN: 6,\n MASK: 0x00000040\n },\n CD: {\n PIN: 8,\n MASK: 0x00000100\n },\n DTR: {\n PIN: 20,\n MASK: 0x00100000\n },\n RI: {\n PIN: 22,\n MASK: 0x00400000\n }\n};\n\n/*\n * NODE should be true if we're running under NodeJS (eg, command-line), false if not (eg, web browser)\n */\nvar NODE = false;\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/diskapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Our \"DiskIO API\" looks like:\n *\n * http://www.pcjs.org/api/v1/disk?action=open&volume=*10mb.img&mode=demandrw&chs=c:h:s&machine=xxx&user=yyy\n */\nvar DiskAPI = {\n ENDPOINT: \"/api/v1/disk\",\n QUERY: {\n ACTION: \"action\", // value is one of DiskAPI.ACTION.*\n VOLUME: \"volume\", // value is path of a disk image\n MODE: \"mode\", // value is one of DiskAPI.MODE.*\n CHS: \"chs\", // value is cylinders:heads:sectors:bytes\n ADDR: \"addr\", // value is cylinder:head:sector:count\n MACHINE: \"machine\", // value is machine token\n USER: \"user\", // value is user ID\n DATA: \"data\" // value is data to be written\n },\n ACTION: {\n OPEN: \"open\",\n READ: \"read\",\n WRITE: \"write\",\n CLOSE: \"close\"\n },\n MODE: {\n LOCAL: \"local\", // this mode implies no API (at best, localStorage backing only)\n PRELOAD: \"preload\", // this mode implies use of the DumpAPI\n DEMANDRW: \"demandrw\",\n DEMANDRO: \"demandro\"\n },\n FAIL: {\n BADACTION: \"invalid action\",\n BADUSER: \"invalid user\",\n BADVOL: \"invalid volume\",\n OPENVOL: \"unable to open volume\",\n CREATEVOL: \"unable to create volume\",\n WRITEVOL: \"unable to write volume\",\n REVOKED: \"access revoked\"\n }\n};\n\n/*\n * TODO: Eventually, our tools will need to support looking up disk formats by \"model\" rather than by raw disk size,\n * because obviously multiple disk geometries can yield the same raw disk size. For each conflict that arises, I'll\n * probably create a fake (approximate) disk size entry above, and then create a mapping to that approximate size below.\n */\nDiskAPI.MODELS = {\n \"RL01\": 5242880,\n \"RL02\": 10485760\n};\n\nDiskAPI.MBR = {\n PARTITIONS: {\n OFFSET: 0x1BE,\n ENTRY: {\n STATUS: 0x00, // 1-byte (0x80 if active)\n CHS_FIRST: 0x01, // 3-byte CHS specifier\n TYPE: 0x04, // 1-byte TYPE (see below)\n CHS_LAST: 0x05, // 3-byte CHS specifier\n LBA_FIRST: 0x08, // 4-byte Logical Block Address\n LBA_TOTAL: 0x0C, // 4-byte Logical Block Address\n },\n ENTRY_LENGTH: 0x10,\n STATUS: {\n ACTIVE: 0x80\n },\n TYPE: {\n EMPTY: 0x00,\n FAT12_PRIMARY: 0x01, // DOS 2.0 and up (12-bit FAT)\n FAT16_PRIMARY: 0x04 // DOS 3.0 and up (16-bit FAT)\n }\n },\n SIG_OFFSET: 0x1FE,\n SIGNATURE: 0xAA55 // to be clear, the low byte (at offset 0x1FE) is 0x55 and the high byte (at offset 0x1FF) is 0xAA\n};\n\n/*\n * Boot sector offsets (and assorted constants) in DOS-compatible boot sectors (DOS 2.0 and up)\n *\n * WARNING: I've heard apocryphal stories about SIGNATURE being improperly reversed on some systems\n * (ie, 0x55AA instead 0xAA55) -- perhaps by a dyslexic programmer -- so be careful out there.\n */\nDiskAPI.BOOT = {\n JMP_OPCODE: 0x000, // 1 byte for a JMP opcode, followed by a 1 or 2-byte offset\n OEM_STRING: 0x003, // 8 bytes\n SIG_OFFSET: 0x1FE,\n SIGNATURE: 0xAA55 // to be clear, the low byte (at offset 0x1FE) is 0x55 and the high byte (at offset 0x1FF) is 0xAA\n};\n\n/*\n * BIOS Parameter Block (BPB) offsets in DOS-compatible boot sectors (DOS 2.x and up)\n *\n * NOTE: DOS 2.x OEM documentation says that the words starting at offset 0x018 (TRACK_SECS, TOTAL_HEADS, and HIDDEN_SECS)\n * are optional, but even the DOS 2.0 FORMAT utility initializes all three of those words. There may be some OEM media out\n * there with BPBs that are only valid up to offset 0x018, but I've not run across any media like that.\n *\n * DOS 3.20 added LARGE_SECS, but unfortunately, it was added as a 2-byte value at offset 0x01E. DOS 3.31 decided\n * to make both HIDDEN_SECS and LARGE_SECS 4-byte values, which meant that LARGE_SECS had to move from 0x01E to 0x020.\n */\nDiskAPI.BPB = {\n SECTOR_BYTES: 0x00B, // 2 bytes: bytes per sector (eg, 0x200 or 512)\n CLUSTER_SECS: 0x00D, // 1 byte: sectors per cluster (eg, 1)\n RESERVED_SECS: 0x00E, // 2 bytes: reserved sectors; ie, # sectors preceding the first FAT--usually just the boot sector (eg, 1)\n TOTAL_FATS: 0x010, // 1 byte: FAT copies (eg, 2)\n ROOT_DIRENTS: 0x011, // 2 bytes: root directory entries (eg, 0x40 or 64) 0x40 * 0x20 = 0x800 (1 sector is 0x200 bytes, total of 4 sectors)\n TOTAL_SECS: 0x013, // 2 bytes: number of sectors (eg, 0x140 or 320); if zero, refer to LARGE_SECS\n MEDIA_ID: 0x015, // 1 byte: media ID (see DiskAPI.FAT.MEDIA_*); should also match the first byte of the FAT (aka FAT ID)\n FAT_SECS: 0x016, // 2 bytes: sectors per FAT (eg, 1)\n TRACK_SECS: 0x018, // 2 bytes: sectors per track (eg, 8)\n TOTAL_HEADS: 0x01A, // 2 bytes: number of heads (eg, 1)\n HIDDEN_SECS: 0x01C, // 2 bytes (DOS 2.x) or 4 bytes (DOS 3.31 and up): number of hidden sectors (always 0 for non-partitioned media)\n LARGE_SECS: 0x020 // 4 bytes (DOS 3.31 and up): number of sectors if TOTAL_SECS is zero\n};\n\n/*\n * Common (supported) diskette geometries.\n *\n * Each entry in GEOMETRIES is an array of values in \"CHS\" order:\n *\n * [# cylinders, # heads, # sectors/track, # bytes/sector, media ID]\n *\n * If the 4th value is omitted, the sector size is assumed to be 512. The order of these \"geometric\" values mirrors\n * the structure of our JSON-encoded disk images, which consist of an array of cylinders, each of which is an array of\n * heads, each of which is an array of sector objects.\n */\nDiskAPI.GEOMETRIES = {\n 163840: [40,1,8,,0xFE], // media ID 0xFE: 40 cylinders, 1 head (single-sided), 8 sectors/track, ( 320 total sectors x 512 bytes/sector == 163840)\n 184320: [40,1,9,,0xFC], // media ID 0xFC: 40 cylinders, 1 head (single-sided), 9 sectors/track, ( 360 total sectors x 512 bytes/sector == 184320)\n 327680: [40,2,8,,0xFF], // media ID 0xFF: 40 cylinders, 2 heads (double-sided), 8 sectors/track, ( 640 total sectors x 512 bytes/sector == 327680)\n 368640: [40,2,9,,0xFD], // media ID 0xFD: 40 cylinders, 2 heads (double-sided), 9 sectors/track, ( 720 total sectors x 512 bytes/sector == 368640)\n 737280: [80,2,9,,0xF9], // media ID 0xF9: 80 cylinders, 2 heads (double-sided), 9 sectors/track, (1440 total sectors x 512 bytes/sector == 737280)\n 1228800: [80,2,15,,0xF9], // media ID 0xF9: 80 cylinders, 2 heads (double-sided), 15 sectors/track, (2400 total sectors x 512 bytes/sector == 1228800)\n 1474560: [80,2,18,,0xF0], // media ID 0xF0: 80 cylinders, 2 heads (double-sided), 18 sectors/track, (2880 total sectors x 512 bytes/sector == 1474560)\n 2949120: [80,2,36,,0xF0], // media ID 0xF0: 80 cylinders, 2 heads (double-sided), 36 sectors/track, (5760 total sectors x 512 bytes/sector == 2949120)\n /*\n * The following are some common disk sizes and their CHS values, since missing or bogus MBR and/or BPB values\n * might mislead us when attempting to determine the exact disk geometry.\n */\n 10653696:[306,4,17], // PC XT 10Mb hard drive (type 3)\n 21411840:[615,4,17], // PC AT 20Mb hard drive (type 2)\n /*\n * Assorted DEC disk formats.\n */\n 256256: [77, 1,26,128], // RX01 single-platter diskette: 77 tracks, 1 head, 26 sectors/track, 128 bytes/sector, for a total of 256256 bytes\n 2494464: [203,2,12,512], // RK03 single-platter disk cartridge: 203 tracks, 2 heads, 12 sectors/track, 512 bytes/sector, for a total of 2494464 bytes\n 5242880: [256,2,40,256], // RL01K single-platter disk cartridge: 256 tracks, 2 heads, 40 sectors/track, 256 bytes/sector, for a total of 5242880 bytes\n 10485760:[512,2,40,256] // RL02K single-platter disk cartridge: 512 tracks, 2 heads, 40 sectors/track, 256 bytes/sector, for a total of 10485760 bytes\n};\n\n/*\n * Media ID (descriptor) bytes for DOS-compatible FAT-formatted disks (stored in the first byte of the FAT)\n */\nDiskAPI.FAT = {\n MEDIA_160KB: 0xFE, // 5.25-inch, 1-sided, 8-sector, 40-track\n MEDIA_180KB: 0xFC, // 5.25-inch, 1-sided, 9-sector, 40-track\n MEDIA_320KB: 0xFF, // 5.25-inch, 2-sided, 8-sector, 40-track\n MEDIA_360KB: 0xFD, // 5.25-inch, 2-sided, 9-sector, 40-track\n MEDIA_720KB: 0xF9, // 3.5-inch, 2-sided, 9-sector, 80-track\n MEDIA_1200KB: 0xF9, // 3.5-inch, 2-sided, 15-sector, 80-track\n MEDIA_FIXED: 0xF8, // fixed disk (aka hard drive)\n MEDIA_1440KB: 0xF0, // 3.5-inch, 2-sided, 18-sector, 80-track\n MEDIA_2880KB: 0xF0 // 3.5-inch, 2-sided, 36-sector, 80-track\n};\n\n/*\n * Cluster constants for 12-bit FATs (CLUSNUM_FREE, CLUSNUM_RES and CLUSNUM_MIN are the same for all FATs)\n */\nDiskAPI.FAT12 = {\n MAX_CLUSTERS: 4084,\n CLUSNUM_FREE: 0, // this should NEVER appear in cluster chain (except at the start of an empty chain)\n CLUSNUM_RES: 1, // reserved; this should NEVER appear in cluster chain\n CLUSNUM_MIN: 2, // smallest valid cluster number\n CLUSNUM_MAX: 0xFF6, // largest valid cluster number\n CLUSNUM_BAD: 0xFF7, // bad cluster; this should NEVER appear in cluster chain\n CLUSNUM_EOC: 0xFF8 // end of chain (actually, anything from 0xFF8-0xFFF indicates EOC)\n};\n\n/*\n * Cluster constants for 16-bit FATs (CLUSNUM_FREE, CLUSNUM_RES and CLUSNUM_MIN are the same for all FATs)\n */\nDiskAPI.FAT16 = {\n MAX_CLUSTERS: 65524,\n CLUSNUM_FREE: 0, // this should NEVER appear in cluster chain (except at the start of an empty chain)\n CLUSNUM_RES: 1, // reserved; this should NEVER appear in cluster chain\n CLUSNUM_MIN: 2, // smallest valid cluster number\n CLUSNUM_MAX: 0xFFF6, // largest valid cluster number\n CLUSNUM_BAD: 0xFFF7, // bad cluster; this should NEVER appear in cluster chain\n CLUSNUM_EOC: 0xFFF8 // end of chain (actually, anything from 0xFFF8-0xFFFF indicates EOC)\n};\n\n/*\n * Directory Entry offsets (and assorted constants) in FAT disk images\n *\n * NOTE: Versions of DOS prior to 2.0 used INVALID exclusively to mark available directory entries; any entry marked\n * UNUSED was actually considered USED. In DOS 2.0 and up, UNUSED was added to indicate that all remaining entries were\n * unused, relieving it from having to initialize the rest of the sectors in the directory cluster(s). And in fact,\n * you will likely encounter garbage in subsequent directory sectors if you read beyond the first UNUSED entry.\n */\nDiskAPI.DIRENT = {\n NAME: 0x000, // 8 bytes\n EXT: 0x008, // 3 bytes\n ATTR: 0x00B, // 1 byte\n MODTIME: 0x016, // 2 bytes\n MODDATE: 0x018, // 2 bytes\n CLUSTER: 0x01A, // 2 bytes\n SIZE: 0x01C, // 4 bytes (typically zero for subdirectories)\n LENGTH: 0x20, // 32 bytes total\n UNUSED: 0x00, // indicates this and all subsequent directory entries are unused\n INVALID: 0xE5 // indicates this directory entry is unused\n};\n\n/*\n * Possible values for DIRENT.ATTR\n */\nDiskAPI.ATTR = {\n READONLY: 0x01, // PC-DOS 2.0 and up\n HIDDEN: 0x02,\n SYSTEM: 0x04,\n LABEL: 0x08, // PC-DOS 2.0 and up\n SUBDIR: 0x10, // PC-DOS 2.0 and up\n ARCHIVE: 0x20 // PC-DOS 2.0 and up\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/dumpapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Our \"DiskDump API\", such as it was, used to look like:\n *\n * http://jsmachines.net/bin/convdisk.php?disk=/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json&format=img\n *\n * To make it (a bit) more \"REST-like\", the above request now looks like:\n *\n * http://www.pcjs.org/api/v1/dump?disk=/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json&format=img\n *\n * Similarly, our \"FileDump API\" used to look like:\n *\n * http://jsmachines.net/bin/convrom.php?rom=/devices/pc/rom/5150/1981-04-24/PCBIOS-REV1.rom&format=json\n *\n * and that request now looks like:\n *\n * http://www.pcjs.org/api/v1/dump?file=/devices/pc/rom/5150/1981-04-24/PCBIOS-REV1.rom&format=json\n *\n * I don't think it makes sense to avoid \"query\" parameters, because blending the path of a disk image with the\n * the rest of the URL would be (a) confusing, and (b) more work to parse.\n */\nvar DumpAPI = {\n ENDPOINT: \"/api/v1/dump\",\n QUERY: {\n DIR: \"dir\", // value is path of a directory (DiskDump only)\n DISK: \"disk\", // value is path of a disk image (DiskDump only)\n FILE: \"file\", // value is path of a ROM image file (FileDump only)\n IMG: \"img\", // alias for DISK\n PATH: \"path\", // value is path of a one or more files (DiskDump only)\n FORMAT: \"format\", // value is one of FORMAT values below\n COMMENTS: \"comments\", // value is either \"true\" or \"false\"\n DECIMAL: \"decimal\", // value is either \"true\" to force all numbers to decimal, \"false\" or undefined otherwise\n MBHD: \"mbhd\", // value is hard drive size in Mb (formerly \"mbsize\") (DiskDump only) (DEPRECATED)\n SIZE: \"size\" // value is target disk size in Kb (supersedes \"mbhd\") (DiskDump only)\n },\n FORMAT: {\n JSON: \"json\", // default\n JSON_GZ: \"gz\", // gzip is currently used ONLY for compressed JSON\n DATA: \"data\", // same as \"json\", but built without JSON.stringify() (DiskDump only)\n HEX: \"hex\", // deprecated\n OCTAL: \"octal\", // displays data as octal words\n BYTES: \"bytes\", // displays data as hex bytes; normally used only when comments are enabled\n WORDS: \"words\", // displays data as hex words; normally used only when comments are enabled\n LONGS: \"longs\", // displays data as dwords\n IMG: \"img\", // returns the raw disk data (ie, using a Buffer object) (DiskDump only)\n ROM: \"rom\" // returns the raw file data (ie, using a Buffer object) (FileDump only)\n }\n};\n\n/*\n * Because we use an overloaded API endpoint (ie, one that's shared with the FileDump module), we must\n * also provide a list of commands which, when combined with the endpoint, define a unique request.\n */\nDumpAPI.asDiskCommands = [DumpAPI.QUERY.DIR, DumpAPI.QUERY.DISK, DumpAPI.QUERY.PATH];\nDumpAPI.asFileCommands = [DumpAPI.QUERY.FILE];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/reportapi.js (C) Jeff Parsons 2012-2018\n */\n\nvar ReportAPI = {\n ENDPOINT: \"/api/v1/report\",\n QUERY: {\n APP: \"app\",\n VER: \"ver\",\n URL: \"url\",\n USER: \"user\",\n TYPE: \"type\",\n DATA: \"data\"\n },\n TYPE: {\n BUG: \"bug\"\n },\n RES: {\n OK: \"Thank you\"\n }\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/userapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Examples of User API requests:\n *\n * web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.VERIFY + '&' + UserAPI.QUERY.USER + '=' + sUser;\n */\nvar UserAPI = {\n ENDPOINT: \"/api/v1/user\",\n QUERY: {\n REQ: \"req\", // specifies a request\n USER: \"user\", // specifies a user ID\n STATE: \"state\", // specifies a state ID\n DATA: \"data\" // specifies state data\n },\n REQ: {\n CREATE: \"create\", // creates a user ID\n VERIFY: \"verify\", // requests verification of a user ID\n STORE: \"store\", // stores a machine state on the server\n LOAD: \"load\" // loads a machine state from the server\n },\n RES: {\n CODE: \"code\",\n DATA: \"data\"\n },\n CODE: {\n OK: \"ok\",\n FAIL: \"error\"\n },\n FAIL: {\n DUPLICATE: \"user already exists\",\n VERIFY: \"unable to verify user\",\n BADSTATE: \"invalid state parameter\",\n NOSTATE: \"no machine state\",\n BADLOAD: \"unable to load machine state\",\n BADSTORE: \"unable to save machine state\"\n }\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/keys.js (C) Jeff Parsons 2012-2018\n */\n\nvar Keys = {\n /*\n * Keys and/or key combinations that generate common ASCII codes.\n *\n * NOTE: If you're looking for a general-purpose ASCII code table, see Str.ASCII in strlib.js;\n * if something's missing, that's probably the more appropriate table to add it to.\n *\n * TODO: The Closure Compiler doesn't inline all references to these values, at least those with\n * quoted property names, which is why I've 'unquoted' as many of them as possible. One solution\n * would be to add mnemonics for all of them, not just the non-printable ones (eg, SPACE instead\n * of ' ', AMP instead of '&', etc.)\n */\n ASCII: {\n BREAK: 0, CTRL_A: 1, CTRL_B: 2, CTRL_C: 3, CTRL_D: 4, CTRL_E: 5, CTRL_F: 6, CTRL_G: 7,\n CTRL_H: 8, CTRL_I: 9, CTRL_J: 10, CTRL_K: 11, CTRL_L: 12, CTRL_M: 13, CTRL_N: 14, CTRL_O: 15,\n CTRL_P: 16, CTRL_Q: 17, CTRL_R: 18, CTRL_S: 19, CTRL_T: 20, CTRL_U: 21, CTRL_V: 22, CTRL_W: 23,\n CTRL_X: 24, CTRL_Y: 25, CTRL_Z: 26, ESC: 27,\n ' ': 32, '!': 33, '\"': 34, '#': 35, '$': 36, '%': 37, '&': 38, \"'\": 39,\n '(': 40, ')': 41, '*': 42, '+': 43, ',': 44, '-': 45, '.': 46, '/': 47,\n '0': 48, '1': 49, '2': 50, '3': 51, '4': 52, '5': 53, '6': 54, '7': 55,\n '8': 56, '9': 57, ':': 58, ';': 59, '<': 60, '=': 61, '>': 62, '?': 63,\n '@': 64, A: 65, B: 66, C: 67, D: 68, E: 69, F: 70, G: 71,\n H: 72, I: 73, J: 74, K: 75, L: 76, M: 77, N: 78, O: 79,\n P: 80, Q: 81, R: 82, S: 83, T: 84, U: 85, V: 86, W: 87,\n X: 88, Y: 89, Z: 90, '[': 91, '\\\\':92, ']': 93, '^': 94, '_': 95,\n '`': 96, a: 97, b: 98, c: 99, d: 100, e: 101, f: 102, g: 103,\n h: 104, i: 105, j: 106, k: 107, l: 108, m: 109, n: 110, o: 111,\n p: 112, q: 113, r: 114, s: 115, t: 116, u: 117, v: 118, w: 119,\n x: 120, y: 121, z: 122, '{':123, '|':124, '}':125, '~':126, DEL: 127\n },\n /*\n * Browser keyCodes we must pay particular attention to. For the most part, these are non-alphanumeric\n * or function keys, some which may require special treatment (eg, preventDefault() if returning false on\n * the initial keyDown event is insufficient).\n *\n * keyCodes for most common ASCII keys can simply use the appropriate ASCII code above.\n *\n * Most of these represent non-ASCII keys (eg, the LEFT arrow key), yet for some reason, browsers defined\n * them using ASCII codes (eg, the LEFT arrow key uses the ASCII code for '%' or 37).\n */\n KEYCODE: {\n /* 0x08 */ BS: 8, // BACKSPACE (ASCII.CTRL_H)\n /* 0x09 */ TAB: 9, // TAB (ASCII.CTRL_I)\n /* 0x0A */ LF: 10, // LINE-FEED (ASCII.CTRL_J) (Some Windows-based browsers used to generate this via CTRL-ENTER)\n /* 0x0D */ CR: 13, // CARRIAGE RETURN (ASCII.CTRL_M)\n /* 0x10 */ SHIFT: 16,\n /* 0x11 */ CTRL: 17,\n /* 0x12 */ ALT: 18,\n /* 0x13 */ PAUSE: 19, // PAUSE/BREAK\n /* 0x14 */ CAPS_LOCK: 20,\n /* 0x1B */ ESC: 27,\n /* 0x20 */ SPACE: 32,\n /* 0x21 */ PGUP: 33,\n /* 0x22 */ PGDN: 34,\n /* 0x23 */ END: 35,\n /* 0x24 */ HOME: 36,\n /* 0x25 */ LEFT: 37,\n /* 0x26 */ UP: 38,\n /* 0x27 */ RIGHT: 39,\n /* 0x27 */ FF_QUOTE: 39,\n /* 0x28 */ DOWN: 40,\n /* 0x2C */ FF_COMMA: 44,\n /* 0x2C */ PRTSC: 44,\n /* 0x2D */ INS: 45,\n /* 0x2E */ DEL: 46,\n /* 0x2E */ FF_PERIOD: 46,\n /* 0x2F */ FF_SLASH: 47,\n /* 0x30 */ ZERO: 48,\n /* 0x31 */ ONE: 49,\n /* 0x32 */ TWO: 50,\n /* 0x33 */ THREE: 51,\n /* 0x34 */ FOUR: 52,\n /* 0x35 */ FIVE: 53,\n /* 0x36 */ SIX: 54,\n /* 0x37 */ SEVEN: 55,\n /* 0x38 */ EIGHT: 56,\n /* 0x39 */ NINE: 57,\n /* 0x3B */ FF_SEMI: 59,\n /* 0x3D */ FF_EQUALS: 61,\n /* 0x5B */ CMD: 91, // aka WIN\n /* 0x5B */ FF_LBRACK: 91,\n /* 0x5C */ FF_BSLASH: 92,\n /* 0x5D */ RCMD: 93, // aka MENU\n /* 0x5D */ FF_RBRACK: 93,\n /* 0x60 */ NUM_0: 96,\n /* 0x60 */ NUM_INS: 96,\n /* 0x60 */ FF_BQUOTE: 96,\n /* 0x61 */ NUM_1: 97,\n /* 0x61 */ NUM_END: 97,\n /* 0x62 */ NUM_2: 98,\n /* 0x62 */ NUM_DOWN: 98,\n /* 0x63 */ NUM_3: 99,\n /* 0x63 */ NUM_PGDN: 99,\n /* 0x64 */ NUM_4: 100,\n /* 0x64 */ NUM_LEFT: 100,\n /* 0x65 */ NUM_5: 101,\n /* 0x65 */ NUM_CENTER: 101,\n /* 0x66 */ NUM_6: 102,\n /* 0x66 */ NUM_RIGHT: 102,\n /* 0x67 */ NUM_7: 103,\n /* 0x67 */ NUM_HOME: 103,\n /* 0x68 */ NUM_8: 104,\n /* 0x68 */ NUM_UP: 104,\n /* 0x69 */ NUM_9: 105,\n /* 0x69 */ NUM_PGUP: 105,\n /* 0x6A */ NUM_MUL: 106,\n /* 0x6B */ NUM_ADD: 107,\n /* 0x6D */ NUM_SUB: 109,\n /* 0x6E */ NUM_DEL: 110, // aka PERIOD\n /* 0x6F */ NUM_DIV: 111,\n /* 0x70 */ F1: 112,\n /* 0x71 */ F2: 113,\n /* 0x72 */ F3: 114,\n /* 0x73 */ F4: 115,\n /* 0x74 */ F5: 116,\n /* 0x75 */ F6: 117,\n /* 0x76 */ F7: 118,\n /* 0x77 */ F8: 119,\n /* 0x78 */ F9: 120,\n /* 0x79 */ F10: 121,\n /* 0x7A */ F11: 122,\n /* 0x7B */ F12: 123,\n /* 0x90 */ NUM_LOCK: 144,\n /* 0x91 */ SCROLL_LOCK: 145,\n /* 0xAD */ FF_DASH: 173,\n /* 0xBA */ SEMI: 186, // Firefox: 59 (FF_SEMI)\n /* 0xBB */ EQUALS: 187, // Firefox: 61 (FF_EQUALS)\n /* 0xBC */ COMMA: 188,\n /* 0xBD */ DASH: 189, // Firefox: 173 (FF_DASH)\n /* 0xBE */ PERIOD: 190,\n /* 0xBF */ SLASH: 191,\n /* 0xC0 */ BQUOTE: 192,\n /* 0xDB */ LBRACK: 219,\n /* 0xDC */ BSLASH: 220,\n /* 0xDD */ RBRACK: 221,\n /* 0xDE */ QUOTE: 222,\n /* 0xE0 */ FF_CMD: 224, // Firefox only (used for both CMD and RCMD)\n //\n // The following biases use what I'll call Decimal Coded Binary or DCB (the opposite of BCD),\n // where the thousands digit is used to store the sum of \"binary\" digits 1 and/or 2 and/or 4.\n //\n // Technically, that makes it DCO (Decimal Coded Octal), but then again, BCD should have really\n // been called HCD (Hexadecimal Coded Decimal), so if \"they\" can take liberties, so can I.\n //\n // ONDOWN is a bias we add to browser keyCodes that we want to handle on \"down\" rather than on \"press\".\n //\n ONDOWN: 1000,\n //\n // ONRIGHT is a bias we add to browser keyCodes that need to check for a \"right\" location (default is \"left\")\n //\n ONRIGHT: 2000,\n //\n // FAKE is a bias we add to signal these are fake keyCodes corresponding to internal keystroke combinations.\n // The actual values are for internal use only and merely need to be unique and used consistently.\n //\n FAKE: 4000\n },\n /*\n * The set of values that a browser may store in the 'location' property of a keyboard event object\n * which we also support.\n */\n LOCATION: {\n LEFT: 1,\n RIGHT: 2,\n NUMPAD: 3\n }\n};\n\n/*\n * Check the event object's 'location' property for a non-zero value for the following ONRIGHT keys.\n */\nKeys.KEYCODE.NUM_CR = Keys.KEYCODE.CR + Keys.KEYCODE.ONRIGHT;\n\n\n/*\n * Maps Firefox keyCodes to their more common keyCode counterparts; a number of entries in this table\n * are no longer valid (if indeed they ever were), so they've been commented out. It's likely that I\n * simply extended this table to resolve additional differences in other browsers (ie, Opera), but without\n * browser-specific checks, it's not safe to perform all the mappings shown below.\n */\nKeys.FF_KEYCODES = {};\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_SEMI] = Keys.KEYCODE.SEMI; // 59 -> 186\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_EQUALS] = Keys.KEYCODE.EQUALS; // 61 -> 187\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.KEYCODE.DASH; // 173 -> 189\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_CMD] = Keys.KEYCODE.CMD; // 224 -> 91\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_COMMA] = Keys.KEYCODE.COMMA; // 44 -> 188\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_PERIOD] = Keys.KEYCODE.PERIOD; // 46 -> 190\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_SLASH] = Keys.KEYCODE.SLASH; // 47 -> 191\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_BQUOTE] = Keys.KEYCODE.BQUOTE; // 96 -> 192\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_LBRACK = Keys.KEYCODE.LBRACK; // 91 -> 219\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_BSLASH] = Keys.KEYCODE.BSLASH; // 92 -> 220\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_RBRACK] = Keys.KEYCODE.RBRACK; // 93 -> 221\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_QUOTE] = Keys.KEYCODE.QUOTE; // 39 -> 222\n\n/*\n * Maps non-ASCII keyCodes to their ASCII counterparts\n */\nKeys.NONASCII_KEYCODES = {};\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.ASCII['-']; // 173 -> 45\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.SEMI] = Keys.ASCII[';']; // 186 -> 59\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.EQUALS] = Keys.ASCII['=']; // 187 -> 61\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.DASH] = Keys.ASCII['-']; // 189 -> 45\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.COMMA] = Keys.ASCII[',']; // 188 -> 44\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.PERIOD] = Keys.ASCII['.']; // 190 -> 46\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.SLASH] = Keys.ASCII['/']; // 191 -> 47\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.BQUOTE] = Keys.ASCII['`']; // 192 -> 96\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.LBRACK] = Keys.ASCII['[']; // 219 -> 91\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.BSLASH] = Keys.ASCII['\\\\']; // 220 -> 92\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.RBRACK] = Keys.ASCII[']']; // 221 -> 93\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.QUOTE] = Keys.ASCII[\"'\"]; // 222 -> 39\n\n/*\n * Maps unshifted keyCodes to their shifted counterparts; to be used when a shift-key is down.\n * Alphabetic characters are handled in code, since they must also take CAPS_LOCK into consideration.\n */\nKeys.SHIFTED_KEYCODES = {};\nKeys.SHIFTED_KEYCODES[Keys.ASCII['1']] = Keys.ASCII['!'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['2']] = Keys.ASCII['@'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['3']] = Keys.ASCII['#'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['4']] = Keys.ASCII['$'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['5']] = Keys.ASCII['%'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['6']] = Keys.ASCII['^'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['7']] = Keys.ASCII['&'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['8']] = Keys.ASCII['*'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['9']] = Keys.ASCII['('];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['0']] = Keys.ASCII[')'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.SEMI] = Keys.ASCII[':'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.EQUALS] = Keys.ASCII['+'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.COMMA] = Keys.ASCII['<'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.DASH] = Keys.ASCII['_'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.PERIOD] = Keys.ASCII['>'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.SLASH] = Keys.ASCII['?'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.BQUOTE] = Keys.ASCII['~'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.LBRACK] = Keys.ASCII['{'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.BSLASH] = Keys.ASCII['|'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.RBRACK] = Keys.ASCII['}'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.QUOTE] = Keys.ASCII['\"'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.ASCII['_'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_EQUALS] = Keys.ASCII['+'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_SEMI] = Keys.ASCII[':'];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/strlib.js (C) Jeff Parsons 2012-2018\n */\n\nclass Str {\n /**\n * isValidInt(s, base)\n *\n * The built-in parseInt() function has the annoying feature of returning a partial value (ie,\n * up to the point where it encounters an invalid character); eg, parseInt(\"foo\", 16) returns 0xf.\n *\n * So it's best to use our own Str.parseInt() function, which will in turn use this function to\n * validate the entire string.\n *\n * @param {string} s is the string representation of some number\n * @param {number} [base] is the radix to use (default is 10); only 2, 8, 10 and 16 are supported\n * @return {boolean} true if valid, false if invalid (or the specified base isn't supported)\n */\n static isValidInt(s, base)\n {\n if (!base || base == 10) return s.match(/^-?[0-9]+$/) !== null;\n if (base == 16) return s.match(/^-?[0-9a-f]+$/i) !== null;\n if (base == 8) return s.match(/^-?[0-7]+$/) !== null;\n if (base == 2) return s.match(/^-?[01]+$/) !== null;\n return false;\n }\n\n /**\n * parseInt(s, base)\n *\n * This is a wrapper around the built-in parseInt() function. Our wrapper recognizes certain prefixes\n * ('$' or \"0x\" for hex, '#' or \"0o\" for octal) and suffixes ('.' for decimal, 'h' for hex, 'y' for\n * binary), and then calls isValidInt() to ensure we don't convert strings that contain partial values;\n * see isValidInt() for details.\n *\n * The use of multiple prefix/suffix combinations is undefined (although for the record, we process\n * prefixes first). We do NOT support the \"0b\" prefix to indicate binary UNLESS one or more commas are\n * also present (because \"0b\" is also a valid hex sequence), and we do NOT support a single leading zero\n * to indicate octal (because such a number could also be decimal or hex). Any number of commas are\n * allowed; we remove them all before calling the built-in parseInt().\n *\n * More recently, we've added support for \"^D\", \"^O\", and \"^B\" prefixes to accommodate the base overrides\n * that the PDP-10's MACRO-10 assembly language supports (decimal, octal, and binary, respectively).\n * If this support turns out to adversely affect other debuggers, then it will have to be \"conditionalized\".\n * Similarly, we've added support for \"K\", \"M\", and \"G\" MACRO-10-style suffixes that add 3, 6, or 9 zeros\n * to the value to be parsed, respectively.\n *\n * @param {string} s is the string representation of some number\n * @param {number} [base] is the radix to use (default is 10); can be overridden by prefixes/suffixes\n * @return {number|undefined} corresponding value, or undefined if invalid\n */\n static parseInt(s, base)\n {\n var value;\n\n if (s) {\n if (!base) base = 10;\n\n var ch, chPrefix, chSuffix;\n var fCommas = (s.indexOf(',') > 0);\n if (fCommas) s = s.replace(/,/g, '');\n\n ch = chPrefix = s.charAt(0);\n if (chPrefix == '#') {\n base = 8;\n chPrefix = '';\n }\n else if (chPrefix == '$') {\n base = 16;\n chPrefix = '';\n }\n if (ch != chPrefix) {\n s = s.substr(1);\n }\n else {\n ch = chPrefix = s.substr(0, 2);\n if (chPrefix == '0b' && fCommas || chPrefix == '^B') {\n base = 2;\n chPrefix = '';\n }\n else if (chPrefix == '0o' || chPrefix == '^O') {\n base = 8;\n chPrefix = '';\n }\n else if (chPrefix == '^D') {\n base = 10;\n chPrefix = '';\n }\n else if (chPrefix == '0x') {\n base = 16;\n chPrefix = '';\n }\n if (ch != chPrefix) s = s.substr(2);\n }\n ch = chSuffix = s.slice(-1);\n if (chSuffix == 'Y' || chSuffix == 'y') {\n base = 2;\n chSuffix = '';\n }\n else if (chSuffix == '.') {\n base = 10;\n chSuffix = '';\n }\n else if (chSuffix == 'H' || chSuffix == 'h') {\n base = 16;\n chSuffix = '';\n }\n else if (chSuffix == 'K') {\n chSuffix = '000';\n }\n else if (chSuffix == 'M') {\n chSuffix = '000000';\n }\n else if (chSuffix == 'G') {\n chSuffix = '000000000';\n }\n if (ch != chSuffix) s = s.slice(0, -1) + chSuffix;\n /*\n * This adds support for the MACRO-10 binary shifting (Bn) suffix, which must be stripped from the\n * number before parsing, and then applied to the value after parsing. If n is omitted, 35 is assumed,\n * which is a net shift of zero. If n < 35, then a left shift of (35 - n) is required; if n > 35, then\n * a right shift of -(35 - n) is required.\n */\n var v, shift = 0;\n if (base <= 10) {\n var match = s.match(/(-?[0-9]+)B([0-9]*)/);\n if (match) {\n s = match[1];\n shift = 35 - ((match[2] || 35) & 0xff);\n }\n }\n if (Str.isValidInt(s, base) && !isNaN(v = parseInt(s, base))) {\n /*\n * With the need to support larger (eg, 36-bit) integers, truncating to 32 bits is no longer helpful.\n *\n * value = v|0;\n */\n if (shift) {\n /*\n * Since binary shifting is a logical operation, and since shifting by division only works properly\n * with positive numbers, we must convert a negative value to a positive value, by computing the two's\n * complement.\n */\n if (v < 0) v += Math.pow(2, 36);\n if (shift > 0) {\n v *= Math.pow(2, shift);\n } else {\n v = Math.trunc(v / Math.pow(2, -shift));\n }\n }\n value = v;\n }\n }\n return value;\n }\n\n /**\n * toBase(n, radix, cch, sPrefix, nGrouping)\n *\n * Displays the given number as an unsigned integer using the specified radix and number of digits.\n *\n * @param {number|null|undefined} n\n * @param {number} radix (ie, the base)\n * @param {number} cch (the desired number of digits)\n * @param {string} [sPrefix] (default is none)\n * @param {number} [nGrouping]\n * @return {string}\n */\n static toBase(n, radix, cch, sPrefix = \"\", nGrouping = 0)\n {\n /*\n * An initial \"falsey\" check for null takes care of both null and undefined;\n * we can't rely entirely on isNaN(), because isNaN(null) returns false, oddly enough.\n *\n * Alternatively, we could mask and shift n regardless of whether it's null/undefined/NaN,\n * since JavaScript coerces such operands to zero, but I think there's \"value\" in seeing those\n * values displayed differently.\n */\n var s = \"\";\n if (isNaN(n)) {\n n = null;\n } else if (n != null) {\n /*\n * Callers that produced an input by dividing by a power of two rather than shifting (in order\n * to access more than 32 bits) may produce a fractional result, which ordinarily we would simply\n * ignore, but if the integer portion is zero and the sign is negative, we should probably treat\n * this value as a sign-extension.\n */\n if (n < 0 && n > -1) n = -1;\n /*\n * Negative values should be two's complemented according to the number of digits; for example,\n * 12 octal digits implies an upper limit 8^12.\n */\n if (n < 0) {\n n += Math.pow(radix, cch);\n }\n if (n >= Math.pow(radix, cch)) {\n cch = Math.ceil(Math.log(n) / Math.log(radix));\n }\n }\n var g = nGrouping || -1;\n while (cch-- > 0) {\n if (!g) {\n s = ',' + s;\n g = nGrouping;\n }\n if (n == null) {\n s = '?' + s;\n } else {\n var d = n % radix;\n d += (d >= 0 && d <= 9? 0x30 : 0x41 - 10);\n s = String.fromCharCode(d) + s;\n n = Math.trunc(n / radix);\n }\n g--;\n }\n return sPrefix + s;\n }\n\n /**\n * toBin(n, cch, nGrouping)\n *\n * Converts an integer to binary, with the specified number of digits (up to a maximum of 36).\n *\n * @param {number|null|undefined} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of binary digits (0 or undefined for default of either 8, 18, or 36)\n * @param {number} [nGrouping]\n * @return {string} the binary representation of n\n */\n static toBin(n, cch, nGrouping)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.LN2) || 1;\n var v = Math.abs(n);\n if (v <= 0b11111111) {\n cch = 8;\n } else if (v <= 0b111111111111111111) {\n cch = 18;\n } else {\n cch = 36;\n }\n } else if (cch > 36) cch = 36;\n return Str.toBase(n, 2, cch, \"\", nGrouping);\n }\n\n /**\n * toBinBytes(n, cb, fPrefix)\n *\n * Converts an integer to binary, with the specified number of bytes (up to the default of 4).\n *\n * @param {number|null|undefined} n (interpreted as a 32-bit value)\n * @param {number} [cb] is the desired number of binary bytes (4 is both the default and the maximum)\n * @param {boolean} [fPrefix]\n * @return {string} the binary representation of n\n */\n static toBinBytes(n, cb, fPrefix)\n {\n var s = \"\";\n if (!cb || cb > 4) cb = 4;\n for (var i = 0; i < cb; i++) {\n if (s) s = ',' + s;\n s = Str.toBin(n & 0xff, 8) + s;\n n >>= 8;\n }\n return (fPrefix? \"0b\" : \"\") + s;\n }\n\n /**\n * toOct(n, cch, fPrefix)\n *\n * Converts an integer to octal, with the specified number of digits (default of 6; max of 12)\n *\n * You might be tempted to use the built-in n.toString(8) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw\n * an exception, whereas this function will return '?' characters.\n *\n * @param {number|null|undefined} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of octal digits (0 or undefined for default of either 6, 8, or 12)\n * @param {boolean} [fPrefix]\n * @return {string} the octal representation of n\n */\n static toOct(n, cch, fPrefix)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.log(8)) || 1;\n var v = Math.abs(n);\n if (v <= 0o777777) {\n cch = 6;\n } else if (v <= 0o77777777) {\n cch = 8;\n } else {\n cch = 12;\n }\n } else if (cch > 12) cch = 12;\n return Str.toBase(n, 8, cch, fPrefix? \"0o\" : \"\");\n }\n\n /**\n * toDec(n, cch)\n *\n * Converts an integer to decimal, with the specified number of digits (default of 5; max of 11)\n *\n * You might be tempted to use the built-in n.toString(10) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw\n * an exception, whereas this function will return '?' characters.\n *\n * @param {number|null|undefined} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of decimal digits (0 or undefined for default of either 5 or 11)\n * @return {string} the decimal representation of n\n */\n static toDec(n, cch)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.LN10) || 1;\n var v = Math.abs(n);\n if (v <= 99999) {\n cch = 5;\n } else {\n cch = 11;\n }\n } else if (cch > 11) cch = 11;\n return Str.toBase(n, 10, cch);\n }\n\n /**\n * toHex(n, cch, fPrefix)\n *\n * Converts an integer to hex, with the specified number of digits (default of 4 or 8, max of 9).\n *\n * You might be tempted to use the built-in n.toString(16) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values; for example, if n is -2147483647, then n.toString(16)\n * will return \"-7fffffff\" instead of \"80000001\". Moreover, if n is undefined, n.toString() will\n * throw an exception, whereas this function will return '?' characters.\n *\n * NOTE: The following work-around (adapted from code found on StackOverflow) would be another solution,\n * taking care of negative values, zero-padding, and upper-casing, but not null/undefined/NaN values:\n *\n * s = (n < 0? n + 0x100000000 : n).toString(16);\n * s = \"00000000\".substr(0, 8 - s.length) + s;\n * s = s.substr(0, cch).toUpperCase();\n *\n * @param {number|null|undefined} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of hex digits (0 or undefined for default of either 4, 8, or 9)\n * @param {boolean} [fPrefix]\n * @return {string} the hex representation of n\n */\n static toHex(n, cch, fPrefix)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.log(16)) || 1;\n var v = Math.abs(n);\n if (v <= 0xffff) {\n cch = 4;\n } else if (v <= 0xffffffff) {\n cch = 8;\n } else {\n cch = 9;\n }\n } else if (cch > 9) cch = 9;\n return Str.toBase(n, 16, cch, fPrefix? \"0x\" : \"\");\n }\n\n /**\n * toHexByte(b)\n *\n * Alias for Str.toHex(b, 2, true)\n *\n * @param {number|null|undefined} b is a byte value\n * @return {string} the hex representation of b\n */\n static toHexByte(b)\n {\n return Str.toHex(b, 2, true);\n }\n\n /**\n * toHexWord(w)\n *\n * Alias for Str.toHex(w, 4, true)\n *\n * @param {number|null|undefined} w is a word (16-bit) value\n * @return {string} the hex representation of w\n */\n static toHexWord(w)\n {\n return Str.toHex(w, 4, true);\n }\n\n /**\n * toHexLong(l)\n *\n * Alias for Str.toHex(l, 8, true)\n *\n * @param {number|null|undefined} l is a dword (32-bit) value\n * @return {string} the hex representation of w\n */\n static toHexLong(l)\n {\n return Str.toHex(l, 8, true);\n }\n\n /**\n * getBaseName(sFileName, fStripExt)\n *\n * This is a poor-man's version of Node's path.basename(), which Node-only components should use instead.\n *\n * Note that if fStripExt is true, this strips ANY extension, whereas path.basename() strips the extension only\n * if it matches the second parameter (eg, path.basename(\"/foo/bar/baz/asdf/quux.html\", \".html\") returns \"quux\").\n *\n * @param {string} sFileName\n * @param {boolean} [fStripExt]\n * @return {string}\n */\n static getBaseName(sFileName, fStripExt)\n {\n var sBaseName = sFileName;\n\n var i = sFileName.lastIndexOf('/');\n if (i >= 0) sBaseName = sFileName.substr(i + 1);\n\n /*\n * This next bit is a kludge to clean up names that are part of a URL that includes unsightly query parameters.\n */\n i = sBaseName.indexOf('&');\n if (i > 0) sBaseName = sBaseName.substr(0, i);\n\n if (fStripExt) {\n i = sBaseName.lastIndexOf(\".\");\n if (i > 0) {\n sBaseName = sBaseName.substring(0, i);\n }\n }\n return sBaseName;\n }\n\n /**\n * getExtension(sFileName)\n *\n * This is a poor-man's version of Node's path.extname(), which Node-only components should use instead.\n *\n * Note that we EXCLUDE the period from the returned extension, whereas path.extname() includes it.\n *\n * @param {string} sFileName\n * @return {string} the filename's extension (in lower-case and EXCLUDING the \".\"), or an empty string\n */\n static getExtension(sFileName)\n {\n var sExtension = \"\";\n var i = sFileName.lastIndexOf(\".\");\n if (i >= 0) {\n sExtension = sFileName.substr(i + 1).toLowerCase();\n }\n return sExtension;\n }\n\n /**\n * endsWith(s, sSuffix)\n *\n * @param {string} s\n * @param {string} sSuffix\n * @return {boolean} true if s ends with sSuffix, false if not\n */\n static endsWith(s, sSuffix)\n {\n return s.indexOf(sSuffix, s.length - sSuffix.length) !== -1;\n }\n\n /**\n * escapeHTML(sHTML)\n *\n * @param {string} sHTML\n * @return {string} with HTML entities \"escaped\", similar to PHP's htmlspecialchars()\n */\n static escapeHTML(sHTML)\n {\n return sHTML.replace(/[&<>\"']/g, function(m)\n {\n return Str.HTMLEscapeMap[m];\n });\n }\n\n /**\n * replace(sSearch, sReplace, s)\n *\n * The JavaScript replace() function ALWAYS interprets \"$\" specially in replacement strings, even when\n * the search string is NOT a RegExp; specifically:\n *\n * $$ Inserts a \"$\"\n * $& Inserts the matched substring\n * $` Inserts the portion of the string that precedes the matched substring\n * $' Inserts the portion of the string that follows the matched substring\n * $n Where n is a positive integer less than 100, inserts the nth parenthesized sub-match string,\n * provided the first argument was a RegExp object\n *\n * So, if a replacement string containing dollar signs passes through a series of replace() calls, untold\n * problems could result. Hence, this function, which simply uses the replacement string as-is.\n *\n * Similar to the JavaScript replace() method (when sSearch is a string), this replaces only ONE occurrence\n * (ie, the FIRST occurrence); it might be nice to add options to replace the LAST occurrence and/or ALL\n * occurrences, but we'll revisit that later.\n *\n * @param {string} sSearch\n * @param {string} sReplace\n * @param {string} s\n * @return {string}\n */\n static replace(sSearch, sReplace, s)\n {\n var i = s.indexOf(sSearch);\n if (i >= 0) {\n s = s.substr(0, i) + sReplace + s.substr(i + sSearch.length);\n }\n return s;\n }\n\n /**\n * replaceAll(sSearch, sReplace, s)\n *\n * @param {string} sSearch\n * @param {string} sReplace\n * @param {string} s\n * @return {string}\n */\n static replaceAll(sSearch, sReplace, s)\n {\n var a = {};\n a[sSearch] = sReplace;\n return Str.replaceArray(a, s);\n }\n\n /**\n * replaceArray(a, s)\n *\n * @param {Object} a\n * @param {string} s\n * @return {string}\n */\n static replaceArray(a, s)\n {\n var sMatch = \"\";\n for (var k in a) {\n /*\n * As noted in:\n *\n * http://www.regexguru.com/2008/04/escape-characters-only-when-necessary/\n *\n * inside character classes, only backslash, caret, hyphen and the closing bracket need to be\n * escaped. And in fact, if you ensure that the closing bracket is first, the caret is not first,\n * and the hyphen is last, you can avoid escaping those as well.\n */\n k = k.replace(/([\\\\[\\]*{}().+?|$])/g, \"\\\\$1\");\n sMatch += (sMatch? '|' : '') + k;\n }\n return s.replace(new RegExp('(' + sMatch + ')', \"g\"), function(m)\n {\n return a[m];\n });\n }\n\n /**\n * pad(s, cch, fPadLeft)\n *\n * NOTE: the maximum amount of padding currently supported is 40 spaces.\n *\n * @param {string} s is a string\n * @param {number} cch is desired length\n * @param {boolean} [fPadLeft] (default is padding on the right)\n * @return {string} the original string (s) with spaces padding it to the specified length\n */\n static pad(s, cch, fPadLeft)\n {\n var sPadding = \" \";\n return fPadLeft? (sPadding + s).slice(-cch) : (s + sPadding).slice(0, cch);\n }\n\n /**\n * sprintf(format, ...args)\n *\n * Copied from the CCjs project (https://github.com/jeffpar/ccjs/blob/master/lib/stdio.js) and extended.\n *\n * Far from complete, let alone sprintf-compatible, but it's adequate for the handful of sprintf-style format\n * specifiers that I use.\n *\n * @param {string} format\n * @param {...} args\n * @return {string}\n */\n static sprintf(format, ...args)\n {\n let buffer = \"\";\n let aParts = format.split(/%([-+ 0#]?)([0-9]*)(\\.?)([0-9]*)([hlL]?)([A-Za-z%])/);\n\n let iArg = 0, iPart;\n for (iPart = 0; iPart < aParts.length - 7; iPart += 7) {\n\n buffer += aParts[iPart];\n\n let arg = args[iArg++];\n let flags = aParts[iPart+1];\n let minimum = +aParts[iPart+2] || 0;\n let precision = +aParts[iPart+4] || 0;\n let conversion = aParts[iPart+6];\n let ach = null, s;\n\n switch(conversion) {\n case 'd':\n /*\n * We could use \"arg |= 0\", but there may be some value to supporting integers > 32 bits.\n * \n * Also, unlike the 'X' and 'x' hexadecimal cases, there's no need to explicitly check for a string\n * arguments, because the call to trunc() automatically coerces any string value to a (decimal) number.\n */\n arg = Math.trunc(arg);\n /* falls through */\n\n case 'f':\n s = Math.trunc(arg) + \"\";\n if (precision) {\n minimum -= (precision + 1);\n }\n if (s.length < minimum) {\n if (flags == '0') {\n if (arg < 0) minimum--;\n s = (\"0000000000\" + Math.abs(arg)).slice(-minimum);\n if (arg < 0) s = '-' + s;\n } else {\n s = (\" \" + s).slice(-minimum);\n }\n }\n if (precision) {\n arg = Math.round((arg - Math.trunc(arg)) * Math.pow(10, precision));\n s += '.' + (\"0000000000\" + Math.abs(arg)).slice(-precision);\n }\n buffer += s;\n break;\n\n case 'c':\n arg = String.fromCharCode(arg);\n /* falls through */\n\n case 's':\n if (typeof arg == \"string\") {\n while (arg.length < minimum) {\n if (flags == '-') {\n arg += ' ';\n } else {\n arg = ' ' + arg;\n }\n }\n }\n buffer += arg;\n break;\n\n case 'X':\n ach = Str.HexUpperCase;\n /* falls through */\n\n case 'x':\n if (!ach) ach = Str.HexLowerCase;\n s = \"\";\n if (typeof arg == \"string\") {\n /*\n * Since we're advised to ALWAYS pass a radix to parseInt(), we must detect explicitly\n * hex values ourselves, because using a radix of 10 with any \"0x...\" value always returns 0.\n * \n * And if the value CAN be interpreted as decimal, then we MUST interpret it as decimal, because\n * we have sprintf() calls in /modules/lib/testmon.js that depend on this code to perform decimal\n * to hex conversion. We're allowed to make our own rules here, since passing numbers in string\n * form isn't part of the sprintf \"spec\". \n */\n arg = Number.parseInt(arg, arg.match(/(^0x|[a-f])/i)? 16 : 10);\n } \n do {\n s = ach[arg & 0xf] + s;\n arg >>>= 4;\n } while (--minimum > 0 || arg);\n buffer += s;\n break;\n\n default:\n /*\n * The supported ANSI C set of conversions: \"dioxXucsfeEgGpn%\"\n */\n buffer += \"(unrecognized printf conversion %\" + conversion + \")\";\n break;\n }\n }\n\n buffer += aParts[iPart];\n return buffer;\n }\n\n /**\n * stripLeadingZeros(s, fPad)\n *\n * @param {string} s\n * @param {boolean} [fPad]\n * @return {string}\n */\n static stripLeadingZeros(s, fPad)\n {\n var cch = s.length;\n s = s.replace(/^0+([0-9A-F]+)$/i, \"$1\");\n if (fPad) s = Str.pad(s, cch, true);\n return s;\n }\n\n /**\n * trim(s)\n *\n * @param {string} s\n * @return {string}\n */\n static trim(s)\n {\n if (String.prototype.trim) {\n return s.trim();\n }\n return s.replace(/^\\s+|\\s+$/g, \"\");\n }\n\n /**\n * toASCIICode(b)\n *\n * @param {number} b\n * @return {string}\n */\n static toASCIICode(b)\n {\n var s;\n if (b != Str.ASCII.CR && b != Str.ASCII.LF) {\n s = Str.ASCIICodeMap[b];\n }\n if (s) {\n s = '<' + s + '>';\n } else {\n s = String.fromCharCode(b);\n }\n return s;\n }\n}\n\n/*\n * Map special characters to their HTML escape sequences.\n */\nStr.HTMLEscapeMap = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n};\n\n/*\n * Map \"unprintable\" ASCII codes to mnemonics, to more clearly see what's being printed.\n */\nStr.ASCIICodeMap = {\n 0x00: \"NUL\",\n 0x01: \"SOH\", // (CTRL_A) Start of Heading\n 0x02: \"STX\", // (CTRL_B) Start of Text\n 0x03: \"ETX\", // (CTRL_C) End of Text\n 0x04: \"EOT\", // (CTRL_D) End of Transmission\n 0x05: \"ENQ\", // (CTRL_E) Enquiry\n 0x06: \"ACK\", // (CTRL_F) Acknowledge\n 0x07: \"BEL\", // (CTRL_G) Bell\n 0x08: \"BS\", // (CTRL_H) Backspace\n 0x09: \"TAB\", // (CTRL_I) Horizontal Tab (aka HT)\n 0x0A: \"LF\", // (CTRL_J) Line Feed (New Line)\n 0x0B: \"VT\", // (CTRL_K) Vertical Tab\n 0x0C: \"FF\", // (CTRL_L) Form Feed (New Page)\n 0x0D: \"CR\", // (CTRL_M) Carriage Return\n 0x0E: \"SO\", // (CTRL_N) Shift Out\n 0x0F: \"SI\", // (CTRL_O) Shift In\n 0x10: \"DLE\", // (CTRL_P) Data Link Escape\n 0x11: \"XON\", // (CTRL_Q) Device Control 1 (aka DC1)\n 0x12: \"DC2\", // (CTRL_R) Device Control 2\n 0x13: \"XOFF\", // (CTRL_S) Device Control 3 (aka DC3)\n 0x14: \"DC4\", // (CTRL_T) Device Control 4\n 0x15: \"NAK\", // (CTRL_U) Negative Acknowledge\n 0x16: \"SYN\", // (CTRL_V) Synchronous Idle\n 0x17: \"ETB\", // (CTRL_W) End of Transmission Block\n 0x18: \"CAN\", // (CTRL_X) Cancel\n 0x19: \"EM\", // (CTRL_Y) End of Medium\n 0x1A: \"SUB\", // (CTRL_Z) Substitute\n 0x1B: \"ESC\", // Escape\n 0x1C: \"FS\", // File Separator\n 0x1D: \"GS\", // Group Separator\n 0x1E: \"RS\", // Record Separator\n 0x1F: \"US\", // Unit Separator\n 0x7F: \"DEL\"\n};\n\n/*\n * Refer to: https://en.wikipedia.org/wiki/Code_page_437\n */\nStr.CP437ToUnicode = [\n '\\u0000', '\\u263A', '\\u263B', '\\u2665', '\\u2666', '\\u2663', '\\u2660', '\\u2022',\n '\\u25D8', '\\u25CB', '\\u25D9', '\\u2642', '\\u2640', '\\u266A', '\\u266B', '\\u263C',\n '\\u25BA', '\\u25C4', '\\u2195', '\\u203C', '\\u00B6', '\\u00A7', '\\u25AC', '\\u21A8',\n '\\u2191', '\\u2193', '\\u2192', '\\u2190', '\\u221F', '\\u2194', '\\u25B2', '\\u25BC',\n '\\u0020', '\\u0021', '\\u0022', '\\u0023', '\\u0024', '\\u0025', '\\u0026', '\\u0027',\n '\\u0028', '\\u0029', '\\u002A', '\\u002B', '\\u002C', '\\u002D', '\\u002E', '\\u002F',\n '\\u0030', '\\u0031', '\\u0032', '\\u0033', '\\u0034', '\\u0035', '\\u0036', '\\u0037',\n '\\u0038', '\\u0039', '\\u003A', '\\u003B', '\\u003C', '\\u003D', '\\u003E', '\\u003F',\n '\\u0040', '\\u0041', '\\u0042', '\\u0043', '\\u0044', '\\u0045', '\\u0046', '\\u0047',\n '\\u0048', '\\u0049', '\\u004A', '\\u004B', '\\u004C', '\\u004D', '\\u004E', '\\u004F',\n '\\u0050', '\\u0051', '\\u0052', '\\u0053', '\\u0054', '\\u0055', '\\u0056', '\\u0057',\n '\\u0058', '\\u0059', '\\u005A', '\\u005B', '\\u005C', '\\u005D', '\\u005E', '\\u005F',\n '\\u0060', '\\u0061', '\\u0062', '\\u0063', '\\u0064', '\\u0065', '\\u0066', '\\u0067',\n '\\u0068', '\\u0069', '\\u006A', '\\u006B', '\\u006C', '\\u006D', '\\u006E', '\\u006F',\n '\\u0070', '\\u0071', '\\u0072', '\\u0073', '\\u0074', '\\u0075', '\\u0076', '\\u0077',\n '\\u0078', '\\u0079', '\\u007A', '\\u007B', '\\u007C', '\\u007D', '\\u007E', '\\u2302',\n '\\u00C7', '\\u00FC', '\\u00E9', '\\u00E2', '\\u00E4', '\\u00E0', '\\u00E5', '\\u00E7',\n '\\u00EA', '\\u00EB', '\\u00E8', '\\u00EF', '\\u00EE', '\\u00EC', '\\u00C4', '\\u00C5',\n '\\u00C9', '\\u00E6', '\\u00C6', '\\u00F4', '\\u00F6', '\\u00F2', '\\u00FB', '\\u00F9',\n '\\u00FF', '\\u00D6', '\\u00DC', '\\u00A2', '\\u00A3', '\\u00A5', '\\u20A7', '\\u0192',\n '\\u00E1', '\\u00ED', '\\u00F3', '\\u00FA', '\\u00F1', '\\u00D1', '\\u00AA', '\\u00BA',\n '\\u00BF', '\\u2310', '\\u00AC', '\\u00BD', '\\u00BC', '\\u00A1', '\\u00AB', '\\u00BB',\n '\\u2591', '\\u2592', '\\u2593', '\\u2502', '\\u2524', '\\u2561', '\\u2562', '\\u2556',\n '\\u2555', '\\u2563', '\\u2551', '\\u2557', '\\u255D', '\\u255C', '\\u255B', '\\u2510',\n '\\u2514', '\\u2534', '\\u252C', '\\u251C', '\\u2500', '\\u253C', '\\u255E', '\\u255F',\n '\\u255A', '\\u2554', '\\u2569', '\\u2566', '\\u2560', '\\u2550', '\\u256C', '\\u2567',\n '\\u2568', '\\u2564', '\\u2565', '\\u2559', '\\u2558', '\\u2552', '\\u2553', '\\u256B',\n '\\u256A', '\\u2518', '\\u250C', '\\u2588', '\\u2584', '\\u258C', '\\u2590', '\\u2580',\n '\\u03B1', '\\u00DF', '\\u0393', '\\u03C0', '\\u03A3', '\\u03C3', '\\u00B5', '\\u03C4',\n '\\u03A6', '\\u0398', '\\u03A9', '\\u03B4', '\\u221E', '\\u03C6', '\\u03B5', '\\u2229',\n '\\u2261', '\\u00B1', '\\u2265', '\\u2264', '\\u2320', '\\u2321', '\\u00F7', '\\u2248',\n '\\u00B0', '\\u2219', '\\u00B7', '\\u221A', '\\u207F', '\\u00B2', '\\u25A0', '\\u00A0'\n];\n\n/*\n * TODO: Future home of a complete ASCII table.\n */\nStr.ASCII = {\n LF: 0x0A,\n CR: 0x0D\n};\n\nStr.TYPES = {\n NULL: 0,\n BYTE: 1,\n WORD: 2,\n DWORD: 3,\n NUMBER: 4,\n STRING: 5,\n BOOLEAN: 6,\n OBJECT: 7,\n ARRAY: 8\n};\n\nStr.HexLowerCase = \"0123456789abcdef\";\nStr.HexUpperCase = \"0123456789ABCDEF\";\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/usrlib.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @typedef {{\n * mask: number,\n * shift: number\n * }}\n */\nvar BitField;\n\n/**\n * @typedef {Object.<BitField>}\n */\nvar BitFields;\n\nclass Usr {\n /**\n * binarySearch(a, v, fnCompare)\n *\n * @param {Array} a is an array\n * @param {number|string|Array|Object} v\n * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]\n * @return {number} the index of matching entry if non-negative, otherwise the index of the insertion point\n */\n static binarySearch(a, v, fnCompare)\n {\n var left = 0;\n var right = a.length;\n var found = 0;\n if (fnCompare === undefined) {\n fnCompare = function(a, b)\n {\n return a > b ? 1 : a < b ? -1 : 0;\n };\n }\n while (left < right) {\n var middle = (left + right) >> 1;\n var compareResult;\n compareResult = fnCompare(v, a[middle]);\n if (compareResult > 0) {\n left = middle + 1;\n } else {\n right = middle;\n found = !compareResult;\n }\n }\n return found ? left : ~left;\n }\n\n /**\n * binaryInsert(a, v, fnCompare)\n *\n * If element v already exists in array a, the array is unchanged (we don't allow duplicates); otherwise, the\n * element is inserted into the array at the appropriate index.\n *\n * @param {Array} a is an array\n * @param {number|string|Array|Object} v is the value to insert\n * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]\n */\n static binaryInsert(a, v, fnCompare)\n {\n var index = Usr.binarySearch(a, v, fnCompare);\n if (index < 0) {\n a.splice(-(index + 1), 0, v);\n }\n }\n\n /**\n * getTimestamp()\n *\n * @return {string} timestamp containing the current date and time (\"yyyy-mm-dd hh:mm:ss\")\n */\n static getTimestamp()\n {\n return Usr.formatDate(\"Y-m-d H:i:s\");\n }\n\n /**\n * getMonthDays(nMonth, nYear)\n *\n * Note that if we're being called on behalf of the RTC, its year is always truncated to two digits (mod 100),\n * so we have no idea what century the year 0 might refer to. When using the normal leap-year formula, 0 fails\n * the mod 100 test but passes the mod 400 test, so as far as the RTC is concerned, every century year is a leap\n * year. Since we're most likely dealing with the year 2000, that's fine, since 2000 was also a leap year.\n *\n * TODO: There IS a separate CMOS byte that's supposed to be set to CMOS_ADDR.CENTURY_DATE; it's always BCD,\n * so theoretically it will contain values like 0x19 or 0x20 (for the 20th and 21st centuries, respectively), and\n * we could add that as another parameter to this function, to improve the accuracy, but that would go beyond what\n * a real RTC actually does.\n *\n * @param {number} nMonth (1-12)\n * @param {number} nYear (normally a 4-digit year, but it may also be mod 100)\n * @return {number} the maximum (1-based) day allowed for the specified month and year\n */\n static getMonthDays(nMonth, nYear)\n {\n var nDays = Usr.aMonthDays[nMonth - 1];\n if (nDays == 28) {\n if ((nYear % 4) === 0 && ((nYear % 100) || (nYear % 400) === 0)) {\n nDays++;\n }\n }\n return nDays;\n }\n\n /**\n * formatDate(sFormat, date)\n *\n * @param {string} sFormat (eg, \"F j, Y\", \"Y-m-d H:i:s\")\n * @param {Date} [date] (default is the current time)\n * @return {string}\n *\n * Supported identifiers in sFormat include:\n *\n * a: lowercase ante meridiem and post meridiem (am or pm)\n * d: day of the month, 2 digits with leading zeros (01,02,...,31)\n * D: 3-letter day of the week (\"Sun\",\"Mon\",...,\"Sat\")\n * F: month (\"January\",\"February\",...,\"December\")\n * g: hour in 12-hour format, without leading zeros (1,2,...,12)\n * h: hour in 24-hour format, without leading zeros (0,1,...,23)\n * H: hour in 24-hour format, with leading zeros (00,01,...,23)\n * i: minutes, with leading zeros (00,01,...,59)\n * j: day of the month, without leading zeros (1,2,...,31)\n * l: day of the week (\"Sunday\",\"Monday\",...,\"Saturday\")\n * m: month, with leading zeros (01,02,...,12)\n * M: 3-letter month (\"Jan\",\"Feb\",...,\"Dec\")\n * n: month, without leading zeros (1,2,...,12)\n * s: seconds, with leading zeros (00,01,...,59)\n * y: 2-digit year (eg, 14)\n * Y: 4-digit year (eg, 2014)\n *\n * For more inspiration, see: http://php.net/manual/en/function.date.php (of which we support ONLY a subset).\n */\n static formatDate(sFormat, date)\n {\n var sDate = \"\";\n if (!date) date = new Date();\n var iHour = date.getHours();\n var iDay = date.getDate();\n var iMonth = date.getMonth() + 1;\n for (var i = 0; i < sFormat.length; i++) {\n var ch;\n switch ((ch = sFormat.charAt(i))) {\n case 'a':\n sDate += (iHour < 12 ? \"am\" : \"pm\");\n break;\n case 'd':\n sDate += ('0' + iDay).slice(-2);\n break;\n case 'D':\n sDate += Usr.asDays[date.getDay()].substr(0, 3);\n break;\n case 'F':\n sDate += Usr.asMonths[iMonth - 1];\n break;\n case 'g':\n sDate += (!iHour ? 12 : (iHour > 12 ? iHour - 12 : iHour));\n break;\n case 'h':\n sDate += iHour;\n break;\n case 'H':\n sDate += ('0' + iHour).slice(-2);\n break;\n case 'i':\n sDate += ('0' + date.getMinutes()).slice(-2);\n break;\n case 'j':\n sDate += iDay;\n break;\n case 'l':\n sDate += Usr.asDays[date.getDay()];\n break;\n case 'm':\n sDate += ('0' + iMonth).slice(-2);\n break;\n case 'M':\n sDate += Usr.asMonths[iMonth - 1].substr(0, 3);\n break;\n case 'n':\n sDate += iMonth;\n break;\n case 's':\n sDate += ('0' + date.getSeconds()).slice(-2);\n break;\n case 'y':\n sDate += (\"\" + date.getFullYear()).slice(-2);\n break;\n case 'Y':\n sDate += date.getFullYear();\n break;\n default:\n sDate += ch;\n break;\n }\n }\n return sDate;\n }\n\n /**\n * defineBitFields(bfs)\n *\n * Prepares a bit field definition for use with getBitField() and setBitField(); eg:\n *\n * var bfs = Usr.defineBitFields({num:20, count:8, btmod:1, type:3});\n *\n * The above defines a set of bit fields containing four fields: num (bits 0-19), count (bits 20-27), btmod (bit 28), and type (bits 29-31).\n *\n * Usr.setBitField(bfs.num, n, 1);\n *\n * The above set bit field \"bfs.num\" in numeric variable \"n\" to the value 1.\n *\n * @param {Object} bfs\n * @return {BitFields}\n */\n static defineBitFields(bfs)\n {\n var bit = 0;\n for (var f in bfs) {\n var width = bfs[f];\n var mask = ((1 << width) - 1) << bit;\n bfs[f] = {mask: mask, shift: bit};\n bit += width;\n }\n return bfs;\n }\n\n /**\n * initBitFields(bfs, ...)\n *\n * @param {BitFields} bfs\n * @param {...number} var_args\n * @return {number} a value containing all supplied bit fields\n */\n static initBitFields(bfs, var_args)\n {\n var v = 0, i = 1;\n for (var f in bfs) {\n if (i >= arguments.length) break;\n v = Usr.setBitField(bfs[f], v, arguments[i++]);\n }\n return v;\n }\n\n /**\n * getBitField(bf, v)\n *\n * @param {BitField} bf\n * @param {number} v is a value containing bit fields\n * @return {number} the value of the bit field in v defined by bf\n */\n static getBitField(bf, v)\n {\n return (v & bf.mask) >> bf.shift;\n }\n\n /**\n * setBitField(bf, v, n)\n *\n * @param {BitField} bf\n * @param {number} v is a value containing bit fields\n * @param {number} n is a value to store in v in the bit field defined by bf\n * @return {number} updated v\n */\n static setBitField(bf, v, n)\n {\n return (v & ~bf.mask) | ((n << bf.shift) & bf.mask);\n }\n\n /**\n * indexOf(a, t, i)\n *\n * Use this instead of Array.prototype.indexOf() if you can't be sure the browser supports it.\n *\n * @param {Array} a\n * @param {*} t\n * @param {number} [i]\n * @returns {number}\n */\n static indexOf(a, t, i)\n {\n if (Array.prototype.indexOf) {\n return a.indexOf(t, i);\n }\n i = i || 0;\n if (i < 0) i += a.length;\n if (i < 0) i = 0;\n for (var n = a.length; i < n; i++) {\n if (i in a && a[i] === t) return i;\n }\n return -1;\n }\n}\n\nUsr.asDays = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\nUsr.asMonths = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\nUsr.aMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\n/**\n * getTime()\n *\n * @return {number} the current time, in milliseconds\n */\nUsr.getTime = Date.now || function() { return +new Date(); };\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/weblib.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * According to http://www.w3schools.com/jsref/jsref_obj_global.asp, these are the *global* properties\n * and functions of JavaScript-in-the-Browser:\n *\n * Property Description\n * ---\n * Infinity A numeric value that represents positive/negative infinity\n * NaN \"Not-a-Number\" value\n * undefined Indicates that a variable has not been assigned a value\n *\n * Function Description\n * ---\n * decodeURI() Decodes a URI\n * decodeURIComponent() Decodes a URI component\n * encodeURI() Encodes a URI\n * encodeURIComponent() Encodes a URI component\n * escape() Deprecated in version 1.5. Use encodeURI() or encodeURIComponent() instead\n * eval() Evaluates a string and executes it as if it was script code\n * isFinite() Determines whether a value is a finite, legal number\n * isNaN() Determines whether a value is an illegal number\n * Number() Converts an object's value to a number\n * parseFloat() Parses a string and returns a floating point number\n * parseInt() Parses a string and returns an integer\n * String() Converts an object's value to a string\n * unescape() Deprecated in version 1.5. Use decodeURI() or decodeURIComponent() instead\n *\n * And according to http://www.w3schools.com/jsref/obj_window.asp, these are the properties and functions\n * of the *window* object.\n *\n * Property Description\n * ---\n * closed Returns a Boolean value indicating whether a window has been closed or not\n * defaultStatus Sets or returns the default text in the statusbar of a window\n * document Returns the Document object for the window (See Document object)\n * frames Returns an array of all the frames (including iframes) in the current window\n * history Returns the History object for the window (See History object)\n * innerHeight Returns the inner height of a window's content area\n * innerWidth Returns the inner width of a window's content area\n * length Returns the number of frames (including iframes) in a window\n * location Returns the Location object for the window (See Location object)\n * name Sets or returns the name of a window\n * navigator Returns the Navigator object for the window (See Navigator object)\n * opener Returns a reference to the window that created the window\n * outerHeight Returns the outer height of a window, including toolbars/scrollbars\n * outerWidth Returns the outer width of a window, including toolbars/scrollbars\n * pageXOffset Returns the pixels the current document has been scrolled (horizontally) from the upper left corner of the window\n * pageYOffset Returns the pixels the current document has been scrolled (vertically) from the upper left corner of the window\n * parent Returns the parent window of the current window\n * screen Returns the Screen object for the window (See Screen object)\n * screenLeft Returns the x coordinate of the window relative to the screen\n * screenTop Returns the y coordinate of the window relative to the screen\n * screenX Returns the x coordinate of the window relative to the screen\n * screenY Returns the y coordinate of the window relative to the screen\n * self Returns the current window\n * status Sets or returns the text in the statusbar of a window\n * top Returns the topmost browser window\n *\n * Method Description\n * ---\n * alert() Displays an alert box with a message and an OK button\n * atob() Decodes a base-64 encoded string\n * blur() Removes focus from the current window\n * btoa() Encodes a string in base-64\n * clearInterval() Clears a timer set with setInterval()\n * clearTimeout() Clears a timer set with setTimeout()\n * close() Closes the current window\n * confirm() Displays a dialog box with a message and an OK and a Cancel button\n * createPopup() Creates a pop-up window\n * focus() Sets focus to the current window\n * moveBy() Moves a window relative to its current position\n * moveTo() Moves a window to the specified position\n * open() Opens a new browser window\n * print() Prints the content of the current window\n * prompt() Displays a dialog box that prompts the visitor for input\n * resizeBy() Resizes the window by the specified pixels\n * resizeTo() Resizes the window to the specified width and height\n * scroll() This method has been replaced by the scrollTo() method.\n * scrollBy() Scrolls the content by the specified number of pixels\n * scrollTo() Scrolls the content to the specified coordinates\n * setInterval() Calls a function or evaluates an expression at specified intervals (in milliseconds)\n * setTimeout() Calls a function or evaluates an expression after a specified number of milliseconds\n * stop() Stops the window from loading\n */\n\nclass Web {\n /**\n * log(s, type)\n *\n * For diagnostic output only. DEBUG must be true (or \"--debug\" specified via the command-line)\n * for Component.log() to display anything.\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n static log(s, type)\n {\n Component.log(s, type);\n }\n\n /**\n * notice(s, fPrintOnly, id)\n *\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n */\n static notice(s, fPrintOnly, id)\n {\n Component.notice(s, fPrintOnly, id);\n }\n\n /**\n * alertUser(sMessage)\n * \n * NOTE: Legacy function for older modules (eg, DiskDump); see Component.alertUser().\n *\n * @param {string} sMessage\n */\n static alertUser(sMessage)\n {\n if (window) {\n window.alert(sMessage);\n } else {\n Web.log(sMessage);\n }\n }\n\n /**\n * getResource(sURL, type, fAsync, done, progress)\n *\n * Request the specified resource (sURL), and once the request is complete, notify done().\n *\n * If fAsync is true, a done() callback should ALWAYS be supplied; otherwise, you'll have no\n * idea when the request is complete or what the response was. done() is passed three parameters:\n *\n * done(sURL, resource, nErrorCode)\n *\n * If nErrorCode is zero, resource should contain the requested data; otherwise, an error occurred.\n *\n * If type is set to a string, that string can be used to control the response format;\n * by default, the response format is plain text, but you can specify \"arraybuffer\" to request arbitrary\n * binary data, in which case the returned resource will be a ArrayBuffer rather than a string.\n *\n * @param {string} sURL\n * @param {string|Object|null} [type] (object for POST request, otherwise type of GET request)\n * @param {boolean} [fAsync] is true for an asynchronous request; false otherwise (MUST be set for IE)\n * @param {function(string,string,number)} [done]\n * @param {function(number)} [progress]\n * @return {Array|null} Array containing [resource, nErrorCode], or null if no response available (yet)\n */\n static getResource(sURL, type = \"text\", fAsync = false, done, progress)\n {\n var nErrorCode = 0, resource = null, response = null;\n\n if (typeof resources == 'object' && (resource = resources[sURL])) {\n if (done) done(sURL, resource, nErrorCode);\n return [resource, nErrorCode];\n }\n else if (fAsync && typeof resources == 'function') {\n resources(sURL, function(resource, nErrorCode)\n {\n if (done) done(sURL, resource, nErrorCode);\n });\n return response;\n }\n\n if (!DEBUG && !NODE) {\n /*\n * TODO: Perhaps it's time for our code in netlib.js to finally add support for HTTPS; for now\n * though, it's just as well that the NODE environment assumes all resources are available locally.\n */\n sURL = sURL.replace(/^\\/(pcjs-disks|private-disks)\\//, \"https://jeffpar.github.io/$1/\");\n }\n else {\n /*\n * The larger resources we put on archive.pcjs.org should also be available locally.\n *\n * NOTE: \"http://archive.pcjs.org\" is now \"https://s3-us-west-2.amazonaws.com/archive.pcjs.org\"\n */\n sURL = sURL.replace(/^(http:\\/\\/archive\\.pcjs\\.org|https:\\/\\/s3-us-west-2\\.amazonaws\\.com\\/archive\\.pcjs\\.org)(\\/.*)\\/([^\\/]*)$/, \"$2/archive/$3\");\n sURL = sURL.replace(/^https:\\/\\/jeffpar\\.github\\.io\\/(pcjs-disks|private-disks)\\/(.*)$/, \"/$1/$2\");\n }\n\n\n var request = (window.XMLHttpRequest? new window.XMLHttpRequest() : new window.ActiveXObject(\"Microsoft.XMLHTTP\"));\n var fArrayBuffer = false, fXHR2 = (typeof request.responseType === 'string');\n \n var callback = function() {\n if (request.readyState !== 4) {\n if (progress) progress(1);\n return null;\n }\n /*\n * The following line was recommended for WebKit, as a work-around to prevent the handler firing multiple\n * times when debugging. Unfortunately, that's not the only XMLHttpRequest problem that occurs when\n * debugging, so I think the WebKit problem is deeper than that. When we have multiple XMLHttpRequests\n * pending, any debugging activity means most of them simply get dropped on floor, so what may actually be\n * happening are mis-notifications rather than redundant notifications.\n *\n * request.onreadystatechange = undefined;\n */\n /*\n * If the request failed due to, say, a CORS policy denial; eg:\n * \n * Failed to load http://www.allbootdisks.com/downloads/Disks/Windows_95_Boot_Disk_Download48/Diskette%20Images/Windows95a.img:\n * Redirect from 'http://www.allbootdisks.com/downloads/Disks/Windows_95_Boot_Disk_Download48/Diskette%20Images/Windows95a.img' to\n * 'http://www.allbootdisks.com/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.\n * Origin 'http://pcjs:8088' is therefore not allowed access.\n * \n * and our request type was \"arraybuffer\", attempting to access responseText may trigger an exception; eg:\n * \n * Uncaught DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's\n * 'responseType' is '' or 'text' (was 'arraybuffer').\n * \n * We could tiptoe around these potential landmines, but the safest thing to do is wrap this code with try/catch.\n */\n try {\n resource = fArrayBuffer? request.response : request.responseText;\n } catch(err) {\n if (MAXDEBUG) Web.log(\"xmlHTTPRequest(\" + sURL + \") exception: \" + err.message);\n }\n /*\n * The normal \"success\" case is a non-null resource and an HTTP status code of 200, but when loading files from the\n * local file system (ie, when using the \"file:\" protocol), we have to be a bit more flexible.\n */\n if (resource != null && (request.status == 200 || !request.status && resource.length && Web.getHostProtocol() == \"file:\")) {\n if (MAXDEBUG) Web.log(\"xmlHTTPRequest(\" + sURL + \"): returned \" + resource.length + \" bytes\");\n }\n else {\n nErrorCode = request.status || -1;\n Web.log(\"xmlHTTPRequest(\" + sURL + \"): error code \" + nErrorCode);\n }\n if (progress) progress(2);\n if (done) done(sURL, resource, nErrorCode);\n return [resource, nErrorCode];\n };\n \n if (fAsync) {\n request.onreadystatechange = callback;\n }\n\n if (progress) progress(0);\n\n if (type && typeof type == \"object\") {\n var sPost = \"\";\n for (var p in type) {\n if (!type.hasOwnProperty(p)) continue;\n if (sPost) sPost += \"&\";\n sPost += p + '=' + encodeURIComponent(type[p]);\n }\n sPost = sPost.replace(/%20/g, '+');\n if (MAXDEBUG) Web.log(\"Web.getResource(POST \" + sURL + \"): \" + sPost.length + \" bytes\");\n request.open(\"POST\", sURL, fAsync);\n request.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\n request.send(sPost);\n } else {\n if (MAXDEBUG) Web.log(\"Web.getResource(GET \" + sURL + \")\");\n request.open(\"GET\", sURL, fAsync);\n if (type == \"arraybuffer\") {\n if (fXHR2) {\n fArrayBuffer = true;\n request.responseType = type;\n } else {\n request.overrideMimeType(\"text/plain; charset=x-user-defined\");\n }\n }\n request.send();\n }\n\n if (!fAsync) {\n request.readyState = 4; // this may already be set for synchronous requests, but I don't want to take any chances \n response = callback();\n }\n return response;\n }\n\n /**\n * parseMemoryResource(sURL, sData)\n *\n * This converts a variety of JSON-style data streams into an Object with the following properties:\n *\n * aBytes\n * aSymbols\n * addrLoad\n * addrExec\n *\n * If the source data contains a 'bytes' array, it's passed through to 'aBytes'; alternatively, if\n * it contains a 'words' array, the values are converted from 16-bit to 8-bit and stored in 'aBytes',\n * and if it contains a 'longs' array, the values are converted from 32-bit longs into bytes and\n * stored in 'aBytes'.\n *\n * Alternatively, if the source data contains a 'data' array, we simply pass that through to the output\n * object as:\n *\n * aData\n *\n * @param {string} sURL\n * @param {string} sData\n * @return {Object|null} (resource)\n */\n static parseMemoryResource(sURL, sData)\n {\n var i;\n var resource = {\n aBytes: null,\n aSymbols: null,\n addrLoad: null,\n addrExec: null\n };\n\n if (sData.charAt(0) == \"[\" || sData.charAt(0) == \"{\") {\n try {\n var a, ib, data;\n\n if (sData.substr(0, 1) == \"<\") { // if the \"data\" begins with a \"<\"...\n /*\n * Early server configs reported an error (via the nErrorCode parameter) if a tape URL was invalid,\n * but more recent server configs now display a somewhat friendlier HTML error page. The downside,\n * however, is that the original error has been buried, and we've received \"data\" that isn't actually\n * tape data. So if the data we've received appears to be \"HTML-like\", we treat it as an error message.\n */\n throw new Error(sData);\n }\n\n /*\n * TODO: IE9 is rather unfriendly and restrictive with regard to how much data it's willing to\n * eval(). In particular, the 10Mb disk image we use for the Windows 1.01 demo config fails in\n * IE9 with an \"Out of memory\" exception. One work-around would be to chop the data into chunks\n * (perhaps one track per chunk, using regular expressions) and then manually re-assemble it.\n *\n * However, it turns out that using JSON.parse(sDiskData) instead of eval(\"(\" + sDiskData + \")\")\n * is a much easier fix. The only drawback is that we must first quote any unquoted property names\n * and remove any comments, because while eval() was cool with them, JSON.parse() is more particular;\n * the following RegExp replacements take care of those requirements.\n *\n * The use of hex values is something else that eval() was OK with, but JSON.parse() is not, and\n * while I've stopped using hex values in DumpAPI responses (at least when \"format=json\" is specified),\n * I can't guarantee they won't show up in \"legacy\" images, and there's no simple RegExp replacement\n * for transforming hex values into decimal values, so I cop out and fall back to eval() if I detect\n * any hex prefixes (\"0x\") in the sequence. Ditto for error messages, which appear like so:\n *\n * [\"unrecognized disk path: test.img\"]\n */\n if (sData.indexOf(\"0x\") < 0 && sData.indexOf(\"0o\") < 0 && sData.substr(0, 2) != '[\"') {\n data = JSON.parse(sData.replace(/([a-z]+):/gm, '\"$1\":').replace(/\\/\\/[^\\n]*/gm, \"\"));\n } else {\n data = eval(\"(\" + sData + \")\");\n }\n\n resource.addrLoad = data['load'];\n resource.addrExec = data['exec'];\n\n if (a = data['bytes']) {\n resource.aBytes = a;\n }\n else if (a = data['words']) {\n /*\n * Convert all words into bytes\n */\n resource.aBytes = new Array(a.length * 2);\n for (i = 0, ib = 0; i < a.length; i++) {\n resource.aBytes[ib++] = a[i] & 0xff;\n resource.aBytes[ib++] = (a[i] >> 8) & 0xff;\n\n }\n }\n else if (a = data['longs']) {\n /*\n * Convert all dwords (longs) into bytes\n */\n resource.aBytes = new Array(a.length * 4);\n for (i = 0, ib = 0; i < a.length; i++) {\n resource.aBytes[ib++] = a[i] & 0xff;\n resource.aBytes[ib++] = (a[i] >> 8) & 0xff;\n resource.aBytes[ib++] = (a[i] >> 16) & 0xff;\n resource.aBytes[ib++] = (a[i] >> 24) & 0xff;\n }\n }\n else if (a = data['data']) {\n resource.aData = a;\n }\n else {\n resource.aBytes = data;\n }\n\n if (resource.aBytes) {\n if (!resource.aBytes.length) {\n Component.error(\"Empty resource: \" + sURL);\n resource = null;\n }\n else if (resource.aBytes.length == 1) {\n Component.error(resource.aBytes[0]);\n resource = null;\n }\n }\n resource.aSymbols = data['symbols'];\n\n } catch (e) {\n Component.error(\"Resource data error (\" + sURL + \"): \" + e.message);\n resource = null;\n }\n }\n else {\n /*\n * Parse the data manually; we assume it's a series of hex byte-values separated by whitespace.\n */\n var ab = [];\n var sHexData = sData.replace(/\\n/gm, \" \").replace(/ +$/, \"\");\n var asHexData = sHexData.split(\" \");\n for (i = 0; i < asHexData.length; i++) {\n var n = parseInt(asHexData[i], 16);\n if (isNaN(n)) {\n Component.error(\"Resource data error (\" + sURL + \"): invalid hex byte (\" + asHexData[i] + \")\");\n break;\n }\n ab.push(n & 0xff);\n }\n if (i == asHexData.length) resource.aBytes = ab;\n }\n return resource;\n }\n\n /**\n * sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)\n *\n * Send a report (eg, bug report) to the server.\n *\n * @param {string} sApp (eg, \"PCjs\")\n * @param {string} sVer (eg, \"1.02\")\n * @param {string} sURL (eg, \"/devices/pc/machine/5150/mda/64kb/machine.xml\")\n * @param {string} sUser (ie, the user key, if any)\n * @param {string} sType (eg, \"bug\"); one of ReportAPI.TYPE.*\n * @param {string} sReport (eg, unparsed state data)\n * @param {string} [sHostName] (default is http://SITEHOST)\n */\n static sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)\n {\n var dataPost = {};\n dataPost[ReportAPI.QUERY.APP] = sApp;\n dataPost[ReportAPI.QUERY.VER] = sVer;\n dataPost[ReportAPI.QUERY.URL] = sURL;\n dataPost[ReportAPI.QUERY.USER] = sUser;\n dataPost[ReportAPI.QUERY.TYPE] = sType;\n dataPost[ReportAPI.QUERY.DATA] = sReport;\n var sReportURL = (sHostName? sHostName : \"http://\" + SITEHOST) + ReportAPI.ENDPOINT;\n Web.getResource(sReportURL, dataPost, true);\n }\n\n /**\n * getHost()\n *\n * @return {string}\n */\n static getHost()\n {\n return (\"http://\" + (window? window.location.host : SITEHOST));\n }\n\n /**\n * getHostURL()\n *\n * @return {string|null}\n */\n static getHostURL()\n {\n return (window? window.location.href : null);\n }\n\n /**\n * getHostProtocol()\n *\n * @return {string}\n */\n static getHostProtocol()\n {\n return (window? window.location.protocol : \"file:\");\n }\n\n /**\n * getUserAgent()\n *\n * @return {string}\n */\n static getUserAgent()\n {\n return (window? window.navigator.userAgent : \"\");\n }\n\n /**\n * hasLocalStorage\n *\n * true if localStorage support exists, is enabled, and works; false otherwise\n *\n * @return {boolean}\n */\n static hasLocalStorage()\n {\n if (Web.fLocalStorage == null) {\n var f = false;\n if (window) {\n try {\n window.localStorage.setItem(Web.sLocalStorageTest, Web.sLocalStorageTest);\n f = (window.localStorage.getItem(Web.sLocalStorageTest) == Web.sLocalStorageTest);\n window.localStorage.removeItem(Web.sLocalStorageTest);\n } catch (e) {\n Web.logLocalStorageError(e);\n f = false;\n }\n }\n Web.fLocalStorage = f;\n }\n return Web.fLocalStorage;\n }\n\n /**\n * logLocalStorageError(e)\n *\n * @param {Error} e is an exception\n */\n static logLocalStorageError(e)\n {\n Web.log(e.message, \"localStorage error\");\n }\n\n /**\n * getLocalStorageItem(sKey)\n *\n * Returns the requested key value, or null if the key does not exist, or undefined if localStorage is not available\n *\n * @param {string} sKey\n * @return {string|null|undefined} sValue\n */\n static getLocalStorageItem(sKey)\n {\n var sValue;\n if (window) {\n try {\n sValue = window.localStorage.getItem(sKey);\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n }\n return sValue;\n }\n\n /**\n * setLocalStorageItem(sKey, sValue)\n *\n * @param {string} sKey\n * @param {string} sValue\n * @return {boolean} true if localStorage is available, false if not\n */\n static setLocalStorageItem(sKey, sValue)\n {\n try {\n window.localStorage.setItem(sKey, sValue);\n return true;\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n return false;\n }\n\n /**\n * removeLocalStorageItem(sKey)\n *\n * @param {string} sKey\n */\n static removeLocalStorageItem(sKey)\n {\n try {\n window.localStorage.removeItem(sKey);\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n }\n\n /**\n * getLocalStorageKeys()\n *\n * @return {Array}\n */\n static getLocalStorageKeys()\n {\n var a = [];\n try {\n for (var i = 0, c = window.localStorage.length; i < c; i++) {\n a.push(window.localStorage.key(i));\n }\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n return a;\n }\n\n /**\n * reloadPage()\n */\n static reloadPage()\n {\n if (window) window.location.reload();\n }\n\n /**\n * isUserAgent(s)\n *\n * Check the browser's user-agent string for the given substring; \"iOS\" and \"MSIE\" are special values you can\n * use that will match any iOS or MSIE browser, respectively (even IE11, in the case of \"MSIE\").\n *\n * 2013-11-06: In a questionable move, MSFT changed the user-agent reported by IE11 on Windows 8.1, eliminating\n * the \"MSIE\" string (which MSDN calls a \"version token\"; see http://msdn.microsoft.com/library/ms537503.aspx);\n * they say \"public websites should rely on feature detection, rather than browser detection, in order to design\n * their sites for browsers that don't support the features used by the website.\" So, in IE11, we get a user-agent\n * that tries to fool apps into thinking the browser is more like WebKit or Gecko:\n *\n * Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko\n *\n * That's a nice idea, but in the meantime, they hosed the XSL transform code in embed.js, which contained\n * some very critical browser-specific code; turning on IE's \"Compatibility Mode\" didn't help either, because\n * that's a sledgehammer solution which restores the old user-agent string but also disables other features like\n * HTML5 canvas support. As an interim solution, I'm treating any \"MSIE\" check as a check for either \"MSIE\" or\n * \"Trident\".\n *\n * UPDATE: I've since found ways to make the code in embed.js more browser-agnostic, so for now, there's isn't\n * any code that cares about \"MSIE\", but I've left the change in place, because I wouldn't be surprised if I'll\n * need more IE-specific code in the future, perhaps for things like copy/paste functionality, or mouse capture.\n *\n * @param {string} s is a substring to search for in the user-agent; as noted above, \"iOS\" and \"MSIE\" are special values\n * @return {boolean} is true if the string was found, false if not\n */\n static isUserAgent(s)\n {\n if (window) {\n var userAgent = Web.getUserAgent();\n /*\n * Here's one case where we have to be careful with Component, because when isUserAgent() is called by\n * the init code below, component.js hasn't been loaded yet. The simple solution for now is to remove the call.\n *\n * Web.log(\"agent: \" + userAgent);\n *\n * And yes, it would be pointless to use the conditional (?) operator below, if not for the Google Closure\n * Compiler (v20130823) failing to detect the entire expression as a boolean.\n */\n return s == \"iOS\" && !!userAgent.match(/(iPod|iPhone|iPad)/) && !!userAgent.match(/AppleWebKit/) || s == \"MSIE\" && !!userAgent.match(/(MSIE|Trident)/) || (userAgent.indexOf(s) >= 0);\n }\n return false;\n }\n\n /**\n * isMobile(sDevice)\n *\n * Checks the URL for a \"mobile\" parameter, and failing that, checks the browser's user-agent string for the\n * substring \"Mobi\", as per Mozilla recommendation:\n *\n * https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent\n *\n * @param {string} [sDevice] (eg, \"iPad\" to check for iPad, or \"!iPad\" to specifically exclude it) \n * @return {boolean} is true if the browser appears to be a mobile (ie, non-desktop) web browser, false if not\n */\n static isMobile(sDevice)\n {\n var sMobile = Web.getURLParm(\"mobile\");\n if (sMobile) return sMobile == \"true\";\n if (Web.isUserAgent(\"Mobi\")) {\n if (!sDevice) return true;\n var fInvert = sDevice[0] == '!';\n if (fInvert) sDevice = sDevice.substr(1);\n return Web.isUserAgent(sDevice) != fInvert;\n }\n return false;\n }\n\n /**\n * findProperty(obj, sProp, sSuffix)\n *\n * If both sProp and sSuffix are set, then any browser-specific prefixes are inserted between sProp and sSuffix,\n * and if a match is found, it is returned without sProp.\n *\n * For example, if findProperty(document, 'on', 'fullscreenchange') discovers that 'onwebkitfullscreenchange' exists,\n * it will return 'webkitfullscreenchange', in preparation for an addEventListener() call.\n *\n * More commonly, sSuffix is not used, so whatever property is found is returned as-is.\n *\n * @param {Object|null|undefined} obj\n * @param {string} sProp\n * @param {string} [sSuffix]\n * @return {string|null}\n */\n static findProperty(obj, sProp, sSuffix)\n {\n if (obj) {\n for (var i = 0; i < Web.asBrowserPrefixes.length; i++) {\n var sName = Web.asBrowserPrefixes[i];\n if (sSuffix) {\n sName += sSuffix;\n var sEvent = sProp + sName;\n if (sEvent in obj) return sName;\n } else {\n if (!sName) {\n sName = sProp[0];\n } else {\n sName += sProp[0].toUpperCase();\n }\n sName += sProp.substr(1);\n if (sName in obj) return sName;\n }\n }\n }\n return null;\n }\n\n /**\n * getURLParm(sParm)\n *\n * First looks for sParm exactly as specified, then looks for the lower-case version.\n *\n * @param {string} sParm\n * @return {string|undefined}\n */\n static getURLParm(sParm)\n {\n if (!Web.parmsURL) {\n Web.parmsURL = Web.parseURLParms();\n }\n return Web.parmsURL[sParm] || Web.parmsURL[sParm.toLowerCase()];\n }\n\n /**\n * parseURLParms(sParms)\n *\n * @param {string} [sParms] containing the parameter portion of a URL (ie, after the '?')\n * @return {Object} containing properties for each parameter found\n */\n static parseURLParms(sParms)\n {\n var aParms = {};\n if (window) { // an alternative to \"if (typeof module === 'undefined')\" if require(\"defines\") was used\n if (!sParms) {\n /*\n * Note that window.location.href returns the entire URL, whereas window.location.search\n * returns only the parameters, if any (starting with the '?', which we skip over with a substr() call).\n */\n sParms = window.location.search.substr(1);\n }\n var match;\n var pl = /\\+/g; // RegExp for replacing addition symbol with a space\n var search = /([^&=]+)=?([^&]*)/g;\n var decode = function(s)\n {\n return decodeURIComponent(s.replace(pl, \" \"));\n };\n\n while ((match = search.exec(sParms))) {\n aParms[decode(match[1])] = decode(match[2]);\n }\n }\n return aParms;\n }\n\n /**\n * downloadFile(sData, sType, fBase64, sFileName)\n *\n * @param {string} sData\n * @param {string} sType\n * @param {boolean} [fBase64]\n * @param {string} [sFileName]\n */\n static downloadFile(sData, sType, fBase64, sFileName)\n {\n var link = null, sAlert;\n var sURI = \"data:application/\" + sType + (fBase64? \";base64\" : \"\") + \",\";\n\n if (!Web.isUserAgent(\"Firefox\")) {\n sURI += (fBase64? sData : encodeURI(sData));\n } else {\n sURI += (fBase64? sData : encodeURIComponent(sData));\n }\n if (sFileName) {\n link = document.createElement('a');\n if (typeof link.download != 'string') link = null;\n }\n if (link) {\n link.href = sURI;\n link.download = sFileName;\n document.body.appendChild(link); // Firefox allegedly requires the link to be in the body\n link.click();\n document.body.removeChild(link);\n sAlert = 'Check your Downloads folder for ' + sFileName + '.';\n if (Web.isUserAgent(\"Chrome\")) {\n sAlert += '\\n\\nIn Chrome, after clicking OK, you may ALSO have to select the \"Window\" menu, choose \"Downloads\", and then locate this download and select \"Keep\".';\n sAlert += '\\n\\nThis is part of Chrome\\'s \"Security By Jumping Through Extra Hoops\" technology, which is much easier for Google to implement than actually checking for something malicious.';\n sAlert += '\\n\\nAnd for the record, there is nothing malicious on the PCjs website.';\n }\n } else {\n window.open(sURI);\n sAlert = 'Check your browser for a new window/tab containing the requested data' + (sFileName? (' (' + sFileName + ')') : '') + '.';\n }\n return sAlert;\n }\n\n /**\n * onCountRepeat(n, fnRepeat, fnComplete, msDelay)\n *\n * Call fnRepeat() n times with an msDelay millisecond delay between calls,\n * then call fnComplete() when n has been exhausted OR fnRepeat() returns false.\n *\n * @param {number} n\n * @param {function()} fnRepeat\n * @param {function()} fnComplete\n * @param {number} [msDelay]\n */\n static onCountRepeat(n, fnRepeat, fnComplete, msDelay)\n {\n var fnTimeout = function doCountRepeat()\n {\n n -= 1;\n if (n >= 0) {\n if (!fnRepeat()) n = 0;\n }\n if (n > 0) {\n setTimeout(fnTimeout, msDelay || 0);\n return;\n }\n fnComplete();\n };\n fnTimeout();\n }\n\n /**\n * onClickRepeat(e, msDelay, msRepeat, fn)\n *\n * Repeatedly call fn() with an initial msDelay, and an msRepeat delay thereafter,\n * as long as HTML control Object e has an active \"down\" event and fn() returns true.\n *\n * @param {Object} e\n * @param {number} msDelay\n * @param {number} msRepeat\n * @param {function(boolean)} fn is passed false on the first call, true on all repeated calls\n */\n static onClickRepeat(e, msDelay, msRepeat, fn)\n {\n var ms = 0, timer = null, fIgnoreMouseEvents = false;\n\n var fnRepeat = function doClickRepeat()\n {\n if (fn(ms === msRepeat)) {\n timer = setTimeout(fnRepeat, ms);\n ms = msRepeat;\n }\n };\n e.onmousedown = function()\n {\n // Web.log(\"onMouseDown()\");\n if (!fIgnoreMouseEvents) {\n if (!timer) {\n ms = msDelay;\n fnRepeat();\n }\n }\n };\n e.ontouchstart = function()\n {\n // Web.log(\"onTouchStart()\");\n if (!timer) {\n ms = msDelay;\n fnRepeat();\n }\n };\n e.onmouseup = e.onmouseout = function()\n {\n // Web.log(\"onMouseUp()/onMouseOut()\");\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n };\n e.ontouchend = e.ontouchcancel = function()\n {\n // Web.log(\"onTouchEnd()/onTouchCancel()\");\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n /*\n * Devices that generate ontouch* events ALSO generate onmouse* events,\n * and generally do so immediately after all the touch events are complete,\n * so unless we want double the action, we need to ignore mouse events.\n */\n fIgnoreMouseEvents = true;\n };\n }\n\n /**\n * onPageEvent(sName, fn)\n *\n * For 'onload', 'onunload', and 'onpageshow' events, most callers should NOT use this function, but\n * instead use Web.onInit(), Web.onShow(), and Web.onExit(), respectively.\n *\n * The only components that should still use onPageEvent() are THIS component (see the bottom of this file)\n * and components that need to capture other events (eg, the 'onresize' event in the Video component).\n *\n * This function creates a chain of callbacks, allowing multiple JavaScript modules to define handlers\n * for the same event, which wouldn't be possible if everyone modified window['onload'], window['onunload'],\n * etc, themselves. However, that's less of a concern now, because assuming everyone else is now using\n * onInit(), onExit(), etc, then there really IS only one component setting the window callback: this one.\n *\n * NOTE: It's risky to refer to obscure event handlers with \"dot\" names, because the Closure Compiler may\n * erroneously replace them (eg, window.onpageshow is a good example).\n *\n * @param {string} sFunc\n * @param {function()} fn\n */\n static onPageEvent(sFunc, fn)\n {\n if (window) {\n var fnPrev = window[sFunc];\n if (typeof fnPrev !== 'function') {\n window[sFunc] = fn;\n } else {\n /*\n * TODO: Determine whether there's any value in receiving/sending the Event object that the\n * browser provides when it generates the original event.\n */\n window[sFunc] = function onWindowEvent()\n {\n if (fnPrev) fnPrev();\n fn();\n };\n }\n }\n };\n\n /**\n * onInit(fn)\n *\n * Use this instead of setting window.onload. Allows multiple JavaScript modules to define their own 'onload' event handler.\n *\n * @param {function()} fn\n */\n static onInit(fn)\n {\n Web.aPageEventHandlers['init'].push(fn);\n };\n\n /**\n * onShow(fn)\n *\n * @param {function()} fn\n *\n * Use this instead of setting window.onpageshow. Allows multiple JavaScript modules to define their own 'onpageshow' event handler.\n */\n static onShow(fn)\n {\n Web.aPageEventHandlers['show'].push(fn);\n };\n\n /**\n * onExit(fn)\n *\n * @param {function()} fn\n *\n * Use this instead of setting window.onunload. Allows multiple JavaScript modules to define their own 'onunload' event handler.\n */\n static onExit(fn)\n {\n Web.aPageEventHandlers['exit'].push(fn);\n };\n\n /**\n * doPageEvent(afn)\n *\n * @param {Array.<function()>} afn\n */\n static doPageEvent(afn)\n {\n if (Web.fPageEventsEnabled) {\n try {\n for (var i = 0; i < afn.length; i++) {\n afn[i]();\n }\n } catch (e) {\n Web.notice(\"An unexpected error occurred: \" + e.message + \"\\n\\nIf it happens again, please send this information to support@pcjs.org. Thanks.\");\n }\n }\n };\n\n /**\n * enablePageEvents(fEnable)\n *\n * @param {boolean} fEnable is true to enable page events, false to disable (they're enabled by default)\n */\n static enablePageEvents(fEnable)\n {\n if (!Web.fPageEventsEnabled && fEnable) {\n Web.fPageEventsEnabled = true;\n if (Web.fPageLoaded) Web.sendPageEvent('init');\n if (Web.fPageShowed) Web.sendPageEvent('show');\n return;\n }\n Web.fPageEventsEnabled = fEnable;\n }\n\n /**\n * sendPageEvent(sEvent)\n *\n * This allows us to manually trigger page events.\n *\n * @param {string} sEvent (one of 'init', 'show' or 'exit')\n */\n static sendPageEvent(sEvent)\n {\n if (Web.aPageEventHandlers[sEvent]) {\n Web.doPageEvent(Web.aPageEventHandlers[sEvent]);\n }\n }\n}\n\nWeb.parmsURL = null; // initialized on first call to parseURLParms()\n\nWeb.aPageEventHandlers = {\n 'init': [], // list of window 'onload' handlers\n 'show': [], // list of window 'onpageshow' handlers\n 'exit': [] // list of window 'onunload' handlers (although we prefer to use 'onbeforeunload' if possible)\n};\n\nWeb.asBrowserPrefixes = ['', 'moz', 'ms', 'webkit'];\n\nWeb.fPageLoaded = false; // set once the page's first 'onload' event has occurred\nWeb.fPageShowed = false; // set once the page's first 'onpageshow' event has occurred\nWeb.fPageEventsEnabled = true; // default is true, set to false (or true) by enablePageEvents()\n\n/**\n * fLocalStorage\n *\n * true if localStorage support exists, is enabled, and works; \"falsey\" otherwise\n *\n * @type {boolean|null}\n */\nWeb.fLocalStorage = null;\n\n/**\n * TODO: Is there any way to get the Closure Compiler to stop inlining this string? This isn't cutting it.\n *\n * @const {string}\n */\nWeb.sLocalStorageTest = \"PCjs.localStorage\";\n\nWeb.onPageEvent('onload', function onPageLoad() {\n Web.fPageLoaded = true;\n Web.doPageEvent(Web.aPageEventHandlers['init']);\n});\n\nWeb.onPageEvent('onpageshow', function onPageShow() {\n Web.fPageShowed = true;\n Web.doPageEvent(Web.aPageEventHandlers['show']);\n});\n\nWeb.onPageEvent(Web.isUserAgent(\"iOS\")? 'onpagehide' : (Web.isUserAgent(\"Opera\")? 'onunload' : 'onbeforeunload'), function onPageUnload() {\n Web.doPageEvent(Web.aPageEventHandlers['exit']);\n});\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/component.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * All PCjs components now use JSDoc types, primarily so that Google's Closure Compiler will compile\n * everything with zero warnings when ADVANCED_OPTIMIZATIONS are enabled. For more information about\n * the JSDoc types supported by the Closure Compiler:\n *\n * https://developers.google.com/closure/compiler/docs/js-for-compiler#types\n *\n * I also attempted to validate this code with JSLint, but it complained too much; eg, it didn't like\n * \"while (true)\", a tried and \"true\" programming convention for decades, and it wanted me to replace\n * all \"++\" and \"--\" operators with \"+= 1\" and \"-= 1\", use \"(s || '')\" instead of \"(s? s : '')\", etc.\n *\n * I prefer sticking with traditional C-style idioms, in part because they are more portable. That\n * does NOT mean I'm trying to write \"portable JavaScript,\" but some of this code was ported from C code\n * I'd written long ago, so portability is good, and I'm not going to throw that away if there's no need.\n *\n * UPDATE: I've since switched from JSLint to JSHint, which seems to have more reasonable defaults.\n * And for new code, I have adopted some popular JavaScript idioms, like \"(s || '')\", although the need\n * for those kinds of expressions will be reduced as I also start adopting some ES6 features, like\n * default parameters.\n */\n\n\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * subclass (eg, SerialPort), because otherwise the Compiler won't allow us to *reference*\n * the named property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass Component {\n /**\n * Component(type, parms, bitsMessage)\n *\n * A Component object requires:\n *\n * type: a user-defined type name (eg, \"CPU\")\n *\n * and accepts any or all of the following (parms) properties:\n *\n * id: component ID (default is \"\")\n * name: component name (default is \"\"; if blank, toString() will use the type name only)\n * comment: component comment string (default is undefined)\n *\n * Component subclasses will usually have additional (parms) properties.\n *\n * @param {string} type\n * @param {Object} [parms]\n * @param {number} [bitsMessage] selects message(s) that the component wants to enable (default is 0)\n */\n constructor(type, parms, bitsMessage)\n {\n this.type = type;\n\n if (!parms) parms = {'id': \"\", 'name': \"\"};\n\n this.id = parms['id'] || \"\";\n this.name = parms['name'];\n this.comment = parms['comment'];\n this.parms = parms;\n\n /*\n * The following Component properties need to be accessible by other machines and/or command scripts;\n * well, OK, or we could have exported some new functions to walk the contents of these properties, as we\n * did with findMachineComponent(), but this works just as well.\n *\n * Also, while the double-assignment looks silly (ie, using both dot and bracket property notation), it\n * resolves a complaint from the Closure Compiler, because if we use ONLY bracket notation here, then the\n * Compiler wants us to change all the other references to bracket notation as well.\n */\n this.exports = this['exports'] = {};\n this.bindings = this['bindings'] = {};\n\n var i = this.id.indexOf('.');\n if (i < 0) {\n this.idComponent = this.id;\n } else {\n this.idMachine = this.id.substr(0, i);\n this.idComponent = this.id.substr(i + 1);\n }\n\n /*\n * Gather all the various component flags (booleans) into a single \"flags\" object, and encourage\n * subclasses to do the same, to reduce the property clutter we have to wade through while debugging.\n */\n this.flags = {\n ready: false,\n busy: false,\n busyCancel: false,\n initDone: false,\n powered: false,\n unloading: false,\n error: false\n };\n\n this.fnReady = null;\n this.clearError();\n this.bitsMessage = bitsMessage || 0;\n\n this.cmp = null;\n this.bus = null;\n this.cpu = null;\n this.dbg = null;\n\n /*\n * TODO: Consider adding another parameter to the Component() constructor that allows components to tell\n * us if they support single or multiple instances per machine. For example, there can be multiple SerialPort\n * components per machine, but only one CPU component (some machines also support an FPU, but that component\n * is considered separate from the CPU).\n *\n * It's not critical, but it would help catch machine configuration errors; for example, a machine that mistakenly\n * includes two CPU components may, aside from wasting memory, end up with odd side-effects, like unresponsive\n * CPU controls.\n */\n Component.add(this);\n }\n\n /**\n * Component.add(component)\n *\n * @param {Component} component\n */\n static add(component)\n {\n /*\n * This just generates a lot of useless noise, handy in the early days, not so much these days....\n *\n * if (DEBUG) Component.log(\"Component.add(\" + component.type + \",\" + component.id + \")\");\n */\n Component.components.push(component);\n }\n\n /**\n * Component.addMachine(idMachine)\n *\n * @param {string} idMachine\n */\n static addMachine(idMachine)\n {\n Component.machines[idMachine] = {};\n }\n\n /**\n * Component.addMachineResource(idMachine, sName, data)\n *\n * @param {string} idMachine\n * @param {string|null} sName (name of the resource)\n * @param {*} data\n */\n static addMachineResource(idMachine, sName, data)\n {\n /*\n * I used to assert(Component.machines[idMachine]), but when we're running as a Node app, embed.js is not used,\n * so addMachine() is never called, so resources do not need to be recorded.\n */\n if (Component.machines[idMachine] && sName) {\n Component.machines[idMachine][sName] = data;\n }\n }\n\n /**\n * Component.getMachineResources(idMachine)\n *\n * @param {string} idMachine\n * @return {Object|undefined}\n */\n static getMachineResources(idMachine)\n {\n return Component.machines[idMachine];\n }\n\n /**\n * Component.getTime()\n *\n * @return {number} the current time, in milliseconds\n */\n static getTime()\n {\n return Date.now() || +new Date();\n }\n\n /**\n * Component.log(s, type)\n *\n * For diagnostic output only.\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n static log(s, type)\n {\n if (!COMPILED) {\n if (s) {\n var sElapsed = \"\", sMsg = (type? (type + \": \") : \"\") + s;\n if (typeof Usr != \"undefined\") {\n if (Component.msStart === undefined) {\n Component.msStart = Component.getTime();\n }\n sElapsed = (Component.getTime() - Component.msStart) + \"ms: \";\n }\n sMsg = sMsg.replace(/\\r/g, '\\\\r').replace(/\\n/g, ' ');\n if (window && window.console) console.log(sElapsed + sMsg);\n }\n }\n }\n\n /**\n * Component.assert(f, s)\n *\n * Verifies conditions that must be true (for DEBUG builds only).\n *\n * The Closure Compiler should automatically remove all references to Component.assert() in non-DEBUG builds.\n * TODO: Add a task to the build process that \"asserts\" there are no instances of \"assertion failure\" in RELEASE builds.\n *\n * @param {boolean} f is the expression we are asserting to be true\n * @param {string} [s] is description of the assertion on failure\n */\n static assert(f, s)\n {\n if (DEBUG) {\n if (!f) {\n if (!s) s = \"assertion failure\";\n Component.log(s);\n throw new Error(s);\n }\n }\n }\n\n /**\n * Component.print(s)\n *\n * Components that inherit from this class should use this.print(), rather than Component.print(), because\n * if a Control Panel is loaded, it will override only the instance method, not the class method (overriding the\n * class method would improperly affect any other machines loaded on the same page).\n *\n * @this {Component}\n * @param {string} s\n */\n static print(s)\n {\n if (!COMPILED) {\n var i = s.lastIndexOf('\\n');\n if (i >= 0) {\n Component.println(s.substr(0, i));\n s = s.substr(i + 1);\n }\n Component.printBuffer += s;\n }\n }\n\n /**\n * Component.println(s, type, id)\n *\n * Components that inherit from this class should use this.println(), rather than Component.println(), because\n * if a Control Panel is loaded, it will override only the instance method, not the class method (overriding the\n * class method would improperly affect any other machines loaded on the same page).\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n * @param {string} [id] is the caller's ID, if any\n */\n static println(s, type, id)\n {\n if (!COMPILED) {\n s = Component.printBuffer + (s || \"\");\n Component.log((id? (id + \": \") : \"\") + (s? (\"\\\"\" + s + \"\\\"\") : \"\"), type);\n Component.printBuffer = \"\";\n }\n }\n\n /**\n * Component.notice(s, fPrintOnly, id)\n *\n * notice() is like println() but implies a need for user notification, so we alert() as well.\n *\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n * @return {boolean}\n */\n static notice(s, fPrintOnly, id)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.NOTICE, id);\n }\n if (!fPrintOnly) Component.alertUser((id? (id + \": \") : \"\") + s);\n return true;\n }\n\n /**\n * Component.warning(s)\n *\n * @param {string} s describes the warning\n */\n static warning(s)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.WARNING);\n }\n Component.alertUser(s);\n }\n\n /**\n * Component.error(s)\n *\n * @param {string} s describes the error; an alert() is displayed as well\n */\n static error(s)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.ERROR);\n }\n Component.alertUser(s);\n }\n\n /**\n * Component.alertUser(sMessage)\n *\n * @param {string} sMessage\n */\n static alertUser(sMessage)\n {\n if (window) {\n window.alert(sMessage);\n } else {\n Component.log(sMessage);\n }\n }\n\n /**\n * Component.confirmUser(sPrompt)\n *\n * @param {string} sPrompt\n * @returns {boolean} true if the user clicked OK, false if Cancel/Close\n */\n static confirmUser(sPrompt)\n {\n var fResponse = false;\n if (window) {\n fResponse = window.confirm(sPrompt);\n }\n return fResponse;\n }\n\n /**\n * Component.promptUser()\n *\n * @param {string} sPrompt\n * @param {string} [sDefault]\n * @returns {string|null}\n */\n static promptUser(sPrompt, sDefault)\n {\n var sResponse = null;\n if (window) {\n sResponse = window.prompt(sPrompt, sDefault === undefined? \"\" : sDefault);\n }\n return sResponse;\n }\n\n /**\n * Component.appendControl(control, sText)\n *\n * @param {Object} control\n * @param {string} sText\n */\n static appendControl(control, sText)\n {\n control.value += sText;\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (COMPILED) {\n sText = control.value;\n if (sText.length > 8192) control.value = sText.substr(sText.length - 4096);\n }\n control.scrollTop = control.scrollHeight;\n }\n\n /**\n * Component.replaceControl(control, sSearch, sReplace)\n *\n * @param {Object} control\n * @param {string} sSearch\n * @param {string} sReplace\n */\n static replaceControl(control, sSearch, sReplace)\n {\n var sText = control.value;\n var i = sText.lastIndexOf(sSearch);\n if (i < 0) {\n sText += sSearch + '\\n';\n } else {\n sText = sText.substr(0, i) + sReplace + sText.substr(i + sSearch.length);\n }\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (COMPILED && sText.length > 8192) sText = sText.substr(sText.length - 4096);\n control.value = sText;\n control.scrollTop = control.scrollHeight;\n }\n\n /**\n * Component.bindExternalControl(component, sBinding, sType)\n *\n * @param {Component} component\n * @param {string} sBinding\n * @param {string} [sType] is the external component type (default is \"Panel\")\n */\n static bindExternalControl(component, sBinding, sType = \"Panel\")\n {\n if (sBinding) {\n var target = Component.getComponentByType(sType, component.id);\n if (target) {\n var control = target.bindings[sBinding];\n if (control) {\n component.setBinding(null, sBinding, control);\n }\n }\n }\n }\n\n /**\n * Component.bindComponentControls(component, element, sAppClass)\n *\n * @param {Component} component\n * @param {HTMLElement} element from the DOM\n * @param {string} sAppClass\n */\n static bindComponentControls(component, element, sAppClass)\n {\n var aeControls = Component.getElementsByClass(element.parentNode, sAppClass + \"-control\");\n\n for (var iControl = 0; iControl < aeControls.length; iControl++) {\n\n var aeChildNodes = aeControls[iControl].childNodes;\n\n for (var iNode = 0; iNode < aeChildNodes.length; iNode++) {\n var control = aeChildNodes[iNode];\n if (control.nodeType !== 1 /* document.ELEMENT_NODE */) {\n continue;\n }\n var sClass = control.getAttribute(\"class\");\n if (!sClass) continue;\n var aClasses = sClass.split(\" \");\n for (var iClass = 0; iClass < aClasses.length; iClass++) {\n var parms;\n sClass = aClasses[iClass];\n switch (sClass) {\n case sAppClass + \"-binding\":\n parms = Component.getComponentParms(/** @type {HTMLElement} */(control));\n if (parms && parms['binding'] !== undefined) {\n component.setBinding(parms['type'], parms['binding'], /** @type {HTMLElement} */(control), parms['value']);\n } else if (!parms || parms['type'] != \"description\") {\n Component.log(\"Component '\" + component.toString() + \"' missing binding\" + (parms? \" for \" + parms['type'] : \"\"), \"warning\");\n }\n iClass = aClasses.length;\n break;\n default:\n // if (DEBUG) Component.log(\"Component.bindComponentControls(\" + component.toString() + \"): unrecognized control class \\\"\" + sClass + \"\\\"\", \"warning\");\n break;\n }\n }\n }\n }\n }\n\n /**\n * Component.getComponents(idRelated)\n *\n * We could store components as properties, using the component's ID, and change\n * this linear lookup into a property lookup, but some components may have no ID.\n *\n * @param {string} [idRelated] of related component\n * @return {Array} of components\n */\n static getComponents(idRelated)\n {\n var i;\n var aComponents = [];\n /*\n * getComponentByID(id, idRelated)\n *\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated) {\n if ((i = idRelated.indexOf('.')) > 0)\n idRelated = idRelated.substr(0, i + 1);\n else\n idRelated = \"\";\n }\n for (i = 0; i < Component.components.length; i++) {\n var component = Component.components[i];\n if (!idRelated || !component.id.indexOf(idRelated)) {\n aComponents.push(component);\n }\n }\n return aComponents;\n }\n\n /**\n * Component.getComponentByID(id, idRelated)\n *\n * We could store components as properties, using the component's ID, and change\n * this linear lookup into a property lookup, but some components may have no ID.\n *\n * @param {string} id of the desired component\n * @param {string} [idRelated] of related component\n * @return {Component|null}\n */\n static getComponentByID(id, idRelated)\n {\n if (id !== undefined) {\n var i;\n /*\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated && (i = idRelated.indexOf('.')) > 0) {\n id = idRelated.substr(0, i + 1) + id;\n }\n for (i = 0; i < Component.components.length; i++) {\n if (Component.components[i].id === id) {\n return Component.components[i];\n }\n }\n if (Component.components.length) {\n Component.log(\"Component ID '\" + id + \"' not found\", \"warning\");\n }\n }\n return null;\n }\n\n /**\n * Component.getComponentByType(sType, idRelated, componentPrev)\n *\n * @param {string} sType of the desired component\n * @param {string} [idRelated] of related component\n * @param {Component|null} [componentPrev] of previously returned component, if any\n * @return {Component|null}\n */\n static getComponentByType(sType, idRelated, componentPrev)\n {\n if (sType !== undefined) {\n var i;\n /*\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated) {\n if ((i = idRelated.indexOf('.')) > 0) {\n idRelated = idRelated.substr(0, i + 1);\n } else {\n idRelated = \"\";\n }\n }\n for (i = 0; i < Component.components.length; i++) {\n if (componentPrev) {\n if (componentPrev == Component.components[i]) componentPrev = null;\n continue;\n }\n if (sType == Component.components[i].type && (!idRelated || !Component.components[i].id.indexOf(idRelated))) {\n return Component.components[i];\n }\n }\n Component.log(\"Component type '\" + sType + \"' not found\", \"warning\");\n }\n return null;\n }\n\n /**\n * Component.getComponentParms(element)\n *\n * @param {HTMLElement} element from the DOM\n */\n static getComponentParms(element)\n {\n var parms = null;\n var sParms = element.getAttribute(\"data-value\");\n if (sParms) {\n try {\n parms = eval('(' + sParms + ')'); // jshint ignore:line\n /*\n * We can no longer invoke removeAttribute() because some components (eg, Panel) need\n * to run their initXXX() code more than once, to avoid initialization-order dependencies.\n *\n * if (!DEBUG) {\n * element.removeAttribute(\"data-value\");\n * }\n */\n } catch(e) {\n Component.error(e.message + \" (\" + sParms + \")\");\n }\n }\n return parms;\n }\n\n /**\n * Component.getElementsByClass(element, sClass, sObjClass)\n *\n * This is a cross-browser helper function, since not all browser's support getElementsByClassName()\n *\n * TODO: This should probably be moved into weblib.js at some point, along with the control binding functions above,\n * to keep all the browser-related code together.\n *\n * @param {HTMLDocument|HTMLElement|Node} element from the DOM\n * @param {string} sClass\n * @param {string} [sObjClass]\n * @return {Array|NodeList}\n */\n static getElementsByClass(element, sClass, sObjClass)\n {\n if (sObjClass) sClass += '-' + sObjClass + \"-object\";\n /*\n * Use the browser's built-in getElementsByClassName() if it appears to be available\n * (for example, it's not available in IE8, but it should be available in IE9 and up)\n */\n if (element.getElementsByClassName) {\n return element.getElementsByClassName(sClass);\n }\n var i, j, ae = [];\n var aeAll = element.getElementsByTagName(\"*\");\n var re = new RegExp('(^| )' + sClass + '( |$)');\n for (i = 0, j = aeAll.length; i < j; i++) {\n if (re.test(aeAll[i].className)) {\n ae.push(aeAll[i]);\n }\n }\n if (!ae.length) {\n Component.log('No elements of class \"' + sClass + '\" found');\n }\n return ae;\n }\n\n /**\n * Component.getScriptCommands(sScript)\n *\n * This is a simple parser that breaks sScript into an array of commands, where each command\n * is an array of tokens, where tokens are sequences of characters separated by any of: tab, space,\n * carriage-return (CR), line-feed (LF), semicolon, single-quote, or double-quote; if a quote is\n * used, all characters up to the next matching quote become part of the token, allowing any of the\n * other separators to be part of the token. CR, LF and semicolon also serve to terminate a command,\n * with semicolon being preferred, because it's 1) more visible, and 2) essential when the entire\n * script is a multi-line string where all CR/LF were replaced by spaces (which is what Jekyll does,\n * and since we can't change Jekyll, it's what our own MarkDown Front Matter parser does as well;\n * see convertMD() in markout.js, where the aCommandDefs array is built).\n *\n * Backslash sequences like \\n, \\r, and \\\\ have already been converted to LF, CR and backslash\n * characters, since the entire script string is injected into a JavaScript function call, so any\n * backslash sequence that JavaScript supports is automatically converted:\n *\n * \\0 \\' \\\" \\\\ \\n \\r \\v \\t \\b \\f \\uXXXX \\xXX\n * ^J ^M ^K ^I ^H ^L\n *\n * To support any other non-printable 8-bit character, such as ESC, you should use \\xXX, where XX\n * is the ASCII code in hex. For ESC, that would be \\x1B.\n *\n * @param {string} sScript\n * @return {Array}\n */\n static getScriptCommands(sScript)\n {\n var cch = sScript.length;\n var aCommands = [], aTokens = [], sToken = \"\", chQuote = null;\n for (var i = 0; i < cch; i++) {\n var ch = sScript[i];\n if (ch == '\"' || ch == \"'\") {\n if (chQuote && ch != chQuote) {\n sToken += ch;\n continue;\n }\n if (!chQuote) {\n chQuote = ch;\n } else {\n chQuote = null;\n }\n if (sToken) {\n aTokens.push(sToken);\n sToken = \"\";\n }\n continue;\n }\n if (!chQuote) {\n if (ch == '\\r' || ch == '\\n') {\n ch = ';';\n }\n if (ch == ' ' || ch == '\\t' || ch == ';') {\n if (sToken) {\n aTokens.push(sToken);\n sToken = \"\";\n }\n if (ch == ';' && aTokens.length) {\n aCommands.push(aTokens);\n aTokens = [];\n }\n continue;\n }\n }\n sToken += ch;\n }\n if (sToken) {\n aTokens.push(sToken);\n }\n if (aTokens.length) {\n aCommands.push(aTokens);\n }\n return aCommands;\n }\n\n /**\n * Component.processScript(idMachine, sScript)\n *\n * @param {string} idMachine\n * @param {string} [sScript]\n * @return {boolean}\n */\n static processScript(idMachine, sScript)\n {\n var fSuccess = false;\n idMachine += \".machine\";\n if (!sScript) {\n delete Component.commands[idMachine];\n fSuccess = true;\n }\n else if (typeof sScript == \"string\" && !Component.commands[idMachine]) {\n fSuccess = true;\n Component.commands[idMachine] = Component.getScriptCommands(sScript);\n if (!Component.processCommands(idMachine)) {\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * Component.processCommands(idMachine)\n *\n * @param {string} idMachine\n * @return {boolean}\n */\n static processCommands(idMachine)\n {\n var fSuccess = true;\n var aCommands = Component.commands[idMachine];\n\n // var dbg = Component.getComponentByType(\"Debugger\", idMachine);\n\n while (aCommands && aCommands.length) {\n\n var aTokens = aCommands.splice(0, 1)[0];\n var sCommand = aTokens[0];\n\n /*\n * It's possible to route this output to the Debugger window with dbg.println()\n * instead, but it's a bit too confusing mingling script output in a window that\n * already mingles Debugger and machine output.\n */\n Component.println(aTokens.join(' '), Component.PRINT.SCRIPT);\n\n var fnCallReady = null;\n if (Component.asyncCommands.indexOf(sCommand) >= 0) {\n fnCallReady = function processNextCommand() {\n return function() {\n Component.processCommands(idMachine);\n }\n }();\n }\n\n var fnCommand = Component.globalCommands[sCommand];\n if (fnCommand) {\n if (!fnCallReady) {\n fSuccess = fnCommand(aTokens[1], aTokens[2], aTokens[3]);\n } else {\n if (!fnCommand(fnCallReady, aTokens[1], aTokens[2], aTokens[3])) break;\n }\n }\n else {\n fSuccess = false;\n var component = Component.getComponentByType(aTokens[1], idMachine);\n if (component) {\n fnCommand = Component.componentCommands[sCommand];\n if (fnCommand) {\n fSuccess = fnCommand(component, aTokens[2], aTokens[3]);\n }\n else {\n var exports = component['exports'];\n if (exports) {\n fnCommand = exports[sCommand];\n if (fnCommand) {\n fSuccess = true;\n if (!fnCallReady) {\n fSuccess = fnCommand.call(component, aTokens[2], aTokens[3]);\n } else {\n if (!fnCommand.call(component, fnCallReady, aTokens[2], aTokens[3])) break;\n }\n }\n }\n }\n }\n }\n\n if (!fSuccess) {\n Component.alertUser(\"Script error: '\" + sCommand + \"' command \" + (fnCommand? \" failed\" : \" not recognized\"));\n break;\n }\n }\n\n if (aCommands && !aCommands.length) {\n delete Component.commands[idMachine];\n }\n\n return fSuccess;\n }\n\n /**\n * Component.scriptAlert(sMessage)\n *\n * @param {string} sMessage\n * @return {boolean}\n */\n static scriptAlert(sMessage)\n {\n Component.alertUser(sMessage);\n return true;\n }\n\n /**\n * Component.scriptSelect(component, sBinding, sValue)\n *\n * @param {Component} component\n * @param {string} sBinding\n * @param {string} sValue\n * @return {boolean}\n */\n static scriptSelect(component, sBinding, sValue)\n {\n var fSuccess = false;\n var aBindings = component['bindings'];\n var control = aBindings[sBinding];\n if (control) {\n for (var i = 0; i < control.options.length; i++) {\n if (control.options[i].textContent == sValue) {\n if (control.selectedIndex != i) {\n control.selectedIndex = i;\n }\n fSuccess = true;\n break;\n }\n }\n }\n return fSuccess;\n }\n\n /**\n * Component.scriptSleep(fnCallback, sDelay)\n *\n * @param {function()} fnCallback\n * @param {string} sDelay (in milliseconds)\n * @return {boolean}\n */\n static scriptSleep(fnCallback, sDelay)\n {\n setTimeout(fnCallback, +sDelay);\n return false;\n }\n\n /**\n * toString()\n *\n * @this {Component}\n * @return {string}\n */\n toString()\n {\n return (this.name? this.name : (this.id || this.type));\n }\n\n /**\n * getMachineNum()\n *\n * @this {Component}\n * @return {number} unique machine number\n */\n getMachineNum()\n {\n var nMachine = 1;\n if (this.idMachine) {\n var aDigits = this.idMachine.match(/\\d+/);\n if (aDigits !== null)\n nMachine = parseInt(aDigits[0], 10);\n }\n return nMachine;\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * Component's setBinding() method is intended to be overridden by subclasses.\n *\n * @this {Component}\n * @param {string|null} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, 'print')\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n switch (sBinding) {\n case 'clear':\n if (!this.bindings[sBinding]) {\n this.bindings[sBinding] = control;\n control.onclick = (function(component) {\n return function clearControl() {\n if (component.bindings['print']) {\n component.bindings['print'].value = \"\";\n }\n };\n }(this));\n }\n return true;\n case 'print':\n if (!this.bindings[sBinding]) {\n var controlTextArea = /** @type {HTMLTextAreaElement} */(control);\n this.bindings[sBinding] = controlTextArea;\n /**\n * Override this.notice() with a replacement function that eliminates the Component.alertUser() call.\n *\n * @this {Component}\n * @param {string} s\n * @return {boolean}\n */\n this.notice = function noticeControl(s /*, fPrintOnly, id*/) {\n this.println(s, this.type);\n return true;\n };\n /*\n * This was added for Firefox (Safari will clear the <textarea> on a page reload, but Firefox does not).\n */\n controlTextArea.value = \"\";\n this.print = function(control) {\n return function printControl(s) {\n Component.appendControl(control, s);\n };\n }(controlTextArea);\n this.println = function(component, control) {\n return function printlnControl(s, type, id) {\n if (!s) s = \"\";\n if (type != Component.PRINT.PROGRESS || s.slice(-3) != \"...\") {\n if (type) s = type + \": \" + s;\n Component.appendControl(control, s + '\\n');\n } else {\n Component.replaceControl(control, s, s + '.');\n }\n if (!COMPILED && window && window.console) Component.println(s, type, id);\n };\n }(this, controlTextArea);\n }\n return true;\n default:\n return false;\n }\n }\n\n /**\n * log(s, type)\n *\n * For diagnostic output only.\n *\n * WARNING: Even though this function's body is completely wrapped in DEBUG, that won't prevent the Closure Compiler\n * from including it, so all calls must still be prefixed with \"if (DEBUG) ....\". For this reason, the class method,\n * Component.log(), is preferred, because the compiler IS smart enough to remove those calls.\n *\n * @this {Component}\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n log(s, type)\n {\n if (!COMPILED) {\n Component.log(s, type || this.id || this.type);\n }\n }\n\n /**\n * assert(f, s)\n *\n * Verifies conditions that must be true (for DEBUG builds only).\n *\n * WARNING: Make sure you preface all calls to this.assert() with \"if (DEBUG)\", because unlike Component.assert(),\n * the Closure Compiler can't be sure that this instance method hasn't been overridden, so it refuses to treat it as\n * dead code in non-DEBUG builds.\n *\n * TODO: Add a task to the build process that \"asserts\" there are no instances of \"assertion failure\" in RELEASE builds.\n *\n * @this {Component}\n * @param {boolean|number} f is the expression asserted to be true\n * @param {string} [s] is a description of the assertion to be displayed or logged on failure\n */\n assert(f, s)\n {\n if (DEBUG) {\n if (!f) {\n s = \"assertion failure in \" + (this.id || this.type) + (s? \": \" + s : \"\");\n if (DEBUGGER && this.dbg) {\n this.dbg.stopCPU();\n /*\n * Why do we throw an Error only to immediately catch and ignore it? Simply to give\n * any IDE the opportunity to inspect the application's state. Even when the IDE has\n * control, you should still be able to invoke Debugger commands from the IDE's REPL,\n * using the global function that the Debugger constructor defines; eg:\n *\n * pcx86('r')\n * pcx86('dw 0:0')\n * pcx86('h')\n * ...\n *\n * If you have no desire to stop on assertions, consider this a no-op. However, another\n * potential benefit of creating an Error object is that, for browsers like Chrome, we get\n * a stack trace, too.\n */\n try {\n throw new Error(s);\n } catch(e) {\n this.println(e.stack || e.message);\n }\n return;\n }\n this.log(s);\n throw new Error(s);\n }\n }\n }\n\n /**\n * print(s)\n *\n * Components using this.print() should wait until after their constructor has run to display any messages, because\n * if a Control Panel has been loaded, its override will not take effect until its own constructor has run.\n *\n * @this {Component}\n * @param {string} s\n */\n print(s)\n {\n Component.print(s);\n }\n\n /**\n * println(s, type, id)\n *\n * Components using this.println() should wait until after their constructor has run to display any messages, because\n * if a Control Panel has been loaded, its override will not take effect until its own constructor has run.\n *\n * @this {Component}\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n * @param {string} [id] is the caller's ID, if any\n */\n println(s, type, id)\n {\n Component.println(s, type, id || this.id);\n }\n\n /**\n * status(s)\n *\n * status() is like println() but it also includes information about the component (ie, the component type),\n * which is why there is no corresponding Component.status() function.\n *\n * @this {Component}\n * @param {string} s is the message text\n */\n status(s)\n {\n this.println(this.type + \": \" + s);\n }\n\n /**\n * notice(s, fPrintOnly, id)\n *\n * notice() is like println() but implies a need for user notification, so we alert() as well; however, if this.println()\n * is overridden, this.notice will be replaced with a similar override, on the assumption that the override is taking care\n * of alerting the user.\n *\n * @this {Component}\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n * @return {boolean}\n */\n notice(s, fPrintOnly, id)\n {\n if (!fPrintOnly) {\n /*\n * See if the associated computer, if any, is \"unloading\"....\n */\n var computer = Component.getComponentByType(\"Computer\", this.id);\n if (computer && computer.flags.unloading) {\n console.log(\"ignoring notice during unload: \" + s);\n return false;\n }\n }\n Component.notice(s, fPrintOnly, id || this.type);\n return true;\n }\n\n /**\n * setError(s)\n *\n * Set a fatal error condition\n *\n * @this {Component}\n * @param {string} s describes a fatal error condition\n */\n setError(s)\n {\n this.flags.error = true;\n this.notice(s); // TODO: Any cases where we should still prefix this string with \"Fatal error: \"?\n }\n\n /**\n * clearError()\n *\n * Clear any fatal error condition\n *\n * @this {Component}\n */\n clearError() {\n this.flags.error = false;\n }\n\n /**\n * isError()\n *\n * Report any fatal error condition\n *\n * @this {Component}\n * @return {boolean} true if a fatal error condition exists, false if not\n */\n isError()\n {\n if (this.flags.error) {\n this.println(this.toString() + \" error\");\n return true;\n }\n return false;\n }\n\n /**\n * isReady(fnReady)\n *\n * Return the \"ready\" state of the component; if the component is not ready, it will queue the optional\n * notification function, otherwise it will immediately call the notification function, if any, without queuing it.\n *\n * NOTE: Since only the Computer component actually cares about the \"readiness\" of other components, the so-called\n * \"queue\" of notification functions supports exactly one function. This keeps things nice and simple.\n *\n * @this {Component}\n * @param {function()} [fnReady]\n * @return {boolean} true if the component is in a \"ready\" state, false if not\n */\n isReady(fnReady)\n {\n if (fnReady) {\n if (this.flags.ready) {\n fnReady();\n } else {\n if (MAXDEBUG) this.log(\"NOT ready\");\n this.fnReady = fnReady;\n }\n }\n return this.flags.ready;\n }\n\n /**\n * setReady(fReady)\n *\n * Set the \"ready\" state of the component to true, and call any queued notification functions.\n *\n * @this {Component}\n * @param {boolean} [fReady] is assumed to indicate \"ready\" unless EXPLICITLY set to false\n */\n setReady(fReady)\n {\n if (!this.flags.error) {\n this.flags.ready = (fReady !== false);\n if (this.flags.ready) {\n if (MAXDEBUG /* || this.name */) this.log(\"ready\");\n var fnReady = this.fnReady;\n this.fnReady = null;\n if (fnReady) fnReady();\n }\n }\n }\n\n /**\n * isBusy(fCancel)\n *\n * Return the \"busy\" state of the component\n *\n * @this {Component}\n * @param {boolean} [fCancel] is set to true to cancel a \"busy\" state\n * @return {boolean} true if \"busy\", false if not\n */\n isBusy(fCancel)\n {\n if (this.flags.busy) {\n if (fCancel) {\n this.flags.busyCancel = true;\n } else if (fCancel === undefined) {\n this.println(this.toString() + \" busy\");\n }\n }\n return this.flags.busy;\n }\n\n /**\n * setBusy(fBusy)\n *\n * Update the current busy state; if a busyCancel request is pending, it will be honored now.\n *\n * @this {Component}\n * @param {boolean} fBusy\n * @return {boolean}\n */\n setBusy(fBusy)\n {\n if (this.flags.busyCancel) {\n this.flags.busy = false;\n this.flags.busyCancel = false;\n return false;\n }\n if (this.flags.error) {\n this.println(this.toString() + \" error\");\n return false;\n }\n this.flags.busy = fBusy;\n return this.flags.busy;\n }\n\n /**\n * powerUp(fSave)\n *\n * @this {Component}\n * @param {Object|null} data\n * @param {boolean} [fRepower] is true if this is \"repower\" notification\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n this.flags.powered = true;\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Component}\n * @param {boolean} fSave\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n if (fShutdown) this.flags.powered = false;\n return true;\n }\n\n /**\n * messageEnabled(bitsMessage)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n *\n * @this {Component}\n * @param {number} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n * @return {boolean} true if all specified message enabled, false if not\n */\n messageEnabled(bitsMessage = 0)\n {\n if (DEBUGGER && this.dbg) {\n if (this !== this.dbg) {\n bitsMessage = bitsMessage || this.bitsMessage;\n }\n var bitsEnabled = this.dbg.bitsMessage & bitsMessage;\n /*\n * This next \"bit\" of logic is for PCx86 and any other machine where we've expanded the set of\n * messages by reusing bits in the low nibbles in combination with different bits in the high nibble.\n * If the input bits adhere to that format, then the mask we just produced must adhere to it as well,\n * and if it doesn't, zero the mask, ensuring that the test will return false.\n */\n if ((bitsMessage & 0xf0000000) && (bitsMessage & 0x0fffffff)) {\n if (!(bitsEnabled & 0xf0000000) || !(bitsEnabled & 0x0fffffff)) bitsEnabled = 0;\n }\n if (bitsMessage && bitsEnabled === bitsMessage) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * printf(format, ...args)\n *\n * @this {Component}\n * @param {string} format\n * @param {...} args\n */\n printf(format, ...args)\n {\n if (DEBUGGER && this.dbg) {\n if (this.messageEnabled()) {\n let s = Str.sprintf(format, ...args);\n /*\n * Since dbg.message() calls println(), we strip any ending linefeed.\n * \n * We could bypass the Debugger and go straight to this.print(), but we would lose\n * the benefits of debugger messages (eg, automatic buffering, halting, yielding, etc).\n */\n if (s.slice(-1) == '\\n') s = s.slice(0, -1);\n this.dbg.message(s);\n }\n }\n }\n\n /**\n * printMessage(sMessage, bitsMessage, fAddress)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n * If bitsMessage is true, the message is displayed regardless.\n *\n * @this {Component}\n * @param {string} sMessage is any caller-defined message string\n * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n * @param {boolean} [fAddress] is true to display the current address\n */\n printMessage(sMessage, bitsMessage, fAddress)\n {\n if (DEBUGGER && this.dbg) {\n if (bitsMessage === true || this.messageEnabled(bitsMessage | 0)) {\n this.dbg.message(sMessage, fAddress);\n }\n }\n }\n\n /**\n * printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n * If bitsMessage is true, the message is displayed as long as MESSAGE.PORT is enabled.\n *\n * @this {Component}\n * @param {number} port\n * @param {number|null} bOut if an output operation\n * @param {number|null} [addrFrom]\n * @param {string|null} [name] of the port, if any\n * @param {number|null} [bIn] is the input value, if known, on an input operation\n * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n */\n printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage)\n {\n if (DEBUGGER && this.dbg) {\n if (bitsMessage === true) {\n bitsMessage = 0;\n } else if (bitsMessage == null) {\n bitsMessage = this.bitsMessage;\n }\n this.dbg.messageIO(this, port, bOut, addrFrom, name, bIn, bitsMessage);\n }\n }\n}\n\n/*\n * Types recognized and supported by selected functions (eg, Computer.getMachineParm())\n */\nComponent.TYPE = {\n NUMBER: \"number\",\n OBJECT: \"object\",\n STRING: \"string\"\n};\n\n/*\n * These are the standard PRINT values you can pass as an optional argument to println(); in reality,\n * you can pass anything you want, because they are simply prepended to the message, although PROGRESS\n * messages may also be merged with earlier similar messages to keep the output buffer under control.\n */\nComponent.PRINT = {\n ERROR: \"error\",\n NOTICE: \"notice\",\n PROGRESS: \"progress\",\n SCRIPT: \"script\",\n WARNING: \"warning\"\n};\n\n/*\n * Every component created on the current page is recorded in this array (see Component.add()),\n * enabling any component to locate another component by ID (see Component.getComponentByID())\n * or by type (see Component.getComponentByType()).\n *\n * Every machine on the page are now recorded as well, by their machine ID. We then record the\n * various resources used by that machine.\n *\n * Includes a fallback for non-browser-based environments (ie, Node). TODO: This will need to be\n * tailored to Node, probably using the global object instead of the window object, if we ever want\n * to support multi-machine configs in that environment.\n */\nif (window) {\n if (!window['PCjs']) window['PCjs'] = {};\n if (!window['PCjs']['Machines']) window['PCjs']['Machines'] = {};\n if (!window['PCjs']['Components']) window['PCjs']['Components'] = [];\n if (!window['PCjs']['Commands']) window['PCjs']['Commands'] = {};\n}\nComponent.machines = window? window['PCjs']['Machines'] : {};\nComponent.components = window? window['PCjs']['Components'] : [];\nComponent.commands = window? window['PCjs']['Commands'] : {};\n\nComponent.asyncCommands = [\n 'hold', 'sleep', 'wait'\n];\nComponent.globalCommands = {\n 'alert': Component.scriptAlert,\n 'sleep': Component.scriptSleep\n};\nComponent.componentCommands = {\n 'select': Component.scriptSelect\n};\nComponent.printBuffer = \"\";\n\n/*\n * The following polyfills provide ES5 functionality that's missing in older browsers (eg, IE8),\n * allowing PCjs apps to run without slamming into exceptions; however, due to the lack of HTML5 canvas\n * support in those browsers, all you're likely to see are \"soft\" errors (eg, \"Missing <canvas> support\").\n *\n * Perhaps we can implement a text-only faux video display for a fun retro-browser experience someday.\n *\n * TODO: Come up with a better place to put these polyfills. We will likely have more if we decide to\n * make the leap from ES5 to ES6 features.\n */\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf\n */\nif (!Array.prototype.indexOf) {\n Array.prototype.indexOf = function(obj, start) {\n for (var i = (start || 0), j = this.length; i < j; i++) {\n if (this[i] === obj) { return i; }\n }\n return -1;\n }\n}\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray\n */\nif (!Array.isArray) {\n Array.isArray = function(arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n };\n}\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind\n */\nif (!Function.prototype.bind) {\n Function.prototype.bind = function(obj) {\n if (typeof this != \"function\") {\n // Closest thing possible to the ECMAScript 5 internal IsCallable function\n throw new TypeError(\"Function.prototype.bind: non-callable object\");\n }\n var args = Array.prototype.slice.call(arguments, 1);\n var fToBind = this;\n var fnNOP = /** @constructor */ (function() {});\n var fnBound = function() {\n return fToBind.apply(this instanceof fnNOP && obj? this : obj, args.concat(/** @type {Array} */(Array.prototype.slice.call(arguments))));\n };\n fnNOP.prototype = this.prototype;\n fnBound.prototype = new fnNOP();\n return fnBound;\n };\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/defines.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @define {string}\n */\nvar APPCLASS = \"pdp11\"; // this @define is the default application class (eg, \"pcx86\", \"c1pjs\")\n\n/**\n * APPNAME is used more for display purposes than anything else now. APPCLASS is what matters in terms\n * of folder and file names, CSS styles, etc.\n *\n * @define {string}\n */\nvar APPNAME = \"PDPjs\"; // this @define is the default application name (eg, \"PCx86\", \"C1Pjs\")\n\n/**\n * WARNING: DEBUGGER needs to accurately reflect whether or not the Debugger component is (or will be) loaded.\n * In the compiled case, we rely on the Closure Compiler to override DEBUGGER as appropriate. When it's *false*,\n * nearly all of debugger.js will be conditionally removed by the compiler, reducing it to little more than a\n * \"type skeleton\", which also solves some type-related warnings we would otherwise have if we tried to remove\n * debugger.js from the compilation process altogether.\n *\n * However, when we're in \"development mode\" and running uncompiled code in debugger-less configurations,\n * I would like to skip loading debugger.js altogether. When doing that, we must ALSO arrange for an additional file\n * (nodebugger.js) to be loaded immediately after this file, which *explicitly* overrides DEBUGGER with *false*.\n *\n * @define {boolean}\n */\nvar DEBUGGER = true; // this @define is overridden by the Closure Compiler to remove Debugger-related support\n\n/**\n * BYTEARRAYS is a Closure Compiler compile-time option that allocates an Array of numbers for every Memory block,\n * where each a number represents ONE byte; very wasteful, but potentially slightly faster.\n *\n * See the Memory component for details.\n *\n * @define {boolean}\n */\nvar BYTEARRAYS = false;\n\n/**\n * TYPEDARRAYS enables use of typed arrays for Memory blocks. This used to be a compile-time-only option, but I've\n * added Memory access functions for typed arrays (see MemoryPDP11.afnTypedArray), so support can be enabled dynamically now.\n *\n * See the Memory component for details.\n */\nvar TYPEDARRAYS = (typeof ArrayBuffer !== 'undefined');\n\n/**\n * MEMFAULT forces the Memory interfaces to signal a CPU fault when a word is accessed using an odd (unaligned) address.\n *\n * Since PDPjs inherited its Bus component from PCx86, it included support for both aligned and unaligned word accesses\n * by default. However, the PDP-11 adds a wrinkle: when an odd address is used to access a memory word, a BUS trap\n * must be generated. Note that odd IOPAGE word accesses are fine; this only affects the Memory component.\n *\n * When the MMU is enabled, these checks may also be performed at a higher level, eliminating the need for them at the\n * physical memory level.\n */\nvar MEMFAULT = true;\n\n/**\n * WORDBUS turns off support for unaligned memory words. Whereas MEMFAULT necessarily slows down memory word accesses\n * slightly, WORDBUS is able to speed them up slightly, by assuming that all word accesses (which didn't fault) must be\n * aligned. This affects all word accesses, even IOPAGE accesses, because it also eliminates cross-block boundary checks.\n *\n * Don't worry that the source code looks MORE complicated rather than LESS with the additional MEMFAULT and WORDBUS checks,\n * because the Closure Compiler eliminates those checks and throws away the (unreachable) code blocks that deal with unaligned\n * accesses.\n */\nvar WORDBUS = true;\n\n/*\n * Combine all the shared globals and machine-specific globals into one machine-specific global object,\n * which all machine components should start using; eg: \"if (PDP11.DEBUG) ...\" instead of \"if (DEBUG) ...\".\n */\nvar PDP11 = {\n APPCLASS: APPCLASS,\n APPNAME: APPNAME,\n APPVERSION: APPVERSION, // shared\n BYTEARRAYS: BYTEARRAYS,\n COMPILED: COMPILED, // shared\n CSSCLASS: CSSCLASS, // shared\n DEBUG: DEBUG, // shared\n DEBUGGER: DEBUGGER,\n MAXDEBUG: MAXDEBUG, // shared\n PRIVATE: PRIVATE, // shared\n TYPEDARRAYS:TYPEDARRAYS,\n MEMFAULT: MEMFAULT,\n WORDBUS: WORDBUS,\n SITEHOST: SITEHOST, // shared\n XMLVERSION: XMLVERSION, // shared\n\n /*\n * CPU model numbers (supported)\n *\n * The 11/20 includes the 11/10, which is not identified separately because there was\n * nothing functionally different about it.\n *\n * The 11/40 added the MODE bits to the PSW (but only KERNEL=00 and USER=11) and 18-bit\n * addressing via an MMU; there was still only one register set.\n *\n * The 11/45 added REGSET bit to the PSW (to support a second register set), SUPER=01\n * mode to the existing KERNEL=00 and USER=11 modes, separate I/D spaces, and other MMU\n * extensions (eg, MMR1 and MMR3).\n *\n * The 11/70 added 22-bit addressing and corresponding extensions to the MMU.\n */\n MODEL_1120: 1120,\n MODEL_1140: 1140,\n MODEL_1145: 1145,\n MODEL_1170: 1170,\n\n /*\n * This constant is used to mark points in the code where the physical address being returned\n * is invalid and should not be used.\n *\n * In a 32-bit CPU, -1 (ie, 0xffffffff) could actually be a valid address, so consider changing\n * ADDR_INVALID to NaN or null (which is also why all ADDR_INVALID tests should use strict equality\n * operators).\n *\n * The main reason I'm NOT using NaN or null now is my concern that, by mixing non-numbers\n * (specifically, values outside the range of signed 32-bit integers), performance may suffer.\n *\n * WARNING: Like many of the properties defined here, ADDR_INVALID is a common constant, which the\n * Closure Compiler will happily inline (with or without @const annotations; in fact, I've yet to\n * see a @const annotation EVER improve automatic inlining). However, if you don't make ABSOLUTELY\n * certain that this file is included BEFORE the first reference to any of these properties, that\n * automatic inlining will no longer occur.\n */\n ADDR_INVALID: -1,\n /*\n * Processor modes\n */\n MODE: {\n KERNEL: 0x0, // 11/40 and higher\n SUPER: 0x1, // 11/45 and higher\n UNUSED: 0x2,\n USER: 0x3, // 11/40 and higher\n MASK: 0x3\n },\n /*\n * Processor Status Word (stored in regPSW) at 177776\n */\n PSW: {\n CF: 0x0001, // bit 0 (000001) Carry Flag\n VF: 0x0002, // bit 1 (000002) Overflow Flag (aka OF on Intel processors)\n ZF: 0x0004, // bit 2 (000004) Zero Flag\n NF: 0x0008, // bit 3 (000010) Negative Flag (aka SF -- Sign Flag -- on Intel processors)\n TF: 0x0010, // bit 4 (000020) Trap Flag\n PRI: 0x00E0, // bits 5-7 (000340) Priority\n UNUSED: 0x0700, // bits 8-10 (003400) UNUSED\n /*\n * The REGSET bit (and the alternate register set stored in regsAlt) came into existence\n * with the 11/45; (ie, they were not present on the 11/10, 11/20, or 11/40).\n */\n REGSET: 0x0800, // bit 11 (004000) Register Set\n /*\n * The MODE bits came into existence with the 11/40 (eg, not present on the 11/10 or 11/20).\n */\n PMODE: 0x3000, // bits 12-13 (030000) Prev Mode (see PDP11.MODE)\n CMODE: 0xC000, // bits 14-15 (140000) Curr Mode (see PDP11.MODE)\n SHIFT: {\n CF: 0,\n VF: 1,\n ZF: 2,\n NF: 3,\n TF: 4,\n PRI: 5,\n PMODE: 12,\n CMODE: 14\n }\n },\n /*\n * Program Interrupt Register (stored in regPIR) at 177772\n *\n * The PIA bits at 5-7 are designed to align with PRI bits 5-7 in the PSW.\n */\n PIR: {\n BITS: 0xFE00, // bits 9-15 correspond to interrupt requests 1-7\n PIA: 0x00EE, // the PIA bits contain two copies of the corresponding interrupt request priority\n PIA_INC: 0x0022, // both sets of PIA bits can be incremented with this constant\n SHIFT: {\n BITS: 9\n }\n },\n /*\n * PDP-11 trap vectors\n */\n TRAP: {\n UNDEFINED: 0x00, // 000 (reserved)\n BUS: 0x04, // 004 unaligned address, non-existent memory, illegal instruction, etc\n RESERVED: 0x08, // 010 reserved instructions\n BPT: 0x0C, // 014 BPT: breakpoint trap (trace)\n IOT: 0x10, // 020 IOT: input/output trap\n PF: 0x14, // 024 power fail\n EMT: 0x18, // 030 EMT: emulator trap\n TRAP: 0x1C, // 034 TRAP instruction\n PIRQ: 0xA0, // 240 PIRQ: program interrupt request\n MMU: 0xA8 // 250 MMU: aborts and traps\n },\n /*\n * PDP-11 trap reasons; the reason may also be a non-negative address indicating a BUS memory error\n * (unaligned address or non-existent memory). Any reason >= RED (which includes BUS memory errors) generate\n * immediate (thrown) traps, as they are considered ABORTs; the rest generate synchronous traps.\n */\n REASON: {\n PANIC: -1, // immediate halt (internal error)\n ABORT: -2, // immediate MMU fault\n ILLEGAL: -3, // immediate invalid opcode (BUS)\n RED: -4, // immediate stack overflow fault (BUS)\n YELLOW: -5, // deferred stack overflow fault (BUS)\n FAULT: -6, // deferred MMU fault\n TRACE: -7, // deferred TF fault (BPT)\n HALT: -8, // illegal HALT (BUS)\n OPCODE: -9, // opcode-generated trap (eg, BPT, EMT, IOT, TRAP, or RESERVED opcode)\n INTERRUPT: -10, // device-generated trap (vector is device-specific)\n },\n REASONS: [\n \"UNKNOWN\",\n \"PANIC\",\n \"ABORT\",\n \"ILLEGAL\",\n \"RED\",\n \"YELLOW\",\n \"FAULT\",\n \"TRACE\",\n \"HALT\",\n \"OPCODE\",\n \"INTERRUPT\"\n ],\n /*\n * Assorted common opcodes\n */\n OPCODE: {\n HALT: 0x0000,\n WAIT: 0x0001,\n BPT: 0x0003,\n IOT: 0x0004,\n JSR_OP: 0x0800,\n JSR_MASK: 0xFE00,\n SOB_OP: 0x7E00,\n SOB_MASK: 0xFE00,\n EMT_OP: 0x8800,\n EMT_MASK: 0xFF00,\n TRAP_OP: 0x8900,\n TRAP_MASK: 0xFF00,\n INVALID: 0xFFFF // far from the only invalid opcode, just a KNOWN invalid opcode\n },\n /*\n * Internal operation state flags\n */\n OPFLAG: {\n IRQ_DELAY: 0x0001, // incremented until it becomes IRQ (set by SPL and traps)\n IRQ: 0x0002, // time to call checkInterrupts()\n IRQ_MASK: 0x0003,\n DEBUGGER: 0x0004, // set if the Debugger wants to perform checks\n WAIT: 0x0008, // WAIT operation in progress\n PRESERVE: 0x000F, // OPFLAG bits to preserve prior to the next instruction\n TRAP_TF: 0x0010, // aka PDP11.PSW.TF (WARNING: do not change this bit, or you will likely break opRTI())\n TRAP_SP: 0x0020, // set for a deferred BUS trap (due to a \"yellow\" stack overflow condition)\n TRAP_MMU: 0x0040,\n TRAP_MASK: 0x0070,\n TRAP_LAST: 0x0080, // set if last operation was a trap (see trapLast for the vector, and trapReason for the reason)\n TRAP_RED: 0x0100, // set whenever a RED trap occurs, used to catch double RED traps (time to PANIC)\n },\n /*\n * Opcode reg (opcode bits 2-0)\n */\n OPREG: {\n MASK: 0x07\n },\n /*\n * Opcode modes (opcode bits 5-3)\n */\n OPMODE: {\n REG: 0x00, // REGISTER (register is operand)\n REGD: 0x08, // REGISTER DEFERRED (register is address of operand)\n POSTINC: 0x10, // AUTO-INCREMENT (register is address of operand, register incremented)\n POSTINCD: 0x18, // AUTO-INCREMENT DEFERRED (register is address of address of operand, register incremented)\n PREDEC: 0x20, // AUTO-DECREMENT (register decremented, register is address of operand)\n PREDECD: 0x28, // AUTO-DECREMENT DEFERRED (register decremented, register is address of address of operand)\n INDEX: 0x30, // INDEX (register + next word is address of operand)\n INDEXD: 0x38, // INDEX DEFERRED (register + next word is address of address of operand)\n MASK: 0x38,\n SHIFT: 3\n },\n DSTMODE: {\n REG: 0x0007,\n MODE: 0x0038,\n MASK: 0x003F,\n SHIFT: 0\n },\n SRCMODE: {\n REG: 0x01C0,\n MODE: 0x0E00,\n MASK: 0x0FC0,\n SHIFT: 6\n },\n REG: {\n SP: 6,\n PC: 7,\n },\n /*\n * Internal memory access flags\n */\n ACCESS: {\n WORD: 0x00,\n BYTE: 0x01,\n READ: 0x02,\n WRITE: 0x04,\n UPDATE: 0x06,\n VIRT: 0x08, // getVirtualByMode() leaves bit 17 clear if this is set (otherwise the caller would have to clear it again)\n ISPACE: 0x00000,\n DSPACE: 0x10000 // getVirtualByMode() sets bit 17 in any 16-bit virtual address that refers to D space (as opposed to I space)\n },\n /*\n * Internal flags passed to writeDstByte()\n *\n * The BYTE and SBYTE values have been chosen so that they can be used directly as masks.\n */\n WRITE: {\n BYTE: 0xff, // write byte normally\n SBYTE: 0xffff // sign-extend byte to word\n },\n CPUERR: { // 177766\n RED: 0x0004, // 000004 red zone stack limit\n YELLOW: 0x0008, // 000010 yellow zone stack limit\n TIMEOUT: 0x0010, // 000020 UNIBUS timeout error\n NOMEMORY: 0x0020, // 000040 non-existent memory error\n ODDADDR: 0x0040, // 000100 odd word address error (as in non-even, not strange)\n BADHALT: 0x0080 // 000200 HALT attempted in USER or SUPER modes\n },\n MMR0: { // 177572\n ENABLED: 0x0001, // 000001 address relocation enabled\n PAGE_NUM: 0x000E, // 000016 page number of last fault\n PAGE_D: 0x0010, // 000020 last fault occurred in D space (11/45 and 11/70)\n PAGE: 0x001E, // 000176 (all of the PAGE bits)\n MODE: 0x0060, // 000140 processor mode as of last fault\n COMPLETED: 0x0080, // 000200 last instruction completed (R/O) (11/70)\n MAINT: 0x0100, // 000400 only destination mode references will be relocated\n MMU_TRAPS: 0x0200, // 001000 enable MMU traps (11/70)\n UNUSED: 0x0C00, // 006000\n TRAP_MMU: 0x1000, // 010000 trap: MMU (11/70)\n ABORT_RO: 0x2000, // 020000 abort: read-only\n ABORT_PL: 0x4000, // 040000 abort: page length\n ABORT_NR: 0x8000, // 100000 abort: non-resident\n ABORT: 0xE000, // 160000 (all of the ABORT bits)\n UPDATE: 0xF0FE, // Includes all of: ABORT, TRAP, COMPLETED, MODE, and PAGE bits\n SHIFT: {\n PAGE: 1,\n MODE: 5\n }\n },\n MMR1: { // 177574: general purpose auto-inc/auto-dec register (11/45 and 11/70)\n REG1_NUM: 0x0007, //\n REG1_DELTA: 0x00F8, //\n REG2_NUM: 0x0700, //\n REG2_DELTA: 0xF800 //\n },\n MMR2: { // 177576: virtual program counter register\n },\n MMR3: { // 172516: mapping register (11/45 and 11/70)\n USER_D: 0x0001, // (000001)\n SUPER_D: 0x0002, // (000002)\n KERNEL_D: 0x0004, // (000004)\n MMU_22BIT: 0x0010, // (000020)\n UNIBUS_MAP: 0x0020 // (000040) UNIBUS map relocation enabled\n },\n PDR: {\n ACF: {\n NR: 0x0, // non-resident, abort all accesses\n RO1: 0x1, // read-only, abort on write attempt, memory management trap on read (11/70)\n RO: 0x2, // read-only, abort on write attempt\n U1: 0x3, // unused, abort all accesses--reserved for future use\n RW1: 0x4, // read/write, memory management trap upon completion of a read or write\n RW2: 0x5, // read/write, memory management trap upon completion of a write (11/70)\n RW: 0x6, // read/write, no system trap/abort action\n U2: 0x7, // unused, abort all accesses--reserved for future use\n MASK: 0x7\n },\n ED: 0x0008, // expansion direction (if set, the page expands downward from block number 127)\n UNUSED: 0x0030,\n MODIFIED: 0x0040, // page has been written (bit cleared when either PDR or PAR is written)\n ACCESSED: 0x0080, // page has been accessed (bit cleared when either PDR or PAR is written) (11/70)\n PLF: 0x7F00, // page length field\n BC: 0x8000 // bypass cache (11/44 only)\n },\n /*\n * Assorted special (UNIBUS) addresses\n *\n * Within the PDP-11/45's 18-bit address space, of the 0x40000 possible addresses (256Kb), the top 0x2000\n * (8Kb) is called the IOPAGE and is reserved for CPU and I/O registers. The IOPAGE spans 0x3E000-0x3FFFF.\n *\n * Within the PDP-11/70's 22-bit address space, of the 0x400000 possible addresses (4Mb), the top 0x20000\n * (256Kb) is mapped to the UNIBUS (not physical memory), and as before, the top 0x2000 (8Kb) of that is\n * mapped to the IOPAGE.\n *\n * To map 18-bit UNIBUS addresses to 22-bit physical addresses, the 11/70 uses a UNIBUS relocation map.\n * It consists of 31 double-word registers that each hold a 22-bit base address. When UNIBUS relocation\n * is enabled, the top 5 bits of an address select one of the 31 mapping registers, and the bottom 13 bits\n * are then added to the contents of the selected mapping register.\n *\n * ES6 ALERT: By using octal constants, I'm finally dipping my toe into ES6 (aka ECMAScript 2015) waters.\n * You'll even see a few binary constants below, too. If you're loading this raw source code into your browser,\n * then by now (2016) you're almost certainly using an ES6-aware browser. Production sites should be using code\n * compiled by Google's Closure Compiler, which we configure to produce code that's backward-compatible with ES5\n * (for example, all binary, octal, and hex constants are converted to decimal values).\n *\n * For more details: https://github.com/google/closure-compiler/wiki/ECMAScript6\n */\n UNIBUS: { //16-bit 18-bit 22-bit Hex Description\n UNIMAP: 0o170200, // UNIBUS Mapping Registers (0-31) 64 words (ends at 0o170372)\n SIPDR0: 0o172200, // Supervisor I Page Descriptor Register 0\n SIPDR1: 0o172202, // Supervisor I Page Descriptor Register 1\n SIPDR2: 0o172204, // Supervisor I Page Descriptor Register 2\n SIPDR3: 0o172206, // Supervisor I Page Descriptor Register 3\n SIPDR4: 0o172210, // Supervisor I Page Descriptor Register 4\n SIPDR5: 0o172212, // Supervisor I Page Descriptor Register 5\n SIPDR6: 0o172214, // Supervisor I Page Descriptor Register 6\n SIPDR7: 0o172216, // Supervisor I Page Descriptor Register 7\n SDPDR0: 0o172220, // Supervisor D Page Descriptor Register 0\n SDPDR1: 0o172222, // Supervisor D Page Descriptor Register 1\n SDPDR2: 0o172224, // Supervisor D Page Descriptor Register 2\n SDPDR3: 0o172226, // Supervisor D Page Descriptor Register 3\n SDPDR4: 0o172230, // Supervisor D Page Descriptor Register 4\n SDPDR5: 0o172232, // Supervisor D Page Descriptor Register 5\n SDPDR6: 0o172234, // Supervisor D Page Descriptor Register 6\n SDPDR7: 0o172236, // Supervisor D Page Descriptor Register 7\n SIPAR0: 0o172240, // Supervisor I Page Address Register 0\n SIPAR1: 0o172242, // Supervisor I Page Address Register 1\n SIPAR2: 0o172244, // Supervisor I Page Address Register 2\n SIPAR3: 0o172246, // Supervisor I Page Address Register 3\n SIPAR4: 0o172250, // Supervisor I Page Address Register 4\n SIPAR5: 0o172252, // Supervisor I Page Address Register 5\n SIPAR6: 0o172254, // Supervisor I Page Address Register 6\n SIPAR7: 0o172256, // Supervisor I Page Address Register 7\n SDPAR0: 0o172260, // Supervisor D Page Address Register 0\n SDPAR1: 0o172262, // Supervisor D Page Address Register 1\n SDPAR2: 0o172264, // Supervisor D Page Address Register 2\n SDPAR3: 0o172266, // Supervisor D Page Address Register 3\n SDPAR4: 0o172270, // Supervisor D Page Address Register 4\n SDPAR5: 0o172272, // Supervisor D Page Address Register 5\n SDPAR6: 0o172274, // Supervisor D Page Address Register 6\n SDPAR7: 0o172276, // Supervisor D Page Address Register 7\n KIPDR0: 0o172300, // Kernel I Page Descriptor Register 0\n KIPDR1: 0o172302, // Kernel I Page Descriptor Register 1\n KIPDR2: 0o172304, // Kernel I Page Descriptor Register 2\n KIPDR3: 0o172306, // Kernel I Page Descriptor Register 3\n KIPDR4: 0o172310, // Kernel I Page Descriptor Register 4\n KIPDR5: 0o172312, // Kernel I Page Descriptor Register 5\n KIPDR6: 0o172314, // Kernel I Page Descriptor Register 6\n KIPDR7: 0o172316, // Kernel I Page Descriptor Register 7\n KDPDR0: 0o172320, // Kernel D Page Descriptor Register 0\n KDPDR1: 0o172322, // Kernel D Page Descriptor Register 1\n KDPDR2: 0o172324, // Kernel D Page Descriptor Register 2\n KDPDR3: 0o172326, // Kernel D Page Descriptor Register 3\n KDPDR4: 0o172330, // Kernel D Page Descriptor Register 4\n KDPDR5: 0o172332, // Kernel D Page Descriptor Register 5\n KDPDR6: 0o172334, // Kernel D Page Descriptor Register 6\n KDPDR7: 0o172336, // Kernel D Page Descriptor Register 7\n KIPAR0: 0o172340, // Kernel I Page Address Register 0\n KIPAR1: 0o172342, // Kernel I Page Address Register 1\n KIPAR2: 0o172344, // Kernel I Page Address Register 2\n KIPAR3: 0o172346, // Kernel I Page Address Register 3\n KIPAR4: 0o172350, // Kernel I Page Address Register 4\n KIPAR5: 0o172352, // Kernel I Page Address Register 5\n KIPAR6: 0o172354, // Kernel I Page Address Register 6\n KIPAR7: 0o172356, // Kernel I Page Address Register 7\n KDPAR0: 0o172360, // Kernel D Page Address Register 0\n KDPAR1: 0o172362, // Kernel D Page Address Register 1\n KDPAR2: 0o172364, // Kernel D Page Address Register 2\n KDPAR3: 0o172366, // Kernel D Page Address Register 3\n KDPAR4: 0o172370, // Kernel D Page Address Register 4\n KDPAR5: 0o172372, // Kernel D Page Address Register 5\n KDPAR6: 0o172374, // Kernel D Page Address Register 6\n KDPAR7: 0o172376, // Kernel D Page Address Register 7\n MMR3: 0o172516, // 772516 17772516\n RLCS: 0o174400, // RL11 Control Status Register\n RLBA: 0o174402, // RL11 Bus Address Register\n RLDA: 0o174404, // RL11 Disk Address Register\n RLMP: 0o174406, // RL11 Multi-Purpose Register\n RLBE: 0o174410, // RL11 Bus (Address) Extension Register (RLV12 controller only)\n DL11: 0o176500, // DL11 Additional Register Range (ends at 0o176676)\n RXCS: 0o177170, // RX11 Command and Status Register\n RXDB: 0o177172, // RX11 Data Buffer Register\n RKDS: 0o177400, // RK11 Drive Status Register\n RKER: 0o177402, // RK11 Error Register\n RKCS: 0o177404, // RK11 Control Status Register\n RKWC: 0o177406, // RK11 Word Count Register\n RKBA: 0o177410, // RK11 Bus Address Register\n RKDA: 0o177412, // RK11 Disk Address Register\n RKUN: 0o177414, // RK11 UNUSED (just to make it clear we didn't forget something)\n RKDB: 0o177416, // RK11 Data Buffer Register\n LKS: 0o177546, // KW11-L Clock Status\n PRS: 0o177550, // PC11 (and PR11) Reader Status Register\n PRB: 0o177552, // PC11 (and PR11) Reader Buffer Register\n PPS: 0o177554, // PC11 Punch Status Register\n PPB: 0o177556, // PC11 Punch Buffer Register\n RCSR: 0o177560, // DL11 Receiver Status Register\n RBUF: 0o177562, // DL11 Receiver Data Buffer Register\n XCSR: 0o177564, // DL11 Transmitter Status Register\n XBUF: 0o177566, // DL11 Transmitter Data Buffer Register\n CNSW: 0o177570, // Console (Front Panel) Switch/Display Register\n MMR0: 0o177572, // 777572 17777572\n MMR1: 0o177574, // 777574 17777574\n MMR2: 0o177576, // 777576 17777576\n UIPDR0: 0o177600, // User I Page Descriptor Register 0\n UIPDR1: 0o177602, // User I Page Descriptor Register 1\n UIPDR2: 0o177604, // User I Page Descriptor Register 2\n UIPDR3: 0o177606, // User I Page Descriptor Register 3\n UIPDR4: 0o177610, // User I Page Descriptor Register 4\n UIPDR5: 0o177612, // User I Page Descriptor Register 5\n UIPDR6: 0o177614, // User I Page Descriptor Register 6\n UIPDR7: 0o177616, // User I Page Descriptor Register 7\n UDPDR0: 0o177620, // User D Page Descriptor Register 0\n UDPDR1: 0o177622, // User D Page Descriptor Register 1\n UDPDR2: 0o177624, // User D Page Descriptor Register 2\n UDPDR3: 0o177626, // User D Page Descriptor Register 3\n UDPDR4: 0o177630, // User D Page Descriptor Register 4\n UDPDR5: 0o177632, // User D Page Descriptor Register 5\n UDPDR6: 0o177634, // User D Page Descriptor Register 6\n UDPDR7: 0o177636, // User D Page Descriptor Register 7\n UIPAR0: 0o177640, // User I Page Address Register 0\n UIPAR1: 0o177642, // User I Page Address Register 1\n UIPAR2: 0o177644, // User I Page Address Register 2\n UIPAR3: 0o177646, // User I Page Address Register 3\n UIPAR4: 0o177650, // User I Page Address Register 4\n UIPAR5: 0o177652, // User I Page Address Register 5\n UIPAR6: 0o177654, // User I Page Address Register 6\n UIPAR7: 0o177656, // User I Page Address Register 7\n UDPAR0: 0o177660, // User D Page Address Register 0\n UDPAR1: 0o177662, // User D Page Address Register 1\n UDPAR2: 0o177664, // User D Page Address Register 2\n UDPAR3: 0o177666, // User D Page Address Register 3\n UDPAR4: 0o177670, // User D Page Address Register 4\n UDPAR5: 0o177672, // User D Page Address Register 5\n UDPAR6: 0o177674, // User D Page Address Register 6\n UDPAR7: 0o177676, // User D Page Address Register 7\n R0SET0: 0o177700, //\n R1SET0: 0o177701, //\n R2SET0: 0o177702, //\n R3SET0: 0o177703, //\n R4SET0: 0o177704, //\n R5SET0: 0o177705, //\n R6KERNEL: 0o177706, //\n R7KERNEL: 0o177707, //\n R0SET1: 0o177710, //\n R1SET1: 0o177711, //\n R2SET1: 0o177712, //\n R3SET1: 0o177713, //\n R4SET1: 0o177714, //\n R5SET1: 0o177715, //\n R6SUPER: 0o177716, //\n R6USER: 0o177717, //\n /*\n * This next group of registers is largely ignored; all accesses are routed to regsControl[],\n * and therefore are managed as a block of 8 \"CTRL\" registers.\n */\n CTRL: 0o177740,\n LAERR: 0o177740, // Low Address Error (11/70 only)\n HAERR: 0o177742, // High Address Error (11/70 only)\n MEMERR: 0o177744, // Memory System Error (11/70 only)\n CACHEC: 0o177746, // Cache Control (11/70 only)\n MAINT: 0o177750, // Maintenance (11/70 only)\n HITMISS: 0o177752, // Hit/Miss (11/70 only)\n UNDEF1: 0o177754, //\n UNDEF2: 0o177756, //\n LSIZE: 0o177760, // Lower Size Register (last 64-byte block #) (11/70 only)\n HSIZE: 0o177762, // Upper Size Register (always zero) (11/70 only)\n SYSID: 0o177764, // System ID Register (11/70 only)\n CPUERR: 0o177766, // CPU error (11/70 only)\n MB: 0o177770, // Microprogram break (11/70 only)\n PIR: 0o177772, // Program Interrupt Request\n SL: 0o177774, // Stack Limit Register\n PSW: 0o177776 // 777776 17777776 0x3FFFFE Processor Status Word\n },\n DL11: { // Serial Line Interface (program compatible with the KL11 for control of console teleprinters)\n PRI: 4,\n RVEC: 0o060,\n XVEC: 0o064,\n RCSR: { // 177560: DL11 Receiver Status Register\n RE: 0x0001, // Reader Enable (W/O)\n DTR: 0x0002, // Data Terminal Ready (R/W)\n RTS: 0x0004, // Request To Send (R/W)\n STD: 0x0008, // Secondary Transmitted Data (R/W)\n DIE: 0x0020, // Dataset Interrupt Enable (R/W)\n RIE: 0x0040, // Receiver Interrupt Enable (R/W)\n RD: 0x0080, // Receiver Done (R/O)\n SRD: 0x0400, // Secondary Received Data (R/O)\n RA: 0x0800, // Receiver Active (R/O)\n CD: 0x1000, // Carrier Detect (R/O)\n CTS: 0x2000, // Clear To Send (R/O)\n RI: 0x4000, // Ring Indicator (R/O)\n DSC: 0x8000, // Dataset Status Change (R/O)\n RMASK: 0xFFFE, // bits readable (TODO: All I know for sure is that bit 0 is NOT readable; see readRCSR())\n WMASK: 0x006F, // bits writable\n RS232: 0x0006, // bits affecting RS-232 status updates\n BAUD: 9600\n },\n RBUF: { // 177562: DL11 Receiver Data Buffer Register\n DATA: 0x00ff, // Received Data (R/O)\n PARITY: 0x1000, // Received Data Parity (R/O)\n FE: 0x2000, // Framing Error (R/O)\n OE: 0x4000, // Overrun Error (R/O)\n ERROR: 0x8000 // Error (R/O)\n },\n XCSR: { // 177564: DL11 Transmitter Status Register\n BREAK: 0x0001, // BREAK (R/W)\n MAINT: 0x0004, // Maintenance (R/W)\n TIE: 0x0040, // Transmitter Interrupt Enable (R/W)\n READY: 0x0080, // Transmitter Ready (R/O)\n RMASK: 0x00C5,\n WMASK: 0x0045,\n BAUD: 9600\n },\n XBUF: { // 177566: DL11 Transmitter Data Buffer Register\n DATA: 0x00FF // Transmitted Data (W/O) (TODO: Determine why pdp11.js effectively defined this as 0x7F)\n }\n },\n KW11: { // KW11-L Line Time Clock (60Hz; well, OK, or 50Hz, if you're in the UK, I suppose...)\n PRI: 6,\n VEC: 0o100,\n DELAY: 0,\n LKS: { // 177546: KW11-L Clock Status\n IE: 0x0040, // Interrupt Enable\n MON: 0x0080, // Monitor\n MASK: 0x00C0 // these are the only bits that can read or written\n }\n },\n PC11: { // High Speed Reader & Punch (PR11 is a Reader-only unit)\n PRI: 4, // NOTE: reader has precedence over punch\n RVEC: 0o070, // reader vector\n PVEC: 0o074, // punch vector\n PRS: { // 177550: PC11 (and PR11) Reader Status Register\n RE: 0x0001, // (000001) Reader Enable (W/O)\n IE: 0x0040, // (000100) Reader Interrupt Enable (allows the DONE and ERROR bits to trigger an interrupt)\n DONE: 0x0080, // (000200) Done (R/O)\n BUSY: 0x0800, // (004000) Busy (R/O)\n ERROR: 0x8000, // (100000) Error (R/O)\n CLEAR: 0x08C0, // (004300) bits cleared on INIT\n RMASK: 0xFFFE, // (177776) bits readable (TODO: All I know for sure is that bit 0 is NOT readable; see readPRS())\n WMASK: 0x0041, // (000101) bits writable\n BAUD: 3600\n },\n PRB: { // 177552: PC11 (and PR11) Reader Buffer Register\n MASK: 0x00FF // Data\n },\n PPS: { // 177554: PC11 Punch Status Register\n IE: 0x0040, // Interrupt Enable\n RDY: 0x0080, // Ready\n ERROR: 0x8000, // Error (eg, no tape in punch, or punch has no power)\n WMASK: 0x0040, // bits writable\n BAUD: 600\n },\n PPB: { // 177556: PC11 Punch Buffer Register\n MASK: 0x00FF // Data\n }\n },\n RK11: { // RK11 Disk Controller\n PRI: 5,\n VEC: 0o220,\n DRIVES: 8, // maximum of 8 drives\n RKDS: { // 177400: Drive Status Register\n SC: 0x000F, // (000017) Sector Counter\n SCESA: 0x0010, // (000020) Sector Counter Equals Sector Address\n WPS: 0x0020, // (000040) Write Protected Status (set if write-protected)\n RRDY: 0x0040, // (000100) Read/Write/Seek Ready\n DRDY: 0x0080, // (000200) Drive Ready\n SOK: 0x0100, // (000400) Sector Counter OK\n SIN: 0x0200, // (001000) Seek Incomplete\n DRU: 0x0400, // (002000) Drive Unsafe\n RK05: 0x0800, // (004000) RK05 is the selected disk drive (always set)\n DPL: 0x1000, // (010000) Drive Power Low\n ID: 0xE000, // (160000) Drive ID (logical drive number of an interrupting drive)\n SHIFT: {\n ID: 13\n }\n },\n RKER: { // 177402: Error Register\n WCE: 0x0001, // Write Check Error\n CSE: 0x0002, // Checksum Error\n SE: 0x0003, // Soft Error bits (cleared at the start of a new function)\n UNUSED: 0x001C, // unused (returns zero)\n NXS: 0x0020, // Non-Existent Sector\n NXC: 0x0040, // Non-Existent Cylinder\n NXD: 0x0080, // Non-Existent Disk\n TE: 0x0100, // Timing Error\n DLT: 0x0200, // Date Late\n NXM: 0x0400, // Non-Existent Memory\n PGE: 0x0800, // Programming Error\n SKE: 0x1000, // Seek Error\n WLO: 0x2000, // Write Lock-Out Violation\n OVR: 0x4000, // Overrun\n DRE: 0x8000, // Drive Error\n HE: 0x7FE0 // Hard Error bits (cleared only by Bus RESET or RK11 CRESET function)\n },\n RKCS: { // 177404: Control Status Register\n GO: 0x0001, // (000001) Go (W/O)\n FUNC: 0x000E, // (000016) Function Code (F2,F1,F0) (R/W)\n MEX: 0x0030, // (000060) Memory Extension (R/W)\n IE: 0x0040, // (000100) Interrupt Enable (R/W)\n CRDY: 0x0080, // (000200) Controller Ready (R/O)\n SSE: 0x0100, // (000400) Stop on Soft Error (R/W)\n EXB: 0x0200, // (001000) Extra Bit (R/W)\n FMT: 0x0400, // (002000) Format (R/W)\n IBA: 0x0800, // (004000) Inhibit RKBA Increment (R/W)\n SCP: 0x2000, // (020000) Search Complete (R/O)\n HE: 0x4000, // (040000) Hard Error (R/O)\n ERR: 0x8000, // (100000) Composite Error (R/O) (set when any RKER bit is set)\n UNUSED: 0x1200, // (011000) unused\n RMASK: 0xEFFE, // (167776) bits readable\n WMASK: 0x0F7F, // (007577) bits writable\n SHIFT: {\n FUNC: 1,\n MEX: 4\n }\n },\n RKDA: { // 177412: Disk Address Register\n SA: 0x000F, // (000017) Sector Address\n HS: 0x0010, // (000020) Head Select (aka SUR: clear for upper disk head, set for lower)\n CA: 0x1FE0, // (017740) Cylinder Address (aka CYL ADDR)\n DS: 0xE000, // (160000) Drive Select (aka DR SEL)\n SHIFT: {\n HS: 4,\n CA: 5,\n DS: 13\n }\n },\n FUNC: {\n CRESET: 0b0000, // (00) Controller Reset\n WRITE: 0b0010, // (02) Write\n READ: 0b0100, // (04) Read\n WCHK: 0b0110, // (06) Write Check\n SEEK: 0b1000, // (10) Seek\n RCHK: 0b1010, // (12) Read Check\n DRESET: 0b1100, // (14) Drive Reset\n WLOCK: 0b1110 // (16) Write Lock\n }\n },\n RL11: { // RL11 Disk Controller\n PRI: 5,\n VEC: 0o160,\n DRIVES: 4, // maximum of 4 drives\n PREFIX: \"DY\",\n RLCS: { // 174400: Control Status Register\n DRDY: 0x0001, // (000001) Drive Ready (R/O)\n FUNC: 0x000E, // (000016) Function Code (F2,F1,F0) (R/W)\n BAE: 0x0030, // (000060) Bus Address Extension bits (BA17,BA16) (R/W)\n IE: 0x0040, // (000100) Interrupt Enable (R/W)\n CRDY: 0x0080, // (000200) Controller Ready (R/W)\n DS: 0x0300, // (001400) Drive Select (DS1,DS0) (R/W)\n ERRC: 0x3C00, // (036000) Error Code (R/O)\n DE: 0x4000, // (040000) Drive Error (R/O)\n ERR: 0x8000, // (100000) Composite Error (R/O)\n CLEAR: 0x3F7E, // (037576) bits cleared on INIT (bits 1-6 and 8-13 are cleared)\n SET: 0x0080, // (000200) bits set on INIT (bit 7 is set)\n RMASK: 0xFFFF, // (177777) no write-only bits\n WMASK: 0x03FE, // (001776) bits writable\n SHIFT: {\n FUNC: 1,\n BAE: 4,\n DS: 8\n }\n },\n RLBA: { // 174402: Bus Address Register\n WMASK: 0xFFFE // bit 0 is effectively not writable (always zero)\n },\n /*\n * This register has 3 formats: one for Seek, another for Read/Write, and a third for Get Status\n */\n RLDA: { // 174404: Disk Address Register\n SEEK_CMD: 0x0001, // Seek: bit 0 must be set, bits 1 and 3 must be clear\n SEEK_DIR: 0x0004, // Direction (clear to move heads away from spindle (lower cylinder), set to move to higher cylinder)\n SEEK_HS: 0x0010, // Head Select (clear to select upper head, set to select lower head)\n SEEK_CAD: 0xFF80, // Cylinder Address Difference\n RW_SA: 0x003F, // Sector Address\n RW_HS: 0x0040, // Head Select\n RW_CA: 0xFF80, // Cylinder Address (RL01 has 256 cylinders, RL02 has 512)\n GS_CMD: 0x0003, // Get Status: bit 0 must be set, bit 1 set, and bits 2 and 4-7 clear (bits 8-15 unused)\n GS_RST: 0x0008, // Reset (when set, clears error register before sending status word to controller)\n SHIFT: {\n RW_HS: 6,\n RW_CA: 7\n }\n },\n /*\n * This register has 3 formats: one for Read Header, another for Read/Write, and a third for Get Status\n */\n RLMP: { // 177406: Multi-Purpose Register\n GS_ST: { // Major State Code (of the drive)\n LOADC: 0x0, // Load Cartridge\n SPINUP: 0x1, // Spin-Up\n BRUSHC: 0x2, // Brush Cycle\n LOADH: 0x3, // Load Heads\n SEEK: 0x4, // Seek\n LOCKON: 0x5, // Lock On\n UNLOADH:0x6, // Unload Heads\n SPINDN: 0x7 // Spin-Down\n },\n GS_BH: 0x0008, // Brushes Home\n GS_HO: 0x0010, // Heads Out\n GS_CO: 0x0020, // Cover Open (or dust cover is not in place)\n GS_HS: 0x0040, // Head Selected (0 for upper head, 1 for lower head)\n GS_DT: 0x0080, // Drive Type (0 for RL01, 1 for RL02)\n GS_DSE: 0x0100, // Drive Select Error\n GS_VC: 0x0200, // Volume Check (Set during transition from a head load state to a head-on-track state; cleared by execution of a Get Status command with Bit 3 asserted)\n GS_WGE: 0x0400, // Write Gate Error\n GS_SPE: 0x0800, // Spin Error\n GS_SKTO: 0x1000, // Seek Time-Out\n GS_WL: 0x2000, // Write Lock\n GS_CHE: 0x4000, // Current Head Error\n GS_WDE: 0x8000 // Write Data Error\n },\n RLBE: { // 174410: Bus (Address) Extension Register\n MASK: 0x003F // bits 5-0 correspond to bus address bits 21-16\n },\n ERRC: { // NOTE: These error codes are pre-shifted to read/write directly from/to RLCS.ERRC\n OPI: 0x0400, // Operation Incomplete\n DCRC: 0x0800, // Read Data CRC\n WCE: 0x0800, // Write Check Error\n HCRC: 0x0C00, // Header CRC\n DLT: 0x1000, // Data Late\n HNF: 0x1400, // Header Not Found\n NXM: 0x2000, // Non-Existent Memory\n MPE: 0x2400 // Memory Parity Error (RLV12 only)\n },\n FUNC: { // NOTE: These function codes are pre-shifted to read/write directly from/to RLCS.FUNC\n NOP: 0b0000, // (00) No-Op\n WCHK: 0b0010, // (02) Write Check\n STATUS: 0b0100, // (04) Get Status\n SEEK: 0b0110, // (06) Seek\n RHDR: 0b1000, // (10) Read Header\n WDATA: 0b1010, // (12) Write Data\n RDATA: 0b1100, // (14) Read Data\n RDNC: 0b1110 // (16) Read Data without Header Check\n }\n },\n RX11: { // RX11 Disk Controller\n PRI: 5,\n VEC: 0o264,\n DRIVES: 2, // maximum of 2 drives\n PREFIX: \"DX\",\n RXCS: { // 177170: Command and Status Register\n GO: 0x0001, // (000001) Go (W/O)\n FUNC: 0x000E, // (000016) Function Code (F2,F1,F0) (W/O)\n UNIT: 0x0010, // (000020) Unit Select (W/O)\n DONE: 0x0020, // (000040) Done (R/O)\n IE: 0x0040, // (000100) Interrupt Enable (R/W, cleared on INIT)\n TR: 0x0080, // (000200) Transfer Request (R/O)\n INIT: 0x4000, // (040000) RX11 Initialize (W/O)\n ERR: 0x8000, // (100000) Error (R/O, cleared on INIT or command)\n UNUSED: 0x3F00, // (037400) unused\n RMASK: 0x80E0, // (100340) bits readable\n WMASK: 0x405F // (040137) bits writable\n },\n RXDB: { // 177172: Data Buffer Register\n },\n RXTA: {\n MASK: 0x007F\n },\n RXSA: {\n MASK: 0x001F\n },\n RXES: {\n /*\n * The DRDY bit is only valid when retrieved via a Read Status function or at completion of Initialize when it indicates\n * status of drive O. It is asserted if the unit currently selected exists, is properly supplied with power, has a diskette\n * installed correctly, has its door closed, and has a diskette up to speed.\n *\n * If the Error bit was set in the RXCS but Error bits are not set in the RXES, then specific error conditions can be accessed via\n * a Read Error Register function.\n */\n CRC: 0x0001, // CRC error (RXES is moved to the RXDB, and Error and Done are asserted)\n PARITY: 0x0002, // parity error (RXES is moved to the RXDB, and Error and Done are asserted)\n ID: 0x0004, // Initialize Done (following a programmable or UNIBUS initialization, or a power failure)\n DEL: 0x0040, // Deleted Data Detected\n DRDY: 0x0080 // Drive Ready\n },\n FUNC: { // NOTE: These function codes are pre-shifted to read/write directly from/to RXCS.FUNC\n FILL: 0b0000, // Fill Buffer\n EMPTY: 0b0010, // Empty Buffer\n WRITE: 0b0100, // Write Sector\n READ: 0b0110, // Read Sector\n UNUSED: 0b1000, // UNUSED\n RDSTAT: 0b1010, // Read Status\n WRDEL: 0b1100, // Write Deleted Data Sector\n RDERR: 0b1110 // Read Error Register\n },\n ERROR: {\n HOME0: 0o0010, // Drive 0 failed to see home on Initialize\n HOME1: 0o0020, // Drive 1 failed to see home on Initialize\n BAD_HOME: 0o0030, // Found home when stepping out 10 tracks for INIT\n NO_TRACK: 0o0040, // Tried to access a track greater than 77\n FOUND_HOME: 0o0050, // Home was found before desired track was reached\n SELF_DIAG: 0o0060, // Self-diagnostic error\n NO_SECTOR: 0o0070, // Desired sector could not be found after looking at 52 headers (2 revolutions)\n NO_SEP: 0o0110, // More than 40us and no SEP clock seen\n NO_PREAM: 0o0120, // A preamble could not be found\n NO_IOMARK: 0o0130, // Preamble found but no I/O mark found within allowable time span\n CRC_HEADER: 0o0140, // CRC error on what we thought was a header\n BAD_TRACK: 0o0150, // The header track address of a good header does not compare with the desired track\n NO_ID: 0o0160, // Too many tries for an IDAM (identifies header)\n NO_DATA: 0o0170, // Data AM not found in allotted time\n CRC_DATA: 0o0200, // CRC error on reading the sector from the disk (No code appears in the ERREG).\n BAD_PARITY: 0o0210 // All parity errors\n }\n },\n VECTORS: {\n 0o060: \"DL11R\",\n 0o064: \"DL11X\",\n 0o070: \"PC11R\",\n 0o074: \"PC11X\",\n 0o100: \"KW11\",\n 0o160: \"RL11\",\n 0o220: \"RK11\",\n 0o264: \"RX11\"\n }\n};\n\nPDP11.RX11.RX01 = [\n \"DX\",\n 77, 1, 26, 128, // disk geometry (CHSN: cylinders, heads, sectors/track, and bytes/sector)\n 1, 0, 0, 128, // boot code location (cylinder, head, sector index (NOT sector number), and number of bytes)\n 0 // default drive status\n];\n\nPDP11.RK11.RK05 = [\n \"RK\",\n 203, 2, 12, 512, // disk geometry (CHSN: cylinders, heads, sectors/track, and bytes/sector)\n 0, 0, 0, 512, // boot code location (cylinder, head, sector index (NOT sector number), and number of bytes)\n PDP11.RK11.RKDS.RK05 | PDP11.RK11.RKDS.SOK | PDP11.RK11.RKDS.RRDY\n];\n\nPDP11.RL11.RL02K = [\n \"RL\",\n 512, 2, 40, 256, // disk geometry (CHSN: cylinders, heads, sectors/track, and bytes/sector)\n 0, 0, 0, 256, // boot code location (cylinder, head, sector index (NOT sector number), and number of bytes)\n PDP11.RL11.RLMP.GS_ST.LOCKON | PDP11.RL11.RLMP.GS_BH | PDP11.RL11.RLMP.GS_HO\n];\n\nPDP11.ACCESS.READ_WORD = PDP11.ACCESS.WORD | PDP11.ACCESS.READ; // formerly READ_MODE (2)\nPDP11.ACCESS.READ_BYTE = PDP11.ACCESS.BYTE | PDP11.ACCESS.READ; // formerly READ_MODE (2) | BYTE_MODE (1)\nPDP11.ACCESS.WRITE_WORD = PDP11.ACCESS.WORD | PDP11.ACCESS.WRITE; // formerly WRITE_MODE (4)\nPDP11.ACCESS.WRITE_BYTE = PDP11.ACCESS.BYTE | PDP11.ACCESS.WRITE; // formerly WRITE_MODE (4) | BYTE_MODE (1)\nPDP11.ACCESS.UPDATE_WORD = PDP11.ACCESS.WORD | PDP11.ACCESS.UPDATE; // formerly MODIFY_WORD (2 | 4)\nPDP11.ACCESS.UPDATE_BYTE = PDP11.ACCESS.BYTE | PDP11.ACCESS.UPDATE; // formerly MODIFY_BYTE (1 | 2 | 4)\n\n/*\n * PSW arithmetic flags are NOT stored directly into the PSW register; they are maintained across separate flag registers.\n */\nPDP11.PSW.FLAGS = (PDP11.PSW.NF | PDP11.PSW.ZF | PDP11.PSW.VF | PDP11.PSW.CF);\n\n/*\n * Combine all the shared globals and machine-specific globals into one machine-specific global object,\n * which all machine components should start using; eg: \"if (PDP11.DEBUGGER)\" instead of \"if (DEBUGGER)\".\n */\nPDP11.APPCLASS = APPCLASS;\nPDP11.APPNAME = APPNAME;\nPDP11.DEBUGGER = DEBUGGER;\nPDP11.BYTEARRAYS = BYTEARRAYS;\nPDP11.TYPEDARRAYS = TYPEDARRAYS;\nPDP11.MEMFAULT = MEMFAULT;\nPDP11.WORDBUS = WORDBUS;\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/messages.js (C) Jeff Parsons 2012-2018\n */\n\nvar MessagesPDP11 = {\n CPU: 0x00000001,\n TRAP: 0x00000002,\n FAULT: 0x00000004,\n INT: 0x00000008,\n BUS: 0x00000010,\n MEMORY: 0x00000020,\n MMU: 0x00000040,\n ROM: 0x00000080,\n DEVICE: 0x00000100,\n PANEL: 0x00000200,\n KEYBOARD: 0x00000400,\n KEYS: 0x00000800,\n PC11: 0x00001000,\n PAPER: 0x00001000,\n DISK: 0x00002000,\n READ: 0x00004000,\n WRITE: 0x00008000,\n RK11: 0x00010000,\n RL11: 0x00020000,\n RX11: 0x00040000,\n DL11: 0x00100000,\n SERIAL: 0x00100000,\n KW11: 0x00200000,\n TIMER: 0x00200000,\n SPEAKER: 0x01000000,\n COMPUTER: 0x02000000,\n BUFFER: 0x20000000,\n WARN: 0x40000000,\n HALT: 0x80000000|0\n};\n\n/*\n * Message categories supported by the messageEnabled() function and other assorted message\n * functions. Each category has a corresponding bit value that can be combined (ie, OR'ed) as\n * needed. The Debugger's message command (\"m\") is used to turn message categories on and off,\n * like so:\n *\n * m port on\n * m port off\n * ...\n *\n * NOTE: The order of these categories can be rearranged, alphabetized, etc, as desired; just be\n * aware that changing the bit values could break saved Debugger states (not a huge concern, just\n * something to be aware of).\n */\nMessagesPDP11.CATEGORIES = {\n \"cpu\": MessagesPDP11.CPU,\n \"trap\": MessagesPDP11.TRAP,\n \"fault\": MessagesPDP11.FAULT,\n \"int\": MessagesPDP11.INT,\n \"bus\": MessagesPDP11.BUS,\n \"memory\": MessagesPDP11.MEMORY,\n \"mmu\": MessagesPDP11.MMU,\n \"rom\": MessagesPDP11.ROM,\n \"device\": MessagesPDP11.DEVICE,\n \"panel\": MessagesPDP11.PANEL,\n \"keyboard\": MessagesPDP11.KEYBOARD, // \"kbd\" is also allowed as shorthand for \"keyboard\"; see doMessages()\n \"key\": MessagesPDP11.KEYS, // using \"key\" instead of \"keys\", since the latter is a method on JavasScript objects\n \"pc11\": MessagesPDP11.PC11,\n \"paper\": MessagesPDP11.PAPER,\n \"disk\": MessagesPDP11.DISK,\n \"read\": MessagesPDP11.READ,\n \"write\": MessagesPDP11.WRITE,\n \"rk11\": MessagesPDP11.RK11,\n \"rl11\": MessagesPDP11.RL11,\n \"rx11\": MessagesPDP11.RX11,\n \"dl11\": MessagesPDP11.DL11,\n \"serial\": MessagesPDP11.SERIAL,\n \"kw11\": MessagesPDP11.KW11,\n \"timer\": MessagesPDP11.TIMER,\n \"speaker\": MessagesPDP11.SPEAKER,\n \"computer\": MessagesPDP11.COMPUTER,\n /*\n * Now we turn to message actions rather than message types; for example, setting \"halt\"\n * on or off doesn't enable \"halt\" messages, but rather halts the CPU on any message above.\n *\n * Similarly, \"m buffer on\" turns on message buffering, deferring the display of all messages\n * until \"m buffer off\" is issued.\n */\n \"buffer\": MessagesPDP11.BUFFER,\n \"warn\": MessagesPDP11.WARN,\n \"halt\": MessagesPDP11.HALT\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/panel.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * Component class, because otherwise the Compiler won't allow us to *reference* the named\n * property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass PanelPDP11 extends Component {\n /**\n * PanelPDP11(parmsPanel)\n *\n * The PanelPDP11 component has no required (parmsPanel) properties.\n *\n * @param {Object} parmsPanel\n * @param {boolean} fBindings (true if panel may have bindings, otherwise not)\n */\n constructor(parmsPanel, fBindings)\n {\n super(\"Panel\", parmsPanel, MessagesPDP11.PANEL);\n\n /*\n * If there are any live registers, LEDs, etc, to display, this will provide a count.\n * TODO: Add some UI for fDisplayLiveRegs (either an XML property, or a UI checkbox, or both).\n */\n this.cLiveRegs = 0;\n this.nDisplayCount = 0;\n this.nDisplayLimit = 60;\n this.fDisplayLiveRegs = true;\n this.fBindings = fBindings;\n\n /*\n * regSwitches contains the Front Panel (aka Console) SWITCH register, which is also available\n * as a read-only register at 177570 (but only the low 16 bits). regDisplay contains the DISPLAY\n * register, a write-only register at the same address.\n *\n * regAddr is an internal register containing the contents of the Front Panel's ADDRESS display,\n * and regData corresponds to the DATA display. They are updated by updateAddr() and updateData(),\n * which in turn take care of calling updateLEDArray().\n *\n * The state of ALL switches is maintained in this.switches, and likewise all LED states are\n * maintained in this.leds, but for convenience, we also mirror some of those states in dedicated\n * variables (eg, regSwitches for the SWITCH register, fLEDTest for the 'TEST' switch, etc).\n */\n this.regDisplay = 0;\n this.regSwitches = 0;\n this.regAddr = this.regData = 0;\n this.ledAddr = this.ledData = -1;\n\n /*\n * The panel hardware has the following additional (supported) state; note that there are several\n * settings on a real Front Panel that we don't support (eg, stepping one cycle vs. one instruction).\n *\n * While my initial intent is to eventually support all the ADDRSEL switch settings, I probably\n * won't bother with any DATASEL switch settings; instead, I will automatically display the DISPLAY\n * register (regDisplay) [the equivalent of selecting 'DISPLAY REGISTER'] except when data is being\n * examined or deposited [the equivalent of selecting 'DATA PATHS'].\n */\n this.fLEDTest = false; // LED (lamp) test in progress\n this.fAutoInc = false; // true if the next 'DEP' or 'EXAM' should auto-increment\n this.nAddrSel = PanelPDP11.ADDRSEL.CONS_PHY;\n\n /*\n * Every LED has a simple numeric value, assigned when setBinding() is called:\n *\n * zero if \"off\", non-zero if \"on\"\n *\n * initBus() will call displayLEDs() to ensure that every LED is set to its initial value.\n */\n this.leds = {};\n\n /*\n * Every switch has an array associated with it:\n *\n * [0]: initial value of switch (0 if \"down\", 1 if \"up\")\n * [1]: current value of switch\n * [2]: true if the switch is momentary, false if not\n * [3]: true if the switch is currently pressed, false if released\n * [4]: optional handler to call whenever the switch is pressed or released\n * [5]: optional switch index (used with CNSW switches 'S0' through 'S21')\n *\n * initBus() will call displaySwitches() to ensure that every switch is the position represented below.\n *\n * NOTE: Not all switches have the same \"process\" criteria. For example, 'TEST' will perform a LED test\n * when it is momentarily pressed \"up\", whereas 'LOAD [ADRS]' will load the ADDRESS register from the\n * SWITCH register when it is momentarily pressed \"down\".\n *\n * This means that processLEDTest(value) must act when value == 1 (\"up\"), whereas processLoadAddr(value)\n * must act when value == 0 (\"down\"). You can infer all this from the table below, because the initial value\n * of any momentary switch is its \"inactive\" value, so the opposite is its \"active\" value.\n */\n this.switches = {\n 'START': [1, 1, true, false, this.processStart],\n 'STEP': [1, 1, false, false, this.processStep],\n 'ENABLE': [1, 1, false, false, this.processEnable],\n 'CONT': [1, 1, true, false, this.processContinue],\n 'DEP': [0, 0, true, false, this.processDeposit],\n 'EXAM': [1, 1, true, false, this.processExamine],\n 'LOAD': [1, 1, true, false, this.processLoadAddr],\n 'TEST': [0, 0, true, false, this.processLEDTest]\n };\n for (var i = 0; i < 22; i++) {\n this.switches['S'+i] = [0, 0, false, false, this.processSRSwitch, i];\n }\n\n /** @type {ComputerPDP11} */\n this.cmp = null;\n\n /** @type {BusPDP11} */\n this.bus = null;\n\n /** @type {CPUStatePDP11} */\n this.cpu = null;\n\n /** @type {DebuggerPDP11} */\n this.dbg = null;\n\n /*\n * The 'hold' and 'toggle' exports, which map to holdSwitch() and toggleSwitch(), both press and release\n * the specified switch, but processCommands() considers a 'hold' function to be asynchronous, which means\n * that holdSwitch() will be passed a callback function that can be used to implement a delay between the\n * press and the release, whereas toggleSwitch() will not.\n *\n * holdSwitch() only makes sense for momentary switches (eg, 'TEST'), where a visual delay might be nice.\n * If the switch isn't momentary, or no delay is desired, then use toggleSwitch(); it will be more efficient.\n *\n * Finally, for switches that are toggles (eg, 'ENABLE'), you can use setSwitch() to set it to a specific\n * state: zero for \"off\" and non-zero for \"on\". setSwitch() also supports meta-switches like \"SR\", using\n * the entire value to set a series of switches at once; the value is assumed to be octal unless overridden\n * by a prefix (eg, \"0x\") or suffix (eg, \".\").\n */\n this['exports'] = {\n 'hold': this.holdSwitch,\n 'toggle': this.toggleSwitch,\n 'reset': this.resetSwitches,\n 'set': this.setSwitch\n };\n\n this.setReady();\n }\n\n /**\n * getAR()\n *\n * @this {PanelPDP11}\n * @return {number} (current ADDRESS register)\n */\n getAR()\n {\n return this.regAddr;\n }\n\n /**\n * setAR(value)\n *\n * @this {PanelPDP11}\n * @param {number} value (new ADDRESS register)\n */\n setAR(value)\n {\n this.updateAddr(this.regAddr = value);\n }\n\n /**\n * getDR()\n *\n * @this {PanelPDP11}\n * @return {number} (current DISPLAY register)\n */\n getDR()\n {\n return this.regDisplay;\n }\n\n /**\n * setDR(value)\n *\n * @this {PanelPDP11}\n * @param {number} value (new DISPLAY register)\n * @return {number}\n */\n setDR(value)\n {\n return this.updateData(this.regDisplay = value);\n }\n\n /**\n * getSR()\n *\n * @this {PanelPDP11}\n * @return {number} (current SWITCH register)\n */\n getSR()\n {\n return this.regSwitches;\n }\n\n /**\n * setSR(value)\n *\n * @this {PanelPDP11}\n * @param {number} value (new SWITCH register)\n */\n setSR(value)\n {\n this.setSRSwitches(value);\n }\n\n /**\n * getSwitch(name)\n *\n * @this {PanelPDP11}\n * @param {string} name\n * @return {number|undefined} 0 if switch is off (\"down\"), 1 if on (\"up\"), or undefined if unrecognized\n */\n getSwitch(name)\n {\n return this.switches[name] && this.switches[name][1];\n }\n\n /**\n * reset(fPowerUp)\n *\n * NOTE: Since we've registered our handler with the Bus component, we will be called twice whenever\n * the entire machine is reset: once when the Computer's reset() handler calls the Bus's reset() handler,\n * and again when the Computer's reset() handler calls us directly. Multiple resets should be harmless.\n *\n * @this {PanelPDP11}\n * @param {boolean} [fPowerUp]\n */\n reset(fPowerUp)\n {\n /*\n * Simulate a call to our stop() handler, to update the panel's ADDRESS register with the current PC.\n */\n this.stop();\n if (fPowerUp) this.setDR(0);\n }\n\n /**\n * setBinding(sType, sBinding, control, sValue)\n *\n * Some panel layouts don't have bindings of their own, and even when they do, there may still be some\n * components (eg, the CPU) that prefer to update their own bindings, so we pass along all binding requests\n * to the Computer, CPU, Keyboard and Debugger components first. The order shouldn't matter, since any\n * component that doesn't recognize the specified binding should simply ignore it.\n *\n * @this {PanelPDP11}\n * @param {string|null} sType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sType, sBinding, control, sValue)\n {\n if (this.cmp && this.cmp.setBinding(sType, sBinding, control, sValue)) {\n return true;\n }\n if (this.cpu && this.cpu.setBinding(sType, sBinding, control, sValue)) {\n return true;\n }\n if (DEBUGGER && this.dbg && this.dbg.setBinding(sType, sBinding, control, sValue)) {\n return true;\n }\n\n switch (sBinding) {\n case 'R0':\n case 'R1':\n case 'R2':\n case 'R3':\n case 'R4':\n case 'R5':\n case 'R6':\n case 'R7':\n case 'NF':\n case 'ZF':\n case 'VF':\n case 'CF':\n case 'PS':\n this.bindings[sBinding] = control;\n this.cLiveRegs++;\n return true;\n\n default:\n /*\n * Square (\"led\") or round (\"rled\") LEDs are defined in machine XML files like so:\n *\n * <control type=\"rled\" binding=\"A3\" value=\"1\" width=\"100%\" container=\"center\"/>\n *\n * Only *type* and *binding* attributes are required; if *value* is omitted, the default value is 0 (\"off\").\n */\n if (sType == \"led\" || sType == \"rled\") {\n this.bindings[sBinding] = control;\n this.leds[sBinding] = sValue? 1 : 0;\n this.cLiveRegs++;\n return true;\n }\n /*\n * Switches are defined in machine XML files like so:\n *\n * <control type=\"switch\" binding=\"S3\" value=\"1\" width=\"100%\" container=\"center\"/>\n *\n * Only *type* and *binding* attributes are required; if *value* is omitted, the default value is 0 (\"down\").\n *\n * Currently, there is no XML attribute to indicate whether a switch is \"momentary\"; only recognized switches\n * in our internal table can have that attribute.\n */\n if (sType == \"switch\") {\n /*\n * Like LEDs, we allow unrecognized switches to be defined as well, but they won't do anything useful,\n * since only recognized switches will have handlers that perform the appropriate operations.\n */\n if (this.switches[sBinding] === undefined) {\n this.switches[sBinding] = [sValue? 1 : 0, sValue? 1 : 0];\n }\n this.bindings[sBinding] = control;\n var parent = control.parentElement || control;\n parent = parent.parentElement || parent;\n parent.onmousedown = function(panel, sBinding) {\n return function onPressSwitch() {\n panel.pressSwitch(sBinding);\n };\n }(this, sBinding);\n parent.onmouseup = parent.onmouseout = function(panel, sBinding) {\n return function onReleaseSwitch() {\n panel.releaseSwitch(sBinding);\n };\n }(this, sBinding);\n parent.ontouchstart = function(panel, sBinding) {\n return function onPressSwitch(event) {\n panel.pressSwitch(sBinding);\n event.preventDefault();\n };\n }(this, sBinding);\n parent.ontouchend = function(panel, sBinding) {\n return function onReleaseSwitch() {\n panel.releaseSwitch(sBinding);\n };\n }(this, sBinding);\n return true;\n }\n return super.setBinding(sType, sBinding, control, sValue);\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {PanelPDP11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n bus.addIOTable(this, PanelPDP11.UNIBUS_IOTABLE);\n bus.addResetHandler(this.reset.bind(this));\n\n this.displayLEDs();\n this.displaySwitches();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {PanelPDP11}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n /*\n * As noted in init(), our powerUp() method gives us a second opportunity to notify any\n * components that that might care (eg, CPU, Keyboard, and Debugger) that we have some controls\n * (ie, bindings) they might want to use.\n */\n if (this.fBindings) PanelPDP11.init();\n\n if (!data) {\n this.reset(true);\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {PanelPDP11}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * save()\n *\n * This implements save support for the PanelPDP11 component.\n *\n * @this {PanelPDP11}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, [\n this.getAR(),\n this.getDR(),\n this.getSR()\n ]);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the PanelPDP11 component.\n *\n * @this {PanelPDP11}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var a = data[0];\n if (a) {\n this.setAR(a[0]);\n this.setDR(a[1]);\n this.setSR(a[2]);\n }\n return true;\n }\n\n /**\n * resetSwitches()\n *\n * @this {PanelPDP11}\n * @return {boolean}\n */\n resetSwitches()\n {\n for (var sBinding in this.switches) {\n var sw = this.switches[sBinding];\n sw[1] = sw[0];\n }\n this.displaySwitches();\n return true;\n }\n\n /**\n * displayLED(sBinding, value)\n *\n * @this {PanelPDP11}\n * @param {string} sBinding\n * @param {boolean|number} value (true or non-zero if the LED should be on, false or zero if off)\n */\n displayLED(sBinding, value)\n {\n var control = this.bindings[sBinding];\n if (control) {\n /*\n * TODO: Add support for user-definable LED colors?\n */\n control.style.backgroundColor = (value? \"#ff0000\" : \"#000000\");\n }\n }\n\n /**\n * displayLEDs(override)\n *\n * @this {PanelPDP11}\n * @param {boolean|number|null} [override] (true turn on all LEDs, false to turn off all LEDs, null or undefined for normal LED activity)\n */\n displayLEDs(override)\n {\n for (var sBinding in this.leds) {\n this.displayLED(sBinding, override != null? override : this.leds[sBinding]);\n }\n }\n\n /**\n * displaySwitch(sBinding, value)\n *\n * @this {PanelPDP11}\n * @param {string} sBinding\n * @param {boolean|number} value (true if the switch should be \"up\" (on), false if \"down\" (off))\n */\n displaySwitch(sBinding, value)\n {\n var control = this.bindings[sBinding];\n if (control) {\n control.style.marginTop = (value? \"0px\" : \"20px\");\n control.style.backgroundColor = (value? \"#00ff00\" : \"#228B22\");\n }\n }\n\n /**\n * displaySwitches()\n *\n * @this {PanelPDP11}\n */\n displaySwitches()\n {\n for (var sBinding in this.switches) {\n this.displaySwitch(sBinding, this.switches[sBinding][1]);\n }\n }\n\n /**\n * displayValue(sLabel, nValue, cch)\n *\n * This is principally for displaying register values, but in reality, it can be used to display any\n * numeric value bound to the given label.\n *\n * @this {PanelPDP11}\n * @param {string} sLabel\n * @param {number} nValue\n * @param {number} [cch]\n */\n displayValue(sLabel, nValue, cch)\n {\n if (this.bindings[sLabel]) {\n var sVal;\n var nBase = this.dbg && this.dbg.nBase || 8;\n nValue = nValue || 0;\n if (!this.cpu.isRunning() || this.fDisplayLiveRegs) {\n sVal = nBase == 8? Str.toOct(nValue, cch) : Str.toHex(nValue, cch);\n } else {\n sVal = \"--------\".substr(0, cch || 4);\n }\n /*\n * TODO: Determine if this test actually avoids any redrawing when a register hasn't changed, and/or if\n * we should maintain our own (numeric) cache of displayed register values (to avoid creating these temporary\n * string values that will have to garbage-collected), and/or if this is actually slower, and/or if I'm being\n * too obsessive.\n */\n if (this.bindings[sLabel].textContent != sVal) this.bindings[sLabel].textContent = sVal;\n }\n }\n\n /**\n * holdSwitch(fnCallback, sBinding, sDelay)\n *\n * @this {PanelPDP11}\n * @param {function()|null} fnCallback\n * @param {string} sBinding\n * @param {string} [sDelay]\n * @return {boolean} false if wait required, true otherwise\n */\n holdSwitch(fnCallback, sBinding, sDelay)\n {\n if (this.pressSwitch(sBinding)) {\n if (sDelay) {\n var panel = this;\n setTimeout(function() {\n panel.releaseSwitch(sBinding);\n if (fnCallback) fnCallback();\n }, +sDelay);\n return false;\n } else {\n this.releaseSwitch(sBinding);\n }\n }\n return true;\n }\n\n /**\n * setSwitch(sBinding, sValue)\n *\n * @this {PanelPDP11}\n * @param {string} sBinding\n * @param {string} sValue\n * @return {boolean}\n */\n setSwitch(sBinding, sValue)\n {\n if (sBinding == \"SR\") {\n return this.setSRSwitches(Str.parseInt(sValue, 8))\n }\n var sw = this.switches[sBinding];\n if (sw) {\n sw[1] = +sValue? 1 : 0;\n this.displaySwitch(sBinding, sw[1]);\n return true;\n }\n return false;\n }\n\n /**\n * toggleSwitch(sBinding)\n *\n * @this {PanelPDP11}\n * @param {string} sBinding\n * @return {boolean}\n */\n toggleSwitch(sBinding)\n {\n if (this.pressSwitch(sBinding)) {\n this.releaseSwitch(sBinding);\n return true;\n }\n return false;\n }\n\n /**\n * pressSwitch(sBinding)\n *\n * @this {PanelPDP11}\n * @param {string} sBinding\n * @return {boolean}\n */\n pressSwitch(sBinding)\n {\n var sw = this.switches[sBinding];\n if (sw) {\n /*\n * Set the new switch value in sw[1] and then immediately display it\n */\n this.displaySwitch(sBinding, (sw[1] = 1 - sw[1]));\n\n /*\n * Mark the switch as \"pressed\"\n */\n sw[3] = true;\n\n /*\n * Call the appropriate process handler with the current switch value (sw[1])\n */\n if (sw[4]) sw[4].call(this, sw[1], sw[5]);\n\n /*\n * Whenever the user presses 'LOAD' to load a new address, we want the next 'DEP' or 'EXAM'\n * to NOT auto-increment. The next 'DEP' or 'EXAM' will automatically re-enable auto-increment. \n */\n if (sBinding == PanelPDP11.SWITCH.LOAD) {\n this.fAutoInc = false;\n }\n return true;\n }\n return false;\n }\n\n /**\n * releaseSwitch(sBinding)\n *\n * @this {PanelPDP11}\n * @param {string} sBinding\n * @return {boolean}\n */\n releaseSwitch(sBinding)\n {\n /*\n * pressSwitch() is simple: flip the switch's current value in sw[1] and marked it \"pressed\" in sw[3].\n *\n * releaseSwitch() is more complicated, because we must handle both mouseUp and mouseOut events. The first time\n * we receive EITHER of those events AND the switch is marked momentary (sw[2]) AND the switch is pressed (sw[3]),\n * then we must flip the switch back to its original value.\n *\n * Otherwise, the only thing we have to do is mark the switch as \"released\" (ie, set sw[3] to false).\n */\n var sw = this.switches[sBinding];\n if (sw) {\n if (sw[2] && sw[3]) {\n /*\n * Set the new switch value in sw[1] and then immediately display it\n */\n this.displaySwitch(sBinding, (sw[1] = sw[0]));\n\n /*\n * Call the appropriate process handler with the current switch value (sw[1])\n */\n if (sw[4]) sw[4].call(this, sw[1], sw[5]);\n }\n /*\n * Mark the switch as \"released\"\n */\n sw[3] = false;\n return true;\n }\n return false;\n }\n\n /**\n * processStart(value, index)\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {number} [index]\n */\n processStart(value, index)\n {\n if (!value && !this.cpu.isRunning()) {\n\n this.cpu.setPC(this.regAddr);\n\n /*\n * TODO: Verify what the PDP-11/70 Handbook means when it says that when the 'START' switch\n * is depressed, \"the computer system will be cleared.\" I take it to mean that it performs\n * the equivalent of a RESET instruction.\n */\n this.cpu.resetCPU();\n\n /*\n * The PDP-11/70 Handbook goes on to say: \"If the system needs to be initialized but execution\n * is not wanted, the START switch should be depressed while the HALT/ENABLE switch is in the HALT\n * position.\"\n */\n if (this.getSwitch(PanelPDP11.SWITCH.ENABLE)) {\n this.cpu.startCPU();\n }\n }\n }\n\n /**\n * processStep(value, index)\n *\n * If value == 1 (our initial value), then the 'STEP' switch is set to \"S INST\" (step one instruction);\n * otherwise, it's set to \"S BUS CYCLE\" (step one bus cycle).\n *\n * However, since we can't currently support cycle-stepping, I've decided to innovate a little and\n * change the meaning of this switch: the normal (\"up\") position means that successive 'EXAM' and 'DEP'\n * operations will first add 2 to the ADDRESS register, while the opposite (\"down\") position means\n * they will first subtract 2.\n *\n * See processLEDTest() for more of these exciting \"innovations\". ;-)\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {number} [index]\n */\n processStep(value, index)\n {\n /*\n * There's really nothing for us to do here, because the normal press and release handlers\n * already record the state of this switch, so it can be queried as needed, using getSwitch().\n */\n }\n\n /**\n * processEnable(value, index)\n *\n * If value == 1 (our initial value), then the 'ENABLE'/'HALT' switch is set to 'ENABLE', otherwise 'HALT'.\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {number} [index]\n */\n processEnable(value, index)\n {\n /*\n * The \"down\" (0) position is 'HALT', which stops the CPU; however, the \"up\" (1) position ('ENABLE')\n * does NOT start the CPU. You must press 'CONT' to continue execution, which will either continue for\n * one instruction if this switch to set to 'HALT' or indefinitely if it is set to 'ENABLE'.\n */\n if (!value) {\n this.cpu.stopCPU();\n }\n }\n\n /**\n * processContinue(value, index)\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {number} [index]\n */\n processContinue(value, index)\n {\n if (!value && !this.cpu.isRunning()) {\n /*\n * TODO: Technically, we're also supposed to check the 'STEP' switch to determine if we should\n * step one instruction or just one cycle, but we don't currently have the ability to do the latter.\n */\n if (!this.getSwitch(PanelPDP11.SWITCH.ENABLE)) {\n /*\n * Using the Debugger's stepCPU() function is more convenient, and has the pleasant side-effect\n * of updating the debugger's display; however, not all machines with a Front Panel will necessarily\n * also have the Debugger loaded.\n */\n var dbg = this.dbg;\n if (dbg && !dbg.isBusy(true)) {\n dbg.setBusy(true);\n dbg.stepCPU(0, null);\n dbg.setBusy(false);\n }\n else {\n /*\n * For this tiny single-instruction burst, mimic what runCPU() does.\n */\n try {\n var nCyclesStep = this.cpu.stepCPU(1);\n if (nCyclesStep > 0) {\n this.cpu.updateTimers(nCyclesStep);\n this.cpu.addCycles(nCyclesStep, true);\n this.cpu.updateChecksum(nCyclesStep);\n }\n }\n catch(exception) {\n /*\n * We assume that any numeric exception was explicitly thrown by the CPU to interrupt the\n * current instruction. For all other exceptions, we attempt a stack dump.\n */\n if (typeof exception != \"number\") {\n var e = exception;\n this.cpu.setError(e.stack || e.message);\n }\n }\n }\n\n /*\n * Simulate a call to our stop() handler, to update the panel's ADDRESS register with the new PC.\n */\n this.stop();\n\n /*\n * Going through the normal channels (ie, the Computer's updateDisplays() interface) ensures that\n * ALL updateDisplay() handlers will be called, including ours.\n *\n * NOTE: If we used the Debugger's stepCPU() function, then that includes a call to updateDisplay();\n * unfortunately, it will have happened BEFORE we called stop() to update the ADDRESS register, so\n * we still need to call it again.\n */\n if (this.cmp) this.cmp.updateDisplays();\n }\n else {\n this.cpu.startCPU();\n }\n }\n }\n\n /**\n * processDeposit(value, index)\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {number} [index]\n */\n processDeposit(value, index)\n {\n if (value && !this.cpu.isRunning()) {\n if (this.fAutoInc) this.advanceAddr();\n this.fAutoInc = true;\n /*\n * This used to be updateData(), but that only updates regData, whereas setDR() updates both regData and regDisplay,\n * and for these kinds of explicit Front Panel operations, I'm assuming the values should be synced.\n */\n var w = this.setDR(this.regSwitches);\n\n if (this.nAddrSel == PanelPDP11.ADDRSEL.CONS_PHY) {\n /*\n * TODO: Determine if this needs to take the UNIBUS map into consideration.\n */\n this.bus.setWordDirect(this.regAddr, w);\n } else {\n /*\n * TODO: This code is obviously incomplete, since it doesn't take into account the precise ADDRSEL mode.\n */\n this.cpu.setWordSafe(this.regAddr, w);\n }\n }\n }\n\n /**\n * processExamine(value, index)\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {number} [index]\n */\n processExamine(value, index)\n {\n if (!value && !this.cpu.isRunning()) {\n var w;\n if (this.fAutoInc) this.advanceAddr();\n this.fAutoInc = true;\n if (this.nAddrSel == PanelPDP11.ADDRSEL.CONS_PHY) {\n /*\n * TODO: Determine if this needs to take the UNIBUS map into consideration.\n */\n w = this.bus.getWordDirect(this.regAddr);\n } else {\n /*\n * TODO: This code is obviously incomplete, since it doesn't take into account the precise ADDRSEL mode.\n */\n w = this.cpu.getWordSafe(this.regAddr);\n }\n /*\n * This used to be updateData(), but that only updates regData, whereas setDR() updates both regData and regDisplay,\n * and for these kinds of explicit Front Panel operations, I'm assuming the values should be synced.\n */\n this.setDR(w);\n }\n }\n\n /**\n * processLoadAddr(value, index)\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {number} [index]\n */\n processLoadAddr(value, index)\n {\n if (!value && !this.cpu.isRunning()) {\n this.updateAddr(this.regSwitches);\n }\n }\n\n /**\n * processLEDTest(value, index)\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {number} [index]\n */\n processLEDTest(value, index)\n {\n if (value) {\n this.fLEDTest = true;\n this.displayLEDs(true);\n } else {\n this.fLEDTest = false;\n this.displayLEDs();\n /*\n * This is another one of my \"innovations\": when you're done testing the LEDs, all the switches reset as well.\n */\n this.setSRSwitches(0);\n }\n }\n\n /**\n * processSRSwitch(value, index)\n *\n * @this {PanelPDP11}\n * @param {number} value (normally 0 or 1, but we only depend on it being zero or non-zero)\n * @param {number} index\n */\n processSRSwitch(value, index)\n {\n if (value) {\n this.regSwitches |= 1 << index;\n } else {\n this.regSwitches &= ~(1 << index);\n }\n }\n\n /**\n * advanceAddr()\n *\n * This should also take care of the following Front Panel behaviors when the accessing the general-purpose\n * registers:\n *\n * 1) ADDRESS display incremented by 1 (instead of 2)\n * 2) The STEP after the last register is 177700, such that the addresses are looped\n *\n * A third behavior is NOT emulated: preventing the ADDRESS from stepping to the first General Register (177700)\n * from 177676.\n *\n * @this {PanelPDP11}\n * @return {number}\n */\n advanceAddr()\n {\n var nRegs = this.cpu.model <= PDP11.MODEL_1140? 8 : 16;\n var fGenRegs = (this.regAddr >= PDP11.UNIBUS.R0SET0 /*177700*/ && this.regAddr < PDP11.UNIBUS.R0SET0 + nRegs);\n var inc = fGenRegs? 1 : 2;\n var mask = fGenRegs? 0xf : this.bus.nBusMask;\n if (!this.getSwitch(PanelPDP11.SWITCH.STEP)) inc = -inc;\n return this.updateAddr((this.regAddr & ~mask) | ((this.regAddr + inc) & mask));\n }\n\n /**\n * updateAddr(value)\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @return {number}\n */\n updateAddr(value)\n {\n this.regAddr = value & this.bus.nBusMask;\n if (this.ledAddr !== this.regAddr) {\n this.ledAddr = this.regAddr;\n this.updateLEDArray(\"A\", this.ledAddr, 22);\n }\n return this.regAddr;\n }\n\n /**\n * updateData(value)\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @return {number}\n */\n updateData(value)\n {\n this.regData = value & 0xffff;\n if (this.ledData !== this.regData) {\n this.ledData = this.regData;\n this.updateLEDArray(\"D\", this.ledData, 16);\n }\n return this.regData;\n }\n\n /**\n * updateLED(sBinding, value)\n *\n * @this {PanelPDP11}\n * @param {string} sBinding\n * @param {number} value\n * @return {number}\n */\n updateLED(sBinding, value)\n {\n this.leds[sBinding] = value;\n if (!this.fLEDTest) this.displayLED(sBinding, value);\n return value;\n }\n\n /**\n * updateLEDArray(sPrefix, value, nLEDs)\n *\n * @this {PanelPDP11}\n * @param {string} sPrefix\n * @param {number} value\n * @param {number} nLEDs\n */\n updateLEDArray(sPrefix, value, nLEDs)\n {\n for (var i = 0; i < nLEDs; i++) {\n var sBinding = sPrefix + i;\n this.updateLED(sBinding, value & (1 << i));\n }\n }\n\n /**\n * setSRSwitches(value)\n *\n * @this {PanelPDP11}\n * @param {number|undefined} value\n * @return {boolean}\n */\n setSRSwitches(value)\n {\n this.regSwitches = value | 0;\n for (var i = 0; i < 22; i++) {\n this.switches['S'+i][1] = (this.regSwitches & (1 << i))? 1 : 0;\n }\n /*\n * This (re)displays ALL switches, not merely the SR switches, but that's OK.\n */\n this.displaySwitches();\n return true;\n }\n\n /**\n * stop(ms, nCycles)\n *\n * This is a notification handler, called by the Computer, to inform us the CPU has now stopped.\n *\n * @this {PanelPDP11}\n * @param {number} [ms]\n * @param {number} [nCycles]\n */\n stop(ms, nCycles)\n {\n this.updateAddr(this.cpu.regsGen[7]);\n }\n\n /**\n * setAddr(value, fActive)\n *\n * This interface is for passing new addresses to the Front Panel. However, whether or not this will become the\n * ADDRESS actually displayed will depend on other settings (see updateStatus() for details).\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {boolean} [fActive] (true if this should become the \"active\" ADDRESS regardless of other settings)\n */\n setAddr(value, fActive)\n {\n this.regAddr = value;\n }\n\n /**\n * setData(value, fActive)\n *\n * This interface is for passing new data to the Front Panel. However, whether or not this will become the\n * DATA actually displayed will depend on the Front Panel's DATASEL switch setting, as well as the fActive flag.\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {boolean} [fActive] (true if this should become the \"active\" DATA regardless of the DATASEL switch setting)\n */\n setData(value, fActive)\n {\n if (!fActive) {\n this.regData = value;\n } else {\n this.regDisplay = value;\n }\n }\n\n /**\n * updateDisplay(nUpdate)\n *\n * Called by the Computer component at intervals to update registers, LEDs, etc.\n *\n * @this {PanelPDP11}\n * @param {number} [nUpdate] (-2 for power on, -1 for forced, > 0 for periodic, 0 or undefined otherwise)\n */\n updateDisplay(nUpdate)\n {\n if (this.cLiveRegs) {\n\n var fRunning = this.cpu.isRunning();\n var fWaiting = this.cpu.isWaiting();\n\n if (nUpdate < 0 || !fRunning || this.fDisplayLiveRegs) {\n\n /*\n * We arbitrarily separate the display elements into two categories: cheap and expensive.\n *\n * LEDs are considered cheap, register displays are not. So we'll skip the latter if this\n * is a periodic update AND our periodic update counter hasn't reached the periodic update limit.\n */\n if (nUpdate <= 0 || (this.nDisplayCount += nUpdate) >= this.nDisplayLimit) {\n for (var i = 0; i < this.cpu.regsGen.length; i++) {\n this.displayValue('R'+i, this.cpu.regsGen[i]);\n }\n var regPSW = this.cpu.getPSW();\n this.displayValue(\"PS\", regPSW);\n this.displayValue(\"NF\", (regPSW & PDP11.PSW.NF)? 1 : 0, 1);\n this.displayValue(\"ZF\", (regPSW & PDP11.PSW.ZF)? 1 : 0, 1);\n this.displayValue(\"VF\", (regPSW & PDP11.PSW.VF)? 1 : 0, 1);\n this.displayValue(\"CF\", (regPSW & PDP11.PSW.CF)? 1 : 0, 1);\n this.nDisplayCount = 0;\n }\n\n /*\n * Update the ADDRESS and DATA LEDs by selecting the appropriate values.\n *\n * TODO: There is currently no mechanism for selecting regData over regDisplay;\n * we are acting as if the DATASEL switch setting is locked to \"DISPLAY REGISTER\".\n */\n if (nUpdate < -1) {\n this.regAddr = this.cpu.regsGen[7];\n } else if (nUpdate > 0 && fRunning && !fWaiting) {\n this.regAddr = this.cpu.getLastAddr();\n }\n\n this.updateAddr(this.regAddr);\n this.updateData(this.regDisplay);\n\n var bits = this.cpu.getMMUState();\n /*\n * Bit 0 set if 22-bit, bit 1 set if 18-bit, bit 2 set if 16-bit\n */\n this.updateLED(PanelPDP11.LED.B22, bits & 1);\n this.updateLED(PanelPDP11.LED.B18, bits & 2);\n this.updateLED(PanelPDP11.LED.B16, bits & 4);\n }\n }\n }\n\n /**\n * readCNSW(addr, fPreWrite)\n *\n * If fPreWrite, this is a read-before-write, so we must return the DISPLAY register (ie, regDisplay);\n * otherwise, this a normal read, so we should return the SWITCH register (ie, regSwitches).\n *\n *\n * @this {PanelPDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.CNSW or 177570)\n * @param {boolean} [fPreWrite]\n * @return {number}\n */\n readCNSW(addr, fPreWrite)\n {\n return (fPreWrite? this.regDisplay : this.regSwitches) & 0xffff;\n }\n\n /**\n * writeCNSW(value, addr)\n *\n * Handles writes to the DISPLAY register (ie, regDisplay).\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {number} addr (eg, PDP11.UNIBUS.CNSW or 177570)\n */\n writeCNSW(value, addr)\n {\n this.regDisplay = value;\n }\n\n /**\n * PanelPDP11.init()\n *\n * This function operates on every HTML element of class \"panel\", extracting the\n * JSON-encoded parameters for the PanelPDP11 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a PanelPDP11 component, and then binding\n * any associated HTML controls to the new component.\n *\n * NOTE: Unlike most other component init() functions, this one is designed to be\n * called multiple times: once at load time, so that we can bind our print()\n * function to the panel's output control ASAP, and again when the Computer component\n * is verifying that all components are ready and invoking their powerUp() functions.\n *\n * Our powerUp() method gives us a second opportunity to notify any components that\n * that might care (eg, CPU, Keyboard, and Debugger) that we have some controls they\n * might want to use.\n */\n static init()\n {\n var aePanels = Component.getElementsByClass(document, PDP11.APPCLASS, \"panel\");\n for (var iPanel=0; iPanel < aePanels.length; iPanel++) {\n var ePanel = aePanels[iPanel];\n var parmsPanel = Component.getComponentParms(ePanel);\n var panel = Component.getComponentByID(parmsPanel['id']);\n if (!panel) panel = new PanelPDP11(parmsPanel, true);\n Component.bindComponentControls(panel, ePanel, PDP11.APPCLASS);\n }\n }\n}\n\nPanelPDP11.ADDRSEL = {\n KERNEL_I: 0, // use a 16-bit virtual address where bits 16 to 21 are always OFF\n KERNEL_D: 1, // use a 16-bit virtual address where bits 16 to 21 are always OFF\n SUPER_I: 2, // use a 16-bit virtual address where bits 16 to 21 are always OFF\n SUPER_D: 3, // use a 16-bit virtual address where bits 16 to 21 are always OFF\n USER_I: 4, // use a 16-bit virtual address where bits 16 to 21 are always OFF\n USER_D: 5, // use a 16-bit virtual address where bits 16 to 21 are always OFF\n PROG_PHY: 6, // display the 22-bit physical address of the current bus cycle generated by the MMU\n CONS_PHY: 7 // use a 22-bit physical address to perform console operations (e.g., LOAD ADRS, EXAM, & DEP)\n};\n\n/*\n * To get the current state of a switch; eg::\n *\n * this.getSwitch(PanelPDP11.SWITCH.ENABLE)\n *\n * I haven't filled out this table, primarily it only needs to list switches we actually query\n * (eg, non-momentary ones like 'ENABLE' and 'STEP', and 'EXAM' and 'DEP' since they have special\n * \"step\" behavior when pressed more than once in a row). Ditto for the LED table.\n */\nPanelPDP11.SWITCH = {\n DEP: 'DEP',\n ENABLE: 'ENABLE',\n EXAM: 'EXAM',\n LOAD: 'LOAD',\n STEP: 'STEP'\n};\n\nPanelPDP11.LED = {\n B16: 'B16',\n B18: 'B18',\n B22: 'B22'\n};\n\nPanelPDP11.UNIBUS_IOTABLE = {\n [PDP11.UNIBUS.CNSW]: /* 177570 */ [null, null, PanelPDP11.prototype.readCNSW, PanelPDP11.prototype.writeCNSW, \"CNSW\"]\n};\n\n/*\n * Initialize every Panel module on the page.\n */\nWeb.onInit(PanelPDP11.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/bus.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * Data types used by scanMemory()\n */\n\n/**\n * This defines the BlockInfo bit fields used by scanMemory() when it creates the aBlocks array.\n *\n * @typedef {{\n * num: BitField,\n * count: BitField,\n * btmod: BitField,\n * type: BitField\n * }}\n */\nvar BlockInfoPDP11 = Usr.defineBitFields({num:20, count:8, btmod:1, type:3});\n\n/**\n * BusInfoPDP11 object definition (returned by scanMemory())\n *\n * cbTotal: total bytes allocated\n * cBlocks: total Memory blocks allocated\n * aBlocks: array of allocated Memory block numbers\n *\n * @typedef {{\n * cbTotal: number,\n * cBlocks: number,\n * aBlocks: Array.<BlockInfoPDP11>\n * }}\n */\nvar BusInfoPDP11;\n\nclass BusPDP11 extends Component {\n /**\n * BusPDP11(parmsBus, cpu, dbg)\n *\n * The BusPDP11 component manages physical memory and I/O address spaces.\n *\n * The BusPDP11 component has no UI elements, so it does not require an init() handler,\n * but it still inherits from the Component class and must be allocated like any\n * other device component. It's currently allocated by the Computer's init() handler,\n * which then calls the initBus() method of all the other components.\n *\n * For memory beyond the simple needs of the ROM and RAM components (ie, memory-mapped\n * devices), the address space must still be allocated through the BusPDP11 component via\n * addMemory(). If the component needs something more than simple read/write storage,\n * it must provide a custom controller.\n *\n * @param {Object} parmsBus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n constructor(parmsBus, cpu, dbg)\n {\n super(\"Bus\", parmsBus, MessagesPDP11.BUS);\n\n this.cpu = cpu;\n this.dbg = dbg;\n\n /*\n * Supported values for nBusWidth are 16 (default), 18, and 22. This represents the maximum size\n * of the bus for the life of the machine, regardless what memory management mode the CPU has enabled.\n */\n this.nBusWidth = +parmsBus['busWidth'] || 16;\n\n /*\n * Compute all BusPDP11 memory block parameters now, based on the width of the bus.\n *\n * Note that all PCjs machines divide their address space into blocks, using a block size appropriate for\n * the machine's bus width. This allows us to efficiently allocate the entire address space, by reusing blocks\n * as appropriate, and to define to different address behaviors on a block-granular level.\n *\n * For PDPjs machines, the ideal block size is 8Kb (IOPAGE_LENGTH), the size of the IOPAGE on all PDP-11 machines;\n * as a result, our IOController functions assume that all incoming offsets are within a single 8Kb block.\n */\n this.addrTotal = 1 << this.nBusWidth;\n this.nBusMask = (this.addrTotal - 1);\n this.nBlockSize = BusPDP11.IOPAGE_LENGTH;\n this.nBlockShift = Math.log2(this.nBlockSize); // ES6 ALERT (alternatively: Math.log(this.nBlockSize) / Math.LN2)\n this.nBlockLen = this.nBlockSize >> 2;\n this.nBlockLimit = this.nBlockSize - 1;\n this.nBlockTotal = (this.addrTotal / this.nBlockSize) | 0;\n this.nBlockMask = this.nBlockTotal - 1;\n\n\n /*\n * aIOHandlers is an array (ie, a hash) of I/O notification handlers, indexed by address, where each\n * entry contains an array:\n *\n * [0]: readByte(addr)\n * [1]: writeByte(b, addr)\n * [2]: readWord(addr)\n * [3]: writeWord(w, addr)\n *\n * Each of these 4-element arrays are similar to the memory access arrays assigned to entire Memory\n * blocks, but these handlers generally target a specific address (or handful of addresses), while\n * Memory access handlers must service the entire block; see the setAccess() function in the Memory\n * component for details.\n *\n * Finally, for debugging purposes, if an I/O address has a symbolic name and message category,\n * they will be saved here:\n *\n * [4]: symbolic name of I/O address\n * [5]: message category\n *\n * UPDATE: The Debugger wants to piggy-back on these arrays to indicate addresses for which it wants\n * notification. In those cases, the following additional element will be set:\n *\n * [6]: true to break on I/O, false to ignore I/O\n *\n * The false case is important if fIOBreakAll is set, because it allows the Debugger to selectively\n * ignore specific addresses.\n */\n this.aIOHandlers = [];\n this.fIOBreakAll = false;\n this.nDisableFaults = 0;\n this.fFault = false;\n\n /*\n * Array of RESET notification handlers registered by Device components.\n */\n this.afnReset = [];\n\n /*\n * Before we can add any memory blocks that declare our component as a custom memory controller,\n * we must initialize the array that the getControllerAccess() method supplies to the Memory component.\n */\n this.afnIOPage = [\n BusPDP11.IOController.readByte,\n BusPDP11.IOController.writeByte,\n BusPDP11.IOController.readWord,\n BusPDP11.IOController.writeWord\n ];\n\n /*\n * Define all the properties to be initialized by initMemory()\n */\n this.aBusBlocks = this.aMemBlocks = [];\n this.iBlockIOPageBus = this.iBlockIOPageMem = 0;\n this.addrIOPage = this.nIOPageRange = this.nMemMask = 0;\n\n /*\n * We're ready to allocate empty Memory blocks to span the entire physical address space, including the\n * initial location of the IOPAGE.\n */\n this.initMemory();\n\n this.setReady();\n }\n\n /**\n * initMemory()\n *\n * Allocate enough (empty) Memory blocks to span the entire physical address space.\n *\n * Note that we now maintain two parallel arrays of these Memory blocks: aBusBlocks is for use by\n * devices (or any component using the \"direct\" interfaces), while aMemBlocks is for use by the CPU.\n *\n * Whereas the Bus memory map is fixed at init time, the CPU's memory map will vary depending on MMU\n * settings. The CPU will call setIOPageRange() as needed to update the range of addressible memory,\n * which in turn will determine where the IOPAGE can be accessed.\n *\n * @this {BusPDP11}\n */\n initMemory()\n {\n var block = new MemoryPDP11(this);\n block.copyBreakpoints(this.dbg);\n\n this.aBusBlocks = new Array(this.nBlockTotal);\n this.aMemBlocks = new Array(this.nBlockTotal);\n for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {\n this.aBusBlocks[iBlock] = this.aMemBlocks[iBlock] = block;\n }\n /*\n * NOTE: Don't confuse the Bus addrIOPage with the CPU's addrIOPage; ours is fixed,\n * based on the machine's Bus width, whereas the CPU's varies according to the MMU setting.\n */\n this.addrIOPage = this.addrTotal - BusPDP11.IOPAGE_LENGTH;\n this.addMemory(this.addrIOPage, BusPDP11.IOPAGE_LENGTH, MemoryPDP11.TYPE.CONTROLLER, this);\n\n this.iBlockIOPageBus = (this.addrIOPage & this.nBusMask) >>> this.nBlockShift;\n this.iBlockIOPageMem = this.iBlockIOPageBus;\n\n this.nIOPageRange = 0;\n this.nMemMask = this.nBusMask;\n }\n\n /**\n * setIOPageRange(nRange)\n *\n * This function is responsible for syncing the CPU memory map (aMemBlocks) with the Bus memory map (aBusBlocks)\n * and then updating the location of the IOPAGE within the CPU's memory map. The location of the IOPAGE is always\n * fixed at the top of the Bus address space, but it moves (logically) within the CPU's address space according\n * to the CPU's current MMU settings, which nRange is a reflection of.\n *\n * @this {BusPDP11}\n * @param {number} nRange (16, 18 or 22; 0 removes the IOPAGE altogether)\n */\n setIOPageRange(nRange)\n {\n if (nRange != this.nIOPageRange) {\n for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {\n this.aMemBlocks[iBlock] = this.aBusBlocks[iBlock];\n }\n this.nIOPageRange = 0;\n this.nMemMask = this.nBusMask;\n if (nRange) {\n this.nIOPageRange = nRange;\n var addr = (1 << nRange);\n this.nMemMask = (addr - 1);\n addr -= BusPDP11.IOPAGE_LENGTH;\n this.iBlockIOPageMem = (addr & this.nMemMask) >>> this.nBlockShift;\n this.aMemBlocks[this.iBlockIOPageMem] = this.aBusBlocks[this.iBlockIOPageBus];\n }\n }\n }\n\n /**\n * getControllerBuffer(addr)\n *\n * Our Bus component also acts as custom memory controller for the IOPAGE, so it must also provide this function.\n *\n * @this {BusPDP11}\n * @param {number} addr\n * @return {Array} containing the buffer (and the offset within that buffer that corresponds to the requested block)\n */\n getControllerBuffer(addr)\n {\n /*\n * No buffer is required for the IOPAGE; all accesses go to registered I/O handlers or to fault().\n */\n return [null, 0];\n }\n\n /**\n * getControllerAccess()\n *\n * Our Bus component also acts as custom memory controller for the IOPAGE, so it must also provide this function.\n *\n * @this {BusPDP11}\n * @return {Array.<function()>}\n */\n getControllerAccess()\n {\n return this.afnIOPage;\n }\n\n /**\n * getWidth()\n *\n * @this {BusPDP11}\n * @return {number}\n */\n getWidth()\n {\n return this.nBusWidth;\n }\n\n /**\n * reset()\n *\n * Call all registered reset() handlers.\n *\n * @this {BusPDP11}\n */\n reset()\n {\n for (var i = 0; i < this.afnReset.length; i++) {\n this.afnReset[i]();\n }\n this.setIOPageRange(16);\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {BusPDP11}\n * @param {Object|null} data (always null because we supply no powerDown() handler)\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {BusPDP11}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * save()\n *\n * @this {BusPDP11}\n * @return {Object|null}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveMemory());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * @this {BusPDP11}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n return this.restoreMemory(data[0]);\n }\n\n /**\n * addMemory(addr, size, type, controller)\n *\n * Adds new Memory blocks to the specified address range. Any Memory blocks previously\n * added to that range must first be removed via removeMemory(); otherwise, you'll get\n * an allocation conflict error. This helps prevent address calculation errors, redundant\n * allocations, etc.\n *\n * We've relaxed some of the original requirements (ie, that addresses must start at a\n * block-granular address, or that sizes must be equal to exactly one or more blocks),\n * because machines with large block sizes can make it impossible to load certain ROMs at\n * their required addresses. Every allocation still allocates a whole number of blocks.\n *\n * Even so, BusPDP11 memory management does NOT provide a general-purpose heap. Most memory\n * allocations occur during machine initialization and never change. In particular, there\n * is NO support for removing partial-block allocations.\n *\n * Each Memory block keeps track of a start address (addr) and length (used), indicating\n * the used space within the block; any free space that precedes or follows that used space\n * can be allocated later, by simply extending the beginning or ending of the previously used\n * space. However, any holes that might have existed between the original allocation and an\n * extension are subsumed by the extension.\n *\n * @this {BusPDP11}\n * @param {number} addr is the starting physical address of the request\n * @param {number} size of the request, in bytes\n * @param {number} type is one of the MemoryPDP11.TYPE constants\n * @param {Object} [controller] is an optional memory controller component\n * @return {boolean} true if successful, false if not\n */\n addMemory(addr, size, type, controller)\n {\n var addrNext = addr;\n var sizeLeft = size;\n var iBlock = addrNext >>> this.nBlockShift;\n\n while (sizeLeft > 0 && iBlock < this.aBusBlocks.length) {\n\n var block = this.aBusBlocks[iBlock];\n var addrBlock = iBlock * this.nBlockSize;\n var sizeBlock = this.nBlockSize - (addrNext - addrBlock);\n if (sizeBlock > sizeLeft) sizeBlock = sizeLeft;\n\n /*\n * addMemory() will now happily replace an existing block when a memory controller is specified;\n * this is a work-around to make life easier for setIOPageRange(), which otherwise would have to call\n * removeMemory() first, which would just waste time and memory allocating more (empty) blocks.\n */\n if (!controller && block && block.size) {\n if (block.type == type /* && block.controller == controller */) {\n /*\n * Where there is already a similar block with a non-zero size, we allow the allocation only if:\n *\n * 1) addrNext + sizeLeft <= block.addr (the request precedes the used portion of the current block), or\n * 2) addrNext >= block.addr + block.used (the request follows the used portion of the current block)\n */\n if (addrNext + sizeLeft <= block.addr) {\n block.used += (block.addr - addrNext);\n block.addr = addrNext;\n return true;\n }\n if (addrNext >= block.addr + block.used) {\n var sizeAvail = block.size - (addrNext - addrBlock);\n if (sizeAvail > sizeLeft) sizeAvail = sizeLeft;\n block.used = addrNext - block.addr + sizeAvail;\n addrNext = addrBlock + this.nBlockSize;\n sizeLeft -= sizeAvail;\n iBlock++;\n continue;\n }\n }\n return this.reportError(BusPDP11.ERROR.RANGE_INUSE, addrNext, sizeLeft);\n }\n\n var blockNew = new MemoryPDP11(this, addrNext, sizeBlock, this.nBlockSize, type, controller);\n blockNew.copyBreakpoints(this.dbg, block);\n this.aBusBlocks[iBlock++] = blockNew;\n\n addrNext = addrBlock + this.nBlockSize;\n sizeLeft -= sizeBlock;\n }\n\n if (sizeLeft <= 0) {\n this.status(\"Added \" + (size >> 10) + \"Kb \" + MemoryPDP11.TYPE_NAMES[type] + \" at \" + Str.toOct(addr));\n return true;\n }\n\n return this.reportError(BusPDP11.ERROR.RANGE_INVALID, addr, size);\n }\n\n /**\n * cleanMemory(addr, size)\n *\n * @this {BusPDP11}\n * @param {number} addr\n * @param {number} size\n * @return {boolean} true if all blocks were clean, false if dirty; all blocks are cleaned in the process\n */\n cleanMemory(addr, size)\n {\n var fClean = true;\n var iBlock = addr >>> this.nBlockShift;\n var sizeBlock = this.nBlockSize - (addr & this.nBlockLimit);\n while (size > 0 && iBlock < this.aBusBlocks.length) {\n if (this.aBusBlocks[iBlock].fDirty) {\n this.aBusBlocks[iBlock].fDirty = fClean = false;\n this.aBusBlocks[iBlock].fDirtyEver = true;\n }\n size -= sizeBlock;\n sizeBlock = this.nBlockSize;\n iBlock++;\n }\n return fClean;\n }\n\n /**\n * zeroMemory(addr, size, pattern)\n *\n * @this {BusPDP11}\n * @param {number} addr\n * @param {number} size\n * @param {number} [pattern]\n */\n zeroMemory(addr, size, pattern)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0 && iBlock < this.aBusBlocks.length) {\n this.aBusBlocks[iBlock].zero(off, size, pattern);\n size -= this.nBlockSize;\n iBlock++;\n off = 0;\n }\n }\n\n /**\n * scanMemory(info, addr, size)\n *\n * Returns a BusInfoPDP11 object for the specified address range.\n *\n * @this {BusPDP11}\n * @param {BusInfoPDP11} [info] previous BusInfoPDP11, if any\n * @param {number} [addr] starting address of range (0 if none provided)\n * @param {number} [size] size of range, in bytes (up to end of address space if none provided)\n * @return {BusInfoPDP11} updated info (or new info if no previous info provided)\n */\n scanMemory(info, addr, size)\n {\n if (addr == null) addr = 0;\n if (size == null) size = (this.addrTotal - addr) | 0;\n if (info == null) info = {cbTotal: 0, cBlocks: 0, aBlocks: []};\n\n var iBlock = addr >>> this.nBlockShift;\n var iBlockMax = ((addr + size - 1) >>> this.nBlockShift);\n\n info.cbTotal = 0;\n info.cBlocks = 0;\n while (iBlock <= iBlockMax) {\n var block = this.aBusBlocks[iBlock];\n info.cbTotal += block.size;\n if (block.size) {\n info.aBlocks.push(/** @type {BlockInfoPDP11} */ (Usr.initBitFields(BlockInfoPDP11, iBlock, 0, 0, block.type)));\n info.cBlocks++\n }\n iBlock++;\n }\n return info;\n }\n\n /**\n * removeMemory(addr, size)\n *\n * Replaces every block in the specified address range with empty Memory blocks that ignore all reads/writes.\n *\n * TODO: Update the removeMemory() interface to reflect the relaxed requirements of the addMemory() interface.\n *\n * @this {BusPDP11}\n * @param {number} addr\n * @param {number} size\n * @return {boolean} true if successful, false if not\n */\n removeMemory(addr, size)\n {\n if (!(addr & this.nBlockLimit) && size && !(size & this.nBlockLimit)) {\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0) {\n var blockOld = this.aBusBlocks[iBlock];\n var blockNew = new MemoryPDP11(this, addr);\n blockNew.copyBreakpoints(this.dbg, blockOld);\n this.aBusBlocks[iBlock++] = blockNew;\n addr = iBlock * this.nBlockSize;\n size -= this.nBlockSize;\n }\n return true;\n }\n return this.reportError(BusPDP11.ERROR.RANGE_INVALID, addr, size);\n }\n\n /**\n * getMemoryBlocks(addr, size)\n *\n * @this {BusPDP11}\n * @param {number} addr is the starting physical address\n * @param {number} size of the request, in bytes\n * @return {Array} of Memory blocks\n */\n getMemoryBlocks(addr, size)\n {\n var aBlocks = [];\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0 && iBlock < this.aBusBlocks.length) {\n aBlocks.push(this.aBusBlocks[iBlock++]);\n size -= this.nBlockSize;\n }\n return aBlocks;\n }\n\n /**\n * setMemoryAccess(addr, size, afn, fQuiet)\n *\n * Updates the access functions in every block of the specified address range. Since the only components\n * that should be dynamically modifying the memory access functions are those that use addMemory() with a custom\n * memory controller, we require that the block(s) being updated do in fact have a controller.\n *\n * @this {BusPDP11}\n * @param {number} addr\n * @param {number} size\n * @param {Array.<function()>} [afn]\n * @param {boolean} [fQuiet] (true if any error should be quietly logged)\n * @return {boolean} true if successful, false if not\n */\n setMemoryAccess(addr, size, afn, fQuiet)\n {\n if (!(addr & this.nBlockLimit) && size && !(size & this.nBlockLimit)) {\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0) {\n var block = this.aBusBlocks[iBlock];\n if (!block.controller) {\n return this.reportError(BusPDP11.ERROR.NO_CONTROLLER, addr, size, fQuiet);\n }\n block.setAccess(afn, true);\n size -= this.nBlockSize;\n iBlock++;\n }\n return true;\n }\n return this.reportError(BusPDP11.ERROR.RANGE_INVALID, addr, size);\n }\n\n /**\n * setMemoryBlocks(addr, size, aBlocks, type)\n *\n * If no type is specified, then specified address range uses all the provided blocks as-is;\n * this form of setMemoryBlocks() is used for complete physical aliases.\n *\n * Otherwise, new blocks are allocated with the specified type; the underlying memory from the\n * provided blocks is still used, but the new blocks may have different access to that memory.\n *\n * @this {BusPDP11}\n * @param {number} addr is the starting physical address\n * @param {number} size of the request, in bytes\n * @param {Array} aBlocks as returned by getMemoryBlocks()\n * @param {number} [type] is one of the MemoryPDP11.TYPE constants\n */\n setMemoryBlocks(addr, size, aBlocks, type)\n {\n var i = 0;\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0 && iBlock < this.aBusBlocks.length) {\n var block = aBlocks[i++];\n\n if (!block) break;\n if (type !== undefined) {\n var blockNew = new MemoryPDP11(this, addr);\n blockNew.clone(block, type, this.dbg);\n block = blockNew;\n }\n this.aBusBlocks[iBlock++] = block;\n size -= this.nBlockSize;\n }\n }\n\n /**\n * getByte(addr)\n *\n * @this {BusPDP11}\n * @param {number} addr is a physical address\n * @return {number} byte (8-bit) value at that address\n */\n getByte(addr)\n {\n return this.aMemBlocks[(addr & this.nMemMask) >>> this.nBlockShift].readByte(addr & this.nBlockLimit, addr);\n }\n\n /**\n * getWord(addr)\n *\n * @this {BusPDP11}\n * @param {number} addr is a physical address\n * @return {number} word (16-bit) value at that address\n */\n getWord(addr)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nMemMask) >>> this.nBlockShift;\n if (!PDP11.WORDBUS && off == this.nBlockLimit) {\n return this.aMemBlocks[iBlock++].readByte(off, addr) | (this.aMemBlocks[iBlock & this.nBlockMask].readByte(0, addr + 1) << 8);\n }\n return this.aMemBlocks[iBlock].readWord(off, addr);\n }\n\n /**\n * setByte(addr, b)\n *\n * @this {BusPDP11}\n * @param {number} addr is a physical address\n * @param {number} b is the byte (8-bit) value to write\n */\n setByte(addr, b)\n {\n\n this.aMemBlocks[(addr & this.nMemMask) >>> this.nBlockShift].writeByte(addr & this.nBlockLimit, b, addr);\n }\n\n /**\n * setWord(addr, w)\n *\n * @this {BusPDP11}\n * @param {number} addr is a physical address\n * @param {number} w is the word (16-bit) value to write\n */\n setWord(addr, w)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nMemMask) >>> this.nBlockShift;\n if (!PDP11.WORDBUS && off == this.nBlockLimit) {\n this.aMemBlocks[iBlock++].writeByte(off, w & 0xff, addr);\n this.aMemBlocks[iBlock & this.nBlockMask].writeByte(0, (w >> 8) & 0xff, addr + 1);\n return;\n }\n this.aMemBlocks[iBlock].writeWord(off, w, addr);\n }\n\n /**\n * getBlockDirect(addr)\n *\n * @this {BusPDP11}\n * @param {number} addr is a physical address\n * @return {MemoryPDP11}\n */\n getBlockDirect(addr)\n {\n return this.aBusBlocks[(addr & this.nBusMask) >>> this.nBlockShift];\n }\n\n /**\n * getByteDirect(addr)\n *\n * This is used for device I/O and Debugger physical memory requests, not the CPU.\n *\n * @this {BusPDP11}\n * @param {number} addr is a physical address\n * @return {number} byte (8-bit) value at that address\n */\n getByteDirect(addr)\n {\n this.fFault = false;\n this.nDisableFaults++;\n var b = this.getBlockDirect(addr).readByteDirect(addr & this.nBlockLimit, addr);\n this.nDisableFaults--;\n return b;\n }\n\n /**\n * getWordDirect(addr)\n *\n * This is used for device I/O and Debugger physical memory requests, not the CPU.\n *\n * @this {BusPDP11}\n * @param {number} addr is a physical address\n * @return {number} word (16-bit) value at that address\n */\n getWordDirect(addr)\n {\n var w;\n this.fFault = false;\n this.nDisableFaults++;\n var off = addr & this.nBlockLimit;\n var block = this.getBlockDirect(addr);\n if (!PDP11.WORDBUS && off == this.nBlockLimit) {\n w = block.readByteDirect(off, addr) | (this.getBlockDirect(addr + 1).readByteDirect(0, addr + 1) << 8);\n } else {\n w = block.readWordDirect(off, addr);\n }\n this.nDisableFaults--;\n return w;\n }\n\n /**\n * setByteDirect(addr, b)\n *\n * This is used for device I/O and Debugger physical memory requests, not the CPU.\n *\n * @this {BusPDP11}\n * @param {number} addr is a physical address\n * @param {number} b is the byte (8-bit) value to write (we truncate it to 8 bits to be safe)\n */\n setByteDirect(addr, b)\n {\n this.fFault = false;\n this.nDisableFaults++;\n this.getBlockDirect(addr).writeByteDirect(addr & this.nBlockLimit, b & 0xff, addr);\n this.nDisableFaults--;\n }\n\n /**\n * setWordDirect(addr, w)\n *\n * This is used for device I/O and Debugger physical memory requests, not the CPU.\n *\n * @this {BusPDP11}\n * @param {number} addr is a physical address\n * @param {number} w is the word (16-bit) value to write (we truncate it to 16 bits to be safe)\n */\n setWordDirect(addr, w)\n {\n this.fFault = false;\n this.nDisableFaults++;\n var off = addr & this.nBlockLimit;\n var block = this.getBlockDirect(addr);\n if (!PDP11.WORDBUS && off == this.nBlockLimit) {\n block.writeByteDirect(off, w & 0xff, addr);\n this.getBlockDirect(addr + 1).writeByteDirect(0, (w >> 8) & 0xff, addr + 1);\n } else {\n block.writeWordDirect(off, w & 0xffff, addr);\n }\n this.nDisableFaults--;\n }\n\n /**\n * addMemBreak(addr, fWrite)\n *\n * @this {BusPDP11}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint\n */\n addMemBreak(addr, fWrite)\n {\n if (DEBUGGER) {\n var iBlock = addr >>> this.nBlockShift;\n this.aBusBlocks[iBlock].addBreakpoint(addr & this.nBlockLimit, fWrite);\n }\n }\n\n /**\n * removeMemBreak(addr, fWrite)\n *\n * @this {BusPDP11}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint\n */\n removeMemBreak(addr, fWrite)\n {\n if (DEBUGGER) {\n var iBlock = addr >>> this.nBlockShift;\n this.aBusBlocks[iBlock].removeBreakpoint(addr & this.nBlockLimit, fWrite);\n }\n }\n\n /**\n * saveMemory(fAll)\n *\n * The only memory blocks we save are those marked as dirty, but most likely all of RAM will have been marked dirty,\n * and even if our dirty-memory flags were as smart as our dirty-sector flags (ie, were set only when a write changed\n * what was already there), it's unlikely that would reduce the number of RAM blocks we must save/restore. At least\n * all the ROM blocks should be clean (except in the unlikely event that the Debugger was used to modify them).\n *\n * All dirty blocks will be stored in a single array, as pairs of block numbers and data arrays, like so:\n *\n * [iBlock0, [dw0, dw1, ...], iBlock1, [dw0, dw1, ...], ...]\n *\n * In a normal 4Kb block, there will be 1K DWORD values in the data array. Remember that each DWORD is a signed 32-bit\n * integer (because they are formed using bitwise operator rather than floating-point math operators), so don't be\n * surprised to see negative numbers in the data.\n *\n * The above example assumes \"uncompressed\" data arrays. If we choose to use \"compressed\" data arrays, the data arrays\n * will look like:\n *\n * [count0, dw0, count1, dw1, ...]\n *\n * where each count indicates how many times the following DWORD value occurs. A data array length less than 1K indicates\n * that it's compressed, since we'll only store them in compressed form if they actually shrank, and we'll use State\n * helper methods compress() and decompress() to create and expand the compressed data arrays.\n *\n * @this {BusPDP11}\n * @param {boolean} [fAll] (true to save all non-ROM memory blocks, regardless of their dirty flags)\n * @return {Array} a\n */\n saveMemory(fAll)\n {\n var i = 0;\n var a = [];\n\n for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {\n var block = this.aBusBlocks[iBlock];\n /*\n * We have to check both fDirty and fDirtyEver, because we may have called cleanMemory() on some of\n * the memory blocks (eg, video memory), and while cleanMemory() will clear a dirty block's fDirty flag,\n * it also sets the dirty block's fDirtyEver flag, which is left set for the lifetime of the machine.\n */\n if (fAll && block.type != MemoryPDP11.TYPE.ROM || block.fDirty || block.fDirtyEver) {\n a[i++] = iBlock;\n a[i++] = State.compress(block.save());\n }\n }\n\n return a;\n }\n\n /**\n * restoreMemory(a)\n *\n * This restores the contents of all Memory blocks; called by CPUState.restore().\n *\n * In theory, we ONLY have to save/restore block contents. Other block attributes,\n * like the type, the memory controller (if any), and the active memory access functions,\n * should already be restored, since every component (re)allocates all the memory blocks\n * it was using when it's restored. And since the CPU is guaranteed to be the last\n * component to be restored, all those blocks (and their attributes) should be in place now.\n *\n * See saveMemory() for more information on how the memory block contents are saved.\n *\n * @this {BusPDP11}\n * @param {Array} a\n * @return {boolean} true if successful, false if not\n */\n restoreMemory(a)\n {\n var i;\n for (i = 0; i < a.length - 1; i += 2) {\n var iBlock = a[i];\n var adw = a[i+1];\n if (adw && adw.length < this.nBlockLen) {\n adw = State.decompress(adw, this.nBlockLen);\n }\n var block = this.aBusBlocks[iBlock];\n if (!block || !block.restore(adw)) {\n /*\n * Either the block to restore hasn't been allocated, indicating a change in the machine\n * configuration since it was last saved (the most likely explanation) or there's some internal\n * inconsistency (eg, the block size is wrong).\n */\n Component.error(\"Unable to restore memory block \" + iBlock);\n return false;\n }\n }\n return true;\n }\n\n /**\n * getMemoryLimit(type)\n *\n * @this {BusPDP11}\n * @param {number} type is one of the MemoryPDP11.TYPE constants\n * @return {number} (the limiting address of the specified memory type, zero if none)\n */\n getMemoryLimit(type)\n {\n var addr = 0;\n for (var iBlock = 0; iBlock < this.aBusBlocks.length; iBlock++) {\n var block = this.aBusBlocks[iBlock];\n if (block.type == type) {\n addr = block.addr + block.used;\n }\n }\n return addr;\n }\n\n /**\n * addIOHandlers(start, end, fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, message, sName)\n *\n * Add I/O notification handlers to the master list (aIOHandlers). The start and end addresses are typically\n * relative to the starting IOPAGE address, but they can also be absolute; we simply mask all addresses with\n * IOPAGE_MASK.\n *\n * CAVEATS: If a conflict is reported, a partial set of handlers may still have been added. There is no mechanism\n * for removing handlers, since this is considered an initialization function. And finally, when a range of addresses\n * is used, each successive address is advanced by 2, so if you really want to add a handler for a \"+1\" (usually odd)\n * address, then you must add it individually. Failure to do is not necessarily fatal, because the IOController's\n * fallback behavior for an odd address is to call the byte handler for the preceding even address, but the byte\n * handler must be prepared for that (the handlers installed by ROM component's addROM() function are a good example).\n *\n * @this {BusPDP11}\n * @param {number} start address\n * @param {number} end address\n * @param {function(number)|null|undefined} fnReadByte\n * @param {function(number,number)|null|undefined} fnWriteByte\n * @param {function(number)|null|undefined} fnReadWord\n * @param {function(number,number)|null|undefined} fnWriteWord\n * @param {number} [message]\n * @param {string} [sName]\n * @return {boolean} (true if entire range successfully registered, false if any conflicts)\n */\n addIOHandlers(start, end, fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, message, sName)\n {\n var index = (start == end? -1 : 0);\n for (var addr = start; addr <= end; addr += 2) {\n var off = addr & BusPDP11.IOPAGE_MASK;\n if (this.aIOHandlers[off] !== undefined) {\n Component.warning(\"I/O address already registered: \" + Str.toHexLong(addr));\n return false;\n }\n var s = sName || \"unknown\";\n if (s && index >= 0) s += index++;\n this.aIOHandlers[off] = [fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, s, message || MessagesPDP11.BUS, false];\n if (MAXDEBUG) this.log(\"addIOHandlers(\" + Str.toHexLong(addr) + \")\");\n }\n return true;\n }\n\n /**\n * addIOTable(component, table, offReg)\n *\n * Add I/O notification handlers from the specified table (a batch version of addIOHandlers).\n *\n * @this {BusPDP11}\n * @param {Component} component\n * @param {Object} table\n * @param {number} [offReg] (optional offset to add to all register addresses)\n * @return {boolean} (true if entire range successfully registered, false if any conflicts)\n */\n addIOTable(component, table, offReg)\n {\n for (var reg in table) {\n var addr = +reg + (offReg || 0);\n var afn = table[reg];\n\n /*\n * Don't install (ie, ignore) handlers for I/O addresses that are defined with a model number\n * that is \"greater than\" than the current model.\n */\n if (afn[6] && afn[6] > this.cpu.model) continue;\n\n var fnReadByte = afn[0]? afn[0].bind(component) : null;\n var fnWriteByte = afn[1]? afn[1].bind(component) : null;\n var fnReadWord = afn[2]? afn[2].bind(component) : null;\n var fnWriteWord = afn[3]? afn[3].bind(component) : null;\n\n /*\n * As discussed in the IOController comments below, when handlers are being registered for these\n * BYTE-granular UNIBUS addresses, we must install custom fallback handlers for all BYTE accesses.\n */\n if (addr >= PDP11.UNIBUS.R0SET0 && addr <= PDP11.UNIBUS.R6USER) {\n if (!fnReadByte && fnReadWord) {\n fnReadByte = function readByteIORegister(readWord) {\n return function(addr) {\n return readWord(addr) & 0xff;\n }.bind(component);\n }(fnReadWord);\n }\n if (!fnWriteByte && fnWriteWord) {\n fnWriteByte = function writeByteIORegister(writeWord) {\n return function(data, addr) {\n return writeWord(data, addr);\n }.bind(component);\n }(fnWriteWord);\n }\n }\n\n var sReg = afn[4];\n var nRegs = afn[5] || 1;\n\n for (var iReg = 0; iReg < nRegs; iReg++, addr += 2) {\n if (sReg && nRegs > 1) sReg = afn[4] + iReg;\n if (!this.addIOHandlers(addr, addr, fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, afn[7] || component.bitsMessage, sReg || component.idComponent)) {\n return false;\n }\n }\n }\n return true;\n }\n\n /**\n * getAddrInfo(addr)\n *\n * Determine if the physical address is a known IOPAGE address, and return information about it (ie, the name).\n *\n * @this {BusPDP11}\n * @param {number} addr (physical)\n * @return {string|null}\n */\n getAddrInfo(addr)\n {\n var sName = null;\n if (addr >= this.addrIOPage) {\n var off = addr & BusPDP11.IOPAGE_MASK;\n var afn = this.aIOHandlers[off];\n if (afn) sName = afn[BusPDP11.IOHANDLER.REG_NAME];\n }\n return sName;\n }\n\n /**\n * getAddrByName(sName)\n *\n * Determine if the specified name has a corresponding physical address.\n *\n * @this {BusPDP11}\n * @param {string} sName\n * @return {number|null}\n */\n getAddrByName(sName)\n {\n sName = sName.toUpperCase();\n for (var i in this.aIOHandlers) {\n var off = +i;\n var afn = this.aIOHandlers[off];\n if (afn[BusPDP11.IOHANDLER.REG_NAME] == sName) {\n return this.addrIOPage + off;\n }\n }\n return null;\n }\n\n /**\n * addResetHandler(fnReset)\n *\n * @this {BusPDP11}\n * @param {function()} fnReset\n */\n addResetHandler(fnReset)\n {\n this.afnReset.push(fnReset);\n }\n\n /**\n * fault(addr, err, access)\n *\n * Bus interface for signaling alignment errors, invalid memory, etc.\n *\n * @this {BusPDP11}\n * @param {number} addr\n * @param {number} [err]\n * @param {number} [access] (for diagnostic purposes only)\n */\n fault(addr, err, access)\n {\n this.fFault = true;\n if (!this.nDisableFaults) {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.FAULT)) {\n this.dbg.printMessage(\"memory fault (\" + access + \") on \" + this.dbg.toStrBase(addr), true, true);\n }\n if (err) this.cpu.regErr |= err;\n this.cpu.trap(PDP11.TRAP.BUS, 0, addr);\n }\n }\n\n /**\n * checkFault()\n *\n * This also serves as a clearFault() function.\n *\n * @this {BusPDP11}\n * @return {boolean}\n */\n checkFault()\n {\n var f = this.fFault;\n this.fFault = false;\n return f;\n }\n\n /**\n * reportError(errNum, addr, size, fQuiet)\n *\n * @this {BusPDP11}\n * @param {number} errNum\n * @param {number} addr\n * @param {number} size\n * @param {boolean} [fQuiet] (true if any error should be quietly logged)\n * @return {boolean} false\n */\n reportError(errNum, addr, size, fQuiet)\n {\n var sError = \"Memory block error (\" + errNum + \": \" + Str.toHex(addr) + \",\" + Str.toHex(size) + \")\";\n if (fQuiet) {\n if (this.dbg) {\n this.dbg.message(sError);\n } else {\n this.log(sError);\n }\n } else {\n Component.error(sError);\n }\n return false;\n }\n}\n\nBusPDP11.IOPAGE_16BIT = 0x00E000; /*000160000*/ // eg, PDP-11/20\nBusPDP11.IOPAGE_18BIT = 0x03E000; /*000760000*/ // eg, PDP-11/45\nBusPDP11.IOPAGE_22BIT = 0x3FE000; /*017760000*/ // eg, PDP-11/70\nBusPDP11.IOPAGE_LENGTH = 0x002000; // ie, 8Kb\nBusPDP11.IOPAGE_MASK = BusPDP11.IOPAGE_LENGTH - 1;\n\nBusPDP11.MASK_18BIT = 0x03FFFF; /*000777777*/\n\nBusPDP11.UNIBUS_22BIT = 0x3C0000; /*017000000*/\nBusPDP11.MASK_22BIT = 0x3FFFFF; /*017777777*/\n\nBusPDP11.ERROR = {\n RANGE_INUSE: 1,\n RANGE_INVALID: 2,\n NO_CONTROLLER: 3\n};\n\n/*\n * Every entry in the aIOHandlers table is an array with the following indexes:\n */\nBusPDP11.IOHANDLER = {\n READ_BYTE: 0,\n WRITE_BYTE: 1,\n READ_WORD: 2,\n WRITE_WORD: 3,\n REG_NAME: 4,\n MSG_CATEGORY: 5,\n DBG_BREAK: 6\n};\n\n/*\n * These are our custom IOController functions for all IOPAGE accesses. They look up the IOPAGE\n * offset in the aIOHandlers table, and if an entry exists, they use the appropriate IOHANDLER indexes\n * (above) to locate the registered read/write handlers. If no handler is found, then fault() will\n * be called, triggering a trap -- unless traps are disabled because direct access was requested\n * (eg, by the Debugger).\n *\n * Handlers receive the original IOPAGE address that was used, although in most cases, it's ignored,\n * because most handlers usually handle only one address. Only handlers used for a range of addresses\n * must pay attention to it.\n *\n * Note that these functions include fallbacks for byte reads when only word read handlers exist (by\n * masking or shifting the result) and for word reads if only byte handlers exist (by combining bytes).\n * Fallbacks for writes exist, too, but they are slightly more complicated, because a byte write using\n * a word write handler requires reading the word first, and then updating the appropriate byte within\n * that word.\n *\n * Those fallbacks may not always be appropriate; for example, byte writes to some device registers\n * must be zero-extended to update the entire word. For those cases, the fallback's \"preliminary\" read\n * is issued with a fPreWrite flag so that the handler can distinguish a normal read from one of these\n * preliminary reads (aka read-before-write), and return an appropriate value for the update (eg, zero).\n *\n * If none of these fallback behaviors are appropriate, the device has a simple recourse: register\n * handlers for all possible addresses and sizes.\n *\n * Unlike regular Memory blocks, IOPAGE accesses permit word accesses on ODD addresses; that works\n * just fine by registering WORD handlers for the appropriate ODD addresses. For BYTE accesses, it\n * depends. For CPU register addresses, addIOHandlers() installs special byte handlers that perform\n * either a simple word read or write. Other addresses must be handled on a case-by-case basis.\n *\n * TODO: Another small potential improvement would be for addIOHandlers() to install fallbacks for ALL\n * missing handlers, in both the ODD and EVEN cases, so there's never a need to check each function index\n * before calling it. However, since there's no avoiding checking aIOHandlers[off] (unless we FULLY populate\n * the aIOHandlers array), and since these I/O accesses should be pretty infrequent relative to all other\n * memory accesses, the benefit seems pretty minimal. Plus, all our fallback assumptions still need to be\n * verified, so let's wait until that's done before we start optimizing this code.\n */\nBusPDP11.IOController = {\n /**\n * readByte(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByte: function(off, addr)\n {\n var b = -1;\n var bus = this.controller;\n var afn = bus.aIOHandlers[off];\n\n /*\n * Since addr is primarily used to advise an I/O handler of the target IOPAGE address, and since we don't want\n * our handlers to worry about the current IOPAGE location, we truncate addr to 16 bits (the IOPAGE's lowest location).\n */\n var addrMasked = addr & 0xffff;\n\n if (afn) {\n if (afn[BusPDP11.IOHANDLER.READ_BYTE]) {\n b = afn[BusPDP11.IOHANDLER.READ_BYTE](addrMasked);\n } else if (afn[BusPDP11.IOHANDLER.READ_WORD]) {\n if (!(addrMasked & 0x1)) {\n b = afn[BusPDP11.IOHANDLER.READ_WORD](addrMasked) & 0xff;\n } else {\n b = afn[BusPDP11.IOHANDLER.READ_WORD](addrMasked & ~0x1) >> 8;\n }\n }\n } else if (addrMasked & 0x1) {\n afn = bus.aIOHandlers[off & ~0x1];\n if (afn) {\n if (afn[BusPDP11.IOHANDLER.READ_WORD]) {\n b = afn[BusPDP11.IOHANDLER.READ_WORD](addrMasked & ~0x1) >> 8;\n } else if (afn[BusPDP11.IOHANDLER.READ_BYTE]) {\n /*\n * WARNING: This is an unusual fall-back, because we're trying to read an ODD byte\n * access using a BYTE handler registered for EVEN bytes. But if that's all we've got,\n * then presumably the handler is prepared for it (certainly, readROMByte() is).\n */\n b = afn[BusPDP11.IOHANDLER.READ_BYTE](addrMasked)\n }\n }\n }\n if (b >= 0) {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS | afn[BusPDP11.IOHANDLER.MSG_CATEGORY])) {\n this.dbg.printMessage(afn[BusPDP11.IOHANDLER.REG_NAME] + \".readByte(\" + this.dbg.toStrBase(addr) + \"): \" + this.dbg.toStrBase(b), true, !bus.nDisableFaults);\n }\n return b;\n }\n bus.fault(addr, PDP11.CPUERR.TIMEOUT, PDP11.ACCESS.READ_BYTE);\n b = 0xff;\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS)) {\n this.dbg.printMessage(\"warning: unconverted read access to byte @\" + this.dbg.toStrBase(addr) + \": \" + this.dbg.toStrBase(b), true, !bus.nDisableFaults);\n }\n return b;\n },\n\n /**\n * writeByte(off, b, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits)\n * @param {number} addr\n */\n writeByte: function(off, b, addr)\n {\n var w;\n var fWrite = false;\n var bus = this.controller;\n var afn = bus.aIOHandlers[off];\n\n /*\n * Since addr is primarily used to advise an I/O handler of the target IOPAGE address, and since we don't want\n * our handlers to worry about the current IOPAGE location, we truncate addr to 16 bits (the IOPAGE's lowest location).\n */\n var addrMasked = addr & 0xffff;\n\n if (afn) {\n /*\n * If a writeByte() handler exists, call it; we're done.\n */\n if (afn[BusPDP11.IOHANDLER.WRITE_BYTE]) {\n afn[BusPDP11.IOHANDLER.WRITE_BYTE](b, addrMasked);\n fWrite = true;\n }\n /*\n * If a writeWord() handler exists, call the readWord() handler first to get the original data\n * (with fPreWrite set to true) and call writeWord() with the new data inserted into the original data.\n */\n else if (afn[BusPDP11.IOHANDLER.WRITE_WORD]) {\n w = afn[BusPDP11.IOHANDLER.READ_WORD]? afn[BusPDP11.IOHANDLER.READ_WORD](addrMasked, true) : 0;\n if (!(addrMasked & 0x1)) {\n afn[BusPDP11.IOHANDLER.WRITE_WORD]((w & ~0xff) | b, addrMasked);\n fWrite = true;\n } else {\n afn[BusPDP11.IOHANDLER.WRITE_WORD]((w & 0xff) | (b << 8), addrMasked & ~0x1);\n fWrite = true;\n }\n }\n } else if (addrMasked & 0x1) {\n /*\n * If no handler existed, and this address was odd, then perhaps a handler exists for the even address;\n * if so, call the readWord() handler first to get the original data (with fPreWrite set to true) and call\n * writeWord() with the new data inserted into (the high byte of) the original data.\n */\n afn = bus.aIOHandlers[off & ~0x1];\n if (afn) {\n if (afn[BusPDP11.IOHANDLER.WRITE_WORD]) {\n addrMasked &= ~0x1;\n w = afn[BusPDP11.IOHANDLER.READ_WORD]? afn[BusPDP11.IOHANDLER.READ_WORD](addrMasked, true) : 0;\n afn[BusPDP11.IOHANDLER.WRITE_WORD]((w & 0xff) | (b << 8), addrMasked);\n fWrite = true;\n } else if (afn[BusPDP11.IOHANDLER.WRITE_BYTE]) {\n /*\n * WARNING: This is an unusual fall-back, because we're trying to write an ODD byte\n * access using a BYTE handler registered for EVEN bytes. But if that's all we've got,\n * then presumably the handler is prepared for it (certainly, writeROMByte() is).\n */\n afn[BusPDP11.IOHANDLER.WRITE_BYTE](b, addrMasked);\n fWrite = true;\n }\n }\n }\n if (fWrite) {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS | afn[BusPDP11.IOHANDLER.MSG_CATEGORY])) {\n this.dbg.printMessage(afn[BusPDP11.IOHANDLER.REG_NAME] + \".writeByte(\" + this.dbg.toStrBase(addr) + \",\" + this.dbg.toStrBase(b) + \")\", true, !bus.nDisableFaults);\n }\n return;\n }\n bus.fault(addr, PDP11.CPUERR.TIMEOUT, PDP11.ACCESS.WRITE_BYTE);\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS)) {\n this.dbg.printMessage(\"warning: unconverted write access to byte @\" + this.dbg.toStrBase(addr) + \": \" + this.dbg.toStrBase(b), true, !bus.nDisableFaults);\n }\n },\n\n /**\n * readWord(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readWord: function(off, addr)\n {\n var w = -1;\n var bus = this.controller;\n var afn = bus.aIOHandlers[off];\n\n /*\n * Since addr is primarily used to advise an I/O handler of the target IOPAGE address, and since we don't want\n * our handlers to worry about the current IOPAGE location, we truncate addr to 16 bits (the IOPAGE's lowest location).\n */\n var addrMasked = addr & 0xffff;\n\n if (afn) {\n if (afn[BusPDP11.IOHANDLER.READ_WORD]) {\n w = afn[BusPDP11.IOHANDLER.READ_WORD](addrMasked);\n } else if (afn[BusPDP11.IOHANDLER.READ_BYTE]) {\n w = afn[BusPDP11.IOHANDLER.READ_BYTE](addrMasked) | (afn[BusPDP11.IOHANDLER.READ_BYTE](addrMasked + 1) << 8);\n }\n }\n if (w >= 0) {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS | afn[BusPDP11.IOHANDLER.MSG_CATEGORY])) {\n this.dbg.printMessage(afn[BusPDP11.IOHANDLER.REG_NAME] + \".readWord(\" + this.dbg.toStrBase(addr) + \"): \" + this.dbg.toStrBase(w), true, !bus.nDisableFaults);\n }\n return w;\n }\n bus.fault(addr, PDP11.CPUERR.TIMEOUT, PDP11.ACCESS.READ_WORD);\n w = 0xffff;\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS)) {\n this.dbg.printMessage(\"warning: unconverted read access to word @\" + this.dbg.toStrBase(addr) + \": \" + this.dbg.toStrBase(w), true, !bus.nDisableFaults);\n }\n return w;\n },\n\n /**\n * writeWord(off, w, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} w (which should already be pre-masked to 16 bits)\n * @param {number} addr\n */\n writeWord: function(off, w, addr)\n {\n var fWrite = false;\n var bus = this.controller;\n var afn = bus.aIOHandlers[off];\n\n /*\n * Since addr is primarily used to advise an I/O handler of the target IOPAGE address, and since we don't want\n * our handlers to worry about the current IOPAGE location, we truncate addr to 16 bits (the IOPAGE's lowest location).\n */\n var addrMasked = addr & 0xffff;\n\n if (afn) {\n if (afn[BusPDP11.IOHANDLER.WRITE_WORD]) {\n afn[BusPDP11.IOHANDLER.WRITE_WORD](w, addrMasked);\n fWrite = true;\n } else if (afn[BusPDP11.IOHANDLER.WRITE_BYTE]) {\n afn[BusPDP11.IOHANDLER.WRITE_BYTE](w & 0xff, addrMasked);\n afn[BusPDP11.IOHANDLER.WRITE_BYTE](w >> 8, addrMasked + 1);\n fWrite = true;\n }\n }\n if (fWrite) {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS | afn[BusPDP11.IOHANDLER.MSG_CATEGORY])) {\n this.dbg.printMessage(afn[BusPDP11.IOHANDLER.REG_NAME] + \".writeWord(\" + this.dbg.toStrBase(addr) + \",\" + this.dbg.toStrBase(w) + \")\", true, !bus.nDisableFaults);\n }\n return;\n }\n bus.fault(addr, PDP11.CPUERR.TIMEOUT, PDP11.ACCESS.WRITE_WORD);\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS)) {\n this.dbg.printMessage(\"warning: unconverted write access to word @\" + this.dbg.toStrBase(addr) + \": \" + this.dbg.toStrBase(w), true, !bus.nDisableFaults);\n }\n }\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/device.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass DevicePDP11 extends Component {\n /**\n * DevicePDP11(parmsDevice)\n *\n * The Device component implements the following \"default\" devices:\n *\n * KW11 (KW11-L Line Time Clock)\n *\n * as well providing access to all the MMU and CPU registers, PSW, etc.\n *\n * @param {Object} parmsDevice\n */\n constructor(parmsDevice)\n {\n super(\"Device\", parmsDevice, MessagesPDP11.DEVICE);\n\n this.kw11 = { // KW11 registers\n lks: PDP11.KW11.LKS.MON,\n timer: -1 // initBus() will initialize this timer ID\n };\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {DevicePDP11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cmp = cmp;\n this.cpu = cpu;\n this.dbg = dbg;\n\n var device = this;\n this.kw11.timer = cpu.addTimer(function() {\n device.interruptKW11();\n });\n\n this.kw11.irq = cpu.addIRQ(PDP11.KW11.VEC, PDP11.KW11.PRI, MessagesPDP11.KW11);\n\n bus.addIOTable(this, DevicePDP11.UNIBUS_IOTABLE);\n bus.addResetHandler(this.reset.bind(this));\n\n if (DEBUGGER && dbg) {\n dbg.messageDump(MessagesPDP11.MMU, function onDumpMMU(asArgs) {\n device.dumpMMU(asArgs);\n });\n }\n this.setReady();\n }\n\n /**\n * dumpMMU(asArgs)\n *\n * @this {DevicePDP11}\n * @param {Array.<string>} asArgs\n */\n dumpMMU(asArgs)\n {\n if (DEBUGGER) {\n var cpu = this.cpu;\n this.dumpRegs(\"KIPDR\", cpu.regsPDR[0], 0, asArgs[0]);\n this.dumpRegs(\"KDPDR\", cpu.regsPDR[0], 8, asArgs[0]);\n this.dumpRegs(\"KIPAR\", cpu.regsPAR[0], 0, asArgs[0]);\n this.dumpRegs(\"KDPAR\", cpu.regsPAR[0], 8, asArgs[0], true);\n this.dumpRegs(\"SIPDR\", cpu.regsPDR[1], 0, asArgs[0]);\n this.dumpRegs(\"SDPDR\", cpu.regsPDR[1], 8, asArgs[0]);\n this.dumpRegs(\"SIPAR\", cpu.regsPAR[1], 0, asArgs[0]);\n this.dumpRegs(\"SDPAR\", cpu.regsPAR[1], 8, asArgs[0], true);\n this.dumpRegs(\"UIPDR\", cpu.regsPDR[3], 0, asArgs[0]);\n this.dumpRegs(\"UDPDR\", cpu.regsPDR[3], 8, asArgs[0]);\n this.dumpRegs(\"UIPAR\", cpu.regsPAR[3], 0, asArgs[0]);\n this.dumpRegs(\"UDPAR\", cpu.regsPAR[3], 8, asArgs[0], true);\n if (cpu.regMMR3 & PDP11.MMR3.UNIBUS_MAP) {\n this.dumpRegs(\"UNIMAP\", cpu.regsUniMap, -1, asArgs[0]);\n }\n }\n }\n\n /**\n * dumpRegs(sName, aRegs, offset, sFilter, fBreak)\n *\n * @this {DevicePDP11}\n * @param {string} sName\n * @param {Array.<number>} aRegs\n * @param {number} offset\n * @param {string} sFilter\n * @param {boolean} [fBreak]\n */\n dumpRegs(sName, aRegs, offset, sFilter, fBreak)\n {\n if (DEBUGGER) {\n var dbg = this.dbg;\n if (sFilter && sName.indexOf(sFilter.toUpperCase()) < 0) return;\n var nBits = 0;\n var nRegs = 8;\n var sDump = \"\";\n var fIndex = false;\n var nWidth = 8;\n if (offset < 0) {\n nBits = 22;\n nRegs = aRegs.length;\n offset = 0;\n fIndex = true;\n nWidth = 4;\n }\n for (var i = 0; i < nRegs; i++) {\n if (i % nWidth == 0) {\n if (sDump) sDump += '\\n';\n sDump += sName + (fIndex? ('[' + Str.toDec(i, 2) + ']') : '') + ':';\n }\n sDump += ' ' + dbg.toStrBase(aRegs[offset + i], nBits);\n }\n dbg.println(sDump + (fBreak? '\\n' : ''));\n }\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {DevicePDP11}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {DevicePDP11}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {DevicePDP11}\n */\n reset()\n {\n this.kw11.lks = PDP11.KW11.LKS.MON;\n this.cpu.setTimer(this.kw11.timer, 1000/60, true);\n }\n\n /**\n * save()\n *\n * This implements save support for the DevicePDP11 component.\n *\n * @this {DevicePDP11}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, [\n this.kw11.lks\n ]);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the DevicePDP11 component.\n *\n * @this {DevicePDP11}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n /*\n * ES6 ALERT: A handy destructuring assignment, which makes it easy to perform the inverse\n * of what save() does when it collects a bunch of object properties into an array.\n */\n [\n this.kw11.lks\n ] = data[0];\n\n return true;\n }\n\n /**\n * interruptKW11()\n *\n * We used to call this function only when the the KW11's \"Interrupt Enable\" bit was set,\n * but now we call it at 60Hz regardless. In part, this was so we could piggy-back on it\n * to drive display updates, but more importantly, the KW11's \"Monitor\" bit is supposed to\n * be set at the \"line frequency\" independent of whether KW11 interrupts are enabled or not.\n *\n * @this {DevicePDP11}\n */\n interruptKW11()\n {\n this.kw11.lks |= PDP11.KW11.LKS.MON;\n if (this.kw11.lks & PDP11.KW11.LKS.IE) {\n this.cpu.setIRQ(this.kw11.irq);\n }\n if (this.cmp) this.cmp.updateDisplays(1);\n this.cpu.setTimer(this.kw11.timer, 1000/60);\n }\n\n /**\n * readLKS(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.LKS or 177546)\n * @return {number}\n */\n readLKS(addr)\n {\n /*\n * NOTE: The original code always cleared LKS.MON (bit 7) after snapping the value for the read,\n * but based on DEC's \"Non-Interrupt Mode\" programming examples, it's clear that's not how LKS.MON\n * operates; if the caller wants to clear it, they must explicitly clear it with a write.\n */\n return this.kw11.lks;\n }\n\n /**\n * writeLKS(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.LKS or 177546)\n */\n writeLKS(data, addr)\n {\n /*\n * NOTE: The original code always cleared LKS.MON (bit 7) as part of any write, but based on DEC's\n * \"Non-Interrupt Mode\" programming examples, which explicitly CLRB after TSTB reveals LKS.MON is set,\n * I think that was wrong, and that all a write should do is mask off all the other (non-writable) bits.\n */\n this.kw11.lks = data & PDP11.KW11.LKS.MASK;\n if (!(this.kw11.lks & PDP11.KW11.LKS.IE)) this.cpu.clearIRQ(this.kw11.irq);\n }\n\n /**\n * readMMR0(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.MMR0 or 177572)\n * @return {number}\n */\n readMMR0(addr)\n {\n return this.cpu.getMMR0();\n }\n\n /**\n * writeMMR0(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.MMR0 or 177572)\n */\n writeMMR0(data, addr)\n {\n this.cpu.setMMR0((data & ~PDP11.MMR0.COMPLETED) | (this.cpu.regMMR0 & PDP11.MMR0.COMPLETED));\n }\n\n /**\n * readMMR1(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.MMR1 or 177574)\n * @return {number}\n */\n readMMR1(addr)\n {\n return this.cpu.getMMR1();\n }\n\n /**\n * readMMR2(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.MMR2 or 177576)\n * @return {number}\n */\n readMMR2(addr)\n {\n return this.cpu.getMMR2();\n }\n\n /**\n * readMMR3(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.MMR3 or 172516)\n * @return {number}\n */\n readMMR3(addr)\n {\n return this.cpu.getMMR3();\n }\n\n /**\n * writeMMR3(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.MMR3 or 172516)\n */\n writeMMR3(data, addr)\n {\n this.cpu.setMMR3(data);\n }\n\n /**\n * readUNIMAP(addr)\n *\n * NOTE: The UNIBUS map (\"UNIMAP\") is 32 registers spread across 64 words, so we first calculate the word index.\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.UNIMAP)\n * @return {number}\n */\n readUNIMAP(addr)\n {\n var word = (addr >> 1) & 0x3f, reg = word >> 1;\n var data = this.cpu.regsUniMap[reg];\n return (word & 1)? (data >> 16) : (data & 0xffff);\n }\n\n /**\n * writeUNIMAP(data, addr)\n *\n * NOTE: The UNIBUS map (\"UNIMAP\") is 32 registers spread across 64 words, so we first calculate the word index.\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.UNIMAP)\n */\n writeUNIMAP(data, addr)\n {\n var word = (addr >> 1) & 0x3f, reg = word >> 1;\n if (word & 1) {\n this.cpu.regsUniMap[reg] = (this.cpu.regsUniMap[reg] & 0xffff) | ((data & 0x003f) << 16);\n } else {\n this.cpu.regsUniMap[reg] = (this.cpu.regsUniMap[reg] & ~0xffff) | (data & 0xfffe);\n }\n }\n\n /**\n * readSIPDR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.SIPDR0--SIPDR7 or 172200--172216)\n * @return {number}\n */\n readSIPDR(addr)\n {\n var reg = (addr >> 1) & 7;\n return this.cpu.regsPDR[1][reg];\n }\n\n /**\n * writeSIPDR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.SIPDR0--SIPDR7 or 172200--172216)\n */\n writeSIPDR(data, addr)\n {\n var reg = (addr >> 1) & 7;\n this.cpu.regsPDR[1][reg] = data & 0xff0f;\n }\n\n /**\n * readSDPDR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.SDPDR0--SDPDR7 or 172220--172236)\n * @return {number}\n */\n readSDPDR(addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n return this.cpu.regsPDR[1][reg];\n }\n\n /**\n * writeSDPDR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.SDPDR0--SDPDR7 or 172220--172236)\n */\n writeSDPDR(data, addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n this.cpu.regsPDR[1][reg] = data & 0xff0f;\n }\n\n /**\n * readSIPAR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.SIPAR0--SIPAR7 or 172240--172256)\n * @return {number}\n */\n readSIPAR(addr)\n {\n var reg = (addr >> 1) & 7;\n return this.cpu.regsPAR[1][reg];\n }\n\n /**\n * writeSIPAR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.SIPAR0--SIPAR7 or 172240--172256)\n */\n writeSIPAR(data, addr)\n {\n var reg = (addr >> 1) & 7;\n this.cpu.regsPAR[1][reg] = data;\n this.cpu.regsPDR[1][reg] &= 0xff0f;\n\n }\n\n /**\n * readSDPAR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.SDPAR0--SDPAR7 or 172260--172276)\n * @return {number}\n */\n readSDPAR(addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n return this.cpu.regsPAR[1][reg];\n }\n\n /**\n * writeSDPAR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.SDPAR0--SDPAR7 or 172260--172276)\n */\n writeSDPAR(data, addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n this.cpu.regsPAR[1][reg] = data;\n this.cpu.regsPDR[1][reg] &= 0xff0f;\n }\n\n /**\n * readKIPDR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.KIPDR0--KIPDR7 or 172300--172316)\n * @return {number}\n */\n readKIPDR(addr)\n {\n var reg = (addr >> 1) & 7;\n return this.cpu.regsPDR[0][reg];\n }\n\n /**\n * writeKIPDR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.KIPDR0--KIPDR7 or 172300--172316)\n */\n writeKIPDR(data, addr)\n {\n var reg = (addr >> 1) & 7;\n this.cpu.regsPDR[0][reg] = data & 0xff0f;\n }\n\n /**\n * readKDPDR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.KDPDR0--KDPDR7 or 172320--172336)\n * @return {number}\n */\n readKDPDR(addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n return this.cpu.regsPDR[0][reg];\n }\n\n /**\n * writeKDPDR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.KDPDR0--KDPDR7 or 172320--172336)\n */\n writeKDPDR(data, addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n this.cpu.regsPDR[0][reg] = data & 0xff0f;\n }\n\n /**\n * readKIPAR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.KIPAR0--KIPAR7 or 172340--172356)\n * @return {number}\n */\n readKIPAR(addr)\n {\n var reg = (addr >> 1) & 7;\n return this.cpu.regsPAR[0][reg];\n }\n\n /**\n * writeKIPAR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.KIPAR0--KIPAR7 or 172340--172356)\n */\n writeKIPAR(data, addr)\n {\n var reg = (addr >> 1) & 7;\n this.cpu.regsPAR[0][reg] = data;\n this.cpu.regsPDR[0][reg] &= 0xff0f;\n\n }\n\n /**\n * readKDPAR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.KDPAR0--KDPAR7 or 172360--172376)\n * @return {number}\n */\n readKDPAR(addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n return this.cpu.regsPAR[0][reg];\n }\n\n /**\n * writeKDPAR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.KDPAR0--KDPAR7 or 172360--172376)\n */\n writeKDPAR(data, addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n this.cpu.regsPAR[0][reg] = data;\n this.cpu.regsPDR[0][reg] &= 0xff0f;\n }\n\n /**\n * readUIPDR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.UIPDR0--UIPDR7 or 177600--177616)\n * @return {number}\n */\n readUIPDR(addr)\n {\n var reg = (addr >> 1) & 7;\n return this.cpu.regsPDR[3][reg];\n }\n\n /**\n * writeUIPDR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.UIPDR0--UIPDR7 or 177600--177616)\n */\n writeUIPDR(data, addr)\n {\n var reg = (addr >> 1) & 7;\n this.cpu.regsPDR[3][reg] = data & 0xff0f;\n }\n\n /**\n * readUDPDR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.UDPDR0--UDPDR7 or 177620--177636)\n * @return {number}\n */\n readUDPDR(addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n return this.cpu.regsPDR[3][reg];\n }\n\n /**\n * writeUDPDR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.UDPDR0--UDPDR7 or 177620--177636)\n */\n writeUDPDR(data, addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n this.cpu.regsPDR[3][reg] = data & 0xff0f;\n }\n\n /**\n * readUIPAR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.UIPAR0--UIPAR7 or 177640--177656)\n * @return {number}\n */\n readUIPAR(addr)\n {\n var reg = (addr >> 1) & 7;\n return this.cpu.regsPAR[3][reg];\n }\n\n /**\n * writeUIPAR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.UIPAR0--UIPAR7 or 177640--177656)\n */\n writeUIPAR(data, addr)\n {\n var reg = (addr >> 1) & 7;\n this.cpu.regsPAR[3][reg] = data;\n this.cpu.regsPDR[3][reg] &= 0xff0f;\n\n }\n\n /**\n * readUDPAR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.UDPAR0--UDPAR7 or 177660--177676)\n * @return {number}\n */\n readUDPAR(addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n return this.cpu.regsPAR[3][reg];\n }\n\n /**\n * writeUDPAR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.UDPAR0--UDPAR7 or 177660--177676)\n */\n writeUDPAR(data, addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n this.cpu.regsPAR[3][reg] = data;\n this.cpu.regsPDR[3][reg] &= 0xff0f;\n }\n\n /**\n * readRSET0(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.R0SET0--R5SET0 or 177700--177705)\n * @return {number}\n */\n readRSET0(addr)\n {\n var data;\n var reg = addr & 7;\n if (this.cpu.regPSW & PDP11.PSW.REGSET) {\n data = this.cpu.regsAlt[reg];\n } else {\n data = this.cpu.regsGen[reg];\n }\n return data;\n }\n\n /**\n * writeRSET0(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.R0SET0--R5SET0 or 177700--177705)\n */\n writeRSET0(data, addr)\n {\n var reg = addr & 7;\n if (this.cpu.regPSW & PDP11.PSW.REGSET) {\n this.cpu.regsAlt[reg] = data;\n } else {\n this.cpu.regsGen[reg] = data;\n }\n }\n\n /**\n * readR6KERNEL(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.R6KERNEL or 177706)\n * @return {number}\n */\n readR6KERNEL(addr)\n {\n var data;\n if (!(this.cpu.regPSW & PDP11.PSW.CMODE)) { // Kernel Mode\n data = this.cpu.regsGen[6];\n } else {\n data = this.cpu.regsAltStack[0];\n }\n return data;\n }\n\n /**\n * writeR6KERNEL(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.R6KERNEL or 177706)\n */\n writeR6KERNEL(data, addr)\n {\n if (!(this.cpu.regPSW & PDP11.PSW.CMODE)) { // Kernel Mode\n this.cpu.regsGen[6] = data;\n } else {\n this.cpu.regsAltStack[0] = data;\n }\n }\n\n /**\n * readR7KERNEL(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.R7KERNEL or 177707)\n * @return {number}\n */\n readR7KERNEL(addr)\n {\n return this.cpu.regsGen[7];\n }\n\n /**\n * writeR7KERNEL(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.R7KERNEL or 177707)\n */\n writeR7KERNEL(data, addr)\n {\n this.cpu.regsGen[7] = data;\n }\n\n /**\n * readRSET1(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.R0SET1--R5SET1 or 177710--177715)\n * @return {number}\n */\n readRSET1(addr)\n {\n var data;\n var reg = addr & 7;\n if (this.cpu.regPSW & PDP11.PSW.REGSET) {\n data = this.cpu.regsGen[reg];\n } else {\n data = this.cpu.regsAlt[reg];\n }\n return data;\n }\n\n /**\n * writeRSET1(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.R0SET1--R5SET1 or 177710--177715)\n */\n writeRSET1(data, addr)\n {\n var reg = addr & 7;\n if (this.cpu.regPSW & PDP11.PSW.REGSET) {\n this.cpu.regsGen[reg] = data;\n } else {\n this.cpu.regsAlt[reg] = data;\n }\n }\n\n /**\n * readR6SUPER(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.R6SUPER or 177716)\n * @return {number}\n */\n readR6SUPER(addr)\n {\n var data;\n if (((this.cpu.regPSW & PDP11.PSW.CMODE) >> PDP11.PSW.SHIFT.CMODE) == PDP11.MODE.SUPER) {\n data = this.cpu.regsGen[6];\n } else {\n data = this.cpu.regsAltStack[1];\n }\n return data;\n }\n\n /**\n * writeR6SUPER(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.R6SUPER or 177716)\n */\n writeR6SUPER(data, addr)\n {\n if (((this.cpu.regPSW & PDP11.PSW.CMODE) >> PDP11.PSW.SHIFT.CMODE) == PDP11.MODE.SUPER) {\n this.cpu.regsGen[6] = data;\n } else {\n this.cpu.regsAltStack[1] = data;\n }\n }\n\n /**\n * readR6USER(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.R6USER or 177717)\n * @return {number}\n */\n readR6USER(addr)\n {\n var data;\n if (((this.cpu.regPSW & PDP11.PSW.CMODE) >> PDP11.PSW.SHIFT.CMODE) == PDP11.MODE.USER) {\n data = this.cpu.regsGen[6];\n } else {\n data = this.cpu.regsAltStack[3];\n }\n return data;\n }\n\n /**\n * writeR6USER(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.R6USER or 177717)\n */\n writeR6USER(data, addr)\n {\n if (((this.cpu.regPSW & PDP11.PSW.CMODE) >> PDP11.PSW.SHIFT.CMODE) == PDP11.MODE.USER) {\n this.cpu.regsGen[6] = data;\n } else {\n this.cpu.regsAltStack[3] = data;\n }\n }\n\n /**\n * readCTRL(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.LAERR--UNDEF2 or 177740--177756)\n * @return {number}\n */\n readCTRL(addr)\n {\n var reg = (addr - PDP11.UNIBUS.CTRL) >> 1;\n return this.cpu.regsControl[reg];\n }\n\n /**\n * writeCTRL(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.LAERR--UNDEF2 or 177740--177756)\n */\n writeCTRL(data, addr)\n {\n var reg = (addr - PDP11.UNIBUS.CTRL) >> 1;\n this.cpu.regsControl[reg] = data;\n }\n\n /**\n * readSIZE(addr)\n *\n * We're adhering to DEC's documentation, which says:\n *\n * This read-only register specifies the memory size of the system. It is defined to indicate the\n * last addressable block of 32 words in memory (bit 0 is equivalent to bit 6 of the Physical Address).\n *\n * Looking at the Memory Clear \"toggle-in\" code in /devices/pdp11/machine/1170/panel/debugger/README.md, the\n * memory loop gives up when the block number stored in KIPAR0 is >= LSIZE, suggesting that LSIZE is actually\n * the total number of 64-byte blocks, rather than the block number of the last block. But that code is\n * not conclusive, since it writes 8192 bytes at a time rather than 64, so it doesn't really matter if LSIZE\n * is off by one.\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.LSIZE--HSIZE or 177760--177762)\n * @return {number}\n */\n readSIZE(addr)\n {\n return addr == PDP11.UNIBUS.LSIZE? ((this.bus.getMemoryLimit(MemoryPDP11.TYPE.RAM) >> 6) - 1) : 0;\n }\n\n /**\n * writeSIZE(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.LSIZE--HSIZE or 177760--177762)\n */\n writeSIZE(data, addr)\n {\n }\n\n /**\n * readSYSID(addr)\n *\n * TODO: For SYSID, we currently ignore writes and return 1 on reads\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.SYSID or 177764)\n * @return {number}\n */\n readSYSID(addr)\n {\n return 1;\n }\n\n /**\n * writeSYSID(data, addr)\n *\n * TODO: For SYSID, we currently ignore writes and return 1 on reads\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.SYSID or 177764)\n */\n writeSYSID(data, addr)\n {\n }\n\n /**\n * readCPUERR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.CPUERR or 177766)\n * @return {number}\n */\n readCPUERR(addr)\n {\n return this.cpu.regErr;\n }\n\n /**\n * writeCPUERR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.CPUERR or 177766)\n */\n writeCPUERR(data, addr)\n {\n this.cpu.regErr = 0; // TODO: Confirm that writes always zero the register\n }\n\n /**\n * readMBR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.MB or 177770)\n * @return {number}\n */\n readMBR(addr)\n {\n return this.cpu.regMBR;\n }\n\n /**\n * writeMBR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.MB or 177770)\n */\n writeMBR(data, addr)\n {\n if (!(addr & 0x1)) {\n data &= 0xff; // required for KB11-CM without MFPT instruction\n }\n this.cpu.regMBR = data;\n }\n\n /**\n * readPIR(addr, fPreWrite)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.PIR or 177772)\n * @param {boolean} [fPreWrite]\n * @return {number}\n */\n readPIR(addr, fPreWrite)\n {\n if (fPreWrite) return 0;\n return this.cpu.getPIR();\n }\n\n /**\n * writePIR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.PIR or 177772)\n */\n writePIR(data, addr)\n {\n this.cpu.setPIR(data);\n }\n\n /**\n * readSLR(addr, fPreWrite)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.SL or 177774)\n * @param {boolean} [fPreWrite]\n * @return {number}\n */\n readSLR(addr, fPreWrite)\n {\n if (fPreWrite) return 0;\n return this.cpu.getSLR();\n }\n\n /**\n * writeSLR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.SL or 177774)\n */\n writeSLR(data, addr)\n {\n this.cpu.setSLR(data);\n }\n\n /**\n * readPSW(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.PSW or 177776)\n * @return {number}\n */\n readPSW(addr)\n {\n return this.cpu.getPSW();\n }\n\n /**\n * writePSW(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.PSW or 177776)\n */\n writePSW(data, addr)\n {\n /*\n * pdp11.js disallowed PSW.TF in addition to PSW.UNUSED, but DEC's \"TRAP TEST\" expects the\n * following instruction to trap:\n *\n * 004174: 052767 000020 173574 BIS #20,177776\n *\n * Since that test was written for the PDP-11/20, it's possible that newer machines have a different\n * behavior, but for now, we assume that all machines allow setting PSW.TF.\n *\n * Moreover, we have changed setPSW() to disallow the setting of any bits not supported by the current\n * CPU model, so it seems rather pointless to do any masking of bits here.\n */\n this.cpu.setPSW(data);\n }\n\n /**\n * writeIgnored(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr\n */\n writeIgnored(data, addr)\n {\n if (this.messageEnabled()) {\n this.printMessage(\"writeIgnored(\" + Str.toOct(addr) + \"): \" + Str.toOct(data), true, true);\n }\n }\n\n /**\n * DevicePDP11.init()\n *\n * This function operates on every HTML element of class \"device\", extracting the\n * JSON-encoded parameters for the DevicePDP11 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a DevicePDP11 component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeDevice = Component.getElementsByClass(document, PDP11.APPCLASS, \"device\");\n for (var iDevice = 0; iDevice < aeDevice.length; iDevice++) {\n var device;\n var eDevice = aeDevice[iDevice];\n var parmsDevice = Component.getComponentParms(eDevice);\n switch(parmsDevice['type']) {\n case 'default':\n device = new DevicePDP11(parmsDevice);\n Component.bindComponentControls(device, eDevice, PDP11.APPCLASS);\n break;\n case 'pc11':\n device = new PC11(parmsDevice);\n Component.bindComponentControls(device, eDevice, PDP11.APPCLASS);\n break;\n case 'rl11':\n device = new RL11(parmsDevice);\n Component.bindComponentControls(device, eDevice, PDP11.APPCLASS);\n break;\n case 'rk11':\n device = new RK11(parmsDevice);\n Component.bindComponentControls(device, eDevice, PDP11.APPCLASS);\n break;\n case 'rx11':\n device = new RX11(parmsDevice);\n Component.bindComponentControls(device, eDevice, PDP11.APPCLASS);\n break;\n }\n }\n }\n}\n\n/*\n * ES6 ALERT: As you can see below, I've finally started using computed property names.\n */\nDevicePDP11.UNIBUS_IOTABLE = {\n [PDP11.UNIBUS.UNIMAP]: /* 170200 */ [null, null, DevicePDP11.prototype.readUNIMAP, DevicePDP11.prototype.writeUNIMAP, \"UNIMAP\", 64, PDP11.MODEL_1170],\n [PDP11.UNIBUS.SIPDR0]: /* 172200 */ [null, null, DevicePDP11.prototype.readSIPDR, DevicePDP11.prototype.writeSIPDR, \"SIPDR\", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],\n [PDP11.UNIBUS.SDPDR0]: /* 172220 */ [null, null, DevicePDP11.prototype.readSDPDR, DevicePDP11.prototype.writeSDPDR, \"SDPDR\", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],\n [PDP11.UNIBUS.SIPAR0]: /* 172240 */ [null, null, DevicePDP11.prototype.readSIPAR, DevicePDP11.prototype.writeSIPAR, \"SIPAR\", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],\n [PDP11.UNIBUS.SDPAR0]: /* 172260 */ [null, null, DevicePDP11.prototype.readSDPAR, DevicePDP11.prototype.writeSDPAR, \"SDPAR\", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],\n [PDP11.UNIBUS.KIPDR0]: /* 172300 */ [null, null, DevicePDP11.prototype.readKIPDR, DevicePDP11.prototype.writeKIPDR, \"KIPDR\", 8, PDP11.MODEL_1140, MessagesPDP11.MMU],\n [PDP11.UNIBUS.KDPDR0]: /* 172320 */ [null, null, DevicePDP11.prototype.readKDPDR, DevicePDP11.prototype.writeKDPDR, \"KDPDR\", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],\n [PDP11.UNIBUS.KIPAR0]: /* 172340 */ [null, null, DevicePDP11.prototype.readKIPAR, DevicePDP11.prototype.writeKIPAR, \"KIPAR\", 8, PDP11.MODEL_1140, MessagesPDP11.MMU],\n [PDP11.UNIBUS.KDPAR0]: /* 172360 */ [null, null, DevicePDP11.prototype.readKDPAR, DevicePDP11.prototype.writeKDPAR, \"KDPAR\", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],\n [PDP11.UNIBUS.MMR3]: /* 172516 */ [null, null, DevicePDP11.prototype.readMMR3, DevicePDP11.prototype.writeMMR3, \"MMR3\", 1, PDP11.MODEL_1145, MessagesPDP11.MMU],\n [PDP11.UNIBUS.LKS]: /* 177546 */ [null, null, DevicePDP11.prototype.readLKS, DevicePDP11.prototype.writeLKS, \"LKS\"],\n [PDP11.UNIBUS.MMR0]: /* 177572 */ [null, null, DevicePDP11.prototype.readMMR0, DevicePDP11.prototype.writeMMR0, \"MMR0\", 1, PDP11.MODEL_1140, MessagesPDP11.MMU],\n [PDP11.UNIBUS.MMR1]: /* 177574 */ [null, null, DevicePDP11.prototype.readMMR1, DevicePDP11.prototype.writeIgnored, \"MMR1\", 1, PDP11.MODEL_1145, MessagesPDP11.MMU],\n [PDP11.UNIBUS.MMR2]: /* 177576 */ [null, null, DevicePDP11.prototype.readMMR2, DevicePDP11.prototype.writeIgnored, \"MMR2\", 1, PDP11.MODEL_1140, MessagesPDP11.MMU],\n [PDP11.UNIBUS.UIPDR0]: /* 177600 */ [null, null, DevicePDP11.prototype.readUIPDR, DevicePDP11.prototype.writeUIPDR, \"UIPDR\", 8, PDP11.MODEL_1140, MessagesPDP11.MMU],\n [PDP11.UNIBUS.UDPDR0]: /* 177620 */ [null, null, DevicePDP11.prototype.readUDPDR, DevicePDP11.prototype.writeUDPDR, \"UDPDR\", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],\n [PDP11.UNIBUS.UIPAR0]: /* 177640 */ [null, null, DevicePDP11.prototype.readUIPAR, DevicePDP11.prototype.writeUIPAR, \"UIPAR\", 8, PDP11.MODEL_1140, MessagesPDP11.MMU],\n [PDP11.UNIBUS.UDPAR0]: /* 177660 */ [null, null, DevicePDP11.prototype.readUDPAR, DevicePDP11.prototype.writeUDPAR, \"UDPAR\", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],\n [PDP11.UNIBUS.R0SET0]: /* 177700 */ [null, null, DevicePDP11.prototype.readRSET0, DevicePDP11.prototype.writeRSET0, \"R0SET0\"],\n [PDP11.UNIBUS.R1SET0]: /* 177701 */ [null, null, DevicePDP11.prototype.readRSET0, DevicePDP11.prototype.writeRSET0, \"R1SET0\"],\n [PDP11.UNIBUS.R2SET0]: /* 177702 */ [null, null, DevicePDP11.prototype.readRSET0, DevicePDP11.prototype.writeRSET0, \"R2SET0\"],\n [PDP11.UNIBUS.R3SET0]: /* 177703 */ [null, null, DevicePDP11.prototype.readRSET0, DevicePDP11.prototype.writeRSET0, \"R3SET0\"],\n [PDP11.UNIBUS.R4SET0]: /* 177704 */ [null, null, DevicePDP11.prototype.readRSET0, DevicePDP11.prototype.writeRSET0, \"R4SET0\"],\n [PDP11.UNIBUS.R5SET0]: /* 177705 */ [null, null, DevicePDP11.prototype.readRSET0, DevicePDP11.prototype.writeRSET0, \"R5SET0\"],\n [PDP11.UNIBUS.R6KERNEL]:/* 177706 */ [null, null, DevicePDP11.prototype.readR6KERNEL,DevicePDP11.prototype.writeR6KERNEL,\"R6KERNEL\"],\n [PDP11.UNIBUS.R7KERNEL]:/* 177707 */ [null, null, DevicePDP11.prototype.readR7KERNEL,DevicePDP11.prototype.writeR7KERNEL,\"R7KERNEL\"],\n [PDP11.UNIBUS.R0SET1]: /* 177710 */ [null, null, DevicePDP11.prototype.readRSET1, DevicePDP11.prototype.writeRSET1, \"R0SET1\", 1, PDP11.MODEL_1145],\n [PDP11.UNIBUS.R1SET1]: /* 177711 */ [null, null, DevicePDP11.prototype.readRSET1, DevicePDP11.prototype.writeRSET1, \"R1SET1\", 1, PDP11.MODEL_1145],\n [PDP11.UNIBUS.R2SET1]: /* 177712 */ [null, null, DevicePDP11.prototype.readRSET1, DevicePDP11.prototype.writeRSET1, \"R2SET1\", 1, PDP11.MODEL_1145],\n [PDP11.UNIBUS.R3SET1]: /* 177713 */ [null, null, DevicePDP11.prototype.readRSET1, DevicePDP11.prototype.writeRSET1, \"R3SET1\", 1, PDP11.MODEL_1145],\n [PDP11.UNIBUS.R4SET1]: /* 177714 */ [null, null, DevicePDP11.prototype.readRSET1, DevicePDP11.prototype.writeRSET1, \"R4SET1\", 1, PDP11.MODEL_1145],\n [PDP11.UNIBUS.R5SET1]: /* 177715 */ [null, null, DevicePDP11.prototype.readRSET1, DevicePDP11.prototype.writeRSET1, \"R5SET1\", 1, PDP11.MODEL_1145],\n [PDP11.UNIBUS.R6SUPER]: /* 177716 */ [null, null, DevicePDP11.prototype.readR6SUPER, DevicePDP11.prototype.writeR6SUPER, \"R6SUPER\", 1, PDP11.MODEL_1145],\n [PDP11.UNIBUS.R6USER]: /* 177717 */ [null, null, DevicePDP11.prototype.readR6USER, DevicePDP11.prototype.writeR6USER, \"R6USER\", 1, PDP11.MODEL_1145],\n [PDP11.UNIBUS.CTRL]: /* 177740 */ [null, null, DevicePDP11.prototype.readCTRL, DevicePDP11.prototype.writeCTRL, \"CTRL\", 8, PDP11.MODEL_1170],\n [PDP11.UNIBUS.LSIZE]: /* 177760 */ [null, null, DevicePDP11.prototype.readSIZE, DevicePDP11.prototype.writeSIZE, \"LSIZE\", 1, PDP11.MODEL_1170],\n [PDP11.UNIBUS.HSIZE]: /* 177762 */ [null, null, DevicePDP11.prototype.readSIZE, DevicePDP11.prototype.writeSIZE, \"HSIZE\", 1, PDP11.MODEL_1170],\n [PDP11.UNIBUS.SYSID]: /* 177764 */ [null, null, DevicePDP11.prototype.readSYSID, DevicePDP11.prototype.writeSYSID, \"SYSID\", 1, PDP11.MODEL_1170],\n [PDP11.UNIBUS.CPUERR]: /* 177766 */ [null, null, DevicePDP11.prototype.readCPUERR, DevicePDP11.prototype.writeCPUERR, \"ERR\", 1, PDP11.MODEL_1170],\n [PDP11.UNIBUS.MB]: /* 177770 */ [null, null, DevicePDP11.prototype.readMBR, DevicePDP11.prototype.writeMBR, \"MBR\", 1, PDP11.MODEL_1170],\n [PDP11.UNIBUS.PIR]: /* 177772 */ [null, null, DevicePDP11.prototype.readPIR, DevicePDP11.prototype.writePIR, \"PIR\"],\n [PDP11.UNIBUS.SL]: /* 177774 */ [null, null, DevicePDP11.prototype.readSLR, DevicePDP11.prototype.writeSLR, \"SLR\"],\n [PDP11.UNIBUS.PSW]: /* 177776 */ [null, null, DevicePDP11.prototype.readPSW, DevicePDP11.prototype.writePSW, \"PSW\"]\n};\n\n/*\n * Initialize all the DevicePDP11 modules on the page.\n */\nWeb.onInit(DevicePDP11.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/memory.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * @class DataView\n * @property {function(number,boolean):number} getUint8\n * @property {function(number,number,boolean)} setUint8\n * @property {function(number,boolean):number} getUint16\n * @property {function(number,number,boolean)} setUint16\n * @property {function(number,boolean):number} getInt32\n * @property {function(number,number,boolean)} setInt32\n */\n\n/**\n * @class MemoryPDP11\n * @property {number} id\n * @property {number} used\n * @property {number} size\n * @property {Int32Array} adw\n * @property {Object} controller\n * @property {DebuggerPDP11} dbg\n */\nclass MemoryPDP11 {\n /**\n * MemoryPDP11(bus, addr, used, size, type, controller)\n *\n * The Bus component allocates Memory objects so that each has a memory buffer with a\n * block-granular starting address and an address range equal to bus.nBlockSize; however,\n * the size of any given Memory object's underlying buffer can be either zero or bus.nBlockSize;\n * memory read/write functions for empty (buffer-less) blocks are mapped to readNone/writeNone.\n *\n * The Bus allocates empty blocks for the entire address space during initialization, so that\n * any reads/writes to undefined addresses will have no effect. Later, the ROM and RAM\n * components will ask the Bus to allocate memory for specific ranges, and the Bus will allocate\n * as many new blockSize Memory objects as the ranges require. Partial Memory blocks could\n * also be supported in theory, but in practice, they're not.\n *\n * Because Memory blocks now allow us to have a \"sparse\" address space, we could choose to\n * take the memory hit of allocating 4K arrays per block, where each element stores only one byte,\n * instead of the more frugal but slightly slower approach of allocating arrays of 32-bit dwords\n * (LONGARRAYS) and shifting/masking bytes/words to/from dwords; in theory, byte accesses would\n * be faster and word accesses somewhat less faster.\n *\n * However, preliminary testing of that feature (BYTEARRAYS) did not yield significantly faster\n * performance, so it is OFF by default to minimize our memory consumption. Using TYPEDARRAYS\n * would seem best, but as discussed in defines.js, it's off by default, because it doesn't perform\n * as well as LONGARRAYS; the other advantage of TYPEDARRAYS is that it should theoretically use\n * about 1/2 the memory of LONGARRAYS (32-bit elements vs 64-bit numbers), but I value speed over\n * size at this point. Also, not all JavaScript implementations support TYPEDARRAYS (IE9 is probably\n * the only real outlier: it lacks typed arrays but otherwise has all the necessary HTML5 support).\n *\n * WARNING: Since Memory blocks are low-level objects that have no UI requirements, they\n * do not inherit from the Component class, so if you want to use any Component class methods,\n * such as Component.assert(), use the corresponding Debugger methods instead (assuming a debugger\n * is available).\n *\n * @param {BusPDP11} bus\n * @param {number|null} [addr] of lowest used address in block\n * @param {number} [used] portion of block in bytes (0 for none); must be a multiple of 4\n * @param {number} [size] of block's buffer in bytes (0 for none); must be a multiple of 4\n * @param {number} [type] is one of the MemoryPDP11.TYPE constants (default is MemoryPDP11.TYPE.NONE)\n * @param {Object} [controller] is an optional memory controller component\n */\n constructor(bus, addr, used, size, type, controller)\n {\n var a, i;\n this.bus = bus;\n this.id = (MemoryPDP11.idBlock += 2);\n this.adw = null;\n this.offset = 0;\n this.addr = addr;\n this.used = used;\n this.size = size || 0;\n this.type = type || MemoryPDP11.TYPE.NONE;\n this.fReadOnly = (type == MemoryPDP11.TYPE.ROM);\n this.controller = null;\n this.dbg = null;\n this.readByte = this.readByteDirect = this.readNone;\n this.readWord = this.readWordDirect = this.readWordDefault;\n this.writeByte = this.writeByteDirect = this.writeNone;\n this.writeWord = this.writeWordDirect = this.writeWordDefault;\n this.cReadBreakpoints = this.cWriteBreakpoints = 0;\n this.copyBreakpoints(); // initialize the block's Debugger info; the caller will reinitialize\n\n /*\n * TODO: Study the impact of dirty block tracking. The original purposes were to allow saveMemory()\n * to save only dirty blocks, and to enable the Video component to quickly detect changes to the video buffer.\n * But the benefit to saveMemory() is minimal, and the Video component has other options; for example, it can\n * now use a custom memory controller that performs its own dirty block tracking.\n *\n * However, a quick test with dirty block tracking disabled didn't yield a noticeable improvement in performance,\n * so I think the overhead of our block-based architecture is swamping the impact of these micro-updates.\n */\n this.fDirty = this.fDirtyEver = false;\n\n /*\n * For empty memory blocks, all we need to do is ensure all access functions are mapped to \"none\" handlers.\n */\n if (!this.size) {\n this.setAccess();\n return;\n }\n\n /*\n * When a controller is specified, the controller must provide a buffer, via getControllerBuffer(),\n * and memory access functions, via getControllerAccess().\n */\n if (controller) {\n this.controller = controller;\n a = controller.getControllerBuffer(addr);\n this.adw = a[0];\n this.offset = a[1];\n this.setAccess(controller.getControllerAccess());\n return;\n }\n\n /*\n * This is the normal case: allocate a buffer that provides 8 bits of data per address;\n * no controller is required because our default memory access functions (see afnMemory)\n * know how to deal with this simple 1-1 mapping of addresses to bytes and words.\n *\n * TODO: Consider initializing the memory array to random (or pseudo-random) values in DEBUG\n * mode; pseudo-random might be best, to help make any bugs reproducible.\n */\n if (TYPEDARRAYS) {\n this.buffer = new ArrayBuffer(this.size);\n this.dv = new DataView(this.buffer, 0, this.size);\n /*\n * If littleEndian is true, we can use ab[], aw[] and adw[] directly; well, we can use them\n * whenever the offset is a multiple of 1, 2 or 4, respectively. Otherwise, we must fallback to\n * dv.getUint8()/dv.setUint8(), dv.getUint16()/dv.setUint16() and dv.getInt32()/dv.setInt32().\n */\n this.ab = new Uint8Array(this.buffer, 0, this.size);\n this.aw = new Uint16Array(this.buffer, 0, this.size >> 1);\n this.adw = new Int32Array(this.buffer, 0, this.size >> 2);\n this.setAccess(littleEndian? MemoryPDP11.afnArrayLE : MemoryPDP11.afnArrayBE);\n } else {\n /*\n * NOTE: An ArrayBuffer is defined as being zero-initialized, but the elements of a new\n * Array are not, so this code path takes care of zero-initialization ourselves.\n */\n if (BYTEARRAYS) {\n a = this.ab = new Array(this.size);\n } else {\n /*\n * NOTE: This used to be the default mode of operation (!TYPEDARRAYS && !BYTEARRAYS), because\n * it seemed to provide the best performance; however, that was then, and this is now. TYPEDARRAYS\n * is more efficient.\n */\n a = this.adw = new Array(this.size >> 2);\n }\n for (i = 0; i < a.length; i++) a[i] = 0;\n this.setAccess(MemoryPDP11.afnMemory);\n }\n }\n\n /**\n * init(addr)\n *\n * Quick reinitializer when reusing a Memory block.\n *\n * @this {MemoryPDP11}\n * @param {number} addr\n */\n init(addr)\n {\n this.addr = addr;\n }\n\n /**\n * clone(mem, type, dbg)\n *\n * Converts the current Memory block (this) into a clone of the given Memory block (mem),\n * and optionally overrides the current block's type with the specified type.\n *\n * @this {MemoryPDP11}\n * @param {MemoryPDP11} mem\n * @param {number} [type]\n * @param {DebuggerPDP11} [dbg]\n */\n clone(mem, type, dbg)\n {\n /*\n * Original memory block IDs are even; cloned memory block IDs are odd;\n * the original ID of the current block is lost, but that's OK, since it was presumably\n * produced merely to become a clone.\n */\n this.id = mem.id | 0x1;\n this.used = mem.used;\n this.size = mem.size;\n if (type) {\n this.type = type;\n this.fReadOnly = (type == MemoryPDP11.TYPE.ROM);\n }\n if (TYPEDARRAYS) {\n this.buffer = mem.buffer;\n this.dv = mem.dv;\n this.ab = mem.ab;\n this.aw = mem.aw;\n this.adw = mem.adw;\n this.setAccess(littleEndian? MemoryPDP11.afnArrayLE : MemoryPDP11.afnArrayBE);\n } else {\n if (BYTEARRAYS) {\n this.ab = mem.ab;\n } else {\n this.adw = mem.adw;\n }\n this.setAccess(MemoryPDP11.afnMemory);\n }\n this.copyBreakpoints(dbg, mem);\n }\n\n /**\n * save()\n *\n * This gets the contents of a Memory block as an array of 32-bit values; used by Bus.saveMemory(),\n * which in turn is called by CPUState.save().\n *\n * Memory blocks with custom memory controllers do NOT save their contents; that's the responsibility\n * of the controller component.\n *\n * @this {MemoryPDP11}\n * @return {Array|Int32Array|null}\n */\n save()\n {\n var adw, i;\n if (this.controller) {\n adw = null;\n }\n else if (BYTEARRAYS) {\n adw = new Array(this.size >> 2);\n var off = 0;\n for (i = 0; i < adw.length; i++) {\n adw[i] = this.ab[off] | (this.ab[off + 1] << 8) | (this.ab[off + 2] << 16) | (this.ab[off + 3] << 24);\n off += 4;\n }\n }\n else if (TYPEDARRAYS) {\n /*\n * It might be tempting to just return a copy of Int32Array(this.buffer, 0, this.size >> 2),\n * but we can't be sure of the \"endianness\" of an Int32Array -- which would be OK if the array\n * was always saved/restored on the same machine, but there's no guarantee of that, either.\n * So we use getInt32() and require little-endian values.\n *\n * Moreover, an Int32Array isn't treated by JSON.stringify() and JSON.parse() exactly like\n * a normal array; it's serialized as an Object rather than an Array, so it lacks a \"length\"\n * property and causes problems for State.store() and State.parse().\n */\n adw = new Array(this.size >> 2);\n for (i = 0; i < adw.length; i++) {\n adw[i] = this.dv.getInt32(i << 2, true);\n }\n }\n else {\n adw = this.adw;\n }\n return adw;\n }\n\n /**\n * restore(adw)\n *\n * This restores the contents of a Memory block from an array of 32-bit values;\n * used by Bus.restoreMemory(), which is called by CPUState.restore(), after all other\n * components have been restored and thus all Memory blocks have been allocated\n * by their respective components.\n *\n * @this {MemoryPDP11}\n * @param {Array|null} adw\n * @return {boolean} true if successful, false if block size mismatch\n */\n restore(adw)\n {\n if (this.controller) {\n return (adw == null);\n }\n /*\n * At this point, it's a consistency error for adw to be null; it's happened once already,\n * when there was a restore bug in the Video component that added the frame buffer at the video\n * card's \"spec'ed\" address instead of the programmed address, so there were no controller-owned\n * memory blocks installed at the programmed address, and so we arrived here at a block with\n * no controller AND no data.\n */\n\n\n if (adw && this.size == adw.length << 2) {\n var i;\n if (BYTEARRAYS) {\n var off = 0;\n for (i = 0; i < adw.length; i++) {\n this.ab[off] = adw[i] & 0xff;\n this.ab[off + 1] = (adw[i] >> 8) & 0xff;\n this.ab[off + 2] = (adw[i] >> 16) & 0xff;\n this.ab[off + 3] = (adw[i] >> 24) & 0xff;\n off += 4;\n }\n } else if (TYPEDARRAYS) {\n for (i = 0; i < adw.length; i++) {\n this.dv.setInt32(i << 2, adw[i], true);\n }\n } else {\n this.adw = adw;\n }\n this.fDirty = true;\n return true;\n }\n return false;\n }\n\n /**\n * zero(off, len, pattern)\n *\n * Zeros the block. Supporting off and len parameters is probably overkill, and makes more\n * work in the non-TYPEDARRAY, non-BYTEARRAY case, but that's not the typical case. The other\n * exception is controller-based blocks, which may not have any array backing at all.\n *\n * @this {MemoryPDP11}\n * @param {number} [off] (optional starting byte offset within block)\n * @param {number} [len] (optional maximum number of bytes; default is the entire block)\n * @param {number} [pattern]\n */\n zero(off, len, pattern)\n {\n var i;\n off = off || 0;\n pattern = (pattern || 0) & 0xff; // pattern & 0xff wasn't good enough for the Closure Compiler\n /*\n * NOTE: If len happens to be larger than the block, that's OK, because we also bounds-check the index.\n */\n if (len === undefined) len = this.size;\n\n if ((TYPEDARRAYS || BYTEARRAYS) && this.ab) {\n for (i = off; len-- && i < this.ab.length; i++) this.ab[i] = pattern;\n } else {\n for (i = off; len-- && i < this.size; i++) this.writeByteDirect(off, pattern, this.addr + off);\n }\n }\n\n /**\n * setAccess(afn, fDirect)\n *\n * The afn parameter should be a 4-entry function table containing two byte handlers and\n * two word handlers. See the static afnMemory table for an example.\n *\n * If no function table is specified, a default is selected based on the Memory type;\n * similarly, any undefined entries in the table are filled with default handlers that fall\n * back to the byte handlers, and if one or both byte handlers are undefined, they default\n * to handlers that simply ignore the access.\n *\n * fDirect indicates that both the default AND the direct handlers should be updated. Direct\n * handlers normally match the default handlers, except when \"checked\" handlers are installed;\n * this allows \"checked\" handlers to know where to dispatch the call after performing checks.\n * Examples of checks are read/write breakpoints, but it's really up to the Debugger to decide\n * what the check consists of.\n *\n * @this {MemoryPDP11}\n * @param {Array.<function()>} [afn] function table\n * @param {boolean} [fDirect] (true to update direct access functions as well; default is true)\n */\n setAccess(afn, fDirect)\n {\n if (!afn) {\n\n afn = MemoryPDP11.afnNone;\n }\n this.setReadAccess(afn, fDirect);\n this.setWriteAccess(afn, fDirect);\n }\n\n /**\n * setReadAccess(afn, fDirect)\n *\n * @this {MemoryPDP11}\n * @param {Array.<function()>} afn\n * @param {boolean} [fDirect]\n */\n setReadAccess(afn, fDirect)\n {\n if (!fDirect || !this.cReadBreakpoints) {\n this.readByte = afn[0] || this.readNone;\n this.readWord = afn[2] || this.readWordDefault;\n }\n if (fDirect || fDirect === undefined) {\n this.readByteDirect = afn[0] || this.readNone;\n this.readWordDirect = afn[2] || this.readWordDefault;\n }\n }\n\n /**\n * setWriteAccess(afn, fDirect)\n *\n * @this {MemoryPDP11}\n * @param {Array.<function()>} afn\n * @param {boolean} [fDirect]\n */\n setWriteAccess(afn, fDirect)\n {\n if (!fDirect || !this.cWriteBreakpoints) {\n this.writeByte = !this.fReadOnly && afn[1] || this.writeNone;\n this.writeWord = !this.fReadOnly && afn[3] || this.writeWordDefault;\n }\n if (fDirect || fDirect === undefined) {\n this.writeByteDirect = afn[1] || this.writeNone;\n this.writeWordDirect = afn[3] || this.writeWordDefault;\n }\n }\n\n /**\n * resetReadAccess()\n *\n * @this {MemoryPDP11}\n */\n resetReadAccess()\n {\n this.readByte = this.readByteDirect;\n this.readWord = this.readWordDirect;\n }\n\n /**\n * resetWriteAccess()\n *\n * @this {MemoryPDP11}\n */\n resetWriteAccess()\n {\n this.writeByte = this.fReadOnly? this.writeNone : this.writeByteDirect;\n this.writeWord = this.fReadOnly? this.writeWordDefault : this.writeWordDirect;\n }\n\n /**\n * printAddr(sMessage)\n *\n * @this {MemoryPDP11}\n * @param {string} sMessage\n */\n printAddr(sMessage)\n {\n if (DEBUG && this.dbg && this.dbg.messageEnabled(MessagesPDP11.MEMORY)) {\n this.dbg.printMessage(sMessage + ' ' + (this.addr != null? ('@' + this.dbg.toStrBase(this.addr)) : '#' + this.id), true);\n }\n }\n\n /**\n * addBreakpoint(off, fWrite)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {boolean} fWrite\n */\n addBreakpoint(off, fWrite)\n {\n if (!fWrite) {\n if (this.cReadBreakpoints++ === 0) {\n this.setReadAccess(MemoryPDP11.afnChecked, false);\n }\n if (DEBUG) this.printAddr(\"read breakpoint added to memory block\");\n }\n else {\n if (this.cWriteBreakpoints++ === 0) {\n this.setWriteAccess(MemoryPDP11.afnChecked, false);\n }\n if (DEBUG) this.printAddr(\"write breakpoint added to memory block\");\n }\n }\n\n /**\n * removeBreakpoint(off, fWrite)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {boolean} fWrite\n */\n removeBreakpoint(off, fWrite)\n {\n if (!fWrite) {\n if (--this.cReadBreakpoints === 0) {\n this.resetReadAccess();\n if (DEBUG) this.printAddr(\"all read breakpoints removed from memory block\");\n }\n\n }\n else {\n if (--this.cWriteBreakpoints === 0) {\n this.resetWriteAccess();\n if (DEBUG) this.printAddr(\"all write breakpoints removed from memory block\");\n }\n\n }\n }\n\n /**\n * copyBreakpoints(dbg, mem)\n *\n * @this {MemoryPDP11}\n * @param {DebuggerPDP11} [dbg]\n * @param {MemoryPDP11} [mem] (outgoing MemoryPDP11 block to copy breakpoints from, if any)\n */\n copyBreakpoints(dbg, mem)\n {\n this.dbg = dbg;\n this.cReadBreakpoints = this.cWriteBreakpoints = 0;\n if (mem) {\n if ((this.cReadBreakpoints = mem.cReadBreakpoints)) {\n this.setReadAccess(MemoryPDP11.afnChecked, false);\n }\n if ((this.cWriteBreakpoints = mem.cWriteBreakpoints)) {\n this.setWriteAccess(MemoryPDP11.afnChecked, false);\n }\n }\n }\n\n /**\n * readNone(off, addr)\n *\n * Previously, this always returned 0x00, but the initial memory probe by the COMPAQ DeskPro 386 ROM BIOS\n * writes 0x0000 to the first word of every 64Kb block in the nearly 16Mb address space it supports, and\n * if it reads back 0x0000, it will initially think that LOTS of RAM exists, only to be disappointed later\n * when it performs a more exhaustive memory test, generating unwanted error messages in the process.\n *\n * TODO: Determine if we should have separate readByteNone(), readWordNone() and readLongNone() functions\n * to return 0xff, 0xffff and 0xffffffff|0, respectively. This seems sufficient for now, as it seems unlikely\n * that a system would require nonexistent memory locations to return ALL bits set. However, another factor\n * is whether or not ODDADDR faults take precedence over NOMEMORY faults; if they do, then we need separate\n * interfaces.\n *\n * Also, I'm reluctant to address that potential issue by simply returning -1, because to date, the above\n * Memory interfaces have always returned values that are properly masked to 8, 16 or 32 bits, respectively.\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readNone(off, addr)\n {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.MEMORY) /* && !off */) {\n this.dbg.printMessage(\"attempt to read invalid address \" + this.dbg.toStrBase(addr), true);\n }\n this.bus.fault(addr, PDP11.CPUERR.NOMEMORY, PDP11.ACCESS.READ);\n return 0xff;\n }\n\n /**\n * writeNone(off, v, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} v (could be either a byte or word value, since we use the same handler for both kinds of accesses)\n * @param {number} addr\n */\n writeNone(off, v, addr)\n {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.MEMORY) /* && !off */) {\n this.dbg.printMessage(\"attempt to write \" + this.dbg.toStrBase(v) + \" to invalid addresses \" + this.dbg.toStrBase(addr), true);\n }\n this.bus.fault(addr, PDP11.CPUERR.NOMEMORY, PDP11.ACCESS.WRITE);\n }\n\n /**\n * readWordDefault(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readWordDefault(off, addr)\n {\n return this.readByte(off++, addr++) | (this.readByte(off, addr) << 8);\n }\n\n /**\n * writeWordDefault(off, w, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeWordDefault(off, w, addr)\n {\n this.writeByte(off++, w & 0xff, addr++);\n this.writeByte(off, w >> 8, addr);\n }\n\n /**\n * readByteMemory(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteMemory(off, addr)\n {\n if (BYTEARRAYS) {\n return this.ab[off];\n }\n return ((this.adw[off >> 2] >>> ((off & 0x3) << 3)) & 0xff);\n }\n\n /**\n * readWordMemory(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readWordMemory(off, addr)\n {\n if (PDP11.MEMFAULT && (off & 0x1)) {\n this.bus.fault(addr, PDP11.CPUERR.ODDADDR, PDP11.ACCESS.READ_WORD);\n }\n if (BYTEARRAYS) {\n return this.ab[off] | (this.ab[off + 1] << 8);\n }\n var w;\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n var dw = (this.adw[idw] >> nShift);\n if (nShift < 24) {\n w = dw & 0xffff;\n } else {\n w = (dw & 0xff) | ((this.adw[idw + 1] & 0xff) << 8);\n }\n return w;\n }\n\n /**\n * writeByteMemory(off, b, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} b\n * @param {number} addr\n */\n writeByteMemory(off, b, addr)\n {\n if (BYTEARRAYS) {\n this.ab[off] = b;\n } else {\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n this.adw[idw] = (this.adw[idw] & ~(0xff << nShift)) | (b << nShift);\n }\n this.fDirty = true;\n }\n\n /**\n * writeWordMemory(off, w, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeWordMemory(off, w, addr)\n {\n if (PDP11.MEMFAULT && (off & 0x1)) {\n this.bus.fault(addr, PDP11.CPUERR.ODDADDR, PDP11.ACCESS.WRITE_WORD);\n }\n if (BYTEARRAYS) {\n this.ab[off] = (w & 0xff);\n this.ab[off + 1] = (w >> 8);\n } else {\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n if (nShift < 24) {\n this.adw[idw] = (this.adw[idw] & ~(0xffff << nShift)) | (w << nShift);\n } else {\n this.adw[idw] = (this.adw[idw] & 0x00ffffff) | (w << 24);\n idw++;\n this.adw[idw] = (this.adw[idw] & (0xffffff00|0)) | (w >> 8);\n }\n }\n this.fDirty = true;\n }\n\n /**\n * readByteChecked(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteChecked(off, addr)\n {\n if (DEBUGGER && this.dbg && this.addr != null) {\n this.dbg.checkMemoryRead(this.addr + off);\n }\n return this.readByteDirect(off, addr);\n }\n\n /**\n * readWordChecked(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readWordChecked(off, addr)\n {\n if (DEBUGGER && this.dbg && this.addr != null) {\n this.dbg.checkMemoryRead(this.addr + off, 2);\n }\n return this.readWordDirect(off, addr);\n }\n\n /**\n * writeByteChecked(off, b, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} b\n * @param {number} addr\n */\n writeByteChecked(off, b, addr)\n {\n if (DEBUGGER && this.dbg && this.addr != null) {\n this.dbg.checkMemoryWrite(this.addr + off);\n }\n if (this.fReadOnly) this.writeNone(off, b, addr); else this.writeByteDirect(off, b, addr);\n }\n\n /**\n * writeWordChecked(off, w, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeWordChecked(off, w, addr)\n {\n if (DEBUGGER && this.dbg && this.addr != null) {\n this.dbg.checkMemoryWrite(this.addr + off, 2)\n }\n if (this.fReadOnly) this.writeNone(off, w, addr); else this.writeWordDirect(off, w, addr);\n }\n\n /**\n * readByteBE(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteBE(off, addr)\n {\n return this.ab[off];\n }\n\n /**\n * readByteLE(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteLE(off, addr)\n {\n var b = this.ab[off];\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.MEMORY)) {\n this.dbg.printMessage(\"Memory.readByte(\" + this.dbg.toStrBase(addr) + \"): \" + this.dbg.toStrBase(b), true);\n }\n return b;\n }\n\n /**\n * readWordBE(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readWordBE(off, addr)\n {\n if (PDP11.MEMFAULT && (off & 0x1)) {\n this.bus.fault(addr, PDP11.CPUERR.ODDADDR, PDP11.ACCESS.READ_WORD);\n }\n return this.dv.getUint16(off, true);\n }\n\n /**\n * readWordLE(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readWordLE(off, addr)\n {\n var w;\n if (PDP11.MEMFAULT && (off & 0x1)) {\n this.bus.fault(addr, PDP11.CPUERR.ODDADDR, PDP11.ACCESS.READ_WORD);\n }\n /*\n * TODO: For non-WORDBUS machines, it remains to be seen if there's any advantage to checking the offset\n * for an aligned read vs. always reading the bytes separately.\n */\n if (PDP11.WORDBUS || !(off & 0x1)) {\n w = this.aw[off >> 1];\n } else {\n w = this.ab[off] | (this.ab[off+1] << 8);\n }\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.MEMORY)) {\n this.dbg.printMessage(\"Memory.readWord(\" + this.dbg.toStrBase(addr) + \"): \" + this.dbg.toStrBase(w), true);\n }\n return w;\n }\n\n /**\n * writeByteBE(off, b, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} b\n * @param {number} addr\n */\n writeByteBE(off, b, addr)\n {\n this.ab[off] = b;\n this.fDirty = true;\n }\n\n /**\n * writeByteLE(off, b, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} b\n * @param {number} addr\n */\n writeByteLE(off, b, addr)\n {\n this.ab[off] = b;\n this.fDirty = true;\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.MEMORY)) {\n this.dbg.printMessage(\"Memory.writeByte(\" + this.dbg.toStrBase(addr) + \",\" + this.dbg.toStrBase(b) + \")\", true);\n }\n }\n\n /**\n * writeWordBE(off, w, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeWordBE(off, w, addr)\n {\n if (PDP11.MEMFAULT && (off & 0x1)) {\n this.bus.fault(addr, PDP11.CPUERR.ODDADDR, PDP11.ACCESS.WRITE_WORD);\n }\n this.dv.setUint16(off, w, true);\n this.fDirty = true;\n }\n\n /**\n * writeWordLE(off, w, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeWordLE(off, w, addr)\n {\n if (PDP11.MEMFAULT && (off & 0x1)) {\n this.bus.fault(addr, PDP11.CPUERR.ODDADDR, PDP11.ACCESS.WRITE_WORD);\n }\n /*\n * TODO: For non-WORDBUS machines, it remains to be seen if there's any advantage to checking the offset\n * for an aligned write vs. always writing the bytes separately.\n */\n if (PDP11.WORDBUS || !(off & 0x1)) {\n this.aw[off >> 1] = w;\n } else {\n this.ab[off] = w;\n this.ab[off+1] = w >> 8;\n }\n this.fDirty = true;\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.MEMORY)) {\n this.dbg.printMessage(\"Memory.writeWord(\" + this.dbg.toStrBase(addr) + \",\" + this.dbg.toStrBase(w) + \")\", true);\n }\n }\n}\n\n/*\n * Basic memory types\n *\n * RAM is the most conventional memory type, providing full read/write capability to x86-compatible (ie,\n * 'little endian\") storage. ROM is equally conventional, except that the fReadOnly property is set,\n * disabling writes. VIDEO is treated exactly like RAM, unless a controller is provided. Both RAM and\n * VIDEO memory are always considered writable, and even ROM can be written using the Bus setByteDirect()\n * interface (which in turn uses the Memory writeByteDirect() interface), allowing the ROM component to\n * initialize its own memory. The CONTROLLER type is used to identify memory-mapped devices that do not\n * need any default storage and always provide their own controller.\n *\n * Unallocated regions of the address space contain a special memory block of type NONE that contains\n * no storage. Mapping every addressible location to a memory block allows all accesses to be routed in\n * exactly the same manner, without resorting to any range or processor checks.\n *\n * These types are not mutually exclusive. For example, VIDEO memory could be allocated as RAM, with or\n * without a custom controller (the original Monochrome and CGA video cards used read/write storage that\n * was indistinguishable from RAM), and CONTROLLER memory could be allocated as an empty block of any type,\n * with a custom controller. A few types are required for certain features (eg, ROM is required if you want\n * read-only memory), but the larger purpose of these types is to help document the caller's intent and to\n * provide the Control Panel with the ability to highlight memory regions accordingly.\n */\nMemoryPDP11.TYPE = {\n NONE: 0,\n RAM: 1,\n ROM: 2,\n VIDEO: 3,\n CONTROLLER: 4\n};\nMemoryPDP11.TYPE_COLORS = [\"black\", \"blue\", \"green\", \"cyan\"];\nMemoryPDP11.TYPE_NAMES = [\"NONE\", \"RAM\", \"ROM\", \"VID\", \"H/W\"];\n\n/*\n * Last used block ID (used for debugging only)\n */\nMemoryPDP11.idBlock = 0;\n\n/*\n * This is the effective definition of afnNone, but we need not fully define it, because setAccess()\n * uses these defaults when any of the 4 handlers (ie, 2 byte handlers and 2 word handlers) are undefined.\n *\nMemoryPDP11.afnNone = [\n MemoryPDP11.prototype.readNone,\n MemoryPDP11.prototype.writeNone,\n MemoryPDP11.prototype.readWordDefault,\n MemoryPDP11.prototype.writeWordDefault\n];\n */\nMemoryPDP11.afnNone = [];\n\nMemoryPDP11.afnMemory = [\n MemoryPDP11.prototype.readByteMemory,\n MemoryPDP11.prototype.writeByteMemory,\n MemoryPDP11.prototype.readWordMemory,\n MemoryPDP11.prototype.writeWordMemory\n];\n\nMemoryPDP11.afnChecked = [\n MemoryPDP11.prototype.readByteChecked,\n MemoryPDP11.prototype.writeByteChecked,\n MemoryPDP11.prototype.readWordChecked,\n MemoryPDP11.prototype.writeWordChecked\n];\n\nif (TYPEDARRAYS) {\n MemoryPDP11.afnArrayBE = [\n MemoryPDP11.prototype.readByteBE,\n MemoryPDP11.prototype.writeByteBE,\n MemoryPDP11.prototype.readWordBE,\n MemoryPDP11.prototype.writeWordBE\n ];\n\n MemoryPDP11.afnArrayLE = [\n MemoryPDP11.prototype.readByteLE,\n MemoryPDP11.prototype.writeByteLE,\n MemoryPDP11.prototype.readWordLE,\n MemoryPDP11.prototype.writeWordLE\n ];\n}\n\nvar littleEndian = (TYPEDARRAYS? (function() {\n var buffer = new ArrayBuffer(2);\n new DataView(buffer).setUint16(0, 256, true);\n return new Uint16Array(buffer)[0] === 256;\n})() : false);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/cpu.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass CPUPDP11 extends Component {\n /**\n * CPUPDP11(parmsCPU, nCyclesDefault)\n *\n * The CPUPDP11 class supports the following (parmsCPU) properties:\n *\n * cycles: the machine's base cycles per second; the CPUStatePDP11 constructor\n * will provide us with a default (based on the CPU model) to use as a fallback.\n *\n * multiplier: base cycle multiplier; default is 1.\n *\n * autoStart: true to automatically start, false to not, or null if \"it depends\";\n * null is the default, which means do not autostart UNLESS there is no Debugger\n * and no \"Run\" button (ie, no way to manually start the machine).\n *\n * csStart: the number of cycles that runCPU() must wait before generating\n * checksum records; -1 if disabled. checksum records are a diagnostic aid\n * used to help compare one CPU run to another.\n *\n * csInterval: the number of cycles that runCPU() must execute before generating\n * a checksum record; -1 if disabled.\n *\n * csStop: the number of cycles to stop generating checksum records.\n *\n * This component is primarily responsible for interfacing the CPU with the outside\n * world (eg, Panel and Debugger components), and managing overall CPU operation.\n *\n * It is extended by the CPUStatePDP11 component, where the simulation control logic resides.\n *\n * @param {Object} parmsCPU\n * @param {number} nCyclesDefault\n */\n constructor(parmsCPU, nCyclesDefault)\n {\n super(\"CPU\", parmsCPU, MessagesPDP11.CPU);\n\n var nCycles = +parmsCPU['cycles'] || nCyclesDefault;\n\n var nMultiplier = +parmsCPU['multiplier'] || 1;\n\n this.nDisplayCount = 0;\n this.nDisplayLimit = 30;\n this.nCyclesPerSecond = nCycles;\n\n /*\n * nCyclesMultiplier replaces the old \"speed\" variable (0, 1, 2) and eliminates the need for\n * the constants (SPEED_SLOW, SPEED_FAST and SPEED_MAX). The UI simply doubles the multiplier\n * until we've exceeded the host's speed limit and then starts the multiplier over at 1.\n */\n this.nCyclesMultiplier = nMultiplier;\n this.mhzDefault = Math.round(this.nCyclesPerSecond / 10000) / 100;\n this.mhzTarget = this.mhzDefault * this.nCyclesMultiplier;\n this.msPerYield = this.nCyclesPerYield = this.nCyclesNextYield = this.nCyclesRecalc = 0;\n\n /*\n * We add a number of flags to the set initialized by Component\n */\n this.flags.running = this.flags.starting = false;\n this.flags.autoStart = parmsCPU['autoStart'];\n if (typeof this.flags.autoStart == \"string\") this.flags.autoStart = (this.flags.autoStart == \"true\");\n\n /*\n * Get checksum parameters, if any. runCPU() behavior is not affected until fChecksum\n * is true, which won't happen until resetChecksum() is called with nCyclesChecksumInterval\n * (\"csInterval\") set to a positive value.\n *\n * As above, any of these parameters can also be set with the Debugger's execution options\n * command (\"x\"); for example, \"x cs int 5000\" will set nCyclesChecksumInterval to 5000\n * and call resetChecksum().\n */\n this.flags.checksum = false;\n this.nChecksum = this.nCyclesChecksumNext = 0;\n this.nCyclesChecksumStart = +parmsCPU[\"csStart\"];\n this.nCyclesChecksumInterval = +parmsCPU[\"csInterval\"];\n this.nCyclesChecksumStop = +parmsCPU[\"csStop\"];\n\n /*\n * Array of countdown timers managed by addTimer() and setTimer().\n */\n this.aTimers = [];\n\n this.onRunTimeout = this.runCPU.bind(this); // function onRunTimeout() { cpu.runCPU(); };\n\n /*\n * Define the rest of the properties used by the class\n */\n this.mhz = 0;\n this.nYieldsSinceStatusUpdate = 0;\n this.msStartRun = this.msStartThisRun = this.msEndThisRun = this.nCyclesThisRun = 0;\n this.nTotalCycles = this.nRunCycles = this.nBurstCycles = this.nStepCycles = this.nSnapCycles = 0;\n this.panel = null;\n\n this.setReady();\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {CPUPDP11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUPDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.dbg = dbg;\n this.panel = cmp.panel;\n for (var i = 0; i < CPUPDP11.BUTTONS.length; i++) {\n var control = this.bindings[CPUPDP11.BUTTONS[i]];\n if (control) this.cmp.setBinding(null, CPUPDP11.BUTTONS[i], control);\n }\n this.setReady();\n }\n\n /**\n * reset()\n *\n * Stub for reset notification (overridden by the CPUStatePDP11 component).\n *\n * @this {CPUPDP11}\n */\n reset()\n {\n }\n\n /**\n * save()\n *\n * Stub for save support (overridden by the CPUStatePDP11 component).\n *\n * @this {CPUPDP11}\n * @return {Object|null}\n */\n save()\n {\n return null;\n }\n\n /**\n * restore(data)\n *\n * Stub for restore support (overridden by the CPUStatePDP11 component).\n *\n * @this {CPUPDP11}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n return false;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {CPUPDP11}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n /*\n * We've already saved the parmsCPU 'autoStart' setting, but there may be a machine (or URL) override.\n */\n var sAutoStart = this.cmp.getMachineParm('autoStart');\n if (sAutoStart != null) {\n this.flags.autoStart = (sAutoStart == \"true\"? true : (sAutoStart == \"false\"? false : !!sAutoStart));\n }\n else if (this.flags.autoStart == null) {\n /*\n * If there's no explicit parmsCPU setting either, then we will autoStart if there's no Debugger and\n * no \"Run\" button.\n */\n this.flags.autoStart = ((!DEBUGGER || !this.dbg) && this.bindings[\"run\"] === undefined);\n }\n\n if (!fRepower) {\n if (!data) {\n this.reset();\n } else {\n this.resetCycles();\n if (!this.restore(data)) return false;\n this.resetChecksum();\n }\n /*\n * Give the Debugger a chance to do/print something once we've powered up.\n */\n if (DEBUGGER && this.dbg) {\n this.dbg.init(this.flags.autoStart);\n } else {\n this.status(\"No debugger detected\");\n }\n if (!this.flags.autoStart) {\n this.println(\"CPU will not be auto-started \" + (this.panel? \"(click Run to start)\" : \"(type 'go' to start)\"));\n }\n }\n /*\n * The Computer component (which is responsible for all powerDown and powerUp notifications)\n * is now responsible for managing a component's fPowered flag, not us.\n *\n * this.flags.powered = true;\n */\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {CPUPDP11}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * autoStart()\n *\n * @this {CPUPDP11}\n * @return {boolean} true if started, false if not\n */\n autoStart()\n {\n if (this.flags.running) {\n return true;\n }\n if (this.flags.autoStart) {\n /*\n * We used to also set fUpdateFocus when calling startCPU(), on the assumption that in the \"auto-starting\"\n * context, a machine without focus is like a day without sunshine, but in reality, focus should only be\n * forced when the user takes some other machine-related action.\n */\n return this.startCPU();\n }\n return false;\n }\n\n /**\n * isPowered()\n *\n * @this {CPUPDP11}\n * @return {boolean}\n */\n isPowered()\n {\n if (!this.flags.powered) {\n this.println(this.toString() + \" not powered\");\n return false;\n }\n return true;\n }\n\n /**\n * isRunning()\n *\n * @this {CPUPDP11}\n * @return {boolean}\n */\n isRunning()\n {\n return this.flags.running;\n }\n\n /**\n * getChecksum()\n *\n * This will be implemented by the CPUStatePDP11 component.\n *\n * @this {CPUPDP11}\n * @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code)\n */\n getChecksum()\n {\n return 0;\n }\n\n /**\n * resetChecksum()\n *\n * If checksum generation is enabled (fChecksum is true), this resets the running 32-bit checksum and the\n * cycle counter that will trigger the next displayChecksum(); called by resetCycles(), which is called whenever\n * the CPU is reset or restored.\n *\n * @this {CPUPDP11}\n * @return {boolean} true if checksum generation enabled, false if not\n */\n resetChecksum()\n {\n if (this.nCyclesChecksumStart === undefined) this.nCyclesChecksumStart = 0;\n if (this.nCyclesChecksumInterval === undefined) this.nCyclesChecksumInterval = -1;\n if (this.nCyclesChecksumStop === undefined) this.nCyclesChecksumStop = -1;\n this.flags.checksum = (this.nCyclesChecksumStart >= 0 && this.nCyclesChecksumInterval > 0);\n if (this.flags.checksum) {\n this.nChecksum = 0;\n this.nCyclesChecksumNext = this.nCyclesChecksumStart - this.nTotalCycles;\n /*\n * this.nCyclesChecksumNext = this.nCyclesChecksumStart + this.nCyclesChecksumInterval -\n * (this.nTotalCycles % this.nCyclesChecksumInterval);\n */\n return true;\n }\n return false;\n }\n\n /**\n * updateChecksum(nCycles)\n *\n * When checksum generation is enabled (fChecksum is true), runCPU() asks stepCPU() to execute a minimum\n * number of cycles (1), effectively limiting execution to a single instruction, and then we're called with\n * the exact number cycles that were actually executed. This should give us instruction-granular checksums\n * at precise intervals that are 100% repeatable.\n *\n * @this {CPUPDP11}\n * @param {number} nCycles\n */\n updateChecksum(nCycles)\n {\n if (this.flags.checksum) {\n /*\n * Get a 32-bit summation of the current CPU state and add it to our running 32-bit checksum\n */\n var fDisplay = false;\n this.nChecksum = (this.nChecksum + this.getChecksum())|0;\n this.nCyclesChecksumNext -= nCycles;\n if (this.nCyclesChecksumNext <= 0) {\n this.nCyclesChecksumNext += this.nCyclesChecksumInterval;\n fDisplay = true;\n }\n if (this.nCyclesChecksumStop >= 0) {\n if (this.nCyclesChecksumStop <= this.getCycles()) {\n this.nCyclesChecksumInterval = this.nCyclesChecksumStop = -1;\n this.resetChecksum();\n this.stopCPU();\n fDisplay = true;\n }\n }\n if (fDisplay) this.displayChecksum();\n }\n }\n\n /**\n * displayChecksum()\n *\n * When checksum generation is enabled (fChecksum is true), this is called to provide a crude log of all\n * checksums generated at the specified cycle intervals, as specified by the \"csStart\" and \"csInterval\" parmsCPU\n * properties).\n *\n * @this {CPUPDP11}\n */\n displayChecksum()\n {\n this.println(this.getCycles() + \" cycles: \" + \"checksum=\" + Str.toHex(this.nChecksum));\n }\n\n /**\n * setBinding(sType, sBinding, control, sValue)\n *\n * @this {CPUPDP11}\n * @param {string|null} sType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"run\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sType, sBinding, control, sValue)\n {\n var cpu = this;\n\n switch (sBinding) {\n case \"power\":\n case \"reset\":\n /*\n * The \"power\" and \"reset\" buttons are functions of the entire computer, not just the CPU,\n * but it's not always convenient to stick a power button in the Computer component definition,\n * so we record those bindings here and pass them on to the Computer component in initBus().\n */\n this.bindings[sBinding] = control;\n return true;\n\n case \"run\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickRun() {\n if (!cpu.cmp || !cpu.cmp.checkPower()) return;\n /*\n * We no longer pass true to these startCPU()/stopCPU() calls, on the theory that if the \"run\"\n * control is visible, then the computer is probably sufficiently visible as well; the problem\n * with setting fUpdateFocus to true is that it can jerk the web page around in annoying ways.\n */\n if (!cpu.flags.running)\n cpu.startCPU();\n else\n cpu.stopCPU();\n };\n return true;\n\n case \"speed\":\n this.bindings[sBinding] = control;\n return true;\n\n case \"setSpeed\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickSetSpeed() {\n cpu.setSpeed(cpu.nCyclesMultiplier << 1, true);\n };\n control.textContent = this.getSpeedTarget();\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * updateDisplays(nUpdate)\n *\n * Simpler wrapper around the Computer's updateDisplays() method.\n *\n * @this {CPUPDP11}\n * @param {number} [nUpdate] (1 for periodic, -1 for forced, 0 or undefined otherwise)\n */\n updateDisplays(nUpdate)\n {\n if (this.cmp) this.cmp.updateDisplays(nUpdate);\n }\n\n /**\n * updateDisplay(nUpdate)\n *\n * Some of the CPU bindings provide feedback and therefore need to be updated periodically.\n * However, this should be called via the Computer's updateDisplays() interface, not directly.\n *\n * @this {CPUPDP11}\n * @param {number} [nUpdate] (1 for periodic, -1 for forced, 0 otherwise)\n */\n updateDisplay(nUpdate)\n {\n var controlSpeed = this.bindings[\"speed\"];\n if (controlSpeed) {\n if (nUpdate <= 0 || (this.nDisplayCount += nUpdate) >= this.nDisplayLimit) {\n controlSpeed.textContent = this.getSpeedCurrent();\n this.nDisplayCount = 0;\n }\n }\n }\n\n /**\n * addCycles(nCycles, fEndStep)\n *\n * @this {CPUPDP11}\n * @param {number} nCycles\n * @param {boolean} [fEndStep]\n */\n addCycles(nCycles, fEndStep)\n {\n this.nTotalCycles += nCycles;\n if (fEndStep) {\n this.nBurstCycles = this.nStepCycles = this.nSnapCycles = 0;\n }\n }\n\n /**\n * calcCycles(fRecalc)\n *\n * Calculate the number of cycles to process for each \"burst\" of CPU activity. The size of a burst\n * is driven by YIELDS_PER_SECOND (eg, 30).\n *\n * At the end of each burst, we subtract burst cycles from the yield cycle \"threshold\" counter.\n * Whenever the \"next yield\" cycle counter goes to (or below) zero, we compare elapsed time to the time\n * we expected the virtual hardware to take (eg, 1000ms/50 or 20ms), and if we still have time remaining,\n * we sleep the remaining time (or 0ms if there's no remaining time), and then restart runCPU().\n *\n * @this {CPUPDP11}\n * @param {boolean} [fRecalc] is true if the caller wants to recalculate thresholds based on the most recent\n * speed calculation (see calcSpeed).\n */\n calcCycles(fRecalc)\n {\n /*\n * Calculate \"per\" yield values.\n */\n var vMultiplier = 1;\n if (fRecalc) {\n if (this.nCyclesMultiplier > 1 && this.mhz) {\n vMultiplier = (this.mhz / this.mhzDefault);\n }\n }\n\n this.msPerYield = Math.round(1000 / CPUPDP11.YIELDS_PER_SECOND);\n this.nCyclesPerYield = Math.floor(this.nCyclesPerSecond / CPUPDP11.YIELDS_PER_SECOND * vMultiplier);\n\n /*\n * And initialize \"next\" yield values to the \"per\" values.\n */\n if (!fRecalc) this.nCyclesNextYield = this.nCyclesPerYield;\n this.nCyclesRecalc = 0;\n }\n\n /**\n * getCycles(fScaled)\n *\n * getCycles() returns the number of cycles executed so far. Note that we can be called after\n * runCPU() OR during runCPU(), perhaps from a handler triggered during the current run's stepCPU(),\n * so nRunCycles must always be adjusted by number of cycles stepCPU() was asked to run (nBurstCycles),\n * less the number of cycles it has yet to run (nStepCycles).\n *\n * nRunCycles is zeroed whenever the CPU is halted or the CPU speed is changed, which is why we also\n * have nTotalCycles, which accumulates all nRunCycles before we zero it. However, nRunCycles and\n * nTotalCycles eventually get reset by calcSpeed(), to avoid overflow, so components that rely on\n * getCycles() returning steadily increasing values should also be prepared for a reset at any time.\n *\n * @this {CPUPDP11}\n * @param {boolean} [fScaled] is true if the caller wants a cycle count relative to a multiplier of 1\n * @return {number}\n */\n getCycles(fScaled)\n {\n var nCycles = this.nTotalCycles + this.nRunCycles + this.nBurstCycles - this.nStepCycles;\n if (fScaled && this.nCyclesMultiplier > 1 && this.mhz > this.mhzDefault) {\n /*\n * We could scale the current cycle count by the current effective speed (this.mhz); eg:\n *\n * nCycles = Math.round(nCycles / (this.mhz / this.mhzDefault));\n *\n * but that speed will fluctuate somewhat: large fluctuations at first, but increasingly smaller\n * fluctuations after each burst of instructions that runCPU() executes.\n *\n * Alternatively, we can scale the cycle count by the multiplier, which is good in that the\n * multiplier doesn't vary once the user changes it, but a potential downside is that the\n * multiplier might be set too high, resulting in a target speed that's higher than the effective\n * speed is able to reach.\n *\n * Also, if multipliers were always limited to a power-of-two, then this could be calculated\n * with a simple shift. However, only the \"setSpeed\" UI binding limits it that way; the Debugger\n * interface allows any value, as does the CPU \"multiplier\" parmsCPU property (from the machine's\n * XML file).\n */\n nCycles = Math.round(nCycles / this.nCyclesMultiplier);\n }\n return nCycles;\n }\n\n /**\n * getCyclesPerSecond()\n *\n * This returns the CPU's \"base\" speed (ie, the original cycles per second defined for the machine)\n *\n * @this {CPUPDP11}\n * @return {number}\n */\n getCyclesPerSecond()\n {\n return this.nCyclesPerSecond;\n }\n\n /**\n * resetCycles()\n *\n * Resets speed and cycle information as part of any reset() or restore(); this typically occurs during powerUp().\n * It's important that this be called BEFORE the actual restore() call, because restore() may want to call setSpeed(),\n * which in turn assumes that all the cycle counts have been initialized to sensible values.\n *\n * @this {CPUPDP11}\n */\n resetCycles()\n {\n this.mhz = 0;\n this.nYieldsSinceStatusUpdate = 0;\n this.nTotalCycles = this.nRunCycles = this.nBurstCycles = this.nStepCycles = this.nSnapCycles = 0;\n this.resetChecksum();\n this.setSpeed(1);\n }\n\n /**\n * getSpeed()\n *\n * @this {CPUPDP11}\n * @return {number} the current speed multiplier\n */\n getSpeed()\n {\n return this.nCyclesMultiplier;\n }\n\n /**\n * getSpeedCurrent()\n *\n * @this {CPUPDP11}\n * @return {string} the current speed, in mhz, as a string formatted to two decimal places\n */\n getSpeedCurrent()\n {\n /*\n * TODO: Has toFixed() been \"fixed\" in all browsers (eg, IE) to return a rounded value now?\n */\n return ((this.flags.running)? (this.mhz.toFixed(2) + \"Mhz\") : \"Stopped\");\n }\n\n /**\n * getSpeedTarget()\n *\n * @this {CPUPDP11}\n * @return {string} the target speed, in mhz, as a string formatted to two decimal places\n */\n getSpeedTarget()\n {\n /*\n * TODO: Has toFixed() been \"fixed\" in all browsers (eg, IE) to return a rounded value now?\n */\n return this.mhzTarget.toFixed(2) + \"Mhz\";\n }\n\n /**\n * setSpeed(nMultiplier, fUpdateFocus)\n *\n * NOTE: This used to return the target speed, in mhz, but no callers appear to care at this point.\n *\n * @desc Whenever the speed is changed, the running cycle count and corresponding start time must be reset,\n * so that the next effective speed calculation obtains sensible results. In fact, when runCPU() initially calls\n * setSpeed() with no parameters, that's all this function does (it doesn't change the current speed setting).\n *\n * @this {CPUPDP11}\n * @param {number} [nMultiplier] is the new proposed multiplier (reverts to 1 if the target was too high)\n * @param {boolean} [fUpdateFocus] is true to update Computer focus\n * @return {boolean} true if successful, false if not\n */\n setSpeed(nMultiplier, fUpdateFocus)\n {\n var fSuccess = false;\n if (nMultiplier !== undefined) {\n /*\n * If we haven't reached 80% (0.8) of the current target speed, revert to a multiplier of one (1).\n */\n if (this.mhz / this.mhzTarget < 0.8) {\n nMultiplier = 1;\n } else {\n fSuccess = true;\n }\n this.nCyclesMultiplier = nMultiplier;\n var mhz = this.mhzDefault * this.nCyclesMultiplier;\n if (this.mhzTarget != mhz) {\n this.mhzTarget = mhz;\n var sSpeed = this.getSpeedTarget();\n var controlSpeed = this.bindings[\"setSpeed\"];\n if (controlSpeed) controlSpeed.textContent = sSpeed;\n this.println(\"target speed: \" + sSpeed);\n }\n if (fUpdateFocus && this.cmp) this.cmp.setFocus();\n }\n this.addCycles(this.nRunCycles);\n this.nRunCycles = 0;\n this.msStartRun = Component.getTime();\n this.msEndThisRun = 0;\n this.calcCycles();\n return fSuccess;\n }\n\n /**\n * calcSpeed(nCycles, msElapsed)\n *\n * @this {CPUPDP11}\n * @param {number} nCycles\n * @param {number} msElapsed\n */\n calcSpeed(nCycles, msElapsed)\n {\n if (msElapsed) {\n this.mhz = Math.round(nCycles / (msElapsed * 10)) / 100;\n if (msElapsed >= 86400000) {\n this.nTotalCycles = 0;\n this.setSpeed(); // reset all counters once per day so that we never have to worry about overflow\n }\n }\n }\n\n /**\n * calcStartTime()\n *\n * @this {CPUPDP11}\n */\n calcStartTime()\n {\n if (this.nCyclesRecalc >= this.nCyclesPerSecond) {\n this.calcCycles(true);\n }\n this.nCyclesThisRun = 0;\n this.msStartThisRun = Component.getTime();\n\n /*\n * Try to detect situations where the browser may have throttled us, such as when the user switches\n * to a different tab; in those situations, Chrome and Safari may restrict setTimeout() callbacks\n * to roughly one per second.\n *\n * Another scenario: the user resizes the browser window. setTimeout() callbacks are not throttled,\n * but there can still be enough of a lag between the callbacks that CPU speed will be noticeably\n * erratic if we don't compensate for it here.\n *\n * We can detect throttling/lagging by verifying that msEndThisRun (which was set at the end of the\n * previous run and includes any requested sleep time) is comparable to the current msStartThisRun;\n * if the delta is significant, we compensate by bumping msStartRun forward by that delta.\n *\n * This shouldn't be triggered when the Debugger halts the CPU, because setSpeed() -- which is called\n * whenever the CPU starts running again -- zeroes msEndThisRun.\n *\n * This also won't do anything about other internal delays; for example, Debugger message() calls.\n * By the time the message() function has called yieldCPU(), the cost of the message has already been\n * incurred, so it will be end up being charged against the instruction(s) that triggered it.\n *\n * TODO: Consider calling yieldCPU() sooner from message(), so that it can arrange for the msEndThisRun\n * \"snapshot\" to occur sooner; it's unclear, however, whether that will really improve the CPU's ability\n * to hit its target speed, since you would expect any instruction that displays a message to be an\n * EXTREMELY slow instruction.\n */\n if (this.msEndThisRun) {\n var msDelta = this.msStartThisRun - this.msEndThisRun;\n if (msDelta > this.msPerYield) {\n if (MAXDEBUG) this.println(\"large time delay: \" + msDelta + \"ms\");\n this.msStartRun += msDelta;\n /*\n * Bumping msStartRun forward should NEVER cause it to exceed msStartThisRun; however, just\n * in case, I make absolutely sure it cannot happen, since doing so could result in negative\n * speed calculations.\n */\n\n if (this.msStartRun > this.msStartThisRun) {\n this.msStartRun = this.msStartThisRun;\n }\n }\n }\n }\n\n /**\n * calcRemainingTime()\n *\n * @this {CPUPDP11}\n * @return {number}\n */\n calcRemainingTime()\n {\n this.msEndThisRun = Component.getTime();\n\n var msYield = this.msPerYield;\n if (this.nCyclesThisRun) {\n /*\n * Normally, we would assume we executed a full quota of work over msPerYield, but since the CPU\n * now has the option of calling yieldCPU(), that might not be true. If nCyclesThisRun is correct, then\n * the ratio of nCyclesThisRun/nCyclesPerYield should represent the percentage of work we performed,\n * and so applying that percentage to msPerYield should give us a better estimate of work vs. time.\n */\n msYield = Math.round(msYield * this.nCyclesThisRun / this.nCyclesPerYield);\n }\n\n var msElapsedThisRun = this.msEndThisRun - this.msStartThisRun;\n var msRemainsThisRun = msYield - msElapsedThisRun;\n\n /*\n * We could pass only \"this run\" results to calcSpeed():\n *\n * nCycles = this.nCyclesThisRun;\n * msElapsed = msElapsedThisRun;\n *\n * but it seems preferable to use longer time periods and hopefully get a more accurate speed.\n *\n * Also, if msRemainsThisRun >= 0 && this.nCyclesMultiplier == 1, we could pass these results instead:\n *\n * nCycles = this.nCyclesThisRun;\n * msElapsed = this.msPerYield;\n *\n * to insure that we display a smooth, constant N Mhz. But for now, I prefer seeing any fluctuations.\n */\n var nCycles = this.nRunCycles;\n var msElapsed = this.msEndThisRun - this.msStartRun;\n\n if (MAXDEBUG && msRemainsThisRun < 0 && this.nCyclesMultiplier > 1) {\n this.println(\"warning: updates @\" + msElapsedThisRun + \"ms (prefer \" + Math.round(msYield) + \"ms)\");\n }\n\n this.calcSpeed(nCycles, msElapsed);\n\n if (msRemainsThisRun < 0 || this.mhz < this.mhzTarget) {\n /*\n * Try \"throwing out\" the effects of large anomalies, by moving the overall run start time up;\n * ordinarily, this should only happen when the someone is using an external Debugger or some other\n * tool or feature that is interfering with our overall execution.\n */\n if (msRemainsThisRun < -1000) {\n this.msStartRun -= msRemainsThisRun;\n }\n /*\n * If the last burst took MORE time than we allotted (ie, it's taking more than 1 second to simulate\n * nCyclesPerSecond), all we can do is yield for as little time as possible (ie, 0ms) and hope that the\n * simulation is at least usable.\n */\n msRemainsThisRun = 0;\n }\n\n /*\n * Last but not least, update nCyclesRecalc, so that when runCPU() starts up again and calls calcStartTime(),\n * it'll be ready to decide if calcCycles() should be called again.\n */\n this.nCyclesRecalc += this.nCyclesThisRun;\n\n if (DEBUG && this.messageEnabled(MessagesPDP11.BUFFER) && msRemainsThisRun) {\n this.log(\"calcRemainingTime: \" + msRemainsThisRun + \"ms to sleep after \" + this.msEndThisRun + \"ms\");\n }\n\n this.msEndThisRun += msRemainsThisRun;\n return msRemainsThisRun;\n }\n\n /**\n * addTimer(callBack)\n *\n * Components that want to have timers that periodically fire after some number of milliseconds call\n * addTimer() to create the timer, and then setTimer() every time they want to arm it. There is currently\n * no removeTimer() because these are generally used for the entire lifetime of a component.\n *\n * Internally, each timer entry is a preallocated Array with two entries: a cycle countdown in element [0]\n * and a callback function in element [1]. A timer is initially dormant; dormant timers have a countdown\n * value of -1 (although any negative number will suffice) and active timers have a non-negative value.\n *\n * Why not use JavaScript's setTimeout() instead? Good question. For a good answer, see setTimer() below.\n *\n * TODO: Consider making the addTimer() and setTimer() interfaces more like the addIRQ() and setIRQ()\n * interfaces (which return the underlying object instead of an array index) and maintaining a separate list\n * of active timers, in order of highest to lowest cycle countdown values, as this could speed up\n * getBurstCycles() and updateTimers() functions ever so slightly.\n *\n * @this {CPUPDP11}\n * @param {function()} callBack\n * @return {number} timer index\n */\n addTimer(callBack)\n {\n var iTimer = this.aTimers.length;\n this.aTimers.push([-1, callBack]);\n return iTimer;\n }\n\n /**\n * setTimer(iTimer, ms, fReset)\n *\n * Using the timer index from a previous addTimer() call, this sets that timer to fire after the\n * specified number of milliseconds.\n *\n * This is preferred over JavaScript's setTimeout(), because all our timers are effectively paused when\n * the CPU is paused (eg, when the Debugger halts execution). Moreover, setTimeout() handlers only run after\n * runCPU() yields, which is far too granular for some components (eg, when the SerialPort tries to simulate\n * interrupts at 9600 baud).\n *\n * Ideally, the only function that would use setTimeout() is runCPU(), while the rest of the components\n * use setTimer(); however, due to legacy code (ie, code that predates these functions) and/or laziness,\n * that may not be the case.\n *\n * @this {CPUPDP11}\n * @param {number} iTimer\n * @param {number} ms (converted into a cycle countdown internally)\n * @param {boolean} [fReset] (true if the timer should be reset even if already armed)\n * @return {number} (number of cycles used to arm timer, or -1 if error)\n */\n setTimer(iTimer, ms, fReset)\n {\n var nCycles = -1;\n if (iTimer >= 0 && iTimer < this.aTimers.length) {\n if (fReset || this.aTimers[iTimer][0] < 0) {\n nCycles = this.getMSCycles(ms);\n /*\n * We must now confront the following problem: if the CPU is currently executing a burst of cycles,\n * the number of cycles it has executed in that burst so far must NOT be charged against the cycle\n * timeout we're about to set. The simplest way to resolve that is to immediately call endBurst()\n * and bias the cycle timeout by the number of cycles that the burst executed.\n */\n if (this.flags.running) {\n nCycles += this.endBurst();\n }\n this.aTimers[iTimer][0] = nCycles;\n }\n }\n return nCycles;\n }\n\n /**\n * getMSCycles(ms)\n *\n * @this {CPUPDP11}\n * @param {number} ms\n * @return {number} number of corresponding cycles\n */\n getMSCycles(ms)\n {\n return ((this.nCyclesPerSecond * this.nCyclesMultiplier) / 1000 * ms)|0;\n }\n\n /**\n * getBurstCycles(nCycles)\n *\n * Used by runCPU() to get min(nCycles,[timer cycle counts])\n *\n * @this {CPUPDP11}\n * @param {number} nCycles (number of cycles about to execute)\n * @return {number} (either nCycles or less if a timer needs to fire)\n */\n getBurstCycles(nCycles)\n {\n for (var i = this.aTimers.length - 1; i >= 0; i--) {\n var timer = this.aTimers[i];\n\n if (timer[0] < 0) continue;\n if (nCycles > timer[0]) {\n nCycles = timer[0];\n }\n }\n return nCycles;\n }\n\n /**\n * saveTimers()\n *\n * @this {CPUPDP11}\n * @return {Array.<number>}\n */\n saveTimers()\n {\n var aTimerCycles = [];\n for (var i = 0; i < this.aTimers.length; i++) {\n var timer = this.aTimers[i];\n aTimerCycles.push(timer[0]);\n }\n return aTimerCycles;\n }\n\n /**\n * restoreTimers(aTimerCycles)\n *\n * @this {CPUPDP11}\n * @param {Array.<number>} aTimerCycles\n */\n restoreTimers(aTimerCycles)\n {\n\n for (var i = 0; i < this.aTimers.length && i < aTimerCycles.length; i++) {\n var timer = this.aTimers[i];\n timer[0] = aTimerCycles[i];\n }\n }\n\n /**\n * updateTimers(nCycles)\n *\n * Used by runCPU() to reduce all active timer countdown values by the number of cycles just executed;\n * this is the function that actually \"fires\" any timer(s) whose countdown has reached (or dropped below)\n * zero, invoking their callback function.\n *\n * @this {CPUPDP11}\n * @param {number} nCycles (number of cycles actually executed)\n */\n updateTimers(nCycles)\n {\n for (var i = this.aTimers.length - 1; i >= 0; i--) {\n var timer = this.aTimers[i];\n\n if (timer[0] < 0) continue;\n timer[0] -= nCycles;\n if (timer[0] <= 0) {\n timer[0] = -1; // zero is technically an \"active\" value, so ensure the timer is dormant now\n timer[1](); // safe to invoke the callback function now\n }\n }\n }\n\n /**\n * endBurst(fReset)\n *\n * @this {CPUPDP11}\n * @param {boolean} [fReset]\n * @return {number} (number of cycles executed in the most recent burst)\n */\n endBurst(fReset)\n {\n var nCycles = this.nBurstCycles -= this.nStepCycles;\n /*\n * In addition to zeroing nStepCycles, it's important that we also zero nSnapCycles, because if a CPU\n * burst is being ended after nStepCycles has been \"snapped\" (because a certain opcode has an unusual timing\n * calculation that must be based on a \"snapped\" cycle count rather the opcode's starting cycle count), we\n * could inadvertently undo the endBurst() if the original \"snapped\" value was used to update nStepCycles.\n */\n this.nStepCycles = this.nSnapCycles = 0;\n if (fReset) this.nBurstCycles = 0;\n return nCycles;\n }\n\n /**\n * runCPU()\n *\n * @this {CPUPDP11}\n */\n runCPU()\n {\n if (!this.flags.running) return;\n\n /*\n * calcStartTime() initializes the cycle counter and timestamp for this runCPU() invocation, and optionally\n * recalculates the the maximum number of cycles for each burst if the nCyclesRecalc threshold has been reached.\n */\n this.calcStartTime();\n\n try {\n do {\n /*\n * nCycles is how many cycles we WANT to run on each iteration of stepCPU(), and may be as\n * HIGH as nCyclesPerYield, but it may be significantly less. getBurstCycles() will adjust\n * nCycles downward if any CPU timers need to fire during the next burst.\n */\n var nCycles = this.getBurstCycles(this.flags.checksum? 1 : this.nCyclesPerYield);\n\n /*\n * Execute the burst.\n */\n try {\n this.stepCPU(nCycles);\n }\n catch(exception) {\n /*\n * We assume that any numeric exception was explicitly thrown by the CPU to interrupt the\n * current instruction (and by extension, the current burst, but not the current run). All\n * other exceptions are re-thrown to the catch below, which will attempt a stack dump.\n */\n if (typeof exception != \"number\") throw exception;\n }\n\n /*\n * Terminate the burst, returning the number of cycles that stepCPU() actually ran.\n */\n nCycles = this.endBurst(true);\n\n /*\n * Add nCycles to nCyclesThisRun, as well as nRunCycles (the cycle count since the CPU started).\n */\n this.nCyclesThisRun += nCycles;\n this.nRunCycles += nCycles;\n this.updateChecksum(nCycles);\n\n /*\n * Update any/all timers, firing those whose cycle countdowns have reached (or dropped below) zero.\n */\n this.updateTimers(nCycles);\n\n this.nCyclesNextYield -= nCycles;\n if (this.nCyclesNextYield <= 0) {\n this.nCyclesNextYield += this.nCyclesPerYield;\n if (++this.nYieldsSinceStatusUpdate >= CPUPDP11.YIELDS_PER_STATUS) {\n this.updateDisplays();\n this.nYieldsSinceStatusUpdate = 0;\n }\n break;\n }\n } while (this.flags.running);\n }\n catch (e) {\n this.stopCPU();\n if (this.cmp) this.cmp.stop(Component.getTime(), this.getCycles());\n this.setError(e.stack || e.message);\n return;\n }\n\n if (this.flags.running) setTimeout(this.onRunTimeout, this.calcRemainingTime());\n }\n\n /**\n * startCPU(fUpdateFocus)\n *\n * For use by any component that wants to start the CPU.\n *\n * @param {boolean} [fUpdateFocus]\n * @return {boolean}\n */\n startCPU(fUpdateFocus)\n {\n if (this.isError()) {\n return false;\n }\n if (this.flags.running) {\n this.println(this.toString() + \" busy\");\n return false;\n }\n /*\n * setSpeed() without a speed parameter leaves the selected speed in place, but also resets the\n * cycle counter and timestamp for the current series of runCPU() calls, calculates the maximum number\n * of cycles for each burst based on the last known effective CPU speed, and resets the nCyclesRecalc\n * threshold counter.\n */\n this.setSpeed();\n this.flags.running = true;\n this.flags.starting = true;\n var controlRun = this.bindings[\"run\"];\n if (controlRun) controlRun.textContent = \"Halt\";\n if (this.cmp) {\n if (fUpdateFocus) this.cmp.setFocus(true);\n this.cmp.start(this.msStartRun, this.getCycles());\n }\n if (!this.dbg) this.status(\"Started\");\n setTimeout(this.onRunTimeout, 0);\n return true;\n }\n\n /**\n * stepCPU(nMinCycles)\n *\n * This will be implemented by the CPUStatePDP11 component.\n *\n * @this {CPUPDP11}\n * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored)\n * @return {number} of cycles executed; 0 indicates that the last instruction was not executed\n */\n stepCPU(nMinCycles)\n {\n return 0;\n }\n\n /**\n * stopCPU(fComplete)\n *\n * For use by any component that wants to stop the CPU.\n *\n * This similar to yieldCPU(), but it doesn't need to zero nCyclesNextYield to break out of runCPU();\n * it simply needs to clear fRunning (well, \"simply\" may be oversimplifying a bit....)\n *\n * @this {CPUPDP11}\n * @param {boolean} [fComplete]\n * @return {boolean} true if the CPU was stopped, false if it was already stopped\n */\n stopCPU(fComplete)\n {\n var fStopped = false;\n if (this.flags.running) {\n this.endBurst();\n this.addCycles(this.nRunCycles);\n this.nRunCycles = 0;\n this.flags.running = false;\n var controlRun = this.bindings[\"run\"];\n if (controlRun) controlRun.textContent = \"Run\";\n if (this.cmp) {\n this.cmp.stop(Component.getTime(), this.getCycles());\n }\n fStopped = true;\n if (!this.dbg) this.status(\"Stopped\");\n }\n this.flags.complete = fComplete;\n return fStopped;\n }\n\n /**\n * yieldCPU()\n *\n * Similar to stopCPU() with regard to how it resets various cycle countdown values, but the CPU\n * remains in a \"running\" state.\n *\n * @this {CPUPDP11}\n */\n yieldCPU()\n {\n this.endBurst(); // this will break us out of stepCPU()\n this.nCyclesNextYield = 0; // this will break us out of runCPU(), once we break out of stepCPU()\n /*\n * The Debugger calls yieldCPU() after every message() to ensure browser responsiveness, but it looks\n * odd for those messages to show CPU state changes if the Control Panel, Video display, etc, does not,\n * so I've added this call to try to keep things looking synchronized.\n */\n this.updateDisplays();\n }\n}\n\n/*\n * Constants that control the frequency at which various updates should occur.\n *\n * These values do NOT control the simulation directly. Instead, they are used by\n * calcCycles(), which uses the nCyclesPerSecond passed to the constructor as a starting\n * point and computes the following variables:\n *\n * this.nCyclesPerYield: (this.nCyclesPerSecond / CPUPDP11.YIELDS_PER_SECOND)\n *\n * The above variables are also multiplied by any cycle multiplier in effect, via setSpeed(),\n * and then they're used to initialize another set of variables for each runCPU() iteration:\n *\n * this.nCyclesNextYield: this.nCyclesPerYield\n */\nCPUPDP11.YIELDS_PER_SECOND = 30; // just a gut feeling for the MINIMUM number of yields per second\nCPUPDP11.YIELDS_PER_STATUS = 15; // every 15 yields (ie, twice per second), perform CPU status updates\n\nCPUPDP11.BUTTONS = [\"power\", \"reset\"];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/cpustate.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * Overview of Device Interrupt Support\n *\n * Originally, the CPU maintained a queue of requested interrupts. Entries in this queue recorded a device's\n * priority, vector, and delay (ie, a number of instructions to execute before dispatching the interrupt). This\n * queue would constantly grow and shrink as requests were issued and dispatched, and as long as there was something\n * in the queue, the CPU was constantly examining it.\n *\n * Now we are trying something more efficient. First, for devices that require delays (like the SerialPort's receiver\n * and transmitter buffer registers, which are supposed to \"clock\" the data in and out at a specific baud rate), the\n * CPU offers timer services that will \"fire\" a callback after a specified delay, which are much more efficient than\n * requiring the CPU to dive into an interrupt queue and decrement delay counts on every instruction.\n *\n * Second, devices that generate interrupts will allocate an IRQ object during initialization; we will no longer\n * be creating and destroying interrupt event objects and inserting/deleting them in a constantly changing queue.\n * Each IRQ contains properties that never change (eg, the vector and priority), along with a \"next\" pointer that's\n * only used when the IRQ is active.\n *\n * When a device decides it's time to interrupt (either at the end of some I/O operation or when a timer has fired),\n * it will simply set the IRQ, which basically means that the IRQ will be linked onto a list of active IRQs, in\n * priority order, so that when the CPU is ready to acknowledge interrupts, it need only check the top of the active\n * IRQ list.\n */\n\n/**\n * @typedef {{\n * vector: number,\n * priority: number,\n * message: number,\n * next: (IRQ|null)\n * }}\n */\nvar IRQ;\n\nclass CPUStatePDP11 extends CPUPDP11 {\n /**\n * CPUStatePDP11(parmsCPU)\n *\n * The CPUStatePDP11 class uses the following (parmsCPU) properties:\n *\n * model: a number (eg, 1170) that should match one of the PDP11.MODEL_* values\n * addrReset: reset address (default is 0)\n *\n * This extends the CPU class and passes any remaining parmsCPU properties to the CPU class\n * constructor, along with a default speed (cycles per second) based on the specified\n * (or default) CPU model number.\n *\n * After looking over the timings of PDP-11/70 instructions, nearly all of them appear\n * to be multiples of 150ns. So that's what we'll consider a cycle. How many 150ns are\n * in one second? Approximately 6666667. So by way of comparison to other PCjs machines,\n * that makes the PDP-11 (or at least the PDP-11/70) look like a 6.67Mhz machine.\n *\n * I've started with the PDP-11/70, since that's what Paul Nankervis started with. When\n * I go back and add support for earlier PDP-11 models (primarily by neutering functions\n * that didn't exist), I will no doubt have to tweak some instruction cycle counts, too.\n *\n * Examples of operations that take 1 extra cycle (150ns): single and double operand byte\n * instructions with an odd address (except MOV/MTPI/MTPD/JMP/JRS), ADD/SUB/BIC/BIS/MOVB/CMP/BIT\n * instructions with src of R1-R7 and dst of R6-R7, RORB/ASRB with an odd address, and each\n * shift of ASH/ASHC. As you can see, the rules are not simple.\n *\n * We're not simulating cache hardware, but our timings should be optimistic and assume 100%\n * cache hits; for cache hits, each read cycle is 300ns. As for write cycles, they are always\n * 750ns. My initial take on DEC's timings is that they are including the write time as part\n * of the total EF (execute/fetch) time. So, for instructions that write to memory, it looks\n * like we'll normally need to add 5 cycles (750/150) to the instruction's base time, but\n * we'll need to keep an eye out for exceptions.\n *\n * @param {Object} parmsCPU\n */\n constructor(parmsCPU)\n {\n var nCyclesDefault = 0;\n var model = +parmsCPU['model'] || PDP11.MODEL_1170;\n\n switch(model) {\n case PDP11.MODEL_1170:\n default:\n nCyclesDefault = 6666667;\n break;\n }\n\n /*\n * ES6 ALERT: Classes cannot access \"this\" until all superclasses have been initialized as well.\n */\n super(parmsCPU, nCyclesDefault);\n\n this.model = model;\n this.addrReset = +parmsCPU['addrReset'] || 0;\n\n /*\n * These properties will be initialized by initCPU()\n */\n this.flagC = this.flagV = this.flagZ = this.flagN = 0;\n this.regPSW = this.pswMode = 0;\n this.pswTrap = 0;\n this.regsGen = this.regsAlt = this.regsAltStack = [];\n this.regsPAR = this.regsPDR = this.regsUniMap = this.regsControl = [];\n this.opFlags = 0;\n\n /*\n * These properties will be initialized by initMMU()\n */\n this.regMMR0 = this.regMMR1 = this.regMMR2 = this.regMMR3 = 0;\n this.regErr = this.regMBR = this.regPIR = this.regSLR = 0;\n this.mmuEnable = this.mmuLastMode = this.mmuLastPage = this.mmuMask = 0;\n this.addrLast = this.opLast = this.addrInvalid = 0;\n\n this.mapMMR3 = [4,2,0,1]; // map from mode to MMR3 I/D bit\n\n /*\n * Initialize processor operation to match the requested model.\n *\n * offRegSrc is a bias added to the register index calculated in readSrcWord() and readSrcByte(),\n * and by default has no effect on the register index, UNLESS this is a PDP-11/20, in which case the\n * bias is changed to 8 and we return one of the negative values you see above. Those negative values\n * act as signals to writeDstWord() and writeDstByte(), effectively delaying evaluation of the register\n * until then.\n */\n this.offRegSrc = 0;\n this.maskRegSrcByte = 0xff;\n\n if (this.model <= PDP11.MODEL_1120) {\n this.opDecode = PDP11.op1120.bind(this);\n this.checkStackLimit = this.checkStackLimit1120;\n this.offRegSrc = 8;\n this.maskRegSrcByte = -1;\n this.pswUsed = ~(PDP11.PSW.UNUSED | PDP11.PSW.REGSET | PDP11.PSW.PMODE | PDP11.PSW.CMODE) & 0xffff;\n this.pswRegSet = 0;\n } else {\n this.opDecode = PDP11.op1140.bind(this);\n this.checkStackLimit = this.checkStackLimit1140;\n /*\n * The alternate register set (REGSET) doesn't exist on the 11/20 or 11/40; it's available on the 11/45 and 11/70.\n * Ditto for separate I/D spaces, SUPER mode, and the instructions MFPD, MTPD, and SPL.\n */\n this.pswUsed = ~(PDP11.PSW.UNUSED | (this.model <= PDP11.MODEL_1140? PDP11.PSW.REGSET : 0)) & 0xffff;\n this.pswRegSet = (this.model > PDP11.MODEL_1140? PDP11.PSW.REGSET : 0);\n }\n\n this.nDisableTraps = 0;\n this.trapVector = this.trapReason = 0;\n\n /** @type {IRQ|null} */\n this.irqNext = null; // the head of the active IRQ list, in priority order\n\n /** @type {Array.<IRQ>} */\n this.aIRQs = []; // list of all IRQs, active or not (to be used for auto-configuration)\n\n this.getByte = this.getByteDirect = this.getByteChecked;\n this.getWord = this.getWordDirect = this.getWordChecked;\n this.setByte = this.setByteDirect = this.setByteChecked;\n this.setWord = this.setWordDirect = this.setWordChecked;\n this.nReadBreaks = this.nWriteBreaks = 0;\n\n this.addrDSpace = this.addrIOPage = 0;\n this.getAddr = this.getVirtualAddrByMode;\n this.readWord = this.readWordFromVirtual;\n this.writeWord = this.writeWordToVirtual;\n\n this.srcMode = this.srcReg = 0;\n this.dstMode = this.dstReg = this.dstAddr = 0;\n\n this.flags.complete = false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * Called once the Bus has been initialized.\n *\n * @this {CPUStatePDP11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUPDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n super.initBus(cmp, bus, cpu, dbg);\n this.getByteDirect = bus.getByte.bind(bus);\n this.getWordDirect = bus.getWord.bind(bus);\n this.setByteDirect = bus.setByte.bind(bus);\n this.setWordDirect = bus.setWord.bind(bus);\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * We hook the powerUp() notification only because it's our best opportunity to take care of any\n * floating vector assignments.\n *\n * @this {CPUStatePDP11}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n var vectorFloating = 0o300;\n for (var i = 0; i < this.aIRQs.length; i++) {\n var irq = this.aIRQs[i];\n if (irq.vector < 0) {\n irq.vector = vectorFloating;\n vectorFloating += 4;\n }\n }\n return super.powerUp(data, fRepower);\n }\n\n /**\n * reset()\n *\n * @this {CPUStatePDP11}\n */\n reset()\n {\n this.status(\"Model \" + this.model);\n if (this.flags.running) this.stopCPU();\n this.initCPU();\n this.resetCycles();\n this.clearError(); // clear any fatal error/exception that setError() may have flagged\n super.reset();\n }\n\n /**\n * initCPU()\n *\n * WARNING: It's tempting to call this function as early as the constructor() or initBus() calls, but\n * but we actually need to wait until our reset() or restore() function is called by the powerUp() handler,\n * ensuring that all device memory allocations have finished. Only then is it safe to make the first call\n * to initCPU() -> initMMU() -> setMemoryAccess() -> Bus.setIOPageRange() and sync the Bus memory map with\n * the CPU memory map.\n *\n * @this {CPUStatePDP11}\n */\n initCPU()\n {\n /*\n * TODO: Verify the initial state of all PDP-11 flags and registers (are they well-documented?)\n */\n var f = 0xffff;\n this.flagC = 0x10000; // PSW C bit\n this.flagV = 0x8000; // PSW V bit\n this.flagZ = f; // PSW Z bit (TODO: Why do we clear instead of set Z, like other flags?)\n this.flagN = 0x8000; // PSW N bit\n this.regPSW = 0x000f; // PSW other bits (TODO: What's the point of setting the flag bits here, too?)\n\n this.regsGen = [ // General R0-R7\n 0, 0, 0, 0, 0, 0, 0, this.addrReset, -1, -2, -3, -4, -5, -6, -7, -8\n ];\n this.regsAlt = [ // Alternate R0-R5\n 0, 0, 0, 0, 0, 0\n ];\n this.regsAltStack = [ // Alternate R6 stack pointers (KERNEL, SUPER, UNUSED, USER)\n 0, 0, 0, 0\n ];\n this.regsPAR = [ // memory management PAR registers by mode\n [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // KERNEL (8 KIPAR regs followed by 8 KDPAR regs)\n [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // SUPER (8 SIPDR regs followed by 8 SDPDR regs)\n [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // mode 2 (not used)\n [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] // USER (8 UIPDR regs followed by 8 UDPDR regs)\n ];\n this.regsPDR = [ // memory management PDR registers by mode\n [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // KERNEL (8 KIPDR regs followed by 8 KDPDR regs)\n [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // SUPER (8 SIPDR regs followed by 8 SDPDR regs)\n [f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f], // mode 2 (not used)\n [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] // USER (8 UIPDR regs followed by 8 UDPDR regs)\n ];\n this.regsUniMap = [ // 32 UNIBUS map registers\n 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\n ];\n this.regsControl = [ // various control registers (177740-177756) we don't really care about\n 0, 0, 0, 0, 0, 0, 0, 0\n ];\n\n this.pswMode = 0; // current memory management mode (see PDP11.MODE.KERNEL | SUPER | UNUSED | USER)\n this.pswTrap = -1;\n this.regMBR = 0;\n\n /*\n * opFlags contains various conditions that stepCPU() needs to be aware of.\n */\n this.opFlags = 0;\n\n /*\n * srcMode and srcReg are set by SRCMODE decodes, and dstMode and dstReg are set for DSTMODE decodes,\n * indicating to the opcode handlers the mode(s) and register(s) used as part of the current opcode, so\n * that they can calculate the correct number of cycles. dstAddr is set for byte operations that also\n * need to know the effective address for their cycle calculation.\n */\n this.srcMode = this.srcReg = 0;\n this.dstMode = this.dstReg = this.dstAddr = 0;\n\n this.initMMU();\n }\n\n /**\n * initMMU()\n *\n * Reset all registers required as part of a RESET instruction.\n *\n * TODO: Do we ever need to automatically clear regErr, or is it cleared manually?\n *\n * @this {CPUStatePDP11}\n */\n initMMU()\n {\n this.regMMR0 = 0; // 177572\n this.regMMR1 = 0; // 177574\n this.regMMR2 = 0; // 177576\n this.regMMR3 = 0; // 172516\n this.regErr = 0; // 177766\n this.regPIR = 0; // 177772\n this.regSLR = 0xff; // 177774\n this.mmuEnable = 0; // MMU enabled for PDP11.ACCESS.READ or PDP11.ACCESS.WRITE\n this.mmuLastMode = 0;\n this.mmuLastPage = 0;\n this.mmuMask = 0x3ffff;\n\n /*\n * This is queried and displayed by the Panel when it's not displaying its own ADDRESS register\n * (which takes precedence when, for example, you've manually halted the CPU and are independently\n * examining the contents of other addresses).\n *\n * We initialize it to whatever the current PC is, because according to @paulnank's pdp11.js: \"Reset\n * displays next instruction address\" and initMMU() is called on a RESET.\n */\n this.addrLast = this.regsGen[7];\n\n /*\n * This stores the PC in the lower 16 bits, and any auto-incs or auto-decs from the last opcode in the\n * upper 16 bits; the lower 16 bits are used to update MMR2, and the upper 16 bits are used to update MMR1.\n * The upper bits are automatically zeroed at the start of every operation when the PC is copied to opLast.\n */\n this.opLast = 0;\n\n this.resetIRQs();\n\n /*\n * As initCPU() explains, we shouldn't be calling this function until well after initBus() has been\n * called, but we still make absolutely sure we have Bus access.\n */\n if (this.bus) {\n this.setMemoryAccess();\n this.addrInvalid = this.bus.getMemoryLimit(MemoryPDP11.TYPE.RAM);\n }\n }\n\n /**\n * getMMUState()\n *\n * Returns bit 0 set if 22-bit, bit 1 set if 18-bit, or bit 2 set if 16-bit; used by the Panel component.\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getMMUState()\n {\n return this.mmuEnable? ((this.regMMR3 & PDP11.MMR3.MMU_22BIT)? 1 : 2) : 4;\n }\n\n /**\n * resetCPU()\n *\n * @this {CPUStatePDP11}\n */\n resetCPU()\n {\n this.bus.reset();\n this.initMMU();\n }\n\n /**\n * setMemoryAccess()\n *\n * Define handlers and DSPACE setting appropriate for the current MMU mode, in order to eliminate unnecessary calls\n * to mapVirtualToPhysical().\n *\n * @this {CPUStatePDP11}\n */\n setMemoryAccess()\n {\n this.getByte = this.getByteDirect;\n this.getWord = this.getWordDirect;\n this.setByte = this.setByteDirect;\n this.setWord = this.setWordDirect;\n if (this.nReadBreaks) {\n this.getByte = this.getByteChecked;\n this.getWord = this.getWordChecked;\n }\n if (this.nWriteBreaks) {\n this.setByte = this.setByteChecked;\n this.setWord = this.setWordChecked;\n }\n if (this.mmuEnable) {\n this.addrDSpace = PDP11.ACCESS.DSPACE;\n this.addrIOPage = (this.regMMR3 & PDP11.MMR3.MMU_22BIT)? BusPDP11.IOPAGE_22BIT : BusPDP11.IOPAGE_18BIT;\n this.getAddr = this.getVirtualAddrByMode;\n this.readWord = this.nReadBreaks? this.readWordFromVirtualChecked : this.readWordFromVirtual;\n this.writeWord = this.nWriteBreaks? this.writeWordToVirtualChecked : this.writeWordToVirtual;\n this.bus.setIOPageRange((this.regMMR3 & PDP11.MMR3.MMU_22BIT)? 22 : 18);\n } else {\n this.addrDSpace = 0;\n this.addrIOPage = BusPDP11.IOPAGE_16BIT;\n this.getAddr = this.getPhysicalAddrByMode;\n this.readWord = this.nReadBreaks? this.readWordFromPhysicalChecked : this.readWordFromPhysical;\n this.writeWord = this.nWriteBreaks? this.writeWordToPhysicalChecked : this.writeWordToPhysical;\n this.bus.setIOPageRange(16);\n }\n }\n\n /**\n * getMMR0()\n *\n * NOTE: It's OK to bypass this function if you're only interested in bits that always stored directly in MMR0.\n *\n * 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 MMR0\n * nonr leng read trap unus unus ena mnt cmp -mode- i/d --page-- enable\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getMMR0()\n {\n var data = this.regMMR0;\n if (!(data & PDP11.MMR0.ABORT)) {\n data = (data & ~(PDP11.MMR0.UNUSED | PDP11.MMR0.PAGE | PDP11.MMR0.MODE)) | (this.mmuLastMode << 5) | (this.mmuLastPage << 1);\n }\n return data;\n }\n\n /**\n * setMMR0()\n *\n * @this {CPUStatePDP11}\n * @param {number} newMMR0\n */\n setMMR0(newMMR0)\n {\n newMMR0 &= ~PDP11.MMR0.UNUSED;\n\n if (this.regMMR0 != newMMR0) {\n if (newMMR0 & PDP11.MMR0.ABORT) {\n /*\n * If updates to MMR0[1-7], MMR1, and MMR2 are being shut off (ie, MMR0.ABORT bits are transitioning\n * from clear to set), then do one final sync with their real-time counterparts in opLast.\n */\n if (!(this.regMMR0 & PDP11.MMR0.ABORT)) {\n this.regMMR1 = (this.opLast >> 16) & 0xffff;\n this.regMMR2 = this.opLast & 0xffff;\n }\n }\n /*\n * NOTE: We are not protecting the read-only state of the COMPLETED bit here; that's handled by writeMMR0().\n */\n this.regMMR0 = newMMR0;\n this.mmuLastMode = (newMMR0 & PDP11.MMR0.MODE) >> PDP11.MMR0.SHIFT.MODE;\n this.mmuLastPage = (newMMR0 & PDP11.MMR0.PAGE) >> PDP11.MMR0.SHIFT.PAGE;\n var mmuEnable = 0;\n if (newMMR0 & (PDP11.MMR0.ENABLED | PDP11.MMR0.MAINT)) {\n mmuEnable = PDP11.ACCESS.WRITE;\n if (newMMR0 & PDP11.MMR0.ENABLED) mmuEnable |= PDP11.ACCESS.READ;\n }\n if (this.mmuEnable != mmuEnable) {\n this.mmuEnable = mmuEnable;\n this.setMemoryAccess();\n }\n }\n }\n\n /**\n * getMMR1()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getMMR1()\n {\n /*\n * If updates to MMR1 have not been shut off (ie, MMR0.ABORT bits are clear), then we are allowed\n * to sync MMR1 with its real-time counterpart in opLast.\n *\n * UPDATE: Apparently, I was mistaken that this register would only be updated when the MMR0 ENABLED\n * bit was set.\n *\n * if ((this.regMMR0 & (PDP11.MMR0.ABORT | PDP11.MMR0.ENABLED)) == PDP11.MMR0.ENABLED)\n */\n if (!(this.regMMR0 & PDP11.MMR0.ABORT)) {\n this.regMMR1 = (this.opLast >> 16) & 0xffff;\n }\n var result = this.regMMR1;\n if (result & 0xff00) {\n result = ((result << 8) | (result >> 8)) & 0xffff;\n }\n return result;\n }\n\n /**\n * getMMR2()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getMMR2()\n {\n /*\n * If updates to MMR2 have not been shut off (ie, MMR0.ABORT bits are clear), then we are allowed\n * to sync MMR2 with its real-time counterpart in opLast.\n *\n * UPDATE: Apparently, I was mistaken that this register would only be updated when the MMR0 ENABLED\n * bit was set.\n *\n * if ((this.regMMR0 & (PDP11.MMR0.ABORT | PDP11.MMR0.ENABLED)) == PDP11.MMR0.ENABLED)\n */\n if (!(this.regMMR0 & PDP11.MMR0.ABORT)) {\n this.regMMR2 = this.opLast & 0xffff;\n }\n return this.regMMR2;\n }\n\n /**\n * getMMR3()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getMMR3()\n {\n return this.regMMR3;\n }\n\n /**\n * setMMR3()\n *\n * @this {CPUStatePDP11}\n * @param {number} newMMR3\n */\n setMMR3(newMMR3)\n {\n /*\n * Don't allow non-11/70 models to use 22-bit addressing or the UNIBUS map.\n */\n if (this.model < PDP11.MODEL_1170) {\n newMMR3 &= ~(PDP11.MMR3.MMU_22BIT | PDP11.MMR3.UNIBUS_MAP);\n }\n if (this.regMMR3 != newMMR3) {\n this.regMMR3 = newMMR3;\n this.mmuMask = (newMMR3 & PDP11.MMR3.MMU_22BIT)? BusPDP11.MASK_22BIT : BusPDP11.MASK_18BIT;\n this.setMemoryAccess();\n }\n }\n\n /**\n * setReset(addr, fStart, bUnit, addrStack)\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @param {boolean} [fStart] (true if a \"startable\" image was just loaded, false if not)\n * @param {number} [bUnit] (boot unit #)\n * @param {number} [addrStack]\n */\n setReset(addr, fStart, bUnit, addrStack)\n {\n this.addrReset = addr;\n\n this.setPC(addr);\n this.setPSW(0);\n\n this.resetCPU();\n\n if (fStart) {\n this.regsGen[0] = bUnit || 0;\n for (var i = 1; i <= 5; i++) this.regsGen[i] = 0;\n this.regsGen[6] = addrStack || 0o2000;\n if (!this.flags.powered) {\n this.flags.autoStart = true;\n }\n else if (!this.flags.running) {\n this.startCPU();\n }\n }\n else {\n if (this.dbg && this.flags.powered) {\n /*\n * TODO: Review the decision to always stop the CPU if the Debugger is loaded. Note that\n * when stopCPU() stops a running CPU, the Debugger gets notified, so no need to notify it again.\n *\n * TODO: There are more serious problems to deal with if another component is slamming a new PC down\n * the CPU's throat (presumably while also dropping some new code into RAM) while the CPU is running;\n * we should probably force a complete reset, but for now, it's up to the user to hit the reset button\n * themselves.\n */\n if (!this.stopCPU() && !this.cmp.flags.reset) {\n this.dbg.updateStatus();\n this.cmp.updateDisplays(-1);\n }\n }\n else if (fStart === false) {\n this.stopCPU();\n }\n }\n if (!this.isRunning() && this.panel) this.panel.stop();\n }\n\n /**\n * getChecksum()\n *\n * TODO: Implement\n *\n * @this {CPUStatePDP11}\n * @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code)\n */\n getChecksum()\n {\n return 0;\n }\n\n /**\n * save()\n *\n * @this {CPUStatePDP11}\n * @return {Object|null}\n */\n save()\n {\n var state = new State(this);\n state.set(0, [\n this.regsGen,\n this.regsAlt,\n this.regsAltStack,\n this.regsPAR,\n this.regsPDR,\n this.regsUniMap,\n this.regsControl,\n this.regErr,\n this.regMBR,\n this.regPIR,\n this.regSLR,\n this.mmuLastMode,\n this.mmuLastPage,\n this.addrLast,\n this.opFlags,\n this.opLast,\n this.pswTrap,\n this.trapReason,\n this.trapVector,\n this.addrReset\n ]);\n state.set(1, [this.getPSW(),this.getMMR0(),this.getMMR1(),this.getMMR2(),this.getMMR3()]);\n state.set(2, [this.nTotalCycles, this.getSpeed(), this.flags.autoStart]);\n state.set(3, this.saveIRQs());\n state.set(4, this.saveTimers());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * @this {CPUStatePDP11}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n /*\n * ES6 ALERT: A handy destructuring assignment, which makes it easy to perform the inverse\n * of what save() does when it collects a bunch of object properties into an array.\n */\n [\n this.regsGen,\n this.regsAlt,\n this.regsAltStack,\n this.regsPAR,\n this.regsPDR,\n this.regsUniMap,\n this.regsControl,\n this.regErr,\n this.regMBR,\n this.regPIR,\n this.regSLR,\n this.mmuLastMode,\n this.mmuLastPage,\n this.addrLast,\n this.opFlags,\n this.opLast,\n this.pswTrap,\n this.trapReason,\n this.trapVector,\n this.addrReset\n ] = data[0];\n\n var a = data[1];\n this.setPSW(a[0]);\n this.setMMR0(a[1]);\n this.regMMR1 = a[2];\n this.regMMR2 = a[3];\n this.setMMR3(a[4]);\n\n a = data[2];\n this.nTotalCycles = a[0];\n this.setSpeed(a[1]);\n this.flags.autoStart = a[2];\n\n this.restoreIRQs(data[3]);\n this.restoreTimers(data[4]);\n return true;\n }\n\n /**\n * clearCF()\n *\n * @this {CPUStatePDP11}\n */\n clearCF()\n {\n this.flagC = 0;\n }\n\n /**\n * getCF()\n *\n * @this {CPUStatePDP11}\n * @return {number} 0 or PDP11.PSW.CF\n */\n getCF()\n {\n return (this.flagC & 0x10000)? PDP11.PSW.CF: 0;\n }\n\n /**\n * setCF()\n *\n * @this {CPUStatePDP11}\n */\n setCF()\n {\n this.flagC = 0x10000;\n }\n\n /**\n * clearVF()\n *\n * @this {CPUStatePDP11}\n */\n clearVF()\n {\n this.flagV = 0;\n }\n\n /**\n * getVF()\n *\n * @this {CPUStatePDP11}\n * @return {number} 0 or PDP11.PSW.VF\n */\n getVF()\n {\n return (this.flagV & 0x8000)? PDP11.PSW.VF: 0;\n }\n\n /**\n * setVF()\n *\n * @this {CPUStatePDP11}\n */\n setVF()\n {\n this.flagV = 0x8000;\n }\n\n /**\n * clearZF()\n *\n * @this {CPUStatePDP11}\n */\n clearZF()\n {\n this.flagZ = 1;\n }\n\n /**\n * getZF()\n *\n * @this {CPUStatePDP11}\n * @return {number} 0 or PDP11.PSW.ZF\n */\n getZF()\n {\n return (this.flagZ & 0xffff)? 0 : PDP11.PSW.ZF;\n }\n\n /**\n * setZF()\n *\n * @this {CPUStatePDP11}\n */\n setZF()\n {\n this.flagZ = 0;\n }\n\n /**\n * clearNF()\n *\n * @this {CPUStatePDP11}\n */\n clearNF()\n {\n this.flagN = 0;\n }\n\n /**\n * getNF()\n *\n * @this {CPUStatePDP11}\n * @return {number} 0 or PDP11.PSW.NF\n */\n getNF()\n {\n return (this.flagN & 0x8000)? PDP11.PSW.NF : 0;\n }\n\n /**\n * setNF()\n *\n * @this {CPUStatePDP11}\n */\n setNF()\n {\n this.flagN = 0x8000;\n }\n\n /**\n * getOpcode()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getOpcode()\n {\n var pc = this.opLast = this.regsGen[PDP11.REG.PC];\n /*\n * If PC is unaligned, a BUS trap will be generated, and because it will generate an\n * exception, the next line (the equivalent of advancePC(2)) will not be executed, ensuring that\n * original unaligned PC will be pushed onto the stack by trap().\n */\n var opCode = this.readWord(pc);\n this.regsGen[PDP11.REG.PC] = (pc + 2) & 0xffff;\n return opCode;\n }\n\n /**\n * advancePC(off)\n *\n * NOTE: This function is nothing more than a convenience, and we fully expect it to be inlined at runtime.\n *\n * @this {CPUStatePDP11}\n * @param {number} off\n * @return {number} (original PC)\n */\n advancePC(off)\n {\n var pc = this.regsGen[PDP11.REG.PC];\n this.regsGen[PDP11.REG.PC] = (pc + off) & 0xffff;\n return pc;\n }\n\n /**\n * branch(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @param {boolean|number} condition\n */\n branch(opCode, condition)\n {\n if (condition) {\n var off = ((opCode << 24) >> 23);\n if (DEBUG && DEBUGGER && this.dbg && off == -2) {\n this.dbg.stopInstruction(\"branch to self\");\n }\n this.setPC(this.getPC() + off);\n this.nStepCycles -= 2;\n }\n this.nStepCycles -= (2 + 1);\n }\n\n /**\n * getPC()\n *\n * NOTE: This function is nothing more than a convenience, and we fully expect it to be inlined at runtime.\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getPC()\n {\n return this.regsGen[PDP11.REG.PC];\n }\n\n /**\n * getLastAddr()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getLastAddr()\n {\n return this.addrLast;\n }\n\n /**\n * getLastPC()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getLastPC()\n {\n return this.opLast & 0xffff;\n }\n\n /**\n * setPC()\n *\n * NOTE: Unlike other PCjs emulators, such as PCx86, where all PC updates MUST go through the setPC()\n * function, this function is nothing more than a convenience, because in the PDP-11, the PC can be loaded\n * like any other general register. We fully expect this function to be inlined at runtime.\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n */\n setPC(addr)\n {\n this.regsGen[PDP11.REG.PC] = addr & 0xffff;\n }\n\n /**\n * getSP()\n *\n * NOTE: This function is nothing more than a convenience, and we fully expect it to be inlined at runtime.\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getSP()\n {\n return this.regsGen[PDP11.REG.SP];\n }\n\n /**\n * setSP()\n *\n * NOTE: Unlike other PCjs emulators, such as PCx86, where all SP updates MUST go through the setSP()\n * function, this function is nothing more than a convenience, because in the PDP-11, the PC can be loaded\n * like any other general register. We fully expect this function to be inlined at runtime.\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n */\n setSP(addr)\n {\n this.regsGen[PDP11.REG.SP] = addr & 0xffff;\n }\n\n /**\n * addIRQ(vector, priority, message)\n *\n * @this {CPUStatePDP11}\n * @param {number} vector (-1 for floating vector)\n * @param {number} priority\n * @param {number} [message]\n * @return {IRQ}\n */\n addIRQ(vector, priority, message)\n {\n var irq = {vector: vector, priority: priority, message: message || 0, name: PDP11.VECTORS[vector], next: null};\n this.aIRQs.push(/** @type {IRQ} */ (irq)); // TODO: Why the F*CK do I need a type override? Damn JSDoc types....\n return irq;\n }\n\n /**\n * insertIRQ(irq)\n *\n * @this {CPUStatePDP11}\n * @param {IRQ} irq\n */\n insertIRQ(irq)\n {\n if (irq != this.irqNext) {\n var irqPrev = this.irqNext;\n if (!irqPrev || irqPrev.priority <= irq.priority) {\n irq.next = irqPrev;\n this.irqNext = irq;\n } else {\n do {\n var irqNext = irqPrev.next;\n if (!irqNext || irqNext.priority <= irq.priority) {\n irq.next = irqNext;\n irqPrev.next = irq;\n break;\n }\n irqPrev = irqNext;\n } while (irqPrev);\n }\n }\n /*\n * See the writeXCSR() function for an explanation of why signalling an IRQ hardware interrupt\n * should be done using IRQ_DELAY rather than setting IRQ directly.\n */\n this.opFlags |= PDP11.OPFLAG.IRQ_DELAY;\n }\n\n /**\n * removeIRQ(irq)\n *\n * @this {CPUStatePDP11}\n * @param {IRQ} irq\n */\n removeIRQ(irq)\n {\n var irqPrev = this.irqNext;\n if (irqPrev == irq) {\n this.irqNext = irq.next;\n } else {\n while (irqPrev) {\n var irqNext = irqPrev.next;\n if (irqNext == irq) {\n irqPrev.next = irqNext.next;\n break;\n }\n irqPrev = irqNext;\n }\n }\n /*\n * We could also set irq.next to null now, but strictly speaking, that shouldn't be necessary.\n *\n * Last but not least, if there's still an IRQ on the active IRQ list, we need to make sure IRQ_DELAY\n * is still set.\n */\n if (this.irqNext) {\n this.opFlags |= PDP11.OPFLAG.IRQ_DELAY;\n }\n }\n\n /**\n * setIRQ(irq)\n *\n * @this {CPUStatePDP11}\n * @param {IRQ|null} irq\n */\n setIRQ(irq)\n {\n if (irq) {\n this.insertIRQ(irq);\n if (irq.message && this.messageEnabled(irq.message | MessagesPDP11.INT)) {\n this.printMessage(\"setIRQ(vector=\" + Str.toOct(irq.vector) + \",priority=\" + irq.priority + \")\", true, true);\n }\n }\n }\n\n /**\n * clearIRQ(irq)\n *\n * @this {CPUStatePDP11}\n * @param {IRQ|null} irq\n */\n clearIRQ(irq)\n {\n if (irq) {\n this.removeIRQ(irq);\n if (irq.message && this.messageEnabled(irq.message | MessagesPDP11.INT)) {\n this.printMessage(\"clearIRQ(vector=\" + Str.toOct(irq.vector) + \",priority=\" + irq.priority + \")\", true, true);\n }\n }\n }\n\n /**\n * findIRQ(vector)\n *\n * @this {CPUStatePDP11}\n * @param {number} vector\n * @return {IRQ|null}\n */\n findIRQ(vector)\n {\n for (var i = 0; i < this.aIRQs.length; i++) {\n var irq = this.aIRQs[i];\n if (irq.vector === vector) return irq;\n }\n return null;\n }\n\n /**\n * checkIRQs(priority)\n *\n * @this {CPUStatePDP11}\n * @param {number} priority\n * @return {IRQ|null}\n */\n checkIRQs(priority)\n {\n return (this.irqNext && this.irqNext.priority > priority)? this.irqNext : null;\n }\n\n /**\n * resetIRQs(priority)\n *\n * @this {CPUStatePDP11}\n */\n resetIRQs()\n {\n this.irqNext = null;\n }\n\n /**\n * saveIRQs()\n *\n * @this {CPUStatePDP11}\n * @return {Array.<number>}\n */\n saveIRQs()\n {\n var aIRQVectors = [];\n var irq = this.irqNext;\n while (irq) {\n aIRQVectors.push(irq.vector);\n irq = irq.next;\n }\n return aIRQVectors;\n }\n\n /**\n * restoreIRQs(aIRQVectors)\n *\n * @this {CPUStatePDP11}\n * @param {Array.<number>} aIRQVectors\n */\n restoreIRQs(aIRQVectors)\n {\n for (var i = aIRQVectors.length - 1; i >= 0; i--) {\n var irq = this.findIRQ(aIRQVectors[i]);\n\n if (irq) {\n irq.next = this.irqNext;\n this.irqNext = irq;\n }\n }\n }\n\n /**\n * checkInterrupts()\n *\n * @this {CPUStatePDP11}\n * @return {boolean} true if an interrupt was dispatched, false if not\n */\n checkInterrupts()\n {\n var fInterrupt = false;\n\n if (this.opFlags & PDP11.OPFLAG.IRQ) {\n\n var vector = PDP11.TRAP.PIRQ;\n var priority = (this.regPIR & PDP11.PSW.PRI) >> PDP11.PSW.SHIFT.PRI;\n\n var irq = this.checkIRQs(priority);\n if (irq) {\n vector = irq.vector;\n priority = irq.priority;\n }\n\n if (this.dispatchInterrupt(vector, priority)) {\n if (irq) this.removeIRQ(irq);\n fInterrupt = true;\n }\n\n if (!this.irqNext && !this.regPIR) {\n this.opFlags &= ~PDP11.OPFLAG.IRQ;\n }\n }\n else if (this.opFlags & PDP11.OPFLAG.IRQ_DELAY) {\n /*\n * We know that IRQ (bit 2) is clear, so since IRQ_DELAY (bit 0) is set, incrementing opFlags\n * will eventually transform IRQ_DELAY into IRQ, without affecting any other (higher) bits.\n */\n this.opFlags++;\n }\n return fInterrupt;\n }\n\n /**\n * dispatchInterrupt(vector, priority)\n *\n * TODO: The process of dispatching an interrupt MUST cost some cycles; either trap() needs to assess\n * that cost, or we do.\n *\n * @this {CPUStatePDP11}\n * @param {number} vector\n * @param {number} priority\n * @return {boolean} (true if dispatched, false if not)\n */\n dispatchInterrupt(vector, priority)\n {\n var priorityCPU = (this.regPSW & PDP11.PSW.PRI) >> PDP11.PSW.SHIFT.PRI;\n if (priority > priorityCPU) {\n if (this.opFlags & PDP11.OPFLAG.WAIT) {\n this.advancePC(2);\n this.opFlags &= ~PDP11.OPFLAG.WAIT;\n }\n this.trap(vector, 0, PDP11.REASON.INTERRUPT);\n return true;\n }\n return false;\n }\n\n /**\n * checkTraps()\n *\n * NOTE: The following code processes these \"deferred\" traps in priority order. Unfortunately, that\n * order seems to have changed since the 11/20. For reference, here's the priority list for the 11/20:\n *\n * 1. Bus Errors\n * 2. Instruction Traps\n * 3. Trace Trap\n * 4. Stack Overflow Trap\n * 5. Power Failure Trap\n *\n * and for the 11/70:\n *\n * 1. HALT (Instruction, Switch, or Command)\n * 2. MMU Faults\n * 3. Parity Errors\n * 4. Bus Errors (including stack overflow traps?)\n * 5. Floating Point Traps\n * 6. TRAP Instruction\n * 7. TRACE Trap\n * 8. OVFL Trap\n * 9. Power Fail Trap\n * 10. Console Bus Request (Front Panel Operation)\n * 11. PIR 7, BR 7, PIR 6, BR 6, PIR 5, BR 5, PIR 4, BR 4, PIR 3, BR 3, PIR 2, PIR 1\n * 12. WAIT Loop\n *\n * TODO: Determine 1) if the 11/20 Handbook was wrong, or 2) if the 11/70 really has different priorities.\n *\n * Also, as the PDP-11/20 Handbook (1971), p.100, notes:\n *\n * If a bus error is caused by the trap process handling instruction traps, trace traps, stack overflow\n * traps, or a previous bus error, the processor is halted.\n *\n * If a stack overflow is caused by the trap process in handling bus errors, instruction traps, or trace traps,\n * the process is completed and then the stack overflow trap is sprung.\n *\n * TODO: Based on the above notes, we should probably be halting the CPU when a bus error occurs during a trap.\n *\n * @this {CPUStatePDP11}\n * @return {boolean} (true if dispatched, false if not)\n */\n checkTraps()\n {\n if (this.opFlags & PDP11.OPFLAG.TRAP_MMU) {\n this.trap(PDP11.TRAP.MMU, PDP11.OPFLAG.TRAP_MMU, PDP11.REASON.FAULT);\n return true;\n }\n if (this.opFlags & PDP11.OPFLAG.TRAP_SP) {\n this.trap(PDP11.TRAP.BUS, PDP11.OPFLAG.TRAP_SP, PDP11.REASON.YELLOW);\n return true;\n }\n if (this.opFlags & PDP11.OPFLAG.TRAP_TF) {\n this.trap(PDP11.TRAP.BPT, PDP11.OPFLAG.TRAP_TF, PDP11.REASON.TRACE);\n return true;\n }\n return false;\n }\n\n /**\n * isWaiting()\n *\n * @this {CPUStatePDP11}\n * @return {boolean} (true if OPFLAG.WAIT is set, false otherwise)\n */\n isWaiting()\n {\n return !!(this.opFlags & PDP11.OPFLAG.WAIT);\n }\n\n /**\n * getPSW()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getPSW()\n {\n var mask = PDP11.PSW.CMODE | PDP11.PSW.PMODE | PDP11.PSW.REGSET | PDP11.PSW.PRI | PDP11.PSW.TF;\n return this.regPSW = (this.regPSW & mask) | this.getNF() | this.getZF() | this.getVF() | this.getCF();\n }\n\n /**\n * setPSW(newPSW)\n *\n * This updates the CPU Processor Status Word. The PSW should generally be written through\n * this routine so that changes can be tracked properly, for example the correct register set,\n * the current memory management mode, etc. An exception is SPL which writes the priority directly.\n * Note that that N, Z, V, and C flags are actually stored separately for performance reasons.\n *\n * PSW 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0\n * CMODE PMODE RS -------- PRIORITY T N Z V C\n *\n * @this {CPUStatePDP11}\n * @param {number} newPSW\n */\n setPSW(newPSW)\n {\n newPSW &= this.pswUsed;\n this.flagN = newPSW << 12;\n this.flagZ = (~newPSW) & 4;\n this.flagV = newPSW << 14;\n this.flagC = newPSW << 16;\n if ((newPSW ^ this.regPSW) & this.pswRegSet) {\n /*\n * Swap register sets\n */\n for (var i = this.regsAlt.length; --i >= 0;) {\n var tmp = this.regsGen[i];\n this.regsGen[i] = this.regsAlt[i];\n this.regsAlt[i] = tmp;\n }\n }\n this.pswMode = (newPSW >> PDP11.PSW.SHIFT.CMODE) & PDP11.MODE.MASK;\n var oldMode = (this.regPSW >> PDP11.PSW.SHIFT.CMODE) & PDP11.MODE.MASK;\n if (this.pswMode != oldMode) {\n /*\n * Swap stack pointers\n */\n this.regsAltStack[oldMode] = this.regsGen[6];\n this.regsGen[6] = this.regsAltStack[this.pswMode];\n }\n this.regPSW = newPSW;\n\n /*\n * Trigger a call to checkInterrupts(), just in case. If there's an active IRQ, then setting\n * OPFLAG.IRQ is a no-brainer, but even if not, we set IRQ_DELAY in case the priority was lowered\n * enough to permit a programmed interrupt (via regPIR).\n */\n this.opFlags &= ~PDP11.OPFLAG.IRQ;\n this.opFlags |= (this.irqNext? PDP11.OPFLAG.IRQ : PDP11.OPFLAG.IRQ_DELAY);\n }\n\n /**\n * getSLR()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getSLR()\n {\n return this.regSLR & 0xff00;\n }\n\n /**\n * setSLR(newSL)\n *\n * @this {CPUStatePDP11}\n * @param {number} newSLR\n */\n setSLR(newSLR)\n {\n this.regSLR = newSLR | 0xff;\n }\n\n /**\n * getPIR()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getPIR()\n {\n return this.regPIR;\n }\n\n /**\n * setPIR(newPIR)\n *\n * @this {CPUStatePDP11}\n * @param {number} newPIR\n */\n setPIR(newPIR)\n {\n newPIR &= PDP11.PIR.BITS;\n if (newPIR) {\n var bits = newPIR >> PDP11.PIR.SHIFT.BITS;\n do {\n newPIR += PDP11.PIR.PIA_INC;\n } while (bits >>= 1);\n this.opFlags |= PDP11.OPFLAG.IRQ_DELAY;\n }\n this.regPIR = newPIR;\n }\n\n /**\n * updateNZVFlags(result)\n *\n * NOTE: Only N and Z are updated based on the result; V is zeroed, C is unchanged.\n *\n * @this {CPUStatePDP11}\n * @param {number} result\n */\n updateNZVFlags(result)\n {\n this.flagN = this.flagZ = result;\n this.flagV = 0;\n }\n\n /**\n * updateNZVCFlags(result)\n *\n * NOTE: Only N and Z are updated based on the result; both V and C are simply zeroed.\n *\n * @this {CPUStatePDP11}\n * @param {number} result\n */\n updateNZVCFlags(result)\n {\n this.flagN = this.flagZ = result;\n this.flagV = this.flagC = 0;\n }\n\n /**\n * updateAllFlags(result, overflow)\n *\n * NOTE: The V flag is simply zeroed, unless a specific value is provided (eg, by NEG).\n *\n * @this {CPUStatePDP11}\n * @param {number} result\n * @param {number} [overflow]\n */\n updateAllFlags(result, overflow)\n {\n this.flagN = this.flagZ = this.flagC = result;\n this.flagV = overflow || 0;\n }\n\n /**\n * updateAddFlags(result, src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} result (dst + src)\n * @param {number} src\n * @param {number} dst\n */\n updateAddFlags(result, src, dst)\n {\n this.flagN = this.flagZ = this.flagC = result;\n this.flagV = (src ^ result) & (dst ^ result);\n }\n\n /**\n * updateDecFlags(result, dst)\n *\n * NOTE: We could have used updateSubFlags() if not for the fact that the C flag must be preserved.\n *\n * @this {CPUStatePDP11}\n * @param {number} result (dst - src, where src is an implied 1)\n * @param {number} dst\n */\n updateDecFlags(result, dst)\n {\n this.flagN = this.flagZ = result;\n /*\n * Because src is always 1 (with a zero sign bit), it can be optimized out of this calculation.\n */\n this.flagV = (/* src ^ */ dst) & (dst ^ result);\n }\n\n /**\n * updateIncFlags(result, dst)\n *\n * NOTE: We could have used updateAddFlags() if not for the fact that the C flag must be preserved.\n *\n * @this {CPUStatePDP11}\n * @param {number} result (dst + src, where src is an implied 1)\n * @param {number} dst\n */\n updateIncFlags(result, dst)\n {\n this.flagN = this.flagZ = result;\n /*\n * Because src is always 1 (with a zero sign bit), it can be optimized out of this calculation.\n */\n this.flagV = (/* src ^ */ result) & (dst ^ result);\n }\n\n /**\n * updateMulFlags(result)\n *\n * @this {CPUStatePDP11}\n * @param {number} result\n */\n updateMulFlags(result)\n {\n this.flagN = result >> 16;\n this.flagZ = this.flagN | result;\n this.flagV = 0;\n this.flagC = (result < -32768 || result > 32767)? 0x10000 : 0;\n }\n\n /**\n * updateShiftFlags(result)\n *\n * @this {CPUStatePDP11}\n * @param {number} result\n */\n updateShiftFlags(result)\n {\n this.flagN = this.flagZ = this.flagC = result;\n this.flagV = this.flagN ^ (this.flagC >> 1);\n }\n\n /**\n * updateSubFlags(result, src, dst)\n *\n * NOTE: CMP operations calculate (src - dst) rather than (dst - src), so when they call updateSubFlags(),\n * they must reverse the order of the src and dst parameters.\n *\n * @this {CPUStatePDP11}\n * @param {number} result (dst - src)\n * @param {number} src\n * @param {number} dst\n */\n updateSubFlags(result, src, dst)\n {\n this.flagN = this.flagZ = this.flagC = result;\n this.flagV = (src ^ dst) & (dst ^ result);\n }\n\n /**\n * trap(vector, flag, reason)\n *\n * trap() handles all the trap/abort functions. It reads the trap vector from kernel\n * D space, changes mode to reflect the new PSW and PC, and then pushes the old PSW and\n * PC onto the new mode stack.\n *\n * @this {CPUStatePDP11}\n * @param {number} vector\n * @param {number} flag\n * @param {number} [reason] (for diagnostic purposes only)\n */\n trap(vector, flag, reason)\n {\n if (DEBUG && this.dbg) {\n if (this.messageEnabled(MessagesPDP11.TRAP)) {\n var sReason = reason < 0? PDP11.REASONS[-reason] : this.dbg.toStrBase(reason);\n this.printMessage(\"trap to vector \" + this.dbg.toStrBase(vector, 8) + \" (\" + sReason + \")\", MessagesPDP11.TRAP, true);\n }\n }\n\n if (this.nDisableTraps) return;\n\n if (this.pswTrap < 0) {\n this.pswTrap = this.getPSW();\n } else if (!this.pswMode) {\n reason = PDP11.REASON.RED; // double-fault (nested trap) forces a RED condition\n }\n\n if (reason == PDP11.REASON.RED) {\n if (this.opFlags & PDP11.OPFLAG.TRAP_RED) {\n reason = PDP11.REASON.PANIC;\n }\n this.opFlags |= PDP11.OPFLAG.TRAP_RED;\n /*\n * The next two lines used to be deferred until after the setPSW() below, but\n * I'm not seeing any dependencies on these registers, so I'm consolidating the code.\n */\n this.regErr |= PDP11.CPUERR.RED;\n this.regsGen[6] = vector = 4;\n }\n\n if (reason != PDP11.REASON.PANIC) {\n /*\n * NOTE: Pre-setting the auto-dec values for MMR1 to 0xF6F6 is a work-around for an \"EKBEE1\"\n * diagnostic (PC 056710), which tests what happens when a misaligned read triggers a BUS trap,\n * and that trap then triggers an MMU trap during the first pushWord() below.\n *\n * One would think it would be fine to zero those bits by setting opLast to vector alone,\n * and then letting each of the pushWord() calls below shift their own 0xF6 auto-dec value into\n * opLast. When the first pushWord() triggers an MMU trap, we obviously won't get to the second\n * pushWord(), yet the diagnostic expects TWO auto-decs to be recorded. I'm puzzled why the\n * hardware apparently indicates TWO auto-decs, if SP wasn't actually decremented twice, but who\n * am I to judge.\n */\n this.opLast = vector | 0xf6f60000;\n\n /*\n * Read from kernel D space\n */\n this.pswMode = 0;\n var newPC = this.readWord(vector | this.addrDSpace);\n var newPSW = this.readWord(((vector + 2) & 0xffff) | this.addrDSpace);\n\n /*\n * Set new PSW with previous mode\n */\n this.setPSW((newPSW & ~PDP11.PSW.PMODE) | ((this.pswTrap >> 2) & PDP11.PSW.PMODE));\n\n this.pushWord(this.pswTrap);\n this.pushWord(this.regsGen[7]);\n this.setPC(newPC);\n }\n\n /*\n * TODO: Determine the appropriate number of cycles for traps; all I've done for now is move the\n * cycle charge from opTrap() to here, and reduced the amount the other opcode handlers that call\n * trap() charge by a corresponding amount (5).\n */\n this.nStepCycles -= (4 + 1);\n\n /*\n * DEC's \"TRAP TEST\" (MAINDEC-11-D0NA-PB) triggers a RESERVED trap with an invalid opcode and the\n * stack deliberately set too low, and expects the stack overflow trap to be \"sprung\" immediately\n * afterward, so we only want to \"lose interest\" in the TRAP flag(s) that were set on entry, not ALL\n * of them.\n *\n * this.opFlags &= ~PDP11.OPFLAG.TRAP_MASK; // lose interest in traps after an abort\n *\n * Well, OK, we're also supposed to \"lose interest\" in the TF flag, too; otherwise, DEC tests fail.\n *\n * Finally, setPSW() likes to always set IRQ, to force a check of hardware interrupts prior to\n * the next instruction, just in case the PSW priority was lowered. However, there are \"TRAP TEST\"\n * tests like this one:\n *\n * 005640: 012706 007700 MOV #7700,SP\n * 005644: 012767 000340 172124 MOV #340,177776\n * 005652: 012767 000100 171704 MOV #100,177564\n * 005660: 012767 005712 172146 MOV #5712,000034 ; set TRAP vector (its PSW is already zero)\n * 005666: 012767 005714 172170 MOV #5714,000064 ; set hardware interrupt vector (its PSW is already zero)\n * 005674: 012767 005716 172116 MOV #5716,000020 ; set IOT vector\n * 005702: 012767 000340 172112 MOV #340,000022 ; set IOT PSW\n * 005710: 104400 TRAP 000\n * 005712: 000004 IOT\n * 005714: 000000 HALT\n *\n * where, after \"TRAP 000\" has executed, a hardware interrupt will be acknowledged, and instead of\n * executing the IOT, we'll execute the HALT and fail the test. We avoid that by relying on the same\n * trick that the SPL instruction uses: setting IRQ_DELAY instead of IRQ, which effectively delays\n * IRQ detection for one instruction, which is just long enough to allow the diagnostic to pass.\n */\n this.opFlags &= ~(flag | PDP11.OPFLAG.TRAP_TF | PDP11.OPFLAG.IRQ_MASK);\n this.opFlags |= PDP11.OPFLAG.IRQ_DELAY | PDP11.OPFLAG.TRAP_LAST;\n\n this.pswTrap = -1; // reset flag that we have a trap within a trap\n\n /*\n * These next properties (in conjunction with setting PDP11.OPFLAG.TRAP_LAST) are purely an aid for the Debugger;\n * see getTrapStatus().\n */\n this.trapReason = reason;\n this.trapVector = vector;\n\n if (reason == PDP11.REASON.PANIC) {\n this.stopCPU();\n }\n if (reason >= PDP11.REASON.RED) throw vector;\n }\n\n /**\n * trapReturn()\n *\n * @this {CPUStatePDP11}\n */\n trapReturn()\n {\n /*\n * This code used to defer updating regsGen[6] (SP) until after BOTH words had been popped, which seems\n * safer, but if we're going to do pushes in trap(), then I see no reason to avoid doing pops in trapReturn().\n */\n var addr = this.popWord();\n var newPSW = this.popWord();\n if (this.regPSW & PDP11.PSW.CMODE) {\n /*\n * Keep SPL and allow lower only for modes and register set.\n *\n * TODO: Review, because it seems a bit odd to only CLEAR the PRI bits in the new PSW, and then to OR in\n * CMODE, PMODE, and REGSET bits from the current PSW.\n */\n newPSW = (newPSW & ~PDP11.PSW.PRI) | (this.regPSW & (PDP11.PSW.PRI | PDP11.PSW.REGSET | PDP11.PSW.PMODE | PDP11.PSW.CMODE));\n }\n this.setPC(addr);\n this.setPSW(newPSW);\n this.opFlags &= ~PDP11.OPFLAG.TRAP_TF;\n }\n\n /**\n * getTrapStatus()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getTrapStatus()\n {\n return (this.opFlags & PDP11.OPFLAG.TRAP_LAST)? (this.trapVector | this.trapReason << 8) : 0;\n }\n\n /**\n * mapUnibus(addr)\n *\n * Used to convert 18-bit addresses to 22-bit addresses. Since mapUnibus() only looks at the low 18 bits of addr,\n * there's no need to mask addr first. Note that if bits 13-17 are all set, then the 18-bit address points to the\n * top 8Kb of its 256Kb range, and mapUnibus() will return addr unchanged, since it should already be pointing to\n * the top 8Kb of the 4Mb 22-bit range.\n *\n * Also, when bits 18-21 of addr are ALL set (which callers check using addr >= BusPDP11.UNIBUS_22BIT aka 0x3C0000),\n * then we have a 22-bit address pointing to the top 256Kb range, so if the UNIBUS relocation map is enabled, we again\n * pass the lower 18 bits of that address through the map.\n *\n * From the PDP-11/70 Handbook:\n *\n * On the 11/44 and 11/70, there are a total of 31 mapping registers for address relocation. Each register is\n * composed of a double 16-bit PDP-11 word (in consecutive locations) that holds the 22-bit base address. These\n * registers have UNIBUS addresses in the range 770200 to 770372.\n *\n * If the UNIBUS map relocation is not enabled, an incoming 18-bit UNIBUS address has 4 leading zeroes added for\n * referencing a 22-bit physical address. The lower 18 bits are the same. No relocation is performed.\n *\n * If UNIBUS map relocation is enabled, the five high order bits of the UNIBUS address are used to select one of the\n * 31 mapping registers. The low-order 13 bits of the incoming address are used as an offset from the base address\n * contained in the 22-bit mapping register. To form the physical address, the 13 low-order bits of the UNIBUS\n * address are added to 22 bits of the selected mapping register to produce the 22-bit physical address. The lowest\n * order bit of all mapping registers is always a zero, since relocation is always on word boundaries.\n *\n * Sadly, because these mappings occur at a word-granular level, we can't implement the mappings by simply shuffling\n * the underlying block around in the Bus component; it would be much more efficient if we could. That's how we move\n * the IOPAGE in response to addressing changes.\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @return {number}\n */\n mapUnibus(addr)\n {\n var idx = (addr >> 13) & 0x1F;\n if (idx < 31) {\n if (this.regMMR3 & PDP11.MMR3.UNIBUS_MAP) {\n /*\n * The UNIBUS map relocation is enabled\n */\n addr = (this.regsUniMap[idx] + (addr & 0x1FFF)) & BusPDP11.MASK_22BIT;\n /*\n * TODO: Review this assertion.\n *\n *\n */\n } else {\n /*\n * Since UNIBUS map relocation is NOT enabled, then as explained above:\n *\n * If the UNIBUS map relocation is not enabled, an incoming 18-bit UNIBUS address has 4 leading zeroes added for\n * referencing a 22-bit physical address. The lower 18 bits are the same. No relocation is performed.\n */\n addr &= ~BusPDP11.UNIBUS_22BIT;\n }\n }\n return addr;\n }\n\n /**\n * getAddrInfo(addr, fPhysical)\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @param {boolean} [fPhysical]\n * @return {Array}\n */\n getAddrInfo(addr, fPhysical)\n {\n var a = [];\n var addrPhysical;\n\n if (fPhysical) {\n addrPhysical = this.mapUnibus(addr);\n var idx = (addr >> 13) & 0x1F;\n a.push(addrPhysical);\n a.push(idx);\n if (this.regMMR3 & PDP11.MMR3.UNIBUS_MAP) {\n a.push(this.regsUniMap[idx]);\n a.push(addr & 0x1FFF);\n }\n }\n else if (!this.mmuEnable) {\n addrPhysical = addr & 0xffff;\n if (addrPhysical >= BusPDP11.IOPAGE_16BIT) addrPhysical |= this.addrIOPage;\n a.push(addrPhysical);\n }\n else {\n var mode = this.pswMode << 1;\n var page = addr >> 13;\n if (page > 7) mode |= 1;\n if (!(this.regMMR3 & this.mapMMR3[this.pswMode])) page &= 7;\n var pdr = this.regsPDR[this.pswMode][page];\n var off = addr & 0x1fff;\n var paf = (this.regsPAR[this.pswMode][page] << 6);\n addrPhysical = (paf + off) & this.mmuMask;\n if (addrPhysical >= BusPDP11.UNIBUS_22BIT) addrPhysical = this.mapUnibus(addrPhysical);\n a.push(addrPhysical); // a[0]\n a.push(off); // a[1]\n a.push(mode); // a[2] (0=KI, 1=KD, 2=SI, 3=SD, 4=??, 5=??, 6=UI, 7=UD)\n a.push(page & 7); // a[3]\n a.push(paf); // a[4]\n a.push(this.mmuMask); // a[5]\n }\n return a;\n }\n\n /**\n * mapVirtualToPhysical(addrVirtual, access)\n *\n * mapVirtualToPhysical() does memory management. It converts a 17-bit I/D virtual address to a\n * 22-bit physical address. A real PDP 11/70 memory management unit can be enabled separately for\n * read and write for diagnostic purposes. This is handled here by having an enable mask (mmuEnable)\n * which is tested against the operation access mask (access). If there is no match, then the virtual\n * address is simply mapped as a 16 bit physical address with the upper page going to the IO address\n * space. Significant access mask values used are PDP11.ACCESS.READ and PDP11.ACCESS.WRITE.\n *\n * When doing mapping, pswMode is used to decide what address space is to be used (0 = kernel,\n * 1 = supervisor, 2 = illegal, 3 = user). Normally, pswMode is set by the setPSW() function, but\n * there are exceptions for instructions which move data between address spaces (MFPD, MFPI, MTPD,\n * and MTPI) and trap(). These will modify pswMode outside of setPSW() and then restore it again if\n * all worked. If however something happens to cause a trap then no restore is done as setPSW()\n * will have been invoked as part of the trap, which will resynchronize pswMode.\n *\n * A PDP-11/70 is different from other PDP-11s in that the highest 18 bit space (017000000 & above)\n * maps directly to UNIBUS space - including low memory. This doesn't appear to be particularly useful\n * as it restricts maximum system memory - although it does appear to allow software testing of the\n * UNIBUS map. This feature also appears to confuse some OSes which test consecutive memory locations\n * to find maximum memory -- and on a full memory system find themselves accessing low memory again at\n * high addresses.\n *\n * Construction of a Physical Address\n * ----------------------------------\n *\n * Virtual Addr (VA) 12 11 10 9 8 7 6 5 4 3 2 1 0\n * + Page Addr Field (PAF) 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0\n * -----------------------------------------------------------------\n * = Physical Addr (PA) 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0\n *\n * The Page Address Field (PAF) comes from a Page Address Register (PAR) that is selected by Virtual\n * Address (VA) bits 15-13. You can see from the above alignments that the VA contributes to the low\n * 13 bits, providing an 8Kb range.\n *\n * VA bits 0-5 pass directly through to the PA; those are also called the DIB (Displacement in Block) bits.\n * VA bits 6-12 are added to the low 7 bits of the PAF and are also called the BN (Block Number) bits.\n *\n * You can also think of the entire PAF as a block number, where each block is 64 bytes. This is consistent\n * with the LSIZE register at 177760, which is supposed to contain the block number of the last 64-byte block\n * of memory installed.\n *\n * Note that if a PAR is initialized to zero, successively adding 0200 (0x80) to the PAR will advance the\n * base physical address to the next 8Kb page.\n *\n * @this {CPUStatePDP11}\n * @param {number} addrVirtual\n * @param {number} access\n * @return {number}\n */\n mapVirtualToPhysical(addrVirtual, access)\n {\n var page, pdr, addr;\n\n /*\n * This can happen when the MAINT bit of MMR0 is set but not the ENABLED bit.\n */\n if (!(access & this.mmuEnable)) {\n addr = addrVirtual & 0xffff;\n if (addr >= BusPDP11.IOPAGE_16BIT) addr |= this.addrIOPage;\n return addr;\n }\n\n page = addrVirtual >> 13;\n if (!(this.regMMR3 & this.mapMMR3[this.pswMode])) page &= 7;\n pdr = this.regsPDR[this.pswMode][page];\n addr = ((this.regsPAR[this.pswMode][page] << 6) + (addrVirtual & 0x1fff)) & this.mmuMask;\n\n if (addr >= BusPDP11.UNIBUS_22BIT) addr = this.mapUnibus(addr);\n\n if (this.nDisableTraps) return addr;\n\n /*\n * TEST #122 (\"KT BEND\") in the \"EKBEE1\" diagnostic (PC 076060) triggers a NOMEMORY error using\n * this instruction:\n *\n * 076170: 005037 140100 CLR @#140100\n *\n * It also triggers an ODDADDR error using this instruction:\n *\n * 076356: 005037 140001 CLR @#140001\n *\n * @paulnank: So it turns out that the memory management unit that does odd address and non-existent\n * memory trapping: who knew? :-) I thought these would have been handled at access time.\n *\n * @jeffpar: We're assuming, at least, that the MMU does its \"NEXM\" (NOMEMORY) non-existent memory test\n * very simplistically, by range-checking the address against something like the memory SIZE registers,\n * because otherwise the MMU would have to wait for a bus time-out: something so prohibitively expensive\n * that the MMU could not afford to do it. I rely on addrInvalid, which is derived from the same Bus\n * getMemoryLimit() service that the SIZE registers (177760--177762) use to derive their value.\n */\n if (addr >= this.addrInvalid && addr < this.addrIOPage) {\n this.regErr |= PDP11.CPUERR.NOMEMORY;\n this.trap(PDP11.TRAP.BUS, 0, addr);\n }\n else if ((addr & 0x1) && !(access & PDP11.ACCESS.BYTE)) {\n this.regErr |= PDP11.CPUERR.ODDADDR;\n this.trap(PDP11.TRAP.BUS, 0, addr);\n }\n\n var newMMR0 = 0;\n switch (pdr & PDP11.PDR.ACF.MASK) {\n\n case PDP11.PDR.ACF.RO1: // 0x1: read-only, abort on write attempt, memory management trap on read (11/70 only)\n newMMR0 = PDP11.MMR0.TRAP_MMU;\n /* falls through */\n\n case PDP11.PDR.ACF.RO: // 0x2: read-only, abort on write attempt\n pdr |= PDP11.PDR.ACCESSED;\n if (access & PDP11.ACCESS.WRITE) {\n newMMR0 = PDP11.MMR0.ABORT_RO;\n }\n break;\n\n case PDP11.PDR.ACF.RW1: // 0x4: read/write, memory management trap upon completion of a read or write\n newMMR0 = PDP11.MMR0.TRAP_MMU;\n /* falls through */\n\n case PDP11.PDR.ACF.RW2: // 0x5: read/write, memory management trap upon completion of a write (11/70 only)\n if (access & PDP11.ACCESS.WRITE) {\n newMMR0 = PDP11.MMR0.TRAP_MMU;\n }\n /* falls through */\n\n case PDP11.PDR.ACF.RW: // 0x6: read/write, no system trap/abort action\n pdr |= ((access & PDP11.ACCESS.WRITE) ? (PDP11.PDR.ACCESSED | PDP11.PDR.MODIFIED) : PDP11.PDR.ACCESSED);\n break;\n\n default: // 0x0 (non-resident, abort all accesses) or 0x3 or 0x7 (unused, abort all accesses)\n newMMR0 = PDP11.MMR0.ABORT_NR;\n break;\n }\n\n if ((pdr & (PDP11.PDR.PLF | PDP11.PDR.ED)) != PDP11.PDR.PLF) { // skip checking most common case (hopefully)\n /*\n * The Page Descriptor Register (PDR) Page Length Field (PLF) is a 7-bit block number, where a block\n * is 64 bytes. Since the bit 0 of the block number is located at bit 8 of the PDR, we shift the PDR\n * right 2 bits and then clear the bottom 6 bits by masking it with 0x1FC0.\n */\n if (pdr & PDP11.PDR.ED) {\n if (pdr & PDP11.PDR.PLF) {\n if ((addrVirtual & 0x1FC0) < ((pdr >> 2) & 0x1FC0)) {\n newMMR0 |= PDP11.MMR0.ABORT_PL;\n }\n }\n } else {\n if ((addrVirtual & 0x1FC0) > ((pdr >> 2) & 0x1FC0)) {\n newMMR0 |= PDP11.MMR0.ABORT_PL;\n }\n }\n }\n\n /*\n * Aborts and traps: log FIRST trap and MOST RECENT abort\n */\n this.regsPDR[this.pswMode][page] = pdr;\n if (addr != ((BusPDP11.IOPAGE_22BIT | PDP11.UNIBUS.MMR0) & this.mmuMask) || this.pswMode) {\n this.mmuLastMode = this.pswMode;\n this.mmuLastPage = page;\n }\n\n if (newMMR0) {\n if (newMMR0 & PDP11.MMR0.ABORT) {\n if (this.pswTrap >= 0) {\n newMMR0 |= PDP11.MMR0.COMPLETED;\n }\n if (!(this.regMMR0 & PDP11.MMR0.ABORT)) {\n newMMR0 |= (this.regMMR0 & PDP11.MMR0.TRAP_MMU) | (this.mmuLastMode << 5) | (this.mmuLastPage << 1);\n\n this.setMMR0((this.regMMR0 & ~PDP11.MMR0.UPDATE) | (newMMR0 & PDP11.MMR0.UPDATE));\n }\n /*\n * NOTE: In unusual circumstances, if regMMR0 already indicated an ABORT condition above,\n * we run the risk of infinitely looping; eg, we call trap(), which calls mapVirtualToPhysical()\n * on the trap vector, which faults again, etc.\n *\n * TODO: Determine what a real PDP-11 does in that situation; in our case, trap() deals with it\n * by checking an internal OPFLAG (TRAP_RED) and turning the next trap into a PANIC, triggering an\n * immediate HALT.\n */\n this.trap(PDP11.TRAP.MMU, PDP11.OPFLAG.TRAP_MMU, PDP11.REASON.ABORT);\n }\n if (!(this.regMMR0 & (PDP11.MMR0.ABORT | PDP11.MMR0.TRAP_MMU))) {\n /*\n * TODO: Review the code below, because the address range seems over-inclusive.\n */\n if (addr < ((BusPDP11.IOPAGE_22BIT | PDP11.UNIBUS.SIPDR0) & this.mmuMask) ||\n addr > ((BusPDP11.IOPAGE_22BIT | PDP11.UNIBUS.UDPAR7 | 0x1) & this.mmuMask)) {\n this.regMMR0 |= PDP11.MMR0.TRAP_MMU;\n if (this.regMMR0 & PDP11.MMR0.MMU_TRAPS) this.opFlags |= PDP11.OPFLAG.TRAP_MMU;\n }\n }\n }\n return addr;\n }\n\n /**\n * popWord()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n popWord()\n {\n var result = this.readWord(this.regsGen[6] | this.addrDSpace);\n this.regsGen[6] = (this.regsGen[6] + 2) & 0xffff;\n return result;\n }\n\n /**\n * pushWord(data)\n *\n * @this {CPUStatePDP11}\n * @param {number} data\n */\n pushWord(data)\n {\n var addrVirtual = (this.regsGen[6] - 2) & 0xffff;\n this.regsGen[6] = addrVirtual; // BSD needs SP updated before any fault :-(\n this.opLast = (this.opLast & 0xffff) | ((this.opLast & ~0xffff) << 8) | (0x00f6 << 16);\n if (!(this.opFlags & PDP11.OPFLAG.TRAP_RED)) this.checkStackLimit(PDP11.ACCESS.WRITE_WORD, -2, addrVirtual);\n this.writeWord(addrVirtual, data);\n }\n\n /**\n * getAddrByMode(mode, reg, access)\n *\n * getAddrByMode() maps a six bit operand to a 17 bit I/D virtual address space.\n *\n * Instruction operands are six bits in length - three bits for the mode and three\n * for the register. The 17th I/D bit in the resulting virtual address represents\n * whether the reference is to Instruction space or Data space - which depends on\n * combination of the mode and whether the register is the Program Counter (R7).\n *\n * The eight modes are:-\n * 0 R no valid virtual address\n * 1 (R) operand from I/D depending if R = 7\n * 2 (R)+ operand from I/D depending if R = 7\n * 3 @(R)+ address from I/D depending if R = 7 and operand from D space\n * 4 -(R) operand from I/D depending if R = 7\n * 5 @-(R) address from I/D depending if R = 7 and operand from D space\n * 6 x(R) x from I space but operand from D space\n * 7 @x(R) x from I space but address and operand from D space\n *\n * Also need to keep MMR1 updated as this stores which registers have been\n * incremented and decremented so that the OS can reset and restart an instruction\n * if a page fault occurs.\n *\n * Stack Overflow Traps\n * --------------------\n * On the PDP-11/20, stack overflow traps occur when an address below 400 is referenced\n * by SP in either mode 4 (auto-decrement) or 5 (auto-decrement deferred). The instruction\n * is allowed to complete before the trap is issued. NOTE: This information comes\n * directly from the PDP-11/20 Handbook (1971), but the 11/20 diagnostics apparently only\n * test mode 4, not mode 5, because when I later removed stack limit checks for mode 5 on\n * the 11/70, none of the 11/20 tests complained.\n *\n * TODO: Find some independent confirmation as to whether ANY PDP-11 models check for\n * stack overflow on mode 5 (auto-decrement deferred); if they do, then further tweaks to\n * checkStackLimit functions may be required.\n *\n * On the PDP-11/70, the stack limit register (177774) allows a variable boundary for the\n * kernel stack.\n *\n * @this {CPUStatePDP11}\n * @param {number} mode\n * @param {number} reg\n * @param {number} access\n * @return {number}\n */\n getAddrByMode(mode, reg, access)\n {\n var addrVirtual, step;\n var addrDSpace = (access & PDP11.ACCESS.VIRT)? 0 : this.addrDSpace;\n\n /*\n * Modes that need to auto-increment or auto-decrement will break, in order to perform\n * the update; others will return an address immediately.\n */\n switch (mode) {\n /*\n * Mode 0: Registers don't have a virtual address, so trap.\n *\n * NOTE: Most instruction code paths never call getAddrByMode() when the mode is zero;\n * JMP and JSR instructions are exceptions, but that's OK, because those are documented as\n * ILLEGAL instructions which produce a BUS trap (as opposed to UNDEFINED instructions\n * that cause a RESERVED trap).\n */\n case 0:\n this.trap(PDP11.TRAP.BUS, 0, PDP11.REASON.ILLEGAL);\n return 0;\n\n /*\n * Mode 1: (R)\n */\n case 1:\n if (reg == 6) this.checkStackLimit(access, 0, this.regsGen[6]);\n this.nStepCycles -= (2 + 1);\n return (reg == 7? this.regsGen[reg] : (this.regsGen[reg] | addrDSpace));\n\n /*\n * Mode 2: (R)+\n */\n case 2:\n step = 2;\n addrVirtual = this.regsGen[reg];\n if (reg == 6) this.checkStackLimit(access, step, addrVirtual);\n if (reg != 7) {\n addrVirtual |= addrDSpace;\n if (reg < 6 && (access & PDP11.ACCESS.BYTE)) step = 1;\n }\n this.nStepCycles -= (2 + 1);\n break;\n\n /*\n * Mode 3: @(R)+\n */\n case 3:\n step = 2;\n addrVirtual = this.regsGen[reg];\n if (reg != 7) addrVirtual |= addrDSpace;\n addrVirtual = this.readWord(addrVirtual);\n addrVirtual |= addrDSpace;\n this.nStepCycles -= (5 + 2);\n break;\n\n /*\n * Mode 4: -(R)\n */\n case 4:\n step = -2;\n if (reg < 6 && (access & PDP11.ACCESS.BYTE)) step = -1;\n addrVirtual = (this.regsGen[reg] + step) & 0xffff;\n if (reg == 6) this.checkStackLimit(access, step, addrVirtual);\n if (reg != 7) addrVirtual |= addrDSpace;\n this.nStepCycles -= (3 + 1);\n break;\n\n /*\n * Mode 5: @-(R)\n */\n case 5:\n step = -2;\n addrVirtual = (this.regsGen[reg] - 2) & 0xffff;\n if (reg != 7) addrVirtual |= addrDSpace;\n addrVirtual = this.readWord(addrVirtual) | addrDSpace;\n this.nStepCycles -= (6 + 2);\n break;\n\n /*\n * Mode 6: d(R)\n */\n case 6:\n addrVirtual = this.readWord(this.advancePC(2));\n addrVirtual = (addrVirtual + this.regsGen[reg]) & 0xffff;\n if (reg == 6) this.checkStackLimit(access, 0, addrVirtual);\n this.nStepCycles -= (4 + 2);\n return addrVirtual | addrDSpace;\n\n /*\n * Mode 7: @d(R)\n */\n case 7:\n addrVirtual = this.readWord(this.advancePC(2));\n addrVirtual = (addrVirtual + this.regsGen[reg]) & 0xffff;\n addrVirtual = this.readWord(addrVirtual | this.addrDSpace);\n this.nStepCycles -= (7 + 3);\n return addrVirtual | addrDSpace;\n }\n\n this.regsGen[reg] = (this.regsGen[reg] + step) & 0xffff;\n this.opLast = (this.opLast & 0xffff) | ((this.opLast & ~0xffff) << 8) | ((((step << 3) & 0xf8) | reg) << 16);\n\n return addrVirtual;\n }\n\n /**\n * checkStackLimit1120(access, step, addr)\n *\n * @this {CPUStatePDP11}\n * @param {number} access\n * @param {number} step\n * @param {number} addr\n */\n checkStackLimit1120(access, step, addr)\n {\n /*\n * NOTE: DEC's \"TRAP TEST\" (MAINDEC-11-D0NA-PB) expects \"TST -(SP)\" to trap when SP is 150,\n * so we ignore the access parameter. Also, strangely, it does NOT expect this instruction\n * to trap:\n *\n * R0=006302 R1=000000 R2=000000 R3=000000 R4=000000 R5=000776\n * SP=000000 PC=006346 PS=000344 IR=000000 SL=000377 T0 N0 Z1 V0 C0\n * 006346: 112667 171426 MOVB (SP)+,000000\n *\n * so if the step parameter is positive, we let it go.\n */\n if (!this.pswMode && step <= 0 && addr <= this.regSLR) {\n /*\n * On older machines (eg, the PDP-11/20), there is no \"YELLOW\" and \"RED\" distinction, and the\n * instruction is always allowed to complete, so the trap must always be issued in this fashion.\n */\n this.opFlags |= PDP11.OPFLAG.TRAP_SP;\n }\n }\n\n /**\n * checkStackLimit1140(access, step, addr)\n *\n * @this {CPUStatePDP11}\n * @param {number} access\n * @param {number} step\n * @param {number} addr\n */\n checkStackLimit1140(access, step, addr)\n {\n if (!this.pswMode) {\n /*\n * NOTE: The 11/70 CPU Instruction Exerciser does NOT expect reads to trigger a stack overflow,\n * so we check the access parameter.\n *\n * Moreover, TEST 40 of diagnostic EKBBF0 executes this instruction:\n *\n * R0=177777 R1=032435 R2=152110 R3=000024 R4=153352 R5=001164\n * SP=177776 PC=020632 PS=000350 IR=000000 SL=000377 T0 N1 Z0 V0 C0\n * 020632: 005016 CLR @SP ;cycles=7\n *\n * expecting a RED stack overflow trap. Yes, using *any* addresses in the IOPAGE for the stack isn't\n * a good idea, but who said it was illegal? For now, we're going to restrict overflows to the highest\n * address tested by the diagnostic (0xFFFE, aka the PSW), by making that address negative.\n */\n if (addr >= 0xFFFE) addr |= ~0xFFFF;\n if ((access & PDP11.ACCESS.WRITE) && addr <= this.regSLR) {\n /*\n * regSLR can never fall below 0xFF, so this subtraction can never go negative, so this comparison\n * is always safe.\n */\n if (addr <= this.regSLR - 32) {\n this.trap(PDP11.TRAP.BUS, 0, PDP11.REASON.RED);\n } else {\n this.regErr |= PDP11.CPUERR.YELLOW;\n this.opFlags |= PDP11.OPFLAG.TRAP_SP;\n }\n }\n }\n }\n\n /**\n * getByteChecked(addr)\n *\n * This is the getByte() handler whenever the Debugger has one or more virtual memory READ breakpoints set;\n * otherwise, getByte() is bound to Bus.getByte().\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @return {number}\n */\n getByteChecked(addr)\n {\n if (DEBUGGER && this.dbg) {\n this.dbg.checkMemoryRead(addr, 1);\n }\n return this.getByteDirect(addr);\n }\n\n /**\n * getWordChecked(addr)\n *\n * This is the getWord() handler whenever the Debugger has one or more virtual memory READ breakpoints set;\n * otherwise, getWord() is bound to Bus.getWord().\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @return {number}\n */\n getWordChecked(addr)\n {\n if (DEBUGGER && this.dbg) {\n this.dbg.checkMemoryRead(addr, 2);\n }\n return this.getWordDirect(addr);\n }\n\n /**\n * setByteChecked(addr, data)\n *\n * This is the setByte() handler whenever the Debugger has one or more virtual memory WRITE breakpoints set;\n * otherwise, setByte() is bound to Bus.setByte().\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @param {number} data\n */\n setByteChecked(addr, data)\n {\n if (DEBUGGER && this.dbg) {\n this.dbg.checkMemoryWrite(addr, 1);\n }\n this.setByteDirect(addr, data);\n }\n\n /**\n * setWordChecked(addr, data)\n *\n * This is the setWord() handler whenever the Debugger has one or more virtual memory WRITE breakpoints set;\n * otherwise, setWord() is bound to Bus.setWord().\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @param {number} data\n */\n setWordChecked(addr, data)\n {\n if (DEBUGGER && this.dbg) {\n this.dbg.checkMemoryWrite(addr, 2);\n }\n this.setWordDirect(addr, data);\n }\n\n /**\n * getByteSafe(addr)\n *\n * This interface is expressly for the Debugger, to access virtual memory without faulting.\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @return {number}\n */\n getByteSafe(addr)\n {\n this.nDisableTraps++;\n var b = this.bus.getByte(this.mapVirtualToPhysical(addr, PDP11.ACCESS.READ_BYTE));\n this.nDisableTraps--;\n return b;\n }\n\n /**\n * getWordSafe(addr)\n *\n * This interface is expressly for the Debugger, to access virtual memory without faulting.\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @return {number}\n */\n getWordSafe(addr)\n {\n this.nDisableTraps++;\n var w = this.bus.getWord(this.mapVirtualToPhysical(addr, PDP11.ACCESS.READ_WORD));\n this.nDisableTraps--;\n return w;\n }\n\n /**\n * setByteSafe(addr, data)\n *\n * This interface is expressly for the Debugger, to access virtual memory without faulting.\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @param {number} data\n */\n setByteSafe(addr, data)\n {\n this.nDisableTraps++;\n this.bus.setByte(this.mapVirtualToPhysical(addr, PDP11.ACCESS.WRITE_BYTE), data);\n this.nDisableTraps--;\n }\n\n /**\n * setWordSafe(addr, data)\n *\n * This interface is expressly for the Debugger, to access virtual memory without faulting.\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @param {number} data\n */\n setWordSafe(addr, data)\n {\n this.nDisableTraps++;\n this.bus.setWord(this.mapVirtualToPhysical(addr, PDP11.ACCESS.WRITE_WORD), data);\n this.nDisableTraps--;\n }\n\n /**\n * addMemBreak(addr, fWrite)\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint\n */\n addMemBreak(addr, fWrite)\n {\n if (DEBUGGER) {\n var nBreaks = fWrite? this.nWriteBreaks++ : this.nReadBreaks++;\n\n if (!nBreaks) this.setMemoryAccess();\n }\n }\n\n /**\n * removeMemBreak(addr, fWrite)\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint\n */\n removeMemBreak(addr, fWrite)\n {\n if (DEBUGGER) {\n var nBreaks = fWrite? --this.nWriteBreaks : --this.nReadBreaks;\n\n if (!nBreaks) this.setMemoryAccess();\n }\n }\n\n /**\n * getPhysicalAddrByMode(mode, reg, access)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through getAddr().\n *\n * @this {CPUStatePDP11}\n * @param {number} mode\n * @param {number} reg\n * @param {number} access\n * @return {number}\n */\n getPhysicalAddrByMode(mode, reg, access)\n {\n return this.getAddrByMode(mode, reg, access);\n }\n\n /**\n * getVirtualAddrByMode(mode, reg, access)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through getAddr().\n *\n * @this {CPUStatePDP11}\n * @param {number} mode\n * @param {number} reg\n * @param {number} access\n * @return {number}\n */\n getVirtualAddrByMode(mode, reg, access)\n {\n return this.mapVirtualToPhysical(this.getAddrByMode(mode, reg, access), access);\n }\n\n /**\n * readWordFromPhysical(addr)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through readWord().\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @return {number}\n */\n readWordFromPhysical(addr)\n {\n return this.bus.getWord(this.addrLast = addr);\n }\n\n /**\n * readWordFromPhysicalChecked(addr)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through readWord().\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @return {number}\n */\n readWordFromPhysicalChecked(addr)\n {\n if (DEBUGGER && this.dbg) {\n this.dbg.checkMemoryRead(addr, 2);\n }\n return this.readWordFromPhysical(addr);\n }\n\n /**\n * readWordFromVirtual(addrVirtual)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through readWord().\n *\n * @this {CPUStatePDP11}\n * @param {number} addrVirtual (input address is 17 bit (I&D))\n * @return {number}\n */\n readWordFromVirtual(addrVirtual)\n {\n return this.bus.getWord(this.addrLast = this.mapVirtualToPhysical(addrVirtual, PDP11.ACCESS.READ_WORD));\n }\n\n /**\n * readWordFromVirtualChecked(addrVirtual)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through readWord().\n *\n * @this {CPUStatePDP11}\n * @param {number} addrVirtual (input address is 17 bit (I&D))\n * @return {number}\n */\n readWordFromVirtualChecked(addrVirtual)\n {\n if (DEBUGGER && this.dbg) {\n this.dbg.checkMemoryRead(addrVirtual, 2);\n }\n return this.readWordFromVirtual(addrVirtual);\n }\n\n /**\n * writeWordToPhysical(addr, data)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through writeWord().\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @param {number} data\n */\n writeWordToPhysical(addr, data)\n {\n this.bus.setWord(this.addrLast = addr, data);\n }\n\n /**\n * writeWordToPhysicalChecked(addr, data)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through writeWord().\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @param {number} data\n */\n writeWordToPhysicalChecked(addr, data)\n {\n if (DEBUGGER && this.dbg) {\n this.dbg.checkMemoryWrite(addr, 2);\n }\n this.writeWordToPhysical(addr, data);\n }\n\n /**\n * writeWordToVirtual(addrVirtual, data)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through writeWord().\n *\n * @this {CPUStatePDP11}\n * @param {number} addrVirtual (input address is 17 bit (I&D))\n * @param {number} data\n */\n writeWordToVirtual(addrVirtual, data)\n {\n this.bus.setWord(this.addrLast = this.mapVirtualToPhysical(addrVirtual, PDP11.ACCESS.WRITE_WORD), data);\n }\n\n /**\n * writeWordToVirtualChecked(addrVirtual, data)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through writeWord().\n *\n * @this {CPUStatePDP11}\n * @param {number} addrVirtual (input address is 17 bit (I&D))\n * @param {number} data\n */\n writeWordToVirtualChecked(addrVirtual, data)\n {\n if (DEBUGGER && this.dbg) {\n this.dbg.checkMemoryWrite(addrVirtual, 2);\n }\n this.writeWordToVirtual(addrVirtual, data);\n }\n\n /**\n * readWordFromPrevSpace(opCode, access)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @param {number} access (really just PDP11.ACCESS.DSPACE or PDP11.ACCESS.ISPACE)\n * @return {number}\n */\n readWordFromPrevSpace(opCode, access)\n {\n var data;\n var reg = this.dstReg = opCode & PDP11.OPREG.MASK;\n var mode = this.dstMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n if (!mode) {\n if (reg != 6 || ((this.regPSW >> 2) & PDP11.PSW.PMODE) === (this.regPSW & PDP11.PSW.PMODE)) {\n data = this.regsGen[reg];\n } else {\n data = this.regsAltStack[(this.regPSW >> 12) & 3];\n }\n } else {\n var addr = this.getAddrByMode(mode, reg, PDP11.ACCESS.READ_WORD);\n if (!(access & PDP11.ACCESS.DSPACE)) {\n if ((this.regPSW & 0xf000) !== 0xf000) addr &= 0xffff;\n }\n this.pswMode = (this.regPSW >> 12) & 3;\n data = this.readWord(addr | (access & this.addrDSpace));\n this.pswMode = (this.regPSW >> 14) & 3;\n }\n return data;\n }\n\n /**\n * writeWordToPrevSpace(opCode, access, data)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @param {number} access (really just PDP11.ACCESS.DSPACE or PDP11.ACCESS.ISPACE)\n * @param {number} data\n */\n writeWordToPrevSpace(opCode, access, data)\n {\n this.opLast = (this.opLast & 0xffff) | (0x0016 << 16);\n var reg = this.dstReg = opCode & PDP11.OPREG.MASK;\n var mode = this.dstMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n if (!mode) {\n if (reg != 6 || ((this.regPSW >> 2) & PDP11.PSW.PMODE) === (this.regPSW & PDP11.PSW.PMODE)) {\n this.regsGen[reg] = data;\n } else {\n this.regsAltStack[(this.regPSW >> 12) & 3] = data;\n }\n } else {\n var addr = this.getAddrByMode(mode, reg, PDP11.ACCESS.WRITE_WORD);\n if (!(access & PDP11.ACCESS.DSPACE)) addr &= 0xffff;\n /*\n * TODO: Consider replacing the following code with writeWord(), by adding optional pswMode\n * parameters for each of the discrete mapVirtualToPhysical() and setWord() operations, because\n * as it stands, this is the only remaining call to mapVirtualToPhysical() outside of our\n * setMemoryAccess() handlers.\n */\n this.pswMode = (this.regPSW >> 12) & 3;\n addr = this.mapVirtualToPhysical(addr | (access & PDP11.ACCESS.DSPACE), PDP11.ACCESS.WRITE);\n this.pswMode = (this.regPSW >> 14) & 3;\n this.setWord(addr, data);\n }\n }\n\n /**\n * readSrcByte(opCode)\n *\n * WARNING: If the SRC operand is a register, offRegSrc ensures we return a negative register number\n * rather than the register value, because on the PDP-11/20, the final value of the register must be\n * resolved AFTER the DST operand has been decoded and any pre-decrement or post-increment operations\n * affecting the SRC register have been completed. See readSrcWord() for more details.\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @return {number}\n */\n readSrcByte(opCode)\n {\n var result;\n opCode >>= PDP11.SRCMODE.SHIFT;\n var reg = this.srcReg = opCode & PDP11.OPREG.MASK;\n var mode = this.srcMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n if (!mode) {\n result = this.regsGen[reg + this.offRegSrc] & this.maskRegSrcByte;\n } else {\n result = this.getByte(this.getAddr(mode, reg, PDP11.ACCESS.READ_BYTE));\n }\n return result;\n }\n\n /**\n * readSrcWord(opCode)\n *\n * WARNING: If the SRC operand is a register, offRegSrc ensures we return a negative register number\n * rather than the register value, because on the PDP-11/20, the final value of the register must be\n * resolved AFTER the DST operand has been decoded and any pre-decrement or post-increment operations\n * affecting the SRC register have been completed.\n *\n * Here's an example from DEC's \"TRAP TEST\" (MAINDEC-11-D0NA-PB):\n *\n * 007200: 012700 006340 MOV #6340,R0\n * 007204: 010020 MOV R0,(R0)+\n * 007206: 026727 177126 006342 CMP 006340,#6342\n * 007214: 001401 BEQ 007220\n * 007216: 000000 HALT\n *\n * If this function returned the value of R0 for the SRC operand of \"MOV R0,(R0)+\", then the operation\n * would write 6340 to the destination, rather than 6342.\n *\n * Most callers don't need to worry about this, because if they pass the result from readSrcWord() directly\n * to writeDstWord() or updateDstWord(), those functions will take care of converting any negative register\n * number back into the current register value. The exceptions are opcodes that don't modify the DST operand\n * (BIT, BITB, CMP, and CMPB); those opcode handlers must deal with negative register numbers themselves.\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @return {number}\n */\n readSrcWord(opCode)\n {\n var result;\n opCode >>= PDP11.SRCMODE.SHIFT;\n var reg = this.srcReg = opCode & PDP11.OPREG.MASK;\n var mode = this.srcMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n if (!mode) {\n result = this.regsGen[reg + this.offRegSrc];\n } else {\n result = this.getWord(this.getAddr(mode, reg, PDP11.ACCESS.READ_WORD));\n }\n return result;\n }\n\n /**\n * readDstAddr(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @return {number}\n */\n readDstAddr(opCode)\n {\n var reg = this.dstReg = opCode & PDP11.OPREG.MASK;\n var mode = this.dstMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n return this.getAddrByMode(mode, reg, PDP11.ACCESS.VIRT);\n }\n\n /**\n * readDstByte(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @return {number}\n */\n readDstByte(opCode)\n {\n var result;\n var reg = this.dstReg = opCode & PDP11.OPREG.MASK;\n var mode = this.dstMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n if (!mode) {\n result = this.regsGen[reg] & 0xff;\n } else {\n result = this.getByte(this.getAddr(mode, reg, PDP11.ACCESS.READ_BYTE));\n }\n return result;\n }\n\n /**\n * readDstWord(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @return {number}\n */\n readDstWord(opCode)\n {\n var result;\n var reg = this.dstReg = opCode & PDP11.OPREG.MASK;\n var mode = this.dstMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n if (!mode) {\n result = this.regsGen[reg];\n } else {\n result = this.getWord(this.getAddr(mode, reg, PDP11.ACCESS.READ_WORD));\n }\n return result;\n }\n\n /**\n * updateDstByte(opCode, data, fnOp)\n *\n * Used whenever the DST operand (as described by opCode) needs to be read before writing.\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @param {number} data\n * @param {function(number,number)} fnOp\n */\n updateDstByte(opCode, data, fnOp)\n {\n var reg = this.dstReg = opCode & PDP11.OPREG.MASK;\n var mode = this.dstMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n if (!mode) {\n var dst = this.regsGen[reg];\n data = (data < 0? (this.regsGen[-data-1] & 0xff) : data);\n this.regsGen[reg] = (dst & 0xff00) | fnOp.call(this, data, dst & 0xff);\n } else {\n var addr = this.dstAddr = this.getAddr(mode, reg, PDP11.ACCESS.UPDATE_BYTE);\n data = (data < 0? (this.regsGen[-data-1] & 0xff) : data);\n this.setByte(addr, fnOp.call(this, data, this.getByte(addr)));\n if (addr & 1) this.nStepCycles--;\n }\n }\n\n /**\n * updateDstWord(opCode, data, fnOp)\n *\n * Used whenever the DST operand (as described by opCode) needs to be read before writing.\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @param {number} data\n * @param {function(number,number)} fnOp\n */\n updateDstWord(opCode, data, fnOp)\n {\n var reg = this.dstReg = opCode & PDP11.OPREG.MASK;\n var mode = this.dstMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n\n\n\n if (!mode) {\n this.regsGen[reg] = fnOp.call(this, data < 0? this.regsGen[-data-1] : data, this.regsGen[reg]);\n } else {\n var addr = this.getAddr(mode, reg, PDP11.ACCESS.UPDATE_WORD);\n this.setWord(addr, fnOp.call(this, data < 0? this.regsGen[-data-1] : data, this.getWord(addr)));\n }\n }\n\n /**\n * writeDstByte(opCode, data, writeFlags, fnFlags)\n *\n * Used whenever the DST operand (as described by opCode) does NOT need to be read before writing.\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @param {number} data\n * @param {number} writeFlags (WRITE.BYTE aka 0xff, or WRITE.SBYTE aka 0xffff)\n * @param {function(number)} fnFlags\n */\n writeDstByte(opCode, data, writeFlags, fnFlags)\n {\n\n var reg = this.dstReg = opCode & PDP11.OPREG.MASK;\n var mode = this.dstMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n if (!mode) {\n if (!data) {\n /*\n * Potentially worthless optimization (but it looks good on \"paper\").\n */\n this.regsGen[reg] &= ~writeFlags;\n } else {\n /*\n * Potentially worthwhile optimization: skipping the sign-extending data shifts\n * if writeFlags is WRITE.BYTE (but that requires an extra test and separate code paths).\n */\n data = (data < 0? (this.regsGen[-data-1] & 0xff): data);\n this.regsGen[reg] = (this.regsGen[reg] & ~writeFlags) | (((data << 24) >> 24) & writeFlags);\n }\n fnFlags.call(this, data << 8);\n } else {\n var addr = this.getAddr(mode, reg, PDP11.ACCESS.WRITE_BYTE);\n fnFlags.call(this, (data = data < 0? (this.regsGen[-data-1] & 0xff) : data) << 8);\n this.setByte(addr, data);\n if (addr & 1) this.nStepCycles--;\n }\n }\n\n /**\n * writeDstWord(opCode, data, fnFlags)\n *\n * Used whenever the DST operand (as described by opCode) does NOT need to be read before writing.\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @param {number} data\n * @param {function(number)} fnFlags\n */\n writeDstWord(opCode, data, fnFlags)\n {\n var reg = this.dstReg = opCode & PDP11.OPREG.MASK;\n var mode = this.dstMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n\n\n\n if (!mode) {\n this.regsGen[reg] = (data = data < 0? this.regsGen[-data-1] : data);\n fnFlags.call(this, data);\n } else {\n var addr = this.getAddr(mode, reg, PDP11.ACCESS.WRITE_WORD);\n fnFlags.call(this, (data = data < 0? this.regsGen[-data-1] : data));\n this.setWord(addr, data);\n }\n }\n\n /**\n * stepCPU(nMinCycles)\n *\n * NOTE: Single-stepping should not be confused with the Trap flag; single-stepping is a Debugger\n * operation that's completely independent of Trap status. The CPU can go in and out of Trap mode,\n * in and out of h/w interrupt service routines (ISRs), etc, but from the Debugger's perspective,\n * they're all one continuous stream of instructions that can be stepped or run at will. Moreover,\n * stepping vs. running should never change the behavior of the simulation.\n *\n * @this {CPUStatePDP11}\n * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored)\n * @return {number} of cycles executed; 0 indicates a pre-execution condition (ie, an execution breakpoint\n * was hit), -1 indicates a post-execution condition (eg, a read or write breakpoint was hit), and a positive\n * number indicates successful completion of that many cycles (which should always be >= nMinCycles).\n */\n stepCPU(nMinCycles)\n {\n /*\n * The Debugger uses complete to determine if the instruction completed (true) or was interrupted\n * by a breakpoint or some other exceptional condition (false). NOTE: this does NOT include JavaScript\n * exceptions, which stepCPU() expects the caller to catch using its own exception handler.\n *\n * The CPU relies on the use of stopCPU() rather than complete, because the CPU never single-steps\n * (ie, nMinCycles is always some large number), whereas the Debugger does. And conversely, when the\n * Debugger is single-stepping (even when performing multiple single-steps), fRunning is never set,\n * so stopCPU() would have no effect as far as the Debugger is concerned.\n */\n this.flags.complete = true;\n\n /*\n * nDebugCheck is 1 if we want the Debugger's checkInstruction() to check every instruction,\n * -1 if we want it to check just the first instruction, and 0 if there's no need for any checks.\n */\n var nDebugCheck = (DEBUGGER && this.dbg)? (this.dbg.checksEnabled()? 1 : (this.flags.starting? -1 : 0)) : 0;\n\n /*\n * nDebugState is needed only when nDebugCheck is non-zero; it is -1 if this is a single-step, 0 if\n * this is the start of a new run, and 1 if this is a continuation of a previous run. It is used by\n * checkInstruction() to determine if it should skip breakpoint checks and/or HALT instructions (ie,\n * if nDebugState is <= zero).\n */\n var nDebugState = (!nMinCycles)? -1 : (this.flags.starting? 0 : 1);\n this.flags.starting = false; // we've moved beyond \"starting\" and have officially \"started\" now\n\n /*\n * We move the minimum cycle count to nStepCycles (the number of cycles left to step), so that other\n * functions have the ability to force that number to zero (eg, stopCPU()), and thus we don't have to check\n * any other criteria to determine whether we should continue stepping or not.\n */\n this.nBurstCycles = this.nStepCycles = nMinCycles;\n\n /*\n * And finally, move the nDebugCheck state to an OPFLAG bit, so that the loop need check only one variable.\n */\n this.opFlags = (this.opFlags & ~PDP11.OPFLAG.DEBUGGER) | (nDebugCheck? PDP11.OPFLAG.DEBUGGER : 0);\n\n do {\n if (this.opFlags) {\n /*\n * NOTE: We still check DEBUGGER to ensure that this code will be compiled out of existence in\n * non-DEBUGGER builds.\n */\n if (DEBUGGER && (this.opFlags & PDP11.OPFLAG.DEBUGGER)) {\n if (this.dbg.checkInstruction(this.getPC(), nDebugState)) {\n this.stopCPU();\n break;\n }\n if (!++nDebugCheck) this.opFlags &= ~PDP11.OPFLAG.DEBUGGER;\n if (!nDebugState) nDebugState++;\n }\n /*\n * If we're in the IRQ or WAIT state, check for any pending interrupts.\n *\n * NOTE: It's no coincidence that we're checking this BEFORE any pending traps, because in rare\n * cases (including some presented by those pesky \"TRAP TEST\" diagnostics), the process of dispatching\n * an interrupt can trigger a TRAP_SP stack overflow condition, which must be dealt with BEFORE we\n * execute the first instruction of the interrupt handler.\n */\n if ((this.opFlags & (PDP11.OPFLAG.IRQ_MASK | PDP11.OPFLAG.WAIT)) /* && nDebugState >= 0 */) {\n if (this.checkInterrupts()) {\n if ((this.opFlags & PDP11.OPFLAG.DEBUGGER) && this.dbg.checkInstruction(this.getPC(), nDebugState)) {\n this.stopCPU();\n break;\n }\n /*\n * Since an interrupt was just dispatched, altering the normal flow of time and changing\n * the future as we knew it, let's break out immediately if we're single-stepping, so that\n * the Debugger gets to see the first instruction of the interrupt handler. NOTE: This\n * assumes that we've still commented out the nDebugState check above that used to bypass\n * checkInterrupts() when single-stepping.\n */\n if (nDebugState < 0) break;\n }\n }\n /*\n * Next, check for any pending traps (which, as noted above, must be done after checkInterrupts()).\n *\n * I've moved this TRAP_MASK check BEFORE we decode the next instruction instead of immediately AFTER,\n * just in case the last instruction threw an exception that kicked us out before we reached the bottom\n * of the stepCPU() loop.\n */\n if (this.opFlags & PDP11.OPFLAG.TRAP_MASK) {\n if (this.checkTraps()) {\n if ((this.opFlags & PDP11.OPFLAG.DEBUGGER) && this.dbg.checkInstruction(this.getPC(), nDebugState)) {\n this.stopCPU();\n break;\n }\n if (nDebugState < 0) break;\n }\n }\n }\n\n /*\n * Snapshot the TF bit in opFlags, while clearing all other opFlags (except those in PRESERVE);\n * we'll check the TRAP_TF bit in opFlags when we come back around for another opcode.\n */\n this.opFlags = (this.opFlags & PDP11.OPFLAG.PRESERVE) | (this.regPSW & PDP11.PSW.TF);\n\n var opCode = this.getOpcode();\n this.opDecode(opCode);\n\n } while (this.nStepCycles > 0);\n\n return (this.flags.complete? this.nBurstCycles - this.nStepCycles : (this.flags.complete === false? -1 : 0));\n }\n\n /**\n * CPUStatePDP11.init()\n *\n * This function operates on every HTML element of class \"cpu\", extracting the\n * JSON-encoded parameters for the CPUStatePDP11 constructor from the element's \"data-value\"\n * attribute, invoking the constructor (which in turn invokes the CPU constructor)\n * to create a CPUStatePDP11 component, and then binding any associated HTML controls to the\n * new component.\n */\n static init()\n {\n var aeCPUs = Component.getElementsByClass(document, PDP11.APPCLASS, \"cpu\");\n for (var iCPU = 0; iCPU < aeCPUs.length; iCPU++) {\n var eCPU = aeCPUs[iCPU];\n var parmsCPU = Component.getComponentParms(eCPU);\n var cpu = new CPUStatePDP11(parmsCPU);\n Component.bindComponentControls(cpu, eCPU, PDP11.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize every CPU module on the page\n */\nWeb.onInit(CPUStatePDP11.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/cpuops.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * Decoding starts near the bottom of this file, in op1120() and op1140(). Obviously, there are\n * MANY more PDP-11 models than the 11/20 and 11/40, but for the broad model categories that PDPjs\n * supports (ie, MODEL_1120, MODEL_1140, MODEL_1145, and MODEL_1170), the biggest differences are\n * between MODEL_1120 and MODEL_1140, so decoding is divided into those two categories, and all\n * other differences are handled inside the opcode handlers.\n *\n * The basic decoding approach is to dispatch on the top 4 bits of the opcode, and if further\n * decoding is required, the dispatched function will dispatch on the next 4 bits, and so on\n * (although some of the intermediate levels dispatch only on 2 bits, which could also be handled\n * with a switch statement).\n *\n * Eventually, every opcode should end up either in an opXXX() function or opUndefined(). For\n * opcodes that perform a simple read or write operation, the entire operation is handled by\n * the opXXX() function. For opcodes that perform a more extensive read/modify/write operation\n * (also known as an update operation), those opXXX() functions usually rely on a corresponding\n * fnXXX() helper function.\n *\n * For example, opADD() passes the helper function fnADD() to the appropriate update method. This\n * allows the update method to perform the entire read/modify/write operation, because the modify\n * step is performed internally, via the fnXXX() helper function.\n *\n * For the handful of instructions in the 1140 tables that actually exist only on the 11/45 and\n * 11/70 (ie, MFPD, MTPD, and SPL), those opcode handlers perform their own model checks. That's\n * simpler than creating additional tables, and seems fine for instructions that are not commonly\n * executed.\n */\n\n/**\n * fnADD(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src\n * @param {number} dst\n * @return {number} (dst + src)\n */\nPDP11.fnADD = function(src, dst)\n{\n var result = dst + src;\n this.updateAddFlags(result, src, dst);\n return result & 0xffff;\n};\n\n/**\n * fnADDB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src\n * @param {number} dst\n * @return {number} (dst + src)\n */\nPDP11.fnADDB = function(src, dst)\n{\n var result = dst + src;\n this.updateAddFlags(result << 8, src << 8, dst << 8);\n return result & 0xff;\n};\n\n/**\n * fnASL(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (dst << 1)\n */\nPDP11.fnASL = function(src, dst)\n{\n var result = dst << 1;\n this.updateShiftFlags(result);\n return result & 0xffff;\n};\n\n/**\n * fnASLB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (dst << 1)\n */\nPDP11.fnASLB = function(src, dst)\n{\n var result = dst << 1;\n this.updateShiftFlags(result << 8);\n return result & 0xff;\n};\n\n/**\n * fnASR(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (dst >> 1)\n */\nPDP11.fnASR = function(src, dst)\n{\n var result = (dst & 0x8000) | (dst >> 1) | (dst << 16);\n this.updateShiftFlags(result);\n return result & 0xffff;\n};\n\n/**\n * fnASRB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (dst >> 1)\n */\nPDP11.fnASRB = function(src, dst)\n{\n var result = (dst & 0x80) | (dst >> 1) | (dst << 8);\n this.updateShiftFlags(result << 8);\n return result & 0xff;\n};\n\n/**\n * fnBIC(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src\n * @param {number} dst\n * @return {number} (~src & dst)\n */\nPDP11.fnBIC = function(src, dst)\n{\n var result = dst & ~src;\n this.updateNZVFlags(result);\n return result;\n};\n\n/**\n * fnBICB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src\n * @param {number} dst\n * @return {number} (~src & dst)\n */\nPDP11.fnBICB = function(src, dst)\n{\n var result = dst & ~src;\n this.updateNZVFlags(result << 8);\n return result;\n};\n\n/**\n * fnBIS(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src\n * @param {number} dst\n * @return {number} (dst | src)\n */\nPDP11.fnBIS = function(src, dst)\n{\n var result = dst | src;\n this.updateNZVFlags(result);\n return result;\n};\n\n/**\n * fnBISB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src\n * @param {number} dst\n * @return {number} (dst | src)\n */\nPDP11.fnBISB = function(src, dst)\n{\n var result = dst | src;\n this.updateNZVFlags(result << 8);\n return result;\n};\n\n/**\n * fnCOM(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (~dst)\n */\nPDP11.fnCOM = function(src, dst)\n{\n var result = ~dst | 0x10000;\n this.updateAllFlags(result);\n return result & 0xffff;\n};\n\n/**\n * fnCOMB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (~dst)\n */\nPDP11.fnCOMB = function(src, dst)\n{\n var result = ~dst | 0x100;\n this.updateAllFlags(result << 8);\n return result & 0xff;\n};\n\n/**\n * fnDEC(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ie, 1)\n * @param {number} dst\n * @return {number} (dst - src)\n */\nPDP11.fnDEC = function(src, dst)\n{\n var result = dst - src;\n this.updateDecFlags(result, dst);\n return result & 0xffff;\n};\n\n/**\n * fnDECB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ie, 1)\n * @param {number} dst\n * @return {number} (dst - src)\n */\nPDP11.fnDECB = function(src, dst)\n{\n var result = dst - src;\n this.updateDecFlags(result << 8, dst << 8);\n return result & 0xff;\n};\n\n/**\n * fnINC(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ie, 1)\n * @param {number} dst\n * @return {number} (dst + src)\n */\nPDP11.fnINC = function(src, dst)\n{\n var result = dst + src;\n this.updateIncFlags(result, dst);\n return result & 0xffff;\n};\n\n/**\n * fnINCB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ie, 1)\n * @param {number} dst\n * @return {number} (dst + src)\n */\nPDP11.fnINCB = function(src, dst)\n{\n var result = dst + src;\n this.updateIncFlags(result << 8, dst << 8);\n return result & 0xff;\n};\n\n/**\n * fnNEG(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (-dst)\n */\nPDP11.fnNEG = function(src, dst)\n{\n var result = -dst;\n /*\n * If the sign bit of both dst and result are set, the original value must have been 0x8000, triggering overflow.\n */\n this.updateAllFlags(result, result & dst & 0x8000);\n return result & 0xffff;\n};\n\n/**\n * fnNEGB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (-dst)\n */\nPDP11.fnNEGB = function(src, dst)\n{\n var result = -dst;\n /*\n * If the sign bit of both dst and result are set, the original value must have been 0x80, which triggers overflow.\n */\n this.updateAllFlags(result << 8, (result & dst & 0x80) << 8);\n return result & 0xff;\n};\n\n/**\n * fnROL(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (dst >> 1)\n */\nPDP11.fnROL = function(src, dst)\n{\n var result = (dst << 1) | ((this.flagC >> 16) & 1);\n this.updateShiftFlags(result);\n return result & 0xffff;\n};\n\n/**\n * fnROLB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (dst >> 1)\n */\nPDP11.fnROLB = function(src, dst)\n{\n var result = (dst << 1) | ((this.flagC >> 16) & 1);\n this.updateShiftFlags(result << 8);\n return result & 0xff;\n};\n\n/**\n * fnROR(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (dst >> 1)\n */\nPDP11.fnROR = function(src, dst)\n{\n var result = (((this.flagC & 0x10000) | dst) >> 1) | (dst << 16);\n this.updateShiftFlags(result);\n return result & 0xffff;\n};\n\n/**\n * fnRORB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (dst >> 1)\n */\nPDP11.fnRORB = function(src, dst)\n{\n var result = ((((this.flagC & 0x10000) >> 8) | dst) >> 1) | (dst << 8);\n this.updateShiftFlags(result << 8);\n return result & 0xff;\n};\n\n/**\n * fnSUB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src\n * @param {number} dst\n * @return {number} (dst - src)\n */\nPDP11.fnSUB = function(src, dst)\n{\n var result = dst - src;\n this.updateSubFlags(result, src, dst);\n return result & 0xffff;\n};\n\n/**\n * fnSUBB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src\n * @param {number} dst\n * @return {number} (dst - src)\n */\nPDP11.fnSUBB = function(src, dst)\n{\n var result = dst - src;\n this.updateSubFlags(result << 8, src << 8, dst << 8);\n return result & 0xff;\n};\n\n/**\n * fnSWAB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (dst with bytes swapped)\n */\nPDP11.fnSWAB = function(src, dst)\n{\n var result = (dst << 8) | (dst >> 8);\n /*\n * N and Z are based on the low byte of the result, which is the same as the high byte of dst.\n */\n this.updateNZVCFlags(dst & 0xff00);\n return result & 0xffff;\n};\n\n/**\n * fnXOR(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src\n * @param {number} dst\n * @return {number} (dst ^ src)\n */\nPDP11.fnXOR = function(src, dst)\n{\n var result = dst ^ src;\n this.updateNZVFlags(result);\n return result & 0xffff;\n};\n\n/**\n * opADC(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opADC = function(opCode)\n{\n this.updateDstWord(opCode, this.getCF()? 1 : 0, PDP11.fnADD);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opADCB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opADCB = function(opCode)\n{\n this.updateDstByte(opCode, this.getCF()? 1 : 0, PDP11.fnADDB);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opADD(opCode)\n *\n * From the PDP-11/20 Processor HandBook (1971), p. 61:\n *\n * Add src,dst (06SSDD)\n *\n * Operation:\n * (dst) = (src) + (dst)\n *\n * Condition Codes:\n * N: set if result < 0; cleared otherwise\n * Z: set if result = 0; cleared otherwise\n * V: set if there was arithmetic overflow as a result of the operation, that is both operands\n * were of the same sign and the result was of the opposite sign; cleared otherwise\n * C: set if there was a carry from the most significant bit of the result; cleared otherwise\n *\n * Description:\n * Adds the source operand to the destination operand and stores the result at the destination address.\n * The original contents of the destination are lost. The contents of the source are not affected.\n * Two's complement addition is performed.\n *\n * Examples:\n * Add to register: ADD 20,R0\n * Add to memory: ADD R1,XXX\n * Add register to register: ADD R1,R2\n * Add memory to memory: ADD @#17750,XXX\n *\n * XXX is a programmer-defined mnemonic for a memory location.\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opADD = function(opCode)\n{\n this.updateDstWord(opCode, this.readSrcWord(opCode), PDP11.fnADD);\n this.nStepCycles -= (this.dstMode? (8 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 2) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opASH(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opASH = function(opCode)\n{\n var src = this.readDstWord(opCode);\n var reg = (opCode >> 6) & 7;\n var result = this.regsGen[reg];\n if (result & 0x8000) result |= 0xffff0000;\n this.flagC = this.flagV = 0;\n src &= 0x3F;\n if (src & 0x20) {\n src = 64 - src; // shift right\n if (src > 16) src = 16;\n this.flagC = result << (17 - src);\n result = result >> src;\n } else if (src) {\n if (src > 16) { // shift left\n this.flagV = result;\n result = 0;\n } else {\n result = result << src;\n this.flagC = result;\n var dst = (result >> 15) & 0xffff; // check successive sign bits\n if (dst && dst !== 0xffff) this.flagV = 0x8000;\n }\n }\n this.regsGen[reg] = result & 0xffff;\n this.flagN = this.flagZ = result;\n this.nStepCycles -= (this.dstMode? (5 + 1) : (6 + 1)) + src;\n};\n\n/**\n * opASHC(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opASHC = function(opCode)\n{\n var src = this.readDstWord(opCode);\n var reg = (opCode >> 6) & 7;\n var dst = (this.regsGen[reg] << 16) | this.regsGen[reg | 1];\n this.flagC = this.flagV = 0;\n src &= 0x3F;\n if (src & 0x20) {\n src = 64 - src; // shift right\n if (src > 32) src = 32;\n var result = dst >> (src - 1);\n this.flagC = result << 16;\n result >>= 1;\n if (dst & 0x80000000) result |= 0xffffffff << (32 - src);\n } else {\n if (src) { // shift left\n result = dst << (src - 1);\n this.flagC = result >> 15;\n result <<= 1;\n if (src > 32) src = 32;\n dst = dst >> (32 - src);\n if (dst) {\n dst |= (0xffffffff << src) & 0xffffffff;\n if (dst !== 0xffffffff) this.flagV = 0x8000;\n }\n } else {\n result = dst;\n }\n }\n this.regsGen[reg] = (result >> 16) & 0xffff;\n this.regsGen[reg | 1] = result & 0xffff;\n this.flagN = result >> 16;\n this.flagZ = result >> 16 | result;\n this.nStepCycles -= (this.dstMode? (5 + 1) : (6 + 1)) + src;\n};\n\n/**\n * opASL(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opASL = function(opCode)\n{\n this.updateDstWord(opCode, 0, PDP11.fnASL);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opASLB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opASLB = function(opCode)\n{\n this.updateDstByte(opCode, 0, PDP11.fnASLB);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opASR(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opASR = function(opCode)\n{\n this.updateDstWord(opCode, 0, PDP11.fnASR);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opASRB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opASRB = function(opCode)\n{\n this.updateDstByte(opCode, 0, PDP11.fnASRB);\n this.nStepCycles -= (this.dstMode? (8 + 1) + (this.dstAddr & 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opBCC(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBCC = function(opCode)\n{\n this.branch(opCode, !this.getCF());\n};\n\n/**\n * opBCS(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBCS = function(opCode)\n{\n this.branch(opCode, this.getCF());\n};\n\n/**\n * opBIC(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBIC = function(opCode)\n{\n this.updateDstWord(opCode, this.readSrcWord(opCode), PDP11.fnBIC);\n this.nStepCycles -= (this.dstMode? (8 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 2) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opBICB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBICB = function(opCode)\n{\n this.updateDstByte(opCode, this.readSrcByte(opCode), PDP11.fnBICB);\n this.nStepCycles -= (this.dstMode? (8 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 2) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opBIS(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBIS = function(opCode)\n{\n this.updateDstWord(opCode, this.readSrcWord(opCode), PDP11.fnBIS);\n this.nStepCycles -= (this.dstMode? (8 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 2) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opBISB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBISB = function(opCode)\n{\n this.updateDstByte(opCode, this.readSrcByte(opCode), PDP11.fnBISB);\n this.nStepCycles -= (this.dstMode? (8 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 2) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opBIT(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBIT = function(opCode)\n{\n var src = this.readSrcWord(opCode);\n var dst = this.readDstWord(opCode);\n this.updateNZVFlags((src < 0? this.regsGen[-src-1] : src) & dst);\n this.nStepCycles -= (this.dstMode? (3 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 1) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opBITB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBITB = function(opCode)\n{\n var src = this.readSrcByte(opCode);\n var dst = this.readDstByte(opCode);\n this.updateNZVFlags(((src < 0? (this.regsGen[-src-1] & 0xff) : src) & dst) << 8);\n this.nStepCycles -= (this.dstMode? (3 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 1) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opBEQ(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBEQ = function(opCode)\n{\n this.branch(opCode, this.getZF());\n};\n\n/**\n * opBGE(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBGE = function(opCode)\n{\n this.branch(opCode, !this.getNF() == !this.getVF());\n};\n\n/**\n * opBGT(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBGT = function(opCode)\n{\n this.branch(opCode, !this.getZF() && (!this.getNF() == !this.getVF()));\n};\n\n/**\n * opBHI(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBHI = function(opCode)\n{\n this.branch(opCode, !this.getCF() && !this.getZF());\n};\n\n/**\n * opBLE(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBLE = function(opCode)\n{\n this.branch(opCode, this.getZF() || (!this.getNF() != !this.getVF()));\n};\n\n/**\n * opBLOS(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBLOS = function(opCode)\n{\n this.branch(opCode, this.getCF() || this.getZF());\n};\n\n/**\n * opBLT(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBLT = function(opCode)\n{\n this.branch(opCode, !this.getNF() != !this.getVF());\n};\n\n/**\n * opBMI(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBMI = function(opCode)\n{\n this.branch(opCode, this.getNF());\n};\n\n/**\n * opBNE(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBNE = function(opCode)\n{\n this.branch(opCode, !this.getZF());\n};\n\n/**\n * opBPL(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBPL = function(opCode)\n{\n this.branch(opCode, !this.getNF());\n};\n\n/**\n * opBPT(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBPT = function(opCode)\n{\n this.trap(PDP11.TRAP.BPT, 0, PDP11.REASON.OPCODE);\n};\n\n/**\n * opBR(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBR = function(opCode)\n{\n this.branch(opCode, true);\n};\n\n/**\n * opBVC(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBVC = function(opCode)\n{\n this.branch(opCode, !this.getVF());\n};\n\n/**\n * opBVS(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBVS = function(opCode)\n{\n this.branch(opCode, this.getVF());\n};\n\n/**\n * opCLR(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCLR = function(opCode)\n{\n this.writeDstWord(opCode, 0, this.updateAllFlags);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opCLRB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCLRB = function(opCode)\n{\n this.writeDstByte(opCode, 0, PDP11.WRITE.BYTE, this.updateAllFlags);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opCLC(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCLC = function(opCode)\n{\n this.clearCF();\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opCLN(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCLN = function(opCode)\n{\n this.clearNF();\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opCLV(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCLV = function(opCode)\n{\n this.clearVF();\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opCLZ(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCLZ = function(opCode)\n{\n this.clearZF();\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opCLx(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCLx = function(opCode)\n{\n if (opCode & 0x1) this.clearCF();\n if (opCode & 0x2) this.clearVF();\n if (opCode & 0x4) this.clearZF();\n if (opCode & 0x8) this.clearNF();\n /*\n * TODO: Review whether this class of undocumented instructions really has a constant cycle time.\n */\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opCMP(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCMP = function(opCode)\n{\n var src = this.readSrcWord(opCode);\n var dst = this.readDstWord(opCode);\n var result = (src = (src < 0? this.regsGen[-src-1] : src)) - dst;\n /*\n * NOTE: CMP calculates (src - dst) rather than (dst - src), so src and dst updateSubFlags() parms must be reversed.\n */\n this.updateSubFlags(result, dst, src);\n this.nStepCycles -= (this.dstMode? (3 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 1) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opCMPB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCMPB = function(opCode)\n{\n var src = this.readSrcByte(opCode);\n var dst = this.readDstByte(opCode);\n var result = (src = (src < 0? (this.regsGen[-src-1] & 0xff): src) << 8) - (dst <<= 8);\n /*\n * NOTE: CMP calculates (src - dst) rather than (dst - src), so src and dst updateSubFlags() parms must be reversed.\n */\n this.updateSubFlags(result, dst, src);\n this.nStepCycles -= (this.dstMode? (3 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 1) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opCOM(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCOM = function(opCode)\n{\n this.updateDstWord(opCode, 0, PDP11.fnCOM);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opCOMB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCOMB = function(opCode)\n{\n this.updateDstByte(opCode, 0, PDP11.fnCOMB);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opDEC(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opDEC = function(opCode)\n{\n this.updateDstWord(opCode, 1, PDP11.fnDEC);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opDECB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opDECB = function(opCode)\n{\n this.updateDstByte(opCode, 1, PDP11.fnDECB);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opDIV(opCode)\n *\n * The instruction \"DIV SRC,Rn\" determines SRC using the DSTMODE portion of the opcode and Rn using\n * the SRCMODE portion; Rn can only be a register (and it should be an EVEN-numbered register, lest you\n * get unexpected results). The dividend (DST) is then calculated as:\n *\n * DST = (regs[Rn] << 16) | (regs[Rn|1])\n *\n * DST is divided by SRC, and the quotient is stored in regs[Rn] and the remainder in regs[Rn|1].\n *\n * For example:\n *\n * DIV R4,R0\n *\n * where R4 = 006400 and R0,R1 = 000000,015000 will result in R0,R1 = 000002,000000.\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opDIV = function(opCode)\n{\n /*\n * TODO: Review and determine if flag updates can be encapsulated in an updateDivFlags() function.\n */\n var src = this.readDstWord(opCode);\n if (!src) {\n this.flagN = 0; // NZVC\n this.flagZ = 0;\n this.flagV = 0x8000;\n this.flagC = 0x10000; // divide by zero\n this.nStepCycles -= (6 + 1);\n } else {\n var reg = (opCode >> 6) & 7;\n var dst = (this.regsGen[reg] << 16) | this.regsGen[reg | 1];\n this.flagC = this.flagV = 0;\n if (src & 0x8000) src |= ~0xffff;\n var result = ~~(dst / src);\n if (result >= -32768 && result <= 32767) {\n this.regsGen[reg] = result & 0xffff;\n this.regsGen[reg | 1] = (dst - (result * src)) & 0xffff;\n this.flagZ = (result >> 16) | result;\n this.flagN = result >> 16;\n } else {\n this.flagV = 0x8000; // overflow - following are indeterminate\n this.flagZ = (result >> 15) | result; // dodgy\n this.flagN = dst >> 16; // just as dodgy\n if (src === -1 && this.regsGen[reg] === 0xfffe) {\n this.regsGen[reg] = this.regsGen[reg | 1] = 1; // etc\n }\n }\n this.nStepCycles -= (52 + 1); // 52 is the average of the shortest and longest times\n }\n};\n\n/**\n * opEMT(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opEMT = function(opCode)\n{\n this.trap(PDP11.TRAP.EMT, 0, PDP11.REASON.OPCODE);\n this.nStepCycles -= (22 + 3 - 5);\n};\n\n/**\n * opHALT(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opHALT = function(opCode)\n{\n if (this.regPSW & PDP11.PSW.CMODE) {\n this.regErr |= PDP11.CPUERR.BADHALT;\n this.trap(PDP11.TRAP.BUS, 0, PDP11.REASON.HALT);\n } else {\n if (this.panel) {\n /*\n * The PDP-11/20 Handbook (1971) says that HALT does the following:\n *\n * Causes the processor operation to cease. The console is given control of the bus.\n * The console data lights display the contents of RO; the console address lights display\n * the address after the halt instruction. Transfers on the UNIBUS are terminated immediately.\n * The PC points to the next instruction to be executed. Pressing the continue key on the\n * console causes processor operation to resume. No INIT signal is given.\n *\n * However, the PDP-11/70 Handbook (1979) suggests some slight differences:\n *\n * Causes the processor operation to cease. The console is given control of the processor.\n * The data lights display the contents of the PC (which is the address of the HALT instruction\n * plus 2). Transfers on the UNIBUS are terminated immediately. Pressing the continue key on\n * the console causes processor operation to resume.\n *\n * Given that the 11/70 doesn't saying anything about displaying R0 on a HALT, and also given that\n * the 11/70 CPU EXERCISER diagnostic writes a value to the Console Switch/Display Register immediately\n * before HALT'ing, I'm going to assume that updating the data display with R0 is unique to the 11/20.\n *\n * Also, I'm a little suspicious of the 11/70 comment that the \"data lights display the contents of\n * the PC,\" since previous models display the PC on the ADDRESS lights, not the DATA lights. And as\n * I already explained, doing anything to the data lights at this point would undo what the 11/70\n * diagnostics do.\n */\n if (this.model == PDP11.MODEL_1120) {\n this.panel.setData(this.regsGen[0], true);\n }\n }\n if (!this.dbg) {\n /*\n * This will leave the PC exactly where it's supposed to be: at the address of the HALT + 2.\n */\n this.stopCPU();\n } else {\n /*\n * When the Debugger is present, this call will rewind PC by 2 so that the HALT instruction is\n * displayed, making it clear why the processor stopped; the user could also use the \"dh\" command\n * to dump the Debugger's instruction history buffer to see why it stopped, assuming the history\n * buffer is enabled, but that's more work.\n *\n * Because rewinding is not normal CPU behavior, attempting to Run again (or use the Debugger's\n * \"g\" command) would cause an immediate HALT again -- except that checkInstruction() checks for that\n * precise condition, so if the CPU starts on a HALT, checkInstruction() will skip over it.\n */\n this.dbg.stopInstruction();\n }\n }\n this.nStepCycles -= 7;\n};\n\n/**\n * opINC(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opINC = function(opCode)\n{\n this.updateDstWord(opCode, 1, PDP11.fnINC);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opINCB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opINCB = function(opCode)\n{\n this.updateDstByte(opCode, 1, PDP11.fnINCB);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opIOT(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opIOT = function(opCode)\n{\n this.trap(PDP11.TRAP.IOT, 0, PDP11.REASON.OPCODE);\n this.nStepCycles -= (22 + 3 - 5);\n};\n\nPDP11.JMP_CYCLES = [\n 0, 6 + 1, 6 + 1, 8 + 2, 6 + 1, 9 + 2, 7 + 2, 10 + 3\n];\n\n/**\n * opJMP(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opJMP = function(opCode)\n{\n /*\n * Since JMP and JSR opcodes have their own unique timings for the various dst modes, we must snapshot\n * nStepCycles before decoding the mode, and then use that to update nStepCycles.\n */\n this.nSnapCycles = this.nStepCycles;\n this.setPC(this.readDstAddr(opCode));\n this.nStepCycles = this.nSnapCycles - PDP11.JMP_CYCLES[this.dstMode];\n};\n\nPDP11.JSR_CYCLES = [\n 0, 13 + 1, 13 + 1, 15 + 2, 13 + 1, 16 + 2, 14 + 2, 17 + 3\n];\n\n/**\n * opJSR(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opJSR = function(opCode)\n{\n /*\n * Since JMP and JSR opcodes have their own unique timings for the various dst modes, we must\n * snapshot nStepCycles before decoding the mode, and then use that to update nStepCycles.\n */\n this.nSnapCycles = this.nStepCycles;\n var addr = this.readDstAddr(opCode);\n /*\n * As per the WARNING in readSrcWord(), reading the SRC register AFTER decoding the DST operand\n * is entirely appropriate.\n */\n var reg = (opCode >> PDP11.SRCMODE.SHIFT) & PDP11.OPREG.MASK;\n this.pushWord(this.regsGen[reg]);\n this.regsGen[reg] = this.getPC();\n this.setPC(addr);\n this.nStepCycles = this.nSnapCycles - PDP11.JSR_CYCLES[this.dstMode];\n};\n\n/**\n * opMARK(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMARK = function(opCode)\n{\n var addr = (this.getPC() + ((opCode & 0x3F) << 1)) & 0xffff;\n var src = this.readWord(addr | this.addrDSpace);\n this.setPC(this.regsGen[5]);\n this.setSP(addr + 2);\n this.regsGen[5] = src;\n this.nStepCycles -= (6 + 2);\n};\n\n/**\n * opMFPD(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMFPD = function(opCode)\n{\n var data = this.readWordFromPrevSpace(opCode, PDP11.ACCESS.DSPACE);\n this.updateNZVFlags(data);\n this.pushWord(data);\n this.nStepCycles -= (10 + 1);\n};\n\n/**\n * opMFPI(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMFPI = function(opCode)\n{\n var data = this.readWordFromPrevSpace(opCode, PDP11.ACCESS.ISPACE);\n this.updateNZVFlags(data);\n this.pushWord(data);\n this.nStepCycles -= (10 + 1);\n};\n\n/**\n * opMFPS(opCode)\n *\n * 1067XX MFPS - Move Byte From PSW\n *\n * The 8-bit contents of the PS are moved to the effective destination. If destination is mode 0,\n * PS bit 7 is sign extended through the upper byte of the register. The destination operand is treated\n * as a byte address. 11/34A only.\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMFPS = function(opCode)\n{\n PDP11.opUndefined.call(this, opCode);\n};\n\n/**\n * opMFPT(opCode)\n *\n * 000007 MFPT - Move From Processor Type\n *\n * Loads R0 with a value indicating the processor type.\n *\n * R0 Hardware\n * 1 PDP-11/44\n * 3 PDP-11/24 (should be 2)\n * 3 PDP-11/23\n * 4 SBC-11/21\n * 5 All J11 chips including 11/73, 11/83, 11/93\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMFPT = function(opCode)\n{\n PDP11.opUndefined.call(this, opCode);\n};\n\nPDP11.MOV_CYCLES = [\n 2 + 1, 8 + 1, 8 + 1, 11 + 2, 9 + 1, 12 + 2, 10 + 2, 13 + 3,\n 3 + 1, 8 + 1, 8 + 1, 11 + 2, 9 + 1, 12 + 2, 11 + 2, 14 + 3\n];\n\n/**\n * opMOV(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMOV = function(opCode)\n{\n /*\n * Since MOV opcodes have their own unique timings for the various dst modes, we must snapshot\n * nStepCycles after decoding the src mode, and then use that to update nStepCycles.\n */\n var data = this.readSrcWord(opCode);\n this.nSnapCycles = this.nStepCycles;\n this.writeDstWord(opCode, data, this.updateNZVFlags);\n this.nStepCycles = this.nSnapCycles - PDP11.MOV_CYCLES[(this.srcMode? 8 : 0) + this.dstMode] + (this.dstReg == 7 && !this.dstMode? 2 : 0);\n};\n\n/**\n * opMOVB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMOVB = function(opCode)\n{\n var data = this.readSrcByte(opCode);\n this.writeDstByte(opCode, data, PDP11.WRITE.SBYTE, this.updateNZVFlags);\n this.nStepCycles -= (this.dstMode? (8 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 2) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\nPDP11.MTP_CYCLES = [\n 6 + 1, 11 + 2, 11 + 2, 14 + 3, 12 + 2, 15 + 3, 14 + 3, 17 + 4\n];\n\n/**\n * opMTPD(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMTPD = function(opCode)\n{\n /*\n * Since MTPD and MTPI opcodes have their own unique timings for the various dst modes, we must snapshot\n * nStepCycles before decoding the mode, and then use that to update nStepCycles.\n */\n var data = this.popWord();\n this.nSnapCycles = this.nStepCycles;\n this.updateNZVFlags(data);\n this.writeWordToPrevSpace(opCode, PDP11.ACCESS.DSPACE, data);\n this.nStepCycles = this.nSnapCycles - PDP11.MTP_CYCLES[this.dstMode];\n};\n\n/**\n * opMTPI(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMTPI = function(opCode)\n{\n /*\n * Since MTPD and MTPI opcodes have their own unique timings for the various dst modes, we must snapshot\n * nStepCycles before decoding the mode, and then use that to update nStepCycles.\n */\n var data = this.popWord();\n this.nSnapCycles = this.nStepCycles;\n this.updateNZVFlags(data);\n this.writeWordToPrevSpace(opCode, PDP11.ACCESS.ISPACE, data);\n this.nStepCycles = this.nSnapCycles - PDP11.MTP_CYCLES[this.dstMode];\n};\n\n/**\n * opMTPS(opCode)\n *\n * 1064XX MTPS - Move Byte To PSW\n *\n * The 8 bits of the effective operand replace the current contents of the PS <0:7>. The source operand\n * address is treated as a byte address. Note that PS bit 4 cannot be set with this instruction. The\n * src operand remains unchanged. 11/34A only.\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMTPS = function(opCode)\n{\n PDP11.opUndefined.call(this, opCode);\n};\n\n/**\n * opMUL(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMUL = function(opCode)\n{\n var src = this.readDstWord(opCode);\n var reg = (opCode >> 6) & 7;\n var dst = this.regsGen[reg];\n var result = ((src << 16) >> 16) * ((dst << 16) >> 16);\n this.regsGen[reg] = (result >> 16) & 0xffff;\n this.regsGen[reg | 1] = result & 0xffff;\n this.updateMulFlags(result|0);\n this.nStepCycles -= (22 + 1);\n};\n\n/**\n * opNEG(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opNEG = function(opCode)\n{\n this.updateDstWord(opCode, 0, PDP11.fnNEG);\n this.nStepCycles -= (this.dstMode? (10 + 1) : (5 + 1));\n};\n\n/**\n * opNEGB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opNEGB = function(opCode)\n{\n this.updateDstByte(opCode, 0, PDP11.fnNEGB);\n this.nStepCycles -= (this.dstMode? (10 + 1) : (5 + 1));\n};\n\n/**\n * opNOP(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opNOP = function(opCode)\n{\n this.nStepCycles -= (4 + 1); // TODO: Review (this is just a guess based on CLC)\n};\n\n/**\n * opRESET(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opRESET = function(opCode)\n{\n if (!(this.regPSW & PDP11.PSW.CMODE)) {\n this.resetCPU();\n\n if (this.panel) {\n /*\n * The PDP-11/70 XXDP test \"EKBBF0\" reports the following, with PANEL messages on (\"m panel on\"):\n *\n * CNSW.writeWord(177570,000101) @033502\n * CNSW.readWord(177570): 000000 @032114\n * LOOK AT THE CONSOLE LIGHTS\n * THE DATA LIGHTS SHOULD READ 166667\n * THE ADDRESS LIGHTS SHOULD READ CNSW.readWord(177570): 000000 @032150\n * 032236\n * CHANGE SWITCH 7 TO CONTINUE\n * CNSW.readWord(177570): 000000 @032236\n * stopped (31518011 instructions, 358048873 cycles, 58644 ms, 6105465 hz)\n * R0=166667 R1=002362 R2=000000 R3=000000 R4=000000 R5=026642\n * SP=001074 PC=032236 PS=000344 SR=00000000 T0 N0 Z1 V0 C0\n * 032236: 032737 000200 177570 BIT #200,@#177570\n * >> tr\n * CNSW.readWord(177570): 000000 @032236 (cpu halted)\n * R0=166667 R1=002362 R2=000000 R3=000000 R4=000000 R5=026642\n * SP=001074 PC=032244 PS=000344 SR=00000000 T0 N0 Z1 V0 C0\n * 032244: 001773 BEQ 032234 ;cycles=0\n * >> tr\n * R0=166667 R1=002362 R2=000000 R3=000000 R4=000000 R5=026642\n * SP=001074 PC=032234 PS=000344 SR=00000000 T0 N0 Z1 V0 C0\n * 032234: 000005 RESET ;cycles=5\n *\n * It's a little hard to see why the DATA lights should read 166667, since the PANEL messages indicate\n * that the last CNSW.writeWord(177570) was for 000101, not 166667. So I'm guessing that the RESET\n * instruction is supposed to propagate R0 to the console's DISPLAY register.\n *\n * This is similar to what we do for the HALT instruction (but only if this.model == PDP11.MODEL_1120).\n * These Console features do not seem to be very well documented, assuming they exist.\n *\n * UPDATE: This behavior appears to be confirmed by remarks in the PDP-11/20 Processor Handbook (1971),\n * p. 141:\n *\n * HALT - displays processor register R0 when bus control is transferred to console during a HALT\n * instruction.\n *\n * RESET - displays register R0 for during [duration?] of RESET (70 msec).\n *\n * I haven't found similar remarks in the PDP-11/70 Processor Handbooks, so I'm not sure if that's an\n * oversight or if 11/70 panels are slightly different in this regard. It's also not clear what they meant\n * by \"for duration of RESET\". Is something supposed to happen to the DATA lights after the RESET is done?\n */\n this.panel.setData(this.regsGen[0], true);\n }\n }\n this.nStepCycles -= 667; // TODO: Review (but it's definitely a big number)\n};\n\n/**\n * opROL(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opROL = function(opCode)\n{\n this.updateDstWord(opCode, 0, PDP11.fnROL);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opROLB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opROLB = function(opCode)\n{\n this.updateDstByte(opCode, 0, PDP11.fnROLB);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opROR(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opROR = function(opCode)\n{\n this.updateDstWord(opCode, 0, PDP11.fnROR);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opRORB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opRORB = function(opCode)\n{\n this.updateDstByte(opCode, 0, PDP11.fnRORB);\n this.nStepCycles -= (this.dstMode? (8 + 1) + (this.dstAddr & 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opRTI(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opRTI = function(opCode)\n{\n this.trapReturn();\n /*\n * Unlike RTT, RTI permits an immediate trace, which we resolve by propagating PSW.TF to OPFLAG.TRAP_TF\n * (which, as written below, requires that both flags have the same bit value; see defines.js).\n *\n * NOTE: This RTI trace behavior is NEW for machines that have both RTI and RTT. Early models didn't have RTT,\n * so the old RTI behaved exactly like the new RTT. Which is why the 11/20 jump table below calls opRTT() instead\n * of opRTI() for RTI.\n */\n this.opFlags |= (this.regPSW & PDP11.PSW.TF);\n this.nStepCycles -= (10 + 3);\n};\n\n/**\n * opRTS(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opRTS = function(opCode)\n{\n if (opCode & 0x08) {\n PDP11.opUndefined.call(this, opCode);\n return;\n }\n var src = this.popWord();\n var reg = opCode & PDP11.OPREG.MASK;\n /*\n * When the popular \"RTS PC\" form is used, we might as well eliminate the useless setting of PC...\n */\n if (reg == PDP11.REG.PC) {\n this.setPC(src);\n } else {\n this.setPC(this.regsGen[reg]);\n this.regsGen[reg] = src;\n }\n this.nStepCycles -= (7 + 2);\n};\n\n/**\n * opRTT(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opRTT = function(opCode)\n{\n this.trapReturn();\n this.nStepCycles -= (10 + 3);\n};\n\n/**\n * opSBC(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSBC = function(opCode)\n{\n this.updateDstWord(opCode, this.getCF()? 1 : 0, PDP11.fnSUB);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opSBCB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSBCB = function(opCode)\n{\n this.updateDstByte(opCode, this.getCF()? 1 : 0, PDP11.fnSUBB);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opSEC(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSEC = function(opCode)\n{\n this.setCF();\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opSEN(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSEN = function(opCode)\n{\n this.setNF();\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opSEV(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSEV = function(opCode)\n{\n this.setVF();\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opSEZ(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSEZ = function(opCode)\n{\n this.setZF();\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opSEx(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSEx = function(opCode)\n{\n if (opCode & 0x1) this.setCF();\n if (opCode & 0x2) this.setVF();\n if (opCode & 0x4) this.setZF();\n if (opCode & 0x8) this.setNF();\n /*\n * TODO: Review whether this class of undocumented instructions really has a constant cycle time.\n */\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opSOB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode (077Rnn)\n */\nPDP11.opSOB = function(opCode)\n{\n var reg = (opCode & PDP11.SRCMODE.REG) >> PDP11.SRCMODE.SHIFT;\n if ((this.regsGen[reg] = ((this.regsGen[reg] - 1) & 0xffff))) {\n this.setPC(this.getPC() - ((opCode & PDP11.DSTMODE.MASK) << 1));\n this.nStepCycles += 1; // unlike normal branches, taking this branch is actually 1 cycle faster\n }\n this.nStepCycles -= (5 + 1);\n};\n\n/**\n * opSPL(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSPL = function(opCode)\n{\n if (!(opCode & 0x08) || this.model < PDP11.MODEL_1145) {\n PDP11.opUndefined.call(this, opCode);\n return;\n }\n if (!(this.regPSW & PDP11.PSW.CMODE)) {\n this.regPSW = (this.regPSW & ~PDP11.PSW.PRI) | ((opCode & 0x7) << PDP11.PSW.SHIFT.PRI);\n this.opFlags |= PDP11.OPFLAG.IRQ_DELAY;\n this.opFlags &= ~PDP11.OPFLAG.IRQ;\n }\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opSUB(opCode)\n *\n * From the PDP-11/20 Processor HandBook (1971), p. 62:\n *\n * Subtract src,dst (16SSDD)\n *\n * Operation:\n * (dst) = (dst) - (src) [in detail, (dst) + ~(src) + 1 (dst)]\n *\n * Condition Codes:\n * N: set if result < 0; cleared otherwise\n * Z: set if result = 0; cleared otherwise\n * V: set if there was arithmetic overflow as a result of the operation, that is if operands were of\n * opposite signs and the sign of the source was the same as the sign of the result; cleared otherwise\n * C: cleared if there was a carry from the most significant bit of the result; set otherwise\n *\n * Description:\n * Subtracts the source operand from the destination operand and leaves the result at the destination address.\n * The orignial [sic] contents of the destination are lost. The contents of the source are not affected.\n * In double-precision arithmetic the C-bit, when set, indicates a \"borrow\".\n *\n * Example:\n * SUB R1,R2\n *\n * BEFORE AFTER\n * (R1) = 011111 (R2) = 012345\n * (R1) = 011111 (R2) = 001234\n *\n * NZVC NZVC\n * 1111 0001\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSUB = function(opCode)\n{\n this.updateDstWord(opCode, this.readSrcWord(opCode), PDP11.fnSUB);\n this.nStepCycles -= (this.dstMode? (8 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 2) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opSWAB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSWAB = function(opCode)\n{\n this.updateDstWord(opCode, 0, PDP11.fnSWAB);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opSXT(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSXT = function(opCode)\n{\n this.writeDstWord(opCode, this.getNF()? 0xffff : 0, this.updateNZVFlags);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opTRAP(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opTRAP = function(opCode)\n{\n this.trap(PDP11.TRAP.TRAP, 0, PDP11.REASON.OPCODE);\n};\n\n/**\n * opTST(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opTST = function(opCode)\n{\n var result = this.readDstWord(opCode);\n\n this.updateAllFlags(result);\n this.nStepCycles -= (this.dstMode? (3 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opTSTB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opTSTB = function(opCode)\n{\n var result = this.readDstByte(opCode);\n\n this.updateAllFlags(result << 8);\n this.nStepCycles -= (this.dstMode? (3 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opWAIT(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opWAIT = function(opCode)\n{\n /*\n * The original PDP-11 emulation code would actually stop emulating instructions now, relying on assorted\n * setTimeout() callbacks, setInterval() callbacks, device XHR (XMLHttpRequest) callbacks, etc, to eventually\n * call interrupt(), which would then transition the CPU out of its \"wait\" state and kickstart emulate() again.\n *\n * That approach isn't compatible with PCjs emulators, which prefer to rely on the simulated CPU clock to\n * drive all simulated device updates. This means components should call the CPU's setTimer() function, which\n * invokes the provided callback when the number of CPU cycles that correspond to the requested number of\n * milliseconds have elapsed. This also gives us the ability to scale device response times as needed if the\n * user decides to crank up CPU speed, and to freeze them along with the CPU whenever the user halts the machine.\n *\n * However, the PCjs approach requires the CPU to continue running. One simple solution to this dilemma:\n *\n * 1) opWAIT() sets a new opFlags bit (OPFLAG.WAIT)\n * 2) Rewind the PC back to the WAIT instruction\n * 3) Whenever stepCPU() detects OPFLAG.WAIT, call checkInterrupts()\n * 4) If checkInterrupts() detects an interrupt, advance PC past the WAIT and then dispatch the interrupt\n *\n * Technically, the PC is already exactly where it's supposed to be, so why are we wasting time with steps\n * 2 and 4? It's largely for the Debugger's sake, so that as long as execution is \"blocked\" by a WAIT, that's\n * what you'll see in the Debugger. I could make those steps conditioned on the presence of the Debugger,\n * but I feel it's better to keep all code paths the same.\n *\n * NOTE: It's almost always a bad idea to add more checks to the inner stepCPU() loop, because every additional\n * check can have a measurable (negative) impact on performance. Which is why it's important to use opFlags bits\n * whenever possible, since we can test for multiple (up to 32) exceptional conditions with a single check.\n *\n * We also used to update the machine's display(s) whenever transitioning to the WAIT state. However, that\n * caused this instruction to generate enormous overhead, and it's no longer necessary, since we now rely on\n * a timer (the PDP-11's own KW11 60Hz Line Clock timer, to be precise) to generate periodic display updates.\n *\n * if (!(this.opFlags & PDP11.OPFLAG.WAIT) && this.cmp) this.cmp.updateDisplays();\n *\n * Finally, it's been noted several places online that the WAIT instruction puts the contents of R0 into the\n * Front Panel's \"DATA PATH\" (and possibly even directly into the \"DISPLAY REGISTER\", making the DATASEL switch\n * setting irrelevant). I can't find any supporting DEC documentation regarding this, but for now, we'll go\n * with popular lore and propagate R0 to the panel's \"active\" data register.\n */\n if (this.panel) {\n this.panel.setAddr(this.regsGen[7], true);\n this.panel.setData(this.regsGen[0], true);\n }\n this.opFlags |= PDP11.OPFLAG.WAIT;\n this.advancePC(-2);\n this.nStepCycles -= 3;\n};\n\n/**\n * opXOR(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opXOR = function(opCode)\n{\n var reg = (opCode >> PDP11.SRCMODE.SHIFT) & PDP11.OPREG.MASK;\n this.updateDstWord(opCode, this.regsGen[reg + this.offRegSrc], PDP11.fnXOR);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opUndefined(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opUndefined = function(opCode)\n{\n if (DEBUGGER && this.dbg) {\n if (this.dbg.undefinedInstruction(opCode)) return;\n }\n this.trap(PDP11.TRAP.RESERVED, 0, PDP11.REASON.OPCODE);\n};\n\n/**\n * op1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op1120 = function(opCode)\n{\n PDP11.aOpXnnn_1120[opCode >> 12].call(this, opCode);\n};\n\n/**\n * op0Xnn_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op0Xnn_1120 = function(opCode)\n{\n PDP11.aOp0Xnn_1120[(opCode >> 8) & 0xf].call(this, opCode);\n};\n\n/**\n * op0AXn_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op0AXn_1120 = function(opCode)\n{\n PDP11.aOp0AXn_1120[(opCode >> 6) & 0x3].call(this, opCode);\n};\n\n/**\n * op0BXn_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op0BXn_1120 = function(opCode)\n{\n PDP11.aOp0BXn_1120[(opCode >> 6) & 0x3].call(this, opCode);\n};\n\n/**\n * op0CXn_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op0CXn_1120 = function(opCode)\n{\n PDP11.aOp0CXn_1120[(opCode >> 6) & 0x3].call(this, opCode);\n};\n\n/**\n * op00Xn_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op00Xn_1120 = function(opCode)\n{\n PDP11.aOp00Xn_1120[(opCode >> 4) & 0xf].call(this, opCode);\n};\n\n/**\n * op00AX_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op00AX_1120 = function(opCode)\n{\n PDP11.aOp00AX_1120[opCode & 0xf].call(this, opCode);\n};\n\n/**\n * op00BX_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op00BX_1120 = function(opCode)\n{\n PDP11.aOp00BX_1120[opCode & 0xf].call(this, opCode);\n};\n\n/**\n * op000X_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op000X_1120 = function(opCode)\n{\n PDP11.aOp000X_1120[opCode & 0xf].call(this, opCode);\n};\n\n/**\n * op8Xnn_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op8Xnn_1120 = function(opCode)\n{\n PDP11.aOp8Xnn_1120[(opCode >> 8) & 0xf].call(this, opCode);\n};\n\n/**\n * op8AXn_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op8AXn_1120 = function(opCode)\n{\n PDP11.aOp8AXn_1120[(opCode >> 6) & 0x3].call(this, opCode);\n};\n\n/**\n * op8BXn_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op8BXn_1120 = function(opCode)\n{\n PDP11.aOp8BXn_1120[(opCode >> 6) & 0x3].call(this, opCode);\n};\n\n/**\n * op8CXn_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op8CXn_1120 = function(opCode)\n{\n PDP11.aOp8CXn_1120[(opCode >> 6) & 0x3].call(this, opCode);\n};\n\nPDP11.aOpXnnn_1120 = [\n PDP11.op0Xnn_1120, // 0x0nnn\n PDP11.opMOV, // 0x1nnn 01SSDD 11/20+ 2.3\n PDP11.opCMP, // 0x2nnn 02SSDD 11/20+ 2.3*\n PDP11.opBIT, // 0x3nnn 03SSDD 11/20+ 2.9*\n PDP11.opBIC, // 0x4nnn 04SSDD 11/20+ 2.9\n PDP11.opBIS, // 0x5nnn 05SSDD 11/20+ 2.3\n PDP11.opADD, // 0x6nnn 06SSDD 11/20+ 2.3\n PDP11.opUndefined, // 0x7nnn\n PDP11.op8Xnn_1120, // 0x8nnn\n PDP11.opMOVB, // 0x9nnn 11SSDD 11/20+ 2.3\n PDP11.opCMPB, // 0xAnnn 12SSDD 11/20+ 2.3\n PDP11.opBITB, // 0xBnnn 13SSDD 11/20+ 2.9\n PDP11.opBICB, // 0xCnnn 14SSDD 11/20+ 2.9\n PDP11.opBISB, // 0xDnnn 15SSDD 11/20+ 2.3\n PDP11.opSUB, // 0xEnnn 16SSDD 11/20+ 2.3\n PDP11.opUndefined // 0xFnnn\n];\n\nPDP11.aOp0Xnn_1120 = [\n PDP11.op00Xn_1120, // 0x00nn\n PDP11.opBR, // 0x01nn 0004XX 11/20+ 2.6\n PDP11.opBNE, // 0x02nn 0010XX 11/20+ 2.6**\n PDP11.opBEQ, // 0x03nn 0014XX 11/20+ 2.6**\n PDP11.opBGE, // 0x04nn 0020XX 11/20+ 2.6**\n PDP11.opBLT, // 0x05nn 0024XX 11/20+ 2.6**\n PDP11.opBGT, // 0x06nn 0030XX 11/20+ 2.6**\n PDP11.opBLE, // 0x07nn 0034XX 11/20+ 2.6**\n PDP11.opJSR, // 0x08nn 004RDD 11/20+ 4.4\n PDP11.opJSR, // 0x09nn 004RDD 11/20+ 4.4\n PDP11.op0AXn_1120, // 0x0Ann\n PDP11.op0BXn_1120, // 0x0Bnn\n PDP11.op0CXn_1120, // 0x0Cnn\n PDP11.opUndefined, // 0x0Dnn\n PDP11.opUndefined, // 0x0Enn\n PDP11.opUndefined // 0x0Fnn\n];\n\nPDP11.aOp0AXn_1120 = [\n PDP11.opCLR, // 0x0A0n 0050DD 11/20+ 2.3\n PDP11.opCOM, // 0x0A4n 0051DD 11/20+ 2.3\n PDP11.opINC, // 0x0A8n 0052DD 11/20+ 2.3\n PDP11.opDEC // 0x0ACn 0053DD 11/20+ 2.3\n];\n\nPDP11.aOp0BXn_1120 = [\n PDP11.opNEG, // 0x0B0n 0054DD 11/20+ 2.3\n PDP11.opADC, // 0x0B4n 0055DD 11/20+ 2.3\n PDP11.opSBC, // 0x0B8n 0056DD 11/20+ 2.3\n PDP11.opTST // 0x0BCn 0057DD 11/20+ 2.3*\n];\n\nPDP11.aOp0CXn_1120 = [\n PDP11.opROR, // 0x0C0n 0060DD 11/20+ 2.3*\n PDP11.opROL, // 0x0C4n 0061DD 11/20+ 2.3*\n PDP11.opASR, // 0x0C8n 0062DD 11/20+ 2.3*\n PDP11.opASL // 0x0CCn 0063DD 11/20+ 2.3*\n];\n\nPDP11.aOp00Xn_1120 = [\n PDP11.op000X_1120, // 0x000n 000000-000017\n PDP11.opUndefined, // 0x001n 000020-000037\n PDP11.opUndefined, // 0x002n 000040-000057\n PDP11.opUndefined, // 0x003n 000060-000077\n PDP11.opJMP, // 0x004n 0001DD 11/20+ 1.2\n PDP11.opJMP, // 0x005n 0001DD 11/20+ 1.2\n PDP11.opJMP, // 0x006n 0001DD 11/20+ 1.2\n PDP11.opJMP, // 0x007n 0001DD 11/20+ 1.2\n PDP11.opRTS, // 0x008n 00020R 11/20+ 3.5 (opRTS() will also confirm that bit 3 is clear)\n PDP11.opUndefined, // 0x009n 00023N\n PDP11.op00AX_1120, // 0x00An 000240-000257\n PDP11.op00BX_1120, // 0x00Bn 000260-000277\n PDP11.opSWAB, // 0x00Cn 0003DD 11/20+ 2.3\n PDP11.opSWAB, // 0x00Dn 0003DD 11/20+ 2.3\n PDP11.opSWAB, // 0x00En 0003DD 11/20+ 2.3\n PDP11.opSWAB // 0x00Fn 0003DD 11/20+ 2.3\n];\n\nPDP11.aOp000X_1120 = [\n PDP11.opHALT, // 0x0000 000000 11/20+ 1.8\n PDP11.opWAIT, // 0x0001 000001 11/20+ 1.8\n PDP11.opRTT, // 0x0002 000002 11/20+ 4.8 (this is really RTI, but on the 11/20, it behaves like RTT)\n PDP11.opBPT, // 0x0003\n PDP11.opIOT, // 0x0004 000004 11/20+ 9.3\n PDP11.opRESET, // 0x0005 000005 11/20+ 20ms\n PDP11.opUndefined, // 0x0006\n PDP11.opUndefined, // 0x0007\n PDP11.opUndefined, // 0x0008\n PDP11.opUndefined, // 0x0009\n PDP11.opUndefined, // 0x000A\n PDP11.opUndefined, // 0x000B\n PDP11.opUndefined, // 0x000C\n PDP11.opUndefined, // 0x000D\n PDP11.opUndefined, // 0x000E\n PDP11.opUndefined // 0x000F\n];\n\nPDP11.aOp00AX_1120 = [\n PDP11.opNOP, // 0x00A0 000240 11/20+ 1.5\n PDP11.opCLC, // 0x00A1 000241 11/20+ 1.5\n PDP11.opCLV, // 0x00A2 000242 11/20+ 1.5\n PDP11.opCLx, // 0x00A3 000243 11/20+ 1.5\n PDP11.opCLZ, // 0x00A4 000244 11/20+ 1.5\n PDP11.opCLx, // 0x00A5 000245 11/20+ 1.5\n PDP11.opCLx, // 0x00A6 000246 11/20+ 1.5\n PDP11.opCLx, // 0x00A7 000247 11/20+ 1.5\n PDP11.opCLN, // 0x00A8 000250 11/20+ 1.5\n PDP11.opCLx, // 0x00A9 000251 11/20+ 1.5\n PDP11.opCLx, // 0x00AA 000252 11/20+ 1.5\n PDP11.opCLx, // 0x00AB 000253 11/20+ 1.5\n PDP11.opCLx, // 0x00AC 000254 11/20+ 1.5\n PDP11.opCLx, // 0x00AD 000255 11/20+ 1.5\n PDP11.opCLx, // 0x00AE 000256 11/20+ 1.5\n PDP11.opCLx // 0x00AF 000257 11/20+ 1.5\n];\n\nPDP11.aOp00BX_1120 = [\n PDP11.opNOP, // 0x00B0 000260 11/20+ 1.5\n PDP11.opSEC, // 0x00B1 000261 11/20+ 1.5\n PDP11.opSEV, // 0x00B2 000262 11/20+ 1.5\n PDP11.opSEx, // 0x00B3 000263 11/20+ 1.5\n PDP11.opSEZ, // 0x00B4 000264 11/20+ 1.5\n PDP11.opSEx, // 0x00B5 000265 11/20+ 1.5\n PDP11.opSEx, // 0x00B6 000266 11/20+ 1.5\n PDP11.opSEx, // 0x00B7 000267 11/20+ 1.5\n PDP11.opSEN, // 0x00B8 000270 11/20+ 1.5\n PDP11.opSEx, // 0x00B9 000271 11/20+ 1.5\n PDP11.opSEx, // 0x00BA 000272 11/20+ 1.5\n PDP11.opSEx, // 0x00BB 000273 11/20+ 1.5\n PDP11.opSEx, // 0x00BC 000274 11/20+ 1.5\n PDP11.opSEx, // 0x00BD 000275 11/20+ 1.5\n PDP11.opSEx, // 0x00BE 000276 11/20+ 1.5\n PDP11.opSEx // 0x00BF 000277 11/20+ 1.5\n];\n\nPDP11.aOp8Xnn_1120 = [\n PDP11.opBPL, // 0x80nn 1000XX 11/20+ 2.6**\n PDP11.opBMI, // 0x81nn 1004XX 11/20+ 2.6**\n PDP11.opBHI, // 0x82nn 1010XX 11/20+ 2.6**\n PDP11.opBLOS, // 0x83nn 1014XX 11/20+ 2.6**\n PDP11.opBVC, // 0x84nn 1020XX 11/20+ 2.6**\n PDP11.opBVS, // 0x85nn 1024XX 11/20+ 2.6**\n PDP11.opBCC, // 0x86nn 1030XX 11/20+ 2.6**\n PDP11.opBCS, // 0x87nn 1034XX 11/20+ 2.6**\n PDP11.opEMT, // 0x88nn 104000-104377 11/20+ 9.3\n PDP11.opTRAP, // 0x89nn 104400-104777 11/20+ 9.3\n PDP11.op8AXn_1120, // 0x8Ann\n PDP11.op8BXn_1120, // 0x8Bnn\n PDP11.op8CXn_1120, // 0x8Cnn\n PDP11.opUndefined, // 0x8Dnn\n PDP11.opUndefined, // 0x8Enn\n PDP11.opUndefined // 0x8Fnn\n];\n\nPDP11.aOp8AXn_1120 = [\n PDP11.opCLRB, // 0x8A0n 1050DD 11/20+ 2.3\n PDP11.opCOMB, // 0x8A4n 1051DD 11/20+ 2.3\n PDP11.opINCB, // 0x8A8n 1052DD 11/20+ 2.3\n PDP11.opDECB // 0x8ACn 1053DD 11/20+ 2.3\n];\n\nPDP11.aOp8BXn_1120 = [\n PDP11.opNEGB, // 0x8B0n 1054DD 11/20+ 2.3\n PDP11.opADCB, // 0x8B4n 1055DD 11/20+ 2.3\n PDP11.opSBCB, // 0x8B8n 1056DD 11/20+ 2.3\n PDP11.opTSTB // 0x8BCn 1057DD 11/20+ 2.3*\n];\n\nPDP11.aOp8CXn_1120 = [\n PDP11.opRORB, // 0x8C0n 1060DD 11/20+ 2.3*\n PDP11.opROLB, // 0x8C4n 1061DD 11/20+ 2.3*\n PDP11.opASRB, // 0x8C8n 1062DD 11/20+ 2.3*\n PDP11.opASLB // 0x8CCn 1063DD 11/20+ 2.3*\n];\n\n/**\n * op1140(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op1140 = function(opCode)\n{\n PDP11.aOpXnnn_1140[opCode >> 12].call(this, opCode);\n};\n\n/**\n * op0Xnn_1140(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op0Xnn_1140 = function(opCode)\n{\n PDP11.aOp0Xnn_1140[(opCode >> 8) & 0xf].call(this, opCode);\n};\n\n/**\n * op0DXn_1140(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op0DXn_1140 = function(opCode)\n{\n PDP11.aOp0DXn_1140[(opCode >> 6) & 0x3].call(this, opCode);\n};\n\n/**\n * op00Xn_1140(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op00Xn_1140 = function(opCode)\n{\n PDP11.aOp00Xn_1140[(opCode >> 4) & 0xf].call(this, opCode);\n};\n\n/**\n * op000X_1140(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op000X_1140 = function(opCode)\n{\n PDP11.aOp000X_1140[opCode & 0xf].call(this, opCode);\n};\n\n/**\n * op7Xnn_1140(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op7Xnn_1140 = function(opCode)\n{\n PDP11.aOp7Xnn_1140[(opCode >> 8) & 0xf].call(this, opCode);\n};\n\n/**\n * op8Xnn_1140(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op8Xnn_1140 = function(opCode)\n{\n PDP11.aOp8Xnn_1140[(opCode >> 8) & 0xf].call(this, opCode);\n};\n\n/**\n * op8DXn_1140(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op8DXn_1140 = function(opCode)\n{\n if (this.model < PDP11.MODEL_1145) {\n PDP11.opUndefined.call(this, opCode);\n return;\n }\n PDP11.aOp8DXn_1140[(opCode >> 6) & 0x3].call(this, opCode);\n};\n\nPDP11.aOpXnnn_1140 = [\n PDP11.op0Xnn_1140, // 0x0nnn\n PDP11.opMOV, // 0x1nnn 01SSDD 11/20+ 2.3\n PDP11.opCMP, // 0x2nnn 02SSDD 11/20+ 2.3*\n PDP11.opBIT, // 0x3nnn 03SSDD 11/20+ 2.9*\n PDP11.opBIC, // 0x4nnn 04SSDD 11/20+ 2.9\n PDP11.opBIS, // 0x5nnn 05SSDD 11/20+ 2.3\n PDP11.opADD, // 0x6nnn 06SSDD 11/20+ 2.3\n PDP11.op7Xnn_1140, // 0x7nnn\n PDP11.op8Xnn_1140, // 0x8nnn\n PDP11.opMOVB, // 0x9nnn 11SSDD 11/20+ 2.3\n PDP11.opCMPB, // 0xAnnn 12SSDD 11/20+ 2.3\n PDP11.opBITB, // 0xBnnn 13SSDD 11/20+ 2.9\n PDP11.opBICB, // 0xCnnn 14SSDD 11/20+ 2.9\n PDP11.opBISB, // 0xDnnn 15SSDD 11/20+ 2.3\n PDP11.opSUB, // 0xEnnn 16SSDD 11/20+ 2.3\n PDP11.opUndefined // 0xFnnn\n];\n\nPDP11.aOp0Xnn_1140 = [\n PDP11.op00Xn_1140, // 0x00nn\n PDP11.opBR, // 0x01nn 0004XX 11/20+ 2.6\n PDP11.opBNE, // 0x02nn 0010XX 11/20+ 2.6**\n PDP11.opBEQ, // 0x03nn 0014XX 11/20+ 2.6**\n PDP11.opBGE, // 0x04nn 0020XX 11/20+ 2.6**\n PDP11.opBLT, // 0x05nn 0024XX 11/20+ 2.6**\n PDP11.opBGT, // 0x06nn 0030XX 11/20+ 2.6**\n PDP11.opBLE, // 0x07nn 0034XX 11/20+ 2.6**\n PDP11.opJSR, // 0x08nn 004RDD 11/20+ 4.4\n PDP11.opJSR, // 0x09nn 004RDD 11/20+ 4.4\n PDP11.op0AXn_1120, // 0x0Ann\n PDP11.op0BXn_1120, // 0x0Bnn\n PDP11.op0CXn_1120, // 0x0Cnn\n PDP11.op0DXn_1140, // 0x0Dnn\n PDP11.opUndefined, // 0x0Enn\n PDP11.opUndefined // 0x0Fnn\n];\n\nPDP11.aOp0DXn_1140 = [\n PDP11.opMARK, // 0x0D0n 11/40+ LEIS\n PDP11.opMFPI, // 0x0D4n 11/40+\n PDP11.opMTPI, // 0x0D8n 11/40+\n PDP11.opSXT // 0x0DCn 11/40+ LEIS\n];\n\nPDP11.aOp00Xn_1140 = [\n PDP11.op000X_1140, // 0x000n 000000-000017\n PDP11.opUndefined, // 0x001n 000020-000037\n PDP11.opUndefined, // 0x002n 000040-000057\n PDP11.opUndefined, // 0x003n 000060-000077\n PDP11.opJMP, // 0x004n 0001DD 11/20+ 1.2\n PDP11.opJMP, // 0x005n 0001DD 11/20+ 1.2\n PDP11.opJMP, // 0x006n 0001DD 11/20+ 1.2\n PDP11.opJMP, // 0x007n 0001DD 11/20+ 1.2\n PDP11.opRTS, // 0x008n 00020R 11/20+ 3.5 (opRTS() will also confirm that bit 3 is clear)\n PDP11.opSPL, // 0x009n 00023N 11/45+ (opSPL() will also confirm that bit 3 is set)\n PDP11.op00AX_1120, // 0x00An 000240-000257\n PDP11.op00BX_1120, // 0x00Bn 000260-000277\n PDP11.opSWAB, // 0x00Cn 0003DD 11/20+ 2.3\n PDP11.opSWAB, // 0x00Dn 0003DD 11/20+ 2.3\n PDP11.opSWAB, // 0x00En 0003DD 11/20+ 2.3\n PDP11.opSWAB // 0x00Fn 0003DD 11/20+ 2.3\n];\n\nPDP11.aOp000X_1140 = [\n PDP11.opHALT, // 0x0000 000000 11/20+ 1.8\n PDP11.opWAIT, // 0x0001 000001 11/20+ 1.8\n PDP11.opRTI, // 0x0002 000002 11/20+ 4.8\n PDP11.opBPT, // 0x0003 000003\n PDP11.opIOT, // 0x0004 000004 11/20+ 9.3\n PDP11.opRESET, // 0x0005 000005 11/20+ 20ms\n PDP11.opRTT, // 0x0006 000006 11/40+ LEIS\n PDP11.opMFPT, // 0x0007 000007 11/44+\n PDP11.opUndefined, // 0x0008\n PDP11.opUndefined, // 0x0009\n PDP11.opUndefined, // 0x000A\n PDP11.opUndefined, // 0x000B\n PDP11.opUndefined, // 0x000C\n PDP11.opUndefined, // 0x000D\n PDP11.opUndefined, // 0x000E\n PDP11.opUndefined // 0x000F\n];\n\nPDP11.aOp7Xnn_1140 = [\n PDP11.opMUL, // 0x70nn 11/40+ EIS\n PDP11.opMUL, // 0x71nn 11/40+ EIS\n PDP11.opDIV, // 0x72nn 11/40+ EIS\n PDP11.opDIV, // 0x73nn 11/40+ EIS\n PDP11.opASH, // 0x74nn 11/40+ EIS\n PDP11.opASH, // 0x75nn 11/40+ EIS\n PDP11.opASHC, // 0x76nn 11/40+ EIS\n PDP11.opASHC, // 0x77nn 11/40+ EIS\n PDP11.opXOR, // 0x78nn 11/40+ LEIS\n PDP11.opXOR, // 0x79nn 11/40+ LEIS\n PDP11.opUndefined, // 0x7Ann\n PDP11.opUndefined, // 0x7Bnn\n PDP11.opUndefined, // 0x7Cnn\n PDP11.opUndefined, // 0x7Dnn\n PDP11.opSOB, // 0x7Enn 11/40+ LEIS\n PDP11.opSOB // 0x7Fnn 11/40+ LEIS\n];\n\nPDP11.aOp8Xnn_1140 = [\n PDP11.opBPL, // 0x80nn 1000XX 11/20+ 2.6**\n PDP11.opBMI, // 0x81nn 1004XX 11/20+ 2.6**\n PDP11.opBHI, // 0x82nn 1010XX 11/20+ 2.6**\n PDP11.opBLOS, // 0x83nn 1014XX 11/20+ 2.6**\n PDP11.opBVC, // 0x84nn 1020XX 11/20+ 2.6**\n PDP11.opBVS, // 0x85nn 1024XX 11/20+ 2.6**\n PDP11.opBCC, // 0x86nn 1030XX 11/20+ 2.6**\n PDP11.opBCS, // 0x87nn 1034XX 11/20+ 2.6**\n PDP11.opEMT, // 0x88nn 104000-104377 11/20+ 9.3\n PDP11.opTRAP, // 0x89nn 104400-104777 11/20+ 9.3\n PDP11.op8AXn_1120, // 0x8Ann 1050XX\n PDP11.op8BXn_1120, // 0x8Bnn 1054XX\n PDP11.op8CXn_1120, // 0x8Cnn 1060XX\n PDP11.op8DXn_1140, // 0x8Dnn 106400-106777\n PDP11.opUndefined, // 0x8Enn 1070XX\n PDP11.opUndefined // 0x8Fnn 1074XX\n];\n\nPDP11.aOp8DXn_1140 = [\n PDP11.opMTPS, // 0x8D0n 1064XX 11/34A only\n PDP11.opMFPD, // 0x8D4n 1065XX 11/45+\n PDP11.opMTPD, // 0x8D8n 1066XX 11/45+\n PDP11.opMFPS // 0x8DCn 1067XX 11/34A only\n];\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/rom.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass ROMPDP11 extends Component {\n /**\n * ROMPDP11(parmsROM)\n *\n * The ROMPDP11 component expects the following (parmsROM) properties:\n *\n * addr: physical address of ROM\n * size: amount of ROM, in bytes\n * alias: physical alias address (null if none)\n * file: name of ROM data file\n *\n * NOTE: The ROM data will not be copied into place until the Bus is ready (see initBus()) AND\n * the ROM data file has finished loading (see finishLoad()).\n *\n * Also, while the size parameter may seem redundant, I consider it useful to confirm that the ROM\n * you received is the ROM you expected.\n *\n * @param {Object} parmsROM\n */\n constructor(parmsROM)\n {\n super(\"ROM\", parmsROM, MessagesPDP11.ROM);\n\n this.abInit = null;\n this.aSymbols = null;\n\n this.addrROM = +parmsROM['addr'];\n this.sizeROM = +parmsROM['size'];\n this.fRetainROM = false;\n\n /*\n * The new 'alias' property can now be EITHER a single physical address (like 'addr') OR an array of\n * physical addresses; eg:\n *\n * [0xf0000,0xffff0000,0xffff8000]\n *\n * We could have overloaded 'addr' to accomplish the same thing, but I think it's better to have any\n * aliased locations listed under a separate property.\n *\n * Most ROMs are not aliased, in which case the 'alias' property should have the default value of null.\n */\n this.addrAlias = parmsROM['alias'];\n if (typeof this.addrAlias == \"string\") {\n this.addrAlias = eval(this.addrAlias);\n }\n\n this.sFilePath = parmsROM['file'];\n this.sFileName = Str.getBaseName(this.sFilePath);\n\n if (this.sFilePath) {\n var sFileURL = this.sFilePath;\n if (DEBUG) this.log('load(\"' + sFileURL + '\")');\n /*\n * If the selected ROM file has a \".json\" extension, then we assume it's pre-converted\n * JSON-encoded ROM data, so we load it as-is; ditto for ROM files with a \".hex\" extension.\n * Otherwise, we ask our server-side ROM converter to return the file in a JSON-compatible format.\n */\n var sFileExt = Str.getExtension(this.sFileName);\n if (sFileExt != DumpAPI.FORMAT.JSON && sFileExt != DumpAPI.FORMAT.HEX) {\n sFileURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFilePath + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES + '&' + DumpAPI.QUERY.DECIMAL + '=true';\n }\n var rom = this;\n Web.getResource(sFileURL, null, true, function doneLoad(sURL, sResponse, nErrorCode) {\n rom.finishLoad(sURL, sResponse, nErrorCode);\n });\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {ROMPDP11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.initROM();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {ROMPDP11}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (this.aSymbols) {\n if (this.dbg) {\n this.dbg.addSymbols(this.id, this.addrROM, this.sizeROM, this.aSymbols);\n }\n /*\n * Our only role in the handling of symbols is to hand them off to the Debugger at our\n * first opportunity. Now that we've done that, our copy of the symbols, if any, are toast.\n */\n delete this.aSymbols;\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * Since we have nothing to do on powerDown(), and no state to return, we could simply omit\n * this function. But it doesn't hurt anything, and maybe we'll use our state to save something\n * useful down the road, like user-defined symbols (ie, symbols that the Debugger may have\n * created, above and beyond those symbols we automatically loaded, if any, along with the ROM).\n *\n * @this {ROMPDP11}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return true;\n }\n\n /**\n * finishLoad(sURL, sData, nErrorCode)\n *\n * @this {ROMPDP11}\n * @param {string} sURL\n * @param {string} sData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n finishLoad(sURL, sData, nErrorCode)\n {\n if (nErrorCode) {\n this.notice(\"Unable to load ROM resource (error \" + nErrorCode + \": \" + sURL + \")\");\n this.sFilePath = null;\n }\n else {\n Component.addMachineResource(this.idMachine, sURL, sData);\n var resource = Web.parseMemoryResource(sURL, sData);\n if (resource) {\n this.abInit = resource.aBytes;\n this.aSymbols = resource.aSymbols;\n } else {\n this.sFilePath = null;\n }\n }\n this.initROM();\n }\n\n /**\n * initROM()\n *\n * This function is called by both initBus() and finishLoad(), but it cannot copy the initial data into place\n * until after initBus() has received the Bus component AND finishLoad() has received the data. When both those\n * criteria are satisfied, the component becomes \"ready\".\n *\n * @this {ROMPDP11}\n */\n initROM()\n {\n if (!this.isReady()) {\n if (this.sFilePath) {\n /*\n * Too early...\n */\n if (!this.abInit || !this.bus) return;\n\n /*\n * If no explicit size was specified, then use whatever the actual size is.\n */\n if (!this.sizeROM) {\n this.sizeROM = this.abInit.length;\n }\n if (this.abInit.length != this.sizeROM) {\n /*\n * Note that setError() sets the component's fError flag, which in turn prevents setReady() from\n * marking the component ready. TODO: Revisit this decision. On the one hand, it sounds like a\n * good idea to stop the machine in its tracks whenever a setError() occurs, but there may also be\n * times when we'd like to forge ahead anyway.\n */\n this.setError(\"ROM size (\" + Str.toHexLong(this.abInit.length) + \") does not match specified size (\" + Str.toHexLong(this.sizeROM) + \")\");\n }\n else if (this.addROM(this.addrROM)) {\n\n var aliases = [];\n if (typeof this.addrAlias == \"number\") {\n aliases.push(this.addrAlias);\n } else if (this.addrAlias != null && this.addrAlias.length) {\n aliases = this.addrAlias;\n }\n for (var i = 0; i < aliases.length; i++) {\n this.cloneROM(aliases[i]);\n }\n /*\n * We used to hang onto the initial ROM data so that we could restore any bytes the CPU overwrote,\n * using memory write-notification handlers, but with the introduction of read-only memory blocks, that's\n * no longer necessary.\n *\n * TODO: Consider an option to retain the ROM data, and give the user some way of restoring ROMs.\n * That may be useful for \"resumable\" machines that save/restore all dirty block of memory, regardless\n * whether they're ROM or RAM. However, the only way to modify a machine's ROM is with the Debugger,\n * and Debugger users should know better.\n */\n if (!this.fRetainROM) {\n delete this.abInit;\n }\n }\n }\n this.setReady();\n }\n }\n\n /**\n * addROM(addr)\n *\n * @this {ROMPDP11}\n * @param {number} addr\n * @return {boolean}\n */\n addROM(addr)\n {\n if (addr >= BusPDP11.IOPAGE_16BIT && addr < BusPDP11.IOPAGE_16BIT + BusPDP11.IOPAGE_LENGTH) {\n /*\n * This code has been added as a work-around to effectively allow us to install small ROMs into portions\n * of the IOPAGE address space, by installing I/O handlers for the entire range that return the corresponding\n * bytes of the current ROM image on reads, and ignore any writes (which I'm only assuming is how a typical\n * ROM \"device\" deals with writes; we could remove the write handler, but then writes would fault).\n *\n * TODO: It would be more efficient if we parsed ROM data as words rather than bytes, and then installed\n * only word handlers instead of only byte handlers. It was done this way purely for historical reasons (ie,\n * because that's how other PCjs machines parse their ROMs). For now, all this means is that executing code\n * out of ROM will be slower than out of RAM -- although that's often true in the real world as well.\n */\n var IOTable = {\n [addr]: [ROMPDP11.prototype.readROMByte, ROMPDP11.prototype.writeROMByte, null, null, null, this.sizeROM >> 1]\n };\n if (this.bus.addIOTable(this, IOTable)) {\n this.status(\"Added \" + this.sizeROM + \"-byte ROM at \" + Str.toOct(addr));\n this.fRetainROM = true;\n return true;\n }\n }\n else if (this.bus.addMemory(addr, this.sizeROM, MemoryPDP11.TYPE.ROM)) {\n if (DEBUG) this.log(\"addROM(): copying ROM to \" + Str.toHexLong(addr) + \" (\" + Str.toHexLong(this.abInit.length) + \" bytes)\");\n var i;\n for (i = 0; i < this.abInit.length; i++) {\n this.bus.setByteDirect(addr + i, this.abInit[i]);\n }\n return true;\n }\n\n /*\n * We don't need to report an error here, because addMemory() already takes care of that.\n */\n return false;\n }\n\n /**\n * cloneROM(addr)\n *\n * For ROMs with one or more alias addresses, we used to call addROM() for each address. However,\n * that obviously wasted memory, since each alias was an independent copy, and if you used the\n * Debugger to edit the ROM in one location, the changes would not appear in the other location(s).\n *\n * Now that the Bus component provides low-level getMemoryBlocks() and setMemoryBlocks() methods\n * to manually get and set the blocks of any memory range, it is now possible to create true aliases.\n *\n * @this {ROMPDP11}\n * @param {number} addr\n */\n cloneROM(addr)\n {\n var aBlocks = this.bus.getMemoryBlocks(this.addrROM, this.sizeROM);\n this.bus.setMemoryBlocks(addr, this.sizeROM, aBlocks);\n }\n\n /**\n * readROMByte(addr)\n *\n * @this {ROMPDP11}\n * @param {number} addr\n * @return {number}\n */\n readROMByte(addr)\n {\n var i = (addr - this.addrROM);\n return this.abInit[i];\n }\n\n /**\n * writeROMByte(data, addr)\n *\n * This handler exists simply to ignore any writes, so that they don't cause faults.\n *\n * TODO: Another possible use for this would be to allow the Debugger to alter ROM contents,\n * if the Debugger were to provide an interface indicating whether or not it was responsible\n * for this write.\n *\n * @this {ROMPDP11}\n * @param {number} data\n * @param {number} addr\n */\n writeROMByte(data, addr)\n {\n }\n\n /**\n * ROMPDP11.init()\n *\n * This function operates on every HTML element of class \"rom\", extracting the\n * JSON-encoded parameters for the ROMPDP11 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a ROMPDP11 component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeROM = Component.getElementsByClass(document, PDP11.APPCLASS, \"rom\");\n for (var iROM = 0; iROM < aeROM.length; iROM++) {\n var eROM = aeROM[iROM];\n var parmsROM = Component.getComponentParms(eROM);\n var rom = new ROMPDP11(parmsROM);\n Component.bindComponentControls(rom, eROM, PDP11.APPCLASS);\n }\n }\n}\n\n/*\n * NOTE: There's currently no need for this component to have a reset() function, since\n * once the ROM data is loaded, it can't be changed, so there's nothing to reinitialize.\n *\n * OK, well, I take that back, because the Debugger, if installed, has the ability to modify\n * ROM contents, so in that case, having a reset() function that restores the original ROM data\n * might be useful; then again, it might not, depending on what you're trying to debug.\n *\n * If we do add reset(), then we'll want to change initROM() to hang onto the original\n * ROM data; currently, we release it after copying it into the read-only memory allocated\n * via bus.addMemory().\n */\n\n/*\n * Initialize all the ROMPDP11 modules on the page.\n */\nWeb.onInit(ROMPDP11.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/ram.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass RAMPDP11 extends Component {\n /**\n * RAMPDP11(parmsRAM)\n *\n * The RAMPDP11 component expects the following (parmsRAM) properties:\n *\n * addr: starting physical address of RAM (default is 0)\n * size: amount of RAM, in bytes (default is 0, which means defer to motherboard switch settings)\n * file: name of optional data file to load into RAM (default is \"\")\n * load: optional file load address (overrides any load address specified in the data file; default is null)\n * exec: optional file exec address (overrides any exec address specified in the data file; default is null)\n *\n * NOTE: We make a note of the specified size, but no memory is initially allocated for the RAM until the\n * Computer component calls powerUp().\n *\n * TODO: I seem to recall a PDP-11 diagnostic that failed if total RAM wasn't a multiple of 16Kb; our Bus\n * component defaults to a block size that matches BusPDP11.IOPAGE_LENGTH (ie, 8Kb), and we even allow partial\n * block allocations, so internally, we don't have that requirement, but for better compatibility, perhaps we\n * should display a non-fatal warning if addr or size don't fall on 16Kb boundaries.\n *\n * @param {Object} parmsRAM\n */\n constructor(parmsRAM)\n {\n super(\"RAM\", parmsRAM);\n\n this.abInit = null;\n this.aSymbols = null;\n\n this.addrRAM = +parmsRAM['addr'];\n this.sizeRAM = +parmsRAM['size'];\n\n this.addrLoad = parmsRAM['load'];\n this.addrExec = parmsRAM['exec'];\n if (this.addrLoad != null) this.addrLoad = +this.addrLoad;\n if (this.addrExec != null) this.addrExec = +this.addrExec;\n\n this.fInstalled = (!!this.sizeRAM); // 0 is the default value for 'size' when none is specified\n this.fAllocated = this.fReset = false;\n\n this.sFilePath = parmsRAM['file'];\n this.sFileName = Str.getBaseName(this.sFilePath);\n\n if (this.sFilePath) {\n var sFileURL = this.sFilePath;\n if (DEBUG) this.log('load(\"' + sFileURL + '\")');\n /*\n * If the selected data file has a \".json\" extension, then we assume it's pre-converted\n * JSON-encoded data, so we load it as-is; ditto for ROM files with a \".hex\" extension.\n * Otherwise, we ask our server-side converter to return the file in a JSON-compatible format.\n */\n var sFileExt = Str.getExtension(this.sFileName);\n if (sFileExt != DumpAPI.FORMAT.JSON && sFileExt != DumpAPI.FORMAT.HEX) {\n sFileURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFilePath + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES + '&' + DumpAPI.QUERY.DECIMAL + '=true';\n }\n var ram = this;\n Web.getResource(sFileURL, null, true, function doneLoad(sURL, sResponse, nErrorCode) {\n ram.finishLoad(sURL, sResponse, nErrorCode);\n });\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {RAMPDP11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.initRAM();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {RAMPDP11}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (this.aSymbols) {\n if (this.dbg) {\n this.dbg.addSymbols(this.id, this.addrRAM, this.sizeRAM, this.aSymbols);\n }\n /*\n * Our only role in the handling of symbols is to hand them off to the Debugger at our\n * first opportunity. Now that we've done that, our copy of the symbols, if any, are toast.\n */\n delete this.aSymbols;\n }\n if (!fRepower) {\n /*\n * Since we use the Bus to allocate all our memory, memory contents are already restored for us,\n * so we don't save any state, and therefore no state should be restored. Just do a reset().\n */\n\n this.reset();\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {RAMPDP11}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n /*\n * The Computer powers down the CPU first, at which point CPUState state is saved,\n * which includes the Bus state, and since we use the Bus component to allocate all\n * our memory, memory contents are already saved for us, so we don't need the usual\n * save logic.\n */\n return true;\n }\n\n /**\n * finishLoad(sURL, sData, nErrorCode)\n *\n * @this {RAMPDP11}\n * @param {string} sURL\n * @param {string} sData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n finishLoad(sURL, sData, nErrorCode)\n {\n if (nErrorCode) {\n this.notice(\"Unable to load RAM resource (error \" + nErrorCode + \": \" + sURL + \")\");\n this.sFilePath = null;\n }\n else {\n Component.addMachineResource(this.idMachine, sURL, sData);\n var resource = Web.parseMemoryResource(sURL, sData);\n if (resource) {\n this.abInit = resource.aBytes;\n this.aSymbols = resource.aSymbols;\n if (this.addrLoad == null) this.addrLoad = resource.addrLoad;\n if (this.addrExec == null) this.addrExec = resource.addrExec;\n } else {\n this.sFilePath = null;\n }\n }\n this.initRAM();\n }\n\n /**\n * initRAM()\n *\n * This function is called by both initBus() and finishLoad(), but it cannot copy the initial data into place\n * until after initBus() has received the Bus component AND finishLoad() has received the data. When both those\n * criteria are satisfied, the component becomes \"ready\".\n *\n * @this {RAMPDP11}\n */\n initRAM()\n {\n if (!this.bus) return;\n\n if (!this.fAllocated && this.sizeRAM) {\n if (this.bus.addMemory(this.addrRAM, this.sizeRAM, MemoryPDP11.TYPE.RAM)) {\n this.fAllocated = true;\n } else {\n this.sizeRAM = 0; // don't bother trying again (it just results in redundant error messages)\n }\n }\n if (!this.isReady()) {\n if (!this.fAllocated) {\n Component.error(\"No RAM allocated\");\n }\n else if (this.sFilePath) {\n /*\n * Too early...\n */\n if (!this.abInit) return;\n\n if (this.loadImage(this.abInit, this.addrLoad, this.addrExec, this.addrRAM)) {\n this.status('Loaded image \"' + this.sFileName + '\"');\n } else {\n this.notice('Error loading image \"' + this.sFileName + '\"');\n }\n\n /*\n * NOTE: We now retain this data, so that reset() can return the RAM to its predefined state.\n *\n * delete this.abInit;\n */\n }\n this.fReset = true;\n this.setReady();\n }\n }\n\n /**\n * reset()\n *\n * @this {RAMPDP11}\n */\n reset()\n {\n if (this.fAllocated && !this.fReset) {\n /*\n * TODO: Add a configuration parameter for selecting the byte pattern on reset?\n * Note that when memory blocks are originally created, they are currently always\n * zero-initialized, so this would only affect resets.\n */\n this.bus.zeroMemory(this.addrRAM, this.sizeRAM, 0);\n if (this.abInit) {\n this.loadImage(this.abInit, this.addrLoad, this.addrExec, this.addrRAM, !this.dbg);\n }\n }\n this.fReset = false;\n }\n\n /**\n * loadImage(aBytes, addrLoad, addrExec, addrInit, fStart)\n *\n * If the array contains a PAPER tape image in the \"Absolute Format,\" load it as specified\n * by the format; otherwise, load it as-is using the address(es) supplied.\n *\n * @this {RAMPDP11}\n * @param {Array|Uint8Array} aBytes\n * @param {number|null} [addrLoad]\n * @param {number|null} [addrExec] (this CAN override any starting address INSIDE the image)\n * @param {number|null} [addrInit]\n * @param {boolean} [fStart]\n * @return {boolean} (true if loaded, false if not)\n */\n loadImage(aBytes, addrLoad, addrExec, addrInit, fStart)\n {\n var fStop = false;\n var fLoaded = false;\n /*\n * Data on tapes in the \"Absolute Format\" is organized into blocks; each block begins with\n * a 6-byte header:\n *\n * 2-byte signature (0x0001)\n * 2-byte block length (N + 6, because it includes the 6-byte header)\n * 2-byte load address\n *\n * followed by N data bytes. If N is zero, then the 2-byte load address is the exec address,\n * unless the address is odd (usually 1). DEC's Absolute Loader jumps to the exec address\n * in former case, halts in the latter.\n *\n * All values are stored \"little endian\" (low byte followed by high byte), just like the\n * PDP-11's memory architecture.\n *\n * After the data bytes, there is a single checksum byte. The 8-bit sum of all the bytes in\n * the block (including the header bytes and checksum byte) should be zero.\n *\n * ANOMALIES: Tape files don't always begin with a signature word, so I allow any number of\n * leading zeros before the first signature. Tape files don't always end cleanly either, so as\n * soon as I see an invalid signature, I break out of the loop without signalling an error, as\n * long as at least ONE block was successfully processed. In fact, it's possible that as\n * soon as a block with ZERO data bytes is encountered, processing is supposed to stop, but\n * I haven't examined enough tapes (or the Absolute Loader code) to know for sure.\n */\n if (addrLoad == null) {\n var off = 0, fError = false;\n while (off < aBytes.length - 1) {\n var w = (aBytes[off] & 0xff) | ((aBytes[off+1] & 0xff) << 8);\n if (!w) { // ignore pairs of leading zeros\n off += 2;\n continue;\n }\n if (!(w & 0xff)) { // as well as single bytes of zero\n off++;\n continue;\n }\n var offBlock = off;\n if (w != 0x0001) {\n this.printMessage(\"invalid signature (\" + Str.toHexWord(w) + \") at offset \" + Str.toHexWord(offBlock), MessagesPDP11.PAPER);\n break;\n }\n if (off + 6 >= aBytes.length) {\n this.printMessage(\"invalid block at offset \" + Str.toHexWord(offBlock), MessagesPDP11.PAPER);\n break;\n }\n off += 2;\n var checksum = w;\n var len = (aBytes[off++] & 0xff) | ((aBytes[off++] & 0xff) << 8);\n var addr = (aBytes[off++] & 0xff) | ((aBytes[off++] & 0xff) << 8);\n checksum += (len & 0xff) + (len >> 8) + (addr & 0xff) + (addr >> 8);\n var offData = off, cbData = len -= 6;\n while (len > 0 && off < aBytes.length) {\n checksum += aBytes[off++] & 0xff;\n len--;\n }\n if (len != 0 || off >= aBytes.length) {\n this.printMessage(\"insufficient data for block at offset \" + Str.toHexWord(offBlock), MessagesPDP11.PAPER);\n break;\n }\n checksum += aBytes[off++] & 0xff;\n if (checksum & 0xff) {\n this.printMessage(\"invalid checksum (\" + Str.toHexByte(checksum) + \") for block at offset \" + Str.toHexWord(offBlock), MessagesPDP11.PAPER);\n break;\n }\n if (!cbData) {\n if (addr & 0x1) {\n fStop = true;\n } else {\n if (addrExec == null) addrExec = addr;\n }\n if (addrExec != null) this.printMessage(\"starting address: \" + Str.toHexWord(addrExec), MessagesPDP11.PAPER);\n } else {\n this.printMessage(\"loading \" + Str.toHexWord(cbData) + \" bytes at \" + Str.toHexWord(addr) + \"-\" + Str.toHexWord(addr + cbData), MessagesPDP11.PAPER);\n while (cbData--) {\n this.bus.setByteDirect(addr++, aBytes[offData++] & 0xff);\n }\n }\n fLoaded = true;\n }\n }\n if (!fLoaded) {\n if (addrLoad == null) addrLoad = addrInit;\n if (addrLoad != null) {\n for (var i = 0; i < aBytes.length; i++) {\n this.bus.setByteDirect(addrLoad + i, aBytes[i]);\n }\n fLoaded = true;\n }\n }\n if (fLoaded) {\n /*\n * Set the start address to whatever the caller provided, or failing that, whatever start\n * address was specified inside the image.\n *\n * For example, the diagnostic \"MAINDEC-11-D0AA-PB\" doesn't include a start address inside the\n * image, but we know that the directions for that diagnostic say to \"Start and Restart at 200\",\n * so we have manually inserted an \"exec\":128 in the JSON containing the image.\n */\n if (addrExec == null || fStop) {\n this.cpu.stopCPU();\n fStart = false;\n }\n if (addrExec != null) {\n this.cpu.setReset(addrExec, fStart);\n }\n }\n return fLoaded;\n }\n\n /**\n * RAMPDP11.init()\n *\n * This function operates on every HTML element of class \"ram\", extracting the\n * JSON-encoded parameters for the RAMPDP11 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a RAMPDP11 component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeRAM = Component.getElementsByClass(document, PDP11.APPCLASS, \"ram\");\n for (var iRAM = 0; iRAM < aeRAM.length; iRAM++) {\n var eRAM = aeRAM[iRAM];\n var parmsRAM = Component.getComponentParms(eRAM);\n var ram = new RAMPDP11(parmsRAM);\n Component.bindComponentControls(ram, eRAM, PDP11.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize all the RAMPDP11 modules on the page.\n */\nWeb.onInit(RAMPDP11.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/keyboard.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass KeyboardPDP11 extends Component {\n /**\n * KeyboardPDP11(parmsKbd)\n *\n * @param {Object} parmsKbd\n */\n constructor(parmsKbd)\n {\n super(\"Keyboard\", parmsKbd, MessagesPDP11.KEYBOARD);\n\n this.setReady();\n }\n\n /**\n * setBinding(sType, sBinding, control, sValue)\n *\n * @this {KeyboardPDP11}\n * @param {string|null} sType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"esc\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sType, sBinding, control, sValue)\n {\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {KeyboardPDP11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.cpu = cpu;\n this.dbg = dbg; // NOTE: The \"dbg\" property must be set for the message functions to work\n }\n\n /**\n * KeyboardPDP11.init()\n *\n * This function operates on every HTML element of class \"keyboard\", extracting the\n * JSON-encoded parameters for the Keyboard constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Keyboard component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeKbd = Component.getElementsByClass(document, PDP11.APPCLASS, \"keyboard\");\n for (var iKbd = 0; iKbd < aeKbd.length; iKbd++) {\n var eKbd = aeKbd[iKbd];\n var parmsKbd = Component.getComponentParms(eKbd);\n var kbd = new KeyboardPDP11(parmsKbd);\n Component.bindComponentControls(kbd, eKbd, PDP11.APPCLASS);\n }\n }\n}\n\nKeyboardPDP11.MINPRESSTIME = 100; // 100ms\n\n/*\n * Initialize every Keyboard module on the page.\n */\nWeb.onInit(KeyboardPDP11.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/serial.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * Component class, because otherwise the Compiler won't allow us to *reference* the named\n * property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass SerialPortPDP11 extends Component {\n /**\n * SerialPortPDP11(parmsSerial)\n *\n * The SerialPort component has the following component-specific (parmsSerial) properties:\n *\n * adapter: adapter number; 0 if not defined (the PCx86 SerialPort component uses this\n * value to set the device's internal COM number, which in turn determines other properties,\n * such as I/O ports and IRQ; for the PDP-11, this currently has no defined use)\n *\n * baudReceive: the default number of bits/second that the device should receive data at;\n * 0 means use the device default (PDP11.DL11.RCSR.BAUD)\n *\n * baudTransmit: the default number of bits/second that the device should transmit data at;\n * 0 means use the device default (PDP11.DL11.XCSR.BAUD)\n *\n * binding: name of a control (based on its \"binding\" attribute) to bind to this port's I/O\n *\n * tabSize: set to a non-zero number to convert tabs to spaces (applies only to output to\n * the above binding); default is 0 (no conversion)\n *\n * upperCase: if true, all received input is upper-cased; it is normally the responsibility\n * of the sending device to ensure this, but sometimes it's more convenient to enforce\n * on the receiving end.\n *\n * NOTE: Since the XSL file defines the 'adapter' and 'baud' properties as numbers, not strings,\n * there's no need to use parseInt(), and as an added benefit, we don't need to worry about whether\n * a hex or decimal format was used.\n *\n * @param {Object} parmsSerial\n */\n constructor(parmsSerial)\n {\n super(\"SerialPort\", parmsSerial, MessagesPDP11.SERIAL);\n\n this.iAdapter = +parmsSerial['adapter'];\n this.nBaudReceive = +parmsSerial['baudReceive'] || PDP11.DL11.RCSR.BAUD;\n this.nBaudTransmit = +parmsSerial['baudTransmit'] || PDP11.DL11.XCSR.BAUD;\n this.fUpperCase = parmsSerial['upperCase'];\n if (typeof this.fUpperCase == \"string\") this.fUpperCase = (this.fUpperCase == \"true\");\n /**\n * consoleBuffer becomes a string that records serial port output if the 'binding' property is set to the\n * reserved name \"console\". Nothing is written to the console, however, until a linefeed (0x0A) is output\n * or the string length reaches a threshold (currently, 1024 characters).\n *\n * @type {string|null}\n */\n this.consoleBuffer = null;\n\n /**\n * controlBuffer is a DOM element bound to the port (currently used for output only; see transmitByte()).\n *\n * Example: CTTY COM2\n *\n * The CTTY DOS command redirects all CON I/O to the specified serial port (eg, COM2), which it assumes is\n * connected to a serial terminal, and therefore anything it *transmits* via COM2 will be displayed by the\n * terminal. It further assumes that anything typed on such a terminal is NOT displayed, so as DOS *receives*\n * serial input, DOS *transmits* the appropriate characters back to the terminal via COM2.\n *\n * As a result, controlBuffer only needs to be updated by the transmitByte() function.\n *\n * @type {Object}\n */\n this.controlBuffer = null;\n\n /*\n * If controlBuffer is being used AND 'tabSize' is set, then we make an attempt to monitor the characters\n * being echoed via transmitByte(), maintain a logical column position, and convert any tabs into the appropriate\n * number of spaces.\n *\n * charBOL, if nonzero, is a character to automatically output at the beginning of every line. This probably\n * isn't generally useful; I use it internally to preformat serial output.\n */\n this.tabSize = +parmsSerial['tabSize'];\n this.charBOL = +parmsSerial['charBOL'];\n this.iLogicalCol = 0;\n this.fNullModem = true;\n\n this.irqReceiver = this.irqTransmitter = null;\n this.timerReceiveInterrupt = this.timerTransmitInterrupt = -1;\n\n this.regRBUF = this.regRCSR = this.regXCSR = 0;\n this.abReceive = [];\n\n var sBinding = parmsSerial['binding'];\n if (sBinding == \"console\") {\n this.consoleBuffer = \"\";\n } else {\n /*\n * If the SerialPort wants to bind to a control (eg, \"print\") in a DIFFERENT component (eg, \"Panel\"),\n * then it specifies the name of that control with the 'binding' property. The SerialPort constructor\n * will then call bindExternalControl(), which looks up the control, and then passes it to our own\n * setBinding() handler.\n * \n * For bindExternalControl() to succeed, it also need to know the target component; for now, that's\n * been hard-coded to \"Panel\", in part because that's one of the few components we can rely upon\n * initializing before we do, but it would be a simple matter to include a component type or ID as part\n * of the 'binding' property as well, if we need more flexibility later.\n * \n * NOTE: If sBinding is not the name of a valid Control Panel DOM element, this call does nothing.\n */\n Component.bindExternalControl(this, sBinding);\n }\n\n /*\n * No connection until initConnection() is called.\n */\n this.sDataReceived = \"\";\n this.connection = this.sendData = this.updateStatus = null;\n\n /*\n * Export all functions required by initConnection().\n */\n this['exports'] = {\n 'connect': this.initConnection,\n 'receiveData': this.receiveData,\n 'receiveStatus': this.receiveStatus,\n 'setConnection': this.setConnection\n };\n }\n\n /**\n * setBinding(sType, sBinding, control, sValue)\n *\n * @this {SerialPortPDP11}\n * @param {string|null} sType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"buffer\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sType, sBinding, control, sValue)\n {\n if (sType == null || sType == \"textarea\") {\n\n var serial = this;\n this.bindings[sBinding] = this.controlBuffer = control;\n\n /*\n * An onkeydown handler is required for certain keys that browsers tend to consume themselves;\n * for example, BACKSPACE is often defined as going back to the previous web page, and certain\n * CTRL keys are often used for browser shortcuts (usually on Windows-based browsers).\n *\n * NOTE: We don't bother with a keyUp handler, because for the most part, we're only intercepting\n * keys that require special treatment; in general, we're content with keyPress events.\n */\n control.onkeydown = function onKeyDown(event) {\n event = event || window.event;\n var bASCII = 0;\n var keyCode = event.keyCode;\n /*\n * Perform the same remapping of BACKSPACE and DELETE that our VT100 emulation performs,\n * for PCjs-wide consistency; see the KEYMAP table in /modules/pc8080/lib/keyboard.js for\n * the rationale. Ditto for ALT-DELETE; see onKeyDown() in /modules/pc8080/lib/keyboard.js\n * for details.\n *\n * NOTE: keyDown (and keyUp) events supply us with KEYCODE values, which are NOT the same as\n * ASCII values, which is why we are comparing with KEYCODE values but assigning ASCII values,\n * because receiveData() requires ASCII values.\n */\n if (keyCode == Keys.KEYCODE.BS) {\n bASCII = event.altKey? Keys.ASCII.CTRL_H : Keys.ASCII.DEL;\n }\n else if (keyCode == Keys.KEYCODE.DEL) {\n bASCII = Keys.ASCII.CTRL_H;\n }\n else if (event.ctrlKey && keyCode >= Keys.ASCII.A && keyCode <= Keys.ASCII.Z) {\n bASCII = keyCode - (Keys.ASCII.A - Keys.ASCII.CTRL_A);\n }\n if (bASCII) {\n if (event.preventDefault) event.preventDefault();\n serial.receiveData(bASCII);\n }\n return true;\n };\n\n control.onkeypress = function onKeyPress(event) {\n /*\n * NOTE: Unlike keyDown events, keyPress events generally supply us with ASCII values,\n * despite the fact that, as above, they come to us via the keyCode property. Yes, it's\n * brilliant (or rather, the opposite of brilliant), but that's life.\n */\n event = event || window.event;\n /*\n * Not sure why COMMAND-key combinations are coming through here (on Safari at least),\n * but in any case, let's make sure we don't act on them.\n */\n if (!event.metaKey) {\n var bASCII = event.which || event.keyCode;\n /*\n * Perform the same remapping of ALT-ENTER (to LINE-FEED) that our VT100 emulation performs,\n * for PCjs-wide consistency; see onKeyDown() in /modules/pc8080/lib/keyboard.js for details.\n */\n if (event.altKey) {\n if (bASCII == Keys.ASCII.CTRL_M) {\n bASCII = Keys.ASCII.CTRL_J;\n }\n }\n serial.receiveData(bASCII);\n /*\n * Since we're going to remove the \"readonly\" attribute from the <textarea> control\n * (so that the soft keyboard activates on iOS), instead of calling preventDefault() for\n * selected keys (eg, the SPACE key, whose default behavior is to scroll the page), we must\n * now call it for *all* keys, so that the keyCode isn't added to the control immediately,\n * on top of whatever the machine is echoing back, resulting in double characters.\n */\n if (event.preventDefault) event.preventDefault();\n }\n return true;\n };\n\n control.onpaste = function onKeyPress(event) {\n if (event.stopPropagation) event.stopPropagation();\n if (event.preventDefault) event.preventDefault();\n var clipboardData = event.clipboardData || window.clipboardData;\n if (clipboardData) {\n /*\n * NOTE: Multiple lines of pasted text will (at least on macOS) contain LFs instead of CRs;\n * this is dealt with in receiveData() whenever it receives a string of characters.\n */\n serial.receiveData(clipboardData.getData('Text'));\n }\n };\n\n /*\n * Now that we've added an onkeypress handler that calls preventDefault() for ALL keys, the control\n * itself no longer needs the \"readonly\" attribute; we primarily need to remove it for iOS browsers,\n * so that the soft keyboard will activate, but it shouldn't hurt to remove the attribute for all browsers.\n */\n control.removeAttribute(\"readonly\");\n\n return true;\n }\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {SerialPortPDP11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n var serial = this;\n\n this.irqReceiver = this.cpu.addIRQ(this.iAdapter? -1 : PDP11.DL11.RVEC, PDP11.DL11.PRI, MessagesPDP11.DL11);\n\n this.timerReceiveInterrupt = this.cpu.addTimer(function readyReceiver() {\n var b = serial.receiveByte();\n if (b >= 0) {\n serial.regRBUF = b;\n if (!(serial.regRCSR & PDP11.DL11.RCSR.RD)) {\n serial.regRCSR |= PDP11.DL11.RCSR.RD;\n } else {\n serial.regRBUF |= PDP11.DL11.RBUF.OE | PDP11.DL11.RBUF.ERROR;\n }\n if (serial.regRCSR & PDP11.DL11.RCSR.RIE) {\n cpu.setIRQ(serial.irqReceiver);\n }\n }\n });\n\n this.irqTransmitter = this.cpu.addIRQ(this.iAdapter? -1 : PDP11.DL11.XVEC, PDP11.DL11.PRI, MessagesPDP11.DL11);\n\n this.timerTransmitInterrupt = this.cpu.addTimer(function readyTransmitter() {\n serial.regXCSR |= PDP11.DL11.XCSR.READY;\n if (serial.regXCSR & PDP11.DL11.XCSR.TIE) {\n cpu.setIRQ(serial.irqTransmitter);\n }\n });\n\n bus.addIOTable(this, SerialPortPDP11.UNIBUS_IOTABLE, this.iAdapter? ((PDP11.UNIBUS.DL11 + (this.iAdapter - 1) * 8) - PDP11.UNIBUS.RCSR) : 0);\n bus.addResetHandler(this.reset.bind(this));\n\n this.setReady();\n }\n\n /**\n * initConnection(fNullModem)\n *\n * If a machine 'connection' parameter exists of the form \"{sourcePort}->{targetMachine}.{targetPort}\",\n * and \"{sourcePort}\" matches our idComponent, then look for a component with id \"{targetMachine}.{targetPort}\".\n *\n * If the target component is found, then verify that it has exported functions with the following names:\n *\n * receiveData(data): called when we have data to transmit; aliased internally to sendData(data)\n * receiveStatus(pins): called when our control signals have changed; aliased internally to updateStatus(pins)\n *\n * For now, we're not going to worry about communication in the other direction, because when the target component\n * performs its own initConnection(), it will find our receiveData() and receiveStatus() functions, at which point\n * communication in both directions should be established, and the circle of life complete.\n *\n * For added robustness, if the target machine initializes much more slowly than we do, and our connection attempt\n * fails, that's OK, because when it finally initializes, its initConnection() will call our initConnection();\n * if we've already initialized, no harm done.\n *\n * @this {SerialPortPDP11}\n * @param {boolean} [fNullModem] (caller's null-modem setting, to ensure our settings are in agreement)\n */\n initConnection(fNullModem)\n {\n if (!this.connection) {\n var sConnection = this.cmp.getMachineParm(\"connection\");\n if (sConnection) {\n var asParts = sConnection.split('->');\n if (asParts.length == 2) {\n var sSourceID = Str.trim(asParts[0]);\n if (sSourceID != this.idComponent) return; // this connection string is intended for another instance\n var sTargetID = Str.trim(asParts[1]);\n this.connection = Component.getComponentByID(sTargetID);\n if (this.connection) {\n var exports = this.connection['exports'];\n if (exports) {\n var fnConnect = /** @function */ (exports['connect']);\n if (fnConnect) fnConnect.call(this.connection, this.fNullModem);\n this.sendData = exports['receiveData'];\n if (this.sendData) {\n this.fNullModem = fNullModem;\n this.updateStatus = exports['receiveStatus'];\n this.status(\"Connected \" + this.idMachine + '.' + sSourceID + \" to \" + sTargetID);\n return;\n }\n }\n }\n }\n /*\n * Changed from notice() to status() because sometimes a connection fails simply because one of us is a laggard.\n */\n this.status(\"Unable to establish connection: \" + sConnection);\n }\n }\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {SerialPortPDP11}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n\n /*\n * This is as late as we can currently wait to make our first inter-machine connection attempt;\n * even so, the target machine's initialization process may still be ongoing, so any connection\n * may be not fully resolved until the target machine performs its own initConnection(), which will\n * in turn invoke our initConnection() again.\n */\n this.initConnection(this.fNullModem);\n\n if (!data) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {SerialPortPDP11}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {SerialPortPDP11}\n */\n reset()\n {\n this.initState();\n }\n\n /**\n * save()\n *\n * This implements save support for the SerialPort component.\n *\n * @this {SerialPortPDP11}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveRegisters());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the SerialPort component.\n *\n * @this {SerialPortPDP11}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return this.initState(data[0]);\n }\n\n /**\n * initState(a)\n *\n * @this {SerialPortPDP11}\n * @param {Array} [a]\n * @return {boolean} true if successful, false if failure\n */\n initState(a)\n {\n if (!a) {\n a = [0, PDP11.DL11.RCSR.CTS, PDP11.DL11.XCSR.READY, this.abReceive];\n }\n\n /*\n * ES6 ALERT: A handy destructuring assignment, which makes it easy to perform the inverse\n * of what saveRegisters() does when it collects a bunch of object properties into an array.\n */\n [\n this.regRBUF,\n this.regRCSR,\n this.regXCSR,\n this.abReceive\n ] = a;\n\n return true;\n }\n\n /**\n * saveRegisters()\n *\n * Basically, the inverse of initState().\n *\n * @this {SerialPortPDP11}\n * @return {Array}\n */\n saveRegisters()\n {\n return [\n this.regRBUF,\n this.regRCSR,\n this.regXCSR,\n this.abReceive\n ];\n }\n\n /**\n * getBaudTimeout(nBaud)\n *\n * Based on the selected baud rate (nBaud), convert that rate into a millisecond delay.\n *\n * @this {SerialPortPDP11}\n * @param {number} nBaud\n * @return {number} (number of milliseconds per byte)\n */\n getBaudTimeout(nBaud)\n {\n /*\n * TODO: Do a better job computing this, based on actual numbers of start, stop and parity bits,\n * instead of hard-coding the total number of bits per byte to 10.\n */\n var nBytesPerSecond = Math.round(nBaud / 10);\n return 1000 / nBytesPerSecond;\n }\n\n /**\n * receiveData(data)\n *\n * This replaces the old sendRBR() function, which expected an Array of bytes. We still support that,\n * but in order to support connections with other SerialPort components (ie, the PC8080 SerialPort), we\n * have added support for numbers and strings as well.\n *\n * @this {SerialPortPDP11}\n * @param {number|string|Array} data\n * @return {boolean} true if received, false if not\n */\n receiveData(data)\n {\n if (typeof data == \"number\") {\n this.abReceive.push(data);\n }\n else if (typeof data == \"string\") {\n var bASCII = 0, bASCIIPrev;\n for (var i = 0; i < data.length; i++) {\n bASCIIPrev = bASCII;\n bASCII = data.charCodeAt(i);\n /*\n * NOTE: Multiple lines of pasted text will (at least on macOS) contain LFs instead of CRs;\n * we convert them to CRs below. Windows may do something different, but in the worst case,\n * even if we receive CR/LF pairs, this code should keep the CRs and lose the LFs.\n */\n if (bASCII == Str.ASCII.LF) {\n if (bASCIIPrev == Str.ASCII.CR) continue;\n bASCII = Str.ASCII.CR;\n }\n this.abReceive.push(bASCII);\n }\n }\n else {\n this.abReceive = this.abReceive.concat(data);\n }\n\n this.cpu.setTimer(this.timerReceiveInterrupt, this.getBaudTimeout(this.nBaudReceive));\n\n return true; // for now, return true regardless, since we're buffering everything anyway\n }\n\n /**\n * receiveByte()\n *\n * @this {SerialPortPDP11}\n * @return {number} (0x00-0xff if byte available, -1 if not)\n */\n receiveByte()\n {\n var b = -1;\n if (this.abReceive.length) {\n /*\n * Here, as elsewhere (eg, the PC11 component), even if I trusted all incoming data\n * to be byte values (which I don't), there's also the risk that it could be signed data\n * (eg, -128 to 127, instead of 0 to 255). Both risks are good reasons to always mask\n * the data assigned to RBUF with 0xff.\n */\n b = this.abReceive.shift() & 0xff;\n this.printMessage(\"receiveByte(\" + Str.toHexByte(b) + \")\");\n if (this.fUpperCase) {\n /*\n * Automatically transform lower-case ASCII codes to upper-case; fUpperCase should\n * only be set when a terminal or some sort of pseudo-display is being used and we don't\n * trust it to have its CAPS-LOCK setting correct.\n */\n if (b >= 0x61 && b < 0x7A) b -= 0x20;\n }\n this.cpu.setTimer(this.timerReceiveInterrupt, this.getBaudTimeout(this.nBaudReceive));\n }\n return b;\n }\n\n /**\n * receiveStatus(pins)\n *\n * @this {SerialPortPDP11}\n * @param {number} pins\n */\n receiveStatus(pins)\n {\n var oldRCSR = this.regRCSR;\n this.regRCSR &= ~(PDP11.DL11.RCSR.CTS | PDP11.DL11.RCSR.CD);\n if (pins & RS232.CTS.MASK) {\n this.regRCSR |= PDP11.DL11.RCSR.CTS;\n }\n if (pins & RS232.CD.MASK) {\n this.regRCSR |= PDP11.DL11.RCSR.CD;\n }\n if (oldRCSR != this.regRCSR) {\n this.regRCSR |= PDP11.DL11.RCSR.DSC;\n if (this.regRCSR & PDP11.DL11.RCSR.DIE) {\n this.cpu.setIRQ(this.irqReceiver);\n }\n }\n }\n\n /**\n * setConnection(component, fn)\n *\n * @this {SerialPortPDP11}\n * @param {Object|null} component\n * @param {function(number)} fn\n * @return {boolean}\n */\n setConnection(component, fn)\n {\n if (!this.connection) {\n this.connection = component;\n this.sendData = fn;\n return true;\n }\n return false;\n }\n\n /**\n * transmitByte(b)\n *\n * @this {SerialPortPDP11}\n * @param {number} b\n * @return {boolean} true if transmitted, false if not\n */\n transmitByte(b)\n {\n var fTransmitted = false;\n\n if (MAXDEBUG) this.printMessage(\"transmitByte(\" + Str.toHexByte(b) + \")\");\n\n if (this.sendData) {\n if (this.sendData.call(this.connection, b)) {\n fTransmitted = true;\n }\n }\n\n /*\n * TODO: Why do DEC diagnostics like to output bytes with bit 7 set?\n */\n b &= 0x7F;\n if (this.controlBuffer) {\n if (b == 0x0D) {\n this.iLogicalCol = 0;\n }\n else if (b == 0x08) {\n this.controlBuffer.value = this.controlBuffer.value.slice(0, -1);\n /*\n * TODO: Back up the correct number of columns if the character erased was a tab.\n */\n if (this.iLogicalCol > 0) this.iLogicalCol--;\n }\n else if (b) {\n /*\n * RT-11 outputs lots of NULL characters, at least after a \"D 56=5015\" (0x0A0D) command has\n * been issued, hence the \"if (b)\" check above.\n *\n * TODO: Also consider a check for Keys.ASCII.CTRL_C, because by default, RT-11 outputs \"raw\"\n * CTRL_C characters, which we capture below and render as <ETX>. RT-11 does this for other keys\n * as well, such as CTRL_K (<VT>) and CTRL_L (<FF>).\n */\n var s = Str.toASCIICode(b); // formerly: String.fromCharCode(b);\n var nChars = s.length; // formerly: (b >= 0x20? 1 : 0);\n if (b < 0x20 && nChars == 1) nChars = 0;\n if (b == 0x09) {\n var tabSize = this.tabSize || 8;\n nChars = tabSize - (this.iLogicalCol % tabSize);\n if (this.tabSize) s = Str.pad(\"\", nChars);\n }\n if (this.charBOL && !this.iLogicalCol && nChars) s = String.fromCharCode(this.charBOL) + s;\n this.controlBuffer.value += s;\n this.controlBuffer.scrollTop = this.controlBuffer.scrollHeight;\n this.iLogicalCol += nChars;\n }\n fTransmitted = true;\n }\n else if (this.consoleBuffer != null) {\n if (b == 0x0A || this.consoleBuffer.length >= 1024) {\n this.println(this.consoleBuffer);\n this.consoleBuffer = \"\";\n }\n if (b != 0x0A) {\n this.consoleBuffer += String.fromCharCode(b);\n }\n fTransmitted = true;\n }\n\n /*\n * NOTE: When debugging issues involving the SerialPort, such as debugging code between a pair of\n * transmitted bytes, you can pass 0 instead of getBaudTimeout() to setTimer() to minimize the amount\n * of time spent waiting for XCSR.READY to be set again.\n */\n this.cpu.setTimer(this.timerTransmitInterrupt, this.getBaudTimeout(this.nBaudTransmit));\n\n return fTransmitted;\n }\n\n /**\n * readRCSR(addr)\n *\n * @this {SerialPortPDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.RCSR or 177560)\n * @return {number}\n */\n readRCSR(addr)\n {\n var data = this.regRCSR & PDP11.DL11.RCSR.RMASK;\n this.regRCSR &= ~PDP11.DL11.RCSR.DSC;\n return data;\n }\n\n /**\n * writeRCSR(data, addr)\n *\n * @this {SerialPortPDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RCSR or 177560)\n */\n writeRCSR(data, addr)\n {\n var delta = (data ^ this.regRCSR);\n this.regRCSR = (this.regRCSR & ~PDP11.DL11.RCSR.WMASK) | (data & PDP11.DL11.RCSR.WMASK);\n /*\n * Whenever DTR or RTS changes, we also want to notify any connected machine, via updateStatus().\n */\n if (this.updateStatus) {\n if (delta & PDP11.DL11.RCSR.RS232) {\n var pins = 0;\n if (this.fNullModem) {\n pins |= (data & PDP11.DL11.RCSR.RTS)? RS232.CTS.MASK : 0;\n pins |= (data & PDP11.DL11.RCSR.DTR)? (RS232.DSR.MASK | RS232.CD.MASK): 0;\n } else {\n pins |= (data & PDP11.DL11.RCSR.RTS)? RS232.RTS.MASK : 0;\n pins |= (data & PDP11.DL11.RCSR.DTR)? RS232.DTR.MASK : 0;\n }\n this.updateStatus.call(this.connection, pins);\n }\n }\n }\n\n /**\n * readRBUF(addr)\n *\n * @this {SerialPortPDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.RBUF or 177562)\n * @return {number}\n */\n readRBUF(addr)\n {\n this.regRCSR &= ~PDP11.DL11.RCSR.RD;\n return this.regRBUF;\n }\n\n /**\n * writeRBUF(data, addr)\n *\n * @this {SerialPortPDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RBUF or 177562)\n */\n writeRBUF(data, addr)\n {\n }\n\n /**\n * readXCSR(addr)\n *\n * @this {SerialPortPDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.XCSR or 177564)\n * @return {number}\n */\n readXCSR(addr)\n {\n return this.regXCSR;\n }\n\n /**\n * writeXCSR(data, addr)\n *\n * @this {SerialPortPDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.XCSR or 177564)\n */\n writeXCSR(data, addr)\n {\n /*\n * If the device is READY, and TIE is being set, then request a hardware interrupt.\n *\n * Conversely, if TIE is being cleared, remove the request; this resolves a problem within\n * MAINDEC TEST 15, where the Transmitter Interrupt Enable (TIE) bit is cleared, set, and cleared\n * in rapid succession, with the expectation that NO interrupt will be generated. Note that\n * this fix also requires a complementary change in setIRQ(), to request hardware interrupts with\n * IRQ_DELAY rather than IRQ.\n */\n if (this.regXCSR & PDP11.DL11.XCSR.READY) {\n if (data & PDP11.DL11.XCSR.TIE) {\n this.cpu.setIRQ(this.irqTransmitter);\n } else {\n this.cpu.clearIRQ(this.irqTransmitter);\n }\n }\n this.regXCSR = (this.regXCSR & ~PDP11.DL11.XCSR.WMASK) | (data & PDP11.DL11.XCSR.WMASK);\n }\n\n /**\n * readXBUF(addr)\n *\n * @this {SerialPortPDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.XBUF or 177566)\n * @return {number}\n */\n readXBUF(addr)\n {\n return 0;\n }\n\n /**\n * writeXBUF(data, addr)\n *\n * @this {SerialPortPDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.XBUF or 177566)\n */\n writeXBUF(data, addr)\n {\n this.transmitByte(data & PDP11.DL11.XBUF.DATA);\n this.regXCSR &= ~PDP11.DL11.XCSR.READY;\n }\n\n /**\n * SerialPortPDP11.init()\n *\n * This function operates on every HTML element of class \"serial\", extracting the\n * JSON-encoded parameters for the SerialPort constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a SerialPort component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeSerial = Component.getElementsByClass(document, PDP11.APPCLASS, \"serial\");\n for (var iSerial = 0; iSerial < aeSerial.length; iSerial++) {\n var eSerial = aeSerial[iSerial];\n var parmsSerial = Component.getComponentParms(eSerial);\n var serial = new SerialPortPDP11(parmsSerial);\n Component.bindComponentControls(serial, eSerial, PDP11.APPCLASS);\n }\n }\n}\n\n/*\n * ES6 ALERT: As you can see below, I've finally started using computed property names.\n */\nSerialPortPDP11.UNIBUS_IOTABLE = {\n [PDP11.UNIBUS.RCSR]: /* 177560 */ [null, null, SerialPortPDP11.prototype.readRCSR, SerialPortPDP11.prototype.writeRCSR, \"RCSR\"],\n [PDP11.UNIBUS.RBUF]: /* 177562 */ [null, null, SerialPortPDP11.prototype.readRBUF, SerialPortPDP11.prototype.writeRBUF, \"RBUF\"],\n [PDP11.UNIBUS.XCSR]: /* 177564 */ [null, null, SerialPortPDP11.prototype.readXCSR, SerialPortPDP11.prototype.writeXCSR, \"XCSR\"],\n [PDP11.UNIBUS.XBUF]: /* 177566 */ [null, null, SerialPortPDP11.prototype.readXBUF, SerialPortPDP11.prototype.writeXBUF, \"XBUF\"]\n};\n\n/*\n * Initialize every SerialPort module on the page.\n */\nWeb.onInit(SerialPortPDP11.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/pc11.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass PC11 extends Component {\n /**\n * PC11(parms)\n *\n * The PC11 component has the following component-specific (parms) properties:\n *\n * autoMount: a JSON-encoded object containing 'name' and 'path' properties, describing a\n * tape resource to automatically load at startup (only the \"load\" operation is supported\n * for autoMount; if you want to \"read\" a tape image directly into RAM at startup, you must\n * ask the RAM component to do that).\n *\n * baudReceive: the default number of bits/second that the device should receive data at;\n * 0 means use the device default (PDP11.PC11.PRS.BAUD)\n *\n * baudTransmit: the default number of bits/second that the device should transmit data at;\n * 0 means use the device default (PDP11.PC11.PPS.BAUD); currently ignored, since punch\n * support isn't implemented yet.\n *\n * NOTE: Since the XSL file defines the 'baud' properties as numbers, not strings, there's no need to\n * use parseInt(), and as an added benefit, we don't need to worry about whether a hex or decimal format\n * was used.\n *\n * @param {Object} parms\n */\n constructor(parms)\n {\n super(\"PC11\", parms, MessagesPDP11.PC11);\n\n this.sDevice = \"PTR\"; // TODO: Make the device name configurable\n\n /*\n * We preliminarily parse and record any 'autoMount' object now, but we no longer process it\n * until initBus(), because the Computer's getMachineParm() service may have an override for us.\n */\n this.configMount = this.parseConfig(parms['autoMount']);\n this.cAutoMount = 0;\n this.nBaudReceive = +parms['baudReceive'] || PDP11.PC11.PRS.BAUD;\n\n this.regPRS = 0; // PRS register\n this.regPRB = 0; // PRB register\n this.regPPS = PDP11.PC11.PPS.ERROR; // PPS register (TODO: Stop signaling error once punch is implemented)\n this.regPPB = 0; // PPB register\n this.iTapeData = 0; // buffer index\n this.aTapeData = []; // buffer for the PRB register\n this.sTapeSource = PC11.SOURCE.NONE;\n this.nTapeTarget = PC11.TARGET.NONE;\n this.sTapeName = this.sTapePath = \"\";\n\n /*\n * These next few variables simply keep track of the previous parameters to parseTape(),\n * so that we can easily reparse the previous tape as needed.\n */\n this.aBytes = this.addrLoad = this.addrExec = null;\n\n this.nLastPercent = -1; // ensure the first displayProgress() displays something\n\n /*\n * Support for local tape images is currently limited to desktop browsers with FileReader support;\n * when this flag is set, setBinding() allows local tape bindings and informs initBus() to update the\n * \"listTapes\" binding accordingly.\n */\n this.fLocalTapes = (!Web.isMobile() && window && 'FileReader' in window);\n\n this.irqReader = null;\n this.timerReader = -1;\n this.ram = null;\n }\n\n /**\n * parseConfig(config)\n *\n * @this {PC11}\n * @param {*} config\n * @return {*}\n */\n parseConfig(config)\n {\n if (config && typeof config == \"string\") {\n try {\n /*\n * The most likely source of any exception will be right here, where we're parsing\n * this JSON-encoded data.\n */\n config = eval(\"(\" + config + \")\");\n } catch (e) {\n Component.error(this.type + \" auto-mount error: \" + e.message + \" (\" + config + \")\");\n config = null;\n }\n }\n return config || {};\n }\n\n /**\n * setBinding(sType, sBinding, control, sValue)\n *\n * @this {PC11}\n * @param {string|null} sType is the type of the HTML control (eg, \"button\", \"list\", \"text\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"listTapes\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sType, sBinding, control, sValue)\n {\n var pc11 = this;\n var nTapeTarget = PC11.TARGET.NONE;\n\n switch (sBinding) {\n\n case \"listTapes\":\n var controlSelect = /** @type {HTMLSelectElement} */ (control);\n this.bindings[sBinding] = controlSelect;\n controlSelect.onchange = function onChangeListTapes(event) {\n var controlDesc = pc11.bindings[\"descTape\"];\n var controlOption = controlSelect.options[controlSelect.selectedIndex];\n if (controlDesc && controlOption) {\n var dataValue = {};\n var sValue = controlOption.getAttribute(\"data-value\");\n if (sValue) {\n try {\n dataValue = eval(\"(\" + sValue + \")\");\n } catch (e) {\n Component.error(\"PC11 option error: \" + e.message);\n }\n }\n var sHTML = dataValue['desc'];\n if (sHTML === undefined) sHTML = \"\";\n var sHRef = dataValue['href'];\n if (sHRef !== undefined) sHTML = \"<a href=\\\"\" + sHRef + \"\\\" target=\\\"_blank\\\">\" + sHTML + \"</a>\";\n controlDesc.innerHTML = sHTML;\n }\n };\n return true;\n\n case \"descTape\":\n this.bindings[sBinding] = control;\n return true;\n\n /*\n * \"readTape\" operation must do pretty much everything that the \"loadTape\" does, but whereas the load\n * operation records the bytes in aTapeData, the read operation stuffs them directly into the machine's memory;\n * the former sets nTapeTarget to TARGET.READER, while the latter sets it to TARGET.MEMORY.\n */\n case \"readTape\":\n nTapeTarget = PC11.TARGET.MEMORY;\n /* falls through */\n\n case \"loadTape\":\n if (!nTapeTarget) nTapeTarget = PC11.TARGET.READER;\n this.bindings[sBinding] = control;\n control.onclick = function onClickReadTape(event) {\n var controlTapes = pc11.bindings[\"listTapes\"];\n if (controlTapes) {\n var sTapeName = controlTapes.options[controlTapes.selectedIndex].text;\n var sTapePath = controlTapes.value;\n pc11.loadSelectedTape(sTapeName, sTapePath, nTapeTarget);\n }\n };\n return true;\n\n case \"mountTape\":\n var controlInput = /** @type {Object} */ (control);\n \n if (!this.fLocalTapes) {\n if (DEBUG) this.log(\"Local tape support not available\");\n /*\n * We could also simply hide the control; eg:\n *\n * controlInput.style.display = \"none\";\n *\n * but removing the control altogether seems better.\n */\n controlInput.parentNode.removeChild(/** @type {Node} */ (controlInput));\n return false;\n }\n\n this.bindings[sBinding] = controlInput;\n\n /*\n * Enable \"Mount\" button only if a file is actually selected\n */\n controlInput.addEventListener('change', function() {\n var fieldset = controlInput.children[0];\n var files = fieldset.children[0].files;\n var submit = fieldset.children[1];\n submit.disabled = !files.length;\n });\n\n controlInput.onsubmit = function(event) {\n var file = event.currentTarget[1].files[0];\n if (file) {\n var sTapePath = file.name;\n var sTapeName = Str.getBaseName(sTapePath, true);\n /*\n * TODO: Provide a way to mount tapes into MEMORY as well as READER.\n */\n pc11.loadSelectedTape(sTapeName, sTapePath, PC11.TARGET.READER, file);\n }\n /*\n * Prevent reloading of web page after form submission\n */\n return false;\n };\n return true;\n\n case PC11.BINDING.READ_PROGRESS:\n this.bindings[sBinding] = control;\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {PC11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.ram = /** @type {RAMPDP11} */ (cmp.getMachineComponent(\"RAM\"));\n\n var pc11 = this;\n\n var configMount = this.parseConfig(this.cmp.getMachineParm('autoMount'));\n\n /*\n * Add only devices from the machine-wide autoMount configuration that match devices managed by this component.\n */\n if (configMount) {\n for (var sDevice in configMount) {\n if (sDevice != this.sDevice) continue;\n this.configMount[sDevice] = configMount[sDevice];\n }\n }\n\n this.irqReader = this.cpu.addIRQ(PDP11.PC11.RVEC, PDP11.PC11.PRI, MessagesPDP11.PC11);\n\n this.timerReader = this.cpu.addTimer(function readyReader() {\n pc11.advanceReader();\n });\n\n bus.addIOTable(this, PC11.UNIBUS_IOTABLE);\n bus.addResetHandler(this.reset.bind(this));\n\n this.addTape(\"None\", PC11.SOURCE.NONE, true);\n if (this.fLocalTapes) this.addTape(\"Local Tape\", PC11.SOURCE.LOCAL);\n this.addTape(\"Remote Tape\", PC11.SOURCE.REMOTE);\n\n if (!this.autoMount()) this.setReady();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {PC11}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {PC11}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * TODO: Consider making our reset() handler ALSO restore the original loaded tape, in much the same\n * way the RAM component now restores the original predefined memory or tape image after resetting the RAM.\n *\n * @this {PC11}\n */\n reset()\n {\n this.regPRS &= ~PDP11.PC11.PRS.CLEAR;\n this.regPRB = 0;\n }\n\n /**\n * autoMount(fRemount)\n *\n * @this {PC11}\n * @param {boolean} [fRemount] is true if we're remounting all auto-mounted tapes\n * @return {boolean} true if one or more tape images are being auto-mounted, false if none\n */\n autoMount(fRemount)\n {\n if (!fRemount) this.cAutoMount = 0;\n var configMount = this.configMount[this.sDevice];\n if (configMount) {\n var sTapePath = configMount['path'] || \"\";\n var sTapeName = configMount['name'] || this.findTape(sTapePath);\n if (sTapePath && sTapeName) {\n /*\n * TODO: Provide a way to autoMount tapes into MEMORY as well as READER.\n */\n if (!this.loadTape(sTapeName, sTapePath, PC11.TARGET.READER, true) && fRemount) {\n this.setReady(false);\n }\n } else {\n /*\n * This likely happened because there was no autoMount setting (or it was overridden with an empty value),\n * so just make sure the current selection is set to \"None\".\n */\n this.displayTape();\n }\n }\n return !!this.cAutoMount;\n }\n\n /**\n * loadSelectedTape(sTapeName, sTapePath, nTapeTarget, file)\n *\n * @this {PC11}\n * @param {string} sTapeName\n * @param {string} sTapePath\n * @param {number} nTapeTarget\n * @param {File} [file] is set if there's an associated File object\n */\n loadSelectedTape(sTapeName, sTapePath, nTapeTarget, file)\n {\n if (!sTapePath) {\n this.unloadTape(false);\n return;\n }\n\n if (sTapePath == PC11.SOURCE.LOCAL) {\n this.notice('Use \"Choose File\" and \"Mount\" to select and load a local tape.');\n return;\n }\n\n /*\n * If the special PC11.SOURCE.REMOTE path is selected, then we want to prompt the user for a URL.\n * Oh, and make sure we pass an empty string as the 2nd parameter to prompt(), so that IE won't display\n * \"undefined\" -- because after all, undefined and \"undefined\" are EXACTLY the same thing, right?\n *\n * TODO: This is literally all I've done to support remote tape images. There's probably more\n * I should do, like dynamically updating \"listTapes\" to include new entries, and adding new entries\n * to the save/restore data.\n */\n if (sTapePath == PC11.SOURCE.REMOTE) {\n sTapePath = window.prompt(\"Enter the URL of a remote tape image.\", \"\") || \"\";\n if (!sTapePath) return;\n sTapeName = Str.getBaseName(sTapePath);\n this.status(\"Attempting to load \" + sTapePath + \" as \\\"\" + sTapeName + \"\\\"\");\n this.sTapeSource = PC11.SOURCE.REMOTE;\n }\n else {\n this.sTapeSource = sTapePath;\n }\n\n this.loadTape(sTapeName, sTapePath, nTapeTarget, false, file);\n }\n\n /**\n * loadTape(sTapeName, sTapePath, nTapeTarget, fAutoMount, file)\n *\n * NOTE: If sTapePath is already loaded, nothing needs to be done.\n *\n * @this {PC11}\n * @param {string} sTapeName\n * @param {string} sTapePath\n * @param {number} nTapeTarget\n * @param {boolean} [fAutoMount]\n * @param {File} [file] is set if there's an associated File object\n * @return {number} 1 if tape loaded, 0 if queued up (or busy), -1 if already loaded\n */\n loadTape(sTapeName, sTapePath, nTapeTarget, fAutoMount, file)\n {\n var nResult = -1;\n\n if (this.sTapePath.toLowerCase() != sTapePath.toLowerCase() || this.nTapeTarget != nTapeTarget) {\n\n nResult++;\n this.unloadTape(true);\n\n if (this.flags.busy) {\n this.notice(\"PC11 busy\");\n }\n else {\n // this.status(\"tape queued: \" + sTapeName);\n if (fAutoMount) {\n this.cAutoMount++;\n if (this.messageEnabled()) this.printMessage(\"auto-loading tape: \" + sTapeName);\n }\n if (this.load(sTapeName, sTapePath, nTapeTarget, file)) {\n nResult++;\n } else {\n this.flags.busy = true;\n }\n }\n }\n if (nResult) {\n /*\n * Now that we're calling parseTape() again (so that the current tape can either be restarted on\n * the reader or reloaded into RAM), we can also rely on it to display an appropriate status message, too.\n *\n * this.status(this.nTapeTarget == PC11.TARGET.READER? \"tape loaded\" : \"tape read\");\n */\n this.parseTape(this.sTapeName, this.sTapePath, this.nTapeTarget, this.aBytes, this.addrLoad, this.addrExec);\n }\n return nResult;\n }\n\n /**\n * load(sTapeName, sTapePath, nTapeTarget, file)\n *\n * @this {PC11}\n * @param {string} sTapeName\n * @param {string} sTapePath\n * @param {number} nTapeTarget\n * @param {File} [file] is set if there's an associated File object\n * @return {boolean} true if load completed (successfully or not), false if queued\n */\n load(sTapeName, sTapePath, nTapeTarget, file)\n {\n var pc11 = this;\n var sTapeURL = sTapePath;\n\n if (DEBUG) {\n var sMessage = 'load(\"' + sTapeName + '\",\"' + sTapePath + '\")';\n this.printMessage(sMessage);\n }\n\n if (file) {\n var reader = new FileReader();\n reader.onload = function doneRead() {\n pc11.finishRead(sTapeName, sTapePath, nTapeTarget, reader.result);\n };\n reader.readAsArrayBuffer(file);\n return false;\n }\n\n /*\n * If there's an occurrence of API_ENDPOINT anywhere in the path, we assume we can use it as-is;\n * ie, that the user has already formed a URL of the type we use ourselves for unconverted tape images.\n */\n if (sTapePath.indexOf(DumpAPI.ENDPOINT) < 0) {\n /*\n * If the selected tape image has a \"json\" extension, then we assume it's a pre-converted\n * JSON-encoded tape image, so we load it as-is; otherwise, we ask our server-side tape image\n * converter to return the corresponding JSON-encoded data.\n */\n var sTapeExt = Str.getExtension(sTapePath);\n if (sTapeExt == DumpAPI.FORMAT.JSON || sTapeExt == DumpAPI.FORMAT.JSON_GZ) {\n sTapeURL = encodeURI(sTapePath);\n } else {\n var sTapeParm = DumpAPI.QUERY.PATH;\n sTapeURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + sTapeParm + '=' + encodeURIComponent(sTapePath) + \"&\" + DumpAPI.QUERY.FORMAT + \"=\" + DumpAPI.FORMAT.JSON;\n }\n }\n\n return !!Web.getResource(sTapeURL, null, true, function doneLoad(sURL, sResponse, nErrorCode) {\n pc11.finishLoad(sTapeName, sTapePath, nTapeTarget, sResponse, sURL, nErrorCode);\n });\n }\n\n /**\n * finishLoad(sTapeName, sTapePath, sTapeData, nTapeTarget, sURL, nErrorCode)\n *\n * @this {PC11}\n * @param {string} sTapeName\n * @param {string} sTapePath\n * @param {string} sTapeData\n * @param {number} nTapeTarget\n * @param {string} sURL\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n finishLoad(sTapeName, sTapePath, nTapeTarget, sTapeData, sURL, nErrorCode)\n {\n var fPrintOnly = (nErrorCode < 0 && !!this.cmp && !this.cmp.flags.powered);\n\n if (nErrorCode) {\n /*\n * This can happen for innocuous reasons, such as the user switching away too quickly, forcing\n * the request to be cancelled. And unfortunately, the browser cancels XMLHttpRequest requests\n * BEFORE it notifies any page event handlers, so if the Computer's being powered down, we won't know\n * that yet. For now, we rely on the lack of a specific error (nErrorCode < 0), and suppress the\n * notify() alert if there's no specific error AND the computer is not powered up yet.\n */\n this.notice(\"Unable to load tape \\\"\" + sTapeName + \"\\\" (error \" + nErrorCode + \": \" + sURL + \")\", fPrintOnly);\n }\n else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage('finishLoad(\"' + sTapePath + '\")');\n }\n Component.addMachineResource(this.idMachine, sURL, sTapeData);\n var resource = Web.parseMemoryResource(sURL, sTapeData);\n if (resource) {\n this.parseTape(sTapeName, sTapePath, nTapeTarget, resource.aBytes, resource.addrLoad, resource.addrExec);\n }\n }\n this.flags.busy = false;\n if (this.cAutoMount) {\n this.cAutoMount--;\n if (!this.cAutoMount) this.setReady();\n }\n this.displayTape();\n }\n\n /**\n * finishRead(sTapeName, sTapePath, nTapeTarget, buffer)\n *\n * @this {PC11}\n * @param {string} sTapeName\n * @param {string} sTapePath\n * @param {number} nTapeTarget\n * @param {?} buffer (we KNOW this is an ArrayBuffer, but we can't seem to convince the Closure Compiler)\n */\n finishRead(sTapeName, sTapePath, nTapeTarget, buffer)\n {\n if (buffer) {\n var aBytes = new Uint8Array(buffer, 0, buffer.byteLength);\n this.parseTape(sTapeName, sTapePath, nTapeTarget, aBytes);\n this.sTapeSource = PC11.SOURCE.LOCAL;\n }\n this.flags.busy = false;\n this.displayTape();\n }\n\n /**\n * addTape(sName, sPath, fTop)\n *\n * @this {PC11}\n * @param {string} sName\n * @param {string} sPath\n * @param {boolean} [fTop] (default is bottom)\n */\n addTape(sName, sPath, fTop)\n {\n var controlTapes = this.bindings[\"listTapes\"];\n if (controlTapes && controlTapes.options) {\n for (var i = 0; i < controlTapes.options.length; i++) {\n if (controlTapes.options[i].value == sPath) return;\n }\n var controlOption = document.createElement(\"option\");\n controlOption.text = sName;\n controlOption.value = sPath;\n if (fTop && controlTapes.childNodes[0]) {\n controlTapes.insertBefore(controlOption, controlTapes.childNodes[0]);\n } else {\n controlTapes.appendChild(controlOption);\n }\n }\n }\n\n /**\n * findTape(sPath)\n *\n * This is used to deal with mount requests (eg, autoMount) that supply a path without a name;\n * if we can find the path in the \"listTapes\" control, then we return the associated tape name.\n *\n * @this {PC11}\n * @param {string} sPath\n * @return {string|null}\n */\n findTape(sPath)\n {\n var controlTapes = this.bindings[\"listTapes\"];\n if (controlTapes && controlTapes.options) {\n for (var i = 0; i < controlTapes.options.length; i++) {\n var control = controlTapes.options[i];\n if (control.value == sPath) return control.text;\n }\n }\n return Str.getBaseName(sPath, true);\n }\n\n /**\n * displayTape()\n *\n * @this {PC11}\n */\n displayTape()\n {\n var controlTapes = this.bindings[\"listTapes\"];\n if (controlTapes && controlTapes.options) {\n var sTargetPath = this.sTapeSource || this.sTapePath;\n for (var i = 0; i < controlTapes.options.length; i++) {\n if (controlTapes.options[i].value == sTargetPath) {\n if (controlTapes.selectedIndex != i) {\n controlTapes.selectedIndex = i;\n }\n break;\n }\n }\n if (i == controlTapes.options.length) controlTapes.selectedIndex = 0;\n }\n }\n\n /**\n * displayProgress(nPercent)\n *\n * @this {PC11}\n * @param {number} nPercent\n */\n displayProgress(nPercent)\n {\n nPercent |= 0;\n if (nPercent !== this.nLastPercent) {\n var control = this.bindings[PC11.BINDING.READ_PROGRESS];\n if (control) {\n var aeControls = Component.getElementsByClass(control, PC11.CSSCLASS.PROGRESS_BAR);\n var controlBar = aeControls && aeControls[0];\n if (controlBar && controlBar.style) {\n controlBar.style.width = nPercent + \"%\";\n }\n }\n this.nLastPercent = nPercent;\n }\n }\n\n /**\n * parseTape(sTapeName, sTapePath, nTapeTarget, aBytes, addrLoad, addrExec)\n *\n * @this {PC11}\n * @param {string} sTapeName\n * @param {string} sTapePath\n * @param {number} nTapeTarget\n * @param {Array|Uint8Array} aBytes\n * @param {number|null} [addrLoad]\n * @param {number|null} [addrExec]\n */\n parseTape(sTapeName, sTapePath, nTapeTarget, aBytes, addrLoad, addrExec)\n {\n this.sTapeName = sTapeName;\n this.sTapePath = sTapePath;\n this.nTapeTarget = nTapeTarget;\n this.aBytes = aBytes;\n this.addrLoad = addrLoad;\n this.addrExec = addrExec;\n\n if (nTapeTarget == PC11.TARGET.MEMORY) {\n /*\n * Use the RAM component's loadImage() service to do our dirty work. If the load succeeds, then\n * depending on whether there was also exec address, either the CPU will be stopped or the PC wil be\n * reset.\n *\n * NOTE: Some tapes are not in the Absolute Loader format, so if the JSON-encoded tape resource file\n * we downloaded didn't ALSO include a load address, the load will fail.\n *\n * For example, the \"Absolute Loader\" tape is NOT itself in the Absolute Loader format. You just have\n * to know that in order to load that tape, you must first load the appropriate \"Bootstrap Loader\" (which\n * DOES include its own hard-coded load address), load the \"Absolute Loader\" tape, and then run the\n * \"Bootstrap Loader\".\n */\n if (!this.ram || !this.ram.loadImage(aBytes, addrLoad, addrExec, null, false)) {\n /*\n * This doesn't seem to serve any purpose, other than to be annoying, because perhaps you accidentally\n * clicked \"Read\" instead of \"Load\"....\n *\n * this.sTapeName = \"\";\n * this.sTapePath = \"\";\n * this.sTapeSource = PC11.SOURCE.NONE;\n * this.nTapeTarget = PC11.TARGET.NONE;\n */\n this.notice('No valid memory address for tape \"' + sTapeName + '\"');\n return;\n }\n this.status('Read tape \"' + sTapeName + '\"');\n return;\n }\n\n this.iTapeData = 0;\n this.aTapeData = aBytes;\n this.regPRS &= ~PDP11.PC11.PRS.ERROR;\n\n this.status('Loaded tape \"' + sTapeName + '\" (' + aBytes.length + \" bytes)\");\n this.displayProgress(0);\n }\n\n /**\n * unloadTape(fLoading)\n *\n * @this {PC11}\n * @param {boolean} [fLoading]\n */\n unloadTape(fLoading)\n {\n if (this.sTapePath || fLoading === false) {\n this.sTapeName = \"\";\n this.sTapePath = \"\";\n /*\n * Avoid any unnecessary hysteresis regarding the display if this unload is merely a prelude to another load.\n */\n if (!fLoading) {\n if (this.nTapeTarget) this.status(this.nTapeTarget == PC11.TARGET.READER? \"tape detached\" : \"tape unloaded\");\n this.sTapeSource = PC11.SOURCE.NONE;\n this.nTapeTarget = PC11.TARGET.NONE;\n this.displayTape();\n }\n }\n }\n\n /**\n * save()\n *\n * This implements save support for the PC11 component.\n *\n * @this {PC11}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the PC11 component.\n *\n * @this {PC11}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return true;\n }\n\n /**\n * getBaudTimeout(nBaud)\n *\n * Based on the selected baud rate (nBaud), convert that rate into a millisecond delay.\n *\n * @this {PC11}\n * @param {number} nBaud\n * @return {number} (number of milliseconds per byte)\n */\n getBaudTimeout(nBaud)\n {\n /*\n * TODO: Do a better job computing this, based on actual numbers of start, stop and parity bits,\n * instead of hard-coding the total number of bits per byte to 10.\n */\n var nBytesPerSecond = Math.round(nBaud / 10);\n return 1000 / nBytesPerSecond;\n }\n\n /**\n * advanceReader()\n *\n * If the reader is enabled (RE is set) and there is no exceptional condition (ie, ERROR is set),\n * and if the buffer register is empty (DONE is clear), then if we have more data in our internal buffer,\n * store it in the buffer register, and optionally trigger an interrupt if device interrupts are enabled.\n *\n * @this {PC11}\n */\n advanceReader()\n {\n if ((this.regPRS & (PDP11.PC11.PRS.RE | PDP11.PC11.PRS.ERROR)) == PDP11.PC11.PRS.RE) {\n if (!(this.regPRS & PDP11.PC11.PRS.DONE)) {\n if (this.iTapeData < this.aTapeData.length) {\n /*\n * Here, as elsewhere (eg, the DL11 component), even if I trusted all incoming data\n * to be byte values (which I don't), there's also the risk that it could be signed data\n * (eg, -128 to 127, instead of 0 to 255). Both risks are good reasons to always mask\n * the data assigned to PRB with 0xff.\n */\n this.regPRB = this.aTapeData[this.iTapeData] & 0xff;\n if (this.messageEnabled()) this.printMessage(this.type + \".advanceReader(\" + this.iTapeData + \"): \" + Str.toHexByte(this.regPRB), true);\n this.iTapeData++;\n this.displayProgress(this.iTapeData / this.aTapeData.length * 100);\n }\n else {\n this.regPRS |= PDP11.PC11.PRS.ERROR;\n }\n this.regPRS |= PDP11.PC11.PRS.DONE;\n this.regPRS &= ~PDP11.PC11.PRS.BUSY;\n if (this.regPRS & PDP11.PC11.PRS.IE) {\n this.cpu.setIRQ(this.irqReader);\n }\n }\n }\n }\n\n /**\n * readPRS(addr)\n *\n * NOTE: We use the PRS RMASK to honor the \"write-only\" behavior of bit 0, the reader enable bit (RE), because\n * DEC's tiny Bootstrap Loader (/apps/pdp11/boot/bootstrap/BOOTSTRAP-16KB.lst) repeatedly enables the reader using\n * the INC instruction, which causes the PRS to be read, incremented, and written, so if bit 0 isn't always read\n * as zero, the INC instruction would clear RE instead of setting it.\n *\n * @this {PC11}\n * @param {number} addr (eg, PDP11.UNIBUS.PRS or 177550)\n * @return {number}\n */\n readPRS(addr)\n {\n return this.regPRS & PDP11.PC11.PRS.RMASK; // RMASK honors the \"write-only\" nature of the RE bit by returning zero on reads\n }\n\n /**\n * writePRS(data, addr)\n *\n * @this {PC11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.PRS or 177550)\n */\n writePRS(data, addr)\n {\n if (data & PDP11.PC11.PRS.RE) {\n /*\n * From the 1976 Peripherals Handbook, p. 4-378:\n *\n * Set [RE] to allow the Reader to fetch one character. The setting of this bit clears Done,\n * sets Busy, and clears the Reader Buffer (PRB). Operation of this bit is disabled if Error = 1;\n * attempting to set it when Error = 1 will cause an immediate interrupt if Interrupt Enable = 1.\n */\n if (this.regPRS & PDP11.PC11.PRS.ERROR) {\n data &= ~PDP11.PC11.PRS.RE;\n if (this.regPRS & PDP11.PC11.PRS.IE) {\n this.cpu.setIRQ(this.irqReader);\n }\n } else {\n this.regPRS &= ~PDP11.PC11.PRS.DONE;\n this.regPRS |= PDP11.PC11.PRS.BUSY;\n this.regPRB = 0;\n /*\n * The PC11, by virtue of its \"high speed\", is supposed to deliver characters at 300 CPS, so\n * that's the rate we'll choose as well (ie, 1000ms / 300). As an aside, the original \"low speed\"\n * version of the reader ran at 10 CPS.\n */\n this.cpu.setTimer(this.timerReader, this.getBaudTimeout(this.nBaudReceive));\n }\n }\n this.regPRS = (this.regPRS & ~PDP11.PC11.PRS.WMASK) | (data & PDP11.PC11.PRS.WMASK);\n }\n\n /**\n * readPRB(addr)\n *\n * @this {PC11}\n * @param {number} addr (eg, PDP11.UNIBUS.PRB or 177552)\n * @return {number}\n */\n readPRB(addr)\n {\n /*\n * I'm guessing that the DONE and BUSY bits always remain more-or-less inverses of each other. They definitely\n * start out that way when writePRS() sets the reader enable (RE) bit, and so that's how we treat them elsewhere, too.\n */\n this.regPRS &= ~PDP11.PC11.PRS.DONE;\n this.regPRS |= PDP11.PC11.PRS.BUSY;\n return this.regPRB;\n }\n\n /**\n * writePRB(data, addr)\n *\n * @this {PC11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.PRB or 177552)\n */\n writePRB(data, addr)\n {\n }\n\n /**\n * readPPS(addr)\n *\n * @this {PC11}\n * @param {number} addr (eg, PDP11.UNIBUS.PPS or 177554)\n * @return {number}\n */\n readPPS(addr)\n {\n return this.regPPS;\n }\n\n /**\n * writePPS(data, addr)\n *\n * NOTE: This was originally added ONLY because when RT-11 v4.0 copies from device \"PC:\" (the paper tape reader),\n * it executes the following code:\n *\n * 016010: 005037 177550 CLR @#177550 ;history=2 PRS\n * 016014: 005037 177554 CLR @#177554 ;history=1\n *\n * and as you can see, without this PPS handler, a TRAP to 4 would normally occur. I guess since we claim to be\n * a PC11, that makes sense. But what about PDP-11 machines with only a PR11 (ie, a reader-only unit)?\n *\n * @this {PC11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.PPS or 177554)\n */\n writePPS(data, addr)\n {\n this.regPPS = (this.regPPS & ~PDP11.PC11.PPS.WMASK) | (data & PDP11.PC11.PPS.WMASK);\n }\n\n /**\n * readPPB(addr)\n *\n * @this {PC11}\n * @param {number} addr (eg, PDP11.UNIBUS.PPB or 177556)\n * @return {number}\n */\n readPPB(addr)\n {\n return this.regPPB;\n }\n\n /**\n * writePPB(data, addr)\n *\n * @this {PC11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.PPB or 177556)\n */\n writePPB(data, addr)\n {\n this.regPPB = (data & PDP11.PC11.PPB.MASK);\n }\n}\n\n/*\n * There's nothing super special about these values, except that NONE should be falsey and the others should not.\n */\nPC11.SOURCE = {\n NONE: \"\",\n LOCAL: \"?\",\n REMOTE: \"??\"\n};\n\nPC11.TARGET = {\n NONE: 0,\n READER: 1,\n MEMORY: 2\n};\n\nPC11.BINDING = {\n READ_PROGRESS: \"readProgress\"\n};\n\nPC11.CSSCLASS = {\n PROGRESS_BAR: PDP11.CSSCLASS + \"-progress-bar\"\n};\n\n/*\n * ES6 ALERT: As you can see below, I've finally started using computed property names.\n */\nPC11.UNIBUS_IOTABLE = {\n [PDP11.UNIBUS.PRS]: /* 177550 */ [null, null, PC11.prototype.readPRS, PC11.prototype.writePRS, \"PRS\"],\n [PDP11.UNIBUS.PRB]: /* 177552 */ [null, null, PC11.prototype.readPRB, PC11.prototype.writePRB, \"PRB\"],\n [PDP11.UNIBUS.PPS]: /* 177554 */ [null, null, PC11.prototype.readPPS, PC11.prototype.writePPS, \"PPS\"],\n [PDP11.UNIBUS.PPB]: /* 177556 */ [null, null, PC11.prototype.readPPB, PC11.prototype.writePPB, \"PPB\"]\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/disk.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * The DiskPDP11 component provides methods for:\n *\n * 1) creating an empty disk: create()\n * 2) loading a disk image: load()\n * 3) getting disk information: info()\n * 4) seeking a disk sector: seek()\n * 5) reading data from a sector: read()\n * 6) writing data to a sector: write()\n * 7) save disk deltas: save()\n * 8) restore disk deltas: restore()\n * 9) converting disk contents: convertToJSON()\n *\n * More functionality may be factored out of the disk controller components later and moved here,\n * to further reduce some of the duplication between them, but the above functionality is a good start.\n */\n\n\n/**\n * Every Sector object (once loaded, parsed, and \"normalized\") should have ALL of the following named properties:\n *\n * 'sector': sector number\n * 'length': size of the sector, in bytes\n * 'data': array of dwords\n * 'pattern': dword pattern to use for empty or partial sectors (or null if sector still needs to be loaded)\n *\n * initSector() also sets the following properties, to help us quickly identify its location within aDiskData:\n *\n * iCylinder\n * iHead\n *\n * In addition, we will maintain the following information on a per-sector basis, as sectors are modified:\n *\n * iModify: index of first modified dword in sector\n * cModify: number of modified dwords in sector\n * fDirty: true if sector is dirty, false if clean (or cleaning in progress)\n *\n * @typedef {{\n * sector: number,\n * length: number,\n * data: Array.<number>,\n * pattern: (number|null),\n * iCylinder: number,\n * iHead: number,\n * iModify: number,\n * cModify: number\n * }}\n */\nvar SectorInfo;\n\nclass DiskPDP11 extends Component {\n /**\n * DiskPDP11(controller, drive, mode)\n *\n * Disk contents are stored as an array (aDiskData) of cylinders, each of which is an array of\n * heads, each of which is an array of sector objects; the latter contain sector numbers and\n * sector data, where sector data is an array of dwords. The format does not impose any\n * limitations on number of cylinders, number of heads, sectors per track, or bytes per sector.\n *\n * WARNING: All accesses to disk sector properties must be via their string names, not their\n * \"dot\" names, otherwise code will break after it's been processed by the Closure Compiler,\n * and any dumped disks may be unmountable. This is a side-effect of how we mount and dump\n * disk images (ie, as JSON-encoded streams).\n *\n * This means, for example, that all references to \"track[iSector].data\" must actually appear as\n * \"track[iSector]['data']\".\n *\n * @param {DriveController|RK11|RL11} controller\n * @param {Object} drive\n * @param {string} mode\n */\n constructor(controller, drive, mode)\n {\n super(\"Disk\", {'id': controller.idMachine + \".disk\" + Str.toHex(++DiskPDP11.nDisks, 4)}, MessagesPDP11.DISK);\n\n /*\n * Route all non-Debugger messages (eg, notice() and println() calls) through\n * this.controller (eg, controller.notice() and controller.println()), because\n * the Computer component is unaware of any Disk objects and therefore will not\n * set up the usual overrides when a Control Panel is installed.\n */\n this.controller = controller;\n this.cmp = controller.cmp;\n this.dbg = controller.dbg;\n this.drive = drive;\n\n /*\n * We pull out a number of drive properties that we may or may not need as defaults.\n */\n this.sDiskName = drive.name;\n this.sDiskPath = this.sDiskFile = \"\";\n this.fRemovable = drive.fRemovable;\n\n /*\n * Initialize the disk contents\n */\n this.mode = 0;\n this.nCylinders = this.nHeads = this.nSectors = this.cbSector = 0;\n this.aDiskData = [];\n this.dwChecksum = null;\n this.fWriteProtected = false;\n this.create(mode, drive.nCylinders, drive.nHeads, drive.nSectors, drive.cbSector);\n\n this.fnNotify = this.controllerNotify = null;\n\n this.setReady();\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * We have no real interest in this notification, other than to obtain a reference to the Debugger\n * for every disk loaded BEFORE the initBus() phase; any disk loaded AFTER that point will get its Debugger\n * reference, if any, from the disk controller passed to the DiskPDP11() constructor.\n *\n * @this {DiskPDP11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.dbg = dbg;\n }\n\n /**\n * create()\n *\n * @this {DiskPDP11}\n * @param {string} mode\n * @param {number} nCylinders\n * @param {number} nHeads\n * @param {number} nSectors (per track)\n * @param {number} cbSector\n *\n * Initializes the disk contents according to the current drive mode and parameters.\n */\n create(mode, nCylinders, nHeads, nSectors, cbSector)\n {\n this.mode = mode;\n this.nCylinders = nCylinders;\n this.nHeads = nHeads;\n this.nSectors = nSectors;\n this.cbSector = cbSector;\n this.aDiskData = [];\n /*\n * If the drive is using PRELOAD mode, then it will use the load()/mount() process to initialize the disk contents;\n * it wouldn't hurt to let create() do its thing, too, but it's a waste of time.\n */\n if (this.mode != DiskAPI.MODE.PRELOAD) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"blank disk for \\\"\" + this.sDiskName + \"\\\": \" + this.nCylinders + \" cylinders, \" + this.nHeads + \" head(s)\");\n }\n var aCylinders = new Array(this.nCylinders);\n for (var iCylinder = 0; iCylinder < aCylinders.length; iCylinder++) {\n var aHeads = new Array(this.nHeads);\n for (var iHead = 0; iHead < aHeads.length; iHead++) {\n var aSectors = new Array(this.nSectors);\n for (var iSector = 1; iSector <= aSectors.length; iSector++) {\n /*\n * Now that our read() and write() functions can deal with unallocated data\n * arrays, and can read/write the specified pattern on-the-fly, we no longer need\n * to pre-allocate and pre-initialize the 'data' array.\n */\n aSectors[iSector - 1] = this.initSector(null, iCylinder, iHead, iSector, this.cbSector, 0);\n }\n aHeads[iHead] = aSectors;\n }\n aCylinders[iCylinder] = aHeads;\n }\n this.aDiskData = aCylinders;\n }\n this.dwChecksum = null;\n }\n\n /**\n * load(sDiskName, sDiskPath, file, fnNotify)\n *\n * TODO: Figure out how we can strongly type fnNotify, because the Closure Compiler has issues with:\n *\n * param {function(Component,Object,Disk,string,string)} fnNotify\n *\n * for:\n *\n * this.fnNotify.call(this.controller, this.drive, disk, this.sDiskName, this.sDiskPath);\n *\n * Also, while we're at it, learn if there are ways to:\n *\n * 1) declare a function taking NO parameters (ie, generate a warning if any parameters are specified)\n * 2) declare a type for a function's return value\n *\n * @this {DiskPDP11}\n * @param {string} sDiskName\n * @param {string} sDiskPath\n * @param {File} [file] is set if there's an associated File object\n * @param {function(...)} [fnNotify]\n * @param {Component} [controller]\n * @return {boolean} true if load completed (successfully or not), false if queued\n */\n load(sDiskName, sDiskPath, file, fnNotify, controller)\n {\n var sDiskURL = sDiskPath;\n\n /*\n * We could use this.log() as well, but it wouldn't display which component initiated the load.\n */\n if (DEBUG) {\n var sMessage = 'load(\"' + sDiskName + '\",\"' + sDiskPath + '\")';\n this.controller.log(sMessage);\n this.printMessage(sMessage);\n }\n\n if (this.fnNotify) {\n if (DEBUG) this.controller.log('too many load requests for \"' + sDiskName + '\" (' + sDiskPath + ')');\n return true;\n }\n\n this.sDiskName = sDiskName;\n this.sDiskPath = sDiskPath;\n this.sDiskFile = Str.getBaseName(sDiskPath);\n\n var disk = this;\n this.fnNotify = fnNotify;\n this.controllerNotify = controller || this.controller;\n\n if (file) {\n var reader = new FileReader();\n reader.onload = function() {\n disk.build(reader.result, true);\n };\n reader.readAsArrayBuffer(file);\n return true;\n }\n\n /*\n * If there's an occurrence of API_ENDPOINT anywhere in the path, we assume we can use it as-is;\n * ie, that the user has already formed a URL of the type we use ourselves for unconverted disk images.\n */\n if (sDiskPath.indexOf(DumpAPI.ENDPOINT) < 0) {\n /*\n * If the selected disk image has a \"json\" extension, then we assume it's a pre-converted\n * JSON-encoded disk image, so we load it as-is; otherwise, we ask our server-side disk image\n * converter to return the corresponding JSON-encoded data.\n */\n var sDiskExt = Str.getExtension(sDiskPath);\n if (sDiskExt == DumpAPI.FORMAT.JSON || sDiskExt == DumpAPI.FORMAT.JSON_GZ) {\n sDiskURL = encodeURI(sDiskPath);\n } else {\n var sDiskParm = DumpAPI.QUERY.PATH;\n var sSizeParm = '&' + DumpAPI.QUERY.MBHD + \"=10\";\n /*\n * 'mbhd' is a new parm added for hard drive support. In the case of 'file' or 'dir' requests,\n * 'mbhd' informs DumpAPI.ENDPOINT that it should create a hard disk image, and one not larger than\n * the specified size (eg, 10mb). In fact, until DumpAPI.ENDPOINT is changed to create custom hard\n * disk BPBs, you'll always get a standard PC XT 10mb disk image, so if the 'file' or 'dir' contains\n * more than 10mb of data, the request will fail. Ultimately, I want to honor the controller's\n * driveConfig 'size' parm, or to match the capacity required by the driveConfig 'type' parameter.\n *\n * If a 'disk' is specified, we pass mbhd=0, because the actual size will depend on the image.\n * However, I don't currently have any \"dsk\" or \"img\" files containing hard disk images; those formats\n * were really intended for floppy disk images. If I never create any hard disk image files, then\n * we can simply eliminate sSizeParm in the 'disk' case.\n *\n * Added more extensions to the list of paths-treated-as-disk-images, so that URLs to files located here:\n *\n * ftp://ftp.oldskool.org/pub/TOPBENCH/dskimage/\n *\n * can be used as-is. TODO: There's a TODO in netlib.getFile() regarding remote support that needs\n * to be resolved first; DiskDump relies on that function for its remote requests, and it currently\n * supports only HTTP.\n */\n if (!sDiskPath.indexOf(\"http:\") || !sDiskPath.indexOf(\"ftp:\") || [\"dsk\", \"ima\", \"img\", \"360\", \"720\", \"12\", \"144\"].indexOf(sDiskExt) >= 0) {\n sDiskParm = DumpAPI.QUERY.DISK;\n sSizeParm = '&' + DumpAPI.QUERY.MBHD + \"=0\";\n } else if (Str.endsWith(sDiskPath, '/')) {\n sDiskParm = DumpAPI.QUERY.DIR;\n }\n sDiskURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + sDiskParm + '=' + encodeURIComponent(sDiskPath) + (this.fRemovable ? \"\" : sSizeParm) + \"&\" + DumpAPI.QUERY.FORMAT + \"=\" + DumpAPI.FORMAT.JSON;\n }\n }\n return !!Web.getResource(sDiskURL, null, true, function(sURL, sResponse, nErrorCode) {\n disk.doneLoad(sURL, sResponse, nErrorCode);\n });\n }\n\n /**\n * build(buffer, fModified)\n *\n * Builds a disk image from an ArrayBuffer (eg, from a FileReader object), rather than from JSON-encoded data.\n *\n * @this {DiskPDP11}\n * @param {?} buffer (we KNOW this is an ArrayBuffer, but we can't seem to convince the Closure Compiler)\n * @param {boolean} [fModified] is true if we should mark the entire disk modified (to ensure that we save/restore it)\n */\n build(buffer, fModified)\n {\n var disk;\n var cbDiskData = buffer? buffer.byteLength : 0;\n var diskFormat = DiskAPI.GEOMETRIES[cbDiskData];\n\n if (diskFormat) {\n this.nCylinders = diskFormat[0];\n this.nHeads = diskFormat[1];\n this.nSectors = diskFormat[2];\n this.cbSector = (diskFormat[3] || 512);\n\n var cdw = this.cbSector >> 2, dwPattern = 0, dwChecksum = 0;\n var ib = 0;\n var dv = new DataView(buffer, 0, cbDiskData);\n\n this.aDiskData = new Array(this.nCylinders);\n for (var iCylinder = 0; iCylinder < this.aDiskData.length; iCylinder++) {\n var cylinder = this.aDiskData[iCylinder] = new Array(this.nHeads);\n for (var iHead = 0; iHead < cylinder.length; iHead++) {\n var head = cylinder[iHead] = new Array(this.nSectors);\n for (var iSector = 0; iSector < head.length; iSector++) {\n var sector = this.initSector(null, iCylinder, iHead, iSector + 1, this.cbSector, dwPattern);\n var adw = sector['data'];\n for (var idw = 0; idw < cdw; idw++, ib += 4) {\n var dw = adw[idw] = dv.getInt32(ib, true);\n dwChecksum = (dwChecksum + dw) & (0xffffffff|0);\n }\n if (fModified) sector.cModify = cdw;\n head[iSector] = sector;\n }\n }\n }\n this.dwChecksum = dwChecksum;\n disk = this;\n } else {\n this.notice(\"Unrecognized disk format (\" + cbDiskData + \" bytes)\");\n }\n\n if (this.fnNotify) {\n this.fnNotify.call(this.controller, this.drive, disk, this.sDiskName, this.sDiskPath);\n this.fnNotify = null;\n }\n }\n\n /**\n * doneLoad(sURL, sDiskData, nErrorCode)\n *\n * This function was originally called mount(). If the mount is successful, we pass the Disk object to the\n * caller's fnNotify handler; otherwise, we pass null.\n *\n * @this {DiskPDP11}\n * @param {string} sURL\n * @param {string|null} sDiskData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n doneLoad(sURL, sDiskData, nErrorCode)\n {\n var disk = null;\n var fPrintOnly = (nErrorCode < 0 && !!this.cmp && !this.cmp.flags.powered);\n\n this.fWriteProtected = false;\n\n if (nErrorCode) {\n /*\n * This can happen for innocuous reasons, such as the user switching away too quickly, forcing\n * the request to be cancelled. And unfortunately, the browser cancels XMLHttpRequest requests\n * BEFORE it notifies any page event handlers, so if the Computer's being powered down, we won't know\n * that yet. For now, we rely on the lack of a specific error (nErrorCode < 0), and suppress the\n * notify() alert if there's no specific error AND the computer is not powered up yet.\n */\n this.controller.notice(\"Unable to load disk \\\"\" + this.sDiskName + \"\\\" (error \" + nErrorCode + \": \" + sURL + \")\", fPrintOnly);\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage('doneLoad(\"' + this.sDiskPath + '\")');\n }\n\n Component.addMachineResource(this.controller.idMachine, sURL, sDiskData);\n\n try {\n /*\n * The following code was a hack to turn on write-protection for a disk image if there was\n * an initial comment line containing the string \"write-protected\". However, since comments\n * are technically not allowed in JSON, I needed an alternative solution. So, if the basename\n * contains the suffix \"-readonly\", then I'll turn on write-protection for that disk as well.\n *\n * TODO: Provide some UI for turning write-protection on/off for disks at will, and provide\n * an XML-based solution (ie, a per-disk XML configuration option) for controlling it as well.\n */\n var sBaseName = Str.getBaseName(this.sDiskFile, true).toLowerCase();\n if (sBaseName.indexOf(\"-readonly\") > 0) {\n this.fWriteProtected = true;\n } else {\n var iEOL = sDiskData.indexOf(\"\\n\");\n if (iEOL > 0 && iEOL < 1024) {\n var sConfig = sDiskData.substring(0, iEOL);\n if (sConfig.indexOf(\"write-protected\") > 0) {\n this.fWriteProtected = true;\n }\n }\n }\n /*\n * The most likely source of any exception will be here, where we're parsing the disk data.\n */\n var aDiskData;\n if (sDiskData.substr(0, 1) == \"<\") { // if the \"data\" begins with a \"<\"...\n /*\n * Early server configs reported an error (via the nErrorCode parameter) if a disk URL was invalid,\n * but more recent server configs now display a somewhat friendlier HTML error page. The downside,\n * however, is that the original error has been buried, and we've received \"data\" that isn't actually\n * disk data.\n *\n * So, if the data we've received appears to be \"HTML-like\", all we can really do is assume that the\n * disk image is missing. And so we pretend we received an error message to that effect.\n */\n aDiskData = [\"Missing disk image: \" + this.sDiskName];\n } else {\n /*\n * TODO: IE9 is rather unfriendly and restrictive with regard to how much data it's willing to\n * eval(). In particular, the 10Mb disk image we use for the Windows 1.01 demo config fails in\n * IE9 with an \"Out of memory\" exception. One work-around would be to chop the data into chunks\n * (perhaps one track per chunk, using regular expressions) and then manually re-assemble it.\n *\n * However, it turns out that using JSON.parse(sDiskData) instead of eval(\"(\" + sDiskData + \")\")\n * is a much easier fix. The only drawback is that we must first quote any unquoted property names\n * and remove any comments, because while eval() was cool with them, JSON.parse() is more particular;\n * the following RegExp replacements take care of those requirements.\n *\n * The use of hex values is something else that eval() was OK with, but JSON.parse() is not, and\n * while I've stopped using hex values in DumpAPI responses (at least when \"format=json\" is specified),\n * I can't guarantee they won't show up in \"legacy\" images, and there's no simple RegExp replacement\n * for transforming hex values into decimal values, so I cop out and fall back to eval() if I detect\n * any hex prefixes (\"0x\") in the sequence. Ditto for error messages, which appear like so:\n *\n * [\"unrecognized disk path: test.img\"]\n */\n if (sDiskData.indexOf(\"0x\") < 0 && sDiskData.substr(0, 2) != \"[\\\"\") {\n aDiskData = JSON.parse(sDiskData.replace(/([a-z]+):/gm, \"\\\"$1\\\":\").replace(/\\/\\/[^\\n]*/gm, \"\"));\n } else {\n aDiskData = eval(\"(\" + sDiskData + \")\");\n }\n }\n\n if (!aDiskData.length) {\n Component.error(\"Empty disk image: \" + this.sDiskName);\n }\n else if (aDiskData.length == 1) {\n Component.error(aDiskData[0]);\n }\n /*\n * aDiskData is an array of cylinders, each of which is an array of heads, each of which\n * is an array of sector objects. The format does not impose any limitations on number of\n * cylinders, number of heads, or number of bytes in any of the sector object byte-arrays.\n *\n * WARNING: All accesses to sector object properties must be via their string names, not their\n * \"dot\" names, otherwise code will break after it's been processed by the Closure Compiler.\n *\n * Sector object properties include:\n *\n * 'sector' the sector number (1-based, not required to be sequential)\n * 'length' the byte-length (ie, formatted length) of the sector\n * 'data' the dword-array containing the sector data\n * 'pattern' if the dword-array length is less than 'length'/4, this value must be used\n * to pad out the sector; if no 'pattern' is specified, it's assumed to be zero\n *\n * We still support the older JSON encoding, where sector data was encoded as an array of 'bytes'\n * rather than a dword 'data' array. However, our support is strictly limited to an on-the-fly\n * conversion to a forward-compatible 'data' array.\n */\n else {\n if (DEBUG && this.messageEnabled(MessagesPDP11.DISK | MessagesPDP11.BUFFER)) {\n var sCylinders = aDiskData.length + \" track\" + (aDiskData.length > 1 ? \"s\" : \"\");\n var nHeads = aDiskData[0].length;\n var sHeads = nHeads + \" head\" + (nHeads > 1 ? \"s\" : \"\");\n var nSectorsPerTrack = aDiskData[0][0].length;\n var sSectorsPerTrack = nSectorsPerTrack + \" sector\" + (nSectorsPerTrack > 1 ? \"s\" : \"\") + \"/track\";\n this.printMessage(sCylinders + \", \" + sHeads + \", \" + sSectorsPerTrack);\n }\n /*\n * Before the image is usable, we must \"normalize\" all the sectors. In the past, this meant\n * \"inflating\" them all. However, that's no longer strictly necessary. Mainly, it just means\n * setting 'length', 'data', and 'pattern' properties, so that all the sectors are well-defined.\n * This includes detecting sector data in older formats (eg, the old array of 'bytes' instead\n * of the new 'data' array of dwords) and converting them on-the-fly to the current format.\n */\n this.nCylinders = aDiskData.length;\n this.nHeads = aDiskData[0].length;\n this.nSectors = aDiskData[0][0].length;\n var sector = aDiskData[0][0][0];\n this.cbSector = (sector && sector['length']) || 512;\n\n var dwChecksum = 0;\n for (var iCylinder = 0; iCylinder < this.nCylinders; iCylinder++) {\n for (var iHead = 0; iHead < this.nHeads; iHead++) {\n for (var iSector = 0; iSector < this.nSectors; iSector++) {\n sector = aDiskData[iCylinder][iHead][iSector];\n if (!sector) continue; // non-standard (eg, XDF) disk images may have \"unused\" (null) sectors\n var length = sector['length'];\n if (length === undefined) { // provide backward-compatibility with older JSON...\n length = sector['length'] = 512;\n }\n length >>= 2; // convert length from a byte-length to a dword-length\n var dwPattern = sector['pattern'];\n if (dwPattern === undefined) {\n dwPattern = sector['pattern'] = 0;\n }\n var adw = sector['data'];\n if (adw === undefined) {\n var ab = sector['bytes'];\n if (ab === undefined || !ab.length) {\n /*\n * It would be odd if there was neither a 'bytes' nor 'data' array; I'm just\n * being paranoid. It's more likely that the 'bytes' array is simply empty,\n * in which case we need only create an empty 'data' array and turn the byte\n * pattern, if any, into a dword pattern.\n */\n adw = [];\n\n dwPattern = sector['pattern'] = (dwPattern | (dwPattern << 8) | (dwPattern << 16) | (dwPattern << 24));\n sector['data'] = adw;\n } else {\n /*\n * To keep the conversion code simple, we'll do any necessary pattern-filling first,\n * to fully \"inflate\" the sector, eliminating the possibility of partial dwords and\n * saving any code downstream from dealing with byte-size patterns.\n */\n var cb = length << 2;\n for (var ib = ab.length; ib < cb; ib++) {\n ab[ib] = dwPattern; // the pattern for byte-arrays was only a byte\n }\n this.fill(sector, ab, 0);\n }\n delete sector['bytes'];\n }\n this.initSector(sector, iCylinder, iHead);\n /*\n * For the disk as a whole, we maintain a checksum of the original unmodified data:\n *\n * dwChecksum: summation of all dwords in all non-empty sectors\n *\n * Pattern-filling of sectors is deferred until absolutely necessary (eg, when a sector is\n * being written). So all we need to do at this point is checksum all the initial sector data.\n */\n for (var idw = 0; idw < adw.length; idw++) {\n dwChecksum = (dwChecksum + adw[idw]) & (0xffffffff|0);\n }\n }\n }\n }\n this.aDiskData = aDiskData;\n this.dwChecksum = dwChecksum;\n disk = this;\n }\n } catch (e) {\n Component.error(\"Disk image error (\" + sURL + \"): \" + e.message);\n }\n }\n\n if (this.fnNotify) {\n this.fnNotify.call(this.controllerNotify, this.drive, disk, this.sDiskName, this.sDiskPath);\n this.fnNotify = null;\n }\n }\n\n /**\n * getSectorString(sector, off, len)\n *\n * WARNING: This function is restricted to reading a string contained ENTIRELY within the specified sector.\n *\n * @this {DiskPDP11}\n * @param {Object} sector\n * @param {number} off (byte offset)\n * @param {number} len (use -1 to read a null-terminated string)\n * @return {string}\n */\n getSectorString(sector, off, len)\n {\n var s = \"\";\n while (len--) {\n var b = this.read(sector, off++);\n if (b <= 0) break;\n s += String.fromCharCode(b);\n }\n return s;\n }\n\n /**\n * initSector(sector, iCylinder, iHead, iSector, cbSector, dwPattern)\n *\n * Ensures every sector has ALL the properties of a proper Sector object; ie:\n *\n * 'sector': sector number\n * 'length': size of the sector, in bytes\n * 'data': array of dwords\n * 'pattern': dword pattern to use for empty or partial sectors\n *\n * In addition, we will maintain the following information on a per-sector basis,\n * as sectors are modified:\n *\n * iModify: index of first modified dword in sector\n * cModify: number of modified dwords in sector\n * fDirty: true if sector is dirty, false if clean (or cleaning in progress)\n *\n * @this {DiskPDP11}\n * @param {Object} sector\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} [iSector]\n * @param {number} [cbSector]\n * @param {number|null} [dwPattern]\n * @return {Object}\n */\n initSector(sector, iCylinder, iHead, iSector, cbSector, dwPattern)\n {\n if (!sector) {\n sector = {'sector': iSector, 'length': cbSector, 'data': [], 'pattern': dwPattern};\n }\n sector.iCylinder = iCylinder;\n sector.iHead = iHead;\n sector.iModify = sector.cModify = 0;\n sector.fDirty = false;\n return sector;\n }\n\n /**\n * info()\n *\n * TODO: Decide whether deprecate this in favor of accessing the nCylinders, nHeads, nSectors, and cbSector\n * properties of the Disk object directly.\n *\n * @this {DiskPDP11}\n * @return {Array} containing: [nCylinders, nHeads, nSectorsPerTrack, nBytesPerSector]\n */\n info()\n {\n if (!this.aDiskData.length) {\n return [0, 0, 0, 0];\n }\n return [this.aDiskData.length, this.aDiskData[0].length, this.aDiskData[0][0].length, this.aDiskData[0][0][0]['length']];\n }\n\n /**\n * seek(iCylinder, iHead, iSector, fWrite, done)\n *\n * TODO: There's some dodgy code in seek() that allows floppy images to be dynamically\n * reconfigured with more heads and/or sectors/track, and it does so by peeking at more drive\n * properties. That code used to be in the FDC component, where it was perfectly reasonable\n * to access those properties. We need a cleaner interface back to the drive, similar to the\n * info() interface we provide to the controller.\n *\n * Whether or not the \"dynamic reconfiguration\" feature itself is perfectly reasonable is,\n * of course, a separate question.\n *\n * @this {DiskPDP11}\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {boolean} [fWrite]\n * @param {function(Object,boolean)} [done]\n * @return {Object|null} is the requested sector, or null if not found (or not available yet)\n */\n seek(iCylinder, iHead, iSector, fWrite, done)\n {\n var sector = null;\n var drive = this.drive;\n var cylinder = this.aDiskData[iCylinder];\n if (cylinder) {\n var i;\n var track = cylinder[iHead];\n /*\n * The following code allows a single-sided diskette image to be reformatted (ie, \"expanded\")\n * as a double-sided image, provided the drive has more than one head (see drive.nHeads).\n */\n if (!track && drive.bFormatting && iHead < drive.nHeads) {\n track = cylinder[iHead] = new Array(drive.bSectorEnd);\n for (i = 0; i < track.length; i++) {\n track[i] = this.initSector(null, iCylinder, iHead, i + 1, drive.nBytes, 0);\n }\n }\n if (track) {\n for (i = 0; i < track.length; i++) {\n if (track[i] && track[i]['sector'] == iSector) {\n /*\n * If the sector's pattern is null, then this sector's true contents have not yet\n * been fetched from the server.\n */\n sector = track[i];\n break;\n }\n }\n /*\n * The following code allows an 8-sector track to be reformatted (ie, \"expanded\") as a 9-sector track.\n */\n if (!sector && drive.bFormatting && drive.bSector == 9) {\n sector = track[i] = this.initSector(null, iCylinder, iHead, drive.bSector, drive.nBytes, 0);\n }\n }\n }\n if (done) done(sector, false);\n return sector;\n }\n\n /**\n * fill(sector, ab, off)\n *\n * @this {DiskPDP11}\n * @param {Object} sector\n * @param {*} ab (technically, this should be typed as Array.<number> but I'm having trouble coercing JSON.parse() to that)\n * @param {number} off\n */\n fill(sector, ab, off)\n {\n var cdw = sector['length'] >> 2;\n var adw = new Array(cdw);\n for (var idw = 0; idw < cdw; idw++) {\n adw[idw] = ab[off] | (ab[off + 1] << 8) | (ab[off + 2] << 16) | (ab[off + 3] << 24);\n off += 4;\n }\n sector['data'] = adw;\n /*\n * TODO: Consider taking this opportunity to shrink 'data' down by the number of dwords at the end of the buffer that\n * contain the same pattern, and setting 'pattern' accordingly.\n */\n }\n\n /**\n * toBytes(sector)\n *\n * @this {DiskPDP11}\n * @param {Object} sector\n * @return {Array.<number>} is an array of bytes\n */\n toBytes(sector)\n {\n var cb = sector['length'];\n var ab = new Array(cb);\n var ib = 0;\n var cdw = cb >> 2;\n var adw = sector['data'];\n var dwPattern = sector['pattern'];\n for (var idw = 0; idw < cdw; idw++) {\n var dw = (idw < adw.length? adw[idw] : dwPattern);\n ab[ib++] = dw & 0xff;\n ab[ib++] = (dw >> 8) & 0xff;\n ab[ib++] = (dw >> 16) & 0xff;\n ab[ib++] = (dw >> 24) & 0xff;\n }\n return ab;\n }\n\n /**\n * read(sector, ibSector, fCompare)\n *\n * @this {DiskPDP11}\n * @param {Object} sector (returned from a previous seek)\n * @param {number} ibSector a byte index within the given sector\n * @param {boolean} [fCompare] is true if this write-compare read\n * @return {number} the specified (unsigned) byte, or -1 if no more data in the sector\n */\n read(sector, ibSector, fCompare)\n {\n var b = -1;\n if (sector) {\n if (ibSector < sector['length']) {\n var adw = sector['data'];\n var idw = ibSector >> 2;\n var dw = (idw < adw.length ? adw[idw] : sector['pattern']);\n b = ((dw >> ((ibSector & 0x3) << 3)) & 0xff);\n }\n if (DEBUG && !fCompare && this.messageEnabled()) {\n this.printMessage('read(\"' + this.sDiskFile + '\",CHS=' + sector.iCylinder + ':' + sector.iHead + ':' + sector['sector'] + ',index=' + ibSector + ',value=' + Str.toHexByte(b) + ')');\n }\n }\n return b;\n }\n\n /**\n * write(sector, ibSector, b)\n *\n * @this {DiskPDP11}\n * @param {Object} sector (returned from a previous seek)\n * @param {number} ibSector a byte index within the given sector\n * @param {number} b the byte value to write\n * @return {boolean|null} true if write successful, false if write-protected, null if out of bounds\n */\n write(sector, ibSector, b)\n {\n if (this.fWriteProtected)\n return false;\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage('write(\"' + this.sDiskFile + '\",CHS=' + sector.iCylinder + ':' + sector.iHead + ':' + sector['sector'] + ',index=' + ibSector + ',value=' + Str.toHexByte(b) + ')');\n }\n\n if (ibSector < sector['length']) {\n if (b != this.read(sector, ibSector, true)) {\n var adw = sector['data'];\n var dwPattern = sector['pattern'];\n var idw = ibSector >> 2;\n var nShift = (ibSector & 0x3) << 3;\n\n /*\n * Ensure every byte up to the specified byte is properly initialized.\n */\n for (var i = adw.length; i <= idw; i++) adw[i] = dwPattern;\n\n if (!sector.cModify) {\n sector.iModify = idw;\n sector.cModify = 1;\n } else if (idw < sector.iModify) {\n sector.cModify += sector.iModify - idw;\n sector.iModify = idw;\n } else if (idw >= sector.iModify + sector.cModify) {\n sector.cModify += idw - (sector.iModify + sector.cModify) + 1;\n }\n adw[idw] = (adw[idw] & ~(0xff << nShift)) | (b << nShift);\n }\n return true;\n }\n return null;\n }\n\n /**\n * getSector(pba)\n *\n * @this {DiskPDP11}\n * @param {number} pba (physical block address)\n * @return {Object|null} sector\n */\n getSector(pba)\n {\n var nSectorsPerCylinder = this.nHeads * this.nSectors;\n var iCylinder = (pba / nSectorsPerCylinder) | 0;\n if (iCylinder < this.nCylinders) {\n var nSectorsRemaining = (pba % nSectorsPerCylinder);\n var iHead = (nSectorsRemaining / this.nSectors) | 0;\n /*\n * PBA numbers are 0-based, but the sector numbers in CHS addressing are 1-based, so add one to iSector\n */\n var iSector = (nSectorsRemaining % this.nSectors) + 1;\n return this.seek(iCylinder, iHead, iSector);\n }\n return null;\n }\n\n /**\n * getSectorData(sector, off, len)\n *\n * WARNING: This function is restricted to reading data contained ENTIRELY within the specified sector.\n *\n * NOTE: Yes, this function is not the most efficient way to read a byte/word/dword value from within a sector,\n * but given the different states a sector may be in, it's certainly the simplest and safest, and since this is\n * only used by buildFileTable() and its progeny, it's not clear that we need to be superfast anyway.\n *\n * @this {DiskPDP11}\n * @param {Object} sector\n * @param {number} off (byte offset)\n * @param {number} len (1 to 4 bytes)\n * @return {number}\n */\n getSectorData(sector, off, len)\n {\n var dw = 0;\n var nShift = 0;\n\n while (len--) {\n\n var b = this.read(sector, off++);\n\n if (b < 0) break;\n dw |= (b << nShift);\n nShift += 8;\n }\n return dw;\n }\n\n /**\n * encodeAsBase64()\n *\n * @this {DiskPDP11}\n * @return {string}\n */\n encodeAsBase64()\n {\n /*\n * Gross, but simple; more importantly, it works -- at least for disks of typical floppy magnitude.\n */\n var s = \"\", pba = 0, sector;\n while ((sector = this.getSector(pba++))) {\n for (var off = 0, len = sector['length']; off < len; off++) {\n s += String.fromCharCode(this.getSectorData(sector, off, 1));\n }\n }\n return btoa(s);\n }\n\n /**\n * save()\n *\n * The first array entry contains some disk information:\n *\n * [sDiskPath, dwChecksum, nCylinders, nHeads, nSectors, cbSector]\n *\n * Each subsequent entry in the returned array contains the following:\n *\n * [iCylinder, iHead, iSector, iModify, [...]]\n *\n * where [...] is an array of modified dword(s) in the corresponding sector.\n *\n * @this {DiskPDP11}\n * @return {Array} of modified sectors\n */\n save()\n {\n var i = 0;\n var deltas = [];\n deltas[i++] = [this.sDiskPath, this.dwChecksum, this.nCylinders, this.nHeads, this.nSectors, this.cbSector];\n if (!this.fWriteProtected) {\n var aDiskData = this.aDiskData;\n for (var iCylinder = 0; iCylinder < aDiskData.length; iCylinder++) {\n for (var iHead = 0; iHead < aDiskData[iCylinder].length; iHead++) {\n for (var iSector = 0; iSector < aDiskData[iCylinder][iHead].length; iSector++) {\n var sector = aDiskData[iCylinder][iHead][iSector];\n if (sector && sector.cModify) {\n var mods = [], n = 0;\n var iModify = sector.iModify, iModifyLimit = sector.iModify + sector.cModify;\n while (iModify < iModifyLimit) {\n mods[n++] = sector['data'][iModify++];\n }\n deltas[i++] = [iCylinder, iHead, iSector, sector.iModify, mods];\n }\n }\n }\n }\n }\n if (DEBUG && this.messageEnabled()) {\n this.printMessage('save(\"' + this.sDiskName + '\"): saved ' + (deltas.length - 1) + ' change(s)');\n }\n return deltas;\n }\n\n /**\n * restore(deltas)\n *\n * The first array entry contains some disk information:\n *\n * [sDiskPath, dwChecksum, nCylinders, nHeads, nSectors, cbSector]\n *\n * Each subsequent entry in the supplied array contains the following:\n *\n * [iCylinder, iHead, iSector, iModify, [...]]\n *\n * where [...] is an array of modified dword(s) in the corresponding sector.\n *\n * @this {DiskPDP11}\n * @param {Array} deltas\n * @return {number} 0 if no changes applied, -1 if an error occurred, otherwise the number of sectors modified\n */\n restore(deltas)\n {\n /*\n * If deltas is undefined, that's not necessarily an error; the controller may simply be (re)initializing\n * itself (although neither controller should be calling restore() under those conditions anymore).\n */\n var nChanges = 0;\n var sReason = \"unsupported restore format\";\n /*\n * I originally added a check for aDiskData here on the assumption that if there was an error loading\n * a disk image, we will have already notified the user, so any additional errors about differing checksums,\n * failure to restore the disk state, etc, would just be annoying. HOWEVER, HDC will create an empty disk\n * image if its initialization code discovers that no disk was loaded earlier (see verifyDrive). So while\n * checking aDiskData is still a good idea, be aware that it won't necessarily avoid redundant error messages\n * (at least in the case of HDC).\n */\n if (deltas && deltas.length > 0) {\n\n var i = 0;\n var aDiskInfo = deltas[i++];\n\n if (aDiskInfo && aDiskInfo.length >= 2) {\n /*\n * Before getting to the checksum, we have to deal with a new situation: restoring an uninitialized\n * disk image from a complete set of deltas. And that is only possible if the disk was saved with the\n * original disk geometry.\n */\n if (!this.aDiskData.length && aDiskInfo.length >= 6) {\n this.create(DiskAPI.MODE.LOCAL, aDiskInfo[2], aDiskInfo[3], aDiskInfo[4], aDiskInfo[5]);\n /*\n * TODO: Consider setting a flag here that we can check at the end of the restore() function\n * that indicates we should recalculate dwChecksum, because we currently have an inconsistency\n * between local disks that are mounted via build() and the same disks that are \"remounted\"\n * later by this code; the former has the correct checksum, while the latter has a null checksum.\n *\n * As you can see below, we currently deal with this by simply ignoring null checksums....\n */\n }\n /*\n * v1.01 failed to indicate an error if either one of these failure conditions occurred. Although maybe that's\n * just as well, since v1.01 also failed to properly deal with situations where the user mounted different diskette(s)\n * prior to exiting (hopefully fixed in v1.02).\n */\n else if (aDiskInfo[1] != null && this.dwChecksum != null && aDiskInfo[1] != this.dwChecksum) {\n sReason = \"original checksum (\" + aDiskInfo[1] + \") differs from current checksum (\" + this.dwChecksum + \")\";\n nChanges = -2;\n }\n /*\n * Checksum is more important than disk path, and for now, I want the flexibility to move disk images.\n *\n else if (aDiskInfo[0] != this.sDiskPath) {\n sReason = \"original path '\" + aDiskInfo[0] + \"' differs from current path '\" + this.sDiskPath + \"'\";\n nChanges = -1;\n }\n */\n }\n\n if (!this.aDiskData.length) nChanges = -1;\n\n while (i < deltas.length && nChanges >= 0) {\n var m = 0;\n var mod = deltas[i++];\n var iCylinder = mod[m++];\n var iHead = mod[m++];\n var iSector = mod[m++];\n /*\n * Note the buried test for write-protection. Yes, an invariant condition should be tested\n * outside the loop, not inside, but (a) it's a trivial test, (b) the test should never fail\n * because save() should never generate any mods for a write-protected disk, and (c) it\n * centralizes all the failure conditions we're currently checking (which, admittedly, ain't much).\n */\n if (iCylinder >= this.aDiskData.length || iHead >= this.aDiskData[iCylinder].length || iSector >= this.aDiskData[iCylinder][iHead].length) {\n sReason = \"sector (CHS=\" + iCylinder + ':' + iHead + ':' + iSector + \") out of range (\" + nChanges + \" changes applied)\";\n nChanges = -1;\n break;\n }\n if (this.fWriteProtected) {\n sReason = \"unable to modify write-protected disk\";\n nChanges = -1;\n break;\n }\n var iModify = mod[m++];\n var mods = mod[m++];\n var iModifyLimit = iModify + mods.length;\n var sector = this.aDiskData[iCylinder][iHead][iSector];\n if (!sector) continue;\n /*\n * Since write() now deals with empty/partial sectors, we no longer need to completely \"inflate\"\n * the sector prior to applying modifications. So let's just make sure that the sector is \"inflated\"\n * up to iModify.\n */\n var idw = sector['data'].length;\n while (idw < iModify) {\n sector['data'][idw++] = sector['pattern'];\n }\n var n = 0;\n sector.iModify = iModify;\n sector.cModify = mods.length;\n while (iModify < iModifyLimit) {\n sector['data'][iModify++] = mods[n++];\n }\n nChanges++;\n }\n }\n\n if (nChanges < 0) {\n /*\n * We're suppressing checksum messages for the general public for now....\n */\n if (DEBUG || nChanges != -2) {\n this.controller.notice(\"Unable to restore disk '\" + this.sDiskName + \": \" + sReason);\n }\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage('restore(\"' + this.sDiskName + '\"): restored ' + nChanges + ' change(s)');\n }\n }\n return nChanges;\n }\n\n /**\n * convertToJSON(fFormatted)\n *\n * We perform some RegExp massaging on the JSON data to eliminate unnecessary properties\n * (eg, 'length' values of 512, 'pattern' values of 0, since those are defaults).\n *\n * In addition, we first check every sector to see if it can be \"deflated\". Sectors that were\n * initially \"deflated\" should remain that way unless/until they were modified, so technically,\n * we could call deflateSector() just for modified sectors, but this isn't a common operation,\n * so it doesn't hurt to check every sector.\n *\n * @this {DiskPDP11}\n * @param {boolean} [fFormatted]\n * @return {string} containing the entire disk image as JSON-encoded data\n */\n convertToJSON(fFormatted)\n {\n var s, pba = 0, sector, sectorLast;\n\n while ((sector = this.getSector(pba++))) {\n this.deflateSector(sector);\n }\n\n s = JSON.stringify(this.aDiskData, function(key, value) {\n /*\n * If BACKTRACK support is enabled, we have to filter out any 'file' properties that may\n * be attached to the sector objects, lest we risk blowing the stack due to circular references.\n */\n if (key == 'file') {\n return undefined;\n }\n return value;\n });\n\n /*\n * Eliminate unnecessary default properties (eg, 'length' values of 512, 'pattern' values of 0).\n */\n s = s.replace(/,\"length\":512/g, \"\").replace(/,\"pattern\":0/g, \"\");\n\n /*\n * I don't really want to strip quotes from disk image property names, since I would have to put them\n * back again during mount() -- or whenever JSON.parse() is used instead of eval(). But I still remove\n * them temporarily, so that any remaining property names (eg, \"iModify\", \"cModify\", \"fDirty\") can\n * easily be stripped out, by virtue of their being the only quoted properties left. We then \"requote\"\n * all the property names that remain.\n */\n s = s.replace(/\"(sector|length|data|pattern)\":/g, \"$1:\");\n\n /*\n * The next line will remove any other numeric or boolean properties that were added at runtime, although\n * they may have completely different (\"minified\") names if the code has been compiled.\n */\n s = s.replace(/,\"[^\"]*\":([0-9]+|true|false)/g, \"\");\n s = s.replace(/(sector|length|data|pattern):/g, \"\\\"$1\\\":\");\n\n /*\n * Last but not least, insert line breaks after every object definition, to improve human readability\n * (but only if the caller asks for it).\n */\n if (fFormatted) s = s.replace(/([\\]}]),/g, \"$1,\\n\");\n return s;\n }\n\n /**\n * deflateSector(sector)\n *\n * This is just the first revision: it currently looks only at fully inflated sectors.\n *\n * @this {DiskPDP11}\n * @param {Object} sector\n */\n deflateSector(sector)\n {\n var adw = sector['data'];\n var cdw = adw.length;\n if ((cdw << 2) == sector['length']) {\n var idw = cdw - 1;\n var dwPattern = adw[idw], cDupes = 0;\n while (idw--) {\n if (adw[idw] !== dwPattern) break;\n cDupes++;\n }\n if (cDupes++) {\n adw.length = cdw - cDupes;\n sector['pattern'] = dwPattern;\n }\n }\n }\n\n /**\n * dumpSector(sector, pba, sDesc)\n *\n * @this {DiskPDP11}\n * @param {Object} sector (returned from a previous seek)\n * @param {number} [pba]\n * @param {string} [sDesc]\n * @return {string}\n */\n dumpSector(sector, pba, sDesc)\n {\n var sDump = \"\";\n if (DEBUG && sector) {\n if (pba != null) sDump += \"sector \" + pba + (sDesc? (\" for \" + sDesc) : \"\") + ':';\n var sBytes = \"\", sChars = \"\";\n var cbSector = sector['length'];\n var cdwData = sector['data'].length;\n var dw = 0;\n for (var i = 0; i < cbSector; i++) {\n if ((i % 16) === 0) {\n if (sDump) sDump += sBytes + ' ' + sChars + '\\n';\n sDump += Str.toHex(i, 4) + \": \";\n sBytes = sChars = \"\";\n }\n if ((i % 4) === 0) {\n var idw = i >> 2;\n dw = (idw < cdwData? sector['data'][idw] : sector['pattern']);\n }\n var b = dw & 0xff;\n dw >>>= 8;\n sBytes += Str.toHex(b, 2) + (i % 16 == 7? \"-\" : \" \");\n sChars += (b >= 32 && b < 128? String.fromCharCode(b) : \".\");\n }\n if (sBytes) sDump += sBytes + ' ' + sChars;\n }\n return sDump;\n }\n}\n\n/*\n * A global disk count, used to form unique Disk component IDs (totally optional; for debugging purposes only)\n */\nDiskPDP11.nDisks = 0;\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/drive.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * @typedef {{\n * PRI: number,\n * VEC: number,\n * DRIVES: number\n * }}\n */\nvar Config;\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * Component class, because otherwise the Compiler won't allow us to *reference* the named\n * property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass DriveController extends Component {\n /**\n * DriveController(type, parms, bitsMessage, configDC, configDrive, configIO)\n *\n * The DriveController component has the following component-specific (parms) properties:\n *\n * autoMount: one or more JSON-encoded objects, each containing 'name' and 'path' properties\n *\n * @this {DriveController}\n * @param {string} type\n * @param {Object} parms\n * @param {number} bitsMessage\n * @param {Config} configDC\n * @param {Array} configDrive\n * @param {Object} configIO\n */\n constructor(type, parms, bitsMessage, configDC, configDrive, configIO)\n {\n super(type, parms, bitsMessage);\n\n /*\n * We preliminarily parse and record any 'autoMount' object now, but we no longer process it\n * until initBus(), because the Computer's getMachineParm() service may have an override for us.\n */\n this.configMount = this.parseConfig(parms['autoMount']);\n this.cAutoMount = 0;\n\n this.configDC = configDC;\n this.configDrive = configDrive;\n this.configIO = configIO;\n\n this.nDrives = configDC.DRIVES;\n this.aDrives = new Array(this.nDrives);\n this.fLocalDisks = (!Web.isMobile() && window && 'FileReader' in window);\n this.sDiskSource = DriveController.SOURCE.NONE;\n\n /*\n * The following array keeps track of every disk image we've ever mounted. Each entry in the\n * array is another array whose elements are:\n *\n * [0]: name of disk\n * [1]: path of disk\n * [2]: array of deltas, uninitialized until the disk is unmounted and/or all state is saved\n *\n * See functions addDiskHistory() and updateDiskHistory().\n */\n this.aDiskHistory = [];\n\n this.irq = null;\n\n this['exports'] = {\n 'bootDisk': this.bootSelectedDisk,\n 'loadDisk': this.loadSelectedDisk,\n 'selectDrive': this.selectDrive,\n 'wait': this.waitDrives\n };\n }\n\n /**\n * parseConfig(config)\n *\n * @this {DriveController}\n * @param {*} config\n * @return {*}\n */\n parseConfig(config)\n {\n if (config && typeof config == \"string\") {\n try {\n /*\n * The most likely source of any exception will be right here, where we're parsing\n * this JSON-encoded data.\n */\n config = eval(\"(\" + config + \")\");\n } catch (e) {\n Component.error(this.type + \" auto-mount error: \" + e.message + \" (\" + config + \")\");\n config = null;\n }\n }\n return config || {};\n }\n\n /**\n * setBinding(sType, sBinding, control, sValue)\n *\n * @this {DriveController}\n * @param {string|null} sType is the type of the HTML control (eg, \"button\", \"list\", \"text\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"listDisks\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sType, sBinding, control, sValue)\n {\n var dc = this;\n\n switch (sBinding) {\n\n case \"listDisks\":\n this.bindings[sBinding] = control;\n control.onchange = function onChangeListDisks(event) {\n dc.updateSelectedDisk();\n };\n return true;\n\n case \"descDisk\":\n case \"listDrives\":\n this.bindings[sBinding] = control;\n /*\n * I tried going with onclick instead of onchange, so that if you wanted to confirm what's\n * loaded in a particular drive, you could click the drive control without having to change it.\n * However, that doesn't seem to work for all browsers, so I've reverted to onchange.\n */\n var controlSelect = /** @type {HTMLSelectElement} */ (control);\n control.onchange = function onChangeListDrives(event) {\n var iDrive = Str.parseInt(controlSelect.value, 10);\n if (iDrive != null) dc.displayDisk(iDrive);\n };\n return true;\n\n case \"loadDisk\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickLoadDrive(event) {\n dc.loadSelectedDisk();\n };\n return true;\n\n case \"bootDisk\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickBootDisk(event) {\n dc.bootSelectedDisk();\n };\n return true;\n\n case \"saveDisk\":\n /*\n * Yes, technically, this feature does not require \"Local disk support\" (which is really a reference\n * to FileReader support), but since fLocalDisks is also false for all mobile devices, and since there\n * is an \"orthogonality\" to disabling both features in tandem, let's just let it slide, OK?\n */\n if (!this.fLocalDisks) {\n if (DEBUG) this.log(\"Local disk support not available\");\n /*\n * We could also simply hide the control; eg:\n *\n * control.style.display = \"none\";\n *\n * but removing the control altogether seems better.\n */\n control.parentNode.removeChild(/** @type {Node} */ (control));\n return false;\n }\n\n this.bindings[sBinding] = control;\n\n control.onclick = function onClickSaveDrive(event) {\n var controlDrives = dc.bindings[\"listDrives\"];\n if (controlDrives && controlDrives.options && dc.aDrives) {\n var iDriveSelected = Str.parseInt(controlDrives.value, 10) || 0;\n var drive = dc.aDrives[iDriveSelected];\n if (drive) {\n /*\n * Note the similarity (and hence factoring opportunity) between this code and the HDC's \"saveHD*\" binding.\n */\n var disk = drive.disk;\n if (disk) {\n if (DEBUG) dc.println(\"saving disk \" + disk.sDiskPath + \"...\");\n var sAlert = Web.downloadFile(disk.encodeAsBase64(), \"octet-stream\", true, disk.sDiskFile.replace(\".json\", \".img\"));\n Component.alertUser(sAlert);\n } else {\n dc.notice(\"No disk loaded in drive.\");\n }\n } else {\n dc.notice(\"No disk drive selected.\");\n }\n }\n };\n return true;\n\n case \"mountDisk\":\n var controlInput = /** @type {Object} */ (control);\n\n if (!this.fLocalDisks) {\n if (DEBUG) this.log(\"Local disk support not available\");\n /*\n * We could also simply hide the control; eg:\n *\n * controlInput.style.display = \"none\";\n *\n * but removing the control altogether seems better.\n */\n controlInput.parentNode.removeChild(/** @type {Node} */ (controlInput));\n return false;\n }\n\n this.bindings[sBinding] = controlInput;\n\n /*\n * Enable \"Mount\" button only if a file is actually selected\n */\n controlInput.addEventListener('change', function() {\n var fieldset = controlInput.children[0];\n var files = fieldset.children[0].files;\n var submit = fieldset.children[1];\n submit.disabled = !files.length;\n });\n\n controlInput.onsubmit = function(event) {\n var file = event.currentTarget[1].files[0];\n if (file) {\n var sDiskPath = file.name;\n var sDiskName = Str.getBaseName(sDiskPath, true);\n dc.loadSelectedDisk(sDiskName, sDiskPath, file);\n }\n /*\n * Prevent reloading of web page after form submission\n */\n return false;\n };\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {DriveController}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n var configMount = this.parseConfig(this.cmp.getMachineParm('autoMount'));\n\n /*\n * Add only drives from the machine-wide autoMount configuration that match drives managed by this component.\n */\n if (configMount) {\n for (var sDrive in configMount) {\n if (sDrive.substr(0, 2) != this.type.substr(0, 2)) continue;\n this.configMount[sDrive] = configMount[sDrive];\n }\n }\n\n /*\n * If we didn't need auto-mount support, we could defer controller and drive initialization until we received\n * a powerUp() notification, at which point reset() would call initController(), or restore() would restore the\n * controller.\n */\n this.reset();\n\n this.irq = this.cpu.addIRQ(this.configDC.VEC, this.configDC.PRI, this.bitsMessage);\n\n bus.addIOTable(this, this.configIO);\n bus.addResetHandler(this.reset.bind(this));\n\n this.addDisk(\"None\", DriveController.SOURCE.NONE, true);\n if (this.fLocalDisks) this.addDisk(\"Local Disk\", DriveController.SOURCE.LOCAL);\n this.addDisk(\"Remote Disk\", DriveController.SOURCE.REMOTE);\n\n if (!this.autoMount()) this.setReady();\n }\n\n /**\n * getDriveName(iDrive)\n *\n * Form a drive name using the two-letter controller type prefix and the drive number.\n *\n * @this {DriveController}\n * @param {number} iDrive\n * @return {string}\n */\n getDriveName(iDrive)\n {\n var drive = this.aDrives[iDrive];\n return drive.sName || \"---\";\n }\n\n /**\n * getDriveNumber(sDrive)\n *\n * @this {DriveController}\n * @param {string} sDrive\n * @return {number} (0-3, or -1 if error)\n */\n getDriveNumber(sDrive)\n {\n var iDrive = -1;\n if (sDrive) {\n iDrive = sDrive.charCodeAt(sDrive.length - 1) - 0x30;\n if (iDrive < 0 || iDrive > 9) iDrive = -1;\n }\n return iDrive;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {DriveController}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.reset();\n if (this.cmp.fReload) {\n /*\n * If the computer's fReload flag is set, we're required to toss all currently\n * loaded disks and remount all disks specified in the auto-mount configuration.\n */\n this.unloadAllDrives(true);\n this.autoMount(true);\n }\n } else {\n if (!this.restore(data)) return false;\n }\n /*\n * Populate the HTML controls to match the actual (well, um, specified) number of floppy drives.\n */\n var controlDrives;\n if ((controlDrives = this.bindings['listDrives'])) {\n while (controlDrives.firstChild) {\n controlDrives.removeChild(controlDrives.firstChild);\n }\n controlDrives.value = \"\";\n for (var iDrive = 0; iDrive < this.nDrives; iDrive++) {\n var controlOption = document.createElement(\"option\");\n controlOption.value = iDrive;\n controlOption.text = this.getDriveName(iDrive);\n controlDrives.appendChild(controlOption);\n }\n if (this.nDrives > 0) {\n controlDrives.value = \"0\";\n this.displayDisk(0);\n }\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {DriveController}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {DriveController}\n */\n reset()\n {\n this.initController();\n this.initDrives();\n }\n\n /**\n * save()\n *\n * This implements save support for the DriveController component.\n *\n * @this {DriveController}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveController());\n state.set(1, this.saveHistory());\n state.set(2, this.saveDrives());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the DriveController component.\n *\n * @this {DriveController}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var fSuccess = true;\n if (!this.initController(data[0])) fSuccess = false;\n if (!this.initHistory(data[1])) fSuccess = false;\n if (!this.initDrives(data[2])) fSuccess = false;\n return fSuccess;\n }\n\n /**\n * initController(aRegs)\n *\n * Placeholder for subclasses.\n *\n * @this {DriveController}\n * @param {Array} [aRegs]\n * @return {boolean} true if successful, false if failure\n */\n initController(aRegs)\n {\n return true;\n }\n\n /**\n * saveController()\n *\n * Placeholder for subclasses.\n *\n * @this {DriveController}\n * @return {Array}\n */\n saveController()\n {\n return [];\n }\n\n /**\n * initDrive(drive, iDrive, configDrive, configDisk)\n *\n * @this {DriveController}\n * @param {Object} drive\n * @param {number} iDrive\n * @param {Array} configDrive\n * @param {Array} [configDisk]\n * @return {boolean} true if successful, false if failure\n */\n initDrive(drive, iDrive, configDrive, configDisk)\n {\n var i = 0;\n var fSuccess = true;\n\n drive.iDrive = iDrive;\n drive.name = this.idComponent;\n drive.fBusy = drive.fLocal = false;\n drive.fnCallReady = null;\n drive.fRemovable = true;\n\n /*\n * NOTE: We initialize the following drive properties to their MAXIMUMs; disks may have\n * these or SMALLER values (subject to the limits of what the controller supports, of course).\n */\n drive.sName = configDrive[i++] + iDrive;\n drive.nCylinders = configDrive[i++];\n drive.nHeads = configDrive[i++];\n drive.nSectors = configDrive[i++];\n drive.cbSector = configDrive[i++];\n drive.iCylinderBoot = configDrive[i++];\n drive.iHeadBoot = configDrive[i++];\n drive.iSectorBoot = configDrive[i++];\n drive.cbSectorBoot = configDrive[i++];\n drive.status = configDrive[i];\n\n /*\n * The next group of properties are set by various controller command sequences.\n */\n drive.bHead = 0;\n drive.bCylinder = 0;\n drive.bSector = 1;\n drive.bSectorEnd = drive.nSectors; // aka EOT\n drive.nBytes = drive.cbSector;\n\n /*\n * The next group of properties are managed by worker functions (eg, doRead()) to maintain state across DMA requests.\n */\n drive.ibSector = 0;\n drive.sector = null;\n\n if (!drive.disk) {\n drive.sDiskPath = \"\"; // ensure this is initialized to a default that displayDisk() can deal with\n }\n\n if (configDisk) {\n var fLocal = configDisk[0];\n var sDiskName = configDisk[1];\n var sDiskPath = configDisk[2];\n /*\n * If we're restoring a local disk image, then the entire disk contents should be captured in aDiskHistory,\n * so all we have to do is mount a blank disk and let disk.restore() do the rest; ie, there's nothing to\n * \"load\" (it's a purely synchronous operation).\n *\n * Otherwise, we must call loadDrive(); in the common case, loadDrive() will have already \"auto-mounted\"\n * the disk, so it will return true, and then we restore any deltas to the current image.\n *\n * However, if loadDrive() returns false, then it has initiated the load for a *different* disk image,\n * so we must mark ourselves as \"not ready\" again, and add another \"wait for ready\" test in Computer before\n * finally powering the CPU.\n */\n if (fLocal) {\n this.mountDrive(iDrive, sDiskName, sDiskPath);\n }\n else if (this.loadDrive(iDrive, sDiskName, sDiskPath, true)) {\n if (drive.disk) {\n if (sDiskPath) {\n this.addDiskHistory(sDiskName, sDiskPath, drive.disk);\n } else {\n if (MAXDEBUG) Component.warning(\"Disk '\" + (drive.disk.sDiskName || sDiskName) + \"' not recorded properly in drive \" + iDrive);\n }\n }\n } else {\n this.setReady(false);\n }\n }\n return fSuccess;\n }\n\n /**\n * initDrives(aConfigDisks)\n *\n * @this {DriveController}\n * @param {Array} [aConfigDisks]\n * @return {boolean} true if successful, false if failure\n */\n initDrives(aConfigDisks)\n {\n var fSuccess = true;\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n var drive = this.aDrives[iDrive];\n if (drive === undefined) {\n drive = this.aDrives[iDrive] = {};\n }\n var configDisk = aConfigDisks && aConfigDisks[iDrive];\n if (!this.initDrive(drive, iDrive, this.configDrive, configDisk)) {\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * saveDrive(drive)\n *\n * @this {DriveController}\n * @param {Object} drive\n * @return {Array}\n */\n saveDrive(drive)\n {\n return [\n drive.fLocal,\n drive.sDiskName,\n drive.sDiskPath\n ]\n }\n\n /**\n * saveDrives()\n *\n * @this {DriveController}\n * @return {Array}\n */\n saveDrives()\n {\n var data = [];\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n data.push(this.saveDrive(this.aDrives[iDrive]));\n }\n return data;\n }\n\n /**\n * initHistory(aHistory)\n *\n * @this {DriveController}\n * @param {Array} [aHistory]\n * @return {boolean} true if successful, false if failure\n */\n initHistory(aHistory)\n {\n /*\n * Initialize the disk history (if available) before initializing the drives, so that any disk deltas can be\n * applied to disk images that are already loaded.\n */\n if (aHistory) this.aDiskHistory = aHistory;\n\n return true;\n }\n\n /**\n * saveHistory()\n *\n * This returns an array of entries, one for each disk image we've ever mounted, including any deltas; ie:\n *\n * [name, path, deltas]\n *\n * aDiskHistory contains exactly that, except that deltas may not be up-to-date for any currently mounted\n * disk image(s), so we call updateHistory() for all those disks, and then aDiskHistory is ready to be saved.\n *\n * @this {DriveController}\n * @return {Array}\n */\n saveHistory()\n {\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n var drive = this.aDrives[iDrive];\n if (drive.disk) {\n this.updateDiskHistory(drive.sDiskName, drive.sDiskPath, drive.disk);\n }\n }\n return this.aDiskHistory;\n }\n\n /**\n * autoMount(fRemount)\n *\n * @this {DriveController}\n * @param {boolean} [fRemount] is true if we're remounting all auto-mounted disks\n * @return {boolean} true if one or more disk images are being auto-mounted, false if none\n */\n autoMount(fRemount)\n {\n if (!fRemount) this.cAutoMount = 0;\n for (var sDrive in this.configMount) {\n var configDisk = this.configMount[sDrive];\n var sDiskPath = configDisk['path'] || \"\";\n var sDiskName = configDisk['name'] || this.findDisk(sDiskPath);\n if (sDiskPath && sDiskName) {\n var iDrive = this.getDriveNumber(sDrive);\n if (iDrive >= 0 && iDrive < this.aDrives.length) {\n if (!this.loadDrive(iDrive, sDiskName, sDiskPath, true) && fRemount) {\n this.setReady(false);\n }\n continue;\n }\n }\n this.notice(\"Incorrect auto-mount settings for drive \" + sDrive + \" (\" + JSON.stringify(configDisk) + \")\");\n }\n return !!this.cAutoMount;\n }\n\n /**\n * loadSelectedDisk(sDiskName, sDiskPath, file)\n *\n * @this {DriveController}\n * @param {string} [sDiskName]\n * @param {string} [sDiskPath]\n * @param {File} [file] is set if there's an associated File object\n * @return {boolean}\n */\n loadSelectedDisk(sDiskName, sDiskPath, file)\n {\n if (!sDiskName && !sDiskPath) {\n var controlDisks = this.bindings[\"listDisks\"];\n if (controlDisks && controlDisks.options) {\n sDiskName = controlDisks.options[controlDisks.selectedIndex].text;\n sDiskPath = controlDisks.value;\n }\n }\n\n var controlDrives = this.bindings[\"listDrives\"];\n var iDrive = controlDrives && Str.parseInt(controlDrives.value, 10);\n\n if (iDrive === undefined || iDrive < 0 || iDrive >= this.aDrives.length) {\n this.notice(\"Unable to load the selected drive\");\n return false;\n }\n\n if (!sDiskPath) {\n this.unloadDrive(iDrive);\n return true;\n }\n\n if (sDiskPath == DriveController.SOURCE.LOCAL) {\n this.notice('Use \"Choose File\" and \"Mount\" to select and load a local disk.');\n return false;\n }\n\n /*\n * If the special DriveController.SOURCE.REMOTE path is selected, then we want to prompt the user for a URL.\n * Oh, and make sure we pass an empty string as the 2nd parameter to prompt(), so that IE won't display\n * \"undefined\" -- because after all, undefined and \"undefined\" are EXACTLY the same thing, right?\n *\n * TODO: This is literally all I've done to support remote disk images. There's probably more\n * I should do, like dynamically updating \"listDisks\" to include new entries, and adding new entries\n * to the save/restore data.\n */\n if (sDiskPath == DriveController.SOURCE.REMOTE) {\n sDiskPath = window.prompt(\"Enter the URL of a remote disk image.\", \"\") || \"\";\n if (!sDiskPath) return false;\n sDiskName = Str.getBaseName(sDiskPath);\n this.status(\"Attempting to load \" + sDiskPath + \" as \\\"\" + sDiskName + \"\\\"\");\n this.sDiskSource = DriveController.SOURCE.REMOTE;\n }\n else {\n this.sDiskSource = sDiskPath;\n }\n\n this.loadDrive(iDrive, sDiskName, sDiskPath, false, file);\n return true;\n }\n\n /**\n * bootSelectedDisk()\n *\n * @this {DriveController}\n * @return {boolean}\n */\n bootSelectedDisk()\n {\n var drive;\n var controlDrives = this.bindings[\"listDrives\"];\n var iDrive = controlDrives && Str.parseInt(controlDrives.value, 10);\n\n if (iDrive == null || iDrive < 0 || iDrive >= this.aDrives.length || !(drive = this.aDrives[iDrive])) {\n this.notice(\"Unable to boot the selected drive\");\n return false;\n }\n\n if (!drive.disk) {\n this.notice(\"Load a disk into the drive first\");\n return false;\n }\n\n /*\n * NOTE: We're calling setReset() BEFORE reading the boot code in order to eliminate any side-effects\n * of the previous state of either the controller OR the CPU; for example, we don't want any previous MMU\n * or UNIBUS Map registers affecting the simulated readData() call. Also, some boot code (eg, RSTS/E)\n * expects the controller to be in a READY state; since setReset() triggers a call to our reset() handler,\n * a READY state is assured, and the readData() call shouldn't do anything to change that.\n */\n this.cpu.setReset(0, true, iDrive);\n\n var err = this.readData(drive, drive.iCylinderBoot, drive.iHeadBoot, drive.iSectorBoot, drive.cbSectorBoot, 0x0000, 2);\n if (err) {\n this.notice(\"Unable to read the boot sector (\" + err + \")\");\n return false;\n }\n return true;\n }\n\n /**\n * mountDrive(iDrive, sDiskName, sDiskPath)\n *\n * @this {DriveController}\n * @param {number} iDrive\n * @param {string} sDiskName\n * @param {string} sDiskPath\n */\n mountDrive(iDrive, sDiskName, sDiskPath)\n {\n var drive = this.aDrives[iDrive];\n this.unloadDrive(iDrive, true);\n drive.fLocal = true;\n var disk = new DiskPDP11(this, drive, DiskAPI.MODE.PRELOAD);\n this.doneLoadDrive(drive, disk, sDiskName, sDiskPath, true);\n }\n\n /**\n * loadDrive(iDrive, sDiskName, sDiskPath, fAutoMount, file)\n *\n * NOTE: If sDiskPath is already loaded, nothing needs to be done.\n *\n * @this {DriveController}\n * @param {number} iDrive\n * @param {string} sDiskName\n * @param {string} sDiskPath\n * @param {boolean} [fAutoMount]\n * @param {File} [file] is set if there's an associated File object\n * @return {number} 1 if disk loaded, 0 if queued up (or busy), -1 if already loaded\n */\n loadDrive(iDrive, sDiskName, sDiskPath, fAutoMount, file)\n {\n var nResult = -1;\n var drive = this.aDrives[iDrive];\n\n if (drive.sDiskPath.toLowerCase() != sDiskPath.toLowerCase()) {\n\n nResult++;\n this.unloadDrive(iDrive, true);\n\n if (drive.fBusy) {\n this.notice(this.type + \" busy\");\n }\n else {\n // this.status(\"disk queued: \" + sDiskName);\n drive.fBusy = true;\n if (fAutoMount) {\n drive.fAutoMount = true;\n this.cAutoMount++;\n if (this.messageEnabled()) this.printMessage(\"auto-loading disk: \" + sDiskName);\n }\n drive.fLocal = !!file;\n var disk = new DiskPDP11(this, drive, DiskAPI.MODE.PRELOAD);\n if (disk.load(sDiskName, sDiskPath, file, this.doneLoadDrive)) {\n nResult++;\n }\n }\n }\n return nResult;\n }\n\n /**\n * doneLoadDrive(drive, disk, sDiskName, sDiskPath, fAutoMount)\n *\n * The disk parameter is set if the disk was successfully loaded, null if not.\n *\n * @this {DriveController}\n * @param {Object} drive\n * @param {DiskPDP11} disk\n * @param {string} sDiskName\n * @param {string} sDiskPath\n * @param {boolean} [fAutoMount]\n */\n doneLoadDrive(drive, disk, sDiskName, sDiskPath, fAutoMount)\n {\n drive.fBusy = false;\n\n if (disk) {\n /*\n * TODO: While this is a perfectly reasonable thing to do, one wonders if the Disk object shouldn't\n * have done this itself, since we passed our Drive object to it (it already knows the drive's limits).\n */\n if (disk.nCylinders > drive.nCylinders || disk.nHeads > drive.nHeads /* || disk.nSectors > drive.nSectors */) {\n this.notice(\"Disk \\\"\" + sDiskName + \"\\\" too large for drive \" + this.getDriveName(drive.iDrive));\n disk = null;\n }\n }\n\n if (disk) {\n drive.disk = disk;\n drive.sDiskName = sDiskName;\n drive.sDiskPath = sDiskPath;\n\n /*\n * Inform the controller implementation (eg, RX11) of the disk change.\n */\n this.notifyLoad(drive.iDrive);\n\n /*\n * Adding local disk image names to the disk list seems like a nice idea, but it's too confusing,\n * because then it looks like the \"Mount\" button should be able to (re)load them, and that can NEVER\n * happen, for security reasons; local disk images can ONLY be loaded via the \"Mount\" button after\n * the user has selected them via the \"Choose File\" button.\n *\n * this.addDisk(sDiskName, sDiskPath);\n *\n * So we're going to take a different approach: when displayDisk() is asked to display the name\n * of a local disk image, it will map all such disks to \"Local Disk\", and any attempt to \"Mount\" such\n * a disk, will essentially result in a \"Disk not found\" error.\n */\n this.addDiskHistory(sDiskName, sDiskPath, disk);\n\n /*\n * With the addition of notify(), users are now \"alerted\" whenever a disk has finished loading;\n * notify() is selective about its output, using print() if a print window is open, alert() otherwise.\n */\n this.notice(\"Loaded disk \\\"\" + sDiskName + \"\\\" in drive \" + this.getDriveName(drive.iDrive), drive.fAutoMount || fAutoMount);\n\n /*\n * Since you usually want the Computer to have focus again after loading a new disk, let's try automatically\n * updating the focus after a successful load.\n */\n if (this.cmp) this.cmp.setFocus();\n }\n else {\n drive.fLocal = false;\n }\n\n if (drive.fAutoMount) {\n drive.fAutoMount = false;\n if (!--this.cAutoMount) this.setReady();\n }\n\n this.displayDisk(drive.iDrive);\n\n if (drive.fnCallReady) {\n drive.fnCallReady();\n drive.fnCallReady = null;\n }\n }\n\n /**\n * addDisk(sName, sPath, fTop)\n *\n * @this {DriveController}\n * @param {string} sName\n * @param {string} sPath\n * @param {boolean} [fTop] (default is bottom)\n */\n addDisk(sName, sPath, fTop)\n {\n var controlDisks = this.bindings[\"listDisks\"];\n if (controlDisks && controlDisks.options) {\n for (var i = 0; i < controlDisks.options.length; i++) {\n if (controlDisks.options[i].value == sPath) return;\n }\n var controlOption = document.createElement(\"option\");\n controlOption.text = sName;\n controlOption.value = sPath;\n if (fTop && controlDisks.childNodes[0]) {\n controlDisks.insertBefore(controlOption, controlDisks.childNodes[0]);\n } else {\n controlDisks.appendChild(controlOption);\n }\n }\n }\n\n /**\n * findDisk(sPath)\n *\n * This is used to deal with mount requests (eg, autoMount) that supply a path without a name;\n * if we can find the path in the \"listDisks\" control, then we return the associated disk name.\n *\n * @this {DriveController}\n * @param {string} sPath\n * @return {string|null}\n */\n findDisk(sPath)\n {\n var controlDisks = this.bindings[\"listDisks\"];\n if (controlDisks && controlDisks.options) {\n for (var i = 0; i < controlDisks.options.length; i++) {\n var control = controlDisks.options[i];\n if (control.value == sPath) return control.text;\n }\n }\n return Str.getBaseName(sPath, true);\n }\n\n /**\n * displayDisk(iDrive, fUpdateDrive)\n *\n * This ensures that the selected disk matches the drive's sDiskPath property, and if fUpdateDrive is set,\n * it also ensures that the selected drive matches the specified drive number.\n *\n * @this {DriveController}\n * @param {number} iDrive (unvalidated)\n * @param {boolean} [fUpdateDrive] is true to update the drive list to match the specified drive (eg, the auto-mount case)\n * @return {boolean} true if successful, false if not\n */\n displayDisk(iDrive, fUpdateDrive)\n {\n /*\n * First things first: validate iDrive.\n */\n var fSuccess = false;\n if (iDrive >= 0 && iDrive < this.aDrives.length) {\n var drive = this.aDrives[iDrive];\n var controlDisks = this.bindings[\"listDisks\"];\n var controlDrives = this.bindings[\"listDrives\"];\n /*\n * Next, make sure controls for both drives and disks exist.\n */\n if (controlDisks && controlDrives && controlDisks.options && controlDrives.options) {\n /*\n * Next, update the drive if the caller has requested it.\n */\n var i;\n if (fUpdateDrive) {\n\n for (i = 0; i < controlDrives.options.length; i++) {\n if (Str.parseInt(controlDrives.options[i].value, 10) == drive.iDrive) {\n if (controlDrives.selectedIndex != i) {\n controlDrives.selectedIndex = i;\n }\n fSuccess = true;\n break;\n }\n }\n }\n /*\n * Next, make sure the drive whose disk we're updating is the currently selected drive.\n */\n var iDriveSelected = Str.parseInt(controlDrives.value, 10);\n var sTargetPath = (drive.fLocal? DriveController.SOURCE.LOCAL : drive.sDiskPath);\n if (!isNaN(iDriveSelected) && iDriveSelected == iDrive) {\n for (i = 0; i < controlDisks.options.length; i++) {\n if (controlDisks.options[i].value == sTargetPath) {\n if (controlDisks.selectedIndex != i) {\n controlDisks.selectedIndex = i;\n }\n fSuccess = true;\n break;\n }\n }\n if (i == controlDisks.options.length) controlDisks.selectedIndex = 0;\n }\n }\n }\n return fSuccess;\n }\n\n /**\n * selectDrive(sDrive)\n *\n * Used to select a drive by name.\n *\n * @this {DriveController}\n * @param {number} sDrive\n * @return {boolean} true if successful, false if not\n */\n selectDrive(sDrive)\n {\n var controlDrives = this.bindings[\"listDrives\"];\n if (controlDrives && controlDrives.options) {\n var nDrives = controlDrives.options.length;\n for (var i = 0; i < nDrives; i++) {\n if (controlDrives.options[i].textContent == sDrive) {\n var iDrive = Str.parseInt(controlDrives.options[i].value, 10);\n if (iDrive >= 0) {\n return this.displayDisk(iDrive, true);\n }\n }\n }\n }\n return false;\n }\n\n /**\n * updateSelectedDisk()\n *\n * @this {DriveController}\n */\n updateSelectedDisk()\n {\n var control = this.bindings[\"listDisks\"];\n var controlDesc = this.bindings[\"descDisk\"];\n var controlOption = control.options && control.options[control.selectedIndex];\n if (controlDesc && controlOption) {\n var dataValue = {};\n var sValue = controlOption.getAttribute(\"data-value\");\n if (sValue) {\n try {\n dataValue = eval(\"(\" + sValue + \")\");\n } catch (e) {\n Component.error(this.type + \" option error: \" + e.message);\n }\n }\n var sHTML = dataValue['desc'];\n if (sHTML === undefined) sHTML = \"\";\n var sHRef = dataValue['href'];\n if (sHRef !== undefined) sHTML = \"<a href=\\\"\" + sHRef + \"\\\" target=\\\"_blank\\\">\" + sHTML + \"</a>\";\n controlDesc.innerHTML = sHTML;\n }\n }\n\n /**\n * waitDrives(fnCallReady)\n *\n * @this {DriveController}\n * @param {function()|null} fnCallReady\n * @return {boolean} false if wait required, true otherwise\n */\n waitDrives(fnCallReady)\n {\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n var drive = this.aDrives[iDrive];\n if (drive && drive.fBusy) {\n if (!drive.fnCallReady) drive.fnCallReady = fnCallReady;\n return false;\n }\n }\n return true;\n }\n\n /**\n * unloadDrive(iDrive, fLoading)\n *\n * @this {DriveController}\n * @param {number} iDrive\n * @param {boolean} [fLoading]\n */\n unloadDrive(iDrive, fLoading)\n {\n var drive = this.aDrives[iDrive];\n\n if (drive.disk || fLoading === false) {\n\n /*\n * Before we toss the disk's information, capture any deltas that may have occurred.\n */\n this.updateDiskHistory(drive.sDiskName, drive.sDiskPath, drive.disk);\n\n drive.sDiskName = \"\";\n drive.sDiskPath = \"\";\n drive.disk = null;\n drive.fLocal = false;\n\n if (!fLoading) {\n this.notice(\"Drive \" + this.getDriveName(iDrive) + \" unloaded\", fLoading);\n this.sDiskSource = DriveController.SOURCE.NONE;\n this.displayDisk(iDrive);\n }\n\n /*\n * Inform the controller implementation (eg, RX11) of the disk removal.\n */\n this.notifyUnload(iDrive);\n }\n }\n\n /**\n * unloadAllDrives(fDiscard)\n *\n * @this {DriveController}\n * @param {boolean} fDiscard to discard all disk history before unloading\n */\n unloadAllDrives(fDiscard)\n {\n if (fDiscard) this.aDiskHistory = [];\n\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n this.unloadDrive(iDrive, true);\n }\n }\n\n /**\n * addDiskHistory(sDiskName, sDiskPath, disk)\n *\n * @this {DriveController}\n * @param {string} sDiskName\n * @param {string} sDiskPath\n * @param {DiskPDP11} disk containing corresponding disk image\n */\n addDiskHistory(sDiskName, sDiskPath, disk)\n {\n var i;\n\n for (i = 0; i < this.aDiskHistory.length; i++) {\n if (this.aDiskHistory[i][1] == sDiskPath) {\n var nChanges = disk.restore(this.aDiskHistory[i][2]);\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"disk '\" + sDiskName + \"' restored from history (\" + nChanges + \" changes)\");\n }\n return;\n }\n }\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"disk '\" + sDiskName + \"' added to history (nothing to restore)\");\n }\n this.aDiskHistory[i] = [sDiskName, sDiskPath, []];\n }\n\n /**\n * removeDiskHistory(sDiskName, sDiskPath)\n *\n * @this {DriveController}\n * @param {string} sDiskName\n * @param {string} sDiskPath\n */\n removeDiskHistory(sDiskName, sDiskPath)\n {\n var i;\n for (i = 0; i < this.aDiskHistory.length; i++) {\n if (this.aDiskHistory[i][1] == sDiskPath) {\n this.aDiskHistory.splice(i, 1);\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"disk '\" + sDiskName + \"' removed from history\");\n }\n return;\n }\n }\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"unable to remove disk '\" + sDiskName + \"' from history (\" + sDiskPath + \")\");\n }\n }\n\n /**\n * updateDiskHistory(sDiskName, sDiskPath, disk)\n *\n * @this {DriveController}\n * @param {string} sDiskName\n * @param {string} sDiskPath\n * @param {DiskPDP11} disk containing corresponding disk image, with possible deltas\n */\n updateDiskHistory(sDiskName, sDiskPath, disk)\n {\n var i;\n for (i = 0; i < this.aDiskHistory.length; i++) {\n if (this.aDiskHistory[i][1] == sDiskPath) {\n this.aDiskHistory[i][2] = disk.save();\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"disk '\" + sDiskName + \"' updated in history\");\n }\n return;\n }\n }\n /*\n * I used to report this as an error (at least in the DEBUG release), but it's no longer really\n * an error, because if we're trying to re-mount a clean copy of a disk, we toss its history, then\n * unload, and then reload/remount. And since unloadDrive's normal behavior is to call updateDiskHistory()\n * before unloading, the fact that the disk is no longer listed here can't be treated as an error.\n */\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"unable to update disk '\" + sDiskName + \"' in history (\" + sDiskPath + \")\");\n }\n }\n\n /**\n * notifyLoad(iDrive)\n *\n * Placeholder for subclasses. Called whenever DriveController has loaded a new disk into the specified drive.\n *\n * @this {RX11}\n * @param {number} iDrive\n */\n notifyLoad(iDrive)\n {\n }\n\n /**\n * notifyUnload(iDrive)\n *\n * Placeholder for subclasses. Called whenever DriveController has unloaded a disk from the specified drive.\n *\n * @this {RX11}\n * @param {number} iDrive\n */\n notifyUnload(iDrive)\n {\n }\n\n /**\n * readData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n *\n * Placeholder for subclasses. Implementation is optional, but the automatic BOOT feature will be unavailable.\n *\n * @this {DriveController}\n * @param {Object} drive\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nWords\n * @param {number} addr\n * @param {number} inc (normally 2, unless inhibited, in which case it's 0)\n * @param {boolean} [fCheck]\n * @param {function(...)} [done]\n * @return {boolean|number} true if complete, false if queued (or if no done() is supplied, the error code, if any)\n */\n readData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n {\n return -1;\n }\n\n /**\n * writeData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n *\n * Placeholder for subclasses. Implementation is optional.\n *\n * @this {DriveController}\n * @param {Object} drive\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nWords\n * @param {number} addr\n * @param {number} inc (normally 2, unless inhibited, in which case it's 0)\n * @param {boolean} [fCheck]\n * @param {function(...)} [done]\n * @return {boolean|number} true if complete, false if queued (or if no done() is supplied, the error code, if any)\n */\n writeData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n {\n return -1;\n }\n}\n\n/*\n * There's nothing super special about these values, except that NONE should be falsey and the others should not.\n */\nDriveController.SOURCE = {\n NONE: \"\",\n LOCAL: \"?\",\n REMOTE: \"??\"\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/rk11.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass RK11 extends DriveController {\n /**\n * RK11(parms)\n *\n * The RK11 component has the following component-specific (parms) properties:\n *\n * autoMount: one or more JSON-encoded objects, each containing 'name' and 'path' properties\n *\n * The RK11 Disk Controller controls up to eight RK05 disk drives, which in turn read/write RK03-KA\n * disk cartridges. See [RK11 Disk Controller Configuration Files](/devices/pdp11/rk11/).\n *\n * RK03 (or more precisely, RK03-KA) disks are single-platter cartridges with 203 tracks per side,\n * 12 sectors per track, and a sector size of 256 words (512 bytes), for a total capacity of 2.38Mb\n * (2,494,464 bytes). See [RK03-KA Disk Images](/disks/dec/rk03/).\n *\n * @param {Object} parms\n */\n constructor(parms)\n {\n super(\"RK11\", parms, MessagesPDP11.RK11, PDP11.RK11, PDP11.RK11.RK05, RK11.UNIBUS_IOTABLE);\n\n /*\n * Define all the registers required for this controller.\n *\n * TODO: Determine what we should really be doing with the RKDB register.\n */\n this.regRKDS = this.regRKER = this.regRKCS = this.regRKWC = this.regRKBA = this.regRKDA = this.regRKDB = 0;\n }\n\n /**\n * initController(aRegs)\n *\n * @this {RK11}\n * @param {Array} [aRegs]\n * @return {boolean} true if successful, false if failure\n */\n initController(aRegs)\n {\n if (!aRegs) {\n aRegs = [(RK11.RKDS.RK05 | RK11.RKDS.SOK | RK11.RKDS.RRDY), 0, (RK11.RKCS.CRDY), 0, 0, 0, 0];\n }\n\n /*\n * ES6 ALERT: A handy destructuring assignment, which makes it easy to perform the inverse\n * of what saveController() does when it collects a bunch of object properties into an array.\n */\n [\n this.regRKDS,\n this.regRKER,\n this.regRKCS,\n this.regRKWC,\n this.regRKBA,\n this.regRKDA,\n this.regRKDB\n ] = aRegs;\n\n return true;\n }\n\n /**\n * saveController()\n *\n * Basically, the inverse of initController().\n *\n * @this {RK11}\n * @return {Array}\n */\n saveController()\n {\n return [\n this.regRKDS,\n this.regRKER,\n this.regRKCS,\n this.regRKWC,\n this.regRKBA,\n this.regRKDA,\n this.regRKDB\n ];\n }\n\n /**\n * processCommand()\n *\n * @this {RK11}\n */\n processCommand()\n {\n var fInterrupt = true;\n var fnReadWrite, func, sFunc = \"\";\n var iDrive = (this.regRKDA & RK11.RKDA.DS) >> RK11.RKDA.SHIFT.DS;\n var drive = this.aDrives[iDrive];\n var iCylinder, iHead, iSector, nWords, addr, inc;\n\n this.regRKCS &= ~(RK11.RKCS.CRDY | RK11.RKCS.SCP);\n this.regRKER &= ~(RK11.RKER.SE);\n\n switch(func = this.regRKCS & RK11.RKCS.FUNC) {\n\n case RK11.FUNC.CRESET:\n if (this.messageEnabled()) this.printMessage(this.type + \": CRESET(\" + iDrive + \")\", true);\n this.regRKER = this.regRKDA = 0;\n this.regRKCS = RK11.RKCS.CRDY;\n break;\n\n case RK11.FUNC.RCHK:\n sFunc = \"RCHK\";\n /* falls through */\n\n case RK11.FUNC.READ:\n if (!sFunc) sFunc = \"READ\";\n fnReadWrite = this.readData;\n /* falls through */\n\n case RK11.FUNC.WCHK:\n if (!sFunc) sFunc = \"WCHK\";\n /* falls through */\n\n case RK11.FUNC.WRITE:\n if (!sFunc) sFunc = \"WRITE\";\n if (!fnReadWrite) fnReadWrite = this.writeData;\n\n iCylinder = (this.regRKDA & RK11.RKDA.CA) >> RK11.RKDA.SHIFT.CA;\n iHead = (this.regRKDA & RK11.RKDA.HS) >> RK11.RKDA.SHIFT.HS;\n iSector = this.regRKDA & RK11.RKDA.SA;\n nWords = (0x10000 - this.regRKWC) & 0xffff;\n addr = (((this.regRKCS & RK11.RKCS.MEX)) << (16 - RK11.RKCS.SHIFT.MEX)) | this.regRKBA;\n inc = (this.regRKCS & RK11.RKCS.IBA)? 0 : 2;\n\n if (this.messageEnabled()) this.printMessage(this.type + \": \" + sFunc + \"(\" + iCylinder + \":\" + iHead + \":\" + iSector + \") \" + Str.toOct(addr) + \"--\" + Str.toOct(addr + (nWords << 1)), true, true);\n\n if (iCylinder >= drive.nCylinders) {\n this.regRKER |= RK11.RKER.NXC;\n break;\n }\n if (iSector >= drive.nSectors) {\n this.regRKER |= RK11.RKER.NXS;\n break;\n }\n\n fInterrupt = fnReadWrite.call(this, drive, iCylinder, iHead, iSector, nWords, addr, inc, (func >= RK11.FUNC.WCHK), this.doneReadWrite.bind(this));\n break;\n\n case RK11.FUNC.SEEK:\n iCylinder = (this.regRKDA & RK11.RKDA.CA) >> RK11.RKDA.SHIFT.CA;\n if (this.messageEnabled()) this.printMessage(this.type + \": SEEK(\" + iCylinder + \")\", true);\n if (iCylinder < drive.nCylinders) {\n this.regRKCS |= RK11.RKCS.SCP;\n } else {\n this.regRKER |= RK11.RKER.NXC;\n }\n break;\n\n case RK11.FUNC.DRESET:\n if (this.messageEnabled()) this.printMessage(this.type + \": DRESET(\" + iDrive + \")\");\n this.regRKER = this.regRKDA = 0;\n this.regRKCS = RK11.RKCS.CRDY | RK11.RKCS.SCP;\n break;\n\n default:\n if (this.messageEnabled()) this.printMessage(this.type + \": UNSUPPORTED(\" + func + \")\");\n break;\n }\n\n this.regRKDS = drive.status | (drive.disk? RK11.RKDS.DRDY : 0) | (iDrive << RK11.RKDS.SHIFT.ID) | (this.regRKDA & RK11.RKDS.SC);\n\n this.updateErrors();\n\n if (fInterrupt) {\n this.regRKCS &= ~RK11.RKCS.GO;\n this.regRKCS |= RK11.RKCS.CRDY;\n if (this.regRKCS & RK11.RKCS.IE) this.cpu.setIRQ(this.irq);\n }\n }\n\n /**\n * readData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n *\n * @this {RK11}\n * @param {Object} drive\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nWords\n * @param {number} addr\n * @param {number} inc (normally 2, unless inhibited, in which case it's 0)\n * @param {boolean} [fCheck]\n * @param {function(...)} [done]\n * @return {boolean|number} true if complete, false if queued (or if no done() is supplied, the error code, if any)\n */\n readData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n {\n var nError = 0;\n var disk = drive.disk;\n var sector = null, ibSector;\n\n if (!disk) {\n nError = RK11.RKER.NXD;\n nWords = 0;\n }\n\n var sWords = \"\";\n while (nWords) {\n if (!sector) {\n if (iCylinder >= disk.nCylinders) {\n nError = RK11.RKER.NXC;\n break;\n }\n sector = disk.seek(iCylinder, iHead, iSector + 1);\n if (!sector) {\n nError = RK11.RKER.SKE;\n break;\n }\n ibSector = 0;\n if (++iSector >= disk.nSectors) {\n iSector = 0;\n if (++iHead >= disk.nHeads) {\n iHead = 0;\n ++iCylinder;\n }\n }\n }\n var b0, b1;\n if ((b0 = disk.read(sector, ibSector++)) < 0 || (b1 = disk.read(sector, ibSector++)) < 0) {\n nError = RK11.RKER.NXS;\n break;\n }\n if (!fCheck) {\n var data = b0 | (b1 << 8);\n this.bus.setWordDirect(this.cpu.mapUnibus(addr), data);\n if (DEBUG && this.messageEnabled(MessagesPDP11.READ)) {\n if (!sWords) sWords = Str.toOct(addr) + \": \";\n sWords += Str.toOct(data) + ' ';\n if (sWords.length >= 64) {\n console.log(sWords);\n sWords = \"\";\n }\n }\n if (this.bus.checkFault()) {\n nError = RK11.RKER.NXM;\n break;\n }\n }\n if (ibSector >= disk.cbSector) sector = null;\n addr += inc;\n nWords--;\n }\n return done? done(nError, iCylinder, iHead, iSector, nWords, addr) : nError;\n }\n\n /**\n * writeData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n *\n * @this {RK11}\n * @param {Object} drive\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nWords\n * @param {number} addr\n * @param {number} inc (normally 2, unless inhibited, in which case it's 0)\n * @param {boolean} [fCheck]\n * @param {function(...)} [done]\n * @return {boolean|number} true if complete, false if queued (or if no done() is supplied, the error code, if any)\n */\n writeData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n {\n var nError = 0;\n var disk = drive.disk;\n var sector = null, ibSector;\n\n if (!disk) {\n nError = RK11.RKER.NXD;\n nWords = 0;\n }\n\n while (nWords) {\n var data = this.bus.getWordDirect(this.cpu.mapUnibus(addr));\n if (this.bus.checkFault()) {\n nError = RK11.RKER.NXM;\n break;\n }\n if (!sector) {\n if (iCylinder >= disk.nCylinders) {\n nError = RK11.RKER.NXC;\n break;\n }\n sector = disk.seek(iCylinder, iHead, iSector + 1, true);\n if (!sector) {\n nError = RK11.RKER.SKE;\n break;\n }\n ibSector = 0;\n if (++iSector >= disk.nSectors) {\n iSector = 0;\n if (++iHead >= disk.nHeads) {\n iHead = 0;\n ++iCylinder;\n }\n }\n }\n if (fCheck) {\n var b0, b1;\n if ((b0 = disk.read(sector, ibSector++)) < 0 || (b1 = disk.read(sector, ibSector++)) < 0) {\n nError = RK11.RKER.NXS;\n break;\n }\n /*\n * NOTE: During the 11/70 CPU EXERCISER diagnostic, a number of WCHK requests will fail\n * when the test starts reading/writing with physical addresses > 177777. I'm pretty sure all\n * the UNIBUS address calculations are fine, and therefore those failures are expected.\n *\n * Originally, those failures were causing me some grief because I was treating a WCE error like\n * any other error; ie, as a HARD error. That was wrong. Two errors (WCE and CSE) are soft\n * errors, so while they should still trigger the general-purpose RKCS ERR bit, they should NOT\n * trigger the RKCS HE (Hard Error) bit. This is all taken care of in updateErrors() now.\n */\n if (data != (b0 | (b1 << 8))) {\n nError = RK11.RKER.WCE;\n break;\n }\n } else {\n if (!disk.write(sector, ibSector++, data & 0xff) || !disk.write(sector, ibSector++, data >> 8)) {\n nError = RK11.RKER.NXS;\n break;\n }\n }\n if (ibSector >= disk.cbSector) sector = null;\n addr += inc;\n nWords--;\n }\n return done? done(nError, iCylinder, iHead, iSector, nWords, addr) : nError;\n }\n\n /**\n * doneReadWrite(nError, iCylinder, iHead, iSector, nWords, addr)\n *\n * @this {RK11}\n * @param {number} nError\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nWords\n * @param {number} addr\n * @return {boolean}\n */\n doneReadWrite(nError, iCylinder, iHead, iSector, nWords, addr)\n {\n this.regRKBA = addr & 0xffff;\n this.regRKCS = (this.regRKCS & ~RK11.RKCS.MEX) | ((addr >> (16 - RK11.RKCS.SHIFT.MEX)) & RK11.RKCS.MEX);\n this.regRKWC = (0x10000 - nWords) & 0xffff;\n this.regRKDA = (this.regRKDA & ~RK11.RKDA.SA) | (iSector & RK11.RKDA.SA);\n this.regRKER |= nError;\n this.updateErrors();\n return true;\n }\n\n /**\n * updateErrors()\n *\n * @this {RK11}\n */\n updateErrors()\n {\n /*\n * Reflect RKER bits to RKCS bits as appropriate.\n *\n * TODO: I'm not entirely sure about the handling of the DRE bit here. DEC's RK11 documentation says:\n *\n * Sets if one of the drives in the system senses a loss of either AC or DC power and a function is\n * either initiated or in process while the selected drive is not ready or in some error condition.\n *\n * I'm not sure how to parse all the \"ands\" and \"ors\" in that sentence. For now, we're treating the DRE bit\n * much like the high error bit found in other hardware registers: we always set it if any lower error bits\n * are also set.\n */\n this.regRKCS &= ~RK11.RKCS.ERR;\n if (this.regRKER) {\n this.regRKER |= RK11.RKER.DRE;\n this.regRKCS |= RK11.RKCS.ERR;\n if (this.regRKER & RK11.RKER.HE) this.regRKCS |= RK11.RKCS.HE;\n if (this.messageEnabled()) this.printMessage(this.type + \": ERROR: \" + Str.toOct(this.regRKER));\n }\n }\n\n /**\n * readRKDS(addr)\n *\n * @this {RK11}\n * @param {number} addr (eg, PDP11.UNIBUS.RKDS or 177400)\n * @return {number}\n */\n readRKDS(addr)\n {\n return this.regRKDS;\n }\n\n /**\n * writeRKDS(data, addr)\n *\n * @this {RK11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RKDS or 177400)\n */\n writeRKDS(data, addr)\n {\n /*\n * This is a read-only register\n */\n }\n\n /**\n * readRKER(addr)\n *\n * @this {RK11}\n * @param {number} addr (eg, PDP11.UNIBUS.RKER or 177402)\n * @return {number}\n */\n readRKER(addr)\n {\n return this.regRKER;\n }\n\n /**\n * writeRKER(data, addr)\n *\n * @this {RK11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RKER or 177402)\n */\n writeRKER(data, addr)\n {\n /*\n * This is a read-only register\n */\n }\n\n /**\n * readRKCS(addr)\n *\n * @this {RK11}\n * @param {number} addr (eg, PDP11.UNIBUS.RKCS or 177404)\n * @return {number}\n */\n readRKCS(addr)\n {\n return this.regRKCS & RK11.RKCS.RMASK;\n }\n\n /**\n * writeRKCS(data, addr)\n *\n * @this {RK11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RKCS or 177404)\n */\n writeRKCS(data, addr)\n {\n this.regRKCS = (this.regRKCS & ~RK11.RKCS.WMASK) | (data & RK11.RKCS.WMASK);\n\n if (this.regRKCS & RK11.RKCS.GO) this.processCommand();\n }\n\n /**\n * readRKWC(addr)\n *\n * @this {RK11}\n * @param {number} addr (eg, PDP11.UNIBUS.RKWC or 177406)\n * @return {number}\n */\n readRKWC(addr)\n {\n return this.regRKWC;\n }\n\n /**\n * writeRKWC(data, addr)\n *\n * @this {RK11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RKWC or 177406)\n */\n writeRKWC(data, addr)\n {\n this.regRKWC = data;\n }\n\n /**\n * readRKBA(addr)\n *\n * @this {RK11}\n * @param {number} addr (eg, PDP11.UNIBUS.RKBA or 177410)\n * @return {number}\n */\n readRKBA(addr)\n {\n return this.regRKBA;\n }\n\n /**\n * writeRKBA(data, addr)\n *\n * @this {RK11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RKBA or 177410)\n */\n writeRKBA(data, addr)\n {\n this.regRKBA = data;\n }\n\n /**\n * readRKDA(addr)\n *\n * @this {RK11}\n * @param {number} addr (eg, PDP11.UNIBUS.RKDA or 177412)\n * @return {number}\n */\n readRKDA(addr)\n {\n return this.regRKDA;\n }\n\n /**\n * writeRKDA(data, addr)\n *\n * @this {RK11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RKDA or 177412)\n */\n writeRKDA(data, addr)\n {\n this.regRKDA = data;\n }\n\n /**\n * readRKDB(addr)\n *\n * @this {RK11}\n * @param {number} addr (eg, PDP11.UNIBUS.RKDB or 177416)\n * @return {number}\n */\n readRKDB(addr)\n {\n return this.regRKDB;\n }\n\n /**\n * writeRKDB(data, addr)\n *\n * @this {RK11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RKDB or 177416)\n */\n writeRKDB(data, addr)\n {\n this.regRKDB = data;\n }\n}\n\n/*\n * Alias RK11 definitions as class constants\n */\nRK11.RKDS = PDP11.RK11.RKDS; // 177400: Drive Status Register\nRK11.RKER = PDP11.RK11.RKER; // 177402: Error Register\nRK11.RKCS = PDP11.RK11.RKCS; // 177404: Control Status Register\nRK11.RKDA = PDP11.RK11.RKDA; // 177412: Disk Address Register\nRK11.FUNC = PDP11.RK11.FUNC;\n\n/*\n * ES6 ALERT: As you can see below, I've finally started using computed property names.\n */\nRK11.UNIBUS_IOTABLE = {\n [PDP11.UNIBUS.RKDS]: /* 177400 */ [null, null, RK11.prototype.readRKDS, RK11.prototype.writeRKDS, \"RKDS\"],\n [PDP11.UNIBUS.RKER]: /* 177402 */ [null, null, RK11.prototype.readRKER, RK11.prototype.writeRKER, \"RKER\"],\n [PDP11.UNIBUS.RKCS]: /* 177404 */ [null, null, RK11.prototype.readRKCS, RK11.prototype.writeRKCS, \"RKCS\"],\n [PDP11.UNIBUS.RKWC]: /* 177406 */ [null, null, RK11.prototype.readRKWC, RK11.prototype.writeRKWC, \"RKWC\"],\n [PDP11.UNIBUS.RKBA]: /* 177410 */ [null, null, RK11.prototype.readRKBA, RK11.prototype.writeRKBA, \"RKBA\"],\n [PDP11.UNIBUS.RKDA]: /* 177412 */ [null, null, RK11.prototype.readRKDA, RK11.prototype.writeRKDA, \"RKDA\"],\n [PDP11.UNIBUS.RKDB]: /* 177416 */ [null, null, RK11.prototype.readRKDB, RK11.prototype.writeRKDB, \"RKDB\"]\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/rl11.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass RL11 extends DriveController {\n /**\n * RL11(parms)\n *\n * The RL11 component has the following component-specific (parms) properties:\n *\n * autoMount: one or more JSON-encoded objects, each containing 'name' and 'path' properties\n *\n * The RL11 Disk Controller controls up to four RL01 or RL02 disk drives, which in turn read/write RL01K or\n * RL02K disk cartridges. See [RL11 Disk Controller Configuration Files](/devices/pdp11/rl11/).\n *\n * RL01K disks are single-platter cartridges with 256 tracks per side, 40 sectors per track, and a sector size\n * of 256 bytes, for a total capacity of 5Mb (5,242,880 bytes). See [RL01K Disk Images](/disks/dec/rl01k/).\n *\n * RL02K disks are single-platter cartridges with 512 tracks per side, 40 sectors per track, and a sector size\n * of 256 bytes, for a total capacity of 10Mb (10,485,760 bytes). See [RL02K Disk Images](/disks/dec/rl02k/).\n *\n * @param {Object} parms\n */\n constructor(parms)\n {\n super(\"RL11\", parms, MessagesPDP11.RL11, PDP11.RL11, PDP11.RL11.RL02K, RL11.UNIBUS_IOTABLE);\n\n /*\n * Define all the registers required for this controller.\n */\n this.regRLCS = this.regRLBA = this.regRLDA = this.tmpRLDA = this.regRLMP = this.regRLBE = 0;\n }\n\n /**\n * initController(aRegs)\n *\n * @this {RL11}\n * @param {Array} [aRegs]\n * @return {boolean} true if successful, false if failure\n */\n initController(aRegs)\n {\n if (!aRegs) {\n aRegs = [(RL11.RLCS.DRDY | RL11.RLCS.CRDY), 0, 0, 0, 0, 0];\n }\n\n /*\n * ES6 ALERT: A handy destructuring assignment, which makes it easy to perform the inverse\n * of what saveController() does when it collects a bunch of object properties into an array.\n */\n [\n this.regRLCS,\n this.regRLBA,\n this.regRLDA,\n this.tmpRLDA,\n this.regRLMP,\n this.regRLBE\n ] = aRegs;\n\n return true;\n }\n\n /**\n * saveController()\n *\n * Basically, the inverse of initController().\n *\n * @this {RL11}\n * @return {Array}\n */\n saveController()\n {\n return [\n this.regRLCS,\n this.regRLBA,\n this.regRLDA,\n this.tmpRLDA,\n this.regRLMP,\n this.regRLBE\n ];\n }\n\n /**\n * processCommand()\n *\n * @this {RL11}\n */\n processCommand()\n {\n var fInterrupt = true;\n var fnReadWrite, sFunc = \"\";\n var iDrive = (this.regRLCS & RL11.RLCS.DS) >> RL11.RLCS.SHIFT.DS;\n var drive = this.aDrives[iDrive];\n var disk = drive.disk;\n var iCylinder, iHead, iSector, nWords, addr;\n\n /*\n * The typical pattern of DRDY and CRDY:\n *\n * 1) Normally both set\n * 2) CRDY is cleared to process a command\n * 3) DRDY is cleared to indicate a command in process\n */\n this.regRLCS &= ~RL11.RLCS.DRDY;\n\n switch(this.regRLCS & RL11.RLCS.FUNC) {\n\n case RL11.FUNC.NOP:\n case RL11.FUNC.WCHK:\n case RL11.FUNC.RDNC:\n break;\n\n case RL11.FUNC.STATUS:\n if (this.regRLMP & RL11.RLMP.GS_BH) {\n this.regRLCS &= (RL11.RLCS.DRDY | RL11.RLCS.FUNC | RL11.RLCS.BAE); // TODO: Review\n }\n /*\n * The bit indicating whether or not the disk contains 256 or 512 cylinders is critical;\n * for example, the first RSTS/E disk image we tried was an RL01K, which has only 256 cylinders,\n * and the operating system would crash mysteriously if we didn't report the correct geometry.\n */\n this.regRLMP = drive.status | (this.tmpRLDA & RL11.RLDA.RW_HS) | (disk && disk.nCylinders == 512? RL11.RLMP.GS_DT : 0);\n break;\n\n case RL11.FUNC.SEEK:\n if ((this.regRLDA & RL11.RLDA.GS_CMD) == RL11.RLDA.SEEK_CMD) {\n var darCA = (this.regRLDA & RL11.RLDA.RW_CA);\n var darHS = (this.regRLDA & RL11.RLDA.SEEK_HS) << 2;\n if (this.regRLDA & RL11.RLDA.SEEK_DIR) {\n this.tmpRLDA += darCA;\n } else {\n this.tmpRLDA -= darCA;\n }\n this.regRLDA = this.tmpRLDA = (this.tmpRLDA & RL11.RLDA.RW_CA) | darHS;\n }\n break;\n\n case RL11.FUNC.RHDR:\n this.regRLMP = this.tmpRLDA;\n break;\n\n case RL11.FUNC.RDATA:\n sFunc = \"READ\";\n fnReadWrite = this.readData;\n /* falls through */\n\n case RL11.FUNC.WDATA:\n if (!sFunc) sFunc = \"WRITE\";\n if (!fnReadWrite) fnReadWrite = this.writeData;\n\n iCylinder = this.regRLDA >> RL11.RLDA.SHIFT.RW_CA;\n iHead = (this.regRLDA & RL11.RLDA.RW_HS)? 1 : 0;\n iSector = this.regRLDA & RL11.RLDA.RW_SA;\n if (!disk || iCylinder >= disk.nCylinders || iSector >= disk.nSectors) {\n this.regRLCS |= RL11.ERRC.HNF | RL11.RLCS.ERR;\n break;\n }\n nWords = (0x10000 - this.regRLMP) & 0xffff;\n addr = (((this.regRLBE & RL11.RLBE.MASK)) << 16) | this.regRLBA; // 22 bit mode\n\n if (this.messageEnabled()) this.printMessage(this.type + \": \" + sFunc + \"(\" + iCylinder + \":\" + iHead + \":\" + iSector + \") \" + Str.toOct(addr) + \"--\" + Str.toOct(addr + (nWords << 1)), true, true);\n\n fInterrupt = fnReadWrite.call(this, drive, iCylinder, iHead, iSector, nWords, addr, 2, false, this.doneReadWrite.bind(this));\n break;\n\n default:\n break;\n }\n\n if (fInterrupt) {\n this.regRLCS |= RL11.RLCS.DRDY | RL11.RLCS.CRDY;\n if (this.regRLCS & RL11.RLCS.IE) this.cpu.setIRQ(this.irq);\n }\n }\n\n /**\n * readData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n *\n * @this {RL11}\n * @param {Object} drive\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nWords\n * @param {number} addr\n * @param {number} inc (normally 2, unless inhibited, in which case it's 0)\n * @param {boolean} [fCheck]\n * @param {function(...)} [done]\n * @return {boolean|number} true if complete, false if queued (or if no done() is supplied, the error code, if any)\n */\n readData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n {\n var nError = 0;\n var checksum = 0;\n var disk = drive.disk;\n var sector = null, ibSector;\n\n if (!disk) {\n nError = RL11.ERRC.HNF; // TODO: Review\n nWords = 0;\n }\n\n var sWords = \"\";\n while (nWords) {\n if (!sector) {\n sector = disk.seek(iCylinder, iHead, iSector + 1);\n if (!sector) {\n nError = RL11.ERRC.HNF;\n break;\n }\n ibSector = 0;\n }\n var b0, b1, data;\n if ((b0 = disk.read(sector, ibSector++)) < 0 || (b1 = disk.read(sector, ibSector++)) < 0) {\n nError = RL11.ERRC.HNF;\n break;\n }\n /*\n * Apparently, this controller honors the UNIBUS Map registers, which means we must call mapUnibus()\n * on the address REGARDLESS whether it is actually >= BusPDP11.UNIBUS_22BIT. TODO: This is inherited\n * code, so let's review the documentation on this.\n */\n this.bus.setWordDirect(this.cpu.mapUnibus(addr), data = b0 | (b1 << 8));\n if (DEBUG && this.messageEnabled(MessagesPDP11.READ)) {\n if (!sWords) sWords = Str.toOct(addr) + \": \";\n sWords += Str.toOct(data) + ' ';\n if (sWords.length >= 64) {\n console.log(sWords);\n sWords = \"\";\n }\n }\n if (this.bus.checkFault()) {\n nError = RL11.ERRC.NXM;\n break;\n }\n addr += 2;\n nWords--;\n checksum += data;\n if (ibSector >= disk.cbSector) {\n sector = null;\n if (++iSector >= disk.nSectors) {\n iSector = 0;\n if (++iHead >= disk.nHeads) {\n iHead = 0;\n if (++iCylinder >= disk.nCylinders) {\n nError = RL11.ERRC.HNF;\n break;\n }\n }\n }\n }\n }\n\n if (DEBUG && this.messageEnabled(MessagesPDP11.READ)) {\n console.log(\"checksum: \" + (checksum|0));\n }\n\n return done? done(nError, iCylinder, iHead, iSector, nWords, addr) : nError;\n }\n\n /**\n * writeData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n *\n * @this {RL11}\n * @param {Object} drive\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nWords\n * @param {number} addr\n * @param {number} inc (normally 2, unless inhibited, in which case it's 0)\n * @param {boolean} [fCheck]\n * @param {function(...)} [done]\n * @return {boolean|number} true if complete, false if queued (or if no done() is supplied, the error code, if any)\n */\n writeData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n {\n var nError = 0;\n var checksum = 0;\n var disk = drive.disk;\n var sector = null, ibSector;\n\n if (!disk) {\n nError = RL11.ERRC.HNF; // TODO: Review\n nWords = 0;\n }\n\n var sWords = \"\";\n while (nWords) {\n /*\n * Apparently, this controller honors the UNIBUS Map registers, which means we must call mapUnibus()\n * on the address REGARDLESS whether it is actually >= BusPDP11.UNIBUS_22BIT. TODO: This is inherited\n * code, so let's review the documentation on this.\n */\n var data = this.bus.getWordDirect(this.cpu.mapUnibus(addr));\n if (this.bus.checkFault()) {\n nError = RL11.ERRC.NXM;\n break;\n }\n if (DEBUG && this.messageEnabled(MessagesPDP11.WRITE)) {\n if (!sWords) sWords = Str.toOct(addr) + \": \";\n sWords += Str.toOct(data) + ' ';\n if (sWords.length >= 64) {\n console.log(sWords);\n sWords = \"\";\n }\n }\n addr += 2;\n nWords--;\n checksum += data;\n if (!sector) {\n sector = disk.seek(iCylinder, iHead, iSector + 1, true);\n if (!sector) {\n nError = RL11.ERRC.HNF;\n break;\n }\n ibSector = 0;\n }\n if (!disk.write(sector, ibSector++, data & 0xff) || !disk.write(sector, ibSector++, data >> 8)) {\n nError = RL11.ERRC.HNF;\n break;\n }\n if (ibSector >= disk.cbSector) {\n sector = null;\n if (++iSector >= disk.nSectors) {\n iSector = 0;\n if (++iHead >= disk.nHeads) {\n iHead = 0;\n if (++iCylinder >= disk.nCylinders) {\n nError = RL11.ERRC.HNF;\n break;\n }\n }\n }\n }\n }\n\n if (DEBUG && this.messageEnabled(MessagesPDP11.WRITE)) {\n console.log(\"checksum: \" + (checksum|0));\n }\n\n return done? done(nError, iCylinder, iHead, iSector, nWords, addr) : nError;\n }\n\n /**\n * doneReadWrite(nError, iCylinder, iHead, iSector, nWords, addr)\n *\n * @this {RL11}\n * @param {number} nError\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nWords\n * @param {number} addr\n * @return {boolean}\n */\n doneReadWrite(nError, iCylinder, iHead, iSector, nWords, addr)\n {\n this.regRLBA = addr & 0xffff;\n this.regRLCS = (this.regRLCS & ~RL11.RLCS.BAE) | ((addr >> (16 - RL11.RLCS.SHIFT.BAE)) & RL11.RLCS.BAE);\n this.regRLBE = (addr >> 16) & RL11.RLBE.MASK; // 22 bit mode\n this.regRLDA = (iCylinder << RL11.RLDA.SHIFT.RW_CA) | (iHead? RL11.RLDA.RW_HS : 0) | (iSector & RL11.RLDA.RW_SA);\n this.tmpRLDA = this.regRLDA;\n this.regRLMP = (0x10000 - nWords) & 0xffff;\n if (nError) {\n this.regRLCS |= nError | RL11.RLCS.ERR;\n }\n return true;\n }\n\n /**\n * readRLCS(addr)\n *\n * @this {RL11}\n * @param {number} addr (eg, PDP11.UNIBUS.RLCS or 174400)\n * @return {number}\n */\n readRLCS(addr)\n {\n return this.regRLCS & RL11.RLCS.RMASK;\n }\n\n /**\n * writeRLCS(data, addr)\n *\n * @this {RL11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RLCS or 174400)\n */\n writeRLCS(data, addr)\n {\n this.regRLCS = (this.regRLCS & ~RL11.RLCS.WMASK) | (data & RL11.RLCS.WMASK);\n this.regRLBE = (this.regRLBE & 0x3C) | ((data & RL11.RLCS.BAE) >> RL11.RLCS.SHIFT.BAE);\n if (!(this.regRLCS & RL11.RLCS.CRDY)) this.processCommand();\n }\n\n /**\n * readRLBA(addr)\n *\n * @this {RL11}\n * @param {number} addr (eg, PDP11.UNIBUS.RLBA or 174402)\n * @return {number}\n */\n readRLBA(addr)\n {\n return this.regRLBA;\n }\n\n /**\n * writeRLBA(data, addr)\n *\n * @this {RL11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RLBA or 174402)\n */\n writeRLBA(data, addr)\n {\n this.regRLBA = data & RL11.RLBA.WMASK;\n }\n\n /**\n * readRLDA(addr)\n *\n * @this {RL11}\n * @param {number} addr (eg, PDP11.UNIBUS.RLDA or 174404)\n * @return {number}\n */\n readRLDA(addr)\n {\n return this.regRLDA;\n }\n\n /**\n * writeRLDA(data, addr)\n *\n * @this {RL11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RLDA or 174404)\n */\n writeRLDA(data, addr)\n {\n this.regRLDA = data;\n }\n\n /**\n * readRLMP(addr)\n *\n * @this {RL11}\n * @param {number} addr (eg, PDP11.UNIBUS.RLMP or 174406)\n * @return {number}\n */\n readRLMP(addr)\n {\n return this.regRLMP;\n }\n\n /**\n * writeRLMP(data, addr)\n *\n * @this {RL11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RLMP or 174406)\n */\n writeRLMP(data, addr)\n {\n this.regRLMP = data;\n }\n\n /**\n * readRLBE(addr)\n *\n * @this {RL11}\n * @param {number} addr (eg, PDP11.UNIBUS.RLBE or 174410)\n * @return {number}\n */\n readRLBE(addr)\n {\n return this.regRLBE;\n }\n\n /**\n * writeRLBE(data, addr)\n *\n * Curiously, we see RSTS/E v7.0 writing RLBE bits that aren't documented:\n *\n * R0=000000 R1=000000 R2=174410 R3=000000 R4=102076 R5=045166\n * SP=052662 PC=067624 PS=034344 IR=000000 SL=000377 T0 N0 Z1 V0 C0\n * 067624: 012712 000300 MOV #300,@R2\n *\n * @this {RL11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RLBE or 174410)\n */\n writeRLBE(data, addr)\n {\n this.regRLBE = data & RL11.RLBE.MASK;\n this.regRLCS = (this.regRLCS & ~RL11.RLCS.BAE) | ((this.regRLBE & 0x3) << RL11.RLCS.SHIFT.BAE);\n }\n}\n\n/*\n * Alias RL11 definitions as class constants\n */\nRL11.RLCS = PDP11.RL11.RLCS; // 174400: Control Status Register\nRL11.RLBA = PDP11.RL11.RLBA; // 174402: Bus Address Register\nRL11.RLDA = PDP11.RL11.RLDA; // 174404: Disk Address Register\nRL11.RLMP = PDP11.RL11.RLMP; // 177406: Multi-Purpose Register\nRL11.RLBE = PDP11.RL11.RLBE; // 174410: Bus (Address) Extension Register\nRL11.ERRC = PDP11.RL11.ERRC; // NOTE: These error codes are pre-shifted to read/write directly from/to RLCS.ERRC\nRL11.FUNC = PDP11.RL11.FUNC; // NOTE: These function codes are pre-shifted to read/write directly from/to RLCS.FUNC\n\n/*\n * ES6 ALERT: As you can see below, I've finally started using computed property names.\n */\nRL11.UNIBUS_IOTABLE = {\n [PDP11.UNIBUS.RLCS]: /* 174400 */ [null, null, RL11.prototype.readRLCS, RL11.prototype.writeRLCS, \"RLCS\"],\n [PDP11.UNIBUS.RLBA]: /* 174402 */ [null, null, RL11.prototype.readRLBA, RL11.prototype.writeRLBA, \"RLBA\"],\n [PDP11.UNIBUS.RLDA]: /* 174404 */ [null, null, RL11.prototype.readRLDA, RL11.prototype.writeRLDA, \"RLDA\"],\n [PDP11.UNIBUS.RLMP]: /* 174406 */ [null, null, RL11.prototype.readRLMP, RL11.prototype.writeRLMP, \"RLMP\"],\n [PDP11.UNIBUS.RLBE]: /* 174410 */ [null, null, RL11.prototype.readRLBE, RL11.prototype.writeRLBE, \"RLBE\"]\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/rx11.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass RX11 extends DriveController {\n /**\n * RX11(parms)\n *\n * The RX11 component has the following component-specific (parms) properties:\n *\n * autoMount: one or more JSON-encoded objects, each containing 'name' and 'path' properties\n *\n * The RX11 Disk Controller controls up to two RX01 disk drives, which in turn read/write\n * disk cartridges. See [RX11 Disk Controller Configuration Files](/devices/pdp11/rx11/).\n *\n * RX01 diskettes are single-sided, with 77 tracks per side, 26 sectors per track, and a sector size\n * of 128 bytes, for a total capacity of 250Kb (256,256 bytes). See [RX01 Disk Images](/disks/dec/rx01/).\n *\n * @param {Object} parms\n */\n constructor(parms)\n {\n super(\"RX11\", parms, MessagesPDP11.RX11, PDP11.RX11, PDP11.RX11.RX01, RX11.UNIBUS_IOTABLE);\n\n /*\n * Define all the registers required for this controller.\n */\n this.regRXCS = this.regRXDB = 0;\n this.regRXTA = this.regRXSA = this.regRXES = this.regError = 0;\n\n /*\n * Whenever a command is issued, we record the function code internally here, and when the command\n * is completed, we set the internal function code back to UNUSED.\n */\n this.funCode = RX11.FUNC.UNUSED; // no function in progress (device is idle)\n\n this.iBuffer = 0;\n /*\n * We use the new ES6 fill() method to ensure that the buffer returns something reasonable if, for some\n * strange reason, the first command we receive is an Empty Buffer command.\n */\n this.abBuffer = new Array(128).fill(0);\n }\n\n /**\n * initController(aRegs)\n *\n * @this {RX11}\n * @param {Array} [aRegs]\n * @return {boolean} true if successful, false if failure\n */\n initController(aRegs)\n {\n if (!aRegs) {\n this.regRXCS = 0;\n this.regRXDB = 0;\n this.regRXTA = 1;\n this.regRXSA = 1;\n this.regRXES = 0;\n this.regError = 0;\n this.funCode = RX11.FUNC.READ;\n this.iBuffer = 0;\n this.cpu.clearIRQ(this.irq);\n this.readSector();\n }\n else {\n /*\n * ES6 ALERT: A handy destructuring assignment, which makes it easy to perform the inverse\n * of what saveController() does when it collects a bunch of object properties into an array.\n */\n [\n this.regRXCS,\n this.regRXDB,\n this.regRXTA,\n this.regRXSA,\n this.regRXES,\n this.regError,\n this.funCode,\n this.iBuffer,\n this.abBuffer\n ] = aRegs;\n }\n return true;\n }\n\n /**\n * saveController()\n *\n * Basically, the inverse of initController().\n *\n * @this {RX11}\n * @return {Array}\n */\n saveController()\n {\n return [\n this.regRXCS,\n this.regRXDB,\n this.regRXTA,\n this.regRXSA,\n this.regRXES,\n this.regError,\n this.funCode,\n this.iBuffer,\n this.abBuffer\n ];\n }\n\n /**\n * notifyLoad(iDrive)\n *\n * Called whenever DriveController has loaded a new disk into the specified drive.\n *\n * We're interested in this so that whenever a disk change occurs for drive 0, we can automatically\n * refill the sector buffer with the data from sector 1 from track 1.\n *\n * @this {RX11}\n * @param {number} iDrive\n */\n notifyLoad(iDrive)\n {\n if (iDrive == 0) this.initController();\n }\n\n /**\n * notifyUnload(iDrive)\n *\n * Called whenever DriveController has unloaded a disk from the specified drive.\n *\n * @this {RX11}\n * @param {number} iDrive\n */\n notifyUnload(iDrive)\n {\n }\n\n /**\n * processCommand()\n *\n * @this {RX11}\n */\n processCommand()\n {\n this.funCode = this.regRXCS & RX11.RXCS.FUNC;\n this.regRXCS &= ~(RX11.RXCS.GO | RX11.RXCS.TR | RX11.RXCS.DONE | RX11.RXCS.ERR);\n this.cpu.clearIRQ(this.irq);\n\n if (this.messageEnabled()) this.printMessage(this.type + \".processCommand(\" + RX11.FUNCS[this.funCode >> 1]+ \")\", true, true);\n\n switch(this.funCode) {\n\n case RX11.FUNC.FILL:\n case RX11.FUNC.EMPTY:\n case RX11.FUNC.READ:\n case RX11.FUNC.WRITE:\n case RX11.FUNC.WRDEL:\n this.initCommand();\n break;\n\n case RX11.FUNC.RDSTAT:\n this.readStatus();\n break;\n\n case RX11.FUNC.RDERR:\n this.readError();\n break;\n\n default:\n\n break;\n }\n }\n\n /**\n * initCommand()\n *\n * @this {RX11}\n */\n initCommand()\n {\n this.iBuffer = 0;\n }\n\n /**\n * doneCommand(nError)\n *\n * @this {RX11}\n * @param {number} [nError]\n */\n doneCommand(nError)\n {\n if (nError) {\n this.regError = nError;\n this.regRXDB = this.regRXES;\n this.regRXCS |= RX11.RXCS.ERR;\n }\n this.funCode = RX11.FUNC.UNUSED;\n this.regRXCS |= RX11.RXCS.DONE;\n if (this.regRXCS & RX11.RXCS.IE) this.cpu.setIRQ(this.irq);\n }\n\n /**\n * readData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n *\n * This function is required ONLY if we want to support DriveController's bootSelectedDisk() function (and we do).\n *\n * @this {RX11}\n * @param {Object} drive\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nWords\n * @param {number} addr\n * @param {number} inc (normally 2, unless inhibited, in which case it's 0)\n * @param {boolean} [fCheck]\n * @param {function(...)} [done]\n * @return {boolean|number} true if complete, false if queued (or if no done() is supplied, the error code, if any)\n */\n readData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n {\n var nError = 0;\n var disk = drive.disk;\n var sector = null, ibSector;\n\n if (this.messageEnabled()) this.printMessage(this.type + \".readData(\" + iCylinder + \":\" + iHead + \":\" + iSector + \") \" + Str.toOct(addr) + \"--\" + Str.toOct(addr + (nWords << 1)), true, true);\n\n if (!disk) {\n nError = drive.iDrive? RX11.ERROR.HOME1 : RX11.ERROR.HOME0;\n nWords = 0;\n }\n\n var sWords = \"\";\n while (nWords) {\n if (!sector) {\n if (iCylinder >= disk.nCylinders) {\n nError = RX11.ERROR.NO_TRACK;\n break;\n }\n sector = disk.seek(iCylinder, iHead, iSector + 1);\n if (!sector) {\n nError = RX11.ERROR.NO_SECTOR;\n break;\n }\n ibSector = 0;\n if (++iSector >= disk.nSectors) {\n iSector = 0;\n if (++iHead >= disk.nHeads) {\n iHead = 0;\n ++iCylinder;\n }\n }\n }\n var b0, b1;\n if ((b0 = disk.read(sector, ibSector++)) < 0 || (b1 = disk.read(sector, ibSector++)) < 0) {\n nError = RX11.ERROR.NO_DATA;\n break;\n }\n var data = b0 | (b1 << 8);\n this.bus.setWordDirect(this.cpu.mapUnibus(addr), data);\n if (DEBUG && this.messageEnabled(MessagesPDP11.READ)) {\n if (!sWords) sWords = Str.toOct(addr) + \": \";\n sWords += Str.toOct(data) + ' ';\n if (sWords.length >= 64) {\n console.log(sWords);\n sWords = \"\";\n }\n }\n if (ibSector >= disk.cbSector) sector = null;\n addr += inc;\n nWords--;\n }\n\n return done? done(nError, iCylinder, iHead, iSector, nWords, addr) : nError;\n }\n\n /**\n * readSector()\n *\n * @this {RX11}\n */\n readSector()\n {\n var nError = 0;\n var iDrive = (this.regRXCS & RX11.RXCS.UNIT)? 1 : 0;\n var drive = this.aDrives[iDrive];\n var disk = drive && drive.disk;\n var iCylinder = this.regRXTA & RX11.RXTA.MASK, iHead = 0, nSector = this.regRXSA & RX11.RXSA.MASK;\n\n this.regRXES &= ~(RX11.RXES.CRC | RX11.RXES.PARITY | RX11.RXES.DEL | RX11.RXES.DRDY);\n\n if (disk) {\n this.regRXES |= RX11.RXES.DRDY;\n if (this.messageEnabled()) this.printMessage(this.type + \".readSector(\" + iCylinder + \":\" + iHead + \":\" + nSector + \")\", true, true);\n\n var sector = disk.seek(iCylinder, iHead, nSector, true);\n if (sector) {\n var i = 0, nBytes = this.abBuffer.length;\n while (i < nBytes) {\n var b = disk.read(sector, i);\n if (b < 0) {\n nError = RX11.ERROR.NO_DATA;\n break;\n }\n this.abBuffer[i++] = b;\n }\n if (sector.deleted) this.regRXES |= RX11.RXES.DEL;\n } else {\n nError = RX11.ERROR.NO_SECTOR;\n }\n } else {\n nError = iDrive? RX11.ERROR.HOME1 : RX11.ERROR.HOME0;\n }\n this.doneCommand(nError);\n }\n\n /**\n * writeSector(fDeleted)\n *\n * @this {RX11}\n * @param {boolean} fDeleted\n */\n writeSector(fDeleted)\n {\n var nError = 0;\n var iDrive = (this.regRXCS & RX11.RXCS.UNIT)? 1 : 0;\n var drive = this.aDrives[iDrive];\n var disk = drive && drive.disk;\n var iCylinder = this.regRXTA & RX11.RXTA.MASK, iHead = 0, nSector = this.regRXSA & RX11.RXSA.MASK;\n\n this.regRXES &= ~(RX11.RXES.CRC | RX11.RXES.PARITY | RX11.RXES.DEL | RX11.RXES.DRDY);\n\n if (disk) {\n this.regRXES |= RX11.RXES.DRDY;\n if (this.messageEnabled()) this.printMessage(this.type + \".writeSector(\" + iCylinder + \":\" + iHead + \":\" + nSector + \")\", true, true);\n\n var sector = disk.seek(iCylinder, iHead, nSector, true);\n if (sector) {\n if (fDeleted) sector.deleted = true;\n var i = 0, nBytes = this.abBuffer.length;\n while (i < nBytes) {\n var data = this.abBuffer[i];\n if (!disk.write(sector, i, data & 0xff)) {\n nError = RX11.ERROR.NO_DATA;\n break;\n }\n i++;\n }\n } else {\n nError = RX11.ERROR.NO_SECTOR;\n }\n } else {\n nError = iDrive? RX11.ERROR.HOME1 : RX11.ERROR.HOME0;\n }\n this.doneCommand(nError);\n }\n\n /**\n * readStatus()\n *\n * @this {RX11}\n */\n readStatus()\n {\n var iDrive = (this.regRXCS & RX11.RXCS.UNIT)? 1 : 0;\n var drive = this.aDrives[iDrive];\n\n this.regRXES &= ~RX11.RXES.DRDY;\n if (drive && drive.disk) this.regRXES |= RX11.RXES.DRDY;\n\n this.regRXDB = this.regRXES;\n this.doneCommand();\n }\n\n /**\n * readError()\n *\n * @this {RX11}\n */\n readError()\n {\n this.regRXDB = this.regError;\n this.doneCommand();\n }\n\n /**\n * readRXCS(addr)\n *\n * @this {RX11}\n * @param {number} addr (eg, PDP11.UNIBUS.RXCS or 177170)\n * @param {boolean} [fPreWrite]\n * @return {number}\n */\n readRXCS(addr, fPreWrite)\n {\n var w = this.regRXCS;\n\n if (!fPreWrite) {\n w &= RX11.RXCS.RMASK;\n\n switch (this.funCode) {\n\n case RX11.FUNC.FILL:\n case RX11.FUNC.EMPTY:\n if (this.iBuffer < this.abBuffer.length) {\n this.regRXCS |= RX11.RXCS.TR;\n }\n break;\n\n case RX11.FUNC.READ:\n case RX11.FUNC.WRITE:\n case RX11.FUNC.WRDEL:\n if (this.iBuffer < 2) {\n this.regRXCS |= RX11.RXCS.TR;\n }\n break;\n }\n }\n return w;\n }\n\n /**\n * writeRXCS(data, addr)\n *\n * @this {RX11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RXCS or 177170)\n */\n writeRXCS(data, addr)\n {\n this.regRXCS = (this.regRXCS & ~RX11.RXCS.WMASK) | (data & RX11.RXCS.WMASK);\n\n if (this.regRXCS & RX11.RXCS.INIT) {\n this.initController();\n return;\n }\n\n if ((this.regRXCS & RX11.RXCS.GO) && this.funCode == RX11.FUNC.UNUSED) {\n this.processCommand();\n return;\n }\n\n if (!(this.regRXCS & RX11.RXCS.IE)) {\n this.cpu.clearIRQ(this.irq);\n }\n else if (this.regRXCS & RX11.RXCS.DONE) {\n this.cpu.setIRQ(this.irq);\n }\n }\n\n /**\n * readRXDB(addr)\n *\n * @this {RX11}\n * @param {number} addr (eg, PDP11.UNIBUS.RXDB or 177172)\n * @param {boolean} [fPreWrite]\n * @return {number}\n */\n readRXDB(addr, fPreWrite)\n {\n if (!fPreWrite) {\n switch (this.funCode) {\n\n case RX11.FUNC.EMPTY:\n if (this.regRXCS & RX11.RXCS.TR) {\n this.regRXCS &= ~RX11.RXCS.TR;\n\n this.regRXDB = this.abBuffer[this.iBuffer] & 0xff;\n if (this.messageEnabled()) this.printMessage(this.type + \".readByte(\" + this.iBuffer + \"): \" + Str.toHexByte(this.regRXDB), true, true);\n if (++this.iBuffer >= this.abBuffer.length) {\n this.doneCommand();\n }\n }\n break;\n }\n }\n return this.regRXDB;\n }\n\n /**\n * writeRXDB(data, addr)\n *\n * @this {RX11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RXDB or 177172)\n */\n writeRXDB(data, addr)\n {\n switch(this.funCode) {\n\n case RX11.FUNC.FILL:\n if (this.regRXCS & RX11.RXCS.TR) {\n this.regRXCS &= ~RX11.RXCS.TR;\n\n this.abBuffer[this.iBuffer] = data & 0xff;\n if (this.messageEnabled()) this.printMessage(this.type + \".writeByte(\" + this.iBuffer + \",\" + Str.toHexByte(data) + \")\", true, true);\n if (++this.iBuffer >= this.abBuffer.length) {\n this.doneCommand();\n }\n }\n break;\n\n case RX11.FUNC.READ:\n case RX11.FUNC.WRITE:\n case RX11.FUNC.WRDEL:\n if (this.regRXCS & RX11.RXCS.TR) {\n this.regRXCS &= ~RX11.RXCS.TR;\n\n switch(this.iBuffer++) {\n case 0:\n this.regRXSA = data;\n break;\n\n case 1:\n this.regRXTA = data;\n if (this.funCode == RX11.FUNC.READ) {\n this.readSector();\n } else {\n this.writeSector(this.funCode == RX11.FUNC.WRDEL);\n }\n break;\n\n default:\n\n break;\n }\n }\n break;\n }\n this.regRXDB = data;\n }\n}\n\n/*\n * Alias RX11 definitions as class constants\n */\nRX11.RXCS = PDP11.RX11.RXCS; // 177170: Command and Status Register\nRX11.RXDB = PDP11.RX11.RXDB; // 177172: Data Buffer Register\nRX11.RXTA = PDP11.RX11.RXTA;\nRX11.RXSA = PDP11.RX11.RXSA;\nRX11.RXES = PDP11.RX11.RXES;\nRX11.FUNC = PDP11.RX11.FUNC;\nRX11.ERROR = PDP11.RX11.ERROR;\n\nRX11.FUNCS = [\n \"FILL\", \"EMPTY\", \"WRITE\", \"READ\", \"UNUSED\", \"RDSTAT\", \"WRDEL\", \"RDERR\"\n];\n\n/*\n * ES6 ALERT: As you can see below, I've finally started using computed property names.\n */\nRX11.UNIBUS_IOTABLE = {\n [PDP11.UNIBUS.RXCS]: /* 177170 */ [null, null, RX11.prototype.readRXCS, RX11.prototype.writeRXCS, \"RXCS\"],\n [PDP11.UNIBUS.RXDB]: /* 177172 */ [null, null, RX11.prototype.readRXDB, RX11.prototype.writeRXDB, \"RXDB\"]\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/debugger.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Debugger Address Object\n *\n * This is the basic structure; other debuggers may extend it.\n *\n * addr address\n * fTemporary true if this is a temporary breakpoint address\n * sCmd set for breakpoint addresses if there's an associated command string\n * aCmds preprocessed commands (from sCmd)\n *\n * @typedef {{\n * addr:(number|undefined),\n * fTemporary:(boolean|undefined),\n * sCmd:(string|undefined),\n * aCmds:(Array.<string>|undefined)\n * }}\n */\nvar DbgAddr;\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * subclass (eg, SerialPort), because otherwise the Compiler won't allow us to *reference*\n * the named property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass Debugger extends Component\n{\n /**\n * Debugger(parmsDbg)\n *\n * The Debugger component supports the following optional (parmsDbg) properties:\n *\n * base: the base to use for most numeric input/output (default is 16)\n *\n * The Debugger component is a shared component containing a subset of functionality used by\n * the other CPU-specific Debuggers (eg, DebuggerX86). Over time, the goal is to factor out as\n * much common debugging support as possible from those components into this one.\n *\n * @param {Object} parmsDbg\n */\n constructor(parmsDbg)\n {\n if (DEBUGGER) {\n\n super(\"Debugger\", parmsDbg);\n\n /*\n * Default base used to display all values; modified with the \"s base\" command.\n */\n this.nBase = +parmsDbg['base'] || 16;\n\n /*\n * Default number of bits of integer precision; it can be overridden by the Debugger\n * but there is no command to adjust it.\n */\n this.nBits = 32;\n\n this.achGroup = ['{','}'];\n this.achAddress = ['[',']'];\n\n /*\n * These keep track of instruction activity, but only when tracing or when Debugger checks\n * have been enabled (eg, one or more breakpoints have been set).\n *\n * They are zeroed by the reset() notification handler. cInstructions is advanced by\n * stepCPU() and checkInstruction() calls. nCycles is updated by every stepCPU() or stop()\n * call and simply represents the number of cycles performed by the last run of instructions.\n */\n this.nCycles = 0;\n this.cOpcodes = this.cOpcodesStart = 0;\n\n /*\n * fAssemble is true when \"assemble mode\" is active, false when not.\n */\n this.fAssemble = false;\n\n /*\n * This maintains command history. New commands are inserted at index 0 of the array.\n * When Enter is pressed on an empty input buffer, we default to the command at aPrevCmds[0].\n */\n this.iPrevCmd = -1;\n this.aPrevCmds = [];\n\n /*\n * aVariables is an object with properties that grow as setVariable() assigns more variables;\n * each property corresponds to one variable, where the property name is the variable name (ie,\n * a string beginning with a non-digit, followed by zero or more symbol characters and/or digits)\n * and the property value is the variable's numeric value. See doVar() and setVariable() for\n * details.\n *\n * Note that parseValue() parses variables before numbers, so any variable that looks like a\n * unprefixed hex value (eg, \"a5\" as opposed to \"0xa5\") will trump the numeric value. Unprefixed\n * hex values are a convenience of parseValue(), which always calls Str.parseInt() with a default\n * base of 16; however, that default be overridden with a variety of explicit prefixes or suffixes\n * (eg, a leading \"0o\" to indicate octal, a trailing period to indicate decimal, etc.)\n *\n * See Str.parseInt() for more details about supported numbers.\n */\n this.aVariables = {};\n\n } // endif DEBUGGER\n }\n\n /**\n * getRegIndex(sReg, off)\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {string} sReg\n * @param {number} [off] optional offset into sReg\n * @return {number} register index, or -1 if not found\n */\n getRegIndex(sReg, off)\n {\n return -1;\n }\n\n /**\n * getRegValue(iReg)\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {number} iReg\n * @return {number|undefined}\n */\n getRegValue(iReg)\n {\n return undefined;\n }\n\n /**\n * parseAddrReference(s, sAddr)\n *\n * Returns the given string with the given address reference replaced with the contents of that address.\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {string} s\n * @param {string} sAddr\n * @return {string}\n */\n parseAddrReference(s, sAddr)\n {\n return s.replace('[' + sAddr + ']', \"unimplemented\");\n }\n\n /**\n * getNextCommand()\n *\n * @this {Debugger}\n * @return {string}\n */\n getNextCommand()\n {\n var sCmd;\n if (this.iPrevCmd > 0) {\n sCmd = this.aPrevCmds[--this.iPrevCmd];\n } else {\n sCmd = \"\";\n this.iPrevCmd = -1;\n }\n return sCmd;\n }\n\n /**\n * getPrevCommand()\n *\n * @this {Debugger}\n * @return {string|null}\n */\n getPrevCommand()\n {\n var sCmd = null;\n if (this.iPrevCmd < this.aPrevCmds.length - 1) {\n sCmd = this.aPrevCmds[++this.iPrevCmd];\n }\n return sCmd;\n }\n\n /**\n * parseCommand(sCmd, fSave, chSep)\n *\n * @this {Debugger}\n * @param {string|undefined} sCmd\n * @param {boolean} [fSave] is true to save the command, false if not\n * @param {string} [chSep] is the command separator character (default is ';')\n * @return {Array.<string>}\n */\n parseCommand(sCmd, fSave, chSep)\n {\n if (fSave) {\n if (!sCmd) {\n if (this.fAssemble) {\n sCmd = \"end\";\n } else {\n sCmd = this.aPrevCmds[this.iPrevCmd+1];\n }\n } else {\n if (this.iPrevCmd < 0 && this.aPrevCmds.length) {\n this.iPrevCmd = 0;\n }\n if (this.iPrevCmd < 0 || sCmd != this.aPrevCmds[this.iPrevCmd]) {\n this.aPrevCmds.splice(0, 0, sCmd);\n this.iPrevCmd = 0;\n }\n this.iPrevCmd--;\n }\n }\n var a = [];\n if (sCmd) {\n /*\n * With the introduction of breakpoint commands (ie, quoted command sequences\n * associated with a breakpoint), we can no longer perform simplistic splitting.\n *\n * a = sCmd.split(chSep || ';');\n * for (var i = 0; i < a.length; i++) a[i] = Str.trim(a[i]);\n *\n * We may now split on semi-colons ONLY if they are outside a quoted sequence.\n *\n * Also, to allow quoted strings *inside* breakpoint commands, we first replace all\n * DOUBLE double-quotes with single quotes.\n */\n sCmd = sCmd.replace(/\"\"/g, \"'\");\n\n var iPrev = 0;\n var chQuote = null;\n chSep = chSep || ';';\n /*\n * NOTE: Processing charAt() up to and INCLUDING length is not a typo; we're taking\n * advantage of the fact that charAt() with an invalid index returns an empty string,\n * allowing us to use the same substring() call to capture the final portion of sCmd.\n *\n * In a sense, it allows us to pretend that the string ends with a zero terminator.\n */\n for (var i = 0; i <= sCmd.length; i++) {\n var ch = sCmd.charAt(i);\n if (ch == '\"' || ch == \"'\") {\n if (!chQuote) {\n chQuote = ch;\n } else if (ch == chQuote) {\n chQuote = null;\n }\n }\n else if (ch == chSep && !chQuote || !ch) {\n /*\n * Recall that substring() accepts starting (inclusive) and ending (exclusive)\n * indexes, whereas substr() accepts a starting index and a length. We need the former.\n */\n a.push(Str.trim(sCmd.substring(iPrev, i)));\n iPrev = i + 1;\n }\n }\n }\n return a;\n }\n\n /**\n * evalAND(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.AND().\n *\n * Performs the bitwise \"and\" (AND) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst & src)\n */\n evalAND(dst, src)\n {\n /*\n * We AND the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 AND 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst & src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) & ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst & src) >>> 0);\n }\n\n /**\n * evalIOR(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.IOR().\n *\n * Performs the logical \"inclusive-or\" (OR) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst | src)\n */\n evalIOR(dst, src)\n {\n /*\n * We OR the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 OR 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst | src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) | ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst | src) >>> 0);\n }\n\n /**\n * evalXOR(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.XOR().\n *\n * Performs the logical \"exclusive-or\" (XOR) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst ^ src)\n */\n evalXOR(dst, src)\n {\n /*\n * We XOR the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 XOR 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst | src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) ^ ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst ^ src) >>> 0);\n }\n\n /**\n * evalMUL(dst, src)\n *\n * I could have adapted the code from /modules/pdp10/lib/cpuops.js:PDP10.doMUL(), but it was simpler to\n * write this base method and let the PDP-10 Debugger override it with a call to the *actual* doMUL() method.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst * src)\n */\n evalMUL(dst, src)\n {\n return dst * src;\n }\n\n /**\n * truncate(v, nBits, fUnsigned)\n *\n * @this {Debugger}\n * @param {number} v\n * @param {number} [nBits]\n * @param {boolean} [fUnsigned]\n * @return {number}\n */\n truncate(v, nBits, fUnsigned)\n {\n var limit, vNew = v;\n nBits = nBits || this.nBits;\n\n if (fUnsigned) {\n if (nBits == 32) {\n vNew = v >>> 0;\n }\n else if (nBits < 32) {\n vNew = v & ((1 << nBits) - 1);\n }\n else {\n limit = Math.pow(2, nBits);\n if (v < 0 || v >= limit) {\n vNew = v % limit;\n if (vNew < 0) vNew += limit;\n }\n }\n }\n else {\n if (nBits <= 32) {\n vNew = (v << (32 - nBits)) >> (32 - nBits);\n }\n else {\n limit = Math.pow(2, nBits - 1);\n if (v >= limit) {\n vNew = (v % limit);\n if (((v / limit)|0) & 1) vNew -= limit;\n } else if (v < -limit) {\n vNew = (v % limit);\n if ((((-v - 1) / limit) | 0) & 1) {\n if (vNew) vNew += limit;\n }\n else {\n if (!vNew) vNew -= limit;\n }\n }\n }\n }\n if (v != vNew) {\n if (MAXDEBUG) this.println(\"warning: value \" + v + \" truncated to \" + vNew);\n v = vNew;\n }\n return v;\n }\n\n /**\n * evalOps(aVals, aOps, cOps)\n *\n * Some of our clients want a specific number of bits of integer precision. If that precision is\n * greater than 32, some of the operations below will fail; for example, JavaScript bitwise operators\n * always truncate the result to 32 bits, so beware when using shift operations. Similarly, it would\n * be wrong to always \"|0\" the final result, which is why we rely on truncate() now.\n *\n * Note that JavaScript integer precision is limited to 52 bits. For example, in Node, if you set a\n * variable to 0x80000001:\n *\n * foo=0x80000001|0\n *\n * then calculate foo*foo and display the result in binary using \"(foo*foo).toString(2)\":\n *\n * '11111111111111111111111111111100000000000000000000000000000000'\n *\n * which is slightly incorrect because it has overflowed JavaScript's floating-point precision.\n *\n * 0x80000001 in decimal is -2147483647, so the product is 4611686014132420609, which is 0x3FFFFFFF00000001.\n *\n * @this {Debugger}\n * @param {Array.<number>} aVals\n * @param {Array.<string>} aOps\n * @param {number} [cOps] (default is -1 for all)\n * @return {boolean} true if successful, false if error\n */\n evalOps(aVals, aOps, cOps = -1)\n {\n while (cOps-- && aOps.length) {\n var chOp = aOps.pop();\n if (aVals.length < 2) return false;\n var valNew;\n var val2 = aVals.pop();\n var val1 = aVals.pop();\n switch(chOp) {\n case '*':\n valNew = this.evalMUL(val1, val2);\n break;\n case '/':\n if (!val2) return false;\n valNew = Math.trunc(val1 / val2);\n break;\n case '^/':\n if (!val2) return false;\n valNew = val1 % val2;\n break;\n case '+':\n valNew = val1 + val2;\n break;\n case '-':\n valNew = val1 - val2;\n break;\n case '<<':\n valNew = val1 << val2;\n break;\n case '>>':\n valNew = val1 >> val2;\n break;\n case '>>>':\n valNew = val1 >>> val2;\n break;\n case '<':\n valNew = (val1 < val2? 1 : 0);\n break;\n case '<=':\n valNew = (val1 <= val2? 1 : 0);\n break;\n case '>':\n valNew = (val1 > val2? 1 : 0);\n break;\n case '>=':\n valNew = (val1 >= val2? 1 : 0);\n break;\n case '==':\n valNew = (val1 == val2? 1 : 0);\n break;\n case '!=':\n valNew = (val1 != val2? 1 : 0);\n break;\n case '&':\n valNew = this.evalAND(val1, val2);\n break;\n case '!': // alias for MACRO-10 to perform a bitwise inclusive-or (OR)\n case '|':\n valNew = this.evalIOR(val1, val2);\n break;\n case '^!': // since MACRO-10 uses '^' for base overrides, '^!' is used for bitwise exclusive-or (XOR)\n valNew = this.evalXOR(val1, val2);\n break;\n case '&&':\n valNew = (val1 && val2? 1 : 0);\n break;\n case '||':\n valNew = (val1 || val2? 1 : 0);\n break;\n case ',,':\n valNew = this.truncate(val1, 18, true) * Math.pow(2, 18) + this.truncate(val2, 18, true);\n break;\n case '_':\n case '^_':\n valNew = val1;\n /*\n * While we always try to avoid assuming any particular number of bits of precision, the 'B' shift\n * operator (which we've converted to '^_') is unique to the MACRO-10 environment, which imposes the\n * following restrictions on the shift count.\n */\n if (chOp == '^_') val2 = 35 - (val2 & 0xff);\n if (val2) {\n /*\n * Since binary shifting is a logical (not arithmetic) operation, and since shifting by division only\n * works properly with positive numbers, we call truncate() to produce an unsigned value.\n */\n valNew = this.truncate(valNew, 0, true);\n if (val2 > 0) {\n valNew *= Math.pow(2, val2);\n } else {\n valNew = Math.trunc(valNew / Math.pow(2, -val2));\n }\n }\n break;\n default:\n return false;\n }\n aVals.push(this.truncate(valNew));\n }\n return true;\n }\n\n /**\n * parseArray(asValues, iValue, iLimit, nBase, aUndefined)\n *\n * parseExpression() takes a complete expression and divides it into array elements, where even elements\n * are values (which may be empty if two or more operators appear consecutively) and odd elements are operators.\n *\n * For example, if the original expression was \"2*{3+{4/2}}\", parseExpression() would call parseArray() with:\n *\n * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14\n * - - - - - - - - - - -- -- -- -- --\n * 2 * { 3 + { 4 / 2 } }\n *\n * This function takes care of recursively processing grouped expressions, by processing subsets of the array,\n * as well as handling certain base overrides (eg, temporarily switching to base-10 for binary shift suffixes).\n *\n * @param {Array.<string>} asValues\n * @param {number} iValue\n * @param {number} iLimit\n * @param {number} nBase\n * @param {Array|undefined} [aUndefined]\n * @return {number|undefined}\n */\n parseArray(asValues, iValue, iLimit, nBase, aUndefined)\n {\n var value;\n var sValue, sOp;\n var fError = false;\n var nUnary = 0;\n var aVals = [], aOps = [];\n\n var nBasePrev = this.nBase;\n this.nBase = nBase;\n\n while (iValue < iLimit) {\n var v;\n sValue = asValues[iValue++].trim();\n sOp = (iValue < iLimit? asValues[iValue++] : \"\");\n\n if (sValue) {\n v = this.parseValue(sValue, null, aUndefined, nUnary);\n } else {\n if (sOp == '{') {\n var cOpen = 1;\n var iStart = iValue;\n while (iValue < iLimit) {\n sValue = asValues[iValue++].trim();\n sOp = (iValue < asValues.length? asValues[iValue++] : \"\");\n if (sOp == '{') {\n cOpen++;\n } else if (sOp == '}') {\n if (!--cOpen) break;\n }\n }\n v = this.parseArray(asValues, iStart, iValue-1, this.nBase, aUndefined);\n if (v != null && nUnary) {\n v = this.parseUnary(v, nUnary);\n }\n sValue = (iValue < iLimit? asValues[iValue++].trim() : \"\");\n sOp = (iValue < iLimit? asValues[iValue++] : \"\");\n }\n else {\n /*\n * When parseExpression() calls us, it has collapsed all runs of whitespace into single spaces,\n * and although it allows single spaces to divide the elements of the expression, a space is neither\n * a unary nor binary operator. It's essentially a no-op. If we encounter it here, then it followed\n * another operator and is easily ignored (although perhaps it should still trigger a reset of nBase\n * and nUnary -- TBD).\n */\n if (sOp == ' ') {\n continue;\n }\n if (sOp == '^B') {\n this.nBase = 2;\n continue;\n }\n if (sOp == '^O') {\n this.nBase = 8;\n continue;\n }\n if (sOp == '^D') {\n this.nBase = 10;\n continue;\n }\n if (!(nUnary & (0xC0000000|0))) {\n if (sOp == '+') {\n continue;\n }\n if (sOp == '-') {\n nUnary = (nUnary << 2) | 1;\n continue;\n }\n if (sOp == '~' || sOp == '^-') {\n nUnary = (nUnary << 2) | 2;\n continue;\n }\n if (sOp == '^L') {\n nUnary = (nUnary << 2) | 3;\n continue;\n }\n }\n fError = true;\n break;\n }\n }\n\n if (v === undefined) {\n if (aUndefined) {\n aUndefined.push(sValue);\n v = 0;\n } else {\n fError = true;\n aUndefined = [];\n break;\n }\n }\n\n aVals.push(this.truncate(v));\n\n /*\n * When parseExpression() calls us, it has collapsed all runs of whitespace into single spaces,\n * and although it allows single spaces to divide the elements of the expression, a space is neither\n * a unary nor binary operator. It's essentially a no-op. If we encounter it here, then it followed\n * a value, and since we don't want to misinterpret the next operator as a unary operator, we look\n * ahead and grab the next operator if it's not preceded by a value.\n */\n if (sOp == ' ') {\n if (iValue < asValues.length - 1 && !asValues[iValue]) {\n iValue++;\n sOp = asValues[iValue++]\n } else {\n fError = true;\n break;\n }\n }\n\n if (!sOp) break;\n\n var aBinOp = (this.achGroup[0] == '<'? Debugger.aDECOpPrecedence : Debugger.aBinOpPrecedence);\n if (!aBinOp[sOp]) {\n fError = true;\n break;\n }\n if (aOps.length && aBinOp[sOp] <= aBinOp[aOps[aOps.length - 1]]) {\n this.evalOps(aVals, aOps, 1);\n }\n aOps.push(sOp);\n\n /*\n * The MACRO-10 binary shifting operator assumes a base-10 shift count, regardless of the current\n * base, so we must override the current base to ensure the count is parsed correctly.\n */\n this.nBase = (sOp == '^_')? 10 : nBase;\n nUnary = 0;\n }\n\n if (fError || !this.evalOps(aVals, aOps) || aVals.length != 1) {\n fError = true;\n }\n\n if (!fError) {\n value = aVals.pop();\n\n } else if (!aUndefined) {\n this.println(\"parse error (\" + (sValue || sOp) + \")\");\n }\n\n this.nBase = nBasePrev;\n return value;\n }\n\n /**\n * parseASCII(sExp, chDelim, nBits, cchMax)\n *\n * @this {Debugger}\n * @param {string} sExp\n * @param {string} chDelim\n * @param {number} nBits\n * @param {number} cchMax\n * @return {string|undefined}\n */\n parseASCII(sExp, chDelim, nBits, cchMax)\n {\n var i;\n while ((i = sExp.indexOf(chDelim)) >= 0) {\n var v = 0;\n var j = i + 1;\n var cch = cchMax;\n while (j < sExp.length) {\n var ch = sExp[j++];\n if (ch == chDelim) {\n cch = -1;\n break;\n }\n if (!cch) break;\n cch--;\n var c = ch.charCodeAt(0);\n if (nBits == 7) {\n c &= 0x7F;\n } else {\n c = (c - 0x20) & 0x3F;\n }\n v = this.truncate(v * Math.pow(2, nBits) + c, nBits * cchMax, true);\n }\n if (cch >= 0) {\n this.println(\"parse error (\" + chDelim + sExp + chDelim + \")\");\n return undefined;\n } else {\n sExp = sExp.substr(0, i) + this.toStrBase(v, -1) + sExp.substr(j);\n }\n }\n return sExp;\n }\n\n /**\n * parseExpression(sExp, fQuiet)\n *\n * A quick-and-dirty expression parser. It takes an expression like:\n *\n * EDX+EDX*4+12345678\n *\n * and builds a value stack in aVals and a \"binop\" (binary operator) stack in aOps:\n *\n * aVals aOps\n * ----- ----\n * EDX +\n * EDX *\n * 4 +\n * ...\n *\n * We pop 1 \"binop\" from aOps and 2 values from aVals whenever a \"binop\" of lower priority than its\n * predecessor is encountered, evaluate, and push the result back onto aVals. Only selected unary\n * operators are supported (eg, negate and complement); no ternary operators like '?:' are supported.\n *\n * fQuiet can be used to pass an array that collects any undefined variables that parseExpression()\n * encounters; the value of an undefined variable is zero. This mode was added for components that need\n * to support expressions containing \"fixups\" (ie, values that must be determined later).\n *\n * @this {Debugger}\n * @param {string|undefined} sExp\n * @param {Array|undefined|boolean} [fQuiet]\n * @return {number|undefined} numeric value, or undefined if sExp contains any undefined or invalid values\n */\n parseExpression(sExp, fQuiet)\n {\n var value = undefined;\n var fPrint = (fQuiet === false);\n var aUndefined = Array.isArray(fQuiet)? fQuiet : undefined;\n\n if (sExp) {\n\n /*\n * The default delimiting characters for grouped expressions are braces; they can be changed by altering\n * achGroup, but when that happens, instead of changing our regular expressions and operator tables,\n * we simply replace all achGroup characters with braces in the given expression.\n *\n * Why not use parentheses for grouped expressions? Because some debuggers use parseReference() to perform\n * parenthetical value replacements in message strings, and they don't want parentheses taking on a different\n * meaning. And for some machines, like the PDP-10, the convention is to use parentheses for other things,\n * like indexed addressing, and to use angle brackets for grouped expressions.\n */\n if (this.achGroup[0] != '{') {\n sExp = sExp.split(this.achGroup[0]).join('{').split(this.achGroup[1]).join('}');\n }\n\n /*\n * Quoted ASCII characters can have a numeric value, too, which must be converted now, to avoid any\n * conflicts with the operators below.\n */\n sExp = this.parseASCII(sExp, '\"', 7, 5); // MACRO-10 packs up to 5 7-bit ASCII codes into a value\n if (!sExp) return value;\n sExp = this.parseASCII(sExp, \"'\", 6, 6); // MACRO-10 packs up to 6 6-bit ASCII (SIXBIT) codes into a value\n if (!sExp) return value;\n\n /*\n * All browsers (including, I believe, IE9 and up) support the following idiosyncrasy of a RegExp split():\n * when the RegExp uses a capturing pattern, the resulting array will include entries for all the pattern\n * matches along with the non-matches. This effectively means that, in the set of expressions that we\n * support, all even entries in asValues will contain \"values\" and all odd entries will contain \"operators\".\n *\n * Although I started listing the operators in the RegExp in \"precedential\" order, that's not important;\n * what IS important is listing operators than contain shorter operators first. For example, bitwise\n * shift operators must be listed BEFORE the logical less-than or greater-than operators. The aBinOp tables\n * (aBinOpPrecedence and aDECOpPrecedence) are what determine precedence, not the RegExp.\n *\n * Also, to better accommodate MACRO-10 syntax, I've replaced the single '^' for XOR with '^!', and I've\n * added '!' as an alias for '|' (bitwise inclusive-or), '^-' as an alias for '~' (one's complement operator),\n * and '_' as a shift operator (+/- values specify a left/right shift, and the count is not limited to 32).\n *\n * And to avoid conflicts with MACRO-10 syntax, I've replaced the original mod operator ('%') with '^/'.\n *\n * The MACRO-10 binary shifting suffix ('B') is a bit more problematic, since a capital B can also appear\n * inside symbols, or inside hex values. So if the default base is NOT 16, then I pre-scan for that suffix\n * and replace all non-symbolic occurrences with an internal shift operator ('^_').\n *\n * Note that Str.parseInt(), which parseValue() relies on, supports both the MACRO-10 base prefix overrides\n * and the binary shifting suffix ('B'), but since that suffix can also be a bracketed expression, we have to\n * support it here as well.\n *\n * MACRO-10 supports only a subset of all the PCjs operators; for example, MACRO-10 doesn't support any of\n * the boolean logical/compare operators. But unless we run into conflicts, I prefer sticking with this\n * common set of operators.\n *\n * All whitespace in the expression is collapsed to single spaces, and space has been added to the list\n * of \"operators\", but its sole function is as a separator, not as an operator. parseArray() will ignore\n * single spaces as long as they are preceded and/or followed by a \"real\" operator. It would be dangerous\n * to remove spaces entirely, because if an operator-less expression like \"A B\" was passed in, we would want\n * that to generate an error; if we converted it to \"AB\", evaluation might inadvertently succeed.\n */\n var regExp = /({|}|\\|\\||&&|\\||\\^!|\\^B|\\^O|\\^D|\\^L|\\^-|~|\\^_|_|&|!=|!|==|>=|>>>|>>|>|<=|<<|<|-|\\+|\\^\\/|\\/|\\*|,,| )/;\n if (this.nBase != 16) {\n sExp = sExp.replace(/(^|[^A-Z0-9$%.])([0-9]+)B/, \"$1$2^_\").replace(/\\s+/g, ' ');\n }\n var asValues = sExp.split(regExp);\n value = this.parseArray(asValues, 0, asValues.length, this.nBase, aUndefined);\n if (value !== undefined && fPrint) {\n this.printValue(null, value);\n }\n }\n return value;\n }\n\n /**\n * parseReference(s)\n *\n * Returns the given string with any \"{expression}\" sequences replaced with the value of the expression,\n * and any \"[address]\" references replaced with the contents of the address. Expressions are parsed BEFORE\n * addresses.\n *\n * @this {Debugger}\n * @param {string} s\n * @return {string|undefined}\n */\n parseReference(s)\n {\n var a;\n var chOpen = this.achGroup[0];\n var chClose = this.achGroup[1];\n var chEscape = (chOpen == '(' || chOpen == '{' || chOpen == '[')? '\\\\' : '';\n var chInnerEscape = (chOpen == '['? '\\\\' : '');\n var reSubExp = new RegExp(chEscape + chOpen + \"([^\" + chInnerEscape + chOpen + chInnerEscape + chClose + \"]+)\" + chEscape + chClose);\n while (a = s.match(reSubExp)) {\n var value = this.parseExpression(a[1]);\n if (value === undefined) return undefined;\n var sSearch = chOpen + a[1] + chClose;\n var sReplace = value != null? this.toStrBase(value) : \"undefined\";\n /*\n * Note that by default, the String replace() method only replaces the FIRST occurrence,\n * and there MIGHT be more than one occurrence of the expression we just parsed, so we could\n * do this instead:\n *\n * s = s.split(sSearch).join(sReplace);\n *\n * However, that's knd of an expensive (slow) solution, and it's not strictly necessary, since\n * any additional identical expressions will be picked up on a subsequent iteration through this loop.\n */\n s = s.replace(sSearch, sReplace);\n }\n if (this.achAddress.length) {\n chOpen = this.achAddress[0];\n chClose = this.achAddress[1];\n chEscape = (chOpen == '(' || chOpen == '{' || chOpen == '[')? '\\\\' : '';\n chInnerEscape = (chOpen == '['? '\\\\' : '');\n reSubExp = new RegExp(chEscape + chOpen + \"([^\" + chInnerEscape + chOpen + chInnerEscape + chClose + \"]+)\" + chEscape + chClose);\n while (a = s.match(reSubExp)) {\n s = this.parseAddrReference(s, a[1]);\n }\n }\n return this.parseSysVars(s);\n }\n\n /**\n * parseSysVars(s)\n *\n * Returns the given string with any recognized \"$var\" replaced with its value; eg:\n *\n * $ops: the number of opcodes executed since the last time it was displayed (or reset)\n *\n * @this {Debugger}\n * @param {string} s\n * @return {string}\n */\n parseSysVars(s)\n {\n var a;\n while (a = s.match(/\\$([a-z]+)/i)) {\n var v = null;\n switch(a[1].toLowerCase()) {\n case \"ops\":\n v = this.cOpcodes - this.cOpcodesStart;\n break;\n }\n if (v == null) break;\n s = s.replace(a[0], v.toString());\n }\n return s;\n }\n\n /**\n * parseUnary(value, nUnary)\n *\n * nUnary is actually a small \"stack\" of unary operations encoded in successive pairs of bits.\n * As parseExpression() encounters each unary operator, nUnary is shifted left 2 bits, and the\n * new unary operator is encoded in bits 0 and 1 (0b00 is none, 0b01 is negate, 0b10 is complement,\n * and 0b11 is reserved). Here, we process the bits in reverse order (hence the stack-like nature),\n * ensuring that we process the unary operators associated with this value right-to-left.\n *\n * Since bitwise operators see only 32 bits, more than 16 unary operators cannot be supported\n * using this method. We'll let parseExpression() worry about that; if it ever happens in practice,\n * then we'll have to switch to a more \"expensive\" approach (eg, an actual array of unary operators).\n *\n * @this {Debugger}\n * @param {number} value\n * @param {number} nUnary\n * @return {number}\n */\n parseUnary(value, nUnary)\n {\n while (nUnary) {\n switch(nUnary & 0o3) {\n case 1:\n value = -this.truncate(value);\n break;\n case 2:\n value = this.evalXOR(value, -1); // this is easier than adding an evalNOT()...\n break;\n case 3:\n var bit = 35; // simple left-to-right zero-bit-counting loop...\n while (bit >= 0 && !this.evalAND(value, Math.pow(2, bit))) bit--;\n value = 35 - bit;\n break;\n }\n nUnary >>>= 2;\n }\n return value;\n }\n\n /**\n * parseValue(sValue, sName, fQuiet, nUnary)\n *\n * @this {Debugger}\n * @param {string|undefined} sValue\n * @param {string|null} [sName] is the name of the value, if any\n * @param {Array|undefined|boolean} [fQuiet]\n * @param {number} [nUnary] (0 for none, 1 for negate, 2 for complement, 3 for leading zeros)\n * @return {number|undefined} numeric value, or undefined if sValue is either undefined or invalid\n */\n parseValue(sValue, sName, fQuiet, nUnary = 0)\n {\n var value;\n var aUndefined = Array.isArray(fQuiet)? fQuiet : undefined;\n\n if (sValue != null) {\n var iReg = this.getRegIndex(sValue);\n if (iReg >= 0) {\n value = this.getRegValue(iReg);\n } else {\n value = this.getVariable(sValue);\n if (value != null) {\n var sUndefined = this.getVariableFixup(sValue);\n if (sUndefined) {\n if (aUndefined) {\n aUndefined.push(sUndefined);\n } else {\n var valueUndefined = this.parseExpression(sUndefined, fQuiet);\n if (valueUndefined !== undefined) {\n value += valueUndefined;\n } else {\n if (!fQuiet) {\n this.println(\"undefined \" + (sName || \"value\") + \": \" + sValue + \" (\" + sUndefined + \")\");\n }\n value = undefined;\n }\n }\n }\n } else {\n /*\n * A feature of MACRO-10 is that any single-digit number is automatically interpreted as base-10.\n */\n value = Str.parseInt(sValue, sValue.length > 1 || this.nBase > 10? this.nBase : 10);\n }\n }\n if (value != null) {\n value = this.truncate(this.parseUnary(value, nUnary));\n } else {\n if (!fQuiet) {\n this.println(\"invalid \" + (sName || \"value\") + \": \" + sValue);\n }\n }\n } else {\n if (!fQuiet) {\n this.println(\"missing \" + (sName || \"value\"));\n }\n }\n return value;\n }\n\n /**\n * printValue(sVar, value)\n *\n * @this {Debugger}\n * @param {string|null} sVar\n * @param {number|undefined} value\n * @return {boolean} true if value defined, false if not\n */\n printValue(sVar, value)\n {\n var sValue;\n var fDefined = false;\n if (value !== undefined) {\n fDefined = true;\n if (this.nBase == 8) {\n sValue = this.toStrBase(value, this.nBits, 8, 1) + \" \" + value + '.';\n } else {\n sValue = this.toStrBase(value, this.nBits, 16, 1) + \" \" + this.toStrBase(value, this.nBits, 8, 1) + \" \" + this.toStrBase(value, this.nBits, 2, this.nBits <= 32? 8 : 6) + \" \" + value + '.';\n }\n if (value >= 0x20 && value < 0x7F) {\n sValue += \" '\" + String.fromCharCode(value) + \"'\";\n }\n }\n sVar = (sVar != null? (sVar + \": \") : \"\");\n this.println(sVar + sValue);\n return fDefined;\n }\n\n /**\n * resetVariables()\n *\n * @this {Debugger}\n * @return {Object}\n */\n resetVariables()\n {\n var a = this.aVariables;\n this.aVariables = {};\n return a;\n }\n\n /**\n * restoreVariables(a)\n *\n * @this {Debugger}\n * @param {Object} a (from previous resetVariables() call)\n */\n restoreVariables(a)\n {\n this.aVariables = a;\n }\n\n /**\n * printVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} [sVar]\n * @return {boolean} true if all value(s) defined, false if not\n */\n printVariable(sVar)\n {\n var cVariables = 0;\n if (this.aVariables) {\n if (sVar) {\n return this.printValue(sVar, this.aVariables[sVar] && this.aVariables[sVar].value);\n }\n var aVars = Object.keys(this.aVariables);\n aVars.sort();\n for (var i = 0; i < aVars.length; i++) {\n this.printValue(aVars[i], this.aVariables[aVars[i]].value);\n cVariables++;\n }\n }\n return cVariables > 0;\n }\n\n /**\n * delVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n */\n delVariable(sVar)\n {\n delete this.aVariables[sVar];\n }\n\n /**\n * getVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {number|undefined}\n */\n getVariable(sVar)\n {\n if (this.aVariables[sVar]) {\n return this.aVariables[sVar].value;\n }\n sVar = sVar.substr(0, 6);\n return this.aVariables[sVar] && this.aVariables[sVar].value;\n }\n\n /**\n * getVariableFixup(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {string|undefined}\n */\n getVariableFixup(sVar)\n {\n return this.aVariables[sVar] && this.aVariables[sVar].sUndefined;\n }\n\n /**\n * isVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {boolean}\n */\n isVariable(sVar)\n {\n return this.aVariables[sVar] !== undefined;\n }\n\n /**\n * setVariable(sVar, value, sUndefined)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @param {number} value\n * @param {string|undefined} [sUndefined]\n */\n setVariable(sVar, value, sUndefined)\n {\n this.aVariables[sVar] = {value, sUndefined};\n }\n\n /**\n * toStrBase(n, nBits, nBase, nGrouping)\n *\n * Use this instead of Str's toOct()/toDec()/toHex() to convert numbers to the Debugger's default base.\n *\n * @this {Debugger}\n * @param {number|null|undefined} n\n * @param {number} [nBits] (-1 to strip leading zeros, 0 to allow a variable number of digits)\n * @param {number} [nBase]\n * @param {number} [nGrouping] (if nBase is 2, this is a grouping; otherwise, it's a prefix condition)\n * @return {string}\n */\n toStrBase(n, nBits = 0, nBase = 0, nGrouping = 0)\n {\n var s;\n switch(nBase || this.nBase) {\n case 2:\n s = Str.toBin(n, nBits > 0? nBits : 0, nGrouping);\n break;\n case 8:\n s = Str.toOct(n, nBits > 0? ((nBits + 2)/3)|0 : 0, !!nGrouping);\n break;\n case 10:\n /*\n * The multiplier is actually Math.log(2)/Math.log(10), but an approximation is more than adequate.\n */\n s = Str.toDec(n, nBits > 0? Math.ceil(nBits * 0.3) : 0);\n break;\n case 16:\n default:\n s = Str.toHex(n, nBits > 0? ((nBits + 3) >> 2) : 0, !!nGrouping);\n break;\n }\n return (nBits < 0? Str.stripLeadingZeros(s) : s);\n }\n}\n\nif (DEBUGGER) {\n\n /*\n * These are our operator precedence tables. Operators toward the bottom (with higher values) have\n * higher precedence. aBinOpPrecedence was our original table; we had to add aDECOpPrecedence because\n * the precedence of operators in DEC's MACRO-10 expressions differ. Having separate tables also allows\n * us to remove operators that shouldn't be supported, but unless some operator creates a problem,\n * I prefer to keep as much commonality between the tables as possible.\n *\n * Missing from these tables are the (limited) set of unary operators we support (negate and complement),\n * since this is only a BINARY operator precedence, not a general-purpose precedence table. Assume that\n * all unary operators take precedence over all binary operators.\n */\n Debugger.aBinOpPrecedence = {\n '||': 5, // logical OR\n '&&': 6, // logical AND\n '!': 7, // bitwise OR (conflicts with logical NOT, but we never supported that)\n '|': 7, // bitwise OR\n '^!': 8, // bitwise XOR (added by MACRO-10 sometime between the 1972 and 1978 versions)\n '&': 9, // bitwise AND\n '!=': 10, // inequality\n '==': 10, // equality\n '>=': 11, // greater than or equal to\n '>': 11, // greater than\n '<=': 11, // less than or equal to\n '<': 11, // less than\n '>>>': 12, // unsigned bitwise right shift\n '>>': 12, // bitwise right shift\n '<<': 12, // bitwise left shift\n '-': 13, // subtraction\n '+': 13, // addition\n '^/': 14, // remainder\n '/': 14, // division\n '*': 14, // multiplication\n '_': 19, // MACRO-10 shift operator\n '^_': 19, // MACRO-10 internal shift operator (converted from 'B' suffix form that MACRO-10 uses)\n '{': 20, // open grouped expression (converted from achGroup[0])\n '}': 20 // close grouped expression (converted from achGroup[1])\n };\n Debugger.aDECOpPrecedence = {\n ',,': 1, // high-word,,low-word\n '||': 5, // logical OR\n '&&': 6, // logical AND\n '!=': 10, // inequality\n '==': 10, // equality\n '>=': 11, // greater than or equal to\n '>': 11, // greater than\n '<=': 11, // less than or equal to\n '<': 11, // less than\n '>>>': 12, // unsigned bitwise right shift\n '>>': 12, // bitwise right shift\n '<<': 12, // bitwise left shift\n '-': 13, // subtraction\n '+': 13, // addition\n '^/': 14, // remainder\n '/': 14, // division\n '*': 14, // multiplication\n '!': 15, // bitwise OR (conflicts with logical NOT, but we never supported that)\n '|': 15, // bitwise OR\n '^!': 15, // bitwise XOR (added by MACRO-10 sometime between the 1972 and 1978 versions)\n '&': 15, // bitwise AND\n '_': 19, // MACRO-10 shift operator\n '^_': 19, // MACRO-10 internal shift operator (converted from 'B' suffix form that MACRO-10 uses)\n '{': 20, // open grouped expression (converted from achGroup[0])\n '}': 20 // close grouped expression (converted from achGroup[1])\n };\n\n /*\n * Assorted constants\n */\n Debugger.TWO_POW32 = Math.pow(2, 32);\n\n} // endif DEBUGGER\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/debugger.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * DebuggerPDP11 Address Object\n *\n * addr address\n * fPhysical true if this is a physical address\n * fTemporary true if this is a temporary breakpoint address\n * nBase set if the address contained an explicit base (eg, 16, 10, 8, etc)\n * sCmd set for breakpoint addresses if there's an associated command string\n * aCmds preprocessed commands (from sCmd)\n *\n * @typedef {{\n * addr:(number|null),\n * fPhysical:(boolean),\n * fTemporary:(boolean),\n * nBase:(number|undefined),\n * sCmd:(string|undefined),\n * aCmds:(Array.<string>|undefined)\n * }}\n */\nvar DbgAddrPDP11;\n\nclass DebuggerPDP11 extends Debugger {\n /**\n * DebuggerPDP11(parmsDbg)\n *\n * The DebuggerPDP11 component supports the following optional (parmsDbg) properties:\n *\n * commands: string containing zero or more commands, separated by ';'\n *\n * messages: string containing zero or more message categories to enable;\n * multiple categories must be separated by '|' or ';'. Parsed by messageInit().\n *\n * The DebuggerPDP11 component is an optional component that implements a variety of user\n * commands for controlling the CPU, dumping and editing memory, etc.\n *\n * @param {Object} parmsDbg\n */\n constructor(parmsDbg)\n {\n if (DEBUGGER) {\n\n super(parmsDbg);\n\n /*\n * Since this Debugger doesn't use replaceRegs(), we can use parentheses instead of braces.\n */\n this.fInit = false;\n\n this.achGroup = ['(',')'];\n this.achAddress = [];\n\n /*\n * Most commands that require an address call parseAddr(), which defaults to dbgAddrNextCode\n * or dbgAddrNextData when no address has been given. doDump() and doUnassemble(), in turn,\n * update dbgAddrNextData and dbgAddrNextCode, respectively, when they're done.\n *\n * For TEMPORARY breakpoint addresses, we set fTemporary to true, so that they can be automatically\n * cleared when they're hit.\n */\n this.dbgAddrNextCode = this.newAddr();\n this.dbgAddrNextData = this.newAddr();\n this.dbgAddrAssemble = this.newAddr();\n\n /*\n * aSymbolTable is an array of SymbolTable objects, one per ROM or other chunk of address space,\n * where each object contains the following properties:\n *\n * sModule\n * addr (physical address, if any; eg, symbols for a ROM)\n * len\n * aSymbols\n * aOffsets\n *\n * See addSymbols() for more details, since that's how callers add sets of symbols to the table.\n */\n this.aSymbolTable = [];\n\n /*\n * clearBreakpoints() initializes the breakpoints lists: aBreakExec is a list of addresses\n * to halt on whenever attempting to execute an instruction at the corresponding address,\n * and aBreakRead and aBreakWrite are lists of addresses to halt on whenever a read or write,\n * respectively, occurs at the corresponding address.\n *\n * NOTE: Curiously, after upgrading the Google Closure Compiler from v20141215 to v20150609,\n * the resulting compiled code would crash in clearBreakpoints(), because the (renamed) aBreakRead\n * property was already defined. To eliminate whatever was confusing the Closure Compiler, I've\n * explicitly initialized all the properties that clearBreakpoints() (re)initializes.\n */\n this.aBreakExec = this.aBreakRead = this.aBreakWrite = [];\n this.clearBreakpoints();\n\n /*\n * The new \"bn\" command allows you to specify a number of instructions to execute and then stop;\n * \"bn 0\" disables any outstanding count.\n */\n this.nBreakInstructions = 0;\n\n /*\n * Execution history is allocated by historyInit() whenever checksEnabled() conditions change.\n * Execution history is updated whenever the CPU calls checkInstruction(), which will happen\n * only when checksEnabled() returns true (eg, whenever one or more breakpoints have been set).\n * This ensures that, by default, the CPU runs as fast as possible.\n */\n this.iInstructionHistory = 0;\n this.aInstructionHistory = [];\n this.nextHistory = undefined;\n this.historyInit();\n\n /*\n * Initialize DebuggerPDP11 message support.\n */\n this.dbg = this;\n this.afnDumpers = {};\n this.bitsMessage = this.bitsWarning = 0;\n this.sMessagePrev = null;\n this.aMessageBuffer = [];\n this.messageInit(parmsDbg['messages']);\n this.sInitCommands = parmsDbg['commands'];\n\n /*\n * Define remaining miscellaneous DebuggerPDP11 properties.\n */\n this.opTable = DebuggerPDP11.OPTABLE;\n this.aOpReserved = [];\n this.nStep = 0;\n this.sCmdTracePrev = null;\n this.sCmdDumpPrev = null;\n this.fIgnoreNextCheckFault = false; // TODO: Does this serve any purpose on a PDP-11?\n this.nSuppressBreaks = 0;\n this.cInstructions = this.cInstructionsStart = 0;\n this.nCycles = this.nCyclesStart = this.msStart = 0;\n this.controlDebug = null;\n this.panel = null;\n\n /*\n * Make it easier to access DebuggerPDP11 commands from an external REPL (eg, the WebStorm\n * \"live\" console window); eg:\n *\n * pdp11('r')\n * pdp11('dw 0:0')\n * pdp11('h')\n * ...\n */\n var dbg = this;\n if (window) {\n if (window[PDP11.APPCLASS] === undefined) {\n window[PDP11.APPCLASS] = function(s) { return dbg.doCommands(s); };\n }\n } else {\n if (global[PDP11.APPCLASS] === undefined) {\n global[PDP11.APPCLASS] = function(s) { return dbg.doCommands(s); };\n }\n }\n\n } // endif DEBUGGER\n }\n\n /**\n * getAddr(dbgAddr, fWrite, nb)\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11|null} [dbgAddr]\n * @param {boolean} [fWrite]\n * @param {number} [nb] number of bytes to check (1 or 2); default is 1\n * @return {number} is the corresponding linear address, or PDP11.ADDR_INVALID\n */\n getAddr(dbgAddr, fWrite, nb)\n {\n var addr = dbgAddr && dbgAddr.addr;\n if (addr == null) addr = PDP11.ADDR_INVALID;\n return addr;\n }\n\n /**\n * newAddr(addr, fPhysical, nBase)\n *\n * Returns a NEW DbgAddrPDP11 object, initialized with specified values and/or defaults.\n *\n * @this {DebuggerPDP11}\n * @param {number|null} [addr]\n * @param {boolean} [fPhysical]\n * @param {number} [nBase]\n * @return {DbgAddrPDP11}\n */\n newAddr(addr = null, fPhysical = false, nBase)\n {\n return {addr: addr, fPhysical: fPhysical, fTemporary: false, nBase: nBase};\n }\n\n /**\n * setAddr(dbgAddr, addr)\n *\n * Updates an EXISTING DbgAddrPDP11 object, initialized with specified values and/or defaults.\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @param {number} addr\n * @return {DbgAddrPDP11}\n */\n setAddr(dbgAddr, addr)\n {\n dbgAddr.addr = addr;\n dbgAddr.fTemporary = false;\n dbgAddr.nBase = undefined;\n return dbgAddr;\n }\n\n /**\n * packAddr(dbgAddr)\n *\n * Packs a DbgAddrPDP11 object into an Array suitable for saving in a machine state object.\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @return {Array}\n */\n packAddr(dbgAddr)\n {\n return [dbgAddr.addr, dbgAddr.fPhysical, dbgAddr.nBase, dbgAddr.fTemporary, dbgAddr.sCmd];\n }\n\n /**\n * unpackAddr(aAddr)\n *\n * Unpacks a DbgAddrPDP11 object from an Array created by packAddr() and restored from a saved machine state.\n *\n * @this {DebuggerPDP11}\n * @param {Array} aAddr\n * @return {DbgAddrPDP11}\n */\n unpackAddr(aAddr)\n {\n var dbgAddr = this.newAddr(aAddr[0], aAddr[1], aAddr[2]);\n dbgAddr.fTemporary = aAddr[3];\n if (aAddr[4]) {\n dbgAddr.aCmds = this.parseCommand(dbgAddr.sCmd = aAddr[4]);\n }\n return dbgAddr;\n }\n\n /**\n * initBus(bus, cpu, dbg)\n *\n * @this {DebuggerPDP11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cmp = cmp;\n this.cpu = cpu;\n this.panel = cmp.panel;\n\n /*\n * Re-initialize Debugger message support if necessary\n */\n var sMessages = /** @type {string|undefined} */ (cmp.getMachineParm('messages'));\n if (sMessages) this.messageInit(sMessages);\n\n if (this.cpu.model < PDP11.MODEL_1140) {\n this.aOpReserved = this.aOpReserved.concat(DebuggerPDP11.OP1140);\n }\n if (this.cpu.model < PDP11.MODEL_1145) {\n this.aOpReserved = this.aOpReserved.concat(DebuggerPDP11.OP1145);\n }\n\n this.messageDump(MessagesPDP11.BUS, function onDumpBus(asArgs) { dbg.dumpBus(asArgs); });\n\n this.setReady();\n }\n\n /**\n * setBinding(sType, sBinding, control, sValue)\n *\n * @this {DebuggerPDP11}\n * @param {string|null} sType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"debugInput\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sType, sBinding, control, sValue)\n {\n var dbg = this;\n switch (sBinding) {\n\n case \"debugInput\":\n this.bindings[sBinding] = control;\n this.controlDebug = /** @type {HTMLInputElement} */ (control);\n /*\n * For halted machines, this is fine, but for auto-start machines, it can be annoying.\n *\n * control.focus();\n */\n control.onkeydown = function onKeyDownDebugInput(event) {\n var sCmd;\n if (event.keyCode == Keys.KEYCODE.CR) {\n sCmd = dbg.controlDebug.value;\n dbg.controlDebug.value = \"\";\n dbg.doCommands(sCmd, true);\n }\n else if (event.keyCode == Keys.KEYCODE.ESC) {\n dbg.controlDebug.value = sCmd = \"\";\n }\n else {\n if (event.keyCode == Keys.KEYCODE.UP) {\n sCmd = dbg.getPrevCommand();\n }\n else if (event.keyCode == Keys.KEYCODE.DOWN) {\n sCmd = dbg.getNextCommand();\n }\n if (sCmd != null) {\n var cch = sCmd.length;\n dbg.controlDebug.value = sCmd;\n dbg.controlDebug.setSelectionRange(cch, cch);\n }\n }\n if (sCmd != null && event.preventDefault) event.preventDefault();\n };\n return true;\n\n case \"debugEnter\":\n this.bindings[sBinding] = control;\n Web.onClickRepeat(\n control,\n 500, 100,\n function onClickDebugEnter(fRepeat) {\n if (dbg.controlDebug) {\n var sCmd = dbg.controlDebug.value;\n dbg.controlDebug.value = \"\";\n dbg.doCommands(sCmd, true);\n return true;\n }\n if (DEBUG) dbg.log(\"no debugger input buffer\");\n return false;\n }\n );\n return true;\n\n case \"step\":\n this.bindings[sBinding] = control;\n Web.onClickRepeat(\n control,\n 500, 100,\n function onClickStep(fRepeat) {\n var fCompleted = false;\n if (!dbg.isBusy(true)) {\n dbg.setBusy(true);\n fCompleted = dbg.stepCPU(fRepeat? 1 : 0, null);\n dbg.setBusy(false);\n }\n return fCompleted;\n }\n );\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * setFocus(fScroll)\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fScroll] (true if you really want the control scrolled into view)\n */\n setFocus(fScroll)\n {\n if (this.controlDebug) {\n /*\n * This is the recommended work-around to prevent the browser from scrolling the focused element\n * into view. The CPU is not a visual component, so when the CPU wants to set focus, the primary intent\n * is to ensure that keyboard input is fielded properly.\n */\n var x = 0, y = 0;\n if (!fScroll && window) {\n x = window.scrollX;\n y = window.scrollY;\n }\n\n this.controlDebug.focus();\n\n if (!fScroll && window) {\n window.scrollTo(x, y);\n }\n }\n }\n\n /**\n * mapUnibus(addr)\n *\n * @this {DebuggerPDP11}\n * @param {number} addr\n * @return {number}\n */\n mapUnibus(addr)\n {\n return this.cpu.mapUnibus(addr);\n }\n\n /**\n * getByte(dbgAddr, inc)\n *\n * We must route all our memory requests through the CPU now, in case paging is enabled.\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @param {number} [inc]\n * @return {number}\n */\n getByte(dbgAddr, inc)\n {\n var b = 0xff;\n var addr = this.getAddr(dbgAddr, false, 1);\n if (addr !== PDP11.ADDR_INVALID) {\n b = (dbgAddr.fPhysical || addr > 0xffff)? this.bus.getByteDirect(this.mapUnibus(addr)) : this.cpu.getByteSafe(addr);\n if (inc) this.incAddr(dbgAddr, inc);\n }\n return b;\n }\n\n /**\n * getWord(dbgAddr, inc)\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @param {number} [inc]\n * @return {number}\n */\n getWord(dbgAddr, inc)\n {\n var w = 0xffff;\n var addr = this.getAddr(dbgAddr, false, 2);\n if (addr !== PDP11.ADDR_INVALID) {\n w = (dbgAddr.fPhysical || addr > 0xffff)? this.bus.getWordDirect(this.mapUnibus(addr)) : this.cpu.getWordSafe(addr);\n if (inc) this.incAddr(dbgAddr, inc);\n }\n return w;\n }\n\n /**\n * setByte(dbgAddr, b, inc)\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @param {number} b\n * @param {number} [inc]\n */\n setByte(dbgAddr, b, inc)\n {\n var addr = this.getAddr(dbgAddr, true, 1);\n if (addr !== PDP11.ADDR_INVALID) {\n if (dbgAddr.fPhysical || addr > 0xffff) {\n this.bus.setByteDirect(this.mapUnibus(addr), b);\n } else {\n this.cpu.setByteSafe(addr, b);\n }\n if (inc) this.incAddr(dbgAddr, inc);\n this.cmp.updateDisplays(-1);\n }\n }\n\n /**\n * setWord(dbgAddr, w, inc)\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @param {number} w\n * @param {number} [inc]\n */\n setWord(dbgAddr, w, inc)\n {\n var addr = this.getAddr(dbgAddr, true, 2);\n if (addr !== PDP11.ADDR_INVALID) {\n if (dbgAddr.fPhysical || addr > 0xffff) {\n this.bus.setWordDirect(this.mapUnibus(addr), w);\n } else {\n this.cpu.setWordSafe(addr, w);\n }\n if (inc) this.incAddr(dbgAddr, inc);\n this.cmp.updateDisplays(-1);\n }\n }\n\n /**\n * parseAddr(sAddr, fCode, fNoChecks)\n *\n * Address evaluation and validation (eg, range checks) are no longer performed at this stage. That's\n * done later, by getAddr(), which returns PDP11.ADDR_INVALID for invalid segments, out-of-range offsets,\n * etc. The Debugger's low-level get/set memory functions verify all getAddr() results, but even if an\n * invalid address is passed through to the Bus memory interfaces, the address will simply be masked with\n * bus.nBusMask; in the case of PDP11.ADDR_INVALID, that will generally refer to the top of the physical\n * address space.\n *\n * @this {DebuggerPDP11}\n * @param {string|undefined} sAddr\n * @param {boolean} [fCode] (true if target is code, false if target is data)\n * @param {boolean} [fNoChecks] (true when setting breakpoints that may not be valid now, but will be later)\n * @return {DbgAddrPDP11|null|undefined}\n */\n parseAddr(sAddr, fCode, fNoChecks)\n {\n var dbgAddr;\n var dbgAddrNext = (fCode? this.dbgAddrNextCode : this.dbgAddrNextData);\n var addr = dbgAddrNext.addr;\n var fPhysical, nBase;\n if (sAddr !== undefined) {\n sAddr = this.parseReference(sAddr);\n var ch = sAddr.charAt(0);\n if (ch == '%') {\n fPhysical = true;\n sAddr = sAddr.substr(1);\n }\n dbgAddr = this.findSymbolAddr(sAddr);\n if (dbgAddr) return dbgAddr;\n if (sAddr.indexOf(\"0x\") >= 0) {\n nBase = 16\n } else if (sAddr.indexOf(\"0o\") >= 0) {\n nBase = 8;\n } else if (sAddr.indexOf('.') >= 0) {\n nBase = 10;\n }\n addr = this.parseExpression(sAddr);\n }\n if (addr != null) {\n dbgAddr = this.newAddr(addr, fPhysical, nBase);\n }\n return dbgAddr;\n }\n\n /**\n * parseAddrOptions(dbdAddr, sOptions)\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @param {string} [sOptions]\n */\n parseAddrOptions(dbgAddr, sOptions)\n {\n if (sOptions) {\n var a = sOptions.match(/(['\"])(.*?)\\1/);\n if (a) {\n dbgAddr.aCmds = this.parseCommand(dbgAddr.sCmd = a[2]);\n }\n }\n }\n\n /**\n * incAddr(dbgAddr, inc)\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @param {number} [inc] contains value to increment dbgAddr by (default is 1)\n */\n incAddr(dbgAddr, inc)\n {\n if (dbgAddr.addr != null) {\n dbgAddr.addr += (inc || 1);\n }\n }\n\n /**\n * toStrOffset(off)\n *\n * @this {DebuggerPDP11}\n * @param {number|null|undefined} [off]\n * @return {string} the hex representation of off\n */\n toStrOffset(off)\n {\n return this.toStrBase(off);\n }\n\n /**\n * toStrAddr(dbgAddr)\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @return {string} the hex representation of the address\n */\n toStrAddr(dbgAddr)\n {\n return (dbgAddr.fPhysical? '%' : '') + this.toStrOffset(dbgAddr.addr);\n }\n\n /**\n * getSZ(dbgAddr, cchMax)\n *\n * Gets zero-terminated (aka \"ASCIIZ\") string from dbgAddr. It also stops at the first '$', in case this is\n * a '$'-terminated string -- mainly because I'm lazy and didn't feel like writing a separate get() function.\n * Yes, a zero-terminated string containing a '$' will be prematurely terminated, and no, I don't care.\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @param {number} [cchMax] (default is 256)\n * @return {string} (and dbgAddr advanced past the terminating zero)\n */\n getSZ(dbgAddr, cchMax)\n {\n var s = \"\";\n cchMax = cchMax || 256;\n while (s.length < cchMax) {\n var b = this.getByte(dbgAddr, 1);\n if (!b || b == 0x24 || b >= 127) break;\n s += (b >= 32? String.fromCharCode(b) : '.');\n }\n return s;\n }\n\n /**\n * dumpBlocks(aBlocks, sAddr)\n *\n * @this {DebuggerPDP11}\n * @param {Array} aBlocks\n * @param {string} [sAddr] (optional block address)\n */\n dumpBlocks(aBlocks, sAddr)\n {\n var addr = 0, i = 0, n = aBlocks.length;\n\n if (sAddr) {\n addr = this.getAddr(this.parseAddr(sAddr));\n if (addr === PDP11.ADDR_INVALID) {\n this.println(\"invalid address: \" + sAddr);\n return;\n }\n i = addr >>> this.bus.nBlockShift;\n n = 1;\n }\n\n this.println(\"blockid physical blockaddr used size type\");\n this.println(\"-------- --------- --------- ------ ------ ----\");\n\n var typePrev = -1, cPrev = 0;\n while (n--) {\n var block = aBlocks[i];\n if (block.type == typePrev) {\n if (!cPrev++) this.println(\"...\");\n } else {\n typePrev = block.type;\n var sType = MemoryPDP11.TYPE_NAMES[typePrev];\n if (block) {\n this.println(Str.toHex(block.id, 8) + \" %\" + Str.toHex(i << this.bus.nBlockShift, 8) + \" %\" + Str.toHex(block.addr, 8) + \" \" + Str.toHexWord(block.used) + \" \" + Str.toHexWord(block.size) + \" \" + sType);\n }\n if (typePrev != MemoryPDP11.TYPE.NONE) typePrev = -1;\n cPrev = 0;\n }\n addr += this.bus.nBlockSize;\n i++;\n }\n }\n\n /**\n * dumpBus(asArgs)\n *\n * Dumps Bus allocations.\n *\n * @this {DebuggerPDP11}\n * @param {Array.<string>} asArgs (asArgs[0] is an optional block address)\n */\n dumpBus(asArgs)\n {\n this.dumpBlocks(this.bus.aBusBlocks, asArgs[0]);\n }\n\n /**\n * dumpHistory(sPrev, sLines)\n *\n * If sLines is not a number, it can be a instruction filter. However, for the moment, the only\n * supported filter is \"call\", which filters the history buffer for all CALL and RET instructions\n * from the specified previous point forward.\n *\n * @this {DebuggerPDP11}\n * @param {string} [sPrev] is a (decimal) number of instructions to rewind to (default is 10)\n * @param {string} [sLines] is a (decimal) number of instructions to print (default is, again, 10)\n */\n dumpHistory(sPrev, sLines)\n {\n var sMore = \"\";\n var cHistory = 0;\n var iHistory = this.iInstructionHistory;\n var aHistory = this.aInstructionHistory;\n\n if (aHistory.length) {\n var nPrev = +sPrev || this.nextHistory;\n var nLines = +sLines || 10;\n\n if (isNaN(nPrev)) {\n nPrev = nLines;\n } else {\n sMore = \"more \";\n }\n\n if (nPrev > aHistory.length) {\n this.println(\"note: only \" + aHistory.length + \" available\");\n nPrev = aHistory.length;\n }\n\n iHistory -= nPrev;\n if (iHistory < 0) {\n /*\n * If the dbgAddr of the last aHistory element contains a valid selector, wrap around.\n */\n if (aHistory[aHistory.length - 1].addr == null) {\n nPrev = iHistory + nPrev;\n iHistory = 0;\n } else {\n iHistory += aHistory.length;\n }\n }\n\n var aFilters = [];\n if (sLines == \"call\") {\n nLines = 100000;\n aFilters = [\"CALL\"];\n }\n\n if (sPrev !== undefined) {\n this.println(nPrev + \" instructions earlier:\");\n }\n\n /*\n * TODO: The following is necessary to prevent dumpHistory() from causing additional (or worse, recursive)\n * faults due to segmented addresses that are no longer valid, but the only alternative is to dramatically\n * increase the amount of memory used to store instruction history (eg, storing copies of all the instruction\n * bytes alongside the execution addresses).\n *\n * For now, we're living dangerously, so that our history dumps actually work.\n *\n * this.nSuppressBreaks++;\n *\n * If you re-enable this protection, be sure to re-enable the decrement below, too.\n */\n while (nLines > 0 && iHistory != this.iInstructionHistory) {\n\n var dbgAddr = aHistory[iHistory++];\n if (dbgAddr.addr == null) break;\n\n /*\n * We must create a new dbgAddr from the address in aHistory, because dbgAddr was\n * a reference, not a copy, and we don't want getInstruction() modifying the original.\n */\n var dbgAddrNew = this.newAddr(dbgAddr.addr);\n\n var sComment = \"history\";\n var nSequence = nPrev--;\n\n /*\n * TODO: Need to some UI to control whether cycle counts are displayed as part of the history.\n * It's currently disabled in checkInstruction(), so it's disable here, too.\n *\n if (DEBUG && dbgAddr.cycleCount != null) {\n sComment = \"cycles\";\n nSequence = dbgAddr.cycleCount;\n }\n */\n\n var sInstruction = this.getInstruction(dbgAddrNew, sComment, nSequence);\n\n if (!aFilters.length || sInstruction.indexOf(aFilters[0]) >= 0) {\n this.println(sInstruction);\n }\n\n /*\n * If there were OPERAND or ADDRESS overrides on the previous instruction, getInstruction()\n * will have automatically disassembled additional bytes, so skip additional history entries.\n */\n if (dbgAddrNew.cOverrides) {\n iHistory += dbgAddrNew.cOverrides; nLines -= dbgAddrNew.cOverrides; nPrev -= dbgAddrNew.cOverrides;\n }\n\n if (iHistory >= aHistory.length) iHistory = 0;\n this.nextHistory = nPrev;\n cHistory++;\n nLines--;\n }\n /*\n * See comments above.\n *\n * this.nSuppressBreaks--;\n */\n }\n\n if (!cHistory) {\n this.println(\"no \" + sMore + \"history available\");\n this.nextHistory = undefined;\n }\n }\n\n /**\n * messageInit(sEnable)\n *\n * @this {DebuggerPDP11}\n * @param {string|undefined} sEnable contains zero or more message categories to enable, separated by '|'\n */\n messageInit(sEnable)\n {\n this.dbg = this;\n this.bitsMessage = this.bitsWarning = MessagesPDP11.WARN;\n this.sMessagePrev = null;\n this.aMessageBuffer = [];\n /*\n * Internally, we use \"key\" instead of \"keys\", since the latter is a method on JavasScript objects,\n * but externally, we allow the user to specify \"keys\"; \"kbd\" is also allowed as shorthand for \"keyboard\".\n */\n var aEnable = this.parseCommand(sEnable.replace(\"keys\",\"key\").replace(\"kbd\",\"keyboard\"), false, '|');\n if (aEnable.length) {\n for (var m in MessagesPDP11.CATEGORIES) {\n if (Usr.indexOf(aEnable, m) >= 0) {\n this.bitsMessage |= MessagesPDP11.CATEGORIES[m];\n this.println(m + \" messages enabled\");\n }\n }\n }\n }\n\n /**\n * messageDump(bitMessage, fnDumper)\n *\n * @this {DebuggerPDP11}\n * @param {number} bitMessage is one Messages category flag\n * @param {function(Array.<string>)} fnDumper is a function the Debugger can use to dump data for that category\n * @return {boolean} true if successfully registered, false if not\n */\n messageDump(bitMessage, fnDumper)\n {\n for (var m in MessagesPDP11.CATEGORIES) {\n if (bitMessage == MessagesPDP11.CATEGORIES[m]) {\n this.afnDumpers[m] = fnDumper;\n return true;\n }\n }\n return false;\n }\n\n /**\n * getRegIndex(sReg, off)\n *\n * @this {DebuggerPDP11}\n * @param {string} sReg\n * @param {number} [off] optional offset into sReg\n * @return {number} register index, or -1 if not found\n */\n getRegIndex(sReg, off)\n {\n sReg = sReg.toUpperCase();\n var iReg = DebuggerPDP11.REGS[sReg];\n if (iReg == null) {\n iReg = -1;\n if (sReg.charAt(0) == \"R\") {\n iReg = +sReg.charAt(1);\n if (iReg < 0 || iReg > 7) iReg = -1;\n }\n }\n return iReg;\n }\n\n /**\n * getRegName(iReg)\n *\n * @this {DebuggerPDP11}\n * @param {number} iReg (0-7; not used for other registers)\n * @return {string}\n */\n getRegName(iReg)\n {\n var sReg;\n if (iReg < DebuggerPDP11.REG_AR || this.panel) sReg = DebuggerPDP11.REGNAMES[iReg];\n return sReg || \"\";\n }\n\n /**\n * getRegValue(iReg)\n *\n * Register numbers 0-7 are reserved for cpu.regsGen, 8-15 are reserved for cpu.regsAlt,\n * 16-19 for cpu.regsAltStack, 20 for regPSW, etc.\n *\n * @this {DebuggerPDP11}\n * @param {number} iReg\n * @return {number|undefined}\n */\n getRegValue(iReg)\n {\n var value;\n if (iReg >= 0) {\n if (iReg < 8) {\n value = this.cpu.regsGen[iReg];\n }\n else if (iReg < 16) {\n value = this.cpu.regsAlt[iReg-8];\n }\n else if (iReg < 20) {\n value = this.cpu.regsAltStack[iReg-16];\n }\n else {\n var cpu = this.cpu;\n var panel = this.panel;\n switch(iReg) {\n case DebuggerPDP11.REG_PS:\n value = this.cpu.getPSW();\n break;\n case DebuggerPDP11.REG_PI:\n value = cpu.getPIR();\n break;\n case DebuggerPDP11.REG_ER:\n value = cpu.regErr;\n break;\n case DebuggerPDP11.REG_SL:\n value = cpu.getSLR();\n break;\n case DebuggerPDP11.REG_M0:\n value = cpu.getMMR0();\n break;\n case DebuggerPDP11.REG_M1:\n value = cpu.getMMR1();\n break;\n case DebuggerPDP11.REG_M2:\n value = cpu.getMMR2();\n break;\n case DebuggerPDP11.REG_M3:\n value = cpu.getMMR3();\n break;\n case DebuggerPDP11.REG_AR:\n if (panel) value = panel.getAR();\n break;\n case DebuggerPDP11.REG_DR:\n if (panel) value = panel.getDR();\n break;\n case DebuggerPDP11.REG_SR:\n if (panel) value = panel.getSR();\n break;\n }\n }\n }\n return value;\n }\n\n /**\n * replaceRegs(s)\n *\n * TODO: Implement or eliminate.\n *\n * @this {DebuggerPDP11}\n * @param {string} s\n * @return {string}\n */\n replaceRegs(s)\n {\n return s;\n }\n\n /**\n * message(sMessage, fAddress)\n *\n * @this {DebuggerPDP11}\n * @param {string} sMessage is any caller-defined message string\n * @param {boolean} [fAddress] is true to display the current address\n */\n message(sMessage, fAddress)\n {\n if (fAddress) {\n sMessage += \" @\" + this.toStrAddr(this.newAddr(this.cpu.getLastPC()));\n }\n\n if (this.sMessagePrev && sMessage == this.sMessagePrev) return;\n this.sMessagePrev = sMessage;\n\n if (this.bitsMessage & MessagesPDP11.BUFFER) {\n this.aMessageBuffer.push(sMessage);\n return;\n }\n\n var fRunning;\n if ((this.bitsMessage & MessagesPDP11.HALT) && this.cpu && (fRunning = this.cpu.isRunning()) || this.isBusy(true)) {\n this.stopCPU();\n if (fRunning) sMessage += \" (cpu halted)\";\n }\n\n this.println(sMessage); // + \" (\" + this.cpu.getCycles() + \" cycles)\"\n\n /*\n * We have no idea what the frequency of println() calls might be; all we know is that they easily\n * screw up the CPU's careful assumptions about cycles per burst. So we call yieldCPU() after every\n * message, to effectively end the current burst and start fresh.\n *\n * TODO: See CPUPDP11.calcStartTime() for a discussion of why we might want to call yieldCPU() *before*\n * we display the message.\n */\n if (this.cpu) this.cpu.yieldCPU();\n }\n\n /**\n * init()\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fAutoStart]\n */\n init(fAutoStart)\n {\n this.fInit = true;\n this.println(\"Type ? for help with PDPjs Debugger commands\");\n this.updateStatus();\n if (!fAutoStart) this.setFocus();\n if (this.sInitCommands) {\n var sCmds = this.sInitCommands;\n this.sInitCommands = null;\n this.doCommands(sCmds);\n }\n }\n\n /**\n * historyInit(fQuiet)\n *\n * This function is intended to be called by the constructor, reset(), addBreakpoint(), findBreakpoint()\n * and any other function that changes the checksEnabled() criteria used to decide whether checkInstruction()\n * should be called.\n *\n * That is, if the history arrays need to be allocated and haven't already been allocated, then allocate them,\n * and if the arrays are no longer needed, then deallocate them.\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fQuiet]\n */\n historyInit(fQuiet)\n {\n var i;\n if (!this.checksEnabled()) {\n if (this.aInstructionHistory && this.aInstructionHistory.length && !fQuiet) {\n this.println(\"instruction history buffer freed\");\n }\n this.iInstructionHistory = 0;\n this.aInstructionHistory = [];\n return;\n }\n if (!this.aInstructionHistory || !this.aInstructionHistory.length) {\n this.aInstructionHistory = new Array(DebuggerPDP11.HISTORY_LIMIT);\n for (i = 0; i < this.aInstructionHistory.length; i++) {\n /*\n * Preallocate dummy Addr (Array) objects in every history slot, so that\n * checkInstruction() doesn't need to call newAddr() on every slot update.\n */\n this.aInstructionHistory[i] = this.newAddr();\n }\n this.iInstructionHistory = 0;\n if (!fQuiet) {\n this.println(\"instruction history buffer allocated\");\n }\n }\n }\n\n /**\n * startCPU(fUpdateFocus, fQuiet)\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fUpdateFocus] is true to update focus\n * @param {boolean} [fQuiet]\n * @return {boolean} true if run request successful, false if not\n */\n startCPU(fUpdateFocus, fQuiet)\n {\n if (!this.checkCPU(fQuiet)) return false;\n this.cpu.startCPU(fUpdateFocus);\n return true;\n }\n\n /**\n * stepCPU(nCycles, fRegs, fUpdateDisplays)\n *\n * @this {DebuggerPDP11}\n * @param {number} nCycles (0 for one instruction without checking breakpoints)\n * @param {boolean|null} [fRegs] is true to display registers after step (default is false; use null for previous setting)\n * @param {boolean} [fUpdateDisplays] is false to disable Computer display updates (default is true)\n * @return {boolean}\n */\n stepCPU(nCycles, fRegs, fUpdateDisplays)\n {\n if (!this.checkCPU()) return false;\n\n var sCmd = \"\";\n if (fRegs === null) {\n fRegs = (!this.sCmdTracePrev || this.sCmdTracePrev == \"tr\");\n sCmd = fRegs? \"tr\" : \"t\";\n }\n\n this.nCycles = 0;\n\n if (!nCycles) {\n /*\n * When single-stepping, the CPU won't call checkInstruction(), which is good for\n * avoiding breakpoints, but bad for instruction data collection if checks are enabled.\n * So we call checkInstruction() ourselves.\n */\n if (this.checksEnabled()) this.checkInstruction(this.cpu.getPC(), 0);\n }\n /*\n * For our typically tiny bursts (usually single instructions), mimic what runCPU() does.\n */\n try {\n nCycles = this.cpu.getBurstCycles(nCycles);\n var nCyclesStep = this.cpu.stepCPU(nCycles);\n if (nCyclesStep > 0) {\n this.cpu.updateTimers(nCyclesStep);\n this.nCycles += nCyclesStep;\n this.cpu.addCycles(nCyclesStep, true);\n this.cpu.updateChecksum(nCyclesStep);\n this.cInstructions++;\n }\n }\n catch(exception) {\n /*\n * We assume that any numeric exception was explicitly thrown by the CPU to interrupt the\n * current instruction. For all other exceptions, we attempt a stack dump.\n */\n if (typeof exception != \"number\") {\n var e = exception;\n this.nCycles = 0;\n this.cpu.setError(e.stack || e.message);\n }\n }\n\n /*\n * Because we called cpu.stepCPU() and not cpu.startCPU(), we must nudge the Computer's update code,\n * and then update our own state. Normally, the only time fUpdateDisplays will be false is when doTrace()\n * is calling us in a loop, in which case it will perform its own updateDisplays() when it's done.\n */\n if (fUpdateDisplays !== false) {\n if (this.panel) this.panel.stop();\n this.cmp.updateDisplays(-1);\n }\n\n this.updateStatus(fRegs || false, sCmd);\n return (this.nCycles > 0);\n }\n\n /**\n * stopCPU()\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fComplete]\n */\n stopCPU(fComplete)\n {\n if (this.cpu) this.cpu.stopCPU(fComplete);\n }\n\n /**\n * updateStatus(fRegs, sCmd)\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fRegs] (default is true)\n * @param {string} [sCmd]\n */\n updateStatus(fRegs, sCmd)\n {\n if (!this.fInit) return;\n\n if (fRegs === undefined) fRegs = true;\n\n if (sCmd) {\n this.println(DebuggerPDP11.PROMPT + sCmd);\n }\n\n var trapStatus = this.cpu.getTrapStatus();\n if (trapStatus) {\n var reason = trapStatus >> 8;\n var sReason = reason < 0? PDP11.REASONS[-reason] : this.toStrBase(reason);\n this.println(\"trapped to \" + this.toStrBase(trapStatus & 0xff, 8) + \" (\" + sReason + \")\");\n }\n\n this.dbgAddrNextCode = this.newAddr(this.cpu.getPC());\n /*\n * this.nStep used to be a simple boolean, but now it's 0 (or undefined)\n * if inactive, 1 if stepping over an instruction without a register dump, or 2\n * if stepping over an instruction with a register dump.\n */\n if (!fRegs || this.nStep == 1) {\n this.doUnassemble();\n } else {\n this.doRegisters();\n }\n }\n\n /**\n * checkCPU(fQuiet)\n *\n * Make sure the CPU is ready (finished initializing), powered, not already running, and not in an error state.\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fQuiet]\n * @return {boolean}\n */\n checkCPU(fQuiet)\n {\n if (!this.cpu || !this.cpu.isReady() || !this.cpu.isPowered() || this.cpu.isRunning()) {\n if (!fQuiet) this.println(\"cpu busy or unavailable, command ignored\");\n return false;\n }\n return !this.cpu.isError();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {DebuggerPDP11}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n /*\n * Because Debugger save/restore support is somewhat limited (and didn't always exist),\n * we deviate from the typical save/restore design pattern: instead of reset OR restore,\n * we always reset and then perform a (potentially limited) restore.\n */\n this.reset(true);\n\n // this.println(data? \"resuming\" : \"powering up\");\n\n if (data) {\n return this.restore(data);\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean}\n */\n powerDown(fSave, fShutdown)\n {\n if (fShutdown) this.println(fSave? \"suspending\" : \"shutting down\");\n return fSave? this.save() : true;\n }\n\n /**\n * reset(fQuiet)\n *\n * This is a notification handler, called by the Computer, to inform us of a reset.\n *\n * @this {DebuggerPDP11}\n * @param {boolean} fQuiet (true only when called from our own powerUp handler)\n */\n reset(fQuiet)\n {\n this.historyInit();\n this.cInstructions = this.cInstructionsStart = 0;\n this.sMessagePrev = null;\n this.nCycles = 0;\n this.dbgAddrNextCode = this.newAddr(this.cpu.getPC());\n /*\n * fRunning is set by start() and cleared by stop(). In addition, we clear\n * it here, so that if the CPU is reset while running, we can prevent stop()\n * from unnecessarily dumping the CPU state.\n */\n this.flags.running = false;\n this.clearTempBreakpoint();\n if (!fQuiet) this.updateStatus();\n }\n\n /**\n * save()\n *\n * This implements (very rudimentary) save support for the Debugger component.\n *\n * @this {DebuggerPDP11}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.packAddr(this.dbgAddrNextCode));\n state.set(1, this.packAddr(this.dbgAddrAssemble));\n state.set(2, [this.aPrevCmds, this.fAssemble, this.bitsMessage]);\n state.set(3, this.aSymbolTable);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements (very rudimentary) restore support for the Debugger component.\n *\n * @this {DebuggerPDP11}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var i = 0;\n if (data[2] !== undefined) {\n this.dbgAddrNextCode = this.unpackAddr(data[i++]);\n this.dbgAddrAssemble = this.unpackAddr(data[i++]);\n this.aPrevCmds = data[i][0];\n if (typeof this.aPrevCmds == \"string\") this.aPrevCmds = [this.aPrevCmds];\n this.fAssemble = data[i][1];\n this.bitsMessage |= data[i][2]; // keep our current message bits set, and simply \"add\" any extra bits defined by the saved state\n }\n if (data[3]) this.aSymbolTable = data[3];\n return true;\n }\n\n /**\n * start(ms, nCycles)\n *\n * This is a notification handler, called by the Computer, to inform us the CPU has started.\n *\n * @this {DebuggerPDP11}\n * @param {number} ms\n * @param {number} nCycles\n */\n start(ms, nCycles)\n {\n if (!this.nStep) this.println(\"running\");\n this.flags.running = true;\n this.msStart = ms;\n this.nCyclesStart = nCycles;\n }\n\n /**\n * stop(ms, nCycles)\n *\n * This is a notification handler, called by the Computer, to inform us the CPU has now stopped.\n *\n * @this {DebuggerPDP11}\n * @param {number} ms\n * @param {number} nCycles\n */\n stop(ms, nCycles)\n {\n if (this.flags.running) {\n this.flags.running = false;\n this.nCycles = nCycles - this.nCyclesStart;\n if (!this.nStep) {\n var sStopped = \"stopped\";\n if (this.nCycles) {\n var msTotal = ms - this.msStart;\n var nCyclesPerSecond = (msTotal > 0? Math.round(this.nCycles * 1000 / msTotal) : 0);\n sStopped += \" (\";\n if (this.checksEnabled()) {\n sStopped += this.cInstructions + \" instructions, \";\n /*\n * $ops displays progress by calculating cInstructions - cInstructionsStart, so before\n * zeroing cInstructions, we should subtract cInstructions from cInstructionsStart (since\n * we're effectively subtracting cInstructions from cInstructions as well).\n */\n this.cInstructionsStart -= this.cInstructions;\n this.cInstructions = 0;\n }\n sStopped += this.nCycles + \" cycles, \" + msTotal + \" ms, \" + nCyclesPerSecond + \" hz)\";\n } else {\n if (this.messageEnabled(MessagesPDP11.HALT)) {\n /*\n * It's possible the user is trying to 'g' past a fault that was blocked by helpCheckFault()\n * for the Debugger's benefit; if so, it will continue to be blocked, so try displaying a helpful\n * message (another helpful tip would be to simply turn off the \"halt\" message category).\n */\n sStopped += \" (use the 't' command to execute blocked faults)\";\n }\n }\n this.println(sStopped);\n }\n this.updateStatus(true);\n this.setFocus();\n this.clearTempBreakpoint(this.cpu.getPC());\n this.sMessagePrev = null;\n }\n }\n\n /**\n * checksEnabled(fRelease)\n *\n * This \"check\" function is called by the CPU; we indicate whether or not every instruction needs to be checked.\n *\n * Originally, this returned true even when there were only read and/or write breakpoints, but those breakpoints\n * no longer require the intervention of checkInstruction(); the Bus component automatically swaps in/out appropriate\n * \"checked\" Memory access functions to deal with those breakpoints in the corresponding Memory blocks. So I've\n * simplified the test below.\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fRelease] is true for release criteria only; default is false (any criteria)\n * @return {boolean} true if every instruction needs to pass through checkInstruction(), false if not\n */\n checksEnabled(fRelease)\n {\n return ((DEBUG && !fRelease)? true : (this.aBreakExec.length > 1 || !!this.nBreakInstructions));\n }\n\n /**\n * checkInstruction(addr, nState)\n *\n * This \"check\" function is called by the CPU to inform us about the next instruction to be executed,\n * giving us an opportunity to look for \"exec\" breakpoints and update opcode instruction history.\n *\n * @this {DebuggerPDP11}\n * @param {number} addr\n * @param {number} nState is < 0 if stepping, 0 if starting, or > 0 if running\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkInstruction(addr, nState)\n {\n var opCode = -1;\n var cpu = this.cpu;\n\n /*\n * If opHalt() calls our stopInstruction() function, it will effectively rewind the PC back to the HALT,\n * purely for our debugging benefit, so we must compensate for that here by advancing the PC past the HALT\n * when the machine starts up again.\n */\n if (!nState) {\n opCode = this.cpu.getWordSafe(addr);\n /*\n * We have to be careful about this HALT-skipping code, because as fate would have it, I inadvertently\n * stopped the following diagnostic with a breakpoint *on* a HALT instruction:\n *\n * .R EKBEE1\n * EKBEE1.BIC\n *\n * CEKBEE0 11/70 MEM MGMT\n *\n * CPU UNDER TEST FOUND TO BE A KB11-CM\n * bp 033330 hit\n * stopped (28339757 instructions, 123994176 cycles, 19177 ms, 6465775 hz)\n * R0=140000 R1=033330 R2=100143 R3=133260 R4=000000 R5=177700\n * SP=000600 PC=033330 PS=140000 IR=000000 SL=000377 T0 N0 Z0 V0 C0\n * 033330: 000000 HALT\n *\n * Since we haven't executed the HALT yet, it would be wrong (and would cause a diagnostic failure) to\n * skip over it. In this particular case, the PDR for the address of the HALT instruction was invalid,\n * so the HALT gets fetched but not executed.\n *\n * My first thought was that maybe we need to probe the address more thoroughly (getWordSafe() does\n * not), but it should be sufficient to simply confirm that the PC of the last opcode executed matches\n * the addr of this HALT.\n *\n * Yes, I could save myself this grief by eliminating these PC hacks, both here and in stopInstruction(),\n * but I still think it's a useful debugging aid.\n */\n if (opCode == PDP11.OPCODE.HALT && this.cpu.getLastPC() == addr) {\n addr = this.cpu.advancePC(2);\n }\n }\n\n /*\n * If the CPU stopped on a breakpoint, we're not interested in stopping again if the machine is starting.\n */\n if (nState > 0) {\n if (this.nBreakInstructions) {\n if (!--this.nBreakInstructions) return true;\n }\n if (this.checkBreakpoint(addr, 1, this.aBreakExec)) {\n return true;\n }\n }\n\n /*\n * The rest of the instruction tracking logic can only be performed if historyInit() has allocated the\n * necessary data structures. Note that there is no explicit UI for enabling/disabling history, other than\n * adding/removing breakpoints, simply because it's breakpoints that trigger the call to checkInstruction();\n * well, OK, and a few other things now, like enabling MessagesPDP11.INT messages.\n */\n if (nState >= 0 && this.aInstructionHistory.length) {\n this.cInstructions++;\n if (opCode < 0) {\n opCode = this.cpu.getWordSafe(addr);\n }\n if ((opCode & 0xffff) != PDP11.OPCODE.INVALID) {\n var dbgAddr = this.aInstructionHistory[this.iInstructionHistory];\n this.setAddr(dbgAddr, addr);\n // if (DEBUG) dbgAddr.cycleCount = cpu.getCycles();\n if (++this.iInstructionHistory == this.aInstructionHistory.length) this.iInstructionHistory = 0;\n }\n }\n return false;\n }\n\n /**\n * stopInstruction(sMessage)\n *\n * TODO: Currently, the only way to prevent this call from stopping the CPU is when you're single-stepping.\n *\n * @this {DebuggerPDP11}\n * @param {string} [sMessage]\n * @return {boolean} true if stopping is enabled, false if not\n */\n stopInstruction(sMessage)\n {\n var cpu = this.cpu;\n if (cpu.isRunning()) {\n cpu.setPC(this.cpu.getLastPC());\n if (sMessage) this.println(sMessage);\n this.stopCPU();\n /*\n * TODO: Review the appropriate-ness of throwing a bogus vector number in order to immediately stop\n * the instruction. It's handy, but it also means that we no longer actually return true, so callers\n * of either stopInstruction() or undefinedInstruction() may have unreachable code paths.\n */\n throw -1;\n }\n return false;\n }\n\n /**\n * undefinedInstruction(opCode)\n *\n * @this {DebuggerPDP11}\n * @param {number} opCode\n * @return {boolean} true if stopping is enabled, false if not\n */\n undefinedInstruction(opCode)\n {\n if (this.messageEnabled(MessagesPDP11.CPU)) {\n this.printMessage(\"undefined opcode \" + this.toStrBase(opCode), true, true);\n return this.stopInstruction(); // allow the caller to step over it if they really want a trap generated\n }\n return false;\n }\n\n /**\n * checkMemoryRead(addr, nb)\n *\n * This \"check\" function is called by a Memory block to inform us that a memory read occurred, giving us an\n * opportunity to track the read if we want, and look for a matching \"read\" breakpoint, if any.\n *\n * In the \"old days\", it would be an error for this call to fail to find a matching Debugger breakpoint, but now\n * Memory blocks have no idea whether the Debugger or the machine's Debug register(s) triggered this \"checked\" read.\n *\n * If we return true, we \"trump\" the machine's Debug register(s); false allows normal Debug register processing.\n *\n * @this {DebuggerPDP11}\n * @param {number} addr\n * @param {number} [nb] (# of bytes; default is 1)\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkMemoryRead(addr, nb)\n {\n if (this.checkBreakpoint(addr, nb || 1, this.aBreakRead)) {\n this.stopCPU(false);\n return true;\n }\n return false;\n }\n\n /**\n * checkMemoryWrite(addr, nb)\n *\n * This \"check\" function is called by a Memory block to inform us that a memory write occurred, giving us an\n * opportunity to track the write if we want, and look for a matching \"write\" breakpoint, if any.\n *\n * In the \"old days\", it would be an error for this call to fail to find a matching Debugger breakpoint, but now\n * Memory blocks have no idea whether the Debugger or the machine's Debug register(s) triggered this \"checked\" write.\n *\n * If we return true, we \"trump\" the machine's Debug register(s); false allows normal Debug register processing.\n *\n * @this {DebuggerPDP11}\n * @param {number} addr\n * @param {number} [nb] (# of bytes; default is 1)\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkMemoryWrite(addr, nb)\n {\n if (this.checkBreakpoint(addr, nb || 1, this.aBreakWrite)) {\n this.stopCPU(false);\n return true;\n }\n return false;\n }\n\n /**\n * clearBreakpoints()\n *\n * @this {DebuggerPDP11}\n */\n clearBreakpoints()\n {\n var i, dbgAddr, addr;\n this.aBreakExec = [\"bp\"];\n if (this.aBreakRead !== undefined) {\n for (i = 1; i < this.aBreakRead.length; i++) {\n dbgAddr = this.aBreakRead[i];\n addr = this.getAddr(dbgAddr);\n if (!dbgAddr.fPhysical) {\n this.cpu.removeMemBreak(addr, false);\n } else {\n this.bus.removeMemBreak(addr, false);\n }\n }\n }\n this.aBreakRead = [\"br\"];\n if (this.aBreakWrite !== undefined) {\n for (i = 1; i < this.aBreakWrite.length; i++) {\n dbgAddr = this.aBreakWrite[i];\n addr = this.getAddr(dbgAddr);\n if (!dbgAddr.fPhysical) {\n this.cpu.removeMemBreak(addr, true);\n } else {\n this.bus.removeMemBreak(addr, true);\n }\n }\n }\n this.aBreakWrite = [\"bw\"];\n /*\n * nSuppressBreaks ensures we can't get into an infinite loop where a breakpoint lookup\n * requires reading memory that triggers more memory reads, which triggers more breakpoint checks.\n */\n this.nSuppressBreaks = 0;\n this.nBreakInstructions = 0;\n }\n\n /**\n * addBreakpoint(aBreak, dbgAddr, fTemporary)\n *\n * In case you haven't already figured this out, all our breakpoint commands use the address\n * to identify a breakpoint, not an incrementally assigned breakpoint index like other debuggers;\n * see doBreak() for details.\n *\n * This has a few implications, one being that you CANNOT set more than one kind of breakpoint\n * on a single address. In practice, that's rarely a problem, because you can almost always set\n * a different breakpoint on a neighboring address.\n *\n * Also, there is one exception to the \"one address, one breakpoint\" rule, and that involves\n * temporary breakpoints (ie, one-time execution breakpoints that either a \"p\" or \"g\" command\n * may create to step over a chunk of code). Those breakpoints automatically clear themselves,\n * so there usually isn't any need to refer to them using breakpoint commands.\n *\n * TODO: Consider supporting the more \"traditional\" breakpoint index syntax; the current\n * address-based syntax was implemented solely for expediency and consistency. At the same time,\n * also consider a more WDEB386-like syntax, where \"br\" is used to set a variety of access-specific\n * breakpoints, using modifiers like \"r1\", \"r2\", \"w1\", \"w2, etc.\n *\n * @this {DebuggerPDP11}\n * @param {Array} aBreak\n * @param {DbgAddrPDP11} dbgAddr\n * @param {boolean} [fTemporary]\n * @return {boolean} true if breakpoint added, false if already exists\n */\n addBreakpoint(aBreak, dbgAddr, fTemporary)\n {\n var fSuccess = true;\n\n // this.nSuppressBreaks++;\n\n /*\n * Instead of complaining that a breakpoint already exists (as we used to do), we now\n * allow breakpoints to be re-set; this makes it easier to update any commands that may\n * be associated with the breakpoint.\n *\n * The only exception: we DO allow a temporary breakpoint at an address where there may\n * already be a breakpoint, so that you can easily step (\"p\" or \"g\") over such addresses.\n */\n if (!fTemporary) {\n this.findBreakpoint(aBreak, dbgAddr, true, false, true);\n }\n\n if (aBreak != this.aBreakExec) {\n var addr = this.getAddr(dbgAddr);\n if (addr === PDP11.ADDR_INVALID) {\n this.println(\"invalid address: \" + this.toStrAddr(dbgAddr));\n fSuccess = false;\n } else {\n var fWrite = (aBreak == this.aBreakWrite);\n /*\n * We automatically promote any read/write breakpoint address to fPhysical if it's\n * outside the 16-bit virtual address range.\n */\n if (addr > 0xffff) dbgAddr.fPhysical = true;\n if (!dbgAddr.fPhysical) {\n this.cpu.addMemBreak(addr, fWrite);\n } else {\n this.bus.addMemBreak(addr, fWrite);\n }\n }\n }\n\n if (fSuccess) {\n aBreak.push(dbgAddr);\n if (fTemporary) {\n dbgAddr.fTemporary = true;\n }\n else {\n this.printBreakpoint(aBreak, aBreak.length-1, \"set\");\n this.historyInit();\n }\n }\n\n // this.nSuppressBreaks--;\n\n return fSuccess;\n }\n\n /**\n * findBreakpoint(aBreak, dbgAddr, fRemove, fTemporary, fQuiet)\n *\n * @this {DebuggerPDP11}\n * @param {Array} aBreak\n * @param {DbgAddrPDP11} dbgAddr\n * @param {boolean} [fRemove]\n * @param {boolean} [fTemporary]\n * @param {boolean} [fQuiet]\n * @return {boolean} true if found, false if not\n */\n findBreakpoint(aBreak, dbgAddr, fRemove, fTemporary, fQuiet)\n {\n var fFound = false;\n var addr = this.getAddr(dbgAddr);\n for (var i = 1; i < aBreak.length; i++) {\n var dbgAddrBreak = aBreak[i];\n if (addr == this.getAddr(dbgAddrBreak)) {\n if (!fTemporary || dbgAddrBreak.fTemporary) {\n fFound = true;\n if (fRemove) {\n if (!dbgAddrBreak.fTemporary && !fQuiet) {\n this.printBreakpoint(aBreak, i, \"cleared\");\n }\n aBreak.splice(i, 1);\n if (aBreak != this.aBreakExec) {\n var fWrite = (aBreak == this.aBreakWrite);\n if (!dbgAddrBreak.fPhysical) {\n this.cpu.removeMemBreak(addr, fWrite);\n } else {\n this.bus.removeMemBreak(addr, fWrite);\n }\n }\n /*\n * We'll mirror the logic in addBreakpoint() and leave the history buffer alone if this\n * was a temporary breakpoint.\n */\n if (!dbgAddrBreak.fTemporary) {\n this.historyInit();\n }\n break;\n }\n if (!fQuiet) this.printBreakpoint(aBreak, i, \"exists\");\n break;\n }\n }\n }\n return fFound;\n }\n\n /**\n * listBreakpoints(aBreak)\n *\n * @this {DebuggerPDP11}\n * @param {Array} aBreak\n * @return {number} of breakpoints listed, 0 if none\n */\n listBreakpoints(aBreak)\n {\n for (var i = 1; i < aBreak.length; i++) {\n this.printBreakpoint(aBreak, i);\n }\n return aBreak.length - 1;\n }\n\n /**\n * printBreakpoint(aBreak, i, sAction)\n *\n * @this {DebuggerPDP11}\n * @param {Array} aBreak\n * @param {number} i\n * @param {string} [sAction]\n */\n printBreakpoint(aBreak, i, sAction)\n {\n var dbgAddr = aBreak[i];\n this.println(aBreak[0] + ' ' + this.toStrAddr(dbgAddr) + (sAction? (' ' + sAction) : (dbgAddr.sCmd? (' \"' + dbgAddr.sCmd + '\"') : '')));\n }\n\n /**\n * setTempBreakpoint(dbgAddr)\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr of new temp breakpoint\n */\n setTempBreakpoint(dbgAddr)\n {\n this.addBreakpoint(this.aBreakExec, dbgAddr, true);\n }\n\n /**\n * clearTempBreakpoint(addr)\n *\n * @this {DebuggerPDP11}\n * @param {number|undefined} [addr] clear all temp breakpoints if no address specified\n */\n clearTempBreakpoint(addr)\n {\n if (addr !== undefined) {\n this.checkBreakpoint(addr, 1, this.aBreakExec, true);\n this.nStep = 0;\n } else {\n for (var i = 1; i < this.aBreakExec.length; i++) {\n var dbgAddrBreak = this.aBreakExec[i];\n if (dbgAddrBreak.fTemporary) {\n if (!this.findBreakpoint(this.aBreakExec, dbgAddrBreak, true, true)) break;\n i = 0;\n }\n }\n }\n }\n\n /**\n * checkBreakpoint(addr, nb, aBreak, fTemporary)\n *\n * @this {DebuggerPDP11}\n * @param {number} addr\n * @param {number} nb (# of bytes)\n * @param {Array} aBreak\n * @param {boolean} [fTemporary]\n * @return {boolean} true if breakpoint has been hit, false if not\n */\n checkBreakpoint(addr, nb, aBreak, fTemporary)\n {\n /*\n * Time to check for breakpoints; note that this should be done BEFORE updating history data\n * (see checkInstruction), since we might not actually execute the current instruction.\n */\n var fBreak = false;\n\n if (!this.nSuppressBreaks++) {\n\n for (var i = 1; !fBreak && i < aBreak.length; i++) {\n\n var dbgAddrBreak = aBreak[i];\n\n if (fTemporary && !dbgAddrBreak.fTemporary) continue;\n\n /*\n * If we're checking an execution address, which is always virtual, and virtual\n * addresses are always restricted to 16 bits, let's mask the breakpoint address to match\n * (the user should know better, but we'll be nice).\n */\n var addrBreak = this.getAddr(dbgAddrBreak) & (aBreak == this.aBreakExec? 0xffff : -1);\n for (var n = 0; n < nb; n++) {\n\n if ((addr + n) != addrBreak) continue;\n\n var a;\n fBreak = true;\n if (dbgAddrBreak.fTemporary) {\n this.findBreakpoint(aBreak, dbgAddrBreak, true, true);\n fTemporary = true;\n }\n if (a = dbgAddrBreak.aCmds) {\n /*\n * When one or more commands are attached to a breakpoint, we don't halt by default.\n * Instead, we set fBreak to true only if, at the completion of all the commands, the\n * CPU is halted; in other words, you should include \"h\" as one of the breakpoint commands\n * if you want the breakpoint to stop execution.\n *\n * Another useful command is \"if\", which will return false if the expression is false,\n * at which point we'll jump ahead to the next \"else\" command, and if there isn't an \"else\",\n * we abort.\n */\n fBreak = false;\n for (var j = 0; j < a.length; j++) {\n if (!this.doCommand(a[j], true)) {\n if (a[j].indexOf(\"if\")) {\n fBreak = true; // the failed command wasn't \"if\", so abort\n break;\n }\n var k = j + 1;\n for (; k < a.length; k++) {\n if (!a[k].indexOf(\"else\")) break;\n j++;\n }\n if (k == a.length) { // couldn't find an \"else\" after the \"if\", so abort\n fBreak = true;\n break;\n }\n /*\n * If we're still here, we'll execute the \"else\" command (which is just a no-op),\n * followed by any remaining commands.\n */\n }\n }\n if (!this.cpu.isRunning()) fBreak = true;\n }\n if (fBreak) {\n if (!fTemporary) this.printBreakpoint(aBreak, i, \"hit\");\n break;\n }\n }\n }\n }\n\n this.nSuppressBreaks--;\n\n return fBreak;\n }\n\n /**\n * getInstruction(dbgAddr, sComment, nSequence)\n *\n * Get the next instruction, by decoding the opcode and any operands.\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @param {string} [sComment] is an associated comment\n * @param {number|null} [nSequence] is an associated sequence number, undefined if none\n * @return {string} (and dbgAddr is updated to the next instruction)\n */\n getInstruction(dbgAddr, sComment, nSequence)\n {\n var opNames = DebuggerPDP11.OPNAMES;\n var dbgAddrOp = this.newAddr(dbgAddr.addr);\n var opCode = this.getWord(dbgAddr, 2);\n\n var opDesc;\n for (var mask in this.opTable) {\n var opMasks = this.opTable[mask];\n opDesc = opMasks[opCode & mask];\n if (opDesc) break;\n }\n\n if (!opDesc) {\n opDesc = DebuggerPDP11.OPNONE;\n }\n\n var opNum = opDesc[0];\n if (this.aOpReserved.indexOf(opNum) >= 0) {\n opDesc = DebuggerPDP11.OPNONE;\n opNum = opDesc[0];\n }\n\n var sOperands = \"\", sTarget = \"\";\n var sOpName = opNames[opNum];\n var cOperands = opDesc.length - 1;\n\n if (!opNum && !cOperands) {\n sOperands = this.toStrBase(opCode);\n }\n\n for (var iOperand = 1; iOperand <= cOperands; iOperand++) {\n\n var opType = opDesc[iOperand];\n if (opType === undefined) continue;\n\n var sOperand = this.getOperand(opCode, opType, dbgAddr);\n\n if (!sOperand || !sOperand.length) {\n sOperands = \"INVALID\";\n break;\n }\n\n /*\n * If getOperand() returns an Array rather than a string, then the first element is the original\n * operand, and the second element contains additional information (eg, the target) of the operand.\n */\n if (typeof sOperand != \"string\") {\n sTarget = sOperand[1];\n sOperand = sOperand[0];\n }\n\n if (sOperands.length > 0) sOperands += ',';\n sOperands += (sOperand || \"???\");\n }\n\n var sOpCodes = \"\";\n var sLine = this.toStrAddr(dbgAddrOp) + \":\";\n if (dbgAddrOp.addr !== PDP11.ADDR_INVALID && dbgAddr.addr !== PDP11.ADDR_INVALID) {\n do {\n sOpCodes += ' ' + this.toStrBase(this.getWord(dbgAddrOp, 2));\n if (dbgAddrOp.addr == null) break;\n } while (dbgAddrOp.addr != dbgAddr.addr);\n }\n\n sLine += Str.pad(sOpCodes, 24);\n sLine += Str.pad(sOpName, 5);\n if (sOperands) sLine += ' ' + sOperands;\n\n if (sComment || sTarget) {\n sLine = Str.pad(sLine, 60) + ';' + (sComment || \"\");\n if (!this.cpu.flags.checksum) {\n sLine += (nSequence != null? '=' + nSequence.toString() : \"\");\n } else {\n var nCycles = this.cpu.getCycles();\n sLine += \"cycles=\" + nCycles.toString() + \" cs=\" + Str.toHex(this.cpu.nChecksum);\n }\n if (sTarget) {\n if (sLine.slice(-1) != ';') sLine += ' ';\n sLine += sTarget;\n }\n }\n return sLine;\n }\n\n /**\n * getOperand(opCode, opType, dbgAddr)\n *\n * If getOperand() returns an Array rather than a string, then the first element is the original\n * operand, and the second element is a comment containing additional information (eg, the target)\n * of the operand.\n *\n * @this {DebuggerPDP11}\n * @param {number} opCode\n * @param {number} opType\n * @param {DbgAddrPDP11} dbgAddr\n * @return {string|Array.<string>}\n */\n getOperand(opCode, opType, dbgAddr)\n {\n var sOperand = \"\", disp, addr;\n /*\n * Take care of OP_OTHER opcodes first; then all we'll have to worry about\n * next are OP_SRC or OP_DST opcodes.\n */\n var opTypeOther = opType & DebuggerPDP11.OP_OTHER;\n if (opTypeOther == DebuggerPDP11.OP_BRANCH) {\n disp = ((opCode & 0xff) << 24) >> 23;\n addr = (dbgAddr.addr + disp) & 0xffff;\n sOperand = this.toStrBase(addr);\n }\n else if (opTypeOther == DebuggerPDP11.OP_DSTOFF) {\n disp = (opCode & 0x3f) << 1;\n addr = (dbgAddr.addr - disp) & 0xffff;\n sOperand = this.toStrBase(addr);\n }\n else if (opTypeOther == DebuggerPDP11.OP_DSTNUM3) {\n disp = (opCode & 0x07);\n sOperand = this.toStrBase(disp, 3);\n }\n else if (opTypeOther == DebuggerPDP11.OP_DSTNUM6) {\n disp = (opCode & 0x3f);\n sOperand = this.toStrBase(disp, 6);\n }\n else if (opTypeOther == DebuggerPDP11.OP_DSTNUM8) {\n disp = (opCode & 0xff);\n sOperand = this.toStrBase(disp, 8);\n }\n else {\n /*\n * Isolate all OP_SRC or OP_DST bits from opcode in the opMode variable.\n */\n var opMode = opCode & opType;\n\n /*\n * Convert OP_SRC bits into OP_DST bits, since they use the same format.\n */\n if (opType & DebuggerPDP11.OP_SRC) {\n opMode >>= 6;\n opType >>= 6;\n }\n if (opType & DebuggerPDP11.OP_DST) {\n var wIndex;\n var sTarget = null;\n var reg = opMode & DebuggerPDP11.OP_DSTREG;\n /*\n * Note that opcodes that specify only REG bits in the opType mask (ie, no MOD bits)\n * will automatically default to OPMODE_REG below.\n */\n switch((opMode & DebuggerPDP11.OP_DSTMODE)) {\n\n case PDP11.OPMODE.REG: // 0x0: REGISTER\n sOperand = this.getRegName(reg);\n break;\n\n case PDP11.OPMODE.REGD: // 0x1: REGISTER DEFERRED\n sOperand = '@' + this.getRegName(reg);\n sTarget = this.getTarget(this.cpu.regsGen[reg]);\n break;\n\n case PDP11.OPMODE.POSTINC: // 0x2: POST-INCREMENT\n if (reg < 7) {\n sOperand = '(' + this.getRegName(reg) + \")+\";\n } else {\n /*\n * When using R7 (aka PC), POST-INCREMENT is known as IMMEDIATE\n */\n wIndex = this.getWord(dbgAddr, 2);\n sOperand = '#' + this.toStrBase(wIndex, -1);\n }\n break;\n\n case PDP11.OPMODE.POSTINCD: // 0x3: POST-INCREMENT DEFERRED\n if (reg < 7) {\n sOperand = \"@(\" + this.getRegName(reg) + \")+\";\n } else {\n /*\n * When using R7 (aka PC), POST-INCREMENT DEFERRED is known as ABSOLUTE\n */\n wIndex = this.getWord(dbgAddr, 2);\n sOperand = \"@#\" + this.toStrBase(wIndex, -1);\n sTarget = this.getTarget(wIndex);\n }\n break;\n\n case PDP11.OPMODE.PREDEC: // 0x4: PRE-DECREMENT\n sOperand = \"-(\" + this.getRegName(reg) + \")\";\n break;\n\n case PDP11.OPMODE.PREDECD: // 0x5: PRE-DECREMENT DEFERRED\n sOperand = \"@-(\" + this.getRegName(reg) + \")\";\n break;\n\n case PDP11.OPMODE.INDEX: // 0x6: INDEX\n wIndex = this.getWord(dbgAddr, 2);\n sOperand = this.toStrBase(wIndex, -1) + '(' + this.getRegName(reg) + ')';\n if (reg == 7) {\n /*\n * When using R7 (aka PC), INDEX is known as RELATIVE. However, instead of displaying\n * such an instruction like this:\n *\n * 016156: 010167 001300 MOV R1,1300(PC) ; @017462\n *\n * with the effective address display to the far right, let's display it like this instead:\n *\n * 016156: 010167 001300 MOV R1,017462\n *\n * because you can still clearly see PC-relative offset (eg, 001300) as part of the disassembly.\n *\n * sOperand = [sOperand, this.toStrBase((wIndex + dbgAddr.addr) & 0xffff)];\n */\n sOperand = this.toStrBase(wIndex = (wIndex + dbgAddr.addr) & 0xffff);\n sTarget = this.getTarget(wIndex);\n }\n break;\n\n case PDP11.OPMODE.INDEXD: // 0x7: INDEX DEFERRED\n wIndex = this.getWord(dbgAddr, 2);\n sOperand = '@' + this.toStrBase(wIndex) + '(' + this.getRegName(reg) + ')';\n if (reg == 7) {\n /*\n * When using R7 (aka PC), INDEX DEFERRED is known as RELATIVE DEFERRED. And for the same\n * reasons articulated above, we now display the effective address inline.\n *\n * sOperand = [sOperand, this.toStrBase((wIndex + dbgAddr.addr) & 0xffff)];\n */\n sOperand = '@' + this.toStrBase(wIndex = (wIndex + dbgAddr.addr) & 0xffff);\n sTarget = this.getTarget(this.cpu.getWordSafe(wIndex));\n }\n break;\n\n default:\n\n break;\n }\n\n if (sTarget) sOperand = [sOperand, sTarget];\n }\n else {\n\n }\n }\n return sOperand;\n }\n\n /**\n * getTarget(addr)\n *\n * @this {DebuggerPDP11}\n * @param {number} addr\n * @return {string|null}\n */\n getTarget(addr)\n {\n var sTarget = null;\n var a = this.cpu.getAddrInfo(addr);\n var addrPhysical = a[0];\n if (addrPhysical >= this.cpu.addrIOPage && addrPhysical < this.bus.addrIOPage) {\n addrPhysical = (addrPhysical - this.cpu.addrIOPage) + this.bus.addrIOPage;\n }\n return this.bus.getAddrInfo(addrPhysical);\n }\n\n /**\n * parseInstruction(sOp, sOperand, addr)\n *\n * TODO: Unimplemented. See parseInstruction() in modules/c1pjs/lib/debugger.js for a sample implementation.\n *\n * @this {DebuggerPDP11}\n * @param {string} sOp\n * @param {string|undefined} sOperand\n * @param {DbgAddrPDP11} dbgAddr of memory where this instruction is being assembled\n * @return {Array.<number>} of opcode bytes; if the instruction can't be parsed, the array will be empty\n */\n parseInstruction(sOp, sOperand, dbgAddr)\n {\n var aOpBytes = [];\n this.println(\"not supported yet\");\n return aOpBytes;\n }\n\n /**\n * getFlagOutput(sFlag)\n *\n * @this {DebuggerPDP11}\n * @param {string} sFlag\n * @return {string} value of flag\n */\n getFlagOutput(sFlag)\n {\n var b;\n switch (sFlag) {\n case 'N':\n b = this.cpu.getNF();\n break;\n case 'Z':\n b = this.cpu.getZF();\n break;\n case 'V':\n b = this.cpu.getVF();\n break;\n case 'C':\n b = this.cpu.getCF();\n break;\n default:\n b = 0;\n break;\n }\n return sFlag.charAt(0) + (b? '1' : '0') + ' ';\n }\n\n /**\n * getRegOutput(iReg)\n *\n * @this {DebuggerPDP11}\n * @param {number} iReg\n * @return {string}\n */\n getRegOutput(iReg)\n {\n var sReg = this.getRegName(iReg);\n if (sReg) {\n sReg += '=' + this.toStrBase(this.getRegValue(iReg)) + ' ';\n }\n return sReg;\n }\n\n /**\n * getMiscDump()\n *\n * Sample register dump:\n *\n * M0=xxxxxx M1=xxxxxx M2=xxxxxx M3=xxxxxx ER=xxxxxx\n *\n * @this {DebuggerPDP11}\n * @return {string}\n */\n getMiscDump()\n {\n var sDump = \"\";\n sDump += this.getRegOutput(DebuggerPDP11.REG_M0) + this.getRegOutput(DebuggerPDP11.REG_M1);\n sDump += this.getRegOutput(DebuggerPDP11.REG_M2) + this.getRegOutput(DebuggerPDP11.REG_M3) + this.getRegOutput(DebuggerPDP11.REG_ER);\n sDump += '\\n';\n sDump += this.getRegOutput(DebuggerPDP11.REG_SR) + this.getRegOutput(DebuggerPDP11.REG_AR) + this.getRegOutput(DebuggerPDP11.REG_DR);\n return sDump;\n }\n\n /**\n * getRegDump(fMisc)\n *\n * Sample register dump:\n *\n * R0=xxxxxx R1=xxxxxx R2=xxxxxx R3=xxxxxx R4=xxxxxx R5=xxxxxx\n * SP=xxxxxx PC=xxxxxx PS=xxxxxx PI=xxxxxx SL=xxxxxx T0 N0 Z0 V0 C0\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fMisc] (true to include misc registers)\n * @return {string}\n */\n getRegDump(fMisc)\n {\n var i;\n var sDump = \"\";\n for (i = 0; i < PDP11.REG.SP; i++) {\n sDump += this.getRegOutput(i);\n }\n sDump += '\\n';\n sDump += this.getRegOutput(PDP11.REG.SP) + this.getRegOutput(PDP11.REG.PC);\n sDump += this.getRegOutput(DebuggerPDP11.REG_PS) + this.getRegOutput(DebuggerPDP11.REG_PI) + this.getRegOutput(DebuggerPDP11.REG_SL);\n sDump += this.getFlagOutput('T') + this.getFlagOutput('N') + this.getFlagOutput('Z') + this.getFlagOutput('V') + this.getFlagOutput('C');\n if (fMisc) sDump += '\\n' + this.getMiscDump();\n return sDump;\n }\n\n /**\n * comparePairs(p1, p2)\n *\n * @this {DebuggerPDP11}\n * @param {number|string|Array|Object} p1\n * @param {number|string|Array|Object} p2\n * @return {number}\n */\n comparePairs(p1, p2)\n {\n return p1[0] > p2[0]? 1 : p1[0] < p2[0]? -1 : 0;\n }\n\n /**\n * addSymbols(sModule, addr, len, aSymbols)\n *\n * As filedump.js (formerly convrom.php) explains, aSymbols is a JSON-encoded object whose properties consist\n * of all the symbols (in upper-case), and the values of those properties are objects containing any or all of\n * the following properties:\n *\n * 'v': the value of an absolute (unsized) value\n * 'b': either 1, 2, 4 or undefined if an unsized value\n * 's': either a hard-coded segment or undefined\n * 'o': the offset of the symbol within the associated address space\n * 'l': the original-case version of the symbol, present only if it wasn't originally upper-case\n * 'a': annotation for the specified offset; eg, the original assembly language, with optional comment\n *\n * To that list of properties, we also add:\n *\n * 'p': the physical address (calculated whenever both 's' and 'o' properties are defined)\n *\n * Note that values for any 'v', 'b', 's' and 'o' properties are unquoted decimal values, and the values\n * for any 'l' or 'a' properties are quoted strings. Also, if double-quotes were used in any of the original\n * annotation ('a') values, they will have been converted to two single-quotes, so we're responsible for\n * converting them back to individual double-quotes.\n *\n * For example:\n * {\n * 'HF_PORT': {\n * 'v':800\n * },\n * 'HDISK_INT': {\n * 'b':4, 's':0, 'o':52\n * },\n * 'ORG_VECTOR': {\n * 'b':4, 's':0, 'o':76\n * },\n * 'CMD_BLOCK': {\n * 'b':1, 's':64, 'o':66\n * },\n * 'DISK_SETUP': {\n * 'o':3\n * },\n * '.40': {\n * 'o':40, 'a':\"MOV AX,WORD PTR ORG_VECTOR ;GET DISKETTE VECTOR\"\n * }\n * }\n *\n * If a symbol only has an offset, then that offset value can be assigned to the symbol property directly:\n *\n * 'DISK_SETUP': 3\n *\n * The last property is an example of an \"anonymous\" entry, for offsets where there is no associated symbol.\n * Such entries are identified by a period followed by a unique number (usually the offset of the entry), and\n * they usually only contain offset ('o') and annotation ('a') properties. I could eliminate the leading\n * period, but it offers a very convenient way of quickly discriminating among genuine vs. anonymous symbols.\n *\n * We add all these entries to our internal symbol table, which is an array of 4-element arrays, each of which\n * look like:\n *\n * [addr, len, aSymbols, aOffsets]\n *\n * There are two basic symbol operations: findSymbol(), which takes an address and finds the symbol, if any,\n * at that address, and findSymbolAddr(), which takes a string and attempts to match it to a non-anonymous\n * symbol with a matching offset ('o') property.\n *\n * To implement findSymbol() efficiently, addSymbols() creates an array of [offset, sSymbol] pairs\n * (aOffsets), one pair for each symbol that corresponds to an offset within the specified address space.\n *\n * We guarantee the elements of aOffsets are in offset order, because we build it using binaryInsert();\n * it's quite likely that the MAP file already ordered all its symbols in offset order, but since they're\n * hand-edited files, we can't assume that, and we need to ensure that findSymbol()'s binarySearch() operates\n * properly.\n *\n * @this {DebuggerPDP11}\n * @param {string|null} sModule\n * @param {number|null} addr (physical address where the symbols are located, if the memory is physical; eg, ROM)\n * @param {number} len (the size of the region, in bytes)\n * @param {Object} aSymbols (collection of symbols in this group; the format of this collection is described below)\n */\n addSymbols(sModule, addr, len, aSymbols)\n {\n var dbgAddr = {};\n var aOffsets = [];\n for (var sSymbol in aSymbols) {\n var symbol = aSymbols[sSymbol];\n if (typeof symbol == \"number\") {\n aSymbols[sSymbol] = symbol = {'o': symbol};\n }\n var offSymbol = symbol['o'];\n var sAnnotation = symbol['a'];\n if (offSymbol !== undefined) {\n Usr.binaryInsert(aOffsets, [offSymbol >>> 0, sSymbol], this.comparePairs);\n }\n if (sAnnotation) symbol['a'] = sAnnotation.replace(/''/g, \"\\\"\");\n }\n var symbolTable = {\n sModule: sModule,\n addr: addr,\n len: len,\n aSymbols: aSymbols,\n aOffsets: aOffsets\n };\n this.aSymbolTable.push(symbolTable);\n }\n\n /**\n * dumpSymbols()\n *\n * TODO: Add \"numerical\" and \"alphabetical\" dump options. This is simply dumping them in whatever\n * order they appeared in the original MAP file.\n *\n * @this {DebuggerPDP11}\n */\n dumpSymbols()\n {\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n for (var sSymbol in symbolTable.aSymbols) {\n if (sSymbol.charAt(0) == '.') continue;\n var symbol = symbolTable.aSymbols[sSymbol];\n var offSymbol = symbol['o'];\n if (offSymbol === undefined) continue;\n var sSymbolOrig = symbolTable.aSymbols[sSymbol]['l'];\n if (sSymbolOrig) sSymbol = sSymbolOrig;\n this.println(this.toStrOffset(offSymbol) + ' ' + sSymbol);\n }\n }\n }\n\n /**\n * findSymbol(dbgAddr, fNearest)\n *\n * Search aSymbolTable for dbgAddr, and return an Array for the corresponding symbol (empty if not found).\n *\n * If fNearest is true, and no exact match was found, then the Array returned will contain TWO sets of\n * entries: [0]-[3] will refer to closest preceding symbol, and [4]-[7] will refer to the closest subsequent symbol.\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @param {boolean} [fNearest]\n * @return {Array} where [0] == symbol name, [1] == symbol value, [2] == any annotation, and [3] == any associated comment\n */\n findSymbol(dbgAddr, fNearest)\n {\n var aSymbol = [];\n var addrSymbol = this.getAddr(dbgAddr) >>> 0;\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n var addr = symbolTable.addr >>> 0;\n var len = symbolTable.len;\n if (addrSymbol >= addr && addrSymbol < addr + len) {\n var offSymbol = addrSymbol - addr;\n var result = Usr.binarySearch(symbolTable.aOffsets, [offSymbol], this.comparePairs);\n if (result >= 0) {\n this.returnSymbol(iTable, result, aSymbol);\n }\n else if (fNearest) {\n result = ~result;\n this.returnSymbol(iTable, result-1, aSymbol);\n this.returnSymbol(iTable, result, aSymbol);\n }\n break;\n }\n }\n return aSymbol;\n }\n\n /**\n * findSymbolAddr(sSymbol)\n *\n * Search our symbol tables for sSymbol, and if found, return a dbgAddr (same as parseAddr()).\n *\n * @this {DebuggerPDP11}\n * @param {string} sSymbol\n * @return {DbgAddrPDP11|undefined}\n */\n findSymbolAddr(sSymbol)\n {\n var dbgAddr;\n var offSymbol = this.bus.getAddrByName(sSymbol);\n\n if (offSymbol == null && sSymbol.match(/^[a-z_][a-z0-9_]*$/i)) {\n var sUpperCase = sSymbol.toUpperCase();\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n var symbol = symbolTable.aSymbols[sUpperCase];\n if (symbol != null) {\n offSymbol = symbol['o'];\n /*\n * If the symbol matched but there's no 'o' offset (ie, it wasn't for an address), there's\n * no point looking any farther, since each symbol appears only once.\n *\n * NOTE: We assume that every ROM is ORG'ed at 0x0000, and therefore unless the symbol has an\n * explicitly-defined segment, we return the segment associated with the entire group; for a ROM,\n * that segment is normally \"addrROM >>> 4\". Down the road, we may want/need to support a special\n * symbol entry (eg, \".ORG\") that defines an alternate origin.\n */\n break;\n }\n }\n }\n if (offSymbol != null) {\n dbgAddr = this.newAddr(offSymbol);\n }\n return dbgAddr;\n }\n\n /**\n * returnSymbol(iTable, iOffset, aSymbol)\n *\n * Helper function for findSymbol().\n *\n * @param {number} iTable\n * @param {number} iOffset\n * @param {Array} aSymbol is updated with the specified symbol, if it exists\n */\n returnSymbol(iTable, iOffset, aSymbol)\n {\n var symbol = {};\n var aOffsets = this.aSymbolTable[iTable].aOffsets;\n var offset = 0, sSymbol = null;\n if (iOffset >= 0 && iOffset < aOffsets.length) {\n offset = aOffsets[iOffset][0];\n sSymbol = aOffsets[iOffset][1];\n }\n if (sSymbol) {\n symbol = this.aSymbolTable[iTable].aSymbols[sSymbol];\n sSymbol = (sSymbol.charAt(0) == '.'? null : (symbol['l'] || sSymbol));\n }\n aSymbol.push(sSymbol);\n aSymbol.push(offset);\n aSymbol.push(symbol['a']);\n aSymbol.push(symbol['c']);\n }\n\n /**\n * doHelp()\n *\n * @this {DebuggerPDP11}\n */\n doHelp()\n {\n var s = \"commands:\";\n for (var sCommand in DebuggerPDP11.COMMANDS) {\n s += '\\n' + Str.pad(sCommand, 9) + DebuggerPDP11.COMMANDS[sCommand];\n }\n if (!this.checksEnabled()) s += \"\\nnote: history disabled if no exec breakpoints\";\n this.println(s);\n }\n\n /**\n * doAssemble(asArgs)\n *\n * This always receives the complete argument array, where the order of the arguments is:\n *\n * [0]: the assemble command (assumed to be \"a\")\n * [1]: the target address (eg, \"200\")\n * [2]: the operation code, aka instruction name (eg, \"adc\")\n * [3]: the operation mode operand, if any (eg, \"14\", \"[1234]\", etc)\n *\n * The Debugger enters \"assemble mode\" whenever only the first (or first and second) arguments are present.\n * As long as \"assemble mode is active, the user can omit the first two arguments on all later assemble commands\n * until \"assemble mode\" is cancelled with an empty command line; the command processor automatically prepends \"a\"\n * and the next available target address to the argument array.\n *\n * Entering \"assemble mode\" is optional; one could enter a series of fully-qualified assemble commands; eg:\n *\n * a ff00 cld\n * a ff01 ldx 28\n * ...\n *\n * without ever entering \"assemble mode\", but of course, that requires more typing and doesn't take advantage\n * of automatic target address advancement (see dbgAddrAssemble).\n *\n * NOTE: As the previous example implies, you can even assemble new instructions into ROM address space;\n * as our setByte() function explains, the ROM write-notification handlers only refuse writes from the CPU.\n *\n * @this {DebuggerPDP11}\n * @param {Array.<string>} asArgs is the complete argument array, beginning with the \"a\" command in asArgs[0]\n */\n doAssemble(asArgs)\n {\n var dbgAddr = this.parseAddr(asArgs[1], true);\n if (!dbgAddr) return;\n\n this.dbgAddrAssemble = dbgAddr;\n if (asArgs[2] === undefined) {\n this.println(\"begin assemble at \" + this.toStrAddr(dbgAddr));\n this.fAssemble = true;\n this.cmp.updateDisplays();\n return;\n }\n\n var aOpBytes = this.parseInstruction(asArgs[2], asArgs[3], dbgAddr);\n if (aOpBytes.length) {\n for (var i = 0; i < aOpBytes.length; i++) {\n this.setByte(dbgAddr, aOpBytes[i], 1);\n }\n /*\n * Since getInstruction() also updates the specified address, dbgAddrAssemble is automatically advanced.\n */\n this.println(this.getInstruction(this.dbgAddrAssemble));\n }\n }\n\n /**\n * doBreak(sCmd, sAddr, sOptions)\n *\n * As the \"help\" output below indicates, the following breakpoint commands are supported:\n *\n * bp # set exec breakpoint\n * br # set read breakpoint\n * bw # set write breakpoint\n * bc # clear breakpoint (* to clear all)\n * bl list all breakpoints\n * bn [#] break after # instruction(s)\n *\n * The \"bn\" command, like the \"dh\" command and all other commands that use an instruction count,\n * assumes a decimal value, regardless of the current base. Use \"bn\" without an argument to display\n * the break count, and use \"bn 0\" to clear the break count.\n *\n * @this {DebuggerPDP11}\n * @param {string} sCmd\n * @param {string|undefined} [sAddr]\n * @param {string} [sOptions] (the rest of the breakpoint command-line)\n */\n doBreak(sCmd, sAddr, sOptions)\n {\n if (sAddr == '?') {\n this.println(\"breakpoint commands:\");\n this.println(\"\\tbp #\\tset exec breakpoint\");\n this.println(\"\\tbr #\\tset read breakpoint\");\n this.println(\"\\tbw #\\tset write breakpoint\");\n this.println(\"\\tbc #\\tclear breakpoint (* to clear all)\");\n this.println(\"\\tbl\\tlist all breakpoints\");\n this.println(\"\\tbn [#]\\tbreak after # instruction(s)\");\n return;\n }\n\n var sParm = sCmd.charAt(1);\n if (sParm == 'l') {\n var cBreaks = 0;\n cBreaks += this.listBreakpoints(this.aBreakExec);\n cBreaks += this.listBreakpoints(this.aBreakRead);\n cBreaks += this.listBreakpoints(this.aBreakWrite);\n if (!cBreaks) this.println(\"no breakpoints\");\n return;\n }\n\n if (sParm == 'n') {\n var n = +sAddr || 0;\n if (sAddr) this.nBreakInstructions = n;\n this.println(\"break after \" + n + \" instruction(s)\");\n return;\n }\n\n if (sAddr === undefined) {\n this.println(\"missing breakpoint address\");\n return;\n }\n\n var dbgAddr = this.newAddr();\n if (sAddr != '*') {\n dbgAddr = this.parseAddr(sAddr, true, true);\n if (!dbgAddr) return;\n }\n\n if (sParm == 'c') {\n if (dbgAddr.addr == null) {\n this.clearBreakpoints();\n this.println(\"all breakpoints cleared\");\n return;\n }\n if (this.findBreakpoint(this.aBreakExec, dbgAddr, true))\n return;\n if (this.findBreakpoint(this.aBreakRead, dbgAddr, true))\n return;\n if (this.findBreakpoint(this.aBreakWrite, dbgAddr, true))\n return;\n this.println(\"breakpoint missing: \" + this.toStrAddr(dbgAddr));\n return;\n }\n\n if (dbgAddr.addr == null) return;\n\n this.parseAddrOptions(dbgAddr, sOptions);\n\n if (sParm == 'p') {\n this.addBreakpoint(this.aBreakExec, dbgAddr);\n return;\n }\n if (sParm == 'r') {\n this.addBreakpoint(this.aBreakRead, dbgAddr);\n return;\n }\n if (sParm == 'w') {\n this.addBreakpoint(this.aBreakWrite, dbgAddr);\n return;\n }\n this.println(\"unknown breakpoint command: \" + sParm);\n }\n\n /**\n * doClear(sCmd)\n *\n * @this {DebuggerPDP11}\n * @param {string} [sCmd] (eg, \"cls\" or \"clear\")\n */\n doClear(sCmd)\n {\n this.cmp.clearPanel();\n }\n\n /**\n * doDump(asArgs)\n *\n * The length parameter is interpreted as a number of bytes (or words, or dwords) to dump,\n * and it is interpreted using the current base.\n *\n * @this {DebuggerPDP11}\n * @param {Array.<string>} asArgs (formerly sCmd, [sAddr], [sLen] and [sBytes])\n */\n doDump(asArgs)\n {\n var m;\n var sCmd = asArgs[0];\n var sAddr = asArgs[1];\n var sLen = asArgs[2];\n var sBytes = asArgs[3];\n\n if (sAddr == '?') {\n var sDumpers = \"\";\n for (m in MessagesPDP11.CATEGORIES) {\n if (this.afnDumpers[m]) {\n if (sDumpers) sDumpers += ',';\n sDumpers += m;\n }\n }\n sDumpers += \",state,symbols\";\n this.println(\"dump memory commands:\");\n this.println(\"\\tda [a] dump info for address a\");\n this.println(\"\\tdb [a] [n] dump n bytes at address a\");\n this.println(\"\\tdw [a] [n] dump n words at address a\");\n this.println(\"\\tdd [a] [n] dump n dwords at address a\");\n this.println(\"\\tds [a] [n] dump n words at address a as JSON\");\n this.println(\"\\tdh [p] [n] dump n instructions from history position p\");\n if (sDumpers.length) this.println(\"dump extension commands:\\n\\t\" + sDumpers);\n return;\n }\n\n if (sAddr == \"state\") {\n var sState = this.cmp.powerOff(true);\n if (sLen == \"console\") {\n /*\n * Console buffers are notoriously small, and even the following code, which breaks the\n * data into parts (eg, \"d state console 1\", \"d state console 2\", etc) just isn't that helpful.\n *\n * var nPart = +sBytes;\n * if (nPart) sState = sState.substr(1000000 * (nPart-1), 1000000);\n *\n * So, the best way to capture a large machine state is to use the new \"Save Machine\" link\n * that downloads a machine's entire state. Alternatively, run your own local server and use\n * server-side storage. Take a look at the \"Save\" binding in computer.js, which binds an HTML\n * control to the computer.powerOff() and computer.saveServerState() functions.\n */\n console.log(sState);\n } else {\n this.doClear();\n if (sState) this.println(sState);\n }\n return;\n }\n\n if (sAddr == \"symbols\") {\n this.dumpSymbols();\n return;\n }\n\n if (sCmd == \"d\") {\n for (m in MessagesPDP11.CATEGORIES) {\n if (asArgs[1] == m) {\n var fnDumper = this.afnDumpers[m];\n if (fnDumper) {\n asArgs.shift();\n asArgs.shift();\n fnDumper(asArgs);\n } else {\n this.println(\"no dump registered for \" + sAddr);\n }\n return;\n }\n }\n if (!sAddr) sCmd = this.sCmdDumpPrev || \"dw\";\n } else {\n this.sCmdDumpPrev = sCmd;\n }\n\n if (sCmd == \"dh\") {\n this.dumpHistory(sAddr, sLen);\n return;\n }\n\n var dbgAddr = this.parseAddr(sAddr);\n if (!dbgAddr) return;\n\n if (sCmd == \"da\") {\n /*\n * Sample output for a virtual address (\"da 23042\"):\n *\n * 00,010,011,000,100,010 00023042\n * OFFSET: 0,011,000,100,010 00003042\n * + KIPAR1: 0,000,001,101,111,010,000,000 00157200\n * & MMUMASK: 1,111,111,111,111,111,111,111 17777777\n * = PHYSICAL: 0,000,001,110,010,010,100,010 00162242\n *\n * and sample output for a physical address (eg, \"da %37772\"; note the % prefix):\n *\n * 0,000,000,011,111,111,111,010 00037772\n * OFFSET: 1,111,111,111,010 00017772\n * UNIMAP[01]: 1,111,100,001,110,111,000,000 17416700\n * PHYSICAL: 1,111,100,011,110,110,111,010 17436672\n *\n * TODO: Tweak this output to accommodate 18-bit machines as well as 22-bit machines.\n */\n var fPhysical = (dbgAddr.fPhysical || dbgAddr.addr > 0xffff);\n var a = this.cpu.getAddrInfo(dbgAddr.addr || 0, fPhysical);\n this.println(Str.pad(\"\", fPhysical? 12: 19) + Str.toBin(dbgAddr.addr, fPhysical? 22 : 17, 3) + \" \" + Str.toOct(dbgAddr.addr, 8));\n if (a.length < 6) {\n if (a.length > 2) {\n this.println(\" OFFSET: \" + Str.toBin(a[3], 13, 3) + \" \" + Str.toOct(a[3], 8));\n this.println(\"UNIMAP[\" + Str.toDec(a[1], 2) + \"]: \" + Str.toBin(a[2], 22, 3) + \" \" + Str.toOct(a[2], 8));\n }\n this.println(\" PHYSICAL: \" + Str.toBin(a[0], 22, 3) + \" \" + Str.toOct(a[0], 8))\n } else {\n this.println(\" OFFSET: \" + Str.toBin(a[1], 13, 3) + \" \" + Str.toOct(a[1], 8));\n this.println(\"+ \" + DebuggerPDP11.MODES[a[2]] + \"PAR\" + a[3] + \": \" + Str.toBin(a[4], 22, 3) + \" \" + Str.toOct(a[4], 8));\n this.println(\"& MMUMASK: \" + Str.toBin(a[5], 22, 3) + \" \" + Str.toOct(a[5], 8));\n this.println(\"= PHYSICAL: \" + Str.toBin(a[0], 22, 3) + \" \" + Str.toOct(a[0], 8))\n }\n return;\n }\n\n var len = 0;\n var fJSON = (sCmd == \"ds\");\n\n if (sLen) {\n if (sLen.charAt(0) == 'l') {\n sLen = sLen.substr(1) || sBytes;\n len = this.parseValue(sLen);\n }\n else {\n var dbgAddrEnd = this.parseAddr(sLen);\n if (dbgAddrEnd) len = dbgAddrEnd.addr - dbgAddr.addr;\n }\n if (len < 0) len = 0;\n if (len > 0x10000) len = 0x10000;\n }\n\n var nBase = this.nBase;\n if (dbgAddr.nBase) this.nBase = dbgAddr.nBase;\n\n /*\n * I've changed the code below to effectively make \"dw\" the default if only \"d\" is specified,\n * since this is primarily a word-oriented machine.\n */\n var size = (sCmd == \"dd\"? 4 : (sCmd == \"db\"? 1 : 2));\n var nBytes = (size * len) || 128;\n var nBytesPerLine = fJSON? 16 : this.nBase;\n var nLines = (((nBytes + nBytesPerLine - 1) / nBytesPerLine)|0) || 1;\n\n var sDump = \"\";\n while (nLines-- && nBytes > 0) {\n var sData = \"\", sChars = \"\";\n sAddr = this.toStrAddr(dbgAddr);\n /*\n * Dump 8 bytes per line when using base 8, and dump 16 bytes when using base 16.\n *\n * And while we used to always call getByte() and assemble them into words or dwords as appropriate, I've\n * changed the logic below to honor \"dw\" by calling getWord(), since the Bus interfaces have been updated\n * to prevent generating traps due to to Debugger access of unaligned memory and/or undefined IOPAGE addresses.\n *\n * Besides, it's nice for \"db\" and \"dw\" to generate the same Bus activity that typical byte and word reads do.\n */\n var i = nBytesPerLine;\n var data = 0, shift = 0;\n while (i > 0 && nBytes > 0) {\n var n = 1;\n var v = size == 1? this.getByte(dbgAddr, n) : this.getWord(dbgAddr, (n = 2));\n data |= (v << (shift << 3));\n shift += n;\n if (shift == size) {\n if (fJSON) {\n if (sData) sData += \",\";\n sData += \"0x\"+ Str.toHex(data, size << 1);\n } else {\n sData += this.toStrBase(data, size << 3);\n sData += (size == 1? (i == 9? '-' : ' ') : \" \");\n }\n data = shift = 0;\n }\n i -= n; nBytes -= n;\n while (size == 1 && n--) {\n var c = v & 0xff;\n sChars += (c >= 32 && c < 127? String.fromCharCode(c) : '.');\n v >>= 8;\n }\n }\n if (sDump) sDump += \"\\n\";\n if (fJSON) {\n sDump += sData + \",\";\n } else {\n sDump += sAddr + \": \" + sData + ((i == 0)? (' ' + sChars) : \"\");\n }\n }\n\n if (sDump) this.println(sDump);\n\n this.dbgAddrNextData = dbgAddr;\n this.nBase = nBase;\n }\n\n /**\n * doEdit(asArgs)\n *\n * @this {DebuggerPDP11}\n * @param {Array.<string>} asArgs\n */\n doEdit(asArgs)\n {\n var size, mask;\n var fnGet, fnSet;\n var sCmd = asArgs[0];\n var sAddr = asArgs[1];\n if (sCmd == \"eb\") {\n size = 1;\n mask = 0xff;\n fnGet = this.getByte;\n fnSet = this.setByte;\n }\n else if (sCmd == \"e\" || sCmd == \"ew\") {\n size = 2;\n mask = 0xffff;\n fnGet = this.getWord;\n fnSet = this.setWord;\n } else {\n sAddr = null;\n }\n if (sAddr == null) {\n this.println(\"edit memory commands:\");\n this.println(\"\\teb [a] [...] edit bytes at address a\");\n this.println(\"\\tew [a] [...] edit words at address a\");\n return;\n }\n var dbgAddr = this.parseAddr(sAddr);\n if (!dbgAddr) return;\n for (var i = 2; i < asArgs.length; i++) {\n var vNew = this.parseExpression(asArgs[i]);\n if (vNew === undefined) {\n this.println(\"unrecognized value: \" + asArgs[i]);\n break;\n }\n if (vNew & ~mask) {\n this.println(\"warning: \" + Str.toHex(vNew) + \" exceeds \" + size + \"-byte value\");\n }\n this.println(\"changing \" + this.toStrAddr(dbgAddr) + (this.messageEnabled(MessagesPDP11.BUS)? \"\" : (\" from \" + this.toStrBase(fnGet.call(this, dbgAddr), size << 3))) + \" to \" + this.toStrBase(vNew, size << 3));\n fnSet.call(this, dbgAddr, vNew, size);\n }\n }\n\n /**\n * doHalt(fQuiet)\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fQuiet]\n */\n doHalt(fQuiet)\n {\n var sMsg;\n if (this.flags.running) {\n if (!fQuiet) this.println(\"halting\");\n this.stopCPU();\n } else {\n if (this.isBusy(true)) return;\n if (!fQuiet) this.println(\"already halted\");\n }\n }\n\n /**\n * doIf(sCmd, fQuiet)\n *\n * NOTE: Don't forget that the default base for all numeric constants is 16 (hex), so when you evaluate\n * an expression like \"a==10\", it will compare the value of the variable \"a\" to 0x10; use a trailing period\n * (eg, \"10.\") if you really intend decimal.\n *\n * Also, if no variable named \"a\" exists, \"a\" will evaluate to 0x0A, so the expression \"a==10\" becomes\n * \"0x0A==0x10\" (false), whereas the expression \"a==10.\" becomes \"0x0A==0x0A\" (true).\n *\n * @this {DebuggerPDP11}\n * @param {string} sCmd\n * @param {boolean} [fQuiet]\n * @return {boolean} true if expression is non-zero, false if zero (or undefined due to a parse error)\n */\n doIf(sCmd, fQuiet)\n {\n sCmd = Str.trim(sCmd);\n if (!this.parseExpression(sCmd)) {\n if (!fQuiet) this.println(\"false: \" + sCmd);\n return false;\n }\n if (!fQuiet) this.println(\"true: \" + sCmd);\n return true;\n }\n\n /**\n * doInfo(asArgs)\n *\n * @this {DebuggerPDP11}\n * @param {Array.<string>} asArgs\n * @return {boolean} true only if the instruction info command (\"n\") is supported\n */\n doInfo(asArgs)\n {\n if (DEBUG) {\n this.println(\"msPerYield: \" + this.cpu.msPerYield);\n this.println(\"nCyclesPerYield: \" + this.cpu.nCyclesPerYield);\n return true;\n }\n return false;\n }\n\n /**\n * doVar(sCmd)\n *\n * The command must be of the form \"{variable} = [{expression}]\", where expression may contain constants,\n * operators, registers, symbols, other variables, or nothing at all; in the latter case, the variable, if\n * any, is deleted.\n *\n * Other supported shorthand: \"var\" with no parameters prints the values of all variables, and \"var {variable}\"\n * prints the value of the specified variable.\n *\n * @this {DebuggerPDP11}\n * @param {string} sCmd\n * @return {boolean} true if valid \"var\" assignment, false if not\n */\n doVar(sCmd)\n {\n var a = sCmd.match(/^\\s*([A-Z_]?[A-Z0-9_]*)\\s*(=?)\\s*(.*)$/i);\n if (a) {\n if (!a[1]) {\n if (!this.printVariable()) this.println(\"no variables\");\n return true; // it's not considered an error to print an empty list of variables\n }\n if (!a[2]) {\n return this.printVariable(a[1]);\n }\n if (!a[3]) {\n this.delVariable(a[1]);\n return true; // it's not considered an error to delete a variable that didn't exist\n }\n var v = this.parseExpression(a[3]);\n if (v !== undefined) {\n this.setVariable(a[1], v);\n return true;\n }\n return false;\n }\n this.println(\"invalid assignment:\" + sCmd);\n return false;\n }\n\n /**\n * doList(sAddr, fPrint)\n *\n * @this {DebuggerPDP11}\n * @param {string} sAddr\n * @param {boolean} [fPrint]\n * @return {string|null}\n */\n doList(sAddr, fPrint)\n {\n var sSymbol = null;\n\n var dbgAddr = this.parseAddr(sAddr, true);\n if (dbgAddr) {\n var addr = this.getAddr(dbgAddr);\n var aSymbol = this.findSymbol(dbgAddr, true);\n if (aSymbol.length) {\n var nDelta, sDelta, s;\n if (aSymbol[0]) {\n sDelta = \"\";\n nDelta = dbgAddr.addr - aSymbol[1];\n if (nDelta) sDelta = \" + \" + Str.toHexWord(nDelta);\n s = aSymbol[0] + \" (\" + this.toStrOffset(aSymbol[1]) + ')' + sDelta;\n if (fPrint) this.println(s);\n sSymbol = s;\n }\n if (aSymbol.length > 4 && aSymbol[4]) {\n sDelta = \"\";\n nDelta = aSymbol[5] - dbgAddr.addr;\n if (nDelta) sDelta = \" - \" + Str.toHexWord(nDelta);\n s = aSymbol[4] + \" (\" + this.toStrOffset(aSymbol[5]) + ')' + sDelta;\n if (fPrint) this.println(s);\n if (!sSymbol) sSymbol = s;\n }\n } else {\n if (fPrint) this.println(\"no symbols\");\n }\n }\n return sSymbol;\n }\n\n /**\n * doMessages(asArgs)\n *\n * @this {DebuggerPDP11}\n * @param {Array.<string>} asArgs\n */\n doMessages(asArgs)\n {\n var m;\n var fCriteria = null;\n var sCategory = asArgs[1];\n if (sCategory == '?') sCategory = undefined;\n\n if (sCategory !== undefined) {\n var bitsMessage = 0;\n if (sCategory == \"all\") {\n bitsMessage = (0xffffffff|0) & ~(MessagesPDP11.HALT | MessagesPDP11.KEYS | MessagesPDP11.BUFFER);\n sCategory = null;\n } else if (sCategory == \"on\") {\n fCriteria = true;\n sCategory = null;\n } else if (sCategory == \"off\") {\n fCriteria = false;\n sCategory = null;\n } else {\n /*\n * Internally, we use \"key\" instead of \"keys\", since the latter is a method on JavasScript objects,\n * but externally, we allow the user to specify \"keys\"; \"kbd\" is also allowed as shorthand for \"keyboard\".\n */\n if (sCategory == \"keys\") sCategory = \"key\";\n if (sCategory == \"kbd\") sCategory = \"keyboard\";\n for (m in MessagesPDP11.CATEGORIES) {\n if (sCategory == m) {\n bitsMessage = MessagesPDP11.CATEGORIES[m];\n fCriteria = !!(this.bitsMessage & bitsMessage);\n break;\n }\n }\n if (!bitsMessage) {\n this.println(\"unknown message category: \" + sCategory);\n return;\n }\n }\n if (bitsMessage) {\n if (asArgs[2] == \"on\") {\n this.bitsMessage |= bitsMessage;\n fCriteria = true;\n }\n else if (asArgs[2] == \"off\") {\n this.bitsMessage &= ~bitsMessage;\n fCriteria = false;\n if (bitsMessage == MessagesPDP11.BUFFER) {\n var i = this.aMessageBuffer.length >= 1000? this.aMessageBuffer.length - 1000 : 0;\n while (i < this.aMessageBuffer.length) {\n this.println(this.aMessageBuffer[i++]);\n }\n this.aMessageBuffer = [];\n }\n }\n }\n }\n\n /*\n * Display those message categories that match the current criteria (on or off)\n */\n var n = 0;\n var sCategories = \"\";\n for (m in MessagesPDP11.CATEGORIES) {\n if (!sCategory || sCategory == m) {\n var bitMessage = MessagesPDP11.CATEGORIES[m];\n var fEnabled = !!(this.bitsMessage & bitMessage);\n if (fCriteria !== null && fCriteria != fEnabled) continue;\n if (sCategories) sCategories += ',';\n if (!(++n % 10)) sCategories += \"\\n\\t\"; // jshint ignore:line\n /*\n * Internally, we use \"key\" instead of \"keys\", since the latter is a method on JavasScript objects,\n * but externally, we allow the user to specify \"keys\".\n */\n if (m == \"key\") m = \"keys\";\n sCategories += m;\n }\n }\n\n if (sCategory === undefined) {\n this.println(\"message commands:\\n\\tm [category] [on|off]\\tturn categories on/off\");\n }\n\n this.println((fCriteria !== null? (fCriteria? \"messages on: \" : \"messages off: \") : \"message categories:\\n\\t\") + (sCategories || \"none\"));\n\n this.historyInit(); // call this just in case MessagesPDP11.INT was turned on\n }\n\n /**\n * doOptions(asArgs)\n *\n * @this {DebuggerPDP11}\n * @param {Array.<string>} asArgs\n */\n doOptions(asArgs)\n {\n switch (asArgs[1]) {\n\n case \"base\":\n if (asArgs[2]) {\n var nBase = +asArgs[2];\n if (nBase == 8 || nBase == 10 || nBase == 16) {\n this.nBase = nBase;\n } else {\n this.println(\"invalid base: \" + nBase);\n break;\n }\n }\n this.println(\"default base: \" + this.nBase);\n break;\n\n case \"cs\":\n var nCycles;\n if (asArgs[3] !== undefined) nCycles = +asArgs[3]; // warning: decimal instead of hex conversion\n switch (asArgs[2]) {\n case \"int\":\n this.cpu.nCyclesChecksumInterval = nCycles;\n break;\n case \"start\":\n this.cpu.nCyclesChecksumStart = nCycles;\n break;\n case \"stop\":\n this.cpu.nCyclesChecksumStop = nCycles;\n break;\n default:\n this.println(\"unknown cs option\");\n return;\n }\n if (nCycles !== undefined) {\n this.cpu.resetChecksum();\n }\n this.println(\"checksums \" + (this.cpu.flags.checksum? \"enabled\" : \"disabled\"));\n return;\n\n case \"sp\":\n if (asArgs[2] !== undefined) {\n if (!this.cpu.setSpeed(+asArgs[2])) {\n this.println(\"warning: using 1x multiplier, previous target not reached\");\n }\n }\n this.println(\"target speed: \" + this.cpu.getSpeedTarget() + \" (\" + this.cpu.getSpeed() + \"x)\");\n return;\n\n default:\n if (asArgs[1]) {\n this.println(\"unknown option: \" + asArgs[1]);\n return;\n }\n /* falls through */\n\n case \"?\":\n this.println(\"debugger options:\");\n this.println(\"\\tbase #\\t\\tset default base to #\");\n this.println(\"\\tcs int #\\tset checksum cycle interval to #\");\n this.println(\"\\tcs start #\\tset checksum cycle start count to #\");\n this.println(\"\\tcs stop #\\tset checksum cycle stop count to #\");\n this.println(\"\\tsp #\\t\\tset speed multiplier to #\");\n break;\n }\n }\n\n /**\n * doRegisters(asArgs, fInstruction)\n *\n * @this {DebuggerPDP11}\n * @param {Array.<string>} [asArgs]\n * @param {boolean} [fInstruction] (true to include the current instruction; default is true)\n */\n doRegisters(asArgs, fInstruction)\n {\n if (asArgs && asArgs[1] == '?') {\n this.println(\"register commands:\");\n this.println(\"\\tr\\tdump registers\");\n this.println(\"\\trm\\tdump misc registers\");\n this.println(\"\\trx [#]\\tset flag or register x to [#]\");\n return;\n }\n\n var fMisc = false;\n var cpu = this.cpu;\n if (fInstruction == null) fInstruction = true;\n\n if (asArgs != null && asArgs.length > 1) {\n var sReg = asArgs[1];\n\n if (sReg == 'm') {\n fMisc = true;\n }\n else {\n var sValue = null;\n var i = sReg.indexOf('=');\n if (i > 0) {\n sValue = sReg.substr(i + 1);\n sReg = sReg.substr(0, i);\n }\n else if (asArgs.length > 2) {\n sValue = asArgs[2];\n }\n else {\n this.println(\"missing value for \" + asArgs[1]);\n return;\n }\n\n var w = this.parseExpression(sValue);\n if (w === undefined) return;\n\n var sRegMatch = sReg.toUpperCase();\n switch (sRegMatch) {\n case \"SP\":\n case \"R6\":\n cpu.setSP(w);\n break;\n case \"PC\":\n case \"R7\":\n cpu.setPC(w);\n this.dbgAddrNextCode = this.newAddr(cpu.getPC());\n break;\n case \"N\":\n if (w) cpu.setNF(); else cpu.clearNF();\n break;\n case \"Z\":\n if (w) cpu.setZF(); else cpu.clearZF();\n break;\n case \"V\":\n if (w) cpu.setVF(); else cpu.clearVF();\n break;\n case \"C\":\n if (w) cpu.setCF(); else cpu.clearCF();\n break;\n case \"PS\":\n cpu.setPSW(w);\n break;\n case \"PI\":\n cpu.setPIR(w);\n break;\n case \"ER\":\n cpu.regErr = w;\n fMisc = true;\n break;\n case \"SL\":\n cpu.setSLR(w);\n break;\n case \"M0\":\n cpu.setMMR0(w);\n fMisc = true;\n break;\n case \"M3\":\n cpu.setMMR3(w);\n fMisc = true;\n break;\n case \"AR\":\n if (this.panel) this.panel.setAR(w);\n fMisc = true;\n break;\n case \"DR\":\n if (this.panel) this.panel.setDR(w);\n fMisc = true;\n break;\n case \"SR\":\n if (this.panel) this.panel.setSR(w);\n fMisc = true;\n break;\n default:\n if (sRegMatch.charAt(0) == 'R') {\n var iReg = +sRegMatch.charAt(1);\n if (iReg >= 0 && iReg < 6) {\n cpu.regsGen[iReg] = w & 0xffff;\n break;\n }\n }\n this.println(\"unknown register: \" + sReg);\n return;\n }\n this.cmp.updateDisplays();\n this.println(\"updated registers:\");\n }\n }\n\n this.println(this.getRegDump(fMisc));\n\n if (fInstruction) {\n this.dbgAddrNextCode = this.newAddr(cpu.getPC());\n this.doUnassemble(this.toStrAddr(this.dbgAddrNextCode));\n }\n }\n\n /**\n * doRun(sCmd, sAddr, sOptions, fQuiet)\n *\n * @this {DebuggerPDP11}\n * @param {string} sCmd\n * @param {string|undefined} [sAddr]\n * @param {string} [sOptions] (the rest of the breakpoint command-line)\n * @param {boolean} [fQuiet]\n */\n doRun(sCmd, sAddr, sOptions, fQuiet)\n {\n if (sCmd == \"gt\") {\n this.fIgnoreNextCheckFault = true;\n }\n if (sAddr !== undefined) {\n var dbgAddr = this.parseAddr(sAddr, true);\n if (!dbgAddr) return;\n this.parseAddrOptions(dbgAddr, sOptions);\n this.setTempBreakpoint(dbgAddr);\n }\n this.startCPU(true, fQuiet);\n }\n\n /**\n * doPrint(sCmd)\n *\n * NOTE: If the string to print is a quoted string, then we run it through replaceRegs(), so that\n * you can take advantage of all the special replacement options used for software interrupt logging.\n *\n * @this {DebuggerPDP11}\n * @param {string} sCmd\n */\n doPrint(sCmd)\n {\n sCmd = Str.trim(sCmd);\n var a = sCmd.match(/^(['\"])(.*?)\\1$/);\n if (!a) {\n this.parseExpression(sCmd, false);\n } else {\n if (a[2].length > 1) {\n this.println(this.replaceRegs(a[2]));\n } else {\n this.printValue(null, a[2].charCodeAt(0));\n }\n }\n }\n\n /**\n * doStep(sCmd, sOption)\n *\n * @this {DebuggerPDP11}\n * @param {string} [sCmd] \"p\" or \"pr\"\n * @param {string} [sOption]\n */\n doStep(sCmd, sOption)\n {\n if (sOption == '?') {\n this.println(\"step commands:\");\n this.println(\"\\tp\\tstep over instruction\");\n this.println(\"\\tpr\\tstep over instruction with register update\");\n return;\n }\n\n var fCallStep = true;\n var nRegs = (sCmd == \"pr\"? 1 : 0);\n /*\n * Set up the value for this.nStep (ie, 1 or 2) depending on whether the user wants\n * a subsequent register dump (\"pr\") or not (\"p\").\n */\n var nStep = 1 + nRegs;\n\n if (!this.nStep) {\n var dbgAddr = this.newAddr(this.cpu.getPC());\n var opCode = this.getWord(dbgAddr);\n\n if (opCode == PDP11.OPCODE.BPT || opCode == PDP11.OPCODE.IOT ||\n (opCode & PDP11.OPCODE.EMT_MASK) == PDP11.OPCODE.EMT_OP ||\n (opCode & PDP11.OPCODE.SOB_MASK) == PDP11.OPCODE.SOB_OP ||\n (opCode & PDP11.OPCODE.TRAP_MASK) == PDP11.OPCODE.TRAP_OP) {\n if (fCallStep) {\n this.nStep = nStep;\n this.incAddr(dbgAddr, 2);\n }\n } else if ((opCode & PDP11.OPCODE.JSR_MASK) == PDP11.OPCODE.JSR_OP) {\n var s = this.getInstruction(dbgAddr);\n\n if (fCallStep) {\n this.nStep = nStep;\n }\n }\n\n if (this.nStep) {\n this.setTempBreakpoint(dbgAddr);\n if (!this.startCPU()) {\n if (this.cmp) this.cmp.setFocus();\n this.nStep = 0;\n }\n /*\n * A successful run will ultimately call stop(), which will in turn call clearTempBreakpoint(),\n * which will clear nStep, so there's your assurance that nStep will be reset. Now we may have\n * stopped for reasons unrelated to the temporary breakpoint, but that's OK.\n */\n } else {\n this.doTrace(nRegs? \"tr\" : \"t\");\n }\n } else {\n this.println(\"step in progress\");\n }\n }\n\n /**\n * getCall(dbgAddr)\n *\n * Given a possible return address (typically from the stack), look for a matching CALL (or INT) that\n * immediately precedes that address.\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @return {string|null} CALL instruction at or near dbgAddr, or null if none\n */\n getCall(dbgAddr)\n {\n var sCall = null;\n var addr = dbgAddr.addr;\n var addrOrig = addr;\n for (var n = 1; n <= 6 && !!addr; n++) {\n if (n > 2) {\n dbgAddr.addr = addr;\n var s = this.getInstruction(dbgAddr);\n if (s.indexOf(\"JSR\") >= 0) {\n /*\n * Verify that the length of this call, when added to the address of the call, matches\n * the original return address. We do this by getting the string index of the opcode bytes,\n * subtracting that from the string index of the next space, and dividing that difference\n * by two, to yield the length of the CALL (or INT) instruction, in bytes.\n */\n var i = s.indexOf(' ');\n var j = s.indexOf(' ', i+1);\n if (addr + (j - i - 1)/2 == addrOrig) {\n sCall = s;\n break;\n }\n }\n }\n addr -= 2;\n }\n dbgAddr.addr = addrOrig;\n return sCall;\n }\n\n /**\n * doStackTrace(sCmd, sAddr)\n *\n * Use \"k\" for a normal stack trace and \"ks\" for a stack trace with symbolic info.\n *\n * @this {DebuggerPDP11}\n * @param {string} [sCmd]\n * @param {string} [sAddr] (not used yet)\n */\n doStackTrace(sCmd, sAddr)\n {\n if (sAddr == '?') {\n this.println(\"stack trace commands:\");\n this.println(\"\\tk\\tshow frame addresses\");\n this.println(\"\\tks\\tshow symbol information\");\n return;\n }\n\n var nFrames = 10, cFrames = 0;\n var dbgAddrCall = this.newAddr();\n var dbgAddrStack = this.newAddr(this.cpu.getSP());\n this.println(\"stack trace for \" + this.toStrAddr(dbgAddrStack));\n\n while (cFrames < nFrames) {\n var sCall = null, sCallPrev = null, cTests = 256;\n while ((dbgAddrStack.addr >>> 0) < 0x10000) {\n dbgAddrCall.addr = this.getWord(dbgAddrStack, 2);\n /*\n * Because we're using the auto-increment feature of getWord(), and because that will automatically\n * wrap the offset around the end of the segment, we must also check the addr property to detect the wrap.\n */\n if (dbgAddrStack.addr == null || !cTests--) break;\n if (dbgAddrCall.addr & 0x1) continue; // an odd address on the PDP-11 is not a valid instruction boundary\n sCall = this.getCall(dbgAddrCall);\n if (sCall) break;\n }\n /*\n * The sCallPrev check eliminates duplicate sequential calls, which are usually (but not always)\n * indicative of a false positive, in which case the previous call is probably bogus as well, but\n * at least we won't duplicate that mistake. Of course, there are always exceptions, recursion\n * being one of them, but it's rare that we're debugging recursive code.\n */\n if (!sCall || sCall == sCallPrev) break;\n var sSymbol = null;\n if (sCmd == \"ks\") {\n var a = sCall.match(/[0-9A-F]+$/);\n if (a) sSymbol = this.doList(a[0]);\n }\n sCall = Str.pad(sCall, 50) + \" ;\" + (sSymbol || \"stack=\" + this.toStrAddr(dbgAddrStack)); // + \" return=\" + this.toStrAddr(dbgAddrCall));\n this.println(sCall);\n sCallPrev = sCall;\n cFrames++;\n }\n if (!cFrames) this.println(\"no return addresses found\");\n }\n\n /**\n * doTrace(sCmd, sCount)\n *\n * The \"t\" and \"tr\" commands interpret the count as a number of instructions, and since\n * we call the Debugger's stepCPU() for each iteration, a single instruction includes\n * any/all prefixes; the CPU's stepCPU() treats prefixes as discrete operations. The only\n * difference between \"t\" and \"tr\": the former displays only the next instruction, while\n * the latter also displays the (updated) registers.\n *\n * The \"tc\" command interprets the count as a number of cycles rather than instructions,\n * allowing you to quickly execute large chunks of instructions with a single command; it\n * doesn't display anything until the the chunk has finished. \"tc 1\" is also a useful\n * command in that it doesn't inhibit interrupts like \"t\" or \"tr\" does.\n *\n * However, generally a more useful command is \"bn\", which allows you to break after some\n * number of instructions have been executed (as opposed to some number of cycles).\n *\n * @this {DebuggerPDP11}\n * @param {string} [sCmd] (\"t\", \"tc\", or \"tr\")\n * @param {string} [sCount] # of instructions to step\n */\n doTrace(sCmd, sCount)\n {\n if (sCount == '?') {\n this.println(\"trace commands:\");\n this.println(\"\\tt [#]\\ttrace # instructions\");\n this.println(\"\\ttr [#]\\ttrace # instructions with register updates\");\n this.println(\"\\ttc [#]\\ttrace # cycles\");\n this.println(\"note: bn [#] breaks after # instructions without updates\");\n return;\n }\n\n var dbg = this;\n var fRegs = (sCmd != \"t\");\n var nCount = this.parseValue(sCount, null, true) || 1;\n\n /*\n * We used to set nCycles to 1 when a count > 1 was specified, because nCycles set\n * to 0 used to mean \"execute the next instruction without checking for interrupts\".\n * Well, this machine's stepCPU() doesn't do that; it ALWAYS checks for interrupts,\n * so we should leave nCycles set to 0, so that if an interrupt is dispatched, we will\n * get to see the first instruction of the interrupt handler.\n */\n var nCycles = 0; // (nCount == 1? 0 : 1);\n\n if (sCmd == \"tc\") {\n nCycles = nCount;\n nCount = 1;\n }\n this.sCmdTracePrev = sCmd;\n\n Web.onCountRepeat(\n nCount,\n function onCountStep() {\n return dbg.setBusy(true) && dbg.stepCPU(nCycles, fRegs, false);\n },\n function onCountStepComplete() {\n /*\n * We explicitly called stepCPU() with fUpdateDisplays set to false, because repeatedly\n * calling updateDisplays() can be very slow, especially if a Control Panel is present with\n * displayLiveRegs enabled, so once the repeat count has been exhausted, we must perform\n * a final updateDisplays().\n */\n if (dbg.panel) dbg.panel.stop();\n dbg.cmp.updateDisplays(-1);\n dbg.setBusy(false);\n }\n );\n }\n\n /**\n * doUnassemble(sAddr, sAddrEnd, nLines)\n *\n * @this {DebuggerPDP11}\n * @param {string} [sAddr]\n * @param {string} [sAddrEnd]\n * @param {number} [nLines]\n */\n doUnassemble(sAddr, sAddrEnd, nLines)\n {\n var dbgAddr = this.parseAddr(sAddr, true);\n if (!dbgAddr) return;\n\n if (nLines === undefined) nLines = 1;\n\n var nBytes = 0x100;\n if (sAddrEnd !== undefined) {\n\n if (sAddrEnd.charAt(0) == 'l') {\n var n = this.parseValue(sAddrEnd.substr(1));\n if (n != null) nLines = n;\n }\n else {\n var dbgAddrEnd = this.parseAddr(sAddrEnd, true);\n if (!dbgAddrEnd || dbgAddrEnd.addr < dbgAddr.addr) return;\n\n nBytes = dbgAddrEnd.addr - dbgAddr.addr;\n if (!DEBUG && nBytes > 0x100) {\n /*\n * Limiting the amount of disassembled code to 256 bytes in non-DEBUG builds is partly to\n * prevent the user from wedging the browser by dumping too many lines, but also a recognition\n * that, in non-DEBUG builds, this.println() keeps print output buffer truncated to 8Kb anyway.\n */\n this.println(\"range too large\");\n return;\n }\n nLines = -1;\n }\n }\n\n var nPrinted = 0;\n var sInstruction;\n\n while (nBytes > 0 && nLines--) {\n\n var nSequence = (this.isBusy(false) || this.nStep)? this.nCycles : null;\n var sComment = (nSequence != null? \"cycles\" : null);\n var aSymbol = this.findSymbol(dbgAddr);\n\n var addr = dbgAddr.addr; // we snap dbgAddr.addr *after* calling findSymbol(), which re-evaluates it\n\n if (aSymbol[0] && nLines) {\n if (!nPrinted && nLines || aSymbol[0].indexOf('+') < 0) {\n var sLabel = aSymbol[0] + ':';\n if (aSymbol[2]) sLabel += ' ' + aSymbol[2];\n this.println(sLabel);\n }\n }\n\n if (aSymbol[3]) {\n sComment = aSymbol[3];\n nSequence = null;\n }\n\n sInstruction = this.getInstruction(dbgAddr, sComment, nSequence);\n\n this.println(sInstruction);\n this.dbgAddrNextCode = dbgAddr;\n nBytes -= dbgAddr.addr - addr;\n nPrinted++;\n }\n }\n\n /**\n * splitArgs(sCmd)\n *\n * @this {DebuggerPDP11}\n * @param {string} sCmd\n * @return {Array.<string>}\n */\n splitArgs(sCmd)\n {\n var asArgs = sCmd.replace(/ +/g, ' ').split(' ');\n asArgs[0] = asArgs[0].toLowerCase();\n if (asArgs && asArgs.length) {\n var s0 = asArgs[0];\n var ch0 = s0.charAt(0);\n for (var i = 1; i < s0.length; i++) {\n var ch = s0.charAt(i);\n if (ch0 == '?' || ch0 == 'r' || ch < 'a' || ch > 'z') {\n asArgs[0] = s0.substr(i);\n asArgs.unshift(s0.substr(0, i));\n break;\n }\n }\n }\n return asArgs;\n }\n\n /**\n * doCommand(sCmd, fQuiet)\n *\n * @this {DebuggerPDP11}\n * @param {string} sCmd\n * @param {boolean} [fQuiet]\n * @return {boolean} true if command processed, false if unrecognized\n */\n doCommand(sCmd, fQuiet)\n {\n var result = true;\n\n try {\n if (!sCmd.length || sCmd == \"end\") {\n if (this.fAssemble) {\n this.println(\"ended assemble at \" + this.toStrAddr(this.dbgAddrAssemble));\n this.dbgAddrNextCode = this.dbgAddrAssemble;\n this.fAssemble = false;\n }\n sCmd = \"\";\n }\n else if (!fQuiet) {\n this.println(DebuggerPDP11.PROMPT + sCmd);\n }\n\n var ch = sCmd.charAt(0);\n if (ch == '\"' || ch == \"'\") return true;\n\n /*\n * Zap the previous message buffer to ensure the new command's output is not tossed out as a repeat.\n */\n this.sMessagePrev = null;\n\n /*\n * I've relaxed the !isBusy() requirement, to maximize our ability to issue Debugger commands externally.\n */\n if (this.isReady() /* && !this.isBusy(true) */ && sCmd.length > 0) {\n\n if (this.fAssemble) {\n sCmd = \"a \" + this.toStrAddr(this.dbgAddrAssemble) + ' ' + sCmd;\n }\n\n var fError = false;\n var asArgs = this.splitArgs(sCmd);\n\n switch (asArgs[0].charAt(0)) {\n case 'a':\n this.doAssemble(asArgs);\n break;\n case 'b':\n this.doBreak(asArgs[0], asArgs[1], sCmd);\n break;\n case 'c':\n this.doClear(asArgs[0]);\n break;\n case 'd':\n if (!COMPILED && sCmd == \"debug\") {\n window.DEBUG = true;\n this.println(\"DEBUG checks on\");\n break;\n }\n this.doDump(asArgs);\n break;\n case 'e':\n if (asArgs[0] == \"else\") break;\n this.doEdit(asArgs);\n break;\n case 'g':\n this.doRun(asArgs[0], asArgs[1], sCmd, fQuiet);\n break;\n case 'h':\n this.doHalt(fQuiet);\n break;\n case 'i':\n if (asArgs[0] == \"if\") {\n if (!this.doIf(sCmd.substr(2), fQuiet)) {\n result = false;\n }\n break;\n }\n fError = true;\n break;\n case 'k':\n this.doStackTrace(asArgs[0], asArgs[1]);\n break;\n case 'l':\n if (asArgs[0] == \"ln\") {\n this.doList(asArgs[1], true);\n break;\n }\n fError = true;\n break;\n case 'm':\n this.doMessages(asArgs);\n break;\n case 'p':\n if (asArgs[0] == \"print\") {\n this.doPrint(sCmd.substr(5));\n break;\n }\n this.doStep(asArgs[0], asArgs[1]);\n break;\n case 'r':\n if (sCmd == \"reset\") {\n if (this.cmp) this.cmp.reset();\n break;\n }\n this.doRegisters(asArgs);\n break;\n case 's':\n this.doOptions(asArgs);\n break;\n case 't':\n this.doTrace(asArgs[0], asArgs[1]);\n break;\n case 'u':\n this.doUnassemble(asArgs[1], asArgs[2], 8);\n break;\n case 'v':\n if (asArgs[0] == \"var\") {\n if (!this.doVar(sCmd.substr(3))) {\n result = false;\n }\n break;\n }\n if (asArgs[0] == \"ver\") {\n 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\")) + ')');\n this.println(Web.getUserAgent());\n break;\n }\n fError = true;\n break;\n case '?':\n if (asArgs[1]) {\n this.doPrint(sCmd.substr(1));\n break;\n }\n this.doHelp();\n break;\n case 'n':\n if (!COMPILED && sCmd == \"nodebug\") {\n window.DEBUG = false;\n this.println(\"DEBUG checks off\");\n break;\n }\n if (this.doInfo(asArgs)) break;\n /* falls through */\n default:\n fError = true;\n break;\n }\n if (fError) {\n this.println(\"unknown command: \" + sCmd);\n result = false;\n }\n }\n } catch(e) {\n this.println(\"debugger error: \" + (e.stack || e.message));\n result = false;\n }\n return result;\n }\n\n /**\n * doCommands(sCmds, fSave)\n *\n * @this {DebuggerPDP11}\n * @param {string} sCmds\n * @param {boolean} [fSave]\n * @return {boolean} true if all commands processed, false if not\n */\n doCommands(sCmds, fSave)\n {\n var a = this.parseCommand(sCmds, fSave);\n for (var s in a) {\n if (!this.doCommand(a[+s])) return false;\n }\n return true;\n }\n\n /**\n * DebuggerPDP11.init()\n *\n * This function operates on every HTML element of class \"debugger\", extracting the\n * JSON-encoded parameters for the Debugger constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Debugger component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeDbg = Component.getElementsByClass(document, PDP11.APPCLASS, \"debugger\");\n for (var iDbg = 0; iDbg < aeDbg.length; iDbg++) {\n var eDbg = aeDbg[iDbg];\n var parmsDbg = Component.getComponentParms(eDbg);\n var dbg = new DebuggerPDP11(parmsDbg);\n Component.bindComponentControls(dbg, eDbg, PDP11.APPCLASS);\n }\n }\n}\n\nif (DEBUGGER) {\n\n /*\n * NOTE: Every DebuggerPDP11 property from here to the first prototype function definition (initBus()) is\n * considered a \"class constant\"; most of them use our \"all-caps\" convention (and all of them SHOULD, but\n * that wouldn't help us catch any bugs).\n *\n * Technically, all of them should ALSO be preceded by a \"@const\" annotation, but that's a lot of work and it\n * really clutters the code. I wish the Closure Compiler had a way to annotate every definition with a given\n * section with a single annotation....\n */\n\n DebuggerPDP11.COMMANDS = {\n '?': \"help/print\",\n 'a [#]': \"assemble\", // TODO: Implement this command someday\n 'b [#]': \"breakpoint\", // multiple variations (use b? to list them)\n 'c': \"clear output\",\n 'd [#]': \"dump memory\", // additional syntax: d [#] [l#], where l# is a number of bytes to dump\n 'e [#]': \"edit memory\",\n 'g [#]': \"go [to #]\",\n 'h': \"halt\",\n 'if': \"eval expression\",\n 'int [#]': \"request interrupt\",\n 'k': \"stack trace\",\n \"ln\": \"list nearest symbol(s)\",\n 'm': \"messages\",\n 'p': \"step over\", // other variations: pr (step and dump registers)\n 'print': \"print expression\",\n 'r': \"dump/set registers\",\n 'reset': \"reset machine\",\n 's': \"set options\",\n 't [#]': \"trace\", // other variations: tr (trace and dump registers)\n 'u [#]': \"unassemble\",\n 'var': \"assign variable\",\n 'ver': \"print version\"\n };\n\n /*\n * CPU opcode IDs\n *\n * Not listed: BLO (same as BCS) and BHIS (same as BCC).\n */\n DebuggerPDP11.OPS = {\n NONE: 0, ADC: 1, ADCB: 2, ADD: 3, ASL: 4, ASLB: 5, ASR: 6, ASRB: 7,\n BCC: 8, BCS: 9, BEQ: 10, BGE: 11, BGT: 12, BHI: 13, BIC: 14, BICB: 15,\n BIS: 16, BISB: 17, BIT: 18, BITB: 19, BLE: 20, BLOS: 21, BLT: 22, BMI: 23,\n BNE: 24, BPL: 25, BPT: 26, BR: 27, BVC: 28, BVS: 29, CCC: 30, CLC: 31,\n CLCN: 32, CLCV: 33, CLCVN: 34, CLCVZ: 35, CLCZ: 36, CLCZN: 37, CLN: 38, CLR: 39,\n CLRB: 40, CLV: 41, CLVN: 42, CLVZ: 43, CLVZN: 44, CLZ: 45, CLZN: 46, CMP: 47,\n CMPB: 48, COM: 49, COMB: 50, DEC: 51, DECB: 52, INC: 53, INCB: 54, HALT: 55,\n JMP: 56, JSR: 57, MARK: 58, MFPD: 59, MFPI: 60, MFPS: 61, MOV: 62, MOVB: 63,\n MTPD: 64, MTPI: 65, MTPS: 66, NEG: 67, NEGB: 68, NOP: 69, RESET: 70, ROL: 71,\n ROLB: 72, ROR: 73, RORB: 74, RTI: 75, RTS: 76, SBC: 77, SBCB: 78, SCC: 79,\n SEC: 80, SECN: 81, SECV: 82, SECVN: 83, SECVZ: 84, SECZ: 85, SECZN: 86, SEN: 87,\n SEV: 88, SEVN: 89, SEVZ: 90, SEVZN: 91, SEZ: 92, SEZN: 93, SUB: 94, SWAB: 95,\n SXT: 96, TST: 97, TSTB: 98, WAIT: 99, MUL: 100, DIV: 101, ASH: 102, ASHC: 103,\n XOR: 104, SOB: 105, EMT: 106, TRAP: 107, SPL: 108, IOT: 109, RTT: 110, MFPT: 111\n };\n\n /*\n * CPU opcode names, indexed by CPU opcode ordinal (above)\n */\n DebuggerPDP11.OPNAMES = [\n \".WORD\", \"ADC\", \"ADCB\", \"ADD\", \"ASL\", \"ASLB\", \"ASR\", \"ASRB\",\n \"BCC\", \"BCS\", \"BEQ\", \"BGE\", \"BGT\", \"BHI\", \"BIC\", \"BICB\",\n \"BIS\", \"BISB\", \"BIT\", \"BITB\", \"BLE\", \"BLOS\", \"BLT\", \"BMI\",\n \"BNE\", \"BPL\", \"BPT\", \"BR\", \"BVC\", \"BVS\", \"CCC\", \"CLC\",\n \"CLCN\", \"CLCV\", \"CLCVN\", \"CLCVZ\", \"CLCZ\", \"CLCZN\", \"CLN\", \"CLR\",\n \"CLRB\", \"CLV\", \"CLVN\", \"CLVZ\", \"CLVZN\", \"CLZ\", \"CLZN\", \"CMP\",\n \"CMPB\", \"COM\", \"COMB\", \"DEC\", \"DECB\", \"INC\", \"INCB\", \"HALT\",\n \"JMP\", \"JSR\", \"MARK\", \"MFPD\", \"MFPI\", \"MFPS\", \"MOV\", \"MOVB\",\n \"MTPD\", \"MTPI\", \"MTPS\", \"NEG\", \"NEGB\", \"NOP\", \"RESET\", \"ROL\",\n \"ROLB\", \"ROR\", \"RORB\", \"RTI\", \"RTS\", \"SBC\", \"SBCB\", \"SCC\",\n \"SEC\", \"SECN\", \"SECV\", \"SECVN\", \"SECVZ\", \"SECZ\", \"SECZN\", \"SEN\",\n \"SEV\", \"SEVN\", \"SEVZ\", \"SEVZN\", \"SEZ\", \"SEZN\", \"SUB\", \"SWAB\",\n \"SXT\", \"TST\", \"TSTB\", \"WAIT\", \"MUL\", \"DIV\", \"ASH\", \"ASHC\",\n \"XOR\", \"SOB\", \"EMT\", \"TRAP\", \"SPL\", \"IOT\", \"RTT\", \"MFPT\"\n ];\n\n /*\n * Register numbers 0-7 are reserved for cpu.regsGen, 8-15 are reserved for cpu.regsAlt, and 16-19 for cpu.regsStack.\n */\n DebuggerPDP11.REG_PS = 20;\n DebuggerPDP11.REG_PI = 21;\n DebuggerPDP11.REG_ER = 22;\n DebuggerPDP11.REG_SL = 23;\n DebuggerPDP11.REG_M0 = 24;\n DebuggerPDP11.REG_M1 = 25;\n DebuggerPDP11.REG_M2 = 26;\n DebuggerPDP11.REG_M3 = 27;\n DebuggerPDP11.REG_AR = 28; // ADDRESS register; see Panel's getAR() and setAR()\n DebuggerPDP11.REG_DR = 29; // DISPLAY/DATA register; see Panel's getDR() and setDR()\n DebuggerPDP11.REG_SR = 30; // SWITCH register; see Panel's getSR() and setSR()\n\n DebuggerPDP11.REGS = {\n \"SP\": 6,\n \"PC\": 7,\n \"PS\": DebuggerPDP11.REG_PS,\n \"PI\": DebuggerPDP11.REG_PI,\n \"ER\": DebuggerPDP11.REG_ER,\n \"SL\": DebuggerPDP11.REG_SL,\n \"M0\": DebuggerPDP11.REG_M0,\n \"M1\": DebuggerPDP11.REG_M1,\n \"M2\": DebuggerPDP11.REG_M2,\n \"M3\": DebuggerPDP11.REG_M3,\n \"AR\": DebuggerPDP11.REG_AR,\n \"DR\": DebuggerPDP11.REG_DR,\n \"SR\": DebuggerPDP11.REG_SR\n };\n\n DebuggerPDP11.REGNAMES = [\n \"R0\", \"R1\", \"R2\", \"R3\", \"R4\", \"R5\", \"SP\", \"PC\",\n \"A0\", \"A1\", \"A2\", \"A3\", \"A4\", \"A5\", \"A6\", \"A7\",\n \"S0\", \"S1\", \"S2\", \"S3\",\n \"PS\", \"PI\", \"ER\", \"SL\", \"M0\", \"M1\", \"M2\", \"M3\",\n \"AR\", \"DR\", \"SR\"\n ];\n\n DebuggerPDP11.MODES = [\"KI\",\"KD\",\"SI\",\"SD\",\"??\",\"??\",\"UI\",\"UD\"];\n\n /*\n * Operand type masks; anything that's not covered by OP_SRC or OP_DST must be a OP_OTHER value.\n */\n DebuggerPDP11.OP_DSTREG = PDP11.OPREG.MASK;\n DebuggerPDP11.OP_DSTMODE = PDP11.OPMODE.MASK;\n DebuggerPDP11.OP_DST = (DebuggerPDP11.OP_DSTMODE | DebuggerPDP11.OP_DSTREG);\n DebuggerPDP11.OP_SRCREG = PDP11.OPREG.MASK << 6;\n DebuggerPDP11.OP_SRCMODE = PDP11.OPMODE.MASK << 6;\n DebuggerPDP11.OP_SRC = (DebuggerPDP11.OP_SRCMODE | DebuggerPDP11.OP_SRCREG);\n DebuggerPDP11.OP_BRANCH = 0x1000;\n DebuggerPDP11.OP_DSTOFF = 0x2000;\n DebuggerPDP11.OP_DSTNUM3 = 0x3000; // DST 3-bit number (ie, just the DSTREG field)\n DebuggerPDP11.OP_DSTNUM6 = 0x6000; // DST 6-bit number (ie, both the DSTREG and DSTMODE fields)\n DebuggerPDP11.OP_DSTNUM8 = 0x8000; // DST 8-bit number\n DebuggerPDP11.OP_OTHER = 0xF000;\n\n /*\n * The OPTABLE contains opcode masks, and each mask refers to table of possible values, and each\n * value refers to an array that contains:\n *\n * [0]: {number} of the opcode name (see OP.*)\n * [1]: {number} containing the first operand type bit(s), if any\n * [2]: {number} containing the second operand type bit(s), if any\n *\n * Note that, by convention, opcodes that require two operands list the SRC operand first and DST operand\n * second (ie, the OPPOSITE of the Intel convention).\n *\n * Also note that, for some of the newer PDP-11 opcodes (eg, MUL, DIV, ASH, ASHC), the location of the\n * opcode's SRC and DST bits are reversed. This is why, for example, you'll see the MUL instruction defined\n * below as having OP_DST for the first operand and OP_SRCREG for the second operand. This does NOT mean\n * that the opcode's destination operand is being listed first, but rather that the bits describing the source\n * operand are in the opcode's OP_DST field.\n */\n DebuggerPDP11.OPTABLE = {\n 0xF000: {\n 0x1000: [DebuggerPDP11.OPS.MOV, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 01SSDD\n 0x2000: [DebuggerPDP11.OPS.CMP, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 02SSDD\n 0x3000: [DebuggerPDP11.OPS.BIT, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 03SSDD\n 0x4000: [DebuggerPDP11.OPS.BIC, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 04SSDD\n 0x5000: [DebuggerPDP11.OPS.BIS, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 05SSDD\n 0x6000: [DebuggerPDP11.OPS.ADD, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 06SSDD\n 0x9000: [DebuggerPDP11.OPS.MOVB, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 11SSDD\n 0xA000: [DebuggerPDP11.OPS.CMPB, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 12SSDD\n 0xB000: [DebuggerPDP11.OPS.BITB, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 13SSDD\n 0xC000: [DebuggerPDP11.OPS.BICB, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 14SSDD\n 0xD000: [DebuggerPDP11.OPS.BISB, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 15SSDD\n 0xE000: [DebuggerPDP11.OPS.SUB, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST] // 16SSDD\n },\n 0xFE00: {\n 0x0800: [DebuggerPDP11.OPS.JSR, DebuggerPDP11.OP_SRCREG, DebuggerPDP11.OP_DST], // 004RDD\n 0x7000: [DebuggerPDP11.OPS.MUL, DebuggerPDP11.OP_DST, DebuggerPDP11.OP_SRCREG], // 070RSS\n 0x7200: [DebuggerPDP11.OPS.DIV, DebuggerPDP11.OP_DST, DebuggerPDP11.OP_SRCREG], // 071RSS\n 0x7400: [DebuggerPDP11.OPS.ASH, DebuggerPDP11.OP_DST, DebuggerPDP11.OP_SRCREG], // 072RSS\n 0x7600: [DebuggerPDP11.OPS.ASHC, DebuggerPDP11.OP_DST, DebuggerPDP11.OP_SRCREG], // 073RSS\n 0x7800: [DebuggerPDP11.OPS.XOR, DebuggerPDP11.OP_SRCREG, DebuggerPDP11.OP_DST], // 074RDD\n 0x7E00: [DebuggerPDP11.OPS.SOB, DebuggerPDP11.OP_SRCREG, DebuggerPDP11.OP_DSTOFF] // 077Rnn\n },\n 0xFF00: {\n 0x0100: [DebuggerPDP11.OPS.BR, DebuggerPDP11.OP_BRANCH],\n 0x0200: [DebuggerPDP11.OPS.BNE, DebuggerPDP11.OP_BRANCH],\n 0x0300: [DebuggerPDP11.OPS.BEQ, DebuggerPDP11.OP_BRANCH],\n 0x0400: [DebuggerPDP11.OPS.BGE, DebuggerPDP11.OP_BRANCH],\n 0x0500: [DebuggerPDP11.OPS.BLT, DebuggerPDP11.OP_BRANCH],\n 0x0600: [DebuggerPDP11.OPS.BGT, DebuggerPDP11.OP_BRANCH],\n 0x0700: [DebuggerPDP11.OPS.BLE, DebuggerPDP11.OP_BRANCH],\n 0x8000: [DebuggerPDP11.OPS.BPL, DebuggerPDP11.OP_BRANCH],\n 0x8100: [DebuggerPDP11.OPS.BMI, DebuggerPDP11.OP_BRANCH],\n 0x8200: [DebuggerPDP11.OPS.BHI, DebuggerPDP11.OP_BRANCH],\n 0x8300: [DebuggerPDP11.OPS.BLOS, DebuggerPDP11.OP_BRANCH],\n 0x8400: [DebuggerPDP11.OPS.BVC, DebuggerPDP11.OP_BRANCH],\n 0x8500: [DebuggerPDP11.OPS.BVS, DebuggerPDP11.OP_BRANCH],\n 0x8600: [DebuggerPDP11.OPS.BCC, DebuggerPDP11.OP_BRANCH],\n 0x8700: [DebuggerPDP11.OPS.BCS, DebuggerPDP11.OP_BRANCH],\n 0x8800: [DebuggerPDP11.OPS.EMT, DebuggerPDP11.OP_DSTNUM8], // 104000..104377\n 0x8900: [DebuggerPDP11.OPS.TRAP, DebuggerPDP11.OP_DSTNUM8] // 104400..104777\n },\n 0xFFC0: {\n 0x0040: [DebuggerPDP11.OPS.JMP, DebuggerPDP11.OP_DST], // 0001DD\n 0x00C0: [DebuggerPDP11.OPS.SWAB, DebuggerPDP11.OP_DST], // 0003DD\n 0x0A00: [DebuggerPDP11.OPS.CLR, DebuggerPDP11.OP_DST], // 0050DD\n 0x0A40: [DebuggerPDP11.OPS.COM, DebuggerPDP11.OP_DST], // 0051DD\n 0x0A80: [DebuggerPDP11.OPS.INC, DebuggerPDP11.OP_DST], // 0052DD\n 0x0AC0: [DebuggerPDP11.OPS.DEC, DebuggerPDP11.OP_DST], // 0053DD\n 0x0B00: [DebuggerPDP11.OPS.NEG, DebuggerPDP11.OP_DST], // 0054DD\n 0x0B40: [DebuggerPDP11.OPS.ADC, DebuggerPDP11.OP_DST], // 0055DD\n 0x0B80: [DebuggerPDP11.OPS.SBC, DebuggerPDP11.OP_DST], // 0056DD\n 0x0BC0: [DebuggerPDP11.OPS.TST, DebuggerPDP11.OP_DST], // 0057DD\n 0x0C00: [DebuggerPDP11.OPS.ROR, DebuggerPDP11.OP_DST], // 0060DD\n 0x0C40: [DebuggerPDP11.OPS.ROL, DebuggerPDP11.OP_DST], // 0061DD\n 0x0C80: [DebuggerPDP11.OPS.ASR, DebuggerPDP11.OP_DST], // 0062DD\n 0x0CC0: [DebuggerPDP11.OPS.ASL, DebuggerPDP11.OP_DST], // 0063DD\n 0x0D00: [DebuggerPDP11.OPS.MARK, DebuggerPDP11.OP_DSTNUM6], // 0064nn\n 0x0D40: [DebuggerPDP11.OPS.MFPI, DebuggerPDP11.OP_DST], // 0065SS\n 0x0D80: [DebuggerPDP11.OPS.MTPI, DebuggerPDP11.OP_DST], // 0066DD\n 0x0DC0: [DebuggerPDP11.OPS.SXT, DebuggerPDP11.OP_DST], // 0067DD\n 0x8A00: [DebuggerPDP11.OPS.CLRB, DebuggerPDP11.OP_DST], // 1050DD\n 0x8A40: [DebuggerPDP11.OPS.COMB, DebuggerPDP11.OP_DST], // 1051DD\n 0x8A80: [DebuggerPDP11.OPS.INCB, DebuggerPDP11.OP_DST], // 1052DD\n 0x8AC0: [DebuggerPDP11.OPS.DECB, DebuggerPDP11.OP_DST], // 1053DD\n 0x8B00: [DebuggerPDP11.OPS.NEGB, DebuggerPDP11.OP_DST], // 1054DD\n 0x8B40: [DebuggerPDP11.OPS.ADCB, DebuggerPDP11.OP_DST], // 1055DD\n 0x8B80: [DebuggerPDP11.OPS.SBCB, DebuggerPDP11.OP_DST], // 1056DD\n 0x8BC0: [DebuggerPDP11.OPS.TSTB, DebuggerPDP11.OP_DST], // 1057DD\n 0x8C00: [DebuggerPDP11.OPS.RORB, DebuggerPDP11.OP_DST], // 1060DD\n 0x8C40: [DebuggerPDP11.OPS.ROLB, DebuggerPDP11.OP_DST], // 1061DD\n 0x8C80: [DebuggerPDP11.OPS.ASRB, DebuggerPDP11.OP_DST], // 1062DD\n 0x8CC0: [DebuggerPDP11.OPS.ASLB, DebuggerPDP11.OP_DST], // 1063DD\n 0x8D00: [DebuggerPDP11.OPS.MTPS, DebuggerPDP11.OP_DST], // 1064SS (only on LSI-11)\n 0x8D40: [DebuggerPDP11.OPS.MFPD, DebuggerPDP11.OP_DST], // 1065DD (same as MFPI if no separate instruction/data spaces)\n 0x8D80: [DebuggerPDP11.OPS.MTPD, DebuggerPDP11.OP_DST], // 1066DD (same as MTPI if no separate instruction/data spaces)\n 0x8DC0: [DebuggerPDP11.OPS.MFPS, DebuggerPDP11.OP_DST] // 1067SS (only on LSI-11)\n },\n 0xFFF8: {\n 0x0080: [DebuggerPDP11.OPS.RTS, DebuggerPDP11.OP_DSTREG], // 00020R\n 0x0098: [DebuggerPDP11.OPS.SPL, DebuggerPDP11.OP_DSTNUM3] // 00023N\n },\n 0xFFFF: {\n 0x0000: [DebuggerPDP11.OPS.HALT], // 000000\n 0x0001: [DebuggerPDP11.OPS.WAIT], // 000001\n 0x0002: [DebuggerPDP11.OPS.RTI], // 000002\n 0x0003: [DebuggerPDP11.OPS.BPT], // 000003\n 0x0004: [DebuggerPDP11.OPS.IOT], // 000004\n 0x0005: [DebuggerPDP11.OPS.RESET], // 000005\n 0x0006: [DebuggerPDP11.OPS.RTT], // 000006\n 0x0007: [DebuggerPDP11.OPS.MFPT], // 000007 (only on PDP-11/44 & KB11-EM?)\n 0x00A0: [DebuggerPDP11.OPS.NOP],\n 0x00A1: [DebuggerPDP11.OPS.CLC],\n 0x00A2: [DebuggerPDP11.OPS.CLV],\n 0x00A3: [DebuggerPDP11.OPS.CLCV],\n 0x00A4: [DebuggerPDP11.OPS.CLZ],\n 0x00A5: [DebuggerPDP11.OPS.CLCZ],\n 0x00A6: [DebuggerPDP11.OPS.CLVZ],\n 0x00A7: [DebuggerPDP11.OPS.CLCVZ],\n 0x00A8: [DebuggerPDP11.OPS.CLN],\n 0x00A9: [DebuggerPDP11.OPS.CLCN],\n 0x00AA: [DebuggerPDP11.OPS.CLVN],\n 0x00AB: [DebuggerPDP11.OPS.CLCVN],\n 0x00AC: [DebuggerPDP11.OPS.CLZN],\n 0x00AD: [DebuggerPDP11.OPS.CLCZN],\n 0x00AE: [DebuggerPDP11.OPS.CLVZN],\n 0x00AF: [DebuggerPDP11.OPS.CCC], // aka CLCVZN\n 0x00B0: [DebuggerPDP11.OPS.NOP],\n 0x00B1: [DebuggerPDP11.OPS.SEC],\n 0x00B2: [DebuggerPDP11.OPS.SEV],\n 0x00B3: [DebuggerPDP11.OPS.SECV],\n 0x00B4: [DebuggerPDP11.OPS.SEZ],\n 0x00B5: [DebuggerPDP11.OPS.SECZ],\n 0x00B6: [DebuggerPDP11.OPS.SEVZ],\n 0x00B7: [DebuggerPDP11.OPS.SECVZ],\n 0x00B8: [DebuggerPDP11.OPS.SEN],\n 0x00B9: [DebuggerPDP11.OPS.SECN],\n 0x00BA: [DebuggerPDP11.OPS.SEVN],\n 0x00BB: [DebuggerPDP11.OPS.SECVN],\n 0x00BC: [DebuggerPDP11.OPS.SEZN],\n 0x00BD: [DebuggerPDP11.OPS.SECZN],\n 0x00BE: [DebuggerPDP11.OPS.SEVZN],\n 0x00BF: [DebuggerPDP11.OPS.SCC] // aka SECVZN\n }\n };\n\n DebuggerPDP11.OPNONE = [DebuggerPDP11.OPS.NONE];\n\n /*\n * Table of opcodes added to the 11/40 and newer\n */\n DebuggerPDP11.OP1140 = [\n DebuggerPDP11.OPS.MARK,\n DebuggerPDP11.OPS.MFPI,\n DebuggerPDP11.OPS.MTPI,\n DebuggerPDP11.OPS.SXT,\n DebuggerPDP11.OPS.RTT,\n DebuggerPDP11.OPS.MUL,\n DebuggerPDP11.OPS.DIV,\n DebuggerPDP11.OPS.ASH,\n DebuggerPDP11.OPS.ASHC,\n DebuggerPDP11.OPS.XOR,\n DebuggerPDP11.OPS.SOB\n ];\n\n /*\n * Table of opcodes added to the 11/45 and newer\n */\n DebuggerPDP11.OP1145 = [\n DebuggerPDP11.OPS.SPL,\n DebuggerPDP11.OPS.MFPD,\n DebuggerPDP11.OPS.MTPD\n ];\n\n DebuggerPDP11.HISTORY_LIMIT = DEBUG? 100000 : 1000;\n\n DebuggerPDP11.PROMPT = \">> \";\n\n /*\n * Initialize every Debugger module on the page (as IF there's ever going to be more than one ;-))\n */\n Web.onInit(DebuggerPDP11.init);\n\n} // endif DEBUGGER\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/computer.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass ComputerPDP11 extends Component {\n /**\n * ComputerPDP11(parmsComputer, parmsMachine, fSuspended)\n *\n * The ComputerPDP11 component has no required (parmsComputer) properties, but it does\n * support the following:\n *\n * autoPower: true to automatically power the computer (default), false to wait;\n * false is honored only if a \"power\" button binding exists.\n *\n * busWidth: number of memory address lines (address bits) on the computer's \"bus\";\n * 20 is the minimum (and the default), which implies 8086/8088 real-mode addressing,\n * while 24 is required for 80286 protected-mode addressing. This value is passed\n * directly through to the Bus component; see that component for more details.\n *\n * resume: one of the ComputerPDP11.RESUME constants, which are as follows:\n * '0' if resume disabled (default)\n * '1' if enabled without prompting\n * '2' if enabled with prompting\n * '3' if enabled with prompting and auto-delete\n * or a string containing the path of a predefined JSON-encoded state\n *\n * state: the path to JSON-encoded state file (see details regarding 'state' below)\n *\n * The parmsMachine object, if provided, may contain any of:\n *\n * autoMount: if set, this should override any 'autoMount' property in the FDC's\n * parmsFDC object.\n *\n * autoPower: if set, this should override any 'autoPower' property in the ComputerPDP11's\n * parmsComputer object.\n *\n * messages: if set, this should override any 'messages' property in the Debugger's\n * parmsDbg object.\n *\n * state: if set, this should override any 'state' property in the ComputerPDP11's\n * parmsComputer object.\n *\n * url: the location of the machine XML file\n *\n * If a predefined state is supplied AND it's successfully loaded, then resume behavior\n * defaults to '1' (ie, resume enabled without prompting).\n *\n * This component insures that all components are ready before \"powering\" them.\n *\n * Different components become ready at different times, and initialization order (ie,\n * the order the scripts are combined on the page) only partially determines readiness.\n * This is because components like ROM and Video must finish loading their resource files\n * before they are ready. Other components become ready after we call their initBus()\n * function, because they have a Bus or CPU dependency, such as access to memory management\n * functions. And other components, like CPU and Panel, are ready as soon as their\n * constructor finishes.\n *\n * Once a component has indicated it's ready, we call its powerUp() notification\n * function (if it has one--it's optional). We call the CPU's powerUp() function last,\n * so that the CPU is assured that all other components are ready and \"powered\".\n *\n * @this {ComputerPDP11}\n * @param {Object} parmsComputer\n * @param {Object} [parmsMachine]\n * @param {boolean} [fSuspended]\n */\n constructor(parmsComputer, parmsMachine, fSuspended)\n {\n super(\"Computer\", parmsComputer, MessagesPDP11.COMPUTER);\n\n this.flags.powered = false;\n\n this.parmsMachine = null;\n this.setMachineParms(parmsMachine);\n\n this.fAutoPower = this.getMachineParm('autoPower', parmsComputer, Str.TYPES.BOOLEAN);\n\n /*\n * nPowerChange is 0 while the power state is stable, 1 while power is transitioning\n * to \"on\", and -1 while power is transitioning to \"off\".\n */\n this.nPowerChange = 0;\n\n /*\n * TODO: Deprecate 'buswidth' (it should have always used camelCase)\n */\n this.nBusWidth = +parmsComputer['busWidth'] || +parmsComputer['buswidth'];\n\n this.sResumePath = this.sStatePath = null;\n this.sStateData = null;\n this.fStateData = false; // remembers if sStateData was loaded\n this.fServerState = false;\n this.stateComputer = this.stateFailSafe = null;\n this.fInitialized = this.fReload = this.fRestoreError = false;\n\n this.url = /** @type {string} */ (this.getMachineParm('url') || \"\");\n\n /*\n * Generate a random number x (where 0 <= x < 1), add 0.1 so that it's guaranteed to be\n * non-zero, convert to base 36, and chop off the leading digit and \"decimal\" point.\n */\n this.sMachineID = (Math.random() + 0.1).toString(36).substr(2,12);\n this.sUserID = this.queryUserID();\n\n /*\n * Find the appropriate CPU (and Debugger and Control Panel, if any).\n *\n * CLOSURE COMPILER TIP: To override the type of a right-hand expression (as we need to do here,\n * where we know getComponentByType() will only return an CPUState object or null), wrap the expression\n * in parentheses. I never knew this until I stumbled across it in \"Closure: The Definitive Guide\".\n */\n this.cpu = /** @type {CPUStatePDP11} */ (Component.getComponentByType(\"CPU\", this.id));\n if (!this.cpu) {\n Component.error(\"Unable to find CPU component\");\n return;\n }\n this.dbg = /** @type {DebuggerPDP11} */ (Component.getComponentByType(\"Debugger\", this.id));\n\n /*\n * Initialize the Bus component\n */\n this.bus = new BusPDP11({'id': this.idMachine + '.bus', 'busWidth': this.nBusWidth}, this.cpu, this.dbg);\n\n /*\n * Iterate through all the components and connect them to the Control Panel, if any\n */\n var iComponent, component;\n var aComponents = Component.getComponents(this.id);\n\n this.panel = /** @type {PanelPDP11} */ (Component.getComponentByType(\"Panel\", this.id));\n this.controlPrint = this.panel && this.panel.bindings['print'];\n\n if (this.controlPrint) {\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n /*\n * I can think of many \"cleaner\" ways for the Control Panel component to pass its\n * notice(), println(), etc, overrides on to all the other components, but it's just\n * too darn convenient to slam those overrides into the components directly.\n */\n component.notice = this.panel.notice;\n component.print = this.panel.print;\n component.println = this.panel.println;\n }\n }\n\n this.println(PDP11.APPNAME + \" v\" + PDP11.APPVERSION + \"\\n\" + COPYRIGHT + \"\\n\" + LICENSE);\n\n this.println(\"Portions adapted from the PDP-11/70 Emulator by Paul Nankervis <http://skn.noip.me/pdp11/pdp11.html>\");\n\n if (DEBUG && this.messageEnabled()) this.printMessage(\"TYPEDARRAYS: \" + TYPEDARRAYS);\n\n /*\n * Iterate through all the components again and call their initBus() handler, if any\n */\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component.initBus) component.initBus(this, this.bus, this.cpu, this.dbg);\n }\n\n var sStatePath = null;\n var sResume = /** @type {string} */ (this.getMachineParm('resume', parmsComputer));\n if (sResume !== undefined) {\n /*\n * Decide whether the 'resume' property is a number or the path of a state file to resume.\n */\n if (sResume.length > 1) {\n sStatePath = this.sResumePath = sResume;\n } else {\n this.resume = parseInt(sResume, 10);\n }\n }\n\n /*\n * The Computer 'state' property allows a state file to be specified independent of the 'resume' feature;\n * previously, you could only use 'resume' to load a state file -- which we still support, but loading a state\n * file that way prevents the machine's state from being saved, since we always resume from the 'resume' file.\n *\n * The other wrinkle is on the restore side: we need to IGNORE the 'state' property if a saved state now exists.\n * So we have to peek at localStorage, and unfortunately, the only way to \"peek\" is to actually load the data,\n * but we're not ready to use it yet, so powerUp() has been changed to use any existing stateComputer that we've\n * already loaded.\n *\n * However, there's now a wrinkle to the wrinkle: if a 'state' parameter has been passed via the URL, then that\n * OVERRIDES everything; it overrides any 'state' Computer parameter AND it disables resume of any saved state in\n * localStorage (in other words, it prevents fAllowResume from being true, and forcing resume off).\n */\n var fAllowResume;\n var sState = this.getMachineParm('state') || (fAllowResume = true) && parmsComputer['state'];\n\n if (sState) {\n this.sStatePath = sStatePath = sState;\n if (!fAllowResume) {\n this.fServerState = true;\n this.resume = ComputerPDP11.RESUME_NONE;\n }\n if (this.resume) {\n this.stateComputer = new State(this, PDP11.APPVERSION);\n if (this.stateComputer.load()) {\n sStatePath = null;\n } else {\n delete this.stateComputer;\n }\n }\n }\n\n /*\n * If sStatePath is set, we must use it. But if there's no sStatePath AND resume is set,\n * then we have the option of resuming from a server-side state, assuming a valid USERID.\n */\n if (!sStatePath && this.resume) {\n sStatePath = this.getServerStatePath();\n if (sStatePath) this.fServerState = true;\n }\n\n if (!sStatePath) {\n this.setReady();\n } else {\n var cmp = this;\n Web.getResource(sStatePath, null, true, function doneStateLoad(sURL, sResource, nErrorCode) {\n cmp.finishStateLoad(sURL, sResource, nErrorCode);\n });\n }\n\n if (!this.bindings[\"power\"]) this.fAutoPower = true;\n\n /*\n * Power on the computer, giving every component the opportunity to reset or restore itself.\n */\n if (!fSuspended && this.fAutoPower) this.wait(this.powerOn);\n }\n\n /**\n * clearPanel()\n *\n * @this {ComputerPDP11}\n */\n clearPanel()\n {\n if (this.controlPrint) {\n this.controlPrint.value = \"\";\n }\n }\n\n /**\n * getMachineID()\n *\n * @this {ComputerPDP11}\n * @return {string}\n */\n getMachineID()\n {\n return this.sMachineID;\n }\n\n /**\n * setMachineParms(parmsMachine)\n *\n * If no explicit machine parms were provided, then we check for 'parms' in the bundled resources (if any).\n *\n * @this {ComputerPDP11}\n * @param {Object} [parmsMachine]\n */\n setMachineParms(parmsMachine)\n {\n if (!parmsMachine) {\n var sParms;\n if (typeof resources == 'object' && (sParms = resources['parms'])) {\n try {\n parmsMachine = /** @type {Object} */ (eval(\"(\" + sParms + \")\"));\n } catch(e) {\n Component.error(e.message + \" (\" + sParms + \")\");\n }\n }\n }\n this.parmsMachine = parmsMachine;\n }\n\n /**\n * getMachineParm(sParm, parmsComponent, type, defaultValue)\n *\n * If the machine parameter doesn't exist, we check for a matching component parameter\n * (if parmsComponent is provided), and failing that, we check the bundled resources (if any).\n *\n * At the moment, the only bundled resource request we expect to encounter is 'state'; if it exists,\n * then we return 'state' back to the caller (ie, the name of the resource), so that the caller will\n * then attempt to load the 'state' resource to obtain the actual state.\n *\n * TODO: It would be nice if we could tell the Closure Compiler that when a specific type parameter\n * (eg, Str.TYPES.NUMBER) is used, the return value will be that type; unfortunately, every caller\n * must coerce their own return value.\n *\n * @this {ComputerPDP11}\n * @param {string} sParm\n * @param {Object|null} [parmsComponent]\n * @param {number} [type] (from Str.TYPES)\n * @param {*} [defaultValue]\n * @return {*}\n */\n getMachineParm(sParm, parmsComponent, type, defaultValue)\n {\n /*\n * When checking parmsURL, the check is allowed be a bit looser, because URL parameters are\n * user-supplied, whereas most other parameters are developer-supplied. Granted, a developer\n * may also be sloppy and neglect to use correct case (eg, 'automount' instead of 'autoMount'),\n * but there are limits to my paranoia.\n */\n var sParmLC = sParm.toLowerCase();\n var value = Web.getURLParm(sParm) || Web.getURLParm(sParmLC);\n if (value === undefined && this.parmsMachine) value = this.parmsMachine[sParm];\n if (value === undefined && parmsComponent) value = parmsComponent[sParm];\n if (value === undefined && typeof resources == 'object' && resources[sParm]) value = sParm;\n if (value === undefined) value = defaultValue;\n if (typeof value == \"string\" && type) {\n switch(type) {\n case Str.TYPES.NUMBER:\n value = +value;\n if (isNaN(/** @type {number} */(value))) value = defaultValue || 0;\n break;\n case Str.TYPES.BOOLEAN:\n value = (value == \"true\");\n break;\n }\n }\n return value;\n }\n\n /**\n * saveMachineParms()\n *\n * @this {ComputerPDP11}\n * @return {string|null}\n */\n saveMachineParms()\n {\n return this.parmsMachine? JSON.stringify(this.parmsMachine) : null;\n }\n\n /**\n * getUserID()\n *\n * @this {ComputerPDP11}\n * @return {string}\n */\n getUserID()\n {\n return this.sUserID || \"\";\n }\n\n /**\n * finishStateLoad(sURL, sStateData, nErrorCode)\n *\n * @this {ComputerPDP11}\n * @param {string} sURL\n * @param {string} sStateData\n * @param {number} nErrorCode\n */\n finishStateLoad(sURL, sStateData, nErrorCode)\n {\n if (!nErrorCode) {\n this.sStateData = sStateData;\n this.fStateData = true;\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"loaded state file \" + sURL.replace(this.sUserID || \"xxx\", \"xxx\"));\n }\n } else {\n this.sResumePath = null;\n this.fServerState = false;\n this.notice('Unable to load machine state from server (error ' + nErrorCode + (sStateData? ': ' + Str.trim(sStateData) : '') + ')');\n }\n this.setReady();\n }\n\n /**\n * wait(fn, parms)\n *\n * wait() waits until every component is ready (including ourselves, the last component we check), then calls the\n * specified Computer method.\n *\n * TODO: The Closure Compiler makes it difficult for us to define a function type for \"fn\" that works in all cases;\n * sometimes we want to pass a function that takes only a \"number\", and other times we want to pass a function that\n * takes only an \"Array\" (the type will mirror that of the \"parms\" parameter). However, the Closure Compiler insists\n * that both functions must be declared as accepting both types of parameters. So once again, we must use an untyped\n * function declaration, instead of something stricter like:\n *\n * param {function(this:Computer, (number|Array|undefined)): undefined} fn\n *\n * @this {ComputerPDP11}\n * @param {function(...)} fn\n * @param {number|Array} [parms] optional parameters\n */\n wait(fn, parms)\n {\n var computer = this;\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent <= aComponents.length; iComponent++) {\n var component = (iComponent < aComponents.length ? aComponents[iComponent] : this);\n if (!component.isReady()) {\n component.isReady(function onComponentReady() {\n computer.wait(fn, parms);\n });\n return;\n }\n }\n if (DEBUG && this.messageEnabled()) this.printMessage(\"ComputerPDP11.wait(ready)\");\n fn.call(this, parms);\n }\n\n /**\n * validateState(stateComputer)\n *\n * NOTE: We clear() stateValidate only when there's no stateComputer.\n *\n * @this {ComputerPDP11}\n * @param {State|null} [stateComputer]\n * @return {boolean} true if state passes validation, false if not\n */\n validateState(stateComputer)\n {\n var fValid = true;\n var stateValidate = new State(this, PDP11.APPVERSION, ComputerPDP11.STATE_VALIDATE);\n if (stateValidate.load() && stateValidate.parse()) {\n var sTimestampValidate = stateValidate.get(ComputerPDP11.STATE_TIMESTAMP);\n var sTimestampComputer = stateComputer? stateComputer.get(ComputerPDP11.STATE_TIMESTAMP) : \"unknown\";\n if (sTimestampValidate != sTimestampComputer) {\n this.notice(\"Machine state may be out-of-date\\n(\" + sTimestampValidate + \" vs. \" + sTimestampComputer + \")\\nCheck your browser's local storage limits\");\n fValid = false;\n if (!stateComputer) stateValidate.clear();\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"Last state: \" + sTimestampComputer + \" (validate: \" + sTimestampValidate + \")\");\n }\n }\n }\n return fValid;\n }\n\n /**\n * powerOn(resume)\n *\n * Power every component \"up\", applying any previously available state information.\n *\n * @this {ComputerPDP11}\n * @param {number} [resume] is a valid RESUME value; default is this.resume\n */\n powerOn(resume)\n {\n if (resume === undefined) {\n resume = this.resume || (this.sStateData? ComputerPDP11.RESUME_AUTO : ComputerPDP11.RESUME_NONE);\n }\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"ComputerPDP11.powerOn(\" + (resume == ComputerPDP11.RESUME_REPOWER ? \"repower\" : (resume ? \"resume\" : \"\")) + \")\");\n }\n\n if (this.nPowerChange) {\n return;\n }\n this.nPowerChange++;\n\n var fRepower = false;\n var fRestore = false;\n this.fRestoreError = false;\n var stateComputer = this.stateComputer || new State(this, PDP11.APPVERSION);\n\n if (resume == ComputerPDP11.RESUME_REPOWER) {\n fRepower = true;\n }\n else if (resume > ComputerPDP11.RESUME_NONE) {\n if (stateComputer.load(this.sStateData)) {\n /*\n * Since we're resuming something (either a predefined state or a state from localStorage), let's\n * create a \"failsafe\" checkpoint in localStorage, and destroy it at the end of a successful powerOn().\n * Which means, of course, that if a previous \"failsafe\" checkpoint already exists, something bad\n * may have happened the last time around.\n */\n this.stateFailSafe = new State(this, PDP11.APPVERSION, ComputerPDP11.STATE_FAILSAFE);\n if (this.stateFailSafe.load()) {\n this.powerReport(stateComputer);\n /*\n * We already know resume is something other than RESUME_NONE, so we'll go ahead and bump it\n * all the way to RESUME_PROMPT, so that the user will be prompted, and if the user declines to\n * restore, the state will be removed.\n */\n resume = ComputerPDP11.RESUME_PROMPT;\n /*\n * To ensure that the set() below succeeds, we need to call unload(), otherwise it may fail\n * with a \"read only\" error (eg, \"TypeError: Cannot assign to read only property 'timestamp'\").\n */\n this.stateFailSafe.unload();\n }\n\n this.stateFailSafe.set(ComputerPDP11.STATE_TIMESTAMP, Usr.getTimestamp());\n this.stateFailSafe.store();\n\n var fValidate = this.resume && !this.fServerState;\n if (resume == ComputerPDP11.RESUME_AUTO || Component.confirmUser(\"Click OK to restore the previous \" + PDP11.APPNAME + \" machine state, or CANCEL to reset the machine.\")) {\n fRestore = stateComputer.parse();\n if (fRestore) {\n var sCode = /** @type {string} */ (stateComputer.get(UserAPI.RES.CODE));\n var sData = /** @type {string} */ (stateComputer.get(UserAPI.RES.DATA));\n if (sCode) {\n if (sCode == UserAPI.CODE.OK) {\n stateComputer.load(sData);\n } else {\n /*\n * A missing (or not yet created) state file is no cause for alarm, but other errors might be\n */\n if (sCode == UserAPI.CODE.FAIL && sData != UserAPI.FAIL.NOSTATE) {\n this.notice(\"Error: \" + sData);\n if (sData == UserAPI.FAIL.VERIFY) this.resetUserID();\n } else {\n this.println(sCode + \": \" + sData);\n }\n /*\n * Try falling back to the state that we should have saved in localStorage, as a backup to the\n * server-side state.\n */\n stateComputer.unload(); // discard the invalid server-side state first\n if (stateComputer.load()) {\n fRestore = stateComputer.parse();\n fValidate = true;\n } else {\n fRestore = false; // hmmm, there was nothing in localStorage either\n }\n }\n }\n }\n /*\n * If the load/parse was successful, and it was from localStorage (not sStateData),\n * then we should to try verify that localStorage snapshot is current. One reason it may\n * NOT be current is if localStorage was full and we got a quota error during the last\n * powerOff().\n */\n if (fValidate) this.validateState(fRestore? stateComputer : null);\n } else {\n /*\n * RESUME_PROMPT indicates we should delete the state if they clicked Cancel to confirm() above.\n */\n if (resume == ComputerPDP11.RESUME_PROMPT) stateComputer.clear();\n }\n } else {\n /*\n * If there's no state, then there should also be no validation timestamp; if there is, then once again,\n * we're probably dealing with a quota error.\n */\n this.validateState();\n }\n delete this.sStateData;\n delete this.stateComputer;\n }\n\n /*\n * Start powering all components, including any data they may need to restore their state;\n * we restore power to the CPU last.\n */\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component !== this && component != this.cpu) {\n fRestore = this.powerRestore(component, stateComputer, fRepower, fRestore);\n }\n }\n\n /*\n * Assuming this is not a repower, we must perform another wait, because some components may\n * have marked themselves as \"not ready\" again (eg, the FDC component, if the restore forced it\n * to mount one or more additional disk images).\n */\n var aParms = [stateComputer, resume, fRestore];\n\n if (resume != ComputerPDP11.RESUME_REPOWER) {\n this.wait(this.donePowerOn, aParms);\n return;\n }\n this.donePowerOn(aParms);\n }\n\n /**\n * powerRestore(component, stateComputer, fRepower, fRestore)\n *\n * @this {ComputerPDP11}\n * @param {Component} component\n * @param {State} stateComputer\n * @param {boolean} fRepower\n * @param {boolean} fRestore\n * @return {boolean} true if restore should continue, false if not\n */\n powerRestore(component, stateComputer, fRepower, fRestore)\n {\n if (!component.flags.powered) {\n\n /*\n * TODO: If all components called super.powerUp(), the powered flag would be set automatically.\n */\n\n component.flags.powered = true;\n\n var data = null;\n\n try {\n if (fRestore) {\n data = stateComputer.get(component.id);\n if (!data) {\n /*\n * This is a hack that makes it possible for a machine whose ID has been\n * supplemented with a hyphenated numeric suffix to find object IDs in states\n * created from a machine without such a suffix.\n *\n * For example, if a state file was created from a machine with ID \"ibm5160\"\n * but the current machine is \"ibm5160-1\", this attempts a second lookup with\n * \"ibm5160\", enabling us to find objects that match the original machine ID\n * (eg, \"ibm5160.romEGA\").\n *\n * See /devices/pcx86/machine/5160/ega/640kb/array/ for examples of this.\n */\n data = stateComputer.get(component.id.replace(/-[0-9]+\\./i, '.'));\n }\n }\n\n /*\n * State.get() will return whatever was originally passed to State.set() (eg, an\n * Object or a string), but components are supposed to store only Objects, so if a\n * string comes back, something went wrong. By explicitly eliminating \"string\" data,\n * the Closure Compiler stops complaining that we might be passing strings to our\n * powerUp() functions (even though we know we're not).\n *\n * TODO: Determine if there's some way to coerce the Closure Compiler into treating\n * data as Object or null, without having to include this runtime check. An assert\n * would be a good idea, but this is overkill.\n */\n if (typeof data === \"string\") data = null;\n\n /*\n * If computer is null, this is simply a repower notification, which most components\n * don't do anything with. Exceptions include: CPU (since it may be halted) and Video\n * (since its screen may be \"turned off\").\n */\n if (!component.powerUp(data, fRepower) && data) {\n\n Component.error(\"Unable to restore state for \" + component.type);\n /*\n * If this is a resume error for a machine that also has a predefined state\n * AND we're not restoring from that state, then throw away the current state,\n * prevent any new state from being created, and then force a reload, which will\n * hopefully restore us to the functioning predefined state.\n *\n * TODO: Considering doing this in ALL cases, not just in situations where a\n * 'state' exists but we're not actually resuming from it.\n */\n if (this.sStatePath && !this.fStateData) {\n stateComputer.clear();\n this.resume = ComputerPDP11.RESUME_NONE;\n Web.reloadPage();\n } else {\n /*\n * In all other cases, we set fRestoreError, which should trigger a call to\n * powerReport() and then delete the offending state.\n */\n this.fRestoreError = true;\n }\n /*\n * Any failure triggers an automatic to call powerUp() again, without any state,\n * in the hopes that the component can recover by performing a reset.\n */\n component.powerUp(null);\n /*\n * We also disable the rest of the restore operation, because it's not clear\n * the remaining state information can be trusted; the machine is already in an\n * inconsistent state, so we're not likely to make things worse, and the only\n * alternative (starting over and performing a state-less reset) isn't likely to make\n * the user any happier. But, we'll see... we need some experience with the code.\n */\n fRestore = false;\n }\n\n if (!fRepower && component.comment) {\n var asComments = component.comment.split(\"|\");\n for (var i = 0; i < asComments.length; i++) {\n component.status(asComments[i]);\n }\n }\n }\n catch (err) {\n Component.error(\"Error restoring state for \" + component.type + \" (\" + err.message + \")\");\n }\n }\n return fRestore;\n }\n\n /**\n * donePowerOn(aParms)\n *\n * This is nothing more than a continuation of powerOn(), giving us the option of calling wait() one more time.\n *\n * @this {ComputerPDP11}\n * @param {Array} aParms containing [stateComputer, resume, fRestore]\n */\n donePowerOn(aParms)\n {\n var stateComputer = aParms[0];\n var fRepower = (aParms[1] < 0);\n var fRestore = aParms[2];\n\n if (DEBUG && this.flags.powered && this.messageEnabled()) {\n this.printMessage(\"ComputerPDP11.donePowerOn(): redundant\");\n }\n\n this.fInitialized = true;\n this.flags.powered = true;\n var controlPower = this.bindings[\"power\"];\n if (controlPower) controlPower.textContent = \"Shutdown\";\n\n /*\n * Once we get to this point, we're guaranteed that all components are ready, so it's safe to power the CPU;\n * the CPU should begin executing immediately, unless a debugger is attached.\n */\n if (this.cpu) {\n /*\n * TODO: Do we not care about the return value here? (ie, is checking fRestoreError sufficient)?\n */\n this.powerRestore(this.cpu, stateComputer, fRepower, fRestore);\n this.updateDisplays(-2);\n this.cpu.autoStart();\n }\n\n /*\n * If the state was bad, offer to report it and then delete it. Deleting may be moot, since invariably a new\n * state will be created on powerOff() before the next powerOn(), but it seems like good paranoia all the same.\n */\n if (this.fRestoreError) {\n this.powerReport(stateComputer);\n stateComputer.clear();\n }\n\n if (!fRepower && this.stateFailSafe) {\n this.stateFailSafe.clear();\n delete this.stateFailSafe;\n }\n\n this.nPowerChange = 0;\n }\n\n /**\n * checkPower()\n *\n * @this {ComputerPDP11}\n * @return {boolean} true if the computer is fully powered, false otherwise\n */\n checkPower()\n {\n if (this.flags.powered) return true;\n\n var component = null, iComponent;\n var aComponents = Component.getComponents(this.id);\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component !== this && !component.flags.ready) break;\n }\n if (iComponent == aComponents.length) {\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component !== this && !component.flags.powered) break;\n }\n }\n if (iComponent == aComponents.length) component = this;\n var s = \"The \" + component.type + \" component (\" + component.id + \") is not \" + (!component.flags.ready? \"ready yet\" + (component.fnReady? \" (waiting for notification)\" : \"\") : \"powered yet\") + \".\";\n Component.alertUser(s);\n return false;\n }\n\n /**\n * powerReport(stateComputer)\n *\n * @this {ComputerPDP11}\n * @param {State} stateComputer\n */\n powerReport(stateComputer)\n {\n if (Component.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 + \".\")) {\n Web.sendReport(PDP11.APPNAME, PDP11.APPVERSION, this.url, this.getUserID(), ReportAPI.TYPE.BUG, stateComputer.toString());\n }\n }\n\n /**\n * powerOff(fSave, fShutdown)\n *\n * Power every component \"down\" and optionally save the machine state.\n *\n * There's one scenario that powerOff() isn't currently able to deal with very effectively: what to do when\n * the user switches away while it's still being restored, causing Disk getResource() calls to fail. The\n * Disk component calls notify() when that happens -- see Disk.mount() -- but the FDC and HDC controllers don't\n * notify *us* of those problems, so Computer assumes that the restore was completely successful, when in fact\n * it was only partially successful.\n *\n * Then we immediately arrive here to perform a save, following that incomplete restore. It would be wrong to\n * deal with that incomplete restore by setting fRestoreError, because we don't want to trigger a powerReport()\n * and the deletion of the previous state, because the state itself was presumably OK. Unfortunately, the new\n * state we now save will no longer include manually mounted disk images whose remounts were interrupted, so future\n * restores won't remount them either.\n *\n * We could perhaps solve this by having the Disk component notify us in those situations, set a new flag\n * (fRestoreIncomplete?), and set fSave to false if that's ever set. Be careful though: when fSave is false,\n * that means MORE than not saving; it also means deleting any previous state, which is NOT what you'd want to\n * do in a \"fRestoreIncomplete\" situation. Also, we have to worry about Disk operations that fail for other reasons,\n * making sure those failures don't interfere with the save process in the same way.\n *\n * As it stands, the worst that happens is any manually mounted disk images might have to be manually remounted,\n * which doesn't seem like a huge problem.\n *\n * @this {ComputerPDP11}\n * @param {boolean} [fSave] is true to request a saved state\n * @param {boolean} [fShutdown] is true if the machine is being shut down\n * @return {string|null} string representing the saved state (or null if error)\n */\n powerOff(fSave, fShutdown)\n {\n var data;\n var sState = \"none\";\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"ComputerPDP11.powerOff(\" + (fSave ? \"save\" : \"nosave\") + (fShutdown ? \",shutdown\" : \"\") + \")\");\n }\n\n if (this.nPowerChange) {\n return null;\n }\n this.nPowerChange--;\n\n var stateComputer = new State(this, PDP11.APPVERSION);\n var stateValidate = new State(this, PDP11.APPVERSION, ComputerPDP11.STATE_VALIDATE);\n\n var sTimestamp = Usr.getTimestamp();\n stateValidate.set(ComputerPDP11.STATE_TIMESTAMP, sTimestamp);\n stateComputer.set(ComputerPDP11.STATE_TIMESTAMP, sTimestamp);\n stateComputer.set(ComputerPDP11.STATE_VERSION, APPVERSION);\n stateComputer.set(ComputerPDP11.STATE_HOSTURL, Web.getHostURL());\n stateComputer.set(ComputerPDP11.STATE_BROWSER, Web.getUserAgent());\n\n /*\n * Always power the CPU \"down\" first, just to help insure it doesn't ask other components to do anything\n * after they're no longer ready.\n */\n if (this.cpu && this.cpu.powerDown) {\n if (fShutdown) {\n if (fSave) this.cpu.flags.autoStart = this.cpu.flags.running;\n this.cpu.stopCPU();\n }\n data = this.cpu.powerDown(fSave, fShutdown);\n if (typeof data === \"object\") stateComputer.set(this.cpu.id, data);\n if (fShutdown) {\n this.cpu.flags.powered = false;\n if (data === false) sState = null;\n }\n }\n\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.flags.powered) {\n if (component.powerDown) {\n data = component.powerDown(fSave, fShutdown);\n if (typeof data === \"object\") stateComputer.set(component.id, data);\n }\n if (fShutdown) {\n component.flags.powered = false;\n if (data === false) sState = null;\n }\n }\n }\n\n if (sState) {\n if (fShutdown) {\n var fClear = false;\n var fClearAll = false;\n if (fSave) {\n if (this.sUserID) {\n this.saveServerState(this.sUserID, stateComputer.toString());\n }\n if (!stateValidate.store() || !stateComputer.store()) {\n sState = null;\n /*\n * New behavior as of v1.13.2: if it appears that localStorage is full, we blow it ALL away.\n * Dedicated server-side storage is the only way we'll ever be able to reliably preserve a\n * particular machine's state. Historically, attempting to limp along with whatever localStorage\n * is left just generates the same useless and annoying warnings over and over.\n */\n fClear = fClearAll = true;\n }\n }\n else {\n /*\n * I used to ALWAYS clear (ie, delete) any associated computer state, but now I do this only if the\n * current machine is \"resumable\", because there are situations where I have two configurations\n * for the same machine -- one resumable and one not -- and I don't want the latter throwing away the\n * state of the former.\n *\n * So this code is here now strictly for callers to delete the state of a \"resumable\" machine, not as\n * some paranoid clean-up operation.\n *\n * An undocumented feature of this operation is that if your configuration uses the special 'resume=\"3\"'\n * value, and you click the \"Reset\" button, and then you click OK to reset the everything, this will\n * actually reset EVERYTHING (ie, all localStorage for ALL configs will be reclaimed).\n */\n if (this.resume) {\n fClear = true;\n fClearAll = (this.resume == ComputerPDP11.RESUME_DELETE);\n }\n }\n if (fClear) {\n stateComputer.clear(fClearAll);\n }\n } else {\n sState = stateComputer.toString();\n }\n }\n\n if (fShutdown) {\n this.flags.powered = false;\n var controlPower = this.bindings[\"power\"];\n if (controlPower) controlPower.textContent = \"Power\";\n }\n\n this.nPowerChange = 0;\n\n return sState;\n }\n\n /**\n * reset()\n *\n * Notify all (other) components with a reset() method that the Computer is being reset.\n *\n * NOTE: We'd like to reset the Bus first (due to the importance of the A20 line), but since we\n * allocated the Bus object ourselves, after all the other components were allocated, it ends\n * up near the end of Component's list of components. Hence the special case for this.bus below.\n *\n * Ditto for the CPU, in part because if the Front Panel resets before the CPU, it will end up\n * snapping/displaying the PC as of the last instruction executed, before the CPU resets the PC,\n * causing the Front Panel to display a stale address when we call updateDisplays() at the end.\n *\n * @this {ComputerPDP11}\n */\n reset()\n {\n this.flags.reset = true;\n if (this.bus && this.bus.reset) {\n this.printMessage(\"Resetting \" + this.bus.type);\n this.bus.reset();\n }\n if (this.cpu && this.cpu.reset) {\n this.printMessage(\"Resetting \" + this.cpu.type);\n this.cpu.reset();\n }\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component !== this && component !== this.bus && component !== this.cpu && component.reset) {\n this.printMessage(\"Resetting \" + component.type);\n component.reset();\n }\n }\n this.flags.reset = false;\n this.updateDisplays(-1);\n }\n\n /**\n * start(ms, nCycles)\n *\n * Notify all (other) components with a start() method that the CPU has started.\n *\n * Note that we're called by startCPU(), which is why we exclude the CPU component,\n * as well as ourselves.\n *\n * @this {ComputerPDP11}\n * @param {number} ms\n * @param {number} nCycles\n */\n start(ms, nCycles)\n {\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.type == \"CPU\" || component === this) continue;\n if (component.start) {\n component.start(ms, nCycles);\n }\n }\n this.updateDisplays(-1);\n }\n\n /**\n * stop(ms, nCycles)\n *\n * Notify all (other) components with a stop() method that the CPU has stopped.\n *\n * Note that we're called by stopCPU(), which is why we exclude the CPU component,\n * as well as ourselves.\n *\n * @this {ComputerPDP11}\n * @param {number} ms\n * @param {number} nCycles\n */\n stop(ms, nCycles)\n {\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.type == \"CPU\" || component === this) continue;\n if (component.stop) {\n component.stop(ms, nCycles);\n }\n }\n this.updateDisplays(-1);\n }\n\n /**\n * updateDisplays(nUpdate)\n *\n * TODO: Notify all components with an updateDisplay() method that the computer's state has changed (not\n * just the hard-coded ones below).\n *\n * If any DOM controls were bound to the CPU, then we need to call its updateDisplay() handler; if there are no\n * such bindings, then cpu.updateDisplay() does nothing.\n *\n * Similarly, if there's a Panel, then we need to call its updateDisplay() handler, in case it created its own canvas\n * and implemented its own register display (eg, dumpRegisters()); if not, then panel.updateDisplay() also does nothing.\n *\n * In practice, there will *either* be a Panel with a custom canvas *or* a set of DOM controls bound to the CPU *or*\n * neither. In theory, there could be BOTH, but that would be unusual.\n *\n * TODO: Consider alternate approaches to these largely register-oriented display updates. Ordinarily, we like to\n * separate logic from presentation, and currently the CPUState contains both, since it's the component that intimately\n * knows the names, number, sizes, etc, of all the active registers. The Panel component is the logical candidate,\n * but Panel is an optional component; it's often the case that only machines that include the Debugger also include\n * Panel.\n *\n * @this {ComputerPDP11}\n * @param {number} [nUpdate] (1 for periodic, -1 for forced, 0 or undefined otherwise)\n */\n updateDisplays(nUpdate)\n {\n /*\n * nUpdate is generally set to -1 whenever the CPU is transitioning to/from a running state, in which case\n * cpu.updateDisplay() will definitely want to hide/show register contents; however, at other times, when the\n * CPU is running, constantly updating the DOM controls too frequently can adversely impact overall performance.\n *\n * nUpdate will also be -1 whenever the Debugger has modified the state of the machine, implying that we're\n * not sure what, if anything, actually changed.\n */\n if (this.cpu) this.cpu.updateDisplay(nUpdate || 0);\n if (this.panel) this.panel.updateDisplay(nUpdate || 0);\n }\n\n /**\n * setBinding(sType, sBinding, control, sValue)\n *\n * @this {ComputerPDP11}\n * @param {string|null} sType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sType, sBinding, control, sValue)\n {\n var computer = this;\n\n switch (sBinding) {\n case \"power\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickPower() {\n computer.onPower();\n };\n return true;\n\n case \"reset\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickReset() {\n computer.onReset();\n };\n return true;\n\n /*\n * Technically, this binding should now be called \"saveState\", to clearly distinguish it from\n * the \"Save Machine\" control that's normally bound to the savePC() function in save.js. Saving\n * an entire machine includes everything needed to start/restore the machine; eg, the machine\n * XML configuration file(s) *and* the JSON-encoded machine state.\n */\n case \"save\":\n /*\n * Since this feature depends on the server supporting the PCjs User API (see userapi.js),\n * and since pcjs.org is no longer running a Node web server, we disable the feature for that\n * particular host.\n */\n if (Str.endsWith(Web.getHost(), \"pcjs.org\")) {\n if (DEBUG) this.log(\"Remote user API not available\");\n /*\n * We could also simply hide the control; eg:\n *\n * control.style.display = \"none\";\n *\n * but removing the control altogether seems better.\n */\n control.parentNode.removeChild(/** @type {Node} */ (control));\n return false;\n }\n this.bindings[sBinding] = control;\n control.onclick = function onClickSave() {\n var sUserID = computer.queryUserID(true);\n if (sUserID) {\n /*\n * I modified the test to include a check for sStatePath so that I could save new states\n * for machines with existing states; otherwise, I'd have no (easy) way of capturing and\n * updating their state. Making the machine (even temporarily) resumable would have been\n * one work-around, but it's not appropriate for some machines, as their state is simply\n * too large (for localStorage anyway, which is the default storage solution).\n */\n var fSave = !!(computer.resume && !computer.sResumePath || computer.sStatePath);\n var sState = computer.powerOff(fSave);\n if (fSave) {\n computer.saveServerState(sUserID, sState);\n } else {\n computer.notice(\"Resume disabled, machine state not saved\");\n }\n }\n /*\n * This seemed like a handy alternative, but it turned out to be a no-go, at least for large states:\n *\n * var sState = computer.powerOff(true);\n * if (sState) {\n * sState = \"data:text/json;charset=utf-8,\" + encodeURIComponent(sState);\n * window.open(sState);\n * }\n *\n * Perhaps if I embedded the data in a link on the current page instead; eg:\n *\n * $('<a href=\"' + sState + '\" download=\"state.json\">Download</a>').appendTo('#container');\n */\n };\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * resetUserID()\n *\n * @this {ComputerPDP11}\n */\n resetUserID()\n {\n Web.setLocalStorageItem(ComputerPDP11.STATE_USERID, \"\");\n this.sUserID = null;\n }\n\n /**\n * queryUserID(fPrompt)\n *\n * @this {ComputerPDP11}\n * @param {boolean} [fPrompt]\n * @returns {string|null|undefined}\n */\n queryUserID(fPrompt)\n {\n var sUserID = this.sUserID;\n if (!sUserID) {\n sUserID = Web.getLocalStorageItem(ComputerPDP11.STATE_USERID);\n if (sUserID !== undefined) {\n if (!sUserID && fPrompt) {\n /*\n * NOTE: Warning the user here that \"Save\" operations are not currently supported by pcjs.org is\n * merely a precaution, because ordinarily, setBinding() should have already determined if we are\n * running from pcjs.org and disabled any \"Save\" button.\n */\n sUserID = Component.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.\");\n if (sUserID) {\n sUserID = this.verifyUserID(sUserID);\n if (!sUserID) this.notice(\"The user ID is invalid.\");\n }\n }\n } else if (fPrompt) {\n this.notice(\"Browser local storage is not available\");\n }\n }\n return sUserID;\n }\n\n /**\n * verifyUserID(sUserID)\n *\n * @this {ComputerPDP11}\n * @param {string} sUserID\n * @return {string} validated user ID, or null if error\n */\n verifyUserID(sUserID)\n {\n this.sUserID = null;\n var fMessages = DEBUG && this.messageEnabled();\n if (fMessages) this.printMessage(\"verifyUserID(\" + sUserID + \")\");\n var sRequest = Web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.VERIFY + '&' + UserAPI.QUERY.USER + '=' + sUserID;\n var response = Web.getResource(sRequest);\n var nErrorCode = response[0];\n var sResponse = response[1];\n if (!nErrorCode && sResponse) {\n try {\n response = eval(\"(\" + sResponse + \")\");\n if (response.code && response.code == UserAPI.CODE.OK) {\n Web.setLocalStorageItem(ComputerPDP11.STATE_USERID, response.data);\n if (fMessages) this.printMessage(ComputerPDP11.STATE_USERID + \" updated: \" + response.data);\n this.sUserID = response.data;\n } else {\n if (fMessages) this.printMessage(response.code + \": \" + response.data);\n }\n } catch (e) {\n Component.error(e.message + \" (\" + sResponse + \")\");\n }\n } else {\n if (fMessages) this.printMessage(\"invalid response (error \" + nErrorCode + \")\");\n }\n return this.sUserID;\n }\n\n /**\n * getServerStatePath()\n *\n * @this {ComputerPDP11}\n * @return {string|null} sStatePath (null if no localStorage or no USERID stored in localStorage)\n */\n getServerStatePath()\n {\n var sStatePath = null;\n if (this.sUserID) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(ComputerPDP11.STATE_USERID + \" for load: \" + this.sUserID);\n }\n sStatePath = Web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.LOAD + '&' + UserAPI.QUERY.USER + '=' + this.sUserID + '&' + UserAPI.QUERY.STATE + '=' + State.key(this, PDP11.APPVERSION);\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(ComputerPDP11.STATE_USERID + \" unavailable\");\n }\n }\n return sStatePath;\n }\n\n /**\n * saveServerState(sUserID, sState)\n *\n * @this {ComputerPDP11}\n * @param {string} sUserID\n * @param {string|null} sState\n */\n saveServerState(sUserID, sState)\n {\n /*\n * We must pass fSync == true, because (as I understand it) browsers will blow off any async\n * requests when a page is being closed. Since our request is synchronous, storeServerState()\n * should also return a result, but there's not much we can do with it, since browsers ALSO\n * tend to blow off alerts() and the like when closing down.\n */\n if (sState) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"size of server state: \" + sState.length + \" bytes\");\n }\n var response = this.storeServerState(sUserID, sState, true);\n if (response && response[UserAPI.RES.CODE] == UserAPI.CODE.OK) {\n this.notice(\"Machine state saved to server\");\n } else if (sState) {\n var sError = (response && response[UserAPI.RES.DATA]) || UserAPI.FAIL.BADSTORE;\n if (response[UserAPI.RES.CODE] == UserAPI.CODE.FAIL) {\n sError = \"Error: \" + sError;\n } else {\n sError = \"Error \" + response[UserAPI.RES.CODE] + \": \" + sError;\n }\n this.notice(sError);\n this.resetUserID();\n }\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"no state to store\");\n }\n }\n }\n\n /**\n * storeServerState(sUserID, sState, fSync)\n *\n * @this {ComputerPDP11}\n * @param {string} sUserID\n * @param {string} sState\n * @param {boolean} [fSync] is true if we're powering down and should perform a synchronous request (default is async)\n * @return {*} server response if fSync is true and a response was received; otherwise null\n */\n storeServerState(sUserID, sState, fSync)\n {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(ComputerPDP11.STATE_USERID + \" for store: \" + sUserID);\n }\n /*\n * TODO: Determine whether or not any browsers cancel our request if we're called during a browser \"shutdown\" event,\n * and whether or not it matters if we do an async request (currently, we're not, to try to ensure the request goes through).\n */\n var dataPost = {};\n dataPost[UserAPI.QUERY.REQ] = UserAPI.REQ.STORE;\n dataPost[UserAPI.QUERY.USER] = sUserID;\n dataPost[UserAPI.QUERY.STATE] = State.key(this, PDP11.APPVERSION);\n dataPost[UserAPI.QUERY.DATA] = sState;\n var sRequest = Web.getHost() + UserAPI.ENDPOINT;\n if (!fSync) {\n Web.getResource(sRequest, dataPost, true);\n } else {\n var response = Web.getResource(sRequest, dataPost);\n var sResponse = response[0];\n if (response[1]) {\n if (sResponse) {\n var i = sResponse.indexOf('\\n');\n if (i > 0) sResponse = sResponse.substr(0, i);\n if (!sResponse.indexOf(\"Error: \")) sResponse = sResponse.substr(7);\n }\n sResponse = '{\"' + UserAPI.RES.CODE + '\":' + response[1] + ',\"' + UserAPI.RES.DATA + '\":\"' + sResponse + '\"}';\n }\n if (DEBUG && this.messageEnabled()) this.printMessage(sResponse);\n return JSON.parse(sResponse);\n }\n return null;\n }\n\n /**\n * onPower()\n *\n * This handles UI requests to toggle the computer's power (eg, see the \"power\" button binding).\n *\n * @this {ComputerPDP11}\n */\n onPower()\n {\n if (!this.nPowerChange) {\n if (!this.flags.powered) {\n this.wait(this.powerOn);\n } else {\n this.powerOff(false, true);\n }\n }\n }\n\n /**\n * onReset()\n *\n * This handles UI requests to reset the computer's state (eg, see the \"reset\" button binding).\n *\n * @this {ComputerPDP11}\n */\n onReset()\n {\n /*\n * I'm going to start with the presumption that it makes little sense for an \"unpowered\" computer to be \"reset\";\n * ditto if the power state is currently being changed.\n */\n if (!this.flags.powered || this.nPowerChange) return;\n\n /*\n * If this is a \"resumable\" machine (and it's not using a predefined state), then we overload the reset\n * operation to offer an explicit \"save or discard\" option first. This is currently the only UI we offer to\n * discard a machine's state, including any disk changes. The traditional \"reset\" operation is still available\n * for non-resumable machines.\n *\n * TODO: Break this behavior out into a separate \"discard\" operation, in case the designer of the machine really\n * wants to clutter the UI with confusing options. ;-)\n */\n if (this.resume && !this.sResumePath) {\n /*\n * I used to bypass the prompt if this.resume == ComputerPDP11.RESUME_AUTO, setting fSave to true automatically,\n * but that gives the user no means of resetting a resumable machine that contains errors in its resume state.\n */\n var fSave = (/* this.resume == ComputerPDP11.RESUME_AUTO || */ Component.confirmUser(\"Click OK to save changes to this \" + PDP11.APPNAME + \" machine.\\n\\nWARNING: If you CANCEL, all disk changes will be discarded.\"));\n this.powerOff(fSave, true);\n /*\n * Forcing the page to reload is an expedient option, but ugly. It's preferable to call powerOn()\n * and rely on all the components to reset themselves to their default state. The components with\n * the greatest burden here are FDC and HDC, which must rely on the fReload flag to determine whether\n * or not to unload/reload all their original auto-mounted disk images.\n *\n * However, if we started with a predefined state (ie, sStatePath is set), we take this shortcut, because\n * we don't (yet) have code in place to gracefully reload the initial state (requires calling getResource()\n * again); alternatively, we could avoid throwing that state away, but it seems better to save the memory.\n *\n * TODO: Make this more graceful, so that we can stop using the reloadPage() sledgehammer.\n */\n if (!fSave && this.sStatePath) {\n Web.reloadPage();\n return;\n }\n if (!fSave) this.fReload = true;\n this.powerOn(ComputerPDP11.RESUME_NONE);\n this.fReload = false;\n } else {\n this.reset();\n if (this.cpu && !this.dbg) this.cpu.autoStart();\n }\n }\n\n /**\n * getMachineComponent(sType, componentPrev)\n *\n * @this {ComputerPDP11}\n * @param {string} sType\n * @param {Component|null} [componentPrev] of previously returned component, if any\n * @return {Component|null}\n */\n getMachineComponent(sType, componentPrev)\n {\n var componentLast = componentPrev;\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (componentPrev) {\n if (componentPrev == component) componentPrev = null;\n continue;\n }\n if (component.type == sType) return component;\n }\n if (!componentLast) Component.log(\"Machine component type '\" + sType + \"' not found\", \"warning\");\n return null;\n }\n\n /**\n * setFocus(fScroll)\n *\n * NOTE: When soft keyboard buttons call us to return focus to the machine (and away from the button),\n * the browser's default behavior is to scroll the element into view, which can be annoying, especially on iOS,\n * where the display is more constrained, so we no longer do it by default (fScroll must be true).\n *\n * @this {ComputerPDP11}\n * @param {boolean} [fScroll] (true if you really want the control scrolled into view)\n */\n setFocus(fScroll)\n {\n if (this.controlPrint) {\n /*\n * This seems to be recommended work-around to prevent the browser from scrolling the focused element\n * into view. The CPU is not a visual component, so when the CPU wants to set focus, the primary intent\n * is to ensure that keyboard input is fielded properly.\n */\n var x = 0, y = 0;\n if (!fScroll && window) {\n x = window.scrollX;\n y = window.scrollY;\n }\n\n this.controlPrint.focus();\n\n if (!fScroll && window) {\n window.scrollTo(x, y);\n }\n }\n }\n\n /**\n * ComputerPDP11.init()\n *\n * For every machine represented by an HTML element of class \"pdp11-machine\", this function\n * locates the HTML element of class \"computer\", extracting the JSON-encoded parameters for the\n * Computer constructor from the element's \"data-value\" attribute, invoking the constructor to\n * create a Computer component, and then binding any associated HTML controls to the new component.\n */\n static init()\n {\n /*\n * In non-COMPILED builds, embedMachine() may have set XMLVERSION.\n */\n if (!COMPILED && XMLVERSION) PDP11.APPVERSION = XMLVERSION;\n\n var aeMachines = Component.getElementsByClass(document, PDP11.APPCLASS + \"-machine\");\n\n for (var iMachine = 0; iMachine < aeMachines.length; iMachine++) {\n\n var eMachine = aeMachines[iMachine];\n var parmsMachine = Component.getComponentParms(eMachine);\n\n var aeComputers = Component.getElementsByClass(eMachine, PDP11.APPCLASS, \"computer\");\n\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n\n /*\n * We set fSuspended in the Computer constructor because we want to \"power up\" the\n * computer ourselves, after any/all bindings are in place.\n */\n var computer = new ComputerPDP11(parmsComputer, parmsMachine, true);\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onInit(\" + computer.flags.powered + \")\");\n }\n\n /*\n * Bind any \"power\", \"reset\" and \"save\" buttons. An \"erase\" button was also considered,\n * but \"reset\" now provides a way to force the machine to start from scratch again, so \"erase\"\n * may be redundant now.\n */\n Component.bindComponentControls(computer, eComputer, PDP11.APPCLASS);\n\n /*\n * Power on the computer, giving every component the opportunity to reset or restore itself.\n */\n if (computer.fAutoPower) computer.wait(computer.powerOn);\n }\n }\n }\n\n /**\n * ComputerPDP11.show()\n *\n * When exit() is using an \"onbeforeunload\" handler, this \"onpageshow\" handler allows us to repower everything,\n * without either resetting or restoring. We call powerOn() with a special resume value (RESUME_REPOWER) if the\n * computer is already marked as \"ready\", meaning the browser didn't change anything. This \"repower\" process\n * should be very quick, essentially just marking all components as powered again (so that, for example, the Video\n * component will start drawing again) and firing the CPU up again.\n */\n static show()\n {\n var aeComputers = Component.getElementsByClass(document, PDP11.APPCLASS, \"computer\");\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n var computer = /** @type {ComputerPDP11} */ (Component.getComponentByType(\"Computer\", parmsComputer['id']));\n if (computer) {\n\n computer.flags.unloading = false;\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onShow(\" + computer.fInitialized + \",\" + computer.flags.powered + \")\");\n }\n\n /*\n * Note that the FIRST 'onpageshow' event, and therefore the first show() callback, occurs\n * AFTER the the initial 'onload' event, and at that point in time, fInitialized will not be set yet.\n * So, practically speaking, the first show() callback isn't all that useful.\n */\n if (computer.fInitialized && !computer.flags.powered) {\n /**\n * Repower the computer, notifying every component to continue running as-is.\n */\n computer.powerOn(ComputerPDP11.RESUME_REPOWER);\n }\n }\n }\n }\n\n /**\n * ComputerPDP11.exit()\n *\n * The Computer is currently the only component that uses an \"exit\" handler, which Web.onExit() defines as\n * either an \"unload\" or \"onbeforeunload\" handler. This gives us the opportunity to save the machine state,\n * using our powerOff() function, before the page goes away.\n *\n * It's worth noting that \"onbeforeunload\" offers one nice feature when used instead of \"onload\": the entire\n * page (and therefore this entire application) is retained in its current state by the browser (well, some\n * browsers), so that if you go to a new URL, either by entering a new URL in the same window/tab, or by pressing\n * the FORWARD button, and then you press the BACK button, the page is immediately restored to its previous state.\n *\n * In fact, that's how some browsers operate whether you have an \"onbeforeunload\" handler or not; in other words,\n * an \"onbeforeunload\" handler doesn't change the page retention behavior of the browser. By contrast, the mere\n * presence of an \"onunload\" handler generally causes a browser to throw the page away once the handler returns.\n *\n * However, in order to safely use \"onbeforeunload\", we must add yet another handler (\"onpageshow\") to repower\n * everything, without either resetting or restoring. Hence, the ComputerPDP11.show() function, which calls powerOn()\n * with a special resume value (RESUME_REPOWER) if the computer is already marked as \"ready\", meaning the browser\n * didn't change anything. This \"repower\" process should be very quick, essentially just marking all components as\n * powered again (so that, for example, the Video component will start drawing again) and firing the CPU up again.\n *\n * Reportedly, some browsers (eg, Opera) don't support \"onbeforeunload\", in which case Component will have to use\n * \"unload\" instead. But even when the page must be rebuilt from scratch, the combination of browser cache and\n * localStorage means the simulation should be restored and become operational almost immediately.\n */\n static exit()\n {\n var aeComputers = Component.getElementsByClass(document, PDP11.APPCLASS, \"computer\");\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n var computer = /** @type {ComputerPDP11} */ (Component.getComponentByType(\"Computer\", parmsComputer['id']));\n if (computer) {\n\n /*\n * Added a new flag that Component functions (eg, notice()) should check before alerting the user.\n */\n computer.flags.unloading = true;\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onExit(\" + computer.flags.powered + \")\");\n }\n\n if (computer.flags.powered) {\n /**\n * Power off the computer, giving every component an opportunity to save its state,\n * but only if 'resume' has been set AND there is no valid resume path (because if a valid resume\n * path exists, we'll always load our state from there, and not from whatever we save here).\n */\n computer.powerOff(!!(computer.resume && !computer.sResumePath), true);\n }\n }\n }\n }\n}\n\nComputerPDP11.STATE_FAILSAFE = \"failsafe\";\nComputerPDP11.STATE_VALIDATE = \"validate\";\nComputerPDP11.STATE_TIMESTAMP = \"timestamp\";\nComputerPDP11.STATE_VERSION = \"version\";\nComputerPDP11.STATE_HOSTURL = \"url\";\nComputerPDP11.STATE_BROWSER = \"browser\";\nComputerPDP11.STATE_USERID = \"user\";\n\n/*\n * The following constants define all the resume options. Negative values (eg, RESUME_REPOWER) are for\n * internal use only, and RESUME_DELETE is not documented (it provides a way of deleting ALL saved states\n * whenever a resume is declined). As a result, the only \"end-user\" values are 0, 1 and 2.\n */\nComputerPDP11.RESUME_REPOWER = -1; // resume without changing any state (for internal use only)\nComputerPDP11.RESUME_NONE = 0; // default (no resume)\nComputerPDP11.RESUME_AUTO = 1; // automatically save/restore state\nComputerPDP11.RESUME_PROMPT = 2; // automatically save but conditionally restore (WARNING: if restore is declined, any state is discarded)\nComputerPDP11.RESUME_DELETE = 3; // same as RESUME_PROMPT but discards ALL machines states whenever ANY machine restore is declined (undocumented)\n\n/*\n * Initialize every Computer on the page.\n */\nWeb.onInit(ComputerPDP11.init);\nWeb.onShow(ComputerPDP11.show);\nWeb.onExit(ComputerPDP11.exit);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/state.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass State {\n /**\n * State(component, sVersion, sSuffix)\n *\n * State objects are used by components to save/restore their state.\n *\n * During a save operation, components add data to a State object via set(), and then return\n * the resulting data using data().\n *\n * During a restore operation, the Computer component passes the results of each data() call\n * back to the originating component.\n *\n * WARNING: Since State objects are low-level objects that have no UI requirements, they do not\n * inherit from the Component class, so you should only use class methods of Component, such as\n * Component.assert() (or Debugger methods if the Debugger is available).\n *\n * NOTE: 1.01 is the first version to provide limited save/restore support using localStorage.\n * From that point on, care must be taken to insure that any new version that's incompatible with\n * previous localStorage data be released with a version number that is at least 1 greater,\n * since we're tagging the localStorage data with the integer portion of the version string.\n *\n * @param {Component} component\n * @param {string} [sVersion] is used to append a major version number to the key\n * @param {string} [sSuffix] is used to append any additional suffixes to the key\n */\n constructor(component, sVersion, sSuffix)\n {\n this.id = component.id;\n this.dbg = component.dbg;\n this.json = \"\";\n this.state = {};\n this.fLoaded = this.fParsed = false;\n this.key = State.key(component, sVersion, sSuffix);\n this.unload(component.parms);\n }\n\n /**\n * set(id, data)\n *\n * @this {State}\n * @param {number|string} id\n * @param {Object|string} data\n */\n set(id, data)\n {\n try {\n this.state[id] = data;\n } catch(e) {\n Component.log(e.message);\n }\n }\n\n /**\n * get(id)\n *\n * @this {State}\n * @param {number|string} id\n * @return {Object|string|null}\n */\n get(id)\n {\n return this.state[id] || null;\n }\n\n /**\n * data()\n *\n * @this {State}\n * @return {Object}\n */\n data()\n {\n return this.state;\n }\n\n /**\n * load(json)\n *\n * WARNING: Make sure you follow this call with either a call to parse() or unload(),\n * because any stringified data that we've loaded isn't usable until it's been parsed.\n *\n * @this {State}\n * @param {string|null} [json]\n * @return {boolean} true if state exists in localStorage, false if not\n */\n load(json)\n {\n if (json) {\n this.json = json;\n this.fLoaded = true;\n this.fParsed = false;\n return true;\n }\n if (this.fLoaded) {\n /*\n * This is assumed to be a redundant load().\n */\n return true;\n }\n if (Web.hasLocalStorage()) {\n var s = Web.getLocalStorageItem(this.key);\n if (s) {\n this.json = s;\n this.fLoaded = true;\n if (DEBUG) Component.log(\"localStorage(\" + this.key + \"): \" + s.length + \" bytes loaded\");\n return true;\n }\n }\n return false;\n }\n\n /**\n * parse()\n *\n * This completes the load() operation, by parsing what was loaded, on the assumption there\n * might be some benefit to deferring parsing until we've given the user a chance to confirm.\n * Otherwise, load() could have just as easily done this, too.\n *\n * @this {State}\n * @return {boolean} true if successful, false if error\n */\n parse()\n {\n var fSuccess = true;\n if (!this.fParsed) {\n try {\n this.state = JSON.parse(this.json);\n this.fParsed = true;\n } catch (e) {\n Component.error(e.message || e);\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * store()\n *\n * @this {State}\n * @return {boolean} true if successful, false if error\n */\n store()\n {\n var fSuccess = true;\n if (Web.hasLocalStorage()) {\n var s = JSON.stringify(this.state);\n if (Web.setLocalStorageItem(this.key, s)) {\n if (DEBUG) Component.log(\"localStorage(\" + this.key + \"): \" + s.length + \" bytes stored\");\n } else {\n /*\n * WARNING: Because browsers tend to disable all alerts() during an \"unload\" operation,\n * it's unlikely anyone will ever see the \"quota\" errors that occur at this point. Need to\n * think of some way to notify the user that there's a problem, and offer a way of cleaning\n * up old states.\n */\n Component.error(\"Unable to store \" + s.length + \" bytes in browser local storage\");\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * toString()\n *\n * @this {State}\n * @return {string} JSON-encoded state\n */\n toString()\n {\n return this.state? JSON.stringify(this.state) : this.json;\n }\n\n /**\n * unload(parms)\n *\n * This discards any data saved via set() or loaded via load(), creating an empty State object.\n * Note that you have to follow this call with an explicit call to store() if you want to remove\n * the state from localStorage as well.\n *\n * @this {State}\n * @param {Object} [parms]\n */\n unload(parms)\n {\n this.json = \"\";\n this.state = {};\n this.fLoaded = this.fParsed = false;\n if (parms) this.set(\"parms\", parms);\n }\n\n /**\n * clear(fAll)\n *\n * This unloads the current state, and then clears ALL localStorage for the current machine,\n * independent of version, to reduce the chance of orphaned states wasting part of our limited allocation.\n *\n * @this {State}\n * @param {boolean} [fAll] true to unconditionally clear ALL localStorage for the current domain\n */\n clear(fAll)\n {\n this.unload();\n var aKeys = Web.getLocalStorageKeys();\n for (var i = 0; i < aKeys.length; i++) {\n var sKey = aKeys[i];\n if (sKey && (fAll || sKey.substr(0, this.key.length) == this.key)) {\n Web.removeLocalStorageItem(sKey);\n if (DEBUG) Component.log(\"localStorage(\" + sKey + \") removed\");\n aKeys.splice(i, 1);\n i = 0;\n }\n }\n }\n\n /**\n * State.key(component, sVersion, sSuffix)\n *\n * This encapsulates the key generation code.\n *\n * @param {Component} component\n * @param {string} [sVersion] is used to append a major version number to the key\n * @param {string} [sSuffix] is used to append any additional suffixes to the key\n * @return {string} key\n */\n static key(component, sVersion, sSuffix)\n {\n var key = component.id;\n if (sVersion) {\n var i = sVersion.indexOf('.');\n if (i > 0) key += \".v\" + sVersion.substr(0, i);\n }\n if (sSuffix) {\n key += \".\" + sSuffix;\n }\n return key;\n }\n\n /**\n * State.compress(aSrc)\n *\n * @param {Array.<number>|null} aSrc\n * @return {Array.<number>|null} is either the original array (aSrc), or a smaller array of \"count, value\" pairs (aComp)\n */\n static compress(aSrc)\n {\n if (aSrc) {\n var iSrc = 0;\n var iComp = 0;\n var aComp = [];\n while (iSrc < aSrc.length) {\n var n = aSrc[iSrc];\n\n var iCompare = iSrc + 1;\n while (iCompare < aSrc.length && aSrc[iCompare] === n) iCompare++;\n aComp[iComp++] = iCompare - iSrc;\n aComp[iComp++] = n;\n iSrc = iCompare;\n }\n if (aComp.length < aSrc.length) return aComp;\n }\n return aSrc;\n }\n\n /**\n * State.decompress(aComp)\n *\n * @param {Array.<number>} aComp\n * @param {number} nLength is expected length of decompressed data\n * @return {Array.<number>}\n */\n static decompress(aComp, nLength)\n {\n var iDst = 0;\n var aDst = new Array(nLength);\n var iComp = 0;\n while (iComp < aComp.length - 1) {\n var c = aComp[iComp++];\n var n = aComp[iComp++];\n while (c--) {\n aDst[iDst++] = n;\n }\n }\n\n return aDst;\n }\n\n /**\n * State.compressEvenOdd(aSrc)\n *\n * This is a very simple variation on compress() that compresses all the EVEN elements of aSrc first,\n * followed by all the ODD elements. This tends to work better on EGA video memory, because when odd/even\n * addressing is enabled (eg, for text modes), the DWORD values tend to alternate, which is the worst case\n * for compress(), but the best case for compressEvenOdd().\n *\n * One wrinkle we support: if the first element is uninitialized, then we assume the entire array is undefined,\n * and return an empty compressed array. Conversely, decompressEvenOdd() will take an empty compressed array\n * and return an uninitialized array.\n *\n * @param {Array.<number>|null} aSrc\n * @return {Array.<number>|null} is either the original array (aSrc), or a smaller array of \"count, value\" pairs (aComp)\n */\n static compressEvenOdd(aSrc)\n {\n if (aSrc) {\n var iComp = 0, aComp = [];\n if (aSrc[0] !== undefined) {\n for (var off = 0; off < 2; off++) {\n var iSrc = off;\n while (iSrc < aSrc.length) {\n var n = aSrc[iSrc];\n var iCompare = iSrc + 2;\n while (iCompare < aSrc.length && aSrc[iCompare] === n) iCompare += 2;\n aComp[iComp++] = (iCompare - iSrc) >> 1;\n aComp[iComp++] = n;\n iSrc = iCompare;\n }\n }\n }\n if (aComp.length < aSrc.length) return aComp;\n }\n return aSrc;\n }\n\n /**\n * State.decompressEvenOdd(aComp, nLength)\n *\n * This is the counterpart to compressEvenOdd(). Note that because there's nothing in the compressed sequence\n * that differentiates a compress() sequence from a compressEvenOdd() sequence, you simply have to be consistent:\n * if you used even/odd compression, then you must use even/odd decompression.\n *\n * @param {Array.<number>} aComp\n * @param {number} nLength is expected length of decompressed data\n * @return {Array.<number>}\n */\n static decompressEvenOdd(aComp, nLength)\n {\n var iDst = 0;\n var aDst = new Array(nLength);\n var iComp = 0;\n while (iComp < aComp.length - 1) {\n var c = aComp[iComp++];\n var n = aComp[iComp++];\n while (c--) {\n aDst[iDst] = n;\n iDst += 2;\n }\n /*\n * The output of a \"count,value\" pair will never exceed the end of the output array, so as soon as we reach it\n * the first time, we know it's time to switch to ODD elements, and as soon as we reach it again, we should be\n * done.\n */\n\n if (iDst == nLength) iDst = 1;\n }\n\n return aDst;\n }\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/embed.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * We now support asynchronous XML and XSL file loads; simply set fAsync (below) to true.\n *\n * NOTE: For that support to work, we have to keep track of the number of machines on the page\n * (ie, how many embedMachine() calls were issued), reduce the count as each machine XML file\n * is fully transformed into HTML, and when the count finally returns to zero, notify all the\n * machine component init() handlers.\n *\n * Also, to prevent those init() handlers from running prematurely, we must disable all page\n * notification events at the start of the embedding process (Web.enablePageEvents(false)) and\n * re-enable them at the end (Web.enablePageEvents(true)).\n */\nvar fAsync = true;\nvar cAsyncMachines = 0;\n\n/**\n * loadXML(sFile, idMachine, sAppName, sAppClass, sParms, fResolve, display, done)\n *\n * This is the preferred way to load all XML and XSL files. It uses getResource()\n * to load them as strings, which parseXML() can massage before parsing/transforming them.\n *\n * For example, since I've been unable to get the XSLT document() function to work inside any\n * XSL document loaded by JavaScript's XSLT processor, that has prevented me from dynamically\n * loading any XML machine file that uses the \"ref\" attribute to refer to and incorporate\n * another XML document.\n *\n * To solve that, I've added an fResolve parameter that tells parseXML() to fetch any\n * referenced documents ITSELF and insert them into the XML string prior to parsing, instead\n * of relying on the XSLT template to pull them in. That fetching is handled by resolveXML(),\n * which iterates over the XML until all \"refs\" have been resolved (including any nested\n * references).\n *\n * Also, XSL files with a <!DOCTYPE [...]> cause MSIE's Microsoft.XMLDOM.loadXML() function\n * to choke, so I strip that out prior to parsing as well.\n *\n * TODO: Figure out why the XSLT document() function works great when the web browser loads an\n * XML file (and the associated XSL file) itself, but does not work when loading documents via\n * JavaScript XSLT support. Is it broken, is it a security issue, or am I just calling it wrong?\n *\n * @param {string} sXMLFile\n * @param {string|null|undefined} idMachine\n * @param {string|null|undefined} sAppName\n * @param {string|null|undefined} sAppClass\n * @param {string|null|undefined} sParms (machine parameters, if any)\n * @param {string|null|undefined} sClass (an optional machine class name used to style the machine)\n * @param {boolean} fResolve is true to resolve any \"ref\" attributes\n * @param {function(string)} display\n * @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)\n */\nfunction loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n{\n var doneLoadXML = function(sURLName, sXML, nErrorCode) {\n if (nErrorCode) {\n if (!sXML) sXML = \"unable to load \" + sXMLFile + \" (\" + nErrorCode + \")\";\n done(sXML, null);\n return;\n }\n parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done);\n };\n display(\"Loading \" + sXMLFile + \"...\");\n Web.getResource(sXMLFile, null, fAsync, doneLoadXML);\n}\n\n/**\n * parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n *\n * Generates an XML document from an XML string. This function also provides a work-around for XSLT's\n * lack of support for the document() function (at least on some browsers), by replacing every reference\n * tag (ie, a tag with a \"ref\" attribute) with the contents of the referenced file.\n *\n * @param {string} sXML\n * @param {string|null} sXMLFile\n * @param {string|null|undefined} idMachine\n * @param {string|null|undefined} sAppName\n * @param {string|null|undefined} sAppClass\n * @param {string|null|undefined} sParms (machine parameters, if any)\n * @param {string|null|undefined} sClass (an optional machine class name used to style the machine)\n * @param {boolean} fResolve is true to resolve any \"ref\" attributes; default is false\n * @param {function(string)} display\n * @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)\n */\nfunction parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n{\n var buildXML = function(sXML, sError) {\n if (sError) {\n done(sError, null);\n return;\n }\n if (idMachine) {\n\n /*\n * A more sensible place to record the machine XML would be embedMachine(), like we do for the\n * XSL file, but since we're about to modify the original machine XML, it's best to record it now.\n */\n Component.addMachineResource(idMachine, sXMLFile, sXML);\n\n var sURL = sXMLFile;\n if (sURL && sURL.indexOf('/') < 0 && window.location.pathname.slice(-1) == '/') {\n sURL = window.location.pathname + sURL;\n }\n /*\n * We embed the URL of the XML file both as a separate \"xml\" attribute for easy access from the\n * XSL file, and as part of the \"parms\" attribute for easy access from machines (see getMachineParm()).\n */\n if (!sParms) {\n sParms = '{';\n } else if (sParms.slice(-1) == '}') {\n sParms = sParms.slice(0, -1);\n if (sParms.length > 1) sParms += ',';\n } else { // sParms must just be a \"state\" file, so encode it as a \"state\" property\n sParms = '{state:\"' + sParms + '\",';\n }\n sParms += 'url:\"' + sURL + '\"}';\n /*\n * Note that while we no longer generate a machine XML file with a \"state\" attribute (because it's\n * encoded inside the \"parms\" attribute), the XSL file must still cope with \"state\" attributes inside\n * other XML files; for example, manifest XML files like /apps/pcx86/1981/visicalc/manifest.xml contain\n * machine elements with \"state\" attributes that must still be passed down to the computer element\n * \"the old fashioned way\".\n *\n * Until/unless that changes, components.xsl cannot be simplified as much as I might have hoped.\n */\n if (typeof resources == 'object') sURL = null; // turn off URL inclusion if we have embedded resources\n sParms = sParms.replace(/\\$/g, \"$$$$\");\n if (sClass) {\n /*\n * If there's no hard-coded \"class\" attribute in the machine tag, then we can set one in the final\n * replacement below, just like we do for sParms and sURL. However, if a \"class\" attribute already\n * exists, we need alter it and then zap the sClass variable.\n */\n var match = sXML.match(/(<machine[^>]*\\sclass=)(['\"])(.*?)(\\2.*?>)/);\n if (match) {\n sXML = sXML.replace(match[0], match[1] + match[2] + sClass + match[4]);\n sClass = null;\n }\n }\n sXML = sXML.replace(/(<machine[^>]*\\sid=)(['\"]).*?\\2/, \"$1$2\" + idMachine + \"$2\" + (sClass? ' class=\"' + sClass + '\"' : '') + (sParms? \" parms='\" + sParms + \"'\" : \"\") + (sURL? ' url=\"' + sURL + '\"' : ''));\n }\n\n if (!fResolve) {\n /*\n * I'm trying to switch to a shared components.xsl (at least for all PC-class machines),\n * but in the interim, that means hacking the XSL file on the fly to reflect the actual class.\n */\n sXML = sXML.replace(/(<xsl:variable name=\"APPNAME\">).*?(<\\/xsl:variable>)/, \"$1\" + sAppName + \"$2\");\n sXML = sXML.replace(/(<xsl:variable name=\"APPCLASS\">).*?(<\\/xsl:variable>)/, \"$1\" + sAppClass + \"$2\");\n\n /*\n * Non-COMPILED kludge to replace the version number template in the XSL file (which we assume we're reading,\n * since fResolve is false) with whatever XMLVERSION we extracted from the XML file (see corresponding kludge below).\n *\n * ES6 ALERT: Template strings.\n */\n if (!COMPILED && XMLVERSION) {\n sXML = sXML.replace(/<xsl:variable name=\"APPVERSION\"\\/>/, `<xsl:variable name=\"APPVERSION\">${XMLVERSION}</xsl:variable>`);\n }\n }\n\n /*\n * If the resource we requested is not really an XML file (or the file didn't exist and the server simply returned\n * a message like \"Cannot GET /devices/pc/machine/5150/cga/64kb/donkey/machine.xml\"), we'd like to display a more\n * meaningful message, because the XML DOM parsers will blithely return a document that contains nothing useful; eg:\n *\n * This page contains the following errors:error on line 1 at column 1:\n * Document is empty Below is a rendering of the page up to the first error.\n *\n * Supposedly, the IE XML DOM parser will throw an exception, but I haven't tested that, and unless all other\n * browsers do that, that's not helpful.\n *\n * The best I can do at this stage (assuming Web.getResource() didn't drop any error information on the floor)\n * is verify that the requested resource \"looks like\" valid XML (in other words, it begins with a '<').\n */\n var xmlDoc = null;\n if (sXML.charAt(0) == '<') {\n try {\n /*\n * Another hack for MSIE, which fails to load XSL documents containing a <!DOCTYPE [...]> tag.\n *\n * This is also why the XSLTProcessor 'transformToFragment' method in Microsoft Edge silently failed,\n * so I had pull this hack out of the \"ActiveXObject\" code. And rather than add yet-another Microsoft\n * browser check, I'm going to try doing this across the board, and hope that none of the other XSLT\n * processors fail *without* the DOCTYPE tag.\n */\n if (!fResolve) {\n sXML = sXML.replace(/<!DOCTYPE(.|[\\r\\n])*]>\\s*/g, \"\");\n }\n /*\n * Beginning with Microsoft Edge and the corresponding release of Windows 10, all the\n * 'ActiveXObject' crud has gone away; but of course, this code must remain in place if\n * we want to continue supporting older Internet Explorer browsers (ie, back to IE9).\n */\n /** @namespace window.ActiveXObject */\n if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1\n xmlDoc = new window.ActiveXObject(\"Microsoft.XMLDOM\");\n xmlDoc.async = false;\n xmlDoc['loadXML'](sXML);\n } else {\n /** @namespace window.DOMParser */\n xmlDoc = (new window.DOMParser()).parseFromString(sXML, \"text/xml\");\n }\n } catch(e) {\n xmlDoc = null;\n sXML = e.message;\n }\n } else {\n sXML = \"unrecognized XML: \" + (sXML.length > 255? sXML.substr(0, 255) + \"...\" : sXML);\n }\n done(sXML, xmlDoc);\n };\n if (sXML) {\n if (PRIVATE) sXML = sXML.replace(/\\/library.xml/, \"/private/library.xml\");\n if (fResolve) {\n resolveXML(sXML, display, buildXML);\n return;\n }\n buildXML(sXML, null);\n return;\n }\n done(\"no data\" + (sXMLFile? \" for file: \" + sXMLFile : \"\"), null);\n}\n\n/**\n * resolveXML(sXML, display, done)\n *\n * Replaces every tag with a \"ref\" attribute with the contents of the corresponding file.\n *\n * TODO: Fix some of the limitations of this code, such as: 1) requiring the \"ref\" attribute\n * to appear as the tag's first attribute, 2) requiring the \"ref\" attribute to be double-quoted,\n * and 3) requiring the \"ref\" tag to be self-closing.\n *\n * @param {string} sXML\n * @param {function(string)} display\n * @param {function(string,(string|null))} done (the first string contains the resolved XML data, the second is for any error message)\n */\nfunction resolveXML(sXML, display, done)\n{\n var matchRef;\n var reRef = /<([a-z]+)\\s+ref=\"(.*?)\"(.*?)\\/>/g;\n\n if ((matchRef = reRef.exec(sXML))) {\n\n var sRefFile = matchRef[2];\n\n var doneReadXML = function(sURLName, sXMLRef, nErrorCode) {\n if (nErrorCode || !sXMLRef) {\n done(sXML, \"unable to resolve XML reference: \" + matchRef[0] + \" (\" + nErrorCode + \")\");\n return;\n }\n /*\n * If there are additional attributes in the \"referring\" XML tag, we want to insert them\n * into the \"referred\" XML tag; attributes that don't exist in the referred tag should be\n * appended, and attributes that DO exist should be overwritten.\n */\n var sRefAttrs = matchRef[3];\n if (sRefAttrs) {\n var aXMLRefTag = sXMLRef.match(new RegExp(\"<\" + matchRef[1] + \"[^>]*>\"));\n if (aXMLRefTag) {\n var sXMLNewTag = aXMLRefTag[0];\n /*\n * Iterate over all the attributes in the \"referring\" XML tag (sRefAttrs)\n */\n var matchAttr;\n var reAttr = /( [a-z]+=)(['\"])(.*?)\\2/gi;\n while ((matchAttr = reAttr.exec(sRefAttrs))) {\n if (sXMLNewTag.toLowerCase().indexOf(matchAttr[1].toLowerCase()) < 0) {\n /*\n * This is the append case....\n */\n sXMLNewTag = sXMLNewTag.replace(\">\", matchAttr[0] + \">\");\n } else {\n /*\n * This is the overwrite case....\n */\n sXMLNewTag = sXMLNewTag.replace(new RegExp(matchAttr[1] + \"(['\\\"])(.*?)\\\\1\"), matchAttr[0]);\n }\n }\n if (aXMLRefTag[0] != sXMLNewTag) {\n sXMLRef = sXMLRef.replace(aXMLRefTag[0], sXMLNewTag);\n }\n } else {\n done(sXML, \"missing <\" + matchRef[1] + \"> in \" + sRefFile);\n return;\n }\n }\n\n /*\n * Apparently when a Windows Azure server delivers one of my XML files, it may modify the first line:\n *\n * <?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n\n *\n * I didn't determine exactly what it was doing at this point (probably just changing the \\n to \\r\\n),\n * but in any case, relaxing the following replace() solved it.\n */\n sXMLRef = sXMLRef.replace(/<\\?xml[^>]*>[\\r\\n]*/, \"\");\n\n sXML = sXML.replace(matchRef[0], sXMLRef);\n\n resolveXML(sXML, display, done);\n };\n\n display(\"Loading \" + sRefFile + \"...\");\n Web.getResource(sRefFile, null, fAsync, doneReadXML);\n return;\n }\n done(sXML, null);\n}\n\n/**\n * embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * This allows to you embed a machine on a web page, by transforming the machine XML into HTML.\n *\n * @param {string} sAppName is the app name (eg, \"PCx86\")\n * @param {string} sAppClass is the app class (eg, \"pcx86\"); also known as the machine class\n * @param {string} sVersion is the app version (eg, \"1.15.7\")\n * @param {string} idMachine\n * @param {string|undefined} sXMLFile\n * @param {string|undefined} sXSLFile\n * @param {string|undefined} sParms (machine parameters, if any)\n * @param {string|undefined} sClass (an optional machine class name used to style the machine)\n * @return {boolean} true if successful, false if error\n */\nfunction embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n var eMachine, eWarning, fSuccess = true;\n\n if (!sXMLFile) {\n sXMLFile = \"machine.xml\";\n if (!sXSLFile) sXSLFile = \"components.xsl\";\n }\n \n cAsyncMachines++;\n Component.addMachine(idMachine);\n\n var doneMachine = function() {\n\n if (!--cAsyncMachines) {\n if (fAsync) Web.enablePageEvents(true);\n }\n };\n\n var displayError = function(sError) {\n Component.log(sError);\n displayMessage(\"Error: \" + sError);\n if (fSuccess) doneMachine();\n fSuccess = false;\n };\n\n var displayMessage = function(sMessage) {\n if (eWarning === undefined) {\n /*\n * Our MarkOut module (in convertMDMachineLinks()) creates machine containers that look like:\n *\n * <div id=\"' + sMachineID + '\" class=\"machine-placeholder\"><p>Embedded PC</p><p class=\"machine-warning\">...</p></div>\n *\n * with the \"machine-warning\" paragraph pre-populated with a warning message that the user will\n * see if nothing at all happens. But hopefully, in the normal case (and especially the error case),\n * *something* will have happened.\n *\n * Note that it is the HTMLOut module (in processMachines()) that ultimately decides which scripts to\n * include and then generates the embedXXX() call.\n */\n var aeWarning = (eMachine && Component.getElementsByClass(eMachine, \"machine-warning\"));\n eWarning = (aeWarning && aeWarning[0]) || eMachine;\n }\n if (eWarning) eWarning.innerHTML = Str.escapeHTML(sMessage);\n };\n\n try {\n eMachine = document.getElementById(idMachine);\n if (eMachine) {\n\n /*\n * If we have a 'css' resource, add it to the page first.\n */\n var css;\n if (typeof resources == \"object\" && (css = resources['css'])) {\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n // noinspection JSDeprecatedSymbols\n if (style.styleSheet) {\n // noinspection JSDeprecatedSymbols\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n head.appendChild(style);\n }\n\n if (!sXSLFile) {\n /*\n * Now that PCjs is an open-source project, we can make the following test more flexible,\n * and revert to the internal template if DEBUG *or* internal version (instead of *and*).\n *\n * Third-party sites that don't use the PCjs server will ALWAYS want to specify a fully-qualified\n * path to the XSL file, unless they choose to mirror our folder structure.\n */\n var sAppFolder = sAppClass;\n if (DEBUG || !sVersion) {\n if (sAppClass != \"c1pjs\") sAppFolder = \"shared\";\n sXSLFile = \"/modules/\" + sAppFolder + \"/templates/components.xsl\";\n } else {\n if (sAppClass.substr(0, 3) == \"pdp\") sAppFolder = \"pdpjs\";\n sXSLFile = \"/versions/\" + sAppFolder + \"/\" + sVersion + \"/components.xsl\";\n }\n }\n\n var processXML = function(sXML, xml) {\n if (!xml) {\n displayError(sXML);\n return;\n }\n\n /*\n * Non-COMPILED kludge to extract the version number from the stylesheet path in the machine XML file;\n * we don't need this code in COMPILED (non-DEBUG) releases, because APPVERSION is hard-coded into them.\n */\n if (!COMPILED) {\n var aMatch = sXML.match(/<\\?xml-stylesheet[^>]* href=(['\"])[^'\"]*?\\/([0-9.]*)\\/([^'\"]*)\\1/);\n if (aMatch) {\n XMLVERSION = aMatch[2];\n }\n }\n\n var transformXML = function(sXSL, xsl) {\n if (!xsl) {\n displayError(sXSL);\n return;\n }\n\n /*\n * Record the XSL file, in case someone wants to save the entire machine later.\n * \n * NOTE: sXSLFile will never be undefined by this point, but apparently the Closure Compiler doesn't realize that. \n */\n Component.addMachineResource(idMachine, sXSLFile || \"\", sXSL);\n\n /*\n * The <machine> template in components.xsl now generates a \"machine div\" that makes\n * the div we required the caller of embedMachine() to provide redundant, so instead\n * of appending this fragment to the caller's node, we REPLACE the caller's node.\n * This works only because because we ALSO inject the caller's \"machine div\" ID into\n * the fragment's ID during parseXML().\n *\n * eMachine.innerHTML = sFragment;\n *\n * Also, if the transform function fails, make sure you're using the appropriate\n * \"components.xsl\" and not a \"machine.xsl\", because the latter will not produce valid\n * embeddable HTML (and is the most common cause of failure at this final stage).\n */\n displayMessage(\"Processing \" + sXMLFile + \"...\");\n\n /*\n * Beginning with Microsoft Edge and the corresponding release of Windows 10, all the\n * 'ActiveXObject' crud has gone away; but of course, this code must remain in place if\n * we want to continue supporting older Internet Explorer browsers (ie, back to IE9).\n */\n if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1\n var sFragment = xml['transformNode'](xsl);\n if (sFragment) {\n eMachine.outerHTML = sFragment;\n doneMachine();\n } else {\n displayError(\"transformNodeToObject failed\");\n }\n }\n else if (document.implementation && document.implementation.createDocument) {\n var xsltProcessor = new XSLTProcessor();\n xsltProcessor['importStylesheet'](xsl);\n var eFragment = xsltProcessor['transformToFragment'](xml, document);\n if (eFragment) {\n /*\n * This fails in Microsoft Edge...\n *\n var machine = eFragment.getElementById(idMachine);\n if (!machine) {\n displayError(\"machine generation failed: \" + idMachine);\n } else\n */\n if (eMachine.parentNode) {\n eMachine.parentNode.replaceChild(eFragment, eMachine);\n doneMachine();\n } else {\n /*\n * NOTE: This error can occur if our Node web server, when processing a folder with\n * both a manifest.xml with a machine.xml reference AND a README.md containing a\n * machine link, generates duplicate embedXXX() calls for the same machine; if the\n * first embedXXX() call finds its target, subsequent calls for the same target will\n * fail.\n *\n * Technically, such a folder is in a misconfigured state, but it happens, in part\n * because when we switched to the Jekyll web server, we had to add machine links to\n * all README.md files where we had previously relied on manifest.xml or machine.xml\n * processing. This is because the Jekyll web server currently doesn't process XML\n * files, nor is support for that likely to be added any time soon; it was a nice\n * feature of the Node web server, but it's not clear that it's worth doing for Jekyll.\n */\n displayError(\"invalid machine element: \" + idMachine);\n }\n } else {\n displayError(\"transformToFragment failed\");\n }\n } else {\n /*\n * Perhaps I should have performed this test at the outset; on the other hand, I'm\n * not aware of any browsers don't support one or both of the above XSLT transformation\n * methods, so treat this as a bug.\n */\n displayError(\"unable to transform XML: unsupported browser\");\n }\n };\n /*\n * NOTE: sXSLFile will never be undefined by this point, but apparently the Closure Compiler doesn't realize that. \n */\n loadXML(sXSLFile || \"\", null, sAppName, sAppClass, null, null, false, displayMessage, transformXML);\n };\n\n if (sXMLFile.charAt(0) != '<') {\n loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, true, displayMessage, processXML);\n } else {\n parseXML(sXMLFile, null, idMachine, sAppName, sAppClass, sParms, sClass, false, displayMessage, processXML);\n }\n } else {\n displayError(\"missing machine element: \" + idMachine);\n }\n } catch(e) {\n displayError(e.message);\n }\n return fSuccess;\n}\n\n/**\n * embedC1P(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedC1P(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"C1Pjs\", \"c1pjs\", APPVERSION, idMachine, sXMLFile, sXSLFile, undefined, sClass);\n}\n\n/**\n * embedPCx86(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPCx86(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PCx86\", \"pcx86\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPC8080(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPC8080(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PC8080\", \"pc8080\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPDP10(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPDP10(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PDPjs\", \"pdp10\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPDP11(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPDP11(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PDPjs\", \"pdp11\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * findMachineComponent(idMachine, sType)\n *\n * @param {string} idMachine\n * @param {string} sType\n * @return {Component|null}\n */\nfunction findMachineComponent(idMachine, sType)\n{\n return Component.getComponentByType(sType, idMachine + \".machine\");\n}\n\n/**\n * commandMachine(control, fSingle, idMachine, sComponent, sCommand, sValue)\n *\n * Use Component methods to find the requested component for a specific machine, and if the component is found,\n * then check its 'exports' table for an entry matching the specified command string, and if an entry is found, then\n * the corresponding function is called with the specified data.\n *\n * @param {Object} control\n * @param {boolean} fSingle\n * @param {string} idMachine\n * @param {string} sComponent\n * @param {string} sCommand\n * @param {string} [sValue]\n * @return {boolean}\n */\nfunction commandMachine(control, fSingle, idMachine, sComponent, sCommand, sValue)\n{\n if (sCommand == \"script\") {\n if (Component.processScript(idMachine, sValue)) {\n if (fSingle) control.disabled = true;\n return true;\n }\n return false;\n }\n if (sComponent) {\n var component = Component.getComponentByType(sComponent, idMachine + \".machine\");\n if (component) {\n var exports = component['exports'];\n if (exports) {\n var fnCommand = exports[sCommand];\n if (fnCommand) {\n if (fnCommand.call(component, sValue)) {\n if (fSingle) control.disabled = true;\n return true;\n }\n return false;\n }\n }\n }\n }\n console.log(\"unimplemented: commandMachine('\" + idMachine + \"','\" + sComponent + \"','\" + sCommand + \"','\" + sValue + \"')\");\n return false;\n}\n\n/**\n * Prevent the Closure Compiler from renaming functions we want to export, by adding them as global properties.\n *\n * TODO: Consider making all these functions properties on a single global object (eg, 'PCjs'), to minimize global\n * pollution and risk of name collision.\n */\nif (APPNAME == \"C1Pjs\") {\n window['embedC1P'] = embedC1P;\n}\nif (APPNAME == \"PCx86\") {\n window['embedPC'] = embedPCx86; // WARNING: embedPC() deprecated as of v1.23.0\n window['embedPCx86'] = embedPCx86;\n}\nif (APPNAME == \"PC8080\") {\n window['embedPC8080'] = embedPC8080;\n}\nif (APPNAME == \"PDPjs\") {\n window['embedPDP10'] = embedPDP10;\n window['embedPDP11'] = embedPDP11;\n}\n\nwindow['commandMachine'] = commandMachine;\n\nwindow['enableEvents'] = Web.enablePageEvents;\nwindow['sendEvent'] = Web.sendPageEvent;\n"]} \ No newline at end of file +{"version":3,"file":"pdp11.js","lineCount":410,"mappings":"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","sources":["versions/pdpjs/1.61.0/pdp11-uncompiled.js"," [synthetic:util/defineproperty] "," [synthetic:util/global] "," [synthetic:es6/symbol] "," [synthetic:es6/util/makeiterator] "," [synthetic:util/objectcreate] "," [synthetic:es6/util/setprototypeof] "," [synthetic:es6/util/inherits] "," [synthetic:util/polyfill] "," [synthetic:es6/math/trunc] "," [synthetic:es6/number/parseint] "," [synthetic:es6/math/log2] "," [synthetic:es6/array/fill] "],"names":["$jscomp.defineProperty","$jscomp.global","$jscomp.initSymbol","$jscomp.Symbol","$jscomp.SYMBOL_PREFIX","$jscomp.arrayIterator","$jscomp.initSymbolIterator","$jscomp.iteratorPrototype","$jscomp.objectCreate","$jscomp.setPrototypeOf","$jscomp.polyfill","DiskAPI.GEOMETRIES","ASCII","BREAK","CTRL_A","CTRL_B","CTRL_C","CTRL_D","CTRL_E","CTRL_F","CTRL_G","CTRL_H","CTRL_I","CTRL_J","CTRL_K","CTRL_L","CTRL_M","CTRL_N","CTRL_O","CTRL_P","CTRL_Q","CTRL_R","CTRL_S","CTRL_T","CTRL_U","CTRL_V","CTRL_W","CTRL_X","CTRL_Y","CTRL_Z","ESC","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","DEL","parseInt","base","chPrefix","fCommas","indexOf","replace","ch","charAt","substr","chSuffix","slice","shift","match","isNaN","Math","pow","trunc","value","toBase","radix","cch","sPrefix","nGrouping","ceil","log","String","fromCharCode","toBin","abs","Str.toBase","toOct","fPrefix","toDec","toHex","toHexWord","Str.toHex","getBaseName","sFileName","fStripExt","sBaseName","lastIndexOf","substring","getExtension","sExtension","toLowerCase","endsWith","sSuffix","length","escapeHTML","sHTML","Str.HTMLEscapeMap","pad","sPadding","trim","prototype","Str.ASCIICodeMap","binarySearch","fnCompare","left","right","found","undefined","middle","compareResult","formatDate","date","sDate","Date","iHour","getHours","iDay","getDate","iMonth","getMonth","sFormat","Usr.asDays","getDay","Usr.asMonths","getMinutes","getSeconds","getFullYear","getResource","sURL","type","fAsync","done","callback","request","readyState","resource","fArrayBuffer","response","responseText","err","status","window","location","protocol","nErrorCode","resources","XMLHttpRequest","ActiveXObject","fXHR2","responseType","onreadystatechange","sPost","hasOwnProperty","encodeURIComponent","open","setRequestHeader","send","overrideMimeType","parseMemoryResource","sData","aBytes","aSymbols","addrLoad","addrExec","ib","Error","data","JSON","parse","eval","Array","aData","Component.alertUser","message","ab","asHexData","sHexData","split","push","getHost","host","SITEHOST","hasLocalStorage","Web.fLocalStorage","localStorage","setItem","Web.sLocalStorageTest","getItem","removeItem","getLocalStorageItem","sKey","sValue","setLocalStorageItem","isUserAgent","userAgent","navigator","isMobile","sDevice","sMobile","Web.getURLParm","Web.isUserAgent","fInvert","getURLParm","sParm","Web.parmsURL","sParms","aParms","search","pl","exec","decodeURIComponent","onCountRepeat","fnRepeat","fnComplete","fnTimeout","doCountRepeat","setTimeout","onClickRepeat","fn","doClickRepeat","msRepeat","ms","timer","fIgnoreMouseEvents","onmousedown","e.onmousedown","msDelay","ontouchstart","e.ontouchstart","onmouseup","onmouseout","e.onmouseout","clearTimeout","ontouchend","ontouchcancel","e.ontouchcancel","onPageEvent","sFunc","fnPrev","onInit","Web.aPageEventHandlers","doPageEvent","afn","Web.fPageEventsEnabled","enablePageEvents","fEnable","Web.fPageLoaded","Web.sendPageEvent","Web.fPageShowed","sendPageEvent","sEvent","Web.doPageEvent","Web.onPageEvent","onPageLoad","onPageShow","onPageUnload","constructor","Component","parms","bitsMessage","id","name","comment","bindings","idComponent","idMachine","flags","ready","busy","busyCancel","initDone","powered","unloading","error","fnReady","clearError","dbg","cpu","bus","cmp","Component.components.push","component","addMachineResource","sName","Component.machines","getTime","now","alertUser","sMessage","alert","confirmUser","sPrompt","fResponse","confirm","appendControl","control","sText","scrollTop","scrollHeight","bindComponentControls","element","sAppClass","PDP11.APPCLASS","aeControls","Component.getElementsByClass","parentNode","iControl","aeChildNodes","childNodes","iNode","nodeType","sClass","getAttribute","aClasses","iClass","Component.getComponentParms","setBinding","getComponents","idRelated","aComponents","Component.components.length","Component.components","getComponentByID","getComponentByType","sType","componentPrev","getComponentParms","getElementsByClass","sObjClass","getElementsByClassName","ae","aeAll","getElementsByTagName","re","RegExp","test","className","processCommands","fSuccess","aCommands","Component.commands","aTokens","splice","sCommand","fnCallReady","Component.asyncCommands.indexOf","processNextCommand","Component.processCommands","fnCommand","Component.globalCommands","Component.getComponentByType","Component.componentCommands","exports","call","Component.prototype","?.prototype","toString","sHTMLType","sBinding","onclick","clearControl","notice","this.notice","println","print","printControl","Component.appendControl","printlnControl","Component.PRINT.PROGRESS","fPrintOnly","computer","console","setError","isError","isReady","setReady","fReady","isBusy","fCancel","setBusy","fBusy","powerUp","powerDown","fSave","fShutdown","messageEnabled","bitsEnabled","printMessage","fAddress","PROGRESS","Component.asyncCommands","scriptAlert","scriptSleep","fnCallback","sDelay","scriptSelect","aBindings","options","textContent","selectedIndex","Array.prototype.indexOf","obj","start","isArray","Array.isArray","arg","Object","Function","bind","Function.prototype.bind","fnBound","fToBind","apply","fnNOP","args","concat","arguments","TypeError","TYPEDARRAYS","ArrayBuffer","APPCLASS","APPNAME","BYTEARRAYS","MEMFAULT","WORDBUS","REASONS","RK11","PRI","VEC","DRIVES","RKDS","SC","SCESA","WPS","RRDY","DRDY","SOK","SIN","DRU","RK05","DPL","ID","SHIFT","RKER","WCE","CSE","SE","UNUSED","NXS","NXC","NXD","TE","DLT","NXM","PGE","SKE","WLO","OVR","DRE","HE","RKCS","GO","FUNC","MEX","IE","CRDY","SSE","EXB","FMT","IBA","SCP","ERR","RMASK","WMASK","RKDA","SA","HS","CA","DS","CRESET","WRITE","READ","WCHK","SEEK","RCHK","DRESET","WLOCK","RL11","PREFIX","RLCS","BAE","ERRC","DE","CLEAR","SET","RLBA","RLDA","SEEK_CMD","SEEK_DIR","SEEK_HS","SEEK_CAD","RW_SA","RW_HS","RW_CA","GS_CMD","GS_RST","RLMP","GS_ST","LOADC","SPINUP","BRUSHC","LOADH","LOCKON","UNLOADH","SPINDN","GS_BH","GS_HO","GS_CO","GS_HS","GS_DT","GS_DSE","GS_VC","GS_WGE","GS_SPE","GS_SKTO","GS_WL","GS_CHE","GS_WDE","RLBE","MASK","OPI","DCRC","HCRC","HNF","MPE","NOP","STATUS","RHDR","WDATA","RDATA","RDNC","RX11","RXCS","UNIT","DONE","TR","INIT","RXDB","RXTA","RXSA","RXES","CRC","PARITY","FILL","EMPTY","RDSTAT","WRDEL","RDERR","ERROR","HOME0","HOME1","BAD_HOME","NO_TRACK","FOUND_HOME","SELF_DIAG","NO_SECTOR","NO_SEP","NO_PREAM","NO_IOMARK","CRC_HEADER","BAD_TRACK","NO_ID","NO_DATA","CRC_DATA","BAD_PARITY","VECTORS","PDP11.RX11.RX01","RX01","PDP11.RK11.RK05","PDP11.RK11.RKDS.RK05","PDP11.RK11.RKDS.SOK","PDP11.RK11.RKDS.RRDY","PDP11.RL11.RL02K","RL02K","PDP11.RL11.RLMP.GS_ST.LOCKON","PDP11.RL11.RLMP.GS_BH","PDP11.RL11.RLMP.GS_HO","PDP11.APPNAME","PDP11.BYTEARRAYS","PDP11.TYPEDARRAYS","PDP11.WORDBUS","PDP11.MEMFAULT","MessagesPDP11.CATEGORIES","CPU","TRAP","FAULT","INT","BUS","MEMORY","MMU","ROM","DEVICE","PANEL","KEYBOARD","KEYS","PC11","PAPER","DISK","DL11","SERIAL","KW11","TIMER","SPEAKER","COMPUTER","BUFFER","WARN","HALT","PanelPDP11","parmsPanel","fBindings","nDisplayCount","cLiveRegs","regAddr","regData","regSwitches","regDisplay","ledAddr","ledData","fAutoInc","fLEDTest","nAddrSel","PanelPDP11.ADDRSEL.CONS_PHY","leds","switches","processStart","processStep","processEnable","processContinue","processDeposit","processExamine","processLoadAddr","processLEDTest","processSRSwitch","holdSwitch","toggleSwitch","resetSwitches","setSwitch","$jscomp.inherits","setDR","updateData","PanelPDP11.prototype","reset","fPowerUp","stop","parent","parentElement","panel","onPressSwitch","pressSwitch","onReleaseSwitch","releaseSwitch","event","preventDefault","initBus","addIOTable","PanelPDP11.UNIBUS_IOTABLE","addResetHandler","displayLEDs","displaySwitches","fRepower","PanelPDP11.init","restore","save","state","State","set","getAR","getDR","getSR","updateAddr","setAR","setSRSwitches","setSR","sw","displayLED","style","backgroundColor","override","displaySwitch","marginTop","displayValue","sLabel","nValue","nBase","sVal","Str.toOct","Str.parseInt","PanelPDP11.SWITCH.LOAD","running","setPC","initMMU","getSwitch","PanelPDP11.SWITCH.ENABLE","startCPU","stopCPU","stepCPU","nCyclesStep","updateTimers","addCycles","updateChecksum","exception","stack","updateDisplays","advanceAddr","setWordDirect","nDisableTraps","setWord","mapVirtualToPhysical","addr","PDP11.ACCESS.WRITE_WORD","getWordDirect","getWordSafe","index","nRegs","MODEL_1140","model","fGenRegs","UNIBUS","inc","mask","nBusMask","PanelPDP11.SWITCH.STEP","nLEDs","updateLED","updateLEDArray","regsGen","setAddr","setData","fActive","readCNSW","fPreWrite","writeCNSW","init","aePanels","document","iPanel","ePanel","Component.getComponentByID","Component.bindComponentControls","CONS_PHY","ENABLE","LOAD","STEP","Web.onInit","BusPDP11","parmsBus","nBusWidth","addrTotal","nBlockSize","BusPDP11.IOPAGE_LENGTH","nBlockShift","log2","nBlockLen","nBlockLimit","nBlockTotal","nBlockMask","aIOHandlers","nDisableFaults","fFault","afnReset","afnIOPage","BusPDP11.IOController.readByte","BusPDP11.IOController.writeByte","BusPDP11.IOController.readWord","BusPDP11.IOController.writeWord","aBusBlocks","aMemBlocks","addrIOPage","nIOPageRange","nMemMask","iBlockIOPageBus","iBlockIOPageMem","block","MemoryPDP11","initMemory","copyBreakpoints","iBlock","addMemory","MemoryPDP11.TYPE.CONTROLLER","setIOPageRange","nRange","BusPDP11.prototype","saveMemory","adw","restoreMemory","iDst","aDst","iComp","aComp","size","controller","addrNext","sizeLeft","addrBlock","sizeBlock","used","sizeAvail","reportError","BusPDP11.ERROR.RANGE_INUSE","blockNew","MemoryPDP11.TYPE_NAMES","BusPDP11.ERROR.RANGE_INVALID","BusPDP11_prototype$getByte","getByte","readByte","BusPDP11_prototype$getWord","getWord","off","readWord","BusPDP11_prototype$setByte","setByte","writeByte","BusPDP11_prototype$setWord","writeWord","getBlockDirect","readWordDirect","readByteDirect","setByteDirect","writeByteDirect","writeWordDirect","removeMemBreak","fWrite","removeBreakpoint","cWriteBreakpoints","resetWriteAccess","fReadOnly","writeNone","writeWordDefault","cReadBreakpoints","resetReadAccess","fDirty","fDirtyEver","iSrc","aSrc","iCompare","getMemoryLimit","MemoryPDP11.TYPE.RAM","addIOHandlers","end","fnReadByte","fnWriteByte","fnReadWord","fnWriteWord","BusPDP11.IOPAGE_MASK","table","offReg","reg","readByteIORegister","writeByteIORegister","sReg","iReg","fnReset","fault","access","toStrBase","regErr","trap","checkFault","errNum","RANGE_INUSE","RANGE_INVALID","addrMasked","READ_BYTE","READ_WORD","MSG_CATEGORY","REG_NAME","CPUERR","PDP11.ACCESS.READ_BYTE","WRITE_BYTE","WRITE_WORD","PDP11.ACCESS.WRITE_BYTE","PDP11.ACCESS.READ_WORD","DevicePDP11","parmsDevice","kw11","lks","DevicePDP11.prototype","device","addTimer","setIRQ","irq","setTimer","addIRQ","DevicePDP11.UNIBUS_IOTABLE","messageDump","onDumpMMU","asArgs","dumpRegs","regsPDR","regsPAR","regMMR3","MMR3","regsUniMap","aRegs","offset","sFilter","fBreak","toUpperCase","nBits","sDump","fIndex","nWidth","Str.toDec","$jscomp.makeIterator","readLKS","writeLKS","clearIRQ","readMMR0","getMMR0","writeMMR0","setMMR0","regMMR0","MMR0","readMMR1","getMMR1","readMMR2","getMMR2","readMMR3","writeMMR3","setMMR3","readUNIMAP","word","writeUNIMAP","readSIPDR","writeSIPDR","readSDPDR","writeSDPDR","readSIPAR","writeSIPAR","readSDPAR","writeSDPAR","readKIPDR","writeKIPDR","readKDPDR","writeKDPDR","readKIPAR","writeKIPAR","readKDPAR","writeKDPAR","readUIPDR","writeUIPDR","readUDPDR","writeUDPDR","readUIPAR","writeUIPAR","readUDPAR","writeUDPAR","readRSET0","regPSW","PSW","regsAlt","writeRSET0","readR6KERNEL","regsAltStack","writeR6KERNEL","readR7KERNEL","writeR7KERNEL","readRSET1","writeRSET1","readR6SUPER","MODE","writeR6SUPER","readR6USER","writeR6USER","readCTRL","regsControl","writeCTRL","readSIZE","writeSIZE","readSYSID","writeSYSID","readCPUERR","writeCPUERR","readMBR","regMBR","writeMBR","readPIR","regPIR","writePIR","setPIR","readSLR","regSLR","writeSLR","readPSW","getPSW","writePSW","setPSW","writeIgnored","MODEL_1170","MODEL_1145","aeDevice","iDevice","eDevice","MemoryPDP11.idBlock","MemoryPDP11.TYPE.NONE","MemoryPDP11.TYPE.ROM","readNone","readWordDefault","setAccess","buffer","dv","DataView","Uint8Array","aw","Uint16Array","Int32Array","littleEndian","MemoryPDP11.afnArrayLE","MemoryPDP11.afnArrayBE","MemoryPDP11.afnMemory","MemoryPDP11.prototype","getInt32","setInt32","MemoryPDP11.afnNone","setReadAccess","fDirect","setWriteAccess","addBreakpoint","MemoryPDP11.afnChecked","mem","ACCESS","readByteMemory","readWordMemory","idw","nShift","dw","writeByteMemory","writeWordMemory","readByteChecked","checkMemoryRead","readWordChecked","writeByteChecked","checkMemoryWrite","writeWordChecked","readByteBE","readByteLE","readWordBE","getUint16","readWordLE","writeByteBE","writeByteLE","writeWordBE","setUint16","writeWordLE","NONE","RAM","CONTROLLER","CPUPDP11","parmsCPU","nCyclesDefault","nCycles","nMultiplier","nCyclesPerSecond","nCyclesMultiplier","mhzDefault","round","mhzTarget","msPerYield","nCyclesPerYield","nCyclesNextYield","nCyclesRecalc","starting","autoStart","checksum","nChecksum","nCyclesChecksumNext","nCyclesChecksumStart","nCyclesChecksumInterval","nCyclesChecksumStop","aTimers","onRunTimeout","runCPU","nTotalCycles","nRunCycles","nBurstCycles","nStepCycles","nSnapCycles","msStartRun","msStartThisRun","msEndThisRun","nCyclesThisRun","nYieldsSinceStatusUpdate","mhz","CPUPDP11.prototype","CPUPDP11.BUTTONS.length","CPUPDP11.BUTTONS","sAutoStart","getMachineParm","resetCycles","resetChecksum","fInit","updateStatus","fAutoStart","setFocus","sInitCommands","sCmds","doCommands","getChecksum","fDisplay","getCycles","displayChecksum","control.onclick","iComponent","Component.getComponents","setSpeed","getSpeedTarget","toFixed","fEndStep","calcCycles","fRecalc","vMultiplier","CPUPDP11.YIELDS_PER_SECOND","floor","fUpdateFocus","sSpeed","controlSpeed","Component.getTime","callBack","iTimer","fReset","getMSCycles","endBurst","getBurstCycles","saveTimers","aTimerCycles","calcStartTime","msDelta","CPUPDP11.YIELDS_PER_STATUS","nUpdate","calcRemainingTime","msYield","msRemainsThisRun","msElapsed","controlRun","CPUPDP11_prototype$stepCPU","fComplete","fStopped","complete","CPUStatePDP11","addrReset","pswTrap","pswMode","flagC","flagV","flagZ","flagN","addrLast","opLast","addrInvalid","mmuEnable","mmuLastMode","mmuLastPage","mmuMask","regMMR1","regMMR2","opFlags","mapMMR3","offRegSrc","maskRegSrcByte","MODEL_1120","opDecode","PDP11.op1120.bind","checkStackLimit","checkStackLimit1120","pswUsed","pswRegSet","PDP11.op1140.bind","checkStackLimit1140","trapVector","trapReason","irqNext","aIRQs","getByteDirect","getByteChecked","getWordChecked","setByteChecked","setWordChecked","addrDSpace","nReadBreaks","nWriteBreaks","getAddr","getVirtualAddrByMode","readWordFromVirtual","writeWordToVirtual","dstMode","dstReg","dstAddr","srcMode","srcReg","CPUStatePDP11.prototype","vectorFloating","vector","initCPU","resetIRQs","setMemoryAccess","BusPDP11.IOPAGE_22BIT","BusPDP11.IOPAGE_18BIT","readWordFromVirtualChecked","writeWordToVirtualChecked","BusPDP11.IOPAGE_16BIT","getPhysicalAddrByMode","readWordFromPhysicalChecked","readWordFromPhysical","writeWordToPhysicalChecked","writeWordToPhysical","newMMR0","result","newMMR3","BusPDP11.MASK_22BIT","BusPDP11.MASK_18BIT","setReset","fStart","bUnit","resetCPU","isRunning","getMMR3","getSpeed","saveIRQs","aIRQVectors","restoreIRQs","next","restoreTimers","getCF","getVF","getZF","getNF","advancePC","pc","REG","branch","opCode","condition","getPC","priority","PDP11.VECTORS","removeIRQ","irqPrev","OPFLAG","insertIRQ","checkTraps","REASON","newPSW","tmp","oldMode","newPIR","PIR","bits","updateNZVFlags","updateAllFlags","overflow","updateShiftFlags","updateSubFlags","src","dst","flag","reason","newPC","pushWord","trapReturn","popWord","mapUnibus","idx","getAddrInfo","fPhysical","addrPhysical","mode","page","paf","BusPDP11.UNIBUS_22BIT","addrVirtual","pdr","PDR","getAddrByMode","step","readWordFromPrevSpace","OPREG","OPMODE","writeWordToPrevSpace","readSrcByte","SRCMODE","readSrcWord","readDstAddr","readDstByte","readDstWord","updateDstByte","fnOp","PDP11.ACCESS.UPDATE_BYTE","updateDstWord","PDP11.ACCESS.UPDATE_WORD","writeDstByte","writeFlags","fnFlags","writeDstWord","nMinCycles","nDebugCheck","checksEnabled","nDebugState","checkInstruction","fInterrupt","checkIRQs","dispatchInterrupt","getOpcode","aeCPUs","iCPU","eCPU","PDP11.fnADD","updateAddFlags","PDP11.fnADDB","PDP11.fnASL","PDP11.fnASLB","PDP11.fnASR","PDP11.fnASRB","PDP11.fnBIC","PDP11.fnBICB","PDP11.fnBIS","PDP11.fnBISB","PDP11.fnCOM","PDP11.fnCOMB","PDP11.fnDEC","updateDecFlags","PDP11.fnDECB","PDP11.fnINC","updateIncFlags","PDP11.fnINCB","PDP11.fnNEG","PDP11.fnNEGB","PDP11.fnROL","PDP11.fnROLB","PDP11.fnROR","PDP11.fnRORB","PDP11.fnSUB","PDP11.fnSUBB","PDP11.fnSWAB","updateNZVCFlags","PDP11.fnXOR","PDP11.opADD","PDP11.opASH","PDP11.opASHC","PDP11.opBCC","PDP11.opBCS","PDP11.opBIC","PDP11.opBICB","PDP11.opBIS","PDP11.opBISB","PDP11.opBIT","PDP11.opBITB","PDP11.opBEQ","PDP11.opBGE","PDP11.opBGT","PDP11.opBHI","PDP11.opBLE","PDP11.opBLOS","PDP11.opBLT","PDP11.opBMI","PDP11.opBNE","PDP11.opBPL","PDP11.opBPT","PDP11.opBR","PDP11.opBVC","PDP11.opBVS","PDP11.opCLx","clearCF","clearVF","clearZF","clearNF","PDP11.opCMP","PDP11.opCMPB","PDP11.opDIV","PDP11.opEMT","PDP11.opHALT","stopInstruction","PDP11.opIOT","PDP11.JMP_CYCLES","PDP11.opJMP","PDP11.JSR_CYCLES","PDP11.opJSR","PDP11.MOV_CYCLES","PDP11.opMOV","PDP11.opMOVB","PDP11.MTP_CYCLES","PDP11.opMUL","updateMulFlags","PDP11.opNOP","PDP11.opRESET","PDP11.opRTS","PDP11.opUndefined.call","PDP11.opRTT","PDP11.opSEx","setCF","setVF","setZF","setNF","PDP11.opSOB","DSTMODE","PDP11.opSUB","PDP11.opSWAB","PDP11.opTRAP","PDP11.opWAIT","PDP11.opXOR","PDP11.opUndefined","PDP11.op1120","PDP11.aOpXnnn_1120","PDP11.op0AXn_1120","PDP11.aOp0AXn_1120","PDP11.op0BXn_1120","PDP11.aOp0BXn_1120","PDP11.op0CXn_1120","PDP11.aOp0CXn_1120","PDP11.op00AX_1120","PDP11.aOp00AX_1120","PDP11.op00BX_1120","PDP11.aOp00BX_1120","PDP11.op8AXn_1120","PDP11.aOp8AXn_1120","PDP11.op8BXn_1120","PDP11.aOp8BXn_1120","PDP11.op8CXn_1120","PDP11.aOp8CXn_1120","PDP11.op0Xnn_1120","PDP11.aOp0Xnn_1120","PDP11.op8Xnn_1120","PDP11.aOp8Xnn_1120","PDP11.op00Xn_1120","PDP11.aOp00Xn_1120","PDP11.opCLR","PDP11.opCOM","PDP11.opINC","PDP11.opDEC","PDP11.opNEG","PDP11.opADC","PDP11.opSBC","PDP11.opTST","PDP11.opROR","PDP11.opROL","PDP11.opASR","PDP11.opASL","PDP11.op000X_1120","PDP11.aOp000X_1120","PDP11.opCLC","PDP11.opCLV","PDP11.opCLZ","PDP11.opCLN","PDP11.opSEC","PDP11.opSEV","PDP11.opSEZ","PDP11.opSEN","PDP11.opCLRB","PDP11.opCOMB","PDP11.opINCB","PDP11.opDECB","PDP11.opNEGB","PDP11.opADCB","PDP11.opSBCB","PDP11.opTSTB","PDP11.opRORB","PDP11.opROLB","PDP11.opASRB","PDP11.opASLB","PDP11.op1140","PDP11.aOpXnnn_1140","PDP11.op0Xnn_1140","PDP11.aOp0Xnn_1140","PDP11.op7Xnn_1140","PDP11.aOp7Xnn_1140","PDP11.op8Xnn_1140","PDP11.aOp8Xnn_1140","PDP11.op00Xn_1140","PDP11.aOp00Xn_1140","PDP11.op0DXn_1140","PDP11.aOp0DXn_1140","PDP11.opMARK","setSP","PDP11.opMFPI","PDP11.opMTPI","PDP11.opSXT","PDP11.op000X_1140","PDP11.aOp000X_1140","PDP11.opSPL","PDP11.opRTI","PDP11.opMFPT","PDP11.op8DXn_1140","PDP11.aOp8DXn_1140","PDP11.opMTPS","PDP11.opMFPD","PDP11.opMTPD","PDP11.opMFPS","ROMPDP11","parmsROM","abInit","addrROM","sizeROM","fRetainROM","addrAlias","sFilePath","Str.getBaseName","sFileURL","sFileExt","Str.getExtension","FORMAT","Web.getHost","rom","Web.getResource","doneLoad","sResponse","Component.addMachineResource","Web.parseMemoryResource","initROM","ROMPDP11.prototype","addSymbols","IOTable","readROMByte","writeROMByte","addROM","aliases","cloneROM","aBlocks","aeROM","iROM","eROM","RAMPDP11","parmsRAM","addrRAM","sizeRAM","fAllocated","ram","initRAM","loadImage","zero","pattern","len","addrInit","fStop","fLoaded","offBlock","Str.toHexWord","offData","cbData","aeRAM","iRAM","eRAM","KeyboardPDP11","parmsKbd","aeKbd","iKbd","eKbd","kbd","SerialPortPDP11","parmsSerial","iAdapter","nBaudReceive","nBaudTransmit","fUpperCase","controlBuffer","consoleBuffer","tabSize","charBOL","iLogicalCol","fNullModem","irqReceiver","irqTransmitter","timerReceiveInterrupt","timerTransmitInterrupt","regRBUF","regRCSR","regXCSR","abReceive","target","connection","sendData","initConnection","receiveData","receiveStatus","setConnection","SerialPortPDP11.prototype","serial","onkeydown","control.onkeydown","bASCII","keyCode","KEYCODE","altKey","Keys.ASCII.CTRL_H","Keys.ASCII.DEL","ctrlKey","Keys.ASCII.A","Keys.ASCII.Z","Keys.ASCII.CTRL_A","onkeypress","control.onkeypress","metaKey","which","Keys.ASCII.CTRL_M","Keys.ASCII.CTRL_J","onpaste","control.onpaste","stopPropagation","clipboardData","getData","removeAttribute","readyReceiver","nBytesPerSecond","readyTransmitter","SerialPortPDP11.UNIBUS_IOTABLE","sConnection","asParts","sSourceID","Str.trim","sTargetID","fnConnect","initState","saveRegisters","bASCIIPrev","charCodeAt","LF","CR","pins","oldRCSR","CTS","CD","readRCSR","writeRCSR","delta","RTS","DTR","readRBUF","writeRBUF","readXCSR","writeXCSR","readXBUF","writeXBUF","transmitByte","nChars","Str.pad","aeSerial","iSerial","eSerial","configMount","parseConfig","cAutoMount","regPRB","regPRS","regPPS","iTapeData","regPPB","aTapeData","sTapeSource","PC11.SOURCE.NONE","nTapeTarget","PC11.TARGET.NONE","sTapeName","sTapePath","nLastPercent","fLocalTapes","Web.isMobile","irqReader","timerReader","config","PC11.prototype","pc11","onchange","controlSelect.onchange","controlDesc","controlOption","dataValue","sHRef","innerHTML","PC11.TARGET.MEMORY","PC11.TARGET.READER","controlTapes","loadSelectedTape","text","removeChild","addEventListener","fieldset","children","submit","disabled","files","onsubmit","controlInput.onsubmit","file","currentTarget","PC11.BINDING.READ_PROGRESS","getMachineComponent","readyReader","displayProgress","PC11.UNIBUS_IOTABLE","addTape","PC11.SOURCE.LOCAL","PC11.SOURCE.REMOTE","autoMount","sPath","loadTape","displayTape","prompt","unloadTape","fAutoMount","nResult","load","parseTape","sTapeURL","reader","FileReader","onload","reader.onload","byteLength","readAsArrayBuffer","ENDPOINT","sTapeExt","encodeURI","fTop","createElement","insertBefore","appendChild","sTargetPath","nPercent","controlBar","PC11.CSSCLASS.PROGRESS_BAR","width","fLoading","readPRS","writePRS","readPRB","writePRB","readPPS","writePPS","readPPB","writePPB","LOCAL","REMOTE","READER","READ_PROGRESS","PROGRESS_BAR","DiskPDP11","drive","DiskPDP11.nDisks","sDiskName","sDiskPath","sDiskFile","fRemovable","nCylinders","nHeads","nSectors","cbSector","aDiskData","dwChecksum","fWriteProtected","create","fnNotify","controllerNotify","DiskPDP11.prototype","aCylinders","iCylinder","aHeads","iHead","aSectors","iSector","initSector","sDiskURL","disk","cbDiskData","diskFormat","cdw","cylinder","head","sector","dwPattern","cModify","sDiskExt","sDiskParm","QUERY","sSizeParm","Str.endsWith","sDiskData","iEOL","sConfig","cb","fill","iModify","seek","track","bFormatting","bSectorEnd","nBytes","bSector","read","ibSector","write","getSector","pba","nSectorsPerCylinder","nSectorsRemaining","getSectorData","deltas","mods","iModifyLimit","nChanges","sReason","aDiskInfo","mod","DriveController","configDC","configDrive","configIO","nDrives","aDrives","fLocalDisks","aDiskHistory","bootSelectedDisk","loadSelectedDisk","selectDrive","waitDrives","DriveController.prototype","dc","control.onchange","updateSelectedDisk","iDrive","displayDisk","controlDrives","btoa","link","sURI","download","href","body","click","sAlert","sDrive","addDisk","DriveController.SOURCE.NONE","DriveController.SOURCE.LOCAL","DriveController.SOURCE.REMOTE","fReload","unloadAllDrives","unloadDrive","firstChild","getDriveName","initController","initDrives","saveController","saveHistory","saveDrives","aHistory","initHistory","aConfigDisks","initDrive","configDisk","fLocal","iCylinderBoot","iHeadBoot","iSectorBoot","cbSectorBoot","bHead","bCylinder","doneLoadDrive","loadDrive","addDiskHistory","updateDiskHistory","fRemount","controlDisks","stringify","readData","notifyLoad","fUpdateDrive","iDriveSelected","writeData","PDP11.RK11","RK11.UNIBUS_IOTABLE","regRKDS","regRKER","regRKCS","regRKWC","regRKBA","regRKDA","regRKDB","RK11.prototype","RK11.RKDS.RK05","RK11.RKDS.SOK","RK11.RKDS.RRDY","RK11.RKCS.CRDY","nWords","fCheck","nError","RK11.RKER.NXD","RK11.RKER.NXC","RK11.RKER.SKE","b0","b1","RK11.RKER.NXS","RK11.RKER.NXM","RK11.RKER.WCE","RK11_prototype$doneReadWrite","doneReadWrite","RK11.RKCS.MEX","RK11.RKCS.SHIFT.MEX","RK11.RKDA.SA","updateErrors","RK11.RKCS.ERR","RK11.RKER.DRE","RK11.RKER.HE","RK11.RKCS.HE","readRKDS","writeRKDS","readRKER","writeRKER","readRKCS","RK11.RKCS.RMASK","writeRKCS","RK11.RKCS.WMASK","RK11.RKCS.GO","func","processCommand","RK11.RKDA.DS","RK11.RKDA.SHIFT.DS","RK11.RKCS.SCP","RK11.RKER.SE","RK11.RKCS.FUNC","RK11.FUNC.CRESET","RK11.FUNC.RCHK","RK11.FUNC.READ","fnReadWrite","RK11.FUNC.WCHK","RK11.FUNC.WRITE","RK11.RKDA.CA","RK11.RKDA.SHIFT.CA","RK11.RKDA.HS","RK11.RKDA.SHIFT.HS","RK11.RKCS.IBA","RK11.FUNC.SEEK","RK11.FUNC.DRESET","RK11.RKDS.DRDY","RK11.RKDS.SHIFT.ID","RK11.RKDS.SC","RK11.RKCS.IE","readRKWC","writeRKWC","readRKBA","writeRKBA","readRKDA","writeRKDA","readRKDB","writeRKDB","RK11.RKDS","PDP11.RK11.RKDS","RK11.RKER","PDP11.RK11.RKER","RK11.RKCS","PDP11.RK11.RKCS","RK11.RKDA","PDP11.RK11.RKDA","RK11.FUNC","PDP11.RK11.FUNC","PDP11.RL11","RL11.UNIBUS_IOTABLE","regRLCS","regRLBA","regRLDA","tmpRLDA","regRLMP","regRLBE","RL11.prototype","RL11.RLCS.DRDY","RL11.RLCS.CRDY","RL11.ERRC.HNF","RL11.ERRC.NXM","RL11_prototype$doneReadWrite","RL11.RLCS.BAE","RL11.RLCS.SHIFT.BAE","RL11.RLBE.MASK","RL11.RLDA.SHIFT.RW_CA","RL11.RLDA.RW_HS","RL11.RLDA.RW_SA","RL11.RLCS.ERR","readRLCS","RL11.RLCS.RMASK","writeRLCS","RL11.RLCS.WMASK","RL11.RLCS.DS","RL11.RLCS.SHIFT.DS","RL11.RLCS.FUNC","RL11.FUNC.STATUS","RL11.RLMP.GS_BH","RL11.RLMP.GS_DT","RL11.FUNC.SEEK","RL11.RLDA.GS_CMD","RL11.RLDA.SEEK_CMD","darCA","RL11.RLDA.RW_CA","darHS","RL11.RLDA.SEEK_HS","RL11.RLDA.SEEK_DIR","RL11.FUNC.RHDR","RL11.FUNC.RDATA","RL11.FUNC.WDATA","RL11.RLCS.IE","readRLBA","writeRLBA","RL11.RLBA.WMASK","readRLDA","writeRLDA","readRLMP","writeRLMP","readRLBE","writeRLBE","RL11.RLCS","PDP11.RL11.RLCS","RL11.RLBA","PDP11.RL11.RLBA","RL11.RLDA","PDP11.RL11.RLDA","RL11.RLMP","PDP11.RL11.RLMP","RL11.RLBE","PDP11.RL11.RLBE","RL11.ERRC","PDP11.RL11.ERRC","RL11.FUNC","PDP11.RL11.FUNC","PDP11.RX11","RX11.UNIBUS_IOTABLE","regRXTA","regRXSA","regRXES","regError","regRXCS","regRXDB","funCode","RX11.FUNC.UNUSED","iBuffer","abBuffer","RX11.prototype","RX11.FUNC.READ","readSector","doneCommand","RX11.RXCS.ERR","RX11.RXCS.DONE","RX11.RXCS.IE","RX11.ERROR.HOME1","RX11.ERROR.HOME0","RX11.ERROR.NO_TRACK","RX11.ERROR.NO_SECTOR","RX11.ERROR.NO_DATA","RX11.RXCS.UNIT","RX11.RXTA.MASK","nSector","RX11.RXSA.MASK","RX11.RXES.CRC","RX11.RXES.PARITY","RX11.RXES.DEL","RX11.RXES.DRDY","deleted","readRXCS","RX11.RXCS.RMASK","RX11.FUNC.FILL","RX11.FUNC.EMPTY","RX11.RXCS.TR","RX11.FUNC.WRITE","RX11.FUNC.WRDEL","writeRXCS","RX11.RXCS.WMASK","RX11.RXCS.INIT","RX11.RXCS.GO","RX11.RXCS.FUNC","RX11.FUNCS","RX11.FUNC.RDSTAT","RX11.FUNC.RDERR","readRXDB","writeRXDB","writeSector","fDeleted","RX11.RXCS","PDP11.RX11.RXCS","RX11.RXTA","PDP11.RX11.RXTA","RX11.RXSA","PDP11.RX11.RXSA","RX11.RXES","PDP11.RX11.RXES","RX11.FUNC","PDP11.RX11.FUNC","RX11.ERROR","PDP11.RX11.ERROR","Debugger","parmsDbg","achGroup","achAddress","fAssemble","iPrevCmd","aPrevCmds","aVariables","getRegIndex","getRegValue","parseCommand","sCmd","chSep","iPrev","chQuote","truncate","fUnsigned","vNew","limit","evalOps","aVals","aOps","cOps","chOp","pop","val2","val1","valNew","parseArray","asValues","iValue","iLimit","aUndefined","fError","nUnary","nBasePrev","sOp","parseValue","cOpen","iStart","parseUnary","aBinOp","Debugger.aDECOpPrecedence","Debugger.aBinOpPrecedence","parseASCII","sExp","chDelim","cchMax","parseExpression","fQuiet","fPrint","join","regExp","printValue","bit","getVariable","sVar","sUndefined","getVariableFixup","valueUndefined","fDefined","printVariable","cVariables","aVars","keys","sort","Str.toBin","DebuggerPDP11","dbgAddrNextCode","newAddr","dbgAddrNextData","dbgAddrAssemble","aSymbolTable","aBreakExec","aBreakRead","aBreakWrite","clearBreakpoints","iInstructionHistory","nBreakInstructions","aInstructionHistory","nextHistory","historyInit","afnDumpers","sMessagePrev","aMessageBuffer","messageInit","opTable","DebuggerPDP11.OPTABLE","aOpReserved","nStep","sCmdDumpPrev","sCmdTracePrev","nCyclesStart","msStart","cInstructions","nSuppressBreaks","controlDebug","global","dbgAddr","ADDR_INVALID","fTemporary","DebuggerPDP11.prototype","packAddr","unpackAddr","aAddr","aCmds","sMessages","DebuggerPDP11.OP1140","DebuggerPDP11.OP1145","onDumpBus","sAddr","parseAddr","typePrev","cPrev","setSelectionRange","Web.onClickRepeat","onClickDebugEnter","onClickStep","fRepeat","fCompleted","scrollX","scrollY","focus","scrollTo","DebuggerPDP11_prototype$getByte","incAddr","DebuggerPDP11_prototype$getWord","DebuggerPDP11_prototype$setByte","DebuggerPDP11_prototype$setWord","fCode","dbgAddrNext","chOpen","parseReference","chClose","chEscape","chInnerEscape","reSubExp","sReplace","findSymbolAddr","sSymbol","offSymbol","sUpperCase","iTable","symbol","symbolTable","parseAddrOptions","sOptions","toStrAddr","toStrOffset","sEnable","aEnable","bitMessage","fnDumper","DebuggerPDP11.REGS","getRegName","DebuggerPDP11.REG_AR","DebuggerPDP11.REGNAMES","DebuggerPDP11.REG_PS","DebuggerPDP11.REG_PI","DebuggerPDP11.REG_ER","DebuggerPDP11.REG_SL","DebuggerPDP11.REG_M0","DebuggerPDP11.REG_M1","DebuggerPDP11.REG_M2","DebuggerPDP11.REG_M3","DebuggerPDP11.REG_DR","DebuggerPDP11.REG_SR","fRunning","DebuggerPDP11.HISTORY_LIMIT","checkCPU","fRegs","fUpdateDisplays","DebuggerPDP11.PROMPT","trapStatus","PDP11.REASONS","doRegisters","doUnassemble","clearTempBreakpoint","sStopped","msTotal","nState","OPCODE","checkBreakpoint","nb","nBreaks","aBreak","findBreakpoint","printBreakpoint","fFound","dbgAddrBreak","listBreakpoints","sAction","addrBreak","doCommand","getInstruction","sComment","nSequence","dbgAddrOp","opDesc","opMasks","DebuggerPDP11.OPNONE","opNum","sTarget","sOperands","sOpName","DebuggerPDP11.OPNAMES","cOperands","iOperand","opType","getOperand","sOperand","opTypeOther","DebuggerPDP11.OP_OTHER","DebuggerPDP11.OP_BRANCH","DebuggerPDP11.OP_DSTOFF","DebuggerPDP11.OP_DSTNUM3","DebuggerPDP11.OP_DSTNUM6","DebuggerPDP11.OP_DSTNUM8","opMode","DebuggerPDP11.OP_SRC","DebuggerPDP11.OP_DST","DebuggerPDP11.OP_DSTREG","DebuggerPDP11.OP_DSTMODE","getTarget","wIndex","sOpCodes","sLine","getFlagOutput","sFlag","getRegOutput","getRegDump","fMisc","getMiscDump","comparePairs","p1","p2","sModule","aOffsets","sAnnotation","Usr.binarySearch","findSymbol","fNearest","aSymbol","addrSymbol","returnSymbol","iOffset","doVar","delVariable","setVariable","doList","nDelta","sDelta","fInstruction","sRegMatch","doPrint","doTrace","sCount","nCount","Web.onCountRepeat","onCountStep","onCountStepComplete","sAddrEnd","nLines","dbgAddrEnd","nPrinted","sInstruction","s0","ch0","unshift","doAssemble","aOpBytes","doBreak","cBreaks","doClear","controlPrint","sLen","sBytes","sDumpers","doDump","sState","powerOff","sSymbolOrig","sMore","cHistory","iHistory","nPrev","sPrev","sLines","aFilters","dbgAddrNew","cOverrides","DebuggerPDP11.MODES","fJSON","nBytesPerLine","sChars","fnGet","doEdit","fnSet","doRun","doHalt","doIf","doStackTrace","cFrames","dbgAddrCall","dbgAddrStack","nFrames","sCall","cTests","addrOrig","sCallPrev","fCriteria","sCategory","doMessages","sCategories","fEnabled","sOption","doStep","doOptions","DebuggerPDP11.COMMANDS","doHelp","MOV","CMP","BIT","BIC","BIS","ADD","MOVB","CMPB","BITB","BICB","BISB","SUB","JSR","DebuggerPDP11.OP_SRCREG","MUL","DIV","ASH","ASHC","XOR","SOB","BR","BNE","BEQ","BGE","BLT","BGT","BLE","BPL","BMI","BHI","BLOS","BVC","BVS","BCC","BCS","EMT","JMP","SWAB","CLR","COM","INC","DEC","NEG","ADC","SBC","TST","ROR","ROL","ASR","ASL","MARK","MFPI","MTPI","SXT","CLRB","COMB","INCB","DECB","NEGB","ADCB","SBCB","TSTB","RORB","ROLB","ASRB","ASLB","MTPS","MFPD","MTPD","MFPS","SPL","WAIT","RTI","BPT","IOT","RESET","RTT","MFPT","CLC","CLV","CLCV","CLZ","CLCZ","CLVZ","CLCVZ","CLN","CLCN","CLVN","CLCVN","CLZN","CLCZN","CLVZN","CCC","SEC","SEV","SECV","SEZ","SECZ","SEVZ","SECVZ","SEN","SECN","SEVN","SECVN","SEZN","SECZN","SEVZN","SCC","aeDbg","iDbg","eDbg","ComputerPDP11","parmsComputer","parmsMachine","fSuspended","setMachineParms","fAutoPower","BOOLEAN","nPowerChange","sStateData","sResumePath","sStatePath","fServerState","fStateData","stateComputer","stateFailSafe","fInitialized","fRestoreError","url","random","sUserID","queryUserID","LICENSE","sResume","resume","fAllowResume","ComputerPDP11.RESUME_NONE","APPVERSION","getServerStatePath","doneStateLoad","sResource","wait","powerOn","parmsComponent","sParmLC","defaultValue","NUMBER","ComputerPDP11.prototype","onComponentReady","validateState","stateValidate","ComputerPDP11.STATE_VALIDATE","sTimestampValidate","get","ComputerPDP11.STATE_TIMESTAMP","sTimestampComputer","clear","ComputerPDP11.RESUME_AUTO","fRestore","ComputerPDP11.RESUME_REPOWER","ComputerPDP11.STATE_FAILSAFE","powerReport","ComputerPDP11.RESUME_PROMPT","unload","Usr.formatDate","store","fValidate","Component.confirmUser","sCode","RES","CODE","FAIL","Web.setLocalStorageItem","ComputerPDP11.STATE_USERID","resetUserID","powerRestore","donePowerOn","reload","asComments","controlPower","getUserID","dataPost","sUser","TYPE","sReport","sReportURL","sTimestamp","ComputerPDP11.STATE_VERSION","ComputerPDP11.STATE_HOSTURL","ComputerPDP11.STATE_BROWSER","fClearAll","fClear","saveServerState","ComputerPDP11.RESUME_DELETE","nDisplayLimit","getSpeedCurrent","fWaiting","B22","B18","B16","fPrompt","Web.getLocalStorageItem","verifyUserID","code","State.key","REQ","storeServerState","sError","fScroll","aeMachines","iMachine","eMachine","aeComputers","iComputer","eComputer","show","exit","sVersion","json","fParsed","key","State.prototype","Web.hasLocalStorage","fAll","cAsyncMachines","loadXML","sXMLFile","fResolve","display","doneLoadXML","sURLName","sXML","parseXML","buildXML","pathname","xmlDoc","async","parseFromString","DOMParser","resolveXML","matchRef","reRef","sRefFile","doneReadXML","sXMLRef","sRefAttrs","aXMLRefTag","sXMLNewTag","matchAttr","reAttr","embedMachine","sXSLFile","displayMessage","eWarning","aeWarning","Str.escapeHTML","displayError","Web.enablePageEvents","getElementById","css","styleSheet","cssText","createTextNode","sAppFolder","processXML","xml","transformXML","sXSL","xsl","sFragment","outerHTML","implementation","createDocument","xsltProcessor","XSLTProcessor","eFragment","replaceChild","embedPDP10","embedPDP11","commandMachine","fSingle","sComponent","sToken"],"sourcesContent":["\"use strict\";\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/defines.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @define {string}\n */\nvar APPVERSION = \"\"; // this @define is overridden by the Closure Compiler with the version in machines.json\n\nvar XMLVERSION = null; // this is set in non-COMPILED builds by embedMachine() if a version number was found in the machine XML\n\nvar COPYRIGHT = \"Copyright © 2012-2018 Jeff Parsons <Jeff@pcjs.org>\";\n\nvar LICENSE = \"License: GPL version 3 or later <http://gnu.org/licenses/gpl.html>\";\n\nvar CSSCLASS = \"pcjs\";\n\n/**\n * @define {string}\n */\nvar SITEHOST = \"localhost:8088\";// this @define is overridden by the Closure Compiler with \"www.pcjs.org\"\n\n/**\n * @define {boolean}\n */\nvar COMPILED = false; // this @define is overridden by the Closure Compiler (to true)\n\n/**\n * @define {boolean}\n */\nvar DEBUG = true; // this @define is overridden by the Closure Compiler (to false) to remove DEBUG-only code\n\n/**\n * @define {boolean}\n */\nvar MAXDEBUG = false; // this @define is overridden by the Closure Compiler (to false) to remove MAXDEBUG-only code\n\n/**\n * @define {boolean}\n */\nvar PRIVATE = false; // this @define is overridden by the Closure Compiler (to false) to enable PRIVATE code\n\n/*\n * RS-232 DB-25 Pin Definitions, mapped to bits 1-25 in a 32-bit status value.\n *\n * SerialPorts in PCjs machines are considered DTE (Data Terminal Equipment), which means they should be \"virtually\"\n * connected to each other via a null-modem cable, which assumes the following cross-wiring:\n *\n * G 1 <-> 1 G (Ground)\n * TD 2 <-> 3 RD (Received Data)\n * RD 3 <-> 2 TD (Transmitted Data)\n * RTS 4 <-> 5 CTS (Clear To Send)\n * CTS 5 <-> 4 RTS (Request To Send)\n * DSR 6+8 <-> 20 DTR (Data Terminal Ready)\n * SG 7 <-> 7 SG (Signal Ground)\n * DTR 20 <-> 6+8 DSR (Data Set Ready + Carrier Detect)\n * RI 22 <-> 22 RI (Ring Indicator)\n *\n * TODO: Move these definitions to a more appropriate shared file at some point.\n */\nvar RS232 = {\n RTS: {\n PIN: 4,\n MASK: 0x00000010\n },\n CTS: {\n PIN: 5,\n MASK: 0x00000020\n },\n DSR: {\n PIN: 6,\n MASK: 0x00000040\n },\n CD: {\n PIN: 8,\n MASK: 0x00000100\n },\n DTR: {\n PIN: 20,\n MASK: 0x00100000\n },\n RI: {\n PIN: 22,\n MASK: 0x00400000\n }\n};\n\n/*\n * NODE should be true if we're running under NodeJS (eg, command-line), false if not (eg, web browser)\n */\nvar NODE = false;\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/diskapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Our \"DiskIO API\" looks like:\n *\n * http://www.pcjs.org/api/v1/disk?action=open&volume=*10mb.img&mode=demandrw&chs=c:h:s&machine=xxx&user=yyy\n */\nvar DiskAPI = {\n ENDPOINT: \"/api/v1/disk\",\n QUERY: {\n ACTION: \"action\", // value is one of DiskAPI.ACTION.*\n VOLUME: \"volume\", // value is path of a disk image\n MODE: \"mode\", // value is one of DiskAPI.MODE.*\n CHS: \"chs\", // value is cylinders:heads:sectors:bytes\n ADDR: \"addr\", // value is cylinder:head:sector:count\n MACHINE: \"machine\", // value is machine token\n USER: \"user\", // value is user ID\n DATA: \"data\" // value is data to be written\n },\n ACTION: {\n OPEN: \"open\",\n READ: \"read\",\n WRITE: \"write\",\n CLOSE: \"close\"\n },\n MODE: {\n LOCAL: \"local\", // this mode implies no API (at best, localStorage backing only)\n PRELOAD: \"preload\", // this mode implies use of the DumpAPI\n DEMANDRW: \"demandrw\",\n DEMANDRO: \"demandro\"\n },\n FAIL: {\n BADACTION: \"invalid action\",\n BADUSER: \"invalid user\",\n BADVOL: \"invalid volume\",\n OPENVOL: \"unable to open volume\",\n CREATEVOL: \"unable to create volume\",\n WRITEVOL: \"unable to write volume\",\n REVOKED: \"access revoked\"\n }\n};\n\n/*\n * TODO: Eventually, our tools will need to support looking up disk formats by \"model\" rather than by raw disk size,\n * because obviously multiple disk geometries can yield the same raw disk size. For each conflict that arises, I'll\n * probably create a fake (approximate) disk size entry above, and then create a mapping to that approximate size below.\n */\nDiskAPI.MODELS = {\n \"RL01\": 5242880,\n \"RL02\": 10485760\n};\n\nDiskAPI.MBR = {\n PARTITIONS: {\n OFFSET: 0x1BE,\n ENTRY: {\n STATUS: 0x00, // 1-byte (0x80 if active)\n CHS_FIRST: 0x01, // 3-byte CHS specifier\n TYPE: 0x04, // 1-byte TYPE (see below)\n CHS_LAST: 0x05, // 3-byte CHS specifier\n LBA_FIRST: 0x08, // 4-byte Logical Block Address\n LBA_TOTAL: 0x0C, // 4-byte Logical Block Address\n },\n ENTRY_LENGTH: 0x10,\n STATUS: {\n ACTIVE: 0x80\n },\n TYPE: {\n EMPTY: 0x00,\n FAT12_PRIMARY: 0x01, // DOS 2.0 and up (12-bit FAT)\n FAT16_PRIMARY: 0x04 // DOS 3.0 and up (16-bit FAT)\n }\n },\n SIG_OFFSET: 0x1FE,\n SIGNATURE: 0xAA55 // to be clear, the low byte (at offset 0x1FE) is 0x55 and the high byte (at offset 0x1FF) is 0xAA\n};\n\n/*\n * Boot sector offsets (and assorted constants) in DOS-compatible boot sectors (DOS 2.0 and up)\n *\n * WARNING: I've heard apocryphal stories about SIGNATURE being improperly reversed on some systems\n * (ie, 0x55AA instead 0xAA55) -- perhaps by a dyslexic programmer -- so be careful out there.\n */\nDiskAPI.BOOT = {\n JMP_OPCODE: 0x000, // 1 byte for a JMP opcode, followed by a 1 or 2-byte offset\n OEM_STRING: 0x003, // 8 bytes\n SIG_OFFSET: 0x1FE,\n SIGNATURE: 0xAA55 // to be clear, the low byte (at offset 0x1FE) is 0x55 and the high byte (at offset 0x1FF) is 0xAA\n};\n\n/*\n * BIOS Parameter Block (BPB) offsets in DOS-compatible boot sectors (DOS 2.x and up)\n *\n * NOTE: DOS 2.x OEM documentation says that the words starting at offset 0x018 (TRACK_SECS, TOTAL_HEADS, and HIDDEN_SECS)\n * are optional, but even the DOS 2.0 FORMAT utility initializes all three of those words. There may be some OEM media out\n * there with BPBs that are only valid up to offset 0x018, but I've not run across any media like that.\n *\n * DOS 3.20 added LARGE_SECS, but unfortunately, it was added as a 2-byte value at offset 0x01E. DOS 3.31 decided\n * to make both HIDDEN_SECS and LARGE_SECS 4-byte values, which meant that LARGE_SECS had to move from 0x01E to 0x020.\n */\nDiskAPI.BPB = {\n SECTOR_BYTES: 0x00B, // 2 bytes: bytes per sector (eg, 0x200 or 512)\n CLUSTER_SECS: 0x00D, // 1 byte: sectors per cluster (eg, 1)\n RESERVED_SECS: 0x00E, // 2 bytes: reserved sectors; ie, # sectors preceding the first FAT--usually just the boot sector (eg, 1)\n TOTAL_FATS: 0x010, // 1 byte: FAT copies (eg, 2)\n ROOT_DIRENTS: 0x011, // 2 bytes: root directory entries (eg, 0x40 or 64) 0x40 * 0x20 = 0x800 (1 sector is 0x200 bytes, total of 4 sectors)\n TOTAL_SECS: 0x013, // 2 bytes: number of sectors (eg, 0x140 or 320); if zero, refer to LARGE_SECS\n MEDIA_ID: 0x015, // 1 byte: media ID (see DiskAPI.FAT.MEDIA_*); should also match the first byte of the FAT (aka FAT ID)\n FAT_SECS: 0x016, // 2 bytes: sectors per FAT (eg, 1)\n TRACK_SECS: 0x018, // 2 bytes: sectors per track (eg, 8)\n TOTAL_HEADS: 0x01A, // 2 bytes: number of heads (eg, 1)\n HIDDEN_SECS: 0x01C, // 2 bytes (DOS 2.x) or 4 bytes (DOS 3.31 and up): number of hidden sectors (always 0 for non-partitioned media)\n LARGE_SECS: 0x020 // 4 bytes (DOS 3.31 and up): number of sectors if TOTAL_SECS is zero\n};\n\n/*\n * Common (supported) diskette geometries.\n *\n * Each entry in GEOMETRIES is an array of values in \"CHS\" order:\n *\n * [# cylinders, # heads, # sectors/track, # bytes/sector, media ID]\n *\n * If the 4th value is omitted, the sector size is assumed to be 512. The order of these \"geometric\" values mirrors\n * the structure of our JSON-encoded disk images, which consist of an array of cylinders, each of which is an array of\n * heads, each of which is an array of sector objects.\n */\nDiskAPI.GEOMETRIES = {\n 163840: [40,1,8,,0xFE], // media ID 0xFE: 40 cylinders, 1 head (single-sided), 8 sectors/track, ( 320 total sectors x 512 bytes/sector == 163840)\n 184320: [40,1,9,,0xFC], // media ID 0xFC: 40 cylinders, 1 head (single-sided), 9 sectors/track, ( 360 total sectors x 512 bytes/sector == 184320)\n 327680: [40,2,8,,0xFF], // media ID 0xFF: 40 cylinders, 2 heads (double-sided), 8 sectors/track, ( 640 total sectors x 512 bytes/sector == 327680)\n 368640: [40,2,9,,0xFD], // media ID 0xFD: 40 cylinders, 2 heads (double-sided), 9 sectors/track, ( 720 total sectors x 512 bytes/sector == 368640)\n 737280: [80,2,9,,0xF9], // media ID 0xF9: 80 cylinders, 2 heads (double-sided), 9 sectors/track, (1440 total sectors x 512 bytes/sector == 737280)\n 1228800: [80,2,15,,0xF9], // media ID 0xF9: 80 cylinders, 2 heads (double-sided), 15 sectors/track, (2400 total sectors x 512 bytes/sector == 1228800)\n 1474560: [80,2,18,,0xF0], // media ID 0xF0: 80 cylinders, 2 heads (double-sided), 18 sectors/track, (2880 total sectors x 512 bytes/sector == 1474560)\n 2949120: [80,2,36,,0xF0], // media ID 0xF0: 80 cylinders, 2 heads (double-sided), 36 sectors/track, (5760 total sectors x 512 bytes/sector == 2949120)\n /*\n * The following are some common disk sizes and their CHS values, since missing or bogus MBR and/or BPB values\n * might mislead us when attempting to determine the exact disk geometry.\n */\n 10653696:[306,4,17], // PC XT 10Mb hard drive (type 3)\n 21411840:[615,4,17], // PC AT 20Mb hard drive (type 2)\n /*\n * Assorted DEC disk formats.\n */\n 256256: [77, 1,26,128], // RX01 single-platter diskette: 77 tracks, 1 head, 26 sectors/track, 128 bytes/sector, for a total of 256256 bytes\n 2494464: [203,2,12,512], // RK03 single-platter disk cartridge: 203 tracks, 2 heads, 12 sectors/track, 512 bytes/sector, for a total of 2494464 bytes\n 5242880: [256,2,40,256], // RL01K single-platter disk cartridge: 256 tracks, 2 heads, 40 sectors/track, 256 bytes/sector, for a total of 5242880 bytes\n 10485760:[512,2,40,256] // RL02K single-platter disk cartridge: 512 tracks, 2 heads, 40 sectors/track, 256 bytes/sector, for a total of 10485760 bytes\n};\n\n/*\n * Media ID (descriptor) bytes for DOS-compatible FAT-formatted disks (stored in the first byte of the FAT)\n */\nDiskAPI.FAT = {\n MEDIA_160KB: 0xFE, // 5.25-inch, 1-sided, 8-sector, 40-track\n MEDIA_180KB: 0xFC, // 5.25-inch, 1-sided, 9-sector, 40-track\n MEDIA_320KB: 0xFF, // 5.25-inch, 2-sided, 8-sector, 40-track\n MEDIA_360KB: 0xFD, // 5.25-inch, 2-sided, 9-sector, 40-track\n MEDIA_720KB: 0xF9, // 3.5-inch, 2-sided, 9-sector, 80-track\n MEDIA_1200KB: 0xF9, // 3.5-inch, 2-sided, 15-sector, 80-track\n MEDIA_FIXED: 0xF8, // fixed disk (aka hard drive)\n MEDIA_1440KB: 0xF0, // 3.5-inch, 2-sided, 18-sector, 80-track\n MEDIA_2880KB: 0xF0 // 3.5-inch, 2-sided, 36-sector, 80-track\n};\n\n/*\n * Cluster constants for 12-bit FATs (CLUSNUM_FREE, CLUSNUM_RES and CLUSNUM_MIN are the same for all FATs)\n */\nDiskAPI.FAT12 = {\n MAX_CLUSTERS: 4084,\n CLUSNUM_FREE: 0, // this should NEVER appear in cluster chain (except at the start of an empty chain)\n CLUSNUM_RES: 1, // reserved; this should NEVER appear in cluster chain\n CLUSNUM_MIN: 2, // smallest valid cluster number\n CLUSNUM_MAX: 0xFF6, // largest valid cluster number\n CLUSNUM_BAD: 0xFF7, // bad cluster; this should NEVER appear in cluster chain\n CLUSNUM_EOC: 0xFF8 // end of chain (actually, anything from 0xFF8-0xFFF indicates EOC)\n};\n\n/*\n * Cluster constants for 16-bit FATs (CLUSNUM_FREE, CLUSNUM_RES and CLUSNUM_MIN are the same for all FATs)\n */\nDiskAPI.FAT16 = {\n MAX_CLUSTERS: 65524,\n CLUSNUM_FREE: 0, // this should NEVER appear in cluster chain (except at the start of an empty chain)\n CLUSNUM_RES: 1, // reserved; this should NEVER appear in cluster chain\n CLUSNUM_MIN: 2, // smallest valid cluster number\n CLUSNUM_MAX: 0xFFF6, // largest valid cluster number\n CLUSNUM_BAD: 0xFFF7, // bad cluster; this should NEVER appear in cluster chain\n CLUSNUM_EOC: 0xFFF8 // end of chain (actually, anything from 0xFFF8-0xFFFF indicates EOC)\n};\n\n/*\n * Directory Entry offsets (and assorted constants) in FAT disk images\n *\n * NOTE: Versions of DOS prior to 2.0 used INVALID exclusively to mark available directory entries; any entry marked\n * UNUSED was actually considered USED. In DOS 2.0 and up, UNUSED was added to indicate that all remaining entries were\n * unused, relieving it from having to initialize the rest of the sectors in the directory cluster(s). And in fact,\n * you will likely encounter garbage in subsequent directory sectors if you read beyond the first UNUSED entry.\n */\nDiskAPI.DIRENT = {\n NAME: 0x000, // 8 bytes\n EXT: 0x008, // 3 bytes\n ATTR: 0x00B, // 1 byte\n MODTIME: 0x016, // 2 bytes\n MODDATE: 0x018, // 2 bytes\n CLUSTER: 0x01A, // 2 bytes\n SIZE: 0x01C, // 4 bytes (typically zero for subdirectories)\n LENGTH: 0x20, // 32 bytes total\n UNUSED: 0x00, // indicates this and all subsequent directory entries are unused\n INVALID: 0xE5 // indicates this directory entry is unused\n};\n\n/*\n * Possible values for DIRENT.ATTR\n */\nDiskAPI.ATTR = {\n READONLY: 0x01, // PC-DOS 2.0 and up\n HIDDEN: 0x02,\n SYSTEM: 0x04,\n LABEL: 0x08, // PC-DOS 2.0 and up\n SUBDIR: 0x10, // PC-DOS 2.0 and up\n ARCHIVE: 0x20 // PC-DOS 2.0 and up\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/dumpapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Our \"DiskDump API\", such as it was, used to look like:\n *\n * http://jsmachines.net/bin/convdisk.php?disk=/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json&format=img\n *\n * To make it (a bit) more \"REST-like\", the above request now looks like:\n *\n * http://www.pcjs.org/api/v1/dump?disk=/disks/pc/dos/ibm/2.00/PCDOS200-DISK1.json&format=img\n *\n * Similarly, our \"FileDump API\" used to look like:\n *\n * http://jsmachines.net/bin/convrom.php?rom=/devices/pc/rom/5150/1981-04-24/PCBIOS-REV1.rom&format=json\n *\n * and that request now looks like:\n *\n * http://www.pcjs.org/api/v1/dump?file=/devices/pc/rom/5150/1981-04-24/PCBIOS-REV1.rom&format=json\n *\n * I don't think it makes sense to avoid \"query\" parameters, because blending the path of a disk image with the\n * the rest of the URL would be (a) confusing, and (b) more work to parse.\n */\nvar DumpAPI = {\n ENDPOINT: \"/api/v1/dump\",\n QUERY: {\n DIR: \"dir\", // value is path of a directory (DiskDump only)\n DISK: \"disk\", // value is path of a disk image (DiskDump only)\n FILE: \"file\", // value is path of a ROM image file (FileDump only)\n IMG: \"img\", // alias for DISK\n PATH: \"path\", // value is path of a one or more files (DiskDump only)\n FORMAT: \"format\", // value is one of FORMAT values below\n COMMENTS: \"comments\", // value is either \"true\" or \"false\"\n DECIMAL: \"decimal\", // value is either \"true\" to force all numbers to decimal, \"false\" or undefined otherwise\n MBHD: \"mbhd\", // value is hard drive size in Mb (formerly \"mbsize\") (DiskDump only) (DEPRECATED)\n SIZE: \"size\" // value is target disk size in Kb (supersedes \"mbhd\") (DiskDump only)\n },\n FORMAT: {\n JSON: \"json\", // default\n JSON_GZ: \"gz\", // gzip is currently used ONLY for compressed JSON\n DATA: \"data\", // same as \"json\", but built without JSON.stringify() (DiskDump only)\n HEX: \"hex\", // deprecated\n OCTAL: \"octal\", // displays data as octal words\n BYTES: \"bytes\", // displays data as hex bytes; normally used only when comments are enabled\n WORDS: \"words\", // displays data as hex words; normally used only when comments are enabled\n LONGS: \"longs\", // displays data as dwords\n IMG: \"img\", // returns the raw disk data (ie, using a Buffer object) (DiskDump only)\n ROM: \"rom\" // returns the raw file data (ie, using a Buffer object) (FileDump only)\n }\n};\n\n/*\n * Because we use an overloaded API endpoint (ie, one that's shared with the FileDump module), we must\n * also provide a list of commands which, when combined with the endpoint, define a unique request.\n */\nDumpAPI.asDiskCommands = [DumpAPI.QUERY.DIR, DumpAPI.QUERY.DISK, DumpAPI.QUERY.PATH];\nDumpAPI.asFileCommands = [DumpAPI.QUERY.FILE];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/reportapi.js (C) Jeff Parsons 2012-2018\n */\n\nvar ReportAPI = {\n ENDPOINT: \"/api/v1/report\",\n QUERY: {\n APP: \"app\",\n VER: \"ver\",\n URL: \"url\",\n USER: \"user\",\n TYPE: \"type\",\n DATA: \"data\"\n },\n TYPE: {\n BUG: \"bug\"\n },\n RES: {\n OK: \"Thank you\"\n }\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/userapi.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * Examples of User API requests:\n *\n * web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.VERIFY + '&' + UserAPI.QUERY.USER + '=' + sUser;\n */\nvar UserAPI = {\n ENDPOINT: \"/api/v1/user\",\n QUERY: {\n REQ: \"req\", // specifies a request\n USER: \"user\", // specifies a user ID\n STATE: \"state\", // specifies a state ID\n DATA: \"data\" // specifies state data\n },\n REQ: {\n CREATE: \"create\", // creates a user ID\n VERIFY: \"verify\", // requests verification of a user ID\n STORE: \"store\", // stores a machine state on the server\n LOAD: \"load\" // loads a machine state from the server\n },\n RES: {\n CODE: \"code\",\n DATA: \"data\"\n },\n CODE: {\n OK: \"ok\",\n FAIL: \"error\"\n },\n FAIL: {\n DUPLICATE: \"user already exists\",\n VERIFY: \"unable to verify user\",\n BADSTATE: \"invalid state parameter\",\n NOSTATE: \"no machine state\",\n BADLOAD: \"unable to load machine state\",\n BADSTORE: \"unable to save machine state\"\n }\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/keys.js (C) Jeff Parsons 2012-2018\n */\n\nvar Keys = {\n /*\n * Keys and/or key combinations that generate common ASCII codes.\n *\n * NOTE: If you're looking for a general-purpose ASCII code table, see Str.ASCII in strlib.js;\n * if something's missing, that's probably the more appropriate table to add it to.\n *\n * TODO: The Closure Compiler doesn't inline all references to these values, at least those with\n * quoted property names, which is why I've 'unquoted' as many of them as possible. One solution\n * would be to add mnemonics for all of them, not just the non-printable ones (eg, SPACE instead\n * of ' ', AMP instead of '&', etc.)\n */\n ASCII: {\n BREAK: 0, CTRL_A: 1, CTRL_B: 2, CTRL_C: 3, CTRL_D: 4, CTRL_E: 5, CTRL_F: 6, CTRL_G: 7,\n CTRL_H: 8, CTRL_I: 9, CTRL_J: 10, CTRL_K: 11, CTRL_L: 12, CTRL_M: 13, CTRL_N: 14, CTRL_O: 15,\n CTRL_P: 16, CTRL_Q: 17, CTRL_R: 18, CTRL_S: 19, CTRL_T: 20, CTRL_U: 21, CTRL_V: 22, CTRL_W: 23,\n CTRL_X: 24, CTRL_Y: 25, CTRL_Z: 26, ESC: 27,\n ' ': 32, '!': 33, '\"': 34, '#': 35, '$': 36, '%': 37, '&': 38, \"'\": 39,\n '(': 40, ')': 41, '*': 42, '+': 43, ',': 44, '-': 45, '.': 46, '/': 47,\n '0': 48, '1': 49, '2': 50, '3': 51, '4': 52, '5': 53, '6': 54, '7': 55,\n '8': 56, '9': 57, ':': 58, ';': 59, '<': 60, '=': 61, '>': 62, '?': 63,\n '@': 64, A: 65, B: 66, C: 67, D: 68, E: 69, F: 70, G: 71,\n H: 72, I: 73, J: 74, K: 75, L: 76, M: 77, N: 78, O: 79,\n P: 80, Q: 81, R: 82, S: 83, T: 84, U: 85, V: 86, W: 87,\n X: 88, Y: 89, Z: 90, '[': 91, '\\\\':92, ']': 93, '^': 94, '_': 95,\n '`': 96, a: 97, b: 98, c: 99, d: 100, e: 101, f: 102, g: 103,\n h: 104, i: 105, j: 106, k: 107, l: 108, m: 109, n: 110, o: 111,\n p: 112, q: 113, r: 114, s: 115, t: 116, u: 117, v: 118, w: 119,\n x: 120, y: 121, z: 122, '{':123, '|':124, '}':125, '~':126, DEL: 127\n },\n /*\n * Browser keyCodes we must pay particular attention to. For the most part, these are non-alphanumeric\n * or function keys, some which may require special treatment (eg, preventDefault() if returning false on\n * the initial keyDown event is insufficient).\n *\n * keyCodes for most common ASCII keys can simply use the appropriate ASCII code above.\n *\n * Most of these represent non-ASCII keys (eg, the LEFT arrow key), yet for some reason, browsers defined\n * them using ASCII codes (eg, the LEFT arrow key uses the ASCII code for '%' or 37).\n */\n KEYCODE: {\n /* 0x08 */ BS: 8, // BACKSPACE (ASCII.CTRL_H)\n /* 0x09 */ TAB: 9, // TAB (ASCII.CTRL_I)\n /* 0x0A */ LF: 10, // LINE-FEED (ASCII.CTRL_J) (Some Windows-based browsers used to generate this via CTRL-ENTER)\n /* 0x0D */ CR: 13, // CARRIAGE RETURN (ASCII.CTRL_M)\n /* 0x10 */ SHIFT: 16,\n /* 0x11 */ CTRL: 17,\n /* 0x12 */ ALT: 18,\n /* 0x13 */ PAUSE: 19, // PAUSE/BREAK\n /* 0x14 */ CAPS_LOCK: 20,\n /* 0x1B */ ESC: 27,\n /* 0x20 */ SPACE: 32,\n /* 0x21 */ PGUP: 33,\n /* 0x22 */ PGDN: 34,\n /* 0x23 */ END: 35,\n /* 0x24 */ HOME: 36,\n /* 0x25 */ LEFT: 37,\n /* 0x26 */ UP: 38,\n /* 0x27 */ RIGHT: 39,\n /* 0x27 */ FF_QUOTE: 39,\n /* 0x28 */ DOWN: 40,\n /* 0x2C */ FF_COMMA: 44,\n /* 0x2C */ PRTSC: 44,\n /* 0x2D */ INS: 45,\n /* 0x2E */ DEL: 46,\n /* 0x2E */ FF_PERIOD: 46,\n /* 0x2F */ FF_SLASH: 47,\n /* 0x30 */ ZERO: 48,\n /* 0x31 */ ONE: 49,\n /* 0x32 */ TWO: 50,\n /* 0x33 */ THREE: 51,\n /* 0x34 */ FOUR: 52,\n /* 0x35 */ FIVE: 53,\n /* 0x36 */ SIX: 54,\n /* 0x37 */ SEVEN: 55,\n /* 0x38 */ EIGHT: 56,\n /* 0x39 */ NINE: 57,\n /* 0x3B */ FF_SEMI: 59,\n /* 0x3D */ FF_EQUALS: 61,\n /* 0x5B */ CMD: 91, // aka WIN\n /* 0x5B */ FF_LBRACK: 91,\n /* 0x5C */ FF_BSLASH: 92,\n /* 0x5D */ RCMD: 93, // aka MENU\n /* 0x5D */ FF_RBRACK: 93,\n /* 0x60 */ NUM_0: 96,\n /* 0x60 */ NUM_INS: 96,\n /* 0x60 */ FF_BQUOTE: 96,\n /* 0x61 */ NUM_1: 97,\n /* 0x61 */ NUM_END: 97,\n /* 0x62 */ NUM_2: 98,\n /* 0x62 */ NUM_DOWN: 98,\n /* 0x63 */ NUM_3: 99,\n /* 0x63 */ NUM_PGDN: 99,\n /* 0x64 */ NUM_4: 100,\n /* 0x64 */ NUM_LEFT: 100,\n /* 0x65 */ NUM_5: 101,\n /* 0x65 */ NUM_CENTER: 101,\n /* 0x66 */ NUM_6: 102,\n /* 0x66 */ NUM_RIGHT: 102,\n /* 0x67 */ NUM_7: 103,\n /* 0x67 */ NUM_HOME: 103,\n /* 0x68 */ NUM_8: 104,\n /* 0x68 */ NUM_UP: 104,\n /* 0x69 */ NUM_9: 105,\n /* 0x69 */ NUM_PGUP: 105,\n /* 0x6A */ NUM_MUL: 106,\n /* 0x6B */ NUM_ADD: 107,\n /* 0x6D */ NUM_SUB: 109,\n /* 0x6E */ NUM_DEL: 110, // aka PERIOD\n /* 0x6F */ NUM_DIV: 111,\n /* 0x70 */ F1: 112,\n /* 0x71 */ F2: 113,\n /* 0x72 */ F3: 114,\n /* 0x73 */ F4: 115,\n /* 0x74 */ F5: 116,\n /* 0x75 */ F6: 117,\n /* 0x76 */ F7: 118,\n /* 0x77 */ F8: 119,\n /* 0x78 */ F9: 120,\n /* 0x79 */ F10: 121,\n /* 0x7A */ F11: 122,\n /* 0x7B */ F12: 123,\n /* 0x90 */ NUM_LOCK: 144,\n /* 0x91 */ SCROLL_LOCK: 145,\n /* 0xAD */ FF_DASH: 173,\n /* 0xBA */ SEMI: 186, // Firefox: 59 (FF_SEMI)\n /* 0xBB */ EQUALS: 187, // Firefox: 61 (FF_EQUALS)\n /* 0xBC */ COMMA: 188,\n /* 0xBD */ DASH: 189, // Firefox: 173 (FF_DASH)\n /* 0xBE */ PERIOD: 190,\n /* 0xBF */ SLASH: 191,\n /* 0xC0 */ BQUOTE: 192,\n /* 0xDB */ LBRACK: 219,\n /* 0xDC */ BSLASH: 220,\n /* 0xDD */ RBRACK: 221,\n /* 0xDE */ QUOTE: 222,\n /* 0xE0 */ FF_CMD: 224, // Firefox only (used for both CMD and RCMD)\n //\n // The following biases use what I'll call Decimal Coded Binary or DCB (the opposite of BCD),\n // where the thousands digit is used to store the sum of \"binary\" digits 1 and/or 2 and/or 4.\n //\n // Technically, that makes it DCO (Decimal Coded Octal), but then again, BCD should have really\n // been called HCD (Hexadecimal Coded Decimal), so if \"they\" can take liberties, so can I.\n //\n // ONDOWN is a bias we add to browser keyCodes that we want to handle on \"down\" rather than on \"press\".\n //\n ONDOWN: 1000,\n //\n // ONRIGHT is a bias we add to browser keyCodes that need to check for a \"right\" location (default is \"left\")\n //\n ONRIGHT: 2000,\n //\n // FAKE is a bias we add to signal these are fake keyCodes corresponding to internal keystroke combinations.\n // The actual values are for internal use only and merely need to be unique and used consistently.\n //\n FAKE: 4000\n },\n /*\n * The set of values that a browser may store in the 'location' property of a keyboard event object\n * which we also support.\n */\n LOCATION: {\n LEFT: 1,\n RIGHT: 2,\n NUMPAD: 3\n }\n};\n\n/*\n * Check the event object's 'location' property for a non-zero value for the following ONRIGHT keys.\n */\nKeys.KEYCODE.NUM_CR = Keys.KEYCODE.CR + Keys.KEYCODE.ONRIGHT;\n\n\n/*\n * Maps Firefox keyCodes to their more common keyCode counterparts; a number of entries in this table\n * are no longer valid (if indeed they ever were), so they've been commented out. It's likely that I\n * simply extended this table to resolve additional differences in other browsers (ie, Opera), but without\n * browser-specific checks, it's not safe to perform all the mappings shown below.\n */\nKeys.FF_KEYCODES = {};\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_SEMI] = Keys.KEYCODE.SEMI; // 59 -> 186\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_EQUALS] = Keys.KEYCODE.EQUALS; // 61 -> 187\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.KEYCODE.DASH; // 173 -> 189\nKeys.FF_KEYCODES[Keys.KEYCODE.FF_CMD] = Keys.KEYCODE.CMD; // 224 -> 91\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_COMMA] = Keys.KEYCODE.COMMA; // 44 -> 188\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_PERIOD] = Keys.KEYCODE.PERIOD; // 46 -> 190\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_SLASH] = Keys.KEYCODE.SLASH; // 47 -> 191\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_BQUOTE] = Keys.KEYCODE.BQUOTE; // 96 -> 192\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_LBRACK = Keys.KEYCODE.LBRACK; // 91 -> 219\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_BSLASH] = Keys.KEYCODE.BSLASH; // 92 -> 220\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_RBRACK] = Keys.KEYCODE.RBRACK; // 93 -> 221\n// Keys.FF_KEYCODES[Keys.KEYCODE.FF_QUOTE] = Keys.KEYCODE.QUOTE; // 39 -> 222\n\n/*\n * Maps non-ASCII keyCodes to their ASCII counterparts\n */\nKeys.NONASCII_KEYCODES = {};\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.ASCII['-']; // 173 -> 45\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.SEMI] = Keys.ASCII[';']; // 186 -> 59\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.EQUALS] = Keys.ASCII['=']; // 187 -> 61\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.DASH] = Keys.ASCII['-']; // 189 -> 45\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.COMMA] = Keys.ASCII[',']; // 188 -> 44\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.PERIOD] = Keys.ASCII['.']; // 190 -> 46\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.SLASH] = Keys.ASCII['/']; // 191 -> 47\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.BQUOTE] = Keys.ASCII['`']; // 192 -> 96\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.LBRACK] = Keys.ASCII['[']; // 219 -> 91\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.BSLASH] = Keys.ASCII['\\\\']; // 220 -> 92\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.RBRACK] = Keys.ASCII[']']; // 221 -> 93\nKeys.NONASCII_KEYCODES[Keys.KEYCODE.QUOTE] = Keys.ASCII[\"'\"]; // 222 -> 39\n\n/*\n * Maps unshifted keyCodes to their shifted counterparts; to be used when a shift-key is down.\n * Alphabetic characters are handled in code, since they must also take CAPS_LOCK into consideration.\n */\nKeys.SHIFTED_KEYCODES = {};\nKeys.SHIFTED_KEYCODES[Keys.ASCII['1']] = Keys.ASCII['!'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['2']] = Keys.ASCII['@'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['3']] = Keys.ASCII['#'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['4']] = Keys.ASCII['$'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['5']] = Keys.ASCII['%'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['6']] = Keys.ASCII['^'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['7']] = Keys.ASCII['&'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['8']] = Keys.ASCII['*'];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['9']] = Keys.ASCII['('];\nKeys.SHIFTED_KEYCODES[Keys.ASCII['0']] = Keys.ASCII[')'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.SEMI] = Keys.ASCII[':'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.EQUALS] = Keys.ASCII['+'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.COMMA] = Keys.ASCII['<'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.DASH] = Keys.ASCII['_'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.PERIOD] = Keys.ASCII['>'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.SLASH] = Keys.ASCII['?'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.BQUOTE] = Keys.ASCII['~'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.LBRACK] = Keys.ASCII['{'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.BSLASH] = Keys.ASCII['|'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.RBRACK] = Keys.ASCII['}'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.QUOTE] = Keys.ASCII['\"'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.ASCII['_'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_EQUALS] = Keys.ASCII['+'];\nKeys.SHIFTED_KEYCODES[Keys.KEYCODE.FF_SEMI] = Keys.ASCII[':'];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/strlib.js (C) Jeff Parsons 2012-2018\n */\n\nclass Str {\n /**\n * isValidInt(s, base)\n *\n * The built-in parseInt() function has the annoying feature of returning a partial value (ie,\n * up to the point where it encounters an invalid character); eg, parseInt(\"foo\", 16) returns 0xf.\n *\n * So it's best to use our own Str.parseInt() function, which will in turn use this function to\n * validate the entire string.\n *\n * @param {string} s is the string representation of some number\n * @param {number} [base] is the radix to use (default is 10); only 2, 8, 10 and 16 are supported\n * @return {boolean} true if valid, false if invalid (or the specified base isn't supported)\n */\n static isValidInt(s, base)\n {\n if (!base || base == 10) return s.match(/^-?[0-9]+$/) !== null;\n if (base == 16) return s.match(/^-?[0-9a-f]+$/i) !== null;\n if (base == 8) return s.match(/^-?[0-7]+$/) !== null;\n if (base == 2) return s.match(/^-?[01]+$/) !== null;\n return false;\n }\n\n /**\n * parseInt(s, base)\n *\n * This is a wrapper around the built-in parseInt() function. Our wrapper recognizes certain prefixes\n * ('$' or \"0x\" for hex, '#' or \"0o\" for octal) and suffixes ('.' for decimal, 'h' for hex, 'y' for\n * binary), and then calls isValidInt() to ensure we don't convert strings that contain partial values;\n * see isValidInt() for details.\n *\n * The use of multiple prefix/suffix combinations is undefined (although for the record, we process\n * prefixes first). We do NOT support the \"0b\" prefix to indicate binary UNLESS one or more commas are\n * also present (because \"0b\" is also a valid hex sequence), and we do NOT support a single leading zero\n * to indicate octal (because such a number could also be decimal or hex). Any number of commas are\n * allowed; we remove them all before calling the built-in parseInt().\n *\n * More recently, we've added support for \"^D\", \"^O\", and \"^B\" prefixes to accommodate the base overrides\n * that the PDP-10's MACRO-10 assembly language supports (decimal, octal, and binary, respectively).\n * If this support turns out to adversely affect other debuggers, then it will have to be \"conditionalized\".\n * Similarly, we've added support for \"K\", \"M\", and \"G\" MACRO-10-style suffixes that add 3, 6, or 9 zeros\n * to the value to be parsed, respectively.\n *\n * @param {string} s is the string representation of some number\n * @param {number} [base] is the radix to use (default is 10); can be overridden by prefixes/suffixes\n * @return {number|undefined} corresponding value, or undefined if invalid\n */\n static parseInt(s, base)\n {\n var value;\n\n if (s) {\n if (!base) base = 10;\n\n var ch, chPrefix, chSuffix;\n var fCommas = (s.indexOf(',') > 0);\n if (fCommas) s = s.replace(/,/g, '');\n\n ch = chPrefix = s.charAt(0);\n if (chPrefix == '#') {\n base = 8;\n chPrefix = '';\n }\n else if (chPrefix == '$') {\n base = 16;\n chPrefix = '';\n }\n if (ch != chPrefix) {\n s = s.substr(1);\n }\n else {\n ch = chPrefix = s.substr(0, 2);\n if (chPrefix == '0b' && fCommas || chPrefix == '^B') {\n base = 2;\n chPrefix = '';\n }\n else if (chPrefix == '0o' || chPrefix == '^O') {\n base = 8;\n chPrefix = '';\n }\n else if (chPrefix == '^D') {\n base = 10;\n chPrefix = '';\n }\n else if (chPrefix == '0x') {\n base = 16;\n chPrefix = '';\n }\n if (ch != chPrefix) s = s.substr(2);\n }\n ch = chSuffix = s.slice(-1);\n if (chSuffix == 'Y' || chSuffix == 'y') {\n base = 2;\n chSuffix = '';\n }\n else if (chSuffix == '.') {\n base = 10;\n chSuffix = '';\n }\n else if (chSuffix == 'H' || chSuffix == 'h') {\n base = 16;\n chSuffix = '';\n }\n else if (chSuffix == 'K') {\n chSuffix = '000';\n }\n else if (chSuffix == 'M') {\n chSuffix = '000000';\n }\n else if (chSuffix == 'G') {\n chSuffix = '000000000';\n }\n if (ch != chSuffix) s = s.slice(0, -1) + chSuffix;\n /*\n * This adds support for the MACRO-10 binary shifting (Bn) suffix, which must be stripped from the\n * number before parsing, and then applied to the value after parsing. If n is omitted, 35 is assumed,\n * which is a net shift of zero. If n < 35, then a left shift of (35 - n) is required; if n > 35, then\n * a right shift of -(35 - n) is required.\n */\n var v, shift = 0;\n if (base <= 10) {\n var match = s.match(/(-?[0-9]+)B([0-9]*)/);\n if (match) {\n s = match[1];\n shift = 35 - ((match[2] || 35) & 0xff);\n }\n }\n if (Str.isValidInt(s, base) && !isNaN(v = parseInt(s, base))) {\n /*\n * With the need to support larger (eg, 36-bit) integers, truncating to 32 bits is no longer helpful.\n *\n * value = v|0;\n */\n if (shift) {\n /*\n * Since binary shifting is a logical operation, and since shifting by division only works properly\n * with positive numbers, we must convert a negative value to a positive value, by computing the two's\n * complement.\n */\n if (v < 0) v += Math.pow(2, 36);\n if (shift > 0) {\n v *= Math.pow(2, shift);\n } else {\n v = Math.trunc(v / Math.pow(2, -shift));\n }\n }\n value = v;\n }\n }\n return value;\n }\n\n /**\n * toBase(n, radix, cch, sPrefix, nGrouping)\n *\n * Displays the given number as an unsigned integer using the specified radix and number of digits.\n *\n * @param {number|*} n\n * @param {number} radix (ie, the base)\n * @param {number} cch (the desired number of digits)\n * @param {string} [sPrefix] (default is none)\n * @param {number} [nGrouping]\n * @return {string}\n */\n static toBase(n, radix, cch, sPrefix = \"\", nGrouping = 0)\n {\n /*\n * We can't rely entirely on isNaN(), because isNaN(null) returns false, and we can't rely\n * entirely on typeof either, because typeof Nan returns \"number\". Sigh.\n *\n * Alternatively, we could mask and shift n regardless of whether it's null/undefined/NaN,\n * since JavaScript coerces such operands to zero, but I think there's \"value\" in seeing those\n * values displayed differently.\n */\n var s = \"\";\n if (isNaN(n) || typeof n != \"number\") {\n n = null;\n } else {\n /*\n * Callers that produced an input by dividing by a power of two rather than shifting (in order\n * to access more than 32 bits) may produce a fractional result, which ordinarily we would simply\n * ignore, but if the integer portion is zero and the sign is negative, we should probably treat\n * this value as a sign-extension.\n */\n if (n < 0 && n > -1) n = -1;\n /*\n * Negative values should be two's complemented according to the number of digits; for example,\n * 12 octal digits implies an upper limit 8^12.\n */\n if (n < 0) {\n n += Math.pow(radix, cch);\n }\n if (n >= Math.pow(radix, cch)) {\n cch = Math.ceil(Math.log(n) / Math.log(radix));\n }\n }\n var g = nGrouping || -1;\n while (cch-- > 0) {\n if (!g) {\n s = ',' + s;\n g = nGrouping;\n }\n if (n == null) {\n s = '?' + s;\n } else {\n var d = n % radix;\n d += (d >= 0 && d <= 9? 0x30 : 0x41 - 10);\n s = String.fromCharCode(d) + s;\n n = Math.trunc(n / radix);\n }\n g--;\n }\n return sPrefix + s;\n }\n\n /**\n * toBin(n, cch, nGrouping)\n *\n * Converts an integer to binary, with the specified number of digits (up to a maximum of 36).\n *\n * @param {number|*} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of binary digits (0 or undefined for default of either 8, 18, or 36)\n * @param {number} [nGrouping]\n * @return {string} the binary representation of n\n */\n static toBin(n, cch, nGrouping)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.LN2) || 1;\n var v = Math.abs(n);\n if (v <= 0b11111111) {\n cch = 8;\n } else if (v <= 0b111111111111111111) {\n cch = 18;\n } else {\n cch = 36;\n }\n } else if (cch > 36) cch = 36;\n return Str.toBase(n, 2, cch, \"\", nGrouping);\n }\n\n /**\n * toBinBytes(n, cb, fPrefix)\n *\n * Converts an integer to binary, with the specified number of bytes (up to the default of 4).\n *\n * @param {number|null|undefined} n (interpreted as a 32-bit value)\n * @param {number} [cb] is the desired number of binary bytes (4 is both the default and the maximum)\n * @param {boolean} [fPrefix]\n * @return {string} the binary representation of n\n */\n static toBinBytes(n, cb, fPrefix)\n {\n var s = \"\";\n if (!cb || cb > 4) cb = 4;\n for (var i = 0; i < cb; i++) {\n if (s) s = ',' + s;\n s = Str.toBin(n & 0xff, 8) + s;\n n >>= 8;\n }\n return (fPrefix? \"0b\" : \"\") + s;\n }\n\n /**\n * toOct(n, cch, fPrefix)\n *\n * Converts an integer to octal, with the specified number of digits (default of 6; max of 12)\n *\n * You might be tempted to use the built-in n.toString(8) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw\n * an exception, whereas this function will return '?' characters.\n *\n * @param {number|*} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of octal digits (0 or undefined for default of either 6, 8, or 12)\n * @param {boolean} [fPrefix]\n * @return {string} the octal representation of n\n */\n static toOct(n, cch, fPrefix)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.log(8)) || 1;\n var v = Math.abs(n);\n if (v <= 0o777777) {\n cch = 6;\n } else if (v <= 0o77777777) {\n cch = 8;\n } else {\n cch = 12;\n }\n } else if (cch > 12) cch = 12;\n return Str.toBase(n, 8, cch, fPrefix? \"0o\" : \"\");\n }\n\n /**\n * toDec(n, cch)\n *\n * Converts an integer to decimal, with the specified number of digits (default of 5; max of 11)\n *\n * You might be tempted to use the built-in n.toString(10) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values. Moreover, if n is undefined, n.toString() will throw\n * an exception, whereas this function will return '?' characters.\n *\n * @param {number|*} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of decimal digits (0 or undefined for default of either 5 or 11)\n * @return {string} the decimal representation of n\n */\n static toDec(n, cch)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.LN10) || 1;\n var v = Math.abs(n);\n if (v <= 99999) {\n cch = 5;\n } else {\n cch = 11;\n }\n } else if (cch > 11) cch = 11;\n return Str.toBase(n, 10, cch);\n }\n\n /**\n * toHex(n, cch, fPrefix)\n *\n * Converts an integer to hex, with the specified number of digits (default of 4 or 8, max of 9).\n *\n * You might be tempted to use the built-in n.toString(16) instead, but it doesn't zero-pad and it\n * doesn't properly convert negative values; for example, if n is -2147483647, then n.toString(16)\n * will return \"-7fffffff\" instead of \"80000001\". Moreover, if n is undefined, n.toString() will\n * throw an exception, whereas this function will return '?' characters.\n *\n * NOTE: The following work-around (adapted from code found on StackOverflow) would be another solution,\n * taking care of negative values, zero-padding, and upper-casing, but not null/undefined/NaN values:\n *\n * s = (n < 0? n + 0x100000000 : n).toString(16);\n * s = \"00000000\".substr(0, 8 - s.length) + s;\n * s = s.substr(0, cch).toUpperCase();\n *\n * @param {number|*} n (supports integers up to 36 bits now)\n * @param {number} [cch] is the desired number of hex digits (0 or undefined for default of either 4, 8, or 9)\n * @param {boolean} [fPrefix]\n * @return {string} the hex representation of n\n */\n static toHex(n, cch, fPrefix)\n {\n if (!cch) {\n // cch = Math.ceil(Math.log(Math.abs(n) + 1) / Math.log(16)) || 1;\n var v = Math.abs(n);\n if (v <= 0xffff) {\n cch = 4;\n } else if (v <= 0xffffffff) {\n cch = 8;\n } else {\n cch = 9;\n }\n } else if (cch > 9) cch = 9;\n return Str.toBase(n, 16, cch, fPrefix? \"0x\" : \"\");\n }\n\n /**\n * toHexByte(b)\n *\n * Alias for Str.toHex(b, 2, true)\n *\n * @param {number|null|undefined} b is a byte value\n * @return {string} the hex representation of b\n */\n static toHexByte(b)\n {\n return Str.toHex(b, 2, true);\n }\n\n /**\n * toHexWord(w)\n *\n * Alias for Str.toHex(w, 4, true)\n *\n * @param {number|null|undefined} w is a word (16-bit) value\n * @return {string} the hex representation of w\n */\n static toHexWord(w)\n {\n return Str.toHex(w, 4, true);\n }\n\n /**\n * toHexLong(l)\n *\n * Alias for Str.toHex(l, 8, true)\n *\n * @param {number|null|undefined} l is a dword (32-bit) value\n * @return {string} the hex representation of w\n */\n static toHexLong(l)\n {\n return Str.toHex(l, 8, true);\n }\n\n /**\n * getBaseName(sFileName, fStripExt)\n *\n * This is a poor-man's version of Node's path.basename(), which Node-only components should use instead.\n *\n * Note that if fStripExt is true, this strips ANY extension, whereas path.basename() strips the extension only\n * if it matches the second parameter (eg, path.basename(\"/foo/bar/baz/asdf/quux.html\", \".html\") returns \"quux\").\n *\n * @param {string} sFileName\n * @param {boolean} [fStripExt]\n * @return {string}\n */\n static getBaseName(sFileName, fStripExt)\n {\n var sBaseName = sFileName;\n\n var i = sFileName.lastIndexOf('/');\n if (i >= 0) sBaseName = sFileName.substr(i + 1);\n\n /*\n * This next bit is a kludge to clean up names that are part of a URL that includes unsightly query parameters.\n */\n i = sBaseName.indexOf('&');\n if (i > 0) sBaseName = sBaseName.substr(0, i);\n\n if (fStripExt) {\n i = sBaseName.lastIndexOf(\".\");\n if (i > 0) {\n sBaseName = sBaseName.substring(0, i);\n }\n }\n return sBaseName;\n }\n\n /**\n * getExtension(sFileName)\n *\n * This is a poor-man's version of Node's path.extname(), which Node-only components should use instead.\n *\n * Note that we EXCLUDE the period from the returned extension, whereas path.extname() includes it.\n *\n * @param {string} sFileName\n * @return {string} the filename's extension (in lower-case and EXCLUDING the \".\"), or an empty string\n */\n static getExtension(sFileName)\n {\n var sExtension = \"\";\n var i = sFileName.lastIndexOf(\".\");\n if (i >= 0) {\n sExtension = sFileName.substr(i + 1).toLowerCase();\n }\n return sExtension;\n }\n\n /**\n * endsWith(s, sSuffix)\n *\n * @param {string} s\n * @param {string} sSuffix\n * @return {boolean} true if s ends with sSuffix, false if not\n */\n static endsWith(s, sSuffix)\n {\n return s.indexOf(sSuffix, s.length - sSuffix.length) !== -1;\n }\n\n /**\n * escapeHTML(sHTML)\n *\n * @param {string} sHTML\n * @return {string} with HTML entities \"escaped\", similar to PHP's htmlspecialchars()\n */\n static escapeHTML(sHTML)\n {\n return sHTML.replace(/[&<>\"']/g, function(m)\n {\n return Str.HTMLEscapeMap[m];\n });\n }\n\n /**\n * replace(sSearch, sReplace, s)\n *\n * The JavaScript replace() function ALWAYS interprets \"$\" specially in replacement strings, even when\n * the search string is NOT a RegExp; specifically:\n *\n * $$ Inserts a \"$\"\n * $& Inserts the matched substring\n * $` Inserts the portion of the string that precedes the matched substring\n * $' Inserts the portion of the string that follows the matched substring\n * $n Where n is a positive integer less than 100, inserts the nth parenthesized sub-match string,\n * provided the first argument was a RegExp object\n *\n * So, if a replacement string containing dollar signs passes through a series of replace() calls, untold\n * problems could result. Hence, this function, which simply uses the replacement string as-is.\n *\n * Similar to the JavaScript replace() method (when sSearch is a string), this replaces only ONE occurrence\n * (ie, the FIRST occurrence); it might be nice to add options to replace the LAST occurrence and/or ALL\n * occurrences, but we'll revisit that later.\n *\n * @param {string} sSearch\n * @param {string} sReplace\n * @param {string} s\n * @return {string}\n */\n static replace(sSearch, sReplace, s)\n {\n var i = s.indexOf(sSearch);\n if (i >= 0) {\n s = s.substr(0, i) + sReplace + s.substr(i + sSearch.length);\n }\n return s;\n }\n\n /**\n * replaceAll(sSearch, sReplace, s)\n *\n * @param {string} sSearch\n * @param {string} sReplace\n * @param {string} s\n * @return {string}\n */\n static replaceAll(sSearch, sReplace, s)\n {\n var a = {};\n a[sSearch] = sReplace;\n return Str.replaceArray(a, s);\n }\n\n /**\n * replaceArray(a, s)\n *\n * @param {Object} a\n * @param {string} s\n * @return {string}\n */\n static replaceArray(a, s)\n {\n var sMatch = \"\";\n for (var k in a) {\n /*\n * As noted in:\n *\n * http://www.regexguru.com/2008/04/escape-characters-only-when-necessary/\n *\n * inside character classes, only backslash, caret, hyphen and the closing bracket need to be\n * escaped. And in fact, if you ensure that the closing bracket is first, the caret is not first,\n * and the hyphen is last, you can avoid escaping those as well.\n */\n k = k.replace(/([\\\\[\\]*{}().+?|$])/g, \"\\\\$1\");\n sMatch += (sMatch? '|' : '') + k;\n }\n return s.replace(new RegExp('(' + sMatch + ')', \"g\"), function(m)\n {\n return a[m];\n });\n }\n\n /**\n * pad(s, cch, fPadLeft)\n *\n * NOTE: the maximum amount of padding currently supported is 40 spaces.\n *\n * @param {string} s is a string\n * @param {number} cch is desired length\n * @param {boolean} [fPadLeft] (default is padding on the right)\n * @return {string} the original string (s) with spaces padding it to the specified length\n */\n static pad(s, cch, fPadLeft)\n {\n var sPadding = \" \";\n return fPadLeft? (sPadding + s).slice(-cch) : (s + sPadding).slice(0, cch);\n }\n\n /**\n * sprintf(format, ...args)\n *\n * Copied from the CCjs project (https://github.com/jeffpar/ccjs/blob/master/lib/stdio.js) and extended.\n *\n * Far from complete, let alone sprintf-compatible, but it's adequate for the handful of sprintf-style format\n * specifiers that I use.\n *\n * @param {string} format\n * @param {...} args\n * @return {string}\n */\n static sprintf(format, ...args)\n {\n let buffer = \"\";\n let aParts = format.split(/%([-+ 0#]?)([0-9]*)(\\.?)([0-9]*)([hlL]?)([A-Za-z%])/);\n\n let iArg = 0, iPart;\n for (iPart = 0; iPart < aParts.length - 7; iPart += 7) {\n\n buffer += aParts[iPart];\n\n let arg = args[iArg++];\n let flags = aParts[iPart+1];\n let minimum = +aParts[iPart+2] || 0;\n let precision = +aParts[iPart+4] || 0;\n let conversion = aParts[iPart+6];\n let ach = null, s;\n\n switch(conversion) {\n case 'd':\n /*\n * We could use \"arg |= 0\", but there may be some value to supporting integers > 32 bits.\n * \n * Also, unlike the 'X' and 'x' hexadecimal cases, there's no need to explicitly check for a string\n * arguments, because the call to trunc() automatically coerces any string value to a (decimal) number.\n */\n arg = Math.trunc(arg);\n /* falls through */\n\n case 'f':\n s = Math.trunc(arg) + \"\";\n if (precision) {\n minimum -= (precision + 1);\n }\n if (s.length < minimum) {\n if (flags == '0') {\n if (arg < 0) minimum--;\n s = (\"0000000000\" + Math.abs(arg)).slice(-minimum);\n if (arg < 0) s = '-' + s;\n } else {\n s = (\" \" + s).slice(-minimum);\n }\n }\n if (precision) {\n arg = Math.round((arg - Math.trunc(arg)) * Math.pow(10, precision));\n s += '.' + (\"0000000000\" + Math.abs(arg)).slice(-precision);\n }\n buffer += s;\n break;\n\n case 'c':\n arg = String.fromCharCode(arg);\n /* falls through */\n\n case 's':\n if (typeof arg == \"string\") {\n while (arg.length < minimum) {\n if (flags == '-') {\n arg += ' ';\n } else {\n arg = ' ' + arg;\n }\n }\n }\n buffer += arg;\n break;\n\n case 'X':\n ach = Str.HexUpperCase;\n /* falls through */\n\n case 'x':\n if (!ach) ach = Str.HexLowerCase;\n s = \"\";\n if (typeof arg == \"string\") {\n /*\n * Since we're advised to ALWAYS pass a radix to parseInt(), we must detect explicitly\n * hex values ourselves, because using a radix of 10 with any \"0x...\" value always returns 0.\n * \n * And if the value CAN be interpreted as decimal, then we MUST interpret it as decimal, because\n * we have sprintf() calls in /modules/lib/testmon.js that depend on this code to perform decimal\n * to hex conversion. We're allowed to make our own rules here, since passing numbers in string\n * form isn't part of the sprintf \"spec\". \n */\n arg = Number.parseInt(arg, arg.match(/(^0x|[a-f])/i)? 16 : 10);\n } \n do {\n s = ach[arg & 0xf] + s;\n arg >>>= 4;\n } while (--minimum > 0 || arg);\n buffer += s;\n break;\n\n default:\n /*\n * The supported ANSI C set of conversions: \"dioxXucsfeEgGpn%\"\n */\n buffer += \"(unrecognized printf conversion %\" + conversion + \")\";\n break;\n }\n }\n\n buffer += aParts[iPart];\n return buffer;\n }\n\n /**\n * stripLeadingZeros(s, fPad)\n *\n * @param {string} s\n * @param {boolean} [fPad]\n * @return {string}\n */\n static stripLeadingZeros(s, fPad)\n {\n var cch = s.length;\n s = s.replace(/^0+([0-9A-F]+)$/i, \"$1\");\n if (fPad) s = Str.pad(s, cch, true);\n return s;\n }\n\n /**\n * trim(s)\n *\n * @param {string} s\n * @return {string}\n */\n static trim(s)\n {\n if (String.prototype.trim) {\n return s.trim();\n }\n return s.replace(/^\\s+|\\s+$/g, \"\");\n }\n\n /**\n * toASCIICode(b)\n *\n * @param {number} b\n * @return {string}\n */\n static toASCIICode(b)\n {\n var s;\n if (b != Str.ASCII.CR && b != Str.ASCII.LF) {\n s = Str.ASCIICodeMap[b];\n }\n if (s) {\n s = '<' + s + '>';\n } else {\n s = String.fromCharCode(b);\n }\n return s;\n }\n}\n\n/*\n * Map special characters to their HTML escape sequences.\n */\nStr.HTMLEscapeMap = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n};\n\n/*\n * Map \"unprintable\" ASCII codes to mnemonics, to more clearly see what's being printed.\n */\nStr.ASCIICodeMap = {\n 0x00: \"NUL\",\n 0x01: \"SOH\", // (CTRL_A) Start of Heading\n 0x02: \"STX\", // (CTRL_B) Start of Text\n 0x03: \"ETX\", // (CTRL_C) End of Text\n 0x04: \"EOT\", // (CTRL_D) End of Transmission\n 0x05: \"ENQ\", // (CTRL_E) Enquiry\n 0x06: \"ACK\", // (CTRL_F) Acknowledge\n 0x07: \"BEL\", // (CTRL_G) Bell\n 0x08: \"BS\", // (CTRL_H) Backspace\n 0x09: \"TAB\", // (CTRL_I) Horizontal Tab (aka HT)\n 0x0A: \"LF\", // (CTRL_J) Line Feed (New Line)\n 0x0B: \"VT\", // (CTRL_K) Vertical Tab\n 0x0C: \"FF\", // (CTRL_L) Form Feed (New Page)\n 0x0D: \"CR\", // (CTRL_M) Carriage Return\n 0x0E: \"SO\", // (CTRL_N) Shift Out\n 0x0F: \"SI\", // (CTRL_O) Shift In\n 0x10: \"DLE\", // (CTRL_P) Data Link Escape\n 0x11: \"XON\", // (CTRL_Q) Device Control 1 (aka DC1)\n 0x12: \"DC2\", // (CTRL_R) Device Control 2\n 0x13: \"XOFF\", // (CTRL_S) Device Control 3 (aka DC3)\n 0x14: \"DC4\", // (CTRL_T) Device Control 4\n 0x15: \"NAK\", // (CTRL_U) Negative Acknowledge\n 0x16: \"SYN\", // (CTRL_V) Synchronous Idle\n 0x17: \"ETB\", // (CTRL_W) End of Transmission Block\n 0x18: \"CAN\", // (CTRL_X) Cancel\n 0x19: \"EM\", // (CTRL_Y) End of Medium\n 0x1A: \"SUB\", // (CTRL_Z) Substitute\n 0x1B: \"ESC\", // Escape\n 0x1C: \"FS\", // File Separator\n 0x1D: \"GS\", // Group Separator\n 0x1E: \"RS\", // Record Separator\n 0x1F: \"US\", // Unit Separator\n 0x7F: \"DEL\"\n};\n\n/*\n * Refer to: https://en.wikipedia.org/wiki/Code_page_437\n */\nStr.CP437ToUnicode = [\n '\\u0000', '\\u263A', '\\u263B', '\\u2665', '\\u2666', '\\u2663', '\\u2660', '\\u2022',\n '\\u25D8', '\\u25CB', '\\u25D9', '\\u2642', '\\u2640', '\\u266A', '\\u266B', '\\u263C',\n '\\u25BA', '\\u25C4', '\\u2195', '\\u203C', '\\u00B6', '\\u00A7', '\\u25AC', '\\u21A8',\n '\\u2191', '\\u2193', '\\u2192', '\\u2190', '\\u221F', '\\u2194', '\\u25B2', '\\u25BC',\n '\\u0020', '\\u0021', '\\u0022', '\\u0023', '\\u0024', '\\u0025', '\\u0026', '\\u0027',\n '\\u0028', '\\u0029', '\\u002A', '\\u002B', '\\u002C', '\\u002D', '\\u002E', '\\u002F',\n '\\u0030', '\\u0031', '\\u0032', '\\u0033', '\\u0034', '\\u0035', '\\u0036', '\\u0037',\n '\\u0038', '\\u0039', '\\u003A', '\\u003B', '\\u003C', '\\u003D', '\\u003E', '\\u003F',\n '\\u0040', '\\u0041', '\\u0042', '\\u0043', '\\u0044', '\\u0045', '\\u0046', '\\u0047',\n '\\u0048', '\\u0049', '\\u004A', '\\u004B', '\\u004C', '\\u004D', '\\u004E', '\\u004F',\n '\\u0050', '\\u0051', '\\u0052', '\\u0053', '\\u0054', '\\u0055', '\\u0056', '\\u0057',\n '\\u0058', '\\u0059', '\\u005A', '\\u005B', '\\u005C', '\\u005D', '\\u005E', '\\u005F',\n '\\u0060', '\\u0061', '\\u0062', '\\u0063', '\\u0064', '\\u0065', '\\u0066', '\\u0067',\n '\\u0068', '\\u0069', '\\u006A', '\\u006B', '\\u006C', '\\u006D', '\\u006E', '\\u006F',\n '\\u0070', '\\u0071', '\\u0072', '\\u0073', '\\u0074', '\\u0075', '\\u0076', '\\u0077',\n '\\u0078', '\\u0079', '\\u007A', '\\u007B', '\\u007C', '\\u007D', '\\u007E', '\\u2302',\n '\\u00C7', '\\u00FC', '\\u00E9', '\\u00E2', '\\u00E4', '\\u00E0', '\\u00E5', '\\u00E7',\n '\\u00EA', '\\u00EB', '\\u00E8', '\\u00EF', '\\u00EE', '\\u00EC', '\\u00C4', '\\u00C5',\n '\\u00C9', '\\u00E6', '\\u00C6', '\\u00F4', '\\u00F6', '\\u00F2', '\\u00FB', '\\u00F9',\n '\\u00FF', '\\u00D6', '\\u00DC', '\\u00A2', '\\u00A3', '\\u00A5', '\\u20A7', '\\u0192',\n '\\u00E1', '\\u00ED', '\\u00F3', '\\u00FA', '\\u00F1', '\\u00D1', '\\u00AA', '\\u00BA',\n '\\u00BF', '\\u2310', '\\u00AC', '\\u00BD', '\\u00BC', '\\u00A1', '\\u00AB', '\\u00BB',\n '\\u2591', '\\u2592', '\\u2593', '\\u2502', '\\u2524', '\\u2561', '\\u2562', '\\u2556',\n '\\u2555', '\\u2563', '\\u2551', '\\u2557', '\\u255D', '\\u255C', '\\u255B', '\\u2510',\n '\\u2514', '\\u2534', '\\u252C', '\\u251C', '\\u2500', '\\u253C', '\\u255E', '\\u255F',\n '\\u255A', '\\u2554', '\\u2569', '\\u2566', '\\u2560', '\\u2550', '\\u256C', '\\u2567',\n '\\u2568', '\\u2564', '\\u2565', '\\u2559', '\\u2558', '\\u2552', '\\u2553', '\\u256B',\n '\\u256A', '\\u2518', '\\u250C', '\\u2588', '\\u2584', '\\u258C', '\\u2590', '\\u2580',\n '\\u03B1', '\\u00DF', '\\u0393', '\\u03C0', '\\u03A3', '\\u03C3', '\\u00B5', '\\u03C4',\n '\\u03A6', '\\u0398', '\\u03A9', '\\u03B4', '\\u221E', '\\u03C6', '\\u03B5', '\\u2229',\n '\\u2261', '\\u00B1', '\\u2265', '\\u2264', '\\u2320', '\\u2321', '\\u00F7', '\\u2248',\n '\\u00B0', '\\u2219', '\\u00B7', '\\u221A', '\\u207F', '\\u00B2', '\\u25A0', '\\u00A0'\n];\n\n/*\n * TODO: Future home of a complete ASCII table.\n */\nStr.ASCII = {\n LF: 0x0A,\n CR: 0x0D\n};\n\nStr.TYPES = {\n NULL: 0,\n BYTE: 1,\n WORD: 2,\n DWORD: 3,\n NUMBER: 4,\n STRING: 5,\n BOOLEAN: 6,\n OBJECT: 7,\n ARRAY: 8\n};\n\nStr.HexLowerCase = \"0123456789abcdef\";\nStr.HexUpperCase = \"0123456789ABCDEF\";\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/usrlib.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @typedef {{\n * mask: number,\n * shift: number\n * }}\n */\nvar BitField;\n\n/**\n * @typedef {Object.<BitField>}\n */\nvar BitFields;\n\nclass Usr {\n /**\n * binarySearch(a, v, fnCompare)\n *\n * @param {Array} a is an array\n * @param {number|string|Array|Object} v\n * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]\n * @return {number} the index of matching entry if non-negative, otherwise the index of the insertion point\n */\n static binarySearch(a, v, fnCompare)\n {\n var left = 0;\n var right = a.length;\n var found = 0;\n if (fnCompare === undefined) {\n fnCompare = function(a, b)\n {\n return a > b ? 1 : a < b ? -1 : 0;\n };\n }\n while (left < right) {\n var middle = (left + right) >> 1;\n var compareResult;\n compareResult = fnCompare(v, a[middle]);\n if (compareResult > 0) {\n left = middle + 1;\n } else {\n right = middle;\n found = !compareResult;\n }\n }\n return found ? left : ~left;\n }\n\n /**\n * binaryInsert(a, v, fnCompare)\n *\n * If element v already exists in array a, the array is unchanged (we don't allow duplicates); otherwise, the\n * element is inserted into the array at the appropriate index.\n *\n * @param {Array} a is an array\n * @param {number|string|Array|Object} v is the value to insert\n * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]\n */\n static binaryInsert(a, v, fnCompare)\n {\n var index = Usr.binarySearch(a, v, fnCompare);\n if (index < 0) {\n a.splice(-(index + 1), 0, v);\n }\n }\n\n /**\n * getTimestamp()\n *\n * @return {string} timestamp containing the current date and time (\"yyyy-mm-dd hh:mm:ss\")\n */\n static getTimestamp()\n {\n return Usr.formatDate(\"Y-m-d H:i:s\");\n }\n\n /**\n * getMonthDays(nMonth, nYear)\n *\n * Note that if we're being called on behalf of the RTC, its year is always truncated to two digits (mod 100),\n * so we have no idea what century the year 0 might refer to. When using the normal leap-year formula, 0 fails\n * the mod 100 test but passes the mod 400 test, so as far as the RTC is concerned, every century year is a leap\n * year. Since we're most likely dealing with the year 2000, that's fine, since 2000 was also a leap year.\n *\n * TODO: There IS a separate CMOS byte that's supposed to be set to CMOS_ADDR.CENTURY_DATE; it's always BCD,\n * so theoretically it will contain values like 0x19 or 0x20 (for the 20th and 21st centuries, respectively), and\n * we could add that as another parameter to this function, to improve the accuracy, but that would go beyond what\n * a real RTC actually does.\n *\n * @param {number} nMonth (1-12)\n * @param {number} nYear (normally a 4-digit year, but it may also be mod 100)\n * @return {number} the maximum (1-based) day allowed for the specified month and year\n */\n static getMonthDays(nMonth, nYear)\n {\n var nDays = Usr.aMonthDays[nMonth - 1];\n if (nDays == 28) {\n if ((nYear % 4) === 0 && ((nYear % 100) || (nYear % 400) === 0)) {\n nDays++;\n }\n }\n return nDays;\n }\n\n /**\n * formatDate(sFormat, date)\n *\n * @param {string} sFormat (eg, \"F j, Y\", \"Y-m-d H:i:s\")\n * @param {Date} [date] (default is the current time)\n * @return {string}\n *\n * Supported identifiers in sFormat include:\n *\n * a: lowercase ante meridiem and post meridiem (am or pm)\n * d: day of the month, 2 digits with leading zeros (01,02,...,31)\n * D: 3-letter day of the week (\"Sun\",\"Mon\",...,\"Sat\")\n * F: month (\"January\",\"February\",...,\"December\")\n * g: hour in 12-hour format, without leading zeros (1,2,...,12)\n * h: hour in 24-hour format, without leading zeros (0,1,...,23)\n * H: hour in 24-hour format, with leading zeros (00,01,...,23)\n * i: minutes, with leading zeros (00,01,...,59)\n * j: day of the month, without leading zeros (1,2,...,31)\n * l: day of the week (\"Sunday\",\"Monday\",...,\"Saturday\")\n * m: month, with leading zeros (01,02,...,12)\n * M: 3-letter month (\"Jan\",\"Feb\",...,\"Dec\")\n * n: month, without leading zeros (1,2,...,12)\n * s: seconds, with leading zeros (00,01,...,59)\n * y: 2-digit year (eg, 14)\n * Y: 4-digit year (eg, 2014)\n *\n * For more inspiration, see: http://php.net/manual/en/function.date.php (of which we support ONLY a subset).\n */\n static formatDate(sFormat, date)\n {\n var sDate = \"\";\n if (!date) date = new Date();\n var iHour = date.getHours();\n var iDay = date.getDate();\n var iMonth = date.getMonth() + 1;\n for (var i = 0; i < sFormat.length; i++) {\n var ch;\n switch ((ch = sFormat.charAt(i))) {\n case 'a':\n sDate += (iHour < 12 ? \"am\" : \"pm\");\n break;\n case 'd':\n sDate += ('0' + iDay).slice(-2);\n break;\n case 'D':\n sDate += Usr.asDays[date.getDay()].substr(0, 3);\n break;\n case 'F':\n sDate += Usr.asMonths[iMonth - 1];\n break;\n case 'g':\n sDate += (!iHour ? 12 : (iHour > 12 ? iHour - 12 : iHour));\n break;\n case 'h':\n sDate += iHour;\n break;\n case 'H':\n sDate += ('0' + iHour).slice(-2);\n break;\n case 'i':\n sDate += ('0' + date.getMinutes()).slice(-2);\n break;\n case 'j':\n sDate += iDay;\n break;\n case 'l':\n sDate += Usr.asDays[date.getDay()];\n break;\n case 'm':\n sDate += ('0' + iMonth).slice(-2);\n break;\n case 'M':\n sDate += Usr.asMonths[iMonth - 1].substr(0, 3);\n break;\n case 'n':\n sDate += iMonth;\n break;\n case 's':\n sDate += ('0' + date.getSeconds()).slice(-2);\n break;\n case 'y':\n sDate += (\"\" + date.getFullYear()).slice(-2);\n break;\n case 'Y':\n sDate += date.getFullYear();\n break;\n default:\n sDate += ch;\n break;\n }\n }\n return sDate;\n }\n\n /**\n * defineBitFields(bfs)\n *\n * Prepares a bit field definition for use with getBitField() and setBitField(); eg:\n *\n * var bfs = Usr.defineBitFields({num:20, count:8, btmod:1, type:3});\n *\n * The above defines a set of bit fields containing four fields: num (bits 0-19), count (bits 20-27), btmod (bit 28), and type (bits 29-31).\n *\n * Usr.setBitField(bfs.num, n, 1);\n *\n * The above set bit field \"bfs.num\" in numeric variable \"n\" to the value 1.\n *\n * @param {Object} bfs\n * @return {BitFields}\n */\n static defineBitFields(bfs)\n {\n var bit = 0;\n for (var f in bfs) {\n var width = bfs[f];\n var mask = ((1 << width) - 1) << bit;\n bfs[f] = {mask: mask, shift: bit};\n bit += width;\n }\n return bfs;\n }\n\n /**\n * initBitFields(bfs, ...)\n *\n * @param {BitFields} bfs\n * @param {...number} var_args\n * @return {number} a value containing all supplied bit fields\n */\n static initBitFields(bfs, var_args)\n {\n var v = 0, i = 1;\n for (var f in bfs) {\n if (i >= arguments.length) break;\n v = Usr.setBitField(bfs[f], v, arguments[i++]);\n }\n return v;\n }\n\n /**\n * getBitField(bf, v)\n *\n * @param {BitField} bf\n * @param {number} v is a value containing bit fields\n * @return {number} the value of the bit field in v defined by bf\n */\n static getBitField(bf, v)\n {\n return (v & bf.mask) >> bf.shift;\n }\n\n /**\n * setBitField(bf, v, n)\n *\n * @param {BitField} bf\n * @param {number} v is a value containing bit fields\n * @param {number} n is a value to store in v in the bit field defined by bf\n * @return {number} updated v\n */\n static setBitField(bf, v, n)\n {\n return (v & ~bf.mask) | ((n << bf.shift) & bf.mask);\n }\n\n /**\n * indexOf(a, t, i)\n *\n * Use this instead of Array.prototype.indexOf() if you can't be sure the browser supports it.\n *\n * @param {Array} a\n * @param {*} t\n * @param {number} [i]\n * @returns {number}\n */\n static indexOf(a, t, i)\n {\n if (Array.prototype.indexOf) {\n return a.indexOf(t, i);\n }\n i = i || 0;\n if (i < 0) i += a.length;\n if (i < 0) i = 0;\n for (var n = a.length; i < n; i++) {\n if (i in a && a[i] === t) return i;\n }\n return -1;\n }\n}\n\nUsr.asDays = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\nUsr.asMonths = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\nUsr.aMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\n/**\n * getTime()\n *\n * @return {number} the current time, in milliseconds\n */\nUsr.getTime = Date.now || function() { return +new Date(); };\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/weblib.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * According to http://www.w3schools.com/jsref/jsref_obj_global.asp, these are the *global* properties\n * and functions of JavaScript-in-the-Browser:\n *\n * Property Description\n * ---\n * Infinity A numeric value that represents positive/negative infinity\n * NaN \"Not-a-Number\" value\n * undefined Indicates that a variable has not been assigned a value\n *\n * Function Description\n * ---\n * decodeURI() Decodes a URI\n * decodeURIComponent() Decodes a URI component\n * encodeURI() Encodes a URI\n * encodeURIComponent() Encodes a URI component\n * escape() Deprecated in version 1.5. Use encodeURI() or encodeURIComponent() instead\n * eval() Evaluates a string and executes it as if it was script code\n * isFinite() Determines whether a value is a finite, legal number\n * isNaN() Determines whether a value is an illegal number\n * Number() Converts an object's value to a number\n * parseFloat() Parses a string and returns a floating point number\n * parseInt() Parses a string and returns an integer\n * String() Converts an object's value to a string\n * unescape() Deprecated in version 1.5. Use decodeURI() or decodeURIComponent() instead\n *\n * And according to http://www.w3schools.com/jsref/obj_window.asp, these are the properties and functions\n * of the *window* object.\n *\n * Property Description\n * ---\n * closed Returns a Boolean value indicating whether a window has been closed or not\n * defaultStatus Sets or returns the default text in the statusbar of a window\n * document Returns the Document object for the window (See Document object)\n * frames Returns an array of all the frames (including iframes) in the current window\n * history Returns the History object for the window (See History object)\n * innerHeight Returns the inner height of a window's content area\n * innerWidth Returns the inner width of a window's content area\n * length Returns the number of frames (including iframes) in a window\n * location Returns the Location object for the window (See Location object)\n * name Sets or returns the name of a window\n * navigator Returns the Navigator object for the window (See Navigator object)\n * opener Returns a reference to the window that created the window\n * outerHeight Returns the outer height of a window, including toolbars/scrollbars\n * outerWidth Returns the outer width of a window, including toolbars/scrollbars\n * pageXOffset Returns the pixels the current document has been scrolled (horizontally) from the upper left corner of the window\n * pageYOffset Returns the pixels the current document has been scrolled (vertically) from the upper left corner of the window\n * parent Returns the parent window of the current window\n * screen Returns the Screen object for the window (See Screen object)\n * screenLeft Returns the x coordinate of the window relative to the screen\n * screenTop Returns the y coordinate of the window relative to the screen\n * screenX Returns the x coordinate of the window relative to the screen\n * screenY Returns the y coordinate of the window relative to the screen\n * self Returns the current window\n * status Sets or returns the text in the statusbar of a window\n * top Returns the topmost browser window\n *\n * Method Description\n * ---\n * alert() Displays an alert box with a message and an OK button\n * atob() Decodes a base-64 encoded string\n * blur() Removes focus from the current window\n * btoa() Encodes a string in base-64\n * clearInterval() Clears a timer set with setInterval()\n * clearTimeout() Clears a timer set with setTimeout()\n * close() Closes the current window\n * confirm() Displays a dialog box with a message and an OK and a Cancel button\n * createPopup() Creates a pop-up window\n * focus() Sets focus to the current window\n * moveBy() Moves a window relative to its current position\n * moveTo() Moves a window to the specified position\n * open() Opens a new browser window\n * print() Prints the content of the current window\n * prompt() Displays a dialog box that prompts the visitor for input\n * resizeBy() Resizes the window by the specified pixels\n * resizeTo() Resizes the window to the specified width and height\n * scroll() This method has been replaced by the scrollTo() method.\n * scrollBy() Scrolls the content by the specified number of pixels\n * scrollTo() Scrolls the content to the specified coordinates\n * setInterval() Calls a function or evaluates an expression at specified intervals (in milliseconds)\n * setTimeout() Calls a function or evaluates an expression after a specified number of milliseconds\n * stop() Stops the window from loading\n */\n\nclass Web {\n /**\n * log(s, type)\n *\n * For diagnostic output only. DEBUG must be true (or \"--debug\" specified via the command-line)\n * for Component.log() to display anything.\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n static log(s, type)\n {\n Component.log(s, type);\n }\n\n /**\n * notice(s, fPrintOnly, id)\n *\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n */\n static notice(s, fPrintOnly, id)\n {\n Component.notice(s, fPrintOnly, id);\n }\n\n /**\n * alertUser(sMessage)\n * \n * NOTE: Legacy function for older modules (eg, DiskDump); see Component.alertUser().\n *\n * @param {string} sMessage\n */\n static alertUser(sMessage)\n {\n if (window) {\n window.alert(sMessage);\n } else {\n Web.log(sMessage);\n }\n }\n\n /**\n * getResource(sURL, type, fAsync, done, progress)\n *\n * Request the specified resource (sURL), and once the request is complete, notify done().\n *\n * If fAsync is true, a done() callback should ALWAYS be supplied; otherwise, you'll have no\n * idea when the request is complete or what the response was. done() is passed three parameters:\n *\n * done(sURL, resource, nErrorCode)\n *\n * If nErrorCode is zero, resource should contain the requested data; otherwise, an error occurred.\n *\n * If type is set to a string, that string can be used to control the response format;\n * by default, the response format is plain text, but you can specify \"arraybuffer\" to request arbitrary\n * binary data, in which case the returned resource will be a ArrayBuffer rather than a string.\n *\n * @param {string} sURL\n * @param {string|Object|null} [type] (object for POST request, otherwise type of GET request)\n * @param {boolean} [fAsync] is true for an asynchronous request; false otherwise (MUST be set for IE)\n * @param {function(string,string,number)} [done]\n * @param {function(number)} [progress]\n * @return {Array|null} Array containing [resource, nErrorCode], or null if no response available (yet)\n */\n static getResource(sURL, type = \"text\", fAsync = false, done, progress)\n {\n var nErrorCode = 0, resource = null, response = null;\n\n if (typeof resources == 'object' && (resource = resources[sURL])) {\n if (done) done(sURL, resource, nErrorCode);\n return [resource, nErrorCode];\n }\n else if (fAsync && typeof resources == 'function') {\n resources(sURL, function(resource, nErrorCode)\n {\n if (done) done(sURL, resource, nErrorCode);\n });\n return response;\n }\n\n if (!DEBUG && !NODE) {\n /*\n * TODO: Perhaps it's time for our code in netlib.js to finally add support for HTTPS; for now\n * though, it's just as well that the NODE environment assumes all resources are available locally.\n */\n sURL = sURL.replace(/^\\/(pcjs-disks|private-disks)\\//, \"https://jeffpar.github.io/$1/\");\n }\n else {\n /*\n * The larger resources we put on archive.pcjs.org should also be available locally.\n *\n * NOTE: \"http://archive.pcjs.org\" is now \"https://s3-us-west-2.amazonaws.com/archive.pcjs.org\"\n */\n sURL = sURL.replace(/^(http:\\/\\/archive\\.pcjs\\.org|https:\\/\\/s3-us-west-2\\.amazonaws\\.com\\/archive\\.pcjs\\.org)(\\/.*)\\/([^\\/]*)$/, \"$2/archive/$3\");\n sURL = sURL.replace(/^https:\\/\\/jeffpar\\.github\\.io\\/(pcjs-disks|private-disks)\\/(.*)$/, \"/$1/$2\");\n }\n\n\n var request = (window.XMLHttpRequest? new window.XMLHttpRequest() : new window.ActiveXObject(\"Microsoft.XMLHTTP\"));\n var fArrayBuffer = false, fXHR2 = (typeof request.responseType === 'string');\n \n var callback = function() {\n if (request.readyState !== 4) {\n if (progress) progress(1);\n return null;\n }\n /*\n * The following line was recommended for WebKit, as a work-around to prevent the handler firing multiple\n * times when debugging. Unfortunately, that's not the only XMLHttpRequest problem that occurs when\n * debugging, so I think the WebKit problem is deeper than that. When we have multiple XMLHttpRequests\n * pending, any debugging activity means most of them simply get dropped on floor, so what may actually be\n * happening are mis-notifications rather than redundant notifications.\n *\n * request.onreadystatechange = undefined;\n */\n /*\n * If the request failed due to, say, a CORS policy denial; eg:\n * \n * Failed to load http://www.allbootdisks.com/downloads/Disks/Windows_95_Boot_Disk_Download48/Diskette%20Images/Windows95a.img:\n * Redirect from 'http://www.allbootdisks.com/downloads/Disks/Windows_95_Boot_Disk_Download48/Diskette%20Images/Windows95a.img' to\n * 'http://www.allbootdisks.com/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.\n * Origin 'http://pcjs:8088' is therefore not allowed access.\n * \n * and our request type was \"arraybuffer\", attempting to access responseText may trigger an exception; eg:\n * \n * Uncaught DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's\n * 'responseType' is '' or 'text' (was 'arraybuffer').\n * \n * We could tiptoe around these potential landmines, but the safest thing to do is wrap this code with try/catch.\n */\n try {\n resource = fArrayBuffer? request.response : request.responseText;\n } catch(err) {\n if (MAXDEBUG) Web.log(\"xmlHTTPRequest(\" + sURL + \") exception: \" + err.message);\n }\n /*\n * The normal \"success\" case is a non-null resource and an HTTP status code of 200, but when loading files from the\n * local file system (ie, when using the \"file:\" protocol), we have to be a bit more flexible.\n */\n if (resource != null && (request.status == 200 || !request.status && resource.length && Web.getHostProtocol() == \"file:\")) {\n if (MAXDEBUG) Web.log(\"xmlHTTPRequest(\" + sURL + \"): returned \" + resource.length + \" bytes\");\n }\n else {\n nErrorCode = request.status || -1;\n Web.log(\"xmlHTTPRequest(\" + sURL + \"): error code \" + nErrorCode);\n }\n if (progress) progress(2);\n if (done) done(sURL, resource, nErrorCode);\n return [resource, nErrorCode];\n };\n \n if (fAsync) {\n request.onreadystatechange = callback;\n }\n\n if (progress) progress(0);\n\n if (type && typeof type == \"object\") {\n var sPost = \"\";\n for (var p in type) {\n if (!type.hasOwnProperty(p)) continue;\n if (sPost) sPost += \"&\";\n sPost += p + '=' + encodeURIComponent(type[p]);\n }\n sPost = sPost.replace(/%20/g, '+');\n if (MAXDEBUG) Web.log(\"Web.getResource(POST \" + sURL + \"): \" + sPost.length + \" bytes\");\n request.open(\"POST\", sURL, fAsync);\n request.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\n request.send(sPost);\n } else {\n if (MAXDEBUG) Web.log(\"Web.getResource(GET \" + sURL + \")\");\n request.open(\"GET\", sURL, fAsync);\n if (type == \"arraybuffer\") {\n if (fXHR2) {\n fArrayBuffer = true;\n request.responseType = type;\n } else {\n request.overrideMimeType(\"text/plain; charset=x-user-defined\");\n }\n }\n request.send();\n }\n\n if (!fAsync) {\n request.readyState = 4; // this may already be set for synchronous requests, but I don't want to take any chances \n response = callback();\n }\n return response;\n }\n\n /**\n * parseMemoryResource(sURL, sData)\n *\n * This converts a variety of JSON-style data streams into an Object with the following properties:\n *\n * aBytes\n * aSymbols\n * addrLoad\n * addrExec\n *\n * If the source data contains a 'bytes' array, it's passed through to 'aBytes'; alternatively, if\n * it contains a 'words' array, the values are converted from 16-bit to 8-bit and stored in 'aBytes',\n * and if it contains a 'longs' array, the values are converted from 32-bit longs into bytes and\n * stored in 'aBytes'.\n *\n * Alternatively, if the source data contains a 'data' array, we simply pass that through to the output\n * object as:\n *\n * aData\n *\n * @param {string} sURL\n * @param {string} sData\n * @return {Object|null} (resource)\n */\n static parseMemoryResource(sURL, sData)\n {\n var i;\n var resource = {\n aBytes: null,\n aSymbols: null,\n addrLoad: null,\n addrExec: null\n };\n\n if (sData.charAt(0) == \"[\" || sData.charAt(0) == \"{\") {\n try {\n var a, ib, data;\n\n if (sData.substr(0, 1) == \"<\") { // if the \"data\" begins with a \"<\"...\n /*\n * Early server configs reported an error (via the nErrorCode parameter) if a tape URL was invalid,\n * but more recent server configs now display a somewhat friendlier HTML error page. The downside,\n * however, is that the original error has been buried, and we've received \"data\" that isn't actually\n * tape data. So if the data we've received appears to be \"HTML-like\", we treat it as an error message.\n */\n throw new Error(sData);\n }\n\n /*\n * TODO: IE9 is rather unfriendly and restrictive with regard to how much data it's willing to\n * eval(). In particular, the 10Mb disk image we use for the Windows 1.01 demo config fails in\n * IE9 with an \"Out of memory\" exception. One work-around would be to chop the data into chunks\n * (perhaps one track per chunk, using regular expressions) and then manually re-assemble it.\n *\n * However, it turns out that using JSON.parse(sDiskData) instead of eval(\"(\" + sDiskData + \")\")\n * is a much easier fix. The only drawback is that we must first quote any unquoted property names\n * and remove any comments, because while eval() was cool with them, JSON.parse() is more particular;\n * the following RegExp replacements take care of those requirements.\n *\n * The use of hex values is something else that eval() was OK with, but JSON.parse() is not, and\n * while I've stopped using hex values in DumpAPI responses (at least when \"format=json\" is specified),\n * I can't guarantee they won't show up in \"legacy\" images, and there's no simple RegExp replacement\n * for transforming hex values into decimal values, so I cop out and fall back to eval() if I detect\n * any hex prefixes (\"0x\") in the sequence. Ditto for error messages, which appear like so:\n *\n * [\"unrecognized disk path: test.img\"]\n */\n if (sData.indexOf(\"0x\") < 0 && sData.indexOf(\"0o\") < 0 && sData.substr(0, 2) != '[\"') {\n data = JSON.parse(sData.replace(/([a-z]+):/gm, '\"$1\":').replace(/\\/\\/[^\\n]*/gm, \"\"));\n } else {\n data = eval(\"(\" + sData + \")\");\n }\n\n resource.addrLoad = data['load'];\n resource.addrExec = data['exec'];\n\n if (a = data['bytes']) {\n resource.aBytes = a;\n }\n else if (a = data['words']) {\n /*\n * Convert all words into bytes\n */\n resource.aBytes = new Array(a.length * 2);\n for (i = 0, ib = 0; i < a.length; i++) {\n resource.aBytes[ib++] = a[i] & 0xff;\n resource.aBytes[ib++] = (a[i] >> 8) & 0xff;\n\n }\n }\n else if (a = data['longs']) {\n /*\n * Convert all dwords (longs) into bytes\n */\n resource.aBytes = new Array(a.length * 4);\n for (i = 0, ib = 0; i < a.length; i++) {\n resource.aBytes[ib++] = a[i] & 0xff;\n resource.aBytes[ib++] = (a[i] >> 8) & 0xff;\n resource.aBytes[ib++] = (a[i] >> 16) & 0xff;\n resource.aBytes[ib++] = (a[i] >> 24) & 0xff;\n }\n }\n else if (a = data['data']) {\n resource.aData = a;\n }\n else {\n resource.aBytes = data;\n }\n\n if (resource.aBytes) {\n if (!resource.aBytes.length) {\n Component.error(\"Empty resource: \" + sURL);\n resource = null;\n }\n else if (resource.aBytes.length == 1) {\n Component.error(resource.aBytes[0]);\n resource = null;\n }\n }\n resource.aSymbols = data['symbols'];\n\n } catch (e) {\n Component.error(\"Resource data error (\" + sURL + \"): \" + e.message);\n resource = null;\n }\n }\n else {\n /*\n * Parse the data manually; we assume it's a series of hex byte-values separated by whitespace.\n */\n var ab = [];\n var sHexData = sData.replace(/\\n/gm, \" \").replace(/ +$/, \"\");\n var asHexData = sHexData.split(\" \");\n for (i = 0; i < asHexData.length; i++) {\n var n = parseInt(asHexData[i], 16);\n if (isNaN(n)) {\n Component.error(\"Resource data error (\" + sURL + \"): invalid hex byte (\" + asHexData[i] + \")\");\n break;\n }\n ab.push(n & 0xff);\n }\n if (i == asHexData.length) resource.aBytes = ab;\n }\n return resource;\n }\n\n /**\n * sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)\n *\n * Send a report (eg, bug report) to the server.\n *\n * @param {string} sApp (eg, \"PCjs\")\n * @param {string} sVer (eg, \"1.02\")\n * @param {string} sURL (eg, \"/devices/pc/machine/5150/mda/64kb/machine.xml\")\n * @param {string} sUser (ie, the user key, if any)\n * @param {string} sType (eg, \"bug\"); one of ReportAPI.TYPE.*\n * @param {string} sReport (eg, unparsed state data)\n * @param {string} [sHostName] (default is http://SITEHOST)\n */\n static sendReport(sApp, sVer, sURL, sUser, sType, sReport, sHostName)\n {\n var dataPost = {};\n dataPost[ReportAPI.QUERY.APP] = sApp;\n dataPost[ReportAPI.QUERY.VER] = sVer;\n dataPost[ReportAPI.QUERY.URL] = sURL;\n dataPost[ReportAPI.QUERY.USER] = sUser;\n dataPost[ReportAPI.QUERY.TYPE] = sType;\n dataPost[ReportAPI.QUERY.DATA] = sReport;\n var sReportURL = (sHostName? sHostName : \"http://\" + SITEHOST) + ReportAPI.ENDPOINT;\n Web.getResource(sReportURL, dataPost, true);\n }\n\n /**\n * getHost()\n *\n * @return {string}\n */\n static getHost()\n {\n return (\"http://\" + (window? window.location.host : SITEHOST));\n }\n\n /**\n * getHostURL()\n *\n * @return {string|null}\n */\n static getHostURL()\n {\n return (window? window.location.href : null);\n }\n\n /**\n * getHostProtocol()\n *\n * @return {string}\n */\n static getHostProtocol()\n {\n return (window? window.location.protocol : \"file:\");\n }\n\n /**\n * getUserAgent()\n *\n * @return {string}\n */\n static getUserAgent()\n {\n return (window? window.navigator.userAgent : \"\");\n }\n\n /**\n * hasLocalStorage\n *\n * true if localStorage support exists, is enabled, and works; false otherwise\n *\n * @return {boolean}\n */\n static hasLocalStorage()\n {\n if (Web.fLocalStorage == null) {\n var f = false;\n if (window) {\n try {\n window.localStorage.setItem(Web.sLocalStorageTest, Web.sLocalStorageTest);\n f = (window.localStorage.getItem(Web.sLocalStorageTest) == Web.sLocalStorageTest);\n window.localStorage.removeItem(Web.sLocalStorageTest);\n } catch (e) {\n Web.logLocalStorageError(e);\n f = false;\n }\n }\n Web.fLocalStorage = f;\n }\n return Web.fLocalStorage;\n }\n\n /**\n * logLocalStorageError(e)\n *\n * @param {Error} e is an exception\n */\n static logLocalStorageError(e)\n {\n Web.log(e.message, \"localStorage error\");\n }\n\n /**\n * getLocalStorageItem(sKey)\n *\n * Returns the requested key value, or null if the key does not exist, or undefined if localStorage is not available\n *\n * @param {string} sKey\n * @return {string|null|undefined} sValue\n */\n static getLocalStorageItem(sKey)\n {\n var sValue;\n if (window) {\n try {\n sValue = window.localStorage.getItem(sKey);\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n }\n return sValue;\n }\n\n /**\n * setLocalStorageItem(sKey, sValue)\n *\n * @param {string} sKey\n * @param {string} sValue\n * @return {boolean} true if localStorage is available, false if not\n */\n static setLocalStorageItem(sKey, sValue)\n {\n try {\n window.localStorage.setItem(sKey, sValue);\n return true;\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n return false;\n }\n\n /**\n * removeLocalStorageItem(sKey)\n *\n * @param {string} sKey\n */\n static removeLocalStorageItem(sKey)\n {\n try {\n window.localStorage.removeItem(sKey);\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n }\n\n /**\n * getLocalStorageKeys()\n *\n * @return {Array}\n */\n static getLocalStorageKeys()\n {\n var a = [];\n try {\n for (var i = 0, c = window.localStorage.length; i < c; i++) {\n a.push(window.localStorage.key(i));\n }\n } catch (e) {\n Web.logLocalStorageError(e);\n }\n return a;\n }\n\n /**\n * reloadPage()\n */\n static reloadPage()\n {\n if (window) window.location.reload();\n }\n\n /**\n * isUserAgent(s)\n *\n * Check the browser's user-agent string for the given substring; \"iOS\" and \"MSIE\" are special values you can\n * use that will match any iOS or MSIE browser, respectively (even IE11, in the case of \"MSIE\").\n *\n * 2013-11-06: In a questionable move, MSFT changed the user-agent reported by IE11 on Windows 8.1, eliminating\n * the \"MSIE\" string (which MSDN calls a \"version token\"; see http://msdn.microsoft.com/library/ms537503.aspx);\n * they say \"public websites should rely on feature detection, rather than browser detection, in order to design\n * their sites for browsers that don't support the features used by the website.\" So, in IE11, we get a user-agent\n * that tries to fool apps into thinking the browser is more like WebKit or Gecko:\n *\n * Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko\n *\n * That's a nice idea, but in the meantime, they hosed the XSL transform code in embed.js, which contained\n * some very critical browser-specific code; turning on IE's \"Compatibility Mode\" didn't help either, because\n * that's a sledgehammer solution which restores the old user-agent string but also disables other features like\n * HTML5 canvas support. As an interim solution, I'm treating any \"MSIE\" check as a check for either \"MSIE\" or\n * \"Trident\".\n *\n * UPDATE: I've since found ways to make the code in embed.js more browser-agnostic, so for now, there's isn't\n * any code that cares about \"MSIE\", but I've left the change in place, because I wouldn't be surprised if I'll\n * need more IE-specific code in the future, perhaps for things like copy/paste functionality, or mouse capture.\n *\n * @param {string} s is a substring to search for in the user-agent; as noted above, \"iOS\" and \"MSIE\" are special values\n * @return {boolean} is true if the string was found, false if not\n */\n static isUserAgent(s)\n {\n if (window) {\n var userAgent = Web.getUserAgent();\n /*\n * Here's one case where we have to be careful with Component, because when isUserAgent() is called by\n * the init code below, component.js hasn't been loaded yet. The simple solution for now is to remove the call.\n *\n * Web.log(\"agent: \" + userAgent);\n *\n * And yes, it would be pointless to use the conditional (?) operator below, if not for the Google Closure\n * Compiler (v20130823) failing to detect the entire expression as a boolean.\n */\n return s == \"iOS\" && !!userAgent.match(/(iPod|iPhone|iPad)/) && !!userAgent.match(/AppleWebKit/) || s == \"MSIE\" && !!userAgent.match(/(MSIE|Trident)/) || (userAgent.indexOf(s) >= 0);\n }\n return false;\n }\n\n /**\n * isMobile(sDevice)\n *\n * Checks the URL for a \"mobile\" parameter, and failing that, checks the browser's user-agent string for the\n * substring \"Mobi\", as per Mozilla recommendation:\n *\n * https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent\n *\n * @param {string} [sDevice] (eg, \"iPad\" to check for iPad, or \"!iPad\" to specifically exclude it) \n * @return {boolean} is true if the browser appears to be a mobile (ie, non-desktop) web browser, false if not\n */\n static isMobile(sDevice)\n {\n var sMobile = Web.getURLParm(\"mobile\");\n if (sMobile) return sMobile == \"true\";\n if (Web.isUserAgent(\"Mobi\")) {\n if (!sDevice) return true;\n var fInvert = sDevice[0] == '!';\n if (fInvert) sDevice = sDevice.substr(1);\n return Web.isUserAgent(sDevice) != fInvert;\n }\n return false;\n }\n\n /**\n * findProperty(obj, sProp, sSuffix)\n *\n * If both sProp and sSuffix are set, then any browser-specific prefixes are inserted between sProp and sSuffix,\n * and if a match is found, it is returned without sProp.\n *\n * For example, if findProperty(document, 'on', 'fullscreenchange') discovers that 'onwebkitfullscreenchange' exists,\n * it will return 'webkitfullscreenchange', in preparation for an addEventListener() call.\n *\n * More commonly, sSuffix is not used, so whatever property is found is returned as-is.\n *\n * @param {Object|null|undefined} obj\n * @param {string} sProp\n * @param {string} [sSuffix]\n * @return {string|null}\n */\n static findProperty(obj, sProp, sSuffix)\n {\n if (obj) {\n for (var i = 0; i < Web.asBrowserPrefixes.length; i++) {\n var sName = Web.asBrowserPrefixes[i];\n if (sSuffix) {\n sName += sSuffix;\n var sEvent = sProp + sName;\n if (sEvent in obj) return sName;\n } else {\n if (!sName) {\n sName = sProp[0];\n } else {\n sName += sProp[0].toUpperCase();\n }\n sName += sProp.substr(1);\n if (sName in obj) return sName;\n }\n }\n }\n return null;\n }\n\n /**\n * getURLParm(sParm)\n *\n * First looks for sParm exactly as specified, then looks for the lower-case version.\n *\n * @param {string} sParm\n * @return {string|undefined}\n */\n static getURLParm(sParm)\n {\n if (!Web.parmsURL) {\n Web.parmsURL = Web.parseURLParms();\n }\n return Web.parmsURL[sParm] || Web.parmsURL[sParm.toLowerCase()];\n }\n\n /**\n * parseURLParms(sParms)\n *\n * @param {string} [sParms] containing the parameter portion of a URL (ie, after the '?')\n * @return {Object} containing properties for each parameter found\n */\n static parseURLParms(sParms)\n {\n var aParms = {};\n if (window) { // an alternative to \"if (typeof module === 'undefined')\" if require(\"defines\") was used\n if (!sParms) {\n /*\n * Note that window.location.href returns the entire URL, whereas window.location.search\n * returns only the parameters, if any (starting with the '?', which we skip over with a substr() call).\n */\n sParms = window.location.search.substr(1);\n }\n var match;\n var pl = /\\+/g; // RegExp for replacing addition symbol with a space\n var search = /([^&=]+)=?([^&]*)/g;\n var decode = function(s)\n {\n return decodeURIComponent(s.replace(pl, \" \"));\n };\n\n while ((match = search.exec(sParms))) {\n aParms[decode(match[1])] = decode(match[2]);\n }\n }\n return aParms;\n }\n\n /**\n * downloadFile(sData, sType, fBase64, sFileName)\n *\n * @param {string} sData\n * @param {string} sType\n * @param {boolean} [fBase64]\n * @param {string} [sFileName]\n */\n static downloadFile(sData, sType, fBase64, sFileName)\n {\n var link = null, sAlert;\n var sURI = \"data:application/\" + sType + (fBase64? \";base64\" : \"\") + \",\";\n\n if (!Web.isUserAgent(\"Firefox\")) {\n sURI += (fBase64? sData : encodeURI(sData));\n } else {\n sURI += (fBase64? sData : encodeURIComponent(sData));\n }\n if (sFileName) {\n link = document.createElement('a');\n if (typeof link.download != 'string') link = null;\n }\n if (link) {\n link.href = sURI;\n link.download = sFileName;\n document.body.appendChild(link); // Firefox allegedly requires the link to be in the body\n link.click();\n document.body.removeChild(link);\n sAlert = 'Check your Downloads folder for ' + sFileName + '.';\n if (Web.isUserAgent(\"Chrome\")) {\n sAlert += '\\n\\nIn Chrome, after clicking OK, you may ALSO have to select the \"Window\" menu, choose \"Downloads\", and then locate this download and select \"Keep\".';\n sAlert += '\\n\\nThis is part of Chrome\\'s \"Security By Jumping Through Extra Hoops\" technology, which is much easier for Google to implement than actually checking for something malicious.';\n sAlert += '\\n\\nAnd for the record, there is nothing malicious on the PCjs website.';\n }\n } else {\n window.open(sURI);\n sAlert = 'Check your browser for a new window/tab containing the requested data' + (sFileName? (' (' + sFileName + ')') : '') + '.';\n }\n return sAlert;\n }\n\n /**\n * onCountRepeat(n, fnRepeat, fnComplete, msDelay)\n *\n * Call fnRepeat() n times with an msDelay millisecond delay between calls,\n * then call fnComplete() when n has been exhausted OR fnRepeat() returns false.\n *\n * @param {number} n\n * @param {function()} fnRepeat\n * @param {function()} fnComplete\n * @param {number} [msDelay]\n */\n static onCountRepeat(n, fnRepeat, fnComplete, msDelay)\n {\n var fnTimeout = function doCountRepeat()\n {\n n -= 1;\n if (n >= 0) {\n if (!fnRepeat()) n = 0;\n }\n if (n > 0) {\n setTimeout(fnTimeout, msDelay || 0);\n return;\n }\n fnComplete();\n };\n fnTimeout();\n }\n\n /**\n * onClickRepeat(e, msDelay, msRepeat, fn)\n *\n * Repeatedly call fn() with an initial msDelay, and an msRepeat delay thereafter,\n * as long as HTML control Object e has an active \"down\" event and fn() returns true.\n *\n * @param {Object} e\n * @param {number} msDelay\n * @param {number} msRepeat\n * @param {function(boolean)} fn is passed false on the first call, true on all repeated calls\n */\n static onClickRepeat(e, msDelay, msRepeat, fn)\n {\n var ms = 0, timer = null, fIgnoreMouseEvents = false;\n\n var fnRepeat = function doClickRepeat()\n {\n if (fn(ms === msRepeat)) {\n timer = setTimeout(fnRepeat, ms);\n ms = msRepeat;\n }\n };\n e.onmousedown = function()\n {\n // Web.log(\"onMouseDown()\");\n if (!fIgnoreMouseEvents) {\n if (!timer) {\n ms = msDelay;\n fnRepeat();\n }\n }\n };\n e.ontouchstart = function()\n {\n // Web.log(\"onTouchStart()\");\n if (!timer) {\n ms = msDelay;\n fnRepeat();\n }\n };\n e.onmouseup = e.onmouseout = function()\n {\n // Web.log(\"onMouseUp()/onMouseOut()\");\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n };\n e.ontouchend = e.ontouchcancel = function()\n {\n // Web.log(\"onTouchEnd()/onTouchCancel()\");\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n /*\n * Devices that generate ontouch* events ALSO generate onmouse* events,\n * and generally do so immediately after all the touch events are complete,\n * so unless we want double the action, we need to ignore mouse events.\n */\n fIgnoreMouseEvents = true;\n };\n }\n\n /**\n * onPageEvent(sName, fn)\n *\n * For 'onload', 'onunload', and 'onpageshow' events, most callers should NOT use this function, but\n * instead use Web.onInit(), Web.onShow(), and Web.onExit(), respectively.\n *\n * The only components that should still use onPageEvent() are THIS component (see the bottom of this file)\n * and components that need to capture other events (eg, the 'onresize' event in the Video component).\n *\n * This function creates a chain of callbacks, allowing multiple JavaScript modules to define handlers\n * for the same event, which wouldn't be possible if everyone modified window['onload'], window['onunload'],\n * etc, themselves. However, that's less of a concern now, because assuming everyone else is now using\n * onInit(), onExit(), etc, then there really IS only one component setting the window callback: this one.\n *\n * NOTE: It's risky to refer to obscure event handlers with \"dot\" names, because the Closure Compiler may\n * erroneously replace them (eg, window.onpageshow is a good example).\n *\n * @param {string} sFunc\n * @param {function()} fn\n */\n static onPageEvent(sFunc, fn)\n {\n if (window) {\n var fnPrev = window[sFunc];\n if (typeof fnPrev !== 'function') {\n window[sFunc] = fn;\n } else {\n /*\n * TODO: Determine whether there's any value in receiving/sending the Event object that the\n * browser provides when it generates the original event.\n */\n window[sFunc] = function onWindowEvent()\n {\n if (fnPrev) fnPrev();\n fn();\n };\n }\n }\n };\n\n /**\n * onInit(fn)\n *\n * Use this instead of setting window.onload. Allows multiple JavaScript modules to define their own 'onload' event handler.\n *\n * @param {function()} fn\n */\n static onInit(fn)\n {\n Web.aPageEventHandlers['init'].push(fn);\n };\n\n /**\n * onShow(fn)\n *\n * @param {function()} fn\n *\n * Use this instead of setting window.onpageshow. Allows multiple JavaScript modules to define their own 'onpageshow' event handler.\n */\n static onShow(fn)\n {\n Web.aPageEventHandlers['show'].push(fn);\n };\n\n /**\n * onExit(fn)\n *\n * @param {function()} fn\n *\n * Use this instead of setting window.onunload. Allows multiple JavaScript modules to define their own 'onunload' event handler.\n */\n static onExit(fn)\n {\n Web.aPageEventHandlers['exit'].push(fn);\n };\n\n /**\n * doPageEvent(afn)\n *\n * @param {Array.<function()>} afn\n */\n static doPageEvent(afn)\n {\n if (Web.fPageEventsEnabled) {\n try {\n for (var i = 0; i < afn.length; i++) {\n afn[i]();\n }\n } catch (e) {\n Web.notice(\"An unexpected error occurred: \" + e.message + \"\\n\\nIf it happens again, please send this information to support@pcjs.org. Thanks.\");\n }\n }\n };\n\n /**\n * enablePageEvents(fEnable)\n *\n * @param {boolean} fEnable is true to enable page events, false to disable (they're enabled by default)\n */\n static enablePageEvents(fEnable)\n {\n if (!Web.fPageEventsEnabled && fEnable) {\n Web.fPageEventsEnabled = true;\n if (Web.fPageLoaded) Web.sendPageEvent('init');\n if (Web.fPageShowed) Web.sendPageEvent('show');\n return;\n }\n Web.fPageEventsEnabled = fEnable;\n }\n\n /**\n * sendPageEvent(sEvent)\n *\n * This allows us to manually trigger page events.\n *\n * @param {string} sEvent (one of 'init', 'show' or 'exit')\n */\n static sendPageEvent(sEvent)\n {\n if (Web.aPageEventHandlers[sEvent]) {\n Web.doPageEvent(Web.aPageEventHandlers[sEvent]);\n }\n }\n}\n\nWeb.parmsURL = null; // initialized on first call to parseURLParms()\n\nWeb.aPageEventHandlers = {\n 'init': [], // list of window 'onload' handlers\n 'show': [], // list of window 'onpageshow' handlers\n 'exit': [] // list of window 'onunload' handlers (although we prefer to use 'onbeforeunload' if possible)\n};\n\nWeb.asBrowserPrefixes = ['', 'moz', 'ms', 'webkit'];\n\nWeb.fPageLoaded = false; // set once the page's first 'onload' event has occurred\nWeb.fPageShowed = false; // set once the page's first 'onpageshow' event has occurred\nWeb.fPageEventsEnabled = true; // default is true, set to false (or true) by enablePageEvents()\n\n/**\n * fLocalStorage\n *\n * true if localStorage support exists, is enabled, and works; \"falsey\" otherwise\n *\n * @type {boolean|null}\n */\nWeb.fLocalStorage = null;\n\n/**\n * TODO: Is there any way to get the Closure Compiler to stop inlining this string? This isn't cutting it.\n *\n * @const {string}\n */\nWeb.sLocalStorageTest = \"PCjs.localStorage\";\n\nWeb.onPageEvent('onload', function onPageLoad() {\n Web.fPageLoaded = true;\n Web.doPageEvent(Web.aPageEventHandlers['init']);\n});\n\nWeb.onPageEvent('onpageshow', function onPageShow() {\n Web.fPageShowed = true;\n Web.doPageEvent(Web.aPageEventHandlers['show']);\n});\n\nWeb.onPageEvent(Web.isUserAgent(\"iOS\")? 'onpagehide' : (Web.isUserAgent(\"Opera\")? 'onunload' : 'onbeforeunload'), function onPageUnload() {\n Web.doPageEvent(Web.aPageEventHandlers['exit']);\n});\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/component.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * All PCjs components now use JSDoc types, primarily so that Google's Closure Compiler will compile\n * everything with zero warnings when ADVANCED_OPTIMIZATIONS are enabled. For more information about\n * the JSDoc types supported by the Closure Compiler:\n *\n * https://developers.google.com/closure/compiler/docs/js-for-compiler#types\n *\n * I also attempted to validate this code with JSLint, but it complained too much; eg, it didn't like\n * \"while (true)\", a tried and \"true\" programming convention for decades, and it wanted me to replace\n * all \"++\" and \"--\" operators with \"+= 1\" and \"-= 1\", use \"(s || '')\" instead of \"(s? s : '')\", etc.\n *\n * I prefer sticking with traditional C-style idioms, in part because they are more portable. That\n * does NOT mean I'm trying to write \"portable JavaScript,\" but some of this code was ported from C code\n * I'd written long ago, so portability is good, and I'm not going to throw that away if there's no need.\n *\n * UPDATE: I've since switched from JSLint to JSHint, which seems to have more reasonable defaults.\n * And for new code, I have adopted some popular JavaScript idioms, like \"(s || '')\", although the need\n * for those kinds of expressions will be reduced as I also start adopting some ES6 features, like\n * default parameters.\n */\n\n\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * subclass (eg, SerialPort), because otherwise the Compiler won't allow us to *reference*\n * the named property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass Component {\n /**\n * Component(type, parms, bitsMessage)\n *\n * A Component object requires:\n *\n * type: a user-defined type name (eg, \"CPU\")\n *\n * and accepts any or all of the following (parms) properties:\n *\n * id: component ID (default is \"\")\n * name: component name (default is \"\"; if blank, toString() will use the type name only)\n * comment: component comment string (default is undefined)\n *\n * Component subclasses will usually have additional (parms) properties.\n *\n * @param {string} type\n * @param {Object} [parms]\n * @param {number} [bitsMessage] selects message(s) that the component wants to enable (default is 0)\n */\n constructor(type, parms, bitsMessage)\n {\n this.type = type;\n\n if (!parms) parms = {'id': \"\", 'name': \"\"};\n\n this.id = parms['id'] || \"\";\n this.name = parms['name'];\n this.comment = parms['comment'];\n this.parms = parms;\n\n /*\n * The following Component properties need to be accessible by other machines and/or command scripts;\n * well, OK, or we could have exported some new functions to walk the contents of these properties, as we\n * did with findMachineComponent(), but this works just as well.\n *\n * Also, while the double-assignment looks silly (ie, using both dot and bracket property notation), it\n * resolves a complaint from the Closure Compiler, because if we use ONLY bracket notation here, then the\n * Compiler wants us to change all the other references to bracket notation as well.\n */\n this.exports = this['exports'] = {};\n this.bindings = this['bindings'] = {};\n\n var i = this.id.indexOf('.');\n if (i < 0) {\n this.idComponent = this.id;\n } else {\n this.idMachine = this.id.substr(0, i);\n this.idComponent = this.id.substr(i + 1);\n }\n\n /*\n * Gather all the various component flags (booleans) into a single \"flags\" object, and encourage\n * subclasses to do the same, to reduce the property clutter we have to wade through while debugging.\n */\n this.flags = {\n ready: false,\n busy: false,\n busyCancel: false,\n initDone: false,\n powered: false,\n unloading: false,\n error: false\n };\n\n this.fnReady = null;\n this.clearError();\n this.bitsMessage = bitsMessage || 0;\n\n this.cmp = null;\n this.bus = null;\n this.cpu = null;\n this.dbg = null;\n\n /*\n * TODO: Consider adding another parameter to the Component() constructor that allows components to tell\n * us if they support single or multiple instances per machine. For example, there can be multiple SerialPort\n * components per machine, but only one CPU component (some machines also support an FPU, but that component\n * is considered separate from the CPU).\n *\n * It's not critical, but it would help catch machine configuration errors; for example, a machine that mistakenly\n * includes two CPU components may, aside from wasting memory, end up with odd side-effects, like unresponsive\n * CPU controls.\n */\n Component.add(this);\n }\n\n /**\n * Component.add(component)\n *\n * @param {Component} component\n */\n static add(component)\n {\n /*\n * This just generates a lot of useless noise, handy in the early days, not so much these days....\n *\n * if (DEBUG) Component.log(\"Component.add(\" + component.type + \",\" + component.id + \")\");\n */\n Component.components.push(component);\n }\n\n /**\n * Component.addMachine(idMachine)\n *\n * @param {string} idMachine\n */\n static addMachine(idMachine)\n {\n Component.machines[idMachine] = {};\n }\n\n /**\n * Component.addMachineResource(idMachine, sName, data)\n *\n * @param {string} idMachine\n * @param {string|null} sName (name of the resource)\n * @param {*} data\n */\n static addMachineResource(idMachine, sName, data)\n {\n /*\n * I used to assert(Component.machines[idMachine]), but when we're running as a Node app, embed.js is not used,\n * so addMachine() is never called, so resources do not need to be recorded.\n */\n if (Component.machines[idMachine] && sName) {\n Component.machines[idMachine][sName] = data;\n }\n }\n\n /**\n * Component.getMachineResources(idMachine)\n *\n * @param {string} idMachine\n * @return {Object|undefined}\n */\n static getMachineResources(idMachine)\n {\n return Component.machines[idMachine];\n }\n\n /**\n * Component.getTime()\n *\n * @return {number} the current time, in milliseconds\n */\n static getTime()\n {\n return Date.now() || +new Date();\n }\n\n /**\n * Component.log(s, type)\n *\n * For diagnostic output only.\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n static log(s, type)\n {\n if (!COMPILED) {\n if (s) {\n var sElapsed = \"\", sMsg = (type? (type + \": \") : \"\") + s;\n if (typeof Usr != \"undefined\") {\n if (Component.msStart === undefined) {\n Component.msStart = Component.getTime();\n }\n sElapsed = (Component.getTime() - Component.msStart) + \"ms: \";\n }\n sMsg = sMsg.replace(/\\r/g, '\\\\r').replace(/\\n/g, ' ');\n if (window && window.console) console.log(sElapsed + sMsg);\n }\n }\n }\n\n /**\n * Component.assert(f, s)\n *\n * Verifies conditions that must be true (for DEBUG builds only).\n *\n * The Closure Compiler should automatically remove all references to Component.assert() in non-DEBUG builds.\n * TODO: Add a task to the build process that \"asserts\" there are no instances of \"assertion failure\" in RELEASE builds.\n *\n * @param {boolean} f is the expression we are asserting to be true\n * @param {string} [s] is description of the assertion on failure\n */\n static assert(f, s)\n {\n if (DEBUG) {\n if (!f) {\n if (!s) s = \"assertion failure\";\n Component.log(s);\n throw new Error(s);\n }\n }\n }\n\n /**\n * Component.print(s)\n *\n * Components that inherit from this class should use this.print(), rather than Component.print(), because\n * if a Control Panel is loaded, it will override only the instance method, not the class method (overriding the\n * class method would improperly affect any other machines loaded on the same page).\n *\n * @this {Component}\n * @param {string} s\n */\n static print(s)\n {\n if (!COMPILED) {\n var i = s.lastIndexOf('\\n');\n if (i >= 0) {\n Component.println(s.substr(0, i));\n s = s.substr(i + 1);\n }\n Component.printBuffer += s;\n }\n }\n\n /**\n * Component.println(s, type, id)\n *\n * Components that inherit from this class should use this.println(), rather than Component.println(), because\n * if a Control Panel is loaded, it will override only the instance method, not the class method (overriding the\n * class method would improperly affect any other machines loaded on the same page).\n *\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n * @param {string} [id] is the caller's ID, if any\n */\n static println(s, type, id)\n {\n if (!COMPILED) {\n s = Component.printBuffer + (s || \"\");\n Component.log((id? (id + \": \") : \"\") + (s? (\"\\\"\" + s + \"\\\"\") : \"\"), type);\n Component.printBuffer = \"\";\n }\n }\n\n /**\n * Component.notice(s, fPrintOnly, id)\n *\n * notice() is like println() but implies a need for user notification, so we alert() as well.\n *\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n * @return {boolean}\n */\n static notice(s, fPrintOnly, id)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.NOTICE, id);\n }\n if (!fPrintOnly) Component.alertUser((id? (id + \": \") : \"\") + s);\n return true;\n }\n\n /**\n * Component.warning(s)\n *\n * @param {string} s describes the warning\n */\n static warning(s)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.WARNING);\n }\n Component.alertUser(s);\n }\n\n /**\n * Component.error(s)\n *\n * @param {string} s describes the error; an alert() is displayed as well\n */\n static error(s)\n {\n if (!COMPILED) {\n Component.println(s, Component.PRINT.ERROR);\n }\n Component.alertUser(s);\n }\n\n /**\n * Component.alertUser(sMessage)\n *\n * @param {string} sMessage\n */\n static alertUser(sMessage)\n {\n if (window) {\n window.alert(sMessage);\n } else {\n Component.log(sMessage);\n }\n }\n\n /**\n * Component.confirmUser(sPrompt)\n *\n * @param {string} sPrompt\n * @returns {boolean} true if the user clicked OK, false if Cancel/Close\n */\n static confirmUser(sPrompt)\n {\n var fResponse = false;\n if (window) {\n fResponse = window.confirm(sPrompt);\n }\n return fResponse;\n }\n\n /**\n * Component.promptUser()\n *\n * @param {string} sPrompt\n * @param {string} [sDefault]\n * @returns {string|null}\n */\n static promptUser(sPrompt, sDefault)\n {\n var sResponse = null;\n if (window) {\n sResponse = window.prompt(sPrompt, sDefault === undefined? \"\" : sDefault);\n }\n return sResponse;\n }\n\n /**\n * Component.appendControl(control, sText)\n *\n * @param {Object} control\n * @param {string} sText\n */\n static appendControl(control, sText)\n {\n control.value += sText;\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (COMPILED) {\n sText = control.value;\n if (sText.length > 8192) control.value = sText.substr(sText.length - 4096);\n }\n control.scrollTop = control.scrollHeight;\n }\n\n /**\n * Component.replaceControl(control, sSearch, sReplace)\n *\n * @param {Object} control\n * @param {string} sSearch\n * @param {string} sReplace\n */\n static replaceControl(control, sSearch, sReplace)\n {\n var sText = control.value;\n var i = sText.lastIndexOf(sSearch);\n if (i < 0) {\n sText += sSearch + '\\n';\n } else {\n sText = sText.substr(0, i) + sReplace + sText.substr(i + sSearch.length);\n }\n /*\n * Prevent the <textarea> from getting too large; otherwise, printing becomes slower and slower.\n */\n if (COMPILED && sText.length > 8192) sText = sText.substr(sText.length - 4096);\n control.value = sText;\n control.scrollTop = control.scrollHeight;\n }\n\n /**\n * Component.bindExternalControl(component, sBinding, sType)\n *\n * @param {Component} component\n * @param {string} sBinding\n * @param {string} [sType] is the external component type (default is \"Panel\")\n */\n static bindExternalControl(component, sBinding, sType = \"Panel\")\n {\n if (sBinding) {\n var target = Component.getComponentByType(sType, component.id);\n if (target) {\n var control = target.bindings[sBinding];\n if (control) {\n component.setBinding(\"\", sBinding, control);\n }\n }\n }\n }\n\n /**\n * Component.bindComponentControls(component, element, sAppClass)\n *\n * @param {Component} component\n * @param {HTMLElement} element from the DOM\n * @param {string} sAppClass\n */\n static bindComponentControls(component, element, sAppClass)\n {\n var aeControls = Component.getElementsByClass(element.parentNode, sAppClass + \"-control\");\n\n for (var iControl = 0; iControl < aeControls.length; iControl++) {\n\n var aeChildNodes = aeControls[iControl].childNodes;\n\n for (var iNode = 0; iNode < aeChildNodes.length; iNode++) {\n var control = aeChildNodes[iNode];\n if (control.nodeType !== 1 /* document.ELEMENT_NODE */) {\n continue;\n }\n var sClass = control.getAttribute(\"class\");\n if (!sClass) continue;\n var aClasses = sClass.split(\" \");\n for (var iClass = 0; iClass < aClasses.length; iClass++) {\n var parms;\n sClass = aClasses[iClass];\n switch (sClass) {\n case sAppClass + \"-binding\":\n parms = Component.getComponentParms(/** @type {HTMLElement} */(control));\n if (parms && parms['binding'] !== undefined) {\n component.setBinding(parms['type'], parms['binding'], /** @type {HTMLElement} */(control), parms['value']);\n } else if (!parms || parms['type'] != \"description\") {\n Component.log(\"Component '\" + component.toString() + \"' missing binding\" + (parms? \" for \" + parms['type'] : \"\"), \"warning\");\n }\n iClass = aClasses.length;\n break;\n default:\n // if (DEBUG) Component.log(\"Component.bindComponentControls(\" + component.toString() + \"): unrecognized control class \\\"\" + sClass + \"\\\"\", \"warning\");\n break;\n }\n }\n }\n }\n }\n\n /**\n * Component.getComponents(idRelated)\n *\n * We could store components as properties, using the component's ID, and change\n * this linear lookup into a property lookup, but some components may have no ID.\n *\n * @param {string} [idRelated] of related component\n * @return {Array} of components\n */\n static getComponents(idRelated)\n {\n var i;\n var aComponents = [];\n /*\n * getComponentByID(id, idRelated)\n *\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated) {\n if ((i = idRelated.indexOf('.')) > 0)\n idRelated = idRelated.substr(0, i + 1);\n else\n idRelated = \"\";\n }\n for (i = 0; i < Component.components.length; i++) {\n var component = Component.components[i];\n if (!idRelated || !component.id.indexOf(idRelated)) {\n aComponents.push(component);\n }\n }\n return aComponents;\n }\n\n /**\n * Component.getComponentByID(id, idRelated)\n *\n * We could store components as properties, using the component's ID, and change\n * this linear lookup into a property lookup, but some components may have no ID.\n *\n * @param {string} id of the desired component\n * @param {string} [idRelated] of related component\n * @return {Component|null}\n */\n static getComponentByID(id, idRelated)\n {\n if (id !== undefined) {\n var i;\n /*\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated && (i = idRelated.indexOf('.')) > 0) {\n id = idRelated.substr(0, i + 1) + id;\n }\n for (i = 0; i < Component.components.length; i++) {\n if (Component.components[i].id === id) {\n return Component.components[i];\n }\n }\n if (Component.components.length) {\n Component.log(\"Component ID '\" + id + \"' not found\", \"warning\");\n }\n }\n return null;\n }\n\n /**\n * Component.getComponentByType(sType, idRelated, componentPrev)\n *\n * @param {string} sType of the desired component\n * @param {string} [idRelated] of related component\n * @param {Component|null} [componentPrev] of previously returned component, if any\n * @return {Component|null}\n */\n static getComponentByType(sType, idRelated, componentPrev)\n {\n if (sType !== undefined) {\n var i;\n /*\n * If idRelated is provided, we check it for a machine prefix, and use any\n * existing prefix to constrain matches to IDs with the same prefix, in order to\n * avoid matching components belonging to other machines.\n */\n if (idRelated) {\n if ((i = idRelated.indexOf('.')) > 0) {\n idRelated = idRelated.substr(0, i + 1);\n } else {\n idRelated = \"\";\n }\n }\n for (i = 0; i < Component.components.length; i++) {\n if (componentPrev) {\n if (componentPrev == Component.components[i]) componentPrev = null;\n continue;\n }\n if (sType == Component.components[i].type && (!idRelated || !Component.components[i].id.indexOf(idRelated))) {\n return Component.components[i];\n }\n }\n Component.log(\"Component type '\" + sType + \"' not found\", \"warning\");\n }\n return null;\n }\n\n /**\n * Component.getComponentParms(element)\n *\n * @param {HTMLElement} element from the DOM\n */\n static getComponentParms(element)\n {\n var parms = null;\n var sParms = element.getAttribute(\"data-value\");\n if (sParms) {\n try {\n parms = eval('(' + sParms + ')'); // jshint ignore:line\n /*\n * We can no longer invoke removeAttribute() because some components (eg, Panel) need\n * to run their initXXX() code more than once, to avoid initialization-order dependencies.\n *\n * if (!DEBUG) {\n * element.removeAttribute(\"data-value\");\n * }\n */\n } catch(e) {\n Component.error(e.message + \" (\" + sParms + \")\");\n }\n }\n return parms;\n }\n\n /**\n * Component.getElementsByClass(element, sClass, sObjClass)\n *\n * This is a cross-browser helper function, since not all browser's support getElementsByClassName()\n *\n * TODO: This should probably be moved into weblib.js at some point, along with the control binding functions above,\n * to keep all the browser-related code together.\n *\n * @param {HTMLDocument|HTMLElement|Node} element from the DOM\n * @param {string} sClass\n * @param {string} [sObjClass]\n * @return {Array|NodeList}\n */\n static getElementsByClass(element, sClass, sObjClass)\n {\n if (sObjClass) sClass += '-' + sObjClass + \"-object\";\n /*\n * Use the browser's built-in getElementsByClassName() if it appears to be available\n * (for example, it's not available in IE8, but it should be available in IE9 and up)\n */\n if (element.getElementsByClassName) {\n return element.getElementsByClassName(sClass);\n }\n var i, j, ae = [];\n var aeAll = element.getElementsByTagName(\"*\");\n var re = new RegExp('(^| )' + sClass + '( |$)');\n for (i = 0, j = aeAll.length; i < j; i++) {\n if (re.test(aeAll[i].className)) {\n ae.push(aeAll[i]);\n }\n }\n if (!ae.length) {\n Component.log('No elements of class \"' + sClass + '\" found');\n }\n return ae;\n }\n\n /**\n * Component.getScriptCommands(sScript)\n *\n * This is a simple parser that breaks sScript into an array of commands, where each command\n * is an array of tokens, where tokens are sequences of characters separated by any of: tab, space,\n * carriage-return (CR), line-feed (LF), semicolon, single-quote, or double-quote; if a quote is\n * used, all characters up to the next matching quote become part of the token, allowing any of the\n * other separators to be part of the token. CR, LF and semicolon also serve to terminate a command,\n * with semicolon being preferred, because it's 1) more visible, and 2) essential when the entire\n * script is a multi-line string where all CR/LF were replaced by spaces (which is what Jekyll does,\n * and since we can't change Jekyll, it's what our own MarkDown Front Matter parser does as well;\n * see convertMD() in markout.js, where the aCommandDefs array is built).\n *\n * Backslash sequences like \\n, \\r, and \\\\ have already been converted to LF, CR and backslash\n * characters, since the entire script string is injected into a JavaScript function call, so any\n * backslash sequence that JavaScript supports is automatically converted:\n *\n * \\0 \\' \\\" \\\\ \\n \\r \\v \\t \\b \\f \\uXXXX \\xXX\n * ^J ^M ^K ^I ^H ^L\n *\n * To support any other non-printable 8-bit character, such as ESC, you should use \\xXX, where XX\n * is the ASCII code in hex. For ESC, that would be \\x1B.\n *\n * @param {string} sScript\n * @return {Array}\n */\n static getScriptCommands(sScript)\n {\n var cch = sScript.length;\n var aCommands = [], aTokens = [], sToken = \"\", chQuote = null;\n for (var i = 0; i < cch; i++) {\n var ch = sScript[i];\n if (ch == '\"' || ch == \"'\") {\n if (chQuote && ch != chQuote) {\n sToken += ch;\n continue;\n }\n if (!chQuote) {\n chQuote = ch;\n } else {\n chQuote = null;\n }\n if (sToken) {\n aTokens.push(sToken);\n sToken = \"\";\n }\n continue;\n }\n if (!chQuote) {\n if (ch == '\\r' || ch == '\\n') {\n ch = ';';\n }\n if (ch == ' ' || ch == '\\t' || ch == ';') {\n if (sToken) {\n aTokens.push(sToken);\n sToken = \"\";\n }\n if (ch == ';' && aTokens.length) {\n aCommands.push(aTokens);\n aTokens = [];\n }\n continue;\n }\n }\n sToken += ch;\n }\n if (sToken) {\n aTokens.push(sToken);\n }\n if (aTokens.length) {\n aCommands.push(aTokens);\n }\n return aCommands;\n }\n\n /**\n * Component.processScript(idMachine, sScript)\n *\n * @param {string} idMachine\n * @param {string} [sScript]\n * @return {boolean}\n */\n static processScript(idMachine, sScript)\n {\n var fSuccess = false;\n idMachine += \".machine\";\n if (!sScript) {\n delete Component.commands[idMachine];\n fSuccess = true;\n }\n else if (typeof sScript == \"string\" && !Component.commands[idMachine]) {\n fSuccess = true;\n Component.commands[idMachine] = Component.getScriptCommands(sScript);\n if (!Component.processCommands(idMachine)) {\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * Component.processCommands(idMachine)\n *\n * @param {string} idMachine\n * @return {boolean}\n */\n static processCommands(idMachine)\n {\n var fSuccess = true;\n var aCommands = Component.commands[idMachine];\n\n // var dbg = Component.getComponentByType(\"Debugger\", idMachine);\n\n while (aCommands && aCommands.length) {\n\n var aTokens = aCommands.splice(0, 1)[0];\n var sCommand = aTokens[0];\n\n /*\n * It's possible to route this output to the Debugger window with dbg.println()\n * instead, but it's a bit too confusing mingling script output in a window that\n * already mingles Debugger and machine output.\n */\n Component.println(aTokens.join(' '), Component.PRINT.SCRIPT);\n\n var fnCallReady = null;\n if (Component.asyncCommands.indexOf(sCommand) >= 0) {\n fnCallReady = function processNextCommand() {\n return function() {\n Component.processCommands(idMachine);\n }\n }();\n }\n\n var fnCommand = Component.globalCommands[sCommand];\n if (fnCommand) {\n if (!fnCallReady) {\n fSuccess = fnCommand(aTokens[1], aTokens[2], aTokens[3]);\n } else {\n if (!fnCommand(fnCallReady, aTokens[1], aTokens[2], aTokens[3])) break;\n }\n }\n else {\n fSuccess = false;\n var component = Component.getComponentByType(aTokens[1], idMachine);\n if (component) {\n fnCommand = Component.componentCommands[sCommand];\n if (fnCommand) {\n fSuccess = fnCommand(component, aTokens[2], aTokens[3]);\n }\n else {\n var exports = component['exports'];\n if (exports) {\n fnCommand = exports[sCommand];\n if (fnCommand) {\n fSuccess = true;\n if (!fnCallReady) {\n fSuccess = fnCommand.call(component, aTokens[2], aTokens[3]);\n } else {\n if (!fnCommand.call(component, fnCallReady, aTokens[2], aTokens[3])) break;\n }\n }\n }\n }\n }\n }\n\n if (!fSuccess) {\n Component.alertUser(\"Script error: '\" + sCommand + \"' command \" + (fnCommand? \" failed\" : \" not recognized\"));\n break;\n }\n }\n\n if (aCommands && !aCommands.length) {\n delete Component.commands[idMachine];\n }\n\n return fSuccess;\n }\n\n /**\n * Component.scriptAlert(sMessage)\n *\n * @param {string} sMessage\n * @return {boolean}\n */\n static scriptAlert(sMessage)\n {\n Component.alertUser(sMessage);\n return true;\n }\n\n /**\n * Component.scriptSelect(component, sBinding, sValue)\n *\n * @param {Component} component\n * @param {string} sBinding\n * @param {string} sValue\n * @return {boolean}\n */\n static scriptSelect(component, sBinding, sValue)\n {\n var fSuccess = false;\n var aBindings = component['bindings'];\n var control = aBindings[sBinding];\n if (control) {\n for (var i = 0; i < control.options.length; i++) {\n if (control.options[i].textContent == sValue) {\n if (control.selectedIndex != i) {\n control.selectedIndex = i;\n }\n fSuccess = true;\n break;\n }\n }\n }\n return fSuccess;\n }\n\n /**\n * Component.scriptSleep(fnCallback, sDelay)\n *\n * @param {function()} fnCallback\n * @param {string} sDelay (in milliseconds)\n * @return {boolean}\n */\n static scriptSleep(fnCallback, sDelay)\n {\n setTimeout(fnCallback, +sDelay);\n return false;\n }\n\n /**\n * toString()\n *\n * @this {Component}\n * @return {string}\n */\n toString()\n {\n return (this.name? this.name : (this.id || this.type));\n }\n\n /**\n * getMachineNum()\n *\n * @this {Component}\n * @return {number} unique machine number\n */\n getMachineNum()\n {\n var nMachine = 1;\n if (this.idMachine) {\n var aDigits = this.idMachine.match(/\\d+/);\n if (aDigits !== null)\n nMachine = parseInt(aDigits[0], 10);\n }\n return nMachine;\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * Component's setBinding() method is intended to be overridden by subclasses.\n *\n * @this {Component}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", \"submit\", \"textarea\", \"canvas\")\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, 'print')\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n switch (sBinding) {\n case 'clear':\n if (!this.bindings[sBinding]) {\n this.bindings[sBinding] = control;\n control.onclick = (function(component) {\n return function clearControl() {\n if (component.bindings['print']) {\n component.bindings['print'].value = \"\";\n }\n };\n }(this));\n }\n return true;\n case 'print':\n if (!this.bindings[sBinding]) {\n var controlTextArea = /** @type {HTMLTextAreaElement} */(control);\n this.bindings[sBinding] = controlTextArea;\n /**\n * Override this.notice() with a replacement function that eliminates the Component.alertUser() call.\n *\n * @this {Component}\n * @param {string} s\n * @return {boolean}\n */\n this.notice = function noticeControl(s /*, fPrintOnly, id*/) {\n this.println(s, this.type);\n return true;\n };\n /*\n * This was added for Firefox (Safari will clear the <textarea> on a page reload, but Firefox does not).\n */\n controlTextArea.value = \"\";\n this.print = function(control) {\n return function printControl(s) {\n Component.appendControl(control, s);\n };\n }(controlTextArea);\n this.println = function(component, control) {\n return function printlnControl(s, type, id) {\n if (!s) s = \"\";\n if (type != Component.PRINT.PROGRESS || s.slice(-3) != \"...\") {\n if (type) s = type + \": \" + s;\n Component.appendControl(control, s + '\\n');\n } else {\n Component.replaceControl(control, s, s + '.');\n }\n if (!COMPILED && window && window.console) Component.println(s, type, id);\n };\n }(this, controlTextArea);\n }\n return true;\n default:\n return false;\n }\n }\n\n /**\n * log(s, type)\n *\n * For diagnostic output only.\n *\n * WARNING: Even though this function's body is completely wrapped in DEBUG, that won't prevent the Closure Compiler\n * from including it, so all calls must still be prefixed with \"if (DEBUG) ....\". For this reason, the class method,\n * Component.log(), is preferred, because the compiler IS smart enough to remove those calls.\n *\n * @this {Component}\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n */\n log(s, type)\n {\n if (!COMPILED) {\n Component.log(s, type || this.id || this.type);\n }\n }\n\n /**\n * assert(f, s)\n *\n * Verifies conditions that must be true (for DEBUG builds only).\n *\n * WARNING: Make sure you preface all calls to this.assert() with \"if (DEBUG)\", because unlike Component.assert(),\n * the Closure Compiler can't be sure that this instance method hasn't been overridden, so it refuses to treat it as\n * dead code in non-DEBUG builds.\n *\n * TODO: Add a task to the build process that \"asserts\" there are no instances of \"assertion failure\" in RELEASE builds.\n *\n * @this {Component}\n * @param {boolean|number} f is the expression asserted to be true\n * @param {string} [s] is a description of the assertion to be displayed or logged on failure\n */\n assert(f, s)\n {\n if (DEBUG) {\n if (!f) {\n s = \"assertion failure in \" + (this.id || this.type) + (s? \": \" + s : \"\");\n if (DEBUGGER && this.dbg) {\n this.dbg.stopCPU();\n /*\n * Why do we throw an Error only to immediately catch and ignore it? Simply to give\n * any IDE the opportunity to inspect the application's state. Even when the IDE has\n * control, you should still be able to invoke Debugger commands from the IDE's REPL,\n * using the global function that the Debugger constructor defines; eg:\n *\n * pcx86('r')\n * pcx86('dw 0:0')\n * pcx86('h')\n * ...\n *\n * If you have no desire to stop on assertions, consider this a no-op. However, another\n * potential benefit of creating an Error object is that, for browsers like Chrome, we get\n * a stack trace, too.\n */\n try {\n throw new Error(s);\n } catch(e) {\n this.println(e.stack || e.message);\n }\n return;\n }\n this.log(s);\n throw new Error(s);\n }\n }\n }\n\n /**\n * print(s)\n *\n * Components using this.print() should wait until after their constructor has run to display any messages, because\n * if a Control Panel has been loaded, its override will not take effect until its own constructor has run.\n *\n * @this {Component}\n * @param {string} s\n */\n print(s)\n {\n Component.print(s);\n }\n\n /**\n * println(s, type, id)\n *\n * Components using this.println() should wait until after their constructor has run to display any messages, because\n * if a Control Panel has been loaded, its override will not take effect until its own constructor has run.\n *\n * @this {Component}\n * @param {string} [s] is the message text\n * @param {string} [type] is the message type\n * @param {string} [id] is the caller's ID, if any\n */\n println(s, type, id)\n {\n Component.println(s, type, id || this.id);\n }\n\n /**\n * status(s)\n *\n * status() is like println() but it also includes information about the component (ie, the component type),\n * which is why there is no corresponding Component.status() function.\n *\n * @this {Component}\n * @param {string} s is the message text\n */\n status(s)\n {\n this.println(this.type + \": \" + s);\n }\n\n /**\n * notice(s, fPrintOnly, id)\n *\n * notice() is like println() but implies a need for user notification, so we alert() as well; however, if this.println()\n * is overridden, this.notice will be replaced with a similar override, on the assumption that the override is taking care\n * of alerting the user.\n *\n * @this {Component}\n * @param {string} s is the message text\n * @param {boolean} [fPrintOnly]\n * @param {string} [id] is the caller's ID, if any\n * @return {boolean}\n */\n notice(s, fPrintOnly, id)\n {\n if (!fPrintOnly) {\n /*\n * See if the associated computer, if any, is \"unloading\"....\n */\n var computer = Component.getComponentByType(\"Computer\", this.id);\n if (computer && computer.flags.unloading) {\n console.log(\"ignoring notice during unload: \" + s);\n return false;\n }\n }\n Component.notice(s, fPrintOnly, id || this.type);\n return true;\n }\n\n /**\n * setError(s)\n *\n * Set a fatal error condition\n *\n * @this {Component}\n * @param {string} s describes a fatal error condition\n */\n setError(s)\n {\n this.flags.error = true;\n this.notice(s); // TODO: Any cases where we should still prefix this string with \"Fatal error: \"?\n }\n\n /**\n * clearError()\n *\n * Clear any fatal error condition\n *\n * @this {Component}\n */\n clearError() {\n this.flags.error = false;\n }\n\n /**\n * isError()\n *\n * Report any fatal error condition\n *\n * @this {Component}\n * @return {boolean} true if a fatal error condition exists, false if not\n */\n isError()\n {\n if (this.flags.error) {\n this.println(this.toString() + \" error\");\n return true;\n }\n return false;\n }\n\n /**\n * isReady(fnReady)\n *\n * Return the \"ready\" state of the component; if the component is not ready, it will queue the optional\n * notification function, otherwise it will immediately call the notification function, if any, without queuing it.\n *\n * NOTE: Since only the Computer component actually cares about the \"readiness\" of other components, the so-called\n * \"queue\" of notification functions supports exactly one function. This keeps things nice and simple.\n *\n * @this {Component}\n * @param {function()} [fnReady]\n * @return {boolean} true if the component is in a \"ready\" state, false if not\n */\n isReady(fnReady)\n {\n if (fnReady) {\n if (this.flags.ready) {\n fnReady();\n } else {\n if (MAXDEBUG) this.log(\"NOT ready\");\n this.fnReady = fnReady;\n }\n }\n return this.flags.ready;\n }\n\n /**\n * setReady(fReady)\n *\n * Set the \"ready\" state of the component to true, and call any queued notification functions.\n *\n * @this {Component}\n * @param {boolean} [fReady] is assumed to indicate \"ready\" unless EXPLICITLY set to false\n */\n setReady(fReady)\n {\n if (!this.flags.error) {\n this.flags.ready = (fReady !== false);\n if (this.flags.ready) {\n if (MAXDEBUG /* || this.name */) this.log(\"ready\");\n var fnReady = this.fnReady;\n this.fnReady = null;\n if (fnReady) fnReady();\n }\n }\n }\n\n /**\n * isBusy(fCancel)\n *\n * Return the \"busy\" state of the component\n *\n * @this {Component}\n * @param {boolean} [fCancel] is set to true to cancel a \"busy\" state\n * @return {boolean} true if \"busy\", false if not\n */\n isBusy(fCancel)\n {\n if (this.flags.busy) {\n if (fCancel) {\n this.flags.busyCancel = true;\n } else if (fCancel === undefined) {\n this.println(this.toString() + \" busy\");\n }\n }\n return this.flags.busy;\n }\n\n /**\n * setBusy(fBusy)\n *\n * Update the current busy state; if a busyCancel request is pending, it will be honored now.\n *\n * @this {Component}\n * @param {boolean} fBusy\n * @return {boolean}\n */\n setBusy(fBusy)\n {\n if (this.flags.busyCancel) {\n this.flags.busy = false;\n this.flags.busyCancel = false;\n return false;\n }\n if (this.flags.error) {\n this.println(this.toString() + \" error\");\n return false;\n }\n this.flags.busy = fBusy;\n return this.flags.busy;\n }\n\n /**\n * powerUp(fSave)\n *\n * @this {Component}\n * @param {Object|null} data\n * @param {boolean} [fRepower] is true if this is \"repower\" notification\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n this.flags.powered = true;\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {Component}\n * @param {boolean} fSave\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n if (fShutdown) this.flags.powered = false;\n return true;\n }\n\n /**\n * messageEnabled(bitsMessage)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n *\n * @this {Component}\n * @param {number} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n * @return {boolean} true if all specified message enabled, false if not\n */\n messageEnabled(bitsMessage = 0)\n {\n if (DEBUGGER && this.dbg) {\n if (this !== this.dbg) {\n bitsMessage = bitsMessage || this.bitsMessage;\n }\n var bitsEnabled = this.dbg.bitsMessage & bitsMessage;\n /*\n * This next \"bit\" of logic is for PCx86 and any other machine where we've expanded the set of\n * messages by reusing bits in the low nibbles in combination with different bits in the high nibble.\n * If the input bits adhere to that format, then the mask we just produced must adhere to it as well,\n * and if it doesn't, zero the mask, ensuring that the test will return false.\n */\n if ((bitsMessage & 0xf0000000) && (bitsMessage & 0x0fffffff)) {\n if (!(bitsEnabled & 0xf0000000) || !(bitsEnabled & 0x0fffffff)) bitsEnabled = 0;\n }\n if (bitsMessage && bitsEnabled === bitsMessage) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * printf(format, ...args)\n *\n * @this {Component}\n * @param {string} format\n * @param {...} args\n */\n printf(format, ...args)\n {\n if (DEBUGGER && this.dbg) {\n if (this.messageEnabled()) {\n let s = Str.sprintf(format, ...args);\n /*\n * Since dbg.message() calls println(), we strip any ending linefeed.\n * \n * We could bypass the Debugger and go straight to this.print(), but we would lose\n * the benefits of debugger messages (eg, automatic buffering, halting, yielding, etc).\n */\n if (s.slice(-1) == '\\n') s = s.slice(0, -1);\n this.dbg.message(s);\n }\n }\n }\n\n /**\n * printMessage(sMessage, bitsMessage, fAddress)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n * If bitsMessage is true, the message is displayed regardless.\n *\n * @this {Component}\n * @param {string} sMessage is any caller-defined message string\n * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n * @param {boolean} [fAddress] is true to display the current address\n */\n printMessage(sMessage, bitsMessage, fAddress)\n {\n if (DEBUGGER && this.dbg) {\n if (bitsMessage === true || this.messageEnabled(bitsMessage | 0)) {\n this.dbg.message(sMessage, fAddress);\n }\n }\n }\n\n /**\n * printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage)\n *\n * If bitsMessage is not specified, the component's MESSAGE category is used.\n * If bitsMessage is true, the message is displayed as long as MESSAGE.PORT is enabled.\n *\n * @this {Component}\n * @param {number} port\n * @param {number|null|*} bOut if an output operation\n * @param {number|null|*} [addrFrom]\n * @param {string|null|*} [name] of the port, if any\n * @param {number|null|*} [bIn] is the input value, if known, on an input operation\n * @param {number|boolean} [bitsMessage] is zero or more MESSAGE_* category flag(s)\n */\n printMessageIO(port, bOut, addrFrom, name, bIn, bitsMessage)\n {\n if (DEBUGGER && this.dbg) {\n if (bitsMessage === true) {\n bitsMessage = 0;\n } else if (bitsMessage == null) {\n bitsMessage = this.bitsMessage;\n }\n this.dbg.messageIO(this, port, bOut, addrFrom, name, bIn, bitsMessage);\n }\n }\n}\n\n/*\n * Types recognized and supported by selected functions (eg, Computer.getMachineParm())\n */\nComponent.TYPE = {\n NUMBER: \"number\",\n OBJECT: \"object\",\n STRING: \"string\"\n};\n\n/*\n * These are the standard PRINT values you can pass as an optional argument to println(); in reality,\n * you can pass anything you want, because they are simply prepended to the message, although PROGRESS\n * messages may also be merged with earlier similar messages to keep the output buffer under control.\n */\nComponent.PRINT = {\n ERROR: \"error\",\n NOTICE: \"notice\",\n PROGRESS: \"progress\",\n SCRIPT: \"script\",\n WARNING: \"warning\"\n};\n\n/*\n * Every component created on the current page is recorded in this array (see Component.add()),\n * enabling any component to locate another component by ID (see Component.getComponentByID())\n * or by type (see Component.getComponentByType()).\n *\n * Every machine on the page are now recorded as well, by their machine ID. We then record the\n * various resources used by that machine.\n *\n * Includes a fallback for non-browser-based environments (ie, Node). TODO: This will need to be\n * tailored to Node, probably using the global object instead of the window object, if we ever want\n * to support multi-machine configs in that environment.\n */\nif (window) {\n if (!window['PCjs']) window['PCjs'] = {};\n if (!window['PCjs']['Machines']) window['PCjs']['Machines'] = {};\n if (!window['PCjs']['Components']) window['PCjs']['Components'] = [];\n if (!window['PCjs']['Commands']) window['PCjs']['Commands'] = {};\n}\nComponent.machines = window? window['PCjs']['Machines'] : {};\nComponent.components = window? window['PCjs']['Components'] : [];\nComponent.commands = window? window['PCjs']['Commands'] : {};\n\nComponent.asyncCommands = [\n 'hold', 'sleep', 'wait'\n];\nComponent.globalCommands = {\n 'alert': Component.scriptAlert,\n 'sleep': Component.scriptSleep\n};\nComponent.componentCommands = {\n 'select': Component.scriptSelect\n};\nComponent.printBuffer = \"\";\n\n/*\n * The following polyfills provide ES5 functionality that's missing in older browsers (eg, IE8),\n * allowing PCjs apps to run without slamming into exceptions; however, due to the lack of HTML5 canvas\n * support in those browsers, all you're likely to see are \"soft\" errors (eg, \"Missing <canvas> support\").\n *\n * Perhaps we can implement a text-only faux video display for a fun retro-browser experience someday.\n *\n * TODO: Come up with a better place to put these polyfills. We will likely have more if we decide to\n * make the leap from ES5 to ES6 features.\n */\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf\n */\nif (!Array.prototype.indexOf) {\n Array.prototype.indexOf = function(obj, start) {\n for (var i = (start || 0), j = this.length; i < j; i++) {\n if (this[i] === obj) { return i; }\n }\n return -1;\n }\n}\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray\n */\nif (!Array.isArray) {\n Array.isArray = function(arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n };\n}\n\n/*\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind\n */\nif (!Function.prototype.bind) {\n Function.prototype.bind = function(obj) {\n if (typeof this != \"function\") {\n // Closest thing possible to the ECMAScript 5 internal IsCallable function\n throw new TypeError(\"Function.prototype.bind: non-callable object\");\n }\n var args = Array.prototype.slice.call(arguments, 1);\n var fToBind = this;\n var fnNOP = /** @constructor */ (function() {});\n var fnBound = function() {\n return fToBind.apply(this instanceof fnNOP && obj? this : obj, args.concat(/** @type {Array} */(Array.prototype.slice.call(arguments))));\n };\n fnNOP.prototype = this.prototype;\n fnBound.prototype = new fnNOP();\n return fnBound;\n };\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/defines.js (C) Jeff Parsons 2012-2018\n */\n\n/**\n * @define {string}\n */\nvar APPCLASS = \"pdp11\"; // this @define is the default application class (eg, \"pcx86\", \"c1pjs\")\n\n/**\n * APPNAME is used more for display purposes than anything else now. APPCLASS is what matters in terms\n * of folder and file names, CSS styles, etc.\n *\n * @define {string}\n */\nvar APPNAME = \"PDPjs\"; // this @define is the default application name (eg, \"PCx86\", \"C1Pjs\")\n\n/**\n * WARNING: DEBUGGER needs to accurately reflect whether or not the Debugger component is (or will be) loaded.\n * In the compiled case, we rely on the Closure Compiler to override DEBUGGER as appropriate. When it's *false*,\n * nearly all of debugger.js will be conditionally removed by the compiler, reducing it to little more than a\n * \"type skeleton\", which also solves some type-related warnings we would otherwise have if we tried to remove\n * debugger.js from the compilation process altogether.\n *\n * However, when we're in \"development mode\" and running uncompiled code in debugger-less configurations,\n * I would like to skip loading debugger.js altogether. When doing that, we must ALSO arrange for an additional file\n * (nodebugger.js) to be loaded immediately after this file, which *explicitly* overrides DEBUGGER with *false*.\n *\n * @define {boolean}\n */\nvar DEBUGGER = true; // this @define is overridden by the Closure Compiler to remove Debugger-related support\n\n/**\n * BYTEARRAYS is a Closure Compiler compile-time option that allocates an Array of numbers for every Memory block,\n * where each a number represents ONE byte; very wasteful, but potentially slightly faster.\n *\n * See the Memory component for details.\n *\n * @define {boolean}\n */\nvar BYTEARRAYS = false;\n\n/**\n * TYPEDARRAYS enables use of typed arrays for Memory blocks. This used to be a compile-time-only option, but I've\n * added Memory access functions for typed arrays (see MemoryPDP11.afnTypedArray), so support can be enabled dynamically now.\n *\n * See the Memory component for details.\n */\nvar TYPEDARRAYS = (typeof ArrayBuffer !== 'undefined');\n\n/**\n * MEMFAULT forces the Memory interfaces to signal a CPU fault when a word is accessed using an odd (unaligned) address.\n *\n * Since PDPjs inherited its Bus component from PCx86, it included support for both aligned and unaligned word accesses\n * by default. However, the PDP-11 adds a wrinkle: when an odd address is used to access a memory word, a BUS trap\n * must be generated. Note that odd IOPAGE word accesses are fine; this only affects the Memory component.\n *\n * When the MMU is enabled, these checks may also be performed at a higher level, eliminating the need for them at the\n * physical memory level.\n */\nvar MEMFAULT = true;\n\n/**\n * WORDBUS turns off support for unaligned memory words. Whereas MEMFAULT necessarily slows down memory word accesses\n * slightly, WORDBUS is able to speed them up slightly, by assuming that all word accesses (which didn't fault) must be\n * aligned. This affects all word accesses, even IOPAGE accesses, because it also eliminates cross-block boundary checks.\n *\n * Don't worry that the source code looks MORE complicated rather than LESS with the additional MEMFAULT and WORDBUS checks,\n * because the Closure Compiler eliminates those checks and throws away the (unreachable) code blocks that deal with unaligned\n * accesses.\n */\nvar WORDBUS = true;\n\n/*\n * Combine all the shared globals and machine-specific globals into one machine-specific global object,\n * which all machine components should start using; eg: \"if (PDP11.DEBUG) ...\" instead of \"if (DEBUG) ...\".\n */\nvar PDP11 = {\n APPCLASS: APPCLASS,\n APPNAME: APPNAME,\n APPVERSION: APPVERSION, // shared\n BYTEARRAYS: BYTEARRAYS,\n COMPILED: COMPILED, // shared\n CSSCLASS: CSSCLASS, // shared\n DEBUG: DEBUG, // shared\n DEBUGGER: DEBUGGER,\n MAXDEBUG: MAXDEBUG, // shared\n PRIVATE: PRIVATE, // shared\n TYPEDARRAYS:TYPEDARRAYS,\n MEMFAULT: MEMFAULT,\n WORDBUS: WORDBUS,\n SITEHOST: SITEHOST, // shared\n XMLVERSION: XMLVERSION, // shared\n\n /*\n * CPU model numbers (supported)\n *\n * The 11/20 includes the 11/10, which is not identified separately because there was\n * nothing functionally different about it.\n *\n * The 11/40 added the MODE bits to the PSW (but only KERNEL=00 and USER=11) and 18-bit\n * addressing via an MMU; there was still only one register set.\n *\n * The 11/45 added REGSET bit to the PSW (to support a second register set), SUPER=01\n * mode to the existing KERNEL=00 and USER=11 modes, separate I/D spaces, and other MMU\n * extensions (eg, MMR1 and MMR3).\n *\n * The 11/70 added 22-bit addressing and corresponding extensions to the MMU.\n */\n MODEL_1120: 1120,\n MODEL_1140: 1140,\n MODEL_1145: 1145,\n MODEL_1170: 1170,\n\n /*\n * This constant is used to mark points in the code where the physical address being returned\n * is invalid and should not be used.\n *\n * In a 32-bit CPU, -1 (ie, 0xffffffff) could actually be a valid address, so consider changing\n * ADDR_INVALID to NaN or null (which is also why all ADDR_INVALID tests should use strict equality\n * operators).\n *\n * The main reason I'm NOT using NaN or null now is my concern that, by mixing non-numbers\n * (specifically, values outside the range of signed 32-bit integers), performance may suffer.\n *\n * WARNING: Like many of the properties defined here, ADDR_INVALID is a common constant, which the\n * Closure Compiler will happily inline (with or without @const annotations; in fact, I've yet to\n * see a @const annotation EVER improve automatic inlining). However, if you don't make ABSOLUTELY\n * certain that this file is included BEFORE the first reference to any of these properties, that\n * automatic inlining will no longer occur.\n */\n ADDR_INVALID: -1,\n /*\n * Processor modes\n */\n MODE: {\n KERNEL: 0x0, // 11/40 and higher\n SUPER: 0x1, // 11/45 and higher\n UNUSED: 0x2,\n USER: 0x3, // 11/40 and higher\n MASK: 0x3\n },\n /*\n * Processor Status Word (stored in regPSW) at 177776\n */\n PSW: {\n CF: 0x0001, // bit 0 (000001) Carry Flag\n VF: 0x0002, // bit 1 (000002) Overflow Flag (aka OF on Intel processors)\n ZF: 0x0004, // bit 2 (000004) Zero Flag\n NF: 0x0008, // bit 3 (000010) Negative Flag (aka SF -- Sign Flag -- on Intel processors)\n TF: 0x0010, // bit 4 (000020) Trap Flag\n PRI: 0x00E0, // bits 5-7 (000340) Priority\n UNUSED: 0x0700, // bits 8-10 (003400) UNUSED\n /*\n * The REGSET bit (and the alternate register set stored in regsAlt) came into existence\n * with the 11/45; (ie, they were not present on the 11/10, 11/20, or 11/40).\n */\n REGSET: 0x0800, // bit 11 (004000) Register Set\n /*\n * The MODE bits came into existence with the 11/40 (eg, not present on the 11/10 or 11/20).\n */\n PMODE: 0x3000, // bits 12-13 (030000) Prev Mode (see PDP11.MODE)\n CMODE: 0xC000, // bits 14-15 (140000) Curr Mode (see PDP11.MODE)\n SHIFT: {\n CF: 0,\n VF: 1,\n ZF: 2,\n NF: 3,\n TF: 4,\n PRI: 5,\n PMODE: 12,\n CMODE: 14\n }\n },\n /*\n * Program Interrupt Register (stored in regPIR) at 177772\n *\n * The PIA bits at 5-7 are designed to align with PRI bits 5-7 in the PSW.\n */\n PIR: {\n BITS: 0xFE00, // bits 9-15 correspond to interrupt requests 1-7\n PIA: 0x00EE, // the PIA bits contain two copies of the corresponding interrupt request priority\n PIA_INC: 0x0022, // both sets of PIA bits can be incremented with this constant\n SHIFT: {\n BITS: 9\n }\n },\n /*\n * PDP-11 trap vectors\n */\n TRAP: {\n UNDEFINED: 0x00, // 000 (reserved)\n BUS: 0x04, // 004 unaligned address, non-existent memory, illegal instruction, etc\n RESERVED: 0x08, // 010 reserved instructions\n BPT: 0x0C, // 014 BPT: breakpoint trap (trace)\n IOT: 0x10, // 020 IOT: input/output trap\n PF: 0x14, // 024 power fail\n EMT: 0x18, // 030 EMT: emulator trap\n TRAP: 0x1C, // 034 TRAP instruction\n PIRQ: 0xA0, // 240 PIRQ: program interrupt request\n MMU: 0xA8 // 250 MMU: aborts and traps\n },\n /*\n * PDP-11 trap reasons; the reason may also be a non-negative address indicating a BUS memory error\n * (unaligned address or non-existent memory). Any reason >= RED (which includes BUS memory errors) generate\n * immediate (thrown) traps, as they are considered ABORTs; the rest generate synchronous traps.\n */\n REASON: {\n PANIC: -1, // immediate halt (internal error)\n ABORT: -2, // immediate MMU fault\n ILLEGAL: -3, // immediate invalid opcode (BUS)\n RED: -4, // immediate stack overflow fault (BUS)\n YELLOW: -5, // deferred stack overflow fault (BUS)\n FAULT: -6, // deferred MMU fault\n TRACE: -7, // deferred TF fault (BPT)\n HALT: -8, // illegal HALT (BUS)\n OPCODE: -9, // opcode-generated trap (eg, BPT, EMT, IOT, TRAP, or RESERVED opcode)\n INTERRUPT: -10, // device-generated trap (vector is device-specific)\n },\n REASONS: [\n \"UNKNOWN\",\n \"PANIC\",\n \"ABORT\",\n \"ILLEGAL\",\n \"RED\",\n \"YELLOW\",\n \"FAULT\",\n \"TRACE\",\n \"HALT\",\n \"OPCODE\",\n \"INTERRUPT\"\n ],\n /*\n * Assorted common opcodes\n */\n OPCODE: {\n HALT: 0x0000,\n WAIT: 0x0001,\n BPT: 0x0003,\n IOT: 0x0004,\n JSR_OP: 0x0800,\n JSR_MASK: 0xFE00,\n SOB_OP: 0x7E00,\n SOB_MASK: 0xFE00,\n EMT_OP: 0x8800,\n EMT_MASK: 0xFF00,\n TRAP_OP: 0x8900,\n TRAP_MASK: 0xFF00,\n INVALID: 0xFFFF // far from the only invalid opcode, just a KNOWN invalid opcode\n },\n /*\n * Internal operation state flags\n */\n OPFLAG: {\n IRQ_DELAY: 0x0001, // incremented until it becomes IRQ (set by SPL and traps)\n IRQ: 0x0002, // time to call checkInterrupts()\n IRQ_MASK: 0x0003,\n DEBUGGER: 0x0004, // set if the Debugger wants to perform checks\n WAIT: 0x0008, // WAIT operation in progress\n PRESERVE: 0x000F, // OPFLAG bits to preserve prior to the next instruction\n TRAP_TF: 0x0010, // aka PDP11.PSW.TF (WARNING: do not change this bit, or you will likely break opRTI())\n TRAP_SP: 0x0020, // set for a deferred BUS trap (due to a \"yellow\" stack overflow condition)\n TRAP_MMU: 0x0040,\n TRAP_MASK: 0x0070,\n TRAP_LAST: 0x0080, // set if last operation was a trap (see trapLast for the vector, and trapReason for the reason)\n TRAP_RED: 0x0100, // set whenever a RED trap occurs, used to catch double RED traps (time to PANIC)\n },\n /*\n * Opcode reg (opcode bits 2-0)\n */\n OPREG: {\n MASK: 0x07\n },\n /*\n * Opcode modes (opcode bits 5-3)\n */\n OPMODE: {\n REG: 0x00, // REGISTER (register is operand)\n REGD: 0x08, // REGISTER DEFERRED (register is address of operand)\n POSTINC: 0x10, // AUTO-INCREMENT (register is address of operand, register incremented)\n POSTINCD: 0x18, // AUTO-INCREMENT DEFERRED (register is address of address of operand, register incremented)\n PREDEC: 0x20, // AUTO-DECREMENT (register decremented, register is address of operand)\n PREDECD: 0x28, // AUTO-DECREMENT DEFERRED (register decremented, register is address of address of operand)\n INDEX: 0x30, // INDEX (register + next word is address of operand)\n INDEXD: 0x38, // INDEX DEFERRED (register + next word is address of address of operand)\n MASK: 0x38,\n SHIFT: 3\n },\n DSTMODE: {\n REG: 0x0007,\n MODE: 0x0038,\n MASK: 0x003F,\n SHIFT: 0\n },\n SRCMODE: {\n REG: 0x01C0,\n MODE: 0x0E00,\n MASK: 0x0FC0,\n SHIFT: 6\n },\n REG: {\n SP: 6,\n PC: 7,\n },\n /*\n * Internal memory access flags\n */\n ACCESS: {\n WORD: 0x00,\n BYTE: 0x01,\n READ: 0x02,\n WRITE: 0x04,\n UPDATE: 0x06,\n VIRT: 0x08, // getVirtualByMode() leaves bit 17 clear if this is set (otherwise the caller would have to clear it again)\n ISPACE: 0x00000,\n DSPACE: 0x10000 // getVirtualByMode() sets bit 17 in any 16-bit virtual address that refers to D space (as opposed to I space)\n },\n /*\n * Internal flags passed to writeDstByte()\n *\n * The BYTE and SBYTE values have been chosen so that they can be used directly as masks.\n */\n WRITE: {\n BYTE: 0xff, // write byte normally\n SBYTE: 0xffff // sign-extend byte to word\n },\n CPUERR: { // 177766\n RED: 0x0004, // 000004 red zone stack limit\n YELLOW: 0x0008, // 000010 yellow zone stack limit\n TIMEOUT: 0x0010, // 000020 UNIBUS timeout error\n NOMEMORY: 0x0020, // 000040 non-existent memory error\n ODDADDR: 0x0040, // 000100 odd word address error (as in non-even, not strange)\n BADHALT: 0x0080 // 000200 HALT attempted in USER or SUPER modes\n },\n MMR0: { // 177572\n ENABLED: 0x0001, // 000001 address relocation enabled\n PAGE_NUM: 0x000E, // 000016 page number of last fault\n PAGE_D: 0x0010, // 000020 last fault occurred in D space (11/45 and 11/70)\n PAGE: 0x001E, // 000176 (all of the PAGE bits)\n MODE: 0x0060, // 000140 processor mode as of last fault\n COMPLETED: 0x0080, // 000200 last instruction completed (R/O) (11/70)\n MAINT: 0x0100, // 000400 only destination mode references will be relocated\n MMU_TRAPS: 0x0200, // 001000 enable MMU traps (11/70)\n UNUSED: 0x0C00, // 006000\n TRAP_MMU: 0x1000, // 010000 trap: MMU (11/70)\n ABORT_RO: 0x2000, // 020000 abort: read-only\n ABORT_PL: 0x4000, // 040000 abort: page length\n ABORT_NR: 0x8000, // 100000 abort: non-resident\n ABORT: 0xE000, // 160000 (all of the ABORT bits)\n UPDATE: 0xF0FE, // Includes all of: ABORT, TRAP, COMPLETED, MODE, and PAGE bits\n SHIFT: {\n PAGE: 1,\n MODE: 5\n }\n },\n MMR1: { // 177574: general purpose auto-inc/auto-dec register (11/45 and 11/70)\n REG1_NUM: 0x0007, //\n REG1_DELTA: 0x00F8, //\n REG2_NUM: 0x0700, //\n REG2_DELTA: 0xF800 //\n },\n MMR2: { // 177576: virtual program counter register\n },\n MMR3: { // 172516: mapping register (11/45 and 11/70)\n USER_D: 0x0001, // (000001)\n SUPER_D: 0x0002, // (000002)\n KERNEL_D: 0x0004, // (000004)\n MMU_22BIT: 0x0010, // (000020)\n UNIBUS_MAP: 0x0020 // (000040) UNIBUS map relocation enabled\n },\n PDR: {\n ACF: {\n NR: 0x0, // non-resident, abort all accesses\n RO1: 0x1, // read-only, abort on write attempt, memory management trap on read (11/70)\n RO: 0x2, // read-only, abort on write attempt\n U1: 0x3, // unused, abort all accesses--reserved for future use\n RW1: 0x4, // read/write, memory management trap upon completion of a read or write\n RW2: 0x5, // read/write, memory management trap upon completion of a write (11/70)\n RW: 0x6, // read/write, no system trap/abort action\n U2: 0x7, // unused, abort all accesses--reserved for future use\n MASK: 0x7\n },\n ED: 0x0008, // expansion direction (if set, the page expands downward from block number 127)\n UNUSED: 0x0030,\n MODIFIED: 0x0040, // page has been written (bit cleared when either PDR or PAR is written)\n ACCESSED: 0x0080, // page has been accessed (bit cleared when either PDR or PAR is written) (11/70)\n PLF: 0x7F00, // page length field\n BC: 0x8000 // bypass cache (11/44 only)\n },\n /*\n * Assorted special (UNIBUS) addresses\n *\n * Within the PDP-11/45's 18-bit address space, of the 0x40000 possible addresses (256Kb), the top 0x2000\n * (8Kb) is called the IOPAGE and is reserved for CPU and I/O registers. The IOPAGE spans 0x3E000-0x3FFFF.\n *\n * Within the PDP-11/70's 22-bit address space, of the 0x400000 possible addresses (4Mb), the top 0x20000\n * (256Kb) is mapped to the UNIBUS (not physical memory), and as before, the top 0x2000 (8Kb) of that is\n * mapped to the IOPAGE.\n *\n * To map 18-bit UNIBUS addresses to 22-bit physical addresses, the 11/70 uses a UNIBUS relocation map.\n * It consists of 31 double-word registers that each hold a 22-bit base address. When UNIBUS relocation\n * is enabled, the top 5 bits of an address select one of the 31 mapping registers, and the bottom 13 bits\n * are then added to the contents of the selected mapping register.\n *\n * ES6 ALERT: By using octal constants, I'm finally dipping my toe into ES6 (aka ECMAScript 2015) waters.\n * You'll even see a few binary constants below, too. If you're loading this raw source code into your browser,\n * then by now (2016) you're almost certainly using an ES6-aware browser. Production sites should be using code\n * compiled by Google's Closure Compiler, which we configure to produce code that's backward-compatible with ES5\n * (for example, all binary, octal, and hex constants are converted to decimal values).\n *\n * For more details: https://github.com/google/closure-compiler/wiki/ECMAScript6\n */\n UNIBUS: { //16-bit 18-bit 22-bit Hex Description\n UNIMAP: 0o170200, // UNIBUS Mapping Registers (0-31) 64 words (ends at 0o170372)\n SIPDR0: 0o172200, // Supervisor I Page Descriptor Register 0\n SIPDR1: 0o172202, // Supervisor I Page Descriptor Register 1\n SIPDR2: 0o172204, // Supervisor I Page Descriptor Register 2\n SIPDR3: 0o172206, // Supervisor I Page Descriptor Register 3\n SIPDR4: 0o172210, // Supervisor I Page Descriptor Register 4\n SIPDR5: 0o172212, // Supervisor I Page Descriptor Register 5\n SIPDR6: 0o172214, // Supervisor I Page Descriptor Register 6\n SIPDR7: 0o172216, // Supervisor I Page Descriptor Register 7\n SDPDR0: 0o172220, // Supervisor D Page Descriptor Register 0\n SDPDR1: 0o172222, // Supervisor D Page Descriptor Register 1\n SDPDR2: 0o172224, // Supervisor D Page Descriptor Register 2\n SDPDR3: 0o172226, // Supervisor D Page Descriptor Register 3\n SDPDR4: 0o172230, // Supervisor D Page Descriptor Register 4\n SDPDR5: 0o172232, // Supervisor D Page Descriptor Register 5\n SDPDR6: 0o172234, // Supervisor D Page Descriptor Register 6\n SDPDR7: 0o172236, // Supervisor D Page Descriptor Register 7\n SIPAR0: 0o172240, // Supervisor I Page Address Register 0\n SIPAR1: 0o172242, // Supervisor I Page Address Register 1\n SIPAR2: 0o172244, // Supervisor I Page Address Register 2\n SIPAR3: 0o172246, // Supervisor I Page Address Register 3\n SIPAR4: 0o172250, // Supervisor I Page Address Register 4\n SIPAR5: 0o172252, // Supervisor I Page Address Register 5\n SIPAR6: 0o172254, // Supervisor I Page Address Register 6\n SIPAR7: 0o172256, // Supervisor I Page Address Register 7\n SDPAR0: 0o172260, // Supervisor D Page Address Register 0\n SDPAR1: 0o172262, // Supervisor D Page Address Register 1\n SDPAR2: 0o172264, // Supervisor D Page Address Register 2\n SDPAR3: 0o172266, // Supervisor D Page Address Register 3\n SDPAR4: 0o172270, // Supervisor D Page Address Register 4\n SDPAR5: 0o172272, // Supervisor D Page Address Register 5\n SDPAR6: 0o172274, // Supervisor D Page Address Register 6\n SDPAR7: 0o172276, // Supervisor D Page Address Register 7\n KIPDR0: 0o172300, // Kernel I Page Descriptor Register 0\n KIPDR1: 0o172302, // Kernel I Page Descriptor Register 1\n KIPDR2: 0o172304, // Kernel I Page Descriptor Register 2\n KIPDR3: 0o172306, // Kernel I Page Descriptor Register 3\n KIPDR4: 0o172310, // Kernel I Page Descriptor Register 4\n KIPDR5: 0o172312, // Kernel I Page Descriptor Register 5\n KIPDR6: 0o172314, // Kernel I Page Descriptor Register 6\n KIPDR7: 0o172316, // Kernel I Page Descriptor Register 7\n KDPDR0: 0o172320, // Kernel D Page Descriptor Register 0\n KDPDR1: 0o172322, // Kernel D Page Descriptor Register 1\n KDPDR2: 0o172324, // Kernel D Page Descriptor Register 2\n KDPDR3: 0o172326, // Kernel D Page Descriptor Register 3\n KDPDR4: 0o172330, // Kernel D Page Descriptor Register 4\n KDPDR5: 0o172332, // Kernel D Page Descriptor Register 5\n KDPDR6: 0o172334, // Kernel D Page Descriptor Register 6\n KDPDR7: 0o172336, // Kernel D Page Descriptor Register 7\n KIPAR0: 0o172340, // Kernel I Page Address Register 0\n KIPAR1: 0o172342, // Kernel I Page Address Register 1\n KIPAR2: 0o172344, // Kernel I Page Address Register 2\n KIPAR3: 0o172346, // Kernel I Page Address Register 3\n KIPAR4: 0o172350, // Kernel I Page Address Register 4\n KIPAR5: 0o172352, // Kernel I Page Address Register 5\n KIPAR6: 0o172354, // Kernel I Page Address Register 6\n KIPAR7: 0o172356, // Kernel I Page Address Register 7\n KDPAR0: 0o172360, // Kernel D Page Address Register 0\n KDPAR1: 0o172362, // Kernel D Page Address Register 1\n KDPAR2: 0o172364, // Kernel D Page Address Register 2\n KDPAR3: 0o172366, // Kernel D Page Address Register 3\n KDPAR4: 0o172370, // Kernel D Page Address Register 4\n KDPAR5: 0o172372, // Kernel D Page Address Register 5\n KDPAR6: 0o172374, // Kernel D Page Address Register 6\n KDPAR7: 0o172376, // Kernel D Page Address Register 7\n MMR3: 0o172516, // 772516 17772516\n RLCS: 0o174400, // RL11 Control Status Register\n RLBA: 0o174402, // RL11 Bus Address Register\n RLDA: 0o174404, // RL11 Disk Address Register\n RLMP: 0o174406, // RL11 Multi-Purpose Register\n RLBE: 0o174410, // RL11 Bus (Address) Extension Register (RLV12 controller only)\n DL11: 0o176500, // DL11 Additional Register Range (ends at 0o176676)\n RXCS: 0o177170, // RX11 Command and Status Register\n RXDB: 0o177172, // RX11 Data Buffer Register\n RKDS: 0o177400, // RK11 Drive Status Register\n RKER: 0o177402, // RK11 Error Register\n RKCS: 0o177404, // RK11 Control Status Register\n RKWC: 0o177406, // RK11 Word Count Register\n RKBA: 0o177410, // RK11 Bus Address Register\n RKDA: 0o177412, // RK11 Disk Address Register\n RKUN: 0o177414, // RK11 UNUSED (just to make it clear we didn't forget something)\n RKDB: 0o177416, // RK11 Data Buffer Register\n LKS: 0o177546, // KW11-L Clock Status\n PRS: 0o177550, // PC11 (and PR11) Reader Status Register\n PRB: 0o177552, // PC11 (and PR11) Reader Buffer Register\n PPS: 0o177554, // PC11 Punch Status Register\n PPB: 0o177556, // PC11 Punch Buffer Register\n RCSR: 0o177560, // DL11 Receiver Status Register\n RBUF: 0o177562, // DL11 Receiver Data Buffer Register\n XCSR: 0o177564, // DL11 Transmitter Status Register\n XBUF: 0o177566, // DL11 Transmitter Data Buffer Register\n CNSW: 0o177570, // Console (Front Panel) Switch/Display Register\n MMR0: 0o177572, // 777572 17777572\n MMR1: 0o177574, // 777574 17777574\n MMR2: 0o177576, // 777576 17777576\n UIPDR0: 0o177600, // User I Page Descriptor Register 0\n UIPDR1: 0o177602, // User I Page Descriptor Register 1\n UIPDR2: 0o177604, // User I Page Descriptor Register 2\n UIPDR3: 0o177606, // User I Page Descriptor Register 3\n UIPDR4: 0o177610, // User I Page Descriptor Register 4\n UIPDR5: 0o177612, // User I Page Descriptor Register 5\n UIPDR6: 0o177614, // User I Page Descriptor Register 6\n UIPDR7: 0o177616, // User I Page Descriptor Register 7\n UDPDR0: 0o177620, // User D Page Descriptor Register 0\n UDPDR1: 0o177622, // User D Page Descriptor Register 1\n UDPDR2: 0o177624, // User D Page Descriptor Register 2\n UDPDR3: 0o177626, // User D Page Descriptor Register 3\n UDPDR4: 0o177630, // User D Page Descriptor Register 4\n UDPDR5: 0o177632, // User D Page Descriptor Register 5\n UDPDR6: 0o177634, // User D Page Descriptor Register 6\n UDPDR7: 0o177636, // User D Page Descriptor Register 7\n UIPAR0: 0o177640, // User I Page Address Register 0\n UIPAR1: 0o177642, // User I Page Address Register 1\n UIPAR2: 0o177644, // User I Page Address Register 2\n UIPAR3: 0o177646, // User I Page Address Register 3\n UIPAR4: 0o177650, // User I Page Address Register 4\n UIPAR5: 0o177652, // User I Page Address Register 5\n UIPAR6: 0o177654, // User I Page Address Register 6\n UIPAR7: 0o177656, // User I Page Address Register 7\n UDPAR0: 0o177660, // User D Page Address Register 0\n UDPAR1: 0o177662, // User D Page Address Register 1\n UDPAR2: 0o177664, // User D Page Address Register 2\n UDPAR3: 0o177666, // User D Page Address Register 3\n UDPAR4: 0o177670, // User D Page Address Register 4\n UDPAR5: 0o177672, // User D Page Address Register 5\n UDPAR6: 0o177674, // User D Page Address Register 6\n UDPAR7: 0o177676, // User D Page Address Register 7\n R0SET0: 0o177700, //\n R1SET0: 0o177701, //\n R2SET0: 0o177702, //\n R3SET0: 0o177703, //\n R4SET0: 0o177704, //\n R5SET0: 0o177705, //\n R6KERNEL: 0o177706, //\n R7KERNEL: 0o177707, //\n R0SET1: 0o177710, //\n R1SET1: 0o177711, //\n R2SET1: 0o177712, //\n R3SET1: 0o177713, //\n R4SET1: 0o177714, //\n R5SET1: 0o177715, //\n R6SUPER: 0o177716, //\n R6USER: 0o177717, //\n /*\n * This next group of registers is largely ignored; all accesses are routed to regsControl[],\n * and therefore are managed as a block of 8 \"CTRL\" registers.\n */\n CTRL: 0o177740,\n LAERR: 0o177740, // Low Address Error (11/70 only)\n HAERR: 0o177742, // High Address Error (11/70 only)\n MEMERR: 0o177744, // Memory System Error (11/70 only)\n CACHEC: 0o177746, // Cache Control (11/70 only)\n MAINT: 0o177750, // Maintenance (11/70 only)\n HITMISS: 0o177752, // Hit/Miss (11/70 only)\n UNDEF1: 0o177754, //\n UNDEF2: 0o177756, //\n LSIZE: 0o177760, // Lower Size Register (last 64-byte block #) (11/70 only)\n HSIZE: 0o177762, // Upper Size Register (always zero) (11/70 only)\n SYSID: 0o177764, // System ID Register (11/70 only)\n CPUERR: 0o177766, // CPU error (11/70 only)\n MB: 0o177770, // Microprogram break (11/70 only)\n PIR: 0o177772, // Program Interrupt Request\n SL: 0o177774, // Stack Limit Register\n PSW: 0o177776 // 777776 17777776 0x3FFFFE Processor Status Word\n },\n DL11: { // Serial Line Interface (program compatible with the KL11 for control of console teleprinters)\n PRI: 4,\n RVEC: 0o060,\n XVEC: 0o064,\n RCSR: { // 177560: DL11 Receiver Status Register\n RE: 0x0001, // Reader Enable (W/O)\n DTR: 0x0002, // Data Terminal Ready (R/W)\n RTS: 0x0004, // Request To Send (R/W)\n STD: 0x0008, // Secondary Transmitted Data (R/W)\n DIE: 0x0020, // Dataset Interrupt Enable (R/W)\n RIE: 0x0040, // Receiver Interrupt Enable (R/W)\n RD: 0x0080, // Receiver Done (R/O)\n SRD: 0x0400, // Secondary Received Data (R/O)\n RA: 0x0800, // Receiver Active (R/O)\n CD: 0x1000, // Carrier Detect (R/O)\n CTS: 0x2000, // Clear To Send (R/O)\n RI: 0x4000, // Ring Indicator (R/O)\n DSC: 0x8000, // Dataset Status Change (R/O)\n RMASK: 0xFFFE, // bits readable (TODO: All I know for sure is that bit 0 is NOT readable; see readRCSR())\n WMASK: 0x006F, // bits writable\n RS232: 0x0006, // bits affecting RS-232 status updates\n BAUD: 9600\n },\n RBUF: { // 177562: DL11 Receiver Data Buffer Register\n DATA: 0x00ff, // Received Data (R/O)\n PARITY: 0x1000, // Received Data Parity (R/O)\n FE: 0x2000, // Framing Error (R/O)\n OE: 0x4000, // Overrun Error (R/O)\n ERROR: 0x8000 // Error (R/O)\n },\n XCSR: { // 177564: DL11 Transmitter Status Register\n BREAK: 0x0001, // BREAK (R/W)\n MAINT: 0x0004, // Maintenance (R/W)\n TIE: 0x0040, // Transmitter Interrupt Enable (R/W)\n READY: 0x0080, // Transmitter Ready (R/O)\n RMASK: 0x00C5,\n WMASK: 0x0045,\n BAUD: 9600\n },\n XBUF: { // 177566: DL11 Transmitter Data Buffer Register\n DATA: 0x00FF // Transmitted Data (W/O) (TODO: Determine why pdp11.js effectively defined this as 0x7F)\n }\n },\n KW11: { // KW11-L Line Time Clock (60Hz; well, OK, or 50Hz, if you're in the UK, I suppose...)\n PRI: 6,\n VEC: 0o100,\n DELAY: 0,\n LKS: { // 177546: KW11-L Clock Status\n IE: 0x0040, // Interrupt Enable\n MON: 0x0080, // Monitor\n MASK: 0x00C0 // these are the only bits that can read or written\n }\n },\n PC11: { // High Speed Reader & Punch (PR11 is a Reader-only unit)\n PRI: 4, // NOTE: reader has precedence over punch\n RVEC: 0o070, // reader vector\n PVEC: 0o074, // punch vector\n PRS: { // 177550: PC11 (and PR11) Reader Status Register\n RE: 0x0001, // (000001) Reader Enable (W/O)\n IE: 0x0040, // (000100) Reader Interrupt Enable (allows the DONE and ERROR bits to trigger an interrupt)\n DONE: 0x0080, // (000200) Done (R/O)\n BUSY: 0x0800, // (004000) Busy (R/O)\n ERROR: 0x8000, // (100000) Error (R/O)\n CLEAR: 0x08C0, // (004300) bits cleared on INIT\n RMASK: 0xFFFE, // (177776) bits readable (TODO: All I know for sure is that bit 0 is NOT readable; see readPRS())\n WMASK: 0x0041, // (000101) bits writable\n BAUD: 3600\n },\n PRB: { // 177552: PC11 (and PR11) Reader Buffer Register\n MASK: 0x00FF // Data\n },\n PPS: { // 177554: PC11 Punch Status Register\n IE: 0x0040, // Interrupt Enable\n RDY: 0x0080, // Ready\n ERROR: 0x8000, // Error (eg, no tape in punch, or punch has no power)\n WMASK: 0x0040, // bits writable\n BAUD: 600\n },\n PPB: { // 177556: PC11 Punch Buffer Register\n MASK: 0x00FF // Data\n }\n },\n RK11: { // RK11 Disk Controller\n PRI: 5,\n VEC: 0o220,\n DRIVES: 8, // maximum of 8 drives\n RKDS: { // 177400: Drive Status Register\n SC: 0x000F, // (000017) Sector Counter\n SCESA: 0x0010, // (000020) Sector Counter Equals Sector Address\n WPS: 0x0020, // (000040) Write Protected Status (set if write-protected)\n RRDY: 0x0040, // (000100) Read/Write/Seek Ready\n DRDY: 0x0080, // (000200) Drive Ready\n SOK: 0x0100, // (000400) Sector Counter OK\n SIN: 0x0200, // (001000) Seek Incomplete\n DRU: 0x0400, // (002000) Drive Unsafe\n RK05: 0x0800, // (004000) RK05 is the selected disk drive (always set)\n DPL: 0x1000, // (010000) Drive Power Low\n ID: 0xE000, // (160000) Drive ID (logical drive number of an interrupting drive)\n SHIFT: {\n ID: 13\n }\n },\n RKER: { // 177402: Error Register\n WCE: 0x0001, // Write Check Error\n CSE: 0x0002, // Checksum Error\n SE: 0x0003, // Soft Error bits (cleared at the start of a new function)\n UNUSED: 0x001C, // unused (returns zero)\n NXS: 0x0020, // Non-Existent Sector\n NXC: 0x0040, // Non-Existent Cylinder\n NXD: 0x0080, // Non-Existent Disk\n TE: 0x0100, // Timing Error\n DLT: 0x0200, // Date Late\n NXM: 0x0400, // Non-Existent Memory\n PGE: 0x0800, // Programming Error\n SKE: 0x1000, // Seek Error\n WLO: 0x2000, // Write Lock-Out Violation\n OVR: 0x4000, // Overrun\n DRE: 0x8000, // Drive Error\n HE: 0x7FE0 // Hard Error bits (cleared only by Bus RESET or RK11 CRESET function)\n },\n RKCS: { // 177404: Control Status Register\n GO: 0x0001, // (000001) Go (W/O)\n FUNC: 0x000E, // (000016) Function Code (F2,F1,F0) (R/W)\n MEX: 0x0030, // (000060) Memory Extension (R/W)\n IE: 0x0040, // (000100) Interrupt Enable (R/W)\n CRDY: 0x0080, // (000200) Controller Ready (R/O)\n SSE: 0x0100, // (000400) Stop on Soft Error (R/W)\n EXB: 0x0200, // (001000) Extra Bit (R/W)\n FMT: 0x0400, // (002000) Format (R/W)\n IBA: 0x0800, // (004000) Inhibit RKBA Increment (R/W)\n SCP: 0x2000, // (020000) Search Complete (R/O)\n HE: 0x4000, // (040000) Hard Error (R/O)\n ERR: 0x8000, // (100000) Composite Error (R/O) (set when any RKER bit is set)\n UNUSED: 0x1200, // (011000) unused\n RMASK: 0xEFFE, // (167776) bits readable\n WMASK: 0x0F7F, // (007577) bits writable\n SHIFT: {\n FUNC: 1,\n MEX: 4\n }\n },\n RKDA: { // 177412: Disk Address Register\n SA: 0x000F, // (000017) Sector Address\n HS: 0x0010, // (000020) Head Select (aka SUR: clear for upper disk head, set for lower)\n CA: 0x1FE0, // (017740) Cylinder Address (aka CYL ADDR)\n DS: 0xE000, // (160000) Drive Select (aka DR SEL)\n SHIFT: {\n HS: 4,\n CA: 5,\n DS: 13\n }\n },\n FUNC: {\n CRESET: 0b0000, // (00) Controller Reset\n WRITE: 0b0010, // (02) Write\n READ: 0b0100, // (04) Read\n WCHK: 0b0110, // (06) Write Check\n SEEK: 0b1000, // (10) Seek\n RCHK: 0b1010, // (12) Read Check\n DRESET: 0b1100, // (14) Drive Reset\n WLOCK: 0b1110 // (16) Write Lock\n }\n },\n RL11: { // RL11 Disk Controller\n PRI: 5,\n VEC: 0o160,\n DRIVES: 4, // maximum of 4 drives\n PREFIX: \"DY\",\n RLCS: { // 174400: Control Status Register\n DRDY: 0x0001, // (000001) Drive Ready (R/O)\n FUNC: 0x000E, // (000016) Function Code (F2,F1,F0) (R/W)\n BAE: 0x0030, // (000060) Bus Address Extension bits (BA17,BA16) (R/W)\n IE: 0x0040, // (000100) Interrupt Enable (R/W)\n CRDY: 0x0080, // (000200) Controller Ready (R/W)\n DS: 0x0300, // (001400) Drive Select (DS1,DS0) (R/W)\n ERRC: 0x3C00, // (036000) Error Code (R/O)\n DE: 0x4000, // (040000) Drive Error (R/O)\n ERR: 0x8000, // (100000) Composite Error (R/O)\n CLEAR: 0x3F7E, // (037576) bits cleared on INIT (bits 1-6 and 8-13 are cleared)\n SET: 0x0080, // (000200) bits set on INIT (bit 7 is set)\n RMASK: 0xFFFF, // (177777) no write-only bits\n WMASK: 0x03FE, // (001776) bits writable\n SHIFT: {\n FUNC: 1,\n BAE: 4,\n DS: 8\n }\n },\n RLBA: { // 174402: Bus Address Register\n WMASK: 0xFFFE // bit 0 is effectively not writable (always zero)\n },\n /*\n * This register has 3 formats: one for Seek, another for Read/Write, and a third for Get Status\n */\n RLDA: { // 174404: Disk Address Register\n SEEK_CMD: 0x0001, // Seek: bit 0 must be set, bits 1 and 3 must be clear\n SEEK_DIR: 0x0004, // Direction (clear to move heads away from spindle (lower cylinder), set to move to higher cylinder)\n SEEK_HS: 0x0010, // Head Select (clear to select upper head, set to select lower head)\n SEEK_CAD: 0xFF80, // Cylinder Address Difference\n RW_SA: 0x003F, // Sector Address\n RW_HS: 0x0040, // Head Select\n RW_CA: 0xFF80, // Cylinder Address (RL01 has 256 cylinders, RL02 has 512)\n GS_CMD: 0x0003, // Get Status: bit 0 must be set, bit 1 set, and bits 2 and 4-7 clear (bits 8-15 unused)\n GS_RST: 0x0008, // Reset (when set, clears error register before sending status word to controller)\n SHIFT: {\n RW_HS: 6,\n RW_CA: 7\n }\n },\n /*\n * This register has 3 formats: one for Read Header, another for Read/Write, and a third for Get Status\n */\n RLMP: { // 177406: Multi-Purpose Register\n GS_ST: { // Major State Code (of the drive)\n LOADC: 0x0, // Load Cartridge\n SPINUP: 0x1, // Spin-Up\n BRUSHC: 0x2, // Brush Cycle\n LOADH: 0x3, // Load Heads\n SEEK: 0x4, // Seek\n LOCKON: 0x5, // Lock On\n UNLOADH:0x6, // Unload Heads\n SPINDN: 0x7 // Spin-Down\n },\n GS_BH: 0x0008, // Brushes Home\n GS_HO: 0x0010, // Heads Out\n GS_CO: 0x0020, // Cover Open (or dust cover is not in place)\n GS_HS: 0x0040, // Head Selected (0 for upper head, 1 for lower head)\n GS_DT: 0x0080, // Drive Type (0 for RL01, 1 for RL02)\n GS_DSE: 0x0100, // Drive Select Error\n GS_VC: 0x0200, // Volume Check (Set during transition from a head load state to a head-on-track state; cleared by execution of a Get Status command with Bit 3 asserted)\n GS_WGE: 0x0400, // Write Gate Error\n GS_SPE: 0x0800, // Spin Error\n GS_SKTO: 0x1000, // Seek Time-Out\n GS_WL: 0x2000, // Write Lock\n GS_CHE: 0x4000, // Current Head Error\n GS_WDE: 0x8000 // Write Data Error\n },\n RLBE: { // 174410: Bus (Address) Extension Register\n MASK: 0x003F // bits 5-0 correspond to bus address bits 21-16\n },\n ERRC: { // NOTE: These error codes are pre-shifted to read/write directly from/to RLCS.ERRC\n OPI: 0x0400, // Operation Incomplete\n DCRC: 0x0800, // Read Data CRC\n WCE: 0x0800, // Write Check Error\n HCRC: 0x0C00, // Header CRC\n DLT: 0x1000, // Data Late\n HNF: 0x1400, // Header Not Found\n NXM: 0x2000, // Non-Existent Memory\n MPE: 0x2400 // Memory Parity Error (RLV12 only)\n },\n FUNC: { // NOTE: These function codes are pre-shifted to read/write directly from/to RLCS.FUNC\n NOP: 0b0000, // (00) No-Op\n WCHK: 0b0010, // (02) Write Check\n STATUS: 0b0100, // (04) Get Status\n SEEK: 0b0110, // (06) Seek\n RHDR: 0b1000, // (10) Read Header\n WDATA: 0b1010, // (12) Write Data\n RDATA: 0b1100, // (14) Read Data\n RDNC: 0b1110 // (16) Read Data without Header Check\n }\n },\n RX11: { // RX11 Disk Controller\n PRI: 5,\n VEC: 0o264,\n DRIVES: 2, // maximum of 2 drives\n PREFIX: \"DX\",\n RXCS: { // 177170: Command and Status Register\n GO: 0x0001, // (000001) Go (W/O)\n FUNC: 0x000E, // (000016) Function Code (F2,F1,F0) (W/O)\n UNIT: 0x0010, // (000020) Unit Select (W/O)\n DONE: 0x0020, // (000040) Done (R/O)\n IE: 0x0040, // (000100) Interrupt Enable (R/W, cleared on INIT)\n TR: 0x0080, // (000200) Transfer Request (R/O)\n INIT: 0x4000, // (040000) RX11 Initialize (W/O)\n ERR: 0x8000, // (100000) Error (R/O, cleared on INIT or command)\n UNUSED: 0x3F00, // (037400) unused\n RMASK: 0x80E0, // (100340) bits readable\n WMASK: 0x405F // (040137) bits writable\n },\n RXDB: { // 177172: Data Buffer Register\n },\n RXTA: {\n MASK: 0x007F\n },\n RXSA: {\n MASK: 0x001F\n },\n RXES: {\n /*\n * The DRDY bit is only valid when retrieved via a Read Status function or at completion of Initialize when it indicates\n * status of drive O. It is asserted if the unit currently selected exists, is properly supplied with power, has a diskette\n * installed correctly, has its door closed, and has a diskette up to speed.\n *\n * If the Error bit was set in the RXCS but Error bits are not set in the RXES, then specific error conditions can be accessed via\n * a Read Error Register function.\n */\n CRC: 0x0001, // CRC error (RXES is moved to the RXDB, and Error and Done are asserted)\n PARITY: 0x0002, // parity error (RXES is moved to the RXDB, and Error and Done are asserted)\n ID: 0x0004, // Initialize Done (following a programmable or UNIBUS initialization, or a power failure)\n DEL: 0x0040, // Deleted Data Detected\n DRDY: 0x0080 // Drive Ready\n },\n FUNC: { // NOTE: These function codes are pre-shifted to read/write directly from/to RXCS.FUNC\n FILL: 0b0000, // Fill Buffer\n EMPTY: 0b0010, // Empty Buffer\n WRITE: 0b0100, // Write Sector\n READ: 0b0110, // Read Sector\n UNUSED: 0b1000, // UNUSED\n RDSTAT: 0b1010, // Read Status\n WRDEL: 0b1100, // Write Deleted Data Sector\n RDERR: 0b1110 // Read Error Register\n },\n ERROR: {\n HOME0: 0o0010, // Drive 0 failed to see home on Initialize\n HOME1: 0o0020, // Drive 1 failed to see home on Initialize\n BAD_HOME: 0o0030, // Found home when stepping out 10 tracks for INIT\n NO_TRACK: 0o0040, // Tried to access a track greater than 77\n FOUND_HOME: 0o0050, // Home was found before desired track was reached\n SELF_DIAG: 0o0060, // Self-diagnostic error\n NO_SECTOR: 0o0070, // Desired sector could not be found after looking at 52 headers (2 revolutions)\n NO_SEP: 0o0110, // More than 40us and no SEP clock seen\n NO_PREAM: 0o0120, // A preamble could not be found\n NO_IOMARK: 0o0130, // Preamble found but no I/O mark found within allowable time span\n CRC_HEADER: 0o0140, // CRC error on what we thought was a header\n BAD_TRACK: 0o0150, // The header track address of a good header does not compare with the desired track\n NO_ID: 0o0160, // Too many tries for an IDAM (identifies header)\n NO_DATA: 0o0170, // Data AM not found in allotted time\n CRC_DATA: 0o0200, // CRC error on reading the sector from the disk (No code appears in the ERREG).\n BAD_PARITY: 0o0210 // All parity errors\n }\n },\n VECTORS: {\n 0o060: \"DL11R\",\n 0o064: \"DL11X\",\n 0o070: \"PC11R\",\n 0o074: \"PC11X\",\n 0o100: \"KW11\",\n 0o160: \"RL11\",\n 0o220: \"RK11\",\n 0o264: \"RX11\"\n }\n};\n\nPDP11.RX11.RX01 = [\n \"DX\",\n 77, 1, 26, 128, // disk geometry (CHSN: cylinders, heads, sectors/track, and bytes/sector)\n 1, 0, 0, 128, // boot code location (cylinder, head, sector index (NOT sector number), and number of bytes)\n 0 // default drive status\n];\n\nPDP11.RK11.RK05 = [\n \"RK\",\n 203, 2, 12, 512, // disk geometry (CHSN: cylinders, heads, sectors/track, and bytes/sector)\n 0, 0, 0, 512, // boot code location (cylinder, head, sector index (NOT sector number), and number of bytes)\n PDP11.RK11.RKDS.RK05 | PDP11.RK11.RKDS.SOK | PDP11.RK11.RKDS.RRDY\n];\n\nPDP11.RL11.RL02K = [\n \"RL\",\n 512, 2, 40, 256, // disk geometry (CHSN: cylinders, heads, sectors/track, and bytes/sector)\n 0, 0, 0, 256, // boot code location (cylinder, head, sector index (NOT sector number), and number of bytes)\n PDP11.RL11.RLMP.GS_ST.LOCKON | PDP11.RL11.RLMP.GS_BH | PDP11.RL11.RLMP.GS_HO\n];\n\nPDP11.ACCESS.READ_WORD = PDP11.ACCESS.WORD | PDP11.ACCESS.READ; // formerly READ_MODE (2)\nPDP11.ACCESS.READ_BYTE = PDP11.ACCESS.BYTE | PDP11.ACCESS.READ; // formerly READ_MODE (2) | BYTE_MODE (1)\nPDP11.ACCESS.WRITE_WORD = PDP11.ACCESS.WORD | PDP11.ACCESS.WRITE; // formerly WRITE_MODE (4)\nPDP11.ACCESS.WRITE_BYTE = PDP11.ACCESS.BYTE | PDP11.ACCESS.WRITE; // formerly WRITE_MODE (4) | BYTE_MODE (1)\nPDP11.ACCESS.UPDATE_WORD = PDP11.ACCESS.WORD | PDP11.ACCESS.UPDATE; // formerly MODIFY_WORD (2 | 4)\nPDP11.ACCESS.UPDATE_BYTE = PDP11.ACCESS.BYTE | PDP11.ACCESS.UPDATE; // formerly MODIFY_BYTE (1 | 2 | 4)\n\n/*\n * PSW arithmetic flags are NOT stored directly into the PSW register; they are maintained across separate flag registers.\n */\nPDP11.PSW.FLAGS = (PDP11.PSW.NF | PDP11.PSW.ZF | PDP11.PSW.VF | PDP11.PSW.CF);\n\n/*\n * Combine all the shared globals and machine-specific globals into one machine-specific global object,\n * which all machine components should start using; eg: \"if (PDP11.DEBUGGER)\" instead of \"if (DEBUGGER)\".\n */\nPDP11.APPCLASS = APPCLASS;\nPDP11.APPNAME = APPNAME;\nPDP11.DEBUGGER = DEBUGGER;\nPDP11.BYTEARRAYS = BYTEARRAYS;\nPDP11.TYPEDARRAYS = TYPEDARRAYS;\nPDP11.MEMFAULT = MEMFAULT;\nPDP11.WORDBUS = WORDBUS;\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/messages.js (C) Jeff Parsons 2012-2018\n */\n\nvar MessagesPDP11 = {\n CPU: 0x00000001,\n TRAP: 0x00000002,\n FAULT: 0x00000004,\n INT: 0x00000008,\n BUS: 0x00000010,\n MEMORY: 0x00000020,\n MMU: 0x00000040,\n ROM: 0x00000080,\n DEVICE: 0x00000100,\n PANEL: 0x00000200,\n KEYBOARD: 0x00000400,\n KEYS: 0x00000800,\n PC11: 0x00001000,\n PAPER: 0x00001000,\n DISK: 0x00002000,\n READ: 0x00004000,\n WRITE: 0x00008000,\n RK11: 0x00010000,\n RL11: 0x00020000,\n RX11: 0x00040000,\n DL11: 0x00100000,\n SERIAL: 0x00100000,\n KW11: 0x00200000,\n TIMER: 0x00200000,\n SPEAKER: 0x01000000,\n COMPUTER: 0x02000000,\n BUFFER: 0x20000000,\n WARN: 0x40000000,\n HALT: 0x80000000|0\n};\n\n/*\n * Message categories supported by the messageEnabled() function and other assorted message\n * functions. Each category has a corresponding bit value that can be combined (ie, OR'ed) as\n * needed. The Debugger's message command (\"m\") is used to turn message categories on and off,\n * like so:\n *\n * m port on\n * m port off\n * ...\n *\n * NOTE: The order of these categories can be rearranged, alphabetized, etc, as desired; just be\n * aware that changing the bit values could break saved Debugger states (not a huge concern, just\n * something to be aware of).\n */\nMessagesPDP11.CATEGORIES = {\n \"cpu\": MessagesPDP11.CPU,\n \"trap\": MessagesPDP11.TRAP,\n \"fault\": MessagesPDP11.FAULT,\n \"int\": MessagesPDP11.INT,\n \"bus\": MessagesPDP11.BUS,\n \"memory\": MessagesPDP11.MEMORY,\n \"mmu\": MessagesPDP11.MMU,\n \"rom\": MessagesPDP11.ROM,\n \"device\": MessagesPDP11.DEVICE,\n \"panel\": MessagesPDP11.PANEL,\n \"keyboard\": MessagesPDP11.KEYBOARD, // \"kbd\" is also allowed as shorthand for \"keyboard\"; see doMessages()\n \"key\": MessagesPDP11.KEYS, // using \"key\" instead of \"keys\", since the latter is a method on JavasScript objects\n \"pc11\": MessagesPDP11.PC11,\n \"paper\": MessagesPDP11.PAPER,\n \"disk\": MessagesPDP11.DISK,\n \"read\": MessagesPDP11.READ,\n \"write\": MessagesPDP11.WRITE,\n \"rk11\": MessagesPDP11.RK11,\n \"rl11\": MessagesPDP11.RL11,\n \"rx11\": MessagesPDP11.RX11,\n \"dl11\": MessagesPDP11.DL11,\n \"serial\": MessagesPDP11.SERIAL,\n \"kw11\": MessagesPDP11.KW11,\n \"timer\": MessagesPDP11.TIMER,\n \"speaker\": MessagesPDP11.SPEAKER,\n \"computer\": MessagesPDP11.COMPUTER,\n /*\n * Now we turn to message actions rather than message types; for example, setting \"halt\"\n * on or off doesn't enable \"halt\" messages, but rather halts the CPU on any message above.\n *\n * Similarly, \"m buffer on\" turns on message buffering, deferring the display of all messages\n * until \"m buffer off\" is issued.\n */\n \"buffer\": MessagesPDP11.BUFFER,\n \"warn\": MessagesPDP11.WARN,\n \"halt\": MessagesPDP11.HALT\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/panel.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * Component class, because otherwise the Compiler won't allow us to *reference* the named\n * property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass PanelPDP11 extends Component {\n /**\n * PanelPDP11(parmsPanel)\n *\n * The PanelPDP11 component has no required (parmsPanel) properties.\n *\n * @param {Object} parmsPanel\n * @param {boolean} fBindings (true if panel may have bindings, otherwise not)\n */\n constructor(parmsPanel, fBindings)\n {\n super(\"Panel\", parmsPanel, MessagesPDP11.PANEL);\n\n /*\n * If there are any live registers, LEDs, etc, to display, this will provide a count.\n * TODO: Add some UI for fDisplayLiveRegs (either an XML property, or a UI checkbox, or both).\n */\n this.cLiveRegs = 0;\n this.nDisplayCount = 0;\n this.nDisplayLimit = 60;\n this.fDisplayLiveRegs = true;\n this.fBindings = fBindings;\n\n /*\n * regSwitches contains the Front Panel (aka Console) SWITCH register, which is also available\n * as a read-only register at 177570 (but only the low 16 bits). regDisplay contains the DISPLAY\n * register, a write-only register at the same address.\n *\n * regAddr is an internal register containing the contents of the Front Panel's ADDRESS display,\n * and regData corresponds to the DATA display. They are updated by updateAddr() and updateData(),\n * which in turn take care of calling updateLEDArray().\n *\n * The state of ALL switches is maintained in this.switches, and likewise all LED states are\n * maintained in this.leds, but for convenience, we also mirror some of those states in dedicated\n * variables (eg, regSwitches for the SWITCH register, fLEDTest for the 'TEST' switch, etc).\n */\n this.regDisplay = 0;\n this.regSwitches = 0;\n this.regAddr = this.regData = 0;\n this.ledAddr = this.ledData = -1;\n\n /*\n * The panel hardware has the following additional (supported) state; note that there are several\n * settings on a real Front Panel that we don't support (eg, stepping one cycle vs. one instruction).\n *\n * While my initial intent is to eventually support all the ADDRSEL switch settings, I probably\n * won't bother with any DATASEL switch settings; instead, I will automatically display the DISPLAY\n * register (regDisplay) [the equivalent of selecting 'DISPLAY REGISTER'] except when data is being\n * examined or deposited [the equivalent of selecting 'DATA PATHS'].\n */\n this.fLEDTest = false; // LED (lamp) test in progress\n this.fAutoInc = false; // true if the next 'DEP' or 'EXAM' should auto-increment\n this.nAddrSel = PanelPDP11.ADDRSEL.CONS_PHY;\n\n /*\n * Every LED has a simple numeric value, assigned when setBinding() is called:\n *\n * zero if \"off\", non-zero if \"on\"\n *\n * initBus() will call displayLEDs() to ensure that every LED is set to its initial value.\n */\n this.leds = {};\n\n /*\n * Every switch has an array associated with it:\n *\n * [0]: initial value of switch (0 if \"down\", 1 if \"up\")\n * [1]: current value of switch\n * [2]: true if the switch is momentary, false if not\n * [3]: true if the switch is currently pressed, false if released\n * [4]: optional handler to call whenever the switch is pressed or released\n * [5]: optional switch index (used with CNSW switches 'S0' through 'S21')\n *\n * initBus() will call displaySwitches() to ensure that every switch is the position represented below.\n *\n * NOTE: Not all switches have the same \"process\" criteria. For example, 'TEST' will perform a LED test\n * when it is momentarily pressed \"up\", whereas 'LOAD [ADRS]' will load the ADDRESS register from the\n * SWITCH register when it is momentarily pressed \"down\".\n *\n * This means that processLEDTest(value) must act when value == 1 (\"up\"), whereas processLoadAddr(value)\n * must act when value == 0 (\"down\"). You can infer all this from the table below, because the initial value\n * of any momentary switch is its \"inactive\" value, so the opposite is its \"active\" value.\n */\n this.switches = {\n 'START': [1, 1, true, false, this.processStart],\n 'STEP': [1, 1, false, false, this.processStep],\n 'ENABLE': [1, 1, false, false, this.processEnable],\n 'CONT': [1, 1, true, false, this.processContinue],\n 'DEP': [0, 0, true, false, this.processDeposit],\n 'EXAM': [1, 1, true, false, this.processExamine],\n 'LOAD': [1, 1, true, false, this.processLoadAddr],\n 'TEST': [0, 0, true, false, this.processLEDTest]\n };\n for (var i = 0; i < 22; i++) {\n this.switches['S'+i] = [0, 0, false, false, this.processSRSwitch, i];\n }\n\n /** @type {ComputerPDP11} */\n this.cmp = null;\n\n /** @type {BusPDP11} */\n this.bus = null;\n\n /** @type {CPUStatePDP11} */\n this.cpu = null;\n\n /** @type {DebuggerPDP11} */\n this.dbg = null;\n\n /*\n * The 'hold' and 'toggle' exports, which map to holdSwitch() and toggleSwitch(), both press and release\n * the specified switch, but processCommands() considers a 'hold' function to be asynchronous, which means\n * that holdSwitch() will be passed a callback function that can be used to implement a delay between the\n * press and the release, whereas toggleSwitch() will not.\n *\n * holdSwitch() only makes sense for momentary switches (eg, 'TEST'), where a visual delay might be nice.\n * If the switch isn't momentary, or no delay is desired, then use toggleSwitch(); it will be more efficient.\n *\n * Finally, for switches that are toggles (eg, 'ENABLE'), you can use setSwitch() to set it to a specific\n * state: zero for \"off\" and non-zero for \"on\". setSwitch() also supports meta-switches like \"SR\", using\n * the entire value to set a series of switches at once; the value is assumed to be octal unless overridden\n * by a prefix (eg, \"0x\") or suffix (eg, \".\").\n */\n this['exports'] = {\n 'hold': this.holdSwitch,\n 'toggle': this.toggleSwitch,\n 'reset': this.resetSwitches,\n 'set': this.setSwitch\n };\n\n this.setReady();\n }\n\n /**\n * getAR()\n *\n * @this {PanelPDP11}\n * @return {number} (current ADDRESS register)\n */\n getAR()\n {\n return this.regAddr;\n }\n\n /**\n * setAR(value)\n *\n * @this {PanelPDP11}\n * @param {number} value (new ADDRESS register)\n */\n setAR(value)\n {\n this.updateAddr(this.regAddr = value);\n }\n\n /**\n * getDR()\n *\n * @this {PanelPDP11}\n * @return {number} (current DISPLAY register)\n */\n getDR()\n {\n return this.regDisplay;\n }\n\n /**\n * setDR(value)\n *\n * @this {PanelPDP11}\n * @param {number} value (new DISPLAY register)\n * @return {number}\n */\n setDR(value)\n {\n return this.updateData(this.regDisplay = value);\n }\n\n /**\n * getSR()\n *\n * @this {PanelPDP11}\n * @return {number} (current SWITCH register)\n */\n getSR()\n {\n return this.regSwitches;\n }\n\n /**\n * setSR(value)\n *\n * @this {PanelPDP11}\n * @param {number} value (new SWITCH register)\n */\n setSR(value)\n {\n this.setSRSwitches(value);\n }\n\n /**\n * getSwitch(name)\n *\n * @this {PanelPDP11}\n * @param {string} name\n * @return {number|undefined} 0 if switch is off (\"down\"), 1 if on (\"up\"), or undefined if unrecognized\n */\n getSwitch(name)\n {\n return this.switches[name] && this.switches[name][1];\n }\n\n /**\n * reset(fPowerUp)\n *\n * NOTE: Since we've registered our handler with the Bus component, we will be called twice whenever\n * the entire machine is reset: once when the Computer's reset() handler calls the Bus's reset() handler,\n * and again when the Computer's reset() handler calls us directly. Multiple resets should be harmless.\n *\n * @this {PanelPDP11}\n * @param {boolean} [fPowerUp]\n */\n reset(fPowerUp)\n {\n /*\n * Simulate a call to our stop() handler, to update the panel's ADDRESS register with the current PC.\n */\n this.stop();\n if (fPowerUp) this.setDR(0);\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * Some panel layouts don't have bindings of their own, and even when they do, there may still be some\n * components (eg, the CPU) that prefer to update their own bindings, so we pass along all binding requests\n * to the Computer, CPU, Keyboard and Debugger components first. The order shouldn't matter, since any\n * component that doesn't recognize the specified binding should simply ignore it.\n *\n * @this {PanelPDP11}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n if (this.cmp && this.cmp.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (this.cpu && this.cpu.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n if (DEBUGGER && this.dbg && this.dbg.setBinding(sHTMLType, sBinding, control, sValue)) return true;\n\n switch (sBinding) {\n case 'R0':\n case 'R1':\n case 'R2':\n case 'R3':\n case 'R4':\n case 'R5':\n case 'R6':\n case 'R7':\n case 'NF':\n case 'ZF':\n case 'VF':\n case 'CF':\n case 'PS':\n this.bindings[sBinding] = control;\n this.cLiveRegs++;\n return true;\n\n default:\n /*\n * Square (\"led\") or round (\"rled\") LEDs are defined in machine XML files like so:\n *\n * <control type=\"rled\" binding=\"A3\" value=\"1\" width=\"100%\" container=\"center\"/>\n *\n * Only *type* and *binding* attributes are required; if *value* is omitted, the default value is 0 (\"off\").\n */\n if (sHTMLType == \"led\" || sHTMLType == \"rled\") {\n this.bindings[sBinding] = control;\n this.leds[sBinding] = sValue? 1 : 0;\n this.cLiveRegs++;\n return true;\n }\n /*\n * Switches are defined in machine XML files like so:\n *\n * <control type=\"switch\" binding=\"S3\" value=\"1\" width=\"100%\" container=\"center\"/>\n *\n * Only *type* and *binding* attributes are required; if *value* is omitted, the default value is 0 (\"down\").\n *\n * Currently, there is no XML attribute to indicate whether a switch is \"momentary\"; only recognized switches\n * in our internal table can have that attribute.\n */\n if (sHTMLType == \"switch\") {\n /*\n * Like LEDs, we allow unrecognized switches to be defined as well, but they won't do anything useful,\n * since only recognized switches will have handlers that perform the appropriate operations.\n */\n if (this.switches[sBinding] === undefined) {\n this.switches[sBinding] = [sValue? 1 : 0, sValue? 1 : 0];\n }\n this.bindings[sBinding] = control;\n var parent = control.parentElement || control;\n parent = parent.parentElement || parent;\n parent.onmousedown = function(panel, sBinding) {\n return function onPressSwitch() {\n panel.pressSwitch(sBinding);\n };\n }(this, sBinding);\n parent.onmouseup = parent.onmouseout = function(panel, sBinding) {\n return function onReleaseSwitch() {\n panel.releaseSwitch(sBinding);\n };\n }(this, sBinding);\n parent.ontouchstart = function(panel, sBinding) {\n return function onPressSwitch(event) {\n panel.pressSwitch(sBinding);\n event.preventDefault();\n };\n }(this, sBinding);\n parent.ontouchend = function(panel, sBinding) {\n return function onReleaseSwitch() {\n panel.releaseSwitch(sBinding);\n };\n }(this, sBinding);\n return true;\n }\n return super.setBinding(sHTMLType, sBinding, control, sValue);\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {PanelPDP11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n bus.addIOTable(this, PanelPDP11.UNIBUS_IOTABLE);\n bus.addResetHandler(this.reset.bind(this));\n\n this.displayLEDs();\n this.displaySwitches();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {PanelPDP11}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n /*\n * As noted in init(), our powerUp() method gives us a second opportunity to notify any\n * components that that might care (eg, CPU, Keyboard, and Debugger) that we have some controls\n * (ie, bindings) they might want to use.\n */\n if (this.fBindings) PanelPDP11.init();\n\n if (!data) {\n this.reset(true);\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {PanelPDP11}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * save()\n *\n * This implements save support for the PanelPDP11 component.\n *\n * @this {PanelPDP11}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, [\n this.getAR(),\n this.getDR(),\n this.getSR()\n ]);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the PanelPDP11 component.\n *\n * @this {PanelPDP11}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var a = data[0];\n if (a) {\n this.setAR(a[0]);\n this.setDR(a[1]);\n this.setSR(a[2]);\n }\n return true;\n }\n\n /**\n * resetSwitches()\n *\n * @this {PanelPDP11}\n * @return {boolean}\n */\n resetSwitches()\n {\n for (var sBinding in this.switches) {\n var sw = this.switches[sBinding];\n sw[1] = sw[0];\n }\n this.displaySwitches();\n return true;\n }\n\n /**\n * displayLED(sBinding, value)\n *\n * @this {PanelPDP11}\n * @param {string} sBinding\n * @param {boolean|number} value (true or non-zero if the LED should be on, false or zero if off)\n */\n displayLED(sBinding, value)\n {\n var control = this.bindings[sBinding];\n if (control) {\n /*\n * TODO: Add support for user-definable LED colors?\n */\n control.style.backgroundColor = (value? \"#ff0000\" : \"#000000\");\n }\n }\n\n /**\n * displayLEDs(override)\n *\n * @this {PanelPDP11}\n * @param {boolean|number|null} [override] (true turn on all LEDs, false to turn off all LEDs, null or undefined for normal LED activity)\n */\n displayLEDs(override)\n {\n for (var sBinding in this.leds) {\n this.displayLED(sBinding, override != null? override : this.leds[sBinding]);\n }\n }\n\n /**\n * displaySwitch(sBinding, value)\n *\n * @this {PanelPDP11}\n * @param {string} sBinding\n * @param {boolean|number} value (true if the switch should be \"up\" (on), false if \"down\" (off))\n */\n displaySwitch(sBinding, value)\n {\n var control = this.bindings[sBinding];\n if (control) {\n control.style.marginTop = (value? \"0px\" : \"20px\");\n control.style.backgroundColor = (value? \"#00ff00\" : \"#228B22\");\n }\n }\n\n /**\n * displaySwitches()\n *\n * @this {PanelPDP11}\n */\n displaySwitches()\n {\n for (var sBinding in this.switches) {\n this.displaySwitch(sBinding, this.switches[sBinding][1]);\n }\n }\n\n /**\n * displayValue(sLabel, nValue, cch)\n *\n * This is principally for displaying register values, but in reality, it can be used to display any\n * numeric value bound to the given label.\n *\n * @this {PanelPDP11}\n * @param {string} sLabel\n * @param {number} nValue\n * @param {number} [cch]\n */\n displayValue(sLabel, nValue, cch)\n {\n if (this.bindings[sLabel]) {\n var sVal;\n var nBase = this.dbg && this.dbg.nBase || 8;\n nValue = nValue || 0;\n if (!this.cpu.isRunning() || this.fDisplayLiveRegs) {\n sVal = nBase == 8? Str.toOct(nValue, cch) : Str.toHex(nValue, cch);\n } else {\n sVal = \"--------\".substr(0, cch || 4);\n }\n /*\n * TODO: Determine if this test actually avoids any redrawing when a register hasn't changed, and/or if\n * we should maintain our own (numeric) cache of displayed register values (to avoid creating these temporary\n * string values that will have to garbage-collected), and/or if this is actually slower, and/or if I'm being\n * too obsessive.\n */\n if (this.bindings[sLabel].textContent != sVal) this.bindings[sLabel].textContent = sVal;\n }\n }\n\n /**\n * holdSwitch(fnCallback, sBinding, sDelay)\n *\n * @this {PanelPDP11}\n * @param {function()|null} fnCallback\n * @param {string} sBinding\n * @param {string} [sDelay]\n * @return {boolean} false if wait required, true otherwise\n */\n holdSwitch(fnCallback, sBinding, sDelay)\n {\n if (this.pressSwitch(sBinding)) {\n if (sDelay) {\n var panel = this;\n setTimeout(function() {\n panel.releaseSwitch(sBinding);\n if (fnCallback) fnCallback();\n }, +sDelay);\n return false;\n } else {\n this.releaseSwitch(sBinding);\n }\n }\n return true;\n }\n\n /**\n * setSwitch(sBinding, sValue)\n *\n * @this {PanelPDP11}\n * @param {string} sBinding\n * @param {string} sValue\n * @return {boolean}\n */\n setSwitch(sBinding, sValue)\n {\n if (sBinding == \"SR\") {\n return this.setSRSwitches(Str.parseInt(sValue, 8))\n }\n var sw = this.switches[sBinding];\n if (sw) {\n sw[1] = +sValue? 1 : 0;\n this.displaySwitch(sBinding, sw[1]);\n return true;\n }\n return false;\n }\n\n /**\n * toggleSwitch(sBinding)\n *\n * @this {PanelPDP11}\n * @param {string} sBinding\n * @return {boolean}\n */\n toggleSwitch(sBinding)\n {\n if (this.pressSwitch(sBinding)) {\n this.releaseSwitch(sBinding);\n return true;\n }\n return false;\n }\n\n /**\n * pressSwitch(sBinding)\n *\n * @this {PanelPDP11}\n * @param {string} sBinding\n * @return {boolean}\n */\n pressSwitch(sBinding)\n {\n var sw = this.switches[sBinding];\n if (sw) {\n /*\n * Set the new switch value in sw[1] and then immediately display it\n */\n this.displaySwitch(sBinding, (sw[1] = 1 - sw[1]));\n\n /*\n * Mark the switch as \"pressed\"\n */\n sw[3] = true;\n\n /*\n * Call the appropriate process handler with the current switch value (sw[1])\n */\n if (sw[4]) sw[4].call(this, sw[1], sw[5]);\n\n /*\n * Whenever the user presses 'LOAD' to load a new address, we want the next 'DEP' or 'EXAM'\n * to NOT auto-increment. The next 'DEP' or 'EXAM' will automatically re-enable auto-increment. \n */\n if (sBinding == PanelPDP11.SWITCH.LOAD) {\n this.fAutoInc = false;\n }\n return true;\n }\n return false;\n }\n\n /**\n * releaseSwitch(sBinding)\n *\n * @this {PanelPDP11}\n * @param {string} sBinding\n * @return {boolean}\n */\n releaseSwitch(sBinding)\n {\n /*\n * pressSwitch() is simple: flip the switch's current value in sw[1] and marked it \"pressed\" in sw[3].\n *\n * releaseSwitch() is more complicated, because we must handle both mouseUp and mouseOut events. The first time\n * we receive EITHER of those events AND the switch is marked momentary (sw[2]) AND the switch is pressed (sw[3]),\n * then we must flip the switch back to its original value.\n *\n * Otherwise, the only thing we have to do is mark the switch as \"released\" (ie, set sw[3] to false).\n */\n var sw = this.switches[sBinding];\n if (sw) {\n if (sw[2] && sw[3]) {\n /*\n * Set the new switch value in sw[1] and then immediately display it\n */\n this.displaySwitch(sBinding, (sw[1] = sw[0]));\n\n /*\n * Call the appropriate process handler with the current switch value (sw[1])\n */\n if (sw[4]) sw[4].call(this, sw[1], sw[5]);\n }\n /*\n * Mark the switch as \"released\"\n */\n sw[3] = false;\n return true;\n }\n return false;\n }\n\n /**\n * processStart(value, index)\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {number} [index]\n */\n processStart(value, index)\n {\n if (!value && !this.cpu.isRunning()) {\n\n this.cpu.setPC(this.regAddr);\n\n /*\n * TODO: Verify what the PDP-11/70 Handbook means when it says that when the 'START' switch\n * is depressed, \"the computer system will be cleared.\" I take it to mean that it performs\n * the equivalent of a RESET instruction.\n */\n this.cpu.resetCPU();\n\n /*\n * The PDP-11/70 Handbook goes on to say: \"If the system needs to be initialized but execution\n * is not wanted, the START switch should be depressed while the HALT/ENABLE switch is in the HALT\n * position.\"\n */\n if (this.getSwitch(PanelPDP11.SWITCH.ENABLE)) {\n this.cpu.startCPU();\n }\n }\n }\n\n /**\n * processStep(value, index)\n *\n * If value == 1 (our initial value), then the 'STEP' switch is set to \"S INST\" (step one instruction);\n * otherwise, it's set to \"S BUS CYCLE\" (step one bus cycle).\n *\n * However, since we can't currently support cycle-stepping, I've decided to innovate a little and\n * change the meaning of this switch: the normal (\"up\") position means that successive 'EXAM' and 'DEP'\n * operations will first add 2 to the ADDRESS register, while the opposite (\"down\") position means\n * they will first subtract 2.\n *\n * See processLEDTest() for more of these exciting \"innovations\". ;-)\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {number} [index]\n */\n processStep(value, index)\n {\n /*\n * There's really nothing for us to do here, because the normal press and release handlers\n * already record the state of this switch, so it can be queried as needed, using getSwitch().\n */\n }\n\n /**\n * processEnable(value, index)\n *\n * If value == 1 (our initial value), then the 'ENABLE'/'HALT' switch is set to 'ENABLE', otherwise 'HALT'.\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {number} [index]\n */\n processEnable(value, index)\n {\n /*\n * The \"down\" (0) position is 'HALT', which stops the CPU; however, the \"up\" (1) position ('ENABLE')\n * does NOT start the CPU. You must press 'CONT' to continue execution, which will either continue for\n * one instruction if this switch to set to 'HALT' or indefinitely if it is set to 'ENABLE'.\n */\n if (!value) {\n this.cpu.stopCPU();\n }\n }\n\n /**\n * processContinue(value, index)\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {number} [index]\n */\n processContinue(value, index)\n {\n if (!value && !this.cpu.isRunning()) {\n /*\n * TODO: Technically, we're also supposed to check the 'STEP' switch to determine if we should\n * step one instruction or just one cycle, but we don't currently have the ability to do the latter.\n */\n if (!this.getSwitch(PanelPDP11.SWITCH.ENABLE)) {\n /*\n * Using the Debugger's stepCPU() function is more convenient, and has the pleasant side-effect\n * of updating the debugger's display; however, not all machines with a Front Panel will necessarily\n * also have the Debugger loaded.\n */\n var dbg = this.dbg;\n if (dbg && !dbg.isBusy(true)) {\n dbg.setBusy(true);\n dbg.stepCPU(0, null);\n dbg.setBusy(false);\n }\n else {\n /*\n * For this tiny single-instruction burst, mimic what runCPU() does.\n */\n try {\n var nCyclesStep = this.cpu.stepCPU(1);\n if (nCyclesStep > 0) {\n this.cpu.updateTimers(nCyclesStep);\n this.cpu.addCycles(nCyclesStep, true);\n this.cpu.updateChecksum(nCyclesStep);\n }\n }\n catch(exception) {\n /*\n * We assume that any numeric exception was explicitly thrown by the CPU to interrupt the\n * current instruction. For all other exceptions, we attempt a stack dump.\n */\n if (typeof exception != \"number\") {\n var e = exception;\n this.cpu.setError(e.stack || e.message);\n }\n }\n }\n\n /*\n * Simulate a call to our stop() handler, to update the panel's ADDRESS register with the new PC.\n */\n this.stop();\n\n /*\n * Going through the normal channels (ie, the Computer's updateDisplays() interface) ensures that\n * ALL updateDisplay() handlers will be called, including ours.\n *\n * NOTE: If we used the Debugger's stepCPU() function, then that includes a call to updateDisplay();\n * unfortunately, it will have happened BEFORE we called stop() to update the ADDRESS register, so\n * we still need to call it again.\n */\n if (this.cmp) this.cmp.updateDisplays();\n }\n else {\n this.cpu.startCPU();\n }\n }\n }\n\n /**\n * processDeposit(value, index)\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {number} [index]\n */\n processDeposit(value, index)\n {\n if (value && !this.cpu.isRunning()) {\n if (this.fAutoInc) this.advanceAddr();\n this.fAutoInc = true;\n /*\n * This used to be updateData(), but that only updates regData, whereas setDR() updates both regData and regDisplay,\n * and for these kinds of explicit Front Panel operations, I'm assuming the values should be synced.\n */\n var w = this.setDR(this.regSwitches);\n\n if (this.nAddrSel == PanelPDP11.ADDRSEL.CONS_PHY) {\n /*\n * TODO: Determine if this needs to take the UNIBUS map into consideration.\n */\n this.bus.setWordDirect(this.regAddr, w);\n } else {\n /*\n * TODO: This code is obviously incomplete, since it doesn't take into account the precise ADDRSEL mode.\n */\n this.cpu.setWordSafe(this.regAddr, w);\n }\n }\n }\n\n /**\n * processExamine(value, index)\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {number} [index]\n */\n processExamine(value, index)\n {\n if (!value && !this.cpu.isRunning()) {\n var w;\n if (this.fAutoInc) this.advanceAddr();\n this.fAutoInc = true;\n if (this.nAddrSel == PanelPDP11.ADDRSEL.CONS_PHY) {\n /*\n * TODO: Determine if this needs to take the UNIBUS map into consideration.\n */\n w = this.bus.getWordDirect(this.regAddr);\n } else {\n /*\n * TODO: This code is obviously incomplete, since it doesn't take into account the precise ADDRSEL mode.\n */\n w = this.cpu.getWordSafe(this.regAddr);\n }\n /*\n * This used to be updateData(), but that only updates regData, whereas setDR() updates both regData and regDisplay,\n * and for these kinds of explicit Front Panel operations, I'm assuming the values should be synced.\n */\n this.setDR(w);\n }\n }\n\n /**\n * processLoadAddr(value, index)\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {number} [index]\n */\n processLoadAddr(value, index)\n {\n if (!value && !this.cpu.isRunning()) {\n this.updateAddr(this.regSwitches);\n }\n }\n\n /**\n * processLEDTest(value, index)\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {number} [index]\n */\n processLEDTest(value, index)\n {\n if (value) {\n this.fLEDTest = true;\n this.displayLEDs(true);\n } else {\n this.fLEDTest = false;\n this.displayLEDs();\n /*\n * This is another one of my \"innovations\": when you're done testing the LEDs, all the switches reset as well.\n */\n this.setSRSwitches(0);\n }\n }\n\n /**\n * processSRSwitch(value, index)\n *\n * @this {PanelPDP11}\n * @param {number} value (normally 0 or 1, but we only depend on it being zero or non-zero)\n * @param {number} index\n */\n processSRSwitch(value, index)\n {\n if (value) {\n this.regSwitches |= 1 << index;\n } else {\n this.regSwitches &= ~(1 << index);\n }\n }\n\n /**\n * advanceAddr()\n *\n * This should also take care of the following Front Panel behaviors when the accessing the general-purpose\n * registers:\n *\n * 1) ADDRESS display incremented by 1 (instead of 2)\n * 2) The STEP after the last register is 177700, such that the addresses are looped\n *\n * A third behavior is NOT emulated: preventing the ADDRESS from stepping to the first General Register (177700)\n * from 177676.\n *\n * @this {PanelPDP11}\n * @return {number}\n */\n advanceAddr()\n {\n var nRegs = this.cpu.model <= PDP11.MODEL_1140? 8 : 16;\n var fGenRegs = (this.regAddr >= PDP11.UNIBUS.R0SET0 /*177700*/ && this.regAddr < PDP11.UNIBUS.R0SET0 + nRegs);\n var inc = fGenRegs? 1 : 2;\n var mask = fGenRegs? 0xf : this.bus.nBusMask;\n if (!this.getSwitch(PanelPDP11.SWITCH.STEP)) inc = -inc;\n return this.updateAddr((this.regAddr & ~mask) | ((this.regAddr + inc) & mask));\n }\n\n /**\n * updateAddr(value)\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @return {number}\n */\n updateAddr(value)\n {\n this.regAddr = value & this.bus.nBusMask;\n if (this.ledAddr !== this.regAddr) {\n this.ledAddr = this.regAddr;\n this.updateLEDArray(\"A\", this.ledAddr, 22);\n }\n return this.regAddr;\n }\n\n /**\n * updateData(value)\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @return {number}\n */\n updateData(value)\n {\n this.regData = value & 0xffff;\n if (this.ledData !== this.regData) {\n this.ledData = this.regData;\n this.updateLEDArray(\"D\", this.ledData, 16);\n }\n return this.regData;\n }\n\n /**\n * updateLED(sBinding, value)\n *\n * @this {PanelPDP11}\n * @param {string} sBinding\n * @param {number} value\n * @return {number}\n */\n updateLED(sBinding, value)\n {\n this.leds[sBinding] = value;\n if (!this.fLEDTest) this.displayLED(sBinding, value);\n return value;\n }\n\n /**\n * updateLEDArray(sPrefix, value, nLEDs)\n *\n * @this {PanelPDP11}\n * @param {string} sPrefix\n * @param {number} value\n * @param {number} nLEDs\n */\n updateLEDArray(sPrefix, value, nLEDs)\n {\n for (var i = 0; i < nLEDs; i++) {\n var sBinding = sPrefix + i;\n this.updateLED(sBinding, value & (1 << i));\n }\n }\n\n /**\n * setSRSwitches(value)\n *\n * @this {PanelPDP11}\n * @param {number|undefined} value\n * @return {boolean}\n */\n setSRSwitches(value)\n {\n this.regSwitches = value | 0;\n for (var i = 0; i < 22; i++) {\n this.switches['S'+i][1] = (this.regSwitches & (1 << i))? 1 : 0;\n }\n /*\n * This (re)displays ALL switches, not merely the SR switches, but that's OK.\n */\n this.displaySwitches();\n return true;\n }\n\n /**\n * stop(ms, nCycles)\n *\n * This is a notification handler, called by the Computer, to inform us the CPU has now stopped.\n *\n * @this {PanelPDP11}\n * @param {number} [ms]\n * @param {number} [nCycles]\n */\n stop(ms, nCycles)\n {\n this.updateAddr(this.cpu.regsGen[7]);\n }\n\n /**\n * setAddr(value, fActive)\n *\n * This interface is for passing new addresses to the Front Panel. However, whether or not this will become the\n * ADDRESS actually displayed will depend on other settings (see updateStatus() for details).\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {boolean} [fActive] (true if this should become the \"active\" ADDRESS regardless of other settings)\n */\n setAddr(value, fActive)\n {\n this.regAddr = value;\n }\n\n /**\n * setData(value, fActive)\n *\n * This interface is for passing new data to the Front Panel. However, whether or not this will become the\n * DATA actually displayed will depend on the Front Panel's DATASEL switch setting, as well as the fActive flag.\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {boolean} [fActive] (true if this should become the \"active\" DATA regardless of the DATASEL switch setting)\n */\n setData(value, fActive)\n {\n if (!fActive) {\n this.regData = value;\n } else {\n this.regDisplay = value;\n }\n }\n\n /**\n * updateDisplay(nUpdate)\n *\n * Called by the Computer component at intervals to update registers, LEDs, etc.\n *\n * @this {PanelPDP11}\n * @param {number} [nUpdate] (-2 for power on, -1 for forced, > 0 for periodic, 0 or undefined otherwise)\n */\n updateDisplay(nUpdate)\n {\n if (this.cLiveRegs) {\n\n var fRunning = this.cpu.isRunning();\n var fWaiting = this.cpu.isWaiting();\n\n if (nUpdate < 0 || !fRunning || this.fDisplayLiveRegs) {\n\n /*\n * We arbitrarily separate the display elements into two categories: cheap and expensive.\n *\n * LEDs are considered cheap, register displays are not. So we'll skip the latter if this\n * is a periodic update AND our periodic update counter hasn't reached the periodic update limit.\n */\n if (nUpdate <= 0 || (this.nDisplayCount += nUpdate) >= this.nDisplayLimit) {\n for (var i = 0; i < this.cpu.regsGen.length; i++) {\n this.displayValue('R'+i, this.cpu.regsGen[i]);\n }\n var regPSW = this.cpu.getPSW();\n this.displayValue(\"PS\", regPSW);\n this.displayValue(\"NF\", (regPSW & PDP11.PSW.NF)? 1 : 0, 1);\n this.displayValue(\"ZF\", (regPSW & PDP11.PSW.ZF)? 1 : 0, 1);\n this.displayValue(\"VF\", (regPSW & PDP11.PSW.VF)? 1 : 0, 1);\n this.displayValue(\"CF\", (regPSW & PDP11.PSW.CF)? 1 : 0, 1);\n this.nDisplayCount = 0;\n }\n\n /*\n * Update the ADDRESS and DATA LEDs by selecting the appropriate values.\n *\n * TODO: There is currently no mechanism for selecting regData over regDisplay;\n * we are acting as if the DATASEL switch setting is locked to \"DISPLAY REGISTER\".\n */\n if (nUpdate < -1) {\n this.regAddr = this.cpu.regsGen[7];\n } else if (nUpdate > 0 && fRunning && !fWaiting) {\n this.regAddr = this.cpu.getLastAddr();\n }\n\n this.updateAddr(this.regAddr);\n this.updateData(this.regDisplay);\n\n var bits = this.cpu.getMMUState();\n /*\n * Bit 0 set if 22-bit, bit 1 set if 18-bit, bit 2 set if 16-bit\n */\n this.updateLED(PanelPDP11.LED.B22, bits & 1);\n this.updateLED(PanelPDP11.LED.B18, bits & 2);\n this.updateLED(PanelPDP11.LED.B16, bits & 4);\n }\n }\n }\n\n /**\n * readCNSW(addr, fPreWrite)\n *\n * If fPreWrite, this is a read-before-write, so we must return the DISPLAY register (ie, regDisplay);\n * otherwise, this a normal read, so we should return the SWITCH register (ie, regSwitches).\n *\n *\n * @this {PanelPDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.CNSW or 177570)\n * @param {boolean} [fPreWrite]\n * @return {number}\n */\n readCNSW(addr, fPreWrite)\n {\n return (fPreWrite? this.regDisplay : this.regSwitches) & 0xffff;\n }\n\n /**\n * writeCNSW(value, addr)\n *\n * Handles writes to the DISPLAY register (ie, regDisplay).\n *\n * @this {PanelPDP11}\n * @param {number} value\n * @param {number} addr (eg, PDP11.UNIBUS.CNSW or 177570)\n */\n writeCNSW(value, addr)\n {\n this.regDisplay = value;\n }\n\n /**\n * PanelPDP11.init()\n *\n * This function operates on every HTML element of class \"panel\", extracting the\n * JSON-encoded parameters for the PanelPDP11 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a PanelPDP11 component, and then binding\n * any associated HTML controls to the new component.\n *\n * NOTE: Unlike most other component init() functions, this one is designed to be\n * called multiple times: once at load time, so that we can bind our print()\n * function to the panel's output control ASAP, and again when the Computer component\n * is verifying that all components are ready and invoking their powerUp() functions.\n *\n * Our powerUp() method gives us a second opportunity to notify any components that\n * that might care (eg, CPU, Keyboard, and Debugger) that we have some controls they\n * might want to use.\n */\n static init()\n {\n var aePanels = Component.getElementsByClass(document, PDP11.APPCLASS, \"panel\");\n for (var iPanel=0; iPanel < aePanels.length; iPanel++) {\n var ePanel = aePanels[iPanel];\n var parmsPanel = Component.getComponentParms(ePanel);\n var panel = Component.getComponentByID(parmsPanel['id']);\n if (!panel) panel = new PanelPDP11(parmsPanel, true);\n Component.bindComponentControls(panel, ePanel, PDP11.APPCLASS);\n }\n }\n}\n\nPanelPDP11.ADDRSEL = {\n KERNEL_I: 0, // use a 16-bit virtual address where bits 16 to 21 are always OFF\n KERNEL_D: 1, // use a 16-bit virtual address where bits 16 to 21 are always OFF\n SUPER_I: 2, // use a 16-bit virtual address where bits 16 to 21 are always OFF\n SUPER_D: 3, // use a 16-bit virtual address where bits 16 to 21 are always OFF\n USER_I: 4, // use a 16-bit virtual address where bits 16 to 21 are always OFF\n USER_D: 5, // use a 16-bit virtual address where bits 16 to 21 are always OFF\n PROG_PHY: 6, // display the 22-bit physical address of the current bus cycle generated by the MMU\n CONS_PHY: 7 // use a 22-bit physical address to perform console operations (e.g., LOAD ADRS, EXAM, & DEP)\n};\n\n/*\n * To get the current state of a switch; eg::\n *\n * this.getSwitch(PanelPDP11.SWITCH.ENABLE)\n *\n * I haven't filled out this table, primarily it only needs to list switches we actually query\n * (eg, non-momentary ones like 'ENABLE' and 'STEP', and 'EXAM' and 'DEP' since they have special\n * \"step\" behavior when pressed more than once in a row). Ditto for the LED table.\n */\nPanelPDP11.SWITCH = {\n DEP: 'DEP',\n ENABLE: 'ENABLE',\n EXAM: 'EXAM',\n LOAD: 'LOAD',\n STEP: 'STEP'\n};\n\nPanelPDP11.LED = {\n B16: 'B16',\n B18: 'B18',\n B22: 'B22'\n};\n\nPanelPDP11.UNIBUS_IOTABLE = {\n [PDP11.UNIBUS.CNSW]: /* 177570 */ [null, null, PanelPDP11.prototype.readCNSW, PanelPDP11.prototype.writeCNSW, \"CNSW\"]\n};\n\n/*\n * Initialize every Panel module on the page.\n */\nWeb.onInit(PanelPDP11.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/bus.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * Data types used by scanMemory()\n */\n\n/**\n * This defines the BlockInfo bit fields used by scanMemory() when it creates the aBlocks array.\n *\n * @typedef {{\n * num: BitField,\n * count: BitField,\n * btmod: BitField,\n * type: BitField\n * }}\n */\nvar BlockInfoPDP11 = Usr.defineBitFields({num:20, count:8, btmod:1, type:3});\n\n/**\n * BusInfoPDP11 object definition (returned by scanMemory())\n *\n * cbTotal: total bytes allocated\n * cBlocks: total Memory blocks allocated\n * aBlocks: array of allocated Memory block numbers\n *\n * @typedef {{\n * cbTotal: number,\n * cBlocks: number,\n * aBlocks: Array.<BlockInfoPDP11>\n * }}\n */\nvar BusInfoPDP11;\n\nclass BusPDP11 extends Component {\n /**\n * BusPDP11(parmsBus, cpu, dbg)\n *\n * The BusPDP11 component manages physical memory and I/O address spaces.\n *\n * The BusPDP11 component has no UI elements, so it does not require an init() handler,\n * but it still inherits from the Component class and must be allocated like any\n * other device component. It's currently allocated by the Computer's init() handler,\n * which then calls the initBus() method of all the other components.\n *\n * For memory beyond the simple needs of the ROM and RAM components (ie, memory-mapped\n * devices), the address space must still be allocated through the BusPDP11 component via\n * addMemory(). If the component needs something more than simple read/write storage,\n * it must provide a custom controller.\n *\n * @param {Object} parmsBus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n constructor(parmsBus, cpu, dbg)\n {\n super(\"Bus\", parmsBus, MessagesPDP11.BUS);\n\n this.cpu = cpu;\n this.dbg = dbg;\n\n /*\n * Supported values for nBusWidth are 16 (default), 18, and 22. This represents the maximum size\n * of the bus for the life of the machine, regardless what memory management mode the CPU has enabled.\n */\n this.nBusWidth = +parmsBus['busWidth'] || 16;\n\n /*\n * Compute all BusPDP11 memory block parameters now, based on the width of the bus.\n *\n * Note that all PCjs machines divide their address space into blocks, using a block size appropriate for\n * the machine's bus width. This allows us to efficiently allocate the entire address space, by reusing blocks\n * as appropriate, and to define to different address behaviors on a block-granular level.\n *\n * For PDPjs machines, the ideal block size is 8Kb (IOPAGE_LENGTH), the size of the IOPAGE on all PDP-11 machines;\n * as a result, our IOController functions assume that all incoming offsets are within a single 8Kb block.\n */\n this.addrTotal = 1 << this.nBusWidth;\n this.nBusMask = (this.addrTotal - 1);\n this.nBlockSize = BusPDP11.IOPAGE_LENGTH;\n this.nBlockShift = Math.log2(this.nBlockSize); // ES6 ALERT (alternatively: Math.log(this.nBlockSize) / Math.LN2)\n this.nBlockLen = this.nBlockSize >> 2;\n this.nBlockLimit = this.nBlockSize - 1;\n this.nBlockTotal = (this.addrTotal / this.nBlockSize) | 0;\n this.nBlockMask = this.nBlockTotal - 1;\n\n\n /*\n * aIOHandlers is an array (ie, a hash) of I/O notification handlers, indexed by address, where each\n * entry contains an array:\n *\n * [0]: readByte(addr)\n * [1]: writeByte(b, addr)\n * [2]: readWord(addr)\n * [3]: writeWord(w, addr)\n *\n * Each of these 4-element arrays are similar to the memory access arrays assigned to entire Memory\n * blocks, but these handlers generally target a specific address (or handful of addresses), while\n * Memory access handlers must service the entire block; see the setAccess() function in the Memory\n * component for details.\n *\n * Finally, for debugging purposes, if an I/O address has a symbolic name and message category,\n * they will be saved here:\n *\n * [4]: symbolic name of I/O address\n * [5]: message category\n *\n * UPDATE: The Debugger wants to piggy-back on these arrays to indicate addresses for which it wants\n * notification. In those cases, the following additional element will be set:\n *\n * [6]: true to break on I/O, false to ignore I/O\n *\n * The false case is important if fIOBreakAll is set, because it allows the Debugger to selectively\n * ignore specific addresses.\n */\n this.aIOHandlers = [];\n this.fIOBreakAll = false;\n this.nDisableFaults = 0;\n this.fFault = false;\n\n /*\n * Array of RESET notification handlers registered by Device components.\n */\n this.afnReset = [];\n\n /*\n * Before we can add any memory blocks that declare our component as a custom memory controller,\n * we must initialize the array that the getControllerAccess() method supplies to the Memory component.\n */\n this.afnIOPage = [\n BusPDP11.IOController.readByte,\n BusPDP11.IOController.writeByte,\n BusPDP11.IOController.readWord,\n BusPDP11.IOController.writeWord\n ];\n\n /*\n * Define all the properties to be initialized by initMemory()\n */\n this.aBusBlocks = this.aMemBlocks = [];\n this.iBlockIOPageBus = this.iBlockIOPageMem = 0;\n this.addrIOPage = this.nIOPageRange = this.nMemMask = 0;\n\n /*\n * We're ready to allocate empty Memory blocks to span the entire physical address space, including the\n * initial location of the IOPAGE.\n */\n this.initMemory();\n\n this.setReady();\n }\n\n /**\n * initMemory()\n *\n * Allocate enough (empty) Memory blocks to span the entire physical address space.\n *\n * Note that we now maintain two parallel arrays of these Memory blocks: aBusBlocks is for use by\n * devices (or any component using the \"direct\" interfaces), while aMemBlocks is for use by the CPU.\n *\n * Whereas the Bus memory map is fixed at init time, the CPU's memory map will vary depending on MMU\n * settings. The CPU will call setIOPageRange() as needed to update the range of addressible memory,\n * which in turn will determine where the IOPAGE can be accessed.\n *\n * @this {BusPDP11}\n */\n initMemory()\n {\n var block = new MemoryPDP11(this);\n block.copyBreakpoints(this.dbg);\n\n this.aBusBlocks = new Array(this.nBlockTotal);\n this.aMemBlocks = new Array(this.nBlockTotal);\n for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {\n this.aBusBlocks[iBlock] = this.aMemBlocks[iBlock] = block;\n }\n /*\n * NOTE: Don't confuse the Bus addrIOPage with the CPU's addrIOPage; ours is fixed,\n * based on the machine's Bus width, whereas the CPU's varies according to the MMU setting.\n */\n this.addrIOPage = this.addrTotal - BusPDP11.IOPAGE_LENGTH;\n this.addMemory(this.addrIOPage, BusPDP11.IOPAGE_LENGTH, MemoryPDP11.TYPE.CONTROLLER, this);\n\n this.iBlockIOPageBus = (this.addrIOPage & this.nBusMask) >>> this.nBlockShift;\n this.iBlockIOPageMem = this.iBlockIOPageBus;\n\n this.nIOPageRange = 0;\n this.nMemMask = this.nBusMask;\n }\n\n /**\n * setIOPageRange(nRange)\n *\n * This function is responsible for syncing the CPU memory map (aMemBlocks) with the Bus memory map (aBusBlocks)\n * and then updating the location of the IOPAGE within the CPU's memory map. The location of the IOPAGE is always\n * fixed at the top of the Bus address space, but it moves (logically) within the CPU's address space according\n * to the CPU's current MMU settings, which nRange is a reflection of.\n *\n * @this {BusPDP11}\n * @param {number} nRange (16, 18 or 22; 0 removes the IOPAGE altogether)\n */\n setIOPageRange(nRange)\n {\n if (nRange != this.nIOPageRange) {\n for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {\n this.aMemBlocks[iBlock] = this.aBusBlocks[iBlock];\n }\n this.nIOPageRange = 0;\n this.nMemMask = this.nBusMask;\n if (nRange) {\n this.nIOPageRange = nRange;\n var addr = (1 << nRange);\n this.nMemMask = (addr - 1);\n addr -= BusPDP11.IOPAGE_LENGTH;\n this.iBlockIOPageMem = (addr & this.nMemMask) >>> this.nBlockShift;\n this.aMemBlocks[this.iBlockIOPageMem] = this.aBusBlocks[this.iBlockIOPageBus];\n }\n }\n }\n\n /**\n * getControllerBuffer(addr)\n *\n * Our Bus component also acts as custom memory controller for the IOPAGE, so it must also provide this function.\n *\n * @this {BusPDP11}\n * @param {number} addr\n * @return {Array} containing the buffer (and the offset within that buffer that corresponds to the requested block)\n */\n getControllerBuffer(addr)\n {\n /*\n * No buffer is required for the IOPAGE; all accesses go to registered I/O handlers or to fault().\n */\n return [null, 0];\n }\n\n /**\n * getControllerAccess()\n *\n * Our Bus component also acts as custom memory controller for the IOPAGE, so it must also provide this function.\n *\n * @this {BusPDP11}\n * @return {Array.<function()>}\n */\n getControllerAccess()\n {\n return this.afnIOPage;\n }\n\n /**\n * getWidth()\n *\n * @this {BusPDP11}\n * @return {number}\n */\n getWidth()\n {\n return this.nBusWidth;\n }\n\n /**\n * reset()\n *\n * Call all registered reset() handlers.\n *\n * @this {BusPDP11}\n */\n reset()\n {\n for (var i = 0; i < this.afnReset.length; i++) {\n this.afnReset[i]();\n }\n this.setIOPageRange(16);\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {BusPDP11}\n * @param {Object|null} data (always null because we supply no powerDown() handler)\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {BusPDP11}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * save()\n *\n * @this {BusPDP11}\n * @return {Object|null}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveMemory());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * @this {BusPDP11}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n return this.restoreMemory(data[0]);\n }\n\n /**\n * addMemory(addr, size, type, controller)\n *\n * Adds new Memory blocks to the specified address range. Any Memory blocks previously\n * added to that range must first be removed via removeMemory(); otherwise, you'll get\n * an allocation conflict error. This helps prevent address calculation errors, redundant\n * allocations, etc.\n *\n * We've relaxed some of the original requirements (ie, that addresses must start at a\n * block-granular address, or that sizes must be equal to exactly one or more blocks),\n * because machines with large block sizes can make it impossible to load certain ROMs at\n * their required addresses. Every allocation still allocates a whole number of blocks.\n *\n * Even so, BusPDP11 memory management does NOT provide a general-purpose heap. Most memory\n * allocations occur during machine initialization and never change. In particular, there\n * is NO support for removing partial-block allocations.\n *\n * Each Memory block keeps track of a start address (addr) and length (used), indicating\n * the used space within the block; any free space that precedes or follows that used space\n * can be allocated later, by simply extending the beginning or ending of the previously used\n * space. However, any holes that might have existed between the original allocation and an\n * extension are subsumed by the extension.\n *\n * @this {BusPDP11}\n * @param {number} addr is the starting physical address of the request\n * @param {number} size of the request, in bytes\n * @param {number} type is one of the MemoryPDP11.TYPE constants\n * @param {Object} [controller] is an optional memory controller component\n * @return {boolean} true if successful, false if not\n */\n addMemory(addr, size, type, controller)\n {\n var addrNext = addr;\n var sizeLeft = size;\n var iBlock = addrNext >>> this.nBlockShift;\n\n while (sizeLeft > 0 && iBlock < this.aBusBlocks.length) {\n\n var block = this.aBusBlocks[iBlock];\n var addrBlock = iBlock * this.nBlockSize;\n var sizeBlock = this.nBlockSize - (addrNext - addrBlock);\n if (sizeBlock > sizeLeft) sizeBlock = sizeLeft;\n\n /*\n * addMemory() will now happily replace an existing block when a memory controller is specified;\n * this is a work-around to make life easier for setIOPageRange(), which otherwise would have to call\n * removeMemory() first, which would just waste time and memory allocating more (empty) blocks.\n */\n if (!controller && block && block.size) {\n if (block.type == type /* && block.controller == controller */) {\n /*\n * Where there is already a similar block with a non-zero size, we allow the allocation only if:\n *\n * 1) addrNext + sizeLeft <= block.addr (the request precedes the used portion of the current block), or\n * 2) addrNext >= block.addr + block.used (the request follows the used portion of the current block)\n */\n if (addrNext + sizeLeft <= block.addr) {\n block.used += (block.addr - addrNext);\n block.addr = addrNext;\n return true;\n }\n if (addrNext >= block.addr + block.used) {\n var sizeAvail = block.size - (addrNext - addrBlock);\n if (sizeAvail > sizeLeft) sizeAvail = sizeLeft;\n block.used = addrNext - block.addr + sizeAvail;\n addrNext = addrBlock + this.nBlockSize;\n sizeLeft -= sizeAvail;\n iBlock++;\n continue;\n }\n }\n return this.reportError(BusPDP11.ERROR.RANGE_INUSE, addrNext, sizeLeft);\n }\n\n var blockNew = new MemoryPDP11(this, addrNext, sizeBlock, this.nBlockSize, type, controller);\n blockNew.copyBreakpoints(this.dbg, block);\n this.aBusBlocks[iBlock++] = blockNew;\n\n addrNext = addrBlock + this.nBlockSize;\n sizeLeft -= sizeBlock;\n }\n\n if (sizeLeft <= 0) {\n this.status(\"Added \" + (size >> 10) + \"Kb \" + MemoryPDP11.TYPE_NAMES[type] + \" at \" + Str.toOct(addr));\n return true;\n }\n\n return this.reportError(BusPDP11.ERROR.RANGE_INVALID, addr, size);\n }\n\n /**\n * cleanMemory(addr, size)\n *\n * @this {BusPDP11}\n * @param {number} addr\n * @param {number} size\n * @return {boolean} true if all blocks were clean, false if dirty; all blocks are cleaned in the process\n */\n cleanMemory(addr, size)\n {\n var fClean = true;\n var iBlock = addr >>> this.nBlockShift;\n var sizeBlock = this.nBlockSize - (addr & this.nBlockLimit);\n while (size > 0 && iBlock < this.aBusBlocks.length) {\n if (this.aBusBlocks[iBlock].fDirty) {\n this.aBusBlocks[iBlock].fDirty = fClean = false;\n this.aBusBlocks[iBlock].fDirtyEver = true;\n }\n size -= sizeBlock;\n sizeBlock = this.nBlockSize;\n iBlock++;\n }\n return fClean;\n }\n\n /**\n * zeroMemory(addr, size, pattern)\n *\n * @this {BusPDP11}\n * @param {number} addr\n * @param {number} size\n * @param {number} [pattern]\n */\n zeroMemory(addr, size, pattern)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0 && iBlock < this.aBusBlocks.length) {\n this.aBusBlocks[iBlock].zero(off, size, pattern);\n size -= this.nBlockSize;\n iBlock++;\n off = 0;\n }\n }\n\n /**\n * scanMemory(info, addr, size)\n *\n * Returns a BusInfoPDP11 object for the specified address range.\n *\n * @this {BusPDP11}\n * @param {BusInfoPDP11} [info] previous BusInfoPDP11, if any\n * @param {number} [addr] starting address of range (0 if none provided)\n * @param {number} [size] size of range, in bytes (up to end of address space if none provided)\n * @return {BusInfoPDP11} updated info (or new info if no previous info provided)\n */\n scanMemory(info, addr, size)\n {\n if (addr == null) addr = 0;\n if (size == null) size = (this.addrTotal - addr) | 0;\n if (info == null) info = {cbTotal: 0, cBlocks: 0, aBlocks: []};\n\n var iBlock = addr >>> this.nBlockShift;\n var iBlockMax = ((addr + size - 1) >>> this.nBlockShift);\n\n info.cbTotal = 0;\n info.cBlocks = 0;\n while (iBlock <= iBlockMax) {\n var block = this.aBusBlocks[iBlock];\n info.cbTotal += block.size;\n if (block.size) {\n info.aBlocks.push(/** @type {BlockInfoPDP11} */ (Usr.initBitFields(BlockInfoPDP11, iBlock, 0, 0, block.type)));\n info.cBlocks++\n }\n iBlock++;\n }\n return info;\n }\n\n /**\n * removeMemory(addr, size)\n *\n * Replaces every block in the specified address range with empty Memory blocks that ignore all reads/writes.\n *\n * TODO: Update the removeMemory() interface to reflect the relaxed requirements of the addMemory() interface.\n *\n * @this {BusPDP11}\n * @param {number} addr\n * @param {number} size\n * @return {boolean} true if successful, false if not\n */\n removeMemory(addr, size)\n {\n if (!(addr & this.nBlockLimit) && size && !(size & this.nBlockLimit)) {\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0) {\n var blockOld = this.aBusBlocks[iBlock];\n var blockNew = new MemoryPDP11(this, addr);\n blockNew.copyBreakpoints(this.dbg, blockOld);\n this.aBusBlocks[iBlock++] = blockNew;\n addr = iBlock * this.nBlockSize;\n size -= this.nBlockSize;\n }\n return true;\n }\n return this.reportError(BusPDP11.ERROR.RANGE_INVALID, addr, size);\n }\n\n /**\n * getMemoryBlocks(addr, size)\n *\n * @this {BusPDP11}\n * @param {number} addr is the starting physical address\n * @param {number} size of the request, in bytes\n * @return {Array} of Memory blocks\n */\n getMemoryBlocks(addr, size)\n {\n var aBlocks = [];\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0 && iBlock < this.aBusBlocks.length) {\n aBlocks.push(this.aBusBlocks[iBlock++]);\n size -= this.nBlockSize;\n }\n return aBlocks;\n }\n\n /**\n * setMemoryAccess(addr, size, afn, fQuiet)\n *\n * Updates the access functions in every block of the specified address range. Since the only components\n * that should be dynamically modifying the memory access functions are those that use addMemory() with a custom\n * memory controller, we require that the block(s) being updated do in fact have a controller.\n *\n * @this {BusPDP11}\n * @param {number} addr\n * @param {number} size\n * @param {Array.<function()>} [afn]\n * @param {boolean} [fQuiet] (true if any error should be quietly logged)\n * @return {boolean} true if successful, false if not\n */\n setMemoryAccess(addr, size, afn, fQuiet)\n {\n if (!(addr & this.nBlockLimit) && size && !(size & this.nBlockLimit)) {\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0) {\n var block = this.aBusBlocks[iBlock];\n if (!block.controller) {\n return this.reportError(BusPDP11.ERROR.NO_CONTROLLER, addr, size, fQuiet);\n }\n block.setAccess(afn, true);\n size -= this.nBlockSize;\n iBlock++;\n }\n return true;\n }\n return this.reportError(BusPDP11.ERROR.RANGE_INVALID, addr, size);\n }\n\n /**\n * setMemoryBlocks(addr, size, aBlocks, type)\n *\n * If no type is specified, then specified address range uses all the provided blocks as-is;\n * this form of setMemoryBlocks() is used for complete physical aliases.\n *\n * Otherwise, new blocks are allocated with the specified type; the underlying memory from the\n * provided blocks is still used, but the new blocks may have different access to that memory.\n *\n * @this {BusPDP11}\n * @param {number} addr is the starting physical address\n * @param {number} size of the request, in bytes\n * @param {Array} aBlocks as returned by getMemoryBlocks()\n * @param {number} [type] is one of the MemoryPDP11.TYPE constants\n */\n setMemoryBlocks(addr, size, aBlocks, type)\n {\n var i = 0;\n var iBlock = addr >>> this.nBlockShift;\n while (size > 0 && iBlock < this.aBusBlocks.length) {\n var block = aBlocks[i++];\n\n if (!block) break;\n if (type !== undefined) {\n var blockNew = new MemoryPDP11(this, addr);\n blockNew.clone(block, type, this.dbg);\n block = blockNew;\n }\n this.aBusBlocks[iBlock++] = block;\n size -= this.nBlockSize;\n }\n }\n\n /**\n * getByte(addr)\n *\n * @this {BusPDP11}\n * @param {number} addr is a physical address\n * @return {number} byte (8-bit) value at that address\n */\n getByte(addr)\n {\n return this.aMemBlocks[(addr & this.nMemMask) >>> this.nBlockShift].readByte(addr & this.nBlockLimit, addr);\n }\n\n /**\n * getWord(addr)\n *\n * @this {BusPDP11}\n * @param {number} addr is a physical address\n * @return {number} word (16-bit) value at that address\n */\n getWord(addr)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nMemMask) >>> this.nBlockShift;\n if (!PDP11.WORDBUS && off == this.nBlockLimit) {\n return this.aMemBlocks[iBlock++].readByte(off, addr) | (this.aMemBlocks[iBlock & this.nBlockMask].readByte(0, addr + 1) << 8);\n }\n return this.aMemBlocks[iBlock].readWord(off, addr);\n }\n\n /**\n * setByte(addr, b)\n *\n * @this {BusPDP11}\n * @param {number} addr is a physical address\n * @param {number} b is the byte (8-bit) value to write\n */\n setByte(addr, b)\n {\n\n this.aMemBlocks[(addr & this.nMemMask) >>> this.nBlockShift].writeByte(addr & this.nBlockLimit, b, addr);\n }\n\n /**\n * setWord(addr, w)\n *\n * @this {BusPDP11}\n * @param {number} addr is a physical address\n * @param {number} w is the word (16-bit) value to write\n */\n setWord(addr, w)\n {\n var off = addr & this.nBlockLimit;\n var iBlock = (addr & this.nMemMask) >>> this.nBlockShift;\n if (!PDP11.WORDBUS && off == this.nBlockLimit) {\n this.aMemBlocks[iBlock++].writeByte(off, w & 0xff, addr);\n this.aMemBlocks[iBlock & this.nBlockMask].writeByte(0, (w >> 8) & 0xff, addr + 1);\n return;\n }\n this.aMemBlocks[iBlock].writeWord(off, w, addr);\n }\n\n /**\n * getBlockDirect(addr)\n *\n * @this {BusPDP11}\n * @param {number} addr is a physical address\n * @return {MemoryPDP11}\n */\n getBlockDirect(addr)\n {\n return this.aBusBlocks[(addr & this.nBusMask) >>> this.nBlockShift];\n }\n\n /**\n * getByteDirect(addr)\n *\n * This is used for device I/O and Debugger physical memory requests, not the CPU.\n *\n * @this {BusPDP11}\n * @param {number} addr is a physical address\n * @return {number} byte (8-bit) value at that address\n */\n getByteDirect(addr)\n {\n this.fFault = false;\n this.nDisableFaults++;\n var b = this.getBlockDirect(addr).readByteDirect(addr & this.nBlockLimit, addr);\n this.nDisableFaults--;\n return b;\n }\n\n /**\n * getWordDirect(addr)\n *\n * This is used for device I/O and Debugger physical memory requests, not the CPU.\n *\n * @this {BusPDP11}\n * @param {number} addr is a physical address\n * @return {number} word (16-bit) value at that address\n */\n getWordDirect(addr)\n {\n var w;\n this.fFault = false;\n this.nDisableFaults++;\n var off = addr & this.nBlockLimit;\n var block = this.getBlockDirect(addr);\n if (!PDP11.WORDBUS && off == this.nBlockLimit) {\n w = block.readByteDirect(off, addr) | (this.getBlockDirect(addr + 1).readByteDirect(0, addr + 1) << 8);\n } else {\n w = block.readWordDirect(off, addr);\n }\n this.nDisableFaults--;\n return w;\n }\n\n /**\n * setByteDirect(addr, b)\n *\n * This is used for device I/O and Debugger physical memory requests, not the CPU.\n *\n * @this {BusPDP11}\n * @param {number} addr is a physical address\n * @param {number} b is the byte (8-bit) value to write (we truncate it to 8 bits to be safe)\n */\n setByteDirect(addr, b)\n {\n this.fFault = false;\n this.nDisableFaults++;\n this.getBlockDirect(addr).writeByteDirect(addr & this.nBlockLimit, b & 0xff, addr);\n this.nDisableFaults--;\n }\n\n /**\n * setWordDirect(addr, w)\n *\n * This is used for device I/O and Debugger physical memory requests, not the CPU.\n *\n * @this {BusPDP11}\n * @param {number} addr is a physical address\n * @param {number} w is the word (16-bit) value to write (we truncate it to 16 bits to be safe)\n */\n setWordDirect(addr, w)\n {\n this.fFault = false;\n this.nDisableFaults++;\n var off = addr & this.nBlockLimit;\n var block = this.getBlockDirect(addr);\n if (!PDP11.WORDBUS && off == this.nBlockLimit) {\n block.writeByteDirect(off, w & 0xff, addr);\n this.getBlockDirect(addr + 1).writeByteDirect(0, (w >> 8) & 0xff, addr + 1);\n } else {\n block.writeWordDirect(off, w & 0xffff, addr);\n }\n this.nDisableFaults--;\n }\n\n /**\n * addMemBreak(addr, fWrite)\n *\n * @this {BusPDP11}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint\n */\n addMemBreak(addr, fWrite)\n {\n if (DEBUGGER) {\n var iBlock = addr >>> this.nBlockShift;\n this.aBusBlocks[iBlock].addBreakpoint(addr & this.nBlockLimit, fWrite);\n }\n }\n\n /**\n * removeMemBreak(addr, fWrite)\n *\n * @this {BusPDP11}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint\n */\n removeMemBreak(addr, fWrite)\n {\n if (DEBUGGER) {\n var iBlock = addr >>> this.nBlockShift;\n this.aBusBlocks[iBlock].removeBreakpoint(addr & this.nBlockLimit, fWrite);\n }\n }\n\n /**\n * saveMemory(fAll)\n *\n * The only memory blocks we save are those marked as dirty, but most likely all of RAM will have been marked dirty,\n * and even if our dirty-memory flags were as smart as our dirty-sector flags (ie, were set only when a write changed\n * what was already there), it's unlikely that would reduce the number of RAM blocks we must save/restore. At least\n * all the ROM blocks should be clean (except in the unlikely event that the Debugger was used to modify them).\n *\n * All dirty blocks will be stored in a single array, as pairs of block numbers and data arrays, like so:\n *\n * [iBlock0, [dw0, dw1, ...], iBlock1, [dw0, dw1, ...], ...]\n *\n * In a normal 4Kb block, there will be 1K DWORD values in the data array. Remember that each DWORD is a signed 32-bit\n * integer (because they are formed using bitwise operator rather than floating-point math operators), so don't be\n * surprised to see negative numbers in the data.\n *\n * The above example assumes \"uncompressed\" data arrays. If we choose to use \"compressed\" data arrays, the data arrays\n * will look like:\n *\n * [count0, dw0, count1, dw1, ...]\n *\n * where each count indicates how many times the following DWORD value occurs. A data array length less than 1K indicates\n * that it's compressed, since we'll only store them in compressed form if they actually shrank, and we'll use State\n * helper methods compress() and decompress() to create and expand the compressed data arrays.\n *\n * @this {BusPDP11}\n * @param {boolean} [fAll] (true to save all non-ROM memory blocks, regardless of their dirty flags)\n * @return {Array} a\n */\n saveMemory(fAll)\n {\n var i = 0;\n var a = [];\n\n for (var iBlock = 0; iBlock < this.nBlockTotal; iBlock++) {\n var block = this.aBusBlocks[iBlock];\n /*\n * We have to check both fDirty and fDirtyEver, because we may have called cleanMemory() on some of\n * the memory blocks (eg, video memory), and while cleanMemory() will clear a dirty block's fDirty flag,\n * it also sets the dirty block's fDirtyEver flag, which is left set for the lifetime of the machine.\n */\n if (fAll && block.type != MemoryPDP11.TYPE.ROM || block.fDirty || block.fDirtyEver) {\n a[i++] = iBlock;\n a[i++] = State.compress(block.save());\n }\n }\n\n return a;\n }\n\n /**\n * restoreMemory(a)\n *\n * This restores the contents of all Memory blocks; called by CPUState.restore().\n *\n * In theory, we ONLY have to save/restore block contents. Other block attributes,\n * like the type, the memory controller (if any), and the active memory access functions,\n * should already be restored, since every component (re)allocates all the memory blocks\n * it was using when it's restored. And since the CPU is guaranteed to be the last\n * component to be restored, all those blocks (and their attributes) should be in place now.\n *\n * See saveMemory() for more information on how the memory block contents are saved.\n *\n * @this {BusPDP11}\n * @param {Array} a\n * @return {boolean} true if successful, false if not\n */\n restoreMemory(a)\n {\n var i;\n for (i = 0; i < a.length - 1; i += 2) {\n var iBlock = a[i];\n var adw = a[i+1];\n if (adw && adw.length < this.nBlockLen) {\n adw = State.decompress(adw, this.nBlockLen);\n }\n var block = this.aBusBlocks[iBlock];\n if (!block || !block.restore(adw)) {\n /*\n * Either the block to restore hasn't been allocated, indicating a change in the machine\n * configuration since it was last saved (the most likely explanation) or there's some internal\n * inconsistency (eg, the block size is wrong).\n */\n Component.error(\"Unable to restore memory block \" + iBlock);\n return false;\n }\n }\n return true;\n }\n\n /**\n * getMemoryLimit(type)\n *\n * @this {BusPDP11}\n * @param {number} type is one of the MemoryPDP11.TYPE constants\n * @return {number} (the limiting address of the specified memory type, zero if none)\n */\n getMemoryLimit(type)\n {\n var addr = 0;\n for (var iBlock = 0; iBlock < this.aBusBlocks.length; iBlock++) {\n var block = this.aBusBlocks[iBlock];\n if (block.type == type) {\n addr = block.addr + block.used;\n }\n }\n return addr;\n }\n\n /**\n * addIOHandlers(start, end, fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, message, sName)\n *\n * Add I/O notification handlers to the master list (aIOHandlers). The start and end addresses are typically\n * relative to the starting IOPAGE address, but they can also be absolute; we simply mask all addresses with\n * IOPAGE_MASK.\n *\n * CAVEATS: If a conflict is reported, a partial set of handlers may still have been added. There is no mechanism\n * for removing handlers, since this is considered an initialization function. And finally, when a range of addresses\n * is used, each successive address is advanced by 2, so if you really want to add a handler for a \"+1\" (usually odd)\n * address, then you must add it individually. Failure to do is not necessarily fatal, because the IOController's\n * fallback behavior for an odd address is to call the byte handler for the preceding even address, but the byte\n * handler must be prepared for that (the handlers installed by ROM component's addROM() function are a good example).\n *\n * @this {BusPDP11}\n * @param {number} start address\n * @param {number} end address\n * @param {function(number)|null|undefined} fnReadByte\n * @param {function(number,number)|null|undefined} fnWriteByte\n * @param {function(number)|null|undefined} fnReadWord\n * @param {function(number,number)|null|undefined} fnWriteWord\n * @param {number} [message]\n * @param {string} [sName]\n * @return {boolean} (true if entire range successfully registered, false if any conflicts)\n */\n addIOHandlers(start, end, fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, message, sName)\n {\n var index = (start == end? -1 : 0);\n for (var addr = start; addr <= end; addr += 2) {\n var off = addr & BusPDP11.IOPAGE_MASK;\n if (this.aIOHandlers[off] !== undefined) {\n Component.warning(\"I/O address already registered: \" + Str.toHexLong(addr));\n return false;\n }\n var s = sName || \"unknown\";\n if (s && index >= 0) s += index++;\n this.aIOHandlers[off] = [fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, s, message || MessagesPDP11.BUS, false];\n if (MAXDEBUG) this.log(\"addIOHandlers(\" + Str.toHexLong(addr) + \")\");\n }\n return true;\n }\n\n /**\n * addIOTable(component, table, offReg)\n *\n * Add I/O notification handlers from the specified table (a batch version of addIOHandlers).\n *\n * @this {BusPDP11}\n * @param {Component} component\n * @param {Object} table\n * @param {number} [offReg] (optional offset to add to all register addresses)\n * @return {boolean} (true if entire range successfully registered, false if any conflicts)\n */\n addIOTable(component, table, offReg)\n {\n for (var reg in table) {\n var addr = +reg + (offReg || 0);\n var afn = table[reg];\n\n /*\n * Don't install (ie, ignore) handlers for I/O addresses that are defined with a model number\n * that is \"greater than\" than the current model.\n */\n if (afn[6] && afn[6] > this.cpu.model) continue;\n\n var fnReadByte = afn[0]? afn[0].bind(component) : null;\n var fnWriteByte = afn[1]? afn[1].bind(component) : null;\n var fnReadWord = afn[2]? afn[2].bind(component) : null;\n var fnWriteWord = afn[3]? afn[3].bind(component) : null;\n\n /*\n * As discussed in the IOController comments below, when handlers are being registered for these\n * BYTE-granular UNIBUS addresses, we must install custom fallback handlers for all BYTE accesses.\n */\n if (addr >= PDP11.UNIBUS.R0SET0 && addr <= PDP11.UNIBUS.R6USER) {\n if (!fnReadByte && fnReadWord) {\n fnReadByte = function readByteIORegister(readWord) {\n return function(addr) {\n return readWord(addr) & 0xff;\n }.bind(component);\n }(fnReadWord);\n }\n if (!fnWriteByte && fnWriteWord) {\n fnWriteByte = function writeByteIORegister(writeWord) {\n return function(data, addr) {\n return writeWord(data, addr);\n }.bind(component);\n }(fnWriteWord);\n }\n }\n\n var sReg = afn[4];\n var nRegs = afn[5] || 1;\n\n for (var iReg = 0; iReg < nRegs; iReg++, addr += 2) {\n if (sReg && nRegs > 1) sReg = afn[4] + iReg;\n if (!this.addIOHandlers(addr, addr, fnReadByte, fnWriteByte, fnReadWord, fnWriteWord, afn[7] || component.bitsMessage, sReg || component.idComponent)) {\n return false;\n }\n }\n }\n return true;\n }\n\n /**\n * getAddrInfo(addr)\n *\n * Determine if the physical address is a known IOPAGE address, and return information about it (ie, the name).\n *\n * @this {BusPDP11}\n * @param {number} addr (physical)\n * @return {string|null}\n */\n getAddrInfo(addr)\n {\n var sName = null;\n if (addr >= this.addrIOPage) {\n var off = addr & BusPDP11.IOPAGE_MASK;\n var afn = this.aIOHandlers[off];\n if (afn) sName = afn[BusPDP11.IOHANDLER.REG_NAME];\n }\n return sName;\n }\n\n /**\n * getAddrByName(sName)\n *\n * Determine if the specified name has a corresponding physical address.\n *\n * @this {BusPDP11}\n * @param {string} sName\n * @return {number|null}\n */\n getAddrByName(sName)\n {\n sName = sName.toUpperCase();\n for (var i in this.aIOHandlers) {\n var off = +i;\n var afn = this.aIOHandlers[off];\n if (afn[BusPDP11.IOHANDLER.REG_NAME] == sName) {\n return this.addrIOPage + off;\n }\n }\n return null;\n }\n\n /**\n * addResetHandler(fnReset)\n *\n * @this {BusPDP11}\n * @param {function()} fnReset\n */\n addResetHandler(fnReset)\n {\n this.afnReset.push(fnReset);\n }\n\n /**\n * fault(addr, err, access)\n *\n * Bus interface for signaling alignment errors, invalid memory, etc.\n *\n * @this {BusPDP11}\n * @param {number} addr\n * @param {number} [err]\n * @param {number} [access] (for diagnostic purposes only)\n */\n fault(addr, err, access)\n {\n this.fFault = true;\n if (!this.nDisableFaults) {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.FAULT)) {\n this.dbg.printMessage(\"memory fault (\" + access + \") on \" + this.dbg.toStrBase(addr), true, true);\n }\n if (err) this.cpu.regErr |= err;\n this.cpu.trap(PDP11.TRAP.BUS, 0, addr);\n }\n }\n\n /**\n * checkFault()\n *\n * This also serves as a clearFault() function.\n *\n * @this {BusPDP11}\n * @return {boolean}\n */\n checkFault()\n {\n var f = this.fFault;\n this.fFault = false;\n return f;\n }\n\n /**\n * reportError(errNum, addr, size, fQuiet)\n *\n * @this {BusPDP11}\n * @param {number} errNum\n * @param {number} addr\n * @param {number} size\n * @param {boolean} [fQuiet] (true if any error should be quietly logged)\n * @return {boolean} false\n */\n reportError(errNum, addr, size, fQuiet)\n {\n var sError = \"Memory block error (\" + errNum + \": \" + Str.toHex(addr) + \",\" + Str.toHex(size) + \")\";\n if (fQuiet) {\n if (this.dbg) {\n this.dbg.message(sError);\n } else {\n this.log(sError);\n }\n } else {\n Component.error(sError);\n }\n return false;\n }\n}\n\nBusPDP11.IOPAGE_16BIT = 0x00E000; /*000160000*/ // eg, PDP-11/20\nBusPDP11.IOPAGE_18BIT = 0x03E000; /*000760000*/ // eg, PDP-11/45\nBusPDP11.IOPAGE_22BIT = 0x3FE000; /*017760000*/ // eg, PDP-11/70\nBusPDP11.IOPAGE_LENGTH = 0x002000; // ie, 8Kb\nBusPDP11.IOPAGE_MASK = BusPDP11.IOPAGE_LENGTH - 1;\n\nBusPDP11.MASK_18BIT = 0x03FFFF; /*000777777*/\n\nBusPDP11.UNIBUS_22BIT = 0x3C0000; /*017000000*/\nBusPDP11.MASK_22BIT = 0x3FFFFF; /*017777777*/\n\nBusPDP11.ERROR = {\n RANGE_INUSE: 1,\n RANGE_INVALID: 2,\n NO_CONTROLLER: 3\n};\n\n/*\n * Every entry in the aIOHandlers table is an array with the following indexes:\n */\nBusPDP11.IOHANDLER = {\n READ_BYTE: 0,\n WRITE_BYTE: 1,\n READ_WORD: 2,\n WRITE_WORD: 3,\n REG_NAME: 4,\n MSG_CATEGORY: 5,\n DBG_BREAK: 6\n};\n\n/*\n * These are our custom IOController functions for all IOPAGE accesses. They look up the IOPAGE\n * offset in the aIOHandlers table, and if an entry exists, they use the appropriate IOHANDLER indexes\n * (above) to locate the registered read/write handlers. If no handler is found, then fault() will\n * be called, triggering a trap -- unless traps are disabled because direct access was requested\n * (eg, by the Debugger).\n *\n * Handlers receive the original IOPAGE address that was used, although in most cases, it's ignored,\n * because most handlers usually handle only one address. Only handlers used for a range of addresses\n * must pay attention to it.\n *\n * Note that these functions include fallbacks for byte reads when only word read handlers exist (by\n * masking or shifting the result) and for word reads if only byte handlers exist (by combining bytes).\n * Fallbacks for writes exist, too, but they are slightly more complicated, because a byte write using\n * a word write handler requires reading the word first, and then updating the appropriate byte within\n * that word.\n *\n * Those fallbacks may not always be appropriate; for example, byte writes to some device registers\n * must be zero-extended to update the entire word. For those cases, the fallback's \"preliminary\" read\n * is issued with a fPreWrite flag so that the handler can distinguish a normal read from one of these\n * preliminary reads (aka read-before-write), and return an appropriate value for the update (eg, zero).\n *\n * If none of these fallback behaviors are appropriate, the device has a simple recourse: register\n * handlers for all possible addresses and sizes.\n *\n * Unlike regular Memory blocks, IOPAGE accesses permit word accesses on ODD addresses; that works\n * just fine by registering WORD handlers for the appropriate ODD addresses. For BYTE accesses, it\n * depends. For CPU register addresses, addIOHandlers() installs special byte handlers that perform\n * either a simple word read or write. Other addresses must be handled on a case-by-case basis.\n *\n * TODO: Another small potential improvement would be for addIOHandlers() to install fallbacks for ALL\n * missing handlers, in both the ODD and EVEN cases, so there's never a need to check each function index\n * before calling it. However, since there's no avoiding checking aIOHandlers[off] (unless we FULLY populate\n * the aIOHandlers array), and since these I/O accesses should be pretty infrequent relative to all other\n * memory accesses, the benefit seems pretty minimal. Plus, all our fallback assumptions still need to be\n * verified, so let's wait until that's done before we start optimizing this code.\n */\nBusPDP11.IOController = {\n /**\n * readByte(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByte: function(off, addr)\n {\n var b = -1;\n var bus = this.controller;\n var afn = bus.aIOHandlers[off];\n\n /*\n * Since addr is primarily used to advise an I/O handler of the target IOPAGE address, and since we don't want\n * our handlers to worry about the current IOPAGE location, we truncate addr to 16 bits (the IOPAGE's lowest location).\n */\n var addrMasked = addr & 0xffff;\n\n if (afn) {\n if (afn[BusPDP11.IOHANDLER.READ_BYTE]) {\n b = afn[BusPDP11.IOHANDLER.READ_BYTE](addrMasked);\n } else if (afn[BusPDP11.IOHANDLER.READ_WORD]) {\n if (!(addrMasked & 0x1)) {\n b = afn[BusPDP11.IOHANDLER.READ_WORD](addrMasked) & 0xff;\n } else {\n b = afn[BusPDP11.IOHANDLER.READ_WORD](addrMasked & ~0x1) >> 8;\n }\n }\n } else if (addrMasked & 0x1) {\n afn = bus.aIOHandlers[off & ~0x1];\n if (afn) {\n if (afn[BusPDP11.IOHANDLER.READ_WORD]) {\n b = afn[BusPDP11.IOHANDLER.READ_WORD](addrMasked & ~0x1) >> 8;\n } else if (afn[BusPDP11.IOHANDLER.READ_BYTE]) {\n /*\n * WARNING: This is an unusual fall-back, because we're trying to read an ODD byte\n * access using a BYTE handler registered for EVEN bytes. But if that's all we've got,\n * then presumably the handler is prepared for it (certainly, readROMByte() is).\n */\n b = afn[BusPDP11.IOHANDLER.READ_BYTE](addrMasked)\n }\n }\n }\n if (b >= 0) {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS | afn[BusPDP11.IOHANDLER.MSG_CATEGORY])) {\n this.dbg.printMessage(afn[BusPDP11.IOHANDLER.REG_NAME] + \".readByte(\" + this.dbg.toStrBase(addr) + \"): \" + this.dbg.toStrBase(b), true, !bus.nDisableFaults);\n }\n return b;\n }\n bus.fault(addr, PDP11.CPUERR.TIMEOUT, PDP11.ACCESS.READ_BYTE);\n b = 0xff;\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS)) {\n this.dbg.printMessage(\"warning: unconverted read access to byte @\" + this.dbg.toStrBase(addr) + \": \" + this.dbg.toStrBase(b), true, !bus.nDisableFaults);\n }\n return b;\n },\n\n /**\n * writeByte(off, b, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} b (which should already be pre-masked to 8 bits)\n * @param {number} addr\n */\n writeByte: function(off, b, addr)\n {\n var w;\n var fWrite = false;\n var bus = this.controller;\n var afn = bus.aIOHandlers[off];\n\n /*\n * Since addr is primarily used to advise an I/O handler of the target IOPAGE address, and since we don't want\n * our handlers to worry about the current IOPAGE location, we truncate addr to 16 bits (the IOPAGE's lowest location).\n */\n var addrMasked = addr & 0xffff;\n\n if (afn) {\n /*\n * If a writeByte() handler exists, call it; we're done.\n */\n if (afn[BusPDP11.IOHANDLER.WRITE_BYTE]) {\n afn[BusPDP11.IOHANDLER.WRITE_BYTE](b, addrMasked);\n fWrite = true;\n }\n /*\n * If a writeWord() handler exists, call the readWord() handler first to get the original data\n * (with fPreWrite set to true) and call writeWord() with the new data inserted into the original data.\n */\n else if (afn[BusPDP11.IOHANDLER.WRITE_WORD]) {\n w = afn[BusPDP11.IOHANDLER.READ_WORD]? afn[BusPDP11.IOHANDLER.READ_WORD](addrMasked, true) : 0;\n if (!(addrMasked & 0x1)) {\n afn[BusPDP11.IOHANDLER.WRITE_WORD]((w & ~0xff) | b, addrMasked);\n fWrite = true;\n } else {\n afn[BusPDP11.IOHANDLER.WRITE_WORD]((w & 0xff) | (b << 8), addrMasked & ~0x1);\n fWrite = true;\n }\n }\n } else if (addrMasked & 0x1) {\n /*\n * If no handler existed, and this address was odd, then perhaps a handler exists for the even address;\n * if so, call the readWord() handler first to get the original data (with fPreWrite set to true) and call\n * writeWord() with the new data inserted into (the high byte of) the original data.\n */\n afn = bus.aIOHandlers[off & ~0x1];\n if (afn) {\n if (afn[BusPDP11.IOHANDLER.WRITE_WORD]) {\n addrMasked &= ~0x1;\n w = afn[BusPDP11.IOHANDLER.READ_WORD]? afn[BusPDP11.IOHANDLER.READ_WORD](addrMasked, true) : 0;\n afn[BusPDP11.IOHANDLER.WRITE_WORD]((w & 0xff) | (b << 8), addrMasked);\n fWrite = true;\n } else if (afn[BusPDP11.IOHANDLER.WRITE_BYTE]) {\n /*\n * WARNING: This is an unusual fall-back, because we're trying to write an ODD byte\n * access using a BYTE handler registered for EVEN bytes. But if that's all we've got,\n * then presumably the handler is prepared for it (certainly, writeROMByte() is).\n */\n afn[BusPDP11.IOHANDLER.WRITE_BYTE](b, addrMasked);\n fWrite = true;\n }\n }\n }\n if (fWrite) {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS | afn[BusPDP11.IOHANDLER.MSG_CATEGORY])) {\n this.dbg.printMessage(afn[BusPDP11.IOHANDLER.REG_NAME] + \".writeByte(\" + this.dbg.toStrBase(addr) + \",\" + this.dbg.toStrBase(b) + \")\", true, !bus.nDisableFaults);\n }\n return;\n }\n bus.fault(addr, PDP11.CPUERR.TIMEOUT, PDP11.ACCESS.WRITE_BYTE);\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS)) {\n this.dbg.printMessage(\"warning: unconverted write access to byte @\" + this.dbg.toStrBase(addr) + \": \" + this.dbg.toStrBase(b), true, !bus.nDisableFaults);\n }\n },\n\n /**\n * readWord(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readWord: function(off, addr)\n {\n var w = -1;\n var bus = this.controller;\n var afn = bus.aIOHandlers[off];\n\n /*\n * Since addr is primarily used to advise an I/O handler of the target IOPAGE address, and since we don't want\n * our handlers to worry about the current IOPAGE location, we truncate addr to 16 bits (the IOPAGE's lowest location).\n */\n var addrMasked = addr & 0xffff;\n\n if (afn) {\n if (afn[BusPDP11.IOHANDLER.READ_WORD]) {\n w = afn[BusPDP11.IOHANDLER.READ_WORD](addrMasked);\n } else if (afn[BusPDP11.IOHANDLER.READ_BYTE]) {\n w = afn[BusPDP11.IOHANDLER.READ_BYTE](addrMasked) | (afn[BusPDP11.IOHANDLER.READ_BYTE](addrMasked + 1) << 8);\n }\n }\n if (w >= 0) {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS | afn[BusPDP11.IOHANDLER.MSG_CATEGORY])) {\n this.dbg.printMessage(afn[BusPDP11.IOHANDLER.REG_NAME] + \".readWord(\" + this.dbg.toStrBase(addr) + \"): \" + this.dbg.toStrBase(w), true, !bus.nDisableFaults);\n }\n return w;\n }\n bus.fault(addr, PDP11.CPUERR.TIMEOUT, PDP11.ACCESS.READ_WORD);\n w = 0xffff;\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS)) {\n this.dbg.printMessage(\"warning: unconverted read access to word @\" + this.dbg.toStrBase(addr) + \": \" + this.dbg.toStrBase(w), true, !bus.nDisableFaults);\n }\n return w;\n },\n\n /**\n * writeWord(off, w, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} w (which should already be pre-masked to 16 bits)\n * @param {number} addr\n */\n writeWord: function(off, w, addr)\n {\n var fWrite = false;\n var bus = this.controller;\n var afn = bus.aIOHandlers[off];\n\n /*\n * Since addr is primarily used to advise an I/O handler of the target IOPAGE address, and since we don't want\n * our handlers to worry about the current IOPAGE location, we truncate addr to 16 bits (the IOPAGE's lowest location).\n */\n var addrMasked = addr & 0xffff;\n\n if (afn) {\n if (afn[BusPDP11.IOHANDLER.WRITE_WORD]) {\n afn[BusPDP11.IOHANDLER.WRITE_WORD](w, addrMasked);\n fWrite = true;\n } else if (afn[BusPDP11.IOHANDLER.WRITE_BYTE]) {\n afn[BusPDP11.IOHANDLER.WRITE_BYTE](w & 0xff, addrMasked);\n afn[BusPDP11.IOHANDLER.WRITE_BYTE](w >> 8, addrMasked + 1);\n fWrite = true;\n }\n }\n if (fWrite) {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS | afn[BusPDP11.IOHANDLER.MSG_CATEGORY])) {\n this.dbg.printMessage(afn[BusPDP11.IOHANDLER.REG_NAME] + \".writeWord(\" + this.dbg.toStrBase(addr) + \",\" + this.dbg.toStrBase(w) + \")\", true, !bus.nDisableFaults);\n }\n return;\n }\n bus.fault(addr, PDP11.CPUERR.TIMEOUT, PDP11.ACCESS.WRITE_WORD);\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.BUS)) {\n this.dbg.printMessage(\"warning: unconverted write access to word @\" + this.dbg.toStrBase(addr) + \": \" + this.dbg.toStrBase(w), true, !bus.nDisableFaults);\n }\n }\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/device.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass DevicePDP11 extends Component {\n /**\n * DevicePDP11(parmsDevice)\n *\n * The Device component implements the following \"default\" devices:\n *\n * KW11 (KW11-L Line Time Clock)\n *\n * as well providing access to all the MMU and CPU registers, PSW, etc.\n *\n * @param {Object} parmsDevice\n */\n constructor(parmsDevice)\n {\n super(\"Device\", parmsDevice, MessagesPDP11.DEVICE);\n\n this.kw11 = { // KW11 registers\n lks: PDP11.KW11.LKS.MON,\n timer: -1 // initBus() will initialize this timer ID\n };\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {DevicePDP11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cmp = cmp;\n this.cpu = cpu;\n this.dbg = dbg;\n\n var device = this;\n this.kw11.timer = cpu.addTimer(function() {\n device.interruptKW11();\n });\n\n this.kw11.irq = cpu.addIRQ(PDP11.KW11.VEC, PDP11.KW11.PRI, MessagesPDP11.KW11);\n\n bus.addIOTable(this, DevicePDP11.UNIBUS_IOTABLE);\n bus.addResetHandler(this.reset.bind(this));\n\n if (DEBUGGER && dbg) {\n dbg.messageDump(MessagesPDP11.MMU, function onDumpMMU(asArgs) {\n device.dumpMMU(asArgs);\n });\n }\n this.setReady();\n }\n\n /**\n * dumpMMU(asArgs)\n *\n * @this {DevicePDP11}\n * @param {Array.<string>} asArgs\n */\n dumpMMU(asArgs)\n {\n if (DEBUGGER) {\n var cpu = this.cpu;\n this.dumpRegs(\"KIPDR\", cpu.regsPDR[0], 0, asArgs[0]);\n this.dumpRegs(\"KDPDR\", cpu.regsPDR[0], 8, asArgs[0]);\n this.dumpRegs(\"KIPAR\", cpu.regsPAR[0], 0, asArgs[0]);\n this.dumpRegs(\"KDPAR\", cpu.regsPAR[0], 8, asArgs[0], true);\n this.dumpRegs(\"SIPDR\", cpu.regsPDR[1], 0, asArgs[0]);\n this.dumpRegs(\"SDPDR\", cpu.regsPDR[1], 8, asArgs[0]);\n this.dumpRegs(\"SIPAR\", cpu.regsPAR[1], 0, asArgs[0]);\n this.dumpRegs(\"SDPAR\", cpu.regsPAR[1], 8, asArgs[0], true);\n this.dumpRegs(\"UIPDR\", cpu.regsPDR[3], 0, asArgs[0]);\n this.dumpRegs(\"UDPDR\", cpu.regsPDR[3], 8, asArgs[0]);\n this.dumpRegs(\"UIPAR\", cpu.regsPAR[3], 0, asArgs[0]);\n this.dumpRegs(\"UDPAR\", cpu.regsPAR[3], 8, asArgs[0], true);\n if (cpu.regMMR3 & PDP11.MMR3.UNIBUS_MAP) {\n this.dumpRegs(\"UNIMAP\", cpu.regsUniMap, -1, asArgs[0]);\n }\n }\n }\n\n /**\n * dumpRegs(sName, aRegs, offset, sFilter, fBreak)\n *\n * @this {DevicePDP11}\n * @param {string} sName\n * @param {Array.<number>} aRegs\n * @param {number} offset\n * @param {string} sFilter\n * @param {boolean} [fBreak]\n */\n dumpRegs(sName, aRegs, offset, sFilter, fBreak)\n {\n if (DEBUGGER) {\n var dbg = this.dbg;\n if (sFilter && sName.indexOf(sFilter.toUpperCase()) < 0) return;\n var nBits = 0;\n var nRegs = 8;\n var sDump = \"\";\n var fIndex = false;\n var nWidth = 8;\n if (offset < 0) {\n nBits = 22;\n nRegs = aRegs.length;\n offset = 0;\n fIndex = true;\n nWidth = 4;\n }\n for (var i = 0; i < nRegs; i++) {\n if (i % nWidth == 0) {\n if (sDump) sDump += '\\n';\n sDump += sName + (fIndex? ('[' + Str.toDec(i, 2) + ']') : '') + ':';\n }\n sDump += ' ' + dbg.toStrBase(aRegs[offset + i], nBits);\n }\n dbg.println(sDump + (fBreak? '\\n' : ''));\n }\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {DevicePDP11}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {DevicePDP11}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {DevicePDP11}\n */\n reset()\n {\n this.kw11.lks = PDP11.KW11.LKS.MON;\n this.cpu.setTimer(this.kw11.timer, 1000/60, true);\n }\n\n /**\n * save()\n *\n * This implements save support for the DevicePDP11 component.\n *\n * @this {DevicePDP11}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, [\n this.kw11.lks\n ]);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the DevicePDP11 component.\n *\n * @this {DevicePDP11}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n /*\n * ES6 ALERT: A handy destructuring assignment, which makes it easy to perform the inverse\n * of what save() does when it collects a bunch of object properties into an array.\n */\n [\n this.kw11.lks\n ] = data[0];\n\n return true;\n }\n\n /**\n * interruptKW11()\n *\n * We used to call this function only when the the KW11's \"Interrupt Enable\" bit was set,\n * but now we call it at 60Hz regardless. In part, this was so we could piggy-back on it\n * to drive display updates, but more importantly, the KW11's \"Monitor\" bit is supposed to\n * be set at the \"line frequency\" independent of whether KW11 interrupts are enabled or not.\n *\n * @this {DevicePDP11}\n */\n interruptKW11()\n {\n this.kw11.lks |= PDP11.KW11.LKS.MON;\n if (this.kw11.lks & PDP11.KW11.LKS.IE) {\n this.cpu.setIRQ(this.kw11.irq);\n }\n if (this.cmp) this.cmp.updateDisplays(1);\n this.cpu.setTimer(this.kw11.timer, 1000/60);\n }\n\n /**\n * readLKS(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.LKS or 177546)\n * @return {number}\n */\n readLKS(addr)\n {\n /*\n * NOTE: The original code always cleared LKS.MON (bit 7) after snapping the value for the read,\n * but based on DEC's \"Non-Interrupt Mode\" programming examples, it's clear that's not how LKS.MON\n * operates; if the caller wants to clear it, they must explicitly clear it with a write.\n */\n return this.kw11.lks;\n }\n\n /**\n * writeLKS(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.LKS or 177546)\n */\n writeLKS(data, addr)\n {\n /*\n * NOTE: The original code always cleared LKS.MON (bit 7) as part of any write, but based on DEC's\n * \"Non-Interrupt Mode\" programming examples, which explicitly CLRB after TSTB reveals LKS.MON is set,\n * I think that was wrong, and that all a write should do is mask off all the other (non-writable) bits.\n */\n this.kw11.lks = data & PDP11.KW11.LKS.MASK;\n if (!(this.kw11.lks & PDP11.KW11.LKS.IE)) this.cpu.clearIRQ(this.kw11.irq);\n }\n\n /**\n * readMMR0(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.MMR0 or 177572)\n * @return {number}\n */\n readMMR0(addr)\n {\n return this.cpu.getMMR0();\n }\n\n /**\n * writeMMR0(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.MMR0 or 177572)\n */\n writeMMR0(data, addr)\n {\n this.cpu.setMMR0((data & ~PDP11.MMR0.COMPLETED) | (this.cpu.regMMR0 & PDP11.MMR0.COMPLETED));\n }\n\n /**\n * readMMR1(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.MMR1 or 177574)\n * @return {number}\n */\n readMMR1(addr)\n {\n return this.cpu.getMMR1();\n }\n\n /**\n * readMMR2(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.MMR2 or 177576)\n * @return {number}\n */\n readMMR2(addr)\n {\n return this.cpu.getMMR2();\n }\n\n /**\n * readMMR3(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.MMR3 or 172516)\n * @return {number}\n */\n readMMR3(addr)\n {\n return this.cpu.getMMR3();\n }\n\n /**\n * writeMMR3(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.MMR3 or 172516)\n */\n writeMMR3(data, addr)\n {\n this.cpu.setMMR3(data);\n }\n\n /**\n * readUNIMAP(addr)\n *\n * NOTE: The UNIBUS map (\"UNIMAP\") is 32 registers spread across 64 words, so we first calculate the word index.\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.UNIMAP)\n * @return {number}\n */\n readUNIMAP(addr)\n {\n var word = (addr >> 1) & 0x3f, reg = word >> 1;\n var data = this.cpu.regsUniMap[reg];\n return (word & 1)? (data >> 16) : (data & 0xffff);\n }\n\n /**\n * writeUNIMAP(data, addr)\n *\n * NOTE: The UNIBUS map (\"UNIMAP\") is 32 registers spread across 64 words, so we first calculate the word index.\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.UNIMAP)\n */\n writeUNIMAP(data, addr)\n {\n var word = (addr >> 1) & 0x3f, reg = word >> 1;\n if (word & 1) {\n this.cpu.regsUniMap[reg] = (this.cpu.regsUniMap[reg] & 0xffff) | ((data & 0x003f) << 16);\n } else {\n this.cpu.regsUniMap[reg] = (this.cpu.regsUniMap[reg] & ~0xffff) | (data & 0xfffe);\n }\n }\n\n /**\n * readSIPDR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.SIPDR0--SIPDR7 or 172200--172216)\n * @return {number}\n */\n readSIPDR(addr)\n {\n var reg = (addr >> 1) & 7;\n return this.cpu.regsPDR[1][reg];\n }\n\n /**\n * writeSIPDR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.SIPDR0--SIPDR7 or 172200--172216)\n */\n writeSIPDR(data, addr)\n {\n var reg = (addr >> 1) & 7;\n this.cpu.regsPDR[1][reg] = data & 0xff0f;\n }\n\n /**\n * readSDPDR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.SDPDR0--SDPDR7 or 172220--172236)\n * @return {number}\n */\n readSDPDR(addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n return this.cpu.regsPDR[1][reg];\n }\n\n /**\n * writeSDPDR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.SDPDR0--SDPDR7 or 172220--172236)\n */\n writeSDPDR(data, addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n this.cpu.regsPDR[1][reg] = data & 0xff0f;\n }\n\n /**\n * readSIPAR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.SIPAR0--SIPAR7 or 172240--172256)\n * @return {number}\n */\n readSIPAR(addr)\n {\n var reg = (addr >> 1) & 7;\n return this.cpu.regsPAR[1][reg];\n }\n\n /**\n * writeSIPAR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.SIPAR0--SIPAR7 or 172240--172256)\n */\n writeSIPAR(data, addr)\n {\n var reg = (addr >> 1) & 7;\n this.cpu.regsPAR[1][reg] = data;\n this.cpu.regsPDR[1][reg] &= 0xff0f;\n\n }\n\n /**\n * readSDPAR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.SDPAR0--SDPAR7 or 172260--172276)\n * @return {number}\n */\n readSDPAR(addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n return this.cpu.regsPAR[1][reg];\n }\n\n /**\n * writeSDPAR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.SDPAR0--SDPAR7 or 172260--172276)\n */\n writeSDPAR(data, addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n this.cpu.regsPAR[1][reg] = data;\n this.cpu.regsPDR[1][reg] &= 0xff0f;\n }\n\n /**\n * readKIPDR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.KIPDR0--KIPDR7 or 172300--172316)\n * @return {number}\n */\n readKIPDR(addr)\n {\n var reg = (addr >> 1) & 7;\n return this.cpu.regsPDR[0][reg];\n }\n\n /**\n * writeKIPDR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.KIPDR0--KIPDR7 or 172300--172316)\n */\n writeKIPDR(data, addr)\n {\n var reg = (addr >> 1) & 7;\n this.cpu.regsPDR[0][reg] = data & 0xff0f;\n }\n\n /**\n * readKDPDR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.KDPDR0--KDPDR7 or 172320--172336)\n * @return {number}\n */\n readKDPDR(addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n return this.cpu.regsPDR[0][reg];\n }\n\n /**\n * writeKDPDR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.KDPDR0--KDPDR7 or 172320--172336)\n */\n writeKDPDR(data, addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n this.cpu.regsPDR[0][reg] = data & 0xff0f;\n }\n\n /**\n * readKIPAR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.KIPAR0--KIPAR7 or 172340--172356)\n * @return {number}\n */\n readKIPAR(addr)\n {\n var reg = (addr >> 1) & 7;\n return this.cpu.regsPAR[0][reg];\n }\n\n /**\n * writeKIPAR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.KIPAR0--KIPAR7 or 172340--172356)\n */\n writeKIPAR(data, addr)\n {\n var reg = (addr >> 1) & 7;\n this.cpu.regsPAR[0][reg] = data;\n this.cpu.regsPDR[0][reg] &= 0xff0f;\n\n }\n\n /**\n * readKDPAR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.KDPAR0--KDPAR7 or 172360--172376)\n * @return {number}\n */\n readKDPAR(addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n return this.cpu.regsPAR[0][reg];\n }\n\n /**\n * writeKDPAR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.KDPAR0--KDPAR7 or 172360--172376)\n */\n writeKDPAR(data, addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n this.cpu.regsPAR[0][reg] = data;\n this.cpu.regsPDR[0][reg] &= 0xff0f;\n }\n\n /**\n * readUIPDR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.UIPDR0--UIPDR7 or 177600--177616)\n * @return {number}\n */\n readUIPDR(addr)\n {\n var reg = (addr >> 1) & 7;\n return this.cpu.regsPDR[3][reg];\n }\n\n /**\n * writeUIPDR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.UIPDR0--UIPDR7 or 177600--177616)\n */\n writeUIPDR(data, addr)\n {\n var reg = (addr >> 1) & 7;\n this.cpu.regsPDR[3][reg] = data & 0xff0f;\n }\n\n /**\n * readUDPDR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.UDPDR0--UDPDR7 or 177620--177636)\n * @return {number}\n */\n readUDPDR(addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n return this.cpu.regsPDR[3][reg];\n }\n\n /**\n * writeUDPDR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.UDPDR0--UDPDR7 or 177620--177636)\n */\n writeUDPDR(data, addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n this.cpu.regsPDR[3][reg] = data & 0xff0f;\n }\n\n /**\n * readUIPAR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.UIPAR0--UIPAR7 or 177640--177656)\n * @return {number}\n */\n readUIPAR(addr)\n {\n var reg = (addr >> 1) & 7;\n return this.cpu.regsPAR[3][reg];\n }\n\n /**\n * writeUIPAR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.UIPAR0--UIPAR7 or 177640--177656)\n */\n writeUIPAR(data, addr)\n {\n var reg = (addr >> 1) & 7;\n this.cpu.regsPAR[3][reg] = data;\n this.cpu.regsPDR[3][reg] &= 0xff0f;\n\n }\n\n /**\n * readUDPAR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.UDPAR0--UDPAR7 or 177660--177676)\n * @return {number}\n */\n readUDPAR(addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n return this.cpu.regsPAR[3][reg];\n }\n\n /**\n * writeUDPAR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.UDPAR0--UDPAR7 or 177660--177676)\n */\n writeUDPAR(data, addr)\n {\n var reg = ((addr >> 1) & 7) + 8;\n this.cpu.regsPAR[3][reg] = data;\n this.cpu.regsPDR[3][reg] &= 0xff0f;\n }\n\n /**\n * readRSET0(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.R0SET0--R5SET0 or 177700--177705)\n * @return {number}\n */\n readRSET0(addr)\n {\n var data;\n var reg = addr & 7;\n if (this.cpu.regPSW & PDP11.PSW.REGSET) {\n data = this.cpu.regsAlt[reg];\n } else {\n data = this.cpu.regsGen[reg];\n }\n return data;\n }\n\n /**\n * writeRSET0(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.R0SET0--R5SET0 or 177700--177705)\n */\n writeRSET0(data, addr)\n {\n var reg = addr & 7;\n if (this.cpu.regPSW & PDP11.PSW.REGSET) {\n this.cpu.regsAlt[reg] = data;\n } else {\n this.cpu.regsGen[reg] = data;\n }\n }\n\n /**\n * readR6KERNEL(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.R6KERNEL or 177706)\n * @return {number}\n */\n readR6KERNEL(addr)\n {\n var data;\n if (!(this.cpu.regPSW & PDP11.PSW.CMODE)) { // Kernel Mode\n data = this.cpu.regsGen[6];\n } else {\n data = this.cpu.regsAltStack[0];\n }\n return data;\n }\n\n /**\n * writeR6KERNEL(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.R6KERNEL or 177706)\n */\n writeR6KERNEL(data, addr)\n {\n if (!(this.cpu.regPSW & PDP11.PSW.CMODE)) { // Kernel Mode\n this.cpu.regsGen[6] = data;\n } else {\n this.cpu.regsAltStack[0] = data;\n }\n }\n\n /**\n * readR7KERNEL(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.R7KERNEL or 177707)\n * @return {number}\n */\n readR7KERNEL(addr)\n {\n return this.cpu.regsGen[7];\n }\n\n /**\n * writeR7KERNEL(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.R7KERNEL or 177707)\n */\n writeR7KERNEL(data, addr)\n {\n this.cpu.regsGen[7] = data;\n }\n\n /**\n * readRSET1(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.R0SET1--R5SET1 or 177710--177715)\n * @return {number}\n */\n readRSET1(addr)\n {\n var data;\n var reg = addr & 7;\n if (this.cpu.regPSW & PDP11.PSW.REGSET) {\n data = this.cpu.regsGen[reg];\n } else {\n data = this.cpu.regsAlt[reg];\n }\n return data;\n }\n\n /**\n * writeRSET1(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.R0SET1--R5SET1 or 177710--177715)\n */\n writeRSET1(data, addr)\n {\n var reg = addr & 7;\n if (this.cpu.regPSW & PDP11.PSW.REGSET) {\n this.cpu.regsGen[reg] = data;\n } else {\n this.cpu.regsAlt[reg] = data;\n }\n }\n\n /**\n * readR6SUPER(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.R6SUPER or 177716)\n * @return {number}\n */\n readR6SUPER(addr)\n {\n var data;\n if (((this.cpu.regPSW & PDP11.PSW.CMODE) >> PDP11.PSW.SHIFT.CMODE) == PDP11.MODE.SUPER) {\n data = this.cpu.regsGen[6];\n } else {\n data = this.cpu.regsAltStack[1];\n }\n return data;\n }\n\n /**\n * writeR6SUPER(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.R6SUPER or 177716)\n */\n writeR6SUPER(data, addr)\n {\n if (((this.cpu.regPSW & PDP11.PSW.CMODE) >> PDP11.PSW.SHIFT.CMODE) == PDP11.MODE.SUPER) {\n this.cpu.regsGen[6] = data;\n } else {\n this.cpu.regsAltStack[1] = data;\n }\n }\n\n /**\n * readR6USER(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.R6USER or 177717)\n * @return {number}\n */\n readR6USER(addr)\n {\n var data;\n if (((this.cpu.regPSW & PDP11.PSW.CMODE) >> PDP11.PSW.SHIFT.CMODE) == PDP11.MODE.USER) {\n data = this.cpu.regsGen[6];\n } else {\n data = this.cpu.regsAltStack[3];\n }\n return data;\n }\n\n /**\n * writeR6USER(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.R6USER or 177717)\n */\n writeR6USER(data, addr)\n {\n if (((this.cpu.regPSW & PDP11.PSW.CMODE) >> PDP11.PSW.SHIFT.CMODE) == PDP11.MODE.USER) {\n this.cpu.regsGen[6] = data;\n } else {\n this.cpu.regsAltStack[3] = data;\n }\n }\n\n /**\n * readCTRL(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.LAERR--UNDEF2 or 177740--177756)\n * @return {number}\n */\n readCTRL(addr)\n {\n var reg = (addr - PDP11.UNIBUS.CTRL) >> 1;\n return this.cpu.regsControl[reg];\n }\n\n /**\n * writeCTRL(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.LAERR--UNDEF2 or 177740--177756)\n */\n writeCTRL(data, addr)\n {\n var reg = (addr - PDP11.UNIBUS.CTRL) >> 1;\n this.cpu.regsControl[reg] = data;\n }\n\n /**\n * readSIZE(addr)\n *\n * We're adhering to DEC's documentation, which says:\n *\n * This read-only register specifies the memory size of the system. It is defined to indicate the\n * last addressable block of 32 words in memory (bit 0 is equivalent to bit 6 of the Physical Address).\n *\n * Looking at the Memory Clear \"toggle-in\" code in /devices/pdp11/machine/1170/panel/debugger/README.md, the\n * memory loop gives up when the block number stored in KIPAR0 is >= LSIZE, suggesting that LSIZE is actually\n * the total number of 64-byte blocks, rather than the block number of the last block. But that code is\n * not conclusive, since it writes 8192 bytes at a time rather than 64, so it doesn't really matter if LSIZE\n * is off by one.\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.LSIZE--HSIZE or 177760--177762)\n * @return {number}\n */\n readSIZE(addr)\n {\n return addr == PDP11.UNIBUS.LSIZE? ((this.bus.getMemoryLimit(MemoryPDP11.TYPE.RAM) >> 6) - 1) : 0;\n }\n\n /**\n * writeSIZE(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.LSIZE--HSIZE or 177760--177762)\n */\n writeSIZE(data, addr)\n {\n }\n\n /**\n * readSYSID(addr)\n *\n * TODO: For SYSID, we currently ignore writes and return 1 on reads\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.SYSID or 177764)\n * @return {number}\n */\n readSYSID(addr)\n {\n return 1;\n }\n\n /**\n * writeSYSID(data, addr)\n *\n * TODO: For SYSID, we currently ignore writes and return 1 on reads\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.SYSID or 177764)\n */\n writeSYSID(data, addr)\n {\n }\n\n /**\n * readCPUERR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.CPUERR or 177766)\n * @return {number}\n */\n readCPUERR(addr)\n {\n return this.cpu.regErr;\n }\n\n /**\n * writeCPUERR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.CPUERR or 177766)\n */\n writeCPUERR(data, addr)\n {\n this.cpu.regErr = 0; // TODO: Confirm that writes always zero the register\n }\n\n /**\n * readMBR(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.MB or 177770)\n * @return {number}\n */\n readMBR(addr)\n {\n return this.cpu.regMBR;\n }\n\n /**\n * writeMBR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.MB or 177770)\n */\n writeMBR(data, addr)\n {\n if (!(addr & 0x1)) {\n data &= 0xff; // required for KB11-CM without MFPT instruction\n }\n this.cpu.regMBR = data;\n }\n\n /**\n * readPIR(addr, fPreWrite)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.PIR or 177772)\n * @param {boolean} [fPreWrite]\n * @return {number}\n */\n readPIR(addr, fPreWrite)\n {\n if (fPreWrite) return 0;\n return this.cpu.getPIR();\n }\n\n /**\n * writePIR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.PIR or 177772)\n */\n writePIR(data, addr)\n {\n this.cpu.setPIR(data);\n }\n\n /**\n * readSLR(addr, fPreWrite)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.SL or 177774)\n * @param {boolean} [fPreWrite]\n * @return {number}\n */\n readSLR(addr, fPreWrite)\n {\n if (fPreWrite) return 0;\n return this.cpu.getSLR();\n }\n\n /**\n * writeSLR(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.SL or 177774)\n */\n writeSLR(data, addr)\n {\n this.cpu.setSLR(data);\n }\n\n /**\n * readPSW(addr)\n *\n * @this {DevicePDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.PSW or 177776)\n * @return {number}\n */\n readPSW(addr)\n {\n return this.cpu.getPSW();\n }\n\n /**\n * writePSW(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.PSW or 177776)\n */\n writePSW(data, addr)\n {\n /*\n * pdp11.js disallowed PSW.TF in addition to PSW.UNUSED, but DEC's \"TRAP TEST\" expects the\n * following instruction to trap:\n *\n * 004174: 052767 000020 173574 BIS #20,177776\n *\n * Since that test was written for the PDP-11/20, it's possible that newer machines have a different\n * behavior, but for now, we assume that all machines allow setting PSW.TF.\n *\n * Moreover, we have changed setPSW() to disallow the setting of any bits not supported by the current\n * CPU model, so it seems rather pointless to do any masking of bits here.\n */\n this.cpu.setPSW(data);\n }\n\n /**\n * writeIgnored(data, addr)\n *\n * @this {DevicePDP11}\n * @param {number} data\n * @param {number} addr\n */\n writeIgnored(data, addr)\n {\n if (this.messageEnabled()) {\n this.printMessage(\"writeIgnored(\" + Str.toOct(addr) + \"): \" + Str.toOct(data), true, true);\n }\n }\n\n /**\n * DevicePDP11.init()\n *\n * This function operates on every HTML element of class \"device\", extracting the\n * JSON-encoded parameters for the DevicePDP11 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a DevicePDP11 component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeDevice = Component.getElementsByClass(document, PDP11.APPCLASS, \"device\");\n for (var iDevice = 0; iDevice < aeDevice.length; iDevice++) {\n var device;\n var eDevice = aeDevice[iDevice];\n var parmsDevice = Component.getComponentParms(eDevice);\n switch(parmsDevice['type']) {\n case 'default':\n device = new DevicePDP11(parmsDevice);\n Component.bindComponentControls(device, eDevice, PDP11.APPCLASS);\n break;\n case 'pc11':\n device = new PC11(parmsDevice);\n Component.bindComponentControls(device, eDevice, PDP11.APPCLASS);\n break;\n case 'rl11':\n device = new RL11(parmsDevice);\n Component.bindComponentControls(device, eDevice, PDP11.APPCLASS);\n break;\n case 'rk11':\n device = new RK11(parmsDevice);\n Component.bindComponentControls(device, eDevice, PDP11.APPCLASS);\n break;\n case 'rx11':\n device = new RX11(parmsDevice);\n Component.bindComponentControls(device, eDevice, PDP11.APPCLASS);\n break;\n }\n }\n }\n}\n\n/*\n * ES6 ALERT: As you can see below, I've finally started using computed property names.\n */\nDevicePDP11.UNIBUS_IOTABLE = {\n [PDP11.UNIBUS.UNIMAP]: /* 170200 */ [null, null, DevicePDP11.prototype.readUNIMAP, DevicePDP11.prototype.writeUNIMAP, \"UNIMAP\", 64, PDP11.MODEL_1170],\n [PDP11.UNIBUS.SIPDR0]: /* 172200 */ [null, null, DevicePDP11.prototype.readSIPDR, DevicePDP11.prototype.writeSIPDR, \"SIPDR\", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],\n [PDP11.UNIBUS.SDPDR0]: /* 172220 */ [null, null, DevicePDP11.prototype.readSDPDR, DevicePDP11.prototype.writeSDPDR, \"SDPDR\", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],\n [PDP11.UNIBUS.SIPAR0]: /* 172240 */ [null, null, DevicePDP11.prototype.readSIPAR, DevicePDP11.prototype.writeSIPAR, \"SIPAR\", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],\n [PDP11.UNIBUS.SDPAR0]: /* 172260 */ [null, null, DevicePDP11.prototype.readSDPAR, DevicePDP11.prototype.writeSDPAR, \"SDPAR\", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],\n [PDP11.UNIBUS.KIPDR0]: /* 172300 */ [null, null, DevicePDP11.prototype.readKIPDR, DevicePDP11.prototype.writeKIPDR, \"KIPDR\", 8, PDP11.MODEL_1140, MessagesPDP11.MMU],\n [PDP11.UNIBUS.KDPDR0]: /* 172320 */ [null, null, DevicePDP11.prototype.readKDPDR, DevicePDP11.prototype.writeKDPDR, \"KDPDR\", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],\n [PDP11.UNIBUS.KIPAR0]: /* 172340 */ [null, null, DevicePDP11.prototype.readKIPAR, DevicePDP11.prototype.writeKIPAR, \"KIPAR\", 8, PDP11.MODEL_1140, MessagesPDP11.MMU],\n [PDP11.UNIBUS.KDPAR0]: /* 172360 */ [null, null, DevicePDP11.prototype.readKDPAR, DevicePDP11.prototype.writeKDPAR, \"KDPAR\", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],\n [PDP11.UNIBUS.MMR3]: /* 172516 */ [null, null, DevicePDP11.prototype.readMMR3, DevicePDP11.prototype.writeMMR3, \"MMR3\", 1, PDP11.MODEL_1145, MessagesPDP11.MMU],\n [PDP11.UNIBUS.LKS]: /* 177546 */ [null, null, DevicePDP11.prototype.readLKS, DevicePDP11.prototype.writeLKS, \"LKS\"],\n [PDP11.UNIBUS.MMR0]: /* 177572 */ [null, null, DevicePDP11.prototype.readMMR0, DevicePDP11.prototype.writeMMR0, \"MMR0\", 1, PDP11.MODEL_1140, MessagesPDP11.MMU],\n [PDP11.UNIBUS.MMR1]: /* 177574 */ [null, null, DevicePDP11.prototype.readMMR1, DevicePDP11.prototype.writeIgnored, \"MMR1\", 1, PDP11.MODEL_1145, MessagesPDP11.MMU],\n [PDP11.UNIBUS.MMR2]: /* 177576 */ [null, null, DevicePDP11.prototype.readMMR2, DevicePDP11.prototype.writeIgnored, \"MMR2\", 1, PDP11.MODEL_1140, MessagesPDP11.MMU],\n [PDP11.UNIBUS.UIPDR0]: /* 177600 */ [null, null, DevicePDP11.prototype.readUIPDR, DevicePDP11.prototype.writeUIPDR, \"UIPDR\", 8, PDP11.MODEL_1140, MessagesPDP11.MMU],\n [PDP11.UNIBUS.UDPDR0]: /* 177620 */ [null, null, DevicePDP11.prototype.readUDPDR, DevicePDP11.prototype.writeUDPDR, \"UDPDR\", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],\n [PDP11.UNIBUS.UIPAR0]: /* 177640 */ [null, null, DevicePDP11.prototype.readUIPAR, DevicePDP11.prototype.writeUIPAR, \"UIPAR\", 8, PDP11.MODEL_1140, MessagesPDP11.MMU],\n [PDP11.UNIBUS.UDPAR0]: /* 177660 */ [null, null, DevicePDP11.prototype.readUDPAR, DevicePDP11.prototype.writeUDPAR, \"UDPAR\", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],\n [PDP11.UNIBUS.R0SET0]: /* 177700 */ [null, null, DevicePDP11.prototype.readRSET0, DevicePDP11.prototype.writeRSET0, \"R0SET0\"],\n [PDP11.UNIBUS.R1SET0]: /* 177701 */ [null, null, DevicePDP11.prototype.readRSET0, DevicePDP11.prototype.writeRSET0, \"R1SET0\"],\n [PDP11.UNIBUS.R2SET0]: /* 177702 */ [null, null, DevicePDP11.prototype.readRSET0, DevicePDP11.prototype.writeRSET0, \"R2SET0\"],\n [PDP11.UNIBUS.R3SET0]: /* 177703 */ [null, null, DevicePDP11.prototype.readRSET0, DevicePDP11.prototype.writeRSET0, \"R3SET0\"],\n [PDP11.UNIBUS.R4SET0]: /* 177704 */ [null, null, DevicePDP11.prototype.readRSET0, DevicePDP11.prototype.writeRSET0, \"R4SET0\"],\n [PDP11.UNIBUS.R5SET0]: /* 177705 */ [null, null, DevicePDP11.prototype.readRSET0, DevicePDP11.prototype.writeRSET0, \"R5SET0\"],\n [PDP11.UNIBUS.R6KERNEL]:/* 177706 */ [null, null, DevicePDP11.prototype.readR6KERNEL,DevicePDP11.prototype.writeR6KERNEL,\"R6KERNEL\"],\n [PDP11.UNIBUS.R7KERNEL]:/* 177707 */ [null, null, DevicePDP11.prototype.readR7KERNEL,DevicePDP11.prototype.writeR7KERNEL,\"R7KERNEL\"],\n [PDP11.UNIBUS.R0SET1]: /* 177710 */ [null, null, DevicePDP11.prototype.readRSET1, DevicePDP11.prototype.writeRSET1, \"R0SET1\", 1, PDP11.MODEL_1145],\n [PDP11.UNIBUS.R1SET1]: /* 177711 */ [null, null, DevicePDP11.prototype.readRSET1, DevicePDP11.prototype.writeRSET1, \"R1SET1\", 1, PDP11.MODEL_1145],\n [PDP11.UNIBUS.R2SET1]: /* 177712 */ [null, null, DevicePDP11.prototype.readRSET1, DevicePDP11.prototype.writeRSET1, \"R2SET1\", 1, PDP11.MODEL_1145],\n [PDP11.UNIBUS.R3SET1]: /* 177713 */ [null, null, DevicePDP11.prototype.readRSET1, DevicePDP11.prototype.writeRSET1, \"R3SET1\", 1, PDP11.MODEL_1145],\n [PDP11.UNIBUS.R4SET1]: /* 177714 */ [null, null, DevicePDP11.prototype.readRSET1, DevicePDP11.prototype.writeRSET1, \"R4SET1\", 1, PDP11.MODEL_1145],\n [PDP11.UNIBUS.R5SET1]: /* 177715 */ [null, null, DevicePDP11.prototype.readRSET1, DevicePDP11.prototype.writeRSET1, \"R5SET1\", 1, PDP11.MODEL_1145],\n [PDP11.UNIBUS.R6SUPER]: /* 177716 */ [null, null, DevicePDP11.prototype.readR6SUPER, DevicePDP11.prototype.writeR6SUPER, \"R6SUPER\", 1, PDP11.MODEL_1145],\n [PDP11.UNIBUS.R6USER]: /* 177717 */ [null, null, DevicePDP11.prototype.readR6USER, DevicePDP11.prototype.writeR6USER, \"R6USER\", 1, PDP11.MODEL_1145],\n [PDP11.UNIBUS.CTRL]: /* 177740 */ [null, null, DevicePDP11.prototype.readCTRL, DevicePDP11.prototype.writeCTRL, \"CTRL\", 8, PDP11.MODEL_1170],\n [PDP11.UNIBUS.LSIZE]: /* 177760 */ [null, null, DevicePDP11.prototype.readSIZE, DevicePDP11.prototype.writeSIZE, \"LSIZE\", 1, PDP11.MODEL_1170],\n [PDP11.UNIBUS.HSIZE]: /* 177762 */ [null, null, DevicePDP11.prototype.readSIZE, DevicePDP11.prototype.writeSIZE, \"HSIZE\", 1, PDP11.MODEL_1170],\n [PDP11.UNIBUS.SYSID]: /* 177764 */ [null, null, DevicePDP11.prototype.readSYSID, DevicePDP11.prototype.writeSYSID, \"SYSID\", 1, PDP11.MODEL_1170],\n [PDP11.UNIBUS.CPUERR]: /* 177766 */ [null, null, DevicePDP11.prototype.readCPUERR, DevicePDP11.prototype.writeCPUERR, \"ERR\", 1, PDP11.MODEL_1170],\n [PDP11.UNIBUS.MB]: /* 177770 */ [null, null, DevicePDP11.prototype.readMBR, DevicePDP11.prototype.writeMBR, \"MBR\", 1, PDP11.MODEL_1170],\n [PDP11.UNIBUS.PIR]: /* 177772 */ [null, null, DevicePDP11.prototype.readPIR, DevicePDP11.prototype.writePIR, \"PIR\"],\n [PDP11.UNIBUS.SL]: /* 177774 */ [null, null, DevicePDP11.prototype.readSLR, DevicePDP11.prototype.writeSLR, \"SLR\"],\n [PDP11.UNIBUS.PSW]: /* 177776 */ [null, null, DevicePDP11.prototype.readPSW, DevicePDP11.prototype.writePSW, \"PSW\"]\n};\n\n/*\n * Initialize all the DevicePDP11 modules on the page.\n */\nWeb.onInit(DevicePDP11.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/memory.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * @class DataView\n * @property {function(number,boolean):number} getUint8\n * @property {function(number,number,boolean)} setUint8\n * @property {function(number,boolean):number} getUint16\n * @property {function(number,number,boolean)} setUint16\n * @property {function(number,boolean):number} getInt32\n * @property {function(number,number,boolean)} setInt32\n */\n\n/**\n * @class MemoryPDP11\n * @property {number} id\n * @property {number} used\n * @property {number} size\n * @property {Int32Array} adw\n * @property {Object} controller\n * @property {DebuggerPDP11} dbg\n */\nclass MemoryPDP11 {\n /**\n * MemoryPDP11(bus, addr, used, size, type, controller)\n *\n * The Bus component allocates Memory objects so that each has a memory buffer with a\n * block-granular starting address and an address range equal to bus.nBlockSize; however,\n * the size of any given Memory object's underlying buffer can be either zero or bus.nBlockSize;\n * memory read/write functions for empty (buffer-less) blocks are mapped to readNone/writeNone.\n *\n * The Bus allocates empty blocks for the entire address space during initialization, so that\n * any reads/writes to undefined addresses will have no effect. Later, the ROM and RAM\n * components will ask the Bus to allocate memory for specific ranges, and the Bus will allocate\n * as many new blockSize Memory objects as the ranges require. Partial Memory blocks could\n * also be supported in theory, but in practice, they're not.\n *\n * Because Memory blocks now allow us to have a \"sparse\" address space, we could choose to\n * take the memory hit of allocating 4K arrays per block, where each element stores only one byte,\n * instead of the more frugal but slightly slower approach of allocating arrays of 32-bit dwords\n * (LONGARRAYS) and shifting/masking bytes/words to/from dwords; in theory, byte accesses would\n * be faster and word accesses somewhat less faster.\n *\n * However, preliminary testing of that feature (BYTEARRAYS) did not yield significantly faster\n * performance, so it is OFF by default to minimize our memory consumption. Using TYPEDARRAYS\n * would seem best, but as discussed in defines.js, it's off by default, because it doesn't perform\n * as well as LONGARRAYS; the other advantage of TYPEDARRAYS is that it should theoretically use\n * about 1/2 the memory of LONGARRAYS (32-bit elements vs 64-bit numbers), but I value speed over\n * size at this point. Also, not all JavaScript implementations support TYPEDARRAYS (IE9 is probably\n * the only real outlier: it lacks typed arrays but otherwise has all the necessary HTML5 support).\n *\n * WARNING: Since Memory blocks are low-level objects that have no UI requirements, they\n * do not inherit from the Component class, so if you want to use any Component class methods,\n * such as Component.assert(), use the corresponding Debugger methods instead (assuming a debugger\n * is available).\n *\n * @param {BusPDP11} bus\n * @param {number|null} [addr] of lowest used address in block\n * @param {number} [used] portion of block in bytes (0 for none); must be a multiple of 4\n * @param {number} [size] of block's buffer in bytes (0 for none); must be a multiple of 4\n * @param {number} [type] is one of the MemoryPDP11.TYPE constants (default is MemoryPDP11.TYPE.NONE)\n * @param {Object} [controller] is an optional memory controller component\n */\n constructor(bus, addr, used, size, type, controller)\n {\n var a, i;\n this.bus = bus;\n this.id = (MemoryPDP11.idBlock += 2);\n this.adw = null;\n this.offset = 0;\n this.addr = addr;\n this.used = used;\n this.size = size || 0;\n this.type = type || MemoryPDP11.TYPE.NONE;\n this.fReadOnly = (type == MemoryPDP11.TYPE.ROM);\n this.controller = null;\n this.dbg = null;\n this.readByte = this.readByteDirect = this.readNone;\n this.readWord = this.readWordDirect = this.readWordDefault;\n this.writeByte = this.writeByteDirect = this.writeNone;\n this.writeWord = this.writeWordDirect = this.writeWordDefault;\n this.cReadBreakpoints = this.cWriteBreakpoints = 0;\n this.copyBreakpoints(); // initialize the block's Debugger info; the caller will reinitialize\n\n /*\n * TODO: Study the impact of dirty block tracking. The original purposes were to allow saveMemory()\n * to save only dirty blocks, and to enable the Video component to quickly detect changes to the video buffer.\n * But the benefit to saveMemory() is minimal, and the Video component has other options; for example, it can\n * now use a custom memory controller that performs its own dirty block tracking.\n *\n * However, a quick test with dirty block tracking disabled didn't yield a noticeable improvement in performance,\n * so I think the overhead of our block-based architecture is swamping the impact of these micro-updates.\n */\n this.fDirty = this.fDirtyEver = false;\n\n /*\n * For empty memory blocks, all we need to do is ensure all access functions are mapped to \"none\" handlers.\n */\n if (!this.size) {\n this.setAccess();\n return;\n }\n\n /*\n * When a controller is specified, the controller must provide a buffer, via getControllerBuffer(),\n * and memory access functions, via getControllerAccess().\n */\n if (controller) {\n this.controller = controller;\n a = controller.getControllerBuffer(addr);\n this.adw = a[0];\n this.offset = a[1];\n this.setAccess(controller.getControllerAccess());\n return;\n }\n\n /*\n * This is the normal case: allocate a buffer that provides 8 bits of data per address;\n * no controller is required because our default memory access functions (see afnMemory)\n * know how to deal with this simple 1-1 mapping of addresses to bytes and words.\n *\n * TODO: Consider initializing the memory array to random (or pseudo-random) values in DEBUG\n * mode; pseudo-random might be best, to help make any bugs reproducible.\n */\n if (TYPEDARRAYS) {\n this.buffer = new ArrayBuffer(this.size);\n this.dv = new DataView(this.buffer, 0, this.size);\n /*\n * If littleEndian is true, we can use ab[], aw[] and adw[] directly; well, we can use them\n * whenever the offset is a multiple of 1, 2 or 4, respectively. Otherwise, we must fallback to\n * dv.getUint8()/dv.setUint8(), dv.getUint16()/dv.setUint16() and dv.getInt32()/dv.setInt32().\n */\n this.ab = new Uint8Array(this.buffer, 0, this.size);\n this.aw = new Uint16Array(this.buffer, 0, this.size >> 1);\n this.adw = new Int32Array(this.buffer, 0, this.size >> 2);\n this.setAccess(littleEndian? MemoryPDP11.afnArrayLE : MemoryPDP11.afnArrayBE);\n } else {\n /*\n * NOTE: An ArrayBuffer is defined as being zero-initialized, but the elements of a new\n * Array are not, so this code path takes care of zero-initialization ourselves.\n */\n if (BYTEARRAYS) {\n a = this.ab = new Array(this.size);\n } else {\n /*\n * NOTE: This used to be the default mode of operation (!TYPEDARRAYS && !BYTEARRAYS), because\n * it seemed to provide the best performance; however, that was then, and this is now. TYPEDARRAYS\n * is more efficient.\n */\n a = this.adw = new Array(this.size >> 2);\n }\n for (i = 0; i < a.length; i++) a[i] = 0;\n this.setAccess(MemoryPDP11.afnMemory);\n }\n }\n\n /**\n * init(addr)\n *\n * Quick reinitializer when reusing a Memory block.\n *\n * @this {MemoryPDP11}\n * @param {number} addr\n */\n init(addr)\n {\n this.addr = addr;\n }\n\n /**\n * clone(mem, type, dbg)\n *\n * Converts the current Memory block (this) into a clone of the given Memory block (mem),\n * and optionally overrides the current block's type with the specified type.\n *\n * @this {MemoryPDP11}\n * @param {MemoryPDP11} mem\n * @param {number} [type]\n * @param {DebuggerPDP11} [dbg]\n */\n clone(mem, type, dbg)\n {\n /*\n * Original memory block IDs are even; cloned memory block IDs are odd;\n * the original ID of the current block is lost, but that's OK, since it was presumably\n * produced merely to become a clone.\n */\n this.id = mem.id | 0x1;\n this.used = mem.used;\n this.size = mem.size;\n if (type) {\n this.type = type;\n this.fReadOnly = (type == MemoryPDP11.TYPE.ROM);\n }\n if (TYPEDARRAYS) {\n this.buffer = mem.buffer;\n this.dv = mem.dv;\n this.ab = mem.ab;\n this.aw = mem.aw;\n this.adw = mem.adw;\n this.setAccess(littleEndian? MemoryPDP11.afnArrayLE : MemoryPDP11.afnArrayBE);\n } else {\n if (BYTEARRAYS) {\n this.ab = mem.ab;\n } else {\n this.adw = mem.adw;\n }\n this.setAccess(MemoryPDP11.afnMemory);\n }\n this.copyBreakpoints(dbg, mem);\n }\n\n /**\n * save()\n *\n * This gets the contents of a Memory block as an array of 32-bit values; used by Bus.saveMemory(),\n * which in turn is called by CPUState.save().\n *\n * Memory blocks with custom memory controllers do NOT save their contents; that's the responsibility\n * of the controller component.\n *\n * @this {MemoryPDP11}\n * @return {Array|Int32Array|null}\n */\n save()\n {\n var adw, i;\n if (this.controller) {\n adw = null;\n }\n else if (BYTEARRAYS) {\n adw = new Array(this.size >> 2);\n var off = 0;\n for (i = 0; i < adw.length; i++) {\n adw[i] = this.ab[off] | (this.ab[off + 1] << 8) | (this.ab[off + 2] << 16) | (this.ab[off + 3] << 24);\n off += 4;\n }\n }\n else if (TYPEDARRAYS) {\n /*\n * It might be tempting to just return a copy of Int32Array(this.buffer, 0, this.size >> 2),\n * but we can't be sure of the \"endianness\" of an Int32Array -- which would be OK if the array\n * was always saved/restored on the same machine, but there's no guarantee of that, either.\n * So we use getInt32() and require little-endian values.\n *\n * Moreover, an Int32Array isn't treated by JSON.stringify() and JSON.parse() exactly like\n * a normal array; it's serialized as an Object rather than an Array, so it lacks a \"length\"\n * property and causes problems for State.store() and State.parse().\n */\n adw = new Array(this.size >> 2);\n for (i = 0; i < adw.length; i++) {\n adw[i] = this.dv.getInt32(i << 2, true);\n }\n }\n else {\n adw = this.adw;\n }\n return adw;\n }\n\n /**\n * restore(adw)\n *\n * This restores the contents of a Memory block from an array of 32-bit values;\n * used by Bus.restoreMemory(), which is called by CPUState.restore(), after all other\n * components have been restored and thus all Memory blocks have been allocated\n * by their respective components.\n *\n * @this {MemoryPDP11}\n * @param {Array|null} adw\n * @return {boolean} true if successful, false if block size mismatch\n */\n restore(adw)\n {\n if (this.controller) {\n return (adw == null);\n }\n /*\n * At this point, it's a consistency error for adw to be null; it's happened once already,\n * when there was a restore bug in the Video component that added the frame buffer at the video\n * card's \"spec'ed\" address instead of the programmed address, so there were no controller-owned\n * memory blocks installed at the programmed address, and so we arrived here at a block with\n * no controller AND no data.\n */\n\n\n if (adw && this.size == adw.length << 2) {\n var i;\n if (BYTEARRAYS) {\n var off = 0;\n for (i = 0; i < adw.length; i++) {\n this.ab[off] = adw[i] & 0xff;\n this.ab[off + 1] = (adw[i] >> 8) & 0xff;\n this.ab[off + 2] = (adw[i] >> 16) & 0xff;\n this.ab[off + 3] = (adw[i] >> 24) & 0xff;\n off += 4;\n }\n } else if (TYPEDARRAYS) {\n for (i = 0; i < adw.length; i++) {\n this.dv.setInt32(i << 2, adw[i], true);\n }\n } else {\n this.adw = adw;\n }\n this.fDirty = true;\n return true;\n }\n return false;\n }\n\n /**\n * zero(off, len, pattern)\n *\n * Zeros the block. Supporting off and len parameters is probably overkill, and makes more\n * work in the non-TYPEDARRAY, non-BYTEARRAY case, but that's not the typical case. The other\n * exception is controller-based blocks, which may not have any array backing at all.\n *\n * @this {MemoryPDP11}\n * @param {number} [off] (optional starting byte offset within block)\n * @param {number} [len] (optional maximum number of bytes; default is the entire block)\n * @param {number} [pattern]\n */\n zero(off, len, pattern)\n {\n var i;\n off = off || 0;\n pattern = (pattern || 0) & 0xff; // pattern & 0xff wasn't good enough for the Closure Compiler\n /*\n * NOTE: If len happens to be larger than the block, that's OK, because we also bounds-check the index.\n */\n if (len === undefined) len = this.size;\n\n if ((TYPEDARRAYS || BYTEARRAYS) && this.ab) {\n for (i = off; len-- && i < this.ab.length; i++) this.ab[i] = pattern;\n } else {\n for (i = off; len-- && i < this.size; i++) this.writeByteDirect(off, pattern, this.addr + off);\n }\n }\n\n /**\n * setAccess(afn, fDirect)\n *\n * The afn parameter should be a 4-entry function table containing two byte handlers and\n * two word handlers. See the static afnMemory table for an example.\n *\n * If no function table is specified, a default is selected based on the Memory type;\n * similarly, any undefined entries in the table are filled with default handlers that fall\n * back to the byte handlers, and if one or both byte handlers are undefined, they default\n * to handlers that simply ignore the access.\n *\n * fDirect indicates that both the default AND the direct handlers should be updated. Direct\n * handlers normally match the default handlers, except when \"checked\" handlers are installed;\n * this allows \"checked\" handlers to know where to dispatch the call after performing checks.\n * Examples of checks are read/write breakpoints, but it's really up to the Debugger to decide\n * what the check consists of.\n *\n * @this {MemoryPDP11}\n * @param {Array.<function()>} [afn] function table\n * @param {boolean} [fDirect] (true to update direct access functions as well; default is true)\n */\n setAccess(afn, fDirect)\n {\n if (!afn) {\n\n afn = MemoryPDP11.afnNone;\n }\n this.setReadAccess(afn, fDirect);\n this.setWriteAccess(afn, fDirect);\n }\n\n /**\n * setReadAccess(afn, fDirect)\n *\n * @this {MemoryPDP11}\n * @param {Array.<function()>} afn\n * @param {boolean} [fDirect]\n */\n setReadAccess(afn, fDirect)\n {\n if (!fDirect || !this.cReadBreakpoints) {\n this.readByte = afn[0] || this.readNone;\n this.readWord = afn[2] || this.readWordDefault;\n }\n if (fDirect || fDirect === undefined) {\n this.readByteDirect = afn[0] || this.readNone;\n this.readWordDirect = afn[2] || this.readWordDefault;\n }\n }\n\n /**\n * setWriteAccess(afn, fDirect)\n *\n * @this {MemoryPDP11}\n * @param {Array.<function()>} afn\n * @param {boolean} [fDirect]\n */\n setWriteAccess(afn, fDirect)\n {\n if (!fDirect || !this.cWriteBreakpoints) {\n this.writeByte = !this.fReadOnly && afn[1] || this.writeNone;\n this.writeWord = !this.fReadOnly && afn[3] || this.writeWordDefault;\n }\n if (fDirect || fDirect === undefined) {\n this.writeByteDirect = afn[1] || this.writeNone;\n this.writeWordDirect = afn[3] || this.writeWordDefault;\n }\n }\n\n /**\n * resetReadAccess()\n *\n * @this {MemoryPDP11}\n */\n resetReadAccess()\n {\n this.readByte = this.readByteDirect;\n this.readWord = this.readWordDirect;\n }\n\n /**\n * resetWriteAccess()\n *\n * @this {MemoryPDP11}\n */\n resetWriteAccess()\n {\n this.writeByte = this.fReadOnly? this.writeNone : this.writeByteDirect;\n this.writeWord = this.fReadOnly? this.writeWordDefault : this.writeWordDirect;\n }\n\n /**\n * printAddr(sMessage)\n *\n * @this {MemoryPDP11}\n * @param {string} sMessage\n */\n printAddr(sMessage)\n {\n if (DEBUG && this.dbg && this.dbg.messageEnabled(MessagesPDP11.MEMORY)) {\n this.dbg.printMessage(sMessage + ' ' + (this.addr != null? ('@' + this.dbg.toStrBase(this.addr)) : '#' + this.id), true);\n }\n }\n\n /**\n * addBreakpoint(off, fWrite)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {boolean} fWrite\n */\n addBreakpoint(off, fWrite)\n {\n if (!fWrite) {\n if (this.cReadBreakpoints++ === 0) {\n this.setReadAccess(MemoryPDP11.afnChecked, false);\n }\n if (DEBUG) this.printAddr(\"read breakpoint added to memory block\");\n }\n else {\n if (this.cWriteBreakpoints++ === 0) {\n this.setWriteAccess(MemoryPDP11.afnChecked, false);\n }\n if (DEBUG) this.printAddr(\"write breakpoint added to memory block\");\n }\n }\n\n /**\n * removeBreakpoint(off, fWrite)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {boolean} fWrite\n */\n removeBreakpoint(off, fWrite)\n {\n if (!fWrite) {\n if (--this.cReadBreakpoints === 0) {\n this.resetReadAccess();\n if (DEBUG) this.printAddr(\"all read breakpoints removed from memory block\");\n }\n\n }\n else {\n if (--this.cWriteBreakpoints === 0) {\n this.resetWriteAccess();\n if (DEBUG) this.printAddr(\"all write breakpoints removed from memory block\");\n }\n\n }\n }\n\n /**\n * copyBreakpoints(dbg, mem)\n *\n * @this {MemoryPDP11}\n * @param {DebuggerPDP11} [dbg]\n * @param {MemoryPDP11} [mem] (outgoing MemoryPDP11 block to copy breakpoints from, if any)\n */\n copyBreakpoints(dbg, mem)\n {\n this.dbg = dbg;\n this.cReadBreakpoints = this.cWriteBreakpoints = 0;\n if (mem) {\n if ((this.cReadBreakpoints = mem.cReadBreakpoints)) {\n this.setReadAccess(MemoryPDP11.afnChecked, false);\n }\n if ((this.cWriteBreakpoints = mem.cWriteBreakpoints)) {\n this.setWriteAccess(MemoryPDP11.afnChecked, false);\n }\n }\n }\n\n /**\n * readNone(off, addr)\n *\n * Previously, this always returned 0x00, but the initial memory probe by the COMPAQ DeskPro 386 ROM BIOS\n * writes 0x0000 to the first word of every 64Kb block in the nearly 16Mb address space it supports, and\n * if it reads back 0x0000, it will initially think that LOTS of RAM exists, only to be disappointed later\n * when it performs a more exhaustive memory test, generating unwanted error messages in the process.\n *\n * TODO: Determine if we should have separate readByteNone(), readWordNone() and readLongNone() functions\n * to return 0xff, 0xffff and 0xffffffff|0, respectively. This seems sufficient for now, as it seems unlikely\n * that a system would require nonexistent memory locations to return ALL bits set. However, another factor\n * is whether or not ODDADDR faults take precedence over NOMEMORY faults; if they do, then we need separate\n * interfaces.\n *\n * Also, I'm reluctant to address that potential issue by simply returning -1, because to date, the above\n * Memory interfaces have always returned values that are properly masked to 8, 16 or 32 bits, respectively.\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readNone(off, addr)\n {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.MEMORY) /* && !off */) {\n this.dbg.printMessage(\"attempt to read invalid address \" + this.dbg.toStrBase(addr), true);\n }\n this.bus.fault(addr, PDP11.CPUERR.NOMEMORY, PDP11.ACCESS.READ);\n return 0xff;\n }\n\n /**\n * writeNone(off, v, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} v (could be either a byte or word value, since we use the same handler for both kinds of accesses)\n * @param {number} addr\n */\n writeNone(off, v, addr)\n {\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.MEMORY) /* && !off */) {\n this.dbg.printMessage(\"attempt to write \" + this.dbg.toStrBase(v) + \" to invalid addresses \" + this.dbg.toStrBase(addr), true);\n }\n this.bus.fault(addr, PDP11.CPUERR.NOMEMORY, PDP11.ACCESS.WRITE);\n }\n\n /**\n * readWordDefault(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readWordDefault(off, addr)\n {\n return this.readByte(off++, addr++) | (this.readByte(off, addr) << 8);\n }\n\n /**\n * writeWordDefault(off, w, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeWordDefault(off, w, addr)\n {\n this.writeByte(off++, w & 0xff, addr++);\n this.writeByte(off, w >> 8, addr);\n }\n\n /**\n * readByteMemory(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteMemory(off, addr)\n {\n if (BYTEARRAYS) {\n return this.ab[off];\n }\n return ((this.adw[off >> 2] >>> ((off & 0x3) << 3)) & 0xff);\n }\n\n /**\n * readWordMemory(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readWordMemory(off, addr)\n {\n if (PDP11.MEMFAULT && (off & 0x1)) {\n this.bus.fault(addr, PDP11.CPUERR.ODDADDR, PDP11.ACCESS.READ_WORD);\n }\n if (BYTEARRAYS) {\n return this.ab[off] | (this.ab[off + 1] << 8);\n }\n var w;\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n var dw = (this.adw[idw] >> nShift);\n if (nShift < 24) {\n w = dw & 0xffff;\n } else {\n w = (dw & 0xff) | ((this.adw[idw + 1] & 0xff) << 8);\n }\n return w;\n }\n\n /**\n * writeByteMemory(off, b, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} b\n * @param {number} addr\n */\n writeByteMemory(off, b, addr)\n {\n if (BYTEARRAYS) {\n this.ab[off] = b;\n } else {\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n this.adw[idw] = (this.adw[idw] & ~(0xff << nShift)) | (b << nShift);\n }\n this.fDirty = true;\n }\n\n /**\n * writeWordMemory(off, w, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeWordMemory(off, w, addr)\n {\n if (PDP11.MEMFAULT && (off & 0x1)) {\n this.bus.fault(addr, PDP11.CPUERR.ODDADDR, PDP11.ACCESS.WRITE_WORD);\n }\n if (BYTEARRAYS) {\n this.ab[off] = (w & 0xff);\n this.ab[off + 1] = (w >> 8);\n } else {\n var idw = off >> 2;\n var nShift = (off & 0x3) << 3;\n if (nShift < 24) {\n this.adw[idw] = (this.adw[idw] & ~(0xffff << nShift)) | (w << nShift);\n } else {\n this.adw[idw] = (this.adw[idw] & 0x00ffffff) | (w << 24);\n idw++;\n this.adw[idw] = (this.adw[idw] & (0xffffff00|0)) | (w >> 8);\n }\n }\n this.fDirty = true;\n }\n\n /**\n * readByteChecked(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteChecked(off, addr)\n {\n if (DEBUGGER && this.dbg && this.addr != null) {\n this.dbg.checkMemoryRead(this.addr + off);\n }\n return this.readByteDirect(off, addr);\n }\n\n /**\n * readWordChecked(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readWordChecked(off, addr)\n {\n if (DEBUGGER && this.dbg && this.addr != null) {\n this.dbg.checkMemoryRead(this.addr + off, 2);\n }\n return this.readWordDirect(off, addr);\n }\n\n /**\n * writeByteChecked(off, b, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} b\n * @param {number} addr\n */\n writeByteChecked(off, b, addr)\n {\n if (DEBUGGER && this.dbg && this.addr != null) {\n this.dbg.checkMemoryWrite(this.addr + off);\n }\n if (this.fReadOnly) this.writeNone(off, b, addr); else this.writeByteDirect(off, b, addr);\n }\n\n /**\n * writeWordChecked(off, w, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeWordChecked(off, w, addr)\n {\n if (DEBUGGER && this.dbg && this.addr != null) {\n this.dbg.checkMemoryWrite(this.addr + off, 2)\n }\n if (this.fReadOnly) this.writeNone(off, w, addr); else this.writeWordDirect(off, w, addr);\n }\n\n /**\n * readByteBE(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteBE(off, addr)\n {\n return this.ab[off];\n }\n\n /**\n * readByteLE(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readByteLE(off, addr)\n {\n var b = this.ab[off];\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.MEMORY)) {\n this.dbg.printMessage(\"Memory.readByte(\" + this.dbg.toStrBase(addr) + \"): \" + this.dbg.toStrBase(b), true);\n }\n return b;\n }\n\n /**\n * readWordBE(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readWordBE(off, addr)\n {\n if (PDP11.MEMFAULT && (off & 0x1)) {\n this.bus.fault(addr, PDP11.CPUERR.ODDADDR, PDP11.ACCESS.READ_WORD);\n }\n return this.dv.getUint16(off, true);\n }\n\n /**\n * readWordLE(off, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} addr\n * @return {number}\n */\n readWordLE(off, addr)\n {\n var w;\n if (PDP11.MEMFAULT && (off & 0x1)) {\n this.bus.fault(addr, PDP11.CPUERR.ODDADDR, PDP11.ACCESS.READ_WORD);\n }\n /*\n * TODO: For non-WORDBUS machines, it remains to be seen if there's any advantage to checking the offset\n * for an aligned read vs. always reading the bytes separately.\n */\n if (PDP11.WORDBUS || !(off & 0x1)) {\n w = this.aw[off >> 1];\n } else {\n w = this.ab[off] | (this.ab[off+1] << 8);\n }\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.MEMORY)) {\n this.dbg.printMessage(\"Memory.readWord(\" + this.dbg.toStrBase(addr) + \"): \" + this.dbg.toStrBase(w), true);\n }\n return w;\n }\n\n /**\n * writeByteBE(off, b, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} b\n * @param {number} addr\n */\n writeByteBE(off, b, addr)\n {\n this.ab[off] = b;\n this.fDirty = true;\n }\n\n /**\n * writeByteLE(off, b, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} b\n * @param {number} addr\n */\n writeByteLE(off, b, addr)\n {\n this.ab[off] = b;\n this.fDirty = true;\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.MEMORY)) {\n this.dbg.printMessage(\"Memory.writeByte(\" + this.dbg.toStrBase(addr) + \",\" + this.dbg.toStrBase(b) + \")\", true);\n }\n }\n\n /**\n * writeWordBE(off, w, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeWordBE(off, w, addr)\n {\n if (PDP11.MEMFAULT && (off & 0x1)) {\n this.bus.fault(addr, PDP11.CPUERR.ODDADDR, PDP11.ACCESS.WRITE_WORD);\n }\n this.dv.setUint16(off, w, true);\n this.fDirty = true;\n }\n\n /**\n * writeWordLE(off, w, addr)\n *\n * @this {MemoryPDP11}\n * @param {number} off\n * @param {number} w\n * @param {number} addr\n */\n writeWordLE(off, w, addr)\n {\n if (PDP11.MEMFAULT && (off & 0x1)) {\n this.bus.fault(addr, PDP11.CPUERR.ODDADDR, PDP11.ACCESS.WRITE_WORD);\n }\n /*\n * TODO: For non-WORDBUS machines, it remains to be seen if there's any advantage to checking the offset\n * for an aligned write vs. always writing the bytes separately.\n */\n if (PDP11.WORDBUS || !(off & 0x1)) {\n this.aw[off >> 1] = w;\n } else {\n this.ab[off] = w;\n this.ab[off+1] = w >> 8;\n }\n this.fDirty = true;\n if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.MEMORY)) {\n this.dbg.printMessage(\"Memory.writeWord(\" + this.dbg.toStrBase(addr) + \",\" + this.dbg.toStrBase(w) + \")\", true);\n }\n }\n}\n\n/*\n * Basic memory types\n *\n * RAM is the most conventional memory type, providing full read/write capability to x86-compatible (ie,\n * 'little endian\") storage. ROM is equally conventional, except that the fReadOnly property is set,\n * disabling writes. VIDEO is treated exactly like RAM, unless a controller is provided. Both RAM and\n * VIDEO memory are always considered writable, and even ROM can be written using the Bus setByteDirect()\n * interface (which in turn uses the Memory writeByteDirect() interface), allowing the ROM component to\n * initialize its own memory. The CONTROLLER type is used to identify memory-mapped devices that do not\n * need any default storage and always provide their own controller.\n *\n * Unallocated regions of the address space contain a special memory block of type NONE that contains\n * no storage. Mapping every addressible location to a memory block allows all accesses to be routed in\n * exactly the same manner, without resorting to any range or processor checks.\n *\n * These types are not mutually exclusive. For example, VIDEO memory could be allocated as RAM, with or\n * without a custom controller (the original Monochrome and CGA video cards used read/write storage that\n * was indistinguishable from RAM), and CONTROLLER memory could be allocated as an empty block of any type,\n * with a custom controller. A few types are required for certain features (eg, ROM is required if you want\n * read-only memory), but the larger purpose of these types is to help document the caller's intent and to\n * provide the Control Panel with the ability to highlight memory regions accordingly.\n */\nMemoryPDP11.TYPE = {\n NONE: 0,\n RAM: 1,\n ROM: 2,\n VIDEO: 3,\n CONTROLLER: 4\n};\nMemoryPDP11.TYPE_COLORS = [\"black\", \"blue\", \"green\", \"cyan\"];\nMemoryPDP11.TYPE_NAMES = [\"NONE\", \"RAM\", \"ROM\", \"VID\", \"H/W\"];\n\n/*\n * Last used block ID (used for debugging only)\n */\nMemoryPDP11.idBlock = 0;\n\n/*\n * This is the effective definition of afnNone, but we need not fully define it, because setAccess()\n * uses these defaults when any of the 4 handlers (ie, 2 byte handlers and 2 word handlers) are undefined.\n *\nMemoryPDP11.afnNone = [\n MemoryPDP11.prototype.readNone,\n MemoryPDP11.prototype.writeNone,\n MemoryPDP11.prototype.readWordDefault,\n MemoryPDP11.prototype.writeWordDefault\n];\n */\nMemoryPDP11.afnNone = [];\n\nMemoryPDP11.afnMemory = [\n MemoryPDP11.prototype.readByteMemory,\n MemoryPDP11.prototype.writeByteMemory,\n MemoryPDP11.prototype.readWordMemory,\n MemoryPDP11.prototype.writeWordMemory\n];\n\nMemoryPDP11.afnChecked = [\n MemoryPDP11.prototype.readByteChecked,\n MemoryPDP11.prototype.writeByteChecked,\n MemoryPDP11.prototype.readWordChecked,\n MemoryPDP11.prototype.writeWordChecked\n];\n\nif (TYPEDARRAYS) {\n MemoryPDP11.afnArrayBE = [\n MemoryPDP11.prototype.readByteBE,\n MemoryPDP11.prototype.writeByteBE,\n MemoryPDP11.prototype.readWordBE,\n MemoryPDP11.prototype.writeWordBE\n ];\n\n MemoryPDP11.afnArrayLE = [\n MemoryPDP11.prototype.readByteLE,\n MemoryPDP11.prototype.writeByteLE,\n MemoryPDP11.prototype.readWordLE,\n MemoryPDP11.prototype.writeWordLE\n ];\n}\n\nvar littleEndian = (TYPEDARRAYS? (function() {\n var buffer = new ArrayBuffer(2);\n new DataView(buffer).setUint16(0, 256, true);\n return new Uint16Array(buffer)[0] === 256;\n})() : false);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/cpu.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass CPUPDP11 extends Component {\n /**\n * CPUPDP11(parmsCPU, nCyclesDefault)\n *\n * The CPUPDP11 class supports the following (parmsCPU) properties:\n *\n * cycles: the machine's base cycles per second; the CPUStatePDP11 constructor\n * will provide us with a default (based on the CPU model) to use as a fallback.\n *\n * multiplier: base cycle multiplier; default is 1.\n *\n * autoStart: true to automatically start, false to not, or null if \"it depends\";\n * null is the default, which means do not autostart UNLESS there is no Debugger\n * and no \"Run\" button (ie, no way to manually start the machine).\n *\n * csStart: the number of cycles that runCPU() must wait before generating\n * checksum records; -1 if disabled. checksum records are a diagnostic aid\n * used to help compare one CPU run to another.\n *\n * csInterval: the number of cycles that runCPU() must execute before generating\n * a checksum record; -1 if disabled.\n *\n * csStop: the number of cycles to stop generating checksum records.\n *\n * This component is primarily responsible for interfacing the CPU with the outside\n * world (eg, Panel and Debugger components), and managing overall CPU operation.\n *\n * It is extended by the CPUStatePDP11 component, where the simulation control logic resides.\n *\n * @param {Object} parmsCPU\n * @param {number} nCyclesDefault\n */\n constructor(parmsCPU, nCyclesDefault)\n {\n super(\"CPU\", parmsCPU, MessagesPDP11.CPU);\n\n var nCycles = +parmsCPU['cycles'] || nCyclesDefault;\n\n var nMultiplier = +parmsCPU['multiplier'] || 1;\n\n this.nDisplayCount = 0;\n this.nDisplayLimit = 30;\n this.nCyclesPerSecond = nCycles;\n\n /*\n * nCyclesMultiplier replaces the old \"speed\" variable (0, 1, 2) and eliminates the need for\n * the constants (SPEED_SLOW, SPEED_FAST and SPEED_MAX). The UI simply doubles the multiplier\n * until we've exceeded the host's speed limit and then starts the multiplier over at 1.\n */\n this.nCyclesMultiplier = nMultiplier;\n this.mhzDefault = Math.round(this.nCyclesPerSecond / 10000) / 100;\n this.mhzTarget = this.mhzDefault * this.nCyclesMultiplier;\n this.msPerYield = this.nCyclesPerYield = this.nCyclesNextYield = this.nCyclesRecalc = 0;\n\n /*\n * We add a number of flags to the set initialized by Component\n */\n this.flags.running = this.flags.starting = false;\n this.flags.autoStart = parmsCPU['autoStart'];\n if (typeof this.flags.autoStart == \"string\") this.flags.autoStart = (this.flags.autoStart == \"true\");\n\n /*\n * Get checksum parameters, if any. runCPU() behavior is not affected until fChecksum\n * is true, which won't happen until resetChecksum() is called with nCyclesChecksumInterval\n * (\"csInterval\") set to a positive value.\n *\n * As above, any of these parameters can also be set with the Debugger's execution options\n * command (\"x\"); for example, \"x cs int 5000\" will set nCyclesChecksumInterval to 5000\n * and call resetChecksum().\n */\n this.flags.checksum = false;\n this.nChecksum = this.nCyclesChecksumNext = 0;\n this.nCyclesChecksumStart = +parmsCPU[\"csStart\"];\n this.nCyclesChecksumInterval = +parmsCPU[\"csInterval\"];\n this.nCyclesChecksumStop = +parmsCPU[\"csStop\"];\n\n /*\n * Array of countdown timers managed by addTimer() and setTimer().\n */\n this.aTimers = [];\n\n this.onRunTimeout = this.runCPU.bind(this); // function onRunTimeout() { cpu.runCPU(); };\n\n /*\n * Define the rest of the properties used by the class\n */\n this.mhz = 0;\n this.nYieldsSinceStatusUpdate = 0;\n this.msStartRun = this.msStartThisRun = this.msEndThisRun = this.nCyclesThisRun = 0;\n this.nTotalCycles = this.nRunCycles = this.nBurstCycles = this.nStepCycles = this.nSnapCycles = 0;\n this.panel = null;\n\n this.setReady();\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {CPUPDP11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUPDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.dbg = dbg;\n this.panel = cmp.panel;\n for (var i = 0; i < CPUPDP11.BUTTONS.length; i++) {\n var control = this.bindings[CPUPDP11.BUTTONS[i]];\n if (control) this.cmp.setBinding(\"\", CPUPDP11.BUTTONS[i], control);\n }\n this.setReady();\n }\n\n /**\n * reset()\n *\n * Stub for reset notification (overridden by the CPUStatePDP11 component).\n *\n * @this {CPUPDP11}\n */\n reset()\n {\n }\n\n /**\n * save()\n *\n * Stub for save support (overridden by the CPUStatePDP11 component).\n *\n * @this {CPUPDP11}\n * @return {Object|null}\n */\n save()\n {\n return null;\n }\n\n /**\n * restore(data)\n *\n * Stub for restore support (overridden by the CPUStatePDP11 component).\n *\n * @this {CPUPDP11}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n return false;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {CPUPDP11}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n /*\n * We've already saved the parmsCPU 'autoStart' setting, but there may be a machine (or URL) override.\n */\n var sAutoStart = this.cmp.getMachineParm('autoStart');\n if (sAutoStart != null) {\n this.flags.autoStart = (sAutoStart == \"true\"? true : (sAutoStart == \"false\"? false : !!sAutoStart));\n }\n else if (this.flags.autoStart == null) {\n /*\n * If there's no explicit parmsCPU setting either, then we will autoStart if there's no Debugger and\n * no \"Run\" button.\n */\n this.flags.autoStart = ((!DEBUGGER || !this.dbg) && this.bindings[\"run\"] === undefined);\n }\n\n if (!fRepower) {\n if (!data) {\n this.reset();\n } else {\n this.resetCycles();\n if (!this.restore(data)) return false;\n this.resetChecksum();\n }\n /*\n * Give the Debugger a chance to do/print something once we've powered up.\n */\n if (DEBUGGER && this.dbg) {\n this.dbg.init(this.flags.autoStart);\n } else {\n this.status(\"No debugger detected\");\n }\n if (!this.flags.autoStart) {\n this.println(\"CPU will not be auto-started \" + (this.panel? \"(click Run to start)\" : \"(type 'go' to start)\"));\n }\n }\n /*\n * The Computer component (which is responsible for all powerDown and powerUp notifications)\n * is now responsible for managing a component's fPowered flag, not us.\n *\n * this.flags.powered = true;\n */\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {CPUPDP11}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * autoStart()\n *\n * @this {CPUPDP11}\n * @return {boolean} true if started, false if not\n */\n autoStart()\n {\n if (this.flags.running) {\n return true;\n }\n if (this.flags.autoStart) {\n /*\n * We used to also set fUpdateFocus when calling startCPU(), on the assumption that in the \"auto-starting\"\n * context, a machine without focus is like a day without sunshine, but in reality, focus should only be\n * forced when the user takes some other machine-related action.\n */\n return this.startCPU();\n }\n return false;\n }\n\n /**\n * isPowered()\n *\n * @this {CPUPDP11}\n * @return {boolean}\n */\n isPowered()\n {\n if (!this.flags.powered) {\n this.println(this.toString() + \" not powered\");\n return false;\n }\n return true;\n }\n\n /**\n * isRunning()\n *\n * @this {CPUPDP11}\n * @return {boolean}\n */\n isRunning()\n {\n return this.flags.running;\n }\n\n /**\n * getChecksum()\n *\n * This will be implemented by the CPUStatePDP11 component.\n *\n * @this {CPUPDP11}\n * @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code)\n */\n getChecksum()\n {\n return 0;\n }\n\n /**\n * resetChecksum()\n *\n * If checksum generation is enabled (fChecksum is true), this resets the running 32-bit checksum and the\n * cycle counter that will trigger the next displayChecksum(); called by resetCycles(), which is called whenever\n * the CPU is reset or restored.\n *\n * @this {CPUPDP11}\n * @return {boolean} true if checksum generation enabled, false if not\n */\n resetChecksum()\n {\n if (this.nCyclesChecksumStart === undefined) this.nCyclesChecksumStart = 0;\n if (this.nCyclesChecksumInterval === undefined) this.nCyclesChecksumInterval = -1;\n if (this.nCyclesChecksumStop === undefined) this.nCyclesChecksumStop = -1;\n this.flags.checksum = (this.nCyclesChecksumStart >= 0 && this.nCyclesChecksumInterval > 0);\n if (this.flags.checksum) {\n this.nChecksum = 0;\n this.nCyclesChecksumNext = this.nCyclesChecksumStart - this.nTotalCycles;\n /*\n * this.nCyclesChecksumNext = this.nCyclesChecksumStart + this.nCyclesChecksumInterval -\n * (this.nTotalCycles % this.nCyclesChecksumInterval);\n */\n return true;\n }\n return false;\n }\n\n /**\n * updateChecksum(nCycles)\n *\n * When checksum generation is enabled (fChecksum is true), runCPU() asks stepCPU() to execute a minimum\n * number of cycles (1), effectively limiting execution to a single instruction, and then we're called with\n * the exact number cycles that were actually executed. This should give us instruction-granular checksums\n * at precise intervals that are 100% repeatable.\n *\n * @this {CPUPDP11}\n * @param {number} nCycles\n */\n updateChecksum(nCycles)\n {\n if (this.flags.checksum) {\n /*\n * Get a 32-bit summation of the current CPU state and add it to our running 32-bit checksum\n */\n var fDisplay = false;\n this.nChecksum = (this.nChecksum + this.getChecksum())|0;\n this.nCyclesChecksumNext -= nCycles;\n if (this.nCyclesChecksumNext <= 0) {\n this.nCyclesChecksumNext += this.nCyclesChecksumInterval;\n fDisplay = true;\n }\n if (this.nCyclesChecksumStop >= 0) {\n if (this.nCyclesChecksumStop <= this.getCycles()) {\n this.nCyclesChecksumInterval = this.nCyclesChecksumStop = -1;\n this.resetChecksum();\n this.stopCPU();\n fDisplay = true;\n }\n }\n if (fDisplay) this.displayChecksum();\n }\n }\n\n /**\n * displayChecksum()\n *\n * When checksum generation is enabled (fChecksum is true), this is called to provide a crude log of all\n * checksums generated at the specified cycle intervals, as specified by the \"csStart\" and \"csInterval\" parmsCPU\n * properties).\n *\n * @this {CPUPDP11}\n */\n displayChecksum()\n {\n this.println(this.getCycles() + \" cycles: \" + \"checksum=\" + Str.toHex(this.nChecksum));\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {CPUPDP11}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"run\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var cpu = this;\n\n switch (sBinding) {\n case \"power\":\n case \"reset\":\n /*\n * The \"power\" and \"reset\" buttons are functions of the entire computer, not just the CPU,\n * but it's not always convenient to stick a power button in the Computer component definition,\n * so we record those bindings here and pass them on to the Computer component in initBus().\n */\n this.bindings[sBinding] = control;\n return true;\n\n case \"run\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickRun() {\n if (!cpu.cmp || !cpu.cmp.checkPower()) return;\n /*\n * We no longer pass true to these startCPU()/stopCPU() calls, on the theory that if the \"run\"\n * control is visible, then the computer is probably sufficiently visible as well; the problem\n * with setting fUpdateFocus to true is that it can jerk the web page around in annoying ways.\n */\n if (!cpu.flags.running)\n cpu.startCPU();\n else\n cpu.stopCPU();\n };\n return true;\n\n case \"speed\":\n this.bindings[sBinding] = control;\n return true;\n\n case \"setSpeed\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickSetSpeed() {\n cpu.setSpeed(cpu.nCyclesMultiplier << 1, true);\n };\n control.textContent = this.getSpeedTarget();\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * updateDisplays(nUpdate)\n *\n * Simpler wrapper around the Computer's updateDisplays() method.\n *\n * @this {CPUPDP11}\n * @param {number} [nUpdate] (1 for periodic, -1 for forced, 0 or undefined otherwise)\n */\n updateDisplays(nUpdate)\n {\n if (this.cmp) this.cmp.updateDisplays(nUpdate);\n }\n\n /**\n * updateDisplay(nUpdate)\n *\n * Some of the CPU bindings provide feedback and therefore need to be updated periodically.\n * However, this should be called via the Computer's updateDisplays() interface, not directly.\n *\n * @this {CPUPDP11}\n * @param {number} [nUpdate] (1 for periodic, -1 for forced, 0 otherwise)\n */\n updateDisplay(nUpdate)\n {\n var controlSpeed = this.bindings[\"speed\"];\n if (controlSpeed) {\n if (nUpdate <= 0 || (this.nDisplayCount += nUpdate) >= this.nDisplayLimit) {\n controlSpeed.textContent = this.getSpeedCurrent();\n this.nDisplayCount = 0;\n }\n }\n }\n\n /**\n * addCycles(nCycles, fEndStep)\n *\n * @this {CPUPDP11}\n * @param {number} nCycles\n * @param {boolean} [fEndStep]\n */\n addCycles(nCycles, fEndStep)\n {\n this.nTotalCycles += nCycles;\n if (fEndStep) {\n this.nBurstCycles = this.nStepCycles = this.nSnapCycles = 0;\n }\n }\n\n /**\n * calcCycles(fRecalc)\n *\n * Calculate the number of cycles to process for each \"burst\" of CPU activity. The size of a burst\n * is driven by YIELDS_PER_SECOND (eg, 30).\n *\n * At the end of each burst, we subtract burst cycles from the yield cycle \"threshold\" counter.\n * Whenever the \"next yield\" cycle counter goes to (or below) zero, we compare elapsed time to the time\n * we expected the virtual hardware to take (eg, 1000ms/50 or 20ms), and if we still have time remaining,\n * we sleep the remaining time (or 0ms if there's no remaining time), and then restart runCPU().\n *\n * @this {CPUPDP11}\n * @param {boolean} [fRecalc] is true if the caller wants to recalculate thresholds based on the most recent\n * speed calculation (see calcSpeed).\n */\n calcCycles(fRecalc)\n {\n /*\n * Calculate \"per\" yield values.\n */\n var vMultiplier = 1;\n if (fRecalc) {\n if (this.nCyclesMultiplier > 1 && this.mhz) {\n vMultiplier = (this.mhz / this.mhzDefault);\n }\n }\n\n this.msPerYield = Math.round(1000 / CPUPDP11.YIELDS_PER_SECOND);\n this.nCyclesPerYield = Math.floor(this.nCyclesPerSecond / CPUPDP11.YIELDS_PER_SECOND * vMultiplier);\n\n /*\n * And initialize \"next\" yield values to the \"per\" values.\n */\n if (!fRecalc) this.nCyclesNextYield = this.nCyclesPerYield;\n this.nCyclesRecalc = 0;\n }\n\n /**\n * getCycles(fScaled)\n *\n * getCycles() returns the number of cycles executed so far. Note that we can be called after\n * runCPU() OR during runCPU(), perhaps from a handler triggered during the current run's stepCPU(),\n * so nRunCycles must always be adjusted by number of cycles stepCPU() was asked to run (nBurstCycles),\n * less the number of cycles it has yet to run (nStepCycles).\n *\n * nRunCycles is zeroed whenever the CPU is halted or the CPU speed is changed, which is why we also\n * have nTotalCycles, which accumulates all nRunCycles before we zero it. However, nRunCycles and\n * nTotalCycles eventually get reset by calcSpeed(), to avoid overflow, so components that rely on\n * getCycles() returning steadily increasing values should also be prepared for a reset at any time.\n *\n * @this {CPUPDP11}\n * @param {boolean} [fScaled] is true if the caller wants a cycle count relative to a multiplier of 1\n * @return {number}\n */\n getCycles(fScaled)\n {\n var nCycles = this.nTotalCycles + this.nRunCycles + this.nBurstCycles - this.nStepCycles;\n if (fScaled && this.nCyclesMultiplier > 1 && this.mhz > this.mhzDefault) {\n /*\n * We could scale the current cycle count by the current effective speed (this.mhz); eg:\n *\n * nCycles = Math.round(nCycles / (this.mhz / this.mhzDefault));\n *\n * but that speed will fluctuate somewhat: large fluctuations at first, but increasingly smaller\n * fluctuations after each burst of instructions that runCPU() executes.\n *\n * Alternatively, we can scale the cycle count by the multiplier, which is good in that the\n * multiplier doesn't vary once the user changes it, but a potential downside is that the\n * multiplier might be set too high, resulting in a target speed that's higher than the effective\n * speed is able to reach.\n *\n * Also, if multipliers were always limited to a power-of-two, then this could be calculated\n * with a simple shift. However, only the \"setSpeed\" UI binding limits it that way; the Debugger\n * interface allows any value, as does the CPU \"multiplier\" parmsCPU property (from the machine's\n * XML file).\n */\n nCycles = Math.round(nCycles / this.nCyclesMultiplier);\n }\n return nCycles;\n }\n\n /**\n * getCyclesPerSecond()\n *\n * This returns the CPU's \"base\" speed (ie, the original cycles per second defined for the machine)\n *\n * @this {CPUPDP11}\n * @return {number}\n */\n getCyclesPerSecond()\n {\n return this.nCyclesPerSecond;\n }\n\n /**\n * resetCycles()\n *\n * Resets speed and cycle information as part of any reset() or restore(); this typically occurs during powerUp().\n * It's important that this be called BEFORE the actual restore() call, because restore() may want to call setSpeed(),\n * which in turn assumes that all the cycle counts have been initialized to sensible values.\n *\n * @this {CPUPDP11}\n */\n resetCycles()\n {\n this.mhz = 0;\n this.nYieldsSinceStatusUpdate = 0;\n this.nTotalCycles = this.nRunCycles = this.nBurstCycles = this.nStepCycles = this.nSnapCycles = 0;\n this.resetChecksum();\n this.setSpeed(1);\n }\n\n /**\n * getSpeed()\n *\n * @this {CPUPDP11}\n * @return {number} the current speed multiplier\n */\n getSpeed()\n {\n return this.nCyclesMultiplier;\n }\n\n /**\n * getSpeedCurrent()\n *\n * @this {CPUPDP11}\n * @return {string} the current speed, in mhz, as a string formatted to two decimal places\n */\n getSpeedCurrent()\n {\n /*\n * TODO: Has toFixed() been \"fixed\" in all browsers (eg, IE) to return a rounded value now?\n */\n return ((this.flags.running)? (this.mhz.toFixed(2) + \"Mhz\") : \"Stopped\");\n }\n\n /**\n * getSpeedTarget()\n *\n * @this {CPUPDP11}\n * @return {string} the target speed, in mhz, as a string formatted to two decimal places\n */\n getSpeedTarget()\n {\n /*\n * TODO: Has toFixed() been \"fixed\" in all browsers (eg, IE) to return a rounded value now?\n */\n return this.mhzTarget.toFixed(2) + \"Mhz\";\n }\n\n /**\n * setSpeed(nMultiplier, fUpdateFocus)\n *\n * NOTE: This used to return the target speed, in mhz, but no callers appear to care at this point.\n *\n * @desc Whenever the speed is changed, the running cycle count and corresponding start time must be reset,\n * so that the next effective speed calculation obtains sensible results. In fact, when runCPU() initially calls\n * setSpeed() with no parameters, that's all this function does (it doesn't change the current speed setting).\n *\n * @this {CPUPDP11}\n * @param {number} [nMultiplier] is the new proposed multiplier (reverts to 1 if the target was too high)\n * @param {boolean} [fUpdateFocus] is true to update Computer focus\n * @return {boolean} true if successful, false if not\n */\n setSpeed(nMultiplier, fUpdateFocus)\n {\n var fSuccess = false;\n if (nMultiplier !== undefined) {\n /*\n * If we haven't reached 80% (0.8) of the current target speed, revert to a multiplier of one (1).\n */\n if (this.mhz / this.mhzTarget < 0.8) {\n nMultiplier = 1;\n } else {\n fSuccess = true;\n }\n this.nCyclesMultiplier = nMultiplier;\n var mhz = this.mhzDefault * this.nCyclesMultiplier;\n if (this.mhzTarget != mhz) {\n this.mhzTarget = mhz;\n var sSpeed = this.getSpeedTarget();\n var controlSpeed = this.bindings[\"setSpeed\"];\n if (controlSpeed) controlSpeed.textContent = sSpeed;\n this.println(\"target speed: \" + sSpeed);\n }\n if (fUpdateFocus && this.cmp) this.cmp.setFocus();\n }\n this.addCycles(this.nRunCycles);\n this.nRunCycles = 0;\n this.msStartRun = Component.getTime();\n this.msEndThisRun = 0;\n this.calcCycles();\n return fSuccess;\n }\n\n /**\n * calcSpeed(nCycles, msElapsed)\n *\n * @this {CPUPDP11}\n * @param {number} nCycles\n * @param {number} msElapsed\n */\n calcSpeed(nCycles, msElapsed)\n {\n if (msElapsed) {\n this.mhz = Math.round(nCycles / (msElapsed * 10)) / 100;\n if (msElapsed >= 86400000) {\n this.nTotalCycles = 0;\n this.setSpeed(); // reset all counters once per day so that we never have to worry about overflow\n }\n }\n }\n\n /**\n * calcStartTime()\n *\n * @this {CPUPDP11}\n */\n calcStartTime()\n {\n if (this.nCyclesRecalc >= this.nCyclesPerSecond) {\n this.calcCycles(true);\n }\n this.nCyclesThisRun = 0;\n this.msStartThisRun = Component.getTime();\n\n /*\n * Try to detect situations where the browser may have throttled us, such as when the user switches\n * to a different tab; in those situations, Chrome and Safari may restrict setTimeout() callbacks\n * to roughly one per second.\n *\n * Another scenario: the user resizes the browser window. setTimeout() callbacks are not throttled,\n * but there can still be enough of a lag between the callbacks that CPU speed will be noticeably\n * erratic if we don't compensate for it here.\n *\n * We can detect throttling/lagging by verifying that msEndThisRun (which was set at the end of the\n * previous run and includes any requested sleep time) is comparable to the current msStartThisRun;\n * if the delta is significant, we compensate by bumping msStartRun forward by that delta.\n *\n * This shouldn't be triggered when the Debugger halts the CPU, because setSpeed() -- which is called\n * whenever the CPU starts running again -- zeroes msEndThisRun.\n *\n * This also won't do anything about other internal delays; for example, Debugger message() calls.\n * By the time the message() function has called yieldCPU(), the cost of the message has already been\n * incurred, so it will be end up being charged against the instruction(s) that triggered it.\n *\n * TODO: Consider calling yieldCPU() sooner from message(), so that it can arrange for the msEndThisRun\n * \"snapshot\" to occur sooner; it's unclear, however, whether that will really improve the CPU's ability\n * to hit its target speed, since you would expect any instruction that displays a message to be an\n * EXTREMELY slow instruction.\n */\n if (this.msEndThisRun) {\n var msDelta = this.msStartThisRun - this.msEndThisRun;\n if (msDelta > this.msPerYield) {\n if (MAXDEBUG) this.println(\"large time delay: \" + msDelta + \"ms\");\n this.msStartRun += msDelta;\n /*\n * Bumping msStartRun forward should NEVER cause it to exceed msStartThisRun; however, just\n * in case, I make absolutely sure it cannot happen, since doing so could result in negative\n * speed calculations.\n */\n\n if (this.msStartRun > this.msStartThisRun) {\n this.msStartRun = this.msStartThisRun;\n }\n }\n }\n }\n\n /**\n * calcRemainingTime()\n *\n * @this {CPUPDP11}\n * @return {number}\n */\n calcRemainingTime()\n {\n this.msEndThisRun = Component.getTime();\n\n var msYield = this.msPerYield;\n if (this.nCyclesThisRun) {\n /*\n * Normally, we would assume we executed a full quota of work over msPerYield, but since the CPU\n * now has the option of calling yieldCPU(), that might not be true. If nCyclesThisRun is correct, then\n * the ratio of nCyclesThisRun/nCyclesPerYield should represent the percentage of work we performed,\n * and so applying that percentage to msPerYield should give us a better estimate of work vs. time.\n */\n msYield = Math.round(msYield * this.nCyclesThisRun / this.nCyclesPerYield);\n }\n\n var msElapsedThisRun = this.msEndThisRun - this.msStartThisRun;\n var msRemainsThisRun = msYield - msElapsedThisRun;\n\n /*\n * We could pass only \"this run\" results to calcSpeed():\n *\n * nCycles = this.nCyclesThisRun;\n * msElapsed = msElapsedThisRun;\n *\n * but it seems preferable to use longer time periods and hopefully get a more accurate speed.\n *\n * Also, if msRemainsThisRun >= 0 && this.nCyclesMultiplier == 1, we could pass these results instead:\n *\n * nCycles = this.nCyclesThisRun;\n * msElapsed = this.msPerYield;\n *\n * to insure that we display a smooth, constant N Mhz. But for now, I prefer seeing any fluctuations.\n */\n var nCycles = this.nRunCycles;\n var msElapsed = this.msEndThisRun - this.msStartRun;\n\n if (MAXDEBUG && msRemainsThisRun < 0 && this.nCyclesMultiplier > 1) {\n this.println(\"warning: updates @\" + msElapsedThisRun + \"ms (prefer \" + Math.round(msYield) + \"ms)\");\n }\n\n this.calcSpeed(nCycles, msElapsed);\n\n if (msRemainsThisRun < 0 || this.mhz < this.mhzTarget) {\n /*\n * Try \"throwing out\" the effects of large anomalies, by moving the overall run start time up;\n * ordinarily, this should only happen when the someone is using an external Debugger or some other\n * tool or feature that is interfering with our overall execution.\n */\n if (msRemainsThisRun < -1000) {\n this.msStartRun -= msRemainsThisRun;\n }\n /*\n * If the last burst took MORE time than we allotted (ie, it's taking more than 1 second to simulate\n * nCyclesPerSecond), all we can do is yield for as little time as possible (ie, 0ms) and hope that the\n * simulation is at least usable.\n */\n msRemainsThisRun = 0;\n }\n\n /*\n * Last but not least, update nCyclesRecalc, so that when runCPU() starts up again and calls calcStartTime(),\n * it'll be ready to decide if calcCycles() should be called again.\n */\n this.nCyclesRecalc += this.nCyclesThisRun;\n\n if (DEBUG && this.messageEnabled(MessagesPDP11.BUFFER) && msRemainsThisRun) {\n this.log(\"calcRemainingTime: \" + msRemainsThisRun + \"ms to sleep after \" + this.msEndThisRun + \"ms\");\n }\n\n this.msEndThisRun += msRemainsThisRun;\n return msRemainsThisRun;\n }\n\n /**\n * addTimer(callBack)\n *\n * Components that want to have timers that periodically fire after some number of milliseconds call\n * addTimer() to create the timer, and then setTimer() every time they want to arm it. There is currently\n * no removeTimer() because these are generally used for the entire lifetime of a component.\n *\n * Internally, each timer entry is a preallocated Array with two entries: a cycle countdown in element [0]\n * and a callback function in element [1]. A timer is initially dormant; dormant timers have a countdown\n * value of -1 (although any negative number will suffice) and active timers have a non-negative value.\n *\n * Why not use JavaScript's setTimeout() instead? Good question. For a good answer, see setTimer() below.\n *\n * TODO: Consider making the addTimer() and setTimer() interfaces more like the addIRQ() and setIRQ()\n * interfaces (which return the underlying object instead of an array index) and maintaining a separate list\n * of active timers, in order of highest to lowest cycle countdown values, as this could speed up\n * getBurstCycles() and updateTimers() functions ever so slightly.\n *\n * @this {CPUPDP11}\n * @param {function()} callBack\n * @return {number} timer index\n */\n addTimer(callBack)\n {\n var iTimer = this.aTimers.length;\n this.aTimers.push([-1, callBack]);\n return iTimer;\n }\n\n /**\n * setTimer(iTimer, ms, fReset)\n *\n * Using the timer index from a previous addTimer() call, this sets that timer to fire after the\n * specified number of milliseconds.\n *\n * This is preferred over JavaScript's setTimeout(), because all our timers are effectively paused when\n * the CPU is paused (eg, when the Debugger halts execution). Moreover, setTimeout() handlers only run after\n * runCPU() yields, which is far too granular for some components (eg, when the SerialPort tries to simulate\n * interrupts at 9600 baud).\n *\n * Ideally, the only function that would use setTimeout() is runCPU(), while the rest of the components\n * use setTimer(); however, due to legacy code (ie, code that predates these functions) and/or laziness,\n * that may not be the case.\n *\n * @this {CPUPDP11}\n * @param {number} iTimer\n * @param {number} ms (converted into a cycle countdown internally)\n * @param {boolean} [fReset] (true if the timer should be reset even if already armed)\n * @return {number} (number of cycles used to arm timer, or -1 if error)\n */\n setTimer(iTimer, ms, fReset)\n {\n var nCycles = -1;\n if (iTimer >= 0 && iTimer < this.aTimers.length) {\n if (fReset || this.aTimers[iTimer][0] < 0) {\n nCycles = this.getMSCycles(ms);\n /*\n * We must now confront the following problem: if the CPU is currently executing a burst of cycles,\n * the number of cycles it has executed in that burst so far must NOT be charged against the cycle\n * timeout we're about to set. The simplest way to resolve that is to immediately call endBurst()\n * and bias the cycle timeout by the number of cycles that the burst executed.\n */\n if (this.flags.running) {\n nCycles += this.endBurst();\n }\n this.aTimers[iTimer][0] = nCycles;\n }\n }\n return nCycles;\n }\n\n /**\n * getMSCycles(ms)\n *\n * @this {CPUPDP11}\n * @param {number} ms\n * @return {number} number of corresponding cycles\n */\n getMSCycles(ms)\n {\n return ((this.nCyclesPerSecond * this.nCyclesMultiplier) / 1000 * ms)|0;\n }\n\n /**\n * getBurstCycles(nCycles)\n *\n * Used by runCPU() to get min(nCycles,[timer cycle counts])\n *\n * @this {CPUPDP11}\n * @param {number} nCycles (number of cycles about to execute)\n * @return {number} (either nCycles or less if a timer needs to fire)\n */\n getBurstCycles(nCycles)\n {\n for (var i = this.aTimers.length - 1; i >= 0; i--) {\n var timer = this.aTimers[i];\n\n if (timer[0] < 0) continue;\n if (nCycles > timer[0]) {\n nCycles = timer[0];\n }\n }\n return nCycles;\n }\n\n /**\n * saveTimers()\n *\n * @this {CPUPDP11}\n * @return {Array.<number>}\n */\n saveTimers()\n {\n var aTimerCycles = [];\n for (var i = 0; i < this.aTimers.length; i++) {\n var timer = this.aTimers[i];\n aTimerCycles.push(timer[0]);\n }\n return aTimerCycles;\n }\n\n /**\n * restoreTimers(aTimerCycles)\n *\n * @this {CPUPDP11}\n * @param {Array.<number>} aTimerCycles\n */\n restoreTimers(aTimerCycles)\n {\n\n for (var i = 0; i < this.aTimers.length && i < aTimerCycles.length; i++) {\n var timer = this.aTimers[i];\n timer[0] = aTimerCycles[i];\n }\n }\n\n /**\n * updateTimers(nCycles)\n *\n * Used by runCPU() to reduce all active timer countdown values by the number of cycles just executed;\n * this is the function that actually \"fires\" any timer(s) whose countdown has reached (or dropped below)\n * zero, invoking their callback function.\n *\n * @this {CPUPDP11}\n * @param {number} nCycles (number of cycles actually executed)\n */\n updateTimers(nCycles)\n {\n for (var i = this.aTimers.length - 1; i >= 0; i--) {\n var timer = this.aTimers[i];\n\n if (timer[0] < 0) continue;\n timer[0] -= nCycles;\n if (timer[0] <= 0) {\n timer[0] = -1; // zero is technically an \"active\" value, so ensure the timer is dormant now\n timer[1](); // safe to invoke the callback function now\n }\n }\n }\n\n /**\n * endBurst(fReset)\n *\n * @this {CPUPDP11}\n * @param {boolean} [fReset]\n * @return {number} (number of cycles executed in the most recent burst)\n */\n endBurst(fReset)\n {\n var nCycles = this.nBurstCycles -= this.nStepCycles;\n /*\n * In addition to zeroing nStepCycles, it's important that we also zero nSnapCycles, because if a CPU\n * burst is being ended after nStepCycles has been \"snapped\" (because a certain opcode has an unusual timing\n * calculation that must be based on a \"snapped\" cycle count rather the opcode's starting cycle count), we\n * could inadvertently undo the endBurst() if the original \"snapped\" value was used to update nStepCycles.\n */\n this.nStepCycles = this.nSnapCycles = 0;\n if (fReset) this.nBurstCycles = 0;\n return nCycles;\n }\n\n /**\n * runCPU()\n *\n * @this {CPUPDP11}\n */\n runCPU()\n {\n if (!this.flags.running) return;\n\n /*\n * calcStartTime() initializes the cycle counter and timestamp for this runCPU() invocation, and optionally\n * recalculates the the maximum number of cycles for each burst if the nCyclesRecalc threshold has been reached.\n */\n this.calcStartTime();\n\n try {\n do {\n /*\n * nCycles is how many cycles we WANT to run on each iteration of stepCPU(), and may be as\n * HIGH as nCyclesPerYield, but it may be significantly less. getBurstCycles() will adjust\n * nCycles downward if any CPU timers need to fire during the next burst.\n */\n var nCycles = this.getBurstCycles(this.flags.checksum? 1 : this.nCyclesPerYield);\n\n /*\n * Execute the burst.\n */\n try {\n this.stepCPU(nCycles);\n }\n catch(exception) {\n /*\n * We assume that any numeric exception was explicitly thrown by the CPU to interrupt the\n * current instruction (and by extension, the current burst, but not the current run). All\n * other exceptions are re-thrown to the catch below, which will attempt a stack dump.\n */\n if (typeof exception != \"number\") throw exception;\n }\n\n /*\n * Terminate the burst, returning the number of cycles that stepCPU() actually ran.\n */\n nCycles = this.endBurst(true);\n\n /*\n * Add nCycles to nCyclesThisRun, as well as nRunCycles (the cycle count since the CPU started).\n */\n this.nCyclesThisRun += nCycles;\n this.nRunCycles += nCycles;\n this.updateChecksum(nCycles);\n\n /*\n * Update any/all timers, firing those whose cycle countdowns have reached (or dropped below) zero.\n */\n this.updateTimers(nCycles);\n\n this.nCyclesNextYield -= nCycles;\n if (this.nCyclesNextYield <= 0) {\n this.nCyclesNextYield += this.nCyclesPerYield;\n if (++this.nYieldsSinceStatusUpdate >= CPUPDP11.YIELDS_PER_STATUS) {\n this.updateDisplays();\n this.nYieldsSinceStatusUpdate = 0;\n }\n break;\n }\n } while (this.flags.running);\n }\n catch (e) {\n this.stopCPU();\n if (this.cmp) this.cmp.stop(Component.getTime(), this.getCycles());\n this.setError(e.stack || e.message);\n return;\n }\n\n if (this.flags.running) setTimeout(this.onRunTimeout, this.calcRemainingTime());\n }\n\n /**\n * startCPU(fUpdateFocus)\n *\n * For use by any component that wants to start the CPU.\n *\n * @param {boolean} [fUpdateFocus]\n * @return {boolean}\n */\n startCPU(fUpdateFocus)\n {\n if (this.isError()) {\n return false;\n }\n if (this.flags.running) {\n this.println(this.toString() + \" busy\");\n return false;\n }\n /*\n * setSpeed() without a speed parameter leaves the selected speed in place, but also resets the\n * cycle counter and timestamp for the current series of runCPU() calls, calculates the maximum number\n * of cycles for each burst based on the last known effective CPU speed, and resets the nCyclesRecalc\n * threshold counter.\n */\n this.setSpeed();\n this.flags.running = true;\n this.flags.starting = true;\n var controlRun = this.bindings[\"run\"];\n if (controlRun) controlRun.textContent = \"Halt\";\n if (this.cmp) {\n if (fUpdateFocus) this.cmp.setFocus(true);\n this.cmp.start(this.msStartRun, this.getCycles());\n }\n if (!this.dbg) this.status(\"Started\");\n setTimeout(this.onRunTimeout, 0);\n return true;\n }\n\n /**\n * stepCPU(nMinCycles)\n *\n * This will be implemented by the CPUStatePDP11 component.\n *\n * @this {CPUPDP11}\n * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored)\n * @return {number} of cycles executed; 0 indicates that the last instruction was not executed\n */\n stepCPU(nMinCycles)\n {\n return 0;\n }\n\n /**\n * stopCPU(fComplete)\n *\n * For use by any component that wants to stop the CPU.\n *\n * This similar to yieldCPU(), but it doesn't need to zero nCyclesNextYield to break out of runCPU();\n * it simply needs to clear fRunning (well, \"simply\" may be oversimplifying a bit....)\n *\n * @this {CPUPDP11}\n * @param {boolean} [fComplete]\n * @return {boolean} true if the CPU was stopped, false if it was already stopped\n */\n stopCPU(fComplete)\n {\n var fStopped = false;\n if (this.flags.running) {\n this.endBurst();\n this.addCycles(this.nRunCycles);\n this.nRunCycles = 0;\n this.flags.running = false;\n var controlRun = this.bindings[\"run\"];\n if (controlRun) controlRun.textContent = \"Run\";\n if (this.cmp) {\n this.cmp.stop(Component.getTime(), this.getCycles());\n }\n fStopped = true;\n if (!this.dbg) this.status(\"Stopped\");\n }\n this.flags.complete = fComplete;\n return fStopped;\n }\n\n /**\n * yieldCPU()\n *\n * Similar to stopCPU() with regard to how it resets various cycle countdown values, but the CPU\n * remains in a \"running\" state.\n *\n * @this {CPUPDP11}\n */\n yieldCPU()\n {\n this.endBurst(); // this will break us out of stepCPU()\n this.nCyclesNextYield = 0; // this will break us out of runCPU(), once we break out of stepCPU()\n /*\n * The Debugger calls yieldCPU() after every message() to ensure browser responsiveness, but it looks\n * odd for those messages to show CPU state changes if the Control Panel, Video display, etc, does not,\n * so I've added this call to try to keep things looking synchronized.\n */\n this.updateDisplays();\n }\n}\n\n/*\n * Constants that control the frequency at which various updates should occur.\n *\n * These values do NOT control the simulation directly. Instead, they are used by\n * calcCycles(), which uses the nCyclesPerSecond passed to the constructor as a starting\n * point and computes the following variables:\n *\n * this.nCyclesPerYield: (this.nCyclesPerSecond / CPUPDP11.YIELDS_PER_SECOND)\n *\n * The above variables are also multiplied by any cycle multiplier in effect, via setSpeed(),\n * and then they're used to initialize another set of variables for each runCPU() iteration:\n *\n * this.nCyclesNextYield: this.nCyclesPerYield\n */\nCPUPDP11.YIELDS_PER_SECOND = 30; // just a gut feeling for the MINIMUM number of yields per second\nCPUPDP11.YIELDS_PER_STATUS = 15; // every 15 yields (ie, twice per second), perform CPU status updates\n\nCPUPDP11.BUTTONS = [\"power\", \"reset\"];\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/cpustate.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * Overview of Device Interrupt Support\n *\n * Originally, the CPU maintained a queue of requested interrupts. Entries in this queue recorded a device's\n * priority, vector, and delay (ie, a number of instructions to execute before dispatching the interrupt). This\n * queue would constantly grow and shrink as requests were issued and dispatched, and as long as there was something\n * in the queue, the CPU was constantly examining it.\n *\n * Now we are trying something more efficient. First, for devices that require delays (like the SerialPort's receiver\n * and transmitter buffer registers, which are supposed to \"clock\" the data in and out at a specific baud rate), the\n * CPU offers timer services that will \"fire\" a callback after a specified delay, which are much more efficient than\n * requiring the CPU to dive into an interrupt queue and decrement delay counts on every instruction.\n *\n * Second, devices that generate interrupts will allocate an IRQ object during initialization; we will no longer\n * be creating and destroying interrupt event objects and inserting/deleting them in a constantly changing queue.\n * Each IRQ contains properties that never change (eg, the vector and priority), along with a \"next\" pointer that's\n * only used when the IRQ is active.\n *\n * When a device decides it's time to interrupt (either at the end of some I/O operation or when a timer has fired),\n * it will simply set the IRQ, which basically means that the IRQ will be linked onto a list of active IRQs, in\n * priority order, so that when the CPU is ready to acknowledge interrupts, it need only check the top of the active\n * IRQ list.\n */\n\n/**\n * @typedef {{\n * vector: number,\n * priority: number,\n * message: number,\n * next: (IRQ|null)\n * }}\n */\nvar IRQ;\n\nclass CPUStatePDP11 extends CPUPDP11 {\n /**\n * CPUStatePDP11(parmsCPU)\n *\n * The CPUStatePDP11 class uses the following (parmsCPU) properties:\n *\n * model: a number (eg, 1170) that should match one of the PDP11.MODEL_* values\n * addrReset: reset address (default is 0)\n *\n * This extends the CPU class and passes any remaining parmsCPU properties to the CPU class\n * constructor, along with a default speed (cycles per second) based on the specified\n * (or default) CPU model number.\n *\n * After looking over the timings of PDP-11/70 instructions, nearly all of them appear\n * to be multiples of 150ns. So that's what we'll consider a cycle. How many 150ns are\n * in one second? Approximately 6666667. So by way of comparison to other PCjs machines,\n * that makes the PDP-11 (or at least the PDP-11/70) look like a 6.67Mhz machine.\n *\n * I've started with the PDP-11/70, since that's what Paul Nankervis started with. When\n * I go back and add support for earlier PDP-11 models (primarily by neutering functions\n * that didn't exist), I will no doubt have to tweak some instruction cycle counts, too.\n *\n * Examples of operations that take 1 extra cycle (150ns): single and double operand byte\n * instructions with an odd address (except MOV/MTPI/MTPD/JMP/JRS), ADD/SUB/BIC/BIS/MOVB/CMP/BIT\n * instructions with src of R1-R7 and dst of R6-R7, RORB/ASRB with an odd address, and each\n * shift of ASH/ASHC. As you can see, the rules are not simple.\n *\n * We're not simulating cache hardware, but our timings should be optimistic and assume 100%\n * cache hits; for cache hits, each read cycle is 300ns. As for write cycles, they are always\n * 750ns. My initial take on DEC's timings is that they are including the write time as part\n * of the total EF (execute/fetch) time. So, for instructions that write to memory, it looks\n * like we'll normally need to add 5 cycles (750/150) to the instruction's base time, but\n * we'll need to keep an eye out for exceptions.\n *\n * @param {Object} parmsCPU\n */\n constructor(parmsCPU)\n {\n var nCyclesDefault = 0;\n var model = +parmsCPU['model'] || PDP11.MODEL_1170;\n\n switch(model) {\n case PDP11.MODEL_1170:\n default:\n nCyclesDefault = 6666667;\n break;\n }\n\n /*\n * ES6 ALERT: Classes cannot access \"this\" until all superclasses have been initialized as well.\n */\n super(parmsCPU, nCyclesDefault);\n\n this.model = model;\n this.addrReset = +parmsCPU['addrReset'] || 0;\n\n /*\n * These properties will be initialized by initCPU()\n */\n this.flagC = this.flagV = this.flagZ = this.flagN = 0;\n this.regPSW = this.pswMode = 0;\n this.pswTrap = 0;\n this.regsGen = this.regsAlt = this.regsAltStack = [];\n this.regsPAR = this.regsPDR = this.regsUniMap = this.regsControl = [];\n this.opFlags = 0;\n\n /*\n * These properties will be initialized by initMMU()\n */\n this.regMMR0 = this.regMMR1 = this.regMMR2 = this.regMMR3 = 0;\n this.regErr = this.regMBR = this.regPIR = this.regSLR = 0;\n this.mmuEnable = this.mmuLastMode = this.mmuLastPage = this.mmuMask = 0;\n this.addrLast = this.opLast = this.addrInvalid = 0;\n\n this.mapMMR3 = [4,2,0,1]; // map from mode to MMR3 I/D bit\n\n /*\n * Initialize processor operation to match the requested model.\n *\n * offRegSrc is a bias added to the register index calculated in readSrcWord() and readSrcByte(),\n * and by default has no effect on the register index, UNLESS this is a PDP-11/20, in which case the\n * bias is changed to 8 and we return one of the negative values you see above. Those negative values\n * act as signals to writeDstWord() and writeDstByte(), effectively delaying evaluation of the register\n * until then.\n */\n this.offRegSrc = 0;\n this.maskRegSrcByte = 0xff;\n\n if (this.model <= PDP11.MODEL_1120) {\n this.opDecode = PDP11.op1120.bind(this);\n this.checkStackLimit = this.checkStackLimit1120;\n this.offRegSrc = 8;\n this.maskRegSrcByte = -1;\n this.pswUsed = ~(PDP11.PSW.UNUSED | PDP11.PSW.REGSET | PDP11.PSW.PMODE | PDP11.PSW.CMODE) & 0xffff;\n this.pswRegSet = 0;\n } else {\n this.opDecode = PDP11.op1140.bind(this);\n this.checkStackLimit = this.checkStackLimit1140;\n /*\n * The alternate register set (REGSET) doesn't exist on the 11/20 or 11/40; it's available on the 11/45 and 11/70.\n * Ditto for separate I/D spaces, SUPER mode, and the instructions MFPD, MTPD, and SPL.\n */\n this.pswUsed = ~(PDP11.PSW.UNUSED | (this.model <= PDP11.MODEL_1140? PDP11.PSW.REGSET : 0)) & 0xffff;\n this.pswRegSet = (this.model > PDP11.MODEL_1140? PDP11.PSW.REGSET : 0);\n }\n\n this.nDisableTraps = 0;\n this.trapVector = this.trapReason = 0;\n\n /** @type {IRQ|null} */\n this.irqNext = null; // the head of the active IRQ list, in priority order\n\n /** @type {Array.<IRQ>} */\n this.aIRQs = []; // list of all IRQs, active or not (to be used for auto-configuration)\n\n this.getByte = this.getByteDirect = this.getByteChecked;\n this.getWord = this.getWordDirect = this.getWordChecked;\n this.setByte = this.setByteDirect = this.setByteChecked;\n this.setWord = this.setWordDirect = this.setWordChecked;\n this.nReadBreaks = this.nWriteBreaks = 0;\n\n this.addrDSpace = this.addrIOPage = 0;\n this.getAddr = this.getVirtualAddrByMode;\n this.readWord = this.readWordFromVirtual;\n this.writeWord = this.writeWordToVirtual;\n\n this.srcMode = this.srcReg = 0;\n this.dstMode = this.dstReg = this.dstAddr = 0;\n\n this.flags.complete = false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * Called once the Bus has been initialized.\n *\n * @this {CPUStatePDP11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUPDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n super.initBus(cmp, bus, cpu, dbg);\n this.getByteDirect = bus.getByte.bind(bus);\n this.getWordDirect = bus.getWord.bind(bus);\n this.setByteDirect = bus.setByte.bind(bus);\n this.setWordDirect = bus.setWord.bind(bus);\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * We hook the powerUp() notification only because it's our best opportunity to take care of any\n * floating vector assignments.\n *\n * @this {CPUStatePDP11}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n var vectorFloating = 0o300;\n for (var i = 0; i < this.aIRQs.length; i++) {\n var irq = this.aIRQs[i];\n if (irq.vector < 0) {\n irq.vector = vectorFloating;\n vectorFloating += 4;\n }\n }\n return super.powerUp(data, fRepower);\n }\n\n /**\n * reset()\n *\n * @this {CPUStatePDP11}\n */\n reset()\n {\n this.status(\"Model \" + this.model);\n if (this.flags.running) this.stopCPU();\n this.initCPU();\n this.resetCycles();\n this.clearError(); // clear any fatal error/exception that setError() may have flagged\n super.reset();\n }\n\n /**\n * initCPU()\n *\n * WARNING: It's tempting to call this function as early as the constructor() or initBus() calls, but\n * but we actually need to wait until our reset() or restore() function is called by the powerUp() handler,\n * ensuring that all device memory allocations have finished. Only then is it safe to make the first call\n * to initCPU() -> initMMU() -> setMemoryAccess() -> Bus.setIOPageRange() and sync the Bus memory map with\n * the CPU memory map.\n *\n * @this {CPUStatePDP11}\n */\n initCPU()\n {\n /*\n * TODO: Verify the initial state of all PDP-11 flags and registers (are they well-documented?)\n */\n var f = 0xffff;\n this.flagC = 0x10000; // PSW C bit\n this.flagV = 0x8000; // PSW V bit\n this.flagZ = f; // PSW Z bit (TODO: Why do we clear instead of set Z, like other flags?)\n this.flagN = 0x8000; // PSW N bit\n this.regPSW = 0x000f; // PSW other bits (TODO: What's the point of setting the flag bits here, too?)\n\n this.regsGen = [ // General R0-R7\n 0, 0, 0, 0, 0, 0, 0, this.addrReset, -1, -2, -3, -4, -5, -6, -7, -8\n ];\n this.regsAlt = [ // Alternate R0-R5\n 0, 0, 0, 0, 0, 0\n ];\n this.regsAltStack = [ // Alternate R6 stack pointers (KERNEL, SUPER, UNUSED, USER)\n 0, 0, 0, 0\n ];\n this.regsPAR = [ // memory management PAR registers by mode\n [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // KERNEL (8 KIPAR regs followed by 8 KDPAR regs)\n [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // SUPER (8 SIPDR regs followed by 8 SDPDR regs)\n [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // mode 2 (not used)\n [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] // USER (8 UIPDR regs followed by 8 UDPDR regs)\n ];\n this.regsPDR = [ // memory management PDR registers by mode\n [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // KERNEL (8 KIPDR regs followed by 8 KDPDR regs)\n [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // SUPER (8 SIPDR regs followed by 8 SDPDR regs)\n [f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f], // mode 2 (not used)\n [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] // USER (8 UIPDR regs followed by 8 UDPDR regs)\n ];\n this.regsUniMap = [ // 32 UNIBUS map registers\n 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\n ];\n this.regsControl = [ // various control registers (177740-177756) we don't really care about\n 0, 0, 0, 0, 0, 0, 0, 0\n ];\n\n this.pswMode = 0; // current memory management mode (see PDP11.MODE.KERNEL | SUPER | UNUSED | USER)\n this.pswTrap = -1;\n this.regMBR = 0;\n\n /*\n * opFlags contains various conditions that stepCPU() needs to be aware of.\n */\n this.opFlags = 0;\n\n /*\n * srcMode and srcReg are set by SRCMODE decodes, and dstMode and dstReg are set for DSTMODE decodes,\n * indicating to the opcode handlers the mode(s) and register(s) used as part of the current opcode, so\n * that they can calculate the correct number of cycles. dstAddr is set for byte operations that also\n * need to know the effective address for their cycle calculation.\n */\n this.srcMode = this.srcReg = 0;\n this.dstMode = this.dstReg = this.dstAddr = 0;\n\n this.initMMU();\n }\n\n /**\n * initMMU()\n *\n * Reset all registers required as part of a RESET instruction.\n *\n * TODO: Do we ever need to automatically clear regErr, or is it cleared manually?\n *\n * @this {CPUStatePDP11}\n */\n initMMU()\n {\n this.regMMR0 = 0; // 177572\n this.regMMR1 = 0; // 177574\n this.regMMR2 = 0; // 177576\n this.regMMR3 = 0; // 172516\n this.regErr = 0; // 177766\n this.regPIR = 0; // 177772\n this.regSLR = 0xff; // 177774\n this.mmuEnable = 0; // MMU enabled for PDP11.ACCESS.READ or PDP11.ACCESS.WRITE\n this.mmuLastMode = 0;\n this.mmuLastPage = 0;\n this.mmuMask = 0x3ffff;\n\n /*\n * This is queried and displayed by the Panel when it's not displaying its own ADDRESS register\n * (which takes precedence when, for example, you've manually halted the CPU and are independently\n * examining the contents of other addresses).\n *\n * We initialize it to whatever the current PC is, because according to @paulnank's pdp11.js: \"Reset\n * displays next instruction address\" and initMMU() is called on a RESET.\n */\n this.addrLast = this.regsGen[7];\n\n /*\n * This stores the PC in the lower 16 bits, and any auto-incs or auto-decs from the last opcode in the\n * upper 16 bits; the lower 16 bits are used to update MMR2, and the upper 16 bits are used to update MMR1.\n * The upper bits are automatically zeroed at the start of every operation when the PC is copied to opLast.\n */\n this.opLast = 0;\n\n this.resetIRQs();\n\n /*\n * As initCPU() explains, we shouldn't be calling this function until well after initBus() has been\n * called, but we still make absolutely sure we have Bus access.\n */\n if (this.bus) {\n this.setMemoryAccess();\n this.addrInvalid = this.bus.getMemoryLimit(MemoryPDP11.TYPE.RAM);\n }\n }\n\n /**\n * getMMUState()\n *\n * Returns bit 0 set if 22-bit, bit 1 set if 18-bit, or bit 2 set if 16-bit; used by the Panel component.\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getMMUState()\n {\n return this.mmuEnable? ((this.regMMR3 & PDP11.MMR3.MMU_22BIT)? 1 : 2) : 4;\n }\n\n /**\n * resetCPU()\n *\n * @this {CPUStatePDP11}\n */\n resetCPU()\n {\n this.bus.reset();\n this.initMMU();\n }\n\n /**\n * setMemoryAccess()\n *\n * Define handlers and DSPACE setting appropriate for the current MMU mode, in order to eliminate unnecessary calls\n * to mapVirtualToPhysical().\n *\n * @this {CPUStatePDP11}\n */\n setMemoryAccess()\n {\n this.getByte = this.getByteDirect;\n this.getWord = this.getWordDirect;\n this.setByte = this.setByteDirect;\n this.setWord = this.setWordDirect;\n if (this.nReadBreaks) {\n this.getByte = this.getByteChecked;\n this.getWord = this.getWordChecked;\n }\n if (this.nWriteBreaks) {\n this.setByte = this.setByteChecked;\n this.setWord = this.setWordChecked;\n }\n if (this.mmuEnable) {\n this.addrDSpace = PDP11.ACCESS.DSPACE;\n this.addrIOPage = (this.regMMR3 & PDP11.MMR3.MMU_22BIT)? BusPDP11.IOPAGE_22BIT : BusPDP11.IOPAGE_18BIT;\n this.getAddr = this.getVirtualAddrByMode;\n this.readWord = this.nReadBreaks? this.readWordFromVirtualChecked : this.readWordFromVirtual;\n this.writeWord = this.nWriteBreaks? this.writeWordToVirtualChecked : this.writeWordToVirtual;\n this.bus.setIOPageRange((this.regMMR3 & PDP11.MMR3.MMU_22BIT)? 22 : 18);\n } else {\n this.addrDSpace = 0;\n this.addrIOPage = BusPDP11.IOPAGE_16BIT;\n this.getAddr = this.getPhysicalAddrByMode;\n this.readWord = this.nReadBreaks? this.readWordFromPhysicalChecked : this.readWordFromPhysical;\n this.writeWord = this.nWriteBreaks? this.writeWordToPhysicalChecked : this.writeWordToPhysical;\n this.bus.setIOPageRange(16);\n }\n }\n\n /**\n * getMMR0()\n *\n * NOTE: It's OK to bypass this function if you're only interested in bits that always stored directly in MMR0.\n *\n * 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 MMR0\n * nonr leng read trap unus unus ena mnt cmp -mode- i/d --page-- enable\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getMMR0()\n {\n var data = this.regMMR0;\n if (!(data & PDP11.MMR0.ABORT)) {\n data = (data & ~(PDP11.MMR0.UNUSED | PDP11.MMR0.PAGE | PDP11.MMR0.MODE)) | (this.mmuLastMode << 5) | (this.mmuLastPage << 1);\n }\n return data;\n }\n\n /**\n * setMMR0()\n *\n * @this {CPUStatePDP11}\n * @param {number} newMMR0\n */\n setMMR0(newMMR0)\n {\n newMMR0 &= ~PDP11.MMR0.UNUSED;\n\n if (this.regMMR0 != newMMR0) {\n if (newMMR0 & PDP11.MMR0.ABORT) {\n /*\n * If updates to MMR0[1-7], MMR1, and MMR2 are being shut off (ie, MMR0.ABORT bits are transitioning\n * from clear to set), then do one final sync with their real-time counterparts in opLast.\n */\n if (!(this.regMMR0 & PDP11.MMR0.ABORT)) {\n this.regMMR1 = (this.opLast >> 16) & 0xffff;\n this.regMMR2 = this.opLast & 0xffff;\n }\n }\n /*\n * NOTE: We are not protecting the read-only state of the COMPLETED bit here; that's handled by writeMMR0().\n */\n this.regMMR0 = newMMR0;\n this.mmuLastMode = (newMMR0 & PDP11.MMR0.MODE) >> PDP11.MMR0.SHIFT.MODE;\n this.mmuLastPage = (newMMR0 & PDP11.MMR0.PAGE) >> PDP11.MMR0.SHIFT.PAGE;\n var mmuEnable = 0;\n if (newMMR0 & (PDP11.MMR0.ENABLED | PDP11.MMR0.MAINT)) {\n mmuEnable = PDP11.ACCESS.WRITE;\n if (newMMR0 & PDP11.MMR0.ENABLED) mmuEnable |= PDP11.ACCESS.READ;\n }\n if (this.mmuEnable != mmuEnable) {\n this.mmuEnable = mmuEnable;\n this.setMemoryAccess();\n }\n }\n }\n\n /**\n * getMMR1()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getMMR1()\n {\n /*\n * If updates to MMR1 have not been shut off (ie, MMR0.ABORT bits are clear), then we are allowed\n * to sync MMR1 with its real-time counterpart in opLast.\n *\n * UPDATE: Apparently, I was mistaken that this register would only be updated when the MMR0 ENABLED\n * bit was set.\n *\n * if ((this.regMMR0 & (PDP11.MMR0.ABORT | PDP11.MMR0.ENABLED)) == PDP11.MMR0.ENABLED)\n */\n if (!(this.regMMR0 & PDP11.MMR0.ABORT)) {\n this.regMMR1 = (this.opLast >> 16) & 0xffff;\n }\n var result = this.regMMR1;\n if (result & 0xff00) {\n result = ((result << 8) | (result >> 8)) & 0xffff;\n }\n return result;\n }\n\n /**\n * getMMR2()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getMMR2()\n {\n /*\n * If updates to MMR2 have not been shut off (ie, MMR0.ABORT bits are clear), then we are allowed\n * to sync MMR2 with its real-time counterpart in opLast.\n *\n * UPDATE: Apparently, I was mistaken that this register would only be updated when the MMR0 ENABLED\n * bit was set.\n *\n * if ((this.regMMR0 & (PDP11.MMR0.ABORT | PDP11.MMR0.ENABLED)) == PDP11.MMR0.ENABLED)\n */\n if (!(this.regMMR0 & PDP11.MMR0.ABORT)) {\n this.regMMR2 = this.opLast & 0xffff;\n }\n return this.regMMR2;\n }\n\n /**\n * getMMR3()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getMMR3()\n {\n return this.regMMR3;\n }\n\n /**\n * setMMR3()\n *\n * @this {CPUStatePDP11}\n * @param {number} newMMR3\n */\n setMMR3(newMMR3)\n {\n /*\n * Don't allow non-11/70 models to use 22-bit addressing or the UNIBUS map.\n */\n if (this.model < PDP11.MODEL_1170) {\n newMMR3 &= ~(PDP11.MMR3.MMU_22BIT | PDP11.MMR3.UNIBUS_MAP);\n }\n if (this.regMMR3 != newMMR3) {\n this.regMMR3 = newMMR3;\n this.mmuMask = (newMMR3 & PDP11.MMR3.MMU_22BIT)? BusPDP11.MASK_22BIT : BusPDP11.MASK_18BIT;\n this.setMemoryAccess();\n }\n }\n\n /**\n * setReset(addr, fStart, bUnit, addrStack)\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @param {boolean} [fStart] (true if a \"startable\" image was just loaded, false if not)\n * @param {number} [bUnit] (boot unit #)\n * @param {number} [addrStack]\n */\n setReset(addr, fStart, bUnit, addrStack)\n {\n this.addrReset = addr;\n\n this.setPC(addr);\n this.setPSW(0);\n\n this.resetCPU();\n\n if (fStart) {\n this.regsGen[0] = bUnit || 0;\n for (var i = 1; i <= 5; i++) this.regsGen[i] = 0;\n this.regsGen[6] = addrStack || 0o2000;\n if (!this.flags.powered) {\n this.flags.autoStart = true;\n }\n else if (!this.flags.running) {\n this.startCPU();\n }\n }\n else {\n if (this.dbg && this.flags.powered) {\n /*\n * TODO: Review the decision to always stop the CPU if the Debugger is loaded. Note that\n * when stopCPU() stops a running CPU, the Debugger gets notified, so no need to notify it again.\n *\n * TODO: There are more serious problems to deal with if another component is slamming a new PC down\n * the CPU's throat (presumably while also dropping some new code into RAM) while the CPU is running;\n * we should probably force a complete reset, but for now, it's up to the user to hit the reset button\n * themselves.\n */\n if (!this.stopCPU() && !this.cmp.flags.reset) {\n this.dbg.updateStatus();\n this.cmp.updateDisplays(-1);\n }\n }\n else if (fStart === false) {\n this.stopCPU();\n }\n }\n if (!this.isRunning() && this.panel) this.panel.stop();\n }\n\n /**\n * getChecksum()\n *\n * TODO: Implement\n *\n * @this {CPUStatePDP11}\n * @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code)\n */\n getChecksum()\n {\n return 0;\n }\n\n /**\n * save()\n *\n * @this {CPUStatePDP11}\n * @return {Object|null}\n */\n save()\n {\n var state = new State(this);\n state.set(0, [\n this.regsGen,\n this.regsAlt,\n this.regsAltStack,\n this.regsPAR,\n this.regsPDR,\n this.regsUniMap,\n this.regsControl,\n this.regErr,\n this.regMBR,\n this.regPIR,\n this.regSLR,\n this.mmuLastMode,\n this.mmuLastPage,\n this.addrLast,\n this.opFlags,\n this.opLast,\n this.pswTrap,\n this.trapReason,\n this.trapVector,\n this.addrReset\n ]);\n state.set(1, [this.getPSW(),this.getMMR0(),this.getMMR1(),this.getMMR2(),this.getMMR3()]);\n state.set(2, [this.nTotalCycles, this.getSpeed(), this.flags.autoStart]);\n state.set(3, this.saveIRQs());\n state.set(4, this.saveTimers());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * @this {CPUStatePDP11}\n * @param {Object} data\n * @return {boolean} true if restore successful, false if not\n */\n restore(data)\n {\n /*\n * ES6 ALERT: A handy destructuring assignment, which makes it easy to perform the inverse\n * of what save() does when it collects a bunch of object properties into an array.\n */\n [\n this.regsGen,\n this.regsAlt,\n this.regsAltStack,\n this.regsPAR,\n this.regsPDR,\n this.regsUniMap,\n this.regsControl,\n this.regErr,\n this.regMBR,\n this.regPIR,\n this.regSLR,\n this.mmuLastMode,\n this.mmuLastPage,\n this.addrLast,\n this.opFlags,\n this.opLast,\n this.pswTrap,\n this.trapReason,\n this.trapVector,\n this.addrReset\n ] = data[0];\n\n var a = data[1];\n this.setPSW(a[0]);\n this.setMMR0(a[1]);\n this.regMMR1 = a[2];\n this.regMMR2 = a[3];\n this.setMMR3(a[4]);\n\n a = data[2];\n this.nTotalCycles = a[0];\n this.setSpeed(a[1]);\n this.flags.autoStart = a[2];\n\n this.restoreIRQs(data[3]);\n this.restoreTimers(data[4]);\n return true;\n }\n\n /**\n * clearCF()\n *\n * @this {CPUStatePDP11}\n */\n clearCF()\n {\n this.flagC = 0;\n }\n\n /**\n * getCF()\n *\n * @this {CPUStatePDP11}\n * @return {number} 0 or PDP11.PSW.CF\n */\n getCF()\n {\n return (this.flagC & 0x10000)? PDP11.PSW.CF: 0;\n }\n\n /**\n * setCF()\n *\n * @this {CPUStatePDP11}\n */\n setCF()\n {\n this.flagC = 0x10000;\n }\n\n /**\n * clearVF()\n *\n * @this {CPUStatePDP11}\n */\n clearVF()\n {\n this.flagV = 0;\n }\n\n /**\n * getVF()\n *\n * @this {CPUStatePDP11}\n * @return {number} 0 or PDP11.PSW.VF\n */\n getVF()\n {\n return (this.flagV & 0x8000)? PDP11.PSW.VF: 0;\n }\n\n /**\n * setVF()\n *\n * @this {CPUStatePDP11}\n */\n setVF()\n {\n this.flagV = 0x8000;\n }\n\n /**\n * clearZF()\n *\n * @this {CPUStatePDP11}\n */\n clearZF()\n {\n this.flagZ = 1;\n }\n\n /**\n * getZF()\n *\n * @this {CPUStatePDP11}\n * @return {number} 0 or PDP11.PSW.ZF\n */\n getZF()\n {\n return (this.flagZ & 0xffff)? 0 : PDP11.PSW.ZF;\n }\n\n /**\n * setZF()\n *\n * @this {CPUStatePDP11}\n */\n setZF()\n {\n this.flagZ = 0;\n }\n\n /**\n * clearNF()\n *\n * @this {CPUStatePDP11}\n */\n clearNF()\n {\n this.flagN = 0;\n }\n\n /**\n * getNF()\n *\n * @this {CPUStatePDP11}\n * @return {number} 0 or PDP11.PSW.NF\n */\n getNF()\n {\n return (this.flagN & 0x8000)? PDP11.PSW.NF : 0;\n }\n\n /**\n * setNF()\n *\n * @this {CPUStatePDP11}\n */\n setNF()\n {\n this.flagN = 0x8000;\n }\n\n /**\n * getOpcode()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getOpcode()\n {\n var pc = this.opLast = this.regsGen[PDP11.REG.PC];\n /*\n * If PC is unaligned, a BUS trap will be generated, and because it will generate an\n * exception, the next line (the equivalent of advancePC(2)) will not be executed, ensuring that\n * original unaligned PC will be pushed onto the stack by trap().\n */\n var opCode = this.readWord(pc);\n this.regsGen[PDP11.REG.PC] = (pc + 2) & 0xffff;\n return opCode;\n }\n\n /**\n * advancePC(off)\n *\n * NOTE: This function is nothing more than a convenience, and we fully expect it to be inlined at runtime.\n *\n * @this {CPUStatePDP11}\n * @param {number} off\n * @return {number} (original PC)\n */\n advancePC(off)\n {\n var pc = this.regsGen[PDP11.REG.PC];\n this.regsGen[PDP11.REG.PC] = (pc + off) & 0xffff;\n return pc;\n }\n\n /**\n * branch(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @param {boolean|number} condition\n */\n branch(opCode, condition)\n {\n if (condition) {\n var off = ((opCode << 24) >> 23);\n if (DEBUG && DEBUGGER && this.dbg && off == -2) {\n this.dbg.stopInstruction(\"branch to self\");\n }\n this.setPC(this.getPC() + off);\n this.nStepCycles -= 2;\n }\n this.nStepCycles -= (2 + 1);\n }\n\n /**\n * getPC()\n *\n * NOTE: This function is nothing more than a convenience, and we fully expect it to be inlined at runtime.\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getPC()\n {\n return this.regsGen[PDP11.REG.PC];\n }\n\n /**\n * getLastAddr()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getLastAddr()\n {\n return this.addrLast;\n }\n\n /**\n * getLastPC()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getLastPC()\n {\n return this.opLast & 0xffff;\n }\n\n /**\n * setPC()\n *\n * NOTE: Unlike other PCjs emulators, such as PCx86, where all PC updates MUST go through the setPC()\n * function, this function is nothing more than a convenience, because in the PDP-11, the PC can be loaded\n * like any other general register. We fully expect this function to be inlined at runtime.\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n */\n setPC(addr)\n {\n this.regsGen[PDP11.REG.PC] = addr & 0xffff;\n }\n\n /**\n * getSP()\n *\n * NOTE: This function is nothing more than a convenience, and we fully expect it to be inlined at runtime.\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getSP()\n {\n return this.regsGen[PDP11.REG.SP];\n }\n\n /**\n * setSP()\n *\n * NOTE: Unlike other PCjs emulators, such as PCx86, where all SP updates MUST go through the setSP()\n * function, this function is nothing more than a convenience, because in the PDP-11, the PC can be loaded\n * like any other general register. We fully expect this function to be inlined at runtime.\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n */\n setSP(addr)\n {\n this.regsGen[PDP11.REG.SP] = addr & 0xffff;\n }\n\n /**\n * addIRQ(vector, priority, message)\n *\n * @this {CPUStatePDP11}\n * @param {number} vector (-1 for floating vector)\n * @param {number} priority\n * @param {number} [message]\n * @return {IRQ}\n */\n addIRQ(vector, priority, message)\n {\n var irq = {vector: vector, priority: priority, message: message || 0, name: PDP11.VECTORS[vector], next: null};\n this.aIRQs.push(/** @type {IRQ} */ (irq)); // TODO: Why the F*CK do I need a type override? Damn JSDoc types....\n return irq;\n }\n\n /**\n * insertIRQ(irq)\n *\n * @this {CPUStatePDP11}\n * @param {IRQ} irq\n */\n insertIRQ(irq)\n {\n if (irq != this.irqNext) {\n var irqPrev = this.irqNext;\n if (!irqPrev || irqPrev.priority <= irq.priority) {\n irq.next = irqPrev;\n this.irqNext = irq;\n } else {\n do {\n var irqNext = irqPrev.next;\n if (!irqNext || irqNext.priority <= irq.priority) {\n irq.next = irqNext;\n irqPrev.next = irq;\n break;\n }\n irqPrev = irqNext;\n } while (irqPrev);\n }\n }\n /*\n * See the writeXCSR() function for an explanation of why signalling an IRQ hardware interrupt\n * should be done using IRQ_DELAY rather than setting IRQ directly.\n */\n this.opFlags |= PDP11.OPFLAG.IRQ_DELAY;\n }\n\n /**\n * removeIRQ(irq)\n *\n * @this {CPUStatePDP11}\n * @param {IRQ} irq\n */\n removeIRQ(irq)\n {\n var irqPrev = this.irqNext;\n if (irqPrev == irq) {\n this.irqNext = irq.next;\n } else {\n while (irqPrev) {\n var irqNext = irqPrev.next;\n if (irqNext == irq) {\n irqPrev.next = irqNext.next;\n break;\n }\n irqPrev = irqNext;\n }\n }\n /*\n * We could also set irq.next to null now, but strictly speaking, that shouldn't be necessary.\n *\n * Last but not least, if there's still an IRQ on the active IRQ list, we need to make sure IRQ_DELAY\n * is still set.\n */\n if (this.irqNext) {\n this.opFlags |= PDP11.OPFLAG.IRQ_DELAY;\n }\n }\n\n /**\n * setIRQ(irq)\n *\n * @this {CPUStatePDP11}\n * @param {IRQ|null} irq\n */\n setIRQ(irq)\n {\n if (irq) {\n this.insertIRQ(irq);\n if (irq.message && this.messageEnabled(irq.message | MessagesPDP11.INT)) {\n this.printMessage(\"setIRQ(vector=\" + Str.toOct(irq.vector) + \",priority=\" + irq.priority + \")\", true, true);\n }\n }\n }\n\n /**\n * clearIRQ(irq)\n *\n * @this {CPUStatePDP11}\n * @param {IRQ|null} irq\n */\n clearIRQ(irq)\n {\n if (irq) {\n this.removeIRQ(irq);\n if (irq.message && this.messageEnabled(irq.message | MessagesPDP11.INT)) {\n this.printMessage(\"clearIRQ(vector=\" + Str.toOct(irq.vector) + \",priority=\" + irq.priority + \")\", true, true);\n }\n }\n }\n\n /**\n * findIRQ(vector)\n *\n * @this {CPUStatePDP11}\n * @param {number} vector\n * @return {IRQ|null}\n */\n findIRQ(vector)\n {\n for (var i = 0; i < this.aIRQs.length; i++) {\n var irq = this.aIRQs[i];\n if (irq.vector === vector) return irq;\n }\n return null;\n }\n\n /**\n * checkIRQs(priority)\n *\n * @this {CPUStatePDP11}\n * @param {number} priority\n * @return {IRQ|null}\n */\n checkIRQs(priority)\n {\n return (this.irqNext && this.irqNext.priority > priority)? this.irqNext : null;\n }\n\n /**\n * resetIRQs(priority)\n *\n * @this {CPUStatePDP11}\n */\n resetIRQs()\n {\n this.irqNext = null;\n }\n\n /**\n * saveIRQs()\n *\n * @this {CPUStatePDP11}\n * @return {Array.<number>}\n */\n saveIRQs()\n {\n var aIRQVectors = [];\n var irq = this.irqNext;\n while (irq) {\n aIRQVectors.push(irq.vector);\n irq = irq.next;\n }\n return aIRQVectors;\n }\n\n /**\n * restoreIRQs(aIRQVectors)\n *\n * @this {CPUStatePDP11}\n * @param {Array.<number>} aIRQVectors\n */\n restoreIRQs(aIRQVectors)\n {\n for (var i = aIRQVectors.length - 1; i >= 0; i--) {\n var irq = this.findIRQ(aIRQVectors[i]);\n\n if (irq) {\n irq.next = this.irqNext;\n this.irqNext = irq;\n }\n }\n }\n\n /**\n * checkInterrupts()\n *\n * @this {CPUStatePDP11}\n * @return {boolean} true if an interrupt was dispatched, false if not\n */\n checkInterrupts()\n {\n var fInterrupt = false;\n\n if (this.opFlags & PDP11.OPFLAG.IRQ) {\n\n var vector = PDP11.TRAP.PIRQ;\n var priority = (this.regPIR & PDP11.PSW.PRI) >> PDP11.PSW.SHIFT.PRI;\n\n var irq = this.checkIRQs(priority);\n if (irq) {\n vector = irq.vector;\n priority = irq.priority;\n }\n\n if (this.dispatchInterrupt(vector, priority)) {\n if (irq) this.removeIRQ(irq);\n fInterrupt = true;\n }\n\n if (!this.irqNext && !this.regPIR) {\n this.opFlags &= ~PDP11.OPFLAG.IRQ;\n }\n }\n else if (this.opFlags & PDP11.OPFLAG.IRQ_DELAY) {\n /*\n * We know that IRQ (bit 2) is clear, so since IRQ_DELAY (bit 0) is set, incrementing opFlags\n * will eventually transform IRQ_DELAY into IRQ, without affecting any other (higher) bits.\n */\n this.opFlags++;\n }\n return fInterrupt;\n }\n\n /**\n * dispatchInterrupt(vector, priority)\n *\n * TODO: The process of dispatching an interrupt MUST cost some cycles; either trap() needs to assess\n * that cost, or we do.\n *\n * @this {CPUStatePDP11}\n * @param {number} vector\n * @param {number} priority\n * @return {boolean} (true if dispatched, false if not)\n */\n dispatchInterrupt(vector, priority)\n {\n var priorityCPU = (this.regPSW & PDP11.PSW.PRI) >> PDP11.PSW.SHIFT.PRI;\n if (priority > priorityCPU) {\n if (this.opFlags & PDP11.OPFLAG.WAIT) {\n this.advancePC(2);\n this.opFlags &= ~PDP11.OPFLAG.WAIT;\n }\n this.trap(vector, 0, PDP11.REASON.INTERRUPT);\n return true;\n }\n return false;\n }\n\n /**\n * checkTraps()\n *\n * NOTE: The following code processes these \"deferred\" traps in priority order. Unfortunately, that\n * order seems to have changed since the 11/20. For reference, here's the priority list for the 11/20:\n *\n * 1. Bus Errors\n * 2. Instruction Traps\n * 3. Trace Trap\n * 4. Stack Overflow Trap\n * 5. Power Failure Trap\n *\n * and for the 11/70:\n *\n * 1. HALT (Instruction, Switch, or Command)\n * 2. MMU Faults\n * 3. Parity Errors\n * 4. Bus Errors (including stack overflow traps?)\n * 5. Floating Point Traps\n * 6. TRAP Instruction\n * 7. TRACE Trap\n * 8. OVFL Trap\n * 9. Power Fail Trap\n * 10. Console Bus Request (Front Panel Operation)\n * 11. PIR 7, BR 7, PIR 6, BR 6, PIR 5, BR 5, PIR 4, BR 4, PIR 3, BR 3, PIR 2, PIR 1\n * 12. WAIT Loop\n *\n * TODO: Determine 1) if the 11/20 Handbook was wrong, or 2) if the 11/70 really has different priorities.\n *\n * Also, as the PDP-11/20 Handbook (1971), p.100, notes:\n *\n * If a bus error is caused by the trap process handling instruction traps, trace traps, stack overflow\n * traps, or a previous bus error, the processor is halted.\n *\n * If a stack overflow is caused by the trap process in handling bus errors, instruction traps, or trace traps,\n * the process is completed and then the stack overflow trap is sprung.\n *\n * TODO: Based on the above notes, we should probably be halting the CPU when a bus error occurs during a trap.\n *\n * @this {CPUStatePDP11}\n * @return {boolean} (true if dispatched, false if not)\n */\n checkTraps()\n {\n if (this.opFlags & PDP11.OPFLAG.TRAP_MMU) {\n this.trap(PDP11.TRAP.MMU, PDP11.OPFLAG.TRAP_MMU, PDP11.REASON.FAULT);\n return true;\n }\n if (this.opFlags & PDP11.OPFLAG.TRAP_SP) {\n this.trap(PDP11.TRAP.BUS, PDP11.OPFLAG.TRAP_SP, PDP11.REASON.YELLOW);\n return true;\n }\n if (this.opFlags & PDP11.OPFLAG.TRAP_TF) {\n this.trap(PDP11.TRAP.BPT, PDP11.OPFLAG.TRAP_TF, PDP11.REASON.TRACE);\n return true;\n }\n return false;\n }\n\n /**\n * isWaiting()\n *\n * @this {CPUStatePDP11}\n * @return {boolean} (true if OPFLAG.WAIT is set, false otherwise)\n */\n isWaiting()\n {\n return !!(this.opFlags & PDP11.OPFLAG.WAIT);\n }\n\n /**\n * getPSW()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getPSW()\n {\n var mask = PDP11.PSW.CMODE | PDP11.PSW.PMODE | PDP11.PSW.REGSET | PDP11.PSW.PRI | PDP11.PSW.TF;\n return this.regPSW = (this.regPSW & mask) | this.getNF() | this.getZF() | this.getVF() | this.getCF();\n }\n\n /**\n * setPSW(newPSW)\n *\n * This updates the CPU Processor Status Word. The PSW should generally be written through\n * this routine so that changes can be tracked properly, for example the correct register set,\n * the current memory management mode, etc. An exception is SPL which writes the priority directly.\n * Note that that N, Z, V, and C flags are actually stored separately for performance reasons.\n *\n * PSW 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0\n * CMODE PMODE RS -------- PRIORITY T N Z V C\n *\n * @this {CPUStatePDP11}\n * @param {number} newPSW\n */\n setPSW(newPSW)\n {\n newPSW &= this.pswUsed;\n this.flagN = newPSW << 12;\n this.flagZ = (~newPSW) & 4;\n this.flagV = newPSW << 14;\n this.flagC = newPSW << 16;\n if ((newPSW ^ this.regPSW) & this.pswRegSet) {\n /*\n * Swap register sets\n */\n for (var i = this.regsAlt.length; --i >= 0;) {\n var tmp = this.regsGen[i];\n this.regsGen[i] = this.regsAlt[i];\n this.regsAlt[i] = tmp;\n }\n }\n this.pswMode = (newPSW >> PDP11.PSW.SHIFT.CMODE) & PDP11.MODE.MASK;\n var oldMode = (this.regPSW >> PDP11.PSW.SHIFT.CMODE) & PDP11.MODE.MASK;\n if (this.pswMode != oldMode) {\n /*\n * Swap stack pointers\n */\n this.regsAltStack[oldMode] = this.regsGen[6];\n this.regsGen[6] = this.regsAltStack[this.pswMode];\n }\n this.regPSW = newPSW;\n\n /*\n * Trigger a call to checkInterrupts(), just in case. If there's an active IRQ, then setting\n * OPFLAG.IRQ is a no-brainer, but even if not, we set IRQ_DELAY in case the priority was lowered\n * enough to permit a programmed interrupt (via regPIR).\n */\n this.opFlags &= ~PDP11.OPFLAG.IRQ;\n this.opFlags |= (this.irqNext? PDP11.OPFLAG.IRQ : PDP11.OPFLAG.IRQ_DELAY);\n }\n\n /**\n * getSLR()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getSLR()\n {\n return this.regSLR & 0xff00;\n }\n\n /**\n * setSLR(newSL)\n *\n * @this {CPUStatePDP11}\n * @param {number} newSLR\n */\n setSLR(newSLR)\n {\n this.regSLR = newSLR | 0xff;\n }\n\n /**\n * getPIR()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getPIR()\n {\n return this.regPIR;\n }\n\n /**\n * setPIR(newPIR)\n *\n * @this {CPUStatePDP11}\n * @param {number} newPIR\n */\n setPIR(newPIR)\n {\n newPIR &= PDP11.PIR.BITS;\n if (newPIR) {\n var bits = newPIR >> PDP11.PIR.SHIFT.BITS;\n do {\n newPIR += PDP11.PIR.PIA_INC;\n } while (bits >>= 1);\n this.opFlags |= PDP11.OPFLAG.IRQ_DELAY;\n }\n this.regPIR = newPIR;\n }\n\n /**\n * updateNZVFlags(result)\n *\n * NOTE: Only N and Z are updated based on the result; V is zeroed, C is unchanged.\n *\n * @this {CPUStatePDP11}\n * @param {number} result\n */\n updateNZVFlags(result)\n {\n this.flagN = this.flagZ = result;\n this.flagV = 0;\n }\n\n /**\n * updateNZVCFlags(result)\n *\n * NOTE: Only N and Z are updated based on the result; both V and C are simply zeroed.\n *\n * @this {CPUStatePDP11}\n * @param {number} result\n */\n updateNZVCFlags(result)\n {\n this.flagN = this.flagZ = result;\n this.flagV = this.flagC = 0;\n }\n\n /**\n * updateAllFlags(result, overflow)\n *\n * NOTE: The V flag is simply zeroed, unless a specific value is provided (eg, by NEG).\n *\n * @this {CPUStatePDP11}\n * @param {number} result\n * @param {number} [overflow]\n */\n updateAllFlags(result, overflow)\n {\n this.flagN = this.flagZ = this.flagC = result;\n this.flagV = overflow || 0;\n }\n\n /**\n * updateAddFlags(result, src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} result (dst + src)\n * @param {number} src\n * @param {number} dst\n */\n updateAddFlags(result, src, dst)\n {\n this.flagN = this.flagZ = this.flagC = result;\n this.flagV = (src ^ result) & (dst ^ result);\n }\n\n /**\n * updateDecFlags(result, dst)\n *\n * NOTE: We could have used updateSubFlags() if not for the fact that the C flag must be preserved.\n *\n * @this {CPUStatePDP11}\n * @param {number} result (dst - src, where src is an implied 1)\n * @param {number} dst\n */\n updateDecFlags(result, dst)\n {\n this.flagN = this.flagZ = result;\n /*\n * Because src is always 1 (with a zero sign bit), it can be optimized out of this calculation.\n */\n this.flagV = (/* src ^ */ dst) & (dst ^ result);\n }\n\n /**\n * updateIncFlags(result, dst)\n *\n * NOTE: We could have used updateAddFlags() if not for the fact that the C flag must be preserved.\n *\n * @this {CPUStatePDP11}\n * @param {number} result (dst + src, where src is an implied 1)\n * @param {number} dst\n */\n updateIncFlags(result, dst)\n {\n this.flagN = this.flagZ = result;\n /*\n * Because src is always 1 (with a zero sign bit), it can be optimized out of this calculation.\n */\n this.flagV = (/* src ^ */ result) & (dst ^ result);\n }\n\n /**\n * updateMulFlags(result)\n *\n * @this {CPUStatePDP11}\n * @param {number} result\n */\n updateMulFlags(result)\n {\n this.flagN = result >> 16;\n this.flagZ = this.flagN | result;\n this.flagV = 0;\n this.flagC = (result < -32768 || result > 32767)? 0x10000 : 0;\n }\n\n /**\n * updateShiftFlags(result)\n *\n * @this {CPUStatePDP11}\n * @param {number} result\n */\n updateShiftFlags(result)\n {\n this.flagN = this.flagZ = this.flagC = result;\n this.flagV = this.flagN ^ (this.flagC >> 1);\n }\n\n /**\n * updateSubFlags(result, src, dst)\n *\n * NOTE: CMP operations calculate (src - dst) rather than (dst - src), so when they call updateSubFlags(),\n * they must reverse the order of the src and dst parameters.\n *\n * @this {CPUStatePDP11}\n * @param {number} result (dst - src)\n * @param {number} src\n * @param {number} dst\n */\n updateSubFlags(result, src, dst)\n {\n this.flagN = this.flagZ = this.flagC = result;\n this.flagV = (src ^ dst) & (dst ^ result);\n }\n\n /**\n * trap(vector, flag, reason)\n *\n * trap() handles all the trap/abort functions. It reads the trap vector from kernel\n * D space, changes mode to reflect the new PSW and PC, and then pushes the old PSW and\n * PC onto the new mode stack.\n *\n * @this {CPUStatePDP11}\n * @param {number} vector\n * @param {number} flag\n * @param {number} [reason] (for diagnostic purposes only)\n */\n trap(vector, flag, reason)\n {\n if (DEBUG && this.dbg) {\n if (this.messageEnabled(MessagesPDP11.TRAP)) {\n var sReason = reason < 0? PDP11.REASONS[-reason] : this.dbg.toStrBase(reason);\n this.printMessage(\"trap to vector \" + this.dbg.toStrBase(vector, 8) + \" (\" + sReason + \")\", MessagesPDP11.TRAP, true);\n }\n }\n\n if (this.nDisableTraps) return;\n\n if (this.pswTrap < 0) {\n this.pswTrap = this.getPSW();\n } else if (!this.pswMode) {\n reason = PDP11.REASON.RED; // double-fault (nested trap) forces a RED condition\n }\n\n if (reason == PDP11.REASON.RED) {\n if (this.opFlags & PDP11.OPFLAG.TRAP_RED) {\n reason = PDP11.REASON.PANIC;\n }\n this.opFlags |= PDP11.OPFLAG.TRAP_RED;\n /*\n * The next two lines used to be deferred until after the setPSW() below, but\n * I'm not seeing any dependencies on these registers, so I'm consolidating the code.\n */\n this.regErr |= PDP11.CPUERR.RED;\n this.regsGen[6] = vector = 4;\n }\n\n if (reason != PDP11.REASON.PANIC) {\n /*\n * NOTE: Pre-setting the auto-dec values for MMR1 to 0xF6F6 is a work-around for an \"EKBEE1\"\n * diagnostic (PC 056710), which tests what happens when a misaligned read triggers a BUS trap,\n * and that trap then triggers an MMU trap during the first pushWord() below.\n *\n * One would think it would be fine to zero those bits by setting opLast to vector alone,\n * and then letting each of the pushWord() calls below shift their own 0xF6 auto-dec value into\n * opLast. When the first pushWord() triggers an MMU trap, we obviously won't get to the second\n * pushWord(), yet the diagnostic expects TWO auto-decs to be recorded. I'm puzzled why the\n * hardware apparently indicates TWO auto-decs, if SP wasn't actually decremented twice, but who\n * am I to judge.\n */\n this.opLast = vector | 0xf6f60000;\n\n /*\n * Read from kernel D space\n */\n this.pswMode = 0;\n var newPC = this.readWord(vector | this.addrDSpace);\n var newPSW = this.readWord(((vector + 2) & 0xffff) | this.addrDSpace);\n\n /*\n * Set new PSW with previous mode\n */\n this.setPSW((newPSW & ~PDP11.PSW.PMODE) | ((this.pswTrap >> 2) & PDP11.PSW.PMODE));\n\n this.pushWord(this.pswTrap);\n this.pushWord(this.regsGen[7]);\n this.setPC(newPC);\n }\n\n /*\n * TODO: Determine the appropriate number of cycles for traps; all I've done for now is move the\n * cycle charge from opTrap() to here, and reduced the amount the other opcode handlers that call\n * trap() charge by a corresponding amount (5).\n */\n this.nStepCycles -= (4 + 1);\n\n /*\n * DEC's \"TRAP TEST\" (MAINDEC-11-D0NA-PB) triggers a RESERVED trap with an invalid opcode and the\n * stack deliberately set too low, and expects the stack overflow trap to be \"sprung\" immediately\n * afterward, so we only want to \"lose interest\" in the TRAP flag(s) that were set on entry, not ALL\n * of them.\n *\n * this.opFlags &= ~PDP11.OPFLAG.TRAP_MASK; // lose interest in traps after an abort\n *\n * Well, OK, we're also supposed to \"lose interest\" in the TF flag, too; otherwise, DEC tests fail.\n *\n * Finally, setPSW() likes to always set IRQ, to force a check of hardware interrupts prior to\n * the next instruction, just in case the PSW priority was lowered. However, there are \"TRAP TEST\"\n * tests like this one:\n *\n * 005640: 012706 007700 MOV #7700,SP\n * 005644: 012767 000340 172124 MOV #340,177776\n * 005652: 012767 000100 171704 MOV #100,177564\n * 005660: 012767 005712 172146 MOV #5712,000034 ; set TRAP vector (its PSW is already zero)\n * 005666: 012767 005714 172170 MOV #5714,000064 ; set hardware interrupt vector (its PSW is already zero)\n * 005674: 012767 005716 172116 MOV #5716,000020 ; set IOT vector\n * 005702: 012767 000340 172112 MOV #340,000022 ; set IOT PSW\n * 005710: 104400 TRAP 000\n * 005712: 000004 IOT\n * 005714: 000000 HALT\n *\n * where, after \"TRAP 000\" has executed, a hardware interrupt will be acknowledged, and instead of\n * executing the IOT, we'll execute the HALT and fail the test. We avoid that by relying on the same\n * trick that the SPL instruction uses: setting IRQ_DELAY instead of IRQ, which effectively delays\n * IRQ detection for one instruction, which is just long enough to allow the diagnostic to pass.\n */\n this.opFlags &= ~(flag | PDP11.OPFLAG.TRAP_TF | PDP11.OPFLAG.IRQ_MASK);\n this.opFlags |= PDP11.OPFLAG.IRQ_DELAY | PDP11.OPFLAG.TRAP_LAST;\n\n this.pswTrap = -1; // reset flag that we have a trap within a trap\n\n /*\n * These next properties (in conjunction with setting PDP11.OPFLAG.TRAP_LAST) are purely an aid for the Debugger;\n * see getTrapStatus().\n */\n this.trapReason = reason;\n this.trapVector = vector;\n\n if (reason == PDP11.REASON.PANIC) {\n this.stopCPU();\n }\n if (reason >= PDP11.REASON.RED) throw vector;\n }\n\n /**\n * trapReturn()\n *\n * @this {CPUStatePDP11}\n */\n trapReturn()\n {\n /*\n * This code used to defer updating regsGen[6] (SP) until after BOTH words had been popped, which seems\n * safer, but if we're going to do pushes in trap(), then I see no reason to avoid doing pops in trapReturn().\n */\n var addr = this.popWord();\n var newPSW = this.popWord();\n if (this.regPSW & PDP11.PSW.CMODE) {\n /*\n * Keep SPL and allow lower only for modes and register set.\n *\n * TODO: Review, because it seems a bit odd to only CLEAR the PRI bits in the new PSW, and then to OR in\n * CMODE, PMODE, and REGSET bits from the current PSW.\n */\n newPSW = (newPSW & ~PDP11.PSW.PRI) | (this.regPSW & (PDP11.PSW.PRI | PDP11.PSW.REGSET | PDP11.PSW.PMODE | PDP11.PSW.CMODE));\n }\n this.setPC(addr);\n this.setPSW(newPSW);\n this.opFlags &= ~PDP11.OPFLAG.TRAP_TF;\n }\n\n /**\n * getTrapStatus()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n getTrapStatus()\n {\n return (this.opFlags & PDP11.OPFLAG.TRAP_LAST)? (this.trapVector | this.trapReason << 8) : 0;\n }\n\n /**\n * mapUnibus(addr)\n *\n * Used to convert 18-bit addresses to 22-bit addresses. Since mapUnibus() only looks at the low 18 bits of addr,\n * there's no need to mask addr first. Note that if bits 13-17 are all set, then the 18-bit address points to the\n * top 8Kb of its 256Kb range, and mapUnibus() will return addr unchanged, since it should already be pointing to\n * the top 8Kb of the 4Mb 22-bit range.\n *\n * Also, when bits 18-21 of addr are ALL set (which callers check using addr >= BusPDP11.UNIBUS_22BIT aka 0x3C0000),\n * then we have a 22-bit address pointing to the top 256Kb range, so if the UNIBUS relocation map is enabled, we again\n * pass the lower 18 bits of that address through the map.\n *\n * From the PDP-11/70 Handbook:\n *\n * On the 11/44 and 11/70, there are a total of 31 mapping registers for address relocation. Each register is\n * composed of a double 16-bit PDP-11 word (in consecutive locations) that holds the 22-bit base address. These\n * registers have UNIBUS addresses in the range 770200 to 770372.\n *\n * If the UNIBUS map relocation is not enabled, an incoming 18-bit UNIBUS address has 4 leading zeroes added for\n * referencing a 22-bit physical address. The lower 18 bits are the same. No relocation is performed.\n *\n * If UNIBUS map relocation is enabled, the five high order bits of the UNIBUS address are used to select one of the\n * 31 mapping registers. The low-order 13 bits of the incoming address are used as an offset from the base address\n * contained in the 22-bit mapping register. To form the physical address, the 13 low-order bits of the UNIBUS\n * address are added to 22 bits of the selected mapping register to produce the 22-bit physical address. The lowest\n * order bit of all mapping registers is always a zero, since relocation is always on word boundaries.\n *\n * Sadly, because these mappings occur at a word-granular level, we can't implement the mappings by simply shuffling\n * the underlying block around in the Bus component; it would be much more efficient if we could. That's how we move\n * the IOPAGE in response to addressing changes.\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @return {number}\n */\n mapUnibus(addr)\n {\n var idx = (addr >> 13) & 0x1F;\n if (idx < 31) {\n if (this.regMMR3 & PDP11.MMR3.UNIBUS_MAP) {\n /*\n * The UNIBUS map relocation is enabled\n */\n addr = (this.regsUniMap[idx] + (addr & 0x1FFF)) & BusPDP11.MASK_22BIT;\n /*\n * TODO: Review this assertion.\n *\n *\n */\n } else {\n /*\n * Since UNIBUS map relocation is NOT enabled, then as explained above:\n *\n * If the UNIBUS map relocation is not enabled, an incoming 18-bit UNIBUS address has 4 leading zeroes added for\n * referencing a 22-bit physical address. The lower 18 bits are the same. No relocation is performed.\n */\n addr &= ~BusPDP11.UNIBUS_22BIT;\n }\n }\n return addr;\n }\n\n /**\n * getAddrInfo(addr, fPhysical)\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @param {boolean} [fPhysical]\n * @return {Array}\n */\n getAddrInfo(addr, fPhysical)\n {\n var a = [];\n var addrPhysical;\n\n if (fPhysical) {\n addrPhysical = this.mapUnibus(addr);\n var idx = (addr >> 13) & 0x1F;\n a.push(addrPhysical);\n a.push(idx);\n if (this.regMMR3 & PDP11.MMR3.UNIBUS_MAP) {\n a.push(this.regsUniMap[idx]);\n a.push(addr & 0x1FFF);\n }\n }\n else if (!this.mmuEnable) {\n addrPhysical = addr & 0xffff;\n if (addrPhysical >= BusPDP11.IOPAGE_16BIT) addrPhysical |= this.addrIOPage;\n a.push(addrPhysical);\n }\n else {\n var mode = this.pswMode << 1;\n var page = addr >> 13;\n if (page > 7) mode |= 1;\n if (!(this.regMMR3 & this.mapMMR3[this.pswMode])) page &= 7;\n var pdr = this.regsPDR[this.pswMode][page];\n var off = addr & 0x1fff;\n var paf = (this.regsPAR[this.pswMode][page] << 6);\n addrPhysical = (paf + off) & this.mmuMask;\n if (addrPhysical >= BusPDP11.UNIBUS_22BIT) addrPhysical = this.mapUnibus(addrPhysical);\n a.push(addrPhysical); // a[0]\n a.push(off); // a[1]\n a.push(mode); // a[2] (0=KI, 1=KD, 2=SI, 3=SD, 4=??, 5=??, 6=UI, 7=UD)\n a.push(page & 7); // a[3]\n a.push(paf); // a[4]\n a.push(this.mmuMask); // a[5]\n }\n return a;\n }\n\n /**\n * mapVirtualToPhysical(addrVirtual, access)\n *\n * mapVirtualToPhysical() does memory management. It converts a 17-bit I/D virtual address to a\n * 22-bit physical address. A real PDP 11/70 memory management unit can be enabled separately for\n * read and write for diagnostic purposes. This is handled here by having an enable mask (mmuEnable)\n * which is tested against the operation access mask (access). If there is no match, then the virtual\n * address is simply mapped as a 16 bit physical address with the upper page going to the IO address\n * space. Significant access mask values used are PDP11.ACCESS.READ and PDP11.ACCESS.WRITE.\n *\n * When doing mapping, pswMode is used to decide what address space is to be used (0 = kernel,\n * 1 = supervisor, 2 = illegal, 3 = user). Normally, pswMode is set by the setPSW() function, but\n * there are exceptions for instructions which move data between address spaces (MFPD, MFPI, MTPD,\n * and MTPI) and trap(). These will modify pswMode outside of setPSW() and then restore it again if\n * all worked. If however something happens to cause a trap then no restore is done as setPSW()\n * will have been invoked as part of the trap, which will resynchronize pswMode.\n *\n * A PDP-11/70 is different from other PDP-11s in that the highest 18 bit space (017000000 & above)\n * maps directly to UNIBUS space - including low memory. This doesn't appear to be particularly useful\n * as it restricts maximum system memory - although it does appear to allow software testing of the\n * UNIBUS map. This feature also appears to confuse some OSes which test consecutive memory locations\n * to find maximum memory -- and on a full memory system find themselves accessing low memory again at\n * high addresses.\n *\n * Construction of a Physical Address\n * ----------------------------------\n *\n * Virtual Addr (VA) 12 11 10 9 8 7 6 5 4 3 2 1 0\n * + Page Addr Field (PAF) 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0\n * -----------------------------------------------------------------\n * = Physical Addr (PA) 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0\n *\n * The Page Address Field (PAF) comes from a Page Address Register (PAR) that is selected by Virtual\n * Address (VA) bits 15-13. You can see from the above alignments that the VA contributes to the low\n * 13 bits, providing an 8Kb range.\n *\n * VA bits 0-5 pass directly through to the PA; those are also called the DIB (Displacement in Block) bits.\n * VA bits 6-12 are added to the low 7 bits of the PAF and are also called the BN (Block Number) bits.\n *\n * You can also think of the entire PAF as a block number, where each block is 64 bytes. This is consistent\n * with the LSIZE register at 177760, which is supposed to contain the block number of the last 64-byte block\n * of memory installed.\n *\n * Note that if a PAR is initialized to zero, successively adding 0200 (0x80) to the PAR will advance the\n * base physical address to the next 8Kb page.\n *\n * @this {CPUStatePDP11}\n * @param {number} addrVirtual\n * @param {number} access\n * @return {number}\n */\n mapVirtualToPhysical(addrVirtual, access)\n {\n var page, pdr, addr;\n\n /*\n * This can happen when the MAINT bit of MMR0 is set but not the ENABLED bit.\n */\n if (!(access & this.mmuEnable)) {\n addr = addrVirtual & 0xffff;\n if (addr >= BusPDP11.IOPAGE_16BIT) addr |= this.addrIOPage;\n return addr;\n }\n\n page = addrVirtual >> 13;\n if (!(this.regMMR3 & this.mapMMR3[this.pswMode])) page &= 7;\n pdr = this.regsPDR[this.pswMode][page];\n addr = ((this.regsPAR[this.pswMode][page] << 6) + (addrVirtual & 0x1fff)) & this.mmuMask;\n\n if (addr >= BusPDP11.UNIBUS_22BIT) addr = this.mapUnibus(addr);\n\n if (this.nDisableTraps) return addr;\n\n /*\n * TEST #122 (\"KT BEND\") in the \"EKBEE1\" diagnostic (PC 076060) triggers a NOMEMORY error using\n * this instruction:\n *\n * 076170: 005037 140100 CLR @#140100\n *\n * It also triggers an ODDADDR error using this instruction:\n *\n * 076356: 005037 140001 CLR @#140001\n *\n * @paulnank: So it turns out that the memory management unit that does odd address and non-existent\n * memory trapping: who knew? :-) I thought these would have been handled at access time.\n *\n * @jeffpar: We're assuming, at least, that the MMU does its \"NEXM\" (NOMEMORY) non-existent memory test\n * very simplistically, by range-checking the address against something like the memory SIZE registers,\n * because otherwise the MMU would have to wait for a bus time-out: something so prohibitively expensive\n * that the MMU could not afford to do it. I rely on addrInvalid, which is derived from the same Bus\n * getMemoryLimit() service that the SIZE registers (177760--177762) use to derive their value.\n */\n if (addr >= this.addrInvalid && addr < this.addrIOPage) {\n this.regErr |= PDP11.CPUERR.NOMEMORY;\n this.trap(PDP11.TRAP.BUS, 0, addr);\n }\n else if ((addr & 0x1) && !(access & PDP11.ACCESS.BYTE)) {\n this.regErr |= PDP11.CPUERR.ODDADDR;\n this.trap(PDP11.TRAP.BUS, 0, addr);\n }\n\n var newMMR0 = 0;\n switch (pdr & PDP11.PDR.ACF.MASK) {\n\n case PDP11.PDR.ACF.RO1: // 0x1: read-only, abort on write attempt, memory management trap on read (11/70 only)\n newMMR0 = PDP11.MMR0.TRAP_MMU;\n /* falls through */\n\n case PDP11.PDR.ACF.RO: // 0x2: read-only, abort on write attempt\n pdr |= PDP11.PDR.ACCESSED;\n if (access & PDP11.ACCESS.WRITE) {\n newMMR0 = PDP11.MMR0.ABORT_RO;\n }\n break;\n\n case PDP11.PDR.ACF.RW1: // 0x4: read/write, memory management trap upon completion of a read or write\n newMMR0 = PDP11.MMR0.TRAP_MMU;\n /* falls through */\n\n case PDP11.PDR.ACF.RW2: // 0x5: read/write, memory management trap upon completion of a write (11/70 only)\n if (access & PDP11.ACCESS.WRITE) {\n newMMR0 = PDP11.MMR0.TRAP_MMU;\n }\n /* falls through */\n\n case PDP11.PDR.ACF.RW: // 0x6: read/write, no system trap/abort action\n pdr |= ((access & PDP11.ACCESS.WRITE) ? (PDP11.PDR.ACCESSED | PDP11.PDR.MODIFIED) : PDP11.PDR.ACCESSED);\n break;\n\n default: // 0x0 (non-resident, abort all accesses) or 0x3 or 0x7 (unused, abort all accesses)\n newMMR0 = PDP11.MMR0.ABORT_NR;\n break;\n }\n\n if ((pdr & (PDP11.PDR.PLF | PDP11.PDR.ED)) != PDP11.PDR.PLF) { // skip checking most common case (hopefully)\n /*\n * The Page Descriptor Register (PDR) Page Length Field (PLF) is a 7-bit block number, where a block\n * is 64 bytes. Since the bit 0 of the block number is located at bit 8 of the PDR, we shift the PDR\n * right 2 bits and then clear the bottom 6 bits by masking it with 0x1FC0.\n */\n if (pdr & PDP11.PDR.ED) {\n if (pdr & PDP11.PDR.PLF) {\n if ((addrVirtual & 0x1FC0) < ((pdr >> 2) & 0x1FC0)) {\n newMMR0 |= PDP11.MMR0.ABORT_PL;\n }\n }\n } else {\n if ((addrVirtual & 0x1FC0) > ((pdr >> 2) & 0x1FC0)) {\n newMMR0 |= PDP11.MMR0.ABORT_PL;\n }\n }\n }\n\n /*\n * Aborts and traps: log FIRST trap and MOST RECENT abort\n */\n this.regsPDR[this.pswMode][page] = pdr;\n if (addr != ((BusPDP11.IOPAGE_22BIT | PDP11.UNIBUS.MMR0) & this.mmuMask) || this.pswMode) {\n this.mmuLastMode = this.pswMode;\n this.mmuLastPage = page;\n }\n\n if (newMMR0) {\n if (newMMR0 & PDP11.MMR0.ABORT) {\n if (this.pswTrap >= 0) {\n newMMR0 |= PDP11.MMR0.COMPLETED;\n }\n if (!(this.regMMR0 & PDP11.MMR0.ABORT)) {\n newMMR0 |= (this.regMMR0 & PDP11.MMR0.TRAP_MMU) | (this.mmuLastMode << 5) | (this.mmuLastPage << 1);\n\n this.setMMR0((this.regMMR0 & ~PDP11.MMR0.UPDATE) | (newMMR0 & PDP11.MMR0.UPDATE));\n }\n /*\n * NOTE: In unusual circumstances, if regMMR0 already indicated an ABORT condition above,\n * we run the risk of infinitely looping; eg, we call trap(), which calls mapVirtualToPhysical()\n * on the trap vector, which faults again, etc.\n *\n * TODO: Determine what a real PDP-11 does in that situation; in our case, trap() deals with it\n * by checking an internal OPFLAG (TRAP_RED) and turning the next trap into a PANIC, triggering an\n * immediate HALT.\n */\n this.trap(PDP11.TRAP.MMU, PDP11.OPFLAG.TRAP_MMU, PDP11.REASON.ABORT);\n }\n if (!(this.regMMR0 & (PDP11.MMR0.ABORT | PDP11.MMR0.TRAP_MMU))) {\n /*\n * TODO: Review the code below, because the address range seems over-inclusive.\n */\n if (addr < ((BusPDP11.IOPAGE_22BIT | PDP11.UNIBUS.SIPDR0) & this.mmuMask) ||\n addr > ((BusPDP11.IOPAGE_22BIT | PDP11.UNIBUS.UDPAR7 | 0x1) & this.mmuMask)) {\n this.regMMR0 |= PDP11.MMR0.TRAP_MMU;\n if (this.regMMR0 & PDP11.MMR0.MMU_TRAPS) this.opFlags |= PDP11.OPFLAG.TRAP_MMU;\n }\n }\n }\n return addr;\n }\n\n /**\n * popWord()\n *\n * @this {CPUStatePDP11}\n * @return {number}\n */\n popWord()\n {\n var result = this.readWord(this.regsGen[6] | this.addrDSpace);\n this.regsGen[6] = (this.regsGen[6] + 2) & 0xffff;\n return result;\n }\n\n /**\n * pushWord(data)\n *\n * @this {CPUStatePDP11}\n * @param {number} data\n */\n pushWord(data)\n {\n var addrVirtual = (this.regsGen[6] - 2) & 0xffff;\n this.regsGen[6] = addrVirtual; // BSD needs SP updated before any fault :-(\n this.opLast = (this.opLast & 0xffff) | ((this.opLast & ~0xffff) << 8) | (0x00f6 << 16);\n if (!(this.opFlags & PDP11.OPFLAG.TRAP_RED)) this.checkStackLimit(PDP11.ACCESS.WRITE_WORD, -2, addrVirtual);\n this.writeWord(addrVirtual, data);\n }\n\n /**\n * getAddrByMode(mode, reg, access)\n *\n * getAddrByMode() maps a six bit operand to a 17 bit I/D virtual address space.\n *\n * Instruction operands are six bits in length - three bits for the mode and three\n * for the register. The 17th I/D bit in the resulting virtual address represents\n * whether the reference is to Instruction space or Data space - which depends on\n * combination of the mode and whether the register is the Program Counter (R7).\n *\n * The eight modes are:-\n * 0 R no valid virtual address\n * 1 (R) operand from I/D depending if R = 7\n * 2 (R)+ operand from I/D depending if R = 7\n * 3 @(R)+ address from I/D depending if R = 7 and operand from D space\n * 4 -(R) operand from I/D depending if R = 7\n * 5 @-(R) address from I/D depending if R = 7 and operand from D space\n * 6 x(R) x from I space but operand from D space\n * 7 @x(R) x from I space but address and operand from D space\n *\n * Also need to keep MMR1 updated as this stores which registers have been\n * incremented and decremented so that the OS can reset and restart an instruction\n * if a page fault occurs.\n *\n * Stack Overflow Traps\n * --------------------\n * On the PDP-11/20, stack overflow traps occur when an address below 400 is referenced\n * by SP in either mode 4 (auto-decrement) or 5 (auto-decrement deferred). The instruction\n * is allowed to complete before the trap is issued. NOTE: This information comes\n * directly from the PDP-11/20 Handbook (1971), but the 11/20 diagnostics apparently only\n * test mode 4, not mode 5, because when I later removed stack limit checks for mode 5 on\n * the 11/70, none of the 11/20 tests complained.\n *\n * TODO: Find some independent confirmation as to whether ANY PDP-11 models check for\n * stack overflow on mode 5 (auto-decrement deferred); if they do, then further tweaks to\n * checkStackLimit functions may be required.\n *\n * On the PDP-11/70, the stack limit register (177774) allows a variable boundary for the\n * kernel stack.\n *\n * @this {CPUStatePDP11}\n * @param {number} mode\n * @param {number} reg\n * @param {number} access\n * @return {number}\n */\n getAddrByMode(mode, reg, access)\n {\n var addrVirtual, step;\n var addrDSpace = (access & PDP11.ACCESS.VIRT)? 0 : this.addrDSpace;\n\n /*\n * Modes that need to auto-increment or auto-decrement will break, in order to perform\n * the update; others will return an address immediately.\n */\n switch (mode) {\n /*\n * Mode 0: Registers don't have a virtual address, so trap.\n *\n * NOTE: Most instruction code paths never call getAddrByMode() when the mode is zero;\n * JMP and JSR instructions are exceptions, but that's OK, because those are documented as\n * ILLEGAL instructions which produce a BUS trap (as opposed to UNDEFINED instructions\n * that cause a RESERVED trap).\n */\n case 0:\n this.trap(PDP11.TRAP.BUS, 0, PDP11.REASON.ILLEGAL);\n return 0;\n\n /*\n * Mode 1: (R)\n */\n case 1:\n if (reg == 6) this.checkStackLimit(access, 0, this.regsGen[6]);\n this.nStepCycles -= (2 + 1);\n return (reg == 7? this.regsGen[reg] : (this.regsGen[reg] | addrDSpace));\n\n /*\n * Mode 2: (R)+\n */\n case 2:\n step = 2;\n addrVirtual = this.regsGen[reg];\n if (reg == 6) this.checkStackLimit(access, step, addrVirtual);\n if (reg != 7) {\n addrVirtual |= addrDSpace;\n if (reg < 6 && (access & PDP11.ACCESS.BYTE)) step = 1;\n }\n this.nStepCycles -= (2 + 1);\n break;\n\n /*\n * Mode 3: @(R)+\n */\n case 3:\n step = 2;\n addrVirtual = this.regsGen[reg];\n if (reg != 7) addrVirtual |= addrDSpace;\n addrVirtual = this.readWord(addrVirtual);\n addrVirtual |= addrDSpace;\n this.nStepCycles -= (5 + 2);\n break;\n\n /*\n * Mode 4: -(R)\n */\n case 4:\n step = -2;\n if (reg < 6 && (access & PDP11.ACCESS.BYTE)) step = -1;\n addrVirtual = (this.regsGen[reg] + step) & 0xffff;\n if (reg == 6) this.checkStackLimit(access, step, addrVirtual);\n if (reg != 7) addrVirtual |= addrDSpace;\n this.nStepCycles -= (3 + 1);\n break;\n\n /*\n * Mode 5: @-(R)\n */\n case 5:\n step = -2;\n addrVirtual = (this.regsGen[reg] - 2) & 0xffff;\n if (reg != 7) addrVirtual |= addrDSpace;\n addrVirtual = this.readWord(addrVirtual) | addrDSpace;\n this.nStepCycles -= (6 + 2);\n break;\n\n /*\n * Mode 6: d(R)\n */\n case 6:\n addrVirtual = this.readWord(this.advancePC(2));\n addrVirtual = (addrVirtual + this.regsGen[reg]) & 0xffff;\n if (reg == 6) this.checkStackLimit(access, 0, addrVirtual);\n this.nStepCycles -= (4 + 2);\n return addrVirtual | addrDSpace;\n\n /*\n * Mode 7: @d(R)\n */\n case 7:\n addrVirtual = this.readWord(this.advancePC(2));\n addrVirtual = (addrVirtual + this.regsGen[reg]) & 0xffff;\n addrVirtual = this.readWord(addrVirtual | this.addrDSpace);\n this.nStepCycles -= (7 + 3);\n return addrVirtual | addrDSpace;\n }\n\n this.regsGen[reg] = (this.regsGen[reg] + step) & 0xffff;\n this.opLast = (this.opLast & 0xffff) | ((this.opLast & ~0xffff) << 8) | ((((step << 3) & 0xf8) | reg) << 16);\n\n return addrVirtual;\n }\n\n /**\n * checkStackLimit1120(access, step, addr)\n *\n * @this {CPUStatePDP11}\n * @param {number} access\n * @param {number} step\n * @param {number} addr\n */\n checkStackLimit1120(access, step, addr)\n {\n /*\n * NOTE: DEC's \"TRAP TEST\" (MAINDEC-11-D0NA-PB) expects \"TST -(SP)\" to trap when SP is 150,\n * so we ignore the access parameter. Also, strangely, it does NOT expect this instruction\n * to trap:\n *\n * R0=006302 R1=000000 R2=000000 R3=000000 R4=000000 R5=000776\n * SP=000000 PC=006346 PS=000344 IR=000000 SL=000377 T0 N0 Z1 V0 C0\n * 006346: 112667 171426 MOVB (SP)+,000000\n *\n * so if the step parameter is positive, we let it go.\n */\n if (!this.pswMode && step <= 0 && addr <= this.regSLR) {\n /*\n * On older machines (eg, the PDP-11/20), there is no \"YELLOW\" and \"RED\" distinction, and the\n * instruction is always allowed to complete, so the trap must always be issued in this fashion.\n */\n this.opFlags |= PDP11.OPFLAG.TRAP_SP;\n }\n }\n\n /**\n * checkStackLimit1140(access, step, addr)\n *\n * @this {CPUStatePDP11}\n * @param {number} access\n * @param {number} step\n * @param {number} addr\n */\n checkStackLimit1140(access, step, addr)\n {\n if (!this.pswMode) {\n /*\n * NOTE: The 11/70 CPU Instruction Exerciser does NOT expect reads to trigger a stack overflow,\n * so we check the access parameter.\n *\n * Moreover, TEST 40 of diagnostic EKBBF0 executes this instruction:\n *\n * R0=177777 R1=032435 R2=152110 R3=000024 R4=153352 R5=001164\n * SP=177776 PC=020632 PS=000350 IR=000000 SL=000377 T0 N1 Z0 V0 C0\n * 020632: 005016 CLR @SP ;cycles=7\n *\n * expecting a RED stack overflow trap. Yes, using *any* addresses in the IOPAGE for the stack isn't\n * a good idea, but who said it was illegal? For now, we're going to restrict overflows to the highest\n * address tested by the diagnostic (0xFFFE, aka the PSW), by making that address negative.\n */\n if (addr >= 0xFFFE) addr |= ~0xFFFF;\n if ((access & PDP11.ACCESS.WRITE) && addr <= this.regSLR) {\n /*\n * regSLR can never fall below 0xFF, so this subtraction can never go negative, so this comparison\n * is always safe.\n */\n if (addr <= this.regSLR - 32) {\n this.trap(PDP11.TRAP.BUS, 0, PDP11.REASON.RED);\n } else {\n this.regErr |= PDP11.CPUERR.YELLOW;\n this.opFlags |= PDP11.OPFLAG.TRAP_SP;\n }\n }\n }\n }\n\n /**\n * getByteChecked(addr)\n *\n * This is the getByte() handler whenever the Debugger has one or more virtual memory READ breakpoints set;\n * otherwise, getByte() is bound to Bus.getByte().\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @return {number}\n */\n getByteChecked(addr)\n {\n if (DEBUGGER && this.dbg) {\n this.dbg.checkMemoryRead(addr, 1);\n }\n return this.getByteDirect(addr);\n }\n\n /**\n * getWordChecked(addr)\n *\n * This is the getWord() handler whenever the Debugger has one or more virtual memory READ breakpoints set;\n * otherwise, getWord() is bound to Bus.getWord().\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @return {number}\n */\n getWordChecked(addr)\n {\n if (DEBUGGER && this.dbg) {\n this.dbg.checkMemoryRead(addr, 2);\n }\n return this.getWordDirect(addr);\n }\n\n /**\n * setByteChecked(addr, data)\n *\n * This is the setByte() handler whenever the Debugger has one or more virtual memory WRITE breakpoints set;\n * otherwise, setByte() is bound to Bus.setByte().\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @param {number} data\n */\n setByteChecked(addr, data)\n {\n if (DEBUGGER && this.dbg) {\n this.dbg.checkMemoryWrite(addr, 1);\n }\n this.setByteDirect(addr, data);\n }\n\n /**\n * setWordChecked(addr, data)\n *\n * This is the setWord() handler whenever the Debugger has one or more virtual memory WRITE breakpoints set;\n * otherwise, setWord() is bound to Bus.setWord().\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @param {number} data\n */\n setWordChecked(addr, data)\n {\n if (DEBUGGER && this.dbg) {\n this.dbg.checkMemoryWrite(addr, 2);\n }\n this.setWordDirect(addr, data);\n }\n\n /**\n * getByteSafe(addr)\n *\n * This interface is expressly for the Debugger, to access virtual memory without faulting.\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @return {number}\n */\n getByteSafe(addr)\n {\n this.nDisableTraps++;\n var b = this.bus.getByte(this.mapVirtualToPhysical(addr, PDP11.ACCESS.READ_BYTE));\n this.nDisableTraps--;\n return b;\n }\n\n /**\n * getWordSafe(addr)\n *\n * This interface is expressly for the Debugger, to access virtual memory without faulting.\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @return {number}\n */\n getWordSafe(addr)\n {\n this.nDisableTraps++;\n var w = this.bus.getWord(this.mapVirtualToPhysical(addr, PDP11.ACCESS.READ_WORD));\n this.nDisableTraps--;\n return w;\n }\n\n /**\n * setByteSafe(addr, data)\n *\n * This interface is expressly for the Debugger, to access virtual memory without faulting.\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @param {number} data\n */\n setByteSafe(addr, data)\n {\n this.nDisableTraps++;\n this.bus.setByte(this.mapVirtualToPhysical(addr, PDP11.ACCESS.WRITE_BYTE), data);\n this.nDisableTraps--;\n }\n\n /**\n * setWordSafe(addr, data)\n *\n * This interface is expressly for the Debugger, to access virtual memory without faulting.\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @param {number} data\n */\n setWordSafe(addr, data)\n {\n this.nDisableTraps++;\n this.bus.setWord(this.mapVirtualToPhysical(addr, PDP11.ACCESS.WRITE_WORD), data);\n this.nDisableTraps--;\n }\n\n /**\n * addMemBreak(addr, fWrite)\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint\n */\n addMemBreak(addr, fWrite)\n {\n if (DEBUGGER) {\n var nBreaks = fWrite? this.nWriteBreaks++ : this.nReadBreaks++;\n\n if (!nBreaks) this.setMemoryAccess();\n }\n }\n\n /**\n * removeMemBreak(addr, fWrite)\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @param {boolean} fWrite is true for a memory write breakpoint, false for a memory read breakpoint\n */\n removeMemBreak(addr, fWrite)\n {\n if (DEBUGGER) {\n var nBreaks = fWrite? --this.nWriteBreaks : --this.nReadBreaks;\n\n if (!nBreaks) this.setMemoryAccess();\n }\n }\n\n /**\n * getPhysicalAddrByMode(mode, reg, access)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through getAddr().\n *\n * @this {CPUStatePDP11}\n * @param {number} mode\n * @param {number} reg\n * @param {number} access\n * @return {number}\n */\n getPhysicalAddrByMode(mode, reg, access)\n {\n return this.getAddrByMode(mode, reg, access);\n }\n\n /**\n * getVirtualAddrByMode(mode, reg, access)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through getAddr().\n *\n * @this {CPUStatePDP11}\n * @param {number} mode\n * @param {number} reg\n * @param {number} access\n * @return {number}\n */\n getVirtualAddrByMode(mode, reg, access)\n {\n return this.mapVirtualToPhysical(this.getAddrByMode(mode, reg, access), access);\n }\n\n /**\n * readWordFromPhysical(addr)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through readWord().\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @return {number}\n */\n readWordFromPhysical(addr)\n {\n return this.bus.getWord(this.addrLast = addr);\n }\n\n /**\n * readWordFromPhysicalChecked(addr)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through readWord().\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @return {number}\n */\n readWordFromPhysicalChecked(addr)\n {\n if (DEBUGGER && this.dbg) {\n this.dbg.checkMemoryRead(addr, 2);\n }\n return this.readWordFromPhysical(addr);\n }\n\n /**\n * readWordFromVirtual(addrVirtual)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through readWord().\n *\n * @this {CPUStatePDP11}\n * @param {number} addrVirtual (input address is 17 bit (I&D))\n * @return {number}\n */\n readWordFromVirtual(addrVirtual)\n {\n return this.bus.getWord(this.addrLast = this.mapVirtualToPhysical(addrVirtual, PDP11.ACCESS.READ_WORD));\n }\n\n /**\n * readWordFromVirtualChecked(addrVirtual)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through readWord().\n *\n * @this {CPUStatePDP11}\n * @param {number} addrVirtual (input address is 17 bit (I&D))\n * @return {number}\n */\n readWordFromVirtualChecked(addrVirtual)\n {\n if (DEBUGGER && this.dbg) {\n this.dbg.checkMemoryRead(addrVirtual, 2);\n }\n return this.readWordFromVirtual(addrVirtual);\n }\n\n /**\n * writeWordToPhysical(addr, data)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through writeWord().\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @param {number} data\n */\n writeWordToPhysical(addr, data)\n {\n this.bus.setWord(this.addrLast = addr, data);\n }\n\n /**\n * writeWordToPhysicalChecked(addr, data)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through writeWord().\n *\n * @this {CPUStatePDP11}\n * @param {number} addr\n * @param {number} data\n */\n writeWordToPhysicalChecked(addr, data)\n {\n if (DEBUGGER && this.dbg) {\n this.dbg.checkMemoryWrite(addr, 2);\n }\n this.writeWordToPhysical(addr, data);\n }\n\n /**\n * writeWordToVirtual(addrVirtual, data)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through writeWord().\n *\n * @this {CPUStatePDP11}\n * @param {number} addrVirtual (input address is 17 bit (I&D))\n * @param {number} data\n */\n writeWordToVirtual(addrVirtual, data)\n {\n this.bus.setWord(this.addrLast = this.mapVirtualToPhysical(addrVirtual, PDP11.ACCESS.WRITE_WORD), data);\n }\n\n /**\n * writeWordToVirtualChecked(addrVirtual, data)\n *\n * This is a handler set up by setMemoryAccess(). All calls should go through writeWord().\n *\n * @this {CPUStatePDP11}\n * @param {number} addrVirtual (input address is 17 bit (I&D))\n * @param {number} data\n */\n writeWordToVirtualChecked(addrVirtual, data)\n {\n if (DEBUGGER && this.dbg) {\n this.dbg.checkMemoryWrite(addrVirtual, 2);\n }\n this.writeWordToVirtual(addrVirtual, data);\n }\n\n /**\n * readWordFromPrevSpace(opCode, access)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @param {number} access (really just PDP11.ACCESS.DSPACE or PDP11.ACCESS.ISPACE)\n * @return {number}\n */\n readWordFromPrevSpace(opCode, access)\n {\n var data;\n var reg = this.dstReg = opCode & PDP11.OPREG.MASK;\n var mode = this.dstMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n if (!mode) {\n if (reg != 6 || ((this.regPSW >> 2) & PDP11.PSW.PMODE) === (this.regPSW & PDP11.PSW.PMODE)) {\n data = this.regsGen[reg];\n } else {\n data = this.regsAltStack[(this.regPSW >> 12) & 3];\n }\n } else {\n var addr = this.getAddrByMode(mode, reg, PDP11.ACCESS.READ_WORD);\n if (!(access & PDP11.ACCESS.DSPACE)) {\n if ((this.regPSW & 0xf000) !== 0xf000) addr &= 0xffff;\n }\n this.pswMode = (this.regPSW >> 12) & 3;\n data = this.readWord(addr | (access & this.addrDSpace));\n this.pswMode = (this.regPSW >> 14) & 3;\n }\n return data;\n }\n\n /**\n * writeWordToPrevSpace(opCode, access, data)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @param {number} access (really just PDP11.ACCESS.DSPACE or PDP11.ACCESS.ISPACE)\n * @param {number} data\n */\n writeWordToPrevSpace(opCode, access, data)\n {\n this.opLast = (this.opLast & 0xffff) | (0x0016 << 16);\n var reg = this.dstReg = opCode & PDP11.OPREG.MASK;\n var mode = this.dstMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n if (!mode) {\n if (reg != 6 || ((this.regPSW >> 2) & PDP11.PSW.PMODE) === (this.regPSW & PDP11.PSW.PMODE)) {\n this.regsGen[reg] = data;\n } else {\n this.regsAltStack[(this.regPSW >> 12) & 3] = data;\n }\n } else {\n var addr = this.getAddrByMode(mode, reg, PDP11.ACCESS.WRITE_WORD);\n if (!(access & PDP11.ACCESS.DSPACE)) addr &= 0xffff;\n /*\n * TODO: Consider replacing the following code with writeWord(), by adding optional pswMode\n * parameters for each of the discrete mapVirtualToPhysical() and setWord() operations, because\n * as it stands, this is the only remaining call to mapVirtualToPhysical() outside of our\n * setMemoryAccess() handlers.\n */\n this.pswMode = (this.regPSW >> 12) & 3;\n addr = this.mapVirtualToPhysical(addr | (access & PDP11.ACCESS.DSPACE), PDP11.ACCESS.WRITE);\n this.pswMode = (this.regPSW >> 14) & 3;\n this.setWord(addr, data);\n }\n }\n\n /**\n * readSrcByte(opCode)\n *\n * WARNING: If the SRC operand is a register, offRegSrc ensures we return a negative register number\n * rather than the register value, because on the PDP-11/20, the final value of the register must be\n * resolved AFTER the DST operand has been decoded and any pre-decrement or post-increment operations\n * affecting the SRC register have been completed. See readSrcWord() for more details.\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @return {number}\n */\n readSrcByte(opCode)\n {\n var result;\n opCode >>= PDP11.SRCMODE.SHIFT;\n var reg = this.srcReg = opCode & PDP11.OPREG.MASK;\n var mode = this.srcMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n if (!mode) {\n result = this.regsGen[reg + this.offRegSrc] & this.maskRegSrcByte;\n } else {\n result = this.getByte(this.getAddr(mode, reg, PDP11.ACCESS.READ_BYTE));\n }\n return result;\n }\n\n /**\n * readSrcWord(opCode)\n *\n * WARNING: If the SRC operand is a register, offRegSrc ensures we return a negative register number\n * rather than the register value, because on the PDP-11/20, the final value of the register must be\n * resolved AFTER the DST operand has been decoded and any pre-decrement or post-increment operations\n * affecting the SRC register have been completed.\n *\n * Here's an example from DEC's \"TRAP TEST\" (MAINDEC-11-D0NA-PB):\n *\n * 007200: 012700 006340 MOV #6340,R0\n * 007204: 010020 MOV R0,(R0)+\n * 007206: 026727 177126 006342 CMP 006340,#6342\n * 007214: 001401 BEQ 007220\n * 007216: 000000 HALT\n *\n * If this function returned the value of R0 for the SRC operand of \"MOV R0,(R0)+\", then the operation\n * would write 6340 to the destination, rather than 6342.\n *\n * Most callers don't need to worry about this, because if they pass the result from readSrcWord() directly\n * to writeDstWord() or updateDstWord(), those functions will take care of converting any negative register\n * number back into the current register value. The exceptions are opcodes that don't modify the DST operand\n * (BIT, BITB, CMP, and CMPB); those opcode handlers must deal with negative register numbers themselves.\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @return {number}\n */\n readSrcWord(opCode)\n {\n var result;\n opCode >>= PDP11.SRCMODE.SHIFT;\n var reg = this.srcReg = opCode & PDP11.OPREG.MASK;\n var mode = this.srcMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n if (!mode) {\n result = this.regsGen[reg + this.offRegSrc];\n } else {\n result = this.getWord(this.getAddr(mode, reg, PDP11.ACCESS.READ_WORD));\n }\n return result;\n }\n\n /**\n * readDstAddr(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @return {number}\n */\n readDstAddr(opCode)\n {\n var reg = this.dstReg = opCode & PDP11.OPREG.MASK;\n var mode = this.dstMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n return this.getAddrByMode(mode, reg, PDP11.ACCESS.VIRT);\n }\n\n /**\n * readDstByte(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @return {number}\n */\n readDstByte(opCode)\n {\n var result;\n var reg = this.dstReg = opCode & PDP11.OPREG.MASK;\n var mode = this.dstMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n if (!mode) {\n result = this.regsGen[reg] & 0xff;\n } else {\n result = this.getByte(this.getAddr(mode, reg, PDP11.ACCESS.READ_BYTE));\n }\n return result;\n }\n\n /**\n * readDstWord(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @return {number}\n */\n readDstWord(opCode)\n {\n var result;\n var reg = this.dstReg = opCode & PDP11.OPREG.MASK;\n var mode = this.dstMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n if (!mode) {\n result = this.regsGen[reg];\n } else {\n result = this.getWord(this.getAddr(mode, reg, PDP11.ACCESS.READ_WORD));\n }\n return result;\n }\n\n /**\n * updateDstByte(opCode, data, fnOp)\n *\n * Used whenever the DST operand (as described by opCode) needs to be read before writing.\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @param {number} data\n * @param {function(number,number)} fnOp\n */\n updateDstByte(opCode, data, fnOp)\n {\n var reg = this.dstReg = opCode & PDP11.OPREG.MASK;\n var mode = this.dstMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n if (!mode) {\n var dst = this.regsGen[reg];\n data = (data < 0? (this.regsGen[-data-1] & 0xff) : data);\n this.regsGen[reg] = (dst & 0xff00) | fnOp.call(this, data, dst & 0xff);\n } else {\n var addr = this.dstAddr = this.getAddr(mode, reg, PDP11.ACCESS.UPDATE_BYTE);\n data = (data < 0? (this.regsGen[-data-1] & 0xff) : data);\n this.setByte(addr, fnOp.call(this, data, this.getByte(addr)));\n if (addr & 1) this.nStepCycles--;\n }\n }\n\n /**\n * updateDstWord(opCode, data, fnOp)\n *\n * Used whenever the DST operand (as described by opCode) needs to be read before writing.\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @param {number} data\n * @param {function(number,number)} fnOp\n */\n updateDstWord(opCode, data, fnOp)\n {\n var reg = this.dstReg = opCode & PDP11.OPREG.MASK;\n var mode = this.dstMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n\n\n\n if (!mode) {\n this.regsGen[reg] = fnOp.call(this, data < 0? this.regsGen[-data-1] : data, this.regsGen[reg]);\n } else {\n var addr = this.getAddr(mode, reg, PDP11.ACCESS.UPDATE_WORD);\n this.setWord(addr, fnOp.call(this, data < 0? this.regsGen[-data-1] : data, this.getWord(addr)));\n }\n }\n\n /**\n * writeDstByte(opCode, data, writeFlags, fnFlags)\n *\n * Used whenever the DST operand (as described by opCode) does NOT need to be read before writing.\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @param {number} data\n * @param {number} writeFlags (WRITE.BYTE aka 0xff, or WRITE.SBYTE aka 0xffff)\n * @param {function(number)} fnFlags\n */\n writeDstByte(opCode, data, writeFlags, fnFlags)\n {\n\n var reg = this.dstReg = opCode & PDP11.OPREG.MASK;\n var mode = this.dstMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n if (!mode) {\n if (!data) {\n /*\n * Potentially worthless optimization (but it looks good on \"paper\").\n */\n this.regsGen[reg] &= ~writeFlags;\n } else {\n /*\n * Potentially worthwhile optimization: skipping the sign-extending data shifts\n * if writeFlags is WRITE.BYTE (but that requires an extra test and separate code paths).\n */\n data = (data < 0? (this.regsGen[-data-1] & 0xff): data);\n this.regsGen[reg] = (this.regsGen[reg] & ~writeFlags) | (((data << 24) >> 24) & writeFlags);\n }\n fnFlags.call(this, data << 8);\n } else {\n var addr = this.getAddr(mode, reg, PDP11.ACCESS.WRITE_BYTE);\n fnFlags.call(this, (data = data < 0? (this.regsGen[-data-1] & 0xff) : data) << 8);\n this.setByte(addr, data);\n if (addr & 1) this.nStepCycles--;\n }\n }\n\n /**\n * writeDstWord(opCode, data, fnFlags)\n *\n * Used whenever the DST operand (as described by opCode) does NOT need to be read before writing.\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n * @param {number} data\n * @param {function(number)} fnFlags\n */\n writeDstWord(opCode, data, fnFlags)\n {\n var reg = this.dstReg = opCode & PDP11.OPREG.MASK;\n var mode = this.dstMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;\n\n\n\n if (!mode) {\n this.regsGen[reg] = (data = data < 0? this.regsGen[-data-1] : data);\n fnFlags.call(this, data);\n } else {\n var addr = this.getAddr(mode, reg, PDP11.ACCESS.WRITE_WORD);\n fnFlags.call(this, (data = data < 0? this.regsGen[-data-1] : data));\n this.setWord(addr, data);\n }\n }\n\n /**\n * stepCPU(nMinCycles)\n *\n * NOTE: Single-stepping should not be confused with the Trap flag; single-stepping is a Debugger\n * operation that's completely independent of Trap status. The CPU can go in and out of Trap mode,\n * in and out of h/w interrupt service routines (ISRs), etc, but from the Debugger's perspective,\n * they're all one continuous stream of instructions that can be stepped or run at will. Moreover,\n * stepping vs. running should never change the behavior of the simulation.\n *\n * @this {CPUStatePDP11}\n * @param {number} nMinCycles (0 implies a single-step, and therefore breakpoints should be ignored)\n * @return {number} of cycles executed; 0 indicates a pre-execution condition (ie, an execution breakpoint\n * was hit), -1 indicates a post-execution condition (eg, a read or write breakpoint was hit), and a positive\n * number indicates successful completion of that many cycles (which should always be >= nMinCycles).\n */\n stepCPU(nMinCycles)\n {\n /*\n * The Debugger uses complete to determine if the instruction completed (true) or was interrupted\n * by a breakpoint or some other exceptional condition (false). NOTE: this does NOT include JavaScript\n * exceptions, which stepCPU() expects the caller to catch using its own exception handler.\n *\n * The CPU relies on the use of stopCPU() rather than complete, because the CPU never single-steps\n * (ie, nMinCycles is always some large number), whereas the Debugger does. And conversely, when the\n * Debugger is single-stepping (even when performing multiple single-steps), fRunning is never set,\n * so stopCPU() would have no effect as far as the Debugger is concerned.\n */\n this.flags.complete = true;\n\n /*\n * nDebugCheck is 1 if we want the Debugger's checkInstruction() to check every instruction,\n * -1 if we want it to check just the first instruction, and 0 if there's no need for any checks.\n */\n var nDebugCheck = (DEBUGGER && this.dbg)? (this.dbg.checksEnabled()? 1 : (this.flags.starting? -1 : 0)) : 0;\n\n /*\n * nDebugState is needed only when nDebugCheck is non-zero; it is -1 if this is a single-step, 0 if\n * this is the start of a new run, and 1 if this is a continuation of a previous run. It is used by\n * checkInstruction() to determine if it should skip breakpoint checks and/or HALT instructions (ie,\n * if nDebugState is <= zero).\n */\n var nDebugState = (!nMinCycles)? -1 : (this.flags.starting? 0 : 1);\n this.flags.starting = false; // we've moved beyond \"starting\" and have officially \"started\" now\n\n /*\n * We move the minimum cycle count to nStepCycles (the number of cycles left to step), so that other\n * functions have the ability to force that number to zero (eg, stopCPU()), and thus we don't have to check\n * any other criteria to determine whether we should continue stepping or not.\n */\n this.nBurstCycles = this.nStepCycles = nMinCycles;\n\n /*\n * And finally, move the nDebugCheck state to an OPFLAG bit, so that the loop need check only one variable.\n */\n this.opFlags = (this.opFlags & ~PDP11.OPFLAG.DEBUGGER) | (nDebugCheck? PDP11.OPFLAG.DEBUGGER : 0);\n\n do {\n if (this.opFlags) {\n /*\n * NOTE: We still check DEBUGGER to ensure that this code will be compiled out of existence in\n * non-DEBUGGER builds.\n */\n if (DEBUGGER && (this.opFlags & PDP11.OPFLAG.DEBUGGER)) {\n if (this.dbg.checkInstruction(this.getPC(), nDebugState)) {\n this.stopCPU();\n break;\n }\n if (!++nDebugCheck) this.opFlags &= ~PDP11.OPFLAG.DEBUGGER;\n if (!nDebugState) nDebugState++;\n }\n /*\n * If we're in the IRQ or WAIT state, check for any pending interrupts.\n *\n * NOTE: It's no coincidence that we're checking this BEFORE any pending traps, because in rare\n * cases (including some presented by those pesky \"TRAP TEST\" diagnostics), the process of dispatching\n * an interrupt can trigger a TRAP_SP stack overflow condition, which must be dealt with BEFORE we\n * execute the first instruction of the interrupt handler.\n */\n if ((this.opFlags & (PDP11.OPFLAG.IRQ_MASK | PDP11.OPFLAG.WAIT)) /* && nDebugState >= 0 */) {\n if (this.checkInterrupts()) {\n if ((this.opFlags & PDP11.OPFLAG.DEBUGGER) && this.dbg.checkInstruction(this.getPC(), nDebugState)) {\n this.stopCPU();\n break;\n }\n /*\n * Since an interrupt was just dispatched, altering the normal flow of time and changing\n * the future as we knew it, let's break out immediately if we're single-stepping, so that\n * the Debugger gets to see the first instruction of the interrupt handler. NOTE: This\n * assumes that we've still commented out the nDebugState check above that used to bypass\n * checkInterrupts() when single-stepping.\n */\n if (nDebugState < 0) break;\n }\n }\n /*\n * Next, check for any pending traps (which, as noted above, must be done after checkInterrupts()).\n *\n * I've moved this TRAP_MASK check BEFORE we decode the next instruction instead of immediately AFTER,\n * just in case the last instruction threw an exception that kicked us out before we reached the bottom\n * of the stepCPU() loop.\n */\n if (this.opFlags & PDP11.OPFLAG.TRAP_MASK) {\n if (this.checkTraps()) {\n if ((this.opFlags & PDP11.OPFLAG.DEBUGGER) && this.dbg.checkInstruction(this.getPC(), nDebugState)) {\n this.stopCPU();\n break;\n }\n if (nDebugState < 0) break;\n }\n }\n }\n\n /*\n * Snapshot the TF bit in opFlags, while clearing all other opFlags (except those in PRESERVE);\n * we'll check the TRAP_TF bit in opFlags when we come back around for another opcode.\n */\n this.opFlags = (this.opFlags & PDP11.OPFLAG.PRESERVE) | (this.regPSW & PDP11.PSW.TF);\n\n var opCode = this.getOpcode();\n this.opDecode(opCode);\n\n } while (this.nStepCycles > 0);\n\n return (this.flags.complete? this.nBurstCycles - this.nStepCycles : (this.flags.complete === false? -1 : 0));\n }\n\n /**\n * CPUStatePDP11.init()\n *\n * This function operates on every HTML element of class \"cpu\", extracting the\n * JSON-encoded parameters for the CPUStatePDP11 constructor from the element's \"data-value\"\n * attribute, invoking the constructor (which in turn invokes the CPU constructor)\n * to create a CPUStatePDP11 component, and then binding any associated HTML controls to the\n * new component.\n */\n static init()\n {\n var aeCPUs = Component.getElementsByClass(document, PDP11.APPCLASS, \"cpu\");\n for (var iCPU = 0; iCPU < aeCPUs.length; iCPU++) {\n var eCPU = aeCPUs[iCPU];\n var parmsCPU = Component.getComponentParms(eCPU);\n var cpu = new CPUStatePDP11(parmsCPU);\n Component.bindComponentControls(cpu, eCPU, PDP11.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize every CPU module on the page\n */\nWeb.onInit(CPUStatePDP11.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/cpuops.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * Decoding starts near the bottom of this file, in op1120() and op1140(). Obviously, there are\n * MANY more PDP-11 models than the 11/20 and 11/40, but for the broad model categories that PDPjs\n * supports (ie, MODEL_1120, MODEL_1140, MODEL_1145, and MODEL_1170), the biggest differences are\n * between MODEL_1120 and MODEL_1140, so decoding is divided into those two categories, and all\n * other differences are handled inside the opcode handlers.\n *\n * The basic decoding approach is to dispatch on the top 4 bits of the opcode, and if further\n * decoding is required, the dispatched function will dispatch on the next 4 bits, and so on\n * (although some of the intermediate levels dispatch only on 2 bits, which could also be handled\n * with a switch statement).\n *\n * Eventually, every opcode should end up either in an opXXX() function or opUndefined(). For\n * opcodes that perform a simple read or write operation, the entire operation is handled by\n * the opXXX() function. For opcodes that perform a more extensive read/modify/write operation\n * (also known as an update operation), those opXXX() functions usually rely on a corresponding\n * fnXXX() helper function.\n *\n * For example, opADD() passes the helper function fnADD() to the appropriate update method. This\n * allows the update method to perform the entire read/modify/write operation, because the modify\n * step is performed internally, via the fnXXX() helper function.\n *\n * For the handful of instructions in the 1140 tables that actually exist only on the 11/45 and\n * 11/70 (ie, MFPD, MTPD, and SPL), those opcode handlers perform their own model checks. That's\n * simpler than creating additional tables, and seems fine for instructions that are not commonly\n * executed.\n */\n\n/**\n * fnADD(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src\n * @param {number} dst\n * @return {number} (dst + src)\n */\nPDP11.fnADD = function(src, dst)\n{\n var result = dst + src;\n this.updateAddFlags(result, src, dst);\n return result & 0xffff;\n};\n\n/**\n * fnADDB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src\n * @param {number} dst\n * @return {number} (dst + src)\n */\nPDP11.fnADDB = function(src, dst)\n{\n var result = dst + src;\n this.updateAddFlags(result << 8, src << 8, dst << 8);\n return result & 0xff;\n};\n\n/**\n * fnASL(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (dst << 1)\n */\nPDP11.fnASL = function(src, dst)\n{\n var result = dst << 1;\n this.updateShiftFlags(result);\n return result & 0xffff;\n};\n\n/**\n * fnASLB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (dst << 1)\n */\nPDP11.fnASLB = function(src, dst)\n{\n var result = dst << 1;\n this.updateShiftFlags(result << 8);\n return result & 0xff;\n};\n\n/**\n * fnASR(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (dst >> 1)\n */\nPDP11.fnASR = function(src, dst)\n{\n var result = (dst & 0x8000) | (dst >> 1) | (dst << 16);\n this.updateShiftFlags(result);\n return result & 0xffff;\n};\n\n/**\n * fnASRB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (dst >> 1)\n */\nPDP11.fnASRB = function(src, dst)\n{\n var result = (dst & 0x80) | (dst >> 1) | (dst << 8);\n this.updateShiftFlags(result << 8);\n return result & 0xff;\n};\n\n/**\n * fnBIC(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src\n * @param {number} dst\n * @return {number} (~src & dst)\n */\nPDP11.fnBIC = function(src, dst)\n{\n var result = dst & ~src;\n this.updateNZVFlags(result);\n return result;\n};\n\n/**\n * fnBICB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src\n * @param {number} dst\n * @return {number} (~src & dst)\n */\nPDP11.fnBICB = function(src, dst)\n{\n var result = dst & ~src;\n this.updateNZVFlags(result << 8);\n return result;\n};\n\n/**\n * fnBIS(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src\n * @param {number} dst\n * @return {number} (dst | src)\n */\nPDP11.fnBIS = function(src, dst)\n{\n var result = dst | src;\n this.updateNZVFlags(result);\n return result;\n};\n\n/**\n * fnBISB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src\n * @param {number} dst\n * @return {number} (dst | src)\n */\nPDP11.fnBISB = function(src, dst)\n{\n var result = dst | src;\n this.updateNZVFlags(result << 8);\n return result;\n};\n\n/**\n * fnCOM(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (~dst)\n */\nPDP11.fnCOM = function(src, dst)\n{\n var result = ~dst | 0x10000;\n this.updateAllFlags(result);\n return result & 0xffff;\n};\n\n/**\n * fnCOMB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (~dst)\n */\nPDP11.fnCOMB = function(src, dst)\n{\n var result = ~dst | 0x100;\n this.updateAllFlags(result << 8);\n return result & 0xff;\n};\n\n/**\n * fnDEC(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ie, 1)\n * @param {number} dst\n * @return {number} (dst - src)\n */\nPDP11.fnDEC = function(src, dst)\n{\n var result = dst - src;\n this.updateDecFlags(result, dst);\n return result & 0xffff;\n};\n\n/**\n * fnDECB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ie, 1)\n * @param {number} dst\n * @return {number} (dst - src)\n */\nPDP11.fnDECB = function(src, dst)\n{\n var result = dst - src;\n this.updateDecFlags(result << 8, dst << 8);\n return result & 0xff;\n};\n\n/**\n * fnINC(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ie, 1)\n * @param {number} dst\n * @return {number} (dst + src)\n */\nPDP11.fnINC = function(src, dst)\n{\n var result = dst + src;\n this.updateIncFlags(result, dst);\n return result & 0xffff;\n};\n\n/**\n * fnINCB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ie, 1)\n * @param {number} dst\n * @return {number} (dst + src)\n */\nPDP11.fnINCB = function(src, dst)\n{\n var result = dst + src;\n this.updateIncFlags(result << 8, dst << 8);\n return result & 0xff;\n};\n\n/**\n * fnNEG(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (-dst)\n */\nPDP11.fnNEG = function(src, dst)\n{\n var result = -dst;\n /*\n * If the sign bit of both dst and result are set, the original value must have been 0x8000, triggering overflow.\n */\n this.updateAllFlags(result, result & dst & 0x8000);\n return result & 0xffff;\n};\n\n/**\n * fnNEGB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (-dst)\n */\nPDP11.fnNEGB = function(src, dst)\n{\n var result = -dst;\n /*\n * If the sign bit of both dst and result are set, the original value must have been 0x80, which triggers overflow.\n */\n this.updateAllFlags(result << 8, (result & dst & 0x80) << 8);\n return result & 0xff;\n};\n\n/**\n * fnROL(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (dst >> 1)\n */\nPDP11.fnROL = function(src, dst)\n{\n var result = (dst << 1) | ((this.flagC >> 16) & 1);\n this.updateShiftFlags(result);\n return result & 0xffff;\n};\n\n/**\n * fnROLB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (dst >> 1)\n */\nPDP11.fnROLB = function(src, dst)\n{\n var result = (dst << 1) | ((this.flagC >> 16) & 1);\n this.updateShiftFlags(result << 8);\n return result & 0xff;\n};\n\n/**\n * fnROR(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (dst >> 1)\n */\nPDP11.fnROR = function(src, dst)\n{\n var result = (((this.flagC & 0x10000) | dst) >> 1) | (dst << 16);\n this.updateShiftFlags(result);\n return result & 0xffff;\n};\n\n/**\n * fnRORB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (dst >> 1)\n */\nPDP11.fnRORB = function(src, dst)\n{\n var result = ((((this.flagC & 0x10000) >> 8) | dst) >> 1) | (dst << 8);\n this.updateShiftFlags(result << 8);\n return result & 0xff;\n};\n\n/**\n * fnSUB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src\n * @param {number} dst\n * @return {number} (dst - src)\n */\nPDP11.fnSUB = function(src, dst)\n{\n var result = dst - src;\n this.updateSubFlags(result, src, dst);\n return result & 0xffff;\n};\n\n/**\n * fnSUBB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src\n * @param {number} dst\n * @return {number} (dst - src)\n */\nPDP11.fnSUBB = function(src, dst)\n{\n var result = dst - src;\n this.updateSubFlags(result << 8, src << 8, dst << 8);\n return result & 0xff;\n};\n\n/**\n * fnSWAB(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src (ignored)\n * @param {number} dst\n * @return {number} (dst with bytes swapped)\n */\nPDP11.fnSWAB = function(src, dst)\n{\n var result = (dst << 8) | (dst >> 8);\n /*\n * N and Z are based on the low byte of the result, which is the same as the high byte of dst.\n */\n this.updateNZVCFlags(dst & 0xff00);\n return result & 0xffff;\n};\n\n/**\n * fnXOR(src, dst)\n *\n * @this {CPUStatePDP11}\n * @param {number} src\n * @param {number} dst\n * @return {number} (dst ^ src)\n */\nPDP11.fnXOR = function(src, dst)\n{\n var result = dst ^ src;\n this.updateNZVFlags(result);\n return result & 0xffff;\n};\n\n/**\n * opADC(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opADC = function(opCode)\n{\n this.updateDstWord(opCode, this.getCF()? 1 : 0, PDP11.fnADD);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opADCB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opADCB = function(opCode)\n{\n this.updateDstByte(opCode, this.getCF()? 1 : 0, PDP11.fnADDB);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opADD(opCode)\n *\n * From the PDP-11/20 Processor HandBook (1971), p. 61:\n *\n * Add src,dst (06SSDD)\n *\n * Operation:\n * (dst) = (src) + (dst)\n *\n * Condition Codes:\n * N: set if result < 0; cleared otherwise\n * Z: set if result = 0; cleared otherwise\n * V: set if there was arithmetic overflow as a result of the operation, that is both operands\n * were of the same sign and the result was of the opposite sign; cleared otherwise\n * C: set if there was a carry from the most significant bit of the result; cleared otherwise\n *\n * Description:\n * Adds the source operand to the destination operand and stores the result at the destination address.\n * The original contents of the destination are lost. The contents of the source are not affected.\n * Two's complement addition is performed.\n *\n * Examples:\n * Add to register: ADD 20,R0\n * Add to memory: ADD R1,XXX\n * Add register to register: ADD R1,R2\n * Add memory to memory: ADD @#17750,XXX\n *\n * XXX is a programmer-defined mnemonic for a memory location.\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opADD = function(opCode)\n{\n this.updateDstWord(opCode, this.readSrcWord(opCode), PDP11.fnADD);\n this.nStepCycles -= (this.dstMode? (8 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 2) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opASH(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opASH = function(opCode)\n{\n var src = this.readDstWord(opCode);\n var reg = (opCode >> 6) & 7;\n var result = this.regsGen[reg];\n if (result & 0x8000) result |= 0xffff0000;\n this.flagC = this.flagV = 0;\n src &= 0x3F;\n if (src & 0x20) {\n src = 64 - src; // shift right\n if (src > 16) src = 16;\n this.flagC = result << (17 - src);\n result = result >> src;\n } else if (src) {\n if (src > 16) { // shift left\n this.flagV = result;\n result = 0;\n } else {\n result = result << src;\n this.flagC = result;\n var dst = (result >> 15) & 0xffff; // check successive sign bits\n if (dst && dst !== 0xffff) this.flagV = 0x8000;\n }\n }\n this.regsGen[reg] = result & 0xffff;\n this.flagN = this.flagZ = result;\n this.nStepCycles -= (this.dstMode? (5 + 1) : (6 + 1)) + src;\n};\n\n/**\n * opASHC(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opASHC = function(opCode)\n{\n var src = this.readDstWord(opCode);\n var reg = (opCode >> 6) & 7;\n var dst = (this.regsGen[reg] << 16) | this.regsGen[reg | 1];\n this.flagC = this.flagV = 0;\n src &= 0x3F;\n if (src & 0x20) {\n src = 64 - src; // shift right\n if (src > 32) src = 32;\n var result = dst >> (src - 1);\n this.flagC = result << 16;\n result >>= 1;\n if (dst & 0x80000000) result |= 0xffffffff << (32 - src);\n } else {\n if (src) { // shift left\n result = dst << (src - 1);\n this.flagC = result >> 15;\n result <<= 1;\n if (src > 32) src = 32;\n dst = dst >> (32 - src);\n if (dst) {\n dst |= (0xffffffff << src) & 0xffffffff;\n if (dst !== 0xffffffff) this.flagV = 0x8000;\n }\n } else {\n result = dst;\n }\n }\n this.regsGen[reg] = (result >> 16) & 0xffff;\n this.regsGen[reg | 1] = result & 0xffff;\n this.flagN = result >> 16;\n this.flagZ = result >> 16 | result;\n this.nStepCycles -= (this.dstMode? (5 + 1) : (6 + 1)) + src;\n};\n\n/**\n * opASL(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opASL = function(opCode)\n{\n this.updateDstWord(opCode, 0, PDP11.fnASL);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opASLB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opASLB = function(opCode)\n{\n this.updateDstByte(opCode, 0, PDP11.fnASLB);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opASR(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opASR = function(opCode)\n{\n this.updateDstWord(opCode, 0, PDP11.fnASR);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opASRB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opASRB = function(opCode)\n{\n this.updateDstByte(opCode, 0, PDP11.fnASRB);\n this.nStepCycles -= (this.dstMode? (8 + 1) + (this.dstAddr & 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opBCC(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBCC = function(opCode)\n{\n this.branch(opCode, !this.getCF());\n};\n\n/**\n * opBCS(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBCS = function(opCode)\n{\n this.branch(opCode, this.getCF());\n};\n\n/**\n * opBIC(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBIC = function(opCode)\n{\n this.updateDstWord(opCode, this.readSrcWord(opCode), PDP11.fnBIC);\n this.nStepCycles -= (this.dstMode? (8 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 2) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opBICB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBICB = function(opCode)\n{\n this.updateDstByte(opCode, this.readSrcByte(opCode), PDP11.fnBICB);\n this.nStepCycles -= (this.dstMode? (8 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 2) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opBIS(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBIS = function(opCode)\n{\n this.updateDstWord(opCode, this.readSrcWord(opCode), PDP11.fnBIS);\n this.nStepCycles -= (this.dstMode? (8 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 2) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opBISB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBISB = function(opCode)\n{\n this.updateDstByte(opCode, this.readSrcByte(opCode), PDP11.fnBISB);\n this.nStepCycles -= (this.dstMode? (8 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 2) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opBIT(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBIT = function(opCode)\n{\n var src = this.readSrcWord(opCode);\n var dst = this.readDstWord(opCode);\n this.updateNZVFlags((src < 0? this.regsGen[-src-1] : src) & dst);\n this.nStepCycles -= (this.dstMode? (3 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 1) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opBITB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBITB = function(opCode)\n{\n var src = this.readSrcByte(opCode);\n var dst = this.readDstByte(opCode);\n this.updateNZVFlags(((src < 0? (this.regsGen[-src-1] & 0xff) : src) & dst) << 8);\n this.nStepCycles -= (this.dstMode? (3 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 1) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opBEQ(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBEQ = function(opCode)\n{\n this.branch(opCode, this.getZF());\n};\n\n/**\n * opBGE(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBGE = function(opCode)\n{\n this.branch(opCode, !this.getNF() == !this.getVF());\n};\n\n/**\n * opBGT(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBGT = function(opCode)\n{\n this.branch(opCode, !this.getZF() && (!this.getNF() == !this.getVF()));\n};\n\n/**\n * opBHI(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBHI = function(opCode)\n{\n this.branch(opCode, !this.getCF() && !this.getZF());\n};\n\n/**\n * opBLE(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBLE = function(opCode)\n{\n this.branch(opCode, this.getZF() || (!this.getNF() != !this.getVF()));\n};\n\n/**\n * opBLOS(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBLOS = function(opCode)\n{\n this.branch(opCode, this.getCF() || this.getZF());\n};\n\n/**\n * opBLT(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBLT = function(opCode)\n{\n this.branch(opCode, !this.getNF() != !this.getVF());\n};\n\n/**\n * opBMI(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBMI = function(opCode)\n{\n this.branch(opCode, this.getNF());\n};\n\n/**\n * opBNE(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBNE = function(opCode)\n{\n this.branch(opCode, !this.getZF());\n};\n\n/**\n * opBPL(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBPL = function(opCode)\n{\n this.branch(opCode, !this.getNF());\n};\n\n/**\n * opBPT(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBPT = function(opCode)\n{\n this.trap(PDP11.TRAP.BPT, 0, PDP11.REASON.OPCODE);\n};\n\n/**\n * opBR(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBR = function(opCode)\n{\n this.branch(opCode, true);\n};\n\n/**\n * opBVC(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBVC = function(opCode)\n{\n this.branch(opCode, !this.getVF());\n};\n\n/**\n * opBVS(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opBVS = function(opCode)\n{\n this.branch(opCode, this.getVF());\n};\n\n/**\n * opCLR(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCLR = function(opCode)\n{\n this.writeDstWord(opCode, 0, this.updateAllFlags);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opCLRB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCLRB = function(opCode)\n{\n this.writeDstByte(opCode, 0, PDP11.WRITE.BYTE, this.updateAllFlags);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opCLC(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCLC = function(opCode)\n{\n this.clearCF();\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opCLN(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCLN = function(opCode)\n{\n this.clearNF();\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opCLV(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCLV = function(opCode)\n{\n this.clearVF();\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opCLZ(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCLZ = function(opCode)\n{\n this.clearZF();\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opCLx(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCLx = function(opCode)\n{\n if (opCode & 0x1) this.clearCF();\n if (opCode & 0x2) this.clearVF();\n if (opCode & 0x4) this.clearZF();\n if (opCode & 0x8) this.clearNF();\n /*\n * TODO: Review whether this class of undocumented instructions really has a constant cycle time.\n */\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opCMP(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCMP = function(opCode)\n{\n var src = this.readSrcWord(opCode);\n var dst = this.readDstWord(opCode);\n var result = (src = (src < 0? this.regsGen[-src-1] : src)) - dst;\n /*\n * NOTE: CMP calculates (src - dst) rather than (dst - src), so src and dst updateSubFlags() parms must be reversed.\n */\n this.updateSubFlags(result, dst, src);\n this.nStepCycles -= (this.dstMode? (3 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 1) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opCMPB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCMPB = function(opCode)\n{\n var src = this.readSrcByte(opCode);\n var dst = this.readDstByte(opCode);\n var result = (src = (src < 0? (this.regsGen[-src-1] & 0xff): src) << 8) - (dst <<= 8);\n /*\n * NOTE: CMP calculates (src - dst) rather than (dst - src), so src and dst updateSubFlags() parms must be reversed.\n */\n this.updateSubFlags(result, dst, src);\n this.nStepCycles -= (this.dstMode? (3 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 1) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opCOM(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCOM = function(opCode)\n{\n this.updateDstWord(opCode, 0, PDP11.fnCOM);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opCOMB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opCOMB = function(opCode)\n{\n this.updateDstByte(opCode, 0, PDP11.fnCOMB);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opDEC(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opDEC = function(opCode)\n{\n this.updateDstWord(opCode, 1, PDP11.fnDEC);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opDECB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opDECB = function(opCode)\n{\n this.updateDstByte(opCode, 1, PDP11.fnDECB);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opDIV(opCode)\n *\n * The instruction \"DIV SRC,Rn\" determines SRC using the DSTMODE portion of the opcode and Rn using\n * the SRCMODE portion; Rn can only be a register (and it should be an EVEN-numbered register, lest you\n * get unexpected results). The dividend (DST) is then calculated as:\n *\n * DST = (regs[Rn] << 16) | (regs[Rn|1])\n *\n * DST is divided by SRC, and the quotient is stored in regs[Rn] and the remainder in regs[Rn|1].\n *\n * For example:\n *\n * DIV R4,R0\n *\n * where R4 = 006400 and R0,R1 = 000000,015000 will result in R0,R1 = 000002,000000.\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opDIV = function(opCode)\n{\n /*\n * TODO: Review and determine if flag updates can be encapsulated in an updateDivFlags() function.\n */\n var src = this.readDstWord(opCode);\n if (!src) {\n this.flagN = 0; // NZVC\n this.flagZ = 0;\n this.flagV = 0x8000;\n this.flagC = 0x10000; // divide by zero\n this.nStepCycles -= (6 + 1);\n } else {\n var reg = (opCode >> 6) & 7;\n var dst = (this.regsGen[reg] << 16) | this.regsGen[reg | 1];\n this.flagC = this.flagV = 0;\n if (src & 0x8000) src |= ~0xffff;\n var result = ~~(dst / src);\n if (result >= -32768 && result <= 32767) {\n this.regsGen[reg] = result & 0xffff;\n this.regsGen[reg | 1] = (dst - (result * src)) & 0xffff;\n this.flagZ = (result >> 16) | result;\n this.flagN = result >> 16;\n } else {\n this.flagV = 0x8000; // overflow - following are indeterminate\n this.flagZ = (result >> 15) | result; // dodgy\n this.flagN = dst >> 16; // just as dodgy\n if (src === -1 && this.regsGen[reg] === 0xfffe) {\n this.regsGen[reg] = this.regsGen[reg | 1] = 1; // etc\n }\n }\n this.nStepCycles -= (52 + 1); // 52 is the average of the shortest and longest times\n }\n};\n\n/**\n * opEMT(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opEMT = function(opCode)\n{\n this.trap(PDP11.TRAP.EMT, 0, PDP11.REASON.OPCODE);\n this.nStepCycles -= (22 + 3 - 5);\n};\n\n/**\n * opHALT(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opHALT = function(opCode)\n{\n if (this.regPSW & PDP11.PSW.CMODE) {\n this.regErr |= PDP11.CPUERR.BADHALT;\n this.trap(PDP11.TRAP.BUS, 0, PDP11.REASON.HALT);\n } else {\n if (this.panel) {\n /*\n * The PDP-11/20 Handbook (1971) says that HALT does the following:\n *\n * Causes the processor operation to cease. The console is given control of the bus.\n * The console data lights display the contents of RO; the console address lights display\n * the address after the halt instruction. Transfers on the UNIBUS are terminated immediately.\n * The PC points to the next instruction to be executed. Pressing the continue key on the\n * console causes processor operation to resume. No INIT signal is given.\n *\n * However, the PDP-11/70 Handbook (1979) suggests some slight differences:\n *\n * Causes the processor operation to cease. The console is given control of the processor.\n * The data lights display the contents of the PC (which is the address of the HALT instruction\n * plus 2). Transfers on the UNIBUS are terminated immediately. Pressing the continue key on\n * the console causes processor operation to resume.\n *\n * Given that the 11/70 doesn't saying anything about displaying R0 on a HALT, and also given that\n * the 11/70 CPU EXERCISER diagnostic writes a value to the Console Switch/Display Register immediately\n * before HALT'ing, I'm going to assume that updating the data display with R0 is unique to the 11/20.\n *\n * Also, I'm a little suspicious of the 11/70 comment that the \"data lights display the contents of\n * the PC,\" since previous models display the PC on the ADDRESS lights, not the DATA lights. And as\n * I already explained, doing anything to the data lights at this point would undo what the 11/70\n * diagnostics do.\n */\n if (this.model == PDP11.MODEL_1120) {\n this.panel.setData(this.regsGen[0], true);\n }\n }\n if (!this.dbg) {\n /*\n * This will leave the PC exactly where it's supposed to be: at the address of the HALT + 2.\n */\n this.stopCPU();\n } else {\n /*\n * When the Debugger is present, this call will rewind PC by 2 so that the HALT instruction is\n * displayed, making it clear why the processor stopped; the user could also use the \"dh\" command\n * to dump the Debugger's instruction history buffer to see why it stopped, assuming the history\n * buffer is enabled, but that's more work.\n *\n * Because rewinding is not normal CPU behavior, attempting to Run again (or use the Debugger's\n * \"g\" command) would cause an immediate HALT again -- except that checkInstruction() checks for that\n * precise condition, so if the CPU starts on a HALT, checkInstruction() will skip over it.\n */\n this.dbg.stopInstruction();\n }\n }\n this.nStepCycles -= 7;\n};\n\n/**\n * opINC(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opINC = function(opCode)\n{\n this.updateDstWord(opCode, 1, PDP11.fnINC);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opINCB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opINCB = function(opCode)\n{\n this.updateDstByte(opCode, 1, PDP11.fnINCB);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opIOT(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opIOT = function(opCode)\n{\n this.trap(PDP11.TRAP.IOT, 0, PDP11.REASON.OPCODE);\n this.nStepCycles -= (22 + 3 - 5);\n};\n\nPDP11.JMP_CYCLES = [\n 0, 6 + 1, 6 + 1, 8 + 2, 6 + 1, 9 + 2, 7 + 2, 10 + 3\n];\n\n/**\n * opJMP(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opJMP = function(opCode)\n{\n /*\n * Since JMP and JSR opcodes have their own unique timings for the various dst modes, we must snapshot\n * nStepCycles before decoding the mode, and then use that to update nStepCycles.\n */\n this.nSnapCycles = this.nStepCycles;\n this.setPC(this.readDstAddr(opCode));\n this.nStepCycles = this.nSnapCycles - PDP11.JMP_CYCLES[this.dstMode];\n};\n\nPDP11.JSR_CYCLES = [\n 0, 13 + 1, 13 + 1, 15 + 2, 13 + 1, 16 + 2, 14 + 2, 17 + 3\n];\n\n/**\n * opJSR(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opJSR = function(opCode)\n{\n /*\n * Since JMP and JSR opcodes have their own unique timings for the various dst modes, we must\n * snapshot nStepCycles before decoding the mode, and then use that to update nStepCycles.\n */\n this.nSnapCycles = this.nStepCycles;\n var addr = this.readDstAddr(opCode);\n /*\n * As per the WARNING in readSrcWord(), reading the SRC register AFTER decoding the DST operand\n * is entirely appropriate.\n */\n var reg = (opCode >> PDP11.SRCMODE.SHIFT) & PDP11.OPREG.MASK;\n this.pushWord(this.regsGen[reg]);\n this.regsGen[reg] = this.getPC();\n this.setPC(addr);\n this.nStepCycles = this.nSnapCycles - PDP11.JSR_CYCLES[this.dstMode];\n};\n\n/**\n * opMARK(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMARK = function(opCode)\n{\n var addr = (this.getPC() + ((opCode & 0x3F) << 1)) & 0xffff;\n var src = this.readWord(addr | this.addrDSpace);\n this.setPC(this.regsGen[5]);\n this.setSP(addr + 2);\n this.regsGen[5] = src;\n this.nStepCycles -= (6 + 2);\n};\n\n/**\n * opMFPD(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMFPD = function(opCode)\n{\n var data = this.readWordFromPrevSpace(opCode, PDP11.ACCESS.DSPACE);\n this.updateNZVFlags(data);\n this.pushWord(data);\n this.nStepCycles -= (10 + 1);\n};\n\n/**\n * opMFPI(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMFPI = function(opCode)\n{\n var data = this.readWordFromPrevSpace(opCode, PDP11.ACCESS.ISPACE);\n this.updateNZVFlags(data);\n this.pushWord(data);\n this.nStepCycles -= (10 + 1);\n};\n\n/**\n * opMFPS(opCode)\n *\n * 1067XX MFPS - Move Byte From PSW\n *\n * The 8-bit contents of the PS are moved to the effective destination. If destination is mode 0,\n * PS bit 7 is sign extended through the upper byte of the register. The destination operand is treated\n * as a byte address. 11/34A only.\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMFPS = function(opCode)\n{\n PDP11.opUndefined.call(this, opCode);\n};\n\n/**\n * opMFPT(opCode)\n *\n * 000007 MFPT - Move From Processor Type\n *\n * Loads R0 with a value indicating the processor type.\n *\n * R0 Hardware\n * 1 PDP-11/44\n * 3 PDP-11/24 (should be 2)\n * 3 PDP-11/23\n * 4 SBC-11/21\n * 5 All J11 chips including 11/73, 11/83, 11/93\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMFPT = function(opCode)\n{\n PDP11.opUndefined.call(this, opCode);\n};\n\nPDP11.MOV_CYCLES = [\n 2 + 1, 8 + 1, 8 + 1, 11 + 2, 9 + 1, 12 + 2, 10 + 2, 13 + 3,\n 3 + 1, 8 + 1, 8 + 1, 11 + 2, 9 + 1, 12 + 2, 11 + 2, 14 + 3\n];\n\n/**\n * opMOV(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMOV = function(opCode)\n{\n /*\n * Since MOV opcodes have their own unique timings for the various dst modes, we must snapshot\n * nStepCycles after decoding the src mode, and then use that to update nStepCycles.\n */\n var data = this.readSrcWord(opCode);\n this.nSnapCycles = this.nStepCycles;\n this.writeDstWord(opCode, data, this.updateNZVFlags);\n this.nStepCycles = this.nSnapCycles - PDP11.MOV_CYCLES[(this.srcMode? 8 : 0) + this.dstMode] + (this.dstReg == 7 && !this.dstMode? 2 : 0);\n};\n\n/**\n * opMOVB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMOVB = function(opCode)\n{\n var data = this.readSrcByte(opCode);\n this.writeDstByte(opCode, data, PDP11.WRITE.SBYTE, this.updateNZVFlags);\n this.nStepCycles -= (this.dstMode? (8 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 2) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\nPDP11.MTP_CYCLES = [\n 6 + 1, 11 + 2, 11 + 2, 14 + 3, 12 + 2, 15 + 3, 14 + 3, 17 + 4\n];\n\n/**\n * opMTPD(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMTPD = function(opCode)\n{\n /*\n * Since MTPD and MTPI opcodes have their own unique timings for the various dst modes, we must snapshot\n * nStepCycles before decoding the mode, and then use that to update nStepCycles.\n */\n var data = this.popWord();\n this.nSnapCycles = this.nStepCycles;\n this.updateNZVFlags(data);\n this.writeWordToPrevSpace(opCode, PDP11.ACCESS.DSPACE, data);\n this.nStepCycles = this.nSnapCycles - PDP11.MTP_CYCLES[this.dstMode];\n};\n\n/**\n * opMTPI(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMTPI = function(opCode)\n{\n /*\n * Since MTPD and MTPI opcodes have their own unique timings for the various dst modes, we must snapshot\n * nStepCycles before decoding the mode, and then use that to update nStepCycles.\n */\n var data = this.popWord();\n this.nSnapCycles = this.nStepCycles;\n this.updateNZVFlags(data);\n this.writeWordToPrevSpace(opCode, PDP11.ACCESS.ISPACE, data);\n this.nStepCycles = this.nSnapCycles - PDP11.MTP_CYCLES[this.dstMode];\n};\n\n/**\n * opMTPS(opCode)\n *\n * 1064XX MTPS - Move Byte To PSW\n *\n * The 8 bits of the effective operand replace the current contents of the PS <0:7>. The source operand\n * address is treated as a byte address. Note that PS bit 4 cannot be set with this instruction. The\n * src operand remains unchanged. 11/34A only.\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMTPS = function(opCode)\n{\n PDP11.opUndefined.call(this, opCode);\n};\n\n/**\n * opMUL(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opMUL = function(opCode)\n{\n var src = this.readDstWord(opCode);\n var reg = (opCode >> 6) & 7;\n var dst = this.regsGen[reg];\n var result = ((src << 16) >> 16) * ((dst << 16) >> 16);\n this.regsGen[reg] = (result >> 16) & 0xffff;\n this.regsGen[reg | 1] = result & 0xffff;\n this.updateMulFlags(result|0);\n this.nStepCycles -= (22 + 1);\n};\n\n/**\n * opNEG(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opNEG = function(opCode)\n{\n this.updateDstWord(opCode, 0, PDP11.fnNEG);\n this.nStepCycles -= (this.dstMode? (10 + 1) : (5 + 1));\n};\n\n/**\n * opNEGB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opNEGB = function(opCode)\n{\n this.updateDstByte(opCode, 0, PDP11.fnNEGB);\n this.nStepCycles -= (this.dstMode? (10 + 1) : (5 + 1));\n};\n\n/**\n * opNOP(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opNOP = function(opCode)\n{\n this.nStepCycles -= (4 + 1); // TODO: Review (this is just a guess based on CLC)\n};\n\n/**\n * opRESET(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opRESET = function(opCode)\n{\n if (!(this.regPSW & PDP11.PSW.CMODE)) {\n this.resetCPU();\n\n if (this.panel) {\n /*\n * The PDP-11/70 XXDP test \"EKBBF0\" reports the following, with PANEL messages on (\"m panel on\"):\n *\n * CNSW.writeWord(177570,000101) @033502\n * CNSW.readWord(177570): 000000 @032114\n * LOOK AT THE CONSOLE LIGHTS\n * THE DATA LIGHTS SHOULD READ 166667\n * THE ADDRESS LIGHTS SHOULD READ CNSW.readWord(177570): 000000 @032150\n * 032236\n * CHANGE SWITCH 7 TO CONTINUE\n * CNSW.readWord(177570): 000000 @032236\n * stopped (31518011 instructions, 358048873 cycles, 58644 ms, 6105465 hz)\n * R0=166667 R1=002362 R2=000000 R3=000000 R4=000000 R5=026642\n * SP=001074 PC=032236 PS=000344 SR=00000000 T0 N0 Z1 V0 C0\n * 032236: 032737 000200 177570 BIT #200,@#177570\n * >> tr\n * CNSW.readWord(177570): 000000 @032236 (cpu halted)\n * R0=166667 R1=002362 R2=000000 R3=000000 R4=000000 R5=026642\n * SP=001074 PC=032244 PS=000344 SR=00000000 T0 N0 Z1 V0 C0\n * 032244: 001773 BEQ 032234 ;cycles=0\n * >> tr\n * R0=166667 R1=002362 R2=000000 R3=000000 R4=000000 R5=026642\n * SP=001074 PC=032234 PS=000344 SR=00000000 T0 N0 Z1 V0 C0\n * 032234: 000005 RESET ;cycles=5\n *\n * It's a little hard to see why the DATA lights should read 166667, since the PANEL messages indicate\n * that the last CNSW.writeWord(177570) was for 000101, not 166667. So I'm guessing that the RESET\n * instruction is supposed to propagate R0 to the console's DISPLAY register.\n *\n * This is similar to what we do for the HALT instruction (but only if this.model == PDP11.MODEL_1120).\n * These Console features do not seem to be very well documented, assuming they exist.\n *\n * UPDATE: This behavior appears to be confirmed by remarks in the PDP-11/20 Processor Handbook (1971),\n * p. 141:\n *\n * HALT - displays processor register R0 when bus control is transferred to console during a HALT\n * instruction.\n *\n * RESET - displays register R0 for during [duration?] of RESET (70 msec).\n *\n * I haven't found similar remarks in the PDP-11/70 Processor Handbooks, so I'm not sure if that's an\n * oversight or if 11/70 panels are slightly different in this regard. It's also not clear what they meant\n * by \"for duration of RESET\". Is something supposed to happen to the DATA lights after the RESET is done?\n */\n this.panel.setData(this.regsGen[0], true);\n }\n }\n this.nStepCycles -= 667; // TODO: Review (but it's definitely a big number)\n};\n\n/**\n * opROL(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opROL = function(opCode)\n{\n this.updateDstWord(opCode, 0, PDP11.fnROL);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opROLB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opROLB = function(opCode)\n{\n this.updateDstByte(opCode, 0, PDP11.fnROLB);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opROR(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opROR = function(opCode)\n{\n this.updateDstWord(opCode, 0, PDP11.fnROR);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opRORB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opRORB = function(opCode)\n{\n this.updateDstByte(opCode, 0, PDP11.fnRORB);\n this.nStepCycles -= (this.dstMode? (8 + 1) + (this.dstAddr & 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opRTI(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opRTI = function(opCode)\n{\n this.trapReturn();\n /*\n * Unlike RTT, RTI permits an immediate trace, which we resolve by propagating PSW.TF to OPFLAG.TRAP_TF\n * (which, as written below, requires that both flags have the same bit value; see defines.js).\n *\n * NOTE: This RTI trace behavior is NEW for machines that have both RTI and RTT. Early models didn't have RTT,\n * so the old RTI behaved exactly like the new RTT. Which is why the 11/20 jump table below calls opRTT() instead\n * of opRTI() for RTI.\n */\n this.opFlags |= (this.regPSW & PDP11.PSW.TF);\n this.nStepCycles -= (10 + 3);\n};\n\n/**\n * opRTS(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opRTS = function(opCode)\n{\n if (opCode & 0x08) {\n PDP11.opUndefined.call(this, opCode);\n return;\n }\n var src = this.popWord();\n var reg = opCode & PDP11.OPREG.MASK;\n /*\n * When the popular \"RTS PC\" form is used, we might as well eliminate the useless setting of PC...\n */\n if (reg == PDP11.REG.PC) {\n this.setPC(src);\n } else {\n this.setPC(this.regsGen[reg]);\n this.regsGen[reg] = src;\n }\n this.nStepCycles -= (7 + 2);\n};\n\n/**\n * opRTT(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opRTT = function(opCode)\n{\n this.trapReturn();\n this.nStepCycles -= (10 + 3);\n};\n\n/**\n * opSBC(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSBC = function(opCode)\n{\n this.updateDstWord(opCode, this.getCF()? 1 : 0, PDP11.fnSUB);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opSBCB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSBCB = function(opCode)\n{\n this.updateDstByte(opCode, this.getCF()? 1 : 0, PDP11.fnSUBB);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opSEC(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSEC = function(opCode)\n{\n this.setCF();\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opSEN(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSEN = function(opCode)\n{\n this.setNF();\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opSEV(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSEV = function(opCode)\n{\n this.setVF();\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opSEZ(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSEZ = function(opCode)\n{\n this.setZF();\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opSEx(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSEx = function(opCode)\n{\n if (opCode & 0x1) this.setCF();\n if (opCode & 0x2) this.setVF();\n if (opCode & 0x4) this.setZF();\n if (opCode & 0x8) this.setNF();\n /*\n * TODO: Review whether this class of undocumented instructions really has a constant cycle time.\n */\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opSOB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode (077Rnn)\n */\nPDP11.opSOB = function(opCode)\n{\n var reg = (opCode & PDP11.SRCMODE.REG) >> PDP11.SRCMODE.SHIFT;\n if ((this.regsGen[reg] = ((this.regsGen[reg] - 1) & 0xffff))) {\n this.setPC(this.getPC() - ((opCode & PDP11.DSTMODE.MASK) << 1));\n this.nStepCycles += 1; // unlike normal branches, taking this branch is actually 1 cycle faster\n }\n this.nStepCycles -= (5 + 1);\n};\n\n/**\n * opSPL(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSPL = function(opCode)\n{\n if (!(opCode & 0x08) || this.model < PDP11.MODEL_1145) {\n PDP11.opUndefined.call(this, opCode);\n return;\n }\n if (!(this.regPSW & PDP11.PSW.CMODE)) {\n this.regPSW = (this.regPSW & ~PDP11.PSW.PRI) | ((opCode & 0x7) << PDP11.PSW.SHIFT.PRI);\n this.opFlags |= PDP11.OPFLAG.IRQ_DELAY;\n this.opFlags &= ~PDP11.OPFLAG.IRQ;\n }\n this.nStepCycles -= (4 + 1);\n};\n\n/**\n * opSUB(opCode)\n *\n * From the PDP-11/20 Processor HandBook (1971), p. 62:\n *\n * Subtract src,dst (16SSDD)\n *\n * Operation:\n * (dst) = (dst) - (src) [in detail, (dst) + ~(src) + 1 (dst)]\n *\n * Condition Codes:\n * N: set if result < 0; cleared otherwise\n * Z: set if result = 0; cleared otherwise\n * V: set if there was arithmetic overflow as a result of the operation, that is if operands were of\n * opposite signs and the sign of the source was the same as the sign of the result; cleared otherwise\n * C: cleared if there was a carry from the most significant bit of the result; set otherwise\n *\n * Description:\n * Subtracts the source operand from the destination operand and leaves the result at the destination address.\n * The orignial [sic] contents of the destination are lost. The contents of the source are not affected.\n * In double-precision arithmetic the C-bit, when set, indicates a \"borrow\".\n *\n * Example:\n * SUB R1,R2\n *\n * BEFORE AFTER\n * (R1) = 011111 (R2) = 012345\n * (R1) = 011111 (R2) = 001234\n *\n * NZVC NZVC\n * 1111 0001\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSUB = function(opCode)\n{\n this.updateDstWord(opCode, this.readSrcWord(opCode), PDP11.fnSUB);\n this.nStepCycles -= (this.dstMode? (8 + 1) + (this.srcReg && this.dstReg >= 6? 1 : 0) : (this.srcMode? (3 + 2) : (2 + 1)) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opSWAB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSWAB = function(opCode)\n{\n this.updateDstWord(opCode, 0, PDP11.fnSWAB);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opSXT(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opSXT = function(opCode)\n{\n this.writeDstWord(opCode, this.getNF()? 0xffff : 0, this.updateNZVFlags);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opTRAP(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opTRAP = function(opCode)\n{\n this.trap(PDP11.TRAP.TRAP, 0, PDP11.REASON.OPCODE);\n};\n\n/**\n * opTST(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opTST = function(opCode)\n{\n var result = this.readDstWord(opCode);\n\n this.updateAllFlags(result);\n this.nStepCycles -= (this.dstMode? (3 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opTSTB(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opTSTB = function(opCode)\n{\n var result = this.readDstByte(opCode);\n\n this.updateAllFlags(result << 8);\n this.nStepCycles -= (this.dstMode? (3 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opWAIT(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opWAIT = function(opCode)\n{\n /*\n * The original PDP-11 emulation code would actually stop emulating instructions now, relying on assorted\n * setTimeout() callbacks, setInterval() callbacks, device XHR (XMLHttpRequest) callbacks, etc, to eventually\n * call interrupt(), which would then transition the CPU out of its \"wait\" state and kickstart emulate() again.\n *\n * That approach isn't compatible with PCjs emulators, which prefer to rely on the simulated CPU clock to\n * drive all simulated device updates. This means components should call the CPU's setTimer() function, which\n * invokes the provided callback when the number of CPU cycles that correspond to the requested number of\n * milliseconds have elapsed. This also gives us the ability to scale device response times as needed if the\n * user decides to crank up CPU speed, and to freeze them along with the CPU whenever the user halts the machine.\n *\n * However, the PCjs approach requires the CPU to continue running. One simple solution to this dilemma:\n *\n * 1) opWAIT() sets a new opFlags bit (OPFLAG.WAIT)\n * 2) Rewind the PC back to the WAIT instruction\n * 3) Whenever stepCPU() detects OPFLAG.WAIT, call checkInterrupts()\n * 4) If checkInterrupts() detects an interrupt, advance PC past the WAIT and then dispatch the interrupt\n *\n * Technically, the PC is already exactly where it's supposed to be, so why are we wasting time with steps\n * 2 and 4? It's largely for the Debugger's sake, so that as long as execution is \"blocked\" by a WAIT, that's\n * what you'll see in the Debugger. I could make those steps conditioned on the presence of the Debugger,\n * but I feel it's better to keep all code paths the same.\n *\n * NOTE: It's almost always a bad idea to add more checks to the inner stepCPU() loop, because every additional\n * check can have a measurable (negative) impact on performance. Which is why it's important to use opFlags bits\n * whenever possible, since we can test for multiple (up to 32) exceptional conditions with a single check.\n *\n * We also used to update the machine's display(s) whenever transitioning to the WAIT state. However, that\n * caused this instruction to generate enormous overhead, and it's no longer necessary, since we now rely on\n * a timer (the PDP-11's own KW11 60Hz Line Clock timer, to be precise) to generate periodic display updates.\n *\n * if (!(this.opFlags & PDP11.OPFLAG.WAIT) && this.cmp) this.cmp.updateDisplays();\n *\n * Finally, it's been noted several places online that the WAIT instruction puts the contents of R0 into the\n * Front Panel's \"DATA PATH\" (and possibly even directly into the \"DISPLAY REGISTER\", making the DATASEL switch\n * setting irrelevant). I can't find any supporting DEC documentation regarding this, but for now, we'll go\n * with popular lore and propagate R0 to the panel's \"active\" data register.\n */\n if (this.panel) {\n this.panel.setAddr(this.regsGen[7], true);\n this.panel.setData(this.regsGen[0], true);\n }\n this.opFlags |= PDP11.OPFLAG.WAIT;\n this.advancePC(-2);\n this.nStepCycles -= 3;\n};\n\n/**\n * opXOR(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opXOR = function(opCode)\n{\n var reg = (opCode >> PDP11.SRCMODE.SHIFT) & PDP11.OPREG.MASK;\n this.updateDstWord(opCode, this.regsGen[reg + this.offRegSrc], PDP11.fnXOR);\n this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));\n};\n\n/**\n * opUndefined(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.opUndefined = function(opCode)\n{\n if (DEBUGGER && this.dbg) {\n if (this.dbg.undefinedInstruction(opCode)) return;\n }\n this.trap(PDP11.TRAP.RESERVED, 0, PDP11.REASON.OPCODE);\n};\n\n/**\n * op1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op1120 = function(opCode)\n{\n PDP11.aOpXnnn_1120[opCode >> 12].call(this, opCode);\n};\n\n/**\n * op0Xnn_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op0Xnn_1120 = function(opCode)\n{\n PDP11.aOp0Xnn_1120[(opCode >> 8) & 0xf].call(this, opCode);\n};\n\n/**\n * op0AXn_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op0AXn_1120 = function(opCode)\n{\n PDP11.aOp0AXn_1120[(opCode >> 6) & 0x3].call(this, opCode);\n};\n\n/**\n * op0BXn_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op0BXn_1120 = function(opCode)\n{\n PDP11.aOp0BXn_1120[(opCode >> 6) & 0x3].call(this, opCode);\n};\n\n/**\n * op0CXn_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op0CXn_1120 = function(opCode)\n{\n PDP11.aOp0CXn_1120[(opCode >> 6) & 0x3].call(this, opCode);\n};\n\n/**\n * op00Xn_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op00Xn_1120 = function(opCode)\n{\n PDP11.aOp00Xn_1120[(opCode >> 4) & 0xf].call(this, opCode);\n};\n\n/**\n * op00AX_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op00AX_1120 = function(opCode)\n{\n PDP11.aOp00AX_1120[opCode & 0xf].call(this, opCode);\n};\n\n/**\n * op00BX_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op00BX_1120 = function(opCode)\n{\n PDP11.aOp00BX_1120[opCode & 0xf].call(this, opCode);\n};\n\n/**\n * op000X_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op000X_1120 = function(opCode)\n{\n PDP11.aOp000X_1120[opCode & 0xf].call(this, opCode);\n};\n\n/**\n * op8Xnn_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op8Xnn_1120 = function(opCode)\n{\n PDP11.aOp8Xnn_1120[(opCode >> 8) & 0xf].call(this, opCode);\n};\n\n/**\n * op8AXn_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op8AXn_1120 = function(opCode)\n{\n PDP11.aOp8AXn_1120[(opCode >> 6) & 0x3].call(this, opCode);\n};\n\n/**\n * op8BXn_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op8BXn_1120 = function(opCode)\n{\n PDP11.aOp8BXn_1120[(opCode >> 6) & 0x3].call(this, opCode);\n};\n\n/**\n * op8CXn_1120(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op8CXn_1120 = function(opCode)\n{\n PDP11.aOp8CXn_1120[(opCode >> 6) & 0x3].call(this, opCode);\n};\n\nPDP11.aOpXnnn_1120 = [\n PDP11.op0Xnn_1120, // 0x0nnn\n PDP11.opMOV, // 0x1nnn 01SSDD 11/20+ 2.3\n PDP11.opCMP, // 0x2nnn 02SSDD 11/20+ 2.3*\n PDP11.opBIT, // 0x3nnn 03SSDD 11/20+ 2.9*\n PDP11.opBIC, // 0x4nnn 04SSDD 11/20+ 2.9\n PDP11.opBIS, // 0x5nnn 05SSDD 11/20+ 2.3\n PDP11.opADD, // 0x6nnn 06SSDD 11/20+ 2.3\n PDP11.opUndefined, // 0x7nnn\n PDP11.op8Xnn_1120, // 0x8nnn\n PDP11.opMOVB, // 0x9nnn 11SSDD 11/20+ 2.3\n PDP11.opCMPB, // 0xAnnn 12SSDD 11/20+ 2.3\n PDP11.opBITB, // 0xBnnn 13SSDD 11/20+ 2.9\n PDP11.opBICB, // 0xCnnn 14SSDD 11/20+ 2.9\n PDP11.opBISB, // 0xDnnn 15SSDD 11/20+ 2.3\n PDP11.opSUB, // 0xEnnn 16SSDD 11/20+ 2.3\n PDP11.opUndefined // 0xFnnn\n];\n\nPDP11.aOp0Xnn_1120 = [\n PDP11.op00Xn_1120, // 0x00nn\n PDP11.opBR, // 0x01nn 0004XX 11/20+ 2.6\n PDP11.opBNE, // 0x02nn 0010XX 11/20+ 2.6**\n PDP11.opBEQ, // 0x03nn 0014XX 11/20+ 2.6**\n PDP11.opBGE, // 0x04nn 0020XX 11/20+ 2.6**\n PDP11.opBLT, // 0x05nn 0024XX 11/20+ 2.6**\n PDP11.opBGT, // 0x06nn 0030XX 11/20+ 2.6**\n PDP11.opBLE, // 0x07nn 0034XX 11/20+ 2.6**\n PDP11.opJSR, // 0x08nn 004RDD 11/20+ 4.4\n PDP11.opJSR, // 0x09nn 004RDD 11/20+ 4.4\n PDP11.op0AXn_1120, // 0x0Ann\n PDP11.op0BXn_1120, // 0x0Bnn\n PDP11.op0CXn_1120, // 0x0Cnn\n PDP11.opUndefined, // 0x0Dnn\n PDP11.opUndefined, // 0x0Enn\n PDP11.opUndefined // 0x0Fnn\n];\n\nPDP11.aOp0AXn_1120 = [\n PDP11.opCLR, // 0x0A0n 0050DD 11/20+ 2.3\n PDP11.opCOM, // 0x0A4n 0051DD 11/20+ 2.3\n PDP11.opINC, // 0x0A8n 0052DD 11/20+ 2.3\n PDP11.opDEC // 0x0ACn 0053DD 11/20+ 2.3\n];\n\nPDP11.aOp0BXn_1120 = [\n PDP11.opNEG, // 0x0B0n 0054DD 11/20+ 2.3\n PDP11.opADC, // 0x0B4n 0055DD 11/20+ 2.3\n PDP11.opSBC, // 0x0B8n 0056DD 11/20+ 2.3\n PDP11.opTST // 0x0BCn 0057DD 11/20+ 2.3*\n];\n\nPDP11.aOp0CXn_1120 = [\n PDP11.opROR, // 0x0C0n 0060DD 11/20+ 2.3*\n PDP11.opROL, // 0x0C4n 0061DD 11/20+ 2.3*\n PDP11.opASR, // 0x0C8n 0062DD 11/20+ 2.3*\n PDP11.opASL // 0x0CCn 0063DD 11/20+ 2.3*\n];\n\nPDP11.aOp00Xn_1120 = [\n PDP11.op000X_1120, // 0x000n 000000-000017\n PDP11.opUndefined, // 0x001n 000020-000037\n PDP11.opUndefined, // 0x002n 000040-000057\n PDP11.opUndefined, // 0x003n 000060-000077\n PDP11.opJMP, // 0x004n 0001DD 11/20+ 1.2\n PDP11.opJMP, // 0x005n 0001DD 11/20+ 1.2\n PDP11.opJMP, // 0x006n 0001DD 11/20+ 1.2\n PDP11.opJMP, // 0x007n 0001DD 11/20+ 1.2\n PDP11.opRTS, // 0x008n 00020R 11/20+ 3.5 (opRTS() will also confirm that bit 3 is clear)\n PDP11.opUndefined, // 0x009n 00023N\n PDP11.op00AX_1120, // 0x00An 000240-000257\n PDP11.op00BX_1120, // 0x00Bn 000260-000277\n PDP11.opSWAB, // 0x00Cn 0003DD 11/20+ 2.3\n PDP11.opSWAB, // 0x00Dn 0003DD 11/20+ 2.3\n PDP11.opSWAB, // 0x00En 0003DD 11/20+ 2.3\n PDP11.opSWAB // 0x00Fn 0003DD 11/20+ 2.3\n];\n\nPDP11.aOp000X_1120 = [\n PDP11.opHALT, // 0x0000 000000 11/20+ 1.8\n PDP11.opWAIT, // 0x0001 000001 11/20+ 1.8\n PDP11.opRTT, // 0x0002 000002 11/20+ 4.8 (this is really RTI, but on the 11/20, it behaves like RTT)\n PDP11.opBPT, // 0x0003\n PDP11.opIOT, // 0x0004 000004 11/20+ 9.3\n PDP11.opRESET, // 0x0005 000005 11/20+ 20ms\n PDP11.opUndefined, // 0x0006\n PDP11.opUndefined, // 0x0007\n PDP11.opUndefined, // 0x0008\n PDP11.opUndefined, // 0x0009\n PDP11.opUndefined, // 0x000A\n PDP11.opUndefined, // 0x000B\n PDP11.opUndefined, // 0x000C\n PDP11.opUndefined, // 0x000D\n PDP11.opUndefined, // 0x000E\n PDP11.opUndefined // 0x000F\n];\n\nPDP11.aOp00AX_1120 = [\n PDP11.opNOP, // 0x00A0 000240 11/20+ 1.5\n PDP11.opCLC, // 0x00A1 000241 11/20+ 1.5\n PDP11.opCLV, // 0x00A2 000242 11/20+ 1.5\n PDP11.opCLx, // 0x00A3 000243 11/20+ 1.5\n PDP11.opCLZ, // 0x00A4 000244 11/20+ 1.5\n PDP11.opCLx, // 0x00A5 000245 11/20+ 1.5\n PDP11.opCLx, // 0x00A6 000246 11/20+ 1.5\n PDP11.opCLx, // 0x00A7 000247 11/20+ 1.5\n PDP11.opCLN, // 0x00A8 000250 11/20+ 1.5\n PDP11.opCLx, // 0x00A9 000251 11/20+ 1.5\n PDP11.opCLx, // 0x00AA 000252 11/20+ 1.5\n PDP11.opCLx, // 0x00AB 000253 11/20+ 1.5\n PDP11.opCLx, // 0x00AC 000254 11/20+ 1.5\n PDP11.opCLx, // 0x00AD 000255 11/20+ 1.5\n PDP11.opCLx, // 0x00AE 000256 11/20+ 1.5\n PDP11.opCLx // 0x00AF 000257 11/20+ 1.5\n];\n\nPDP11.aOp00BX_1120 = [\n PDP11.opNOP, // 0x00B0 000260 11/20+ 1.5\n PDP11.opSEC, // 0x00B1 000261 11/20+ 1.5\n PDP11.opSEV, // 0x00B2 000262 11/20+ 1.5\n PDP11.opSEx, // 0x00B3 000263 11/20+ 1.5\n PDP11.opSEZ, // 0x00B4 000264 11/20+ 1.5\n PDP11.opSEx, // 0x00B5 000265 11/20+ 1.5\n PDP11.opSEx, // 0x00B6 000266 11/20+ 1.5\n PDP11.opSEx, // 0x00B7 000267 11/20+ 1.5\n PDP11.opSEN, // 0x00B8 000270 11/20+ 1.5\n PDP11.opSEx, // 0x00B9 000271 11/20+ 1.5\n PDP11.opSEx, // 0x00BA 000272 11/20+ 1.5\n PDP11.opSEx, // 0x00BB 000273 11/20+ 1.5\n PDP11.opSEx, // 0x00BC 000274 11/20+ 1.5\n PDP11.opSEx, // 0x00BD 000275 11/20+ 1.5\n PDP11.opSEx, // 0x00BE 000276 11/20+ 1.5\n PDP11.opSEx // 0x00BF 000277 11/20+ 1.5\n];\n\nPDP11.aOp8Xnn_1120 = [\n PDP11.opBPL, // 0x80nn 1000XX 11/20+ 2.6**\n PDP11.opBMI, // 0x81nn 1004XX 11/20+ 2.6**\n PDP11.opBHI, // 0x82nn 1010XX 11/20+ 2.6**\n PDP11.opBLOS, // 0x83nn 1014XX 11/20+ 2.6**\n PDP11.opBVC, // 0x84nn 1020XX 11/20+ 2.6**\n PDP11.opBVS, // 0x85nn 1024XX 11/20+ 2.6**\n PDP11.opBCC, // 0x86nn 1030XX 11/20+ 2.6**\n PDP11.opBCS, // 0x87nn 1034XX 11/20+ 2.6**\n PDP11.opEMT, // 0x88nn 104000-104377 11/20+ 9.3\n PDP11.opTRAP, // 0x89nn 104400-104777 11/20+ 9.3\n PDP11.op8AXn_1120, // 0x8Ann\n PDP11.op8BXn_1120, // 0x8Bnn\n PDP11.op8CXn_1120, // 0x8Cnn\n PDP11.opUndefined, // 0x8Dnn\n PDP11.opUndefined, // 0x8Enn\n PDP11.opUndefined // 0x8Fnn\n];\n\nPDP11.aOp8AXn_1120 = [\n PDP11.opCLRB, // 0x8A0n 1050DD 11/20+ 2.3\n PDP11.opCOMB, // 0x8A4n 1051DD 11/20+ 2.3\n PDP11.opINCB, // 0x8A8n 1052DD 11/20+ 2.3\n PDP11.opDECB // 0x8ACn 1053DD 11/20+ 2.3\n];\n\nPDP11.aOp8BXn_1120 = [\n PDP11.opNEGB, // 0x8B0n 1054DD 11/20+ 2.3\n PDP11.opADCB, // 0x8B4n 1055DD 11/20+ 2.3\n PDP11.opSBCB, // 0x8B8n 1056DD 11/20+ 2.3\n PDP11.opTSTB // 0x8BCn 1057DD 11/20+ 2.3*\n];\n\nPDP11.aOp8CXn_1120 = [\n PDP11.opRORB, // 0x8C0n 1060DD 11/20+ 2.3*\n PDP11.opROLB, // 0x8C4n 1061DD 11/20+ 2.3*\n PDP11.opASRB, // 0x8C8n 1062DD 11/20+ 2.3*\n PDP11.opASLB // 0x8CCn 1063DD 11/20+ 2.3*\n];\n\n/**\n * op1140(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op1140 = function(opCode)\n{\n PDP11.aOpXnnn_1140[opCode >> 12].call(this, opCode);\n};\n\n/**\n * op0Xnn_1140(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op0Xnn_1140 = function(opCode)\n{\n PDP11.aOp0Xnn_1140[(opCode >> 8) & 0xf].call(this, opCode);\n};\n\n/**\n * op0DXn_1140(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op0DXn_1140 = function(opCode)\n{\n PDP11.aOp0DXn_1140[(opCode >> 6) & 0x3].call(this, opCode);\n};\n\n/**\n * op00Xn_1140(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op00Xn_1140 = function(opCode)\n{\n PDP11.aOp00Xn_1140[(opCode >> 4) & 0xf].call(this, opCode);\n};\n\n/**\n * op000X_1140(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op000X_1140 = function(opCode)\n{\n PDP11.aOp000X_1140[opCode & 0xf].call(this, opCode);\n};\n\n/**\n * op7Xnn_1140(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op7Xnn_1140 = function(opCode)\n{\n PDP11.aOp7Xnn_1140[(opCode >> 8) & 0xf].call(this, opCode);\n};\n\n/**\n * op8Xnn_1140(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op8Xnn_1140 = function(opCode)\n{\n PDP11.aOp8Xnn_1140[(opCode >> 8) & 0xf].call(this, opCode);\n};\n\n/**\n * op8DXn_1140(opCode)\n *\n * @this {CPUStatePDP11}\n * @param {number} opCode\n */\nPDP11.op8DXn_1140 = function(opCode)\n{\n if (this.model < PDP11.MODEL_1145) {\n PDP11.opUndefined.call(this, opCode);\n return;\n }\n PDP11.aOp8DXn_1140[(opCode >> 6) & 0x3].call(this, opCode);\n};\n\nPDP11.aOpXnnn_1140 = [\n PDP11.op0Xnn_1140, // 0x0nnn\n PDP11.opMOV, // 0x1nnn 01SSDD 11/20+ 2.3\n PDP11.opCMP, // 0x2nnn 02SSDD 11/20+ 2.3*\n PDP11.opBIT, // 0x3nnn 03SSDD 11/20+ 2.9*\n PDP11.opBIC, // 0x4nnn 04SSDD 11/20+ 2.9\n PDP11.opBIS, // 0x5nnn 05SSDD 11/20+ 2.3\n PDP11.opADD, // 0x6nnn 06SSDD 11/20+ 2.3\n PDP11.op7Xnn_1140, // 0x7nnn\n PDP11.op8Xnn_1140, // 0x8nnn\n PDP11.opMOVB, // 0x9nnn 11SSDD 11/20+ 2.3\n PDP11.opCMPB, // 0xAnnn 12SSDD 11/20+ 2.3\n PDP11.opBITB, // 0xBnnn 13SSDD 11/20+ 2.9\n PDP11.opBICB, // 0xCnnn 14SSDD 11/20+ 2.9\n PDP11.opBISB, // 0xDnnn 15SSDD 11/20+ 2.3\n PDP11.opSUB, // 0xEnnn 16SSDD 11/20+ 2.3\n PDP11.opUndefined // 0xFnnn\n];\n\nPDP11.aOp0Xnn_1140 = [\n PDP11.op00Xn_1140, // 0x00nn\n PDP11.opBR, // 0x01nn 0004XX 11/20+ 2.6\n PDP11.opBNE, // 0x02nn 0010XX 11/20+ 2.6**\n PDP11.opBEQ, // 0x03nn 0014XX 11/20+ 2.6**\n PDP11.opBGE, // 0x04nn 0020XX 11/20+ 2.6**\n PDP11.opBLT, // 0x05nn 0024XX 11/20+ 2.6**\n PDP11.opBGT, // 0x06nn 0030XX 11/20+ 2.6**\n PDP11.opBLE, // 0x07nn 0034XX 11/20+ 2.6**\n PDP11.opJSR, // 0x08nn 004RDD 11/20+ 4.4\n PDP11.opJSR, // 0x09nn 004RDD 11/20+ 4.4\n PDP11.op0AXn_1120, // 0x0Ann\n PDP11.op0BXn_1120, // 0x0Bnn\n PDP11.op0CXn_1120, // 0x0Cnn\n PDP11.op0DXn_1140, // 0x0Dnn\n PDP11.opUndefined, // 0x0Enn\n PDP11.opUndefined // 0x0Fnn\n];\n\nPDP11.aOp0DXn_1140 = [\n PDP11.opMARK, // 0x0D0n 11/40+ LEIS\n PDP11.opMFPI, // 0x0D4n 11/40+\n PDP11.opMTPI, // 0x0D8n 11/40+\n PDP11.opSXT // 0x0DCn 11/40+ LEIS\n];\n\nPDP11.aOp00Xn_1140 = [\n PDP11.op000X_1140, // 0x000n 000000-000017\n PDP11.opUndefined, // 0x001n 000020-000037\n PDP11.opUndefined, // 0x002n 000040-000057\n PDP11.opUndefined, // 0x003n 000060-000077\n PDP11.opJMP, // 0x004n 0001DD 11/20+ 1.2\n PDP11.opJMP, // 0x005n 0001DD 11/20+ 1.2\n PDP11.opJMP, // 0x006n 0001DD 11/20+ 1.2\n PDP11.opJMP, // 0x007n 0001DD 11/20+ 1.2\n PDP11.opRTS, // 0x008n 00020R 11/20+ 3.5 (opRTS() will also confirm that bit 3 is clear)\n PDP11.opSPL, // 0x009n 00023N 11/45+ (opSPL() will also confirm that bit 3 is set)\n PDP11.op00AX_1120, // 0x00An 000240-000257\n PDP11.op00BX_1120, // 0x00Bn 000260-000277\n PDP11.opSWAB, // 0x00Cn 0003DD 11/20+ 2.3\n PDP11.opSWAB, // 0x00Dn 0003DD 11/20+ 2.3\n PDP11.opSWAB, // 0x00En 0003DD 11/20+ 2.3\n PDP11.opSWAB // 0x00Fn 0003DD 11/20+ 2.3\n];\n\nPDP11.aOp000X_1140 = [\n PDP11.opHALT, // 0x0000 000000 11/20+ 1.8\n PDP11.opWAIT, // 0x0001 000001 11/20+ 1.8\n PDP11.opRTI, // 0x0002 000002 11/20+ 4.8\n PDP11.opBPT, // 0x0003 000003\n PDP11.opIOT, // 0x0004 000004 11/20+ 9.3\n PDP11.opRESET, // 0x0005 000005 11/20+ 20ms\n PDP11.opRTT, // 0x0006 000006 11/40+ LEIS\n PDP11.opMFPT, // 0x0007 000007 11/44+\n PDP11.opUndefined, // 0x0008\n PDP11.opUndefined, // 0x0009\n PDP11.opUndefined, // 0x000A\n PDP11.opUndefined, // 0x000B\n PDP11.opUndefined, // 0x000C\n PDP11.opUndefined, // 0x000D\n PDP11.opUndefined, // 0x000E\n PDP11.opUndefined // 0x000F\n];\n\nPDP11.aOp7Xnn_1140 = [\n PDP11.opMUL, // 0x70nn 11/40+ EIS\n PDP11.opMUL, // 0x71nn 11/40+ EIS\n PDP11.opDIV, // 0x72nn 11/40+ EIS\n PDP11.opDIV, // 0x73nn 11/40+ EIS\n PDP11.opASH, // 0x74nn 11/40+ EIS\n PDP11.opASH, // 0x75nn 11/40+ EIS\n PDP11.opASHC, // 0x76nn 11/40+ EIS\n PDP11.opASHC, // 0x77nn 11/40+ EIS\n PDP11.opXOR, // 0x78nn 11/40+ LEIS\n PDP11.opXOR, // 0x79nn 11/40+ LEIS\n PDP11.opUndefined, // 0x7Ann\n PDP11.opUndefined, // 0x7Bnn\n PDP11.opUndefined, // 0x7Cnn\n PDP11.opUndefined, // 0x7Dnn\n PDP11.opSOB, // 0x7Enn 11/40+ LEIS\n PDP11.opSOB // 0x7Fnn 11/40+ LEIS\n];\n\nPDP11.aOp8Xnn_1140 = [\n PDP11.opBPL, // 0x80nn 1000XX 11/20+ 2.6**\n PDP11.opBMI, // 0x81nn 1004XX 11/20+ 2.6**\n PDP11.opBHI, // 0x82nn 1010XX 11/20+ 2.6**\n PDP11.opBLOS, // 0x83nn 1014XX 11/20+ 2.6**\n PDP11.opBVC, // 0x84nn 1020XX 11/20+ 2.6**\n PDP11.opBVS, // 0x85nn 1024XX 11/20+ 2.6**\n PDP11.opBCC, // 0x86nn 1030XX 11/20+ 2.6**\n PDP11.opBCS, // 0x87nn 1034XX 11/20+ 2.6**\n PDP11.opEMT, // 0x88nn 104000-104377 11/20+ 9.3\n PDP11.opTRAP, // 0x89nn 104400-104777 11/20+ 9.3\n PDP11.op8AXn_1120, // 0x8Ann 1050XX\n PDP11.op8BXn_1120, // 0x8Bnn 1054XX\n PDP11.op8CXn_1120, // 0x8Cnn 1060XX\n PDP11.op8DXn_1140, // 0x8Dnn 106400-106777\n PDP11.opUndefined, // 0x8Enn 1070XX\n PDP11.opUndefined // 0x8Fnn 1074XX\n];\n\nPDP11.aOp8DXn_1140 = [\n PDP11.opMTPS, // 0x8D0n 1064XX 11/34A only\n PDP11.opMFPD, // 0x8D4n 1065XX 11/45+\n PDP11.opMTPD, // 0x8D8n 1066XX 11/45+\n PDP11.opMFPS // 0x8DCn 1067XX 11/34A only\n];\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/rom.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass ROMPDP11 extends Component {\n /**\n * ROMPDP11(parmsROM)\n *\n * The ROMPDP11 component expects the following (parmsROM) properties:\n *\n * addr: physical address of ROM\n * size: amount of ROM, in bytes\n * alias: physical alias address (null if none)\n * file: name of ROM data file\n *\n * NOTE: The ROM data will not be copied into place until the Bus is ready (see initBus()) AND\n * the ROM data file has finished loading (see finishLoad()).\n *\n * Also, while the size parameter may seem redundant, I consider it useful to confirm that the ROM\n * you received is the ROM you expected.\n *\n * @param {Object} parmsROM\n */\n constructor(parmsROM)\n {\n super(\"ROM\", parmsROM, MessagesPDP11.ROM);\n\n this.abInit = null;\n this.aSymbols = null;\n\n this.addrROM = +parmsROM['addr'];\n this.sizeROM = +parmsROM['size'];\n this.fRetainROM = false;\n\n /*\n * The new 'alias' property can now be EITHER a single physical address (like 'addr') OR an array of\n * physical addresses; eg:\n *\n * [0xf0000,0xffff0000,0xffff8000]\n *\n * We could have overloaded 'addr' to accomplish the same thing, but I think it's better to have any\n * aliased locations listed under a separate property.\n *\n * Most ROMs are not aliased, in which case the 'alias' property should have the default value of null.\n */\n this.addrAlias = parmsROM['alias'];\n if (typeof this.addrAlias == \"string\") {\n this.addrAlias = eval(this.addrAlias);\n }\n\n this.sFilePath = parmsROM['file'];\n this.sFileName = Str.getBaseName(this.sFilePath);\n\n if (this.sFilePath) {\n var sFileURL = this.sFilePath;\n if (DEBUG) this.log('load(\"' + sFileURL + '\")');\n /*\n * If the selected ROM file has a \".json\" extension, then we assume it's pre-converted\n * JSON-encoded ROM data, so we load it as-is; ditto for ROM files with a \".hex\" extension.\n * Otherwise, we ask our server-side ROM converter to return the file in a JSON-compatible format.\n */\n var sFileExt = Str.getExtension(this.sFileName);\n if (sFileExt != DumpAPI.FORMAT.JSON && sFileExt != DumpAPI.FORMAT.HEX) {\n sFileURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFilePath + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES + '&' + DumpAPI.QUERY.DECIMAL + '=true';\n }\n var rom = this;\n Web.getResource(sFileURL, null, true, function doneLoad(sURL, sResponse, nErrorCode) {\n rom.finishLoad(sURL, sResponse, nErrorCode);\n });\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {ROMPDP11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.initROM();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {ROMPDP11}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (this.aSymbols) {\n if (this.dbg) {\n this.dbg.addSymbols(this.id, this.addrROM, this.sizeROM, this.aSymbols);\n }\n /*\n * Our only role in the handling of symbols is to hand them off to the Debugger at our\n * first opportunity. Now that we've done that, our copy of the symbols, if any, are toast.\n */\n delete this.aSymbols;\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * Since we have nothing to do on powerDown(), and no state to return, we could simply omit\n * this function. But it doesn't hurt anything, and maybe we'll use our state to save something\n * useful down the road, like user-defined symbols (ie, symbols that the Debugger may have\n * created, above and beyond those symbols we automatically loaded, if any, along with the ROM).\n *\n * @this {ROMPDP11}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return true;\n }\n\n /**\n * finishLoad(sURL, sData, nErrorCode)\n *\n * @this {ROMPDP11}\n * @param {string} sURL\n * @param {string} sData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n finishLoad(sURL, sData, nErrorCode)\n {\n if (nErrorCode) {\n this.notice(\"Unable to load ROM resource (error \" + nErrorCode + \": \" + sURL + \")\");\n this.sFilePath = null;\n }\n else {\n Component.addMachineResource(this.idMachine, sURL, sData);\n var resource = Web.parseMemoryResource(sURL, sData);\n if (resource) {\n this.abInit = resource.aBytes;\n this.aSymbols = resource.aSymbols;\n } else {\n this.sFilePath = null;\n }\n }\n this.initROM();\n }\n\n /**\n * initROM()\n *\n * This function is called by both initBus() and finishLoad(), but it cannot copy the initial data into place\n * until after initBus() has received the Bus component AND finishLoad() has received the data. When both those\n * criteria are satisfied, the component becomes \"ready\".\n *\n * @this {ROMPDP11}\n */\n initROM()\n {\n if (!this.isReady()) {\n if (this.sFilePath) {\n /*\n * Too early...\n */\n if (!this.abInit || !this.bus) return;\n\n /*\n * If no explicit size was specified, then use whatever the actual size is.\n */\n if (!this.sizeROM) {\n this.sizeROM = this.abInit.length;\n }\n if (this.abInit.length != this.sizeROM) {\n /*\n * Note that setError() sets the component's fError flag, which in turn prevents setReady() from\n * marking the component ready. TODO: Revisit this decision. On the one hand, it sounds like a\n * good idea to stop the machine in its tracks whenever a setError() occurs, but there may also be\n * times when we'd like to forge ahead anyway.\n */\n this.setError(\"ROM size (\" + Str.toHexLong(this.abInit.length) + \") does not match specified size (\" + Str.toHexLong(this.sizeROM) + \")\");\n }\n else if (this.addROM(this.addrROM)) {\n\n var aliases = [];\n if (typeof this.addrAlias == \"number\") {\n aliases.push(this.addrAlias);\n } else if (this.addrAlias != null && this.addrAlias.length) {\n aliases = this.addrAlias;\n }\n for (var i = 0; i < aliases.length; i++) {\n this.cloneROM(aliases[i]);\n }\n /*\n * We used to hang onto the initial ROM data so that we could restore any bytes the CPU overwrote,\n * using memory write-notification handlers, but with the introduction of read-only memory blocks, that's\n * no longer necessary.\n *\n * TODO: Consider an option to retain the ROM data, and give the user some way of restoring ROMs.\n * That may be useful for \"resumable\" machines that save/restore all dirty block of memory, regardless\n * whether they're ROM or RAM. However, the only way to modify a machine's ROM is with the Debugger,\n * and Debugger users should know better.\n */\n if (!this.fRetainROM) {\n delete this.abInit;\n }\n }\n }\n this.setReady();\n }\n }\n\n /**\n * addROM(addr)\n *\n * @this {ROMPDP11}\n * @param {number} addr\n * @return {boolean}\n */\n addROM(addr)\n {\n if (addr >= BusPDP11.IOPAGE_16BIT && addr < BusPDP11.IOPAGE_16BIT + BusPDP11.IOPAGE_LENGTH) {\n /*\n * This code has been added as a work-around to effectively allow us to install small ROMs into portions\n * of the IOPAGE address space, by installing I/O handlers for the entire range that return the corresponding\n * bytes of the current ROM image on reads, and ignore any writes (which I'm only assuming is how a typical\n * ROM \"device\" deals with writes; we could remove the write handler, but then writes would fault).\n *\n * TODO: It would be more efficient if we parsed ROM data as words rather than bytes, and then installed\n * only word handlers instead of only byte handlers. It was done this way purely for historical reasons (ie,\n * because that's how other PCjs machines parse their ROMs). For now, all this means is that executing code\n * out of ROM will be slower than out of RAM -- although that's often true in the real world as well.\n */\n var IOTable = {\n [addr]: [ROMPDP11.prototype.readROMByte, ROMPDP11.prototype.writeROMByte, null, null, null, this.sizeROM >> 1]\n };\n if (this.bus.addIOTable(this, IOTable)) {\n this.status(\"Added \" + this.sizeROM + \"-byte ROM at \" + Str.toOct(addr));\n this.fRetainROM = true;\n return true;\n }\n }\n else if (this.bus.addMemory(addr, this.sizeROM, MemoryPDP11.TYPE.ROM)) {\n if (DEBUG) this.log(\"addROM(): copying ROM to \" + Str.toHexLong(addr) + \" (\" + Str.toHexLong(this.abInit.length) + \" bytes)\");\n var i;\n for (i = 0; i < this.abInit.length; i++) {\n this.bus.setByteDirect(addr + i, this.abInit[i]);\n }\n return true;\n }\n\n /*\n * We don't need to report an error here, because addMemory() already takes care of that.\n */\n return false;\n }\n\n /**\n * cloneROM(addr)\n *\n * For ROMs with one or more alias addresses, we used to call addROM() for each address. However,\n * that obviously wasted memory, since each alias was an independent copy, and if you used the\n * Debugger to edit the ROM in one location, the changes would not appear in the other location(s).\n *\n * Now that the Bus component provides low-level getMemoryBlocks() and setMemoryBlocks() methods\n * to manually get and set the blocks of any memory range, it is now possible to create true aliases.\n *\n * @this {ROMPDP11}\n * @param {number} addr\n */\n cloneROM(addr)\n {\n var aBlocks = this.bus.getMemoryBlocks(this.addrROM, this.sizeROM);\n this.bus.setMemoryBlocks(addr, this.sizeROM, aBlocks);\n }\n\n /**\n * readROMByte(addr)\n *\n * @this {ROMPDP11}\n * @param {number} addr\n * @return {number}\n */\n readROMByte(addr)\n {\n var i = (addr - this.addrROM);\n return this.abInit[i];\n }\n\n /**\n * writeROMByte(data, addr)\n *\n * This handler exists simply to ignore any writes, so that they don't cause faults.\n *\n * TODO: Another possible use for this would be to allow the Debugger to alter ROM contents,\n * if the Debugger were to provide an interface indicating whether or not it was responsible\n * for this write.\n *\n * @this {ROMPDP11}\n * @param {number} data\n * @param {number} addr\n */\n writeROMByte(data, addr)\n {\n }\n\n /**\n * ROMPDP11.init()\n *\n * This function operates on every HTML element of class \"rom\", extracting the\n * JSON-encoded parameters for the ROMPDP11 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a ROMPDP11 component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeROM = Component.getElementsByClass(document, PDP11.APPCLASS, \"rom\");\n for (var iROM = 0; iROM < aeROM.length; iROM++) {\n var eROM = aeROM[iROM];\n var parmsROM = Component.getComponentParms(eROM);\n var rom = new ROMPDP11(parmsROM);\n Component.bindComponentControls(rom, eROM, PDP11.APPCLASS);\n }\n }\n}\n\n/*\n * NOTE: There's currently no need for this component to have a reset() function, since\n * once the ROM data is loaded, it can't be changed, so there's nothing to reinitialize.\n *\n * OK, well, I take that back, because the Debugger, if installed, has the ability to modify\n * ROM contents, so in that case, having a reset() function that restores the original ROM data\n * might be useful; then again, it might not, depending on what you're trying to debug.\n *\n * If we do add reset(), then we'll want to change initROM() to hang onto the original\n * ROM data; currently, we release it after copying it into the read-only memory allocated\n * via bus.addMemory().\n */\n\n/*\n * Initialize all the ROMPDP11 modules on the page.\n */\nWeb.onInit(ROMPDP11.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/ram.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass RAMPDP11 extends Component {\n /**\n * RAMPDP11(parmsRAM)\n *\n * The RAMPDP11 component expects the following (parmsRAM) properties:\n *\n * addr: starting physical address of RAM (default is 0)\n * size: amount of RAM, in bytes (default is 0, which means defer to motherboard switch settings)\n * file: name of optional data file to load into RAM (default is \"\")\n * load: optional file load address (overrides any load address specified in the data file; default is null)\n * exec: optional file exec address (overrides any exec address specified in the data file; default is null)\n *\n * NOTE: We make a note of the specified size, but no memory is initially allocated for the RAM until the\n * Computer component calls powerUp().\n *\n * TODO: I seem to recall a PDP-11 diagnostic that failed if total RAM wasn't a multiple of 16Kb; our Bus\n * component defaults to a block size that matches BusPDP11.IOPAGE_LENGTH (ie, 8Kb), and we even allow partial\n * block allocations, so internally, we don't have that requirement, but for better compatibility, perhaps we\n * should display a non-fatal warning if addr or size don't fall on 16Kb boundaries.\n *\n * @param {Object} parmsRAM\n */\n constructor(parmsRAM)\n {\n super(\"RAM\", parmsRAM);\n\n this.abInit = null;\n this.aSymbols = null;\n\n this.addrRAM = +parmsRAM['addr'];\n this.sizeRAM = +parmsRAM['size'];\n\n this.addrLoad = parmsRAM['load'];\n this.addrExec = parmsRAM['exec'];\n if (this.addrLoad != null) this.addrLoad = +this.addrLoad;\n if (this.addrExec != null) this.addrExec = +this.addrExec;\n\n this.fInstalled = (!!this.sizeRAM); // 0 is the default value for 'size' when none is specified\n this.fAllocated = this.fReset = false;\n\n this.sFilePath = parmsRAM['file'];\n this.sFileName = Str.getBaseName(this.sFilePath);\n\n if (this.sFilePath) {\n var sFileURL = this.sFilePath;\n if (DEBUG) this.log('load(\"' + sFileURL + '\")');\n /*\n * If the selected data file has a \".json\" extension, then we assume it's pre-converted\n * JSON-encoded data, so we load it as-is; ditto for ROM files with a \".hex\" extension.\n * Otherwise, we ask our server-side converter to return the file in a JSON-compatible format.\n */\n var sFileExt = Str.getExtension(this.sFileName);\n if (sFileExt != DumpAPI.FORMAT.JSON && sFileExt != DumpAPI.FORMAT.HEX) {\n sFileURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + DumpAPI.QUERY.FILE + '=' + this.sFilePath + '&' + DumpAPI.QUERY.FORMAT + '=' + DumpAPI.FORMAT.BYTES + '&' + DumpAPI.QUERY.DECIMAL + '=true';\n }\n var ram = this;\n Web.getResource(sFileURL, null, true, function doneLoad(sURL, sResponse, nErrorCode) {\n ram.finishLoad(sURL, sResponse, nErrorCode);\n });\n }\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {RAMPDP11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.initRAM();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {RAMPDP11}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (this.aSymbols) {\n if (this.dbg) {\n this.dbg.addSymbols(this.id, this.addrRAM, this.sizeRAM, this.aSymbols);\n }\n /*\n * Our only role in the handling of symbols is to hand them off to the Debugger at our\n * first opportunity. Now that we've done that, our copy of the symbols, if any, are toast.\n */\n delete this.aSymbols;\n }\n if (!fRepower) {\n /*\n * Since we use the Bus to allocate all our memory, memory contents are already restored for us,\n * so we don't save any state, and therefore no state should be restored. Just do a reset().\n */\n\n this.reset();\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {RAMPDP11}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n /*\n * The Computer powers down the CPU first, at which point CPUState state is saved,\n * which includes the Bus state, and since we use the Bus component to allocate all\n * our memory, memory contents are already saved for us, so we don't need the usual\n * save logic.\n */\n return true;\n }\n\n /**\n * finishLoad(sURL, sData, nErrorCode)\n *\n * @this {RAMPDP11}\n * @param {string} sURL\n * @param {string} sData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n finishLoad(sURL, sData, nErrorCode)\n {\n if (nErrorCode) {\n this.notice(\"Unable to load RAM resource (error \" + nErrorCode + \": \" + sURL + \")\");\n this.sFilePath = null;\n }\n else {\n Component.addMachineResource(this.idMachine, sURL, sData);\n var resource = Web.parseMemoryResource(sURL, sData);\n if (resource) {\n this.abInit = resource.aBytes;\n this.aSymbols = resource.aSymbols;\n if (this.addrLoad == null) this.addrLoad = resource.addrLoad;\n if (this.addrExec == null) this.addrExec = resource.addrExec;\n } else {\n this.sFilePath = null;\n }\n }\n this.initRAM();\n }\n\n /**\n * initRAM()\n *\n * This function is called by both initBus() and finishLoad(), but it cannot copy the initial data into place\n * until after initBus() has received the Bus component AND finishLoad() has received the data. When both those\n * criteria are satisfied, the component becomes \"ready\".\n *\n * @this {RAMPDP11}\n */\n initRAM()\n {\n if (!this.bus) return;\n\n if (!this.fAllocated && this.sizeRAM) {\n if (this.bus.addMemory(this.addrRAM, this.sizeRAM, MemoryPDP11.TYPE.RAM)) {\n this.fAllocated = true;\n } else {\n this.sizeRAM = 0; // don't bother trying again (it just results in redundant error messages)\n }\n }\n if (!this.isReady()) {\n if (!this.fAllocated) {\n Component.error(\"No RAM allocated\");\n }\n else if (this.sFilePath) {\n /*\n * Too early...\n */\n if (!this.abInit) return;\n\n if (this.loadImage(this.abInit, this.addrLoad, this.addrExec, this.addrRAM)) {\n this.status('Loaded image \"' + this.sFileName + '\"');\n } else {\n this.notice('Error loading image \"' + this.sFileName + '\"');\n }\n\n /*\n * NOTE: We now retain this data, so that reset() can return the RAM to its predefined state.\n *\n * delete this.abInit;\n */\n }\n this.fReset = true;\n this.setReady();\n }\n }\n\n /**\n * reset()\n *\n * @this {RAMPDP11}\n */\n reset()\n {\n if (this.fAllocated && !this.fReset) {\n /*\n * TODO: Add a configuration parameter for selecting the byte pattern on reset?\n * Note that when memory blocks are originally created, they are currently always\n * zero-initialized, so this would only affect resets.\n */\n this.bus.zeroMemory(this.addrRAM, this.sizeRAM, 0);\n if (this.abInit) {\n this.loadImage(this.abInit, this.addrLoad, this.addrExec, this.addrRAM, !this.dbg);\n }\n }\n this.fReset = false;\n }\n\n /**\n * loadImage(aBytes, addrLoad, addrExec, addrInit, fStart)\n *\n * If the array contains a PAPER tape image in the \"Absolute Format,\" load it as specified\n * by the format; otherwise, load it as-is using the address(es) supplied.\n *\n * @this {RAMPDP11}\n * @param {Array|Uint8Array} aBytes\n * @param {number|null} [addrLoad]\n * @param {number|null} [addrExec] (this CAN override any starting address INSIDE the image)\n * @param {number|null} [addrInit]\n * @param {boolean} [fStart]\n * @return {boolean} (true if loaded, false if not)\n */\n loadImage(aBytes, addrLoad, addrExec, addrInit, fStart)\n {\n var fStop = false;\n var fLoaded = false;\n /*\n * Data on tapes in the \"Absolute Format\" is organized into blocks; each block begins with\n * a 6-byte header:\n *\n * 2-byte signature (0x0001)\n * 2-byte block length (N + 6, because it includes the 6-byte header)\n * 2-byte load address\n *\n * followed by N data bytes. If N is zero, then the 2-byte load address is the exec address,\n * unless the address is odd (usually 1). DEC's Absolute Loader jumps to the exec address\n * in former case, halts in the latter.\n *\n * All values are stored \"little endian\" (low byte followed by high byte), just like the\n * PDP-11's memory architecture.\n *\n * After the data bytes, there is a single checksum byte. The 8-bit sum of all the bytes in\n * the block (including the header bytes and checksum byte) should be zero.\n *\n * ANOMALIES: Tape files don't always begin with a signature word, so I allow any number of\n * leading zeros before the first signature. Tape files don't always end cleanly either, so as\n * soon as I see an invalid signature, I break out of the loop without signalling an error, as\n * long as at least ONE block was successfully processed. In fact, it's possible that as\n * soon as a block with ZERO data bytes is encountered, processing is supposed to stop, but\n * I haven't examined enough tapes (or the Absolute Loader code) to know for sure.\n */\n if (addrLoad == null) {\n var off = 0, fError = false;\n while (off < aBytes.length - 1) {\n var w = (aBytes[off] & 0xff) | ((aBytes[off+1] & 0xff) << 8);\n if (!w) { // ignore pairs of leading zeros\n off += 2;\n continue;\n }\n if (!(w & 0xff)) { // as well as single bytes of zero\n off++;\n continue;\n }\n var offBlock = off;\n if (w != 0x0001) {\n this.printMessage(\"invalid signature (\" + Str.toHexWord(w) + \") at offset \" + Str.toHexWord(offBlock), MessagesPDP11.PAPER);\n break;\n }\n if (off + 6 >= aBytes.length) {\n this.printMessage(\"invalid block at offset \" + Str.toHexWord(offBlock), MessagesPDP11.PAPER);\n break;\n }\n off += 2;\n var checksum = w;\n var len = (aBytes[off++] & 0xff) | ((aBytes[off++] & 0xff) << 8);\n var addr = (aBytes[off++] & 0xff) | ((aBytes[off++] & 0xff) << 8);\n checksum += (len & 0xff) + (len >> 8) + (addr & 0xff) + (addr >> 8);\n var offData = off, cbData = len -= 6;\n while (len > 0 && off < aBytes.length) {\n checksum += aBytes[off++] & 0xff;\n len--;\n }\n if (len != 0 || off >= aBytes.length) {\n this.printMessage(\"insufficient data for block at offset \" + Str.toHexWord(offBlock), MessagesPDP11.PAPER);\n break;\n }\n checksum += aBytes[off++] & 0xff;\n if (checksum & 0xff) {\n this.printMessage(\"invalid checksum (\" + Str.toHexByte(checksum) + \") for block at offset \" + Str.toHexWord(offBlock), MessagesPDP11.PAPER);\n break;\n }\n if (!cbData) {\n if (addr & 0x1) {\n fStop = true;\n } else {\n if (addrExec == null) addrExec = addr;\n }\n if (addrExec != null) this.printMessage(\"starting address: \" + Str.toHexWord(addrExec), MessagesPDP11.PAPER);\n } else {\n this.printMessage(\"loading \" + Str.toHexWord(cbData) + \" bytes at \" + Str.toHexWord(addr) + \"-\" + Str.toHexWord(addr + cbData), MessagesPDP11.PAPER);\n while (cbData--) {\n this.bus.setByteDirect(addr++, aBytes[offData++] & 0xff);\n }\n }\n fLoaded = true;\n }\n }\n if (!fLoaded) {\n if (addrLoad == null) addrLoad = addrInit;\n if (addrLoad != null) {\n for (var i = 0; i < aBytes.length; i++) {\n this.bus.setByteDirect(addrLoad + i, aBytes[i]);\n }\n fLoaded = true;\n }\n }\n if (fLoaded) {\n /*\n * Set the start address to whatever the caller provided, or failing that, whatever start\n * address was specified inside the image.\n *\n * For example, the diagnostic \"MAINDEC-11-D0AA-PB\" doesn't include a start address inside the\n * image, but we know that the directions for that diagnostic say to \"Start and Restart at 200\",\n * so we have manually inserted an \"exec\":128 in the JSON containing the image.\n */\n if (addrExec == null || fStop) {\n this.cpu.stopCPU();\n fStart = false;\n }\n if (addrExec != null) {\n this.cpu.setReset(addrExec, fStart);\n }\n }\n return fLoaded;\n }\n\n /**\n * RAMPDP11.init()\n *\n * This function operates on every HTML element of class \"ram\", extracting the\n * JSON-encoded parameters for the RAMPDP11 constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a RAMPDP11 component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeRAM = Component.getElementsByClass(document, PDP11.APPCLASS, \"ram\");\n for (var iRAM = 0; iRAM < aeRAM.length; iRAM++) {\n var eRAM = aeRAM[iRAM];\n var parmsRAM = Component.getComponentParms(eRAM);\n var ram = new RAMPDP11(parmsRAM);\n Component.bindComponentControls(ram, eRAM, PDP11.APPCLASS);\n }\n }\n}\n\n/*\n * Initialize all the RAMPDP11 modules on the page.\n */\nWeb.onInit(RAMPDP11.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/keyboard.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass KeyboardPDP11 extends Component {\n /**\n * KeyboardPDP11(parmsKbd)\n *\n * @param {Object} parmsKbd\n */\n constructor(parmsKbd)\n {\n super(\"Keyboard\", parmsKbd, MessagesPDP11.KEYBOARD);\n\n this.setReady();\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {KeyboardPDP11}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"esc\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {KeyboardPDP11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.cpu = cpu;\n this.dbg = dbg; // NOTE: The \"dbg\" property must be set for the message functions to work\n }\n\n /**\n * KeyboardPDP11.init()\n *\n * This function operates on every HTML element of class \"keyboard\", extracting the\n * JSON-encoded parameters for the Keyboard constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Keyboard component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeKbd = Component.getElementsByClass(document, PDP11.APPCLASS, \"keyboard\");\n for (var iKbd = 0; iKbd < aeKbd.length; iKbd++) {\n var eKbd = aeKbd[iKbd];\n var parmsKbd = Component.getComponentParms(eKbd);\n var kbd = new KeyboardPDP11(parmsKbd);\n Component.bindComponentControls(kbd, eKbd, PDP11.APPCLASS);\n }\n }\n}\n\nKeyboardPDP11.MINPRESSTIME = 100; // 100ms\n\n/*\n * Initialize every Keyboard module on the page.\n */\nWeb.onInit(KeyboardPDP11.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/serial.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * Component class, because otherwise the Compiler won't allow us to *reference* the named\n * property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass SerialPortPDP11 extends Component {\n /**\n * SerialPortPDP11(parmsSerial)\n *\n * The SerialPort component has the following component-specific (parmsSerial) properties:\n *\n * adapter: adapter number; 0 if not defined (the PCx86 SerialPort component uses this\n * value to set the device's internal COM number, which in turn determines other properties,\n * such as I/O ports and IRQ; for the PDP-11, this currently has no defined use)\n *\n * baudReceive: the default number of bits/second that the device should receive data at;\n * 0 means use the device default (PDP11.DL11.RCSR.BAUD)\n *\n * baudTransmit: the default number of bits/second that the device should transmit data at;\n * 0 means use the device default (PDP11.DL11.XCSR.BAUD)\n *\n * binding: name of a control (based on its \"binding\" attribute) to bind to this port's I/O\n *\n * tabSize: set to a non-zero number to convert tabs to spaces (applies only to output to\n * the above binding); default is 0 (no conversion)\n *\n * upperCase: if true, all received input is upper-cased; it is normally the responsibility\n * of the sending device to ensure this, but sometimes it's more convenient to enforce\n * on the receiving end.\n *\n * NOTE: Since the XSL file defines the 'adapter' and 'baud' properties as numbers, not strings,\n * there's no need to use parseInt(), and as an added benefit, we don't need to worry about whether\n * a hex or decimal format was used.\n *\n * @param {Object} parmsSerial\n */\n constructor(parmsSerial)\n {\n super(\"SerialPort\", parmsSerial, MessagesPDP11.SERIAL);\n\n this.iAdapter = +parmsSerial['adapter'];\n this.nBaudReceive = +parmsSerial['baudReceive'] || PDP11.DL11.RCSR.BAUD;\n this.nBaudTransmit = +parmsSerial['baudTransmit'] || PDP11.DL11.XCSR.BAUD;\n this.fUpperCase = parmsSerial['upperCase'];\n if (typeof this.fUpperCase == \"string\") this.fUpperCase = (this.fUpperCase == \"true\");\n /**\n * consoleBuffer becomes a string that records serial port output if the 'binding' property is set to the\n * reserved name \"console\". Nothing is written to the console, however, until a linefeed (0x0A) is output\n * or the string length reaches a threshold (currently, 1024 characters).\n *\n * @type {string|null}\n */\n this.consoleBuffer = null;\n\n /**\n * controlBuffer is a DOM element bound to the port (currently used for output only; see transmitByte()).\n *\n * Example: CTTY COM2\n *\n * The CTTY DOS command redirects all CON I/O to the specified serial port (eg, COM2), which it assumes is\n * connected to a serial terminal, and therefore anything it *transmits* via COM2 will be displayed by the\n * terminal. It further assumes that anything typed on such a terminal is NOT displayed, so as DOS *receives*\n * serial input, DOS *transmits* the appropriate characters back to the terminal via COM2.\n *\n * As a result, controlBuffer only needs to be updated by the transmitByte() function.\n *\n * @type {Object}\n */\n this.controlBuffer = null;\n\n /*\n * If controlBuffer is being used AND 'tabSize' is set, then we make an attempt to monitor the characters\n * being echoed via transmitByte(), maintain a logical column position, and convert any tabs into the appropriate\n * number of spaces.\n *\n * charBOL, if nonzero, is a character to automatically output at the beginning of every line. This probably\n * isn't generally useful; I use it internally to preformat serial output.\n */\n this.tabSize = +parmsSerial['tabSize'];\n this.charBOL = +parmsSerial['charBOL'];\n this.iLogicalCol = 0;\n this.fNullModem = true;\n\n this.irqReceiver = this.irqTransmitter = null;\n this.timerReceiveInterrupt = this.timerTransmitInterrupt = -1;\n\n this.regRBUF = this.regRCSR = this.regXCSR = 0;\n this.abReceive = [];\n\n var sBinding = parmsSerial['binding'];\n if (sBinding == \"console\") {\n this.consoleBuffer = \"\";\n } else {\n /*\n * If the SerialPort wants to bind to a control (eg, \"print\") in a DIFFERENT component (eg, \"Panel\"),\n * then it specifies the name of that control with the 'binding' property. The SerialPort constructor\n * will then call bindExternalControl(), which looks up the control, and then passes it to our own\n * setBinding() handler.\n * \n * For bindExternalControl() to succeed, it also need to know the target component; for now, that's\n * been hard-coded to \"Panel\", in part because that's one of the few components we can rely upon\n * initializing before we do, but it would be a simple matter to include a component type or ID as part\n * of the 'binding' property as well, if we need more flexibility later.\n * \n * NOTE: If sBinding is not the name of a valid Control Panel DOM element, this call does nothing.\n */\n Component.bindExternalControl(this, sBinding);\n }\n\n /*\n * No connection until initConnection() is called.\n */\n this.sDataReceived = \"\";\n this.connection = this.sendData = this.updateStatus = null;\n\n /*\n * Export all functions required by initConnection().\n */\n this['exports'] = {\n 'connect': this.initConnection,\n 'receiveData': this.receiveData,\n 'receiveStatus': this.receiveStatus,\n 'setConnection': this.setConnection\n };\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {SerialPortPDP11}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"buffer\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n if (!sHTMLType || sHTMLType == \"textarea\") {\n\n var serial = this;\n this.bindings[sBinding] = this.controlBuffer = control;\n\n /*\n * An onkeydown handler is required for certain keys that browsers tend to consume themselves;\n * for example, BACKSPACE is often defined as going back to the previous web page, and certain\n * CTRL keys are often used for browser shortcuts (usually on Windows-based browsers).\n *\n * NOTE: We don't bother with a keyUp handler, because for the most part, we're only intercepting\n * keys that require special treatment; in general, we're content with keyPress events.\n */\n control.onkeydown = function onKeyDown(event) {\n event = event || window.event;\n var bASCII = 0;\n var keyCode = event.keyCode;\n /*\n * Perform the same remapping of BACKSPACE and DELETE that our VT100 emulation performs,\n * for PCjs-wide consistency; see the KEYMAP table in /modules/pc8080/lib/keyboard.js for\n * the rationale. Ditto for ALT-DELETE; see onKeyDown() in /modules/pc8080/lib/keyboard.js\n * for details.\n *\n * NOTE: keyDown (and keyUp) events supply us with KEYCODE values, which are NOT the same as\n * ASCII values, which is why we are comparing with KEYCODE values but assigning ASCII values,\n * because receiveData() requires ASCII values.\n */\n if (keyCode == Keys.KEYCODE.BS) {\n bASCII = event.altKey? Keys.ASCII.CTRL_H : Keys.ASCII.DEL;\n }\n else if (keyCode == Keys.KEYCODE.DEL) {\n bASCII = Keys.ASCII.CTRL_H;\n }\n else if (event.ctrlKey && keyCode >= Keys.ASCII.A && keyCode <= Keys.ASCII.Z) {\n bASCII = keyCode - (Keys.ASCII.A - Keys.ASCII.CTRL_A);\n }\n if (bASCII) {\n if (event.preventDefault) event.preventDefault();\n serial.receiveData(bASCII);\n }\n return true;\n };\n\n control.onkeypress = function onKeyPress(event) {\n /*\n * NOTE: Unlike keyDown events, keyPress events generally supply us with ASCII values,\n * despite the fact that, as above, they come to us via the keyCode property. Yes, it's\n * brilliant (or rather, the opposite of brilliant), but that's life.\n */\n event = event || window.event;\n /*\n * Not sure why COMMAND-key combinations are coming through here (on Safari at least),\n * but in any case, let's make sure we don't act on them.\n */\n if (!event.metaKey) {\n var bASCII = event.which || event.keyCode;\n /*\n * Perform the same remapping of ALT-ENTER (to LINE-FEED) that our VT100 emulation performs,\n * for PCjs-wide consistency; see onKeyDown() in /modules/pc8080/lib/keyboard.js for details.\n */\n if (event.altKey) {\n if (bASCII == Keys.ASCII.CTRL_M) {\n bASCII = Keys.ASCII.CTRL_J;\n }\n }\n serial.receiveData(bASCII);\n /*\n * Since we're going to remove the \"readonly\" attribute from the <textarea> control\n * (so that the soft keyboard activates on iOS), instead of calling preventDefault() for\n * selected keys (eg, the SPACE key, whose default behavior is to scroll the page), we must\n * now call it for *all* keys, so that the keyCode isn't added to the control immediately,\n * on top of whatever the machine is echoing back, resulting in double characters.\n */\n if (event.preventDefault) event.preventDefault();\n }\n return true;\n };\n\n control.onpaste = function onKeyPress(event) {\n if (event.stopPropagation) event.stopPropagation();\n if (event.preventDefault) event.preventDefault();\n var clipboardData = event.clipboardData || window.clipboardData;\n if (clipboardData) {\n /*\n * NOTE: Multiple lines of pasted text will (at least on macOS) contain LFs instead of CRs;\n * this is dealt with in receiveData() whenever it receives a string of characters.\n */\n serial.receiveData(clipboardData.getData('Text'));\n }\n };\n\n /*\n * Now that we've added an onkeypress handler that calls preventDefault() for ALL keys, the control\n * itself no longer needs the \"readonly\" attribute; we primarily need to remove it for iOS browsers,\n * so that the soft keyboard will activate, but it shouldn't hurt to remove the attribute for all browsers.\n */\n control.removeAttribute(\"readonly\");\n\n return true;\n }\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {SerialPortPDP11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n var serial = this;\n\n this.irqReceiver = this.cpu.addIRQ(this.iAdapter? -1 : PDP11.DL11.RVEC, PDP11.DL11.PRI, MessagesPDP11.DL11);\n\n this.timerReceiveInterrupt = this.cpu.addTimer(function readyReceiver() {\n var b = serial.receiveByte();\n if (b >= 0) {\n serial.regRBUF = b;\n if (!(serial.regRCSR & PDP11.DL11.RCSR.RD)) {\n serial.regRCSR |= PDP11.DL11.RCSR.RD;\n } else {\n serial.regRBUF |= PDP11.DL11.RBUF.OE | PDP11.DL11.RBUF.ERROR;\n }\n if (serial.regRCSR & PDP11.DL11.RCSR.RIE) {\n cpu.setIRQ(serial.irqReceiver);\n }\n }\n });\n\n this.irqTransmitter = this.cpu.addIRQ(this.iAdapter? -1 : PDP11.DL11.XVEC, PDP11.DL11.PRI, MessagesPDP11.DL11);\n\n this.timerTransmitInterrupt = this.cpu.addTimer(function readyTransmitter() {\n serial.regXCSR |= PDP11.DL11.XCSR.READY;\n if (serial.regXCSR & PDP11.DL11.XCSR.TIE) {\n cpu.setIRQ(serial.irqTransmitter);\n }\n });\n\n bus.addIOTable(this, SerialPortPDP11.UNIBUS_IOTABLE, this.iAdapter? ((PDP11.UNIBUS.DL11 + (this.iAdapter - 1) * 8) - PDP11.UNIBUS.RCSR) : 0);\n bus.addResetHandler(this.reset.bind(this));\n\n this.setReady();\n }\n\n /**\n * initConnection(fNullModem)\n *\n * If a machine 'connection' parameter exists of the form \"{sourcePort}->{targetMachine}.{targetPort}\",\n * and \"{sourcePort}\" matches our idComponent, then look for a component with id \"{targetMachine}.{targetPort}\".\n *\n * If the target component is found, then verify that it has exported functions with the following names:\n *\n * receiveData(data): called when we have data to transmit; aliased internally to sendData(data)\n * receiveStatus(pins): called when our control signals have changed; aliased internally to updateStatus(pins)\n *\n * For now, we're not going to worry about communication in the other direction, because when the target component\n * performs its own initConnection(), it will find our receiveData() and receiveStatus() functions, at which point\n * communication in both directions should be established, and the circle of life complete.\n *\n * For added robustness, if the target machine initializes much more slowly than we do, and our connection attempt\n * fails, that's OK, because when it finally initializes, its initConnection() will call our initConnection();\n * if we've already initialized, no harm done.\n *\n * @this {SerialPortPDP11}\n * @param {boolean} [fNullModem] (caller's null-modem setting, to ensure our settings are in agreement)\n */\n initConnection(fNullModem)\n {\n if (!this.connection) {\n var sConnection = this.cmp.getMachineParm(\"connection\");\n if (sConnection) {\n var asParts = sConnection.split('->');\n if (asParts.length == 2) {\n var sSourceID = Str.trim(asParts[0]);\n if (sSourceID != this.idComponent) return; // this connection string is intended for another instance\n var sTargetID = Str.trim(asParts[1]);\n this.connection = Component.getComponentByID(sTargetID);\n if (this.connection) {\n var exports = this.connection['exports'];\n if (exports) {\n var fnConnect = /** @function */ (exports['connect']);\n if (fnConnect) fnConnect.call(this.connection, this.fNullModem);\n this.sendData = exports['receiveData'];\n if (this.sendData) {\n this.fNullModem = fNullModem;\n this.updateStatus = exports['receiveStatus'];\n this.status(\"Connected \" + this.idMachine + '.' + sSourceID + \" to \" + sTargetID);\n return;\n }\n }\n }\n }\n /*\n * Changed from notice() to status() because sometimes a connection fails simply because one of us is a laggard.\n */\n this.status(\"Unable to establish connection: \" + sConnection);\n }\n }\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {SerialPortPDP11}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n\n /*\n * This is as late as we can currently wait to make our first inter-machine connection attempt;\n * even so, the target machine's initialization process may still be ongoing, so any connection\n * may be not fully resolved until the target machine performs its own initConnection(), which will\n * in turn invoke our initConnection() again.\n */\n this.initConnection(this.fNullModem);\n\n if (!data) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {SerialPortPDP11}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {SerialPortPDP11}\n */\n reset()\n {\n this.initState();\n }\n\n /**\n * save()\n *\n * This implements save support for the SerialPort component.\n *\n * @this {SerialPortPDP11}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveRegisters());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the SerialPort component.\n *\n * @this {SerialPortPDP11}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return this.initState(data[0]);\n }\n\n /**\n * initState(a)\n *\n * @this {SerialPortPDP11}\n * @param {Array} [a]\n * @return {boolean} true if successful, false if failure\n */\n initState(a)\n {\n if (!a) {\n a = [0, PDP11.DL11.RCSR.CTS, PDP11.DL11.XCSR.READY, this.abReceive];\n }\n\n /*\n * ES6 ALERT: A handy destructuring assignment, which makes it easy to perform the inverse\n * of what saveRegisters() does when it collects a bunch of object properties into an array.\n */\n [\n this.regRBUF,\n this.regRCSR,\n this.regXCSR,\n this.abReceive\n ] = a;\n\n return true;\n }\n\n /**\n * saveRegisters()\n *\n * Basically, the inverse of initState().\n *\n * @this {SerialPortPDP11}\n * @return {Array}\n */\n saveRegisters()\n {\n return [\n this.regRBUF,\n this.regRCSR,\n this.regXCSR,\n this.abReceive\n ];\n }\n\n /**\n * getBaudTimeout(nBaud)\n *\n * Based on the selected baud rate (nBaud), convert that rate into a millisecond delay.\n *\n * @this {SerialPortPDP11}\n * @param {number} nBaud\n * @return {number} (number of milliseconds per byte)\n */\n getBaudTimeout(nBaud)\n {\n /*\n * TODO: Do a better job computing this, based on actual numbers of start, stop and parity bits,\n * instead of hard-coding the total number of bits per byte to 10.\n */\n var nBytesPerSecond = Math.round(nBaud / 10);\n return 1000 / nBytesPerSecond;\n }\n\n /**\n * receiveData(data)\n *\n * This replaces the old sendRBR() function, which expected an Array of bytes. We still support that,\n * but in order to support connections with other SerialPort components (ie, the PC8080 SerialPort), we\n * have added support for numbers and strings as well.\n *\n * @this {SerialPortPDP11}\n * @param {number|string|Array} data\n * @return {boolean} true if received, false if not\n */\n receiveData(data)\n {\n if (typeof data == \"number\") {\n this.abReceive.push(data);\n }\n else if (typeof data == \"string\") {\n var bASCII = 0, bASCIIPrev;\n for (var i = 0; i < data.length; i++) {\n bASCIIPrev = bASCII;\n bASCII = data.charCodeAt(i);\n /*\n * NOTE: Multiple lines of pasted text will (at least on macOS) contain LFs instead of CRs;\n * we convert them to CRs below. Windows may do something different, but in the worst case,\n * even if we receive CR/LF pairs, this code should keep the CRs and lose the LFs.\n */\n if (bASCII == Str.ASCII.LF) {\n if (bASCIIPrev == Str.ASCII.CR) continue;\n bASCII = Str.ASCII.CR;\n }\n this.abReceive.push(bASCII);\n }\n }\n else {\n this.abReceive = this.abReceive.concat(data);\n }\n\n this.cpu.setTimer(this.timerReceiveInterrupt, this.getBaudTimeout(this.nBaudReceive));\n\n return true; // for now, return true regardless, since we're buffering everything anyway\n }\n\n /**\n * receiveByte()\n *\n * @this {SerialPortPDP11}\n * @return {number} (0x00-0xff if byte available, -1 if not)\n */\n receiveByte()\n {\n var b = -1;\n if (this.abReceive.length) {\n /*\n * Here, as elsewhere (eg, the PC11 component), even if I trusted all incoming data\n * to be byte values (which I don't), there's also the risk that it could be signed data\n * (eg, -128 to 127, instead of 0 to 255). Both risks are good reasons to always mask\n * the data assigned to RBUF with 0xff.\n */\n b = this.abReceive.shift() & 0xff;\n this.printMessage(\"receiveByte(\" + Str.toHexByte(b) + \")\");\n if (this.fUpperCase) {\n /*\n * Automatically transform lower-case ASCII codes to upper-case; fUpperCase should\n * only be set when a terminal or some sort of pseudo-display is being used and we don't\n * trust it to have its CAPS-LOCK setting correct.\n */\n if (b >= 0x61 && b < 0x7A) b -= 0x20;\n }\n this.cpu.setTimer(this.timerReceiveInterrupt, this.getBaudTimeout(this.nBaudReceive));\n }\n return b;\n }\n\n /**\n * receiveStatus(pins)\n *\n * @this {SerialPortPDP11}\n * @param {number} pins\n */\n receiveStatus(pins)\n {\n var oldRCSR = this.regRCSR;\n this.regRCSR &= ~(PDP11.DL11.RCSR.CTS | PDP11.DL11.RCSR.CD);\n if (pins & RS232.CTS.MASK) {\n this.regRCSR |= PDP11.DL11.RCSR.CTS;\n }\n if (pins & RS232.CD.MASK) {\n this.regRCSR |= PDP11.DL11.RCSR.CD;\n }\n if (oldRCSR != this.regRCSR) {\n this.regRCSR |= PDP11.DL11.RCSR.DSC;\n if (this.regRCSR & PDP11.DL11.RCSR.DIE) {\n this.cpu.setIRQ(this.irqReceiver);\n }\n }\n }\n\n /**\n * setConnection(component, fn)\n *\n * @this {SerialPortPDP11}\n * @param {Object|null} component\n * @param {function(number)} fn\n * @return {boolean}\n */\n setConnection(component, fn)\n {\n if (!this.connection) {\n this.connection = component;\n this.sendData = fn;\n return true;\n }\n return false;\n }\n\n /**\n * transmitByte(b)\n *\n * @this {SerialPortPDP11}\n * @param {number} b\n * @return {boolean} true if transmitted, false if not\n */\n transmitByte(b)\n {\n var fTransmitted = false;\n\n if (MAXDEBUG) this.printMessage(\"transmitByte(\" + Str.toHexByte(b) + \")\");\n\n if (this.sendData) {\n if (this.sendData.call(this.connection, b)) {\n fTransmitted = true;\n }\n }\n\n /*\n * TODO: Why do DEC diagnostics like to output bytes with bit 7 set?\n */\n b &= 0x7F;\n if (this.controlBuffer) {\n if (b == 0x0D) {\n this.iLogicalCol = 0;\n }\n else if (b == 0x08) {\n this.controlBuffer.value = this.controlBuffer.value.slice(0, -1);\n /*\n * TODO: Back up the correct number of columns if the character erased was a tab.\n */\n if (this.iLogicalCol > 0) this.iLogicalCol--;\n }\n else if (b) {\n /*\n * RT-11 outputs lots of NULL characters, at least after a \"D 56=5015\" (0x0A0D) command has\n * been issued, hence the \"if (b)\" check above.\n *\n * TODO: Also consider a check for Keys.ASCII.CTRL_C, because by default, RT-11 outputs \"raw\"\n * CTRL_C characters, which we capture below and render as <ETX>. RT-11 does this for other keys\n * as well, such as CTRL_K (<VT>) and CTRL_L (<FF>).\n */\n var s = Str.toASCIICode(b); // formerly: String.fromCharCode(b);\n var nChars = s.length; // formerly: (b >= 0x20? 1 : 0);\n if (b < 0x20 && nChars == 1) nChars = 0;\n if (b == 0x09) {\n var tabSize = this.tabSize || 8;\n nChars = tabSize - (this.iLogicalCol % tabSize);\n if (this.tabSize) s = Str.pad(\"\", nChars);\n }\n if (this.charBOL && !this.iLogicalCol && nChars) s = String.fromCharCode(this.charBOL) + s;\n this.controlBuffer.value += s;\n this.controlBuffer.scrollTop = this.controlBuffer.scrollHeight;\n this.iLogicalCol += nChars;\n }\n fTransmitted = true;\n }\n else if (this.consoleBuffer != null) {\n if (b == 0x0A || this.consoleBuffer.length >= 1024) {\n this.println(this.consoleBuffer);\n this.consoleBuffer = \"\";\n }\n if (b != 0x0A) {\n this.consoleBuffer += String.fromCharCode(b);\n }\n fTransmitted = true;\n }\n\n /*\n * NOTE: When debugging issues involving the SerialPort, such as debugging code between a pair of\n * transmitted bytes, you can pass 0 instead of getBaudTimeout() to setTimer() to minimize the amount\n * of time spent waiting for XCSR.READY to be set again.\n */\n this.cpu.setTimer(this.timerTransmitInterrupt, this.getBaudTimeout(this.nBaudTransmit));\n\n return fTransmitted;\n }\n\n /**\n * readRCSR(addr)\n *\n * @this {SerialPortPDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.RCSR or 177560)\n * @return {number}\n */\n readRCSR(addr)\n {\n var data = this.regRCSR & PDP11.DL11.RCSR.RMASK;\n this.regRCSR &= ~PDP11.DL11.RCSR.DSC;\n return data;\n }\n\n /**\n * writeRCSR(data, addr)\n *\n * @this {SerialPortPDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RCSR or 177560)\n */\n writeRCSR(data, addr)\n {\n var delta = (data ^ this.regRCSR);\n this.regRCSR = (this.regRCSR & ~PDP11.DL11.RCSR.WMASK) | (data & PDP11.DL11.RCSR.WMASK);\n /*\n * Whenever DTR or RTS changes, we also want to notify any connected machine, via updateStatus().\n */\n if (this.updateStatus) {\n if (delta & PDP11.DL11.RCSR.RS232) {\n var pins = 0;\n if (this.fNullModem) {\n pins |= (data & PDP11.DL11.RCSR.RTS)? RS232.CTS.MASK : 0;\n pins |= (data & PDP11.DL11.RCSR.DTR)? (RS232.DSR.MASK | RS232.CD.MASK): 0;\n } else {\n pins |= (data & PDP11.DL11.RCSR.RTS)? RS232.RTS.MASK : 0;\n pins |= (data & PDP11.DL11.RCSR.DTR)? RS232.DTR.MASK : 0;\n }\n this.updateStatus.call(this.connection, pins);\n }\n }\n }\n\n /**\n * readRBUF(addr)\n *\n * @this {SerialPortPDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.RBUF or 177562)\n * @return {number}\n */\n readRBUF(addr)\n {\n this.regRCSR &= ~PDP11.DL11.RCSR.RD;\n return this.regRBUF;\n }\n\n /**\n * writeRBUF(data, addr)\n *\n * @this {SerialPortPDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RBUF or 177562)\n */\n writeRBUF(data, addr)\n {\n }\n\n /**\n * readXCSR(addr)\n *\n * @this {SerialPortPDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.XCSR or 177564)\n * @return {number}\n */\n readXCSR(addr)\n {\n return this.regXCSR;\n }\n\n /**\n * writeXCSR(data, addr)\n *\n * @this {SerialPortPDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.XCSR or 177564)\n */\n writeXCSR(data, addr)\n {\n /*\n * If the device is READY, and TIE is being set, then request a hardware interrupt.\n *\n * Conversely, if TIE is being cleared, remove the request; this resolves a problem within\n * MAINDEC TEST 15, where the Transmitter Interrupt Enable (TIE) bit is cleared, set, and cleared\n * in rapid succession, with the expectation that NO interrupt will be generated. Note that\n * this fix also requires a complementary change in setIRQ(), to request hardware interrupts with\n * IRQ_DELAY rather than IRQ.\n */\n if (this.regXCSR & PDP11.DL11.XCSR.READY) {\n if (data & PDP11.DL11.XCSR.TIE) {\n this.cpu.setIRQ(this.irqTransmitter);\n } else {\n this.cpu.clearIRQ(this.irqTransmitter);\n }\n }\n this.regXCSR = (this.regXCSR & ~PDP11.DL11.XCSR.WMASK) | (data & PDP11.DL11.XCSR.WMASK);\n }\n\n /**\n * readXBUF(addr)\n *\n * @this {SerialPortPDP11}\n * @param {number} addr (eg, PDP11.UNIBUS.XBUF or 177566)\n * @return {number}\n */\n readXBUF(addr)\n {\n return 0;\n }\n\n /**\n * writeXBUF(data, addr)\n *\n * @this {SerialPortPDP11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.XBUF or 177566)\n */\n writeXBUF(data, addr)\n {\n this.transmitByte(data & PDP11.DL11.XBUF.DATA);\n this.regXCSR &= ~PDP11.DL11.XCSR.READY;\n }\n\n /**\n * SerialPortPDP11.init()\n *\n * This function operates on every HTML element of class \"serial\", extracting the\n * JSON-encoded parameters for the SerialPort constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a SerialPort component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeSerial = Component.getElementsByClass(document, PDP11.APPCLASS, \"serial\");\n for (var iSerial = 0; iSerial < aeSerial.length; iSerial++) {\n var eSerial = aeSerial[iSerial];\n var parmsSerial = Component.getComponentParms(eSerial);\n var serial = new SerialPortPDP11(parmsSerial);\n Component.bindComponentControls(serial, eSerial, PDP11.APPCLASS);\n }\n }\n}\n\n/*\n * ES6 ALERT: As you can see below, I've finally started using computed property names.\n */\nSerialPortPDP11.UNIBUS_IOTABLE = {\n [PDP11.UNIBUS.RCSR]: /* 177560 */ [null, null, SerialPortPDP11.prototype.readRCSR, SerialPortPDP11.prototype.writeRCSR, \"RCSR\"],\n [PDP11.UNIBUS.RBUF]: /* 177562 */ [null, null, SerialPortPDP11.prototype.readRBUF, SerialPortPDP11.prototype.writeRBUF, \"RBUF\"],\n [PDP11.UNIBUS.XCSR]: /* 177564 */ [null, null, SerialPortPDP11.prototype.readXCSR, SerialPortPDP11.prototype.writeXCSR, \"XCSR\"],\n [PDP11.UNIBUS.XBUF]: /* 177566 */ [null, null, SerialPortPDP11.prototype.readXBUF, SerialPortPDP11.prototype.writeXBUF, \"XBUF\"]\n};\n\n/*\n * Initialize every SerialPort module on the page.\n */\nWeb.onInit(SerialPortPDP11.init);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/pc11.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass PC11 extends Component {\n /**\n * PC11(parms)\n *\n * The PC11 component has the following component-specific (parms) properties:\n *\n * autoMount: a JSON-encoded object containing 'name' and 'path' properties, describing a\n * tape resource to automatically load at startup (only the \"load\" operation is supported\n * for autoMount; if you want to \"read\" a tape image directly into RAM at startup, you must\n * ask the RAM component to do that).\n *\n * baudReceive: the default number of bits/second that the device should receive data at;\n * 0 means use the device default (PDP11.PC11.PRS.BAUD)\n *\n * baudTransmit: the default number of bits/second that the device should transmit data at;\n * 0 means use the device default (PDP11.PC11.PPS.BAUD); currently ignored, since punch\n * support isn't implemented yet.\n *\n * NOTE: Since the XSL file defines the 'baud' properties as numbers, not strings, there's no need to\n * use parseInt(), and as an added benefit, we don't need to worry about whether a hex or decimal format\n * was used.\n *\n * @param {Object} parms\n */\n constructor(parms)\n {\n super(\"PC11\", parms, MessagesPDP11.PC11);\n\n this.sDevice = \"PTR\"; // TODO: Make the device name configurable\n\n /*\n * We preliminarily parse and record any 'autoMount' object now, but we no longer process it\n * until initBus(), because the Computer's getMachineParm() service may have an override for us.\n */\n this.configMount = this.parseConfig(parms['autoMount']);\n this.cAutoMount = 0;\n this.nBaudReceive = +parms['baudReceive'] || PDP11.PC11.PRS.BAUD;\n\n this.regPRS = 0; // PRS register\n this.regPRB = 0; // PRB register\n this.regPPS = PDP11.PC11.PPS.ERROR; // PPS register (TODO: Stop signaling error once punch is implemented)\n this.regPPB = 0; // PPB register\n this.iTapeData = 0; // buffer index\n this.aTapeData = []; // buffer for the PRB register\n this.sTapeSource = PC11.SOURCE.NONE;\n this.nTapeTarget = PC11.TARGET.NONE;\n this.sTapeName = this.sTapePath = \"\";\n\n /*\n * These next few variables simply keep track of the previous parameters to parseTape(),\n * so that we can easily reparse the previous tape as needed.\n */\n this.aBytes = this.addrLoad = this.addrExec = null;\n\n this.nLastPercent = -1; // ensure the first displayProgress() displays something\n\n /*\n * Support for local tape images is currently limited to desktop browsers with FileReader support;\n * when this flag is set, setBinding() allows local tape bindings and informs initBus() to update the\n * \"listTapes\" binding accordingly.\n */\n this.fLocalTapes = (!Web.isMobile() && window && 'FileReader' in window);\n\n this.irqReader = null;\n this.timerReader = -1;\n this.ram = null;\n }\n\n /**\n * parseConfig(config)\n *\n * @this {PC11}\n * @param {*} config\n * @return {*}\n */\n parseConfig(config)\n {\n if (config && typeof config == \"string\") {\n try {\n /*\n * The most likely source of any exception will be right here, where we're parsing\n * this JSON-encoded data.\n */\n config = eval(\"(\" + config + \")\");\n } catch (e) {\n Component.error(this.type + \" auto-mount error: \" + e.message + \" (\" + config + \")\");\n config = null;\n }\n }\n return config || {};\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {PC11}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"listTapes\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var pc11 = this;\n var nTapeTarget = PC11.TARGET.NONE;\n\n switch (sBinding) {\n\n case \"listTapes\":\n var controlSelect = /** @type {HTMLSelectElement} */ (control);\n this.bindings[sBinding] = controlSelect;\n controlSelect.onchange = function onChangeListTapes(event) {\n var controlDesc = pc11.bindings[\"descTape\"];\n var controlOption = controlSelect.options[controlSelect.selectedIndex];\n if (controlDesc && controlOption) {\n var dataValue = {};\n var sValue = controlOption.getAttribute(\"data-value\");\n if (sValue) {\n try {\n dataValue = eval(\"(\" + sValue + \")\");\n } catch (e) {\n Component.error(\"PC11 option error: \" + e.message);\n }\n }\n var sHTML = dataValue['desc'];\n if (sHTML === undefined) sHTML = \"\";\n var sHRef = dataValue['href'];\n if (sHRef !== undefined) sHTML = \"<a href=\\\"\" + sHRef + \"\\\" target=\\\"_blank\\\">\" + sHTML + \"</a>\";\n controlDesc.innerHTML = sHTML;\n }\n };\n return true;\n\n case \"descTape\":\n this.bindings[sBinding] = control;\n return true;\n\n /*\n * \"readTape\" operation must do pretty much everything that the \"loadTape\" does, but whereas the load\n * operation records the bytes in aTapeData, the read operation stuffs them directly into the machine's memory;\n * the former sets nTapeTarget to TARGET.READER, while the latter sets it to TARGET.MEMORY.\n */\n case \"readTape\":\n nTapeTarget = PC11.TARGET.MEMORY;\n /* falls through */\n\n case \"loadTape\":\n if (!nTapeTarget) nTapeTarget = PC11.TARGET.READER;\n this.bindings[sBinding] = control;\n control.onclick = function onClickReadTape(event) {\n var controlTapes = pc11.bindings[\"listTapes\"];\n if (controlTapes) {\n var sTapeName = controlTapes.options[controlTapes.selectedIndex].text;\n var sTapePath = controlTapes.value;\n pc11.loadSelectedTape(sTapeName, sTapePath, nTapeTarget);\n }\n };\n return true;\n\n case \"mountTape\":\n var controlInput = /** @type {Object} */ (control);\n \n if (!this.fLocalTapes) {\n if (DEBUG) this.log(\"Local tape support not available\");\n /*\n * We could also simply hide the control; eg:\n *\n * controlInput.style.display = \"none\";\n *\n * but removing the control altogether seems better.\n */\n controlInput.parentNode.removeChild(/** @type {Node} */ (controlInput));\n return false;\n }\n\n this.bindings[sBinding] = controlInput;\n\n /*\n * Enable \"Mount\" button only if a file is actually selected\n */\n controlInput.addEventListener('change', function() {\n var fieldset = controlInput.children[0];\n var files = fieldset.children[0].files;\n var submit = fieldset.children[1];\n submit.disabled = !files.length;\n });\n\n controlInput.onsubmit = function(event) {\n var file = event.currentTarget[1].files[0];\n if (file) {\n var sTapePath = file.name;\n var sTapeName = Str.getBaseName(sTapePath, true);\n /*\n * TODO: Provide a way to mount tapes into MEMORY as well as READER.\n */\n pc11.loadSelectedTape(sTapeName, sTapePath, PC11.TARGET.READER, file);\n }\n /*\n * Prevent reloading of web page after form submission\n */\n return false;\n };\n return true;\n\n case PC11.BINDING.READ_PROGRESS:\n this.bindings[sBinding] = control;\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {PC11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n this.ram = /** @type {RAMPDP11} */ (cmp.getMachineComponent(\"RAM\"));\n\n var pc11 = this;\n\n var configMount = this.parseConfig(this.cmp.getMachineParm('autoMount'));\n\n /*\n * Add only devices from the machine-wide autoMount configuration that match devices managed by this component.\n */\n if (configMount) {\n for (var sDevice in configMount) {\n if (sDevice != this.sDevice) continue;\n this.configMount[sDevice] = configMount[sDevice];\n }\n }\n\n this.irqReader = this.cpu.addIRQ(PDP11.PC11.RVEC, PDP11.PC11.PRI, MessagesPDP11.PC11);\n\n this.timerReader = this.cpu.addTimer(function readyReader() {\n pc11.advanceReader();\n });\n\n bus.addIOTable(this, PC11.UNIBUS_IOTABLE);\n bus.addResetHandler(this.reset.bind(this));\n\n this.addTape(\"None\", PC11.SOURCE.NONE, true);\n if (this.fLocalTapes) this.addTape(\"Local Tape\", PC11.SOURCE.LOCAL);\n this.addTape(\"Remote Tape\", PC11.SOURCE.REMOTE);\n\n if (!this.autoMount()) this.setReady();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {PC11}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.reset();\n } else {\n if (!this.restore(data)) return false;\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {PC11}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * TODO: Consider making our reset() handler ALSO restore the original loaded tape, in much the same\n * way the RAM component now restores the original predefined memory or tape image after resetting the RAM.\n *\n * @this {PC11}\n */\n reset()\n {\n this.regPRS &= ~PDP11.PC11.PRS.CLEAR;\n this.regPRB = 0;\n }\n\n /**\n * autoMount(fRemount)\n *\n * @this {PC11}\n * @param {boolean} [fRemount] is true if we're remounting all auto-mounted tapes\n * @return {boolean} true if one or more tape images are being auto-mounted, false if none\n */\n autoMount(fRemount)\n {\n if (!fRemount) this.cAutoMount = 0;\n var configMount = this.configMount[this.sDevice];\n if (configMount) {\n var sTapePath = configMount['path'] || \"\";\n var sTapeName = configMount['name'] || this.findTape(sTapePath);\n if (sTapePath && sTapeName) {\n /*\n * TODO: Provide a way to autoMount tapes into MEMORY as well as READER.\n */\n if (!this.loadTape(sTapeName, sTapePath, PC11.TARGET.READER, true) && fRemount) {\n this.setReady(false);\n }\n } else {\n /*\n * This likely happened because there was no autoMount setting (or it was overridden with an empty value),\n * so just make sure the current selection is set to \"None\".\n */\n this.displayTape();\n }\n }\n return !!this.cAutoMount;\n }\n\n /**\n * loadSelectedTape(sTapeName, sTapePath, nTapeTarget, file)\n *\n * @this {PC11}\n * @param {string} sTapeName\n * @param {string} sTapePath\n * @param {number} nTapeTarget\n * @param {File} [file] is set if there's an associated File object\n */\n loadSelectedTape(sTapeName, sTapePath, nTapeTarget, file)\n {\n if (!sTapePath) {\n this.unloadTape(false);\n return;\n }\n\n if (sTapePath == PC11.SOURCE.LOCAL) {\n this.notice('Use \"Choose File\" and \"Mount\" to select and load a local tape.');\n return;\n }\n\n /*\n * If the special PC11.SOURCE.REMOTE path is selected, then we want to prompt the user for a URL.\n * Oh, and make sure we pass an empty string as the 2nd parameter to prompt(), so that IE won't display\n * \"undefined\" -- because after all, undefined and \"undefined\" are EXACTLY the same thing, right?\n *\n * TODO: This is literally all I've done to support remote tape images. There's probably more\n * I should do, like dynamically updating \"listTapes\" to include new entries, and adding new entries\n * to the save/restore data.\n */\n if (sTapePath == PC11.SOURCE.REMOTE) {\n sTapePath = window.prompt(\"Enter the URL of a remote tape image.\", \"\") || \"\";\n if (!sTapePath) return;\n sTapeName = Str.getBaseName(sTapePath);\n this.status(\"Attempting to load \" + sTapePath + \" as \\\"\" + sTapeName + \"\\\"\");\n this.sTapeSource = PC11.SOURCE.REMOTE;\n }\n else {\n this.sTapeSource = sTapePath;\n }\n\n this.loadTape(sTapeName, sTapePath, nTapeTarget, false, file);\n }\n\n /**\n * loadTape(sTapeName, sTapePath, nTapeTarget, fAutoMount, file)\n *\n * NOTE: If sTapePath is already loaded, nothing needs to be done.\n *\n * @this {PC11}\n * @param {string} sTapeName\n * @param {string} sTapePath\n * @param {number} nTapeTarget\n * @param {boolean} [fAutoMount]\n * @param {File} [file] is set if there's an associated File object\n * @return {number} 1 if tape loaded, 0 if queued up (or busy), -1 if already loaded\n */\n loadTape(sTapeName, sTapePath, nTapeTarget, fAutoMount, file)\n {\n var nResult = -1;\n\n if (this.sTapePath.toLowerCase() != sTapePath.toLowerCase() || this.nTapeTarget != nTapeTarget) {\n\n nResult++;\n this.unloadTape(true);\n\n if (this.flags.busy) {\n this.notice(\"PC11 busy\");\n }\n else {\n // this.status(\"tape queued: \" + sTapeName);\n if (fAutoMount) {\n this.cAutoMount++;\n if (this.messageEnabled()) this.printMessage(\"auto-loading tape: \" + sTapeName);\n }\n if (this.load(sTapeName, sTapePath, nTapeTarget, file)) {\n nResult++;\n } else {\n this.flags.busy = true;\n }\n }\n }\n if (nResult) {\n /*\n * Now that we're calling parseTape() again (so that the current tape can either be restarted on\n * the reader or reloaded into RAM), we can also rely on it to display an appropriate status message, too.\n *\n * this.status(this.nTapeTarget == PC11.TARGET.READER? \"tape loaded\" : \"tape read\");\n */\n this.parseTape(this.sTapeName, this.sTapePath, this.nTapeTarget, this.aBytes, this.addrLoad, this.addrExec);\n }\n return nResult;\n }\n\n /**\n * load(sTapeName, sTapePath, nTapeTarget, file)\n *\n * @this {PC11}\n * @param {string} sTapeName\n * @param {string} sTapePath\n * @param {number} nTapeTarget\n * @param {File} [file] is set if there's an associated File object\n * @return {boolean} true if load completed (successfully or not), false if queued\n */\n load(sTapeName, sTapePath, nTapeTarget, file)\n {\n var pc11 = this;\n var sTapeURL = sTapePath;\n\n if (DEBUG) {\n var sMessage = 'load(\"' + sTapeName + '\",\"' + sTapePath + '\")';\n this.printMessage(sMessage);\n }\n\n if (file) {\n var reader = new FileReader();\n reader.onload = function doneRead() {\n pc11.finishRead(sTapeName, sTapePath, nTapeTarget, reader.result);\n };\n reader.readAsArrayBuffer(file);\n return false;\n }\n\n /*\n * If there's an occurrence of API_ENDPOINT anywhere in the path, we assume we can use it as-is;\n * ie, that the user has already formed a URL of the type we use ourselves for unconverted tape images.\n */\n if (sTapePath.indexOf(DumpAPI.ENDPOINT) < 0) {\n /*\n * If the selected tape image has a \"json\" extension, then we assume it's a pre-converted\n * JSON-encoded tape image, so we load it as-is; otherwise, we ask our server-side tape image\n * converter to return the corresponding JSON-encoded data.\n */\n var sTapeExt = Str.getExtension(sTapePath);\n if (sTapeExt == DumpAPI.FORMAT.JSON || sTapeExt == DumpAPI.FORMAT.JSON_GZ) {\n sTapeURL = encodeURI(sTapePath);\n } else {\n var sTapeParm = DumpAPI.QUERY.PATH;\n sTapeURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + sTapeParm + '=' + encodeURIComponent(sTapePath) + \"&\" + DumpAPI.QUERY.FORMAT + \"=\" + DumpAPI.FORMAT.JSON;\n }\n }\n\n return !!Web.getResource(sTapeURL, null, true, function doneLoad(sURL, sResponse, nErrorCode) {\n pc11.finishLoad(sTapeName, sTapePath, nTapeTarget, sResponse, sURL, nErrorCode);\n });\n }\n\n /**\n * finishLoad(sTapeName, sTapePath, sTapeData, nTapeTarget, sURL, nErrorCode)\n *\n * @this {PC11}\n * @param {string} sTapeName\n * @param {string} sTapePath\n * @param {string} sTapeData\n * @param {number} nTapeTarget\n * @param {string} sURL\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n finishLoad(sTapeName, sTapePath, nTapeTarget, sTapeData, sURL, nErrorCode)\n {\n var fPrintOnly = (nErrorCode < 0 && !!this.cmp && !this.cmp.flags.powered);\n\n if (nErrorCode) {\n /*\n * This can happen for innocuous reasons, such as the user switching away too quickly, forcing\n * the request to be cancelled. And unfortunately, the browser cancels XMLHttpRequest requests\n * BEFORE it notifies any page event handlers, so if the Computer's being powered down, we won't know\n * that yet. For now, we rely on the lack of a specific error (nErrorCode < 0), and suppress the\n * notify() alert if there's no specific error AND the computer is not powered up yet.\n */\n this.notice(\"Unable to load tape \\\"\" + sTapeName + \"\\\" (error \" + nErrorCode + \": \" + sURL + \")\", fPrintOnly);\n }\n else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage('finishLoad(\"' + sTapePath + '\")');\n }\n Component.addMachineResource(this.idMachine, sURL, sTapeData);\n var resource = Web.parseMemoryResource(sURL, sTapeData);\n if (resource) {\n this.parseTape(sTapeName, sTapePath, nTapeTarget, resource.aBytes, resource.addrLoad, resource.addrExec);\n }\n }\n this.flags.busy = false;\n if (this.cAutoMount) {\n this.cAutoMount--;\n if (!this.cAutoMount) this.setReady();\n }\n this.displayTape();\n }\n\n /**\n * finishRead(sTapeName, sTapePath, nTapeTarget, buffer)\n *\n * @this {PC11}\n * @param {string} sTapeName\n * @param {string} sTapePath\n * @param {number} nTapeTarget\n * @param {?} buffer (we KNOW this is an ArrayBuffer, but we can't seem to convince the Closure Compiler)\n */\n finishRead(sTapeName, sTapePath, nTapeTarget, buffer)\n {\n if (buffer) {\n var aBytes = new Uint8Array(buffer, 0, buffer.byteLength);\n this.parseTape(sTapeName, sTapePath, nTapeTarget, aBytes);\n this.sTapeSource = PC11.SOURCE.LOCAL;\n }\n this.flags.busy = false;\n this.displayTape();\n }\n\n /**\n * addTape(sName, sPath, fTop)\n *\n * @this {PC11}\n * @param {string} sName\n * @param {string} sPath\n * @param {boolean} [fTop] (default is bottom)\n */\n addTape(sName, sPath, fTop)\n {\n var controlTapes = this.bindings[\"listTapes\"];\n if (controlTapes && controlTapes.options) {\n for (var i = 0; i < controlTapes.options.length; i++) {\n if (controlTapes.options[i].value == sPath) return;\n }\n var controlOption = document.createElement(\"option\");\n controlOption.text = sName;\n controlOption.value = sPath;\n if (fTop && controlTapes.childNodes[0]) {\n controlTapes.insertBefore(controlOption, controlTapes.childNodes[0]);\n } else {\n controlTapes.appendChild(controlOption);\n }\n }\n }\n\n /**\n * findTape(sPath)\n *\n * This is used to deal with mount requests (eg, autoMount) that supply a path without a name;\n * if we can find the path in the \"listTapes\" control, then we return the associated tape name.\n *\n * @this {PC11}\n * @param {string} sPath\n * @return {string|null}\n */\n findTape(sPath)\n {\n var controlTapes = this.bindings[\"listTapes\"];\n if (controlTapes && controlTapes.options) {\n for (var i = 0; i < controlTapes.options.length; i++) {\n var control = controlTapes.options[i];\n if (control.value == sPath) return control.text;\n }\n }\n return Str.getBaseName(sPath, true);\n }\n\n /**\n * displayTape()\n *\n * @this {PC11}\n */\n displayTape()\n {\n var controlTapes = this.bindings[\"listTapes\"];\n if (controlTapes && controlTapes.options) {\n var sTargetPath = this.sTapeSource || this.sTapePath;\n for (var i = 0; i < controlTapes.options.length; i++) {\n if (controlTapes.options[i].value == sTargetPath) {\n if (controlTapes.selectedIndex != i) {\n controlTapes.selectedIndex = i;\n }\n break;\n }\n }\n if (i == controlTapes.options.length) controlTapes.selectedIndex = 0;\n }\n }\n\n /**\n * displayProgress(nPercent)\n *\n * @this {PC11}\n * @param {number} nPercent\n */\n displayProgress(nPercent)\n {\n nPercent |= 0;\n if (nPercent !== this.nLastPercent) {\n var control = this.bindings[PC11.BINDING.READ_PROGRESS];\n if (control) {\n var aeControls = Component.getElementsByClass(control, PC11.CSSCLASS.PROGRESS_BAR);\n var controlBar = aeControls && aeControls[0];\n if (controlBar && controlBar.style) {\n controlBar.style.width = nPercent + \"%\";\n }\n }\n this.nLastPercent = nPercent;\n }\n }\n\n /**\n * parseTape(sTapeName, sTapePath, nTapeTarget, aBytes, addrLoad, addrExec)\n *\n * @this {PC11}\n * @param {string} sTapeName\n * @param {string} sTapePath\n * @param {number} nTapeTarget\n * @param {Array|Uint8Array} aBytes\n * @param {number|null} [addrLoad]\n * @param {number|null} [addrExec]\n */\n parseTape(sTapeName, sTapePath, nTapeTarget, aBytes, addrLoad, addrExec)\n {\n this.sTapeName = sTapeName;\n this.sTapePath = sTapePath;\n this.nTapeTarget = nTapeTarget;\n this.aBytes = aBytes;\n this.addrLoad = addrLoad;\n this.addrExec = addrExec;\n\n if (nTapeTarget == PC11.TARGET.MEMORY) {\n /*\n * Use the RAM component's loadImage() service to do our dirty work. If the load succeeds, then\n * depending on whether there was also exec address, either the CPU will be stopped or the PC wil be\n * reset.\n *\n * NOTE: Some tapes are not in the Absolute Loader format, so if the JSON-encoded tape resource file\n * we downloaded didn't ALSO include a load address, the load will fail.\n *\n * For example, the \"Absolute Loader\" tape is NOT itself in the Absolute Loader format. You just have\n * to know that in order to load that tape, you must first load the appropriate \"Bootstrap Loader\" (which\n * DOES include its own hard-coded load address), load the \"Absolute Loader\" tape, and then run the\n * \"Bootstrap Loader\".\n */\n if (!this.ram || !this.ram.loadImage(aBytes, addrLoad, addrExec, null, false)) {\n /*\n * This doesn't seem to serve any purpose, other than to be annoying, because perhaps you accidentally\n * clicked \"Read\" instead of \"Load\"....\n *\n * this.sTapeName = \"\";\n * this.sTapePath = \"\";\n * this.sTapeSource = PC11.SOURCE.NONE;\n * this.nTapeTarget = PC11.TARGET.NONE;\n */\n this.notice('No valid memory address for tape \"' + sTapeName + '\"');\n return;\n }\n this.status('Read tape \"' + sTapeName + '\"');\n return;\n }\n\n this.iTapeData = 0;\n this.aTapeData = aBytes;\n this.regPRS &= ~PDP11.PC11.PRS.ERROR;\n\n this.status('Loaded tape \"' + sTapeName + '\" (' + aBytes.length + \" bytes)\");\n this.displayProgress(0);\n }\n\n /**\n * unloadTape(fLoading)\n *\n * @this {PC11}\n * @param {boolean} [fLoading]\n */\n unloadTape(fLoading)\n {\n if (this.sTapePath || fLoading === false) {\n this.sTapeName = \"\";\n this.sTapePath = \"\";\n /*\n * Avoid any unnecessary hysteresis regarding the display if this unload is merely a prelude to another load.\n */\n if (!fLoading) {\n if (this.nTapeTarget) this.status(this.nTapeTarget == PC11.TARGET.READER? \"tape detached\" : \"tape unloaded\");\n this.sTapeSource = PC11.SOURCE.NONE;\n this.nTapeTarget = PC11.TARGET.NONE;\n this.displayTape();\n }\n }\n }\n\n /**\n * save()\n *\n * This implements save support for the PC11 component.\n *\n * @this {PC11}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the PC11 component.\n *\n * @this {PC11}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n return true;\n }\n\n /**\n * getBaudTimeout(nBaud)\n *\n * Based on the selected baud rate (nBaud), convert that rate into a millisecond delay.\n *\n * @this {PC11}\n * @param {number} nBaud\n * @return {number} (number of milliseconds per byte)\n */\n getBaudTimeout(nBaud)\n {\n /*\n * TODO: Do a better job computing this, based on actual numbers of start, stop and parity bits,\n * instead of hard-coding the total number of bits per byte to 10.\n */\n var nBytesPerSecond = Math.round(nBaud / 10);\n return 1000 / nBytesPerSecond;\n }\n\n /**\n * advanceReader()\n *\n * If the reader is enabled (RE is set) and there is no exceptional condition (ie, ERROR is set),\n * and if the buffer register is empty (DONE is clear), then if we have more data in our internal buffer,\n * store it in the buffer register, and optionally trigger an interrupt if device interrupts are enabled.\n *\n * @this {PC11}\n */\n advanceReader()\n {\n if ((this.regPRS & (PDP11.PC11.PRS.RE | PDP11.PC11.PRS.ERROR)) == PDP11.PC11.PRS.RE) {\n if (!(this.regPRS & PDP11.PC11.PRS.DONE)) {\n if (this.iTapeData < this.aTapeData.length) {\n /*\n * Here, as elsewhere (eg, the DL11 component), even if I trusted all incoming data\n * to be byte values (which I don't), there's also the risk that it could be signed data\n * (eg, -128 to 127, instead of 0 to 255). Both risks are good reasons to always mask\n * the data assigned to PRB with 0xff.\n */\n this.regPRB = this.aTapeData[this.iTapeData] & 0xff;\n if (this.messageEnabled()) this.printMessage(this.type + \".advanceReader(\" + this.iTapeData + \"): \" + Str.toHexByte(this.regPRB), true);\n this.iTapeData++;\n this.displayProgress(this.iTapeData / this.aTapeData.length * 100);\n }\n else {\n this.regPRS |= PDP11.PC11.PRS.ERROR;\n }\n this.regPRS |= PDP11.PC11.PRS.DONE;\n this.regPRS &= ~PDP11.PC11.PRS.BUSY;\n if (this.regPRS & PDP11.PC11.PRS.IE) {\n this.cpu.setIRQ(this.irqReader);\n }\n }\n }\n }\n\n /**\n * readPRS(addr)\n *\n * NOTE: We use the PRS RMASK to honor the \"write-only\" behavior of bit 0, the reader enable bit (RE), because\n * DEC's tiny Bootstrap Loader (/apps/pdp11/boot/bootstrap/BOOTSTRAP-16KB.lst) repeatedly enables the reader using\n * the INC instruction, which causes the PRS to be read, incremented, and written, so if bit 0 isn't always read\n * as zero, the INC instruction would clear RE instead of setting it.\n *\n * @this {PC11}\n * @param {number} addr (eg, PDP11.UNIBUS.PRS or 177550)\n * @return {number}\n */\n readPRS(addr)\n {\n return this.regPRS & PDP11.PC11.PRS.RMASK; // RMASK honors the \"write-only\" nature of the RE bit by returning zero on reads\n }\n\n /**\n * writePRS(data, addr)\n *\n * @this {PC11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.PRS or 177550)\n */\n writePRS(data, addr)\n {\n if (data & PDP11.PC11.PRS.RE) {\n /*\n * From the 1976 Peripherals Handbook, p. 4-378:\n *\n * Set [RE] to allow the Reader to fetch one character. The setting of this bit clears Done,\n * sets Busy, and clears the Reader Buffer (PRB). Operation of this bit is disabled if Error = 1;\n * attempting to set it when Error = 1 will cause an immediate interrupt if Interrupt Enable = 1.\n */\n if (this.regPRS & PDP11.PC11.PRS.ERROR) {\n data &= ~PDP11.PC11.PRS.RE;\n if (this.regPRS & PDP11.PC11.PRS.IE) {\n this.cpu.setIRQ(this.irqReader);\n }\n } else {\n this.regPRS &= ~PDP11.PC11.PRS.DONE;\n this.regPRS |= PDP11.PC11.PRS.BUSY;\n this.regPRB = 0;\n /*\n * The PC11, by virtue of its \"high speed\", is supposed to deliver characters at 300 CPS, so\n * that's the rate we'll choose as well (ie, 1000ms / 300). As an aside, the original \"low speed\"\n * version of the reader ran at 10 CPS.\n */\n this.cpu.setTimer(this.timerReader, this.getBaudTimeout(this.nBaudReceive));\n }\n }\n this.regPRS = (this.regPRS & ~PDP11.PC11.PRS.WMASK) | (data & PDP11.PC11.PRS.WMASK);\n }\n\n /**\n * readPRB(addr)\n *\n * @this {PC11}\n * @param {number} addr (eg, PDP11.UNIBUS.PRB or 177552)\n * @return {number}\n */\n readPRB(addr)\n {\n /*\n * I'm guessing that the DONE and BUSY bits always remain more-or-less inverses of each other. They definitely\n * start out that way when writePRS() sets the reader enable (RE) bit, and so that's how we treat them elsewhere, too.\n */\n this.regPRS &= ~PDP11.PC11.PRS.DONE;\n this.regPRS |= PDP11.PC11.PRS.BUSY;\n return this.regPRB;\n }\n\n /**\n * writePRB(data, addr)\n *\n * @this {PC11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.PRB or 177552)\n */\n writePRB(data, addr)\n {\n }\n\n /**\n * readPPS(addr)\n *\n * @this {PC11}\n * @param {number} addr (eg, PDP11.UNIBUS.PPS or 177554)\n * @return {number}\n */\n readPPS(addr)\n {\n return this.regPPS;\n }\n\n /**\n * writePPS(data, addr)\n *\n * NOTE: This was originally added ONLY because when RT-11 v4.0 copies from device \"PC:\" (the paper tape reader),\n * it executes the following code:\n *\n * 016010: 005037 177550 CLR @#177550 ;history=2 PRS\n * 016014: 005037 177554 CLR @#177554 ;history=1\n *\n * and as you can see, without this PPS handler, a TRAP to 4 would normally occur. I guess since we claim to be\n * a PC11, that makes sense. But what about PDP-11 machines with only a PR11 (ie, a reader-only unit)?\n *\n * @this {PC11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.PPS or 177554)\n */\n writePPS(data, addr)\n {\n this.regPPS = (this.regPPS & ~PDP11.PC11.PPS.WMASK) | (data & PDP11.PC11.PPS.WMASK);\n }\n\n /**\n * readPPB(addr)\n *\n * @this {PC11}\n * @param {number} addr (eg, PDP11.UNIBUS.PPB or 177556)\n * @return {number}\n */\n readPPB(addr)\n {\n return this.regPPB;\n }\n\n /**\n * writePPB(data, addr)\n *\n * @this {PC11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.PPB or 177556)\n */\n writePPB(data, addr)\n {\n this.regPPB = (data & PDP11.PC11.PPB.MASK);\n }\n}\n\n/*\n * There's nothing super special about these values, except that NONE should be falsey and the others should not.\n */\nPC11.SOURCE = {\n NONE: \"\",\n LOCAL: \"?\",\n REMOTE: \"??\"\n};\n\nPC11.TARGET = {\n NONE: 0,\n READER: 1,\n MEMORY: 2\n};\n\nPC11.BINDING = {\n READ_PROGRESS: \"readProgress\"\n};\n\nPC11.CSSCLASS = {\n PROGRESS_BAR: PDP11.CSSCLASS + \"-progress-bar\"\n};\n\n/*\n * ES6 ALERT: As you can see below, I've finally started using computed property names.\n */\nPC11.UNIBUS_IOTABLE = {\n [PDP11.UNIBUS.PRS]: /* 177550 */ [null, null, PC11.prototype.readPRS, PC11.prototype.writePRS, \"PRS\"],\n [PDP11.UNIBUS.PRB]: /* 177552 */ [null, null, PC11.prototype.readPRB, PC11.prototype.writePRB, \"PRB\"],\n [PDP11.UNIBUS.PPS]: /* 177554 */ [null, null, PC11.prototype.readPPS, PC11.prototype.writePPS, \"PPS\"],\n [PDP11.UNIBUS.PPB]: /* 177556 */ [null, null, PC11.prototype.readPPB, PC11.prototype.writePPB, \"PPB\"]\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/disk.js (C) Jeff Parsons 2012-2018\n */\n\n/*\n * The DiskPDP11 component provides methods for:\n *\n * 1) creating an empty disk: create()\n * 2) loading a disk image: load()\n * 3) getting disk information: info()\n * 4) seeking a disk sector: seek()\n * 5) reading data from a sector: read()\n * 6) writing data to a sector: write()\n * 7) save disk deltas: save()\n * 8) restore disk deltas: restore()\n * 9) converting disk contents: convertToJSON()\n *\n * More functionality may be factored out of the disk controller components later and moved here,\n * to further reduce some of the duplication between them, but the above functionality is a good start.\n */\n\n\n/**\n * Every Sector object (once loaded, parsed, and \"normalized\") should have ALL of the following named properties:\n *\n * 'sector': sector number\n * 'length': size of the sector, in bytes\n * 'data': array of dwords\n * 'pattern': dword pattern to use for empty or partial sectors (or null if sector still needs to be loaded)\n *\n * initSector() also sets the following properties, to help us quickly identify its location within aDiskData:\n *\n * iCylinder\n * iHead\n *\n * In addition, we will maintain the following information on a per-sector basis, as sectors are modified:\n *\n * iModify: index of first modified dword in sector\n * cModify: number of modified dwords in sector\n * fDirty: true if sector is dirty, false if clean (or cleaning in progress)\n *\n * @typedef {{\n * sector: number,\n * length: number,\n * data: Array.<number>,\n * pattern: (number|null),\n * iCylinder: number,\n * iHead: number,\n * iModify: number,\n * cModify: number\n * }}\n */\nvar SectorInfo;\n\nclass DiskPDP11 extends Component {\n /**\n * DiskPDP11(controller, drive, mode)\n *\n * Disk contents are stored as an array (aDiskData) of cylinders, each of which is an array of\n * heads, each of which is an array of sector objects; the latter contain sector numbers and\n * sector data, where sector data is an array of dwords. The format does not impose any\n * limitations on number of cylinders, number of heads, sectors per track, or bytes per sector.\n *\n * WARNING: All accesses to disk sector properties must be via their string names, not their\n * \"dot\" names, otherwise code will break after it's been processed by the Closure Compiler,\n * and any dumped disks may be unmountable. This is a side-effect of how we mount and dump\n * disk images (ie, as JSON-encoded streams).\n *\n * This means, for example, that all references to \"track[iSector].data\" must actually appear as\n * \"track[iSector]['data']\".\n *\n * @param {DriveController|RK11|RL11} controller\n * @param {Object} drive\n * @param {string} mode\n */\n constructor(controller, drive, mode)\n {\n super(\"Disk\", {'id': controller.idMachine + \".disk\" + Str.toHex(++DiskPDP11.nDisks, 4)}, MessagesPDP11.DISK);\n\n /*\n * Route all non-Debugger messages (eg, notice() and println() calls) through\n * this.controller (eg, controller.notice() and controller.println()), because\n * the Computer component is unaware of any Disk objects and therefore will not\n * set up the usual overrides when a Control Panel is installed.\n */\n this.controller = controller;\n this.cmp = controller.cmp;\n this.dbg = controller.dbg;\n this.drive = drive;\n\n /*\n * We pull out a number of drive properties that we may or may not need as defaults.\n */\n this.sDiskName = drive.name;\n this.sDiskPath = this.sDiskFile = \"\";\n this.fRemovable = drive.fRemovable;\n\n /*\n * Initialize the disk contents\n */\n this.mode = 0;\n this.nCylinders = this.nHeads = this.nSectors = this.cbSector = 0;\n this.aDiskData = [];\n this.dwChecksum = null;\n this.fWriteProtected = false;\n this.create(mode, drive.nCylinders, drive.nHeads, drive.nSectors, drive.cbSector);\n\n this.fnNotify = this.controllerNotify = null;\n\n this.setReady();\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * We have no real interest in this notification, other than to obtain a reference to the Debugger\n * for every disk loaded BEFORE the initBus() phase; any disk loaded AFTER that point will get its Debugger\n * reference, if any, from the disk controller passed to the DiskPDP11() constructor.\n *\n * @this {DiskPDP11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.dbg = dbg;\n }\n\n /**\n * create()\n *\n * @this {DiskPDP11}\n * @param {string} mode\n * @param {number} nCylinders\n * @param {number} nHeads\n * @param {number} nSectors (per track)\n * @param {number} cbSector\n *\n * Initializes the disk contents according to the current drive mode and parameters.\n */\n create(mode, nCylinders, nHeads, nSectors, cbSector)\n {\n this.mode = mode;\n this.nCylinders = nCylinders;\n this.nHeads = nHeads;\n this.nSectors = nSectors;\n this.cbSector = cbSector;\n this.aDiskData = [];\n /*\n * If the drive is using PRELOAD mode, then it will use the load()/mount() process to initialize the disk contents;\n * it wouldn't hurt to let create() do its thing, too, but it's a waste of time.\n */\n if (this.mode != DiskAPI.MODE.PRELOAD) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"blank disk for \\\"\" + this.sDiskName + \"\\\": \" + this.nCylinders + \" cylinders, \" + this.nHeads + \" head(s)\");\n }\n var aCylinders = new Array(this.nCylinders);\n for (var iCylinder = 0; iCylinder < aCylinders.length; iCylinder++) {\n var aHeads = new Array(this.nHeads);\n for (var iHead = 0; iHead < aHeads.length; iHead++) {\n var aSectors = new Array(this.nSectors);\n for (var iSector = 1; iSector <= aSectors.length; iSector++) {\n /*\n * Now that our read() and write() functions can deal with unallocated data\n * arrays, and can read/write the specified pattern on-the-fly, we no longer need\n * to pre-allocate and pre-initialize the 'data' array.\n */\n aSectors[iSector - 1] = this.initSector(null, iCylinder, iHead, iSector, this.cbSector, 0);\n }\n aHeads[iHead] = aSectors;\n }\n aCylinders[iCylinder] = aHeads;\n }\n this.aDiskData = aCylinders;\n }\n this.dwChecksum = null;\n }\n\n /**\n * load(sDiskName, sDiskPath, file, fnNotify)\n *\n * TODO: Figure out how we can strongly type fnNotify, because the Closure Compiler has issues with:\n *\n * param {function(Component,Object,Disk,string,string)} fnNotify\n *\n * for:\n *\n * this.fnNotify.call(this.controller, this.drive, disk, this.sDiskName, this.sDiskPath);\n *\n * Also, while we're at it, learn if there are ways to:\n *\n * 1) declare a function taking NO parameters (ie, generate a warning if any parameters are specified)\n * 2) declare a type for a function's return value\n *\n * @this {DiskPDP11}\n * @param {string} sDiskName\n * @param {string} sDiskPath\n * @param {File} [file] is set if there's an associated File object\n * @param {function(...)} [fnNotify]\n * @param {Component} [controller]\n * @return {boolean} true if load completed (successfully or not), false if queued\n */\n load(sDiskName, sDiskPath, file, fnNotify, controller)\n {\n var sDiskURL = sDiskPath;\n\n /*\n * We could use this.log() as well, but it wouldn't display which component initiated the load.\n */\n if (DEBUG) {\n var sMessage = 'load(\"' + sDiskName + '\",\"' + sDiskPath + '\")';\n this.controller.log(sMessage);\n this.printMessage(sMessage);\n }\n\n if (this.fnNotify) {\n if (DEBUG) this.controller.log('too many load requests for \"' + sDiskName + '\" (' + sDiskPath + ')');\n return true;\n }\n\n this.sDiskName = sDiskName;\n this.sDiskPath = sDiskPath;\n this.sDiskFile = Str.getBaseName(sDiskPath);\n\n var disk = this;\n this.fnNotify = fnNotify;\n this.controllerNotify = controller || this.controller;\n\n if (file) {\n var reader = new FileReader();\n reader.onload = function() {\n disk.build(reader.result, true);\n };\n reader.readAsArrayBuffer(file);\n return true;\n }\n\n /*\n * If there's an occurrence of API_ENDPOINT anywhere in the path, we assume we can use it as-is;\n * ie, that the user has already formed a URL of the type we use ourselves for unconverted disk images.\n */\n if (sDiskPath.indexOf(DumpAPI.ENDPOINT) < 0) {\n /*\n * If the selected disk image has a \"json\" extension, then we assume it's a pre-converted\n * JSON-encoded disk image, so we load it as-is; otherwise, we ask our server-side disk image\n * converter to return the corresponding JSON-encoded data.\n */\n var sDiskExt = Str.getExtension(sDiskPath);\n if (sDiskExt == DumpAPI.FORMAT.JSON || sDiskExt == DumpAPI.FORMAT.JSON_GZ) {\n sDiskURL = encodeURI(sDiskPath);\n } else {\n var sDiskParm = DumpAPI.QUERY.PATH;\n var sSizeParm = '&' + DumpAPI.QUERY.MBHD + \"=10\";\n /*\n * 'mbhd' is a new parm added for hard drive support. In the case of 'file' or 'dir' requests,\n * 'mbhd' informs DumpAPI.ENDPOINT that it should create a hard disk image, and one not larger than\n * the specified size (eg, 10mb). In fact, until DumpAPI.ENDPOINT is changed to create custom hard\n * disk BPBs, you'll always get a standard PC XT 10mb disk image, so if the 'file' or 'dir' contains\n * more than 10mb of data, the request will fail. Ultimately, I want to honor the controller's\n * driveConfig 'size' parm, or to match the capacity required by the driveConfig 'type' parameter.\n *\n * If a 'disk' is specified, we pass mbhd=0, because the actual size will depend on the image.\n * However, I don't currently have any \"dsk\" or \"img\" files containing hard disk images; those formats\n * were really intended for floppy disk images. If I never create any hard disk image files, then\n * we can simply eliminate sSizeParm in the 'disk' case.\n *\n * Added more extensions to the list of paths-treated-as-disk-images, so that URLs to files located here:\n *\n * ftp://ftp.oldskool.org/pub/TOPBENCH/dskimage/\n *\n * can be used as-is. TODO: There's a TODO in netlib.getFile() regarding remote support that needs\n * to be resolved first; DiskDump relies on that function for its remote requests, and it currently\n * supports only HTTP.\n */\n if (!sDiskPath.indexOf(\"http:\") || !sDiskPath.indexOf(\"ftp:\") || [\"dsk\", \"ima\", \"img\", \"360\", \"720\", \"12\", \"144\"].indexOf(sDiskExt) >= 0) {\n sDiskParm = DumpAPI.QUERY.DISK;\n sSizeParm = '&' + DumpAPI.QUERY.MBHD + \"=0\";\n } else if (Str.endsWith(sDiskPath, '/')) {\n sDiskParm = DumpAPI.QUERY.DIR;\n }\n sDiskURL = Web.getHost() + DumpAPI.ENDPOINT + '?' + sDiskParm + '=' + encodeURIComponent(sDiskPath) + (this.fRemovable ? \"\" : sSizeParm) + \"&\" + DumpAPI.QUERY.FORMAT + \"=\" + DumpAPI.FORMAT.JSON;\n }\n }\n return !!Web.getResource(sDiskURL, null, true, function(sURL, sResponse, nErrorCode) {\n disk.doneLoad(sURL, sResponse, nErrorCode);\n });\n }\n\n /**\n * build(buffer, fModified)\n *\n * Builds a disk image from an ArrayBuffer (eg, from a FileReader object), rather than from JSON-encoded data.\n *\n * @this {DiskPDP11}\n * @param {?} buffer (we KNOW this is an ArrayBuffer, but we can't seem to convince the Closure Compiler)\n * @param {boolean} [fModified] is true if we should mark the entire disk modified (to ensure that we save/restore it)\n */\n build(buffer, fModified)\n {\n var disk;\n var cbDiskData = buffer? buffer.byteLength : 0;\n var diskFormat = DiskAPI.GEOMETRIES[cbDiskData];\n\n if (diskFormat) {\n this.nCylinders = diskFormat[0];\n this.nHeads = diskFormat[1];\n this.nSectors = diskFormat[2];\n this.cbSector = (diskFormat[3] || 512);\n\n var cdw = this.cbSector >> 2, dwPattern = 0, dwChecksum = 0;\n var ib = 0;\n var dv = new DataView(buffer, 0, cbDiskData);\n\n this.aDiskData = new Array(this.nCylinders);\n for (var iCylinder = 0; iCylinder < this.aDiskData.length; iCylinder++) {\n var cylinder = this.aDiskData[iCylinder] = new Array(this.nHeads);\n for (var iHead = 0; iHead < cylinder.length; iHead++) {\n var head = cylinder[iHead] = new Array(this.nSectors);\n for (var iSector = 0; iSector < head.length; iSector++) {\n var sector = this.initSector(null, iCylinder, iHead, iSector + 1, this.cbSector, dwPattern);\n var adw = sector['data'];\n for (var idw = 0; idw < cdw; idw++, ib += 4) {\n var dw = adw[idw] = dv.getInt32(ib, true);\n dwChecksum = (dwChecksum + dw) & (0xffffffff|0);\n }\n if (fModified) sector.cModify = cdw;\n head[iSector] = sector;\n }\n }\n }\n this.dwChecksum = dwChecksum;\n disk = this;\n } else {\n this.notice(\"Unrecognized disk format (\" + cbDiskData + \" bytes)\");\n }\n\n if (this.fnNotify) {\n this.fnNotify.call(this.controller, this.drive, disk, this.sDiskName, this.sDiskPath);\n this.fnNotify = null;\n }\n }\n\n /**\n * doneLoad(sURL, sDiskData, nErrorCode)\n *\n * This function was originally called mount(). If the mount is successful, we pass the Disk object to the\n * caller's fnNotify handler; otherwise, we pass null.\n *\n * @this {DiskPDP11}\n * @param {string} sURL\n * @param {string|null} sDiskData\n * @param {number} nErrorCode (response from server if anything other than 200)\n */\n doneLoad(sURL, sDiskData, nErrorCode)\n {\n var disk = null;\n var fPrintOnly = (nErrorCode < 0 && !!this.cmp && !this.cmp.flags.powered);\n\n this.fWriteProtected = false;\n\n if (nErrorCode) {\n /*\n * This can happen for innocuous reasons, such as the user switching away too quickly, forcing\n * the request to be cancelled. And unfortunately, the browser cancels XMLHttpRequest requests\n * BEFORE it notifies any page event handlers, so if the Computer's being powered down, we won't know\n * that yet. For now, we rely on the lack of a specific error (nErrorCode < 0), and suppress the\n * notify() alert if there's no specific error AND the computer is not powered up yet.\n */\n this.controller.notice(\"Unable to load disk \\\"\" + this.sDiskName + \"\\\" (error \" + nErrorCode + \": \" + sURL + \")\", fPrintOnly);\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage('doneLoad(\"' + this.sDiskPath + '\")');\n }\n\n Component.addMachineResource(this.controller.idMachine, sURL, sDiskData);\n\n try {\n /*\n * The following code was a hack to turn on write-protection for a disk image if there was\n * an initial comment line containing the string \"write-protected\". However, since comments\n * are technically not allowed in JSON, I needed an alternative solution. So, if the basename\n * contains the suffix \"-readonly\", then I'll turn on write-protection for that disk as well.\n *\n * TODO: Provide some UI for turning write-protection on/off for disks at will, and provide\n * an XML-based solution (ie, a per-disk XML configuration option) for controlling it as well.\n */\n var sBaseName = Str.getBaseName(this.sDiskFile, true).toLowerCase();\n if (sBaseName.indexOf(\"-readonly\") > 0) {\n this.fWriteProtected = true;\n } else {\n var iEOL = sDiskData.indexOf(\"\\n\");\n if (iEOL > 0 && iEOL < 1024) {\n var sConfig = sDiskData.substring(0, iEOL);\n if (sConfig.indexOf(\"write-protected\") > 0) {\n this.fWriteProtected = true;\n }\n }\n }\n /*\n * The most likely source of any exception will be here, where we're parsing the disk data.\n */\n var aDiskData;\n if (sDiskData.substr(0, 1) == \"<\") { // if the \"data\" begins with a \"<\"...\n /*\n * Early server configs reported an error (via the nErrorCode parameter) if a disk URL was invalid,\n * but more recent server configs now display a somewhat friendlier HTML error page. The downside,\n * however, is that the original error has been buried, and we've received \"data\" that isn't actually\n * disk data.\n *\n * So, if the data we've received appears to be \"HTML-like\", all we can really do is assume that the\n * disk image is missing. And so we pretend we received an error message to that effect.\n */\n aDiskData = [\"Missing disk image: \" + this.sDiskName];\n } else {\n /*\n * TODO: IE9 is rather unfriendly and restrictive with regard to how much data it's willing to\n * eval(). In particular, the 10Mb disk image we use for the Windows 1.01 demo config fails in\n * IE9 with an \"Out of memory\" exception. One work-around would be to chop the data into chunks\n * (perhaps one track per chunk, using regular expressions) and then manually re-assemble it.\n *\n * However, it turns out that using JSON.parse(sDiskData) instead of eval(\"(\" + sDiskData + \")\")\n * is a much easier fix. The only drawback is that we must first quote any unquoted property names\n * and remove any comments, because while eval() was cool with them, JSON.parse() is more particular;\n * the following RegExp replacements take care of those requirements.\n *\n * The use of hex values is something else that eval() was OK with, but JSON.parse() is not, and\n * while I've stopped using hex values in DumpAPI responses (at least when \"format=json\" is specified),\n * I can't guarantee they won't show up in \"legacy\" images, and there's no simple RegExp replacement\n * for transforming hex values into decimal values, so I cop out and fall back to eval() if I detect\n * any hex prefixes (\"0x\") in the sequence. Ditto for error messages, which appear like so:\n *\n * [\"unrecognized disk path: test.img\"]\n */\n if (sDiskData.indexOf(\"0x\") < 0 && sDiskData.substr(0, 2) != \"[\\\"\") {\n aDiskData = JSON.parse(sDiskData.replace(/([a-z]+):/gm, \"\\\"$1\\\":\").replace(/\\/\\/[^\\n]*/gm, \"\"));\n } else {\n aDiskData = eval(\"(\" + sDiskData + \")\");\n }\n }\n\n if (!aDiskData.length) {\n Component.error(\"Empty disk image: \" + this.sDiskName);\n }\n else if (aDiskData.length == 1) {\n Component.error(aDiskData[0]);\n }\n /*\n * aDiskData is an array of cylinders, each of which is an array of heads, each of which\n * is an array of sector objects. The format does not impose any limitations on number of\n * cylinders, number of heads, or number of bytes in any of the sector object byte-arrays.\n *\n * WARNING: All accesses to sector object properties must be via their string names, not their\n * \"dot\" names, otherwise code will break after it's been processed by the Closure Compiler.\n *\n * Sector object properties include:\n *\n * 'sector' the sector number (1-based, not required to be sequential)\n * 'length' the byte-length (ie, formatted length) of the sector\n * 'data' the dword-array containing the sector data\n * 'pattern' if the dword-array length is less than 'length'/4, this value must be used\n * to pad out the sector; if no 'pattern' is specified, it's assumed to be zero\n *\n * We still support the older JSON encoding, where sector data was encoded as an array of 'bytes'\n * rather than a dword 'data' array. However, our support is strictly limited to an on-the-fly\n * conversion to a forward-compatible 'data' array.\n */\n else {\n if (DEBUG && this.messageEnabled(MessagesPDP11.DISK | MessagesPDP11.BUFFER)) {\n var sCylinders = aDiskData.length + \" track\" + (aDiskData.length > 1 ? \"s\" : \"\");\n var nHeads = aDiskData[0].length;\n var sHeads = nHeads + \" head\" + (nHeads > 1 ? \"s\" : \"\");\n var nSectorsPerTrack = aDiskData[0][0].length;\n var sSectorsPerTrack = nSectorsPerTrack + \" sector\" + (nSectorsPerTrack > 1 ? \"s\" : \"\") + \"/track\";\n this.printMessage(sCylinders + \", \" + sHeads + \", \" + sSectorsPerTrack);\n }\n /*\n * Before the image is usable, we must \"normalize\" all the sectors. In the past, this meant\n * \"inflating\" them all. However, that's no longer strictly necessary. Mainly, it just means\n * setting 'length', 'data', and 'pattern' properties, so that all the sectors are well-defined.\n * This includes detecting sector data in older formats (eg, the old array of 'bytes' instead\n * of the new 'data' array of dwords) and converting them on-the-fly to the current format.\n */\n this.nCylinders = aDiskData.length;\n this.nHeads = aDiskData[0].length;\n this.nSectors = aDiskData[0][0].length;\n var sector = aDiskData[0][0][0];\n this.cbSector = (sector && sector['length']) || 512;\n\n var dwChecksum = 0;\n for (var iCylinder = 0; iCylinder < this.nCylinders; iCylinder++) {\n for (var iHead = 0; iHead < this.nHeads; iHead++) {\n for (var iSector = 0; iSector < this.nSectors; iSector++) {\n sector = aDiskData[iCylinder][iHead][iSector];\n if (!sector) continue; // non-standard (eg, XDF) disk images may have \"unused\" (null) sectors\n var length = sector['length'];\n if (length === undefined) { // provide backward-compatibility with older JSON...\n length = sector['length'] = 512;\n }\n length >>= 2; // convert length from a byte-length to a dword-length\n var dwPattern = sector['pattern'];\n if (dwPattern === undefined) {\n dwPattern = sector['pattern'] = 0;\n }\n var adw = sector['data'];\n if (adw === undefined) {\n var ab = sector['bytes'];\n if (ab === undefined || !ab.length) {\n /*\n * It would be odd if there was neither a 'bytes' nor 'data' array; I'm just\n * being paranoid. It's more likely that the 'bytes' array is simply empty,\n * in which case we need only create an empty 'data' array and turn the byte\n * pattern, if any, into a dword pattern.\n */\n adw = [];\n\n dwPattern = sector['pattern'] = (dwPattern | (dwPattern << 8) | (dwPattern << 16) | (dwPattern << 24));\n sector['data'] = adw;\n } else {\n /*\n * To keep the conversion code simple, we'll do any necessary pattern-filling first,\n * to fully \"inflate\" the sector, eliminating the possibility of partial dwords and\n * saving any code downstream from dealing with byte-size patterns.\n */\n var cb = length << 2;\n for (var ib = ab.length; ib < cb; ib++) {\n ab[ib] = dwPattern; // the pattern for byte-arrays was only a byte\n }\n this.fill(sector, ab, 0);\n }\n delete sector['bytes'];\n }\n this.initSector(sector, iCylinder, iHead);\n /*\n * For the disk as a whole, we maintain a checksum of the original unmodified data:\n *\n * dwChecksum: summation of all dwords in all non-empty sectors\n *\n * Pattern-filling of sectors is deferred until absolutely necessary (eg, when a sector is\n * being written). So all we need to do at this point is checksum all the initial sector data.\n */\n for (var idw = 0; idw < adw.length; idw++) {\n dwChecksum = (dwChecksum + adw[idw]) & (0xffffffff|0);\n }\n }\n }\n }\n this.aDiskData = aDiskData;\n this.dwChecksum = dwChecksum;\n disk = this;\n }\n } catch (e) {\n Component.error(\"Disk image error (\" + sURL + \"): \" + e.message);\n }\n }\n\n if (this.fnNotify) {\n this.fnNotify.call(this.controllerNotify, this.drive, disk, this.sDiskName, this.sDiskPath);\n this.fnNotify = null;\n }\n }\n\n /**\n * getSectorString(sector, off, len)\n *\n * WARNING: This function is restricted to reading a string contained ENTIRELY within the specified sector.\n *\n * @this {DiskPDP11}\n * @param {Object} sector\n * @param {number} off (byte offset)\n * @param {number} len (use -1 to read a null-terminated string)\n * @return {string}\n */\n getSectorString(sector, off, len)\n {\n var s = \"\";\n while (len--) {\n var b = this.read(sector, off++);\n if (b <= 0) break;\n s += String.fromCharCode(b);\n }\n return s;\n }\n\n /**\n * initSector(sector, iCylinder, iHead, iSector, cbSector, dwPattern)\n *\n * Ensures every sector has ALL the properties of a proper Sector object; ie:\n *\n * 'sector': sector number\n * 'length': size of the sector, in bytes\n * 'data': array of dwords\n * 'pattern': dword pattern to use for empty or partial sectors\n *\n * In addition, we will maintain the following information on a per-sector basis,\n * as sectors are modified:\n *\n * iModify: index of first modified dword in sector\n * cModify: number of modified dwords in sector\n * fDirty: true if sector is dirty, false if clean (or cleaning in progress)\n *\n * @this {DiskPDP11}\n * @param {Object} sector\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} [iSector]\n * @param {number} [cbSector]\n * @param {number|null} [dwPattern]\n * @return {Object}\n */\n initSector(sector, iCylinder, iHead, iSector, cbSector, dwPattern)\n {\n if (!sector) {\n sector = {'sector': iSector, 'length': cbSector, 'data': [], 'pattern': dwPattern};\n }\n sector.iCylinder = iCylinder;\n sector.iHead = iHead;\n sector.iModify = sector.cModify = 0;\n sector.fDirty = false;\n return sector;\n }\n\n /**\n * info()\n *\n * TODO: Decide whether deprecate this in favor of accessing the nCylinders, nHeads, nSectors, and cbSector\n * properties of the Disk object directly.\n *\n * @this {DiskPDP11}\n * @return {Array} containing: [nCylinders, nHeads, nSectorsPerTrack, nBytesPerSector]\n */\n info()\n {\n if (!this.aDiskData.length) {\n return [0, 0, 0, 0];\n }\n return [this.aDiskData.length, this.aDiskData[0].length, this.aDiskData[0][0].length, this.aDiskData[0][0][0]['length']];\n }\n\n /**\n * seek(iCylinder, iHead, iSector, fWrite, done)\n *\n * TODO: There's some dodgy code in seek() that allows floppy images to be dynamically\n * reconfigured with more heads and/or sectors/track, and it does so by peeking at more drive\n * properties. That code used to be in the FDC component, where it was perfectly reasonable\n * to access those properties. We need a cleaner interface back to the drive, similar to the\n * info() interface we provide to the controller.\n *\n * Whether or not the \"dynamic reconfiguration\" feature itself is perfectly reasonable is,\n * of course, a separate question.\n *\n * @this {DiskPDP11}\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {boolean} [fWrite]\n * @param {function(Object,boolean)} [done]\n * @return {Object|null} is the requested sector, or null if not found (or not available yet)\n */\n seek(iCylinder, iHead, iSector, fWrite, done)\n {\n var sector = null;\n var drive = this.drive;\n var cylinder = this.aDiskData[iCylinder];\n if (cylinder) {\n var i;\n var track = cylinder[iHead];\n /*\n * The following code allows a single-sided diskette image to be reformatted (ie, \"expanded\")\n * as a double-sided image, provided the drive has more than one head (see drive.nHeads).\n */\n if (!track && drive.bFormatting && iHead < drive.nHeads) {\n track = cylinder[iHead] = new Array(drive.bSectorEnd);\n for (i = 0; i < track.length; i++) {\n track[i] = this.initSector(null, iCylinder, iHead, i + 1, drive.nBytes, 0);\n }\n }\n if (track) {\n for (i = 0; i < track.length; i++) {\n if (track[i] && track[i]['sector'] == iSector) {\n /*\n * If the sector's pattern is null, then this sector's true contents have not yet\n * been fetched from the server.\n */\n sector = track[i];\n break;\n }\n }\n /*\n * The following code allows an 8-sector track to be reformatted (ie, \"expanded\") as a 9-sector track.\n */\n if (!sector && drive.bFormatting && drive.bSector == 9) {\n sector = track[i] = this.initSector(null, iCylinder, iHead, drive.bSector, drive.nBytes, 0);\n }\n }\n }\n if (done) done(sector, false);\n return sector;\n }\n\n /**\n * fill(sector, ab, off)\n *\n * @this {DiskPDP11}\n * @param {Object} sector\n * @param {*} ab (technically, this should be typed as Array.<number> but I'm having trouble coercing JSON.parse() to that)\n * @param {number} off\n */\n fill(sector, ab, off)\n {\n var cdw = sector['length'] >> 2;\n var adw = new Array(cdw);\n for (var idw = 0; idw < cdw; idw++) {\n adw[idw] = ab[off] | (ab[off + 1] << 8) | (ab[off + 2] << 16) | (ab[off + 3] << 24);\n off += 4;\n }\n sector['data'] = adw;\n /*\n * TODO: Consider taking this opportunity to shrink 'data' down by the number of dwords at the end of the buffer that\n * contain the same pattern, and setting 'pattern' accordingly.\n */\n }\n\n /**\n * toBytes(sector)\n *\n * @this {DiskPDP11}\n * @param {Object} sector\n * @return {Array.<number>} is an array of bytes\n */\n toBytes(sector)\n {\n var cb = sector['length'];\n var ab = new Array(cb);\n var ib = 0;\n var cdw = cb >> 2;\n var adw = sector['data'];\n var dwPattern = sector['pattern'];\n for (var idw = 0; idw < cdw; idw++) {\n var dw = (idw < adw.length? adw[idw] : dwPattern);\n ab[ib++] = dw & 0xff;\n ab[ib++] = (dw >> 8) & 0xff;\n ab[ib++] = (dw >> 16) & 0xff;\n ab[ib++] = (dw >> 24) & 0xff;\n }\n return ab;\n }\n\n /**\n * read(sector, ibSector, fCompare)\n *\n * @this {DiskPDP11}\n * @param {Object} sector (returned from a previous seek)\n * @param {number} ibSector a byte index within the given sector\n * @param {boolean} [fCompare] is true if this write-compare read\n * @return {number} the specified (unsigned) byte, or -1 if no more data in the sector\n */\n read(sector, ibSector, fCompare)\n {\n var b = -1;\n if (sector) {\n if (ibSector < sector['length']) {\n var adw = sector['data'];\n var idw = ibSector >> 2;\n var dw = (idw < adw.length ? adw[idw] : sector['pattern']);\n b = ((dw >> ((ibSector & 0x3) << 3)) & 0xff);\n }\n if (DEBUG && !fCompare && this.messageEnabled()) {\n this.printMessage('read(\"' + this.sDiskFile + '\",CHS=' + sector.iCylinder + ':' + sector.iHead + ':' + sector['sector'] + ',index=' + ibSector + ',value=' + Str.toHexByte(b) + ')');\n }\n }\n return b;\n }\n\n /**\n * write(sector, ibSector, b)\n *\n * @this {DiskPDP11}\n * @param {Object} sector (returned from a previous seek)\n * @param {number} ibSector a byte index within the given sector\n * @param {number} b the byte value to write\n * @return {boolean|null} true if write successful, false if write-protected, null if out of bounds\n */\n write(sector, ibSector, b)\n {\n if (this.fWriteProtected)\n return false;\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage('write(\"' + this.sDiskFile + '\",CHS=' + sector.iCylinder + ':' + sector.iHead + ':' + sector['sector'] + ',index=' + ibSector + ',value=' + Str.toHexByte(b) + ')');\n }\n\n if (ibSector < sector['length']) {\n if (b != this.read(sector, ibSector, true)) {\n var adw = sector['data'];\n var dwPattern = sector['pattern'];\n var idw = ibSector >> 2;\n var nShift = (ibSector & 0x3) << 3;\n\n /*\n * Ensure every byte up to the specified byte is properly initialized.\n */\n for (var i = adw.length; i <= idw; i++) adw[i] = dwPattern;\n\n if (!sector.cModify) {\n sector.iModify = idw;\n sector.cModify = 1;\n } else if (idw < sector.iModify) {\n sector.cModify += sector.iModify - idw;\n sector.iModify = idw;\n } else if (idw >= sector.iModify + sector.cModify) {\n sector.cModify += idw - (sector.iModify + sector.cModify) + 1;\n }\n adw[idw] = (adw[idw] & ~(0xff << nShift)) | (b << nShift);\n }\n return true;\n }\n return null;\n }\n\n /**\n * getSector(pba)\n *\n * @this {DiskPDP11}\n * @param {number} pba (physical block address)\n * @return {Object|null} sector\n */\n getSector(pba)\n {\n var nSectorsPerCylinder = this.nHeads * this.nSectors;\n var iCylinder = (pba / nSectorsPerCylinder) | 0;\n if (iCylinder < this.nCylinders) {\n var nSectorsRemaining = (pba % nSectorsPerCylinder);\n var iHead = (nSectorsRemaining / this.nSectors) | 0;\n /*\n * PBA numbers are 0-based, but the sector numbers in CHS addressing are 1-based, so add one to iSector\n */\n var iSector = (nSectorsRemaining % this.nSectors) + 1;\n return this.seek(iCylinder, iHead, iSector);\n }\n return null;\n }\n\n /**\n * getSectorData(sector, off, len)\n *\n * WARNING: This function is restricted to reading data contained ENTIRELY within the specified sector.\n *\n * NOTE: Yes, this function is not the most efficient way to read a byte/word/dword value from within a sector,\n * but given the different states a sector may be in, it's certainly the simplest and safest, and since this is\n * only used by buildFileTable() and its progeny, it's not clear that we need to be superfast anyway.\n *\n * @this {DiskPDP11}\n * @param {Object} sector\n * @param {number} off (byte offset)\n * @param {number} len (1 to 4 bytes)\n * @return {number}\n */\n getSectorData(sector, off, len)\n {\n var dw = 0;\n var nShift = 0;\n\n while (len--) {\n\n var b = this.read(sector, off++);\n\n if (b < 0) break;\n dw |= (b << nShift);\n nShift += 8;\n }\n return dw;\n }\n\n /**\n * encodeAsBase64()\n *\n * @this {DiskPDP11}\n * @return {string}\n */\n encodeAsBase64()\n {\n /*\n * Gross, but simple; more importantly, it works -- at least for disks of typical floppy magnitude.\n */\n var s = \"\", pba = 0, sector;\n while ((sector = this.getSector(pba++))) {\n for (var off = 0, len = sector['length']; off < len; off++) {\n s += String.fromCharCode(this.getSectorData(sector, off, 1));\n }\n }\n return btoa(s);\n }\n\n /**\n * save()\n *\n * The first array entry contains some disk information:\n *\n * [sDiskPath, dwChecksum, nCylinders, nHeads, nSectors, cbSector]\n *\n * Each subsequent entry in the returned array contains the following:\n *\n * [iCylinder, iHead, iSector, iModify, [...]]\n *\n * where [...] is an array of modified dword(s) in the corresponding sector.\n *\n * @this {DiskPDP11}\n * @return {Array} of modified sectors\n */\n save()\n {\n var i = 0;\n var deltas = [];\n deltas[i++] = [this.sDiskPath, this.dwChecksum, this.nCylinders, this.nHeads, this.nSectors, this.cbSector];\n if (!this.fWriteProtected) {\n var aDiskData = this.aDiskData;\n for (var iCylinder = 0; iCylinder < aDiskData.length; iCylinder++) {\n for (var iHead = 0; iHead < aDiskData[iCylinder].length; iHead++) {\n for (var iSector = 0; iSector < aDiskData[iCylinder][iHead].length; iSector++) {\n var sector = aDiskData[iCylinder][iHead][iSector];\n if (sector && sector.cModify) {\n var mods = [], n = 0;\n var iModify = sector.iModify, iModifyLimit = sector.iModify + sector.cModify;\n while (iModify < iModifyLimit) {\n mods[n++] = sector['data'][iModify++];\n }\n deltas[i++] = [iCylinder, iHead, iSector, sector.iModify, mods];\n }\n }\n }\n }\n }\n if (DEBUG && this.messageEnabled()) {\n this.printMessage('save(\"' + this.sDiskName + '\"): saved ' + (deltas.length - 1) + ' change(s)');\n }\n return deltas;\n }\n\n /**\n * restore(deltas)\n *\n * The first array entry contains some disk information:\n *\n * [sDiskPath, dwChecksum, nCylinders, nHeads, nSectors, cbSector]\n *\n * Each subsequent entry in the supplied array contains the following:\n *\n * [iCylinder, iHead, iSector, iModify, [...]]\n *\n * where [...] is an array of modified dword(s) in the corresponding sector.\n *\n * @this {DiskPDP11}\n * @param {Array} deltas\n * @return {number} 0 if no changes applied, -1 if an error occurred, otherwise the number of sectors modified\n */\n restore(deltas)\n {\n /*\n * If deltas is undefined, that's not necessarily an error; the controller may simply be (re)initializing\n * itself (although neither controller should be calling restore() under those conditions anymore).\n */\n var nChanges = 0;\n var sReason = \"unsupported restore format\";\n /*\n * I originally added a check for aDiskData here on the assumption that if there was an error loading\n * a disk image, we will have already notified the user, so any additional errors about differing checksums,\n * failure to restore the disk state, etc, would just be annoying. HOWEVER, HDC will create an empty disk\n * image if its initialization code discovers that no disk was loaded earlier (see verifyDrive). So while\n * checking aDiskData is still a good idea, be aware that it won't necessarily avoid redundant error messages\n * (at least in the case of HDC).\n */\n if (deltas && deltas.length > 0) {\n\n var i = 0;\n var aDiskInfo = deltas[i++];\n\n if (aDiskInfo && aDiskInfo.length >= 2) {\n /*\n * Before getting to the checksum, we have to deal with a new situation: restoring an uninitialized\n * disk image from a complete set of deltas. And that is only possible if the disk was saved with the\n * original disk geometry.\n */\n if (!this.aDiskData.length && aDiskInfo.length >= 6) {\n this.create(DiskAPI.MODE.LOCAL, aDiskInfo[2], aDiskInfo[3], aDiskInfo[4], aDiskInfo[5]);\n /*\n * TODO: Consider setting a flag here that we can check at the end of the restore() function\n * that indicates we should recalculate dwChecksum, because we currently have an inconsistency\n * between local disks that are mounted via build() and the same disks that are \"remounted\"\n * later by this code; the former has the correct checksum, while the latter has a null checksum.\n *\n * As you can see below, we currently deal with this by simply ignoring null checksums....\n */\n }\n /*\n * v1.01 failed to indicate an error if either one of these failure conditions occurred. Although maybe that's\n * just as well, since v1.01 also failed to properly deal with situations where the user mounted different diskette(s)\n * prior to exiting (hopefully fixed in v1.02).\n */\n else if (aDiskInfo[1] != null && this.dwChecksum != null && aDiskInfo[1] != this.dwChecksum) {\n sReason = \"original checksum (\" + aDiskInfo[1] + \") differs from current checksum (\" + this.dwChecksum + \")\";\n nChanges = -2;\n }\n /*\n * Checksum is more important than disk path, and for now, I want the flexibility to move disk images.\n *\n else if (aDiskInfo[0] != this.sDiskPath) {\n sReason = \"original path '\" + aDiskInfo[0] + \"' differs from current path '\" + this.sDiskPath + \"'\";\n nChanges = -1;\n }\n */\n }\n\n if (!this.aDiskData.length) nChanges = -1;\n\n while (i < deltas.length && nChanges >= 0) {\n var m = 0;\n var mod = deltas[i++];\n var iCylinder = mod[m++];\n var iHead = mod[m++];\n var iSector = mod[m++];\n /*\n * Note the buried test for write-protection. Yes, an invariant condition should be tested\n * outside the loop, not inside, but (a) it's a trivial test, (b) the test should never fail\n * because save() should never generate any mods for a write-protected disk, and (c) it\n * centralizes all the failure conditions we're currently checking (which, admittedly, ain't much).\n */\n if (iCylinder >= this.aDiskData.length || iHead >= this.aDiskData[iCylinder].length || iSector >= this.aDiskData[iCylinder][iHead].length) {\n sReason = \"sector (CHS=\" + iCylinder + ':' + iHead + ':' + iSector + \") out of range (\" + nChanges + \" changes applied)\";\n nChanges = -1;\n break;\n }\n if (this.fWriteProtected) {\n sReason = \"unable to modify write-protected disk\";\n nChanges = -1;\n break;\n }\n var iModify = mod[m++];\n var mods = mod[m++];\n var iModifyLimit = iModify + mods.length;\n var sector = this.aDiskData[iCylinder][iHead][iSector];\n if (!sector) continue;\n /*\n * Since write() now deals with empty/partial sectors, we no longer need to completely \"inflate\"\n * the sector prior to applying modifications. So let's just make sure that the sector is \"inflated\"\n * up to iModify.\n */\n var idw = sector['data'].length;\n while (idw < iModify) {\n sector['data'][idw++] = sector['pattern'];\n }\n var n = 0;\n sector.iModify = iModify;\n sector.cModify = mods.length;\n while (iModify < iModifyLimit) {\n sector['data'][iModify++] = mods[n++];\n }\n nChanges++;\n }\n }\n\n if (nChanges < 0) {\n /*\n * We're suppressing checksum messages for the general public for now....\n */\n if (DEBUG || nChanges != -2) {\n this.controller.notice(\"Unable to restore disk '\" + this.sDiskName + \": \" + sReason);\n }\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage('restore(\"' + this.sDiskName + '\"): restored ' + nChanges + ' change(s)');\n }\n }\n return nChanges;\n }\n\n /**\n * convertToJSON(fFormatted)\n *\n * We perform some RegExp massaging on the JSON data to eliminate unnecessary properties\n * (eg, 'length' values of 512, 'pattern' values of 0, since those are defaults).\n *\n * In addition, we first check every sector to see if it can be \"deflated\". Sectors that were\n * initially \"deflated\" should remain that way unless/until they were modified, so technically,\n * we could call deflateSector() just for modified sectors, but this isn't a common operation,\n * so it doesn't hurt to check every sector.\n *\n * @this {DiskPDP11}\n * @param {boolean} [fFormatted]\n * @return {string} containing the entire disk image as JSON-encoded data\n */\n convertToJSON(fFormatted)\n {\n var s, pba = 0, sector, sectorLast;\n\n while ((sector = this.getSector(pba++))) {\n this.deflateSector(sector);\n }\n\n s = JSON.stringify(this.aDiskData, function(key, value) {\n /*\n * If BACKTRACK support is enabled, we have to filter out any 'file' properties that may\n * be attached to the sector objects, lest we risk blowing the stack due to circular references.\n */\n if (key == 'file') {\n return undefined;\n }\n return value;\n });\n\n /*\n * Eliminate unnecessary default properties (eg, 'length' values of 512, 'pattern' values of 0).\n */\n s = s.replace(/,\"length\":512/g, \"\").replace(/,\"pattern\":0/g, \"\");\n\n /*\n * I don't really want to strip quotes from disk image property names, since I would have to put them\n * back again during mount() -- or whenever JSON.parse() is used instead of eval(). But I still remove\n * them temporarily, so that any remaining property names (eg, \"iModify\", \"cModify\", \"fDirty\") can\n * easily be stripped out, by virtue of their being the only quoted properties left. We then \"requote\"\n * all the property names that remain.\n */\n s = s.replace(/\"(sector|length|data|pattern)\":/g, \"$1:\");\n\n /*\n * The next line will remove any other numeric or boolean properties that were added at runtime, although\n * they may have completely different (\"minified\") names if the code has been compiled.\n */\n s = s.replace(/,\"[^\"]*\":([0-9]+|true|false)/g, \"\");\n s = s.replace(/(sector|length|data|pattern):/g, \"\\\"$1\\\":\");\n\n /*\n * Last but not least, insert line breaks after every object definition, to improve human readability\n * (but only if the caller asks for it).\n */\n if (fFormatted) s = s.replace(/([\\]}]),/g, \"$1,\\n\");\n return s;\n }\n\n /**\n * deflateSector(sector)\n *\n * This is just the first revision: it currently looks only at fully inflated sectors.\n *\n * @this {DiskPDP11}\n * @param {Object} sector\n */\n deflateSector(sector)\n {\n var adw = sector['data'];\n var cdw = adw.length;\n if ((cdw << 2) == sector['length']) {\n var idw = cdw - 1;\n var dwPattern = adw[idw], cDupes = 0;\n while (idw--) {\n if (adw[idw] !== dwPattern) break;\n cDupes++;\n }\n if (cDupes++) {\n adw.length = cdw - cDupes;\n sector['pattern'] = dwPattern;\n }\n }\n }\n\n /**\n * dumpSector(sector, pba, sDesc)\n *\n * @this {DiskPDP11}\n * @param {Object} sector (returned from a previous seek)\n * @param {number} [pba]\n * @param {string} [sDesc]\n * @return {string}\n */\n dumpSector(sector, pba, sDesc)\n {\n var sDump = \"\";\n if (DEBUG && sector) {\n if (pba != null) sDump += \"sector \" + pba + (sDesc? (\" for \" + sDesc) : \"\") + ':';\n var sBytes = \"\", sChars = \"\";\n var cbSector = sector['length'];\n var cdwData = sector['data'].length;\n var dw = 0;\n for (var i = 0; i < cbSector; i++) {\n if ((i % 16) === 0) {\n if (sDump) sDump += sBytes + ' ' + sChars + '\\n';\n sDump += Str.toHex(i, 4) + \": \";\n sBytes = sChars = \"\";\n }\n if ((i % 4) === 0) {\n var idw = i >> 2;\n dw = (idw < cdwData? sector['data'][idw] : sector['pattern']);\n }\n var b = dw & 0xff;\n dw >>>= 8;\n sBytes += Str.toHex(b, 2) + (i % 16 == 7? \"-\" : \" \");\n sChars += (b >= 32 && b < 128? String.fromCharCode(b) : \".\");\n }\n if (sBytes) sDump += sBytes + ' ' + sChars;\n }\n return sDump;\n }\n}\n\n/*\n * A global disk count, used to form unique Disk component IDs (totally optional; for debugging purposes only)\n */\nDiskPDP11.nDisks = 0;\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/drive.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * @typedef {{\n * PRI: number,\n * VEC: number,\n * DRIVES: number\n * }}\n */\nvar Config;\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * Component class, because otherwise the Compiler won't allow us to *reference* the named\n * property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass DriveController extends Component {\n /**\n * DriveController(type, parms, bitsMessage, configDC, configDrive, configIO)\n *\n * The DriveController component has the following component-specific (parms) properties:\n *\n * autoMount: one or more JSON-encoded objects, each containing 'name' and 'path' properties\n *\n * @this {DriveController}\n * @param {string} type\n * @param {Object} parms\n * @param {number} bitsMessage\n * @param {Config} configDC\n * @param {Array} configDrive\n * @param {Object} configIO\n */\n constructor(type, parms, bitsMessage, configDC, configDrive, configIO)\n {\n super(type, parms, bitsMessage);\n\n /*\n * We preliminarily parse and record any 'autoMount' object now, but we no longer process it\n * until initBus(), because the Computer's getMachineParm() service may have an override for us.\n */\n this.configMount = this.parseConfig(parms['autoMount']);\n this.cAutoMount = 0;\n\n this.configDC = configDC;\n this.configDrive = configDrive;\n this.configIO = configIO;\n\n this.nDrives = configDC.DRIVES;\n this.aDrives = new Array(this.nDrives);\n this.fLocalDisks = (!Web.isMobile() && window && 'FileReader' in window);\n this.sDiskSource = DriveController.SOURCE.NONE;\n\n /*\n * The following array keeps track of every disk image we've ever mounted. Each entry in the\n * array is another array whose elements are:\n *\n * [0]: name of disk\n * [1]: path of disk\n * [2]: array of deltas, uninitialized until the disk is unmounted and/or all state is saved\n *\n * See functions addDiskHistory() and updateDiskHistory().\n */\n this.aDiskHistory = [];\n\n this.irq = null;\n\n this['exports'] = {\n 'bootDisk': this.bootSelectedDisk,\n 'loadDisk': this.loadSelectedDisk,\n 'selectDrive': this.selectDrive,\n 'wait': this.waitDrives\n };\n }\n\n /**\n * parseConfig(config)\n *\n * @this {DriveController}\n * @param {*} config\n * @return {*}\n */\n parseConfig(config)\n {\n if (config && typeof config == \"string\") {\n try {\n /*\n * The most likely source of any exception will be right here, where we're parsing\n * this JSON-encoded data.\n */\n config = eval(\"(\" + config + \")\");\n } catch (e) {\n Component.error(this.type + \" auto-mount error: \" + e.message + \" (\" + config + \")\");\n config = null;\n }\n }\n return config || {};\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {DriveController}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"list\", \"text\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"listDisks\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var dc = this;\n\n switch (sBinding) {\n\n case \"listDisks\":\n this.bindings[sBinding] = control;\n control.onchange = function onChangeListDisks(event) {\n dc.updateSelectedDisk();\n };\n return true;\n\n case \"descDisk\":\n case \"listDrives\":\n this.bindings[sBinding] = control;\n /*\n * I tried going with onclick instead of onchange, so that if you wanted to confirm what's\n * loaded in a particular drive, you could click the drive control without having to change it.\n * However, that doesn't seem to work for all browsers, so I've reverted to onchange.\n */\n var controlSelect = /** @type {HTMLSelectElement} */ (control);\n control.onchange = function onChangeListDrives(event) {\n var iDrive = Str.parseInt(controlSelect.value, 10);\n if (iDrive != null) dc.displayDisk(iDrive);\n };\n return true;\n\n case \"loadDisk\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickLoadDrive(event) {\n dc.loadSelectedDisk();\n };\n return true;\n\n case \"bootDisk\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickBootDisk(event) {\n dc.bootSelectedDisk();\n };\n return true;\n\n case \"saveDisk\":\n /*\n * Yes, technically, this feature does not require \"Local disk support\" (which is really a reference\n * to FileReader support), but since fLocalDisks is also false for all mobile devices, and since there\n * is an \"orthogonality\" to disabling both features in tandem, let's just let it slide, OK?\n */\n if (!this.fLocalDisks) {\n if (DEBUG) this.log(\"Local disk support not available\");\n /*\n * We could also simply hide the control; eg:\n *\n * control.style.display = \"none\";\n *\n * but removing the control altogether seems better.\n */\n control.parentNode.removeChild(/** @type {Node} */ (control));\n return false;\n }\n\n this.bindings[sBinding] = control;\n\n control.onclick = function onClickSaveDrive(event) {\n var controlDrives = dc.bindings[\"listDrives\"];\n if (controlDrives && controlDrives.options && dc.aDrives) {\n var iDriveSelected = Str.parseInt(controlDrives.value, 10) || 0;\n var drive = dc.aDrives[iDriveSelected];\n if (drive) {\n /*\n * Note the similarity (and hence factoring opportunity) between this code and the HDC's \"saveHD*\" binding.\n */\n var disk = drive.disk;\n if (disk) {\n if (DEBUG) dc.println(\"saving disk \" + disk.sDiskPath + \"...\");\n var sAlert = Web.downloadFile(disk.encodeAsBase64(), \"octet-stream\", true, disk.sDiskFile.replace(\".json\", \".img\"));\n Component.alertUser(sAlert);\n } else {\n dc.notice(\"No disk loaded in drive.\");\n }\n } else {\n dc.notice(\"No disk drive selected.\");\n }\n }\n };\n return true;\n\n case \"mountDisk\":\n var controlInput = /** @type {Object} */ (control);\n\n if (!this.fLocalDisks) {\n if (DEBUG) this.log(\"Local disk support not available\");\n /*\n * We could also simply hide the control; eg:\n *\n * controlInput.style.display = \"none\";\n *\n * but removing the control altogether seems better.\n */\n controlInput.parentNode.removeChild(/** @type {Node} */ (controlInput));\n return false;\n }\n\n this.bindings[sBinding] = controlInput;\n\n /*\n * Enable \"Mount\" button only if a file is actually selected\n */\n controlInput.addEventListener('change', function() {\n var fieldset = controlInput.children[0];\n var files = fieldset.children[0].files;\n var submit = fieldset.children[1];\n submit.disabled = !files.length;\n });\n\n controlInput.onsubmit = function(event) {\n var file = event.currentTarget[1].files[0];\n if (file) {\n var sDiskPath = file.name;\n var sDiskName = Str.getBaseName(sDiskPath, true);\n dc.loadSelectedDisk(sDiskName, sDiskPath, file);\n }\n /*\n * Prevent reloading of web page after form submission\n */\n return false;\n };\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * initBus(cmp, bus, cpu, dbg)\n *\n * @this {DriveController}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.cmp = cmp;\n this.bus = bus;\n this.cpu = cpu;\n this.dbg = dbg;\n\n var configMount = this.parseConfig(this.cmp.getMachineParm('autoMount'));\n\n /*\n * Add only drives from the machine-wide autoMount configuration that match drives managed by this component.\n */\n if (configMount) {\n for (var sDrive in configMount) {\n if (sDrive.substr(0, 2) != this.type.substr(0, 2)) continue;\n this.configMount[sDrive] = configMount[sDrive];\n }\n }\n\n /*\n * If we didn't need auto-mount support, we could defer controller and drive initialization until we received\n * a powerUp() notification, at which point reset() would call initController(), or restore() would restore the\n * controller.\n */\n this.reset();\n\n this.irq = this.cpu.addIRQ(this.configDC.VEC, this.configDC.PRI, this.bitsMessage);\n\n bus.addIOTable(this, this.configIO);\n bus.addResetHandler(this.reset.bind(this));\n\n this.addDisk(\"None\", DriveController.SOURCE.NONE, true);\n if (this.fLocalDisks) this.addDisk(\"Local Disk\", DriveController.SOURCE.LOCAL);\n this.addDisk(\"Remote Disk\", DriveController.SOURCE.REMOTE);\n\n if (!this.autoMount()) this.setReady();\n }\n\n /**\n * getDriveName(iDrive)\n *\n * Form a drive name using the two-letter controller type prefix and the drive number.\n *\n * @this {DriveController}\n * @param {number} iDrive\n * @return {string}\n */\n getDriveName(iDrive)\n {\n var drive = this.aDrives[iDrive];\n return drive.sName || \"---\";\n }\n\n /**\n * getDriveNumber(sDrive)\n *\n * @this {DriveController}\n * @param {string} sDrive\n * @return {number} (0-3, or -1 if error)\n */\n getDriveNumber(sDrive)\n {\n var iDrive = -1;\n if (sDrive) {\n iDrive = sDrive.charCodeAt(sDrive.length - 1) - 0x30;\n if (iDrive < 0 || iDrive > 9) iDrive = -1;\n }\n return iDrive;\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {DriveController}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n if (!data) {\n this.reset();\n if (this.cmp.fReload) {\n /*\n * If the computer's fReload flag is set, we're required to toss all currently\n * loaded disks and remount all disks specified in the auto-mount configuration.\n */\n this.unloadAllDrives(true);\n this.autoMount(true);\n }\n } else {\n if (!this.restore(data)) return false;\n }\n /*\n * Populate the HTML controls to match the actual (well, um, specified) number of floppy drives.\n */\n var controlDrives;\n if ((controlDrives = this.bindings['listDrives'])) {\n while (controlDrives.firstChild) {\n controlDrives.removeChild(controlDrives.firstChild);\n }\n controlDrives.value = \"\";\n for (var iDrive = 0; iDrive < this.nDrives; iDrive++) {\n var controlOption = document.createElement(\"option\");\n controlOption.value = iDrive;\n controlOption.text = this.getDriveName(iDrive);\n controlDrives.appendChild(controlOption);\n }\n if (this.nDrives > 0) {\n controlDrives.value = \"0\";\n this.displayDisk(0);\n }\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {DriveController}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure\n */\n powerDown(fSave, fShutdown)\n {\n return fSave? this.save() : true;\n }\n\n /**\n * reset()\n *\n * @this {DriveController}\n */\n reset()\n {\n this.initController();\n this.initDrives();\n }\n\n /**\n * save()\n *\n * This implements save support for the DriveController component.\n *\n * @this {DriveController}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.saveController());\n state.set(1, this.saveHistory());\n state.set(2, this.saveDrives());\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements restore support for the DriveController component.\n *\n * @this {DriveController}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var fSuccess = true;\n if (!this.initController(data[0])) fSuccess = false;\n if (!this.initHistory(data[1])) fSuccess = false;\n if (!this.initDrives(data[2])) fSuccess = false;\n return fSuccess;\n }\n\n /**\n * initController(aRegs)\n *\n * Placeholder for subclasses.\n *\n * @this {DriveController}\n * @param {Array} [aRegs]\n * @return {boolean} true if successful, false if failure\n */\n initController(aRegs)\n {\n return true;\n }\n\n /**\n * saveController()\n *\n * Placeholder for subclasses.\n *\n * @this {DriveController}\n * @return {Array}\n */\n saveController()\n {\n return [];\n }\n\n /**\n * initDrive(drive, iDrive, configDrive, configDisk)\n *\n * @this {DriveController}\n * @param {Object} drive\n * @param {number} iDrive\n * @param {Array} configDrive\n * @param {Array} [configDisk]\n * @return {boolean} true if successful, false if failure\n */\n initDrive(drive, iDrive, configDrive, configDisk)\n {\n var i = 0;\n var fSuccess = true;\n\n drive.iDrive = iDrive;\n drive.name = this.idComponent;\n drive.fBusy = drive.fLocal = false;\n drive.fnCallReady = null;\n drive.fRemovable = true;\n\n /*\n * NOTE: We initialize the following drive properties to their MAXIMUMs; disks may have\n * these or SMALLER values (subject to the limits of what the controller supports, of course).\n */\n drive.sName = configDrive[i++] + iDrive;\n drive.nCylinders = configDrive[i++];\n drive.nHeads = configDrive[i++];\n drive.nSectors = configDrive[i++];\n drive.cbSector = configDrive[i++];\n drive.iCylinderBoot = configDrive[i++];\n drive.iHeadBoot = configDrive[i++];\n drive.iSectorBoot = configDrive[i++];\n drive.cbSectorBoot = configDrive[i++];\n drive.status = configDrive[i];\n\n /*\n * The next group of properties are set by various controller command sequences.\n */\n drive.bHead = 0;\n drive.bCylinder = 0;\n drive.bSector = 1;\n drive.bSectorEnd = drive.nSectors; // aka EOT\n drive.nBytes = drive.cbSector;\n\n /*\n * The next group of properties are managed by worker functions (eg, doRead()) to maintain state across DMA requests.\n */\n drive.ibSector = 0;\n drive.sector = null;\n\n if (!drive.disk) {\n drive.sDiskPath = \"\"; // ensure this is initialized to a default that displayDisk() can deal with\n }\n\n if (configDisk) {\n var fLocal = configDisk[0];\n var sDiskName = configDisk[1];\n var sDiskPath = configDisk[2];\n /*\n * If we're restoring a local disk image, then the entire disk contents should be captured in aDiskHistory,\n * so all we have to do is mount a blank disk and let disk.restore() do the rest; ie, there's nothing to\n * \"load\" (it's a purely synchronous operation).\n *\n * Otherwise, we must call loadDrive(); in the common case, loadDrive() will have already \"auto-mounted\"\n * the disk, so it will return true, and then we restore any deltas to the current image.\n *\n * However, if loadDrive() returns false, then it has initiated the load for a *different* disk image,\n * so we must mark ourselves as \"not ready\" again, and add another \"wait for ready\" test in Computer before\n * finally powering the CPU.\n */\n if (fLocal) {\n this.mountDrive(iDrive, sDiskName, sDiskPath);\n }\n else if (this.loadDrive(iDrive, sDiskName, sDiskPath, true)) {\n if (drive.disk) {\n if (sDiskPath) {\n this.addDiskHistory(sDiskName, sDiskPath, drive.disk);\n } else {\n if (MAXDEBUG) Component.warning(\"Disk '\" + (drive.disk.sDiskName || sDiskName) + \"' not recorded properly in drive \" + iDrive);\n }\n }\n } else {\n this.setReady(false);\n }\n }\n return fSuccess;\n }\n\n /**\n * initDrives(aConfigDisks)\n *\n * @this {DriveController}\n * @param {Array} [aConfigDisks]\n * @return {boolean} true if successful, false if failure\n */\n initDrives(aConfigDisks)\n {\n var fSuccess = true;\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n var drive = this.aDrives[iDrive];\n if (drive === undefined) {\n drive = this.aDrives[iDrive] = {};\n }\n var configDisk = aConfigDisks && aConfigDisks[iDrive];\n if (!this.initDrive(drive, iDrive, this.configDrive, configDisk)) {\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * saveDrive(drive)\n *\n * @this {DriveController}\n * @param {Object} drive\n * @return {Array}\n */\n saveDrive(drive)\n {\n return [\n drive.fLocal,\n drive.sDiskName,\n drive.sDiskPath\n ]\n }\n\n /**\n * saveDrives()\n *\n * @this {DriveController}\n * @return {Array}\n */\n saveDrives()\n {\n var data = [];\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n data.push(this.saveDrive(this.aDrives[iDrive]));\n }\n return data;\n }\n\n /**\n * initHistory(aHistory)\n *\n * @this {DriveController}\n * @param {Array} [aHistory]\n * @return {boolean} true if successful, false if failure\n */\n initHistory(aHistory)\n {\n /*\n * Initialize the disk history (if available) before initializing the drives, so that any disk deltas can be\n * applied to disk images that are already loaded.\n */\n if (aHistory) this.aDiskHistory = aHistory;\n\n return true;\n }\n\n /**\n * saveHistory()\n *\n * This returns an array of entries, one for each disk image we've ever mounted, including any deltas; ie:\n *\n * [name, path, deltas]\n *\n * aDiskHistory contains exactly that, except that deltas may not be up-to-date for any currently mounted\n * disk image(s), so we call updateHistory() for all those disks, and then aDiskHistory is ready to be saved.\n *\n * @this {DriveController}\n * @return {Array}\n */\n saveHistory()\n {\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n var drive = this.aDrives[iDrive];\n if (drive.disk) {\n this.updateDiskHistory(drive.sDiskName, drive.sDiskPath, drive.disk);\n }\n }\n return this.aDiskHistory;\n }\n\n /**\n * autoMount(fRemount)\n *\n * @this {DriveController}\n * @param {boolean} [fRemount] is true if we're remounting all auto-mounted disks\n * @return {boolean} true if one or more disk images are being auto-mounted, false if none\n */\n autoMount(fRemount)\n {\n if (!fRemount) this.cAutoMount = 0;\n for (var sDrive in this.configMount) {\n var configDisk = this.configMount[sDrive];\n var sDiskPath = configDisk['path'] || \"\";\n var sDiskName = configDisk['name'] || this.findDisk(sDiskPath);\n if (sDiskPath && sDiskName) {\n var iDrive = this.getDriveNumber(sDrive);\n if (iDrive >= 0 && iDrive < this.aDrives.length) {\n if (!this.loadDrive(iDrive, sDiskName, sDiskPath, true) && fRemount) {\n this.setReady(false);\n }\n continue;\n }\n }\n this.notice(\"Incorrect auto-mount settings for drive \" + sDrive + \" (\" + JSON.stringify(configDisk) + \")\");\n }\n return !!this.cAutoMount;\n }\n\n /**\n * loadSelectedDisk(sDiskName, sDiskPath, file)\n *\n * @this {DriveController}\n * @param {string} [sDiskName]\n * @param {string} [sDiskPath]\n * @param {File} [file] is set if there's an associated File object\n * @return {boolean}\n */\n loadSelectedDisk(sDiskName, sDiskPath, file)\n {\n if (!sDiskName && !sDiskPath) {\n var controlDisks = this.bindings[\"listDisks\"];\n if (controlDisks && controlDisks.options) {\n sDiskName = controlDisks.options[controlDisks.selectedIndex].text;\n sDiskPath = controlDisks.value;\n }\n }\n\n var controlDrives = this.bindings[\"listDrives\"];\n var iDrive = controlDrives && Str.parseInt(controlDrives.value, 10);\n\n if (iDrive === undefined || iDrive < 0 || iDrive >= this.aDrives.length) {\n this.notice(\"Unable to load the selected drive\");\n return false;\n }\n\n if (!sDiskPath) {\n this.unloadDrive(iDrive);\n return true;\n }\n\n if (sDiskPath == DriveController.SOURCE.LOCAL) {\n this.notice('Use \"Choose File\" and \"Mount\" to select and load a local disk.');\n return false;\n }\n\n /*\n * If the special DriveController.SOURCE.REMOTE path is selected, then we want to prompt the user for a URL.\n * Oh, and make sure we pass an empty string as the 2nd parameter to prompt(), so that IE won't display\n * \"undefined\" -- because after all, undefined and \"undefined\" are EXACTLY the same thing, right?\n *\n * TODO: This is literally all I've done to support remote disk images. There's probably more\n * I should do, like dynamically updating \"listDisks\" to include new entries, and adding new entries\n * to the save/restore data.\n */\n if (sDiskPath == DriveController.SOURCE.REMOTE) {\n sDiskPath = window.prompt(\"Enter the URL of a remote disk image.\", \"\") || \"\";\n if (!sDiskPath) return false;\n sDiskName = Str.getBaseName(sDiskPath);\n this.status(\"Attempting to load \" + sDiskPath + \" as \\\"\" + sDiskName + \"\\\"\");\n this.sDiskSource = DriveController.SOURCE.REMOTE;\n }\n else {\n this.sDiskSource = sDiskPath;\n }\n\n this.loadDrive(iDrive, sDiskName, sDiskPath, false, file);\n return true;\n }\n\n /**\n * bootSelectedDisk()\n *\n * @this {DriveController}\n * @return {boolean}\n */\n bootSelectedDisk()\n {\n var drive;\n var controlDrives = this.bindings[\"listDrives\"];\n var iDrive = controlDrives && Str.parseInt(controlDrives.value, 10);\n\n if (iDrive == null || iDrive < 0 || iDrive >= this.aDrives.length || !(drive = this.aDrives[iDrive])) {\n this.notice(\"Unable to boot the selected drive\");\n return false;\n }\n\n if (!drive.disk) {\n this.notice(\"Load a disk into the drive first\");\n return false;\n }\n\n /*\n * NOTE: We're calling setReset() BEFORE reading the boot code in order to eliminate any side-effects\n * of the previous state of either the controller OR the CPU; for example, we don't want any previous MMU\n * or UNIBUS Map registers affecting the simulated readData() call. Also, some boot code (eg, RSTS/E)\n * expects the controller to be in a READY state; since setReset() triggers a call to our reset() handler,\n * a READY state is assured, and the readData() call shouldn't do anything to change that.\n */\n this.cpu.setReset(0, true, iDrive);\n\n var err = this.readData(drive, drive.iCylinderBoot, drive.iHeadBoot, drive.iSectorBoot, drive.cbSectorBoot, 0x0000, 2);\n if (err) {\n this.notice(\"Unable to read the boot sector (\" + err + \")\");\n return false;\n }\n return true;\n }\n\n /**\n * mountDrive(iDrive, sDiskName, sDiskPath)\n *\n * @this {DriveController}\n * @param {number} iDrive\n * @param {string} sDiskName\n * @param {string} sDiskPath\n */\n mountDrive(iDrive, sDiskName, sDiskPath)\n {\n var drive = this.aDrives[iDrive];\n this.unloadDrive(iDrive, true);\n drive.fLocal = true;\n var disk = new DiskPDP11(this, drive, DiskAPI.MODE.PRELOAD);\n this.doneLoadDrive(drive, disk, sDiskName, sDiskPath, true);\n }\n\n /**\n * loadDrive(iDrive, sDiskName, sDiskPath, fAutoMount, file)\n *\n * NOTE: If sDiskPath is already loaded, nothing needs to be done.\n *\n * @this {DriveController}\n * @param {number} iDrive\n * @param {string} sDiskName\n * @param {string} sDiskPath\n * @param {boolean} [fAutoMount]\n * @param {File} [file] is set if there's an associated File object\n * @return {number} 1 if disk loaded, 0 if queued up (or busy), -1 if already loaded\n */\n loadDrive(iDrive, sDiskName, sDiskPath, fAutoMount, file)\n {\n var nResult = -1;\n var drive = this.aDrives[iDrive];\n\n if (drive.sDiskPath.toLowerCase() != sDiskPath.toLowerCase()) {\n\n nResult++;\n this.unloadDrive(iDrive, true);\n\n if (drive.fBusy) {\n this.notice(this.type + \" busy\");\n }\n else {\n // this.status(\"disk queued: \" + sDiskName);\n drive.fBusy = true;\n if (fAutoMount) {\n drive.fAutoMount = true;\n this.cAutoMount++;\n if (this.messageEnabled()) this.printMessage(\"auto-loading disk: \" + sDiskName);\n }\n drive.fLocal = !!file;\n var disk = new DiskPDP11(this, drive, DiskAPI.MODE.PRELOAD);\n if (disk.load(sDiskName, sDiskPath, file, this.doneLoadDrive)) {\n nResult++;\n }\n }\n }\n return nResult;\n }\n\n /**\n * doneLoadDrive(drive, disk, sDiskName, sDiskPath, fAutoMount)\n *\n * The disk parameter is set if the disk was successfully loaded, null if not.\n *\n * @this {DriveController}\n * @param {Object} drive\n * @param {DiskPDP11} disk\n * @param {string} sDiskName\n * @param {string} sDiskPath\n * @param {boolean} [fAutoMount]\n */\n doneLoadDrive(drive, disk, sDiskName, sDiskPath, fAutoMount)\n {\n drive.fBusy = false;\n\n if (disk) {\n /*\n * TODO: While this is a perfectly reasonable thing to do, one wonders if the Disk object shouldn't\n * have done this itself, since we passed our Drive object to it (it already knows the drive's limits).\n */\n if (disk.nCylinders > drive.nCylinders || disk.nHeads > drive.nHeads /* || disk.nSectors > drive.nSectors */) {\n this.notice(\"Disk \\\"\" + sDiskName + \"\\\" too large for drive \" + this.getDriveName(drive.iDrive));\n disk = null;\n }\n }\n\n if (disk) {\n drive.disk = disk;\n drive.sDiskName = sDiskName;\n drive.sDiskPath = sDiskPath;\n\n /*\n * Inform the controller implementation (eg, RX11) of the disk change.\n */\n this.notifyLoad(drive.iDrive);\n\n /*\n * Adding local disk image names to the disk list seems like a nice idea, but it's too confusing,\n * because then it looks like the \"Mount\" button should be able to (re)load them, and that can NEVER\n * happen, for security reasons; local disk images can ONLY be loaded via the \"Mount\" button after\n * the user has selected them via the \"Choose File\" button.\n *\n * this.addDisk(sDiskName, sDiskPath);\n *\n * So we're going to take a different approach: when displayDisk() is asked to display the name\n * of a local disk image, it will map all such disks to \"Local Disk\", and any attempt to \"Mount\" such\n * a disk, will essentially result in a \"Disk not found\" error.\n */\n this.addDiskHistory(sDiskName, sDiskPath, disk);\n\n /*\n * With the addition of notify(), users are now \"alerted\" whenever a disk has finished loading;\n * notify() is selective about its output, using print() if a print window is open, alert() otherwise.\n */\n this.notice(\"Loaded disk \\\"\" + sDiskName + \"\\\" in drive \" + this.getDriveName(drive.iDrive), drive.fAutoMount || fAutoMount);\n\n /*\n * Since you usually want the Computer to have focus again after loading a new disk, let's try automatically\n * updating the focus after a successful load.\n */\n if (this.cmp) this.cmp.setFocus();\n }\n else {\n drive.fLocal = false;\n }\n\n if (drive.fAutoMount) {\n drive.fAutoMount = false;\n if (!--this.cAutoMount) this.setReady();\n }\n\n this.displayDisk(drive.iDrive);\n\n if (drive.fnCallReady) {\n drive.fnCallReady();\n drive.fnCallReady = null;\n }\n }\n\n /**\n * addDisk(sName, sPath, fTop)\n *\n * @this {DriveController}\n * @param {string} sName\n * @param {string} sPath\n * @param {boolean} [fTop] (default is bottom)\n */\n addDisk(sName, sPath, fTop)\n {\n var controlDisks = this.bindings[\"listDisks\"];\n if (controlDisks && controlDisks.options) {\n for (var i = 0; i < controlDisks.options.length; i++) {\n if (controlDisks.options[i].value == sPath) return;\n }\n var controlOption = document.createElement(\"option\");\n controlOption.text = sName;\n controlOption.value = sPath;\n if (fTop && controlDisks.childNodes[0]) {\n controlDisks.insertBefore(controlOption, controlDisks.childNodes[0]);\n } else {\n controlDisks.appendChild(controlOption);\n }\n }\n }\n\n /**\n * findDisk(sPath)\n *\n * This is used to deal with mount requests (eg, autoMount) that supply a path without a name;\n * if we can find the path in the \"listDisks\" control, then we return the associated disk name.\n *\n * @this {DriveController}\n * @param {string} sPath\n * @return {string|null}\n */\n findDisk(sPath)\n {\n var controlDisks = this.bindings[\"listDisks\"];\n if (controlDisks && controlDisks.options) {\n for (var i = 0; i < controlDisks.options.length; i++) {\n var control = controlDisks.options[i];\n if (control.value == sPath) return control.text;\n }\n }\n return Str.getBaseName(sPath, true);\n }\n\n /**\n * displayDisk(iDrive, fUpdateDrive)\n *\n * This ensures that the selected disk matches the drive's sDiskPath property, and if fUpdateDrive is set,\n * it also ensures that the selected drive matches the specified drive number.\n *\n * @this {DriveController}\n * @param {number} iDrive (unvalidated)\n * @param {boolean} [fUpdateDrive] is true to update the drive list to match the specified drive (eg, the auto-mount case)\n * @return {boolean} true if successful, false if not\n */\n displayDisk(iDrive, fUpdateDrive)\n {\n /*\n * First things first: validate iDrive.\n */\n var fSuccess = false;\n if (iDrive >= 0 && iDrive < this.aDrives.length) {\n var drive = this.aDrives[iDrive];\n var controlDisks = this.bindings[\"listDisks\"];\n var controlDrives = this.bindings[\"listDrives\"];\n /*\n * Next, make sure controls for both drives and disks exist.\n */\n if (controlDisks && controlDrives && controlDisks.options && controlDrives.options) {\n /*\n * Next, update the drive if the caller has requested it.\n */\n var i;\n if (fUpdateDrive) {\n\n for (i = 0; i < controlDrives.options.length; i++) {\n if (Str.parseInt(controlDrives.options[i].value, 10) == drive.iDrive) {\n if (controlDrives.selectedIndex != i) {\n controlDrives.selectedIndex = i;\n }\n fSuccess = true;\n break;\n }\n }\n }\n /*\n * Next, make sure the drive whose disk we're updating is the currently selected drive.\n */\n var iDriveSelected = Str.parseInt(controlDrives.value, 10);\n var sTargetPath = (drive.fLocal? DriveController.SOURCE.LOCAL : drive.sDiskPath);\n if (!isNaN(iDriveSelected) && iDriveSelected == iDrive) {\n for (i = 0; i < controlDisks.options.length; i++) {\n if (controlDisks.options[i].value == sTargetPath) {\n if (controlDisks.selectedIndex != i) {\n controlDisks.selectedIndex = i;\n }\n fSuccess = true;\n break;\n }\n }\n if (i == controlDisks.options.length) controlDisks.selectedIndex = 0;\n }\n }\n }\n return fSuccess;\n }\n\n /**\n * selectDrive(sDrive)\n *\n * Used to select a drive by name.\n *\n * @this {DriveController}\n * @param {number} sDrive\n * @return {boolean} true if successful, false if not\n */\n selectDrive(sDrive)\n {\n var controlDrives = this.bindings[\"listDrives\"];\n if (controlDrives && controlDrives.options) {\n var nDrives = controlDrives.options.length;\n for (var i = 0; i < nDrives; i++) {\n if (controlDrives.options[i].textContent == sDrive) {\n var iDrive = Str.parseInt(controlDrives.options[i].value, 10);\n if (iDrive >= 0) {\n return this.displayDisk(iDrive, true);\n }\n }\n }\n }\n return false;\n }\n\n /**\n * updateSelectedDisk()\n *\n * @this {DriveController}\n */\n updateSelectedDisk()\n {\n var control = this.bindings[\"listDisks\"];\n var controlDesc = this.bindings[\"descDisk\"];\n var controlOption = control.options && control.options[control.selectedIndex];\n if (controlDesc && controlOption) {\n var dataValue = {};\n var sValue = controlOption.getAttribute(\"data-value\");\n if (sValue) {\n try {\n dataValue = eval(\"(\" + sValue + \")\");\n } catch (e) {\n Component.error(this.type + \" option error: \" + e.message);\n }\n }\n var sHTML = dataValue['desc'];\n if (sHTML === undefined) sHTML = \"\";\n var sHRef = dataValue['href'];\n if (sHRef !== undefined) sHTML = \"<a href=\\\"\" + sHRef + \"\\\" target=\\\"_blank\\\">\" + sHTML + \"</a>\";\n controlDesc.innerHTML = sHTML;\n }\n }\n\n /**\n * waitDrives(fnCallReady)\n *\n * @this {DriveController}\n * @param {function()|null} fnCallReady\n * @return {boolean} false if wait required, true otherwise\n */\n waitDrives(fnCallReady)\n {\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n var drive = this.aDrives[iDrive];\n if (drive && drive.fBusy) {\n if (!drive.fnCallReady) drive.fnCallReady = fnCallReady;\n return false;\n }\n }\n return true;\n }\n\n /**\n * unloadDrive(iDrive, fLoading)\n *\n * @this {DriveController}\n * @param {number} iDrive\n * @param {boolean} [fLoading]\n */\n unloadDrive(iDrive, fLoading)\n {\n var drive = this.aDrives[iDrive];\n\n if (drive.disk || fLoading === false) {\n\n /*\n * Before we toss the disk's information, capture any deltas that may have occurred.\n */\n this.updateDiskHistory(drive.sDiskName, drive.sDiskPath, drive.disk);\n\n drive.sDiskName = \"\";\n drive.sDiskPath = \"\";\n drive.disk = null;\n drive.fLocal = false;\n\n if (!fLoading) {\n this.notice(\"Drive \" + this.getDriveName(iDrive) + \" unloaded\", fLoading);\n this.sDiskSource = DriveController.SOURCE.NONE;\n this.displayDisk(iDrive);\n }\n\n /*\n * Inform the controller implementation (eg, RX11) of the disk removal.\n */\n this.notifyUnload(iDrive);\n }\n }\n\n /**\n * unloadAllDrives(fDiscard)\n *\n * @this {DriveController}\n * @param {boolean} fDiscard to discard all disk history before unloading\n */\n unloadAllDrives(fDiscard)\n {\n if (fDiscard) this.aDiskHistory = [];\n\n for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {\n this.unloadDrive(iDrive, true);\n }\n }\n\n /**\n * addDiskHistory(sDiskName, sDiskPath, disk)\n *\n * @this {DriveController}\n * @param {string} sDiskName\n * @param {string} sDiskPath\n * @param {DiskPDP11} disk containing corresponding disk image\n */\n addDiskHistory(sDiskName, sDiskPath, disk)\n {\n var i;\n\n for (i = 0; i < this.aDiskHistory.length; i++) {\n if (this.aDiskHistory[i][1] == sDiskPath) {\n var nChanges = disk.restore(this.aDiskHistory[i][2]);\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"disk '\" + sDiskName + \"' restored from history (\" + nChanges + \" changes)\");\n }\n return;\n }\n }\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"disk '\" + sDiskName + \"' added to history (nothing to restore)\");\n }\n this.aDiskHistory[i] = [sDiskName, sDiskPath, []];\n }\n\n /**\n * removeDiskHistory(sDiskName, sDiskPath)\n *\n * @this {DriveController}\n * @param {string} sDiskName\n * @param {string} sDiskPath\n */\n removeDiskHistory(sDiskName, sDiskPath)\n {\n var i;\n for (i = 0; i < this.aDiskHistory.length; i++) {\n if (this.aDiskHistory[i][1] == sDiskPath) {\n this.aDiskHistory.splice(i, 1);\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"disk '\" + sDiskName + \"' removed from history\");\n }\n return;\n }\n }\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"unable to remove disk '\" + sDiskName + \"' from history (\" + sDiskPath + \")\");\n }\n }\n\n /**\n * updateDiskHistory(sDiskName, sDiskPath, disk)\n *\n * @this {DriveController}\n * @param {string} sDiskName\n * @param {string} sDiskPath\n * @param {DiskPDP11} disk containing corresponding disk image, with possible deltas\n */\n updateDiskHistory(sDiskName, sDiskPath, disk)\n {\n var i;\n for (i = 0; i < this.aDiskHistory.length; i++) {\n if (this.aDiskHistory[i][1] == sDiskPath) {\n this.aDiskHistory[i][2] = disk.save();\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"disk '\" + sDiskName + \"' updated in history\");\n }\n return;\n }\n }\n /*\n * I used to report this as an error (at least in the DEBUG release), but it's no longer really\n * an error, because if we're trying to re-mount a clean copy of a disk, we toss its history, then\n * unload, and then reload/remount. And since unloadDrive's normal behavior is to call updateDiskHistory()\n * before unloading, the fact that the disk is no longer listed here can't be treated as an error.\n */\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"unable to update disk '\" + sDiskName + \"' in history (\" + sDiskPath + \")\");\n }\n }\n\n /**\n * notifyLoad(iDrive)\n *\n * Placeholder for subclasses. Called whenever DriveController has loaded a new disk into the specified drive.\n *\n * @this {RX11}\n * @param {number} iDrive\n */\n notifyLoad(iDrive)\n {\n }\n\n /**\n * notifyUnload(iDrive)\n *\n * Placeholder for subclasses. Called whenever DriveController has unloaded a disk from the specified drive.\n *\n * @this {RX11}\n * @param {number} iDrive\n */\n notifyUnload(iDrive)\n {\n }\n\n /**\n * readData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n *\n * Placeholder for subclasses. Implementation is optional, but the automatic BOOT feature will be unavailable.\n *\n * @this {DriveController}\n * @param {Object} drive\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nWords\n * @param {number} addr\n * @param {number} inc (normally 2, unless inhibited, in which case it's 0)\n * @param {boolean} [fCheck]\n * @param {function(...)} [done]\n * @return {boolean|number} true if complete, false if queued (or if no done() is supplied, the error code, if any)\n */\n readData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n {\n return -1;\n }\n\n /**\n * writeData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n *\n * Placeholder for subclasses. Implementation is optional.\n *\n * @this {DriveController}\n * @param {Object} drive\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nWords\n * @param {number} addr\n * @param {number} inc (normally 2, unless inhibited, in which case it's 0)\n * @param {boolean} [fCheck]\n * @param {function(...)} [done]\n * @return {boolean|number} true if complete, false if queued (or if no done() is supplied, the error code, if any)\n */\n writeData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n {\n return -1;\n }\n}\n\n/*\n * There's nothing super special about these values, except that NONE should be falsey and the others should not.\n */\nDriveController.SOURCE = {\n NONE: \"\",\n LOCAL: \"?\",\n REMOTE: \"??\"\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/rk11.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass RK11 extends DriveController {\n /**\n * RK11(parms)\n *\n * The RK11 component has the following component-specific (parms) properties:\n *\n * autoMount: one or more JSON-encoded objects, each containing 'name' and 'path' properties\n *\n * The RK11 Disk Controller controls up to eight RK05 disk drives, which in turn read/write RK03-KA\n * disk cartridges. See [RK11 Disk Controller Configuration Files](/devices/pdp11/rk11/).\n *\n * RK03 (or more precisely, RK03-KA) disks are single-platter cartridges with 203 tracks per side,\n * 12 sectors per track, and a sector size of 256 words (512 bytes), for a total capacity of 2.38Mb\n * (2,494,464 bytes). See [RK03-KA Disk Images](/disks/dec/rk03/).\n *\n * @param {Object} parms\n */\n constructor(parms)\n {\n super(\"RK11\", parms, MessagesPDP11.RK11, PDP11.RK11, PDP11.RK11.RK05, RK11.UNIBUS_IOTABLE);\n\n /*\n * Define all the registers required for this controller.\n *\n * TODO: Determine what we should really be doing with the RKDB register.\n */\n this.regRKDS = this.regRKER = this.regRKCS = this.regRKWC = this.regRKBA = this.regRKDA = this.regRKDB = 0;\n }\n\n /**\n * initController(aRegs)\n *\n * @this {RK11}\n * @param {Array} [aRegs]\n * @return {boolean} true if successful, false if failure\n */\n initController(aRegs)\n {\n if (!aRegs) {\n aRegs = [(RK11.RKDS.RK05 | RK11.RKDS.SOK | RK11.RKDS.RRDY), 0, (RK11.RKCS.CRDY), 0, 0, 0, 0];\n }\n\n /*\n * ES6 ALERT: A handy destructuring assignment, which makes it easy to perform the inverse\n * of what saveController() does when it collects a bunch of object properties into an array.\n */\n [\n this.regRKDS,\n this.regRKER,\n this.regRKCS,\n this.regRKWC,\n this.regRKBA,\n this.regRKDA,\n this.regRKDB\n ] = aRegs;\n\n return true;\n }\n\n /**\n * saveController()\n *\n * Basically, the inverse of initController().\n *\n * @this {RK11}\n * @return {Array}\n */\n saveController()\n {\n return [\n this.regRKDS,\n this.regRKER,\n this.regRKCS,\n this.regRKWC,\n this.regRKBA,\n this.regRKDA,\n this.regRKDB\n ];\n }\n\n /**\n * processCommand()\n *\n * @this {RK11}\n */\n processCommand()\n {\n var fInterrupt = true;\n var fnReadWrite, func, sFunc = \"\";\n var iDrive = (this.regRKDA & RK11.RKDA.DS) >> RK11.RKDA.SHIFT.DS;\n var drive = this.aDrives[iDrive];\n var iCylinder, iHead, iSector, nWords, addr, inc;\n\n this.regRKCS &= ~(RK11.RKCS.CRDY | RK11.RKCS.SCP);\n this.regRKER &= ~(RK11.RKER.SE);\n\n switch(func = this.regRKCS & RK11.RKCS.FUNC) {\n\n case RK11.FUNC.CRESET:\n if (this.messageEnabled()) this.printMessage(this.type + \": CRESET(\" + iDrive + \")\", true);\n this.regRKER = this.regRKDA = 0;\n this.regRKCS = RK11.RKCS.CRDY;\n break;\n\n case RK11.FUNC.RCHK:\n sFunc = \"RCHK\";\n /* falls through */\n\n case RK11.FUNC.READ:\n if (!sFunc) sFunc = \"READ\";\n fnReadWrite = this.readData;\n /* falls through */\n\n case RK11.FUNC.WCHK:\n if (!sFunc) sFunc = \"WCHK\";\n /* falls through */\n\n case RK11.FUNC.WRITE:\n if (!sFunc) sFunc = \"WRITE\";\n if (!fnReadWrite) fnReadWrite = this.writeData;\n\n iCylinder = (this.regRKDA & RK11.RKDA.CA) >> RK11.RKDA.SHIFT.CA;\n iHead = (this.regRKDA & RK11.RKDA.HS) >> RK11.RKDA.SHIFT.HS;\n iSector = this.regRKDA & RK11.RKDA.SA;\n nWords = (0x10000 - this.regRKWC) & 0xffff;\n addr = (((this.regRKCS & RK11.RKCS.MEX)) << (16 - RK11.RKCS.SHIFT.MEX)) | this.regRKBA;\n inc = (this.regRKCS & RK11.RKCS.IBA)? 0 : 2;\n\n if (this.messageEnabled()) this.printMessage(this.type + \": \" + sFunc + \"(\" + iCylinder + \":\" + iHead + \":\" + iSector + \") \" + Str.toOct(addr) + \"--\" + Str.toOct(addr + (nWords << 1)), true, true);\n\n if (iCylinder >= drive.nCylinders) {\n this.regRKER |= RK11.RKER.NXC;\n break;\n }\n if (iSector >= drive.nSectors) {\n this.regRKER |= RK11.RKER.NXS;\n break;\n }\n\n fInterrupt = fnReadWrite.call(this, drive, iCylinder, iHead, iSector, nWords, addr, inc, (func >= RK11.FUNC.WCHK), this.doneReadWrite.bind(this));\n break;\n\n case RK11.FUNC.SEEK:\n iCylinder = (this.regRKDA & RK11.RKDA.CA) >> RK11.RKDA.SHIFT.CA;\n if (this.messageEnabled()) this.printMessage(this.type + \": SEEK(\" + iCylinder + \")\", true);\n if (iCylinder < drive.nCylinders) {\n this.regRKCS |= RK11.RKCS.SCP;\n } else {\n this.regRKER |= RK11.RKER.NXC;\n }\n break;\n\n case RK11.FUNC.DRESET:\n if (this.messageEnabled()) this.printMessage(this.type + \": DRESET(\" + iDrive + \")\");\n this.regRKER = this.regRKDA = 0;\n this.regRKCS = RK11.RKCS.CRDY | RK11.RKCS.SCP;\n break;\n\n default:\n if (this.messageEnabled()) this.printMessage(this.type + \": UNSUPPORTED(\" + func + \")\");\n break;\n }\n\n this.regRKDS = drive.status | (drive.disk? RK11.RKDS.DRDY : 0) | (iDrive << RK11.RKDS.SHIFT.ID) | (this.regRKDA & RK11.RKDS.SC);\n\n this.updateErrors();\n\n if (fInterrupt) {\n this.regRKCS &= ~RK11.RKCS.GO;\n this.regRKCS |= RK11.RKCS.CRDY;\n if (this.regRKCS & RK11.RKCS.IE) this.cpu.setIRQ(this.irq);\n }\n }\n\n /**\n * readData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n *\n * @this {RK11}\n * @param {Object} drive\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nWords\n * @param {number} addr\n * @param {number} inc (normally 2, unless inhibited, in which case it's 0)\n * @param {boolean} [fCheck]\n * @param {function(...)} [done]\n * @return {boolean|number} true if complete, false if queued (or if no done() is supplied, the error code, if any)\n */\n readData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n {\n var nError = 0;\n var disk = drive.disk;\n var sector = null, ibSector;\n\n if (!disk) {\n nError = RK11.RKER.NXD;\n nWords = 0;\n }\n\n var sWords = \"\";\n while (nWords) {\n if (!sector) {\n if (iCylinder >= disk.nCylinders) {\n nError = RK11.RKER.NXC;\n break;\n }\n sector = disk.seek(iCylinder, iHead, iSector + 1);\n if (!sector) {\n nError = RK11.RKER.SKE;\n break;\n }\n ibSector = 0;\n if (++iSector >= disk.nSectors) {\n iSector = 0;\n if (++iHead >= disk.nHeads) {\n iHead = 0;\n ++iCylinder;\n }\n }\n }\n var b0, b1;\n if ((b0 = disk.read(sector, ibSector++)) < 0 || (b1 = disk.read(sector, ibSector++)) < 0) {\n nError = RK11.RKER.NXS;\n break;\n }\n if (!fCheck) {\n var data = b0 | (b1 << 8);\n this.bus.setWordDirect(this.cpu.mapUnibus(addr), data);\n if (DEBUG && this.messageEnabled(MessagesPDP11.READ)) {\n if (!sWords) sWords = Str.toOct(addr) + \": \";\n sWords += Str.toOct(data) + ' ';\n if (sWords.length >= 64) {\n console.log(sWords);\n sWords = \"\";\n }\n }\n if (this.bus.checkFault()) {\n nError = RK11.RKER.NXM;\n break;\n }\n }\n if (ibSector >= disk.cbSector) sector = null;\n addr += inc;\n nWords--;\n }\n return done? done(nError, iCylinder, iHead, iSector, nWords, addr) : nError;\n }\n\n /**\n * writeData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n *\n * @this {RK11}\n * @param {Object} drive\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nWords\n * @param {number} addr\n * @param {number} inc (normally 2, unless inhibited, in which case it's 0)\n * @param {boolean} [fCheck]\n * @param {function(...)} [done]\n * @return {boolean|number} true if complete, false if queued (or if no done() is supplied, the error code, if any)\n */\n writeData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n {\n var nError = 0;\n var disk = drive.disk;\n var sector = null, ibSector;\n\n if (!disk) {\n nError = RK11.RKER.NXD;\n nWords = 0;\n }\n\n while (nWords) {\n var data = this.bus.getWordDirect(this.cpu.mapUnibus(addr));\n if (this.bus.checkFault()) {\n nError = RK11.RKER.NXM;\n break;\n }\n if (!sector) {\n if (iCylinder >= disk.nCylinders) {\n nError = RK11.RKER.NXC;\n break;\n }\n sector = disk.seek(iCylinder, iHead, iSector + 1, true);\n if (!sector) {\n nError = RK11.RKER.SKE;\n break;\n }\n ibSector = 0;\n if (++iSector >= disk.nSectors) {\n iSector = 0;\n if (++iHead >= disk.nHeads) {\n iHead = 0;\n ++iCylinder;\n }\n }\n }\n if (fCheck) {\n var b0, b1;\n if ((b0 = disk.read(sector, ibSector++)) < 0 || (b1 = disk.read(sector, ibSector++)) < 0) {\n nError = RK11.RKER.NXS;\n break;\n }\n /*\n * NOTE: During the 11/70 CPU EXERCISER diagnostic, a number of WCHK requests will fail\n * when the test starts reading/writing with physical addresses > 177777. I'm pretty sure all\n * the UNIBUS address calculations are fine, and therefore those failures are expected.\n *\n * Originally, those failures were causing me some grief because I was treating a WCE error like\n * any other error; ie, as a HARD error. That was wrong. Two errors (WCE and CSE) are soft\n * errors, so while they should still trigger the general-purpose RKCS ERR bit, they should NOT\n * trigger the RKCS HE (Hard Error) bit. This is all taken care of in updateErrors() now.\n */\n if (data != (b0 | (b1 << 8))) {\n nError = RK11.RKER.WCE;\n break;\n }\n } else {\n if (!disk.write(sector, ibSector++, data & 0xff) || !disk.write(sector, ibSector++, data >> 8)) {\n nError = RK11.RKER.NXS;\n break;\n }\n }\n if (ibSector >= disk.cbSector) sector = null;\n addr += inc;\n nWords--;\n }\n return done? done(nError, iCylinder, iHead, iSector, nWords, addr) : nError;\n }\n\n /**\n * doneReadWrite(nError, iCylinder, iHead, iSector, nWords, addr)\n *\n * @this {RK11}\n * @param {number} nError\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nWords\n * @param {number} addr\n * @return {boolean}\n */\n doneReadWrite(nError, iCylinder, iHead, iSector, nWords, addr)\n {\n this.regRKBA = addr & 0xffff;\n this.regRKCS = (this.regRKCS & ~RK11.RKCS.MEX) | ((addr >> (16 - RK11.RKCS.SHIFT.MEX)) & RK11.RKCS.MEX);\n this.regRKWC = (0x10000 - nWords) & 0xffff;\n this.regRKDA = (this.regRKDA & ~RK11.RKDA.SA) | (iSector & RK11.RKDA.SA);\n this.regRKER |= nError;\n this.updateErrors();\n return true;\n }\n\n /**\n * updateErrors()\n *\n * @this {RK11}\n */\n updateErrors()\n {\n /*\n * Reflect RKER bits to RKCS bits as appropriate.\n *\n * TODO: I'm not entirely sure about the handling of the DRE bit here. DEC's RK11 documentation says:\n *\n * Sets if one of the drives in the system senses a loss of either AC or DC power and a function is\n * either initiated or in process while the selected drive is not ready or in some error condition.\n *\n * I'm not sure how to parse all the \"ands\" and \"ors\" in that sentence. For now, we're treating the DRE bit\n * much like the high error bit found in other hardware registers: we always set it if any lower error bits\n * are also set.\n */\n this.regRKCS &= ~RK11.RKCS.ERR;\n if (this.regRKER) {\n this.regRKER |= RK11.RKER.DRE;\n this.regRKCS |= RK11.RKCS.ERR;\n if (this.regRKER & RK11.RKER.HE) this.regRKCS |= RK11.RKCS.HE;\n if (this.messageEnabled()) this.printMessage(this.type + \": ERROR: \" + Str.toOct(this.regRKER));\n }\n }\n\n /**\n * readRKDS(addr)\n *\n * @this {RK11}\n * @param {number} addr (eg, PDP11.UNIBUS.RKDS or 177400)\n * @return {number}\n */\n readRKDS(addr)\n {\n return this.regRKDS;\n }\n\n /**\n * writeRKDS(data, addr)\n *\n * @this {RK11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RKDS or 177400)\n */\n writeRKDS(data, addr)\n {\n /*\n * This is a read-only register\n */\n }\n\n /**\n * readRKER(addr)\n *\n * @this {RK11}\n * @param {number} addr (eg, PDP11.UNIBUS.RKER or 177402)\n * @return {number}\n */\n readRKER(addr)\n {\n return this.regRKER;\n }\n\n /**\n * writeRKER(data, addr)\n *\n * @this {RK11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RKER or 177402)\n */\n writeRKER(data, addr)\n {\n /*\n * This is a read-only register\n */\n }\n\n /**\n * readRKCS(addr)\n *\n * @this {RK11}\n * @param {number} addr (eg, PDP11.UNIBUS.RKCS or 177404)\n * @return {number}\n */\n readRKCS(addr)\n {\n return this.regRKCS & RK11.RKCS.RMASK;\n }\n\n /**\n * writeRKCS(data, addr)\n *\n * @this {RK11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RKCS or 177404)\n */\n writeRKCS(data, addr)\n {\n this.regRKCS = (this.regRKCS & ~RK11.RKCS.WMASK) | (data & RK11.RKCS.WMASK);\n\n if (this.regRKCS & RK11.RKCS.GO) this.processCommand();\n }\n\n /**\n * readRKWC(addr)\n *\n * @this {RK11}\n * @param {number} addr (eg, PDP11.UNIBUS.RKWC or 177406)\n * @return {number}\n */\n readRKWC(addr)\n {\n return this.regRKWC;\n }\n\n /**\n * writeRKWC(data, addr)\n *\n * @this {RK11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RKWC or 177406)\n */\n writeRKWC(data, addr)\n {\n this.regRKWC = data;\n }\n\n /**\n * readRKBA(addr)\n *\n * @this {RK11}\n * @param {number} addr (eg, PDP11.UNIBUS.RKBA or 177410)\n * @return {number}\n */\n readRKBA(addr)\n {\n return this.regRKBA;\n }\n\n /**\n * writeRKBA(data, addr)\n *\n * @this {RK11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RKBA or 177410)\n */\n writeRKBA(data, addr)\n {\n this.regRKBA = data;\n }\n\n /**\n * readRKDA(addr)\n *\n * @this {RK11}\n * @param {number} addr (eg, PDP11.UNIBUS.RKDA or 177412)\n * @return {number}\n */\n readRKDA(addr)\n {\n return this.regRKDA;\n }\n\n /**\n * writeRKDA(data, addr)\n *\n * @this {RK11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RKDA or 177412)\n */\n writeRKDA(data, addr)\n {\n this.regRKDA = data;\n }\n\n /**\n * readRKDB(addr)\n *\n * @this {RK11}\n * @param {number} addr (eg, PDP11.UNIBUS.RKDB or 177416)\n * @return {number}\n */\n readRKDB(addr)\n {\n return this.regRKDB;\n }\n\n /**\n * writeRKDB(data, addr)\n *\n * @this {RK11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RKDB or 177416)\n */\n writeRKDB(data, addr)\n {\n this.regRKDB = data;\n }\n}\n\n/*\n * Alias RK11 definitions as class constants\n */\nRK11.RKDS = PDP11.RK11.RKDS; // 177400: Drive Status Register\nRK11.RKER = PDP11.RK11.RKER; // 177402: Error Register\nRK11.RKCS = PDP11.RK11.RKCS; // 177404: Control Status Register\nRK11.RKDA = PDP11.RK11.RKDA; // 177412: Disk Address Register\nRK11.FUNC = PDP11.RK11.FUNC;\n\n/*\n * ES6 ALERT: As you can see below, I've finally started using computed property names.\n */\nRK11.UNIBUS_IOTABLE = {\n [PDP11.UNIBUS.RKDS]: /* 177400 */ [null, null, RK11.prototype.readRKDS, RK11.prototype.writeRKDS, \"RKDS\"],\n [PDP11.UNIBUS.RKER]: /* 177402 */ [null, null, RK11.prototype.readRKER, RK11.prototype.writeRKER, \"RKER\"],\n [PDP11.UNIBUS.RKCS]: /* 177404 */ [null, null, RK11.prototype.readRKCS, RK11.prototype.writeRKCS, \"RKCS\"],\n [PDP11.UNIBUS.RKWC]: /* 177406 */ [null, null, RK11.prototype.readRKWC, RK11.prototype.writeRKWC, \"RKWC\"],\n [PDP11.UNIBUS.RKBA]: /* 177410 */ [null, null, RK11.prototype.readRKBA, RK11.prototype.writeRKBA, \"RKBA\"],\n [PDP11.UNIBUS.RKDA]: /* 177412 */ [null, null, RK11.prototype.readRKDA, RK11.prototype.writeRKDA, \"RKDA\"],\n [PDP11.UNIBUS.RKDB]: /* 177416 */ [null, null, RK11.prototype.readRKDB, RK11.prototype.writeRKDB, \"RKDB\"]\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/rl11.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass RL11 extends DriveController {\n /**\n * RL11(parms)\n *\n * The RL11 component has the following component-specific (parms) properties:\n *\n * autoMount: one or more JSON-encoded objects, each containing 'name' and 'path' properties\n *\n * The RL11 Disk Controller controls up to four RL01 or RL02 disk drives, which in turn read/write RL01K or\n * RL02K disk cartridges. See [RL11 Disk Controller Configuration Files](/devices/pdp11/rl11/).\n *\n * RL01K disks are single-platter cartridges with 256 tracks per side, 40 sectors per track, and a sector size\n * of 256 bytes, for a total capacity of 5Mb (5,242,880 bytes). See [RL01K Disk Images](/disks/dec/rl01k/).\n *\n * RL02K disks are single-platter cartridges with 512 tracks per side, 40 sectors per track, and a sector size\n * of 256 bytes, for a total capacity of 10Mb (10,485,760 bytes). See [RL02K Disk Images](/disks/dec/rl02k/).\n *\n * @param {Object} parms\n */\n constructor(parms)\n {\n super(\"RL11\", parms, MessagesPDP11.RL11, PDP11.RL11, PDP11.RL11.RL02K, RL11.UNIBUS_IOTABLE);\n\n /*\n * Define all the registers required for this controller.\n */\n this.regRLCS = this.regRLBA = this.regRLDA = this.tmpRLDA = this.regRLMP = this.regRLBE = 0;\n }\n\n /**\n * initController(aRegs)\n *\n * @this {RL11}\n * @param {Array} [aRegs]\n * @return {boolean} true if successful, false if failure\n */\n initController(aRegs)\n {\n if (!aRegs) {\n aRegs = [(RL11.RLCS.DRDY | RL11.RLCS.CRDY), 0, 0, 0, 0, 0];\n }\n\n /*\n * ES6 ALERT: A handy destructuring assignment, which makes it easy to perform the inverse\n * of what saveController() does when it collects a bunch of object properties into an array.\n */\n [\n this.regRLCS,\n this.regRLBA,\n this.regRLDA,\n this.tmpRLDA,\n this.regRLMP,\n this.regRLBE\n ] = aRegs;\n\n return true;\n }\n\n /**\n * saveController()\n *\n * Basically, the inverse of initController().\n *\n * @this {RL11}\n * @return {Array}\n */\n saveController()\n {\n return [\n this.regRLCS,\n this.regRLBA,\n this.regRLDA,\n this.tmpRLDA,\n this.regRLMP,\n this.regRLBE\n ];\n }\n\n /**\n * processCommand()\n *\n * @this {RL11}\n */\n processCommand()\n {\n var fInterrupt = true;\n var fnReadWrite, sFunc = \"\";\n var iDrive = (this.regRLCS & RL11.RLCS.DS) >> RL11.RLCS.SHIFT.DS;\n var drive = this.aDrives[iDrive];\n var disk = drive.disk;\n var iCylinder, iHead, iSector, nWords, addr;\n\n /*\n * The typical pattern of DRDY and CRDY:\n *\n * 1) Normally both set\n * 2) CRDY is cleared to process a command\n * 3) DRDY is cleared to indicate a command in process\n */\n this.regRLCS &= ~RL11.RLCS.DRDY;\n\n switch(this.regRLCS & RL11.RLCS.FUNC) {\n\n case RL11.FUNC.NOP:\n case RL11.FUNC.WCHK:\n case RL11.FUNC.RDNC:\n break;\n\n case RL11.FUNC.STATUS:\n if (this.regRLMP & RL11.RLMP.GS_BH) {\n this.regRLCS &= (RL11.RLCS.DRDY | RL11.RLCS.FUNC | RL11.RLCS.BAE); // TODO: Review\n }\n /*\n * The bit indicating whether or not the disk contains 256 or 512 cylinders is critical;\n * for example, the first RSTS/E disk image we tried was an RL01K, which has only 256 cylinders,\n * and the operating system would crash mysteriously if we didn't report the correct geometry.\n */\n this.regRLMP = drive.status | (this.tmpRLDA & RL11.RLDA.RW_HS) | (disk && disk.nCylinders == 512? RL11.RLMP.GS_DT : 0);\n break;\n\n case RL11.FUNC.SEEK:\n if ((this.regRLDA & RL11.RLDA.GS_CMD) == RL11.RLDA.SEEK_CMD) {\n var darCA = (this.regRLDA & RL11.RLDA.RW_CA);\n var darHS = (this.regRLDA & RL11.RLDA.SEEK_HS) << 2;\n if (this.regRLDA & RL11.RLDA.SEEK_DIR) {\n this.tmpRLDA += darCA;\n } else {\n this.tmpRLDA -= darCA;\n }\n this.regRLDA = this.tmpRLDA = (this.tmpRLDA & RL11.RLDA.RW_CA) | darHS;\n }\n break;\n\n case RL11.FUNC.RHDR:\n this.regRLMP = this.tmpRLDA;\n break;\n\n case RL11.FUNC.RDATA:\n sFunc = \"READ\";\n fnReadWrite = this.readData;\n /* falls through */\n\n case RL11.FUNC.WDATA:\n if (!sFunc) sFunc = \"WRITE\";\n if (!fnReadWrite) fnReadWrite = this.writeData;\n\n iCylinder = this.regRLDA >> RL11.RLDA.SHIFT.RW_CA;\n iHead = (this.regRLDA & RL11.RLDA.RW_HS)? 1 : 0;\n iSector = this.regRLDA & RL11.RLDA.RW_SA;\n if (!disk || iCylinder >= disk.nCylinders || iSector >= disk.nSectors) {\n this.regRLCS |= RL11.ERRC.HNF | RL11.RLCS.ERR;\n break;\n }\n nWords = (0x10000 - this.regRLMP) & 0xffff;\n addr = (((this.regRLBE & RL11.RLBE.MASK)) << 16) | this.regRLBA; // 22 bit mode\n\n if (this.messageEnabled()) this.printMessage(this.type + \": \" + sFunc + \"(\" + iCylinder + \":\" + iHead + \":\" + iSector + \") \" + Str.toOct(addr) + \"--\" + Str.toOct(addr + (nWords << 1)), true, true);\n\n fInterrupt = fnReadWrite.call(this, drive, iCylinder, iHead, iSector, nWords, addr, 2, false, this.doneReadWrite.bind(this));\n break;\n\n default:\n break;\n }\n\n if (fInterrupt) {\n this.regRLCS |= RL11.RLCS.DRDY | RL11.RLCS.CRDY;\n if (this.regRLCS & RL11.RLCS.IE) this.cpu.setIRQ(this.irq);\n }\n }\n\n /**\n * readData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n *\n * @this {RL11}\n * @param {Object} drive\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nWords\n * @param {number} addr\n * @param {number} inc (normally 2, unless inhibited, in which case it's 0)\n * @param {boolean} [fCheck]\n * @param {function(...)} [done]\n * @return {boolean|number} true if complete, false if queued (or if no done() is supplied, the error code, if any)\n */\n readData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n {\n var nError = 0;\n var checksum = 0;\n var disk = drive.disk;\n var sector = null, ibSector;\n\n if (!disk) {\n nError = RL11.ERRC.HNF; // TODO: Review\n nWords = 0;\n }\n\n var sWords = \"\";\n while (nWords) {\n if (!sector) {\n sector = disk.seek(iCylinder, iHead, iSector + 1);\n if (!sector) {\n nError = RL11.ERRC.HNF;\n break;\n }\n ibSector = 0;\n }\n var b0, b1, data;\n if ((b0 = disk.read(sector, ibSector++)) < 0 || (b1 = disk.read(sector, ibSector++)) < 0) {\n nError = RL11.ERRC.HNF;\n break;\n }\n /*\n * Apparently, this controller honors the UNIBUS Map registers, which means we must call mapUnibus()\n * on the address REGARDLESS whether it is actually >= BusPDP11.UNIBUS_22BIT. TODO: This is inherited\n * code, so let's review the documentation on this.\n */\n this.bus.setWordDirect(this.cpu.mapUnibus(addr), data = b0 | (b1 << 8));\n if (DEBUG && this.messageEnabled(MessagesPDP11.READ)) {\n if (!sWords) sWords = Str.toOct(addr) + \": \";\n sWords += Str.toOct(data) + ' ';\n if (sWords.length >= 64) {\n console.log(sWords);\n sWords = \"\";\n }\n }\n if (this.bus.checkFault()) {\n nError = RL11.ERRC.NXM;\n break;\n }\n addr += 2;\n nWords--;\n checksum += data;\n if (ibSector >= disk.cbSector) {\n sector = null;\n if (++iSector >= disk.nSectors) {\n iSector = 0;\n if (++iHead >= disk.nHeads) {\n iHead = 0;\n if (++iCylinder >= disk.nCylinders) {\n nError = RL11.ERRC.HNF;\n break;\n }\n }\n }\n }\n }\n\n if (DEBUG && this.messageEnabled(MessagesPDP11.READ)) {\n console.log(\"checksum: \" + (checksum|0));\n }\n\n return done? done(nError, iCylinder, iHead, iSector, nWords, addr) : nError;\n }\n\n /**\n * writeData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n *\n * @this {RL11}\n * @param {Object} drive\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nWords\n * @param {number} addr\n * @param {number} inc (normally 2, unless inhibited, in which case it's 0)\n * @param {boolean} [fCheck]\n * @param {function(...)} [done]\n * @return {boolean|number} true if complete, false if queued (or if no done() is supplied, the error code, if any)\n */\n writeData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n {\n var nError = 0;\n var checksum = 0;\n var disk = drive.disk;\n var sector = null, ibSector;\n\n if (!disk) {\n nError = RL11.ERRC.HNF; // TODO: Review\n nWords = 0;\n }\n\n var sWords = \"\";\n while (nWords) {\n /*\n * Apparently, this controller honors the UNIBUS Map registers, which means we must call mapUnibus()\n * on the address REGARDLESS whether it is actually >= BusPDP11.UNIBUS_22BIT. TODO: This is inherited\n * code, so let's review the documentation on this.\n */\n var data = this.bus.getWordDirect(this.cpu.mapUnibus(addr));\n if (this.bus.checkFault()) {\n nError = RL11.ERRC.NXM;\n break;\n }\n if (DEBUG && this.messageEnabled(MessagesPDP11.WRITE)) {\n if (!sWords) sWords = Str.toOct(addr) + \": \";\n sWords += Str.toOct(data) + ' ';\n if (sWords.length >= 64) {\n console.log(sWords);\n sWords = \"\";\n }\n }\n addr += 2;\n nWords--;\n checksum += data;\n if (!sector) {\n sector = disk.seek(iCylinder, iHead, iSector + 1, true);\n if (!sector) {\n nError = RL11.ERRC.HNF;\n break;\n }\n ibSector = 0;\n }\n if (!disk.write(sector, ibSector++, data & 0xff) || !disk.write(sector, ibSector++, data >> 8)) {\n nError = RL11.ERRC.HNF;\n break;\n }\n if (ibSector >= disk.cbSector) {\n sector = null;\n if (++iSector >= disk.nSectors) {\n iSector = 0;\n if (++iHead >= disk.nHeads) {\n iHead = 0;\n if (++iCylinder >= disk.nCylinders) {\n nError = RL11.ERRC.HNF;\n break;\n }\n }\n }\n }\n }\n\n if (DEBUG && this.messageEnabled(MessagesPDP11.WRITE)) {\n console.log(\"checksum: \" + (checksum|0));\n }\n\n return done? done(nError, iCylinder, iHead, iSector, nWords, addr) : nError;\n }\n\n /**\n * doneReadWrite(nError, iCylinder, iHead, iSector, nWords, addr)\n *\n * @this {RL11}\n * @param {number} nError\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nWords\n * @param {number} addr\n * @return {boolean}\n */\n doneReadWrite(nError, iCylinder, iHead, iSector, nWords, addr)\n {\n this.regRLBA = addr & 0xffff;\n this.regRLCS = (this.regRLCS & ~RL11.RLCS.BAE) | ((addr >> (16 - RL11.RLCS.SHIFT.BAE)) & RL11.RLCS.BAE);\n this.regRLBE = (addr >> 16) & RL11.RLBE.MASK; // 22 bit mode\n this.regRLDA = (iCylinder << RL11.RLDA.SHIFT.RW_CA) | (iHead? RL11.RLDA.RW_HS : 0) | (iSector & RL11.RLDA.RW_SA);\n this.tmpRLDA = this.regRLDA;\n this.regRLMP = (0x10000 - nWords) & 0xffff;\n if (nError) {\n this.regRLCS |= nError | RL11.RLCS.ERR;\n }\n return true;\n }\n\n /**\n * readRLCS(addr)\n *\n * @this {RL11}\n * @param {number} addr (eg, PDP11.UNIBUS.RLCS or 174400)\n * @return {number}\n */\n readRLCS(addr)\n {\n return this.regRLCS & RL11.RLCS.RMASK;\n }\n\n /**\n * writeRLCS(data, addr)\n *\n * @this {RL11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RLCS or 174400)\n */\n writeRLCS(data, addr)\n {\n this.regRLCS = (this.regRLCS & ~RL11.RLCS.WMASK) | (data & RL11.RLCS.WMASK);\n this.regRLBE = (this.regRLBE & 0x3C) | ((data & RL11.RLCS.BAE) >> RL11.RLCS.SHIFT.BAE);\n if (!(this.regRLCS & RL11.RLCS.CRDY)) this.processCommand();\n }\n\n /**\n * readRLBA(addr)\n *\n * @this {RL11}\n * @param {number} addr (eg, PDP11.UNIBUS.RLBA or 174402)\n * @return {number}\n */\n readRLBA(addr)\n {\n return this.regRLBA;\n }\n\n /**\n * writeRLBA(data, addr)\n *\n * @this {RL11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RLBA or 174402)\n */\n writeRLBA(data, addr)\n {\n this.regRLBA = data & RL11.RLBA.WMASK;\n }\n\n /**\n * readRLDA(addr)\n *\n * @this {RL11}\n * @param {number} addr (eg, PDP11.UNIBUS.RLDA or 174404)\n * @return {number}\n */\n readRLDA(addr)\n {\n return this.regRLDA;\n }\n\n /**\n * writeRLDA(data, addr)\n *\n * @this {RL11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RLDA or 174404)\n */\n writeRLDA(data, addr)\n {\n this.regRLDA = data;\n }\n\n /**\n * readRLMP(addr)\n *\n * @this {RL11}\n * @param {number} addr (eg, PDP11.UNIBUS.RLMP or 174406)\n * @return {number}\n */\n readRLMP(addr)\n {\n return this.regRLMP;\n }\n\n /**\n * writeRLMP(data, addr)\n *\n * @this {RL11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RLMP or 174406)\n */\n writeRLMP(data, addr)\n {\n this.regRLMP = data;\n }\n\n /**\n * readRLBE(addr)\n *\n * @this {RL11}\n * @param {number} addr (eg, PDP11.UNIBUS.RLBE or 174410)\n * @return {number}\n */\n readRLBE(addr)\n {\n return this.regRLBE;\n }\n\n /**\n * writeRLBE(data, addr)\n *\n * Curiously, we see RSTS/E v7.0 writing RLBE bits that aren't documented:\n *\n * R0=000000 R1=000000 R2=174410 R3=000000 R4=102076 R5=045166\n * SP=052662 PC=067624 PS=034344 IR=000000 SL=000377 T0 N0 Z1 V0 C0\n * 067624: 012712 000300 MOV #300,@R2\n *\n * @this {RL11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RLBE or 174410)\n */\n writeRLBE(data, addr)\n {\n this.regRLBE = data & RL11.RLBE.MASK;\n this.regRLCS = (this.regRLCS & ~RL11.RLCS.BAE) | ((this.regRLBE & 0x3) << RL11.RLCS.SHIFT.BAE);\n }\n}\n\n/*\n * Alias RL11 definitions as class constants\n */\nRL11.RLCS = PDP11.RL11.RLCS; // 174400: Control Status Register\nRL11.RLBA = PDP11.RL11.RLBA; // 174402: Bus Address Register\nRL11.RLDA = PDP11.RL11.RLDA; // 174404: Disk Address Register\nRL11.RLMP = PDP11.RL11.RLMP; // 177406: Multi-Purpose Register\nRL11.RLBE = PDP11.RL11.RLBE; // 174410: Bus (Address) Extension Register\nRL11.ERRC = PDP11.RL11.ERRC; // NOTE: These error codes are pre-shifted to read/write directly from/to RLCS.ERRC\nRL11.FUNC = PDP11.RL11.FUNC; // NOTE: These function codes are pre-shifted to read/write directly from/to RLCS.FUNC\n\n/*\n * ES6 ALERT: As you can see below, I've finally started using computed property names.\n */\nRL11.UNIBUS_IOTABLE = {\n [PDP11.UNIBUS.RLCS]: /* 174400 */ [null, null, RL11.prototype.readRLCS, RL11.prototype.writeRLCS, \"RLCS\"],\n [PDP11.UNIBUS.RLBA]: /* 174402 */ [null, null, RL11.prototype.readRLBA, RL11.prototype.writeRLBA, \"RLBA\"],\n [PDP11.UNIBUS.RLDA]: /* 174404 */ [null, null, RL11.prototype.readRLDA, RL11.prototype.writeRLDA, \"RLDA\"],\n [PDP11.UNIBUS.RLMP]: /* 174406 */ [null, null, RL11.prototype.readRLMP, RL11.prototype.writeRLMP, \"RLMP\"],\n [PDP11.UNIBUS.RLBE]: /* 174410 */ [null, null, RL11.prototype.readRLBE, RL11.prototype.writeRLBE, \"RLBE\"]\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/rx11.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass RX11 extends DriveController {\n /**\n * RX11(parms)\n *\n * The RX11 component has the following component-specific (parms) properties:\n *\n * autoMount: one or more JSON-encoded objects, each containing 'name' and 'path' properties\n *\n * The RX11 Disk Controller controls up to two RX01 disk drives, which in turn read/write\n * disk cartridges. See [RX11 Disk Controller Configuration Files](/devices/pdp11/rx11/).\n *\n * RX01 diskettes are single-sided, with 77 tracks per side, 26 sectors per track, and a sector size\n * of 128 bytes, for a total capacity of 250Kb (256,256 bytes). See [RX01 Disk Images](/disks/dec/rx01/).\n *\n * @param {Object} parms\n */\n constructor(parms)\n {\n super(\"RX11\", parms, MessagesPDP11.RX11, PDP11.RX11, PDP11.RX11.RX01, RX11.UNIBUS_IOTABLE);\n\n /*\n * Define all the registers required for this controller.\n */\n this.regRXCS = this.regRXDB = 0;\n this.regRXTA = this.regRXSA = this.regRXES = this.regError = 0;\n\n /*\n * Whenever a command is issued, we record the function code internally here, and when the command\n * is completed, we set the internal function code back to UNUSED.\n */\n this.funCode = RX11.FUNC.UNUSED; // no function in progress (device is idle)\n\n this.iBuffer = 0;\n /*\n * We use the new ES6 fill() method to ensure that the buffer returns something reasonable if, for some\n * strange reason, the first command we receive is an Empty Buffer command.\n */\n this.abBuffer = new Array(128).fill(0);\n }\n\n /**\n * initController(aRegs)\n *\n * @this {RX11}\n * @param {Array} [aRegs]\n * @return {boolean} true if successful, false if failure\n */\n initController(aRegs)\n {\n if (!aRegs) {\n this.regRXCS = 0;\n this.regRXDB = 0;\n this.regRXTA = 1;\n this.regRXSA = 1;\n this.regRXES = 0;\n this.regError = 0;\n this.funCode = RX11.FUNC.READ;\n this.iBuffer = 0;\n this.cpu.clearIRQ(this.irq);\n this.readSector();\n }\n else {\n /*\n * ES6 ALERT: A handy destructuring assignment, which makes it easy to perform the inverse\n * of what saveController() does when it collects a bunch of object properties into an array.\n */\n [\n this.regRXCS,\n this.regRXDB,\n this.regRXTA,\n this.regRXSA,\n this.regRXES,\n this.regError,\n this.funCode,\n this.iBuffer,\n this.abBuffer\n ] = aRegs;\n }\n return true;\n }\n\n /**\n * saveController()\n *\n * Basically, the inverse of initController().\n *\n * @this {RX11}\n * @return {Array}\n */\n saveController()\n {\n return [\n this.regRXCS,\n this.regRXDB,\n this.regRXTA,\n this.regRXSA,\n this.regRXES,\n this.regError,\n this.funCode,\n this.iBuffer,\n this.abBuffer\n ];\n }\n\n /**\n * notifyLoad(iDrive)\n *\n * Called whenever DriveController has loaded a new disk into the specified drive.\n *\n * We're interested in this so that whenever a disk change occurs for drive 0, we can automatically\n * refill the sector buffer with the data from sector 1 from track 1.\n *\n * @this {RX11}\n * @param {number} iDrive\n */\n notifyLoad(iDrive)\n {\n if (iDrive == 0) this.initController();\n }\n\n /**\n * notifyUnload(iDrive)\n *\n * Called whenever DriveController has unloaded a disk from the specified drive.\n *\n * @this {RX11}\n * @param {number} iDrive\n */\n notifyUnload(iDrive)\n {\n }\n\n /**\n * processCommand()\n *\n * @this {RX11}\n */\n processCommand()\n {\n this.funCode = this.regRXCS & RX11.RXCS.FUNC;\n this.regRXCS &= ~(RX11.RXCS.GO | RX11.RXCS.TR | RX11.RXCS.DONE | RX11.RXCS.ERR);\n this.cpu.clearIRQ(this.irq);\n\n if (this.messageEnabled()) this.printMessage(this.type + \".processCommand(\" + RX11.FUNCS[this.funCode >> 1]+ \")\", true, true);\n\n switch(this.funCode) {\n\n case RX11.FUNC.FILL:\n case RX11.FUNC.EMPTY:\n case RX11.FUNC.READ:\n case RX11.FUNC.WRITE:\n case RX11.FUNC.WRDEL:\n this.initCommand();\n break;\n\n case RX11.FUNC.RDSTAT:\n this.readStatus();\n break;\n\n case RX11.FUNC.RDERR:\n this.readError();\n break;\n\n default:\n\n break;\n }\n }\n\n /**\n * initCommand()\n *\n * @this {RX11}\n */\n initCommand()\n {\n this.iBuffer = 0;\n }\n\n /**\n * doneCommand(nError)\n *\n * @this {RX11}\n * @param {number} [nError]\n */\n doneCommand(nError)\n {\n if (nError) {\n this.regError = nError;\n this.regRXDB = this.regRXES;\n this.regRXCS |= RX11.RXCS.ERR;\n }\n this.funCode = RX11.FUNC.UNUSED;\n this.regRXCS |= RX11.RXCS.DONE;\n if (this.regRXCS & RX11.RXCS.IE) this.cpu.setIRQ(this.irq);\n }\n\n /**\n * readData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n *\n * This function is required ONLY if we want to support DriveController's bootSelectedDisk() function (and we do).\n *\n * @this {RX11}\n * @param {Object} drive\n * @param {number} iCylinder\n * @param {number} iHead\n * @param {number} iSector\n * @param {number} nWords\n * @param {number} addr\n * @param {number} inc (normally 2, unless inhibited, in which case it's 0)\n * @param {boolean} [fCheck]\n * @param {function(...)} [done]\n * @return {boolean|number} true if complete, false if queued (or if no done() is supplied, the error code, if any)\n */\n readData(drive, iCylinder, iHead, iSector, nWords, addr, inc, fCheck, done)\n {\n var nError = 0;\n var disk = drive.disk;\n var sector = null, ibSector;\n\n if (this.messageEnabled()) this.printMessage(this.type + \".readData(\" + iCylinder + \":\" + iHead + \":\" + iSector + \") \" + Str.toOct(addr) + \"--\" + Str.toOct(addr + (nWords << 1)), true, true);\n\n if (!disk) {\n nError = drive.iDrive? RX11.ERROR.HOME1 : RX11.ERROR.HOME0;\n nWords = 0;\n }\n\n var sWords = \"\";\n while (nWords) {\n if (!sector) {\n if (iCylinder >= disk.nCylinders) {\n nError = RX11.ERROR.NO_TRACK;\n break;\n }\n sector = disk.seek(iCylinder, iHead, iSector + 1);\n if (!sector) {\n nError = RX11.ERROR.NO_SECTOR;\n break;\n }\n ibSector = 0;\n if (++iSector >= disk.nSectors) {\n iSector = 0;\n if (++iHead >= disk.nHeads) {\n iHead = 0;\n ++iCylinder;\n }\n }\n }\n var b0, b1;\n if ((b0 = disk.read(sector, ibSector++)) < 0 || (b1 = disk.read(sector, ibSector++)) < 0) {\n nError = RX11.ERROR.NO_DATA;\n break;\n }\n var data = b0 | (b1 << 8);\n this.bus.setWordDirect(this.cpu.mapUnibus(addr), data);\n if (DEBUG && this.messageEnabled(MessagesPDP11.READ)) {\n if (!sWords) sWords = Str.toOct(addr) + \": \";\n sWords += Str.toOct(data) + ' ';\n if (sWords.length >= 64) {\n console.log(sWords);\n sWords = \"\";\n }\n }\n if (ibSector >= disk.cbSector) sector = null;\n addr += inc;\n nWords--;\n }\n\n return done? done(nError, iCylinder, iHead, iSector, nWords, addr) : nError;\n }\n\n /**\n * readSector()\n *\n * @this {RX11}\n */\n readSector()\n {\n var nError = 0;\n var iDrive = (this.regRXCS & RX11.RXCS.UNIT)? 1 : 0;\n var drive = this.aDrives[iDrive];\n var disk = drive && drive.disk;\n var iCylinder = this.regRXTA & RX11.RXTA.MASK, iHead = 0, nSector = this.regRXSA & RX11.RXSA.MASK;\n\n this.regRXES &= ~(RX11.RXES.CRC | RX11.RXES.PARITY | RX11.RXES.DEL | RX11.RXES.DRDY);\n\n if (disk) {\n this.regRXES |= RX11.RXES.DRDY;\n if (this.messageEnabled()) this.printMessage(this.type + \".readSector(\" + iCylinder + \":\" + iHead + \":\" + nSector + \")\", true, true);\n\n var sector = disk.seek(iCylinder, iHead, nSector, true);\n if (sector) {\n var i = 0, nBytes = this.abBuffer.length;\n while (i < nBytes) {\n var b = disk.read(sector, i);\n if (b < 0) {\n nError = RX11.ERROR.NO_DATA;\n break;\n }\n this.abBuffer[i++] = b;\n }\n if (sector.deleted) this.regRXES |= RX11.RXES.DEL;\n } else {\n nError = RX11.ERROR.NO_SECTOR;\n }\n } else {\n nError = iDrive? RX11.ERROR.HOME1 : RX11.ERROR.HOME0;\n }\n this.doneCommand(nError);\n }\n\n /**\n * writeSector(fDeleted)\n *\n * @this {RX11}\n * @param {boolean} fDeleted\n */\n writeSector(fDeleted)\n {\n var nError = 0;\n var iDrive = (this.regRXCS & RX11.RXCS.UNIT)? 1 : 0;\n var drive = this.aDrives[iDrive];\n var disk = drive && drive.disk;\n var iCylinder = this.regRXTA & RX11.RXTA.MASK, iHead = 0, nSector = this.regRXSA & RX11.RXSA.MASK;\n\n this.regRXES &= ~(RX11.RXES.CRC | RX11.RXES.PARITY | RX11.RXES.DEL | RX11.RXES.DRDY);\n\n if (disk) {\n this.regRXES |= RX11.RXES.DRDY;\n if (this.messageEnabled()) this.printMessage(this.type + \".writeSector(\" + iCylinder + \":\" + iHead + \":\" + nSector + \")\", true, true);\n\n var sector = disk.seek(iCylinder, iHead, nSector, true);\n if (sector) {\n if (fDeleted) sector.deleted = true;\n var i = 0, nBytes = this.abBuffer.length;\n while (i < nBytes) {\n var data = this.abBuffer[i];\n if (!disk.write(sector, i, data & 0xff)) {\n nError = RX11.ERROR.NO_DATA;\n break;\n }\n i++;\n }\n } else {\n nError = RX11.ERROR.NO_SECTOR;\n }\n } else {\n nError = iDrive? RX11.ERROR.HOME1 : RX11.ERROR.HOME0;\n }\n this.doneCommand(nError);\n }\n\n /**\n * readStatus()\n *\n * @this {RX11}\n */\n readStatus()\n {\n var iDrive = (this.regRXCS & RX11.RXCS.UNIT)? 1 : 0;\n var drive = this.aDrives[iDrive];\n\n this.regRXES &= ~RX11.RXES.DRDY;\n if (drive && drive.disk) this.regRXES |= RX11.RXES.DRDY;\n\n this.regRXDB = this.regRXES;\n this.doneCommand();\n }\n\n /**\n * readError()\n *\n * @this {RX11}\n */\n readError()\n {\n this.regRXDB = this.regError;\n this.doneCommand();\n }\n\n /**\n * readRXCS(addr)\n *\n * @this {RX11}\n * @param {number} addr (eg, PDP11.UNIBUS.RXCS or 177170)\n * @param {boolean} [fPreWrite]\n * @return {number}\n */\n readRXCS(addr, fPreWrite)\n {\n var w = this.regRXCS;\n\n if (!fPreWrite) {\n w &= RX11.RXCS.RMASK;\n\n switch (this.funCode) {\n\n case RX11.FUNC.FILL:\n case RX11.FUNC.EMPTY:\n if (this.iBuffer < this.abBuffer.length) {\n this.regRXCS |= RX11.RXCS.TR;\n }\n break;\n\n case RX11.FUNC.READ:\n case RX11.FUNC.WRITE:\n case RX11.FUNC.WRDEL:\n if (this.iBuffer < 2) {\n this.regRXCS |= RX11.RXCS.TR;\n }\n break;\n }\n }\n return w;\n }\n\n /**\n * writeRXCS(data, addr)\n *\n * @this {RX11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RXCS or 177170)\n */\n writeRXCS(data, addr)\n {\n this.regRXCS = (this.regRXCS & ~RX11.RXCS.WMASK) | (data & RX11.RXCS.WMASK);\n\n if (this.regRXCS & RX11.RXCS.INIT) {\n this.initController();\n return;\n }\n\n if ((this.regRXCS & RX11.RXCS.GO) && this.funCode == RX11.FUNC.UNUSED) {\n this.processCommand();\n return;\n }\n\n if (!(this.regRXCS & RX11.RXCS.IE)) {\n this.cpu.clearIRQ(this.irq);\n }\n else if (this.regRXCS & RX11.RXCS.DONE) {\n this.cpu.setIRQ(this.irq);\n }\n }\n\n /**\n * readRXDB(addr)\n *\n * @this {RX11}\n * @param {number} addr (eg, PDP11.UNIBUS.RXDB or 177172)\n * @param {boolean} [fPreWrite]\n * @return {number}\n */\n readRXDB(addr, fPreWrite)\n {\n if (!fPreWrite) {\n switch (this.funCode) {\n\n case RX11.FUNC.EMPTY:\n if (this.regRXCS & RX11.RXCS.TR) {\n this.regRXCS &= ~RX11.RXCS.TR;\n\n this.regRXDB = this.abBuffer[this.iBuffer] & 0xff;\n if (this.messageEnabled()) this.printMessage(this.type + \".readByte(\" + this.iBuffer + \"): \" + Str.toHexByte(this.regRXDB), true, true);\n if (++this.iBuffer >= this.abBuffer.length) {\n this.doneCommand();\n }\n }\n break;\n }\n }\n return this.regRXDB;\n }\n\n /**\n * writeRXDB(data, addr)\n *\n * @this {RX11}\n * @param {number} data\n * @param {number} addr (eg, PDP11.UNIBUS.RXDB or 177172)\n */\n writeRXDB(data, addr)\n {\n switch(this.funCode) {\n\n case RX11.FUNC.FILL:\n if (this.regRXCS & RX11.RXCS.TR) {\n this.regRXCS &= ~RX11.RXCS.TR;\n\n this.abBuffer[this.iBuffer] = data & 0xff;\n if (this.messageEnabled()) this.printMessage(this.type + \".writeByte(\" + this.iBuffer + \",\" + Str.toHexByte(data) + \")\", true, true);\n if (++this.iBuffer >= this.abBuffer.length) {\n this.doneCommand();\n }\n }\n break;\n\n case RX11.FUNC.READ:\n case RX11.FUNC.WRITE:\n case RX11.FUNC.WRDEL:\n if (this.regRXCS & RX11.RXCS.TR) {\n this.regRXCS &= ~RX11.RXCS.TR;\n\n switch(this.iBuffer++) {\n case 0:\n this.regRXSA = data;\n break;\n\n case 1:\n this.regRXTA = data;\n if (this.funCode == RX11.FUNC.READ) {\n this.readSector();\n } else {\n this.writeSector(this.funCode == RX11.FUNC.WRDEL);\n }\n break;\n\n default:\n\n break;\n }\n }\n break;\n }\n this.regRXDB = data;\n }\n}\n\n/*\n * Alias RX11 definitions as class constants\n */\nRX11.RXCS = PDP11.RX11.RXCS; // 177170: Command and Status Register\nRX11.RXDB = PDP11.RX11.RXDB; // 177172: Data Buffer Register\nRX11.RXTA = PDP11.RX11.RXTA;\nRX11.RXSA = PDP11.RX11.RXSA;\nRX11.RXES = PDP11.RX11.RXES;\nRX11.FUNC = PDP11.RX11.FUNC;\nRX11.ERROR = PDP11.RX11.ERROR;\n\nRX11.FUNCS = [\n \"FILL\", \"EMPTY\", \"WRITE\", \"READ\", \"UNUSED\", \"RDSTAT\", \"WRDEL\", \"RDERR\"\n];\n\n/*\n * ES6 ALERT: As you can see below, I've finally started using computed property names.\n */\nRX11.UNIBUS_IOTABLE = {\n [PDP11.UNIBUS.RXCS]: /* 177170 */ [null, null, RX11.prototype.readRXCS, RX11.prototype.writeRXCS, \"RXCS\"],\n [PDP11.UNIBUS.RXDB]: /* 177172 */ [null, null, RX11.prototype.readRXDB, RX11.prototype.writeRXDB, \"RXDB\"]\n};\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/debugger.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * Debugger Address Object\n *\n * This is the basic structure; other debuggers may extend it.\n *\n * addr address\n * fTemporary true if this is a temporary breakpoint address\n * sCmd set for breakpoint addresses if there's an associated command string\n * aCmds preprocessed commands (from sCmd)\n *\n * @typedef {{\n * addr:(number|undefined),\n * fTemporary:(boolean|undefined),\n * sCmd:(string|undefined),\n * aCmds:(Array.<string>|undefined)\n * }}\n */\nvar DbgAddr;\n\n/**\n * Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,\n * it deters us from defining named properties on our components; eg:\n *\n * this['exports'] = {...}\n *\n * results in an error:\n *\n * Cannot do '[]' access on a struct\n *\n * So, in order to define 'exports', we must override the @struct assumption by annotating\n * the class as @unrestricted (or @dict). Note that this must be done both here and in the\n * subclass (eg, SerialPort), because otherwise the Compiler won't allow us to *reference*\n * the named property either.\n *\n * TODO: Consider marking ALL our classes unrestricted, because otherwise it forces us to\n * define every single property the class uses in its constructor, which results in a fair\n * bit of redundant initialization, since many properties aren't (and don't need to be) fully\n * initialized until the appropriate init(), reset(), restore(), etc. function is called.\n *\n * The upside, however, may be that since the structure of the class is completely defined by\n * the constructor, JavaScript engines may be able to optimize and run more efficiently.\n *\n * @unrestricted\n */\nclass Debugger extends Component\n{\n /**\n * Debugger(parmsDbg)\n *\n * The Debugger component supports the following optional (parmsDbg) properties:\n *\n * base: the base to use for most numeric input/output (default is 16)\n *\n * The Debugger component is a shared component containing a subset of functionality used by\n * the other CPU-specific Debuggers (eg, DebuggerX86). Over time, the goal is to factor out as\n * much common debugging support as possible from those components into this one.\n *\n * @param {Object} parmsDbg\n */\n constructor(parmsDbg)\n {\n if (DEBUGGER) {\n\n super(\"Debugger\", parmsDbg);\n\n /*\n * Default base used to display all values; modified with the \"s base\" command.\n */\n this.nBase = +parmsDbg['base'] || 16;\n\n /*\n * Default number of bits of integer precision; it can be overridden by the Debugger\n * but there is no command to adjust it.\n */\n this.nBits = 32;\n\n this.achGroup = ['{','}'];\n this.achAddress = ['[',']'];\n\n /*\n * These keep track of instruction activity, but only when tracing or when Debugger checks\n * have been enabled (eg, one or more breakpoints have been set).\n *\n * They are zeroed by the reset() notification handler. cInstructions is advanced by\n * stepCPU() and checkInstruction() calls. nCycles is updated by every stepCPU() or stop()\n * call and simply represents the number of cycles performed by the last run of instructions.\n */\n this.nCycles = 0;\n this.cOpcodes = this.cOpcodesStart = 0;\n\n /*\n * fAssemble is true when \"assemble mode\" is active, false when not.\n */\n this.fAssemble = false;\n\n /*\n * This maintains command history. New commands are inserted at index 0 of the array.\n * When Enter is pressed on an empty input buffer, we default to the command at aPrevCmds[0].\n */\n this.iPrevCmd = -1;\n this.aPrevCmds = [];\n\n /*\n * aVariables is an object with properties that grow as setVariable() assigns more variables;\n * each property corresponds to one variable, where the property name is the variable name (ie,\n * a string beginning with a non-digit, followed by zero or more symbol characters and/or digits)\n * and the property value is the variable's numeric value. See doVar() and setVariable() for\n * details.\n *\n * Note that parseValue() parses variables before numbers, so any variable that looks like a\n * unprefixed hex value (eg, \"a5\" as opposed to \"0xa5\") will trump the numeric value. Unprefixed\n * hex values are a convenience of parseValue(), which always calls Str.parseInt() with a default\n * base of 16; however, that default be overridden with a variety of explicit prefixes or suffixes\n * (eg, a leading \"0o\" to indicate octal, a trailing period to indicate decimal, etc.)\n *\n * See Str.parseInt() for more details about supported numbers.\n */\n this.aVariables = {};\n\n } // endif DEBUGGER\n }\n\n /**\n * getRegIndex(sReg, off)\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {string} sReg\n * @param {number} [off] optional offset into sReg\n * @return {number} register index, or -1 if not found\n */\n getRegIndex(sReg, off)\n {\n return -1;\n }\n\n /**\n * getRegValue(iReg)\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {number} iReg\n * @return {number|undefined}\n */\n getRegValue(iReg)\n {\n return undefined;\n }\n\n /**\n * parseAddrReference(s, sAddr)\n *\n * Returns the given string with the given address reference replaced with the contents of that address.\n *\n * NOTE: This must be implemented by the individual debuggers.\n *\n * @this {Debugger}\n * @param {string} s\n * @param {string} sAddr\n * @return {string}\n */\n parseAddrReference(s, sAddr)\n {\n return s.replace('[' + sAddr + ']', \"unimplemented\");\n }\n\n /**\n * getNextCommand()\n *\n * @this {Debugger}\n * @return {string}\n */\n getNextCommand()\n {\n var sCmd;\n if (this.iPrevCmd > 0) {\n sCmd = this.aPrevCmds[--this.iPrevCmd];\n } else {\n sCmd = \"\";\n this.iPrevCmd = -1;\n }\n return sCmd;\n }\n\n /**\n * getPrevCommand()\n *\n * @this {Debugger}\n * @return {string|null}\n */\n getPrevCommand()\n {\n var sCmd = null;\n if (this.iPrevCmd < this.aPrevCmds.length - 1) {\n sCmd = this.aPrevCmds[++this.iPrevCmd];\n }\n return sCmd;\n }\n\n /**\n * parseCommand(sCmd, fSave, chSep)\n *\n * @this {Debugger}\n * @param {string|undefined} sCmd\n * @param {boolean} [fSave] is true to save the command, false if not\n * @param {string} [chSep] is the command separator character (default is ';')\n * @return {Array.<string>}\n */\n parseCommand(sCmd, fSave, chSep)\n {\n if (fSave) {\n if (!sCmd) {\n if (this.fAssemble) {\n sCmd = \"end\";\n } else {\n sCmd = this.aPrevCmds[this.iPrevCmd+1];\n }\n } else {\n if (this.iPrevCmd < 0 && this.aPrevCmds.length) {\n this.iPrevCmd = 0;\n }\n if (this.iPrevCmd < 0 || sCmd != this.aPrevCmds[this.iPrevCmd]) {\n this.aPrevCmds.splice(0, 0, sCmd);\n this.iPrevCmd = 0;\n }\n this.iPrevCmd--;\n }\n }\n var a = [];\n if (sCmd) {\n /*\n * With the introduction of breakpoint commands (ie, quoted command sequences\n * associated with a breakpoint), we can no longer perform simplistic splitting.\n *\n * a = sCmd.split(chSep || ';');\n * for (var i = 0; i < a.length; i++) a[i] = Str.trim(a[i]);\n *\n * We may now split on semi-colons ONLY if they are outside a quoted sequence.\n *\n * Also, to allow quoted strings *inside* breakpoint commands, we first replace all\n * DOUBLE double-quotes with single quotes.\n */\n sCmd = sCmd.replace(/\"\"/g, \"'\");\n\n var iPrev = 0;\n var chQuote = null;\n chSep = chSep || ';';\n /*\n * NOTE: Processing charAt() up to and INCLUDING length is not a typo; we're taking\n * advantage of the fact that charAt() with an invalid index returns an empty string,\n * allowing us to use the same substring() call to capture the final portion of sCmd.\n *\n * In a sense, it allows us to pretend that the string ends with a zero terminator.\n */\n for (var i = 0; i <= sCmd.length; i++) {\n var ch = sCmd.charAt(i);\n if (ch == '\"' || ch == \"'\") {\n if (!chQuote) {\n chQuote = ch;\n } else if (ch == chQuote) {\n chQuote = null;\n }\n }\n else if (ch == chSep && !chQuote || !ch) {\n /*\n * Recall that substring() accepts starting (inclusive) and ending (exclusive)\n * indexes, whereas substr() accepts a starting index and a length. We need the former.\n */\n a.push(Str.trim(sCmd.substring(iPrev, i)));\n iPrev = i + 1;\n }\n }\n }\n return a;\n }\n\n /**\n * evalAND(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.AND().\n *\n * Performs the bitwise \"and\" (AND) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst & src)\n */\n evalAND(dst, src)\n {\n /*\n * We AND the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 AND 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst & src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) & ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst & src) >>> 0);\n }\n\n /**\n * evalIOR(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.IOR().\n *\n * Performs the logical \"inclusive-or\" (OR) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst | src)\n */\n evalIOR(dst, src)\n {\n /*\n * We OR the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 OR 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst | src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) | ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst | src) >>> 0);\n }\n\n /**\n * evalXOR(dst, src)\n *\n * Adapted from /modules/pdp10/lib/cpuops.js:PDP10.XOR().\n *\n * Performs the logical \"exclusive-or\" (XOR) of two operands > 32 bits.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst ^ src)\n */\n evalXOR(dst, src)\n {\n /*\n * We XOR the low 32 bits separately from the higher bits, and then combine them with addition.\n * Since all bits above 32 will be zero, and since 0 XOR 0 is 0, no special masking for the higher\n * bits is required.\n *\n * WARNING: When using JavaScript's 32-bit operators with values that could set bit 31 and produce a\n * negative value, it's critical to perform a final right-shift of 0, ensuring that the final result is\n * positive.\n */\n if (this.nBits <= 32) {\n return dst | src;\n }\n /*\n * Negative values don't yield correct results when dividing, so pass them through an unsigned truncate().\n */\n dst = this.truncate(dst, 0, true);\n src = this.truncate(src, 0, true);\n return ((((dst / Debugger.TWO_POW32)|0) ^ ((src / Debugger.TWO_POW32)|0)) * Debugger.TWO_POW32) + ((dst ^ src) >>> 0);\n }\n\n /**\n * evalMUL(dst, src)\n *\n * I could have adapted the code from /modules/pdp10/lib/cpuops.js:PDP10.doMUL(), but it was simpler to\n * write this base method and let the PDP-10 Debugger override it with a call to the *actual* doMUL() method.\n *\n * @this {Debugger}\n * @param {number} dst\n * @param {number} src\n * @return {number} (dst * src)\n */\n evalMUL(dst, src)\n {\n return dst * src;\n }\n\n /**\n * truncate(v, nBits, fUnsigned)\n *\n * @this {Debugger}\n * @param {number} v\n * @param {number} [nBits]\n * @param {boolean} [fUnsigned]\n * @return {number}\n */\n truncate(v, nBits, fUnsigned)\n {\n var limit, vNew = v;\n nBits = nBits || this.nBits;\n\n if (fUnsigned) {\n if (nBits == 32) {\n vNew = v >>> 0;\n }\n else if (nBits < 32) {\n vNew = v & ((1 << nBits) - 1);\n }\n else {\n limit = Math.pow(2, nBits);\n if (v < 0 || v >= limit) {\n vNew = v % limit;\n if (vNew < 0) vNew += limit;\n }\n }\n }\n else {\n if (nBits <= 32) {\n vNew = (v << (32 - nBits)) >> (32 - nBits);\n }\n else {\n limit = Math.pow(2, nBits - 1);\n if (v >= limit) {\n vNew = (v % limit);\n if (((v / limit)|0) & 1) vNew -= limit;\n } else if (v < -limit) {\n vNew = (v % limit);\n if ((((-v - 1) / limit) | 0) & 1) {\n if (vNew) vNew += limit;\n }\n else {\n if (!vNew) vNew -= limit;\n }\n }\n }\n }\n if (v != vNew) {\n if (MAXDEBUG) this.println(\"warning: value \" + v + \" truncated to \" + vNew);\n v = vNew;\n }\n return v;\n }\n\n /**\n * evalOps(aVals, aOps, cOps)\n *\n * Some of our clients want a specific number of bits of integer precision. If that precision is\n * greater than 32, some of the operations below will fail; for example, JavaScript bitwise operators\n * always truncate the result to 32 bits, so beware when using shift operations. Similarly, it would\n * be wrong to always \"|0\" the final result, which is why we rely on truncate() now.\n *\n * Note that JavaScript integer precision is limited to 52 bits. For example, in Node, if you set a\n * variable to 0x80000001:\n *\n * foo=0x80000001|0\n *\n * then calculate foo*foo and display the result in binary using \"(foo*foo).toString(2)\":\n *\n * '11111111111111111111111111111100000000000000000000000000000000'\n *\n * which is slightly incorrect because it has overflowed JavaScript's floating-point precision.\n *\n * 0x80000001 in decimal is -2147483647, so the product is 4611686014132420609, which is 0x3FFFFFFF00000001.\n *\n * @this {Debugger}\n * @param {Array.<number>} aVals\n * @param {Array.<string>} aOps\n * @param {number} [cOps] (default is -1 for all)\n * @return {boolean} true if successful, false if error\n */\n evalOps(aVals, aOps, cOps = -1)\n {\n while (cOps-- && aOps.length) {\n var chOp = aOps.pop();\n if (aVals.length < 2) return false;\n var valNew;\n var val2 = aVals.pop();\n var val1 = aVals.pop();\n switch(chOp) {\n case '*':\n valNew = this.evalMUL(val1, val2);\n break;\n case '/':\n if (!val2) return false;\n valNew = Math.trunc(val1 / val2);\n break;\n case '^/':\n if (!val2) return false;\n valNew = val1 % val2;\n break;\n case '+':\n valNew = val1 + val2;\n break;\n case '-':\n valNew = val1 - val2;\n break;\n case '<<':\n valNew = val1 << val2;\n break;\n case '>>':\n valNew = val1 >> val2;\n break;\n case '>>>':\n valNew = val1 >>> val2;\n break;\n case '<':\n valNew = (val1 < val2? 1 : 0);\n break;\n case '<=':\n valNew = (val1 <= val2? 1 : 0);\n break;\n case '>':\n valNew = (val1 > val2? 1 : 0);\n break;\n case '>=':\n valNew = (val1 >= val2? 1 : 0);\n break;\n case '==':\n valNew = (val1 == val2? 1 : 0);\n break;\n case '!=':\n valNew = (val1 != val2? 1 : 0);\n break;\n case '&':\n valNew = this.evalAND(val1, val2);\n break;\n case '!': // alias for MACRO-10 to perform a bitwise inclusive-or (OR)\n case '|':\n valNew = this.evalIOR(val1, val2);\n break;\n case '^!': // since MACRO-10 uses '^' for base overrides, '^!' is used for bitwise exclusive-or (XOR)\n valNew = this.evalXOR(val1, val2);\n break;\n case '&&':\n valNew = (val1 && val2? 1 : 0);\n break;\n case '||':\n valNew = (val1 || val2? 1 : 0);\n break;\n case ',,':\n valNew = this.truncate(val1, 18, true) * Math.pow(2, 18) + this.truncate(val2, 18, true);\n break;\n case '_':\n case '^_':\n valNew = val1;\n /*\n * While we always try to avoid assuming any particular number of bits of precision, the 'B' shift\n * operator (which we've converted to '^_') is unique to the MACRO-10 environment, which imposes the\n * following restrictions on the shift count.\n */\n if (chOp == '^_') val2 = 35 - (val2 & 0xff);\n if (val2) {\n /*\n * Since binary shifting is a logical (not arithmetic) operation, and since shifting by division only\n * works properly with positive numbers, we call truncate() to produce an unsigned value.\n */\n valNew = this.truncate(valNew, 0, true);\n if (val2 > 0) {\n valNew *= Math.pow(2, val2);\n } else {\n valNew = Math.trunc(valNew / Math.pow(2, -val2));\n }\n }\n break;\n default:\n return false;\n }\n aVals.push(this.truncate(valNew));\n }\n return true;\n }\n\n /**\n * parseArray(asValues, iValue, iLimit, nBase, aUndefined)\n *\n * parseExpression() takes a complete expression and divides it into array elements, where even elements\n * are values (which may be empty if two or more operators appear consecutively) and odd elements are operators.\n *\n * For example, if the original expression was \"2*{3+{4/2}}\", parseExpression() would call parseArray() with:\n *\n * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14\n * - - - - - - - - - - -- -- -- -- --\n * 2 * { 3 + { 4 / 2 } }\n *\n * This function takes care of recursively processing grouped expressions, by processing subsets of the array,\n * as well as handling certain base overrides (eg, temporarily switching to base-10 for binary shift suffixes).\n *\n * @param {Array.<string>} asValues\n * @param {number} iValue\n * @param {number} iLimit\n * @param {number} nBase\n * @param {Array|undefined} [aUndefined]\n * @return {number|undefined}\n */\n parseArray(asValues, iValue, iLimit, nBase, aUndefined)\n {\n var value;\n var sValue, sOp;\n var fError = false;\n var nUnary = 0;\n var aVals = [], aOps = [];\n\n var nBasePrev = this.nBase;\n this.nBase = nBase;\n\n while (iValue < iLimit) {\n var v;\n sValue = asValues[iValue++].trim();\n sOp = (iValue < iLimit? asValues[iValue++] : \"\");\n\n if (sValue) {\n v = this.parseValue(sValue, null, aUndefined, nUnary);\n } else {\n if (sOp == '{') {\n var cOpen = 1;\n var iStart = iValue;\n while (iValue < iLimit) {\n sValue = asValues[iValue++].trim();\n sOp = (iValue < asValues.length? asValues[iValue++] : \"\");\n if (sOp == '{') {\n cOpen++;\n } else if (sOp == '}') {\n if (!--cOpen) break;\n }\n }\n v = this.parseArray(asValues, iStart, iValue-1, this.nBase, aUndefined);\n if (v != null && nUnary) {\n v = this.parseUnary(v, nUnary);\n }\n sValue = (iValue < iLimit? asValues[iValue++].trim() : \"\");\n sOp = (iValue < iLimit? asValues[iValue++] : \"\");\n }\n else {\n /*\n * When parseExpression() calls us, it has collapsed all runs of whitespace into single spaces,\n * and although it allows single spaces to divide the elements of the expression, a space is neither\n * a unary nor binary operator. It's essentially a no-op. If we encounter it here, then it followed\n * another operator and is easily ignored (although perhaps it should still trigger a reset of nBase\n * and nUnary -- TBD).\n */\n if (sOp == ' ') {\n continue;\n }\n if (sOp == '^B') {\n this.nBase = 2;\n continue;\n }\n if (sOp == '^O') {\n this.nBase = 8;\n continue;\n }\n if (sOp == '^D') {\n this.nBase = 10;\n continue;\n }\n if (!(nUnary & (0xC0000000|0))) {\n if (sOp == '+') {\n continue;\n }\n if (sOp == '-') {\n nUnary = (nUnary << 2) | 1;\n continue;\n }\n if (sOp == '~' || sOp == '^-') {\n nUnary = (nUnary << 2) | 2;\n continue;\n }\n if (sOp == '^L') {\n nUnary = (nUnary << 2) | 3;\n continue;\n }\n }\n fError = true;\n break;\n }\n }\n\n if (v === undefined) {\n if (aUndefined) {\n aUndefined.push(sValue);\n v = 0;\n } else {\n fError = true;\n aUndefined = [];\n break;\n }\n }\n\n aVals.push(this.truncate(v));\n\n /*\n * When parseExpression() calls us, it has collapsed all runs of whitespace into single spaces,\n * and although it allows single spaces to divide the elements of the expression, a space is neither\n * a unary nor binary operator. It's essentially a no-op. If we encounter it here, then it followed\n * a value, and since we don't want to misinterpret the next operator as a unary operator, we look\n * ahead and grab the next operator if it's not preceded by a value.\n */\n if (sOp == ' ') {\n if (iValue < asValues.length - 1 && !asValues[iValue]) {\n iValue++;\n sOp = asValues[iValue++]\n } else {\n fError = true;\n break;\n }\n }\n\n if (!sOp) break;\n\n var aBinOp = (this.achGroup[0] == '<'? Debugger.aDECOpPrecedence : Debugger.aBinOpPrecedence);\n if (!aBinOp[sOp]) {\n fError = true;\n break;\n }\n if (aOps.length && aBinOp[sOp] <= aBinOp[aOps[aOps.length - 1]]) {\n this.evalOps(aVals, aOps, 1);\n }\n aOps.push(sOp);\n\n /*\n * The MACRO-10 binary shifting operator assumes a base-10 shift count, regardless of the current\n * base, so we must override the current base to ensure the count is parsed correctly.\n */\n this.nBase = (sOp == '^_')? 10 : nBase;\n nUnary = 0;\n }\n\n if (fError || !this.evalOps(aVals, aOps) || aVals.length != 1) {\n fError = true;\n }\n\n if (!fError) {\n value = aVals.pop();\n\n } else if (!aUndefined) {\n this.println(\"parse error (\" + (sValue || sOp) + \")\");\n }\n\n this.nBase = nBasePrev;\n return value;\n }\n\n /**\n * parseASCII(sExp, chDelim, nBits, cchMax)\n *\n * @this {Debugger}\n * @param {string} sExp\n * @param {string} chDelim\n * @param {number} nBits\n * @param {number} cchMax\n * @return {string|undefined}\n */\n parseASCII(sExp, chDelim, nBits, cchMax)\n {\n var i;\n while ((i = sExp.indexOf(chDelim)) >= 0) {\n var v = 0;\n var j = i + 1;\n var cch = cchMax;\n while (j < sExp.length) {\n var ch = sExp[j++];\n if (ch == chDelim) {\n cch = -1;\n break;\n }\n if (!cch) break;\n cch--;\n var c = ch.charCodeAt(0);\n if (nBits == 7) {\n c &= 0x7F;\n } else {\n c = (c - 0x20) & 0x3F;\n }\n v = this.truncate(v * Math.pow(2, nBits) + c, nBits * cchMax, true);\n }\n if (cch >= 0) {\n this.println(\"parse error (\" + chDelim + sExp + chDelim + \")\");\n return undefined;\n } else {\n sExp = sExp.substr(0, i) + this.toStrBase(v, -1) + sExp.substr(j);\n }\n }\n return sExp;\n }\n\n /**\n * parseExpression(sExp, fQuiet)\n *\n * A quick-and-dirty expression parser. It takes an expression like:\n *\n * EDX+EDX*4+12345678\n *\n * and builds a value stack in aVals and a \"binop\" (binary operator) stack in aOps:\n *\n * aVals aOps\n * ----- ----\n * EDX +\n * EDX *\n * 4 +\n * ...\n *\n * We pop 1 \"binop\" from aOps and 2 values from aVals whenever a \"binop\" of lower priority than its\n * predecessor is encountered, evaluate, and push the result back onto aVals. Only selected unary\n * operators are supported (eg, negate and complement); no ternary operators like '?:' are supported.\n *\n * fQuiet can be used to pass an array that collects any undefined variables that parseExpression()\n * encounters; the value of an undefined variable is zero. This mode was added for components that need\n * to support expressions containing \"fixups\" (ie, values that must be determined later).\n *\n * @this {Debugger}\n * @param {string|undefined} sExp\n * @param {Array|undefined|boolean} [fQuiet]\n * @return {number|undefined} numeric value, or undefined if sExp contains any undefined or invalid values\n */\n parseExpression(sExp, fQuiet)\n {\n var value = undefined;\n var fPrint = (fQuiet === false);\n var aUndefined = Array.isArray(fQuiet)? fQuiet : undefined;\n\n if (sExp) {\n\n /*\n * The default delimiting characters for grouped expressions are braces; they can be changed by altering\n * achGroup, but when that happens, instead of changing our regular expressions and operator tables,\n * we simply replace all achGroup characters with braces in the given expression.\n *\n * Why not use parentheses for grouped expressions? Because some debuggers use parseReference() to perform\n * parenthetical value replacements in message strings, and they don't want parentheses taking on a different\n * meaning. And for some machines, like the PDP-10, the convention is to use parentheses for other things,\n * like indexed addressing, and to use angle brackets for grouped expressions.\n */\n if (this.achGroup[0] != '{') {\n sExp = sExp.split(this.achGroup[0]).join('{').split(this.achGroup[1]).join('}');\n }\n\n /*\n * Quoted ASCII characters can have a numeric value, too, which must be converted now, to avoid any\n * conflicts with the operators below.\n */\n sExp = this.parseASCII(sExp, '\"', 7, 5); // MACRO-10 packs up to 5 7-bit ASCII codes into a value\n if (!sExp) return value;\n sExp = this.parseASCII(sExp, \"'\", 6, 6); // MACRO-10 packs up to 6 6-bit ASCII (SIXBIT) codes into a value\n if (!sExp) return value;\n\n /*\n * All browsers (including, I believe, IE9 and up) support the following idiosyncrasy of a RegExp split():\n * when the RegExp uses a capturing pattern, the resulting array will include entries for all the pattern\n * matches along with the non-matches. This effectively means that, in the set of expressions that we\n * support, all even entries in asValues will contain \"values\" and all odd entries will contain \"operators\".\n *\n * Although I started listing the operators in the RegExp in \"precedential\" order, that's not important;\n * what IS important is listing operators than contain shorter operators first. For example, bitwise\n * shift operators must be listed BEFORE the logical less-than or greater-than operators. The aBinOp tables\n * (aBinOpPrecedence and aDECOpPrecedence) are what determine precedence, not the RegExp.\n *\n * Also, to better accommodate MACRO-10 syntax, I've replaced the single '^' for XOR with '^!', and I've\n * added '!' as an alias for '|' (bitwise inclusive-or), '^-' as an alias for '~' (one's complement operator),\n * and '_' as a shift operator (+/- values specify a left/right shift, and the count is not limited to 32).\n *\n * And to avoid conflicts with MACRO-10 syntax, I've replaced the original mod operator ('%') with '^/'.\n *\n * The MACRO-10 binary shifting suffix ('B') is a bit more problematic, since a capital B can also appear\n * inside symbols, or inside hex values. So if the default base is NOT 16, then I pre-scan for that suffix\n * and replace all non-symbolic occurrences with an internal shift operator ('^_').\n *\n * Note that Str.parseInt(), which parseValue() relies on, supports both the MACRO-10 base prefix overrides\n * and the binary shifting suffix ('B'), but since that suffix can also be a bracketed expression, we have to\n * support it here as well.\n *\n * MACRO-10 supports only a subset of all the PCjs operators; for example, MACRO-10 doesn't support any of\n * the boolean logical/compare operators. But unless we run into conflicts, I prefer sticking with this\n * common set of operators.\n *\n * All whitespace in the expression is collapsed to single spaces, and space has been added to the list\n * of \"operators\", but its sole function is as a separator, not as an operator. parseArray() will ignore\n * single spaces as long as they are preceded and/or followed by a \"real\" operator. It would be dangerous\n * to remove spaces entirely, because if an operator-less expression like \"A B\" was passed in, we would want\n * that to generate an error; if we converted it to \"AB\", evaluation might inadvertently succeed.\n */\n var regExp = /({|}|\\|\\||&&|\\||\\^!|\\^B|\\^O|\\^D|\\^L|\\^-|~|\\^_|_|&|!=|!|==|>=|>>>|>>|>|<=|<<|<|-|\\+|\\^\\/|\\/|\\*|,,| )/;\n if (this.nBase != 16) {\n sExp = sExp.replace(/(^|[^A-Z0-9$%.])([0-9]+)B/, \"$1$2^_\").replace(/\\s+/g, ' ');\n }\n var asValues = sExp.split(regExp);\n value = this.parseArray(asValues, 0, asValues.length, this.nBase, aUndefined);\n if (value !== undefined && fPrint) {\n this.printValue(null, value);\n }\n }\n return value;\n }\n\n /**\n * parseReference(s)\n *\n * Returns the given string with any \"{expression}\" sequences replaced with the value of the expression,\n * and any \"[address]\" references replaced with the contents of the address. Expressions are parsed BEFORE\n * addresses.\n *\n * @this {Debugger}\n * @param {string} s\n * @return {string|undefined}\n */\n parseReference(s)\n {\n var a;\n var chOpen = this.achGroup[0];\n var chClose = this.achGroup[1];\n var chEscape = (chOpen == '(' || chOpen == '{' || chOpen == '[')? '\\\\' : '';\n var chInnerEscape = (chOpen == '['? '\\\\' : '');\n var reSubExp = new RegExp(chEscape + chOpen + \"([^\" + chInnerEscape + chOpen + chInnerEscape + chClose + \"]+)\" + chEscape + chClose);\n while (a = s.match(reSubExp)) {\n var value = this.parseExpression(a[1]);\n if (value === undefined) return undefined;\n var sSearch = chOpen + a[1] + chClose;\n var sReplace = value != null? this.toStrBase(value) : \"undefined\";\n /*\n * Note that by default, the String replace() method only replaces the FIRST occurrence,\n * and there MIGHT be more than one occurrence of the expression we just parsed, so we could\n * do this instead:\n *\n * s = s.split(sSearch).join(sReplace);\n *\n * However, that's knd of an expensive (slow) solution, and it's not strictly necessary, since\n * any additional identical expressions will be picked up on a subsequent iteration through this loop.\n */\n s = s.replace(sSearch, sReplace);\n }\n if (this.achAddress.length) {\n chOpen = this.achAddress[0];\n chClose = this.achAddress[1];\n chEscape = (chOpen == '(' || chOpen == '{' || chOpen == '[')? '\\\\' : '';\n chInnerEscape = (chOpen == '['? '\\\\' : '');\n reSubExp = new RegExp(chEscape + chOpen + \"([^\" + chInnerEscape + chOpen + chInnerEscape + chClose + \"]+)\" + chEscape + chClose);\n while (a = s.match(reSubExp)) {\n s = this.parseAddrReference(s, a[1]);\n }\n }\n return this.parseSysVars(s);\n }\n\n /**\n * parseSysVars(s)\n *\n * Returns the given string with any recognized \"$var\" replaced with its value; eg:\n *\n * $ops: the number of opcodes executed since the last time it was displayed (or reset)\n *\n * @this {Debugger}\n * @param {string} s\n * @return {string}\n */\n parseSysVars(s)\n {\n var a;\n while (a = s.match(/\\$([a-z]+)/i)) {\n var v = null;\n switch(a[1].toLowerCase()) {\n case \"ops\":\n v = this.cOpcodes - this.cOpcodesStart;\n break;\n }\n if (v == null) break;\n s = s.replace(a[0], v.toString());\n }\n return s;\n }\n\n /**\n * parseUnary(value, nUnary)\n *\n * nUnary is actually a small \"stack\" of unary operations encoded in successive pairs of bits.\n * As parseExpression() encounters each unary operator, nUnary is shifted left 2 bits, and the\n * new unary operator is encoded in bits 0 and 1 (0b00 is none, 0b01 is negate, 0b10 is complement,\n * and 0b11 is reserved). Here, we process the bits in reverse order (hence the stack-like nature),\n * ensuring that we process the unary operators associated with this value right-to-left.\n *\n * Since bitwise operators see only 32 bits, more than 16 unary operators cannot be supported\n * using this method. We'll let parseExpression() worry about that; if it ever happens in practice,\n * then we'll have to switch to a more \"expensive\" approach (eg, an actual array of unary operators).\n *\n * @this {Debugger}\n * @param {number} value\n * @param {number} nUnary\n * @return {number}\n */\n parseUnary(value, nUnary)\n {\n while (nUnary) {\n switch(nUnary & 0o3) {\n case 1:\n value = -this.truncate(value);\n break;\n case 2:\n value = this.evalXOR(value, -1); // this is easier than adding an evalNOT()...\n break;\n case 3:\n var bit = 35; // simple left-to-right zero-bit-counting loop...\n while (bit >= 0 && !this.evalAND(value, Math.pow(2, bit))) bit--;\n value = 35 - bit;\n break;\n }\n nUnary >>>= 2;\n }\n return value;\n }\n\n /**\n * parseValue(sValue, sName, fQuiet, nUnary)\n *\n * @this {Debugger}\n * @param {string|undefined} sValue\n * @param {string|null|*} [sName] is the name of the value, if any\n * @param {Array|undefined|boolean} [fQuiet]\n * @param {number} [nUnary] (0 for none, 1 for negate, 2 for complement, 3 for leading zeros)\n * @return {number|undefined} numeric value, or undefined if sValue is either undefined or invalid\n */\n parseValue(sValue, sName, fQuiet, nUnary = 0)\n {\n var value;\n var aUndefined = Array.isArray(fQuiet)? fQuiet : undefined;\n\n if (sValue != null) {\n var iReg = this.getRegIndex(sValue);\n if (iReg >= 0) {\n value = this.getRegValue(iReg);\n } else {\n value = this.getVariable(sValue);\n if (value != null) {\n var sUndefined = this.getVariableFixup(sValue);\n if (sUndefined) {\n if (aUndefined) {\n aUndefined.push(sUndefined);\n } else {\n var valueUndefined = this.parseExpression(sUndefined, fQuiet);\n if (valueUndefined !== undefined) {\n value += valueUndefined;\n } else {\n if (!fQuiet) {\n this.println(\"undefined \" + (sName || \"value\") + \": \" + sValue + \" (\" + sUndefined + \")\");\n }\n value = undefined;\n }\n }\n }\n } else {\n /*\n * A feature of MACRO-10 is that any single-digit number is automatically interpreted as base-10.\n */\n value = Str.parseInt(sValue, sValue.length > 1 || this.nBase > 10? this.nBase : 10);\n }\n }\n if (value != null) {\n value = this.truncate(this.parseUnary(value, nUnary));\n } else {\n if (!fQuiet) {\n this.println(\"invalid \" + (sName || \"value\") + \": \" + sValue);\n }\n }\n } else {\n if (!fQuiet) {\n this.println(\"missing \" + (sName || \"value\"));\n }\n }\n return value;\n }\n\n /**\n * printValue(sVar, value)\n *\n * @this {Debugger}\n * @param {string|null} sVar\n * @param {number|undefined} value\n * @return {boolean} true if value defined, false if not\n */\n printValue(sVar, value)\n {\n var sValue;\n var fDefined = false;\n if (value !== undefined) {\n fDefined = true;\n if (this.nBase == 8) {\n sValue = this.toStrBase(value, this.nBits, 8, 1) + \" \" + value + '.';\n } else {\n sValue = this.toStrBase(value, this.nBits, 16, 1) + \" \" + this.toStrBase(value, this.nBits, 8, 1) + \" \" + this.toStrBase(value, this.nBits, 2, this.nBits <= 32? 8 : 6) + \" \" + value + '.';\n }\n if (value >= 0x20 && value < 0x7F) {\n sValue += \" '\" + String.fromCharCode(value) + \"'\";\n }\n }\n sVar = (sVar != null? (sVar + \": \") : \"\");\n this.println(sVar + sValue);\n return fDefined;\n }\n\n /**\n * resetVariables()\n *\n * @this {Debugger}\n * @return {Object}\n */\n resetVariables()\n {\n var a = this.aVariables;\n this.aVariables = {};\n return a;\n }\n\n /**\n * restoreVariables(a)\n *\n * @this {Debugger}\n * @param {Object} a (from previous resetVariables() call)\n */\n restoreVariables(a)\n {\n this.aVariables = a;\n }\n\n /**\n * printVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} [sVar]\n * @return {boolean} true if all value(s) defined, false if not\n */\n printVariable(sVar)\n {\n var cVariables = 0;\n if (this.aVariables) {\n if (sVar) {\n return this.printValue(sVar, this.aVariables[sVar] && this.aVariables[sVar].value);\n }\n var aVars = Object.keys(this.aVariables);\n aVars.sort();\n for (var i = 0; i < aVars.length; i++) {\n this.printValue(aVars[i], this.aVariables[aVars[i]].value);\n cVariables++;\n }\n }\n return cVariables > 0;\n }\n\n /**\n * delVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n */\n delVariable(sVar)\n {\n delete this.aVariables[sVar];\n }\n\n /**\n * getVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {number|undefined}\n */\n getVariable(sVar)\n {\n if (this.aVariables[sVar]) {\n return this.aVariables[sVar].value;\n }\n sVar = sVar.substr(0, 6);\n return this.aVariables[sVar] && this.aVariables[sVar].value;\n }\n\n /**\n * getVariableFixup(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {string|undefined}\n */\n getVariableFixup(sVar)\n {\n return this.aVariables[sVar] && this.aVariables[sVar].sUndefined;\n }\n\n /**\n * isVariable(sVar)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @return {boolean}\n */\n isVariable(sVar)\n {\n return this.aVariables[sVar] !== undefined;\n }\n\n /**\n * setVariable(sVar, value, sUndefined)\n *\n * @this {Debugger}\n * @param {string} sVar\n * @param {number} value\n * @param {string|undefined} [sUndefined]\n */\n setVariable(sVar, value, sUndefined)\n {\n this.aVariables[sVar] = {value, sUndefined};\n }\n\n /**\n * toStrBase(n, nBits, nBase, nGrouping)\n *\n * Use this instead of Str's toOct()/toDec()/toHex() to convert numbers to the Debugger's default base.\n *\n * @this {Debugger}\n * @param {number|null|undefined} n\n * @param {number} [nBits] (-1 to strip leading zeros, 0 to allow a variable number of digits)\n * @param {number} [nBase]\n * @param {number} [nGrouping] (if nBase is 2, this is a grouping; otherwise, it's a prefix condition)\n * @return {string}\n */\n toStrBase(n, nBits = 0, nBase = 0, nGrouping = 0)\n {\n var s;\n switch(nBase || this.nBase) {\n case 2:\n s = Str.toBin(n, nBits > 0? nBits : 0, nGrouping);\n break;\n case 8:\n s = Str.toOct(n, nBits > 0? ((nBits + 2)/3)|0 : 0, !!nGrouping);\n break;\n case 10:\n /*\n * The multiplier is actually Math.log(2)/Math.log(10), but an approximation is more than adequate.\n */\n s = Str.toDec(n, nBits > 0? Math.ceil(nBits * 0.3) : 0);\n break;\n case 16:\n default:\n s = Str.toHex(n, nBits > 0? ((nBits + 3) >> 2) : 0, !!nGrouping);\n break;\n }\n return (nBits < 0? Str.stripLeadingZeros(s) : s);\n }\n}\n\nif (DEBUGGER) {\n\n /*\n * These are our operator precedence tables. Operators toward the bottom (with higher values) have\n * higher precedence. aBinOpPrecedence was our original table; we had to add aDECOpPrecedence because\n * the precedence of operators in DEC's MACRO-10 expressions differ. Having separate tables also allows\n * us to remove operators that shouldn't be supported, but unless some operator creates a problem,\n * I prefer to keep as much commonality between the tables as possible.\n *\n * Missing from these tables are the (limited) set of unary operators we support (negate and complement),\n * since this is only a BINARY operator precedence, not a general-purpose precedence table. Assume that\n * all unary operators take precedence over all binary operators.\n */\n Debugger.aBinOpPrecedence = {\n '||': 5, // logical OR\n '&&': 6, // logical AND\n '!': 7, // bitwise OR (conflicts with logical NOT, but we never supported that)\n '|': 7, // bitwise OR\n '^!': 8, // bitwise XOR (added by MACRO-10 sometime between the 1972 and 1978 versions)\n '&': 9, // bitwise AND\n '!=': 10, // inequality\n '==': 10, // equality\n '>=': 11, // greater than or equal to\n '>': 11, // greater than\n '<=': 11, // less than or equal to\n '<': 11, // less than\n '>>>': 12, // unsigned bitwise right shift\n '>>': 12, // bitwise right shift\n '<<': 12, // bitwise left shift\n '-': 13, // subtraction\n '+': 13, // addition\n '^/': 14, // remainder\n '/': 14, // division\n '*': 14, // multiplication\n '_': 19, // MACRO-10 shift operator\n '^_': 19, // MACRO-10 internal shift operator (converted from 'B' suffix form that MACRO-10 uses)\n '{': 20, // open grouped expression (converted from achGroup[0])\n '}': 20 // close grouped expression (converted from achGroup[1])\n };\n Debugger.aDECOpPrecedence = {\n ',,': 1, // high-word,,low-word\n '||': 5, // logical OR\n '&&': 6, // logical AND\n '!=': 10, // inequality\n '==': 10, // equality\n '>=': 11, // greater than or equal to\n '>': 11, // greater than\n '<=': 11, // less than or equal to\n '<': 11, // less than\n '>>>': 12, // unsigned bitwise right shift\n '>>': 12, // bitwise right shift\n '<<': 12, // bitwise left shift\n '-': 13, // subtraction\n '+': 13, // addition\n '^/': 14, // remainder\n '/': 14, // division\n '*': 14, // multiplication\n '!': 15, // bitwise OR (conflicts with logical NOT, but we never supported that)\n '|': 15, // bitwise OR\n '^!': 15, // bitwise XOR (added by MACRO-10 sometime between the 1972 and 1978 versions)\n '&': 15, // bitwise AND\n '_': 19, // MACRO-10 shift operator\n '^_': 19, // MACRO-10 internal shift operator (converted from 'B' suffix form that MACRO-10 uses)\n '{': 20, // open grouped expression (converted from achGroup[0])\n '}': 20 // close grouped expression (converted from achGroup[1])\n };\n\n /*\n * Assorted constants\n */\n Debugger.TWO_POW32 = Math.pow(2, 32);\n\n} // endif DEBUGGER\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/debugger.js (C) Jeff Parsons 2012-2018\n */\n\n\n/**\n * DebuggerPDP11 Address Object\n *\n * addr address\n * fPhysical true if this is a physical address\n * fTemporary true if this is a temporary breakpoint address\n * nBase set if the address contained an explicit base (eg, 16, 10, 8, etc)\n * sCmd set for breakpoint addresses if there's an associated command string\n * aCmds preprocessed commands (from sCmd)\n *\n * @typedef {{\n * addr:(number|null),\n * fPhysical:(boolean),\n * fTemporary:(boolean),\n * nBase:(number|undefined),\n * sCmd:(string|undefined),\n * aCmds:(Array.<string>|undefined)\n * }}\n */\nvar DbgAddrPDP11;\n\nclass DebuggerPDP11 extends Debugger {\n /**\n * DebuggerPDP11(parmsDbg)\n *\n * The DebuggerPDP11 component supports the following optional (parmsDbg) properties:\n *\n * commands: string containing zero or more commands, separated by ';'\n *\n * messages: string containing zero or more message categories to enable;\n * multiple categories must be separated by '|' or ';'. Parsed by messageInit().\n *\n * The DebuggerPDP11 component is an optional component that implements a variety of user\n * commands for controlling the CPU, dumping and editing memory, etc.\n *\n * @param {Object} parmsDbg\n */\n constructor(parmsDbg)\n {\n if (DEBUGGER) {\n\n super(parmsDbg);\n\n /*\n * Since this Debugger doesn't use replaceRegs(), we can use parentheses instead of braces.\n */\n this.fInit = false;\n\n this.achGroup = ['(',')'];\n this.achAddress = [];\n\n /*\n * Most commands that require an address call parseAddr(), which defaults to dbgAddrNextCode\n * or dbgAddrNextData when no address has been given. doDump() and doUnassemble(), in turn,\n * update dbgAddrNextData and dbgAddrNextCode, respectively, when they're done.\n *\n * For TEMPORARY breakpoint addresses, we set fTemporary to true, so that they can be automatically\n * cleared when they're hit.\n */\n this.dbgAddrNextCode = this.newAddr();\n this.dbgAddrNextData = this.newAddr();\n this.dbgAddrAssemble = this.newAddr();\n\n /*\n * aSymbolTable is an array of SymbolTable objects, one per ROM or other chunk of address space,\n * where each object contains the following properties:\n *\n * sModule\n * addr (physical address, if any; eg, symbols for a ROM)\n * len\n * aSymbols\n * aOffsets\n *\n * See addSymbols() for more details, since that's how callers add sets of symbols to the table.\n */\n this.aSymbolTable = [];\n\n /*\n * clearBreakpoints() initializes the breakpoints lists: aBreakExec is a list of addresses\n * to halt on whenever attempting to execute an instruction at the corresponding address,\n * and aBreakRead and aBreakWrite are lists of addresses to halt on whenever a read or write,\n * respectively, occurs at the corresponding address.\n *\n * NOTE: Curiously, after upgrading the Google Closure Compiler from v20141215 to v20150609,\n * the resulting compiled code would crash in clearBreakpoints(), because the (renamed) aBreakRead\n * property was already defined. To eliminate whatever was confusing the Closure Compiler, I've\n * explicitly initialized all the properties that clearBreakpoints() (re)initializes.\n */\n this.aBreakExec = this.aBreakRead = this.aBreakWrite = [];\n this.clearBreakpoints();\n\n /*\n * The new \"bn\" command allows you to specify a number of instructions to execute and then stop;\n * \"bn 0\" disables any outstanding count.\n */\n this.nBreakInstructions = 0;\n\n /*\n * Execution history is allocated by historyInit() whenever checksEnabled() conditions change.\n * Execution history is updated whenever the CPU calls checkInstruction(), which will happen\n * only when checksEnabled() returns true (eg, whenever one or more breakpoints have been set).\n * This ensures that, by default, the CPU runs as fast as possible.\n */\n this.iInstructionHistory = 0;\n this.aInstructionHistory = [];\n this.nextHistory = undefined;\n this.historyInit();\n\n /*\n * Initialize DebuggerPDP11 message support.\n */\n this.dbg = this;\n this.afnDumpers = {};\n this.bitsMessage = this.bitsWarning = 0;\n this.sMessagePrev = null;\n this.aMessageBuffer = [];\n this.messageInit(parmsDbg['messages']);\n this.sInitCommands = parmsDbg['commands'];\n\n /*\n * Define remaining miscellaneous DebuggerPDP11 properties.\n */\n this.opTable = DebuggerPDP11.OPTABLE;\n this.aOpReserved = [];\n this.nStep = 0;\n this.sCmdTracePrev = null;\n this.sCmdDumpPrev = null;\n this.fIgnoreNextCheckFault = false; // TODO: Does this serve any purpose on a PDP-11?\n this.nSuppressBreaks = 0;\n this.cInstructions = this.cInstructionsStart = 0;\n this.nCycles = this.nCyclesStart = this.msStart = 0;\n this.controlDebug = null;\n this.panel = null;\n\n /*\n * Make it easier to access DebuggerPDP11 commands from an external REPL (eg, the WebStorm\n * \"live\" console window); eg:\n *\n * pdp11('r')\n * pdp11('dw 0:0')\n * pdp11('h')\n * ...\n */\n var dbg = this;\n if (window) {\n if (window[PDP11.APPCLASS] === undefined) {\n window[PDP11.APPCLASS] = function(s) { return dbg.doCommands(s); };\n }\n } else {\n if (global[PDP11.APPCLASS] === undefined) {\n global[PDP11.APPCLASS] = function(s) { return dbg.doCommands(s); };\n }\n }\n\n } // endif DEBUGGER\n }\n\n /**\n * getAddr(dbgAddr, fWrite, nb)\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11|null} [dbgAddr]\n * @param {boolean} [fWrite]\n * @param {number} [nb] number of bytes to check (1 or 2); default is 1\n * @return {number} is the corresponding linear address, or PDP11.ADDR_INVALID\n */\n getAddr(dbgAddr, fWrite, nb)\n {\n var addr = dbgAddr && dbgAddr.addr;\n if (addr == null) addr = PDP11.ADDR_INVALID;\n return addr;\n }\n\n /**\n * newAddr(addr, fPhysical, nBase)\n *\n * Returns a NEW DbgAddrPDP11 object, initialized with specified values and/or defaults.\n *\n * @this {DebuggerPDP11}\n * @param {number|null} [addr]\n * @param {boolean} [fPhysical]\n * @param {number} [nBase]\n * @return {DbgAddrPDP11}\n */\n newAddr(addr = null, fPhysical = false, nBase)\n {\n return {addr: addr, fPhysical: fPhysical, fTemporary: false, nBase: nBase};\n }\n\n /**\n * setAddr(dbgAddr, addr)\n *\n * Updates an EXISTING DbgAddrPDP11 object, initialized with specified values and/or defaults.\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @param {number} addr\n * @return {DbgAddrPDP11}\n */\n setAddr(dbgAddr, addr)\n {\n dbgAddr.addr = addr;\n dbgAddr.fTemporary = false;\n dbgAddr.nBase = undefined;\n return dbgAddr;\n }\n\n /**\n * packAddr(dbgAddr)\n *\n * Packs a DbgAddrPDP11 object into an Array suitable for saving in a machine state object.\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @return {Array}\n */\n packAddr(dbgAddr)\n {\n return [dbgAddr.addr, dbgAddr.fPhysical, dbgAddr.nBase, dbgAddr.fTemporary, dbgAddr.sCmd];\n }\n\n /**\n * unpackAddr(aAddr)\n *\n * Unpacks a DbgAddrPDP11 object from an Array created by packAddr() and restored from a saved machine state.\n *\n * @this {DebuggerPDP11}\n * @param {Array} aAddr\n * @return {DbgAddrPDP11}\n */\n unpackAddr(aAddr)\n {\n var dbgAddr = this.newAddr(aAddr[0], aAddr[1], aAddr[2]);\n dbgAddr.fTemporary = aAddr[3];\n if (aAddr[4]) {\n dbgAddr.aCmds = this.parseCommand(dbgAddr.sCmd = aAddr[4]);\n }\n return dbgAddr;\n }\n\n /**\n * initBus(bus, cpu, dbg)\n *\n * @this {DebuggerPDP11}\n * @param {ComputerPDP11} cmp\n * @param {BusPDP11} bus\n * @param {CPUStatePDP11} cpu\n * @param {DebuggerPDP11} dbg\n */\n initBus(cmp, bus, cpu, dbg)\n {\n this.bus = bus;\n this.cmp = cmp;\n this.cpu = cpu;\n this.panel = cmp.panel;\n\n /*\n * Re-initialize Debugger message support if necessary\n */\n var sMessages = /** @type {string|undefined} */ (cmp.getMachineParm('messages'));\n if (sMessages) this.messageInit(sMessages);\n\n if (this.cpu.model < PDP11.MODEL_1140) {\n this.aOpReserved = this.aOpReserved.concat(DebuggerPDP11.OP1140);\n }\n if (this.cpu.model < PDP11.MODEL_1145) {\n this.aOpReserved = this.aOpReserved.concat(DebuggerPDP11.OP1145);\n }\n\n this.messageDump(MessagesPDP11.BUS, function onDumpBus(asArgs) { dbg.dumpBus(asArgs); });\n\n this.setReady();\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {DebuggerPDP11}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"debugInput\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var dbg = this;\n switch (sBinding) {\n\n case \"debugInput\":\n this.bindings[sBinding] = control;\n this.controlDebug = /** @type {HTMLInputElement} */ (control);\n /*\n * For halted machines, this is fine, but for auto-start machines, it can be annoying.\n *\n * control.focus();\n */\n control.onkeydown = function onKeyDownDebugInput(event) {\n var sCmd;\n if (event.keyCode == Keys.KEYCODE.CR) {\n sCmd = dbg.controlDebug.value;\n dbg.controlDebug.value = \"\";\n dbg.doCommands(sCmd, true);\n }\n else if (event.keyCode == Keys.KEYCODE.ESC) {\n dbg.controlDebug.value = sCmd = \"\";\n }\n else {\n if (event.keyCode == Keys.KEYCODE.UP) {\n sCmd = dbg.getPrevCommand();\n }\n else if (event.keyCode == Keys.KEYCODE.DOWN) {\n sCmd = dbg.getNextCommand();\n }\n if (sCmd != null) {\n var cch = sCmd.length;\n dbg.controlDebug.value = sCmd;\n dbg.controlDebug.setSelectionRange(cch, cch);\n }\n }\n if (sCmd != null && event.preventDefault) event.preventDefault();\n };\n return true;\n\n case \"debugEnter\":\n this.bindings[sBinding] = control;\n Web.onClickRepeat(\n control,\n 500, 100,\n function onClickDebugEnter(fRepeat) {\n if (dbg.controlDebug) {\n var sCmd = dbg.controlDebug.value;\n dbg.controlDebug.value = \"\";\n dbg.doCommands(sCmd, true);\n return true;\n }\n if (DEBUG) dbg.log(\"no debugger input buffer\");\n return false;\n }\n );\n return true;\n\n case \"step\":\n this.bindings[sBinding] = control;\n Web.onClickRepeat(\n control,\n 500, 100,\n function onClickStep(fRepeat) {\n var fCompleted = false;\n if (!dbg.isBusy(true)) {\n dbg.setBusy(true);\n fCompleted = dbg.stepCPU(fRepeat? 1 : 0, null);\n dbg.setBusy(false);\n }\n return fCompleted;\n }\n );\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * setFocus(fScroll)\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fScroll] (true if you really want the control scrolled into view)\n */\n setFocus(fScroll)\n {\n if (this.controlDebug) {\n /*\n * This is the recommended work-around to prevent the browser from scrolling the focused element\n * into view. The CPU is not a visual component, so when the CPU wants to set focus, the primary intent\n * is to ensure that keyboard input is fielded properly.\n */\n var x = 0, y = 0;\n if (!fScroll && window) {\n x = window.scrollX;\n y = window.scrollY;\n }\n\n this.controlDebug.focus();\n\n if (!fScroll && window) {\n window.scrollTo(x, y);\n }\n }\n }\n\n /**\n * mapUnibus(addr)\n *\n * @this {DebuggerPDP11}\n * @param {number} addr\n * @return {number}\n */\n mapUnibus(addr)\n {\n return this.cpu.mapUnibus(addr);\n }\n\n /**\n * getByte(dbgAddr, inc)\n *\n * We must route all our memory requests through the CPU now, in case paging is enabled.\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @param {number} [inc]\n * @return {number}\n */\n getByte(dbgAddr, inc)\n {\n var b = 0xff;\n var addr = this.getAddr(dbgAddr, false, 1);\n if (addr !== PDP11.ADDR_INVALID) {\n b = (dbgAddr.fPhysical || addr > 0xffff)? this.bus.getByteDirect(this.mapUnibus(addr)) : this.cpu.getByteSafe(addr);\n if (inc) this.incAddr(dbgAddr, inc);\n }\n return b;\n }\n\n /**\n * getWord(dbgAddr, inc)\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @param {number} [inc]\n * @return {number}\n */\n getWord(dbgAddr, inc)\n {\n var w = 0xffff;\n var addr = this.getAddr(dbgAddr, false, 2);\n if (addr !== PDP11.ADDR_INVALID) {\n w = (dbgAddr.fPhysical || addr > 0xffff)? this.bus.getWordDirect(this.mapUnibus(addr)) : this.cpu.getWordSafe(addr);\n if (inc) this.incAddr(dbgAddr, inc);\n }\n return w;\n }\n\n /**\n * setByte(dbgAddr, b, inc)\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @param {number} b\n * @param {number} [inc]\n */\n setByte(dbgAddr, b, inc)\n {\n var addr = this.getAddr(dbgAddr, true, 1);\n if (addr !== PDP11.ADDR_INVALID) {\n if (dbgAddr.fPhysical || addr > 0xffff) {\n this.bus.setByteDirect(this.mapUnibus(addr), b);\n } else {\n this.cpu.setByteSafe(addr, b);\n }\n if (inc) this.incAddr(dbgAddr, inc);\n this.cmp.updateDisplays(-1);\n }\n }\n\n /**\n * setWord(dbgAddr, w, inc)\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @param {number} w\n * @param {number} [inc]\n */\n setWord(dbgAddr, w, inc)\n {\n var addr = this.getAddr(dbgAddr, true, 2);\n if (addr !== PDP11.ADDR_INVALID) {\n if (dbgAddr.fPhysical || addr > 0xffff) {\n this.bus.setWordDirect(this.mapUnibus(addr), w);\n } else {\n this.cpu.setWordSafe(addr, w);\n }\n if (inc) this.incAddr(dbgAddr, inc);\n this.cmp.updateDisplays(-1);\n }\n }\n\n /**\n * parseAddr(sAddr, fCode, fNoChecks)\n *\n * Address evaluation and validation (eg, range checks) are no longer performed at this stage. That's\n * done later, by getAddr(), which returns PDP11.ADDR_INVALID for invalid segments, out-of-range offsets,\n * etc. The Debugger's low-level get/set memory functions verify all getAddr() results, but even if an\n * invalid address is passed through to the Bus memory interfaces, the address will simply be masked with\n * bus.nBusMask; in the case of PDP11.ADDR_INVALID, that will generally refer to the top of the physical\n * address space.\n *\n * @this {DebuggerPDP11}\n * @param {string|undefined} sAddr\n * @param {boolean} [fCode] (true if target is code, false if target is data)\n * @param {boolean} [fNoChecks] (true when setting breakpoints that may not be valid now, but will be later)\n * @return {DbgAddrPDP11|null|undefined}\n */\n parseAddr(sAddr, fCode, fNoChecks)\n {\n var dbgAddr;\n var dbgAddrNext = (fCode? this.dbgAddrNextCode : this.dbgAddrNextData);\n var addr = dbgAddrNext.addr;\n var fPhysical, nBase;\n if (sAddr !== undefined) {\n sAddr = this.parseReference(sAddr);\n var ch = sAddr.charAt(0);\n if (ch == '%') {\n fPhysical = true;\n sAddr = sAddr.substr(1);\n }\n dbgAddr = this.findSymbolAddr(sAddr);\n if (dbgAddr) return dbgAddr;\n if (sAddr.indexOf(\"0x\") >= 0) {\n nBase = 16\n } else if (sAddr.indexOf(\"0o\") >= 0) {\n nBase = 8;\n } else if (sAddr.indexOf('.') >= 0) {\n nBase = 10;\n }\n addr = this.parseExpression(sAddr);\n }\n if (addr != null) {\n dbgAddr = this.newAddr(addr, fPhysical, nBase);\n }\n return dbgAddr;\n }\n\n /**\n * parseAddrOptions(dbdAddr, sOptions)\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @param {string} [sOptions]\n */\n parseAddrOptions(dbgAddr, sOptions)\n {\n if (sOptions) {\n var a = sOptions.match(/(['\"])(.*?)\\1/);\n if (a) {\n dbgAddr.aCmds = this.parseCommand(dbgAddr.sCmd = a[2]);\n }\n }\n }\n\n /**\n * incAddr(dbgAddr, inc)\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @param {number} [inc] contains value to increment dbgAddr by (default is 1)\n */\n incAddr(dbgAddr, inc)\n {\n if (dbgAddr.addr != null) {\n dbgAddr.addr += (inc || 1);\n }\n }\n\n /**\n * toStrOffset(off)\n *\n * @this {DebuggerPDP11}\n * @param {number|null|undefined} [off]\n * @return {string} the hex representation of off\n */\n toStrOffset(off)\n {\n return this.toStrBase(off);\n }\n\n /**\n * toStrAddr(dbgAddr)\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @return {string} the hex representation of the address\n */\n toStrAddr(dbgAddr)\n {\n return (dbgAddr.fPhysical? '%' : '') + this.toStrOffset(dbgAddr.addr);\n }\n\n /**\n * getSZ(dbgAddr, cchMax)\n *\n * Gets zero-terminated (aka \"ASCIIZ\") string from dbgAddr. It also stops at the first '$', in case this is\n * a '$'-terminated string -- mainly because I'm lazy and didn't feel like writing a separate get() function.\n * Yes, a zero-terminated string containing a '$' will be prematurely terminated, and no, I don't care.\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @param {number} [cchMax] (default is 256)\n * @return {string} (and dbgAddr advanced past the terminating zero)\n */\n getSZ(dbgAddr, cchMax)\n {\n var s = \"\";\n cchMax = cchMax || 256;\n while (s.length < cchMax) {\n var b = this.getByte(dbgAddr, 1);\n if (!b || b == 0x24 || b >= 127) break;\n s += (b >= 32? String.fromCharCode(b) : '.');\n }\n return s;\n }\n\n /**\n * dumpBlocks(aBlocks, sAddr)\n *\n * @this {DebuggerPDP11}\n * @param {Array} aBlocks\n * @param {string} [sAddr] (optional block address)\n */\n dumpBlocks(aBlocks, sAddr)\n {\n var addr = 0, i = 0, n = aBlocks.length;\n\n if (sAddr) {\n addr = this.getAddr(this.parseAddr(sAddr));\n if (addr === PDP11.ADDR_INVALID) {\n this.println(\"invalid address: \" + sAddr);\n return;\n }\n i = addr >>> this.bus.nBlockShift;\n n = 1;\n }\n\n this.println(\"blockid physical blockaddr used size type\");\n this.println(\"-------- --------- --------- ------ ------ ----\");\n\n var typePrev = -1, cPrev = 0;\n while (n--) {\n var block = aBlocks[i];\n if (block.type == typePrev) {\n if (!cPrev++) this.println(\"...\");\n } else {\n typePrev = block.type;\n var sType = MemoryPDP11.TYPE_NAMES[typePrev];\n if (block) {\n this.println(Str.toHex(block.id, 8) + \" %\" + Str.toHex(i << this.bus.nBlockShift, 8) + \" %\" + Str.toHex(block.addr, 8) + \" \" + Str.toHexWord(block.used) + \" \" + Str.toHexWord(block.size) + \" \" + sType);\n }\n if (typePrev != MemoryPDP11.TYPE.NONE) typePrev = -1;\n cPrev = 0;\n }\n addr += this.bus.nBlockSize;\n i++;\n }\n }\n\n /**\n * dumpBus(asArgs)\n *\n * Dumps Bus allocations.\n *\n * @this {DebuggerPDP11}\n * @param {Array.<string>} asArgs (asArgs[0] is an optional block address)\n */\n dumpBus(asArgs)\n {\n this.dumpBlocks(this.bus.aBusBlocks, asArgs[0]);\n }\n\n /**\n * dumpHistory(sPrev, sLines)\n *\n * If sLines is not a number, it can be a instruction filter. However, for the moment, the only\n * supported filter is \"call\", which filters the history buffer for all CALL and RET instructions\n * from the specified previous point forward.\n *\n * @this {DebuggerPDP11}\n * @param {string} [sPrev] is a (decimal) number of instructions to rewind to (default is 10)\n * @param {string} [sLines] is a (decimal) number of instructions to print (default is, again, 10)\n */\n dumpHistory(sPrev, sLines)\n {\n var sMore = \"\";\n var cHistory = 0;\n var iHistory = this.iInstructionHistory;\n var aHistory = this.aInstructionHistory;\n\n if (aHistory.length) {\n var nPrev = +sPrev || this.nextHistory;\n var nLines = +sLines || 10;\n\n if (isNaN(nPrev)) {\n nPrev = nLines;\n } else {\n sMore = \"more \";\n }\n\n if (nPrev > aHistory.length) {\n this.println(\"note: only \" + aHistory.length + \" available\");\n nPrev = aHistory.length;\n }\n\n iHistory -= nPrev;\n if (iHistory < 0) {\n /*\n * If the dbgAddr of the last aHistory element contains a valid selector, wrap around.\n */\n if (aHistory[aHistory.length - 1].addr == null) {\n nPrev = iHistory + nPrev;\n iHistory = 0;\n } else {\n iHistory += aHistory.length;\n }\n }\n\n var aFilters = [];\n if (sLines == \"call\") {\n nLines = 100000;\n aFilters = [\"CALL\"];\n }\n\n if (sPrev !== undefined) {\n this.println(nPrev + \" instructions earlier:\");\n }\n\n /*\n * TODO: The following is necessary to prevent dumpHistory() from causing additional (or worse, recursive)\n * faults due to segmented addresses that are no longer valid, but the only alternative is to dramatically\n * increase the amount of memory used to store instruction history (eg, storing copies of all the instruction\n * bytes alongside the execution addresses).\n *\n * For now, we're living dangerously, so that our history dumps actually work.\n *\n * this.nSuppressBreaks++;\n *\n * If you re-enable this protection, be sure to re-enable the decrement below, too.\n */\n while (nLines > 0 && iHistory != this.iInstructionHistory) {\n\n var dbgAddr = aHistory[iHistory++];\n if (dbgAddr.addr == null) break;\n\n /*\n * We must create a new dbgAddr from the address in aHistory, because dbgAddr was\n * a reference, not a copy, and we don't want getInstruction() modifying the original.\n */\n var dbgAddrNew = this.newAddr(dbgAddr.addr);\n\n var sComment = \"history\";\n var nSequence = nPrev--;\n\n /*\n * TODO: Need to some UI to control whether cycle counts are displayed as part of the history.\n * It's currently disabled in checkInstruction(), so it's disable here, too.\n *\n if (DEBUG && dbgAddr.cycleCount != null) {\n sComment = \"cycles\";\n nSequence = dbgAddr.cycleCount;\n }\n */\n\n var sInstruction = this.getInstruction(dbgAddrNew, sComment, nSequence);\n\n if (!aFilters.length || sInstruction.indexOf(aFilters[0]) >= 0) {\n this.println(sInstruction);\n }\n\n /*\n * If there were OPERAND or ADDRESS overrides on the previous instruction, getInstruction()\n * will have automatically disassembled additional bytes, so skip additional history entries.\n */\n if (dbgAddrNew.cOverrides) {\n iHistory += dbgAddrNew.cOverrides; nLines -= dbgAddrNew.cOverrides; nPrev -= dbgAddrNew.cOverrides;\n }\n\n if (iHistory >= aHistory.length) iHistory = 0;\n this.nextHistory = nPrev;\n cHistory++;\n nLines--;\n }\n /*\n * See comments above.\n *\n * this.nSuppressBreaks--;\n */\n }\n\n if (!cHistory) {\n this.println(\"no \" + sMore + \"history available\");\n this.nextHistory = undefined;\n }\n }\n\n /**\n * messageInit(sEnable)\n *\n * @this {DebuggerPDP11}\n * @param {string|undefined} sEnable contains zero or more message categories to enable, separated by '|'\n */\n messageInit(sEnable)\n {\n this.dbg = this;\n this.bitsMessage = this.bitsWarning = MessagesPDP11.WARN;\n this.sMessagePrev = null;\n this.aMessageBuffer = [];\n /*\n * Internally, we use \"key\" instead of \"keys\", since the latter is a method on JavasScript objects,\n * but externally, we allow the user to specify \"keys\"; \"kbd\" is also allowed as shorthand for \"keyboard\".\n */\n var aEnable = this.parseCommand(sEnable.replace(\"keys\",\"key\").replace(\"kbd\",\"keyboard\"), false, '|');\n if (aEnable.length) {\n for (var m in MessagesPDP11.CATEGORIES) {\n if (Usr.indexOf(aEnable, m) >= 0) {\n this.bitsMessage |= MessagesPDP11.CATEGORIES[m];\n this.println(m + \" messages enabled\");\n }\n }\n }\n }\n\n /**\n * messageDump(bitMessage, fnDumper)\n *\n * @this {DebuggerPDP11}\n * @param {number} bitMessage is one Messages category flag\n * @param {function(Array.<string>)} fnDumper is a function the Debugger can use to dump data for that category\n * @return {boolean} true if successfully registered, false if not\n */\n messageDump(bitMessage, fnDumper)\n {\n for (var m in MessagesPDP11.CATEGORIES) {\n if (bitMessage == MessagesPDP11.CATEGORIES[m]) {\n this.afnDumpers[m] = fnDumper;\n return true;\n }\n }\n return false;\n }\n\n /**\n * getRegIndex(sReg, off)\n *\n * @this {DebuggerPDP11}\n * @param {string} sReg\n * @param {number} [off] optional offset into sReg\n * @return {number} register index, or -1 if not found\n */\n getRegIndex(sReg, off)\n {\n sReg = sReg.toUpperCase();\n var iReg = DebuggerPDP11.REGS[sReg];\n if (iReg == null) {\n iReg = -1;\n if (sReg.charAt(0) == \"R\") {\n iReg = +sReg.charAt(1);\n if (iReg < 0 || iReg > 7) iReg = -1;\n }\n }\n return iReg;\n }\n\n /**\n * getRegName(iReg)\n *\n * @this {DebuggerPDP11}\n * @param {number} iReg (0-7; not used for other registers)\n * @return {string}\n */\n getRegName(iReg)\n {\n var sReg;\n if (iReg < DebuggerPDP11.REG_AR || this.panel) sReg = DebuggerPDP11.REGNAMES[iReg];\n return sReg || \"\";\n }\n\n /**\n * getRegValue(iReg)\n *\n * Register numbers 0-7 are reserved for cpu.regsGen, 8-15 are reserved for cpu.regsAlt,\n * 16-19 for cpu.regsAltStack, 20 for regPSW, etc.\n *\n * @this {DebuggerPDP11}\n * @param {number} iReg\n * @return {number|undefined}\n */\n getRegValue(iReg)\n {\n var value;\n if (iReg >= 0) {\n if (iReg < 8) {\n value = this.cpu.regsGen[iReg];\n }\n else if (iReg < 16) {\n value = this.cpu.regsAlt[iReg-8];\n }\n else if (iReg < 20) {\n value = this.cpu.regsAltStack[iReg-16];\n }\n else {\n var cpu = this.cpu;\n var panel = this.panel;\n switch(iReg) {\n case DebuggerPDP11.REG_PS:\n value = this.cpu.getPSW();\n break;\n case DebuggerPDP11.REG_PI:\n value = cpu.getPIR();\n break;\n case DebuggerPDP11.REG_ER:\n value = cpu.regErr;\n break;\n case DebuggerPDP11.REG_SL:\n value = cpu.getSLR();\n break;\n case DebuggerPDP11.REG_M0:\n value = cpu.getMMR0();\n break;\n case DebuggerPDP11.REG_M1:\n value = cpu.getMMR1();\n break;\n case DebuggerPDP11.REG_M2:\n value = cpu.getMMR2();\n break;\n case DebuggerPDP11.REG_M3:\n value = cpu.getMMR3();\n break;\n case DebuggerPDP11.REG_AR:\n if (panel) value = panel.getAR();\n break;\n case DebuggerPDP11.REG_DR:\n if (panel) value = panel.getDR();\n break;\n case DebuggerPDP11.REG_SR:\n if (panel) value = panel.getSR();\n break;\n }\n }\n }\n return value;\n }\n\n /**\n * replaceRegs(s)\n *\n * TODO: Implement or eliminate.\n *\n * @this {DebuggerPDP11}\n * @param {string} s\n * @return {string}\n */\n replaceRegs(s)\n {\n return s;\n }\n\n /**\n * message(sMessage, fAddress)\n *\n * @this {DebuggerPDP11}\n * @param {string} sMessage is any caller-defined message string\n * @param {boolean} [fAddress] is true to display the current address\n */\n message(sMessage, fAddress)\n {\n if (fAddress) {\n sMessage += \" @\" + this.toStrAddr(this.newAddr(this.cpu.getLastPC()));\n }\n\n if (this.sMessagePrev && sMessage == this.sMessagePrev) return;\n this.sMessagePrev = sMessage;\n\n if (this.bitsMessage & MessagesPDP11.BUFFER) {\n this.aMessageBuffer.push(sMessage);\n return;\n }\n\n var fRunning;\n if ((this.bitsMessage & MessagesPDP11.HALT) && this.cpu && (fRunning = this.cpu.isRunning()) || this.isBusy(true)) {\n this.stopCPU();\n if (fRunning) sMessage += \" (cpu halted)\";\n }\n\n this.println(sMessage); // + \" (\" + this.cpu.getCycles() + \" cycles)\"\n\n /*\n * We have no idea what the frequency of println() calls might be; all we know is that they easily\n * screw up the CPU's careful assumptions about cycles per burst. So we call yieldCPU() after every\n * message, to effectively end the current burst and start fresh.\n *\n * TODO: See CPUPDP11.calcStartTime() for a discussion of why we might want to call yieldCPU() *before*\n * we display the message.\n */\n if (this.cpu) this.cpu.yieldCPU();\n }\n\n /**\n * init()\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fAutoStart]\n */\n init(fAutoStart)\n {\n this.fInit = true;\n this.println(\"Type ? for help with PDPjs Debugger commands\");\n this.updateStatus();\n if (!fAutoStart) this.setFocus();\n if (this.sInitCommands) {\n var sCmds = this.sInitCommands;\n this.sInitCommands = null;\n this.doCommands(sCmds);\n }\n }\n\n /**\n * historyInit(fQuiet)\n *\n * This function is intended to be called by the constructor, reset(), addBreakpoint(), findBreakpoint()\n * and any other function that changes the checksEnabled() criteria used to decide whether checkInstruction()\n * should be called.\n *\n * That is, if the history arrays need to be allocated and haven't already been allocated, then allocate them,\n * and if the arrays are no longer needed, then deallocate them.\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fQuiet]\n */\n historyInit(fQuiet)\n {\n var i;\n if (!this.checksEnabled()) {\n if (this.aInstructionHistory && this.aInstructionHistory.length && !fQuiet) {\n this.println(\"instruction history buffer freed\");\n }\n this.iInstructionHistory = 0;\n this.aInstructionHistory = [];\n return;\n }\n if (!this.aInstructionHistory || !this.aInstructionHistory.length) {\n this.aInstructionHistory = new Array(DebuggerPDP11.HISTORY_LIMIT);\n for (i = 0; i < this.aInstructionHistory.length; i++) {\n /*\n * Preallocate dummy Addr (Array) objects in every history slot, so that\n * checkInstruction() doesn't need to call newAddr() on every slot update.\n */\n this.aInstructionHistory[i] = this.newAddr();\n }\n this.iInstructionHistory = 0;\n if (!fQuiet) {\n this.println(\"instruction history buffer allocated\");\n }\n }\n }\n\n /**\n * startCPU(fUpdateFocus, fQuiet)\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fUpdateFocus] is true to update focus\n * @param {boolean} [fQuiet]\n * @return {boolean} true if run request successful, false if not\n */\n startCPU(fUpdateFocus, fQuiet)\n {\n if (!this.checkCPU(fQuiet)) return false;\n this.cpu.startCPU(fUpdateFocus);\n return true;\n }\n\n /**\n * stepCPU(nCycles, fRegs, fUpdateDisplays)\n *\n * @this {DebuggerPDP11}\n * @param {number} nCycles (0 for one instruction without checking breakpoints)\n * @param {boolean|null} [fRegs] is true to display registers after step (default is false; use null for previous setting)\n * @param {boolean} [fUpdateDisplays] is false to disable Computer display updates (default is true)\n * @return {boolean}\n */\n stepCPU(nCycles, fRegs, fUpdateDisplays)\n {\n if (!this.checkCPU()) return false;\n\n var sCmd = \"\";\n if (fRegs === null) {\n fRegs = (!this.sCmdTracePrev || this.sCmdTracePrev == \"tr\");\n sCmd = fRegs? \"tr\" : \"t\";\n }\n\n this.nCycles = 0;\n\n if (!nCycles) {\n /*\n * When single-stepping, the CPU won't call checkInstruction(), which is good for\n * avoiding breakpoints, but bad for instruction data collection if checks are enabled.\n * So we call checkInstruction() ourselves.\n */\n if (this.checksEnabled()) this.checkInstruction(this.cpu.getPC(), 0);\n }\n /*\n * For our typically tiny bursts (usually single instructions), mimic what runCPU() does.\n */\n try {\n nCycles = this.cpu.getBurstCycles(nCycles);\n var nCyclesStep = this.cpu.stepCPU(nCycles);\n if (nCyclesStep > 0) {\n this.cpu.updateTimers(nCyclesStep);\n this.nCycles += nCyclesStep;\n this.cpu.addCycles(nCyclesStep, true);\n this.cpu.updateChecksum(nCyclesStep);\n this.cInstructions++;\n }\n }\n catch(exception) {\n /*\n * We assume that any numeric exception was explicitly thrown by the CPU to interrupt the\n * current instruction. For all other exceptions, we attempt a stack dump.\n */\n if (typeof exception != \"number\") {\n var e = exception;\n this.nCycles = 0;\n this.cpu.setError(e.stack || e.message);\n }\n }\n\n /*\n * Because we called cpu.stepCPU() and not cpu.startCPU(), we must nudge the Computer's update code,\n * and then update our own state. Normally, the only time fUpdateDisplays will be false is when doTrace()\n * is calling us in a loop, in which case it will perform its own updateDisplays() when it's done.\n */\n if (fUpdateDisplays !== false) {\n if (this.panel) this.panel.stop();\n this.cmp.updateDisplays(-1);\n }\n\n this.updateStatus(fRegs || false, sCmd);\n return (this.nCycles > 0);\n }\n\n /**\n * stopCPU()\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fComplete]\n */\n stopCPU(fComplete)\n {\n if (this.cpu) this.cpu.stopCPU(fComplete);\n }\n\n /**\n * updateStatus(fRegs, sCmd)\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fRegs] (default is true)\n * @param {string} [sCmd]\n */\n updateStatus(fRegs, sCmd)\n {\n if (!this.fInit) return;\n\n if (fRegs === undefined) fRegs = true;\n\n if (sCmd) {\n this.println(DebuggerPDP11.PROMPT + sCmd);\n }\n\n var trapStatus = this.cpu.getTrapStatus();\n if (trapStatus) {\n var reason = trapStatus >> 8;\n var sReason = reason < 0? PDP11.REASONS[-reason] : this.toStrBase(reason);\n this.println(\"trapped to \" + this.toStrBase(trapStatus & 0xff, 8) + \" (\" + sReason + \")\");\n }\n\n this.dbgAddrNextCode = this.newAddr(this.cpu.getPC());\n /*\n * this.nStep used to be a simple boolean, but now it's 0 (or undefined)\n * if inactive, 1 if stepping over an instruction without a register dump, or 2\n * if stepping over an instruction with a register dump.\n */\n if (!fRegs || this.nStep == 1) {\n this.doUnassemble();\n } else {\n this.doRegisters();\n }\n }\n\n /**\n * checkCPU(fQuiet)\n *\n * Make sure the CPU is ready (finished initializing), powered, not already running, and not in an error state.\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fQuiet]\n * @return {boolean}\n */\n checkCPU(fQuiet)\n {\n if (!this.cpu || !this.cpu.isReady() || !this.cpu.isPowered() || this.cpu.isRunning()) {\n if (!fQuiet) this.println(\"cpu busy or unavailable, command ignored\");\n return false;\n }\n return !this.cpu.isError();\n }\n\n /**\n * powerUp(data, fRepower)\n *\n * @this {DebuggerPDP11}\n * @param {Object|null} data\n * @param {boolean} [fRepower]\n * @return {boolean} true if successful, false if failure\n */\n powerUp(data, fRepower)\n {\n if (!fRepower) {\n /*\n * Because Debugger save/restore support is somewhat limited (and didn't always exist),\n * we deviate from the typical save/restore design pattern: instead of reset OR restore,\n * we always reset and then perform a (potentially limited) restore.\n */\n this.reset(true);\n\n // this.println(data? \"resuming\" : \"powering up\");\n\n if (data) {\n return this.restore(data);\n }\n }\n return true;\n }\n\n /**\n * powerDown(fSave, fShutdown)\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fSave]\n * @param {boolean} [fShutdown]\n * @return {Object|boolean}\n */\n powerDown(fSave, fShutdown)\n {\n if (fShutdown) this.println(fSave? \"suspending\" : \"shutting down\");\n return fSave? this.save() : true;\n }\n\n /**\n * reset(fQuiet)\n *\n * This is a notification handler, called by the Computer, to inform us of a reset.\n *\n * @this {DebuggerPDP11}\n * @param {boolean} fQuiet (true only when called from our own powerUp handler)\n */\n reset(fQuiet)\n {\n this.historyInit();\n this.cInstructions = this.cInstructionsStart = 0;\n this.sMessagePrev = null;\n this.nCycles = 0;\n this.dbgAddrNextCode = this.newAddr(this.cpu.getPC());\n /*\n * fRunning is set by start() and cleared by stop(). In addition, we clear\n * it here, so that if the CPU is reset while running, we can prevent stop()\n * from unnecessarily dumping the CPU state.\n */\n this.flags.running = false;\n this.clearTempBreakpoint();\n if (!fQuiet) this.updateStatus();\n }\n\n /**\n * save()\n *\n * This implements (very rudimentary) save support for the Debugger component.\n *\n * @this {DebuggerPDP11}\n * @return {Object}\n */\n save()\n {\n var state = new State(this);\n state.set(0, this.packAddr(this.dbgAddrNextCode));\n state.set(1, this.packAddr(this.dbgAddrAssemble));\n state.set(2, [this.aPrevCmds, this.fAssemble, this.bitsMessage]);\n state.set(3, this.aSymbolTable);\n return state.data();\n }\n\n /**\n * restore(data)\n *\n * This implements (very rudimentary) restore support for the Debugger component.\n *\n * @this {DebuggerPDP11}\n * @param {Object} data\n * @return {boolean} true if successful, false if failure\n */\n restore(data)\n {\n var i = 0;\n if (data[2] !== undefined) {\n this.dbgAddrNextCode = this.unpackAddr(data[i++]);\n this.dbgAddrAssemble = this.unpackAddr(data[i++]);\n this.aPrevCmds = data[i][0];\n if (typeof this.aPrevCmds == \"string\") this.aPrevCmds = [this.aPrevCmds];\n this.fAssemble = data[i][1];\n this.bitsMessage |= data[i][2]; // keep our current message bits set, and simply \"add\" any extra bits defined by the saved state\n }\n if (data[3]) this.aSymbolTable = data[3];\n return true;\n }\n\n /**\n * start(ms, nCycles)\n *\n * This is a notification handler, called by the Computer, to inform us the CPU has started.\n *\n * @this {DebuggerPDP11}\n * @param {number} ms\n * @param {number} nCycles\n */\n start(ms, nCycles)\n {\n if (!this.nStep) this.println(\"running\");\n this.flags.running = true;\n this.msStart = ms;\n this.nCyclesStart = nCycles;\n }\n\n /**\n * stop(ms, nCycles)\n *\n * This is a notification handler, called by the Computer, to inform us the CPU has now stopped.\n *\n * @this {DebuggerPDP11}\n * @param {number} ms\n * @param {number} nCycles\n */\n stop(ms, nCycles)\n {\n if (this.flags.running) {\n this.flags.running = false;\n this.nCycles = nCycles - this.nCyclesStart;\n if (!this.nStep) {\n var sStopped = \"stopped\";\n if (this.nCycles) {\n var msTotal = ms - this.msStart;\n var nCyclesPerSecond = (msTotal > 0? Math.round(this.nCycles * 1000 / msTotal) : 0);\n sStopped += \" (\";\n if (this.checksEnabled()) {\n sStopped += this.cInstructions + \" instructions, \";\n /*\n * $ops displays progress by calculating cInstructions - cInstructionsStart, so before\n * zeroing cInstructions, we should subtract cInstructions from cInstructionsStart (since\n * we're effectively subtracting cInstructions from cInstructions as well).\n */\n this.cInstructionsStart -= this.cInstructions;\n this.cInstructions = 0;\n }\n sStopped += this.nCycles + \" cycles, \" + msTotal + \" ms, \" + nCyclesPerSecond + \" hz)\";\n } else {\n if (this.messageEnabled(MessagesPDP11.HALT)) {\n /*\n * It's possible the user is trying to 'g' past a fault that was blocked by helpCheckFault()\n * for the Debugger's benefit; if so, it will continue to be blocked, so try displaying a helpful\n * message (another helpful tip would be to simply turn off the \"halt\" message category).\n */\n sStopped += \" (use the 't' command to execute blocked faults)\";\n }\n }\n this.println(sStopped);\n }\n this.updateStatus(true);\n this.setFocus();\n this.clearTempBreakpoint(this.cpu.getPC());\n this.sMessagePrev = null;\n }\n }\n\n /**\n * checksEnabled(fRelease)\n *\n * This \"check\" function is called by the CPU; we indicate whether or not every instruction needs to be checked.\n *\n * Originally, this returned true even when there were only read and/or write breakpoints, but those breakpoints\n * no longer require the intervention of checkInstruction(); the Bus component automatically swaps in/out appropriate\n * \"checked\" Memory access functions to deal with those breakpoints in the corresponding Memory blocks. So I've\n * simplified the test below.\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fRelease] is true for release criteria only; default is false (any criteria)\n * @return {boolean} true if every instruction needs to pass through checkInstruction(), false if not\n */\n checksEnabled(fRelease)\n {\n return ((DEBUG && !fRelease)? true : (this.aBreakExec.length > 1 || !!this.nBreakInstructions));\n }\n\n /**\n * checkInstruction(addr, nState)\n *\n * This \"check\" function is called by the CPU to inform us about the next instruction to be executed,\n * giving us an opportunity to look for \"exec\" breakpoints and update opcode instruction history.\n *\n * @this {DebuggerPDP11}\n * @param {number} addr\n * @param {number} nState is < 0 if stepping, 0 if starting, or > 0 if running\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkInstruction(addr, nState)\n {\n var opCode = -1;\n var cpu = this.cpu;\n\n /*\n * If opHalt() calls our stopInstruction() function, it will effectively rewind the PC back to the HALT,\n * purely for our debugging benefit, so we must compensate for that here by advancing the PC past the HALT\n * when the machine starts up again.\n */\n if (!nState) {\n opCode = this.cpu.getWordSafe(addr);\n /*\n * We have to be careful about this HALT-skipping code, because as fate would have it, I inadvertently\n * stopped the following diagnostic with a breakpoint *on* a HALT instruction:\n *\n * .R EKBEE1\n * EKBEE1.BIC\n *\n * CEKBEE0 11/70 MEM MGMT\n *\n * CPU UNDER TEST FOUND TO BE A KB11-CM\n * bp 033330 hit\n * stopped (28339757 instructions, 123994176 cycles, 19177 ms, 6465775 hz)\n * R0=140000 R1=033330 R2=100143 R3=133260 R4=000000 R5=177700\n * SP=000600 PC=033330 PS=140000 IR=000000 SL=000377 T0 N0 Z0 V0 C0\n * 033330: 000000 HALT\n *\n * Since we haven't executed the HALT yet, it would be wrong (and would cause a diagnostic failure) to\n * skip over it. In this particular case, the PDR for the address of the HALT instruction was invalid,\n * so the HALT gets fetched but not executed.\n *\n * My first thought was that maybe we need to probe the address more thoroughly (getWordSafe() does\n * not), but it should be sufficient to simply confirm that the PC of the last opcode executed matches\n * the addr of this HALT.\n *\n * Yes, I could save myself this grief by eliminating these PC hacks, both here and in stopInstruction(),\n * but I still think it's a useful debugging aid.\n */\n if (opCode == PDP11.OPCODE.HALT && this.cpu.getLastPC() == addr) {\n addr = this.cpu.advancePC(2);\n }\n }\n\n /*\n * If the CPU stopped on a breakpoint, we're not interested in stopping again if the machine is starting.\n */\n if (nState > 0) {\n if (this.nBreakInstructions) {\n if (!--this.nBreakInstructions) return true;\n }\n if (this.checkBreakpoint(addr, 1, this.aBreakExec)) {\n return true;\n }\n }\n\n /*\n * The rest of the instruction tracking logic can only be performed if historyInit() has allocated the\n * necessary data structures. Note that there is no explicit UI for enabling/disabling history, other than\n * adding/removing breakpoints, simply because it's breakpoints that trigger the call to checkInstruction();\n * well, OK, and a few other things now, like enabling MessagesPDP11.INT messages.\n */\n if (nState >= 0 && this.aInstructionHistory.length) {\n this.cInstructions++;\n if (opCode < 0) {\n opCode = this.cpu.getWordSafe(addr);\n }\n if ((opCode & 0xffff) != PDP11.OPCODE.INVALID) {\n var dbgAddr = this.aInstructionHistory[this.iInstructionHistory];\n this.setAddr(dbgAddr, addr);\n // if (DEBUG) dbgAddr.cycleCount = cpu.getCycles();\n if (++this.iInstructionHistory == this.aInstructionHistory.length) this.iInstructionHistory = 0;\n }\n }\n return false;\n }\n\n /**\n * stopInstruction(sMessage)\n *\n * TODO: Currently, the only way to prevent this call from stopping the CPU is when you're single-stepping.\n *\n * @this {DebuggerPDP11}\n * @param {string} [sMessage]\n * @return {boolean} true if stopping is enabled, false if not\n */\n stopInstruction(sMessage)\n {\n var cpu = this.cpu;\n if (cpu.isRunning()) {\n cpu.setPC(this.cpu.getLastPC());\n if (sMessage) this.println(sMessage);\n this.stopCPU();\n /*\n * TODO: Review the appropriate-ness of throwing a bogus vector number in order to immediately stop\n * the instruction. It's handy, but it also means that we no longer actually return true, so callers\n * of either stopInstruction() or undefinedInstruction() may have unreachable code paths.\n */\n throw -1;\n }\n return false;\n }\n\n /**\n * undefinedInstruction(opCode)\n *\n * @this {DebuggerPDP11}\n * @param {number} opCode\n * @return {boolean} true if stopping is enabled, false if not\n */\n undefinedInstruction(opCode)\n {\n if (this.messageEnabled(MessagesPDP11.CPU)) {\n this.printMessage(\"undefined opcode \" + this.toStrBase(opCode), true, true);\n return this.stopInstruction(); // allow the caller to step over it if they really want a trap generated\n }\n return false;\n }\n\n /**\n * checkMemoryRead(addr, nb)\n *\n * This \"check\" function is called by a Memory block to inform us that a memory read occurred, giving us an\n * opportunity to track the read if we want, and look for a matching \"read\" breakpoint, if any.\n *\n * In the \"old days\", it would be an error for this call to fail to find a matching Debugger breakpoint, but now\n * Memory blocks have no idea whether the Debugger or the machine's Debug register(s) triggered this \"checked\" read.\n *\n * If we return true, we \"trump\" the machine's Debug register(s); false allows normal Debug register processing.\n *\n * @this {DebuggerPDP11}\n * @param {number} addr\n * @param {number} [nb] (# of bytes; default is 1)\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkMemoryRead(addr, nb)\n {\n if (this.checkBreakpoint(addr, nb || 1, this.aBreakRead)) {\n this.stopCPU(false);\n return true;\n }\n return false;\n }\n\n /**\n * checkMemoryWrite(addr, nb)\n *\n * This \"check\" function is called by a Memory block to inform us that a memory write occurred, giving us an\n * opportunity to track the write if we want, and look for a matching \"write\" breakpoint, if any.\n *\n * In the \"old days\", it would be an error for this call to fail to find a matching Debugger breakpoint, but now\n * Memory blocks have no idea whether the Debugger or the machine's Debug register(s) triggered this \"checked\" write.\n *\n * If we return true, we \"trump\" the machine's Debug register(s); false allows normal Debug register processing.\n *\n * @this {DebuggerPDP11}\n * @param {number} addr\n * @param {number} [nb] (# of bytes; default is 1)\n * @return {boolean} true if breakpoint hit, false if not\n */\n checkMemoryWrite(addr, nb)\n {\n if (this.checkBreakpoint(addr, nb || 1, this.aBreakWrite)) {\n this.stopCPU(false);\n return true;\n }\n return false;\n }\n\n /**\n * clearBreakpoints()\n *\n * @this {DebuggerPDP11}\n */\n clearBreakpoints()\n {\n var i, dbgAddr, addr;\n this.aBreakExec = [\"bp\"];\n if (this.aBreakRead !== undefined) {\n for (i = 1; i < this.aBreakRead.length; i++) {\n dbgAddr = this.aBreakRead[i];\n addr = this.getAddr(dbgAddr);\n if (!dbgAddr.fPhysical) {\n this.cpu.removeMemBreak(addr, false);\n } else {\n this.bus.removeMemBreak(addr, false);\n }\n }\n }\n this.aBreakRead = [\"br\"];\n if (this.aBreakWrite !== undefined) {\n for (i = 1; i < this.aBreakWrite.length; i++) {\n dbgAddr = this.aBreakWrite[i];\n addr = this.getAddr(dbgAddr);\n if (!dbgAddr.fPhysical) {\n this.cpu.removeMemBreak(addr, true);\n } else {\n this.bus.removeMemBreak(addr, true);\n }\n }\n }\n this.aBreakWrite = [\"bw\"];\n /*\n * nSuppressBreaks ensures we can't get into an infinite loop where a breakpoint lookup\n * requires reading memory that triggers more memory reads, which triggers more breakpoint checks.\n */\n this.nSuppressBreaks = 0;\n this.nBreakInstructions = 0;\n }\n\n /**\n * addBreakpoint(aBreak, dbgAddr, fTemporary)\n *\n * In case you haven't already figured this out, all our breakpoint commands use the address\n * to identify a breakpoint, not an incrementally assigned breakpoint index like other debuggers;\n * see doBreak() for details.\n *\n * This has a few implications, one being that you CANNOT set more than one kind of breakpoint\n * on a single address. In practice, that's rarely a problem, because you can almost always set\n * a different breakpoint on a neighboring address.\n *\n * Also, there is one exception to the \"one address, one breakpoint\" rule, and that involves\n * temporary breakpoints (ie, one-time execution breakpoints that either a \"p\" or \"g\" command\n * may create to step over a chunk of code). Those breakpoints automatically clear themselves,\n * so there usually isn't any need to refer to them using breakpoint commands.\n *\n * TODO: Consider supporting the more \"traditional\" breakpoint index syntax; the current\n * address-based syntax was implemented solely for expediency and consistency. At the same time,\n * also consider a more WDEB386-like syntax, where \"br\" is used to set a variety of access-specific\n * breakpoints, using modifiers like \"r1\", \"r2\", \"w1\", \"w2, etc.\n *\n * @this {DebuggerPDP11}\n * @param {Array} aBreak\n * @param {DbgAddrPDP11} dbgAddr\n * @param {boolean} [fTemporary]\n * @return {boolean} true if breakpoint added, false if already exists\n */\n addBreakpoint(aBreak, dbgAddr, fTemporary)\n {\n var fSuccess = true;\n\n // this.nSuppressBreaks++;\n\n /*\n * Instead of complaining that a breakpoint already exists (as we used to do), we now\n * allow breakpoints to be re-set; this makes it easier to update any commands that may\n * be associated with the breakpoint.\n *\n * The only exception: we DO allow a temporary breakpoint at an address where there may\n * already be a breakpoint, so that you can easily step (\"p\" or \"g\") over such addresses.\n */\n if (!fTemporary) {\n this.findBreakpoint(aBreak, dbgAddr, true, false, true);\n }\n\n if (aBreak != this.aBreakExec) {\n var addr = this.getAddr(dbgAddr);\n if (addr === PDP11.ADDR_INVALID) {\n this.println(\"invalid address: \" + this.toStrAddr(dbgAddr));\n fSuccess = false;\n } else {\n var fWrite = (aBreak == this.aBreakWrite);\n /*\n * We automatically promote any read/write breakpoint address to fPhysical if it's\n * outside the 16-bit virtual address range.\n */\n if (addr > 0xffff) dbgAddr.fPhysical = true;\n if (!dbgAddr.fPhysical) {\n this.cpu.addMemBreak(addr, fWrite);\n } else {\n this.bus.addMemBreak(addr, fWrite);\n }\n }\n }\n\n if (fSuccess) {\n aBreak.push(dbgAddr);\n if (fTemporary) {\n dbgAddr.fTemporary = true;\n }\n else {\n this.printBreakpoint(aBreak, aBreak.length-1, \"set\");\n this.historyInit();\n }\n }\n\n // this.nSuppressBreaks--;\n\n return fSuccess;\n }\n\n /**\n * findBreakpoint(aBreak, dbgAddr, fRemove, fTemporary, fQuiet)\n *\n * @this {DebuggerPDP11}\n * @param {Array} aBreak\n * @param {DbgAddrPDP11} dbgAddr\n * @param {boolean} [fRemove]\n * @param {boolean} [fTemporary]\n * @param {boolean} [fQuiet]\n * @return {boolean} true if found, false if not\n */\n findBreakpoint(aBreak, dbgAddr, fRemove, fTemporary, fQuiet)\n {\n var fFound = false;\n var addr = this.getAddr(dbgAddr);\n for (var i = 1; i < aBreak.length; i++) {\n var dbgAddrBreak = aBreak[i];\n if (addr == this.getAddr(dbgAddrBreak)) {\n if (!fTemporary || dbgAddrBreak.fTemporary) {\n fFound = true;\n if (fRemove) {\n if (!dbgAddrBreak.fTemporary && !fQuiet) {\n this.printBreakpoint(aBreak, i, \"cleared\");\n }\n aBreak.splice(i, 1);\n if (aBreak != this.aBreakExec) {\n var fWrite = (aBreak == this.aBreakWrite);\n if (!dbgAddrBreak.fPhysical) {\n this.cpu.removeMemBreak(addr, fWrite);\n } else {\n this.bus.removeMemBreak(addr, fWrite);\n }\n }\n /*\n * We'll mirror the logic in addBreakpoint() and leave the history buffer alone if this\n * was a temporary breakpoint.\n */\n if (!dbgAddrBreak.fTemporary) {\n this.historyInit();\n }\n break;\n }\n if (!fQuiet) this.printBreakpoint(aBreak, i, \"exists\");\n break;\n }\n }\n }\n return fFound;\n }\n\n /**\n * listBreakpoints(aBreak)\n *\n * @this {DebuggerPDP11}\n * @param {Array} aBreak\n * @return {number} of breakpoints listed, 0 if none\n */\n listBreakpoints(aBreak)\n {\n for (var i = 1; i < aBreak.length; i++) {\n this.printBreakpoint(aBreak, i);\n }\n return aBreak.length - 1;\n }\n\n /**\n * printBreakpoint(aBreak, i, sAction)\n *\n * @this {DebuggerPDP11}\n * @param {Array} aBreak\n * @param {number} i\n * @param {string} [sAction]\n */\n printBreakpoint(aBreak, i, sAction)\n {\n var dbgAddr = aBreak[i];\n this.println(aBreak[0] + ' ' + this.toStrAddr(dbgAddr) + (sAction? (' ' + sAction) : (dbgAddr.sCmd? (' \"' + dbgAddr.sCmd + '\"') : '')));\n }\n\n /**\n * setTempBreakpoint(dbgAddr)\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr of new temp breakpoint\n */\n setTempBreakpoint(dbgAddr)\n {\n this.addBreakpoint(this.aBreakExec, dbgAddr, true);\n }\n\n /**\n * clearTempBreakpoint(addr)\n *\n * @this {DebuggerPDP11}\n * @param {number|undefined} [addr] clear all temp breakpoints if no address specified\n */\n clearTempBreakpoint(addr)\n {\n if (addr !== undefined) {\n this.checkBreakpoint(addr, 1, this.aBreakExec, true);\n this.nStep = 0;\n } else {\n for (var i = 1; i < this.aBreakExec.length; i++) {\n var dbgAddrBreak = this.aBreakExec[i];\n if (dbgAddrBreak.fTemporary) {\n if (!this.findBreakpoint(this.aBreakExec, dbgAddrBreak, true, true)) break;\n i = 0;\n }\n }\n }\n }\n\n /**\n * checkBreakpoint(addr, nb, aBreak, fTemporary)\n *\n * @this {DebuggerPDP11}\n * @param {number} addr\n * @param {number} nb (# of bytes)\n * @param {Array} aBreak\n * @param {boolean} [fTemporary]\n * @return {boolean} true if breakpoint has been hit, false if not\n */\n checkBreakpoint(addr, nb, aBreak, fTemporary)\n {\n /*\n * Time to check for breakpoints; note that this should be done BEFORE updating history data\n * (see checkInstruction), since we might not actually execute the current instruction.\n */\n var fBreak = false;\n\n if (!this.nSuppressBreaks++) {\n\n for (var i = 1; !fBreak && i < aBreak.length; i++) {\n\n var dbgAddrBreak = aBreak[i];\n\n if (fTemporary && !dbgAddrBreak.fTemporary) continue;\n\n /*\n * If we're checking an execution address, which is always virtual, and virtual\n * addresses are always restricted to 16 bits, let's mask the breakpoint address to match\n * (the user should know better, but we'll be nice).\n */\n var addrBreak = this.getAddr(dbgAddrBreak) & (aBreak == this.aBreakExec? 0xffff : -1);\n for (var n = 0; n < nb; n++) {\n\n if ((addr + n) != addrBreak) continue;\n\n var a;\n fBreak = true;\n if (dbgAddrBreak.fTemporary) {\n this.findBreakpoint(aBreak, dbgAddrBreak, true, true);\n fTemporary = true;\n }\n if (a = dbgAddrBreak.aCmds) {\n /*\n * When one or more commands are attached to a breakpoint, we don't halt by default.\n * Instead, we set fBreak to true only if, at the completion of all the commands, the\n * CPU is halted; in other words, you should include \"h\" as one of the breakpoint commands\n * if you want the breakpoint to stop execution.\n *\n * Another useful command is \"if\", which will return false if the expression is false,\n * at which point we'll jump ahead to the next \"else\" command, and if there isn't an \"else\",\n * we abort.\n */\n fBreak = false;\n for (var j = 0; j < a.length; j++) {\n if (!this.doCommand(a[j], true)) {\n if (a[j].indexOf(\"if\")) {\n fBreak = true; // the failed command wasn't \"if\", so abort\n break;\n }\n var k = j + 1;\n for (; k < a.length; k++) {\n if (!a[k].indexOf(\"else\")) break;\n j++;\n }\n if (k == a.length) { // couldn't find an \"else\" after the \"if\", so abort\n fBreak = true;\n break;\n }\n /*\n * If we're still here, we'll execute the \"else\" command (which is just a no-op),\n * followed by any remaining commands.\n */\n }\n }\n if (!this.cpu.isRunning()) fBreak = true;\n }\n if (fBreak) {\n if (!fTemporary) this.printBreakpoint(aBreak, i, \"hit\");\n break;\n }\n }\n }\n }\n\n this.nSuppressBreaks--;\n\n return fBreak;\n }\n\n /**\n * getInstruction(dbgAddr, sComment, nSequence)\n *\n * Get the next instruction, by decoding the opcode and any operands.\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @param {string} [sComment] is an associated comment\n * @param {number|null} [nSequence] is an associated sequence number, undefined if none\n * @return {string} (and dbgAddr is updated to the next instruction)\n */\n getInstruction(dbgAddr, sComment, nSequence)\n {\n var opNames = DebuggerPDP11.OPNAMES;\n var dbgAddrOp = this.newAddr(dbgAddr.addr);\n var opCode = this.getWord(dbgAddr, 2);\n\n var opDesc;\n for (var mask in this.opTable) {\n var opMasks = this.opTable[mask];\n opDesc = opMasks[opCode & mask];\n if (opDesc) break;\n }\n\n if (!opDesc) {\n opDesc = DebuggerPDP11.OPNONE;\n }\n\n var opNum = opDesc[0];\n if (this.aOpReserved.indexOf(opNum) >= 0) {\n opDesc = DebuggerPDP11.OPNONE;\n opNum = opDesc[0];\n }\n\n var sOperands = \"\", sTarget = \"\";\n var sOpName = opNames[opNum];\n var cOperands = opDesc.length - 1;\n\n if (!opNum && !cOperands) {\n sOperands = this.toStrBase(opCode);\n }\n\n for (var iOperand = 1; iOperand <= cOperands; iOperand++) {\n\n var opType = opDesc[iOperand];\n if (opType === undefined) continue;\n\n var sOperand = this.getOperand(opCode, opType, dbgAddr);\n\n if (!sOperand || !sOperand.length) {\n sOperands = \"INVALID\";\n break;\n }\n\n /*\n * If getOperand() returns an Array rather than a string, then the first element is the original\n * operand, and the second element contains additional information (eg, the target) of the operand.\n */\n if (typeof sOperand != \"string\") {\n sTarget = sOperand[1];\n sOperand = sOperand[0];\n }\n\n if (sOperands.length > 0) sOperands += ',';\n sOperands += (sOperand || \"???\");\n }\n\n var sOpCodes = \"\";\n var sLine = this.toStrAddr(dbgAddrOp) + \":\";\n if (dbgAddrOp.addr !== PDP11.ADDR_INVALID && dbgAddr.addr !== PDP11.ADDR_INVALID) {\n do {\n sOpCodes += ' ' + this.toStrBase(this.getWord(dbgAddrOp, 2));\n if (dbgAddrOp.addr == null) break;\n } while (dbgAddrOp.addr != dbgAddr.addr);\n }\n\n sLine += Str.pad(sOpCodes, 24);\n sLine += Str.pad(sOpName, 5);\n if (sOperands) sLine += ' ' + sOperands;\n\n if (sComment || sTarget) {\n sLine = Str.pad(sLine, 60) + ';' + (sComment || \"\");\n if (!this.cpu.flags.checksum) {\n sLine += (nSequence != null? '=' + nSequence.toString() : \"\");\n } else {\n var nCycles = this.cpu.getCycles();\n sLine += \"cycles=\" + nCycles.toString() + \" cs=\" + Str.toHex(this.cpu.nChecksum);\n }\n if (sTarget) {\n if (sLine.slice(-1) != ';') sLine += ' ';\n sLine += sTarget;\n }\n }\n return sLine;\n }\n\n /**\n * getOperand(opCode, opType, dbgAddr)\n *\n * If getOperand() returns an Array rather than a string, then the first element is the original\n * operand, and the second element is a comment containing additional information (eg, the target)\n * of the operand.\n *\n * @this {DebuggerPDP11}\n * @param {number} opCode\n * @param {number} opType\n * @param {DbgAddrPDP11} dbgAddr\n * @return {string|Array.<string>}\n */\n getOperand(opCode, opType, dbgAddr)\n {\n var sOperand = \"\", disp, addr;\n /*\n * Take care of OP_OTHER opcodes first; then all we'll have to worry about\n * next are OP_SRC or OP_DST opcodes.\n */\n var opTypeOther = opType & DebuggerPDP11.OP_OTHER;\n if (opTypeOther == DebuggerPDP11.OP_BRANCH) {\n disp = ((opCode & 0xff) << 24) >> 23;\n addr = (dbgAddr.addr + disp) & 0xffff;\n sOperand = this.toStrBase(addr);\n }\n else if (opTypeOther == DebuggerPDP11.OP_DSTOFF) {\n disp = (opCode & 0x3f) << 1;\n addr = (dbgAddr.addr - disp) & 0xffff;\n sOperand = this.toStrBase(addr);\n }\n else if (opTypeOther == DebuggerPDP11.OP_DSTNUM3) {\n disp = (opCode & 0x07);\n sOperand = this.toStrBase(disp, 3);\n }\n else if (opTypeOther == DebuggerPDP11.OP_DSTNUM6) {\n disp = (opCode & 0x3f);\n sOperand = this.toStrBase(disp, 6);\n }\n else if (opTypeOther == DebuggerPDP11.OP_DSTNUM8) {\n disp = (opCode & 0xff);\n sOperand = this.toStrBase(disp, 8);\n }\n else {\n /*\n * Isolate all OP_SRC or OP_DST bits from opcode in the opMode variable.\n */\n var opMode = opCode & opType;\n\n /*\n * Convert OP_SRC bits into OP_DST bits, since they use the same format.\n */\n if (opType & DebuggerPDP11.OP_SRC) {\n opMode >>= 6;\n opType >>= 6;\n }\n if (opType & DebuggerPDP11.OP_DST) {\n var wIndex;\n var sTarget = null;\n var reg = opMode & DebuggerPDP11.OP_DSTREG;\n /*\n * Note that opcodes that specify only REG bits in the opType mask (ie, no MOD bits)\n * will automatically default to OPMODE_REG below.\n */\n switch((opMode & DebuggerPDP11.OP_DSTMODE)) {\n\n case PDP11.OPMODE.REG: // 0x0: REGISTER\n sOperand = this.getRegName(reg);\n break;\n\n case PDP11.OPMODE.REGD: // 0x1: REGISTER DEFERRED\n sOperand = '@' + this.getRegName(reg);\n sTarget = this.getTarget(this.cpu.regsGen[reg]);\n break;\n\n case PDP11.OPMODE.POSTINC: // 0x2: POST-INCREMENT\n if (reg < 7) {\n sOperand = '(' + this.getRegName(reg) + \")+\";\n } else {\n /*\n * When using R7 (aka PC), POST-INCREMENT is known as IMMEDIATE\n */\n wIndex = this.getWord(dbgAddr, 2);\n sOperand = '#' + this.toStrBase(wIndex, -1);\n }\n break;\n\n case PDP11.OPMODE.POSTINCD: // 0x3: POST-INCREMENT DEFERRED\n if (reg < 7) {\n sOperand = \"@(\" + this.getRegName(reg) + \")+\";\n } else {\n /*\n * When using R7 (aka PC), POST-INCREMENT DEFERRED is known as ABSOLUTE\n */\n wIndex = this.getWord(dbgAddr, 2);\n sOperand = \"@#\" + this.toStrBase(wIndex, -1);\n sTarget = this.getTarget(wIndex);\n }\n break;\n\n case PDP11.OPMODE.PREDEC: // 0x4: PRE-DECREMENT\n sOperand = \"-(\" + this.getRegName(reg) + \")\";\n break;\n\n case PDP11.OPMODE.PREDECD: // 0x5: PRE-DECREMENT DEFERRED\n sOperand = \"@-(\" + this.getRegName(reg) + \")\";\n break;\n\n case PDP11.OPMODE.INDEX: // 0x6: INDEX\n wIndex = this.getWord(dbgAddr, 2);\n sOperand = this.toStrBase(wIndex, -1) + '(' + this.getRegName(reg) + ')';\n if (reg == 7) {\n /*\n * When using R7 (aka PC), INDEX is known as RELATIVE. However, instead of displaying\n * such an instruction like this:\n *\n * 016156: 010167 001300 MOV R1,1300(PC) ; @017462\n *\n * with the effective address display to the far right, let's display it like this instead:\n *\n * 016156: 010167 001300 MOV R1,017462\n *\n * because you can still clearly see PC-relative offset (eg, 001300) as part of the disassembly.\n *\n * sOperand = [sOperand, this.toStrBase((wIndex + dbgAddr.addr) & 0xffff)];\n */\n sOperand = this.toStrBase(wIndex = (wIndex + dbgAddr.addr) & 0xffff);\n sTarget = this.getTarget(wIndex);\n }\n break;\n\n case PDP11.OPMODE.INDEXD: // 0x7: INDEX DEFERRED\n wIndex = this.getWord(dbgAddr, 2);\n sOperand = '@' + this.toStrBase(wIndex) + '(' + this.getRegName(reg) + ')';\n if (reg == 7) {\n /*\n * When using R7 (aka PC), INDEX DEFERRED is known as RELATIVE DEFERRED. And for the same\n * reasons articulated above, we now display the effective address inline.\n *\n * sOperand = [sOperand, this.toStrBase((wIndex + dbgAddr.addr) & 0xffff)];\n */\n sOperand = '@' + this.toStrBase(wIndex = (wIndex + dbgAddr.addr) & 0xffff);\n sTarget = this.getTarget(this.cpu.getWordSafe(wIndex));\n }\n break;\n\n default:\n\n break;\n }\n\n if (sTarget) sOperand = [sOperand, sTarget];\n }\n else {\n\n }\n }\n return sOperand;\n }\n\n /**\n * getTarget(addr)\n *\n * @this {DebuggerPDP11}\n * @param {number} addr\n * @return {string|null}\n */\n getTarget(addr)\n {\n var sTarget = null;\n var a = this.cpu.getAddrInfo(addr);\n var addrPhysical = a[0];\n if (addrPhysical >= this.cpu.addrIOPage && addrPhysical < this.bus.addrIOPage) {\n addrPhysical = (addrPhysical - this.cpu.addrIOPage) + this.bus.addrIOPage;\n }\n return this.bus.getAddrInfo(addrPhysical);\n }\n\n /**\n * parseInstruction(sOp, sOperand, addr)\n *\n * TODO: Unimplemented. See parseInstruction() in modules/c1pjs/lib/debugger.js for a sample implementation.\n *\n * @this {DebuggerPDP11}\n * @param {string} sOp\n * @param {string|undefined} sOperand\n * @param {DbgAddrPDP11} dbgAddr of memory where this instruction is being assembled\n * @return {Array.<number>} of opcode bytes; if the instruction can't be parsed, the array will be empty\n */\n parseInstruction(sOp, sOperand, dbgAddr)\n {\n var aOpBytes = [];\n this.println(\"not supported yet\");\n return aOpBytes;\n }\n\n /**\n * getFlagOutput(sFlag)\n *\n * @this {DebuggerPDP11}\n * @param {string} sFlag\n * @return {string} value of flag\n */\n getFlagOutput(sFlag)\n {\n var b;\n switch (sFlag) {\n case 'N':\n b = this.cpu.getNF();\n break;\n case 'Z':\n b = this.cpu.getZF();\n break;\n case 'V':\n b = this.cpu.getVF();\n break;\n case 'C':\n b = this.cpu.getCF();\n break;\n default:\n b = 0;\n break;\n }\n return sFlag.charAt(0) + (b? '1' : '0') + ' ';\n }\n\n /**\n * getRegOutput(iReg)\n *\n * @this {DebuggerPDP11}\n * @param {number} iReg\n * @return {string}\n */\n getRegOutput(iReg)\n {\n var sReg = this.getRegName(iReg);\n if (sReg) {\n sReg += '=' + this.toStrBase(this.getRegValue(iReg)) + ' ';\n }\n return sReg;\n }\n\n /**\n * getMiscDump()\n *\n * Sample register dump:\n *\n * M0=xxxxxx M1=xxxxxx M2=xxxxxx M3=xxxxxx ER=xxxxxx\n *\n * @this {DebuggerPDP11}\n * @return {string}\n */\n getMiscDump()\n {\n var sDump = \"\";\n sDump += this.getRegOutput(DebuggerPDP11.REG_M0) + this.getRegOutput(DebuggerPDP11.REG_M1);\n sDump += this.getRegOutput(DebuggerPDP11.REG_M2) + this.getRegOutput(DebuggerPDP11.REG_M3) + this.getRegOutput(DebuggerPDP11.REG_ER);\n sDump += '\\n';\n sDump += this.getRegOutput(DebuggerPDP11.REG_SR) + this.getRegOutput(DebuggerPDP11.REG_AR) + this.getRegOutput(DebuggerPDP11.REG_DR);\n return sDump;\n }\n\n /**\n * getRegDump(fMisc)\n *\n * Sample register dump:\n *\n * R0=xxxxxx R1=xxxxxx R2=xxxxxx R3=xxxxxx R4=xxxxxx R5=xxxxxx\n * SP=xxxxxx PC=xxxxxx PS=xxxxxx PI=xxxxxx SL=xxxxxx T0 N0 Z0 V0 C0\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fMisc] (true to include misc registers)\n * @return {string}\n */\n getRegDump(fMisc)\n {\n var i;\n var sDump = \"\";\n for (i = 0; i < PDP11.REG.SP; i++) {\n sDump += this.getRegOutput(i);\n }\n sDump += '\\n';\n sDump += this.getRegOutput(PDP11.REG.SP) + this.getRegOutput(PDP11.REG.PC);\n sDump += this.getRegOutput(DebuggerPDP11.REG_PS) + this.getRegOutput(DebuggerPDP11.REG_PI) + this.getRegOutput(DebuggerPDP11.REG_SL);\n sDump += this.getFlagOutput('T') + this.getFlagOutput('N') + this.getFlagOutput('Z') + this.getFlagOutput('V') + this.getFlagOutput('C');\n if (fMisc) sDump += '\\n' + this.getMiscDump();\n return sDump;\n }\n\n /**\n * comparePairs(p1, p2)\n *\n * @this {DebuggerPDP11}\n * @param {number|string|Array|Object} p1\n * @param {number|string|Array|Object} p2\n * @return {number}\n */\n comparePairs(p1, p2)\n {\n return p1[0] > p2[0]? 1 : p1[0] < p2[0]? -1 : 0;\n }\n\n /**\n * addSymbols(sModule, addr, len, aSymbols)\n *\n * As filedump.js (formerly convrom.php) explains, aSymbols is a JSON-encoded object whose properties consist\n * of all the symbols (in upper-case), and the values of those properties are objects containing any or all of\n * the following properties:\n *\n * 'v': the value of an absolute (unsized) value\n * 'b': either 1, 2, 4 or undefined if an unsized value\n * 's': either a hard-coded segment or undefined\n * 'o': the offset of the symbol within the associated address space\n * 'l': the original-case version of the symbol, present only if it wasn't originally upper-case\n * 'a': annotation for the specified offset; eg, the original assembly language, with optional comment\n *\n * To that list of properties, we also add:\n *\n * 'p': the physical address (calculated whenever both 's' and 'o' properties are defined)\n *\n * Note that values for any 'v', 'b', 's' and 'o' properties are unquoted decimal values, and the values\n * for any 'l' or 'a' properties are quoted strings. Also, if double-quotes were used in any of the original\n * annotation ('a') values, they will have been converted to two single-quotes, so we're responsible for\n * converting them back to individual double-quotes.\n *\n * For example:\n * {\n * 'HF_PORT': {\n * 'v':800\n * },\n * 'HDISK_INT': {\n * 'b':4, 's':0, 'o':52\n * },\n * 'ORG_VECTOR': {\n * 'b':4, 's':0, 'o':76\n * },\n * 'CMD_BLOCK': {\n * 'b':1, 's':64, 'o':66\n * },\n * 'DISK_SETUP': {\n * 'o':3\n * },\n * '.40': {\n * 'o':40, 'a':\"MOV AX,WORD PTR ORG_VECTOR ;GET DISKETTE VECTOR\"\n * }\n * }\n *\n * If a symbol only has an offset, then that offset value can be assigned to the symbol property directly:\n *\n * 'DISK_SETUP': 3\n *\n * The last property is an example of an \"anonymous\" entry, for offsets where there is no associated symbol.\n * Such entries are identified by a period followed by a unique number (usually the offset of the entry), and\n * they usually only contain offset ('o') and annotation ('a') properties. I could eliminate the leading\n * period, but it offers a very convenient way of quickly discriminating among genuine vs. anonymous symbols.\n *\n * We add all these entries to our internal symbol table, which is an array of 4-element arrays, each of which\n * look like:\n *\n * [addr, len, aSymbols, aOffsets]\n *\n * There are two basic symbol operations: findSymbol(), which takes an address and finds the symbol, if any,\n * at that address, and findSymbolAddr(), which takes a string and attempts to match it to a non-anonymous\n * symbol with a matching offset ('o') property.\n *\n * To implement findSymbol() efficiently, addSymbols() creates an array of [offset, sSymbol] pairs\n * (aOffsets), one pair for each symbol that corresponds to an offset within the specified address space.\n *\n * We guarantee the elements of aOffsets are in offset order, because we build it using binaryInsert();\n * it's quite likely that the MAP file already ordered all its symbols in offset order, but since they're\n * hand-edited files, we can't assume that, and we need to ensure that findSymbol()'s binarySearch() operates\n * properly.\n *\n * @this {DebuggerPDP11}\n * @param {string|null} sModule\n * @param {number|null} addr (physical address where the symbols are located, if the memory is physical; eg, ROM)\n * @param {number} len (the size of the region, in bytes)\n * @param {Object} aSymbols (collection of symbols in this group; the format of this collection is described below)\n */\n addSymbols(sModule, addr, len, aSymbols)\n {\n var dbgAddr = {};\n var aOffsets = [];\n for (var sSymbol in aSymbols) {\n var symbol = aSymbols[sSymbol];\n if (typeof symbol == \"number\") {\n aSymbols[sSymbol] = symbol = {'o': symbol};\n }\n var offSymbol = symbol['o'];\n var sAnnotation = symbol['a'];\n if (offSymbol !== undefined) {\n Usr.binaryInsert(aOffsets, [offSymbol >>> 0, sSymbol], this.comparePairs);\n }\n if (sAnnotation) symbol['a'] = sAnnotation.replace(/''/g, \"\\\"\");\n }\n var symbolTable = {\n sModule: sModule,\n addr: addr,\n len: len,\n aSymbols: aSymbols,\n aOffsets: aOffsets\n };\n this.aSymbolTable.push(symbolTable);\n }\n\n /**\n * dumpSymbols()\n *\n * TODO: Add \"numerical\" and \"alphabetical\" dump options. This is simply dumping them in whatever\n * order they appeared in the original MAP file.\n *\n * @this {DebuggerPDP11}\n */\n dumpSymbols()\n {\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n for (var sSymbol in symbolTable.aSymbols) {\n if (sSymbol.charAt(0) == '.') continue;\n var symbol = symbolTable.aSymbols[sSymbol];\n var offSymbol = symbol['o'];\n if (offSymbol === undefined) continue;\n var sSymbolOrig = symbolTable.aSymbols[sSymbol]['l'];\n if (sSymbolOrig) sSymbol = sSymbolOrig;\n this.println(this.toStrOffset(offSymbol) + ' ' + sSymbol);\n }\n }\n }\n\n /**\n * findSymbol(dbgAddr, fNearest)\n *\n * Search aSymbolTable for dbgAddr, and return an Array for the corresponding symbol (empty if not found).\n *\n * If fNearest is true, and no exact match was found, then the Array returned will contain TWO sets of\n * entries: [0]-[3] will refer to closest preceding symbol, and [4]-[7] will refer to the closest subsequent symbol.\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @param {boolean} [fNearest]\n * @return {Array} where [0] == symbol name, [1] == symbol value, [2] == any annotation, and [3] == any associated comment\n */\n findSymbol(dbgAddr, fNearest)\n {\n var aSymbol = [];\n var addrSymbol = this.getAddr(dbgAddr) >>> 0;\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n var addr = symbolTable.addr >>> 0;\n var len = symbolTable.len;\n if (addrSymbol >= addr && addrSymbol < addr + len) {\n var offSymbol = addrSymbol - addr;\n var result = Usr.binarySearch(symbolTable.aOffsets, [offSymbol], this.comparePairs);\n if (result >= 0) {\n this.returnSymbol(iTable, result, aSymbol);\n }\n else if (fNearest) {\n result = ~result;\n this.returnSymbol(iTable, result-1, aSymbol);\n this.returnSymbol(iTable, result, aSymbol);\n }\n break;\n }\n }\n return aSymbol;\n }\n\n /**\n * findSymbolAddr(sSymbol)\n *\n * Search our symbol tables for sSymbol, and if found, return a dbgAddr (same as parseAddr()).\n *\n * @this {DebuggerPDP11}\n * @param {string} sSymbol\n * @return {DbgAddrPDP11|undefined}\n */\n findSymbolAddr(sSymbol)\n {\n var dbgAddr;\n var offSymbol = this.bus.getAddrByName(sSymbol);\n\n if (offSymbol == null && sSymbol.match(/^[a-z_][a-z0-9_]*$/i)) {\n var sUpperCase = sSymbol.toUpperCase();\n for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {\n var symbolTable = this.aSymbolTable[iTable];\n var symbol = symbolTable.aSymbols[sUpperCase];\n if (symbol != null) {\n offSymbol = symbol['o'];\n /*\n * If the symbol matched but there's no 'o' offset (ie, it wasn't for an address), there's\n * no point looking any farther, since each symbol appears only once.\n *\n * NOTE: We assume that every ROM is ORG'ed at 0x0000, and therefore unless the symbol has an\n * explicitly-defined segment, we return the segment associated with the entire group; for a ROM,\n * that segment is normally \"addrROM >>> 4\". Down the road, we may want/need to support a special\n * symbol entry (eg, \".ORG\") that defines an alternate origin.\n */\n break;\n }\n }\n }\n if (offSymbol != null) {\n dbgAddr = this.newAddr(offSymbol);\n }\n return dbgAddr;\n }\n\n /**\n * returnSymbol(iTable, iOffset, aSymbol)\n *\n * Helper function for findSymbol().\n *\n * @param {number} iTable\n * @param {number} iOffset\n * @param {Array} aSymbol is updated with the specified symbol, if it exists\n */\n returnSymbol(iTable, iOffset, aSymbol)\n {\n var symbol = {};\n var aOffsets = this.aSymbolTable[iTable].aOffsets;\n var offset = 0, sSymbol = null;\n if (iOffset >= 0 && iOffset < aOffsets.length) {\n offset = aOffsets[iOffset][0];\n sSymbol = aOffsets[iOffset][1];\n }\n if (sSymbol) {\n symbol = this.aSymbolTable[iTable].aSymbols[sSymbol];\n sSymbol = (sSymbol.charAt(0) == '.'? null : (symbol['l'] || sSymbol));\n }\n aSymbol.push(sSymbol);\n aSymbol.push(offset);\n aSymbol.push(symbol['a']);\n aSymbol.push(symbol['c']);\n }\n\n /**\n * doHelp()\n *\n * @this {DebuggerPDP11}\n */\n doHelp()\n {\n var s = \"commands:\";\n for (var sCommand in DebuggerPDP11.COMMANDS) {\n s += '\\n' + Str.pad(sCommand, 9) + DebuggerPDP11.COMMANDS[sCommand];\n }\n if (!this.checksEnabled()) s += \"\\nnote: history disabled if no exec breakpoints\";\n this.println(s);\n }\n\n /**\n * doAssemble(asArgs)\n *\n * This always receives the complete argument array, where the order of the arguments is:\n *\n * [0]: the assemble command (assumed to be \"a\")\n * [1]: the target address (eg, \"200\")\n * [2]: the operation code, aka instruction name (eg, \"adc\")\n * [3]: the operation mode operand, if any (eg, \"14\", \"[1234]\", etc)\n *\n * The Debugger enters \"assemble mode\" whenever only the first (or first and second) arguments are present.\n * As long as \"assemble mode is active, the user can omit the first two arguments on all later assemble commands\n * until \"assemble mode\" is cancelled with an empty command line; the command processor automatically prepends \"a\"\n * and the next available target address to the argument array.\n *\n * Entering \"assemble mode\" is optional; one could enter a series of fully-qualified assemble commands; eg:\n *\n * a ff00 cld\n * a ff01 ldx 28\n * ...\n *\n * without ever entering \"assemble mode\", but of course, that requires more typing and doesn't take advantage\n * of automatic target address advancement (see dbgAddrAssemble).\n *\n * NOTE: As the previous example implies, you can even assemble new instructions into ROM address space;\n * as our setByte() function explains, the ROM write-notification handlers only refuse writes from the CPU.\n *\n * @this {DebuggerPDP11}\n * @param {Array.<string>} asArgs is the complete argument array, beginning with the \"a\" command in asArgs[0]\n */\n doAssemble(asArgs)\n {\n var dbgAddr = this.parseAddr(asArgs[1], true);\n if (!dbgAddr) return;\n\n this.dbgAddrAssemble = dbgAddr;\n if (asArgs[2] === undefined) {\n this.println(\"begin assemble at \" + this.toStrAddr(dbgAddr));\n this.fAssemble = true;\n this.cmp.updateDisplays();\n return;\n }\n\n var aOpBytes = this.parseInstruction(asArgs[2], asArgs[3], dbgAddr);\n if (aOpBytes.length) {\n for (var i = 0; i < aOpBytes.length; i++) {\n this.setByte(dbgAddr, aOpBytes[i], 1);\n }\n /*\n * Since getInstruction() also updates the specified address, dbgAddrAssemble is automatically advanced.\n */\n this.println(this.getInstruction(this.dbgAddrAssemble));\n }\n }\n\n /**\n * doBreak(sCmd, sAddr, sOptions)\n *\n * As the \"help\" output below indicates, the following breakpoint commands are supported:\n *\n * bp # set exec breakpoint\n * br # set read breakpoint\n * bw # set write breakpoint\n * bc # clear breakpoint (* to clear all)\n * bl list all breakpoints\n * bn [#] break after # instruction(s)\n *\n * The \"bn\" command, like the \"dh\" command and all other commands that use an instruction count,\n * assumes a decimal value, regardless of the current base. Use \"bn\" without an argument to display\n * the break count, and use \"bn 0\" to clear the break count.\n *\n * @this {DebuggerPDP11}\n * @param {string} sCmd\n * @param {string|undefined} [sAddr]\n * @param {string} [sOptions] (the rest of the breakpoint command-line)\n */\n doBreak(sCmd, sAddr, sOptions)\n {\n if (sAddr == '?') {\n this.println(\"breakpoint commands:\");\n this.println(\"\\tbp #\\tset exec breakpoint\");\n this.println(\"\\tbr #\\tset read breakpoint\");\n this.println(\"\\tbw #\\tset write breakpoint\");\n this.println(\"\\tbc #\\tclear breakpoint (* to clear all)\");\n this.println(\"\\tbl\\tlist all breakpoints\");\n this.println(\"\\tbn [#]\\tbreak after # instruction(s)\");\n return;\n }\n\n var sParm = sCmd.charAt(1);\n if (sParm == 'l') {\n var cBreaks = 0;\n cBreaks += this.listBreakpoints(this.aBreakExec);\n cBreaks += this.listBreakpoints(this.aBreakRead);\n cBreaks += this.listBreakpoints(this.aBreakWrite);\n if (!cBreaks) this.println(\"no breakpoints\");\n return;\n }\n\n if (sParm == 'n') {\n var n = +sAddr || 0;\n if (sAddr) this.nBreakInstructions = n;\n this.println(\"break after \" + n + \" instruction(s)\");\n return;\n }\n\n if (sAddr === undefined) {\n this.println(\"missing breakpoint address\");\n return;\n }\n\n var dbgAddr = this.newAddr();\n if (sAddr != '*') {\n dbgAddr = this.parseAddr(sAddr, true, true);\n if (!dbgAddr) return;\n }\n\n if (sParm == 'c') {\n if (dbgAddr.addr == null) {\n this.clearBreakpoints();\n this.println(\"all breakpoints cleared\");\n return;\n }\n if (this.findBreakpoint(this.aBreakExec, dbgAddr, true))\n return;\n if (this.findBreakpoint(this.aBreakRead, dbgAddr, true))\n return;\n if (this.findBreakpoint(this.aBreakWrite, dbgAddr, true))\n return;\n this.println(\"breakpoint missing: \" + this.toStrAddr(dbgAddr));\n return;\n }\n\n if (dbgAddr.addr == null) return;\n\n this.parseAddrOptions(dbgAddr, sOptions);\n\n if (sParm == 'p') {\n this.addBreakpoint(this.aBreakExec, dbgAddr);\n return;\n }\n if (sParm == 'r') {\n this.addBreakpoint(this.aBreakRead, dbgAddr);\n return;\n }\n if (sParm == 'w') {\n this.addBreakpoint(this.aBreakWrite, dbgAddr);\n return;\n }\n this.println(\"unknown breakpoint command: \" + sParm);\n }\n\n /**\n * doClear(sCmd)\n *\n * @this {DebuggerPDP11}\n * @param {string} [sCmd] (eg, \"cls\" or \"clear\")\n */\n doClear(sCmd)\n {\n this.cmp.clearPanel();\n }\n\n /**\n * doDump(asArgs)\n *\n * The length parameter is interpreted as a number of bytes (or words, or dwords) to dump,\n * and it is interpreted using the current base.\n *\n * @this {DebuggerPDP11}\n * @param {Array.<string>} asArgs (formerly sCmd, [sAddr], [sLen] and [sBytes])\n */\n doDump(asArgs)\n {\n var m;\n var sCmd = asArgs[0];\n var sAddr = asArgs[1];\n var sLen = asArgs[2];\n var sBytes = asArgs[3];\n\n if (sAddr == '?') {\n var sDumpers = \"\";\n for (m in MessagesPDP11.CATEGORIES) {\n if (this.afnDumpers[m]) {\n if (sDumpers) sDumpers += ',';\n sDumpers += m;\n }\n }\n sDumpers += \",state,symbols\";\n this.println(\"dump memory commands:\");\n this.println(\"\\tda [a] dump info for address a\");\n this.println(\"\\tdb [a] [n] dump n bytes at address a\");\n this.println(\"\\tdw [a] [n] dump n words at address a\");\n this.println(\"\\tdd [a] [n] dump n dwords at address a\");\n this.println(\"\\tds [a] [n] dump n words at address a as JSON\");\n this.println(\"\\tdh [p] [n] dump n instructions from history position p\");\n if (sDumpers.length) this.println(\"dump extension commands:\\n\\t\" + sDumpers);\n return;\n }\n\n if (sAddr == \"state\") {\n var sState = this.cmp.powerOff(true);\n if (sLen == \"console\") {\n /*\n * Console buffers are notoriously small, and even the following code, which breaks the\n * data into parts (eg, \"d state console 1\", \"d state console 2\", etc) just isn't that helpful.\n *\n * var nPart = +sBytes;\n * if (nPart) sState = sState.substr(1000000 * (nPart-1), 1000000);\n *\n * So, the best way to capture a large machine state is to use the new \"Save Machine\" link\n * that downloads a machine's entire state. Alternatively, run your own local server and use\n * server-side storage. Take a look at the \"Save\" binding in computer.js, which binds an HTML\n * control to the computer.powerOff() and computer.saveServerState() functions.\n */\n console.log(sState);\n } else {\n this.doClear();\n if (sState) this.println(sState);\n }\n return;\n }\n\n if (sAddr == \"symbols\") {\n this.dumpSymbols();\n return;\n }\n\n if (sCmd == \"d\") {\n for (m in MessagesPDP11.CATEGORIES) {\n if (asArgs[1] == m) {\n var fnDumper = this.afnDumpers[m];\n if (fnDumper) {\n asArgs.shift();\n asArgs.shift();\n fnDumper(asArgs);\n } else {\n this.println(\"no dump registered for \" + sAddr);\n }\n return;\n }\n }\n if (!sAddr) sCmd = this.sCmdDumpPrev || \"dw\";\n } else {\n this.sCmdDumpPrev = sCmd;\n }\n\n if (sCmd == \"dh\") {\n this.dumpHistory(sAddr, sLen);\n return;\n }\n\n var dbgAddr = this.parseAddr(sAddr);\n if (!dbgAddr) return;\n\n if (sCmd == \"da\") {\n /*\n * Sample output for a virtual address (\"da 23042\"):\n *\n * 00,010,011,000,100,010 00023042\n * OFFSET: 0,011,000,100,010 00003042\n * + KIPAR1: 0,000,001,101,111,010,000,000 00157200\n * & MMUMASK: 1,111,111,111,111,111,111,111 17777777\n * = PHYSICAL: 0,000,001,110,010,010,100,010 00162242\n *\n * and sample output for a physical address (eg, \"da %37772\"; note the % prefix):\n *\n * 0,000,000,011,111,111,111,010 00037772\n * OFFSET: 1,111,111,111,010 00017772\n * UNIMAP[01]: 1,111,100,001,110,111,000,000 17416700\n * PHYSICAL: 1,111,100,011,110,110,111,010 17436672\n *\n * TODO: Tweak this output to accommodate 18-bit machines as well as 22-bit machines.\n */\n var fPhysical = (dbgAddr.fPhysical || dbgAddr.addr > 0xffff);\n var a = this.cpu.getAddrInfo(dbgAddr.addr || 0, fPhysical);\n this.println(Str.pad(\"\", fPhysical? 12: 19) + Str.toBin(dbgAddr.addr, fPhysical? 22 : 17, 3) + \" \" + Str.toOct(dbgAddr.addr, 8));\n if (a.length < 6) {\n if (a.length > 2) {\n this.println(\" OFFSET: \" + Str.toBin(a[3], 13, 3) + \" \" + Str.toOct(a[3], 8));\n this.println(\"UNIMAP[\" + Str.toDec(a[1], 2) + \"]: \" + Str.toBin(a[2], 22, 3) + \" \" + Str.toOct(a[2], 8));\n }\n this.println(\" PHYSICAL: \" + Str.toBin(a[0], 22, 3) + \" \" + Str.toOct(a[0], 8))\n } else {\n this.println(\" OFFSET: \" + Str.toBin(a[1], 13, 3) + \" \" + Str.toOct(a[1], 8));\n this.println(\"+ \" + DebuggerPDP11.MODES[a[2]] + \"PAR\" + a[3] + \": \" + Str.toBin(a[4], 22, 3) + \" \" + Str.toOct(a[4], 8));\n this.println(\"& MMUMASK: \" + Str.toBin(a[5], 22, 3) + \" \" + Str.toOct(a[5], 8));\n this.println(\"= PHYSICAL: \" + Str.toBin(a[0], 22, 3) + \" \" + Str.toOct(a[0], 8))\n }\n return;\n }\n\n var len = 0;\n var fJSON = (sCmd == \"ds\");\n\n if (sLen) {\n if (sLen.charAt(0) == 'l') {\n sLen = sLen.substr(1) || sBytes;\n len = this.parseValue(sLen);\n }\n else {\n var dbgAddrEnd = this.parseAddr(sLen);\n if (dbgAddrEnd) len = dbgAddrEnd.addr - dbgAddr.addr;\n }\n if (len < 0) len = 0;\n if (len > 0x10000) len = 0x10000;\n }\n\n var nBase = this.nBase;\n if (dbgAddr.nBase) this.nBase = dbgAddr.nBase;\n\n /*\n * I've changed the code below to effectively make \"dw\" the default if only \"d\" is specified,\n * since this is primarily a word-oriented machine.\n */\n var size = (sCmd == \"dd\"? 4 : (sCmd == \"db\"? 1 : 2));\n var nBytes = (size * len) || 128;\n var nBytesPerLine = fJSON? 16 : this.nBase;\n var nLines = (((nBytes + nBytesPerLine - 1) / nBytesPerLine)|0) || 1;\n\n var sDump = \"\";\n while (nLines-- && nBytes > 0) {\n var sData = \"\", sChars = \"\";\n sAddr = this.toStrAddr(dbgAddr);\n /*\n * Dump 8 bytes per line when using base 8, and dump 16 bytes when using base 16.\n *\n * And while we used to always call getByte() and assemble them into words or dwords as appropriate, I've\n * changed the logic below to honor \"dw\" by calling getWord(), since the Bus interfaces have been updated\n * to prevent generating traps due to to Debugger access of unaligned memory and/or undefined IOPAGE addresses.\n *\n * Besides, it's nice for \"db\" and \"dw\" to generate the same Bus activity that typical byte and word reads do.\n */\n var i = nBytesPerLine;\n var data = 0, shift = 0;\n while (i > 0 && nBytes > 0) {\n var n = 1;\n var v = size == 1? this.getByte(dbgAddr, n) : this.getWord(dbgAddr, (n = 2));\n data |= (v << (shift << 3));\n shift += n;\n if (shift == size) {\n if (fJSON) {\n if (sData) sData += \",\";\n sData += \"0x\"+ Str.toHex(data, size << 1);\n } else {\n sData += this.toStrBase(data, size << 3);\n sData += (size == 1? (i == 9? '-' : ' ') : \" \");\n }\n data = shift = 0;\n }\n i -= n; nBytes -= n;\n while (size == 1 && n--) {\n var c = v & 0xff;\n sChars += (c >= 32 && c < 127? String.fromCharCode(c) : '.');\n v >>= 8;\n }\n }\n if (sDump) sDump += \"\\n\";\n if (fJSON) {\n sDump += sData + \",\";\n } else {\n sDump += sAddr + \": \" + sData + ((i == 0)? (' ' + sChars) : \"\");\n }\n }\n\n if (sDump) this.println(sDump);\n\n this.dbgAddrNextData = dbgAddr;\n this.nBase = nBase;\n }\n\n /**\n * doEdit(asArgs)\n *\n * @this {DebuggerPDP11}\n * @param {Array.<string>} asArgs\n */\n doEdit(asArgs)\n {\n var size, mask;\n var fnGet, fnSet;\n var sCmd = asArgs[0];\n var sAddr = asArgs[1];\n if (sCmd == \"eb\") {\n size = 1;\n mask = 0xff;\n fnGet = this.getByte;\n fnSet = this.setByte;\n }\n else if (sCmd == \"e\" || sCmd == \"ew\") {\n size = 2;\n mask = 0xffff;\n fnGet = this.getWord;\n fnSet = this.setWord;\n } else {\n sAddr = null;\n }\n if (sAddr == null) {\n this.println(\"edit memory commands:\");\n this.println(\"\\teb [a] [...] edit bytes at address a\");\n this.println(\"\\tew [a] [...] edit words at address a\");\n return;\n }\n var dbgAddr = this.parseAddr(sAddr);\n if (!dbgAddr) return;\n for (var i = 2; i < asArgs.length; i++) {\n var vNew = this.parseExpression(asArgs[i]);\n if (vNew === undefined) {\n this.println(\"unrecognized value: \" + asArgs[i]);\n break;\n }\n if (vNew & ~mask) {\n this.println(\"warning: \" + Str.toHex(vNew) + \" exceeds \" + size + \"-byte value\");\n }\n this.println(\"changing \" + this.toStrAddr(dbgAddr) + (this.messageEnabled(MessagesPDP11.BUS)? \"\" : (\" from \" + this.toStrBase(fnGet.call(this, dbgAddr), size << 3))) + \" to \" + this.toStrBase(vNew, size << 3));\n fnSet.call(this, dbgAddr, vNew, size);\n }\n }\n\n /**\n * doHalt(fQuiet)\n *\n * @this {DebuggerPDP11}\n * @param {boolean} [fQuiet]\n */\n doHalt(fQuiet)\n {\n var sMsg;\n if (this.flags.running) {\n if (!fQuiet) this.println(\"halting\");\n this.stopCPU();\n } else {\n if (this.isBusy(true)) return;\n if (!fQuiet) this.println(\"already halted\");\n }\n }\n\n /**\n * doIf(sCmd, fQuiet)\n *\n * NOTE: Don't forget that the default base for all numeric constants is 16 (hex), so when you evaluate\n * an expression like \"a==10\", it will compare the value of the variable \"a\" to 0x10; use a trailing period\n * (eg, \"10.\") if you really intend decimal.\n *\n * Also, if no variable named \"a\" exists, \"a\" will evaluate to 0x0A, so the expression \"a==10\" becomes\n * \"0x0A==0x10\" (false), whereas the expression \"a==10.\" becomes \"0x0A==0x0A\" (true).\n *\n * @this {DebuggerPDP11}\n * @param {string} sCmd\n * @param {boolean} [fQuiet]\n * @return {boolean} true if expression is non-zero, false if zero (or undefined due to a parse error)\n */\n doIf(sCmd, fQuiet)\n {\n sCmd = Str.trim(sCmd);\n if (!this.parseExpression(sCmd)) {\n if (!fQuiet) this.println(\"false: \" + sCmd);\n return false;\n }\n if (!fQuiet) this.println(\"true: \" + sCmd);\n return true;\n }\n\n /**\n * doInfo(asArgs)\n *\n * @this {DebuggerPDP11}\n * @param {Array.<string>} asArgs\n * @return {boolean} true only if the instruction info command (\"n\") is supported\n */\n doInfo(asArgs)\n {\n if (DEBUG) {\n this.println(\"msPerYield: \" + this.cpu.msPerYield);\n this.println(\"nCyclesPerYield: \" + this.cpu.nCyclesPerYield);\n return true;\n }\n return false;\n }\n\n /**\n * doVar(sCmd)\n *\n * The command must be of the form \"{variable} = [{expression}]\", where expression may contain constants,\n * operators, registers, symbols, other variables, or nothing at all; in the latter case, the variable, if\n * any, is deleted.\n *\n * Other supported shorthand: \"var\" with no parameters prints the values of all variables, and \"var {variable}\"\n * prints the value of the specified variable.\n *\n * @this {DebuggerPDP11}\n * @param {string} sCmd\n * @return {boolean} true if valid \"var\" assignment, false if not\n */\n doVar(sCmd)\n {\n var a = sCmd.match(/^\\s*([A-Z_]?[A-Z0-9_]*)\\s*(=?)\\s*(.*)$/i);\n if (a) {\n if (!a[1]) {\n if (!this.printVariable()) this.println(\"no variables\");\n return true; // it's not considered an error to print an empty list of variables\n }\n if (!a[2]) {\n return this.printVariable(a[1]);\n }\n if (!a[3]) {\n this.delVariable(a[1]);\n return true; // it's not considered an error to delete a variable that didn't exist\n }\n var v = this.parseExpression(a[3]);\n if (v !== undefined) {\n this.setVariable(a[1], v);\n return true;\n }\n return false;\n }\n this.println(\"invalid assignment:\" + sCmd);\n return false;\n }\n\n /**\n * doList(sAddr, fPrint)\n *\n * @this {DebuggerPDP11}\n * @param {string} sAddr\n * @param {boolean} [fPrint]\n * @return {string|null}\n */\n doList(sAddr, fPrint)\n {\n var sSymbol = null;\n\n var dbgAddr = this.parseAddr(sAddr, true);\n if (dbgAddr) {\n var addr = this.getAddr(dbgAddr);\n var aSymbol = this.findSymbol(dbgAddr, true);\n if (aSymbol.length) {\n var nDelta, sDelta, s;\n if (aSymbol[0]) {\n sDelta = \"\";\n nDelta = dbgAddr.addr - aSymbol[1];\n if (nDelta) sDelta = \" + \" + Str.toHexWord(nDelta);\n s = aSymbol[0] + \" (\" + this.toStrOffset(aSymbol[1]) + ')' + sDelta;\n if (fPrint) this.println(s);\n sSymbol = s;\n }\n if (aSymbol.length > 4 && aSymbol[4]) {\n sDelta = \"\";\n nDelta = aSymbol[5] - dbgAddr.addr;\n if (nDelta) sDelta = \" - \" + Str.toHexWord(nDelta);\n s = aSymbol[4] + \" (\" + this.toStrOffset(aSymbol[5]) + ')' + sDelta;\n if (fPrint) this.println(s);\n if (!sSymbol) sSymbol = s;\n }\n } else {\n if (fPrint) this.println(\"no symbols\");\n }\n }\n return sSymbol;\n }\n\n /**\n * doMessages(asArgs)\n *\n * @this {DebuggerPDP11}\n * @param {Array.<string>} asArgs\n */\n doMessages(asArgs)\n {\n var m;\n var fCriteria = null;\n var sCategory = asArgs[1];\n if (sCategory == '?') sCategory = undefined;\n\n if (sCategory !== undefined) {\n var bitsMessage = 0;\n if (sCategory == \"all\") {\n bitsMessage = (0xffffffff|0) & ~(MessagesPDP11.HALT | MessagesPDP11.KEYS | MessagesPDP11.BUFFER);\n sCategory = null;\n } else if (sCategory == \"on\") {\n fCriteria = true;\n sCategory = null;\n } else if (sCategory == \"off\") {\n fCriteria = false;\n sCategory = null;\n } else {\n /*\n * Internally, we use \"key\" instead of \"keys\", since the latter is a method on JavasScript objects,\n * but externally, we allow the user to specify \"keys\"; \"kbd\" is also allowed as shorthand for \"keyboard\".\n */\n if (sCategory == \"keys\") sCategory = \"key\";\n if (sCategory == \"kbd\") sCategory = \"keyboard\";\n for (m in MessagesPDP11.CATEGORIES) {\n if (sCategory == m) {\n bitsMessage = MessagesPDP11.CATEGORIES[m];\n fCriteria = !!(this.bitsMessage & bitsMessage);\n break;\n }\n }\n if (!bitsMessage) {\n this.println(\"unknown message category: \" + sCategory);\n return;\n }\n }\n if (bitsMessage) {\n if (asArgs[2] == \"on\") {\n this.bitsMessage |= bitsMessage;\n fCriteria = true;\n }\n else if (asArgs[2] == \"off\") {\n this.bitsMessage &= ~bitsMessage;\n fCriteria = false;\n if (bitsMessage == MessagesPDP11.BUFFER) {\n var i = this.aMessageBuffer.length >= 1000? this.aMessageBuffer.length - 1000 : 0;\n while (i < this.aMessageBuffer.length) {\n this.println(this.aMessageBuffer[i++]);\n }\n this.aMessageBuffer = [];\n }\n }\n }\n }\n\n /*\n * Display those message categories that match the current criteria (on or off)\n */\n var n = 0;\n var sCategories = \"\";\n for (m in MessagesPDP11.CATEGORIES) {\n if (!sCategory || sCategory == m) {\n var bitMessage = MessagesPDP11.CATEGORIES[m];\n var fEnabled = !!(this.bitsMessage & bitMessage);\n if (fCriteria !== null && fCriteria != fEnabled) continue;\n if (sCategories) sCategories += ',';\n if (!(++n % 10)) sCategories += \"\\n\\t\"; // jshint ignore:line\n /*\n * Internally, we use \"key\" instead of \"keys\", since the latter is a method on JavasScript objects,\n * but externally, we allow the user to specify \"keys\".\n */\n if (m == \"key\") m = \"keys\";\n sCategories += m;\n }\n }\n\n if (sCategory === undefined) {\n this.println(\"message commands:\\n\\tm [category] [on|off]\\tturn categories on/off\");\n }\n\n this.println((fCriteria !== null? (fCriteria? \"messages on: \" : \"messages off: \") : \"message categories:\\n\\t\") + (sCategories || \"none\"));\n\n this.historyInit(); // call this just in case MessagesPDP11.INT was turned on\n }\n\n /**\n * doOptions(asArgs)\n *\n * @this {DebuggerPDP11}\n * @param {Array.<string>} asArgs\n */\n doOptions(asArgs)\n {\n switch (asArgs[1]) {\n\n case \"base\":\n if (asArgs[2]) {\n var nBase = +asArgs[2];\n if (nBase == 8 || nBase == 10 || nBase == 16) {\n this.nBase = nBase;\n } else {\n this.println(\"invalid base: \" + nBase);\n break;\n }\n }\n this.println(\"default base: \" + this.nBase);\n break;\n\n case \"cs\":\n var nCycles;\n if (asArgs[3] !== undefined) nCycles = +asArgs[3]; // warning: decimal instead of hex conversion\n switch (asArgs[2]) {\n case \"int\":\n this.cpu.nCyclesChecksumInterval = nCycles;\n break;\n case \"start\":\n this.cpu.nCyclesChecksumStart = nCycles;\n break;\n case \"stop\":\n this.cpu.nCyclesChecksumStop = nCycles;\n break;\n default:\n this.println(\"unknown cs option\");\n return;\n }\n if (nCycles !== undefined) {\n this.cpu.resetChecksum();\n }\n this.println(\"checksums \" + (this.cpu.flags.checksum? \"enabled\" : \"disabled\"));\n return;\n\n case \"sp\":\n if (asArgs[2] !== undefined) {\n if (!this.cpu.setSpeed(+asArgs[2])) {\n this.println(\"warning: using 1x multiplier, previous target not reached\");\n }\n }\n this.println(\"target speed: \" + this.cpu.getSpeedTarget() + \" (\" + this.cpu.getSpeed() + \"x)\");\n return;\n\n default:\n if (asArgs[1]) {\n this.println(\"unknown option: \" + asArgs[1]);\n return;\n }\n /* falls through */\n\n case \"?\":\n this.println(\"debugger options:\");\n this.println(\"\\tbase #\\t\\tset default base to #\");\n this.println(\"\\tcs int #\\tset checksum cycle interval to #\");\n this.println(\"\\tcs start #\\tset checksum cycle start count to #\");\n this.println(\"\\tcs stop #\\tset checksum cycle stop count to #\");\n this.println(\"\\tsp #\\t\\tset speed multiplier to #\");\n break;\n }\n }\n\n /**\n * doRegisters(asArgs, fInstruction)\n *\n * @this {DebuggerPDP11}\n * @param {Array.<string>} [asArgs]\n * @param {boolean} [fInstruction] (true to include the current instruction; default is true)\n */\n doRegisters(asArgs, fInstruction)\n {\n if (asArgs && asArgs[1] == '?') {\n this.println(\"register commands:\");\n this.println(\"\\tr\\tdump registers\");\n this.println(\"\\trm\\tdump misc registers\");\n this.println(\"\\trx [#]\\tset flag or register x to [#]\");\n return;\n }\n\n var fMisc = false;\n var cpu = this.cpu;\n if (fInstruction == null) fInstruction = true;\n\n if (asArgs != null && asArgs.length > 1) {\n var sReg = asArgs[1];\n\n if (sReg == 'm') {\n fMisc = true;\n }\n else {\n var sValue = null;\n var i = sReg.indexOf('=');\n if (i > 0) {\n sValue = sReg.substr(i + 1);\n sReg = sReg.substr(0, i);\n }\n else if (asArgs.length > 2) {\n sValue = asArgs[2];\n }\n else {\n this.println(\"missing value for \" + asArgs[1]);\n return;\n }\n\n var w = this.parseExpression(sValue);\n if (w === undefined) return;\n\n var sRegMatch = sReg.toUpperCase();\n switch (sRegMatch) {\n case \"SP\":\n case \"R6\":\n cpu.setSP(w);\n break;\n case \"PC\":\n case \"R7\":\n cpu.setPC(w);\n this.dbgAddrNextCode = this.newAddr(cpu.getPC());\n break;\n case \"N\":\n if (w) cpu.setNF(); else cpu.clearNF();\n break;\n case \"Z\":\n if (w) cpu.setZF(); else cpu.clearZF();\n break;\n case \"V\":\n if (w) cpu.setVF(); else cpu.clearVF();\n break;\n case \"C\":\n if (w) cpu.setCF(); else cpu.clearCF();\n break;\n case \"PS\":\n cpu.setPSW(w);\n break;\n case \"PI\":\n cpu.setPIR(w);\n break;\n case \"ER\":\n cpu.regErr = w;\n fMisc = true;\n break;\n case \"SL\":\n cpu.setSLR(w);\n break;\n case \"M0\":\n cpu.setMMR0(w);\n fMisc = true;\n break;\n case \"M3\":\n cpu.setMMR3(w);\n fMisc = true;\n break;\n case \"AR\":\n if (this.panel) this.panel.setAR(w);\n fMisc = true;\n break;\n case \"DR\":\n if (this.panel) this.panel.setDR(w);\n fMisc = true;\n break;\n case \"SR\":\n if (this.panel) this.panel.setSR(w);\n fMisc = true;\n break;\n default:\n if (sRegMatch.charAt(0) == 'R') {\n var iReg = +sRegMatch.charAt(1);\n if (iReg >= 0 && iReg < 6) {\n cpu.regsGen[iReg] = w & 0xffff;\n break;\n }\n }\n this.println(\"unknown register: \" + sReg);\n return;\n }\n this.cmp.updateDisplays();\n this.println(\"updated registers:\");\n }\n }\n\n this.println(this.getRegDump(fMisc));\n\n if (fInstruction) {\n this.dbgAddrNextCode = this.newAddr(cpu.getPC());\n this.doUnassemble(this.toStrAddr(this.dbgAddrNextCode));\n }\n }\n\n /**\n * doRun(sCmd, sAddr, sOptions, fQuiet)\n *\n * @this {DebuggerPDP11}\n * @param {string} sCmd\n * @param {string|undefined} [sAddr]\n * @param {string} [sOptions] (the rest of the breakpoint command-line)\n * @param {boolean} [fQuiet]\n */\n doRun(sCmd, sAddr, sOptions, fQuiet)\n {\n if (sCmd == \"gt\") {\n this.fIgnoreNextCheckFault = true;\n }\n if (sAddr !== undefined) {\n var dbgAddr = this.parseAddr(sAddr, true);\n if (!dbgAddr) return;\n this.parseAddrOptions(dbgAddr, sOptions);\n this.setTempBreakpoint(dbgAddr);\n }\n this.startCPU(true, fQuiet);\n }\n\n /**\n * doPrint(sCmd)\n *\n * NOTE: If the string to print is a quoted string, then we run it through replaceRegs(), so that\n * you can take advantage of all the special replacement options used for software interrupt logging.\n *\n * @this {DebuggerPDP11}\n * @param {string} sCmd\n */\n doPrint(sCmd)\n {\n sCmd = Str.trim(sCmd);\n var a = sCmd.match(/^(['\"])(.*?)\\1$/);\n if (!a) {\n this.parseExpression(sCmd, false);\n } else {\n if (a[2].length > 1) {\n this.println(this.replaceRegs(a[2]));\n } else {\n this.printValue(null, a[2].charCodeAt(0));\n }\n }\n }\n\n /**\n * doStep(sCmd, sOption)\n *\n * @this {DebuggerPDP11}\n * @param {string} [sCmd] \"p\" or \"pr\"\n * @param {string} [sOption]\n */\n doStep(sCmd, sOption)\n {\n if (sOption == '?') {\n this.println(\"step commands:\");\n this.println(\"\\tp\\tstep over instruction\");\n this.println(\"\\tpr\\tstep over instruction with register update\");\n return;\n }\n\n var fCallStep = true;\n var nRegs = (sCmd == \"pr\"? 1 : 0);\n /*\n * Set up the value for this.nStep (ie, 1 or 2) depending on whether the user wants\n * a subsequent register dump (\"pr\") or not (\"p\").\n */\n var nStep = 1 + nRegs;\n\n if (!this.nStep) {\n var dbgAddr = this.newAddr(this.cpu.getPC());\n var opCode = this.getWord(dbgAddr);\n\n if (opCode == PDP11.OPCODE.BPT || opCode == PDP11.OPCODE.IOT ||\n (opCode & PDP11.OPCODE.EMT_MASK) == PDP11.OPCODE.EMT_OP ||\n (opCode & PDP11.OPCODE.SOB_MASK) == PDP11.OPCODE.SOB_OP ||\n (opCode & PDP11.OPCODE.TRAP_MASK) == PDP11.OPCODE.TRAP_OP) {\n if (fCallStep) {\n this.nStep = nStep;\n this.incAddr(dbgAddr, 2);\n }\n } else if ((opCode & PDP11.OPCODE.JSR_MASK) == PDP11.OPCODE.JSR_OP) {\n var s = this.getInstruction(dbgAddr);\n\n if (fCallStep) {\n this.nStep = nStep;\n }\n }\n\n if (this.nStep) {\n this.setTempBreakpoint(dbgAddr);\n if (!this.startCPU()) {\n if (this.cmp) this.cmp.setFocus();\n this.nStep = 0;\n }\n /*\n * A successful run will ultimately call stop(), which will in turn call clearTempBreakpoint(),\n * which will clear nStep, so there's your assurance that nStep will be reset. Now we may have\n * stopped for reasons unrelated to the temporary breakpoint, but that's OK.\n */\n } else {\n this.doTrace(nRegs? \"tr\" : \"t\");\n }\n } else {\n this.println(\"step in progress\");\n }\n }\n\n /**\n * getCall(dbgAddr)\n *\n * Given a possible return address (typically from the stack), look for a matching CALL (or INT) that\n * immediately precedes that address.\n *\n * @this {DebuggerPDP11}\n * @param {DbgAddrPDP11} dbgAddr\n * @return {string|null} CALL instruction at or near dbgAddr, or null if none\n */\n getCall(dbgAddr)\n {\n var sCall = null;\n var addr = dbgAddr.addr;\n var addrOrig = addr;\n for (var n = 1; n <= 6 && !!addr; n++) {\n if (n > 2) {\n dbgAddr.addr = addr;\n var s = this.getInstruction(dbgAddr);\n if (s.indexOf(\"JSR\") >= 0) {\n /*\n * Verify that the length of this call, when added to the address of the call, matches\n * the original return address. We do this by getting the string index of the opcode bytes,\n * subtracting that from the string index of the next space, and dividing that difference\n * by two, to yield the length of the CALL (or INT) instruction, in bytes.\n */\n var i = s.indexOf(' ');\n var j = s.indexOf(' ', i+1);\n if (addr + (j - i - 1)/2 == addrOrig) {\n sCall = s;\n break;\n }\n }\n }\n addr -= 2;\n }\n dbgAddr.addr = addrOrig;\n return sCall;\n }\n\n /**\n * doStackTrace(sCmd, sAddr)\n *\n * Use \"k\" for a normal stack trace and \"ks\" for a stack trace with symbolic info.\n *\n * @this {DebuggerPDP11}\n * @param {string} [sCmd]\n * @param {string} [sAddr] (not used yet)\n */\n doStackTrace(sCmd, sAddr)\n {\n if (sAddr == '?') {\n this.println(\"stack trace commands:\");\n this.println(\"\\tk\\tshow frame addresses\");\n this.println(\"\\tks\\tshow symbol information\");\n return;\n }\n\n var nFrames = 10, cFrames = 0;\n var dbgAddrCall = this.newAddr();\n var dbgAddrStack = this.newAddr(this.cpu.getSP());\n this.println(\"stack trace for \" + this.toStrAddr(dbgAddrStack));\n\n while (cFrames < nFrames) {\n var sCall = null, sCallPrev = null, cTests = 256;\n while ((dbgAddrStack.addr >>> 0) < 0x10000) {\n dbgAddrCall.addr = this.getWord(dbgAddrStack, 2);\n /*\n * Because we're using the auto-increment feature of getWord(), and because that will automatically\n * wrap the offset around the end of the segment, we must also check the addr property to detect the wrap.\n */\n if (dbgAddrStack.addr == null || !cTests--) break;\n if (dbgAddrCall.addr & 0x1) continue; // an odd address on the PDP-11 is not a valid instruction boundary\n sCall = this.getCall(dbgAddrCall);\n if (sCall) break;\n }\n /*\n * The sCallPrev check eliminates duplicate sequential calls, which are usually (but not always)\n * indicative of a false positive, in which case the previous call is probably bogus as well, but\n * at least we won't duplicate that mistake. Of course, there are always exceptions, recursion\n * being one of them, but it's rare that we're debugging recursive code.\n */\n if (!sCall || sCall == sCallPrev) break;\n var sSymbol = null;\n if (sCmd == \"ks\") {\n var a = sCall.match(/[0-9A-F]+$/);\n if (a) sSymbol = this.doList(a[0]);\n }\n sCall = Str.pad(sCall, 50) + \" ;\" + (sSymbol || \"stack=\" + this.toStrAddr(dbgAddrStack)); // + \" return=\" + this.toStrAddr(dbgAddrCall));\n this.println(sCall);\n sCallPrev = sCall;\n cFrames++;\n }\n if (!cFrames) this.println(\"no return addresses found\");\n }\n\n /**\n * doTrace(sCmd, sCount)\n *\n * The \"t\" and \"tr\" commands interpret the count as a number of instructions, and since\n * we call the Debugger's stepCPU() for each iteration, a single instruction includes\n * any/all prefixes; the CPU's stepCPU() treats prefixes as discrete operations. The only\n * difference between \"t\" and \"tr\": the former displays only the next instruction, while\n * the latter also displays the (updated) registers.\n *\n * The \"tc\" command interprets the count as a number of cycles rather than instructions,\n * allowing you to quickly execute large chunks of instructions with a single command; it\n * doesn't display anything until the the chunk has finished. \"tc 1\" is also a useful\n * command in that it doesn't inhibit interrupts like \"t\" or \"tr\" does.\n *\n * However, generally a more useful command is \"bn\", which allows you to break after some\n * number of instructions have been executed (as opposed to some number of cycles).\n *\n * @this {DebuggerPDP11}\n * @param {string} [sCmd] (\"t\", \"tc\", or \"tr\")\n * @param {string} [sCount] # of instructions to step\n */\n doTrace(sCmd, sCount)\n {\n if (sCount == '?') {\n this.println(\"trace commands:\");\n this.println(\"\\tt [#]\\ttrace # instructions\");\n this.println(\"\\ttr [#]\\ttrace # instructions with register updates\");\n this.println(\"\\ttc [#]\\ttrace # cycles\");\n this.println(\"note: bn [#] breaks after # instructions without updates\");\n return;\n }\n\n var dbg = this;\n var fRegs = (sCmd != \"t\");\n var nCount = this.parseValue(sCount, null, true) || 1;\n\n /*\n * We used to set nCycles to 1 when a count > 1 was specified, because nCycles set\n * to 0 used to mean \"execute the next instruction without checking for interrupts\".\n * Well, this machine's stepCPU() doesn't do that; it ALWAYS checks for interrupts,\n * so we should leave nCycles set to 0, so that if an interrupt is dispatched, we will\n * get to see the first instruction of the interrupt handler.\n */\n var nCycles = 0; // (nCount == 1? 0 : 1);\n\n if (sCmd == \"tc\") {\n nCycles = nCount;\n nCount = 1;\n }\n this.sCmdTracePrev = sCmd;\n\n Web.onCountRepeat(\n nCount,\n function onCountStep() {\n return dbg.setBusy(true) && dbg.stepCPU(nCycles, fRegs, false);\n },\n function onCountStepComplete() {\n /*\n * We explicitly called stepCPU() with fUpdateDisplays set to false, because repeatedly\n * calling updateDisplays() can be very slow, especially if a Control Panel is present with\n * displayLiveRegs enabled, so once the repeat count has been exhausted, we must perform\n * a final updateDisplays().\n */\n if (dbg.panel) dbg.panel.stop();\n dbg.cmp.updateDisplays(-1);\n dbg.setBusy(false);\n }\n );\n }\n\n /**\n * doUnassemble(sAddr, sAddrEnd, nLines)\n *\n * @this {DebuggerPDP11}\n * @param {string} [sAddr]\n * @param {string} [sAddrEnd]\n * @param {number} [nLines]\n */\n doUnassemble(sAddr, sAddrEnd, nLines)\n {\n var dbgAddr = this.parseAddr(sAddr, true);\n if (!dbgAddr) return;\n\n if (nLines === undefined) nLines = 1;\n\n var nBytes = 0x100;\n if (sAddrEnd !== undefined) {\n\n if (sAddrEnd.charAt(0) == 'l') {\n var n = this.parseValue(sAddrEnd.substr(1));\n if (n != null) nLines = n;\n }\n else {\n var dbgAddrEnd = this.parseAddr(sAddrEnd, true);\n if (!dbgAddrEnd || dbgAddrEnd.addr < dbgAddr.addr) return;\n\n nBytes = dbgAddrEnd.addr - dbgAddr.addr;\n if (!DEBUG && nBytes > 0x100) {\n /*\n * Limiting the amount of disassembled code to 256 bytes in non-DEBUG builds is partly to\n * prevent the user from wedging the browser by dumping too many lines, but also a recognition\n * that, in non-DEBUG builds, this.println() keeps print output buffer truncated to 8Kb anyway.\n */\n this.println(\"range too large\");\n return;\n }\n nLines = -1;\n }\n }\n\n var nPrinted = 0;\n var sInstruction;\n\n while (nBytes > 0 && nLines--) {\n\n var nSequence = (this.isBusy(false) || this.nStep)? this.nCycles : null;\n var sComment = (nSequence != null? \"cycles\" : null);\n var aSymbol = this.findSymbol(dbgAddr);\n\n var addr = dbgAddr.addr; // we snap dbgAddr.addr *after* calling findSymbol(), which re-evaluates it\n\n if (aSymbol[0] && nLines) {\n if (!nPrinted && nLines || aSymbol[0].indexOf('+') < 0) {\n var sLabel = aSymbol[0] + ':';\n if (aSymbol[2]) sLabel += ' ' + aSymbol[2];\n this.println(sLabel);\n }\n }\n\n if (aSymbol[3]) {\n sComment = aSymbol[3];\n nSequence = null;\n }\n\n sInstruction = this.getInstruction(dbgAddr, sComment, nSequence);\n\n this.println(sInstruction);\n this.dbgAddrNextCode = dbgAddr;\n nBytes -= dbgAddr.addr - addr;\n nPrinted++;\n }\n }\n\n /**\n * splitArgs(sCmd)\n *\n * @this {DebuggerPDP11}\n * @param {string} sCmd\n * @return {Array.<string>}\n */\n splitArgs(sCmd)\n {\n var asArgs = sCmd.replace(/ +/g, ' ').split(' ');\n asArgs[0] = asArgs[0].toLowerCase();\n if (asArgs && asArgs.length) {\n var s0 = asArgs[0];\n var ch0 = s0.charAt(0);\n for (var i = 1; i < s0.length; i++) {\n var ch = s0.charAt(i);\n if (ch0 == '?' || ch0 == 'r' || ch < 'a' || ch > 'z') {\n asArgs[0] = s0.substr(i);\n asArgs.unshift(s0.substr(0, i));\n break;\n }\n }\n }\n return asArgs;\n }\n\n /**\n * doCommand(sCmd, fQuiet)\n *\n * @this {DebuggerPDP11}\n * @param {string} sCmd\n * @param {boolean} [fQuiet]\n * @return {boolean} true if command processed, false if unrecognized\n */\n doCommand(sCmd, fQuiet)\n {\n var result = true;\n\n try {\n if (!sCmd.length || sCmd == \"end\") {\n if (this.fAssemble) {\n this.println(\"ended assemble at \" + this.toStrAddr(this.dbgAddrAssemble));\n this.dbgAddrNextCode = this.dbgAddrAssemble;\n this.fAssemble = false;\n }\n sCmd = \"\";\n }\n else if (!fQuiet) {\n this.println(DebuggerPDP11.PROMPT + sCmd);\n }\n\n var ch = sCmd.charAt(0);\n if (ch == '\"' || ch == \"'\") return true;\n\n /*\n * Zap the previous message buffer to ensure the new command's output is not tossed out as a repeat.\n */\n this.sMessagePrev = null;\n\n /*\n * I've relaxed the !isBusy() requirement, to maximize our ability to issue Debugger commands externally.\n */\n if (this.isReady() /* && !this.isBusy(true) */ && sCmd.length > 0) {\n\n if (this.fAssemble) {\n sCmd = \"a \" + this.toStrAddr(this.dbgAddrAssemble) + ' ' + sCmd;\n }\n\n var fError = false;\n var asArgs = this.splitArgs(sCmd);\n\n switch (asArgs[0].charAt(0)) {\n case 'a':\n this.doAssemble(asArgs);\n break;\n case 'b':\n this.doBreak(asArgs[0], asArgs[1], sCmd);\n break;\n case 'c':\n this.doClear(asArgs[0]);\n break;\n case 'd':\n if (!COMPILED && sCmd == \"debug\") {\n window.DEBUG = true;\n this.println(\"DEBUG checks on\");\n break;\n }\n this.doDump(asArgs);\n break;\n case 'e':\n if (asArgs[0] == \"else\") break;\n this.doEdit(asArgs);\n break;\n case 'g':\n this.doRun(asArgs[0], asArgs[1], sCmd, fQuiet);\n break;\n case 'h':\n this.doHalt(fQuiet);\n break;\n case 'i':\n if (asArgs[0] == \"if\") {\n if (!this.doIf(sCmd.substr(2), fQuiet)) {\n result = false;\n }\n break;\n }\n fError = true;\n break;\n case 'k':\n this.doStackTrace(asArgs[0], asArgs[1]);\n break;\n case 'l':\n if (asArgs[0] == \"ln\") {\n this.doList(asArgs[1], true);\n break;\n }\n fError = true;\n break;\n case 'm':\n this.doMessages(asArgs);\n break;\n case 'p':\n if (asArgs[0] == \"print\") {\n this.doPrint(sCmd.substr(5));\n break;\n }\n this.doStep(asArgs[0], asArgs[1]);\n break;\n case 'r':\n if (sCmd == \"reset\") {\n if (this.cmp) this.cmp.reset();\n break;\n }\n this.doRegisters(asArgs);\n break;\n case 's':\n this.doOptions(asArgs);\n break;\n case 't':\n this.doTrace(asArgs[0], asArgs[1]);\n break;\n case 'u':\n this.doUnassemble(asArgs[1], asArgs[2], 8);\n break;\n case 'v':\n if (asArgs[0] == \"var\") {\n if (!this.doVar(sCmd.substr(3))) {\n result = false;\n }\n break;\n }\n if (asArgs[0] == \"ver\") {\n 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\")) + ')');\n this.println(Web.getUserAgent());\n break;\n }\n fError = true;\n break;\n case '?':\n if (asArgs[1]) {\n this.doPrint(sCmd.substr(1));\n break;\n }\n this.doHelp();\n break;\n case 'n':\n if (!COMPILED && sCmd == \"nodebug\") {\n window.DEBUG = false;\n this.println(\"DEBUG checks off\");\n break;\n }\n if (this.doInfo(asArgs)) break;\n /* falls through */\n default:\n fError = true;\n break;\n }\n if (fError) {\n this.println(\"unknown command: \" + sCmd);\n result = false;\n }\n }\n } catch(e) {\n this.println(\"debugger error: \" + (e.stack || e.message));\n result = false;\n }\n return result;\n }\n\n /**\n * doCommands(sCmds, fSave)\n *\n * @this {DebuggerPDP11}\n * @param {string} sCmds\n * @param {boolean} [fSave]\n * @return {boolean} true if all commands processed, false if not\n */\n doCommands(sCmds, fSave)\n {\n var a = this.parseCommand(sCmds, fSave);\n for (var s in a) {\n if (!this.doCommand(a[+s])) return false;\n }\n return true;\n }\n\n /**\n * DebuggerPDP11.init()\n *\n * This function operates on every HTML element of class \"debugger\", extracting the\n * JSON-encoded parameters for the Debugger constructor from the element's \"data-value\"\n * attribute, invoking the constructor to create a Debugger component, and then binding\n * any associated HTML controls to the new component.\n */\n static init()\n {\n var aeDbg = Component.getElementsByClass(document, PDP11.APPCLASS, \"debugger\");\n for (var iDbg = 0; iDbg < aeDbg.length; iDbg++) {\n var eDbg = aeDbg[iDbg];\n var parmsDbg = Component.getComponentParms(eDbg);\n var dbg = new DebuggerPDP11(parmsDbg);\n Component.bindComponentControls(dbg, eDbg, PDP11.APPCLASS);\n }\n }\n}\n\nif (DEBUGGER) {\n\n /*\n * NOTE: Every DebuggerPDP11 property from here to the first prototype function definition (initBus()) is\n * considered a \"class constant\"; most of them use our \"all-caps\" convention (and all of them SHOULD, but\n * that wouldn't help us catch any bugs).\n *\n * Technically, all of them should ALSO be preceded by a \"@const\" annotation, but that's a lot of work and it\n * really clutters the code. I wish the Closure Compiler had a way to annotate every definition with a given\n * section with a single annotation....\n */\n\n DebuggerPDP11.COMMANDS = {\n '?': \"help/print\",\n 'a [#]': \"assemble\", // TODO: Implement this command someday\n 'b [#]': \"breakpoint\", // multiple variations (use b? to list them)\n 'c': \"clear output\",\n 'd [#]': \"dump memory\", // additional syntax: d [#] [l#], where l# is a number of bytes to dump\n 'e [#]': \"edit memory\",\n 'g [#]': \"go [to #]\",\n 'h': \"halt\",\n 'if': \"eval expression\",\n 'int [#]': \"request interrupt\",\n 'k': \"stack trace\",\n \"ln\": \"list nearest symbol(s)\",\n 'm': \"messages\",\n 'p': \"step over\", // other variations: pr (step and dump registers)\n 'print': \"print expression\",\n 'r': \"dump/set registers\",\n 'reset': \"reset machine\",\n 's': \"set options\",\n 't [#]': \"trace\", // other variations: tr (trace and dump registers)\n 'u [#]': \"unassemble\",\n 'var': \"assign variable\",\n 'ver': \"print version\"\n };\n\n /*\n * CPU opcode IDs\n *\n * Not listed: BLO (same as BCS) and BHIS (same as BCC).\n */\n DebuggerPDP11.OPS = {\n NONE: 0, ADC: 1, ADCB: 2, ADD: 3, ASL: 4, ASLB: 5, ASR: 6, ASRB: 7,\n BCC: 8, BCS: 9, BEQ: 10, BGE: 11, BGT: 12, BHI: 13, BIC: 14, BICB: 15,\n BIS: 16, BISB: 17, BIT: 18, BITB: 19, BLE: 20, BLOS: 21, BLT: 22, BMI: 23,\n BNE: 24, BPL: 25, BPT: 26, BR: 27, BVC: 28, BVS: 29, CCC: 30, CLC: 31,\n CLCN: 32, CLCV: 33, CLCVN: 34, CLCVZ: 35, CLCZ: 36, CLCZN: 37, CLN: 38, CLR: 39,\n CLRB: 40, CLV: 41, CLVN: 42, CLVZ: 43, CLVZN: 44, CLZ: 45, CLZN: 46, CMP: 47,\n CMPB: 48, COM: 49, COMB: 50, DEC: 51, DECB: 52, INC: 53, INCB: 54, HALT: 55,\n JMP: 56, JSR: 57, MARK: 58, MFPD: 59, MFPI: 60, MFPS: 61, MOV: 62, MOVB: 63,\n MTPD: 64, MTPI: 65, MTPS: 66, NEG: 67, NEGB: 68, NOP: 69, RESET: 70, ROL: 71,\n ROLB: 72, ROR: 73, RORB: 74, RTI: 75, RTS: 76, SBC: 77, SBCB: 78, SCC: 79,\n SEC: 80, SECN: 81, SECV: 82, SECVN: 83, SECVZ: 84, SECZ: 85, SECZN: 86, SEN: 87,\n SEV: 88, SEVN: 89, SEVZ: 90, SEVZN: 91, SEZ: 92, SEZN: 93, SUB: 94, SWAB: 95,\n SXT: 96, TST: 97, TSTB: 98, WAIT: 99, MUL: 100, DIV: 101, ASH: 102, ASHC: 103,\n XOR: 104, SOB: 105, EMT: 106, TRAP: 107, SPL: 108, IOT: 109, RTT: 110, MFPT: 111\n };\n\n /*\n * CPU opcode names, indexed by CPU opcode ordinal (above)\n */\n DebuggerPDP11.OPNAMES = [\n \".WORD\", \"ADC\", \"ADCB\", \"ADD\", \"ASL\", \"ASLB\", \"ASR\", \"ASRB\",\n \"BCC\", \"BCS\", \"BEQ\", \"BGE\", \"BGT\", \"BHI\", \"BIC\", \"BICB\",\n \"BIS\", \"BISB\", \"BIT\", \"BITB\", \"BLE\", \"BLOS\", \"BLT\", \"BMI\",\n \"BNE\", \"BPL\", \"BPT\", \"BR\", \"BVC\", \"BVS\", \"CCC\", \"CLC\",\n \"CLCN\", \"CLCV\", \"CLCVN\", \"CLCVZ\", \"CLCZ\", \"CLCZN\", \"CLN\", \"CLR\",\n \"CLRB\", \"CLV\", \"CLVN\", \"CLVZ\", \"CLVZN\", \"CLZ\", \"CLZN\", \"CMP\",\n \"CMPB\", \"COM\", \"COMB\", \"DEC\", \"DECB\", \"INC\", \"INCB\", \"HALT\",\n \"JMP\", \"JSR\", \"MARK\", \"MFPD\", \"MFPI\", \"MFPS\", \"MOV\", \"MOVB\",\n \"MTPD\", \"MTPI\", \"MTPS\", \"NEG\", \"NEGB\", \"NOP\", \"RESET\", \"ROL\",\n \"ROLB\", \"ROR\", \"RORB\", \"RTI\", \"RTS\", \"SBC\", \"SBCB\", \"SCC\",\n \"SEC\", \"SECN\", \"SECV\", \"SECVN\", \"SECVZ\", \"SECZ\", \"SECZN\", \"SEN\",\n \"SEV\", \"SEVN\", \"SEVZ\", \"SEVZN\", \"SEZ\", \"SEZN\", \"SUB\", \"SWAB\",\n \"SXT\", \"TST\", \"TSTB\", \"WAIT\", \"MUL\", \"DIV\", \"ASH\", \"ASHC\",\n \"XOR\", \"SOB\", \"EMT\", \"TRAP\", \"SPL\", \"IOT\", \"RTT\", \"MFPT\"\n ];\n\n /*\n * Register numbers 0-7 are reserved for cpu.regsGen, 8-15 are reserved for cpu.regsAlt, and 16-19 for cpu.regsStack.\n */\n DebuggerPDP11.REG_PS = 20;\n DebuggerPDP11.REG_PI = 21;\n DebuggerPDP11.REG_ER = 22;\n DebuggerPDP11.REG_SL = 23;\n DebuggerPDP11.REG_M0 = 24;\n DebuggerPDP11.REG_M1 = 25;\n DebuggerPDP11.REG_M2 = 26;\n DebuggerPDP11.REG_M3 = 27;\n DebuggerPDP11.REG_AR = 28; // ADDRESS register; see Panel's getAR() and setAR()\n DebuggerPDP11.REG_DR = 29; // DISPLAY/DATA register; see Panel's getDR() and setDR()\n DebuggerPDP11.REG_SR = 30; // SWITCH register; see Panel's getSR() and setSR()\n\n DebuggerPDP11.REGS = {\n \"SP\": 6,\n \"PC\": 7,\n \"PS\": DebuggerPDP11.REG_PS,\n \"PI\": DebuggerPDP11.REG_PI,\n \"ER\": DebuggerPDP11.REG_ER,\n \"SL\": DebuggerPDP11.REG_SL,\n \"M0\": DebuggerPDP11.REG_M0,\n \"M1\": DebuggerPDP11.REG_M1,\n \"M2\": DebuggerPDP11.REG_M2,\n \"M3\": DebuggerPDP11.REG_M3,\n \"AR\": DebuggerPDP11.REG_AR,\n \"DR\": DebuggerPDP11.REG_DR,\n \"SR\": DebuggerPDP11.REG_SR\n };\n\n DebuggerPDP11.REGNAMES = [\n \"R0\", \"R1\", \"R2\", \"R3\", \"R4\", \"R5\", \"SP\", \"PC\",\n \"A0\", \"A1\", \"A2\", \"A3\", \"A4\", \"A5\", \"A6\", \"A7\",\n \"S0\", \"S1\", \"S2\", \"S3\",\n \"PS\", \"PI\", \"ER\", \"SL\", \"M0\", \"M1\", \"M2\", \"M3\",\n \"AR\", \"DR\", \"SR\"\n ];\n\n DebuggerPDP11.MODES = [\"KI\",\"KD\",\"SI\",\"SD\",\"??\",\"??\",\"UI\",\"UD\"];\n\n /*\n * Operand type masks; anything that's not covered by OP_SRC or OP_DST must be a OP_OTHER value.\n */\n DebuggerPDP11.OP_DSTREG = PDP11.OPREG.MASK;\n DebuggerPDP11.OP_DSTMODE = PDP11.OPMODE.MASK;\n DebuggerPDP11.OP_DST = (DebuggerPDP11.OP_DSTMODE | DebuggerPDP11.OP_DSTREG);\n DebuggerPDP11.OP_SRCREG = PDP11.OPREG.MASK << 6;\n DebuggerPDP11.OP_SRCMODE = PDP11.OPMODE.MASK << 6;\n DebuggerPDP11.OP_SRC = (DebuggerPDP11.OP_SRCMODE | DebuggerPDP11.OP_SRCREG);\n DebuggerPDP11.OP_BRANCH = 0x1000;\n DebuggerPDP11.OP_DSTOFF = 0x2000;\n DebuggerPDP11.OP_DSTNUM3 = 0x3000; // DST 3-bit number (ie, just the DSTREG field)\n DebuggerPDP11.OP_DSTNUM6 = 0x6000; // DST 6-bit number (ie, both the DSTREG and DSTMODE fields)\n DebuggerPDP11.OP_DSTNUM8 = 0x8000; // DST 8-bit number\n DebuggerPDP11.OP_OTHER = 0xF000;\n\n /*\n * The OPTABLE contains opcode masks, and each mask refers to table of possible values, and each\n * value refers to an array that contains:\n *\n * [0]: {number} of the opcode name (see OP.*)\n * [1]: {number} containing the first operand type bit(s), if any\n * [2]: {number} containing the second operand type bit(s), if any\n *\n * Note that, by convention, opcodes that require two operands list the SRC operand first and DST operand\n * second (ie, the OPPOSITE of the Intel convention).\n *\n * Also note that, for some of the newer PDP-11 opcodes (eg, MUL, DIV, ASH, ASHC), the location of the\n * opcode's SRC and DST bits are reversed. This is why, for example, you'll see the MUL instruction defined\n * below as having OP_DST for the first operand and OP_SRCREG for the second operand. This does NOT mean\n * that the opcode's destination operand is being listed first, but rather that the bits describing the source\n * operand are in the opcode's OP_DST field.\n */\n DebuggerPDP11.OPTABLE = {\n 0xF000: {\n 0x1000: [DebuggerPDP11.OPS.MOV, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 01SSDD\n 0x2000: [DebuggerPDP11.OPS.CMP, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 02SSDD\n 0x3000: [DebuggerPDP11.OPS.BIT, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 03SSDD\n 0x4000: [DebuggerPDP11.OPS.BIC, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 04SSDD\n 0x5000: [DebuggerPDP11.OPS.BIS, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 05SSDD\n 0x6000: [DebuggerPDP11.OPS.ADD, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 06SSDD\n 0x9000: [DebuggerPDP11.OPS.MOVB, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 11SSDD\n 0xA000: [DebuggerPDP11.OPS.CMPB, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 12SSDD\n 0xB000: [DebuggerPDP11.OPS.BITB, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 13SSDD\n 0xC000: [DebuggerPDP11.OPS.BICB, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 14SSDD\n 0xD000: [DebuggerPDP11.OPS.BISB, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST], // 15SSDD\n 0xE000: [DebuggerPDP11.OPS.SUB, DebuggerPDP11.OP_SRC, DebuggerPDP11.OP_DST] // 16SSDD\n },\n 0xFE00: {\n 0x0800: [DebuggerPDP11.OPS.JSR, DebuggerPDP11.OP_SRCREG, DebuggerPDP11.OP_DST], // 004RDD\n 0x7000: [DebuggerPDP11.OPS.MUL, DebuggerPDP11.OP_DST, DebuggerPDP11.OP_SRCREG], // 070RSS\n 0x7200: [DebuggerPDP11.OPS.DIV, DebuggerPDP11.OP_DST, DebuggerPDP11.OP_SRCREG], // 071RSS\n 0x7400: [DebuggerPDP11.OPS.ASH, DebuggerPDP11.OP_DST, DebuggerPDP11.OP_SRCREG], // 072RSS\n 0x7600: [DebuggerPDP11.OPS.ASHC, DebuggerPDP11.OP_DST, DebuggerPDP11.OP_SRCREG], // 073RSS\n 0x7800: [DebuggerPDP11.OPS.XOR, DebuggerPDP11.OP_SRCREG, DebuggerPDP11.OP_DST], // 074RDD\n 0x7E00: [DebuggerPDP11.OPS.SOB, DebuggerPDP11.OP_SRCREG, DebuggerPDP11.OP_DSTOFF] // 077Rnn\n },\n 0xFF00: {\n 0x0100: [DebuggerPDP11.OPS.BR, DebuggerPDP11.OP_BRANCH],\n 0x0200: [DebuggerPDP11.OPS.BNE, DebuggerPDP11.OP_BRANCH],\n 0x0300: [DebuggerPDP11.OPS.BEQ, DebuggerPDP11.OP_BRANCH],\n 0x0400: [DebuggerPDP11.OPS.BGE, DebuggerPDP11.OP_BRANCH],\n 0x0500: [DebuggerPDP11.OPS.BLT, DebuggerPDP11.OP_BRANCH],\n 0x0600: [DebuggerPDP11.OPS.BGT, DebuggerPDP11.OP_BRANCH],\n 0x0700: [DebuggerPDP11.OPS.BLE, DebuggerPDP11.OP_BRANCH],\n 0x8000: [DebuggerPDP11.OPS.BPL, DebuggerPDP11.OP_BRANCH],\n 0x8100: [DebuggerPDP11.OPS.BMI, DebuggerPDP11.OP_BRANCH],\n 0x8200: [DebuggerPDP11.OPS.BHI, DebuggerPDP11.OP_BRANCH],\n 0x8300: [DebuggerPDP11.OPS.BLOS, DebuggerPDP11.OP_BRANCH],\n 0x8400: [DebuggerPDP11.OPS.BVC, DebuggerPDP11.OP_BRANCH],\n 0x8500: [DebuggerPDP11.OPS.BVS, DebuggerPDP11.OP_BRANCH],\n 0x8600: [DebuggerPDP11.OPS.BCC, DebuggerPDP11.OP_BRANCH],\n 0x8700: [DebuggerPDP11.OPS.BCS, DebuggerPDP11.OP_BRANCH],\n 0x8800: [DebuggerPDP11.OPS.EMT, DebuggerPDP11.OP_DSTNUM8], // 104000..104377\n 0x8900: [DebuggerPDP11.OPS.TRAP, DebuggerPDP11.OP_DSTNUM8] // 104400..104777\n },\n 0xFFC0: {\n 0x0040: [DebuggerPDP11.OPS.JMP, DebuggerPDP11.OP_DST], // 0001DD\n 0x00C0: [DebuggerPDP11.OPS.SWAB, DebuggerPDP11.OP_DST], // 0003DD\n 0x0A00: [DebuggerPDP11.OPS.CLR, DebuggerPDP11.OP_DST], // 0050DD\n 0x0A40: [DebuggerPDP11.OPS.COM, DebuggerPDP11.OP_DST], // 0051DD\n 0x0A80: [DebuggerPDP11.OPS.INC, DebuggerPDP11.OP_DST], // 0052DD\n 0x0AC0: [DebuggerPDP11.OPS.DEC, DebuggerPDP11.OP_DST], // 0053DD\n 0x0B00: [DebuggerPDP11.OPS.NEG, DebuggerPDP11.OP_DST], // 0054DD\n 0x0B40: [DebuggerPDP11.OPS.ADC, DebuggerPDP11.OP_DST], // 0055DD\n 0x0B80: [DebuggerPDP11.OPS.SBC, DebuggerPDP11.OP_DST], // 0056DD\n 0x0BC0: [DebuggerPDP11.OPS.TST, DebuggerPDP11.OP_DST], // 0057DD\n 0x0C00: [DebuggerPDP11.OPS.ROR, DebuggerPDP11.OP_DST], // 0060DD\n 0x0C40: [DebuggerPDP11.OPS.ROL, DebuggerPDP11.OP_DST], // 0061DD\n 0x0C80: [DebuggerPDP11.OPS.ASR, DebuggerPDP11.OP_DST], // 0062DD\n 0x0CC0: [DebuggerPDP11.OPS.ASL, DebuggerPDP11.OP_DST], // 0063DD\n 0x0D00: [DebuggerPDP11.OPS.MARK, DebuggerPDP11.OP_DSTNUM6], // 0064nn\n 0x0D40: [DebuggerPDP11.OPS.MFPI, DebuggerPDP11.OP_DST], // 0065SS\n 0x0D80: [DebuggerPDP11.OPS.MTPI, DebuggerPDP11.OP_DST], // 0066DD\n 0x0DC0: [DebuggerPDP11.OPS.SXT, DebuggerPDP11.OP_DST], // 0067DD\n 0x8A00: [DebuggerPDP11.OPS.CLRB, DebuggerPDP11.OP_DST], // 1050DD\n 0x8A40: [DebuggerPDP11.OPS.COMB, DebuggerPDP11.OP_DST], // 1051DD\n 0x8A80: [DebuggerPDP11.OPS.INCB, DebuggerPDP11.OP_DST], // 1052DD\n 0x8AC0: [DebuggerPDP11.OPS.DECB, DebuggerPDP11.OP_DST], // 1053DD\n 0x8B00: [DebuggerPDP11.OPS.NEGB, DebuggerPDP11.OP_DST], // 1054DD\n 0x8B40: [DebuggerPDP11.OPS.ADCB, DebuggerPDP11.OP_DST], // 1055DD\n 0x8B80: [DebuggerPDP11.OPS.SBCB, DebuggerPDP11.OP_DST], // 1056DD\n 0x8BC0: [DebuggerPDP11.OPS.TSTB, DebuggerPDP11.OP_DST], // 1057DD\n 0x8C00: [DebuggerPDP11.OPS.RORB, DebuggerPDP11.OP_DST], // 1060DD\n 0x8C40: [DebuggerPDP11.OPS.ROLB, DebuggerPDP11.OP_DST], // 1061DD\n 0x8C80: [DebuggerPDP11.OPS.ASRB, DebuggerPDP11.OP_DST], // 1062DD\n 0x8CC0: [DebuggerPDP11.OPS.ASLB, DebuggerPDP11.OP_DST], // 1063DD\n 0x8D00: [DebuggerPDP11.OPS.MTPS, DebuggerPDP11.OP_DST], // 1064SS (only on LSI-11)\n 0x8D40: [DebuggerPDP11.OPS.MFPD, DebuggerPDP11.OP_DST], // 1065DD (same as MFPI if no separate instruction/data spaces)\n 0x8D80: [DebuggerPDP11.OPS.MTPD, DebuggerPDP11.OP_DST], // 1066DD (same as MTPI if no separate instruction/data spaces)\n 0x8DC0: [DebuggerPDP11.OPS.MFPS, DebuggerPDP11.OP_DST] // 1067SS (only on LSI-11)\n },\n 0xFFF8: {\n 0x0080: [DebuggerPDP11.OPS.RTS, DebuggerPDP11.OP_DSTREG], // 00020R\n 0x0098: [DebuggerPDP11.OPS.SPL, DebuggerPDP11.OP_DSTNUM3] // 00023N\n },\n 0xFFFF: {\n 0x0000: [DebuggerPDP11.OPS.HALT], // 000000\n 0x0001: [DebuggerPDP11.OPS.WAIT], // 000001\n 0x0002: [DebuggerPDP11.OPS.RTI], // 000002\n 0x0003: [DebuggerPDP11.OPS.BPT], // 000003\n 0x0004: [DebuggerPDP11.OPS.IOT], // 000004\n 0x0005: [DebuggerPDP11.OPS.RESET], // 000005\n 0x0006: [DebuggerPDP11.OPS.RTT], // 000006\n 0x0007: [DebuggerPDP11.OPS.MFPT], // 000007 (only on PDP-11/44 & KB11-EM?)\n 0x00A0: [DebuggerPDP11.OPS.NOP],\n 0x00A1: [DebuggerPDP11.OPS.CLC],\n 0x00A2: [DebuggerPDP11.OPS.CLV],\n 0x00A3: [DebuggerPDP11.OPS.CLCV],\n 0x00A4: [DebuggerPDP11.OPS.CLZ],\n 0x00A5: [DebuggerPDP11.OPS.CLCZ],\n 0x00A6: [DebuggerPDP11.OPS.CLVZ],\n 0x00A7: [DebuggerPDP11.OPS.CLCVZ],\n 0x00A8: [DebuggerPDP11.OPS.CLN],\n 0x00A9: [DebuggerPDP11.OPS.CLCN],\n 0x00AA: [DebuggerPDP11.OPS.CLVN],\n 0x00AB: [DebuggerPDP11.OPS.CLCVN],\n 0x00AC: [DebuggerPDP11.OPS.CLZN],\n 0x00AD: [DebuggerPDP11.OPS.CLCZN],\n 0x00AE: [DebuggerPDP11.OPS.CLVZN],\n 0x00AF: [DebuggerPDP11.OPS.CCC], // aka CLCVZN\n 0x00B0: [DebuggerPDP11.OPS.NOP],\n 0x00B1: [DebuggerPDP11.OPS.SEC],\n 0x00B2: [DebuggerPDP11.OPS.SEV],\n 0x00B3: [DebuggerPDP11.OPS.SECV],\n 0x00B4: [DebuggerPDP11.OPS.SEZ],\n 0x00B5: [DebuggerPDP11.OPS.SECZ],\n 0x00B6: [DebuggerPDP11.OPS.SEVZ],\n 0x00B7: [DebuggerPDP11.OPS.SECVZ],\n 0x00B8: [DebuggerPDP11.OPS.SEN],\n 0x00B9: [DebuggerPDP11.OPS.SECN],\n 0x00BA: [DebuggerPDP11.OPS.SEVN],\n 0x00BB: [DebuggerPDP11.OPS.SECVN],\n 0x00BC: [DebuggerPDP11.OPS.SEZN],\n 0x00BD: [DebuggerPDP11.OPS.SECZN],\n 0x00BE: [DebuggerPDP11.OPS.SEVZN],\n 0x00BF: [DebuggerPDP11.OPS.SCC] // aka SECVZN\n }\n };\n\n DebuggerPDP11.OPNONE = [DebuggerPDP11.OPS.NONE];\n\n /*\n * Table of opcodes added to the 11/40 and newer\n */\n DebuggerPDP11.OP1140 = [\n DebuggerPDP11.OPS.MARK,\n DebuggerPDP11.OPS.MFPI,\n DebuggerPDP11.OPS.MTPI,\n DebuggerPDP11.OPS.SXT,\n DebuggerPDP11.OPS.RTT,\n DebuggerPDP11.OPS.MUL,\n DebuggerPDP11.OPS.DIV,\n DebuggerPDP11.OPS.ASH,\n DebuggerPDP11.OPS.ASHC,\n DebuggerPDP11.OPS.XOR,\n DebuggerPDP11.OPS.SOB\n ];\n\n /*\n * Table of opcodes added to the 11/45 and newer\n */\n DebuggerPDP11.OP1145 = [\n DebuggerPDP11.OPS.SPL,\n DebuggerPDP11.OPS.MFPD,\n DebuggerPDP11.OPS.MTPD\n ];\n\n DebuggerPDP11.HISTORY_LIMIT = DEBUG? 100000 : 1000;\n\n DebuggerPDP11.PROMPT = \">> \";\n\n /*\n * Initialize every Debugger module on the page (as IF there's ever going to be more than one ;-))\n */\n Web.onInit(DebuggerPDP11.init);\n\n} // endif DEBUGGER\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/pdp11/lib/computer.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass ComputerPDP11 extends Component {\n /**\n * ComputerPDP11(parmsComputer, parmsMachine, fSuspended)\n *\n * The ComputerPDP11 component has no required (parmsComputer) properties, but it does\n * support the following:\n *\n * autoPower: true to automatically power the computer (default), false to wait;\n * false is honored only if a \"power\" button binding exists.\n *\n * busWidth: number of memory address lines (address bits) on the computer's \"bus\";\n * 20 is the minimum (and the default), which implies 8086/8088 real-mode addressing,\n * while 24 is required for 80286 protected-mode addressing. This value is passed\n * directly through to the Bus component; see that component for more details.\n *\n * resume: one of the ComputerPDP11.RESUME constants, which are as follows:\n * '0' if resume disabled (default)\n * '1' if enabled without prompting\n * '2' if enabled with prompting\n * '3' if enabled with prompting and auto-delete\n * or a string containing the path of a predefined JSON-encoded state\n *\n * state: the path to JSON-encoded state file (see details regarding 'state' below)\n *\n * The parmsMachine object, if provided, may contain any of:\n *\n * autoMount: if set, this should override any 'autoMount' property in the FDC's\n * parmsFDC object.\n *\n * autoPower: if set, this should override any 'autoPower' property in the ComputerPDP11's\n * parmsComputer object.\n *\n * messages: if set, this should override any 'messages' property in the Debugger's\n * parmsDbg object.\n *\n * state: if set, this should override any 'state' property in the ComputerPDP11's\n * parmsComputer object.\n *\n * url: the location of the machine XML file\n *\n * If a predefined state is supplied AND it's successfully loaded, then resume behavior\n * defaults to '1' (ie, resume enabled without prompting).\n *\n * This component insures that all components are ready before \"powering\" them.\n *\n * Different components become ready at different times, and initialization order (ie,\n * the order the scripts are combined on the page) only partially determines readiness.\n * This is because components like ROM and Video must finish loading their resource files\n * before they are ready. Other components become ready after we call their initBus()\n * function, because they have a Bus or CPU dependency, such as access to memory management\n * functions. And other components, like CPU and Panel, are ready as soon as their\n * constructor finishes.\n *\n * Once a component has indicated it's ready, we call its powerUp() notification\n * function (if it has one--it's optional). We call the CPU's powerUp() function last,\n * so that the CPU is assured that all other components are ready and \"powered\".\n *\n * @this {ComputerPDP11}\n * @param {Object} parmsComputer\n * @param {Object} [parmsMachine]\n * @param {boolean} [fSuspended]\n */\n constructor(parmsComputer, parmsMachine, fSuspended)\n {\n super(\"Computer\", parmsComputer, MessagesPDP11.COMPUTER);\n\n this.flags.powered = false;\n\n this.parmsMachine = null;\n this.setMachineParms(parmsMachine);\n\n this.fAutoPower = this.getMachineParm('autoPower', parmsComputer, Str.TYPES.BOOLEAN);\n\n /*\n * nPowerChange is 0 while the power state is stable, 1 while power is transitioning\n * to \"on\", and -1 while power is transitioning to \"off\".\n */\n this.nPowerChange = 0;\n\n /*\n * TODO: Deprecate 'buswidth' (it should have always used camelCase)\n */\n this.nBusWidth = +parmsComputer['busWidth'] || +parmsComputer['buswidth'];\n\n this.sResumePath = this.sStatePath = null;\n this.sStateData = null;\n this.fStateData = false; // remembers if sStateData was loaded\n this.fServerState = false;\n this.stateComputer = this.stateFailSafe = null;\n this.fInitialized = this.fReload = this.fRestoreError = false;\n\n this.url = /** @type {string} */ (this.getMachineParm('url') || \"\");\n\n /*\n * Generate a random number x (where 0 <= x < 1), add 0.1 so that it's guaranteed to be\n * non-zero, convert to base 36, and chop off the leading digit and \"decimal\" point.\n */\n this.sMachineID = (Math.random() + 0.1).toString(36).substr(2,12);\n this.sUserID = this.queryUserID();\n\n /*\n * Find the appropriate CPU (and Debugger and Control Panel, if any).\n *\n * CLOSURE COMPILER TIP: To override the type of a right-hand expression (as we need to do here,\n * where we know getComponentByType() will only return an CPUState object or null), wrap the expression\n * in parentheses. I never knew this until I stumbled across it in \"Closure: The Definitive Guide\".\n */\n this.cpu = /** @type {CPUStatePDP11} */ (Component.getComponentByType(\"CPU\", this.id));\n if (!this.cpu) {\n Component.error(\"Unable to find CPU component\");\n return;\n }\n this.dbg = /** @type {DebuggerPDP11} */ (Component.getComponentByType(\"Debugger\", this.id));\n\n /*\n * Initialize the Bus component\n */\n this.bus = new BusPDP11({'id': this.idMachine + '.bus', 'busWidth': this.nBusWidth}, this.cpu, this.dbg);\n\n /*\n * Iterate through all the components and connect them to the Control Panel, if any\n */\n var iComponent, component;\n var aComponents = Component.getComponents(this.id);\n\n this.panel = /** @type {PanelPDP11} */ (Component.getComponentByType(\"Panel\", this.id));\n this.controlPrint = this.panel && this.panel.bindings['print'];\n\n if (this.controlPrint) {\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n /*\n * I can think of many \"cleaner\" ways for the Control Panel component to pass its\n * notice(), println(), etc, overrides on to all the other components, but it's just\n * too darn convenient to slam those overrides into the components directly.\n */\n component.notice = this.panel.notice;\n component.print = this.panel.print;\n component.println = this.panel.println;\n }\n }\n\n this.println(PDP11.APPNAME + \" v\" + PDP11.APPVERSION + \"\\n\" + COPYRIGHT + \"\\n\" + LICENSE);\n\n this.println(\"Portions adapted from the PDP-11/70 Emulator by Paul Nankervis <http://skn.noip.me/pdp11/pdp11.html>\");\n\n if (DEBUG && this.messageEnabled()) this.printMessage(\"TYPEDARRAYS: \" + TYPEDARRAYS);\n\n /*\n * Iterate through all the components again and call their initBus() handler, if any\n */\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component.initBus) component.initBus(this, this.bus, this.cpu, this.dbg);\n }\n\n var sStatePath = null;\n var sResume = /** @type {string} */ (this.getMachineParm('resume', parmsComputer));\n if (sResume !== undefined) {\n /*\n * Decide whether the 'resume' property is a number or the path of a state file to resume.\n */\n if (sResume.length > 1) {\n sStatePath = this.sResumePath = sResume;\n } else {\n this.resume = parseInt(sResume, 10);\n }\n }\n\n /*\n * The Computer 'state' property allows a state file to be specified independent of the 'resume' feature;\n * previously, you could only use 'resume' to load a state file -- which we still support, but loading a state\n * file that way prevents the machine's state from being saved, since we always resume from the 'resume' file.\n *\n * The other wrinkle is on the restore side: we need to IGNORE the 'state' property if a saved state now exists.\n * So we have to peek at localStorage, and unfortunately, the only way to \"peek\" is to actually load the data,\n * but we're not ready to use it yet, so powerUp() has been changed to use any existing stateComputer that we've\n * already loaded.\n *\n * However, there's now a wrinkle to the wrinkle: if a 'state' parameter has been passed via the URL, then that\n * OVERRIDES everything; it overrides any 'state' Computer parameter AND it disables resume of any saved state in\n * localStorage (in other words, it prevents fAllowResume from being true, and forcing resume off).\n */\n var fAllowResume;\n var sState = this.getMachineParm('state') || (fAllowResume = true) && parmsComputer['state'];\n\n if (sState) {\n this.sStatePath = sStatePath = sState;\n if (!fAllowResume) {\n this.fServerState = true;\n this.resume = ComputerPDP11.RESUME_NONE;\n }\n if (this.resume) {\n this.stateComputer = new State(this, PDP11.APPVERSION);\n if (this.stateComputer.load()) {\n sStatePath = null;\n } else {\n delete this.stateComputer;\n }\n }\n }\n\n /*\n * If sStatePath is set, we must use it. But if there's no sStatePath AND resume is set,\n * then we have the option of resuming from a server-side state, assuming a valid USERID.\n */\n if (!sStatePath && this.resume) {\n sStatePath = this.getServerStatePath();\n if (sStatePath) this.fServerState = true;\n }\n\n if (!sStatePath) {\n this.setReady();\n } else {\n var cmp = this;\n Web.getResource(sStatePath, null, true, function doneStateLoad(sURL, sResource, nErrorCode) {\n cmp.finishStateLoad(sURL, sResource, nErrorCode);\n });\n }\n\n if (!this.bindings[\"power\"]) this.fAutoPower = true;\n\n /*\n * Power on the computer, giving every component the opportunity to reset or restore itself.\n */\n if (!fSuspended && this.fAutoPower) this.wait(this.powerOn);\n }\n\n /**\n * clearPanel()\n *\n * @this {ComputerPDP11}\n */\n clearPanel()\n {\n if (this.controlPrint) {\n this.controlPrint.value = \"\";\n }\n }\n\n /**\n * getMachineID()\n *\n * @this {ComputerPDP11}\n * @return {string}\n */\n getMachineID()\n {\n return this.sMachineID;\n }\n\n /**\n * setMachineParms(parmsMachine)\n *\n * If no explicit machine parms were provided, then we check for 'parms' in the bundled resources (if any).\n *\n * @this {ComputerPDP11}\n * @param {Object} [parmsMachine]\n */\n setMachineParms(parmsMachine)\n {\n if (!parmsMachine) {\n var sParms;\n if (typeof resources == 'object' && (sParms = resources['parms'])) {\n try {\n parmsMachine = /** @type {Object} */ (eval(\"(\" + sParms + \")\"));\n } catch(e) {\n Component.error(e.message + \" (\" + sParms + \")\");\n }\n }\n }\n this.parmsMachine = parmsMachine;\n }\n\n /**\n * getMachineParm(sParm, parmsComponent, type, defaultValue)\n *\n * If the machine parameter doesn't exist, we check for a matching component parameter\n * (if parmsComponent is provided), and failing that, we check the bundled resources (if any).\n *\n * At the moment, the only bundled resource request we expect to encounter is 'state'; if it exists,\n * then we return 'state' back to the caller (ie, the name of the resource), so that the caller will\n * then attempt to load the 'state' resource to obtain the actual state.\n *\n * TODO: It would be nice if we could tell the Closure Compiler that when a specific type parameter\n * (eg, Str.TYPES.NUMBER) is used, the return value will be that type; unfortunately, every caller\n * must coerce their own return value.\n *\n * @this {ComputerPDP11}\n * @param {string} sParm\n * @param {Object|null} [parmsComponent]\n * @param {number} [type] (from Str.TYPES)\n * @param {*} [defaultValue]\n * @return {*}\n */\n getMachineParm(sParm, parmsComponent, type, defaultValue)\n {\n /*\n * When checking parmsURL, the check is allowed be a bit looser, because URL parameters are\n * user-supplied, whereas most other parameters are developer-supplied. Granted, a developer\n * may also be sloppy and neglect to use correct case (eg, 'automount' instead of 'autoMount'),\n * but there are limits to my paranoia.\n */\n var sParmLC = sParm.toLowerCase();\n var value = Web.getURLParm(sParm) || Web.getURLParm(sParmLC);\n if (value === undefined && this.parmsMachine) value = this.parmsMachine[sParm];\n if (value === undefined && parmsComponent) value = parmsComponent[sParm];\n if (value === undefined && typeof resources == 'object' && resources[sParm]) value = sParm;\n if (value === undefined) value = defaultValue;\n if (typeof value == \"string\" && type) {\n switch(type) {\n case Str.TYPES.NUMBER:\n value = +value;\n if (isNaN(/** @type {number} */(value))) value = defaultValue || 0;\n break;\n case Str.TYPES.BOOLEAN:\n value = (value == \"true\");\n break;\n }\n }\n return value;\n }\n\n /**\n * saveMachineParms()\n *\n * @this {ComputerPDP11}\n * @return {string|null}\n */\n saveMachineParms()\n {\n return this.parmsMachine? JSON.stringify(this.parmsMachine) : null;\n }\n\n /**\n * getUserID()\n *\n * @this {ComputerPDP11}\n * @return {string}\n */\n getUserID()\n {\n return this.sUserID || \"\";\n }\n\n /**\n * finishStateLoad(sURL, sStateData, nErrorCode)\n *\n * @this {ComputerPDP11}\n * @param {string} sURL\n * @param {string} sStateData\n * @param {number} nErrorCode\n */\n finishStateLoad(sURL, sStateData, nErrorCode)\n {\n if (!nErrorCode) {\n this.sStateData = sStateData;\n this.fStateData = true;\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"loaded state file \" + sURL.replace(this.sUserID || \"xxx\", \"xxx\"));\n }\n } else {\n this.sResumePath = null;\n this.fServerState = false;\n this.notice('Unable to load machine state from server (error ' + nErrorCode + (sStateData? ': ' + Str.trim(sStateData) : '') + ')');\n }\n this.setReady();\n }\n\n /**\n * wait(fn, parms)\n *\n * wait() waits until every component is ready (including ourselves, the last component we check), then calls the\n * specified Computer method.\n *\n * TODO: The Closure Compiler makes it difficult for us to define a function type for \"fn\" that works in all cases;\n * sometimes we want to pass a function that takes only a \"number\", and other times we want to pass a function that\n * takes only an \"Array\" (the type will mirror that of the \"parms\" parameter). However, the Closure Compiler insists\n * that both functions must be declared as accepting both types of parameters. So once again, we must use an untyped\n * function declaration, instead of something stricter like:\n *\n * param {function(this:Computer, (number|Array|undefined)): undefined} fn\n *\n * @this {ComputerPDP11}\n * @param {function(...)} fn\n * @param {number|Array} [parms] optional parameters\n */\n wait(fn, parms)\n {\n var computer = this;\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent <= aComponents.length; iComponent++) {\n var component = (iComponent < aComponents.length ? aComponents[iComponent] : this);\n if (!component.isReady()) {\n component.isReady(function onComponentReady() {\n computer.wait(fn, parms);\n });\n return;\n }\n }\n if (DEBUG && this.messageEnabled()) this.printMessage(\"ComputerPDP11.wait(ready)\");\n fn.call(this, parms);\n }\n\n /**\n * validateState(stateComputer)\n *\n * NOTE: We clear() stateValidate only when there's no stateComputer.\n *\n * @this {ComputerPDP11}\n * @param {State|null} [stateComputer]\n * @return {boolean} true if state passes validation, false if not\n */\n validateState(stateComputer)\n {\n var fValid = true;\n var stateValidate = new State(this, PDP11.APPVERSION, ComputerPDP11.STATE_VALIDATE);\n if (stateValidate.load() && stateValidate.parse()) {\n var sTimestampValidate = stateValidate.get(ComputerPDP11.STATE_TIMESTAMP);\n var sTimestampComputer = stateComputer? stateComputer.get(ComputerPDP11.STATE_TIMESTAMP) : \"unknown\";\n if (sTimestampValidate != sTimestampComputer) {\n this.notice(\"Machine state may be out-of-date\\n(\" + sTimestampValidate + \" vs. \" + sTimestampComputer + \")\\nCheck your browser's local storage limits\");\n fValid = false;\n if (!stateComputer) stateValidate.clear();\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"Last state: \" + sTimestampComputer + \" (validate: \" + sTimestampValidate + \")\");\n }\n }\n }\n return fValid;\n }\n\n /**\n * powerOn(resume)\n *\n * Power every component \"up\", applying any previously available state information.\n *\n * @this {ComputerPDP11}\n * @param {number} [resume] is a valid RESUME value; default is this.resume\n */\n powerOn(resume)\n {\n if (resume === undefined) {\n resume = this.resume || (this.sStateData? ComputerPDP11.RESUME_AUTO : ComputerPDP11.RESUME_NONE);\n }\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"ComputerPDP11.powerOn(\" + (resume == ComputerPDP11.RESUME_REPOWER ? \"repower\" : (resume ? \"resume\" : \"\")) + \")\");\n }\n\n if (this.nPowerChange) {\n return;\n }\n this.nPowerChange++;\n\n var fRepower = false;\n var fRestore = false;\n this.fRestoreError = false;\n var stateComputer = this.stateComputer || new State(this, PDP11.APPVERSION);\n\n if (resume == ComputerPDP11.RESUME_REPOWER) {\n fRepower = true;\n }\n else if (resume > ComputerPDP11.RESUME_NONE) {\n if (stateComputer.load(this.sStateData)) {\n /*\n * Since we're resuming something (either a predefined state or a state from localStorage), let's\n * create a \"failsafe\" checkpoint in localStorage, and destroy it at the end of a successful powerOn().\n * Which means, of course, that if a previous \"failsafe\" checkpoint already exists, something bad\n * may have happened the last time around.\n */\n this.stateFailSafe = new State(this, PDP11.APPVERSION, ComputerPDP11.STATE_FAILSAFE);\n if (this.stateFailSafe.load()) {\n this.powerReport(stateComputer);\n /*\n * We already know resume is something other than RESUME_NONE, so we'll go ahead and bump it\n * all the way to RESUME_PROMPT, so that the user will be prompted, and if the user declines to\n * restore, the state will be removed.\n */\n resume = ComputerPDP11.RESUME_PROMPT;\n /*\n * To ensure that the set() below succeeds, we need to call unload(), otherwise it may fail\n * with a \"read only\" error (eg, \"TypeError: Cannot assign to read only property 'timestamp'\").\n */\n this.stateFailSafe.unload();\n }\n\n this.stateFailSafe.set(ComputerPDP11.STATE_TIMESTAMP, Usr.getTimestamp());\n this.stateFailSafe.store();\n\n var fValidate = this.resume && !this.fServerState;\n if (resume == ComputerPDP11.RESUME_AUTO || Component.confirmUser(\"Click OK to restore the previous \" + PDP11.APPNAME + \" machine state, or CANCEL to reset the machine.\")) {\n fRestore = stateComputer.parse();\n if (fRestore) {\n var sCode = /** @type {string} */ (stateComputer.get(UserAPI.RES.CODE));\n var sData = /** @type {string} */ (stateComputer.get(UserAPI.RES.DATA));\n if (sCode) {\n if (sCode == UserAPI.CODE.OK) {\n stateComputer.load(sData);\n } else {\n /*\n * A missing (or not yet created) state file is no cause for alarm, but other errors might be\n */\n if (sCode == UserAPI.CODE.FAIL && sData != UserAPI.FAIL.NOSTATE) {\n this.notice(\"Error: \" + sData);\n if (sData == UserAPI.FAIL.VERIFY) this.resetUserID();\n } else {\n this.println(sCode + \": \" + sData);\n }\n /*\n * Try falling back to the state that we should have saved in localStorage, as a backup to the\n * server-side state.\n */\n stateComputer.unload(); // discard the invalid server-side state first\n if (stateComputer.load()) {\n fRestore = stateComputer.parse();\n fValidate = true;\n } else {\n fRestore = false; // hmmm, there was nothing in localStorage either\n }\n }\n }\n }\n /*\n * If the load/parse was successful, and it was from localStorage (not sStateData),\n * then we should to try verify that localStorage snapshot is current. One reason it may\n * NOT be current is if localStorage was full and we got a quota error during the last\n * powerOff().\n */\n if (fValidate) this.validateState(fRestore? stateComputer : null);\n } else {\n /*\n * RESUME_PROMPT indicates we should delete the state if they clicked Cancel to confirm() above.\n */\n if (resume == ComputerPDP11.RESUME_PROMPT) stateComputer.clear();\n }\n } else {\n /*\n * If there's no state, then there should also be no validation timestamp; if there is, then once again,\n * we're probably dealing with a quota error.\n */\n this.validateState();\n }\n delete this.sStateData;\n delete this.stateComputer;\n }\n\n /*\n * Start powering all components, including any data they may need to restore their state;\n * we restore power to the CPU last.\n */\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component !== this && component != this.cpu) {\n fRestore = this.powerRestore(component, stateComputer, fRepower, fRestore);\n }\n }\n\n /*\n * Assuming this is not a repower, we must perform another wait, because some components may\n * have marked themselves as \"not ready\" again (eg, the FDC component, if the restore forced it\n * to mount one or more additional disk images).\n */\n var aParms = [stateComputer, resume, fRestore];\n\n if (resume != ComputerPDP11.RESUME_REPOWER) {\n this.wait(this.donePowerOn, aParms);\n return;\n }\n this.donePowerOn(aParms);\n }\n\n /**\n * powerRestore(component, stateComputer, fRepower, fRestore)\n *\n * @this {ComputerPDP11}\n * @param {Component} component\n * @param {State} stateComputer\n * @param {boolean} fRepower\n * @param {boolean} fRestore\n * @return {boolean} true if restore should continue, false if not\n */\n powerRestore(component, stateComputer, fRepower, fRestore)\n {\n if (!component.flags.powered) {\n\n /*\n * TODO: If all components called super.powerUp(), the powered flag would be set automatically.\n */\n\n component.flags.powered = true;\n\n var data = null;\n\n try {\n if (fRestore) {\n data = stateComputer.get(component.id);\n if (!data) {\n /*\n * This is a hack that makes it possible for a machine whose ID has been\n * supplemented with a hyphenated numeric suffix to find object IDs in states\n * created from a machine without such a suffix.\n *\n * For example, if a state file was created from a machine with ID \"ibm5160\"\n * but the current machine is \"ibm5160-1\", this attempts a second lookup with\n * \"ibm5160\", enabling us to find objects that match the original machine ID\n * (eg, \"ibm5160.romEGA\").\n *\n * See /devices/pcx86/machine/5160/ega/640kb/array/ for examples of this.\n */\n data = stateComputer.get(component.id.replace(/-[0-9]+\\./i, '.'));\n }\n }\n\n /*\n * State.get() will return whatever was originally passed to State.set() (eg, an\n * Object or a string), but components are supposed to store only Objects, so if a\n * string comes back, something went wrong. By explicitly eliminating \"string\" data,\n * the Closure Compiler stops complaining that we might be passing strings to our\n * powerUp() functions (even though we know we're not).\n *\n * TODO: Determine if there's some way to coerce the Closure Compiler into treating\n * data as Object or null, without having to include this runtime check. An assert\n * would be a good idea, but this is overkill.\n */\n if (typeof data === \"string\") data = null;\n\n /*\n * If computer is null, this is simply a repower notification, which most components\n * don't do anything with. Exceptions include: CPU (since it may be halted) and Video\n * (since its screen may be \"turned off\").\n */\n if (!component.powerUp(data, fRepower) && data) {\n\n Component.error(\"Unable to restore state for \" + component.type);\n /*\n * If this is a resume error for a machine that also has a predefined state\n * AND we're not restoring from that state, then throw away the current state,\n * prevent any new state from being created, and then force a reload, which will\n * hopefully restore us to the functioning predefined state.\n *\n * TODO: Considering doing this in ALL cases, not just in situations where a\n * 'state' exists but we're not actually resuming from it.\n */\n if (this.sStatePath && !this.fStateData) {\n stateComputer.clear();\n this.resume = ComputerPDP11.RESUME_NONE;\n Web.reloadPage();\n } else {\n /*\n * In all other cases, we set fRestoreError, which should trigger a call to\n * powerReport() and then delete the offending state.\n */\n this.fRestoreError = true;\n }\n /*\n * Any failure triggers an automatic to call powerUp() again, without any state,\n * in the hopes that the component can recover by performing a reset.\n */\n component.powerUp(null);\n /*\n * We also disable the rest of the restore operation, because it's not clear\n * the remaining state information can be trusted; the machine is already in an\n * inconsistent state, so we're not likely to make things worse, and the only\n * alternative (starting over and performing a state-less reset) isn't likely to make\n * the user any happier. But, we'll see... we need some experience with the code.\n */\n fRestore = false;\n }\n\n if (!fRepower && component.comment) {\n var asComments = component.comment.split(\"|\");\n for (var i = 0; i < asComments.length; i++) {\n component.status(asComments[i]);\n }\n }\n }\n catch (err) {\n Component.error(\"Error restoring state for \" + component.type + \" (\" + err.message + \")\");\n }\n }\n return fRestore;\n }\n\n /**\n * donePowerOn(aParms)\n *\n * This is nothing more than a continuation of powerOn(), giving us the option of calling wait() one more time.\n *\n * @this {ComputerPDP11}\n * @param {Array} aParms containing [stateComputer, resume, fRestore]\n */\n donePowerOn(aParms)\n {\n var stateComputer = aParms[0];\n var fRepower = (aParms[1] < 0);\n var fRestore = aParms[2];\n\n if (DEBUG && this.flags.powered && this.messageEnabled()) {\n this.printMessage(\"ComputerPDP11.donePowerOn(): redundant\");\n }\n\n this.fInitialized = true;\n this.flags.powered = true;\n var controlPower = this.bindings[\"power\"];\n if (controlPower) controlPower.textContent = \"Shutdown\";\n\n /*\n * Once we get to this point, we're guaranteed that all components are ready, so it's safe to power the CPU;\n * the CPU should begin executing immediately, unless a debugger is attached.\n */\n if (this.cpu) {\n /*\n * TODO: Do we not care about the return value here? (ie, is checking fRestoreError sufficient)?\n */\n this.powerRestore(this.cpu, stateComputer, fRepower, fRestore);\n this.updateDisplays(-2);\n this.cpu.autoStart();\n }\n\n /*\n * If the state was bad, offer to report it and then delete it. Deleting may be moot, since invariably a new\n * state will be created on powerOff() before the next powerOn(), but it seems like good paranoia all the same.\n */\n if (this.fRestoreError) {\n this.powerReport(stateComputer);\n stateComputer.clear();\n }\n\n if (!fRepower && this.stateFailSafe) {\n this.stateFailSafe.clear();\n delete this.stateFailSafe;\n }\n\n this.nPowerChange = 0;\n }\n\n /**\n * checkPower()\n *\n * @this {ComputerPDP11}\n * @return {boolean} true if the computer is fully powered, false otherwise\n */\n checkPower()\n {\n if (this.flags.powered) return true;\n\n var component = null, iComponent;\n var aComponents = Component.getComponents(this.id);\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component !== this && !component.flags.ready) break;\n }\n if (iComponent == aComponents.length) {\n for (iComponent = 0; iComponent < aComponents.length; iComponent++) {\n component = aComponents[iComponent];\n if (component !== this && !component.flags.powered) break;\n }\n }\n if (iComponent == aComponents.length) component = this;\n var s = \"The \" + component.type + \" component (\" + component.id + \") is not \" + (!component.flags.ready? \"ready yet\" + (component.fnReady? \" (waiting for notification)\" : \"\") : \"powered yet\") + \".\";\n Component.alertUser(s);\n return false;\n }\n\n /**\n * powerReport(stateComputer)\n *\n * @this {ComputerPDP11}\n * @param {State} stateComputer\n */\n powerReport(stateComputer)\n {\n if (Component.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 + \".\")) {\n Web.sendReport(PDP11.APPNAME, PDP11.APPVERSION, this.url, this.getUserID(), ReportAPI.TYPE.BUG, stateComputer.toString());\n }\n }\n\n /**\n * powerOff(fSave, fShutdown)\n *\n * Power every component \"down\" and optionally save the machine state.\n *\n * There's one scenario that powerOff() isn't currently able to deal with very effectively: what to do when\n * the user switches away while it's still being restored, causing Disk getResource() calls to fail. The\n * Disk component calls notify() when that happens -- see Disk.mount() -- but the FDC and HDC controllers don't\n * notify *us* of those problems, so Computer assumes that the restore was completely successful, when in fact\n * it was only partially successful.\n *\n * Then we immediately arrive here to perform a save, following that incomplete restore. It would be wrong to\n * deal with that incomplete restore by setting fRestoreError, because we don't want to trigger a powerReport()\n * and the deletion of the previous state, because the state itself was presumably OK. Unfortunately, the new\n * state we now save will no longer include manually mounted disk images whose remounts were interrupted, so future\n * restores won't remount them either.\n *\n * We could perhaps solve this by having the Disk component notify us in those situations, set a new flag\n * (fRestoreIncomplete?), and set fSave to false if that's ever set. Be careful though: when fSave is false,\n * that means MORE than not saving; it also means deleting any previous state, which is NOT what you'd want to\n * do in a \"fRestoreIncomplete\" situation. Also, we have to worry about Disk operations that fail for other reasons,\n * making sure those failures don't interfere with the save process in the same way.\n *\n * As it stands, the worst that happens is any manually mounted disk images might have to be manually remounted,\n * which doesn't seem like a huge problem.\n *\n * @this {ComputerPDP11}\n * @param {boolean} [fSave] is true to request a saved state\n * @param {boolean} [fShutdown] is true if the machine is being shut down\n * @return {string|null} string representing the saved state (or null if error)\n */\n powerOff(fSave, fShutdown)\n {\n var data;\n var sState = \"none\";\n\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"ComputerPDP11.powerOff(\" + (fSave ? \"save\" : \"nosave\") + (fShutdown ? \",shutdown\" : \"\") + \")\");\n }\n\n if (this.nPowerChange) {\n return null;\n }\n this.nPowerChange--;\n\n var stateComputer = new State(this, PDP11.APPVERSION);\n var stateValidate = new State(this, PDP11.APPVERSION, ComputerPDP11.STATE_VALIDATE);\n\n var sTimestamp = Usr.getTimestamp();\n stateValidate.set(ComputerPDP11.STATE_TIMESTAMP, sTimestamp);\n stateComputer.set(ComputerPDP11.STATE_TIMESTAMP, sTimestamp);\n stateComputer.set(ComputerPDP11.STATE_VERSION, APPVERSION);\n stateComputer.set(ComputerPDP11.STATE_HOSTURL, Web.getHostURL());\n stateComputer.set(ComputerPDP11.STATE_BROWSER, Web.getUserAgent());\n\n /*\n * Always power the CPU \"down\" first, just to help insure it doesn't ask other components to do anything\n * after they're no longer ready.\n */\n if (this.cpu && this.cpu.powerDown) {\n if (fShutdown) {\n if (fSave) this.cpu.flags.autoStart = this.cpu.flags.running;\n this.cpu.stopCPU();\n }\n data = this.cpu.powerDown(fSave, fShutdown);\n if (typeof data === \"object\") stateComputer.set(this.cpu.id, data);\n if (fShutdown) {\n this.cpu.flags.powered = false;\n if (data === false) sState = null;\n }\n }\n\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.flags.powered) {\n if (component.powerDown) {\n data = component.powerDown(fSave, fShutdown);\n if (typeof data === \"object\") stateComputer.set(component.id, data);\n }\n if (fShutdown) {\n component.flags.powered = false;\n if (data === false) sState = null;\n }\n }\n }\n\n if (sState) {\n if (fShutdown) {\n var fClear = false;\n var fClearAll = false;\n if (fSave) {\n if (this.sUserID) {\n this.saveServerState(this.sUserID, stateComputer.toString());\n }\n if (!stateValidate.store() || !stateComputer.store()) {\n sState = null;\n /*\n * New behavior as of v1.13.2: if it appears that localStorage is full, we blow it ALL away.\n * Dedicated server-side storage is the only way we'll ever be able to reliably preserve a\n * particular machine's state. Historically, attempting to limp along with whatever localStorage\n * is left just generates the same useless and annoying warnings over and over.\n */\n fClear = fClearAll = true;\n }\n }\n else {\n /*\n * I used to ALWAYS clear (ie, delete) any associated computer state, but now I do this only if the\n * current machine is \"resumable\", because there are situations where I have two configurations\n * for the same machine -- one resumable and one not -- and I don't want the latter throwing away the\n * state of the former.\n *\n * So this code is here now strictly for callers to delete the state of a \"resumable\" machine, not as\n * some paranoid clean-up operation.\n *\n * An undocumented feature of this operation is that if your configuration uses the special 'resume=\"3\"'\n * value, and you click the \"Reset\" button, and then you click OK to reset the everything, this will\n * actually reset EVERYTHING (ie, all localStorage for ALL configs will be reclaimed).\n */\n if (this.resume) {\n fClear = true;\n fClearAll = (this.resume == ComputerPDP11.RESUME_DELETE);\n }\n }\n if (fClear) {\n stateComputer.clear(fClearAll);\n }\n } else {\n sState = stateComputer.toString();\n }\n }\n\n if (fShutdown) {\n this.flags.powered = false;\n var controlPower = this.bindings[\"power\"];\n if (controlPower) controlPower.textContent = \"Power\";\n }\n\n this.nPowerChange = 0;\n\n return sState;\n }\n\n /**\n * reset()\n *\n * Notify all (other) components with a reset() method that the Computer is being reset.\n *\n * NOTE: We'd like to reset the Bus first (due to the importance of the A20 line), but since we\n * allocated the Bus object ourselves, after all the other components were allocated, it ends\n * up near the end of Component's list of components. Hence the special case for this.bus below.\n *\n * Ditto for the CPU, in part because if the Front Panel resets before the CPU, it will end up\n * snapping/displaying the PC as of the last instruction executed, before the CPU resets the PC,\n * causing the Front Panel to display a stale address when we call updateDisplays() at the end.\n *\n * @this {ComputerPDP11}\n */\n reset()\n {\n this.flags.reset = true;\n if (this.bus && this.bus.reset) {\n this.printMessage(\"Resetting \" + this.bus.type);\n this.bus.reset();\n }\n if (this.cpu && this.cpu.reset) {\n this.printMessage(\"Resetting \" + this.cpu.type);\n this.cpu.reset();\n }\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component !== this && component !== this.bus && component !== this.cpu && component.reset) {\n this.printMessage(\"Resetting \" + component.type);\n component.reset();\n }\n }\n this.flags.reset = false;\n this.updateDisplays(-1);\n }\n\n /**\n * start(ms, nCycles)\n *\n * Notify all (other) components with a start() method that the CPU has started.\n *\n * Note that we're called by startCPU(), which is why we exclude the CPU component,\n * as well as ourselves.\n *\n * @this {ComputerPDP11}\n * @param {number} ms\n * @param {number} nCycles\n */\n start(ms, nCycles)\n {\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.type == \"CPU\" || component === this) continue;\n if (component.start) {\n component.start(ms, nCycles);\n }\n }\n this.updateDisplays(-1);\n }\n\n /**\n * stop(ms, nCycles)\n *\n * Notify all (other) components with a stop() method that the CPU has stopped.\n *\n * Note that we're called by stopCPU(), which is why we exclude the CPU component,\n * as well as ourselves.\n *\n * @this {ComputerPDP11}\n * @param {number} ms\n * @param {number} nCycles\n */\n stop(ms, nCycles)\n {\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (component.type == \"CPU\" || component === this) continue;\n if (component.stop) {\n component.stop(ms, nCycles);\n }\n }\n this.updateDisplays(-1);\n }\n\n /**\n * updateDisplays(nUpdate)\n *\n * TODO: Notify all components with an updateDisplay() method that the computer's state has changed (not\n * just the hard-coded ones below).\n *\n * If any DOM controls were bound to the CPU, then we need to call its updateDisplay() handler; if there are no\n * such bindings, then cpu.updateDisplay() does nothing.\n *\n * Similarly, if there's a Panel, then we need to call its updateDisplay() handler, in case it created its own canvas\n * and implemented its own register display (eg, dumpRegisters()); if not, then panel.updateDisplay() also does nothing.\n *\n * In practice, there will *either* be a Panel with a custom canvas *or* a set of DOM controls bound to the CPU *or*\n * neither. In theory, there could be BOTH, but that would be unusual.\n *\n * TODO: Consider alternate approaches to these largely register-oriented display updates. Ordinarily, we like to\n * separate logic from presentation, and currently the CPUState contains both, since it's the component that intimately\n * knows the names, number, sizes, etc, of all the active registers. The Panel component is the logical candidate,\n * but Panel is an optional component; it's often the case that only machines that include the Debugger also include\n * Panel.\n *\n * @this {ComputerPDP11}\n * @param {number} [nUpdate] (1 for periodic, -1 for forced, 0 or undefined otherwise)\n */\n updateDisplays(nUpdate)\n {\n /*\n * nUpdate is generally set to -1 whenever the CPU is transitioning to/from a running state, in which case\n * cpu.updateDisplay() will definitely want to hide/show register contents; however, at other times, when the\n * CPU is running, constantly updating the DOM controls too frequently can adversely impact overall performance.\n *\n * nUpdate will also be -1 whenever the Debugger has modified the state of the machine, implying that we're\n * not sure what, if anything, actually changed.\n */\n if (this.cpu) this.cpu.updateDisplay(nUpdate || 0);\n if (this.panel) this.panel.updateDisplay(nUpdate || 0);\n }\n\n /**\n * setBinding(sHTMLType, sBinding, control, sValue)\n *\n * @this {ComputerPDP11}\n * @param {string} sHTMLType is the type of the HTML control (eg, \"button\", \"textarea\", \"register\", \"flag\", \"rled\", etc)\n * @param {string} sBinding is the value of the 'binding' parameter stored in the HTML control's \"data-value\" attribute (eg, \"reset\")\n * @param {HTMLElement} control is the HTML control DOM object (eg, HTMLButtonElement)\n * @param {string} [sValue] optional data value\n * @return {boolean} true if binding was successful, false if unrecognized binding request\n */\n setBinding(sHTMLType, sBinding, control, sValue)\n {\n var computer = this;\n\n switch (sBinding) {\n case \"power\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickPower() {\n computer.onPower();\n };\n return true;\n\n case \"reset\":\n this.bindings[sBinding] = control;\n control.onclick = function onClickReset() {\n computer.onReset();\n };\n return true;\n\n /*\n * Technically, this binding should now be called \"saveState\", to clearly distinguish it from\n * the \"Save Machine\" control that's normally bound to the savePC() function in save.js. Saving\n * an entire machine includes everything needed to start/restore the machine; eg, the machine\n * XML configuration file(s) *and* the JSON-encoded machine state.\n */\n case \"save\":\n /*\n * Since this feature depends on the server supporting the PCjs User API (see userapi.js),\n * and since pcjs.org is no longer running a Node web server, we disable the feature for that\n * particular host.\n */\n if (Str.endsWith(Web.getHost(), \"pcjs.org\")) {\n if (DEBUG) this.log(\"Remote user API not available\");\n /*\n * We could also simply hide the control; eg:\n *\n * control.style.display = \"none\";\n *\n * but removing the control altogether seems better.\n */\n control.parentNode.removeChild(/** @type {Node} */ (control));\n return false;\n }\n this.bindings[sBinding] = control;\n control.onclick = function onClickSave() {\n var sUserID = computer.queryUserID(true);\n if (sUserID) {\n /*\n * I modified the test to include a check for sStatePath so that I could save new states\n * for machines with existing states; otherwise, I'd have no (easy) way of capturing and\n * updating their state. Making the machine (even temporarily) resumable would have been\n * one work-around, but it's not appropriate for some machines, as their state is simply\n * too large (for localStorage anyway, which is the default storage solution).\n */\n var fSave = !!(computer.resume && !computer.sResumePath || computer.sStatePath);\n var sState = computer.powerOff(fSave);\n if (fSave) {\n computer.saveServerState(sUserID, sState);\n } else {\n computer.notice(\"Resume disabled, machine state not saved\");\n }\n }\n /*\n * This seemed like a handy alternative, but it turned out to be a no-go, at least for large states:\n *\n * var sState = computer.powerOff(true);\n * if (sState) {\n * sState = \"data:text/json;charset=utf-8,\" + encodeURIComponent(sState);\n * window.open(sState);\n * }\n *\n * Perhaps if I embedded the data in a link on the current page instead; eg:\n *\n * $('<a href=\"' + sState + '\" download=\"state.json\">Download</a>').appendTo('#container');\n */\n };\n return true;\n\n default:\n break;\n }\n return false;\n }\n\n /**\n * resetUserID()\n *\n * @this {ComputerPDP11}\n */\n resetUserID()\n {\n Web.setLocalStorageItem(ComputerPDP11.STATE_USERID, \"\");\n this.sUserID = null;\n }\n\n /**\n * queryUserID(fPrompt)\n *\n * @this {ComputerPDP11}\n * @param {boolean} [fPrompt]\n * @returns {string|null|undefined}\n */\n queryUserID(fPrompt)\n {\n var sUserID = this.sUserID;\n if (!sUserID) {\n sUserID = Web.getLocalStorageItem(ComputerPDP11.STATE_USERID);\n if (sUserID !== undefined) {\n if (!sUserID && fPrompt) {\n /*\n * NOTE: Warning the user here that \"Save\" operations are not currently supported by pcjs.org is\n * merely a precaution, because ordinarily, setBinding() should have already determined if we are\n * running from pcjs.org and disabled any \"Save\" button.\n */\n sUserID = Component.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.\");\n if (sUserID) {\n sUserID = this.verifyUserID(sUserID);\n if (!sUserID) this.notice(\"The user ID is invalid.\");\n }\n }\n } else if (fPrompt) {\n this.notice(\"Browser local storage is not available\");\n }\n }\n return sUserID;\n }\n\n /**\n * verifyUserID(sUserID)\n *\n * @this {ComputerPDP11}\n * @param {string} sUserID\n * @return {string} validated user ID, or null if error\n */\n verifyUserID(sUserID)\n {\n this.sUserID = null;\n var fMessages = DEBUG && this.messageEnabled();\n if (fMessages) this.printMessage(\"verifyUserID(\" + sUserID + \")\");\n var sRequest = Web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.VERIFY + '&' + UserAPI.QUERY.USER + '=' + sUserID;\n var response = Web.getResource(sRequest);\n var nErrorCode = response[0];\n var sResponse = response[1];\n if (!nErrorCode && sResponse) {\n try {\n response = eval(\"(\" + sResponse + \")\");\n if (response.code && response.code == UserAPI.CODE.OK) {\n Web.setLocalStorageItem(ComputerPDP11.STATE_USERID, response.data);\n if (fMessages) this.printMessage(ComputerPDP11.STATE_USERID + \" updated: \" + response.data);\n this.sUserID = response.data;\n } else {\n if (fMessages) this.printMessage(response.code + \": \" + response.data);\n }\n } catch (e) {\n Component.error(e.message + \" (\" + sResponse + \")\");\n }\n } else {\n if (fMessages) this.printMessage(\"invalid response (error \" + nErrorCode + \")\");\n }\n return this.sUserID;\n }\n\n /**\n * getServerStatePath()\n *\n * @this {ComputerPDP11}\n * @return {string|null} sStatePath (null if no localStorage or no USERID stored in localStorage)\n */\n getServerStatePath()\n {\n var sStatePath = null;\n if (this.sUserID) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(ComputerPDP11.STATE_USERID + \" for load: \" + this.sUserID);\n }\n sStatePath = Web.getHost() + UserAPI.ENDPOINT + '?' + UserAPI.QUERY.REQ + '=' + UserAPI.REQ.LOAD + '&' + UserAPI.QUERY.USER + '=' + this.sUserID + '&' + UserAPI.QUERY.STATE + '=' + State.key(this, PDP11.APPVERSION);\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(ComputerPDP11.STATE_USERID + \" unavailable\");\n }\n }\n return sStatePath;\n }\n\n /**\n * saveServerState(sUserID, sState)\n *\n * @this {ComputerPDP11}\n * @param {string} sUserID\n * @param {string|null} sState\n */\n saveServerState(sUserID, sState)\n {\n /*\n * We must pass fSync == true, because (as I understand it) browsers will blow off any async\n * requests when a page is being closed. Since our request is synchronous, storeServerState()\n * should also return a result, but there's not much we can do with it, since browsers ALSO\n * tend to blow off alerts() and the like when closing down.\n */\n if (sState) {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"size of server state: \" + sState.length + \" bytes\");\n }\n var response = this.storeServerState(sUserID, sState, true);\n if (response && response[UserAPI.RES.CODE] == UserAPI.CODE.OK) {\n this.notice(\"Machine state saved to server\");\n } else if (sState) {\n var sError = (response && response[UserAPI.RES.DATA]) || UserAPI.FAIL.BADSTORE;\n if (response[UserAPI.RES.CODE] == UserAPI.CODE.FAIL) {\n sError = \"Error: \" + sError;\n } else {\n sError = \"Error \" + response[UserAPI.RES.CODE] + \": \" + sError;\n }\n this.notice(sError);\n this.resetUserID();\n }\n } else {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(\"no state to store\");\n }\n }\n }\n\n /**\n * storeServerState(sUserID, sState, fSync)\n *\n * @this {ComputerPDP11}\n * @param {string} sUserID\n * @param {string} sState\n * @param {boolean} [fSync] is true if we're powering down and should perform a synchronous request (default is async)\n * @return {*} server response if fSync is true and a response was received; otherwise null\n */\n storeServerState(sUserID, sState, fSync)\n {\n if (DEBUG && this.messageEnabled()) {\n this.printMessage(ComputerPDP11.STATE_USERID + \" for store: \" + sUserID);\n }\n /*\n * TODO: Determine whether or not any browsers cancel our request if we're called during a browser \"shutdown\" event,\n * and whether or not it matters if we do an async request (currently, we're not, to try to ensure the request goes through).\n */\n var dataPost = {};\n dataPost[UserAPI.QUERY.REQ] = UserAPI.REQ.STORE;\n dataPost[UserAPI.QUERY.USER] = sUserID;\n dataPost[UserAPI.QUERY.STATE] = State.key(this, PDP11.APPVERSION);\n dataPost[UserAPI.QUERY.DATA] = sState;\n var sRequest = Web.getHost() + UserAPI.ENDPOINT;\n if (!fSync) {\n Web.getResource(sRequest, dataPost, true);\n } else {\n var response = Web.getResource(sRequest, dataPost);\n var sResponse = response[0];\n if (response[1]) {\n if (sResponse) {\n var i = sResponse.indexOf('\\n');\n if (i > 0) sResponse = sResponse.substr(0, i);\n if (!sResponse.indexOf(\"Error: \")) sResponse = sResponse.substr(7);\n }\n sResponse = '{\"' + UserAPI.RES.CODE + '\":' + response[1] + ',\"' + UserAPI.RES.DATA + '\":\"' + sResponse + '\"}';\n }\n if (DEBUG && this.messageEnabled()) this.printMessage(sResponse);\n return JSON.parse(sResponse);\n }\n return null;\n }\n\n /**\n * onPower()\n *\n * This handles UI requests to toggle the computer's power (eg, see the \"power\" button binding).\n *\n * @this {ComputerPDP11}\n */\n onPower()\n {\n if (!this.nPowerChange) {\n if (!this.flags.powered) {\n this.wait(this.powerOn);\n } else {\n this.powerOff(false, true);\n }\n }\n }\n\n /**\n * onReset()\n *\n * This handles UI requests to reset the computer's state (eg, see the \"reset\" button binding).\n *\n * @this {ComputerPDP11}\n */\n onReset()\n {\n /*\n * I'm going to start with the presumption that it makes little sense for an \"unpowered\" computer to be \"reset\";\n * ditto if the power state is currently being changed.\n */\n if (!this.flags.powered || this.nPowerChange) return;\n\n /*\n * If this is a \"resumable\" machine (and it's not using a predefined state), then we overload the reset\n * operation to offer an explicit \"save or discard\" option first. This is currently the only UI we offer to\n * discard a machine's state, including any disk changes. The traditional \"reset\" operation is still available\n * for non-resumable machines.\n *\n * TODO: Break this behavior out into a separate \"discard\" operation, in case the designer of the machine really\n * wants to clutter the UI with confusing options. ;-)\n */\n if (this.resume && !this.sResumePath) {\n /*\n * I used to bypass the prompt if this.resume == ComputerPDP11.RESUME_AUTO, setting fSave to true automatically,\n * but that gives the user no means of resetting a resumable machine that contains errors in its resume state.\n */\n var fSave = (/* this.resume == ComputerPDP11.RESUME_AUTO || */ Component.confirmUser(\"Click OK to save changes to this \" + PDP11.APPNAME + \" machine.\\n\\nWARNING: If you CANCEL, all disk changes will be discarded.\"));\n this.powerOff(fSave, true);\n /*\n * Forcing the page to reload is an expedient option, but ugly. It's preferable to call powerOn()\n * and rely on all the components to reset themselves to their default state. The components with\n * the greatest burden here are FDC and HDC, which must rely on the fReload flag to determine whether\n * or not to unload/reload all their original auto-mounted disk images.\n *\n * However, if we started with a predefined state (ie, sStatePath is set), we take this shortcut, because\n * we don't (yet) have code in place to gracefully reload the initial state (requires calling getResource()\n * again); alternatively, we could avoid throwing that state away, but it seems better to save the memory.\n *\n * TODO: Make this more graceful, so that we can stop using the reloadPage() sledgehammer.\n */\n if (!fSave && this.sStatePath) {\n Web.reloadPage();\n return;\n }\n if (!fSave) this.fReload = true;\n this.powerOn(ComputerPDP11.RESUME_NONE);\n this.fReload = false;\n } else {\n this.reset();\n if (this.cpu && !this.dbg) this.cpu.autoStart();\n }\n }\n\n /**\n * getMachineComponent(sType, componentPrev)\n *\n * @this {ComputerPDP11}\n * @param {string} sType\n * @param {Component|null} [componentPrev] of previously returned component, if any\n * @return {Component|null}\n */\n getMachineComponent(sType, componentPrev)\n {\n var componentLast = componentPrev;\n var aComponents = Component.getComponents(this.id);\n for (var iComponent = 0; iComponent < aComponents.length; iComponent++) {\n var component = aComponents[iComponent];\n if (componentPrev) {\n if (componentPrev == component) componentPrev = null;\n continue;\n }\n if (component.type == sType) return component;\n }\n if (!componentLast) Component.log(\"Machine component type '\" + sType + \"' not found\", \"warning\");\n return null;\n }\n\n /**\n * setFocus(fScroll)\n *\n * NOTE: When soft keyboard buttons call us to return focus to the machine (and away from the button),\n * the browser's default behavior is to scroll the element into view, which can be annoying, especially on iOS,\n * where the display is more constrained, so we no longer do it by default (fScroll must be true).\n *\n * @this {ComputerPDP11}\n * @param {boolean} [fScroll] (true if you really want the control scrolled into view)\n */\n setFocus(fScroll)\n {\n if (this.controlPrint) {\n /*\n * This seems to be recommended work-around to prevent the browser from scrolling the focused element\n * into view. The CPU is not a visual component, so when the CPU wants to set focus, the primary intent\n * is to ensure that keyboard input is fielded properly.\n */\n var x = 0, y = 0;\n if (!fScroll && window) {\n x = window.scrollX;\n y = window.scrollY;\n }\n\n this.controlPrint.focus();\n\n if (!fScroll && window) {\n window.scrollTo(x, y);\n }\n }\n }\n\n /**\n * ComputerPDP11.init()\n *\n * For every machine represented by an HTML element of class \"pdp11-machine\", this function\n * locates the HTML element of class \"computer\", extracting the JSON-encoded parameters for the\n * Computer constructor from the element's \"data-value\" attribute, invoking the constructor to\n * create a Computer component, and then binding any associated HTML controls to the new component.\n */\n static init()\n {\n /*\n * In non-COMPILED builds, embedMachine() may have set XMLVERSION.\n */\n if (!COMPILED && XMLVERSION) PDP11.APPVERSION = XMLVERSION;\n\n var aeMachines = Component.getElementsByClass(document, PDP11.APPCLASS + \"-machine\");\n\n for (var iMachine = 0; iMachine < aeMachines.length; iMachine++) {\n\n var eMachine = aeMachines[iMachine];\n var parmsMachine = Component.getComponentParms(eMachine);\n\n var aeComputers = Component.getElementsByClass(eMachine, PDP11.APPCLASS, \"computer\");\n\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n\n /*\n * We set fSuspended in the Computer constructor because we want to \"power up\" the\n * computer ourselves, after any/all bindings are in place.\n */\n var computer = new ComputerPDP11(parmsComputer, parmsMachine, true);\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onInit(\" + computer.flags.powered + \")\");\n }\n\n /*\n * Bind any \"power\", \"reset\" and \"save\" buttons. An \"erase\" button was also considered,\n * but \"reset\" now provides a way to force the machine to start from scratch again, so \"erase\"\n * may be redundant now.\n */\n Component.bindComponentControls(computer, eComputer, PDP11.APPCLASS);\n\n /*\n * Power on the computer, giving every component the opportunity to reset or restore itself.\n */\n if (computer.fAutoPower) computer.wait(computer.powerOn);\n }\n }\n }\n\n /**\n * ComputerPDP11.show()\n *\n * When exit() is using an \"onbeforeunload\" handler, this \"onpageshow\" handler allows us to repower everything,\n * without either resetting or restoring. We call powerOn() with a special resume value (RESUME_REPOWER) if the\n * computer is already marked as \"ready\", meaning the browser didn't change anything. This \"repower\" process\n * should be very quick, essentially just marking all components as powered again (so that, for example, the Video\n * component will start drawing again) and firing the CPU up again.\n */\n static show()\n {\n var aeComputers = Component.getElementsByClass(document, PDP11.APPCLASS, \"computer\");\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n var computer = /** @type {ComputerPDP11} */ (Component.getComponentByType(\"Computer\", parmsComputer['id']));\n if (computer) {\n\n computer.flags.unloading = false;\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onShow(\" + computer.fInitialized + \",\" + computer.flags.powered + \")\");\n }\n\n /*\n * Note that the FIRST 'onpageshow' event, and therefore the first show() callback, occurs\n * AFTER the the initial 'onload' event, and at that point in time, fInitialized will not be set yet.\n * So, practically speaking, the first show() callback isn't all that useful.\n */\n if (computer.fInitialized && !computer.flags.powered) {\n /**\n * Repower the computer, notifying every component to continue running as-is.\n */\n computer.powerOn(ComputerPDP11.RESUME_REPOWER);\n }\n }\n }\n }\n\n /**\n * ComputerPDP11.exit()\n *\n * The Computer is currently the only component that uses an \"exit\" handler, which Web.onExit() defines as\n * either an \"unload\" or \"onbeforeunload\" handler. This gives us the opportunity to save the machine state,\n * using our powerOff() function, before the page goes away.\n *\n * It's worth noting that \"onbeforeunload\" offers one nice feature when used instead of \"onload\": the entire\n * page (and therefore this entire application) is retained in its current state by the browser (well, some\n * browsers), so that if you go to a new URL, either by entering a new URL in the same window/tab, or by pressing\n * the FORWARD button, and then you press the BACK button, the page is immediately restored to its previous state.\n *\n * In fact, that's how some browsers operate whether you have an \"onbeforeunload\" handler or not; in other words,\n * an \"onbeforeunload\" handler doesn't change the page retention behavior of the browser. By contrast, the mere\n * presence of an \"onunload\" handler generally causes a browser to throw the page away once the handler returns.\n *\n * However, in order to safely use \"onbeforeunload\", we must add yet another handler (\"onpageshow\") to repower\n * everything, without either resetting or restoring. Hence, the ComputerPDP11.show() function, which calls powerOn()\n * with a special resume value (RESUME_REPOWER) if the computer is already marked as \"ready\", meaning the browser\n * didn't change anything. This \"repower\" process should be very quick, essentially just marking all components as\n * powered again (so that, for example, the Video component will start drawing again) and firing the CPU up again.\n *\n * Reportedly, some browsers (eg, Opera) don't support \"onbeforeunload\", in which case Component will have to use\n * \"unload\" instead. But even when the page must be rebuilt from scratch, the combination of browser cache and\n * localStorage means the simulation should be restored and become operational almost immediately.\n */\n static exit()\n {\n var aeComputers = Component.getElementsByClass(document, PDP11.APPCLASS, \"computer\");\n for (var iComputer = 0; iComputer < aeComputers.length; iComputer++) {\n var eComputer = aeComputers[iComputer];\n var parmsComputer = Component.getComponentParms(eComputer);\n var computer = /** @type {ComputerPDP11} */ (Component.getComponentByType(\"Computer\", parmsComputer['id']));\n if (computer) {\n\n /*\n * Added a new flag that Component functions (eg, notice()) should check before alerting the user.\n */\n computer.flags.unloading = true;\n\n if (DEBUG && computer.messageEnabled()) {\n computer.printMessage(\"onExit(\" + computer.flags.powered + \")\");\n }\n\n if (computer.flags.powered) {\n /**\n * Power off the computer, giving every component an opportunity to save its state,\n * but only if 'resume' has been set AND there is no valid resume path (because if a valid resume\n * path exists, we'll always load our state from there, and not from whatever we save here).\n */\n computer.powerOff(!!(computer.resume && !computer.sResumePath), true);\n }\n }\n }\n }\n}\n\nComputerPDP11.STATE_FAILSAFE = \"failsafe\";\nComputerPDP11.STATE_VALIDATE = \"validate\";\nComputerPDP11.STATE_TIMESTAMP = \"timestamp\";\nComputerPDP11.STATE_VERSION = \"version\";\nComputerPDP11.STATE_HOSTURL = \"url\";\nComputerPDP11.STATE_BROWSER = \"browser\";\nComputerPDP11.STATE_USERID = \"user\";\n\n/*\n * The following constants define all the resume options. Negative values (eg, RESUME_REPOWER) are for\n * internal use only, and RESUME_DELETE is not documented (it provides a way of deleting ALL saved states\n * whenever a resume is declined). As a result, the only \"end-user\" values are 0, 1 and 2.\n */\nComputerPDP11.RESUME_REPOWER = -1; // resume without changing any state (for internal use only)\nComputerPDP11.RESUME_NONE = 0; // default (no resume)\nComputerPDP11.RESUME_AUTO = 1; // automatically save/restore state\nComputerPDP11.RESUME_PROMPT = 2; // automatically save but conditionally restore (WARNING: if restore is declined, any state is discarded)\nComputerPDP11.RESUME_DELETE = 3; // same as RESUME_PROMPT but discards ALL machines states whenever ANY machine restore is declined (undocumented)\n\n/*\n * Initialize every Computer on the page.\n */\nWeb.onInit(ComputerPDP11.init);\nWeb.onShow(ComputerPDP11.show);\nWeb.onExit(ComputerPDP11.exit);\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/state.js (C) Jeff Parsons 2012-2018\n */\n\n\nclass State {\n /**\n * State(component, sVersion, sSuffix)\n *\n * State objects are used by components to save/restore their state.\n *\n * During a save operation, components add data to a State object via set(), and then return\n * the resulting data using data().\n *\n * During a restore operation, the Computer component passes the results of each data() call\n * back to the originating component.\n *\n * WARNING: Since State objects are low-level objects that have no UI requirements, they do not\n * inherit from the Component class, so you should only use class methods of Component, such as\n * Component.assert() (or Debugger methods if the Debugger is available).\n *\n * NOTE: 1.01 is the first version to provide limited save/restore support using localStorage.\n * From that point on, care must be taken to insure that any new version that's incompatible with\n * previous localStorage data be released with a version number that is at least 1 greater,\n * since we're tagging the localStorage data with the integer portion of the version string.\n *\n * @param {Component} component\n * @param {string} [sVersion] is used to append a major version number to the key\n * @param {string} [sSuffix] is used to append any additional suffixes to the key\n */\n constructor(component, sVersion, sSuffix)\n {\n this.id = component.id;\n this.dbg = component.dbg;\n this.json = \"\";\n this.state = {};\n this.fLoaded = this.fParsed = false;\n this.key = State.key(component, sVersion, sSuffix);\n this.unload(component.parms);\n }\n\n /**\n * set(id, data)\n *\n * @this {State}\n * @param {number|string} id\n * @param {Object|string} data\n */\n set(id, data)\n {\n try {\n this.state[id] = data;\n } catch(e) {\n Component.log(e.message);\n }\n }\n\n /**\n * get(id)\n *\n * @this {State}\n * @param {number|string} id\n * @return {Object|string|null}\n */\n get(id)\n {\n return this.state[id] || null;\n }\n\n /**\n * data()\n *\n * @this {State}\n * @return {Object}\n */\n data()\n {\n return this.state;\n }\n\n /**\n * load(json)\n *\n * WARNING: Make sure you follow this call with either a call to parse() or unload(),\n * because any stringified data that we've loaded isn't usable until it's been parsed.\n *\n * @this {State}\n * @param {string|null} [json]\n * @return {boolean} true if state exists in localStorage, false if not\n */\n load(json)\n {\n if (json) {\n this.json = json;\n this.fLoaded = true;\n this.fParsed = false;\n return true;\n }\n if (this.fLoaded) {\n /*\n * This is assumed to be a redundant load().\n */\n return true;\n }\n if (Web.hasLocalStorage()) {\n var s = Web.getLocalStorageItem(this.key);\n if (s) {\n this.json = s;\n this.fLoaded = true;\n if (DEBUG) Component.log(\"localStorage(\" + this.key + \"): \" + s.length + \" bytes loaded\");\n return true;\n }\n }\n return false;\n }\n\n /**\n * parse()\n *\n * This completes the load() operation, by parsing what was loaded, on the assumption there\n * might be some benefit to deferring parsing until we've given the user a chance to confirm.\n * Otherwise, load() could have just as easily done this, too.\n *\n * @this {State}\n * @return {boolean} true if successful, false if error\n */\n parse()\n {\n var fSuccess = true;\n if (!this.fParsed) {\n try {\n this.state = JSON.parse(this.json);\n this.fParsed = true;\n } catch (e) {\n Component.error(e.message || e);\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * store()\n *\n * @this {State}\n * @return {boolean} true if successful, false if error\n */\n store()\n {\n var fSuccess = true;\n if (Web.hasLocalStorage()) {\n var s = JSON.stringify(this.state);\n if (Web.setLocalStorageItem(this.key, s)) {\n if (DEBUG) Component.log(\"localStorage(\" + this.key + \"): \" + s.length + \" bytes stored\");\n } else {\n /*\n * WARNING: Because browsers tend to disable all alerts() during an \"unload\" operation,\n * it's unlikely anyone will ever see the \"quota\" errors that occur at this point. Need to\n * think of some way to notify the user that there's a problem, and offer a way of cleaning\n * up old states.\n */\n Component.error(\"Unable to store \" + s.length + \" bytes in browser local storage\");\n fSuccess = false;\n }\n }\n return fSuccess;\n }\n\n /**\n * toString()\n *\n * @this {State}\n * @return {string} JSON-encoded state\n */\n toString()\n {\n return this.state? JSON.stringify(this.state) : this.json;\n }\n\n /**\n * unload(parms)\n *\n * This discards any data saved via set() or loaded via load(), creating an empty State object.\n * Note that you have to follow this call with an explicit call to store() if you want to remove\n * the state from localStorage as well.\n *\n * @this {State}\n * @param {Object} [parms]\n */\n unload(parms)\n {\n this.json = \"\";\n this.state = {};\n this.fLoaded = this.fParsed = false;\n if (parms) this.set(\"parms\", parms);\n }\n\n /**\n * clear(fAll)\n *\n * This unloads the current state, and then clears ALL localStorage for the current machine,\n * independent of version, to reduce the chance of orphaned states wasting part of our limited allocation.\n *\n * @this {State}\n * @param {boolean} [fAll] true to unconditionally clear ALL localStorage for the current domain\n */\n clear(fAll)\n {\n this.unload();\n var aKeys = Web.getLocalStorageKeys();\n for (var i = 0; i < aKeys.length; i++) {\n var sKey = aKeys[i];\n if (sKey && (fAll || sKey.substr(0, this.key.length) == this.key)) {\n Web.removeLocalStorageItem(sKey);\n if (DEBUG) Component.log(\"localStorage(\" + sKey + \") removed\");\n aKeys.splice(i, 1);\n i = 0;\n }\n }\n }\n\n /**\n * State.key(component, sVersion, sSuffix)\n *\n * This encapsulates the key generation code.\n *\n * @param {Component} component\n * @param {string} [sVersion] is used to append a major version number to the key\n * @param {string} [sSuffix] is used to append any additional suffixes to the key\n * @return {string} key\n */\n static key(component, sVersion, sSuffix)\n {\n var key = component.id;\n if (sVersion) {\n var i = sVersion.indexOf('.');\n if (i > 0) key += \".v\" + sVersion.substr(0, i);\n }\n if (sSuffix) {\n key += \".\" + sSuffix;\n }\n return key;\n }\n\n /**\n * State.compress(aSrc)\n *\n * @param {Array.<number>|null} aSrc\n * @return {Array.<number>|null} is either the original array (aSrc), or a smaller array of \"count, value\" pairs (aComp)\n */\n static compress(aSrc)\n {\n if (aSrc) {\n var iSrc = 0;\n var iComp = 0;\n var aComp = [];\n while (iSrc < aSrc.length) {\n var n = aSrc[iSrc];\n\n var iCompare = iSrc + 1;\n while (iCompare < aSrc.length && aSrc[iCompare] === n) iCompare++;\n aComp[iComp++] = iCompare - iSrc;\n aComp[iComp++] = n;\n iSrc = iCompare;\n }\n if (aComp.length < aSrc.length) return aComp;\n }\n return aSrc;\n }\n\n /**\n * State.decompress(aComp)\n *\n * @param {Array.<number>} aComp\n * @param {number} nLength is expected length of decompressed data\n * @return {Array.<number>}\n */\n static decompress(aComp, nLength)\n {\n var iDst = 0;\n var aDst = new Array(nLength);\n var iComp = 0;\n while (iComp < aComp.length - 1) {\n var c = aComp[iComp++];\n var n = aComp[iComp++];\n while (c--) {\n aDst[iDst++] = n;\n }\n }\n\n return aDst;\n }\n\n /**\n * State.compressEvenOdd(aSrc)\n *\n * This is a very simple variation on compress() that compresses all the EVEN elements of aSrc first,\n * followed by all the ODD elements. This tends to work better on EGA video memory, because when odd/even\n * addressing is enabled (eg, for text modes), the DWORD values tend to alternate, which is the worst case\n * for compress(), but the best case for compressEvenOdd().\n *\n * One wrinkle we support: if the first element is uninitialized, then we assume the entire array is undefined,\n * and return an empty compressed array. Conversely, decompressEvenOdd() will take an empty compressed array\n * and return an uninitialized array.\n *\n * @param {Array.<number>|null} aSrc\n * @return {Array.<number>|null} is either the original array (aSrc), or a smaller array of \"count, value\" pairs (aComp)\n */\n static compressEvenOdd(aSrc)\n {\n if (aSrc) {\n var iComp = 0, aComp = [];\n if (aSrc[0] !== undefined) {\n for (var off = 0; off < 2; off++) {\n var iSrc = off;\n while (iSrc < aSrc.length) {\n var n = aSrc[iSrc];\n var iCompare = iSrc + 2;\n while (iCompare < aSrc.length && aSrc[iCompare] === n) iCompare += 2;\n aComp[iComp++] = (iCompare - iSrc) >> 1;\n aComp[iComp++] = n;\n iSrc = iCompare;\n }\n }\n }\n if (aComp.length < aSrc.length) return aComp;\n }\n return aSrc;\n }\n\n /**\n * State.decompressEvenOdd(aComp, nLength)\n *\n * This is the counterpart to compressEvenOdd(). Note that because there's nothing in the compressed sequence\n * that differentiates a compress() sequence from a compressEvenOdd() sequence, you simply have to be consistent:\n * if you used even/odd compression, then you must use even/odd decompression.\n *\n * @param {Array.<number>} aComp\n * @param {number} nLength is expected length of decompressed data\n * @return {Array.<number>}\n */\n static decompressEvenOdd(aComp, nLength)\n {\n var iDst = 0;\n var aDst = new Array(nLength);\n var iComp = 0;\n while (iComp < aComp.length - 1) {\n var c = aComp[iComp++];\n var n = aComp[iComp++];\n while (c--) {\n aDst[iDst] = n;\n iDst += 2;\n }\n /*\n * The output of a \"count,value\" pair will never exceed the end of the output array, so as soon as we reach it\n * the first time, we know it's time to switch to ODD elements, and as soon as we reach it again, we should be\n * done.\n */\n\n if (iDst == nLength) iDst = 1;\n }\n\n return aDst;\n }\n}\n\n\n\n/**\n * @copyright https://www.pcjs.org/modules/shared/lib/embed.js (C) Jeff Parsons 2012-2018\n */\n\n\n/*\n * We now support asynchronous XML and XSL file loads; simply set fAsync (below) to true.\n *\n * NOTE: For that support to work, we have to keep track of the number of machines on the page\n * (ie, how many embedMachine() calls were issued), reduce the count as each machine XML file\n * is fully transformed into HTML, and when the count finally returns to zero, notify all the\n * machine component init() handlers.\n *\n * Also, to prevent those init() handlers from running prematurely, we must disable all page\n * notification events at the start of the embedding process (Web.enablePageEvents(false)) and\n * re-enable them at the end (Web.enablePageEvents(true)).\n */\nvar fAsync = true;\nvar cAsyncMachines = 0;\n\n/**\n * loadXML(sFile, idMachine, sAppName, sAppClass, sParms, fResolve, display, done)\n *\n * This is the preferred way to load all XML and XSL files. It uses getResource()\n * to load them as strings, which parseXML() can massage before parsing/transforming them.\n *\n * For example, since I've been unable to get the XSLT document() function to work inside any\n * XSL document loaded by JavaScript's XSLT processor, that has prevented me from dynamically\n * loading any XML machine file that uses the \"ref\" attribute to refer to and incorporate\n * another XML document.\n *\n * To solve that, I've added an fResolve parameter that tells parseXML() to fetch any\n * referenced documents ITSELF and insert them into the XML string prior to parsing, instead\n * of relying on the XSLT template to pull them in. That fetching is handled by resolveXML(),\n * which iterates over the XML until all \"refs\" have been resolved (including any nested\n * references).\n *\n * Also, XSL files with a <!DOCTYPE [...]> cause MSIE's Microsoft.XMLDOM.loadXML() function\n * to choke, so I strip that out prior to parsing as well.\n *\n * TODO: Figure out why the XSLT document() function works great when the web browser loads an\n * XML file (and the associated XSL file) itself, but does not work when loading documents via\n * JavaScript XSLT support. Is it broken, is it a security issue, or am I just calling it wrong?\n *\n * @param {string} sXMLFile\n * @param {string|null|undefined} idMachine\n * @param {string|null|undefined} sAppName\n * @param {string|null|undefined} sAppClass\n * @param {string|null|undefined} sParms (machine parameters, if any)\n * @param {string|null|undefined} sClass (an optional machine class name used to style the machine)\n * @param {boolean} fResolve is true to resolve any \"ref\" attributes\n * @param {function(string)} display\n * @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)\n */\nfunction loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n{\n var doneLoadXML = function(sURLName, sXML, nErrorCode) {\n if (nErrorCode) {\n if (!sXML) sXML = \"unable to load \" + sXMLFile + \" (\" + nErrorCode + \")\";\n done(sXML, null);\n return;\n }\n parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done);\n };\n display(\"Loading \" + sXMLFile + \"...\");\n Web.getResource(sXMLFile, null, fAsync, doneLoadXML);\n}\n\n/**\n * parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n *\n * Generates an XML document from an XML string. This function also provides a work-around for XSLT's\n * lack of support for the document() function (at least on some browsers), by replacing every reference\n * tag (ie, a tag with a \"ref\" attribute) with the contents of the referenced file.\n *\n * @param {string} sXML\n * @param {string|null} sXMLFile\n * @param {string|null|undefined} idMachine\n * @param {string|null|undefined} sAppName\n * @param {string|null|undefined} sAppClass\n * @param {string|null|undefined} sParms (machine parameters, if any)\n * @param {string|null|undefined} sClass (an optional machine class name used to style the machine)\n * @param {boolean} fResolve is true to resolve any \"ref\" attributes; default is false\n * @param {function(string)} display\n * @param {function(string,Object)} done (string contains the unparsed XML string data, and Object contains a parsed XML object)\n */\nfunction parseXML(sXML, sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, fResolve, display, done)\n{\n var buildXML = function(sXML, sError) {\n if (sError) {\n done(sError, null);\n return;\n }\n if (idMachine) {\n\n /*\n * A more sensible place to record the machine XML would be embedMachine(), like we do for the\n * XSL file, but since we're about to modify the original machine XML, it's best to record it now.\n */\n Component.addMachineResource(idMachine, sXMLFile, sXML);\n\n var sURL = sXMLFile;\n if (sURL && sURL.indexOf('/') < 0 && window.location.pathname.slice(-1) == '/') {\n sURL = window.location.pathname + sURL;\n }\n /*\n * We embed the URL of the XML file both as a separate \"xml\" attribute for easy access from the\n * XSL file, and as part of the \"parms\" attribute for easy access from machines (see getMachineParm()).\n */\n if (!sParms) {\n sParms = '{';\n } else if (sParms.slice(-1) == '}') {\n sParms = sParms.slice(0, -1);\n if (sParms.length > 1) sParms += ',';\n } else { // sParms must just be a \"state\" file, so encode it as a \"state\" property\n sParms = '{state:\"' + sParms + '\",';\n }\n sParms += 'url:\"' + sURL + '\"}';\n /*\n * Note that while we no longer generate a machine XML file with a \"state\" attribute (because it's\n * encoded inside the \"parms\" attribute), the XSL file must still cope with \"state\" attributes inside\n * other XML files; for example, manifest XML files like /apps/pcx86/1981/visicalc/manifest.xml contain\n * machine elements with \"state\" attributes that must still be passed down to the computer element\n * \"the old fashioned way\".\n *\n * Until/unless that changes, components.xsl cannot be simplified as much as I might have hoped.\n */\n if (typeof resources == 'object') sURL = null; // turn off URL inclusion if we have embedded resources\n sParms = sParms.replace(/\\$/g, \"$$$$\");\n if (sClass) {\n /*\n * If there's no hard-coded \"class\" attribute in the machine tag, then we can set one in the final\n * replacement below, just like we do for sParms and sURL. However, if a \"class\" attribute already\n * exists, we need alter it and then zap the sClass variable.\n */\n var match = sXML.match(/(<machine[^>]*\\sclass=)(['\"])(.*?)(\\2.*?>)/);\n if (match) {\n sXML = sXML.replace(match[0], match[1] + match[2] + sClass + match[4]);\n sClass = null;\n }\n }\n sXML = sXML.replace(/(<machine[^>]*\\sid=)(['\"]).*?\\2/, \"$1$2\" + idMachine + \"$2\" + (sClass? ' class=\"' + sClass + '\"' : '') + (sParms? \" parms='\" + sParms + \"'\" : \"\") + (sURL? ' url=\"' + sURL + '\"' : ''));\n }\n\n if (!fResolve) {\n /*\n * I'm trying to switch to a shared components.xsl (at least for all PC-class machines),\n * but in the interim, that means hacking the XSL file on the fly to reflect the actual class.\n */\n sXML = sXML.replace(/(<xsl:variable name=\"APPNAME\">).*?(<\\/xsl:variable>)/, \"$1\" + sAppName + \"$2\");\n sXML = sXML.replace(/(<xsl:variable name=\"APPCLASS\">).*?(<\\/xsl:variable>)/, \"$1\" + sAppClass + \"$2\");\n\n /*\n * Non-COMPILED kludge to replace the version number template in the XSL file (which we assume we're reading,\n * since fResolve is false) with whatever XMLVERSION we extracted from the XML file (see corresponding kludge below).\n *\n * ES6 ALERT: Template strings.\n */\n if (!COMPILED && XMLVERSION) {\n sXML = sXML.replace(/<xsl:variable name=\"APPVERSION\"\\/>/, `<xsl:variable name=\"APPVERSION\">${XMLVERSION}</xsl:variable>`);\n }\n }\n\n /*\n * If the resource we requested is not really an XML file (or the file didn't exist and the server simply returned\n * a message like \"Cannot GET /devices/pc/machine/5150/cga/64kb/donkey/machine.xml\"), we'd like to display a more\n * meaningful message, because the XML DOM parsers will blithely return a document that contains nothing useful; eg:\n *\n * This page contains the following errors:error on line 1 at column 1:\n * Document is empty Below is a rendering of the page up to the first error.\n *\n * Supposedly, the IE XML DOM parser will throw an exception, but I haven't tested that, and unless all other\n * browsers do that, that's not helpful.\n *\n * The best I can do at this stage (assuming Web.getResource() didn't drop any error information on the floor)\n * is verify that the requested resource \"looks like\" valid XML (in other words, it begins with a '<').\n */\n var xmlDoc = null;\n if (sXML.charAt(0) == '<') {\n try {\n /*\n * Another hack for MSIE, which fails to load XSL documents containing a <!DOCTYPE [...]> tag.\n *\n * This is also why the XSLTProcessor 'transformToFragment' method in Microsoft Edge silently failed,\n * so I had pull this hack out of the \"ActiveXObject\" code. And rather than add yet-another Microsoft\n * browser check, I'm going to try doing this across the board, and hope that none of the other XSLT\n * processors fail *without* the DOCTYPE tag.\n */\n if (!fResolve) {\n sXML = sXML.replace(/<!DOCTYPE(.|[\\r\\n])*]>\\s*/g, \"\");\n }\n /*\n * Beginning with Microsoft Edge and the corresponding release of Windows 10, all the\n * 'ActiveXObject' crud has gone away; but of course, this code must remain in place if\n * we want to continue supporting older Internet Explorer browsers (ie, back to IE9).\n */\n /** @namespace window.ActiveXObject */\n if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1\n xmlDoc = new window.ActiveXObject(\"Microsoft.XMLDOM\");\n xmlDoc.async = false;\n xmlDoc['loadXML'](sXML);\n } else {\n /** @namespace window.DOMParser */\n xmlDoc = (new window.DOMParser()).parseFromString(sXML, \"text/xml\");\n }\n } catch(e) {\n xmlDoc = null;\n sXML = e.message;\n }\n } else {\n sXML = \"unrecognized XML: \" + (sXML.length > 255? sXML.substr(0, 255) + \"...\" : sXML);\n }\n done(sXML, xmlDoc);\n };\n if (sXML) {\n if (PRIVATE) sXML = sXML.replace(/\\/library.xml/, \"/private/library.xml\");\n if (fResolve) {\n resolveXML(sXML, display, buildXML);\n return;\n }\n buildXML(sXML, null);\n return;\n }\n done(\"no data\" + (sXMLFile? \" for file: \" + sXMLFile : \"\"), null);\n}\n\n/**\n * resolveXML(sXML, display, done)\n *\n * Replaces every tag with a \"ref\" attribute with the contents of the corresponding file.\n *\n * TODO: Fix some of the limitations of this code, such as: 1) requiring the \"ref\" attribute\n * to appear as the tag's first attribute, 2) requiring the \"ref\" attribute to be double-quoted,\n * and 3) requiring the \"ref\" tag to be self-closing.\n *\n * @param {string} sXML\n * @param {function(string)} display\n * @param {function(string,(string|null))} done (the first string contains the resolved XML data, the second is for any error message)\n */\nfunction resolveXML(sXML, display, done)\n{\n var matchRef;\n var reRef = /<([a-z]+)\\s+ref=\"(.*?)\"(.*?)\\/>/g;\n\n if ((matchRef = reRef.exec(sXML))) {\n\n var sRefFile = matchRef[2];\n\n var doneReadXML = function(sURLName, sXMLRef, nErrorCode) {\n if (nErrorCode || !sXMLRef) {\n done(sXML, \"unable to resolve XML reference: \" + matchRef[0] + \" (\" + nErrorCode + \")\");\n return;\n }\n /*\n * If there are additional attributes in the \"referring\" XML tag, we want to insert them\n * into the \"referred\" XML tag; attributes that don't exist in the referred tag should be\n * appended, and attributes that DO exist should be overwritten.\n */\n var sRefAttrs = matchRef[3];\n if (sRefAttrs) {\n var aXMLRefTag = sXMLRef.match(new RegExp(\"<\" + matchRef[1] + \"[^>]*>\"));\n if (aXMLRefTag) {\n var sXMLNewTag = aXMLRefTag[0];\n /*\n * Iterate over all the attributes in the \"referring\" XML tag (sRefAttrs)\n */\n var matchAttr;\n var reAttr = /( [a-z]+=)(['\"])(.*?)\\2/gi;\n while ((matchAttr = reAttr.exec(sRefAttrs))) {\n if (sXMLNewTag.toLowerCase().indexOf(matchAttr[1].toLowerCase()) < 0) {\n /*\n * This is the append case....\n */\n sXMLNewTag = sXMLNewTag.replace(\">\", matchAttr[0] + \">\");\n } else {\n /*\n * This is the overwrite case....\n */\n sXMLNewTag = sXMLNewTag.replace(new RegExp(matchAttr[1] + \"(['\\\"])(.*?)\\\\1\"), matchAttr[0]);\n }\n }\n if (aXMLRefTag[0] != sXMLNewTag) {\n sXMLRef = sXMLRef.replace(aXMLRefTag[0], sXMLNewTag);\n }\n } else {\n done(sXML, \"missing <\" + matchRef[1] + \"> in \" + sRefFile);\n return;\n }\n }\n\n /*\n * Apparently when a Windows Azure server delivers one of my XML files, it may modify the first line:\n *\n * <?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n\n *\n * I didn't determine exactly what it was doing at this point (probably just changing the \\n to \\r\\n),\n * but in any case, relaxing the following replace() solved it.\n */\n sXMLRef = sXMLRef.replace(/<\\?xml[^>]*>[\\r\\n]*/, \"\");\n\n sXML = sXML.replace(matchRef[0], sXMLRef);\n\n resolveXML(sXML, display, done);\n };\n\n display(\"Loading \" + sRefFile + \"...\");\n Web.getResource(sRefFile, null, fAsync, doneReadXML);\n return;\n }\n done(sXML, null);\n}\n\n/**\n * embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * This allows to you embed a machine on a web page, by transforming the machine XML into HTML.\n *\n * @param {string} sAppName is the app name (eg, \"PCx86\")\n * @param {string} sAppClass is the app class (eg, \"pcx86\"); also known as the machine class\n * @param {string} sVersion is the app version (eg, \"1.15.7\")\n * @param {string} idMachine\n * @param {string|undefined} sXMLFile\n * @param {string|undefined} sXSLFile\n * @param {string|undefined} sParms (machine parameters, if any)\n * @param {string|undefined} sClass (an optional machine class name used to style the machine)\n * @return {boolean} true if successful, false if error\n */\nfunction embedMachine(sAppName, sAppClass, sVersion, idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n var eMachine, eWarning, fSuccess = true;\n\n if (!sXMLFile) {\n sXMLFile = \"machine.xml\";\n if (!sXSLFile) sXSLFile = \"components.xsl\";\n }\n \n cAsyncMachines++;\n Component.addMachine(idMachine);\n\n var doneMachine = function() {\n\n if (!--cAsyncMachines) {\n if (fAsync) Web.enablePageEvents(true);\n }\n };\n\n var displayError = function(sError) {\n Component.log(sError);\n displayMessage(\"Error: \" + sError);\n if (fSuccess) doneMachine();\n fSuccess = false;\n };\n\n var displayMessage = function(sMessage) {\n if (eWarning === undefined) {\n /*\n * Our MarkOut module (in convertMDMachineLinks()) creates machine containers that look like:\n *\n * <div id=\"' + sMachineID + '\" class=\"machine-placeholder\"><p>Embedded PC</p><p class=\"machine-warning\">...</p></div>\n *\n * with the \"machine-warning\" paragraph pre-populated with a warning message that the user will\n * see if nothing at all happens. But hopefully, in the normal case (and especially the error case),\n * *something* will have happened.\n *\n * Note that it is the HTMLOut module (in processMachines()) that ultimately decides which scripts to\n * include and then generates the embedXXX() call.\n */\n var aeWarning = (eMachine && Component.getElementsByClass(eMachine, \"machine-warning\"));\n eWarning = (aeWarning && aeWarning[0]) || eMachine;\n }\n if (eWarning) eWarning.innerHTML = Str.escapeHTML(sMessage);\n };\n\n try {\n eMachine = document.getElementById(idMachine);\n if (eMachine) {\n\n /*\n * If we have a 'css' resource, add it to the page first.\n */\n var css;\n if (typeof resources == \"object\" && (css = resources['css'])) {\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n // noinspection JSDeprecatedSymbols\n if (style.styleSheet) {\n // noinspection JSDeprecatedSymbols\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n head.appendChild(style);\n }\n\n if (!sXSLFile) {\n /*\n * Now that PCjs is an open-source project, we can make the following test more flexible,\n * and revert to the internal template if DEBUG *or* internal version (instead of *and*).\n *\n * Third-party sites that don't use the PCjs server will ALWAYS want to specify a fully-qualified\n * path to the XSL file, unless they choose to mirror our folder structure.\n */\n var sAppFolder = sAppClass;\n if (DEBUG || !sVersion) {\n if (sAppClass != \"c1pjs\") sAppFolder = \"shared\";\n sXSLFile = \"/modules/\" + sAppFolder + \"/templates/components.xsl\";\n } else {\n if (sAppClass.substr(0, 3) == \"pdp\") sAppFolder = \"pdpjs\";\n sXSLFile = \"/versions/\" + sAppFolder + \"/\" + sVersion + \"/components.xsl\";\n }\n }\n\n var processXML = function(sXML, xml) {\n if (!xml) {\n displayError(sXML);\n return;\n }\n\n /*\n * Non-COMPILED kludge to extract the version number from the stylesheet path in the machine XML file;\n * we don't need this code in COMPILED (non-DEBUG) releases, because APPVERSION is hard-coded into them.\n */\n if (!COMPILED) {\n var aMatch = sXML.match(/<\\?xml-stylesheet[^>]* href=(['\"])[^'\"]*?\\/([0-9.]*)\\/([^'\"]*)\\1/);\n if (aMatch) {\n XMLVERSION = aMatch[2];\n }\n }\n\n var transformXML = function(sXSL, xsl) {\n if (!xsl) {\n displayError(sXSL);\n return;\n }\n\n /*\n * Record the XSL file, in case someone wants to save the entire machine later.\n * \n * NOTE: sXSLFile will never be undefined by this point, but apparently the Closure Compiler doesn't realize that. \n */\n Component.addMachineResource(idMachine, sXSLFile || \"\", sXSL);\n\n /*\n * The <machine> template in components.xsl now generates a \"machine div\" that makes\n * the div we required the caller of embedMachine() to provide redundant, so instead\n * of appending this fragment to the caller's node, we REPLACE the caller's node.\n * This works only because because we ALSO inject the caller's \"machine div\" ID into\n * the fragment's ID during parseXML().\n *\n * eMachine.innerHTML = sFragment;\n *\n * Also, if the transform function fails, make sure you're using the appropriate\n * \"components.xsl\" and not a \"machine.xsl\", because the latter will not produce valid\n * embeddable HTML (and is the most common cause of failure at this final stage).\n */\n displayMessage(\"Processing \" + sXMLFile + \"...\");\n\n /*\n * Beginning with Microsoft Edge and the corresponding release of Windows 10, all the\n * 'ActiveXObject' crud has gone away; but of course, this code must remain in place if\n * we want to continue supporting older Internet Explorer browsers (ie, back to IE9).\n */\n if (window.ActiveXObject || 'ActiveXObject' in window) { // second test is required for IE11 on Windows 8.1\n var sFragment = xml['transformNode'](xsl);\n if (sFragment) {\n eMachine.outerHTML = sFragment;\n doneMachine();\n } else {\n displayError(\"transformNodeToObject failed\");\n }\n }\n else if (document.implementation && document.implementation.createDocument) {\n var xsltProcessor = new XSLTProcessor();\n xsltProcessor['importStylesheet'](xsl);\n var eFragment = xsltProcessor['transformToFragment'](xml, document);\n if (eFragment) {\n /*\n * This fails in Microsoft Edge...\n *\n var machine = eFragment.getElementById(idMachine);\n if (!machine) {\n displayError(\"machine generation failed: \" + idMachine);\n } else\n */\n if (eMachine.parentNode) {\n eMachine.parentNode.replaceChild(eFragment, eMachine);\n doneMachine();\n } else {\n /*\n * NOTE: This error can occur if our Node web server, when processing a folder with\n * both a manifest.xml with a machine.xml reference AND a README.md containing a\n * machine link, generates duplicate embedXXX() calls for the same machine; if the\n * first embedXXX() call finds its target, subsequent calls for the same target will\n * fail.\n *\n * Technically, such a folder is in a misconfigured state, but it happens, in part\n * because when we switched to the Jekyll web server, we had to add machine links to\n * all README.md files where we had previously relied on manifest.xml or machine.xml\n * processing. This is because the Jekyll web server currently doesn't process XML\n * files, nor is support for that likely to be added any time soon; it was a nice\n * feature of the Node web server, but it's not clear that it's worth doing for Jekyll.\n */\n displayError(\"invalid machine element: \" + idMachine);\n }\n } else {\n displayError(\"transformToFragment failed\");\n }\n } else {\n /*\n * Perhaps I should have performed this test at the outset; on the other hand, I'm\n * not aware of any browsers don't support one or both of the above XSLT transformation\n * methods, so treat this as a bug.\n */\n displayError(\"unable to transform XML: unsupported browser\");\n }\n };\n /*\n * NOTE: sXSLFile will never be undefined by this point, but apparently the Closure Compiler doesn't realize that. \n */\n loadXML(sXSLFile || \"\", null, sAppName, sAppClass, null, null, false, displayMessage, transformXML);\n };\n\n if (sXMLFile.charAt(0) != '<') {\n loadXML(sXMLFile, idMachine, sAppName, sAppClass, sParms, sClass, true, displayMessage, processXML);\n } else {\n parseXML(sXMLFile, null, idMachine, sAppName, sAppClass, sParms, sClass, false, displayMessage, processXML);\n }\n } else {\n displayError(\"missing machine element: \" + idMachine);\n }\n } catch(e) {\n displayError(e.message);\n }\n return fSuccess;\n}\n\n/**\n * embedC1P(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedC1P(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"C1Pjs\", \"c1pjs\", APPVERSION, idMachine, sXMLFile, sXSLFile, undefined, sClass);\n}\n\n/**\n * embedPCx86(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPCx86(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PCx86\", \"pcx86\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPC8080(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPC8080(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PC8080\", \"pc8080\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPDP10(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPDP10(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PDPjs\", \"pdp10\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * embedPDP11(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n *\n * @param {string} idMachine\n * @param {string} [sXMLFile]\n * @param {string} [sXSLFile]\n * @param {string} [sParms]\n * @param {string} [sClass]\n * @return {boolean} true if successful, false if error\n */\nfunction embedPDP11(idMachine, sXMLFile, sXSLFile, sParms, sClass)\n{\n if (fAsync) Web.enablePageEvents(false);\n return embedMachine(\"PDPjs\", \"pdp11\", APPVERSION, idMachine, sXMLFile, sXSLFile, sParms, sClass);\n}\n\n/**\n * findMachineComponent(idMachine, sType)\n *\n * @param {string} idMachine\n * @param {string} sType\n * @return {Component|null}\n */\nfunction findMachineComponent(idMachine, sType)\n{\n return Component.getComponentByType(sType, idMachine + \".machine\");\n}\n\n/**\n * commandMachine(control, fSingle, idMachine, sComponent, sCommand, sValue)\n *\n * Use Component methods to find the requested component for a specific machine, and if the component is found,\n * then check its 'exports' table for an entry matching the specified command string, and if an entry is found, then\n * the corresponding function is called with the specified data.\n *\n * @param {Object} control\n * @param {boolean} fSingle\n * @param {string} idMachine\n * @param {string} sComponent\n * @param {string} sCommand\n * @param {string} [sValue]\n * @return {boolean}\n */\nfunction commandMachine(control, fSingle, idMachine, sComponent, sCommand, sValue)\n{\n if (sCommand == \"script\") {\n if (Component.processScript(idMachine, sValue)) {\n if (fSingle) control.disabled = true;\n return true;\n }\n return false;\n }\n if (sComponent) {\n var component = Component.getComponentByType(sComponent, idMachine + \".machine\");\n if (component) {\n var exports = component['exports'];\n if (exports) {\n var fnCommand = exports[sCommand];\n if (fnCommand) {\n if (fnCommand.call(component, sValue)) {\n if (fSingle) control.disabled = true;\n return true;\n }\n return false;\n }\n }\n }\n }\n console.log(\"unimplemented: commandMachine('\" + idMachine + \"','\" + sComponent + \"','\" + sCommand + \"','\" + sValue + \"')\");\n return false;\n}\n\n/**\n * Prevent the Closure Compiler from renaming functions we want to export, by adding them as global properties.\n *\n * TODO: Consider making all these functions properties on a single global object (eg, 'PCjs'), to minimize global\n * pollution and risk of name collision.\n */\nif (APPNAME == \"C1Pjs\") {\n window['embedC1P'] = embedC1P;\n}\nif (APPNAME == \"PCx86\") {\n window['embedPC'] = embedPCx86; // WARNING: embedPC() deprecated as of v1.23.0\n window['embedPCx86'] = embedPCx86;\n}\nif (APPNAME == \"PC8080\") {\n window['embedPC8080'] = embedPC8080;\n}\nif (APPNAME == \"PDPjs\") {\n window['embedPDP10'] = embedPDP10;\n window['embedPDP11'] = embedPDP11;\n}\n\nwindow['commandMachine'] = commandMachine;\n\nwindow['enableEvents'] = Web.enablePageEvents;\nwindow['sendEvent'] = Web.sendPageEvent;\n"]} \ No newline at end of file